From 1332d38f2805d986ea130e43218c0d2e870b4dc1 Mon Sep 17 00:00:00 2001 From: William Joye Date: Tue, 9 Jan 2018 14:26:44 -0500 Subject: update ast 8.6.2 --- ast/.gitignore | 65 - ast/AST_to_do | 23 - ast/COPYING | 674 - ast/COPYING.LESSER | 165 - ast/COPYING.LIB | 481 - ast/Ers.h | 245 - ast/GRF_PAR | 124 - ast/Makefile.am | 828 - ast/Notes | 105 - ast/STARLINK_BRANCHES | 46 - ast/addcopyright | 2 - ast/addlinks | 163 - ast/addversion.in | 10 - ast/ast-for-wcslib/astTester.c | 85 - ast/ast-for-wcslib/loader.c | 35 - ast/ast-for-wcslib/matrixmap.h | 7 - ast/ast-for-wcslib/plot.h | 2 - ast/ast-for-wcslib/wcslib-instructions | 112 - ast/ast.news | 1189 - ast/ast_cpp.in | 11 - ast/ast_dev | 86 - ast/ast_err.msg | 214 - ast/ast_link.in | 463 - ast/ast_link_adam.in | 406 - ast/ast_par.source | 733 - ast/ast_test.c | 115 - ast/ast_tester/README | 33 - ast/ast_tester/a20070718_00010_02_cube.ast | 339 - ast/ast_tester/a20070718_00010_02_cube.fits-wcs | 61 - ast/ast_tester/aitoff.attr | 1 - ast/ast_tester/aitoff.box | 1 - ast/ast_tester/aitoff.head | 13 - ast/ast_tester/ast_tester | 232 - ast/ast_tester/brad.map | 58 - ast/ast_tester/brad.simp | 49 - ast/ast_tester/car1.attr | 1 - ast/ast_tester/car1.box | 1 - ast/ast_tester/car1.fattr | 1 - ast/ast_tester/car1.head | 32 - ast/ast_tester/car2.attr | 1 - ast/ast_tester/car2.box | 1 - ast/ast_tester/car2.fattr | 1 - ast/ast_tester/car2.head | 32 - ast/ast_tester/car3.attr | 1 - ast/ast_tester/car3.box | 1 - ast/ast_tester/car3.head | 8 - ast/ast_tester/car4.attr | 0 ast/ast_tester/car4.box | 1 - ast/ast_tester/car4.fattr | 1 - ast/ast_tester/car4.head | 38 - ast/ast_tester/car5.attr | 0 ast/ast_tester/car5.box | 1 - ast/ast_tester/car5.head | 38 - ast/ast_tester/car6.attr | 0 ast/ast_tester/car6.box | 1 - ast/ast_tester/car6.head | 39 - ast/ast_tester/cobe.attr | 1 - ast/ast_tester/cobe.box | 1 - ast/ast_tester/cobe.head | 61 - ast/ast_tester/degen1.ast | 318 - ast/ast_tester/degen1.fits-wcs | 40 - ast/ast_tester/doplot | 53 - ast/ast_tester/dss.ast | 166 - ast/ast_tester/dss.dss | 58 - ast/ast_tester/dss.fits-dss | 108 - ast/ast_tester/dss.fits-wcs | 39 - ast/ast_tester/hpx.attr | 1 - ast/ast_tester/hpx.box | 1 - ast/ast_tester/hpx.head | 10 - ast/ast_tester/joye_car_headers/CAR_model.head | 47 - ast/ast_tester/joye_car_headers/CHIPASS_Equ.head | 39 - ast/ast_tester/joye_car_headers/car1.fattr | 1 - ast/ast_tester/joye_car_headers/car1.head | 32 - ast/ast_tester/joye_car_headers/car2.fattr | 1 - ast/ast_tester/joye_car_headers/car2.head | 32 - ast/ast_tester/joye_car_headers/car3.head | 8 - ast/ast_tester/joye_car_headers/car4.fattr | 1 - ast/ast_tester/joye_car_headers/car4.head | 38 - ast/ast_tester/joye_car_headers/car5.head | 38 - .../joye_car_headers/cmap_3years_GP_D2.head | 162 - ast/ast_tester/joye_car_headers/doit | 17 - ast/ast_tester/joye_car_headers/total_hi.head | 35 - ast/ast_tester/longslit.fits-pc | 18 - ast/ast_tester/longslit.fits-wcs | 22 - ast/ast_tester/makeplot | 47 - ast/ast_tester/maketest | 35 - ast/ast_tester/origin.attr | 1 - ast/ast_tester/origin.box | 1 - ast/ast_tester/origin.head | 18 - ast/ast_tester/plot3d-test1.ast | 340 - ast/ast_tester/plotter.f | 230 - ast/ast_tester/polco.attr | 1 - ast/ast_tester/polco.box | 1 - ast/ast_tester/polco.head | 86 - ast/ast_tester/polco2.attr | 1 - ast/ast_tester/polco2.box | 1 - ast/ast_tester/polco2.head | 86 - ast/ast_tester/regression.current | 7583 ---- ast/ast_tester/regression.f | 1515 - ast/ast_tester/regression.out | 7630 ---- ast/ast_tester/rigby.map | 240 - ast/ast_tester/rigby.simp | 201 - ast/ast_tester/scp.attr | 1 - ast/ast_tester/scp.box | 1 - ast/ast_tester/scp.head | 204 - ast/ast_tester/serpens.attr | 1 - ast/ast_tester/serpens.box | 1 - ast/ast_tester/serpens.head | 160 - ast/ast_tester/simplify.f | 123 - ast/ast_tester/sip.fits-wcs | 289 - ast/ast_tester/sip.head | 288 - ast/ast_tester/sparse.ast | 392 - ast/ast_tester/specflux.ast | 29 - ast/ast_tester/specflux.attr | 1 - ast/ast_tester/specflux.box | 2 - ast/ast_tester/specflux.head | 28 - ast/ast_tester/splittest1.ast | 185 - ast/ast_tester/stcschan-test1-doc3-props.ast | 126 - ast/ast_tester/stcschan-test1-doc3.ast | 272 - ast/ast_tester/testchannel.f | 88 - ast/ast_tester/testchebymap.f | 475 - ast/ast_tester/testcmpmap.f | 149 - ast/ast_tester/testconvert.c | 232 - ast/ast_tester/testerror.c | 44 - ast/ast_tester/testfitschan.f | 988 - ast/ast_tester/testfitstable.f | 590 - ast/ast_tester/testflux.f | 354 - ast/ast_tester/testframeset.f | 391 - ast/ast_tester/testkeymap.f | 1369 - ast/ast_tester/testlutmap.f | 177 - ast/ast_tester/testmapping.f | 85 - ast/ast_tester/testnormmap.f | 94 - ast/ast_tester/testobject.c | 120 - ast/ast_tester/testplot3d.f | 1357 - ast/ast_tester/testpolymap.f | 319 - ast/ast_tester/testrate.f | 344 - ast/ast_tester/testratemap.f | 148 - ast/ast_tester/testrebin.f | 4176 -- ast/ast_tester/testrebinseq.f | 1580 - ast/ast_tester/testregions.f | 4032 -- ast/ast_tester/testskyframe.f | 89 - ast/ast_tester/testspecflux.f | 331 - ast/ast_tester/testspecframe.f | 251 - ast/ast_tester/teststc.f | 1858 - ast/ast_tester/teststc_com | 13 - ast/ast_tester/teststc_eg1 | 71 - ast/ast_tester/teststc_eg10 | 18 - ast/ast_tester/teststc_eg2 | 114 - ast/ast_tester/teststc_eg3 | 113 - ast/ast_tester/teststc_eg4 | 55 - ast/ast_tester/teststc_eg5 | 109 - ast/ast_tester/teststc_eg6 | 49 - ast/ast_tester/teststc_eg7 | 52 - ast/ast_tester/teststc_eg8 | 52 - ast/ast_tester/teststc_eg9 | 49 - ast/ast_tester/teststcschan.f | 654 - ast/ast_tester/testswitchmap.f | 794 - ast/ast_tester/testtable.f | 537 - ast/ast_tester/testtime.f | 979 - ast/ast_tester/testtrangrid.f | 276 - ast/ast_tester/testunitnormmap.f | 324 - ast/ast_tester/testxmlchan.f | 246 - ast/ast_tester/testxmlchan_com | 13 - ast/ast_tester/testzoommap.f | 91 - ast/ast_tester/timeplot.attr | 1 - ast/ast_tester/timeplot.box | 1 - ast/ast_tester/timeplot.head | 34 - ast/ast_tester/timj.ast | 234 - ast/ast_tester/timj.fits-aips | 11 - ast/ast_tester/timj.fits-iraf | 13 - ast/ast_tester/timj.fits-pc | 16 - ast/ast_tester/timj.fits-wcs | 39 - ast/ast_tester/timj.native | 217 - ast/ast_tester/tnx.attr | 1 - ast/ast_tester/tnx.box | 1 - ast/ast_tester/tnx.head | 180 - ast/ast_tester/tsc.attr | 1 - ast/ast_tester/tsc.box | 1 - ast/ast_tester/tsc.head | 116 - ast/ast_tester/wcsconverter.f | 222 - ast/ast_tester/zpn.attr | 1 - ast/ast_tester/zpn.box | 1 - ast/ast_tester/zpn.head | 136 - ast/ast_tester/zpx.attr | 1 - ast/ast_tester/zpx.head | 153 - ast/astbad.c | 181 - ast/axis.c | 3500 -- ast/axis.h | 625 - ast/bootstrap | 134 - ast/box.c | 5062 --- ast/box.h | 234 - ast/builddocs.in | 146 - ast/buildhyperdocs | 11 - ast/c2f77.c | 125 - ast/c2f77.h | 166 - ast/cexpand | 32 - ast/cexpand.pl | 22 - ast/channel.c | 6458 --- ast/channel.h | 687 - ast/chebymap.c | 2404 - ast/chebymap.h | 234 - ast/circle.c | 2900 -- ast/circle.h | 241 - ast/cminpack/CopyrightMINPACK.txt | 52 - ast/cminpack/README.md | 128 - ast/cminpack/cminpack.h | 370 - ast/cminpack/cminpackP.h | 62 - ast/cminpack/dpmpar.c | 201 - ast/cminpack/enorm.c | 157 - ast/cminpack/lmder.c | 526 - ast/cminpack/lmder1.c | 167 - ast/cminpack/lmpar.c | 338 - ast/cminpack/qrfac.c | 285 - ast/cminpack/qrsolv.c | 218 - ast/cmpframe.c | 10846 ----- ast/cmpframe.h | 428 - ast/cmpframe.pdf | Bin 7432 -> 0 bytes ast/cmpmap.c | 4739 -- ast/cmpmap.h | 300 - ast/cmpregion.c | 5127 --- ast/cmpregion.h | 251 - ast/complex.pdf | Bin 15323 -> 0 bytes ast/component.xml | 44 - ast/component.xml.in | 44 - ast/configure.ac | 243 - ast/devtools/make_simtest | 4 - ast/devtools/simtest.c | 864 - ast/doincludes | 22 - ast/dsbspecframe.c | 3266 -- ast/dsbspecframe.h | 298 - ast/dssmap.c | 2283 - ast/dssmap.h | 401 - ast/ellipse.c | 3055 -- ast/ellipse.h | 244 - ast/ems.h | 185 - ast/erfa.h | 72 - ast/erfa/INFO | 19 - ast/erfa/LICENSE | 53 - ast/erfa/Makefile.am | 47 - ast/erfa/README.rst | 93 - ast/erfa/RELEASE.rst | 180 - ast/erfa/a2af.c | 129 - ast/erfa/a2tf.c | 125 - ast/erfa/ab.c | 137 - ast/erfa/af2a.c | 116 - ast/erfa/anp.c | 91 - ast/erfa/anpm.c | 91 - ast/erfa/apcg.c | 181 - ast/erfa/apcg13.c | 184 - ast/erfa/apci.c | 190 - ast/erfa/apci13.c | 202 - ast/erfa/apco.c | 264 - ast/erfa/apco13.c | 287 - ast/erfa/apcs.c | 233 - ast/erfa/apcs13.c | 191 - ast/erfa/aper.c | 162 - ast/erfa/aper13.c | 181 - ast/erfa/apio.c | 213 - ast/erfa/apio13.c | 259 - ast/erfa/atci13.c | 159 - ast/erfa/atciq.c | 154 - ast/erfa/atciqn.c | 191 - ast/erfa/atciqz.c | 153 - ast/erfa/atco13.c | 243 - ast/erfa/atic13.c | 152 - ast/erfa/aticq.c | 199 - ast/erfa/aticqn.c | 237 - ast/erfa/atio13.c | 222 - ast/erfa/atioq.c | 243 - ast/erfa/atoc13.c | 233 - ast/erfa/atoi13.c | 228 - ast/erfa/atoiq.c | 260 - ast/erfa/bi00.c | 125 - ast/erfa/bp00.c | 181 - ast/erfa/bp06.c | 152 - ast/erfa/bpn2xy.c | 109 - ast/erfa/c2i00a.c | 148 - ast/erfa/c2i00b.c | 148 - ast/erfa/c2i06a.c | 145 - ast/erfa/c2ibpn.c | 151 - ast/erfa/c2ixy.c | 140 - ast/erfa/c2ixys.c | 132 - ast/erfa/c2s.c | 105 - ast/erfa/c2t00a.c | 163 - ast/erfa/c2t00b.c | 159 - ast/erfa/c2t06a.c | 161 - ast/erfa/c2tcio.c | 131 - ast/erfa/c2teqx.c | 131 - ast/erfa/c2tpe.c | 176 - ast/erfa/c2txy.c | 168 - ast/erfa/cal2jd.c | 148 - ast/erfa/cp.c | 89 - ast/erfa/cpv.c | 91 - ast/erfa/cr.c | 92 - ast/erfa/d2dtf.c | 245 - ast/erfa/d2tf.c | 169 - ast/erfa/dat.c | 306 - ast/erfa/dtdb.c | 1222 - ast/erfa/dtf2d.c | 212 - ast/erfa/eceq06.c | 141 - ast/erfa/ecm06.c | 144 - ast/erfa/ee00.c | 137 - ast/erfa/ee00a.c | 144 - ast/erfa/ee00b.c | 150 - ast/erfa/ee06a.c | 131 - ast/erfa/eect00.c | 291 - ast/erfa/eform.c | 155 - ast/erfa/eo06a.c | 140 - ast/erfa/eors.c | 117 - ast/erfa/epb.c | 100 - ast/erfa/epb2jd.c | 100 - ast/erfa/epj.c | 102 - ast/erfa/epj2jd.c | 100 - ast/erfa/epv00.c | 2598 -- ast/erfa/eqec06.c | 142 - ast/erfa/eqeq94.c | 141 - ast/erfa/era00.c | 145 - ast/erfa/erfa.h | 517 - ast/erfa/erfam.h | 208 - ast/erfa/fad03.c | 112 - ast/erfa/fae03.c | 111 - ast/erfa/faf03.c | 115 - ast/erfa/faju03.c | 111 - ast/erfa/fal03.c | 112 - ast/erfa/falp03.c | 112 - ast/erfa/fama03.c | 111 - ast/erfa/fame03.c | 111 - ast/erfa/fane03.c | 108 - ast/erfa/faom03.c | 113 - ast/erfa/fapa03.c | 112 - ast/erfa/fasa03.c | 111 - ast/erfa/faur03.c | 108 - ast/erfa/fave03.c | 111 - ast/erfa/fk52h.c | 152 - ast/erfa/fk5hip.c | 135 - ast/erfa/fk5hz.c | 169 - ast/erfa/fw2m.c | 143 - ast/erfa/fw2xy.c | 130 - ast/erfa/g2icrs.c | 170 - ast/erfa/gc2gd.c | 143 - ast/erfa/gc2gde.c | 208 - ast/erfa/gd2gc.c | 142 - ast/erfa/gd2gce.c | 146 - ast/erfa/gmst00.c | 154 - ast/erfa/gmst06.c | 145 - ast/erfa/gmst82.c | 160 - ast/erfa/gst00a.c | 147 - ast/erfa/gst00b.c | 155 - ast/erfa/gst06.c | 149 - ast/erfa/gst06a.c | 140 - ast/erfa/gst94.c | 140 - ast/erfa/h2fk5.c | 157 - ast/erfa/hfk5z.c | 184 - ast/erfa/icrs2g.c | 170 - ast/erfa/ir.c | 92 - ast/erfa/jd2cal.c | 164 - ast/erfa/jdcalf.c | 170 - ast/erfa/ld.c | 161 - ast/erfa/ldn.c | 183 - ast/erfa/ldsun.c | 115 - ast/erfa/lteceq.c | 138 - ast/erfa/ltecm.c | 157 - ast/erfa/lteqec.c | 139 - ast/erfa/ltp.c | 140 - ast/erfa/ltpb.c | 133 - ast/erfa/ltpecl.c | 177 - ast/erfa/ltpequ.c | 177 - ast/erfa/num00a.c | 130 - ast/erfa/num00b.c | 130 - ast/erfa/num06a.c | 134 - ast/erfa/numat.c | 118 - ast/erfa/nut00a.c | 2056 - ast/erfa/nut00b.c | 381 - ast/erfa/nut06a.c | 162 - ast/erfa/nut80.c | 334 - ast/erfa/nutm80.c | 126 - ast/erfa/obl06.c | 127 - ast/erfa/obl80.c | 127 - ast/erfa/p06e.c | 330 - ast/erfa/p2pv.c | 92 - ast/erfa/p2s.c | 100 - ast/erfa/pap.c | 148 - ast/erfa/pas.c | 105 - ast/erfa/pb06.c | 153 - ast/erfa/pdp.c | 93 - ast/erfa/pfw06.c | 174 - ast/erfa/plan94.c | 523 - ast/erfa/pm.c | 85 - ast/erfa/pmat00.c | 127 - ast/erfa/pmat06.c | 131 - ast/erfa/pmat76.c | 150 - ast/erfa/pmp.c | 94 - ast/erfa/pmpx.c | 153 - ast/erfa/pmsafe.c | 206 - ast/erfa/pn.c | 118 - ast/erfa/pn00.c | 186 - ast/erfa/pn00a.c | 172 - ast/erfa/pn00b.c | 172 - ast/erfa/pn06.c | 196 - ast/erfa/pn06a.c | 162 - ast/erfa/pnm00a.c | 130 - ast/erfa/pnm00b.c | 130 - ast/erfa/pnm06a.c | 133 - ast/erfa/pnm80.c | 135 - ast/erfa/pom00.c | 124 - ast/erfa/ppp.c | 94 - ast/erfa/ppsp.c | 103 - ast/erfa/pr00.c | 151 - ast/erfa/prec76.c | 157 - ast/erfa/pv2p.c | 90 - ast/erfa/pv2s.c | 153 - ast/erfa/pvdpv.c | 111 - ast/erfa/pvm.c | 95 - ast/erfa/pvmpv.c | 96 - ast/erfa/pvppv.c | 96 - ast/erfa/pvstar.c | 216 - ast/erfa/pvtob.c | 162 - ast/erfa/pvu.c | 102 - ast/erfa/pvup.c | 97 - ast/erfa/pvxpv.c | 116 - ast/erfa/pxp.c | 103 - ast/erfa/refco.c | 262 - ast/erfa/rm2v.c | 120 - ast/erfa/rv2m.c | 127 - ast/erfa/rx.c | 119 - ast/erfa/rxp.c | 108 - ast/erfa/rxpv.c | 95 - ast/erfa/rxr.c | 108 - ast/erfa/ry.c | 119 - ast/erfa/rz.c | 119 - ast/erfa/s00.c | 380 - ast/erfa/s00a.c | 152 - ast/erfa/s00b.c | 152 - ast/erfa/s06.c | 377 - ast/erfa/s06a.c | 154 - ast/erfa/s2c.c | 94 - ast/erfa/s2p.c | 97 - ast/erfa/s2pv.c | 112 - ast/erfa/s2xpv.c | 96 - ast/erfa/sepp.c | 114 - ast/erfa/seps.c | 102 - ast/erfa/sp00.c | 127 - ast/erfa/starpm.c | 214 - ast/erfa/starpv.c | 273 - ast/erfa/sxp.c | 93 - ast/erfa/sxpv.c | 94 - ast/erfa/t_erfa_c.c | 9742 ----- ast/erfa/taitt.c | 119 - ast/erfa/taiut1.c | 120 - ast/erfa/taiutc.c | 168 - ast/erfa/tcbtdb.c | 141 - ast/erfa/tcgtt.c | 118 - ast/erfa/tdbtcb.c | 146 - ast/erfa/tdbtt.c | 130 - ast/erfa/tf2a.c | 116 - ast/erfa/tf2d.c | 116 - ast/erfa/tr.c | 102 - ast/erfa/trxp.c | 102 - ast/erfa/trxpv.c | 102 - ast/erfa/tttai.c | 119 - ast/erfa/tttcg.c | 121 - ast/erfa/tttdb.c | 130 - ast/erfa/ttut1.c | 119 - ast/erfa/ut1tai.c | 120 - ast/erfa/ut1tt.c | 119 - ast/erfa/ut1utc.c | 202 - ast/erfa/utctai.c | 186 - ast/erfa/utcut1.c | 156 - ast/erfa/xy06.c | 2767 -- ast/erfa/xys00a.c | 142 - ast/erfa/xys00b.c | 142 - ast/erfa/xys06a.c | 142 - ast/erfa/zp.c | 86 - ast/erfa/zpv.c | 88 - ast/erfa/zr.c | 92 - ast/erfa2ast.h | 248 - ast/erfam.h | 61 - ast/err.h | 66 - ast/err_drama.c | 122 - ast/err_ems.c | 108 - ast/err_null.c | 111 - ast/error.c | 1359 - ast/error.h | 362 - ast/f77.h.in | 1096 - ast/fbox.c | 110 - ast/fchannel.c | 473 - ast/fchebymap.c | 137 - ast/fcircle.c | 128 - ast/fcmpframe.c | 104 - ast/fcmpmap.c | 106 - ast/fcmpregion.c | 107 - ast/fdsbspecframe.c | 100 - ast/fdssmap.c | 75 - ast/fellipse.c | 136 - ast/ferror.c | 120 - ast/fetch | 5 - ast/ffitschan.c | 1023 - ast/ffitstable.c | 234 - ast/ffluxframe.c | 104 - ast/fframe.c | 514 - ast/fframeset.c | 214 - ast/fgrismmap.c | 99 - ast/finterval.c | 109 - ast/fintramap.c | 332 - ast/fitschan.c | 43747 ------------------- ast/fitschan.h | 933 - ast/fitstable.c | 3006 -- ast/fitstable.h | 235 - ast/fkeymap.c | 1441 - ast/flutmap.c | 107 - ast/fluxframe.c | 4490 -- ast/fluxframe.h | 267 - ast/fmapping.c | 771 - ast/fmathmap.c | 122 - ast/fmatrixmap.c | 110 - ast/fnormmap.c | 101 - ast/fnullregion.c | 104 - ast/fobject.c | 674 - ast/fpcdmap.c | 103 - ast/fpermmap.c | 110 - ast/fplot.c | 683 - ast/fplot3d.c | 107 - ast/fpointlist.c | 117 - ast/fpolygon.c | 226 - ast/fpolymap.c | 159 - ast/fprism.c | 105 - ast/frame.c | 16067 ------- ast/frame.f | 71 - ast/frame.h | 1459 - ast/frames.pdf | Bin 7196 -> 0 bytes ast/frameset.c | 13337 ------ ast/frameset.h | 714 - ast/frameset.pdf | Bin 28443 -> 0 bytes ast/fratemap.c | 106 - ast/fregion.c | 297 - ast/fronta.pdf | Bin 22646 -> 0 bytes ast/fronta_bw.pdf | Bin 22635 -> 0 bytes ast/frontb.pdf | Bin 66281 -> 0 bytes ast/frontb_bw.pdf | Bin 66247 -> 0 bytes ast/frontc.pdf | Bin 43197 -> 0 bytes ast/frontc_bw.pdf | Bin 43186 -> 0 bytes ast/fsalign.pdf | Bin 51413 -> 0 bytes ast/fsconvert.pdf | Bin 18693 -> 0 bytes ast/fselectormap.c | 115 - ast/fsexample.pdf | Bin 17716 -> 0 bytes ast/fshiftmap.c | 103 - ast/fskyframe.c | 112 - ast/fslamap.c | 122 - ast/fsmerge.pdf | Bin 47115 -> 0 bytes ast/fspecfluxframe.c | 104 - ast/fspecframe.c | 134 - ast/fspecmap.c | 124 - ast/fsphmap.c | 99 - ast/fsremap.pdf | Bin 24970 -> 0 bytes ast/fstc.c | 114 - ast/fstccatalogentrylocation.c | 117 - ast/fstcobsdatalocation.c | 117 - ast/fstcresourceprofile.c | 118 - ast/fstcschan.c | 131 - ast/fstcsearchlocation.c | 117 - ast/fswitchmap.c | 118 - ast/ftable.c | 330 - ast/ftemplateclass.c | 109 - ast/ftimeframe.c | 114 - ast/ftimemap.c | 122 - ast/ftranmap.c | 104 - ast/funitmap.c | 101 - ast/funitnormmap.c | 105 - ast/fwcsmap.c | 108 - ast/fwinmap.c | 110 - ast/fxmlchan.c | 130 - ast/fzoommap.c | 103 - ast/getatt | 163 - ast/getnewversion | 15 - ast/globals.c | 253 - ast/globals.h | 247 - ast/grf.h | 110 - ast/grf3d.c | 102 - ast/grf3d.h | 69 - ast/grf3d_pgplot.c | 3196 -- ast/grf_2.0.c | 101 - ast/grf_3.2.c | 74 - ast/grf_5.6.c | 77 - ast/grf_null.c | 98 - ast/grf_pgplot.c | 1494 - ast/gridplot.pdf | Bin 50536 -> 0 bytes ast/gridplot_bw.pdf | Bin 50506 -> 0 bytes ast/grismmap.c | 2596 -- ast/grismmap.h | 353 - ast/interval.c | 4686 -- ast/interval.h | 236 - ast/intramap.c | 2942 -- ast/intramap.h | 344 - ast/keymap.c | 10972 ----- ast/keymap.h | 569 - ast/leap-seconds.png | Bin 47101 -> 0 bytes ast/loader.c | 199 - ast/loader.h | 49 - ast/lutmap.c | 2629 -- ast/lutmap.h | 335 - ast/makeh | 313 - ast/mapping.c | 24692 ----------- ast/mapping.h | 856 - ast/mapping.pdf | Bin 8013 -> 0 bytes ast/mathmap.c | 7421 ---- ast/mathmap.h | 410 - ast/matrixmap.c | 5731 --- ast/matrixmap.h | 318 - ast/memory.c | 5470 --- ast/memory.h | 347 - ast/normmap.c | 1720 - ast/normmap.h | 217 - ast/nullregion.c | 2093 - ast/nullregion.h | 221 - ast/object.c | 8950 ---- ast/object.f | 70 - ast/object.h.in | 1960 - ast/overgrid.pdf | Bin 26963 -> 0 bytes ast/overgrid_bw.pdf | Bin 25865 -> 0 bytes ast/pal.h | 582 - ast/pal/pal.h | 551 - ast/pal/pal1sofa.h | 142 - ast/pal/palAddet.c | 112 - ast/pal/palAmpqk.c | 159 - ast/pal/palCaldj.c | 99 - ast/pal/palDat.c | 95 - ast/pal/palDe2h.c | 142 - ast/pal/palDeuler.c | 141 - ast/pal/palDh2e.c | 133 - ast/pal/palDjcal.c | 97 - ast/pal/palDmat.c | 182 - ast/pal/palDrange.c | 77 - ast/pal/palDs2tp.c | 127 - ast/pal/palDtp2s.c | 95 - ast/pal/palDtps2c.c | 151 - ast/pal/palDtt.c | 77 - ast/pal/palEcmat.c | 82 - ast/pal/palEqgal.c | 118 - ast/pal/palEtrms.c | 106 - ast/pal/palEvp.c | 110 - ast/pal/palFk45z.c | 186 - ast/pal/palFk524.c | 259 - ast/pal/palFk54z.c | 113 - ast/pal/palGaleq.c | 118 - ast/pal/palGalsup.c | 116 - ast/pal/palGeoc.c | 83 - ast/pal/palMappa.c | 129 - ast/pal/palMapqkz.c | 150 - ast/pal/palOne2One.c | 1482 - ast/pal/palPrebn.c | 98 - ast/pal/palPrec.c | 107 - ast/pal/palPrenut.c | 111 - ast/pal/palPvobs.c | 108 - ast/pal/palRvgalc.c | 111 - ast/pal/palRvlg.c | 106 - ast/pal/palRvlsrd.c | 116 - ast/pal/palRvlsrk.c | 116 - ast/pal/palSubet.c | 112 - ast/pal/palSupgal.c | 116 - ast/pal/palmac.h | 136 - ast/pal2ast.h | 134 - ast/palwrap.c | 301 - ast/parallel.pdf | Bin 10441 -> 0 bytes ast/pcdmap.c | 3218 -- ast/pcdmap.h | 357 - ast/permmap.c | 3204 -- ast/permmap.h | 322 - ast/pg3d.h | 68 - ast/plot.c | 32074 -------------- ast/plot.f | 71 - ast/plot.h | 1417 - ast/plot3d.c | 8587 ---- ast/plot3d.h | 258 - ast/pointlist.c | 3407 -- ast/pointlist.h | 239 - ast/pointset.c | 3285 -- ast/pointset.h | 711 - ast/polygon.c | 7087 --- ast/polygon.h | 353 - ast/polymap.c | 6107 --- ast/polymap.h | 386 - ast/prepare_all | 41 - ast/prepare_docs | 16 - ast/prepare_hyperdocs | 37 - ast/prepare_release | 39 - ast/prism.c | 4448 -- ast/prism.h | 238 - ast/proj.c | 4840 -- ast/proj.h | 181 - ast/ratemap.c | 2011 - ast/ratemap.h | 276 - ast/region.c | 13502 ------ ast/region.h | 515 - ast/selectfc | 29 - ast/selectormap.c | 1838 - ast/selectormap.h | 277 - ast/series.pdf | Bin 10149 -> 0 bytes ast/shiftmap.c | 1617 - ast/shiftmap.h | 290 - ast/simpexamp.pdf | Bin 7842 -> 0 bytes ast/skyaxis.c | 5150 --- ast/skyaxis.h | 428 - ast/skyframe.c | 12592 ------ ast/skyframe.h | 508 - ast/slamap.c | 5027 --- ast/slamap.h | 330 - ast/specfluxframe.c | 2189 - ast/specfluxframe.h | 215 - ast/specframe.c | 7437 ---- ast/specframe.h | 430 - ast/specmap.c | 4696 -- ast/specmap.h | 282 - ast/sphmap.c | 2061 - ast/sphmap.h | 374 - ast/stc.c | 3703 -- ast/stc.h | 240 - ast/stccatalogentrylocation.c | 804 - ast/stccatalogentrylocation.h | 223 - ast/stcobsdatalocation.c | 1051 - ast/stcobsdatalocation.h | 236 - ast/stcresourceprofile.c | 807 - ast/stcresourceprofile.h | 223 - ast/stcs-ex1.txt | 13 - ast/stcschan-demo1.c | 288 - ast/stcschan-demo2.c | 263 - ast/stcschan-demo3.c | 435 - ast/stcschan-demo4.c | 262 - ast/stcschan-demo5.c | 300 - ast/stcschan.c | 8732 ---- ast/stcschan.h | 308 - ast/stcsearchlocation.c | 806 - ast/stcsearchlocation.h | 222 - ast/sun210_figures/cmpframe.pdf | Bin 7432 -> 0 bytes ast/sun210_figures/complex.pdf | Bin 15323 -> 0 bytes ast/sun210_figures/frames.pdf | Bin 7196 -> 0 bytes ast/sun210_figures/frameset.pdf | Bin 28443 -> 0 bytes ast/sun210_figures/fronta.pdf | Bin 22394 -> 0 bytes ast/sun210_figures/fronta_bw.pdf | Bin 22635 -> 0 bytes ast/sun210_figures/frontb.pdf | Bin 57273 -> 0 bytes ast/sun210_figures/frontb_bw.pdf | Bin 66247 -> 0 bytes ast/sun210_figures/frontc.pdf | Bin 57629 -> 0 bytes ast/sun210_figures/frontc_bw.pdf | Bin 43186 -> 0 bytes ast/sun210_figures/fsalign.pdf | Bin 51413 -> 0 bytes ast/sun210_figures/fsconvert.pdf | Bin 18693 -> 0 bytes ast/sun210_figures/fsexample.pdf | Bin 17716 -> 0 bytes ast/sun210_figures/fsmerge.pdf | Bin 47115 -> 0 bytes ast/sun210_figures/fsremap.pdf | Bin 24970 -> 0 bytes ast/sun210_figures/gridplot.pdf | Bin 50536 -> 0 bytes ast/sun210_figures/gridplot_bw.pdf | Bin 20421 -> 0 bytes ast/sun210_figures/mapping.pdf | Bin 8013 -> 0 bytes ast/sun210_figures/overgrid.pdf | Bin 26963 -> 0 bytes ast/sun210_figures/overgrid_bw.pdf | Bin 25865 -> 0 bytes ast/sun210_figures/parallel.pdf | Bin 10441 -> 0 bytes ast/sun210_figures/series.pdf | Bin 10149 -> 0 bytes ast/sun210_figures/simpexamp.pdf | Bin 7842 -> 0 bytes ast/sun211_figures/cmpframe.pdf | Bin 7432 -> 0 bytes ast/sun211_figures/complex.pdf | Bin 15323 -> 0 bytes ast/sun211_figures/frames.pdf | Bin 7196 -> 0 bytes ast/sun211_figures/frameset.pdf | Bin 28443 -> 0 bytes ast/sun211_figures/fronta.pdf | Bin 22394 -> 0 bytes ast/sun211_figures/fronta_bw.pdf | Bin 22635 -> 0 bytes ast/sun211_figures/frontb.pdf | Bin 57273 -> 0 bytes ast/sun211_figures/frontb_bw.pdf | Bin 66247 -> 0 bytes ast/sun211_figures/frontc.pdf | Bin 57629 -> 0 bytes ast/sun211_figures/frontc_bw.pdf | Bin 43186 -> 0 bytes ast/sun211_figures/fsalign.pdf | Bin 51413 -> 0 bytes ast/sun211_figures/fsconvert.pdf | Bin 18693 -> 0 bytes ast/sun211_figures/fsexample.pdf | Bin 17716 -> 0 bytes ast/sun211_figures/fsmerge.pdf | Bin 47115 -> 0 bytes ast/sun211_figures/fsremap.pdf | Bin 24962 -> 0 bytes ast/sun211_figures/gridplot.pdf | Bin 50536 -> 0 bytes ast/sun211_figures/gridplot_bw.pdf | Bin 20421 -> 0 bytes ast/sun211_figures/mapping.pdf | Bin 8013 -> 0 bytes ast/sun211_figures/overgrid.pdf | Bin 26963 -> 0 bytes ast/sun211_figures/overgrid_bw.pdf | Bin 25865 -> 0 bytes ast/sun211_figures/parallel.pdf | Bin 10441 -> 0 bytes ast/sun211_figures/series.pdf | Bin 10149 -> 0 bytes ast/sun211_figures/simpexamp.pdf | Bin 7842 -> 0 bytes ast/sun_master.tex | 21879 ---------- ast/switchmap.c | 2875 -- ast/switchmap.h | 289 - ast/table.c | 5246 --- ast/table.h | 309 - ast/templateclass.README | 29 - ast/templateclass.c | 1483 - ast/templateclass.h | 216 - ast/timeframe.c | 7530 ---- ast/timeframe.h | 324 - ast/timemap.c | 5330 --- ast/timemap.h | 285 - ast/tpn.c | 393 - ast/tranmap.c | 2327 - ast/tranmap.h | 276 - ast/unit.c | 6218 --- ast/unit.h | 83 - ast/unitmap.c | 1425 - ast/unitmap.h | 288 - ast/unitnormmap.c | 1666 - ast/unitnormmap.h | 299 - ast/version.h.in | 73 - ast/wcsmap.c | 6094 --- ast/wcsmap.h | 591 - ast/wcsmath.h | 67 - ast/wcstrig.c | 189 - ast/wcstrig.h | 63 - ast/winmap.c | 4389 -- ast/winmap.h | 300 - ast/xml.c | 7119 --- ast/xml.h | 392 - ast/xmlchan.c | 14120 ------ ast/xmlchan.h | 300 - ast/zoommap.c | 2074 - ast/zoommap.h | 322 - 813 files changed, 624593 deletions(-) delete mode 100644 ast/.gitignore delete mode 100644 ast/AST_to_do delete mode 100644 ast/COPYING delete mode 100644 ast/COPYING.LESSER delete mode 100644 ast/COPYING.LIB delete mode 100644 ast/Ers.h delete mode 100644 ast/GRF_PAR delete mode 100644 ast/Makefile.am delete mode 100644 ast/Notes delete mode 100644 ast/STARLINK_BRANCHES delete mode 100755 ast/addcopyright delete mode 100755 ast/addlinks delete mode 100644 ast/addversion.in delete mode 100644 ast/ast-for-wcslib/astTester.c delete mode 100644 ast/ast-for-wcslib/loader.c delete mode 100644 ast/ast-for-wcslib/matrixmap.h delete mode 100644 ast/ast-for-wcslib/plot.h delete mode 100644 ast/ast-for-wcslib/wcslib-instructions delete mode 100644 ast/ast.news delete mode 100644 ast/ast_cpp.in delete mode 100644 ast/ast_dev delete mode 100644 ast/ast_err.msg delete mode 100644 ast/ast_link.in delete mode 100644 ast/ast_link_adam.in delete mode 100644 ast/ast_par.source delete mode 100644 ast/ast_test.c delete mode 100644 ast/ast_tester/README delete mode 100644 ast/ast_tester/a20070718_00010_02_cube.ast delete mode 100644 ast/ast_tester/a20070718_00010_02_cube.fits-wcs delete mode 100644 ast/ast_tester/aitoff.attr delete mode 100644 ast/ast_tester/aitoff.box delete mode 100644 ast/ast_tester/aitoff.head delete mode 100755 ast/ast_tester/ast_tester delete mode 100644 ast/ast_tester/brad.map delete mode 100644 ast/ast_tester/brad.simp delete mode 100644 ast/ast_tester/car1.attr delete mode 100644 ast/ast_tester/car1.box delete mode 100644 ast/ast_tester/car1.fattr delete mode 100644 ast/ast_tester/car1.head delete mode 100644 ast/ast_tester/car2.attr delete mode 100644 ast/ast_tester/car2.box delete mode 100644 ast/ast_tester/car2.fattr delete mode 100644 ast/ast_tester/car2.head delete mode 100644 ast/ast_tester/car3.attr delete mode 100644 ast/ast_tester/car3.box delete mode 100644 ast/ast_tester/car3.head delete mode 100644 ast/ast_tester/car4.attr delete mode 100644 ast/ast_tester/car4.box delete mode 100644 ast/ast_tester/car4.fattr delete mode 100644 ast/ast_tester/car4.head delete mode 100644 ast/ast_tester/car5.attr delete mode 100644 ast/ast_tester/car5.box delete mode 100644 ast/ast_tester/car5.head delete mode 100644 ast/ast_tester/car6.attr delete mode 100644 ast/ast_tester/car6.box delete mode 100644 ast/ast_tester/car6.head delete mode 100644 ast/ast_tester/cobe.attr delete mode 100644 ast/ast_tester/cobe.box delete mode 100644 ast/ast_tester/cobe.head delete mode 100644 ast/ast_tester/degen1.ast delete mode 100644 ast/ast_tester/degen1.fits-wcs delete mode 100755 ast/ast_tester/doplot delete mode 100644 ast/ast_tester/dss.ast delete mode 100644 ast/ast_tester/dss.dss delete mode 100644 ast/ast_tester/dss.fits-dss delete mode 100644 ast/ast_tester/dss.fits-wcs delete mode 100644 ast/ast_tester/hpx.attr delete mode 100644 ast/ast_tester/hpx.box delete mode 100644 ast/ast_tester/hpx.head delete mode 100644 ast/ast_tester/joye_car_headers/CAR_model.head delete mode 100644 ast/ast_tester/joye_car_headers/CHIPASS_Equ.head delete mode 100644 ast/ast_tester/joye_car_headers/car1.fattr delete mode 100644 ast/ast_tester/joye_car_headers/car1.head delete mode 100644 ast/ast_tester/joye_car_headers/car2.fattr delete mode 100644 ast/ast_tester/joye_car_headers/car2.head delete mode 100644 ast/ast_tester/joye_car_headers/car3.head delete mode 100644 ast/ast_tester/joye_car_headers/car4.fattr delete mode 100644 ast/ast_tester/joye_car_headers/car4.head delete mode 100644 ast/ast_tester/joye_car_headers/car5.head delete mode 100644 ast/ast_tester/joye_car_headers/cmap_3years_GP_D2.head delete mode 100755 ast/ast_tester/joye_car_headers/doit delete mode 100644 ast/ast_tester/joye_car_headers/total_hi.head delete mode 100644 ast/ast_tester/longslit.fits-pc delete mode 100644 ast/ast_tester/longslit.fits-wcs delete mode 100755 ast/ast_tester/makeplot delete mode 100755 ast/ast_tester/maketest delete mode 100644 ast/ast_tester/origin.attr delete mode 100644 ast/ast_tester/origin.box delete mode 100644 ast/ast_tester/origin.head delete mode 100644 ast/ast_tester/plot3d-test1.ast delete mode 100644 ast/ast_tester/plotter.f delete mode 100644 ast/ast_tester/polco.attr delete mode 100644 ast/ast_tester/polco.box delete mode 100644 ast/ast_tester/polco.head delete mode 100644 ast/ast_tester/polco2.attr delete mode 100644 ast/ast_tester/polco2.box delete mode 100644 ast/ast_tester/polco2.head delete mode 100644 ast/ast_tester/regression.current delete mode 100644 ast/ast_tester/regression.f delete mode 100644 ast/ast_tester/regression.out delete mode 100644 ast/ast_tester/rigby.map delete mode 100644 ast/ast_tester/rigby.simp delete mode 100644 ast/ast_tester/scp.attr delete mode 100644 ast/ast_tester/scp.box delete mode 100644 ast/ast_tester/scp.head delete mode 100644 ast/ast_tester/serpens.attr delete mode 100644 ast/ast_tester/serpens.box delete mode 100644 ast/ast_tester/serpens.head delete mode 100644 ast/ast_tester/simplify.f delete mode 100644 ast/ast_tester/sip.fits-wcs delete mode 100644 ast/ast_tester/sip.head delete mode 100644 ast/ast_tester/sparse.ast delete mode 100644 ast/ast_tester/specflux.ast delete mode 100644 ast/ast_tester/specflux.attr delete mode 100644 ast/ast_tester/specflux.box delete mode 100644 ast/ast_tester/specflux.head delete mode 100644 ast/ast_tester/splittest1.ast delete mode 100644 ast/ast_tester/stcschan-test1-doc3-props.ast delete mode 100644 ast/ast_tester/stcschan-test1-doc3.ast delete mode 100644 ast/ast_tester/testchannel.f delete mode 100644 ast/ast_tester/testchebymap.f delete mode 100644 ast/ast_tester/testcmpmap.f delete mode 100644 ast/ast_tester/testconvert.c delete mode 100644 ast/ast_tester/testerror.c delete mode 100644 ast/ast_tester/testfitschan.f delete mode 100644 ast/ast_tester/testfitstable.f delete mode 100644 ast/ast_tester/testflux.f delete mode 100644 ast/ast_tester/testframeset.f delete mode 100644 ast/ast_tester/testkeymap.f delete mode 100644 ast/ast_tester/testlutmap.f delete mode 100644 ast/ast_tester/testmapping.f delete mode 100644 ast/ast_tester/testnormmap.f delete mode 100644 ast/ast_tester/testobject.c delete mode 100644 ast/ast_tester/testplot3d.f delete mode 100644 ast/ast_tester/testpolymap.f delete mode 100644 ast/ast_tester/testrate.f delete mode 100644 ast/ast_tester/testratemap.f delete mode 100644 ast/ast_tester/testrebin.f delete mode 100644 ast/ast_tester/testrebinseq.f delete mode 100644 ast/ast_tester/testregions.f delete mode 100644 ast/ast_tester/testskyframe.f delete mode 100644 ast/ast_tester/testspecflux.f delete mode 100644 ast/ast_tester/testspecframe.f delete mode 100644 ast/ast_tester/teststc.f delete mode 100644 ast/ast_tester/teststc_com delete mode 100644 ast/ast_tester/teststc_eg1 delete mode 100644 ast/ast_tester/teststc_eg10 delete mode 100644 ast/ast_tester/teststc_eg2 delete mode 100644 ast/ast_tester/teststc_eg3 delete mode 100644 ast/ast_tester/teststc_eg4 delete mode 100644 ast/ast_tester/teststc_eg5 delete mode 100644 ast/ast_tester/teststc_eg6 delete mode 100644 ast/ast_tester/teststc_eg7 delete mode 100644 ast/ast_tester/teststc_eg8 delete mode 100644 ast/ast_tester/teststc_eg9 delete mode 100755 ast/ast_tester/teststcschan.f delete mode 100644 ast/ast_tester/testswitchmap.f delete mode 100644 ast/ast_tester/testtable.f delete mode 100644 ast/ast_tester/testtime.f delete mode 100644 ast/ast_tester/testtrangrid.f delete mode 100644 ast/ast_tester/testunitnormmap.f delete mode 100644 ast/ast_tester/testxmlchan.f delete mode 100644 ast/ast_tester/testxmlchan_com delete mode 100644 ast/ast_tester/testzoommap.f delete mode 100644 ast/ast_tester/timeplot.attr delete mode 100644 ast/ast_tester/timeplot.box delete mode 100644 ast/ast_tester/timeplot.head delete mode 100644 ast/ast_tester/timj.ast delete mode 100644 ast/ast_tester/timj.fits-aips delete mode 100644 ast/ast_tester/timj.fits-iraf delete mode 100644 ast/ast_tester/timj.fits-pc delete mode 100644 ast/ast_tester/timj.fits-wcs delete mode 100644 ast/ast_tester/timj.native delete mode 100644 ast/ast_tester/tnx.attr delete mode 100644 ast/ast_tester/tnx.box delete mode 100644 ast/ast_tester/tnx.head delete mode 100644 ast/ast_tester/tsc.attr delete mode 100644 ast/ast_tester/tsc.box delete mode 100644 ast/ast_tester/tsc.head delete mode 100644 ast/ast_tester/wcsconverter.f delete mode 100644 ast/ast_tester/zpn.attr delete mode 100644 ast/ast_tester/zpn.box delete mode 100644 ast/ast_tester/zpn.head delete mode 100644 ast/ast_tester/zpx.attr delete mode 100644 ast/ast_tester/zpx.head delete mode 100644 ast/astbad.c delete mode 100644 ast/axis.c delete mode 100644 ast/axis.h delete mode 100755 ast/bootstrap delete mode 100644 ast/box.c delete mode 100644 ast/box.h delete mode 100644 ast/builddocs.in delete mode 100755 ast/buildhyperdocs delete mode 100644 ast/c2f77.c delete mode 100644 ast/c2f77.h delete mode 100755 ast/cexpand delete mode 100755 ast/cexpand.pl delete mode 100644 ast/channel.c delete mode 100644 ast/channel.h delete mode 100644 ast/chebymap.c delete mode 100644 ast/chebymap.h delete mode 100644 ast/circle.c delete mode 100644 ast/circle.h delete mode 100644 ast/cminpack/CopyrightMINPACK.txt delete mode 100644 ast/cminpack/README.md delete mode 100644 ast/cminpack/cminpack.h delete mode 100644 ast/cminpack/cminpackP.h delete mode 100644 ast/cminpack/dpmpar.c delete mode 100644 ast/cminpack/enorm.c delete mode 100644 ast/cminpack/lmder.c delete mode 100644 ast/cminpack/lmder1.c delete mode 100644 ast/cminpack/lmpar.c delete mode 100644 ast/cminpack/qrfac.c delete mode 100644 ast/cminpack/qrsolv.c delete mode 100644 ast/cmpframe.c delete mode 100644 ast/cmpframe.h delete mode 100644 ast/cmpframe.pdf delete mode 100644 ast/cmpmap.c delete mode 100644 ast/cmpmap.h delete mode 100644 ast/cmpregion.c delete mode 100644 ast/cmpregion.h delete mode 100644 ast/complex.pdf delete mode 100644 ast/component.xml delete mode 100644 ast/component.xml.in delete mode 100644 ast/configure.ac delete mode 100644 ast/devtools/make_simtest delete mode 100644 ast/devtools/simtest.c delete mode 100755 ast/doincludes delete mode 100644 ast/dsbspecframe.c delete mode 100644 ast/dsbspecframe.h delete mode 100644 ast/dssmap.c delete mode 100644 ast/dssmap.h delete mode 100644 ast/ellipse.c delete mode 100644 ast/ellipse.h delete mode 100644 ast/ems.h delete mode 100644 ast/erfa.h delete mode 100644 ast/erfa/INFO delete mode 100644 ast/erfa/LICENSE delete mode 100644 ast/erfa/Makefile.am delete mode 100644 ast/erfa/README.rst delete mode 100644 ast/erfa/RELEASE.rst delete mode 100644 ast/erfa/a2af.c delete mode 100644 ast/erfa/a2tf.c delete mode 100644 ast/erfa/ab.c delete mode 100644 ast/erfa/af2a.c delete mode 100644 ast/erfa/anp.c delete mode 100644 ast/erfa/anpm.c delete mode 100644 ast/erfa/apcg.c delete mode 100644 ast/erfa/apcg13.c delete mode 100644 ast/erfa/apci.c delete mode 100644 ast/erfa/apci13.c delete mode 100644 ast/erfa/apco.c delete mode 100644 ast/erfa/apco13.c delete mode 100644 ast/erfa/apcs.c delete mode 100644 ast/erfa/apcs13.c delete mode 100644 ast/erfa/aper.c delete mode 100644 ast/erfa/aper13.c delete mode 100644 ast/erfa/apio.c delete mode 100644 ast/erfa/apio13.c delete mode 100644 ast/erfa/atci13.c delete mode 100644 ast/erfa/atciq.c delete mode 100644 ast/erfa/atciqn.c delete mode 100644 ast/erfa/atciqz.c delete mode 100644 ast/erfa/atco13.c delete mode 100644 ast/erfa/atic13.c delete mode 100644 ast/erfa/aticq.c delete mode 100644 ast/erfa/aticqn.c delete mode 100644 ast/erfa/atio13.c delete mode 100644 ast/erfa/atioq.c delete mode 100644 ast/erfa/atoc13.c delete mode 100644 ast/erfa/atoi13.c delete mode 100644 ast/erfa/atoiq.c delete mode 100644 ast/erfa/bi00.c delete mode 100644 ast/erfa/bp00.c delete mode 100644 ast/erfa/bp06.c delete mode 100644 ast/erfa/bpn2xy.c delete mode 100644 ast/erfa/c2i00a.c delete mode 100644 ast/erfa/c2i00b.c delete mode 100644 ast/erfa/c2i06a.c delete mode 100644 ast/erfa/c2ibpn.c delete mode 100644 ast/erfa/c2ixy.c delete mode 100644 ast/erfa/c2ixys.c delete mode 100644 ast/erfa/c2s.c delete mode 100644 ast/erfa/c2t00a.c delete mode 100644 ast/erfa/c2t00b.c delete mode 100644 ast/erfa/c2t06a.c delete mode 100644 ast/erfa/c2tcio.c delete mode 100644 ast/erfa/c2teqx.c delete mode 100644 ast/erfa/c2tpe.c delete mode 100644 ast/erfa/c2txy.c delete mode 100644 ast/erfa/cal2jd.c delete mode 100644 ast/erfa/cp.c delete mode 100644 ast/erfa/cpv.c delete mode 100644 ast/erfa/cr.c delete mode 100644 ast/erfa/d2dtf.c delete mode 100644 ast/erfa/d2tf.c delete mode 100644 ast/erfa/dat.c delete mode 100644 ast/erfa/dtdb.c delete mode 100644 ast/erfa/dtf2d.c delete mode 100644 ast/erfa/eceq06.c delete mode 100644 ast/erfa/ecm06.c delete mode 100644 ast/erfa/ee00.c delete mode 100644 ast/erfa/ee00a.c delete mode 100644 ast/erfa/ee00b.c delete mode 100644 ast/erfa/ee06a.c delete mode 100644 ast/erfa/eect00.c delete mode 100644 ast/erfa/eform.c delete mode 100644 ast/erfa/eo06a.c delete mode 100644 ast/erfa/eors.c delete mode 100644 ast/erfa/epb.c delete mode 100644 ast/erfa/epb2jd.c delete mode 100644 ast/erfa/epj.c delete mode 100644 ast/erfa/epj2jd.c delete mode 100644 ast/erfa/epv00.c delete mode 100644 ast/erfa/eqec06.c delete mode 100644 ast/erfa/eqeq94.c delete mode 100644 ast/erfa/era00.c delete mode 100644 ast/erfa/erfa.h delete mode 100644 ast/erfa/erfam.h delete mode 100644 ast/erfa/fad03.c delete mode 100644 ast/erfa/fae03.c delete mode 100644 ast/erfa/faf03.c delete mode 100644 ast/erfa/faju03.c delete mode 100644 ast/erfa/fal03.c delete mode 100644 ast/erfa/falp03.c delete mode 100644 ast/erfa/fama03.c delete mode 100644 ast/erfa/fame03.c delete mode 100644 ast/erfa/fane03.c delete mode 100644 ast/erfa/faom03.c delete mode 100644 ast/erfa/fapa03.c delete mode 100644 ast/erfa/fasa03.c delete mode 100644 ast/erfa/faur03.c delete mode 100644 ast/erfa/fave03.c delete mode 100644 ast/erfa/fk52h.c delete mode 100644 ast/erfa/fk5hip.c delete mode 100644 ast/erfa/fk5hz.c delete mode 100644 ast/erfa/fw2m.c delete mode 100644 ast/erfa/fw2xy.c delete mode 100644 ast/erfa/g2icrs.c delete mode 100644 ast/erfa/gc2gd.c delete mode 100644 ast/erfa/gc2gde.c delete mode 100644 ast/erfa/gd2gc.c delete mode 100644 ast/erfa/gd2gce.c delete mode 100644 ast/erfa/gmst00.c delete mode 100644 ast/erfa/gmst06.c delete mode 100644 ast/erfa/gmst82.c delete mode 100644 ast/erfa/gst00a.c delete mode 100644 ast/erfa/gst00b.c delete mode 100644 ast/erfa/gst06.c delete mode 100644 ast/erfa/gst06a.c delete mode 100644 ast/erfa/gst94.c delete mode 100644 ast/erfa/h2fk5.c delete mode 100644 ast/erfa/hfk5z.c delete mode 100644 ast/erfa/icrs2g.c delete mode 100644 ast/erfa/ir.c delete mode 100644 ast/erfa/jd2cal.c delete mode 100644 ast/erfa/jdcalf.c delete mode 100644 ast/erfa/ld.c delete mode 100644 ast/erfa/ldn.c delete mode 100644 ast/erfa/ldsun.c delete mode 100644 ast/erfa/lteceq.c delete mode 100644 ast/erfa/ltecm.c delete mode 100644 ast/erfa/lteqec.c delete mode 100644 ast/erfa/ltp.c delete mode 100644 ast/erfa/ltpb.c delete mode 100644 ast/erfa/ltpecl.c delete mode 100644 ast/erfa/ltpequ.c delete mode 100644 ast/erfa/num00a.c delete mode 100644 ast/erfa/num00b.c delete mode 100644 ast/erfa/num06a.c delete mode 100644 ast/erfa/numat.c delete mode 100644 ast/erfa/nut00a.c delete mode 100644 ast/erfa/nut00b.c delete mode 100644 ast/erfa/nut06a.c delete mode 100644 ast/erfa/nut80.c delete mode 100644 ast/erfa/nutm80.c delete mode 100644 ast/erfa/obl06.c delete mode 100644 ast/erfa/obl80.c delete mode 100644 ast/erfa/p06e.c delete mode 100644 ast/erfa/p2pv.c delete mode 100644 ast/erfa/p2s.c delete mode 100644 ast/erfa/pap.c delete mode 100644 ast/erfa/pas.c delete mode 100644 ast/erfa/pb06.c delete mode 100644 ast/erfa/pdp.c delete mode 100644 ast/erfa/pfw06.c delete mode 100644 ast/erfa/plan94.c delete mode 100644 ast/erfa/pm.c delete mode 100644 ast/erfa/pmat00.c delete mode 100644 ast/erfa/pmat06.c delete mode 100644 ast/erfa/pmat76.c delete mode 100644 ast/erfa/pmp.c delete mode 100644 ast/erfa/pmpx.c delete mode 100644 ast/erfa/pmsafe.c delete mode 100644 ast/erfa/pn.c delete mode 100644 ast/erfa/pn00.c delete mode 100644 ast/erfa/pn00a.c delete mode 100644 ast/erfa/pn00b.c delete mode 100644 ast/erfa/pn06.c delete mode 100644 ast/erfa/pn06a.c delete mode 100644 ast/erfa/pnm00a.c delete mode 100644 ast/erfa/pnm00b.c delete mode 100644 ast/erfa/pnm06a.c delete mode 100644 ast/erfa/pnm80.c delete mode 100644 ast/erfa/pom00.c delete mode 100644 ast/erfa/ppp.c delete mode 100644 ast/erfa/ppsp.c delete mode 100644 ast/erfa/pr00.c delete mode 100644 ast/erfa/prec76.c delete mode 100644 ast/erfa/pv2p.c delete mode 100644 ast/erfa/pv2s.c delete mode 100644 ast/erfa/pvdpv.c delete mode 100644 ast/erfa/pvm.c delete mode 100644 ast/erfa/pvmpv.c delete mode 100644 ast/erfa/pvppv.c delete mode 100644 ast/erfa/pvstar.c delete mode 100644 ast/erfa/pvtob.c delete mode 100644 ast/erfa/pvu.c delete mode 100644 ast/erfa/pvup.c delete mode 100644 ast/erfa/pvxpv.c delete mode 100644 ast/erfa/pxp.c delete mode 100644 ast/erfa/refco.c delete mode 100644 ast/erfa/rm2v.c delete mode 100644 ast/erfa/rv2m.c delete mode 100644 ast/erfa/rx.c delete mode 100644 ast/erfa/rxp.c delete mode 100644 ast/erfa/rxpv.c delete mode 100644 ast/erfa/rxr.c delete mode 100644 ast/erfa/ry.c delete mode 100644 ast/erfa/rz.c delete mode 100644 ast/erfa/s00.c delete mode 100644 ast/erfa/s00a.c delete mode 100644 ast/erfa/s00b.c delete mode 100644 ast/erfa/s06.c delete mode 100644 ast/erfa/s06a.c delete mode 100644 ast/erfa/s2c.c delete mode 100644 ast/erfa/s2p.c delete mode 100644 ast/erfa/s2pv.c delete mode 100644 ast/erfa/s2xpv.c delete mode 100644 ast/erfa/sepp.c delete mode 100644 ast/erfa/seps.c delete mode 100644 ast/erfa/sp00.c delete mode 100644 ast/erfa/starpm.c delete mode 100644 ast/erfa/starpv.c delete mode 100644 ast/erfa/sxp.c delete mode 100644 ast/erfa/sxpv.c delete mode 100644 ast/erfa/t_erfa_c.c delete mode 100644 ast/erfa/taitt.c delete mode 100644 ast/erfa/taiut1.c delete mode 100644 ast/erfa/taiutc.c delete mode 100644 ast/erfa/tcbtdb.c delete mode 100644 ast/erfa/tcgtt.c delete mode 100644 ast/erfa/tdbtcb.c delete mode 100644 ast/erfa/tdbtt.c delete mode 100644 ast/erfa/tf2a.c delete mode 100644 ast/erfa/tf2d.c delete mode 100644 ast/erfa/tr.c delete mode 100644 ast/erfa/trxp.c delete mode 100644 ast/erfa/trxpv.c delete mode 100644 ast/erfa/tttai.c delete mode 100644 ast/erfa/tttcg.c delete mode 100644 ast/erfa/tttdb.c delete mode 100644 ast/erfa/ttut1.c delete mode 100644 ast/erfa/ut1tai.c delete mode 100644 ast/erfa/ut1tt.c delete mode 100644 ast/erfa/ut1utc.c delete mode 100644 ast/erfa/utctai.c delete mode 100644 ast/erfa/utcut1.c delete mode 100644 ast/erfa/xy06.c delete mode 100644 ast/erfa/xys00a.c delete mode 100644 ast/erfa/xys00b.c delete mode 100644 ast/erfa/xys06a.c delete mode 100644 ast/erfa/zp.c delete mode 100644 ast/erfa/zpv.c delete mode 100644 ast/erfa/zr.c delete mode 100644 ast/erfa2ast.h delete mode 100644 ast/erfam.h delete mode 100644 ast/err.h delete mode 100644 ast/err_drama.c delete mode 100644 ast/err_ems.c delete mode 100644 ast/err_null.c delete mode 100644 ast/error.c delete mode 100644 ast/error.h delete mode 100644 ast/f77.h.in delete mode 100644 ast/fbox.c delete mode 100644 ast/fchannel.c delete mode 100644 ast/fchebymap.c delete mode 100644 ast/fcircle.c delete mode 100644 ast/fcmpframe.c delete mode 100644 ast/fcmpmap.c delete mode 100644 ast/fcmpregion.c delete mode 100644 ast/fdsbspecframe.c delete mode 100644 ast/fdssmap.c delete mode 100644 ast/fellipse.c delete mode 100644 ast/ferror.c delete mode 100755 ast/fetch delete mode 100644 ast/ffitschan.c delete mode 100644 ast/ffitstable.c delete mode 100644 ast/ffluxframe.c delete mode 100644 ast/fframe.c delete mode 100644 ast/fframeset.c delete mode 100644 ast/fgrismmap.c delete mode 100644 ast/finterval.c delete mode 100644 ast/fintramap.c delete mode 100644 ast/fitschan.c delete mode 100644 ast/fitschan.h delete mode 100644 ast/fitstable.c delete mode 100644 ast/fitstable.h delete mode 100644 ast/fkeymap.c delete mode 100644 ast/flutmap.c delete mode 100644 ast/fluxframe.c delete mode 100644 ast/fluxframe.h delete mode 100644 ast/fmapping.c delete mode 100644 ast/fmathmap.c delete mode 100644 ast/fmatrixmap.c delete mode 100644 ast/fnormmap.c delete mode 100644 ast/fnullregion.c delete mode 100644 ast/fobject.c delete mode 100644 ast/fpcdmap.c delete mode 100644 ast/fpermmap.c delete mode 100644 ast/fplot.c delete mode 100644 ast/fplot3d.c delete mode 100644 ast/fpointlist.c delete mode 100644 ast/fpolygon.c delete mode 100644 ast/fpolymap.c delete mode 100644 ast/fprism.c delete mode 100644 ast/frame.c delete mode 100644 ast/frame.f delete mode 100644 ast/frame.h delete mode 100644 ast/frames.pdf delete mode 100644 ast/frameset.c delete mode 100644 ast/frameset.h delete mode 100644 ast/frameset.pdf delete mode 100644 ast/fratemap.c delete mode 100644 ast/fregion.c delete mode 100644 ast/fronta.pdf delete mode 100644 ast/fronta_bw.pdf delete mode 100644 ast/frontb.pdf delete mode 100644 ast/frontb_bw.pdf delete mode 100644 ast/frontc.pdf delete mode 100644 ast/frontc_bw.pdf delete mode 100644 ast/fsalign.pdf delete mode 100644 ast/fsconvert.pdf delete mode 100644 ast/fselectormap.c delete mode 100644 ast/fsexample.pdf delete mode 100644 ast/fshiftmap.c delete mode 100644 ast/fskyframe.c delete mode 100644 ast/fslamap.c delete mode 100644 ast/fsmerge.pdf delete mode 100644 ast/fspecfluxframe.c delete mode 100644 ast/fspecframe.c delete mode 100644 ast/fspecmap.c delete mode 100644 ast/fsphmap.c delete mode 100644 ast/fsremap.pdf delete mode 100644 ast/fstc.c delete mode 100644 ast/fstccatalogentrylocation.c delete mode 100644 ast/fstcobsdatalocation.c delete mode 100644 ast/fstcresourceprofile.c delete mode 100644 ast/fstcschan.c delete mode 100644 ast/fstcsearchlocation.c delete mode 100644 ast/fswitchmap.c delete mode 100644 ast/ftable.c delete mode 100644 ast/ftemplateclass.c delete mode 100644 ast/ftimeframe.c delete mode 100644 ast/ftimemap.c delete mode 100644 ast/ftranmap.c delete mode 100644 ast/funitmap.c delete mode 100644 ast/funitnormmap.c delete mode 100644 ast/fwcsmap.c delete mode 100644 ast/fwinmap.c delete mode 100644 ast/fxmlchan.c delete mode 100644 ast/fzoommap.c delete mode 100755 ast/getatt delete mode 100644 ast/getnewversion delete mode 100644 ast/globals.c delete mode 100644 ast/globals.h delete mode 100644 ast/grf.h delete mode 100644 ast/grf3d.c delete mode 100644 ast/grf3d.h delete mode 100644 ast/grf3d_pgplot.c delete mode 100644 ast/grf_2.0.c delete mode 100644 ast/grf_3.2.c delete mode 100644 ast/grf_5.6.c delete mode 100644 ast/grf_null.c delete mode 100644 ast/grf_pgplot.c delete mode 100644 ast/gridplot.pdf delete mode 100644 ast/gridplot_bw.pdf delete mode 100644 ast/grismmap.c delete mode 100644 ast/grismmap.h delete mode 100644 ast/interval.c delete mode 100644 ast/interval.h delete mode 100644 ast/intramap.c delete mode 100644 ast/intramap.h delete mode 100644 ast/keymap.c delete mode 100644 ast/keymap.h delete mode 100644 ast/leap-seconds.png delete mode 100644 ast/loader.c delete mode 100644 ast/loader.h delete mode 100644 ast/lutmap.c delete mode 100644 ast/lutmap.h delete mode 100644 ast/makeh delete mode 100644 ast/mapping.c delete mode 100644 ast/mapping.h delete mode 100644 ast/mapping.pdf delete mode 100644 ast/mathmap.c delete mode 100644 ast/mathmap.h delete mode 100644 ast/matrixmap.c delete mode 100644 ast/matrixmap.h delete mode 100644 ast/memory.c delete mode 100644 ast/memory.h delete mode 100644 ast/normmap.c delete mode 100644 ast/normmap.h delete mode 100644 ast/nullregion.c delete mode 100644 ast/nullregion.h delete mode 100644 ast/object.c delete mode 100644 ast/object.f delete mode 100644 ast/object.h.in delete mode 100644 ast/overgrid.pdf delete mode 100644 ast/overgrid_bw.pdf delete mode 100644 ast/pal.h delete mode 100644 ast/pal/pal.h delete mode 100644 ast/pal/pal1sofa.h delete mode 100644 ast/pal/palAddet.c delete mode 100644 ast/pal/palAmpqk.c delete mode 100644 ast/pal/palCaldj.c delete mode 100644 ast/pal/palDat.c delete mode 100644 ast/pal/palDe2h.c delete mode 100644 ast/pal/palDeuler.c delete mode 100644 ast/pal/palDh2e.c delete mode 100644 ast/pal/palDjcal.c delete mode 100644 ast/pal/palDmat.c delete mode 100644 ast/pal/palDrange.c delete mode 100644 ast/pal/palDs2tp.c delete mode 100644 ast/pal/palDtp2s.c delete mode 100644 ast/pal/palDtps2c.c delete mode 100644 ast/pal/palDtt.c delete mode 100644 ast/pal/palEcmat.c delete mode 100644 ast/pal/palEqgal.c delete mode 100644 ast/pal/palEtrms.c delete mode 100644 ast/pal/palEvp.c delete mode 100644 ast/pal/palFk45z.c delete mode 100644 ast/pal/palFk524.c delete mode 100644 ast/pal/palFk54z.c delete mode 100644 ast/pal/palGaleq.c delete mode 100644 ast/pal/palGalsup.c delete mode 100644 ast/pal/palGeoc.c delete mode 100644 ast/pal/palMappa.c delete mode 100644 ast/pal/palMapqkz.c delete mode 100644 ast/pal/palOne2One.c delete mode 100644 ast/pal/palPrebn.c delete mode 100644 ast/pal/palPrec.c delete mode 100644 ast/pal/palPrenut.c delete mode 100644 ast/pal/palPvobs.c delete mode 100644 ast/pal/palRvgalc.c delete mode 100644 ast/pal/palRvlg.c delete mode 100644 ast/pal/palRvlsrd.c delete mode 100644 ast/pal/palRvlsrk.c delete mode 100644 ast/pal/palSubet.c delete mode 100644 ast/pal/palSupgal.c delete mode 100644 ast/pal/palmac.h delete mode 100644 ast/pal2ast.h delete mode 100644 ast/palwrap.c delete mode 100644 ast/parallel.pdf delete mode 100644 ast/pcdmap.c delete mode 100644 ast/pcdmap.h delete mode 100644 ast/permmap.c delete mode 100644 ast/permmap.h delete mode 100644 ast/pg3d.h delete mode 100644 ast/plot.c delete mode 100644 ast/plot.f delete mode 100644 ast/plot.h delete mode 100644 ast/plot3d.c delete mode 100644 ast/plot3d.h delete mode 100644 ast/pointlist.c delete mode 100644 ast/pointlist.h delete mode 100644 ast/pointset.c delete mode 100644 ast/pointset.h delete mode 100644 ast/polygon.c delete mode 100644 ast/polygon.h delete mode 100644 ast/polymap.c delete mode 100644 ast/polymap.h delete mode 100755 ast/prepare_all delete mode 100755 ast/prepare_docs delete mode 100755 ast/prepare_hyperdocs delete mode 100755 ast/prepare_release delete mode 100644 ast/prism.c delete mode 100644 ast/prism.h delete mode 100644 ast/proj.c delete mode 100644 ast/proj.h delete mode 100644 ast/ratemap.c delete mode 100644 ast/ratemap.h delete mode 100644 ast/region.c delete mode 100644 ast/region.h delete mode 100755 ast/selectfc delete mode 100644 ast/selectormap.c delete mode 100644 ast/selectormap.h delete mode 100644 ast/series.pdf delete mode 100644 ast/shiftmap.c delete mode 100644 ast/shiftmap.h delete mode 100644 ast/simpexamp.pdf delete mode 100644 ast/skyaxis.c delete mode 100644 ast/skyaxis.h delete mode 100644 ast/skyframe.c delete mode 100644 ast/skyframe.h delete mode 100644 ast/slamap.c delete mode 100644 ast/slamap.h delete mode 100644 ast/specfluxframe.c delete mode 100644 ast/specfluxframe.h delete mode 100644 ast/specframe.c delete mode 100644 ast/specframe.h delete mode 100644 ast/specmap.c delete mode 100644 ast/specmap.h delete mode 100644 ast/sphmap.c delete mode 100644 ast/sphmap.h delete mode 100644 ast/stc.c delete mode 100644 ast/stc.h delete mode 100644 ast/stccatalogentrylocation.c delete mode 100644 ast/stccatalogentrylocation.h delete mode 100644 ast/stcobsdatalocation.c delete mode 100644 ast/stcobsdatalocation.h delete mode 100644 ast/stcresourceprofile.c delete mode 100644 ast/stcresourceprofile.h delete mode 100644 ast/stcs-ex1.txt delete mode 100644 ast/stcschan-demo1.c delete mode 100644 ast/stcschan-demo2.c delete mode 100644 ast/stcschan-demo3.c delete mode 100644 ast/stcschan-demo4.c delete mode 100644 ast/stcschan-demo5.c delete mode 100644 ast/stcschan.c delete mode 100644 ast/stcschan.h delete mode 100644 ast/stcsearchlocation.c delete mode 100644 ast/stcsearchlocation.h delete mode 100644 ast/sun210_figures/cmpframe.pdf delete mode 100644 ast/sun210_figures/complex.pdf delete mode 100644 ast/sun210_figures/frames.pdf delete mode 100644 ast/sun210_figures/frameset.pdf delete mode 100644 ast/sun210_figures/fronta.pdf delete mode 100644 ast/sun210_figures/fronta_bw.pdf delete mode 100644 ast/sun210_figures/frontb.pdf delete mode 100644 ast/sun210_figures/frontb_bw.pdf delete mode 100644 ast/sun210_figures/frontc.pdf delete mode 100644 ast/sun210_figures/frontc_bw.pdf delete mode 100644 ast/sun210_figures/fsalign.pdf delete mode 100644 ast/sun210_figures/fsconvert.pdf delete mode 100644 ast/sun210_figures/fsexample.pdf delete mode 100644 ast/sun210_figures/fsmerge.pdf delete mode 100644 ast/sun210_figures/fsremap.pdf delete mode 100644 ast/sun210_figures/gridplot.pdf delete mode 100644 ast/sun210_figures/gridplot_bw.pdf delete mode 100644 ast/sun210_figures/mapping.pdf delete mode 100644 ast/sun210_figures/overgrid.pdf delete mode 100644 ast/sun210_figures/overgrid_bw.pdf delete mode 100644 ast/sun210_figures/parallel.pdf delete mode 100644 ast/sun210_figures/series.pdf delete mode 100644 ast/sun210_figures/simpexamp.pdf delete mode 100644 ast/sun211_figures/cmpframe.pdf delete mode 100644 ast/sun211_figures/complex.pdf delete mode 100644 ast/sun211_figures/frames.pdf delete mode 100644 ast/sun211_figures/frameset.pdf delete mode 100644 ast/sun211_figures/fronta.pdf delete mode 100644 ast/sun211_figures/fronta_bw.pdf delete mode 100644 ast/sun211_figures/frontb.pdf delete mode 100644 ast/sun211_figures/frontb_bw.pdf delete mode 100644 ast/sun211_figures/frontc.pdf delete mode 100644 ast/sun211_figures/frontc_bw.pdf delete mode 100644 ast/sun211_figures/fsalign.pdf delete mode 100644 ast/sun211_figures/fsconvert.pdf delete mode 100644 ast/sun211_figures/fsexample.pdf delete mode 100644 ast/sun211_figures/fsmerge.pdf delete mode 100644 ast/sun211_figures/fsremap.pdf delete mode 100644 ast/sun211_figures/gridplot.pdf delete mode 100644 ast/sun211_figures/gridplot_bw.pdf delete mode 100644 ast/sun211_figures/mapping.pdf delete mode 100644 ast/sun211_figures/overgrid.pdf delete mode 100644 ast/sun211_figures/overgrid_bw.pdf delete mode 100644 ast/sun211_figures/parallel.pdf delete mode 100644 ast/sun211_figures/series.pdf delete mode 100644 ast/sun211_figures/simpexamp.pdf delete mode 100644 ast/sun_master.tex delete mode 100644 ast/switchmap.c delete mode 100644 ast/switchmap.h delete mode 100644 ast/table.c delete mode 100644 ast/table.h delete mode 100644 ast/templateclass.README delete mode 100644 ast/templateclass.c delete mode 100644 ast/templateclass.h delete mode 100644 ast/timeframe.c delete mode 100644 ast/timeframe.h delete mode 100644 ast/timemap.c delete mode 100644 ast/timemap.h delete mode 100644 ast/tpn.c delete mode 100644 ast/tranmap.c delete mode 100644 ast/tranmap.h delete mode 100644 ast/unit.c delete mode 100644 ast/unit.h delete mode 100644 ast/unitmap.c delete mode 100644 ast/unitmap.h delete mode 100644 ast/unitnormmap.c delete mode 100644 ast/unitnormmap.h delete mode 100644 ast/version.h.in delete mode 100644 ast/wcsmap.c delete mode 100644 ast/wcsmap.h delete mode 100644 ast/wcsmath.h delete mode 100644 ast/wcstrig.c delete mode 100644 ast/wcstrig.h delete mode 100644 ast/winmap.c delete mode 100644 ast/winmap.h delete mode 100644 ast/xml.c delete mode 100644 ast/xml.h delete mode 100644 ast/xmlchan.c delete mode 100644 ast/xmlchan.h delete mode 100644 ast/zoommap.c delete mode 100644 ast/zoommap.h diff --git a/ast/.gitignore b/ast/.gitignore deleted file mode 100644 index 742b687..0000000 --- a/ast/.gitignore +++ /dev/null @@ -1,65 +0,0 @@ -/AST_PAR -/addversion -/ast.h -/astbad -/ast_cpp -/ast_link -/ast_link_adam -/ast_test -/builddocs -/f77.h -/object.h -/sun210.tex -/sun210.pdf -/sun211.tex -/sun211.pdf -/version.h -/*.trs -*.safe -*.lo -*.o -*.la -.deps/ -.libs/ -.bug -AST_ERR -Makefile -Makefile.in -aclocal.m4 -ast_err.h -ast_test.log -autom4te.cache/ -build-aux/ -cminpack/.deps/ -cminpack/.dirstamp -componentinfo.dtd -config.h -config.h.in -config.log -config.status -configure -experiments -fac_1521_err -libtool -stamp-h1 -starconf.status -sun210.htx/ -sun210.htx_tar -sun210.lof -sun210.log -sun210.out -sun210.toc -sun211.htx/ -sun211.htx_tar -sun211.lof -sun211.log -sun211.out -sun211.toc -test-suite.log -make.log -make.log.err -*~ -/ast_tester/*.ps -/ast_tester/fred.tmp -/ast_tester/fred.txt -/ast_tester/fred2.txt diff --git a/ast/AST_to_do b/ast/AST_to_do deleted file mode 100644 index a1faf93..0000000 --- a/ast/AST_to_do +++ /dev/null @@ -1,23 +0,0 @@ -Things to do in AST (not necesarily priority order): - -Added 17/1/05: - -Done 17/1/05 - Add Prism class to CVS -Done 17/1/05 - Correct void * arithmetic in keymap.c -- Changing version in configure.ac and then doing make does not result in - version.h being re-made. -Done 29/6/05 - Complete STC classes -Done 29/6/05 - Integrate TimeFrame -- Move observer position attributes into Frame class -- Extend FluxFrame to describe magnitudes and antenna temperature. -- Write SOAP service to show off STC functionality -- Add AzEl system to SkyFrame -- Flux conservation in Mapping resample routines -- Write proper tutorial documentation for new classes (regions, STC, fluxframe, etc). -- Add support for FITS-WCS paper III "-TAB" algorithm code to FitsChan -- Add support for HEALPIX ?? (e.g. see http://www.spacebanter.com/showthread.php?p=336715#post336715) -- Pure Java version -- Monitor progresss on FITS-WCS paper IV (and eventually paper V) -- Extend ATOOLS to cover Regions, TimeFrame & STC -- Speed up the STC facilities of XmlCHan and Stc (astSimplify is particularly - slow) diff --git a/ast/COPYING b/ast/COPYING deleted file mode 100644 index 94a9ed0..0000000 --- a/ast/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/ast/COPYING.LESSER b/ast/COPYING.LESSER deleted file mode 100644 index 65c5ca8..0000000 --- a/ast/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/ast/COPYING.LIB b/ast/COPYING.LIB deleted file mode 100644 index eb685a5..0000000 --- a/ast/COPYING.LIB +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/ast/Ers.h b/ast/Ers.h deleted file mode 100644 index a66fa82..0000000 --- a/ast/Ers.h +++ /dev/null @@ -1,245 +0,0 @@ -#ifndef ERSINC -#define ERSINC -#ifdef __cplusplus -extern "C" { -#endif - - -/* E r s . h - - * Module name: - Ers.h - - * Function: - Function header for the Ers routines - - * Description: - Should be included by all files using the Ers routines. - - * Language: - C - - * Support: Tony Farrell, AAO - - * Copyright (c) Anglo-Australian Telescope Board, 1995. - Not to be used for commercial purposes without AATB permission. - - * @(#) $Id: Ers.h,v 1.3 2005/05/17 22:21:19 rkackley Exp $ - - - * History: - 04-Aug-1992 - TJF - Original version - 25-Sep-1992 - TJF - Update comments - 06-Oct-1992 - TJF - Rewrite for complete Ers package. - 04-Aug-1993 - TJF - maxsize argument to ErsSPrintf needs a type - 28-Sep-1993 - TJF - Use GNUC attribute to flag the ers calls - as printf style. Use drama.h for configuration - stuff. - - 29-Sep-1993 - TJF - Add Sccs id - 06-Mar-1994 - TJF - Add Task Id stuff. - 05-Feb-1995 - TJF - Add BROADCAST flag - 06-Aug-1996 - TJF - Add const to strings arguments of ErsVSPrintf - 30-May-2001 - TJF - Add ErsSetLogRoutine. - 15-Jun-2001 - TJF - Add ErsGetTaskId. - {@change entry@} - - - */ - -#ifdef ERS_STANDALONE -/* - * DRAMA macros and types used by Ers. They are defined here when we - * are building ers standalone. - */ -#define DVOID void -#define DVOIDP void * -#define DPUBLIC extern -#define DPRIVATE static -#define DCONSTV const -#define DCONSTR const -#define STATUS__OK 0 -#define DPROTOTYPES_OK -#define DFLOAT_OK -#define DCONST_I -typedef long int StatusType; -#define StatusOkP(_value_) (*(_value_) == STATUS__OK) -#else -/* - * Include the drama.h file for configuration macros. - */ - -#include "drama.h" - -#include "status.h" /* For StatusType etc */ -#endif - -/* - * Get around problems in Sparc include files, they are not ANSI compatible - */ -#if defined(__sparc__) && !defined(sparc) -#define sparc 1 -#endif - -/* - * Floating point stuff. Only used in ErsVSPrintf. - */ -#ifdef DFLOAT_OK -/* - * These values taken from bsd floatio.h - */ -# define ERS_MAXEXP 308 -# define ERS_MAXFRACT 39 -#endif - -/* - * Constants - */ - -#define ERS_C_LEN 200 /* Maximum length of reported messages */ -#define ERS_C_MAXMSG 30 /* Maximum number of reported messages */ - -#define ERS_M_NOFMT (1<<0) /* Message flag masks */ -#define ERS_M_HIGHLIGHT (1<<1) -#define ERS_M_BELL (1<<2) -#define ERS_M_ALARM (1<<3) -#define ERS_M_BROADCAST (1<<4) - - -/* - * This structure is used to store details of a message - */ -typedef struct { - StatusType mesStatus; /* Status of message */ - unsigned int context; /* Context message was written at */ - int flags; /* Message flags */ - char message[ERS_C_LEN]; /* The formated message */ - } ErsMessageType; - -typedef DVOIDP ErsTaskIdType; - -#ifdef DPROTOTYPES_OK -/* - * This type is that required for log routines - called on each call to - * ErsRep with details of a single message. - * - * The argument "logArg" is a user value supplied when ErsStart is called. - * It enables the user to pass any appropriate value to the log routine. - */ -typedef DVOID (*ErsLogRoutineType)( - DVOIDP logArg, /* Supplied to ErsStart */ - DCONSTV ErsMessageType * message,/* The message */ - StatusType * status); -/* - * The type is that requried for the output routine - called to output - * the messages to the user. An array of message may be output by one - * call, with count being the number of message to output. - * - * The argument "outArg" is a user value supplied when ErsStart is called. - * It enables the user to pass any appropriate value to the log routine. - */ -typedef DVOID (*ErsOutRoutineType)( - DVOIDP outArg, /* Supplied to ErsStart */ - unsigned int count, /* Number of messages */ - DCONSTV ErsMessageType messages[],/* Array of messages */ - StatusType * status); - - -/* - * Function prototypes. - * - * - * We can't define these prorotype in the Ers main module unless we have - * stdarg.h. - */ -#if !defined(ERS_MAIN) || defined(DSTDARG__OK) - DPUBLIC DVOID ErsRep(DCONSTV int flags, StatusType * status, - DCONSTV char * string , ...) -#ifdef __GNUC__ - __attribute__ ((format (printf, 3, 4))) -#endif - ; - DPUBLIC DVOID ErsOut(DCONSTV int flags, StatusType * status, - DCONSTV char * string, ...) -#ifdef __GNUC__ - __attribute__ ((format (printf, 3, 4))) -#endif - ; - DPUBLIC int ErsSPrintf(DCONSTV int maxLength, - char *string, - DCONSTV char * fmt,...) -#ifdef __GNUC__ - __attribute__ ((format (printf, 3, 4))) -#endif - ; - -#endif /* DSTDARG_OK */ - -DPUBLIC ErsTaskIdType ErsStart( - ErsOutRoutineType outRoutine, - DVOIDP outArg, - ErsLogRoutineType logRoutine, - DVOIDP logArg, - StatusType * status); -DPUBLIC DVOID ErsStop(StatusType * status); -DPUBLIC DVOID ErsPush(void); -DPUBLIC DVOID ErsAnnul(StatusType * status); -DPUBLIC DVOID ErsFlush(StatusType * status); -DPUBLIC DVOID ErsClear(StatusType * status); -DPUBLIC DVOID ErsPop(void); -DPUBLIC DVOID ErsSetLogRoutine( - ErsLogRoutineType logRoutine, - DVOIDP logArg, - ErsLogRoutineType *oldLogRoutine, - DVOIDP *oldLogArg, - StatusType * status); - -DPUBLIC ErsTaskIdType ErsGetTaskId(StatusType *status); -DPUBLIC DVOID ErsEnableTask(ErsTaskIdType TaskId, - ErsTaskIdType * SavedTaskId); -DPUBLIC DVOID ErsRestoreTask(ErsTaskIdType TaskId); - - -#ifdef DSTDARG_OK -# include -#else -# include -#endif -DPUBLIC int ErsVSPrintf( - int maxLength, - char *string , - DCONSTV char * fmt0, - va_list ap); -#else -/* Don't use prorotypes */ -typedef DVOID (*ErsLogRoutineType)(); -typedef DVOID (*ErsOutRoutineType)(); - -DPUBLIC DVOID ErsRep(); -DPUBLIC DVOID ErsOut(); - -DPUBLIC DVOID ErsStart(); -DPUBLIC DVOID ErsStop(); -DPUBLIC DVOID ErsPush(); -DPUBLIC DVOID ErsPop(); -DPUBLIC DVOID ErsAnnul(); -DPUBLIC DVOID ErsFlush(); -DPUBLIC DVOID ErsClear(); -DPUBLIC DVOID ErsSetLogRoutine(); -DPUBLIC ErsTaskIdType ErsGetTaskId(); - -DPUBLIC int ErsVSPrintf(); -DPUBLIC int ErsSPrintf(); - -DPUBLIC DVOID ErsEnableTask(); -DPUBLIC DVOID ErsRestoreTask(); - - -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ast/GRF_PAR b/ast/GRF_PAR deleted file mode 100644 index 0c1d9aa..0000000 --- a/ast/GRF_PAR +++ /dev/null @@ -1,124 +0,0 @@ -*+ -* Name: -* GRF_PAR - -* Purpose: -* Define the constants needed to implement Fortran GRF routines. - -* Language: -* Fortran 77 - -* Type of Module: -* Include file. - -* Description: -* This file contains definitions which are required by Fortran 77 -* programs which implement their own grf routines (routines for -* drawing graphics primitive used by the AST Plot class). - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 13-JUN-2001 (DSB): -* Original version. -*- - -* Values identifying different graphics attributes. - INTEGER GRF__STYLE - PARAMETER ( GRF__STYLE = 0 ) - - INTEGER GRF__WIDTH - PARAMETER ( GRF__WIDTH = 1 ) - - INTEGER GRF__SIZE - PARAMETER ( GRF__SIZE = 2 ) - - INTEGER GRF__FONT - PARAMETER ( GRF__FONT = 3 ) - - INTEGER GRF__COLOUR - PARAMETER ( GRF__COLOUR = 4 ) - -* Values identifying different graphics primatives. - INTEGER GRF__TEXT - PARAMETER ( GRF__TEXT = 0 ) - - INTEGER GRF__LINE - PARAMETER ( GRF__LINE = 1 ) - - INTEGER GRF__MARK - PARAMETER ( GRF__MARK = 2 ) - -* The number of different graphics attributes. - INTEGER GRF__NATTR - PARAMETER ( GRF__NATTR = 5 ) - -* Values identifying capabilities. - INTEGER GRF__ESC - PARAMETER ( GRF__ESC = 0 ) - - INTEGER GRF__MJUST - PARAMETER ( GRF__MJUST = 1 ) - - INTEGER GRF__SCALES - PARAMETER ( GRF__SCALES = 2 ) - -* Values identifying types of graphics escape sequence - INTEGER GRF__ESPER - PARAMETER ( GRF__ESPER = 1 ) - - INTEGER GRF__ESSUP - PARAMETER ( GRF__ESSUP = 2 ) - - INTEGER GRF__ESSUB - PARAMETER ( GRF__ESSUB = 3 ) - - INTEGER GRF__ESGAP - PARAMETER ( GRF__ESGAP = 4 ) - - INTEGER GRF__ESBAC - PARAMETER ( GRF__ESBAC = 5 ) - - INTEGER GRF__ESSIZ - PARAMETER ( GRF__ESSIZ = 6 ) - - INTEGER GRF__ESWID - PARAMETER ( GRF__ESWID = 7 ) - - INTEGER GRF__ESFON - PARAMETER ( GRF__ESFON = 8 ) - - INTEGER GRF__ESCOL - PARAMETER ( GRF__ESCOL = 9 ) - - INTEGER GRF__ESSTY - PARAMETER ( GRF__ESSTY = 10 ) - - INTEGER GRF__ESPOP - PARAMETER ( GRF__ESPOP = 11 ) - - INTEGER GRF__ESPSH - PARAMETER ( GRF__ESPSH = 12 ) - - diff --git a/ast/Makefile.am b/ast/Makefile.am deleted file mode 100644 index 56096e7..0000000 --- a/ast/Makefile.am +++ /dev/null @@ -1,828 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# First declare various groups of files. These were initially extracted -# from the grp.make file, as constructed by the SDT newdev command -GRP_C_ROUTINES = \ - axis.c \ - box.c \ - channel.c \ - chebymap.c \ - circle.c \ - cmpframe.c \ - cmpmap.c \ - cmpregion.c \ - dsbspecframe.c \ - dssmap.c \ - ellipse.c \ - error.c \ - fitschan.c \ - fitstable.c \ - fluxframe.c \ - frame.c \ - frameset.c \ - globals.c \ - grismmap.c \ - interval.c \ - intramap.c \ - keymap.c \ - loader.c \ - lutmap.c \ - mapping.c \ - mathmap.c \ - matrixmap.c \ - memory.c \ - normmap.c \ - nullregion.c \ - object.c \ - pcdmap.c \ - permmap.c \ - plot.c \ - plot3d.c \ - pointlist.c \ - pointset.c \ - polygon.c \ - polymap.c \ - prism.c \ - ratemap.c \ - region.c \ - selectormap.c \ - shiftmap.c \ - skyaxis.c \ - skyframe.c \ - slamap.c \ - specfluxframe.c \ - specframe.c \ - specmap.c \ - sphmap.c \ - stc.c \ - stccatalogentrylocation.c \ - stcobsdatalocation.c \ - stcresourceprofile.c \ - stcschan.c \ - stcsearchlocation.c \ - switchmap.c \ - table.c \ - timeframe.c \ - timemap.c \ - tranmap.c \ - unit.c \ - unitmap.c \ - unitnormmap.c \ - wcsmap.c \ - winmap.c \ - xml.c \ - xmlchan.c \ - zoommap.c - - -# The C source files required for the Fortran interface -if !NOFORTRAN -F_C_ROUTINES = \ - c2f77.c \ - fbox.c \ - fchannel.c \ - fchebymap.c \ - fcircle.c \ - fcmpframe.c \ - fcmpmap.c \ - fcmpregion.c \ - fdsbspecframe.c \ - fdssmap.c \ - fellipse.c \ - ferror.c \ - ffitschan.c \ - ffitstable.c \ - ffluxframe.c \ - fframe.c \ - fframeset.c \ - fgrismmap.c \ - finterval.c \ - fintramap.c \ - fkeymap.c \ - flutmap.c \ - fmapping.c \ - fmathmap.c \ - fmatrixmap.c \ - fnormmap.c \ - fnullregion.c \ - fobject.c \ - fpcdmap.c \ - fpermmap.c \ - fplot.c \ - fplot3d.c \ - fpointlist.c \ - fpolygon.c \ - fpolymap.c \ - fprism.c \ - fratemap.c \ - fregion.c \ - fselectormap.c \ - fshiftmap.c \ - fskyframe.c \ - fslamap.c \ - fspecfluxframe.c \ - fspecframe.c \ - fspecmap.c \ - fsphmap.c \ - fstc.c \ - fstccatalogentrylocation.c \ - fstcobsdatalocation.c \ - fstcresourceprofile.c \ - fstcschan.c \ - fstcsearchlocation.c \ - fswitchmap.c \ - ftable.c \ - ftimeframe.c \ - ftimemap.c \ - ftranmap.c \ - funitmap.c \ - funitnormmap.c \ - fwcsmap.c \ - fwinmap.c \ - fxmlchan.c \ - fzoommap.c -else -F_C_ROUTINES = -endif - -# Header files which contribute to the "ast.h" file, organised to correspond -# with the class hierarchy. -AST_H_FILES = \ - xml.h \ - wcstrig.h \ - proj.h \ - memory.h \ - error.h \ - globals.h \ - unit.h \ - ast_err.h \ - version.h \ - object.h \ - keymap.h \ - table.h \ - fitstable.h \ - pointset.h \ - axis.h \ - skyaxis.h \ - mapping.h \ - cmpmap.h \ - dssmap.h \ - grismmap.h \ - intramap.h \ - lutmap.h \ - mathmap.h \ - matrixmap.h \ - pcdmap.h \ - permmap.h \ - polymap.h \ - chebymap.h \ - ratemap.h \ - normmap.h \ - shiftmap.h \ - slamap.h \ - specmap.h \ - sphmap.h \ - timemap.h \ - selectormap.h \ - switchmap.h \ - tranmap.h \ - unitmap.h \ - unitnormmap.h \ - wcsmap.h \ - winmap.h \ - zoommap.h \ - frame.h \ - cmpframe.h \ - specfluxframe.h \ - fluxframe.h \ - frameset.h \ - plot.h \ - plot3d.h \ - skyframe.h \ - specframe.h \ - dsbspecframe.h \ - region.h \ - box.h \ - circle.h \ - cmpregion.h \ - ellipse.h \ - interval.h \ - nullregion.h \ - pointlist.h \ - polygon.h \ - prism.h \ - stc.h \ - stcresourceprofile.h \ - stcsearchlocation.h \ - stccatalogentrylocation.h \ - stcobsdatalocation.h \ - timeframe.h \ - channel.h \ - fitschan.h \ - stcschan.h \ - xmlchan.h - -# All the (C) include files required to build the library. -GRP_C_INCLUDE_FILES = \ - $(AST_H_FILES) \ - ems.h \ - err.h \ - Ers.h \ - f77.h \ - grf.h \ - grf3d.h \ - pg3d.h \ - loader.h \ - pal2ast.h \ - skyaxis.h \ - erfa2ast.h \ - stc.h \ - stcresourceprofile.h \ - stcsearchlocation.h \ - stccatalogentrylocation.h \ - stcobsdatalocation.h \ - wcsmath.h \ - wcstrig.h \ - xmlchan.h - -if !NOFORTRAN -F_C_INCLUDE_FILES = \ - c2f77.h - -# The following list should include AST_PAR, but that must not be -# distributed, and so it is listed separately in -# nodist_libast_la_SOURCES below. -GRP_F_INCLUDE_FILES = \ - GRF_PAR \ - AST_ERR - -else -F_C_INCLUDE_FILES = -GRP_F_INCLUDE_FILES = -endif - -# If we have no Fortran we are not building f77.h and we probably -# do not want a Fortran runtime. This requires that PGPLOT is disabled. -# We replace it with the stub GRF interface. An alternative would -# be to have the PGPLOT wrappers use a preprocessor symbol to build -# the pgplot to always error if used. -if !NOFORTRAN -GRF_PGPLOT_SOURCES = \ - grf_pgplot.c -GRF3D_PGPLOT_SOURCES = \ - grf3d_pgplot.c -else -GRF_PGPLOT_SOURCES = \ - grf_5.6.c -GRF3D_PGPLOT_SOURCES = \ - grf3d.c -endif - - -## Following declaration isn't used -## LATEX_DOCUMENTATION_FILES = \ -## sun210.tex \ -## sun211.tex - -DOCUMENTATION_PRODUCTS = $(PAPER_DOCUMENTATION) $(HYPER_DOCUMENTATION) -PAPER_DOCUMENTATION = sun210.tex sun211.tex sun210.pdf sun211.pdf -HYPER_DOCUMENTATION = sun210.htx_tar sun211.htx_tar - -PDF_FIGURES = \ - cmpframe.pdf \ - complex.pdf \ - frames.pdf \ - frameset.pdf \ - fronta.pdf \ - fronta_bw.pdf \ - frontb.pdf \ - frontb_bw.pdf \ - frontc.pdf \ - frontc_bw.pdf \ - fsalign.pdf \ - fsconvert.pdf \ - fsexample.pdf \ - fsmerge.pdf \ - fsremap.pdf \ - gridplot.pdf \ - gridplot_bw.pdf \ - mapping.pdf \ - overgrid.pdf \ - overgrid_bw.pdf \ - parallel.pdf \ - series.pdf \ - simpexamp.pdf - -WCSLIB_FILES = \ - proj.c \ - tpn.c \ - proj.h \ - wcstrig.c \ - wcsmath.h \ - wcstrig.h - -STAR_PAL_FILES = \ - pal/pal.h \ - pal/palAddet.c \ - pal/palAmpqk.c \ - pal/palCaldj.c \ - pal/palDat.c \ - pal/palDe2h.c \ - pal/palDeuler.c \ - pal/palDh2e.c \ - pal/palDjcal.c \ - pal/palDmat.c \ - pal/palDrange.c \ - pal/palDs2tp.c \ - pal/palDtp2s.c \ - pal/palDtps2c.c \ - pal/palDtt.c \ - pal/palEcmat.c \ - pal/palEqgal.c \ - pal/palEtrms.c \ - pal/palEvp.c \ - pal/palFk45z.c \ - pal/palFk524.c \ - pal/palFk54z.c \ - pal/palGaleq.c \ - pal/palGalsup.c \ - pal/palMappa.c \ - pal/palMapqkz.c \ - pal/palOne2One.c \ - pal/palPrebn.c \ - pal/palPrec.c \ - pal/palPrenut.c \ - pal/palPvobs.c \ - pal/palRvgalc.c \ - pal/palRvlg.c \ - pal/palRvlsrd.c \ - pal/palRvlsrk.c \ - pal/palSubet.c \ - pal/palSupgal.c \ - pal/pal1sofa.h \ - pal/palmac.h - -ERFA_FILES = \ - erfa/00READ.ME \ - erfa/erfa.h \ - erfa/erfam.h \ - erfa/a2af.c \ - erfa/a2tf.c \ - erfa/af2a.c \ - erfa/anp.c \ - erfa/anpm.c \ - erfa/bi00.c \ - erfa/bp00.c \ - erfa/bp06.c \ - erfa/bpn2xy.c \ - erfa/c2i00a.c \ - erfa/c2i00b.c \ - erfa/c2i06a.c \ - erfa/c2ibpn.c \ - erfa/c2ixy.c \ - erfa/c2ixys.c \ - erfa/c2s.c \ - erfa/c2t00a.c \ - erfa/c2t00b.c \ - erfa/c2t06a.c \ - erfa/c2tcio.c \ - erfa/c2teqx.c \ - erfa/c2tpe.c \ - erfa/c2txy.c \ - erfa/cal2jd.c \ - erfa/cp.c \ - erfa/cpv.c \ - erfa/cr.c \ - erfa/d2dtf.c \ - erfa/d2tf.c \ - erfa/dat.c \ - erfa/dtdb.c \ - erfa/dtf2d.c \ - erfa/ee00.c \ - erfa/ee00a.c \ - erfa/ee00b.c \ - erfa/ee06a.c \ - erfa/eect00.c \ - erfa/eform.c \ - erfa/eo06a.c \ - erfa/eors.c \ - erfa/epb.c \ - erfa/epb2jd.c \ - erfa/epj.c \ - erfa/epj2jd.c \ - erfa/epv00.c \ - erfa/eqeq94.c \ - erfa/era00.c \ - erfa/fad03.c \ - erfa/fae03.c \ - erfa/faf03.c \ - erfa/faju03.c \ - erfa/fal03.c \ - erfa/falp03.c \ - erfa/fama03.c \ - erfa/fame03.c \ - erfa/fane03.c \ - erfa/faom03.c \ - erfa/fapa03.c \ - erfa/fasa03.c \ - erfa/faur03.c \ - erfa/fave03.c \ - erfa/fk52h.c \ - erfa/fk5hip.c \ - erfa/fk5hz.c \ - erfa/fw2m.c \ - erfa/fw2xy.c \ - erfa/gc2gd.c \ - erfa/gc2gde.c \ - erfa/gd2gc.c \ - erfa/gd2gce.c \ - erfa/gmst00.c \ - erfa/gmst06.c \ - erfa/gmst82.c \ - erfa/gst00a.c \ - erfa/gst00b.c \ - erfa/gst06.c \ - erfa/gst06a.c \ - erfa/gst94.c \ - erfa/h2fk5.c \ - erfa/hfk5z.c \ - erfa/ir.c \ - erfa/jd2cal.c \ - erfa/jdcalf.c \ - erfa/num00a.c \ - erfa/num00b.c \ - erfa/num06a.c \ - erfa/numat.c \ - erfa/nut00a.c \ - erfa/nut00b.c \ - erfa/nut06a.c \ - erfa/nut80.c \ - erfa/nutm80.c \ - erfa/obl06.c \ - erfa/obl80.c \ - erfa/p06e.c \ - erfa/p2pv.c \ - erfa/p2s.c \ - erfa/pap.c \ - erfa/pas.c \ - erfa/pb06.c \ - erfa/pdp.c \ - erfa/pfw06.c \ - erfa/plan94.c \ - erfa/pm.c \ - erfa/pmat00.c \ - erfa/pmat06.c \ - erfa/pmat76.c \ - erfa/pmp.c \ - erfa/pn.c \ - erfa/pn00.c \ - erfa/pn00a.c \ - erfa/pn00b.c \ - erfa/pn06.c \ - erfa/pn06a.c \ - erfa/pnm00a.c \ - erfa/pnm00b.c \ - erfa/pnm06a.c \ - erfa/pnm80.c \ - erfa/pom00.c \ - erfa/ppp.c \ - erfa/ppsp.c \ - erfa/pr00.c \ - erfa/prec76.c \ - erfa/pv2p.c \ - erfa/pv2s.c \ - erfa/pvdpv.c \ - erfa/pvm.c \ - erfa/pvmpv.c \ - erfa/pvppv.c \ - erfa/pvstar.c \ - erfa/pvu.c \ - erfa/pvup.c \ - erfa/pvxpv.c \ - erfa/pxp.c \ - erfa/refco.c \ - erfa/rm2v.c \ - erfa/rv2m.c \ - erfa/rx.c \ - erfa/rxp.c \ - erfa/rxpv.c \ - erfa/rxr.c \ - erfa/ry.c \ - erfa/rz.c \ - erfa/s00.c \ - erfa/s00a.c \ - erfa/s00b.c \ - erfa/s06.c \ - erfa/s06a.c \ - erfa/s2c.c \ - erfa/s2p.c \ - erfa/s2pv.c \ - erfa/s2xpv.c \ - erfa/sepp.c \ - erfa/seps.c \ - erfa/sp00.c \ - erfa/starpm.c \ - erfa/starpv.c \ - erfa/sxp.c \ - erfa/sxpv.c \ - erfa/taitt.c \ - erfa/taiut1.c \ - erfa/taiutc.c \ - erfa/tcbtdb.c \ - erfa/tcgtt.c \ - erfa/tdbtcb.c \ - erfa/tdbtt.c \ - erfa/tf2a.c \ - erfa/tf2d.c \ - erfa/tr.c \ - erfa/trxp.c \ - erfa/trxpv.c \ - erfa/tttai.c \ - erfa/tttcg.c \ - erfa/tttdb.c \ - erfa/ttut1.c \ - erfa/ut1tai.c \ - erfa/ut1tt.c \ - erfa/ut1utc.c \ - erfa/utctai.c \ - erfa/utcut1.c \ - erfa/xy06.c \ - erfa/xys00a.c \ - erfa/xys00b.c \ - erfa/xys06a.c \ - erfa/zp.c \ - erfa/zpv.c \ - erfa/zr.c - -PAL_FILES = \ - palwrap.c \ - pal.h \ - erfa.h \ - erfam.h - -CMINPACK_FILES = \ - cminpack/cminpack.h \ - cminpack/cminpackP.h \ - cminpack/lmder1.c \ - cminpack/lmder.c \ - cminpack/dpmpar.c \ - cminpack/enorm.c \ - cminpack/qrfac.c \ - cminpack/lmpar.c \ - cminpack/qrsolv.c - -bin_SCRIPTS = ast_link -dist_bin_SCRIPTS = ast_link_adam -noinst_SCRIPTS = ast_cpp -dist_noinst_SCRIPTS = makeh -# Scripts are not distributed by default (since they might be derived objects) -# Add these to the distribution below. In fact, it would be useful -# and straightforward to make ast_link{,_adam} derived, since they -# could then have installation directories painlessly edited in to -# them. This might be a requirement for scripts which supported -# linking against shared libraries. - -# Headers required by library users. Both of the following lines -# indicate headers which are installed. -include_HEADERS = GRF_PAR grf.h grf3d.h -# Following are generated, so should not be distributed. -nodist_include_HEADERS = ast.h AST_PAR -include_MESSAGES = AST_ERR ast_err.h - -if EXTERNAL_PAL -PAL_LIB = -else -PAL_LIB = libast_pal.la -endif - -lib_LTLIBRARIES = \ - $(PAL_LIB) \ - libast.la \ - libast_err.la \ - libast_ems.la \ - libast_drama.la \ - libast_grf3d.la \ - libast_grf_2.0.la \ - libast_grf_3.2.la \ - libast_grf_5.6.la \ - libast_pgplot.la \ - libast_pgplot3d.la - -stardocs_DATA = @STAR_LATEX_DOCUMENTATION@ -dist_starnews_DATA = ast.news -dist_pkgdata_DATA = COPYING COPYING.LESSER COPYING.LIB - -# Make all library code position independent by default. This is handy for -# creating shareable libraries from the static ones (Java JNI libraries). -# Note we do not simply set the AM_CFLAGS variable, as this would also -# apply to programs compiled without using libtool, possibly causing the -# compilation to fail. - -if !NOTHREADS - -if !NOPIC -libast_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -DTHREAD_SAFE -else -libast_la_CFLAGS = $(AM_CFLAGS) -DTHREAD_SAFE -endif - -else -libast_la_CFLAGS = $(AM_CFLAGS) -prefer-pic - -endif - -if !NOPIC -libast_err_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -libast_ems_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -libast_drama_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -libast_grf3d_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -libast_grf_2_0_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -libast_grf_3_2_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -libast_grf_5_6_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -libast_pgplot_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -libast_pgplot3d_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -libast_pal_la_CFLAGS = $(AM_CFLAGS) -prefer-pic -endif - -# The module containing the main AST classes -libast_la_SOURCES = \ - $(GRP_C_ROUTINES) \ - $(F_C_ROUTINES) \ - $(GRP_C_INCLUDE_FILES) \ - $(F_C_INCLUDE_FILES) \ - $(GRP_F_INCLUDE_FILES) \ - $(CMINPACK_FILES) \ - $(WCSLIB_FILES) \ - ast_err.h - -# Ensure libast links against libraries containing functions used within -# libast. If AST is configured --with-external-pal, then the internal -# libast_pal library will be empty, and we link to an external PAL -# library instead. -if EXTERNAL_PAL -libast_la_LIBADD = $(libdir)/libpal.la -else -libast_la_LIBADD = libast_pal.la -endif - -# AST_PAR is really part of GRP_F_INCLUDE_FILES, but it must not be -# distributed, so list it separately. -nodist_libast_la_SOURCES = \ - ast.h \ - AST_PAR - -# The default error reporting module. -libast_err_la_SOURCES = err_null.c - -# The error reporting module that uses EMS to deliver errors. -libast_ems_la_SOURCES = err_ems.c - -# The error reporting module that uses DRAMA Ers to deliver errors. -libast_drama_la_SOURCES = err_drama.c - -# The module containing null implementations of the 3D graphics routines -# required by AST -libast_grf3d_la_SOURCES = grf3d.c - -# The module containing null implementations of the graphics routines -# required by AST V2.0 -libast_grf_2_0_la_SOURCES = grf_2.0.c - -# The module containing null implementations of the graphics routines -# added by AST V3.2 and not present in V2.0 -libast_grf_3_2_la_SOURCES = grf_3.2.c - -# The module containing null implementations of the graphics routines -# added by AST V5.6 and not present in V3.2 -libast_grf_5_6_la_SOURCES = grf_5.6.c - -# The graphics module that uses PGPLOT for 2D graphical output. -libast_pgplot_la_SOURCES = $(GRF_PGPLOT_SOURCES) - -# The graphics module that uses PGPLOT for 3D graphical output. -libast_pgplot3d_la_SOURCES = $(GRF3D_PGPLOT_SOURCES) - -# Positional astronomy libraries. -libast_pal_la_SOURCES = $(PAL_FILES) - -# The following files are built by the targets in this makefile. -MAINTAINERCLEANFILES = version.h builddocs addversion \ - ast.h $(DOCUMENTATION_PRODUCTS) -CLEANFILES = AST_PAR ast.h - -# Special cases start here - -# The AST_PAR include file is produced by compiling the astbad.c -# program and editing its output into the ast_par.source file (while -# also changing the "E" exponent character to a "D"). The astbad.c -# and ast_par.source must be distributed (the generation of the -# AST__BAD value must be done on the build host) but not installed. -noinst_PROGRAMS = astbad -astbad_SOURCES = astbad.c pointset.h -AST_PAR: ast_par.source astbad - sed -e 's//'`./astbad AST__BAD | tr 'E' 'D'`'/' \ - -e 's//'`./astbad AST__NAN | tr 'E' 'D'`'/' \ - -e 's//'`./astbad AST__NANF | tr 'E' 'D'`'/' \ - ast_par.source >$@ - -# ast_link is generated from ast_link.in; ast_link_adam does not -# need configuration, and so is not mentioned in AC_CONFIG_FILES within -# configure.ac, and so is not distributed automatically. -# -# makeh is required in order to build ast.h after distribution (see below). -EXTRA_DIST = ast_par.source sun210_figures sun211_figures pal erfa cminpack - -# ast.h depends on the error-facility files. ast.h _could_ be made -# before distribution, but since it's generated from other distributed -# files, it's more robust to distribute makeh and make ast.h on the -# build host. -ast.h: $(AST_H_FILES) ast_err.h makeh config.h - @PERL@ ./makeh -s $(srcdir) $(AST_H_FILES) >$@ - -# AST_ERR and ast_err.h are `generated source files', and so must be -# generated before any other compilations are done. Note that these -# files are generated on the distribution host, and so this -# declaration has no effect post-distribution. -# -# AST_PAR is also a generated source file, but it should _not_ be -# included in the list of BUILT_SOURCES, otherwise `make' tries to make -# it before it makes the `astbad' program it depends on. Instead, -# just rely on the dependencies expressed in the main body above to -# have AST_PAR built before it is needed. -# -# version.h is included by object.h, and thus indirectly by most modules. -# It's most straightforward to build it at the beginning. -BUILT_SOURCES = AST_ERR ast_err.h version.h - -# Form a second link to the main object library (static and shared). This -# is used when a second pass through the library is needed during linking -# to resolve references made within other AST libraries (e.g. the grf -# modules, etc), to functions defined within libast (e.g. memory management -# and error reporting functions). Do not forget to change the contents of -# the libast_pass2.la file to refer to libast_pass2.* rather than libast.*. -# Use target install-exec-hook rather than install-exec-local so that the -# soft links and files are created *after* the main library has been -# installed. -install-exec-hook: libast.la - $(mkdir_p) $(DESTDIR)$(libdir) - cd $(DESTDIR)$(libdir); \ - for f in `ls libast.*`; do \ - ff=`echo $$f | sed -e 's/libast/libast_pass2/'`; \ - if test -f "$$ff"; then rm "$$ff"; fi; \ - $(LN_S) $$f $$ff; \ - $(MANIFEST) && echo "MANIFEST:$(DESTDIR)$(libdir)/$$ff" || :; \ - done; \ - if test -f "libast.la"; then \ - if test -f "libast_pass2.la"; then rm "libast_pass2.la"; fi; \ - sed -e 's/libast\./libast_pass2\./g' libast.la > libast_pass2.la; \ - fi - -# Make pre-distribution files. These are files which are required for -# building the distribution, but are not themselves distributed. -# The source files here should be mentioned in STAR_PREDIST_SOURCES in -# configure.ac -@PREDIST@predist_subs = sed \ -@PREDIST@ -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),' \ -@PREDIST@ -e 's,@PACKAGE_VERSION_MAJOR\@,$(PACKAGE_VERSION_MAJOR),' \ -@PREDIST@ -e 's,@PACKAGE_VERSION_MINOR\@,$(PACKAGE_VERSION_MINOR),' \ -@PREDIST@ -e 's,@PACKAGE_VERSION_RELEASE\@,$(PACKAGE_VERSION_RELEASE),' \ -@PREDIST@ -e 's,@PERL\@,$(PERL),' \ -@PREDIST@ -e 's,@STARLINK\@,$(STARLINK),' - -@PREDIST@version.h: version.h.in configure.ac -@PREDIST@ rm -f $@; $(predist_subs) version.h.in >$@ -@PREDIST@builddocs: builddocs.in configure.ac -@PREDIST@ rm -f $@; $(predist_subs) builddocs.in >$@; chmod +x $@ -@PREDIST@addversion: addversion.in configure.ac -@PREDIST@ rm -f $@; $(predist_subs) addversion.in >$@; chmod +x $@ - -# Documentation -@PREDIST@$(PAPER_DOCUMENTATION): sun211_figures builddocs addversion -@PREDIST@ ./builddocs - -# The contents of the sun211_figures directory is identical to that -# sun210_figures -sun211_figures: sun210_figures - $(LN_S) sun210_figures sun211_figures - -# Installation check - -TESTS = ast_test -check_PROGRAMS = ast_test -ast_test_SOURCES = ast_test.c - -test: install - cd ast_tester && STARLINK=@STARLINK@ PGPLOT_DIR=@STARLINK@/bin ./ast_tester -nd - -#ast_test_LDADD = `ast_link` -# Expand ast_link to avoid libast_pass2, which causes problems for Solaris -ast_test_LDADD = @LIBPAL@ libast.la libast_pal.la libast_grf_3.2.la libast_grf_5.6.la libast_grf_2.0.la libast_grf3d.la libast_err.la -lm - -# Need to include latex support files in the distribution tar ball so -# that the docs can be built from the tex source files. Requires environment -# variable STARLATEXSUPPORT to be deined. Is there a better way to do this? -dist-hook: - cp -p $(STARLATEXSUPPORT)/starlink.cls $(distdir)/ - cp -p $(STARLATEXSUPPORT)/starabbrev.sty $(distdir)/ - cp -p $(STARLATEXSUPPORT)/starstyle.sty $(distdir)/ - cp -p $(STARLATEXSUPPORT)/sst.sty $(distdir)/ diff --git a/ast/Notes b/ast/Notes deleted file mode 100644 index bb4ac0e..0000000 --- a/ast/Notes +++ /dev/null @@ -1,105 +0,0 @@ - -Random notes about the autoconfing of AST - -Initial version imported from a tarball supplied by DSB. The tarball -contained David's RCS repository plus the development directory (dev/) -and the `reference' directory (ref/) which contains a checkout of the -RCS repository. The development directory contains working versions -of the files in the reference directory, plus miscellaneous test files -and notes, plus copies of sdt.tar.Z (the RCS wrapper which has long -been used for AST development) and sst_source.tar.Z (the documentation -builder). - -The RCS repository was dropped into the CVS repository on 14 November -2003, and tagged with ast-3-1-0-import. After thinking a bit about -tagging policies (and writing these up on the wiki and posting to the -stardev group), I tagged this same point as -bp-dev-nxg-20031121-autoconfing and created a branch -dev-nxg-20031121-autoconfing (21 November -- busy week since the -14th...). That's the one I'll work on. - -I've created configure.ac, and I've developed the build system using -reasonably current versions of the autotools (namely autoconf-2.57, -automake versions 1.6.3 or 1.7.5, and libtool versions 1.4.2 or 1.5). -There's no point jumping through hoops to use random obsolete versions -(reading old documentation, and trying to keep things forwards -compatible, untestably) simply because they're installed on RH7.3. If -anyone plans to install these newer versions, I recall that autoconf, -libtool, automake was the order that worked (it matters), and you need -to install GNU m4 first on Solaris or Alpha - -Created starlink.m4, which includes macro STAR_FACILITY_CODE which -facilitates declaring the `err' facility code which has been allocated -to this library. This also AC_SUBSTs the variable ERR_FACILITY_CODE, -and I've moved ast_err.msg and error.h to the corresponding .in files, -modified them to have that code inserted, and put them in -AC_CONFIG_FILES. This file should be moved to a central location when -I work out where such a central location should be. At that point, -./bootstrap should be edited to contain that location. - -The two files in grp.make's F_ROUTINES group, object.f and frame.f, -don't appear to be used anywhere. I've omitted them in Makefile.am - - -Building AST ------------- - -To build AST directly from the repository, you need reasonably current -versions of the autotools (as noted above). If anyone plans to -install these newer versions, I recall that autoconf, libtool, -automake was the order that worked (it matters), and you need to -install GNU m4 first on Solaris or Alpha. - -Recall the discussion we had on stardev about autotools and generated -files. I have now checked in the generated files configure, -config.h.in and Makefile.in. Later, I'll either add the fixes I added -to autoastrom to make the `missing' script work, or see if there's a -more supported way to do that. With those fixes and additions, it -_will_not_matter_ which autotools versions you have, as long as you -don't have to alter Makefile.am or configure.ac, and in any case it -the autotools are completely unneeded for building from the -distribution tarball. - -To build from the repository, do - - ./bootstrap - ./configure - make - - -Conventions and facilities so far ---------------------------------- - -The version number is set in the AC_INIT line in configure.ac, and -propagated from there to the locations where it's needed. - -The string @STAR_BOILERPLATE@ must be in Makefile.{am,in}. All this -does at present is include boilerplate for calling messgen _if_ -STAR_FACILITY_CODE is present (which it is, for AST). - -configure.ac should have STAR_DEFAULTS near the beginning (sets the -default installation location to be /star rather than GNU default -/usr/local, ensures that the STARLINK environment variable is set). - -STAR_FACILITY_CODE declares the error-reporting system facility code -which has been allocated to this library. - - -Modifications to AST files --------------------------- - -ast_err.msg is now created from ast_err.msg.in, and has the facility -code declared in STAR_FACILITY_CODE edited into it at that point. -Same for error.h and error.h.in. - -ast_cpp generated from ast_cpp.in with the CC edited in - -makeh now calls ast_cpp through /bin/sh (avoids having to worry about -execute bits) - -Versioning: The version number (as mentioned above, set in -configure.ac) is now substituted into version.h.in, broken into -major.minor-release, and version.h is included in ast.h. File -object.c now includes version.h to implement the astVersion_ -function. AST_MAJOR_VERS and co removed from makeh (since they're now -included in ast.h inside version.h). diff --git a/ast/STARLINK_BRANCHES b/ast/STARLINK_BRANCHES deleted file mode 100644 index 975ab87..0000000 --- a/ast/STARLINK_BRANCHES +++ /dev/null @@ -1,46 +0,0 @@ - -AST branches -============ - -dev-dsb-20040406 ----------------- - -Branch created on 6th April 2004, to support classic ast.tar.Z version. - - -DEV-nxg-20040830-ast-timeframe ------------------------------- - -Branch created on 2004 August 30, to support Norman's TimeFrame work. -Should probably have the trunk merged to it at some point, before much -more work is done on TimeFrame. ABANDONED 2005 March 18, in favour of -DEV-nxg-20050314-ast-timeframe. - -DEV-nxg-20050314-ast-timeframe ------------------------------- - -Created 2005 March 14, as a fresh branch from the AST HEAD, on the -grounds that AST has moved forward a significant amount from the -point where branch DEV-nxg-20040830-ast-timeframe was created, and -there's no point in multiplying our merging problems unnecessarily. -The changes done on that previous branch were merged onto this branch, -mostly with a patch file, but by hand where there were already conflicts. - -By 2005-05-04T16:00, the HEAD had again diverged significantly from -the original branch point, so Norman merged the HEAD differences from -the branch point onto the branch: - - cvs update -j bp-DEV-nxg-20050314-ast-timeframe -j HEAD - -DEV-dsb-20041123-ast-stc ------------------------- - -Branch created on "23rd November 2004" to support DSB's STC work. This is -a branch off dev-dsb-20040406. Once I've got something worth using, I'll -create a similar branch of the trunk. Need to think carefully about how -to distribute AST-with-STC since AST is starting to look a bit bloated, -and the majority of AST users won't be interested in STC. - - - - diff --git a/ast/addcopyright b/ast/addcopyright deleted file mode 100755 index 4772023..0000000 --- a/ast/addcopyright +++ /dev/null @@ -1,2 +0,0 @@ -sed -e 's/* /* Copyright (C) 1997-'"`date +%Y`"' Council for the Central Laboratory of the\n* Research Councils/' \ - -e 's//Copyright (C) 1997-'"`date +%Y`"' Council for the Central Laboratory of the Research Councils/' diff --git a/ast/addlinks b/ast/addlinks deleted file mode 100755 index 997dad6..0000000 --- a/ast/addlinks +++ /dev/null @@ -1,163 +0,0 @@ -#! /usr/bin/env perl - -# Read a set of labels (one per line) from the "global.labels" file. -# Then read the input lines and create links for the first occurrence -# of each label in each Latex section encountered (the links use \htmlref -# to refer to HTX labels elsewhere in the document). Omit links wherever -# they are not appropriate. - -# Read the list of labels for which links should be generated (these may -# contain Latex escape characters, as they must exactly match the text from -# which the link will be generated). - open( LABELS, 'global.labels' ); - @labels = ; - close( LABELS ); - -# Sort the labels into descending order of length. This is to avoid problems -# with labels which are abbreviations of other labels. - @labels = sort { length( $b ) <=> length( $a ) } @labels; - -# Build a regexp that will match any one of the labels. - $pattern = ""; - for $label ( @labels ) { - -# Remove newlines from each label. - $label =~ s/\n//g; - -# Labels must be whole words unless they start/end without an alphanumeric. - $label_q = quotemeta( $label ); - if ( $label =~ m/^\w/ ) { $label_q = "\\b" . $label_q }; - if ( $label =~ m/\w$/ ) { $label_q = $label_q . "\\b" }; - -# Build the regexp. - $pattern = !$pattern ? $label_q : $pattern . "|" . $label_q; - } - -# Loop through the input data. - $sdiy = 0; - $inr = 0; - $source_line = 10; - $verbatim = 0; - while ( <> ) { - -# Detect the start of each type of document section. - ( $s ) = /^ *\\section\{/; # Latex section - ( $ss ) = /^ *\\subsection\{/; # Latex subsection - ( $sss ) = /^ *\\subsubsection\{/; # Latex subsubsection - ( $sr ) = /^ *\\sstroutine\{/; # SST routine description - -# We only consider sst diytopic sections to be of significance if they -# introduce a listing of attributes or Functions. This is so that these -# sections always contain links. SO if the previous line was a diytopic -# line, see if this line contains the single word "Attributes" or -# "Functions" - if( $sdiy ) { - ( $attrfun ) = /^ *(Attributes|Functions) *$/; - $linkatfun = 0; - $sdiy = 0; - } else { - ( $sdiy ) = /^ *\\sstdiytopic\{/; - } - -# Do not make links in the introductory text in an Attributes or -# Functions DIY section. - if( $attrfun ) { - if( /^ *\\sstitemlist\{/ ) { $linkatfun = 1 }; - } else { - $linkatfun = 0; - } - -# Watch for the end of the list of attributes or functions. - if( $attrfun ) { - if( /^ *\} *$/ ) { - $attrfun = 0; - $linkatfun = 0; - } - } - -# Note if a new section has started. - $sx = ( $s || $ss || $sss || $sr ); - if ( $sx ) { - -# Set a flag to indicate which type of section we are in. - $ins = $inss = $insss = $inr = 0; - if ( $s ) { $ins = 1 }; - if ( $ss ) { $inss = 1 }; - if ( $sss ) { $insss = 1 }; - if ( $sr ) { $inr = 1 }; - -# Clear the count of source lines for this section. - $source_line = 0; - -# Clear the array of flags indicating which labels have been used. - undef %used; - } - -# Note if we are in a Latex "verbatim" or "terminalv" environment. - if ( /^ *\\begin\{(verbatim|terminalv)\} *$/ ) { $verbatim = 1 }; - -# Count the source lines read from each section. - $source_line++; - -# Obtain an array of all the labels matched in the current source line. - @match = /$pattern/og; - -# Consider generating a link for each label matched. - for $label ( @match ) { - $label_q = quotemeta( $label ); - -# In an SST routine description, extract the name of the routine from -# the second source line and mark the label of that name "used". This -# prevents links being made to this section from within itself. - if ( $inr && $source_line == 2 ) { - $used{ $label }++; - $label_x = $_; - $label_x =~ s/\W//g; - #s/$/\\sstlabel{$label_x}/; - } - -# If we are in a Functions or Attributes section, see if the match occurs -# at the start of the line and is followed by a colon. If it is, it is the -# name of the main Function or Attribute being described and so should be -# linkified. - $atfun = ( $linkatfun && ( /^ *$label_q:/ ) ); - -# Is this a caption? Do not replace entries in first part of caption -# that appears in TOC LOF - $iscap = /\\caption/; - -# Check if a link should be made. Omit links in "verbatim" environments, -# in any line which starts a new section (because labels don't work properly -# if they get into the table of contents), in the 4th line of an SST -# routine description (because these also go into the TOC), or if the label -# has already been used in this section. We always linkify any match if it -# is in a list of Function or Attribute descriptions, if it is at the start -# of the line and is followed by a colon. - if ( $atfun || ( !$verbatim && - !$iscap && - !$sx && - !( $inr && ( $source_line == 4 ) ) && - !$used{ $label } ) ) { - -# Increment the number of usages of this label. - $used{ $label }++; - -# Labels must be whole words unless they start/end without an alphanumeric. - if ( $label =~ m/^\w/ ) { $label_q = "\\b" . $label_q }; - if ( $label =~ m/\w$/ ) { $label_q = $label_q . "\\b" }; - -# Form a version of the label with non alphanumerics removed. - $label_x = $label; - #$label_x =~ s/\W//g; - -# Edit each instance of the label in the source line to insert an \htmlref. - s/$label_q/\\htmlref{$label}{$label_x}/; - } - } - -# Detect the end of "verbatim" environments. - if ( /^ *\\end\{(verbatim|terminalv)\} *$/ ) { $verbatim = 0 }; - -# Output the modified line. - print; - } diff --git a/ast/addversion.in b/ast/addversion.in deleted file mode 100644 index 955a971..0000000 --- a/ast/addversion.in +++ /dev/null @@ -1,10 +0,0 @@ - -vers="@PACKAGE_VERSION@" -majversno="`echo "${vers}" | awk -F . '{print $1;}'`" -minversno="`echo "${vers}" | awk -F . '{print $2;}'`" -relsno="`echo "${vers}" | awk -F . '{print $3;}'`" -versno="${majversno}.${minversno}" -sed -e 's//'"${versno}"'/g' \ - -e 's//'"${majversno}"'/g' \ - -e 's//'"${minversno}"'/g' \ - -e 's//'"${relsno}"'/g' diff --git a/ast/ast-for-wcslib/astTester.c b/ast/ast-for-wcslib/astTester.c deleted file mode 100644 index 0cd6a92..0000000 --- a/ast/ast-for-wcslib/astTester.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Purpose: - * Tests the cut down version of AST used by WCSLIB for handling units - * strings. - */ - -/* System header files. */ -#include - -/* The following line causes the AST header files to make the internal - "protected" interface available. The functions defined in unit.h are - only available with in the protected interface. */ -#define astCLASS wcslib - -/* Include header files for the AST classes which are used below. */ -#include "unit.h" -#include "mapping.h" - -main(){ - int pass; - char *label; - double xin[3], xout[3]; - - pass = 1; - -/* Get the Mapping from a speed value in km/h to a log(speed) value - in "log(m/s)". */ - AstMapping *map = astUnitMapper( "km/h", "log(m/s)", "speed", &label ); - -/* If no Mapping could be found, test has failed. */ - if( !map ) { - pass = 0; - printf("No Mapping returned by astUnitMapper\n"); - -/* If a Mapping was returned by astUnitMapper, it can be used with any of the - methods defined by the Mapping class. See: - - http://www.starlink.ac.uk/~dsb/ast/sun211.htx/node450.html - - Here, we use the Mapping to transform three speed values (first is - negative and so should produce a bad log(speed) value). */ - } else { - xin[0] = -1.0; - xin[1] = 1.0; - xin[2] = 100.0; - astTran1( map, 3, xin, 1, xout ); - -/* Check above transformation was succesful. */ - if( astOK ) { - -/* Check the transformed values and label are correct. */ - if( xout[ 0 ] != AST__BAD ) { - printf( "xout[0] wrong: %.*g should be %.*g\n", - DBL_DIG, xout[0], DBL_DIG, AST__BAD ); - pass = 0; - - } else if( fabs( xout[ 1 ] - (-0.556302500767287) ) > 1.0E-5 ) { - printf( "xout[1] wrong: %.*g should be -0.556302500767287\n", - DBL_DIG, xout[1] ); - pass = 0; - - } else if( fabs( xout[ 2 ] - 1.44369749923271 ) > 1.0E-5 ) { - printf( "xout[2] wrong: %.*g should be 1.44369749923271\n", - DBL_DIG, xout[2] ); - pass = 0; - - } else if( strcmp( label, "log( speed )" ) ) { - printf( "label wrong: \"%s\" should be \"log( speed )\"\n", - label ); - pass = 0; - } - - } else { - printf( "Error on return from astTran1\n" ); - pass = 0; - } - } - -/* Say whether the test has been passed or not */ - if( !pass ) { - printf("\n AST unit test failed\n\n"); - } else { - printf("\n AST unit test passed\n\n"); - } -} diff --git a/ast/ast-for-wcslib/loader.c b/ast/ast-for-wcslib/loader.c deleted file mode 100644 index d71c6fb..0000000 --- a/ast/ast-for-wcslib/loader.c +++ /dev/null @@ -1,35 +0,0 @@ -/* A dummy version of loader.c for use in the WCSLIB sub-set of AST */ -#define astCLASS -#include "channel.h" -#include "loader.h" -#include "mapping.h" -#include "mathmap.h" -#include "object.h" -#include "pointset.h" -#include "unitmap.h" -#include "zoommap.h" - -#include "error.h" -#include "ast_err.h" -#include -#include - -AstLoaderType *astGetLoader( const char *class ) { - if ( !astOK ) return NULL; - -#define LOAD(name) \ -if ( !strcmp( class, #name ) ) return (AstLoaderType *) astLoad##name##_ - - LOAD(Channel); - LOAD(Mapping); - LOAD(MathMap); - LOAD(Object); - LOAD(PointSet); - LOAD(UnitMap); - LOAD(ZoomMap); - - astError( AST__OCLUK, "astGetLoader: Object of unknown class \"%s\" cannot " - "be loaded.", class ); - return NULL; -#undef LOAD -} diff --git a/ast/ast-for-wcslib/matrixmap.h b/ast/ast-for-wcslib/matrixmap.h deleted file mode 100644 index d999180..0000000 --- a/ast/ast-for-wcslib/matrixmap.h +++ /dev/null @@ -1,7 +0,0 @@ -/* A dummy version of matrixmap.h for use in the WCSLIB sub-set of AST */ -#define astMatrixMap(nin,nout,mode,mat,opts) \ - (astError(AST__INTER,"Internal AST programming error - " \ - "an attempt has been made to create a MatrixMap" ), \ - astError(AST__INTER,"The WCSLIB version of AST does not include " \ - "the MatrixMap class" ), \ - NULL) diff --git a/ast/ast-for-wcslib/plot.h b/ast/ast-for-wcslib/plot.h deleted file mode 100644 index 1678ec9..0000000 --- a/ast/ast-for-wcslib/plot.h +++ /dev/null @@ -1,2 +0,0 @@ -/* A dummy version of plot.h for use in the WCSLIB sub-set of AST */ -#define astStripEscapes(result) result diff --git a/ast/ast-for-wcslib/wcslib-instructions b/ast/ast-for-wcslib/wcslib-instructions deleted file mode 100644 index 82c4369..0000000 --- a/ast/ast-for-wcslib/wcslib-instructions +++ /dev/null @@ -1,112 +0,0 @@ -From dsb@ast.man.ac.uk Thu Jul 15 17:23:14 2004 -Date: Thu, 15 Jul 2004 17:19:38 +0100 (BST) -From: David Berry -To: Mark Calabretta -Cc: Eric Greisen , D.L.Giaretta@rl.ac.uk -Subject: Re: Legacy FITS headers - -Mark, - -> On Tue 2004/07/13 10:38:01 +0100, David Berry wrote -> in a message to: Mark Calabretta -> and copied to: Eric Greisen -> -> >headers. When reading headers, AST parses CUNIT and applies the -> >appropriate conversion factors where necessary. It uses a neat little -> >utility module which, given two units strings (using the paper I syntax) -> >will parse them and return a Mapping between them if possible). -> -> Hi David, -> -> That's something I would like to include directly in WCSLIB if possible -> rather than reinventing the wheel, quite a large one too by the look of -> it! -> -> Looking at unit.c though, it seems to depend on a lot of other AST -> code (dependency list appended), I really need a self-contained -> version, preferably in one .h and one .c file. It looks like the CCLRC -> copyright is reasonably permissive with regard to distributing modified -> forms of the AST code. I'd need to change it only so far as to make it -> self-contained, also probably changing global symbol names to prevent -> potential conflicts with the AST object library. -> -> How does that sound to you? - -All Starlink software is being moved over to GPL licences, so there should -be no legal problem in you using parts of AST. - -Getting everything relevant to unit.c into one .c and one .h file could be -quite tricky. Having said that, you could manage with only a few of the -many files in the AST distribution. I've played about with this a bit -today, and the following seems to produce a minimal AST system which -allows the facilities of unit.c to be used: - -1) Make a new directory and cd into it - -2) Get the latest version of AST (V3.3-4) from: - -ftp://ftp.starlink.ac.uk/pub/users-ftp/dsb/ast/V3.3-4/ast.tar.Z - -(I found and fixed a bug in unit.c today whilst I was looking into this) - -3) Execute the following commands: -% uncompress ast.tar.Z -% tar -xf ast.tar ast_source.tar -% tar -xf ast_source.tar \ - ast_err.h \ - channel.h \ - err.h \ - error.h \ - loader.h \ - mapping.h \ - mathmap.h \ - memory.h \ - object.h \ - pointset.h \ - unitmap.h \ - unit.h \ - zoommap.h \ - channel.c \ - error.c \ - err_null.c \ - mapping.c \ - mathmap.c \ - memory.c \ - object.c \ - pointset.c \ - unitmap.c \ - unit.c \ - zoommap.c - -% rm ast_source.tar ast.tar - -4) Copy the files attached to this e-mail into this directory (astTester.c - loader.c matrixmap.h makefile plot.h). - -5) Do: - -% make -% make test - -(you may need to change some of the macro values in makefile if you are -not running on a system like redhat 9). This will create a libast.a -library and run the astTester.c test program. You could look at -astTester.c to see how to use the astUnitMapper function. - -This is the minimal set of AST files needed to use unit.c - it leaves out -all the graphics and the handling of coordinate systems and FITS headers -(and also most of the Mapping classes). - -In case you need to get back to me about this, I'm away on holiday for the -next two weeks. - -David - - - [ Part 2, "" Application/OCTET-STREAM (Name: "wcslib.tar.gz") ] - [ 2.8KB. ] - [ Unable to print this part. ] - - - - diff --git a/ast/ast.news b/ast/ast.news deleted file mode 100644 index cbefd45..0000000 --- a/ast/ast.news +++ /dev/null @@ -1,1189 +0,0 @@ -AST Library ------------ - A new release (V8.6.2) of the Starlink AST (astrometry) library is -now available. - - AST provides a comprehensive range of facilities for attaching -world coordinate systems (such as RA/Dec, frequency, etc) to astronomical -data, for retrieving and interpreting that information and for generating -graphical output based on it. - - The library should be of interest to anyone writing astronomical -software which needs to manipulate coordinate system data, especially -celestial coordinate systems. AST is portable and -environment-independent. - - - -Main Changes in this Version ----------------------------- - -- The astWrite method of the FitsChan class can now create FITS-WCS headers -that include keyords describing focal plane distortion using the -conventions of the Spitzer SIP scheme. This is however only possible if -the SipOK attribute of the FitsChan is set to a non-zero value (which is -the default), and the FrameSet being written out contains an appropriate -PolyMap that conforms to the requirements of the SIP convention. - -- The behaviour of the astLinearApprox method of the Mapping class has -been changed in cases where the Mapping being approximated generates bad -(AST__BAD) values for one or more of its outputs. Previously, any such -Mapping would be deemed non-linear and no fit would be returned. Now, a -fit is returned, provided the other outputs of the Mapping are linear, -but the fit contains AST__BAD values for the coefficients describing the -bad Mapping output. - - -Main Changes in V8.6.1 ----------------------- - -- A new function call astCreatedAt is now available that returns the function -name, file path and line number at which an AST object was first created. - -- The number of digits used to format floating point values has been -increased in order to avoid loss of precision when converting from binary -to string and back to binary. This could cause very small changes in numerical -values returned by AST functions. - -- If a FrameSet is supplied as the "Map" argument to astAddFrame, it now -extracts and stores the base->current Mapping from the supplied FrameSet. -Previously, the entire FrameSet was stored as the Mapping. - - -Main Changes in V8.5.1 ----------------------- - -- A new class of Mapping called ChebyMap has been added. This is a -Mapping that implements Chebyshev polynomial transformations. - -- If the function that delivers error messages to the user (astPutErr) is -re-implemented, the new version can now be registered at run-time using -the new astSetPutErr function. Previously, the new version needed to be -linked into the application at build time. - -- A bug has been fixed in the PolyMap class that caused incorrect values -to be returned for the TranForward and TranInverse attributes if the PolyMap -has been inverted. - -- The KeyMap class has a new method called astMapGetC (AST_MAPGETC) which -returns a named entry as a single string. If the entry is a vector the -returned string is a comma-separated list of its elements, enclosed in -parentheses. - -- The Frame class now has a new attribute caled DTAI, which can be used -to specify the number of leap seconds at the moment represented by the -Frame's Epoch attribute. By default, the internal look-up table of leap -seconds contained within AST is used. The DTAI attribute allows old -versions of AST, which may not include the most recent leap seconds, to -be used with new data. - -- The TimeMap class has been changed so that some conversions now require -a "Dtai" value (i.e. the number of leap seconds) to be supplied by the -caller. If AST__BAD is supplied for "Dtai", the internal look-up table of -leap seconds contained withn AST will be used. The conversions affected -are those between TAI and UTC, and those between TT and TDB. - -Main Changes in V8.3.0 ----------------------- - -- The PAL library files included in the AST distribution have been updated -to PAL version 0.9.7. - -- Multiple identical NormMaps in series will now be simplified to a -single NormMap. - -- A NormMap that encapsulates a basic Frame will now be simplified to a -UnitMap. - -- The astTimeAdd (AST_TIMEADD) method of the TimeMap class now include an -extra argument that gives the number of values supplied in the arguments -array. Note, any existing code that uses this method will need to be -changed. - -- The astSlaAdd (AST_SLAADD) method of the SlaMap class now include an -extra argument that gives the number of values supplied in the arguments -array. Note, any existing code that uses this method will need to be -changed. - -- The astSpecAdd (AST_SPECADD) method of the SpecMap class now include an -extra argument that gives the number of values supplied in the arguments -array. Note, any existing code that uses this method will need to be -changed. - -- If the astMapRegion (AST_MAPREGION) method is used to map a Region into -a new Frame that has fewer axes than the original Region, and if the -inverse transformation of the supplied Mapping does not specify a value -for the missing axes, then those axes are removed entirely from the -Region. Previously they were retained, but supplied with bad values. This -affects the number of mesh points per axes for such Regions, and so -affects the accuracy of overlap determination. - - -Main Changes in V8.3.0 ----------------------- - -- A new method called astAxNorm has been added to the Frame class that -normalises an array of axis values. When used with SkyFrames, it allows -longitude values to be normalised into the shortest range. - -- A bug has been fixed in the Fortran include file AST_PAR that caused constants -related to PI to be defined as single rather than double precision. - -- A bug has been fixed in the astGetRegionBounds method that could -cause the wrong bounds to be returned for regions spanning a longitude = -zero singularity. - -Main Changes in V8.2.0 ----------------------- - -- A new class of Mapping called UnitNormMap has been added that converts a -vector to a unit vector relative to a specified centre, plus length. A -UnitNormMap has N inputs and N+1 outputs.The lower N output coordinates -represent a unit vector parallel to the supplied input vector, and the -(N+1)'th output coordinate is the length of the input vector. - -- The restriction that Mappings are immutable has been extended to all -Mapping classes. This means that attributes representing parameters of -a Mapping's forward or inverse transformation cannot be changed after -the Mapping has been created. In order to minimise the risk to existing -software, this rule does not apply to Mappings that have not yet been -included in other objects such as CmpMaps or FrameSets, or which have not -yet been cloned. In other words, an error is reported if an attempt is -made to change the nature of a Mapping's transformation, but only if the -reference count of the Mapping is greater than one. The Mapping classes -affected include: GrismMap, LutMap, PcdMap, SphMap, WcsMap and ZoomMap. - - -Main Changes in V8.1.0 ----------------------- - -- The configure script has a new option "--without-fortran" that allows -AST to be built in situations where no Fortran compiler is available. The -resulting library has no Fortran interface and so cannot be used within -Fortran applications. Also, the link scripts do not attempt to include the -fortran runtime libraries. - -Main Changes in V8.0.7 ----------------------- - -- A bug in FitsChan has been fixed which could cause a small shift in - spectral axis value when writing out a spectral cube to FITS-WCS headers, - This shift occurred only if the celestial axes in the cube were not FK5 - (RA,Dec). - -- Avoid some more compiler warnings. - -- A "BadKeyValue" warning is now issued by the FitsChan class if an illegal -FITS keyword value is encountered. See attribute "Warnings" and function -"astWarnings". - -Main Changes in V8.0.6 ----------------------- - -- Fix bug in FitsChan that caused SIP headers to be treated as linear -when creating a FrameSet from the headers. - -- Fix bug in LutMap that incorrectly allowed an inverse lutmap to be used -even if the original LutMap was not monotonic. - -- Allow attributes to be set for each plane of a Plot3D. - -- Avoid some compiler warnings. - -Main Changes in V8.0.5 ----------------------- - -- The SkyFrame class has a new attribute called SkyTol, which specifies -the smallest significant distance within the SkyFrame. It is used to -decide if the Mapping between two SkyFrames can be considered a unit -transformation. The default value is 0.001 arc-seconds. - -- A bug has been fixed in the FitsChan class that prevented illegal -characters within FITS keyword names (i.e. characters not allowed by the -FITS standard) being detected. This bug could under some circumstances -cause a subsequent segmentation violation to occur. - -- A "BadKeyName" warning is now issued by the FitsChan class if a FITS -keyword name is encountered that contains any illegal characters. See -attribute "Warnings" and function "astWarnings". - -Main Changes in V8.0.4 ----------------------- - -- The behaviour of the astAddFrame method has been changed slightly. -Previously, astAddFrame modified the FrameSet by storing references to -the supplied Mapping and Frame objects within the FrameSet. This meant -that any subsequent changes to the current Frame of the modified FrameSet -also affected the supplied Frame object. Now, astAddFrame stores deep -copies of the Mapping and Frame objects (rather than references) within -the modified FrameSet. This means that subsequent changes to the modified -FrameSet will now have no effect on the supplied Frame. - -- The choice of default tick-mark for time axes has been improved, to avoid -previous issues which could result in no suitable gap being found, or -inappropriate tick marks when using formatted dates. - -- A new method called astRegionOutline has been added to the Plot class. -It draws the outline of a supplied AST Region. - -- A bug has been fixed that could cause astSimplfy to enter an infinite loop. - -- Some improvements have been made to the Mapping simplification process -that allow more Mappings to be simplified. - -- The Frame class has a new read-only attribute called "InternalUnit", -which gives the units used for the unformatted (i.e. floating-point) axis -values used internally by application code. For most Frames, the -InternalUnit value is just the same as the Unit value (i.e. formatted and -unformatted axis values use the same units). However, the SkyFrame class -always returns "rad" for InternalUnit, regardless of the value of Unit, -indicating that floating-point SkyFrame axis values are always in units -of radians. - -- The LutMap class has a new attribute called LutEpsilon, which specifies -the relative error of the values in the table. It is used to decide if -the LutMap can be simplified to a straight line. - - -Main Changes in V8.0.3 ----------------------- - -- Methods astRebin, astRebinSeq, astResample and astTranGrid now report an -error if an array is specified that has more pixels than can be counted by -a 32 bit integer. - -- The hypertext documentation is now generated using Tex4HT rather -than latex2html. The format of the hypertext docs has changed -significantly. - -- Another bug fix associated with reading CAR projections from FITS-WCS headers. - -- Constructor options strings of the form "..., "%s", text );" can now be -supplied. This avoids a security issue associated with the alternative -form "..., text );". - - -Main Changes in V8.0.2 ----------------------- - -- For security reasons, the change introduced to astAppendString in - V8.0.1 has been moved to a new function called astAppendStringf, and - astAppendString itself has been reverted to its V8.0.0 version. - - -Main Changes in V8.0.1 ----------------------- - -- The macro used to invoke the astAppendString utility function has - changed to allow printf-style converstions to be included in the - supplied text. Any code that uses this macro must be re-compiled. - -- The astRebin and astRebinSeq family of functions now include support - for arrays with char (byte) and unsigned char (unsigned byte) data types. - -- The Base and Current attributes of a FrameSet may now be set using the - Domain name or the index of the required Frame. - -- The FITS XPH projection is now supported. - -- The order of WCS axes within new FITS-WCS headers created by astWrite - can now be controlled using a new attribute called FitsAxisOrder. - -Main Changes in V8.0.0 ----------------------- - -- AST is now distributed under the Lesser GPL licence. - -- Least squares fitting of N-dimensional polynomials is now done using -files copied from the C/C++ Minpack package (see -http://devernay.free.fr/hacks/cminpack/index.html). - -- Use of the IAU SOFA library has been replaced by ERFA library, which is -a re-badged copy of SOFA distributed under a less restrictive license. A -copy of ERFA is included within AST. - -Main Changes in V7.3.4 ----------------------- - -- By default, the simplification of Polygons no longer checks that the -edges are not bent by the simplification. A new attribute, SimpVertices, -can be set to zero in order to re-instate this check. - -- The Polygon class has a new mathod, astConvex, that returns a Polygon -representing the shortest polygon (i.e. convex hull) enclosing a -specified set of pixel values within a supplied array. - -Main Changes in V7.3.3 ----------------------- - -- The FitsChan class has new attributes CardName and CardComm, which hold -the keyword name and comment of the current card. - -- When reading FITS-WCS headers that include polynomial distortion in the -SIP format, any inverse transformation specified in the header is now -ignored and a new inverse is created to replace it based on the supplied -forward transformation. Previously, an inverse was created only if the -header did not include an inverse. The accuracy of the inverse -transformation has also been improved, although it may now be slower to -evaluate in some circumstances. - -- A bug has been fixed that could over-write the FitsChan CarLin attribute -with a non-zero value if the header contains a spectral axis. - -- The default options for each newly created FitsChan can now be -specified via the environment variable FITSCHAN_OPTIONS. - -Main Changes in V7.3.2 ----------------------- - -- Fix support for reading GLS projections from FITS headers. - -- The KeyMap class has new sorting options "KeyAgeUp" and "KeyAgeDown" that -retain the position of an existing entry if its value is changed. See the -SortBy attribute. - -- A bug has been fixed in FitsChan that caused CDELT keywords for sky -axes to be treated as radians rather than degrees when reading a FITS -header, if the corresponding CTYPE values included no projection code. - - -Main Changes in V7.3.1 ----------------------- - -- Fix bug that could cause a segmenatation fault when reading a FITS TNX -header. - -Main Changes in V7.3.0 ----------------------- - -- IMPORTANT! The interface for the astRebinSeq (AST_REBINSEQ) family -of functions has been changed in order to allow a greater number of -pixels to be pasted into the output array. In C, the "nused" parameter -is now a pointer to a "int64_t" variable, instead of a simple "int". In -Fortran, the NUSED argument for AST_REBINSEQ is now an INTEGER*8. - -APPLICATION CODE SHOULD BE CHANGED ACCORDINGLY TO AVOID SEGMENTATION -FAULTS AND OTHER ERRATIC BEHAVIOUR. - -- Added a new facility to the FrameSet class to allow each Frame to be -associated with multiple Mappings, any one of which can be used to -connect the Frame to the other Frames in the FrameSet. The choice of -which Mapping to use is controlled by the new "Variant" attribute of the -FrameSet class. - -- Mappings (but not Frames) that have a value set for their Ident attribute -are now left unchanged by the astSimplify (AST_SIMPLIFY) function. - -Main Changes in V7.2.0 ----------------------- - -- A new method call astMapDefined has been added to the KeyMap class. -It checks if a gtiven key name has a defined value in a given KeyMap. - - -Main Changes in V7.1.1 ----------------------- - -- A bug has been fixed in FitsChan that caused inappropriate CTYPE values -to be generated when writing a FrameSet to FITS-WCS headers if the -current Frame describes generalised spherical coordinates (i.e. a -SkyFrame with System=Unknown). - -- When a FitsChan is used to write an "offset" SkyFrame (see attribute -SkyRefIs) to a FITS-WCS encoded header, two alternate axis descriptions -are now created - one for the offset coordinates and one for the absolute -coordinates. If such a header is subsequently read back into AST, the -original offset SkyFrame is recreated. - - -Main Changes in V7.1.0 ----------------------- - -- IMPORTANT! The default behaviour of astRebinSeq is now NOT to conserve -flux. To conserve flux, the AST__CONSERVEFLUX flag should be supplied -when calling astRebinSeq. Without this flag, each output value is a -weighted mean of the neighbouring input values. - -- A new flag AST__NONORM can be used with astRebinSeq to indicate that -normalisation of the output arrays is not required. In this case no -weights array need be supplied. - -- A bug has been fixed in astAddFrame (AST_ADDFRAME) method that could -result in the incorrect inversion of Mappings within the FrameSet when -the AST__ALLFRAMES flag is supplied for the "iframe" parameter. - -- The astRate method has been re-written to make it faster and more -reliable. - -Main Changes in V7.0.6 ----------------------- - -- A bug has been fixed in astRebinSeq which could result in -incorrect normalisation of the final binned data and variance values. - -- When reading a FrameSet from a FITS-DSS header, the keywords CNPIX1 and -CNPIX2 now default to zero if absent. Previously an error was reported. - -Main Changes in V7.0.5 ----------------------- - -- The FitsChan class can now read FITS headers that use the SAO -convention for representing distorted TAN projections, based on the use -of "COi_j" keywords to hold the coefficients of the distortion polynomial. - - -Main Changes in V7.0.4 ----------------------- - -- The previously private grf3d.h header file is now installed into -prefix/include. - - -Main Changes in V7.0.3 ----------------------- - -- A bug has been fixed which could cause an incorrect axis to be used when -accessing axis attributes within CmpFrames. This could happen if axes -within the CmpFrame have been permuted. - -- A bug has been fixed in the SkyFrame class that could cause the two -values of the SkyRef and/or SkyRefP attributes to be reversed. - -- Bugs have been fixed in the CmpRegion class that should allow the border -around a compound Region to be plotted more quickly, and more accurately. -Previously, component Regions nested deeply inside a CmpRegion may have -been completely or partially ignored. - -- A bug has been fixed in the Plot3D class that caused a segmentation -violation if the MinTick attribute was set to zero. - -- The astResampleX set of methods now includes astResampleK and -astResampleUK that handles 64 bit integer data. - -Main Changes in V7.0.2 ----------------------- - -- The libast_pal library is no longer built if the "--with-external_pal" -option is used when AST is configured. - - -Main Changes in V7.0.1 ----------------------- - -- The levmar and wcslib code distributed within AST is now stored in the -main AST library (libast.so) rather than in separate libraries. - - -Main Changes in V7.0.0 ----------------------- - -- Fundamental positional astronomy calculations are now performed -using the IAU SOFA library where possible, and the Starlink PAL library -otherwise (the PAL library contains a subset of the Fortran Starlink SLALIB -library re-written in C). Copies of these libraries are bundled with AST -and so do not need to be obtained or built separately, although external -copies of SOFA and PAL can be used if necessary by including the -"--with-external_pal" option when configuring AST. - - -Main Changes in V6.0-1 ------------------------ - -- The Spitzer "-SIP" distortion code is now recognised within FITS -headers that describe non-celestial axes, as well as celestial axes. - -- A bug has been fixed that could cause inappropriate equinox values to -be used when aligning SkyFrames if the AlignSystem attribute is set. - -- The format of the version string for AST has changed from -".-" to "..". - -Main Changes in V6.0 ------------------------ - -- This version of AST is the first that can be used with the Python -AST wrapper module, starlink.Ast, available at http://github.com/timj/starlink-pyast. - -- When reading a FITS-WCS header, the FitsChan class now recognises the -non-standard "TPV" projection code within a CTYPE keyword value. This -code is used by SCAMP (see www.astromatic.net/software/scamp) to -represent a distorted TAN projection. - -- The Plot class has been changed to remove visual anomalies (such as -incorrectly rotated numerical axis labels) if the graphics coordinates have -unequal scales on the X and Y axes. - -- The graphics escape sequences used to produce graphical sky axis labels -can now be changed using the new function astTuneC (AST_TUNEC). - -Main Changes in V5.7-2 ------------------------ - -- The PolyMap class can now use an iterative Newton-Raphson method to -evaluate the inverse the inverse transformation if no inverse -transformation is defined when the PolyMap is created. - -- The FitsChan class has a new method astWriteFits (AST_WRITEFITS) -which writes out all cards currently in the FitsChan to the associated -external data sink (specified either by the SinkFile attribute or the -sink function supplied when the FitsChan was created), and then empties -the FitsChan. - -- The FitsChan class has a new method astReadFits (AST_READFITS) -which forces the FitsChan to reads cards from the associated external -source and appends them to the end of the FitsChan. - -- The FitsChan class has a new read-only attribute called "Nkey", which -holds the number of keywords for which values are held in a FitsChan. - -- The FitsChan class has a new read-only attribute called "CardType", which -holds the data type of the keyword value for the current card. - -- The FitsChan astGetFits (AST_GETFITS) methods can now be used to -returned the value of the current card. - -- If the FitsChan astRead method reads a FITS header that uses the --SIP (Spitzer) distortion code within the CTYPE values, but which does -not provide an inverse polynomial correction, and for which the PolyTran -method of the PolyMap class fails to create an accurate estimate of the -inverse polynomial correction, then an iterative method will be used to -evaluate the inverse correction for each point transformed. - -- The Object class has a new function astToString (C only), which creates -an in-memory textual serialisation of a given AST Object. A corresponding -new function called astFromString re-creates the Object from its -serialisation. - - -Main Changes in V5.7-1 ------------------------ - -- All classes of Channel can now read to and write from specified text -files, without the need to provide source and sink functions when the -Channel is created. The files to use are specified by the new attributes -SourceFile and SinkFile. - -- The FitsChan class now ignores trailing spaces in character-valued WCS -keywords when reading a FrameSet from a FITS header. - -- If the FitsChan astRead method reads a FITS header that uses the -SIP -(Spitzer) distortion code within the CTYPE values, but which does not -provide an inverse polynomial correction, the FitsChan class will now use -the PolyTran method of the PolyMap class to create an estimate of the -inverse polynomial correction. - - - -Main Changes in V5.7-0 ------------------------ - -- The FitsChan class support for the IRAF-specific "TNX" projection has -been extended to include reading TNX headers that use a Chebyshev -representation for the distortion polynomial. - -- The FitsChan class support for the IRAF-specific "ZPX" projection has -been extended to include reading ZPX headers that use simple or Chebyshev -representation for the distortion polynomial. - -- A bug has been fixed in the FitsChan class that caused headers -including the Spitzer "-SIP" distortion code to be read incorrectly if no -inverse polynomial was specified in the header. - -- A new attribute called PolyTan has been added to the FitsChan class. It -can be used to indicate that FITS headers that specify a TAN projection -should be interpreted according to the "distorted TAN" convention -included in an early draft of FITS-WCS paper II. Such headers are created -by (for instance) the SCAMP tool (http://www.astromatic.net/software/scamp). - -- The PolyMap class now provides a method called astPolyTran (AST_POLYTRAN) -that adds an inverse transformation to a PolyMap by sampling the forward -transformation on a regular grid, and then fitting a polynomial function -from the resulting output values to the grid of input values. - - -Main Changes in V5.6-1 ------------------------ - -- Tables can now have any number of parameters describing the global -properties of the Table. - -- Frames now interpret the unit string "A" as meaning "Ampere" rather -than "Angstrom", as specified by FITS-WCS paper I. - -- A bug has been fixed in the astFindFrame (AST_FINDFRAME) method that -allowed a template Frame of a more specialised class to match a target -frame of a less specialised class. For example, this bug would allow a -template SkyFrame to match a target Frame. This no longer happens. - - -Main Changes in V5.6-0 ------------------------ - -- New functions astBBuf (AST_BBUF) and astEBuf (AST_EBUF) have been added -to the Plot class. These control the buffering of graphical output -produced by other Plot methods. - -- New functions astGBBuf and astGEBuf have been added to the interface -defined by file grf.h. The ast_link command has been modified so that the --grf_v3.2 switch loads dummy versions of the new grf functions. This -means that applications that use the -grf_v3.2 switch should continue to -build without any change. However, the new public functions astBBuf and -astEBuf described in the previous item will report an error unless the -new grf functions are implemented. If you choose to implement them, you -should modify your linking procedure to use the -grf (or -grf_v5.6) -switch in place of the older -grf_v3.2 switch. See the description of the -ast_link command for details of these switches. - -- New method astGetRegionMesh (AST_GETREGIONMESH) returns a set of -positions covering the boundary, or volume, of a supplied Region. - -Main Changes in V5.5-0 ------------------------ - -- The FitsChan "TabOK" attribute is now an integer value rather -than a boolean value. As in previous versions, it is used to indicate -whether the "-TAB" algorithm should be supported by the astRead -(AST_READ) and astWrite (AST_WRITE) methods, but in addition it is now -also used to give the version number to assign to any table gebnerated as -a consequence of calling astWrite (AST_WRITE). A negative or zero value -(the default) indicates that support for the -TAB algorithm is not -available, where as a positive non-zero value indicates that support is -available and also gives the table version number to use when creating -subsequent -TAB headers. - - -Main Changes in V5.4-0 ------------------------ - -- The FitsChan class now has an option to support reading and writing -of FITS-WCS headers that use the -TAB algorithm described in FITS-WCS paper -III. This option is controlled by a new FitsChan attribute called TabOK. -See the documentation for TabOK for more information. - -- A new class called "Table" has been added. A Table is a KeyMap in -which each entry represents a cell in a two-dimensional table. - -- A new class called "FitsTable" has been added. A FitsTable is a -Table that has an associated FitsChan holding headers appropriate to a -FITS binary table. - -- KeyMaps can now hold byte (i.e. "unsigned char" or BYTE) values. - -- A new method called astMapRename (AST_MAPRENAME) has been added to rename -an existing entry in a KeyMap. - -- KeyMaps have a new attribute called KeyCase that can be set to zero to -make the handling of keys case insensitive. - -Main Changes in V5.3-2 ------------------------ - -- A bug has been fixed in the FitsChan class that could cause wavelength -axes to be assigned the units "m/s" when reading WCS information from a -FITS header. - -- The astSet function (AST_SET) now allows literal commas to be included in -string attribute values. String attribute values that include a literal -comma should be enclosed in quotation marks. - -- A bug in FitsChan has been fixed that caused "-SIN" projection codes within -FITS-WCS headers to be mis-interpreted, resulting in no FrameSet being -read by astRead. - -- The KeyMap class has a new attribute called "SortBy". It controls -the order in which keys are returned by the astMapKey (AST_MAPKEY) function. -Keys can be sorted alphabetically or by age, or left unsorted. - -- Access to KeyMaps holding thousands of entries is now significantly -faster. - -- KeyMaps can now hold word (i.e. "short int" or INTEGER*2) values. - -Main Changes in V5.3-1 ------------------------ - -- The KeyMap class has a new method called astMapCopy/AST_MAPCOPY that -copies entries from one KeyMap to another KeyMap. - -- The KeyMap class now supports entries that have undefined values. A -new method called astMapPutU/AST_MAPPUTU will store an entry with undefined -value in a keymap. - -- The KeyMap class has a new boolean attribute called MapLocked. If true -(non-zero), an error is reported if an attempt is made to add any new entries -to a KeyMap (the value associated with any old entry may still be changed # -without error). The default is false (zero). - -- The Object class has a new method called astHasAttribute/AST_HASATTRIBUTE -that returns a boolean value indicating if a specified Object has a named -attribute. - -- The SkyFrame class has two new read-only boolean attributes called -IsLatAxis and IsLonAxis that can be used to determine the nature of a -specified SkyFrame axis. - -- A bug has been fixed in the astRebin(Seq)/AST_REBIN(SEQ) methods -that could cause flux to be lost from the edges of the supplied array. - -- A bug has been fixed in the astRebin(Seq)/AST_REBIN(SEQ) methods -that caused the first user supplied parameter to be interpreted as the -full width of the spreading kernel, rather than the half-width. - -- The StcsChan class now ignores case when reading STC-S phrases (except -that units strings are still case sensitive). - -- The Channel class now has an Indent attribute that controls indentation -in the text created by astWrite/AST_WRITE. The StcsIndent and XmlIndent -attributes have been removed. - -- All classes of Channel now use the string "" to represent the -floating point value AST__BAD, rather than the literal formatted value -(typically "-1.79769313486232e+308" ). - -- The KeyMap class now uses the string "" to represent the -floating point value AST__BAD, rather than the literal formatted value -(typically "-1.79769313486232e+308" ). - -- The KeyMap class has a new method called astMapPutElem/AST_MAPPUTELEM -that allows a value to be put into a single element of a vector entry in -a KeyMap. The vector entry is extended automatically to hold the new -element if required. - -- The DSBSpecFrame class now reports an error if the local oscillator -frequency is less than the absoliute value of the intermediate frequency. - -- A new method astQuadApprox produces a quadratic fit to a 2D Mapping. - -- A new method astSkyOffsetMap produces a Mapping from absolute SkyFrame -coordinates to offset SkyFrame coordinates. - - -Main Changes in Version 5.3 ---------------------------- - -- The details of how a Frame is aligned with another Frame by the -astFindFrame and astConvert (AST_FINDFRAME and AST_CONVERT) functions -have been changed. The changes mean that a Frame can now be aligned with -an instance of a sub-class of Frame, so long as the number of axes and -the Domain values are consistent. For instance, a basic 2-dimensional -Frame with Domain "SKY" will now align succesfully with a SkyFrame, -conversion between the two Frames being achieved using a UnitMap. - -- The arrays that supply input values to astMapPut1 are now declared -"const". - -- Added method astMatchAxes (AST_MATCHAXES) to the Frame class. This -allows corresponding axes in two Frames to be identified. - -- The astAddFrame (AST_ADDFRAME) method can now be used to append one or -more axes to all Frames in a FrameSet. - - -Main Changes in Version 5.1 ---------------------------- - -- A new method called astSetFitsCM (AST_SETFITSCM) has been added to -the FitsChan class. It stores a pure comment card in a FitsChan (that -is, a card with no keyword name or equals sign). - -- A new attribute called ObsAlt has been added to the Frame class. It -records the geodetic altitude of the observer, in metres. It defaults to -zero. It is used when converting times to or from the TDB timescale, or -converting spectral positions to or from the topocentric rest frame, or -converting sky positions to or from horizon coordinates. The FitsChan -class will include its effect when creating a set of values for the -OBSGEO-X/Y/Z keywords, and will also assign a value to it when reading a -set of OBSGEO-X/Y/Z keyword values from a FITS header. - -- The TimeMap conversions "TTTOTDB" and "TDBTOTT", and the SpecMap -conversions "TPF2HL" and "HLF2TP", now have an additional argument - -the observer's geodetic altitude. - -- The Polygon class has been modified to make it consistent with the -IVOA STC definition of a Polygon. Specifically, the inside of a polygon -is now the area to the left of each edge as the vertices are traversed in -an anti-clockwise manner, as seen from the inside of the celestial sphere. -Previously, AST used the anti-clockwise convention, but viewed from the -outside of the celestial sphere instead of the inside. Any Polygon saved -using previous versions of AST will be identified and negated automatically -when read by AST V5.2. - -- A new class of Channel, called StcsChan, has been added that allows -conversion of suitable AST Objects to and from IVOA STC-S format. - -- A new method called astDownsize (AST_DOWNSIZE) has been added to the -Polygon class. It produces a new Polygon that contains a subset of the -vertices in the supplied Polygon. The subset is chosen to retain the main -features of the supplied Polygion, in so far as that is possible, within -specified constraints. - -- A new constructor called astOutline (AST_OUTLINE) has been added to the -Polygon class. Given a 2D data array, it identifies the boundary of a -region within the array that holds pixels with specified values. It then -creates a new Polygon to describe this boundary to a specified accuracy. - -- A new method called astRemoveRegions (AST_REMOVEREGIONS) has been added -to the Mapping class. It removes the masking effects of any Regions found -within a (possibly compound) Mapping or Frame. In effect, it replaces -each Region found within the Mapping or Frame with a UnitMap or -equivalent Frame. - -- A new set of methods, called astMapGetElem (AST_MAPGETELEM) has -been added to the KeyMap class. They allow a single element of a vector -valued entry to be returned. - -- A new attribute called KeyError has been added to the KeyMap Class. It -controls whether the astMapGet... (AST_MAPGET...) family of functions report -an error if an entry with the requested key does not exist in the KeyMap. - -Main Changes in Version 5.1 ---------------------------- - -- The astUnlock function now has an extra parameter that controls whether -or not an error is reported if the Object is currently locked by another -thread. - -- The values of the AST__THREADSAFE macro (defined in ast.h) have -been changed from "yes" and "no" to "1" and "0". - -- The PointList class has a new method, astPoints, that copies the axis -values from the PointList into a supplied array. - -- The PointList class has a new (read-only) attribute, ListSize, that -gives the number of points stored in the PointList. - -- A new method (astIntersect) has been added to the Frame class. It -determines the position at which two geodesic curves intersect. - -- The XmlStrict attribute and astXmlWarnings function have been removed. -The same functionality is now available via the existing Strict attribute, -a new attribute called ReportLevel, and a new function called astWarnings. - -- A bug in the type-checking of Objects passed as arguments to constructor -functions has been fixed. This bug could lead to applications crashing or -showing strange behaviour if an inappropriate class of Object was -supplied as an argument to a constructor. - -- The astPickAxes function will now return a Region, if possible, when -applied to a Region. If this is not possible, a Frame will be returned as -before. - -- The default gap size between the ISO date/time labels used by the Plot -class when displaying an annotated axis described by a TimeFrame has been -changed. The changes are meant to improve the labelling of calendar time -axes that span intervals from a day to a few years. - -Main Changes in Version 5.0 ---------------------------- - -- AST is now thread-safe. Many of the macro definitions in the "ast.h" -header file have changed, and so all source code that include "ast.h" -should be re-compiled. - -- The TimeFrame class now support Local Time as a time scale. The offset -from UTC to Local Time is specified by a new TimeFrame attribute called -LTOffset. - -- Addition of a new class called Plot3D that provides facilities for -producing 3-dimensional annotated coordinate grids. - -- A correction for diurnal aberration is now included when -converting between AZEL and other celestial coordinate systems. The -correction is based on the value of the ObsLat Frame attribute (the -geodetic latitude of the observer). - -- A bug has been fixed which caused the DUT1 attribute to be ignored -by the SkyFrame class when finding conversions between AZEL and other -celestial coordinate systems. - -- The Channel class has a new attribute called Strict which controls -whether or not to report an error if unexpected data items are found -within an AST Object description read from an external data source. Note, -the default behaviour is now not to report such errors. This differs from -previous versions of AST which always reported an error is unexpected -input items were encountered. - - - -Main Changes in Version 4.5 ---------------------------- - -- All FITS-CLASS headers are now created with a frequency axis. If the -FrameSet supplied to astWrite contains a velocity axis (or any other form -of spectral axis) it will be converted to an equivalent frequency axis -before being used to create the FITS-CLASS header. - -- The value stored in the FITS-CLASS keyword "VELO-LSR" has been changed -from the velocity of the source to the velocity of the reference channel. - -- Addition of a new method call astPurgeWCS (AST_PURGEWCS) to the FitsChan -class. This method removes all WCS-related header cards from a FitsChan. - -- The astRebinSeq functions now have an extra parameter that is used to -record the total number of input data val;ues added into the output -array. This is necessary to correct a flaw in the calculation of output -variances based on the spread of input values. NOTE, THIS CHANGE WILL -REQUIRE EXISTING CODE THAT USES ASTREBINSEQ TO BE MODIFIED TO INCLUDE THE -NEW PARAMETER (CALLED "NUSED"). -- The Plot class now honours the value of the LabelUp attribute even if -numerical labels are placed around the edge of the Plot. Previously -LabelUp was only used if the labels were drawn within the interior of -the plot. The LabelUp attribute controls whether numerical labels are -drawn horizontally or parallel to the axis they describe. -- The Plot class has a new attribute called GrfContext that can be used -to comminicate context information between an application and any -graphics functions registered with the Plot class via the astGrfSet -(AST_GRFSET) function. -- Functions registered with the Plot class using astGrfSet (AST_GRFSET) -now take a new additional integer parameter, "grfcon". The Plot class -sets this parameter to value of the Plot's GrfContext attribute before -calling the graphics function. NOTE, THIS CHANGE WILL REQUIRE EXISTING -CODE THAT USES astGrfSet (AST_GRFSET) TO BE MODIFIED TO INCLUDE THE -NEW PARAMETER. -- Support has been added for the FITS-WCS "HPX" projection (HEALPix). -- A new flag "AST__VARWGT" can be supplied to astRebinSeq. This causes -the input data values to be weighted using the reciprocals of the input -variances (if supplied). -- The Frame class has a new read-only attribute called NormUnit that -returns the normalised value of the Unit attribute for an axis. Here, -"normalisation" means cancelling redundant units, etc. So for instance, a -Unit value of "s*(m/s)" would result in a NormUnit value of "m". -- A new method astShowMesh has been added to the Region class. It -displays a mesh of points covering the surface of a Region by writing out -a table of axis values to standard output. -- A bug has been fixed that could segmentation violations when setting -attribute values. - -Main Changes in Version 4.4 ---------------------------- - -- The astFindFrame (AST_FINDFRAME) method can now be used to search a -CmpFrame for an instance of a more specialised class of Frame (SkyFrame, -TimeFrame, SpecFrame, DSBSpecFrame or FluxFrame). That is, if an instance -of one of these classes is used as the "template" when calling -astFindFrame, and the "target" being searched is a CmpFrame (or a -FrameSet in which the current Frame is a CmpFrame), then the component -Frames within the CmpFrame will be searched for an instance of the -supplied template Frame, and, if found, a suitable Mapping (which will -include a PermMap to select the required axes from the CmpFrame) will be -returned by astFindFrame. Note, for this to work, the MaxAxes and MinAxes -attributes of the template Frame must be set so that they cover a range -that includes the number of axes in the target CmpFrame. - -- The DSBSpecFrame class has a new attribute called AlignSB that -specifies whether or not to take account of the SideBand attributes when -aligning two DSBSpecFrames using astConvert (AST_CONVERT). - -- The Frame class has a new attribute called Dut1 that can be used to -store a value for the difference between the UT1 and UTC timescales at -the epoch referred to by the Frame. - -- The number of digits used to format the Frame attributes ObsLat and -ObsLon has been increased. - -- The use of the SkyFrame attribute AlignOffset has been changed. This -attribute is used to control how two SkyFrames are aligned by astConvert. -If the template and target SkyFrames both have a non-zero value for -AlignOffset, then alignment occurs within the offset coordinate systems -(that is, a UnitMap will always be used to align the two SkyFrames). - -- The Plot class has a new attribute called ForceExterior that can be -used to force exterior (rather than interior) tick marks to be produced, -even if this would result in less than 3 tick marks being produced. - -- The TimeFrame class now supports conversion between angle based -timescales such as UT1 and atomic based timescales such as UTC. - - -Main Changes in Version 4.3 ---------------------------- - -- The SpecFrame class has a new attribute called SourceSys that specified -whether the SourceVel attribute (which specifies the rest frame of the -source) should be accessed as an apparent radial velocity or a redshift. -Note, any existing software that assumes that SourceVel always represents -a velocity in km/s should be changed to allow for the possibility of -SourceVel representing a redshift value. - -- The astGetFitsS (AST_GETFITSS) function now strips trailing white space -from the returned string, if the original string contains 8 or fewer -characters. - - -Main Changes in Version 4.2 ---------------------------- - -- The SideBand attribute of the DSBSpecFrame class can now take the -option "LO" in addition to "USB" and "LSB". The new option causes the -DSBSpecFrame to represent the offset from the local oscillator frequency, -rather than either of the two sidebands. - -- The FitsChan class has been changed so that it writes out a VELOSYS -keyword when creating a FITS-WCS encoding (VELOSYS indicates the -topocentric apparent velocity of the standard of rest). FitsChan also -strips out VELOSYS keywords when reading a FrameSet from a FITS-WCS -encoding. - -- The FitsChan class has a new method called astRetainFits (AST_RETAINFITS) -that indicates that the current card in the FitsChan should not be -stripped out of the FitsChan when an AST Object is read from the FitsChan. -Unless this method is used, all cards that were involved in the creation -of the AST Object will be stripped from the FitsChan afte a read operation. - -- The ast_link_adam and ast_link scripts now ignore the -fsla and -csla -options, and always link against the minimal cut-down version of SLALIB -distributed as part of AST. - -- A problem with unaligned memory access that could cause bus errors on -Solaris has been fixed. - -- A new function called astTune (or AST_TUNE) has been added which can be -used to get and set global AST tuning parameters. At the moment there are -only two such parameter, both of which are concerned with memory management -within AST. - -- A new method called astTranGrid (AST_TRANGRID in Fortran) has been -added to the Mapping class. This method creates a regular grid of points -covering a rectangular region within the input space of a Mapping, and -then transforms this set of points into the output space of the Mapping, -using a piecewise-continuous linear approximation to the Mapping if -appropriate in order to achive higher speed. - -- A new subclass of Mapping has been added called SwitchMap. A -SwitchMap represents several alternate Mappings, each of which is used to -transforms input positions within a different region of the input -coordinate space. - -- A new subclass of Mapping has been added called SelectorMap. A -SelectorMap tests each input position to see if it falls within one of -several Regions. If it does, the index of the Region containing the -input position is returned as the Mapping output. - -- The behaviour of the astConvert (AST_CONVERT) method when trying to -align a CmpFrame with another Frame has been modified. If no conversion -between positions in the Frame and CmpFrame can be found, an attempt is -now made to find a conversion between the Frame and one of two component -Frames contained within the CmpFrame. Thus is should now be possible to -align a SkyFrame with a CmpFrame containing a SkyFrame and a SpecFrame -(for instance). The returned Mapping produces bad values for the extra -axes (i.e. for the SpecFrame axis in the above example). - -Main Changes in Version 4.1 ---------------------------- - -- A new control flag has been added to the AST_RESAMPLE/astResample -functions which produces approximate flux conservation. - -- The SkyFrame class now supports a System value of "AZEL" corresponding -to horizon (azimuth/elevation) coordinates. - -- The FitsChan class allows the non-standard strings "AZ--" and "EL--" to -be used as axis types in FITS-WCS CTYPE keyword values. - -- The Frame class now has attributes ObsLon and ObsLat to specify -the geodetic longitude and latitude of the observer. - -- The ClockLon and ClockLat attributes have been removed from the -TimeFrame class. Likewise, the GeoLon and GeoLat attributes have been -removed from the SpecFrame class. Both classes now use the ObsLon and -ObsLat attributes of the parent Frame class instead. However, the old -attribute names can be used as synonyms for ObsLat and ObsLon. Also, -dumps created using the old scheme can be read succesfully by AST V4.1 -and converted to the new form. - -- A new function astMapSplit has been added to the Mapping class. This -splits a Mapping into two component Mappings which, when combined in -parallel, are equivalent to the original Mapping. - -- The default value for the SkyRefIs attribute has been changed from -"Origin" to "Ignored". This means that if you want to use a SkyFrame -to represent offsets from some origin position, you must now set the -SkyRefIs attribute explicitly to either "Pole" or "Origin", in addition -to assigning the required origin position to the SkyRef attribute. - - -Main Changes in Version 4.0 ---------------------------- - -- Experimental support for reading IVOA Space-Time-Coordinates (STC) -descriptions using the XmlChan class has been added. Support is included -for a subset of V1.20 of the draft STC specification. - -- A new set of methods (AST_REBIN/astRebin) has been added to -the Mapping class. These are accurately flux-conserving alternatives to the -existing AST_RESAMPLE/astResample methods. - - -Main Changes in Version 3.7 ---------------------------- - -- Support for time coordinate systems has been introduced throught the -addition of two new classes, TimeFrame and TimeMap. The TimeFrame is a -1-dimensional Frame which can be used to describe moments in time (either -absolute or relative) in various systems (MJD, Julian Epoch, etc.) and -referred to various time scales (TAI, UTC, UT1, GMST, etc). The TimeMap -is a Mapping which can transform time values between these various -systems and time scales. - - -Main Changes in Version 3.6 ---------------------------- - -- If the Format attribute associated with an axis of a SkyFrame starts -with a percent character (%), then axis values are now formatted and -unformatted as a decimal radians value, using the Format syntax of a -simple Frame. - -- The Plot class has a new attribute called Clip which controls the -clipping performed by AST at the plot boundary. - -- The PolyMap class has been modified to allow a PolyMap to be written -succesfully to a FitsChan using Native encoding. - -- A mimimal cut down subset of the C version of SLALIB is now included -with the AST distribution and built as part of building AST. This means -that it is no longer necessary to have SLALIB installed separately at -your site. The SLALIB code included with AST is distrubuted under the -GPL. The default behaviour of the ast_link script is now to link with -this internal slalib subset. However, the ``-csla'' option can still be -used to force linking with an external full C SLALIB library. A new -option ``-fsla'' has been introduced which forces linking with the -external full Fortran SLALIB library. - - -Main Changes in Version 3.5 ---------------------------- - -- AST now provides facilities for representing regions of various -shapes within a coordinate system. The Region class provides general -facilities which are independent of the specific shape of region being -used. Various sub-classes of Region are also now available which provide -means of creating Regions of specific shape. Facilities provided by the -Region class include testing points to see if they are inside the -Region, testing two Regions for overlap, transforming Regions from one -coordinate system to another, etc. - -- A new class of 1-dimensional Frame called FluxFrame has been added which -can be used to describe various systems for describing ovserved value at a -single fixed spectral position. - -- A new class of 2-dimensional Frame called SpecFluxFrame has been added which -can be used to describe a 2-d frame spanned by a spectral position axis -and and an observed value axis. - -- A new class of Mapping called RateMap has been added. A RateMap encapsulates -a previously created Mapping. The inputs of the RateMap correspond to the -inputs of the encapsulated Mapping. All RateMaps have just a single -output which correspond to the rate of change of a specified output of -the encapsulated Mapping with respect to a specified input. - -- The SkyFrame class now supports a value of "J2000" for System. This -system is an equatorial system based on the mean dynamical equator and -equinox at J2000, and differs slightly from an FK5(J2000) system. - -- Methods have been added to the FitsChan class to allow values for named -keywords to be changed or added. - -- The parameter list for the astRate method of the Mapping class has been -modified. It no longer returns a second derivative estimate. Existing -code which uses the astRate (AST_RATE) method will need to be changed. diff --git a/ast/ast_cpp.in b/ast/ast_cpp.in deleted file mode 100644 index c4fb206..0000000 --- a/ast/ast_cpp.in +++ /dev/null @@ -1,11 +0,0 @@ - -# Replacement for the C pre-processor command "cpp" which is not -# always available. This uses the compiler command "cc" to do the same -# thing. Also, this reads from standard input (which "cc" won't do). -# -# The name of the CPP processor is substituted in by the ./configure script, -# based on the result of the AC_PROG_CPP test. - -cat >/tmp/ast_cpp_$$.c -@CPP@ /tmp/ast_cpp_$$.c -rm -f /tmp/ast_cpp_$$.c diff --git a/ast/ast_dev b/ast/ast_dev deleted file mode 100644 index a073e9a..0000000 --- a/ast/ast_dev +++ /dev/null @@ -1,86 +0,0 @@ - -# N.B. the previous line should be blank. -#++ -# Name: -# ast_dev - -# Purpose: -# Create links to AST include files. - -# Type of Module: -# Shell script. - -# Description: -# This command creates (or removes) symbolic links in your current -# directory which refer to the AST include files. It is provided so -# that you may develop software which uses these files without having -# to know where they reside. - -# Invocation: -# ast_dev [option] - -# Arguments: -# option -# If no value is supplied for this argument, symbolic links to AST -# include files (for both Fortran and C) are created in your current -# directory. If the value ``remove'' is given, these links are -# removed. Any other value results in an error. - -# Examples: -# ast_dev -# Creates links to the AST include files in your current directory. -# ast_dev remove -# Removes any links to the AST include files from your current -# directory. - -# Copyright: -# Copyright (C) 1997-2006 Council for the Central Laboratory of the Research Councils - -# Authors: -# RFWS: R.F. Warren-Smith (STARLINK, RAL) -# DSB: David S. Berry (STARLINK) -# {enter_new_authors_here} - -# History: -# 11-NOV-1996 (RFWS): -# Original version. -# 18-NOV-1997 (RFWS): -# Adapted prologue for document extraction. -# 13-JUN-2001 (DSB): -# Added GRF_PAR. -# {enter_changes_here} - -# Bugs: -# {note_any_bugs_here} - -#-- - -# Implementation Notes: -# The pathname of the installation include directory (e.g. /star/include) -# must be edited into this script when it is installed. This is normally -# done by the makefile. - -# Interpret command line. - case "${1}" in - -# No arguments: create appropriate links. - '') - LINK INSTALL_INC/ast.h ast.h - LINK INSTALL_INC/ast_par AST_PAR - LINK INSTALL_INC/ast_err AST_ERR - LINK INSTALL_INC/grf_par GRF_PAR - ;; - -# Argument is "remove": delete links. - remove) - rm -f ast.h AST_PAR AST_ERR GRF_PAR - ;; - -# Any other argument is invalid: report an error. - *) - echo "ast_dev: invalid argument \"${1}\" given" >&2 - exit 1 - ;; - esac - -# End of script. diff --git a/ast/ast_err.msg b/ast/ast_err.msg deleted file mode 100644 index 6e42091..0000000 --- a/ast/ast_err.msg +++ /dev/null @@ -1,214 +0,0 @@ -.TITLE AST_ERR -.FACILITY AST,1521/PREFIX=AST__ -!author R.F. Warren-Smith & D.S. Berry (STARLINK) - -.SEVERITY ERROR -.BASE 300 - -ATGER -ATSER -ATTIN -AXIIN -BADAT -BADBX -BADIN -BADNI -BADNO -BADPW -BADSM -BADWM -BDBRK -BDFMT -BDFTS -BDOBJ -CLPAX -CORNG -CVBRK -DIMIN -DTERR -ENDIN -EOCHN -EXPIN -FCRPT -FMTER -FRMIN -FRSIN -FTCNV -GRFER -INHAN -INNCO -INTER -INTRD -KYCIR -LDERR -LUTII -LUTIN -MEMIN -MTR23 -MTRAX -MTRML -MTRMT -NAXIN -NCHIN -NCOIN -NCPIN -NELIN -NOCTS -NODEF -NOFTS -NOMEM -NOPTS -NOWRT -NPTIN -OBJIN -OPT -PDSIN -PLFMT -PRMIN -PTRIN -PTRNG -RDERR -REGIN -REMIN -SCSIN -SELIN -SLAIN -TRNND -UNMQT -VSMAL -WCSAX -WCSNC -WCSPA -WCSTY -XSOBJ -ZOOMI - -! New codes introduced for V1.1. -BADCI -ILOST -ITFER -ITFNI -MBBNF -MRITF -OCLUK -UNFER -URITF - -! New codes introduced for V1.2. -GBDIN -NGDIN -PATIN -SISIN -SSPIN - -! New codes introduced for V1.3. -UINER -UK1ER - -! New codes introduced for V1.4. -COMIN -CONIN -DUVAR -INNTF -MIOPA -MIOPR -MISVN -MLPAR -MRPAR -NORHS -UDVOF -VARIN -WRNFA - -! New codes introduced for V2.0. -BADUN -NORSF -NOSOR -SPCIN - -! New codes introduced for V3.1 -XMLNM -XMLCM -XMLPT -XMLIT -XMLWF - -! New codes introduced for V3.2 -ZERAX - -! New codes introduced for V3.3 -BADOC - -! New codes introduced for V3.5-2 -MPGER -MPIND - -! New codes introduced for V3.6 -REGCN -NOVAL -INCTS -TIMIN -STCKEY -STCIND - -! New codes introduced for V4.0 -CNFLX -TUNAM -BDPAR - - -! New codes introduced for V4.6 -3DFSET -PXFRRM -BADSUB -BADFLG - -! New codes introduced for V5.0 -LCKERR -FUNDEF - -! New codes introduced for V5.2 -MPVIN -OPRIN -NONIN -MPKER -MPPER -BADKEY - -! New codes introduced for V5.4 -BADTYP -OLDCOL -BADNULL -BIGKEY -BADCOL -BIGTAB -BADSIZ -BADTAB -NOTAB - -! New codes introduced for V5.7 -LEVMAR -NOFIT -ISNAN -WRERR - -! New codes introduced for V7.3 -BDVNM -MIRRO - -! New codes introduced for V8.0 -MNPCK - -! New codes introduced for V8.0.3 -EXSPIX - -! New codes introduced for V8.0.4 -NOCNV - -! New codes introduced for V8.2.0 -IMMUT - -! New codes introduced for V8.5.0 -NOBOX - -.END diff --git a/ast/ast_link.in b/ast/ast_link.in deleted file mode 100644 index c5759e2..0000000 --- a/ast/ast_link.in +++ /dev/null @@ -1,463 +0,0 @@ - -# N.B. the previous line should be blank. -#++ -# Name: -# ast_link - -# Purpose: -# Link a program with the AST library. - -# Type of Module: -# Shell script. - -# Description: -# This command should be used when building programs which use the AST -# library, in order to generate the correct arguments to allow the compiler -# to link your program. The arguments generated are written to standard -# output but may be substituted into the compiler command line in the -# standard UNIX way using backward quotes (see below). -# -# By default, it is assumed that you are building a stand-alone program -# which does not produce graphical output. However, switches are provided -# for linking other types of program. - -# Invocation: -#c cc program.c -L/star/lib `ast_link [switches]` -o program -#f f77 program.f -L/star/lib `ast_link [switches]` -o program - -# Switches: -# The following switches may optionally be given to this command to -# modify its behaviour: -# -# -# - ``-csla'': Ignored. Provided for backward compatibility only. -# -# - ``-fsla'': Ignored. Provided for backward compatibility only. -# -# - ``-ems'': Requests that the program be linked so that error messages -# produced by the AST library are delivered via the Starlink EMS (Error -# Message Service) library (Starlink System Note SSN/4). By default, -# error messages are simply written to standard error. -# -# - ``-drama'': Requests that the program be linked so that error messages -# produced by the AST library are delivered via the DRAMA Ers (Error -# Reporting Service) library. By default, error messages are simply -# written to standard error. -# -# - ``-grf'': Requests that no arguments be generated to specify which -# 2D graphics system is used to display output from the AST library. You -# should use this option only if you have implemented an interface to a -# new graphics system yourself and wish to provide your own arguments for -# linking with it. This switch differs from the other ``grf'' switches in -# that it assumes that your graphics module implements the complete -# interface required by the current version of AST. If future versions of -# AST introduce new functions to the graphics interface, this switch will -# cause ``unresolved symbol'' errors to occur during linking, warning you -# that you need to implement new functions in your graphics module. To -# avoid such errors, you can use one of the other, version-specific, -# switches in place of the ``-grf'' switch, but these will cause run-time -# errors to be reported if any AST function is invoked which requires -# facilities not in the implemented interface. -# -# - ``-grf_v2.0'': This switch is equivalent to the ``-mygrf'' switch. -# It indicates that you want to link with your own graphics module -# which implements the 2D graphics interface required by V2.0 of AST. -# -# - ``-grf_v3.2'': Indicates that you want to link with your own -# graphics module which implements the 2D graphics interface required by -# V3.2 of AST. -# -# - ``-grf_v5.6'': Indicates that you want to link with your own -# graphics module which implements the 2D graphics interface required by -# V5.6 of AST. -# -# - ``-myerr'': Requests that no arguments be generated to specify how -# error messages produced by the AST library should be delivered. You -# should use this option only if you have implemented an interface to a -# new error delivery system yourself and wish to provide your own -# arguments for linking with it. -# -# - ``-mygrf'': This switch has been superceeded by the ``-grf'' switch, -# but is retained in order to allow applications to be linked with a -# graphics module which implements the 2D interface used by AST V2.0. It -# is equivalent to the ``-grf_v2.0'' switch. -# -# - ``-pgp'': Requests that the program be linked so that 2D -# graphical output from the AST library is displayed via the -# Starlink version of the PGPLOT graphics package (which uses GKS -# for its output). By default, no 2D graphics package is linked and -# this will result in an error at run time if AST routines are -# invoked that attempt to generate graphical output. -# -# - ``-pgplot'': Requests that the program be linked so that 2D -# graphical output from the AST library is displayed via -# the standard (or ``native'') version of the PGPLOT graphics -# package. By default, no 2D graphics package is linked and this will -# result in an error at run time if AST routines are invoked that -# attempt to generate graphical output. -# -# - ``-grf3d'': Requests that no arguments be generated to specify which -# 3D graphics system is used to display output from the AST library. You -# should use this option only if you have implemented an interface to a -# new 3D graphics system yourself and wish to provide your own arguments -# for linking with it. -# -# - ``-pgp3d'': Requests that the program be linked so that 3D -# graphical output from the AST library is displayed via the -# Starlink version of the PGPLOT graphics package (which uses GKS -# for its output). By default, no 3D graphics package is linked and -# this will result in an error at run time if AST routines are -# invoked that attempt to generate graphical output. -# -# - ``-pgplot3d'': Requests that the program be linked so that 3D -# graphical output from the AST library is displayed via -# the standard (or ``native'') version of the PGPLOT graphics -# package. By default, no 3D graphics package is linked and this will -# result in an error at run time if AST routines are invoked that -# attempt to generate graphical output. - -# ERFA & PAL: -# The AST distribution includes bundled copies of the ERFA and PAL -# libraries. These will be used for fundamental positional astronomy -# calculations unless the "--with-external_pal" option was used when -# AST was configured. If "--with-external_pal" is used, this script -# will include "-lpal" in the returned list of linking options, and -# the user should then ensure that external copies of the PAL and -# ERFA libraries are available (ERFA functions are used within PAL). - -# Examples: -#c cc display.c -L/star/lib `ast_link -pgplot` -o display -#c Compiles and links a C program called ``display'' which uses -#c the standard version of PGPLOT for graphical output. -#c cc plotit.c -L. -L/star/lib `ast_link -grf` -lgrf -o plotit -#c Compiles and links a C program ``plotit''. The ``-grf'' -#c switch indicates that graphical output will be delivered through -#c a graphical interface which you have implemented yourself, which -#c corresponds to the interface required by the current version of AST. -#c Here, this interface is supplied by means of the ``-lgrf'' library -#c reference. -#c cc plotit.c -L. -L/star/lib `ast_link -grf_v2.0` -lgrf -o plotit -#c Compiles and links a C program ``plotit''. The ``-grf_v2.0'' -#c switch indicates that graphical output will be delivered through -#c a graphical interface which you have implemented yourself, which -#c corresponds to the interface required by version 2.0 of AST. -#c Here, this interface is supplied by means of the ``-lgrf'' library -#c reference. -#f f77 display.f -L/star/lib `ast_link -pgplot` -o display -#f Compiles and links a Fortran program called ``display'' which uses -#f the standard version of PGPLOT for graphical output. -#f f77 plotit.f -L. -L/star/lib `ast_link -grf` -lgrf -o plotit -#f Compiles and links a Fortran program ``plotit''. The ``-grf'' -#f switch indicates that graphical output will be delivered through -#f a graphical interface which you have implemented yourself, which -#f corresponds to the interface required by the current version of AST. -#f Here, this interface is supplied by means of the ``-lgrf'' library -#f reference. -#f f77 plotit.f -L. -L/star/lib `ast_link -grf_v2.0` -lgrf -o plotit -#f Compiles and links a Fortran program ``plotit''. The ``-grf_v2.0'' -#f switch indicates that graphical output will be delivered through -#f a graphical interface which you have implemented yourself, which -#f corresponds to the interface required by version 2.0 of AST. -#f Here, this interface is supplied by means of the ``-lgrf'' library -#f reference. - -# Copyright: -# Copyright (C) 1997-2006 Council for the Central Laboratory of the Research Councils -# Copyright (C) 2007-2008 Science & Technology Facilities Council. -# All Rights Reserved. - -# Authors: -# RFWS: R.F. Warren-Smith (STARLINK) -# DSB: David S. Berry (STARLINK) -# TIMJ: Tim Jenness (JAC, Hawaii) -# {enter_new_authors_here} - -# History: -# 11-JUN-1996 (RFWS): -# Original version. -# 11-NOV-1996 (RFWS): -# Added switches. -# 18-NOV-1997 (RFWS): -# Adapted prologue for document extraction. -# 28-SEP-1998 (RFWS): -# Distinguish between -pgp and -pgplot options. -# 12-JAN-2001 (DSB): -# Move terminating "}" in function "find" onto a new line to -# avoid error when run under bash 2.04.11(1) (redhat 7). -# 3-MAY-2001 (DSB): -# Added a terminating ";" to the "done" statement at the end of -# the "find" function, so that ast_link can be used on Debian Linux. -# 23-JAN-2004 (DSB): -# Added switches to support older grf implementations. -# 24-AUG-2004 (DSB): -# Removed f77='y' from -ems case. -# 21-APR-2005 (DSB): -# Added "-fsla" option. -# 16-JUN-2006 (DSB): -# Ignore "-fsla" and "-clsa" options, and always use PAL. -# 26-JUN-2007 (DSB): -# Added "-grf3d", "-pgplot3d" and "-pgp3d" flags. -# 13-NOV-2008 (TIMJ): -# Add -drama option for DRAMA Ers support. -# 3-MAR-2011 (DSB): -# Added grf 5.6 options. -# {enter_further_changes_here} - -# Bugs: -# {note_any_bugs_here} - -#-- - -# This line is edited during configuration of this script to define a list -# of the libraries that must be linked in order to resolve Fortran 77 -# references made from within a C main program. Typically, these will arise -# from libraries written in Fortran which the AST library (or the C -# program) calls. The value here is worked out by the autoconf macro -# AC_FC_LIBRARY_LDFLAGS. - flibs='@FCLIBS@' - -# This function searches the directory path specified in PATH, looking for -# an executable file which is not a directory. If found, it echos the full -# file name to standard output. Otherwise, it outputs nothing. - find() { IFS=':'; for d in $PATH; do f="${d:=.}/${1}" - test -x "${f}" -a ! -d "${f}" && echo "${f}" && break - done; - } - -# Initialise linking options. - err='' - grf='' - grf3d='' - sla='' - f77='' - -# Interpret command line switches. -# -------------------------------- - while :; do - case "${1}" in - -# -csla - Previously used to request C version of SLALIB. Now ignored. - -csla) -# sla='c' - shift;; - -# -fsla - Previously used to request Fortran version of SLALIB. Now ignored. - -fsla) -# sla='f' - shift;; - -# -ems - Requests error reporting through EMS. - -ems) - err='ems' - shift;; - -# -drama - Requests error reporting through DRAMA Ers. - -drama) - err='drama' - shift;; - -# -myerr - Requests no error reporting. - -myerr) - err='my' - shift;; - -# -grf - Requests no 2D graphics. - -grf) - grf='current' - shift;; - -# -mygrf - Requests no 2D graphics, except for null implementations of -# functions aded to the grf interface after AST V2.0. - -mygrf) - grf='v2.0' - shift;; - -# -grf_v2.0 - Requests no 2D graphics, except for null implementations of -# functions aded to the grf interface after AST V2.0. - -grf_v2.0) - grf='v2.0' - shift;; - -# -grf_v3.2 - Requests no 2D graphics, except for null implementations of -# functions aded to the grf interface after AST V3.2. - -grf_v3.2) - grf='v3.2' - shift;; - -# -grf_v5.6 - Requests no 2D graphics, except for null implementations of -# functions aded to the grf interface after AST V5.6. - -grf_v5.6) - grf='v5.6' - shift;; - -# -pgp - Requests 2D graphical output through Starlink PGPLOT. - -pgp) - grf='pgp' - shift;; - -# -pgplot - Requests 2D graphical output through native PGPLOT. - -pgplot) - grf='pgplot' - shift;; - -# -grf3d - Requests no 3D graphics. - -grf3d) - grf3d='current' - shift;; - -# -pgp3d - Requests 3D graphical output through Starlink PGPLOT. - -pgp3d) - grf3d='pgp' - shift;; - -# -pgplot3d - Requests 3D graphical output through native PGPLOT. - -pgplot3d) - grf3d='pgplot' - shift;; - -# Once all switches have been read, continue with the rest of the script. - '') break;; - -# Catch unrecognised arguments and report an error. - *) - echo >&2 "ast_link: unknown argument \""${1}"\" given" - exit 1;; - esac - done - -# Link with the main AST library. -# ------------------------------- -# Start forming the list of arguments with the main AST library itself. - args='-last ' - -# Generate arguments for linking PAL. -# ----------------------------------- - - case "@EXTERNAL_PAL@" in - -# If we configured --with-external_pal include a link option to pick up -# an external PAL library. - 1) args="${args} -lpal";; - -# Otherwise, use the internal PAL & ERFA libraries. - *) args="${args} -last_pal";; - - esac - -# Generate arguments for linking the 2D graphics system. -# ------------------------------------------------------ - case "${grf}" in - -# If using Starlink PGPLOT, link with the AST PGPLOT interface and -# the Fortran library via the PGP link script (if found). - pgp) args="${args} -last_pgplot `\`find pgp_link\``" - f77='y';; - -# If using native PGPLOT, link with the AST PGPLOT interface and the -# Fortran library via the PGPLOT link script (if found). - pgplot) args="${args} -last_pgplot `\`find pgplot_link\``" - f77='y';; - -# If using own graphics which conform to the requirements of the current -# version of AST, do not produce any arguments. - current) :;; - -# If using own graphics which conform to the requirements of version 5.6 -# of AST, produce arguments which link in dummy implementations of any -# functions which are required by the current version of AST but which were -# not required by version 5.6. - v5.6) :;; - -# If using own graphics which conform to the requirements of version 3.2 -# of AST, produce arguments which link in dummy implementations of any -# functions which are required by the current version of AST but which were -# not required by version 3.2. - v3.2) args="${args} -last_grf_5.6";; - -# If using own graphics which conform to the requirements of version 2.0 -# of AST, produce arguments which link in dummy implementations of any -# functions which are required by the current version of AST but which were -# not required by version 2.0. - v2.0) args="${args} -last_grf_3.2 -last_grf_5.6";; - -# Default graphics (none) requires linking with all the default (null) AST -# "grf" modules. - *) args="${args} -last_grf_2.0 -last_grf_3.2 -last_grf_5.6";; - esac - - -# Generate arguments for linking the 3D graphics system. -# ------------------------------------------------------ - case "${grf3d}" in - -# If using Starlink PGPLOT, link with the AST 3D PGPLOT interface and -# the Fortran library via the PGP link script (if found). - pgp) args="${args} -last_pgplot3d `\`find pgp_link\``" - f77='y';; - -# If using native PGPLOT, link with the AST 3D PGPLOT interface and the -# Fortran library via the PGPLOT link script (if found). - pgplot) args="${args} -last_pgplot3d `\`find pgplot_link\``" - f77='y';; - -# If using own 3D graphics which conform to the requirements of the current -# version of AST, do not produce any arguments. - current) :;; - -# Default graphics (none) requires linking with all the default (null) AST -# "grf3d" modules. - *) args="${args} -last_grf3d";; - esac - - - -# Make a second pass through the AST library. -# ------------------------------------------- -# This library is a link to the main AST library and results in a second -# pass to resolve any backward references generated by the other modules -# used above. A different library name must be used to avoid the two passes -# being merged into one (either below, or by other link scripts). - args="${args} -last_pass2" - -# Generate arguments for linking the error reporting system. -# ---------------------------------------------------------- - case "${err}" in - -# If using EMS, link with the AST EMS interface and the EMS library via the -# link script (if found). - ems) args="${args} -last_ems `\`find ems_link\``";; - -# If using DRAMA, link with the AST DRAMA interface and the DRAMA Ers library -# via the link script (if found). - drama) args="${args} -last_drama -lers";; - -# If using own error reporting, do not produce any arguments. - my) :;; - -# Default error reporting requires linking with the default AST "err" module. - *) args="${args} -last_err";; - esac - -# Link with the maths library. -# ---------------------------- - args="${args} -lm" - -# Link with the starmem library, if available. -# -------------------------------------------- - args="${args} `\`find starmem_link\``" - -# Resolve Fortran 77 references. -# ------------------------------ -# If libraries written in Fortran are being linked against, then include -# additional libaries needed to resolve the references these will produce -# (in the event that the main program is not Fortran). - if test "${f77}" = 'y'; then args="${args} ${flibs}"; fi - -# Pass the resulting argument list through an awk script which eliminates -# all except the last reference to each library. - echo "${args}" \ - | awk 'BEGIN{RS=" ";FS="\n"} - {if($1)f[i++]=$1} - END{for(;i--;)if(!w[f[i]]++)l=f[i]" "l;print l}' - -# End of script. diff --git a/ast/ast_link_adam.in b/ast/ast_link_adam.in deleted file mode 100644 index df93c6c..0000000 --- a/ast/ast_link_adam.in +++ /dev/null @@ -1,406 +0,0 @@ - -# N.B. the previous line should be blank. -#++ -# Name: -# ast_link_adam - -# Purpose: -# Link an ADAM program with the AST library. - -# Type of Module: -# Shell script. - -# Description: -# This command should only be used when building Starlink ADAM programs -# which use the AST library, in order to generate the correct arguments -# to allow the ADAM ``alink'' command to link the program. The arguments -# generated are written to standard output but may be substituted into -# the ``alink'' command line in the standard UNIX way using backward -# quotes (see below). -# -# By default, it is assumed that you are building an ADAM program which -# does not produce graphical output. However, switches are provided for -# linking other types of program. This command should not be used when -# building stand-alone (non-ADAM) programs. Use the ``ast_link'' command -# instead. - -# Invocation: -#c alink program.o -L/star/lib `ast_link_adam [switches]` -#f alink program.f -L/star/lib `ast_link_adam [switches]` - -# Switches: -# The following switches may optionally be given to this command to -# modify its behaviour: -# -# - ``-csla'': Ignored. Provided for backward compatibility only. -# -# - ``-fsla'': Ignored. Provided for backward compatibility only. -# -# - ``-grf'': Requests that no arguments be generated to specify which -# 2D graphics system is used to display output from the AST library. You -# should use this option only if you have implemented an interface to a -# new graphics system yourself and wish to provide your own arguments for -# linking with it. This switch differs from the other ``grf'' switches in -# that it assumes that your graphics module implements the complete -# interface required by the current version of AST. If future versions of -# AST introduce new functions to the graphics interface, this switch will -# cause ``unresolved symbol'' errors to occur during linking, warning you -# that you need to implement new functions in your graphics module. To -# avoid such errors, you can use one of the other, version-specific, -# switches in place of the ``-grf'' switch, but these will cause run-time -# errors to be reported if any AST function is invoked which requires -# facilities not in the implemented interface. -# -# - ``-grf_v2.0'': This switch is equivalent to the ``-mygrf'' switch. -# It indicates that you want to link with your own graphics module which -# implements the 2D graphics interface required by V2.0 of AST. -# -# - ``-grf_v3.2'': Indicates that you want to link with your own graphics -# module which implements the 2D graphics interface required by V3.2 of AST. -# -# - ``-grf_v5.6'': Indicates that you want to link with your own graphics -# module which implements the 2D graphics interface required by V5.6 of AST. -# -# - ``-myerr'': Requests that no arguments be generated to specify how -# error messages produced by the AST library should be delivered. You -# should use this option only if you have implemented an interface to a -# new error delivery system yourself and wish to provide your own -# arguments for linking with it. By default, error messages are delivered -# in the standard ADAM way via the EMS Error Message Service (Starlink -# System Note SSN/4). -# -# - ``-mygrf'': This switch has been superceeded by the ``-grf'' switch, -# but is retained in order to allow applications to be linked with a -# graphics module which implements the interface used by AST V2.0. It is -# equivalent to the ``-grf_v2.0'' switch. -# -# - ``-pgp'': Requests that the program be linked so that 2D -# graphical output from the AST library is displayed via the -# Starlink version of the PGPLOT graphics package (which uses GKS -# for its output). By default, no graphics package is linked and -# this will result in an error at run time if AST routines are -# invoked that attempt to generate graphical output. -# -# - ``-pgplot'': Requests that the program be linked so that 2D -# graphical output from the AST library is displayed via the -# standard (or ``native'') version of the PGPLOT graphics -# package. By default, no graphics package is linked and this will -# result in an error at run time if AST routines are invoked that -# attempt to generate graphical output. -# -# - ``-grf3d'': Requests that no arguments be generated to specify which -# 3D graphics system is used to display output from the AST library. You -# should use this option only if you have implemented an interface to a -# new 3D graphics system yourself and wish to provide your own arguments -# for linking with it. -# -# - ``-pgp3d'': Requests that the program be linked so that 3D -# graphical output from the AST library is displayed via the -# Starlink version of the PGPLOT graphics package (which uses GKS -# for its output). By default, no 3D graphics package is linked and -# this will result in an error at run time if AST routines are -# invoked that attempt to generate graphical output. -# -# - ``-pgplot3d'': Requests that the program be linked so that 3D -# graphical output from the AST library is displayed via -# the standard (or ``native'') version of the PGPLOT graphics -# package. By default, no 3D graphics package is linked and this will -# result in an error at run time if AST routines are invoked that -# attempt to generate graphical output. - -# SLALIB: -# The AST distribution includes a cut down subset of the C version of -# the SLALIB library written by Pat Wallace. This subset contains only -# the functions needed by the AST library. It is built as part of the -# process of building AST and is distributed under GPL (and is thus -# compatible with the AST license). Previous version of this script -# allowed AST applications to be linked against external SLALIB -# libraries (either Fortran or C) rather than the internal version. -# The current version of this script does not provide this option, -# and always uses the internal SLALIB library. However, for backward -# compatibility, this script still allows the "-fsla" and "-csla" flags -# (previously used for selecting which version of SLALIB to use) to be -# specified, but they will be ignored. - -# Examples: -#c alink display.o -L/star/lib `ast_link_adam -pgplot` -#c Links an ADAM program ``display'' which uses the standard -#c version of PGPLOT for graphical output. -#c alink plotit.o -L. -L/star/lib `ast_link_adam -grf` -lgrf -#c Links an ADAM program ``plotit'', written in C. The ``-grf'' -#c switch indicates that graphical output will be delivered through -#c a graphical interface which you have implemented yourself, which -#c corresponds to the interface required by the current version of AST. -#c Here, this interface is supplied by means of the ``-lgrf'' library -#c reference. -#c alink plotit.o -L. -L/star/lib `ast_link_adam -grf_v2.0` -lgrf -#c Links an ADAM program ``plotit'', written in C. The ``-grf_v2.0'' -#c switch indicates that graphical output will be delivered through -#c a graphical interface which you have implemented yourself, which -#c corresponds to the interface required by version 2.0 of AST. Here, -#c this interface is supplied by means of the ``-lgrf'' library -#c reference. -#f alink display.f -L/star/lib `ast_link_adam -pgplot` -#f Compiles and links an ADAM Fortran program called ``display'' which -#f uses the standard version of PGPLOT for graphical output. -#f alink plotit.f -L. -L/star/lib `ast_link_adam -grf` -lgrf -#f Compiles and links an ADAM Fortran program ``plotit''. The ``-grf'' -#f switch indicates that graphical output will be delivered through -#f a graphical interface which you have implemented yourself, which -#f corresponds to the interface required by the current version of AST. -#f Here, this interface is supplied by means of the ``-lgrf'' library -#f reference. -#f alink plotit.f -L. -L/star/lib `ast_link_adam -grf_v2.0` -lgrf -#f Compiles and links an ADAM Fortran program ``plotit''. The ``-grf_v2.0'' -#f switch indicates that graphical output will be delivered through -#f a graphical interface which you have implemented yourself, which -#f corresponds to the interface required by version 2.0 of AST. -#f Here, this interface is supplied by means of the ``-lgrf'' library -#f reference. - -# Copyright: -# Copyright (C) 1997-2006 Council for the Central Laboratory of the Research Councils - -# Authors: -# RFWS: R.F. Warren-Smith (STARLINK) -# {enter_new_authors_here} - -# History: -# 11-NOV-1996 (RFWS): -# Original version. -# 18-NOV-1997 (RFWS): -# Adapted prologue for document extraction. -# 28-SEP-1998 (RFWS): -# Distinguish between -pgp and -pgplot options. -# 23-JAN-2004 (DSB): -# Added switches to support older grf implementations. -# 21-APR-2005 (DSB): -# Added "-fsla" option. -# 16-JUN-2006 (DSB): -# Ignore "-fsla" and "-clsa" options, and always use PAL. -# 22-AUG-2007 (DSB): -# Added "-grf3d", "-pgplot3d" and "-pgp3d" flags. -# 4-MAR-2011 (DSB): -# Added v5.6 grf options. -# {enter_changes_here} - -# Bugs: -# {note_any_bugs_here} - -#-- - -# This function searches the directory path specified in PATH, looking for -# an executable file which is not a directory. If found, it echos the full -# file name to standard output. Otherwise, it outputs nothing. - find() { IFS=':'; for d in $PATH; do f="${d:=.}/${1}" - test -x "${f}" -a ! -d "${f}" && echo "${f}" && break - done; - } - -# Initialise linking options. - err='' - grf='' - grf3d='' - sla='' - -# Interpret command line switches. -# -------------------------------- - while :; do - case "${1}" in - -# -csla - Previously used to request C version of SLALIB. Now ignored. - -csla) -# sla='c' - shift;; - -# -fsla - Previously used to request Fortran version of SLALIB. Now ignored. - -fsla) -# sla='f' - shift;; - -# -myerr - Requests no error reporting. - -myerr) - err='my' - shift;; - -# -grf - Requests no 2D graphics. - -grf) - grf='current' - shift;; - -# -mygrf - Requests no 2D graphics, except for null implementations of -# functions aded to the grf interface after AST V2.0. - -mygrf) - grf='v2.0' - shift;; - -# -grf_v2.0 - Requests no 2D graphics, except for null implementations of -# functions aded to the grf interface after AST V2.0. - -grf_v2.0) - grf='v2.0' - shift;; - -# -grf_v3.2 - Requests no 2D graphics, except for null implementations of -# functions aded to the grf interface after AST V3.2. - -grf_v3.2) - grf='v3.2' - shift;; - -# -grf_v5.6 - Requests no 2D graphics, except for null implementations of -# functions added to the grf interface after AST V5.6. - -grf_v5.6) - grf='v5.6' - shift;; - -# -pgp - Requests 2D graphical output through Starlink PGPLOT. - -pgp) - grf='pgp' - shift;; - -# -pgplot - Requests 2D graphical output through native PGPLOT. - -pgplot) - grf='pgplot' - shift;; - -# -grf3d - Requests no 3D graphics. - -grf3d) - grf3d='current' - shift;; - -# -pgp3d - Requests 3D graphical output through Starlink PGPLOT. - -pgp3d) - grf3d='pgp' - shift;; - -# -pgplot3d - Requests 3D graphical output through native PGPLOT. - -pgplot3d) - grf3d='pgplot' - shift;; - -# Once all switches have been read, continue with the rest of the script. - '') break;; - -# Catch unrecognised switches and report an error. - *) - echo >&2 "ast_link_adam: unknown argument \""${1}"\" given" - exit 1;; - esac - done - -# Link with the main AST library. -# ------------------------------- -# Start forming the list of arguments with the main AST library itself. - args='-last' - -# Generate arguments for linking PAL. -# ----------------------------------- - - case "@EXTERNAL_PAL@" in - -# If we configured --with-external_pal include a link option to pick up -# an external PAL library. - 1) args="${args} -lpal";; - -# Otherwise, use the internal PAL & ERFA libraries. - *) args="${args} -last_pal";; - - esac - -# Generate arguments for linking the 2D graphics system. -# ------------------------------------------------------ - case "${grf}" in - -# If using Starlink PGPLOT, link with the AST PGPLOT interface and -# the Fortran library via the PGP link script. - pgp) args="${args} -last_pgplot `pgp_link_adam`";; - -# If using native PGPLOT, link with the AST PGPLOT interface and -# the Fortran library via the PGPLOT link script. - pgplot) args="${args} -last_pgplot `pgplot_link_adam`";; - -# If using own graphics which conform to the requirements of the current -# version of AST, do not produce any arguments. - current) :;; - -# If using own graphics which conform to the requirements of version 5.6 -# of AST, produce arguments which link in dummy implementations of any -# functions which are required by the current version of AST but which were -# not required by version 5.6. - v5.6) :;; - -# If using own graphics which conform to the requirements of version 3.2 -# of AST, produce arguments which link in dummy implementations of any -# functions which are required by the current version of AST but which were -# not required by version 3.2. - v3.2) args="${args} -last_grf_5.6";; - -# If using own graphics which conform to the requirements of version 2.0 -# of AST, produce arguments which link in dummy implementations of any -# functions which are required by the current version of AST but which were -# not required by version 2.0. - v2.0) args="${args} -last_grf_3.2 -last_grf_5.6";; - -# Default graphics (none) requires linking with all the default (null) AST -# "grf" modules. - *) args="${args} -last_grf_2.0 -last_grf_3.2 -last_grf_5.6";; - esac - -# Generate arguments for linking the 3D graphics system. -# ------------------------------------------------------ - case "${grf3d}" in - -# If using Starlink PGPLOT, link with the AST 3D PGPLOT interface and -# the Fortran library via the PGP link script (if found). - pgp) args="${args} -last_pgplot3d `\`find pgp_link\``" - f77='y';; - -# If using native PGPLOT, link with the AST 3D PGPLOT interface and the -# Fortran library via the PGPLOT link script (if found). - pgplot) args="${args} -last_pgplot3d `\`find pgplot_link\``" - f77='y';; - -# If using own 3D graphics which conform to the requirements of the current -# version of AST, do not produce any arguments. - current) :;; - -# Default graphics (none) requires linking with all the default (null) AST -# "grf3d" modules. - *) args="${args} -last_grf3d";; - esac - -# Make a second pass through the AST library. -# ------------------------------------------- -# This library is a link to the main AST library and results in a second -# pass to resolve any backward references generated by the other modules -# used above. A different library name must be used to avoid the two passes -# being merged into one (either below, or by other link scripts). - args="${args} -last_pass2" - -# Generate arguments for linking the error reporting system. -# ---------------------------------------------------------- - case "${err}" in - -# If using own error reporting, do not produce any arguments. - my) :;; - -# Default error reporting requires linking with the AST EMS interface and -# the EMS library via the link script. - *) args="${args} -last_ems `ems_link_adam`";; - esac - -# Link with the maths library. -# ---------------------------- - args="${args} -lm" - -# Link with the starmem library, if available. -# -------------------------------------------- - args="${args} `\`find starmem_link\``" - -# Pass the resulting argument list through an awk script which eliminates -# all except the last reference to each library. - echo "${args}" \ - | awk 'BEGIN{RS=" ";FS="\n"} - {if($1)f[i++]=$1} - END{for(;i--;)if(!w[f[i]]++)l=f[i]" "l;print l}' - -# End of script. diff --git a/ast/ast_par.source b/ast/ast_par.source deleted file mode 100644 index fda7eac..0000000 --- a/ast/ast_par.source +++ /dev/null @@ -1,733 +0,0 @@ -*+ -* Name: -* AST_PAR - -* Purpose: -* Define the Fortran 77 interface to the AST library. - -* Language: -* Fortran 77 - -* Type of Module: -* Include file. - -* Description: -* This file contains definitions which are required by Fortran 77 -* programs which use the AST library. - -* Authors: -* RFWS: R.F. Warren-Smith (STARLINK) -* MBT: Mark Taylor (STARLINK) -* DSB: David S. Berry - -* History: -* 12-NOV-1996 (RFWS): -* Original version. -* 18-MAR-1998 (RFWS): -* Added definitions for the IntraMap class. -* 21-DEC-1998 (RFWS): -* Added resampling definitions for the Mapping class. -* 15-NOV-1999 (RFWS): -* Added definitions for PcdMap. -* 24-NOV-2000 (MBT): -* Added AST__BLOCKAVE interpolation scheme. -* 22-JUN-2001 (DSB): -* Added AST_OFFSET2 and AST_ANGLE to Frame class. -* 6-SEP-2001 (DSB): -* Added AST_AXDISTANCE and AST_AXOFFSET to Frame class. -* 12-SEP-2001 (DSB): -* Added AST_BEAR to Frame class. -* 21-SEP-2001 (DSB): -* Replaced AST_BEAR by AST_AXANGLE. -* 28-JAN-2003 (DSB): -* Added AST_GETACTIVEUNIT. -* 14-FEB-2003 (DSB): -* Added new values for WcsMap projections. -* 30-APR-2003 (DSB): -* Added AST_VERSION. -* 15-JUL-2003 (DSB): -* Added AST_RATE, POLYMAP, SHIFTMAP and GRISMMAP functions. -* 13-NOV-2003 (DSB): -* Added XmlChan class. -* 9-NOV-2004 (DSB): -* Added all initial Region classes. -* 19-NOV-2004 (DSB): -* Added KeyMap. -* 16-JUN-2005 (DSB): -* Added TimeMap and TimeFrame. -* 1-SEP-2005 (DSB): -* Added AST__REBININIT and AST__REBINNORM. -* 17-FEB-2006 (DSB): -* Added AST_ESCAPES. -* 9-FEB-2007 (DSB): -* Use a double precision constant to initialise AST__UNDEFF. -* 4-DEC-2008 (TIMJ): -* Add AST_TESTFITS. Remove AST__UNDEF -* 6-FEB-2009 (DSB): -* Added StcsChan class. -* 26-OCT-2016 (DSB): -* Make angle constants double precision. -*- - -* Length of character string returned by a character function. - INTEGER AST__SZCHR - PARAMETER ( AST__SZCHR = 200 ) - -* Bad coordinate value. - DOUBLE PRECISION AST__BAD - PARAMETER ( AST__BAD = ) - -* Double precision NaN flag (this value is not actually a NaN itself). - DOUBLE PRECISION AST__NAN - PARAMETER ( AST__NAN = ) - -* Single precision NaN flag (this value is not actually a NaN itself). - REAL AST__NANR - PARAMETER ( AST__NANR = ) - -* Error module. - LOGICAL AST_OK - INTEGER AST_STATUS - -* Object class. - EXTERNAL AST_NULL - INTEGER AST__NULL - PARAMETER ( AST__NULL = 0 ) - - INTEGER AST__TUNULL - PARAMETER ( AST__TUNULL = -99999 ) - - - CHARACTER AST__TUNULLC*11 - PARAMETER ( AST__TUNULLC = '' ) - - CHARACTER * ( AST__SZCHR ) AST_GETC - DOUBLE PRECISION AST_GETD - INTEGER AST_CLONE - INTEGER AST_COPY - LOGICAL AST_EQUAL - INTEGER AST_GETI - INTEGER AST_VERSION - LOGICAL AST_GETL - LOGICAL AST_ISAOBJECT - LOGICAL AST_TEST - LOGICAL AST_HASATTRIBUTE - LOGICAL AST_SAME - INTEGER AST_TUNE - REAL AST_GETR - LOGICAL AST_CHRSUB - -* Channel class. - INTEGER AST_CHANNEL - INTEGER AST_READ - INTEGER AST_WRITE - LOGICAL AST_ISACHANNEL - INTEGER AST_WARNINGS - -* FitsChan class. - INTEGER AST_FITSCHAN - LOGICAL AST_FINDFITS - LOGICAL AST_ISAFITSCHAN - LOGICAL AST_GETFITSCF - LOGICAL AST_GETFITSCI - LOGICAL AST_GETFITSF - LOGICAL AST_GETFITSI - LOGICAL AST_GETFITSL - LOGICAL AST_GETFITSS - LOGICAL AST_GETFITSCN - LOGICAL AST_TESTFITS - INTEGER AST_GETTABLES - - CHARACTER AST__TABEXTNAME*7 - PARAMETER ( AST__TABEXTNAME = 'WCS-TAB' ) - - INTEGER AST__NOTYPE - PARAMETER ( AST__NOTYPE = -1 ) - INTEGER AST__COMMENT - PARAMETER ( AST__COMMENT = 0 ) - INTEGER AST__INT - PARAMETER ( AST__INT = 1 ) - INTEGER AST__FLOAT - PARAMETER ( AST__FLOAT = 2 ) - INTEGER AST__STRING - PARAMETER ( AST__STRING = 3 ) - INTEGER AST__COMPLEXF - PARAMETER ( AST__COMPLEXF = 4 ) - INTEGER AST__COMPLEXI - PARAMETER ( AST__COMPLEXI = 5 ) - INTEGER AST__LOGICAL - PARAMETER ( AST__LOGICAL = 6 ) - INTEGER AST__CONTINUE - PARAMETER ( AST__CONTINUE = 7 ) - INTEGER AST__UNDEF - PARAMETER ( AST__UNDEF = 8 ) - - -* Mapping Class. - INTEGER AST__URESAMP1 - PARAMETER ( AST__URESAMP1 = 1 ) - INTEGER AST__URESAMP2 - PARAMETER ( AST__URESAMP2 = 2 ) - INTEGER AST__URESAMP3 - PARAMETER ( AST__URESAMP3 = 4 ) - INTEGER AST__URESAMP4 - PARAMETER ( AST__URESAMP4 = 8 ) - INTEGER AST__USEVAR - PARAMETER ( AST__USEVAR = 16 ) - INTEGER AST__USEBAD - PARAMETER ( AST__USEBAD = 32 ) - INTEGER AST__CONSERVEFLUX - PARAMETER ( AST__CONSERVEFLUX = 64 ) - INTEGER AST__REBININIT - PARAMETER ( AST__REBININIT = 128 ) - INTEGER AST__REBINEND - PARAMETER ( AST__REBINEND = 256 ) - INTEGER AST__GENVAR - PARAMETER ( AST__GENVAR = 512 ) - INTEGER AST__VARWGT - PARAMETER ( AST__VARWGT = 1024 ) - INTEGER AST__NOBAD - PARAMETER ( AST__NOBAD = 2048 ) - INTEGER AST__DISVAR - PARAMETER ( AST__DISVAR = 4096 ) - INTEGER AST__NONORM - PARAMETER ( AST__NONORM = 8192 ) - - INTEGER AST__UKERN1 - PARAMETER ( AST__UKERN1 = 1 ) -c Not yet implemented -c INTEGER AST__UKERNN -c PARAMETER ( AST__UKERNN = 2 ) - INTEGER AST__UINTERP - PARAMETER ( AST__UINTERP = 3 ) - INTEGER AST__NEAREST - PARAMETER ( AST__NEAREST = 4 ) - INTEGER AST__LINEAR - PARAMETER ( AST__LINEAR = 5 ) - INTEGER AST__SINC - PARAMETER ( AST__SINC = 6 ) - INTEGER AST__SINCSINC - PARAMETER ( AST__SINCSINC = 7 ) - INTEGER AST__SINCCOS - PARAMETER ( AST__SINCCOS = 8 ) - INTEGER AST__SINCGAUSS - PARAMETER ( AST__SINCGAUSS = 9 ) - INTEGER AST__BLOCKAVE - PARAMETER ( AST__BLOCKAVE = 10 ) - INTEGER AST__GAUSS - PARAMETER ( AST__GAUSS = 11 ) - INTEGER AST__SOMB - PARAMETER ( AST__SOMB = 12 ) - INTEGER AST__SOMBCOS - PARAMETER ( AST__SOMBCOS = 13 ) - - INTEGER AST_RESAMPLEB - INTEGER AST_RESAMPLED - INTEGER AST_RESAMPLEI - INTEGER AST_RESAMPLEK - INTEGER AST_RESAMPLER - INTEGER AST_RESAMPLES - INTEGER AST_RESAMPLEUB - INTEGER AST_RESAMPLEUI - INTEGER AST_RESAMPLEUK - INTEGER AST_RESAMPLEUS - INTEGER AST_RESAMPLEUW - INTEGER AST_RESAMPLEW - INTEGER AST_REMOVEREGIONS - INTEGER AST_SIMPLIFY - LOGICAL AST_ISAMAPPING - LOGICAL AST_LINEARAPPROX - LOGICAL AST_QUADAPPROX - DOUBLE PRECISION AST_RATE - -* CmpMap class. - INTEGER AST_CMPMAP - LOGICAL AST_ISACMPMAP - -* Frame class. - CHARACTER * ( AST__SZCHR ) AST_FORMAT - DOUBLE PRECISION AST_DISTANCE - INTEGER AST_CONVERT - INTEGER AST_FINDFRAME - INTEGER AST_FRAME - INTEGER AST_PICKAXES - INTEGER AST_UNFORMAT - LOGICAL AST_ISAFRAME - LOGICAL AST_GETACTIVEUNIT - DOUBLE PRECISION AST_ANGLE - DOUBLE PRECISION AST_OFFSET2 - DOUBLE PRECISION AST_AXDISTANCE - DOUBLE PRECISION AST_AXOFFSET - DOUBLE PRECISION AST_AXANGLE - -* CmpFrame class. - INTEGER AST_CMPFRAME - LOGICAL AST_ISACMPFRAME - -* FrameSet class. - INTEGER AST__BASE - PARAMETER ( AST__BASE = 0 ) - INTEGER AST__CURRENT - PARAMETER ( AST__CURRENT = -1 ) - INTEGER AST__NOFRAME - PARAMETER ( AST__NOFRAME = -99 ) - - INTEGER AST_FRAMESET - INTEGER AST_GETFRAME - INTEGER AST_GETMAPPING - LOGICAL AST_ISAFRAMESET - -* IntraMap class. - INTEGER AST__NOFWD - PARAMETER ( AST__NOFWD = 1 ) - INTEGER AST__NOINV - PARAMETER ( AST__NOINV = 2 ) - INTEGER AST__SIMPFI - PARAMETER ( AST__SIMPFI = 4 ) - INTEGER AST__SIMPIF - PARAMETER ( AST__SIMPIF = 8 ) - INTEGER AST__ANY - PARAMETER ( AST__ANY = -66 ) - - INTEGER AST_INTRAMAP - LOGICAL AST_ISAINTRAMAP - -* LutMap class. - INTEGER AST_LUTMAP - LOGICAL AST_ISALUTMAP - -* PcdMap class. - INTEGER AST_PCDMAP - LOGICAL AST_ISAPCDMAP - -* Plot class. - INTEGER AST_PLOT - LOGICAL AST_BORDER - INTEGER AST_GETGRFCONTEXT - LOGICAL AST_ISAPLOT - INTEGER AST_ESCAPES - CHARACTER * ( AST__SZCHR ) AST_STRIPESCAPES - -* SkyFrame class. - INTEGER AST_SKYFRAME - LOGICAL AST_ISASKYFRAME - INTEGER AST_SKYOFFSETMAP - -* SpecFrame class. - INTEGER AST_SPECFRAME - LOGICAL AST_ISASPECFRAME - -* DSBSpecFrame class. - INTEGER AST_DSBSPECFRAME - LOGICAL AST_ISADSBSPECFRAME - -* MathMap class. - INTEGER AST_MATHMAP - LOGICAL AST_ISAMATHMAP - -* MatrixMap class. - INTEGER AST_MATRIXMAP - LOGICAL AST_ISAMATRIXMAP - -* PermMap class. - INTEGER AST_PERMMAP - LOGICAL AST_ISAPERMMAP - -* PolyMap class. - INTEGER AST_POLYMAP - LOGICAL AST_ISAPOLYMAP - INTEGER AST_POLYTRAN - -* SlaMap class. - INTEGER AST_SLAMAP - LOGICAL AST_ISASLAMAP - -* SpecMap class. - INTEGER AST_SPECMAP - LOGICAL AST_ISASPECMAP - -* SphMap class. - INTEGER AST_SPHMAP - LOGICAL AST_ISASPHMAP - -* UnitMap class. - INTEGER AST_UNITMAP - LOGICAL AST_ISAUNITMAP - -* WcsMap class. - - INTEGER AST__WCSMX - PARAMETER ( AST__WCSMX = 10 ) - - DOUBLE PRECISION AST__DPI - PARAMETER ( AST__DPI = 3.1415926535897932384626433832795028842D0 ) - - DOUBLE PRECISION AST__DPIBY2 - PARAMETER ( AST__DPIBY2 = 1.5707963267948966192313216916397514D0 ) - - DOUBLE PRECISION AST__DD2R - PARAMETER ( AST__DD2R = 0.017453292519943295769236907684886127D0 ) - - DOUBLE PRECISION AST__DR2D - PARAMETER ( AST__DR2D = 57.29577951308232087679815481410517033D0 ) - - INTEGER AST__AIR - PARAMETER ( AST__AIR = 9 ) - INTEGER AST__AIT - PARAMETER ( AST__AIT = 17 ) - INTEGER AST__ARC - PARAMETER ( AST__ARC = 6 ) - INTEGER AST__AZP - PARAMETER ( AST__AZP = 1 ) - INTEGER AST__BON - PARAMETER ( AST__BON = 22 ) - INTEGER AST__CAR - PARAMETER ( AST__CAR = 12 ) - INTEGER AST__CEA - PARAMETER ( AST__CEA = 11 ) - INTEGER AST__COD - PARAMETER ( AST__COD = 20 ) - INTEGER AST__COE - PARAMETER ( AST__COE = 19 ) - INTEGER AST__COO - PARAMETER ( AST__COO = 21 ) - INTEGER AST__COP - PARAMETER ( AST__COP = 18 ) - INTEGER AST__CSC - PARAMETER ( AST__CSC = 25 ) - INTEGER AST__CYP - PARAMETER ( AST__CYP = 10 ) - INTEGER AST__GLS - PARAMETER ( AST__GLS = 28 ) - INTEGER AST__HPX - PARAMETER ( AST__HPX = 30 ) - INTEGER AST__MER - PARAMETER ( AST__MER = 13 ) - INTEGER AST__MOL - PARAMETER ( AST__MOL = 16 ) - INTEGER AST__NCP - PARAMETER ( AST__NCP = 27 ) - INTEGER AST__PAR - PARAMETER ( AST__PAR = 15 ) - INTEGER AST__PCO - PARAMETER ( AST__PCO = 23 ) - INTEGER AST__QSC - PARAMETER ( AST__QSC = 26 ) - INTEGER AST__SFL - PARAMETER ( AST__SFL = 14 ) - INTEGER AST__SIN - PARAMETER ( AST__SIN = 5 ) - INTEGER AST__STG - PARAMETER ( AST__STG = 4 ) - INTEGER AST__SZP - PARAMETER ( AST__SZP = 2 ) - INTEGER AST__TAN - PARAMETER ( AST__TAN = 3 ) - INTEGER AST__TPN - PARAMETER ( AST__TPN = 29 ) - INTEGER AST__TSC - PARAMETER ( AST__TSC = 24 ) - INTEGER AST__XPH - PARAMETER ( AST__XPH = 31 ) - INTEGER AST__ZEA - PARAMETER ( AST__ZEA = 8 ) - INTEGER AST__ZPN - PARAMETER ( AST__ZPN = 7 ) - INTEGER AST__WCSBAD - PARAMETER ( AST__WCSBAD = 32 ) - - INTEGER AST_WCSMAP - LOGICAL AST_ISAWCSMAP - -* ShiftMap class. - INTEGER AST_SHIFTMAP - LOGICAL AST_ISASHIFTMAP - -* WinMap class. - INTEGER AST_WINMAP - LOGICAL AST_ISAWINMAP - -* ZoomMap class. - INTEGER AST_ZOOMMAP - LOGICAL AST_ISAZOOMMAP - -* GrismMap class. - INTEGER AST_GRISMMAP - LOGICAL AST_ISAGRISMMAP - -* XmlChan class. - INTEGER AST_XMLCHAN - LOGICAL AST_ISAXMLCHAN - -* TranMap class. - INTEGER AST_TRANMAP - LOGICAL AST_ISATRANMAP - -* Region class. - INTEGER AST_REGION - INTEGER AST_GETUNC - INTEGER AST_GETREGIONFRAME - LOGICAL AST_ISAREGION - INTEGER AST_MAPREGION - INTEGER AST_OVERLAP - INTEGER AST_MASKB - INTEGER AST_MASKD - INTEGER AST_MASKI - INTEGER AST_MASKR - INTEGER AST_MASKS - INTEGER AST_MASKUB - INTEGER AST_MASKUI - INTEGER AST_MASKUS - INTEGER AST_MASKUW - INTEGER AST_MASKW - -* Box class. - INTEGER AST_BOX - LOGICAL AST_ISABOX - -* PointList class. - INTEGER AST_POINTLIST - LOGICAL AST_ISAPOINTLIST - -* Polygon class. - INTEGER AST_POLYGON - LOGICAL AST_ISAPOLYGON - INTEGER AST_DOWNSIZE - INTEGER AST_OUTLINED - INTEGER AST_OUTLINER - INTEGER AST_OUTLINEI - INTEGER AST_OUTLINEUI - INTEGER AST_OUTLINES - INTEGER AST_OUTLINEUS - INTEGER AST_OUTLINEW - INTEGER AST_OUTLINEUW - INTEGER AST_OUTLINEB - INTEGER AST_OUTLINEUB - - INTEGER AST_CONVEXD - INTEGER AST_CONVEXR - INTEGER AST_CONVEXI - INTEGER AST_CONVEXUI - INTEGER AST_CONVEXS - INTEGER AST_CONVEXUS - INTEGER AST_CONVEXW - INTEGER AST_CONVEXUW - INTEGER AST_CONVEXB - INTEGER AST_CONVEXUB - - INTEGER AST__LE - PARAMETER( AST__LE = 2 ) - - INTEGER AST__EQ - PARAMETER( AST__EQ = 3 ) - - INTEGER AST__GE - PARAMETER( AST__GE = 4 ) - - INTEGER AST__GT - PARAMETER( AST__GT = 5 ) - - INTEGER AST__NE - PARAMETER( AST__NE = 6 ) - -* Circle class. - INTEGER AST_CIRCLE - LOGICAL AST_ISACIRCLE - -* Ellipse class. - INTEGER AST_ELLIPSE - LOGICAL AST_ISAELLIPSE - -* NullRegion class. - INTEGER AST_NULLREGION - LOGICAL AST_ISANULLREGION - -* Interval class. - INTEGER AST_INTERVAL - LOGICAL AST_ISAINTERVAL - -* Prism class. - INTEGER AST_PRISM - LOGICAL AST_ISAPRISM - -* CmpRegion class. - INTEGER AST_CMPREGION - LOGICAL AST_ISACMPREGION - - INTEGER AST__AND - PARAMETER( AST__AND = 1 ) - - INTEGER AST__OR - PARAMETER( AST__OR = 2 ) - - INTEGER AST__XOR - PARAMETER( AST__XOR = 3 ) - -* KeyMap class. - INTEGER AST_KEYMAP - LOGICAL AST_ISAKEYMAP - LOGICAL AST_MAPGET0I - LOGICAL AST_MAPGET0S - LOGICAL AST_MAPGET0B - LOGICAL AST_MAPGET0D - LOGICAL AST_MAPGET0R - LOGICAL AST_MAPGET0C - LOGICAL AST_MAPGET0A - LOGICAL AST_MAPGET1I - LOGICAL AST_MAPGET1B - LOGICAL AST_MAPGET1S - LOGICAL AST_MAPGET1D - LOGICAL AST_MAPGET1R - LOGICAL AST_MAPGET1C - LOGICAL AST_MAPGET1A - LOGICAL AST_MAPGETC - LOGICAL AST_MAPGETELEMI - LOGICAL AST_MAPGETELEMS - LOGICAL AST_MAPGETELEMB - LOGICAL AST_MAPGETELEMD - LOGICAL AST_MAPGETELEMR - LOGICAL AST_MAPGETELEMC - LOGICAL AST_MAPGETELEMA - INTEGER AST_MAPSIZE - INTEGER AST_MAPLENGTH - INTEGER AST_MAPLENC - INTEGER AST_MAPTYPE - LOGICAL AST_MAPHASKEY - LOGICAL AST_MAPDEFINED - CHARACTER * ( AST__SZCHR ) AST_MAPKEY - - INTEGER AST__BADTYPE - PARAMETER ( AST__BADTYPE = 0) - - INTEGER AST__INTTYPE - PARAMETER ( AST__INTTYPE = 1) - - INTEGER AST__DOUBLETYPE - PARAMETER ( AST__DOUBLETYPE = 2) - - INTEGER AST__STRINGTYPE - PARAMETER ( AST__STRINGTYPE = 3) - - INTEGER AST__OBJECTTYPE - PARAMETER ( AST__OBJECTTYPE = 4) - - INTEGER AST__FLOATTYPE - PARAMETER ( AST__FLOATTYPE = 5) - - INTEGER AST__SINTTYPE - PARAMETER ( AST__SINTTYPE = 7) - - INTEGER AST__UNDEFTYPE - PARAMETER ( AST__UNDEFTYPE = 8) - - INTEGER AST__BYTETYPE - PARAMETER ( AST__BYTETYPE = 9) - -* FluxFrame class. - INTEGER AST_FLUXFRAME - LOGICAL AST_ISAFLUXFRAME - -* SpecFluxFrame class. - INTEGER AST_SPECFLUXFRAME - LOGICAL AST_ISASPECFLUXFRAME - -* NormMap class. - INTEGER AST_NORMMAP - LOGICAL AST_ISANORMMAP - -* RateMap class. - INTEGER AST_RATEMAP - LOGICAL AST_ISARATEMAP - -* TimeFrame class. - INTEGER AST_TIMEFRAME - LOGICAL AST_ISATIMEFRAME - DOUBLE PRECISION AST_CURRENTTIME - - INTEGER AST__LT - PARAMETER( AST__LT = 11 ) - -* TimeMap class. - INTEGER AST_TIMEMAP - LOGICAL AST_ISATIMEMAP - -* Stc class. - LOGICAL AST_ISASTC - INTEGER AST_GETSTCREGION - INTEGER AST_GETSTCCOORD - INTEGER AST_GETSTCNCOORD - - CHARACTER AST__STCNAME*4 - PARAMETER ( AST__STCNAME = 'Name' ) - - CHARACTER AST__STCVALUE*5 - PARAMETER ( AST__STCVALUE = 'Value' ) - - CHARACTER AST__STCERROR*5 - PARAMETER ( AST__STCERROR = 'Error' ) - - CHARACTER AST__STCRES*10 - PARAMETER ( AST__STCRES = 'Resolution' ) - - CHARACTER AST__STCSIZE*4 - PARAMETER ( AST__STCSIZE = 'Size' ) - - CHARACTER AST__STCPIXSZ*7 - PARAMETER ( AST__STCPIXSZ = 'PixSize' ) - -* StcSearchLocation class. - LOGICAL AST_ISASTCSEARCHLOCATION - INTEGER AST_STCSEARCHLOCATION - -* StcCatalogEntryLocation class. - LOGICAL AST_ISASTCCATALOGENTRYLOCATION - INTEGER AST_STCCATALOGENTRYLOCATION - -* StcResourceProfile class. - LOGICAL AST_ISASTCRESOURCEPROFILE - INTEGER AST_STCRESOURCEPROFILE - -* StcObsDataLocation class. - LOGICAL AST_ISASTCOBSDATALOCATION - INTEGER AST_STCOBSDATALOCATION - -* SwitchMap class. - INTEGER AST_SWITCHMAP - LOGICAL AST_ISASWITCHMAP - -* SelectorMap class. - INTEGER AST_SELECTORMAP - LOGICAL AST_ISASELECTORMAP - -* Plot3D class. - INTEGER AST_PLOT3D - LOGICAL AST_ISAPLOT3D - -* StcsChan class. - INTEGER AST_STCSCHAN - LOGICAL AST_ISASTCSCHAN - -* Table class. - INTEGER AST_TABLE - LOGICAL AST_ISATABLE - LOGICAL AST_HASCOLUMN - CHARACTER * ( AST__SZCHR ) AST_COLUMNNAME - LOGICAL AST_HASPARAMETER - CHARACTER * ( AST__SZCHR ) AST_PARAMETERNAME - -* FitsTable class. - INTEGER AST_FITSTABLE - LOGICAL AST_ISAFITSTABLE - INTEGER AST_COLUMNNULL - INTEGER AST_COLUMNSIZE - INTEGER AST_GETTABLEHEADER - -* UnitNormMap class. - INTEGER AST_UNITNORMMAP - LOGICAL AST_ISAUNITNORMMAP - -* ChebyMap class. - INTEGER AST_CHEBYMAP - LOGICAL AST_ISACHEBYMAP - INTEGER AST_CHEBYTRAN - diff --git a/ast/ast_test.c b/ast/ast_test.c deleted file mode 100644 index 61e948e..0000000 --- a/ast/ast_test.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ -#include "ast.h" /* AST C interface definition */ - -/* C header files. */ -/* --------------- */ -#include - -/* Main function. */ -/* ============== */ -int main( int argc, char *argv[] ) { -/* -*+ -* Name: -* ast_test - -* Purpose: -* Test installation of the AST library. - -* Type: -* C program. - -* Description: -* This program performs a simple test (without using graphics) of -* the AST library, to check that it is correctly installed. It is -* not an exhaustive test of the system. - -* Arguments: -* None. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 19-NOV-1997 (RFWS); -* Original version. -*- -*/ - -/* Local Constants: */ -#define NCOORD 10 /* Number of coordinates to transform */ - -/* Local Variables: */ - AstFrameSet *cvt; /* Pointer to conversion FrameSet */ - AstSkyFrame *sky1; /* Pointer to first SkyFrame */ - AstSkyFrame *sky2; /* Pointer to second SkyFrame */ - double xin[ NCOORD ]; /* Input coordinate array */ - double xout[ NCOORD ]; /* Output coordinate array */ - double yin[ NCOORD ]; /* Input coordinate array */ - double yout[ NCOORD ]; /* Output coordinate array */ - int i; /* Loop counter for coordinates */ - -/* Begin an AST context. */ - astBegin; - -/* Create two SkyFrames. */ - sky1 = astSkyFrame( "system = FK4_NO_E, equinox = B1920, epoch = B1958" ); - sky2 = astSkyFrame( "system = ecliptic, equinox = J2001" ); - -/* Create a FrameSet describing the conversion between them. */ - cvt = astConvert( sky1, sky2, "" ); - -/* If successful, set up some input coordinates. */ - if ( cvt != AST__NULL ) { - for ( i = 0; i < NCOORD; i++ ) { - xin[ i ] = 0.1 * (double) i; - yin[ i ] = 0.2 * (double) i; - } - -/* Display the FrameSet. */ - astShow( cvt ); - printf( "\n"); - -/* Activate reporting of coordinate transformations. */ - astSet( cvt, "Report = 1" ); - -/* Perform the forward transformation. */ - astTran2( cvt, 10, xin, yin, 1, xout, yout ); - printf( "\n"); - -/* Perform the inverse transformation. */ - astTran2( cvt, 10, xout, yout, 0, xin, yin ); - } - -/* End the AST context. */ - astEnd; - -/* Return an error status. */ - return astOK ? 0 : 1; - -/* Undefine local macros. */ -#undef NCOORD -} diff --git a/ast/ast_tester/README b/ast/ast_tester/README deleted file mode 100644 index 8c50db6..0000000 --- a/ast/ast_tester/README +++ /dev/null @@ -1,33 +0,0 @@ - -This directory contains files used for performing some fairly restricted -testing of the AST library. A Fortran 77 compiler is required. As supplied -it uses the g77 Fortran compiler, but this can be changed by editing the ast_tester -script. - -To perform a test: - -- build AST - -- define the environment variables AST and STARLINK so that $AST/lib contains - the AST libraries to be tested, and $STARLINK/lib contains the the USSC libraries. - -- If required, edit the ast_tester script to modify the fortran compiler and/or options. - -- execute the ast_tester script. - - -The script generates various output files which are compared with existing files -which are presumed to represent correct behaviour of the AST library. Any differences -are reported by the script. - -The script also generates various postscript files representing "critically difficult" plots. -A file "*-new.ps" is created for each file "*.head" in the directory. The directory also -contains files "*.ps" which represent the expected appearance of the plots. By default, the -new plots are displayed using ghostview. This can be disabled by specifying the "-nd" option -on the ast_tester command line. - - - - - - diff --git a/ast/ast_tester/a20070718_00010_02_cube.ast b/ast/ast_tester/a20070718_00010_02_cube.ast deleted file mode 100644 index f005938..0000000 --- a/ast/ast_tester/a20070718_00010_02_cube.ast +++ /dev/null @@ -1,339 +0,0 @@ - Begin FrameSet # Set of inter-related coordinate systems -# Title = "3-d compound coordinate system" # Title of coordinate system -# Naxes = 3 # Number of coordinate axes -# Domain = "SKY-DSBSPECTRUM" # Coordinate system domain -# Epoch = 2007.54208230851 # Julian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Lbl3 = "Radio velocity (USB)" # Label for axis 3 -# System = "Compound" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Uni3 = "km/s" # Units for axis 3 -# Dir1 = 0 # Plot axis 1 in reverse direction - IsA Frame # Coordinate system description - Nframe = 4 # Number of Frames in FrameSet -# Base = 1 # Index of base Frame - Currnt = 4 # Index of current Frame - Nnode = 5 # Number of nodes in FrameSet - Nod1 = 3 # Frame 1 is associated with node 3 - Nod2 = 4 # Frame 2 is associated with node 4 - Nod3 = 5 # Frame 3 is associated with node 5 - Nod4 = 2 # Frame 4 is associated with node 2 - Lnk2 = 1 # Node 2 is derived from node 1 - Lnk3 = 1 # Node 3 is derived from node 1 - Lnk4 = 1 # Node 4 is derived from node 1 - Lnk5 = 1 # Node 5 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Data grid indices; first pixel at (1,1,1)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Data grid index 1" # Label for axis 1 -# Lbl2 = "Data grid index 2" # Label for axis 2 -# Lbl3 = "Data grid index 3" # Label for axis 3 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 -# Uni3 = "pixel" # Units for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Data grid index 1" # Axis Label - Symbol = "g1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Data grid index 2" # Axis Label - Symbol = "g2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Data grid index 3" # Axis Label - Symbol = "g3" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm2 = # Frame number 2 - Begin Frame # Coordinate system description - Title = "Pixel coordinates; first pixel at (-8.5,-8.5,-2048.5)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "PIXEL" # Coordinate system domain -# Lbl1 = "Pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Pixel coordinate 2" # Label for axis 2 -# Lbl3 = "Pixel coordinate 3" # Label for axis 3 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 -# Uni3 = "pixel" # Units for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 1" # Axis Label - Symbol = "p1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 2" # Axis Label - Symbol = "p2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 3" # Axis Label - Symbol = "p3" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm3 = # Frame number 3 - Begin Frame # Coordinate system description - Title = "Axis coordinates; first pixel at (-8.5,-8.5,-2048.5)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "AXIS" # Coordinate system domain -# Lbl1 = "Axis 1" # Label for axis 1 -# Lbl2 = "Axis 2" # Label for axis 2 -# Lbl3 = "Axis 3" # Label for axis 3 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 -# Uni3 = "pixel" # Units for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Axis 1" # Axis Label - Symbol = "a1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Axis 2" # Axis Label - Symbol = "a2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Axis 3" # Axis Label - Symbol = "a3" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm4 = # Frame number 4 - Begin CmpFrame # Compound coordinate system description -# Title = "3-d compound coordinate system" # Title of coordinate system -# Naxes = 3 # Number of coordinate axes -# Domain = "SKY-DSBSPECTRUM" # Coordinate system domain -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Lbl3 = "Radio velocity (USB)" # Label for axis 3 -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Uni3 = "km/s" # Units for axis 3 -# Dir1 = 0 # Plot axis 1 in reverse direction - IsA Frame # Coordinate system description - FrameA = # First component Frame - Begin SkyFrame # Description of celestial coordinate system - Naxes = 2 # Number of coordinate axes - Epoch = 2007.54208230851 # Julian epoch of observation - System = "FK5" # Coordinate system type - ObsLat = 0.346026050148997 # Observers geodetic latitude (rads) - ObsLon = -2.71363306946838 # Observers geodetic longitude (rads) - Dut1 = -0.162963400559962 # UT1-UTC in seconds - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - SRef1 = 4.90555239050187 # Ref. pos. RA 18:44:16.2 - SRef2 = -0.0698132003068136 # Ref. pos. Dec -4:00:00 - End SkyFrame - FrameB = # Second component Frame - Begin DSBSpecFrame # Dual sideband spectral axis - Naxes = 1 # Number of coordinate axes - Epoch = 2007.54208230851 # Julian epoch of observation - System = "VRAD" # Coordinate system type - ObsLat = 0.346026069000144 # Observers geodetic latitude (rads) - ObsLon = -2.71363307300091 # Observers geodetic longitude (rads) - Dut1 = -0.162963400559962 # UT1-UTC in seconds - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - End Axis - IsA Frame # Coordinate system description - SoR = "LSRK" # Standard of rest - RefRA = 4.90553899950038 # Reference RA (rads, FK5 J2000) - RefDec = -0.0698131700797732 # Reference Dec (rads, FK5 J2000) - RstFrq = 372672509000 # Rest frequency (Hz) - SrcVel = 87012.623732646 # Source velocity (m/s) - SrcVRF = "LSRK" # Source velocity rest frame - UFreq = "GHz" # Preferred units for frequency - IsA SpecFrame # Description of spectral coordinate system - DSBCen = 372576971505.836 # Central frequency (Hz topo) - IF = -5251168918.31241 # Intermediate frequency (Hz) - SideBn = "USB" # Represents upper sideband - End DSBSpecFrame - End CmpFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = 10 # Shift for axis 1 - Sft2 = 10.4938775599003 # Shift for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = 6105939.046167 # Shift for axis 1 - Scl1 = -1.63834485003565e-05 # Scale factor for axis 1 - End WinMap - MapB = # Second component Mapping - Begin SpecMap # Conversion between spectral coordinate systems - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Nspec = 2 # Number of conversion steps - Spec1 = "FRTOVL" # Convert frequency to rel. velocity - Spec1a = 372672509000 # Rest frequency (Hz) - Spec2 = "VLTOVR" # Convert relativistic to radio velocity - End SpecMap - End CmpMap - End CmpMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - M0 = -2.90888208665722e-05 # Forward matrix value - M1 = 2.90888208665722e-05 # Forward matrix value - Form = "Diagonal" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitude (rad.s) - End SphMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - M0 = -0.0133908234539359 # Forward matrix value - M1 = 0.981401710741326 # Forward matrix value - M2 = 0.191497697117288 # Forward matrix value - M3 = 0.068459122667767 # Forward matrix value - M4 = 0.191965314976427 # Forward matrix value - M5 = -0.979011065499037 # Forward matrix value - M6 = -0.997564050259824 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = -0.0697564737441253 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 4.90555329534916 # Polar longitude (rad.s) - End SphMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - MapB = # Second component Mapping - Begin ZoomMap # Zoom about the origin - Nin = 1 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Zoom = 0.001 # Zoom factor - End ZoomMap - End CmpMap - End CmpMap - Map3 = # Mapping between nodes 1 and 3 - Begin UnitMap # Unit (null) Mapping - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - End UnitMap - Map4 = # Mapping between nodes 1 and 4 - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - Sft1 = -9.5 # Shift for axis 1 - Sft2 = -9.5 # Shift for axis 2 - Sft3 = -2049.5 # Shift for axis 3 - End WinMap - Map5 = # Mapping between nodes 1 and 5 - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - Sft1 = -9.5 # Shift for axis 1 - Sft2 = -9.5 # Shift for axis 2 - Sft3 = -2049.5 # Shift for axis 3 - End WinMap - End FrameSet diff --git a/ast/ast_tester/a20070718_00010_02_cube.fits-wcs b/ast/ast_tester/a20070718_00010_02_cube.fits-wcs deleted file mode 100644 index 428efaa..0000000 --- a/ast/ast_tester/a20070718_00010_02_cube.fits-wcs +++ /dev/null @@ -1,61 +0,0 @@ -WCSAXES = 3 / Number of WCS axes -CRPIX1 = 10.0 / Reference pixel on axis 1 -CRPIX2 = 10.493878 / Reference pixel on axis 2 -CRPIX3 = 1.0 / Reference pixel on axis 3 -CRVAL1 = 281.0675 / Value at ref. pixel on axis 1 -CRVAL2 = -4.0 / Value at ref. pixel on axis 2 -CRVAL3 = -13.610153 / Value at ref. pixel on axis 3 -CTYPE1 = 'RA---TAN' / Type of co-ordinate on axis 1 -CTYPE2 = 'DEC--TAN' / Type of co-ordinate on axis 2 -CTYPE3 = 'VRAD ' / Type of co-ordinate on axis 3 -CDELT1 = -0.0016666667 / Pixel size on axis 1 -CDELT2 = 0.0016666667 / Pixel size on axis 2 -CDELT3 = 0.049100739 / Pixel size on axis 3 -CUNIT3 = 'km/s ' / Units for axis 3 -MJD-OBS = 54299.245 / Modified Julian Date of observation -DATE-OBS= '2007-07-18T05:52:31.475' / Date of observation -RADESYS = 'FK5 ' / Reference frame for RA/DEC values -EQUINOX = 2000.0 / [yr] Epoch of reference equinox -SPECSYS = 'LSRK ' / Standard of rest for spectral axis -SSYSSRC = 'LSRK ' / Standard of rest for source redshift -ZSOURCE = 0.000290285 / [] Redshift of source -VELOSYS = -10097.217 / [m/s] Topo. apparent velocity of rest frame -RESTFRQ = 3.7267251E+11 / [Hz] Rest frequency -IMAGFREQ= 3.621676E+11 / [Hz] Image frequency -OBSGEO-X= -5461073.2 / [m] Observatory geocentric X -OBSGEO-Y= -2491089.0 / [m] Observatory geocentric Y -OBSGEO-Z= 2149568.8 / [m] Observatory geocentric Z -WCSAXESA= 3 / Number of WCS axes -WCSNAMEA= 'PIXEL ' / Reference name for the coord. frame -CRPIX1A = 1.0 / Reference pixel on axis 1 -CRPIX2A = 1.0 / Reference pixel on axis 2 -CRPIX3A = 1.0 / Reference pixel on axis 3 -CRVAL1A = -8.5 / Value at ref. pixel on axis 1 -CRVAL2A = -8.5 / Value at ref. pixel on axis 2 -CRVAL3A = -2048.5 / Value at ref. pixel on axis 3 -CTYPE1A = 'p1 ' / Pixel coordinate 1 -CTYPE2A = 'p2 ' / Pixel coordinate 2 -CTYPE3A = 'p3 ' / Pixel coordinate 3 -CDELT1A = 1.0 / Pixel size on axis 1 -CDELT2A = 1.0 / Pixel size on axis 2 -CDELT3A = 1.0 / Pixel size on axis 3 -CUNIT1A = 'pixel ' / Units for axis 1 -CUNIT2A = 'pixel ' / Units for axis 2 -CUNIT3A = 'pixel ' / Units for axis 3 -WCSAXESB= 3 / Number of WCS axes -WCSNAMEB= 'AXIS ' / Reference name for the coord. frame -CRPIX1B = 1.0 / Reference pixel on axis 1 -CRPIX2B = 1.0 / Reference pixel on axis 2 -CRPIX3B = 1.0 / Reference pixel on axis 3 -CRVAL1B = -8.5 / Value at ref. pixel on axis 1 -CRVAL2B = -8.5 / Value at ref. pixel on axis 2 -CRVAL3B = -2048.5 / Value at ref. pixel on axis 3 -CTYPE1B = 'a1 ' / Axis 1 -CTYPE2B = 'a2 ' / Axis 2 -CTYPE3B = 'a3 ' / Axis 3 -CDELT1B = 1.0 / Pixel size on axis 1 -CDELT2B = 1.0 / Pixel size on axis 2 -CDELT3B = 1.0 / Pixel size on axis 3 -CUNIT1B = 'pixel ' / Units for axis 1 -CUNIT2B = 'pixel ' / Units for axis 2 -CUNIT3B = 'pixel ' / Units for axis 3 diff --git a/ast/ast_tester/aitoff.attr b/ast/ast_tester/aitoff.attr deleted file mode 100644 index 85aa9de..0000000 --- a/ast/ast_tester/aitoff.attr +++ /dev/null @@ -1 +0,0 @@ -Grid=1,tickall=0,border=1,tol=0.001 diff --git a/ast/ast_tester/aitoff.box b/ast/ast_tester/aitoff.box deleted file mode 100644 index b4f303e..0000000 --- a/ast/ast_tester/aitoff.box +++ /dev/null @@ -1 +0,0 @@ -10.0 -10.0 300.0 280.0 diff --git a/ast/ast_tester/aitoff.head b/ast/ast_tester/aitoff.head deleted file mode 100644 index 5f34de0..0000000 --- a/ast/ast_tester/aitoff.head +++ /dev/null @@ -1,13 +0,0 @@ -SIMPLE = T / Written by IDL: 30-Jul-1997 05:35:42.00 -BITPIX = -32 / Bits per pixel. -NAXIS = 2 / Number of dimensions -NAXIS1 = 300 / Length of x axis. -NAXIS2 = 300 / Length of y axis. -CTYPE1 = 'GLON-AIT' / X-axis type -CTYPE2 = 'GLAT-AIT' / Y-axis type -CRVAL1 = -149.56866 / Reference pixel value -CRVAL2 = -19.758201 / Reference pixel value -CRPIX1 = 150.500 / Reference pixel -CRPIX2 = 150.500 / Reference pixel -CDELT1 = -1.20000 / Degrees/pixel -CDELT2 = 1.20000 / Degrees/pixel diff --git a/ast/ast_tester/ast_tester b/ast/ast_tester/ast_tester deleted file mode 100755 index e626157..0000000 --- a/ast/ast_tester/ast_tester +++ /dev/null @@ -1,232 +0,0 @@ -#!/bin/tcsh -#+ -# Purpose: -# Does a few tests of the version of AST installed in $INSTALL. - -# Usage: -# ast_tester <-nd> - -# Description: -# Build and run various tests of an AST installation. -# -# Some tests produce graphical output. Postscript plots of the FITS -# headers in the current directory are produced for visual comparison -# with previous versions. For each file matching "*.head" in the current -# directory, a file is created called "*-new.ps". This file should be -# compared visually with the file "*.ps". The new files are displayed -# automatically unless the -nd option is supplied on the command line -# -# This script assumes the gfortran compiler is available. If this is not -# the case, do a global edit of gfortran to whatever fortran 77 compiler -# you have available (you will probably also need to change the compiler -# flags). - -# Options: -# -nd : Suppresses display of test plots. - -# Prior Requirements: -# - Unless the "-nd" option is specified, it requires the gv command (a -# frontend for ghostscript) to be on your PATH. -# - The following environment variables are used: -# STARLINK_DIR - should be set to the root of the tree in which the SSC is -# installed. A default of /star is used if not set. -# AST - should be set to the root of the tree in which the version of -# AST to be tested is installed. A default of $STARLINK_DIR is used -# if not set. - -# Author: -# DSB: David Berry (JAC, Hawaii) -#- - -if( ! $?STARLINK_DIR ) then - setenv STARLINK_DIR /star -endif - -if( ! $?AST ) then - setenv AST $STARLINK_DIR -endif - -if( ! $?LDFLAGS ) then - setenv LDFLAGS "" -endif - -setenv PATH $AST/bin\:$STARLINK_DIR/bin\:$PATH - - -# Build the progs -#gfortran -fno-second-underscore -o regression regression.f -fno-range-check $LDFLAGS -I$AST/include -I$STARLINK_DIR/include -L$AST/lib -L$STARLINK_DIR/lib `ast_link -ems` `chr_link` -gfortran -fno-second-underscore -o plotter plotter.f -fno-range-check $LDFLAGS -I$AST/include -I$STARLINK_DIR/include -L$AST/lib -L$STARLINK_DIR/lib `ast_link -pgp -ems` `pgplot_link` -gfortran -fno-second-underscore -o wcsconverter wcsconverter.f -fno-range-check $LDFLAGS -I$AST/include -I$STARLINK_DIR/include -L$AST/lib -L$STARLINK_DIR/lib `ast_link -ems` `chr_link` `err_link` -gfortran -fno-second-underscore -o simplify simplify.f -fno-range-check $LDFLAGS -I$AST/include -I$STARLINK_DIR/include -L$AST/lib -L$STARLINK_DIR/lib `ast_link -ems` `chr_link` `err_link` - -# Run the other test progs -echo "" - - -foreach prog (testmapping testchebymap testunitnormmap testskyframe testframeset testchannel testpolymap testcmpmap testlutmap testfitstable testtable teststcschan teststc testspecframe testfitschan testswitchmap testrebin testrebinseq testtrangrid testnormmap testtime testrate testflux testratemap testspecflux testxmlchan testregions testkeymap ) - -gfortran -fno-second-underscore -w -g -o $prog -g $prog.f -fno-range-check $LDFLAGS -I$AST/include \ - -I$STARLINK_DIR/include -L$AST/lib -L$STARLINK_DIR/lib `ast_link -ems` \ - `psx_link` `prm_link` `chr_link` `err_link` - -./$prog -\rm $prog - -end - - - -foreach prog (testobject testconvert testerror) - -gcc -o $prog $prog.c -I.. -DHAVE_CONFIG_H $LDFLAGS -L$STARLINK_DIR/lib `ast_link` - -./$prog -\rm $prog - -end - - - - -# Make new plots. -echo "" -echo "Generating new plots..." -echo "" -if( $1 == "-nd" ) then -echo " (but not displaying them because the -nd option was supplied)" -echo "" -endif - -\rm *-new.ps >& /dev/null - -foreach n (*.head) - set bn = `basename $n .head` - - set atfile = "${bn}.attr" - if( -e $atfile ) then - set attr1 = `cat $atfile` - else - set attr1 = ' ' - endif - - set atfile = "${bn}.fattr" - if( -e $atfile ) then - set attr2 = `cat $atfile` - else - set attr2 = ' ' - endif - - set boxfile = "${bn}.box" - if( -e $boxfile ) then - set box = `cat $boxfile` - else - set box = ' ' - endif - - - set psfile = "${bn}-new.ps" - ./plotter $n "$attr1" "$attr2" a.ps $box - - if( -e $STARLINK_DIR/bin/psmerge ) then - $STARLINK_DIR/bin/psmerge -t300x300 -r90 a.ps > $psfile - else - cp a.ps $psfile - endif - - if( $1 != "-nd" ) then - gv $psfile -orientation=landscape - endif - -end - -\rm -f a.ps - - -# Make new fits headers -echo "" -echo "Doing WCS conversion tests..." -echo "" - -set ok = 1 -foreach n ( "timj ast fits-wcs cdmatrix=1" \ - "timj ast fits-iraf" \ - "timj ast fits-aips" \ - "timj ast fits-pc" \ - "timj ast native" \ - "timj ast native" \ - "a20070718_00010_02_cube ast fits-wcs" \ - "dss fits-dss ast" \ - "dss ast dss" \ - "dss ast fits-wcs cdmatrix=1" \ - "degen1 ast fits-wcs cdmatrix=1" \ - "degen1 ast fits-wcs cdmatrix=1" \ - "sip head fits-wcs cdmatrix=1,sipreplace=0" \ - "longslit fits-pc fits-wcs cdmatrix=1" ) - - set a = `echo $n` - - set base = $a[1] - set in_suffix = $a[2] - set encoding = $a[3] - if( $#a > 3 ) then - set attrs = $a[4] - else - set attrs = "" - endif - - set in_file = "$base.$in_suffix" - set old_file = "$base.$encoding" - set new_file = "$base-new.$encoding" - - - ./wcsconverter $in_file $encoding $new_file "$attrs,FitsDigits=8" - diff -c $old_file $new_file > ! $old_file.diff - - if( $status == 0 ) then - \rm -f $old_file.diff $new_file - else - echo " $old_file and $new_file differ\!\! (see $old_file.diff)" - echo " Command was:" - echo " wcsconverter $in_file $encoding $new_file $attrs,FitsDigits=8" - set ok = 0 - endif - -end - -if( $ok == 1 ) then - echo " All WCS conversion tests passed" - echo "" -endif - - -echo "" -echo "Doing Simplification tests..." -echo "" - -set ok = 1 -foreach n ( *.map ) - set a = `basename $n .map` - ./simplify $n $a.out - diff -c $a.simp $a.out > ! $a.diff - - if( $status == 0 ) then - \rm -f $a.out $a.diff - else - echo " $a.simp and $a.out differ\!\! (see $a.diff)" - set ok = 0 - endif - -end - -if( $ok == 1 ) then - echo " All simplification tests passed" - echo "" - echo "" -endif - - - - - - -\rm -f plotter wcsconverter simplify testxmlchan diff --git a/ast/ast_tester/brad.map b/ast/ast_tester/brad.map deleted file mode 100644 index d403fce..0000000 --- a/ast/ast_tester/brad.map +++ /dev/null @@ -1,58 +0,0 @@ -Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates -IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 1 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = 0.215698 # Shift for axis 1 - End WinMap - MapB = # Second component Mapping - Begin LutMap # Map 1-d coordinates using a lookup table - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Nlut = 11 # Number of lookup table elements - Start = 1 # Input value at first element - Incr = 100 # Input value increment between elements - LutInt = 0 # Interpolation method - L1 = 1.39532005786896 # Lookup table elements... - L2 = 1.50432002544403 - L3 = 1.61332011222839 - L4 = 1.72232007980347 - L5 = 1.83132004737854 - L6 = 1.94032001495361 - L7 = 2.04932022094727 - L8 = 2.15831995010376 - L9 = 2.26732015609741 - L10 = 2.37632012367249 - L11 = 2.48532009124756 - End LutMap - End CmpMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin ZoomMap # Zoom about the origin - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Zoom = 5.23598775598299e-06 # Zoom factor - End ZoomMap - MapB = # Second component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - End WcsMap - End CmpMap -End CmpMap diff --git a/ast/ast_tester/brad.simp b/ast/ast_tester/brad.simp deleted file mode 100644 index ffa6e18..0000000 --- a/ast/ast_tester/brad.simp +++ /dev/null @@ -1,49 +0,0 @@ - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - Sft1 = -0.215698 # Shift for axis 1 - Scl2 = 5.2359877559829903e-06 # Scale factor for axis 2 - Scl3 = 5.2359877559829903e-06 # Scale factor for axis 3 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin LutMap # Map 1-d coordinates using a lookup table - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Nlut = 11 # Number of lookup table elements - Start = 1 # Input value at first element - Incr = 100 # Input value increment between elements - LutInt = 0 # Interpolation method - L1 = 1.39532005786896 # Lookup table elements... - L2 = 1.5043200254440301 - L3 = 1.61332011222839 - L4 = 1.7223200798034699 - L5 = 1.83132004737854 - L6 = 1.94032001495361 - L7 = 2.0493202209472701 - L8 = 2.1583199501037602 - L9 = 2.2673201560974099 - L10 = 2.3763201236724898 - L11 = 2.4853200912475599 - End LutMap - MapB = # Second component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - End WcsMap - End CmpMap - End CmpMap diff --git a/ast/ast_tester/car1.attr b/ast/ast_tester/car1.attr deleted file mode 100644 index f74084f..0000000 --- a/ast/ast_tester/car1.attr +++ /dev/null @@ -1 +0,0 @@ -numlabgap=0.05 diff --git a/ast/ast_tester/car1.box b/ast/ast_tester/car1.box deleted file mode 100644 index 09670e6..0000000 --- a/ast/ast_tester/car1.box +++ /dev/null @@ -1 +0,0 @@ -0 0 2962 562 diff --git a/ast/ast_tester/car1.fattr b/ast/ast_tester/car1.fattr deleted file mode 100644 index 5f408d2..0000000 --- a/ast/ast_tester/car1.fattr +++ /dev/null @@ -1 +0,0 @@ -carlin=1 diff --git a/ast/ast_tester/car1.head b/ast/ast_tester/car1.head deleted file mode 100644 index bec8d59..0000000 --- a/ast/ast_tester/car1.head +++ /dev/null @@ -1,32 +0,0 @@ -SIMPLE = T / Standard FITS format -BITPIX = 16 / Bits per pixel -NAXIS = 2 / Number of axes -NAXIS1 = 2961 / Number pixels on axis 1 -NAXIS2 = 561 / Number pixels on axis 2 -CTYPE1 = 'GLON-CAR' / axis 1 coord type -CRVAL1 = 1.850000e+02 / coord value at CRPIX1 -CDELT1 = -1.250000e-01 / pixel spacing for axis 1 -CRPIX1 = 1.000000 / ref pixel for axis 1 -CTYPE2 = 'GLAT-CAR' / axis 2 coord type -CRVAL2 = -3.500000e+01 / coord value at CRPIX2 -CDELT2 = 1.250000e-01 / pixel spacing for axis 2 -CRPIX2 = 1.000000 / ref pixel for axis 2 -BSCALE = 2.610167e-02 / real = int*bscale + bzero -BZERO = 8.321995e+02 / -DATAMIN = -6.326761e+00 / minimum real value -DATAMAX = 1.670731e+03 / maximum real value -BLANK = -32768 / missing data flag -COMMENT PARENT DISK FILE: Wco_DHT2001.fits -COMMENT temp =colscales( CHANGE-ME , -185.0000, 185.0000) -COMMENT coords=rowscales( temp, 35.0000, -35.0000) -COMMENT Written by MacFITS -COMMENT Created: Tuesday, 14 August, 2001 01:18:06 PM -COMMENT Whole-Galaxy velocity-integrated CO(1-0) map (Fig. 2) from -COMMENT "The Milky Way in Molecular Clouds: A New Complete CO Survey" -COMMENT T. M. Dame, Dap Hartmann, & P. Thaddeus (2001), ApJ, 547, 792. -COMMENT WARNING: Both the angular resolution and the sensitivity varies -COMMENT from region to region in this map: see Fig. 1 and Table 1 from -COMMENT the paper above. Moment masking and clipping were used as -COMMENT necessary to keep the noise in the map below ~1.5 K km/s. -COMMENT See Section 2.2 for details. -END diff --git a/ast/ast_tester/car2.attr b/ast/ast_tester/car2.attr deleted file mode 100644 index 483f747..0000000 --- a/ast/ast_tester/car2.attr +++ /dev/null @@ -1 +0,0 @@ -numlabgap(2)=0.05,labelling=interior diff --git a/ast/ast_tester/car2.box b/ast/ast_tester/car2.box deleted file mode 100644 index 09670e6..0000000 --- a/ast/ast_tester/car2.box +++ /dev/null @@ -1 +0,0 @@ -0 0 2962 562 diff --git a/ast/ast_tester/car2.fattr b/ast/ast_tester/car2.fattr deleted file mode 100644 index 5f408d2..0000000 --- a/ast/ast_tester/car2.fattr +++ /dev/null @@ -1 +0,0 @@ -carlin=1 diff --git a/ast/ast_tester/car2.head b/ast/ast_tester/car2.head deleted file mode 100644 index bec8d59..0000000 --- a/ast/ast_tester/car2.head +++ /dev/null @@ -1,32 +0,0 @@ -SIMPLE = T / Standard FITS format -BITPIX = 16 / Bits per pixel -NAXIS = 2 / Number of axes -NAXIS1 = 2961 / Number pixels on axis 1 -NAXIS2 = 561 / Number pixels on axis 2 -CTYPE1 = 'GLON-CAR' / axis 1 coord type -CRVAL1 = 1.850000e+02 / coord value at CRPIX1 -CDELT1 = -1.250000e-01 / pixel spacing for axis 1 -CRPIX1 = 1.000000 / ref pixel for axis 1 -CTYPE2 = 'GLAT-CAR' / axis 2 coord type -CRVAL2 = -3.500000e+01 / coord value at CRPIX2 -CDELT2 = 1.250000e-01 / pixel spacing for axis 2 -CRPIX2 = 1.000000 / ref pixel for axis 2 -BSCALE = 2.610167e-02 / real = int*bscale + bzero -BZERO = 8.321995e+02 / -DATAMIN = -6.326761e+00 / minimum real value -DATAMAX = 1.670731e+03 / maximum real value -BLANK = -32768 / missing data flag -COMMENT PARENT DISK FILE: Wco_DHT2001.fits -COMMENT temp =colscales( CHANGE-ME , -185.0000, 185.0000) -COMMENT coords=rowscales( temp, 35.0000, -35.0000) -COMMENT Written by MacFITS -COMMENT Created: Tuesday, 14 August, 2001 01:18:06 PM -COMMENT Whole-Galaxy velocity-integrated CO(1-0) map (Fig. 2) from -COMMENT "The Milky Way in Molecular Clouds: A New Complete CO Survey" -COMMENT T. M. Dame, Dap Hartmann, & P. Thaddeus (2001), ApJ, 547, 792. -COMMENT WARNING: Both the angular resolution and the sensitivity varies -COMMENT from region to region in this map: see Fig. 1 and Table 1 from -COMMENT the paper above. Moment masking and clipping were used as -COMMENT necessary to keep the noise in the map below ~1.5 K km/s. -COMMENT See Section 2.2 for details. -END diff --git a/ast/ast_tester/car3.attr b/ast/ast_tester/car3.attr deleted file mode 100644 index b80a7c0..0000000 --- a/ast/ast_tester/car3.attr +++ /dev/null @@ -1 +0,0 @@ -grid=1 diff --git a/ast/ast_tester/car3.box b/ast/ast_tester/car3.box deleted file mode 100644 index 54240c7..0000000 --- a/ast/ast_tester/car3.box +++ /dev/null @@ -1 +0,0 @@ -0 0 400 400 diff --git a/ast/ast_tester/car3.head b/ast/ast_tester/car3.head deleted file mode 100644 index de6c76e..0000000 --- a/ast/ast_tester/car3.head +++ /dev/null @@ -1,8 +0,0 @@ -CTYPE1 = 'GLON-CAR' -CRVAL1 = 1.850000e+02 -CDELT1 = -1.250000e-01 -CRPIX1 = 200.000000 -CTYPE2 = 'GLAT-CAR' -CRVAL2 = -3.500000e+01 -CDELT2 = 1.250000e-01 -CRPIX2 = 200.000000 diff --git a/ast/ast_tester/car4.attr b/ast/ast_tester/car4.attr deleted file mode 100644 index e69de29..0000000 diff --git a/ast/ast_tester/car4.box b/ast/ast_tester/car4.box deleted file mode 100644 index 0393b0d..0000000 --- a/ast/ast_tester/car4.box +++ /dev/null @@ -1 +0,0 @@ -0 0 951 1851 diff --git a/ast/ast_tester/car4.fattr b/ast/ast_tester/car4.fattr deleted file mode 100644 index 5f408d2..0000000 --- a/ast/ast_tester/car4.fattr +++ /dev/null @@ -1 +0,0 @@ -carlin=1 diff --git a/ast/ast_tester/car4.head b/ast/ast_tester/car4.head deleted file mode 100644 index 95cd97a..0000000 --- a/ast/ast_tester/car4.head +++ /dev/null @@ -1,38 +0,0 @@ -SIMPLE = T / Written by IDL: Thu Apr 27 08:52:27 2000 -BITPIX = -32 / -NAXIS = 2 / -NAXIS1 = 951 / -NAXIS2 = 1851 / -CRPIX1 = 211076.0 / -CRVAL1 = 0.000000000 / -CTYPE1 = 'GLON-CAR' / -CRPIX2 = 475.39400 / -CRVAL2 = 0.000000000 / -CTYPE2 = 'GLAT-CAR' / -CROTA2 = 0.000000000 / -LONPOLE = 0.00000 / Defined by Greisen and Calabretta -CD1_1 = -0.0016666667 / -CD1_2 = 0.00000 / -CD2_1 = 0.00000 / -CD2_2 = 0.0016666667 / -WAVELENG= 8.28000e-06 / Isophotal wavelength in meters -BUNIT = 'W/m^2-sr' / -SECURITY= 'Unclassified' / -TELESCOP= 'MSX ' / -INSTRUME= 'SPIRITIII' / -ORIGIN = 'AFRL-VSBC' / -MJD-OBS = 50295.5 / Mean modified Julian date of observation -DATE = '16/02/2000' / Date of file generation -HISTORY Convert Version 6.2.X -HISTORY Level-2A Deshadow Version 4.0 -HISTORY Level-2A Saturation Correction Version 1.0 -HISTORY Pointing Convert Version 6.0.1 -HISTORY Makeimage Version 3.2 -HISTORY Destriped -HISTORY Data collected in J2000 FK5 coordinates -HISTORY Data samples transformed to Galactic coordinates -HISTORY and convolved onto image grid using sigma=3.0 arcsec -HISTORY Gaussian kernel -HISTORY Master Plate: GP_351.0_+0.0_A.fits -HISTORY Written by IDL: 28-Jan-2000 17:44:54.00 -END diff --git a/ast/ast_tester/car5.attr b/ast/ast_tester/car5.attr deleted file mode 100644 index e69de29..0000000 diff --git a/ast/ast_tester/car5.box b/ast/ast_tester/car5.box deleted file mode 100644 index 0393b0d..0000000 --- a/ast/ast_tester/car5.box +++ /dev/null @@ -1 +0,0 @@ -0 0 951 1851 diff --git a/ast/ast_tester/car5.head b/ast/ast_tester/car5.head deleted file mode 100644 index 2be3a64..0000000 --- a/ast/ast_tester/car5.head +++ /dev/null @@ -1,38 +0,0 @@ -SIMPLE = T / Written by IDL: Thu Apr 27 08:52:27 2000 -BITPIX = -32 / -NAXIS = 2 / -NAXIS1 = 951 / -NAXIS2 = 1851 / -CRPIX1 = -4932.0204 / -CRVAL1 = 0.000000000 / -CTYPE1 = 'GLON-CAR' / -CRPIX2 = 475.39400 / -CRVAL2 = 0.000000000 / -CTYPE2 = 'GLAT-CAR' / -CROTA2 = 0.000000000 / -LONPOLE = 0.00000 / Defined by Greisen and Calabretta -CD1_1 = -0.0016666667 / -CD1_2 = 0.00000 / -CD2_1 = 0.00000 / -CD2_2 = 0.0016666667 / -WAVELENG= 8.28000e-06 / Isophotal wavelength in meters -BUNIT = 'W/m^2-sr' / -SECURITY= 'Unclassified' / -TELESCOP= 'MSX ' / -INSTRUME= 'SPIRITIII' / -ORIGIN = 'AFRL-VSBC' / -MJD-OBS = 50295.5 / Mean modified Julian date of observation -DATE = '16/02/2000' / Date of file generation -HISTORY Convert Version 6.2.X -HISTORY Level-2A Deshadow Version 4.0 -HISTORY Level-2A Saturation Correction Version 1.0 -HISTORY Pointing Convert Version 6.0.1 -HISTORY Makeimage Version 3.2 -HISTORY Destriped -HISTORY Data collected in J2000 FK5 coordinates -HISTORY Data samples transformed to Galactic coordinates -HISTORY and convolved onto image grid using sigma=3.0 arcsec -HISTORY Gaussian kernel -HISTORY Master Plate: GP_351.0_+0.0_A.fits -HISTORY Written by IDL: 28-Jan-2000 17:44:54.00 -END diff --git a/ast/ast_tester/car6.attr b/ast/ast_tester/car6.attr deleted file mode 100644 index e69de29..0000000 diff --git a/ast/ast_tester/car6.box b/ast/ast_tester/car6.box deleted file mode 100644 index e5f0493..0000000 --- a/ast/ast_tester/car6.box +++ /dev/null @@ -1 +0,0 @@ -0 0 5401 1741 diff --git a/ast/ast_tester/car6.head b/ast/ast_tester/car6.head deleted file mode 100644 index 5356fa5..0000000 --- a/ast/ast_tester/car6.head +++ /dev/null @@ -1,39 +0,0 @@ -FITS headers in CHIPASS_Equ.fits: -SIMPLE = T / file does conform to FITS standard -BITPIX = -32 / IEEE (big-endian) 32-bit floating point data -NAXIS = 2 / number of data axes -NAXIS1 = 5401 / length of data axis 1 -NAXIS2 = 1741 / length of data axis 2 -EXTEND = T / FITS dataset may contain extensions -COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy -COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H -BUNIT = 'mK ' / Using 438.5 mK/(Jy/beam) plus 3300 mK offset -CTYPE1 = 'RA---CAR' -CRPIX1 = 2701. -CDELT1 = -0.0666666666666667 -CRVAL1 = 180. -CTYPE2 = 'DEC--CAR' -CRPIX2 = 1351. -CDELT2 = 0.0666666666666667 -CRVAL2 = 0. -LONPOLE = 0. / Native longitude of celestial pole -LATPOLE = 90. / Native latitude of celestial pole -RADESYS = 'FK5 ' / Equatorial coordinate system -EQUINOX = 2000.0 / Equinox of equatorial coordinates -BMAJ = 0.24000 / [deg] Beam major axis -BMIN = 0.24000 / [deg] Beam minor axis -BPA = 0.0 / [deg] Beam position angle -FREQENCY= 1.3945E+09 / [Hz] Centre frequency -BANDWID = 6.4E+07 / [Hz] Bandwidth -DATE = '2013-04-20T13:20:39' / file creation date (YYYY-MM-DDThh:mm:ss UT) -COMMENT ------------------------------------------------------------------------ -COMMENT This file contains a 1.4 GHz continuum map of the sky south of dec +26 -COMMENT produced from HIPASS and ZOA data. These surveys were undertaken with -COMMENT the 13-beam multibeam system on the Parkes radio telescope. -COMMENT Details may be found in the following paper: -COMMENT Calabretta, M.R., Staveley-Smith, L., and Barnes, D.G., (2013) -COMMENT PASA (in preparation). -COMMENT ------------------------------------------------------------------------ -COMMENT THIS IS A PRE-PUBLICATION IMAGE, FOR RESTRICTED DISTRIBUTION ONLY -COMMENT ------------------------------------------------------------------------ -END diff --git a/ast/ast_tester/cobe.attr b/ast/ast_tester/cobe.attr deleted file mode 100644 index c1f61e5..0000000 --- a/ast/ast_tester/cobe.attr +++ /dev/null @@ -1 +0,0 @@ -format(1)=gd,format(2)=gd,Grid=1,tickall=0,width(axes)=3 diff --git a/ast/ast_tester/cobe.box b/ast/ast_tester/cobe.box deleted file mode 100644 index b4f303e..0000000 --- a/ast/ast_tester/cobe.box +++ /dev/null @@ -1 +0,0 @@ -10.0 -10.0 300.0 280.0 diff --git a/ast/ast_tester/cobe.head b/ast/ast_tester/cobe.head deleted file mode 100644 index fb6da34..0000000 --- a/ast/ast_tester/cobe.head +++ /dev/null @@ -1,61 +0,0 @@ -SIMPLE = T / Written by IDL: 30-Jul-1997 05:35:42.00 -BITPIX = -32 / Bits per pixel. -NAXIS = 2 / Number of dimensions -NAXIS1 = 300 / Length of x axis. -NAXIS2 = 300 / Length of y axis. -CTYPE1 = 'GLON-ZEA' / X-axis type -CTYPE2 = 'GLAT-ZEA' / Y-axis type -CRVAL1 = -149.56866 / Reference pixel value -CRVAL2 = -19.758201 / Reference pixel value -CRPIX1 = 150.500 / Reference pixel -CRPIX2 = 150.500 / Reference pixel -CDELT1 = -1.20000 / Degrees/pixel -CDELT2 = 1.20000 / Degrees/pixel -CROTA1 = 0.00000 / Rotation in degrees. -COMMENT -COMMENT This file was produced by the SkyView survey analysis system from -COMMENT available astronomical surveys. The data are formatted -COMMENT as a simple two-dimensional FITS image with the same units as -COMMENT the orginal survey. A single ASCII table extension may be present -COMMENT which describes catalog objects found within the field of view. -COMMENT Copies of relevant copyright notices are included in this file. -COMMENT -COMMENT Questions should be directed to: -COMMENT -COMMENT scollick@skyview.gsfc.nasa.gov -COMMENT or -COMMENT mcglynn@grossc.gsfc.nasa.gov -COMMENT -COMMENT SkyView -COMMENT Code 668.1 -COMMENT Goddard Space Flight Center, Greenbelt, MD 20771 -COMMENT 301-286-7780 -COMMENT -COMMENT SkyView is supported by NASA ADP grant NAS 5-32068. -COMMENT -SURVEY = 'COBE DIRBE' -BUNITS = 'MJy/sr ' / -ORIGIN = 'CDAC ' / Cosmology Data Analysis Center -TELESCOP= 'COBE ' / COsmic Background Explorer satellite -INSTRUME= 'DIRBE ' / COBE instrument [DIRBE, DMR, FIRAS] -PIXRESOL= 9 / Quad tree pixel resolution [6, 9] -DATE = '27/09/94' / FITS file creation date (dd/mm/yy) -DATE-MAP= '16/09/94' / Date of original file creation (dd/mm/yy) -COMMENT COBE specific keywords -DATE-BEG= '08/12/89' / date of initial data represented (dd/mm/yy) -DATE-END= '25/09/90' / date of final data represented (dd/mm/yy) -COMMENT -COMMENT THE COBE DIRBE map is a combination of the original ten -COMMENT band passes with the following wavelengths: -COMMENT Band 1 - 1.25 microns -COMMENT Band 2 - 2.2 microns -COMMENT Band 3 - 3.5 microns -COMMENT Band 4 - 4.9 microns -COMMENT Band 5 - 12 microns -COMMENT Band 6 - 25 microns -COMMENT Band 7 - 60 microns -COMMENT Band 8 - 100 microns -COMMENT Band 9 - 140 microns -COMMENT Band 10 - 240 microns -COMMENT -END diff --git a/ast/ast_tester/degen1.ast b/ast/ast_tester/degen1.ast deleted file mode 100644 index 202f149..0000000 --- a/ast/ast_tester/degen1.ast +++ /dev/null @@ -1,318 +0,0 @@ -# -# This FrameSet has 2 axes in the Base (GRID) Frame, but 3 in the Current -# Frame. It is used to test the ability of FitsChan to create degenerate -# WCS axes. It represents the first DEC plane from a WAVE/RA/DEC 3D NDF. -# - Begin FrameSet # Set of inter-related coordinate systems -# Title = "3-d compound coordinate system" # Title of coordinate system -# Naxes = 3 # Number of coordinate axes -# Domain = "CMP" # Coordinate system domain -# Epoch = 2003.0173483725 # Julian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Lbl3 = "Wavelength axis with no distortion" # Label for axis 3 -# System = "Compound" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Uni3 = "um " # Units for axis 3 -# Dir1 = 0 # Plot axis 1 in reverse direction - ActUnt = 0 # Unit strings do not affect alignment - IsA Frame # Coordinate system description - Nframe = 4 # Number of Frames in FrameSet -# Base = 1 # Index of base Frame - Currnt = 4 # Index of current Frame - Nnode = 5 # Number of nodes in FrameSet - Nod1 = 3 # Frame 1 is associated with node 3 - Nod2 = 4 # Frame 2 is associated with node 4 - Nod3 = 5 # Frame 3 is associated with node 5 - Nod4 = 2 # Frame 4 is associated with node 2 - Lnk2 = 1 # Node 2 is derived from node 1 - Lnk3 = 1 # Node 3 is derived from node 1 - Lnk4 = 1 # Node 4 is derived from node 1 - Lnk5 = 1 # Node 5 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Data grid indices; first pixel at (1,1)" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Data grid index 1" # Label for axis 1 -# Lbl2 = "Data grid index 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - ActUnt = 0 # Unit strings do not affect alignment - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Data grid index 1" # Axis Label - Symbol = "g1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Data grid index 2" # Axis Label - Symbol = "g2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm2 = # Frame number 2 - Begin Frame # Coordinate system description - Title = "Pixel coordinates; first pixel at (0.5,0.5)" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "PIXEL" # Coordinate system domain -# Lbl1 = "Pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Pixel coordinate 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - ActUnt = 0 # Unit strings do not affect alignment - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 1" # Axis Label - Symbol = "p1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 2" # Axis Label - Symbol = "p2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm3 = # Frame number 3 - Begin Frame # Coordinate system description - Title = "Axis coordinates; first pixel at (0.5,0.5)" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "AXIS" # Coordinate system domain -# Lbl1 = "Axis 1" # Label for axis 1 -# Lbl2 = "Axis 2" # Label for axis 2 - ActUnt = 0 # Unit strings do not affect alignment - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Axis 1" # Axis Label - Symbol = "a1" # Axis symbol - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Axis 2" # Axis Label - Symbol = "a2" # Axis symbol - End Axis - End Frame - Frm4 = # Frame number 4 - Begin CmpFrame # Compound coordinate system description -# Title = "3-d compound coordinate system" # Title of coordinate system -# Naxes = 3 # Number of coordinate axes -# Domain = "CMP" # Coordinate system domain -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Lbl3 = "Wavelength axis with no distortion" # Label for axis 3 -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Uni3 = "um " # Units for axis 3 -# Dir1 = 0 # Plot axis 1 in reverse direction - ActUnt = 0 # Unit strings do not affect alignment - IsA Frame # Coordinate system description - Axp1 = 3 # Axis 1 permuted to use internal axis 3 - Axp2 = 1 # Axis 2 permuted to use internal axis 1 - Axp3 = 2 # Axis 3 permuted to use internal axis 2 - FrameA = # First component Frame - Begin SkyFrame # Description of celestial coordinate system - Naxes = 2 # Number of coordinate axes - Epoch = 2003.0173483725 # Julian epoch of observation - System = "FK5" # Coordinate system type - ActUnt = 0 # Unit strings do not affect alignment - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - Proj = "gnomonic" # Description of sky projection - Eqnox = 2000 # Julian epoch of mean equinox - End SkyFrame - FrameB = # Second component Frame - Begin Frame # Coordinate system description - Naxes = 1 # Number of coordinate axes - ActUnt = 0 # Unit strings do not affect alignment - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Wavelength axis with no distortion" # Axis Label - Symbol = "WAVE-WAV" # Axis symbol - Unit = "um " # Axis units - End Axis - End Frame - End CmpFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - Nout = 3 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin PermMap # Coordinate permutation - Nin = 2 # Number of input coordinates - Nout = 3 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Out1 = 1 # Output coordinate 1 = input coordinate 1 - Out2 = 2 # Output coordinate 2 = input coordinate 2 - Out3 = -1 # Output coordinate 3 = constant no. 1 - InCpy = 1 # Input coordinates = output coordinates - Nconst = 1 # Number of constants - Con1 = 1 # Constant number 1 - End PermMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -512.5 # Shift for axis 1 - Sft2 = -480.5 # Shift for axis 2 - Sft3 = -480.5 # Shift for axis 3 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -0.00109 # Forward matrix value - M1 = 5.84161700642502e-07 # Forward matrix value - M2 = -5.84161700642502e-07 # Forward matrix value - Form = "Diagonal" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 3 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - WcsAx1 = 2 # Index of celestial longitude axis - WcsAx2 = 3 # Index of celestial latitude axis - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin PermMap # Coordinate permutation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Out1 = 2 # Output coordinate 1 = input coordinate 2 - Out2 = 3 # Output coordinate 2 = input coordinate 3 - Out3 = 1 # Output coordinate 3 = input coordinate 1 - In1 = 3 # Input coordinate 1 = output coordinate 3 - In2 = 1 # Input coordinate 2 = output coordinate 1 - In3 = 2 # Input coordinate 3 = output coordinate 2 - End PermMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - Nout = 3 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - End SphMap - MapB = # Second component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.0122898607703168 # Forward matrix value - M1 = -0.231781944526882 # Forward matrix value - M2 = -0.972690130264301 # Forward matrix value - M3 = -0.00292831230784838 # Forward matrix value - M4 = -0.972767767862061 # Forward matrix value - M5 = 0.231763445771093 # Forward matrix value - M6 = -0.999920188969737 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = -0.0126339103497717 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - End CmpMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - End SphMap - End CmpMap - MapB = # Second component Mapping - Begin WinMap # Map one window on to another - Nin = 1 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Sft1 = 1.9534 # Shift for axis 1 - End WinMap - End CmpMap - MapB = # Second component Mapping - Begin PermMap # Coordinate permutation - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Out1 = 3 # Output coordinate 1 = input coordinate 3 - Out2 = 1 # Output coordinate 2 = input coordinate 1 - Out3 = 2 # Output coordinate 3 = input coordinate 2 - In1 = 2 # Input coordinate 1 = output coordinate 2 - In2 = 3 # Input coordinate 2 = output coordinate 3 - In3 = 1 # Input coordinate 3 = output coordinate 1 - End PermMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - Map3 = # Mapping between nodes 1 and 3 - Begin UnitMap # Unit (null) Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - End UnitMap - Map4 = # Mapping between nodes 1 and 4 - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Sft1 = -0.5 # Shift for axis 1 - Sft2 = -0.5 # Shift for axis 2 - End WinMap - Map5 = # Mapping between nodes 1 and 5 - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Sft1 = -0.5 # Shift for axis 1 - Sft2 = -0.5 # Shift for axis 2 - End WinMap - End FrameSet diff --git a/ast/ast_tester/degen1.fits-wcs b/ast/ast_tester/degen1.fits-wcs deleted file mode 100644 index 6e5309d..0000000 --- a/ast/ast_tester/degen1.fits-wcs +++ /dev/null @@ -1,40 +0,0 @@ -WCSAXES = 3 / Number of WCS axes -CRPIX1 = 1.0 / Reference pixel on axis 1 -CRPIX2 = 480.5 / Reference pixel on axis 2 -CRPIX3 = 480.5 / Reference pixel on axis 3 -CRVAL1 = 2.510935 / Value at ref. pixel on axis 1 -CRVAL2 = 166.59799 / Value at ref. pixel on axis 2 -CRVAL3 = -0.723889 / Value at ref. pixel on axis 3 -CTYPE1 = 'WAVE-WAV' / Wavelength axis with no distortion -CTYPE2 = 'RA---TAN' / Type of co-ordinate on axis 2 -CTYPE3 = 'DEC--TAN' / Type of co-ordinate on axis 3 -CD1_1 = -0.00109 / Transformation matrix element -CD2_2 = 3.347E-5 / Transformation matrix element -CD3_3 = -3.347E-5 / Transformation matrix element -CUNIT1 = 'um ' / Units for axis 1 -MJD-OBS = 52646.586 / Modified Julian Date of observation -DATE-OBS= '2003-01-07T14:03:28.816' / Date of observation -RADESYS = 'FK5 ' / Reference frame for RA/DEC values -EQUINOX = 2000.0 / [yr] Epoch of reference equinox -WCSAXESA= 2 / Number of WCS axes -WCSNAMEA= 'PIXEL ' / Reference name for the coord. frame -CRPIX1A = 1.0 / Reference pixel on axis 1 -CRPIX2A = 1.0 / Reference pixel on axis 2 -CRVAL1A = 0.5 / Value at ref. pixel on axis 1 -CRVAL2A = 0.5 / Value at ref. pixel on axis 2 -CTYPE1A = 'p1 ' / Pixel coordinate 1 -CTYPE2A = 'p2 ' / Pixel coordinate 2 -CD1_1A = 1.0 / Transformation matrix element -CD2_2A = 1.0 / Transformation matrix element -CUNIT1A = 'pixel ' / Units for axis 1 -CUNIT2A = 'pixel ' / Units for axis 2 -WCSAXESB= 2 / Number of WCS axes -WCSNAMEB= 'AXIS ' / Reference name for the coord. frame -CRPIX1B = 1.0 / Reference pixel on axis 1 -CRPIX2B = 1.0 / Reference pixel on axis 2 -CRVAL1B = 0.5 / Value at ref. pixel on axis 1 -CRVAL2B = 0.5 / Value at ref. pixel on axis 2 -CTYPE1B = 'a1 ' / Axis 1 -CTYPE2B = 'a2 ' / Axis 2 -CD1_1B = 1.0 / Transformation matrix element -CD2_2B = 1.0 / Transformation matrix element diff --git a/ast/ast_tester/doplot b/ast/ast_tester/doplot deleted file mode 100755 index f7df1ce..0000000 --- a/ast/ast_tester/doplot +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/tcsh - - if( ! $?STARLINK ) then - setenv STARLINK /star - endif - - if( ! $?AST ) then - setenv AST $STARLINK - endif - - if( ! $?LDFLAGS ) then - setenv LDFLAGS "" - endif - - setenv PATH $AST/bin\:$STARLINK/bin\:$PATH - - gfortran -fno-second-underscore -o plotter plotter.f -fno-range-check $LDFLAGS -I$AST/include -I$STARLINK/include -L$AST/lib -L$STARLINK/lib `ast_link -pgp -ems` `pgplot_link` - - set bn = $1 - set n = "${bn}.head" - - set atfile = "${bn}.attr" - if( -e $atfile ) then - set attr1 = `cat $atfile` - else - set attr1 = ' ' - endif - - set atfile = "${bn}.fattr" - if( -e $atfile ) then - set attr2 = `cat $atfile` - else - set attr2 = ' ' - endif - - set boxfile = "${bn}.box" - if( -e $boxfile ) then - set box = `cat $boxfile` - else - set box = ' ' - endif - - - plotter $n "$attr1" "$attr2" a.ps $box - - if( -e $STARLINK/bin/psmerge ) then - $STARLINK/bin/psmerge -t300x300 -r90 a.ps > b.ps - else - cp a.ps b.ps - endif - - gv b.ps -orientation=landscape - diff --git a/ast/ast_tester/dss.ast b/ast/ast_tester/dss.ast deleted file mode 100644 index 6c778c4..0000000 --- a/ast/ast_tester/dss.ast +++ /dev/null @@ -1,166 +0,0 @@ - Begin FrameSet # Set of inter-related coordinate systems -# Title = "FK5 equatorial coordinates; mean equinox J2000.0; gnomonic polynomial projection" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Epoch = 2000 # Julian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# System = "FK5" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction -# Bot2 = -1.5707963267948966 # Lowest legal axis value -# Top2 = 1.5707963267948966 # Highest legal axis value - IsA Frame # Coordinate system description - Nframe = 2 # Number of Frames in FrameSet - Base = 1 # Index of base Frame - Currnt = 2 # Index of current Frame - Lnk2 = 1 # Node 2 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Pixel Coordinates" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Pixel axis 1" # Label for axis 1 -# Lbl2 = "Pixel axis 2" # Label for axis 2 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel axis 1" # Axis Label - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel axis 2" # Axis Label - End Axis - End Frame - Frm2 = # Frame number 2 - Begin SkyFrame # Description of celestial coordinate system - Ident = " " # Permanent Object identification string - IsA Object # AST Object -# Title = "FK5 equatorial coordinates; mean equinox J2000.0; gnomonic polynomial projection" # Title of coordinate system - Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain - Epoch = 2000 # Julian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 - System = "FK5" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction -# Bot2 = -1.5707963267948966 # Lowest legal axis value -# Top2 = 1.5707963267948966 # Highest legal axis value - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - Proj = "gnomonic polynomial" # Description of sky projection -# SkyTol = 0.001 # Smallest significant separation [arc-sec] - Eqnox = 2000 # Julian epoch of mean equinox - SRefIs = "Ignored" # Not rotated (ref. pos. is ignored) - SRef1 = 2.8272374655684112 # Ref. pos. RA 10:47:57.3 - SRef2 = -1.0518122540502668 # Ref. pos. Dec -60:15:52 - End SkyFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -0.3287946560728543 # Shift for axis 1 - Scl1 = -0.00044129690205585437 # Scale factor for axis 1 - Sft2 = 0.38797155568647818 # Shift for axis 2 - Scl2 = 0.00044129690205585437 # Scale factor for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "TPN" # Gnomonic polynomial projection - PV1_0 = 0.00037777813768480556 # Projection parameter 0 for axis 1 - PV1_1 = 0.018675372165510556 # Projection parameter 1 for axis 1 - PV1_2 = 1.4659181119170556e-05 # Projection parameter 2 for axis 1 - PV1_4 = -5.6541834490241662e-09 # Projection parameter 4 for axis 1 - PV1_5 = -1.6598619578175834e-10 # Projection parameter 5 for axis 1 - PV1_6 = 3.324645548432778e-09 # Projection parameter 6 for axis 1 - PV1_7 = 6.8029375162963896e-10 # Projection parameter 7 for axis 1 - PV1_8 = -1.0315391309210556e-11 # Projection parameter 8 for axis 1 - PV1_9 = 6.5770184096316667e-10 # Projection parameter 9 for axis 1 - PV1_10 = 4.6843790588691666e-11 # Projection parameter 10 for axis 1 - PV1_17 = 0 # Projection parameter 17 for axis 1 - PV1_19 = 0 # Projection parameter 19 for axis 1 - PV1_21 = 0 # Projection parameter 21 for axis 1 - PV2_0 = 0.00020734395690532499 # Projection parameter 0 for axis 2 - PV2_1 = 0.018675089806542779 # Projection parameter 1 for axis 2 - PV2_2 = -1.6578391725152224e-05 # Projection parameter 2 for axis 2 - PV2_4 = -5.1378767937980552e-09 # Projection parameter 4 for axis 2 - PV2_5 = -1.7623932712259446e-09 # Projection parameter 5 for axis 2 - PV2_6 = 2.7161547313251387e-10 # Projection parameter 6 for axis 2 - PV2_7 = 7.088907407099166e-10 # Projection parameter 7 for axis 2 - PV2_8 = 1.8432618513145277e-11 # Projection parameter 8 for axis 2 - PV2_9 = 6.8491061989569442e-10 # Projection parameter 9 for axis 2 - PV2_10 = 7.3325859634708332e-13 # Projection parameter 10 for axis 2 - PV2_17 = 0 # Projection parameter 17 for axis 2 - PV2_19 = 0 # Projection parameter 19 for axis 2 - PV2_21 = 0 # Projection parameter 21 for axis 2 - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitude (rad.s) - End SphMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.82577216035104439 # Forward matrix value - M1 = -0.30920332196760869 # Forward matrix value - M2 = -0.47169232013396639 # Forward matrix value - M3 = -0.26848851872737706 # Forward matrix value - M4 = -0.95099595460979502 # Forward matrix value - M5 = 0.153364303628268 # Forward matrix value - M6 = -0.49599824042101986 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = -0.86832352582390171 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 2.8272374655684112 # Polar longitude (rad.s) - End SphMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End FrameSet diff --git a/ast/ast_tester/dss.dss b/ast/ast_tester/dss.dss deleted file mode 100644 index c57a035..0000000 --- a/ast/ast_tester/dss.dss +++ /dev/null @@ -1,58 +0,0 @@ -CNPIX1 = 1.0 / X corner (pixels) -CNPIX2 = 1.0 / Y corner (pixels) -PPO1 = 0.0 / Orientation co-efficients -PPO2 = 0.0 -PPO3 = -18825.904 -PPO4 = 0.0 -PPO5 = 0.0 -PPO6 = -22216.49 -XPIXELSZ= 25.28445 / X pixel size (microns) -YPIXELSZ= 25.28445 / Y pixel size (microns) -PLTRAH = 10.0 / RA at plate centre -PLTRAM = 47.0 -PLTRAS = 57.30587 -PLTDECD = 60.0 / DEC at plate centre -PLTDECM = 15.0 -PLTDECS = 51.85079 -PLTDECSN= '- ' -PLTSCALE= 67.230832 / Plate scale (arcsec/mm) -AMDX1 = 67.23134 / Plate solution x co-efficients -AMDX2 = 0.052773052 -AMDX3 = 1.3600013 -AMDX4 = -2.035506E-5 -AMDX5 = -5.975503E-7 -AMDX6 = 1.1968724E-5 -AMDX7 = 0.0 -AMDX8 = 2.4490575E-6 -AMDX9 = -3.7135409E-8 -AMDX10 = 2.3677266E-6 -AMDX11 = 1.6863765E-7 -AMDX12 = 0.0 -AMDX13 = 0.0 -AMDX14 = 0.0 -AMDX15 = 0.0 -AMDX16 = 0.0 -AMDX17 = 0.0 -AMDX18 = 0.0 -AMDX19 = 0.0 -AMDX20 = 0.0 -AMDY1 = 67.230323 / Plate solution y co-efficients -AMDY2 = -0.05968221 -AMDY3 = 0.74643824 -AMDY4 = -1.8496356E-5 -AMDY5 = -6.3446158E-6 -AMDY6 = 9.778157E-7 -AMDY7 = 0.0 -AMDY8 = 2.5520067E-6 -AMDY9 = 6.6357427E-8 -AMDY10 = 2.4656782E-6 -AMDY11 = 2.6397309E-9 -AMDY12 = 0.0 -AMDY13 = 0.0 -AMDY14 = 0.0 -AMDY15 = 0.0 -AMDY16 = 0.0 -AMDY17 = 0.0 -AMDY18 = 0.0 -AMDY19 = 0.0 -AMDY20 = 0.0 diff --git a/ast/ast_tester/dss.fits-dss b/ast/ast_tester/dss.fits-dss deleted file mode 100644 index c728dc4..0000000 --- a/ast/ast_tester/dss.fits-dss +++ /dev/null @@ -1,108 +0,0 @@ -SIMPLE = T /FITS header -BITPIX = 16 /No.Bits per pixel -NAXIS = 2 /No.dimensions -NAXIS1 = 530 /Length X axis -NAXIS2 = 530 /Length Y axis -EXTEND = T / -DATE = '29/08/02 ' /Date of FITS file creation -ORIGIN = 'CASB -- STScI ' /Origin of FITS image -PLTLABEL= 'V 11596 ' /Observatory plate label -PLATEID = '06A6 ' /GSSS Plate ID -REGION = 'XV128 ' /GSSS Region Name -DATE-OBS= '19/01/87 ' /UT date of Observation -UT = '17:35:00.00 ' /UT time of observation -EPOCH = 1.9870512695313E+03 /Epoch of plate -PLTRAH = 10 /Plate center RA -PLTRAM = 47 / -PLTRAS = 5.7305870000000E+01 / -PLTDECSN= '- ' /Plate center Dec -PLTDECD = 60 / -PLTDECM = 15 / -PLTDECS = 5.1850790000000E+01 / -EQUINOX = 2.0000000000000E+03 /Julian Reference frame equinox -EXPOSURE= 4.0000000000000E+00 /Exposure time minutes -BANDPASS= 6 /GSSS Bandpass code -PLTGRADE= 1 /Plate grade -PLTSCALE= 6.7200000000000E+01 /Plate Scale arcsec per mm -SITELAT = '-31:16:24.00 ' /Latitude of Observatory -SITELONG= '+149:03:42.00 ' /Longitude of Observatory -TELESCOP= 'UK Schmidt (new optics)' /Telescope where plate taken -CNPIX1 = 7696 /X corner (pixels) -CNPIX2 = 7926 /Y corner -DATATYPE= 'INTEGER*2 ' /Type of Data -SCANIMG = 'XV128_06A6_00_00.PIM' /Name of original scan -SCANNUM = 0 /Identifies scan of the plate -DCHOPPED= F /Image repaired for chopping effects -DSHEARED= F /Image repaired for shearing effects -DSCNDNUM= 0 /Identifies descendant of plate scan image -XPIXELSZ= 2.5284450000000E+01 /X pixel size microns -YPIXELSZ= 2.5284450000000E+01 /Y pixel size microns -PPO1 = 0.0000000000000E+00 /Orientation Coefficients -PPO2 = 0.0000000000000E+00 / -PPO3 = 1.7573793885557E+05 / -PPO4 = 0.0000000000000E+00 / -PPO5 = 0.0000000000000E+00 / -PPO6 = 1.7816277576304E+05 / -AMDX1 = 6.7231339795838E+01 /Plate solution x coefficients -AMDX2 = 5.2773052029014E-02 / -AMDX3 = 1.3600012956653E+00 / -AMDX4 = -2.0355060416487E-05 / -AMDX5 = -5.9755030481433E-07 / -AMDX6 = 1.1968723974358E-05 / -AMDX7 = 0.0000000000000E+00 / -AMDX8 = 2.4490575058667E-06 / -AMDX9 = -3.7135408713158E-08 / -AMDX10 = 2.3677266274674E-06 / -AMDX11 = 1.6863764611929E-07 / -AMDX12 = 0.0000000000000E+00 / -AMDX13 = 0.0000000000000E+00 / -AMDX14 = 0.0000000000000E+00 / -AMDX15 = 0.0000000000000E+00 / -AMDX16 = 0.0000000000000E+00 / -AMDX17 = 0.0000000000000E+00 / -AMDX18 = 0.0000000000000E+00 / -AMDX19 = 0.0000000000000E+00 / -AMDX20 = 0.0000000000000E+00 / -AMDY1 = 6.7230323303554E+01 /Plate solution y coefficients -AMDY2 = -5.9682210210548E-02 / -AMDY3 = 7.4643824485917E-01 / -AMDY4 = -1.8496356457673E-05 / -AMDY5 = -6.3446157764134E-06 / -AMDY6 = 9.7781570327705E-07 / -AMDY7 = 0.0000000000000E+00 / -AMDY8 = 2.5520066665557E-06 / -AMDY9 = 6.6357426647323E-08 / -AMDY10 = 2.4656782316245E-06 / -AMDY11 = 2.6397309468495E-09 / -AMDY12 = 0.0000000000000E+00 / -AMDY13 = 0.0000000000000E+00 / -AMDY14 = 0.0000000000000E+00 / -AMDY15 = 0.0000000000000E+00 / -AMDY16 = 0.0000000000000E+00 / -AMDY17 = 0.0000000000000E+00 / -AMDY18 = 0.0000000000000E+00 / -AMDY19 = 0.0000000000000E+00 / -AMDY20 = 0.0000000000000E+00 / - Based on photographic data obtained using The UK Schmidt Telescope. - The UK Schmidt Telescope was operated by the Royal Observatory - Edinburgh, with funding from the UK Science and Engineering Research - Council, until 1988 June, and thereafter by the Anglo-Australian - Observatory. Original plate material is copyright (c) the Royal - Observatory Edinburgh and the Anglo-Australian Observatory. The - plates were processed into the present compressed digital form with - their permission. The Digitized Sky Survey was produced at the Space - Telescope Science Institute under US Government grant NAG W-2166. - - Investigators using these scans are requested to include the above - acknowledgements in any publications. - - Copyright (c) 1993, 1994, Association of Universities for Research in - Astronomy, Inc. All rights reserved. -DATAMAX = 23833 /Maximum data value -DATAMIN = 3673 /Minimum data value -OBJECT = 'data ' /Object ID -OBJCTRA = '10 44 10.340 ' /Object Right Ascension (J2000) -OBJCTDEC= '-59 43 11.40 ' /Object Declination (J2000) -OBJCTX = 7961.96 /Object X on plate (pixels) -OBJCTY = 8191.07 /Object Y on plate (pixels) -END diff --git a/ast/ast_tester/dss.fits-wcs b/ast/ast_tester/dss.fits-wcs deleted file mode 100644 index e9896db..0000000 --- a/ast/ast_tester/dss.fits-wcs +++ /dev/null @@ -1,39 +0,0 @@ -WCSAXES = 2 / Number of WCS axes -CRPIX1 = -745.0645 / Reference pixel on axis 1 -CRPIX2 = -879.1622 / Reference pixel on axis 2 -CRVAL1 = 161.98877 / Value at ref. pixel on axis 1 -CRVAL2 = -60.264403 / Value at ref. pixel on axis 2 -CTYPE1 = 'RA---TAN' / Type of co-ordinate on axis 1 -CTYPE2 = 'DEC--TAN' / Type of co-ordinate on axis 2 -CD1_1 = -0.02528445 / Transformation matrix element -CD2_2 = 0.02528445 / Transformation matrix element -MJD-OBS = 51544.499 / Modified Julian Date of observation -DATE-OBS= '2000-01-01T11:58:55.816' / Date of observation -QV1_0 = 0.00037777814 / Projection parameter -QV1_1 = 0.018675372 / Projection parameter -QV1_2 = 1.4659181E-5 / Projection parameter -QV1_4 = -5.6541834E-9 / Projection parameter -QV1_5 = -1.659862E-10 / Projection parameter -QV1_6 = 3.3246455E-9 / Projection parameter -QV1_7 = 6.8029375E-10 / Projection parameter -QV1_8 = -1.0315391E-11 / Projection parameter -QV1_9 = 6.5770184E-10 / Projection parameter -QV1_10 = 4.6843791E-11 / Projection parameter -QV1_17 = 0.0 / Projection parameter -QV1_19 = 0.0 / Projection parameter -QV1_21 = 0.0 / Projection parameter -QV2_0 = 0.00020734396 / Projection parameter -QV2_1 = 0.01867509 / Projection parameter -QV2_2 = -1.6578392E-5 / Projection parameter -QV2_4 = -5.1378768E-9 / Projection parameter -QV2_5 = -1.7623933E-9 / Projection parameter -QV2_6 = 2.7161547E-10 / Projection parameter -QV2_7 = 7.0889074E-10 / Projection parameter -QV2_8 = 1.8432619E-11 / Projection parameter -QV2_9 = 6.8491062E-10 / Projection parameter -QV2_10 = 7.332586E-13 / Projection parameter -QV2_17 = 0.0 / Projection parameter -QV2_19 = 0.0 / Projection parameter -QV2_21 = 0.0 / Projection parameter -RADESYS = 'FK5 ' / Reference frame for RA/DEC values -EQUINOX = 2000.0 / [yr] Epoch of reference equinox diff --git a/ast/ast_tester/hpx.attr b/ast/ast_tester/hpx.attr deleted file mode 100644 index 496403c..0000000 --- a/ast/ast_tester/hpx.attr +++ /dev/null @@ -1 +0,0 @@ -border=1 diff --git a/ast/ast_tester/hpx.box b/ast/ast_tester/hpx.box deleted file mode 100644 index 8b52762..0000000 --- a/ast/ast_tester/hpx.box +++ /dev/null @@ -1 +0,0 @@ -0.5 0.5 300.5 200.5 diff --git a/ast/ast_tester/hpx.head b/ast/ast_tester/hpx.head deleted file mode 100644 index 9e82b8e..0000000 --- a/ast/ast_tester/hpx.head +++ /dev/null @@ -1,10 +0,0 @@ -NAXIS1 = 300 -NAXIS2 = 200 -CTYPE1 = 'GLON-HPX' -CTYPE2 = 'GLAT-HPX' -CRVAL1 = -149.56866 -CRVAL2 = -19.758201 -CRPIX1 = 150.500 -CRPIX2 = 100.500 -CDELT1 = -1.00000 -CDELT2 = 1.00000 diff --git a/ast/ast_tester/joye_car_headers/CAR_model.head b/ast/ast_tester/joye_car_headers/CAR_model.head deleted file mode 100644 index 82a7d4e..0000000 --- a/ast/ast_tester/joye_car_headers/CAR_model.head +++ /dev/null @@ -1,47 +0,0 @@ -FITS headers in CAR_model.fits: -SIMPLE = T / File conforms to NOST standard -BITPIX = -32 / Bits per pixel -NAXIS = 2 / No data is associated with this header -NAXIS1 = 72 / Length of data axis 1 -NAXIS2 = 36 / Length of data axis 2 -EXTEND = T / Extensions may be present -COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy -COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H -CTYPE1 = 'RA---CAR' / RA---%%%, %%% is the projection, e.g., AIT -CRPIX1 = 36.5 / Reference pixel -CRVAL1 = 266.41683 / RA at the reference pixel -CDELT1 = -5. / X-axis incr per pixel at ref pixel (deg) -CUNIT1 = 'deg ' / Physical unit of X-axis -CTYPE2 = 'DEC--CAR' / DEC---%%%, %%% is the projection, e.g., AIT -CRPIX2 = 18.5 / Reference pixel -CRVAL2 = -29.00781 / DEC at the reference pixel -CDELT2 = 5. / Y-axis incr per pixel at ref pixel (deg) -CUNIT2 = 'deg ' / Physical unit of Y-axis -CROTA2 = 0. / Image rotation (deg) -DATE = '2011-03-16T11:50:24' / -TELESCOP= 'GLAST ' / Name of telescope generating data -INSTRUME= 'LAT ' / Name of instrument generating data -EQUINOX = 2000. / Equinox of RA & DEC specifications -CREATOR = 'gtmodel ' / Software creating file -HISTORY $Id: LatCountsMapTemplate,v 1.2 2004/09/24 03:54:20 jc -HISTORY hiang E -CHECKSUM= 'AU2LCU0IAU0IAU0I' / HDU checksum updated 2011-03-16T15:51:49 -DATASUM = '2800807754' / data unit checksum updated 2011-03-16T15:51:49 -DSTYP1 = 'TIME ' -DSUNI1 = 's ' -DSVAL1 = 'TABLE ' -DSREF1 = ':GTI ' -DSTYP2 = 'ENERGY ' -DSUNI2 = 'MeV ' -DSVAL2 = '100:1000' -DSTYP3 = 'EVENT_CLASS' -DSUNI3 = 'dimensionless' -DSVAL3 = '4:4 ' -DSTYP4 = 'ZENITH_ANGLE' -DSUNI4 = 'deg ' -DSVAL4 = '0:105 ' -NDSKEYS = 4 -FILENAME= 'CAR_model.fits' -HISTORY File modified by user 'jsperki1' with fv on 2011-03-16T12:00:29 -HISTORY File modified by user 'jsperki1' with fv on 2011-03-16T12:01:49 -END diff --git a/ast/ast_tester/joye_car_headers/CHIPASS_Equ.head b/ast/ast_tester/joye_car_headers/CHIPASS_Equ.head deleted file mode 100644 index 5356fa5..0000000 --- a/ast/ast_tester/joye_car_headers/CHIPASS_Equ.head +++ /dev/null @@ -1,39 +0,0 @@ -FITS headers in CHIPASS_Equ.fits: -SIMPLE = T / file does conform to FITS standard -BITPIX = -32 / IEEE (big-endian) 32-bit floating point data -NAXIS = 2 / number of data axes -NAXIS1 = 5401 / length of data axis 1 -NAXIS2 = 1741 / length of data axis 2 -EXTEND = T / FITS dataset may contain extensions -COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy -COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H -BUNIT = 'mK ' / Using 438.5 mK/(Jy/beam) plus 3300 mK offset -CTYPE1 = 'RA---CAR' -CRPIX1 = 2701. -CDELT1 = -0.0666666666666667 -CRVAL1 = 180. -CTYPE2 = 'DEC--CAR' -CRPIX2 = 1351. -CDELT2 = 0.0666666666666667 -CRVAL2 = 0. -LONPOLE = 0. / Native longitude of celestial pole -LATPOLE = 90. / Native latitude of celestial pole -RADESYS = 'FK5 ' / Equatorial coordinate system -EQUINOX = 2000.0 / Equinox of equatorial coordinates -BMAJ = 0.24000 / [deg] Beam major axis -BMIN = 0.24000 / [deg] Beam minor axis -BPA = 0.0 / [deg] Beam position angle -FREQENCY= 1.3945E+09 / [Hz] Centre frequency -BANDWID = 6.4E+07 / [Hz] Bandwidth -DATE = '2013-04-20T13:20:39' / file creation date (YYYY-MM-DDThh:mm:ss UT) -COMMENT ------------------------------------------------------------------------ -COMMENT This file contains a 1.4 GHz continuum map of the sky south of dec +26 -COMMENT produced from HIPASS and ZOA data. These surveys were undertaken with -COMMENT the 13-beam multibeam system on the Parkes radio telescope. -COMMENT Details may be found in the following paper: -COMMENT Calabretta, M.R., Staveley-Smith, L., and Barnes, D.G., (2013) -COMMENT PASA (in preparation). -COMMENT ------------------------------------------------------------------------ -COMMENT THIS IS A PRE-PUBLICATION IMAGE, FOR RESTRICTED DISTRIBUTION ONLY -COMMENT ------------------------------------------------------------------------ -END diff --git a/ast/ast_tester/joye_car_headers/car1.fattr b/ast/ast_tester/joye_car_headers/car1.fattr deleted file mode 100644 index 5f408d2..0000000 --- a/ast/ast_tester/joye_car_headers/car1.fattr +++ /dev/null @@ -1 +0,0 @@ -carlin=1 diff --git a/ast/ast_tester/joye_car_headers/car1.head b/ast/ast_tester/joye_car_headers/car1.head deleted file mode 100644 index bec8d59..0000000 --- a/ast/ast_tester/joye_car_headers/car1.head +++ /dev/null @@ -1,32 +0,0 @@ -SIMPLE = T / Standard FITS format -BITPIX = 16 / Bits per pixel -NAXIS = 2 / Number of axes -NAXIS1 = 2961 / Number pixels on axis 1 -NAXIS2 = 561 / Number pixels on axis 2 -CTYPE1 = 'GLON-CAR' / axis 1 coord type -CRVAL1 = 1.850000e+02 / coord value at CRPIX1 -CDELT1 = -1.250000e-01 / pixel spacing for axis 1 -CRPIX1 = 1.000000 / ref pixel for axis 1 -CTYPE2 = 'GLAT-CAR' / axis 2 coord type -CRVAL2 = -3.500000e+01 / coord value at CRPIX2 -CDELT2 = 1.250000e-01 / pixel spacing for axis 2 -CRPIX2 = 1.000000 / ref pixel for axis 2 -BSCALE = 2.610167e-02 / real = int*bscale + bzero -BZERO = 8.321995e+02 / -DATAMIN = -6.326761e+00 / minimum real value -DATAMAX = 1.670731e+03 / maximum real value -BLANK = -32768 / missing data flag -COMMENT PARENT DISK FILE: Wco_DHT2001.fits -COMMENT temp =colscales( CHANGE-ME , -185.0000, 185.0000) -COMMENT coords=rowscales( temp, 35.0000, -35.0000) -COMMENT Written by MacFITS -COMMENT Created: Tuesday, 14 August, 2001 01:18:06 PM -COMMENT Whole-Galaxy velocity-integrated CO(1-0) map (Fig. 2) from -COMMENT "The Milky Way in Molecular Clouds: A New Complete CO Survey" -COMMENT T. M. Dame, Dap Hartmann, & P. Thaddeus (2001), ApJ, 547, 792. -COMMENT WARNING: Both the angular resolution and the sensitivity varies -COMMENT from region to region in this map: see Fig. 1 and Table 1 from -COMMENT the paper above. Moment masking and clipping were used as -COMMENT necessary to keep the noise in the map below ~1.5 K km/s. -COMMENT See Section 2.2 for details. -END diff --git a/ast/ast_tester/joye_car_headers/car2.fattr b/ast/ast_tester/joye_car_headers/car2.fattr deleted file mode 100644 index 5f408d2..0000000 --- a/ast/ast_tester/joye_car_headers/car2.fattr +++ /dev/null @@ -1 +0,0 @@ -carlin=1 diff --git a/ast/ast_tester/joye_car_headers/car2.head b/ast/ast_tester/joye_car_headers/car2.head deleted file mode 100644 index bec8d59..0000000 --- a/ast/ast_tester/joye_car_headers/car2.head +++ /dev/null @@ -1,32 +0,0 @@ -SIMPLE = T / Standard FITS format -BITPIX = 16 / Bits per pixel -NAXIS = 2 / Number of axes -NAXIS1 = 2961 / Number pixels on axis 1 -NAXIS2 = 561 / Number pixels on axis 2 -CTYPE1 = 'GLON-CAR' / axis 1 coord type -CRVAL1 = 1.850000e+02 / coord value at CRPIX1 -CDELT1 = -1.250000e-01 / pixel spacing for axis 1 -CRPIX1 = 1.000000 / ref pixel for axis 1 -CTYPE2 = 'GLAT-CAR' / axis 2 coord type -CRVAL2 = -3.500000e+01 / coord value at CRPIX2 -CDELT2 = 1.250000e-01 / pixel spacing for axis 2 -CRPIX2 = 1.000000 / ref pixel for axis 2 -BSCALE = 2.610167e-02 / real = int*bscale + bzero -BZERO = 8.321995e+02 / -DATAMIN = -6.326761e+00 / minimum real value -DATAMAX = 1.670731e+03 / maximum real value -BLANK = -32768 / missing data flag -COMMENT PARENT DISK FILE: Wco_DHT2001.fits -COMMENT temp =colscales( CHANGE-ME , -185.0000, 185.0000) -COMMENT coords=rowscales( temp, 35.0000, -35.0000) -COMMENT Written by MacFITS -COMMENT Created: Tuesday, 14 August, 2001 01:18:06 PM -COMMENT Whole-Galaxy velocity-integrated CO(1-0) map (Fig. 2) from -COMMENT "The Milky Way in Molecular Clouds: A New Complete CO Survey" -COMMENT T. M. Dame, Dap Hartmann, & P. Thaddeus (2001), ApJ, 547, 792. -COMMENT WARNING: Both the angular resolution and the sensitivity varies -COMMENT from region to region in this map: see Fig. 1 and Table 1 from -COMMENT the paper above. Moment masking and clipping were used as -COMMENT necessary to keep the noise in the map below ~1.5 K km/s. -COMMENT See Section 2.2 for details. -END diff --git a/ast/ast_tester/joye_car_headers/car3.head b/ast/ast_tester/joye_car_headers/car3.head deleted file mode 100644 index de6c76e..0000000 --- a/ast/ast_tester/joye_car_headers/car3.head +++ /dev/null @@ -1,8 +0,0 @@ -CTYPE1 = 'GLON-CAR' -CRVAL1 = 1.850000e+02 -CDELT1 = -1.250000e-01 -CRPIX1 = 200.000000 -CTYPE2 = 'GLAT-CAR' -CRVAL2 = -3.500000e+01 -CDELT2 = 1.250000e-01 -CRPIX2 = 200.000000 diff --git a/ast/ast_tester/joye_car_headers/car4.fattr b/ast/ast_tester/joye_car_headers/car4.fattr deleted file mode 100644 index 5f408d2..0000000 --- a/ast/ast_tester/joye_car_headers/car4.fattr +++ /dev/null @@ -1 +0,0 @@ -carlin=1 diff --git a/ast/ast_tester/joye_car_headers/car4.head b/ast/ast_tester/joye_car_headers/car4.head deleted file mode 100644 index 95cd97a..0000000 --- a/ast/ast_tester/joye_car_headers/car4.head +++ /dev/null @@ -1,38 +0,0 @@ -SIMPLE = T / Written by IDL: Thu Apr 27 08:52:27 2000 -BITPIX = -32 / -NAXIS = 2 / -NAXIS1 = 951 / -NAXIS2 = 1851 / -CRPIX1 = 211076.0 / -CRVAL1 = 0.000000000 / -CTYPE1 = 'GLON-CAR' / -CRPIX2 = 475.39400 / -CRVAL2 = 0.000000000 / -CTYPE2 = 'GLAT-CAR' / -CROTA2 = 0.000000000 / -LONPOLE = 0.00000 / Defined by Greisen and Calabretta -CD1_1 = -0.0016666667 / -CD1_2 = 0.00000 / -CD2_1 = 0.00000 / -CD2_2 = 0.0016666667 / -WAVELENG= 8.28000e-06 / Isophotal wavelength in meters -BUNIT = 'W/m^2-sr' / -SECURITY= 'Unclassified' / -TELESCOP= 'MSX ' / -INSTRUME= 'SPIRITIII' / -ORIGIN = 'AFRL-VSBC' / -MJD-OBS = 50295.5 / Mean modified Julian date of observation -DATE = '16/02/2000' / Date of file generation -HISTORY Convert Version 6.2.X -HISTORY Level-2A Deshadow Version 4.0 -HISTORY Level-2A Saturation Correction Version 1.0 -HISTORY Pointing Convert Version 6.0.1 -HISTORY Makeimage Version 3.2 -HISTORY Destriped -HISTORY Data collected in J2000 FK5 coordinates -HISTORY Data samples transformed to Galactic coordinates -HISTORY and convolved onto image grid using sigma=3.0 arcsec -HISTORY Gaussian kernel -HISTORY Master Plate: GP_351.0_+0.0_A.fits -HISTORY Written by IDL: 28-Jan-2000 17:44:54.00 -END diff --git a/ast/ast_tester/joye_car_headers/car5.head b/ast/ast_tester/joye_car_headers/car5.head deleted file mode 100644 index 2be3a64..0000000 --- a/ast/ast_tester/joye_car_headers/car5.head +++ /dev/null @@ -1,38 +0,0 @@ -SIMPLE = T / Written by IDL: Thu Apr 27 08:52:27 2000 -BITPIX = -32 / -NAXIS = 2 / -NAXIS1 = 951 / -NAXIS2 = 1851 / -CRPIX1 = -4932.0204 / -CRVAL1 = 0.000000000 / -CTYPE1 = 'GLON-CAR' / -CRPIX2 = 475.39400 / -CRVAL2 = 0.000000000 / -CTYPE2 = 'GLAT-CAR' / -CROTA2 = 0.000000000 / -LONPOLE = 0.00000 / Defined by Greisen and Calabretta -CD1_1 = -0.0016666667 / -CD1_2 = 0.00000 / -CD2_1 = 0.00000 / -CD2_2 = 0.0016666667 / -WAVELENG= 8.28000e-06 / Isophotal wavelength in meters -BUNIT = 'W/m^2-sr' / -SECURITY= 'Unclassified' / -TELESCOP= 'MSX ' / -INSTRUME= 'SPIRITIII' / -ORIGIN = 'AFRL-VSBC' / -MJD-OBS = 50295.5 / Mean modified Julian date of observation -DATE = '16/02/2000' / Date of file generation -HISTORY Convert Version 6.2.X -HISTORY Level-2A Deshadow Version 4.0 -HISTORY Level-2A Saturation Correction Version 1.0 -HISTORY Pointing Convert Version 6.0.1 -HISTORY Makeimage Version 3.2 -HISTORY Destriped -HISTORY Data collected in J2000 FK5 coordinates -HISTORY Data samples transformed to Galactic coordinates -HISTORY and convolved onto image grid using sigma=3.0 arcsec -HISTORY Gaussian kernel -HISTORY Master Plate: GP_351.0_+0.0_A.fits -HISTORY Written by IDL: 28-Jan-2000 17:44:54.00 -END diff --git a/ast/ast_tester/joye_car_headers/cmap_3years_GP_D2.head b/ast/ast_tester/joye_car_headers/cmap_3years_GP_D2.head deleted file mode 100644 index d27e368..0000000 --- a/ast/ast_tester/joye_car_headers/cmap_3years_GP_D2.head +++ /dev/null @@ -1,162 +0,0 @@ -FITS headers in cmap_3years_GP_D2.fits: -SIMPLE = T / File conforms to NOST standard -BITPIX = 32 / Bits per pixel -NAXIS = 2 / No data is associated with this header -NAXIS1 = 1800 / Length of data axis 1 -NAXIS2 = 500 / Length of data axis 2 -EXTEND = T / Extensions may be present -COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy -COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H -CTYPE1 = 'GLON-CAR' / RA---%%%, %%% represents the projection method -CRPIX1 = 900.5 / Reference pixel -CRVAL1 = 0. / RA at the reference pixel -CDELT1 = -0.2 / X-axis incr per pixel of physical coord at posi -CUNIT1 = 'deg ' / Physical unit of X-axis -CTYPE2 = 'GLAT-CAR' / DEC---%%%, %%% represents the projection method -CRPIX2 = 250.5 / Reference pixel -CRVAL2 = 0. / DEC at the reference pixel -CDELT2 = 0.2 / Y-axis incr per pixel of physical coord at posi -CUNIT2 = 'deg ' / Physical unit of Y-axis -CROTA2 = 0. / Image rotation (deg) -DATE = '2011-11-18T09:38:44' / file creation date (YYYY-MM-DDThh:mm:ss U -FILENAME= 'cmap_3years_GP_D2.fits' / -TELESCOP= 'GLAST ' / name of telescope generating data -INSTRUME= 'LAT ' / name of instrument generating data -DATE-OBS= '2008-08-04T15:43:37.6089' / start date and time of the observation (U -DATE-END= '2011-07-31T23:59:59.0000' / end date and time of the observation (UTC -TIMEUNIT= 's ' / units for the time related keywords -TIMEZERO= 0. / clock correction -TIMESYS = 'TT ' / type of time system that is used -TIMEREF = 'LOCAL ' / reference frame used for times -CLOCKAPP= F / whether a clock drift correction has been appli -GPS_OUT = F / whether GPS time was unavailable at any time du -NDSKEYS = 5 -EQUINOX = 2000. / Equinox of RA & DEC specifications -OBSERVER= 'Peter Michelson' / GLAST/LAT PI -CREATOR = 'gtbin ' / Software and version creating file -HISTORY LatCountMapTemplate,v 1.3 2005/04/05 21:06:39 peachey -HISTORY Exp -CHECKSUM= 'HG8SH95PHE5PH95P' / HDU checksum updated 2011-11-18T08:38:44 -DATASUM = '3748023 ' / data unit checksum updated 2011-11-18T08:38:44 -DSTYP1 = 'TIME ' -DSUNI1 = 's ' -DSVAL1 = 'TABLE ' -DSREF1 = ':GTI ' -DSTYP2 = 'CONVERSION_TYPE' -DSUNI2 = 'dimensionless' -DSVAL2 = '1:1 ' -DSTYP3 = 'ENERGY ' -DSUNI3 = 'MeV ' -DSVAL3 = '2000:10000' -DSTYP4 = 'EVENT_CLASS' -DSUNI4 = 'dimensionless' -DSVAL4 = '4: ' -DSTYP5 = 'ZENITH_ANGLE' -DSUNI5 = 'deg ' -DSVAL5 = '0:100 ' -HISTORY The following history was copied from input files by gtbin -HISTORY ------------------------------------------------------------------------ -HISTORY BEGIN history copied from ft1_D2_Front.fits[EVENTS] -HISTORY ------------------------------------------------------------------------ -HISTORY Input merit file: /scratch/glastmp/P120-FT1/128/r0240311566_v120_merit.r -HISTORY oot -HISTORY Filter string: (FT1EventClass!=0) && (EvtElapsedTime >= 240311568) && ( -HISTORY EvtElapsedTime <= 240314221) -HISTORY CFITSIO used the following filtering expression to create this table: -HISTORY /scratch/glastmp/P120-FT1/128/foo.fit[EVENTS][gtifilter("/scratch/glastm -HISTORY p/P120-FT1/128/gll_xp_p120_r0240311566_v122.fit_tempgti")] -HISTORY CFITSIO used the following filtering expression to create this table: -HISTORY data/august_08-ft1.fits[EVENTS][100 <= ENERGY && ENERGY <= 1000000 && 4 -HISTORY <= EVENT_CLASS && 0 <= TIME && TIME <= 1000000000 && 0 <= ZENITH_ANGLE & -HISTORY & ZENITH_ANGLE <= 100 && gtifilter()] -HISTORY Filter string: 100 <= ENERGY && ENERGY <= 1000000 && 4 <= EVENT_CLASS && -HISTORY 0 <= TIME && TIME <= 1000000000 && 0 <= ZENITH_ANGLE && ZENITH_ANGLE <= -HISTORY 100 && gtifilter() -HISTORY CFITSIO used the following filtering expression to create this table: -HISTORY data/august_08_z100_ft1.fits[EVENTS][gtifilter("data/august_08-ft1.fits_ -HISTORY rocking_tempgti")] -HISTORY Filter string: 0 <= CONVERSION_TYPE && CONVERSION_TYPE <= 0 && 1000 <= E -HISTORY NERGY && ENERGY <= 5000 && 4 <= EVENT_CLASS && 0 <= TIME && TIME <= 1000 -HISTORY 000000 && 0 <= ZENITH_ANGLE && ZENITH_ANGLE <= 100 && gtifilter() -HISTORY ------------------------------------------------------------------------ -HISTORY END copied history -HISTORY ------------------------------------------------------------------------ -HISTORY ------------------------------------------------------------------------ -HISTORY BEGIN history copied from ft1_D2_Back.fits[EVENTS] -HISTORY ------------------------------------------------------------------------ -HISTORY Input merit file: /scratch/glastmp/P120-FT1/128/r0240311566_v120_merit.r -HISTORY oot -HISTORY Filter string: (FT1EventClass!=0) && (EvtElapsedTime >= 240311568) && ( -HISTORY EvtElapsedTime <= 240314221) -HISTORY CFITSIO used the following filtering expression to create this table: -HISTORY /scratch/glastmp/P120-FT1/128/foo.fit[EVENTS][gtifilter("/scratch/glastm -HISTORY p/P120-FT1/128/gll_xp_p120_r0240311566_v122.fit_tempgti")] -HISTORY CFITSIO used the following filtering expression to create this table: -HISTORY data/august_08-ft1.fits[EVENTS][100 <= ENERGY && ENERGY <= 1000000 && 4 -HISTORY <= EVENT_CLASS && 0 <= TIME && TIME <= 1000000000 && 0 <= ZENITH_ANGLE & -HISTORY & ZENITH_ANGLE <= 100 && gtifilter()] -HISTORY Filter string: 100 <= ENERGY && ENERGY <= 1000000 && 4 <= EVENT_CLASS && -HISTORY 0 <= TIME && TIME <= 1000000000 && 0 <= ZENITH_ANGLE && ZENITH_ANGLE <= -HISTORY 100 && gtifilter() -HISTORY CFITSIO used the following filtering expression to create this table: -HISTORY data/august_08_z100_ft1.fits[EVENTS][gtifilter("data/august_08-ft1.fits_ -HISTORY rocking_tempgti")] -HISTORY Filter string: 1 <= CONVERSION_TYPE && CONVERSION_TYPE <= 1 && 2000 <= E -HISTORY NERGY && ENERGY <= 10000 && 4 <= EVENT_CLASS && 0 <= TIME && TIME <= 100 -HISTORY 0000000 && 0 <= ZENITH_ANGLE && ZENITH_ANGLE <= 100 && gtifilter() -HISTORY ------------------------------------------------------------------------ -HISTORY END copied history -HISTORY ------------------------------------------------------------------------ -END -XTENSION= 'BINTABLE' / Binary table extension -BITPIX = 8 / Bits per pixel -NAXIS = 2 / Required value -NAXIS1 = 16 / Number of bytes per row -NAXIS2 = 17159 / Number of rows -PCOUNT = 0 / Normally 0 (no varying arrays) -GCOUNT = 1 / Required value -TFIELDS = 2 / Number of columns in table -TTYPE1 = 'START ' / Start time of an interval -TFORM1 = 'D ' / Data format of this field -TTYPE2 = 'STOP ' / Stop time of an interval -TFORM2 = 'D ' / Data format of this field -EXTNAME = 'GTI ' / Extension name -TELESCOP= 'GLAST ' / name of telescope generating data -INSTRUME= 'LAT ' / name of instrument generating data -MJDREFI = 51910. / Integer part of MJD corresponding to SC clock s -MJDREFF = '7.428703703703703D-4' / Fractional part of MJD corresponding to SC c -TSTART = 239557418.608944 / mission time of the start of the observation -TSTOP = 333849601. / mission time of the end of the observation -EXPOSURE= 69878014.2344566 / Integration time (in seconds) for the PHA data -HDUCLASS= 'OGIP ' / File format is OGIP standard -HDUCLAS1= 'GTI ' / Contains Good Time Intervals -HDUVERS = '1.2.0 ' / Version of file format -DATE-OBS= '2008-08-04T15:43:37.6089' / start date and time of the observation (U -DATE-END= '2011-07-31T23:59:59.0000' / end date and time of the observation (UTC -TIMEUNIT= 's ' / units for the time related keywords -TIMEZERO= 0. / clock correction -TIMESYS = 'TT ' / type of time system that is used -TIMEREF = 'LOCAL ' / reference frame used for times -CLOCKAPP= F / whether a clock drift correction has been appli -GPS_OUT = F / whether GPS time was unavailable at any time du -CREATOR = 'gtbin ' / Software and version creating file -HISTORY LatCountMapTemplate,v 1.3 2005/04/05 21:06:39 peachey -HISTORY Exp - - - - -TUNIT1 = 's ' / Unit of this field - -TUNIT2 = 's ' / Unit of this field -EXTVER = 1 / auto assigned by template parser -CHECKSUM= 'S4FDU3FBS3FBS3FB' / HDU checksum updated 2011-11-18T08:38:44 -DATASUM = '1639695499' / data unit checksum updated 2011-11-18T08:38:44 -HISTORY The following history was copied from input files by gtbin -HISTORY ------------------------------------------------------------------------ -HISTORY No history available in ft1_D2_Front.fits[GTI] -HISTORY ------------------------------------------------------------------------ -HISTORY ------------------------------------------------------------------------ -HISTORY No history available in ft1_D2_Back.fits[GTI] -HISTORY ------------------------------------------------------------------------ -END diff --git a/ast/ast_tester/joye_car_headers/doit b/ast/ast_tester/joye_car_headers/doit deleted file mode 100755 index a78a590..0000000 --- a/ast/ast_tester/joye_car_headers/doit +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/tcsh - -foreach n (*.head) - set bn = `basename $n .head` - echo "Doing $bn" - - set fat = "${bn}.fattr" - if( -e "$fat" ) then - set fattr = `cat $fat` - else - set fattr = "" - endif - - $HOME/work/ast/fplottest $n ps_l "$fattr" n - mv gks74.ps ${bn}.ps -end - diff --git a/ast/ast_tester/joye_car_headers/total_hi.head b/ast/ast_tester/joye_car_headers/total_hi.head deleted file mode 100644 index 2ed691c..0000000 --- a/ast/ast_tester/joye_car_headers/total_hi.head +++ /dev/null @@ -1,35 +0,0 @@ -SIMPLE = T -BITPIX = -32 -NAXIS = 2 -NAXIS1 = 721 -NAXIS2 = 361 -BUNIT = 'K km/s ' -DATAMAX = 11847.260742187500 -DATAMIN = -368.407501220703 -BZERO = 0.000000000000 -BSCALE = 1.000000000000 -BLANK = -32768 -OBJECT = 'Leiden/Dwingeloo HI Survey; (l,b) total HI' -TELESCOP= 'Dwingeloo 25-m' -OBSERVER= 'Dap Hartmann' -DATE-OBS= '02/09/93' -DATE = '20/01/96' -CTYPE1 = 'GLON-CAR' -CRVAL1 = 360.000000000000 -CRPIX1 = 1 -CDELT1 = -0.500000000000 -CTYPE2 = 'GLAT-CAR' -CRVAL2 = -90.000000000000 -CRPIX2 = 1 -CDELT2 = 0.500000000000 -COMMENT = +-------------------------------------------------------------+ -COMMENT = | (l,b) map, integrated between -450 km/s < V_lsr < +400 km/s | -COMMENT = | To Convert to N_HI, multiply by 1.8224e18 K km s^-1 cm^-2 | -COMMENT = +-------------------------------------------------------------+ -COMMENT = -COMMENT = +-------------------------------------------------+ -COMMENT = | The Leiden/Dwingeloo Survey of HI in the Galaxy | -COMMENT = | Dap Hartmann & W.B.Burton | -COMMENT = | Leiden Observatory | -COMMENT = | Cambridge University Press 1997 | -END diff --git a/ast/ast_tester/longslit.fits-pc b/ast/ast_tester/longslit.fits-pc deleted file mode 100644 index 2adf05a..0000000 --- a/ast/ast_tester/longslit.fits-pc +++ /dev/null @@ -1,18 +0,0 @@ -NAXIS = 3 -NAXIS1 = 1024 -NAXIS2 = 2048 -NAXIS3 = 1 -CRPIX1 = 1 -CRPIX2 = 1024.5 -CRPIX3 = 1 -CDELT1 = 100.0 / delta lambda = 100 nm -CDELT2 = -0.0005555555 / sigma = 2 arcsec -CDELT3 = 1 -CTYPE1 = 'WAVE ' -CTYPE2 = 'RA---ARC' -CTYPE3 = 'DEC--ARC' -CUNIT1 = 'nm ' -CRVAL1 = 1000.0 / Lambda-ref = 1000 nm -CRVAL2 = 150.000 / RA-ref = 150 deg (10:00:00) -CRVAL3 = -35.0 / Dec-ref = -35:00:00 -LONPOLE = 120.0 / rho = 30 degs diff --git a/ast/ast_tester/longslit.fits-wcs b/ast/ast_tester/longslit.fits-wcs deleted file mode 100644 index cff2ca0..0000000 --- a/ast/ast_tester/longslit.fits-wcs +++ /dev/null @@ -1,22 +0,0 @@ -NAXIS = 3 -NAXIS1 = 1024 -NAXIS2 = 2048 -NAXIS3 = 1 -CRPIX1 = 1.0 / Reference pixel on axis 1 -CRPIX2 = 1024.5 / Reference pixel on axis 2 -CRPIX3 = 1.0 / Reference pixel on axis 3 -CTYPE1 = 'WAVE ' / Type of co-ordinate on axis 1 -CTYPE2 = 'RA---ARC' / Type of co-ordinate on axis 2 -CTYPE3 = 'DEC--ARC' / Type of co-ordinate on axis 3 -CUNIT1 = 'nm ' / Units for axis 1 -CRVAL1 = 1000.0 / Lambda-ref = 1000 nm -CRVAL2 = 150.0 / RA-ref = 150 deg (10:00:00) -CRVAL3 = -35.0 / Dec-ref = -35:00:00 -LONPOLE = 120.0 / rho = 30 degs -CD1_1 = 100.0 / Transformation matrix element -CD2_2 = -5.555555E-4 / Transformation matrix element -CD3_3 = 1.0 / Transformation matrix element -PV2_3 = 120.0 / Projection parameter -RADESYS = 'ICRS ' / Reference frame for RA/DEC values -SPECSYS = 'HELIOCEN' / Standard of rest for spectral axis -VELOSYS = -20038.807 / [m/s] Topo. apparent velocity of rest frame diff --git a/ast/ast_tester/makeplot b/ast/ast_tester/makeplot deleted file mode 100755 index 760fac9..0000000 --- a/ast/ast_tester/makeplot +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/tcsh - -if( "$1" == "" ) then - echo "Usage: makeplot " - echo " (e.g. makeplot serpens)" - exit -endif - -gfortran -fno-second-underscore -w -g -fno-range-check -o plotter plotter.f \ - -I$GITSTAR/include -L$GITSTAR/lib `ast_link -pgp -ems` `pgplot_link` - -set bn = $1 - -set atfile = "${bn}.attr" -if( -e $atfile ) then - set attr1 = `cat $atfile` -else - set attr1 = ' ' -endif - -set atfile = "${bn}.fattr" -if( -e $atfile ) then - set attr2 = `cat $atfile` -else - set attr2 = ' ' -endif - -set boxfile = "${bn}.box" -if( -e $boxfile ) then - set box = `cat $boxfile` -else - set box = ' ' -endif - - -set psfile = "${bn}-new.ps" -echo "plotter $bn.head '$attr1' '$attr2' a.ps $box" -plotter $bn.head "$attr1" "$attr2" a.ps $box - -if( -e $GITSTAR/bin/psmerge ) then - $GITSTAR/bin/psmerge -t300x300 -r90 a.ps > $psfile -else - cp a.ps $psfile -endif - -gv $psfile -orientation=landscape - diff --git a/ast/ast_tester/maketest b/ast/ast_tester/maketest deleted file mode 100755 index 5891121..0000000 --- a/ast/ast_tester/maketest +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/tcsh - -if( "$1" == "" ) then - echo "Usage: maketest " - echo " (e.g. maketest regions)" - exit -endif - -if( ! $?LDFLAGS ) then - setenv LDFLAGS "" -endif - -set a = "test$1" - -echo "Building $a" -if( "$a" == "testplot3d" ) then - gfortran -fno-second-underscore -w -g -fno-range-check $LDFLAGS -o testplot3d testplot3d.f \ - -L$GITSTAR/lib -I$GITSTAR/include \ - `ast_link -ems -pgplot3d` `sla_link` `chr_link` `err_link` - -else if( -e "$a.f" ) then - gfortran -fno-second-underscore -w -g -fno-range-check $LDFLAGS -o $a $a.f -L$GITSTAR/lib -I$GITSTAR/include \ - `ast_link -ems` `chr_link` `err_link` `prm_link` `psx_link` - -else if( -e "$a.c" ) then - gcc -o $a -g $a.c -I.. -DHAVE_CONFIG_H -L$GITSTAR/lib $LDFLAGS `ast_link` - -else - echo "Cannot find $a.f or $a.c" - -endif - -echo "Running $a" -$a - diff --git a/ast/ast_tester/origin.attr b/ast/ast_tester/origin.attr deleted file mode 100644 index 277e359..0000000 --- a/ast/ast_tester/origin.attr +++ /dev/null @@ -1 +0,0 @@ -format(1)=ghms,format(2)=gdm,edge(2)=r,tickall=0,grid=1 diff --git a/ast/ast_tester/origin.box b/ast/ast_tester/origin.box deleted file mode 100644 index 9b5eb80..0000000 --- a/ast/ast_tester/origin.box +++ /dev/null @@ -1 +0,0 @@ -0 0 500 500 diff --git a/ast/ast_tester/origin.head b/ast/ast_tester/origin.head deleted file mode 100644 index 88ea783..0000000 --- a/ast/ast_tester/origin.head +++ /dev/null @@ -1,18 +0,0 @@ -SIMPLE = T / file does conform to FITS standard -BITPIX = 16 / number of bits per data pixel -NAXIS = 2 / number of data axes -NAXIS1 = 500 / length of data axis 1 -NAXIS2 = 500 / length of data axis 2 -EPOCH = 1.977780E+03 / Epoch of observation -RADECSYS= 'ICRS ' / Reference frame for RA/DEC in original file -CRVAL1 = 0.0 / Axis 1 reference value -CRPIX1 = 250 / Axis 1 pixel value -CTYPE1 = 'RA---ARC' / Quantity represented by axis 1 -CRVAL2 = 0.0 / Axis 2 reference value -CRPIX2 = 250 / Axis 2 pixel value -CTYPE2 = 'DEC--ARC' / Quantity represented by axis 2 -CDELT1 = 0.001 / Co-ordinate transformation matrix -CDELT2 = 0.001 / Co-ordinate transformation matrix -EQUINOX = 2.000000E+03 / Julian reference frame equinox - -END diff --git a/ast/ast_tester/plot3d-test1.ast b/ast/ast_tester/plot3d-test1.ast deleted file mode 100644 index 271faf1..0000000 --- a/ast/ast_tester/plot3d-test1.ast +++ /dev/null @@ -1,340 +0,0 @@ - Begin FrameSet # Set of inter-related coordinate systems -# Title = "3-d compound coordinate system" # Title of coordinate system -# Naxes = 3 # Number of coordinate axes -# Domain = "SKY-DSBSPECTRUM" # Coordinate system domain -# Epoch = 2007.3268594222 # Julian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Lbl3 = "Radio velocity (USB)" # Label for axis 3 -# System = "Compound" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Uni3 = "km/s" # Units for axis 3 -# Dir1 = 0 # Plot axis 1 in reverse direction - IsA Frame # Coordinate system description - Nframe = 4 # Number of Frames in FrameSet -# Base = 1 # Index of base Frame - Currnt = 4 # Index of current Frame - Nnode = 5 # Number of nodes in FrameSet - Nod1 = 3 # Frame 1 is associated with node 3 - Nod2 = 4 # Frame 2 is associated with node 4 - Nod3 = 5 # Frame 3 is associated with node 5 - Nod4 = 2 # Frame 4 is associated with node 2 - Lnk2 = 1 # Node 2 is derived from node 1 - Lnk3 = 1 # Node 3 is derived from node 1 - Lnk4 = 1 # Node 4 is derived from node 1 - Lnk5 = 1 # Node 5 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Data grid indices; first pixel at (1,1,1)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Data grid index 1" # Label for axis 1 -# Lbl2 = "Data grid index 2" # Label for axis 2 -# Lbl3 = "Data grid index 3" # Label for axis 3 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 -# Uni3 = "pixel" # Units for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Data grid index 1" # Axis Label - Symbol = "g1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Data grid index 2" # Axis Label - Symbol = "g2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Data grid index 3" # Axis Label - Symbol = "g3" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm2 = # Frame number 2 - Begin Frame # Coordinate system description - Title = "Pixel coordinates; first pixel at (-77.5,-52.5,-820.5)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "PIXEL" # Coordinate system domain -# Lbl1 = "Pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Pixel coordinate 2" # Label for axis 2 -# Lbl3 = "Pixel coordinate 3" # Label for axis 3 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 -# Uni3 = "pixel" # Units for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 1" # Axis Label - Symbol = "p1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 2" # Axis Label - Symbol = "p2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 3" # Axis Label - Symbol = "p3" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm3 = # Frame number 3 - Begin Frame # Coordinate system description - Title = "Axis coordinates; first pixel at (-77.5,-52.5,-820.5)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "AXIS" # Coordinate system domain -# Lbl1 = "Axis 1" # Label for axis 1 -# Lbl2 = "Axis 2" # Label for axis 2 -# Lbl3 = "Axis 3" # Label for axis 3 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 -# Uni3 = "pixel" # Units for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Axis 1" # Axis Label - Symbol = "a1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Axis 2" # Axis Label - Symbol = "a2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Axis 3" # Axis Label - Symbol = "a3" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm4 = # Frame number 4 - Begin CmpFrame # Compound coordinate system description -# Title = "3-d compound coordinate system" # Title of coordinate system -# Naxes = 3 # Number of coordinate axes -# Domain = "SKY-DSBSPECTRUM" # Coordinate system domain -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Lbl3 = "Radio velocity (USB)" # Label for axis 3 -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Uni3 = "km/s" # Units for axis 3 -# Dir1 = 0 # Plot axis 1 in reverse direction - IsA Frame # Coordinate system description - FrameA = # First component Frame - Begin SkyFrame # Description of celestial coordinate system - Naxes = 2 # Number of coordinate axes - Epoch = 2007.3268594222 # Julian epoch of observation - System = "FK5" # Coordinate system type - ObsLat = 0.346026050148997 # Observers geodetic latitude (rads) - ObsLon = -2.71363306946838 # Observers geodetic longitude (rads) - Dut1 = -0.0989801599329792 # UT1-UTC in seconds - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - SRef1 = 4.8432980149123 # Ref. pos. RA 18:30:00.1 - SRef2 = 0.0213067755653197 # Ref. pos. Dec 1:13:15 - End SkyFrame - FrameB = # Second component Frame - Begin DSBSpecFrame # Dual sideband spectral axis - Naxes = 1 # Number of coordinate axes - Epoch = 2007.3268594222 # Julian epoch of observation - System = "VRAD" # Coordinate system type - ObsLat = 0.346026069000144 # Observers geodetic latitude (rads) - ObsLon = -2.71363307300091 # Observers geodetic longitude (rads) - Dut1 = -0.0989801599329792 # UT1-UTC in seconds - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - End Axis - IsA Frame # Coordinate system description - SoR = "LSRK" # Standard of rest - RefRA = 4.84328867428426 # Reference RA (rads, FK5 J2000) - RefDec = 0.0213075607299356 # Reference Dec (rads, FK5 J2000) - RstFrq = 345795989900 # Rest frequency (Hz) - SrcVel = 7000.08172321467 # Source velocity (m/s) - SrcVRF = "LSRK" # Source velocity rest frame - UFreq = "GHz" # Preferred units for frequency - IsA SpecFrame # Description of spectral coordinate system - DSBCen = 345834569302.861 # Central frequency (Hz topo) - IF = -5000001243.89453 # Intermediate frequency (Hz) - SideBn = "USB" # Represents upper sideband - AlSdBn = 1 # Align sidebands? - End DSBSpecFrame - End CmpFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -78.9102040827274 # Shift for axis 1 - Sft2 = -54.3591836988926 # Shift for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = 346188848728.921 # Shift for axis 1 - Scl1 = -488347.122802699 # Scale factor for axis 1 - End WinMap - MapB = # Second component Mapping - Begin SpecMap # Conversion between spectral coordinate systems - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Nspec = 2 # Number of conversion steps - Spec1 = "FRTOVL" # Convert frequency to rel. velocity - Spec1a = 345795989900 # Rest frequency (Hz) - Spec2 = "VLTOVR" # Convert relativistic to radio velocity - End SpecMap - End CmpMap - End CmpMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - M0 = 1.49080827566563e-05 # Forward matrix value - M1 = -3.19704866431787e-05 # Forward matrix value - M2 = -3.19704866431787e-05 # Forward matrix value - M3 = -1.49080827566563e-05 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitude (rad.s) - End SphMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.00278113801100606 # Forward matrix value - M1 = 0.991443912134338 # Forward matrix value - M2 = 0.130503771451718 # Forward matrix value - M3 = -0.021123653434259 # Forward matrix value - M4 = 0.130533402207093 # Forward matrix value - M5 = -0.9912188568494 # Forward matrix value - M6 = -0.999773002504545 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = 0.0213059490060158 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 4.84329594648948 # Polar longitude (rad.s) - End SphMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - MapB = # Second component Mapping - Begin ZoomMap # Zoom about the origin - Nin = 1 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Zoom = 0.001 # Zoom factor - End ZoomMap - End CmpMap - End CmpMap - Map3 = # Mapping between nodes 1 and 3 - Begin UnitMap # Unit (null) Mapping - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - End UnitMap - Map4 = # Mapping between nodes 1 and 4 - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - Sft1 = -78.5 # Shift for axis 1 - Sft2 = -53.5 # Shift for axis 2 - Sft3 = -821.5 # Shift for axis 3 - End WinMap - Map5 = # Mapping between nodes 1 and 5 - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - Sft1 = -78.5 # Shift for axis 1 - Sft2 = -53.5 # Shift for axis 2 - Sft3 = -821.5 # Shift for axis 3 - End WinMap - End FrameSet diff --git a/ast/ast_tester/plotter.f b/ast/ast_tester/plotter.f deleted file mode 100644 index 79bb8e1..0000000 --- a/ast/ast_tester/plotter.f +++ /dev/null @@ -1,230 +0,0 @@ - PROGRAM PLOTTER - -* Usage: -* PLOTTER [ ] - -* Description: -* Plots a standard grid from the specified fits header file, using -* the specified attributes, and sends postscript output to the -* specified ps file. - -* Parameters: -* file file -* A text file containing fits headers. -* attr1 -* A string containg a comma-separated list of attribute -* settings for the Plot. -* attr2 -* A string containg a comma-separated list of attribute -* settings for the FitsChan. -* ps file -* The output postscript file -* xlo ylo xhi yhi -* The bounds within the GRID Frame of the required plot. -* Taken from the FITS headers if not supplied - - - IMPLICIT NONE - INCLUDE 'AST_PAR' - - INTEGER STATUS, FC, FS, NAXIS1, NAXIS2, PL, PGBEG, IARGC, OC - CHARACTER FILE*80, CARD*80, DEVN*80, PSFILE*80, ATTR*255, TEXT*80 - REAL GBOX(4), RANGE, DELTA, ASP - DOUBLE PRECISION PBOX(4) - - STATUS = 0 -* -* Check command line arguments have been supplied. -* - IF( IARGC() .LT. 3 ) THEN - WRITE(*,*) 'Usage: plotter '// - : ' [ ]' - RETURN - END IF - -* -* Use object caching to minimise allocation of new memory -* - OC = AST_TUNE( 'ObjectCaching', 1, STATUS ) - IF( OC .NE. 0 ) THEN - WRITE(*,'(A,I6)') 'Default ObjectCaching VALUE is ',OC - END IF - - IF( AST_TUNE( 'ObjectCaching', AST__TUNULL, STATUS ) .NE. 1 ) THEN - WRITE(*,'(A,I6)') 'Set ObjectCaching VALUE is ',OC - END IF - -* -* Create a FitsChan to store the FITS headers. -* - CALL GETARG( 3, ATTR ) - FC = AST_FITSCHAN( AST_NULL, AST_NULL, ATTR, STATUS ) - -* -* Open a text file containing a list of FITS headers. -* - CALL GETARG( 1, FILE ) - OPEN( UNIT=10, FILE=FILE, STATUS='OLD' ) - -* -* Read each card out of the text file and store it in the FitsChan. -* - DO WHILE( .TRUE. ) - READ( 10, '(A)', END = 10 ) CARD - CALL AST_PUTFITS( FC, CARD, 0, STATUS ) - END DO - - 10 CLOSE( 10 ) - - -* -* If the base frame box was supplied on the command line, use it. -* - IF( IARGC() .GT. 6 ) THEN - CALL GETARG( 5, TEXT ) - READ( TEXT, * ) PBOX( 1 ) - - CALL GETARG( 6, TEXT ) - READ( TEXT, * ) PBOX( 2 ) - - CALL GETARG( 7, TEXT ) - READ( TEXT, * ) PBOX( 3 ) - - CALL GETARG( 8, TEXT ) - READ( TEXT, * ) PBOX( 4 ) - -* Otherwise use NAXISi keywords in the header. - ELSE - -* -* See if values were supplied for NAXIS1 and NAXIS2. If not assume a value -* of 100 for each. The FitsChan is re-wound before calling AST_FINDFITS so -* that the search starts form the beginning. -* - CALL AST_CLEAR( FC, 'CARD', STATUS ) - IF ( AST_FINDFITS( FC, 'NAXIS1', CARD, .TRUE., STATUS ) ) THEN - READ(CARD(11:),*) NAXIS1 - ELSE - NAXIS1 = 100 - END IF - - CALL AST_CLEAR( FC, 'CARD', STATUS ) - IF ( AST_FINDFITS( FC, 'NAXIS2', CARD, .TRUE., STATUS ) ) THEN - READ(CARD(11:),*) NAXIS2 - ELSE - NAXIS2 = 100 - END IF - - PBOX(1) = 0.5 - PBOX(2) = 0.5 - PBOX(3) = DBLE( NAXIS1 )+0.5 - PBOX(4) = DBLE( NAXIS2 )+0.5 - END IF - -* -* Read an Object from the contents of the FitsChan. This should be a -* FrameSet (this should be tested really, and an error reported if any -* other type of Object is obtained). Re-wind the FitsChan first so that -* its entire contents are read. Note, this is a destructive read, in that -* the cards which are significant to the creation of the FrameSet are -* removed from the FitsChan (this is why NAXIS1 and NAXIS2 are read out -* earlier - just in case they are significant to the FrameSet). Any -* insignificant cards are left as they are. -* - CALL AST_CLEAR( FC, 'CARD', STATUS ) - FS = AST_READ( FC, STATUS ) - - IF( FS .EQ. AST__NULL ) THEN - WRITE(*,*) '!!! No object read from FitsChan!!!' - GO TO 999 - END IF - -* -* If all is OK, start up PGPLOT. -* - IF( STATUS .EQ. 0 ) THEN - CALL GETARG( 4, PSFILE ) - CALL DELETEFILE( PSFILE ) - - DEVN = 'pscol_l;'//PSFILE -c IF( PGBEG( 0, '?', 1, 1 ) .EQ. 1 ) THEN - IF( PGBEG( 0, DEVN, 1, 1 ) .EQ. 1 ) THEN - CALL PGPAGE - CALL PGWNAD( 0.0, 1.0, 0.0, 1.0 ) - -* -* Create the Plot. The pixel coordinates box is -* mapped onto a window which is 10% smaller than the full PGPLOT window. -* This gives some space for things like tick marks with negative length -* (which stick outside the pixel cooridnates box). -* - CALL PGQWIN( GBOX(1), GBOX(3), GBOX(2), GBOX(4) ) - - RANGE = GBOX(3) - GBOX(1) - GBOX(1) = GBOX(1) + 0.05*RANGE - GBOX(3) = GBOX(3) - 0.05*RANGE - - RANGE = GBOX(4) - GBOX(2) - GBOX(2) = GBOX(2) + 0.05*RANGE - GBOX(4) = GBOX(4) - 0.05*RANGE - - ASP = REAL( PBOX(4) - PBOX(2) )/REAL( PBOX(3) - PBOX(1) ) - IF( ASP .LT. 0.05 .OR. ASP .GT. 20 ) ASP = 1.0 - - IF( ASP .GT. 1.0 ) THEN - DELTA = 0.5*( ( GBOX(3) - GBOX(1) ) - - : ( GBOX(4) - GBOX(2) )/ASP ) - GBOX(3) = GBOX(3) - DELTA - GBOX(1) = GBOX(1) + DELTA - ELSE - DELTA = 0.5*( ( GBOX(4) - GBOX(2) ) - - : ASP*( GBOX(3) - GBOX(1) ) ) - GBOX(4) = GBOX(4) - DELTA - GBOX(2) = GBOX(2) + DELTA - END IF - - CALL GETARG( 2, ATTR ) - PL = AST_PLOT( FS, GBOX, PBOX, 'title = A FITS test', - : STATUS ) - CALL AST_SET( PL, ATTR, STATUS ) - -* -* Draw the grid. -* - CALL AST_GRID( PL, STATUS ) - -* -* Annul the Plot, and close PGPLOT. -* - CALL AST_ANNUL( PL, STATUS ) - CALL PGEND - END IF - END IF - -* -* Annul the other objects. -* - CALL AST_ANNUL( FS, STATUS ) - 999 CALL AST_ANNUL( FC, STATUS ) - - END - - -* -* Delete a file if it exists. -* - SUBROUTINE DELETEFILE( FILNAM ) - IMPLICIT NONE - - CHARACTER FILNAM*(*) - LOGICAL EXISTS - - INQUIRE ( FILE = FILNAM, - : EXIST = EXISTS ) - - IF( EXISTS ) THEN - OPEN ( UNIT=10, FILE=FILNAM, STATUS='OLD' ) - CLOSE ( 10, STATUS='DELETE' ) - END IF - - END diff --git a/ast/ast_tester/polco.attr b/ast/ast_tester/polco.attr deleted file mode 100644 index c220287..0000000 --- a/ast/ast_tester/polco.attr +++ /dev/null @@ -1 +0,0 @@ -Grid=1,labelling=interior,bottom(1)=0 diff --git a/ast/ast_tester/polco.box b/ast/ast_tester/polco.box deleted file mode 100644 index 0661792..0000000 --- a/ast/ast_tester/polco.box +++ /dev/null @@ -1 +0,0 @@ --300 -300 500 500 diff --git a/ast/ast_tester/polco.head b/ast/ast_tester/polco.head deleted file mode 100644 index d953089..0000000 --- a/ast/ast_tester/polco.head +++ /dev/null @@ -1,86 +0,0 @@ - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST Beginning of AST data for FrameSet object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'FrameSet' / Set of inter-related coordinate systems -NFRAME_A= 2 / Number of Frames in FrameSet -CURRNT_A= 2 / Index of current Frame -NOD1_A = 2 / Frame 1 is associated with node 2 -NOD2_A = 1 / Frame 2 is associated with node 1 -LNK2_A = 1 / Node 2 is derived from node 1 -FRM1_A = ' ' / Frame number 1 -BEGAST_B= 'Frame ' / Coordinate system description -TITLE_A = 'Data grid indices; first pixel at (1&'/ Title of coordinate system -CONTINUE '",1) "' -NAXES_A = 2 / Number of coordinate axes -DOMAIN_A= 'GRID ' / Coordinate system domain -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -LABEL_A = 'Data grid index 1' / Axis Label -SYMBOL_A= 'g1 ' / Axis symbol -UNIT_A = 'pixel ' / Axis units -FORMAT_A= '%3.1f ' / Format specifier -ENDAST_A= 'Axis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_D= 'Axis ' / Coordinate axis -LABEL_B = 'Data grid index 2' / Axis Label -SYMBOL_B= 'g2 ' / Axis symbol -UNIT_B = 'pixel ' / Axis units -FORMAT_B= '%3.1f ' / Format specifier -ENDAST_B= 'Axis ' / End of object definition -ENDAST_C= 'Frame ' / End of object definition -FRM2_A = ' ' / Frame number 2 -BEGAST_E= 'Frame ' / Coordinate system description -TITLE_B = 'Pixel coordinates; first pixel at (-&'/ Title of coordinate system -CONTINUE '100.5,-200.5)' -NAXES_B = 2 / Number of coordinate axes -DOMAIN_B= 'POLAR ' / Coordinate system domain -AX1_B = ' ' / Axis number 1 -BEGAST_F= 'Axis ' / Coordinate axis -LABEL_C = 'Pixel coordinate 1' / Axis Label -SYMBOL_C= 'p1 ' / Axis symbol -UNIT_C = 'pixel ' / Axis units -FORMAT_C= '%3.1f ' / Format specifier -BOTTOM_A= 0.0 / Minimum legal axis value -ENDAST_D= 'Axis ' / End of object definition -AX2_B = ' ' / Axis number 2 -BEGAST_G= 'Axis ' / Coordinate axis -LABEL_D = 'Pixel coordinate 2' / Axis Label -SYMBOL_D= 'p2 ' / Axis symbol -UNIT_D = 'pixel ' / Axis units -FORMAT_D= '%3.1f ' / Format specifier -TOP_A = 3.141592 / Maximum legal axis value -BOTTOM_B= -3.141592 / Minimum legal axis value -ENDAST_E= 'Axis ' / End of object definition -ENDAST_F= 'Frame ' / End of object definition -MAP2_A = ' ' / Mapping between nodes 1 and 2 -BEGAST_H= 'CmpMap ' / Compound Mapping -NIN_A = 2 / Number of input coordinates -ISA_A = 'Mapping ' / Mapping between coordinate systems -INVA_A = 1 / First Mapping used in inverse direction -INVB_A = 1 / Second Mapping used in inverse direction -MAPA_A = ' ' / First component Mapping -BEGAST_I= 'MathMap ' / Transformation using mathematical functions -NIN_B = 2 / Number of input coordinates -INVERT_A= 0 / Mapping not inverted -ISA_B = 'Mapping ' / Mapping between coordinate systems -FWD1_A = 'r=sqrt(x*x+y*y)' / Forward function 1 -FWD2_A = 'theta=atan2(y,x)' / Forward function 2 -INV1_A = 'x=r*cos(theta)' / Inverse function 1 -INV2_A = 'y=r*sin(theta)' / Inverse function 2 -SIMPFI_A= 1 / Forward-inverse pairs may simplify -SIMPIF_A= 1 / Inverse-forward pairs may simplify -ENDAST_G= 'MathMap ' / End of object definition -MAPB_A = ' ' / Second component Mapping -BEGAST_J= 'WinMap ' / Map one window on to another -NIN_C = 2 / Number of input coordinates -INVERT_B= 0 / Mapping not inverted -ISA_C = 'Mapping ' / Mapping between coordinate systems -SFT1_A = -101.5 / Shift for axis 1 -SFT2_A = -201.5 / Shift for axis 2 -ENDAST_H= 'WinMap ' / End of object definition -ENDAST_I= 'CmpMap ' / End of object definition -ENDAST_J= 'FrameSet' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for FrameSet object AST -COMMENT AST ---------------------------------------------------------------- AST diff --git a/ast/ast_tester/polco2.attr b/ast/ast_tester/polco2.attr deleted file mode 100644 index 5019421..0000000 --- a/ast/ast_tester/polco2.attr +++ /dev/null @@ -1 +0,0 @@ -Grid=0,labelling=exterior,gap(1)=50 diff --git a/ast/ast_tester/polco2.box b/ast/ast_tester/polco2.box deleted file mode 100644 index 0661792..0000000 --- a/ast/ast_tester/polco2.box +++ /dev/null @@ -1 +0,0 @@ --300 -300 500 500 diff --git a/ast/ast_tester/polco2.head b/ast/ast_tester/polco2.head deleted file mode 100644 index d953089..0000000 --- a/ast/ast_tester/polco2.head +++ /dev/null @@ -1,86 +0,0 @@ - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST Beginning of AST data for FrameSet object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'FrameSet' / Set of inter-related coordinate systems -NFRAME_A= 2 / Number of Frames in FrameSet -CURRNT_A= 2 / Index of current Frame -NOD1_A = 2 / Frame 1 is associated with node 2 -NOD2_A = 1 / Frame 2 is associated with node 1 -LNK2_A = 1 / Node 2 is derived from node 1 -FRM1_A = ' ' / Frame number 1 -BEGAST_B= 'Frame ' / Coordinate system description -TITLE_A = 'Data grid indices; first pixel at (1&'/ Title of coordinate system -CONTINUE '",1) "' -NAXES_A = 2 / Number of coordinate axes -DOMAIN_A= 'GRID ' / Coordinate system domain -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -LABEL_A = 'Data grid index 1' / Axis Label -SYMBOL_A= 'g1 ' / Axis symbol -UNIT_A = 'pixel ' / Axis units -FORMAT_A= '%3.1f ' / Format specifier -ENDAST_A= 'Axis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_D= 'Axis ' / Coordinate axis -LABEL_B = 'Data grid index 2' / Axis Label -SYMBOL_B= 'g2 ' / Axis symbol -UNIT_B = 'pixel ' / Axis units -FORMAT_B= '%3.1f ' / Format specifier -ENDAST_B= 'Axis ' / End of object definition -ENDAST_C= 'Frame ' / End of object definition -FRM2_A = ' ' / Frame number 2 -BEGAST_E= 'Frame ' / Coordinate system description -TITLE_B = 'Pixel coordinates; first pixel at (-&'/ Title of coordinate system -CONTINUE '100.5,-200.5)' -NAXES_B = 2 / Number of coordinate axes -DOMAIN_B= 'POLAR ' / Coordinate system domain -AX1_B = ' ' / Axis number 1 -BEGAST_F= 'Axis ' / Coordinate axis -LABEL_C = 'Pixel coordinate 1' / Axis Label -SYMBOL_C= 'p1 ' / Axis symbol -UNIT_C = 'pixel ' / Axis units -FORMAT_C= '%3.1f ' / Format specifier -BOTTOM_A= 0.0 / Minimum legal axis value -ENDAST_D= 'Axis ' / End of object definition -AX2_B = ' ' / Axis number 2 -BEGAST_G= 'Axis ' / Coordinate axis -LABEL_D = 'Pixel coordinate 2' / Axis Label -SYMBOL_D= 'p2 ' / Axis symbol -UNIT_D = 'pixel ' / Axis units -FORMAT_D= '%3.1f ' / Format specifier -TOP_A = 3.141592 / Maximum legal axis value -BOTTOM_B= -3.141592 / Minimum legal axis value -ENDAST_E= 'Axis ' / End of object definition -ENDAST_F= 'Frame ' / End of object definition -MAP2_A = ' ' / Mapping between nodes 1 and 2 -BEGAST_H= 'CmpMap ' / Compound Mapping -NIN_A = 2 / Number of input coordinates -ISA_A = 'Mapping ' / Mapping between coordinate systems -INVA_A = 1 / First Mapping used in inverse direction -INVB_A = 1 / Second Mapping used in inverse direction -MAPA_A = ' ' / First component Mapping -BEGAST_I= 'MathMap ' / Transformation using mathematical functions -NIN_B = 2 / Number of input coordinates -INVERT_A= 0 / Mapping not inverted -ISA_B = 'Mapping ' / Mapping between coordinate systems -FWD1_A = 'r=sqrt(x*x+y*y)' / Forward function 1 -FWD2_A = 'theta=atan2(y,x)' / Forward function 2 -INV1_A = 'x=r*cos(theta)' / Inverse function 1 -INV2_A = 'y=r*sin(theta)' / Inverse function 2 -SIMPFI_A= 1 / Forward-inverse pairs may simplify -SIMPIF_A= 1 / Inverse-forward pairs may simplify -ENDAST_G= 'MathMap ' / End of object definition -MAPB_A = ' ' / Second component Mapping -BEGAST_J= 'WinMap ' / Map one window on to another -NIN_C = 2 / Number of input coordinates -INVERT_B= 0 / Mapping not inverted -ISA_C = 'Mapping ' / Mapping between coordinate systems -SFT1_A = -101.5 / Shift for axis 1 -SFT2_A = -201.5 / Shift for axis 2 -ENDAST_H= 'WinMap ' / End of object definition -ENDAST_I= 'CmpMap ' / End of object definition -ENDAST_J= 'FrameSet' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for FrameSet object AST -COMMENT AST ---------------------------------------------------------------- AST diff --git a/ast/ast_tester/regression.current b/ast/ast_tester/regression.current deleted file mode 100644 index 788c2bc..0000000 --- a/ast/ast_tester/regression.current +++ /dev/null @@ -1,7583 +0,0 @@ - Begin FitsChan # I/O channels to FITS files - Card = 1 # Index of current card -# Encod = "NATIVE" # Encoding system -# FitsDg = 15 # No. of digits for floating point values -# DfB1950 = 1 # Default to FK4 B1950 -# CdMat = 0 # Use PC matrix -# CarLin = 0 # Use full FITS-WCS CAR projections -# Iwc = 0 # Do not include an IWC Frame -# Warn = "Tnx Zpx BadCel BadMat BadCTYPE" # Warnings to be reported - Nm1 = "NAXIS" # FITS keyword name - Ty1 = "integer" # FITS keyword data type - Dt1 = 1 # FITS keyword value - Nm2 = "NAXIS1" # FITS keyword name - Ty2 = "integer" # FITS keyword data type - Dt2 = 100 # FITS keyword value - Nm3 = "CTYPE1" # FITS keyword name - Ty3 = "string" # FITS keyword data type - Dt3 = "fred" # FITS keyword value - Nm4 = "CDELT1" # FITS keyword name - Ty4 = "floating point" # FITS keyword data type - Dt4 = 0 # FITS keyword value - Nm5 = "CRPIX1" # FITS keyword name - Ty5 = "integer" # FITS keyword data type - Dt5 = 50 # FITS keyword value - Nm6 = "CUNIT1" # FITS keyword name - Ty6 = "string" # FITS keyword data type - Dt6 = "GHz" # FITS keyword value - Nm7 = " " # FITS keyword name - Ty7 = "comment" # FITS keyword data type - End FitsChan - Begin FrameSet # Set of inter-related coordinate systems -# Title = "IAU (1958) galactic coordinates; zenithal equal area projection" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Epoch = 1950 # Besselian epoch of observation -# Lbl1 = "Galactic longitude" # Label for axis 1 -# Lbl2 = "Galactic latitude" # Label for axis 2 -# System = "GALACTIC" # Coordinate system type -# Uni1 = "degrees" # Units for axis 1 -# Uni2 = "degrees" # Units for axis 2 -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - IsA Frame # Coordinate system description - Nframe = 2 # Number of Frames in FrameSet - Base = 1 # Index of base Frame - Currnt = 2 # Index of current Frame - Lnk2 = 1 # Node 2 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Pixel Coordinates" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Pixel axis 1" # Label for axis 1 -# Lbl2 = "Pixel axis 2" # Label for axis 2 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel axis 1" # Axis Label - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel axis 2" # Axis Label - End Axis - End Frame - Frm2 = # Frame number 2 - Begin SkyFrame # Description of celestial coordinate system - Ident = " " # Permanent Object identification string - IsA Object # AST Object -# Title = "IAU (1958) galactic coordinates; zenithal equal area projection" # Title of coordinate system - Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain - Epoch = 1950 # Besselian epoch of observation -# Lbl1 = "Galactic longitude" # Label for axis 1 -# Lbl2 = "Galactic latitude" # Label for axis 2 - System = "GALACTIC" # Coordinate system type -# Uni1 = "degrees" # Units for axis 1 -# Uni2 = "degrees" # Units for axis 2 -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - Proj = "zenithal equal area" # Description of sky projection - SRefIs = "Ignored" # Not rotated (ref. pos. is ignored) - SRef1 = -2.61046557479594 # Ref. pos. l -149.5687 - SRef2 = -0.344845661720836 # Ref. pos. b -19.7582 - End SkyFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -150.5 # Shift for axis 1 - Sft2 = -150.5 # Shift for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -0.020943951023932 # Forward matrix value - M1 = 0.020943951023932 # Forward matrix value - Form = "Diagonal" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "ZEA" # Zenithal equal area projection - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitude (rad.s) - End SphMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.291480364581799 # Forward matrix value - M1 = 0.506505471460186 # AST version 4.2- 1 -PutCards Ncards = 7 -PutCards Card = 1 -PutCards Card = 8 -PutCards Ncards = 7 -PutCards Card = 1 - - - - - FITS test number 1 - ==================== - - - -AST_SHOW: - -REG_SINK: -SIMPLE = T / Written by IDL: 30-Jul-1997 05:35:42.00 -BITPIX = -32 / Bits per pixel. -NAXIS = 2 / Number of dimensions -NAXIS1 = 300 / Length of x axis. -NAXIS2 = 300 / Length of y axis. -COMMENT -COMMENT This file was produced by the SkyView survey analysis system from -COMMENT available astronomical surveys. The data are formatted -COMMENT as a simple two-dimensional FITS image with the same units as -COMMENT the orginal survey. A single ASCII table extension may be present -COMMENT which describes catalog objects found within the field of view. -COMMENT Copies of relevant copyright notices are included in this file. -COMMENT -COMMENT Questions should be directed to: -COMMENT -COMMENT scollick@skyview.gsfc.nasa.gov -COMMENT or -COMMENT mcglynn@grossc.gsfc.nasa.gov -COMMENT -COMMENT SkyView -COMMENT Code 668.1 -COMMENT Goddard Space Flight Center, Greenbelt, MD 20771 -COMMENT 301-286-7780 -COMMENT -COMMENT SkyView is supported by NASA ADP grant NAS 5-32068. -COMMENT -SURVEY = 'COBE DIRBE' -BUNITS = 'MJy/sr ' -ORIGIN = 'CDAC ' / Cosmology Data Analysis Center -TELESCOP= 'COBE ' / COsmic Background Explorer satellite -INSTRUME= 'DIRBE ' / COBE instrument [DIRBE, DMR, FIRAS] -PIXRESOL= 9 / Quad tree pixel resolution [6, 9] -DATE = '27/09/94' / FITS file creation date (dd/mm/yy) -DATE-MAP= '16/09/94' / Date of original file creation (dd/mm/yy) -COMMENT COBE specific keywords -DATE-BEG= '08/12/89' / date of initial data represented (dd/mm/yy) -DATE-END= '25/09/90' / date of final data represented (dd/mm/yy) -COMMENT -COMMENT THE COBE DIRBE map is a combination of the original ten -COMMENT band passes with the following wavelengths: -COMMENT Band 1 - 1.25 microns -COMMENT Band 2 - 2.2 microns -COMMENT Band 3 - 3.5 microns -COMMENT Band 4 - 4.9 microns -COMMENT Band 5 - 12 microns -COMMENT Band 6 - 25 microns -COMMENT Band 7 - 60 microns -COMMENT Band 8 - 100 microns -COMMENT Band 9 - 140 microns -COMMENT Band 10 - 240 microns -COMMENT - -Objects written: 1 - -Native Encoding: - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST WCS information in AST format AST -COMMENT AST See http://www.starlink.ac.uk/ast/ AST -COMMENT AST Beginning of AST data for FrameSet object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'FrameSet' / Set of inter-related coordinate systems -NFRAME_A= 2 / Number of Frames in FrameSet -BASE_A = 1 / Index of base Frame -CURRNT_A= 2 / Index of current Frame -LNK2_A = 1 / Node 2 is derived from node 1 -FRM1_A = ' ' / Frame number 1 -BEGAST_B= 'Frame ' / Coordinate system description -TITLE_A = 'Pixel Coordinates' / Title of coordinate system -NAXES_A = 2 / Number of coordinate axes -DOMAIN_A= 'GRID ' / Coordinate system domain -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -LABEL_A = 'Pixel axis 1' / Axis Label -ENDAST_A= 'Axis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_D= 'Axis ' / Coordinate axis -LABEL_B = 'Pixel axis 2' / Axis Label -ENDAST_B= 'Axis ' / End of object definition -ENDAST_C= 'Frame ' / End of object definition -FRM2_A = ' ' / Frame number 2 -BEGAST_E= 'SkyFrame' / Description of celestial coordinate system -IDENT_A = '" " ' / Permanent Object identification string -ISA_A = 'Object ' / AST Object -NAXES_B = 2 / Number of coordinate axes -EPOCH_A = 1950.0 / Besselian epoch of observation -SYSTEM_A= 'GALACTIC' / Coordinate system type -AX1_B = ' ' / Axis number 1 -BEGAST_F= 'SkyAxis ' / Celestial coordinate axis -ENDAST_D= 'SkyAxis ' / End of object definition -AX2_B = ' ' / Axis number 2 -BEGAST_G= 'SkyAxis ' / Celestial coordinate axis -ENDAST_E= 'SkyAxis ' / End of object definition -ISA_B = 'Frame ' / Coordinate system description -PROJ_A = 'zenithal equal area'/ Description of sky projection -SREFIS_A= 'Ignored ' / Not rotated (ref. pos. is ignored) -SREF1_A = -2.61046557479594 / Ref. pos. l -149.5687 -SREF2_A = -0.344845661720836 / Ref. pos. b -19.7582 -ENDAST_F= 'SkyFrame' / End of object definition -MAP2_A = ' ' / Mapping between nodes 1 and 2 -BEGAST_H= 'CmpMap ' / Compound Mapping -NIN_A = 2 / Number of input coordinates -ISSIMP_A= 1 / Mapping has been simplified -ISA_C = 'Mapping ' / Mapping between coordinate systems -MAPA_A = ' ' / First component Mapping -BEGAST_I= 'WinMap ' / Map one window on to another -NIN_B = 2 / Number of input coordinates -INVERT_A= 0 / Mapping not inverted -ISA_D = 'Mapping ' / Mapping between coordinate systems -SFT1_A = -150.5 / Shift for axis 1 -SFT2_A = -150.5 / Shift for axis 2 -ENDAST_G= 'WinMap ' / End of object definition -MAPB_A = ' ' / Second component Mapping -BEGAST_J= 'CmpMap ' / Compound Mapping -NIN_C = 2 / Number of input coordinates -ISA_E = 'Mapping ' / Mapping between coordinate systems -MAPA_B = ' ' / First component Mapping -BEGAST_K= 'MatrixMap' / Matrix transformation -NIN_D = 2 / Number of input coordinates -INVERT_B= 0 / Mapping not inverted -ISA_F = 'Mapping ' / Mapping between coordinate systems -M0_A = -0.020943951023932 / Forward matrix value -M1_A = 0.020943951023932 / Forward matrix value -FORM_A = 'Diagonal' / Matrix storage form -ENDAST_H= 'MatrixMap' / End of object definition -MAPB_B = ' ' / Second component Mapping -BEGAST_L= 'CmpMap ' / Compound Mapping -NIN_E = 2 / Number of input coordinates -ISA_G = 'Mapping ' / Mapping between coordinate systems -INVA_A = 1 / First Mapping used in inverse direction -MAPA_C = ' ' / First component Mapping -BEGAST_M= 'WcsMap ' / FITS-WCS sky projection -NIN_F = 2 / Number of input coordinates -INVERT_C= 1 / Mapping inverted -ISA_H = 'Mapping ' / Mapping between coordinate systems -TYPE_A = 'ZEA ' / Zenithal equal area projection -ENDAST_I= 'WcsMap ' / End of object definition -MAPB_C = ' ' / Second component Mapping -BEGAST_N= 'CmpMap ' / Compound Mapping -NIN_G = 2 / Number of input coordinates -ISA_I = 'Mapping ' / Mapping between coordinate systems -INVA_B = 1 / First Mapping used in inverse direction -MAPA_D = ' ' / First component Mapping -BEGAST_O= 'SphMap ' / Cartesian to Spherical mapping -NIN_H = 3 / Number of input coordinates -NOUT_A = 2 / Number of output coordinates -INVERT_D= 1 / Mapping inverted -ISA_J = 'Mapping ' / Mapping between coordinate systems -UNTRD_A = 1 / All input vectors have unit length -PLRLG_A = 0.0 / Polar longitude (rad.s) -ENDAST_J= 'SphMap ' / End of object definition -MAPB_D = ' ' / Second component Mapping -BEGAST_P= 'CmpMap ' / Compound Mapping -NIN_I = 3 / Number of input coordinates -NOUT_B = 2 / Number of output coordinates -ISA_K = 'Mapping ' / Mapping between coordinate systems -MAPA_E = ' ' / First component Mapping -BEGAST_Q= 'MatrixMap' / Matrix transformation -NIN_J = 3 / Number of input coordinates -INVERT_E= 0 / Mapping not inverted -ISA_L = 'Mapping ' / Mapping between coordinate systems -M0_B = 0.291480364581799 / Forward matrix value -M1_B = 0.506505471460186 / Forward matrix value -M2_A = -0.811474832908671 / Forward matrix value -M3_A = 0.171224898552328 / Forward matrix value -M4_A = -0.862236746712233 / Forward matrix value -M5_A = -0.476686298035564 / Forward matrix value -M6_A = -0.941127638091139 / Forward matrix value -M7_A = 0.0 / Forward matrix value -M8_A = -0.338051429254475 / Forward matrix value -FORM_B = 'Full ' / Matrix storage form -ENDAST_K= 'MatrixMap' / End of object definition -MAPB_E = ' ' / Second component Mapping -BEGAST_R= 'SphMap ' / Cartesian to Spherical mapping -NIN_K = 3 / Number of input coordinates -NOUT_C = 2 / Number of output coordinates -INVERT_F= 0 / Mapping not inverted -ISA_M = 'Mapping ' / Mapping between coordinate systems -UNTRD_B = 1 / All input vectors have unit length -PLRLG_B = -2.61046557479594 / Polar longitude (rad.s) -ENDAST_L= 'SphMap ' / End of object definition -ENDAST_M= 'CmpMap ' / End of object definition -ENDAST_N= 'CmpMap ' / End of object definition -ENDAST_O= 'CmpMap ' / End of object definition -ENDAST_P= 'CmpMap ' / End of object definition -ENDAST_Q= 'CmpMap ' / End of object definition -ENDAST_R= 'FrameSet' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for FrameSet object AST -COMMENT AST ---------------------------------------------------------------- AST - -ATTRIBUTES: - Colour(axis1) : 1 - Font(Stri) : 1 - Nout : 1 - Class : 4 - Tol : 0.100000E-01 - Gap(1) : 1.04720 - Border : 0 - Invert : 0 - TextLabGap : 0.100000E-01 - Nin : 2 - Current : 3 - Base : 1 - Nobject : 1 - RefCOUNT : 1 - -AST_GRID: -REG_LINE: 15 - 25.4 -29.7 - 20.1 -16.6 - 15.4 -2.03 - 11.5 13.7 - 8.35 30.3 - 5.92 47.5 - 4.25 65.0 - 3.39 82.6 - 3.35 100. - 4.19 117. - 5.99 133. - 8.83 149. - 12.9 163. - 18.3 175. - 25.4 185. -REG_LINE: 119 - 25.4 -29.7 - 24.6 -29.7 - 23.8 -29.7 - 22.9 -29.6 - 22.1 -29.5 - 21.3 -29.5 - 20.4 -29.3 - 19.6 -29.2 - 18.8 -29.0 - 17.9 -28.9 - 17.1 -28.7 - 16.3 -28.5 - 15.5 -28.2 - 14.6 -28.0 - 13.8 -27.7 - 13.0 -27.4 - 12.2 -27.1 - 11.4 -26.7 - 10.6 -26.4 - 9.74 -26.0 - 8.93 -25.6 - 8.12 -25.2 - 7.32 -24.8 - 6.52 -24.3 - 5.73 -23.9 - 4.93 -23.4 - 4.14 -22.9 - 3.35 -22.3 - 2.57 -21.8 - 1.79 -21.2 - 1.02 -20.6 - .247 -20.0 - -.520 -19.4 - -1.28 -18.8 - -2.04 -18.1 - -2.79 -17.4 - -3.54 -16.7 - -4.29 -16.0 - -5.02 -15.3 - -5.76 -14.5 - -6.49 -13.7 - -7.21 -12.9 - -7.92 -12.1 - -17.3 1.12 - -25.1 17.7 - -31.1 37.2 - -34.6 59.1 - -35.4 82.8 - -33.1 107. - -32.8 109. - -32.5 111. - -32.2 112. - -31.9 114. - -31.5 116. - -31.1 117. - -30.7 119. - -30.3 121. - -29.9 123. - -29.4 124. - -28.9 126. - -28.5 128. - -27.9 129. - -27.4 131. - -26.9 132. - -26.3 134. - -25.7 136. - -25.2 137. - -24.5 139. - -23.9 140. - -23.3 142. - -22.6 143. - -21.9 145. - -21.2 146. - -20.5 148. - -19.8 149. - -19.0 151. - -18.2 152. - -17.5 154. - -16.7 155. - -15.8 156. - -15.0 158. - -14.2 159. - -13.3 160. - -12.4 162. - -11.5 163. - -10.6 164. - -9.69 165. - -8.75 166. - -7.80 167. - -6.83 168. - -5.85 170. - -4.86 171. - -3.85 172. - -2.83 172. - -1.80 173. - -.761 174. - .293 175. - 1.36 176. - 2.43 177. - 3.52 178. - 4.61 178. - 5.72 179. - 6.83 180. - 7.95 180. - 9.08 181. - 10.2 181. - 11.4 182. - 12.5 182. - 13.7 183. - 14.8 183. - 16.0 184. - 17.2 184. - 18.3 184. - 19.5 184. - 20.7 185. - 21.9 185. - 23.1 185. - 24.3 185. - 25.4 185. -REG_LINE: 171 - 25.4 -29.7 - 19.1 -40.9 - 11.9 -49.9 - 11.3 -50.4 - 10.8 -50.9 - 10.2 -51.4 - 9.62 -51.9 - 9.04 -52.4 - 8.46 -52.8 - 7.87 -53.3 - 7.28 -53.7 - 6.68 -54.1 - 6.07 -54.5 - 5.46 -54.9 - 4.84 -55.2 - 4.21 -55.6 - 3.58 -55.9 - 2.95 -56.2 - 2.30 -56.5 - 1.65 -56.7 - .990 -56.9 - .325 -57.2 - -.348 -57.3 - -1.03 -57.5 - -1.71 -57.7 - -2.41 -57.8 - -3.11 -57.9 - -3.82 -57.9 - -4.54 -58.0 - -5.27 -58.0 - -6.00 -58.0 - -6.74 -58.0 - -7.50 -57.9 - -8.26 -57.8 - -9.03 -57.7 - -9.80 -57.5 - -10.6 -57.3 - -11.4 -57.1 - -12.2 -56.8 - -13.0 -56.5 - -13.8 -56.2 - -14.7 -55.8 - -15.5 -55.4 - -16.4 -55.0 - -17.2 -54.5 - -18.1 -53.9 - -19.0 -53.4 - -19.9 -52.7 - -20.8 -52.0 - -21.7 -51.3 - -22.6 -50.5 - -23.6 -49.7 - -24.5 -48.8 - -25.5 -47.8 - -26.4 -46.8 - -27.4 -45.7 - -28.4 -44.5 - -29.4 -43.3 - -30.4 -42.0 - -31.4 -40.6 - -32.4 -39.1 - -33.5 -37.6 - -34.5 -36.0 - -35.5 -34.3 - -36.6 -32.5 - -37.6 -30.5 - -38.7 -28.5 - -39.7 -26.4 - -40.8 -24.2 - -41.8 -21.9 - -42.8 -19.5 - -43.9 -16.9 - -44.9 -14.2 - -45.9 -11.4 - -46.9 -8.53 - -47.8 -5.48 - -48.8 -2.30 - -49.7 1.01 - -50.6 4.45 - -51.4 8.02 - -52.2 11.7 - -53.0 15.6 - -53.7 19.5 - -54.4 23.6 - -55.0 27.8 - -55.5 32.2 - -56.0 36.6 - -56.4 41.1 - -56.7 45.8 - -56.9 50.5 - -57.1 55.3 - -57.1 60.1 - -57.1 65.1 - -56.9 70.0 - -56.7 74.9 - -56.4 79.9 - -55.9 84.9 - -55.4 89.8 - -54.8 94.7 - -54.1 99.5 - -53.3 104. - -52.4 109. - -51.4 114. - -50.3 118. - -49.2 122. - -48.0 127. - -46.7 131. - -45.4 135. - -44.1 138. - -42.7 142. - -41.2 146. - -39.8 149. - -38.3 152. - -36.8 155. - -35.2 158. - -33.7 161. - -32.2 164. - -30.6 166. - -29.1 168. - -27.5 171. - -26.0 173. - -24.5 175. - -23.0 176. - -21.5 178. - -20.0 180. - -18.5 181. - -17.1 182. - -15.7 184. - -14.3 185. - -12.9 186. - -11.5 187. - -10.2 188. - -8.92 188. - -7.64 189. - -6.38 190. - -5.15 190. - -3.94 191. - -2.75 191. - -1.59 192. - -.448 192. - .669 193. - 1.76 193. - 2.83 193. - 3.88 193. - 4.91 193. - 5.92 193. - 6.91 193. - 7.88 193. - 8.82 193. - 9.75 193. - 10.7 193. - 11.6 193. - 12.4 193. - 13.3 192. - 14.1 192. - 14.9 192. - 15.7 192. - 16.5 191. - 17.3 191. - 18.1 190. - 18.8 190. - 19.5 190. - 20.2 189. - 20.9 189. - 21.6 188. - 22.3 188. - 22.9 187. - 23.6 187. - 24.2 186. - 24.8 185. - 25.4 185. -REG_LINE: 171 - 25.4 -29.7 - 31.6 -41.1 - 38.7 -50.2 - 39.2 -50.7 - 39.8 -51.2 - 40.3 -51.8 - 40.9 -52.3 - 41.5 -52.8 - 42.0 -53.2 - 42.6 -53.7 - 43.2 -54.1 - 43.8 -54.6 - 44.4 -55.0 - 45.0 -55.4 - 45.6 -55.7 - 46.2 -56.1 - 46.8 -56.4 - 47.4 -56.7 - 48.1 -57.0 - 48.7 -57.3 - 49.4 -57.6 - 50.0 -57.8 - 50.7 -58.0 - 51.3 -58.2 - 52.0 -58.4 - 52.7 -58.5 - 53.4 -58.6 - 54.1 -58.7 - 54.8 -58.8 - 55.5 -58.8 - 56.2 -58.9 - 57.0 -58.8 - 57.7 -58.8 - 58.5 -58.7 - 59.2 -58.6 - 60.0 -58.5 - 60.8 -58.3 - 61.6 -58.2 - 62.4 -57.9 - 63.2 -57.7 - 64.0 -57.4 - 64.8 -57.0 - 65.6 -56.6 - 66.5 -56.2 - 67.3 -55.8 - 68.2 -55.2 - 69.1 -54.7 - 70.0 -54.1 - 70.9 -53.4 - 71.8 -52.7 - 72.7 -52.0 - 73.7 -51.2 - 74.6 -50.3 - 75.6 -49.4 - 76.6 -48.4 - 77.5 -47.3 - 78.5 -46.2 - 79.5 -45.0 - 80.5 -43.7 - 81.6 -42.4 - 82.6 -41.0 - 83.6 -39.5 - 84.7 -37.9 - 85.7 -36.2 - 86.8 -34.4 - 87.8 -32.5 - 88.9 -30.5 - 90.0 -28.5 - 91.1 -26.3 - 92.1 -23.9 - 93.2 -21.5 - 94.2 -19.0 - 95.3 -16.3 - 96.3 -13.5 - 97.3 -10.6 - 98.4 -7.51 - 99.3 -4.31 - 100. -.976 - 101. 2.50 - 102. 6.12 - 103. 9.88 - 104. 13.8 - 105. 17.8 - 105. 22.0 - 106. 26.3 - 106. 30.7 - 107. 35.2 - 107. 39.9 - 108. 44.7 - 108. 49.5 - 108. 54.4 - 108. 59.4 - 108. 64.5 - 108. 69.5 - 108. 74.6 - 107. 79.7 - 107. 84.8 - 106. 89.9 - 106. 94.9 - 105. 99.9 - 104. 105. - 103. 110. - 102. 114. - 101. 119. - 100. 123. - 98.8 128. - 97.5 132. - 96.1 136. - 94.7 140. - 93.3 143. - 91.8 147. - 90.3 150. - 88.8 154. - 87.2 157. - 85.7 159. - 84.1 162. - 82.5 165. - 80.9 167. - 79.4 170. - 77.8 172. - 76.3 174. - 74.7 176. - 73.2 177. - 71.7 179. - 70.2 181. - 68.8 182. - 67.3 183. - 65.9 185. - 64.5 186. - 63.2 187. - 61.8 188. - 60.5 188. - 59.2 189. - 57.9 190. - 56.7 191. - 55.5 191. - 54.3 192. - 53.1 192. - 51.9 192. - 50.8 193. - 49.7 193. - 48.6 193. - 47.6 193. - 46.5 193. - 45.5 194. - 44.5 194. - 43.6 194. - 42.6 194. - 41.7 193. - 40.8 193. - 39.9 193. - 39.0 193. - 38.2 193. - 37.3 193. - 36.5 192. - 35.7 192. - 34.9 192. - 34.2 191. - 33.4 191. - 32.7 191. - 31.9 190. - 31.2 190. - 30.5 189. - 29.8 189. - 29.2 188. - 28.5 188. - 27.9 187. - 27.3 187. - 26.6 186. - 26.0 185. - 25.4 185. -REG_LINE: 119 - 25.4 -29.7 - 26.3 -29.7 - 27.1 -29.7 - 28.0 -29.7 - 28.8 -29.6 - 29.6 -29.5 - 30.5 -29.4 - 31.3 -29.3 - 32.1 -29.2 - 33.0 -29.0 - 33.8 -28.8 - 34.6 -28.6 - 35.4 -28.4 - 36.3 -28.2 - 37.1 -27.9 - 37.9 -27.6 - 38.7 -27.3 - 39.5 -27.0 - 40.4 -26.7 - 41.2 -26.3 - 42.0 -25.9 - 42.8 -25.5 - 43.6 -25.1 - 44.4 -24.7 - 45.2 -24.2 - 46.0 -23.7 - 46.8 -23.2 - 47.6 -22.7 - 48.4 -22.2 - 49.2 -21.6 - 49.9 -21.1 - 50.7 -20.5 - 51.5 -19.8 - 52.2 -19.2 - 53.0 -18.6 - 53.8 -17.9 - 54.5 -17.2 - 55.3 -16.5 - 56.0 -15.8 - 56.8 -15.0 - 57.5 -14.3 - 58.2 -13.5 - 58.9 -12.7 - 68.4 .462 - 76.3 17.0 - 82.3 36.5 - 85.9 58.6 - 86.8 82.4 - 84.5 107. - 84.2 109. - 83.9 110. - 83.5 112. - 83.2 114. - 82.8 116. - 82.4 117. - 82.0 119. - 81.6 121. - 81.2 122. - 80.7 124. - 80.2 126. - 79.7 128. - 79.2 129. - 78.7 131. - 78.1 132. - 77.6 134. - 77.0 136. - 76.4 137. - 75.8 139. - 75.1 140. - 74.5 142. - 73.8 144. - 73.1 145. - 72.4 147. - 71.7 148. - 70.9 150. - 70.2 151. - 69.4 152. - 68.6 154. - 67.8 155. - 67.0 157. - 66.1 158. - 65.3 159. - 64.4 160. - 63.5 162. - 62.6 163. - 61.7 164. - 60.8 165. - 59.8 166. - 58.8 168. - 57.9 169. - 56.9 170. - 55.9 171. - 54.9 172. - 53.8 173. - 52.8 174. - 51.8 175. - 50.7 175. - 49.6 176. - 48.5 177. - 47.4 178. - 46.3 178. - 45.2 179. - 44.1 180. - 43.0 180. - 41.8 181. - 40.7 182. - 39.6 182. - 38.4 182. - 37.2 183. - 36.1 183. - 34.9 184. - 33.7 184. - 32.6 184. - 31.4 184. - 30.2 185. - 29.0 185. - 27.8 185. - 26.6 185. - 25.4 185. -REG_LINE: 15 - 25.4 -29.7 - 31.0 -16.7 - 35.7 -2.18 - 39.8 13.5 - 43.0 30.1 - 45.5 47.3 - 47.2 64.8 - 48.1 82.5 - 48.2 99.9 - 47.3 117. - 45.5 133. - 42.5 149. - 38.4 163. - 32.8 175. - 25.4 185. -REG_LINE: 197 - 37.2 2.94 - 36.4 3.34 - 35.6 3.71 - 34.8 4.05 - 34.0 4.37 - 33.2 4.65 - 32.3 4.90 - 31.5 5.13 - 30.7 5.32 - 29.8 5.49 - 29.0 5.63 - 28.2 5.74 - 27.3 5.82 - 26.5 5.87 - 25.6 5.89 - 24.8 5.88 - 23.9 5.84 - 23.1 5.77 - 22.2 5.68 - 21.4 5.55 - 20.5 5.40 - 19.7 5.21 - 18.9 5.00 - 18.1 4.75 - 17.2 4.48 - 16.4 4.18 - 15.6 3.85 - 14.8 3.49 - 14.0 3.10 - 13.3 2.69 - 12.5 2.24 - 11.8 1.77 - 11.0 1.26 - 10.3 .730 - 9.57 .169 - 8.87 -.420 - 8.18 -1.04 - 7.51 -1.68 - 6.86 -2.36 - 6.23 -3.06 - 5.61 -3.79 - 5.02 -4.55 - 4.44 -5.33 - 3.89 -6.14 - 3.35 -6.98 - 2.84 -7.84 - 2.36 -8.73 - 1.89 -9.65 - 1.46 -10.6 - 1.04 -11.6 - .660 -12.5 - .304 -13.6 - -0.240E-01 -14.6 - -.322 -15.7 - -.589 -16.7 - -.825 -17.8 - -1.03 -19.0 - -1.20 -20.1 - -1.34 -21.3 - -1.44 -22.5 - -1.50 -23.6 - -1.53 -24.9 - -1.52 -26.1 - -1.48 -27.3 - -1.39 -28.6 - -1.26 -29.8 - -1.10 -31.1 - -.889 -32.3 - -.640 -33.6 - -.348 -34.9 - -0.127E-01 -36.1 - .365 -37.4 - .787 -38.7 - 1.25 -39.9 - 1.76 -41.2 - 2.32 -42.4 - 2.92 -43.6 - 3.56 -44.8 - 4.24 -45.9 - 4.97 -47.1 - 5.74 -48.2 - 6.56 -49.2 - 7.41 -50.3 - 8.30 -51.3 - 9.23 -52.2 - 10.2 -53.1 - 11.2 -54.0 - 12.2 -54.8 - 13.3 -55.5 - 14.4 -56.2 - 15.5 -56.8 - 16.7 -57.4 - 17.9 -57.9 - 19.1 -58.3 - 20.3 -58.7 - 21.5 -58.9 - 22.7 -59.1 - 24.0 -59.3 - 25.2 -59.3 - 26.4 -59.3 - 27.7 -59.2 - 28.9 -59.0 - 30.1 -58.8 - 31.4 -58.5 - 32.6 -58.1 - 33.7 -57.6 - 34.9 -57.1 - 36.0 -56.5 - 37.1 -55.8 - 38.2 -55.1 - 39.3 -54.3 - 40.3 -53.5 - 41.3 -52.6 - 42.2 -51.7 - 43.1 -50.7 - 44.0 -49.7 - 44.8 -48.6 - 45.6 -47.5 - 46.4 -46.4 - 47.1 -45.2 - 47.7 -44.1 - 48.3 -42.9 - 48.9 -41.7 - 49.4 -40.4 - 49.9 -39.2 - 50.4 -37.9 - 50.8 -36.7 - 51.1 -35.4 - 51.4 -34.1 - 51.7 -32.8 - 51.9 -31.6 - 52.1 -30.3 - 52.2 -29.1 - 52.3 -27.8 - 52.4 -26.6 - 52.4 -25.3 - 52.4 -24.1 - 52.4 -22.9 - 52.3 -21.7 - 52.2 -20.6 - 52.0 -19.4 - 51.8 -18.3 - 51.6 -17.2 - 51.3 -16.1 - 51.0 -15.0 - 50.7 -14.0 - 50.4 -13.0 - 50.0 -12.0 - 49.6 -11.0 - 49.2 -10.0 - 48.7 -9.10 - 48.2 -8.20 - 47.7 -7.32 - 47.2 -6.48 - 46.7 -5.65 - 46.1 -4.86 - 45.5 -4.09 - 44.9 -3.35 - 44.3 -2.64 - 43.6 -1.95 - 43.0 -1.29 - 42.3 -.665 - 41.6 -0.645E-01 - 40.9 .508 - 40.2 1.05 - 39.4 1.57 - 38.7 2.05 - 37.9 2.51 - 37.2 2.94 - 36.4 3.34 - 35.6 3.71 - 34.8 4.05 - 34.0 4.37 - 33.2 4.65 - 32.3 4.90 - 31.5 5.13 - 30.7 5.32 - 29.8 5.49 - 29.0 5.63 - 28.2 5.74 - 27.3 5.82 - 26.5 5.87 - 25.6 5.89 - 24.8 5.88 - 23.9 5.84 - 23.1 5.77 - 22.2 5.68 - 21.4 5.55 - 20.5 5.40 - 19.7 5.21 - 18.9 5.00 - 18.1 4.75 - 17.2 4.48 - 16.4 4.18 - 15.6 3.85 - 14.8 3.49 - 14.0 3.10 -REG_LINE: 197 - 44.8 41.5 - 43.5 42.0 - 42.1 42.5 - 40.8 42.9 - 39.5 43.3 - 38.1 43.6 - 36.7 43.9 - 35.4 44.2 - 34.0 44.4 - 32.6 44.6 - 31.3 44.8 - 29.9 44.9 - 28.5 45.0 - 27.1 45.1 - 25.7 45.1 - 24.3 45.1 - 23.0 45.1 - 21.6 45.0 - 20.2 44.9 - 18.8 44.7 - 17.4 44.5 - 16.1 44.3 - 14.7 44.0 - 13.3 43.7 - 12.0 43.4 - 10.6 43.0 - 9.29 42.6 - 7.96 42.2 - 6.65 41.7 - 5.34 41.2 - 4.04 40.6 - 2.75 40.0 - 1.48 39.4 - .220 38.8 - -1.02 38.0 - -2.25 37.3 - -3.47 36.5 - -4.66 35.7 - -5.84 34.8 - -7.00 33.9 - -8.14 33.0 - -9.25 32.0 - -10.3 31.0 - -11.4 29.9 - -12.5 28.8 - -13.5 27.6 - -14.5 26.4 - -15.5 25.2 - -16.4 23.9 - -17.3 22.5 - -18.2 21.2 - -19.0 19.7 - -19.8 18.2 - -20.6 16.7 - -21.4 15.1 - -22.1 13.5 - -22.7 11.8 - -23.3 10.1 - -23.9 8.29 - -24.4 6.45 - -24.9 4.55 - -25.3 2.59 - -25.7 .576 - -26.0 -1.49 - -26.3 -3.62 - -26.5 -5.81 - -26.6 -8.05 - -26.7 -10.4 - -26.7 -12.7 - -26.6 -15.1 - -26.4 -17.6 - -26.2 -20.2 - -25.8 -22.7 - -25.4 -25.4 - -24.9 -28.1 - -24.3 -30.8 - -23.5 -33.6 - -22.7 -36.4 - -21.7 -39.3 - -20.7 -42.1 - -19.5 -45.0 - -18.1 -47.9 - -16.6 -50.8 - -15.0 -53.6 - -13.3 -56.4 - -11.4 -59.2 - -9.34 -61.9 - -7.15 -64.5 - -4.82 -67.0 - -2.34 -69.3 - .268 -71.5 - 3.01 -73.5 - 5.87 -75.3 - 8.84 -76.9 - 11.9 -78.3 - 15.1 -79.3 - 18.3 -80.1 - 21.5 -80.6 - 24.8 -80.9 - 28.1 -80.8 - 31.3 -80.4 - 34.6 -79.7 - 37.7 -78.7 - 40.8 -77.5 - 43.8 -76.0 - 46.7 -74.3 - 49.5 -72.4 - 52.2 -70.2 - 54.7 -67.9 - 57.1 -65.5 - 59.4 -63.0 - 61.5 -60.3 - 63.4 -57.6 - 65.2 -54.8 - 66.9 -51.9 - 68.4 -49.1 - 69.8 -46.2 - 71.1 -43.3 - 72.2 -40.4 - 73.2 -37.6 - 74.1 -34.7 - 74.9 -31.9 - 75.5 -29.2 - 76.1 -26.5 - 76.6 -23.8 - 76.9 -21.2 - 77.2 -18.6 - 77.4 -16.1 - 77.5 -13.7 - 77.6 -11.3 - 77.5 -8.97 - 77.4 -6.71 - 77.3 -4.50 - 77.0 -2.34 - 76.7 -.250 - 76.4 1.79 - 76.0 3.76 - 75.5 5.69 - 75.0 7.55 - 74.5 9.37 - 73.9 11.1 - 73.2 12.8 - 72.5 14.5 - 71.8 16.1 - 71.1 17.6 - 70.3 19.1 - 69.4 20.6 - 68.6 22.0 - 67.7 23.3 - 66.7 24.7 - 65.8 25.9 - 64.8 27.1 - 63.8 28.3 - 62.7 29.5 - 61.7 30.5 - 60.6 31.6 - 59.5 32.6 - 58.4 33.5 - 57.2 34.5 - 56.0 35.3 - 54.8 36.2 - 53.6 37.0 - 52.4 37.7 - 51.2 38.5 - 49.9 39.2 - 48.7 39.8 - 47.4 40.4 - 46.1 41.0 - 44.8 41.5 - 43.5 42.0 - 42.1 42.5 - 40.8 42.9 - 39.5 43.3 - 38.1 43.6 - 36.7 43.9 - 35.4 44.2 - 34.0 44.4 - 32.6 44.6 - 31.3 44.8 - 29.9 44.9 - 28.5 45.0 - 27.1 45.1 - 25.7 45.1 - 24.3 45.1 - 23.0 45.1 - 21.6 45.0 - 20.2 44.9 - 18.8 44.7 - 17.4 44.5 - 16.1 44.3 - 14.7 44.0 - 13.3 43.7 - 12.0 43.4 - 10.6 43.0 - 9.29 42.6 - 7.96 42.2 - 6.65 41.7 -REG_LINE: 197 - 48.1 82.5 - 46.6 82.8 - 45.0 83.2 - 43.4 83.5 - 41.8 83.8 - 40.3 84.1 - 38.7 84.4 - 37.1 84.6 - 35.5 84.8 - 33.8 84.9 - 32.2 85.0 - 30.6 85.2 - 29.0 85.2 - 27.4 85.3 - 25.8 85.3 - 24.2 85.3 - 22.5 85.3 - 20.9 85.2 - 19.3 85.1 - 17.7 85.0 - 16.1 84.8 - 14.5 84.6 - 12.9 84.4 - 11.3 84.2 - 9.69 83.9 - 8.10 83.7 - 6.52 83.3 - 4.95 83.0 - 3.39 82.6 - 1.83 82.2 - .284 81.8 - -1.25 81.3 - -2.78 80.8 - -4.29 80.3 - -5.80 79.7 - -7.29 79.2 - -8.77 78.6 - -10.2 77.9 - -11.7 77.2 - -13.1 76.5 - -14.5 75.8 - -15.9 75.0 - -17.3 74.2 - -18.7 73.4 - -20.1 72.5 - -21.4 71.6 - -22.7 70.7 - -24.0 69.7 - -25.3 68.7 - -26.5 67.6 - -27.8 66.5 - -29.0 65.4 - -30.1 64.2 - -31.3 63.0 - -32.4 61.8 - -33.5 60.5 - -34.6 59.1 - -35.7 57.8 - -36.7 56.3 - -37.7 54.8 - -38.7 53.3 - -39.6 51.7 - -40.5 50.0 - -41.3 48.3 - -42.2 46.5 - -42.9 44.6 - -43.7 42.7 - -44.4 40.6 - -45.0 38.5 - -45.7 36.3 - -46.2 34.0 - -46.7 31.6 - -47.1 29.1 - -47.5 26.5 - -47.8 23.7 - -48.1 20.8 - -48.2 17.8 - -48.3 14.5 - -48.2 11.1 - -48.1 7.50 - -47.8 3.67 - -47.3 -.401 - -46.7 -4.73 - -45.9 -9.33 - -44.9 -14.2 - -43.6 -19.5 - -42.0 -25.0 - -40.0 -30.9 - -37.7 -37.2 - -34.8 -43.8 - -31.3 -50.6 - -27.2 -57.6 - -22.3 -64.7 - -16.7 -71.6 - -10.1 -78.1 - -2.67 -83.8 - 5.54 -88.4 - 14.4 -91.5 - 23.6 -92.8 - 32.8 -92.3 - 41.9 -89.9 - 50.3 -85.8 - 58.1 -80.5 - 65.0 -74.3 - 71.1 -67.5 - 76.2 -60.5 - 80.7 -53.4 - 84.4 -46.5 - 87.5 -39.8 - 90.0 -33.4 - 92.1 -27.4 - 93.9 -21.7 - 95.3 -16.3 - 96.4 -11.3 - 97.3 -6.55 - 98.0 -2.11 - 98.5 2.06 - 98.8 5.99 - 99.1 9.69 - 99.1 13.2 - 99.1 16.5 - 99.0 19.6 - 98.8 22.6 - 98.5 25.4 - 98.2 28.1 - 97.8 30.6 - 97.3 33.1 - 96.8 35.4 - 96.2 37.7 - 95.6 39.8 - 94.9 41.9 - 94.1 43.8 - 93.4 45.7 - 92.6 47.6 - 91.7 49.3 - 90.8 51.0 - 89.9 52.6 - 89.0 54.2 - 88.0 55.7 - 87.0 57.2 - 85.9 58.6 - 84.9 60.0 - 83.8 61.3 - 82.7 62.5 - 81.5 63.8 - 80.3 65.0 - 79.1 66.1 - 77.9 67.2 - 76.7 68.3 - 75.4 69.3 - 74.1 70.3 - 72.8 71.2 - 71.5 72.2 - 70.1 73.0 - 68.8 73.9 - 67.4 74.7 - 66.0 75.5 - 64.6 76.2 - 63.2 77.0 - 61.7 77.6 - 60.3 78.3 - 58.8 78.9 - 57.3 79.5 - 55.8 80.1 - 54.3 80.6 - 52.8 81.1 - 51.2 81.6 - 49.7 82.0 - 48.1 82.5 - 46.6 82.8 - 45.0 83.2 - 43.4 83.5 - 41.8 83.8 - 40.3 84.1 - 38.7 84.4 - 37.1 84.6 - 35.5 84.8 - 33.8 84.9 - 32.2 85.0 - 30.6 85.2 - 29.0 85.2 - 27.4 85.3 - 25.8 85.3 - 24.2 85.3 - 22.5 85.3 - 20.9 85.2 - 19.3 85.1 - 17.7 85.0 - 16.1 84.8 - 14.5 84.6 - 12.9 84.4 - 11.3 84.2 - 9.69 83.9 - 8.10 83.7 - 6.52 83.3 - 4.95 83.0 - 3.39 82.6 -REG_LINE: 158 - 46.8 122. - 25.8 124. - 4.68 123. - -14.9 119. - -31.6 115. - -32.7 115. - -33.7 115. - -34.7 114. - -35.7 114. - -36.6 114. - -37.5 114. - -38.4 114. - -39.3 113. - -40.1 113. - -41.0 113. - -41.7 113. - -42.5 113. - -43.2 113. - -43.9 113. - -44.6 113. - -45.2 113. - -45.8 114. - -46.3 114. - -46.8 114. - -47.2 115. - -47.6 116. - -48.0 116. - -48.3 117. - -48.5 118. - -48.6 120. - -48.7 121. - -48.6 123. - -48.4 125. - -48.1 128. - -47.6 131. - -46.8 134. - -45.8 138. - -44.3 143. - -42.4 149. - -39.8 155. - -36.3 163. - -31.6 172. - -25.2 181. - -16.8 192. - -5.96 201. - -5.08 202. - -4.20 203. - -3.30 203. - -2.39 204. - -1.47 204. - -.536 205. - .410 205. - 1.37 206. - 2.33 206. - 3.31 207. - 4.30 207. - 5.30 208. - 6.31 208. - 7.33 209. - 8.36 209. - 9.40 209. - 10.4 210. - 11.5 210. - 12.6 210. - 13.6 211. - 14.7 211. - 15.8 211. - 16.9 211. - 17.9 212. - 19.0 212. - 20.1 212. - 21.2 212. - 22.3 212. - 23.4 212. - 24.5 212. - 25.6 212. - 26.8 212. - 27.9 212. - 29.0 212. - 30.1 212. - 31.2 212. - 32.3 212. - 33.3 212. - 34.4 211. - 35.5 211. - 36.6 211. - 37.7 211. - 38.7 210. - 39.8 210. - 40.8 210. - 41.9 209. - 42.9 209. - 43.9 209. - 44.9 208. - 46.0 208. - 47.0 207. - 47.9 207. - 48.9 206. - 49.9 206. - 50.8 205. - 51.8 205. - 52.7 204. - 53.6 204. - 54.5 203. - 55.4 202. - 56.3 202. - 57.2 201. - 58.0 200. - 58.9 200. - 59.7 199. - 60.5 198. - 61.3 198. - 62.1 197. - 62.9 196. - 63.6 196. - 73.0 186. - 80.2 176. - 85.5 166. - 89.4 158. - 92.4 151. - 94.5 145. - 96.1 140. - 97.3 136. - 98.2 132. - 98.8 129. - 99.2 126. - 99.4 124. - 99.5 122. - 99.5 120. - 99.4 119. - 99.3 118. - 99.0 117. - 98.7 116. - 98.3 115. - 97.9 115. - 97.4 114. - 96.9 114. - 96.3 114. - 95.7 113. - 95.1 113. - 94.4 113. - 93.7 113. - 92.9 113. - 92.2 113. - 91.4 113. - 90.5 113. - 89.7 113. - 88.8 114. - 87.9 114. - 86.9 114. - 86.0 114. - 85.0 115. - 84.0 115. - 82.9 115. - 66.3 119. - 46.8 122. - 25.8 124. - 4.68 123. -REG_LINE: 132 - 39.9 158. - 25.7 158. - 11.4 158. - -1.28 160. - -2.08 160. - -2.85 160. - -3.60 160. - -4.34 161. - -5.05 161. - -5.74 161. - -6.40 162. - -7.04 162. - -7.66 162. - -8.25 163. - -8.81 163. - -9.34 163. - -9.84 164. - -10.3 164. - -10.7 165. - -11.1 165. - -11.5 166. - -11.8 167. - -12.1 167. - -12.4 168. - -12.6 169. - -12.7 169. - -12.8 170. - -12.9 171. - -12.9 172. - -12.9 173. - -12.8 174. - -12.6 174. - -12.4 175. - -12.1 177. - -11.7 178. - -11.3 179. - -10.8 180. - -10.2 181. - -9.53 182. - -8.78 184. - -7.94 185. - -7.02 186. - -6.00 188. - -4.88 189. - -3.67 190. - -2.36 192. - -.951 193. - .557 194. - 2.16 195. - 3.87 197. - 5.66 198. - 7.55 199. - 9.52 200. - 11.6 201. - 13.7 202. - 15.9 202. - 18.1 203. - 20.4 203. - 22.7 203. - 25.0 203. - 27.3 203. - 29.6 203. - 31.9 203. - 34.1 202. - 36.3 202. - 38.5 201. - 40.6 200. - 42.6 199. - 44.5 198. - 46.3 197. - 48.1 196. - 49.7 195. - 51.2 193. - 52.7 192. - 54.0 191. - 55.3 189. - 56.5 188. - 57.5 187. - 58.5 185. - 59.3 184. - 60.1 183. - 60.8 182. - 61.4 180. - 62.0 179. - 62.4 178. - 62.8 177. - 63.2 176. - 63.4 175. - 63.6 174. - 63.7 173. - 63.8 172. - 63.8 171. - 63.8 170. - 63.7 170. - 63.5 169. - 63.3 168. - 63.1 167. - 62.9 167. - 62.5 166. - 62.2 166. - 61.8 165. - 61.4 165. - 60.9 164. - 60.4 164. - 59.9 163. - 59.4 163. - 58.8 162. - 58.2 162. - 57.6 162. - 56.9 161. - 56.2 161. - 55.5 161. - 54.8 161. - 54.0 160. - 53.3 160. - 52.5 160. - 51.7 160. - 50.9 159. - 50.0 159. - 49.2 159. - 48.3 159. - 47.4 159. - 46.5 159. - 45.6 159. - 44.7 158. - 43.8 158. - 42.8 158. - 41.9 158. - 40.9 158. - 39.9 158. - 25.7 158. - 11.4 158. -REG_LINE: 2 - 40.8 84.0 - 40.8 85.8 -REG_LINE: 2 - 33.3 85.0 - 33.3 86.7 -REG_LINE: 2 - 25.8 85.3 - 25.8 87.0 -REG_LINE: 2 - 18.2 85.0 - 18.2 86.8 -REG_LINE: 2 - 10.7 84.1 - 10.7 85.9 -REG_LINE: 2 - -3.79 80.5 - -3.83 82.2 -REG_LINE: 2 - -10.7 77.7 - -10.8 79.4 -REG_LINE: 2 - -17.3 74.2 - -17.4 76.0 -REG_LINE: 2 - -23.6 70.0 - -23.6 71.8 -REG_LINE: 2 - -29.4 65.0 - -29.5 66.8 -REG_LINE: 2 - -39.3 52.2 - -39.4 54.0 -REG_LINE: 2 - -43.2 44.0 - -43.4 45.7 -REG_LINE: 2 - -46.2 34.0 - -46.4 35.8 -REG_LINE: 2 - -48.0 21.8 - -48.3 23.5 -REG_LINE: 2 - -48.0 6.25 - -48.3 7.96 -REG_LINE: 2 - -35.8 -41.5 - -36.5 -39.9 -REG_LINE: 2 - -14.6 -73.9 - -15.8 -72.6 -REG_LINE: 2 - 23.6 -92.8 - 22.6 -94.3 -REG_LINE: 2 - 62.8 -76.5 - 64.1 -75.2 -REG_LINE: 2 - 85.5 -44.2 - 86.2 -42.6 -REG_LINE: 2 - 98.7 4.70 - 99.1 6.41 -REG_LINE: 2 - 99.0 20.6 - 99.3 22.3 -REG_LINE: 2 - 97.3 33.1 - 97.5 34.8 -REG_LINE: 2 - 94.4 43.2 - 94.6 44.9 -REG_LINE: 2 - 90.5 51.6 - 90.7 53.3 -REG_LINE: 2 - 80.7 64.6 - 80.8 66.3 -REG_LINE: 2 - 75.0 69.6 - 75.1 71.4 -REG_LINE: 2 - 68.8 73.9 - 68.8 75.6 -REG_LINE: 2 - 62.2 77.4 - 62.2 79.2 -REG_LINE: 2 - 55.3 80.3 - 55.3 82.0 -REG_LINE: 2 - 40.8 84.0 - 40.8 85.8 -REG_LINE: 2 - 33.3 85.0 - 33.3 86.7 -REG_LINE: 2 - 25.8 85.3 - 25.8 87.0 -REG_LINE: 2 - 18.2 85.0 - 18.2 86.8 -REG_LINE: 2 - 10.7 84.1 - 10.7 85.9 -REG_LINE: 2 - 23.1 -34.3 - 21.6 -33.5 -REG_LINE: 2 - 20.6 -38.6 - 19.1 -37.7 -REG_LINE: 2 - 18.0 -42.6 - 16.5 -41.7 -REG_LINE: 2 - 15.2 -46.2 - 13.8 -45.2 -REG_LINE: 2 - 12.3 -49.4 - 10.9 -48.4 -REG_LINE: 2 - 6.00 -54.5 - 4.63 -53.5 -REG_LINE: 2 - 2.59 -56.3 - 1.25 -55.2 -REG_LINE: 2 - -1.03 -57.5 - -2.33 -56.3 -REG_LINE: 2 - -4.86 -58.0 - -6.12 -56.8 -REG_LINE: 2 - -8.94 -57.7 - -10.1 -56.4 -REG_LINE: 2 - -17.9 -54.1 - -19.0 -52.7 -REG_LINE: 2 - -22.8 -50.3 - -23.9 -48.9 -REG_LINE: 2 - -28.1 -44.9 - -29.0 -43.4 -REG_LINE: 2 - -33.6 -37.4 - -34.4 -35.9 -REG_LINE: 2 - -39.3 -27.4 - -40.0 -25.8 -REG_LINE: 2 - -50.1 2.52 - -50.5 4.22 -REG_LINE: 2 - -54.3 23.2 - -54.6 24.9 -REG_LINE: 2 - -56.8 47.3 - -56.8 49.1 -REG_LINE: 2 - -56.8 73.8 - -56.1 75.5 -REG_LINE: 2 - -53.9 101. - -54.0 98.8 -REG_LINE: 2 - -41.1 146. - -41.7 144. -REG_LINE: 2 - -32.8 162. - -33.7 161. -REG_LINE: 2 - -24.5 175. - -25.5 173. -REG_LINE: 2 - -16.5 183. - -17.6 182. -REG_LINE: 2 - -9.06 188. - -10.4 187. -REG_LINE: 2 - 3.65 193. - 2.17 192. -REG_LINE: 2 - 9.03 193. - 7.49 192. -REG_LINE: 2 - 13.8 192. - 12.2 192. -REG_LINE: 2 - 18.1 190. - 16.5 190. -REG_LINE: 2 - 22.0 188. - 20.3 187. -REG_LINE: 15 - 3.39 82.6 - 6.52 83.3 - 9.69 83.9 - 12.9 84.4 - 16.1 84.8 - 19.3 85.1 - 22.5 85.3 - 25.8 85.3 - 29.0 85.2 - 32.2 85.0 - 35.5 84.8 - 38.7 84.4 - 41.8 83.8 - 45.0 83.2 - 48.1 82.5 -REG_LINE: 15 - 3.39 82.6 - .284 81.8 - -2.78 80.8 - -5.80 79.7 - -8.77 78.6 - -11.7 77.2 - -14.5 75.8 - -17.3 74.2 - -20.1 72.5 - -22.7 70.7 - -25.3 68.7 - -27.8 66.5 - -30.1 64.2 - -32.4 61.8 - -34.6 59.1 -REG_LINE: 15 - -34.6 59.1 - -36.7 56.3 - -38.7 53.3 - -40.5 50.0 - -42.2 46.5 - -43.7 42.7 - -45.0 38.5 - -46.2 34.0 - -47.1 29.1 - -47.8 23.7 - -48.2 17.8 - -48.2 11.1 - -47.8 3.67 - -46.7 -4.73 - -44.9 -14.2 -REG_LINE: 93 - -44.9 -14.2 - -42.0 -25.0 - -37.7 -37.2 - -31.3 -50.6 - -22.3 -64.7 - -21.6 -65.7 - -20.8 -66.7 - -20.0 -67.7 - -19.2 -68.7 - -18.4 -69.7 - -17.5 -70.7 - -16.7 -71.6 - -15.8 -72.6 - -14.9 -73.5 - -14.0 -74.5 - -13.0 -75.4 - -12.1 -76.3 - -11.1 -77.2 - -10.1 -78.1 - -9.08 -79.0 - -8.06 -79.8 - -7.01 -80.7 - -5.95 -81.5 - -4.87 -82.3 - -3.78 -83.1 - -2.67 -83.8 - -1.54 -84.6 - -.395 -85.3 - .764 -86.0 - 1.94 -86.6 - 3.13 -87.2 - 4.33 -87.8 - 5.54 -88.4 - 6.77 -89.0 - 8.01 -89.5 - 9.27 -89.9 - 10.5 -90.4 - 11.8 -90.8 - 13.1 -91.2 - 14.4 -91.5 - 15.7 -91.8 - 17.0 -92.1 - 18.3 -92.3 - 19.6 -92.5 - 20.9 -92.6 - 22.3 -92.8 - 23.6 -92.8 - 24.9 -92.9 - 26.2 -92.9 - 27.6 -92.8 - 28.9 -92.7 - 30.2 -92.6 - 31.5 -92.5 - 32.8 -92.3 - 34.2 -92.0 - 35.5 -91.8 - 36.8 -91.4 - 38.0 -91.1 - 39.3 -90.7 - 40.6 -90.3 - 41.9 -89.9 - 43.1 -89.4 - 44.3 -88.9 - 45.6 -88.3 - 46.8 -87.7 - 48.0 -87.1 - 49.2 -86.5 - 50.3 -85.8 - 51.5 -85.2 - 52.6 -84.4 - 53.8 -83.7 - 54.9 -82.9 - 56.0 -82.2 - 57.0 -81.4 - 58.1 -80.5 - 59.1 -79.7 - 60.2 -78.8 - 61.2 -78.0 - 62.2 -77.1 - 63.1 -76.2 - 64.1 -75.2 - 65.0 -74.3 - 65.9 -73.4 - 66.8 -72.4 - 67.7 -71.4 - 68.6 -70.5 - 69.4 -69.5 - 70.2 -68.5 - 71.1 -67.5 - 80.7 -53.4 - 87.5 -39.8 - 92.1 -27.4 - 95.3 -16.3 -REG_LINE: 15 - 95.3 -16.3 - 97.3 -6.55 - 98.5 2.06 - 99.1 9.69 - 99.1 16.5 - 98.8 22.6 - 98.2 28.1 - 97.3 33.1 - 96.2 37.7 - 94.9 41.9 - 93.4 45.7 - 91.7 49.3 - 89.9 52.6 - 88.0 55.7 - 85.9 58.6 -REG_LINE: 15 - 85.9 58.6 - 83.8 61.3 - 81.5 63.8 - 79.1 66.1 - 76.7 68.3 - 74.1 70.3 - 71.5 72.2 - 68.8 73.9 - 66.0 75.5 - 63.2 77.0 - 60.3 78.3 - 57.3 79.5 - 54.3 80.6 - 51.2 81.6 - 48.1 82.5 -REG_LINE: 15 - 48.1 82.5 - 45.0 83.2 - 41.8 83.8 - 38.7 84.4 - 35.5 84.8 - 32.2 85.0 - 29.0 85.2 - 25.8 85.3 - 22.5 85.3 - 19.3 85.1 - 16.1 84.8 - 12.9 84.4 - 9.69 83.9 - 6.52 83.3 - 3.39 82.6 -REG_LINE: 15 - 48.1 82.5 - 45.0 83.2 - 41.8 83.8 - 38.7 84.4 - 35.5 84.8 - 32.2 85.0 - 29.0 85.2 - 25.8 85.3 - 22.5 85.3 - 19.3 85.1 - 16.1 84.8 - 12.9 84.4 - 9.69 83.9 - 6.52 83.3 - 3.39 82.6 -REG_LINE: 15 - 25.4 -29.7 - 24.4 -31.7 - 23.4 -33.7 - 22.4 -35.6 - 21.3 -37.4 - 20.2 -39.2 - 19.1 -40.9 - 18.0 -42.6 - 16.8 -44.2 - 15.6 -45.7 - 14.4 -47.2 - 13.1 -48.6 - 11.9 -49.9 - 10.6 -51.1 - 9.23 -52.2 -REG_LINE: 15 - 9.23 -52.2 - 7.87 -53.3 - 6.48 -54.2 - 5.05 -55.1 - 3.58 -55.9 - 2.08 -56.5 - .548 -57.1 - -1.03 -57.5 - -2.64 -57.8 - -4.30 -58.0 - -6.00 -58.0 - -7.75 -57.9 - -9.54 -57.6 - -11.4 -57.1 - -13.3 -56.4 -REG_LINE: 15 - -13.3 -56.4 - -15.2 -55.6 - -17.2 -54.5 - -19.3 -53.2 - -21.4 -51.6 - -23.6 -49.7 - -25.8 -47.5 - -28.1 -44.9 - -30.4 -42.0 - -32.8 -38.6 - -35.2 -34.8 - -37.6 -30.5 - -40.1 -25.7 - -42.5 -20.3 - -44.9 -14.2 -REG_LINE: 15 - -44.9 -14.2 - -47.2 -7.52 - -49.4 -.109 - -51.4 8.02 - -53.3 16.9 - -54.8 26.4 - -56.0 36.6 - -56.8 47.3 - -57.1 58.5 - -56.9 70.0 - -56.2 81.6 - -55.0 93.1 - -53.3 104. - -51.0 115. - -48.4 125. -REG_LINE: 15 - -48.4 125. - -45.4 135. - -42.2 143. - -38.8 151. - -35.2 158. - -31.6 164. - -28.0 170. - -24.5 175. - -21.0 179. - -17.6 182. - -14.3 185. - -11.1 187. - -8.06 189. - -5.15 190. - -2.36 192. -REG_LINE: 15 - -2.36 192. - .299 192. - 2.83 193. - 5.25 193. - 7.56 193. - 9.75 193. - 11.8 193. - 13.8 192. - 15.7 192. - 17.6 191. - 19.3 190. - 20.9 189. - 22.5 188. - 24.0 186. - 25.4 185. -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -Forward matrix value - M2 = -0.811474832908671 # Forward matrix value - M3 = 0.171224898552328 # Forward matrix value - M4 = -0.862236746712233 # Forward matrix value - M5 = -0.476686298035564 # Forward matrix value - M6 = -0.941127638091139 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = -0.338051429254475 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = -2.61046557479594 # Polar longitude (rad.s) - End SphMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End FrameSet - Begin FrameSet # Set of inter-related coordinate systems -# Title = "Pixel coordinates; first pixel at (-100.5,-200.5)" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "POLAR" # Coordinate system domain -# Lbl1 = "Pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Pixel coordinate 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - IsA Frame # Coordinate system description - Nframe = 2 # Number of Frames in FrameSet -# Base = 1 # Index of base Frame - Currnt = 2 # Index of current Frame - Nod1 = 2 # Frame 1 is associated with node 2 - Nod2 = 1 # Frame 2 is associated with node 1 - Lnk2 = 1 # Node 2 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Data grid indices; first pixel at (1,1) " # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Data grid index 1" # Label for axis 1 -# Lbl2 = "Data grid index 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Data grid index 1" # Axis Label - Symbol = "g1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Data grid index 2" # Axis Label - Symbol = "g2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm2 = # Frame number 2 - Begin Frame # Coordinate system description - Title = "Pixel coordinates; first pixel at (-100.5,-200.5)" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "POLAR" # Coordinate system domain -# Lbl1 = "Pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Pixel coordinate 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 1" # Axis Label - REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '240' - 4.00 80.2 TC -.245 .969 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '300' - -32.7 57.6 TC -.791 .612 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0' - -42.4 -13.7 BC .974 .227 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '60' - 92.9 -15.7 BC -.973 .231 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '120' - 84.0 57.1 TC .798 .602 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '180' - 47.5 80.0 TC .253 .968 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-90' - 27.7 -30.8 TC -.899 .438 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-60' - 10.8 -54.2 TC -.629 .777 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-30' - -14.2 -58.8 TC .374 .927 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0' - -47.2 -15.1 TC .937 .350 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '30' - -50.8 126. BC -.960 .278 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '60' - -3.21 194. BC -.341 .940 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '90' - 27.2 187. BC .711 .704 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 1 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: ' A FITS test' - 31.5 225. BC .000 1.00 - - - - - FITS test number 2 - ==================== - - - -AST_SHOW: - -REG_SINK: -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -AST -COMMENT AST Beginning of AST data for FrameSet object -AST -COMMENT AST ................................................................ -AST -COMMENT AST ................................................................ -AST -COMMENT AST End of AST data for FrameSet object -AST -COMMENT AST ---------------------------------------------------------------- - -Objects written: 1 - -Native Encoding: - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST WCS information in AST format AST -COMMENT AST See http://www.starlink.ac.uk/ast/ AST -COMMENT AST Beginning of AST data for FrameSet object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'FrameSet' / Set of inter-related coordinate systems -NFRAME_A= 2 / Number of Frames in FrameSet -CURRNT_A= 2 / Index of current Frame -NOD1_A = 2 / Frame 1 is associated with node 2 -NOD2_A = 1 / Frame 2 is associated with node 1 -LNK2_A = 1 / Node 2 is derived from node 1 -FRM1_A = ' ' / Frame number 1 -BEGAST_B= 'Frame ' / Coordinate system description -TITLE_A = 'Data grid indices; first pixel at (1&'/ Title of coordinate system -CONTINUE '",1) "' -NAXES_A = 2 / Number of coordinate axes -DOMAIN_A= 'GRID ' / Coordinate system domain -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -LABEL_A = 'Data grid index 1' / Axis Label -SYMBOL_A= 'g1 ' / Axis symbol -UNIT_A = 'pixel ' / Axis units -FORMAT_A= '%3.1f ' / Format specifier -ENDAST_A= 'Axis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_D= 'Axis ' / Coordinate axis -LABEL_B = 'Data grid index 2' / Axis Label -SYMBOL_B= 'g2 ' / Axis symbol -UNIT_B = 'pixel ' / Axis units -FORMAT_B= '%3.1f ' / Format specifier -ENDAST_B= 'Axis ' / End of object definition -ENDAST_C= 'Frame ' / End of object definition -FRM2_A = ' ' / Frame number 2 -BEGAST_E= 'Frame ' / Coordinate system description -TITLE_B = 'Pixel coordinates; first pixel at (-&'/ Title of coordinate system -CONTINUE '100.5,-200.5)' -NAXES_B = 2 / Number of coordinate axes -DOMAIN_B= 'POLAR ' / Coordinate system domain -AX1_B = ' ' / Axis number 1 -BEGAST_F= 'Axis ' / Coordinate axis -LABEL_C = 'Pixel coordinate 1' / Axis Label -SYMBOL_C= 'p1 ' / Axis symbol -UNIT_C = 'pixel ' / Axis units -FORMAT_C= '%3.1f ' / Format specifier -ENDAST_D= 'Axis ' / End of object definition -AX2_B = ' ' / Axis number 2 -BEGAST_G= 'Axis ' / Coordinate axis -LABEL_D = 'Pixel coordinate 2' / Axis Label -SYMBOL_D= 'p2 ' / Axis symbol -UNIT_D = 'pixel ' / Axis units -FORMAT_D= '%3.1f ' / Format specifier -ENDAST_E= 'Axis ' / End of object definition -ENDAST_F= 'Frame ' / End of object definition -MAP2_A = ' ' / Mapping between nodes 1 and 2 -BEGAST_H= 'CmpMap ' / Compound Mapping -NIN_A = 2 / Number of input coordinates -ISA_A = 'Mapping ' / Mapping between coordinate systems -INVA_A = 1 / First Mapping used in inverse direction -INVB_A = 1 / Second Mapping used in inverse direction -MAPA_A = ' ' / First component Mapping -BEGAST_I= 'MathMap ' / Transformation using mathematical functions -NIN_B = 2 / Number of input coordinates -INVERT_A= 0 / Mapping not inverted -ISA_B = 'Mapping ' / Mapping between coordinate systems -FWD1_A = 'r=sqrt(x*x+y*y)' / Forward function 1 -FWD2_A = 'theta=atan2(y,x)' / Forward function 2 -INV1_A = 'x=r*cos(theta)' / Inverse function 1 -INV2_A = 'y=r*sin(theta)' / Inverse function 2 -SIMPFI_A= 1 / Forward-inverse pairs may simplify -SIMPIF_A= 1 / Inverse-forward pairs may simplify -ENDAST_G= 'MathMap ' / End of object definition -MAPB_A = ' ' / Second component Mapping -BEGAST_J= 'WinMap ' / Map one window on to another -NIN_C = 2 / Number of input coordinates -INVERT_B= 0 / Mapping not inverted -ISA_C = 'Mapping ' / Mapping between coordinate systems -SFT1_A = -101.5 / Shift for axis 1 -SFT2_A = -201.5 / Shift for axis 2 -ENDAST_H= 'WinMap ' / End of object definition -ENDAST_I= 'CmpMap ' / End of object definition -ENDAST_J= 'FrameSet' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for FrameSet object AST -COMMENT AST ---------------------------------------------------------------- AST - -ATTRIBUTES: - Colour(axis1) : 1 - Font(Stri) : 1 - Nout : 1 - Class : 4 - Tol : 0.100000E-01 - Gap(1) : 50.0000 - Border : 0 - Invert : 0 - TextLabGap : 0.100000E-01 - Nin : 2 - Current : 3 - Base : 1 - Nobject : 1 - RefCOUNT : 1 - -AST_GRID: -REG_LINE: 197 - 10.8 124. - 10.7 123. - 10.5 122. - 10.3 121. - 10.2 120. - 10.1 119. - 10.0 118. - 9.94 117. - 9.89 116. - 9.85 115. - 9.84 113. - 9.85 112. - 9.88 111. - 9.93 110. - 10.0 109. - 10.1 108. - 10.2 107. - 10.3 106. - 10.5 105. - 10.6 104. - 10.8 103. - 11.0 102. - 11.2 100. - 11.5 99.5 - 11.7 98.5 - 12.0 97.5 - 12.3 96.6 - 12.6 95.6 - 13.0 94.7 - 13.3 93.9 - 13.7 93.0 - 14.0 92.2 - 14.4 91.4 - 14.8 90.6 - 15.2 89.8 - 15.7 89.1 - 16.1 88.4 - 16.5 87.8 - 17.0 87.2 - 17.5 86.6 - 18.0 86.0 - 18.5 85.5 - 19.0 85.0 - 19.5 84.6 - 20.0 84.2 - 20.5 83.8 - 21.1 83.5 - 21.6 83.2 - 22.1 82.9 - 22.7 82.7 - 23.2 82.5 - 23.8 82.4 - 24.3 82.3 - 24.9 82.2 - 25.5 82.2 - 26.0 82.2 - 26.6 82.3 - 27.1 82.4 - 27.7 82.5 - 28.2 82.7 - 28.8 82.9 - 29.3 83.2 - 29.9 83.4 - 30.4 83.8 - 30.9 84.2 - 31.4 84.6 - 32.0 85.0 - 32.5 85.5 - 33.0 86.0 - 33.4 86.6 - 33.9 87.1 - 34.4 87.8 - 34.8 88.4 - 35.3 89.1 - 35.7 89.8 - 36.1 90.6 - 36.5 91.3 - 36.9 92.1 - 37.3 93.0 - 37.6 93.8 - 38.0 94.7 - 38.3 95.6 - 38.6 96.5 - 38.9 97.5 - 39.2 98.5 - 39.4 99.4 - 39.7 100. - 39.9 101. - 40.1 103. - 40.3 104. - 40.5 105. - 40.6 106. - 40.7 107. - 40.8 108. - 40.9 109. - 41.0 110. - 41.1 111. - 41.1 112. - 41.1 113. - 41.1 115. - 41.1 116. - 41.0 117. - 40.9 118. - 40.8 119. - 40.7 120. - 40.6 121. - 40.5 122. - 40.3 123. - 40.1 124. - 39.9 125. - 39.7 126. - 39.4 127. - 39.2 128. - 38.9 129. - 38.6 130. - 38.3 131. - 38.0 132. - 37.6 133. - 37.3 134. - 36.9 135. - 36.5 136. - 36.1 136. - 35.7 137. - 35.3 138. - 34.8 138. - 34.4 139. - 33.9 140. - 33.4 140. - 33.0 141. - 32.5 141. - 32.0 142. - 31.4 142. - 30.9 143. - 30.4 143. - 29.9 143. - 29.3 144. - 28.8 144. - 28.2 144. - 27.7 144. - 27.1 145. - 26.6 145. - 26.0 145. - 25.5 145. - 24.9 145. - 24.3 145. - 23.8 145. - 23.2 144. - 22.7 144. - 22.1 144. - 21.6 144. - 21.1 143. - 20.5 143. - 20.0 143. - 19.5 142. - 19.0 142. - 18.5 141. - 18.0 141. - 17.5 140. - 17.0 140. - 16.5 139. - 16.1 138. - 15.7 138. - 15.2 137. - 14.8 136. - 14.4 136. - 14.0 135. - 13.7 134. - 13.3 133. - 13.0 132. - 12.6 131. - 12.3 130. - 12.0 129. - 11.7 128. - 11.5 127. - 11.2 126. - 11.0 125. - 10.8 124. - 10.6 123. - 10.5 122. - 10.3 121. - 10.2 120. - 10.1 119. - 10.0 118. - 9.93 117. - 9.88 116. - 9.85 115. - 9.84 113. - 9.85 112. - 9.89 111. - 9.94 110. - 10.0 109. - 10.1 108. - 10.2 107. - 10.3 106. - 10.5 105. - 10.7 104. - 10.8 102. -REG_LINE: 197 - -3.80 135. - -4.17 133. - -4.50 131. - -4.80 129. - -5.06 127. - -5.28 125. - -5.46 122. - -5.60 120. - -5.70 118. - -5.76 116. - -5.78 114. - -5.76 111. - -5.70 109. - -5.61 107. - -5.47 105. - -5.29 102. - -5.07 100. - -4.82 98.1 - -4.53 95.9 - -4.19 93.8 - -3.82 91.7 - -3.42 89.6 - -2.97 87.5 - -2.49 85.5 - -1.97 83.5 - -1.42 81.6 - -.838 79.7 - -.219 77.8 - .433 76.0 - 1.12 74.3 - 1.83 72.6 - 2.58 70.9 - 3.35 69.3 - 4.15 67.7 - 4.98 66.2 - 5.84 64.8 - 6.72 63.4 - 7.62 62.1 - 8.55 60.9 - 9.50 59.7 - 10.5 58.6 - 11.5 57.6 - 12.5 56.6 - 13.5 55.7 - 14.5 54.9 - 15.6 54.2 - 16.6 53.5 - 17.7 52.9 - 18.8 52.4 - 19.9 51.9 - 21.0 51.6 - 22.1 51.3 - 23.2 51.1 - 24.3 51.0 - 25.4 50.9 - 26.6 51.0 - 27.7 51.1 - 28.8 51.3 - 29.9 51.6 - 31.0 51.9 - 32.1 52.4 - 33.2 52.9 - 34.3 53.5 - 35.3 54.1 - 36.4 54.9 - 37.4 55.7 - 38.4 56.6 - 39.4 57.5 - 40.4 58.6 - 41.4 59.7 - 42.4 60.8 - 43.3 62.1 - 44.2 63.4 - 45.1 64.8 - 45.9 66.2 - 46.8 67.7 - 47.6 69.2 - 48.3 70.8 - 49.1 72.5 - 49.8 74.2 - 50.5 76.0 - 51.1 77.8 - 51.8 79.6 - 52.3 81.5 - 52.9 83.5 - 53.4 85.5 - 53.9 87.5 - 54.3 89.5 - 54.7 91.6 - 55.1 93.7 - 55.5 95.8 - 55.7 98.0 - 56.0 100. - 56.2 102. - 56.4 105. - 56.5 107. - 56.6 109. - 56.7 111. - 56.7 113. - 56.7 116. - 56.6 118. - 56.5 120. - 56.4 122. - 56.2 125. - 56.0 127. - 55.7 129. - 55.5 131. - 55.1 133. - 54.7 135. - 54.3 137. - 53.9 139. - 53.4 141. - 52.9 143. - 52.3 145. - 51.8 147. - 51.1 149. - 50.5 151. - 49.8 153. - 49.1 154. - 48.3 156. - 47.6 158. - 46.8 159. - 45.9 161. - 45.1 162. - 44.2 163. - 43.3 165. - 42.4 166. - 41.4 167. - 40.4 168. - 39.4 169. - 38.4 170. - 37.4 171. - 36.4 172. - 35.3 173. - 34.3 173. - 33.2 174. - 32.1 175. - 31.0 175. - 29.9 175. - 28.8 176. - 27.7 176. - 26.6 176. - 25.4 176. - 24.3 176. - 23.2 176. - 22.1 176. - 21.0 175. - 19.9 175. - 18.8 174. - 17.7 174. - 16.6 173. - 15.6 173. - 14.5 172. - 13.5 171. - 12.5 170. - 11.5 169. - 10.5 168. - 9.50 167. - 8.55 166. - 7.62 165. - 6.72 163. - 5.84 162. - 4.98 161. - 4.15 159. - 3.35 158. - 2.58 156. - 1.83 154. - 1.12 153. - .433 151. - -.219 149. - -.838 147. - -1.42 145. - -1.97 143. - -2.49 141. - -2.97 139. - -3.42 137. - -3.82 135. - -4.19 133. - -4.53 131. - -4.82 129. - -5.07 127. - -5.29 124. - -5.47 122. - -5.61 120. - -5.70 118. - -5.76 116. - -5.78 113. - -5.76 111. - -5.70 109. - -5.60 107. - -5.46 104. - -5.28 102. - -5.06 100. - -4.80 97.9 - -4.50 95.7 - -4.17 93.6 - -3.80 91.5 -REG_LINE: 197 - -18.4 146. - -19.0 143. - -19.5 140. - -19.9 137. - -20.3 133. - -20.7 130. - -20.9 127. - -21.1 124. - -21.3 120. - -21.4 117. - -21.4 114. - -21.4 110. - -21.3 107. - -21.1 104. - -20.9 100. - -20.7 96.9 - -20.3 93.6 - -20.0 90.4 - -19.5 87.1 - -19.0 83.9 - -18.5 80.8 - -17.9 77.7 - -17.2 74.6 - -16.5 71.6 - -15.7 68.6 - -14.9 65.7 - -14.0 62.8 - -13.1 60.0 - -12.1 57.3 - -11.1 54.7 - -9.99 52.1 - -8.87 49.6 - -7.71 47.2 - -6.50 44.9 - -5.26 42.6 - -3.98 40.5 - -2.66 38.4 - -1.30 36.5 - 0.922E-01 34.6 - 1.52 32.9 - 2.97 31.2 - 4.45 29.6 - 5.96 28.2 - 7.50 26.9 - 9.05 25.6 - 10.6 24.5 - 12.2 23.5 - 13.8 22.6 - 15.5 21.8 - 17.1 21.2 - 18.8 20.7 - 20.4 20.2 - 22.1 19.9 - 23.8 19.7 - 25.4 19.7 - 27.1 19.7 - 28.8 19.9 - 30.5 20.2 - 32.1 20.6 - 33.8 21.2 - 35.4 21.8 - 37.0 22.6 - 38.7 23.5 - 40.2 24.5 - 41.8 25.6 - 43.4 26.8 - 44.9 28.1 - 46.4 29.6 - 47.9 31.1 - 49.4 32.8 - 50.8 34.5 - 52.2 36.4 - 53.5 38.4 - 54.9 40.4 - 56.2 42.6 - 57.4 44.8 - 58.6 47.1 - 59.8 49.5 - 60.9 52.0 - 62.0 54.6 - 63.0 57.2 - 64.0 60.0 - 64.9 62.7 - 65.8 65.6 - 66.6 68.5 - 67.4 71.5 - 68.1 74.5 - 68.8 77.5 - 69.4 80.7 - 69.9 83.8 - 70.4 87.0 - 70.9 90.2 - 71.3 93.5 - 71.6 96.8 - 71.9 100. - 72.1 103. - 72.2 107. - 72.3 110. - 72.3 113. - 72.3 117. - 72.2 120. - 72.1 123. - 71.9 127. - 71.6 130. - 71.3 133. - 70.9 137. - 70.4 140. - 69.9 143. - 69.4 146. - 68.8 149. - 68.1 152. - 67.4 155. - 66.6 158. - 65.8 161. - 64.9 164. - 64.0 167. - 63.0 170. - 62.0 172. - 60.9 175. - 59.8 177. - 58.6 180. - 57.4 182. - 56.2 184. - 54.9 186. - 53.5 189. - 52.2 190. - 50.8 192. - 49.4 194. - 47.9 196. - 46.4 197. - 44.9 199. - 43.4 200. - 41.8 201. - 40.2 202. - 38.7 203. - 37.0 204. - 35.4 205. - 33.8 206. - 32.1 206. - 30.5 207. - 28.8 207. - 27.1 207. - 25.4 207. - 23.8 207. - 22.1 207. - 20.4 207. - 18.8 206. - 17.1 206. - 15.5 205. - 13.8 204. - 12.2 203. - 10.6 202. - 9.05 201. - 7.50 200. - 5.96 199. - 4.45 197. - 2.97 196. - 1.52 194. - 0.922E-01 192. - -1.30 190. - -2.66 188. - -3.98 186. - -5.26 184. - -6.50 182. - -7.71 180. - -8.87 177. - -9.99 175. - -11.1 172. - -12.1 170. - -13.1 167. - -14.0 164. - -14.9 161. - -15.7 158. - -16.5 155. - -17.2 152. - -17.9 149. - -18.5 146. - -19.0 143. - -19.5 140. - -20.0 137. - -20.3 133. - -20.7 130. - -20.9 127. - -21.1 123. - -21.3 120. - -21.4 117. - -21.4 113. - -21.4 110. - -21.3 107. - -21.1 103. - -20.9 100. - -20.7 96.7 - -20.3 93.4 - -19.9 90.1 - -19.5 86.9 - -19.0 83.7 - -18.4 80.6 -REG_LINE: 197 - -33.1 157. - -33.8 153. - -34.5 149. - -35.1 145. - -35.6 140. - -36.0 136. - -36.4 131. - -36.7 127. - -36.9 123. - -37.0 118. - -37.0 114. - -37.0 109. - -36.9 105. - -36.7 100. - -36.4 95.8 - -36.1 91.4 - -35.6 87.0 - -35.1 82.7 - -34.5 78.4 - -33.9 74.1 - -33.1 69.9 - -32.3 65.7 - -31.4 61.6 - -30.5 57.6 - -29.4 53.6 - -28.3 49.8 - -27.1 46.0 - -25.9 42.3 - -24.6 38.6 - -23.2 35.1 - -21.8 31.7 - -20.3 28.3 - -18.8 25.1 - -17.2 22.0 - -15.5 19.0 - -13.8 16.2 - -12.0 13.4 - -10.2 10.8 - -8.37 8.34 - -6.47 5.99 - -4.53 3.78 - -2.55 1.71 - -.540 -.225 - 1.51 -2.01 - 3.58 -3.65 - 5.69 -5.14 - 7.82 -6.47 - 9.97 -7.66 - 12.1 -8.69 - 14.3 -9.56 - 16.5 -10.3 - 18.7 -10.8 - 21.0 -11.2 - 23.2 -11.5 - 25.4 -11.6 - 27.7 -11.5 - 29.9 -11.2 - 32.1 -10.9 - 34.3 -10.3 - 36.5 -9.59 - 38.7 -8.72 - 40.9 -7.70 - 43.0 -6.52 - 45.2 -5.19 - 47.3 -3.70 - 49.4 -2.07 - 51.4 -.290 - 53.4 1.63 - 55.4 3.70 - 57.3 5.91 - 59.2 8.25 - 61.1 10.7 - 62.9 13.3 - 64.7 16.1 - 66.4 18.9 - 68.0 21.9 - 69.6 25.0 - 71.2 28.2 - 72.7 31.6 - 74.1 35.0 - 75.5 38.5 - 76.8 42.1 - 78.0 45.8 - 79.2 49.6 - 80.3 53.5 - 81.4 57.5 - 82.3 61.5 - 83.2 65.6 - 84.0 69.7 - 84.8 73.9 - 85.4 78.2 - 86.0 82.5 - 86.5 86.9 - 87.0 91.2 - 87.3 95.6 - 87.6 100. - 87.8 105. - 87.9 109. - 88.0 113. - 87.9 118. - 87.8 122. - 87.6 127. - 87.3 131. - 87.0 136. - 86.5 140. - 86.0 144. - 85.4 149. - 84.8 153. - 84.0 157. - 83.2 161. - 82.3 165. - 81.4 169. - 80.3 173. - 79.2 177. - 78.0 181. - 76.8 185. - 75.5 188. - 74.1 192. - 72.7 195. - 71.2 199. - 69.6 202. - 68.0 205. - 66.4 208. - 64.7 211. - 62.9 214. - 61.1 216. - 59.2 219. - 57.3 221. - 55.4 223. - 53.4 225. - 51.4 227. - 49.4 229. - 47.3 231. - 45.2 232. - 43.0 233. - 40.9 235. - 38.7 236. - 36.5 236. - 34.3 237. - 32.1 238. - 29.9 238. - 27.7 238. - 25.4 238. - 23.2 238. - 21.0 238. - 18.7 238. - 16.5 237. - 14.3 236. - 12.1 236. - 9.97 235. - 7.82 233. - 5.69 232. - 3.58 231. - 1.51 229. - -.540 227. - -2.55 225. - -4.53 223. - -6.47 221. - -8.37 219. - -10.2 216. - -12.0 213. - -13.8 211. - -15.5 208. - -17.2 205. - -18.8 202. - -20.3 199. - -21.8 195. - -23.2 192. - -24.6 188. - -25.9 185. - -27.1 181. - -28.3 177. - -29.4 173. - -30.5 169. - -31.4 165. - -32.3 161. - -33.1 157. - -33.9 153. - -34.5 149. - -35.1 144. - -35.6 140. - -36.1 135. - -36.4 131. - -36.7 127. - -36.9 122. - -37.0 118. - -37.0 113. - -37.0 109. - -36.9 104. - -36.7 99.9 - -36.4 95.5 - -36.0 91.1 - -35.6 86.7 - -35.1 82.4 - -34.5 78.1 - -33.8 73.8 - -33.1 69.6 -REG_LINE: 197 - -47.7 168. - -48.6 163. - -49.5 158. - -50.2 152. - -50.8 147. - -51.4 141. - -51.8 136. - -52.2 130. - -52.4 125. - -52.6 119. - -52.7 114. - -52.6 108. - -52.5 102. - -52.2 96.9 - -51.9 91.4 - -51.4 85.9 - -50.9 80.4 - -50.3 75.0 - -49.5 69.6 - -48.7 64.3 - -47.8 59.0 - -46.7 53.8 - -45.6 48.7 - -44.4 43.6 - -43.1 38.7 - -41.8 33.8 - -40.3 29.1 - -38.8 24.5 - -37.1 19.9 - -35.4 15.5 - -33.6 11.2 - -31.8 7.08 - -29.8 3.06 - -27.8 -.822 - -25.7 -4.55 - -23.6 -8.14 - -21.4 -11.6 - -19.1 -14.8 - -16.8 -17.9 - -14.5 -20.9 - -12.0 -23.6 - -9.56 -26.2 - -7.04 -28.6 - -4.49 -30.9 - -1.89 -32.9 - .740 -34.8 - 3.40 -36.5 - 6.09 -37.9 - 8.81 -39.2 - 11.5 -40.3 - 14.3 -41.2 - 17.1 -41.9 - 19.8 -42.4 - 22.6 -42.7 - 25.4 -42.8 - 28.2 -42.7 - 31.0 -42.4 - 33.8 -41.9 - 36.5 -41.2 - 39.3 -40.3 - 42.0 -39.3 - 44.7 -38.0 - 47.4 -36.5 - 50.1 -34.8 - 52.7 -33.0 - 55.3 -30.9 - 57.9 -28.7 - 60.4 -26.3 - 62.9 -23.7 - 65.3 -21.0 - 67.7 -18.0 - 70.0 -14.9 - 72.3 -11.7 - 74.5 -8.26 - 76.6 -4.68 - 78.7 -.956 - 80.7 2.92 - 82.6 6.93 - 84.5 11.1 - 86.3 15.4 - 88.0 19.8 - 89.6 24.3 - 91.2 28.9 - 92.6 33.7 - 94.0 38.5 - 95.3 43.5 - 96.5 48.5 - 97.6 53.6 - 98.7 58.8 - 99.6 64.1 - 100. 69.4 - 101. 74.8 - 102. 80.2 - 102. 85.7 - 103. 91.2 - 103. 96.7 - 103. 102. - 104. 108. - 104. 113. - 104. 119. - 103. 125. - 103. 130. - 103. 136. - 102. 141. - 102. 147. - 101. 152. - 100. 157. - 99.6 163. - 98.7 168. - 97.6 173. - 96.5 178. - 95.3 183. - 94.0 188. - 92.6 193. - 91.2 198. - 89.6 203. - 88.0 207. - 86.3 212. - 84.5 216. - 82.6 220. - 80.7 224. - 78.7 228. - 76.6 232. - 74.5 235. - 72.3 239. - 70.0 242. - 67.7 245. - 65.3 248. - 62.9 251. - 60.4 253. - 57.9 256. - 55.3 258. - 52.7 260. - 50.1 262. - 47.4 263. - 44.7 265. - 42.0 266. - 39.3 267. - 36.5 268. - 33.8 269. - 31.0 269. - 28.2 270. - 25.4 270. - 22.6 270. - 19.8 269. - 17.1 269. - 14.3 268. - 11.5 267. - 8.81 266. - 6.09 265. - 3.40 263. - .740 262. - -1.89 260. - -4.49 258. - -7.04 256. - -9.56 253. - -12.0 251. - -14.5 248. - -16.8 245. - -19.1 242. - -21.4 238. - -23.6 235. - -25.7 231. - -27.8 228. - -29.8 224. - -31.8 220. - -33.6 216. - -35.4 211. - -37.1 207. - -38.8 202. - -40.3 198. - -41.8 193. - -43.1 188. - -44.4 183. - -45.6 178. - -46.7 173. - -47.8 168. - -48.7 163. - -49.5 157. - -50.3 152. - -50.9 146. - -51.4 141. - -51.9 135. - -52.2 130. - -52.5 124. - -52.6 119. - -52.7 113. - -52.6 108. - -52.4 102. - -52.2 96.5 - -51.8 91.0 - -51.4 85.5 - -50.8 80.0 - -50.2 74.6 - -49.5 69.2 - -48.6 63.9 - -47.7 58.6 -REG_LINE: 141 - -62.3 179. - -63.4 173. - -64.4 167. - -65.3 160. - -66.1 154. - -66.8 147. - -67.3 140. - -67.7 134. - -68.0 127. - -68.2 120. - -68.3 114. - -68.2 107. - -68.1 100. - -67.8 93.6 - -67.3 87.0 - -66.8 80.4 - -66.2 73.8 - -65.4 67.3 - -64.5 60.8 - -63.5 54.4 - -62.4 48.1 - -61.2 41.9 - -59.9 35.7 - -58.4 29.7 - -56.9 23.8 - -55.2 17.9 - -53.5 12.2 - -51.6 6.66 - -49.6 1.22 - -47.6 -4.07 - -45.4 -9.21 - -43.2 -14.2 - -40.9 -19.0 - -38.5 -23.7 - -36.0 -28.2 - -33.4 -32.5 - -30.8 -36.6 - -28.1 -40.5 - -25.3 -44.2 - -22.4 -47.7 - -19.5 -51.1 - -16.6 -54.2 - -13.5 -57.1 - -10.5 -59.7 - -7.36 -62.2 - -4.21 -64.4 - -1.01 -66.4 - 2.22 -68.2 - 5.47 -69.7 - 8.76 -71.1 - 12.1 -72.1 - 15.4 -73.0 - 18.7 -73.6 - 22.1 -73.9 - 25.4 -74.1 - 28.8 -73.9 - 32.1 -73.6 - 35.4 -73.0 - 38.8 -72.2 - 42.1 -71.1 - 45.3 -69.8 - 48.6 -68.3 - 51.8 -66.5 - 55.0 -64.5 - 58.2 -62.3 - 61.3 -59.8 - 64.4 -57.2 - 67.4 -54.3 - 70.4 -51.2 - 73.3 -47.9 - 76.1 -44.3 - 78.9 -40.6 - 81.6 -36.7 - 84.3 -32.6 - 86.8 -28.3 - 89.3 -23.8 - 91.7 -19.2 - 94.1 -14.4 - 96.3 -9.39 - 98.5 -4.25 - 101. 1.03 - 102. 6.46 - 104. 12.0 - 106. 17.7 - 108. 23.5 - 109. 29.5 - 111. 35.5 - 112. 41.7 - 113. 47.9 - 114. 54.2 - 115. 60.6 - 116. 67.0 - 117. 73.6 - 118. 80.1 - 118. 86.7 - 119. 93.4 - 119. 100. - 119. 107. - 119. 113. - 119. 120. - 119. 127. - 119. 133. - 118. 140. - 118. 147. - 117. 153. - 116. 160. - 115. 166. - 114. 173. - 113. 179. - 112. 185. - 111. 191. - 109. 197. - 108. 203. - 106. 209. - 104. 215. - 102. 220. - 101. 226. - 98.5 231. - 96.3 236. - 94.1 241. - 91.7 246. - 89.3 251. - 86.8 255. - 84.3 259. - 81.6 264. - 78.9 267. - 76.1 271. - 73.3 275. - 70.4 278. - 67.4 281. - 64.4 284. - 61.3 287. - 58.2 289. - 55.0 291. - 51.8 293. - 48.6 295. - 45.3 297. - 42.1 298. - 38.8 299. - 35.4 300. - 34.7 300. -REG_LINE: 53 - 16.2 300. - 15.4 300. - 12.1 299. - 8.76 298. - 5.47 297. - 2.22 295. - -1.01 293. - -4.21 291. - -7.36 289. - -10.5 287. - -13.5 284. - -16.6 281. - -19.5 278. - -22.4 275. - -25.3 271. - -28.1 267. - -30.8 263. - -33.4 259. - -36.0 255. - -38.5 251. - -40.9 246. - -43.2 241. - -45.4 236. - -47.6 231. - -49.6 226. - -51.6 220. - -53.5 215. - -55.2 209. - -56.9 203. - -58.4 197. - -59.9 191. - -61.2 185. - -62.4 179. - -63.5 172. - -64.5 166. - -65.4 160. - -66.2 153. - -66.8 147. - -67.3 140. - -67.8 133. - -68.1 127. - -68.2 120. - -68.3 113. - -68.2 107. - -68.0 99.8 - -67.7 93.2 - -67.3 86.5 - -66.8 79.9 - -66.1 73.3 - -65.3 66.8 - -64.4 60.4 - -63.4 54.0 - -62.3 47.7 -REG_LINE: 128 - -77.0 190. - -78.3 183. - -79.4 175. - -80.5 168. - -81.4 160. - -82.1 153. - -82.8 145. - -83.3 137. - -83.6 129. - -83.8 122. - -83.9 114. - -83.8 106. - -83.6 98.1 - -83.3 90.3 - -82.8 82.6 - -82.2 74.9 - -81.4 67.2 - -80.5 59.6 - -79.5 52.0 - -78.3 44.6 - -77.1 37.2 - -75.6 29.9 - -74.1 22.8 - -72.4 15.7 - -70.6 8.81 - -68.7 2.01 - -66.6 -4.64 - -64.4 -11.1 - -62.2 -17.5 - -59.8 -23.7 - -57.3 -29.7 - -54.7 -35.5 - -51.9 -41.1 - -49.1 -46.5 - -46.2 -51.8 - -43.2 -56.8 - -40.2 -61.6 - -37.0 -66.1 - -33.7 -70.5 - -30.4 -74.6 - -27.0 -78.5 - -23.6 -82.1 - -20.0 -85.5 - -16.5 -88.6 - -12.8 -91.5 - -9.15 -94.1 - -5.42 -96.4 - -1.66 -98.5 - 2.14 -100. - 5.97 -102. - 9.83 -103. - 13.7 -104. - 17.6 -105. - 21.5 -105. - 25.4 -105. - 29.3 -105. - 33.2 -105. - 37.1 -104. - 41.0 -103. - 44.8 -102. - 48.7 -100. - 52.5 -98.5 - 56.2 -96.5 - 60.0 -94.2 - 63.6 -91.6 - 67.3 -88.7 - 70.9 -85.6 - 74.4 -82.2 - 77.8 -78.6 - 81.2 -74.7 - 84.6 -70.6 - 87.8 -66.3 - 91.0 -61.7 - 94.1 -56.9 - 97.1 -51.9 - 100. -46.7 - 103. -41.3 - 105. -35.7 - 108. -29.9 - 111. -23.9 - 113. -17.7 - 115. -11.4 - 117. -4.87 - 120. 1.78 - 121. 8.56 - 123. 15.5 - 125. 22.5 - 127. 29.7 - 128. 37.0 - 129. 44.3 - 130. 51.8 - 131. 59.3 - 132. 66.9 - 133. 74.6 - 134. 82.3 - 134. 90.0 - 135. 97.8 - 135. 106. - 135. 113. - 135. 121. - 135. 129. - 134. 137. - 134. 145. - 133. 152. - 132. 160. - 131. 168. - 130. 175. - 129. 183. - 128. 190. - 127. 197. - 125. 204. - 123. 211. - 121. 218. - 120. 225. - 117. 232. - 115. 238. - 113. 245. - 111. 251. - 108. 257. - 105. 263. - 103. 268. - 100. 274. - 97.1 279. - 94.1 284. - 91.0 289. - 87.8 293. - 84.6 298. - 82.5 300. -REG_LINE: 40 - -31.6 300. - -33.7 297. - -37.0 293. - -40.2 288. - -43.2 284. - -46.2 279. - -49.1 273. - -51.9 268. - -54.7 262. - -57.3 257. - -59.8 251. - -62.2 244. - -64.4 238. - -66.6 232. - -68.7 225. - -70.6 218. - -72.4 211. - -74.1 204. - -75.6 197. - -77.1 190. - -78.3 182. - -79.5 175. - -80.5 167. - -81.4 160. - -82.2 152. - -82.8 144. - -83.3 137. - -83.6 129. - -83.8 121. - -83.9 113. - -83.8 105. - -83.6 97.5 - -83.3 89.8 - -82.8 82.0 - -82.1 74.3 - -81.4 66.7 - -80.5 59.0 - -79.4 51.5 - -78.3 44.1 - -77.0 36.7 -REG_LINE: 97 - -91.6 201. - -93.1 193. - -94.4 184. - -95.6 176. - -96.6 167. - -97.5 158. - -98.2 149. - -98.8 140. - -99.2 132. - -99.4 123. - -99.5 114. - -99.5 105. - -99.2 95.9 - -98.8 87.0 - -98.3 78.2 - -97.6 69.3 - -96.7 60.6 - -95.7 51.9 - -94.5 43.3 - -93.2 34.8 - -91.7 26.3 - -90.1 18.0 - -88.3 9.83 - -86.4 1.77 - -84.3 -6.14 - -82.1 -13.9 - -79.8 -21.5 - -77.3 -28.9 - -74.7 -36.2 - -71.9 -43.2 - -69.1 -50.1 - -66.1 -56.7 - -63.0 -63.2 - -59.8 -69.4 - -56.5 -75.3 - -53.1 -81.1 - -49.5 -86.6 - -45.9 -91.8 - -42.2 -96.8 - -38.4 -101. - -34.5 -106. - -30.6 -110. - -26.5 -114. - -22.5 -117. - -18.3 -121. - -14.1 -124. - -9.84 -126. - -5.53 -129. - -1.19 -131. - 3.19 -133. - 7.59 -134. - 12.0 -135. - 16.5 -136. - 20.9 -136. - 25.4 -137. - 29.9 -136. - 34.3 -136. - 38.8 -135. - 43.2 -134. - 47.6 -133. - 52.0 -131. - 56.3 -129. - 60.6 -126. - 64.9 -124. - 69.1 -121. - 73.2 -118. - 77.3 -114. - 81.4 -110. - 85.3 -106. - 89.2 -102. - 93.0 -96.9 - 96.7 -92.0 - 100. -86.8 - 104. -81.3 - 107. -75.6 - 111. -69.6 - 114. -63.4 - 117. -57.0 - 120. -50.3 - 123. -43.5 - 126. -36.4 - 128. -29.2 - 131. -21.8 - 133. -14.2 - 135. -6.42 - 137. 1.49 - 139. 9.54 - 141. 17.7 - 143. 26.0 - 144. 34.5 - 145. 43.0 - 147. 51.6 - 148. 60.3 - 148. 69.0 - 149. 77.8 - 150. 86.7 - 150. 92.2 -REG_LINE: 23 - 150. 135. - 150. 140. - 149. 149. - 148. 158. - 148. 167. - 147. 175. - 145. 184. - 144. 192. - 143. 201. - 141. 209. - 139. 217. - 137. 225. - 135. 233. - 133. 241. - 131. 249. - 128. 256. - 126. 263. - 123. 270. - 120. 277. - 117. 284. - 114. 290. - 111. 296. - 109. 300. -REG_LINE: 35 - -57.7 300. - -59.8 296. - -63.0 290. - -66.1 284. - -69.1 277. - -71.9 270. - -74.7 263. - -77.3 256. - -79.8 248. - -82.1 241. - -84.3 233. - -86.4 225. - -88.3 217. - -90.1 209. - -91.7 201. - -93.2 192. - -94.5 184. - -95.7 175. - -96.7 166. - -97.6 158. - -98.3 149. - -98.8 140. - -99.2 131. - -99.5 122. - -99.5 113. - -99.4 104. - -99.2 95.3 - -98.8 86.4 - -98.2 77.5 - -97.5 68.7 - -96.6 60.0 - -95.6 51.3 - -94.4 42.7 - -93.1 34.2 - -91.6 25.7 -REG_LINE: 63 - -100. -13.5 - -98.0 -21.1 - -95.5 -29.8 - -92.9 -38.4 - -90.1 -46.7 - -87.2 -54.9 - -84.1 -62.8 - -80.9 -70.5 - -77.5 -78.0 - -74.1 -85.2 - -70.5 -92.2 - -66.7 -98.9 - -62.9 -105. - -58.9 -112. - -54.8 -117. - -50.7 -123. - -46.4 -128. - -42.0 -133. - -37.6 -138. - -33.1 -142. - -28.4 -146. - -23.8 -150. - -19.0 -153. - -14.3 -156. - -9.41 -159. - -4.52 -161. - .403 -163. - 5.36 -165. - 10.3 -166. - 15.3 -167. - 20.4 -168. - 25.4 -168. - 30.4 -168. - 35.4 -167. - 40.4 -166. - 45.4 -165. - 50.4 -163. - 55.3 -161. - 60.2 -159. - 65.0 -156. - 69.8 -153. - 74.5 -150. - 79.2 -146. - 83.8 -142. - 88.4 -138. - 92.8 -133. - 97.2 -129. - 101. -123. - 106. -118. - 110. -112. - 114. -106. - 118. -99.2 - 121. -92.5 - 125. -85.5 - 128. -78.3 - 132. -70.8 - 135. -63.1 - 138. -55.2 - 141. -47.0 - 144. -38.7 - 146. -30.1 - 149. -21.4 - 150. -17.1 -REG_LINE: 9 - 150. 244. - 149. 248. - 146. 257. - 144. 266. - 141. 274. - 138. 282. - 135. 290. - 132. 298. - 131. 300. -REG_LINE: 9 - -79.7 300. - -80.9 297. - -84.1 290. - -87.2 282. - -90.1 274. - -92.9 265. - -95.5 257. - -98.0 248. - -100. 240. -REG_LINE: 54 - -100. -72.8 - -99.7 -73.6 - -96.3 -82.4 - -92.7 -91.0 - -89.0 -99.3 - -85.1 -107. - -81.1 -115. - -77.0 -123. - -72.7 -130. - -68.3 -137. - -63.8 -143. - -59.1 -149. - -54.4 -155. - -49.5 -161. - -44.6 -166. - -39.6 -171. - -34.4 -175. - -29.2 -179. - -24.0 -183. - -18.7 -186. - -13.3 -189. - -7.85 -192. - -2.38 -194. - 3.13 -196. - 8.66 -197. - 14.2 -198. - 19.8 -199. - 25.4 -199. - 30.9 -199. - 36.5 -198. - 42.1 -197. - 47.6 -196. - 53.1 -194. - 58.6 -192. - 64.0 -189. - 69.4 -186. - 74.7 -183. - 80.0 -179. - 85.2 -175. - 90.3 -171. - 95.3 -166. - 100. -161. - 105. -155. - 110. -150. - 115. -143. - 119. -137. - 123. -130. - 128. -123. - 132. -115. - 136. -108. - 140. -99.6 - 144. -91.3 - 147. -82.7 - 150. -75.3 -REG_LINE: 2 - -99.9 300. - -100. 300. -REG_LINE: 13 - -100. -121. - -96.2 -129. - -91.8 -138. - -87.2 -146. - -82.5 -154. - -77.7 -162. - -72.7 -169. - -67.6 -176. - -62.4 -182. - -57.0 -188. - -51.6 -194. - -46.1 -199. - -45.1 -200. -REG_LINE: 13 - 96.0 -200. - 96.8 -199. - 102. -194. - 108. -188. - 113. -182. - 118. -176. - 123. -169. - 128. -162. - 133. -154. - 138. -146. - 143. -138. - 147. -130. - 150. -123. -REG_LINE: 6 - -100. -165. - -97.4 -170. - -92.3 -178. - -87.0 -187. - -81.6 -194. - -77.4 -200. -REG_LINE: 6 - 128. -200. - 132. -195. - 138. -187. - 143. -179. - 148. -170. - 150. -167. -REG_LINE: 10 - 40.9 118. - 24.4 113. - 7.79 108. - -8.78 104. - -25.4 98.9 - -41.9 94.2 - -58.5 89.5 - -75.1 84.8 - -91.7 80.0 - -100. 77.7 -REG_LINE: 12 - 38.0 132. - 24.6 112. - 11.2 92.1 - -2.25 72.0 - -15.7 52.0 - -29.1 31.9 - -42.5 11.9 - -55.9 -8.13 - -69.3 -28.2 - -82.7 -48.2 - -96.1 -68.2 - -100. -74.0 -REG_LINE: 13 - 32.0 142. - 25.0 111. - 18.0 81.0 - 11.1 50.5 - 4.10 20.1 - -2.86 -10.4 - -9.83 -40.8 - -16.8 -71.3 - -23.8 -102. - -30.7 -132. - -37.7 -163. - -44.7 -193. - -46.3 -200. -REG_LINE: 12 - 24.4 145. - 25.5 111. - 26.7 77.8 - 27.9 44.4 - 29.1 11.0 - 30.3 -22.4 - 31.5 -55.8 - 32.7 -89.2 - 33.8 -123. - 35.0 -156. - 36.2 -189. - 36.6 -200. -REG_LINE: 14 - 17.0 140. - 26.1 112. - 35.1 83.4 - 44.2 55.2 - 53.2 27.0 - 62.3 -1.14 - 71.3 -29.3 - 80.3 -57.5 - 89.4 -85.7 - 98.4 -114. - 107. -142. - 117. -170. - 126. -198. - 126. -200. -REG_LINE: 11 - 11.8 128. - 26.4 112. - 41.1 96.3 - 55.8 80.3 - 70.5 64.2 - 85.2 48.2 - 99.9 32.1 - 115. 16.1 - 129. 0.199E-02 - 144. -16.1 - 150. -22.6 -REG_LINE: 10 - 9.84 113. - 26.6 113. - 43.3 113. - 60.1 113. - 76.8 113. - 93.5 113. - 110. 113. - 127. 113. - 144. 113. - 150. 113. -REG_LINE: 11 - 11.8 98.5 - 26.4 115. - 41.1 131. - 55.8 147. - 70.5 163. - 85.2 179. - 99.9 195. - 115. 211. - 129. 227. - 144. 243. - 150. 250. -REG_LINE: 9 - 17.0 87.1 - 26.1 115. - 35.1 143. - 44.2 172. - 53.2 200. - 62.3 228. - 71.3 256. - 80.3 284. - 85.4 300. -REG_LINE: 8 - 24.4 82.3 - 25.5 116. - 26.7 149. - 27.9 182. - 29.1 216. - 30.3 249. - 31.5 283. - 32.1 300. -REG_LINE: 9 - 32.0 85.0 - 25.0 115. - 18.0 146. - 11.1 176. - 4.10 207. - -2.86 237. - -9.83 268. - -16.8 298. - -17.2 300. -REG_LINE: 12 - 38.0 94.7 - 24.6 115. - 11.2 135. - -2.25 155. - -15.7 175. - -29.1 195. - -42.5 215. - -55.9 235. - -69.3 255. - -82.7 275. - -96.1 295. - -99.4 300. -REG_LINE: 10 - 40.9 109. - 24.4 114. - 7.79 118. - -8.78 123. - -25.4 128. - -41.9 133. - -58.5 137. - -75.1 142. - -91.7 147. - -100. 149. -REG_LINE: 2 - 18.7 134. - 17.7 133. -REG_LINE: 2 - 20.4 129. - 19.4 128. -REG_LINE: 2 - 22.1 124. - 21.1 123. -REG_LINE: 2 - 23.8 119. - 22.8 117. -REG_LINE: 2 - 27.2 108. - 28.2 110. -REG_LINE: 2 - 28.8 103. - 29.8 104. -REG_LINE: 2 - 30.5 97.7 - 31.5 99.1 -REG_LINE: 2 - 32.2 92.4 - 33.2 93.8 -REG_LINE: 2 - 35.6 81.9 - 36.6 83.3 -REG_LINE: 2 - 37.3 76.6 - 38.3 78.1 -REG_LINE: 2 - 39.0 71.4 - 40.0 72.8 -REG_LINE: 2 - 40.7 66.1 - 41.7 67.5 -REG_LINE: 2 - 44.0 55.6 - 45.0 57.0 -REG_LINE: 2 - 45.7 50.3 - 46.7 51.8 -REG_LINE: 2 - 47.4 45.1 - 48.4 46.5 -REG_LINE: 2 - 49.1 39.8 - 50.1 41.2 -REG_LINE: 2 - 52.5 29.3 - 53.5 30.7 -REG_LINE: 2 - 54.2 24.0 - 55.2 25.5 -REG_LINE: 2 - 55.9 18.8 - 56.9 20.2 -REG_LINE: 2 - 57.5 13.5 - 58.6 14.9 -REG_LINE: 2 - 60.9 2.99 - 61.9 4.43 -REG_LINE: 2 - 62.6 -2.26 - 63.6 -.831 -REG_LINE: 2 - 64.3 -7.52 - 65.3 -6.09 -REG_LINE: 2 - 66.0 -12.8 - 67.0 -11.3 -REG_LINE: 2 - 69.4 -23.3 - 70.4 -21.9 -REG_LINE: 2 - 71.1 -28.6 - 72.1 -27.1 -REG_LINE: 2 - 72.7 -33.8 - 73.7 -32.4 -REG_LINE: 2 - 74.4 -39.1 - 75.4 -37.6 -REG_LINE: 2 - 77.8 -49.6 - 78.8 -48.2 -REG_LINE: 2 - 79.5 -54.9 - 80.5 -53.4 -REG_LINE: 2 - 81.2 -60.1 - 82.2 -58.7 -REG_LINE: 2 - 82.9 -65.4 - 83.9 -63.9 -REG_LINE: 2 - 86.3 -75.9 - 87.3 -74.5 -REG_LINE: 2 - 87.9 -81.2 - 88.9 -79.7 -REG_LINE: 2 - 89.6 -86.4 - 90.6 -85.0 -REG_LINE: 2 - 91.3 -91.7 - 92.3 -90.2 -REG_LINE: 2 - 94.7 -102. - 95.7 -101. -REG_LINE: 2 - 96.4 -107. - 97.4 -106. -REG_LINE: 2 - 98.1 -113. - 99.1 -111. -REG_LINE: 2 - 99.8 -118. - 101. -117. -REG_LINE: 2 - 103. -128. - 104. -127. -REG_LINE: 2 - 105. -134. - 106. -132. -REG_LINE: 2 - 107. -139. - 108. -138. -REG_LINE: 2 - 108. -144. - 109. -143. -REG_LINE: 2 - 112. -155. - 113. -153. -REG_LINE: 2 - 113. -160. - 114. -159. -REG_LINE: 2 - 115. -165. - 116. -164. -REG_LINE: 2 - 117. -171. - 118. -169. -REG_LINE: 2 - 120. -181. - 121. -180. -REG_LINE: 2 - 122. -186. - 123. -185. -REG_LINE: 2 - 123. -192. - 124. -190. -REG_LINE: 2 - 125. -197. - 126. -195. -REG_LINE: 2 - -80.3 169. - -81.8 170. -REG_LINE: 2 - -82.5 148. - -84.2 148. -REG_LINE: 2 - -83.7 126. - -85.5 126. -REG_LINE: 2 - -83.8 104. - -85.6 104. -REG_LINE: 2 - -80.7 61.1 - -82.3 60.3 -REG_LINE: 2 - -77.6 40.2 - -79.0 39.1 -REG_LINE: 2 - -73.4 19.9 - -74.7 18.7 -REG_LINE: 2 - -68.3 .672 - -69.4 -.674 -REG_LINE: 2 - -55.2 -34.3 - -56.0 -35.9 -REG_LINE: 2 - -47.4 -49.7 - -48.1 -51.3 -REG_LINE: 2 - -38.9 -63.4 - -39.5 -65.1 -REG_LINE: 2 - -29.7 -75.4 - -30.2 -77.1 -REG_LINE: 2 - -9.89 -93.6 - -10.2 -95.3 -REG_LINE: 2 - .619 -99.6 - .416 -101. -REG_LINE: 2 - 11.4 -103. - 11.3 -105. -REG_LINE: 2 - 22.3 -105. - 22.2 -107. -REG_LINE: 2 - 44.1 -102. - 44.2 -104. -REG_LINE: 2 - 54.7 -97.3 - 55.0 -99.1 -REG_LINE: 2 - 65.1 -90.4 - 65.4 -92.2 -REG_LINE: 2 - 75.1 -81.5 - 75.5 -83.2 -REG_LINE: 2 - 93.5 -57.9 - 94.1 -59.5 -REG_LINE: 2 - 102. -43.5 - 102. -45.1 -REG_LINE: 2 - 109. -27.5 - 110. -29.0 -REG_LINE: 2 - 116. -10.1 - 117. -11.5 -REG_LINE: 2 - 126. 28.3 - 128. 27.1 -REG_LINE: 2 - 130. 48.8 - 131. 47.9 -REG_LINE: 2 - 133. 70.0 - 134. 69.3 -REG_LINE: 2 - 134. 91.6 - 136. 91.3 -REG_LINE: 2 - 134. 135. - 136. 136. -REG_LINE: 2 - 133. 157. - 134. 158. -REG_LINE: 2 - 130. 178. - 131. 179. -REG_LINE: 2 - 126. 199. - 128. 200. -REG_LINE: 2 - 116. 237. - 117. 238. -REG_LINE: 2 - 109. 254. - 110. 256. -REG_LINE: 2 - 102. 270. - 102. 272. -REG_LINE: 2 - 93.5 285. - 94.1 286. -REG_LINE: 2 - -38.9 290. - -39.5 292. -REG_LINE: 2 - -47.4 277. - -48.1 278. -REG_LINE: 2 - -55.2 261. - -56.0 263. -REG_LINE: 2 - -68.3 226. - -69.4 228. -REG_LINE: 2 - -73.4 207. - -74.7 208. -REG_LINE: 2 - -77.6 187. - -79.0 188. -REG_LINE: 2 - -80.7 166. - -82.3 167. -REG_LINE: 2 - -83.8 123. - -85.6 123. -REG_LINE: 2 - -83.7 101. - -85.5 100. -REG_LINE: 2 - -82.5 78.9 - -84.2 78.4 -REG_LINE: 2 - -80.3 57.5 - -81.8 56.7 -REG_LINE: 15 - 25.5 113. - 24.9 115. - 24.3 117. - 23.7 119. - 23.1 121. - 22.5 123. - 21.9 125. - 21.2 127. - 20.6 128. - 20.0 130. - 19.4 132. - 18.8 134. - 18.2 136. - 17.6 138. - 17.0 140. -REG_LINE: 15 - 25.5 113. - 26.1 112. - 26.7 110. - 27.3 108. - 27.9 106. - 28.5 104. - 29.1 102. - 29.7 100. - 30.3 98.4 - 30.9 96.5 - 31.5 94.7 - 32.1 92.8 - 32.7 90.9 - 33.3 89.0 - 33.9 87.1 -REG_LINE: 15 - 33.9 87.1 - 34.5 85.3 - 35.1 83.4 - 35.7 81.5 - 36.3 79.6 - 36.9 77.8 - 37.5 75.9 - 38.1 74.0 - 38.7 72.1 - 39.3 70.2 - 39.9 68.4 - 40.5 66.5 - 41.1 64.6 - 41.8 62.7 - 42.4 60.8 -REG_LINE: 15 - 42.4 60.8 - 43.0 59.0 - 43.6 57.1 - 44.2 55.2 - 44.8 53.3 - 45.4 51.5 - 46.0 49.6 - 46.6 47.7 - 47.2 45.8 - 47.8 43.9 - 48.4 42.1 - 49.0 40.2 - 49.6 38.3 - 50.2 36.4 - 50.8 34.5 -REG_LINE: 15 - 50.8 34.5 - 51.4 32.7 - 52.0 30.8 - 52.6 28.9 - 53.2 27.0 - 53.8 25.2 - 54.4 23.3 - 55.0 21.4 - 55.6 19.5 - 56.2 17.6 - 56.8 15.8 - 57.4 13.9 - 58.0 12.0 - 58.6 10.1 - 59.2 8.25 -REG_LINE: 15 - 59.2 8.25 - 59.8 6.38 - 60.4 4.50 - 61.0 2.62 - 61.6 .740 - 62.3 -1.14 - 62.9 -3.02 - 63.5 -4.89 - 64.1 -6.77 - 64.7 -8.65 - 65.3 -10.5 - 65.9 -12.4 - 66.5 -14.3 - 67.1 -16.2 - 67.7 -18.0 -REG_LINE: 15 - 67.7 -18.0 - 68.3 -19.9 - 68.9 -21.8 - 69.5 -23.7 - 70.1 -25.6 - 70.7 -27.4 - 71.3 -29.3 - 71.9 -31.2 - 72.5 -33.1 - 73.1 -34.9 - 73.7 -36.8 - 74.3 -38.7 - 74.9 -40.6 - 75.5 -42.5 - 76.1 -44.3 -REG_LINE: 15 - 76.1 -44.3 - 76.7 -46.2 - 77.3 -48.1 - 77.9 -50.0 - 78.5 -51.9 - 79.1 -53.7 - 79.7 -55.6 - 80.3 -57.5 - 80.9 -59.4 - 81.5 -61.2 - 82.2 -63.1 - 82.8 -65.0 - 83.4 -66.9 - 84.0 -68.8 - 84.6 -70.6 -REG_LINE: 15 - 84.6 -70.6 - 85.2 -72.5 - 85.8 -74.4 - 86.4 -76.3 - 87.0 -78.1 - 87.6 -80.0 - 88.2 -81.9 - 88.8 -83.8 - 89.4 -85.7 - 90.0 -87.5 - 90.6 -89.4 - 91.2 -91.3 - 91.8 -93.2 - 92.4 -95.1 - 93.0 -96.9 -REG_LINE: 15 - 93.0 -96.9 - 93.6 -98.8 - 94.2 -101. - 94.8 -103. - 95.4 -104. - 96.0 -106. - 96.6 -108. - 97.2 -110. - 97.8 -112. - 98.4 -114. - 99.0 -116. - 99.6 -118. - 100. -119. - 101. -121. - 101. -123. -REG_LINE: 15 - 101. -123. - 102. -125. - 103. -127. - 103. -129. - 104. -131. - 104. -133. - 105. -134. - 106. -136. - 106. -138. - 107. -140. - 107. -142. - 108. -144. - 109. -146. - 109. -148. - 110. -150. -REG_LINE: 15 - 110. -150. - 110. -151. - 111. -153. - 112. -155. - 112. -157. - 113. -159. - 114. -161. - 114. -163. - 115. -165. - 115. -166. - 116. -168. - 117. -170. - 117. -172. - 118. -174. - 118. -176. -REG_LINE: 14 - 118. -176. - 119. -178. - 120. -180. - 120. -181. - 121. -183. - 121. -185. - 122. -187. - 123. -189. - 123. -191. - 124. -193. - 124. -195. - 125. -196. - 126. -198. - 126. -200. -REG_LINE: 15 - -82.8 82.6 - -83.3 90.3 - -83.6 98.1 - -83.8 106. - -83.9 114. - -83.8 122. - -83.6 129. - -83.3 137. - -82.8 145. - -82.1 153. - -81.4 160. - -80.5 168. - -79.4 175. - -78.3 183. - -77.0 190. -REG_LINE: 15 - -82.8 82.6 - -82.2 74.9 - -81.4 67.2 - -80.5 59.6 - -79.5 52.0 - -78.3 44.6 - -77.1 37.2 - -75.6 29.9 - -74.1 22.8 - -72.4 15.7 - -70.6 8.81 - -68.7 2.01 - -66.6 -4.64 - -64.4 -11.1 - -62.2 -17.5 -REG_LINE: 15 - -62.2 -17.5 - -59.8 -23.7 - -57.3 -29.7 - -54.7 -35.5 - -51.9 -41.1 - -49.1 -46.5 - -46.2 -51.8 - -43.2 -56.8 - -40.2 -61.6 - -37.0 -66.1 - -33.7 -70.5 - -30.4 -74.6 - -27.0 -78.5 - -23.6 -82.1 - -20.0 -85.5 -REG_LINE: 15 - -20.0 -85.5 - -16.5 -88.6 - -12.8 -91.5 - -9.15 -94.1 - -5.42 -96.4 - -1.66 -98.5 - 2.14 -100. - 5.97 -102. - 9.83 -103. - 13.7 -104. - 17.6 -105. - 21.5 -105. - 25.4 -105. - 29.3 -105. - 33.2 -105. -REG_LINE: 15 - 33.2 -105. - 37.1 -104. - 41.0 -103. - 44.8 -102. - 48.7 -100. - 52.5 -98.5 - 56.2 -96.5 - 60.0 -94.2 - 63.6 -91.6 - 67.3 -88.7 - 70.9 -85.6 - 74.4 -82.2 - 77.8 -78.6 - 81.2 -74.7 - 84.6 -70.6 -REG_LINE: 15 - 84.6 -70.6 - 87.8 -66.3 - 91.0 -61.7 - 94.1 -56.9 - 97.1 -51.9 - 100. -46.7 - 103. -41.3 - 105. -35.7 - 108. -29.9 - 111. -23.9 - 113. -17.7 - 115. -11.4 - 117. -4.87 - 120. 1.78 - 121. 8.56 -REG_LINE: 15 - 121. 8.56 - 123. 15.5 - 125. 22.5 - 127. 29.7 - 128. 37.0 - 129. 44.3 - 130. 51.8 - 131. 59.3 - 132. 66.9 - 133. 74.6 - 134. 82.3 - 134. 90.0 - 135. 97.8 - 135. 106. - 135. 113. -REG_LINE: 15 - 135. 113. - 135. 121. - 135. 129. - 134. 137. - 134. 145. - 133. 152. - 132. 160. - 131. 168. - 130. 175. - 129. 183. - 128. 190. - 127. 197. - 125. 204. - 123. 211. - 121. 218. -REG_LINE: 15 - 121. 218. - 120. 225. - 117. 232. - 115. 238. - 113. 245. - 111. 251. - 108. 257. - 105. 263. - 103. 268. - 100. 274. - 97.1 279. - 94.1 284. - 91.0 289. - 87.8 293. - 84.6 298. -REG_LINE: 2 - 84.6 298. - 82.5 300. -REG_LINE: 12 - -31.6 300. - -33.7 297. - -37.0 293. - -40.2 288. - -43.2 284. - -46.2 279. - -49.1 273. - -51.9 268. - -54.7 262. - -57.3 257. - -59.8 251. - -62.2 244. -REG_LINE: 15 - -62.2 244. - -64.4 238. - -66.6 232. - -68.7 225. - -70.6 218. - -72.4 211. - -74.1 204. - -75.6 197. - -77.1 190. - -78.3 182. - -79.5 175. - -80.5 167. - -81.4 160. - -82.2 152. - -82.8 144. -REG_LINE: 15 - -82.8 144. - -83.3 137. - -83.6 129. - -83.8 121. - -83.9 113. - -83.8 105. - -83.6 97.5 - -83.3 89.8 - -82.8 82.0 - -82.1 74.3 - -81.4 66.7 - -80.5 59.0 - -79.4 51.5 - -78.3 44.1 - -77.0 36.7 -REG_LINE: 15 - -82.8 144. - -83.3 137. - -83.6 129. - -83.8 121. - -83.9 113. - -83.8 105. - -83.6 97.5 - -83.3 89.8 - -82.8 82.0 - -82.1 74.3 - -81.4 66.7 - -80.5 59.0 - -79.4 51.5 - -78.3 44.1 - -77.0 36.7 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0.0' - 27.8 114. BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '50.0' - 36.3 87.9 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '100.0' - 44.7 61.6 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '150.0' - 53.2 35.3 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '200.0' - 61.6 9.02 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '250.0' - 70.1 -17.3 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '300.0' - 78.5 -43.6 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '350.0' - 86.9 -69.9 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '400.0' - 95.4 -96.2 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '450.0' - 104. -122. BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '500.0' - 112. -149. BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '550.0' - 121. -175. BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-3.0' - -80.3 82.7 BC .997 0.724E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-2.5' - -59.8 -16.6 BC .936 .352 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-2.0' - -18.4 -83.6 BC .673 .740 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-1.5' -Symbol = "p1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 2" # Axis Label - Symbol = "p2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - InvB = 1 # Second Mapping used in inverse direction - MapA = # First component Mapping - Begin MathMap # Transformation using mathematical functions - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Fwd1 = "r=sqrt(x*x+y*y)" # Forward function 1 - Fwd2 = "theta=atan2(y,x)" # Forward function 2 - Inv1 = "x=r*cos(theta)" # Inverse function 1 - Inv2 = "y=r*sin(theta)" # Inverse function 2 - SimpFI = 1 # Forward-inverse pairs may simplify - SimpIF = 1 # Inverse-forward pairs may simplify - End MathMap - MapB = # Second component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -101.5 # Shift for axis 1 - Sft2 = -201.5 # Shift for axis 2 - End WinMap - End CmpMap - End FrameSet - Begin FrameSet # Set of inter-related coordinate systems -# Title = "FK5 equatorial coordinates; mean equinox J2000.0; gnomonic projection" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Epoch = 1977.77512999212 # Besselian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# System = "FK5" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - IsA Frame # Coordinate system description - Nframe = 2 # Number of Frames in FrameSet - Base = 1 # Index of base Frame - Currnt = 2 # Index of current Frame - Lnk2 = 1 # Node 2 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Pixel Coordinates" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Pixel axis 1" # Label for axis 1 -# Lbl2 = "Pixel axis 2" # Label for axis 2 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel axis 1" # Axis Label - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel axis 2" # Axis Label - End Axis - End Frame - Frm2 = # Frame number 2 - Begin SkyFrame # Description of celestial coordinate system - Ident = " " # Permanent Object identification string - IsA Object # AST Object -# Title = "FK5 equatorial coordinates; mean equinox J2000.0; gnomonic projection" # Title of coordinate system - Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain - Epoch = 1977.77512999212 # Besselian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 - System = "FK5" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - Proj = "gnomonic" # Description of sky projection - Eqnox = 2000 # Julian epoch of mean equinox - SRefIs = "Ignored" # Not rotated (ref. pos. is ignored) - SRef1 = 0 # Ref. pos. RA 0:00:00.0 - SRef2 = -1.57079633000002 # Ref. pos. Dec -90:00:00 - End SkyFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -893.6318379289 # Shift for axis 1 - Sft2 = -223.8380193875 # Shift for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -3.25441534352674e-06 # Forward matrix value - M1 = -1.60367292352974e-08 # Forward matrix value - M2 = -1.812057487023e-08 # Forward matrix value - M3 = 3.25725533992408e-06 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longit 32.8 -102. BC -.145 .989 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-0.5' - 119. 9.22 BC -.965 .262 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0.0' - 132. 113. BC -1.00 0.125E-02 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0.5' - 119. 218. TC .964 .265 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '1.0' - 82.6 296. TC .787 .617 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '2.5' - -59.8 243. TC -.936 .352 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '3.0' - -80.3 144. TC -.997 0.724E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 1 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: ' A FITS test' - 31.0 313. BC .000 1.00 - - - - - FITS test number 3 - ==================== - - - -AST_SHOW: - -REG_SINK: -SIMPLE = T / file does conform to FITS standard -BITPIX = 16 / number of bits per data pixel -NAXIS = 2 / number of data axes -NAXIS1 = 1787 / length of data axis 1 -NAXIS2 = 447 / length of data axis 2 -EXTEND = T / FITS dataset may contain extensions -COMMENT FITS (Flexible Image Transport System) format defined in Astronomy and -COMMENT Astrophysics Supplement Series v44/p363, v44/p371, v73/p359, v73/p365. -COMMENT Contact the NASA Science Office of Standards and Technology for the -COMMENT FITS Definition document #100 and other FITS information. -PLATENUM= '3665 ' / Plate number -EMULSION= 'IIIaJ ' / Kodak emulsion type -FILTER = 'GG395 ' / Schott glass filter type -PLTSCALE= '67.14 ' / [arcsec/mm] plate scale -FIELDNUM= '1 ' / Sky survey field number -TELESCOP= 'UKST ' / Telescope on which the plate was taken -TELETYPE= 'SCHM ' / Type of telescope -SITELAT = -0.5458410576565 / [radians] latitude of telescope -SITELONG= 2.601766194458 / [radians] longitude of telescope -LST = '00:20 ' / [hh:mm] local sidereal time at start of obs -INSTRUME= 'SuperCOSMOS I' / Measuring machine -DATE-MES= '2000-11-04' / [yyyy-mm-dd] Date of this plate measurement -NHKLINES= 146 / Number of lines from house-keeping file -HKLIN001= 'JOB.JOBNO UKJ001' -HKLIN002= 'JOB.DATE-MES 2000:11:04' -HKLIN003= 'JOB.TIME 12:51:09' -HKLIN004= 'JOB.INSTRUME SuperCOSMOS I' -HKLIN005= 'JOB.ORIGIN Royal Observatory Edinburgh' -HKLIN006= 'JOB.SOFTWARE /home/scosdev/v033' -HKLIN007= 'JOB.OPERATOR ebt' -HKLIN008= 'JOB.USER htm' -HKLIN009= 'JOB.USERREF NONE' -HKLIN010= 'JOB.UORIGIN ROE' -HKLIN011= 'JOB.UCOUNTRY uk' -HKLIN012= 'JOB.COMMENT Digital catalogue of the Sky' -HKLIN013= 'JOB.IAM_FILE iam.srt'/ / ' / -HKLIN014= 'PLATE.TELESCOP UKST' -HKLIN015= 'PLATE.TELTYPE SCHM' -HKLIN016= 'PLATE.PLATE 3665' -HKLIN017= 'PLATE.MATERIAL 3mm glass' -HKLIN018= 'PLATE.EMULSION IIIaJ' -HKLIN019= 'PLATE.FILTER GG395' -HKLIN020= 'PLATE.PSCALE 67.14' -HKLIN021= 'PLATE.FIELD 1' -HKLIN022= 'PLATE.RA_PNT 0' -HKLIN023= 'PLATE.DEC_PNT -90' -HKLIN024= 'PLATE.RADECSYS FK4' -HKLIN025= 'PLATE.EQUINOX 1950' -HKLIN026= 'PLATE.TIMESYS BESSELIAN' -HKLIN027= 'PLATE.EPOCH 1977.78'/ / ' / -HKLIN028= 'PLATE.EXPOSURE 75' -HKLIN029= 'PLATE.UTDATE 771011' -HKLIN030= 'PLATE.LST 0020' -HKLIN031= 'PLATE.MJD 43426.573008796' -HKLIN032= 'PLATE.TELLAT -0.54584105765654' -HKLIN033= 'PLATE.TELLONG 2.6017661944583' -HKLIN034= 'PLATE.TELHT 1145' -HKLIN035= 'PLATE.TEMP 273.155'/ / ' / -HKLIN036= 'PLATE.ATMOSP 1013.25'/ / ' / -HKLIN037= 'PLATE.HUMID 0.5' -HKLIN038= 'PLATE.WAVE 4500' -HKLIN039= 'PLATE.TROPL 0.0065' -HKLIN040= 'CALIBRATION.CALTYPE SPLINE' -HKLIN041= 'CALIBRATION.STEPWEDG KPNO' -HKLIN042= 'CALIBRATION.NSTEPS 8' -HKLIN043= 'MEASUREMENT.ORIENTAT news' -HKLIN044= 'MEASUREMENT.EMULPOS UP' -HKLIN045= 'MEASUREMENT.SCANFILT 14' -HKLIN046= 'MEASUREMENT.SOSP 552' -HKLIN047= 'MEASUREMENT.STEPSIZE 10' -HKLIN048= 'MEASUREMENT.SCANLEN 1152' -HKLIN049= 'MEASUREMENT.A-XMIN 1622000'/ / ' / -HKLIN050= 'MEASUREMENT.A-YMIN 1622000'/ / ' / -HKLIN051= 'MEASUREMENT.A-XMAX 33878000' -HKLIN052= 'MEASUREMENT.A-YMAX 33878000' -HKLIN053= 'MEASUREMENT.X_PNT 17500000' -HKLIN054= 'MEASUREMENT.Y_PNT 18000000' -HKLIN055= 'ANALYSIS.NPARAMS 32' -HKLIN056= 'ANALYSIS.AREACUT 8' -HKLIN057= 'ANALYSIS.AP-PARAM 1.07' -HKLIN058= 'DEBLEND.DB-PARAM 1.05' -HKLIN059= 'DEBLEND.DB-AMIN 16' -HKLIN060= 'DEBLEND.DB-AMAX 100000' -HKLIN061= 'DEBLEND.DB-ACUT 8' -HKLIN062= 'DEBLEND.DB-LEVEL 16' -HKLIN063= 'DEBLEND.SELECT PARENT+CHILD' -HKLIN064= 'SKY.SKYSQUAR 64' -HKLIN065= 'SKY.SKYDEFN MEDIAN' -HKLIN066= 'SKY.SKYFILTR bdkjunk'/ / ' / -HKLIN067= 'SKY.F-THRESH 8' -HKLIN068= 'SKY.F-SCLEN 4' -HKLIN069= 'THRESHOLDING.PCUT 10' -HKLIN070= 'IAMQC.AREAMIN 8' -HKLIN071= 'IAMQC.AREAMAX 77346' -HKLIN072= 'IAMQC.MINMAG -30515' -HKLIN073= 'IAMQC.MAXMAG -17954' -HKLIN074= 'IAMQC.MINELL 0.0004156232' -HKLIN075= 'IAMQC.MAXELL 1' -HKLIN076= 'IAMQC.MODELL 0.14' -HKLIN077= 'IAMQC.MODOR 91' -HKLIN078= 'IAMQC.MIDELL 0.21' -HKLIN079= 'IAMQC.MIDOR 93' -HKLIN080= 'IAMQC.MEANELL 0.2467037' -HKLIN081= 'IAMQC.MEANOR 91.63474' -HKLIN082= 'IAMQC.NUMOBJ 556985' -HKLIN083= 'IAMQC.PARENTS 486656' -HKLIN084= 'IAMQC.RANGING TRUE' -HKLIN085= 'IAMQC.LANE_1 15571' -HKLIN086= 'IAMQC.LANE_2 33207' -HKLIN087= 'IAMQC.LANE_3 51478' -HKLIN088= 'IAMQC.LANE_4 69944' -HKLIN089= 'IAMQC.LANE_5 89236' -HKLIN090= 'IAMQC.LANE_6 108416' -HKLIN091= 'IAMQC.LANE_7 127481' -HKLIN092= 'IAMQC.LANE_8 146699' -HKLIN093= 'IAMQC.LANE_9 166380' -HKLIN094= 'IAMQC.LANE_10 186126' -HKLIN095= 'IAMQC.LANE_11 205946' -HKLIN096= 'IAMQC.LANE_12 225915' -HKLIN097= 'IAMQC.LANE_13 245926' -HKLIN098= 'IAMQC.LANE_14 266574' -HKLIN099= 'IAMQC.LANE_15 287150' -HKLIN100= 'IAMQC.LANE_16 308087' -HKLIN101= 'IAMQC.LANE_17 328830' -HKLIN102= 'IAMQC.LANE_18 350253' -HKLIN103= 'IAMQC.LANE_19 370738' -HKLIN104= 'IAMQC.LANE_20 391722' -HKLIN105= 'IAMQC.LANE_21 412801' -HKLIN106= 'IAMQC.LANE_22 433795' -HKLIN107= 'IAMQC.LANE_23 454383' -HKLIN108= 'IAMQC.LANE_24 474711' -HKLIN109= 'IAMQC.LANE_25 495108' -HKLIN110= 'IAMQC.LANE_26 515755' -HKLIN111= 'IAMQC.LANE_27 536499' -HKLIN112= 'IAMQC.LANE_28 556985' -HKLIN113= 'XYTORADEC.STARCAT /sdata/scos/refcats/tycho2.FIT' -HKLIN114= 'XYTORADEC.BRIGHTLIM 9' -HKLIN115= 'XYTORADEC.C-EQUIN 2000' -HKLIN116= 'XYTORADEC.C-EQTSYS JULIAN' -HKLIN117= 'XYTORADEC.C-EPOCH 2000' -HKLIN118= 'XYTORADEC.C-EPTSYS JULIAN' -HKLIN119= 'XYTORADEC.R-EQUIN 2000' -HKLIN120= 'XYTORADEC.R-TSYS JULIAN' -HKLIN121= 'XYTORADEC.MAXITER 5000' -HKLIN122= 'XYTORADEC.RCRITINI 500000' -HKLIN123= 'XYTORADEC.RCRITABS 50000' -HKLIN124= 'XYTORADEC.RCRITREL 1' -HKLIN125= 'XYTORADEC.RCRITFIN 3' -HKLIN126= 'XYTORADEC.HARDCOPY /scos1/scos/UKJ001/UKJ001.ps' -HKLIN127= 'XYTORADEC.REFSMULT 5' -HKLIN128= 'XYTORADEC.RESDMULT 1000' -HKLIN129= 'XYTORADEC.RACOL RA' -HKLIN130= 'XYTORADEC.DECOL DEC' -HKLIN131= 'XYTORADEC.RAPMCOL PMRA' -HKLIN132= 'XYTORADEC.DECPMCOL PMDE' -HKLIN133= 'XYTORADEC.PLXCOL NONE' -HKLIN134= 'XYTORADEC.RVCOL NONE' -HKLIN135= 'XYTORADEC.MAGCOL VT' -HKLIN136= 'XYTORADEC.STARSC 2374' -HKLIN137= 'XYTORADEC.STARSU 1727' -HKLIN138= 'XYTORADEC.COEFFS_1 17.640343856524' -HKLIN139= 'XYTORADEC.COEFFS_2 -260.44151995641' -HKLIN140= 'XYTORADEC.COEFFS_3 -163.09155572601' -HKLIN141= 'XYTORADEC.COEFFS_4 17.504230442205' -HKLIN142= 'XYTORADEC.COEFFS_5 -163.08676953832' -HKLIN143= 'XYTORADEC.COEFFS_6 260.48817907668' -HKLIN144= 'XYTORADEC.DISTR -0.33333333333333' -HKLIN145= 'XYTORADEC.RA_PNT 0.54924996662137' -HKLIN146= 'XYTORADEC.DEC_PNT -1.5684931501781' -HISTORY = 'SuperCOSMOS image analysis and mapping mode (IAM and MM)' / -HISTORY = 'data written by xydcomp_ss.' / -HISTORY = 'Any questions/comments/suggestions/bug reports should be sent' / -HISTORY = 'to N.Hambly@roe.ac.uk' / -ASTSIGX = 0.37 / [arcsec] std. dev. of astrometric fit in X -ASTSIGY = 0.38 / [arcsec] std. dev. of astrometric fit in Y -PC001001= 1.0 / DEPRECATED - Axis rotation matrix -PC001002= 0.004927623810613 / DEPRECATED - Axis rotation matrix -PC002001= -0.005563056187788 / DEPRECATED - Axis rotation matrix -PC002002= 1.0 / DEPRECATED - Axis rotation matrix -CROTA2 = 0.3005532298491 / DEPRECATED - rotation of axis 2 -DATATYPE= 'INTEGER*2' / Type of data -DATUNITS= 'DENSITY ' / Units: transmission, density or intensity -XPIXELSZ= 9.997114974 / [microns] X pixel size -YPIXELSZ= 10.0 / [microns] Y pixel size -OBJCTRA = ' 0 0 0.000' / Centre Right Ascension (J2000) -OBJCTDEC= '-90 0 0.00' / Centre Declination (J2000) -OBJCTX = 16368.63183793 / [pixels] Centre X on plate -OBJCTY = 14740.83801939 / [pixels] Centre Y on plate - -Objects written: 1 - -Native Encoding: - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST WCS information in AST format AST -COMMENT AST See http://www.starlink.ac.uk/ast/ AST -COMMENT AST Beginning of AST data for FrameSet object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'FrameSet' / Set of inter-related coordinate systems -NFRAME_A= 2 / Number of Frames in FrameSet -BASE_A = 1 / Index of base Frame -CURRNT_A= 2 / Index of current Frame -LNK2_A = 1 / Node 2 is derived from node 1 -FRM1_A = ' ' / Frame number 1 -BEGAST_B= 'Frame ' / Coordinate system description -TITLE_A = 'Pixel Coordinates' / Title of coordinate system -NAXES_A = 2 / Number of coordinate axes -DOMAIN_A= 'GRID ' / Coordinate system domain -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -LABEL_A = 'Pixel axis 1' / Axis Label -ENDAST_A= 'Axis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_D= 'Axis ' / Coordinate axis -LABEL_B = 'Pixel axis 2' / Axis Label -ENDAST_B= 'Axis ' / End of object definition -ENDAST_C= 'Frame ' / End of object definition -FRM2_A = ' ' / Frame number 2 -BEGAST_E= 'SkyFrame' / Description of celestial coordinate system -IDENT_A = '" " ' / Permanent Object identification string -ISA_A = 'Object ' / AST Object -NAXES_B = 2 / Number of coordinate axes -EPOCH_A = 1977.77512999212 / Besselian epoch of observation -SYSTEM_A= 'FK5 ' / Coordinate system type -AX1_B = ' ' / Axis number 1 -BEGAST_F= 'SkyAxis ' / Celestial coordinate axis -ENDAST_D= 'SkyAxis ' / End of object definition -AX2_B = ' ' / Axis number 2 -BEGAST_G= 'SkyAxis ' / Celestial coordinate axis -ENDAST_E= 'SkyAxis ' / End of object definition -ISA_B = 'Frame ' / Coordinate system description -PROJ_A = 'gnomonic' / Description of sky projection -EQNOX_A = 2000.0 / Julian epoch of mean equinox -SREFIS_A= 'Ignored ' / Not rotated (ref. pos. is ignored) -SREF1_A = 0.0 / Ref. pos. RA 0:00:00.0 -SREF2_A = -1.57079633 / Ref. pos. Dec -90:00:00 -ENDAST_F= 'SkyFrame' / End of object definition -MAP2_A = ' ' / Mapping between nodes 1 and 2 -BEGAST_H= 'CmpMap ' / Compound Mapping -NIN_A = 2 / Number of input coordinates -ISSIMP_A= 1 / Mapping has been simplified -ISA_C = 'Mapping ' / Mapping between coordinate systems -MAPA_A = ' ' / First component Mapping -BEGAST_I= 'WinMap ' / Map one window on to another -NIN_B = 2 / Number of input coordinates -INVERT_A= 0 / Mapping not inverted -ISA_D = 'Mapping ' / Mapping between coordinate systems -SFT1_A = -893.6318379289 / Shift for axis 1 -SFT2_A = -223.8380193875 / Shift for axis 2 -ENDAST_G= 'WinMap ' / End of object definition -MAPB_A = ' ' / Second component Mapping -BEGAST_J= 'CmpMap ' / Compound Mapping -NIN_C = 2 / Number of input coordinates -ISA_E = 'Mapping ' / Mapping between coordinate systems -MAPA_B = ' ' / First component Mapping -BEGAST_K= 'MatrixMap' / Matrix transformation -NIN_D = 2 / Number of input coordinates -INVERT_B= 0 / Mapping not inverted -ISA_F = 'Mapping ' / Mapping between coordinate systems -M0_A = -3.25441534352674E-6/ Forward matrix value -M1_A = -1.60367292352974E-8/ Forward matrix value -M2_A = -1.812057487023E-8 / Forward matrix value -M3_A = 3.25725533992408E-6 / Forward matrix value -FORM_A = 'Full ' / Matrix storage form -ENDAST_H= 'MatrixMap' / End of object definition -MAPB_B = ' ' / Second component Mapping -BEGAST_L= 'CmpMap ' / Compound Mapping -NIN_E = 2 / Number of input coordinates -ISA_G = 'Mapping ' / Mapping between coordinate systems -INVA_A = 1 / First Mapping used in inverse direction -MAPA_C = ' ' / First component Mapping -BEGAST_M= 'WcsMap ' / FITS-WCS sky projection -NIN_F = 2 / Number of input coordinates -INVERT_C= 1 / Mapping inverted -ISA_H = 'Mapping ' / Mapping between coordinate systems -TYPE_A = 'TAN ' / Gnomonic projection -ENDAST_I= 'WcsMap ' / End of object definition -MAPB_C = ' ' / Second component Mapping -BEGAST_N= 'CmpMap ' / Compound Mapping -NIN_G = 2 / Number of input coordinates -ISA_I = 'Mapping ' / Mapping between coordinate systems -INVA_B = 1 / First Mapping used in inverse direction -MAPA_D = ' ' / First component Mapping -BEGAST_O= 'SphMap ' / Cartesian to Spherical mapping -NIN_H = 3 / Number of input coordinates -NOUT_A = 2 / Number of output coordinates -INVERT_D= 1 / Mapping inverted -ISA_J = 'Mapping ' / Mapping between coordinate systems -UNTRD_A = 1 / All input vectors have unit length -PLRLG_A = 0.0 / Polar longitude (rad.s) -ENDAST_J= 'SphMap ' / End of object definition -MAPB_D = ' ' / Second component Mapping -BEGAST_P= 'CmpMap ' / Compound Mapping -NIN_I = 3 / Number of input coordinates -NOUT_B = 2 / Number of output coordinates -ISA_K = 'Mapping ' / Mapping between coordinate systems -MAPA_E = ' ' / First component Mapping -BEGAST_Q= 'MatrixMap' / Matrix transformation -NIN_J = 3 / Number of input coordinates -INVERT_E= 0 / Mapping not inverted -ISA_L = 'Mapping ' / Mapping between coordinate systems -M0_B = -1.0 / Forward matrix value -M1_B = 1.0 / Forward matrix value -M2_B = -1.0 / Forward matrix value -FORM_B = 'Diagonal' / Matrix storage form -ENDAST_K= 'MatrixMap' / End of object definition -MAPB_E = ' ' / Second component Mapping -BEGAST_R= 'SphMap ' / Cartesian to Spherical mapping -NIN_K = 3 / Number of input coordinates -NOUT_C = 2 / Number of output coordinates -INVERT_F= 0 / Mapping not inverted -ISA_M = 'Mapping ' / Mapping between coordinate systems -UNTRD_B = 1 / All input vectors have unit length -PLRLG_B = 0.0 / Polar longitude (rad.s) -ENDAST_L= 'SphMap ' / End of object definition -ENDAST_M= 'CmpMap ' / End of object definition -ENDAST_N= 'CmpMap ' / End of object definition -ENDAST_O= 'CmpMap ' / End of object definition -ENDAST_P= 'CmpMap ' / End of object definition -ENDAST_Q= 'CmpMap ' / End of object definition -ENDAST_R= 'FrameSet' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for FrameSet object AST -COMMENT AST ---------------------------------------------------------------- AST - -ATTRIBUTES: - Colour(axis1) : 1 - Font(Stri) : 1 - Nout : 1 - Class : 4 - Tol : 0.100000E-01 - Gap(1) : .523599 - Border : 0 - Invert : 0 - TextLabGap : 0.100000E-01 - Nin : 2 - Current : 3 - Base : 1 - Nobject : 1 - RefCOUNT : 1 - -AST_GRID: -REG_LINE: 2 - 15.5 -136. - 15.4 -137. -REG_LINE: 2 - 18.6 -144. - 18.5 -146. -REG_LINE: 2 - 21.8 -149. - 21.8 -151. -REG_LINE: 2 - 25.1 -150. - 25.1 -154. -REG_LINE: 2 - 28.3 -149. - 28.4 -150. -REG_LINE: 2 - 31.5 -143. - 31.6 -145. -REG_LINE: 2 - 34.6 -135. - 34.7 -136. -REG_LINE: 2 - 37.6 -123. - 37.8 -127. -REG_LINE: 2 - 40.3 -108. - 40.4 -110. -REG_LINE: 2 - 42.7 -91.0 - 42.9 -92.7 -REG_LINE: 2 - 44.9 -71.2 - 45.2 -72.9 -REG_LINE: 2 - 46.7 -49.3 - 47.5 -53.0 -REG_LINE: 2 - 48.1 -25.8 - 48.6 -27.4 -REG_LINE: 2 - 49.2 -.928 - 49.9 -2.51 -REG_LINE: 2 - 49.8 24.8 - 51.0 23.5 -REG_LINE: 2 - 50.0 50.9 - 53.7 51.1 -REG_LINE: 2 - 49.7 77.1 - 50.9 78.4 -REG_LINE: 2 - 49.1 103. - 49.8 104. -REG_LINE: 2 - 48.0 127. - 48.5 129. -REG_LINE: 2 - 46.6 151. - 47.3 155. -REG_LINE: 2 - 44.7 173. - 45.0 174. -REG_LINE: 2 - 42.6 192. - 42.8 194. -REG_LINE: 2 - 40.1 209. - 40.2 211. -REG_LINE: 2 - 37.4 224. - 37.6 228. -REG_LINE: 2 - 34.4 235. - 34.5 237. -REG_LINE: 2 - 31.3 244. - 31.4 245. -REG_LINE: 2 - 28.1 248. - 28.1 250. -REG_LINE: 2 - 24.8 250. - 24.8 254. -REG_LINE: 2 - 21.6 248. - 21.5 250. -REG_LINE: 2 - 18.4 243. - 18.3 245. -REG_LINE: 2 - 15.3 234. - 15.2 236. -REG_LINE: 2 - 12.3 223. - 12.1 226. -REG_LINE: 2 - 9.62 208. - 9.45 210. -REG_LINE: 2 - 7.17 191. - 6.95 192. -REG_LINE: 2 - 5.02 171. - 4.74 173. -REG_LINE: 2 - 3.22 149. - 2.41 153. -REG_LINE: 2 - 1.78 125. - 1.27 127. -REG_LINE: 2 - .747 101. - -0.657E-02 102. -REG_LINE: 2 - .124 74.8 - -1.11 76.1 -REG_LINE: 2 - -0.740E-01 48.7 - -3.82 48.5 -REG_LINE: 2 - .156 22.6 - -1.02 21.3 -REG_LINE: 2 - .811 -3.08 - 0.841E-01 -4.67 -REG_LINE: 2 - 1.88 -27.8 - 1.38 -29.5 -REG_LINE: 2 - 3.34 -51.3 - 2.56 -54.9 -REG_LINE: 2 - 5.17 -73.0 - 4.89 -74.7 -REG_LINE: 2 - 7.34 -92.6 - 7.13 -94.3 -REG_LINE: 2 - 9.81 -110. - 9.65 -111. -REG_LINE: 2 - 12.5 -124. - 12.3 -128. -REG_LINE: 2 - 15.5 -136. - 15.4 -137. -REG_LINE: 2 - 18.6 -144. - 18.5 -146. -REG_LINE: 2 - 21.8 -149. - 21.8 -151. -REG_LINE: 2 - 25.1 -150. - 25.1 -154. -REG_LINE: 2 - 28.3 -149. - 28.4 -150. -REG_LINE: 2 - 31.5 -143. - 31.6 -145. -REG_LINE: 2 - 34.6 -135. - 34.7 -136. -REG_LINE: 2 - 24.9 74.8 - 26.5 75.6 -REG_LINE: 2 - 24.9 99.9 - 26.5 101. -REG_LINE: 2 - 24.9 125. - 26.5 126. -REG_LINE: 2 - 24.9 150. - 28.3 152. -REG_LINE: 2 - 24.9 175. - 26.5 176. -REG_LINE: 2 - 24.9 200. - 26.4 201. -REG_LINE: 2 - 24.8 225. - 26.4 226. -REG_LINE: 2 - 24.8 250. - 28.2 252. -REG_LINE: 2 - 24.8 275. - 26.4 276. -REG_LINE: 15 - 25.1 -150. - 24.1 -150. - 23.2 -150. - 22.3 -149. - 21.3 -148. - 20.4 -147. - 19.5 -146. - 18.6 -144. - 17.7 -142. - 16.8 -140. - 15.9 -137. - 15.1 -134. - 14.2 -131. - 13.4 -128. - 12.5 -124. -REG_LINE: 15 - 25.1 -150. - 26.0 -150. - 26.9 -150. - 27.9 -149. - 28.8 -148. - 29.7 -147. - 30.6 -145. - 31.5 -143. - 32.4 -141. - 33.3 -139. - 34.2 -136. - 35.1 -133. - 35.9 -130. - 36.7 -127. - 37.6 -123. -REG_LINE: 15 - 37.6 -123. - 38.4 -119. - 39.1 -115. - 39.9 -111. - 40.6 -106. - 41.4 -101. - 42.1 -96.2 - 42.7 -91.0 - 43.4 -85.6 - 44.0 -79.9 - 44.6 -74.2 - 45.2 -68.2 - 45.7 -62.1 - 46.2 -55.8 - 46.7 -49.3 -REG_LINE: 15 - 46.7 -49.3 - 47.1 -42.8 - 47.5 -36.1 - 47.9 -29.2 - 48.3 -22.3 - 48.6 -15.3 - 48.9 -8.13 - 49.2 -.928 - 49.4 6.35 - 49.6 13.7 - 49.7 21.1 - 49.8 28.5 - 49.9 36.0 - 50.0 43.4 - 50.0 50.9 -REG_LINE: 15 - 50.0 50.9 - 49.9 58.4 - 49.9 65.9 - 49.8 73.3 - 49.7 80.8 - 49.5 88.1 - 49.3 95.5 - 49.1 103. - 48.8 110. - 48.5 117. - 48.2 124. - 47.8 131. - 47.4 138. - 47.0 144. - 46.6 151. -REG_LINE: 15 - 46.6 151. - 46.1 157. - 45.6 164. - 45.0 170. - 44.4 176. - 43.8 181. - 43.2 187. - 42.6 192. - 41.9 197. - 41.2 202. - 40.5 207. - 39.7 212. - 38.9 216. - 38.2 220. - 37.4 224. -REG_LINE: 15 - 37.4 224. - 36.5 227. - 35.7 231. - 34.8 234. - 34.0 237. - 33.1 239. - 32.2 241. - 31.3 244. - 30.4 245. - 29.5 247. - 28.6 248. - 27.6 249. - 26.7 250. - 25.8 250. - 24.8 250. -REG_LINE: 15 - 24.8 250. - 23.9 250. - 23.0 249. - 22.0 249. - 21.1 248. - 20.2 246. - 19.3 245. - 18.4 243. - 17.5 241. - 16.6 238. - 15.7 236. - 14.8 233. - 14.0 230. - 13.1 226. - 12.3 223. -REG_LINE: 15 - 12.3 223. - 11.5 219. - 10.8 215. - 9.99 210. - 9.25 206. - 8.53 201. - 7.84 196. - 7.17 191. - 6.52 185. - 5.90 180. - 5.31 174. - 4.74 168. - 4.20 162. - 3.70 155. - 3.22 149. -REG_LINE: 15 - 3.22 149. - 2.77 142. - 2.35 136. - 1.96 129. - 1.61 122. - 1.29 115. - 1.00 108. - .747 101. - .526 93.3 - .339 85.9 - .187 78.6 - 0.696E-01 71.1 - -0.132E-01 63.7 - -0.611E-01 56.2 - -0.740E-01 48.7 -REG_LINE: 15 - -0.740E-01 48.7 - -0.519E-01 41.2 - 0.519E-02 33.7 - 0.971E-01 26.3 - .224 18.9 - .385 11.5 - .581 4.18 - .811 -3.08 - 1.07 -10.3 - 1.37 -17.4 - 1.70 -24.4 - 2.06 -31.3 - 2.46 -38.1 - 2.88 -44.7 - 3.34 -51.3 -REG_LINE: 15 - 3.34 -51.3 - 3.83 -57.7 - 4.34 -63.9 - 4.89 -70.0 - 5.46 -75.9 - 6.06 -81.6 - 6.69 -87.2 - 7.34 -92.6 - 8.02 -97.7 - 8.72 -103. - 9.44 -107. - 10.2 -112. - 11.0 -116. - 11.7 -120. - 12.5 -124. -REG_LINE: 15 - 12.5 -124. - 13.4 -128. - 14.2 -131. - 15.1 -134. - 15.9 -137. - 16.8 -140. - 17.7 -142. - 18.6 -144. - 19.5 -146. - 20.4 -147. - 21.3 -148. - 22.3 -149. - 23.2 -150. - 24.1 -150. - 25.1 -150. -REG_LINE: 15 - 25.1 -150. - 26.0 -150. - 26.9 -150. - 27.9 -149. - 28.8 -148. - 29.7 -147. - 30.6 -145. - 31.5 -143. - 32.4 -141. - 33.3 -139. - 34.2 -136. - 35.1 -133. - 35.9 -130. - 36.7 -127. - 37.6 -123. -REG_LINE: 15 - 25.1 -150. - 26.0 -150. - 26.9 -150. - 27.9 -149. - 28.8 -148. - 29.7 -147. - 30.6 -145. - 31.5 -143. - 32.4 -141. - 33.3 -139. - 34.2 -136. - 35.1 -133. - 35.9 -130. - 36.7 -127. - 37.6 -123. -REG_LINE: 15 - 24.9 49.8 - 24.9 57.0 - 24.9 64.1 - 24.9 71.3 - 24.9 78.4 - 24.9 85.6 - 24.9 92.7 - 24.9 99.9 - 24.9 107. - 24.9 114. - 24.9 121. - 24.9 128. - 24.9 136. - 24.9 143. - 24.9 150. -REG_LINE: 15 - 24.9 150. - 24.9 157. - 24.9 164. - 24.9 171. - 24.9 179. - 24.9 186. - 24.9 193. - 24.9 200. - 24.9 207. - 24.8 214. - 24.8 221. - 24.8 229. - 24.8 236. - 24.8 243. - 24.8 250. -REG_LINE: 8 - 24.8 250. - 24.8 257. - 24.8 264. - 24.8 272. - 24.8 279. - 24.8 286. - 24.8 293. - 24.8 300. -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '12' - 24.9 -148. BC -0.654E-01 .998 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '14' - 35.1 -123. BC -.978 .210 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '16' - 44.2 -49.2 BC -.997 0.716E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '18' - 47.5 50.9 BC -1.00 -0.942E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '20' - 44.1 151. TC .997 0.732E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '22' - 34.9 223. TC .977 .213 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0' - 24.9 248. TC -0.236E-01 1.00 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '2' - 14.8 222. TC -.978 .210 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '4' - 5.71 149. TC -.997 0.716E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '6' - 2.43 48.7 BC 1.00 0.288E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '8' - 5.83 -51.1 BC .997 0.732E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '10' - 15.0 -124. BC .977 .215 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-90:00' - 22.4 49.8 BC -1.00 -0.615E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '59' - 22.4 150. BC -1.00 -0.615E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-89:58' - 22.3 250. BC -1.00 -0.615E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 1 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: ' A FITS test' - 30.9 313. BC .000 1.00 -ude (rad.s) - End SphMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -1 # Forward matrix value - M1 = 1 # Forward matrix value - M2 = -1 # Forward matrix value - Form = "Diagonal" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitude (rad.s) - End SphMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End FrameSet diff --git a/ast/ast_tester/regression.f b/ast/ast_tester/regression.f deleted file mode 100644 index e9ca32e..0000000 --- a/ast/ast_tester/regression.f +++ /dev/null @@ -1,1515 +0,0 @@ - PROGRAM REGRESSION -*+ -* Name: -* REGRESSION - -* Purpose: -* Tests many aspects of the AST library (Fortran interface). - -* Language: -* Starlink Fortran 77 - -* Type of Module: -* Fortran program - -* Invocation: -* regression - -* Description: -* This application utilizes many aspects of the AST library, producing -* textual output on standard output. The output should be redirected -* to a text file and compared to the output from previous runs to -* detect any changes in functionality. - -* Authors: -* DSB: David Berry (STARLINK) -* {enter_new_authors_here} - -* History: -* 29-JAN-2002 (DSB): -* Original version. -* {enter_further_changes_here} - -*- - -* Type Definitions: - IMPLICIT NONE ! No implicit typing - -* Global Variables: - INTEGER CMN_FTEST ! Which FITS test are we doing? - INTEGER CMN_LINE ! The index of the next header to read - COMMON /REG/ CMN_FTEST, CMN_LINE - -* Global Constants: - INCLUDE 'SAE_PAR' ! Standard SAE constants - INCLUDE 'AST_PAR' ! AST constants and declarations - -* Status: - INTEGER STATUS ! Global status - -* External References: - INTEGER CHR_LEN - - EXTERNAL REG_SOURCE - EXTERNAL REG_SINK - - EXTERNAL REG_ATTR - EXTERNAL REG_FLUSH - EXTERNAL REG_LINE - EXTERNAL REG_MARK - EXTERNAL REG_TEXT - EXTERNAL REG_TXEXT - EXTERNAL REG_CAP - EXTERNAL REG_QCH - EXTERNAL REG_SCALES - -* Local Constants: - INTEGER NFITS_TESTS ! How many FITS tests? - PARAMETER ( NFITS_TESTS = 3 ) - - INTEGER NCAT, NRAT, NLAT, NDAT, NIAT ! Numbers of Attributes of each type - PARAMETER ( NCAT = 4, - : NRAT = 2, - : NLAT = 2, - : NDAT = 1, - : NIAT = 5 ) - -* Local Variables: - CHARACTER ATTRS( NFITS_TESTS )*255 ! Plot attributes for each FITS test - CHARACTER CARDS*(7*80) ! Used fot testing ast_putcards - INTEGER FC, FS, PLOT, I, J, OC - - REAL GBOX( 4 ) ! Area of graphics coords to use - DOUBLE PRECISION BBOX( 4, NFITS_TESTS ) ! Base Frame area to be - ! mapped onto GBOX for each FITS test - - CHARACTER*20 CAT(NCAT), RAT(NRAT), LAT(NLAT), DAT(NDAT), IAT(NIAT) - CHARACTER CV*50 - REAL RV - LOGICAL LV - DOUBLE PRECISION DV - INTEGER IV, VERS, MAJ, MIN, REV - -* Data initialization: - DATA CAT / 'Colour(axis1)', 'Font(Stri)', 'Nout', 'Class' / - DATA RAT / 'Tol', 'Gap(1)' / - DATA LAT / 'Border', 'Invert' / - DATA DAT / 'TextLabGap' / - DATA IAT / 'Nin', 'Current', 'Base', 'Nobject', 'RefCOUNT' / - DATA GBOX /-100.0, -200.0, 150.0, 300.0/ - - - - DATA BBOX / 10.0, -10.0, 290.0, 300.0, - : -300.0, -300.0, 500.0, 500.0, - : 1.0, 1.0, 1787.0, 447.0 / - - - - DATA ATTRS/ 'Grid=1,tickall=0', - : 'Grid=1,labelling=interior', - : 'Grid=0' / - - -*. - -* Initialize inherited global status. - STATUS = SAI__OK - -* Use object caching to minimise allocation of new memory - OC = AST_TUNE( 'ObjectCaching', 1, STATUS ) - IF( OC .NE. 0 ) THEN - WRITE(*,'(A,I2)') 'Default ObjectCaching VALUE is ',OC - END IF - - IF( AST_TUNE( 'ObjectCaching', AST__TUNULL, STATUS ) .NE. 1 ) THEN - WRITE(*,'(A,I2)') 'Set ObjectCaching VALUE is ',OC - END IF - -* Display the AST version number. - VERS = AST_VERSION() - MAJ = VERS/1000000 - VERS = VERS - 1000000*MAJ - MIN = VERS/1000 - REV = VERS - 1000*MIN - WRITE(*,'(A,I2,A,I1,A,I2)') 'AST version ',MAJ,'.',MIN,'-',REV - -* First do a test of the AST_PUTCARDS routine. - FC = AST_FITSCHAN( AST_NULL, AST_NULL, ' ', STATUS ) - - CARDS = 'NAXIS = 1' - CARDS( 81: ) = 'NAXIS1 = 100' - CARDS( 2*80 + 1: ) = 'CTYPE1 = ''fred''' - CARDS( 3*80 + 1: ) = 'CDELT1 = 0.0' - CARDS( 4*80 + 1: ) = 'CRPIX1 = 50' - CARDS( 5*80 + 1: ) = 'CUNIT1 = ''GHz''' - - CALL AST_PUTCARDS( FC, CARDS, STATUS ) - WRITE(*,'(A,I2)') 'PutCards Ncards = ',AST_GETI( FC, 'NCARD', - : STATUS ) - WRITE(*,'(A,I2)') 'PutCards Card = ',AST_GETI( FC, 'CARD', - : STATUS ) - - CALL AST_SETI( FC, 'CARD', 10, STATUS ) - WRITE(*,'(A,I2)') 'PutCards Card = ',AST_GETI( FC, 'CARD', - : STATUS ) - - CALL AST_PUTCARDS( FC, CARDS, STATUS ) - WRITE(*,'(A,I2)') 'PutCards Ncards = ',AST_GETI( FC, 'NCARD', - : STATUS ) - WRITE(*,'(A,I2)') 'PutCards Card = ',AST_GETI( FC, 'CARD', - : STATUS ) - CALL AST_SHOW( FC, STATUS ) - -* We loop round testing several sorts of FITS Headers. - DO I = 1, NFITS_TESTS - IF ( STATUS .NE. SAI__OK ) GO TO 999 - -* Tell the REG_SOURCE function which FITS header to load. - CMN_FTEST = I - CMN_LINE = 1 - - WRITE(*,'(A)') ' ' - WRITE(*,'(A)') ' ' - WRITE(*,'(A)') ' ' - WRITE(*,'(A)') ' ' - WRITE(*,'(A,I2)') ' FITS test number ',I - WRITE(*,'(A)') ' ====================' - WRITE(*,'(A)') ' ' - WRITE(*,'(A)') ' ' - -* Create a FitsChan, read an Object from it, and dump the Object -* to standard output. The Object should be a FrameSet if all is OK. - FC = AST_FITSCHAN( REG_SOURCE, REG_SINK, ' ', STATUS ) - FS = AST_READ( FC, STATUS ) - WRITE(*,'(A)') ' ' - WRITE(*,'(A)') 'AST_SHOW:' - CALL AST_SHOW( FS, STATUS ) - -* Annul the FitsChan. This will cause the unused contents (if any) to -* be written out using REG_SINK. - WRITE(*,'(A)') ' ' - WRITE(*,'(A)') 'REG_SINK:' - CALL AST_ANNUL( FC, STATUS ) - -* Create another FrameSet with Native encoding. Write the FrameSet to -* it, and then annul the FitsChan (this will cause the FITS cards to be -* written to stdout). - FC = AST_FITSCHAN( AST_NULL, REG_SINK, 'Encoding=native', - : STATUS ) - WRITE(*,'(A)') ' ' - WRITE(*,'(A,I2)') 'Objects written: ', AST_WRITE( FC, FS, - : STATUS ) - WRITE(*,'(A)') ' ' - WRITE(*,'(A)') 'Native Encoding:' - CALL AST_ANNUL( FC, STATUS ) - -* Create a Plot which maps the area specified by BBOX the Base Frame -* of the FrameSet onto the GBOX area in graphics coords. - PLOT = AST_PLOT( FS, GBOX, BBOX( 1, I), ' grf = 1 , '// - : 'title = A FITS test', STATUS ) - -* Annul the FrameSet. - CALL AST_ANNUL( FS, STATUS ) - -* Tell the Plot to use the REG_... routines included in this file to -* do the drawing. - CALL AST_GRFSET( PLOT, 'Attr', REG_ATTR, STATUS ) - CALL AST_GRFSET( PLOT, 'Flush', REG_FLUSH, STATUS ) - CALL AST_GRFSET( PLOT, 'Line', REG_LINE, STATUS ) - CALL AST_GRFSET( PLOT, 'Mark', REG_MARK, STATUS ) - CALL AST_GRFSET( PLOT, 'Text', REG_TEXT, STATUS ) - CALL AST_GRFSET( PLOT, 'TxExt', REG_TXEXT, STATUS ) - CALL AST_GRFSET( PLOT, 'Scales', REG_SCALES, STATUS ) - CALL AST_GRFSET( PLOT, 'Cap', REG_CAP, STATUS ) - CALL AST_GRFSET( PLOT, 'Qch', REG_QCH, STATUS ) - -* Set some attributes. - CALL AST_SET( PLOT, ATTRS( I ), STATUS ) - -* Get some attributes (separate the AST_GET calls and the WRITEs in order -* to avoid recursive I/O due to the REG_xxx routines trying to write to -* standard output). - WRITE(*,'(A)') ' ' - WRITE(*,'(A)') 'ATTRIBUTES:' - - DO J = 1, NCAT - CV = AST_GETC( PLOT, CAT(J), STATUS ) - WRITE(*,'(A,I10)') ' '//CAT(J)//': ',CHR_LEN(CV) - END DO - - DO J = 1, NRAT - RV = AST_GETR( PLOT, RAT(J), STATUS ) - WRITE(*,'(A,G13.6)') ' '//RAT(J)//': ',RV - END DO - - DO J = 1, NLAT - LV = AST_GETL( PLOT, LAT(J), STATUS ) - IF( LV ) THEN - IV = 1 - ELSE - IV = 0 - END IF - WRITE(*,'(A,I1)') ' '//LAT(J)//': ',IV - END DO - - DO J = 1, NDAT - DV = AST_GETD( PLOT, DAT(J), STATUS ) - WRITE(*,'(A,G13.6)') ' '//DAT(J)//': ',DV - END DO - - DO J = 1, NIAT - IV = AST_GETI( PLOT, IAT(J), STATUS ) - WRITE(*,'(A,I4)') ' '//IAT(J)//': ',IV - END DO - - -* Draw a grid. - WRITE(*,'(A)') ' ' - WRITE(*,'(A)') 'AST_GRID:' - CALL AST_GRID( PLOT, STATUS ) - -* Annul the Plot. - CALL AST_ANNUL( PLOT, STATUS ) - - END DO - - 999 CONTINUE - - END - - - - - -* Grf plotting routines for the Plot tests. These are used in preference -* to the grf routines specified at link time. -* ====================================================================== - -* Flush graphics. -* --------------- - INTEGER FUNCTION REG_FLUSH() - WRITE(*,'(A)') 'REG_FLUSH:' - REG_FLUSH = 1 - END - -* Set or get a Plot graphics attribute. -* ------------------------------------- - INTEGER FUNCTION REG_ATTR( ATT, VAL, OLDVAL, PRIM ) - IMPLICIT NONE - -* Includes: - INCLUDE 'AST_PAR' - INCLUDE 'GRF_PAR' - -* Arguments: - INTEGER ATT - DOUBLE PRECISION VAL - INTEGER PRIM - DOUBLE PRECISION OLDVAL - -* Local Variables: - INTEGER I, J - DOUBLE PRECISION ATTRS( 5, 3 ) - -* Initialization: - DATA ATTRS /15*0.0D0/ - -* Log this call. - WRITE(*,'(I4,1X,G10.3,1X,I4)') 'REG_GATTR: ', ATT, VAL, PRIM - -* Identify the required element. - IF( ATT .EQ. GRF__STYLE ) THEN - I = 1 - ELSE IF( ATT .EQ. GRF__WIDTH ) THEN - I = 2 - ELSE IF( ATT .EQ. GRF__SIZE ) THEN - I = 3 - ELSE IF( ATT .EQ. GRF__FONT ) THEN - I = 4 - ELSE IF( ATT .EQ. GRF__COLOUR ) THEN - I = 5 - ELSE - WRITE(*,'(A,I2)') 'Bad ATT value: ', ATT - END IF - - IF( PRIM .EQ. GRF__LINE ) THEN - J = 1 - ELSE IF( PRIM .EQ. GRF__MARK ) THEN - J = 2 - ELSE IF( PRIM .EQ. GRF__TEXT ) THEN - J = 3 - ELSE - WRITE(*,'(A,I2)') 'Bad PRIM value: ', PRIM - END IF - -* Return the old value. - OLDVAL = ATTRS( I, J ) - -* Store the new value if not bad. - IF( VAL .NE. AST__BAD ) ATTRS( I, J ) = VAL - -* Initialize the returned value to indicate success. - REG_ATTR = 1 - - END - - -* Draw a polyline. -* ---------------- - INTEGER FUNCTION REG_LINE( N, X, Y ) - IMPLICIT NONE - - INTEGER N - REAL X( N ) - REAL Y( N ) - INTEGER I - - WRITE(*,'(A,I4)') 'REG_LINE: ',N - DO I = 1, N - WRITE(*,'(3X,G10.3,1X,G10.3)') X(I),Y(I) - END DO - - REG_LINE = 1 - END - -* Draw a set of markers. -* ---------------------- - INTEGER FUNCTION REG_MARK( N, X, Y, TYPE ) - IMPLICIT NONE - - INTEGER N, TYPE - REAL X( N ) - REAL Y( N ) - INTEGER I - - WRITE(*,'(A,I4,I2)') 'REG_MARK: ', N, TYPE - DO I = 1, N - WRITE(*,'(3X,G10.3,1X,G10.3)') X(I),Y(I) - END DO - - REG_MARK = 1 - END - -* Draw a text string. -* ------------------- - INTEGER FUNCTION REG_TEXT( TEXT, X, Y, JUST, UPX, UPY ) - IMPLICIT NONE - - CHARACTER TEXT*(*), JUST*(*) - REAL X, Y, UPX, UPY - - WRITE(*,'(A,A,A)') 'REG_TEXT: ''', TEXT,'''' - WRITE(*,'(3X,G10.3,1X,G10.3,1X,A,1X,G10.3,1X,G10.3)') - : X, Y, JUST, UPX, UPY - - REG_TEXT = 1 - END - -* Return the extent of a text string. -* -* For some reason, the arguments to this function seem particularly -* prone to random rounding errors, resulting in the regression test -* always failing when run twice in succession, even if not changes -* have been made to the code in plot.c. For this reason this function -* does not write out its argument to standard output. -* -------------------------------------------------------------------- - INTEGER FUNCTION REG_TXEXT( TEXT, X, Y, JUST, UPX, UPY, XB, YB ) - IMPLICIT NONE - - CHARACTER TEXT*(*), JUST*(*) - REAL X, Y, UPX, UPY, XB(4), YB(4) - -c WRITE(*,*) 'REG_TXEXT: ''', TEXT,'''' -c WRITE(*,*) ' ', X, Y, ' ''', JUST,''' ', UPX, UPY - - XB( 1 ) = X - LEN( TEXT )*0.5 - XB( 2 ) = X + LEN( TEXT )*0.5 - XB( 3 ) = XB( 2 ) - XB( 4 ) = XB( 1 ) - - YB( 1 ) = Y - 0.5 - YB( 2 ) = YB( 1 ) - YB( 3 ) = Y + 0.5 - YB( 4 ) = YB( 3 ) - - REG_TXEXT = 1 - END - -* Inquire a capability -* --------------------- - INTEGER FUNCTION REG_CAP( CAP, VALUE ) - IMPLICIT NONE - - INCLUDE 'GRF_PAR' - - INTEGER CAP, VALUE - - WRITE(*,'(A,I2)') 'REG_CAP: ', CAP - - REG_CAP = 0 - IF( CAP .EQ. GRF__SCALES ) REG_CAP = 1 - - END - -* Inquire axis scales -* --------------------- - INTEGER FUNCTION REG_SCALES( ALPHA, BETA ) - IMPLICIT NONE - REAL ALPHA, BETA - - WRITE(*,'(A)') 'REG_SCALES: ' - - ALPHA = 1.0 - BETA = 1.0 - - REG_SCALES = 1 - - END - -* Inquire character size -* ---------------------- - INTEGER FUNCTION REG_QCH( CHV, CHH ) - IMPLICIT NONE - REAL CHV, CHH - - WRITE(*,'(A)') 'REG_QCH: ' - - CHV = 0.01 - CHH = 0.01 - - REG_QCH = 1 - - END - - - -* A Sink funtion for use with the FitsChan class. It writes the FitsChan -* contents to standard output. -* ====================================================================== - SUBROUTINE REG_SINK( CARD, STATUS ) - IMPLICIT NONE - CHARACTER CARD*80 - INTEGER STATUS - WRITE(*,'(A)') CARD - END - - - -* A Source funtion for use with the FitsChan class. It returns a different -* header for each value of REG_FTEST. -* ====================================================================== - INTEGER FUNCTION REG_SOURCE( CARD, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - - INTEGER CMN_FTEST ! Which FITS test are we doing? - INTEGER CMN_LINE ! The index of the next header to read - COMMON /REG/ CMN_FTEST, CMN_LINE - - CHARACTER CARD*80 - INTEGER STATUS - -* Check the inherited status - REG_SOURCE = 0 - IF( STATUS .NE. SAI__OK ) RETURN - -* Assume more cards will be returned. - REG_SOURCE = 1 - -* The following code defines the FITS headers and is generated automatically -* from FITS header files using script make_regtest (in the AST development -* system).... - - -* FITS headers from cobe.head (Tue Jan 29 13:37:07 2002) - IF( CMN_FTEST .EQ. 1 ) THEN - IF( CMN_LINE .EQ. 1 ) THEN - CARD = 'SIMPLE = T / Written by I'// - : 'DL: 30-Jul-1997 05:35:42.00' - ELSE IF( CMN_LINE .EQ. 2 ) THEN - CARD = 'BITPIX = -32 / Bits per pix'// - : 'el.' - ELSE IF( CMN_LINE .EQ. 3 ) THEN - CARD = 'NAXIS = 2 / Number of di'// - : 'mensions' - ELSE IF( CMN_LINE .EQ. 4 ) THEN - CARD = 'NAXIS1 = 300 / Length of x '// - : 'axis.' - ELSE IF( CMN_LINE .EQ. 5 ) THEN - CARD = 'NAXIS2 = 300 / Length of y '// - : 'axis.' - ELSE IF( CMN_LINE .EQ. 6 ) THEN - CARD = 'CTYPE1 = ''GLON-ZEA'' / X-axis typ'// - : 'e' - ELSE IF( CMN_LINE .EQ. 7 ) THEN - CARD = 'CTYPE2 = ''GLAT-ZEA'' / Y-axis typ'// - : 'e' - ELSE IF( CMN_LINE .EQ. 8 ) THEN - CARD = 'CRVAL1 = -149.56866 / Reference pi'// - : 'xel value' - ELSE IF( CMN_LINE .EQ. 9 ) THEN - CARD = 'CRVAL2 = -19.758201 / Reference pi'// - : 'xel value' - ELSE IF( CMN_LINE .EQ. 10 ) THEN - CARD = 'CRPIX1 = 150.500 / Reference pi'// - : 'xel' - ELSE IF( CMN_LINE .EQ. 11 ) THEN - CARD = 'CRPIX2 = 150.500 / Reference pi'// - : 'xel' - ELSE IF( CMN_LINE .EQ. 12 ) THEN - CARD = 'CDELT1 = -1.20000 / Degrees/pixe'// - : 'l' - ELSE IF( CMN_LINE .EQ. 13 ) THEN - CARD = 'CDELT2 = 1.20000 / Degrees/pixe'// - : 'l' - ELSE IF( CMN_LINE .EQ. 14 ) THEN - CARD = 'CROTA1 = 0.00000 / Rotation in '// - : 'degrees.' - ELSE IF( CMN_LINE .EQ. 15 ) THEN - CARD = 'COMMENT' - ELSE IF( CMN_LINE .EQ. 16 ) THEN - CARD = 'COMMENT This file was produced by the SkyView'// - : ' survey analysis system from' - ELSE IF( CMN_LINE .EQ. 17 ) THEN - CARD = 'COMMENT available astronomical surveys. The '// - : 'data are formatted' - ELSE IF( CMN_LINE .EQ. 18 ) THEN - CARD = 'COMMENT as a simple two-dimensional FITS imag'// - : 'e with the same units as' - ELSE IF( CMN_LINE .EQ. 19 ) THEN - CARD = 'COMMENT the orginal survey. A single ASCII t'// - : 'able extension may be present' - ELSE IF( CMN_LINE .EQ. 20 ) THEN - CARD = 'COMMENT which describes catalog objects found'// - : ' within the field of view.' - ELSE IF( CMN_LINE .EQ. 21 ) THEN - CARD = 'COMMENT Copies of relevant copyright notices '// - : 'are included in this file.' - ELSE IF( CMN_LINE .EQ. 22 ) THEN - CARD = 'COMMENT' - ELSE IF( CMN_LINE .EQ. 23 ) THEN - CARD = 'COMMENT Questions should be directed to:' - ELSE IF( CMN_LINE .EQ. 24 ) THEN - CARD = 'COMMENT' - ELSE IF( CMN_LINE .EQ. 25 ) THEN - CARD = 'COMMENT scollick@skyview.gsfc.nasa.gov' - ELSE IF( CMN_LINE .EQ. 26 ) THEN - CARD = 'COMMENT or' - ELSE IF( CMN_LINE .EQ. 27 ) THEN - CARD = 'COMMENT mcglynn@grossc.gsfc.nasa.gov' - ELSE IF( CMN_LINE .EQ. 28 ) THEN - CARD = 'COMMENT' - ELSE IF( CMN_LINE .EQ. 29 ) THEN - CARD = 'COMMENT SkyView' - ELSE IF( CMN_LINE .EQ. 30 ) THEN - CARD = 'COMMENT Code 668.1' - ELSE IF( CMN_LINE .EQ. 31 ) THEN - CARD = 'COMMENT Goddard Space Flight Center, Gree'// - : 'nbelt, MD 20771' - ELSE IF( CMN_LINE .EQ. 32 ) THEN - CARD = 'COMMENT 301-286-7780' - ELSE IF( CMN_LINE .EQ. 33 ) THEN - CARD = 'COMMENT' - ELSE IF( CMN_LINE .EQ. 34 ) THEN - CARD = 'COMMENT SkyView is supported by NASA ADP gran'// - : 't NAS 5-32068.' - ELSE IF( CMN_LINE .EQ. 35 ) THEN - CARD = 'COMMENT' - ELSE IF( CMN_LINE .EQ. 36 ) THEN - CARD = 'SURVEY = ''COBE DIRBE''' - ELSE IF( CMN_LINE .EQ. 37 ) THEN - CARD = 'BUNITS = ''MJy/sr '' /' - ELSE IF( CMN_LINE .EQ. 38 ) THEN - CARD = 'ORIGIN = ''CDAC '' / Cosmology '// - : 'Data Analysis Center' - ELSE IF( CMN_LINE .EQ. 39 ) THEN - CARD = 'TELESCOP= ''COBE '' / COsmic Bac'// - : 'kground Explorer satellite' - ELSE IF( CMN_LINE .EQ. 40 ) THEN - CARD = 'INSTRUME= ''DIRBE '' / COBE instr'// - : 'ument [DIRBE, DMR, FIRAS]' - ELSE IF( CMN_LINE .EQ. 41 ) THEN - CARD = 'PIXRESOL= 9 / Quad tree pi'// - : 'xel resolution [6, 9]' - ELSE IF( CMN_LINE .EQ. 42 ) THEN - CARD = 'DATE = ''27/09/94'' / FITS file '// - : 'creation date (dd/mm/yy)' - ELSE IF( CMN_LINE .EQ. 43 ) THEN - CARD = 'DATE-MAP= ''16/09/94'' / Date of or'// - : 'iginal file creation (dd/mm/yy)' - ELSE IF( CMN_LINE .EQ. 44 ) THEN - CARD = 'COMMENT COBE specific keywords' - ELSE IF( CMN_LINE .EQ. 45 ) THEN - CARD = 'DATE-BEG= ''08/12/89'' / date of in'// - : 'itial data represented (dd/mm/yy)' - ELSE IF( CMN_LINE .EQ. 46 ) THEN - CARD = 'DATE-END= ''25/09/90'' / date of fi'// - : 'nal data represented (dd/mm/yy)' - ELSE IF( CMN_LINE .EQ. 47 ) THEN - CARD = 'COMMENT' - ELSE IF( CMN_LINE .EQ. 48 ) THEN - CARD = 'COMMENT THE COBE DIRBE map is a combination o'// - : 'f the original ten' - ELSE IF( CMN_LINE .EQ. 49 ) THEN - CARD = 'COMMENT band passes with the following wavele'// - : 'ngths:' - ELSE IF( CMN_LINE .EQ. 50 ) THEN - CARD = 'COMMENT Band 1 - 1.25 microns' - ELSE IF( CMN_LINE .EQ. 51 ) THEN - CARD = 'COMMENT Band 2 - 2.2 microns' - ELSE IF( CMN_LINE .EQ. 52 ) THEN - CARD = 'COMMENT Band 3 - 3.5 microns' - ELSE IF( CMN_LINE .EQ. 53 ) THEN - CARD = 'COMMENT Band 4 - 4.9 microns' - ELSE IF( CMN_LINE .EQ. 54 ) THEN - CARD = 'COMMENT Band 5 - 12 microns' - ELSE IF( CMN_LINE .EQ. 55 ) THEN - CARD = 'COMMENT Band 6 - 25 microns' - ELSE IF( CMN_LINE .EQ. 56 ) THEN - CARD = 'COMMENT Band 7 - 60 microns' - ELSE IF( CMN_LINE .EQ. 57 ) THEN - CARD = 'COMMENT Band 8 - 100 microns' - ELSE IF( CMN_LINE .EQ. 58 ) THEN - CARD = 'COMMENT Band 9 - 140 microns' - ELSE IF( CMN_LINE .EQ. 59 ) THEN - CARD = 'COMMENT Band 10 - 240 microns' - ELSE IF( CMN_LINE .EQ. 60 ) THEN - CARD = 'COMMENT' - ELSE IF( CMN_LINE .EQ. 61 ) THEN - CARD = 'END' - REG_SOURCE = 0 - ELSE - REG_SOURCE = 0 - END IF - -* FITS headers from polco.head (Tue Jan 29 15:06:35 2002) - ELSE IF( CMN_FTEST .EQ. 2 ) THEN - IF( CMN_LINE .EQ. 1 ) THEN - CARD = 'COMMENT AST +++++++++++++++++++++++++++++++++'// - : '+++++++++++++++++++++++++++++++' - ELSE IF( CMN_LINE .EQ. 2 ) THEN - CARD = 'AST' - ELSE IF( CMN_LINE .EQ. 3 ) THEN - CARD = 'COMMENT AST Beginning of AST data '// - : 'for FrameSet object' - ELSE IF( CMN_LINE .EQ. 4 ) THEN - CARD = 'AST' - ELSE IF( CMN_LINE .EQ. 5 ) THEN - CARD = 'COMMENT AST .................................'// - : '...............................' - ELSE IF( CMN_LINE .EQ. 6 ) THEN - CARD = 'AST' - ELSE IF( CMN_LINE .EQ. 7 ) THEN - CARD = 'BEGAST_A= ''FrameSet'' / Set of int'// - : 'er-related coordinate systems' - ELSE IF( CMN_LINE .EQ. 8 ) THEN - CARD = 'NFRAME_A= 2 / Number of Fr'// - : 'ames in FrameSet' - ELSE IF( CMN_LINE .EQ. 9 ) THEN - CARD = 'CURRNT_A= 2 / Index of cur'// - : 'rent Frame' - ELSE IF( CMN_LINE .EQ. 10 ) THEN - CARD = 'NOD1_A = 2 / Frame 1 is a'// - : 'ssociated with node 2' - ELSE IF( CMN_LINE .EQ. 11 ) THEN - CARD = 'NOD2_A = 1 / Frame 2 is a'// - : 'ssociated with node 1' - ELSE IF( CMN_LINE .EQ. 12 ) THEN - CARD = 'LNK2_A = 1 / Node 2 is de'// - : 'rived from node 1' - ELSE IF( CMN_LINE .EQ. 13 ) THEN - CARD = 'FRM1_A = '' '' / Frame numb'// - : 'er 1' - ELSE IF( CMN_LINE .EQ. 14 ) THEN - CARD = 'BEGAST_B= ''Frame '' / Coordinate'// - : ' system description' - ELSE IF( CMN_LINE .EQ. 15 ) THEN - CARD = 'TITLE_A = ''Data grid indices; first pixel at'// - : ' (1&''/ Title of coordinate system' - ELSE IF( CMN_LINE .EQ. 16 ) THEN - CARD = 'CONTINUE '',1) ''' - ELSE IF( CMN_LINE .EQ. 17 ) THEN - CARD = 'NAXES_A = 2 / Number of co'// - : 'ordinate axes' - ELSE IF( CMN_LINE .EQ. 18 ) THEN - CARD = 'DOMAIN_A= ''GRID '' / Coordinate'// - : ' system domain' - ELSE IF( CMN_LINE .EQ. 19 ) THEN - CARD = 'AX1_A = '' '' / Axis numbe'// - : 'r 1' - ELSE IF( CMN_LINE .EQ. 20 ) THEN - CARD = 'BEGAST_C= ''Axis '' / Coordinate'// - : ' axis' - ELSE IF( CMN_LINE .EQ. 21 ) THEN - CARD = 'LABEL_A = ''Data grid index 1'' / Axis Label' - ELSE IF( CMN_LINE .EQ. 22 ) THEN - CARD = 'SYMBOL_A= ''g1 '' / Axis symbo'// - : 'l' - ELSE IF( CMN_LINE .EQ. 23 ) THEN - CARD = 'UNIT_A = ''pixel '' / Axis units' - ELSE IF( CMN_LINE .EQ. 24 ) THEN - CARD = 'FORMAT_A= ''%3.1f '' / Format spe'// - : 'cifier' - ELSE IF( CMN_LINE .EQ. 25 ) THEN - CARD = 'ENDAST_A= ''Axis '' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 26 ) THEN - CARD = 'AX2_A = '' '' / Axis numbe'// - : 'r 2' - ELSE IF( CMN_LINE .EQ. 27 ) THEN - CARD = 'BEGAST_D= ''Axis '' / Coordinate'// - : ' axis' - ELSE IF( CMN_LINE .EQ. 28 ) THEN - CARD = 'LABEL_B = ''Data grid index 2'' / Axis Label' - ELSE IF( CMN_LINE .EQ. 29 ) THEN - CARD = 'SYMBOL_B= ''g2 '' / Axis symbo'// - : 'l' - ELSE IF( CMN_LINE .EQ. 30 ) THEN - CARD = 'UNIT_B = ''pixel '' / Axis units' - ELSE IF( CMN_LINE .EQ. 31 ) THEN - CARD = 'FORMAT_B= ''%3.1f '' / Format spe'// - : 'cifier' - ELSE IF( CMN_LINE .EQ. 32 ) THEN - CARD = 'ENDAST_B= ''Axis '' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 33 ) THEN - CARD = 'ENDAST_C= ''Frame '' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 34 ) THEN - CARD = 'FRM2_A = '' '' / Frame numb'// - : 'er 2' - ELSE IF( CMN_LINE .EQ. 35 ) THEN - CARD = 'BEGAST_E= ''Frame '' / Coordinate'// - : ' system description' - ELSE IF( CMN_LINE .EQ. 36 ) THEN - CARD = 'TITLE_B = ''Pixel coordinates; first pixel at'// - : ' (-&''/ Title of coordinate system' - ELSE IF( CMN_LINE .EQ. 37 ) THEN - CARD = 'CONTINUE ''100.5,-200.5)''' - ELSE IF( CMN_LINE .EQ. 38 ) THEN - CARD = 'NAXES_B = 2 / Number of co'// - : 'ordinate axes' - ELSE IF( CMN_LINE .EQ. 39 ) THEN - CARD = 'DOMAIN_B= ''POLAR '' / Coordinate'// - : ' system domain' - ELSE IF( CMN_LINE .EQ. 40 ) THEN - CARD = 'AX1_B = '' '' / Axis numbe'// - : 'r 1' - ELSE IF( CMN_LINE .EQ. 41 ) THEN - CARD = 'BEGAST_F= ''Axis '' / Coordinate'// - : ' axis' - ELSE IF( CMN_LINE .EQ. 42 ) THEN - CARD = 'LABEL_C = ''Pixel coordinate 1'' / Axis Label' - ELSE IF( CMN_LINE .EQ. 43 ) THEN - CARD = 'SYMBOL_C= ''p1 '' / Axis symbo'// - : 'l' - ELSE IF( CMN_LINE .EQ. 44 ) THEN - CARD = 'UNIT_C = ''pixel '' / Axis units' - ELSE IF( CMN_LINE .EQ. 45 ) THEN - CARD = 'FORMAT_C= ''%3.1f '' / Format spe'// - : 'cifier' - ELSE IF( CMN_LINE .EQ. 46 ) THEN - CARD = 'ENDAST_D= ''Axis '' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 47 ) THEN - CARD = 'AX2_B = '' '' / Axis numbe'// - : 'r 2' - ELSE IF( CMN_LINE .EQ. 48 ) THEN - CARD = 'BEGAST_G= ''Axis '' / Coordinate'// - : ' axis' - ELSE IF( CMN_LINE .EQ. 49 ) THEN - CARD = 'LABEL_D = ''Pixel coordinate 2'' / Axis Label' - ELSE IF( CMN_LINE .EQ. 50 ) THEN - CARD = 'SYMBOL_D= ''p2 '' / Axis symbo'// - : 'l' - ELSE IF( CMN_LINE .EQ. 51 ) THEN - CARD = 'UNIT_D = ''pixel '' / Axis units' - ELSE IF( CMN_LINE .EQ. 52 ) THEN - CARD = 'FORMAT_D= ''%3.1f '' / Format spe'// - : 'cifier' - ELSE IF( CMN_LINE .EQ. 53 ) THEN - CARD = 'ENDAST_E= ''Axis '' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 54 ) THEN - CARD = 'ENDAST_F= ''Frame '' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 55 ) THEN - CARD = 'MAP2_A = '' '' / Mapping be'// - : 'tween nodes 1 and 2' - ELSE IF( CMN_LINE .EQ. 56 ) THEN - CARD = 'BEGAST_H= ''CmpMap '' / Compound M'// - : 'apping' - ELSE IF( CMN_LINE .EQ. 57 ) THEN - CARD = 'NIN_A = 2 / Number of in'// - : 'put coordinates' - ELSE IF( CMN_LINE .EQ. 58 ) THEN - CARD = 'ISA_A = ''Mapping '' / Mapping be'// - : 'tween coordinate systems' - ELSE IF( CMN_LINE .EQ. 59 ) THEN - CARD = 'INVA_A = 1 / First Mappin'// - : 'g used in inverse direction' - ELSE IF( CMN_LINE .EQ. 60 ) THEN - CARD = 'INVB_A = 1 / Second Mappi'// - : 'ng used in inverse direction' - ELSE IF( CMN_LINE .EQ. 61 ) THEN - CARD = 'MAPA_A = '' '' / First comp'// - : 'onent Mapping' - ELSE IF( CMN_LINE .EQ. 62 ) THEN - CARD = 'BEGAST_I= ''MathMap '' / Transforma'// - : 'tion using mathematical functions' - ELSE IF( CMN_LINE .EQ. 63 ) THEN - CARD = 'NIN_B = 2 / Number of in'// - : 'put coordinates' - ELSE IF( CMN_LINE .EQ. 64 ) THEN - CARD = 'INVERT_A= 0 / Mapping not '// - : 'inverted' - ELSE IF( CMN_LINE .EQ. 65 ) THEN - CARD = 'ISA_B = ''Mapping '' / Mapping be'// - : 'tween coordinate systems' - ELSE IF( CMN_LINE .EQ. 66 ) THEN - CARD = 'FWD1_A = ''r=sqrt(x*x+y*y)'' / Forward fu'// - : 'nction 1' - ELSE IF( CMN_LINE .EQ. 67 ) THEN - CARD = 'FWD2_A = ''theta=atan2(y,x)'' / Forward fu'// - : 'nction 2' - ELSE IF( CMN_LINE .EQ. 68 ) THEN - CARD = 'INV1_A = ''x=r*cos(theta)'' / Inverse fu'// - : 'nction 1' - ELSE IF( CMN_LINE .EQ. 69 ) THEN - CARD = 'INV2_A = ''y=r*sin(theta)'' / Inverse fu'// - : 'nction 2' - ELSE IF( CMN_LINE .EQ. 70 ) THEN - CARD = 'SIMPFI_A= 1 / Forward-inve'// - : 'rse pairs may simplify' - ELSE IF( CMN_LINE .EQ. 71 ) THEN - CARD = 'SIMPIF_A= 1 / Inverse-forw'// - : 'ard pairs may simplify' - ELSE IF( CMN_LINE .EQ. 72 ) THEN - CARD = 'ENDAST_G= ''MathMap '' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 73 ) THEN - CARD = 'MAPB_A = '' '' / Second com'// - : 'ponent Mapping' - ELSE IF( CMN_LINE .EQ. 74 ) THEN - CARD = 'BEGAST_J= ''WinMap '' / Map one wi'// - : 'ndow on to another' - ELSE IF( CMN_LINE .EQ. 75 ) THEN - CARD = 'NIN_C = 2 / Number of in'// - : 'put coordinates' - ELSE IF( CMN_LINE .EQ. 76 ) THEN - CARD = 'INVERT_B= 0 / Mapping not '// - : 'inverted' - ELSE IF( CMN_LINE .EQ. 77 ) THEN - CARD = 'ISA_C = ''Mapping '' / Mapping be'// - : 'tween coordinate systems' - ELSE IF( CMN_LINE .EQ. 78 ) THEN - CARD = 'SFT1_A = -101.5 / Shift for ax'// - : 'is 1' - ELSE IF( CMN_LINE .EQ. 79 ) THEN - CARD = 'SFT2_A = -201.5 / Shift for ax'// - : 'is 2' - ELSE IF( CMN_LINE .EQ. 80 ) THEN - CARD = 'ENDAST_H= ''WinMap '' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 81 ) THEN - CARD = 'ENDAST_I= ''CmpMap '' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 82 ) THEN - CARD = 'ENDAST_J= ''FrameSet'' / End of obj'// - : 'ect definition' - ELSE IF( CMN_LINE .EQ. 83 ) THEN - CARD = 'COMMENT AST .................................'// - : '...............................' - ELSE IF( CMN_LINE .EQ. 84 ) THEN - CARD = 'AST' - ELSE IF( CMN_LINE .EQ. 85 ) THEN - CARD = 'COMMENT AST End of AST data for'// - : ' FrameSet object' - ELSE IF( CMN_LINE .EQ. 86 ) THEN - CARD = 'AST' - ELSE IF( CMN_LINE .EQ. 87 ) THEN - CARD = 'COMMENT AST ---------------------------------'// - : '-------------------------------' - ELSE IF( CMN_LINE .EQ. 88 ) THEN - CARD = 'AST' - REG_SOURCE = 0 - ELSE - REG_SOURCE = 0 - END IF - - -* FITS headers from scp.head (Tue Jan 29 15:17:50 2002) - ELSE IF( CMN_FTEST .EQ. 3 ) THEN - IF( CMN_LINE .EQ. 1 ) THEN - CARD = 'SIMPLE = T / file does co'// - : 'nform to FITS standard' - ELSE IF( CMN_LINE .EQ. 2 ) THEN - CARD = 'BITPIX = 16 / number of bi'// - : 'ts per data pixel' - ELSE IF( CMN_LINE .EQ. 3 ) THEN - CARD = 'NAXIS = 2 / number of da'// - : 'ta axes' - ELSE IF( CMN_LINE .EQ. 4 ) THEN - CARD = 'NAXIS1 = 1787 / length of da'// - : 'ta axis 1' - ELSE IF( CMN_LINE .EQ. 5 ) THEN - CARD = 'NAXIS2 = 447 / length of da'// - : 'ta axis 2' - ELSE IF( CMN_LINE .EQ. 6 ) THEN - CARD = 'EXTEND = T / FITS dataset'// - : ' may contain extensions' - ELSE IF( CMN_LINE .EQ. 7 ) THEN - CARD = 'COMMENT FITS (Flexible Image Transport Syst'// - : 'em) format defined in Astronomy and' - ELSE IF( CMN_LINE .EQ. 8 ) THEN - CARD = 'COMMENT Astrophysics Supplement Series v44/'// - : 'p363, v44/p371, v73/p359, v73/p365.' - ELSE IF( CMN_LINE .EQ. 9 ) THEN - CARD = 'COMMENT Contact the NASA Science Office of '// - : 'Standards and Technology for the' - ELSE IF( CMN_LINE .EQ. 10 ) THEN - CARD = 'COMMENT FITS Definition document #100 and o'// - : 'ther FITS information.' - ELSE IF( CMN_LINE .EQ. 11 ) THEN - CARD = 'PLATENUM= ''3665 '' / Plate numb'// - : 'er' - ELSE IF( CMN_LINE .EQ. 12 ) THEN - CARD = 'EMULSION= ''IIIaJ '' / Kodak emul'// - : 'sion type' - ELSE IF( CMN_LINE .EQ. 13 ) THEN - CARD = 'FILTER = ''GG395 '' / Schott gla'// - : 'ss filter type' - ELSE IF( CMN_LINE .EQ. 14 ) THEN - CARD = 'PLTSCALE= ''67.14 '' / [arcsec/mm'// - : '] plate scale' - ELSE IF( CMN_LINE .EQ. 15 ) THEN - CARD = 'FIELDNUM= ''1 '' / Sky survey'// - : ' field number' - ELSE IF( CMN_LINE .EQ. 16 ) THEN - CARD = 'EPOCH = 1.977780E+03 / Epoch of obs'// - : 'ervation' - ELSE IF( CMN_LINE .EQ. 17 ) THEN - CARD = 'DATE-OBS= ''1977-10-11'' / [yyyy-mm-d'// - : 'd] UT date of observation' - ELSE IF( CMN_LINE .EQ. 18 ) THEN - CARD = 'TELESCOP= ''UKST '' / Telescope '// - : 'on which the plate was taken' - ELSE IF( CMN_LINE .EQ. 19 ) THEN - CARD = 'TELETYPE= ''SCHM '' / Type of te'// - : 'lescope' - ELSE IF( CMN_LINE .EQ. 20 ) THEN - CARD = 'SITELAT = -5.458410576565E-01 / [radians] la'// - : 'titude of telescope' - ELSE IF( CMN_LINE .EQ. 21 ) THEN - CARD = 'SITELONG= 2.601766194458E+00 / [radians] lo'// - : 'ngitude of telescope' - ELSE IF( CMN_LINE .EQ. 22 ) THEN - CARD = 'LST = ''00:20 '' / [hh:mm] lo'// - : 'cal sidereal time at start of obs' - ELSE IF( CMN_LINE .EQ. 23 ) THEN - CARD = 'MJD-OBS = 4.342657300880E+04 / Modified Jul'// - : 'ian Date of observation' - ELSE IF( CMN_LINE .EQ. 24 ) THEN - CARD = 'INSTRUME= ''SuperCOSMOS I'' / Measuring '// - : 'machine' - ELSE IF( CMN_LINE .EQ. 25 ) THEN - CARD = 'DATE-MES= ''2000-11-04'' / [yyyy-mm-d'// - : 'd] Date of this plate measurement' - ELSE IF( CMN_LINE .EQ. 26 ) THEN - CARD = 'RADECSYS= ''FK5 '' / Reference '// - : 'frame for RA/DEC in original file' - ELSE IF( CMN_LINE .EQ. 27 ) THEN - CARD = 'NHKLINES= 146 / Number of li'// - : 'nes from house-keeping file' - ELSE IF( CMN_LINE .EQ. 28 ) THEN - CARD = 'HKLIN001= ''JOB.JOBNO UKJ001'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 29 ) THEN - CARD = 'HKLIN002= ''JOB.DATE-MES 2000:11:'// - : '04'' /' - ELSE IF( CMN_LINE .EQ. 30 ) THEN - CARD = 'HKLIN003= ''JOB.TIME 12:51:09'// - : ''' /' - ELSE IF( CMN_LINE .EQ. 31 ) THEN - CARD = 'HKLIN004= ''JOB.INSTRUME SuperCOS'// - : 'MOS I'' /' - ELSE IF( CMN_LINE .EQ. 32 ) THEN - CARD = 'HKLIN005= ''JOB.ORIGIN Royal Ob'// - : 'servatory Edinburgh'' /' - ELSE IF( CMN_LINE .EQ. 33 ) THEN - CARD = 'HKLIN006= ''JOB.SOFTWARE /home/sc'// - : 'osdev/v033'' /' - ELSE IF( CMN_LINE .EQ. 34 ) THEN - CARD = 'HKLIN007= ''JOB.OPERATOR ebt'' /' - ELSE IF( CMN_LINE .EQ. 35 ) THEN - CARD = 'HKLIN008= ''JOB.USER htm'' /' - ELSE IF( CMN_LINE .EQ. 36 ) THEN - CARD = 'HKLIN009= ''JOB.USERREF NONE'' /' - ELSE IF( CMN_LINE .EQ. 37 ) THEN - CARD = 'HKLIN010= ''JOB.UORIGIN ROE'' /' - ELSE IF( CMN_LINE .EQ. 38 ) THEN - CARD = 'HKLIN011= ''JOB.UCOUNTRY uk'' /' - ELSE IF( CMN_LINE .EQ. 39 ) THEN - CARD = 'HKLIN012= ''JOB.COMMENT Digital '// - : 'catalogue of the Sky'' /' - ELSE IF( CMN_LINE .EQ. 40 ) THEN - CARD = 'HKLIN013= ''JOB.IAM_FILE iam.srt''// - : '' /' - ELSE IF( CMN_LINE .EQ. 41 ) THEN - CARD = 'HKLIN014= ''PLATE.TELESCOP UKST'' /' - ELSE IF( CMN_LINE .EQ. 42 ) THEN - CARD = 'HKLIN015= ''PLATE.TELTYPE SCHM'' /' - ELSE IF( CMN_LINE .EQ. 43 ) THEN - CARD = 'HKLIN016= ''PLATE.PLATE 3665'' /' - ELSE IF( CMN_LINE .EQ. 44 ) THEN - CARD = 'HKLIN017= ''PLATE.MATERIAL 3mm glas'// - : 's'' /' - ELSE IF( CMN_LINE .EQ. 45 ) THEN - CARD = 'HKLIN018= ''PLATE.EMULSION IIIaJ'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 46 ) THEN - CARD = 'HKLIN019= ''PLATE.FILTER GG395'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 47 ) THEN - CARD = 'HKLIN020= ''PLATE.PSCALE 67.14'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 48 ) THEN - CARD = 'HKLIN021= ''PLATE.FIELD 1'' /' - ELSE IF( CMN_LINE .EQ. 49 ) THEN - CARD = 'HKLIN022= ''PLATE.RA_PNT 0'' /' - ELSE IF( CMN_LINE .EQ. 50 ) THEN - CARD = 'HKLIN023= ''PLATE.DEC_PNT -90'' /' - ELSE IF( CMN_LINE .EQ. 51 ) THEN - CARD = 'HKLIN024= ''PLATE.RADECSYS FK4'' /' - ELSE IF( CMN_LINE .EQ. 52 ) THEN - CARD = 'HKLIN025= ''PLATE.EQUINOX 1950'' /' - ELSE IF( CMN_LINE .EQ. 53 ) THEN - CARD = 'HKLIN026= ''PLATE.TIMESYS BESSELIA'// - : 'N'' /' - ELSE IF( CMN_LINE .EQ. 54 ) THEN - CARD = 'HKLIN027= ''PLATE.EPOCH 1977.78''// - : '' /' - ELSE IF( CMN_LINE .EQ. 55 ) THEN - CARD = 'HKLIN028= ''PLATE.EXPOSURE 75'' /' - ELSE IF( CMN_LINE .EQ. 56 ) THEN - CARD = 'HKLIN029= ''PLATE.UTDATE 771011'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 57 ) THEN - CARD = 'HKLIN030= ''PLATE.LST 0020'' /' - ELSE IF( CMN_LINE .EQ. 58 ) THEN - CARD = 'HKLIN031= ''PLATE.MJD 43426.57'// - : '3008796'' /' - ELSE IF( CMN_LINE .EQ. 59 ) THEN - CARD = 'HKLIN032= ''PLATE.TELLAT -0.54584'// - : '105765654'' /' - ELSE IF( CMN_LINE .EQ. 60 ) THEN - CARD = 'HKLIN033= ''PLATE.TELLONG 2.601766'// - : '1944583'' /' - ELSE IF( CMN_LINE .EQ. 61 ) THEN - CARD = 'HKLIN034= ''PLATE.TELHT 1145'' /' - ELSE IF( CMN_LINE .EQ. 62 ) THEN - CARD = 'HKLIN035= ''PLATE.TEMP 273.155''// - : '' /' - ELSE IF( CMN_LINE .EQ. 63 ) THEN - CARD = 'HKLIN036= ''PLATE.ATMOSP 1013.25''// - : '' /' - ELSE IF( CMN_LINE .EQ. 64 ) THEN - CARD = 'HKLIN037= ''PLATE.HUMID 0.5'' /' - ELSE IF( CMN_LINE .EQ. 65 ) THEN - CARD = 'HKLIN038= ''PLATE.WAVE 4500'' /' - ELSE IF( CMN_LINE .EQ. 66 ) THEN - CARD = 'HKLIN039= ''PLATE.TROPL 0.0065'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 67 ) THEN - CARD = 'HKLIN040= ''CALIBRATION.CALTYPE SPLINE'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 68 ) THEN - CARD = 'HKLIN041= ''CALIBRATION.STEPWEDG KPNO'' /' - ELSE IF( CMN_LINE .EQ. 69 ) THEN - CARD = 'HKLIN042= ''CALIBRATION.NSTEPS 8'' /' - ELSE IF( CMN_LINE .EQ. 70 ) THEN - CARD = 'HKLIN043= ''MEASUREMENT.ORIENTAT news'' /' - ELSE IF( CMN_LINE .EQ. 71 ) THEN - CARD = 'HKLIN044= ''MEASUREMENT.EMULPOS UP'' /' - ELSE IF( CMN_LINE .EQ. 72 ) THEN - CARD = 'HKLIN045= ''MEASUREMENT.SCANFILT 14'' /' - ELSE IF( CMN_LINE .EQ. 73 ) THEN - CARD = 'HKLIN046= ''MEASUREMENT.SOSP 552'' /' - ELSE IF( CMN_LINE .EQ. 74 ) THEN - CARD = 'HKLIN047= ''MEASUREMENT.STEPSIZE 10'' /' - ELSE IF( CMN_LINE .EQ. 75 ) THEN - CARD = 'HKLIN048= ''MEASUREMENT.SCANLEN 1152'' /' - ELSE IF( CMN_LINE .EQ. 76 ) THEN - CARD = 'HKLIN049= ''MEASUREMENT.A-XMIN 1622000''// - : '' /' - ELSE IF( CMN_LINE .EQ. 77 ) THEN - CARD = 'HKLIN050= ''MEASUREMENT.A-YMIN 1622000''// - : '' /' - ELSE IF( CMN_LINE .EQ. 78 ) THEN - CARD = 'HKLIN051= ''MEASUREMENT.A-XMAX 33878000'// - : ''' /' - ELSE IF( CMN_LINE .EQ. 79 ) THEN - CARD = 'HKLIN052= ''MEASUREMENT.A-YMAX 33878000'// - : ''' /' - ELSE IF( CMN_LINE .EQ. 80 ) THEN - CARD = 'HKLIN053= ''MEASUREMENT.X_PNT 17500000'// - : ''' /' - ELSE IF( CMN_LINE .EQ. 81 ) THEN - CARD = 'HKLIN054= ''MEASUREMENT.Y_PNT 18000000'// - : ''' /' - ELSE IF( CMN_LINE .EQ. 82 ) THEN - CARD = 'HKLIN055= ''ANALYSIS.NPARAMS 32'' /' - ELSE IF( CMN_LINE .EQ. 83 ) THEN - CARD = 'HKLIN056= ''ANALYSIS.AREACUT 8'' /' - ELSE IF( CMN_LINE .EQ. 84 ) THEN - CARD = 'HKLIN057= ''ANALYSIS.AP-PARAM 1.07'' /' - ELSE IF( CMN_LINE .EQ. 85 ) THEN - CARD = 'HKLIN058= ''DEBLEND.DB-PARAM 1.05'' /' - ELSE IF( CMN_LINE .EQ. 86 ) THEN - CARD = 'HKLIN059= ''DEBLEND.DB-AMIN 16'' /' - ELSE IF( CMN_LINE .EQ. 87 ) THEN - CARD = 'HKLIN060= ''DEBLEND.DB-AMAX 100000'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 88 ) THEN - CARD = 'HKLIN061= ''DEBLEND.DB-ACUT 8'' /' - ELSE IF( CMN_LINE .EQ. 89 ) THEN - CARD = 'HKLIN062= ''DEBLEND.DB-LEVEL 16'' /' - ELSE IF( CMN_LINE .EQ. 90 ) THEN - CARD = 'HKLIN063= ''DEBLEND.SELECT PARENT+C'// - : 'HILD'' /' - ELSE IF( CMN_LINE .EQ. 91 ) THEN - CARD = 'HKLIN064= ''SKY.SKYSQUAR 64'' /' - ELSE IF( CMN_LINE .EQ. 92 ) THEN - CARD = 'HKLIN065= ''SKY.SKYDEFN MEDIAN'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 93 ) THEN - CARD = 'HKLIN066= ''SKY.SKYFILTR bdkjunk''// - : '' /' - ELSE IF( CMN_LINE .EQ. 94 ) THEN - CARD = 'HKLIN067= ''SKY.F-THRESH 8'' /' - ELSE IF( CMN_LINE .EQ. 95 ) THEN - CARD = 'HKLIN068= ''SKY.F-SCLEN 4'' /' - ELSE IF( CMN_LINE .EQ. 96 ) THEN - CARD = 'HKLIN069= ''THRESHOLDING.PCUT 10'' /' - ELSE IF( CMN_LINE .EQ. 97 ) THEN - CARD = 'HKLIN070= ''IAMQC.AREAMIN 8'' /' - ELSE IF( CMN_LINE .EQ. 98 ) THEN - CARD = 'HKLIN071= ''IAMQC.AREAMAX 77346'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 99 ) THEN - CARD = 'HKLIN072= ''IAMQC.MINMAG -30515'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 100 ) THEN - CARD = 'HKLIN073= ''IAMQC.MAXMAG -17954'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 101 ) THEN - CARD = 'HKLIN074= ''IAMQC.MINELL 0.000415'// - : '6232'' /' - ELSE IF( CMN_LINE .EQ. 102 ) THEN - CARD = 'HKLIN075= ''IAMQC.MAXELL 1'' /' - ELSE IF( CMN_LINE .EQ. 103 ) THEN - CARD = 'HKLIN076= ''IAMQC.MODELL 0.14'' /' - ELSE IF( CMN_LINE .EQ. 104 ) THEN - CARD = 'HKLIN077= ''IAMQC.MODOR 91'' /' - ELSE IF( CMN_LINE .EQ. 105 ) THEN - CARD = 'HKLIN078= ''IAMQC.MIDELL 0.21'' /' - ELSE IF( CMN_LINE .EQ. 106 ) THEN - CARD = 'HKLIN079= ''IAMQC.MIDOR 93'' /' - ELSE IF( CMN_LINE .EQ. 107 ) THEN - CARD = 'HKLIN080= ''IAMQC.MEANELL 0.246703'// - : '7'' /' - ELSE IF( CMN_LINE .EQ. 108 ) THEN - CARD = 'HKLIN081= ''IAMQC.MEANOR 91.63474'// - : ''' /' - ELSE IF( CMN_LINE .EQ. 109 ) THEN - CARD = 'HKLIN082= ''IAMQC.NUMOBJ 556985'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 110 ) THEN - CARD = 'HKLIN083= ''IAMQC.PARENTS 486656'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 111 ) THEN - CARD = 'HKLIN084= ''IAMQC.RANGING TRUE'' /' - ELSE IF( CMN_LINE .EQ. 112 ) THEN - CARD = 'HKLIN085= ''IAMQC.LANE_1 15571'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 113 ) THEN - CARD = 'HKLIN086= ''IAMQC.LANE_2 33207'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 114 ) THEN - CARD = 'HKLIN087= ''IAMQC.LANE_3 51478'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 115 ) THEN - CARD = 'HKLIN088= ''IAMQC.LANE_4 69944'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 116 ) THEN - CARD = 'HKLIN089= ''IAMQC.LANE_5 89236'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 117 ) THEN - CARD = 'HKLIN090= ''IAMQC.LANE_6 108416'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 118 ) THEN - CARD = 'HKLIN091= ''IAMQC.LANE_7 127481'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 119 ) THEN - CARD = 'HKLIN092= ''IAMQC.LANE_8 146699'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 120 ) THEN - CARD = 'HKLIN093= ''IAMQC.LANE_9 166380'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 121 ) THEN - CARD = 'HKLIN094= ''IAMQC.LANE_10 186126'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 122 ) THEN - CARD = 'HKLIN095= ''IAMQC.LANE_11 205946'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 123 ) THEN - CARD = 'HKLIN096= ''IAMQC.LANE_12 225915'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 124 ) THEN - CARD = 'HKLIN097= ''IAMQC.LANE_13 245926'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 125 ) THEN - CARD = 'HKLIN098= ''IAMQC.LANE_14 266574'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 126 ) THEN - CARD = 'HKLIN099= ''IAMQC.LANE_15 287150'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 127 ) THEN - CARD = 'HKLIN100= ''IAMQC.LANE_16 308087'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 128 ) THEN - CARD = 'HKLIN101= ''IAMQC.LANE_17 328830'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 129 ) THEN - CARD = 'HKLIN102= ''IAMQC.LANE_18 350253'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 130 ) THEN - CARD = 'HKLIN103= ''IAMQC.LANE_19 370738'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 131 ) THEN - CARD = 'HKLIN104= ''IAMQC.LANE_20 391722'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 132 ) THEN - CARD = 'HKLIN105= ''IAMQC.LANE_21 412801'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 133 ) THEN - CARD = 'HKLIN106= ''IAMQC.LANE_22 433795'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 134 ) THEN - CARD = 'HKLIN107= ''IAMQC.LANE_23 454383'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 135 ) THEN - CARD = 'HKLIN108= ''IAMQC.LANE_24 474711'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 136 ) THEN - CARD = 'HKLIN109= ''IAMQC.LANE_25 495108'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 137 ) THEN - CARD = 'HKLIN110= ''IAMQC.LANE_26 515755'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 138 ) THEN - CARD = 'HKLIN111= ''IAMQC.LANE_27 536499'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 139 ) THEN - CARD = 'HKLIN112= ''IAMQC.LANE_28 556985'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 140 ) THEN - CARD = 'HKLIN113= ''XYTORADEC.STARCAT /sdata/s'// - : 'cos/refcats/tycho2.FIT'' /' - ELSE IF( CMN_LINE .EQ. 141 ) THEN - CARD = 'HKLIN114= ''XYTORADEC.BRIGHTLIM 9'' /' - ELSE IF( CMN_LINE .EQ. 142 ) THEN - CARD = 'HKLIN115= ''XYTORADEC.C-EQUIN 2000'' /' - ELSE IF( CMN_LINE .EQ. 143 ) THEN - CARD = 'HKLIN116= ''XYTORADEC.C-EQTSYS JULIAN'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 144 ) THEN - CARD = 'HKLIN117= ''XYTORADEC.C-EPOCH 2000'' /' - ELSE IF( CMN_LINE .EQ. 145 ) THEN - CARD = 'HKLIN118= ''XYTORADEC.C-EPTSYS JULIAN'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 146 ) THEN - CARD = 'HKLIN119= ''XYTORADEC.R-EQUIN 2000'' /' - ELSE IF( CMN_LINE .EQ. 147 ) THEN - CARD = 'HKLIN120= ''XYTORADEC.R-TSYS JULIAN'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 148 ) THEN - CARD = 'HKLIN121= ''XYTORADEC.MAXITER 5000'' /' - ELSE IF( CMN_LINE .EQ. 149 ) THEN - CARD = 'HKLIN122= ''XYTORADEC.RCRITINI 500000'''// - : ' /' - ELSE IF( CMN_LINE .EQ. 150 ) THEN - CARD = 'HKLIN123= ''XYTORADEC.RCRITABS 50000'' '// - : '/' - ELSE IF( CMN_LINE .EQ. 151 ) THEN - CARD = 'HKLIN124= ''XYTORADEC.RCRITREL 1'' /' - ELSE IF( CMN_LINE .EQ. 152 ) THEN - CARD = 'HKLIN125= ''XYTORADEC.RCRITFIN 3'' /' - ELSE IF( CMN_LINE .EQ. 153 ) THEN - CARD = 'HKLIN126= ''XYTORADEC.HARDCOPY /scos1/s'// - : 'cos/UKJ001/UKJ001.ps'' /' - ELSE IF( CMN_LINE .EQ. 154 ) THEN - CARD = 'HKLIN127= ''XYTORADEC.REFSMULT 5'' /' - ELSE IF( CMN_LINE .EQ. 155 ) THEN - CARD = 'HKLIN128= ''XYTORADEC.RESDMULT 1000'' /' - ELSE IF( CMN_LINE .EQ. 156 ) THEN - CARD = 'HKLIN129= ''XYTORADEC.RACOL RA'' /' - ELSE IF( CMN_LINE .EQ. 157 ) THEN - CARD = 'HKLIN130= ''XYTORADEC.DECOL DEC'' /' - ELSE IF( CMN_LINE .EQ. 158 ) THEN - CARD = 'HKLIN131= ''XYTORADEC.RAPMCOL PMRA'' /' - ELSE IF( CMN_LINE .EQ. 159 ) THEN - CARD = 'HKLIN132= ''XYTORADEC.DECPMCOL PMDE'' /' - ELSE IF( CMN_LINE .EQ. 160 ) THEN - CARD = 'HKLIN133= ''XYTORADEC.PLXCOL NONE'' /' - ELSE IF( CMN_LINE .EQ. 161 ) THEN - CARD = 'HKLIN134= ''XYTORADEC.RVCOL NONE'' /' - ELSE IF( CMN_LINE .EQ. 162 ) THEN - CARD = 'HKLIN135= ''XYTORADEC.MAGCOL VT'' /' - ELSE IF( CMN_LINE .EQ. 163 ) THEN - CARD = 'HKLIN136= ''XYTORADEC.STARSC 2374'' /' - ELSE IF( CMN_LINE .EQ. 164 ) THEN - CARD = 'HKLIN137= ''XYTORADEC.STARSU 1727'' /' - ELSE IF( CMN_LINE .EQ. 165 ) THEN - CARD = 'HKLIN138= ''XYTORADEC.COEFFS_1 17.64034'// - : '3856524'' /' - ELSE IF( CMN_LINE .EQ. 166 ) THEN - CARD = 'HKLIN139= ''XYTORADEC.COEFFS_2 -260.441'// - : '51995641'' /' - ELSE IF( CMN_LINE .EQ. 167 ) THEN - CARD = 'HKLIN140= ''XYTORADEC.COEFFS_3 -163.091'// - : '55572601'' /' - ELSE IF( CMN_LINE .EQ. 168 ) THEN - CARD = 'HKLIN141= ''XYTORADEC.COEFFS_4 17.50423'// - : '0442205'' /' - ELSE IF( CMN_LINE .EQ. 169 ) THEN - CARD = 'HKLIN142= ''XYTORADEC.COEFFS_5 -163.086'// - : '76953832'' /' - ELSE IF( CMN_LINE .EQ. 170 ) THEN - CARD = 'HKLIN143= ''XYTORADEC.COEFFS_6 260.4881'// - : '7907668'' /' - ELSE IF( CMN_LINE .EQ. 171 ) THEN - CARD = 'HKLIN144= ''XYTORADEC.DISTR -0.33333'// - : '333333333'' /' - ELSE IF( CMN_LINE .EQ. 172 ) THEN - CARD = 'HKLIN145= ''XYTORADEC.RA_PNT 0.549249'// - : '96662137'' /' - ELSE IF( CMN_LINE .EQ. 173 ) THEN - CARD = 'HKLIN146= ''XYTORADEC.DEC_PNT -1.56849'// - : '31501781'' /' - ELSE IF( CMN_LINE .EQ. 174 ) THEN - CARD = 'HISTORY = ''SuperCOSMOS image analysis and ma'// - : 'pping mode (IAM and MM)'' /' - ELSE IF( CMN_LINE .EQ. 175 ) THEN - CARD = 'HISTORY = ''data written by xydcomp_ss.'' /' - ELSE IF( CMN_LINE .EQ. 176 ) THEN - CARD = 'HISTORY = ''Any questions/comments/suggestion'// - : 's/bug reports should be sent'' /' - ELSE IF( CMN_LINE .EQ. 177 ) THEN - CARD = 'HISTORY = ''to N.Hambly@roe.ac.uk'' /' - ELSE IF( CMN_LINE .EQ. 178 ) THEN - CARD = 'ASTSIGX = 3.700000E-01 / [arcsec] std'// - : '. dev. of astrometric fit in X' - ELSE IF( CMN_LINE .EQ. 179 ) THEN - CARD = 'ASTSIGY = 3.800000E-01 / [arcsec] std'// - : '. dev. of astrometric fit in Y' - ELSE IF( CMN_LINE .EQ. 180 ) THEN - CARD = 'CRVAL1 = 0.000000000000E+00 / Axis 1 refer'// - : 'ence value' - ELSE IF( CMN_LINE .EQ. 181 ) THEN - CARD = 'CRPIX1 = 8.936318379289E+02 / Axis 1 pixel'// - : ' value' - ELSE IF( CMN_LINE .EQ. 182 ) THEN - CARD = 'CTYPE1 = ''RA---TAN'' / Quantity r'// - : 'epresented by axis 1' - ELSE IF( CMN_LINE .EQ. 183 ) THEN - CARD = 'CRVAL2 = -9.000000018364E+01 / Axis 2 refer'// - : 'ence value' - ELSE IF( CMN_LINE .EQ. 184 ) THEN - CARD = 'CRPIX2 = 2.238380193875E+02 / Axis 2 pixel'// - : ' value' - ELSE IF( CMN_LINE .EQ. 185 ) THEN - CARD = 'CTYPE2 = ''DEC--TAN'' / Quantity r'// - : 'epresented by axis 2' - ELSE IF( CMN_LINE .EQ. 186 ) THEN - CARD = 'CD1_1 = -1.864642639667E-04 / Co-ordinate '// - : 'transformation matrix' - ELSE IF( CMN_LINE .EQ. 187 ) THEN - CARD = 'CD1_2 = -9.188369023766E-07 / Co-ordinate '// - : 'transformation matrix' - ELSE IF( CMN_LINE .EQ. 188 ) THEN - CARD = 'CD2_1 = -1.038232462415E-06 / Co-ordinate '// - : 'transformation matrix' - ELSE IF( CMN_LINE .EQ. 189 ) THEN - CARD = 'CD2_2 = 1.866269837741E-04 / Co-ordinate '// - : 'transformation matrix' - ELSE IF( CMN_LINE .EQ. 190 ) THEN - CARD = 'CDELT1 = -1.864665278217E-04 / DEPRECATED -'// - : ' Increment per pixel on axis 1' - ELSE IF( CMN_LINE .EQ. 191 ) THEN - CARD = 'CDELT2 = 1.866298716692E-04 / DEPRECATED -'// - : ' Increment per pixel on axis 2' - ELSE IF( CMN_LINE .EQ. 192 ) THEN - CARD = 'PC001001= 9.999878591881E-01 / DEPRECATED -'// - : ' Axis rotation matrix' - ELSE IF( CMN_LINE .EQ. 193 ) THEN - CARD = 'PC001002= 4.927623810613E-03 / DEPRECATED -'// - : ' Axis rotation matrix' - ELSE IF( CMN_LINE .EQ. 194 ) THEN - CARD = 'PC002001= -5.563056187788E-03 / DEPRECATED -'// - : ' Axis rotation matrix' - ELSE IF( CMN_LINE .EQ. 195 ) THEN - CARD = 'PC002002= 9.999845260832E-01 / DEPRECATED -'// - : ' Axis rotation matrix' - ELSE IF( CMN_LINE .EQ. 196 ) THEN - CARD = 'CROTA2 = 3.005532298491E-01 / DEPRECATED -'// - : ' rotation of axis 2' - ELSE IF( CMN_LINE .EQ. 197 ) THEN - CARD = 'EQUINOX = 2.000000E+03 / Julian refer'// - : 'ence frame equinox' - ELSE IF( CMN_LINE .EQ. 198 ) THEN - CARD = 'DATATYPE= ''INTEGER*2'' / Type of da'// - : 'ta' - ELSE IF( CMN_LINE .EQ. 199 ) THEN - CARD = 'DATUNITS= ''DENSITY '' / Units: tra'// - : 'nsmission, density or intensity' - ELSE IF( CMN_LINE .EQ. 200 ) THEN - CARD = 'XPIXELSZ= 9.997114974000E+00 / [microns] X '// - : 'pixel size' - ELSE IF( CMN_LINE .EQ. 201 ) THEN - CARD = 'YPIXELSZ= 1.000000000000E+01 / [microns] Y '// - : 'pixel size' - ELSE IF( CMN_LINE .EQ. 202 ) THEN - CARD = 'OBJCTRA = '' 0 0 0.000'' / Centre Rig'// - : 'ht Ascension (J2000)' - ELSE IF( CMN_LINE .EQ. 203 ) THEN - CARD = 'OBJCTDEC= ''-90 0 0.00'' / Centre Dec'// - : 'lination (J2000)' - ELSE IF( CMN_LINE .EQ. 204 ) THEN - CARD = 'OBJCTX = 1.636863183793E+04 / [pixels] Cen'// - : 'tre X on plate' - ELSE IF( CMN_LINE .EQ. 205 ) THEN - CARD = 'OBJCTY = 1.474083801939E+04 / [pixels] Cen'// - : 'tre Y on plate' - ELSE IF( CMN_LINE .EQ. 206 ) THEN - CARD = 'END' - REG_SOURCE = 0 - ELSE - REG_SOURCE = 0 - END IF - - -* Insert new header code here.... (create new header code using script -* "make_regtest" in the AST development archive). - ELSE - REG_SOURCE = 0 - STATUS = SAI__ERROR - WRITE(*,'(A,I2)') 'REG_SOURCE: No such test: ',CMN_FTEST - END IF - - CMN_LINE = CMN_LINE + 1 - - END - - diff --git a/ast/ast_tester/regression.out b/ast/ast_tester/regression.out deleted file mode 100644 index 7fcaa9c..0000000 --- a/ast/ast_tester/regression.out +++ /dev/null @@ -1,7630 +0,0 @@ - Begin FitsChan # I/O channels to FITS files - Card = 1 # Index of current card -# Encod = "NATIVE" # Encoding system -# FitsDg = 15 # No. of digits for floating point values -# DfB1950 = 1 # Default to FK4 B1950 -# CdMat = 0 # Use PC matrix -# CarLin = 0 # Use full FITS-WCS CAR projections -# Iwc = 0 # Do not include an IWC Frame -# Warn = "Tnx Zpx BadCel BadMat BadCTYPE" # Warnings to be reported - Nm1 = "NAXIS" # FITS keyword name - Ty1 = "integer" # FITS keyword data type - Dt1 = 1 # FITS keyword value - Nm2 = "NAXIS1" # FITS keyword name - Ty2 = "integer" # FITS keyword data type - Dt2 = 100 # FITS keyword value - Nm3 = "CTYPE1" # FITS keyword name - Ty3 = "string" # FITS keyword data type - Dt3 = "fred" # FITS keyword value - Nm4 = "CDELT1" # FITS keyword name - Ty4 = "floating point" # FITS keyword data type - Dt4 = 0 # FITS keyword value - Nm5 = "CRPIX1" # FITS keyword name - Ty5 = "integer" # FITS keyword data type - Dt5 = 50 # FITS keyword value - Nm6 = "CUNIT1" # FITS keyword name - Ty6 = "string" # FITS keyword data type - Dt6 = "GHz" # FITS keyword value - Nm7 = " " # FITS keyword name - Ty7 = "comment" # FITS keyword data type - End FitsChan - Begin FrameSet # Set of inter-related coordinate systems -# Title = "IAU (1958) galactic coordinates; zenithal equal area projection" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Epoch = 1950 # Besselian epoch of observation -# Lbl1 = "Galactic longitude" # Label for axis 1 -# Lbl2 = "Galactic latitude" # Label for axis 2 -# System = "GALACTIC" # Coordinate system type -# Uni1 = "degrees" # Units for axis 1 -# Uni2 = "degrees" # Units for axis 2 -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - IsA Frame # Coordinate system description - Nframe = 2 # Number of Frames in FrameSet - Base = 1 # Index of base Frame - Currnt = 2 # Index of current Frame - Lnk2 = 1 # Node 2 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Pixel Coordinates" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Pixel axis 1" # Label for axis 1 -# Lbl2 = "Pixel axis 2" # Label for axis 2 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel axis 1" # Axis Label - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel axis 2" # Axis Label - End Axis - End Frame - Frm2 = # Frame number 2 - Begin SkyFrame # Description of celestial coordinate system - Ident = " " # Permanent Object identification string - IsA Object # AST Object -# Title = "IAU (1958) galactic coordinates; zenithal equal area projection" # Title of coordinate system - Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain - Epoch = 1950 # Besselian epoch of observation -# Lbl1 = "Galactic longitude" # Label for axis 1 -# Lbl2 = "Galactic latitude" # Label for axis 2 - System = "GALACTIC" # Coordinate system type -# Uni1 = "degrees" # Units for axis 1 -# Uni2 = "degrees" # Units for axis 2 -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - Proj = "zenithal equal area" # Description of sky projection - SRefIs = "Ignored" # Not rotated (ref. pos. is ignored) - SRef1 = -2.61046557479594 # Ref. pos. l -149.5687 - SRef2 = -0.344845661720836 # Ref. pos. b -19.7582 - End SkyFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -150.5 # Shift for axis 1 - Sft2 = -150.5 # Shift for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -0.020943951023932 # Forward matrix value - M1 = 0.020943951023932 # Forward matrix value - Form = "Diagonal" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "ZEA" # Zenithal equal area projection - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitude (rad.s) - End SphMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.291480364581799 # Forward matrix value - M1 = 0.506505471460186 # AST version 4.3- 0 -PutCards Ncards = 7 -PutCards Card = 1 -PutCards Card = 8 -PutCards Ncards = 7 -PutCards Card = 1 - - - - - FITS test number 1 - ==================== - - - -AST_SHOW: - -REG_SINK: -SIMPLE = T / Written by IDL: 30-Jul-1997 05:35:42.00 -BITPIX = -32 / Bits per pixel. -NAXIS = 2 / Number of dimensions -NAXIS1 = 300 / Length of x axis. -NAXIS2 = 300 / Length of y axis. -COMMENT -COMMENT This file was produced by the SkyView survey analysis system from -COMMENT available astronomical surveys. The data are formatted -COMMENT as a simple two-dimensional FITS image with the same units as -COMMENT the orginal survey. A single ASCII table extension may be present -COMMENT which describes catalog objects found within the field of view. -COMMENT Copies of relevant copyright notices are included in this file. -COMMENT -COMMENT Questions should be directed to: -COMMENT -COMMENT scollick@skyview.gsfc.nasa.gov -COMMENT or -COMMENT mcglynn@grossc.gsfc.nasa.gov -COMMENT -COMMENT SkyView -COMMENT Code 668.1 -COMMENT Goddard Space Flight Center, Greenbelt, MD 20771 -COMMENT 301-286-7780 -COMMENT -COMMENT SkyView is supported by NASA ADP grant NAS 5-32068. -COMMENT -SURVEY = 'COBE DIRBE' -BUNITS = 'MJy/sr ' -ORIGIN = 'CDAC ' / Cosmology Data Analysis Center -TELESCOP= 'COBE ' / COsmic Background Explorer satellite -INSTRUME= 'DIRBE ' / COBE instrument [DIRBE, DMR, FIRAS] -PIXRESOL= 9 / Quad tree pixel resolution [6, 9] -DATE = '27/09/94' / FITS file creation date (dd/mm/yy) -DATE-MAP= '16/09/94' / Date of original file creation (dd/mm/yy) -COMMENT COBE specific keywords -DATE-BEG= '08/12/89' / date of initial data represented (dd/mm/yy) -DATE-END= '25/09/90' / date of final data represented (dd/mm/yy) -COMMENT -COMMENT THE COBE DIRBE map is a combination of the original ten -COMMENT band passes with the following wavelengths: -COMMENT Band 1 - 1.25 microns -COMMENT Band 2 - 2.2 microns -COMMENT Band 3 - 3.5 microns -COMMENT Band 4 - 4.9 microns -COMMENT Band 5 - 12 microns -COMMENT Band 6 - 25 microns -COMMENT Band 7 - 60 microns -COMMENT Band 8 - 100 microns -COMMENT Band 9 - 140 microns -COMMENT Band 10 - 240 microns -COMMENT - -Objects written: 1 - -Native Encoding: - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST WCS information in AST format AST -COMMENT AST See http://www.starlink.ac.uk/ast/ AST -COMMENT AST Beginning of AST data for FrameSet object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'FrameSet' / Set of inter-related coordinate systems -NFRAME_A= 2 / Number of Frames in FrameSet -BASE_A = 1 / Index of base Frame -CURRNT_A= 2 / Index of current Frame -LNK2_A = 1 / Node 2 is derived from node 1 -FRM1_A = ' ' / Frame number 1 -BEGAST_B= 'Frame ' / Coordinate system description -TITLE_A = 'Pixel Coordinates' / Title of coordinate system -NAXES_A = 2 / Number of coordinate axes -DOMAIN_A= 'GRID ' / Coordinate system domain -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -LABEL_A = 'Pixel axis 1' / Axis Label -ENDAST_A= 'Axis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_D= 'Axis ' / Coordinate axis -LABEL_B = 'Pixel axis 2' / Axis Label -ENDAST_B= 'Axis ' / End of object definition -ENDAST_C= 'Frame ' / End of object definition -FRM2_A = ' ' / Frame number 2 -BEGAST_E= 'SkyFrame' / Description of celestial coordinate system -IDENT_A = '" " ' / Permanent Object identification string -ISA_A = 'Object ' / AST Object -NAXES_B = 2 / Number of coordinate axes -EPOCH_A = 1950.0 / Besselian epoch of observation -SYSTEM_A= 'GALACTIC' / Coordinate system type -AX1_B = ' ' / Axis number 1 -BEGAST_F= 'SkyAxis ' / Celestial coordinate axis -ENDAST_D= 'SkyAxis ' / End of object definition -AX2_B = ' ' / Axis number 2 -BEGAST_G= 'SkyAxis ' / Celestial coordinate axis -ENDAST_E= 'SkyAxis ' / End of object definition -ISA_B = 'Frame ' / Coordinate system description -PROJ_A = 'zenithal equal area'/ Description of sky projection -SREFIS_A= 'Ignored ' / Not rotated (ref. pos. is ignored) -SREF1_A = -2.61046557479594 / Ref. pos. l -149.5687 -SREF2_A = -0.344845661720836 / Ref. pos. b -19.7582 -ENDAST_F= 'SkyFrame' / End of object definition -MAP2_A = ' ' / Mapping between nodes 1 and 2 -BEGAST_H= 'CmpMap ' / Compound Mapping -NIN_A = 2 / Number of input coordinates -ISSIMP_A= 1 / Mapping has been simplified -ISA_C = 'Mapping ' / Mapping between coordinate systems -MAPA_A = ' ' / First component Mapping -BEGAST_I= 'WinMap ' / Map one window on to another -NIN_B = 2 / Number of input coordinates -INVERT_A= 0 / Mapping not inverted -ISA_D = 'Mapping ' / Mapping between coordinate systems -SFT1_A = -150.5 / Shift for axis 1 -SFT2_A = -150.5 / Shift for axis 2 -ENDAST_G= 'WinMap ' / End of object definition -MAPB_A = ' ' / Second component Mapping -BEGAST_J= 'CmpMap ' / Compound Mapping -NIN_C = 2 / Number of input coordinates -ISA_E = 'Mapping ' / Mapping between coordinate systems -MAPA_B = ' ' / First component Mapping -BEGAST_K= 'MatrixMap' / Matrix transformation -NIN_D = 2 / Number of input coordinates -INVERT_B= 0 / Mapping not inverted -ISA_F = 'Mapping ' / Mapping between coordinate systems -M0_A = -0.020943951023932 / Forward matrix value -M1_A = 0.020943951023932 / Forward matrix value -FORM_A = 'Diagonal' / Matrix storage form -ENDAST_H= 'MatrixMap' / End of object definition -MAPB_B = ' ' / Second component Mapping -BEGAST_L= 'CmpMap ' / Compound Mapping -NIN_E = 2 / Number of input coordinates -ISA_G = 'Mapping ' / Mapping between coordinate systems -INVA_A = 1 / First Mapping used in inverse direction -MAPA_C = ' ' / First component Mapping -BEGAST_M= 'WcsMap ' / FITS-WCS sky projection -NIN_F = 2 / Number of input coordinates -INVERT_C= 1 / Mapping inverted -ISA_H = 'Mapping ' / Mapping between coordinate systems -TYPE_A = 'ZEA ' / Zenithal equal area projection -ENDAST_I= 'WcsMap ' / End of object definition -MAPB_C = ' ' / Second component Mapping -BEGAST_N= 'CmpMap ' / Compound Mapping -NIN_G = 2 / Number of input coordinates -ISA_I = 'Mapping ' / Mapping between coordinate systems -INVA_B = 1 / First Mapping used in inverse direction -MAPA_D = ' ' / First component Mapping -BEGAST_O= 'SphMap ' / Cartesian to Spherical mapping -NIN_H = 3 / Number of input coordinates -NOUT_A = 2 / Number of output coordinates -INVERT_D= 1 / Mapping inverted -ISA_J = 'Mapping ' / Mapping between coordinate systems -UNTRD_A = 1 / All input vectors have unit length -PLRLG_A = 0.0 / Polar longitude (rad.s) -ENDAST_J= 'SphMap ' / End of object definition -MAPB_D = ' ' / Second component Mapping -BEGAST_P= 'CmpMap ' / Compound Mapping -NIN_I = 3 / Number of input coordinates -NOUT_B = 2 / Number of output coordinates -ISA_K = 'Mapping ' / Mapping between coordinate systems -MAPA_E = ' ' / First component Mapping -BEGAST_Q= 'MatrixMap' / Matrix transformation -NIN_J = 3 / Number of input coordinates -INVERT_E= 0 / Mapping not inverted -ISA_L = 'Mapping ' / Mapping between coordinate systems -M0_B = 0.291480364581799 / Forward matrix value -M1_B = 0.506505471460186 / Forward matrix value -M2_A = -0.811474832908671 / Forward matrix value -M3_A = 0.171224898552328 / Forward matrix value -M4_A = -0.862236746712233 / Forward matrix value -M5_A = -0.476686298035564 / Forward matrix value -M6_A = -0.941127638091139 / Forward matrix value -M7_A = 0.0 / Forward matrix value -M8_A = -0.338051429254475 / Forward matrix value -FORM_B = 'Full ' / Matrix storage form -ENDAST_K= 'MatrixMap' / End of object definition -MAPB_E = ' ' / Second component Mapping -BEGAST_R= 'SphMap ' / Cartesian to Spherical mapping -NIN_K = 3 / Number of input coordinates -NOUT_C = 2 / Number of output coordinates -INVERT_F= 0 / Mapping not inverted -ISA_M = 'Mapping ' / Mapping between coordinate systems -UNTRD_B = 1 / All input vectors have unit length -PLRLG_B = -2.61046557479594 / Polar longitude (rad.s) -ENDAST_L= 'SphMap ' / End of object definition -ENDAST_M= 'CmpMap ' / End of object definition -ENDAST_N= 'CmpMap ' / End of object definition -ENDAST_O= 'CmpMap ' / End of object definition -ENDAST_P= 'CmpMap ' / End of object definition -ENDAST_Q= 'CmpMap ' / End of object definition -ENDAST_R= 'FrameSet' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for FrameSet object AST -COMMENT AST ---------------------------------------------------------------- AST - -ATTRIBUTES: - Colour(axis1) : 1 - Font(Stri) : 1 - Nout : 1 - Class : 4 - Tol : 0.100000E-01 - Gap(1) : 1.04720 - Border : 0 - Invert : 0 - TextLabGap : 0.100000E-01 - Nin : 2 - Current : 3 - Base : 1 - Nobject : 1 - RefCOUNT : 1 - -AST_GRID: -REG_LINE: 15 - 25.4 -29.7 - 31.0 -16.7 - 35.7 -2.18 - 39.8 13.5 - 43.0 30.1 - 45.5 47.3 - 47.2 64.8 - 48.1 82.5 - 48.2 99.9 - 47.3 117. - 45.5 133. - 42.5 149. - 38.4 163. - 32.8 175. - 25.4 185. -REG_LINE: 15 - 25.4 -29.7 - 20.1 -16.6 - 15.4 -2.03 - 11.5 13.7 - 8.35 30.3 - 5.92 47.5 - 4.25 65.0 - 3.39 82.6 - 3.35 100. - 4.19 117. - 5.99 133. - 8.83 149. - 12.9 163. - 18.3 175. - 25.4 185. -REG_LINE: 119 - 25.4 -29.7 - 24.6 -29.7 - 23.8 -29.7 - 22.9 -29.6 - 22.1 -29.5 - 21.3 -29.5 - 20.4 -29.3 - 19.6 -29.2 - 18.8 -29.0 - 17.9 -28.9 - 17.1 -28.7 - 16.3 -28.5 - 15.5 -28.2 - 14.6 -28.0 - 13.8 -27.7 - 13.0 -27.4 - 12.2 -27.1 - 11.4 -26.7 - 10.6 -26.4 - 9.74 -26.0 - 8.93 -25.6 - 8.12 -25.2 - 7.32 -24.8 - 6.52 -24.3 - 5.73 -23.9 - 4.93 -23.4 - 4.14 -22.9 - 3.35 -22.3 - 2.57 -21.8 - 1.79 -21.2 - 1.02 -20.6 - .247 -20.0 - -.520 -19.4 - -1.28 -18.8 - -2.04 -18.1 - -2.79 -17.4 - -3.54 -16.7 - -4.29 -16.0 - -5.02 -15.3 - -5.76 -14.5 - -6.49 -13.7 - -7.21 -12.9 - -7.92 -12.1 - -17.3 1.12 - -25.1 17.7 - -31.1 37.2 - -34.6 59.1 - -35.4 82.8 - -33.1 107. - -32.8 109. - -32.5 111. - -32.2 112. - -31.9 114. - -31.5 116. - -31.1 117. - -30.7 119. - -30.3 121. - -29.9 123. - -29.4 124. - -28.9 126. - -28.5 128. - -27.9 129. - -27.4 131. - -26.9 132. - -26.3 134. - -25.7 136. - -25.2 137. - -24.5 139. - -23.9 140. - -23.3 142. - -22.6 143. - -21.9 145. - -21.2 146. - -20.5 148. - -19.8 149. - -19.0 151. - -18.2 152. - -17.5 154. - -16.7 155. - -15.8 156. - -15.0 158. - -14.2 159. - -13.3 160. - -12.4 162. - -11.5 163. - -10.6 164. - -9.69 165. - -8.75 166. - -7.80 167. - -6.83 168. - -5.85 170. - -4.86 171. - -3.85 172. - -2.83 172. - -1.80 173. - -.761 174. - .293 175. - 1.36 176. - 2.43 177. - 3.52 178. - 4.61 178. - 5.72 179. - 6.83 180. - 7.95 180. - 9.08 181. - 10.2 181. - 11.4 182. - 12.5 182. - 13.7 183. - 14.8 183. - 16.0 184. - 17.2 184. - 18.3 184. - 19.5 184. - 20.7 185. - 21.9 185. - 23.1 185. - 24.3 185. - 25.4 185. -REG_LINE: 171 - 25.4 -29.7 - 19.1 -40.9 - 11.9 -49.9 - 11.3 -50.4 - 10.8 -50.9 - 10.2 -51.4 - 9.62 -51.9 - 9.04 -52.4 - 8.46 -52.8 - 7.87 -53.3 - 7.28 -53.7 - 6.68 -54.1 - 6.07 -54.5 - 5.46 -54.9 - 4.84 -55.2 - 4.21 -55.6 - 3.58 -55.9 - 2.95 -56.2 - 2.30 -56.5 - 1.65 -56.7 - .990 -56.9 - .325 -57.2 - -.348 -57.3 - -1.03 -57.5 - -1.71 -57.7 - -2.41 -57.8 - -3.11 -57.9 - -3.82 -57.9 - -4.54 -58.0 - -5.27 -58.0 - -6.00 -58.0 - -6.74 -58.0 - -7.50 -57.9 - -8.26 -57.8 - -9.03 -57.7 - -9.80 -57.5 - -10.6 -57.3 - -11.4 -57.1 - -12.2 -56.8 - -13.0 -56.5 - -13.8 -56.2 - -14.7 -55.8 - -15.5 -55.4 - -16.4 -55.0 - -17.2 -54.5 - -18.1 -53.9 - -19.0 -53.4 - -19.9 -52.7 - -20.8 -52.0 - -21.7 -51.3 - -22.6 -50.5 - -23.6 -49.7 - -24.5 -48.8 - -25.5 -47.8 - -26.4 -46.8 - -27.4 -45.7 - -28.4 -44.5 - -29.4 -43.3 - -30.4 -42.0 - -31.4 -40.6 - -32.4 -39.1 - -33.5 -37.6 - -34.5 -36.0 - -35.5 -34.3 - -36.6 -32.5 - -37.6 -30.5 - -38.7 -28.5 - -39.7 -26.4 - -40.8 -24.2 - -41.8 -21.9 - -42.8 -19.5 - -43.9 -16.9 - -44.9 -14.2 - -45.9 -11.4 - -46.9 -8.53 - -47.8 -5.48 - -48.8 -2.30 - -49.7 1.01 - -50.6 4.45 - -51.4 8.02 - -52.2 11.7 - -53.0 15.6 - -53.7 19.5 - -54.4 23.6 - -55.0 27.8 - -55.5 32.2 - -56.0 36.6 - -56.4 41.1 - -56.7 45.8 - -56.9 50.5 - -57.1 55.3 - -57.1 60.1 - -57.1 65.1 - -56.9 70.0 - -56.7 74.9 - -56.4 79.9 - -55.9 84.9 - -55.4 89.8 - -54.8 94.7 - -54.1 99.5 - -53.3 104. - -52.4 109. - -51.4 114. - -50.3 118. - -49.2 122. - -48.0 127. - -46.7 131. - -45.4 135. - -44.1 138. - -42.7 142. - -41.2 146. - -39.8 149. - -38.3 152. - -36.8 155. - -35.2 158. - -33.7 161. - -32.2 164. - -30.6 166. - -29.1 168. - -27.5 171. - -26.0 173. - -24.5 175. - -23.0 176. - -21.5 178. - -20.0 180. - -18.5 181. - -17.1 182. - -15.7 184. - -14.3 185. - -12.9 186. - -11.5 187. - -10.2 188. - -8.92 188. - -7.64 189. - -6.38 190. - -5.15 190. - -3.94 191. - -2.75 191. - -1.59 192. - -.448 192. - .669 193. - 1.76 193. - 2.83 193. - 3.88 193. - 4.91 193. - 5.92 193. - 6.91 193. - 7.88 193. - 8.82 193. - 9.75 193. - 10.7 193. - 11.6 193. - 12.4 193. - 13.3 192. - 14.1 192. - 14.9 192. - 15.7 192. - 16.5 191. - 17.3 191. - 18.1 190. - 18.8 190. - 19.5 190. - 20.2 189. - 20.9 189. - 21.6 188. - 22.3 188. - 22.9 187. - 23.6 187. - 24.2 186. - 24.8 185. - 25.4 185. -REG_LINE: 171 - 25.4 -29.7 - 31.6 -41.1 - 38.7 -50.2 - 39.2 -50.7 - 39.8 -51.2 - 40.3 -51.8 - 40.9 -52.3 - 41.5 -52.8 - 42.0 -53.2 - 42.6 -53.7 - 43.2 -54.1 - 43.8 -54.6 - 44.4 -55.0 - 45.0 -55.4 - 45.6 -55.7 - 46.2 -56.1 - 46.8 -56.4 - 47.4 -56.7 - 48.1 -57.0 - 48.7 -57.3 - 49.4 -57.6 - 50.0 -57.8 - 50.7 -58.0 - 51.3 -58.2 - 52.0 -58.4 - 52.7 -58.5 - 53.4 -58.6 - 54.1 -58.7 - 54.8 -58.8 - 55.5 -58.8 - 56.2 -58.9 - 57.0 -58.8 - 57.7 -58.8 - 58.5 -58.7 - 59.2 -58.6 - 60.0 -58.5 - 60.8 -58.3 - 61.6 -58.2 - 62.4 -57.9 - 63.2 -57.7 - 64.0 -57.4 - 64.8 -57.0 - 65.6 -56.6 - 66.5 -56.2 - 67.3 -55.8 - 68.2 -55.2 - 69.1 -54.7 - 70.0 -54.1 - 70.9 -53.4 - 71.8 -52.7 - 72.7 -52.0 - 73.7 -51.2 - 74.6 -50.3 - 75.6 -49.4 - 76.6 -48.4 - 77.5 -47.3 - 78.5 -46.2 - 79.5 -45.0 - 80.5 -43.7 - 81.6 -42.4 - 82.6 -41.0 - 83.6 -39.5 - 84.7 -37.9 - 85.7 -36.2 - 86.8 -34.4 - 87.8 -32.5 - 88.9 -30.5 - 90.0 -28.5 - 91.1 -26.3 - 92.1 -23.9 - 93.2 -21.5 - 94.2 -19.0 - 95.3 -16.3 - 96.3 -13.5 - 97.3 -10.6 - 98.4 -7.51 - 99.3 -4.31 - 100. -.976 - 101. 2.50 - 102. 6.12 - 103. 9.88 - 104. 13.8 - 105. 17.8 - 105. 22.0 - 106. 26.3 - 106. 30.7 - 107. 35.2 - 107. 39.9 - 108. 44.7 - 108. 49.5 - 108. 54.4 - 108. 59.4 - 108. 64.5 - 108. 69.5 - 108. 74.6 - 107. 79.7 - 107. 84.8 - 106. 89.9 - 106. 94.9 - 105. 99.9 - 104. 105. - 103. 110. - 102. 114. - 101. 119. - 100. 123. - 98.8 128. - 97.5 132. - 96.1 136. - 94.7 140. - 93.3 143. - 91.8 147. - 90.3 150. - 88.8 154. - 87.2 157. - 85.7 159. - 84.1 162. - 82.5 165. - 80.9 167. - 79.4 170. - 77.8 172. - 76.3 174. - 74.7 176. - 73.2 177. - 71.7 179. - 70.2 181. - 68.8 182. - 67.3 183. - 65.9 185. - 64.5 186. - 63.2 187. - 61.8 188. - 60.5 188. - 59.2 189. - 57.9 190. - 56.7 191. - 55.5 191. - 54.3 192. - 53.1 192. - 51.9 192. - 50.8 193. - 49.7 193. - 48.6 193. - 47.6 193. - 46.5 193. - 45.5 194. - 44.5 194. - 43.6 194. - 42.6 194. - 41.7 193. - 40.8 193. - 39.9 193. - 39.0 193. - 38.2 193. - 37.3 193. - 36.5 192. - 35.7 192. - 34.9 192. - 34.2 191. - 33.4 191. - 32.7 191. - 31.9 190. - 31.2 190. - 30.5 189. - 29.8 189. - 29.2 188. - 28.5 188. - 27.9 187. - 27.3 187. - 26.6 186. - 26.0 185. - 25.4 185. -REG_LINE: 119 - 25.4 -29.7 - 26.3 -29.7 - 27.1 -29.7 - 28.0 -29.7 - 28.8 -29.6 - 29.6 -29.5 - 30.5 -29.4 - 31.3 -29.3 - 32.1 -29.2 - 33.0 -29.0 - 33.8 -28.8 - 34.6 -28.6 - 35.4 -28.4 - 36.3 -28.2 - 37.1 -27.9 - 37.9 -27.6 - 38.7 -27.3 - 39.5 -27.0 - 40.4 -26.7 - 41.2 -26.3 - 42.0 -25.9 - 42.8 -25.5 - 43.6 -25.1 - 44.4 -24.7 - 45.2 -24.2 - 46.0 -23.7 - 46.8 -23.2 - 47.6 -22.7 - 48.4 -22.2 - 49.2 -21.6 - 49.9 -21.1 - 50.7 -20.5 - 51.5 -19.8 - 52.2 -19.2 - 53.0 -18.6 - 53.8 -17.9 - 54.5 -17.2 - 55.3 -16.5 - 56.0 -15.8 - 56.8 -15.0 - 57.5 -14.3 - 58.2 -13.5 - 58.9 -12.7 - 68.4 .462 - 76.3 17.0 - 82.3 36.5 - 85.9 58.6 - 86.8 82.4 - 84.5 107. - 84.2 109. - 83.9 110. - 83.5 112. - 83.2 114. - 82.8 116. - 82.4 117. - 82.0 119. - 81.6 121. - 81.2 122. - 80.7 124. - 80.2 126. - 79.7 128. - 79.2 129. - 78.7 131. - 78.1 132. - 77.6 134. - 77.0 136. - 76.4 137. - 75.8 139. - 75.1 140. - 74.5 142. - 73.8 144. - 73.1 145. - 72.4 147. - 71.7 148. - 70.9 150. - 70.2 151. - 69.4 152. - 68.6 154. - 67.8 155. - 67.0 157. - 66.1 158. - 65.3 159. - 64.4 160. - 63.5 162. - 62.6 163. - 61.7 164. - 60.8 165. - 59.8 166. - 58.8 168. - 57.9 169. - 56.9 170. - 55.9 171. - 54.9 172. - 53.8 173. - 52.8 174. - 51.8 175. - 50.7 175. - 49.6 176. - 48.5 177. - 47.4 178. - 46.3 178. - 45.2 179. - 44.1 180. - 43.0 180. - 41.8 181. - 40.7 182. - 39.6 182. - 38.4 182. - 37.2 183. - 36.1 183. - 34.9 184. - 33.7 184. - 32.6 184. - 31.4 184. - 30.2 185. - 29.0 185. - 27.8 185. - 26.6 185. - 25.4 185. -REG_LINE: 15 - 25.4 -29.7 - 31.0 -16.7 - 35.7 -2.18 - 39.8 13.5 - 43.0 30.1 - 45.5 47.3 - 47.2 64.8 - 48.1 82.5 - 48.2 99.9 - 47.3 117. - 45.5 133. - 42.5 149. - 38.4 163. - 32.8 175. - 25.4 185. -REG_LINE: 197 - 52.0 -19.4 - 51.8 -18.1 - 51.5 -16.9 - 51.2 -15.6 - 50.9 -14.4 - 50.5 -13.2 - 50.1 -12.1 - 49.6 -11.0 - 49.1 -9.89 - 48.6 -8.84 - 48.0 -7.82 - 47.5 -6.84 - 46.8 -5.89 - 46.2 -4.97 - 45.5 -4.09 - 44.8 -3.25 - 44.1 -2.44 - 43.4 -1.67 - 42.6 -.931 - 41.8 -.233 - 41.0 .428 - 40.2 1.05 - 39.3 1.64 - 38.5 2.19 - 37.6 2.70 - 36.7 3.17 - 35.8 3.61 - 34.9 4.01 - 34.0 4.37 - 33.0 4.69 - 32.1 4.97 - 31.2 5.22 - 30.2 5.42 - 29.2 5.59 - 28.3 5.72 - 27.3 5.82 - 26.3 5.87 - 25.4 5.89 - 24.4 5.87 - 23.4 5.81 - 22.5 5.71 - 21.5 5.57 - 20.5 5.40 - 19.6 5.18 - 18.6 4.93 - 17.7 4.64 - 16.8 4.31 - 15.9 3.95 - 14.9 3.55 - 14.0 3.10 - 13.2 2.63 - 12.3 2.11 - 11.4 1.55 - 10.6 .962 - 9.77 .333 - 8.97 -.334 - 8.18 -1.04 - 7.42 -1.78 - 6.68 -2.56 - 5.96 -3.37 - 5.27 -4.22 - 4.60 -5.10 - 3.96 -6.02 - 3.35 -6.98 - 2.77 -7.97 - 2.22 -8.99 - 1.70 -10.1 - 1.22 -11.1 - .767 -12.3 - .353 -13.4 - -0.240E-01 -14.6 - -.362 -15.8 - -.660 -17.1 - -.917 -18.3 - -1.13 -19.6 - -1.30 -20.9 - -1.42 -22.3 - -1.50 -23.6 - -1.53 -25.0 - -1.51 -26.4 - -1.44 -27.8 - -1.32 -29.3 - -1.15 -30.7 - -.921 -32.2 - -.640 -33.6 - -.302 -35.1 - 0.909E-01 -36.5 - .541 -37.9 - 1.05 -39.4 - 1.61 -40.8 - 2.24 -42.2 - 2.92 -43.6 - 3.65 -44.9 - 4.45 -46.3 - 5.30 -47.5 - 6.20 -48.8 - 7.16 -50.0 - 8.17 -51.1 - 9.23 -52.2 - 10.3 -53.3 - 11.5 -54.2 - 12.7 -55.1 - 13.9 -55.9 - 15.2 -56.7 - 16.5 -57.3 - 17.9 -57.9 - 19.2 -58.4 - 20.6 -58.7 - 22.0 -59.0 - 23.4 -59.2 - 24.8 -59.3 - 26.3 -59.3 - 27.7 -59.2 - 29.1 -59.0 - 30.5 -58.7 - 31.9 -58.3 - 33.2 -57.8 - 34.6 -57.2 - 35.9 -56.6 - 37.1 -55.8 - 38.4 -55.0 - 39.6 -54.1 - 40.7 -53.1 - 41.8 -52.1 - 42.9 -51.0 - 43.9 -49.8 - 44.8 -48.6 - 45.7 -47.4 - 46.6 -46.1 - 47.4 -44.7 - 48.1 -43.4 - 48.8 -42.0 - 49.4 -40.6 - 49.9 -39.2 - 50.4 -37.7 - 50.9 -36.3 - 51.2 -34.8 - 51.6 -33.4 - 51.9 -31.9 - 52.1 -30.5 - 52.2 -29.1 - 52.3 -27.6 - 52.4 -26.2 - 52.4 -24.8 - 52.4 -23.4 - 52.3 -22.1 - 52.2 -20.7 - 52.0 -19.4 - 51.8 -18.1 - 51.5 -16.9 - 51.2 -15.6 - 50.9 -14.4 - 50.5 -13.2 - 50.1 -12.1 - 49.6 -11.0 - 49.1 -9.89 - 48.6 -8.84 - 48.0 -7.82 - 47.5 -6.84 - 46.8 -5.89 - 46.2 -4.97 - 45.5 -4.09 - 44.8 -3.25 - 44.1 -2.44 - 43.4 -1.67 - 42.6 -.931 - 41.8 -.233 - 41.0 .428 - 40.2 1.05 - 39.3 1.64 - 38.5 2.19 - 37.6 2.70 - 36.7 3.17 - 35.8 3.61 - 34.9 4.01 - 34.0 4.37 - 33.0 4.69 - 32.1 4.97 - 31.2 5.22 - 30.2 5.42 - 29.2 5.59 - 28.3 5.72 - 27.3 5.82 - 26.3 5.87 - 25.4 5.89 - 24.4 5.87 - 23.4 5.81 - 22.5 5.71 - 21.5 5.57 - 20.5 5.40 - 19.6 5.18 - 18.6 4.93 - 17.7 4.64 - 16.8 4.31 - 15.9 3.95 - 14.9 3.55 - 14.0 3.10 -REG_LINE: 197 - 73.9 11.1 - 73.1 13.1 - 72.3 14.9 - 71.5 16.8 - 70.6 18.5 - 69.7 20.2 - 68.7 21.8 - 67.7 23.3 - 66.6 24.8 - 65.5 26.3 - 64.4 27.7 - 63.2 29.0 - 62.0 30.2 - 60.7 31.4 - 59.5 32.6 - 58.2 33.7 - 56.9 34.7 - 55.5 35.7 - 54.2 36.7 - 52.8 37.5 - 51.4 38.4 - 49.9 39.2 - 48.5 39.9 - 47.0 40.6 - 45.5 41.2 - 44.0 41.8 - 42.5 42.3 - 41.0 42.8 - 39.5 43.3 - 37.9 43.7 - 36.4 44.0 - 34.8 44.3 - 33.2 44.6 - 31.7 44.8 - 30.1 44.9 - 28.5 45.0 - 26.9 45.1 - 25.3 45.1 - 23.7 45.1 - 22.2 45.0 - 20.6 44.9 - 19.0 44.7 - 17.4 44.5 - 15.9 44.3 - 14.3 44.0 - 12.8 43.6 - 11.2 43.2 - 9.68 42.8 - 8.15 42.3 - 6.65 41.7 - 5.15 41.1 - 3.67 40.5 - 2.20 39.8 - .758 39.0 - -.671 38.2 - -2.08 37.4 - -3.47 36.5 - -4.83 35.6 - -6.17 34.6 - -7.49 33.5 - -8.78 32.4 - -10.0 31.3 - -11.3 30.0 - -12.5 28.8 - -13.6 27.5 - -14.8 26.1 - -15.9 24.6 - -16.9 23.1 - -17.9 21.6 - -18.9 19.9 - -19.8 18.2 - -20.7 16.5 - -21.6 14.7 - -22.3 12.8 - -23.1 10.8 - -23.7 8.81 - -24.4 6.71 - -24.9 4.55 - -25.4 2.30 - -25.8 -0.953E-02 - -26.1 -2.40 - -26.4 -4.86 - -26.6 -7.41 - -26.7 -10.0 - -26.7 -12.7 - -26.6 -15.5 - -26.4 -18.3 - -26.0 -21.3 - -25.6 -24.2 - -25.0 -27.3 - -24.4 -30.4 - -23.5 -33.6 - -22.6 -36.8 - -21.4 -40.1 - -20.2 -43.4 - -18.7 -46.7 - -17.1 -49.9 - -15.3 -53.2 - -13.3 -56.4 - -11.1 -59.6 - -8.73 -62.7 - -6.17 -65.6 - -3.42 -68.3 - -.492 -70.9 - 2.61 -73.3 - 5.87 -75.3 - 9.27 -77.1 - 12.8 -78.6 - 16.4 -79.7 - 20.1 -80.5 - 23.8 -80.8 - 27.6 -80.8 - 31.3 -80.4 - 35.0 -79.6 - 38.6 -78.4 - 42.1 -76.9 - 45.5 -75.1 - 48.8 -72.9 - 51.8 -70.6 - 54.7 -67.9 - 57.5 -65.2 - 60.0 -62.2 - 62.3 -59.1 - 64.5 -56.0 - 66.4 -52.7 - 68.2 -49.5 - 69.8 -46.2 - 71.2 -42.9 - 72.5 -39.6 - 73.6 -36.3 - 74.6 -33.1 - 75.4 -30.0 - 76.0 -26.8 - 76.6 -23.8 - 77.0 -20.8 - 77.3 -17.9 - 77.5 -15.1 - 77.6 -12.3 - 77.5 -9.63 - 77.4 -7.03 - 77.3 -4.50 - 77.0 -2.04 - 76.6 .337 - 76.2 2.64 - 75.7 4.87 - 75.2 7.03 - 74.5 9.11 - 73.9 11.1 - 73.1 13.1 - 72.3 14.9 - 71.5 16.8 - 70.6 18.5 - 69.7 20.2 - 68.7 21.8 - 67.7 23.3 - 66.6 24.8 - 65.5 26.3 - 64.4 27.7 - 63.2 29.0 - 62.0 30.2 - 60.7 31.4 - 59.5 32.6 - 58.2 33.7 - 56.9 34.7 - 55.5 35.7 - 54.2 36.7 - 52.8 37.5 - 51.4 38.4 - 49.9 39.2 - 48.5 39.9 - 47.0 40.6 - 45.5 41.2 - 44.0 41.8 - 42.5 42.3 - 41.0 42.8 - 39.5 43.3 - 37.9 43.7 - 36.4 44.0 - 34.8 44.3 - 33.2 44.6 - 31.7 44.8 - 30.1 44.9 - 28.5 45.0 - 26.9 45.1 - 25.3 45.1 - 23.7 45.1 - 22.2 45.0 - 20.6 44.9 - 19.0 44.7 - 17.4 44.5 - 15.9 44.3 - 14.3 44.0 - 12.8 43.6 - 11.2 43.2 - 9.68 42.8 - 8.15 42.3 - 6.65 41.7 -REG_LINE: 197 - 85.9 58.6 - 84.7 60.1 - 83.5 61.6 - 82.2 63.1 - 80.8 64.4 - 79.5 65.8 - 78.1 67.0 - 76.7 68.3 - 75.2 69.4 - 73.7 70.6 - 72.2 71.6 - 70.7 72.7 - 69.2 73.6 - 67.6 74.6 - 66.0 75.5 - 64.4 76.3 - 62.7 77.2 - 61.1 77.9 - 59.4 78.7 - 57.7 79.3 - 56.0 80.0 - 54.3 80.6 - 52.5 81.2 - 50.8 81.7 - 49.0 82.2 - 47.2 82.7 - 45.5 83.1 - 43.7 83.5 - 41.8 83.8 - 40.0 84.1 - 38.2 84.4 - 36.4 84.7 - 34.5 84.9 - 32.7 85.0 - 30.9 85.1 - 29.0 85.2 - 27.2 85.3 - 25.3 85.3 - 23.5 85.3 - 21.6 85.2 - 19.8 85.1 - 17.9 85.0 - 16.1 84.8 - 14.2 84.6 - 12.4 84.4 - 10.6 84.1 - 8.78 83.8 - 6.97 83.4 - 5.17 83.0 - 3.39 82.6 - 1.61 82.2 - -.156 81.6 - -1.91 81.1 - -3.65 80.5 - -5.37 79.9 - -7.08 79.2 - -8.77 78.6 - -10.4 77.8 - -12.1 77.0 - -13.7 76.2 - -15.3 75.4 - -16.9 74.4 - -18.5 73.5 - -20.1 72.5 - -21.6 71.5 - -23.1 70.4 - -24.5 69.3 - -26.0 68.1 - -27.4 66.9 - -28.8 65.6 - -30.1 64.2 - -31.5 62.9 - -32.8 61.4 - -34.0 59.9 - -35.2 58.4 - -36.4 56.7 - -37.6 55.0 - -38.7 53.3 - -39.7 51.4 - -40.7 49.5 - -41.7 47.5 - -42.6 45.4 - -43.5 43.2 - -44.3 40.9 - -45.0 38.5 - -45.7 36.0 - -46.4 33.4 - -46.9 30.6 - -47.4 27.6 - -47.7 24.5 - -48.0 21.3 - -48.2 17.8 - -48.3 14.1 - -48.2 10.1 - -47.9 5.89 - -47.5 1.37 - -46.9 -3.46 - -46.0 -8.66 - -44.9 -14.2 - -43.4 -20.2 - -41.5 -26.7 - -39.1 -33.6 - -36.1 -40.9 - -32.4 -48.6 - -27.8 -56.6 - -22.3 -64.7 - -15.8 -72.6 - -8.06 -79.8 - .764 -86.0 - 10.5 -90.4 - 20.9 -92.6 - 31.5 -92.5 - 41.9 -89.9 - 51.5 -85.2 - 60.2 -78.8 - 67.7 -71.4 - 74.1 -63.5 - 79.5 -55.4 - 83.9 -47.5 - 87.5 -39.8 - 90.4 -32.5 - 92.7 -25.7 - 94.5 -19.3 - 96.0 -13.4 - 97.1 -7.87 - 97.9 -2.73 - 98.5 2.06 - 98.9 6.53 - 99.1 10.7 - 99.2 14.6 - 99.1 18.3 - 98.9 21.7 - 98.6 25.0 - 98.2 28.1 - 97.7 31.0 - 97.2 33.8 - 96.5 36.4 - 95.8 38.9 - 95.1 41.3 - 94.3 43.6 - 93.4 45.7 - 92.5 47.8 - 91.5 49.8 - 90.5 51.7 - 89.4 53.5 - 88.3 55.3 - 87.1 57.0 - 85.9 58.6 - 84.7 60.1 - 83.5 61.6 - 82.2 63.1 - 80.8 64.4 - 79.5 65.8 - 78.1 67.0 - 76.7 68.3 - 75.2 69.4 - 73.7 70.6 - 72.2 71.6 - 70.7 72.7 - 69.2 73.6 - 67.6 74.6 - 66.0 75.5 - 64.4 76.3 - 62.7 77.2 - 61.1 77.9 - 59.4 78.7 - 57.7 79.3 - 56.0 80.0 - 54.3 80.6 - 52.5 81.2 - 50.8 81.7 - 49.0 82.2 - 47.2 82.7 - 45.5 83.1 - 43.7 83.5 - 41.8 83.8 - 40.0 84.1 - 38.2 84.4 - 36.4 84.7 - 34.5 84.9 - 32.7 85.0 - 30.9 85.1 - 29.0 85.2 - 27.2 85.3 - 25.3 85.3 - 23.5 85.3 - 21.6 85.2 - 19.8 85.1 - 17.9 85.0 - 16.1 84.8 - 14.2 84.6 - 12.4 84.4 - 10.6 84.1 - 8.78 83.8 - 6.97 83.4 - 5.17 83.0 - 3.39 82.6 -REG_LINE: 145 - 82.9 115. - 63.7 120. - 40.9 123. - 16.6 123. - -6.79 121. - -27.2 116. - -28.5 116. - -29.8 116. - -31.0 115. - -32.2 115. - -33.4 115. - -34.5 114. - -35.7 114. - -36.7 114. - -37.8 114. - -38.8 113. - -39.8 113. - -40.7 113. - -41.6 113. - -42.5 113. - -43.3 113. - -44.1 113. - -44.8 113. - -45.5 114. - -46.1 114. - -46.7 114. - -47.2 115. - -47.7 116. - -48.1 117. - -48.4 118. - -48.6 119. - -48.7 121. - -48.6 123. - -48.4 125. - -48.0 128. - -47.4 132. - -46.4 136. - -45.0 141. - -43.0 147. - -40.2 154. - -36.3 163. - -30.8 173. - -23.1 184. - -12.5 196. - -11.6 197. - -10.7 198. - -9.78 198. - -8.85 199. - -7.90 200. - -6.94 201. - -5.96 201. - -4.96 202. - -3.94 203. - -2.91 203. - -1.87 204. - -.804 205. - .274 205. - 1.37 206. - 2.47 207. - 3.60 207. - 4.73 208. - 5.88 208. - 7.04 209. - 8.21 209. - 9.40 209. - 10.6 210. - 11.8 210. - 13.0 211. - 14.2 211. - 15.5 211. - 16.7 211. - 17.9 212. - 19.2 212. - 20.4 212. - 21.7 212. - 23.0 212. - 24.2 212. - 25.5 212. - 26.8 212. - 28.0 212. - 29.3 212. - 30.5 212. - 31.8 212. - 33.0 212. - 34.3 211. - 35.5 211. - 36.7 211. - 38.0 211. - 39.2 210. - 40.4 210. - 41.6 209. - 42.8 209. - 43.9 209. - 45.1 208. - 46.2 208. - 47.4 207. - 48.5 206. - 49.6 206. - 50.7 205. - 51.8 205. - 65.1 194. - 75.3 183. - 82.6 171. - 87.9 162. - 91.6 153. - 94.3 146. - 96.1 140. - 97.5 135. - 98.4 131. - 99.0 128. - 99.3 125. - 99.5 122. - 99.5 121. - 99.4 119. - 99.2 118. - 98.9 116. - 98.5 116. - 98.1 115. - 97.5 114. - 97.0 114. - 96.3 114. - 95.6 113. - 94.9 113. - 94.1 113. - 93.3 113. - 92.4 113. - 91.5 113. - 90.5 113. - 89.5 113. - 88.5 114. - 87.5 114. - 86.4 114. - 85.3 114. - 84.1 115. - 82.9 115. - 81.7 115. - 80.5 116. - 79.2 116. - 77.9 116. - 76.6 117. - 75.3 117. - 73.9 117. - 52.6 122. - 28.8 124. - 4.68 123. -REG_LINE: 145 - 61.4 165. - 60.9 164. - 60.3 163. - 59.7 163. - 59.0 163. - 58.4 162. - 57.6 162. - 56.9 161. - 56.1 161. - 55.3 161. - 54.5 160. - 53.6 160. - 52.7 160. - 51.8 160. - 50.9 159. - 49.9 159. - 48.9 159. - 47.9 159. - 46.9 159. - 45.9 159. - 44.8 158. - 43.8 158. - 42.7 158. - 41.6 158. - 40.5 158. - 39.4 158. - 38.2 158. - 37.1 158. - 35.9 158. - 19.4 158. - 3.82 159. - 2.81 159. - 1.81 159. - .836 159. - -.119 159. - -1.05 160. - -1.96 160. - -2.85 160. - -3.71 160. - -4.54 161. - -5.35 161. - -6.12 161. - -6.86 162. - -7.57 162. - -8.25 163. - -8.88 163. - -9.48 164. - -10.0 164. - -10.6 165. - -11.0 165. - -11.5 166. - -11.8 167. - -12.2 167. - -12.4 168. - -12.6 169. - -12.8 170. - -12.9 171. - -12.9 172. - -12.9 173. - -12.7 174. - -12.5 175. - -12.3 176. - -11.9 177. - -11.4 178. - -10.9 180. - -10.2 181. - -9.43 183. - -8.55 184. - -7.56 186. - -6.44 187. - -5.21 189. - -3.85 190. - -2.36 192. - -.742 193. - 1.01 195. - 2.88 196. - 4.88 197. - 7.00 199. - 9.23 200. - 11.6 201. - 14.0 202. - 16.5 202. - 19.1 203. - 21.7 203. - 24.3 203. - 27.0 203. - 29.6 203. - 32.2 203. - 34.8 202. - 37.3 202. - 39.7 201. - 42.0 200. - 44.2 198. - 46.3 197. - 48.3 196. - 50.2 194. - 51.9 193. - 53.5 191. - 55.0 190. - 56.3 188. - 57.5 187. - 58.6 185. - 59.6 184. - 60.4 182. - 61.2 181. - 61.8 180. - 62.4 178. - 62.8 177. - 63.2 176. - 63.5 175. - 63.7 173. - 63.8 172. - 63.8 171. - 63.8 170. - 63.7 170. - 63.5 169. - 63.3 168. - 63.0 167. - 62.7 166. - 62.3 166. - 61.9 165. - 61.4 165. - 60.9 164. - 60.3 163. - 59.7 163. - 59.0 163. - 58.4 162. - 57.6 162. - 56.9 161. - 56.1 161. - 55.3 161. - 54.5 160. - 53.6 160. - 52.7 160. - 51.8 160. - 50.9 159. - 49.9 159. - 48.9 159. - 47.9 159. - 46.9 159. - 45.9 159. - 44.8 158. - 43.8 158. - 27.7 158. - 11.4 158. -REG_LINE: 2 - 80.7 64.6 - 80.8 66.3 -REG_LINE: 2 - 75.0 69.6 - 75.1 71.4 -REG_LINE: 2 - 68.8 73.9 - 68.8 75.6 -REG_LINE: 2 - 62.2 77.4 - 62.2 79.2 -REG_LINE: 2 - 55.3 80.3 - 55.3 82.0 -REG_LINE: 2 - 40.8 84.0 - 40.8 85.8 -REG_LINE: 2 - 33.3 85.0 - 33.3 86.7 -REG_LINE: 2 - 25.8 85.3 - 25.8 87.0 -REG_LINE: 2 - 18.2 85.0 - 18.2 86.8 -REG_LINE: 2 - 10.7 84.1 - 10.7 85.9 -REG_LINE: 2 - -3.79 80.5 - -3.83 82.2 -REG_LINE: 2 - -10.7 77.7 - -10.8 79.4 -REG_LINE: 2 - -17.3 74.2 - -17.4 76.0 -REG_LINE: 2 - -23.6 70.0 - -23.6 71.8 -REG_LINE: 2 - -29.4 65.0 - -29.5 66.8 -REG_LINE: 2 - -39.3 52.2 - -39.4 54.0 -REG_LINE: 2 - -43.2 44.0 - -43.4 45.7 -REG_LINE: 2 - -46.2 34.0 - -46.4 35.8 -REG_LINE: 2 - -48.0 21.8 - -48.3 23.5 -REG_LINE: 2 - -48.0 6.25 - -48.3 7.96 -REG_LINE: 2 - -35.8 -41.5 - -36.5 -39.9 -REG_LINE: 2 - -14.6 -73.9 - -15.8 -72.6 -REG_LINE: 2 - 23.6 -92.8 - 22.6 -94.3 -REG_LINE: 2 - 62.8 -76.5 - 64.1 -75.2 -REG_LINE: 2 - 85.5 -44.2 - 86.2 -42.6 -REG_LINE: 2 - 98.7 4.70 - 99.1 6.41 -REG_LINE: 2 - 99.0 20.6 - 99.3 22.3 -REG_LINE: 2 - 97.3 33.1 - 97.5 34.8 -REG_LINE: 2 - 94.4 43.2 - 94.6 44.9 -REG_LINE: 2 - 90.5 51.6 - 90.7 53.3 -REG_LINE: 2 - 80.7 64.6 - 80.8 66.3 -REG_LINE: 2 - 75.0 69.6 - 75.1 71.4 -REG_LINE: 2 - 68.8 73.9 - 68.8 75.6 -REG_LINE: 2 - 62.2 77.4 - 62.2 79.2 -REG_LINE: 2 - 55.3 80.3 - 55.3 82.0 -REG_LINE: 2 - 40.8 84.0 - 40.8 85.8 -REG_LINE: 2 - 33.3 85.0 - 33.3 86.7 -REG_LINE: 2 - 25.8 85.3 - 25.8 87.0 -REG_LINE: 2 - 18.2 85.0 - 18.2 86.8 -REG_LINE: 2 - 10.7 84.1 - 10.7 85.9 -REG_LINE: 2 - 23.1 -34.3 - 21.6 -33.5 -REG_LINE: 2 - 20.6 -38.6 - 19.1 -37.7 -REG_LINE: 2 - 18.0 -42.6 - 16.5 -41.7 -REG_LINE: 2 - 15.2 -46.2 - 13.8 -45.2 -REG_LINE: 2 - 12.3 -49.4 - 10.9 -48.4 -REG_LINE: 2 - 6.00 -54.5 - 4.63 -53.5 -REG_LINE: 2 - 2.59 -56.3 - 1.25 -55.2 -REG_LINE: 2 - -1.03 -57.5 - -2.33 -56.3 -REG_LINE: 2 - -4.86 -58.0 - -6.12 -56.8 -REG_LINE: 2 - -8.94 -57.7 - -10.1 -56.4 -REG_LINE: 2 - -17.9 -54.1 - -19.0 -52.7 -REG_LINE: 2 - -22.8 -50.3 - -23.9 -48.9 -REG_LINE: 2 - -28.1 -44.9 - -29.0 -43.4 -REG_LINE: 2 - -33.6 -37.4 - -34.4 -35.9 -REG_LINE: 2 - -39.3 -27.4 - -40.0 -25.8 -REG_LINE: 2 - -50.1 2.52 - -50.5 4.22 -REG_LINE: 2 - -54.3 23.2 - -54.6 24.9 -REG_LINE: 2 - -56.8 47.3 - -56.8 49.1 -REG_LINE: 2 - -56.8 73.8 - -56.1 75.5 -REG_LINE: 2 - -53.9 101. - -54.0 98.8 -REG_LINE: 2 - -41.1 146. - -41.7 144. -REG_LINE: 2 - -32.8 162. - -33.7 161. -REG_LINE: 2 - -24.5 175. - -25.5 173. -REG_LINE: 2 - -16.5 183. - -17.6 182. -REG_LINE: 2 - -9.06 188. - -10.4 187. -REG_LINE: 2 - 3.65 193. - 2.17 192. -REG_LINE: 2 - 9.03 193. - 7.49 192. -REG_LINE: 2 - 13.8 192. - 12.2 192. -REG_LINE: 2 - 18.1 190. - 16.5 190. -REG_LINE: 2 - 22.0 188. - 20.3 187. -REG_LINE: 15 - 48.1 82.5 - 51.2 81.6 - 54.3 80.6 - 57.3 79.5 - 60.3 78.3 - 63.2 77.0 - 66.0 75.5 - 68.8 73.9 - 71.5 72.2 - 74.1 70.3 - 76.7 68.3 - 79.1 66.1 - 81.5 63.8 - 83.8 61.3 - 85.9 58.6 -REG_LINE: 15 - 48.1 82.5 - 45.0 83.2 - 41.8 83.8 - 38.7 84.4 - 35.5 84.8 - 32.2 85.0 - 29.0 85.2 - 25.8 85.3 - 22.5 85.3 - 19.3 85.1 - 16.1 84.8 - 12.9 84.4 - 9.69 83.9 - 6.52 83.3 - 3.39 82.6 -REG_LINE: 15 - 3.39 82.6 - .284 81.8 - -2.78 80.8 - -5.80 79.7 - -8.77 78.6 - -11.7 77.2 - -14.5 75.8 - -17.3 74.2 - -20.1 72.5 - -22.7 70.7 - -25.3 68.7 - -27.8 66.5 - -30.1 64.2 - -32.4 61.8 - -34.6 59.1 -REG_LINE: 15 - -34.6 59.1 - -36.7 56.3 - -38.7 53.3 - -40.5 50.0 - -42.2 46.5 - -43.7 42.7 - -45.0 38.5 - -46.2 34.0 - -47.1 29.1 - -47.8 23.7 - -48.2 17.8 - -48.2 11.1 - -47.8 3.67 - -46.7 -4.73 - -44.9 -14.2 -REG_LINE: 93 - -44.9 -14.2 - -42.0 -25.0 - -37.7 -37.2 - -31.3 -50.6 - -22.3 -64.7 - -21.6 -65.7 - -20.8 -66.7 - -20.0 -67.7 - -19.2 -68.7 - -18.4 -69.7 - -17.5 -70.7 - -16.7 -71.6 - -15.8 -72.6 - -14.9 -73.5 - -14.0 -74.5 - -13.0 -75.4 - -12.1 -76.3 - -11.1 -77.2 - -10.1 -78.1 - -9.08 -79.0 - -8.06 -79.8 - -7.01 -80.7 - -5.95 -81.5 - -4.87 -82.3 - -3.78 -83.1 - -2.67 -83.8 - -1.54 -84.6 - -.395 -85.3 - .764 -86.0 - 1.94 -86.6 - 3.13 -87.2 - 4.33 -87.8 - 5.54 -88.4 - 6.77 -89.0 - 8.01 -89.5 - 9.27 -89.9 - 10.5 -90.4 - 11.8 -90.8 - 13.1 -91.2 - 14.4 -91.5 - 15.7 -91.8 - 17.0 -92.1 - 18.3 -92.3 - 19.6 -92.5 - 20.9 -92.6 - 22.3 -92.8 - 23.6 -92.8 - 24.9 -92.9 - 26.2 -92.9 - 27.6 -92.8 - 28.9 -92.7 - 30.2 -92.6 - 31.5 -92.5 - 32.8 -92.3 - 34.2 -92.0 - 35.5 -91.8 - 36.8 -91.4 - 38.0 -91.1 - 39.3 -90.7 - 40.6 -90.3 - 41.9 -89.9 - 43.1 -89.4 - 44.3 -88.9 - 45.6 -88.3 - 46.8 -87.7 - 48.0 -87.1 - 49.2 -86.5 - 50.3 -85.8 - 51.5 -85.2 - 52.6 -84.4 - 53.8 -83.7 - 54.9 -82.9 - 56.0 -82.2 - 57.0 -81.4 - 58.1 -80.5 - 59.1 -79.7 - 60.2 -78.8 - 61.2 -78.0 - 62.2 -77.1 - 63.1 -76.2 - 64.1 -75.2 - 65.0 -74.3 - 65.9 -73.4 - 66.8 -72.4 - 67.7 -71.4 - 68.6 -70.5 - 69.4 -69.5 - 70.2 -68.5 - 71.1 -67.5 - 80.7 -53.4 - 87.5 -39.8 - 92.1 -27.4 - 95.3 -16.3 -REG_LINE: 15 - 95.3 -16.3 - 97.3 -6.55 - 98.5 2.06 - 99.1 9.69 - 99.1 16.5 - 98.8 22.6 - 98.2 28.1 - 97.3 33.1 - 96.2 37.7 - 94.9 41.9 - 93.4 45.7 - 91.7 49.3 - 89.9 52.6 - 88.0 55.7 - 85.9 58.6 -REG_LINE: 15 - 85.9 58.6 - 83.8 61.3 - 81.5 63.8 - 79.1 66.1 - 76.7 68.3 - 74.1 70.3 - 71.5 72.2 - 68.8 73.9 - 66.0 75.5 - 63.2 77.0 - 60.3 78.3 - 57.3 79.5 - 54.3 80.6 - 51.2 81.6 - 48.1 82.5 -REG_LINE: 15 - 48.1 82.5 - 45.0 83.2 - 41.8 83.8 - 38.7 84.4 - 35.5 84.8 - 32.2 85.0 - 29.0 85.2 - 25.8 85.3 - 22.5 85.3 - 19.3 85.1 - 16.1 84.8 - 12.9 84.4 - 9.69 83.9 - 6.52 83.3 - 3.39 82.6 -REG_LINE: 15 - 48.1 82.5 - 45.0 83.2 - 41.8 83.8 - 38.7 84.4 - 35.5 84.8 - 32.2 85.0 - 29.0 85.2 - 25.8 85.3 - 22.5 85.3 - 19.3 85.1 - 16.1 84.8 - 12.9 84.4 - 9.69 83.9 - 6.52 83.3 - 3.39 82.6 -REG_LINE: 15 - 25.4 -29.7 - 24.4 -31.7 - 23.4 -33.7 - 22.4 -35.6 - 21.3 -37.4 - 20.2 -39.2 - 19.1 -40.9 - 18.0 -42.6 - 16.8 -44.2 - 15.6 -45.7 - 14.4 -47.2 - 13.1 -48.6 - 11.9 -49.9 - 10.6 -51.1 - 9.23 -52.2 -REG_LINE: 15 - 9.23 -52.2 - 7.87 -53.3 - 6.48 -54.2 - 5.05 -55.1 - 3.58 -55.9 - 2.08 -56.5 - .548 -57.1 - -1.03 -57.5 - -2.64 -57.8 - -4.30 -58.0 - -6.00 -58.0 - -7.75 -57.9 - -9.54 -57.6 - -11.4 -57.1 - -13.3 -56.4 -REG_LINE: 15 - -13.3 -56.4 - -15.2 -55.6 - -17.2 -54.5 - -19.3 -53.2 - -21.4 -51.6 - -23.6 -49.7 - -25.8 -47.5 - -28.1 -44.9 - -30.4 -42.0 - -32.8 -38.6 - -35.2 -34.8 - -37.6 -30.5 - -40.1 -25.7 - -42.5 -20.3 - -44.9 -14.2 -REG_LINE: 15 - -44.9 -14.2 - -47.2 -7.52 - -49.4 -.109 - -51.4 8.02 - -53.3 16.9 - -54.8 26.4 - -56.0 36.6 - -56.8 47.3 - -57.1 58.5 - -56.9 70.0 - -56.2 81.6 - -55.0 93.1 - -53.3 104. - -51.0 115. - -48.4 125. -REG_LINE: 15 - -48.4 125. - -45.4 135. - -42.2 143. - -38.8 151. - -35.2 158. - -31.6 164. - -28.0 170. - -24.5 175. - -21.0 179. - -17.6 182. - -14.3 185. - -11.1 187. -Forward matrix value - M2 = -0.811474832908671 # Forward matrix value - M3 = 0.171224898552328 # Forward matrix value - M4 = -0.862236746712233 # Forward matrix value - M5 = -0.476686298035564 # Forward matrix value - M6 = -0.941127638091139 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = -0.338051429254475 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = -2.61046557479594 # Polar longitude (rad.s) - End SphMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End FrameSet - Begin FrameSet # Set of inter-related coordinate systems -# Title = "Pixel coordinates; first pixel at (-100.5,-200.5)" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "POLAR" # Coordinate system domain -# Lbl1 = "Pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Pixel coordinate 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - IsA Frame # Coordinate system description - Nframe = 2 # Number of Frames in FrameSet -# Base = 1 # Index of base Frame - Currnt = 2 # Index of current Frame - Nod1 = 2 # Frame 1 is associated with node 2 - Nod2 = 1 # Frame 2 is associated with node 1 - Lnk2 = 1 # Node 2 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Data grid indices; first pixel at (1,1) " # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Data grid index 1" # Label for axis 1 -# Lbl2 = "Data grid index 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Data grid index 1" # Axis Label - Symbol = "g1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Data grid index 2" # Axis Label - Symbol = "g2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm2 = # Frame number 2 - Begin Frame # Coordinate system description - Title = "Pixel coordinates; first pixel at (-100.5,-200.5)" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "POLAR" # Coordinate system domain -# Lbl1 = "Pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Pixel coordinate 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 1" # Axis Label - -8.06 189. - -5.15 190. - -2.36 192. -REG_LINE: 15 - -2.36 192. - .299 192. - 2.83 193. - 5.25 193. - 7.56 193. - 9.75 193. - 11.8 193. - 13.8 192. - 15.7 192. - 17.6 191. - 19.3 190. - 20.9 189. - 22.5 188. - 24.0 186. - 25.4 185. -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '180' - 47.5 80.0 TC .248 .969 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '240' - 4.00 80.2 TC -.245 .969 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '300' - -32.7 57.6 TC -.786 .618 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0' - -42.4 -13.7 BC .976 .217 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '60' - 92.9 -15.7 BC -.971 .241 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '120' - 84.0 57.1 TC .798 .602 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-90' - 27.7 -30.8 TC -.899 .438 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-60' - 10.8 -54.2 TC -.629 .777 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-30' - -14.2 -58.8 TC .374 .927 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0' - -47.2 -15.1 TC .937 .350 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '30' - -50.8 126. BC -.960 .278 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '60' - -3.21 194. BC -.341 .940 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '90' - 27.2 187. BC .711 .704 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 1 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: ' A FITS test' - 31.5 225. BC .000 1.00 - - - - - FITS test number 2 - ==================== - - - -AST_SHOW: - -REG_SINK: -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -AST -COMMENT AST Beginning of AST data for FrameSet object -AST -COMMENT AST ................................................................ -AST -COMMENT AST ................................................................ -AST -COMMENT AST End of AST data for FrameSet object -AST -COMMENT AST ---------------------------------------------------------------- - -Objects written: 1 - -Native Encoding: - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST WCS information in AST format AST -COMMENT AST See http://www.starlink.ac.uk/ast/ AST -COMMENT AST Beginning of AST data for FrameSet object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'FrameSet' / Set of inter-related coordinate systems -NFRAME_A= 2 / Number of Frames in FrameSet -CURRNT_A= 2 / Index of current Frame -NOD1_A = 2 / Frame 1 is associated with node 2 -NOD2_A = 1 / Frame 2 is associated with node 1 -LNK2_A = 1 / Node 2 is derived from node 1 -FRM1_A = ' ' / Frame number 1 -BEGAST_B= 'Frame ' / Coordinate system description -TITLE_A = 'Data grid indices; first pixel at (1&'/ Title of coordinate system -CONTINUE '",1) "' -NAXES_A = 2 / Number of coordinate axes -DOMAIN_A= 'GRID ' / Coordinate system domain -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -LABEL_A = 'Data grid index 1' / Axis Label -SYMBOL_A= 'g1 ' / Axis symbol -UNIT_A = 'pixel ' / Axis units -FORMAT_A= '%3.1f ' / Format specifier -ENDAST_A= 'Axis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_D= 'Axis ' / Coordinate axis -LABEL_B = 'Data grid index 2' / Axis Label -SYMBOL_B= 'g2 ' / Axis symbol -UNIT_B = 'pixel ' / Axis units -FORMAT_B= '%3.1f ' / Format specifier -ENDAST_B= 'Axis ' / End of object definition -ENDAST_C= 'Frame ' / End of object definition -FRM2_A = ' ' / Frame number 2 -BEGAST_E= 'Frame ' / Coordinate system description -TITLE_B = 'Pixel coordinates; first pixel at (-&'/ Title of coordinate system -CONTINUE '100.5,-200.5)' -NAXES_B = 2 / Number of coordinate axes -DOMAIN_B= 'POLAR ' / Coordinate system domain -AX1_B = ' ' / Axis number 1 -BEGAST_F= 'Axis ' / Coordinate axis -LABEL_C = 'Pixel coordinate 1' / Axis Label -SYMBOL_C= 'p1 ' / Axis symbol -UNIT_C = 'pixel ' / Axis units -FORMAT_C= '%3.1f ' / Format specifier -ENDAST_D= 'Axis ' / End of object definition -AX2_B = ' ' / Axis number 2 -BEGAST_G= 'Axis ' / Coordinate axis -LABEL_D = 'Pixel coordinate 2' / Axis Label -SYMBOL_D= 'p2 ' / Axis symbol -UNIT_D = 'pixel ' / Axis units -FORMAT_D= '%3.1f ' / Format specifier -ENDAST_E= 'Axis ' / End of object definition -ENDAST_F= 'Frame ' / End of object definition -MAP2_A = ' ' / Mapping between nodes 1 and 2 -BEGAST_H= 'CmpMap ' / Compound Mapping -NIN_A = 2 / Number of input coordinates -ISA_A = 'Mapping ' / Mapping between coordinate systems -INVA_A = 1 / First Mapping used in inverse direction -INVB_A = 1 / Second Mapping used in inverse direction -MAPA_A = ' ' / First component Mapping -BEGAST_I= 'MathMap ' / Transformation using mathematical functions -NIN_B = 2 / Number of input coordinates -INVERT_A= 0 / Mapping not inverted -ISA_B = 'Mapping ' / Mapping between coordinate systems -FWD1_A = 'r=sqrt(x*x+y*y)' / Forward function 1 -FWD2_A = 'theta=atan2(y,x)' / Forward function 2 -INV1_A = 'x=r*cos(theta)' / Inverse function 1 -INV2_A = 'y=r*sin(theta)' / Inverse function 2 -SIMPFI_A= 1 / Forward-inverse pairs may simplify -SIMPIF_A= 1 / Inverse-forward pairs may simplify -ENDAST_G= 'MathMap ' / End of object definition -MAPB_A = ' ' / Second component Mapping -BEGAST_J= 'WinMap ' / Map one window on to another -NIN_C = 2 / Number of input coordinates -INVERT_B= 0 / Mapping not inverted -ISA_C = 'Mapping ' / Mapping between coordinate systems -SFT1_A = -101.5 / Shift for axis 1 -SFT2_A = -201.5 / Shift for axis 2 -ENDAST_H= 'WinMap ' / End of object definition -ENDAST_I= 'CmpMap ' / End of object definition -ENDAST_J= 'FrameSet' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for FrameSet object AST -COMMENT AST ---------------------------------------------------------------- AST - -ATTRIBUTES: - Colour(axis1) : 1 - Font(Stri) : 1 - Nout : 1 - Class : 4 - Tol : 0.100000E-01 - Gap(1) : 50.0000 - Border : 0 - Invert : 0 - TextLabGap : 0.100000E-01 - Nin : 2 - Current : 3 - Base : 1 - Nobject : 1 - RefCOUNT : 1 - -AST_GRID: -REG_LINE: 197 - 10.8 124. - 10.7 123. - 10.5 122. - 10.3 121. - 10.2 120. - 10.1 119. - 10.0 118. - 9.94 117. - 9.89 116. - 9.85 115. - 9.84 113. - 9.85 112. - 9.88 111. - 9.93 110. - 10.0 109. - 10.1 108. - 10.2 107. - 10.3 106. - 10.5 105. - 10.6 104. - 10.8 103. - 11.0 102. - 11.2 100. - 11.5 99.5 - 11.7 98.5 - 12.0 97.5 - 12.3 96.6 - 12.6 95.6 - 13.0 94.7 - 13.3 93.9 - 13.7 93.0 - 14.0 92.2 - 14.4 91.4 - 14.8 90.6 - 15.2 89.8 - 15.7 89.1 - 16.1 88.4 - 16.5 87.8 - 17.0 87.2 - 17.5 86.6 - 18.0 86.0 - 18.5 85.5 - 19.0 85.0 - 19.5 84.6 - 20.0 84.2 - 20.5 83.8 - 21.1 83.5 - 21.6 83.2 - 22.1 82.9 - 22.7 82.7 - 23.2 82.5 - 23.8 82.4 - 24.3 82.3 - 24.9 82.2 - 25.5 82.2 - 26.0 82.2 - 26.6 82.3 - 27.1 82.4 - 27.7 82.5 - 28.2 82.7 - 28.8 82.9 - 29.3 83.2 - 29.9 83.4 - 30.4 83.8 - 30.9 84.2 - 31.4 84.6 - 32.0 85.0 - 32.5 85.5 - 33.0 86.0 - 33.4 86.6 - 33.9 87.1 - 34.4 87.8 - 34.8 88.4 - 35.3 89.1 - 35.7 89.8 - 36.1 90.6 - 36.5 91.3 - 36.9 92.1 - 37.3 93.0 - 37.6 93.8 - 38.0 94.7 - 38.3 95.6 - 38.6 96.5 - 38.9 97.5 - 39.2 98.5 - 39.4 99.4 - 39.7 100. - 39.9 101. - 40.1 103. - 40.3 104. - 40.5 105. - 40.6 106. - 40.7 107. - 40.8 108. - 40.9 109. - 41.0 110. - 41.1 111. - 41.1 112. - 41.1 113. - 41.1 115. - 41.1 116. - 41.0 117. - 40.9 118. - 40.8 119. - 40.7 120. - 40.6 121. - 40.5 122. - 40.3 123. - 40.1 124. - 39.9 125. - 39.7 126. - 39.4 127. - 39.2 128. - 38.9 129. - 38.6 130. - 38.3 131. - 38.0 132. - 37.6 133. - 37.3 134. - 36.9 135. - 36.5 136. - 36.1 136. - 35.7 137. - 35.3 138. - 34.8 138. - 34.4 139. - 33.9 140. - 33.4 140. - 33.0 141. - 32.5 141. - 32.0 142. - 31.4 142. - 30.9 143. - 30.4 143. - 29.9 143. - 29.3 144. - 28.8 144. - 28.2 144. - 27.7 144. - 27.1 145. - 26.6 145. - 26.0 145. - 25.5 145. - 24.9 145. - 24.3 145. - 23.8 145. - 23.2 144. - 22.7 144. - 22.1 144. - 21.6 144. - 21.1 143. - 20.5 143. - 20.0 143. - 19.5 142. - 19.0 142. - 18.5 141. - 18.0 141. - 17.5 140. - 17.0 140. - 16.5 139. - 16.1 138. - 15.7 138. - 15.2 137. - 14.8 136. - 14.4 136. - 14.0 135. - 13.7 134. - 13.3 133. - 13.0 132. - 12.6 131. - 12.3 130. - 12.0 129. - 11.7 128. - 11.5 127. - 11.2 126. - 11.0 125. - 10.8 124. - 10.6 123. - 10.5 122. - 10.3 121. - 10.2 120. - 10.1 119. - 10.0 118. - 9.93 117. - 9.88 116. - 9.85 115. - 9.84 113. - 9.85 112. - 9.89 111. - 9.94 110. - 10.0 109. - 10.1 108. - 10.2 107. - 10.3 106. - 10.5 105. - 10.7 104. - 10.8 102. -REG_LINE: 197 - -3.80 135. - -4.17 133. - -4.50 131. - -4.80 129. - -5.06 127. - -5.28 125. - -5.46 122. - -5.60 120. - -5.70 118. - -5.76 116. - -5.78 114. - -5.76 111. - -5.70 109. - -5.61 107. - -5.47 105. - -5.29 102. - -5.07 100. - -4.82 98.1 - -4.53 95.9 - -4.19 93.8 - -3.82 91.7 - -3.42 89.6 - -2.97 87.5 - -2.49 85.5 - -1.97 83.5 - -1.42 81.6 - -.838 79.7 - -.219 77.8 - .433 76.0 - 1.12 74.3 - 1.83 72.6 - 2.58 70.9 - 3.35 69.3 - 4.15 67.7 - 4.98 66.2 - 5.84 64.8 - 6.72 63.4 - 7.62 62.1 - 8.55 60.9 - 9.50 59.7 - 10.5 58.6 - 11.5 57.6 - 12.5 56.6 - 13.5 55.7 - 14.5 54.9 - 15.6 54.2 - 16.6 53.5 - 17.7 52.9 - 18.8 52.4 - 19.9 51.9 - 21.0 51.6 - 22.1 51.3 - 23.2 51.1 - 24.3 51.0 - 25.4 50.9 - 26.6 51.0 - 27.7 51.1 - 28.8 51.3 - 29.9 51.6 - 31.0 51.9 - 32.1 52.4 - 33.2 52.9 - 34.3 53.5 - 35.3 54.1 - 36.4 54.9 - 37.4 55.7 - 38.4 56.6 - 39.4 57.5 - 40.4 58.6 - 41.4 59.7 - 42.4 60.8 - 43.3 62.1 - 44.2 63.4 - 45.1 64.8 - 45.9 66.2 - 46.8 67.7 - 47.6 69.2 - 48.3 70.8 - 49.1 72.5 - 49.8 74.2 - 50.5 76.0 - 51.1 77.8 - 51.8 79.6 - 52.3 81.5 - 52.9 83.5 - 53.4 85.5 - 53.9 87.5 - 54.3 89.5 - 54.7 91.6 - 55.1 93.7 - 55.5 95.8 - 55.7 98.0 - 56.0 100. - 56.2 102. - 56.4 105. - 56.5 107. - 56.6 109. - 56.7 111. - 56.7 113. - 56.7 116. - 56.6 118. - 56.5 120. - 56.4 122. - 56.2 125. - 56.0 127. - 55.7 129. - 55.5 131. - 55.1 133. - 54.7 135. - 54.3 137. - 53.9 139. - 53.4 141. - 52.9 143. - 52.3 145. - 51.8 147. - 51.1 149. - 50.5 151. - 49.8 153. - 49.1 154. - 48.3 156. - 47.6 158. - 46.8 159. - 45.9 161. - 45.1 162. - 44.2 163. - 43.3 165. - 42.4 166. - 41.4 167. - 40.4 168. - 39.4 169. - 38.4 170. - 37.4 171. - 36.4 172. - 35.3 173. - 34.3 173. - 33.2 174. - 32.1 175. - 31.0 175. - 29.9 175. - 28.8 176. - 27.7 176. - 26.6 176. - 25.4 176. - 24.3 176. - 23.2 176. - 22.1 176. - 21.0 175. - 19.9 175. - 18.8 174. - 17.7 174. - 16.6 173. - 15.6 173. - 14.5 172. - 13.5 171. - 12.5 170. - 11.5 169. - 10.5 168. - 9.50 167. - 8.55 166. - 7.62 165. - 6.72 163. - 5.84 162. - 4.98 161. - 4.15 159. - 3.35 158. - 2.58 156. - 1.83 154. - 1.12 153. - .433 151. - -.219 149. - -.838 147. - -1.42 145. - -1.97 143. - -2.49 141. - -2.97 139. - -3.42 137. - -3.82 135. - -4.19 133. - -4.53 131. - -4.82 129. - -5.07 127. - -5.29 124. - -5.47 122. - -5.61 120. - -5.70 118. - -5.76 116. - -5.78 113. - -5.76 111. - -5.70 109. - -5.60 107. - -5.46 104. - -5.28 102. - -5.06 100. - -4.80 97.9 - -4.50 95.7 - -4.17 93.6 - -3.80 91.5 -REG_LINE: 197 - -18.4 146. - -19.0 143. - -19.5 140. - -19.9 137. - -20.3 133. - -20.7 130. - -20.9 127. - -21.1 124. - -21.3 120. - -21.4 117. - -21.4 114. - -21.4 110. - -21.3 107. - -21.1 104. - -20.9 100. - -20.7 96.9 - -20.3 93.6 - -20.0 90.4 - -19.5 87.1 - -19.0 83.9 - -18.5 80.8 - -17.9 77.7 - -17.2 74.6 - -16.5 71.6 - -15.7 68.6 - -14.9 65.7 - -14.0 62.8 - -13.1 60.0 - -12.1 57.3 - -11.1 54.7 - -9.99 52.1 - -8.87 49.6 - -7.71 47.2 - -6.50 44.9 - -5.26 42.6 - -3.98 40.5 - -2.66 38.4 - -1.30 36.5 - 0.922E-01 34.6 - 1.52 32.9 - 2.97 31.2 - 4.45 29.6 - 5.96 28.2 - 7.50 26.9 - 9.05 25.6 - 10.6 24.5 - 12.2 23.5 - 13.8 22.6 - 15.5 21.8 - 17.1 21.2 - 18.8 20.7 - 20.4 20.2 - 22.1 19.9 - 23.8 19.7 - 25.4 19.7 - 27.1 19.7 - 28.8 19.9 - 30.5 20.2 - 32.1 20.6 - 33.8 21.2 - 35.4 21.8 - 37.0 22.6 - 38.7 23.5 - 40.2 24.5 - 41.8 25.6 - 43.4 26.8 - 44.9 28.1 - 46.4 29.6 - 47.9 31.1 - 49.4 32.8 - 50.8 34.5 - 52.2 36.4 - 53.5 38.4 - 54.9 40.4 - 56.2 42.6 - 57.4 44.8 - 58.6 47.1 - 59.8 49.5 - 60.9 52.0 - 62.0 54.6 - 63.0 57.2 - 64.0 60.0 - 64.9 62.7 - 65.8 65.6 - 66.6 68.5 - 67.4 71.5 - 68.1 74.5 - 68.8 77.5 - 69.4 80.7 - 69.9 83.8 - 70.4 87.0 - 70.9 90.2 - 71.3 93.5 - 71.6 96.8 - 71.9 100. - 72.1 103. - 72.2 107. - 72.3 110. - 72.3 113. - 72.3 117. - 72.2 120. - 72.1 123. - 71.9 127. - 71.6 130. - 71.3 133. - 70.9 137. - 70.4 140. - 69.9 143. - 69.4 146. - 68.8 149. - 68.1 152. - 67.4 155. - 66.6 158. - 65.8 161. - 64.9 164. - 64.0 167. - 63.0 170. - 62.0 172. - 60.9 175. - 59.8 177. - 58.6 180. - 57.4 182. - 56.2 184. - 54.9 186. - 53.5 189. - 52.2 190. - 50.8 192. - 49.4 194. - 47.9 196. - 46.4 197. - 44.9 199. - 43.4 200. - 41.8 201. - 40.2 202. - 38.7 203. - 37.0 204. - 35.4 205. - 33.8 206. - 32.1 206. - 30.5 207. - 28.8 207. - 27.1 207. - 25.4 207. - 23.8 207. - 22.1 207. - 20.4 207. - 18.8 206. - 17.1 206. - 15.5 205. - 13.8 204. - 12.2 203. - 10.6 202. - 9.05 201. - 7.50 200. - 5.96 199. - 4.45 197. - 2.97 196. - 1.52 194. - 0.922E-01 192. - -1.30 190. - -2.66 188. - -3.98 186. - -5.26 184. - -6.50 182. - -7.71 180. - -8.87 177. - -9.99 175. - -11.1 172. - -12.1 170. - -13.1 167. - -14.0 164. - -14.9 161. - -15.7 158. - -16.5 155. - -17.2 152. - -17.9 149. - -18.5 146. - -19.0 143. - -19.5 140. - -20.0 137. - -20.3 133. - -20.7 130. - -20.9 127. - -21.1 123. - -21.3 120. - -21.4 117. - -21.4 113. - -21.4 110. - -21.3 107. - -21.1 103. - -20.9 100. - -20.7 96.7 - -20.3 93.4 - -19.9 90.1 - -19.5 86.9 - -19.0 83.7 - -18.4 80.6 -REG_LINE: 197 - -33.1 157. - -33.8 153. - -34.5 149. - -35.1 145. - -35.6 140. - -36.0 136. - -36.4 131. - -36.7 127. - -36.9 123. - -37.0 118. - -37.0 114. - -37.0 109. - -36.9 105. - -36.7 100. - -36.4 95.8 - -36.1 91.4 - -35.6 87.0 - -35.1 82.7 - -34.5 78.4 - -33.9 74.1 - -33.1 69.9 - -32.3 65.7 - -31.4 61.6 - -30.5 57.6 - -29.4 53.6 - -28.3 49.8 - -27.1 46.0 - -25.9 42.3 - -24.6 38.6 - -23.2 35.1 - -21.8 31.7 - -20.3 28.3 - -18.8 25.1 - -17.2 22.0 - -15.5 19.0 - -13.8 16.2 - -12.0 13.4 - -10.2 10.8 - -8.37 8.34 - -6.47 5.99 - -4.53 3.78 - -2.55 1.71 - -.540 -.225 - 1.51 -2.01 - 3.58 -3.65 - 5.69 -5.14 - 7.82 -6.47 - 9.97 -7.66 - 12.1 -8.69 - 14.3 -9.56 - 16.5 -10.3 - 18.7 -10.8 - 21.0 -11.2 - 23.2 -11.5 - 25.4 -11.6 - 27.7 -11.5 - 29.9 -11.2 - 32.1 -10.9 - 34.3 -10.3 - 36.5 -9.59 - 38.7 -8.72 - 40.9 -7.70 - 43.0 -6.52 - 45.2 -5.19 - 47.3 -3.70 - 49.4 -2.07 - 51.4 -.290 - 53.4 1.63 - 55.4 3.70 - 57.3 5.91 - 59.2 8.25 - 61.1 10.7 - 62.9 13.3 - 64.7 16.1 - 66.4 18.9 - 68.0 21.9 - 69.6 25.0 - 71.2 28.2 - 72.7 31.6 - 74.1 35.0 - 75.5 38.5 - 76.8 42.1 - 78.0 45.8 - 79.2 49.6 - 80.3 53.5 - 81.4 57.5 - 82.3 61.5 - 83.2 65.6 - 84.0 69.7 - 84.8 73.9 - 85.4 78.2 - 86.0 82.5 - 86.5 86.9 - 87.0 91.2 - 87.3 95.6 - 87.6 100. - 87.8 105. - 87.9 109. - 88.0 113. - 87.9 118. - 87.8 122. - 87.6 127. - 87.3 131. - 87.0 136. - 86.5 140. - 86.0 144. - 85.4 149. - 84.8 153. - 84.0 157. - 83.2 161. - 82.3 165. - 81.4 169. - 80.3 173. - 79.2 177. - 78.0 181. - 76.8 185. - 75.5 188. - 74.1 192. - 72.7 195. - 71.2 199. - 69.6 202. - 68.0 205. - 66.4 208. - 64.7 211. - 62.9 214. - 61.1 216. - 59.2 219. - 57.3 221. - 55.4 223. - 53.4 225. - 51.4 227. - 49.4 229. - 47.3 231. - 45.2 232. - 43.0 233. - 40.9 235. - 38.7 236. - 36.5 236. - 34.3 237. - 32.1 238. - 29.9 238. - 27.7 238. - 25.4 238. - 23.2 238. - 21.0 238. - 18.7 238. - 16.5 237. - 14.3 236. - 12.1 236. - 9.97 235. - 7.82 233. - 5.69 232. - 3.58 231. - 1.51 229. - -.540 227. - -2.55 225. - -4.53 223. - -6.47 221. - -8.37 219. - -10.2 216. - -12.0 213. - -13.8 211. - -15.5 208. - -17.2 205. - -18.8 202. - -20.3 199. - -21.8 195. - -23.2 192. - -24.6 188. - -25.9 185. - -27.1 181. - -28.3 177. - -29.4 173. - -30.5 169. - -31.4 165. - -32.3 161. - -33.1 157. - -33.9 153. - -34.5 149. - -35.1 144. - -35.6 140. - -36.1 135. - -36.4 131. - -36.7 127. - -36.9 122. - -37.0 118. - -37.0 113. - -37.0 109. - -36.9 104. - -36.7 99.9 - -36.4 95.5 - -36.0 91.1 - -35.6 86.7 - -35.1 82.4 - -34.5 78.1 - -33.8 73.8 - -33.1 69.6 -REG_LINE: 197 - -47.7 168. - -48.6 163. - -49.5 158. - -50.2 152. - -50.8 147. - -51.4 141. - -51.8 136. - -52.2 130. - -52.4 125. - -52.6 119. - -52.7 114. - -52.6 108. - -52.5 102. - -52.2 96.9 - -51.9 91.4 - -51.4 85.9 - -50.9 80.4 - -50.3 75.0 - -49.5 69.6 - -48.7 64.3 - -47.8 59.0 - -46.7 53.8 - -45.6 48.7 - -44.4 43.6 - -43.1 38.7 - -41.8 33.8 - -40.3 29.1 - -38.8 24.5 - -37.1 19.9 - -35.4 15.5 - -33.6 11.2 - -31.8 7.08 - -29.8 3.06 - -27.8 -.822 - -25.7 -4.55 - -23.6 -8.14 - -21.4 -11.6 - -19.1 -14.8 - -16.8 -17.9 - -14.5 -20.9 - -12.0 -23.6 - -9.56 -26.2 - -7.04 -28.6 - -4.49 -30.9 - -1.89 -32.9 - .740 -34.8 - 3.40 -36.5 - 6.09 -37.9 - 8.81 -39.2 - 11.5 -40.3 - 14.3 -41.2 - 17.1 -41.9 - 19.8 -42.4 - 22.6 -42.7 - 25.4 -42.8 - 28.2 -42.7 - 31.0 -42.4 - 33.8 -41.9 - 36.5 -41.2 - 39.3 -40.3 - 42.0 -39.3 - 44.7 -38.0 - 47.4 -36.5 - 50.1 -34.8 - 52.7 -33.0 - 55.3 -30.9 - 57.9 -28.7 - 60.4 -26.3 - 62.9 -23.7 - 65.3 -21.0 - 67.7 -18.0 - 70.0 -14.9 - 72.3 -11.7 - 74.5 -8.26 - 76.6 -4.68 - 78.7 -.956 - 80.7 2.92 - 82.6 6.93 - 84.5 11.1 - 86.3 15.4 - 88.0 19.8 - 89.6 24.3 - 91.2 28.9 - 92.6 33.7 - 94.0 38.5 - 95.3 43.5 - 96.5 48.5 - 97.6 53.6 - 98.7 58.8 - 99.6 64.1 - 100. 69.4 - 101. 74.8 - 102. 80.2 - 102. 85.7 - 103. 91.2 - 103. 96.7 - 103. 102. - 104. 108. - 104. 113. - 104. 119. - 103. 125. - 103. 130. - 103. 136. - 102. 141. - 102. 147. - 101. 152. - 100. 157. - 99.6 163. - 98.7 168. - 97.6 173. - 96.5 178. - 95.3 183. - 94.0 188. - 92.6 193. - 91.2 198. - 89.6 203. - 88.0 207. - 86.3 212. - 84.5 216. - 82.6 220. - 80.7 224. - 78.7 228. - 76.6 232. - 74.5 235. - 72.3 239. - 70.0 242. - 67.7 245. - 65.3 248. - 62.9 251. - 60.4 253. - 57.9 256. - 55.3 258. - 52.7 260. - 50.1 262. - 47.4 263. - 44.7 265. - 42.0 266. - 39.3 267. - 36.5 268. - 33.8 269. - 31.0 269. - 28.2 270. - 25.4 270. - 22.6 270. - 19.8 269. - 17.1 269. - 14.3 268. - 11.5 267. - 8.81 266. - 6.09 265. - 3.40 263. - .740 262. - -1.89 260. - -4.49 258. - -7.04 256. - -9.56 253. - -12.0 251. - -14.5 248. - -16.8 245. - -19.1 242. - -21.4 238. - -23.6 235. - -25.7 231. - -27.8 228. - -29.8 224. - -31.8 220. - -33.6 216. - -35.4 211. - -37.1 207. - -38.8 202. - -40.3 198. - -41.8 193. - -43.1 188. - -44.4 183. - -45.6 178. - -46.7 173. - -47.8 168. - -48.7 163. - -49.5 157. - -50.3 152. - -50.9 146. - -51.4 141. - -51.9 135. - -52.2 130. - -52.5 124. - -52.6 119. - -52.7 113. - -52.6 108. - -52.4 102. - -52.2 96.5 - -51.8 91.0 - -51.4 85.5 - -50.8 80.0 - -50.2 74.6 - -49.5 69.2 - -48.6 63.9 - -47.7 58.6 -REG_LINE: 141 - -62.3 179. - -63.4 173. - -64.4 167. - -65.3 160. - -66.1 154. - -66.8 147. - -67.3 140. - -67.7 134. - -68.0 127. - -68.2 120. - -68.3 114. - -68.2 107. - -68.1 100. - -67.8 93.6 - -67.3 87.0 - -66.8 80.4 - -66.2 73.8 - -65.4 67.3 - -64.5 60.8 - -63.5 54.4 - -62.4 48.1 - -61.2 41.9 - -59.9 35.7 - -58.4 29.7 - -56.9 23.8 - -55.2 17.9 - -53.5 12.2 - -51.6 6.66 - -49.6 1.22 - -47.6 -4.07 - -45.4 -9.21 - -43.2 -14.2 - -40.9 -19.0 - -38.5 -23.7 - -36.0 -28.2 - -33.4 -32.5 - -30.8 -36.6 - -28.1 -40.5 - -25.3 -44.2 - -22.4 -47.7 - -19.5 -51.1 - -16.6 -54.2 - -13.5 -57.1 - -10.5 -59.7 - -7.36 -62.2 - -4.21 -64.4 - -1.01 -66.4 - 2.22 -68.2 - 5.47 -69.7 - 8.76 -71.1 - 12.1 -72.1 - 15.4 -73.0 - 18.7 -73.6 - 22.1 -73.9 - 25.4 -74.1 - 28.8 -73.9 - 32.1 -73.6 - 35.4 -73.0 - 38.8 -72.2 - 42.1 -71.1 - 45.3 -69.8 - 48.6 -68.3 - 51.8 -66.5 - 55.0 -64.5 - 58.2 -62.3 - 61.3 -59.8 - 64.4 -57.2 - 67.4 -54.3 - 70.4 -51.2 - 73.3 -47.9 - 76.1 -44.3 - 78.9 -40.6 - 81.6 -36.7 - 84.3 -32.6 - 86.8 -28.3 - 89.3 -23.8 - 91.7 -19.2 - 94.1 -14.4 - 96.3 -9.39 - 98.5 -4.25 - 101. 1.03 - 102. 6.46 - 104. 12.0 - 106. 17.7 - 108. 23.5 - 109. 29.5 - 111. 35.5 - 112. 41.7 - 113. 47.9 - 114. 54.2 - 115. 60.6 - 116. 67.0 - 117. 73.6 - 118. 80.1 - 118. 86.7 - 119. 93.4 - 119. 100. - 119. 107. - 119. 113. - 119. 120. - 119. 127. - 119. 133. - 118. 140. - 118. 147. - 117. 153. - 116. 160. - 115. 166. - 114. 173. - 113. 179. - 112. 185. - 111. 191. - 109. 197. - 108. 203. - 106. 209. - 104. 215. - 102. 220. - 101. 226. - 98.5 231. - 96.3 236. - 94.1 241. - 91.7 246. - 89.3 251. - 86.8 255. - 84.3 259. - 81.6 264. - 78.9 267. - 76.1 271. - 73.3 275. - 70.4 278. - 67.4 281. - 64.4 284. - 61.3 287. - 58.2 289. - 55.0 291. - 51.8 293. - 48.6 295. - 45.3 297. - 42.1 298. - 38.8 299. - 35.4 300. - 34.7 300. -REG_LINE: 53 - 16.2 300. - 15.4 300. - 12.1 299. - 8.76 298. - 5.47 297. - 2.22 295. - -1.01 293. - -4.21 291. - -7.36 289. - -10.5 287. - -13.5 284. - -16.6 281. - -19.5 278. - -22.4 275. - -25.3 271. - -28.1 267. - -30.8 263. - -33.4 259. - -36.0 255. - -38.5 251. - -40.9 246. - -43.2 241. - -45.4 236. - -47.6 231. - -49.6 226. - -51.6 220. - -53.5 215. - -55.2 209. - -56.9 203. - -58.4 197. - -59.9 191. - -61.2 185. - -62.4 179. - -63.5 172. - -64.5 166. - -65.4 160. - -66.2 153. - -66.8 147. - -67.3 140. - -67.8 133. - -68.1 127. - -68.2 120. - -68.3 113. - -68.2 107. - -68.0 99.8 - -67.7 93.2 - -67.3 86.5 - -66.8 79.9 - -66.1 73.3 - -65.3 66.8 - -64.4 60.4 - -63.4 54.0 - -62.3 47.7 -REG_LINE: 128 - -77.0 190. - -78.3 183. - -79.4 175. - -80.5 168. - -81.4 160. - -82.1 153. - -82.8 145. - -83.3 137. - -83.6 129. - -83.8 122. - -83.9 114. - -83.8 106. - -83.6 98.1 - -83.3 90.3 - -82.8 82.6 - -82.2 74.9 - -81.4 67.2 - -80.5 59.6 - -79.5 52.0 - -78.3 44.6 - -77.1 37.2 - -75.6 29.9 - -74.1 22.8 - -72.4 15.7 - -70.6 8.81 - -68.7 2.01 - -66.6 -4.64 - -64.4 -11.1 - -62.2 -17.5 - -59.8 -23.7 - -57.3 -29.7 - -54.7 -35.5 - -51.9 -41.1 - -49.1 -46.5 - -46.2 -51.8 - -43.2 -56.8 - -40.2 -61.6 - -37.0 -66.1 - -33.7 -70.5 - -30.4 -74.6 - -27.0 -78.5 - -23.6 -82.1 - -20.0 -85.5 - -16.5 -88.6 - -12.8 -91.5 - -9.15 -94.1 - -5.42 -96.4 - -1.66 -98.5 - 2.14 -100. - 5.97 -102. - 9.83 -103. - 13.7 -104. - 17.6 -105. - 21.5 -105. - 25.4 -105. - 29.3 -105. - 33.2 -105. - 37.1 -104. - 41.0 -103. - 44.8 -102. - 48.7 -100. - 52.5 -98.5 - 56.2 -96.5 - 60.0 -94.2 - 63.6 -91.6 - 67.3 -88.7 - 70.9 -85.6 - 74.4 -82.2 - 77.8 -78.6 - 81.2 -74.7 - 84.6 -70.6 - 87.8 -66.3 - 91.0 -61.7 - 94.1 -56.9 - 97.1 -51.9 - 100. -46.7 - 103. -41.3 - 105. -35.7 - 108. -29.9 - 111. -23.9 - 113. -17.7 - 115. -11.4 - 117. -4.87 - 120. 1.78 - 121. 8.56 - 123. 15.5 - 125. 22.5 - 127. 29.7 - 128. 37.0 - 129. 44.3 - 130. 51.8 - 131. 59.3 - 132. 66.9 - 133. 74.6 - 134. 82.3 - 134. 90.0 - 135. 97.8 - 135. 106. - 135. 113. - 135. 121. - 135. 129. - 134. 137. - 134. 145. - 133. 152. - 132. 160. - 131. 168. - 130. 175. - 129. 183. - 128. 190. - 127. 197. - 125. 204. - 123. 211. - 121. 218. - 120. 225. - 117. 232. - 115. 238. - 113. 245. - 111. 251. - 108. 257. - 105. 263. - 103. 268. - 100. 274. - 97.1 279. - 94.1 284. - 91.0 289. - 87.8 293. - 84.6 298. - 82.5 300. -REG_LINE: 40 - -31.6 300. - -33.7 297. - -37.0 293. - -40.2 288. - -43.2 284. - -46.2 279. - -49.1 273. - -51.9 268. - -54.7 262. - -57.3 257. - -59.8 251. - -62.2 244. - -64.4 238. - -66.6 232. - -68.7 225. - -70.6 218. - -72.4 211. - -74.1 204. - -75.6 197. - -77.1 190. - -78.3 182. - -79.5 175. - -80.5 167. - -81.4 160. - -82.2 152. - -82.8 144. - -83.3 137. - -83.6 129. - -83.8 121. - -83.9 113. - -83.8 105. - -83.6 97.5 - -83.3 89.8 - -82.8 82.0 - -82.1 74.3 - -81.4 66.7 - -80.5 59.0 - -79.4 51.5 - -78.3 44.1 - -77.0 36.7 -REG_LINE: 97 - -91.6 201. - -93.1 193. - -94.4 184. - -95.6 176. - -96.6 167. - -97.5 158. - -98.2 149. - -98.8 140. - -99.2 132. - -99.4 123. - -99.5 114. - -99.5 105. - -99.2 95.9 - -98.8 87.0 - -98.3 78.2 - -97.6 69.3 - -96.7 60.6 - -95.7 51.9 - -94.5 43.3 - -93.2 34.8 - -91.7 26.3 - -90.1 18.0 - -88.3 9.83 - -86.4 1.77 - -84.3 -6.14 - -82.1 -13.9 - -79.8 -21.5 - -77.3 -28.9 - -74.7 -36.2 - -71.9 -43.2 - -69.1 -50.1 - -66.1 -56.7 - -63.0 -63.2 - -59.8 -69.4 - -56.5 -75.3 - -53.1 -81.1 - -49.5 -86.6 - -45.9 -91.8 - -42.2 -96.8 - -38.4 -101. - -34.5 -106. - -30.6 -110. - -26.5 -114. - -22.5 -117. - -18.3 -121. - -14.1 -124. - -9.84 -126. - -5.53 -129. - -1.19 -131. - 3.19 -133. - 7.59 -134. - 12.0 -135. - 16.5 -136. - 20.9 -136. - 25.4 -137. - 29.9 -136. - 34.3 -136. - 38.8 -135. - 43.2 -134. - 47.6 -133. - 52.0 -131. - 56.3 -129. - 60.6 -126. - 64.9 -124. - 69.1 -121. - 73.2 -118. - 77.3 -114. - 81.4 -110. - 85.3 -106. - 89.2 -102. - 93.0 -96.9 - 96.7 -92.0 - 100. -86.8 - 104. -81.3 - 107. -75.6 - 111. -69.6 - 114. -63.4 - 117. -57.0 - 120. -50.3 - 123. -43.5 - 126. -36.4 - 128. -29.2 - 131. -21.8 - 133. -14.2 - 135. -6.42 - 137. 1.49 - 139. 9.54 - 141. 17.7 - 143. 26.0 - 144. 34.5 - 145. 43.0 - 147. 51.6 - 148. 60.3 - 148. 69.0 - 149. 77.8 - 150. 86.7 - 150. 92.2 -REG_LINE: 23 - 150. 135. - 150. 140. - 149. 149. - 148. 158. - 148. 167. - 147. 175. - 145. 184. - 144. 192. - 143. 201. - 141. 209. - 139. 217. - 137. 225. - 135. 233. - 133. 241. - 131. 249. - 128. 256. - 126. 263. - 123. 270. - 120. 277. - 117. 284. - 114. 290. - 111. 296. - 109. 300. -REG_LINE: 35 - -57.7 300. - -59.8 296. - -63.0 290. - -66.1 284. - -69.1 277. - -71.9 270. - -74.7 263. - -77.3 256. - -79.8 248. - -82.1 241. - -84.3 233. - -86.4 225. - -88.3 217. - -90.1 209. - -91.7 201. - -93.2 192. - -94.5 184. - -95.7 175. - -96.7 166. - -97.6 158. - -98.3 149. - -98.8 140. - -99.2 131. - -99.5 122. - -99.5 113. - -99.4 104. - -99.2 95.3 - -98.8 86.4 - -98.2 77.5 - -97.5 68.7 - -96.6 60.0 - -95.6 51.3 - -94.4 42.7 - -93.1 34.2 - -91.6 25.7 -REG_LINE: 63 - -100. -13.5 - -98.0 -21.1 - -95.5 -29.8 - -92.9 -38.4 - -90.1 -46.7 - -87.2 -54.9 - -84.1 -62.8 - -80.9 -70.5 - -77.5 -78.0 - -74.1 -85.2 - -70.5 -92.2 - -66.7 -98.9 - -62.9 -105. - -58.9 -112. - -54.8 -117. - -50.7 -123. - -46.4 -128. - -42.0 -133. - -37.6 -138. - -33.1 -142. - -28.4 -146. - -23.8 -150. - -19.0 -153. - -14.3 -156. - -9.41 -159. - -4.52 -161. - .403 -163. - 5.36 -165. - 10.3 -166. - 15.3 -167. - 20.4 -168. - 25.4 -168. - 30.4 -168. - 35.4 -167. - 40.4 -166. - 45.4 -165. - 50.4 -163. - 55.3 -161. - 60.2 -159. - 65.0 -156. - 69.8 -153. - 74.5 -150. - 79.2 -146. - 83.8 -142. - 88.4 -138. - 92.8 -133. - 97.2 -129. - 101. -123. - 106. -118. - 110. -112. - 114. -106. - 118. -99.2 - 121. -92.5 - 125. -85.5 - 128. -78.3 - 132. -70.8 - 135. -63.1 - 138. -55.2 - 141. -47.0 - 144. -38.7 - 146. -30.1 - 149. -21.4 - 150. -17.1 -REG_LINE: 9 - 150. 244. - 149. 248. - 146. 257. - 144. 266. - 141. 274. - 138. 282. - 135. 290. - 132. 298. - 131. 300. -REG_LINE: 9 - -79.7 300. - -80.9 297. - -84.1 290. - -87.2 282. - -90.1 274. - -92.9 265. - -95.5 257. - -98.0 248. - -100. 240. -REG_LINE: 54 - -100. -72.8 - -99.7 -73.6 - -96.3 -82.4 - -92.7 -91.0 - -89.0 -99.3 - -85.1 -107. - -81.1 -115. - -77.0 -123. - -72.7 -130. - -68.3 -137. - -63.8 -143. - -59.1 -149. - -54.4 -155. - -49.5 -161. - -44.6 -166. - -39.6 -171. - -34.4 -175. - -29.2 -179. - -24.0 -183. - -18.7 -186. - -13.3 -189. - -7.85 -192. - -2.38 -194. - 3.13 -196. - 8.66 -197. - 14.2 -198. - 19.8 -199. - 25.4 -199. - 30.9 -199. - 36.5 -198. - 42.1 -197. - 47.6 -196. - 53.1 -194. - 58.6 -192. - 64.0 -189. - 69.4 -186. - 74.7 -183. - 80.0 -179. - 85.2 -175. - 90.3 -171. - 95.3 -166. - 100. -161. - 105. -155. - 110. -150. - 115. -143. - 119. -137. - 123. -130. - 128. -123. - 132. -115. - 136. -108. - 140. -99.6 - 144. -91.3 - 147. -82.7 - 150. -75.3 -REG_LINE: 2 - -99.9 300. - -100. 300. -REG_LINE: 13 - -100. -121. - -96.2 -129. - -91.8 -138. - -87.2 -146. - -82.5 -154. - -77.7 -162. - -72.7 -169. - -67.6 -176. - -62.4 -182. - -57.0 -188. - -51.6 -194. - -46.1 -199. - -45.1 -200. -REG_LINE: 13 - 96.0 -200. - 96.8 -199. - 102. -194. - 108. -188. - 113. -182. - 118. -176. - 123. -169. - 128. -162. - 133. -154. - 138. -146. - 143. -138. - 147. -130. - 150. -123. -REG_LINE: 6 - -100. -165. - -97.4 -170. - -92.3 -178. - -87.0 -187. - -81.6 -194. - -77.4 -200. -REG_LINE: 6 - 128. -200. - 132. -195. - 138. -187. - 143. -179. - 148. -170. - 150. -167. -REG_LINE: 10 - 40.9 118. - 24.4 113. - 7.79 108. - -8.78 104. - -25.4 98.9 - -41.9 94.2 - -58.5 89.5 - -75.1 84.8 - -91.7 80.0 - -100. 77.7 -REG_LINE: 12 - 38.0 132. - 24.6 112. - 11.2 92.1 - -2.25 72.0 - -15.7 52.0 - -29.1 31.9 - -42.5 11.9 - -55.9 -8.13 - -69.3 -28.2 - -82.7 -48.2 - -96.1 -68.2 - -100. -74.0 -REG_LINE: 13 - 32.0 142. - 25.0 111. - 18.0 81.0 - 11.1 50.5 - 4.10 20.1 - -2.86 -10.4 - -9.83 -40.8 - -16.8 -71.3 - -23.8 -102. - -30.7 -132. - -37.7 -163. - -44.7 -193. - -46.3 -200. -REG_LINE: 12 - 24.4 145. - 25.5 111. - 26.7 77.8 - 27.9 44.4 - 29.1 11.0 - 30.3 -22.4 - 31.5 -55.8 - 32.7 -89.2 - 33.8 -123. - 35.0 -156. - 36.2 -189. - 36.6 -200. -REG_LINE: 14 - 17.0 140. - 26.1 112. - 35.1 83.4 - 44.2 55.2 - 53.2 27.0 - 62.3 -1.14 - 71.3 -29.3 - 80.3 -57.5 - 89.4 -85.7 - 98.4 -114. - 107. -142. - 117. -170. - 126. -198. - 126. -200. -REG_LINE: 11 - 11.8 128. - 26.4 112. - 41.1 96.3 - 55.8 80.3 - 70.5 64.2 - 85.2 48.2 - 99.9 32.1 - 115. 16.1 - 129. 0.199E-02 - 144. -16.1 - 150. -22.6 -REG_LINE: 10 - 9.84 113. - 26.6 113. - 43.3 113. - 60.1 113. - 76.8 113. - 93.5 113. - 110. 113. - 127. 113. - 144. 113. - 150. 113. -REG_LINE: 11 - 11.8 98.5 - 26.4 115. - 41.1 131. - 55.8 147. - 70.5 163. - 85.2 179. - 99.9 195. - 115. 211. - 129. 227. - 144. 243. - 150. 250. -REG_LINE: 9 - 17.0 87.1 - 26.1 115. - 35.1 143. - 44.2 172. - 53.2 200. - 62.3 228. - 71.3 256. - 80.3 284. - 85.4 300. -REG_LINE: 8 - 24.4 82.3 - 25.5 116. - 26.7 149. - 27.9 182. - 29.1 216. - 30.3 249. - 31.5 283. - 32.1 300. -REG_LINE: 9 - 32.0 85.0 - 25.0 115. - 18.0 146. - 11.1 176. - 4.10 207. - -2.86 237. - -9.83 268. - -16.8 298. - -17.2 300. -REG_LINE: 12 - 38.0 94.7 - 24.6 115. - 11.2 135. - -2.25 155. - -15.7 175. - -29.1 195. - -42.5 215. - -55.9 235. - -69.3 255. - -82.7 275. - -96.1 295. - -99.4 300. -REG_LINE: 10 - 40.9 109. - 24.4 114. - 7.79 118. - -8.78 123. - -25.4 128. - -41.9 133. - -58.5 137. - -75.1 142. - -91.7 147. - -100. 149. -REG_LINE: 2 - 18.7 134. - 17.7 133. -REG_LINE: 2 - 20.4 129. - 19.4 128. -REG_LINE: 2 - 22.1 124. - 21.1 123. -REG_LINE: 2 - 23.8 119. - 22.8 117. -REG_LINE: 2 - 27.2 108. - 28.2 110. -REG_LINE: 2 - 28.8 103. - 29.8 104. -REG_LINE: 2 - 30.5 97.7 - 31.5 99.1 -REG_LINE: 2 - 32.2 92.4 - 33.2 93.8 -REG_LINE: 2 - 35.6 81.9 - 36.6 83.3 -REG_LINE: 2 - 37.3 76.6 - 38.3 78.1 -REG_LINE: 2 - 39.0 71.4 - 40.0 72.8 -REG_LINE: 2 - 40.7 66.1 - 41.7 67.5 -REG_LINE: 2 - 44.0 55.6 - 45.0 57.0 -REG_LINE: 2 - 45.7 50.3 - 46.7 51.8 -REG_LINE: 2 - 47.4 45.1 - 48.4 46.5 -REG_LINE: 2 - 49.1 39.8 - 50.1 41.2 -REG_LINE: 2 - 52.5 29.3 - 53.5 30.7 -REG_LINE: 2 - 54.2 24.0 - 55.2 25.5 -REG_LINE: 2 - 55.9 18.8 - 56.9 20.2 -REG_LINE: 2 - 57.5 13.5 - 58.6 14.9 -REG_LINE: 2 - 60.9 2.99 - 61.9 4.43 -REG_LINE: 2 - 62.6 -2.26 - 63.6 -.831 -REG_LINE: 2 - 64.3 -7.52 - 65.3 -6.09 -REG_LINE: 2 - 66.0 -12.8 - 67.0 -11.3 -REG_LINE: 2 - 69.4 -23.3 - 70.4 -21.9 -REG_LINE: 2 - 71.1 -28.6 - 72.1 -27.1 -REG_LINE: 2 - 72.7 -33.8 - 73.7 -32.4 -REG_LINE: 2 - 74.4 -39.1 - 75.4 -37.6 -REG_LINE: 2 - 77.8 -49.6 - 78.8 -48.2 -REG_LINE: 2 - 79.5 -54.9 - 80.5 -53.4 -REG_LINE: 2 - 81.2 -60.1 - 82.2 -58.7 -REG_LINE: 2 - 82.9 -65.4 - 83.9 -63.9 -REG_LINE: 2 - 86.3 -75.9 - 87.3 -74.5 -REG_LINE: 2 - 87.9 -81.2 - 88.9 -79.7 -REG_LINE: 2 - 89.6 -86.4 - 90.6 -85.0 -REG_LINE: 2 - 91.3 -91.7 - 92.3 -90.2 -REG_LINE: 2 - 94.7 -102. - 95.7 -101. -REG_LINE: 2 - 96.4 -107. - 97.4 -106. -REG_LINE: 2 - 98.1 -113. - 99.1 -111. -REG_LINE: 2 - 99.8 -118. - 101. -117. -REG_LINE: 2 - 103. -128. - 104. -127. -REG_LINE: 2 - 105. -134. - 106. -132. -REG_LINE: 2 - 107. -139. - 108. -138. -REG_LINE: 2 - 108. -144. - 109. -143. -REG_LINE: 2 - 112. -155. - 113. -153. -REG_LINE: 2 - 113. -160. - 114. -159. -REG_LINE: 2 - 115. -165. - 116. -164. -REG_LINE: 2 - 117. -171. - 118. -169. -REG_LINE: 2 - 120. -181. - 121. -180. -REG_LINE: 2 - 122. -186. - 123. -185. -REG_LINE: 2 - 123. -192. - 124. -190. -REG_LINE: 2 - 125. -197. - 126. -195. -REG_LINE: 2 - -80.3 169. - -81.8 170. -REG_LINE: 2 - -82.5 148. - -84.2 148. -REG_LINE: 2 - -83.7 126. - -85.5 126. -REG_LINE: 2 - -83.8 104. - -85.6 104. -REG_LINE: 2 - -80.7 61.1 - -82.3 60.3 -REG_LINE: 2 - -77.6 40.2 - -79.0 39.1 -REG_LINE: 2 - -73.4 19.9 - -74.7 18.7 -REG_LINE: 2 - -68.3 .672 - -69.4 -.674 -REG_LINE: 2 - -55.2 -34.3 - -56.0 -35.9 -REG_LINE: 2 - -47.4 -49.7 - -48.1 -51.3 -REG_LINE: 2 - -38.9 -63.4 - -39.5 -65.1 -REG_LINE: 2 - -29.7 -75.4 - -30.2 -77.1 -REG_LINE: 2 - -9.89 -93.6 - -10.2 -95.3 -REG_LINE: 2 - .619 -99.6 - .416 -101. -REG_LINE: 2 - 11.4 -103. - 11.3 -105. -REG_LINE: 2 - 22.3 -105. - 22.2 -107. -REG_LINE: 2 - 44.1 -102. - 44.2 -104. -REG_LINE: 2 - 54.7 -97.3 - 55.0 -99.1 -REG_LINE: 2 - 65.1 -90.4 - 65.4 -92.2 -REG_LINE: 2 - 75.1 -81.5 - 75.5 -83.2 -REG_LINE: 2 - 93.5 -57.9 - 94.1 -59.5 -REG_LINE: 2 - 102. -43.5 - 102. -45.1 -REG_LINE: 2 - 109. -27.5 - 110. -29.0 -REG_LINE: 2 - 116. -10.1 - 117. -11.5 -REG_LINE: 2 - 126. 28.3 - 128. 27.1 -REG_LINE: 2 - 130. 48.8 - 131. 47.9 -REG_LINE: 2 - 133. 70.0 - 134. 69.3 -REG_LINE: 2 - 134. 91.6 - 136. 91.3 -REG_LINE: 2 - 134. 135. - 136. 136. -REG_LINE: 2 - 133. 157. - 134. 158. -REG_LINE: 2 - 130. 178. - 131. 179. -REG_LINE: 2 - 126. 199. - 128. 200. -REG_LINE: 2 - 116. 237. - 117. 238. -REG_LINE: 2 - 109. 254. - 110. 256. -REG_LINE: 2 - 102. 270. - 102. 272. -REG_LINE: 2 - 93.5 285. - 94.1 286. -REG_LINE: 2 - -38.9 290. - -39.5 292. -REG_LINE: 2 - -47.4 277. - -48.1 278. -REG_LINE: 2 - -55.2 261. - -56.0 263. -REG_LINE: 2 - -68.3 226. - -69.4 228. -REG_LINE: 2 - -73.4 207. - -74.7 208. -REG_LINE: 2 - -77.6 187. - -79.0 188. -REG_LINE: 2 - -80.7 166. - -82.3 167. -REG_LINE: 2 - -83.8 123. - -85.6 123. -REG_LINE: 2 - -83.7 101. - -85.5 100. -REG_LINE: 2 - -82.5 78.9 - -84.2 78.4 -REG_LINE: 2 - -80.3 57.5 - -81.8 56.7 -REG_LINE: 15 - 25.5 113. - 24.9 115. - 24.3 117. - 23.7 119. - 23.1 121. - 22.5 123. - 21.9 125. - 21.2 127. - 20.6 128. - 20.0 130. - 19.4 132. - 18.8 134. - 18.2 136. - 17.6 138. - 17.0 140. -REG_LINE: 15 - 25.5 113. - 26.1 112. - 26.7 110. - 27.3 108. - 27.9 106. - 28.5 104. - 29.1 102. - 29.7 100. - 30.3 98.4 - 30.9 96.5 - 31.5 94.7 - 32.1 92.8 - 32.7 90.9 - 33.3 89.0 - 33.9 87.1 -REG_LINE: 15 - 33.9 87.1 - 34.5 85.3 - 35.1 83.4 - 35.7 81.5 - 36.3 79.6 - 36.9 77.8 - 37.5 75.9 - 38.1 74.0 - 38.7 72.1 - 39.3 70.2 - 39.9 68.4 - 40.5 66.5 - 41.1 64.6 - 41.8 62.7 - 42.4 60.8 -REG_LINE: 15 - 42.4 60.8 - 43.0 59.0 - 43.6 57.1 - 44.2 55.2 - 44.8 53.3 - 45.4 51.5 - 46.0 49.6 - 46.6 47.7 - 47.2 45.8 - 47.8 43.9 - 48.4 42.1 - 49.0 40.2 - 49.6 38.3 - 50.2 36.4 - 50.8 34.5 -REG_LINE: 15 - 50.8 34.5 - 51.4 32.7 - 52.0 30.8 - 52.6 28.9 - 53.2 27.0 - 53.8 25.2 - 54.4 23.3 - 55.0 21.4 - 55.6 19.5 - 56.2 17.6 - 56.8 15.8 - 57.4 13.9 - 58.0 12.0 - 58.6 10.1 - 59.2 8.25 -REG_LINE: 15 - 59.2 8.25 - 59.8 6.38 - 60.4 4.50 - 61.0 2.62 - 61.6 .740 - 62.3 -1.14 - 62.9 -3.02 - 63.5 -4.89 - 64.1 -6.77 - 64.7 -8.65 - 65.3 -10.5 - 65.9 -12.4 - 66.5 -14.3 - 67.1 -16.2 - 67.7 -18.0 -REG_LINE: 15 - 67.7 -18.0 - 68.3 -19.9 - 68.9 -21.8 - 69.5 -23.7 - 70.1 -25.6 - 70.7 -27.4 - 71.3 -29.3 - 71.9 -31.2 - 72.5 -33.1 - 73.1 -34.9 - 73.7 -36.8 - 74.3 -38.7 - 74.9 -40.6 - 75.5 -42.5 - 76.1 -44.3 -REG_LINE: 15 - 76.1 -44.3 - 76.7 -46.2 - 77.3 -48.1 - 77.9 -50.0 - 78.5 -51.9 - 79.1 -53.7 - 79.7 -55.6 - 80.3 -57.5 - 80.9 -59.4 - 81.5 -61.2 - 82.2 -63.1 - 82.8 -65.0 - 83.4 -66.9 - 84.0 -68.8 - 84.6 -70.6 -REG_LINE: 15 - 84.6 -70.6 - 85.2 -72.5 - 85.8 -74.4 - 86.4 -76.3 - 87.0 -78.1 - 87.6 -80.0 - 88.2 -81.9 - 88.8 -83.8 - 89.4 -85.7 - 90.0 -87.5 - 90.6 -89.4 - 91.2 -91.3 - 91.8 -93.2 - 92.4 -95.1 - 93.0 -96.9 -REG_LINE: 15 - 93.0 -96.9 - 93.6 -98.8 - 94.2 -101. - 94.8 -103. - 95.4 -104. - 96.0 -106. - 96.6 -108. - 97.2 -110. - 97.8 -112. - 98.4 -114. - 99.0 -116. - 99.6 -118. - 100. -119. - 101. -121. - 101. -123. -REG_LINE: 15 - 101. -123. - 102. -125. - 103. -127. - 103. -129. - 104. -131. - 104. -133. - 105. -134. - 106. -136. - 106. -138. - 107. -140. - 107. -142. - 108. -144. - 109. -146. - 109. -148. - 110. -150. -REG_LINE: 15 - 110. -150. - 110. -151. - 111. -153. - 112. -155. - 112. -157. - 113. -159. - 114. -161. - 114. -163. - 115. -165. - 115. -166. - 116. -168. - 117. -170. - 117. -172. - 118. -174. - 118. -176. -REG_LINE: 14 - 118. -176. - 119. -178. - 120. -180. - 120. -181. - 121. -183. - 121. -185. - 122. -187. - 123. -189. - 123. -191. - 124. -193. - 124. -195. - 125. -196. - 126. -198. - 126. -200. -REG_LINE: 15 - -82.8 82.6 - -83.3 90.3 - -83.6 98.1 - -83.8 106. - -83.9 114. - -83.8 122. - -83.6 129. - -83.3 137. - -82.8 145. - -82.1 153. - -81.4 160. - -80.5 168. - -79.4 175. - -78.3 183. - -77.0 190. -REG_LINE: 15 - -82.8 82.6 - -82.2 74.9 - -81.4 67.2 - -80.5 59.6 - -79.5 52.0 - -78.3 44.6 - -77.1 37.2 - -75.6 29.9 - -74.1 22.8 - -72.4 15.7 - -70.6 8.81 - -68.7 2.01 - -66.6 -4.64 - -64.4 -11.1 - -62.2 -17.5 -REG_LINE: 15 - -62.2 -17.5 - -59.8 -23.7 - -57.3 -29.7 - -54.7 -35.5 - -51.9 -41.1 - -49.1 -46.5 - -46.2 -51.8 - -43.2 -56.8 - -40.2 -61.6 - -37.0 -66.1 - -33.7 -70.5 - -30.4 -74.6 - -27.0 -78.5 - -23.6 -82.1 - -20.0 -85.5 -REG_LINE: 15 - -20.0 -85.5 - -16.5 -88.6 - -12.8 -91.5 - -9.15 -94.1 - -5.42 -96.4 - -1.66 -98.5 - 2.14 -100. - 5.97 -102. - 9.83 -103. - 13.7 -104. - 17.6 -105. - 21.5 -105. - 25.4 -105. - 29.3 -105. - 33.2 -105. -REG_LINE: 15 - 33.2 -105. - 37.1 -104. - 41.0 -103. - 44.8 -102. - 48.7 -100. - 52.5 -98.5 - 56.2 -96.5 - 60.0 -94.2 - 63.6 -91.6 - 67.3 -88.7 - 70.9 -85.6 - 74.4 -82.2 - 77.8 -78.6 - 81.2 -74.7 - 84.6 -70.6 -REG_LINE: 15 - 84.6 -70.6 - 87.8 -66.3 - 91.0 -61.7 - 94.1 -56.9 - 97.1 -51.9 - 100. -46.7 - 103. -41.3 - 105. -35.7 - 108. -29.9 - 111. -23.9 - 113. -17.7 - 115. -11.4 - 117. -4.87 - 120. 1.78 - 121. 8.56 -REG_LINE: 15 - 121. 8.56 - 123. 15.5 - 125. 22.5 - 127. 29.7 - 128. 37.0 - 129. 44.3 - 130. 51.8 - 131. 59.3 - 132. 66.9 - 133. 74.6 - 134. 82.3 - 134. 90.0 - 135. 97.8 - 135. 106. - 135. 113. -REG_LINE: 15 - 135. 113. - 135. 121. - 135. 129. - 134. 137. - 134. 145. - 133. 152. - 132. 160. - 131. 168. - 130. 175. - 129. 183. - 128. 190. - 127. 197. - 125. 204. - 123. 211. - 121. 218. -REG_LINE: 15 - 121. 218. - 120. 225. - 117. 232. - 115. 238. - 113. 245. - 111. 251. - 108. 257. - 105. 263. - 103. 268. - 100. 274. - 97.1 279. - 94.1 284. - 91.0 289. - 87.8 293. - 84.6 298. -REG_LINE: 2 - 84.6 298. - 82.5 300. -REG_LINE: 12 - -31.6 300. - -33.7 297. - -37.0 293. - -40.2 288. - -43.2 284. - -46.2 279. - -49.1 273. - -51.9 268. - -54.7 262. - -57.3 257. - -59.8 251. - -62.2 244. -REG_LINE: 15 - -62.2 244. - -64.4 238. - -66.6 232. - -68.7 225. - -70.6 218. - -72.4 211. - -74.1 204. - -75.6 197. - -77.1 190. - -78.3 182. - -79.5 175. - -80.5 167. - -81.4 160. - -82.2 152. - -82.8 144. -REG_LINE: 15 - -82.8 144. - -83.3 137. - -83.6 129. - -83.8 121. - -83.9 113. - -83.8 105. - -83.6 97.5 - -83.3 89.8 - -82.8 82.0 - -82.1 74.3 - -81.4 66.7 - -80.5 59.0 - -79.4 51.5 - -78.3 44.1 - -77.0 36.7 -REG_LINE: 15 - -82.8 144. - -83.3 137. - -83.6 129. - -83.8 121. - -83.9 113. - -83.8 105. - -83.6 97.5 - -83.3 89.8 - -82.8 82.0 - -82.1 74.3 - -81.4 66.7 - -80.5 59.0 - -79.4 51.5 - -78.3 44.1 - -77.0 36.7 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0.0' - 27.8 114. BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '50.0' - 36.3 87.9 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '100.0' - 44.7 61.6 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '150.0' - 53.2 35.3 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '200.0' - 61.6 9.02 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '250.0' - 70.1 -17.3 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '300.0' - 78.5 -43.6 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '350.0' - 86.9 -69.9 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '400.0' - 95.4 -96.2 BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '450.0' - 104. -122. BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '500.0' - 112. -149. BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '550.0' - 121. -175. BC .952 .306 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -Symbol = "p1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 2" # Axis Label - Symbol = "p2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - InvB = 1 # Second Mapping used in inverse direction - MapA = # First component Mapping - Begin MathMap # Transformation using mathematical functions - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Fwd1 = "r=sqrt(x*x+y*y)" # Forward function 1 - Fwd2 = "theta=atan2(y,x)" # Forward function 2 - Inv1 = "x=r*cos(theta)" # Inverse function 1 - Inv2 = "y=r*sin(theta)" # Inverse function 2 - SimpFI = 1 # Forward-inverse pairs may simplify - SimpIF = 1 # Inverse-forward pairs may simplify - End MathMap - MapB = # Second component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -101.5 # Shift for axis 1 - Sft2 = -201.5 # Shift for axis 2 - End WinMap - End CmpMap - End FrameSet - Begin FrameSet # Set of inter-related coordinate systems -# Title = "FK5 equatorial coordinates; mean equinox J2000.0; gnomonic projection" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Epoch = 1977.77512999212 # Besselian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# System = "FK5" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - IsA Frame # Coordinate system description - Nframe = 2 # Number of Frames in FrameSet - Base = 1 # Index of base Frame - Currnt = 2 # Index of current Frame - Lnk2 = 1 # Node 2 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Pixel Coordinates" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Pixel axis 1" # Label for axis 1 -# Lbl2 = "Pixel axis 2" # Label for axis 2 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel axis 1" # Axis Label - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel axis 2" # Axis Label - End Axis - End Frame - Frm2 = # Frame number 2 - Begin SkyFrame # Description of celestial coordinate system - Ident = " " # Permanent Object identification string - IsA Object # AST Object -# Title = "FK5 equatorial coordinates; mean equinox J2000.0; gnomonic projection" # Title of coordinate system - Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain - Epoch = 1977.77512999212 # Besselian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 - System = "FK5" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - Proj = "gnomonic" # Description of sky projection - Eqnox = 2000 # Julian epoch of mean equinox - SRefIs = "Ignored" # Not rotated (ref. pos. is ignored) - SRef1 = 0 # Ref. pos. RA 0:00:00.0 - SRef2 = -1.57079633000002 # Ref. pos. Dec -90:00:00 - End SkyFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -893.6318379289 # Shift for axis 1 - Sft2 = -223.8380193875 # Shift for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -3.25441534352674e-06 # Forward matrix value - M1 = -1.60367292352974e-08 # Forward matrix value - M2 = -1.812057487023e-08 # Forward matrix value - M3 = 3.25725533992408e-06 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitREG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-3.0' - -80.3 82.7 BC .997 0.724E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-2.5' - -59.8 -16.6 BC .936 .352 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-2.0' - -18.4 -83.6 BC .673 .740 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-1.5' - 32.8 -102. BC -.145 .989 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-0.5' - 119. 9.22 BC -.965 .262 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0.0' - 132. 113. BC -1.00 0.125E-02 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0.5' - 119. 218. TC .964 .265 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '1.0' - 82.6 296. TC .787 .617 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '2.5' - -59.8 243. TC -.936 .352 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '3.0' - -80.3 144. TC -.997 0.724E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 1 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: ' A FITS test' - 31.0 313. BC .000 1.00 - - - - - FITS test number 3 - ==================== - - - -AST_SHOW: - -REG_SINK: -SIMPLE = T / file does conform to FITS standard -BITPIX = 16 / number of bits per data pixel -NAXIS = 2 / number of data axes -NAXIS1 = 1787 / length of data axis 1 -NAXIS2 = 447 / length of data axis 2 -EXTEND = T / FITS dataset may contain extensions -COMMENT FITS (Flexible Image Transport System) format defined in Astronomy and -COMMENT Astrophysics Supplement Series v44/p363, v44/p371, v73/p359, v73/p365. -COMMENT Contact the NASA Science Office of Standards and Technology for the -COMMENT FITS Definition document #100 and other FITS information. -PLATENUM= '3665 ' / Plate number -EMULSION= 'IIIaJ ' / Kodak emulsion type -FILTER = 'GG395 ' / Schott glass filter type -PLTSCALE= '67.14 ' / [arcsec/mm] plate scale -FIELDNUM= '1 ' / Sky survey field number -TELESCOP= 'UKST ' / Telescope on which the plate was taken -TELETYPE= 'SCHM ' / Type of telescope -SITELAT = -0.5458410576565 / [radians] latitude of telescope -SITELONG= 2.601766194458 / [radians] longitude of telescope -LST = '00:20 ' / [hh:mm] local sidereal time at start of obs -INSTRUME= 'SuperCOSMOS I' / Measuring machine -DATE-MES= '2000-11-04' / [yyyy-mm-dd] Date of this plate measurement -NHKLINES= 146 / Number of lines from house-keeping file -HKLIN001= 'JOB.JOBNO UKJ001' -HKLIN002= 'JOB.DATE-MES 2000:11:04' -HKLIN003= 'JOB.TIME 12:51:09' -HKLIN004= 'JOB.INSTRUME SuperCOSMOS I' -HKLIN005= 'JOB.ORIGIN Royal Observatory Edinburgh' -HKLIN006= 'JOB.SOFTWARE /home/scosdev/v033' -HKLIN007= 'JOB.OPERATOR ebt' -HKLIN008= 'JOB.USER htm' -HKLIN009= 'JOB.USERREF NONE' -HKLIN010= 'JOB.UORIGIN ROE' -HKLIN011= 'JOB.UCOUNTRY uk' -HKLIN012= 'JOB.COMMENT Digital catalogue of the Sky' -HKLIN013= 'JOB.IAM_FILE iam.srt'/ / ' / -HKLIN014= 'PLATE.TELESCOP UKST' -HKLIN015= 'PLATE.TELTYPE SCHM' -HKLIN016= 'PLATE.PLATE 3665' -HKLIN017= 'PLATE.MATERIAL 3mm glass' -HKLIN018= 'PLATE.EMULSION IIIaJ' -HKLIN019= 'PLATE.FILTER GG395' -HKLIN020= 'PLATE.PSCALE 67.14' -HKLIN021= 'PLATE.FIELD 1' -HKLIN022= 'PLATE.RA_PNT 0' -HKLIN023= 'PLATE.DEC_PNT -90' -HKLIN024= 'PLATE.RADECSYS FK4' -HKLIN025= 'PLATE.EQUINOX 1950' -HKLIN026= 'PLATE.TIMESYS BESSELIAN' -HKLIN027= 'PLATE.EPOCH 1977.78'/ / ' / -HKLIN028= 'PLATE.EXPOSURE 75' -HKLIN029= 'PLATE.UTDATE 771011' -HKLIN030= 'PLATE.LST 0020' -HKLIN031= 'PLATE.MJD 43426.573008796' -HKLIN032= 'PLATE.TELLAT -0.54584105765654' -HKLIN033= 'PLATE.TELLONG 2.6017661944583' -HKLIN034= 'PLATE.TELHT 1145' -HKLIN035= 'PLATE.TEMP 273.155'/ / ' / -HKLIN036= 'PLATE.ATMOSP 1013.25'/ / ' / -HKLIN037= 'PLATE.HUMID 0.5' -HKLIN038= 'PLATE.WAVE 4500' -HKLIN039= 'PLATE.TROPL 0.0065' -HKLIN040= 'CALIBRATION.CALTYPE SPLINE' -HKLIN041= 'CALIBRATION.STEPWEDG KPNO' -HKLIN042= 'CALIBRATION.NSTEPS 8' -HKLIN043= 'MEASUREMENT.ORIENTAT news' -HKLIN044= 'MEASUREMENT.EMULPOS UP' -HKLIN045= 'MEASUREMENT.SCANFILT 14' -HKLIN046= 'MEASUREMENT.SOSP 552' -HKLIN047= 'MEASUREMENT.STEPSIZE 10' -HKLIN048= 'MEASUREMENT.SCANLEN 1152' -HKLIN049= 'MEASUREMENT.A-XMIN 1622000'/ / ' / -HKLIN050= 'MEASUREMENT.A-YMIN 1622000'/ / ' / -HKLIN051= 'MEASUREMENT.A-XMAX 33878000' -HKLIN052= 'MEASUREMENT.A-YMAX 33878000' -HKLIN053= 'MEASUREMENT.X_PNT 17500000' -HKLIN054= 'MEASUREMENT.Y_PNT 18000000' -HKLIN055= 'ANALYSIS.NPARAMS 32' -HKLIN056= 'ANALYSIS.AREACUT 8' -HKLIN057= 'ANALYSIS.AP-PARAM 1.07' -HKLIN058= 'DEBLEND.DB-PARAM 1.05' -HKLIN059= 'DEBLEND.DB-AMIN 16' -HKLIN060= 'DEBLEND.DB-AMAX 100000' -HKLIN061= 'DEBLEND.DB-ACUT 8' -HKLIN062= 'DEBLEND.DB-LEVEL 16' -HKLIN063= 'DEBLEND.SELECT PARENT+CHILD' -HKLIN064= 'SKY.SKYSQUAR 64' -HKLIN065= 'SKY.SKYDEFN MEDIAN' -HKLIN066= 'SKY.SKYFILTR bdkjunk'/ / ' / -HKLIN067= 'SKY.F-THRESH 8' -HKLIN068= 'SKY.F-SCLEN 4' -HKLIN069= 'THRESHOLDING.PCUT 10' -HKLIN070= 'IAMQC.AREAMIN 8' -HKLIN071= 'IAMQC.AREAMAX 77346' -HKLIN072= 'IAMQC.MINMAG -30515' -HKLIN073= 'IAMQC.MAXMAG -17954' -HKLIN074= 'IAMQC.MINELL 0.0004156232' -HKLIN075= 'IAMQC.MAXELL 1' -HKLIN076= 'IAMQC.MODELL 0.14' -HKLIN077= 'IAMQC.MODOR 91' -HKLIN078= 'IAMQC.MIDELL 0.21' -HKLIN079= 'IAMQC.MIDOR 93' -HKLIN080= 'IAMQC.MEANELL 0.2467037' -HKLIN081= 'IAMQC.MEANOR 91.63474' -HKLIN082= 'IAMQC.NUMOBJ 556985' -HKLIN083= 'IAMQC.PARENTS 486656' -HKLIN084= 'IAMQC.RANGING TRUE' -HKLIN085= 'IAMQC.LANE_1 15571' -HKLIN086= 'IAMQC.LANE_2 33207' -HKLIN087= 'IAMQC.LANE_3 51478' -HKLIN088= 'IAMQC.LANE_4 69944' -HKLIN089= 'IAMQC.LANE_5 89236' -HKLIN090= 'IAMQC.LANE_6 108416' -HKLIN091= 'IAMQC.LANE_7 127481' -HKLIN092= 'IAMQC.LANE_8 146699' -HKLIN093= 'IAMQC.LANE_9 166380' -HKLIN094= 'IAMQC.LANE_10 186126' -HKLIN095= 'IAMQC.LANE_11 205946' -HKLIN096= 'IAMQC.LANE_12 225915' -HKLIN097= 'IAMQC.LANE_13 245926' -HKLIN098= 'IAMQC.LANE_14 266574' -HKLIN099= 'IAMQC.LANE_15 287150' -HKLIN100= 'IAMQC.LANE_16 308087' -HKLIN101= 'IAMQC.LANE_17 328830' -HKLIN102= 'IAMQC.LANE_18 350253' -HKLIN103= 'IAMQC.LANE_19 370738' -HKLIN104= 'IAMQC.LANE_20 391722' -HKLIN105= 'IAMQC.LANE_21 412801' -HKLIN106= 'IAMQC.LANE_22 433795' -HKLIN107= 'IAMQC.LANE_23 454383' -HKLIN108= 'IAMQC.LANE_24 474711' -HKLIN109= 'IAMQC.LANE_25 495108' -HKLIN110= 'IAMQC.LANE_26 515755' -HKLIN111= 'IAMQC.LANE_27 536499' -HKLIN112= 'IAMQC.LANE_28 556985' -HKLIN113= 'XYTORADEC.STARCAT /sdata/scos/refcats/tycho2.FIT' -HKLIN114= 'XYTORADEC.BRIGHTLIM 9' -HKLIN115= 'XYTORADEC.C-EQUIN 2000' -HKLIN116= 'XYTORADEC.C-EQTSYS JULIAN' -HKLIN117= 'XYTORADEC.C-EPOCH 2000' -HKLIN118= 'XYTORADEC.C-EPTSYS JULIAN' -HKLIN119= 'XYTORADEC.R-EQUIN 2000' -HKLIN120= 'XYTORADEC.R-TSYS JULIAN' -HKLIN121= 'XYTORADEC.MAXITER 5000' -HKLIN122= 'XYTORADEC.RCRITINI 500000' -HKLIN123= 'XYTORADEC.RCRITABS 50000' -HKLIN124= 'XYTORADEC.RCRITREL 1' -HKLIN125= 'XYTORADEC.RCRITFIN 3' -HKLIN126= 'XYTORADEC.HARDCOPY /scos1/scos/UKJ001/UKJ001.ps' -HKLIN127= 'XYTORADEC.REFSMULT 5' -HKLIN128= 'XYTORADEC.RESDMULT 1000' -HKLIN129= 'XYTORADEC.RACOL RA' -HKLIN130= 'XYTORADEC.DECOL DEC' -HKLIN131= 'XYTORADEC.RAPMCOL PMRA' -HKLIN132= 'XYTORADEC.DECPMCOL PMDE' -HKLIN133= 'XYTORADEC.PLXCOL NONE' -HKLIN134= 'XYTORADEC.RVCOL NONE' -HKLIN135= 'XYTORADEC.MAGCOL VT' -HKLIN136= 'XYTORADEC.STARSC 2374' -HKLIN137= 'XYTORADEC.STARSU 1727' -HKLIN138= 'XYTORADEC.COEFFS_1 17.640343856524' -HKLIN139= 'XYTORADEC.COEFFS_2 -260.44151995641' -HKLIN140= 'XYTORADEC.COEFFS_3 -163.09155572601' -HKLIN141= 'XYTORADEC.COEFFS_4 17.504230442205' -HKLIN142= 'XYTORADEC.COEFFS_5 -163.08676953832' -HKLIN143= 'XYTORADEC.COEFFS_6 260.48817907668' -HKLIN144= 'XYTORADEC.DISTR -0.33333333333333' -HKLIN145= 'XYTORADEC.RA_PNT 0.54924996662137' -HKLIN146= 'XYTORADEC.DEC_PNT -1.5684931501781' -HISTORY = 'SuperCOSMOS image analysis and mapping mode (IAM and MM)' / -HISTORY = 'data written by xydcomp_ss.' / -HISTORY = 'Any questions/comments/suggestions/bug reports should be sent' / -HISTORY = 'to N.Hambly@roe.ac.uk' / -ASTSIGX = 0.37 / [arcsec] std. dev. of astrometric fit in X -ASTSIGY = 0.38 / [arcsec] std. dev. of astrometric fit in Y -PC001001= 1.0 / DEPRECATED - Axis rotation matrix -PC001002= 0.004927623810613 / DEPRECATED - Axis rotation matrix -PC002001= -0.005563056187788 / DEPRECATED - Axis rotation matrix -PC002002= 1.0 / DEPRECATED - Axis rotation matrix -CROTA2 = 0.3005532298491 / DEPRECATED - rotation of axis 2 -DATATYPE= 'INTEGER*2' / Type of data -DATUNITS= 'DENSITY ' / Units: transmission, density or intensity -XPIXELSZ= 9.997114974 / [microns] X pixel size -YPIXELSZ= 10.0 / [microns] Y pixel size -OBJCTRA = ' 0 0 0.000' / Centre Right Ascension (J2000) -OBJCTDEC= '-90 0 0.00' / Centre Declination (J2000) -OBJCTX = 16368.63183793 / [pixels] Centre X on plate -OBJCTY = 14740.83801939 / [pixels] Centre Y on plate - -Objects written: 1 - -Native Encoding: - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST WCS information in AST format AST -COMMENT AST See http://www.starlink.ac.uk/ast/ AST -COMMENT AST Beginning of AST data for FrameSet object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'FrameSet' / Set of inter-related coordinate systems -NFRAME_A= 2 / Number of Frames in FrameSet -BASE_A = 1 / Index of base Frame -CURRNT_A= 2 / Index of current Frame -LNK2_A = 1 / Node 2 is derived from node 1 -FRM1_A = ' ' / Frame number 1 -BEGAST_B= 'Frame ' / Coordinate system description -TITLE_A = 'Pixel Coordinates' / Title of coordinate system -NAXES_A = 2 / Number of coordinate axes -DOMAIN_A= 'GRID ' / Coordinate system domain -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -LABEL_A = 'Pixel axis 1' / Axis Label -ENDAST_A= 'Axis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_D= 'Axis ' / Coordinate axis -LABEL_B = 'Pixel axis 2' / Axis Label -ENDAST_B= 'Axis ' / End of object definition -ENDAST_C= 'Frame ' / End of object definition -FRM2_A = ' ' / Frame number 2 -BEGAST_E= 'SkyFrame' / Description of celestial coordinate system -IDENT_A = '" " ' / Permanent Object identification string -ISA_A = 'Object ' / AST Object -NAXES_B = 2 / Number of coordinate axes -EPOCH_A = 1977.77512999212 / Besselian epoch of observation -SYSTEM_A= 'FK5 ' / Coordinate system type -AX1_B = ' ' / Axis number 1 -BEGAST_F= 'SkyAxis ' / Celestial coordinate axis -ENDAST_D= 'SkyAxis ' / End of object definition -AX2_B = ' ' / Axis number 2 -BEGAST_G= 'SkyAxis ' / Celestial coordinate axis -ENDAST_E= 'SkyAxis ' / End of object definition -ISA_B = 'Frame ' / Coordinate system description -PROJ_A = 'gnomonic' / Description of sky projection -EQNOX_A = 2000.0 / Julian epoch of mean equinox -SREFIS_A= 'Ignored ' / Not rotated (ref. pos. is ignored) -SREF1_A = 0.0 / Ref. pos. RA 0:00:00.0 -SREF2_A = -1.57079633 / Ref. pos. Dec -90:00:00 -ENDAST_F= 'SkyFrame' / End of object definition -MAP2_A = ' ' / Mapping between nodes 1 and 2 -BEGAST_H= 'CmpMap ' / Compound Mapping -NIN_A = 2 / Number of input coordinates -ISSIMP_A= 1 / Mapping has been simplified -ISA_C = 'Mapping ' / Mapping between coordinate systems -MAPA_A = ' ' / First component Mapping -BEGAST_I= 'WinMap ' / Map one window on to another -NIN_B = 2 / Number of input coordinates -INVERT_A= 0 / Mapping not inverted -ISA_D = 'Mapping ' / Mapping between coordinate systems -SFT1_A = -893.6318379289 / Shift for axis 1 -SFT2_A = -223.8380193875 / Shift for axis 2 -ENDAST_G= 'WinMap ' / End of object definition -MAPB_A = ' ' / Second component Mapping -BEGAST_J= 'CmpMap ' / Compound Mapping -NIN_C = 2 / Number of input coordinates -ISA_E = 'Mapping ' / Mapping between coordinate systems -MAPA_B = ' ' / First component Mapping -BEGAST_K= 'MatrixMap' / Matrix transformation -NIN_D = 2 / Number of input coordinates -INVERT_B= 0 / Mapping not inverted -ISA_F = 'Mapping ' / Mapping between coordinate systems -M0_A = -3.25441534352674E-6/ Forward matrix value -M1_A = -1.60367292352974E-8/ Forward matrix value -M2_A = -1.812057487023E-8 / Forward matrix value -M3_A = 3.25725533992408E-6 / Forward matrix value -FORM_A = 'Full ' / Matrix storage form -ENDAST_H= 'MatrixMap' / End of object definition -MAPB_B = ' ' / Second component Mapping -BEGAST_L= 'CmpMap ' / Compound Mapping -NIN_E = 2 / Number of input coordinates -ISA_G = 'Mapping ' / Mapping between coordinate systems -INVA_A = 1 / First Mapping used in inverse direction -MAPA_C = ' ' / First component Mapping -BEGAST_M= 'WcsMap ' / FITS-WCS sky projection -NIN_F = 2 / Number of input coordinates -INVERT_C= 1 / Mapping inverted -ISA_H = 'Mapping ' / Mapping between coordinate systems -TYPE_A = 'TAN ' / Gnomonic projection -ENDAST_I= 'WcsMap ' / End of object definition -MAPB_C = ' ' / Second component Mapping -BEGAST_N= 'CmpMap ' / Compound Mapping -NIN_G = 2 / Number of input coordinates -ISA_I = 'Mapping ' / Mapping between coordinate systems -INVA_B = 1 / First Mapping used in inverse direction -MAPA_D = ' ' / First component Mapping -BEGAST_O= 'SphMap ' / Cartesian to Spherical mapping -NIN_H = 3 / Number of input coordinates -NOUT_A = 2 / Number of output coordinates -INVERT_D= 1 / Mapping inverted -ISA_J = 'Mapping ' / Mapping between coordinate systems -UNTRD_A = 1 / All input vectors have unit length -PLRLG_A = 0.0 / Polar longitude (rad.s) -ENDAST_J= 'SphMap ' / End of object definition -MAPB_D = ' ' / Second component Mapping -BEGAST_P= 'CmpMap ' / Compound Mapping -NIN_I = 3 / Number of input coordinates -NOUT_B = 2 / Number of output coordinates -ISA_K = 'Mapping ' / Mapping between coordinate systems -MAPA_E = ' ' / First component Mapping -BEGAST_Q= 'MatrixMap' / Matrix transformation -NIN_J = 3 / Number of input coordinates -INVERT_E= 0 / Mapping not inverted -ISA_L = 'Mapping ' / Mapping between coordinate systems -M0_B = -1.0 / Forward matrix value -M1_B = 1.0 / Forward matrix value -M2_B = -1.0 / Forward matrix value -FORM_B = 'Diagonal' / Matrix storage form -ENDAST_K= 'MatrixMap' / End of object definition -MAPB_E = ' ' / Second component Mapping -BEGAST_R= 'SphMap ' / Cartesian to Spherical mapping -NIN_K = 3 / Number of input coordinates -NOUT_C = 2 / Number of output coordinates -INVERT_F= 0 / Mapping not inverted -ISA_M = 'Mapping ' / Mapping between coordinate systems -UNTRD_B = 1 / All input vectors have unit length -PLRLG_B = 0.0 / Polar longitude (rad.s) -ENDAST_L= 'SphMap ' / End of object definition -ENDAST_M= 'CmpMap ' / End of object definition -ENDAST_N= 'CmpMap ' / End of object definition -ENDAST_O= 'CmpMap ' / End of object definition -ENDAST_P= 'CmpMap ' / End of object definition -ENDAST_Q= 'CmpMap ' / End of object definition -ENDAST_R= 'FrameSet' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for FrameSet object AST -COMMENT AST ---------------------------------------------------------------- AST - -ATTRIBUTES: - Colour(axis1) : 1 - Font(Stri) : 1 - Nout : 1 - Class : 4 - Tol : 0.100000E-01 - Gap(1) : .523599 - Border : 0 - Invert : 0 - TextLabGap : 0.100000E-01 - Nin : 2 - Current : 3 - Base : 1 - Nobject : 1 - RefCOUNT : 1 - -AST_GRID: -REG_LINE: 2 - 15.5 -136. - 15.4 -137. -REG_LINE: 2 - 18.6 -144. - 18.5 -146. -REG_LINE: 2 - 21.8 -149. - 21.8 -151. -REG_LINE: 2 - 25.1 -150. - 25.1 -154. -REG_LINE: 2 - 28.3 -149. - 28.4 -150. -REG_LINE: 2 - 31.5 -143. - 31.6 -145. -REG_LINE: 2 - 34.6 -135. - 34.7 -136. -REG_LINE: 2 - 37.6 -123. - 37.8 -127. -REG_LINE: 2 - 40.3 -108. - 40.4 -110. -REG_LINE: 2 - 42.7 -91.0 - 42.9 -92.7 -REG_LINE: 2 - 44.9 -71.2 - 45.2 -72.9 -REG_LINE: 2 - 46.7 -49.3 - 47.5 -53.0 -REG_LINE: 2 - 48.1 -25.8 - 48.6 -27.4 -REG_LINE: 2 - 49.2 -.928 - 49.9 -2.51 -REG_LINE: 2 - 49.8 24.8 - 51.0 23.5 -REG_LINE: 2 - 50.0 50.9 - 53.7 51.1 -REG_LINE: 2 - 49.7 77.1 - 50.9 78.4 -REG_LINE: 2 - 49.1 103. - 49.8 104. -REG_LINE: 2 - 48.0 127. - 48.5 129. -REG_LINE: 2 - 46.6 151. - 47.3 155. -REG_LINE: 2 - 44.7 173. - 45.0 174. -REG_LINE: 2 - 42.6 192. - 42.8 194. -REG_LINE: 2 - 40.1 209. - 40.2 211. -REG_LINE: 2 - 37.4 224. - 37.6 228. -REG_LINE: 2 - 34.4 235. - 34.5 237. -REG_LINE: 2 - 31.3 244. - 31.4 245. -REG_LINE: 2 - 28.1 248. - 28.1 250. -REG_LINE: 2 - 24.8 250. - 24.8 254. -REG_LINE: 2 - 21.6 248. - 21.5 250. -REG_LINE: 2 - 18.4 243. - 18.3 245. -REG_LINE: 2 - 15.3 234. - 15.2 236. -REG_LINE: 2 - 12.3 223. - 12.1 226. -REG_LINE: 2 - 9.62 208. - 9.45 210. -REG_LINE: 2 - 7.17 191. - 6.95 192. -REG_LINE: 2 - 5.02 171. - 4.74 173. -REG_LINE: 2 - 3.22 149. - 2.41 153. -REG_LINE: 2 - 1.78 125. - 1.27 127. -REG_LINE: 2 - .747 101. - -0.657E-02 102. -REG_LINE: 2 - .124 74.8 - -1.11 76.1 -REG_LINE: 2 - -0.740E-01 48.7 - -3.82 48.5 -REG_LINE: 2 - .156 22.6 - -1.02 21.3 -REG_LINE: 2 - .811 -3.08 - 0.841E-01 -4.67 -REG_LINE: 2 - 1.88 -27.8 - 1.38 -29.5 -REG_LINE: 2 - 3.34 -51.3 - 2.56 -54.9 -REG_LINE: 2 - 5.17 -73.0 - 4.89 -74.7 -REG_LINE: 2 - 7.34 -92.6 - 7.13 -94.3 -REG_LINE: 2 - 9.81 -110. - 9.65 -111. -REG_LINE: 2 - 12.5 -124. - 12.3 -128. -REG_LINE: 2 - 15.5 -136. - 15.4 -137. -REG_LINE: 2 - 18.6 -144. - 18.5 -146. -REG_LINE: 2 - 21.8 -149. - 21.8 -151. -REG_LINE: 2 - 25.1 -150. - 25.1 -154. -REG_LINE: 2 - 28.3 -149. - 28.4 -150. -REG_LINE: 2 - 31.5 -143. - 31.6 -145. -REG_LINE: 2 - 34.6 -135. - 34.7 -136. -REG_LINE: 2 - 24.9 74.8 - 26.5 75.6 -REG_LINE: 2 - 24.9 99.9 - 26.5 101. -REG_LINE: 2 - 24.9 125. - 26.5 126. -REG_LINE: 2 - 24.9 150. - 28.3 152. -REG_LINE: 2 - 24.9 175. - 26.5 176. -REG_LINE: 2 - 24.9 200. - 26.4 201. -REG_LINE: 2 - 24.8 225. - 26.4 226. -REG_LINE: 2 - 24.8 250. - 28.2 252. -REG_LINE: 2 - 24.8 275. - 26.4 276. -REG_LINE: 15 - 25.1 -150. - 24.1 -150. - 23.2 -150. - 22.3 -149. - 21.3 -148. - 20.4 -147. - 19.5 -146. - 18.6 -144. - 17.7 -142. - 16.8 -140. - 15.9 -137. - 15.1 -134. - 14.2 -131. - 13.4 -128. - 12.5 -124. -REG_LINE: 15 - 25.1 -150. - 26.0 -150. - 26.9 -150. - 27.9 -149. - 28.8 -148. - 29.7 -147. - 30.6 -145. - 31.5 -143. - 32.4 -141. - 33.3 -139. - 34.2 -136. - 35.1 -133. - 35.9 -130. - 36.7 -127. - 37.6 -123. -REG_LINE: 15 - 37.6 -123. - 38.4 -119. - 39.1 -115. - 39.9 -111. - 40.6 -106. - 41.4 -101. - 42.1 -96.2 - 42.7 -91.0 - 43.4 -85.6 - 44.0 -79.9 - 44.6 -74.2 - 45.2 -68.2 - 45.7 -62.1 - 46.2 -55.8 - 46.7 -49.3 -REG_LINE: 15 - 46.7 -49.3 - 47.1 -42.8 - 47.5 -36.1 - 47.9 -29.2 - 48.3 -22.3 - 48.6 -15.3 - 48.9 -8.13 - 49.2 -.928 - 49.4 6.35 - 49.6 13.7 - 49.7 21.1 - 49.8 28.5 - 49.9 36.0 - 50.0 43.4 - 50.0 50.9 -REG_LINE: 15 - 50.0 50.9 - 49.9 58.4 - 49.9 65.9 - 49.8 73.3 - 49.7 80.8 - 49.5 88.1 - 49.3 95.5 - 49.1 103. - 48.8 110. - 48.5 117. - 48.2 124. - 47.8 131. - 47.4 138. - 47.0 144. - 46.6 151. -REG_LINE: 15 - 46.6 151. - 46.1 157. - 45.6 164. - 45.0 170. - 44.4 176. - 43.8 181. - 43.2 187. - 42.6 192. - 41.9 197. - 41.2 202. - 40.5 207. - 39.7 212. - 38.9 216. - 38.2 220. - 37.4 224. -REG_LINE: 15 - 37.4 224. - 36.5 227. - 35.7 231. - 34.8 234. - 34.0 237. - 33.1 239. - 32.2 241. - 31.3 244. - 30.4 245. - 29.5 247. - 28.6 248. - 27.6 249. - 26.7 250. - 25.8 250. - 24.8 250. -REG_LINE: 15 - 24.8 250. - 23.9 250. - 23.0 249. - 22.0 249. - 21.1 248. - 20.2 246. - 19.3 245. - 18.4 243. - 17.5 241. - 16.6 238. - 15.7 236. - 14.8 233. - 14.0 230. - 13.1 226. - 12.3 223. -REG_LINE: 15 - 12.3 223. - 11.5 219. - 10.8 215. - 9.99 210. - 9.25 206. - 8.53 201. - 7.84 196. - 7.17 191. - 6.52 185. - 5.90 180. - 5.31 174. - 4.74 168. - 4.20 162. - 3.70 155. - 3.22 149. -REG_LINE: 15 - 3.22 149. - 2.77 142. - 2.35 136. - 1.96 129. - 1.61 122. - 1.29 115. - 1.00 108. - .747 101. - .526 93.3 - .339 85.9 - .187 78.6 - 0.696E-01 71.1 - -0.132E-01 63.7 - -0.611E-01 56.2 - -0.740E-01 48.7 -REG_LINE: 15 - -0.740E-01 48.7 - -0.519E-01 41.2 - 0.519E-02 33.7 - 0.971E-01 26.3 - .224 18.9 - .385 11.5 - .581 4.18 - .811 -3.08 - 1.07 -10.3 - 1.37 -17.4 - 1.70 -24.4 - 2.06 -31.3 - 2.46 -38.1 - 2.88 -44.7 - 3.34 -51.3 -REG_LINE: 15 - 3.34 -51.3 - 3.83 -57.7 - 4.34 -63.9 - 4.89 -70.0 - 5.46 -75.9 - 6.06 -81.6 - 6.69 -87.2 - 7.34 -92.6 - 8.02 -97.7 - 8.72 -103. - 9.44 -107. - 10.2 -112. - 11.0 -116. - 11.7 -120. - 12.5 -124. -REG_LINE: 15 - 12.5 -124. - 13.4 -128. - 14.2 -131. - 15.1 -134. - 15.9 -137. - 16.8 -140. - 17.7 -142. - 18.6 -144. - 19.5 -146. - 20.4 -147. - 21.3 -148. - 22.3 -149. - 23.2 -150. - 24.1 -150. - 25.1 -150. -REG_LINE: 15 - 25.1 -150. - 26.0 -150. - 26.9 -150. - 27.9 -149. - 28.8 -148. - 29.7 -147. - 30.6 -145. - 31.5 -143. - 32.4 -141. - 33.3 -139. - 34.2 -136. - 35.1 -133. - 35.9 -130. - 36.7 -127. - 37.6 -123. -REG_LINE: 15 - 25.1 -150. - 26.0 -150. - 26.9 -150. - 27.9 -149. - 28.8 -148. - 29.7 -147. - 30.6 -145. - 31.5 -143. - 32.4 -141. - 33.3 -139. - 34.2 -136. - 35.1 -133. - 35.9 -130. - 36.7 -127. - 37.6 -123. -REG_LINE: 15 - 24.9 49.8 - 24.9 57.0 - 24.9 64.1 - 24.9 71.3 - 24.9 78.4 - 24.9 85.6 - 24.9 92.7 - 24.9 99.9 - 24.9 107. - 24.9 114. - 24.9 121. - 24.9 128. - 24.9 136. - 24.9 143. - 24.9 150. -REG_LINE: 15 - 24.9 150. - 24.9 157. - 24.9 164. - 24.9 171. - 24.9 179. - 24.9 186. - 24.9 193. - 24.9 200. - 24.9 207. - 24.8 214. - 24.8 221. - 24.8 229. - 24.8 236. - 24.8 243. - 24.8 250. -REG_LINE: 8 - 24.8 250. - 24.8 257. - 24.8 264. - 24.8 272. - 24.8 279. - 24.8 286. - 24.8 293. - 24.8 300. -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '12' - 24.9 -148. BC -0.654E-01 .998 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '14' - 35.1 -123. BC -.978 .210 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '16' - 44.2 -49.2 BC -.997 0.716E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '18' - 47.5 50.9 BC -1.00 -0.942E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '20' - 44.1 151. TC .997 0.732E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '22' - 34.9 223. TC .977 .213 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '0' - 24.9 248. TC -0.236E-01 1.00 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '2' - 14.8 222. TC -.978 .210 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '4' - 5.71 149. TC -.997 0.716E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '6' - 2.43 48.7 BC 1.00 0.288E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '8' - 5.83 -51.1 BC .997 0.732E-01 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '10' - 15.0 -124. BC .977 .215 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-90:00' - 22.4 49.8 BC -1.00 -0.615E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '59' - 22.4 150. BC -1.00 -0.615E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: '-89:58' - 22.3 250. BC -1.00 -0.615E-03 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 1 -REG_CAP: 2 -REG_SCALES: -REG_QCH: -REG_CAP: 0 -REG_CAP: 0 -REG_TEXT: ' A FITS test' - 30.9 313. BC .000 1.00 -ude (rad.s) - End SphMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -1 # Forward matrix value - M1 = 1 # Forward matrix value - M2 = -1 # Forward matrix value - Form = "Diagonal" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitude (rad.s) - End SphMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End FrameSet diff --git a/ast/ast_tester/rigby.map b/ast/ast_tester/rigby.map deleted file mode 100644 index 6482149..0000000 --- a/ast/ast_tester/rigby.map +++ /dev/null @@ -1,240 +0,0 @@ - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.1 # Forward matrix value - M1 = 1 # Forward matrix value - Form = "Diagonal" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -0.0500000000000114 # Shift for axis 1 - End WinMap - End CmpMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Sft1 = -3129 # Shift for axis 1 - Sft2 = -8 # Shift for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin PermMap # Coordinate permutation - Nin = 2 # Number of input coordinates - Nout = 3 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Out1 = 1 # Output coordinate 1 = input coordinate 1 - Out2 = -1 # Output coordinate 2 = constant no. 1 - Out3 = 2 # Output coordinate 3 = input coordinate 2 - In1 = 1 # Input coordinate 1 = output coordinate 1 - In2 = 3 # Input coordinate 2 = output coordinate 3 - Nconst = 1 # Number of constants - Con1 = 232.84 # Constant number 1 - End PermMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.812968257918776 # Forward matrix value - M1 = 0.582308004080753 # Forward matrix value - M2 = 0 # Forward matrix value - M3 = -0.582308004080753 # Forward matrix value - M4 = 0.812968257918776 # Forward matrix value - M5 = 0 # Forward matrix value - M6 = 0 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = 1 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -1236.82078999603 # Shift for axis 1 - Scl1 = 0.999999999977888 # Scale factor for axis 1 - Sft2 = 586.515648677204 # Shift for axis 2 - Scl2 = 0.999999999985306 # Scale factor for axis 2 - Sft3 = 330420868230.796 # Shift for axis 3 - Scl3 = 551361.368168752 # Scale factor for axis 3 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -3.28230370472069e-05 # Forward matrix value - M1 = -1.68687502681513e-05 # Forward matrix value - M2 = -1.68687502681513e-05 # Forward matrix value - M3 = 3.28230370472069e-05 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitude (rad.s) - End SphMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.0160398354926887 # Forward matrix value - M1 = 0.967192049208341 # Forward matrix value - M2 = 0.253539471533602 # Forward matrix value - M3 = -0.0610660311421554 # Forward matrix value - M4 = 0.254046334254542 # Forward matrix value - M5 = -0.96526234770262 # Forward matrix value - M6 = -0.998004841430097 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = 0.0631374412063651 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 4.96925054084174 # Polar longitude (rad.s) - End SphMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - MapB = # Second component Mapping - Begin SlaMap # Conversion between sky coordinate systems - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Nsla = 1 # Number of conversion steps - Sla1 = "EQGAL" # J2000.0 equatorial (FK5) to galactic (IAU 1958) - End SlaMap - End CmpMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin SpecMap # Conversion between spectral coordinate systems - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Nspec = 2 # Number of conversion steps - Spec1 = "FRTOVL" # Convert frequency to rel. velocity - Spec1a = 330587960100 # Rest frequency (Hz) - Spec2 = "VLTOVR" # Convert relativistic to radio velocity - End SpecMap - MapB = # Second component Mapping - Begin ZoomMap # Zoom about the origin - Nin = 1 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Zoom = 0.001 # Zoom factor - End ZoomMap - End CmpMap - End CmpMap - MapB = # Second component Mapping - Begin PermMap # Coordinate permutation - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - Out1 = 1 # Output coordinate 1 = input coordinate 1 - Out2 = 3 # Output coordinate 2 = input coordinate 3 - In1 = 1 # Input coordinate 1 = output coordinate 1 - In2 = -1 # Input coordinate 2 = constant no. 1 - In3 = 2 # Input coordinate 3 = output coordinate 2 - Nconst = 1 # Number of constants - Con1 = -0.000391559614368643 # Constant number 1 - End PermMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap diff --git a/ast/ast_tester/rigby.simp b/ast/ast_tester/rigby.simp deleted file mode 100644 index fa78112..0000000 --- a/ast/ast_tester/rigby.simp +++ /dev/null @@ -1,201 +0,0 @@ - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin PermMap # Coordinate permutation - Nin = 2 # Number of input coordinates - Nout = 3 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Out1 = 1 # Output coordinate 1 = input coordinate 1 - Out2 = -1 # Output coordinate 2 = constant no. 1 - Out3 = 2 # Output coordinate 3 = input coordinate 2 - In1 = 1 # Input coordinate 1 = output coordinate 1 - In2 = 3 # Input coordinate 2 = output coordinate 3 - Nconst = 1 # Number of constants - Con1 = 232.84 # Constant number 1 - End PermMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 8.1296825791877598 # Forward matrix value - M1 = 0.58230800408075301 # Forward matrix value - M2 = 0 # Forward matrix value - M3 = -5.8230800408075298 # Forward matrix value - M4 = 0.81296825791877603 # Forward matrix value - M5 = 0 # Forward matrix value - M6 = 0 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = 1 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -3780.1919848386815 # Shift for axis 1 - Scl1 = 0.99999999997788802 # Scale factor for axis 1 - Sft2 = 2408.2662394170707 # Shift for axis 2 - Scl2 = 0.99999999998530598 # Scale factor for axis 2 - Sft3 = 330416457339.85065 # Shift for axis 3 - Scl3 = 551361.36816875194 # Scale factor for axis 3 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -3.2823037047206903e-05 # Forward matrix value - M1 = -1.6868750268151298e-05 # Forward matrix value - M2 = -1.6868750268151298e-05 # Forward matrix value - M3 = 3.2823037047206903e-05 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap # FITS-WCS sky projection - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - End WcsMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 0 # Polar longitude (rad.s) - End SphMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.016039835492688701 # Forward matrix value - M1 = 0.96719204920834101 # Forward matrix value - M2 = 0.25353947153360201 # Forward matrix value - M3 = -0.061066031142155398 # Forward matrix value - M4 = 0.25404633425454198 # Forward matrix value - M5 = -0.96526234770261998 # Forward matrix value - M6 = -0.99800484143009704 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = 0.063137441206365094 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin SphMap # Cartesian to Spherical mapping - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - PlrLg = 4.96925054084174 # Polar longitude (rad.s) - End SphMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - MapB = # Second component Mapping - Begin SlaMap # Conversion between sky coordinate systems - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Nsla = 1 # Number of conversion steps - Sla1 = "EQGAL" # J2000.0 equatorial (FK5) to galactic (IAU 1958) - End SlaMap - End CmpMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin SpecMap # Conversion between spectral coordinate systems - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Nspec = 2 # Number of conversion steps - Spec1 = "FRTOVL" # Convert frequency to rel. velocity - Spec1a = 330587960100 # Rest frequency (Hz) - Spec2 = "VLTOVR" # Convert relativistic to radio velocity - End SpecMap - MapB = # Second component Mapping - Begin ZoomMap # Zoom about the origin - Nin = 1 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Zoom = 0.001 # Zoom factor - End ZoomMap - End CmpMap - End CmpMap - MapB = # Second component Mapping - Begin PermMap # Coordinate permutation - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - Out1 = 1 # Output coordinate 1 = input coordinate 1 - Out2 = 3 # Output coordinate 2 = input coordinate 3 - In1 = 1 # Input coordinate 1 = output coordinate 1 - In2 = -1 # Input coordinate 2 = constant no. 1 - In3 = 2 # Input coordinate 3 = output coordinate 2 - Nconst = 1 # Number of constants - Con1 = -0.00039155961436864302 # Constant number 1 - End PermMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap diff --git a/ast/ast_tester/scp.attr b/ast/ast_tester/scp.attr deleted file mode 100644 index 54434e8..0000000 --- a/ast/ast_tester/scp.attr +++ /dev/null @@ -1 +0,0 @@ -Grid=1,labelling=int diff --git a/ast/ast_tester/scp.box b/ast/ast_tester/scp.box deleted file mode 100644 index 76f5ba8..0000000 --- a/ast/ast_tester/scp.box +++ /dev/null @@ -1 +0,0 @@ -1.0 1.0 1500.0 1300.0 diff --git a/ast/ast_tester/scp.head b/ast/ast_tester/scp.head deleted file mode 100644 index f35c6f4..0000000 --- a/ast/ast_tester/scp.head +++ /dev/null @@ -1,204 +0,0 @@ -SIMPLE = T / file does conform to FITS standard -BITPIX = 16 / number of bits per data pixel -NAXIS = 2 / number of data axes -NAXIS1 = 1787 / length of data axis 1 -NAXIS2 = 447 / length of data axis 2 -EXTEND = T / FITS dataset may contain extensions -COMMENT FITS (Flexible Image Transport System) format defined in Astronomy and -COMMENT Astrophysics Supplement Series v44/p363, v44/p371, v73/p359, v73/p365. -COMMENT Contact the NASA Science Office of Standards and Technology for the -COMMENT FITS Definition document #100 and other FITS information. -PLATENUM= '3665 ' / Plate number -EMULSION= 'IIIaJ ' / Kodak emulsion type -FILTER = 'GG395 ' / Schott glass filter type -PLTSCALE= '67.14 ' / [arcsec/mm] plate scale -FIELDNUM= '1 ' / Sky survey field number -EPOCH = 1.977780E+03 / Epoch of observation -DATE-OBS= '1977-10-11' / [yyyy-mm-dd] UT date of observation -TELESCOP= 'UKST ' / Telescope on which the plate was taken -TELETYPE= 'SCHM ' / Type of telescope -SITELAT = -5.458410576565E-01 / [radians] latitude of telescope -SITELONG= 2.601766194458E+00 / [radians] longitude of telescope -LST = '00:20 ' / [hh:mm] local sidereal time at start of obs -MJD-OBS = 4.342657300880E+04 / Modified Julian Date of observation -INSTRUME= 'SuperCOSMOS I' / Measuring machine -DATE-MES= '2000-11-04' / [yyyy-mm-dd] Date of this plate measurement -RADECSYS= 'FK5 ' / Reference frame for RA/DEC in original file -NHKLINES= 146 / Number of lines from house-keeping file -HKLIN001= 'JOB.JOBNO UKJ001' / -HKLIN002= 'JOB.DATE-MES 2000:11:04' / -HKLIN003= 'JOB.TIME 12:51:09' / -HKLIN004= 'JOB.INSTRUME SuperCOSMOS I' / -HKLIN005= 'JOB.ORIGIN Royal Observatory Edinburgh' / -HKLIN006= 'JOB.SOFTWARE /home/scosdev/v033' / -HKLIN007= 'JOB.OPERATOR ebt' / -HKLIN008= 'JOB.USER htm' / -HKLIN009= 'JOB.USERREF NONE' / -HKLIN010= 'JOB.UORIGIN ROE' / -HKLIN011= 'JOB.UCOUNTRY uk' / -HKLIN012= 'JOB.COMMENT Digital catalogue of the Sky' / -HKLIN013= 'JOB.IAM_FILE iam.srt' / -HKLIN014= 'PLATE.TELESCOP UKST' / -HKLIN015= 'PLATE.TELTYPE SCHM' / -HKLIN016= 'PLATE.PLATE 3665' / -HKLIN017= 'PLATE.MATERIAL 3mm glass' / -HKLIN018= 'PLATE.EMULSION IIIaJ' / -HKLIN019= 'PLATE.FILTER GG395' / -HKLIN020= 'PLATE.PSCALE 67.14' / -HKLIN021= 'PLATE.FIELD 1' / -HKLIN022= 'PLATE.RA_PNT 0' / -HKLIN023= 'PLATE.DEC_PNT -90' / -HKLIN024= 'PLATE.RADECSYS FK4' / -HKLIN025= 'PLATE.EQUINOX 1950' / -HKLIN026= 'PLATE.TIMESYS BESSELIAN' / -HKLIN027= 'PLATE.EPOCH 1977.78' / -HKLIN028= 'PLATE.EXPOSURE 75' / -HKLIN029= 'PLATE.UTDATE 771011' / -HKLIN030= 'PLATE.LST 0020' / -HKLIN031= 'PLATE.MJD 43426.573008796' / -HKLIN032= 'PLATE.TELLAT -0.54584105765654' / -HKLIN033= 'PLATE.TELLONG 2.6017661944583' / -HKLIN034= 'PLATE.TELHT 1145' / -HKLIN035= 'PLATE.TEMP 273.155' / -HKLIN036= 'PLATE.ATMOSP 1013.25' / -HKLIN037= 'PLATE.HUMID 0.5' / -HKLIN038= 'PLATE.WAVE 4500' / -HKLIN039= 'PLATE.TROPL 0.0065' / -HKLIN040= 'CALIBRATION.CALTYPE SPLINE' / -HKLIN041= 'CALIBRATION.STEPWEDG KPNO' / -HKLIN042= 'CALIBRATION.NSTEPS 8' / -HKLIN043= 'MEASUREMENT.ORIENTAT news' / -HKLIN044= 'MEASUREMENT.EMULPOS UP' / -HKLIN045= 'MEASUREMENT.SCANFILT 14' / -HKLIN046= 'MEASUREMENT.SOSP 552' / -HKLIN047= 'MEASUREMENT.STEPSIZE 10' / -HKLIN048= 'MEASUREMENT.SCANLEN 1152' / -HKLIN049= 'MEASUREMENT.A-XMIN 1622000' / -HKLIN050= 'MEASUREMENT.A-YMIN 1622000' / -HKLIN051= 'MEASUREMENT.A-XMAX 33878000' / -HKLIN052= 'MEASUREMENT.A-YMAX 33878000' / -HKLIN053= 'MEASUREMENT.X_PNT 17500000' / -HKLIN054= 'MEASUREMENT.Y_PNT 18000000' / -HKLIN055= 'ANALYSIS.NPARAMS 32' / -HKLIN056= 'ANALYSIS.AREACUT 8' / -HKLIN057= 'ANALYSIS.AP-PARAM 1.07' / -HKLIN058= 'DEBLEND.DB-PARAM 1.05' / -HKLIN059= 'DEBLEND.DB-AMIN 16' / -HKLIN060= 'DEBLEND.DB-AMAX 100000' / -HKLIN061= 'DEBLEND.DB-ACUT 8' / -HKLIN062= 'DEBLEND.DB-LEVEL 16' / -HKLIN063= 'DEBLEND.SELECT PARENT+CHILD' / -HKLIN064= 'SKY.SKYSQUAR 64' / -HKLIN065= 'SKY.SKYDEFN MEDIAN' / -HKLIN066= 'SKY.SKYFILTR bdkjunk' / -HKLIN067= 'SKY.F-THRESH 8' / -HKLIN068= 'SKY.F-SCLEN 4' / -HKLIN069= 'THRESHOLDING.PCUT 10' / -HKLIN070= 'IAMQC.AREAMIN 8' / -HKLIN071= 'IAMQC.AREAMAX 77346' / -HKLIN072= 'IAMQC.MINMAG -30515' / -HKLIN073= 'IAMQC.MAXMAG -17954' / -HKLIN074= 'IAMQC.MINELL 0.0004156232' / -HKLIN075= 'IAMQC.MAXELL 1' / -HKLIN076= 'IAMQC.MODELL 0.14' / -HKLIN077= 'IAMQC.MODOR 91' / -HKLIN078= 'IAMQC.MIDELL 0.21' / -HKLIN079= 'IAMQC.MIDOR 93' / -HKLIN080= 'IAMQC.MEANELL 0.2467037' / -HKLIN081= 'IAMQC.MEANOR 91.63474' / -HKLIN082= 'IAMQC.NUMOBJ 556985' / -HKLIN083= 'IAMQC.PARENTS 486656' / -HKLIN084= 'IAMQC.RANGING TRUE' / -HKLIN085= 'IAMQC.LANE_1 15571' / -HKLIN086= 'IAMQC.LANE_2 33207' / -HKLIN087= 'IAMQC.LANE_3 51478' / -HKLIN088= 'IAMQC.LANE_4 69944' / -HKLIN089= 'IAMQC.LANE_5 89236' / -HKLIN090= 'IAMQC.LANE_6 108416' / -HKLIN091= 'IAMQC.LANE_7 127481' / -HKLIN092= 'IAMQC.LANE_8 146699' / -HKLIN093= 'IAMQC.LANE_9 166380' / -HKLIN094= 'IAMQC.LANE_10 186126' / -HKLIN095= 'IAMQC.LANE_11 205946' / -HKLIN096= 'IAMQC.LANE_12 225915' / -HKLIN097= 'IAMQC.LANE_13 245926' / -HKLIN098= 'IAMQC.LANE_14 266574' / -HKLIN099= 'IAMQC.LANE_15 287150' / -HKLIN100= 'IAMQC.LANE_16 308087' / -HKLIN101= 'IAMQC.LANE_17 328830' / -HKLIN102= 'IAMQC.LANE_18 350253' / -HKLIN103= 'IAMQC.LANE_19 370738' / -HKLIN104= 'IAMQC.LANE_20 391722' / -HKLIN105= 'IAMQC.LANE_21 412801' / -HKLIN106= 'IAMQC.LANE_22 433795' / -HKLIN107= 'IAMQC.LANE_23 454383' / -HKLIN108= 'IAMQC.LANE_24 474711' / -HKLIN109= 'IAMQC.LANE_25 495108' / -HKLIN110= 'IAMQC.LANE_26 515755' / -HKLIN111= 'IAMQC.LANE_27 536499' / -HKLIN112= 'IAMQC.LANE_28 556985' / -HKLIN113= 'XYTORADEC.STARCAT /sdata/scos/refcats/tycho2.FIT' / -HKLIN114= 'XYTORADEC.BRIGHTLIM 9' / -HKLIN115= 'XYTORADEC.C-EQUIN 2000' / -HKLIN116= 'XYTORADEC.C-EQTSYS JULIAN' / -HKLIN117= 'XYTORADEC.C-EPOCH 2000' / -HKLIN118= 'XYTORADEC.C-EPTSYS JULIAN' / -HKLIN119= 'XYTORADEC.R-EQUIN 2000' / -HKLIN120= 'XYTORADEC.R-TSYS JULIAN' / -HKLIN121= 'XYTORADEC.MAXITER 5000' / -HKLIN122= 'XYTORADEC.RCRITINI 500000' / -HKLIN123= 'XYTORADEC.RCRITABS 50000' / -HKLIN124= 'XYTORADEC.RCRITREL 1' / -HKLIN125= 'XYTORADEC.RCRITFIN 3' / -HKLIN126= 'XYTORADEC.HARDCOPY /scos1/scos/UKJ001/UKJ001.ps' / -HKLIN127= 'XYTORADEC.REFSMULT 5' / -HKLIN128= 'XYTORADEC.RESDMULT 1000' / -HKLIN129= 'XYTORADEC.RACOL RA' / -HKLIN130= 'XYTORADEC.DECOL DEC' / -HKLIN131= 'XYTORADEC.RAPMCOL PMRA' / -HKLIN132= 'XYTORADEC.DECPMCOL PMDE' / -HKLIN133= 'XYTORADEC.PLXCOL NONE' / -HKLIN134= 'XYTORADEC.RVCOL NONE' / -HKLIN135= 'XYTORADEC.MAGCOL VT' / -HKLIN136= 'XYTORADEC.STARSC 2374' / -HKLIN137= 'XYTORADEC.STARSU 1727' / -HKLIN138= 'XYTORADEC.COEFFS_1 17.640343856524' / -HKLIN139= 'XYTORADEC.COEFFS_2 -260.44151995641' / -HKLIN140= 'XYTORADEC.COEFFS_3 -163.09155572601' / -HKLIN141= 'XYTORADEC.COEFFS_4 17.504230442205' / -HKLIN142= 'XYTORADEC.COEFFS_5 -163.08676953832' / -HKLIN143= 'XYTORADEC.COEFFS_6 260.48817907668' / -HKLIN144= 'XYTORADEC.DISTR -0.33333333333333' / -HKLIN145= 'XYTORADEC.RA_PNT 0.54924996662137' / -HKLIN146= 'XYTORADEC.DEC_PNT -1.5684931501781' / -HISTORY = 'SuperCOSMOS image analysis and mapping mode (IAM and MM)' / -HISTORY = 'data written by xydcomp_ss.' / -HISTORY = 'Any questions/comments/suggestions/bug reports should be sent' / -HISTORY = 'to N.Hambly@roe.ac.uk' / -ASTSIGX = 3.700000E-01 / [arcsec] std. dev. of astrometric fit in X -ASTSIGY = 3.800000E-01 / [arcsec] std. dev. of astrometric fit in Y -CRVAL1 = 0.000000000000E+00 / Axis 1 reference value -CRPIX1 = 8.936318379289E+02 / Axis 1 pixel value -CTYPE1 = 'RA---TAN' / Quantity represented by axis 1 -CRVAL2 = -9.000000018364E+01 / Axis 2 reference value -CRPIX2 = 2.238380193875E+02 / Axis 2 pixel value -CTYPE2 = 'DEC--TAN' / Quantity represented by axis 2 -CD1_1 = -1.864642639667E-04 / Co-ordinate transformation matrix -CD1_2 = -9.188369023766E-07 / Co-ordinate transformation matrix -CD2_1 = -1.038232462415E-06 / Co-ordinate transformation matrix -CD2_2 = 1.866269837741E-04 / Co-ordinate transformation matrix -PC001001= 9.999878591881E-01 / DEPRECATED - Axis rotation matrix -PC001002= 4.927623810613E-03 / DEPRECATED - Axis rotation matrix -PC002001= -5.563056187788E-03 / DEPRECATED - Axis rotation matrix -PC002002= 9.999845260832E-01 / DEPRECATED - Axis rotation matrix -CROTA2 = 3.005532298491E-01 / DEPRECATED - rotation of axis 2 -EQUINOX = 2.000000E+03 / Julian reference frame equinox -DATATYPE= 'INTEGER*2' / Type of data -DATUNITS= 'DENSITY ' / Units: transmission, density or intensity -XPIXELSZ= 9.997114974000E+00 / [microns] X pixel size -YPIXELSZ= 1.000000000000E+01 / [microns] Y pixel size -OBJCTRA = ' 0 0 0.000' / Centre Right Ascension (J2000) -OBJCTDEC= '-90 0 0.00' / Centre Declination (J2000) -OBJCTX = 1.636863183793E+04 / [pixels] Centre X on plate -OBJCTY = 1.474083801939E+04 / [pixels] Centre Y on plate -END diff --git a/ast/ast_tester/serpens.attr b/ast/ast_tester/serpens.attr deleted file mode 100644 index 496403c..0000000 --- a/ast/ast_tester/serpens.attr +++ /dev/null @@ -1 +0,0 @@ -border=1 diff --git a/ast/ast_tester/serpens.box b/ast/ast_tester/serpens.box deleted file mode 100644 index f9576e8..0000000 --- a/ast/ast_tester/serpens.box +++ /dev/null @@ -1 +0,0 @@ -0.5 0.5 150.5 120.5 diff --git a/ast/ast_tester/serpens.head b/ast/ast_tester/serpens.head deleted file mode 100644 index 0775604..0000000 --- a/ast/ast_tester/serpens.head +++ /dev/null @@ -1,160 +0,0 @@ -NAXIS1 = 150 / length of data axis 1 -NAXIS2 = 120 / length of data axis 2 -DATE-OBS= '2007-04-30T15:13:53.717'/ Date of observation -CRPIX1 = 75.910204 / Reference pixel on axis 1 -CRPIX2 = 60.359184 / Reference pixel on axis 2 -CRVAL1 = 1.220833333 / Value at ref. pixel on axis 1 -CRVAL2 = 277.5004167 / Value at ref. pixel on axis 2 -CTYPE1 = 'DEC--TAN' / Type of co-ordinate on axis 1 -CTYPE2 = 'RA---TAN' / Type of co-ordinate on axis 2 -CD1_1 = -0.001831773954 / Transformation matrix element -CD1_2 = -8.541702226E-4 / Transformation matrix element -CD2_1 = 0.0008541702226 / Transformation matrix element -CD2_2 = -0.001831773954 / Transformation matrix element -RADECSYS= 'FK5 ' / Reference frame for RA/DEC values -EQUINOX = 2000.0 / Epoch of reference equinox -DUT1 = -1.145603703E-6 / [d] UT1-UTC correction - - - - - - - - - - - - - - - - - - - - - - - - - - -EXP_TIME= 41.97277069 / [s] Median MAKECUBE exposure time -EFF_TIME= 11.13561535 / [s] Median MAKECUBE effective integration time -PROVCNT = 1 / Number of unique OBSIDs -OBS00001= 'acsis_98_20070430T151247'/ OBSID from component observation - - -HISTORY History structure created 2007 Apr 30 05:52:50.656 -HISTORY Update mode: NORMAL Current record: 8 - -HISTORY 1: 2007 Apr 30 05:52:53.959 - MAKECUBE (SMURF V0.2.2) -HISTORY User: operator Host: kolea Width: 72 -HISTORY Dataset: /jcmtdata/reduced/acsis/20070430/a20070430_00098_01_cube -HISTORY Parameters: AUTOGRID=TRUE CROTA=115 DETECTORS=! -HISTORY FBL=[4.8435931408225,0.024206080047514] -HISTORY FBR=[4.8456657339925,0.019762137343435] -HISTORY FLBND=[4.8407875332009,0.018441755319268,-426.75185625342] -HISTORY FUBND=[4.8456891772589,0.024229519070352,440.3284772626] -HISTORY FTL=[4.8408109789176,0.022909013956528] -HISTORY FTR=[4.8428837776034,0.018465194476559] GENVAR='tsys' -HISTORY IN=@^/jcmtdata/reduced/acsis/20070430/oractemppV8I2A.lis -HISTORY INWEIGHT=TRUE LBOUND=[-70,-41,-1024] OUT=@a20070430_00098_01_cube -HISTORY OUTCAT=! PIXSIZE=7.2761 MSG_FILTER='NORM' REFLAT='1:13:15' -HISTORY REFLON='18:30:00.1' SPARSE=FALSE SPECBOUNDS='-426.5402 440.1168' -HISTORY TRIM=TRUE WEIGHTS=FALSE SPREAD='nearest' SYSTEM='TRACKING' -HISTORY UBOUND=[69,46,1023] USEDETPOS=TRUE -HISTORY Software: /star/bin/smurf/smurf_mon - -HISTORY 2: 2007 Apr 30 05:52:59.952 - NDFCOPY (KAPPA 1.7-2) -HISTORY User: operator Host: kolea Width: 72 -HISTORY Dataset: /jcmtdata/reduced/acsis/20070430/a20070430_00098_01_em -HISTORY Parameters: IN=@a20070430_00098_01_cube(,,-820:819) LIKE=! -HISTORY OUT=@a20070430_00098_01_em TITLE=! TRIM=FALSE -HISTORY Software: /star/bin/kappa/ndfpack_mon - -HISTORY 3: 2007 Apr 30 05:53:04.009 - MFITTREND (KAPPA 1.7-2) -HISTORY User: operator Host: kolea Width: 72 -HISTORY Dataset: /jcmtdata/reduced/acsis/20070430/a20070430_00098_01_bl -HISTORY Parameters: ARANGES=[-820,-56,47,819] AUTO=TRUE AXIS=@3 CLIP=[2,2,2.5,3] -HISTORY IN=@a20070430_00098_01_em MODIFYIN=FALSE ORDER=0 -HISTORY OUT=@a20070430_00098_01_bl RMSCLIP=! SECTION='-70:69,-41:46,' -HISTORY SUBTRACT=TRUE TITLE=! VARIANCE=TRUE -HISTORY Software: /star/bin/kappa/kappa_mon - -HISTORY 4: 2007 Apr 30 05:53:17.048 - NDFCOPY (KAPPA 1.7-2) -HISTORY User: operator Host: kolea Width: 72 -HISTORY Dataset: /jcmtdata/reduced/acsis/20070430/ga20070430_98 -HISTORY Parameters: IN=@a20070430_00098_01_bl LIKE=! OUT=@ga20070430_98 -HISTORY TITLE='ga20070430_98' TRIM=FALSE -HISTORY Software: /star/bin/kappa/ndfpack_mon - -HISTORY 5: 2007 Apr 30 06:40:02.994 - WCSMOSAIC (KAPPA 1.7-2) -HISTORY User: operator Host: kolea Width: 72 -HISTORY Dataset: /jcmtdata/reduced/acsis/20070430/oractemppLv7wv -HISTORY Parameters: ACC=0.05 GENVAR=FALSE ILEVEL=2 -HISTORY IN=@^/jcmtdata/reduced/acsis/20070430/oractempyopUhZ.lis LBND=! -HISTORY LBOUND=[-70,-43,-820] MAXPIX=1000 METHOD='nearest' -HISTORY OUT=@/jcmtdata/reduced/acsis/20070430/oractemppLv7wv REF=! UBND=! -HISTORY UBOUND=[69,46,819] VARIANCE=TRUE WLIM=1E-10 -HISTORY Software: /star/bin/kappa/kappa_mon - -HISTORY 6: 2007 Apr 30 06:40:05.801 - NDFCOPY (KAPPA 1.7-2) -HISTORY User: operator Host: kolea Width: 72 -HISTORY Dataset: /jcmtdata/reduced/acsis/20070430/ga20070430_98 -HISTORY Parameters: IN=@/jcmtdata/reduced/acsis/20070430/oractemppLv7wv LIKE=! -HISTORY OUT=@ga20070430_98 TITLE=! TRIM=FALSE -HISTORY Software: /star/bin/kappa/ndfpack_mon - -HISTORY 7: 2007 May 10 10:42:40.627 - WCSMOSAIC (KAPPA 1.7-3) -HISTORY User: jbuckle Host: scubadev Width: 72 -HISTORY Dataset: /home/jbuckle/data/serpens_cube -HISTORY Parameters: ACC=0.05 GENVAR=FALSE ILEVEL=2 -HISTORY IN=@ga20070430_98,ga20070502_63_1 LBND=! LBOUND=[-77,-52,-820] -HISTORY MAXPIX=1000 METHOD='nearest' OUT=@serpens_cube REF=! -HISTORY UBOUND=[77,54,819] VARIANCE=TRUE WLIM=1E-10 -HISTORY Software: /star/bin/kappa/wcsmosaic - -HISTORY 8: 2007 May 17 12:04:41.724 - NDFCOPY (KAPPA 1.7-2) -HISTORY User: dsb Host: localhost.localdomain Width: 72 -HISTORY Dataset: /stardev/jaccvs/jcmt/scuba2/soft/smurf/makecube/jane -HISTORY Parameters: IN=@serpens_cube(~150,~120,0) LIKE=! OUT=@jane TITLE=! -HISTORY TRIM=TRUE TRIMWCS=TRUE USEAXIS=! -HISTORY Software: /stardev/cvs/star/bin/kappa/ndfcopy -END -XTENSION= 'IMAGE ' / IMAGE extension -BITPIX = -32 / number of bits per data pixel -NAXIS = 2 / number of data axes -NAXIS1 = 150 / length of data axis 1 -NAXIS2 = 120 / length of data axis 2 -PCOUNT = 0 / required keyword; must = 0 -GCOUNT = 1 / required keyword; must = 1 -LBOUND1 = -74 / Pixel origin along axis 1 -LBOUND2 = -58 / Pixel origin along axis 2 -OBJECT = 'ga20070430_98' / Title of the dataset -LABEL = 'T%s60+%v30+A%^50+%<20+*%+ corrected antenna ...'/ Label of the pri -BUNIT = 'K ' / Units of the primary array -DATE = '2007-05-17T11:05:09'/ file creation date (YYYY-MM-DDThh:mm:ss UT) -ORIGIN = 'Starlink Project, U.K.'/ Origin of this FITS file -BSCALE = 1.0 / True_value = BSCALE * FITS_value + BZERO -BZERO = 0.0 / True_value = BSCALE * FITS_value + BZERO -HDUCLAS1= 'NDF ' / Starlink NDF (hierarchical n-dim format) -HDUCLAS2= 'VARIANCE' / Array component subclass -EXTNAME = 'VARIANCE' / Array component -HDSTYPE = 'NDF ' / HDS data type of the component - -CRPIX1 = 75.910204 / Reference pixel on axis 1 -CRPIX2 = 60.359184 / Reference pixel on axis 2 -CRVAL1 = 1.220833333 / Value at ref. pixel on axis 1 -CRVAL2 = 277.5004167 / Value at ref. pixel on axis 2 -CTYPE1 = 'DEC--TAN' / Type of co-ordinate on axis 1 -CTYPE2 = 'RA---TAN' / Type of co-ordinate on axis 2 -CD1_1 = -0.001831773954 / Transformation matrix element -CD1_2 = -8.541702226E-4 / Transformation matrix element -CD2_1 = 0.0008541702226 / Transformation matrix element -CD2_2 = -0.001831773954 / Transformation matrix element -RADECSYS= 'FK5 ' / Reference frame for RA/DEC values -EQUINOX = 2000.0 / Epoch of reference equinox -DATE-OBS= '2007-04-30T15:13:53.717'/ Date of observation -END diff --git a/ast/ast_tester/simplify.f b/ast/ast_tester/simplify.f deleted file mode 100644 index 063ebd1..0000000 --- a/ast/ast_tester/simplify.f +++ /dev/null @@ -1,123 +0,0 @@ - PROGRAM SIMPLIFY - -* Usage: -* simplify - -* Description: -* Reads a Mapping from "in file" (as an AST dump), and writes out the -* simplified Mapping to "out file". - -* Parameters: -* in file -* A text file containing an AST dump of a Mapping. -* out file -* The output file. Contains an AST dump of the simplified Mapping -* on exit. - - - IMPLICIT NONE - INCLUDE 'AST_PAR' - EXTERNAL SOURCE, SINK - - INTEGER STATUS, OBJECT, IARGC, CHAN, CHR_LEN, OC, SMAP - CHARACTER FILE*80, OFILE*80, LINE*255 - - STATUS = 0 -* -* Check command line arguments have been supplied. -* - IF( IARGC() .LT. 2 ) THEN - WRITE(*,*) 'Usage: simplify ' - RETURN - END IF - -* -* Open the name of the input text file. -* - CALL GETARG( 1, FILE ) - -* Attempt to read an object from the text file as an AST dump. - OPEN( UNIT=10, FILE=FILE, STATUS='OLD' ) - CHAN = AST_CHANNEL( SOURCE, AST_NULL, ' ', STATUS ) - OBJECT = AST_READ( CHAN, STATUS ) - CALL AST_ANNUL( CHAN, STATUS ) - CLOSE( 10 ) - -* -* Abort if no object was read. -* - IF( OBJECT .EQ. AST__NULL ) THEN - WRITE(*,*) 'simplify: no Mapping could be read from ', - : file( : chr_len( file ) ) - RETURN - -* -* Otherwise write out the simplified Mapping -* - ELSE - CALL GETARG( 2, OFILE ) - CALL DELETEFILE( OFILE ) - - SMAP = AST_SIMPLIFY( OBJECT, STATUS ) - - OPEN( UNIT=10, FILE=OFILE, STATUS='NEW' ) - CHAN = AST_CHANNEL( AST_NULL, SINK, ' ', STATUS ) - IF( AST_WRITE( CHAN, SMAP, STATUS ) .NE. 1 ) THEN - WRITE(*,*) 'simplify: Simplified Mapping read from ', - : file( : chr_len( file ) ),' could not be '// - : 'written out.' - END IF - CALL AST_ANNUL( CHAN, STATUS ) - CALL AST_ANNUL( SMAP, STATUS ) - CLOSE( 10 ) - END IF - - - END - - -* -* Delete a file if it exists. -* - SUBROUTINE DELETEFILE( FILNAM ) - IMPLICIT NONE - - CHARACTER FILNAM*(*) - LOGICAL EXISTS - - INQUIRE ( FILE = FILNAM, - : EXIST = EXISTS ) - - IF( EXISTS ) THEN - OPEN ( UNIT=10, FILE=FILNAM, STATUS='OLD' ) - CLOSE ( 10, STATUS='DELETE' ) - END IF - - END - - -* -* SOURCE FUNCTION FOR AST_CHANNEL. -* - SUBROUTINE SOURCE( STATUS ) - IMPLICIT NONE - INTEGER STATUS - CHARACTER BUFFER*200 - READ( 10, '(A)', END=99 ) BUFFER - CALL AST_PUTLINE( BUFFER, LEN( BUFFER ), STATUS ) - RETURN - 99 CALL AST_PUTLINE( BUFFER, -1, STATUS ) - END - -* -* SINK FUNCTION FOR AST_CHANNEL. -* - SUBROUTINE SINK( STATUS ) - IMPLICIT NONE - INTEGER STATUS, L - CHARACTER BUFFER*200 - - CALL AST_GETLINE( BUFFER, L, STATUS ) - IF( L .GT. 0 ) WRITE( 10, '(A)' ) BUFFER( : L ) - - END diff --git a/ast/ast_tester/sip.fits-wcs b/ast/ast_tester/sip.fits-wcs deleted file mode 100644 index 92d29ed..0000000 --- a/ast/ast_tester/sip.fits-wcs +++ /dev/null @@ -1,289 +0,0 @@ -SIMPLE = T / Fits standard -BITPIX = -32 / FOUR-BYTE SINGLE PRECISION FLOATING POINT -NAXIS = 2 / STANDARD FITS FORMAT -NAXIS1 = 256 / STANDARD FITS FORMAT -NAXIS2 = 256 / STANDARD FITS FORMAT -ORIGIN = 'Spitzer Science Center' / Organization generating this FITS file -CREATOR = 'S16.1.0 ' / SW version used to create this FITS file -TELESCOP= 'Spitzer ' / SPITZER Space Telescope -INSTRUME= 'IRAC ' / SPITZER Space Telescope instrument ID -CHNLNUM = 1 / 1 digit instrument channel number -EXPTYPE = 'sci ' / Exposure Type -REQTYPE = 'AOR ' / Request type (AOR, IER, or SER) -AOT_TYPE= 'IracMap ' / Observation template type -AORLABEL= '05cs-IRAC-2' / AOR Label -FOVID = 67 / Field of View ID -FOVNAME = 'IRAC_Center_of_3.6&5.8umArray' / Field of View Name - - / PROPOSAL INFORMATION - -OBSRVR = 'Ben Sugerman' / Observer Name (Last, First) -OBSRVRID= 14621 / Observer ID of Principal Investigator -PROCYCL = 6 / Proposal Cycle -PROGID = 30494 / Program ID -PROTITLE= 'Supernovae and the Origin of Dust in Galaxies: Follow-Up Observation' -PROGCAT = 30 / Program Category - - / TIME AND EXPOSURE INFORMATION - -DATE_OBS= '2007-06-29T03:15:33.555' / Date & time at DCE start -MJD_OBS = 54280.136 / [days] MJD at DCE start (,JD-2400000.5) -UTCS_OBS= 2.3635893E+8 / [sec] J2000 ephem. time at DCE start -SCLK_OBS= 8.675543E+8 / [sec] SCLK time (since 1/1/1980) at DCE start -SAMPTIME= 0.2 / [sec] Sample integration time -FRAMTIME= 12.0 / [sec] Time spent integrating (whole array) -COMMENT Photons in Well = Flux[photons/sec/pixel] * FRAMTIME -EXPTIME = 10.4 / [sec] Effective integration time per pixel -COMMENT DN per pixel = Flux[photons/sec/pixel] / GAIN * EXPTIME -INTRFDLY= 8.0 / [sec] Inter Frame Delay Time -AINTBEG = 107646.2 / [Secs since IRAC turn-on] Time of integ. start -ATIMEEND= 107658.16 / [Secs since IRAC turn-on] Time of integ. end -AFOWLNUM= 8 / Fowler number -AWAITPER= 44 / [0.2 sec] Wait period -ANUMREPS= 1 / Number of repeat integrations -AREADMOD= 0 / Full (0) or subarray (1) -HDRMODE = F / DCE taken in High Dynamic Range mode -ABARREL = 3 / Barrel shift -APEDSIG = 0 / 0=Normal, 1=Pedestal, 2=Signal - - / TARGET AND POINTING INFORMATION - -OBJECT = 'SN 2005cs' / Target Name -OBJTYPE = 'TargetFixedSingle' / Object Type -CRVAL1 = 202.48232 / [deg] RA at CRPIX1,CRPIX2 (using Pointing Recon -CRVAL2 = 47.175119 / [deg] DEC at CRPIX1,CRPIX2 (using Pointing Reco -RA_HMS = '13h29m55.8s' / [hh:mm:ss.s] CRVAL1 as sexagesimal -DEC_DMS = '+47d10m30s' / [dd:mm:ss] CRVAL2 as sexagesimal -RADESYS = 'ICRS ' / International Celestial Reference System -CD1_1 = 0.00024975688 / Corrected CD matrix element with Pointing Recon -CD1_2 = 0.00023017781 / Corrected CD matrix element with Pointing Recon -CD2_1 = 0.00023042852 / Corrected CD matrix element with Pointing Recon -CD2_2 = -2.4996577E-4 / Corrected CD matrix element with Pointing Reco -CTYPE1 = 'RA---TAN-SIP' / RA---TAN with distortion in pixel space -CTYPE2 = 'DEC--TAN-SIP' / DEC--TAN with distortion in pixel space -CRPIX1 = 128.0 / Reference pixel along axis 1 -CRPIX2 = 128.0 / Reference pixel along axis 2 -MJD-OBS = 51544.499 / Modified Julian Date of observation -DATE-OBS= '2000-01-01T11:58:55.816' / Date of observation -PXSCAL1 = -1.2233412 / [arcsec/pix] Scale for axis 1 at CRPIX1,CRPIX2 -PXSCAL2 = 1.2232836 / [arcsec/pix] Scale for axis 2 at CRPIX1,CRPIX2 -CRDER1 = 4.0250976E-5 / [deg] Uncertainty in CRVAL1 -CRDER2 = 3.4274613E-5 / [deg] Uncertainty in CRVAL2 -UNCRTPA = 0.00037878784 / [deg] Uncertainty in position angle -CSDRADEC= 4.7597178E-7 / [deg] Costandard deviation in RA and Dec -SIGRA = 0.033948714 / [arcsec] RMS dispersion of RA over DCE -SIGDEC = 0.063768266 / [arcsec] RMS dispersion of DEC over DCE -SIGPA = 1.3646427 / [arcsec] RMS dispersion of PA over DCE -PA = 137.35998 / [deg] Position angle of axis 2 (E of N) (was OR -RA_RQST = 202.48212 / [deg] Requested RA at CRPIX1, CRPIX2 -DEC_RQST= 47.175079 / [deg] Requested Dec at CRPIX1, CRPIX2 -PM_RA = 0.0 / [arcsec/yr] Proper Motion in RA (J2000) -PM_DEC = 0.0 / [arcsec/yr] Proper Motion in Dec (J200) -RMS_JIT = 0.007683034 / [arcsec] RMS jitter during DCE -RMS_JITY= 0.0051507034 / [arcsec] RMS jitter during DCE along Y -RMS_JITZ= 0.0057008128 / [arcsec] RMS jitter during DCE along Z -SIG_JTYZ= 0.0023780641 / [arcsec] Costadard deviation of jitter in YZ -PTGDIFF = 0.52510652 / [arcsec] Offset btwn actual and rqsted pntng -PTGDIFFX= 0.46966798 / [pixels] rqsted - actual pntng along axis 1 -PTGDIFFY= -0.2352852 / [pixels] rqsted - actual pntng along axis 2 -RA_REF = 202.47237 / [deg] Commanded RA (J2000) of ref. position -DEC_REF = 47.1745 / [deg] Commanded Dec (J2000) of ref. position -USEDBPHF= T / T if Boresight Pointing History File was used -BPHFNAME= 'SBPHF.0867542400.031.pntg' / Boresight Pointing History Filename -FOVVERSN= 'BodyFrames_FTU_14a.xls' / FOV/BodyFrames file version used -RECONFOV= 'IRAC_Center_of_3.6umArray' / Reconstructed Field of View -RARFND = 202.48232 / [deg] Refined RA -DECRFND = 47.175121 / [deg] Refined DEC -CT2RFND = 137.35905 / [deg] Refined CROT2 -ERARFND = 2.332304E-6 / [deg] Error in RARFND value -EDECRFND= 2.332411E-6 / [deg] Error in DECRFND value -ECT2RFND= 0.00054069905 / [deg] Error in CT2RFND value -NASTROM = 12 / Astrometric sources for absolute refinement -ORIG_RA = 202.48206 / [deg] Original RA from raw BPHF (without pointi -ORIG_DEC= 47.175072 / [deg] Original Dec from raw BPHF (without point -ORIGCD11= 0.00024975633 / [deg/pix] Original CD1_1 element (without point -ORIGCD12= 0.00023017843 / [deg/pix] Original CD1_2 element (without point -ORIGCD21= 0.00023042914 / [deg/pix] Original CD2_1 element (without point -ORIGCD22= -2.499652E-4 / [deg/pix] Original CD2_2 element (without point - - - - / DISTORTION KEYWORDS - -A_ORDER = 3 / polynomial order, axis 1, detector to sky -A_0_2 = 2.9656E-6 / distortion coefficient -A_0_3 = 3.7746E-9 / distortion coefficient -A_1_1 = 2.1886E-5 / distortion coefficient -A_1_2 = -1.6847E-7 / distortion coefficient -A_2_0 = -2.3863E-5 / distortion coefficient -A_2_1 = -8.561E-9 / distortion coefficient -A_3_0 = -1.4172E-7 / distortion coefficient -A_DMAX = 1.394 / [pixel] maximum correction -B_ORDER = 3 / polynomial order, axis 2, detector to sky -B_0_2 = 2.31E-5 / distortion coefficient -B_0_3 = -1.6168E-7 / distortion coefficient -B_1_1 = -2.4386E-5 / distortion coefficient -B_1_2 = -5.7813E-9 / distortion coefficient -B_2_0 = 2.1197E-6 / distortion coefficient -B_2_1 = -1.6583E-7 / distortion coefficient -B_3_0 = -2.0249E-8 / distortion coefficient -B_DMAX = 1.501 / [pixel] maximum correction -AP_ORDER= 3 / polynomial order, axis 1, sky to detector -AP_0_1 = -6.4275E-7 / distortion coefficient -AP_0_2 = -2.9425E-6 / distortion coefficient -AP_0_3 = -3.582E-9 / distortion coefficient -AP_1_0 = -1.4897E-5 / distortion coefficient -AP_1_1 = -2.225E-5 / distortion coefficient -AP_1_2 = 1.7195E-7 / distortion coefficient -AP_2_0 = 2.4146E-5 / distortion coefficient -AP_2_1 = 6.709E-9 / distortion coefficient -AP_3_0 = 1.4492E-7 / distortion coefficient -BP_ORDER= 3 / polynomial order, axis 2, sky to detector -BP_0_1 = -1.6588E-5 / distortion coefficient -BP_0_2 = -2.3424E-5 / distortion coefficient -BP_0_3 = 1.651E-7 / distortion coefficient -BP_1_0 = -2.6783E-6 / distortion coefficient -BP_1_1 = 2.4753E-5 / distortion coefficient -BP_1_2 = 3.8917E-9 / distortion coefficient -BP_2_0 = -2.151E-6 / distortion coefficient -BP_2_1 = 1.7E-7 / distortion coefficient -BP_3_0 = 2.0482E-8 / distortion coefficient - - / PHOTOMETRY - -BUNIT = 'MJy/sr ' / Units of image data -FLUXCONV= 0.1088 / Flux Conv. factor (MJy/sr per DN/sec) -GAIN = 3.3 / e/DN conversion -RONOISE = 9.4 / [Electrons] Readout Noise from Array -ZODY_EST= 0.05291139 / [MJy/sr] Zodiacal Background Estimate -ISM_EST = 0.003677277 / [MJy/sr] Interstellar Medium Estimate -CIB_EST = 0.0 / [MJy/sr] Cosmic Infrared Background Estimate -SKYDRKZB= 0.044533 / [MJy/sr] Zodiacal Background Est of subracted s -SKYDKMED= 0.039081 / [MJy/sr] Median of Subtracted Skydark -SKDKFDLY= 11.554 / [sec] Average Frame Delay Time of Skydark -SKDKIDLY= 11.554 / [sec] Average Immediate Delay Time of Skydark - - / GENERAL MAPPING KEYWORDS - -DITHPOS = 2 / Current dither position - - / IRAC MAPPING KEYWORDS - -READMODE= 'FULL ' / Readout mode -DITHSCAL= 'medium ' / Dither scale (small, medium, large) - - / INSTRUMENT TELEMETRY DATA - -ASHTCON = 2 / Shutter condition (1:closed, 2: open) -AWEASIDE= 0 / WEA side in use (0:B, 1:A) -ACTXSTAT= 0 / Cmded transcal status -ATXSTAT = 0 / transcal status -ACFLSTAT= 0 / Cmded floodcal status -AFLSTAT = 0 / floodcal status -AVRSTUCC= -3.5 / [Volts] Cmded VRSTUC Bias -AVRSTBEG= -3.5114367 / [Volts] VRSTUC Bias at start integration -AVDETC = -2.75 / [Volts] Cmded VDET Bias -AVDETBEG= -2.7585216 / [Volts] VDET Bias at start of integration -AVGG1C = -3.65 / [Volts] Cmded VGG1 Bias -AVGG1BEG= -3.2078801 / [Volts] VGG1 Bias at start of integration -AVDDUCC = -3 / [Volts] Cmded VDDUC Bias -AVDDUBEG= -3 / [Volts] VDDUC Bias at start integration -AVGGCLC = 1 / [Volts] Cmnded VGGCL clock rail voltage -AVGGCBEG= 1 / [Volts] VGGCL clock rail voltage -AHTRIBEG= 204.49722 / [uAmps] Heater current at start of integ -AHTRVBEG= 2.3936886 / [Volts] Heater Voltage at start integ. -AFPAT2B = 15.022535 / [Deg_K] FPA Temp sensor #2 at start integ. -AFPAT2BT= 107644.61 / [Sec] FPA Temp sensor #2 time tag -AFPAT2E = 15.022535 / [Deg_K] FPA temp sensor #2, end integ. -AFPAT2ET= 107644.61 / [Sec] FPA temp sensor #2 time tag -ACTENDT = 20.376773 / [Deg_C] C&T board thermistor -AFPECTE = 18.3055 / [Deg_C] FPE control board thermistor -AFPEATE = 21.814696 / [Deg_C] FPE analog board thermistor -ASHTEMPE= 21.504564 / [Deg_C] Shutter board thermistor -ATCTEMPE= 22.662835 / [Deg_C] Temp. controller board thermistor -ACETEMPE= 20.285331 / [Deg_C] Calib. electronics board thermistor -APDTEMPE= 20.590139 / [Deg_C] PDU board thermistor -ACATMP1E= 1.3181374 / [Deg_K] CA Temp, end integration for temp1 -ACATMP2E= 1.3011689 / [Deg_K] CA Temp, end integration for temp2 -ACATMP3E= 1.3331941 / [Deg_K] CA Temp, end integration for temp3 -ACATMP4E= 1.3299368 / [Deg_K] CA Temp, end integration for temp4 -ACATMP5E= 1.3280274 / [Deg_K] CA Temp, end integration for temp5 -ACATMP6E= 1.32662 / [Deg_K] CA Temp, end integration for temp6 -ACATMP7E= 1.3253879 / [Deg_K] CA Temp, end integration for temp7 -ACATMP8E= 1.3185339 / [Deg_K] CA Temp, end integration for temp8 - - / DATA FLOW KEYWORDS - -ORIGIN0 = 'JPL_FOS ' / Site where RAW FITS file was written -CREATOR0= 'J5.3 ' / SW system that created RAW FITS -DATE = '2007-07-10T04:40:23' / [YYYY-MM-DDThh:mm:ss UTC] file creation date -AORKEY = 18279424 / AOR or EIR key. Astrnmy Obs Req/Instr Eng Req -DS_IDENT= 'ads/sa.spitzer#0018279424' / Data Set Identification for ADS/journals -EXPID = 14 / Exposure ID (0-9999) -DCENUM = 0 / DCE number (0-9999) -TLMGRPS = 1 / expected number of groups -FILE_VER= 1 / Version of the raw file made by SIS -RAWFILE = 'IRAC.1.0018279424.0014.0000.01.mipl.fits' / Raw data file name -CPT_VER = '3.1.11 ' / Channel Param Table FOS versioN -CTD_VER = '3.0.94S ' / Cmded telemetry data version -EXPDFLAG= F / (T/F) expedited DCE -MISS_LCT= 0 / Total Missed Line Cnt in this FITS -MANCPKT = F / T if this FITS is Missing Ancillary Data -MISSDATA= F / T if this FITS is Missing Image Data -CHECKSUM= 0 / MIPL computed checksum -PAONUM = 2463 / PAO Number -CAMPAIGN= 'IRAC009800' / Campaign -DCEID = 80565322 / Data-Collection-Event ID -DCEINSID= 16981930 / DCE Instance ID -DPID = 178643698 / Data Product Instance ID -PIPENUM = 107 / Pipeline Script Number -SOS_VER = 2 / Data-Product Version -PLVID = 4 / Pipeline Version ID -CALID = 6 / CalTrans Version ID - -SDRKEPID= 3230182 / Sky Dark ensemble product ID - -PMSKFBID= 995 / Pixel mask ID -LDRKFBID= 836 / Fall-back lab dark ID -LINCFBID= 357 / Fall-back Linearity correction ID -FLATFBID= 1011 / Fall-back flat ID -FLXCFBID= 1025 / Flux conversion ID -MBLTFBID= 696 / Muxbleed Lookup Table ID -MBCFFBID= 704 / Muxbleed Coefficients ID -LBDRKFLE= 'FUL_12s_12sf8d1r1_ch1_v1.2.0_dark.txt' / Labdark File Used -DDCORR1 = 1.488018 / Darkdrift Correction for Readout Channel 1 -DDCORR2 = -5.919937 / Darkdrift Correction for Readout Channel 2 -DDCORR3 = 2.243147 / Darkdrift Correction for Readout Channel 3 -DDCORR4 = 2.188772 / Darkdrift Correction for Readout Channel 4 -DDBKGND = 68.5909 / arkdrift 'Background' Term - - - - / PROCESSING HISTORY - -HISTORY job.c ver: 1.50 -HISTORY TRANHEAD v. 12.8, ran Mon Jul 9 21:40:04 2007 -HISTORY CALTRANS v. 4.0, ran Mon Jul 9 21:40:08 2007 -HISTORY INSBPOSDOM v. 1.1, ran Mon Jul 9 21:40:08 2007 -HISTORY cvti2r4 v. 1.31 A61025, generated 7/09/07 at 21:40:09 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:11 -HISTORY FFC v. 1.0, ran Mon Jul 9 21:40:12 2007 -HISTORY MUXBLEEDCORR v. 1.600, ran Mon Jul 9 21:40:13 2007 -HISTORY FOWLINEARIZE v. 4.900000, ran Mon Jul 9 21:40:13 2007 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:14 -HISTORY BGMODEL v. 1.0, ran Mon Jul 9 21:40:14 2007 -HISTORY SLREMOVE v. 1.0, ran Mon Jul 9 21:40:14 2007 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:15 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:16 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:16 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:17 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:18 -HISTORY DARKSUBNG v. 1.000, ran Mon Jul 9 21:40:18 2007 -HISTORY DARKDRIFT v. 4.0, ran Mon Jul 9 21:40:19 2007 -HISTORY FLATAP v. 1.500 Mon Jul 9 21:40:20 2007 -HISTORY DNTOFLUX v. 4.1, ran Mon Jul 9 21:40:23 2007 -HISTORY CALTRANS v. 4.0, ran Mon Jul 9 21:47:55 2007 -HISTORY PTNTRAN v. 1.4, ran Mon Jul 9 21:47:56 2007 -HISTORY FPGen v. 1.25, ran Mon Jul 9 21:47:58 2007 -HISTORY PTGADJUST v. 1.0, ran Mon Jul 9 21:51:34 2007 -END diff --git a/ast/ast_tester/sip.head b/ast/ast_tester/sip.head deleted file mode 100644 index 0e9e838..0000000 --- a/ast/ast_tester/sip.head +++ /dev/null @@ -1,288 +0,0 @@ -SIMPLE = T / Fits standard -BITPIX = -32 / FOUR-BYTE SINGLE PRECISION FLOATING POINT -NAXIS = 2 / STANDARD FITS FORMAT -NAXIS1 = 256 / STANDARD FITS FORMAT -NAXIS2 = 256 / STANDARD FITS FORMAT -ORIGIN = 'Spitzer Science Center' / Organization generating this FITS file -CREATOR = 'S16.1.0 ' / SW version used to create this FITS file -TELESCOP= 'Spitzer ' / SPITZER Space Telescope -INSTRUME= 'IRAC ' / SPITZER Space Telescope instrument ID -CHNLNUM = 1 / 1 digit instrument channel number -EXPTYPE = 'sci ' / Exposure Type -REQTYPE = 'AOR ' / Request type (AOR, IER, or SER) -AOT_TYPE= 'IracMap ' / Observation template type -AORLABEL= '05cs-IRAC-2' / AOR Label -FOVID = 67 / Field of View ID -FOVNAME = 'IRAC_Center_of_3.6&5.8umArray' / Field of View Name - - / PROPOSAL INFORMATION - -OBSRVR = 'Ben Sugerman' / Observer Name (Last, First) -OBSRVRID= 14621 / Observer ID of Principal Investigator -PROCYCL = 6 / Proposal Cycle -PROGID = 30494 / Program ID -PROTITLE= 'Supernovae and the Origin of Dust in Galaxies: Follow-Up Observation' -PROGCAT = 30 / Program Category - - / TIME AND EXPOSURE INFORMATION - -DATE_OBS= '2007-06-29T03:15:33.555' / Date & time at DCE start -MJD_OBS = 54280.135805 / [days] MJD at DCE start (,JD-2400000.5) -UTCS_OBS= 236358933.555 / [sec] J2000 ephem. time at DCE start -SCLK_OBS= 867554299.94 / [sec] SCLK time (since 1/1/1980) at DCE start -SAMPTIME= 0.2 / [sec] Sample integration time -FRAMTIME= 12. / [sec] Time spent integrating (whole array) -COMMENT Photons in Well = Flux[photons/sec/pixel] * FRAMTIME -EXPTIME = 10.4 / [sec] Effective integration time per pixel -COMMENT DN per pixel = Flux[photons/sec/pixel] / GAIN * EXPTIME -INTRFDLY= 8. / [sec] Inter Frame Delay Time -AINTBEG = 107646.2 / [Secs since IRAC turn-on] Time of integ. start -ATIMEEND= 107658.16 / [Secs since IRAC turn-on] Time of integ. end -AFOWLNUM= 8 / Fowler number -AWAITPER= 44 / [0.2 sec] Wait period -ANUMREPS= 1 / Number of repeat integrations -AREADMOD= 0 / Full (0) or subarray (1) -HDRMODE = F / DCE taken in High Dynamic Range mode -ABARREL = 3 / Barrel shift -APEDSIG = 0 / 0=Normal, 1=Pedestal, 2=Signal - - / TARGET AND POINTING INFORMATION - -OBJECT = 'SN 2005cs' / Target Name -OBJTYPE = 'TargetFixedSingle' / Object Type -CRVAL1 = 202.482322805429 / [deg] RA at CRPIX1,CRPIX2 (using Pointing Recon -CRVAL2 = 47.1751189300101 / [deg] DEC at CRPIX1,CRPIX2 (using Pointing Reco -RA_HMS = '13h29m55.8s' / [hh:mm:ss.s] CRVAL1 as sexagesimal -DEC_DMS = '+47d10m30s' / [dd:mm:ss] CRVAL2 as sexagesimal -RADESYS = 'ICRS ' / International Celestial Reference System -EQUINOX = 2000. / Equinox for ICRS celestial coord. system -CD1_1 = 0.000249756880272355 / Corrected CD matrix element with Pointing Recon -CD1_2 = 0.000230177809743655 / Corrected CD matrix element with Pointing Recon -CD2_1 = 0.000230428519265417 / Corrected CD matrix element with Pointing Recon -CD2_2 = -0.000249965770576587 / Corrected CD matrix element with Pointing Reco -CTYPE1 = 'RA---TAN-SIP' / RA---TAN with distortion in pixel space -CTYPE2 = 'DEC--TAN-SIP' / DEC--TAN with distortion in pixel space -CRPIX1 = 128. / Reference pixel along axis 1 -CRPIX2 = 128. / Reference pixel along axis 2 -PXSCAL1 = -1.22334117768332 / [arcsec/pix] Scale for axis 1 at CRPIX1,CRPIX2 -PXSCAL2 = 1.22328355209902 / [arcsec/pix] Scale for axis 2 at CRPIX1,CRPIX2 -CRDER1 = 4.02509762361481E-05 / [deg] Uncertainty in CRVAL1 -CRDER2 = 3.4274613195288E-05 / [deg] Uncertainty in CRVAL2 -UNCRTPA = 0.000378787843382542 / [deg] Uncertainty in position angle -CSDRADEC= 4.75971783897902E-07 / [deg] Costandard deviation in RA and Dec -SIGRA = 0.0339487135007807 / [arcsec] RMS dispersion of RA over DCE -SIGDEC = 0.0637682657426773 / [arcsec] RMS dispersion of DEC over DCE -SIGPA = 1.36464273573987 / [arcsec] RMS dispersion of PA over DCE -PA = 137.359976084299 / [deg] Position angle of axis 2 (E of N) (was OR -RA_RQST = 202.482116615975 / [deg] Requested RA at CRPIX1, CRPIX2 -DEC_RQST= 47.1750785413522 / [deg] Requested Dec at CRPIX1, CRPIX2 -PM_RA = 0. / [arcsec/yr] Proper Motion in RA (J2000) -PM_DEC = 0. / [arcsec/yr] Proper Motion in Dec (J200) -RMS_JIT = 0.00768303401855732 / [arcsec] RMS jitter during DCE -RMS_JITY= 0.00515070337437348 / [arcsec] RMS jitter during DCE along Y -RMS_JITZ= 0.00570081279113133 / [arcsec] RMS jitter during DCE along Z -SIG_JTYZ= 0.00237806410221437 / [arcsec] Costadard deviation of jitter in YZ -PTGDIFF = 0.525106524659797 / [arcsec] Offset btwn actual and rqsted pntng -PTGDIFFX= 0.46966798486043 / [pixels] rqsted - actual pntng along axis 1 -PTGDIFFY= -0.235285197422366 / [pixels] rqsted - actual pntng along axis 2 -RA_REF = 202.472375 / [deg] Commanded RA (J2000) of ref. position -DEC_REF = 47.1745 / [deg] Commanded Dec (J2000) of ref. position -USEDBPHF= T / T if Boresight Pointing History File was used -BPHFNAME= 'SBPHF.0867542400.031.pntg' / Boresight Pointing History Filename -FOVVERSN= 'BodyFrames_FTU_14a.xls' / FOV/BodyFrames file version used -RECONFOV= 'IRAC_Center_of_3.6umArray' / Reconstructed Field of View -RARFND = 202.482315063477 / [deg] Refined RA -DECRFND = 47.175121307373 / [deg] Refined DEC -CT2RFND = 137.359054565430 / [deg] Refined CROT2 -ERARFND = 0.000002332304 / [deg] Error in RARFND value -EDECRFND= 0.000002332411 / [deg] Error in DECRFND value -ECT2RFND= 0.000540699053 / [deg] Error in CT2RFND value -NASTROM = 12 / Astrometric sources for absolute refinement -ORIG_RA = 202.482055664062 / [deg] Original RA from raw BPHF (without pointi -ORIG_DEC= 47.1750717163086 / [deg] Original Dec from raw BPHF (without point -ORIGCD11= 0.0002497563255 / [deg/pix] Original CD1_1 element (without point -ORIGCD12= 0.0002301784261 / [deg/pix] Original CD1_2 element (without point -ORIGCD21= 0.0002304291411 / [deg/pix] Original CD2_1 element (without point -ORIGCD22= -0.0002499652037 / [deg/pix] Original CD2_2 element (without point - - - - / DISTORTION KEYWORDS - -A_ORDER = 3 / polynomial order, axis 1, detector to sky -A_0_2 = 2.9656E-06 / distortion coefficient -A_0_3 = 3.7746E-09 / distortion coefficient -A_1_1 = 2.1886E-05 / distortion coefficient -A_1_2 = -1.6847E-07 / distortion coefficient -A_2_0 = -2.3863E-05 / distortion coefficient -A_2_1 = -8.561E-09 / distortion coefficient -A_3_0 = -1.4172E-07 / distortion coefficient -A_DMAX = 1.394 / [pixel] maximum correction -B_ORDER = 3 / polynomial order, axis 2, detector to sky -B_0_2 = 2.31E-05 / distortion coefficient -B_0_3 = -1.6168E-07 / distortion coefficient -B_1_1 = -2.4386E-05 / distortion coefficient -B_1_2 = -5.7813E-09 / distortion coefficient -B_2_0 = 2.1197E-06 / distortion coefficient -B_2_1 = -1.6583E-07 / distortion coefficient -B_3_0 = -2.0249E-08 / distortion coefficient -B_DMAX = 1.501 / [pixel] maximum correction -AP_ORDER= 3 / polynomial order, axis 1, sky to detector -AP_0_1 = -6.4275E-07 / distortion coefficient -AP_0_2 = -2.9425E-06 / distortion coefficient -AP_0_3 = -3.582E-09 / distortion coefficient -AP_1_0 = -1.4897E-05 / distortion coefficient -AP_1_1 = -2.225E-05 / distortion coefficient -AP_1_2 = 1.7195E-07 / distortion coefficient -AP_2_0 = 2.4146E-05 / distortion coefficient -AP_2_1 = 6.709E-09 / distortion coefficient -AP_3_0 = 1.4492E-07 / distortion coefficient -BP_ORDER= 3 / polynomial order, axis 2, sky to detector -BP_0_1 = -1.6588E-05 / distortion coefficient -BP_0_2 = -2.3424E-05 / distortion coefficient -BP_0_3 = 1.651E-07 / distortion coefficient -BP_1_0 = -2.6783E-06 / distortion coefficient -BP_1_1 = 2.4753E-05 / distortion coefficient -BP_1_2 = 3.8917E-09 / distortion coefficient -BP_2_0 = -2.151E-06 / distortion coefficient -BP_2_1 = 1.7E-07 / distortion coefficient -BP_3_0 = 2.0482E-08 / distortion coefficient - - / PHOTOMETRY - -BUNIT = 'MJy/sr ' / Units of image data -FLUXCONV= 0.1088 / Flux Conv. factor (MJy/sr per DN/sec) -GAIN = 3.3 / e/DN conversion -RONOISE = 9.4 / [Electrons] Readout Noise from Array -ZODY_EST= 0.05291139 / [MJy/sr] Zodiacal Background Estimate -ISM_EST = 0.003677277 / [MJy/sr] Interstellar Medium Estimate -CIB_EST = 0. / [MJy/sr] Cosmic Infrared Background Estimate -SKYDRKZB= 0.044533 / [MJy/sr] Zodiacal Background Est of subracted s -SKYDKMED= 0.039081 / [MJy/sr] Median of Subtracted Skydark -SKDKFDLY= 11.554 / [sec] Average Frame Delay Time of Skydark -SKDKIDLY= 11.554 / [sec] Average Immediate Delay Time of Skydark - - / GENERAL MAPPING KEYWORDS - -DITHPOS = 2 / Current dither position - - / IRAC MAPPING KEYWORDS - -READMODE= 'FULL ' / Readout mode -DITHSCAL= 'medium ' / Dither scale (small, medium, large) - - / INSTRUMENT TELEMETRY DATA - -ASHTCON = 2 / Shutter condition (1:closed, 2: open) -AWEASIDE= 0 / WEA side in use (0:B, 1:A) -ACTXSTAT= 0 / Cmded transcal status -ATXSTAT = 0 / transcal status -ACFLSTAT= 0 / Cmded floodcal status -AFLSTAT = 0 / floodcal status -AVRSTUCC= -3.5 / [Volts] Cmded VRSTUC Bias -AVRSTBEG= -3.5114367 / [Volts] VRSTUC Bias at start integration -AVDETC = -2.75 / [Volts] Cmded VDET Bias -AVDETBEG= -2.7585216 / [Volts] VDET Bias at start of integration -AVGG1C = -3.65 / [Volts] Cmded VGG1 Bias -AVGG1BEG= -3.2078801 / [Volts] VGG1 Bias at start of integration -AVDDUCC = -3 / [Volts] Cmded VDDUC Bias -AVDDUBEG= -3 / [Volts] VDDUC Bias at start integration -AVGGCLC = 1 / [Volts] Cmnded VGGCL clock rail voltage -AVGGCBEG= 1 / [Volts] VGGCL clock rail voltage -AHTRIBEG= 204.49722 / [uAmps] Heater current at start of integ -AHTRVBEG= 2.3936886 / [Volts] Heater Voltage at start integ. -AFPAT2B = 15.022535 / [Deg_K] FPA Temp sensor #2 at start integ. -AFPAT2BT= 107644.61 / [Sec] FPA Temp sensor #2 time tag -AFPAT2E = 15.022535 / [Deg_K] FPA temp sensor #2, end integ. -AFPAT2ET= 107644.61 / [Sec] FPA temp sensor #2 time tag -ACTENDT = 20.376773 / [Deg_C] C&T board thermistor -AFPECTE = 18.3055 / [Deg_C] FPE control board thermistor -AFPEATE = 21.814696 / [Deg_C] FPE analog board thermistor -ASHTEMPE= 21.504564 / [Deg_C] Shutter board thermistor -ATCTEMPE= 22.662835 / [Deg_C] Temp. controller board thermistor -ACETEMPE= 20.285331 / [Deg_C] Calib. electronics board thermistor -APDTEMPE= 20.590139 / [Deg_C] PDU board thermistor -ACATMP1E= 1.3181374 / [Deg_K] CA Temp, end integration for temp1 -ACATMP2E= 1.3011689 / [Deg_K] CA Temp, end integration for temp2 -ACATMP3E= 1.3331941 / [Deg_K] CA Temp, end integration for temp3 -ACATMP4E= 1.3299368 / [Deg_K] CA Temp, end integration for temp4 -ACATMP5E= 1.3280274 / [Deg_K] CA Temp, end integration for temp5 -ACATMP6E= 1.32662 / [Deg_K] CA Temp, end integration for temp6 -ACATMP7E= 1.3253879 / [Deg_K] CA Temp, end integration for temp7 -ACATMP8E= 1.3185339 / [Deg_K] CA Temp, end integration for temp8 - - / DATA FLOW KEYWORDS - -ORIGIN0 = 'JPL_FOS ' / Site where RAW FITS file was written -CREATOR0= 'J5.3 ' / SW system that created RAW FITS -DATE = '2007-07-10T04:40:23' / [YYYY-MM-DDThh:mm:ss UTC] file creation date -AORKEY = 18279424 / AOR or EIR key. Astrnmy Obs Req/Instr Eng Req -DS_IDENT= 'ads/sa.spitzer#0018279424' / Data Set Identification for ADS/journals -EXPID = 14 / Exposure ID (0-9999) -DCENUM = 0 / DCE number (0-9999) -TLMGRPS = 1 / expected number of groups -FILE_VER= 1 / Version of the raw file made by SIS -RAWFILE = 'IRAC.1.0018279424.0014.0000.01.mipl.fits' / Raw data file name -CPT_VER = '3.1.11 ' / Channel Param Table FOS versioN -CTD_VER = '3.0.94S ' / Cmded telemetry data version -EXPDFLAG= F / (T/F) expedited DCE -MISS_LCT= 0 / Total Missed Line Cnt in this FITS -MANCPKT = F / T if this FITS is Missing Ancillary Data -MISSDATA= F / T if this FITS is Missing Image Data -CHECKSUM= 0 / MIPL computed checksum -PAONUM = 2463 / PAO Number -CAMPAIGN= 'IRAC009800' / Campaign -DCEID = 80565322 / Data-Collection-Event ID -DCEINSID= 16981930 / DCE Instance ID -DPID = 178643698 / Data Product Instance ID -PIPENUM = 107 / Pipeline Script Number -SOS_VER = 2 / Data-Product Version -PLVID = 4 / Pipeline Version ID -CALID = 6 / CalTrans Version ID - -SDRKEPID= 3230182 / Sky Dark ensemble product ID - -PMSKFBID= 995 / Pixel mask ID -LDRKFBID= 836 / Fall-back lab dark ID -LINCFBID= 357 / Fall-back Linearity correction ID -FLATFBID= 1011 / Fall-back flat ID -FLXCFBID= 1025 / Flux conversion ID -MBLTFBID= 696 / Muxbleed Lookup Table ID -MBCFFBID= 704 / Muxbleed Coefficients ID -LBDRKFLE= 'FUL_12s_12sf8d1r1_ch1_v1.2.0_dark.txt' / Labdark File Used -DDCORR1 = 1.488018 / Darkdrift Correction for Readout Channel 1 -DDCORR2 = -5.919937 / Darkdrift Correction for Readout Channel 2 -DDCORR3 = 2.243147 / Darkdrift Correction for Readout Channel 3 -DDCORR4 = 2.188772 / Darkdrift Correction for Readout Channel 4 -DDBKGND = 68.5909 / arkdrift 'Background' Term - - - - / PROCESSING HISTORY - -HISTORY job.c ver: 1.50 -HISTORY TRANHEAD v. 12.8, ran Mon Jul 9 21:40:04 2007 -HISTORY CALTRANS v. 4.0, ran Mon Jul 9 21:40:08 2007 -HISTORY INSBPOSDOM v. 1.1, ran Mon Jul 9 21:40:08 2007 -HISTORY cvti2r4 v. 1.31 A61025, generated 7/09/07 at 21:40:09 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:11 -HISTORY FFC v. 1.0, ran Mon Jul 9 21:40:12 2007 -HISTORY MUXBLEEDCORR v. 1.600, ran Mon Jul 9 21:40:13 2007 -HISTORY FOWLINEARIZE v. 4.900000, ran Mon Jul 9 21:40:13 2007 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:14 -HISTORY BGMODEL v. 1.0, ran Mon Jul 9 21:40:14 2007 -HISTORY SLREMOVE v. 1.0, ran Mon Jul 9 21:40:14 2007 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:15 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:16 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:16 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:17 -HISTORY hdrupd8 v. 1.5 A50126, updated 7/09/07 at 21:40:18 -HISTORY DARKSUBNG v. 1.000, ran Mon Jul 9 21:40:18 2007 -HISTORY DARKDRIFT v. 4.0, ran Mon Jul 9 21:40:19 2007 -HISTORY FLATAP v. 1.500 Mon Jul 9 21:40:20 2007 -HISTORY DNTOFLUX v. 4.1, ran Mon Jul 9 21:40:23 2007 -HISTORY CALTRANS v. 4.0, ran Mon Jul 9 21:47:55 2007 -HISTORY PTNTRAN v. 1.4, ran Mon Jul 9 21:47:56 2007 -HISTORY FPGen v. 1.25, ran Mon Jul 9 21:47:58 2007 -HISTORY PTGADJUST v. 1.0, ran Mon Jul 9 21:51:34 2007 -END diff --git a/ast/ast_tester/sparse.ast b/ast/ast_tester/sparse.ast deleted file mode 100644 index c28cb4d..0000000 --- a/ast/ast_tester/sparse.ast +++ /dev/null @@ -1,392 +0,0 @@ - Begin FrameSet # Set of inter-related coordinate systems -# Title = "3-d compound coordinate system" # Title of coordinate system -# Naxes = 3 # Number of coordinate axes -# Domain = "SKY-DSBSPECTRUM" # Coordinate system domain -# Epoch = 2007.10664386351 # Julian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Lbl3 = "Radio velocity (USB)" # Label for axis 3 -# System = "Compound" # Coordinate system type -# Uni1 = "hh:mm:ss.sss" # Units for axis 1 -# Uni2 = "ddd:mm:ss.ss" # Units for axis 2 -# Uni3 = "km/s" # Units for axis 3 -# Dig1 = 9 # Individual precision for axis 1 -# Dig2 = 9 # Individual precision for axis 2 -# Digits = 7 # Default formatting precision -# Fmt1 = "hms.3" # Format specifier for axis 1 -# Fmt2 = "dms.2" # Format specifier for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction - IsA Frame # Coordinate system description - Nframe = 5 # Number of Frames in FrameSet -# Base = 1 # Index of base Frame - Currnt = 5 # Index of current Frame - Nnode = 6 # Number of nodes in FrameSet - Nod1 = 3 # Frame 1 is associated with node 3 - Nod2 = 4 # Frame 2 is associated with node 4 - Nod3 = 5 # Frame 3 is associated with node 5 - Nod4 = 6 # Frame 4 is associated with node 6 - Nod5 = 2 # Frame 5 is associated with node 2 - Lnk2 = 1 # Node 2 is derived from node 1 - Lnk3 = 1 # Node 3 is derived from node 1 - Lnk4 = 1 # Node 4 is derived from node 1 - Lnk5 = 1 # Node 5 is derived from node 1 - Lnk6 = 1 # Node 6 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame # Coordinate system description - Title = "Data grid indices; first pixel at (1,1,1)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Data grid index 1" # Label for axis 1 -# Lbl2 = "Data grid index 2" # Label for axis 2 -# Lbl3 = "Data grid index 3" # Label for axis 3 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 -# Uni3 = "pixel" # Units for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Data grid index 1" # Axis Label - Symbol = "g1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Data grid index 2" # Axis Label - Symbol = "g2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Data grid index 3" # Axis Label - Symbol = "g3" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm2 = # Frame number 2 - Begin Frame # Coordinate system description - Title = "Pixel coordinates; first pixel at (0.5,0.5,-1024.5)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "PIXEL" # Coordinate system domain -# Lbl1 = "Pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Pixel coordinate 2" # Label for axis 2 -# Lbl3 = "Pixel coordinate 3" # Label for axis 3 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 -# Uni3 = "pixel" # Units for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 1" # Axis Label - Symbol = "p1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 2" # Axis Label - Symbol = "p2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Pixel coordinate 3" # Axis Label - Symbol = "p3" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm3 = # Frame number 3 - Begin Frame # Coordinate system description - Title = "Axis coordinates; first pixel at (0.5,0.5,-1024.5)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "AXIS" # Coordinate system domain -# Lbl1 = "Axis 1" # Label for axis 1 -# Lbl2 = "Axis 2" # Label for axis 2 -# Lbl3 = "Axis 3" # Label for axis 3 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 -# Uni3 = "pixel" # Units for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Axis 1" # Axis Label - Symbol = "a1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Axis 2" # Axis Label - Symbol = "a2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Axis 3" # Axis Label - Symbol = "a3" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm4 = # Frame number 4 - Begin Frame # Coordinate system description - Title = "Normalised pixel coordinates; first pixel at (0.03846154,0.5,0.0002441406)" # Title of coordinate system - Naxes = 3 # Number of coordinate axes - Domain = "FRACTION" # Coordinate system domain -# Lbl1 = "Normalised pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Normalised pixel coordinate 2" # Label for axis 2 -# Lbl3 = "Normalised pixel coordinate 3" # Label for axis 3 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Label = "Normalised pixel coordinate 1" # Axis Label - Symbol = "f1" # Axis symbol - Unit = "" # Axis units - Format = "%5.4f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis # Coordinate axis - Label = "Normalised pixel coordinate 2" # Axis Label - Symbol = "f2" # Axis symbol - Unit = "" # Axis units - Format = "%5.4f" # Format specifier - End Axis - Ax3 = # Axis number 3 - Begin Axis # Coordinate axis - Label = "Normalised pixel coordinate 3" # Axis Label - Symbol = "f3" # Axis symbol - Unit = "" # Axis units - Format = "%5.4f" # Format specifier - End Axis - End Frame - Frm5 = # Frame number 5 - Begin CmpFrame # Compound coordinate system description -# Title = "3-d compound coordinate system" # Title of coordinate system -# Naxes = 3 # Number of coordinate axes -# Domain = "SKY-DSBSPECTRUM" # Coordinate system domain -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Lbl3 = "Radio velocity (USB)" # Label for axis 3 -# Uni1 = "hh:mm:ss.sss" # Units for axis 1 -# Uni2 = "ddd:mm:ss.ss" # Units for axis 2 -# Uni3 = "km/s" # Units for axis 3 -# Dig1 = 9 # Individual precision for axis 1 -# Dig2 = 9 # Individual precision for axis 2 -# Digits = 7 # Default formatting precision -# Fmt1 = "hms.3" # Format specifier for axis 1 -# Fmt2 = "dms.2" # Format specifier for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction - IsA Frame # Coordinate system description - FrameA = # First component Frame - Begin SkyFrame # Description of celestial coordinate system - Naxes = 2 # Number of coordinate axes - Epoch = 2007.10664386351 # Julian epoch of observation - System = "FK5" # Coordinate system type - ObsLat = 0.346026069000145 # Observers geodetic latitude (rads) - ObsLon = -2.71363307300091 # Observers geodetic longitude (rads) - Dut1 = -0.00321845632046122 # UT1-UTC in seconds - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - Digits = 9 # Default formatting precision - IsA Axis # Coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - Digits = 9 # Default formatting precision - IsA Axis # Coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - SRef1 = 1.2343627630284 # Ref. pos. RA 4:42:53.706 - SRef2 = 0.63032350835257 # Ref. pos. Dec 36:06:53.56 - End SkyFrame - FrameB = # Second component Frame - Begin DSBSpecFrame # Dual sideband spectral axis - Naxes = 1 # Number of coordinate axes - Epoch = 2007.10664386353 # Julian epoch of observation - System = "VRAD" # Coordinate system type - ObsLat = 0.346026069000144 # Observers geodetic latitude (rads) - ObsLon = -2.71363307300091 # Observers geodetic longitude (rads) - Dut1 = -0.00321845632046122 # UT1-UTC in seconds - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - End Axis - IsA Frame # Coordinate system description - SoR = "LSRK" # Standard of rest - RefRA = 1.23436224892048 # Reference RA (rads, FK5 J2000) - RefDec = 0.630323957597852 # Reference Dec (rads, FK5 J2000) - RstFrq = 345795989900 # Rest frequency (Hz) - SrcVel = -21699.2154029027 # Source velocity (m/s) - SrcVRF = "LSRK" # Source velocity rest frame - UFreq = "GHz" # Preferred units for frequency - IsA SpecFrame # Description of spectral coordinate system - DSBCen = 345782054267.698 # Central frequency (Hz topo) - IF = -4999999979.60052 # Intermediate frequency (Hz) - SideBn = "USB" # Represents upper sideband - AlSdBn = 1 # Align sidebands? - End DSBSpecFrame - End CmpFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin PermMap # Coordinate permutation - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Out1 = 1 # Output coordinate 1 = input coordinate 1 - Out2 = 1 # Output coordinate 2 = input coordinate 1 - In1 = 1 # Input coordinate 1 = output coordinate 1 - In2 = 0 # Input coordinate 2 is "bad" - End PermMap - MapB = # Second component Mapping - Begin WinMap # Map one window on to another - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = 2.86538852378726e-05 # Shift for axis 1 - End WinMap - End CmpMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 3 # Number of input coordinates - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin LutMap # Map 1-d coordinates using a lookup table - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - Nlut = 13 # Number of lookup table elements - Start = 1 # Input value at first element -# Incr = 1 # Input value increment between elements - LutInt = 1 # Interpolation method - L1 = 1.23418282732218 # Lookup table elements... - L2 = 1.2343639301616 - L3 = 1.23436339112322 - L4 = 1.2343628519694 - L5 = 1.23436231270009 - L6 = 1.23454235656739 - L7 = 1.23454287673211 - L8 = 1.2345433967854 - L9 = 1.23454391672729 - L10 = 1.23472390339668 - L11 = 1.23472340255133 - L12 = 1.23472290159864 - L13 = 1.23472240053857 - End LutMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin LutMap # Map 1-d coordinates using a lookup table - Nin = 1 # Number of input coordinates - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - Nlut = 13 # Number of lookup table elements - Start = 1 # Input value at first element -# Incr = 1 # Input value increment between elements - LutInt = 1 # Interpolation method - L1 = 0.630323242601191 # Lookup table elements... - L2 = 0.630032824768848 - L3 = 0.630178255337191 - L4 = 0.630323685912113 - L5 = 0.630469116487462 - L6 = 0.630469544411238 - L7 = 0.630324113791166 - L8 = 0.630178683171532 - L9 = 0.630033252558487 - L10 = 0.630033664925644 - L11 = 0.630179095578678 - L12 = 0.630324526238311 - L13 = 0.63046995689839 - End LutMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = 346321451689.665 # Shift for axis 1 - Scl1 = -488226.2403564 # Scale factor for axis 1 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin SpecMap # Conversion between spectral coordinate systems - Nin = 1 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Nspec = 2 # Number of conversion steps - Spec1 = "FRTOVL" # Convert frequency to rel. velocity - Spec1a = 345795989900 # Rest frequency (Hz) - Spec2 = "VLTOVR" # Convert relativistic to radio velocity - End SpecMap - MapB = # Second component Mapping - Begin ZoomMap # Zoom about the origin - Nin = 1 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Zoom = 0.001 # Zoom factor - End ZoomMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - Map3 = # Mapping between nodes 1 and 3 - Begin UnitMap # Unit (null) Mapping - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - End UnitMap - Map4 = # Mapping between nodes 1 and 4 - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - Sft1 = -0.5 # Shift for axis 1 - Sft2 = -0.5 # Shift for axis 2 - Sft3 = -1025.5 # Shift for axis 3 - End WinMap - Map5 = # Mapping between nodes 1 and 5 - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - Sft1 = -0.5 # Shift for axis 1 - Sft2 = -0.5 # Shift for axis 2 - Sft3 = -1025.5 # Shift for axis 3 - End WinMap - Map6 = # Mapping between nodes 1 and 6 - Begin WinMap # Map one window on to another - Nin = 3 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - IsA Mapping # Mapping between coordinate systems - Sft1 = -0.0384615384615385 # Shift for axis 1 - Scl1 = 0.0769230769230769 # Scale factor for axis 1 - Sft2 = -0.5 # Shift for axis 2 - Sft3 = -0.000244140625 # Shift for axis 3 - Scl3 = 0.00048828125 # Scale factor for axis 3 - End WinMap - End FrameSet diff --git a/ast/ast_tester/specflux.ast b/ast/ast_tester/specflux.ast deleted file mode 100644 index 0da5fea..0000000 --- a/ast/ast_tester/specflux.ast +++ /dev/null @@ -1,29 +0,0 @@ - Begin CmpFrame # Compound coordinate system description -# Title = "2-d compound coordinate system" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "SPECTRUM-" # Coordinate system domain -# Lbl1 = "Wavelength" # Label for axis 1 -# Lbl2 = "Axis 2" # Label for axis 2 -# Uni1 = "um" # Units for axis 1 -# Uni2 = "10%^50+%s50+-26%+W/m%^50+%s50+2%+/Angstrom" # Units for axis 2 - IsA Frame # Coordinate system description - FrameA = # First component Frame - Begin SpecFrame # Description of spectral coordinate system - Naxes = 1 # Number of coordinate axes - System = "WAVE" # Coordinate system type - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Unit = "um" # Axis units - End Axis - IsA Frame # Coordinate system description - UWave = "um" # Preferred units for wavelength - End SpecFrame - FrameB = # Second component Frame - Begin Frame # Coordinate system description - Naxes = 1 # Number of coordinate axes - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Unit = "10%^50+%s50+-26%+W/m%^50+%s50+2%+/Angstrom" # Axis units - End Axis - End Frame - End CmpFrame diff --git a/ast/ast_tester/specflux.attr b/ast/ast_tester/specflux.attr deleted file mode 100644 index e00d209..0000000 --- a/ast/ast_tester/specflux.attr +++ /dev/null @@ -1 +0,0 @@ -system=freq,logplot=1,loggap(1)=100 diff --git a/ast/ast_tester/specflux.box b/ast/ast_tester/specflux.box deleted file mode 100644 index 7c6f180..0000000 --- a/ast/ast_tester/specflux.box +++ /dev/null @@ -1,2 +0,0 @@ -1 3 1.0E-8 9 - diff --git a/ast/ast_tester/specflux.head b/ast/ast_tester/specflux.head deleted file mode 100644 index ac4a035..0000000 --- a/ast/ast_tester/specflux.head +++ /dev/null @@ -1,28 +0,0 @@ - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST Beginning of AST data for CmpFrame object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'CmpFrame' / Compound coordinate system description -FRAMEA_A= ' ' / First component Frame -BEGAST_B= 'SpecFrame' / Description of spectral coordinate system -NAXES_A = 1 / Number of coordinate axes -SYSTEM_A= 'WAVE ' / Coordinate system type -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -UNIT_A = 'um ' / Axis units -ENDAST_A= 'Axis ' / End of object definition -ISA_A = 'Frame ' / Coordinate system description -UWAVE_A = 'um ' / Preferred units for wavelength -ENDAST_B= 'SpecFrame' / End of object definition -FRAMEB_A= ' ' / Second component Frame -BEGAST_D= 'Frame ' / Coordinate system description -NAXES_B = 1 / Number of coordinate axes -AX1_B = ' ' / Axis number 1 -BEGAST_E= 'Axis ' / Coordinate axis -UNIT_B = '10%^50+%s50+-26%+W/m%^50+%s50+2%+/Angstrom'/ Axis units -ENDAST_C= 'Axis ' / End of object definition -ENDAST_D= 'Frame ' / End of object definition -ENDAST_E= 'CmpFrame' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for CmpFrame object AST -COMMENT AST ---------------------------------------------------------------- AST diff --git a/ast/ast_tester/splittest1.ast b/ast/ast_tester/splittest1.ast deleted file mode 100644 index 9fb1e2f..0000000 --- a/ast/ast_tester/splittest1.ast +++ /dev/null @@ -1,185 +0,0 @@ - Begin CmpMap # Compound Mapping - Nin = 4 # Number of input coordinates - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin UnitMap # Unit (null) Mapping - Nin = 4 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - End UnitMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 4 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 4 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -129 # Shift for axis 1 - Sft2 = -65 # Shift for axis 2 - Sft3 = -0.5 # Shift for axis 3 - Sft4 = -1 # Shift for axis 4 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 4 # Number of input coordinates - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap # Matrix transformation - Nin = 4 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.996194698 # Forward matrix value - M1 = 0.087155743 # Forward matrix value - M2 = 0 # Forward matrix value - M3 = 0 # Forward matrix value - M4 = -0.087155743 # Forward matrix value - M5 = 0.996194698 # Forward matrix value - M6 = 0 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = 0 # Forward matrix value - M9 = 0 # Forward matrix value - M10 = 1 # Forward matrix value - M11 = 0 # Forward matrix value - M12 = 0 # Forward matrix value - M13 = 0 # Forward matrix value - M14 = 0 # Forward matrix value - M15 = 1 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 4 # Number of input coordinates - Invert = 0 # Mapping not inverted - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = 136 # Shift for axis 1 - Sft2 = 76 # Shift for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 2 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - Series = 0 # Component Mappings applied in parallel - MapA = # First component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap # Map one window on to another - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = 0.5 # Shift for axis 1 - End WinMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin LutMap # Map 1-d coordinates using a lookup table - Nin = 1 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Nlut = 8 # Number of lookup table elements - Start = 1 # Input value at first element -# Incr = 1 # Input value increment between elements - LutInt = 0 # Interpolation method - L1 = 0.5 # Lookup table elements... - L2 = 1.5 - L3 = 1.5 - L4 = 2.5 - L5 = 2.5 - L6 = 3.5 - L7 = 3.5 - L8 = 4.5 - End LutMap - MapB = # Second component Mapping - Begin LutMap # Map 1-d coordinates using a lookup table - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Nlut = 8 # Number of lookup table elements - Start = 1 # Input value at first element -# Incr = 1 # Input value increment between elements - LutInt = 0 # Interpolation method - L1 = 0.21106114 # Lookup table elements... - L2 = 0.21076437 - L3 = 2e-06 - L4 = 2.2e-06 - L5 = 5e-07 - L6 = 6.5e-07 - L7 = 1.24e-09 - L8 = 2.48e-09 - End LutMap - End CmpMap - End CmpMap - MapB = # Second component Mapping - Begin CmpMap # Compound Mapping - Nin = 1 # Number of input coordinates - IsSimp = 1 # Mapping has been simplified - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin LutMap # Map 1-d coordinates using a lookup table - Nin = 1 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Nlut = 8 # Number of lookup table elements - Start = 1 # Input value at first element -# Incr = 1 # Input value increment between elements - LutInt = 0 # Interpolation method - L1 = 0 # Lookup table elements... - L2 = 1 - L3 = 1 - L4 = 2 - L5 = 2 - L6 = 3 - L7 = 3 - L8 = 4 - End LutMap - MapB = # Second component Mapping - Begin LutMap # Map 1-d coordinates using a lookup table - Nin = 1 # Number of input coordinates - Invert = 0 # Mapping not inverted - Inv = 0 # Inverse transformation not defined - IsA Mapping # Mapping between coordinate systems - Nlut = 8 # Number of lookup table elements - Start = 1 # Input value at first element -# Incr = 1 # Input value increment between elements - LutInt = 0 # Interpolation method - L1 = 1997.84512 # Lookup table elements... - L2 = 1997.84631 - L3 = 1993.28451 - L4 = 1993.28456 - L5 = 2001.59234 - L6 = 2001.59239 - L7 = 2002.18265 - L8 = 2002.18301 - End LutMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap diff --git a/ast/ast_tester/stcschan-test1-doc3-props.ast b/ast/ast_tester/stcschan-test1-doc3-props.ast deleted file mode 100644 index 4ab41aa..0000000 --- a/ast/ast_tester/stcschan-test1-doc3-props.ast +++ /dev/null @@ -1,126 +0,0 @@ -Begin KeyMap # Map of key/value pairs - MapSz = 16 # Size of hash table - Key1 = "REDSHIFT_PROPS" # Item name - Typ1 = 4 # Item data type (AST Object) - Val1 = # Item value - Begin KeyMap # Map of key/value pairs - MapSz = 16 # Size of hash table - Key1 = "PIXSIZE" # Item name - Typ1 = 3 # Item data type (string) - Val1 = "0.3" # Item value - Key2 = "ID" # Item name - Typ2 = 3 # Item data type (string) - Val2 = "RedshiftInterval" # Item value - Key3 = "REFPOS" # Item name - Typ3 = 3 # Item data type (string) - Val3 = "BARYCENTER" # Item value - Key4 = "HILIMIT" # Item name - Typ4 = 3 # Item data type (string) - Val4 = "2300.0" # Item value - Key5 = "TYPE" # Item name - Typ5 = 3 # Item data type (string) - Val5 = "VELOCITY" # Item value - Key6 = "RESOLUTION" # Item name - Typ6 = 3 # Item data type (string) - Val6 = "0.7" # Item value - Key7 = "DOPPLERDEF" # Item name - Typ7 = 3 # Item data type (string) - Val7 = "OPTICAL" # Item value - Key8 = "REDSHIFT" # Item name - Typ8 = 3 # Item data type (string) - Val8 = "300.0" # Item value - Key9 = "LOLIMIT" # Item name - Typ9 = 3 # Item data type (string) - Val9 = "200.0" # Item value - End KeyMap - Key2 = "SPACE_PROPS" # Item name - Typ2 = 4 # Item data type (AST Object) - Val2 = # Item value - Begin KeyMap # Map of key/value pairs - MapSz = 16 # Size of hash table - Key1 = "SIZE" # Item name - Typ1 = 3 # Item data type (string) - Val1 = "0.000333 0.000278" # Item value - Key2 = "FRAME" # Item name - Typ2 = 3 # Item data type (string) - Val2 = "ICRS" # Item value - Key3 = "PIXSIZE" # Item name - Typ3 = 3 # Item data type (string) - Val3 = "0.000083 0.000083" # Item value - Key4 = "ID" # Item name - Typ4 = 3 # Item data type (string) - Val4 = "Circle" # Item value - Key5 = "REFPOS" # Item name - Typ5 = 3 # Item data type (string) - Val5 = "GEOCENTER" # Item value - Key6 = "CENTRE" # Item name - Typ6 = 3 # Item data type (string) - Val6 = "179.0 -11.5" # Item value - Key7 = "RESOLUTION" # Item name - Typ7 = 3 # Item data type (string) - Val7 = "0.001778" # Item value - Key8 = "POSITION" # Item name - Typ8 = 3 # Item data type (string) - Val8 = "179.0 -11.5" # Item value - Key9 = "RADIUS" # Item name - Typ9 = 3 # Item data type (string) - Val9 = "0.5" # Item value - Key10 = "ERROR" # Item name - Typ10 = 3 # Item data type (string) - Val10 = "0.000889" # Item value - End KeyMap - Key3 = "SPECTRAL_PROPS" # Item name - Typ3 = 4 # Item data type (AST Object) - Val3 = # Item value - Begin KeyMap # Map of key/value pairs - MapSz = 16 # Size of hash table - Key1 = "ID" # Item name - Typ1 = 3 # Item data type (string) - Val1 = "Spectral" # Item value - Key2 = "SPECTRAL" # Item name - Typ2 = 3 # Item data type (string) - Val2 = "1420.4" # Item value - Key3 = "REFPOS" # Item name - Typ3 = 3 # Item data type (string) - Val3 = "BARYCENTER" # Item value - Key4 = "UNIT" # Item name - Typ4 = 3 # Item data type (string) - Val4 = "MHz" # Item value - Key5 = "RESOLUTION" # Item name - Typ5 = 3 # Item data type (string) - Val5 = "10.0" # Item value - End KeyMap - Key4 = "TIME_PROPS" # Item name - Typ4 = 4 # Item data type (AST Object) - Val4 = # Item value - Begin KeyMap # Map of key/value pairs - MapSz = 16 # Size of hash table - Key1 = "PIXSIZE" # Item name - Typ1 = 3 # Item data type (string) - Val1 = "1024.0" # Item value - Key2 = "ID" # Item name - Typ2 = 3 # Item data type (string) - Val2 = "TimeInterval" # Item value - Key3 = "START" # Item name - Typ3 = 3 # Item data type (string) - Val3 = "1996-01-01T00:00:00" # Item value - Key4 = "TIME" # Item name - Typ4 = 3 # Item data type (string) - Val4 = "MJD 50814.0" # Item value - Key5 = "REFPOS" # Item name - Typ5 = 3 # Item data type (string) - Val5 = "GEOCENTER" # Item value - Key6 = "RESOLUTION" # Item name - Typ6 = 3 # Item data type (string) - Val6 = "0.8" # Item value - Key7 = "STOP" # Item name - Typ7 = 3 # Item data type (string) - Val7 = "1996-01-01T00:30:00" # Item value - Key8 = "TIMESCALE" # Item name - Typ8 = 3 # Item data type (string) - Val8 = "TT" # Item value - Key9 = "ERROR" # Item name - Typ9 = 3 # Item data type (string) - Val9 = "1.2" # Item value - End KeyMap -End KeyMap diff --git a/ast/ast_tester/stcschan-test1-doc3.ast b/ast/ast_tester/stcschan-test1-doc3.ast deleted file mode 100644 index 0758ca7..0000000 --- a/ast/ast_tester/stcschan-test1-doc3.ast +++ /dev/null @@ -1,272 +0,0 @@ - Begin Prism # Region extrusion into higher dimensions -# Title = "5-d compound coordinate system" # Title of coordinate system -# Naxes = 5 # Number of coordinate axes -# Domain = "TIME-SKY-SPECTRUM-REDSHIFT" # Coordinate system domain -# Epoch = 1995.9986310746 # Julian epoch of observation -# Lbl1 = "Modified Julian Date offset from 1996-01-01 " # Label for axis 1 -# Lbl2 = "Right ascension" # Label for axis 2 -# Lbl3 = "Declination" # Label for axis 3 -# Lbl4 = "Frequency" # Label for axis 4 -# Lbl5 = "Optical velocity" # Label for axis 5 -# System = "Compound" # Coordinate system type -# Uni1 = "d" # Units for axis 1 (day) -# Uni2 = "hh:mm:ss.s" # Units for axis 2 -# Uni3 = "ddd:mm:ss" # Units for axis 3 -# Uni4 = "MHz" # Units for axis 4 -# Uni5 = "km/s" # Units for axis 5 -# Dir2 = 0 # Plot axis 2 in reverse direction - IsA Frame # Coordinate system description - Adapt = 1 # Region adapts to coord sys changes - Frm = # Coordinate system - Begin CmpFrame # Compound coordinate system description -# Title = "5-d compound coordinate system" # Title of coordinate system -# Naxes = 5 # Number of coordinate axes -# Domain = "TIME-SKY-SPECTRUM-REDSHIFT" # Coordinate system domain -# Lbl1 = "Modified Julian Date offset from 1996-01-01 " # Label for axis 1 -# Lbl2 = "Right ascension" # Label for axis 2 -# Lbl3 = "Declination" # Label for axis 3 -# Lbl4 = "Frequency" # Label for axis 4 -# Lbl5 = "Optical velocity" # Label for axis 5 -# Uni1 = "d" # Units for axis 1 (day) -# Uni2 = "hh:mm:ss.s" # Units for axis 2 -# Uni3 = "ddd:mm:ss" # Units for axis 3 -# Uni4 = "MHz" # Units for axis 4 -# Uni5 = "km/s" # Units for axis 5 -# Dir2 = 0 # Plot axis 2 in reverse direction - IsA Frame # Coordinate system description - FrameA = # First component Frame - Begin CmpFrame # Compound coordinate system description - FrameA = # First component Frame - Begin CmpFrame # Compound coordinate system description - FrameA = # First component Frame - Begin TimeFrame # Description of time coordinate system - Naxes = 1 # Number of coordinate axes - Epoch = 1995.9986310746 # Julian epoch of observation - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - End Axis - IsA Frame # Coordinate system description - TmScl = "TT" # Time scale - TmOrg = 50083 # Time offset - End TimeFrame - FrameB = # Second component Frame - Begin SkyFrame # Description of celestial coordinate system - Naxes = 2 # Number of coordinate axes - Epoch = 1995.9986310746 # Julian epoch of observation - System = "ICRS" # Coordinate system type - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - End SkyFrame - End CmpFrame - FrameB = # Second component Frame - Begin SpecFrame # Description of spectral coordinate system - Naxes = 1 # Number of coordinate axes - Epoch = 1995.9986310746 # Julian epoch of observation - System = "FREQ" # Coordinate system type - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Unit = "MHz" # Axis units - End Axis - IsA Frame # Coordinate system description - SoR = "Barycentric" # Standard of rest - UFreq = "MHz" # Preferred units for frequency - End SpecFrame - End CmpFrame - FrameB = # Second component Frame - Begin SpecFrame # Description of spectral coordinate system - Naxes = 1 # Number of coordinate axes - Domain = "REDSHIFT" # Coordinate system domain - Epoch = 1995.9986310746 # Julian epoch of observation - System = "VOPT" # Coordinate system type - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Unit = "km/s" # Axis units - End Axis - IsA Frame # Coordinate system description - SoR = "Barycentric" # Standard of rest - UVopt = "km/s" # Preferred units for optical velocity - End SpecFrame - End CmpFrame - RegAxes = 5 # Number of axes spanned by the Region - IsA Region # An area within a coordinate system - RegionA = # First component Region - Begin Prism # Region extrusion into higher dimensions -# Title = "4-d compound coordinate system" # Title of coordinate system -# Naxes = 4 # Number of coordinate axes -# Domain = "TIME-SKY-SPECTRUM" # Coordinate system domain -# Epoch = 1995.9986310746 # Julian epoch of observation -# Lbl1 = "Modified Julian Date offset from 1996-01-01 " # Label for axis 1 -# Lbl2 = "Right ascension" # Label for axis 2 -# Lbl3 = "Declination" # Label for axis 3 -# Lbl4 = "Frequency" # Label for axis 4 -# System = "Compound" # Coordinate system type -# Uni1 = "d" # Units for axis 1 (day) -# Uni2 = "hh:mm:ss.s" # Units for axis 2 -# Uni3 = "ddd:mm:ss" # Units for axis 3 -# Uni4 = "MHz" # Units for axis 4 -# Dir2 = 0 # Plot axis 2 in reverse direction - IsA Frame # Coordinate system description - Adapt = 1 # Region adapts to coord sys changes - RegAxes = 4 # Number of axes spanned by the Region - IsA Region # An area within a coordinate system - RegionA = # First component Region - Begin Prism # Region extrusion into higher dimensions -# Title = "3-d compound coordinate system" # Title of coordinate system -# Naxes = 3 # Number of coordinate axes -# Domain = "TIME-SKY" # Coordinate system domain -# Epoch = 1995.9986310746 # Julian epoch of observation -# Lbl1 = "Modified Julian Date offset from 1996-01-01 " # Label for axis 1 -# Lbl2 = "Right ascension" # Label for axis 2 -# Lbl3 = "Declination" # Label for axis 3 -# System = "Compound" # Coordinate system type -# Uni1 = "d" # Units for axis 1 (day) -# Uni2 = "hh:mm:ss.s" # Units for axis 2 -# Uni3 = "ddd:mm:ss" # Units for axis 3 -# Dir2 = 0 # Plot axis 2 in reverse direction - IsA Frame # Coordinate system description - Adapt = 1 # Region adapts to coord sys changes - RegAxes = 3 # Number of axes spanned by the Region - IsA Region # An area within a coordinate system - RegionA = # First component Region - Begin Box # Axis intervals -# Title = "Modified Julian Date [TT] offset from 1996-01-01 00:00:00" # Title of coordinate system -# Naxes = 1 # Number of coordinate axes -# Domain = "TIME" # Coordinate system domain -# Epoch = 1995.9986310746 # Julian epoch of observation -# Lbl1 = "Modified Julian Date offset from 1996-01-01 " # Label for axis 1 -# System = "MJD" # Coordinate system type -# Uni1 = "d" # Units for axis 1 (day) - IsA Frame # Coordinate system description - Closed = 1 # Boundary is inside - Adapt = 1 # Region adapts to coord sys changes - Points = # Points defining the shape - Begin PointSet # Container for a set of points - Npoint = 2 # Number of points - Ncoord = 1 # Number of coordinates per point - X1 = 0.0104166666678793 # Coordinate values... - X2 = 0.0208333333357587 - End PointSet - Unc = # Region defining positional uncertainties. - Begin Box # Axis intervals -# Title = "Modified Julian Date [TT] offset from 1996-01-01 00:00:00" # Title of coordinate system -# Naxes = 1 # Number of coordinate axes -# Domain = "TIME" # Coordinate system domain -# Epoch = 1995.9986310746 # Julian epoch of observation -# Lbl1 = "Modified Julian Date offset from 1996-01-01 " # Label for axis 1 -# System = "MJD" # Coordinate system type -# Uni1 = "d" # Units for axis 1 (day) - IsA Frame # Coordinate system description - Adapt = 1 # Region adapts to coord sys changes - Points = # Points defining the shape - Begin PointSet # Container for a set of points - Npoint = 2 # Number of points - Ncoord = 1 # Number of coordinates per point - X1 = 0.0104166666678793 # Coordinate values... - X2 = 0.0104305555567682 - End PointSet - IsA Region # An area within a coordinate system - End Box - IsA Region # An area within a coordinate system - End Box - RegionB = # Second component Region - Begin Circle # Circular or spherical region -# Title = "ICRS coordinates" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Epoch = 1995.9986310746 # Julian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# System = "ICRS" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - IsA Frame # Coordinate system description - Adapt = 1 # Region adapts to coord sys changes - Points = # Points defining the shape - Begin PointSet # Container for a set of points - Npoint = 2 # Number of points - Ncoord = 2 # Number of coordinates per point - X1 = 3.12413936106985 # Coordinate values... - X2 = -0.200712863979348 - X3 = 3.13304478740064 - X4 = -0.200712708456374 - End PointSet - Unc = # Region defining positional uncertainties. - Begin Box # Axis intervals -# Title = "ICRS coordinates" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Epoch = 1995.9986310746 # Julian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# System = "ICRS" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - IsA Frame # Coordinate system description - Adapt = 1 # Region adapts to coord sys changes - Points = # Points defining the shape - Begin PointSet # Container for a set of points - Npoint = 2 # Number of points - Ncoord = 2 # Number of coordinates per point - X1 = 3.12413936106985 # Coordinate values... - X2 = -0.200712863979348 - X3 = 3.12415519494 - X4 = -0.200697348002298 - End PointSet - IsA Region # An area within a coordinate system - End Box - IsA Region # An area within a coordinate system - End Circle - End Prism - RegionB = # Second component Region - Begin PointList # Collection of points -# Title = "Frequency (Barycentric)" # Title of coordinate system -# Naxes = 1 # Number of coordinate axes -# Domain = "SPECTRUM" # Coordinate system domain -# Epoch = 1995.9986310746 # Julian epoch of observation -# Lbl1 = "Frequency" # Label for axis 1 -# System = "FREQ" # Coordinate system type -# Uni1 = "MHz" # Units for axis 1 - IsA Frame # Coordinate system description - Adapt = 1 # Region adapts to coord sys changes - Points = # Points defining the shape - Begin PointSet # Container for a set of points - Npoint = 1 # Number of points - Ncoord = 1 # Number of coordinates per point - X1 = 1420.4 # Coordinate values... - End PointSet - IsA Region # An area within a coordinate system - End PointList - End Prism - RegionB = # Second component Region - Begin Box # Axis intervals -# Title = "Optical velocity (Barycentric), rest frequency = 100000 GHz" # Title of coordinate system -# Naxes = 1 # Number of coordinate axes -# Domain = "REDSHIFT" # Coordinate system domain -# Epoch = 1995.9986310746 # Julian epoch of observation -# Lbl1 = "Optical velocity" # Label for axis 1 -# System = "VOPT" # Coordinate system type -# Uni1 = "km/s" # Units for axis 1 - IsA Frame # Coordinate system description - Closed = 1 # Boundary is inside - Adapt = 1 # Region adapts to coord sys changes - Points = # Points defining the shape - Begin PointSet # Container for a set of points - Npoint = 2 # Number of points - Ncoord = 1 # Number of coordinates per point - X1 = 1250 # Coordinate values... - X2 = 2300 - End PointSet - IsA Region # An area within a coordinate system - End Box - End Prism diff --git a/ast/ast_tester/testchannel.f b/ast/ast_tester/testchannel.f deleted file mode 100644 index ac69b2c..0000000 --- a/ast/ast_tester/testchannel.f +++ /dev/null @@ -1,88 +0,0 @@ - program testrate - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - - integer status, ch, sf, sf2 - character buff*50 - status = sai__ok - - call err_begin( status ) - call ast_begin( status ) - - - call ast_tunec( "hrdel", AST__TUNULLC, buff, status ) - if( buff .ne. '%-%^50+%s70+h%+' .and. status .eq. sai__ok ) then - call stopit( 0, status ) - endif - call ast_tunec( "hrdel", "junk", buff, status ) - call ast_tunec( "hrdel", AST__TUNULLC, buff, status ) - if( buff .ne. 'junk' .and. status .eq. sai__ok ) then - call stopit( -1, status ) - endif - - sf = ast_skyframe( ' ', status ) - ch = ast_channel( AST_NULL, AST_NULL, 'SinkFile=./fred.txt', - : status ) - if( ast_write( ch, sf, status ) .ne. 1 ) then - call stopit( 1, status ) - end if - - call ast_set( ch, 'SourceFile=./fred.txt', status ) - if( status .eq. SAI__OK ) then - sf2 = ast_read( ch, status ) - if( status .eq. AST__RDERR ) then - call err_annul( status ) - else - call stopit( 7, status ) - end if - end if - - call ast_clear( ch, 'SinkFile', status ) - - call ast_set( ch, 'SourceFile=./fred.txt', status ) - sf2 = ast_read( ch, status ) - if( sf2 .eq. AST__NULL ) call stopit( 2, status ) - if( .not. ast_equal( sf, sf2, status ) ) then - call stopit( 3, status ) - end if - - - call ast_set( ch, 'SinkFile=./fred2.txt', status ) - if( ast_write( ch, sf, status ) .ne. 1 ) then - call stopit( 4, status ) - end if - call ast_clear( ch, 'SinkFile', status ) - - call ast_set( ch, 'SourceFile=./fred2.txt', status ) - sf2 = ast_read( ch, status ) - if( sf2 .eq. AST__NULL ) call stopit( 5, status ) - if( .not. ast_equal( sf, sf2, status ) ) then - call stopit( 6, status ) - end if - - - call ast_end( status ) - call err_end( status ) - - - - if( status .eq. sai__ok ) then - write(*,*) 'All Channel tests passed' - else - write(*,*) 'Channel tests failed' - end if - - end - - - subroutine stopit( i, status ) - implicit none - include 'SAE_PAR' - integer i, status - if( status .eq. sai__ok ) then - write( *,* ) 'Error ',i - status = sai__error - end if - end diff --git a/ast/ast_tester/testchebymap.f b/ast/ast_tester/testchebymap.f deleted file mode 100644 index b0a0bba..0000000 --- a/ast/ast_tester/testchebymap.f +++ /dev/null @@ -1,475 +0,0 @@ - program testchebymap - implicit none - - include 'SAE_PAR' - include 'AST_PAR' - include 'PRM_PAR' - - integer status, lstat, cm, cm2, cm3, i, j, nco - double precision lbnd( 2 ), ubnd( 2 ), dval, lb, ub, xl(2), xu(2) - double precision tlbnd( 2 ), tubnd( 2 ), dlbnd( 2 ), dubnd( 2 ) - - double precision coeffs_1( 4*3 ), xin( 5 ), xout( 5 ), xrec( 5 ), - : yrec( 5 ), coeffs_4(4*4 ), - : work( 5 ), coeffs_2( 2*3 ), coeffs_3( 4*5 ), - : yin(5), yout(5), xi, yi, xv, yv, y, a, x, - : cofs( 100 ) - - -C f(x) = 1.5*T0(x') - 1.0*T2(x') + 2.0*T3(x') - 1.3*T4(x') - data coeffs_1 /1.5D0, 1.0D0, 0.0D0, - : -1.0D0, 1.0D0, 2.0D0, - : 2.0D0, 1.0D0, 3.0D0, - : 1.3D0, 1.0D0, 4.0D0 / - -C f(x) = 1.0*T0(x') - 2.0*T1(x') - data coeffs_2 /1.0D0, 1.0D0, 0.0D0, - : -2.0D0, 1.0D0, 1.0D0 / - - -C fx(x,y) = 1.0*T0(x')*T0(y') - 2.0*T1(x')*T2(y') + T1(y') -C fy(x,y) = 1.5*T0(x')*T0(y') - 2.5*T1(x')*T2(y') - data coeffs_3 /1.0D0, 1.0D0, 0.0D0, 0.0D0, - : -2.0D0, 1.0D0, 1.0D0, 2.0D0, - : 1.0D0, 1.0D0, 0.0D0, 1.0D0, - : 1.5D0, 2.0D0, 0.0D0, 0.0D0, - : -2.5D0, 2.0D0, 1.0D0, 2.0D0/ - -C fx(x,y) = T1(x') + T1(y') -C fy(x,y) = T1(x') - T1(y') -C -C This has the property that the coeffs of the inverse transformation are -C equal to the coeffs of the forward transformation. - data coeffs_4 /1.0D0, 1.0D0, 1.0D0, 0.0D0, - : 1.0D0, 1.0D0, 0.0D0, 1.0D0, - : 1.0D0, 2.0D0, 1.0D0, 0.0D0, - : -1.0D0, 2.0D0, 0.0D0, 1.0D0 / - - - status = sai__ok - call ast_begin( status ) - -C One-dimensional ChebyMaps, order 1: a constant equal to 1.5 - lbnd( 1 ) = -1.0D0 - lbnd( 2 ) = -1.0D0 - ubnd( 1 ) = 1.0D0 - ubnd( 2 ) = 1.0D0 - - cm = ast_chebymap( 1, 1, 1, coeffs_1, 0, 0.0D0, lbnd, ubnd, 1.0D0, - : 1.0D0, ' ', status ) - - xin( 1 ) = -1.0D0 - xin( 2 ) = -0.5D0 - xin( 3 ) = 0.0D0 - xin( 4 ) = 0.5D0 - xin( 5 ) = 1.0D0 - - call ast_tran1( cm, 5, xin, .true., xout, status ) - do i = 1, 5 - if( xout( i ) .ne. 1.5D0 ) call stopit( 0, status ) - end do - -C One-dimensional ChebyMaps, order 3: 2.5 - 2*x*x - cm = ast_chebymap( 1, 1, 2, coeffs_1, 0, 0.0D0, lbnd, ubnd, 1.0D0, - : 1.0D0, ' ', status ) - call ast_tran1( cm, 5, xin, .true., xout, status ) - do i = 1, 5 - if( xout( i ) .ne. 2.5D0 - 2.0D0*xin( i )**2 ) - : call stopit( 1, status ) - end do - -C One-dimensional ChebyMaps, order 4: 2.5 - 6*x - 2*x*x + 8*x*x*x - cm = ast_chebymap( 1, 1, 3, coeffs_1, 0, 0.0D0, lbnd, ubnd, 1.0D0, - : 1.0D0, ' ', status ) - call ast_tran1( cm, 5, xin, .true., xout, status ) - do i = 1, 5 - dval = 2.5D0-6.0D0*xin(i)-2.0D0*xin(i)**2+8.0D0*xin(i)**3 - if( xout( i ) .ne. dval ) call stopit( 2, status ) - end do - -C One-dimensional ChebyMaps, order 5 - cm = ast_chebymap( 1, 1, 4, coeffs_1, 0, 0.0D0, lbnd, ubnd, 1.0D0, - : 1.0D0, ' ', status ) - call ast_tran1( cm, 5, xin, .true., xout, status ) - - do i = 1, 5 - work( 1 ) = 1.0D0 - work( 2 ) = xin( i ) - do j = 3, 5 - work( j ) = 2.0D0 * xin( i ) * work( j - 1 ) - : - work( j - 2 ) - end do - - if( 1.5D0*work(1) - 1.0D0*work(3) + - : 2.0D0*work(4) + 1.3D0*work(5) .ne. - : xout( i ) ) call stopit( 3, status ) - - end do - -C Check the IterInverse attribute is zero. - if( ast_getl( cm, 'IterInverse', status ) ) then - call stopit( 4, status ) - end if - -c The astPolyTran method on a 1-dimensional ChebyMaps, order 2: 1 - 2*x - cm = ast_chebymap( 1, 1, 2, coeffs_2, 0, 0.0D0, lbnd, ubnd, 1.0D0, - : 1.0D0, ' ', status ) - cm2 = ast_polytran( cm, .false., 0.01D0, 0.01D0, 5, lbnd, - : ubnd, status ) - if( cm2 .eq. AST__NULL ) then - call stopit( 5, status ) - else - xin( 1 ) = -1.0D0 - xin( 2 ) = -0.5D0 - xin( 3 ) = 0.0D0 - xin( 4 ) = 0.5D0 - xin( 5 ) = 1.0D0 - call ast_tran1( cm2, 5, xin, .true., xout, status ) - call ast_tran1( cm2, 5, xout, .false., xrec, status ) - do i = 1, 5 - if( abs( xrec(i) - xin(i) ) .gt. 1.0D-3*abs( xin(i) ) ) - : call stopit( 6, status ) - end do - - call ast_chebydomain( cm2, .false., dlbnd, dubnd, status ) - if( dlbnd(1) .ne. -1.0D0 ) - : call stopit( 501, status ) - if( dubnd(1) .ne. 3.0D0 ) - : call stopit( 502, status ) - - call ast_polycoeffs( cm2, .false., 100, cofs, nco, status ) - if( nco .ne. 1 ) - : call stopit( 503, status ) - - if( abs( cofs(1) + 1.0D0 ) .gt. 1.0D-10 ) - : call stopit( 504, status ) - if( abs( cofs(2) - 1.0D0 ) .gt. 1.0D-10 ) - : call stopit( 505, status ) - if( abs( cofs(3) - 1.0D0 ) .gt. 1.0D-10 ) - : call stopit( 506, status ) - - end if - -c The astPolyTran method on a 1-dimensional ChebyMaps, order 5. - lbnd( 1 ) = -100.0D0 - ubnd( 1 ) = 100.0D0 - cm = ast_chebymap( 1, 1, 4, coeffs_1, 0, 0.0D0, lbnd, ubnd, 1.0D0, - : 1.0D0, ' ', status ) - cm2 = ast_polytran( cm, .false., 0.01D0, 0.01D0, 10, -5.0D0, - : 50.0D0, status ) - - if( cm2 .eq. AST__NULL ) then - call stopit( 7, status ) - else - xin(1) = 0.0D0; - xin(2) = 10.0D0; - xin(3) = 20.0D0; - xin(4) = 30.0D0; - xin(5) = 40.0D0; - call ast_tran1( cm2, 5, xin, .true., xout, status ) - call ast_tran1( cm2, 5, xout, .false., xrec, status ) - - do i = 1, 5 - if( abs( xrec( i ) - xin( i ) ) .gt. 0.01D0 ) - : call stopit( 8, status ) - end do - end if - -c ast_equal and ast_copy - cm3 = ast_copy( cm2, status ) - if( .not. ast_equal( cm2, cm3, status ) ) then - call stopit( 9, status ) - end if - -c astDump and astLoadChebyMap - call checkdump( cm2, status ) - - -c Simple 2d ChebyMap. -C fx(x,y) = T1(x') + T1(y') -C fy(x,y) = T1(x') - T1(y') - - lbnd(1) = -1.0D0 - lbnd(2) = -1.0D0 - ubnd(1) = 1.0D0 - ubnd(2) = 1.0D0 - - cm = ast_chebymap( 2, 2, 4, coeffs_4, 0, 0.0D0, lbnd, ubnd, - : 1.0D0, 1.0D0, ' ', status ) - - cm2 = ast_copy( cm, status ) - call ast_invert( cm2, status ) - cm3 = ast_simplify( ast_cmpmap( cm, cm2, .TRUE., ' ', status ), - : status ) - if( .not. ast_isaunitmap( cm3, status ) ) then - call stopit( 1000, status ) - end if - - xin(1) = 0.5D0 - xin(2) = 0.0D0 - xin(3) = -0.5D0 - xin(4) = 0.0D0 - - yin(1) = 0.0D0 - yin(2) = 0.5D0 - yin(3) = 0.0D0 - yin(4) = -0.5D0 - - call ast_tran2( cm, 4, xin, yin, .true., xout, yout, status ) - do i = 1, 4 - xv = xin(i) + yin(i) - yv = xin(i) - yin(i) - - if( abs( xout(i) - xv ) .gt. 1.0D-6*abs(xv) .or. - : abs( yout(i) - yv ) .gt. 1.0D-6*abs(yv) ) then - call stopit( 101, status ) - end if - end do - - cm2 = ast_polytran( cm, .false., 0.01D0, 0.01D0, 10, lbnd, - : ubnd, status ) - - if( cm2 .eq. AST__NULL ) then - call stopit( 102, status ) - else - call ast_tran2( cm2, 4, xout, yout, .false., xrec, yrec, - : status ) - do i = 1, 4 - if( abs( xrec(i) - xin(i) ) .gt. 0.01D0 .or. - : abs( yrec(i) - yin(i) ) .gt. 0.01D0 ) then - call stopit( 103, status ) - end if - end do - end if - - call ast_polycoeffs( cm2, .false., 100, cofs, nco, status ) - if( nco .ne. 4 ) then - call stopit( 104, status ) - else - do i = 1, 16 - if( abs( cofs(i) - coeffs_4(i) ) .gt. 0.01D0 ) then - call stopit( 105, status ) - end if - end do - end if - - call ast_chebydomain( cm2, .false., dlbnd, dubnd, status ) - - if( dlbnd(1) .ne. -2.0D0 ) then - call stopit( 106, status ) - else if( dlbnd(2) .ne. -2.0D0 ) then - call stopit( 107, status ) - else if( dubnd(1) .ne. 2.0D0 ) then - call stopit( 108, status ) - else if( dubnd(2) .ne. 2.0D0 ) then - call stopit( 109, status ) - end if - -* 2-dimensional ChebyMaps: forward transformation - lbnd(1) = 0.0D0 - lbnd(2) = 0.0D0 - ubnd(1) = 10.0D0 - ubnd(2) = 10.0D0 - - cm = ast_chebymap( 2, 2, 5, coeffs_3, 0, 0.0D0, lbnd, ubnd, - : 1.0D0, 1.0D0, ' ', status ) - - xin(1) = 0.0D0 - xin(2) = 2.0D0 - xin(3) = 6.0D0 - xin(4) = 10.0D0 - - yin(1) = 2.0D0 - yin(2) = 5.0D0 - yin(3) = 8.0D0 - yin(4) = 0.0D0 - - call ast_tran2( cm, 4, xin, yin, .true., xout, yout, status ) - do i = 1, 4 - xi = 2.0D0*( xin(i) - lbnd(1) )/( ubnd(1) - lbnd(1) ) - 1.0D0 - yi = 2.0D0*( yin(i) - lbnd(2) )/( ubnd(2) - lbnd(2) ) - 1.0D0 - - xv = 1 - 2*xi*(2*yi**2 - 1) + yi - yv = 1.5 - 2.5*xi*(2*yi**2 - 1) - - if( abs( xout(i) - xv ) .gt. 1.0D-6*abs(xv) .or. - : abs( yout(i) - yv ) .gt. 1.0D-6*abs(yv) ) then - call stopit( 10, status ) - end if - end do - - -* 2-dimensional ChebyMaps: fitted inverse transformation - tlbnd(1) = 4.0D0 - tlbnd(2) = 4.0D0 - tubnd(1) = 6.0D0 - tubnd(2) = 6.0D0 - cm2 = ast_polytran( cm, .false., 0.01D0, 0.01D0, 10, tlbnd, - : tubnd, status ) - - if( cm2 .eq. AST__NULL ) then - call stopit( 11, status ) - else - xin(1) = 4.0D0 - xin(2) = 4.5D0 - xin(3) = 5.0D0 - xin(4) = 5.5D0 - - yin(1) = 6.0D0 - yin(2) = 5.5D0 - yin(3) = 5.0D0 - yin(4) = 4.5D0 - - call ast_tran2( cm2, 4, xin, yin, .true., xout, yout, status ) - call ast_tran2( cm2, 4, xout, yout, .false., xrec, yrec, - : status ) - do i = 1, 4 - if( abs( xrec(i) - xin(i) ) .gt. 0.01D0 .or. - : abs( yrec(i) - yin(i) ) .gt. 0.01D0 ) then - call stopit( 12, status ) - end if - end do - end if - - -* Test recovery of coeffs - call ast_polycoeffs( cm2, .true., 0, 0.0D0, nco, status ) - if( nco .ne. 5 ) then - call stopit( 13, status ) - endif - - call ast_polycoeffs( cm2, .true., 100, cofs, nco, status ) - if( nco .ne. 5 ) then - call stopit( 14, status ) - else - do i = 1, 20 - if( cofs( i ) .ne. coeffs_3( i ) ) then - call stopit( 15, status ) - end if - end do - endif - - call ast_polycoeffs( cm2, .false., 0, 0.0D0, nco, status ) - if( nco .ne. 9 ) then - call stopit( 16, status ) - endif - - call ast_polycoeffs( cm2, .false., 100, cofs, nco, status ) - - if( nco .ne. 9 ) then - call stopit( 17, status ) - else if( abs( cofs( 1 ) - 5.0000000000000018D0 ) .gt. - : 1.0E-6 ) then - call stopit( 18, status ) - else if( abs( cofs( 13 ) - 0.35096188953505458D0 ) .gt. - : 1.0E-6 ) then - call stopit( 19, status ) - else if( cofs( 15 ) .ne. 2.0D0 ) then - call stopit( 20, status ) - end if - -* Test recovery of domain bounding box - call ast_chebydomain( cm, .true., dlbnd, dubnd, status ) - - if( dlbnd(1) .ne. lbnd(1) ) then - call stopit( 21, status ) - else if( dlbnd(2) .ne. lbnd(2) ) then - call stopit( 22, status ) - else if( dubnd(1) .ne. ubnd(1) ) then - call stopit( 23, status ) - else if( dubnd(2) .ne. ubnd(2) ) then - call stopit( 24, status ) - end if - - call ast_chebydomain( cm, .false., dlbnd, dubnd, status ) - - if( dlbnd(1) .ne. -2.0D0 ) then - call stopit( 25, status ) - else if( dlbnd(2) .ne. -1.0D0 ) then - call stopit( 26, status ) - else if( dubnd(1) .ne. 4.0D0 ) then - call stopit( 27, status ) - else if( dubnd(2) .ne. 4.0D0 ) then - call stopit( 28, status ) - end if - - - call ast_chebydomain( cm2, .true., dlbnd, dubnd, status ) - - if( dlbnd(1) .ne. lbnd(1) ) then - call stopit( 29, status ) - else if( dlbnd(2) .ne. lbnd(2) ) then - call stopit( 30, status ) - else if( dubnd(1) .ne. ubnd(1) ) then - call stopit( 31, status ) - else if( dubnd(2) .ne. ubnd(2) ) then - call stopit( 32, status ) - end if - - call ast_chebydomain( cm2, .false., dlbnd, dubnd, status ) - - if( abs( dlbnd(1) - 0.432 ) .gt. 1.0D-6 ) then - call stopit( 33, status ) - else if( abs( dlbnd(2) - 1.000816 ) .gt. 1.0D-6 ) then - call stopit( 34, status ) - else if( abs( dubnd(1) - 1.568D0 ) .gt. 1.0D-6 ) then - call stopit( 35, status ) - else if( abs( dubnd(2) - 1.9991836D0 ) .gt. 1.0D-6 ) then - call stopit( 36, status ) - end if - - - call ast_end( status ) - call ast_activememory( 'testchebymap' ); - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All ChebyMap tests passed' - else - write(*,*) 'ChebyMap tests failed' - end if - - end - - - subroutine stopit( i, status ) - implicit none - include 'SAE_PAR' - integer i, status - if( status .eq. sai__ok ) then - write( *,* ) 'Error ',i - status = sai__error - end if - end - - - subroutine checkdump( obj, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer obj, status, ch, result - - if( status .ne. sai__ok ) return - - ch = ast_channel( AST_NULL, AST_NULL, ' ', status ) - - call ast_set( ch, 'SinkFile=fred.tmp', status ) - if( ast_write( ch, obj, status ) .ne. 1 ) then - call stopit( -1, status ) - end if - call ast_clear( ch, 'SinkFile', status ) - - call ast_set( ch, 'SourceFile=fred.tmp', status ) - result = ast_read( ch, status ) - if( result .eq. ast__null ) then - call stopit( -2, status ) - end if - call ast_clear( ch, 'SourceFile', status ) - - if( .not. ast_equal( result, obj, status ) ) then - call ast_show( obj, status ) - call ast_show( result, status ) - call stopit( -3, status ) - end if - - end diff --git a/ast/ast_tester/testcmpmap.f b/ast/ast_tester/testcmpmap.f deleted file mode 100644 index bd3cad1..0000000 --- a/ast/ast_tester/testcmpmap.f +++ /dev/null @@ -1,149 +0,0 @@ - program testcmpmap - implicit none - - include 'AST_PAR' - include 'SAE_PAR' - - integer m1, m2, m3, m4, m5, status, i, in(7), out(7) - double precision x( 7 ), y(7), y2(7), matrix( 3 ) - - data matrix /-1.0D0, 1.0D0, 2.0D0 / - - status = sai__ok - call err_mark( status ) - call ast_begin( status ) - - - m1 = ast_UnitMap( 1, ' ', status ) - m2 = ast_ZoomMap( 2, 2.0D0, ' ', status ) - m3 = ast_MatrixMap( 3, 3, 1, matrix, ' ', status ) - m4 = ast_CmpMap( ast_CmpMap( m1, m2, .false., ' ', status ), m3, - : .false., ' ', status ) - - - in( 1 ) = 3 - in( 2 ) = 6 - in( 3 ) = 4 - call ast_mapsplit( m4, 3, in, out, m5, status ) - if( m5 .eq. AST__NULL ) then - call stopit( status, 'Error 1' ) - else if( ast_geti( m5, 'Nin', status ) .ne. 3 ) then - call stopit( status, 'Error 2' ) - else if( ast_geti( m5, 'Nout', status ) .ne. 3 ) then - call stopit( status, 'Error 3' ) - end if - - if( out( 1 ) .ne. 3 ) call stopit( status, 'Error 4' ) - if( out( 2 ) .ne. 4 ) call stopit( status, 'Error 5' ) - if( out( 3 ) .ne. 6 ) call stopit( status, 'Error 6' ) - - - call readobj( 'splittest1.ast', m1, status ) - in(1)= 1 - call ast_mapsplit( m1, 1, in, out, m2, status ) - if( m2 .ne. AST__NULL ) call stopit( status, 'Error 7' ) - - in(2)= 4 - in(3)= 2 - call ast_mapsplit( m1, 3, in, out, m2, status ) - if( m2 .eq. AST__NULL ) then - call stopit( status, 'Error 8' ) - else if( ast_geti( m2, 'Nin', status ) .ne. 3 ) then - call stopit( status, 'Error 9' ) - else if( ast_geti( m2, 'Nout', status ) .ne. 3 ) then - call stopit( status, 'Error 10' ) - end if - - - - x(1) = 1.0D0 - x(2) = 2.0D0 - x(3) = 4.0D0 - x(4) = 8.0D0 - call ast_trann( m1, 1,4, 1, x, .true., 4, 1, y, status ) - - x(1) = 1.0D0 - x(2) = 8.0D0 - x(3) = 2.0D0 - call ast_trann( m2, 1, 3, 1, x, .true., 3, 1, y2, status ) - - if( y2( 1 ) .ne. y( 1 ) ) then - call stopit( status, 'Error 11' ) - else if( y2( 2 ) .ne. y( 2 ) ) then - call stopit( status, 'Error 12' ) - else if( y2( 3 ) .ne. y( 4 ) ) then - call stopit( status, 'Error 13' ) - end if - - - - - - - - call ast_end( status ) - call err_rlse( status ) - -c call ast_activememory( 'testcmpmap' ) - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All cmpmap tests passed' - else - write(*,*) 'cmpmap tests failed' - end if - - end - - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - end - - - - subroutine readobj( file, iobj, status ) - implicit none - - include 'AST_PAR' - include 'SAE_PAR' - - external chsource - integer iobj, status, ch - character file*(*) - - open( 10, status='old', file=file ) - - ch = ast_channel( chsource, AST_NULL, ' ', status ) - iobj = ast_read( ch, status ) - call ast_annul( ch, status ) - - close( 10 ) - - end - - subroutine chsource( status ) - implicit none - - include 'AST_PAR' - include 'SAE_PAR' - - integer status - character line*200 - - read( 10, '(A)', end=99 ) line - - call ast_putline( line, len( line ), status ) - return - - 99 call ast_putline( line, -1, status ) - - end - diff --git a/ast/ast_tester/testconvert.c b/ast/ast_tester/testconvert.c deleted file mode 100644 index d28c318..0000000 --- a/ast/ast_tester/testconvert.c +++ /dev/null @@ -1,232 +0,0 @@ -#define astCLASS testconvert - -#include "ast_err.h" -#include "error.h" -#include "object.h" -#include "skyframe.h" -#include "specframe.h" -#include "cmpframe.h" -#include "frame.h" -#include "unitmap.h" -#include "permmap.h" - -int main(){ - int status_value = 0; - int *status = &status_value; - - AstFrameSet *fs; - - AstSkyFrame *sf = astSkyFrame( " ", status ); - AstSpecFrame *df = astSpecFrame( " ", status ); - AstCmpFrame *cf = astCmpFrame( df, sf, " ", status ); - AstFrame *bf = astFrame( 2, "Domain=SKY", status ); - AstFrame *target, *template; - - - fs = astConvert( bf, sf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), bf ) && astOK ) { - astError( AST__INTER, "Error 1\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), sf ) && astOK ) { - astError( AST__INTER, "Error 2\n", status ); - } else if( !astIsAUnitMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 3\n", status ); - } - } else { - astError( AST__INTER, "Error 4\n", status ); - } - - fs = astConvert( sf, bf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), sf ) && astOK ) { - astError( AST__INTER, "Error 5\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), bf ) && astOK ) { - astError( AST__INTER, "Error 6\n", status ); - } else if( !astIsAUnitMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 7\n", status ); - } - } else { - astError( AST__INTER, "Error 8\n", status ); - } - - - astSetDomain( bf, "NOTSKY" ); - fs = astConvert( bf, sf, " " ); - if( fs ) { - astShow( fs ); - astError( AST__INTER, "Error 9\n", status ); - } - - fs = astConvert( sf, bf, " " ); - if( fs ) { - astShow( fs ); - astError( AST__INTER, "Error 10\n", status ); - } - - astClearDomain( bf ); - - fs = astConvert( bf, sf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), bf ) && astOK ) { - astError( AST__INTER, "Error 11\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), sf ) && astOK ) { - astError( AST__INTER, "Error 12\n", status ); - } else if( !astIsAUnitMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 13\n", status ); - } - } else { - astError( AST__INTER, "Error 14\n", status ); - } - - fs = astConvert( sf, bf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), sf ) && astOK ) { - astError( AST__INTER, "Error 15\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), bf ) && astOK ) { - astError( AST__INTER, "Error 16\n", status ); - } else if( !astIsAUnitMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 17\n", status ); - } - } else { - astError( AST__INTER, "Error 18\n", status ); - } - - - fs = astConvert( bf, cf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), bf ) && astOK ) { - astError( AST__INTER, "Error 19\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), cf ) && astOK ) { - astError( AST__INTER, "Error 20\n", status ); - } else if( !astIsAPermMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 21\n", status ); - } - } else { - astError( AST__INTER, "Error 22\n", status ); - } - - fs = astConvert( cf, bf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), cf ) && astOK ) { - astError( AST__INTER, "Error 23\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), bf ) && astOK ) { - astError( AST__INTER, "Error 24\n", status ); - } else if( !astIsAPermMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 25\n", status ); - } - } else { - astError( AST__INTER, "Error 26\n", status ); - } - - - astSetDomain( bf, "NOTSKY" ); - fs = astConvert( bf, cf, " " ); - if( fs ) { - astShow( fs ); - astError( AST__INTER, "Error 27\n", status ); - } - - fs = astConvert( cf, bf, " " ); - if( fs ) { - astShow( fs ); - astError( AST__INTER, "Error 28\n", status ); - } - - - astSetDomain( bf, "SKY" ); - fs = astConvert( bf, cf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), bf ) && astOK ) { - astError( AST__INTER, "Error 29\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), cf ) && astOK ) { - astError( AST__INTER, "Error 30\n", status ); - } else if( !astIsAPermMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 31\n", status ); - } - } else { - astError( AST__INTER, "Error 32\n", status ); - } - - fs = astConvert( cf, bf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), cf ) && astOK ) { - astError( AST__INTER, "Error 33\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), bf ) && astOK ) { - astError( AST__INTER, "Error 34\n", status ); - } else if( !astIsAPermMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 35\n", status ); - } - } else { - astError( AST__INTER, "Error 36\n", status ); - } - - - fs = astConvert( sf, cf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), sf ) && astOK ) { - astError( AST__INTER, "Error 37\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), cf ) && astOK ) { - astError( AST__INTER, "Error 38\n", status ); - } else if( !astIsAPermMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 39\n", status ); - } - } else { - astError( AST__INTER, "Error 40\n", status ); - } - - fs = astConvert( cf, sf, " " ); - if( fs ) { - if( !astEqual( astGetFrame( fs, AST__BASE ), cf ) && astOK ) { - astError( AST__INTER, "Error 41\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), sf ) && astOK ) { - astError( AST__INTER, "Error 42\n", status ); - } else if( !astIsAPermMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 43\n", status ); - } - } else { - astError( AST__INTER, "Error 44\n", status ); - } - - - fs = astFindFrame( sf, cf, " " ); - if( !fs && astOK ) { - astError( AST__INTER, "Error 45\n", status ); - } - - fs = astFindFrame( cf, sf, " " ); - if( fs && astOK ) { - astError( AST__INTER, "Error 46\n", status ); - } - - astSetMaxAxes( sf, 3 ); - astSetMinAxes( sf, 1 ); - - fs = astFindFrame( cf, sf, " " ); - if( !fs && astOK ) { - astError( AST__INTER, "Error 47\n", status ); - } else { - if( !astEqual( astGetFrame( fs, AST__BASE ), cf ) && astOK ) { - astError( AST__INTER, "Error 48\n", status ); - } else if( !astEqual( astGetFrame( fs, AST__CURRENT ), sf ) && astOK ) { - astError( AST__INTER, "Error 49\n", status ); - } else if( !astIsAPermMap( astGetMapping( fs, AST__BASE, AST__CURRENT ) ) ) { - astError( AST__INTER, "Error 50\n", status ); - } - } - - target = astFrame( 2, "Domain=ARDAPP", status ); - template = (AstFrame *) astSkyFrame( "System=GAPPT", status ); - fs = astFindFrame( target, template, " " ); - if( fs && astOK ) { - astError( AST__INTER, "Error 51\n", status ); - } - - - - - if( astOK ) { - printf(" All astConvert tests passed\n"); - } else { - printf("astConvert tests failed\n"); - } -} diff --git a/ast/ast_tester/testerror.c b/ast/ast_tester/testerror.c deleted file mode 100644 index d668879..0000000 --- a/ast/ast_tester/testerror.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "ast.h" - -#define ERRVAL -1234 -static int flag; - -void myPutErr( int status_value, const char *message ); - -int main(){ - double a[2] = {0.0,0.0}; - -/* Initialise the flag that indicates if the error handler has been - called. */ - flag = 0; - -/* Register the error handler. */ - astSetPutErr( myPutErr ); - -/* Generate an error by making a ShiftMap with a negative number of axes. - The error handler will set the flag to a special value. */ - AstShiftMap *map = astShiftMap( -1, a, " " ); - -/* Clear the error status. */ - astClearStatus; - -/* Clear the error reporter so that the default error reporter is used. */ - astSetPutErr( NULL ); - -/* Report an error if the flag was not set to the correct value. */ - if( flag != ERRVAL ) { - astError( AST__INTER, "Error reporting function has not been " - "called." ); - } - - if( astOK ) { - printf(" All Error tests passed\n"); - } else { - printf("Error tests failed\n"); - } - -} - -void myPutErr( int status_value, const char *message ) { - flag = ERRVAL; -} diff --git a/ast/ast_tester/testfitschan.f b/ast/ast_tester/testfitschan.f deleted file mode 100644 index f2816c3..0000000 --- a/ast/ast_tester/testfitschan.f +++ /dev/null @@ -1,988 +0,0 @@ - program testfitschan - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer status, fs, fc, i, val, iwcfrm, map - character cards(10)*80, card*80 - logical there - double precision xin, yin, xout, yout - - status = sai__ok - - -c call ast_watchmemory( 225192 ) - call ast_begin( status ) - -* Create a FitsChan that will write its contents out to text file -* fred.txt when it is deleted. - fc = ast_fitschan( AST_NULL, AST_NULL, 'SinkFile=./fred.txt', - : status ) - - if( .not. ast_getl( fc, 'SipOK', status ) ) then - call stopit( 776, ' ', status ) - end if - -* Put a FITS-WCS header into it. - cards(1) = 'CRPIX1 = 45' - cards(2) = 'CRPIX2 = 45' - cards(3) = 'CRVAL1 = 45' - cards(4) = 'CRVAL2 = 89.9' - cards(5) = 'MYNAME = ' - cards(6) = 'CDELT1 = -0.01' - cards(7) = 'CDELT2 = 0.01' - cards(8) = 'CTYPE1 = ''RA---TAN''' - cards(9) = 'CTYPE2 = ''DEC--TAN''' - do i = 1, 9 - call ast_putfits( fc, cards(i), .false., status ) - end do - - call ast_seti( fc, 'Card', 2, status ) - if( .not. ast_getfitsi( fc, '.', val, status ) ) then - call stopit( 777, ' ', status ) - else if( val .ne. 45 ) then - call stopit( 778, ' ', status ) - endif - - call ast_seti( fc, 'Card', 5, status ) - if( ast_testfits( fc, '.', there, status ) ) then - call stopit( 779, ' ', status ) - else if( .not. there ) then - call stopit( 780, ' ', status ) - endif - - if( .not. ast_testfits( fc, 'CDELT1', there, status ) ) then - call stopit( 781, ' ', status ) - else if( .not. there ) then - call stopit( 782, ' ', status ) - endif - - if( ast_testfits( fc, 'ABCDEF', there, status ) ) then - call stopit( 783, ' ', status ) - else if( there ) then - call stopit( 784, ' ', status ) - endif - - call ast_seti( fc, 'Card', 10, status ) - if( ast_testfits( fc, '.', there, status ) ) then - call stopit( 785, ' ', status ) - else if( there ) then - call stopit( 786, ' ', status ) - endif - - card = ast_getc( fc, 'CardName', status ) - if( card .ne. ' ' ) call stopit( 787, ' ', status ) - -* Annul the fitschan. Only 1 ref so this should delete it. - call ast_annul( fc, status ) - -* Create another FitsChan and tell it to read headers from fred.txt. - fc = ast_fitschan( AST_NULL, AST_NULL, 'SourceFile=./fred.txt', - : status ) - -* Check it looks like the original header. - if( ast_geti( fc, 'NCard', status ) .ne. 9 ) then - write(*,*) ast_geti( fc, 'NCard', status ) - call stopit( 1000, ' ', status ) - endif - - if( ast_geti( fc, 'Nkey', status ) .ne. 9 ) then - write(*,*) ast_geti( fc, 'Nkey', status ) - call stopit( 999, ' ', status ) - endif - - call ast_clear( fc, 'Card', status ) - i = 0 - do while( ast_findfits( fc, '%f', card, .true., status ) ) - i = i + 1 - if( card .ne. cards( i ) ) then - call stopit( 1001, ' ', status ) - endif - end do - -* Annul the fitschan. - call ast_annul( fc, status ) - -* Put a simple FITS-WCS header into a FitsChan. - cards(1) = 'CRPIX1 = 45' - cards(2) = 'CRPIX2 = 45' - cards(3) = 'CRVAL1 = 45' - cards(4) = 'CRVAL2 = 89.9' - cards(5) = 'CDELT1 = -0.01' - cards(6) = 'CDELT2 = 0.01' - cards(7) = 'CTYPE1 = ''RA---TAN''' - cards(8) = 'CTYPE2 = ''DEC--TAN''' - - fc = ast_fitschan( AST_NULL, AST_NULL, 'Iwc=1', status ) - do i = 1, 8 - call ast_putfits( fc, cards(i), .false., status ) - end do - - - call ast_clear( fc, 'Card', status ) - if( ast_geti( fc, 'CardType', status ) .NE. AST__INT ) then - write(*,*) ast_geti( fc, 'CardType', status ),' should be ', - : AST__STRING - call stopit( 993, ' ', status ) - endif - - -* Indicate that the CTYPE1 card should be retained by ast_read. - if( ast_findfits( fc, 'CTYPE1', card, .FALSE., status ) ) then - call ast_retainfits( fc, status ) - endif - -* Read a FrameSet from the FitsChan. - call ast_clear( fc, 'Card', status ) - fs = ast_read( fc, status ) - if( fs .eq. AST__NULL ) then - call stopit( 1, 'No FrameSet read from FitsChan', status ) - end if - -* Check the CTYPE1 card is still present in the FitsChan. - call ast_clear( fc, 'Card', status ) - if( .not. ast_findfits( fc, 'CTYPE1', card, .FALSE., - : status ) ) then - call stopit( 2, 'CTYPE1 has not been retained', status ) - end if - -* Check the CTYPE2 card is not present in the FitsChan. - call ast_clear( fc, 'Card', status ) - if( ast_findfits( fc, 'CTYPE2', card, .FALSE., status ) ) then - call stopit( 3, 'CTYPE2 has been retained', status ) - end if - -* Check the IWC Frame is present and check the reference point -* transforms to the origin of IWC. - if( ast_geti( fs, 'Nframe', status ) .ne. 3 ) then - call stopit( 301, 'Wrong number of Frames', status ) - endif - if( ast_geti( fs, 'Current', status ) .ne. 2 ) then - call stopit( 302, 'Wrong current Frame', status ) - endif - iwcfrm = ast_getframe( fs, 3, status ) - if( ast_getc( iwcfrm, 'Domain', status ) .ne. 'IWC' ) then - call stopit( 303, 'Wrong Domain in IWC Frame', status ) - endif - - map = ast_getmapping( fs, 1, 3, status ) - xin = 45.0D0 - yin = 45.0D0 - call ast_tran2( map, 1, xin, yin, .true., xout, yout, status ) - if( xout .ne. 0.0D0 .or. yout .ne. 0.0D0 ) then - call stopit( 304, 'Wrong IWC for CRPIX position', status ) - endif - - xin = xin + 1.0D0 - call ast_tran2( map, 1, xin, yin, .true., xout, yout, status ) - if( xout .ne. -0.01D0 .or. yout .ne. 0.0D0 ) then - call stopit( 305, 'Wrong IWC for offset CRPIX position', - : status ) - endif - - map = ast_getmapping( fs, 2, 3, status ) - xin = 45.0D0*AST__DD2R - yin = 89.9D0*AST__DD2R - call ast_tran2( map, 1, xin, yin, .true., xout, yout, status ) - if( abs( xout ) .gt. 1.0D-10 .or. abs( yout ) .gt. 1.0D-10 ) then - call stopit( 306, 'Wrong IWC for CRVAL position', status ) - endif - - -* Do it again, this time with an illegal value for CRPIX2. This will -* cause ast_read to report an error. - cards(1) = 'CRPIX1 = 45' - cards(2) = 'CRPIX2 = ''fred''' - cards(3) = 'CRVAL1 = 45' - cards(4) = 'CRVAL2 = 89.9' - cards(5) = 'CDELT1 = -0.01' - cards(6) = 'CDELT2 = 0.01' - cards(7) = 'CTYPE1 = ''RA---TAN''' - cards(8) = 'CTYPE2 = ''DEC--TAN''' - - fc = ast_fitschan( AST_NULL, AST_NULL, ' ', status ) - do i = 1, 8 - call ast_putfits( fc, cards(i), .false., status ) - end do - -* Set the Clean attribute to true so that used cards are removed from the -* FitsChan even if an error occurrs in astRead. -c call ast_setl( fc, 'Clean', .true., status ) - -* Indicate that the CTYPE1 card should be retained by ast_read. - call ast_clear( fc, 'Card', status ) - if( ast_findfits( fc, 'CTYPE1', card, .FALSE., status ) ) then - call ast_retainfits( fc, status ) - endif - -* Abort if an error has occurred. - if( status .ne. sai__ok ) go to 999 - -* Read a FrameSet from the FitsChan, deferring error reporting. Check an -* error is reported by ast_read. - call ast_clear( fc, 'Card', status ) - - call err_begin( status ) - fs = ast_read( fc, status ) - - if( fs .ne. AST__NULL ) then - call stopit( 4, 'A FrameSet has been read from the FitsChan', - : status ) - - else if( status .eq. sai__ok ) then - call stopit( 5, 'No error has been reported by ast_read', - : status ) - - else - call err_annul( status ) - end if - - call err_end( status ) - -* Check the CTYPE1 card is still present in the FitsChan. - call ast_clear( fc, 'Card', status ) - if( .not. ast_findfits( fc, 'CTYPE1', card, .FALSE., - : status ) ) then - call stopit( 6, 'CTYPE1 has not been retained', status ) - end if - -* Check the CTYPE2 card is also still present in the FitsChan (because -* cards are not removed if an error is reported in ast_read unless the -* Clean attribute is set true). - call ast_clear( fc, 'Card', status ) - if( .not. ast_findfits( fc, 'CTYPE2', card, .FALSE., - : status ) ) then - call stopit( 7, 'CTYPE2 has not been retained', status ) - end if - - - - - -* Do it again, again with an illegal value for CRPIX2, but this time -* setting the Clean attribute true. - cards(1) = 'CRPIX1 = 45' - cards(2) = 'CRPIX2 = ''fred''' - cards(3) = 'CRVAL1 = 45' - cards(4) = 'CRVAL2 = 89.9' - cards(5) = 'CDELT1 = -0.01' - cards(6) = 'CDELT2 = 0.01' - cards(7) = 'CTYPE1 = ''RA---TAN''' - cards(8) = 'CTYPE2 = ''DEC--TAN''' - - fc = ast_fitschan( AST_NULL, AST_NULL, 'Clean=1', status ) - do i = 1, 8 - call ast_putfits( fc, cards(i), .false., status ) - end do - -* Indicate that the CTYPE1 card should be retained by ast_read. - call ast_clear( fc, 'Card', status ) - if( ast_findfits( fc, 'CTYPE1', card, .FALSE., status ) ) then - call ast_retainfits( fc, status ) - endif - -* Abort if an error has occurred. - if( status .ne. sai__ok ) go to 999 - -* Read a FrameSet from the FitsChan, deferring error reporting. Check an -* error is reported by ast_read. - call ast_clear( fc, 'Card', status ) - - call err_begin( status ) - fs = ast_read( fc, status ) - - if( fs .ne. AST__NULL ) then - call stopit( 8, 'A FrameSet has been read from the FitsChan', - : status ) - - else if( status .eq. sai__ok ) then - call stopit( 9, 'No error has been reported by ast_read', - : status ) - - else - call err_annul( status ) - end if - - call err_end( status ) - -* Check the CTYPE1 card is still present in the FitsChan (because of the -* call to ast_retainfits). - call ast_clear( fc, 'Card', status ) - if( .not. ast_findfits( fc, 'CTYPE1', card, .FALSE., - : status ) ) then - call stopit( 10, 'CTYPE1 has not been retained', status ) - end if - -* Check the CTYPE2 card is no longer present in the FitsChan (because -* the Clean attribute is set true). - call ast_clear( fc, 'Card', status ) - if( ast_findfits( fc, 'CTYPE2', card, .FALSE., status ) ) then - call stopit( 11, 'CTYPE2 has been retained', status ) - end if - -* Test -TAB - call checktab( status ) - call checktab2( status ) - -* Read a SIP header and then attempt to write it out. It should fail -* because the SIP header is non-linear. - call ast_emptyfits( fc, status ) - call ast_seti( fc, 'SipOK', 0, status ) - call ast_set( fc, 'SourceFile=sip.head', status ) - call ast_clear( fc, 'Card', status ) - fs = ast_read( fc, status ) - call ast_set( fc, 'Encoding=FITS-WCS', status ) - if( fs .eq. AST__NULL ) then - call stopit( 12, 'Failed to read SIP header', status ) - else if( ast_write( fc, fs, status ) .gt. 0 ) then - call stopit( 13, 'Test on SIP header non-linearity failed', - : status ) - end if - - - - - - - - - 999 continue - - call ast_end( status ) - call ast_activememory( 'testfitschan' ) - call ast_flushmemory( 1 ); - - - if( status .eq. sai__ok ) then - write(*,*) 'All FitsChan tests passed' - else - write(*,*) 'FitsChan tests failed' - end if - - end - - - subroutine stopit( errnum, text, status ) - implicit none - include 'SAE_PAR' - character text*(*) - integer errnum, status - - if( status .eq. sai__ok ) then - status = sai__error - call msg_seti( 'N', errnum ) - call msg_setc( 'T', text ) - call err_rep( ' ', 'Error ^N: ^T', status ) - end if - - end - - - subroutine checktab( status ) - implicit none - - external tabsource - - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - include 'PRM_PAR' - include 'CNF_PAR' - integer status, sf, mm, fc, fs,gf, tables, table, size, pntr1, - : nelem, pntr2, i, lm, sm, fs2, map, fc2, ncard, fs3 - character key*20,card*80 - double precision lut( 100 ), shift, x(3), y(3), y2(3) - - common /tabsrc/ tables - - if( status .ne. sai__ok ) return - - call err_begin( status ) - call ast_begin( status ) - - sf = ast_specframe( 'system=freq,unit=MHz', status ) - gf = ast_frame( 1, 'domain=GRID', status ) - mm = ast_mathmap( 1, 1, 1, 'y=1/(x*x)', 1, 'x=1/sqrt(y)', ' ', - : status ) - fs = ast_frameset( gf, ' ', status ) - call ast_addframe( fs, AST__BASE, mm, sf, status ) - - fc = ast_fitschan( ast_null, ast_null, 'Encoding=FITS-WCS', - : status ) - call ast_putfits( fc, 'NAXIS = 1', .false., status ) - call ast_putfits( fc, 'NAXIS1 = 100', .false., status ) - - - if( ast_write( fc, fs, status ) .ne. 0 ) then - call stopit( 1000, ' ', status ) - else if( ast_gettables( fc, status ) .ne. AST__NULL ) then - call stopit( 1001, ' ', status ) - endif - - call ast_setl( fc, 'TabOK', .true., status ) - - if( ast_write( fc, fs, status ) .ne. 1 ) - : call stopit( 1002, ' ', status ) - - tables = ast_gettables( fc, status ) - if( tables .eq. AST__NULL ) then - call stopit( 1003, ' ', status ) - else if( .not. ast_isakeymap( tables, status ) ) then - call stopit( 1004, ' ', status ) - else if( ast_mapsize( tables, status ) .ne. 1 ) then - call stopit( 1005, ' ', status ) - endif - - key = ast_mapkey( tables, 1, status ) - if( key .ne. 'WCS-TAB' ) then - call stopit( 1006, ' ', status ) - endif - - if( .not. ast_mapget0a( tables, 'WCS-TAB', table, - : status ) ) then - call stopit( 1007, ' ', status ) - else if( .not. ast_isafitstable( table, status ) ) then - call stopit( 1004, ' ', status ) - endif - - if( ast_geti( table, 'NColumn', status ) .ne. 2 ) then - call stopit( 1005, ' ', status ) - else if( ast_geti( table, 'NRow', status ) .ne. 1 ) then - call stopit( 1006, ' ', status ) - else if( ast_geti( table, 'ColumnLength(coords1)', status ) .ne. - : 197 ) then - call stopit( 1007, ' ', status ) - else if( ast_geti( table, 'ColumnLength(index1)', status ) .ne. - : 197 ) then - call stopit( 1008, ' ', status ) - end if - - size = ast_columnsize( table, 'COORDS1', status ) - if( size .ne. VAL__NBD*197 ) call stopit( 1009, ' ', status ) - call psx_malloc( size, pntr1, status ) - call ast_getcolumndata( table, 'Coords1', 0.0, AST__BAD, size, - : %val( cnf_pval( pntr1 ) ), nelem, - : status ) - if( nelem .ne. 197 ) call stopit( 1010, ' ', status ) - - size = ast_columnsize( table, 'INDEX1', status ) - if( size .ne. VAL__NBD*197 ) call stopit( 1011, ' ', status ) - call psx_malloc( size, pntr2, status ) - call ast_getcolumndata( table, 'inDex1', 0.0, AST__BAD, size, - : %val( cnf_pval( pntr2 ) ), nelem, - : status ) - if( nelem .ne. 197 ) call stopit( 1012, ' ', status ) - - call checkft( 197, %val( cnf_pval( pntr1 ) ), - : %val( cnf_pval( pntr2 ) ), status ) - - call psx_free( pntr1, status ) - call psx_free( pntr2, status ) - -c -------------------------------------------------------------------- - do i = 1, 100 - lut( i ) = 1.0D0/dble(i*i) - end do - - lm = ast_lutmap( 100, lut, -49.0D0, 1.0D0, ' ', status ) - - call ast_set( sf, 'System=Wave,Unit=m', status ) - call ast_removeframe( fs, AST__CURRENT, status ) - call ast_addframe( fs, AST__BASE, lm, sf, status ) - call ast_set( fs, 'System=freq', status ) - - shift = 50.0D0 - sm = ast_shiftmap( 1, shift, ' ', status ) - call ast_remapframe( fs, AST__BASE, sm, status ) - - call ast_removetables( fc, 'WCS-TAB', status ) - call ast_purgewcs( fc, status ) - - if( ast_write( fc, fs, status ) .ne. 1 ) - : call stopit( 1013, ' ', status ) - tables = ast_gettables( fc, status ) - - if( tables .eq. AST__NULL ) then - call stopit( 1014, ' ', status ) - else if( .not. ast_isakeymap( tables, status ) ) then - call stopit( 1015, ' ', status ) - else if( ast_mapsize( tables, status ) .ne. 1 ) then - call stopit( 1016, ' ', status ) - endif - - key = ast_mapkey( tables, 1, status ) - if( key .ne. 'WCS-TAB' ) then - call stopit( 1017, ' ', status ) - endif - - if( .not. ast_mapget0a( tables, 'WCS-TAB', table, - : status ) ) then - call stopit( 1018, ' ', status ) - else if( .not. ast_isafitstable( table, status ) ) then - call stopit( 1019, ' ', status ) - endif - - if( ast_geti( table, 'NColumn', status ) .ne. 1 ) then - call stopit( 1020, ' ', status ) - else if( ast_geti( table, 'NRow', status ) .ne. 1 ) then - call stopit( 1021, ' ', status ) - else if( ast_geti( table, 'ColumnLength(coords1)', status ) .ne. - : 100 ) then - call stopit( 1022, ' ', status ) - end if - - size = ast_columnsize( table, 'COORDS1', status ) - if( size .ne. VAL__NBD*100 ) call stopit( 1024, ' ', status ) - call psx_malloc( size, pntr1, status ) - call ast_getcolumndata( table, 'Coords1', 0.0, AST__BAD, size, - : %val( cnf_pval( pntr1 ) ), nelem, - : status ) - if( nelem .ne. 100 ) call stopit( 1025, ' ', status ) - - call checkft2( 100, %val( cnf_pval( pntr1 ) ), status ) - - call psx_free( pntr1, status ) - -c -------------------------------------------------------------------- - - call ast_removetables( fc, ' ', status ) - fc2 = ast_copy( fc, status ) - call ast_puttables( fc, tables, status ) - call ast_clear( fc, 'Card', status ) - - fs2 = ast_read( fc, status ) - if( fs2 .eq. ast__null ) call stopit( 1028, ' ', status ) - - if( .not. ast_equal( ast_getframe( fs, ast__current, status ), - : ast_getframe( fs2, ast__current, status ), - : status ) ) then - call stopit( 1029, ' ', status ) - endif - - map = ast_cmpmap( ast_getmapping( fs, ast__base, ast__current, - : status ), - : ast_getmapping( fs2, ast__current, ast__base, - : status ), .TRUE., ' ', status ) - - x(1) = 1.0D0; - x(2) = 50.0D0; - x(3) = 100.0D0; - call ast_tran1( map, 3, x, .true., y, status ) - - if( abs( y(1) - x(1) ) .gt. 1.0D-4 .OR. - : abs( y(2) - x(2) ) .gt. 1.0D-4 .OR. - : abs( y(3) - x(3) ) .gt. 1.0D-4 ) then - call stopit( 1030, ' ', status ) - end if - - -c -------------------------------------------------------------------- - if( .not. ast_getl( fc2, 'TabOK', status ) ) then - call stopit( 1031, ' ', status ) - endif - ncard = ast_geti( fc2, 'Ncard', status ) - - call ast_clear( fc2, 'Card', status ) - fs2 = ast_read( fc2, status ) - if( status .ne. AST__NOTAB ) then - if( status .ne. SAI__OK ) call err_flush( status ) - call stopit( 1032, ' ', status ) - else - call err_annul( status ) - end if - - call ast_setl( fc2, 'TabOK', .false., status ) - call ast_clear( fc2, 'Card', status ) - fs2 = ast_read( fc2, status ) - if( status .ne. AST__BDFTS ) then - if( status .ne. SAI__OK ) call err_flush( status ) - call stopit( 1032, ' ', status ) - else - call err_annul( status ) - end if - call ast_setl( fc2, 'TabOK', .true., status ) - - if( ncard .ne. ast_geti( fc2, 'Ncard', status ) ) then - call stopit( 1034, ' ', status ) - endif - - call ast_tablesource( fc2, tabsource, status ) - call ast_clear( fc2, 'Card', status ) - fs2 = ast_read( fc2, status ) - if( fs2 .eq. ast__null ) call stopit( 1035, ' ', status ) - - if( .not. ast_equal( ast_getframe( fs, ast__current, status ), - : ast_getframe( fs2, ast__current, status ), - : status ) ) then - call stopit( 1036, ' ', status ) - endif - - map = ast_cmpmap( ast_getmapping( fs, ast__base, ast__current, - : status ), - : ast_getmapping( fs2, ast__current, ast__base, - : status ), .TRUE., ' ', status ) - - x(1) = 1.0D0; - x(2) = 50.0D0; - x(3) = 100.0D0; - call ast_tran1( map, 3, x, .true., y, status ) - - if( abs( y(1) - x(1) ) .gt. 1.0D-4 .OR. - : abs( y(2) - x(2) ) .gt. 1.0D-4 .OR. - : abs( y(3) - x(3) ) .gt. 1.0D-4 ) then - call stopit( 1037, ' ', status ) - end if - -c -------------------------------------------------------------------- - call readobj( 'sparse.ast', fs, status ) - - fc = ast_fitschan( ast_null, ast_null, - : 'Encoding=FITS-WCS,TabOK=1', status ) - - call ast_putfits( fc, 'NAXIS = 2', .false., status ) - call ast_putfits( fc, 'NAXIS1 = 2000', .false., status ) - call ast_putfits( fc, 'NAXIS2 = 1', .false., status ) - - if( ast_write( fc, fs, status ) .ne. 1 ) then - call stopit( 1038, ' ', status ) - end if - - call ast_clear( fc, 'Card', status ) - fs2 = ast_read( fc, status ) - - call ast_invert( fs, status ) - call ast_invert( fs2, status ) - fs3 = ast_convert( fs, fs2, 'SKY-DSBSPECTRUM', status ) - if( fs3 .eq. AST__NULL ) then - call stopit( 1039, ' ', status ) - endif - - if( ast_getc( ast_getframe( fs, AST__BASE, status ), 'Domain', - : status ) .ne. 'SKY-DSBSPECTRUM' ) then - call stopit( 1040, ' ', status ) - endif - - if( ast_getc( ast_getframe( fs2, AST__BASE, status ), 'Domain', - : status ) .ne. 'SKY-DSBSPECTRUM' ) then - call stopit( 1041, ' ', status ) - endif - - call ast_invert( fs, status ) - call ast_invert( fs2, status ) - - x( 1 ) = 1.0 - x( 2 ) = 1.0 - x( 3 ) = 1.0 - call ast_trann( fs, 1, 3, 1, x, .true., 3, 1, y, status ) - call ast_trann( fs2, 1, 3, 1, x, .true., 3, 1, y2, status ) - - do i = 1, 3 - if( abs( y(i) - y2(i) ) .gt. 1.0E-8 ) then - call stopit( 1042, ' ', status ) - endif - enddo - - x( 1 ) = 10.0 - x( 2 ) = 1.0 - x( 3 ) = 1000.0 - call ast_trann( fs, 1, 3, 1, x, .true., 3, 1, y, status ) - call ast_trann( fs2, 1, 3, 1, x, .true., 3, 1, y2, status ) - - do i = 1, 3 - if( abs( y(i) - y2(i) ) .gt. 1.0E-8 ) then - call stopit( 1042, ' ', status ) - endif - enddo - - -c -------------------------------------------------------------------- - - sf = ast_frame( 1, 'domain=voltage,unit=V', status ) - gf = ast_frame( 1, 'domain=GRID', status ) - mm = ast_mathmap( 1, 1, 1, 'y=1/(x*x)', 1, 'x=1/sqrt(y)', ' ', - : status ) - fs = ast_frameset( gf, ' ', status ) - call ast_addframe( fs, AST__BASE, mm, sf, status ) - - call ast_emptyfits( fc, status ) - call ast_putfits( fc, 'NAXIS = 1', .false., status ) - call ast_putfits( fc, 'NAXIS1 = 100', .false., status ) - - if( ast_write( fc, fs, status ) .ne. 1 ) - : call stopit( 1043, ' ', status ) - - if( ast_getfitss( fc, 'CTYPE1', card, status ) ) then - if( card .ne. 'VOLT-TAB' ) call stopit( 1059, ' ', status ) - else - call stopit( 1060, ' ', status ) - endif - - tables = ast_gettables( fc, status ) - if( tables .eq. AST__NULL ) then - call stopit( 1044, ' ', status ) - else if( .not. ast_isakeymap( tables, status ) ) then - call stopit( 1045, ' ', status ) - else if( ast_mapsize( tables, status ) .ne. 1 ) then - call stopit( 1046, ' ', status ) - endif - - key = ast_mapkey( tables, 1, status ) - if( key .ne. 'WCS-TAB' ) then - call stopit( 1047, ' ', status ) - endif - - if( .not. ast_mapget0a( tables, 'WCS-TAB', table, - : status ) ) then - call stopit( 1048, ' ', status ) - else if( .not. ast_isafitstable( table, status ) ) then - call stopit( 1049, ' ', status ) - endif - - if( ast_geti( table, 'NColumn', status ) .ne. 2 ) then - call stopit( 1050, ' ', status ) - else if( ast_geti( table, 'NRow', status ) .ne. 1 ) then - call stopit( 1051, ' ', status ) - else if( ast_geti( table, 'ColumnLength(coords1)', status ) .ne. - : 197 ) then - call stopit( 1052, ' ', status ) - else if( ast_geti( table, 'ColumnLength(index1)', status ) .ne. - : 197 ) then - call stopit( 1053, ' ', status ) - end if - - size = ast_columnsize( table, 'COORDS1', status ) - - if( size .ne. VAL__NBD*197 ) call stopit( 1054, ' ', status ) - call psx_malloc( size, pntr1, status ) - call ast_getcolumndata( table, 'Coords1', 0.0, AST__BAD, size, - : %val( cnf_pval( pntr1 ) ), nelem, - : status ) - if( nelem .ne. 197 ) call stopit( 1055, ' ', status ) - - size = ast_columnsize( table, 'INDEX1', status ) - if( size .ne. VAL__NBD*197 ) call stopit( 1056, ' ', status ) - call psx_malloc( size, pntr2, status ) - call ast_getcolumndata( table, 'inDex1', 0.0, AST__BAD, size, - : %val( cnf_pval( pntr2 ) ), nelem, - : status ) - if( nelem .ne. 197 ) call stopit( 1057, ' ', status ) - - call checkft( 197, %val( cnf_pval( pntr1 ) ), - : %val( cnf_pval( pntr2 ) ), status ) - - call psx_free( pntr1, status ) - call psx_free( pntr2, status ) - - - call ast_clear( fc, 'Card', status ) - fs2 = ast_read( fc, status ) - if( fs2 .eq. AST__NULL ) - : call stopit( 1058, ' ', status ) - - call ast_invert( fs, status ) - call ast_invert( fs2, status ) - fs3 = ast_convert( fs2, fs, ' ', status ) - if( fs3 .eq. AST__NULL ) then - call stopit( 1061, ' ', status ) - endif - - if( ast_getc( ast_getframe( fs, AST__BASE, status ), 'Domain', - : status ) .ne. 'VOLTAGE' ) then - call stopit( 1062, ' ', status ) - endif - - if( ast_getc( ast_getframe( fs2, AST__BASE, status ), 'Domain', - : status ) .ne. 'VOLTAGE' ) then - call stopit( 1063, ' ', status ) - endif - - x(1) = 1.0 - x(2) = 10.0 - x(3) = 100.0 - call ast_tran1( fs3, 3, x, .true., y, status ) - if( abs( y(1) - x(1) ) .gt. 1.0D-2 .OR. - : abs( y(2) - x(2) ) .gt. 1.0D-2 .OR. - : abs( y(3) - x(3) ) .gt. 1.0D-2 ) then - call stopit( 1064, ' ', status ) - end if - - - - call ast_end( status ) - call err_end( status ) - - end - - - subroutine checkft( nelem, coords, indx, status ) - implicit none - include 'SAE_PAR' - integer nelem, status - double precision coords( nelem ), indx( nelem ) - - if( status .ne. sai__ok ) return - - if( indx( 1 ) .ne. 1.0D0 ) then - call stopit( 2001, ' ', status ) - - else if( coords( 1 ) .ne. 1.0D0 ) then - call stopit( 2002, ' ', status ) - - else if( indx( nelem ) .ne. 1.0D2 ) then - call stopit( 2003, ' ', status ) - - else if( coords( nelem ) .ne. 1.0D-4 ) then - call stopit( 2004, ' ', status ) - - else if( coords( nelem/2 ) .ne. - : indx( nelem/2 )**(-2) ) then - call stopit( 2005, ' ', status ) - end if - - end - - subroutine checkft2( nelem, coords, status ) - implicit none - include 'SAE_PAR' - integer nelem, status - double precision coords( nelem ) - - if( status .ne. sai__ok ) return - - if( abs( coords( 1 ) - 299.792458 ) .gt. 1.0D-5 ) then - call stopit( 3002, ' ', status ) - - else if( abs( coords( nelem ) - 2997924.58 ) .gt. 1.0D-1 ) then - call stopit( 3004, ' ', status ) - - end if - - end - - subroutine tabsource( fc, extnam, extver, extlevel, status ) - implicit none - include 'AST_PAR' - - integer fc, status, tables, table, extver, extlevel - character extnam*(*) - - common /tabsrc/ tables - - if( extnam .ne. 'WCS-TAB' ) then - call stopit( 1035, ' ', status ) - - else if( .not. ast_mapget0a( tables, extnam, table, - : status ) ) then - call stopit( 1036, ' ', status ) - - else if( .not. ast_isafitstable( table, status ) ) then - call stopit( 1037, ' ', status ) - - else if( extver .ne. 1 ) then - write(*,*) 'EXTVER=',extver - call stopit( 1065, ' ', status ) - - else if( extlevel .ne. 1 ) then - call stopit( 1066, ' ', status ) - - else - call ast_puttables( fc, tables, status ) - - endif - - call ast_annul( table, status ) - - end - - - - subroutine readobj( file, iobj, status ) - implicit none - - include 'AST_PAR' - include 'SAE_PAR' - - external chsource - integer iobj, status, ch - character file*(*) - - open( 10, status='old', file=file ) - - ch = ast_channel( chsource, AST_NULL, ' ', status ) - iobj = ast_read( ch, status ) - call ast_annul( ch, status ) - - close( 10 ) - - end - - subroutine chsource( status ) - implicit none - - include 'AST_PAR' - include 'SAE_PAR' - - integer status - character line*200 - - read( 10, '(A)', end=99 ) line - - call ast_putline( line, len( line ), status ) - return - - 99 call ast_putline( line, -1, status ) - - end - - - - - subroutine checktab2( status ) - implicit none - - include 'SAE_PAR' - include 'AST_PAR' - integer status, sf, mmm, mm, fc, fs, fs2, gf - - if( status .ne. sai__ok ) return - - call err_begin( status ) - call ast_begin( status ) - - sf = ast_skyframe( ' ', status ) - call ast_setd( sf, 'SkyRef(1)', 0.0001D0, status ) - call ast_setd( sf, 'SkyRef(2)', 0.0001D0, status ) - - gf = ast_frame( 2, 'domain=GRID', status ) - - mm = ast_mathmap( 1, 1, 1, 'y=(x+50)**(-2)', 1, 'x=-50+1/sqrt(y)', - : ' ', status ) - mmm = ast_cmpmap( mm, mm, .false., ' ', status ) - - fs = ast_frameset( gf, ' ', status ) - call ast_addframe( fs, AST__BASE, mmm, sf, status ) - - fc = ast_fitschan( ast_null, ast_null, 'Encoding=FITS-WCS,'// - : 'TabOK=1', status ) - call ast_putfits( fc, 'NAXIS = 2', .false., status ) - call ast_putfits( fc, 'NAXIS1 = 100', .false., status ) - call ast_putfits( fc, 'NAXIS2 = 100', .false., status ) - - if( ast_write( fc, fs, status ) .ne. 1 ) then - call stopit( 2000, ' ', status ) - endif - - call ast_clear( fc, 'Card', status ) - fs2 = ast_read( fc, status ) - if( fs2 .eq. AST__NULL ) - : call stopit( 2001, ' ', status ) - - if( abs( ast_getd( fs2, 'SkyRef(1)', status ) - 0.0001 ) .gt. - : 1E-7 ) call stopit( 2001, ' ', status ) - if( abs( ast_getd( fs2, 'SkyRef(2)', status ) - 0.0001 ) .gt. - : 1E-7 ) call stopit( 2001, ' ', status ) - - call ast_end( status ) - call err_end( status ) - - end diff --git a/ast/ast_tester/testfitstable.f b/ast/ast_tester/testfitstable.f deleted file mode 100644 index e85f065..0000000 --- a/ast/ast_tester/testfitstable.f +++ /dev/null @@ -1,590 +0,0 @@ - program testfitstable - implicit none - - include 'AST_PAR' - include 'AST_ERR' - include 'SAE_PAR' - include 'CNF_PAR' - - integer status, table, table2, dims( 7 ), header, ival, l, nval, - : icard, colsize, pntr, head, clen, oldnull, null - byte bytes(2,3),bval - logical wasset, hasnull - real rval - character cval*30, text(3)*10, card*70 - character header1(18)*30 - character header2(20)*30 - - data header1 / 'XTENSION= ''BINTABLE''', - : 'BITPIX = 8', - : 'NAXIS = 2', - : 'NAXIS1 = 10', - : 'NAXIS2 = 0', - : 'PCOUNT = 0', - : 'GCOUNT = 1', - : 'TFIELDS = 3', - : 'TFORM1 = ''6B ''', - : 'TTYPE1 = ''BYTECOL ''', - : 'TUNIT1 = ''ADU ''', - : 'TDIM1 = ''(2,3) ''', - : 'TFORM2 = ''1J ''', - : 'TTYPE2 = ''INTCOL ''', - : 'TUNIT2 = ''m ''', - : 'TFORM3 = ''0A ''', - : 'TTYPE3 = ''STRINGCOL''', - : 'TDIM3 = ''(0,3) ''' / - - - data header2 / 'XTENSION= ''BINTABLE''', - : 'BITPIX = 8', - : 'NAXIS = 2', - : 'NAXIS1 = 40', - : 'NAXIS2 = 3', - : 'PCOUNT = 0', - : 'GCOUNT = 1', - : 'TFIELDS = 3', - : 'TFORM1 = ''6B ''', - : 'TTYPE1 = ''BYTECOL ''', - : 'TUNIT1 = ''ADU ''', - : 'TNULL1 = 254', - : 'TDIM1 = ''(2,3) ''', - : 'TFORM2 = ''1J ''', - : 'TTYPE2 = ''INTCOL ''', - : 'TUNIT2 = ''m ''', - : 'TNULL2 = 2147483647', - : 'TFORM3 = ''30A ''', - : 'TTYPE3 = ''STRINGCOL''', - : 'TDIM3 = ''(10,3) ''' / - -c call ast_watchmemory(483) - - status = sai__ok - call err_mark( status ) - call ast_begin( status ) - - table = ast_fitstable( AST__NULL, ' ', status ) - - header = ast_gettableheader( table, status ) - if( ast_geti( header, 'NCard', status ) .ne. 8 ) then - call stopit( status, 'FitsTable error 1' ) - else if( .not. ast_getfitsi( header, 'NAXIS', ival, status )) then - call stopit( status, 'FitsTable error 2' ) - else if( ival .ne. 2 ) then - call stopit( status, 'FitsTable error 3' ) - else if( .not. ast_getfitsi( header, 'NAXIS1', ival, status)) then - call stopit( status, 'FitsTable error 4' ) - else if( ival .ne. 0 ) then - call stopit( status, 'FitsTable error 5' ) - else if( .not. ast_getfitsi( header, 'NAXIS2', ival, status)) then - call stopit( status, 'FitsTable error 6' ) - else if( ival .ne. 0 ) then - call stopit( status, 'FitsTable error 7' ) - endif - call ast_annul( header, status ) - - - call ast_addcolumn( table, 'JUNK', AST__OBJECTTYPE, 0, 0, 'm', - : status ) - if( status .eq. AST__NAXIN ) then - call err_annul( status ) - else if( status .eq. sai__ok ) then - call stopit( status, 'FitsTable error 8' ) - endif - - dims( 1 ) = 2 - dims( 2 ) = 3 - call ast_addcolumn( table, 'BYTECOL', AST__BYTETYPE, 2, dims, - : 'ADU', status ) - - call ast_addcolumn( table, 'INTCOL', AST__INTTYPE, 0, 0, 'm', - : status ) - - dims( 1 ) = 3 - call ast_addcolumn( table, 'STRINGCOL', AST__STRINGTYPE, 1, dims, - : ' ', status ) - - - header = ast_gettableheader( table, status ) - icard = 0 - do while( ast_findfits( header, '%f', card, .true., status ) ) - icard = icard + 1 - if( icard .gt. 18 ) then - call stopit( status, 'FitsTable error 9' ) - else if( card .ne. header1( icard ) ) then - call stopit( status, 'FitsTable error 10' ) - end if - end do - if( icard .ne. 18 ) call stopit( status, 'FitsTable error 11' ) - - - table2 = ast_fitstable( header, ' ', status ) - call ast_annul( header, status ) - - if( ast_geti( table2, 'Ncolumn', status ) .ne. 3 ) then - call stopit( status, 'FitsTable error 11a' ) - end if - - - - if( ast_geti( table2, 'ColumnLength(bytecol)', status ) - : .ne. 6 ) then - call stopit( status, 'FitsTable error 11b' ) - endif - - if( ast_geti( table2, 'ColumnNdim(bytecol)', status ) - : .ne. 2 ) then - call stopit( status, 'FitsTable error 11c' ) - end if - - if( ast_geti( table2, 'ColumnType(bytecol)', status ) - : .ne. AST__BYTETYPE ) then - call stopit( status, 'FitsTable error 11d' ) - end if - - if( ast_getc( table2, 'ColumnUnit(bytecol)', status ) - : .ne. 'ADU' ) then - call stopit( status, 'FitsTable error 11e' ) - end if - - - if( ast_geti( table2, 'ColumnLength(intcol)', status ) - : .ne. 1 ) then - call stopit( status, 'FitsTable error 11f' ) - endif - - if( ast_geti( table2, 'ColumnNdim(intcol)', status ) - : .ne. 0 ) then - call stopit( status, 'FitsTable error 11g' ) - end if - - if( ast_geti( table2, 'ColumnType(intcol)', status ) - : .ne. AST__INTTYPE ) then - call stopit( status, 'FitsTable error 11h' ) - end if - - if( ast_getc( table2, 'ColumnUnit(intcol)', status ) - : .ne. 'm' ) then - call stopit( status, 'FitsTable error 11i' ) - end if - - - if( ast_geti( table2, 'ColumnLength(StringCol)', status ) - : .ne. 3 ) then - call stopit( status, 'FitsTable error 11j' ) - endif - - if( ast_geti( table2, 'ColumnNdim(StringCol)', status ) - : .ne. 1 ) then - call stopit( status, 'FitsTable error 11k' ) - end if - - if( ast_geti( table2, 'ColumnType(StringCol)', status ) - : .ne. AST__STRINGTYPE ) then - call stopit( status, 'FitsTable error 11l' ) - end if - - if( ast_getc( table2, 'ColumnUnit(StringCol)', status ) - : .ne. ' ' ) then - call stopit( status, 'FitsTable error 11m' ) - end if - - - - bytes(1,1) = 0 - bytes(1,2) = 128 - bytes(1,3) = -127 - bytes(2,1) = 1 - bytes(2,2) = 127 - bytes(2,3) = -1 - call ast_mapput1b( table, 'BYTECOL(1)', 6, bytes, ' ', status ) - - bytes(1,1) = 0 - bytes(1,2) = 0 - bytes(1,3) = 0 - bytes(2,1) = 1 - bytes(2,2) = 1 - bytes(2,3) = 1 - call ast_mapput1b( table, 'BYTECOL(2)', 6, bytes, ' ', status ) - - call ast_mapput0i( table, 'INTCOL(2)', 10, ' ', status ) - - call ast_mapput0i( table, 'INTCOL(3)', -10, ' ', status ) - - text( 1 ) = 'hello' - text( 2 ) = ' ' - text( 3 ) = 'goodbye' - call ast_mapput1c( table, 'STRINGCOL(1)', 3, text, ' ', status ) - - text( 1 ) = ' ' - text( 2 ) = ' ' - text( 3 ) = ' ' - call ast_mapput1c( table, 'STRINGCOL(3)', 3, text, ' ', status ) - - if( ast_geti( table, 'Nrow', status ) .ne. 3 ) then - call stopit( status, 'FitsTable error 12' ) - endif - - if( ast_geti( table, 'Ncolumn', status ) .ne. 3 ) then - call stopit( status, 'FitsTable error 13' ) - endif - - head = ast_gettableheader( table, status ) - table2 = ast_fitstable( head, ' ', status ) - call ast_annul( head, status ) - - colsize = ast_columnsize( table, 'stringcol', status ) - if( colsize .ne. 90 ) then - call stopit( status, 'FitsTable error 13a' ) - else - call psx_malloc( colsize, pntr, status ) - call ast_getcolumndata( table, 'StringCol', 0.0, 0.0D0, - : colsize, %val( cnf_pval(pntr)), - : colsize, status ) - if( colsize .ne. 9 ) call stopit( status, - : 'FitsTable error 13b' ) - call checkstrings( table, %val( CNF_PVAL( pntr ) ), status ) - - clen = ast_geti( table, 'ColumnLenC(StringCol)', status ) - if( clen .ne. 10 ) call stopit( status, - : 'FitsTable error 13c' ) - - colsize = 90 - call ast_putcolumndata( table2, 'StringCol', 10, colsize, - : %val( CNF_PVAL( pntr ) ), status ) - call ast_getcolumndata( table2, 'StringCol', 0.0, 0.0D0, - : colsize, %val( cnf_pval(pntr)), - : colsize, status ) - - if( colsize .ne. 9 ) call stopit( status, - : 'FitsTable error 13d' ) - call checkstrings( table2, %val( CNF_PVAL( pntr ) ), status ) - - call psx_free( pntr, status ) - end if - - colsize = ast_columnsize( table, 'bytecol', status ) - if( colsize .ne. 18 ) then - call stopit( status, 'FitsTable error 13e' ) - else - call psx_malloc( colsize, pntr, status ) - call ast_getcolumndata( table, 'BYTECOL', 0.0, 0.0D0, colsize, - : %val( cnf_pval( pntr ) ), colsize, - : status ) - if( colsize .ne. 18 ) call stopit( status, - : 'FitsTable error 13f' ) - - null = ast_columnnull( table, 'BYTECOL', .FALSE., 0, - : wasset, hasnull, status ) - call checkbytes( table, %val( CNF_PVAL( pntr ) ), null, - : status ) - - colsize = 18 - call ast_putcolumndata( table2, 'byteCol', 0, colsize, - : %val( CNF_PVAL( pntr ) ), status ) - oldnull = ast_columnnull( table2, 'BYTECOL', .TRUE., null, - : wasset, hasnull, status ) - call ast_getcolumndata( table2, 'BYTECOL', 0.0, 0.0D0, colsize, - : %val( cnf_pval( pntr ) ), colsize, - : status ) - if( colsize .ne. 18 ) call stopit( status, - : 'FitsTable error 13g' ) - call checkbytes( table2, %val( CNF_PVAL( pntr ) ), null, - : status ) - - call psx_free( pntr, status ) - end if - - colsize = ast_columnsize( table, 'intcol', status ) - if( colsize .ne. 12 ) then - call stopit( status, 'FitsTable error 13h' ) - else - call psx_malloc( colsize, pntr, status ) - call ast_getcolumndata( table, 'INTCOL', 0.0, 0.0D0, colsize, - : %val( cnf_pval( pntr ) ), colsize, - : status ) - if( colsize .ne. 3 ) call stopit( status, - : 'FitsTable error 13i' ) - call checkints( table, %val( CNF_PVAL( pntr ) ), - : ast_columnnull( table, 'INTCOL', .FALSE., 0, - : wasset, hasnull, status ), - : status ) - - colsize = 12 - call ast_putcolumndata( table2, 'INTCol', 0, colsize, - : %val( CNF_PVAL( pntr ) ), status ) - - call ast_getcolumndata( table2, 'INTCOL', 0.0, 0.0D0, colsize, - : %val( cnf_pval( pntr ) ), colsize, - : status ) - if( colsize .ne. 3 ) call stopit( status, - : 'FitsTable error 13j' ) - call checkints( table2, %val( CNF_PVAL( pntr ) ), - : ast_columnnull( table2, 'INTCOL', .FALSE., 0, - : wasset, hasnull, status ), - : status ) - - call psx_free( pntr, status ) - end if - - - call ast_addcolumn( table, 'REALCOL', AST__FLOATTYPE, 0, 0, ' ', - : status ) - call ast_addcolumn( table2, 'REALCOL', AST__FLOATTYPE, 0, 0, ' ', - : status ) - call ast_mapput0r( table, 'REALCOL(1)', -10.0, ' ', status ) - call ast_mapput0r( table, 'REALCOL(3)', 10.0, ' ', status ) - - colsize = ast_columnsize( table, 'realcol', status ) - if( colsize .ne. 12 ) then - call stopit( status, 'FitsTable error 13k' ) - else - call psx_malloc( colsize, pntr, status ) - call ast_getcolumndata( table, 'REALCOL', -1.0, 0.0D0, colsize, - : %val( cnf_pval( pntr ) ), colsize, - : status ) - if( colsize .ne. 3 ) call stopit( status, - : 'FitsTable error 13l' ) - call checkreals( table, %val( CNF_PVAL( pntr ) ), -1.0, - : status ) - - colsize = 12 - call ast_putcolumndata( table2, 'realCol', 0, colsize, - : %val( CNF_PVAL( pntr ) ), status ) - - - call ast_mapremove( table2, 'REALCOL(2)', status ) - call ast_getcolumndata( table2, 'REALCOL', AST__NANR, 0.0D0, - : colsize, - : %val( cnf_pval( pntr ) ), colsize, - : status ) - if( colsize .ne. 3 ) call stopit( status, - : 'FitsTable error 13m' ) - call checkreals( table2, %val( CNF_PVAL( pntr ) ), AST__NANR, - : status ) - - call psx_free( pntr, status ) - end if - - call ast_removecolumn( table, 'REALCOL', status ) - - call ast_mapremove( table, 'BYTECOL(3)', status ) - call ast_mapremove( table, 'INTCOL(3)', status ) - call ast_mapremove( table, 'STRINGCOL(3)', status ) - - if( ast_geti( table, 'Nrow', status ) .ne. 3 ) then - call stopit( status, 'FitsTable error 14' ) - endif - - if( ast_geti( table, 'Ncolumn', status ) .ne. 3 ) then - call stopit( status, 'FitsTable error 15' ) - endif - - - - - header = ast_gettableheader( table, status ) - icard = 0 - do while( ast_findfits( header, '%f', card, .true., status ) ) - icard = icard + 1 - if( icard .gt. 20 ) then - call stopit( status, 'FitsTable error 16' ) - else if( card .ne. header2( icard ) ) then - call stopit( status, 'FitsTable error 17' ) - end if - end do - call ast_annul( header, status ) - if( icard .ne. 20 ) call stopit( status, 'FitsTable error 18' ) - - - - if( ast_columnnull( table, 'BYTECOL', .FALSE., 0, wasset, - : hasnull, status ) .ne. 254 ) then - call stopit( status, 'FitsTable error 19' ) - else if( wasset ) then - call stopit( status, 'FitsTable error 20' ) - else if( .not. hasnull ) then - call stopit( status, 'FitsTable error 21' ) - end if - - - - call ast_purgerows( table, status ) - if( ast_geti( table, 'Nrow', status ) .ne. 2 ) then - call stopit( status, 'FitsTable error 22' ) - endif - - if( ast_geti( table, 'Ncolumn', status ) .ne. 3 ) then - call stopit( status, 'FitsTable error 23' ) - endif - - header = ast_gettableheader( table, status ) - if( ast_getfitsi( header, 'TNULL1', ival, status ) ) then - call stopit( status, 'FitsTable error 24' ) - endif - call ast_annul( header, status ) - - if( ast_columnnull( table, 'BYTECOL', .TRUE., 11, wasset, - : hasnull, status ) .ne. 11 ) then - call stopit( status, 'FitsTable error 25' ) - else if( wasset ) then - call stopit( status, 'FitsTable error 26' ) - else if( hasnull ) then - call stopit( status, 'FitsTable error 27' ) - end if - - if( ast_columnnull( table, 'BYTECOL', .FALSE., 0, wasset, - : hasnull, status ) .ne. 11 ) then - call stopit( status, 'FitsTable error 28' ) - else if( .not. wasset ) then - call stopit( status, 'FitsTable error 29' ) - else if( hasnull ) then - call stopit( status, 'FitsTable error 30' ) - end if - - - table2 = ast_copy( table, status ) - - call ast_end( status ) - call err_rlse( status ) - -c call ast_activememory( 'testfitstable' ) - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All FitsTable tests passed' - else - write(*,*) 'FitsTable tests failed' - end if - - end - - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - end - - - - subroutine checkbytes( table, vals, null, status ) - implicit none - include 'SAE_PAR' - integer status, table, null, i - byte vals( * ), ans( 12 ), bnull - - data ans / 0, 1, 128, 127, -127, -1, 0, 1, 0, 1, 0, 1 / - - if( status .ne. sai__ok ) return - - do i = 1, 12 - if( vals( i ) .ne. ans( i ) ) then - write(*,*) 'i,vals,ans: ',i,' ',vals(i),' ',ans(i) - call stopit( status, 'FitsTable error checkbytes 1' ) - end if - end do - - bnull = null - do i = 13, 18 - if( vals( i ) .ne. bnull ) then - call stopit( status, 'FitsTable error checkbytes 2' ) - end if - end do - - end - - subroutine checkints( table, vals, null, status ) - implicit none - include 'SAE_PAR' - integer status, table, null - integer vals( * ) - - if( status .ne. sai__ok ) return - - if( vals( 1 ) .ne. null ) then - call stopit( status, 'FitsTable error checkints 1' ) - end if - - if( vals( 2 ) .ne. 10 ) then - call stopit( status, 'FitsTable error checkints 2' ) - end if - - if( vals( 3 ) .ne. -10 ) then - call stopit( status, 'FitsTable error checkints 3' ) - end if - - end - - subroutine checkreals( table, vals, null, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, table - real vals( * ), null - - if( status .ne. sai__ok ) return - - if( vals( 1 ) .ne. -10.0 ) then - call stopit( status, 'FitsTable error checkreals 1' ) - end if - - if( null .ne. AST__NANR ) then - if( vals( 2 ) .ne. null ) then - call stopit( status, 'FitsTable error checkreals 2a' ) - end if - else - if( .not. isnan( vals( 2 ) ) ) then - call stopit( status, 'FitsTable error checkreals 2b' ) - end if - end if - - if( vals( 3 ) .ne. 10.0 ) then - call stopit( status, 'FitsTable error checkreals 3' ) - end if - - end - - subroutine checkstrings( table, vals, status ) - implicit none - include 'SAE_PAR' - integer status, table, i, start, end, j - character ans( 9 )*10 - character vals*( * ) - - data ans / 'hello', ' ', 'goodbye', '', '', '', ' ', ' ', ' ' / - - if( status .ne. sai__ok ) return - - start = 1 - end = 10 - - do i = 1, 9 - - do j = 1, 11 - if( vals( start + j - 1 : start + j - 1 ) .lt. ' ' ) then - vals( start + j - 1 : start + j - 1 ) = ' ' - endif - end do - - if( vals( start : end ) .ne. ans( i ) ) then - write(*,*) 'start,end,i : ',start,' ',end,' ',i - write(*,*) 'vals: ',vals( start : end ) - write(*,*) 'ans: ',ans( i ) - call stopit( status, 'FitsTable error checkstrings 1' ) - end if - - start = start + 10 - end = end + 10 - - end do - - end - - - - diff --git a/ast/ast_tester/testflux.f b/ast/ast_tester/testflux.f deleted file mode 100644 index f24629f..0000000 --- a/ast/ast_tester/testflux.f +++ /dev/null @@ -1,354 +0,0 @@ - program testflux - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - double precision xin, xout - integer status, sf, ff, ff2, mp, fs, sf2 - status = sai__ok - - sf = ast_specframe( 'system=freq,unit=GHz', status ) - ff = ast_Fluxframe( 123.0D0, sf, ' ', status ) - - if( ast_GetD( ff, 'specval', status ) .ne. 123.0D0 ) then - call stopit( status, 'Error 1' ) - end if - - if( ast_Test( ff, 'specval', status ) ) then - call stopit( status, 'Error 2' ) - end if - - call ast_setd( ff, 'specval', 333.3D0, status ) - if( ast_GetD( ff, 'specval', status ) .ne. 333.3D0 ) then - call stopit( status, 'Error 3' ) - end if - - if( .not. ast_Test( ff, 'specval', status ) ) then - call stopit( status, 'Error 4' ) - end if - - call ast_clear( ff, 'specval', status ) - - if( ast_GetD( ff, 'specval', status ) .ne. 123.0D0 ) then - call stopit( status, 'Error 5' ) - end if - - if( ast_Test( ff, 'specval', status ) ) then - call stopit( status, 'Error 6' ) - end if - - - call checkDump( ff, 'CheckDump 1', status ) - - - ff2 = ast_Fluxframe( 123.1D0, sf, ' ', status ) - fs = ast_convert( ff, ff2, ' ', status ) - if( fs .eq. ast__null ) then - call stopit( status, 'error 8' ) - else - mp = ast_getmapping( fs, AST__BASE, AST__CURRENT, status ) - if( .not. ast_isaunitmap( mp, status ) ) then - call stopit( status, 'error 9' ) - end if - end if - - - - - - ff = ast_Fluxframe( 123.0D0, sf, 'unit=W/m^2/Hz', status ) - if( ast_GetC( ff, 'System', status ) .ne. 'FLXDN' ) then - write(*,*) ast_GetC( ff, 'System', status ) - call stopit( status, 'error 10' ) - endif - - ff2 = ast_Fluxframe( 123.0D0, sf, 'unit=W/m^2/GHz', status ) - if( ast_GetC( ff2, 'System', status ) .ne. 'FLXDN' ) then - write(*,*) ast_GetC( ff2, 'System', status ) - call stopit( status, 'error 11' ) - endif - - fs = ast_convert( ff2, ff, ' ', status ) - if( fs .eq. ast__null ) then - call stopit( status, 'error 12' ) - else - mp = ast_getmapping( fs, AST__BASE, AST__CURRENT, status ) - if( .not. ast_isazoommap( mp, status ) ) then - call stopit( status, 'error 13' ) - else if( abs( ast_getd( mp, 'Zoom', status ) - 1.0D-9 ) - : .gt. 1.0E-24 ) then - write(*,*) ast_getd( mp, 'Zoom', status ) - call stopit( status, 'error 14' ) - end if - end if - - - ff = ast_Fluxframe( 123.0D0, sf, 'unit=W/m^2/m', status ) - if( ast_GetC( ff, 'System', status ) .ne. 'FLXDNW' ) then - write(*,*) ast_GetC( ff, 'System', status ) - call stopit( status, 'error 15' ) - endif - - sf2 = ast_specframe( 'system=freq,unit=Hz', status ) - ff2 = ast_Fluxframe( 123.0D9, sf2, 'unit=W/m^2/Angstrom', status ) - if( ast_GetC( ff2, 'System', status ) .ne. 'FLXDNW' ) then - write(*,*) ast_GetC( ff2, 'System', status ) - call stopit( status, 'error 16' ) - endif - - fs = ast_convert( ff2, ff, ' ', status ) - if( fs .eq. ast__null ) then - call stopit( status, 'error 17' ) - else - mp = ast_getmapping( fs, AST__BASE, AST__CURRENT, status ) - if( .not. ast_isazoommap( mp, status ) ) then - call stopit( status, 'error 18' ) - else if( ast_getd( mp, 'Zoom', status ) .ne. 1.0D10 ) then - write(*,*) ast_getd( mp, 'Zoom', status ) - call stopit( status, 'error 19' ) - end if - end if - - - - - ff = ast_Fluxframe( 123.0D0, sf, 'unit=W/m^2/m', status ) - if( ast_GetC( ff, 'System', status ) .ne. 'FLXDNW' ) then - write(*,*) ast_GetC( ff, 'System', status ) - call stopit( status, 'error 20' ) - endif - - sf2 = ast_specframe( 'system=wave,unit=nm', status ) - ff2 = ast_Fluxframe( 2437337.06D0, sf2, 'unit=W/m^2/Angstrom', - : status ) - if( ast_GetC( ff2, 'System', status ) .ne. 'FLXDNW' ) then - write(*,*) ast_GetC( ff2, 'System', status ) - call stopit( status, 'error 21' ) - endif - - fs = ast_convert( ff, ff2, ' ', status ) - if( fs .eq. ast__null ) then - call stopit( status, 'error 22' ) - else - mp = ast_getmapping( fs, AST__BASE, AST__CURRENT, status ) - if( .not. ast_isazoommap( mp, status ) ) then - call stopit( status, 'error 23' ) - else if( ast_getd( mp, 'Zoom', status ) .ne. 1.0D-10 ) then - write(*,*) ast_getd( mp, 'Zoom', status ) - call stopit( status, 'error 24' ) - end if - end if - - - sf = ast_specframe( 'system=freq,unit=GHz', status ) - ff = ast_Fluxframe( 123.0D0, sf, 'unit=W/m^2/Hz', status ) - sf2 = ast_specframe( 'system=wave,unit=nm', status ) - ff2 = ast_Fluxframe( 2437337.06D0, sf2, 'unit=W/m^2/m', - : status ) - fs = ast_convert( ff, ff2, ' ', status ) - if( fs .eq. ast__null ) then - call stopit( status, 'error 25' ) - else - xin = 1.0D-13 - call ast_tran1( fs, 1,xin, 1,xout, status ) - if( abs( xout - 5.04649119D0 ) .gt. 1.0D-6 ) then - call stopit( status, 'error 26' ) - end if - end if - - - sf = ast_specframe( 'system=freq,unit=GHz', status ) - ff = ast_Fluxframe( 123.0D0, sf, 'unit=W/m^2/Hz/arcsec**2', - : status ) - if( ast_getc( ff, 'System', status ) .ne. 'SFCBR' ) - : call stopit( status, 'error 27a' ) - - sf2 = ast_specframe( 'system=wave,unit=nm', status ) - ff2 = ast_Fluxframe( 2437337.06D0, sf2, 'unit=W/m^2/m/deg**2', - : status ) - if( ast_getc( ff2, 'System', status ) .ne. 'SFCBRW' ) - : call stopit( status, 'error 27b' ) - - fs = ast_convert( ff, ff2, ' ', status ) - if( fs .eq. ast__null ) then - call stopit( status, 'error 27' ) - else - xin = 1.0D-13 - call ast_tran1( fs, 1,xin, 1,xout, status ) - if( abs( xout - 65402525.8D0 ) .gt. 1.0 ) then - write(*,*) xout - 65402525.8D0 - call stopit( status, 'error 28' ) - end if - end if - - - ff = ast_Fluxframe( 123.0D0, sf, 'unit=W/m^2/Hz/arcsec**2', - : status ) - ff2 = ast_Fluxframe( 2437337.06D0, sf2, 'unit=W/m^2/m', - : status ) - - fs = ast_convert( ff, ff2, ' ', status ) - if( fs .ne. ast__null ) call stopit( status, 'error 29' ) - - - - - - - - - - - - - - - - if( status .eq. sai__ok ) then - write(*,*) 'All FluxFrame tests passed' - else - write(*,*) 'FluxFrame tests failed' - end if - - end - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - - subroutine checkdump( obj, text, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*) - integer obj, status, next, end, ch, result, ll, overlap - external mysource, mysink - character buf*25000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - ch = ast_channel( mysource, mysink, ' ', status ) - - - ll = 110 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - - next = 1 - result = ast_read( ch, status ) - if( result .eq. ast__null ) then - write(*,*) text - call stopit( status, 'Cannot read object from channel' ) - end if - - - - if( ast_getd( obj, 'specval', status ) .ne. - : ast_getd( result, 'specval', status ) ) then - call ast_Show( obj, status ) - call ast_Show( result, status ) - write(*,*) text - call stopit( status, 'Object has changed' ) - end if - - end - - subroutine sink1( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - logical fsfound, done - common /sink1com/ fsfound, done - - integer status, l - character line*200 - - if( status .ne. sai__ok ) return - call ast_getline( line, l, status ) - - if( index( line( : l ),'Unc =' ) .GT. 0 ) then - done = .true. - - else if( .not. done .and. - : index( line( : l ),'FrameSet' ) .GT. 0 ) then - fsfound= .true. - end if - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll - character buf*25000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - call ast_putline( buf( next : ), ll, status ) - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll - character buf*25000 - character line*1000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - - if( next + ll - 1 .ge. 25000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf( next : next + l) - write(*,*) 'Line length ',l - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - endif - - next = next + ll - - end - - diff --git a/ast/ast_tester/testframeset.f b/ast/ast_tester/testframeset.f deleted file mode 100644 index 0c9c52e..0000000 --- a/ast/ast_tester/testframeset.f +++ /dev/null @@ -1,391 +0,0 @@ - program testframeset - implicit none - - include 'AST_PAR' - include 'AST_ERR' - include 'SAE_PAR' - - integer status, pfrm, ffrm, p2fmap, fs, p2fmap2, result, orig - double precision ina(2), inb(2), outa(2), outb(2), xout, yout - character text*100 - -c call ast_watchmemory(100) - - - status = sai__ok - call err_mark( status ) - call ast_begin( status ) - - - pfrm = ast_frame( 2, "Domain=PIXEL", status ) - ffrm = ast_frame( 2, "Domain=FPLANE", status ) - - ina( 1 ) = 1.0 - ina( 2 ) = 1.0 - inb( 1 ) = 100.0 - inb( 2 ) = 200.0 - - outa( 1 ) = -2.5 - outa( 2 ) = -1.0 - outb( 1 ) = 2.5 - outb( 2 ) = 1.0 - p2fmap = ast_winmap( 2, ina, inb, outa, outb, ' ', status ) - - fs = ast_frameset( pfrm, ' ', status ) - call ast_addframe( fs, AST__CURRENT, p2fmap, ffrm, status ) - - call ast_setc( fs, 'Base', 'Fplane', status ) - if( ast_geti( fs, 'Base', status ) .ne. 2 ) - : call stopit( status, 'Error -3' ) - - call ast_setc( fs, 'Base', 'pixel', status ) - if( ast_geti( fs, 'Base', status ) .ne. 1 ) - : call stopit( status, 'Error -2' ) - - call ast_setc( fs, 'Current', 'PIXEL', status ) - if( ast_geti( fs, 'Current', status ) .ne. 1 ) - : call stopit( status, 'Error -1' ) - - call ast_setc( fs, 'Current', 'fplane', status ) - if( ast_geti( fs, 'Current', status ) .ne. 2 ) - : call stopit( status, 'Error 0' ) - - text = ast_getc( fs, 'AllVariants', status ) - if( text .ne. 'FPLANE' ) call stopit( status, 'Error 1' ) - - text = ast_getc( fs, 'Variant', status ) - if( text .ne. 'FPLANE' ) call stopit( status, 'Error 2' ) - - if( ast_test( fs, 'Variant', status ) ) call stopit( status, - : 'Error 3' ) - - - call ast_addvariant( FS, ast__null, 'FP1', status ) - - text = ast_getc( fs, 'AllVariants', status ) - if( text .ne. 'FP1' ) call stopit( status, 'Error 4' ) - - text = ast_getc( fs, 'Variant', status ) - if( text .ne. 'FP1' ) call stopit( status, 'Error 5' ) - - if( .not. ast_test( fs, 'Variant', status ) ) call stopit( status, - : 'Error 6' ) - - call ast_clear( fs, 'Variant', status ) - - text = ast_getc( fs, 'AllVariants', status ) - if( text .ne. 'FPLANE' ) call stopit( status, 'Error 7' ) - - text = ast_getc( fs, 'Variant', status ) - if( text .ne. 'FPLANE' ) call stopit( status, 'Error 8' ) - - if( ast_test( fs, 'Variant', status ) ) call stopit( status, - : 'Error 9' ) - - call ast_addvariant( FS, ast__null, 'FP1', status ) - - outa( 1 ) = 100.0 - outa( 2 ) = 100.0 - outb( 1 ) = 200.0 - outb( 2 ) = 200.0 - p2fmap2 = ast_winmap( 2, ina, inb, outa, outb, ' ', status ) - - call ast_invert( p2fmap, status ) - call ast_addvariant( fs, ast_simplify( - : ast_cmpmap( p2fmap, p2fmap2, 1, ' ', - : status ), status ), - : 'FP2', status ) - - text = ast_getc( fs, 'AllVariants', status ) - if( text .ne. 'FP1 FP2' ) call stopit( status, 'Error 10' ) - - text = ast_getc( fs, 'Variant', status ) - if( text .ne. 'FP2' ) call stopit( status, 'Error 11' ) - - if( .not. ast_test( fs, 'Variant', status ) ) call stopit( status, - : 'Error 12' ) - call ast_tran2( fs, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout - 150.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout - 150.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 13' ) - - call ast_setc( fs, 'Variant', 'FP1', status ) - call ast_tran2( fs, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout - 0.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout - 0.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 14' ) - - outa( 1 ) = -100.0 - outa( 2 ) = -100.0 - outb( 1 ) = -200.0 - outb( 2 ) = -200.0 - p2fmap2 = ast_winmap( 2, ina, inb, outa, outb, ' ', status ) - - p2fmap = ast_getmapping( fs, AST__CURRENT, AST__BASE, status ) - call ast_addvariant( fs, ast_simplify( - : ast_cmpmap( p2fmap, p2fmap2, 1, ' ', - : status ), status ), - : 'FP3', status ) - - text = ast_getc( fs, 'AllVariants', status ) - if( text .ne. 'FP1 FP2 FP3' ) call stopit( status, 'Error 15' ) - - text = ast_getc( fs, 'Variant', status ) - if( text .ne. 'FP3' ) call stopit( status, 'Error 16' ) - - if( .not. ast_test( fs, 'Variant', status ) ) call stopit( status, - : 'Error 17' ) - call ast_tran2( fs, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout + 150.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout + 150.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 18' ) - - call ast_setc( fs, 'Variant', 'FP2', status ) - call ast_tran2( fs, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout - 150.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout - 150.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 19' ) - - call checkdump( fs, result, status ) - - text = ast_getc( result, 'AllVariants', status ) - if( text .ne. 'FP1 FP2 FP3' ) call stopit( status, 'Error 20' ) - - text = ast_getc( result, 'Variant', status ) - if( text .ne. 'FP2' ) call stopit( status, 'Error 21' ) - - call ast_tran2( result, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout - 150.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout - 150.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 22' ) - - - - orig = ast_geti( fs, 'Current', status ) - call ast_addframe( fs, AST__CURRENT, AST_UNITMAP( 2, '', status ), - : AST_FRAME( 2, "Domain=DSB", status ), status ) - call ast_tran2( fs, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout - 150.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout - 150.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 23' ) - - if( status .eq. sai__ok ) then - call ast_setc( fs, 'Variant', 'FP1', status ) - if( status .eq. ast__attin ) then - call err_annul( status ) - else - call err_flush( status ) - call stopit( status, 'Error 24' ) - end if - end if - - text = ast_getc( fs, 'AllVariants', status ) - if( text .ne. 'DSB' ) call stopit( status, 'Error 25' ) - - text = ast_getc( fs, 'Variant', status ) - if( text .ne. 'DSB' ) call stopit( status, 'Error 26' ) - - if( ast_test( fs, 'Variant', status ) ) call stopit( status, - : 'Error 27' ) - - call ast_mirrorvariants( fs, orig, status ) - - text = ast_getc( fs, 'AllVariants', status ) - if( text .ne. 'FP1 FP2 FP3' ) call stopit( status, 'Error 28' ) - - text = ast_getc( fs, 'Variant', status ) - if( text .ne. 'FP2' ) call stopit( status, 'Error 29' ) - - if( .not. ast_test( fs, 'Variant', status ) ) call stopit( status, - : 'Error 30' ) - - call ast_tran2( fs, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout - 150.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout - 150.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 31' ) - - call ast_set( fs, 'Variant=FP1', status ) - text = ast_getc( fs, 'Variant', status ) - if( text .ne. 'FP1' ) call stopit( status, 'Error 32' ) - - call ast_tran2( fs, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout - 0.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout - 0.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 33' ) - - call checkdump( fs, result, status ) - - text = ast_getc( result, 'AllVariants', status ) - if( text .ne. 'FP1 FP2 FP3' ) call stopit( status, 'Error 34' ) - - text = ast_getc( result, 'Variant', status ) - if( text .ne. 'FP1' ) call stopit( status, 'Error 35' ) - - call ast_tran2( result, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout - 0.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout - 0.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 36' ) - - result = ast_copy( fs, status ) - - text = ast_getc( result, 'AllVariants', status ) - if( text .ne. 'FP1 FP2 FP3' ) call stopit( status, 'Error 37' ) - - text = ast_getc( result, 'Variant', status ) - if( text .ne. 'FP1' ) call stopit( status, 'Error 38' ) - - call ast_tran2( result, 1, 50.5D0, 100.5D0, .TRUE., xout, yout, - : status ) - if( abs( xout - 0.0D0 ) .gt. 1.0E-6 .OR. - : abs( yout - 0.0D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Error 39' ) - - call ast_clear( fs, 'Variant', status ) - text = ast_getc( fs, 'Variant', status ) - if( text .ne. 'DSB' ) call stopit( status, 'Error 40' ) - - - - - - - call ast_end( status ) - call err_rlse( status ) - - call ast_activememory( 'testframeset' ) - call ast_flushmemory( 1 ); - - if( status .eq. sai__ok ) then - write(*,*) 'All FrameSet tests passed' - else - write(*,*) 'FrameSet tests failed' - end if - - end - - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - subroutine checkdump( obj, result, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character key*30,txt1*50,txt2*50 - integer obj, status, next, end, ch, result, ll, overlap, size, - : i, type,obj1,obj2,l1,l2,nl,nrow,nrowold - external mysource, mysink - character buf*400000 - - common /ss1/ buf - common /ss2/ next, end, ll, nl - - if( status .ne. sai__ok ) return - - ch = ast_channel( mysource, mysink, ' ', status ) - - nl = 0 - ll = 110 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - - next = 1 - nl = 0 - result = ast_read( ch, status ) - - if( result .eq. ast__null ) then - call stopit( status, 'Cannot read object from channel' ) - end if - - if( .not. ast_isaframeset( result, status ) ) then - call stopit( status, 'Object read from channel is not a '// - : 'FrameSet') - end if - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll, nl - character buf*400000 - - common /ss1/ buf - common /ss2/ next, end, ll,nl - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - -c write(*,*) buf( next : next + ll - 1 ) - call ast_putline( buf( next : ), ll, status ) - nl = nl + 1 - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll, nl - character buf*400000 - character line*1000 - - common /ss1/ buf - common /ss2/ next, end, ll, nl - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - - if( next + ll - 1 .ge. 400000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf( next : next + l) - write(*,*) 'Line length ',l - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - nl = nl + 1 - endif - - next = next + ll - - end - - diff --git a/ast/ast_tester/testkeymap.f b/ast/ast_tester/testkeymap.f deleted file mode 100644 index fcd5d5c..0000000 --- a/ast/ast_tester/testkeymap.f +++ /dev/null @@ -1,1369 +0,0 @@ - program testkeymap - implicit none - include 'AST_PAR' - include 'AST_ERR' - include 'SAE_PAR' - integer status,map,map2,ival,aval,l,ivec(2),avec(4),nval,i,iat, - : map1, map3, km2 - character cval*20,cvec(3)*10,key*20,cval0*40 - double precision dval, dvec(2) - logical gota, gotc, gotd, goti, gotr, gotw, lval - real rval - integer*2 sval,svec(2) - - status = sai__ok - call err_mark( status ) - call ast_begin( status ) - -c call ast_watchmemory( 29286 ) - - call testcasesens( status ) - call testsorting( status ) - - map = ast_keymap( ' ', status ) - - call ast_MapPut0s( map, 'Freds', 1999, 'com 1', status ) - call ast_MapPut0i( map, 'Fredi', 1999, 'com 1', status ) - call ast_MapPut0d( map, 'Fredd', 1999.9D0, 'com2 ', status ) - call ast_MapPut0r( map, 'Fredr', 1999.9, 'com2 ', status ) - call ast_MapPut0c( map, 'Fredc', 'Hello', ' ', status ) - call ast_MapPut0A( map, 'Freda', ast_skyframe( ' ', status ), - : ' ', status ) - - if( .not. ast_mapdefined( map, 'Freda', status ) ) then - call stopit( status, 'Error -12' ) - end if - - if( ast_maplenc( map, 'Fredi', status ) .ne. 4 ) then - write(*,*) ast_maplenc( map, 'Fredi', status ) - call stopit( status, 'Error -11' ) - end if - - if( ast_maplenc( map, 'Freda', status ) .ne. 0 ) then - write(*,*) ast_maplenc( map, 'Freda', status ) - call stopit( status, 'Error -10' ) - end if - - if( ast_maplenc( map, 'Fredc', status ) .ne. 5 ) then - write(*,*) ast_maplenc( map, 'Fredc', status ) - call stopit( status, 'Error -9' ) - end if - - if( ast_maptype( map, 'freda', status ) .ne. AST__BADTYPE) then - call stopit( status, 'Error -8' ) - end if - - if( ast_maptype( map, 'Freda', status ) .ne. AST__OBJECTTYPE) then - call stopit( status, 'Error -7' ) - end if - - if( ast_maptype( map, 'Fredc', status ) .ne. AST__STRINGTYPE) then - call stopit( status, 'Error -6' ) - end if - - if( ast_maptype( map, 'Fredd', status ) .ne. AST__DOUBLETYPE) then - call stopit( status, 'Error -5' ) - end if - - if( ast_maptype( map, 'Fredr', status ) .ne. AST__FLOATTYPE) then - call stopit( status, 'Error -5b' ) - end if - - if( ast_maptype( map, 'Fredi', status ) .ne. AST__INTTYPE ) then - call stopit( status, 'Error -4' ) - end if - - if( ast_maphaskey( map, 'fredi', status ) ) then - call stopit( status, 'Error -3' ) - end if - - if( .not. ast_maphaskey( map, 'Fredi', status ) ) then - call stopit( status, 'Error -2' ) - end if - - map2 = ast_copy( map, status ) - - - if( ast_mapsize( map2, status ) .ne. 6 ) then - write(*,*) ast_mapsize( map2, status ) - call stopit( status, 'Error 0' ) - end if - - goti = .false. - gotd = .false. - gotr = .false. - gotc = .false. - gota = .false. - gotw = .false. - - do i = 1, ast_mapsize( map2, status ) - key = ast_mapkey( map2, i, status ) - if( .not. goti .and. key .eq. 'Fredi' ) then - goti = .true. - else if( .not. gotd .and. key .eq. 'Fredd' ) then - gotd = .true. - else if( .not. gotw .and. key .eq. 'Freds' ) then - gotw = .true. - else if( .not. gotr .and. key .eq. 'Fredr' ) then - gotr = .true. - else if( .not. gotc .and. key .eq. 'Fredc' ) then - gotc = .true. - else if( .not. gota .and. key .eq. 'Freda' ) then - gota = .true. - else - call stopit( status, 'Error badkey' ) - endif - end do - - if( .not. ( goti .AND. gotd .AND. gotc - : .AND. gota .and. gotr .and. gotw) ) then - call stopit( status, 'Error nokey' ) - endif - - if( ast_maplength( map2, 'Fredi', status ) .ne. 1 ) then - write(*,*) ast_maplength( map2, 'Fredi', status ) - call stopit( status, 'Error -1' ) - end if - - if( .not. ast_mapget0i( map2, 'Fredi', ival, status ) ) then - call stopit( status, 'Error 1' ) - else if( ival .ne. 1999 ) then - write(*,*) ival - call stopit( status, 'Error 2' ) - end if - - if( .not. ast_mapget0s( map2, 'Freds', sval, status ) ) then - call stopit( status, 'Error 1' ) - else if( sval .ne. 1999 ) then - write(*,*) ival - call stopit( status, 'Error 2B' ) - end if - - if( .not. ast_mapget0d( map2, 'Fredd', dval, status ) ) then - call stopit( status, 'Error 3' ) - else if( dval .ne. 1999.9D0 ) then - write(*,*) dval - 1999.9D0 - call stopit( status, 'Error 4' ) - end if - - if( .not. ast_mapget0r( map2, 'Fredr', rval, status ) ) then - call stopit( status, 'Error 3b' ) - else if( rval .ne. 1999.9 ) then - write(*,*) rval - 1999.9 - call stopit( status, 'Error 4b' ) - end if - - if( .not. ast_mapget0c( map2, 'Fredc', cval, l, status ) ) then - call stopit( status, 'Error 5' ) - else if( l .ne. 5 ) then - write(*,*) l - call stopit( status, 'Error 6' ) - else if( cval( :l ) .ne. 'Hello' ) then - write(*,*) cval( :l ) - call stopit( status, 'Error 7' ) - end if - - if( .not. ast_mapgetc( map2, 'Fredc', cval, l, status ) ) then - call stopit( status, 'Error 5b' ) - else if( l .ne. 5 ) then - write(*,*) l - call stopit( status, 'Error 6b' ) - else if( cval( :l ) .ne. 'Hello' ) then - write(*,*) cval( :l ) - call stopit( status, 'Error 7b' ) - end if - - if( .not. ast_mapget0a( map2, 'Freda', aval, status ) ) then - call stopit( status, 'Error 8' ) - else if( .not. ast_IsASkyFrame( aval, STATUS ) ) then - call stopit( status, 'Error 9' ) - end if - - if( .not. ast_mapget0d( map2, 'Fredi', dval, status ) ) then - call stopit( status, 'Error 10' ) - else if( dval .ne. 1999 ) then - write(*,*) dval - call stopit( status, 'Error 11' ) - end if - - if( .not. ast_mapget0r( map2, 'Fredi', rval, status ) ) then - call stopit( status, 'Error 10b' ) - else if( rval .ne. 1999 ) then - call stopit( status, 'Error 11b' ) - end if - - if( .not. ast_mapget0c( map2, 'Fredi', cval, l, status ) ) then - call stopit( status, 'Error 12' ) - else if( l .ne. 4 ) then - write(*,*) l - call stopit( status, 'Error 13a' ) - else if( cval( :l ) .ne. '1999' ) then - write(*,*) cval - call stopit( status, 'Error 13' ) - end if - - if( .not. ast_mapget0i( map2, 'Fredd', ival, status ) ) then - call stopit( status, 'Error 14' ) - else if( ival .ne. 2000.0 ) then - write(*,*) ival - call stopit( status, 'Error 15' ) - end if - - if( .not. ast_mapget0s( map2, 'Fredd', sval, status ) ) then - call stopit( status, 'Error 14b' ) - else if( sval .ne. 2000.0 ) then - write(*,*) sval - call stopit( status, 'Error 15b' ) - end if - - if( .not. ast_mapget0c( map2, 'Fredd', cval, l, status ) ) then - call stopit( status, 'Error 16' ) - else if( l .ne. 6 ) then - write(*,*) l - call stopit( status, 'Error 17a' ) - else if( cval( :l ) .ne. '1999.9' ) then - write(*,*) cval - call stopit( status, 'Error 17' ) - end if - - - ivec(1) = -10 - ivec(2) = -10 - if( .not. ast_mapget1i( map2, 'Fredi', 2, nval, ivec, - : status ) ) then - call stopit( status, 'Error 18' ) - else if( nval .ne. 1 ) then - write(*,*) nval - call stopit( status, 'Error 19' ) - else if( ivec( 1 ) .ne. 1999 ) then - write(*,*) ivec( 1 ) - call stopit( status, 'Error 20' ) - else if( ivec( 2 ) .ne. -10 ) then - write(*,*) ivec( 2 ) - call stopit( status, 'Error 21' ) - end if - - - dvec(1) = -10.0D0 - dvec(2) = -10.0D0 - if( .not. ast_mapget1d( map2, 'Fredd', 2, nval, dvec, - : status ) ) then - call stopit( status, 'Error 22' ) - else if( nval .ne. 1 ) then - write(*,*) nval - call stopit( status, 'Error 23' ) - else if( dvec( 1 ) .ne. 1999.9D0 ) then - write(*,*) dvec( 1 ) - call stopit( status, 'Error 24' ) - else if( dvec( 2 ) .ne. -10.0D0 ) then - write(*,*) dvec( 2 ) - call stopit( status, 'Error 25' ) - end if - - avec(1) = AST__NULL - avec(2) = AST__NULL - if( .not. ast_mapget1a( map2, 'Freda', 2, nval, avec, - : status ) ) then - call stopit( status, 'Error 26' ) - else if( nval .ne. 1 ) then - write(*,*) nval - call stopit( status, 'Error 27' ) - else if( .not. ast_IsASkyFrame( avec( 1 ), STATUS ) ) then - write(*,*) ast_getc( avec( 1 ), 'class', status ) - call stopit( status, 'Error 28' ) - else if( avec( 2 ) .ne. AST__NULL ) then - write(*,*) ast_getc( avec( 2 ), 'class', status ) - call stopit( status, 'Error 29' ) - end if - - - ivec(1)=1999 - ivec(2)=0 - call ast_mapput1i( map, 'Fredi', 2, ivec, 'com 1', STATUS ) - - if( ast_maplength( map, 'Fredi', status ) .ne. 2 ) then - write(*,*) ast_maplength( map, 'Fredi', status ) - call stopit( status, 'Error 29b' ) - - end if - - svec(1)=1999 - svec(2)=0 - call ast_mapput1s( map, 'Freds', 2, svec, 'com 1', STATUS ) - - if( ast_maplength( map, 'Freds', status ) .ne. 2 ) then - write(*,*) ast_maplength( map, 'Freds', status ) - call stopit( status, 'Error 29c' ) - - end if - - dvec(1)=1999.9D0 - dvec(2)=-0.01D0 - call ast_mapput1d( map, 'Fredd', 2, dvec, 'com2', STATUS ) - - cvec(1)='Hello' - cvec(2)=' ' - cvec(3)=' Hello' - call ast_mapput1c( map, 'Fredc', 3, cvec, ' ', STATUS ) - - if( ast_maplenc( map, 'Fredc', status ) .ne. len(cvec(3)) ) then - write(*,*) ast_maplenc( map, 'Fredc', status ) - call stopit( status, 'Error 29c' ) - end if - - avec(1) = ast_skyframe( ' ', status ) - avec(2) = AST__NULL - avec(3) = ast_specframe( ' ', status ) - avec(4) = AST__NULL - call ast_mapput1a( map, 'Freda', 4, avec, ' ', STATUS ) - - map2 = ast_copy( map, status ) - - if( .not. ast_mapget0i( map2, 'Fredi', ival, status ) ) then - call stopit( status, 'Error A1' ) - else if( ival .ne. 1999 ) then - write(*,*) ival - call stopit( status, 'Error A2' ) - end if - - if( .not. ast_mapget0d( map2, 'Fredd', dval, status ) ) then - call stopit( status, 'Error A3' ) - else if( dval .ne. 1999.9D0 ) then - write(*,*) dval - 1999.9D0 - call stopit( status, 'Error A4' ) - end if - - if( .not. ast_mapget0c( map2, 'Fredc', cval, l, status ) ) then - call stopit( status, 'Error A5' ) - else if( l .ne. 10 ) then - write(*,*) l - call stopit( status, 'Error A6' ) - else if( cval( :l ) .ne. 'Hello ' ) then - write(*,*) cval( :l ) - call stopit( status, 'Error A7' ) - end if - - if( .not. ast_mapget0a( map2, 'Freda', aval, status ) ) then - call stopit( status, 'Error A8' ) - else if( .not. ast_IsASkyFrame( aval, STATUS ) ) then - call stopit( status, 'Error A9' ) - end if - - if( .not. ast_mapget0d( map2, 'Fredi', dval, status ) ) then - call stopit( status, 'Error A10' ) - else if( dval .ne. 1999 ) then - write(*,*) dval - call stopit( status, 'Error A11' ) - end if - - if( .not. ast_mapget0c( map2, 'Fredi', cval, l, status ) ) then - call stopit( status, 'Error A12' ) - else if( l .ne. 4 ) then - write(*,*) l - call stopit( status, 'Error A13a' ) - else if( cval( :l ) .ne. '1999' ) then - write(*,*) cval - call stopit( status, 'Error A13' ) - end if - - if( .not. ast_mapget0i( map2, 'Fredd', ival, status ) ) then - call stopit( status, 'Error A14' ) - else if( ival .ne. 2000.0 ) then - write(*,*) ival - call stopit( status, 'Error A15' ) - end if - - if( .not. ast_mapget0c( map2, 'Fredd', cval, l, status ) ) then - call stopit( status, 'Error A16' ) - else if( l .ne. 6 ) then - write(*,*) l - call stopit( status, 'Error A17a' ) - else if( cval( :l ) .ne. '1999.9' ) then - write(*,*) cval - call stopit( status, 'Error A17' ) - end if - - -c Read vector entries as vectors. - if( .not. ast_mapget1i( map2, 'Fredi', 2, nval, ivec, - : status ) ) then - call stopit( status, 'Error B1' ) - else if( nval .ne. 2 ) then - write(*,*) nval - call stopit( status, 'Error B2a' ) - else if( ivec( 1 ) .ne. 1999 ) then - write(*,*) ivec( 1 ) - call stopit( status, 'Error B2b' ) - else if( ivec( 2 ) .ne. 0 ) then - write(*,*) ivec( 2 ) - call stopit( status, 'Error B2c' ) - end if - - if( .not. ast_mapget1d( map2, 'Fredd', 2, nval, dvec, - : status ) ) then - call stopit( status, 'Error B3' ) - else if( nval .ne. 2 ) then - write(*,*) nval - call stopit( status, 'Error B4a' ) - else if( dvec( 1 ) .ne. 1999.9D0 ) then - write(*,*) dvec( 1 ) - call stopit( status, 'Error B4b' ) - else if( dvec( 2 ) .ne. -0.01D0 ) then - write(*,*) dvec( 2 ) - call stopit( status, 'Error B4c' ) - end if - - if( .not. ast_mapget1a( map2, 'Freda', 4, nval, avec, - : status ) ) then - call stopit( status, 'Error B5' ) - else if( nval .ne. 4 ) then - write(*,*) nval - call stopit( status, 'Error B6a' ) - else if( .not. ast_isaskyframe( avec( 1 ), status ) ) then - write(*,*) ast_getc( avec( 1 ), 'class', status ) - call stopit( status, 'Error B6b' ) - else if( avec( 2 ) .NE. AST__NULL ) then - write(*,*) ast_getc( avec( 2 ), 'class', status ) - call stopit( status, 'Error B6c' ) - else if( .not. ast_isaspecframe( avec( 3 ), status ) ) then - write(*,*) ast_getc( avec( 3 ), 'class', status ) - call stopit( status, 'Error B6d' ) - else if( avec( 4 ) .ne. AST__NULL ) then - write(*,*) ast_getc( avec( 4 ), 'class', status ) - call stopit( status, 'Error B6e' ) - end if - - - if( .not. ast_mapget1c( map2, 'Fredc', 3, nval, cvec, - : status ) ) then - call stopit( status, 'Error B7' ) - else if( nval .ne. 3 ) then - write(*,*) nval - call stopit( status, 'Error B8a' ) - else if( cvec( 1 ) .ne. 'Hello ' ) then - write(*,*) cvec( 1 ) - call stopit( status, 'Error B8b' ) - else if( cvec( 2 ) .ne. ' ' ) then - write(*,*) cvec( 2 ) - call stopit( status, 'Error B8c' ) - else if( cvec( 3 ) .ne. ' Hello ' ) then - write(*,*) cvec( 2 ) - call stopit( status, 'Error B8d' ) - end if - -c Read entire vector as a single string. - if( .not. ast_mapgetc( map2, 'Fredc', cval0, l, status ) ) then - call stopit( status, 'Error BB1' ) - else if( l .ne. 34 ) then - call stopit( status, 'Error BB2' ) - else if( cval0 .ne. '(Hello , , Hello )' ) then - call stopit( status, 'Error BB3' ) - end if - -c Read single elements of vector entries as scalars. - if( .not. ast_mapgetelemi( map2, 'Fredi', 1, ivec, - : status ) ) then - call stopit( status, 'Error B1z' ) - else if( ivec( 1 ) .ne. 1999 ) then - write(*,*) ivec( 1 ) - call stopit( status, 'Error B2bz' ) - end if - - if( .not. ast_mapgetelemd( map2, 'Fredd', 2, dvec, - : status ) ) then - call stopit( status, 'Error B3z' ) - else if( dvec( 1 ) .ne. -0.01D0 ) then - write(*,*) dvec( 1 ) - call stopit( status, 'Error B4cz' ) - end if - - if( .not. ast_mapgetelema( map2, 'Freda', 3, avec, - : status ) ) then - call stopit( status, 'Error B5z' ) - else if( .not. ast_isaspecframe( avec( 1 ), status ) ) then - write(*,*) ast_getc( avec( 1 ), 'class', status ) - call stopit( status, 'Error B6dz' ) - end if - - - if( .not. ast_mapgetelemc( map2, 'Fredc', 3, cval0, - : status ) ) then - call stopit( status, 'Error B7z' ) - else if( cval0 .ne. ' Hello ' ) then - write(*,*) cval0 - call stopit( status, 'Error B8dz' ) - end if - - - call ast_mapremove( map2, 'Bert', status ) - call ast_mapremove( map2, 'Fredc', status ) - if( ast_mapget1c( map2, 'Fredc', 3, nval, cvec, status ) ) then - call stopit( status, 'Error C1' ) - endif - - - call checkDump( map2, 'checkDump 1 ', status ) - - call ast_Annul( map, status ) - call ast_Annul( map2, status ) - - - map = ast_keymap( ' ', status ) - - do i = 1, 500 - key = 'Fred' - iat = 4 - call chr_puti( i, key, iat ) - call ast_MapPut0i( map, key, i, ' ', status ) - end do - - if( ast_mapsize( map, status ) .ne. 500 ) then - call stopit( status, 'Error d1 ' ) - end if - - if( ast_maptype( map, 'Fred123', status ) .ne. AST__INTTYPE ) then - call stopit( status, 'Error d2 ' ) - end if - - if( .not. ast_mapget0c( map, 'Fred489', cval, l, status ) ) then - call stopit( status, 'Error d2 ' ) - else if( cval( : l ) .ne. '489' ) then - call stopit( status, 'Error d3 ' ) - end if - - call checkDump( map, 'checkDump 2 ', status ) - - - -c Test putting single elements into vector entries. - map = ast_keymap( ' ', status ) - - ivec(1) = 1 - ivec(2) = 2 - call ast_mapput1i( map, 'Fredi', 2, ivec, 'com 1', STATUS ) - - call ast_mapputelemi( map, 'Fredi', 1, -1, STATUS ) - if( .not. ast_mapgetelemi( map, 'Fredi', 1, ival, - : status ) ) then - call stopit( status, 'Error GETELEM_1' ) - else if( ival .ne. -1 ) then - write(*,*) ival - call stopit( status, 'Error GETELEM_2' ) - end if - - call ast_mapputelemi( map, 'Fredi', 10, -2, STATUS ) - if( .not. ast_mapgetelemi( map, 'Fredi', 3, ival, - : status ) ) then - call stopit( status, 'Error GETELEM_3' ) - else if( ival .ne. -2 ) then - write(*,*) ival - call stopit( status, 'Error GETELEM_4' ) - end if - - call ast_mapputelemi( map, 'Fredi', 0, -3, STATUS ) - if( .not. ast_mapgetelemi( map, 'Fredi', 4, ival, - : status ) ) then - call stopit( status, 'Error GETELEM_5' ) - else if( ival .ne. -3 ) then - write(*,*) ival - call stopit( status, 'Error GETELEM_6' ) - end if - - if( ast_maplength( map, 'Fredi', status ) .ne. 4 ) then - write(*,*) ast_maplength( map, 'Fredi', status ) - call stopit( status, 'Error GETELEM_7' ) - end if - - map2 = ast_keymap( ' ', status ) - call ast_mapputelema( map2, 'A A', 1, map, STATUS ) - if( ast_maplength( map2, 'A A', status ) .ne. 1 ) then - write(*,*) ast_maplength( map, 'Fredi', status ) - call stopit( status, 'Error GETELEM_8' ) - end if - - if( .not. ast_mapgetelema( map2, 'A A', 1, map3, - : status ) ) then - call stopit( status, 'Error GETELEM_9' ) - else if( .not. ast_mapgetelemi( map3, 'Fredi', 4, ival, - : status ) ) then - call stopit( status, 'Error GETELEM_10' ) - else if( ival .ne. -3 ) then - write(*,*) ival - call stopit( status, 'Error GETELEM_11' ) - end if - - if( status .eq. sai__ok ) then - call ast_mapputelema( map2, 'A A', 1, map2, STATUS ) - if( status .eq. ast__kycir ) then - call err_annul( status ) - else - call stopit( status, 'Error GETELEM_12' ) - end if - end if - - call ast_mapput0c( map, ' B', 'Hello', ' ', status ) - - - call ast_setl( map, 'MapLocked', .TRUE., status ) - if( status .eq. sai__ok ) then - call ast_mapput0c( map, ' BZZ', 'Bye Bye', ' ', STATUS ) - if( status .eq. AST__BADKEY ) then - call err_annul( status ) - call ast_clear( map, 'maplocked', status ) - else - call stopit( status, 'Error GETELEM_12B' ) - end if - end if - - call ast_mapput0c( map, ' BZZ', 'Bye Bye', ' ', STATUS ) - km2 = ast_keymap( ' ', status ) - call ast_mapput0a( map, ' BZY', km2, ' ', STATUS ) - call ast_mapput0c( km2, ' BZZ', 'Bye Bye', ' ', STATUS ) - - call ast_setl( map, 'MapLocked', .TRUE., status ) - call ast_mapput0c( map, ' BZZ', 'You Bye', ' ', STATUS ) - call ast_mapput0c( km2, ' BZZ', 'You Bye', ' ', STATUS ) - if( status .eq. sai__ok ) then - call ast_mapput0c( km2, ' BZA', 'No Bye', ' ', STATUS ) - if( status .eq. AST__BADKEY ) then - call err_annul( status ) - call ast_clear( map, 'maplocked', status ) - call ast_mapput0c( km2, ' BZA', 'No Bye', ' ', STATUS ) - else - call stopit( status, 'Error GETELEM_12C' ) - end if - end if - - if( ast_getl( km2, 'KeyError', status ) ) then - call stopit( status, 'Error GETELEM_12D' ) - end if - - call ast_setl( map, 'KeyError', .TRUE., status ) - - if( .not. ast_getl( km2, 'KeyError', status ) ) then - call stopit( status, 'Error GETELEM_12E' ) - end if - - if( status .eq. sai__ok ) then - lval = ast_mapget0c( km2, 'FRED', cval, l, status ) - if( status .eq. AST__MPKER ) then - call err_annul( status ) - call ast_clear( map, 'keyerror', status ) - lval = ast_mapget0c( km2, 'FRED', cval, l, status ) - else - call stopit( status, 'Error GETELEM_12F' ) - end if - endif - - - - - - - - - call ast_mapputelemc( map, ' B ', 3, 'YES YES', STATUS ) - - if( ast_maplength( map, ' B', status ) .ne. 2 ) then - write(*,*) ast_maplength( map, ' B', status ) - call stopit( status, 'Error GETELEM_13' ) - - else if( .not. ast_mapgetelemc( map, ' B ', 2, cval0, - : status ) ) then - call stopit( status, 'Error GETELEM_14' ) - - else if( cval0 .ne. 'YES YES' ) then - write(*,*) cval0 - call stopit( status, 'Error GETELEM_15' ) - end if - - call ast_annul( map, status ) - - -C Test ast_mapcopy - map = ast_keymap( ' ', status ) - map1 = ast_keymap( ' ', status ) - map2 = ast_keymap( ' ', status ) - map3 = ast_keymap( ' ', status ) - - call ast_mapput0i( map1, 'a1', 1, ' ', status ) - call ast_mapput0i( map1, 'a2', 2, ' ', status ) - call ast_mapput0i( map1, 'a3', 3, ' ', status ) - - call ast_mapput0c( map, 'aa1', 'Yes', ' ', status ) - call ast_mapput0i( map, 'aa2', 2, ' ', status ) - call ast_mapput0a( map, 'aa3', map1, ' ', status ) - - call ast_mapput0i( map2, 'b1', 10, ' ', status ) - call ast_mapput0i( map2, 'b2', 20, ' ', status ) - call ast_mapput0i( map2, 'b3', 30, ' ', status ) - - call ast_mapput0c( map3, 'bb1', 'No', ' ', status ) - call ast_mapput0i( map3, 'aa2', 20, ' ', status ) - call ast_mapput0a( map3, 'bb3', map2, ' ', status ) - - call ast_mapcopy( map, map3, status ) - - if( ast_mapsize( map, status ) .ne. 5 ) then - write(*,*) ast_mapsize( map, status ) - call stopit( status, 'Error MAPCOPY_0' ) - end if - - if( .not. ast_mapget0c( map, 'aa1', cval, l, status ) ) then - call stopit( status, 'Error MAPCOPY_1' ) - else if( cval .ne. 'Yes' ) then - write(*,*) cval - call stopit( status, 'Error MAPCOPY_2' ) - end if - - if( .not. ast_mapget0i( map, 'aa2', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_3' ) - else if( ival .ne. 20 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_4' ) - end if - - if( .not. ast_mapget0a( map, 'aa3', aval, status ) ) then - call stopit( status, 'Error MAPCOPY_5' ) - else if( .not. ast_isakeymap( aval, status ) ) then - write(*,*) ast_getc( aval, 'Class' ) - call stopit( status, 'Error MAPCOPY_6' ) - - if( .not. ast_mapget0i( aval, 'a1', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_7' ) - else if( ival .ne. 1 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_8' ) - end if - - if( .not. ast_mapget0i( aval, 'a2', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_9' ) - else if( ival .ne. 20 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_10' ) - end if - - if( .not. ast_mapget0i( aval, 'a3', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_11' ) - else if( ival .ne. 3 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_12' ) - end if - end if - - if( .not. ast_mapget0c( map, 'bb1', cval, l, status ) ) then - call stopit( status, 'Error MAPCOPY_13' ) - else if( cval .ne. 'No' ) then - write(*,*) cval - call stopit( status, 'Error MAPCOPY_14' ) - end if - - if( .not. ast_mapget0a( map, 'bb3', aval, status ) ) then - call stopit( status, 'Error MAPCOPY_15' ) - else if( .not. ast_isakeymap( aval, status ) ) then - write(*,*) ast_getc( aval, 'Class' ) - call stopit( status, 'Error MAPCOPY_16' ) - - if( .not. ast_mapget0i( aval, 'b1', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_17' ) - else if( ival .ne. 10 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_18' ) - end if - - if( .not. ast_mapget0i( aval, 'b2', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_19' ) - else if( ival .ne. 20 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_20' ) - end if - - if( .not. ast_mapget0i( aval, 'b3', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_21' ) - else if( ival .ne. 30 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_22' ) - end if - end if - - - map = ast_keymap( ' ', status ) - map1 = ast_keymap( ' ', status ) - map2 = ast_keymap( ' ', status ) - map3 = ast_keymap( ' ', status ) - - call ast_mapput0i( map1, 'a1', 1, ' ', status ) - call ast_mapput0i( map1, 'a2', 2, ' ', status ) - call ast_mapput0i( map1, 'a3', 3, ' ', status ) - - call ast_mapput0c( map, 'aa1', 'Yes', ' ', status ) - call ast_mapput0i( map, 'aa2', 2, ' ', status ) - call ast_mapput0a( map, 'aa3', map1, ' ', status ) - - call ast_mapput0i( map2, 'b1', 10, ' ', status ) - call ast_mapput0i( map2, 'b2', 20, ' ', status ) - call ast_mapput0i( map2, 'b3', 30, ' ', status ) - - call ast_mapput0i( map3, 'aa1', 0, ' ', status ) - call ast_mapput0i( map3, 'aa2', 20, ' ', status ) - call ast_mapput0a( map3, 'aa3', map2, ' ', status ) - - call ast_mapcopy( map, map3, status ) - - if( ast_mapsize( map, status ) .ne. 3 ) then - write(*,*) ast_mapsize( map, status ) - call stopit( status, 'Error MAPCOPY_23' ) - end if - - if( .not. ast_mapget0i( map, 'aa1', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_24' ) - else if( ival .ne. 0 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_25' ) - end if - - if( .not. ast_mapget0i( map, 'aa2', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_26' ) - else if( ival .ne. 20 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_27' ) - end if - - if( .not. ast_mapget0a( map, 'aa3', aval, status ) ) then - call stopit( status, 'Error MAPCOPY_28' ) - else if( .not. ast_isakeymap( aval, status ) ) then - write(*,*) ast_getc( aval, 'Class' ) - call stopit( status, 'Error MAPCOPY_29' ) - - if( .not. ast_mapget0i( aval, 'a1', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_30' ) - else if( ival .ne. 1 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_31' ) - end if - - if( .not. ast_mapget0i( aval, 'a2', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_32' ) - else if( ival .ne. 20 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_33' ) - end if - - if( .not. ast_mapget0i( aval, 'a3', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_34' ) - else if( ival .ne. 3 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_35' ) - end if - - if( .not. ast_mapget0i( aval, 'b1', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_36' ) - else if( ival .ne. 10 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_37' ) - end if - - if( .not. ast_mapget0i( aval, 'b2', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_38' ) - else if( ival .ne. 20 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_39' ) - end if - - if( .not. ast_mapget0i( aval, 'b3', ival, status ) ) then - call stopit( status, 'Error MAPCOPY_40' ) - else if( ival .ne. 30 ) then - write(*,*) ival - call stopit( status, 'Error MAPCOPY_41' ) - end if - - end if - - - map = ast_keymap( ' ', status ) - map1 = ast_keymap( ' ', status ) - map2 = ast_keymap( ' ', status ) - map3 = ast_keymap( ' ', status ) - - call ast_mapput0i( map1, 'a1', 1, ' ', status ) - call ast_mapput0i( map1, 'a2', 2, ' ', status ) - call ast_mapput0i( map1, 'a3', 3, ' ', status ) - - call ast_mapput0c( map, 'aa1', 'Yes', ' ', status ) - call ast_mapput0i( map, 'aa2', 2, ' ', status ) - call ast_mapput0a( map, 'aa3', map1, ' ', status ) - - call ast_mapput0i( map2, 'b1', 10, ' ', status ) - call ast_mapput0i( map2, 'b2', 20, ' ', status ) - call ast_mapput0i( map2, 'b3', 30, ' ', status ) - - call ast_mapput0i( map3, 'aa1', 0, ' ', status ) - call ast_mapput0i( map3, 'aa2', 20, ' ', status ) - call ast_mapput0a( map3, 'aa3', map2, ' ', status ) - - call ast_setl( map, 'MapLocked', .TRUE., status ) - if( status .eq. SAI__OK ) then - call ast_mapcopy( map, map3, status ) - if( status .eq. AST__BADKEY ) then - call err_annul( status ) - else - call stopit( status, 'Error MAPCOPY_42' ) - end if - end if - - -C Test AST_MAPPUTU and undefined values - map = ast_keymap( ' ', status ) - call ast_mapputu( map, 'GG', 'A comment', status ) - if( ast_mapdefined( map, 'GG', status ) ) then - call stopit( status, 'Error UNDEF_0' ) - else if( ast_mapget0i( map, 'GG', ival, status ) ) then - call stopit( status, 'Error UNDEF_1' ) - else if( ast_mapget0s( map, 'GG', sval, status ) ) then - call stopit( status, 'Error UNDEF_1B' ) - else if( ast_mapget0c( map, 'GG', cval, l, status ) ) then - call stopit( status, 'Error UNDEF_2' ) - else if( ast_mapget0a( map, 'GG', aval, status ) ) then - call stopit( status, 'Error UNDEF_3' ) - else if( ast_mapget1i( map, 'GG', 2, nval, ivec, - : status ) ) then - call stopit( status, 'Error UNDEF_4' ) - else if( ast_mapgetelemc( map, 'gg', 1, cval, status ) ) then - call stopit( status, 'Error UNDEF_5' ) - else if( .not. ast_maphaskey( map, 'GG', status ) ) then - call stopit( status, 'Error UNDEF_6' ) - end if - - if( ast_maptype( map, 'GG', status ) .ne. AST__UNDEFTYPE ) then - write(*,*) ast_maptype( map, 'GG', status ) - call stopit( status, 'Error UNDEF_7' ) - else if( ast_mapsize( map, status ) .ne. 1 ) then - call stopit( status, 'Error UNDEF_8' ) - end if - - call ast_mapput0i( map, 'GG', 0, ' ', status ) - if( .not. ast_mapget0i( map, 'GG', ival, status ) ) then - call stopit( status, 'Error UNDEF_9' ) - else if( ival .ne. 0 ) then - call stopit( status, 'Error UNDEF_10' ) - endif - - call ast_maprename( map, 'GG', 'GGNEW', status ) - if( ast_maphaskey( map, 'GG', status ) ) then - call stopit( status, 'Error RENAME_1' ) - else if( .not. ast_mapget0i( map, 'GGNEW', ival, status ) ) then - call stopit( status, 'Error RENAME_2' ) - else if( ival .ne. 0 ) then - call stopit( status, 'Error RENAME_3' ) - endif - - call ast_maprename( map, 'GGNEW', 'GG', status ) - if( ast_maphaskey( map, 'GGNEW', status ) ) then - call stopit( status, 'Error RENAME_4' ) - else if( .not. ast_mapget0i( map, 'GG', ival, status ) ) then - call stopit( status, 'Error RENAME_5' ) - else if( ival .ne. 0 ) then - call stopit( status, 'Error RENAME_6' ) - endif - - - - - - - call ast_end( status ) - - call ast_activememory( ' ' ) - call ast_flushmemory( 1 ); - - call err_rlse( status ) - - if( status .eq. sai__ok ) then - write(*,*) 'All KeyMap tests passed' - else - write(*,*) 'KeyMap tests failed' - end if - - end - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - subroutine checkdump( obj, text, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*),key*30,txt1*50,txt2*50 - integer obj, status, next, end, ch, result, ll, overlap, size, - : i, type,obj1,obj2,l1,l2,nl - external mysource, mysink - character buf*400000 - - common /ss1/ buf - common /ss2/ next, end, ll, nl - - if( status .ne. sai__ok ) return - - ch = ast_channel( mysource, mysink, ' ', status ) - - - nl = 0 - ll = 110 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - - next = 1 - nl = 0 - result = ast_read( ch, status ) - - if( result .eq. ast__null ) then - write(*,*) text - call stopit( status, 'Cannot read object from channel' ) - end if - - size = ast_mapsize( result, status ) - if( ast_mapsize( obj, status ) .ne. size ) then - write(*,*) size, ast_mapsize( obj, status ) - call stopit( status, 'checkDump 1' ) - else - do i = 1, size - key = ast_mapkey( result, i, status ) - type = ast_maptype( result, key, status ) - if( ast_maptype( obj, key, status ) .ne. type ) then - write(*,*) type, ast_maptype( obj, key, status ) - call stopit( status, 'checkDump 4' ) - else - - if( type .eq. AST__OBJECTTYPE ) then - - if( .not. ast_mapGet0A( result, key, obj1, - : status ) ) call stopit( status, 'checkDump 5' ) - if( .not. ast_mapGet0A( obj, key, obj2, - : status ) ) call stopit( status, 'checkDump 6' ) - if( ast_GetC( obj1, 'class', status ) .ne. - : ast_GetC( obj2, 'class', status ) ) then - call stopit( status, 'checkDump 7' ) - end if - - else - - if( .not. ast_mapGet0C( result, key, txt1, l1, - : status ) ) call stopit( status, 'checkDump 8' ) - if( .not. ast_mapGet0C( obj, key, txt2, l2, - : status ) ) call stopit( status, 'checkDump 9' ) - if( txt1( : l1 ) .ne. txt2( : l2 ) .or. - : l1 .ne. l2 ) then - call stopit( status, 'checkDump 10' ) - end if - - end if - end if - end do - end if - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll, nl - character buf*400000 - - common /ss1/ buf - common /ss2/ next, end, ll,nl - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - call ast_putline( buf( next : ), ll, status ) - nl = nl + 1 - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll, nl - character buf*400000 - character line*1000 - - common /ss1/ buf - common /ss2/ next, end, ll, nl - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - - if( next + ll - 1 .ge. 400000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf( next : next + l) - write(*,*) 'Line length ',l - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - nl = nl + 1 - endif - - next = next + ll - - end - - - - subroutine testsorting( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer status, km, i - character keys(5)*15 - character skeys(5)*15 - character key*( AST__SZCHR ) - - - data keys / 'ABC', 'zzzzzzzzzzz', 'this_is_a_key', 'HE-HE', 'A' / - data skeys / 'A', 'ABC', 'HE-HE', 'this_is_a_key', 'zzzzzzzzzzz' / - - - if( status .ne. sai__ok ) return - -C Value Age sorting... - -C First test adding entries into an already sorted KeyMap - - km = ast_keymap( 'Sortby=AgeDown', status ) - - do i = 1, 5 - call ast_mapput0i( km, keys(i), i, ' ', status ) - end do - - do i = 1, 5 - key = ast_mapkey( km, i, status ) - if( key .ne. keys(i) .and. status .eq. SAI__OK ) then - write(*,*) 'Key ',i,' is ',key,' (should be ',keys(i),')' - call stopit( status, 'Error Sort 1' ) - return - end if - end do - -C Now test sorting existing entries in a KeyMap. - call ast_set( km, 'Sortby=AgeUp', status ) - - do i = 1, 5 - key = ast_mapkey( km, i, status ) - if( key .ne. keys(6-i) .and. status .eq. SAI__OK ) then - write(*,*) 'Key ',i,' is ',key,' (should be ',keys(6-i),')' - call stopit( status, 'Error Sort 2' ) - return - end if - end do - - -C Changing the value of an existing entry should change its position in -C the list. - call ast_mapput0i( km, keys(1), 10, ' ', status ) - call ast_set( km, 'Sortby=AgeDown', status ) - - do i = 1, 5 - key = ast_mapkey( km, i, status ) - if( i .eq. 5 ) then - if( key .ne. keys(1) .and. status .eq. SAI__OK ) then - write(*,*) 'Key ',1,' is ',key,' (should be ',keys(1),')' - call stopit( status, 'Error Sort 2b' ) - return - end if - else if( key .ne. keys(i+1) .and. status .eq. SAI__OK ) then - write(*,*) 'Key ',i+1,' is ',key,' (should be ',keys(i+1), - : ')' - call stopit( status, 'Error Sort 2c' ) - return - end if - end do - - call ast_annul( km, status ) - - -C Key Age sorting... - -C First test adding entries into an already sorted KeyMap - - km = ast_keymap( 'Sortby=KeyAgeDown', status ) - - do i = 1, 5 - call ast_mapput0i( km, keys(i), i, ' ', status ) - end do - - do i = 1, 5 - key = ast_mapkey( km, i, status ) - if( key .ne. keys(i) .and. status .eq. SAI__OK ) then - write(*,*) 'Key ',i,' is ',key,' (should be ',keys(i),')' - call stopit( status, 'Error Sort 0' ) - return - end if - end do - -C Now test sorting existing entries in a KeyMap. - call ast_set( km, 'Sortby=KeyAgeUp', status ) - - do i = 1, 5 - key = ast_mapkey( km, i, status ) - if( key .ne. keys(6-i) .and. status .eq. SAI__OK ) then - write(*,*) 'Key ',i,' is ',key,' (should be ',keys(6-i),')' - call stopit( status, 'Error Sort -1' ) - return - end if - end do - - -C Changing the value of an existing entry should not change its position -C in the list. - call ast_mapput0i( km, keys(1), 10, ' ', status ) - call ast_set( km, 'Sortby=KeyAgeDown', status ) - - do i = 1, 5 - key = ast_mapkey( km, i, status ) - if( key .ne. keys(i) .and. status .eq. SAI__OK ) then - write(*,*) 'Key ',i,' is ',key,' (should be ',keys(i),')' - call stopit( status, 'Error Sort -2' ) - return - end if - end do - - call ast_annul( km, status ) - - - -C Key sorting... - -C First test adding entries into an already sorted KeyMap - - km = ast_keymap( 'Sortby=KeyUp', status ) - - do i = 1, 5 - call ast_mapput0i( km, keys(i), i, ' ', status ) - end do - - do i = 1, 5 - key = ast_mapkey( km, i, status ) - if( key .ne. skeys(i) .and. status .eq. SAI__OK ) then - write(*,*) 'Key ',i,' is ',key,' (should be ',skeys(i),')' - call stopit( status, 'Error Sort 3' ) - return - end if - end do - -C Now test sorting existing entries in a KeyMap. - call ast_set( km, 'Sortby=KeyDown', status ) - - do i = 1, 5 - key = ast_mapkey( km, i, status ) - if( key .ne. skeys(6-i) .and. status .eq. SAI__OK ) then - write(*,*) 'Key ',i,' is ',key,' (should be ',skeys(6-i),')' - call stopit( status, 'Error Sort 4' ) - return - end if - end do - - call ast_annul( km, status ) - - - - - end - - - - - subroutine testcasesens( status ) - implicit none - include 'AST_PAR' - include 'AST_ERR' - include 'SAE_PAR' - - integer status, map, l - character sval*( AST__SZCHR ) - - if( status .ne. sai__ok ) return - - map = ast_keymap( 'KeyCase=0', status ) - call ast_mapput0i( map, 'Freds', 1999, 'com 1', status ) - - if( .not. ast_maphaskey( map, 'fReDs', status ) ) then - call stopit( status, 'Error case 1' ) - endif - - if( ast_mapkey( map, 1, status ) .ne. 'FREDS' ) then - call stopit( status, 'Error case 2' ) - endif - - if( .not. ast_mapget0c( map, 'freds', sval, l, status ) ) then - call stopit( status, 'Error case 3' ) - else if( sval .ne. '1999' ) then - call stopit( status, 'Error case 4' ) - else if( l .ne. 4 ) then - call stopit( status, 'Error case 4b' ) - end if - - call ast_setl( map, 'KeyCase', 0, status ); - - if( status .eq. sai__ok ) then - call ast_clear( map, 'KeyCase', status ) - if( status .eq. AST__NOWRT ) then - call err_annul( status ) - else if( status .eq. sai__ok ) then - call stopit( status, 'Error case 5' ) - end if - end if - - if( ast_mapsize( map, status ) .ne. 1 ) then - call stopit( status, 'Error case 6' ) - end if - - call ast_mapremove( map, 'freDs', status ) - - if( ast_mapsize( map, status ) .ne. 0 ) then - call stopit( status, 'Error case 7' ) - end if - - call ast_clear( map, 'KeyCase', status ) - call ast_mapput0i( map, 'Freds', 1999, 'com 1', status ) - if( ast_maphaskey( map, ' fReDs', status ) ) then - call stopit( status, 'Error case 8' ) - endif - - - call ast_annul( map, status ) - - end - - - - diff --git a/ast/ast_tester/testlutmap.f b/ast/ast_tester/testlutmap.f deleted file mode 100644 index e183375..0000000 --- a/ast/ast_tester/testlutmap.f +++ /dev/null @@ -1,177 +0,0 @@ - program testlutmap - implicit none - - include 'AST_PAR' - include 'SAE_PAR' - - integer lm, status, i - double precision lut1( 10 ), x( 7 ), y(7) - - status = sai__ok - call err_mark( status ) - call ast_begin( status ) - - - data lut1/ -1D0, 0D0, 1D0, 2D0, 3D0, 4D0, 5D0, 6D0, 7D0, 8D0 / - - - - - lm = ast_lutmap( 10, lut1, -1.0D0, 1.0D0, ' ', status ) - x( 1 ) = -2.0D0 - x( 2 ) = -1.0D0 - x( 3 ) = -0.5D0 - x( 4 ) = 3.0D0 - x( 5 ) = 7.5D0 - x( 6 ) = 8.0D0 - x( 7 ) = 8.5D0 - - call ast_tran1( lm, 7, x, .TRUE., y, status ) - - do i = 1, 7 - if( x( i ) .ne. y( i ) ) then - call stopit( status, "Error 1" ); - end if - end do - - call ast_tran1( lm, 7, y, .FALSE., x, status ) - - do i = 1, 7 - if( x( i ) .ne. y( i ) ) then - call stopit( status, "Error 2" ); - end if - end do - - - - - lut1( 1 ) = lut1( 2 ) - lm = ast_lutmap( 10, lut1, -1.0D0, 1.0D0, ' ', status ) - x( 1 ) = -2.0D0 - x( 2 ) = -1.0D0 - x( 3 ) = -0.5D0 - x( 4 ) = 0.5D0 - x( 5 ) = 3.0D0 - x( 6 ) = 8.0D0 - x( 7 ) = 8.5D0 - - call ast_tran1( lm, 7, x, .TRUE., y, status ) - - do i = 1, 3 - if( y( i ) .ne. 0.0 ) then - call stopit( status, "Error 3" ); - end if - end do - - do i = 4, 7 - if( x( i ) .ne. y( i ) ) then - call stopit( status, "Error 4" ); - end if - end do - - call ast_tran1( lm, 7, y, .FALSE., x, status ) - - do i = 1, 3 - if( x( i ) .ne. AST__BAD ) then - call stopit( status, "Error 5" ); - end if - end do - - do i = 4, 7 - if( x( i ) .ne. y( i ) ) then - call stopit( status, "Error 6" ); - end if - end do - - - lut1( 5 ) = AST__BAD - lm = ast_lutmap( 10, lut1, -1.0D0, 1.0D0, ' ', status ) - x( 1 ) = -2.0D0 - x( 2 ) = -1.0D0 - x( 3 ) = -0.5D0 - x( 4 ) = 0.5D0 - x( 5 ) = 3.0D0 - x( 6 ) = 8.0D0 - x( 7 ) = 8.5D0 - - call ast_tran1( lm, 7, x, .TRUE., y, status ) - - do i = 1, 3 - if( y( i ) .ne. 0.0 ) then - call stopit( status, "Error 7" ); - end if - end do - - if( y( 5 ) .ne. AST__BAD ) then - call stopit( status, "Error 8" ); - end if - y(5) = x( 5 ) - - do i = 4, 7 - if( x( i ) .ne. y( i ) ) then - call stopit( status, "Error 9" ); - end if - end do - - call ast_tran1( lm, 7, y, .FALSE., x, status ) - - do i = 1, 3 - if( x( i ) .ne. AST__BAD ) then - call stopit( status, "Error 10" ); - end if - end do - - if( x( 5 ) .ne. AST__BAD ) then - call stopit( status, "Error 11" ); - end if - x(5) = y( 5 ) - - do i = 4, 7 - if( x( i ) .ne. y( i ) ) then - call stopit( status, "Error 12" ); - end if - end do - - - - - - - - - - - - - - - - - call ast_end( status ) - call err_rlse( status ) - -c call ast_activememory( 'testlutmap' ) - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All LutMap tests passed' - else - write(*,*) 'LutMap tests failed' - end if - - end - - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - end - - - diff --git a/ast/ast_tester/testmapping.f b/ast/ast_tester/testmapping.f deleted file mode 100644 index a02dd5b..0000000 --- a/ast/ast_tester/testmapping.f +++ /dev/null @@ -1,85 +0,0 @@ - program testmapping - implicit none - - include 'AST_PAR' - include 'SAE_PAR' - - integer status, pm - double precision coeff(20), fit(6), lbnd(2), ubnd(2) - - data coeff / 1.0, 1.0, 0.0, 0.0, - : 2.0, 1.0, 1.0, 0.0, - : 1.0, 2.0, 0.0, 0.0, - : 3.0, 2.0, 0.0, 1.0, - : 3.0, 1.0, 0.0, 2.0 / - - - - status = sai__ok - call err_mark( status ) - call ast_begin( status ) - - pm = ast_polymap( 2, 2, 4, coeff, 0, coeff, ' ', status ) - - lbnd( 1 ) = -1.0D0 - lbnd( 2 ) = -1.0D0 - ubnd( 1 ) = 1.0D0 - ubnd( 2 ) = 1.0D0 - if( ast_linearapprox(pm, lbnd, ubnd, 0.001D0, fit, status) ) then - if( fit(1) .ne. 1.0D0 .or. fit(2) .ne. 1.0D0 .or. - : fit(3) .ne. 2.0D0 .or. fit(4) .ne. 0.0D0 .or. - : fit(5) .ne. 0.0D0 .or. fit(6) .ne. 3.0D0 ) then - call stopit( status, 'Error 0' ) - end if - else - call stopit( status, 'Error 1' ) - end if - - coeff( 13 ) = AST__BAD - pm = ast_polymap( 2, 2, 4, coeff, 0, coeff, ' ', status ) - - if( ast_linearapprox(pm, lbnd, ubnd, 0.001D0, fit, status) ) then - if( fit(1) .ne. 1.0D0 .or. fit(2) .ne. AST__BAD .or. - : fit(3) .ne. 2.0D0 .or. fit(4) .ne. 0.0D0 .or. - : fit(5) .ne. AST__BAD .or. fit(6) .ne. AST__BAD ) then - call stopit( status, 'Error 2' ) - end if - else - call stopit( status, 'Error 3' ) - end if - - pm = ast_polymap( 2, 2, 5, coeff, 0, coeff, ' ', status ) - - if( ast_linearapprox(pm, lbnd, ubnd, 0.001D0, fit, status) ) then - write(*,*) fit - call stopit( status, 'Error 4' ) - end if - - - - - call ast_end( status ) - call err_rlse( status ) - - if( status .eq. sai__ok ) then - write(*,*) 'All Mapping tests passed' - else - write(*,*) 'Mapping tests failed' - end if - - end - - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - end - - - diff --git a/ast/ast_tester/testnormmap.f b/ast/ast_tester/testnormmap.f deleted file mode 100644 index 2c57ee6..0000000 --- a/ast/ast_tester/testnormmap.f +++ /dev/null @@ -1,94 +0,0 @@ - program testnormmap - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'PRM_PAR' - - integer status, m, m2, m3, f, perm(3) - double precision at(3), bt(3) - - call ast_begin( status ) - - - status = sai__ok - - f = ast_cmpframe( ast_specframe( ' ', status ), - : ast_skyframe( ' ', status ), ' ', status ) - - perm( 1 ) = 3 - perm( 2 ) = 1 - perm( 3 ) = 2 - call ast_permaxes( f, perm, status ) - m = ast_normmap( f, ' ', status ) - - if( ast_geti( m, 'nin', status ) .ne. 3 ) call stopit( 1, status ) - if( ast_geti( m, 'nout', status ) .ne. 3 ) call stopit( 2, status) - - if( .not. ast_getl( m, 'TranForward', status ) ) call stopit( 3, - : status ) - if( .not. ast_getl( m, 'TranInverse', status ) ) call stopit( 4, - : status ) - - - m2 = ast_copy( m, status ) - call ast_invert( m2, status ) - m3 = ast_simplify( ast_cmpmap( m, m2, .true., ' ', status ), - : status ) - if( .not. ast_isaunitmap( m3, status ) ) call stopit( 5, status ) - - - at( 1 ) = 2.0D0 - at( 2 ) = 3.0D4 - at( 3 ) = 1.0D0 - - call ast_trann( m, 1, 3, 1, at, 1, 3, 1, bt, status ) - - if( abs( bt(1)-1.14159265D0) .gt. 1.0D-6 ) then - write(*,*) bt(1)-1.14159265D0 - call stopit(6,status) - end if - if( bt(2) .ne. 3.0D4 ) call stopit(7,status) - if( abs( bt(3)-4.14159265D0) .gt. 1.0D-6 ) call stopit(8,status) - - - - -* Test adjacent identical NormMaps are simplified to a single NormMap. - m2 = ast_cmpmap( ast_cmpmap( m, ast_copy( m, status ), .true., - : ' ', status ), - : ast_cmpmap( m, ast_copy( m, status ), .true., - : ' ', status ), .true., ' ', status ) - m3 = ast_simplify( m2, status ) - if( .not. ast_isanormmap( m3, status ) ) call stopit( 9, status ) - -* Test NormMap that encapsulate a basic Frame are simplified to a UnitMap. - m = ast_normmap( ast_frame(2, ' ', status ), ' ', status ) - m2 = ast_simplify( m, status ) - if( .not. ast_isaunitmap( m2, status ) ) call stopit( 10, status ) - - - - - - call ast_end( status ) - - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All NormMap tests passed' - else - write(*,*) 'NormMap tests failed' - end if - - end - - - subroutine stopit( i, status ) - implicit none - include 'SAE_PAR' - integer i, status - if( status .eq. sai__ok ) then - write( *,* ) 'Error ',i - status = sai__error - end if - end diff --git a/ast/ast_tester/testobject.c b/ast/ast_tester/testobject.c deleted file mode 100644 index c1c1972..0000000 --- a/ast/ast_tester/testobject.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "ast.h" -#include -#include - -int main(){ - const char *routine; - const char *file; - int i; - int line; - char *pickle1; - char *pickle2; - AstSkyFrame *sf = astSkyFrame( " " ); - AstFrame *bf = astFrame( 2, "Domain=SKY" ); - AstFrameSet *fs = astConvert( bf, sf, " " ); - AstKeyMap *km; - void *p; - - if( fs ) { - pickle1 = astToString( fs ); - AstFrameSet *fs2 = astFromString( pickle1 ); - pickle2 = astToString( fs2 ); - if( pickle1 && pickle2 ) { - if( strcmp( pickle1, pickle2 ) && astOK ) { - astError( AST__INTER, "Error 1\n" ); - } - } else if( astOK ) { - astError( AST__INTER, "Error 2\n" ); - } - - - pickle1 = astFree( pickle1 ); - pickle2 = astFree( pickle2 ); - - if( fs2 && !astEqual( fs, fs2 ) && astOK ) { - astError( AST__INTER, "Error 3\n" ); - } - - astCreatedAt( bf, &routine, &file, &line ); - if( ( !routine || strcmp( routine, "main" ) ) && astOK ) { - astError( AST__INTER, "Error 31\n" ); - } - if( ( !file || strcmp( file, "testobject.c" ) ) && astOK ) { - astError( AST__INTER, "Error 32\n" ); - } - if( line != 13 && astOK ) { - astError( AST__INTER, "Error 33 (line is %d)\n", line ); - } - - - km = astActiveObjects( NULL, 0, 0 ); - if( !km && astOK ) { - astError( AST__INTER, "Error 34\n" ); - } else { - int nkey = astMapSize( km ); - if( nkey != 3 && astOK ) { - astError( AST__INTER, "Error 35 (nkey is %d)\n", nkey ); - } - - astSetC( km, "SortBy", "KeyUp" ); - for( i=0; i < 3; i++ ){ - const char *key = astMapKey( km, i ); - if( i == 0 ) { - if( strcmp( key, "Frame" ) && astOK ) { - astError( AST__INTER, "Error 36 (key 0 is '%s')\n", key ); - } else if( astMapLength(km,key) != 1 && astOK ) { - astError( AST__INTER, "Error 361 (%d)\n", astMapLength(km,key) ); - } else if( ( !astMapGetElemP( km, key, 0, &p ) || ( p != bf ) ) && astOK ) { - astError( AST__INTER, "Error 362\n" ); - } else { - astCreatedAt( p, &routine, &file, &line ); - if( ( !routine || strcmp( routine, "main" ) ) && astOK ) { - astError( AST__INTER, "Error 363\n" ); - } - if( ( !file || strcmp( file, "testobject.c" ) ) && astOK ) { - astError( AST__INTER, "Error 364\n" ); - } - if( line != 13 && astOK ) { - astError( AST__INTER, "Error 365 (line is %d)\n", line ); - } - } - } else if( i == 1 ) { - if( strcmp( key, "FrameSet" ) && astOK ) { - astError( AST__INTER, "Error 37 (key 1 is '%s')\n", key ); - } else if( astMapLength(km,key) != 2 && astOK ) { - astError( AST__INTER, "Error 371 (%d)\n", astMapLength(km,key) ); - } else if( ( !astMapGetElemP( km, key, 1, &p ) || ( p != fs2 ) ) && astOK ) { - astError( AST__INTER, "Error 372\n" ); - } else { - astCreatedAt( p, &routine, &file, &line ); - if( ( !routine || strcmp( routine, "main" ) ) && astOK ) { - astError( AST__INTER, "Error 373\n" ); - } - if( ( !file || strcmp( file, "testobject.c" ) ) && astOK ) { - astError( AST__INTER, "Error 374\n" ); - } - if( line != 20 && astOK ) { - astError( AST__INTER, "Error 375 (line is %d)\n", line ); - } - } - } else { - if( strcmp( key, "SkyFrame" ) && astOK ) { - astError( AST__INTER, "Error 38 (key 2 is '%s')\n", key ); - } else if( astMapLength(km,key) != 1 && astOK ) { - astError( AST__INTER, "Error 381 (%d)\n", astMapLength(km,key) ); - } - } - } - } - km = astAnnul( km ); - - } else if( astOK ){ - astError( AST__INTER, "Error 4\n" ); - } - - if( astOK ) { - printf(" All Object tests passed\n"); - } else { - printf("Object tests failed\n"); - } -} diff --git a/ast/ast_tester/testplot3d.f b/ast/ast_tester/testplot3d.f deleted file mode 100644 index 66a6858..0000000 --- a/ast/ast_tester/testplot3d.f +++ /dev/null @@ -1,1357 +0,0 @@ - program testplot3d - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer fset, plot3d, status, pgbeg - real gbox(6), lbnd(3), ubnd(3) - double precision bbox(6) - integer readtest - logical ok, pg3d_autocamera - character device*30 - - status = sai__ok - -c call ast_watchmemory( 130836 ) - call ast_begin( status ) - - lbnd( 1 ) = -1.0 - lbnd( 2 ) = -1.0 - lbnd( 3 ) = -1.0 - ubnd( 1 ) = 1.0 - ubnd( 2 ) = 1.0 - ubnd( 3 ) = 1.0 - - if( iargc() .gt. 0 ) then - call getarg( 1, device ) - else - device = '/XSERVE' - end if - ok = ( pgbeg( 0, device, 1, 1 ) .eq. 1 ) - - if( .not. ok ) write(*,*) 'PGPLOT OPEN FIALED' - - call pgask( .false. ) - - call pgpage - call pgwnad( 0.0, 1.0, 0.0, 1.0 ) - - ok = pg3d_autocamera( lbnd, ubnd ) -c - gbox(1) = lbnd(1) - gbox(2) = lbnd(2) - gbox(3) = lbnd(3) - gbox(4) = ubnd(1) - gbox(5) = ubnd(2) - gbox(6) = ubnd(3) - - bbox(1) = -1.0 - bbox(2) = -1.0 - bbox(3) = -1.0 - bbox(4) = 1.0 - bbox(5) = 1.0 - bbox(6) = 1.0 - - plot3d = ast_plot3d( AST__NULL, gbox, bbox, 'minticklen=0', - : status ) - call checkdump( plot3d, 'CheckDump test 1', status ) - call ast_annul( plot3d, status ) - bbox(1) = 0.5 - bbox(2) = 0.5 - bbox(3) = 0.5 - bbox(4) = 155.5 - bbox(5) = 107.5 - bbox(6) = 1640.5 - plot3d = ast_plot3d( readtest( "plot3d-test1.ast", status ), gbox, - : bbox, ' ' , status ) -c call checkdump( plot3d, 'CheckDump test 2', status ) -c call ast_set( plot3d, "System(1)=galactic,system(3)=freq", -c : status ) -c call ast_grid( plot3d, status ) - call explore( plot3d, status ) - call pgend - call ast_end( status ) - call ast_activememory( 'testplot3d' ) - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All Plot3D tests passed' - else - write(*,*) 'Plot3D tests failed' - end if - - end - - subroutine checkdump( obj, text, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*) - integer obj, status, next, end, ch, result, ll, overlap - external mysource, mysink, mysink2 - character buf*400000,buf2*400000 - common /ss1/ buf - common /ss2/ next, end, ll - common /ss3/ buf2 - if( status .ne. sai__ok ) return - call ast_begin( status ) - ch = ast_channel( mysource, mysink, ' ', status ) - ll = 200 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - next = 1 - result = ast_read( ch, status ) - if( result .eq. ast__null ) then - write(*,*) text - call stopit( status, 'Cannot read object from channel' ) - end if - - ll = 200 - next = 1 - ch = ast_channel( AST_NULL, mysink2, ' ', status ) - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write copied object to '// - : 'channel' ) - end if - if( buf .ne. buf2 ) then - call ast_Show( obj, status ) - call ast_Show( result, status ) - write(*,*) text - call stopit( status, 'Object has changed' ) - end if - call ast_end( status ) - end - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll - character buf*400000 - common /ss1/ buf - common /ss2/ next, end, ll - if( status .ne. sai__ok ) return - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - call ast_putline( buf( next : ), ll, status ) - endif - next = next + ll - end - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll - character buf*400000 - character line*1000 - common /ss1/ buf - common /ss2/ next, end, ll - if( status .ne. sai__ok ) return - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - if( next + ll - 1 .ge. 400000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) line( f : l ) - write(*,*) 'Line length ',l - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - endif - next = next + ll - end - subroutine mysink2( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll - character buf2*400000 - character line*1000 - common /ss3/ buf2 - common /ss2/ next, end, ll - if( status .ne. sai__ok ) return - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf2( next : ) = line( f : l ) - l = l - f + 1 - if( next + ll - 1 .ge. 400000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink2!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf2( next : next + l) - write(*,*) 'Line length ',l - call stopit( status, 'Line overflow in mysink2!!' ) - else - end = next + l - buf2( end : next + ll - 1 ) = ' ' - endif - next = next + ll - end - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - end - - integer function readtest( name, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character name*(*) - integer status, ch - external mysource3 - readtest = AST__NULL - if( status .ne. sai__ok ) return - open( unit=1, file=name, status='old' ) - ch = ast_channel( mysource3, ast_null, ' ', status ) - readtest = ast_read( ch, status ) - call ast_annul( ch, status ) - close(1) - end - - subroutine mysource3( status ) - integer status - character buffer*200 - read( 1, '(A)', end = 99 ) buffer - call ast_putline( buffer, len( buffer ), status ) - return - 99 call ast_putline( buffer, -1, status ) - - end - - - subroutine explore( plot3d, status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - - real common_par - integer common_map - logical use_common - double precision common_x, common_y - common /ss4/ common_par,common_x,common_y,common_map,use_common - - real pi - parameter( pi = 3.1415927 ) - integer diag, plot3d, status, iopt, i, iclose - logical more, draw, ok, pg3d_findnearest, lval, pg3d_seteye, - : pg3d_setup - character settings*40, attr*20, corn(8)*3, text*40,just*4 - real xc(8), yc(8), zc(8) - double precision pos(3),x,y - real up(3), eye(3) - integer type, map - integer readtest - data xc /-1, 1, -1, 1, -1, 1, -1, 1 / - data yc /-1, -1, 1, 1, -1, -1, 1, 1 / - data zc /-1, -1, -1, -1, 1, 1, 1, 1 / - data corn/ 'lll', 'ull', 'lul', 'uul', - : 'llu', 'ulu', 'luu', 'uuu' / - if( status .ne. sai__ok ) return - eye( 1 ) = -3 - eye( 2 ) = 4 - eye( 3 ) = 3 - ok = pg3d_seteye( eye ) - up( 1 ) = 0.0 - up( 2 ) = -0.03 - up( 3 ) = 1.0 - ok = pg3d_setup( up ) - diag = 1 - common_x = AST__BAD - common_y = AST__BAD - common_map = AST__NULL - use_common = .false. - - call drawit( diag, plot3d, status ) - more = .true. - do while( more ) - - write(*,*) ' 0 - exit' - write(*,*) ' 1 - move forward' - write(*,*) ' 2 - move backwards' - write(*,*) ' 3 - rotate right' - write(*,*) ' 4 - rotate left' - write(*,*) ' 5 - rotate up' - write(*,*) ' 6 - rotate down' - write(*,*) ' 7 - rotate right continuous' - write(*,*) ' 8 - set attribute values' - write(*,*) ' 9 - get an attribute value' - write(*,*) ' 10 - clear an attribute value' - write(*,*) ' 11 - test an attribute value' - write(*,*) ' 12 - show the plot3d (big!)' - write(*,*) ' 13 - Draw a border' - write(*,*) ' 14 - Draw a marker' - write(*,*) ' 15 - Draw a text string' - write(*,*) ' 16 - Draw az-el diagram' - write(*,*) ' 17 - Draw grid-box diagram' - write(*,*) ' 18 - Vary parameter continuously' - write(*,*) ' 19 - Next figure' - write(*,*) ' 20 - Set Mapping' - write(*,*) ' 21 - Mark mapped position' - write(*,'(A,$)' ) 'Option: ' - read(*,*) iopt - - draw = .true. - if( iopt .eq. 0 ) then - draw = .false. - more = .false. - else if( iopt .eq. 1 ) then - call pg3d_forward( 0.1 ) - else if( iopt .eq. 2 ) then - call pg3d_forward( -0.1 ) - else if( iopt .eq. 3 ) then - call pg3d_rotateeye( 4, 7.0 ) - else if( iopt .eq. 4 ) then - call pg3d_rotateeye( 3, 7.0 ) - else if( iopt .eq. 5 ) then - call pg3d_rotateeye( 1, 7.0 ) - else if( iopt .eq. 6 ) then - call pg3d_rotateeye( 2, 7.0 ) - else if( iopt .eq. 7 ) then - do i = 0, 360, 7 - call pg3d_rotateeye( 4, 7.0 ) - call pgpage - call drawit( diag, plot3d, status ) - call pause - end do - draw = .false. - else if( iopt .eq. 8 ) then - write( *, '(A,$)' ) 'Attribute settings: ' - read( *, '(A)' ) settings - call ast_set( plot3d, settings, status ) - else if( iopt .eq. 9 ) then - write( *, '(A,$)' ) 'Attribute name to get: ' - read( *, '(A)' ) attr - write(*,*) ast_getc( plot3d, attr, status ) - draw = .false. - else if( iopt .eq. 10 ) then - write( *, '(A,$)' ) 'Attribute name to clear: ' - read( *, '(A)' ) attr - call ast_clear( plot3d, attr, status ) - else if( iopt .eq. 11 ) then - write( *, '(A,$)' ) 'Attribute name to test: ' - read( *, '(A)' ) attr - write(*,*) ast_test( plot3d, attr, status ) - draw = .false. - else if( iopt .eq. 12 ) then - call ast_show( plot3d, status ) - draw = .false. - else if( iopt .eq. 13 ) then - lval = ast_border( plot3d, status ) - draw = .false. - else if( iopt .eq. 14 ) then - write(*,'(A,$)') 'Marker X coord: ' - read(*,*) pos(1) - write(*,'(A,$)') 'Marker Y coord: ' - read(*,*) pos(2) - write(*,'(A,$)') 'Marker Z coord: ' - read(*,*) pos(3) - write(*,'(A,$)') 'Marker type: ' - read(*,*) type - call ast_mark( plot3d, 1, 3, 1, pos, type, status ) - draw = .false. - else if( iopt .eq. 15 ) then - write(*,'(A,$)') 'Text X coord: ' - read(*,*) pos(1) - write(*,'(A,$)') 'Text Y coord: ' - read(*,*) pos(2) - write(*,'(A,$)') 'Text Z coord: ' - read(*,*) pos(3) - write(*,'(A,$)') 'Text: ' - read(*,*) text - write(*,'(A,$)') 'Justification: ' - read(*,*) just - write(*,'(A,$)') 'Up X: ' - read(*,*) up(1) - write(*,'(A,$)') 'Up Y: ' - read(*,*) up(2) - write(*,'(A,$)') 'Up Z: ' - read(*,*) up(3) - call ast_text( plot3d, text, pos, up, just, status ) - draw = .false. - else if( iopt .eq. 16 ) then - diag = 2 - else if( iopt .eq. 17 ) then - diag = 1 - else if( iopt .eq. 18 ) then - use_common = .true. - do i = 0, 90, 1 - common_par = pi*i/180.0; - call pgpage - call drawit( diag, plot3d, status ) - call pause - end do - draw = .false. - use_common = .false. - else if( iopt .eq. 19 ) then - diag = diag + 1 - write(*,*) 'Drawing diag ',diag - - else if( iopt .eq. 20 ) then - write(*,'(A,$)') 'Supply a 2-in, 2-out Mapping (outputs '// - : 'are (long,lat)):' - read(*,*) text - common_map = readtest( text, status ) - draw = .false. - - else if( iopt .eq. 21 ) then - write(*,'(A,$)') 'Value for input 1: ' - read(*,*) common_x - write(*,'(A,$)') 'Value for input 2: ' - read(*,*) common_y - - else - draw = .false. - write(*,*) 'Bad option ',iopt - end if - - if( draw ) then - call pgpage -c ok = pg3d_findnearest( 8, xc, yc, zc, iclose ) -c call ast_setc( plot3d, 'RootCorner', corn( iclose + 1 ), -c : status ) - call drawit( diag, plot3d, status ) - end if - - if( status .ne. sai__ok ) call err_flush( status ) - end do - - end - - subroutine pause - implicit none - integer i - double precision a - a = 1.0D0 - do i = 1, 2000000 - a = tan( a ) - end do - end - - subroutine drawit( diag, plot3d, status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - integer NP - parameter ( NP = 50 ) - integer w1, w2 - real rd, pi - parameter( w1 = 6, w2 = 3, rd = 1.5, pi = 3.1415927 ) - - real common_par - integer common_map - logical use_common - double precision common_x, common_y - common /ss4/ common_par,common_x,common_y,common_map,use_common - - double precision dlat, dlon, up, north - integer diag, plot3d, status, i, j, azelmap - real x(NP), y(NP), z(NP), axlen, a1, a2, r(3), u(3), n(3), - : ang, k, cen(3), norm(3), start(3), lon, lat, origin(3), - : theta,phi - if( status .ne. sai__ok ) return - - if( diag .eq. 1 ) then - call ast_grid( plot3d, status ) - - else - axlen = 1.8 - a1 = 0.1 - a2 = a1*0.6 - lon = pi*210.0/180.0 - if( use_common ) then - lat = common_par - else - lat = pi*25.0/180.0 - endif - - do while( lat .gt. pi ) - lat = lat - 2*pi - end do - - do while( lat .lt. -pi ) - lat = lat + 2*pi - end do - - if( lat .gt. pi/2 ) then - lat = pi - lat - lon = lon + pi - - else if( lat .lt. -pi/2 ) then - lat = -pi - lat - lon = lon + pi - end if - - do while( lon .gt. 2*pi ) - lon = lon - 2*pi - end do - - do while( lon .lt. 0 ) - lon = lon + 2*pi - end do - - -c+ Fig1 (part a) - if( diag .eq. 2 ) then - call pgslw( w2 ) - cen(1) = 0.0 - cen(2) = 0.0 - cen(3) = 0.0 - call s2c( lon - pi/2, 0.0, 1.0, norm ) - call s2c( lon, 0.0, rd*0.6, start ) - call pgsci( 10 ) - call pgscr( 10, 0.0, 0.0, 1.0 ) - call arc( cen, norm, start, -lat, -rd*0.1 ) - - u(1)=0 - u(2)=0 - u(3)=1 - call s2c( lon, lat/2.2, rd*0.7, r ) - call g3dtext( 'el', r, 'CL', u, norm ) - - norm(1)=0 - norm(2)=0 - norm(3)=-1 - start(1)=rd*0.6 - start(2)=0 - start(3)=0 - call arc( cen, norm, start, lon, rd*0.1 ) - - call s2c( 110.0/180.0*PI, 0.0, rd*0.7, r ) - call g3dtext( 'az', r, 'TC', r, norm ) - - call pgsci( 1 ) - endif - - origin(1) = 0.0 - origin(2) = 0.0 - origin(3) = 0.0 - call axes( origin, axlen, '(north) u', '(east) v', - : '(zenith) w', w1, w2, 'X', 0.0, 0.0, 0.0 ) - -* Quadrant from (0,0,1) to (-1,0,0) - cen(1) = 0.0 - cen(2) = 0.0 - cen(3) = 0.0 - call s2c( (int(2*lon/pi)-1)*pi/2, 0.0, 1.0, norm ) - start(1) = 0.0 - start(2) = 0.0 - start(3) = rd - call pgslw( w2 ) - call arc( cen, norm, start, pi/2, 0.0 ) - -* Quadrant from (0,0,1) to (0,-1,0) - call s2c( int(2*lon/pi)*pi/2, 0.0, 1.0, norm ) - call arc( cen, norm, start, pi/2, 0.0 ) - -* Quadrant from (-1,0,0) to (0,-1,0) - norm(1) = 0.0 - norm(2) = 0.0 - norm(3) = 1.0 - call s2c( (int(2*lon/pi)+1)*pi/2, 0.0, rd, start ) - call arc( cen, norm, start, pi/2, 0.0 ) - -* Dashed red quadrant at az = lon degs - call s2c( lon-pi/2, 0.0, 1.0, norm ) - start(1) = 0.0 - start(2) = 0.0 - start(3) = rd - call pgsci( 10 ) - call pgscr( 10, 1.0, 0.0, 0.0 ) - call pgsls( 2 ) - call pgslw( 2 ) - call arc( cen, norm, start, pi/2, 0.0 ) - -* Dashed red line of latitude at el = lat degs - cen(1) = 0.0 - cen(2) = 0.0 - cen(3) = sin(lat)*rd - norm(1) = 0.0 - norm(2) = 0.0 - norm(3) = 1.0 - call s2c( (int(2*lon/pi)+1)*pi/2, lat, rd, start ) - call arc( cen, norm, start, pi/2, 0.0 ) - -* Dashed red line from centre to az=lon el=0 - x( 1 ) = 0.0 - y( 1 ) = 0.0 - z( 1 ) = 0.0 - x( 2 ) = cos(lon)*rd - y( 2 ) = sin(lon)*rd - z( 2 ) = 0.0 - call g3dline( 2, x, y, z ) - -* Solid red line from centre to az=210 el=45 - x( 1 ) = 0.0 - y( 1 ) = 0.0 - z( 1 ) = 0.0 - call s2c( lon, lat, rd, origin ) - x( 2 ) = origin(1) - y( 2 ) = origin(2) - z( 2 ) = origin(3) - call pgsls( 1 ) - call g3dline( 2, x, y, z ) - -c+ Fig1 - (part b) - if( diag .eq. 2 ) then - call pgscr( 10, 0.0, 0.6, 0.0 ) - call s2c( lon, lat, rd, origin ) - call axes( origin, 0.2*axlen, 'daz', 'del', ' ', w1, w2, - : 'ZYZ', lon, (pi/2 - lat), pi/2 ) - endif - - -c+ Fig2 - if( diag .eq. 3 ) then - call pgscr( 10, 0.6, 0.6, 0.0 ) - call s2c( lon, lat, rd, origin ) - call axes( origin, 0.4*axlen, 'UP', 'N', ' ', w1, w2, - : 'ZYZ', lon, (pi/2 - lat), lat ) - - - call pgscr( 10, 0.0, 0.0, 1.0 ) - call s2c( lon+0.22, lat, rd, start ) - call s2c( lon, lat, rd, cen ) - call s2c( lon, lat, rd, norm ) - call arc( cen, norm, start, -(lat-0.05), -rd*0.02 ) - - call s2c( lon+0.25, lat*1.1, rd, r ) - norm(1) = 0 - norm(2) = 0 - norm(3) = 0 - u(1) = 0 - u(2) = 0 - u(3) = 1.0 - call g3dtext( 'el', r, 'CR', u, norm ) - - endif - - -c+ Fig3 - if( diag .eq. 4 ) then - call pgscr( 10, 0.0, 0.0, 1.0 ) - call s2c( lon, lat, rd, origin ) - do i = 1, 4 - theta = i*5.0*pi/180.0 - cen(1) = cos(theta)*origin(1) - cen(2) = cos(theta)*origin(2) - cen(3) = cos(theta)*origin(3) - call s2c( lon + theta, lat, rd, start ) - call arc( cen, cen, start, 2*pi, 0.05 ) - end do - - - cen(1)=0 - cen(2)=0 - cen(3)=0 - - call s2c( pi, pi/2-pi/2, rd, start ) - call s2c( pi+pi/2, 0.0, 1.0, norm ) - - call rotvec( 'ZYZ', lon, pi/2-lat, lat, norm ) - call rotvec( 'ZYZ', lon, pi/2-lat, lat, start ) - call arc( cen, norm, start, pi/2, 0.0 ) - - - call pgscr( 10, 0.0, 1.0, 1.0 ) - call s2c( lon, lat, rd, origin ) - call axes( origin, 0.2*axlen, 'y', 'x', ' ', w1, w2, - : 'ZYZ', lon, (pi/2 - lat), lat ) - endif - - -c+ Fig4 - if( diag .eq. 5 ) then - call pgscr( 10, 0.0, 0.0, 1.0 ) - call s2c( lon, lat, rd, origin ) - do i = 1, 4 - theta = i*5.0*pi/180.0 - cen(1) = cos(theta)*origin(1) - cen(2) = cos(theta)*origin(2) - cen(3) = cos(theta)*origin(3) - call s2c( lon + theta, lat, rd, start ) - call arc( cen, cen, start, 2*pi, 0.05 ) - end do - - - cen(1)=0 - cen(2)=0 - cen(3)=0 - - call s2c( pi, pi/2-pi/2, rd, start ) - call s2c( pi+pi/2, 0.0, 1.0, norm ) - - call rotvec( 'ZYZ', lon, pi/2-lat, lat, norm ) - call rotvec( 'ZYZ', lon, pi/2-lat, lat, start ) - call arc( cen, norm, start, pi/2, 0.0 ) - - - call pgscr( 10, 0.0, 1.0, 1.0 ) - call s2c( lon, lat, 0.0, origin ) - call axes( origin, rd, 'b', 'a', 'c', w1, w2, - : 'ZYZ', lon, (pi/2 - lat), pi/2 + lat ) - endif - -c+ Fig5 - if( diag .eq. 6 ) then - call pgscr( 10, 0.0, 1.0, 1.0 ) - call s2c( lon, lat, 0.0, origin ) - call axes( origin, rd, 'b', 'a', 'c', w1, w2, - : 'ZYZ', lon, (pi/2 - lat), pi/2 + lat ) - - - call pgscr( 10, 0.0, 0.0, 1.0 ) - call axes( origin, rd, 'b''', 'a''', 'c''', w1, w2, - : 'ZYZ', lon, (pi/2 - lat), pi/2 ) - - call pgsci( 1 ) - call s2c( lon, lat, 1.0, norm ) - start(1) = 0.0 - start(2) = 0.0 - start(3) = rd*0.5 - call s2c( lon, lat, 0.0, cen ) - call arc( cen, norm, start, -lat, 0.0 ) - - call pgsci( 1 ) - call s2c( 0.5*( lon - pi/2), lat/2+0.2, rd*0.55, r ) - norm(1) = 0 - norm(2) = 0 - norm(3) = 0 - u(1) = 0 - u(2) = 0 - u(3) = 1.0 - call g3dtext( 'el', r, 'CR', u, norm ) - endif - -c+ Fig6 - if( diag .eq. 7 ) then - call s2c( lon, lat, 0.0, origin ) - - call pgscr( 10, 0.0, 0.0, 1.0 ) - call axes( origin, rd, 'b''', 'a''', 'c''', w1, w2, - : 'ZYZ', lon, (pi/2 - lat), pi ) - - call pgscr( 10, 0.0, 1.0, 0.0 ) - call axes( origin, rd, 'b''''', 'a''''', 'c''''', w1, w2, - : 'ZYZ', lon, 0.0, pi ) - - endif - - - - - - if( diag .eq. 8 ) then - call pgscr( 10, 0.0, 1.0, 1.0 ) - call s2c( lon, lat, 0.0, origin ) - call axes( origin, rd, 'a', 'b', 'c', w1, w2, - : 'ZYZ', 0.0, 0.0, 0.0 ) - end if - - if( diag .eq. 9 ) then - call pgscr( 10, 0.0, 1.0, 1.0 ) - call s2c( lon, lat, 0.0, origin ) - call axes( origin, rd, 'a', 'b', 'c', w1, w2, - : 'ZYZ', lon, 0.0, 0.0 ) - end if - - if( diag .eq. 10 ) then - call pgscr( 10, 0.0, 1.0, 1.0 ) - call s2c( lon, lat, 0.0, origin ) - call axes( origin, rd, 'a', 'b', 'c', w1, w2, - : 'ZYZ', lon, pi/2-lat, 0.0 ) - end if - - if( diag .eq. 11 ) then - call pgscr( 10, 0.0, 1.0, 1.0 ) - call s2c( lon, lat, 0.0, origin ) - call axes( origin, rd, 'a', 'b', 'c', w1, w2, - : 'ZYZ', lon, pi/2-lat, lat ) - end if - - - - - - - - - - - -c if( common_map .ne. AST__NULL .and. -c ; common_x .ne. AST__BAD .and. -c : common_y .ne. AST__BAD ) then -c call ast_tran2( common_map, 1, common_x, common_y, .true., -c : dlon, dlat, status ) -c call s2c( real(dlon), real(dlat), rd, cen ) -c call pgsci( 10 ) -c call pgscr( 10, 1.0, 0.0, 1.0 ) -c call g3dmark( cen, 2 ) -c end if - - call pgsci( 1 ) - call pgslw( 4 ) - call pgsls( 1 ) - - end if - - end - - subroutine arc( cen, normal, start, ang, arrow ) - implicit none - real cen(3), normal(3), start(3), ang, arrow, ut(3), ur(3) - integer np - parameter( NP = 50 ) - integer i - real v1(3), v2( 3 ), v1l, v2l, x(NP), y(NP), z(NP), a, ca, sa, - : t1(3), t2(3), n(3) - call copy( normal, n ) - call norm( n ) - call sub( start, cen, v1 ) - call cross( n, v1, t1 ) - call cross( t1, n, v1 ) - call mod( v1, v1l ) - call cross( v1, n, v2 ) - call mod( v2, v2l ) - do i = 1, 3 - v1( i ) = v1(i)/v1l - v2( i ) = v2(i)/v2l - end do - - do i = 1, NP - a = ang*( i - 1 )/( NP - 1 ) - ca = cos(a) - sa = sin(a) - x(i) = v1l*( v1(1)*ca + v2(1)*sa ) + cen(1) - y(i) = v1l*( v1(2)*ca + v2(2)*sa ) + cen(2) - z(i) = v1l*( v1(3)*ca + v2(3)*sa ) + cen(3) - end do - call g3dline( NP, x, y, z ) - if( arrow .ne. 0.0 ) then - ca = cos(ang) - sa = sin(ang) - do i = 1, 3 - ut(i) = sa*v1(i)-ca*v2(i) - ur(i) = ca*v1(i)+sa*v2(i) - end do - x(1) = x(NP) + arrow*( ut(1) - 0.5*ur(1) ) - y(1) = y(NP) + arrow*( ut(2) - 0.5*ur(2) ) - z(1) = z(NP) + arrow*( ut(3) - 0.5*ur(3) ) - x(2) = x(NP) - y(2) = y(NP) - z(2) = z(NP) - x(3) = x(NP) + arrow*( ut(1) + 0.5*ur(1) ) - y(3) = y(NP) + arrow*( ut(2) + 0.5*ur(2) ) - z(3) = z(NP) + arrow*( ut(3) + 0.5*ur(3) ) - call g3dline( 3, x, y, z ) - end if - end - subroutine s2c( lon, lat, r, p ) - implicit none - real lon, lat, r, p(3), k - p( 3 ) = r*sin(lat) - k = r*cos(lat) - p( 1 ) = k*cos(lon) - p( 2 ) = k*sin(lon) - end - - subroutine axes( origin, axlen, tx, ty, tz, w1, w2, order, phi, - : theta, psi ) - implicit none - character order*(*),tx*(*), ty*(*), tz*(*) - real phi, theta, psi - double precision rmat(3,3),va,vb - real axlen, a1, a2, mat(3,3),x(10),y(10),z(10),r(3),u(3),n(3), - : origin(3), sn - integer w1, w2 - a1 = 0.05 - a2 = a1*0.6 - sn = 0.0 - call deuler( order, dble(phi), dble(theta), dble(psi), rmat ) - mat(1,1) = rmat(1,1) - mat(1,2) = rmat(1,2) - mat(1,3) = rmat(1,3) - mat(2,1) = rmat(2,1) - mat(2,2) = rmat(2,2) - mat(2,3) = rmat(2,3) - mat(3,1) = rmat(3,1) - mat(3,2) = rmat(3,2) - mat(3,3) = rmat(3,3) -cc* X axis with arrow and label - if( tx .ne. ' ' ) then - x(1) = axlen - y(1) = 0.0 - z(1) = 0.0 - x(2) = -axlen - y(2) = 0.0 - z(2) = 0.0 - call mxv( mat, 2, x, y, z, origin ) - call pgslw( w1 ) - call g3dline( 2, x, y, z ) - x(1) = axlen - a1 - y(1) = -a2 - z(1) = 0.0 - x(2) = axlen - y(2) = 0.0 - z(2) = 0.0 - x(3) = axlen - a1 - y(3) = a2 - z(3) = 0.0 - call mxv( mat, 3, x, y, z, origin ) - call g3dline( 3, x, y, z ) - r(1) = axlen + a1 - r(2) = 0.0 - r(3) = a2 - u(1) = 0.0 - u(2) = 0.0 - u(3) = 1.0 - n(1) = 0.0 - n(2) = sn - n(3) = 0.0 - - call pgslw( w2 ) - call mxv2( mat, r, .true., origin ) - call g3dtext( tx, r, 'BR', u, n ) - call pgslw( w1 ) - end if -c* Y axis with arrow and label - if( ty .ne. ' ' ) then - x(1) = 0.0 - y(1) = -axlen - z(1) = 0.0 - x(2) = 0.0 - y(2) = axlen - z(2) = 0.0 - call mxv( mat, 2, x, y, z, origin ) - call g3dline( 2, x, y, z ) - x(1) = -a2 - y(1) = axlen - a1 - z(1) = 0.0 - x(2) = 0.0 - y(2) = axlen - z(2) = 0.0 - x(3) = a2 - y(3) = axlen - a1 - z(3) = 0.0 - call mxv( mat, 3, x, y, z, origin ) - call g3dline( 3, x, y, z ) - r(1) = 0.0 - r(2) = axlen + a1 - r(3) = a2 - u(1) = 0.0 - u(2) = 0.0 - u(3) = 1.0 - n(1) = sn - n(2) = 0.0 - n(3) = 0.0 - - call pgslw( w2 ) - call mxv2( mat, r, .true., origin ) - call g3dtext( ty, r, 'BR', u, n ) - call pgslw( w1 ) - end if -c* Z axis with arrow and label - if( tz .ne. ' ' ) then - x(1) = 0.0 - y(1) = 0.0 - z(1) = axlen - x(2) = 0.0 - y(2) = 0.0 - z(2) = 0.0 - call mxv( mat, 2, x, y, z, origin ) - call g3dline( 2, x, y, z ) - x(1) = -a2 - y(1) = 0.0 - z(1) = axlen - a1 - x(2) = 0.0 - y(2) = 0.0 - z(2) = axlen - x(3) = a2 - y(3) = 0.0 - z(3) = axlen - a1 - call mxv( mat, 3, x, y, z, origin ) - call g3dline( 3, x, y, z ) - r(1) = 0.0 - r(2) = 0.0 - r(3) = axlen + a1 - u(1) = 0.0 - u(2) = 0.0 - u(3) = 1.0 - n(1) = 0.0 - n(2) = 0.0 - n(3) = 0.0 - - call pgslw( w2 ) - call mxv2( mat, r, .true., origin ) - call g3dtext( tz, r, 'CR', u, n ) - call pgslw( w1 ) - end if - end - - subroutine mxv( mat, n, x, y, z, origin ) - implicit none - integer n, i - real x(n), y(n), z(n), mat(3,3), va(3),vb(3),origin(3) - do i = 1, n - va(1)= x(i) - va(2)= y(i) - va(3)= z(i) - call sla_mxv( mat, va, vb ) - x(i) = vb(1) + origin(1) - y(i) = vb(2) + origin(2) - z(i) = vb(3) + origin(3) - end do - end - - subroutine mxv2( mat, r, move, origin ) - implicit none - real r(3), mat(3,3), vb(3), origin(3) - logical move - call sla_mxv( mat, r, vb ) - if( move ) then - r(1) = vb(1) + origin(1) - r(2) = vb(2) + origin(2) - r(3) = vb(3) + origin(3) - else - r(1) = vb(1) - r(2) = vb(2) - r(3) = vb(3) - end if - end - - subroutine deuler( order, phi, theta, psi, rmat ) - implicit none - character order*(*) - double precision phi, theta, psi, rmat(3,3), t(3), smat(3,3) - double precision ang, v(3), ux(3), uy(3), uz(3), tmat(3,3), - : axvec(3) - integer n, i, j - n = len( order ) - do i = 1, 3 - ux(i) = 0.0D0 - uy(i) = 0.0D0 - uz(i) = 0.0D0 - do j = 1, 3 - rmat(i,j) = 0.0 - end do - rmat(i,i) = 1.0 - end do - ux(1) = 1.0D0 - uy(2) = 1.0D0 - uz(3) = 1.0D0 - do i = 1, 3 - if( i .le. n ) then - if( i .eq. 1 ) then - ang = phi - else if( i .eq. 2 ) then - ang = theta - else - ang = psi - end if - if( order( i : i ) .eq. 'X' ) then - do j = 1, 3 - axvec(j) = -ux(j)*ang - end do - else if( order( i : i ) .eq. 'Y' ) then - do j = 1, 3 - axvec(j) = -uy(j)*ang - end do - else if( order( i : i ) .eq. 'Z' ) then - do j = 1, 3 - axvec(j) = -uz(j)*ang - end do - else - write(*,*) 'Bad axis label (',order(i:i),') in deuler!!!' - end if - call sla_dav2m( axvec, tmat ) - do j = 1, 3 - smat(1,j) = rmat(1,j) - smat(2,j) = rmat(2,j) - smat(3,j) = rmat(3,j) - end do - call sla_dmxm( tmat, smat, rmat ) - call sla_dmxv( tmat, ux, v ) - ux(1) = v(1) - ux(2) = v(2) - ux(3) = v(3) - call sla_dmxv( tmat, uy, v ) - uy(1) = v(1) - uy(2) = v(2) - uy(3) = v(3) - call sla_dmxv( tmat, uz, v ) - uz(1) = v(1) - uz(2) = v(2) - uz(3) = v(3) - end if - end do - end - - subroutine rotvec( order, phi, theta, psi, v ) - implicit none - character order*(*) - real phi, theta, psi,v(3),vt(3) - double precision rmat(3,3) - real mat(3,3) - call deuler( order, dble(phi), dble(theta), dble(psi), rmat ) - mat(1,1) = rmat(1,1) - mat(1,2) = rmat(1,2) - mat(1,3) = rmat(1,3) - mat(2,1) = rmat(2,1) - mat(2,2) = rmat(2,2) - mat(2,3) = rmat(2,3) - mat(3,1) = rmat(3,1) - mat(3,2) = rmat(3,2) - mat(3,3) = rmat(3,3) - call sla_mxv( mat, v, vt ) - v(1) = vt(1) - v(2) = vt(2) - v(3) = vt(3) - end - - subroutine cross( a, b, c ) - implicit none - real a(3), b(3), c(3) - c(1) = a(2)*b(3) - a(3)*b(2) - c(2) = - a(1)*b(3) + a(3)*b(1) - c(3) = a(1)*b(2) - a(2)*b(1) - end - - subroutine sub( a, b, c ) - implicit none - real a(3), b(3), c(3) - c(1) = a(1) - b(1) - c(2) = a(2) - b(2) - c(3) = a(3) - b(3) - end - - subroutine add( a, b, c ) - implicit none - real a(3), b(3), c(3) - c(1) = a(1) + b(1) - c(2) = a(2) + b(2) - c(3) = a(3) + b(3) - end - - subroutine dot( a, b, c ) - implicit none - real a(3), b(3), c - c = a(1)*b(1) + a(2)*b(2) + a(3)*b(3) - end - - subroutine mod( a, c ) - implicit none - real a(3), c - c = sqrt( a(1)*a(1) + a(2)*a(2) + a(3)*a(3) ) - end - - subroutine copy( a, b ) - implicit none - real a(3), b(3) - b(1) = a(1) - b(2) = a(2) - b(3) = a(3) - end - - subroutine norm( a ) - implicit none - real a(3), b - call mod( a, b ) - if( b .ne. 0.0 ) then - a(1) = a(1)/b - a(2) = a(2)/b - a(3) = a(3)/b - end if - end - - subroutine g3dtext( t, r, j, u, n ) - implicit none - character*(*) t, j - real r(3), u(3), n(3), r2(3),u2(3),n2(3) - integer junk, ast_g3dtext - - call copy( r, r2 ) - call copy( u, u2 ) - call copy( n, n2 ) - r2(2) = -r2(2) - u2(2) = -u2(2) - n2(2) = -n2(2) - - junk = ast_g3dtext( t, r2, j, u2, n2 ) - end - - subroutine g3dline( n, x, y, z ) - implicit none - integer i, n - logical junk, ast_g3dline - real x(n), y(n), z(n) - - do i = 1, n - y(i)=-y(i) - end do - - junk = ast_g3dline( n, x, y, z ) - - do i = 1, n - y(i)=-y(i) - end do - - end - - subroutine g3dmark( pos, type ) - implicit none - real pos(3) - integer type - logical junk, ast_g3dmark - - pos(2) = -pos(2) - junk = ast_g3dmark( 1, pos(1), pos(2), pos(3), type, pos ) - pos(2) = -pos(2) - - end - - - - - - subroutine maketanmap( new, lon, lat, rot, azelmap, status ) - implicit none - - include 'SAE_PAR' - include 'AST_PAR' - - logical new - double precision lon, lat, rot - integer azelmap, status - - double precision mmt( 2 ), mat(9), mat1(9), mat2(3) - integer tanmap, tmap, sphmap, wcsmap, m1, m2, m3, c0, c1, matmap1, - : matmap2 - double precision pi, piby2 - - if( status .ne. sai__ok ) return - - pi = 3.1415927D0 - piby2 = pi/2.0 - - c0 = ast_SphMap( 'UnitRadius=1', status ) - wcsmap = ast_WcsMap( 2, AST__TAN, 1, 2, ' ', status ) - call ast_Invert( wcsmap, status ) - call ast_Invert( c0, status ) - c1 = ast_CmpMap( wcsmap, c0, .true., ' ', status ) - call ast_Invert( c0, status ) - - if( new ) then - mmt( 1 ) = -1.0 - mmt( 2 ) = -1.0 - tmap = ast_MatrixMap( 2, 2, 1, mmt, ' ', status ) - -* Note, sla_deuler groups columns in the returned matrix, but slaDeuler -* groups rows. AST always expects rows to be grouped, so transpose the -* matrices returned by sla_deuler. - call sla_Deuler( 'Z', -rot, 0.0D0, 0.0D0, mat1 ) - call trans( mat1 ) - m1 = ast_MatrixMap( 3, 3, 0, mat1, ' ', status ) - - call sla_Deuler( 'Y', (PIBY2-lat), 0.0D0, 0.0D0, mat1 ) - call trans( mat1 ) - m2 = ast_MatrixMap( 3, 3, 0, mat1, ' ', status ) - - call sla_Deuler( 'Z', (lon-PI), 0.0D0, 0.0D0, mat1 ) - call trans( mat1 ) - m3 = ast_MatrixMap( 3, 3, 0, mat1, ' ', status ) - - matmap1 = ast_CmpMap( m1, ast_CmpMap( m2, m3, .true., ' ', - : status ), - : .TRUE., ' ', status ) - - mat2( 1 ) = 1.0 - mat2( 2 ) = -1.0 - mat2( 3 ) = 1.0 - matmap2 = ast_MatrixMap( 3, 3, 1, mat2, ' ', status ) - - m1 = ast_CmpMap( c1, matmap1, .true., ' ', status ) - m2 = ast_CmpMap( m1, matmap2, .true., ' ', status ) - tanmap = ast_CmpMap( m2, c0, .true., ' ', status ) - azelmap = ast_CmpMap( tmap, tanmap, .true., ' ', status ) - - else - -* Note, sla_deuler groups columns in the returned matrix, but slaDeuler -* groups rows. AST always expects rows to be grouped, so transpose the -* matrices returned by sla_deuler. - call sla_Deuler( 'Z', rot, 0.0D0, 0.0D0, mat1 ) - call trans( mat1 ) - m1 = ast_MatrixMap( 3, 3, 0, mat1, ' ', status ) - - call sla_Deuler( 'Y', -(PIBY2-lat), 0.0D0, 0.0D0, mat1 ) - call trans( mat1 ) - m2 = ast_MatrixMap( 3, 3, 0, mat1, ' ', status ) - - call sla_Deuler( 'Z', -lon, 0.0D0, 0.0D0, mat1 ) - call trans( mat1 ) - m3 = ast_MatrixMap( 3, 3, 0, mat1, ' ', status ) - - - matmap1 = ast_CmpMap( m1, ast_CmpMap( m2, m3, .true., ' ', - : status ), - : .TRUE., ' ', status ) - - m1 = ast_CmpMap( c1, matmap1, .true., ' ', status ) - - - - - - - mmt( 1 ) = -1.0 - mmt( 2 ) = 1.0 - tmap = ast_MatrixMap( 2, 2, 1, mmt, ' ', status ) - m2 = ast_CmpMap( tmap, m1, .true., ' ', status ) - - - - - - - azelmap = ast_CmpMap( m2, c0, .true., ' ', status ) - - end if - - end - - subroutine trans( mat ) - implicit none - double precision t, mat(9) - - t = mat(8) - mat(8) = mat(6) - mat(6) = t - - t = mat(3) - mat(3) = mat(7) - mat(7) = t - - t = mat(2) - mat(2) = mat(4) - mat(4) = t - - end diff --git a/ast/ast_tester/testpolymap.f b/ast/ast_tester/testpolymap.f deleted file mode 100644 index 1251894..0000000 --- a/ast/ast_tester/testpolymap.f +++ /dev/null @@ -1,319 +0,0 @@ - program testpolymap - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'PRM_PAR' - - integer status, pm, pm2, i, maxord, nco - double precision coeff( 16 ), lbnd( 2 ), ubnd( 2 ), - : xin(3), yin(3), xout(3), yout(3), errlim, - : xin2(3), yin2(3), coeff_1d(6), acc, - : coeff2( 24 ), coeff3( 6*4 ), err, maxacc, - : cofs( 20 ) - - data coeff / 1.0, 1.0, 0.0, 0.0, - : 2.0, 1.0, 1.0, 0.0, - : 1.0, 2.0, 0.0, 0.0, - : 3.0, 2.0, 0.0, 1.0 / - - data coeff2 / 1.0, 1.0, 0.0, 0.0, - : 2.0, 1.0, 1.0, 0.0, - : 1.0, 1.0, 0.0, 1.0, - : 1.0, 2.0, 0.0, 0.0, - : 1.0, 2.0, 1.0, 0.0, - : 2.0, 2.0, 0.0, 1.0 / - -c data coeff3 / -0.1, 1.0, 0.0, 0.0, -c : 0.99, 1.0, 1.0, 0.0, -c : 1.0E-4, 1.0, 1.0, 1.0, -c : -1.0E-9, 1.0, 2.0, 1.0, -c : -0.1, 2.0, 0.0, 0.0, -c : 0.99, 2.0, 0.0, 1.0, -c : 1.0E-4, 2.0, 1.0, 1.0, -c : -1.0E-9, 2.0, 1.0, 2.0 / - - data coeff3 / -0.1, 1.0, 0.0, 0.0, - : 0.99, 1.0, 1.0, 0.0, - : 1.0E-4, 1.0, 1.0, 1.0, - : -0.1, 2.0, 0.0, 0.0, - : 0.99, 2.0, 0.0, 1.0, - : 1.0E-4, 2.0, 1.0, 1.0 / - - - data coeff_1d / 1.0, 1.0, 0.0, - : 2.0, 1.0, 1.0 / - - data lbnd / -10.0D2, -10.0D2 / - data ubnd / 10.0D2, 10.0D2 / - - - - status = sai__ok - call ast_begin( status ) - -c call ast_watchmemory( 131 ) - - acc = 1.0D-7 - errlim = 1000*acc - maxacc = 1.0D-3 - maxord = 10 - - pm = ast_polymap( 2, 2, 4, coeff, 0, coeff, ' ', status ) - - call ast_polycoeffs( pm, .true., 0, 0.0D0, nco, status ) - if( nco .ne. 4 ) then - call stopit( -1, status ) - endif - - call ast_polycoeffs( pm, .false., 0, 0.0D0, nco, status ) - if( nco .ne. 0 ) then - call stopit( -2, status ) - endif - - call ast_polycoeffs( pm, .true., 20, cofs, nco, status ) - if( nco .ne. 4 ) then - call stopit( -3, status ) - else - do i = 1, 16 - if( cofs( i ) .ne. coeff( i ) ) then - call stopit( -4, status ) - end if - end do - endif - - pm2 = ast_polytran( pm, .FALSE., acc, maxacc, maxord, lbnd, - : ubnd, status ) - - xin( 1 ) = 1.0d0 - xin( 2 ) = 100.0d0 - xin( 3 ) = -50.0d0 - yin( 1 ) = 1.0d0 - yin( 2 ) = 100.0d0 - yin( 3 ) = -50.0d0 - - call ast_tran2( pm2, 3, xin, yin, .true., xout, yout, - : status ) - call ast_tran2( pm2, 3, xout, yout, .false., xin2, yin2, - : status ) - - do i = 1, 3 - if( abs( xin( i ) - xin2( i ) ) .gt. errlim ) then - call stopit( 1, status ) - endif - if( abs( yin( i ) - yin2( i ) ) .gt. errlim ) then - call stopit( 2, status ) - endif - end do - - - - call ast_setl( pm2, 'IterInverse', .TRUE., status ) - call ast_tran2( pm2, 3, xout, yout, .false., xin2, yin2, - : status ) - do i = 1, 3 - if( abs( xin( i ) - xin2( i ) ) .gt. errlim ) then - call stopit( 1001, status ) - endif - if( abs( yin( i ) - yin2( i ) ) .gt. errlim ) then - call stopit( 1002, status ) - endif - end do - - - - - - pm = ast_polymap( 1, 1, 2, coeff_1d, 0, coeff_1d, ' ', status ) - pm2 = ast_polytran( pm, .FALSE., acc, maxacc, maxord, lbnd, - : ubnd, status ) - - xin( 1 ) = 1.0d0 - xin( 2 ) = 100.0d0 - xin( 3 ) = -50.0d0 - - call ast_tran1( pm2, 3, xin, .true., xout, status ) - call ast_tran1( pm2, 3, xout, .false., xin2, status ) - - do i = 1, 3 - if( abs( xin( i ) - xin2( i ) ) .gt. errlim ) then - call stopit( 3, status ) - endif - end do - - call ast_setl( pm2, 'IterInverse', .TRUE., status ) - call ast_tran1( pm2, 3, xout, .false., xin2, status ) - - do i = 1, 3 - if( abs( xin( i ) - xin2( i ) ) .gt. errlim ) then - call stopit( 3001, status ) - endif - end do - - - - - pm = ast_polymap( 2, 2, 6, coeff2, 0, coeff2, ' ', status ) - pm2 = ast_polytran( pm, .FALSE., acc, maxacc, maxord, lbnd, - : ubnd, status ) - - xin( 1 ) = 1.0d0 - xin( 2 ) = 100.0d0 - xin( 3 ) = -50.0d0 - yin( 1 ) = 1.0d0 - yin( 2 ) = 100.0d0 - yin( 3 ) = -50.0d0 - - call ast_tran2( pm2, 3, xin, yin, .true., xout, yout, - : status ) - call ast_tran2( pm2, 3, xout, yout, .false., xin2, yin2, - : status ) - - do i = 1, 3 - if( abs( xin( i ) - xin2( i ) ) .gt. errlim ) then - call stopit( 4, status ) - endif - if( abs( yin( i ) - yin2( i ) ) .gt. errlim ) then - call stopit( 5, status ) - endif - end do - - call ast_setl( pm2, 'IterInverse', .TRUE., status ) - call ast_tran2( pm2, 3, xout, yout, .false., xin2, yin2, - : status ) - - do i = 1, 3 - if( abs( xin( i ) - xin2( i ) ) .gt. errlim ) then - call stopit( 4001, status ) - endif - if( abs( yin( i ) - yin2( i ) ) .gt. errlim ) then - call stopit( 5001, status ) - endif - end do - - - - - - - - pm = ast_polymap( 2, 2, 6, coeff3, 0, coeff3, ' ', status ) - pm2 = ast_polytran( pm, .FALSE., acc, maxacc, maxord, lbnd, - : ubnd, status ) - - xin( 1 ) = 1.0d0 - xin( 2 ) = 100.0d0 - xin( 3 ) = -50.0d0 - yin( 1 ) = 1.0d0 - yin( 2 ) = 100.0d0 - yin( 3 ) = -50.0d0 - - call ast_tran2( pm2, 3, xin, yin, .true., xout, yout, - : status ) - call ast_tran2( pm2, 3, xout, yout, .false., xin2, yin2, - : status ) - - do i = 1, 3 - if( abs( xin( i ) - xin2( i ) ) .gt. errlim ) then - write(*,*) i, xin( i ), xin2( i ), errlim - call stopit( 6, status ) - endif - if( abs( yin( i ) - yin2( i ) ) .gt. errlim ) then - call stopit( 7, status ) - endif - end do - - - call ast_setl( pm2, 'IterInverse', .TRUE., status ) - call ast_tran2( pm2, 3, xout, yout, .false., xin2, yin2, - : status ) - - do i = 1, 3 - if( abs( xin( i ) - xin2( i ) ) .gt. errlim ) then - write(*,*) i, xin( i ), xin2( i ), errlim - call stopit( 6001, status ) - endif - if( abs( yin( i ) - yin2( i ) ) .gt. errlim ) then - call stopit( 7001, status ) - endif - end do - - - - if( .not. ast_getl( pm, 'TranForward', status ) ) then - call stopit( 8001, status ) - else if( .not. ast_getl( pm, 'IterInverse', status ) ) then - call stopit( 8002, status ) - else if( .not. ast_getl( pm, 'TranInverse', status ) ) then - call stopit( 8003, status ) - endif - - call ast_setl( pm, 'IterInverse', .FALSE., status ) - - if( .not. ast_getl( pm, 'TranForward', status ) ) then - call stopit( 8004, status ) - else if( ast_getl( pm, 'IterInverse', status ) ) then - call stopit( 8005, status ) - else if( ast_getl( pm, 'TranInverse', status ) ) then - call stopit( 8006, status ) - endif - - call ast_invert( pm, status ) - - if( ast_getl( pm, 'TranForward', status ) ) then - call stopit( 8007, status ) - else if( ast_getl( pm, 'IterInverse', status ) ) then - call stopit( 8008, status ) - else if( .not. ast_getl( pm, 'TranInverse', status ) ) then - call stopit( 8009, status ) - endif - - call ast_setl( pm, 'IterInverse', .TRUE., status ) - - if( .not. ast_getl( pm, 'TranForward', status ) ) then - call stopit( 8010, status ) - else if( .not. ast_getl( pm, 'IterInverse', status ) ) then - call stopit( 8011, status ) - else if( .not. ast_getl( pm, 'TranInverse', status ) ) then - call stopit( 8012, status ) - endif - - call ast_invert( pm, status ) - - if( .not. ast_getl( pm, 'TranForward', status ) ) then - call stopit( 8013, status ) - else if( .not. ast_getl( pm, 'IterInverse', status ) ) then - call stopit( 8014, status ) - else if( .not. ast_getl( pm, 'TranInverse', status ) ) then - call stopit( 8015, status ) - endif - - - - - - - - - - call ast_end( status ) - call ast_activememory( 'testpolymap' ); - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All PolyMap tests passed' - else - write(*,*) 'PolyMap tests failed' - end if - - end - - - subroutine stopit( i, status ) - implicit none - include 'SAE_PAR' - integer i, status - if( status .eq. sai__ok ) then - write( *,* ) 'Error ',i - status = sai__error - end if - end diff --git a/ast/ast_tester/testrate.f b/ast/ast_tester/testrate.f deleted file mode 100644 index 4803294..0000000 --- a/ast/ast_tester/testrate.f +++ /dev/null @@ -1,344 +0,0 @@ - program testrate - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'PRM_PAR' - - integer status, m, outp(4), inp(4), c1, c2, c3, c4 - double precision at(4), r, mat(4), b1(2), b2(2), a1(2), - : a2(4) - - status = sai__ok - - at(1) = 10.0D0 - at(2) = 1.2D6 - -* UnitMap - m = ast_unitmap( 2, ' ', status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 1.0D0 ) call stopit( 1, r, status ) - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 2, r, status ) - - call ast_invert( m, status ) - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 1.0D0 ) call stopit( 202, r, status ) - -* ZoomMap - m = ast_zoommap( 2, 2.0D0, ' ', status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 2.0D0 ) call stopit( 3, r, status ) - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 4, r, status ) - - call ast_invert( m, status ) - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 0.5D0 ) call stopit( 402, r, status ) - -* MatrixMap - m = ast_matrixmap( 2, 2, 2, mat, ' ', status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 1.0D0 ) call stopit( 5, r, status ) - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 6, r, status ) - - call ast_invert( m, status ) - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 1.0D0 ) call stopit( 602, r, status ) - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 603, r, status ) - - mat(1)= -2.0D0 - mat(2)= 1.5D0 - m = ast_matrixmap( 2, 2, 1, mat, ' ', status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. -2.0D0 ) call stopit( 7, r, status ) - r = ast_rate( m, at, 2, 2, status ) - if( r .ne. 1.5D0 ) call stopit( 8, r, status ) - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 9, r, status ) - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 10, r, status ) - - call ast_invert( m, status ) - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. -0.5D0 ) call stopit( 1002, r, status ) - - mat(1)= 1.2D0 - mat(2)= 1.6D0 - mat(3)= -1.6D0 - mat(4)= 2.2D0 - m = ast_matrixmap( 2, 2, 0, mat, ' ', status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 1.2D0 ) call stopit( 11, r, status ) - r = ast_rate( m, at, 2, 2, status ) - if( r .ne. 2.2D0 ) call stopit( 12, r, status ) - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 1.6D0 ) call stopit( 13, r, status ) - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. -1.6D0 ) call stopit( 14, r, status ) - - call ast_invert( m, status ) - - r = ast_rate( m, at, 1, 1, status ) - if( abs( r - 0.423076923 ) .gt. 1.0E-6 ) call stopit( 15, r, - : status ) - - r = ast_rate( m, at, 2, 2, status ) - if( abs( r - 0.230769231 ) .gt. 1.0E-6 ) call stopit( 16, r, - : status ) - - r = ast_rate( m, at, 1, 2, status ) - if( abs( r + 0.307692308 ) .gt. 1.0E-6 ) call stopit( 17, r, - : status ) - - r = ast_rate( m, at, 2, 1, status ) - if( abs( r - 0.307692308 ) .gt. 1.0E-6 ) call stopit( 18, r, - : status ) - - -* ShiftMap - mat(1) = -1.2D0 - mat(2) = 1.2D0 - m = ast_shiftmap( 2, mat, ' ', status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 1.0D0 ) call stopit( 20, r, status ) - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 21, r, status ) - - call ast_invert( m, status ) - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 1.0D0 ) call stopit( 23, r, status ) - - -* WinMap - a1( 1 ) = 0.0D0 - a1( 2 ) = 0.0D0 - a2( 1 ) = 1.0D0 - a2( 2 ) = 1.0D0 - b1( 1 ) = 0.5D0 - b1( 2 ) = 0.5D0 - b2( 1 ) = 2.5D0 - b2( 2 ) = 2.5D0 - m = ast_winmap( 2, a1, a2, b1, b2, ' ', status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 2.0D0 ) call stopit( 24, r, status ) - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 25, r, status ) - - r = ast_rate( m, at, 2, 2, status ) - if( r .ne. 2.0D0 ) call stopit( 26, r, status ) - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 27, r, status ) - - - call ast_invert( m, status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 0.5D0 ) call stopit( 29, r, status ) - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 30, r, status ) - - r = ast_rate( m, at, 2, 2, status ) - if( r .ne. 0.5D0 ) call stopit( 31, r, status ) - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 32, r, status ) - - - -* PermMap - outp(1)=2 - outp(2)=1 - inp(1)=1 - inp(2)=2 - m = ast_permmap( 2, inp, 2, outp, 0.0D0, ' ', status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 34, r, status ) - - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 1.0D0 ) call stopit( 35, r, status ) - - r = ast_rate( m, at, 2, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 37, r, status ) - - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 1.0D0 ) call stopit( 38, r, status ) - - call ast_invert( m, status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 1.0D0 ) call stopit( 40, r, status ) - - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 41, r, status ) - - r = ast_rate( m, at, 2, 2, status ) - if( r .ne. 1.0D0 ) call stopit( 43, r, status ) - - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 44, r, status ) - -* TranMap - a1( 1 ) = 0.0D0 - a1( 2 ) = 0.0D0 - a2( 1 ) = 1.0D0 - a2( 2 ) = 1.0D0 - b1( 1 ) = 0.5D0 - b1( 2 ) = 0.5D0 - b2( 1 ) = 2.5D0 - b2( 2 ) = 2.5D0 - c1 = ast_winmap( 2, a1, a2, b1, b2, ' ', status ) - - mat(1)= 1.2D0 - mat(2)= 1.6D0 - mat(3)= -1.6D0 - mat(4)= 2.2D0 - c2 = ast_matrixmap( 2, 2, 0, mat, ' ', status ) - - m = ast_tranmap( c1, c2, ' ', status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 2.0D0 ) call stopit( 46, r, status ) - r = ast_rate( m, at, 2, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 47, r, status ) - - r = ast_rate( m, at, 2, 2, status ) - if( r .ne. 2.0D0 ) call stopit( 48, r, status ) - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 49, r, status ) - - call ast_invert( m, status ) - - r = ast_rate( m, at, 1, 1, status ) - if( abs( r - 0.423076923 ) .gt. 1.0E-6 ) call stopit( 51, r, - : status ) - r = ast_rate( m, at, 2, 2, status ) - if( abs( r - 0.230769231 ) .gt. 1.0E-6 ) call stopit( 52, r, - : status ) - r = ast_rate( m, at, 1, 2, status ) - if( abs( r + 0.307692308 ) .gt. 1.0E-6 ) call stopit( 53, r, - : status ) - r = ast_rate( m, at, 2, 1, status ) - if( abs( r - 0.307692308 ) .gt. 1.0E-6 ) call stopit( 54, r, - : status ) - - -* CmpMap - mat(1) = -1.0D0 - mat(2) = 1.0D0 - c1 = ast_shiftmap( 2, mat, ' ', status ) - mat(1)= 1.0D0 - mat(2)= 2.0D0 - mat(3)= -2.0D0 - mat(4)= 3.0D0 - c2 = ast_matrixmap( 2, 2, 0, mat, ' ', status ) - c3 = ast_cmpmap( c1, c2, 0, ' ', status ) - - outp(1) = 3 - outp(2) = 4 - outp(3) = 1 - outp(4) = 2 - inp(1) = 3 - inp(2) = 4 - inp(3) = 1 - inp(4) = 2 - c1 = ast_permmap( 4, inp, 4, outp, 0.0D0, ' ', status ) - c2 = ast_ZoomMap( 4, 0.25D0, ' ', status ) - call ast_invert( c2, status ) - - c4 = ast_cmpmap( c1, c2, 1, ' ', status ) - call ast_invert( c4, status ) - - m = ast_cmpmap( c3, c4, 1, ' ', status ) - - call ast_invert( c2, status ) - call ast_invert( c3, status ) - call ast_invert( c4, status ) - - at(1) = 1.0D0 - at(2) = 2.0D0 - at(3) = 3.0D0 - at(4) = 4.0D0 - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 55, r, status ) - - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 56, r, status ) - - r = ast_rate( m, at, 1, 3, status ) - if( abs( r - 0.25D0 ) .gt. 1.0D-6 ) call stopit( 57, r, status ) - - r = ast_rate( m, at, 1, 4, status ) - if( r .ne. 0.5D0 ) call stopit( 58, r, status ) - - r = ast_rate( m, at, 3, 1, status ) - if( r .ne. 0.25D0 ) call stopit( 59, r, status ) - - r = ast_rate( m, at, 3, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 60, r, status ) - - r = ast_rate( m, at, 3, 3, status ) - if( r .ne. 0.0D0 ) call stopit( 61, r, status ) - - r = ast_rate( m, at, 3, 4, status ) - if( r .ne. 0.0D0 ) call stopit( 62, r, status ) - - - call ast_invert( m, status ) - - r = ast_rate( m, at, 1, 1, status ) - if( r .ne. 0.0D0 ) call stopit( 63, r, status ) - - r = ast_rate( m, at, 1, 2, status ) - if( r .ne. 0.0D0 ) call stopit( 64, r, status ) - - r = ast_rate( m, at, 1, 3, status ) - if( r .ne. 4.0D0 ) call stopit( 65, r, status ) - - r = ast_rate( m, at, 1, 4, status ) - if( r .ne. 0.0D0 ) call stopit( 66, r, status ) - - r = ast_rate( m, at, 3, 1, status ) - if( abs( r - 12.0D0/7.0D0 ) .gt. 1.0D-6 ) - : call stopit( 67, r, status ) - - r = ast_rate( m, at, 3, 2, status ) - if( abs( r - (-8.0D0/7.0D0) ) .gt. 1.0D-6 ) - : call stopit( 68, r, status ) - - r = ast_rate( m, at, 3, 3, status ) - if( r .ne. 0.0D0 ) call stopit( 69, r, status ) - - r = ast_rate( m, at, 3, 4, status ) - if( r .ne. 0.0D0 ) call stopit( 70, r, status ) - - - - - if( status .eq. sai__ok ) then - write(*,*) 'All AST_RATE tests passed' - else - write(*,*) 'AST_RATE tests failed' - end if - - end - - - subroutine stopit( i, r, status ) - implicit none - include 'SAE_PAR' - integer i, status - double precision r - if( status .eq. sai__ok ) then - write( *,* ) 'Error ',i,': ',r - status = sai__error - end if - end diff --git a/ast/ast_tester/testratemap.f b/ast/ast_tester/testratemap.f deleted file mode 100644 index 720a4b9..0000000 --- a/ast/ast_tester/testratemap.f +++ /dev/null @@ -1,148 +0,0 @@ - program testratemap - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'PRM_PAR' - - integer status, m, outp(4), inp(4), c1, c2, c3, c4, rm - double precision at(4), r, mat(4), b1(2), b2(2), a1(2), - : a2(4) - - status = sai__ok - - at(1) = 10.0D0 - at(2) = 1.2D6 - - mat(1) = -1.0D0 - mat(2) = 1.0D0 - c1 = ast_shiftmap( 2, mat, ' ', status ) - mat(1)= 1.0D0 - mat(2)= 2.0D0 - mat(3)= -2.0D0 - mat(4)= 3.0D0 - c2 = ast_matrixmap( 2, 2, 0, mat, ' ', status ) - c3 = ast_cmpmap( c1, c2, 0, ' ', status ) - - outp(1) = 3 - outp(2) = 4 - outp(3) = 1 - outp(4) = 2 - inp(1) = 3 - inp(2) = 4 - inp(3) = 1 - inp(4) = 2 - c1 = ast_permmap( 4, inp, 4, outp, 0.0D0, ' ', status ) - c2 = ast_ZoomMap( 4, 0.25D0, ' ', status ) - call ast_invert( c2, status ) - - c4 = ast_cmpmap( c1, c2, 1, ' ', status ) - call ast_invert( c4, status ) - - m = ast_cmpmap( c3, c4, 1, ' ', status ) - - call ast_invert( c2, status ) - call ast_invert( c3, status ) - call ast_invert( c4, status ) - - rm = ast_ratemap( m, 1, 1, ' ', status ) - at(1) = 1.0D0 - at(2) = 2.0D0 - at(3) = 3.0D0 - at(4) = 4.0D0 - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 1, r, status ) - - if( .not. ast_getl( rm, 'TranForward', status ) ) call stopit( 2, - : r, status ) - - if( ast_getl( rm, 'TranInverse', status ) ) call stopit( 3, r, - : status ) - - rm = ast_ratemap( m, 1, 2, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 4, r, status ) - - rm = ast_ratemap( m, 1, 3, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( abs( r - 0.25D0 ) .gt. 1.0D-6 ) call stopit( 5, r, status ) - - rm = ast_ratemap( m, 1, 4, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.5D0 ) call stopit( 6, r, status ) - - rm = ast_ratemap( m, 3, 1, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.25D0 ) call stopit( 7, r, status ) - - rm = ast_ratemap( m, 3, 2, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 8, r, status ) - - rm = ast_ratemap( m, 3, 3, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 9, r, status ) - - rm = ast_ratemap( m, 3, 4, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 10, r, status ) - - call ast_invert( m, status ) - - rm = ast_ratemap( m, 1, 1, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 11, r, status ) - - rm = ast_ratemap( m, 1, 2, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 12, r, status ) - - rm = ast_ratemap( m, 1, 3, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 4.0D0 ) call stopit( 13, r, status ) - - rm = ast_ratemap( m, 1, 4, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 14, r, status ) - - rm = ast_ratemap( m, 3, 1, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( abs( r - 12.0D0/7.0D0 ) .gt. 1.0E-6 ) - : call stopit( 15, r, status ) - - rm = ast_ratemap( m, 3, 2, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( abs( r - (-8.0D0/7.0D0) ) .gt. 1.0E-6 ) - : call stopit( 16, r, status ) - - rm = ast_ratemap( m, 3, 3, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 17, r, status ) - - rm = ast_ratemap( m, 3, 4, ' ', status ) - call ast_trann( rm, 1, 4, 1, at, 1, 1, 1, r, status ) - if( r .ne. 0.0D0 ) call stopit( 18, r, status ) - - - - - - - if( status .eq. sai__ok ) then - write(*,*) 'All RateMap tests passed' - else - write(*,*) 'RateMap tests failed' - end if - - end - - - subroutine stopit( i, r, status ) - implicit none - include 'SAE_PAR' - integer i, status - double precision r - if( status .eq. sai__ok ) then - write( *,* ) 'Error ',i,': ',r - status = sai__error - end if - end diff --git a/ast/ast_tester/testrebin.f b/ast/ast_tester/testrebin.f deleted file mode 100644 index 5ec976f..0000000 --- a/ast/ast_tester/testrebin.f +++ /dev/null @@ -1,4176 +0,0 @@ - program testrebin - implicit none - include 'SAE_PAR' - external test1, test2, test3, test4, test5, test6, test7, test8, - : test9 - integer status - status = sai__ok - - call ast_begin( status ) - - call tester( test7, status ) - call tester( test8, status ) - call tester( test9, status ) - call tester( test1, status ) - call tester( test2, status ) - call tester( test3, status ) - call tester( test4, status ) - call tester( test5, status ) - call tester( test6, status ) - - call ast_end( status ) - call ast_flushmemory( 1 ) - - - if( status .eq. sai__ok ) then - write(*,*) 'All AST_REBIN tests passed' - else - write(*,*) 'AST_REBIN tests failed' - end if - - end - - - - -* -* Do a given test with a all data types and spread functions. -* - subroutine tester( testfun, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'PRM_PAR' - include 'CNF_PAR' - - integer m, lbnd_in(10), ubnd_in(10), ipin, ipin_var, - : lbnd_out(10), ubnd_out(10), lbnd(10), ubnd(10), ipout, - : ipout_var, status, nin, nout, i, nel_in, nel_out, - : spreads(6), j - character types(3)*15, name*20 - double precision tol, params(20) - external testfun - - data types/ '_DOUBLE', '_REAL', '_INTEGER' / - - data spreads/ AST__SINC, AST__NEAREST, AST__LINEAR, - : AST__SINCSINC, AST__SINCCOS, AST__SINCGAUSS / - - - if( status .ne. sai__ok ) return - -* Get the scalar properties of the test. - call testfun( 0, name, types(1), - : lbnd_in, ubnd_in, ipin, ipin_var, - : lbnd_out, ubnd_out, ipout, ipout_var, - : lbnd, ubnd, m, params, tol, j, status ) - -* Get the number of input and output axes. - nin = ast_geti( m, 'Nin', status ) - nout = ast_geti( m, 'Nout', status ) - -* Get no. of pixels in entire input array. - nel_in = 1 - do i = 1, nin - nel_in = nel_in*( ubnd_in( i ) - lbnd_in( i ) + 1 ) - end do - -* Get no. of pixels in entire output array. - nel_out = 1 - do i = 1, nout - nel_out = nel_out*( ubnd_out( i ) - lbnd_out( i ) + 1 ) - end do - -* Loop round all data types. - do i = 1, 3 - -* Allocate memory for input and output data and variance arrays - call psx_calloc( nel_in, types(i), ipin, status ) - call psx_calloc( nel_in, types(i), ipin_var, status ) - - call psx_calloc( nel_out, types(i), ipout, status ) - call psx_calloc( nel_out, types(i), ipout_var, status ) - -* Loop round all spread functions - do j = 1, 6 - -* Get the scalar properties of the test. This may change the Mapping. - call testfun( 0, name, types(i), - : lbnd_in, ubnd_in, ipin, ipin_var, - : lbnd_out, ubnd_out, ipout, ipout_var, - : lbnd, ubnd, m, params, tol, spreads(j), status ) - -* Fill the input data and variance arrays using the supplied function. - call testfun( 1, name, types(i), - : lbnd_in, ubnd_in, ipin, ipin_var, - : lbnd_out, ubnd_out, ipout, ipout_var, - : lbnd, ubnd, m, params, tol, spreads(j), - : status ) - -* Rebin the input data using the AST function appropriate to the -* supplied data type. - if( types(i) .eq. '_REAL' ) then - call ast_rebinr( m, 0.0D0, nin, lbnd_in, ubnd_in, - : %val( cnf_pval( ipin )), %val( cnf_pval(ipin_var )), - : spreads(j), params, - : AST__USEBAD+AST__USEVAR, tol, 100, VAL__BADR, - : nout, lbnd_out, ubnd_out, - : lbnd, ubnd, %val( cnf_pval( ipout )), - : %val( cnf_pval( ipout_var )), status ) - - else if( types(i) .eq. '_DOUBLE' ) then - call ast_rebind( m, 0.0D0, nin, lbnd_in, ubnd_in, - : %val( cnf_pval( ipin )), %val( cnf_pval(ipin_var )), - : spreads(j), params, - : AST__USEBAD+AST__USEVAR, tol, 100, VAL__BADD, - : nout, lbnd_out, ubnd_out, - : lbnd, ubnd, %val( cnf_pval( ipout ) ), - : %val( cnf_pval( ipout_var )), status ) - - else if( types(i) .eq. '_INTEGER' ) then - call ast_rebini( m, 0.0D0, nin, lbnd_in, ubnd_in, - : %val( cnf_pval( ipin )), %val( cnf_pval(ipin_var )), - : spreads(j), params, - : AST__USEBAD+AST__USEVAR, tol, 100, VAL__BADI, - : nout, lbnd_out, ubnd_out, - : lbnd, ubnd, %val( cnf_pval( ipout )), - : %val( cnf_pval( ipout_var )), status ) - - else if( status .eq. sai__ok ) then - status = SAI__ERROR - call msg_setc( 'T', types(i) ) - call err_rep( ' ', 'Bad data type (^T) supplied to '// - : 'rebin', status ) - end if - -* Call the supplied function to test the results. - call testfun( 2, name, types(i), - : lbnd_in, ubnd_in, ipin, ipin_var, - : lbnd_out, ubnd_out, ipout, ipout_var, - : lbnd, ubnd, m, params, tol, - : spreads(j), status ) - -* Report the data type and spread function if an error occurred, and -* abort. - if( status .ne. sai__ok ) then - call msg_seti( 'sf', j ) - call msg_setc( 'dt', types( i ) ) - call msg_setc( 't', name ) - call err_rep( ' ', '^t failed: Spread function ^sf '// - : 'data type ^dt', status ) - go to 999 - end if - - end do - -* Free resources. - call psx_free( ipout, status ) - call psx_free( ipout_var, status ) - call psx_free( ipin, status ) - call psx_free( ipin_var, status ) - end do - - 999 continue - - end - - LOGICAL FUNCTION EQUALB( A, B ) - IMPLICIT NONE - BYTE A, B - EQUALB = ( A .EQ. B ) - END - - LOGICAL FUNCTION EQUALD( A, B ) - IMPLICIT NONE - INCLUDE 'PRM_PAR' - DOUBLE PRECISION A, B - IF( A .NE. 0.0D0 .AND. B .NE. 0.0D0 ) THEN - EQUALD = ( ABS( A - B ) .LE. 1.0E9*ABS( A + B )*VAL__EPSD ) - ELSE - EQUALD = ( ABS( A + B ) .LE. 1.0D-11 ) - END IF - - END - - LOGICAL FUNCTION MYEQUALD( A, B ) - IMPLICIT NONE - DOUBLE PRECISION A, B - LOGICAL EQUALD - MYEQUALD = EQUALD( A, B ) - END - - LOGICAL FUNCTION EQUALI( A, B ) - IMPLICIT NONE - INTEGER A, B - EQUALI = ( A .EQ. B ) - - END - - LOGICAL FUNCTION EQUALR( A, B ) - IMPLICIT NONE - INCLUDE 'PRM_PAR' - REAL A, B - - IF( A .NE. 0.0 .AND. B .NE. 0.0 ) THEN - EQUALR = ( ABS( A - B ) .LE. 50.0*ABS( A + B )*VAL__EPSR ) - ELSE - EQUALR = ( ABS( A + B ) .LE. 1.0E-11 ) - END IF - - END - - LOGICAL FUNCTION EQUALW( A, B ) - IMPLICIT NONE - INTEGER*2 A, B - EQUALW = ( A .EQ. B ) - END - - - - -* ----------------------------------------------- -* Test 7 -* - - SUBROUTINE TEST7( DO, NAME, TYPE, - : LBND_IN, UBND_IN, IPIN, IPIN_VAR, - : LBND_OUT, UBND_OUT, IPOUT, IPOUT_VAR, - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - - INTEGER M, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), IPIN, IPIN_VAR, IPOUT, IPOUT_VAR, - : STATUS, DO, J - DOUBLE PRECISION TOL, PARAMS(*) - CHARACTER TYPE*(*), NAME*(*) - - IF( STATUS .NE. SAI__OK ) RETURN - - NAME = 'TEST7' - -* Fill the input data and variance arrays if required. - IF( TYPE .EQ. '_REAL' ) THEN - CALL TEST7R( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_DOUBLE' ) THEN - CALL TEST7D( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_INTEGER' ) THEN - CALL TEST7I( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( STATUS .EQ. SAI__OK ) then - STATUS = SAI__ERROR - CALL MSG_SETC( 'T', TYPE ) - CALL ERR_REP( ' ', 'Bad data type (^T) supplied to TEST7', - : STATUS ) - END IF - - END - - - - - SUBROUTINE TEST7D( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, NZ - DOUBLE PRECISION IN(*), IN_VAR(*), OUT(*), OUT_VAR(*), SUM, KT - DOUBLE PRECISION TOL, PARAMS(*), K - LOGICAL EQUALD, MYEQUALD, GOOD - - IF( STATUS .NE. SAI__OK ) RETURN - - K = MIN( 1000.0D0, NUM_DTOD( VAL__MAXD )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 10 - UBND_IN( 1 ) = 19 - LBND_OUT( 1 ) = 12 - UBND_OUT( 1 ) = 20 - LBND( 1 ) = 11 - UBND( 1 ) = 17 - M = AST_SHIFTMAP( 1, 1.5D0, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.1 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - DO I = LBND_IN(1), UBND_IN(1) - IN( I - LBND_IN(1) + 1 ) = 0 - IN_VAR( I - LBND_IN(1) + 1 ) = K - END DO - IN( 14 - LBND_IN(1) + 1 ) = K - -* Otherwise check output data and variance arrays look right. - ELSE - - SUM = 0 - DO I = LBND_OUT(1), UBND_OUT(1) - IF( OUT( I - LBND_OUT(1) + 1) .NE. VAL__BADD ) THEN - SUM = SUM + OUT( I - LBND_OUT(1) + 1) - END IF - END DO - - KT = K - - - IF( 'D' .EQ. 'R' .OR. 'D' .EQ. 'D' ) THEN - GOOD = EQUALD( SUM, KT ) - ELSE - GOOD = ( ABS( SUM - KT ) .LT. 3 ) - END IF - - IF( .NOT. GOOD ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', dble( KT ) ) - CALL MSG_SETD( 'S', dble( SUM ) ) - CALL ERR_REP( ' ', 'TEST7D Data sum is ^S should be ^K', - : STATUS ) - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - NZ = 0 - DO I = LBND_OUT(1), UBND_OUT(1) - IF( OUT( I - LBND_OUT(1) + 1) .NE. 0 .AND. - : OUT( I - LBND_OUT(1) + 1) .NE. VAL__BADD ) THEN - IF( NZ .EQ. 0 ) THEN - NZ = NZ + 1 - IF( OUT( I - LBND_OUT(1) + 1) .NE. KT ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'D1', - : DBLE( OUT( I - LBND_OUT(1) + 1))) - CALL MSG_SETD( 'K', dble( KT ) ) - CALL ERR_REP( ' ', 'TEST7D ^I: ^D1 ^K', - : STATUS ) - END IF - ELSE - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'D1', - : DBLE( OUT( I - LBND_OUT(1) + 1))) - CALL ERR_REP( ' ', 'TEST7D ^I: ^D1', - : STATUS ) - END IF - END IF - END DO - - ELSE - DO I = 0, 3 - IF( .NOT. EQUALD( OUT( 15 - I - LBND_OUT(1) + 1 ), - : OUT( 16 + I - LBND_OUT(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I1', 15 - I ) - CALL MSG_SETI( 'I2', 16 + I ) - CALL MSG_SETD( 'D1', - : DBLE( OUT( 15 - I - LBND_OUT(1) + 1))) - CALL MSG_SETD( 'D2', - : DBLE( OUT( 16 + I - LBND_OUT(1) + 1))) - CALL ERR_REP( ' ', 'TEST7D ^I1 (^D1) != '// - : '^I2 (^D2)', STATUS ) - END IF - END DO - END IF - - END IF - - END - - - SUBROUTINE TEST7I( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, NZ - INTEGER IN(*), IN_VAR(*), OUT(*), OUT_VAR(*), SUM, KT - DOUBLE PRECISION TOL, PARAMS(*), K - LOGICAL EQUALI, MYEQUALD, GOOD - - IF( STATUS .NE. SAI__OK ) RETURN - - K = MIN( 1000.0D0, NUM_ITOD( VAL__MAXI )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 10 - UBND_IN( 1 ) = 19 - LBND_OUT( 1 ) = 12 - UBND_OUT( 1 ) = 20 - LBND( 1 ) = 11 - UBND( 1 ) = 17 - M = AST_SHIFTMAP( 1, 1.5D0, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.1 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - DO I = LBND_IN(1), UBND_IN(1) - IN( I - LBND_IN(1) + 1 ) = 0 - IN_VAR( I - LBND_IN(1) + 1 ) = K - END DO - IN( 14 - LBND_IN(1) + 1 ) = K - -* Otherwise check output data and variance arrays look right. - ELSE - - SUM = 0 - DO I = LBND_OUT(1), UBND_OUT(1) - IF( OUT( I - LBND_OUT(1) + 1) .NE. VAL__BADI ) THEN - SUM = SUM + OUT( I - LBND_OUT(1) + 1) - END IF - END DO - - KT = K - - - IF( 'I' .EQ. 'R' .OR. 'I' .EQ. 'D' ) THEN - GOOD = EQUALI( SUM, KT ) - ELSE - GOOD = ( ABS( SUM - KT ) .LT. 3 ) - END IF - - IF( .NOT. GOOD ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', dble( KT ) ) - CALL MSG_SETD( 'S', dble( SUM ) ) - CALL ERR_REP( ' ', 'TEST7I Data sum is ^S should be ^K', - : STATUS ) - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - NZ = 0 - DO I = LBND_OUT(1), UBND_OUT(1) - IF( OUT( I - LBND_OUT(1) + 1) .NE. 0 .AND. - : OUT( I - LBND_OUT(1) + 1) .NE. VAL__BADI ) THEN - IF( NZ .EQ. 0 ) THEN - NZ = NZ + 1 - IF( OUT( I - LBND_OUT(1) + 1) .NE. KT ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'D1', - : DBLE( OUT( I - LBND_OUT(1) + 1))) - CALL MSG_SETD( 'K', dble( KT ) ) - CALL ERR_REP( ' ', 'TEST7I ^I: ^D1 ^K', - : STATUS ) - END IF - ELSE - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'D1', - : DBLE( OUT( I - LBND_OUT(1) + 1))) - CALL ERR_REP( ' ', 'TEST7I ^I: ^D1', - : STATUS ) - END IF - END IF - END DO - - ELSE - DO I = 0, 3 - IF( .NOT. EQUALI( OUT( 15 - I - LBND_OUT(1) + 1 ), - : OUT( 16 + I - LBND_OUT(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I1', 15 - I ) - CALL MSG_SETI( 'I2', 16 + I ) - CALL MSG_SETD( 'D1', - : DBLE( OUT( 15 - I - LBND_OUT(1) + 1))) - CALL MSG_SETD( 'D2', - : DBLE( OUT( 16 + I - LBND_OUT(1) + 1))) - CALL ERR_REP( ' ', 'TEST7I ^I1 (^D1) != '// - : '^I2 (^D2)', STATUS ) - END IF - END DO - END IF - - END IF - - END - - - SUBROUTINE TEST7R( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, NZ - REAL IN(*), IN_VAR(*), OUT(*), OUT_VAR(*), SUM, KT - DOUBLE PRECISION TOL, PARAMS(*), K - LOGICAL EQUALR, MYEQUALD, GOOD - - IF( STATUS .NE. SAI__OK ) RETURN - - K = MIN( 1000.0D0, NUM_RTOD( VAL__MAXR )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 10 - UBND_IN( 1 ) = 19 - LBND_OUT( 1 ) = 12 - UBND_OUT( 1 ) = 20 - LBND( 1 ) = 11 - UBND( 1 ) = 17 - M = AST_SHIFTMAP( 1, 1.5D0, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.1 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - DO I = LBND_IN(1), UBND_IN(1) - IN( I - LBND_IN(1) + 1 ) = 0 - IN_VAR( I - LBND_IN(1) + 1 ) = K - END DO - IN( 14 - LBND_IN(1) + 1 ) = K - -* Otherwise check output data and variance arrays look right. - ELSE - - SUM = 0 - DO I = LBND_OUT(1), UBND_OUT(1) - IF( OUT( I - LBND_OUT(1) + 1) .NE. VAL__BADR ) THEN - SUM = SUM + OUT( I - LBND_OUT(1) + 1) - END IF - END DO - - KT = K - - - IF( 'R' .EQ. 'R' .OR. 'R' .EQ. 'D' ) THEN - GOOD = EQUALR( SUM, KT ) - ELSE - GOOD = ( ABS( SUM - KT ) .LT. 3 ) - END IF - - IF( .NOT. GOOD ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', dble( KT ) ) - CALL MSG_SETD( 'S', dble( SUM ) ) - CALL ERR_REP( ' ', 'TEST7R Data sum is ^S should be ^K', - : STATUS ) - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - NZ = 0 - DO I = LBND_OUT(1), UBND_OUT(1) - IF( OUT( I - LBND_OUT(1) + 1) .NE. 0 .AND. - : OUT( I - LBND_OUT(1) + 1) .NE. VAL__BADR ) THEN - IF( NZ .EQ. 0 ) THEN - NZ = NZ + 1 - IF( OUT( I - LBND_OUT(1) + 1) .NE. KT ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'D1', - : DBLE( OUT( I - LBND_OUT(1) + 1))) - CALL MSG_SETD( 'K', dble( KT ) ) - CALL ERR_REP( ' ', 'TEST7R ^I: ^D1 ^K', - : STATUS ) - END IF - ELSE - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'D1', - : DBLE( OUT( I - LBND_OUT(1) + 1))) - CALL ERR_REP( ' ', 'TEST7R ^I: ^D1', - : STATUS ) - END IF - END IF - END DO - - ELSE - DO I = 0, 3 - IF( .NOT. EQUALR( OUT( 15 - I - LBND_OUT(1) + 1 ), - : OUT( 16 + I - LBND_OUT(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I1', 15 - I ) - CALL MSG_SETI( 'I2', 16 + I ) - CALL MSG_SETD( 'D1', - : DBLE( OUT( 15 - I - LBND_OUT(1) + 1))) - CALL MSG_SETD( 'D2', - : DBLE( OUT( 16 + I - LBND_OUT(1) + 1))) - CALL ERR_REP( ' ', 'TEST7R ^I1 (^D1) != '// - : '^I2 (^D2)', STATUS ) - END IF - END DO - END IF - - END IF - - END - - - - -* ----------------------------------------------- -* Test 8 -* - - SUBROUTINE TEST8( DO, NAME, TYPE, - : LBND_IN, UBND_IN, IPIN, IPIN_VAR, - : LBND_OUT, UBND_OUT, IPOUT, IPOUT_VAR, - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - - INTEGER M, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), IPIN, IPIN_VAR, IPOUT, IPOUT_VAR, - : STATUS, DO, J - DOUBLE PRECISION TOL, PARAMS(*) - CHARACTER TYPE*(*), NAME*(*) - - IF( STATUS .NE. SAI__OK ) RETURN - - NAME = 'TEST8' - -* Fill the input data and variance arrays if required. - IF( TYPE .EQ. '_REAL' ) THEN - CALL TEST8R( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_DOUBLE' ) THEN - CALL TEST8D( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_INTEGER' ) THEN - CALL TEST8I( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( STATUS .EQ. SAI__OK ) then - STATUS = SAI__ERROR - CALL MSG_SETC( 'T', TYPE ) - CALL ERR_REP( ' ', 'Bad data type (^T) supplied to TEST8', - : STATUS ) - END IF - - END - - - - - SUBROUTINE TEST8D( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, NZ, - : II, JJ, KK - DOUBLE PRECISION IN(*), IN_VAR(*), OUT(*), OUT_VAR(*), SUM, KT - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(2) - LOGICAL EQUALD, GOOD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 10000.0D0, NUM_DTOD( VAL__MAXD )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -2 - UBND_IN( 1 ) = 3 - LBND_OUT( 1 ) = -2 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -2 - UBND( 1 ) = 3 - LBND_IN( 2 ) = 0 - UBND_IN( 2 ) = 5 - LBND_OUT( 2 ) = 0 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 0 - UBND( 2 ) = 5 - SHIFTS(1) = 0.5D0 - SHIFTS(2) = -0.5D0 - M = AST_SHIFTMAP( 2, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = 0 - IN_VAR( K ) = KFAC - K = K + 1 - END DO - END DO - IN( 21 ) = KFAC - -* Otherwise check output data and variance arrays look right. - ELSE - K = 0 - SUM = 0 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( OUT( K ) .NE. VAL__BADD ) THEN - SUM = SUM + OUT( K ) - END IF - END DO - END DO - - KT = KFAC - - IF( 'D' .EQ. 'R' .OR. 'D' .EQ. 'D' ) THEN - GOOD = EQUALD( SUM, KT ) - ELSE - GOOD = ( ABS( SUM - KT ) .LT. 5 ) - END IF - - IF( .NOT. GOOD ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', dble( KT ) ) - CALL MSG_SETD( 'S', dble( SUM ) ) - CALL ERR_REP( ' ', 'TEST8D Data sum is ^S should be ^K', - : STATUS ) - GO TO 999 - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - NZ = 0 - K = 0 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( OUT( K ) .NE. 0 .AND. - : OUT( K ) .NE. VAL__BADD ) THEN - IF( NZ .EQ. 0 ) THEN - NZ = NZ + 1 - IF( OUT( K ) .NE. KT ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'D1', DBLE( OUT( K ))) - CALL MSG_SETD( 'KT', DBLE( KT ) ) - CALL ERR_REP( ' ', 'TEST8D ^K: ^D1 ^KT', - : STATUS ) - GO TO 999 - END IF - ELSE - STATUS = SAI__ERROR - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'D1', DBLE( OUT( K ))) - CALL ERR_REP( ' ', 'TEST8D ^K: ^D1', - : STATUS ) - GO TO 999 - END IF - END IF - END DO - END DO - ELSE - K = 0 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - II = 1 - I - JJ = 5 - J - IF( II .GE. LBND_OUT(1) .AND. - : II .LE. UBND_OUT(1) .AND. - : JJ .GE. LBND_OUT(2) .AND. - : JJ .LE. UBND_OUT(2) ) THEN - KK = 6*JJ + ( II + 3 ) - - IF( .NOT. EQUALD( OUT( KK ), OUT( K ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'KK', KK ) - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'D1', DBLE( OUT(KK) ) ) - CALL MSG_SETD( 'D2', DBLE( OUT(K) ) ) - CALL ERR_REP( ' ', 'TEST8D ^KK (^D1) != '// - : '^K (^D2)', STATUS ) - GO TO 999 - END IF - END IF - END DO - END DO - END IF - - END IF - - 999 CONTINUE - - END - - - - SUBROUTINE TEST8I( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, NZ, - : II, JJ, KK - INTEGER IN(*), IN_VAR(*), OUT(*), OUT_VAR(*), SUM, KT - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(2) - LOGICAL EQUALI, GOOD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 10000.0D0, NUM_ITOD( VAL__MAXI )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -2 - UBND_IN( 1 ) = 3 - LBND_OUT( 1 ) = -2 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -2 - UBND( 1 ) = 3 - LBND_IN( 2 ) = 0 - UBND_IN( 2 ) = 5 - LBND_OUT( 2 ) = 0 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 0 - UBND( 2 ) = 5 - SHIFTS(1) = 0.5D0 - SHIFTS(2) = -0.5D0 - M = AST_SHIFTMAP( 2, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = 0 - IN_VAR( K ) = KFAC - K = K + 1 - END DO - END DO - IN( 21 ) = KFAC - -* Otherwise check output data and variance arrays look right. - ELSE - K = 0 - SUM = 0 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( OUT( K ) .NE. VAL__BADI ) THEN - SUM = SUM + OUT( K ) - END IF - END DO - END DO - - KT = KFAC - - IF( 'I' .EQ. 'R' .OR. 'I' .EQ. 'D' ) THEN - GOOD = EQUALI( SUM, KT ) - ELSE - GOOD = ( ABS( SUM - KT ) .LT. 5 ) - END IF - - IF( .NOT. GOOD ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', dble( KT ) ) - CALL MSG_SETD( 'S', dble( SUM ) ) - CALL ERR_REP( ' ', 'TEST8I Data sum is ^S should be ^K', - : STATUS ) - GO TO 999 - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - NZ = 0 - K = 0 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( OUT( K ) .NE. 0 .AND. - : OUT( K ) .NE. VAL__BADI ) THEN - IF( NZ .EQ. 0 ) THEN - NZ = NZ + 1 - IF( OUT( K ) .NE. KT ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'D1', DBLE( OUT( K ))) - CALL MSG_SETD( 'KT', DBLE( KT ) ) - CALL ERR_REP( ' ', 'TEST8I ^K: ^D1 ^KT', - : STATUS ) - GO TO 999 - END IF - ELSE - STATUS = SAI__ERROR - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'D1', DBLE( OUT( K ))) - CALL ERR_REP( ' ', 'TEST8I ^K: ^D1', - : STATUS ) - GO TO 999 - END IF - END IF - END DO - END DO - ELSE - K = 0 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - II = 1 - I - JJ = 5 - J - IF( II .GE. LBND_OUT(1) .AND. - : II .LE. UBND_OUT(1) .AND. - : JJ .GE. LBND_OUT(2) .AND. - : JJ .LE. UBND_OUT(2) ) THEN - KK = 6*JJ + ( II + 3 ) - - IF( .NOT. EQUALI( OUT( KK ), OUT( K ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'KK', KK ) - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'D1', DBLE( OUT(KK) ) ) - CALL MSG_SETD( 'D2', DBLE( OUT(K) ) ) - CALL ERR_REP( ' ', 'TEST8I ^KK (^D1) != '// - : '^K (^D2)', STATUS ) - GO TO 999 - END IF - END IF - END DO - END DO - END IF - - END IF - - 999 CONTINUE - - END - - - - SUBROUTINE TEST8R( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, NZ, - : II, JJ, KK - REAL IN(*), IN_VAR(*), OUT(*), OUT_VAR(*), SUM, KT - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(2) - LOGICAL EQUALR, GOOD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 10000.0D0, NUM_RTOD( VAL__MAXR )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -2 - UBND_IN( 1 ) = 3 - LBND_OUT( 1 ) = -2 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -2 - UBND( 1 ) = 3 - LBND_IN( 2 ) = 0 - UBND_IN( 2 ) = 5 - LBND_OUT( 2 ) = 0 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 0 - UBND( 2 ) = 5 - SHIFTS(1) = 0.5D0 - SHIFTS(2) = -0.5D0 - M = AST_SHIFTMAP( 2, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = 0 - IN_VAR( K ) = KFAC - K = K + 1 - END DO - END DO - IN( 21 ) = KFAC - -* Otherwise check output data and variance arrays look right. - ELSE - K = 0 - SUM = 0 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( OUT( K ) .NE. VAL__BADR ) THEN - SUM = SUM + OUT( K ) - END IF - END DO - END DO - - KT = KFAC - - IF( 'R' .EQ. 'R' .OR. 'R' .EQ. 'D' ) THEN - GOOD = EQUALR( SUM, KT ) - ELSE - GOOD = ( ABS( SUM - KT ) .LT. 5 ) - END IF - - IF( .NOT. GOOD ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', dble( KT ) ) - CALL MSG_SETD( 'S', dble( SUM ) ) - CALL ERR_REP( ' ', 'TEST8R Data sum is ^S should be ^K', - : STATUS ) - GO TO 999 - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - NZ = 0 - K = 0 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( OUT( K ) .NE. 0 .AND. - : OUT( K ) .NE. VAL__BADR ) THEN - IF( NZ .EQ. 0 ) THEN - NZ = NZ + 1 - IF( OUT( K ) .NE. KT ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'D1', DBLE( OUT( K ))) - CALL MSG_SETD( 'KT', DBLE( KT ) ) - CALL ERR_REP( ' ', 'TEST8R ^K: ^D1 ^KT', - : STATUS ) - GO TO 999 - END IF - ELSE - STATUS = SAI__ERROR - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'D1', DBLE( OUT( K ))) - CALL ERR_REP( ' ', 'TEST8R ^K: ^D1', - : STATUS ) - GO TO 999 - END IF - END IF - END DO - END DO - ELSE - K = 0 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - II = 1 - I - JJ = 5 - J - IF( II .GE. LBND_OUT(1) .AND. - : II .LE. UBND_OUT(1) .AND. - : JJ .GE. LBND_OUT(2) .AND. - : JJ .LE. UBND_OUT(2) ) THEN - KK = 6*JJ + ( II + 3 ) - - IF( .NOT. EQUALR( OUT( KK ), OUT( K ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'KK', KK ) - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'D1', DBLE( OUT(KK) ) ) - CALL MSG_SETD( 'D2', DBLE( OUT(K) ) ) - CALL ERR_REP( ' ', 'TEST8R ^KK (^D1) != '// - : '^K (^D2)', STATUS ) - GO TO 999 - END IF - END IF - END DO - END DO - END IF - - END IF - - 999 CONTINUE - - END - - - - - -* ----------------------------------------------- -* Test 9 -* - - SUBROUTINE TEST9( DO, NAME, TYPE, - : LBND_IN, UBND_IN, IPIN, IPIN_VAR, - : LBND_OUT, UBND_OUT, IPOUT, IPOUT_VAR, - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - - INTEGER M, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), IPIN, IPIN_VAR, IPOUT, IPOUT_VAR, - : STATUS, DO, J - DOUBLE PRECISION TOL, PARAMS(*) - CHARACTER TYPE*(*), NAME*(*) - - IF( STATUS .NE. SAI__OK ) RETURN - - NAME = 'TEST9' - -* Fill the input data and variance arrays if required. - IF( TYPE .EQ. '_REAL' ) THEN - CALL TEST9R( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_DOUBLE' ) THEN - CALL TEST9D( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_INTEGER' ) THEN - CALL TEST9I( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( STATUS .EQ. SAI__OK ) then - STATUS = SAI__ERROR - CALL MSG_SETC( 'T', TYPE ) - CALL ERR_REP( ' ', 'Bad data type (^T) supplied to TEST9', - : STATUS ) - END IF - - END - - - - - SUBROUTINE TEST9D( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, L, K2 - DOUBLE PRECISION IN(*), IN_VAR(*), OUT(*), OUT_VAR(*), KT, SUM - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(3), G(3), W - LOGICAL EQUALD, GOOD, MYEQUALD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 10000.0D0, NUM_DTOD( VAL__MAXD )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 0 - UBND_IN( 1 ) = 6 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 6 - LBND( 1 ) = 0 - UBND( 1 ) = 6 - LBND_IN( 2 ) = 0 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 0 - UBND_OUT( 2 ) = 6 - LBND( 2 ) = 0 - UBND( 2 ) = 6 - LBND_IN( 3 ) = 0 - UBND_IN( 3 ) = 6 - LBND_OUT( 3 ) = 0 - UBND_OUT( 3 ) = 6 - LBND( 3 ) = 0 - UBND( 3 ) = 6 - - IF( SPREAD .EQ. AST__NEAREST ) THEN - SHIFTS(1) = 1.7D0 - SHIFTS(2) = 2.1D0 - SHIFTS(3) = -1.2D0 - ELSE - SHIFTS(1) = 0.5D0 - SHIFTS(2) = 0.0D0 - SHIFTS(3) = -0.5D0 - END IF - - M = AST_SHIFTMAP( 3, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO L = LBND_IN(3), UBND_IN(3) - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = 0 - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - END DO - IN( 172 ) = KFAC - -* Otherwise check output data and variance arrays look right. - ELSE - K = 0 - SUM = 0 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( OUT( K ) .NE. VAL__BADD ) THEN - SUM = SUM + OUT( K ) - END IF - END DO - END DO - END DO - - KT = KFAC - - IF( 'D' .EQ. 'R' .OR. 'D' .EQ. 'D' ) THEN - GOOD = EQUALD( SUM, KT ) - ELSE - GOOD = ( ABS( SUM - KT ) .LT. 5 ) - END IF - - IF( .NOT. GOOD ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', dble( KT ) ) - CALL MSG_SETD( 'S', dble( SUM ) ) - CALL ERR_REP( ' ', 'TEST9D Data sum is ^S should be ^K', - : STATUS ) - GO TO 999 - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - K = 0 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( K .EQ. 139 ) THEN - IF( .NOT. EQUALD( OUT(K), KT ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', DBLE( KT ) ) - CALL MSG_SETD( 'O', DBLE( OUT(K) ) ) - CALL ERR_REP( ' ', 'TEST9D El. 139 is '// - : '^O should be ^K', STATUS ) - GO TO 999 - END IF - ELSE - IF( .NOT. EQUALD( OUT(K), 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'O', DBLE( OUT(K) ) ) - CALL ERR_REP( ' ', 'TEST9D El. ^K is '// - : '^O should be zero', STATUS ) - GO TO 999 - END IF - END IF - END DO - END DO - END DO - ELSE - - G(1) = 0.0 - G(2) = 0.0 - G(3) = 0.0 - W = 0.0 - K = 0 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - G(1) = G(1) + DBLE( I*OUT( k ) ) - G(2) = G(2) + DBLE( J*OUT( K ) ) - G(3) = G(3) + DBLE( L*OUT( K ) ) - W = W + DBLE( OUT( K ) ) - END DO - END DO - END DO - - IF( .NOT. MYEQUALD( G(1)/W, 3.5D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'A', G(1)/W ) - CALL ERR_REP( ' ', 'TEST9D Mean X is ^A '// - : ' should be 3.5', STATUS ) - GO TO 999 - ELSE IF( .NOT. MYEQUALD( G(2)/W, 3.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'A', G(2)/W ) - CALL ERR_REP( ' ', 'TEST9D Mean Y is ^A '// - : ' should be 3.0', STATUS ) - GO TO 999 - ELSE IF( .NOT. MYEQUALD( G(3)/W, 2.5D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'A', G(3)/W ) - CALL ERR_REP( ' ', 'TEST9D Mean Z is ^A '// - : ' should be 2.5', STATUS ) - GO TO 999 - END IF - - END IF - END IF - - 999 CONTINUE - - END - - - - SUBROUTINE TEST9I( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, L, K2 - INTEGER IN(*), IN_VAR(*), OUT(*), OUT_VAR(*), KT, SUM - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(3), G(3), W - LOGICAL EQUALI, GOOD, MYEQUALD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 10000.0D0, NUM_ITOD( VAL__MAXI )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 0 - UBND_IN( 1 ) = 6 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 6 - LBND( 1 ) = 0 - UBND( 1 ) = 6 - LBND_IN( 2 ) = 0 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 0 - UBND_OUT( 2 ) = 6 - LBND( 2 ) = 0 - UBND( 2 ) = 6 - LBND_IN( 3 ) = 0 - UBND_IN( 3 ) = 6 - LBND_OUT( 3 ) = 0 - UBND_OUT( 3 ) = 6 - LBND( 3 ) = 0 - UBND( 3 ) = 6 - - IF( SPREAD .EQ. AST__NEAREST ) THEN - SHIFTS(1) = 1.7D0 - SHIFTS(2) = 2.1D0 - SHIFTS(3) = -1.2D0 - ELSE - SHIFTS(1) = 0.5D0 - SHIFTS(2) = 0.0D0 - SHIFTS(3) = -0.5D0 - END IF - - M = AST_SHIFTMAP( 3, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO L = LBND_IN(3), UBND_IN(3) - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = 0 - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - END DO - IN( 172 ) = KFAC - -* Otherwise check output data and variance arrays look right. - ELSE - K = 0 - SUM = 0 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( OUT( K ) .NE. VAL__BADI ) THEN - SUM = SUM + OUT( K ) - END IF - END DO - END DO - END DO - - KT = KFAC - - IF( 'I' .EQ. 'R' .OR. 'I' .EQ. 'D' ) THEN - GOOD = EQUALI( SUM, KT ) - ELSE - GOOD = ( ABS( SUM - KT ) .LT. 5 ) - END IF - - IF( .NOT. GOOD ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', dble( KT ) ) - CALL MSG_SETD( 'S', dble( SUM ) ) - CALL ERR_REP( ' ', 'TEST9I Data sum is ^S should be ^K', - : STATUS ) - GO TO 999 - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - K = 0 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( K .EQ. 139 ) THEN - IF( .NOT. EQUALI( OUT(K), KT ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', DBLE( KT ) ) - CALL MSG_SETD( 'O', DBLE( OUT(K) ) ) - CALL ERR_REP( ' ', 'TEST9I El. 139 is '// - : '^O should be ^K', STATUS ) - GO TO 999 - END IF - ELSE - IF( .NOT. EQUALI( OUT(K), 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'O', DBLE( OUT(K) ) ) - CALL ERR_REP( ' ', 'TEST9I El. ^K is '// - : '^O should be zero', STATUS ) - GO TO 999 - END IF - END IF - END DO - END DO - END DO - ELSE - - G(1) = 0.0 - G(2) = 0.0 - G(3) = 0.0 - W = 0.0 - K = 0 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - G(1) = G(1) + DBLE( I*OUT( k ) ) - G(2) = G(2) + DBLE( J*OUT( K ) ) - G(3) = G(3) + DBLE( L*OUT( K ) ) - W = W + DBLE( OUT( K ) ) - END DO - END DO - END DO - - IF( .NOT. MYEQUALD( G(1)/W, 3.5D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'A', G(1)/W ) - CALL ERR_REP( ' ', 'TEST9I Mean X is ^A '// - : ' should be 3.5', STATUS ) - GO TO 999 - ELSE IF( .NOT. MYEQUALD( G(2)/W, 3.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'A', G(2)/W ) - CALL ERR_REP( ' ', 'TEST9I Mean Y is ^A '// - : ' should be 3.0', STATUS ) - GO TO 999 - ELSE IF( .NOT. MYEQUALD( G(3)/W, 2.5D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'A', G(3)/W ) - CALL ERR_REP( ' ', 'TEST9I Mean Z is ^A '// - : ' should be 2.5', STATUS ) - GO TO 999 - END IF - - END IF - END IF - - 999 CONTINUE - - END - - - - SUBROUTINE TEST9R( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, L, K2 - REAL IN(*), IN_VAR(*), OUT(*), OUT_VAR(*), KT, SUM - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(3), G(3), W - LOGICAL EQUALR, GOOD, MYEQUALD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 10000.0D0, NUM_RTOD( VAL__MAXR )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 0 - UBND_IN( 1 ) = 6 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 6 - LBND( 1 ) = 0 - UBND( 1 ) = 6 - LBND_IN( 2 ) = 0 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 0 - UBND_OUT( 2 ) = 6 - LBND( 2 ) = 0 - UBND( 2 ) = 6 - LBND_IN( 3 ) = 0 - UBND_IN( 3 ) = 6 - LBND_OUT( 3 ) = 0 - UBND_OUT( 3 ) = 6 - LBND( 3 ) = 0 - UBND( 3 ) = 6 - - IF( SPREAD .EQ. AST__NEAREST ) THEN - SHIFTS(1) = 1.7D0 - SHIFTS(2) = 2.1D0 - SHIFTS(3) = -1.2D0 - ELSE - SHIFTS(1) = 0.5D0 - SHIFTS(2) = 0.0D0 - SHIFTS(3) = -0.5D0 - END IF - - M = AST_SHIFTMAP( 3, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO L = LBND_IN(3), UBND_IN(3) - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = 0 - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - END DO - IN( 172 ) = KFAC - -* Otherwise check output data and variance arrays look right. - ELSE - K = 0 - SUM = 0 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( OUT( K ) .NE. VAL__BADR ) THEN - SUM = SUM + OUT( K ) - END IF - END DO - END DO - END DO - - KT = KFAC - - IF( 'R' .EQ. 'R' .OR. 'R' .EQ. 'D' ) THEN - GOOD = EQUALR( SUM, KT ) - ELSE - GOOD = ( ABS( SUM - KT ) .LT. 5 ) - END IF - - IF( .NOT. GOOD ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', dble( KT ) ) - CALL MSG_SETD( 'S', dble( SUM ) ) - CALL ERR_REP( ' ', 'TEST9R Data sum is ^S should be ^K', - : STATUS ) - GO TO 999 - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - K = 0 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - IF( K .EQ. 139 ) THEN - IF( .NOT. EQUALR( OUT(K), KT ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'K', DBLE( KT ) ) - CALL MSG_SETD( 'O', DBLE( OUT(K) ) ) - CALL ERR_REP( ' ', 'TEST9R El. 139 is '// - : '^O should be ^K', STATUS ) - GO TO 999 - END IF - ELSE - IF( .NOT. EQUALR( OUT(K), 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'K', K ) - CALL MSG_SETD( 'O', DBLE( OUT(K) ) ) - CALL ERR_REP( ' ', 'TEST9R El. ^K is '// - : '^O should be zero', STATUS ) - GO TO 999 - END IF - END IF - END DO - END DO - END DO - ELSE - - G(1) = 0.0 - G(2) = 0.0 - G(3) = 0.0 - W = 0.0 - K = 0 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - K = K + 1 - G(1) = G(1) + DBLE( I*OUT( k ) ) - G(2) = G(2) + DBLE( J*OUT( K ) ) - G(3) = G(3) + DBLE( L*OUT( K ) ) - W = W + DBLE( OUT( K ) ) - END DO - END DO - END DO - - IF( .NOT. MYEQUALD( G(1)/W, 3.5D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'A', G(1)/W ) - CALL ERR_REP( ' ', 'TEST9R Mean X is ^A '// - : ' should be 3.5', STATUS ) - GO TO 999 - ELSE IF( .NOT. MYEQUALD( G(2)/W, 3.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'A', G(2)/W ) - CALL ERR_REP( ' ', 'TEST9R Mean Y is ^A '// - : ' should be 3.0', STATUS ) - GO TO 999 - ELSE IF( .NOT. MYEQUALD( G(3)/W, 2.5D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'A', G(3)/W ) - CALL ERR_REP( ' ', 'TEST9R Mean Z is ^A '// - : ' should be 2.5', STATUS ) - GO TO 999 - END IF - - END IF - END IF - - 999 CONTINUE - - END - - - - - -* ----------------------------------------------- -* Test 1 -* - - SUBROUTINE TEST1( DO, NAME, TYPE, - : LBND_IN, UBND_IN, IPIN, IPIN_VAR, - : LBND_OUT, UBND_OUT, IPOUT, IPOUT_VAR, - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - - INTEGER M, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), IPIN, IPIN_VAR, IPOUT, IPOUT_VAR, - : STATUS, DO, J - DOUBLE PRECISION TOL, PARAMS(*) - CHARACTER TYPE*(*), NAME*(*) - - IF( STATUS .NE. SAI__OK ) RETURN - - NAME = 'TEST1' - -* Fill the input data and variance arrays if required. - IF( TYPE .EQ. '_REAL' ) THEN - CALL TEST1R( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_DOUBLE' ) THEN - CALL TEST1D( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_INTEGER' ) THEN - CALL TEST1I( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( STATUS .EQ. SAI__OK ) then - STATUS = SAI__ERROR - CALL MSG_SETC( 'T', TYPE ) - CALL ERR_REP( ' ', 'Bad data type (^T) supplied to TEST1', - : STATUS ) - END IF - - END - - - - - SUBROUTINE TEST1D( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), STATUS, M, I, SPREAD - DOUBLE PRECISION IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - LOGICAL EQUALD, IGNORE - DOUBLE PRECISION TOL, PARAMS(*), K - - IF( STATUS .NE. SAI__OK ) RETURN - - K = MIN( 1000.0D0, NUM_DTOD( VAL__MAXD )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 10 - UBND_IN( 1 ) = 19 - LBND_OUT( 1 ) = 12 - UBND_OUT( 1 ) = 20 - LBND( 1 ) = 11 - UBND( 1 ) = 17 - M = AST_UNITMAP( 1, ' ', STATUS ) - IF( SPREAD .EQ. AST__GAUSS ) THEN - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - ELSE - PARAMS(1) = 2.0 - PARAMS(2) = 0.5 - END IF - TOL = 0.1 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - DO I = LBND_IN(1), UBND_IN(1) - IN( I - LBND_IN(1) + 1 ) = I*K - IN_VAR( I - LBND_IN(1) + 1 ) = I - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - DO I = LBND_OUT(1), UBND(1) - IGNORE = ( SPREAD .EQ. AST__GAUSS .AND. - : ( I .LE. LBND_OUT(1) + 1 .OR. - : I .GE. UBND(1) - 1 ) ) - IF( IGNORE ) THEN - - ELSE IF( .NOT. EQUALD( OUT( I - LBND_OUT(1) + 1 ), - : IN( I - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1 ) ) ) - CALL MSG_SETD( 'B', DBLE( IN( I - LBND_IN(1) + 1 ) ) ) - CALL ERR_REP( ' ', 'TEST1D ^I: data ^V != ^B', STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT_VAR( I - LBND_OUT(1) + 1 ), - : IN_VAR( I - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1) ) ) - CALL MSG_SETD( 'B', DBLE( IN_VAR(I-LBND_IN(1)+1) ) ) - CALL ERR_REP( ' ', 'TEST1D ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END DO - DO I = UBND(1) + 1, UBND_OUT(1) - IF( .NOT. EQUALD( OUT( I - LBND_OUT(1) + 1 ), - : 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1))) - CALL ERR_REP( ' ', 'TEST1D ^I: ^V != 0.0', STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT_VAR( I - LBND_OUT(1) + 1 ), - : 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1))) - CALL ERR_REP( ' ', 'TEST1D ^I: variance ^V != 0.0', - : STATUS ) - RETURN - END IF - END DO - - END IF - - END - - - - SUBROUTINE TEST1I( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), STATUS, M, I, SPREAD - INTEGER IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - LOGICAL EQUALI, IGNORE - DOUBLE PRECISION TOL, PARAMS(*), K - - IF( STATUS .NE. SAI__OK ) RETURN - - K = MIN( 1000.0D0, NUM_ITOD( VAL__MAXI )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 10 - UBND_IN( 1 ) = 19 - LBND_OUT( 1 ) = 12 - UBND_OUT( 1 ) = 20 - LBND( 1 ) = 11 - UBND( 1 ) = 17 - M = AST_UNITMAP( 1, ' ', STATUS ) - IF( SPREAD .EQ. AST__GAUSS ) THEN - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - ELSE - PARAMS(1) = 2.0 - PARAMS(2) = 0.5 - END IF - TOL = 0.1 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - DO I = LBND_IN(1), UBND_IN(1) - IN( I - LBND_IN(1) + 1 ) = I*K - IN_VAR( I - LBND_IN(1) + 1 ) = I - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - DO I = LBND_OUT(1), UBND(1) - IGNORE = ( SPREAD .EQ. AST__GAUSS .AND. - : ( I .LE. LBND_OUT(1) + 1 .OR. - : I .GE. UBND(1) - 1 ) ) - IF( IGNORE ) THEN - - ELSE IF( .NOT. EQUALI( OUT( I - LBND_OUT(1) + 1 ), - : IN( I - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1 ) ) ) - CALL MSG_SETD( 'B', DBLE( IN( I - LBND_IN(1) + 1 ) ) ) - CALL ERR_REP( ' ', 'TEST1I ^I: data ^V != ^B', STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT_VAR( I - LBND_OUT(1) + 1 ), - : IN_VAR( I - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1) ) ) - CALL MSG_SETD( 'B', DBLE( IN_VAR(I-LBND_IN(1)+1) ) ) - CALL ERR_REP( ' ', 'TEST1I ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END DO - DO I = UBND(1) + 1, UBND_OUT(1) - IF( .NOT. EQUALI( OUT( I - LBND_OUT(1) + 1 ), - : 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1))) - CALL ERR_REP( ' ', 'TEST1I ^I: ^V != 0.0', STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT_VAR( I - LBND_OUT(1) + 1 ), - : 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1))) - CALL ERR_REP( ' ', 'TEST1I ^I: variance ^V != 0.0', - : STATUS ) - RETURN - END IF - END DO - - END IF - - END - - - - SUBROUTINE TEST1R( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), STATUS, M, I, SPREAD - REAL IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - LOGICAL EQUALR, IGNORE - DOUBLE PRECISION TOL, PARAMS(*), K - - IF( STATUS .NE. SAI__OK ) RETURN - - K = MIN( 1000.0D0, NUM_RTOD( VAL__MAXR )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 10 - UBND_IN( 1 ) = 19 - LBND_OUT( 1 ) = 12 - UBND_OUT( 1 ) = 20 - LBND( 1 ) = 11 - UBND( 1 ) = 17 - M = AST_UNITMAP( 1, ' ', STATUS ) - IF( SPREAD .EQ. AST__GAUSS ) THEN - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - ELSE - PARAMS(1) = 2.0 - PARAMS(2) = 0.5 - END IF - TOL = 0.1 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - DO I = LBND_IN(1), UBND_IN(1) - IN( I - LBND_IN(1) + 1 ) = I*K - IN_VAR( I - LBND_IN(1) + 1 ) = I - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - DO I = LBND_OUT(1), UBND(1) - IGNORE = ( SPREAD .EQ. AST__GAUSS .AND. - : ( I .LE. LBND_OUT(1) + 1 .OR. - : I .GE. UBND(1) - 1 ) ) - IF( IGNORE ) THEN - - ELSE IF( .NOT. EQUALR( OUT( I - LBND_OUT(1) + 1 ), - : IN( I - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1 ) ) ) - CALL MSG_SETD( 'B', DBLE( IN( I - LBND_IN(1) + 1 ) ) ) - CALL ERR_REP( ' ', 'TEST1R ^I: data ^V != ^B', STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT_VAR( I - LBND_OUT(1) + 1 ), - : IN_VAR( I - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1) ) ) - CALL MSG_SETD( 'B', DBLE( IN_VAR(I-LBND_IN(1)+1) ) ) - CALL ERR_REP( ' ', 'TEST1R ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END DO - DO I = UBND(1) + 1, UBND_OUT(1) - IF( .NOT. EQUALR( OUT( I - LBND_OUT(1) + 1 ), - : 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1))) - CALL ERR_REP( ' ', 'TEST1R ^I: ^V != 0.0', STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT_VAR( I - LBND_OUT(1) + 1 ), - : 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1))) - CALL ERR_REP( ' ', 'TEST1R ^I: variance ^V != 0.0', - : STATUS ) - RETURN - END IF - END DO - - END IF - - END - - - - - -* ----------------------------------------------- -* Test 2 -* - - SUBROUTINE TEST2( DO, NAME, TYPE, - : LBND_IN, UBND_IN, IPIN, IPIN_VAR, - : LBND_OUT, UBND_OUT, IPOUT, IPOUT_VAR, - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - - INTEGER M, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), IPIN, IPIN_VAR, IPOUT, IPOUT_VAR, - : STATUS, DO, J - DOUBLE PRECISION TOL, PARAMS(*) - CHARACTER TYPE*(*), NAME*(*) - - IF( STATUS .NE. SAI__OK ) RETURN - - NAME = 'TEST2' - -* Fill the input data and variance arrays if required. - IF( TYPE .EQ. '_REAL' ) THEN - CALL TEST2R( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_DOUBLE' ) THEN - CALL TEST2D( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_INTEGER' ) THEN - CALL TEST2I( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( STATUS .EQ. SAI__OK ) then - STATUS = SAI__ERROR - CALL MSG_SETC( 'T', TYPE ) - CALL ERR_REP( ' ', 'Bad data type (^T) supplied to TEST2', - : STATUS ) - END IF - - END - - - - - SUBROUTINE TEST2D( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), STATUS, M, I, J, K, SPREAD - DOUBLE PRECISION IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC - LOGICAL EQUALD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_DTOD( VAL__MAXD )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - M = AST_UNITMAP( 2, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - IF( K .LE. 4 .OR. MOD( K, 4 ) .EQ. 0 .OR. - : MOD( K, 4 ) .EQ. 3 ) THEN - IF( .NOT. EQUALD( OUT( K ), 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - CALL ERR_REP( ' ', 'TEST2D ^I: ^V != 0', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT_VAR( K ), 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - CALL ERR_REP( ' ', 'TEST2D ^I: variance ^V '// - : '!= 0', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALD( OUT( K ), IN( K - 3 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K - 3 ) ) ) - CALL ERR_REP( ' ', 'TEST2D ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT( K ), IN( K-3 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K - 3 ) ) ) - CALL ERR_REP( ' ', - : 'TEST2D ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - - END IF - - END - - - - SUBROUTINE TEST2I( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), STATUS, M, I, J, K, SPREAD - INTEGER IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC - LOGICAL EQUALI - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_ITOD( VAL__MAXI )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - M = AST_UNITMAP( 2, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - IF( K .LE. 4 .OR. MOD( K, 4 ) .EQ. 0 .OR. - : MOD( K, 4 ) .EQ. 3 ) THEN - IF( .NOT. EQUALI( OUT( K ), 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - CALL ERR_REP( ' ', 'TEST2I ^I: ^V != 0', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT_VAR( K ), 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - CALL ERR_REP( ' ', 'TEST2I ^I: variance ^V '// - : '!= 0', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALI( OUT( K ), IN( K - 3 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K - 3 ) ) ) - CALL ERR_REP( ' ', 'TEST2I ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT( K ), IN( K-3 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K - 3 ) ) ) - CALL ERR_REP( ' ', - : 'TEST2I ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - - END IF - - END - - - - SUBROUTINE TEST2R( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), STATUS, M, I, J, K, SPREAD - REAL IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC - LOGICAL EQUALR - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_RTOD( VAL__MAXR )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - M = AST_UNITMAP( 2, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - IF( K .LE. 4 .OR. MOD( K, 4 ) .EQ. 0 .OR. - : MOD( K, 4 ) .EQ. 3 ) THEN - IF( .NOT. EQUALR( OUT( K ), 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - CALL ERR_REP( ' ', 'TEST2R ^I: ^V != 0', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT_VAR( K ), 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - CALL ERR_REP( ' ', 'TEST2R ^I: variance ^V '// - : '!= 0', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALR( OUT( K ), IN( K - 3 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K - 3 ) ) ) - CALL ERR_REP( ' ', 'TEST2R ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT( K ), IN( K-3 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K - 3 ) ) ) - CALL ERR_REP( ' ', - : 'TEST2R ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - - END IF - - END - - - - - -* ----------------------------------------------- -* Test 3 -* - - SUBROUTINE TEST3( DO, NAME, TYPE, - : LBND_IN, UBND_IN, IPIN, IPIN_VAR, - : LBND_OUT, UBND_OUT, IPOUT, IPOUT_VAR, - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - - INTEGER M, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), IPIN, IPIN_VAR, IPOUT, IPOUT_VAR, - : STATUS, DO, J - DOUBLE PRECISION TOL, PARAMS(*) - CHARACTER TYPE*(*), NAME*(*) - - IF( STATUS .NE. SAI__OK ) RETURN - - NAME = 'TEST3' - -* Fill the input data and variance arrays if required. - IF( TYPE .EQ. '_REAL' ) THEN - CALL TEST3R( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_DOUBLE' ) THEN - CALL TEST3D( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_INTEGER' ) THEN - CALL TEST3I( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( STATUS .EQ. SAI__OK ) then - STATUS = SAI__ERROR - CALL MSG_SETC( 'T', TYPE ) - CALL ERR_REP( ' ', 'Bad data type (^T) supplied to TEST3', - : STATUS ) - END IF - - END - - - - - SUBROUTINE TEST3D( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, L, K2 - DOUBLE PRECISION IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC - LOGICAL EQUALD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_DTOD( VAL__MAXD )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - LBND_IN( 3 ) = -1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 0 - UBND_OUT( 3 ) = 2 - LBND( 3 ) = -1 - UBND( 3 ) = 1 - M = AST_UNITMAP( 3, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO L = LBND_IN(3), UBND_IN(3) - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - - K2 = MOD( K - 1, 16 ) + 1 - IF( K2 .LE. 4 .OR. MOD( K2, 4 ) .EQ. 0 .OR. - : MOD( K2, 4 ) .EQ. 3 .OR. - : L .EQ. 2 ) THEN - IF( .NOT. EQUALD( OUT( K ), 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST3D ^I: ^V != 0', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT_VAR( K ), - ; 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT_VAR( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST3D ^I: variance ^V '// - : '!= 0', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALD( OUT( K ), IN( K + 13 ))) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K+13 ) ) ) - CALL ERR_REP( ' ', 'TEST3D ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT( K ), IN(K+13) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K+13 ) ) ) - CALL ERR_REP( ' ', - : 'TEST3D ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - END DO - END IF - - END - - - - SUBROUTINE TEST3I( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, L, K2 - INTEGER IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC - LOGICAL EQUALI - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_ITOD( VAL__MAXI )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - LBND_IN( 3 ) = -1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 0 - UBND_OUT( 3 ) = 2 - LBND( 3 ) = -1 - UBND( 3 ) = 1 - M = AST_UNITMAP( 3, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO L = LBND_IN(3), UBND_IN(3) - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - - K2 = MOD( K - 1, 16 ) + 1 - IF( K2 .LE. 4 .OR. MOD( K2, 4 ) .EQ. 0 .OR. - : MOD( K2, 4 ) .EQ. 3 .OR. - : L .EQ. 2 ) THEN - IF( .NOT. EQUALI( OUT( K ), 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST3I ^I: ^V != 0', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT_VAR( K ), - ; 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT_VAR( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST3I ^I: variance ^V '// - : '!= 0', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALI( OUT( K ), IN( K + 13 ))) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K+13 ) ) ) - CALL ERR_REP( ' ', 'TEST3I ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT( K ), IN(K+13) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K+13 ) ) ) - CALL ERR_REP( ' ', - : 'TEST3I ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - END DO - END IF - - END - - - - SUBROUTINE TEST3R( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, L, K2 - REAL IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC - LOGICAL EQUALR - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_RTOD( VAL__MAXR )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - LBND_IN( 3 ) = -1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 0 - UBND_OUT( 3 ) = 2 - LBND( 3 ) = -1 - UBND( 3 ) = 1 - M = AST_UNITMAP( 3, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO L = LBND_IN(3), UBND_IN(3) - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - - K2 = MOD( K - 1, 16 ) + 1 - IF( K2 .LE. 4 .OR. MOD( K2, 4 ) .EQ. 0 .OR. - : MOD( K2, 4 ) .EQ. 3 .OR. - : L .EQ. 2 ) THEN - IF( .NOT. EQUALR( OUT( K ), 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST3R ^I: ^V != 0', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT_VAR( K ), - ; 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT_VAR( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST3R ^I: variance ^V '// - : '!= 0', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALR( OUT( K ), IN( K + 13 ))) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K+13 ) ) ) - CALL ERR_REP( ' ', 'TEST3R ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT( K ), IN(K+13) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K+13 ) ) ) - CALL ERR_REP( ' ', - : 'TEST3R ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - END DO - END IF - - END - - - - - -* ----------------------------------------------- -* Test 4 -* - - SUBROUTINE TEST4( DO, NAME, TYPE, - : LBND_IN, UBND_IN, IPIN, IPIN_VAR, - : LBND_OUT, UBND_OUT, IPOUT, IPOUT_VAR, - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - - INTEGER M, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), IPIN, IPIN_VAR, IPOUT, IPOUT_VAR, - : STATUS, DO, J - DOUBLE PRECISION TOL, PARAMS(*) - CHARACTER TYPE*(*), NAME*(*) - - IF( STATUS .NE. SAI__OK ) RETURN - - NAME = 'TEST4' - -* Fill the input data and variance arrays if required. - IF( TYPE .EQ. '_REAL' ) THEN - CALL TEST4R( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_DOUBLE' ) THEN - CALL TEST4D( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_INTEGER' ) THEN - CALL TEST4I( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( STATUS .EQ. SAI__OK ) then - STATUS = SAI__ERROR - CALL MSG_SETC( 'T', TYPE ) - CALL ERR_REP( ' ', 'Bad data type (^T) supplied to TEST4', - : STATUS ) - END IF - - END - - - - - SUBROUTINE TEST4D( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I - DOUBLE PRECISION IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), K - LOGICAL EQUALD - - IF( STATUS .NE. SAI__OK ) RETURN - - K = MIN( 1000.0D0, NUM_DTOD( VAL__MAXD )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 10 - UBND_IN( 1 ) = 19 - LBND_OUT( 1 ) = 12 - UBND_OUT( 1 ) = 20 - LBND( 1 ) = 11 - UBND( 1 ) = 17 - M = AST_SHIFTMAP( 1, 3.0D0, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.1 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - DO I = LBND_IN(1), UBND_IN(1) - IN( I - LBND_IN(1) + 1 ) = I*K - IN_VAR( I - LBND_IN(1) + 1 ) = I - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - - DO I = LBND_OUT(1), LBND(1) + 2 - IF( .NOT. EQUALD( OUT( I - LBND_OUT(1) + 1 ), - : 0.0D0) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1 ) ) ) - CALL ERR_REP( ' ', 'TEST4D ^I: ^V != BAD', STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT_VAR( I - LBND_OUT(1) + 1 ), - : 0.0D0) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1) ) ) - CALL ERR_REP( ' ', 'TEST4D ^I: variance ^V != BAD', - : STATUS ) - RETURN - END IF - END DO - - DO I = LBND(1) + 3, UBND_OUT(1) - IF( .NOT. EQUALD( OUT( I - LBND_OUT(1) + 1 ), - : IN( I - 3 - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - IF( OUT( I - LBND_OUT(1) + 1 ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( I -3 - LBND_IN(1) + 1 ) ) ) - CALL ERR_REP( ' ', 'TEST4D ^I: data ^V != ^B', STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT_VAR( I - LBND_OUT(1) + 1 ), - : IN_VAR( I - 3 - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - IF( OUT_VAR(I-LBND_OUT(1)+1) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR(I-3-LBND_IN(1)+1) ) ) - CALL ERR_REP( ' ', 'TEST4D ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END DO - - END IF - - END - - SUBROUTINE TEST4I( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I - INTEGER IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), K - LOGICAL EQUALI - - IF( STATUS .NE. SAI__OK ) RETURN - - K = MIN( 1000.0D0, NUM_ITOD( VAL__MAXI )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 10 - UBND_IN( 1 ) = 19 - LBND_OUT( 1 ) = 12 - UBND_OUT( 1 ) = 20 - LBND( 1 ) = 11 - UBND( 1 ) = 17 - M = AST_SHIFTMAP( 1, 3.0D0, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.1 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - DO I = LBND_IN(1), UBND_IN(1) - IN( I - LBND_IN(1) + 1 ) = I*K - IN_VAR( I - LBND_IN(1) + 1 ) = I - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - - DO I = LBND_OUT(1), LBND(1) + 2 - IF( .NOT. EQUALI( OUT( I - LBND_OUT(1) + 1 ), - : 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1 ) ) ) - CALL ERR_REP( ' ', 'TEST4I ^I: ^V != BAD', STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT_VAR( I - LBND_OUT(1) + 1 ), - : 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1) ) ) - CALL ERR_REP( ' ', 'TEST4I ^I: variance ^V != BAD', - : STATUS ) - RETURN - END IF - END DO - - DO I = LBND(1) + 3, UBND_OUT(1) - IF( .NOT. EQUALI( OUT( I - LBND_OUT(1) + 1 ), - : IN( I - 3 - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - IF( OUT( I - LBND_OUT(1) + 1 ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( I -3 - LBND_IN(1) + 1 ) ) ) - CALL ERR_REP( ' ', 'TEST4I ^I: data ^V != ^B', STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT_VAR( I - LBND_OUT(1) + 1 ), - : IN_VAR( I - 3 - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - IF( OUT_VAR(I-LBND_OUT(1)+1) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR(I-3-LBND_IN(1)+1) ) ) - CALL ERR_REP( ' ', 'TEST4I ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END DO - - END IF - - END - - SUBROUTINE TEST4R( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I - REAL IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), K - LOGICAL EQUALR - - IF( STATUS .NE. SAI__OK ) RETURN - - K = MIN( 1000.0D0, NUM_RTOD( VAL__MAXR )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = 10 - UBND_IN( 1 ) = 19 - LBND_OUT( 1 ) = 12 - UBND_OUT( 1 ) = 20 - LBND( 1 ) = 11 - UBND( 1 ) = 17 - M = AST_SHIFTMAP( 1, 3.0D0, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.1 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - DO I = LBND_IN(1), UBND_IN(1) - IN( I - LBND_IN(1) + 1 ) = I*K - IN_VAR( I - LBND_IN(1) + 1 ) = I - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - - DO I = LBND_OUT(1), LBND(1) + 2 - IF( .NOT. EQUALR( OUT( I - LBND_OUT(1) + 1 ), - : 0.0E0) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1 ) ) ) - CALL ERR_REP( ' ', 'TEST4R ^I: ^V != BAD', STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT_VAR( I - LBND_OUT(1) + 1 ), - : 0.0E0) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1) ) ) - CALL ERR_REP( ' ', 'TEST4R ^I: variance ^V != BAD', - : STATUS ) - RETURN - END IF - END DO - - DO I = LBND(1) + 3, UBND_OUT(1) - IF( .NOT. EQUALR( OUT( I - LBND_OUT(1) + 1 ), - : IN( I - 3 - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - IF( OUT( I - LBND_OUT(1) + 1 ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( I - LBND_OUT(1) + 1))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( I -3 - LBND_IN(1) + 1 ) ) ) - CALL ERR_REP( ' ', 'TEST4R ^I: data ^V != ^B', STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT_VAR( I - LBND_OUT(1) + 1 ), - : IN_VAR( I - 3 - LBND_IN(1) + 1 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - IF( OUT_VAR(I-LBND_OUT(1)+1) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR(I-LBND_OUT(1)+1))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR(I-3-LBND_IN(1)+1) ) ) - CALL ERR_REP( ' ', 'TEST4R ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END DO - - END IF - - END - - - -* ----------------------------------------------- -* Test 5 -* - - SUBROUTINE TEST5( DO, NAME, TYPE, - : LBND_IN, UBND_IN, IPIN, IPIN_VAR, - : LBND_OUT, UBND_OUT, IPOUT, IPOUT_VAR, - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - - INTEGER M, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), IPIN, IPIN_VAR, IPOUT, IPOUT_VAR, - : STATUS, DO, J - DOUBLE PRECISION TOL, PARAMS(*) - CHARACTER TYPE*(*), NAME*(*) - - IF( STATUS .NE. SAI__OK ) RETURN - - NAME = 'TEST5' - -* Fill the input data and variance arrays if required. - IF( TYPE .EQ. '_REAL' ) THEN - CALL TEST5R( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_DOUBLE' ) THEN - CALL TEST5D( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_INTEGER' ) THEN - CALL TEST5I( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( STATUS .EQ. SAI__OK ) then - STATUS = SAI__ERROR - CALL MSG_SETC( 'T', TYPE ) - CALL ERR_REP( ' ', 'Bad data type (^T) supplied to TEST5', - : STATUS ) - END IF - - END - - - - - SUBROUTINE TEST5D( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K - DOUBLE PRECISION IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(2) - LOGICAL EQUALD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_DTOD( VAL__MAXD )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - SHIFTS(1) = 3.0D0 - SHIFTS(2) = -1.0D0 - M = AST_SHIFTMAP( 2, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - IF( MOD( K - 1, 4 ) .LT. 2 ) THEN - IF( .NOT. EQUALD( OUT( K ), 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST5D ^I: ^V != BAD', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT_VAR( K ), - : 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT_VAR( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST5D ^I: variance ^V '// - : '!= BAD', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALD( OUT( K ), IN( K - 2 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K - 2 ) ) ) - CALL ERR_REP( ' ', 'TEST5D ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT( K ), IN( K-2 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K - 2 ) ) ) - CALL ERR_REP( ' ', - : 'TEST5D ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - - END IF - - END - - - - SUBROUTINE TEST5I( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K - INTEGER IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(2) - LOGICAL EQUALI - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_ITOD( VAL__MAXI )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - SHIFTS(1) = 3.0D0 - SHIFTS(2) = -1.0D0 - M = AST_SHIFTMAP( 2, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - IF( MOD( K - 1, 4 ) .LT. 2 ) THEN - IF( .NOT. EQUALI( OUT( K ), 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST5I ^I: ^V != BAD', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT_VAR( K ), - : 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT_VAR( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST5I ^I: variance ^V '// - : '!= BAD', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALI( OUT( K ), IN( K - 2 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K - 2 ) ) ) - CALL ERR_REP( ' ', 'TEST5I ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT( K ), IN( K-2 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K - 2 ) ) ) - CALL ERR_REP( ' ', - : 'TEST5I ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - - END IF - - END - - - - SUBROUTINE TEST5R( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K - REAL IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(2) - LOGICAL EQUALR - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_RTOD( VAL__MAXR )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - SHIFTS(1) = 3.0D0 - SHIFTS(2) = -1.0D0 - M = AST_SHIFTMAP( 2, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - IF( MOD( K - 1, 4 ) .LT. 2 ) THEN - IF( .NOT. EQUALR( OUT( K ), 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST5R ^I: ^V != BAD', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT_VAR( K ), - : 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT_VAR( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST5R ^I: variance ^V '// - : '!= BAD', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALR( OUT( K ), IN( K - 2 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K - 2 ) ) ) - CALL ERR_REP( ' ', 'TEST5R ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT( K ), IN( K-2 ) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K - 2 ) ) ) - CALL ERR_REP( ' ', - : 'TEST5R ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - - END IF - - END - - - - - -* ----------------------------------------------- -* Test 6 -* - - SUBROUTINE TEST6( DO, NAME, TYPE, - : LBND_IN, UBND_IN, IPIN, IPIN_VAR, - : LBND_OUT, UBND_OUT, IPOUT, IPOUT_VAR, - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - - INTEGER M, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : LBND(*), UBND(*), IPIN, IPIN_VAR, IPOUT, IPOUT_VAR, - : STATUS, DO, J - DOUBLE PRECISION TOL, PARAMS(*) - CHARACTER TYPE*(*), NAME*(*) - - IF( STATUS .NE. SAI__OK ) RETURN - - NAME = 'TEST6' - -* Fill the input data and variance arrays if required. - IF( TYPE .EQ. '_REAL' ) THEN - CALL TEST6R( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_DOUBLE' ) THEN - CALL TEST6D( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( TYPE .EQ. '_INTEGER' ) THEN - CALL TEST6I( DO, LBND_IN, UBND_IN, %VAL(CNF_PVAL(IPIN)), - : %VAL(CNF_PVAL(IPIN_VAR)), LBND_OUT, UBND_OUT, - : %VAL(CNF_PVAL(IPOUT)),%VAL(CNF_PVAL(IPOUT_VAR)), - : LBND, UBND, M, PARAMS, TOL, J, STATUS ) - - ELSE IF( STATUS .EQ. SAI__OK ) then - STATUS = SAI__ERROR - CALL MSG_SETC( 'T', TYPE ) - CALL ERR_REP( ' ', 'Bad data type (^T) supplied to TEST6', - : STATUS ) - END IF - - END - - - - - SUBROUTINE TEST6D( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, L, K2 - DOUBLE PRECISION IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(3) - LOGICAL EQUALD - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_DTOD( VAL__MAXD )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - LBND_IN( 3 ) = -1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 0 - UBND_OUT( 3 ) = 2 - LBND( 3 ) = -1 - UBND( 3 ) = 1 - SHIFTS(1) = 3.0D0 - SHIFTS(2) = -1.0D0 - SHIFTS(3) = 1.0D0 - M = AST_SHIFTMAP( 3, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO L = LBND_IN(3), UBND_IN(3) - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - - K2 = MOD( K - 1, 16 ) + 1 - IF( MOD( K2 - 1, 4 ) .LT. 2 ) THEN - IF( .NOT. EQUALD( OUT( K ), 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST6D ^I: ^V != BAD', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT_VAR( K ), - : 0.0D0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT_VAR( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST6D ^I: variance ^V '// - : '!= BAD', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALD( OUT( K ), IN( K - 2 ))) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K-2 ) ) ) - CALL ERR_REP( ' ', 'TEST6D ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALD( OUT( K ), IN(K-2) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADD ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K-2 ) ) ) - CALL ERR_REP( ' ', - : 'TEST6D ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - END DO - END IF - - END - - - - SUBROUTINE TEST6I( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, L, K2 - INTEGER IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(3) - LOGICAL EQUALI - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_ITOD( VAL__MAXI )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - LBND_IN( 3 ) = -1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 0 - UBND_OUT( 3 ) = 2 - LBND( 3 ) = -1 - UBND( 3 ) = 1 - SHIFTS(1) = 3.0D0 - SHIFTS(2) = -1.0D0 - SHIFTS(3) = 1.0D0 - M = AST_SHIFTMAP( 3, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO L = LBND_IN(3), UBND_IN(3) - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - - K2 = MOD( K - 1, 16 ) + 1 - IF( MOD( K2 - 1, 4 ) .LT. 2 ) THEN - IF( .NOT. EQUALI( OUT( K ), 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST6I ^I: ^V != BAD', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT_VAR( K ), - : 0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT_VAR( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST6I ^I: variance ^V '// - : '!= BAD', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALI( OUT( K ), IN( K - 2 ))) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K-2 ) ) ) - CALL ERR_REP( ' ', 'TEST6I ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALI( OUT( K ), IN(K-2) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADI ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K-2 ) ) ) - CALL ERR_REP( ' ', - : 'TEST6I ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - END DO - END IF - - END - - - - SUBROUTINE TEST6R( DO, LBND_IN, UBND_IN, IN, IN_VAR, LBND_OUT, - : UBND_OUT, OUT, OUT_VAR, LBND, UBND, M, - : PARAMS, TOL, SPREAD, STATUS ) - - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'PRM_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'CNF_PAR' - INCLUDE 'NUM_DEC' - INCLUDE 'NUM_DEF' - - INTEGER DO, LBND_IN(*), UBND_IN(*), LBND_OUT(*), UBND_OUT(*), - : SPREAD, LBND(*), UBND(*), STATUS, M, I, J, K, L, K2 - REAL IN(*), IN_VAR(*), OUT(*), OUT_VAR(*) - DOUBLE PRECISION TOL, PARAMS(*), KFAC, SHIFTS(3) - LOGICAL EQUALR - - IF( STATUS .NE. SAI__OK ) RETURN - - KFAC = MIN( 1000.0D0, NUM_RTOD( VAL__MAXR )/20.0 ) - -* Return the scalar parameters of the test if required. - IF( DO .EQ. 0 ) THEN - LBND_IN( 1 ) = -1 - UBND_IN( 1 ) = 2 - LBND_OUT( 1 ) = 0 - UBND_OUT( 1 ) = 3 - LBND( 1 ) = -1 - UBND( 1 ) = 1 - LBND_IN( 2 ) = 3 - UBND_IN( 2 ) = 6 - LBND_OUT( 2 ) = 2 - UBND_OUT( 2 ) = 5 - LBND( 2 ) = 3 - UBND( 2 ) = 6 - LBND_IN( 3 ) = -1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 0 - UBND_OUT( 3 ) = 2 - LBND( 3 ) = -1 - UBND( 3 ) = 1 - SHIFTS(1) = 3.0D0 - SHIFTS(2) = -1.0D0 - SHIFTS(3) = 1.0D0 - M = AST_SHIFTMAP( 3, SHIFTS, ' ', STATUS ) - PARAMS(1) = 2.0 - PARAMS(2) = 2.0 - TOL = 0.0 - -* Fill the input data and variance arrays if required. - ELSE IF( DO .EQ. 1 ) THEN - K = 1 - DO L = LBND_IN(3), UBND_IN(3) - DO J = LBND_IN(2), UBND_IN(2) - DO I = LBND_IN(1), UBND_IN(1) - IN( K ) = K*KFAC - IN_VAR( K ) = K - K = K + 1 - END DO - END DO - END DO - -* Otherwise check output data and variance arrays look right. - ELSE - K = 1 - DO L = LBND_OUT(3), UBND_OUT(3) - DO J = LBND_OUT(2), UBND_OUT(2) - DO I = LBND_OUT(1), UBND_OUT(1) - - K2 = MOD( K - 1, 16 ) + 1 - IF( MOD( K2 - 1, 4 ) .LT. 2 ) THEN - IF( .NOT. EQUALR( OUT( K ), 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST6R ^I: ^V != BAD', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT_VAR( K ), - : 0.0E0 ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT_VAR( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ))) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL ERR_REP( ' ', 'TEST6R ^I: variance ^V '// - : '!= BAD', STATUS ) - RETURN - END IF - ELSE - IF( .NOT. EQUALR( OUT( K ), IN( K - 2 ))) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN( K-2 ) ) ) - CALL ERR_REP( ' ', 'TEST6R ^I: data ^V != ^B', - : STATUS ) - RETURN - ELSE IF( .NOT. EQUALR( OUT( K ), IN(K-2) ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', K ) - IF( OUT( K ) .NE. VAL__BADR ) THEN - CALL MSG_SETD( 'V', DBLE( OUT_VAR( K ) ) ) - ELSE - CALL MSG_SETC( 'V', 'BAD' ) - END IF - CALL MSG_SETD( 'B', DBLE( IN_VAR( K-2 ) ) ) - CALL ERR_REP( ' ', - : 'TEST6R ^I: variance ^V != ^B', - : STATUS ) - RETURN - END IF - END IF - K = K + 1 - END DO - END DO - END DO - END IF - - END - - - diff --git a/ast/ast_tester/testrebinseq.f b/ast/ast_tester/testrebinseq.f deleted file mode 100644 index 3ab4e43..0000000 --- a/ast/ast_tester/testrebinseq.f +++ /dev/null @@ -1,1580 +0,0 @@ - program testrebin - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer status - double precision params(2) - character ch - status = sai__ok - - call ast_begin( status ) - - params(1) = 1.5 - params(2) = 1 - - call tests( 1, AST__GAUSS, params, status ) - call tests( 2, AST__GAUSS, params, status ) - call tests( 3, AST__GAUSS, params, status ) - call tests( 1, AST__NEAREST, params, status ) - call tests( 2, AST__NEAREST, params, status ) - call tests( 3, AST__NEAREST, params, status ) - call tests( 1, AST__LINEAR, params, status ) - call tests( 2, AST__LINEAR, params, status ) - call tests( 3, AST__LINEAR, params, status ) - - call ast_end( status ) - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All AST_REBINSEQ tests passed' - else - write(*,*) 'AST_REBINSEQ tests failed' - end if - - end - - subroutine tests( NDIM, SPREAD, params, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer spread, status, ndim - double precision params(2) - - if( status .ne. sai__ok ) return - - call test1( NDIM, SPREAD, params, status ) - call test2( NDIM, SPREAD, params, status ) - call test3( NDIM, SPREAD, params, status ) - call test4( NDIM, SPREAD, params, status ) - call test5( NDIM, SPREAD, params, status ) - call test6( NDIM, SPREAD, params, status ) - call test7( NDIM, SPREAD, params, status ) - call test8( NDIM, SPREAD, params, status ) - call test9( NDIM, SPREAD, params, status ) - call test10( NDIM, SPREAD, params, status ) - call test11( NDIM, SPREAD, params, status ) - call test12( NDIM, SPREAD, params, status ) - - if( status .ne. SAI__OK ) then - call msg_seti( 'N', ndim ) - - if( spread .eq. AST__GAUSS ) then - call msg_setc( 'S', 'AST__GAUSS' ) - else if( spread .eq. AST__NEAREST ) then - call msg_setc( 'S', 'AST__NEAREST' ) - else if( spread .eq. AST__LINEAR ) then - call msg_setc( 'S', 'AST__LINEAR' ) - endif - call err_rep( ' ', 'Spread=^S (^N-dimensional)', status ) - endif - - end - - - - - SUBROUTINE ADDNOISE( N, ARRAY, SIGMA, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER BUFSIZE - PARAMETER ( BUFSIZE = 100 ) - - INTEGER N, STATUS, MM, IAT, NUSED, I - DOUBLE PRECISION ARRAY( N ) - DOUBLE PRECISION SIGMA - DOUBLE PRECISION NOISE( BUFSIZE ) - DOUBLE PRECISION JUNK( BUFSIZE ) - - CHARACTER FWD(1)*80 - CHARACTER INV(1)*80 - - DATA JUNK/ BUFSIZE*0.0D0 / - - IF( STATUS .NE. SAI__OK ) RETURN - - FWD(1) = 'Y=Gauss(0.0,' - IAT = 12 - CALL CHR_PUTD( SIGMA, FWD(1), IAT ) - CALL CHR_APPND( ')', FWD(1), IAT ) - INV(1) = 'X' - - MM = AST_MATHMAP( 1, 1, 1, FWD, 1, INV, ' ', STATUS ) - - NUSED = BUFSIZE - DO I = 1, N - IF( NUSED .EQ. BUFSIZE ) THEN - CALL AST_TRAN1( MM, BUFSIZE, JUNK, .TRUE., NOISE, STATUS ) - NUSED = 0 - END IF - NUSED = NUSED + 1 - ARRAY( I ) = ARRAY( I ) + NOISE( NUSED ) - END DO - - CALL AST_ANNUL( MM, STATUS ) - - END - - - - - - - SUBROUTINE TEST1( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER NX, NY, JHI - PARAMETER( NX = 100 ) - PARAMETER( NY = 200 ) - - - REAL IN( NX, NY ) - REAL OUT( NX, NY ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( NX, NY ) - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : FLAGS, I, J - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, NX - DO J = 1, NY - IN( I, J ) = 1.0 - END DO - END DO - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - LBND_IN( 3 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - UBND_IN( 3 ) = 1 - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__REBINEND - - MAP = AST_UNITMAP( NDIM, ' ', STATUS ) - CALL AST_REBINSEQR( MAP, 0.0D0, NDIM, LBND_IN, UBND_IN, IN, IN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADR, - : NDIM, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : out, OUT, WEIGHTS, NUSED, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - JHI = 1 - ELSE - JHI = ny - ENDIF - - DO I = 1, NX - DO J = 1, JHI - IF( ABS( OUT( I, J ) - 1.0 ) .GT. 1.0E-6 .AND. - : STATUS .EQ. SAI__OK ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETI( 'J', J ) - CALL MSG_SETR( 'V', OUT(I,J) ) - CALL ERR_REP( ' ', 'Output pixel (^I,^J) should be '// - : '1.0 but is ^V', status ) - END IF - END DO - END DO - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test1 failed', STATUS ) - END IF - - END - - - - SUBROUTINE TEST2( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER NX, NY, JHI - PARAMETER( NX = 100 ) - PARAMETER( NY = 200 ) - - - DOUBLE PRECISION IN( NX, NY ) - DOUBLE PRECISION OUT( NX, NY ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( NX, NY ) - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : FLAGS, I, J - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, NX - DO J = 1, NY - IN( I, J ) = 1.0D0 - END DO - END DO - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT - - MAP = AST_UNITMAP( NDIM, ' ', STATUS ) - - DO I = 1, 3 - IF( I .EQ. 3 ) FLAGS = AST__REBINEND - CALL AST_REBINSEQD( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, IN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADD, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, OUT, WEIGHTS, NUSED, STATUS ) - END DO - - IF( NDIM .EQ. 1 ) THEN - JHI = 1 - ELSE - JHI = ny - ENDIF - - DO I = 1, NX - DO J = 1, JHI - IF( ABS( OUT( I, J ) - 1.0D0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETI( 'J', J ) - CALL MSG_SETD( 'V', OUT(I,J) ) - CALL ERR_REP( ' ', 'Output pixel (^I,^J) should be '// - : '1.0 but is ^V', status ) - END IF - END DO - END DO - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test2 failed', STATUS ) - END IF - - END - - - - - - SUBROUTINE TEST3( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER NX, NY - PARAMETER( NX = 100 ) - PARAMETER( NY = 200 ) - - INTEGER IN( NX, NY ) - INTEGER OUT( NX, NY ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( NX, NY ) - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : FLAGS, I, J, JHI - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, NX - DO J = 1, NY - IN( I, J ) = 1.0D0 - END DO - END DO - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__NONORM - - MAP = AST_UNITMAP( NDIM, ' ', STATUS ) - - DO I = 1, 3 - CALL AST_REBINSEQI( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, IN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADI, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, OUT, WEIGHTS, NUSED, STATUS ) - FLAGS = AST__NONORM - END DO - - IF( NDIM .EQ. 1 ) THEN - JHI = 1 - ELSE - JHI = ny - ENDIF - - DO I = 1, NX - DO J = 1, JHI - IF( OUT( I, J ) .NE. 3 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETI( 'J', J ) - CALL MSG_SETI( 'V', OUT(I,J) ) - CALL ERR_REP( ' ', 'Output pixel (^I,^J) should be '// - : '3 but is ^V', status ) - END IF - END DO - END DO - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test3 failed', STATUS ) - END IF - - END - - - - - - - SUBROUTINE TEST4( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER NX, NY - PARAMETER( NX = 100 ) - PARAMETER( NY = 200 ) - - REAL IN( NX, NY ) - REAL OUT( NX, NY ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( NX, NY ), INA(3), - : INB(3), OUTA(3), OUTB(3), SUM, ANSWER - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : FLAGS, I, J, LBOXG(3), UBOXG(3), JHI - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, NX - DO J = 1, NY - IN( I, J ) = 1.0 - END DO - END DO - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__REBINEND + AST__CONSERVEFLUX - - INA( 1 ) = LBND_IN( 1 ) - INA( 2 ) = LBND_IN( 2 ) - INA( 3 ) = LBND_IN( 3 ) - INB( 1 ) = UBND_IN( 1 ) - INB( 2 ) = UBND_IN( 2 ) - INB( 3 ) = UBND_IN( 3 ) + 1.0D0 - - OUTA( 1 ) = 0.75*LBND_OUT( 1 ) + 0.25*UBND_OUT( 1 ) - OUTA( 2 ) = 0.75*LBND_OUT( 2 ) + 0.25*UBND_OUT( 2 ) - OUTA( 3 ) = INA( 3 ) - OUTB( 1 ) = 0.25*LBND_OUT( 1 ) + 0.75*UBND_OUT( 1 ) - OUTB( 2 ) = 0.25*LBND_OUT( 2 ) + 0.75*UBND_OUT( 2 ) - OUTB( 3 ) = INB( 3 ) - - MAP = AST_WINMAP( NDIM, INA, INB, OUTA, OUTB, ' ', STATUS ) - CALL AST_REBINSEQR( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, IN, - : spread, PARAMS, FLAGS, 0.01D0, 1000, - : VAL__BADR, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, OUT, WEIGHTS, NUSED, STATUS ) - - LBOXG( 1 ) = VAL__MAXI - LBOXG( 2 ) = VAL__MAXI - UBOXG( 1 ) = VAL__MINI - UBOXG( 2 ) = VAL__MINI - - SUM = 0.0D0 - - IF( NDIM .EQ. 1 ) THEN - JHI = 1 - ELSE - JHI = ny - ENDIF - - DO I = 1, NX - DO J = 1, JHI - - IF( OUT(I,J) .NE. VAL__BADR ) THEN - SUM = SUM + OUT(I,J) - IF( I .LT. LBOXG(1) ) THEN - LBOXG(1) = I - ELSE IF( I .GT. UBOXG(1) ) THEN - UBOXG(1) = I - ENDIF - IF( J .LT. LBOXG(2) ) THEN - LBOXG(2) = J - ELSE IF( J .GT. UBOXG(2) ) THEN - UBOXG(2) = J - ENDIF - ENDIF - END DO - END DO - - IF( NDIM .EQ. 1 ) THEN - - IF( ( ( SPREAD .EQ. AST__GAUSS ) .AND. ( - : LBOXG( 1 ) .NE. 24 .OR. - : UBOXG( 1 ) .NE. 77 )) .OR. ( - : ( SPREAD .EQ. AST__NEAREST ) .AND. ( - : LBOXG( 1 ) .NE. 26 .OR. - : UBOXG( 1 ) .NE. 75 )) .OR. ( - : ( SPREAD .EQ. AST__LINEAR ) .AND. ( - : LBOXG( 1 ) .NE. 25 .OR. - : UBOXG( 1 ) .NE. 76 ) ) ) THEN - STATUS = SAI__ERROR - CALL ERR_REP( ' ', 'Good pixel bounding box is wrong', - : STATUS ) - write(*,*) LBOXG, UBOXG - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - ANSWER = 100.0 - ELSE IF( SPREAD .EQ. AST__GAUSS ) THEN - ANSWER = 108.0 - ELSE IF( SPREAD .EQ. AST__LINEAR ) THEN - ANSWER = 104.0 - ELSE - ANSWER = -1 - END IF - - else - - IF( ( ( SPREAD .EQ. AST__GAUSS ) .AND. ( - : LBOXG( 1 ) .NE. 24 .OR. - : LBOXG( 2 ) .NE. 49 .OR. - : UBOXG( 1 ) .NE. 77 .OR. - : UBOXG( 2 ) .NE. 152 ) ) .OR. ( - : ( SPREAD .EQ. AST__NEAREST ) .AND. ( - : LBOXG( 1 ) .NE. 26 .OR. - : LBOXG( 2 ) .NE. 51 .OR. - : UBOXG( 1 ) .NE. 75 .OR. - : UBOXG( 2 ) .NE. 150 ) ) .OR. ( - : ( SPREAD .EQ. AST__LINEAR ) .AND. ( - : LBOXG( 1 ) .NE. 25 .OR. - : LBOXG( 2 ) .NE. 50 .OR. - : UBOXG( 1 ) .NE. 76 .OR. - : UBOXG( 2 ) .NE. 151 ) ) ) THEN - STATUS = SAI__ERROR - CALL ERR_REP( ' ', 'Good pixel bounding box is wrong', - : STATUS ) - write(*,*) LBOXG, UBOXG - END IF - - IF( SPREAD .EQ. AST__NEAREST ) THEN - ANSWER = 20000.0 - ELSE IF( SPREAD .EQ. AST__GAUSS ) THEN - ANSWER = 22464.0 - ELSE IF( SPREAD .EQ. AST__LINEAR ) THEN - ANSWER = 21216.0 - ELSE - ANSWER = -1 - END IF - endif - - IF( ABS( SUM - ANSWER ) .GT. 0.01 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', SUM ) - CALL MSG_SETD( 'W', ANSWER ) - CALL ERR_REP( ' ', 'Total output data sum is ^V (should '// - : 'be ^W).', STATUS ) - END IF - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test4 failed', STATUS ) - END IF - - END - - - - SUBROUTINE TEST5( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER NX_IN, NY_IN - PARAMETER( NX_IN = 100 ) - PARAMETER( NY_IN = 200 ) - - INTEGER BORDER_OUT - PARAMETER( BORDER_OUT = 10 ) - - INTEGER NX_OUT, NY_OUT - PARAMETER( NX_OUT = NX_IN + 2*BORDER_OUT ) - PARAMETER( NY_OUT = NY_IN + 2*BORDER_OUT ) - - DOUBLE PRECISION IN( NX_IN, NY_IN ) - DOUBLE PRECISION OUT( NX_OUT, NY_OUT ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( NX_OUT, NY_OUT ), INA(3), - : INB(3), OUTA(3), OUTB(3), SUM, VA, VB - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : K, FLAGS, I, J, LBOXG(3), UBOXG(3), JHI - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX_IN - 1 - UBND_IN( 2 ) = NY_IN - - LBND_OUT( 1 ) = LBND_IN( 1 ) - BORDER_OUT - LBND_OUT( 2 ) = LBND_IN( 2 ) - BORDER_OUT - UBND_OUT( 1 ) = UBND_IN( 1 ) + BORDER_OUT - UBND_OUT( 2 ) = UBND_IN( 2 ) + BORDER_OUT - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__NONORM - - INA( 1 ) = LBND_IN( 1 ) - INA( 2 ) = LBND_IN( 2 ) - INA( 3 ) = LBND_IN( 3 ) - INB( 1 ) = UBND_IN( 1 ) - INB( 2 ) = UBND_IN( 2 ) - INB( 3 ) = UBND_IN( 3 ) + 1.0D0 - - DO K = 1, 3 - - DO I = 1, NX_IN - DO J = 1, NY_IN - IN( I, J ) = K - END DO - END DO - - VA = (k-1)*0.25 - VB = VA + 0.5 - - OUTA( 1 ) = VB*LBND_IN( 1 ) + VA*UBND_IN( 1 ) - OUTA( 2 ) = VB*LBND_IN( 2 ) + VA*UBND_IN( 2 ) - OUTB( 1 ) = VA*LBND_IN( 1 ) + VB*UBND_IN( 1 ) - OUTB( 2 ) = VA*LBND_IN( 2 ) + VB*UBND_IN( 2 ) - OUTA( 3 ) = INA( 3 ) - OUTB( 3 ) = INB( 3 ) - - MAP = AST_WINMAP( NDIM, INA, INB, OUTA, OUTB, ' ', STATUS ) - CALL AST_REBINSEQD( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, IN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADD, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, OUT, WEIGHTS, NUSED, STATUS ) - - FLAGS = AST__NONORM - END DO - - IF( NDIM .EQ. 1 ) THEN - JHI = 1 - ELSE - JHI = ny_out - ENDIF - - SUM = 0.0D0 - - DO I = 1, NX_OUT - DO J = 1, JHI - IF( OUT(I,J) .NE. VAL__BADR ) THEN - SUM = SUM + OUT(I,J) - ENDIF - END DO - END DO - - IF( NDIM .EQ. 1 ) THEN - IF( ABS( SUM - 600 ) .GT. 1.0E-3 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', SUM ) - CALL ERR_REP( ' ', 'Total output data sum is ^V (should '// - : 'be 600).', STATUS ) - - END IF - - IF( ABS( OUT(20,1) - 2.0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', OUT(20,1) ) - CALL ERR_REP( ' ', 'Output pixel (20) should be 2, '// - : 'is ^V', STATUS ) - - ELSE IF( ABS( OUT(50,1) - 6.0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', OUT(50,1) ) - CALL ERR_REP( ' ', 'Output pixel (50) should be 6, '// - : 'is ^V', STATUS ) - - ELSE IF( ABS( OUT(70,1) - 10.0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', OUT(70,1) ) - CALL ERR_REP( ' ', 'Output pixel (70) should be 10, '// - : 'is ^V', STATUS ) - - ELSE IF( ABS( OUT(100,1) - 6.0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', OUT(100,1) ) - CALL ERR_REP( ' ', 'Output pixel (100) should be 6, '// - : 'is ^V', STATUS ) - END IF - - ELSE IF( NDIM .EQ. 2 ) THEN - IF( ABS( SUM - 120000 ) .GT. 1.0E-3 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', SUM ) - CALL ERR_REP( ' ', 'Total output data sum is ^V (should '// - : 'be 120000).', STATUS ) - - END IF - - IF( ABS( OUT(40,40) - 4.0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', OUT(40,40) ) - CALL ERR_REP( ' ', 'Output pixel (40,40) should be 4, '// - : 'is ^V', STATUS ) - - ELSE IF( ABS( OUT(50,90) - 12.0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', OUT(50,90) ) - CALL ERR_REP( ' ', 'Output pixel (50,90) should be 12, '// - : 'is ^V', STATUS ) - - ELSE IF( ABS( OUT(70,80) - 8.0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', OUT(70,80) ) - CALL ERR_REP( ' ', 'Output pixel (70,80) should be 8, '// - : 'is ^V', STATUS ) - - ELSE IF( ABS( OUT(70,130) - 20.0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', OUT(70,130) ) - CALL ERR_REP( ' ', 'Output pixel (70,130) should be 20, '// - : 'is ^V', STATUS ) - - ELSE IF( ABS( OUT(20,130) - 0.0 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', OUT(20,130) ) - CALL ERR_REP( ' ', 'Output pixel (20,130) should be 0, '// - : 'is ^V', STATUS ) - - END IF - END IF - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test5 failed', STATUS ) - END IF - - END - - - - - SUBROUTINE TEST6( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER NK - PARAMETER( NK = 3 ) - - INTEGER NX_IN, NY_IN - PARAMETER( NX_IN = 100 ) - PARAMETER( NY_IN = 200 ) - - INTEGER BORDER_OUT - PARAMETER( BORDER_OUT = 10 ) - - INTEGER NX_OUT, NY_OUT - PARAMETER( NX_OUT = NX_IN + 2*BORDER_OUT ) - PARAMETER( NY_OUT = NY_IN + 2*BORDER_OUT ) - - DOUBLE PRECISION IN( NX_IN, NY_IN ), ANSWER - DOUBLE PRECISION OUT( NX_OUT, NY_OUT ), MNVAL, MXVAL - DOUBLE PRECISION PARAMS(2), WEIGHTS( NX_OUT, NY_OUT ), INA(3), - : INB(3), OUTA(3), OUTB(3), SUM, VA, VB - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : K, FLAGS, I, J, LBOXG(3), UBOXG(3), JHI - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX_IN - 1 - UBND_IN( 2 ) = NY_IN - - LBND_OUT( 1 ) = LBND_IN( 1 ) - BORDER_OUT - LBND_OUT( 2 ) = LBND_IN( 2 ) - BORDER_OUT - UBND_OUT( 1 ) = UBND_IN( 1 ) + BORDER_OUT - UBND_OUT( 2 ) = UBND_IN( 2 ) + BORDER_OUT - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - INA( 1 ) = LBND_IN( 1 ) - INA( 2 ) = LBND_IN( 2 ) - INA( 3 ) = LBND_IN( 3 ) - INB( 1 ) = UBND_IN( 1 ) - INB( 2 ) = UBND_IN( 2 ) - INB( 3 ) = UBND_IN( 3 ) + 1.0D0 - - DO K = 1, NK - - FLAGS = AST__CONSERVEFLUX - IF( K .EQ. 1 ) FLAGS = FLAGS + AST__REBININIT - IF( K .EQ. NK ) FLAGS = FLAGS + AST__REBINEND - - DO I = 1, NX_IN - DO J = 1, NY_IN - IN( I, J ) = K - END DO - END DO - - VA = (k-1)*0.25 - VB = VA + 0.5 - - OUTA( 1 ) = VB*LBND_IN( 1 ) + VA*UBND_IN( 1 ) - OUTA( 2 ) = VB*LBND_IN( 2 ) + VA*UBND_IN( 2 ) - OUTB( 1 ) = VA*LBND_IN( 1 ) + VB*UBND_IN( 1 ) - OUTB( 2 ) = VA*LBND_IN( 2 ) + VB*UBND_IN( 2 ) - OUTA( 3 ) = INA( 3 ) - OUTB( 3 ) = INB( 3 ) - - MAP = AST_WINMAP( NDIM, INA, INB, OUTA, OUTB, ' ', STATUS ) - CALL AST_REBINSEQD( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, IN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADD, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, OUT, WEIGHTS, NUSED, STATUS ) - - END DO - - IF( NDIM .EQ. 1 ) THEN - JHI = 1 - ELSE - JHI = ny_out - ENDIF - - SUM = 0.0D0 - MXVAL = VAL__MIND - MNVAL = VAL__MAXD - DO I = 1, NX_OUT - DO J = 1, JHI - IF( OUT(I,J) .NE. VAL__BADD ) THEN - SUM = SUM + OUT(I,J) - IF( OUT(I,J) .GT. MXVAL ) MXVAL = OUT(I,J) - IF( OUT(I,J) .lT. MnVAL ) MNVAL = OUT(I,J) - ENDIF - END DO - END DO - - IF( NDIM .eq. 1 ) THEN - IF( SPREAD .EQ. AST__GAUSS ) THEN - ANSWER = 414.0D0 - ELSE IF( SPREAD .EQ. AST__NEAREST ) THEN - ANSWER = 399.4D0 - ELSE IF( SPREAD .EQ. AST__LINEAR ) THEN - ANSWER = 400.0D0 - ELSE - ANSWER = -1.0 - END IF - - IF( ABS( SUM - ANSWER ) .GT. 1.0D-3 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', SUM ) - CALL MSG_SETD( 'W', ANSWER ) - CALL ERR_REP( ' ', 'Total output data sum is ^V (should '// - : 'be ^W).', STATUS ) - - ELSE IF( ABS( MXVAL - 6 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', MXVAL ) - CALL ERR_REP( ' ', 'Max value is ^V (should be 6).', - : STATUS ) - - ELSE IF( ABS( MNVAL - 2 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', MNVAL ) - CALL ERR_REP( ' ', 'Min value is ^V (should be 2).', - : STATUS ) - - END IF - - ELSE IF( NDIM .eq. 2 ) THEN - IF( SPREAD .EQ. AST__GAUSS ) THEN - ANSWER = 109011.729592723D0 - ELSE IF( SPREAD .EQ. AST__NEAREST ) THEN - ANSWER = 100716.666666667D0 - ELSE IF( SPREAD .EQ. AST__LINEAR ) THEN - ANSWER = 102816.0D0 - ELSE - ANSWER = -1.0 - END IF - - IF( ABS( SUM - ANSWER ) .GT. 1.0D-3 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', SUM ) - CALL MSG_SETD( 'W', ANSWER ) - CALL ERR_REP( ' ', 'Total output data sum is ^V (should '// - : 'be ^W).', STATUS ) - - ELSE IF( ABS( MXVAL - 12 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', MXVAL ) - CALL ERR_REP( ' ', 'Max value is ^V (should be 12).', - : STATUS ) - - ELSE IF( ABS( MNVAL - 4 ) .GT. 1.0E-6 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', MNVAL ) - CALL ERR_REP( ' ', 'Min value is ^V (should be 4).', - : STATUS ) - - END IF - END IF - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test6 failed', STATUS ) - END IF - - END - - - SUBROUTINE TEST7( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER NX, NY - PARAMETER( NX = 100 ) - PARAMETER( NY = 200 ) - - - REAL IN( NX, NY ) - REAL OUT( NX, NY ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( NX, NY ) - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : JHI, FLAGS, I, J - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, NX - DO J = 1, NY - IN( I, J ) = 1.0 - END DO - END DO - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__REBINEND - - MAP = AST_ZOOMMAP( NDIM, 0.5D0, ' ', STATUS ) - CALL AST_REBINSEQR( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, IN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADR, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, OUT, WEIGHTS, NUSED, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - JHI = 1 - ELSE - JHI = ny - ENDIF - - DO I = 1, NX - DO J = 1, JHI - IF( ABS( OUT( I, J ) - 1.0 ) .GT. 1.0E-6 .AND. - : OUT( I, J ) .NE. VAL__BADR ) THEN - STATUS = SAI__ERROR - CALL MSG_SETI( 'I', I ) - CALL MSG_SETI( 'J', J ) - CALL MSG_SETR( 'V', OUT(I,J) ) - CALL ERR_REP( ' ', 'Output pixel (^I,^J) should be '// - : '1.0 but is ^V', status ) - END IF - END DO - END DO - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test7 failed', STATUS ) - END IF - - END - - - SUBROUTINE TEST8( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER NX, NY - PARAMETER( NX = 100 ) - PARAMETER( NY = 200 ) - - - REAL IN( NX, NY ) - REAL OUT( NX, NY ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( NX, NY ), SHIFTS(3), SUM - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : FLAGS, I, J, JHI - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, NX - DO J = 1, NY - IN( I, J ) = 1.0 - END DO - END DO - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__REBINEND + AST__NONORM - - SHIFTS(1) = 5.0D0 - SHIFTS(2) = 5.0D0 - - if( ndim .lt. 3 ) then - MAP = AST_CMPMAP( AST_ZOOMMAP( NDIM, 0.5D0, ' ', STATUS ), - : AST_SHIFTMAP( NDIM, SHIFTS, ' ', STATUS ), - : .TRUE., ' ', STATUS ) - else - MAP = AST_CMPMAP( AST_CMPMAP( AST_ZOOMMAP( 2, 0.5D0, ' ', - : STATUS ), - : AST_SHIFTMAP( 2, SHIFTS, ' ', - : STATUS ), - : .TRUE., ' ', STATUS ), - : AST_UNITMAP( 1, ' ', STATUS ), .FALSE., - : ' ', STATUS ) - endif - - CALL AST_REBINSEQR( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, IN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADR, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, OUT, WEIGHTS, NUSED, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - JHI = 1 - ELSE - JHI = ny - ENDIF - - SUM = 0.0D0 - DO I = 1, NX - DO J = 1, JHI - if( out(i,j) .ne. VAL__BADR ) then - SUM = SUM + DBLE(OUT(I,J)) - end if - END DO - END DO - - IF( SUM .NE. SUM ) THEN - STATUS = SAI__ERROR - CALL ERR_REP( ' ', 'Total output data sum is NaN', STATUS ) - - ELSE IF( ABS( SUM - NX*JHI ) .GT. SUM*1.0D-7 ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', SUM ) - CALL MSG_SETD( 'W', DBLE( NX*JHI) ) - CALL ERR_REP( ' ', 'Total output data sum is ^V (should '// - : 'be ^W).', STATUS ) - END IF - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test8 failed', STATUS ) - END IF - - END - - - SUBROUTINE TEST9( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER SIZE - PARAMETER( SIZE = 20000 ) - - INTEGER NX1, NY1 - PARAMETER( NX1 = SIZE ) - PARAMETER( NY1 = 1 ) - - INTEGER NX2, NY2 - PARAMETER( NX2 = SIZE/200 ) - PARAMETER( NY2 = 200 ) - - DOUBLE PRECISION SIGMA - PARAMETER ( SIGMA = 0.1 ) - - REAL*8 IN( size ), VIN( size ) - REAL*8 OUT( size ), VOUT( size ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( size ) - DOUBLE PRECISION REALVAR,MEANVAR,SUM,SUM2,SUM3 - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : FLAGS, I, J, NVAL, JHI, JLO, NX, NY, ILO, IHI, k - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, size - IN( I ) = 1.0D0 - VIN( I ) = SIGMA**2 - END DO - - CALL ADDNOISE( size, IN, SIGMA, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - NX = NX1 - Ny = NY1 - ELSE - NX = NX2 - Ny = NY2 - END IF - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__REBINEND + AST__NONORM + AST__USEVAR - - MAP = AST_ZOOMMAP( NDIM, 0.5D0, ' ', STATUS ) - CALL AST_REBINSEQD( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, VIN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADD, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, VOUT, WEIGHTS, NUSED, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - ILO = 6 - IHI = NINT(0.45*NX1) - JLO = 1 - JHI = 1 - ELSE - ILO = 6 - IHI = 41 - JLO = 8 - JHI = 91 - ENDIF - - SUM = 0.0D0 - SUM2 = 0.0D0 - SUM3 = 0.0D0 - NVAL = 0 - - DO I = ILO, IHI - DO J = JLO, JHI - K = ( J - 1 )*NX + I - IF( OUT(K) .NE. VAL__BADD ) THEN - SUM = SUM + OUT(K) - SUM2 = SUM2 + OUT(K)**2 - SUM3 = SUM3 + VOUT(K) - NVAL = NVAL + 1 - END IF - END DO - END DO - - SUM = SUM/NVAL - REALVAR = SUM2/NVAL - SUM*SUM - MEANVAR = SUM3/NVAL - IF( ABS( REALVAR - MEANVAR ) .GT. - : 0.05*( REALVAR + MEANVAR ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', REALVAR ) - CALL MSG_SETD( 'W', MEANVAR ) - CALL ERR_REP( ' ', 'Real variance is ^V - estimate is ^W.', - : STATUS ) - END IF - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test9 failed', STATUS ) - END IF - - END - - - SUBROUTINE TEST10( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER SIZE - PARAMETER( SIZE = 20000 ) - - INTEGER NX1, NY1 - PARAMETER( NX1 = SIZE ) - PARAMETER( NY1 = 1 ) - - INTEGER NX2, NY2 - PARAMETER( NX2 = SIZE/200 ) - PARAMETER( NY2 = 200 ) - - DOUBLE PRECISION SIGMA - PARAMETER ( SIGMA = 0.1 ) - - REAL*8 IN( size ), VIN( size ) - REAL*8 OUT( size ), VOUT( size ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( size ) - DOUBLE PRECISION REALVAR,MEANVAR,SUM,SUM2,SUM3 - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : FLAGS, I, J, NVAL, JHI, JLO, ILO, IHI, NX, NY, K - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, SIZE - IN( I ) = 1.0D0 - VIN( I ) = SIGMA**2 - END DO - - CALL ADDNOISE( SIZE, IN, SIGMA, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - NX = NX1 - Ny = NY1 - ELSE - NX = NX2 - Ny = NY2 - END IF - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__REBINEND + AST__CONSERVEFLUX - : + AST__USEVAR - - MAP = AST_ZOOMMAP( NDIM, 0.5D0, ' ', STATUS ) - CALL AST_REBINSEQD( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, VIN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADD, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, VOUT, WEIGHTS, NUSED, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - ILO = 6 - IHI = NINT(0.45*NX1) - JLO = 1 - JHI = 1 - ELSE - ILO = 6 - IHI = 41 - JLO = 8 - JHI = 91 - ENDIF - - SUM = 0.0D0 - SUM2 = 0.0D0 - SUM3 = 0.0D0 - NVAL = 0 - - DO I = ILO,IHI - DO J = JLO, JHI - K = ( J - 1 )*NX + I - IF( OUT(K) .NE. VAL__BADD ) THEN - SUM = SUM + OUT(K) - SUM2 = SUM2 + OUT(K)**2 - SUM3 = SUM3 + VOUT(K) - NVAL = NVAL + 1 - END IF - END DO - END DO - - SUM = SUM/NVAL - REALVAR = SUM2/NVAL - SUM*SUM - MEANVAR = SUM3/NVAL - - IF( ABS( REALVAR - MEANVAR ) .GT. - : 0.05*( REALVAR + MEANVAR ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', REALVAR ) - CALL MSG_SETD( 'W', MEANVAR ) - CALL ERR_REP( ' ', 'Real variance is ^V - estimate is ^W.', - : STATUS ) - END IF - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test10 failed', STATUS ) - END IF - - END - - SUBROUTINE TEST11( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER SIZE - PARAMETER( SIZE = 20000 ) - - INTEGER NX1, NY1 - PARAMETER( NX1 = SIZE ) - PARAMETER( NY1 = 1 ) - - INTEGER NX2, NY2 - PARAMETER( NX2 = SIZE/200 ) - PARAMETER( NY2 = 200 ) - - DOUBLE PRECISION SIGMA - PARAMETER ( SIGMA = 0.1 ) - - REAL*8 IN( SIZE ), VIN( SIZE ) - REAL*8 OUT( SIZE ), VOUT( SIZE ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( SIZE, 2 ) - DOUBLE PRECISION REALVAR,MEANVAR,SUM,SUM2,SUM3 - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : FLAGS, I, J, NVAL, JLO, JHI, NX, NY, ILO, IHI, K - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, SIZE - IN( I ) = 1.0D0 - VIN( I ) = SIGMA**2 - END DO - - CALL ADDNOISE( SIZE, IN, SIGMA, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - NX = NX1 - Ny = NY1 - ELSE - NX = NX2 - Ny = NY2 - END IF - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__REBINEND + AST__GENVAR - - MAP = AST_ZOOMMAP( NDIM, 0.5D0, ' ', STATUS ) - CALL AST_REBINSEQD( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, VIN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADD, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, VOUT, WEIGHTS, NUSED, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - ILO = 6 - IHI = NINT(0.45*NX1) - JLO = 1 - JHI = 1 - ELSE - ILO = 6 - IHI = 41 - JLO = 8 - JHI = 91 - ENDIF - - SUM = 0.0D0 - SUM2 = 0.0D0 - SUM3 = 0.0D0 - NVAL = 0 - - DO I = ILO,IHI - DO J = JLO, JHI - K = ( J - 1 )*NX + I - IF( OUT(K) .NE. VAL__BADD ) THEN - SUM = SUM + OUT(K) - SUM2 = SUM2 + OUT(K)**2 - SUM3 = SUM3 + VOUT(K) - NVAL = NVAL + 1 - END IF - END DO - END DO - - SUM = SUM/NVAL - REALVAR = SUM2/NVAL - SUM*SUM - MEANVAR = SUM3/NVAL - IF( ABS( REALVAR - MEANVAR ) .GT. - : 0.05*( REALVAR + MEANVAR ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', REALVAR ) - CALL MSG_SETD( 'W', MEANVAR ) - CALL ERR_REP( ' ', 'Real variance is ^V - estimate is ^W.', - : STATUS ) - END IF - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test11 failed', STATUS ) - END IF - - END - - - SUBROUTINE TEST12( NDIM, SPREAD, PARAMS, STATUS ) - IMPLICIT NONE - INCLUDE 'SAE_PAR' - INCLUDE 'AST_PAR' - INCLUDE 'PRM_PAR' - - INTEGER SPREAD, STATUS, NDIM - - INTEGER SIZE - PARAMETER( SIZE = 20000 ) - - INTEGER NX1, NY1 - PARAMETER( NX1 = SIZE ) - PARAMETER( NY1 = 1 ) - - INTEGER NX2, NY2 - PARAMETER( NX2 = SIZE/200 ) - PARAMETER( NY2 = 200 ) - - DOUBLE PRECISION SIGMA - PARAMETER ( SIGMA = 0.1 ) - - REAL*8 IN( SIZE ), VIN( SIZE ) - REAL*8 OUT( SIZE ), VOUT( SIZE ) - DOUBLE PRECISION PARAMS(2), WEIGHTS( SIZE, 2 ) - DOUBLE PRECISION REALVAR,MEANVAR,SUM,SUM2,SUM3 - INTEGER MAP, LBND_IN(3), UBND_IN(3), LBND_OUT(3), UBND_OUT(3), - : FLAGS, I, J, NVAL,jlo, jhi,NX, NY, ILO, IHI, K - INTEGER*8 NUSED - - IF( STATUS .NE. SAI__OK ) RETURN - CALL AST_BEGIN( STATUS ) - - DO I = 1, SIZE - IN( I ) = 1.0D0 - VIN( I ) = SIGMA**2 - END DO - - CALL ADDNOISE( SIZE, IN, SIGMA, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - NX = NX1 - Ny = NY1 - ELSE - NX = NX2 - Ny = NY2 - END IF - - LBND_IN( 1 ) = 0 - LBND_IN( 2 ) = 1 - UBND_IN( 1 ) = NX - 1 - UBND_IN( 2 ) = NY - - LBND_OUT( 1 ) = 0 - LBND_OUT( 2 ) = 1 - UBND_OUT( 1 ) = NX - 1 - UBND_OUT( 2 ) = NY - - LBND_IN( 3 ) = 1 - UBND_IN( 3 ) = 1 - LBND_OUT( 3 ) = 1 - UBND_OUT( 3 ) = 1 - - FLAGS = AST__REBININIT + AST__REBINEND + AST__GENVAR + - : AST__CONSERVEFLUX + AST__VARWGT - - MAP = AST_ZOOMMAP( NDIM, 0.5D0, ' ', STATUS ) - CALL AST_REBINSEQD( MAP, 0.0D0, ndim, LBND_IN, UBND_IN, IN, VIN, - : spread, PARAMS, FLAGS, 0.01D0, 50, VAL__BADD, - : ndim, LBND_OUT, UBND_OUT, LBND_IN, UBND_IN, - : OUT, VOUT, WEIGHTS, NUSED, STATUS ) - - IF( NDIM .EQ. 1 ) THEN - ILO = 6 - IHI = NINT(0.45*NX1) - JLO = 1 - JHI = 1 - ELSE - ILO = 6 - IHI = 41 - JLO = 8 - JHI = 91 - ENDIF - - SUM = 0.0D0 - SUM2 = 0.0D0 - SUM3 = 0.0D0 - NVAL = 0 - - DO I = ILO,IHI - DO J = JLO, JHI - K = ( J - 1 )*NX + I - IF( OUT(K) .NE. VAL__BADD ) THEN - SUM = SUM + OUT(K) - SUM2 = SUM2 + OUT(K)**2 - SUM3 = SUM3 + VOUT(K) - NVAL = NVAL + 1 - END IF - END DO - END DO - - SUM = SUM/NVAL - REALVAR = SUM2/NVAL - SUM*SUM - MEANVAR = SUM3/NVAL - IF( ABS( REALVAR - MEANVAR ) .GT. - : 0.05*( REALVAR + MEANVAR ) ) THEN - STATUS = SAI__ERROR - CALL MSG_SETD( 'V', REALVAR ) - CALL MSG_SETD( 'W', MEANVAR ) - CALL ERR_REP( ' ', 'Real variance is ^V - estimate is ^W.', - : STATUS ) - END IF - - CALL AST_END( STATUS ) - IF( STATUS .NE. SAI__OK ) THEN - CALL ERR_REP( ' ', 'test12 failed', STATUS ) - END IF - - END - - diff --git a/ast/ast_tester/testregions.f b/ast/ast_tester/testregions.f deleted file mode 100644 index 201ab17..0000000 --- a/ast/ast_tester/testregions.f +++ /dev/null @@ -1,4032 +0,0 @@ - program testregions - implicit none - include 'SAE_PAR' - integer status - - status = sai__ok - -c call ast_watchmemory( 282905 ) - - call ast_begin( status ) - call checkConvex( status ) - call checkRemoveRegions( status ) - call checkInterval( status ) - call checkEllipse( status ) - call checkPrism( status ) - call checkPolygon( status ) - call checkCircle( status ) - call checkBox( status ) - call checkNullRegion( status ) - call generalChecks( status ) - call checkCmpRegion( status ) - call checkPointList( status ) - - call ast_end( status ) - -c call ast_activememory( 'testregions' ) - - if( status .eq. sai__ok ) then - write(*,*) 'All Region tests passed' - else - write(*,*) 'Region tests failed' - end if - - end - - - subroutine generalChecks( status ) - implicit none - include 'AST_PAR' - include 'PRM_PAR' - include 'SAE_PAR' - - integer status, frm1, frm2, frm3, reg1, reg2, reg3, reg4, reg5 - double precision lbnd(3), ubnd(3), p1(2), p2(2) - - if( status .ne.sai__ok ) return - - call ast_begin( status ) - - - - lbnd(1) = 0.0D0 - lbnd(2) = AST__BAD - ubnd(1) = AST__BAD - ubnd(2) = 0.0D0 - frm1 = ast_frame( 2, ' ', status ) - reg1 = ast_interval( frm1, lbnd, ubnd, AST__NULL, ' ', status ) - - call ast_getregionbounds( reg1, lbnd, ubnd, status ) - if( lbnd(1) .ne. 0.0D0 ) call stopit( status, 'General 1' ) - if( lbnd(2) .gt. 0.99*val__mind ) call stopit( status, - : 'General 2' ) - if( ubnd(1) .lt. 0.99*val__maxd ) call stopit( status, - : 'General 3' ) - if( ubnd(2) .ne. 0.0D0 ) call stopit( status, 'General 4' ) - - - - p1(1) = 0.0D0 - p1(2) = 0.0D0 - p2(1) = 1.0D0 - reg2 = ast_circle( frm1, 1, p1, p2, AST__NULL, ' ', status ) - - call ast_getregionbounds( reg2, lbnd, ubnd, status ) - if( lbnd(1) .ne. -1.0D0 ) call stopit( status, 'General 5' ) - if( lbnd(2) .ne. -1.0D0 ) call stopit( status, 'General 6' ) - if( ubnd(1) .ne. 1.0D0 ) call stopit( status, 'General 7' ) - if( ubnd(2) .ne. 1.0D0 ) call stopit( status, 'General 8' ) - - - - reg3 = ast_cmpregion( reg1, reg2, AST__OR, ' ', status ) - - call ast_getregionbounds( reg3, lbnd, ubnd, status ) - if( lbnd(1) .ne. -1.0D0 ) call stopit( status, 'General 9' ) - if( lbnd(2) .gt. 0.99*val__mind ) call stopit( status, - : 'General 10' ) - if( ubnd(1) .lt. 0.99*val__maxd ) call stopit( status, - : 'General 11' ) - if( ubnd(2) .ne. 1.0D0 ) call stopit( status, 'General 12' ) - - - - lbnd(1) = -1.0D0 - ubnd(1) = 1.0D0 - frm2 = ast_frame( 1, ' ', status ) - reg4 = ast_interval( frm2, lbnd, ubnd, AST__NULL, ' ', status ) - - call ast_getregionbounds( reg4, lbnd, ubnd, status ) - if( lbnd(1) .ne. -1.0D0 ) call stopit( status, 'General 13' ) - if( ubnd(1) .ne. 1.0D0 ) call stopit( status, 'General 14' ) - - - - reg5 = ast_prism( reg3, reg4, ' ', status ) - - call ast_getregionbounds( reg5, lbnd, ubnd, status ) - if( lbnd(1) .ne. -1.0D0 ) call stopit( status, 'General 15' ) - if( lbnd(2) .gt. 0.99*val__mind ) call stopit( status, - : 'General 16' ) - if( ubnd(1) .lt. 0.99*val__maxd ) call stopit( status, - : 'General 17' ) - if( ubnd(2) .ne. 1.0D0 ) call stopit( status, 'General 18' ) - if( lbnd(3) .ne. -1.0D0 ) call stopit( status, 'General 19' ) - if( ubnd(3) .ne. 1.0D0 ) call stopit( status, 'General 20' ) - - - - call ast_negate( reg2, status ) - reg3 = ast_cmpregion( reg1, reg2, AST__OR, ' ', status ) - - call ast_getregionbounds( reg3, lbnd, ubnd, status ) - if( lbnd(1) .gt. 0.99*val__mind ) call stopit( status, - : 'General 21' ) - if( lbnd(2) .gt. 0.99*val__mind ) call stopit( status, - : 'General 22' ) - if( ubnd(1) .lt. 0.99*val__maxd ) call stopit( status, - : 'General 23' ) - if( ubnd(2) .lt. 0.99*val__maxd ) call stopit( status, - : 'General 24' ) - - - reg5 = ast_prism( reg3, reg4, ' ', status ) - - call ast_getregionbounds( reg5, lbnd, ubnd, status ) - if( lbnd(1) .gt. 0.99*val__mind ) call stopit( status, - : 'General 25' ) - if( lbnd(2) .gt. 0.99*val__mind ) call stopit( status, - : 'General 26' ) - if( ubnd(1) .lt. 0.99*val__maxd ) call stopit( status, - : 'General 27' ) - if( ubnd(2) .lt. 0.99*val__maxd ) call stopit( status, - : 'General 28' ) - if( lbnd(3) .ne. -1.0D0 ) call stopit( status, 'General 29' ) - if( ubnd(3) .ne. 1.0D0 ) call stopit( status, 'General 30' ) - - - reg3 = ast_cmpregion( reg1, reg2, AST__AND, ' ', status ) - - call ast_getregionbounds( reg3, lbnd, ubnd, status ) - if( lbnd(1) .ne. 0.0D0 ) call stopit( status, 'General 31' ) - if( lbnd(2) .gt. 0.99*val__mind ) call stopit( status, - : 'General 32' ) - if( ubnd(1) .lt. 0.99*val__maxd ) call stopit( status, - : 'General 33' ) - if( ubnd(2) .ne. 0.0D0 ) call stopit( status, 'General 34' ) - - - - reg5 = ast_prism( reg3, reg4, ' ', status ) - - call ast_getregionbounds( reg5, lbnd, ubnd, status ) - if( lbnd(1) .ne. 0.0D0 ) call stopit( status, 'General 35' ) - if( lbnd(2) .gt. 0.99*val__mind ) call stopit( status, - : 'General 36' ) - if( ubnd(1) .lt. 0.99*val__maxd ) call stopit( status, - : 'General 37' ) - if( ubnd(2) .ne. 0.0D0 ) call stopit( status, 'General 38' ) - if( lbnd(3) .ne. -1.0D0 ) call stopit( status, 'General 39' ) - if( ubnd(3) .ne. 1.0D0 ) call stopit( status, 'General 40' ) - - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'General tests failed' - - end - - - - - subroutine checkInterval( status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - - integer status, frm1, frm2, frm3, unc, int1, int2, int3, int4, - : int5, frm4, map, outperm(6), inperm(6), pm, reg - double precision lbnd(3), ubnd(3), p(5,3), q(5,3),in(4,3),out(4,3) - double precision xin(9), yin(9), xout(9), yout(9) - - logical hasframeset - - if( status .ne.sai__ok ) return - - call ast_begin( status ) - - frm1 = ast_skyframe( ' ', status ) - frm2 = ast_specframe( 'Unit=Angstrom', status ) - frm3 = ast_cmpframe( frm1, frm2, ' ', status ) - - if( ast_getc( frm1, 'InternalUnit(1)', status ) .ne. 'rad' ) - : call stopit( status, 'InternalUnit 1' ) - if( ast_getc( frm1, 'InternalUnit(2)', status ) .ne. 'rad' ) - : call stopit( status, 'InternalUnit 2' ) - if( ast_getc( frm2, 'InternalUnit(1)', status ) .ne. 'Angstrom' ) - : call stopit( status, 'InternalUnit 3' ) - if( ast_getc( frm3, 'InternalUnit(1)', status ) .ne. 'rad' ) - : call stopit( status, 'InternalUnit 4' ) - if( ast_getc( frm3, 'InternalUnit(2)', status ) .ne. 'rad' ) - : call stopit( status, 'InternalUnit 5' ) - if( ast_getc( frm3, 'InternalUnit(3)', status ) .ne. 'Angstrom' ) - : call stopit( status, 'InternalUnit 6' ) - - lbnd( 1 ) = AST__BAD - lbnd( 2 ) = AST__BAD - lbnd( 3 ) = 5000.0 - ubnd( 1 ) = AST__BAD - ubnd( 2 ) = AST__BAD - ubnd( 3 ) = 6000.0 - - int1 = ast_interval( frm3, lbnd, ubnd, AST__NULL, ' ', status ) - call checkdump( int1, 'checkdump int1', status ) - - p(1,1) = 0.0 ! On boundary - p(1,2) = 0.0 - p(1,3) = 5000.0 - p(2,1) = 2.0 ! On boundary - p(2,2) = -1.0 - p(2,3) = 6000.0 - p(3,1) = -2.0 ! Inside - p(3,2) = 1.0 - p(3,3) = 5999.0 - p(4,1) = 2.0 ! Outside - p(4,2) = -2.0 - p(4,3) = 6010.0 - p(5,1) = 1.0 ! Outside - p(5,2) = -1.0 - p(5,3) = 4910.0 - - call ast_trann( int1, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. p(1,1)) call stopit( status, 'Interval 1' ) - if( q(1,2) .ne. p(1,2)) call stopit( status, 'Interval 1b' ) - if( q(1,3) .ne. p(1,3)) call stopit( status, 'Interval 1c' ) - if( q(2,1) .ne. p(2,1)) call stopit( status, 'Interval 2' ) - if( q(2,2) .ne. p(2,2)) call stopit( status, 'Interval 2b' ) - if( q(2,3) .ne. p(2,3)) call stopit( status, 'Interval 2c' ) - if( q(3,1) .ne. p(3,1)) call stopit( status, 'Interval 3' ) - if( q(3,2) .ne. p(3,2)) call stopit( status, 'Interval 3b' ) - if( q(3,3) .ne. p(3,3)) call stopit( status, 'Interval 3c' ) - if( q(4,1) .ne. AST__BAD ) call stopit( status, 'Interval 4' ) - if( q(4,2) .ne. AST__BAD ) call stopit( status, 'Interval 4b' ) - if( q(4,3) .ne. AST__BAD ) call stopit( status, 'Interval 4c' ) - if( q(5,1) .ne. AST__BAD ) call stopit( status, 'Interval 5' ) - if( q(5,2) .ne. AST__BAD ) call stopit( status, 'Interval 5b' ) - if( q(5,3) .ne. AST__BAD ) call stopit( status, 'Interval 5c' ) - - call ast_negate( int1, status ) - call ast_trann( int1, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. p(1,1)) call stopit( status, 'Interval 6' ) - if( q(1,2) .ne. p(1,2)) call stopit( status, 'Interval 6b' ) - if( q(1,3) .ne. p(1,3)) call stopit( status, 'Interval 6c' ) - if( q(2,1) .ne. p(2,1)) call stopit( status, 'Interval 7' ) - if( q(2,2) .ne. p(2,2)) call stopit( status, 'Interval 7b' ) - if( q(2,3) .ne. p(2,3)) call stopit( status, 'Interval 7c' ) - if( q(3,1) .ne. AST__BAD) call stopit( status, 'Interval 8' ) - if( q(3,2) .ne. AST__BAD) call stopit( status, 'Interval 8b' ) - if( q(3,3) .ne. AST__BAD) call stopit( status, 'Interval 8c' ) - if( q(4,1) .ne. p(4,1) ) call stopit( status, 'Interval 9' ) - if( q(4,2) .ne. p(4,2) ) call stopit( status, 'Interval 9b' ) - if( q(4,3) .ne. p(4,3) ) call stopit( status, 'Interval 9c' ) - if( q(5,1) .ne. p(5,1) ) call stopit( status, 'Interval 10' ) - if( q(5,2) .ne. p(5,2) ) call stopit( status, 'Interval 10b' ) - if( q(5,3) .ne. p(5,3) ) call stopit( status, 'Interval 10c' ) - - call ast_set( int1, 'closed=0,negated=0', status ) - call ast_trann( int1, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. AST__BAD ) call stopit( status, 'Interval 11' ) - if( q(1,2) .ne. AST__BAD ) call stopit( status, 'Interval 11b' ) - if( q(1,3) .ne. AST__BAD ) call stopit( status, 'Interval 11c' ) - if( q(2,1) .ne. AST__BAD ) call stopit( status, 'Interval 12' ) - if( q(2,2) .ne. AST__BAD ) call stopit( status, 'Interval 12b' ) - if( q(2,3) .ne. AST__BAD ) call stopit( status, 'Interval 12c' ) - if( q(3,1) .ne. p(3,1)) call stopit( status, 'Interval 13' ) - if( q(3,2) .ne. p(3,2)) call stopit( status, 'Interval 13b' ) - if( q(3,3) .ne. p(3,3)) call stopit( status, 'Interval 13c' ) - if( q(4,1) .ne. AST__BAD ) call stopit( status, 'Interval 14' ) - if( q(4,2) .ne. AST__BAD ) call stopit( status, 'Interval 14b' ) - if( q(4,3) .ne. AST__BAD ) call stopit( status, 'Interval 14c' ) - if( q(5,1) .ne. AST__BAD ) call stopit( status, 'Interval 15' ) - if( q(5,2) .ne. AST__BAD ) call stopit( status, 'Interval 15b' ) - if( q(5,3) .ne. AST__BAD ) call stopit( status, 'Interval 15c' ) - - call ast_negate( int1, status ) - call ast_trann( int1, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. AST__BAD) call stopit( status, 'Interval 16' ) - if( q(1,2) .ne. AST__BAD) call stopit( status, 'Interval 16b' ) - if( q(1,3) .ne. AST__BAD) call stopit( status, 'Interval 16c' ) - if( q(2,1) .ne. AST__BAD) call stopit( status, 'Interval 17' ) - if( q(2,2) .ne. AST__BAD) call stopit( status, 'Interval 17b' ) - if( q(2,3) .ne. AST__BAD) call stopit( status, 'Interval 17c' ) - if( q(3,1) .ne. AST__BAD) call stopit( status, 'Interval 18' ) - if( q(3,2) .ne. AST__BAD) call stopit( status, 'Interval 18b' ) - if( q(3,3) .ne. AST__BAD) call stopit( status, 'Interval 18c' ) - if( q(4,1) .ne. p(4,1) ) call stopit( status, 'Interval 19' ) - if( q(4,2) .ne. p(4,2) ) call stopit( status, 'Interval 19b' ) - if( q(4,3) .ne. p(4,3) ) call stopit( status, 'Interval 19c' ) - if( q(5,1) .ne. p(5,1) ) call stopit( status, 'Interval 11' ) - if( q(5,2) .ne. p(5,2) ) call stopit( status, 'Interval 11b' ) - if( q(5,3) .ne. p(5,3) ) call stopit( status, 'Interval 11c' ) - - - lbnd( 1 ) = AST__BAD - lbnd( 2 ) = AST__BAD - lbnd( 3 ) = 6000.0 - ubnd( 1 ) = AST__BAD - ubnd( 2 ) = AST__BAD - ubnd( 3 ) = 5000.0 - - int2 = ast_interval( frm3, lbnd, ubnd, AST__NULL, ' ', status ) - call checkdump( int2, 'checkdump int2', status ) - - p(1,1) = 0.0 ! On boundary - p(1,2) = 0.0 - p(1,3) = 5000.0 - p(2,1) = 2.0 ! On boundary - p(2,2) = -1.0 - p(2,3) = 6000.0 - p(3,1) = -2.0 ! Outside - p(3,2) = 1.0 - p(3,3) = 5999.0 - p(4,1) = 2.0 ! Inside - p(4,2) = -2.0 - p(4,3) = 6010.0 - p(5,1) = 1.0 ! Inside - p(5,2) = -1.0 - p(5,3) = 4910.0 - - call ast_negate( int2, status ) - call ast_trann( int2, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. p(1,1)) call stopit( status, 'Interval B 1' ) - if( q(1,2) .ne. p(1,2)) call stopit( status, 'Interval B 1b' ) - if( q(1,3) .ne. p(1,3)) call stopit( status, 'Interval B 1c' ) - if( q(2,1) .ne. p(2,1)) call stopit( status, 'Interval B 2' ) - if( q(2,2) .ne. p(2,2)) call stopit( status, 'Interval B 2b' ) - if( q(2,3) .ne. p(2,3)) call stopit( status, 'Interval B 2c' ) - if( q(3,1) .ne. p(3,1)) call stopit( status, 'Interval B 3' ) - if( q(3,2) .ne. p(3,2)) call stopit( status, 'Interval B 3b' ) - if( q(3,3) .ne. p(3,3)) call stopit( status, 'Interval B 3c' ) - if( q(4,1) .ne. AST__BAD ) call stopit( status, 'Interval B 4' ) - if( q(4,2) .ne. AST__BAD ) call stopit( status, 'Interval B 4b' ) - if( q(4,3) .ne. AST__BAD ) call stopit( status, 'Interval B 4c' ) - if( q(5,1) .ne. AST__BAD ) call stopit( status, 'Interval B 5' ) - if( q(5,2) .ne. AST__BAD ) call stopit( status, 'Interval B 5b' ) - if( q(5,3) .ne. AST__BAD ) call stopit( status, 'Interval B 5c' ) - - call ast_negate( int2, status ) - call ast_trann( int2, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. p(1,1)) call stopit( status, 'Interval B 6' ) - if( q(1,2) .ne. p(1,2)) call stopit( status, 'Interval B 6b' ) - if( q(1,3) .ne. p(1,3)) call stopit( status, 'Interval B 6c' ) - if( q(2,1) .ne. p(2,1)) call stopit( status, 'Interval B 7' ) - if( q(2,2) .ne. p(2,2)) call stopit( status, 'Interval B 7b' ) - if( q(2,3) .ne. p(2,3)) call stopit( status, 'Interval B 7c' ) - if( q(3,1) .ne. AST__BAD) call stopit( status, 'Interval B 8' ) - if( q(3,2) .ne. AST__BAD) call stopit( status, 'Interval B 8b' ) - if( q(3,3) .ne. AST__BAD) call stopit( status, 'Interval B 8c' ) - if( q(4,1) .ne. p(4,1) ) call stopit( status, 'Interval B 9' ) - if( q(4,2) .ne. p(4,2) ) call stopit( status, 'Interval B 9b' ) - if( q(4,3) .ne. p(4,3) ) call stopit( status, 'Interval B 9c' ) - if( q(5,1) .ne. p(5,1) ) call stopit( status, 'Interval B 10' ) - if( q(5,2) .ne. p(5,2) ) call stopit( status, 'Interval B 10b' ) - if( q(5,3) .ne. p(5,3) ) call stopit( status, 'Interval B 10c' ) - - call ast_set( int2, 'closed=0,negated=1', status ) - call ast_trann( int2, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. AST__BAD ) call stopit( status, 'Interval B 11' ) - if( q(1,2) .ne. AST__BAD ) call stopit( status, 'Interval B 11b' ) - if( q(1,3) .ne. AST__BAD ) call stopit( status, 'Interval B 11c' ) - if( q(2,1) .ne. AST__BAD ) call stopit( status, 'Interval B 12' ) - if( q(2,2) .ne. AST__BAD ) call stopit( status, 'Interval B 12b' ) - if( q(2,3) .ne. AST__BAD ) call stopit( status, 'Interval B 12c' ) - if( q(3,1) .ne. p(3,1)) call stopit( status, 'Interval B 13' ) - if( q(3,2) .ne. p(3,2)) call stopit( status, 'Interval B 13b' ) - if( q(3,3) .ne. p(3,3)) call stopit( status, 'Interval B 13c' ) - if( q(4,1) .ne. AST__BAD ) call stopit( status, 'Interval B 14' ) - if( q(4,2) .ne. AST__BAD ) call stopit( status, 'Interval B 14b' ) - if( q(4,3) .ne. AST__BAD ) call stopit( status, 'Interval B 14c' ) - if( q(5,1) .ne. AST__BAD ) call stopit( status, 'Interval B 15' ) - if( q(5,2) .ne. AST__BAD ) call stopit( status, 'Interval B 15b' ) - if( q(5,3) .ne. AST__BAD ) call stopit( status, 'Interval B 15c' ) - - call ast_negate( int2, status ) - call ast_trann( int2, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. AST__BAD) call stopit( status, 'Interval B 16' ) - if( q(1,2) .ne. AST__BAD) call stopit( status, 'Interval B 16b' ) - if( q(1,3) .ne. AST__BAD) call stopit( status, 'Interval B 16c' ) - if( q(2,1) .ne. AST__BAD) call stopit( status, 'Interval B 17' ) - if( q(2,2) .ne. AST__BAD) call stopit( status, 'Interval B 17b' ) - if( q(2,3) .ne. AST__BAD) call stopit( status, 'Interval B 17c' ) - if( q(3,1) .ne. AST__BAD) call stopit( status, 'Interval B 18' ) - if( q(3,2) .ne. AST__BAD) call stopit( status, 'Interval B 18b' ) - if( q(3,3) .ne. AST__BAD) call stopit( status, 'Interval B 18c' ) - if( q(4,1) .ne. p(4,1) ) call stopit( status, 'Interval B 19' ) - if( q(4,2) .ne. p(4,2) ) call stopit( status, 'Interval B 19b' ) - if( q(4,3) .ne. p(4,3) ) call stopit( status, 'Interval B 19c' ) - if( q(5,1) .ne. p(5,1) ) call stopit( status, 'Interval B 11' ) - if( q(5,2) .ne. p(5,2) ) call stopit( status, 'Interval B 11b' ) - if( q(5,3) .ne. p(5,3) ) call stopit( status, 'Interval B 11c' ) - - - - - lbnd( 1 ) = AST__BAD - lbnd( 2 ) = AST__BAD - lbnd( 3 ) = 5000.0 - ubnd( 1 ) = 0.5 - ubnd( 2 ) = AST__BAD - ubnd( 3 ) = AST__BAD - - int3 = ast_interval( frm3, lbnd, ubnd, AST__NULL, ' ', status ) - - call checkdump( int3, 'checkdump int3', status ) - - p(1,1) = 0.0 ! On boundary - p(1,2) = 0.0 - p(1,3) = 5000.0 - p(2,1) = 0.5 ! On boundary - p(2,2) = -1.0 - p(2,3) = 6000.0 - p(3,1) = -2.0 ! Inside - p(3,2) = 0.4 - p(3,3) = 5999.0 - p(4,1) = 2.0 ! Outside - p(4,2) = -2.0 - p(4,3) = 6010.0 - p(5,1) = 0.0 ! Outside - p(5,2) = -3.0 - p(5,3) = 4910.0 - - call ast_trann( int3, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. p(1,1)) call stopit( status, 'Interval C 1' ) - if( q(1,2) .ne. p(1,2)) call stopit( status, 'Interval C 1b' ) - if( q(1,3) .ne. p(1,3)) call stopit( status, 'Interval C 1c' ) - if( q(2,1) .ne. p(2,1)) call stopit( status, 'Interval C 2' ) - if( q(2,2) .ne. p(2,2)) call stopit( status, 'Interval C 2b' ) - if( q(2,3) .ne. p(2,3)) call stopit( status, 'Interval C 2c' ) - if( q(3,1) .ne. p(3,1)) call stopit( status, 'Interval C 3' ) - if( q(3,2) .ne. p(3,2)) call stopit( status, 'Interval C 3b' ) - if( q(3,3) .ne. p(3,3)) call stopit( status, 'Interval C 3c' ) - if( q(4,1) .ne. AST__BAD ) call stopit( status, 'Interval C 4' ) - if( q(4,2) .ne. AST__BAD ) call stopit( status, 'Interval C 4b' ) - if( q(4,3) .ne. AST__BAD ) call stopit( status, 'Interval C 4c' ) - if( q(5,1) .ne. AST__BAD ) call stopit( status, 'Interval C 5' ) - if( q(5,2) .ne. AST__BAD ) call stopit( status, 'Interval C 5b' ) - if( q(5,3) .ne. AST__BAD ) call stopit( status, 'Interval C 5c' ) - - call ast_negate( int3, status ) - call ast_trann( int3, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. p(1,1)) call stopit( status, 'Interval C 6' ) - if( q(1,2) .ne. p(1,2)) call stopit( status, 'Interval C 6b' ) - if( q(1,3) .ne. p(1,3)) call stopit( status, 'Interval C 6c' ) - if( q(2,1) .ne. p(2,1)) call stopit( status, 'Interval C 7' ) - if( q(2,2) .ne. p(2,2)) call stopit( status, 'Interval C 7b' ) - if( q(2,3) .ne. p(2,3)) call stopit( status, 'Interval C 7c' ) - if( q(3,1) .ne. AST__BAD) call stopit( status, 'Interval C 8' ) - if( q(3,2) .ne. AST__BAD) call stopit( status, 'Interval C 8b' ) - if( q(3,3) .ne. AST__BAD) call stopit( status, 'Interval C 8c' ) - if( q(4,1) .ne. p(4,1) ) call stopit( status, 'Interval C 9' ) - if( q(4,2) .ne. p(4,2) ) call stopit( status, 'Interval C 9b' ) - if( q(4,3) .ne. p(4,3) ) call stopit( status, 'Interval C 9c' ) - if( q(5,1) .ne. p(5,1) ) call stopit( status, 'Interval C 10' ) - if( q(5,2) .ne. p(5,2) ) call stopit( status, 'Interval C 10b' ) - if( q(5,3) .ne. p(5,3) ) call stopit( status, 'Interval C 10c' ) - - call ast_set( int3, 'closed=0,negated=0', status ) - call ast_trann( int3, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. AST__BAD ) call stopit( status, 'Interval C 11' ) - if( q(1,2) .ne. AST__BAD ) call stopit( status, 'Interval C 11b' ) - if( q(1,3) .ne. AST__BAD ) call stopit( status, 'Interval C 11c' ) - if( q(2,1) .ne. AST__BAD ) call stopit( status, 'Interval C 12' ) - if( q(2,2) .ne. AST__BAD ) call stopit( status, 'Interval C 12b' ) - if( q(2,3) .ne. AST__BAD ) call stopit( status, 'Interval C 12c' ) - if( q(3,1) .ne. p(3,1)) call stopit( status, 'Interval C 13' ) - if( q(3,2) .ne. p(3,2)) call stopit( status, 'Interval C 13b' ) - if( q(3,3) .ne. p(3,3)) call stopit( status, 'Interval C 13c' ) - if( q(4,1) .ne. AST__BAD ) call stopit( status, 'Interval C 14' ) - if( q(4,2) .ne. AST__BAD ) call stopit( status, 'Interval C 14b' ) - if( q(4,3) .ne. AST__BAD ) call stopit( status, 'Interval C 14c' ) - if( q(5,1) .ne. AST__BAD ) call stopit( status, 'Interval C 15' ) - if( q(5,2) .ne. AST__BAD ) call stopit( status, 'Interval C 15b' ) - if( q(5,3) .ne. AST__BAD ) call stopit( status, 'Interval C 15c' ) - - call ast_negate( int3, status ) - call ast_trann( int3, 5, 3, 5, p, .true., 3, 5, q, status ) - if( q(1,1) .ne. AST__BAD) call stopit( status, 'Interval C 16' ) - if( q(1,2) .ne. AST__BAD) call stopit( status, 'Interval C 16b' ) - if( q(1,3) .ne. AST__BAD) call stopit( status, 'Interval C 16c' ) - if( q(2,1) .ne. AST__BAD) call stopit( status, 'Interval C 17' ) - if( q(2,2) .ne. AST__BAD) call stopit( status, 'Interval C 17b' ) - if( q(2,3) .ne. AST__BAD) call stopit( status, 'Interval C 17c' ) - if( q(3,1) .ne. AST__BAD) call stopit( status, 'Interval C 18' ) - if( q(3,2) .ne. AST__BAD) call stopit( status, 'Interval C 18b' ) - if( q(3,3) .ne. AST__BAD) call stopit( status, 'Interval C 18c' ) - if( q(4,1) .ne. p(4,1) ) call stopit( status, 'Interval C 19' ) - if( q(4,2) .ne. p(4,2) ) call stopit( status, 'Interval C 19b' ) - if( q(4,3) .ne. p(4,3) ) call stopit( status, 'Interval C 19c' ) - if( q(5,1) .ne. p(5,1) ) call stopit( status, 'Interval C 11' ) - if( q(5,2) .ne. p(5,2) ) call stopit( status, 'Interval C 11b' ) - if( q(5,3) .ne. p(5,3) ) call stopit( status, 'Interval C 11c' ) - - - - lbnd( 1 ) = AST__BAD - lbnd( 2 ) = 0.0 - lbnd( 3 ) = AST__BAD - ubnd( 1 ) = AST__BAD - ubnd( 2 ) = -1.0 - ubnd( 3 ) = 6000.0 - - call ast_setl( int3, 'Negated', .false., status ) - int4 = ast_interval( frm3, lbnd, ubnd, AST__NULL, ' ', status ) - if( ast_overlap( int3, int4, status ) .ne. 4 ) - : call stopit( status, 'Interval overlap 1' ) - - call ast_negate( int3, status ) - if( ast_overlap( int3, int4, status ) .ne. 4 ) - : call stopit( status, 'Interval overlap 2' ) - - call ast_negate( int4, status ) - if( ast_overlap( int3, int4, status ) .ne. 4 ) - : call stopit( status, 'Interval overlap 3' ) - - call ast_negate( int3, status ) - if( ast_overlap( int3, int4, status ) .ne. 4 ) - : call stopit( status, 'Interval overlap 4' ) - - - lbnd( 1 ) = 0.6 - lbnd( 2 ) = 0.0 - lbnd( 3 ) = AST__BAD - ubnd( 1 ) = AST__BAD - ubnd( 2 ) = -1.0 - ubnd( 3 ) = 6000.0 - - int4 = ast_interval( frm3, lbnd, ubnd, AST__NULL, ' ', status ) - if( ast_overlap( int3, int4, status ) .ne. 1 ) - : call stopit( status, 'Interval overlap 5' ) - - call ast_negate( int3, status ) - if( ast_overlap( int3, int4, status ) .ne. 3 ) - : call stopit( status, 'Interval overlap 6' ) - - call ast_negate( int4, status ) - if( ast_overlap( int3, int4, status ) .ne. 4 ) - : call stopit( status, 'Interval overlap 7' ) - - call ast_negate( int3, status ) - if( ast_overlap( int3, int4, status ) .ne. 2 ) - : call stopit( status, 'Interval overlap 8' ) - - - int4 = ast_copy( int3, status ) - if( ast_overlap( int3, int4, status ) .ne. 5 ) - : call stopit( status, 'Interval overlap 9' ) - - call ast_negate( int4, status ) - if( ast_overlap( int3, int4, status ) .ne. 6 ) - : call stopit( status, 'Interval overlap 10' ) - - - -* Changing the number of axes in the Interval. - - frm1 = ast_frame( 2, 'Domain=A', status ) - - lbnd(1) = 0.0 - lbnd(2) = 0.0 - ubnd(1) = 0.01 - ubnd(2) = 0.01 - unc = ast_box( frm1, 0, lbnd, ubnd, AST__NULL, ' ', status ) - - lbnd(1) = -2.0 - lbnd(2) = 0.5 - ubnd(1) = 0.0 - ubnd(2) = AST__BAD - int1 = ast_interval( frm1, lbnd, ubnd, unc, ' ', status ) - - outperm(1) = 2 - outperm(2) = -1 - outperm(3) = 1 - - inperm(1) = 3 - inperm(2) = 1 - - pm = ast_permmap( 2, inperm, 3, outperm, 0.0D0, ' ', status ) - - frm2 = ast_frame( 3, 'Domain=B', status ) - reg = ast_mapregion( int1, pm, frm2, status ) - - if( .not. ast_isainterval( reg, status ) ) call stopit( status, - : 'Int: perm check 1' ) - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Int: perm check 2' ) - if( ast_geti( reg, 'naxes', status ) .ne. 3 ) call stopit( status, - : 'Int: perm check 3' ) - - in( 1, 1 ) = 0.0 ! Outside - in( 1, 2 ) = 0.0 - in( 1, 3 ) = -0.5 - in( 2, 1 ) = 20.0 ! Inside - in( 2, 2 ) = 0.0 - in( 2, 3 ) = -0.5 - in( 3, 1 ) = 20.0 ! Outside - in( 3, 2 ) = -10.0 - in( 3, 3 ) = 0.5 - in( 4, 1 ) = 20.0 ! Boundary - in( 4, 2 ) = 0.0 - in( 4, 3 ) = -2.0 - - call ast_trann( reg, 4, 3, 4, in, .true., 3, 4, out, status ) - - if( out( 1, 1 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 1' ) - if( out( 1, 2 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 2' ) - if( out( 1, 3 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 3' ) - - if( out( 2, 1 ) .ne. in( 2,1 )) call stopit( status, 'Int: pc 4' ) - if( out( 2, 2 ) .ne. in( 2,2 )) call stopit( status, 'Int: pc 5' ) - if( out( 2, 3 ) .ne. in( 2,3 )) call stopit( status, 'Int: pc 6' ) - - if( out( 3, 1 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 7' ) - if( out( 3, 2 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 8' ) - if( out( 3, 3 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 9' ) - - if( out( 4, 1 ) .ne. in( 4,1 )) call stopit( status, 'Int: pc 10') - if( out( 4, 2 ) .ne. in( 4,2 )) call stopit( status, 'Int: pc 11') - if( out( 4, 3 ) .ne. in( 4,3 )) call stopit( status, 'Int: pc 12') - - - - outperm(1) = 2 - outperm(2) = -1 - outperm(3) = 1 - - inperm(1) = 3 - inperm(2) = 1 - - pm = ast_permmap( 2, inperm, 3, outperm, 1.5D0, ' ', status ) - - frm2 = ast_frame( 3, 'Domain=B', status ) - reg = ast_mapregion( int1, pm, frm2, status ) - - if( .not. ast_isainterval( reg, status ) ) call stopit( status, - : 'Int: perm check 4' ) - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Int: perm check 5' ) - if( ast_geti( reg, 'naxes', status ) .ne. 3 ) call stopit( status, - : 'Int: perm check 6' ) - - in( 1, 1 ) = 20.0 ! Outside - in( 1, 2 ) = 0.0 - in( 1, 3 ) = -0.5 - in( 2, 1 ) = 20.0 ! Inside - in( 2, 2 ) = 1.5 - in( 2, 3 ) = -0.5 - in( 3, 1 ) = 20.0 ! Outside - in( 3, 2 ) = 1.6 - in( 3, 3 ) = -0.5 - in( 4, 1 ) = 0.5 ! Boundary - in( 4, 2 ) = 1.5 - in( 4, 3 ) = 0.0 - - call ast_trann( reg, 4, 3, 4, in, .true., 3, 4, out, status ) - - if( out( 1, 1 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 13') - if( out( 1, 2 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 14') - if( out( 1, 3 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 15') - - if( out( 2, 1 ) .ne. in( 2,1 )) call stopit( status, 'Int: pc 16') - if( out( 2, 2 ) .ne. in( 2,2 )) call stopit( status, 'Int: pc 17') - if( out( 2, 3 ) .ne. in( 2,3 )) call stopit( status, 'Int: pc 18') - - if( out( 3, 1 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 19') - if( out( 3, 2 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 20') - if( out( 3, 3 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 21') - - if( out( 4, 1 ) .ne. in( 4,1 )) call stopit( status, 'Int: pc 22') - if( out( 4, 2 ) .ne. in( 4,2 )) call stopit( status, 'Int: pc 23') - if( out( 4, 3 ) .ne. in( 4,3 )) call stopit( status, 'Int: pc 24') - - - - call ast_negate( int1, status ) - call ast_set( int1, 'closed=0', status ) - reg = ast_mapregion( int1, pm, frm2, status ) - call ast_negate( int1, status ) - call ast_set( int1, 'closed=1', status ) - - if( .not. ast_isainterval( reg, status ) ) call stopit( status, - : 'Int: perm check 7' ) - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Int: perm check 8' ) - if( ast_geti( reg, 'naxes', status ) .ne. 3 ) call stopit( status, - : 'Int: perm check 9' ) - - in( 1, 1 ) = 20.0 ! Inside - in( 1, 2 ) = 0.0 - in( 1, 3 ) = -0.5 - in( 2, 1 ) = 20.0 ! Outside - in( 2, 2 ) = 1.5 - in( 2, 3 ) = -0.5 - in( 3, 1 ) = 20.0 ! Inside - in( 3, 2 ) = 1.6 - in( 3, 3 ) = -0.5 - in( 4, 1 ) = 0.5 ! Outside - in( 4, 2 ) = 1.5 - in( 4, 3 ) = 0.0 - - call ast_trann( reg, 4, 3, 4, in, .true., 3, 4, out, status ) - - if( out( 1, 1 ) .ne. in( 1,1 )) call stopit( status, 'Int: pc 25') - if( out( 1, 2 ) .ne. in( 1,2 )) call stopit( status, 'Int: pc 26') - if( out( 1, 3 ) .ne. in( 1,3 )) call stopit( status, 'Int: pc 27') - - if( out( 2, 1 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 28') - if( out( 2, 2 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 29') - if( out( 2, 3 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 30') - - if( out( 3, 1 ) .ne. in( 3,1 )) call stopit( status, 'Int: pc 31') - if( out( 3, 2 ) .ne. in( 3,2 )) call stopit( status, 'Int: pc 32') - if( out( 3, 3 ) .ne. in( 3,3 )) call stopit( status, 'Int: pc 33') - - if( out( 4, 1 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 34') - if( out( 4, 2 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 35') - if( out( 4, 3 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 36') - - - - - frm1 = ast_frame( 3, 'Domain=A', status ) - - - lbnd(1) = 0.0 - lbnd(2) = 0.0 - lbnd(3) = 0.0 - ubnd(1) = 0.01 - ubnd(2) = 0.01 - ubnd(3) = 0.01 - unc = ast_box( frm1, 0, lbnd, ubnd, AST__NULL, ' ', status ) - - lbnd(1) = 0.5 - lbnd(2) = -1.0 - lbnd(3) = -2.0 - ubnd(1) = AST__BAD - ubnd(2) = AST__BAD - ubnd(3) = 0.0 - - int1 = ast_interval( frm1, lbnd, ubnd, unc, ' ', status ) - - outperm(1) = 1 - outperm(2) = 3 - - inperm(1) = 1 - inperm(2) = -1 - inperm(3) = 2 - - pm = ast_permmap( 3, inperm, 2, outperm, 1.0D0, ' ', status ) - - frm2 = ast_frame( 2, 'Domain=B', status ) - reg = ast_mapregion( int1, pm, frm2, status ) - - if( .not. ast_isainterval( reg, status ) ) call stopit( status, - : 'Int: perm check 10' ) - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Int: perm check 11' ) - if( ast_geti( reg, 'naxes', status ) .ne. 2 ) call stopit( status, - : 'Int: perm check 12' ) - - xin( 1 ) = 0.4 ! Out - yin( 1 ) = -1.0 - xin( 2 ) = 1.0 ! Out - yin( 2 ) = 0.1 - xin( 3 ) = 1.0 ! Out - yin( 3 ) = -2.1 - xin( 4 ) = 0.5 ! Boundary - yin( 4 ) = -1.0 - xin( 5 ) = 10.0 ! In - yin( 5 ) = -0.1 - xin( 6 ) = 0.55 ! Boundary - yin( 6 ) = -2.0 - - - call ast_tran2( reg, 6, xin, yin, .true., xout, yout, status ) - - if( xout( 1 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 37') - if( yout( 1 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 38') - if( xout( 2 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 39') - if( yout( 2 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 40') - if( xout( 3 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 41') - if( yout( 3 ) .ne. AST__BAD ) call stopit( status, 'Int: pc 42') - if( xout( 4 ) .ne. xin( 4 ) ) call stopit( status, 'Int: pc 43') - if( yout( 4 ) .ne. yin( 4 ) ) call stopit( status, 'Int: pc 44') - if( xout( 5 ) .ne. xin( 5 ) ) call stopit( status, 'Int: pc 45') - if( yout( 5 ) .ne. yin( 5 ) ) call stopit( status, 'Int: pc 46') - if( xout( 6 ) .ne. xin( 6 ) ) call stopit( status, 'Int: pc 47') - if( yout( 6 ) .ne. yin( 6 ) ) call stopit( status, 'Int: pc 48') - - - pm = ast_permmap( 3, inperm, 2, outperm, -2.0D0, ' ', status ) - reg = ast_mapregion( int1, pm, frm2, status ) - - if( .not. ast_isanullregion( reg, status ) ) call stopit( status, - : 'Int: perm check 13' ) - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Int: perm check 14' ) - if( ast_geti( reg, 'naxes', status ) .ne. 2 ) call stopit( status, - : 'Int: perm check 15' ) - if( ast_getl( reg, 'negated', status ) ) call stopit( status, - : 'Int: perm check 16' ) - - - call ast_negate( int1, status ) - reg = ast_mapregion( int1, pm, frm2, status ) - - if( .not. ast_isanullregion( reg, status ) ) call stopit( status, - : 'Int: perm check 17' ) - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Int: perm check 18' ) - if( ast_geti( reg, 'naxes', status ) .ne. 2 ) call stopit( status, - : 'Int: perm check 19' ) - if( .NOT.ast_getl( reg, 'negated', status ) ) call stopit( status, - : 'Int: perm check 20' ) - - - - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'Interval tests failed' - - end - - - subroutine checkPolygon( status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - - integer status, frm, unc, pol1, pol2, f2, r2, r3, r4 - double precision pi, p(5,2), q(5,2), p1(2), p2(2) - double precision xin(2), yin(2), xout(2), yout(2), lbnd(5), - : ubnd(5) - logical hasframeset - - - if( status .ne.sai__ok ) return - - call ast_begin( status ) - - pi = acos( -1.0d0 ) - - frm = ast_SkyFrame( ' ', status ) - - p1(1) = 0.0 - p1(2) = 0.5*pi - p2(1) = 0.01 - unc = ast_circle( frm, 1, p1, p2, AST__NULL, ' ', status ) - - p(1,1) = 0.0 - p(1,2) = 0.0 - p(2,1) = 1.0 - p(2,2) = 0.5*pi - p(3,1) = 0.5*pi - p(3,2) = 0.25*pi - p(4,1) = 0.25*pi - p(4,2) = 0.0 - p(5,1) = 0.25*pi - p(5,2) = 0.25*pi - - pol1 = ast_polygon( frm, 5, 5, p, unc, 'closed=0', status ) - - call checkdump( pol1, 'checkdump pol1', status ) - - - p(1,1) = 0.0 ! On boundary - p(1,2) = 0.0 - p(2,1) = 1.0 ! Outside - p(2,2) = 0.5*pi + 0.1 - p(3,1) = 0.5*pi - 0.1 ! Inside - p(3,2) = 0.25*pi - p(4,1) = 0.0 ! On boundary - p(4,2) = 0.1 - p(5,1) = 0.25*pi ! Inside - p(5,2) = 0.25*pi + 0.1 - - call ast_trann( pol1, 5, 2, 5, p, .true., 2, 5, q, status ) - - if( q(1,1) .ne. AST__BAD ) call stopit( status, 'Poly 1' ) - if( q(1,2) .ne. AST__BAD ) call stopit( status, 'Poly 1b' ) - if( q(2,1) .ne. AST__BAD ) call stopit( status, 'Poly 2' ) - if( q(2,2) .ne. AST__BAD ) call stopit( status, 'Poly 2b' ) - if( q(3,1) .ne. p(3,1) ) call stopit( status, 'Poly 3' ) - if( q(3,2) .ne. p(3,2) ) call stopit( status, 'Poly 3b' ) - if( q(4,1) .ne. AST__BAD ) call stopit( status, 'Poly 4' ) - if( q(4,2) .ne. AST__BAD ) call stopit( status, 'Poly 4b' ) - if( q(5,1) .ne. p(5,1) ) call stopit( status, 'Poly 5' ) - if( q(5,2) .ne. p(5,2) ) call stopit( status, 'Poly 5b' ) - - - call ast_setl( pol1, 'closed', .true., status ) - call ast_trann( pol1, 5, 2, 5, p, .true., 2, 5, q, status ) - if( q(1,1) .ne. p(1,1) ) call stopit( status, 'Poly 6' ) - if( q(1,2) .ne. p(1,2) ) call stopit( status, 'Poly 6b' ) - if( q(2,1) .ne. AST__BAD ) call stopit( status, 'Poly 7' ) - if( q(2,2) .ne. AST__BAD ) call stopit( status, 'Poly 7b' ) - if( q(3,1) .ne. p(3,1) ) call stopit( status, 'Poly 8' ) - if( q(3,2) .ne. p(3,2) ) call stopit( status, 'Poly 8b' ) - if( q(4,1) .ne. p(4,1) ) call stopit( status, 'Poly 9' ) - if( q(4,2) .ne. p(4,2) ) call stopit( status, 'Poly 9b' ) - if( q(5,1) .ne. p(5,1) ) call stopit( status, 'Poly 10' ) - if( q(5,2) .ne. p(5,2) ) call stopit( status, 'Poly 10b' ) - - call ast_setl( pol1, 'negated', .true., status ) - call ast_trann( pol1, 5, 2, 5, p, .true., 2, 5, q, status ) - if( q(1,1) .ne. p(1,1) ) call stopit( status, 'Poly 11' ) - if( q(1,2) .ne. p(1,2) ) call stopit( status, 'Poly 11b' ) - if( q(2,1) .ne. p(2,1) ) call stopit( status, 'Poly 12' ) - if( q(2,2) .ne. p(2,2) ) call stopit( status, 'Poly 12b' ) - if( q(3,1) .ne. AST__BAD ) call stopit( status, 'Poly 13' ) - if( q(3,2) .ne. AST__BAD ) call stopit( status, 'Poly 13b' ) - if( q(4,1) .ne. p(4,1) ) call stopit( status, 'Poly 14' ) - if( q(4,2) .ne. p(4,2) ) call stopit( status, 'Poly 14b' ) - if( q(5,1) .ne. AST__BAD ) call stopit( status, 'Poly 15' ) - if( q(5,2) .ne. AST__BAD ) call stopit( status, 'Poly 15b' ) - - call ast_setl( pol1, 'closed', .false., status ) - call ast_trann( pol1, 5, 2, 5, p, .true., 2, 5, q, status ) - if( q(1,1) .ne. AST__BAD ) call stopit( status, 'Poly 16' ) - if( q(1,2) .ne. AST__BAD ) call stopit( status, 'Poly 16b' ) - if( q(2,1) .ne. p(2,1) ) call stopit( status, 'Poly 17' ) - if( q(2,2) .ne. p(2,2) ) call stopit( status, 'Poly 17b' ) - if( q(3,1) .ne. AST__BAD ) call stopit( status, 'Poly 18' ) - if( q(3,2) .ne. AST__BAD ) call stopit( status, 'Poly 18b' ) - if( q(4,1) .ne. AST__BAD ) call stopit( status, 'Poly 19' ) - if( q(4,2) .ne. AST__BAD ) call stopit( status, 'Poly 19b' ) - if( q(5,1) .ne. AST__BAD ) call stopit( status, 'Poly 20' ) - if( q(5,2) .ne. AST__BAD ) call stopit( status, 'Poly 20b' ) - - - if( hasframeset( pol1, status ) ) then - call stopit( status, 'pol1 has FrameSet' ) - end if - - call ast_setc( pol1, 'system', 'fk5', status ) - call checkdump( pol1, 'checkdump pol2', status ) - - if( .not. hasframeset( pol1, status ) ) then - call stopit( status, 'pol1 does not have FrameSet' ) - end if - - call ast_seti( pol1, 'meshsize', 30, status ) - - pol2 = ast_simplify( pol1, status ) - - if( hasframeset( pol2, status ) ) then - call stopit( status, 'pol2 has FrameSet' ) - end if - - - - frm = ast_SkyFrame( ' ', status ) - - p1(1) = 0.0 - p1(2) = 0.5*pi - p2(1) = 0.01 - unc = ast_circle( frm, 1, p1, p2, AST__NULL, ' ', status ) - - p(1,1) = 1.5*pi - p(1,2) = 0.4*pi - p(2,1) = pi - p(2,2) = 0.4*pi - p(3,1) = 0.5*pi - p(3,2) = 0.4*pi - p(4,1) = 0.0 - p(4,2) = 0.4*pi - - pol1 = ast_polygon( frm, 4, 5, p, unc, ' ', status ) - - xin(1) = 0.0 - yin(1) = 0.5*pi - call ast_tran2( pol1, 1, xin, yin, .true., xout, yout, status ) - - if( xout(1) .ne. xin(1) ) call stopit( status, 'Poly 21' ) - if( yout(1) .ne. yin(1) ) call stopit( status, 'Poly 22' ) - - call ast_getregionbounds( pol1, lbnd, ubnd, status ) - if( abs( lbnd(1) ) .gt. 1.0E-10 ) call stopit( status, 'Poly 23' ) - if( abs( lbnd(2) - 1.25663708 ) .gt. 1.0E-6 ) - : call stopit( status, 'Poly 24' ) - if( abs( ubnd(1) - 6.28318531 ) .gt. 1.0E-6 ) - : call stopit( status, 'Poly 25' ) - if( abs( ubnd(2) - 1.57079633 ) .gt. 1.0E-6 ) - : call stopit( status, 'Poly 26' ) - - - f2 = ast_specframe( 'Unit=Angstrom', status ) - lbnd( 1 ) = 5000.0 - ubnd( 1 ) = 6000.0 - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r3 = ast_prism( pol1, r2, ' ', status ) - r4 = ast_Simplify( r3, status ) - - call ast_getregionbounds( r4, lbnd, ubnd, status ) - if( abs( lbnd(1) ) .gt. 1.0E-10 ) call stopit( status, 'Poly 27' ) - if( abs( lbnd(2) - 1.25663708 ) .gt. 1.0E-6 ) - : call stopit( status, 'Poly 28' ) - if( abs( ubnd(1) - 6.28318531 ) .gt. 1.0E-6 ) - : call stopit( status, 'Poly 29' ) - if( abs( ubnd(2) - 1.57079633 ) .gt. 1.0E-6 ) - : call stopit( status, 'Poly 30' ) - if( abs( lbnd(3) - 5000.0 ) .gt. 1.0E-10 ) - : call stopit( status, 'Poly 31' ) - if( abs( ubnd(3) - 6000.0 ) .gt. 1.0E-6 ) - : call stopit( status, 'Poly 32' ) - - - - - - - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'Polygon tests failed' - - end - - - - - - subroutine checkBox( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'PRM_PAR' - - integer status, box1, frm1, i, fc, fs, map1, perm(3), frm2, box3, - : box2, frm3, map2, res, j, bfrm, cfrm, reg1, map, - : npoint - double precision p1(3), p2(3), v2, xin(9), yin(9), xout(9), - : yout(9),in(4,3),out(4,3),matrix(9),grid(250,2) - character*(AST__SZCHR) t1, t2, cards(9)*80 - logical hasframeset - - integer lbnd_in(2), ubnd_in(2) - real rin(5,5),image(50,50) - integer outperm(3), inperm(3),pm, reg, unc - - - data cards /'CTYPE1 = ''RA---TAN''', - : 'CTYPE2 = ''DEC--TAN''', - : 'CRPIX1 = 100', - : 'CRPIX2 = 100', - : 'CRVAL1 = 71.619724', - : 'CRVAL2 = 42.971835', - : ' ', - : 'CDELT1 = 0.6', - : 'CDELT2 = 0.6' / - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - - fc = ast_fitschan( ast_null, ast_null, ' ', status ) - do i = 1, 9 - call ast_putfits( fc, cards(i), .false., status ) - end do - call ast_clear( fc, 'card', status ) - fs = ast_read( fc, status ) - - frm1 = ast_getframe( fs, ast__current, status ) - call ast_seti( frm1, 'digits(1)', 12, status ) - - p1( 1 ) = 1.25 - p1( 2 ) = 0.75 - p2( 1 ) = 1.5 - p2( 2 ) = 0.5 - - box1 = ast_box( frm1, 0, p1, p2, AST__NULL, ' ', status ) - call checkdump( box1, 'checkdump box1', status ) - - if( ast_getc( box1, 'system', status ) .ne. 'ICRS' ) - : call stopit( status, 'box1 system is not ICRS' ) - - call ast_setc( box1, 'system', 'galactic', status ) - - perm(1)=2 - perm(2)=1 - call ast_permaxes( box1, perm, status ) - - box3 = ast_copy( box1, status ) - - yin(1) = 2.82175432250852 - xin(1) = -0.0269096590283195 - yin(2) = 2.70798275154741 - xin(2) = 0.2467384819891 - - call ast_tran2( box1, 2, xin, yin, .true., xout, yout, status ) - - if( abs( yout(1)-2.82175422 ) .gt. 1.0E-6 ) - : call stopit( status, 'error 1' ) - if( abs( xout(1)+0.0269096587 ) .gt. 1.0E-7 ) - : call stopit( status, 'error 2' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, 'error 3' ) - if( xout(2) .ne. AST__BAD ) call stopit( status, 'error 4' ) - - - if( .not. ast_getl( box3, 'Adaptive', status ) ) - : call stopit( status, 'error 4a' ) - - call ast_setl( box3, 'Adaptive', .false., status ) - call ast_setc( box3, 'system', 'icrs', status ) - - yin(1) = 2.82175432250852 - xin(1) = -0.0269096590283195 - yin(2) = 2.70798275154741 - xin(2) = 0.2467384819891 - - call ast_tran2( box3, 2, xin, yin, .true., xout, yout, status ) - - if( abs( yout(1)-2.82175422 ) .gt. 1.0E-8 ) - : call stopit( status, 'error 1' ) - if( abs( xout(1)+0.0269096587 ) .gt. 1.0E-8 ) - : call stopit( status, 'error 2' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, 'error 4b' ) - if( xout(2) .ne. AST__BAD ) call stopit( status, 'error 4c' ) - - call ast_clear( box3, 'system', status ) - - yin(1) = 2.82175432250852 - xin(1) = -0.0269096590283195 - yin(2) = 2.70798275154741 - xin(2) = 0.2467384819891 - - call ast_tran2( box3, 2, xin, yin, .true., xout, yout, status ) - - if( abs( yout(1)-2.82175422 ) .gt. 1.0E-8 ) - : call stopit( status, 'error 1' ) - if( abs( xout(1)+0.0269096587 ) .gt. 1.0E-8 ) - : call stopit( status, 'error 2' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, 'error 4d' ) - if( xout(2) .ne. AST__BAD ) call stopit( status, 'error 4e' ) - - box2 = ast_simplify( box1, status ) - - call ast_setc( box1, 'system', 'icrs', status ) - call ast_permaxes( box1, perm, status ) - - t1 = ast_format( frm1, 1, 0.25D0, status ) - call ast_annul( frm1, status ) - t2 = ast_format( box1, 1, 0.25D0, status ) - if( t1 .ne. t2 ) call stopit( status, - : 'ast_format is different for frm1 and box1' ) - - i = ast_unformat( box1, 1, t2, v2, status ) - if( abs( v2 - 0.25 ) .GT. 1.0E-10 ) then - call stopit( status, 'ast_unformat failed for box1' ) - end if - - if( ast_getc( box1, 'System', status ) .ne. 'ICRS' ) then - call stopit( status, 'Box1(b) system is not ICRS' ) - end if - - if( ast_getc( box1, 'Equinox', status ) .ne. '2000.0' ) then - call stopit( status, 'Box1 equinox is not 2000.0' ) - end if - - if( .not. ast_getl( box1, 'Closed', status ) ) then - call stopit( status, 'Box1 closed is not .true.' ) - end if - - xin( 1 ) = 1.25 - yin( 1 ) = 0.75 - xin( 2 ) = 1.0 - yin( 2 ) = 1.0 - xin( 3 ) = 1.0 - yin( 3 ) = 0.5 - xin( 4 ) = 1.5 - yin( 4 ) = 0.5 - xin( 5 ) = 1.5 - yin( 5 ) = 1.0 - xin( 6 ) = 1.0 - yin( 6 ) = 1.2 - xin( 7 ) = 0.8 - yin( 7 ) = 0.5 - xin( 8 ) = 1.5 - yin( 8 ) = 0.45 - xin( 9 ) = 1.501 - yin( 9 ) = 1.0 - - call ast_tran2( BOX1, 9, xin, yin, .true., xout, yout, status ) - - if( xout( 1 ) .ne. 1.25 ) call stopit( status, 'error A1' ) - if( yout( 1 ) .ne. 0.75 ) call stopit( status, 'error A2' ) - if( xout( 2 ) .ne. 1.0 ) call stopit( status, 'error A3' ) - if( yout( 2 ) .ne. 1.0 ) call stopit( status, 'error A4' ) - if( xout( 3 ) .ne. 1.0 ) call stopit( status, 'error A5' ) - if( yout( 3 ) .ne. 0.5 ) call stopit( status, 'error A6' ) - if( xout( 4 ) .ne. 1.5 ) call stopit( status, 'error A7' ) - if( yout( 4 ) .ne. 0.5 ) call stopit( status, 'error A8' ) - if( xout( 5 ) .ne. 1.5 ) call stopit( status, 'error A9' ) - if( yout( 5 ) .ne. 1.0 ) call stopit( status, 'error A10' ) - if( xout( 6 ) .ne. AST__BAD ) call stopit( status, 'error A11' ) - if( yout( 6 ) .ne. AST__BAD ) call stopit( status, 'error A12' ) - if( xout( 7 ) .ne. AST__BAD ) call stopit( status, 'error A13' ) - if( yout( 7 ) .ne. AST__BAD ) call stopit( status, 'error A14' ) - if( xout( 8 ) .ne. AST__BAD ) call stopit( status, 'error A15' ) - if( yout( 8 ) .ne. AST__BAD ) call stopit( status, 'error A16' ) - if( xout( 9 ) .ne. AST__BAD ) call stopit( status, 'error A17' ) - if( yout( 9 ) .ne. AST__BAD ) call stopit( status, 'error A18' ) - - call ast_tran2( box1, 9, xin, yin, .false., xout, yout, status ) - - if( xout( 1 ) .ne. 1.25 ) call stopit( status, 'error B1' ) - if( yout( 1 ) .ne. 0.75 ) call stopit( status, 'error B2' ) - if( xout( 2 ) .ne. 1.0 ) call stopit( status, 'error B3' ) - if( yout( 2 ) .ne. 1.0 ) call stopit( status, 'error B4' ) - if( xout( 3 ) .ne. 1.0 ) call stopit( status, 'error B5' ) - if( yout( 3 ) .ne. 0.5 ) call stopit( status, 'error B6' ) - if( xout( 4 ) .ne. 1.5 ) call stopit( status, 'error B7' ) - if( yout( 4 ) .ne. 0.5 ) call stopit( status, 'error B8' ) - if( xout( 5 ) .ne. 1.5 ) call stopit( status, 'error B9' ) - if( yout( 5 ) .ne. 1.0 ) call stopit( status, 'error B10' ) - if( xout( 6 ) .ne. AST__BAD ) call stopit( status, 'error B11' ) - if( yout( 6 ) .ne. AST__BAD ) call stopit( status, 'error B12' ) - if( xout( 7 ) .ne. AST__BAD ) call stopit( status, 'error B13' ) - if( yout( 7 ) .ne. AST__BAD ) call stopit( status, 'error B14' ) - if( xout( 8 ) .ne. AST__BAD ) call stopit( status, 'error B15' ) - if( yout( 8 ) .ne. AST__BAD ) call stopit( status, 'error B16' ) - if( xout( 9 ) .ne. AST__BAD ) call stopit( status, 'error B17' ) - if( yout( 9 ) .ne. AST__BAD ) call stopit( status, 'error B18' ) - - call ast_negate( box1, status ) - call ast_tran2( box1, 9, xin, yin, .true., xout, yout, status ) - - if( xout( 1 ) .ne. AST__BAD ) call stopit( status, 'error C1' ) - if( yout( 1 ) .ne. AST__BAD ) call stopit( status, 'error C2' ) - if( xout( 2 ) .ne. 1.0 ) call stopit( status, 'error C3' ) - if( yout( 2 ) .ne. 1.0 ) call stopit( status, 'error C4' ) - if( xout( 3 ) .ne. 1.0 ) call stopit( status, 'error C5' ) - if( yout( 3 ) .ne. 0.5 ) call stopit( status, 'error C6' ) - if( xout( 4 ) .ne. 1.5 ) call stopit( status, 'error C7' ) - if( yout( 4 ) .ne. 0.5 ) call stopit( status, 'error C8' ) - if( xout( 5 ) .ne. 1.5 ) call stopit( status, 'error C9' ) - if( yout( 5 ) .ne. 1.0 ) call stopit( status, 'error C10' ) - if( xout( 6 ) .ne. 1.0 ) call stopit( status, 'error C11' ) - if( yout( 6 ) .ne. 1.2 ) call stopit( status, 'error C12' ) - if( xout( 7 ) .ne. 0.8 ) call stopit( status, 'error C13' ) - if( yout( 7 ) .ne. 0.5 ) call stopit( status, 'error C14' ) - if( xout( 8 ) .ne. 1.5 ) call stopit( status, 'error C15' ) - if( yout( 8 ) .ne. 0.45 ) call stopit( status, 'error C16' ) - if( xout( 9 ) .ne. 1.501 ) call stopit( status, 'error C17' ) - if( yout( 9 ) .ne. 1.0 ) call stopit( status, 'error C18' ) - - call ast_setl( box1, 'closed', .false., status ) - call ast_negate( box1, status ) - call ast_tran2( box1, 9, xin, yin, .true., xout, yout, status ) - - if( xout( 1 ) .ne. 1.25 ) call stopit( status, 'error D1' ) - if( yout( 1 ) .ne. 0.75 ) call stopit( status, 'error D2' ) - if( xout( 2 ) .ne. AST__BAD ) call stopit( status, 'error D3' ) - if( yout( 2 ) .ne. AST__BAD ) call stopit( status, 'error D4' ) - if( xout( 3 ) .ne. AST__BAD ) call stopit( status, 'error D5' ) - if( yout( 3 ) .ne. AST__BAD ) call stopit( status, 'error D6' ) - if( xout( 4 ) .ne. AST__BAD ) call stopit( status, 'error D7' ) - if( yout( 4 ) .ne. AST__BAD ) call stopit( status, 'error D8' ) - if( xout( 5 ) .ne. AST__BAD ) call stopit( status, 'error D9' ) - if( yout( 5 ) .ne. AST__BAD ) call stopit( status, 'error D10' ) - if( xout( 6 ) .ne. AST__BAD ) call stopit( status, 'error D11' ) - if( yout( 6 ) .ne. AST__BAD ) call stopit( status, 'error D12' ) - if( xout( 7 ) .ne. AST__BAD ) call stopit( status, 'error D13' ) - if( yout( 7 ) .ne. AST__BAD ) call stopit( status, 'error D14' ) - if( xout( 8 ) .ne. AST__BAD ) call stopit( status, 'error D15' ) - if( yout( 8 ) .ne. AST__BAD ) call stopit( status, 'error D16' ) - if( xout( 9 ) .ne. AST__BAD ) call stopit( status, 'error D17' ) - if( yout( 9 ) .ne. AST__BAD ) call stopit( status, 'error D18' ) - - call ast_setl( box1, 'Negated', .true., status ) - call ast_tran2( box1, 9, xin, yin, .true., xout, yout, status ) - - if( xout( 1 ) .ne. AST__BAD ) call stopit( status, 'error E1' ) - if( yout( 1 ) .ne. AST__BAD ) call stopit( status, 'error E2' ) - if( xout( 2 ) .ne. AST__BAD ) call stopit( status, 'error E3' ) - if( yout( 2 ) .ne. AST__BAD ) call stopit( status, 'error E4' ) - if( xout( 3 ) .ne. AST__BAD ) call stopit( status, 'error E5' ) - if( yout( 3 ) .ne. AST__BAD ) call stopit( status, 'error E6' ) - if( xout( 4 ) .ne. AST__BAD ) call stopit( status, 'error E7' ) - if( yout( 4 ) .ne. AST__BAD ) call stopit( status, 'error E8' ) - if( xout( 5 ) .ne. AST__BAD ) call stopit( status, 'error E9' ) - if( yout( 5 ) .ne. AST__BAD ) call stopit( status, 'error E10' ) - if( xout( 6 ) .ne. 1.0 ) call stopit( status, 'error E11' ) - if( yout( 6 ) .ne. 1.2 ) call stopit( status, 'error E12' ) - if( xout( 7 ) .ne. 0.8 ) call stopit( status, 'error E13' ) - if( yout( 7 ) .ne. 0.5 ) call stopit( status, 'error E14' ) - if( xout( 8 ) .ne. 1.5 ) call stopit( status, 'error E15' ) - if( yout( 8 ) .ne. 0.45 ) call stopit( status, 'error E16' ) - if( xout( 9 ) .ne. 1.501 ) call stopit( status, 'error E17' ) - if( yout( 9 ) .ne. 1.0 ) call stopit( status, 'error E18' ) - - call ast_clear( box1, 'Negated', status ) - call ast_clear( box1, 'Closed', status ) - - call ast_addframe( fs, ast__current, ast_unitmap(2,' ',status), - : box1, status ) - - - - map1 = ast_getmapping( fs, ast__current, ast__current, status ) - - if( .not.ast_isaregion( map1, status ) ) - : call stopit( status, 'map1 is not a Region' ) - - call ast_setl( fs, 'Negated', .true., status ) - if( ast_getl( box1, 'Negated', status ) ) - : call stopit( status, - : 'FrameSet Negated attribute reflected in box1' ) - call ast_clear( fs, 'Negated', status ) - - map1 = ast_getmapping( fs, ast__base, ast__current, status ) - - call ast_tran2( map1, 9, xin, yin, .false., xout, yout, status ) - - if( xout( 1 ) .eq. AST__BAD ) call stopit( status, 'error F1' ) - if( yout( 1 ) .eq. AST__BAD ) call stopit( status, 'error F2' ) - if( xout( 2 ) .eq. AST__BAD ) call stopit( status, 'error F3' ) - if( yout( 2 ) .eq. AST__BAD ) call stopit( status, 'error F4' ) - if( xout( 3 ) .eq. AST__BAD ) call stopit( status, 'error F5' ) - if( yout( 3 ) .eq. AST__BAD ) call stopit( status, 'error F6' ) - if( xout( 4 ) .eq. AST__BAD ) call stopit( status, 'error F7' ) - if( yout( 4 ) .eq. AST__BAD ) call stopit( status, 'error F8' ) - if( xout( 5 ) .eq. AST__BAD ) call stopit( status, 'error F9' ) - if( yout( 5 ) .eq. AST__BAD ) call stopit( status, 'error F10' ) - if( xout( 6 ) .ne. AST__BAD ) call stopit( status, 'error F11' ) - if( yout( 6 ) .ne. AST__BAD ) call stopit( status, 'error F12' ) - if( xout( 7 ) .ne. AST__BAD ) call stopit( status, 'error F13' ) - if( yout( 7 ) .ne. AST__BAD ) call stopit( status, 'error F14' ) - if( xout( 8 ) .ne. AST__BAD ) call stopit( status, 'error F15' ) - if( yout( 8 ) .ne. AST__BAD ) call stopit( status, 'error F16' ) - if( xout( 9 ) .ne. AST__BAD ) call stopit( status, 'error F17' ) - if( yout( 9 ) .ne. AST__BAD ) call stopit( status, 'error F18' ) - - call ast_tran2( map1, 9, xout, yout, .true., xout, yout, status ) - - if( abs( xout( 1 ) - 1.25 ) .gt. 1.0D-7 ) call stopit( status, - : 'error G1' ) - if( abs( yout( 1 ) - 0.75 ) .gt. 1.0D-7 ) call stopit( status, - : 'error G2' ) - if( xout( 6 ) .ne. AST__BAD ) call stopit( status, 'error G11' ) - if( yout( 6 ) .ne. AST__BAD ) call stopit( status, 'error G12' ) - if( xout( 7 ) .ne. AST__BAD ) call stopit( status, 'error G13' ) - if( yout( 7 ) .ne. AST__BAD ) call stopit( status, 'error G14' ) - if( xout( 8 ) .ne. AST__BAD ) call stopit( status, 'error G15' ) - if( yout( 8 ) .ne. AST__BAD ) call stopit( status, 'error G16' ) - if( xout( 9 ) .ne. AST__BAD ) call stopit( status, 'error G17' ) - if( yout( 9 ) .ne. AST__BAD ) call stopit( status, 'error G18' ) - - - - - frm2 = ast_specframe( 'Unit=Angstrom', status ) - p1( 1 ) = 1000.0 - p2( 1 ) = 1100.0 - box2 = ast_box( frm2, 0, p1, p2, AST__NULL, ' ', status ) - frm3 = ast_cmpframe( box1, box2, ' ', status ) - - perm(1)=2 - perm(2)=3 - perm(3)=1 - call ast_permaxes( frm3, perm, status ) - call ast_setc( frm3, 'system(1)', 'galactic', status ) - call ast_setc( frm3, 'system(2)', 'Freq', status ) - - in( 1, 1 ) = -0.0269096590283195 ! In both boxes - in( 1, 2 ) = 2997924.58 - in( 1, 3 ) = 2.82175432250852 - in( 2, 1 ) = 0.2467384819891 ! In spec box, out sky box - in( 2, 2 ) = 2997924.58 - in( 2, 3 ) = 2.70798275154741 - in( 3, 1 ) = -0.0269096590283195 ! Out spec box in sky box - in( 3, 2 ) = 4000000.0 - in( 3, 3 ) = 2.82175432250852 - in( 4, 1 ) = 0.2467384819891 ! Out spec box, out sky box - in( 4, 2 ) = 4000000.0 - in( 4, 3 ) = 2.70798275154741 - call ast_trann( frm3, 4, 3, 4, in, .true., 3, 4, out, status ) - - if( abs( out(1,1)+0.0269096587 ) .gt. 1.0E-8 ) - : call stopit( status, 'error H1' ) - if( abs( out(1,2)-2997924.5 ) .gt. 1.0E-1 ) - : call stopit( status, 'error H2' ) - if( abs( out(1,3)-2.82175422 ) .gt. 1.0E-6 ) - : call stopit( status, 'error H3' ) - - if( out(2,1) .ne. ast__bad ) call stopit( status, 'error H4' ) - if( abs( out(2,2)-2997924.5 ) .gt. 1.0E-1 ) - : call stopit( status, 'error H5' ) - if( out(2,3) .ne. ast__bad ) call stopit( status, 'error H6' ) - - if( abs( out(3,1)+0.0269096587 ) .gt. 1.0E-8 ) - : call stopit( status, 'error H7' ) - if( out(3,2) .ne. ast__bad ) call stopit( status, 'error H8' ) - if( abs( out(3,3)-2.82175422 ) .gt. 1.0E-6 ) - : call stopit( status, 'error H9' ) - - if( out(4,1) .ne. ast__bad ) call stopit( status, 'error H10' ) - if( out(4,2) .ne. ast__bad ) call stopit( status, 'error H11' ) - if( out(4,3) .ne. ast__bad ) call stopit( status, 'error H12' ) - - if( .not. ast_getl( frm3, 'closed(1)', status ) ) - : call stopit( status, 'compound frame region is not closed' ) - - - - -C -C Testing astMapRegion -C - - frm1 = ast_frame( 3, 'Domain=A', status ) - p1(1) = 100 - p1(2) = 200 - p1(3) = 300 - p2(1) = 0 - p2(2) = 400 - p2(3) = 250 - box1 = ast_box( frm1, 0, p1, p2, AST__NULL, ' ', status ) - - frm2 = ast_frame( 3, 'Domain=B', status ) - - matrix(1) = 2.0 - matrix(2) = 0.0 - matrix(3) = 0.0 - matrix(4) = 0.0 - matrix(5) = 4.0 - matrix(6) = 0.0 - matrix(7) = 0.0 - matrix(8) = 0.0 - matrix(9) = 6.0 - - map2 = ast_matrixmap( 3, 3, 0, matrix, ' ', status ) - box2 = ast_mapregion( box1, map2, frm2, status ) - - if( ast_getc( box2, 'Domain', status ) .ne. 'B' ) then - call stopit( status, 'ast_mapregion1: Box2 domain is not B' ) - end if - - if( hasframeset( box2, status ) ) then - call stopit( status, 'ast_mapregion2: Box2 has FrameSet' ) - end if - - matrix(1) = 2.0 - matrix(2) = .1 - matrix(3) = 0.0 - matrix(4) = 0.0 - matrix(5) = 4.0 - matrix(6) = 0.0 - matrix(7) = 0.0 - matrix(8) = 0.0 - matrix(9) = 6.0 - - map2 = ast_matrixmap( 3, 3, 0, matrix, ' ', status ) - - box2 = ast_mapregion( box1, map2, frm2, status ) - - if( ast_getc( box2, 'Domain', status ) .ne. 'B' ) then - call stopit( status, 'ast_mapregion3: Box2 domain is not B' ) - end if - - if( hasframeset( box2, status ) ) then - call stopit( status, 'ast_mapregion4: Box2 has FrameSet' ) - end if - - call checkdump( box2, 'checkdump box2', status ) - - frm1 = ast_frame( 1, 'Domain=A', status ) - p1(1) = 100 - p2(1) = 0 - box1 = ast_box( frm1, 0, p1, p2, AST__NULL, ' ', status ) - - frm2 = ast_frame( 1, 'Domain=B', status ) - - map2 = ast_zoommap( 1, 2.0D0, ' ', status ) - box2 = ast_mapregion( box1, map2, frm2, status ) - - if( ast_getc( box2, 'Domain', status ) .ne. 'B' ) then - call stopit( status, 'ast_mapregion5: Box2 domain is not B' ) - end if - - if( hasframeset( box2, status ) ) then - call stopit( status, 'ast_mapregion6: Box2 has FrameSet (B)' ) - end if - - frm1 = ast_skyframe( ' ', status ) - p1(1) = 0 - p1(2) = 0 - p2(1) = 0.001 - p2(2) = 0.001 - box1 = ast_box( frm1, 0, p1, p2, AST__NULL, ' ', status ) - - frm2 = ast_copy( frm1, status ) - call ast_setd( frm2, 'skyref(1)', 0.0005D0, status ) - call ast_setc( frm2, 'skyrefis', 'origin', status ) - - fs = ast_convert( frm1, frm2, ' ', status ) - - box2 = ast_mapregion( box1, fs, frm2, status ) - - if( hasframeset( box2, status ) ) then - call stopit( status, 'ast_mapregion7: Box2 has FrameSet (C)' ) - end if - - xin( 1 ) = 0.00049 - yin( 1 ) = 0.0009 - xin( 2 ) = 0.00051 - yin( 2 ) = 0.0009 - xin( 3 ) = -0.0016 - yin( 3 ) = 0.0 - xin( 4 ) = -0.0014 - yin( 4 ) = 0.0 - xin( 5 ) = 6.2815853 - yin( 5 ) = 0.0 - xin( 6 ) = 6.2817853 - yin( 6 ) = 0.0 - - call ast_tran2( box2, 6, xin, yin, .true., xout, yout, status ) - - if( abs( xout( 1 ) - xin( 1 ) ) .gt. 1D-10 ) call stopit( status, - : 'error I1' ) - if( abs( yout( 1 ) - yin( 1 ) ) .gt. 1D-10 ) call stopit( status, - : 'error I2' ) - - if( xout(2) .ne. AST__BAD ) call stopit( status, 'error I3' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, 'error I4' ) - if( xout(5) .ne. AST__BAD ) call stopit( status, 'error I5' ) - if( yout(5) .ne. AST__BAD ) call stopit( status, 'error I6' ) - if( xout(3) .ne. AST__BAD ) call stopit( status, 'error I7' ) - if( yout(3) .ne. AST__BAD ) call stopit( status, 'error I8' ) - - if( abs( xout( 4 ) - xin( 4 ) ) .gt. 1D-10 ) call stopit( status, - : 'error I9' ) - if( abs( yout( 4 ) - yin( 4 ) ) .gt. 1D-10 ) call stopit( status, - : 'error I10' ) - if( abs( xout( 6 ) - xin( 6 ) ) .gt. 1D-10 ) call stopit( status, - : 'error I11' ) - if( abs( yout( 6 ) - yin( 6 ) ) .gt. 1D-10 ) call stopit( status, - : 'error I12' ) - - - call ast_setc( box2, 'skyrefis', 'pole', status ) - box2 = ast_Simplify( box2, status ) - - if( hasframeset( box2, status ) ) then - call stopit( status, 'ast_mapregion8: Box2 has '// - : 'FrameSet (B)' ) - end if - -C -C Testing astOverlap -C - - frm1 = ast_frame( 3, 'Domain=A', status ) - p1(1) = 100 - p1(2) = 200 - p1(3) = 300 - p2(1) = 0 - p2(2) = 400 - p2(3) = 250 - box1 = ast_box( frm1, 0, p1, p2, AST__NULL, 'closed=1', status ) - - frm2 = ast_frame( 3, 'Domain=B', status ) - box2 = ast_box( frm2, 0, p1, p2, AST__NULL, 'closed=0', status ) - - if( ast_overlap( box1, box2, status ) .ne. 0 ) then - call stopit( status, 'ast_overlap A: result should be zero' ) - end if - - if( ast_overlap( box1, box1, status ) .ne. 5 ) then - call stopit( status, 'ast_overlap B: result should be 5' ) - end if - - if( ast_overlap( box2, box2, status ) .ne. 5 ) then - call stopit( status, 'ast_overlap C: result should be 5' ) - end if - - call ast_setc( frm2, 'Domain', 'A', status ) - p1(1) = 100 - p1(2) = 200 - p1(3) = 300 - p2(1) = -100 - p2(2) = 600 - p2(3) = 400 - box2 = ast_box( frm2, 0, p1, p2, AST__NULL, ' ', status ) - - if( ast_overlap( box1, box2, status ) .ne. 2 ) then - write(*,*) 'Result is ',ast_overlap( box1, box2, status ) - call stopit( status, 'ast_overlap D: result should be 2' ) - end if - - if( ast_overlap( box2, box1, status ) .ne. 3 ) then - write(*,*) 'Result is ',ast_overlap( box2, box1, status ) - call stopit( status, 'ast_overlap E: result should be 3' ) - end if - - p1(1) = 300 - p1(2) = 200 - p1(3) = 300 - p2(1) = 201 - p2(2) = 400 - p2(3) = 250 - box2 = ast_box( frm2, 0, p1, p2, AST__NULL, ' ', status ) - - if( ast_overlap( box1, box2, status ) .ne. 1 ) then - call stopit( status, 'ast_overlap F: result should be 1' ) - end if - - if( ast_overlap( box2, box1, status ) .ne. 1 ) then - call stopit( status, 'ast_overlap G: result should be 1' ) - end if - - p1(1) = 150 - p1(2) = 200 - p1(3) = 300 - p2(1) = 50 - p2(2) = 400 - p2(3) = 250 - box2 = ast_box( frm2, 0, p1, p2, AST__NULL, ' ', status ) - - if( ast_overlap( box1, box2, status ) .ne. 4 ) then - call stopit( status, 'ast_overlap H: result should be 4' ) - end if - - if( ast_overlap( box2, box1, status ) .ne. 4 ) then - call stopit( status, 'ast_overlap I: result should be 4' ) - end if - - -* Pixel masks - frm1 = ast_frame( 2, 'Domain=A', status ) - p1(1) = 1.0 - p1(2) = 1.0 - p2(1) = 3.1 - p2(2) = 4.1 - box1 = ast_box( frm1, 0, p1, p2, AST__NULL, ' ', status ) - - lbnd_in(1) = 1 - lbnd_in(2) = 1 - ubnd_in(1) = 5 - ubnd_in(2) = 5 - - do i =1, 5 - do j = 1, 5 - rin( j,i)=1.0 - end do - end do - - res = ast_maskr( box1, AST__NULL, .false., 2, lbnd_in, ubnd_in, - : rin, VAL__BADR, status ) - - if( res .ne. 13 ) then - write(*,*) 'Res is ',res - call stopit( status, 'res should be 13' ) - end if - - do i =1, 5 - do j = 1, 5 - if( j .le. 3 .and. i .le. 4 ) then - if( rin(j,i) .NE. 1.0 ) then - write(*,*) 'rin(',j,',',i,') = ',rin(j,i) - call stopit( status, 'Above value should be 1.0' ) - end if - else - if( rin(j,i) .NE. VAL__BADR ) then - write(*,*) 'rin(',j,',',i,') = ',rin(j,i) - call stopit( status, 'Above value should be '// - : 'VAL__BADR' ) - end if - endif - end do - end do - - cards(3) = 'CRPIX1 = 20' - cards(4) = 'CRPIX2 = 20' - cards(5) = 'CRVAL1 = 0.0' - cards(6) = 'CRVAL2 = 0.0' - cards(7) = ' ' - cards(8) = 'CDELT1 = 1.6' - cards(9) = 'CDELT2 = 1.6' - - fc = ast_fitschan( ast_null, ast_null, ' ', status ) - do i = 1, 9 - call ast_putfits( fc, cards(i), .false., status ) - end do - call ast_clear( fc, 'card', status ) - fs = ast_read( fc, status ) - - p1( 1 ) = 0.13089969 ! RA at centre = 0h30m - p1( 2 ) = 0.17453293 ! Dec at centre = 10d - p2( 1 ) = -0.13089971 ! RA at corner = 23h30m - p2( 2 ) = -0.17453293 ! Dec at corner = -10d - - box1 = ast_box( fs, 0, p1, p2, AST__NULL, ' ', status ) - - do i =1, 50 - do j = 1, 50 - image( j,i)=1.0 - end do - end do - - lbnd_in(1) = 1 - lbnd_in(2) = 1 - ubnd_in(1) = 50 - ubnd_in(2) = 50 - - call ast_negate( box1, status ) - call ast_invert( fs, status ) - res = ast_maskr( box1, fs, .false., 2, lbnd_in, ubnd_in, - : image, VAL__BADR, status ) - - if( res .ne. 522 ) then - write(*,*) 'Res is ',res - call stopit( status, 'res should be 522' ) - end if - - if( image(34,42) .ne. VAL__BADR ) then - write(*,*) 'image(34,42) = ',image(34,42) - call stopit( status, 'Above value should be VAL__BADR' ) - end if - - if( image(33,42) .ne. 1.0 ) then - write(*,*) 'image(33,42) = ',image(33,42) - call stopit( status, 'Above value should be 1.0' ) - end if - - if( image(16,14) .ne. VAL__BADR ) then - write(*,*) 'image(16,14) = ',image(16,14) - call stopit( status, 'Above value should be VAL__BADR' ) - end if - - if( image(15,13) .ne. 1.0 ) then - write(*,*) 'image(15,13) = ',image(15,13) - call stopit( status, 'Above value should be 1.0' ) - end if - - -* Changing the number of axes in the Region - - frm1 = ast_frame( 2, 'Domain=A', status ) - - p1(1) = 0.0 - p1(2) = 0.0 - p2(1) = 0.01 - unc = ast_circle( frm1, 1, p1, p2, AST__NULL, ' ', status ) - - p1(1) = -1.0 - p1(2) = 1.0 - p2(1) = -2.0 - p2(2) = 1.5 - box1 = ast_box( frm1, 0, p1, p2, unc, ' ', status ) - - - outperm(1) = 2 - outperm(2) = -1 - outperm(3) = 1 - - inperm(1) = 3 - inperm(2) = 1 - - pm = ast_permmap( 2, inperm, 3, outperm, 0.0D0, ' ', status ) - - frm2 = ast_frame( 3, 'Domain=B', status ) - reg = ast_mapregion( box1, pm, frm2, status ) - - if( .not. ast_isabox( reg, status ) ) call stopit( status, - : 'Box: perm check 1' ) - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Box: perm check 2' ) - if( ast_geti( reg, 'naxes', status ) .ne. 3 ) call stopit( status, - : 'Box: perm check 3' ) - - in( 1, 1 ) = 0.0 ! Outside - in( 1, 2 ) = 0.0 - in( 1, 3 ) = 0.0 - in( 2, 1 ) = 0.7 ! Inside - in( 2, 2 ) = 0.0 - in( 2, 3 ) = -0.5 - in( 3, 1 ) = 2.0 ! Outside - in( 3, 2 ) = 0.0 - in( 3, 3 ) = -1.0 - in( 4, 1 ) = 1.5 ! Boundary - in( 4, 2 ) = 0.0 - in( 4, 3 ) = 0.0 - - call ast_trann( reg, 4, 3, 4, in, .true., 3, 4, out, status ) - - if( out( 1, 1 ) .ne. AST__BAD ) call stopit( status, 'box: pc 1' ) - if( out( 1, 2 ) .ne. AST__BAD ) call stopit( status, 'box: pc 2' ) - if( out( 1, 3 ) .ne. AST__BAD ) call stopit( status, 'box: pc 3' ) - - if( out( 2, 1 ) .ne. in( 2,1 )) call stopit( status, 'box: pc 4' ) - if( out( 2, 2 ) .ne. in( 2,2 )) call stopit( status, 'box: pc 5' ) - if( out( 2, 3 ) .ne. in( 2,3 )) call stopit( status, 'box: pc 6' ) - - if( out( 3, 1 ) .ne. AST__BAD ) call stopit( status, 'box: pc 7' ) - if( out( 3, 2 ) .ne. AST__BAD ) call stopit( status, 'box: pc 8' ) - if( out( 3, 3 ) .ne. AST__BAD ) call stopit( status, 'box: pc 9' ) - - if( out( 4, 1 ) .ne. in( 4,1 )) call stopit( status, 'box: pc 10') - if( out( 4, 2 ) .ne. in( 4,2 )) call stopit( status, 'box: pc 11') - if( out( 4, 3 ) .ne. in( 4,3 )) call stopit( status, 'box: pc 12') - - - outperm(1) = 2 - outperm(2) = -1 - outperm(3) = 1 - - inperm(1) = 3 - inperm(2) = 1 - - pm = ast_permmap( 2, inperm, 3, outperm, 1.0D0, ' ', status ) - - frm2 = ast_frame( 3, 'Domain=B', status ) - reg = ast_mapregion( box1, pm, frm2, status ) - - if( .not. ast_isabox( reg, status ) ) call stopit( status, - : 'Box: perm check 4' ) - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Box: perm check 5' ) - if( ast_geti( reg, 'naxes', status ) .ne. 3 ) call stopit( status, - : 'Box: perm check 6' ) - - in( 1, 1 ) = 0.0 ! Outside - in( 1, 2 ) = 0.0 - in( 1, 3 ) = 0.0 - in( 2, 1 ) = 0.7 ! boundary - in( 2, 2 ) = 1.0 - in( 2, 3 ) = -0.5 - in( 3, 1 ) = 0.7 ! outside - in( 3, 2 ) = 1.1 - in( 3, 3 ) = -0.5 - in( 4, 1 ) = 0.7 ! outside - in( 4, 2 ) = 0.9 - in( 4, 3 ) = -0.5 - - call ast_trann( reg, 4, 3, 4, in, .true., 3, 4, out, status ) - - if( out( 1, 1 ) .ne. AST__BAD ) call stopit( status, 'box: pc 11') - if( out( 1, 2 ) .ne. AST__BAD ) call stopit( status, 'box: pc 12') - if( out( 1, 3 ) .ne. AST__BAD ) call stopit( status, 'box: pc 13') - - if( out( 2, 1 ) .ne. in( 2,1 )) call stopit( status, 'box: pc 14') - if( out( 2, 2 ) .ne. in( 2,2 )) call stopit( status, 'box: pc 15') - if( out( 2, 3 ) .ne. in( 2,3 )) call stopit( status, 'box: pc 16') - - if( out( 3, 1 ) .ne. AST__BAD ) call stopit( status, 'box: pc 17') - if( out( 3, 2 ) .ne. AST__BAD ) call stopit( status, 'box: pc 18') - if( out( 3, 3 ) .ne. AST__BAD ) call stopit( status, 'box: pc 19') - - if( out( 4, 1 ) .ne. AST__BAD ) call stopit( status, 'box: pc 17') - if( out( 4, 2 ) .ne. AST__BAD ) call stopit( status, 'box: pc 18') - if( out( 4, 3 ) .ne. AST__BAD ) call stopit( status, 'box: pc 19') - - - - outperm(1) = 1 - - inperm(1) = 1 - inperm(2) = -1 - - pm = ast_permmap( 2, inperm, 1, outperm, 1.4D0, ' ', status ) - - frm2 = ast_frame( 1, 'Domain=B', status ) - reg = ast_mapregion( box1, pm, frm2, status ) - - if( .not. ast_isabox( reg, status ) ) call stopit( status, - : 'Box: perm check 7' ) - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Box: perm check 8' ) - if( ast_geti( reg, 'naxes', status ) .ne. 1 ) call stopit( status, - : 'Box: perm check 9' ) - - xin( 1 ) = -2.5 ! Outside - xin( 2 ) = -1.9 ! Inside - xin( 3 ) = 0.0 ! boundary - xin( 4 ) = 0.5 ! outside - - call ast_tran1( reg, 4, xin, .true., xout, status ) - - if( xout( 1 ) .ne. AST__BAD ) call stopit( status, 'box: pc 20') - if( xout( 2 ) .ne. xin(2) ) call stopit( status, 'box: pc 21') - if( xout( 3 ) .ne. xin(3) ) call stopit( status, 'box: pc 22') - if( xout( 4 ) .ne. AST__BAD ) call stopit( status, 'box: pc 23') - - - - outperm(1) = 1 - - inperm(1) = 1 - inperm(2) = -1 - - pm = ast_permmap( 2, inperm, 1, outperm, 1.6D0, ' ', status ) - frm2 = ast_frame( 1, 'Domain=B', status ) - reg = ast_mapregion( box1, pm, frm2, status ) - if( .not. ast_isanullregion( reg, status ) ) call stopit( status, - : 'Box: perm check 10' ) - - - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Box: perm check 11' ) - if( ast_geti( reg, 'naxes', status ) .ne. 1 ) call stopit( status, - : 'Box: perm check 12' ) - - xin( 1 ) = -2.5 - xin( 2 ) = -1.9 - xin( 3 ) = 0.0 - xin( 4 ) = 0.5 - - call ast_tran1( reg, 4, xin, .true., xout, status ) - - if( xout( 1 ) .ne. AST__BAD ) call stopit( status, 'box: pc 24') - if( xout( 2 ) .ne. AST__BAD ) call stopit( status, 'box: pc 25') - if( xout( 3 ) .ne. AST__BAD ) call stopit( status, 'box: pc 26') - if( xout( 4 ) .ne. AST__BAD ) call stopit( status, 'box: pc 27') - - - frm1 = ast_frame( 3, 'Domain=A', status ) - - p1(1) = 0.5 - p1(2) = -1.0 - p1(3) = -2.0 - p2(1) = 30.0 - p2(2) = 5.0 - p2(3) = 0.0 - - box1 = ast_box( frm1, 1, p1, p2, AST__NULL, ' ', status ) - - outperm(1) = 1 - outperm(2) = 3 - - inperm(1) = 1 - inperm(2) = -1 - inperm(3) = 2 - - pm = ast_permmap( 3, inperm, 2, outperm, 1.0D0, ' ', status ) - - frm2 = ast_frame( 2, 'Domain=B', status ) - reg = ast_mapregion( box1, pm, frm2, status ) - - if( .not. ast_isabox( reg, status ) ) call stopit( status, - : 'Box: perm check 13' ) - - if( hasFrameSet( reg, status ) ) call stopit( status, - : 'Box: perm check 14' ) - if( ast_geti( reg, 'naxes', status ) .ne. 2 ) call stopit( status, - : 'Box: perm check 15' ) - - xin( 1 ) = 0.4 ! Out - yin( 1 ) = -1.0 - xin( 2 ) = 1.0 ! Out - yin( 2 ) = 0.1 - xin( 3 ) = 1.0 ! Out - yin( 3 ) = -2.1 - xin( 4 ) = 0.5 ! Boundary - yin( 4 ) = -1.0 - xin( 5 ) = 10.0 ! In - yin( 5 ) = -0.1 - xin( 6 ) = 0.55 ! Boundary - yin( 6 ) = -2.0 - - - call ast_tran2( reg, 6, xin, yin, .true., xout, yout, status ) - - if( xout( 1 ) .ne. AST__BAD ) call stopit( status, 'Box: pc 37') - if( yout( 1 ) .ne. AST__BAD ) call stopit( status, 'Box: pc 38') - if( xout( 2 ) .ne. AST__BAD ) call stopit( status, 'Box: pc 39') - if( yout( 2 ) .ne. AST__BAD ) call stopit( status, 'Box: pc 40') - if( xout( 3 ) .ne. AST__BAD ) call stopit( status, 'Box: pc 41') - if( yout( 3 ) .ne. AST__BAD ) call stopit( status, 'Box: pc 42') - if( xout( 4 ) .ne. xin( 4 ) ) call stopit( status, 'Box: pc 43') - if( yout( 4 ) .ne. yin( 4 ) ) call stopit( status, 'Box: pc 44') - if( xout( 5 ) .ne. xin( 5 ) ) call stopit( status, 'Box: pc 45') - if( yout( 5 ) .ne. yin( 5 ) ) call stopit( status, 'Box: pc 46') - if( xout( 6 ) .ne. xin( 6 ) ) call stopit( status, 'Box: pc 47') - if( yout( 6 ) .ne. yin( 6 ) ) call stopit( status, 'Box: pc 48') - - cards(1) = 'CTYPE1 = ''RA---TAN''' - cards(2) = 'CTYPE2 = ''DEC--TAN''' - cards(3) = 'CRPIX1 = 20' - cards(4) = 'CRPIX2 = 20' - cards(5) = 'CRVAL1 = 0.0' - cards(6) = 'CRVAL2 = 0.0' - cards(7) = 'CROTA1 = 30.0' - cards(8) = 'CDELT1 = -0.00001' - cards(9) = 'CDELT2 = 0.00001' - - fc = ast_fitschan( ast_null, ast_null, ' ', status ) - do i = 1, 9 - call ast_putfits( fc, cards(i), .false., status ) - end do - call ast_clear( fc, 'card', status ) - fs = ast_read( fc, status ) - - bfrm = ast_getFrame( fs, AST__BASE, status ) - - p1(1) = 0.0 - p1(2) = 0.0 - p2(1) = 0.1 - unc = ast_circle( bfrm, 1, p1, p2, AST__NULL, ' ', status ) - - p1( 1 ) = 100.0 ! Pix_X at centre - p1( 2 ) = 150.0 ! Pix_Y at centre - p2( 1 ) = 150.0 ! Pix_X at corner - p2( 2 ) = 170.0 ! Pix_Y at corner - - box1 = ast_box( bfrm, 0, p1, p2, AST__NULL, ' ', status ) - - - call ast_getregionmesh( box1, .false., 250, 2, npoint, grid, - : status ) - - if( npoint .ne. 176 ) then - write(*,*) npoint - call stopit( status, 'Box: Error mesh 3' ) - endif - - if( status .ne. SAI__OK ) go to 991 - - do i = 1, npoint - if( abs( grid(i,1) - 100 ) .gt. 50.0D0 ) then - call stopit( status, 'Box: Error mesh 1' ) - else if( abs( grid(i,2) - 150 ) .gt. 20.0D0 ) then - call stopit( status, 'Box: Error mesh 2' ) - endif - enddo - - call ast_getregionmesh( box1, .true., 250, 2, npoint, grid, - : status ) - if( npoint .ne. 198 ) - : call stopit( status, 'Box: Error mesh 4' ) - - if( status .ne. SAI__OK ) go to 991 - - do i = 1, npoint - if( grid(i,1) .ne. 50.0D0 .and. grid(i,1) .ne. 150.0D0 .and. - : grid(i,2) .ne. 130.0D0 .and. grid(i,2) .ne. 170.0D0 ) then - call stopit( status, 'Box: Error mesh 5' ) - endif - enddo - - cfrm = ast_getFrame( fs, AST__CURRENT, status ) - map = ast_getmapping( fs, AST__BASE, AST__CURRENT, status ) - reg1 = ast_mapregion( box1, map, cfrm, status ) - - if( hasFrameSet( reg1, status ) ) call stopit( status, - : 'Box: poly simp 1' ) - if( .not. ast_isapolygon( reg1, status) ) call stopit( status, - : 'Box: poly simp 2' ) - - 991 continue - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'Box tests failed' - - end - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - - - logical function hasframeset( reg, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer reg, status, ch,nw - - logical fsfound, done - common /sink1com/ fsfound, done - external sink1 - - hasframeset = .false. - if( status .ne. sai__ok ) return - - - fsfound = .false. - done = .false. - ch = ast_channel( AST_NULL, sink1, ' ', STATUS ) - nw = ast_write( ch, reg, status ) - call ast_annul( ch, status ) - - hasframeset = fsfound - - end - - subroutine sink1( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - logical fsfound, done - common /sink1com/ fsfound, done - - integer status, l - character line*200 - - if( status .ne. sai__ok ) return - call ast_getline( line, l, status ) - - if( index( line( : l ),'Unc =' ) .GT. 0 ) then - done = .true. - - else if( .not. done .and. - : index( line( : l ),'FrameSet' ) .GT. 0 ) then - fsfound= .true. - end if - - end - - - - subroutine checkPointList( status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - - character fwd(1)*30,inv(1)*30 - integer status, frm, reg, reg2, reg3, reg4, mm, map - integer mdata(-1:15),lbnd,ubnd,nbad,unc - double precision pnts( 3 ), xin(3),xout(3), acc, ina, inb, outa, - : outb - data mdata /17*0/ - - if( status .ne.sai__ok ) return - - call ast_begin( status ) - frm = ast_specframe( ' ', status ) - - pnts(1)=0.0 - pnts(2)=1.0E-5 - unc = ast_box( frm, 0, pnts(1), pnts(2), AST__NULL, ' ', status ) - - pnts(1)=1.0 - pnts(2)=1.1 - reg = ast_pointlist( frm, 2, 1, 3, pnts, unc, ' ', status ) - call checkdump( reg, 'checkdump reg', status ) - - if( ast_overlap( reg, reg, status ) .ne. 5 ) then - call stopit( status, - : 'PointList: self is not identical with self' ) - end if - - reg2 = ast_copy( reg, status ) - call ast_negate( reg2, status ) - call checkdump( reg2, 'checkdump reg2', status ) - - if( ast_overlap( reg, reg2, status ) .ne. 6 ) then - call stopit( status, - : 'PointList: overlap with self-exclusion' ) - end if - - - xin( 1 ) = 1.0 - xin( 2 ) = 1.05 - xin( 3 ) = 1.1 - call ast_tran1( reg, 3, xin, .true., xout, status ) - - if( xout( 1 ) .ne. 1.0 ) then - call stopit( status, 'PointList: Error 1' ) - else if( xout( 2 ) .ne. AST__BAD ) then - call stopit( status, 'PointList: Error 2' ) - else if( xout( 3 ) .ne. 1.1 ) then - call stopit( status, 'PointList: Error 3' ) - end if - - - call ast_tran1( reg2, 3, xin, .true., xout, status ) - if( xout( 1 ) .ne. AST__BAD ) then - call stopit( status, 'PointList: Error 4' ) - else if( xout( 2 ) .ne. 1.05 ) then - call stopit( status, 'PointList: Error 5' ) - else if( xout( 3 ) .ne. AST__BAD ) then - call stopit( status, 'PointList: Error 6' ) - end if - - fwd(1) = 'y=x**2' - inv(1) = 'x=y**0.5' - mm = ast_mathmap( 1, 1, 1, fwd, 1, inv, ' ', status ) - reg3 = ast_mapregion( reg, mm, ast_frame(1,' ', status ), status ) - reg4 = ast_simplify( reg3, status ) - call checkdump( reg4, 'checkdump reg4', status ) - - xin( 1 ) = 1.21 - xin( 2 ) = 1.5 - call ast_tran1( reg4, 2, xin, .true., xout, status ) - if( xout( 1 ) .ne. 1.21 ) then - write(*,*) xout(1), ' (should be 1.21)' - call stopit( status, 'PointList: Error 7' ) - else if( xout( 2 ) .ne. AST__BAD ) then - write(*,*) xout(2), ' (should be bad)' - call stopit( status, 'PointList: Error 8' ) - end if - - - lbnd = -1 - ubnd = 15 - - ina = 1.01 - inb = 1.11 - outa = 2.0 - outb = 7.0 - map = ast_winmap( 1, ina, inb, outa, outb, ' ', status ) - - nbad = ast_maski( reg, map, .true., 1, lbnd, ubnd, mdata, 2, - : status ) - - if( nbad .ne. 2 ) then - write(*,*) 'nbad = ',nbad - call stopit( status, 'Above value should be 2' ) - end if - - if( mdata(1) .ne. 0 ) then - write(*,*) 'mdata(1) = ',mdata(1) - call stopit( status, 'Above value should be 0' ) - end if - - if( mdata(2) .ne. 2 ) then - write(*,*) 'mdata(2) = ',mdata(2) - call stopit( status, 'Above value should be 2' ) - end if - - if( mdata(3) .ne. 0 ) then - write(*,*) 'mdata(3) = ',mdata(3) - call stopit( status, 'Above value should be 0' ) - end if - - if( mdata(6) .ne. 0 ) then - write(*,*) 'mdata(6) = ',mdata(6) - call stopit( status, 'Above value should be 0' ) - end if - - if( mdata(7) .ne. 2 ) then - write(*,*) 'mdata(7) = ',mdata(7) - call stopit( status, 'Above value should be 2' ) - end if - - if( mdata(8) .ne. 0 ) then - write(*,*) 'mdata(8) = ',mdata(8) - call stopit( status, 'Above value should be 0' ) - end if - - - - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'PointList tests failed' - - end - - - - - - - - - subroutine checkCircle( status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - - integer status, cir1, cir2, fc, i, fs, frm1,unc,f1,f2,f3, - : npoint, j - double precision p1(4),p2(4),xin(2),yin(2),xout(2),yout(2), - : p3(3),rad,zin(2),zout(2),pp1(3),pp2(3), - : lbnd(2),ubnd(2), mesh(250,3) - character cards(8)*80, sys*40 - logical hasframeset - - double precision in( 2, 3 ), out( 2, 3 ) - - - data cards /'CTYPE1 = ''RA---TAN''', - : 'CTYPE2 = ''DEC--TAN''', - : 'CRPIX1 = 100', - : 'CRPIX2 = 100', - : 'CRVAL1 = 70.0', - : 'CRVAL2 = 80.0', - : 'CDELT1 = 0.6', - : 'CDELT2 = 0.6' / - - - if( status .ne.sai__ok ) return - call ast_begin( status ) - -* Test 2D circles. - - fc = ast_fitschan( ast_null, ast_null, ' ', status ) - do i = 1, 8 - call ast_putfits( fc, cards(i), .false., status ) - end do - call ast_clear( fc, 'card', status ) - fs = ast_read( fc, status ) - - frm1 = ast_getframe( fs, ast__current, status ) - - p1( 1 ) = 0.0 - p1( 2 ) = 1.0 - p2( 1 ) = 0.01 - - cir1 = ast_circle( frm1, 1, p1, p2, AST__NULL, ' ', status ) - call ast_getregionbounds( cir1, lbnd, ubnd, status ) - - if( abs(lbnd(1)-(-0.01850666061475259)) .gt. 1.0E-6 ) - : call stopit( status, 'Circle: Error AA1' ) - if( abs(lbnd(2)-(0.9900000002235173)) .gt. 1.0E-6 ) - : call stopit( status, 'Circle: Error AA2' ) - if( abs(ubnd(1)-(0.01850666061475276)) .gt. 1.0E-6 ) - : call stopit( status, 'Circle: Error AA3' ) - if( abs(ubnd(2)-(1.009994987166073)) .gt. 1.0E-6 ) - : call stopit( status, 'Circle: Error AA4' ) - - p1( 1 ) = 0.0 - p1( 2 ) = 1.57 - p2( 1 ) = 0.01 - - cir1 = ast_circle( frm1, 1, p1, p2, AST__NULL, ' ', status ) - call ast_getregionbounds( cir1, lbnd, ubnd, status ) - - if( abs(lbnd(1)-(0.0)) .gt. 1.0E-6 ) - : call stopit( status, 'Circle: Error AA5' ) - if( abs(lbnd(2)-(1.560000052675599)) .gt. 1.0E-6 ) - : call stopit( status, 'Circle: Error AA6' ) - if( abs(ubnd(1)-(6.283185307179586)) .gt. 1.0E-6 ) - : call stopit( status, 'Circle: Error AA7' ) - if( abs(ubnd(2)-(1.5707963267948966)) .gt. 1.0E-6 ) - : call stopit( status, 'Circle: Error AA8' ) - - call ast_getregionmesh( cir1, .true., 0, 0, npoint, 0, status ) - if( npoint .ne. 200 ) - : call stopit( status, 'Circle: Error mesh 1' ) - - call ast_getregionmesh( cir1, .true., 250, 3, npoint, mesh, - : status ) - - do i = 1, npoint - p2(1) = mesh(i,1) - p2(2) = mesh(i,2) - if( abs( ast_distance( frm1, p1, p2, status ) - 0.01 ) .gt. - : 1.0E-6 ) call stopit( status, 'Circle: Error mesh 2' ) - enddo - - call ast_getregionmesh( cir1, .false., 250, 3, npoint, mesh, - : status ) - - if( npoint .ne. 201 ) then - write(*,*) npoint - call stopit( status, 'Circle: Error mesh 3' ) - endif - - do i = 1, npoint - p2(1) = mesh(i,1) - p2(2) = mesh(i,2) - if( ast_distance( frm1, p1, p2, status ) .gt. 0.01 ) - : call stopit( status, 'Circle: Error mesh 4' ) - enddo - - p1( 1 ) = 1.2217305 - p1( 2 ) = 1.3962634 - p2( 1 ) = 0.8 - p2( 2 ) = 0.8 - - cir1 = ast_circle( frm1, 0, p1, p2, AST__NULL, ' ', status ) - call checkdump( cir1, 'checkdump cir1', status ) - - rad = ast_distance( cir1, p1, p2, status ) - - call ast_offset( frm1, p1, p2, rad*0.999, p3, status ) - xin(1) = p3(1) - yin(1) = p3(2) - call ast_offset( frm1, p1, p2, rad*1.001, p3, status ) - xin(2) = p3(1) - yin(2) = p3(2) - - call ast_tran2( cir1, 2, xin, yin, .true., xout, yout, status ) - if( xout(1) .ne. xin(1) ) call stopit( status, 'Circle: Error 1' ) - if( yout(1) .ne. yin(1) ) call stopit( status, 'Circle: Error 2' ) - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'Circle: Error 3' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'Circle: Error 4' ) - - - xin(1) = 0.0 - yin(1) = 1.5707963 - call ast_tran2( cir1, 1, xin, yin, .true., xout, yout, status ) - if( xout(1) .ne. xin(1) ) call stopit( status, 'Circle: Error 1b') - if( yout(1) .ne. yin(1) ) call stopit( status, 'Circle: Error 2b') - - p2(1)=0.0 - p2(2)=0.0 - call ast_offset( frm1, p1, p2, rad*0.999, p3, status ) - xin(1) = p3(1) - yin(1) = p3(2) - call ast_offset( frm1, p1, p2, rad*1.001, p3, status ) - xin(2) = p3(1) - yin(2) = p3(2) - - call ast_tran2( cir1, 2, xin, yin, .true., xout, yout, status ) - if( xout(1) .ne. xin(1) ) call stopit( status, 'Circle: Error 5' ) - if( yout(1) .ne. yin(1) ) call stopit( status, 'Circle: Error 6' ) - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'Circle: Error 7' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'Circle: Error 8' ) - - - call ast_setc( cir1, 'system', 'galactic', status ) - cir1 = ast_simplify( cir1, status ) - if( .not. hasframeset( cir1,status ) ) call stopit( status, - : 'Circle: error 9' ) - - - pp1( 1 ) = 0.0 - pp1( 2 ) = 0.0 - pp2( 1 ) = 1.0D-6 - pp2( 2 ) = 1.0D-6 - unc = ast_box( frm1, 0, pp1, pp2, AST__NULL, ' ', status ) - - p1( 1 ) = 1.2217305 - p1( 2 ) = 1.3962634 - p2( 1 ) = 1.2218 - p2( 2 ) = 1.3963 - cir1 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - - rad = ast_distance( cir1, p1, p2, status ) - - call ast_offset( frm1, p1, p2, rad*0.999, p3, status ) - xin(1) = p3(1) - yin(1) = p3(2) - call ast_offset( frm1, p1, p2, rad*1.001, p3, status ) - xin(2) = p3(1) - yin(2) = p3(2) - - call ast_tran2( cir1, 2, xin, yin, .true., xout, yout, status ) - if( xout(1) .ne. xin(1) ) call stopit( status, 'Circle: Error 1b') - if( yout(1) .ne. yin(1) ) call stopit( status, 'Circle: Error 2b') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'Circle: Error 3b' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'Circle: Error 4b' ) - - p2(1)=0.0 - p2(2)=0.0 - call ast_offset( frm1, p1, p2, rad*0.999, p3, status ) - xin(1) = p3(1) - yin(1) = p3(2) - call ast_offset( frm1, p1, p2, rad*1.001, p3, status ) - xin(2) = p3(1) - yin(2) = p3(2) - - call ast_tran2( cir1, 2, xin, yin, .true., xout, yout, status ) - if( xout(1) .ne. xin(1) ) call stopit( status, 'Circle: Error 5b') - if( yout(1) .ne. yin(1) ) call stopit( status, 'Circle: Error 6b') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'Circle: Error 7b' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'Circle: Error 8b' ) - - cir2 = ast_copy( cir1, status ) - call ast_setc( cir2, 'system', 'galactic', status ) - call checkdump( cir2, 'checkdump cir2', status ) - - cir2 = ast_simplify( cir2, status ) - - if( hasframeset( cir2,status ) ) call stopit( status, - : 'Circle: error 9b' ) - - if( ast_overlap( cir1, cir2, status ) .ne. 5 ) call stopit(status, - : 'Circle: Error 10' ) - if( ast_overlap( cir2, cir1, status ) .ne. 5 ) call stopit(status, - : 'Circle: Error 11' ) - - p1( 1 ) = 1.2217305 - p1( 2 ) = 1.3964 - p2( 1 ) = 1.2218 - p2( 2 ) = 1.3963 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - if( ast_overlap( cir1, cir2, status ) .ne. 4 ) call stopit(status, - : 'Circle: Error 12' ) - if( ast_overlap( cir2, cir1, status ) .ne. 4 ) call stopit(status, - : 'Circle: Error 13' ) - - p1( 1 ) = 1.2217305 - p1( 2 ) = 1.3962634 - p2( 1 ) = 1.221731 - p2( 2 ) = 1.396268 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - if( ast_overlap( cir1, cir2, status ) .ne. 3 ) call stopit(status, - : 'Circle: Error 14' ) - if( ast_overlap( cir2, cir1, status ) .ne. 2 ) call stopit(status, - : 'Circle: Error 15' ) - - p1( 1 ) = 0.8 - p1( 2 ) = 1.0 - p2( 1 ) = 0.88 - p2( 2 ) = 1.05 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - if( ast_overlap( cir1, cir2, status ) .ne. 1 ) call stopit(status, - : 'Circle: Error 16' ) - - - p1( 1 ) = 0.8 - p1( 2 ) = 1.5707963 - p2( 1 ) = 0.1 - cir2 = ast_circle( frm1, 1, p1, p2, unc, ' ', status ) - call ast_getregionbounds( cir2, lbnd, ubnd, status ) - if( lbnd(1) .ne. 0.0D0 ) call stopit( status, - : 'Circle: Error 16a' ) - if( abs( lbnd(2) - 1.47079625 ) .gt. 1.0E-6 ) call stopit( status, - : 'Circle: Error 16b' ) - if( abs( ubnd(1) - 6.28318531 ) .gt. 1.0E-6 ) call stopit( status, - : 'Circle: Error 16c' ) - if( abs( ubnd(2) - 1.57079633 ) .gt. 1.0E-6 ) call stopit( status, - : 'Circle: Error 16d' ) - - - frm1 = ast_frame(2,"domain=aa",status) - - pp1( 1 ) = 0.0 - pp1( 2 ) = 0.0 - pp2( 1 ) = 1.0D-6 - pp2( 2 ) = 1.0D-6 - unc = ast_box( frm1, 0, pp1, pp2, AST__NULL, ' ', status ) - - p1( 1 ) = 1.2217305 - p1( 2 ) = 1.3962634 - p2( 1 ) = 1.2218 - p2( 2 ) = 1.3963 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - - if( ast_overlap( cir1, cir2, status ) .ne. 0 ) call stopit(status, - : 'Circle: Error 17' ) - if( ast_overlap( cir2, cir1, status ) .ne. 0 ) call stopit(status, - : 'Circle: Error 18' ) - - - f1 = ast_skyframe( ' ', status ) - f2 = ast_frame( 2, ' ', status ) - f3 = ast_cmpframe( f1, f2, ' ', status ) - - p1( 1 ) = 1.0 - p1( 2 ) = 1.0 - p1( 3 ) = 3.0 - p1( 4 ) = 3.0 - p2( 1 ) = 1.01 - p2( 2 ) = 1.02 - p2( 3 ) = 3.01 - p2( 4 ) = 3.01 - cir2 = ast_circle( f3, 0, p1, p2, AST__NULL, ' ', status ) - if( ast_overlap( cir2, cir2, status ) .ne. 5 ) call stopit(status, - : 'Circle: Error 18b' ) - -* Test 3D spheres - - frm1 = ast_frame( 3, ' ', status ) - - pp1( 1 ) = 0.0 - pp1( 2 ) = 0.0 - pp1( 3 ) = 0.0 - pp2( 1 ) = 1.0E-6 - pp2( 2 ) = 2.0E-6 - pp2( 3 ) = 2.0E-6 - unc = ast_box( frm1, 0, pp1, pp2, AST__NULL, ' ', status ) - - p1( 1 ) = 1.0 - p1( 2 ) = 2.0 - p1( 3 ) = 3.0 - p2( 1 ) = 0.0 - p2( 2 ) = -1.0 - p2( 3 ) = -2.0 - cir1 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - call checkdump( cir1, 'checkdump sph1', status ) - - rad = ast_distance( cir1, p1, p2, status ) - - call ast_offset( frm1, p1, p2, rad*0.999, p3, status ) - in(1,1) = p3(1) - in(1,2) = p3(2) - in(1,3) = p3(3) - call ast_offset( frm1, p1, p2, rad*1.001, p3, status ) - in(2,1) = p3(1) - in(2,2) = p3(2) - in(2,3) = p3(3) - - - call ast_trann( cir1, 2, 3, 2, in, .true., 3, 2, out, status ) - - if( out(1,1) .ne. in(1,1) ) call stopit( status, - : 'Sphere: Error 1' ) - if( out(1,2) .ne. in(1,2) ) call stopit( status, - : 'Sphere: Error 2' ) - if( out(1,3) .ne. in(1,3) ) call stopit( status, - : 'Sphere: Error 2z') - if( out(2,1) .ne. AST__BAD ) call stopit( status, - : 'Sphere: Error 3' ) - if( out(2,2) .ne. AST__BAD ) call stopit( status, - : 'Sphere: Error 4' ) - if( out(2,3) .ne. AST__BAD ) call stopit( status, - : 'Sphere: Error 4z' ) - - p2(1)=0.0 - p2(2)=0.0 - p2(3)=0.0 - call ast_offset( frm1, p1, p2, rad*0.999, p3, status ) - in(1,1) = p3(1) - in(1,2) = p3(2) - in(1,3) = p3(3) - call ast_offset( frm1, p1, p2, rad*1.001, p3, status ) - in(2,1) = p3(1) - in(2,2) = p3(2) - in(2,3) = p3(3) - - call ast_trann( cir1, 2, 3, 2, in, .true., 3, 2, out, status ) - if( out(1,1) .ne. in(1,1) ) call stopit( status, - : 'Sphere: Error 5' ) - if( out(1,2) .ne. in(1,2) ) call stopit( status, - : 'Sphere: Error 6' ) - if( out(1,3) .ne. in(1,3) ) call stopit( status, - : 'Sphere: Error 6z') - if( out(2,1) .ne. AST__BAD ) call stopit( status, - : 'Sphere: Error 7' ) - if( out(2,2) .ne. AST__BAD ) call stopit( status, - : 'Sphere: Error 8' ) - if( out(2,3) .ne. AST__BAD ) call stopit( status, - : 'Sphere: Error 8z' ) - - - if( ast_overlap( cir1, cir1, status ) .ne. 5 ) call stopit(status, - : 'Sphere: Error 10' ) - - - - - p1( 1 ) = 1.0 - p1( 2 ) = 2.0 - p1( 3 ) = 3.0 - p2( 1 ) = 0.5 - p2( 2 ) = 0.0 - p2( 3 ) = -1.0 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - call checkdump( cir2, 'checkdump sph2', status ) - - if( ast_overlap( cir2, cir1, status ) .ne. 2 ) call stopit(status, - : 'Sphere: Error 11' ) - - if( ast_overlap( cir1, cir2, status ) .ne. 3 ) call stopit(status, - : 'Sphere: Error 12' ) - - - - p1( 1 ) = 1.0 - p1( 2 ) = 0.0 - p1( 3 ) = 3.0 - p2( 1 ) = 0.0 - p2( 2 ) = -1.0 - p2( 3 ) = -2.0 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - if( ast_overlap( cir1, cir2, status ) .ne. 4 ) call stopit(status, - : 'Sphere: Error 13' ) - - p1( 1 ) = 1.0 - p1( 2 ) = 102.0 - p1( 3 ) = 3.0 - p2( 1 ) = 0.0 - p2( 2 ) = 99.0 - p2( 3 ) = -2.0 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - if( ast_overlap( cir1, cir2, status ) .ne. 1 ) call stopit(status, - : 'Sphere: Error 14' ) - - - p1( 1 ) = 0.0 - p1( 2 ) = 0.0 - p1( 3 ) = 0.0 - p2( 1 ) = 0.0 - p2( 2 ) = 0.0 - p2( 3 ) = 1.0 - cir1 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - - p1( 1 ) = 2.0000001 - p1( 2 ) = 0.0 - p1( 3 ) = 0.0 - p2( 1 ) = 2.000001 - p2( 2 ) = 1.0 - p2( 3 ) = 0.0 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - - if( ast_overlap( cir1, cir2, status ) .ne. 4 ) then - write(*,*) ast_overlap( cir1, cir2, status ),' should be 4 ' - call stopit(status, 'Sphere: Error 15' ) - end if - - p1( 1 ) = 2.000001 - p1( 2 ) = 0.0 - p1( 3 ) = 0.0 - p2( 1 ) = 2.000001 - p2( 2 ) = 1.0 - p2( 3 ) = 0.0 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - - if( ast_overlap( cir1, cir2, status ) .ne. 4 ) call stopit(status, - : 'Sphere: Error 16' ) - - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - - call ast_setl( cir1, 'Closed', .false., status ) - call ast_setl( cir2, 'Closed', .false., status ) - if( ast_overlap( cir1, cir2, status ) .ne. 1 ) call stopit(status, - : 'Sphere: Error 17' ) - call ast_clear( cir1, 'Closed', status ) - call ast_clear( cir2, 'Closed', status ) - - p1( 1 ) = 2.000004 - p1( 2 ) = 0.0 - p1( 3 ) = 0.0 - p2( 1 ) = 2.000004 - p2( 2 ) = 1.0 - p2( 3 ) = 0.0 - cir2 = ast_circle( frm1, 0, p1, p2, unc, ' ', status ) - - if( ast_overlap( cir1, cir2, status ) .ne. 1 ) call stopit(status, - : 'Sphere: Error 18' ) - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'Circle tests failed' - - end - - - - - - - - subroutine checkEllipse( status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - - integer status, ell1, ell2, fc, i, fs, frm1, fs2,mm,ell3,ell4, - : reg, unc, f1, f2, f3, f4, f5, map, perm(2) - double precision p1(2),p2(2),p3(2),p4(2),pp1(2),pp2(2) - double precision q1(2),q2(2),q3(2),q4(2),lbnd(2),ubnd(2) - double precision q1b(2),q2b(2),q3b(2),q4b(2) - double precision p1b(2),p2b(2),p3b(2),p4b(2),matrix(4) - character cards(10)*80 - double precision xin(4),yin(4),xout(4),yout(4),rad - logical hasframeset - - data cards /'NAXIS1 = 300', - : 'NAXIS2 = 300', - : 'CTYPE1 = ''RA---TAN''', - : 'CTYPE2 = ''DEC--TAN''', - : 'CRPIX1 = 100', - : 'CRPIX2 = 100', - : 'CRVAL1 = 0.0', - : 'CRVAL2 = 90.0', - : 'CDELT1 = 0.6', - : 'CDELT2 = 0.6' / - - - if( status .ne.sai__ok ) return - call ast_begin( status ) - - f1 = ast_SkyFrame( 'system=fk4', status ) - f3 = ast_cmpframe( ast_pickaxes( f1, 1, 1, map, status ), - : ast_specframe( 'system=wave,unit=um', status ), - : ' ', status ) - perm(1)=2 - perm(2)=1 - call ast_permaxes( f3, perm, status ) - p1(1) = 0.0 - p1(2) = 0.0 - p2(1) = 0.001 - p2(2) = 0.001 - p3(1) = -0.001 - p3(2) = 0.001 - ell1 = ast_ellipse( f3, 0, p1, p2, p3, AST__NULL, ' ', status ) - - xin(1) = 0.0 - yin(1) = 0.00141421 - xin(2) = 0.0 - yin(2) = 0.00141422 - xin(3) = -0.000999 - yin(3) = 0.0009999 - xin(4) = -0.001001 - yin(4) = 0.001001 - call ast_tran2( ell1, 4, xin, yin, .true., xout, yout, status ) - - if( xout(1) .ne. xin(1) ) call stopit( status, 'Ellipse: Cmp 1') - if( yout(1) .ne. yin(1) ) call stopit( status, 'Ellipse: Cmp 2') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Cmp 3' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Cmp 4' ) - if( xout(3) .ne. xin(3) ) call stopit( status, 'Ellipse: Cmp 5') - if( yout(3) .ne. yin(3) ) call stopit( status, 'Ellipse: Cmp 6') - if( xout(4) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Cmp 7' ) - if( yout(4) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Cmp 8' ) - - call checkdump( ell1, 'checkdump ell1 cmp', status ) - ell2 = ast_simplify( ell1, status ) - call checkdump( ell2, 'checkdump ell2 cmp', status ) - if( ast_overlap( ell1, ell2, status ) .ne. 5 ) call stopit(status, - : 'ellipse: Error 5 cmp' ) - - fc = ast_fitschan( ast_null, ast_null, ' ', status ) - do i = 1, 10 - call ast_putfits( fc, cards(i), .false., status ) - end do - call ast_clear( fc, 'card', status ) - fs = ast_read( fc, status ) - - frm1 = ast_getframe( fs, ast__current, status ) - - p1( 1 ) = 1.2217305 - p1( 2 ) = 1.570796 - p2( 1 ) = 0.9 - p2( 2 ) = 1.470796 - p3( 1 ) = 2.9217305 - p3( 2 ) = 1.370796 - - ell1 = ast_ellipse( frm1, 0, p1, p2, p3, AST__NULL, ' ', status ) - call checkdump( ell1, 'checkdump ell1', status ) - - - call ast_getregionbounds( ell1, lbnd, ubnd, status ) - if( abs( lbnd(1) ) .gt. 1.0E-10 ) call stopit( status, - : 'Error b1' ) - if( abs( lbnd(2) - 1.19059777 ) .gt. 1.0E-6 ) - : call stopit( status, 'Error b2' ) - if( abs( ubnd(1) - 6.28318531 ) .gt. 1.0E-6 ) - : call stopit( status, 'Error b3' ) - if( abs( ubnd(2) - 1.57079633 ) .gt. 1.0E-6 ) - : call stopit( status, 'Error b4' ) - - rad = ast_distance( ell1, p1, p2, status ) - - call ast_offset( frm1, p1, p2, rad*0.999, p4, status ) - xin(1) = p4(1) - yin(1) = p4(2) - call ast_offset( frm1, p1, p2, rad*1.001, p4, status ) - xin(2) = p4(1) - yin(2) = p4(2) - - call ast_tran2( ell1, 2, xin, yin, .true., xout, yout, status ) - if( xout(1) .ne. xin(1) ) call stopit( status, 'Ellipse: Error 1') - if( yout(1) .ne. yin(1) ) call stopit( status, 'Ellipse: Error 2') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Error 3' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Error 4' ) - - - call ast_offset( frm1, p1, p2, -rad*0.999, p4, status ) - xin(1) = p4(1) - yin(1) = p4(2) - call ast_offset( frm1, p1, p2, -rad*1.001, p4, status ) - xin(2) = p4(1) - yin(2) = p4(2) - - call ast_tran2( ell1, 2, xin, yin, .true., xout, yout, status ) - if( xout(1) .ne. xin(1) ) call stopit( status, - : 'Ellipse: Error 1b') - if( yout(1) .ne. yin(1) ) call stopit( status, - : 'Ellipse: Error 2b') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Error 3b' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Error 4b' ) - - - rad = ast_distance( ell1, p1, p3, status ) - - call ast_offset( frm1, p1, p3, rad*0.999, p4, status ) - xin(1) = p4(1) - yin(1) = p4(2) - call ast_offset( frm1, p1, p3, rad*1.001, p4, status ) - xin(2) = p4(1) - yin(2) = p4(2) - - call ast_tran2( ell1, 2, xin, yin, .true., xout, yout, status ) - if( xout(1) .ne. xin(1) ) call stopit( status, - : 'Ellipse: Error 1c') - if( yout(1) .ne. yin(1) ) call stopit( status, - : 'Ellipse: Error 2c') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Error 3c' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Error 4c' ) - - call ast_offset( frm1, p1, p3, -rad*0.999, p4, status ) - xin(1) = p4(1) - yin(1) = p4(2) - call ast_offset( frm1, p1, p3, -rad*1.001, p4, status ) - xin(2) = p4(1) - yin(2) = p4(2) - - call ast_tran2( ell1, 2, xin, yin, .true., xout, yout, status ) - if( xout(1) .ne. xin(1) ) call stopit( status, - : 'Ellipse: Error 1d') - if( yout(1) .ne. yin(1) ) call stopit( status, - : 'Ellipse: Error 2d') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Error 3d' ) - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'Ellipse: Error 4d' ) - - - ell2 = ast_copy( ell1, status ) - - if( ast_overlap( ell1, ell2, status ) .ne. 5 ) call stopit(status, - : 'ellipse: Error 5' ) - if( ast_overlap( ell2, ell1, status ) .ne. 5 ) call stopit(status, - : 'ellipse: Error 6' ) - - call ast_set( ell2, 'system=galactic', status ) - if( ast_overlap( ell1, ell2, status ) .ne. 5 ) call stopit(status, - : 'ellipse: Error 7' ) - if( ast_overlap( ell2, ell1, status ) .ne. 5 ) call stopit(status, - : 'ellipse: Error 8' ) - - - - - xin(1) = p1( 1 ) - yin(1) = p1( 2 ) - xin(2) = p2( 1 ) - yin(2) = p2( 2 ) - xin(3) = p3( 1 ) - yin(3) = p3( 2 ) - call ast_tran2( fs, 3, xin, yin, .false., xout, yout, status ) - q1(1) = xout(1) - q1(2) = yout(1) - q2(1) = xout(2) - q2(2) = yout(2) - q3(1) = xout(3) - q3(2) = yout(3) - - frm1 = ast_GetFrame( fs, AST__BASE, status ) - - rad = ast_distance( frm1, q1, q2, status ) - - call ast_offset( frm1, q1, q2, rad*1.95, q1b, status ) - - q2b( 1 ) = q2( 1 ) + ( q1b( 1 ) - q1( 1 ) ) - q2b( 2 ) = q2( 2 ) + ( q1b( 2 ) - q1( 2 ) ) - - q3b( 1 ) = q3( 1 ) + ( q1b( 1 ) - q1( 1 ) ) - q3b( 2 ) = q3( 2 ) + ( q1b( 2 ) - q1( 2 ) ) - - xout(1) = q1b(1) - yout(1) = q1b(2) - xout(2) = q2b(1) - yout(2) = q2b(2) - xout(3) = q3b(1) - yout(3) = q3b(2) - call ast_tran2( fs, 3, xout, yout, .true., xin, yin, status ) - p1b( 1 ) = xin(1) - p1b( 2 ) = yin(1) - p2b( 1 ) = xin(2) - p2b( 2 ) = yin(2) - p3b( 1 ) = xin(3) - p3b( 2 ) = yin(3) - - frm1 = ast_GetFrame( fs, AST__CURRENT, status ) - - pp1( 1 ) = 0.0 - pp1( 2 ) = 0.0 - pp2( 1 ) = 1.0D-7 - pp2( 2 ) = 1.0D-7 - unc = ast_box( frm1, 0, pp1, pp2, AST__NULL, ' ', status ) - ell2 = ast_ellipse( frm1, 0, p1b, p2b, p3b, unc, ' ', status ) - if( ast_overlap( ell2, ell1, status ) .ne. 4 ) call stopit(status, - : 'ellipse: Error 9' ) - if( ast_overlap( ell1, ell2, status ) .ne. 4 ) call stopit(status, - : 'ellipse: Error 10' ) - - - call ast_offset( frm1, q1, q2, rad*2.05, q1b, status ) - - q2b( 1 ) = q2( 1 ) + ( q1b( 1 ) - q1( 1 ) ) - q2b( 2 ) = q2( 2 ) + ( q1b( 2 ) - q1( 2 ) ) - - q3b( 1 ) = q3( 1 ) + ( q1b( 1 ) - q1( 1 ) ) - q3b( 2 ) = q3( 2 ) + ( q1b( 2 ) - q1( 2 ) ) - - xout(1) = q1b(1) - yout(1) = q1b(2) - xout(2) = q2b(1) - yout(2) = q2b(2) - xout(3) = q3b(1) - yout(3) = q3b(2) - call ast_tran2( fs, 3, xout, yout, .true., xin, yin, status ) - p1b( 1 ) = xin(1) - p1b( 2 ) = yin(1) - p2b( 1 ) = xin(2) - p2b( 2 ) = yin(2) - p3b( 1 ) = xin(3) - p3b( 2 ) = yin(3) - - frm1 = ast_GetFrame( fs, AST__CURRENT, status ) - pp1( 1 ) = 0.0 - pp1( 2 ) = 0.0 - pp2( 1 ) = 1.0D-7 - pp2( 2 ) = 1.0D-7 - unc = ast_box( frm1, 0, pp1, pp2, AST__NULL, ' ', status ) - ell2 = ast_ellipse( frm1, 0, p1b, p2b, p3b, unc, ' ', status ) - if( ast_overlap( ell2, ell1, status ) .ne. 1 ) call stopit(status, - : 'ellipse: Error 11' ) - if( ast_overlap( ell1, ell2, status ) .ne. 1 ) call stopit(status, - : 'ellipse: Error 12' ) - - p1b( 1 ) = p1( 1 ) - p1b( 2 ) = p1( 2 ) - p2b( 1 ) = p2( 1 ) - p2b( 2 ) = 0.9*p2( 2 ) + 0.1*p1( 2 ) - p3b( 1 ) = p3( 1 ) - p3b( 2 ) = 0.9*p3( 2 ) + 0.1*p1( 2 ) - - ell2 = ast_ellipse( frm1, 0, p1b, p2b, p3b, unc, ' ', status ) - if( ast_overlap( ell2, ell1, status ) .ne. 2 ) call stopit(status, - : 'ellipse: Error 13' ) - if( ast_overlap( ell1, ell2, status ) .ne. 3 ) call stopit(status, - : 'ellipse: Error 14' ) - - - - - - - frm1 = ast_frame( 2, ' ', status ) - - pp1( 1 ) = 0.0 - pp1( 2 ) = 0.0 - pp2( 1 ) = 1.0D-7 - pp2( 2 ) = 1.0D-7 - unc = ast_box( frm1, 0, pp1, pp2, AST__NULL, ' ', status ) - - p1(1)=0.0 - p1(2)=0.0 - p2(1)=1.0 - p2(2)=0.0 - p3(1)=0.0 - p3(2)=0.5 - ell1 = ast_ellipse( frm1, 0, p1, p2, p3, unc, ' ', status ) - - - matrix(1) = 1.73 - matrix(2) = 0.5003 - matrix(3) = -1.0006 - matrix(4) = 0.866 - mm = ast_matrixmap( 2, 2, 0, matrix, ' ', status ) - - ell2 = ast_mapregion( ell1, mm, frm1, status ) - call checkdump( ell2, 'checkdump ell2', status ) - if( hasframeset( ell2, status ) ) call stopit( status, - : 'Ellipse: error 15' ) - call ast_invert( mm, status ) - ell3 = ast_mapregion( ell2, mm, frm1, status ) - if( hasframeset( ell3,status ) ) call stopit( status, - : 'Ellipse: error 16' ) - if( ast_overlap( ell1, ell3, status ) .ne. 5 ) call stopit(status, - : 'ellipse: Error 17' ) - - - frm1 = ast_frame( 2, ' ', status ) - pp1( 1 ) = 0.0 - pp1( 2 ) = 0.0 - pp2( 1 ) = 1.0D-7 - pp2( 2 ) = 1.0D-7 - unc = ast_box( frm1, 0, pp1, pp2, AST__NULL, ' ', status ) - - p1(1)=0.0 - p1(2)=0.0 - p2(1)=1.0 - p2(2)=0.0 - p3(1)=0.0 - p3(2)=1.0 - ell1 = ast_ellipse( frm1, 0, p1, p2, p3, unc, ' ', status ) - reg = ast_simplify( ell1, status ) - if( .not. ast_IsACircle( reg, status ) ) call stopit(status, - : 'ellipse: Error 18' ) - - ell1 = ast_circle( frm1, 0, p1, p2, AST__NULL, ' ', status ) - if( ast_overlap( reg, ell1, status ) .ne. 5 ) call stopit(status, - : 'Ellipse: Error 19' ) - - - - frm1 = ast_skyframe( ' ', status ) - p1(1)=0.0D0 - p1(2)=0.0D0 - p2(1)=0.01D0 - p2(2)=0.01D0 - p3(1)=0.0D0 - p3(2)=0.0D0 - ell1 = ast_ellipse( frm1, 1, p1, p2, p3, AST__NULL, ' ', status ) - - p1(1)=-0.015D0 - p1(2)=0.0D0 - p2(1)=0.01D0 - p2(2)=0.01D0 - p3(1)=0.0D0 - p3(2)=0.0D0 - ell2 = ast_ellipse( frm1, 1, p1, p2, p3, AST__NULL, ' ', status ) - - if( ast_overlap( ell1, ell2, status ) .ne. 4 ) call stopit(status, - : 'Ellipse: Error 20' ) - - p1(1)=6.2681853D0 - p1(2)=0.0D0 - p2(1)=0.01D0 - p2(2)=0.01D0 - p3(1)=0.0D0 - p3(2)=0.0D0 - ell2 = ast_ellipse( frm1, 1, p1, p2, p3, AST__NULL, ' ', status ) - - if( ast_overlap( ell1, ell2, status ) .ne. 4 ) call stopit(status, - : 'Ellipse: Error 21' ) - - p1(1)=-0.015D0 - p1(2)=0.0D0 - p2(1)=0.01D0 - p2(2)=0.01D0 - p3(1)=0.0D0 - p3(2)=0.0D0 - ell1 = ast_ellipse( frm1, 1, p1, p2, p3, AST__NULL, ' ', status ) - - if( ast_overlap( ell1, ell2, status ) .ne. 5 ) call stopit(status, - : 'Ellipse: Error 22' ) - - - - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'Ellipse tests failed' - - end - - - subroutine checkNullRegion( status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - include 'PRM_PAR' - - integer status, f1, f2, f3, nr, cir, i, j, lbnd_in(2), ubnd_in(2), - : nr2, res - double precision p1(4),p2(4),rin(5,5) - logical hasframeset - - if( status .ne.sai__ok ) return - - call ast_begin( status ) - - f1 = ast_skyframe( ' ', status ) - f2 = ast_frame( 2, ' ', status ) - f3 = ast_cmpframe( f1, f2, ' ', status ) - nr = ast_NullRegion( f3, AST__NULL, ' ', status ) - - call checkdump( nr, 'checkdump NullRegion:nr', status ) - - p1( 1 ) = 1.0 - p1( 2 ) = 1.0 - p1( 3 ) = 3.0 - p1( 4 ) = 3.0 - p2( 1 ) = 1.01 - p2( 2 ) = 1.02 - p2( 3 ) = 3.01 - p2( 4 ) = 3.01 - cir = ast_circle( nr, 0, p1, p2, AST__NULL, ' ', status ) - call checkdump( cir, 'checkdump NullRegion:cir', status ) - - if( ast_overlap( cir, nr, status ) .ne. 1 ) call stopit(status, - : 'NullRegion: Error 1' ) - - if( ast_overlap( nr, cir, status ) .ne. 1 ) call stopit(status, - : 'NullRegion: Error 2' ) - - if( ast_overlap( nr, nr, status ) .ne. 5 ) call stopit(status, - : 'NullRegion: Error 3' ) - - call ast_negate( nr, status ) - - if( ast_overlap( cir, nr, status ) .ne. 2 ) call stopit(status, - : 'NullRegion: Error 4' ) - - if( ast_overlap( nr, cir, status ) .ne. 3 ) call stopit(status, - : 'NullRegion: Error 5' ) - - if( ast_overlap( nr, nr, status ) .ne. 5 ) call stopit(status, - : 'NullRegion: Error 6' ) - - call ast_set( nr, 'system(1)=FK4', status ) - nr2 = ast_simplify( nr, status ) - call ast_set( nr2, 'system(1)=ICRS', status ) - nr = ast_simplify( nr2, status ) - if( hasframeset( nr, status ) ) call stopit( status, - : 'NullRegion: error 7' ) - - lbnd_in(1) = 1 - lbnd_in(2) = 1 - ubnd_in(1) = 5 - ubnd_in(2) = 5 - - do i =1, 5 - do j = 1, 5 - rin( j,i)=1.0 - end do - end do - - nr = ast_NullRegion( f2, AST__NULL, 'negated=1', status ) - res = ast_maskd( nr, AST__NULL, .false., 2, lbnd_in, ubnd_in, - : rin, VAL__BADD, status ) - - if( res .ne. 0 ) then - write(*,*) 'NullRegion:Res is ',res - call stopit( status, 'res should be 0' ) - end if - - do i =1, 5 - do j = 1, 5 - if( rin(j,i) .NE. 1.0 ) then - write(*,*) 'rin(',j,',',i,') = ',rin(j,i) - call stopit( status, 'Above value should be 1.0' ) - end if - end do - end do - - call ast_negate( nr, status ) - res = ast_maskd( nr, AST__NULL, .false., 2, lbnd_in, ubnd_in, - : rin, VAL__BADD, status ) - - if( res .ne. 25 ) then - write(*,*) 'NullRegion:Res is ',res - call stopit( status, 'res should be 25' ) - end if - - do i =1, 5 - do j = 1, 5 - if( rin(j,i) .NE. VAL__BADD ) then - write(*,*) 'rin(',j,',',i,') = ',rin(j,i) - call stopit( status, 'Above value should be BAD' ) - end if - end do - end do - - - - - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'NullRegion tests failed' - - end - - - - - subroutine checkCmpRegion( status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - include 'PRM_PAR' - - integer status, r1, r2, r3, cr, f1, f2, cr2, cr3, frm, map, fs - double precision p1(2),p2(2),xout(4),yout(4),xin(4),yin(4) - logical hasframeset - - if( status .ne.sai__ok ) return - - call ast_begin( status ) - - - f1 = ast_skyframe( 'system=fk5', status ) - p1(1) = 0.0 - p1(2) = 0.0 - p2(1) = 1.0E-4 - p2(2) = 1.0E-4 - r1 = ast_box( f1, 0, p1, p2, AST__NULL, ' ', status ) - - f2 = ast_skyframe( 'system=galactic', status ) - - p1(1) = 1.68166715892457 - p1(2) = -1.050436507472 - p2(1) = 1.68140254777194 - p2(2) = -1.05048840003467 - r2 = ast_circle( f2, 0, p1, p2, AST__NULL, ' ', status ) - - if( ast_overlap( r1, r2, status ) .ne. 4 ) call stopit(status, - : 'CmpRegion: Error 0' ) - - cr = ast_cmpregion( r1, r2, AST__AND, ' ', status ) - cr = ast_Copy( cr, status ) - if( ast_overlap( cr, cr, status ) .ne. 5 ) call stopit(status, - : 'CmpRegion: Error 1' ) - - xin( 1 ) = 0.5E-4! In both r1 and r2 - xin( 2 ) = 1.5E-4! In r2 but not r1 - xin( 3 ) = -0.5E-4! In r1 but not r2 - xin( 4 ) = 1.1E-4! In neither - - yin( 1 ) = 0.5E-4 - yin( 2 ) = 1.5E-4 - yin( 3 ) = -0.5E-4 - yin( 4 ) = -1.1E-4 - - call ast_tran2( cr, 4, xin, yin, .true., xout, yout, status ) - - if( xout(1) .ne. xin(1) ) call stopit( status, - : 'CmpRegion: AND Error 1x') - if( yout(1) .ne. yin(1) ) call stopit( status, - : 'CmpRegion: AND Error 1y') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: AND Error 2x') - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: AND Error 2y') - if( xout(3) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: AND Error 3x') - if( yout(3) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: AND Error 3y') - if( xout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: AND Error 4x') - if( yout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: AND Error 4y') - - cr = ast_cmpregion( r1, r2, AST__OR, ' ', status ) - call ast_tran2( cr, 4, xin, yin, .true., xout, yout, status ) - - if( xout(1) .ne. xin(1) ) call stopit( status, - : 'CmpRegion: OR Error 1x') - if( yout(1) .ne. yin(1) ) call stopit( status, - : 'CmpRegion: OR Error 1y') - if( xout(2) .ne. xin(2) ) call stopit( status, - : 'CmpRegion: OR Error 2x') - if( yout(2) .ne. yin(2) ) call stopit( status, - : 'CmpRegion: OR Error 2y') - if( xout(3) .ne. xin(3) ) call stopit( status, - : 'CmpRegion: OR Error 3x') - if( yout(3) .ne. yin(3) ) call stopit( status, - : 'CmpRegion: OR Error 3y') - if( xout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: OR Error 4x') - if( yout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: OR Error 4y') - - - call ast_negate( r2, status ) - cr = ast_cmpregion( r1, r2, AST__AND, ' ', status ) - call ast_tran2( cr, 4, xin, yin, .true., xout, yout, status ) - - if( xout(1) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDb Error 1x') - if( yout(1) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDb Error 1y') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDb Error 2x') - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDb Error 2y') - if( xout(3) .ne. xin(3) ) call stopit( status, - : 'CmpRegion: ANDb Error 3x') - if( yout(3) .ne. yin(3) ) call stopit( status, - : 'CmpRegion: ANDb Error 3y') - if( xout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDb Error 4x') - if( yout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDb Error 4y') - - call ast_negate( r1, status ) - cr = ast_cmpregion( r1, r2, AST__AND, ' ', status ) - call ast_tran2( cr, 4, xin, yin, .true., xout, yout, status ) - - if( xout(1) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDc Error 1x') - if( yout(1) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDc Error 1y') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDc Error 2x') - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDc Error 2y') - if( xout(3) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDc Error 3x') - if( yout(3) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDc Error 3y') - if( xout(4) .ne. xin(4) ) call stopit( status, - : 'CmpRegion: ANDc Error 4x') - if( yout(4) .ne. yin(4) ) call stopit( status, - : 'CmpRegion: ANDc Error 4y') - - - cr = ast_cmpregion( r1, r2, AST__AND, ' ', status ) - call ast_negate( cr, status ) - call ast_tran2( cr, 4, xin, yin, .true., xout, yout, status ) - - if( xout(1) .ne. xin(1) ) call stopit( status, - : 'CmpRegion: ANDd Error 1x') - if( yout(1) .ne. yin(1) ) call stopit( status, - : 'CmpRegion: ANDd Error 1y') - if( xout(2) .ne. xin(2) ) call stopit( status, - : 'CmpRegion: ANDd Error 2x') - if( yout(2) .ne. yin(2) ) call stopit( status, - : 'CmpRegion: ANDd Error 2y') - if( xout(3) .ne. xin(3) ) call stopit( status, - : 'CmpRegion: ANDd Error 3x') - if( yout(3) .ne. yin(3) ) call stopit( status, - : 'CmpRegion: ANDd Error 3y') - if( xout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDd Error 4x') - if( yout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion: ANDd Error 4y') - - - cr2 = ast_cmpregion( r2, r1, AST__AND, ' ', status ) - - fs = ast_convert( cr, cr2, ' ', status ) - if( fs .eq. AST__NULL ) call stopit( status, - : 'CmpRegion: Error 5') - map = ast_getmapping( fs, AST__BASE, AST__CURRENT, status ) - frm = ast_getframe( fs, AST__CURRENT, status ) - cr3 = ast_mapRegion( cr, map, frm, status ) - if( ast_overlap( cr3, cr2, status ) .ne. 6 ) call stopit(status, - : 'CmpRegion: Error 6' ) - - cr = ast_Copy( cr, status ) - call checkdump( cr, 'checkdump CmpRegion: cr', status ) - - - cr2 = ast_Copy( cr, status ) - call ast_negate( cr2, status ) - - cr3 = ast_cmpregion( cr2, cr, AST__OR, ' ', status ) - cr3 = ast_Simplify( cr3, status ) - if( .not. ast_isanullregion( cr3, status ) ) then - call stopit(status, 'CmpRegion: Error 7' ) - else if( .not. ast_getl( cr3, 'negated', status ) ) then - call stopit(status, 'CmpRegion: Error 8' ) - end if - - cr3 = ast_cmpregion( cr2, cr, AST__AND, ' ', status ) - cr3 = ast_Simplify( cr3, status ) - if( .not. ast_isanullregion( cr3, status ) ) then - call stopit(status, 'CmpRegion: Error 9' ) - else if( ast_getl( cr3, 'negated', status ) ) then - call stopit(status, 'CmpRegion: Error 10' ) - end if - - - - f1 = ast_frame( 2, ' ', status ) - p1(1) = 0.0 - p1(2) = 0.0 - p2(1) = 1.0 - p2(2) = 1.0 - r1 = ast_box( f1, 0, p1, p2, AST__NULL, ' ', status ) - - p1(1) = -1.0 - p1(2) = 0.0 - p2(1) = 0.0 - p2(2) = 0.0 - r2 = ast_circle( f1, 0, p1, p2, AST__NULL, ' ', status ) - - p1(1) = 1.0 - p1(2) = 0.0 - p2(1) = 0.0 - p2(2) = 0.0 - r3 = ast_circle( f1, 0, p1, p2, AST__NULL, ' ', status ) - - cr = ast_cmpregion( r2, r3, AST__OR, ' ', status ) - call checkdump( cr, 'checkdump CmpRegion: cr', status ) - - call ast_negate( cr, status ) - cr2 = ast_cmpregion( cr, r1, AST__AND, ' ', status ) - call checkdump( cr2, 'checkdump CmpRegion: cr2', status ) - - cr2 = ast_simplify( cr2, status ) - - xin( 1 ) = 0.0 - xin( 2 ) = 0.2 - xin( 3 ) = 0.5 - xin( 4 ) = -0.5 - - yin( 1 ) = 0.5 - yin( 2 ) = 1.5 - yin( 3 ) = 0.5 - yin( 4 ) = 0.5 - - call ast_tran2( cr2, 4, xin, yin, .true., xout, yout, status ) - - if( xout(1) .ne. xin(1) ) call stopit( status, - : 'CmpRegion:Error 11') - if( yout(1) .ne. yin(1) ) call stopit( status, - : 'CmpRegion:Error 12') - if( xout(2) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion:Error 13') - if( yout(2) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion:Error 14') - if( xout(3) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion:Error 15') - if( yout(3) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion:Error 16') - if( xout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion:Error 17') - if( yout(4) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion:Error 18') - - - - call ast_negate( cr2, status ) - cr2 = ast_simplify( cr2, status ) - call ast_tran2( cr2, 4, xin, yin, .true., xout, yout, status ) - - if( xout(1) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion:Error 19') - if( yout(1) .ne. AST__BAD ) call stopit( status, - : 'CmpRegion:Error 20') - if( xout(2) .ne. xin(2) ) call stopit( status, - : 'CmpRegion:Error 21') - if( yout(2) .ne. yin(2) ) call stopit( status, - : 'CmpRegion:Error 22') - if( xout(3) .ne. xin(3) ) call stopit( status, - : 'CmpRegion:Error 23') - if( yout(3) .ne. yin(3) ) call stopit( status, - : 'CmpRegion:Error 24') - if( xout(4) .ne. xin(4) ) call stopit( status, - : 'CmpRegion:Error 25') - if( yout(4) .ne. yin(4) ) call stopit( status, - : 'CmpRegion:Error 26') - - - - - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'CmpRegion tests failed' - - end - - - - - - - -* -* Tests the dump function, the loader, and the astOverlap method. -* - subroutine checkdump( obj, text, status ) - - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*) - integer obj, status, next, end, ch, result, ll, overlap - external mysource, mysink - character buf*45000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - -* Create a Channel which reads and writes to an internal string buffer. - ch = ast_channel( mysource, mysink, ' ', status ) - -* Write the supplied Region out to this Channel. - ll = 160 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - -* Read an Object back from this Channel. - next = 1 - result = ast_read( ch, status ) - if( result .eq. ast__null ) then - write(*,*) text - call stopit( status, 'Cannot read object from channel' ) - end if - -* Check that it is a Region and its boundary is identical to the supplied -* Region. - overlap = ast_overlap( obj, result, status ) - if( overlap .ne. 5 ) then - write(*,*) 'obj result Overlap: ', overlap - write(*,*) 'obj self-Overlap: ', ast_overlap( obj, obj, - : status ) - write(*,*) 'result self-Overlap: ', ast_overlap( result, - : result, status ) - call ast_Show( obj, status ) - call ast_Show( result, status ) - write(*,*) text - call stopit( status, 'Object has changed' ) - end if - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll - character buf*45000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - call ast_putline( buf( next : ), ll, status ) - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll - character buf*45000 - character line*1000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - - if( next + ll - 1 .ge. 45000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf( next : next + l) - write(*,*) 'Line length ',l,' greater than ',ll - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - endif - - next = next + ll - - end - - - - - subroutine checkPrism( status ) - implicit none - include 'AST_PAR' - include 'SAE_PAR' - - integer f1, f2, r1, r2, r3, r4, status - double precision lbnd(5),ubnd(5),p1(5),p2(5) - logical hasframeset - - if( status .ne.sai__ok ) return - - call ast_begin( status ) - - f1 = ast_skyframe( 'system=fk5', status ) - p1(1) = 0.0 - p1(2) = 0.0 - p2(1) = 1.0E-4 - p2(2) = 1.0E-4 - r1 = ast_box( f1, 0, p1, p2, AST__NULL, ' ', status ) - - f2 = ast_specframe( 'Unit=Angstrom', status ) - lbnd( 1 ) = 5000.0 - ubnd( 1 ) = 6000.0 - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r3 = ast_prism( r1, r2, ' ', status ) - - call checkdump( r3, 'checkdump Prism 1', status ) - - if( ast_overlap( r3, r3, status ) .ne. 5 ) call stopit( status, - : 'Prism 1' ) - - r4 = ast_Simplify( r3, status ) - if( .not. ast_isabox( r4, status ) ) call stopit( status, - : 'Prism 1b' ) - if( hasframeset( r4, status ) ) call stopit( status, 'Prism 1c' ) - if( ast_overlap( r3, r4, status ) .ne. 5 ) call stopit( status, - : 'Prism 1d' ) - - - lbnd( 1 ) = 5500.0 - ubnd( 1 ) = 5800.0 - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r4 = ast_prism( r1, r2, ' ', status ) - - if( ast_overlap( r3, r4, status ) .ne. 3 ) call stopit( status, - : 'Prism 2' ) - if( ast_overlap( r4, r3, status ) .ne. 2 ) then - write(*,*) ast_overlap( r4, r3, status ),' should be 2' - call stopit( status, 'Prism 3' ) - end if - - lbnd( 1 ) = 5500.0 - ubnd( 1 ) = 6500.0 - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r4 = ast_prism( r1, r2, ' ', status ) - if( ast_overlap( r3, r4, status ) .ne. 4 ) call stopit( status, - : 'Prism 4' ) - if( ast_overlap( r4, r3, status ) .ne. 4 ) call stopit( status, - : 'Prism 5' ) - - lbnd( 1 ) = 6500.0 - ubnd( 1 ) = 7500.0 - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r4 = ast_prism( r1, r2, ' ', status ) - if( ast_overlap( r3, r4, status ) .ne. 1 ) call stopit( status, - : 'Prism 6' ) - if( ast_overlap( r4, r3, status ) .ne. 1 ) call stopit( status, - : 'Prism 7' ) - - r4 = ast_copy( r3, status ) - call ast_Negate( r4, status ) - if( ast_overlap( r4, r3, status ) .ne. 6 ) call stopit( status, - : 'Prism 8' ) - - - p1(1) = 2.0E-4 - p1(2) = 2.0E-4 - p2(1) = 1.1E-4 - p2(2) = 1.0E-4 - r1 = ast_box( f1, 0, p1, p2, AST__NULL, ' ', status ) - lbnd( 1 ) = 5000.0 - ubnd( 1 ) = 6000.0 - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r4 = ast_prism( r1, r2, ' ', status ) - if( ast_overlap( r3, r4, status ) .ne. 1 ) call stopit( status, - : 'Prism 9' ) - - p1(1) = 2.0E-4 - p1(2) = 2.0E-4 - p2(1) = 1.0E-4 - p2(2) = 1.0E-4 - r1 = ast_box( f1, 0, p1, p2, AST__NULL, ' ', status ) - r4 = ast_prism( r1, r2, ' ', status ) - if( ast_overlap( r3, r4, status ) .ne. 4 ) call stopit( status, - : 'Prism 10' ) - - call ast_setl( r3, 'Closed', .false., status ) - call ast_setl( r4, 'Closed', .false., status ) - if( ast_overlap( r3, r4, status ) .ne. 1 ) call stopit( status, - : 'Prism 11' ) - - - - f1 = ast_skyframe( 'system=fk5', status ) - p1(1) = 0.0 - p1(2) = 0.0 - p2(1) = 1.0E-4 - p2(2) = 1.0E-4 - r1 = ast_box( f1, 0, p1, p2, AST__NULL, ' ', status ) - - f2 = ast_specframe( 'System=Wavelen,Unit=Angstrom', status ) - lbnd( 1 ) = 5000.0 - ubnd( 1 ) = AST__BAD - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r3 = ast_prism( r1, r2, ' ', status ) - - lbnd( 1 ) = 6000.0 - ubnd( 1 ) = AST__BAD - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r4 = ast_prism( r1, r2, ' ', status ) - - call ast_setc( r3, 'system(1)', 'galactic', status ) - - if( ast_overlap( r3, r4, status ) .ne. 3 ) call stopit( status, - : 'Prism 12' ) - - ubnd( 1 ) = 6000.0 - lbnd( 1 ) = AST__BAD - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r4 = ast_prism( r1, r2, ' ', status ) - - if( ast_overlap( r3, r4, status ) .ne. 4 ) call stopit( status, - : 'Prism 13' ) - - ubnd( 1 ) = 5000.0 - lbnd( 1 ) = AST__BAD - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r4 = ast_prism( r1, r2, ' ', status ) - call ast_setc( r4, 'system(3)', 'freq', status ) - if( ast_overlap( r3, r4, status ) .ne. 4 ) call stopit( status, - : 'Prism 14' ) - - call ast_setl( r4, 'closed', .false., status ) - if( ast_overlap( r3, r4, status ) .ne. 1 ) call stopit( status, - : 'Prism 15' ) - - - f1 = ast_skyframe( 'system=fk5', status ) - p1(1) = 0.0 - p1(2) = -1.57 - p2(1) = 0.8 - p2(2) = -1.5 - r1 = ast_box( f1, 0, p1, p2, AST__NULL, ' ', status ) - - f2 = ast_specframe( 'Unit=Angstrom', status ) - lbnd( 1 ) = 5000.0 - ubnd( 1 ) = 6000.0 - r2 = ast_interval( f2, lbnd, ubnd, AST__NULL, ' ', status ) - r3 = ast_prism( r1, r2, ' ', status ) - r4 = ast_Simplify( r3, status ) - - call ast_getregionbounds( r4, lbnd, ubnd, status ) - if( abs( lbnd(1) + 0.8D0 ) .gt. 1.0E-6 ) call stopit( status, - : 'Prism 16' ) - if( abs( lbnd(2) + 1.64D0 ) .gt. 1.0E-6 ) - : call stopit( status, 'Prism 17' ) - if( abs( ubnd(1) - 0.8D0 ) .gt. 1.0E-6 ) - : call stopit( status, 'Prism 18' ) - if( abs( ubnd(2) + 1.5 ) .gt. 1.0E-6 ) - : call stopit( status, 'Prism 19' ) - if( abs( lbnd(3) - 5000.0 ) .gt. 1.0E-10 ) - : call stopit( status, 'Prism 20' ) - if( abs( ubnd(3) - 6000.0 ) .gt. 1.0E-6 ) - : call stopit( status, 'Prism 21' ) - - call ast_end( status ) - if( status .ne. sai__ok ) write(*,*) 'Prism tests failed' - - end - - - - subroutine checkRemoveRegions( status ) - implicit none - - include 'SAE_PAR' - include 'AST_PAR' - - integer status, sf1, sf2, reg, fs, map, fs2 - double precision cen(2), ixin(2), iyin(2), gxin(2), gyin(2), - : xout(2), yout(2) - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - - sf1 = ast_skyframe( 'System=ICRS', status ) - cen(1) = 0.0 - cen(2) = 0.0 - reg = ast_circle( sf1, 1, cen, 0.001D0, AST__NULL, ' ', status ) - - ixin(1) = 0.0 - iyin(1) = 0.0 - ixin(2) = 0.01 - iyin(2) = 0.01 - - call ast_tran2( reg, 2, ixin, iyin, .true., xout, yout, status ) - - if( xout(1) .eq. AST__BAD .or. yout(1) .eq. AST__BAD ) then - call stopit( status, 'RemoveRegions test 1 failed' ) - - else if( abs( xout(1) - ixin(1) ) .gt. 1.0E-10 .or. - : abs( yout(1) - iyin(1) ) .gt. 1.0E-10 ) then - call stopit( status, 'RemoveRegions test 2 failed' ) - - else if( xout(2) .ne. AST__BAD .or. yout(2) .ne. AST__BAD ) then - write(*,*) xout(2), ixin(2) - write(*,*) yout(2), iyin(2) - call stopit( status, 'RemoveRegions test 3 failed' ) - end if - - - - - sf2 = ast_skyframe( 'System=Galactic', status ) - fs = ast_convert( sf1, sf2, ' ', status ) - call ast_tran2( fs, 2, ixin, iyin, .true., gxin, gyin, status ) - - fs2 = ast_frameset( sf2, ' ', status ) - call ast_addframe( fs2, AST__BASE, ast_unitmap( 2, ' ', status ), - : sf2, status ) - - - fs = ast_convert( fs2, reg, ' ', status ) - - - map = ast_getmapping( fs, AST__BASE, AST__CURRENT, status ) - call ast_tran2( map, 2, gxin, gyin, .true., xout, yout, status ) - - if( xout(1) .eq. AST__BAD .or. yout(1) .eq. AST__BAD ) then - call stopit( status, 'RemoveRegions test 4 failed' ) - - else if( abs( xout(1) - ixin(1) ) .gt. 1.0E-10 .or. - : abs( yout(1) - iyin(1) ) .gt. 1.0E-10 ) then - call stopit( status, 'RemoveRegions test 5 failed' ) - - else if( xout(2) .ne. AST__BAD .or. yout(2) .ne. AST__BAD ) then - write(*,*) xout(2), ixin(2) - write(*,*) yout(2), iyin(2) - call stopit( status, 'RemoveRegions test 6 failed' ) - end if - - - - fs2 = ast_removeregions( fs, status ) - - map = ast_getmapping( fs2, AST__BASE, AST__CURRENT, status ) - call ast_tran2( map, 2, gxin, gyin, .true., xout, yout, status ) - - if( xout(1) .eq. AST__BAD .or. yout(1) .eq. AST__BAD ) then - call stopit( status, 'RemoveRegions test 7 failed' ) - - else if( abs( xout(1) - ixin(1) ) .gt. 1.0E-10 .or. - : abs( yout(1) - iyin(1) ) .gt. 1.0E-10 ) then - call stopit( status, 'RemoveRegions test 8 failed' ) - - else if( abs( xout(2) - ixin(2) ) .gt. 1.0E-10 .or. - : abs( yout(2) - iyin(2) ) .gt. 1.0E-10 ) then - call stopit( status, 'RemoveRegions test 9 failed' ) - end if - - - - call ast_end( status ) - - end - - - - - - subroutine checkConvex( status ) - implicit none - - include 'SAE_PAR' - include 'AST_PAR' - - integer nx, ny, nel - parameter( nx = 8 ) - parameter( ny = 7 ) - parameter( nel = nx*ny ) - - integer status, poly, lbnd(2), ubnd(2), npoint - real array( nx, ny ) - double precision points( 10, 2 ) - - data array / nel*0.0 / - data lbnd / -10, 3 / - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - - ubnd( 1 ) = lbnd( 1 ) + nx- 1 - ubnd( 2 ) = lbnd( 2 ) + ny- 1 - - array( 6, 1 ) = 1.0 - array( 7, 1 ) = 1.0 - array( 8, 1 ) = 1.0 - array( 7, 2 ) = 1.0 - array( 8, 2 ) = 1.0 - array( 2, 3 ) = 1.0 - array( 8, 3 ) = 1.0 - array( 1, 4 ) = 1.0 - array( 1, 6 ) = 1.0 - array( 2, 6 ) = 1.0 - array( 6, 6 ) = 1.0 - - poly = ast_convexr( 1.0, AST__EQ, array, lbnd, ubnd, .FALSE., - : status ) - - call ast_getregionpoints( poly, 10, 2, npoint, points, status ) - - if( npoint .ne. 7 ) call stopit( status, 'Convex 1' ) - if( points( 1, 1 ) .ne. -3) call stopit( status, 'Convex 2' ) - if( points( 1, 2 ) .ne. 3) call stopit( status, 'Convex 3' ) - if( points( 2, 1 ) .ne. -3) call stopit( status, 'Convex 4' ) - if( points( 2, 2 ) .ne. 5) call stopit( status, 'Convex 5' ) - if( points( 3, 1 ) .ne. -5) call stopit( status, 'Convex 6' ) - if( points( 3, 2 ) .ne. 8) call stopit( status, 'Convex 7' ) - if( points( 4, 1 ) .ne. -10) call stopit( status, 'Convex 8' ) - if( points( 4, 2 ) .ne. 8) call stopit( status, 'Convex 9' ) - if( points( 5, 1 ) .ne. -10) call stopit( status, 'Convex 10' ) - if( points( 5, 2 ) .ne. 6) call stopit( status, 'Convex 11' ) - if( points( 6, 1 ) .ne. -9) call stopit( status, 'Convex 12' ) - if( points( 6, 2 ) .ne. 5) call stopit( status, 'Convex 13' ) - if( points( 7, 1 ) .ne. -5) call stopit( status, 'Convex 14' ) - if( points( 7, 2 ) .ne. 3) call stopit( status, 'Convex 15' ) - - call ast_end( status ) - - end - diff --git a/ast/ast_tester/testskyframe.f b/ast/ast_tester/testskyframe.f deleted file mode 100644 index 6359d63..0000000 --- a/ast/ast_tester/testskyframe.f +++ /dev/null @@ -1,89 +0,0 @@ - program testskyframe - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer status, sf1, sf2, fs - double precision vals(5) - - status = sai__ok - - sf1 = ast_skyframe( 'system=fk5,epoch=2015.0', status ) - sf2 = ast_skyframe( 'system=fk5,epoch=2015.1', status ) - fs = ast_convert( sf1, sf2, 'SKY', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'Error 0' ) - end if - - if( .not. ast_isaunitmap( ast_getmapping( fs, ast__base, - : ast__current, status ), - : status ) ) then - call stopit( status, 'Error 1' ) - end if - - if( ast_getd( sf1, 'SkyTol', status ) .ne. 0.001D0 ) then - call stopit( status, 'Error 2' ) - end if - - call ast_setd( sf2, 'SkyTol', 1.0D-6, status ) - fs = ast_convert( sf1, sf2, 'SKY', status ) - - if( ast_isaunitmap( ast_getmapping( fs, ast__base, - : ast__current, status ), - : status ) ) then - call stopit( status, 'Error 3' ) - end if - - sf2 = ast_skyframe( 'system=fk5,epoch=2016.6', status ) - fs = ast_convert( sf1, sf2, 'SKY', status ) - if( ast_isaunitmap( ast_getmapping( fs, ast__base, - : ast__current, status ), - : status ) ) then - call stopit( status, 'Error 4' ) - end if - - - vals(1) = 6.1D0 - vals(2) = 6.15D0 - vals(3) = 6.2D0 - vals(4) = 6.25D0 - vals(5) = 6.3D0 - call ast_axnorm( sf1, 1, 0, 5, vals, status ) - if( vals(1) .ne. 6.1D0 .or. - : vals(2) .ne. 6.15D0 .or. - : vals(3) .ne. 6.2D0 .or. - : vals(4) .ne. 6.25D0 .or. - : vals(5) .ne. 6.3D0 - 2*AST__DPI ) then - call stopit( status, 'Error 5' ) - end if - - call ast_axnorm( sf1, 1, 1, 5, vals, status ) - if( vals(1) .ne. 6.1D0 - 2*AST__DPI .or. - : vals(2) .ne. 6.15D0 - 2*AST__DPI .or. - : vals(3) .ne. 6.2D0 - 2*AST__DPI .or. - : vals(4) .ne. 6.25D0 - 2*AST__DPI .or. - : vals(5) .ne. 6.3D0 - 2*AST__DPI ) then - call stopit( status, 'Error 6' ) - end if - - if( status .eq. sai__ok ) then - write(*,*) 'All SkyFrame tests passed' - else - write(*,*) 'SkyFrame tests failed' - end if - - end - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - diff --git a/ast/ast_tester/testspecflux.f b/ast/ast_tester/testspecflux.f deleted file mode 100644 index ba19984..0000000 --- a/ast/ast_tester/testspecflux.f +++ /dev/null @@ -1,331 +0,0 @@ - program testspecflux - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - double precision xin, xout,yin, yout - integer status, sff, sff2, sf, ff, ff2, mp, fs, sf2,perm(2),csff - status = sai__ok - - sf = ast_specframe( 'system=freq,unit=GHz', status ) - ff = ast_Fluxframe( 123.0D0, sf, 'Unit=Jy', status ) - sff = ast_specfluxframe( sf, ff, ' ', status ) - - - if( ast_GetC( sff, 'class', status ) .ne. 'SpecFluxFrame' ) then - call stopit( status, 'Error 0' ) - end if - - if( ast_GetD( sff, 'specval', status ) .ne. 123.0D0 ) then - call stopit( status, 'Error 1' ) - end if - - if( ast_Test( sff, 'specval', status ) ) then - call stopit( status, 'Error 2' ) - end if - - call ast_setd( sff, 'specval', 333.3D0, status ) - if( ast_GetD( sff, 'specval', status ) .ne. 333.3D0 ) then - call stopit( status, 'Error 3' ) - end if - - if( .not. ast_Test( sff, 'specval', status ) ) then - call stopit( status, 'Error 4' ) - end if - - call ast_clear( sff, 'specval', status ) - - if( ast_GetD( sff, 'specval', status ) .ne. 123.0D0 ) then - call stopit( status, 'Error 5' ) - end if - - if( ast_Test( sff, 'specval', status ) ) then - call stopit( status, 'Error 6' ) - end if - - - call checkDump( sff, 'CheckDump 1', status ) - - - ff2 = ast_Fluxframe( 123.1D0, sf, 'System=flxdnw', status ) - - if( ast_getc( ff2, 'unit', status ) .ne. 'W/m^2/Angstrom' ) - : call stopit( status, 'Error 6B' ) - if( ast_getc( ff2, 'system', status ) .ne. 'FLXDNW' ) - : call stopit( status, 'error 6C' ) - - sff2 = ast_specfluxframe( sf, ff2, ' ', status ) - if( ast_GetC( sff2, 'class', status ) .ne. 'SpecFluxFrame' ) then - call stopit( status, 'Error 7' ) - end if - - csff = ast_copy( sff,status ) - fs = ast_convert( sff, sff2, ' ', status ) - if( fs .eq. ast__null ) call stopit( status, 'error 8' ) - - yin = 1.0D0 - xin = 2.0D0 - call ast_tran2( fs, 1, xin, yin, .true., xout, yout, status ) - - if( abs(yout - 1.33425638D-26) .gt. 1.0D-32 ) - : call stopit( status, 'error 9' ) - - if( xout .ne. 2.0D0 ) call stopit( status, 'error 10' ) - - perm(1)=2 - perm(2)=1 - call ast_PermAxes( sff2, perm, status ) - - fs = ast_convert( sff, sff2, ' ', status ) - if( fs .eq. ast__null ) call stopit( status, 'error 11' ) - call ast_tran2( fs, 1, xin, yin, .true., xout, yout, status ) - - if( abs(xout - 1.33425638D-26) .gt. 1.0D-32 ) - : call stopit( status, 'error 12' ) - - if( yout .ne. 2.0D0 ) call stopit( status, 'error 13' ) - - perm(1)=2 - perm(2)=1 - call ast_PermAxes( sff, perm, status ) - - fs = ast_convert( sff, sff2, ' ', status ) - if( fs .eq. ast__null ) call stopit( status, 'error 14' ) - - yin = 2.0D0 - xin = 1.0D0 - call ast_tran2( fs, 1, xin, yin, .true., xout, yout, status ) - - if( abs(xout - 1.33425638D-26) .gt. 1.0D-32 ) - : call stopit( status, 'error 15' ) - - if( yout .ne. 2.0D0 ) call stopit( status, 'error 16' ) - - - - ff2 = ast_Fluxframe( AST__BAD, AST__NULL, 'Unit=log(W/m2/nm)', - : status ) - if( ast_getc( ff2, 'system', status ) .ne. 'FLXDNW' ) - : call stopit( status, 'error 17' ) - sff2 = ast_specfluxframe( sf, ff2, ' ', status ) - - fs = ast_convert( csff, sff2, ' ', status ) - if( fs .eq. ast__null ) call stopit( status, 'error 18' ) - - yin = 1.0D0 - xin = 2.0D0 - call ast_tran2( fs, 1, xin, yin, .true., xout, yout, status ) - - if( abs(yout + 24.8747607 ) .gt. 0.000001 ) then - write(*,*) yout + 24.8747607 - call stopit( status, 'error 19' ) - endif - - if( xout .ne. 2.0D0 ) call stopit( status, 'error 20' ) - - - call ast_tran2( fs, 1, xout, yout, .false., xin, yin, status ) - - if( abs( xin - 2.0D0 ) .gt. 1.0D-9 ) call stopit( status, - : 'error 21' ) - if( abs( yin - 1.0D0 ) .gt. 1.0D-9 ) call stopit( status, - : 'error 22' ) - - - - - - ff2 = ast_Fluxframe( AST__BAD, AST__NULL, 'Unit=log(W/m2/nm/sr)', - : status ) - if( ast_getc( ff2, 'system', status ) .ne. 'SFCBRW' ) - : call stopit( status, 'error 23' ) - sff2 = ast_specfluxframe( sf, ff2, ' ', status ) - - sf = ast_specframe( 'system=freq,unit=GHz', status ) - ff = ast_Fluxframe( 123.0D0, sf, 'Unit=Jy/deg**2', status ) - if( ast_getc( ff, 'system', status ) .ne. 'SFCBR' ) - : call stopit( status, 'error 24' ) - sff = ast_specfluxframe( sf, ff, ' ', status ) - - fs = ast_convert( sff, sff2, ' ', status ) - if( fs .eq. ast__null ) call stopit( status, 'error 25' ) - - yin = 1.0D0 - xin = 2.0D0 - call ast_tran2( fs, 1, xin, yin, .true., xout, yout, status ) - - if( abs(yout + 21.3585154D0 ) .gt. 0.000001 ) - : call stopit( status, 'error 26' ) - - if( xout .ne. 2.0D0 ) call stopit( status, 'error 27' ) - - call ast_tran2( fs, 1, xout, yout, .false., xin, yin, status ) - if( abs( xin - 2.0D0 ) .gt. 1.0D-9 ) call stopit( status, - : 'error 28' ) - if( abs( yin - 1.0D0 ) .gt. 1.0D-9 ) call stopit( status, - : 'error 29' ) - - - - - - - - - - - - - - - - - - if( status .eq. sai__ok ) then - write(*,*) 'All SpecFluxFrame tests passed' - else - write(*,*) 'SpecFluxFrame tests failed' - end if - - end - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - - subroutine checkdump( obj, text, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*) - integer obj, status, next, end, ch, result, ll, overlap - external mysource, mysink - character buf*25000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - ch = ast_channel( mysource, mysink, ' ', status ) - - - ll = 110 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - - next = 1 - result = ast_read( ch, status ) - if( result .eq. ast__null ) then - write(*,*) text - call stopit( status, 'Cannot read object from channel' ) - end if - - - - if( ast_getd( obj, 'specval', status ) .ne. - : ast_getd( result, 'specval', status ) ) then - call ast_Show( obj, status ) - call ast_Show( result, status ) - write(*,*) text - call stopit( status, 'Object has changed' ) - end if - - end - - subroutine sink1( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - logical fsfound, done - common /sink1com/ fsfound, done - - integer status, l - character line*200 - - if( status .ne. sai__ok ) return - call ast_getline( line, l, status ) - - if( index( line( : l ),'Unc =' ) .GT. 0 ) then - done = .true. - - else if( .not. done .and. - : index( line( : l ),'FrameSet' ) .GT. 0 ) then - fsfound= .true. - end if - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll - character buf*25000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - call ast_putline( buf( next : ), ll, status ) - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll - character buf*25000 - character line*1000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - - if( next + ll - 1 .ge. 25000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf( next : next + l) - write(*,*) 'Line length ',l - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - endif - - next = next + ll - - end - - diff --git a/ast/ast_tester/testspecframe.f b/ast/ast_tester/testspecframe.f deleted file mode 100644 index 4af2606..0000000 --- a/ast/ast_tester/testspecframe.f +++ /dev/null @@ -1,251 +0,0 @@ - program testspecframe - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - double precision rf, x, y - integer status, sf, sf1, sf2, fs - status = sai__ok - - sf = ast_specframe( 'system=freq,unit=Hz', status ) - if( ast_GetD( sf, 'SpecOrigin', status ) .ne. 0.0 ) then - call stopit( status, 'Error 0' ) - end if - - rf = ast_GetD( sf, 'RestFreq', status ) - call ast_SetD( sf, 'SpecOrigin', rf*1.0D9, status ) - if( abs( ast_GetD( sf, 'SpecOrigin', status ) - rf*1.0D9 ) - : .gt. 0.1 ) then - call stopit( status, 'Error 1' ) - end if - - call ast_setc( sf, 'Unit(1)', 'GHz', status ) - if( ast_GetD( sf, 'SpecOrigin', status ) .ne. rf ) then - call stopit( status, 'Error 2' ) - end if - - call checkdump( sf, 'Error 3', status ) - - call ast_setc( sf, 'System', 'vrad', status ) - if( abs( ast_GetD( sf, 'SpecOrigin', status ) ) .gt. 1.0D-8 ) then - write(*,*) ast_GetD( sf, 'SpecOrigin', status ) - call stopit( status, 'Error 4' ) - end if - - call ast_setc( sf, 'System', 'freq', status ) - call ast_setc( sf, 'Unit(1)', 'Hz', status ) - - if( abs( ast_GetD( sf, 'SpecOrigin', status ) - rf*1.0D9 ) - : .gt. 0.1 ) then - write(*,*) ast_GetD( sf, 'SpecOrigin', status ) - call stopit( status, 'Error 5' ) - end if - - call ast_setc( sf, 'StdOfRest', 'LSRD', status ) - if( abs( ast_GetD( sf, 'SpecOrigin', status ) - - : rf*1.00000212890848D9 ) .gt. 10.0 ) then - write(*,*) ast_GetD( sf, 'SpecOrigin', status ) - write(*,*) 'Should be ',rf*1.00000212890848D9 - call stopit( status, 'Error 6' ) - end if - - - sf1 = ast_specframe( 'system=freq,unit=Hz', status ) - call ast_setd( sf1, 'SpecOrigin', 1.0D20, status ) - sf2 = ast_specframe( 'system=freq,unit=Hz', status ) - call ast_setd( sf2, 'SpecOrigin', 1.01D20, status ) - fs = ast_convert( sf1, sf2, "", status ); - - x = 0.03D20 - call ast_tran1( fs, 1, x, .true., y, status ) - if( abs( y - 0.02D20 ) .gt. 0.0 ) then - write(*,*) y, y - 0.02D20 - call stopit( status, 'Error 7' ) - end if - - if( ast_getl( sf1, 'AlignSpecOffset', status ) ) then - call stopit( status, 'Error 8' ) - end if - call ast_setl( sf1, 'AlignSpecOffset', .true., status ) - call ast_setl( sf2, 'AlignSpecOffset', .true., status ) - - fs = ast_convert( sf1, sf2, "", status ); - - x = 0.03D20 - call ast_tran1( fs, 1, x, .true., y, status ) - if( abs( y - x ) .gt. 0.0 ) then - write(*,*) y, y - x - call stopit( status, 'Error 9' ) - end if - - sf = ast_specframe( 'system=freq,unit=Hz', status ) - call ast_setc( sf, 'SourceVRF', 'LSRK', status ) - call ast_setd( sf, 'SourceVel', 1000.0D0, status ) - - call ast_setc( sf, 'SourceVRF', 'BARY', status ) - call ast_setc( sf, 'SourceSys', 'ZOPT', status ) - - if( abs( ast_getd( sf, 'SourceVel', status ) - - : 0.00334028336870307D0 ) .gt. 1.0D-10 ) then - write(*,*) ast_getd( sf, 'SourceVel', status ) - call stopit( status, 'Error 11' ) - end if - - call checkdump( sf, 'Error 10', status ) - call ast_setc( sf, 'SourceVRF', 'LSRK', status ) - call ast_setc( sf, 'SourceSys', 'VREL', status ) - - if( abs( ast_getd( sf, 'SourceVel', status ) - - : 1000.0D0 ) .gt. 1.0D-6 ) then - write(*,*) ast_getd( sf, 'SourceVel', status ) - call stopit( status, 'Error 12' ) - end if - - if( status .eq. sai__ok ) then - write(*,*) 'All SpecFrame tests passed' - else - write(*,*) 'SpecFrame tests failed' - end if - - end - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - - subroutine checkdump( obj, text, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*) - integer obj, status, next, end, ch, result, ll, overlap - external mysource, mysink - character buf*25000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - ch = ast_channel( mysource, mysink, ' ', status ) - - - ll = 110 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - - next = 1 - result = ast_read( ch, status ) - if( result .eq. ast__null ) then - write(*,*) text - call stopit( status, 'Cannot read object from channel' ) - end if - - - - if( ast_getd( obj, 'specorigin', status ) .ne. - : ast_getd( result, 'specorigin', status ) ) then - call ast_Show( obj, status ) - call ast_Show( result, status ) - write(*,*) text - call stopit( status, 'Object has changed' ) - end if - - end - - subroutine sink1( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - logical fsfound, done - common /sink1com/ fsfound, done - - integer status, l - character line*200 - - if( status .ne. sai__ok ) return - call ast_getline( line, l, status ) - - if( index( line( : l ),'Unc =' ) .GT. 0 ) then - done = .true. - - else if( .not. done .and. - : index( line( : l ),'FrameSet' ) .GT. 0 ) then - fsfound= .true. - end if - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll - character buf*25000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - call ast_putline( buf( next : ), ll, status ) - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll - character buf*25000 - character line*1000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - - if( next + ll - 1 .ge. 25000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf( next : next + l) - write(*,*) 'Line length ',l - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - endif - - next = next + ll - - end - - diff --git a/ast/ast_tester/teststc.f b/ast/ast_tester/teststc.f deleted file mode 100644 index 47c3c02..0000000 --- a/ast/ast_tester/teststc.f +++ /dev/null @@ -1,1858 +0,0 @@ - program teststc - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'PRM_PAR' - - - - integer status - - status = sai__ok - - -c call ast_SetWatchId( 565300 ) - - call ast_begin( status ) - call Example5( status ) - call Example1( status ) - call Example1b( status ) - call Example4( status ) - call misc( status ) - call Example3( status ) - call Example2( status ) - call ast_end( status ) - -c call ast_listissued( 'teststc' ) - - - if( status .eq. sai__ok ) then - write(*,*) 'All Stc tests passed' - else - write(*,*) 'Stc tests failed' - end if - - end - - - subroutine misc( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - - - integer status, obj1, obj2, overlap - double precision x, y, xo, yo - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - - call puteg( 'teststc_eg6', 1, status ) - call xmlread( 1, obj1, ' ', status ) - obj1 = ast_simplify( obj1, status ) - call checkdump( obj1, 'checkdump 1', status ) - - call puteg( 'teststc_eg7', 1, status ) - call xmlread( 1, obj2, ' ', status ) - obj2 = ast_simplify( obj2, status ) - call checkdump( obj2, 'checkdump 2', status ) - - overlap = ast_overlap( obj1, obj2, status ) - if( overlap .ne. 4 .and.status .eq. sai__ok ) then - write(*,*) 'Overlap is ',overlap,' (should be 4)' - call stopit( status, 'Error 1' ) - endif - - call puteg( 'teststc_eg8', 1, status ) - call xmlread( 1, obj2, ' ', status ) - obj2 = ast_simplify( obj2, status ) - call checkdump( obj2, 'checkdump 3', status ) - - overlap = ast_overlap( obj1, obj2, status ) - if( overlap .ne. 3 .and.status .eq. sai__ok ) then - write(*,*) 'Overlap is ',overlap,' (should be 3)' - call stopit( status, 'Error 2' ) - endif - - overlap = ast_overlap( obj2, obj1, status ) - if( overlap .ne. 2 .and.status .eq. sai__ok ) then - write(*,*) 'Overlap is ',overlap,' (should be 2)' - call stopit( status, 'Error 3' ) - endif - - call puteg( 'teststc_eg9', 1, status ) - call xmlread( 1, obj2, ' ', status ) - - overlap = ast_overlap( obj1, obj2, status ) - if( overlap .ne. 1 .and.status .eq. sai__ok ) then - write(*,*) 'Overlap is ',overlap,' (should be 1)' - call stopit( status, 'Error 4' ) - endif - - - call puteg( 'teststc_eg10', 1, status ) - call xmlread( 1, obj2, ' ', status ) - - x = 2.4958208 - y = 0.73303829 - call ast_tran2( obj2, 1, x, y, .true., xo, yo, status ) - if( xo .ne. 2.4958208 .or. yo .ne. 0.73303829 ) then - call stopit( status, 'Error 5' ) - end if - - x = 2.4958208 - y = -0.73303829 - call ast_tran2( obj2, 1, x, y, .true., xo, yo, status ) - if( xo .ne. AST__BAD .or. yo .ne. AST__BAD ) then - call stopit( status, 'Error 6' ) - end if - - - - - call ast_end( status ) - - if( status .ne. sai__ok ) write(*,*) 'teststc: miscellaneous '// - : 'tests failed' - - end - - subroutine Example1( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - - integer status, obj2, obj, i, j, unc, km, nval, fs, m, r, f, - : axes(2), map - double precision in(8,4), out(8,4), lbnd(5), ubnd(5) - character cvals(10)*30 - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - -* Put an example of an STCResourceProfile into file 1. - call puteg( 'teststc_eg1', 1, status ) - -* Use a new XmlChan to read an object from file 1,and simplify it. - call xmlread( 1, obj, ' ', status ) - obj = ast_simplify( obj, status ) - -* Write out the object through a Channel and read it back. - call checkdump( obj, 'checkdump 1', status ) - -* Test simplify by negating and simplifying twice. - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - -* Check it is a STCResourceProfile - if( .not. ast_isastcresourceprofile( obj, status ) ) - : call stopit( status, 'Error 1' ) - -* Check it contains an Interval. - if( .not. ast_isainterval( ast_getstcregion( obj, status ), - : status ) ) - : call stopit( status, 'Error 1a' ) - -* Timescale should be tt. Try changing it to TAI. - if( ast_getc( obj, 'timescale', status ) .ne. 'TT' ) - : call stopit( status, 'Error 0a' ) - - if( abs( ast_getd(obj,'TimeOrigin',status)-51382.6666666D0 ) - : .gt. 1.0D-7 ) call stopit( status, 'Error 0b' ) - - call ast_getregionbounds( obj, lbnd, ubnd, status ) - if( lbnd(3) .ne. 0.0 ) call stopit( status, 'Error 0c' ) - - call ast_set( obj, 'timescale=tai', status ) - if( ast_getc( obj, 'timescale', status ) .ne. 'TAI' ) - : call stopit( status, 'Error 0d' ) - - if( abs( ast_getd(obj,'TimeOrigin',status)-51382.6662941667D0 ) - : .gt. 1.0D-7 ) call stopit( status, 'Error 0e' ) - - call ast_getregionbounds( obj, lbnd, ubnd, status ) - if( abs( lbnd(3) ) .gt. 1.0D-6 ) THEN - write(*,*) lbnd(3) - call stopit( status, 'Error 0f' ) - END IF - - - call ast_set( obj, 'timescale=tt', status ) - obj = ast_Simplify( obj, status ) - if( ast_getc( obj, 'timescale', status ) .ne. 'TT' ) - : call stopit( status, 'Error 0g' ) - - if( abs( ast_getd(obj,'TimeOrigin',status)-51382.6666666D0 ) - : .gt. 1.0D-7 ) call stopit( status, 'Error 0h' ) - - call ast_getregionbounds( obj, lbnd, ubnd, status ) - if( abs( lbnd(3) ) .gt. 1.0D-6 ) - : call stopit( status, 'Error 0i' ) - - - -* Other tests - if( ast_getd( obj, 'fillfactor', status ) .ne. 0.02D0 ) - : call stopit( status, 'Error 1b' ) - - if( ast_getc( obj, 'ident', status ) .ne. 'AllSky-CXO' ) - : call stopit( status, 'Error 1c' ) - - if( ast_getc( obj, 'domain(3)', status ) .ne. 'TIME' ) - : call stopit( status, 'Error 2' ) - - if( ast_getc( obj, 'title(3)', status ) .ne. 'Time' ) - : call stopit( status, 'Error 2a' ) - - if( ast_getc( obj, 'label(3)', status ) .ne. - : 'Modified Julian Date offset from 1999-07-23 16:00:00' ) THEN - call stopit( status, 'Error 2b' ) - end if - - if( ast_getc( obj, 'domain(1)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 3' ) - - if( ast_getc( obj, 'system(1)', status ) .ne. 'ICRS' ) - : call stopit( status, 'Error 3a' ) - - if( ast_getc( obj, 'label(1)', status ) .ne. 'Right ascension' ) - : call stopit( status, 'Error 3b' ) - - if( ast_getc( obj, 'label(2)', status ) .ne. 'Declination' ) - : call stopit( status, 'Error 3c' ) - - if( ast_getc( obj, 'title(2)', status ) .ne. 'Space' ) - : call stopit( status, 'Error 3d' ) - - if( ast_getc( obj, 'domain(2)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 4' ) - - if( ast_getc( obj, 'domain(4)', status ) .ne. 'SPECTRUM' ) - : call stopit( status, 'Error 5' ) - - if( ast_getc( obj, 'system(4)', status ) .ne. 'ENER' ) - : call stopit( status, 'Error 5a' ) - - if( ast_getc( obj, 'stdofrest', status ) .ne. 'Topocentric' ) - : call stopit( status, 'Error 5b' ) - - if( ast_getc( obj, 'title(4)', status ) .ne. - : 'Energy (Topocentric)' ) call stopit( status, 'Error 5c' ) - - if( ast_getc( obj, 'unit(4)', status ) .ne. 'keV' ) - : call stopit( status, 'Error 5d' ) - - if( ast_geti( obj, 'naxes', status ) .ne. 4 ) - : call stopit( status, 'Error 6' ) - - in(1,1) = 10.0 - in(1,2) = 10.0 - in(1,3) = -0.1 - in(1,4) = 0.11 - - in(2,1) = -10.0 - in(2,2) = 10.0 - in(2,3) = 0.1 - in(2,4) = 0.11 - - in(3,1) = 0.0 ! inside - in(3,2) = 0.0 - in(3,3) = 100.0 - in(3,4) = 0.13 - - in(4,1) = -1.0 - in(4,2) = 1.0 - in(4,3) = -100.0 - in(4,4) = 0.13 - - in(5,1) = 10.0 - in(5,2) = 10.0 - in(5,3) = -1000.0 - in(5,4) = 9.9 - - in(6,1) = -10.0 ! inside - in(6,2) = 10.0 - in(6,3) = 1000.0 - in(6,4) = 9.9 - - in(7,1) = 0.0 - in(7,2) = 0.0 - in(7,3) = 10.0 - in(7,4) = 10.1 - - in(8,1) = -1.0 - in(8,2) = 1.0 - in(8,3) = -10.0 - in(8,4) = 10.1 - - call ast_trann( obj, 8, 4, 8, in, .true., 4, 8, out, status ) - - do i = 1, 8 - if( i .eq. 3 .or. i .eq. 6 ) then - do j = 1, 4 - if( out(i,j) .ne. in(i,j) ) then - if( status .eq. sai__ok ) then - write(*,*) i,j,out(i,j),in(i,j) - call stopit( status, 'Error 7' ) - end if - end if - end do - else - do j = 1, 4 - if( out(i,j) .ne. AST__BAD ) then - if( status .eq. sai__ok ) then - write(*,*) i,j,out(i,j),in(i,j) - call stopit( status, 'Error 8' ) - end if - end if - end do - end if - end do - -* AstroCoords - if( ast_getstcncoord( obj, status ) .ne. 1 ) then - call stopit( status, 'Error 25' ) - end if - km = ast_getstccoord( obj, 1, status ) - - if( ast_mapsize( km, status ) .ne. 4 ) then - call stopit( status, 'Error 25b' ) - endif - - if( .not. ast_mapget0A( km, AST__STCERROR, r, status ) ) then - call stopit( status, 'Error 26' ) - else if( .not.ast_isabox( r, status ) ) then - call stopit( status, 'Error 27' ) - else if( ast_geti( r, 'naxes', status ) .ne. 4 ) then - call stopit( status, 'Error 28' ) - else - fs = ast_convert( obj, r, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'Error 29' ) - else - m = ast_getMapping( fs, AST__BASE, AST__CURRENT, status ) - m = ast_simplify( m, status ) - if( .not. ast_isaunitmap( m, status ) ) then - call stopit( status, 'Error 30' ) - endif - end if - - - call ast_getregionbounds( r, lbnd, ubnd, status ) - - if( abs( lbnd(1)+2.42406841E-06 ) .gt. 0.0001E-6 ) - : call stopit( status, 'Error 31a' ) - if( abs( ubnd(1)-2.42406841E-06 ) .gt. 0.0001E-6 ) - : call stopit( status, 'Error 31b' ) - if( abs( lbnd(2)+2.42406841E-06 ) .gt. 0.0001E-6 ) - : call stopit( status, 'Error 31c' ) - if( abs( ubnd(2)-2.42406841E-06 ) .gt. 0.0001E-6 ) - : call stopit( status, 'Error 31d' ) - if( abs( 0.5*(ubnd(3)+lbnd(3)) ) .gt. 1.0E-10) - : call stopit( status, 'Error 31e' ) - if( abs( 0.5*(ubnd(3)-lbnd(3))-0.578703703718D-09 ) .gt. - : 1.0E-15 ) call stopit( status, 'Error 31e2' ) - if( abs( lbnd(4)-5.01 ) .gt. 0.00001 ) - : call stopit( status, 'Error 31g' ) - if( abs( ubnd(4)-5.11 ) .gt. 0.00001 ) - : call stopit( status, 'Error 31h' ) - - end if - - - if( .not. ast_mapget1C( km, AST__STCNAME, 6, nval, cvals, - : status ) ) then - call stopit( status, 'Error 32' ) - - else if( nval .ne. 4 ) then - call stopit( status, 'Error 33' ) - else - if( cvals(1) .ne. 'Position' ) - : call stopit( status, 'Error 34a' ) - if( cvals(2) .ne. 'Position' ) - : call stopit( status, 'Error 34b' ) - if( cvals(3) .ne. 'Time' ) - : call stopit( status, 'Error 34c' ) - if( cvals(4) .ne. 'Energy' ) - : call stopit( status, 'Error 34d' ) - end if - - if( .not. ast_mapget0A( km, AST__STCRES, r, status ) ) then - call stopit( status, 'Error 35' ) - else if( .not.ast_isabox( r, status ) ) then - call stopit( status, 'Error 36' ) - else if( ast_geti( r, 'naxes', status ) .ne. 4 ) then - call stopit( status, 'Error 37' ) - else - fs = ast_convert( obj, r, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'Error 38' ) - else - m = ast_getMapping( fs, AST__BASE, AST__CURRENT, status ) - m = ast_simplify( m, status ) - if( .not. ast_isaunitmap( m, status ) ) then - call stopit( status, 'Error 39' ) - endif - end if - - call ast_getregionbounds( r, lbnd, ubnd, status ) - - if( abs( lbnd(1)+1.2120342E-06 ) .gt. 0.0001E-6 ) - : call stopit( status, 'Error 40a' ) - if( abs( ubnd(1)-1.2120342E-06 ) .gt. 0.0001E-6 ) - : call stopit( status, 'Error 40b' ) - if( abs( lbnd(2)+1.2120342E-06 ) .gt. 0.0001E-6 ) - : call stopit( status, 'Error 40c' ) - if( abs( ubnd(2)-1.2120342E-06 ) .gt. 0.0001E-6 ) - : call stopit( status, 'Error 40d' ) - - if( abs( 86400.0D0*(ubnd(3)-lbnd(3))-1.6D-5 ) .gt. 1.0E-10 ) - : call stopit( status, 'Error 40e' ) - if( abs( 0.5*(ubnd(3)+lbnd(3)) ) .gt. 1.0E-10 ) - : call stopit( status, 'Error 40f' ) - if( abs( lbnd(4)-5.05 ) .gt. 0.00001 ) - : call stopit( status, 'Error 40g' ) - if( abs( ubnd(4)-5.07 ) .gt. 0.00001 ) - : call stopit( status, 'Error 40h' ) - - end if - - if( .not. ast_mapget0A( km, AST__STCSIZE, r, status ) ) then - call stopit( status, 'Error 41' ) - else if( .not.ast_isabox( r, status ) ) then - call stopit( status, 'Error 42' ) - else if( ast_geti( r, 'naxes', status ) .ne. 4 ) then - call stopit( status, 'Error 43' ) - else - fs = ast_convert( obj, r, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'Error 44' ) - else - m = ast_getMapping( fs, AST__BASE, AST__CURRENT, status ) - m = ast_simplify( m, status ) - if( .not. ast_isaunitmap( m, status ) ) then - call stopit( status, 'Error 45' ) - endif - end if - - call ast_getregionbounds( r, lbnd, ubnd, status ) - - if( abs( lbnd(1)+0.00242406841 ) .gt. 0.01E-6 ) - : call stopit( status, 'Error 46a' ) - if( abs( ubnd(1)-0.00242406841 ) .gt. 0.01E-6 ) - : call stopit( status, 'Error 46b' ) - if( abs( lbnd(2)+0.00242406841 ) .gt. 0.01E-6 ) - : call stopit( status, 'Error 46c' ) - if( abs( ubnd(2)-0.00242406841 ) .gt. 0.01E-6 ) - : call stopit( status, 'Error 46d' ) - if( abs( 86400.0D0*(ubnd(3)-lbnd(3))- 1000.0 ) .gt. 1.0E-10 ) - : call stopit( status, 'Error 46e' ) - if( abs( 0.5*(ubnd(3)+lbnd(3)) ) .gt. 1.0E-10 ) - : call stopit( status, 'Error 46f' ) - if( abs( lbnd(4)-4.06 ) .gt. 0.001 ) - : call stopit( status, 'Error 46g' ) - if( abs( ubnd(4)-6.06 ) .gt. 0.001 ) - : call stopit( status, 'Error 46h' ) - - end if - - - - - - - obj2 = ast_Copy( obj, status ) - - call ast_setl( obj2, 'Adaptive', .false., status ) - call ast_setc( obj2, 'epoch', '2005', status ) - call ast_clear( obj2, 'Adaptive', status ) - - call ast_setc( obj2, 'system(1)', 'galactic', status ) - - if( ast_getstcncoord( obj2, status ) .ne. 1 ) then - call stopit( status, 'Error 25b' ) - end if - km = ast_getstccoord( obj2, 1, status ) - - if( ast_mapsize( km, status ) .ne. 3 ) then - call stopit( status, 'Error 25bb' ) - end if - - if( .not. ast_mapget0A( km, AST__STCERROR, r, status ) ) then - call stopit( status, 'Error 26b' ) - else if( .not.ast_isaprism( r, status ) ) then - call stopit( status, 'Error 27b' ) - else if( ast_geti( r, 'naxes', status ) .ne. 4 ) then - call stopit( status, 'Error 28b' ) - else - fs = ast_convert( obj2, r, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'Error 29b' ) - else - m = ast_getMapping( fs, AST__BASE, AST__CURRENT, status ) - m = ast_simplify( m, status ) - if( .not. ast_isaunitmap( m, status ) ) then - call stopit( status, 'Error 30b' ) - endif - end if - - call ast_getregionbounds( r, lbnd, ubnd, status ) - - if( abs( lbnd(1)-1.68139639 ) .gt. 1.0E-7 ) - : call stopit( status, 'Error 31ab' ) - if( abs( ubnd(1)-1.68140922 ) .gt. 1.0E-7 ) - : call stopit( status, 'Error 31bb' ) - if( abs( lbnd(2)+1.05049161 ) .gt. 1.0E-7 ) - : call stopit( status, 'Error 31cb' ) - if( abs( ubnd(2)+1.05048523 ) .gt. 1.0E-7 ) - : call stopit( status, 'Error 31db' ) - if( abs( 0.5*86400.0D0*(ubnd(3)-lbnd(3))- 5.0D-5) .gt. 1.0E-10) - : call stopit( status, 'Error 31eb' ) - if( abs( 0.5*86400.0D0*(ubnd(3)+lbnd(3))) .gt. 1.0E-10 ) - : call stopit( status, 'Error 31fb' ) - if( abs( lbnd(4)-5.01 ) .gt. 0.000001 ) - : call stopit( status, 'Error 31gb' ) - if( abs( ubnd(4)-5.11 ) .gt. 0.000001 ) - : call stopit( status, 'Error 31hb' ) - - end if - - - if( ast_mapget1C( km, AST__STCNAME, 6, nval, cvals, status )) - : call stopit( status, 'Error 32b' ) - - -* Uncertainty tests - - unc = ast_getunc( obj, .true., status ) - - if( unc .eq. AST__NULL ) call stopit( status, 'Error 9' ) - if( ast_getunc( unc, .false., status ) .ne. AST__NULL ) - : call stopit( status, 'Error 9a' ) - - call ast_getregionbounds( unc, lbnd, ubnd, status ) - - - if( abs( lbnd(1) + 2.42406841E-06 ) .gt. 0.0000001E-06 ) - : call stopit( status, 'Error 10' ) - - if( abs( lbnd(2) + 2.42406841E-06 ) .gt. 0.0000001E-06 ) - : call stopit( status, 'Error 11' ) - -c if( abs( 86400.0D0*lbnd(3) + 4.9662776D-5 ) .gt. 0.1E-10 ) -c : call stopit( status, 'Error 12' ) - if( abs( lbnd(4) - 0.07 ) .gt. 0.0001 ) - : call stopit( status, 'Error 13' ) - if( abs( ubnd(1) - 2.42406841E-06 ) .gt. 0.0000001E-06 ) - : call stopit( status, 'Error 14' ) - if( abs( ubnd(2) - 2.42406841E-06 ) .gt. 0.0000001E-06 ) - : call stopit( status, 'Error 15' ) -c if( abs( 86400.0D0*ubnd(3) - 4.9662776D-5 ) .gt. 0.1E-10 ) -c : call stopit( status, 'Error 16' ) - if( abs( ubnd(4) - 0.17 ) .gt. 0.0001 ) - : call stopit( status, 'Error 17' ) - - -* UseDefs tests. -c if( status .eq. SAI__OK ) then -c obj2 = ast_copy( obj, status ) -c call err_begin( status ) -c call ast_set( obj2, 'System=FK4', status ) -c if( status .ne. AST__NOVAL ) then -c write(*,*) 'status is ',status,': should be ',AST__NOVAL -c if( status .ne. sai__ok ) call err_annul( status ) -c call stopit( status, 'Error 18' ) -c else -c call err_annul( status ) -c end if -c call err_end( status ) -c call ast_annul( obj2, status ) -c end if -c -c if( status .eq. SAI__OK ) then -c obj2 = ast_copy( obj, status ) -c call err_begin( status ) -c call ast_set( obj2, 'System=velo', status ) -c if( status .ne. AST__NOVAL ) then -c write(*,*) 'status is ',status,': should be ',AST__NOVAL -c if( status .ne. sai__ok ) call err_annul( status ) -c call stopit( status, 'Error 19' ) -c else -c call err_annul( status ) -c end if -c call err_end( status ) -c call ast_annul( obj2, status ) -c end if - - call ast_set( obj, 'Unit(4)=J', status ) - - if( status .ne. SAI__OK ) call stopit( status, 'Error 20' ) - -* Tests on reference values - if( ast_test( obj, 'RefRA(4)', status ) ) then - call stopit( status, 'Error 21' ) - end if - - if( ast_test( obj, 'RefDec(4)', status ) ) then - call stopit( status, 'Error 22' ) - end if - -c if( ast_test( obj, 'Epoch(4)', status ) ) then -c call stopit( status, 'Error 22' ) -c end if - -c if( ast_test( obj, 'Epoch(1)', status ) ) then -c call stopit( status, 'Error 23' ) -c end if - -c if( ast_test( obj, 'Epoch(2)', status ) ) then -c call stopit( status, 'Error 24' ) -c end if - - - - - call ast_end( status ) - - if( status .ne. sai__ok ) write(*,*) 'teststc: example 1 '// - : 'tests failed' - - end - - - subroutine Example1b( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - - include 'teststc_com' - - integer status, obj, i, l - character value*200 - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - -* Test the Strict attribute. - call puteg( 'teststc_eg1', 1, status ) - - call err_mark - call xmlread( 1, obj, 'Strict=1', status ) - - if( status .ne. ast__badin ) then - if( status .ne. sai__ok ) call err_flush( status ) - call stopit( status, 'Error 1' ) - else - call err_annul( status ) - end if - call err_rlse - -* Test the ast_warnings function. - call xmlread( 1, obj, 'Strict=0', status ) - if( warns .EQ. AST__NULL ) then - call stopit( status, 'Error 2' ) - - else if( ast_mapsize( warns, status ) .ne. 5 ) then - call stopit( status, 'Error 3' ) - - else if( .not. ast_mapget0c( warns, 'Warning_1', value, l, - : status ) ) then - call stopit( status, 'Error 4' ) - - else if( value(:l) .ne. 'astRead(XmlChan): Warning whilst '// - : 'reading a Position2D element: contains more than '// - : 'one element. AST can only use the first' ) then - call stopit( status, 'Error 5' ) - end if - - - call ast_end( status ) - - if( status .ne. sai__ok ) write(*,*) 'teststc: example 1b '// - : 'tests failed' - - end - - - subroutine Example2( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer status, obj, i, j - double precision in(12,5), out(12,5) - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - -* Put an example of a CatalogEntryLocation into file 1. - call puteg( 'teststc_eg2', 1, status ) - -* Use a new XmlChan to read an object from file 1,and simplify it. - call xmlread( 1, obj, ' ', status ) - obj = ast_simplify( obj, status ) - -* Test simplify by negating and simplifying twice. - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - call checkdump( obj, 'checkdump 1', status ) - -* Check it is a StcCatalogEntryLocation - if( .not. ast_isastcCatalogEntryLocation( obj, status ) ) - : call stopit( status, 'Error 1' ) - -* Check it is an Interval. - if( .not. ast_isainterval( ast_getstcregion( obj, status ), - : status ) ) - : call stopit( status, 'Error 1a' ) - -* Check it has no uncertainty - if( ast_getunc( obj, .false., status ) .NE. AST__NULL ) - : call stopit( status, 'Error 1b' ) - -* Other tests - if( ast_geti( obj, 'naxes', status ) .ne. 5 ) - : call stopit( status, 'Error 1ab' ) - - if( ast_getd( obj, 'fillfactor', status ) .ne. 1.0D0 ) - : call stopit( status, 'Error 1b' ) - - if( ast_getc( obj, 'ident', status ) .ne. 'RA6-18hDec20-70deg' ) - : call stopit( status, 'Error 1c' ) - - if( ast_getc( obj, 'domain(3)', status ) .ne. 'TIME' ) - : call stopit( status, 'Error 2' ) - - if( ast_getc( obj, 'title(3)', status ) .ne. - : 'Julian Date [TT] offset from 1968-05-23 12:00:00' ) - : call stopit( status, 'Error 2a' ) - - if( ast_getc( obj, 'label(3)', status ) .ne. - : 'Julian Date offset from 1968-05-23 12:00:00' ) THEN - call stopit( status, 'Error 2b' ) - endif - - if( ast_getc( obj, 'domain(1)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 3' ) - - if( ast_getc( obj, 'system(1)', status ) .ne. 'FK4' ) - : call stopit( status, 'Error 3a' ) - - if( ast_getc( obj, 'label(1)', status ) .ne. 'Right ascension' ) - : call stopit( status, 'Error 3b' ) - - if( ast_getc( obj, 'label(2)', status ) .ne. 'Declination' ) - : call stopit( status, 'Error 3c' ) - - if( ast_getc( obj, 'title(2)', status ) .ne. 'PosEq' ) - : call stopit( status, 'Error 3d' ) - - if( ast_getd( obj, 'Equinox', status ) .ne. 1950D0 ) - : call stopit( status, 'Error 3d' ) - - if( ast_getc( obj, 'domain(2)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 4' ) - - if( ast_getc( obj, 'domain(4)', status ) .ne. 'SPECTRUM' ) - : call stopit( status, 'Error 5' ) - - if( ast_getc( obj, 'system(4)', status ) .ne. 'WAVE' ) - : call stopit( status, 'Error 5a' ) - - if( ast_getc( obj, 'stdofrest', status ) .ne. 'Topocentric' ) - : call stopit( status, 'Error 5b' ) - - if( ast_test( obj, 'title(4)', status ) ) - : call stopit( status, 'Error 5c' ) - - if( ast_geti( obj, 'naxes', status ) .ne. 5 ) - : call stopit( status, 'Error 6' ) - - if( ast_getc( obj, 'domain(5)', status ) .ne. 'REDSHIFT' ) - : call stopit( status, 'Error 6a' ) - - if( ast_getc( obj, 'system(5)', status ) .ne. 'VOPT' ) - : call stopit( status, 'Error 6b' ) - - if( ast_getc( obj, 'label(5)', status ) .ne. 'Optical velocity' ) - : call stopit( status, 'Error 6c' ) - - if( ast_getc( obj, 'unit(5)', status ) .ne. 'km/s' ) - : call stopit( status, 'Error 6d' ) - - if( ast_getc( obj, 'unit(4)', status ) .ne. 'Angstrom' ) - : call stopit( status, 'Error 6e' ) - - - in(1,1) = 4.71238 ! inside - in(1,2) = 1.2216 - in(1,3) = 1 - in(1,4) = 6499.9 - in(1,5) = 9999.9 - - in(2,1) = 4.71240 ! outside - in(2,2) = 1.2216 - in(2,3) = 1 - in(2,4) = 6499.9 - in(2,5) = 9999.9 - - in(3,1) = 4.71238 ! outside - in(3,2) = 1.2218 - in(3,3) = 1 - in(3,4) = 6499.9 - in(3,5) = 9999.9 - - in(4,1) = 4.71238 ! outside - in(4,2) = 1.2216 - in(4,3) = -0.6 - in(4,4) = 6499.9 - in(4,5) = 9999.9 - - in(5,1) = 4.71238 ! outside - in(5,2) = 1.2216 - in(5,3) = 1 - in(5,4) = 6500.1 - in(5,5) = 9999.9 - - in(6,1) = 4.71238 ! outside - in(6,2) = 1.2216 - in(6,3) = 1 - in(6,4) = 6499.9 - in(6,5) = 10000.1 - - in(7,1) = 1.5709 ! inside - in(7,2) = 0.3492 - in(7,3) = 999.6 - in(7,4) = 5000.1 - in(7,5) = 5000 - - in(8,1) = 1.5707 ! outside - in(8,2) = 0.3492 - in(8,3) = 999.6 - in(8,4) = 5000.1 - in(8,5) = 5000 - - in(9,1) = 1.5709 ! outside - in(9,2) = 0.3490 - in(9,3) = 999.6 - in(9,4) = 5000.1 - in(9,5) = 5000 - - in(10,1) = 1.5709 ! outside - in(10,2) = 0.3492 - in(10,3) = 1000.4 - in(10,4) = 5000.1 - in(10,5) = 5000 - - in(11,1) = 1.5709 ! outside - in(11,2) = 0.3492 - in(11,3) = 999.6 - in(11,4) = 4999.9 - in(11,5) = 5000 - - in(12,1) = 1.5709 ! inside - in(12,2) = 0.3492 - in(12,3) = 999.6 - in(12,4) = 5000.1 - in(12,5) = 1000 - - call ast_trann( obj, 12, 5, 12, in, .true., 5, 12, out, status ) - - do i = 1, 12 - if( i .eq. 1 .or. i .eq. 7 .or. i .eq. 12 ) then ! inside points - do j = 1, 5 - if( out(i,j) .ne. in(i,j) ) then - if( status .eq. sai__ok ) then - write(*,*) i,j,out(i,j),in(i,j) - call stopit( status, 'Error 7' ) - end if - end if - end do - else ! outside points - do j = 1, 5 - if( out(i,j) .ne. AST__BAD ) then - if( status .eq. sai__ok ) then - write(*,*) i,j,out(i,j),in(i,j) - call stopit( status, 'Error 8' ) - end if - end if - end do - end if - end do - -* Tests on reference values - if( ast_test( obj, 'RefRA(4)', status ) ) then - call stopit( status, 'Error 9' ) - end if - - if( ast_test( obj, 'RefDec(4)', status ) ) then - call stopit( status, 'Error 10' ) - end if - -c if( ast_test( obj, 'Epoch(4)', status ) ) then -c call stopit( status, 'Error 11' ) -c end if - -c if( ast_test( obj, 'Epoch(1)', status ) ) then -c call stopit( status, 'Error 12' ) -c end if - -c if( ast_test( obj, 'Epoch(2)', status ) ) then -c call stopit( status, 'Error 13' ) -c end if - - if( ast_test( obj, 'RestFreq(5)', status ) ) then - call stopit( status, 'Error 14' ) - end if - - - - - - - call ast_end( status ) - - if( status .ne. sai__ok ) write(*,*) 'teststc: example 2 '// - : 'tests failed' - - end - - - - - - - - subroutine Example3( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer status, obj, i, j - double precision in(12,5), out(12,5) - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - -* Put an example of a CatalogEntryLocation into file 1. - call puteg( 'teststc_eg3', 1, status ) - -* Use a new XmlChan to read an object from file 1,and simplify it. - call xmlread( 1, obj, ' ', status ) - obj = ast_simplify( obj, status ) - -* Test simplify by negating and simplifying twice. - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - call checkdump( obj, 'checkdump 1', status ) - -* Check it is a StcCatalogEntryLocation - if( .not. ast_isastcCatalogEntryLocation( obj, status ) ) - : call stopit( status, 'Error 1' ) - -* Check it is an Interval. - if( .not. ast_isainterval( ast_getstcregion( obj, status ), - : status ) ) then - write(*,*) ast_GetC( ast_getstcregion( obj, status ), 'Class', - : status ) - call stopit( status, 'Error 1a' ) - end if - -* Check it has no uncertainty - if( ast_getunc( obj, .false., status ) .NE. AST__NULL ) - : call stopit( status, 'Error 1b' ) - -* Check it has 5 axes. - if( ast_geti( obj, 'naxes', status ) .ne. 5 ) - : call stopit( status, 'Error 1ab' ) - -* Check the rest frequency for axis 5 (redshift) is 5000 Angstrom - if( abs( ast_getd( obj, 'restfreq(5)', status ) - 599584.916D0 ) - : .gt. 0.001D0 ) call stopit( status, 'Error A1' ) - -* Check the epoch for allaxes is JD 2440000 - if( abs( ast_getd( obj, 'epoch(1)', status ) - 1968.39212D0 ) .gt. - : 0.00001D0 ) call stopit( status, 'Error B1' ) - if( abs( ast_getd( obj, 'epoch(2)', status ) - 1968.39212D0 ) .gt. - : 0.00001D0 ) call stopit( status, 'Error B2' ) - if( abs( ast_getd( obj, 'epoch(3)', status ) - 1968.39212D0 ) .gt. - : 0.00001D0 ) call stopit( status, 'Error B3' ) - if( abs( ast_getd( obj, 'epoch(4)', status ) - 1968.39212D0 ) .gt. - : 0.00001D0 ) call stopit( status, 'Error B4' ) - if( abs( ast_getd( obj, 'epoch(5)', status ) - 1968.39212D0 ) .gt. - : 0.00001D0 ) call stopit( status, 'Error B5' ) - -* Other tests - if( ast_getd( obj, 'fillfactor', status ) .ne. 1.0D0 ) - : call stopit( status, 'Error 1b' ) - - if( ast_getc( obj, 'ident', status ) .ne. 'RA6-18hDec20-70deg' ) - : call stopit( status, 'Error 1c' ) - - if( ast_getc( obj, 'domain(3)', status ) .ne. 'TIME' ) - : call stopit( status, 'Error 2' ) - - if( ast_getc( obj, 'label(3)', status ) .ne. - : 'Julian Date offset from 1968-05-23 12:00:00' ) THEN - call stopit( status, 'Error 2b' ) - end if - - if( ast_getc( obj, 'domain(1)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 3' ) - - if( ast_getc( obj, 'system(1)', status ) .ne. 'FK4' ) - : call stopit( status, 'Error 3a' ) - - if( ast_getc( obj, 'label(1)', status ) .ne. 'Right ascension' ) - : call stopit( status, 'Error 3b' ) - - if( ast_getc( obj, 'label(2)', status ) .ne. 'Declination' ) - : call stopit( status, 'Error 3c' ) - - if( ast_getc( obj, 'title(2)', status ) .ne. 'PosEq' ) - : call stopit( status, 'Error 3d' ) - - if( ast_getd( obj, 'Equinox', status ) .ne. 1950D0 ) - : call stopit( status, 'Error 3d' ) - - if( ast_getc( obj, 'domain(2)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 4' ) - - if( ast_getc( obj, 'domain(4)', status ) .ne. 'SPECTRUM' ) - : call stopit( status, 'Error 5' ) - - if( ast_getc( obj, 'system(4)', status ) .ne. 'WAVE' ) - : call stopit( status, 'Error 5a' ) - - if( ast_getc( obj, 'stdofrest', status ) .ne. 'Topocentric' ) - : call stopit( status, 'Error 5b' ) - - if( ast_test( obj, 'title(4)', status ) ) - : call stopit( status, 'Error 5c' ) - - if( ast_geti( obj, 'naxes', status ) .ne. 5 ) - : call stopit( status, 'Error 6' ) - - if( ast_getc( obj, 'domain(5)', status ) .ne. 'REDSHIFT' ) - : call stopit( status, 'Error 6a' ) - - if( ast_getc( obj, 'system(5)', status ) .ne. 'VOPT' ) - : call stopit( status, 'Error 6b' ) - - if( ast_getc( obj, 'label(5)', status ) .ne. 'Optical velocity' ) - : call stopit( status, 'Error 6c' ) - - if( ast_getc( obj, 'unit(5)', status ) .ne. 'km/s' ) - : call stopit( status, 'Error 6d' ) - - if( ast_getc( obj, 'unit(4)', status ) .ne. 'Angstrom' ) - : call stopit( status, 'Error 6e' ) - - - in(1,1) = 4.71238 ! inside - in(1,2) = 1.2216 - in(1,3) = 0.0D0 - in(1,4) = 5000 - in(1,5) = 9999.9 - - in(2,1) = 4.71240 ! outside - in(2,2) = 1.2216 - in(2,3) = 0.0D0 - in(2,4) = 5000 - in(2,5) = 9999.9 - - in(3,1) = 4.71238 ! outside - in(3,2) = 1.2218 - in(3,3) = 0.0D0 - in(3,4) = 5000 - in(3,5) = 9999.9 - - in(4,1) = 4.71238 ! outside - in(4,2) = 1.2216 - in(4,3) = 0.5D0 - in(4,4) = 5000 - in(4,5) = 9999.9 - - in(5,1) = 4.71238 ! outside - in(5,2) = 1.2216 - in(5,3) = 0.0D0 - in(5,4) = 6500.1 - in(5,5) = 9999.9 - - in(6,1) = 4.71238 ! outside - in(6,2) = 1.2216 - in(6,3) = 0.0D0 - in(6,4) = 5000 - in(6,5) = 10000.1 - - in(7,1) = 1.5709 ! inside - in(7,2) = 0.3492 - in(7,3) = 0.0D0 - in(7,4) = 5000 - in(7,5) = 5000 - - in(8,1) = 1.5707 ! outside - in(8,2) = 0.3492 - in(8,3) = 0.0D0 - in(8,4) = 5000 - in(8,5) = 5000 - - in(9,1) = 1.5709 ! outside - in(9,2) = 0.3490 - in(9,3) = 0.0D0 - in(9,4) = 5000 - in(9,5) = 5000 - - in(10,1) = 1.5709 ! outside - in(10,2) = 0.3492 - in(10,3) = 39999.4D0 - in(10,4) = 5000 - in(10,5) = 5000 - - in(11,1) = 1.5709 ! outside - in(11,2) = 0.3492 - in(11,3) = 0.0D0 - in(11,4) = 4999.9 - in(11,5) = 5000 - - in(12,1) = 1.5709 ! inside - in(12,2) = 0.3492 - in(12,3) = 0.0D0 - in(12,4) = 5000 - in(12,5) = 1000 - - call ast_trann( obj, 12, 5, 12, in, .true., 5, 12, out, status ) - - do i = 1, 12 - if( i .eq. 1 .or. i .eq. 7 .or. i .eq. 12 ) then ! inside points - do j = 1, 5 - if( out(i,j) .ne. in(i,j) ) then - if( status .eq. sai__ok ) then - write(*,*) i,j,out(i,j),in(i,j) - call stopit( status, 'Error 7' ) - end if - end if - end do - else ! outside points - do j = 1, 5 - if( out(i,j) .ne. AST__BAD ) then - if( status .eq. sai__ok ) then - write(*,*) i,j,out(i,j),in(i,j) - call stopit( status, 'Error 8' ) - end if - end if - end do - end if - end do - -* Tests on reference values - if( ast_test( obj, 'RefRA(4)', status ) ) then - call stopit( status, 'Error 9' ) - end if - - if( ast_test( obj, 'RefDec(4)', status ) ) then - call stopit( status, 'Error 10' ) - end if - - if( .not. ast_test( obj, 'Epoch(4)', status ) ) then - call stopit( status, 'Error 11' ) - end if - - if( .not. ast_test( obj, 'Epoch(1)', status ) ) then - call stopit( status, 'Error 12' ) - end if - - if( .not. ast_test( obj, 'Epoch(2)', status ) ) then - call stopit( status, 'Error 13' ) - end if - - if( .not. ast_test( obj, 'RestFreq(5)', status ) ) then - call stopit( status, 'Error 14' ) - end if - - - - - - - call ast_end( status ) - - if( status .ne. sai__ok ) write(*,*) 'teststc: example 3 '// - : 'tests failed' - - end - - - - - - - subroutine Example4( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - - integer status, obj2, obj, i, j, unc, frm - double precision in(12,4), out(12,4), lbnd(4), ubnd(4) - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - -* Put an example of an STCSearchLocation into file 1. - call puteg( 'teststc_eg4', 1, status ) - -* Use a new XmlChan to read an object from file 1,and simplify it. - call xmlread( 1, obj, ' ', status ) - obj = ast_simplify( obj, status ) - -* Test simplify by negating and simplifying twice. - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - call checkdump( obj, 'checkdump 1', status ) - - -* Check it is a STCSearchLocation - if( .not. ast_isastcsearchlocation( obj, status ) ) - : call stopit( status, 'Error 1' ) - -* Check it is a Prism. - if( .not. ast_isaprism( ast_getstcregion( obj, status ), - : status ) ) - : call stopit( status, 'Error 1a' ) - -* Check it has no uncertainty - if( ast_getunc( obj, .false., status ) .NE. AST__NULL ) - : call stopit( status, 'Error 1b' ) - -* Other tests - if( ast_geti( obj, 'naxes', status ) .ne. 4 ) - : call stopit( status, 'Error 1ab' ) - - if( ast_getd( obj, 'fillfactor', status ) .ne. 1.0D0 ) - : call stopit( status, 'Error 1b' ) - - if( ast_getc( obj, 'ident', status ) .ne. 'M81' ) - : call stopit( status, 'Error 1c' ) - - if( ast_getc( obj, 'domain(3)', status ) .ne. 'TIME' ) - : call stopit( status, 'Error 2' ) - - if( ast_getc( obj, 'label(3)', status ) .ne. - : 'Modified Julian Date offset from 1900-01-01' ) THEN - call stopit( status, 'Error 2b' ) - end if - - if( ast_getc( obj, 'domain(1)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 3' ) - - if( ast_getc( obj, 'system(1)', status ) .ne. 'ICRS' ) - : call stopit( status, 'Error 3a' ) - - if( ast_getc( obj, 'label(1)', status ) .ne. 'Right ascension' ) - : call stopit( status, 'Error 3b' ) - - if( ast_getc( obj, 'label(2)', status ) .ne. 'Declination' ) - : call stopit( status, 'Error 3c' ) - - if( ast_getc( obj, 'title(2)', status ) .ne. 'Equatorial' ) - : call stopit( status, 'Error 3d' ) - - if( ast_test( obj, 'Equinox', status ) ) - : call stopit( status, 'Error 3d2' ) - - if( ast_getc( obj, 'domain(2)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 4' ) - - if( ast_getc( obj, 'domain(4)', status ) .ne. 'SPECTRUM' ) - : call stopit( status, 'Error 5' ) - - if( ast_getc( obj, 'system(4)', status ) .ne. 'WAVE' ) - : call stopit( status, 'Error 5a' ) - - if( ast_getc( obj, 'stdofrest', status ) .ne. 'Barycentric' ) - : call stopit( status, 'Error 5b' ) - - if( ast_getc( obj, 'title(4)', status ) .ne. 'Wavelength' ) - : call stopit( status, 'Error 5c' ) - - if( ast_geti( obj, 'naxes', status ) .ne. 4 ) - : call stopit( status, 'Error 6' ) - - if( ast_getc( obj, 'unit(4)', status ) .ne. 'Angstrom' ) - : call stopit( status, 'Error 6e' ) - - frm = ast_getregionframe( obj, status ) - if( ast_getc( frm, 'Ident', status ) .ne. 'ICRS-TT-BARY' ) - : call stopit( status, 'Error 7' ) - - - -* Tests on reference values - if( ast_test( obj, 'RefRA(4)', status ) ) then - call stopit( status, 'Error 9' ) - end if - - if( ast_test( obj, 'RefDec(4)', status ) ) then - call stopit( status, 'Error 10' ) - end if - -c if( ast_test( obj, 'Epoch(4)', status ) ) then -c call stopit( status, 'Error 11' ) -c end if - -c if( ast_test( obj, 'Epoch(1)', status ) ) then -c call stopit( status, 'Error 12' ) -c end if - -c if( ast_test( obj, 'Epoch(2)', status ) ) then -c call stopit( status, 'Error 13' ) -c end if - - if( ast_test( obj, 'RestFreq(4)', status ) ) then - call stopit( status, 'Error 14' ) - end if - - if( abs( ast_getd( obj, 'Epoch(3)', status ) - 1900.00051056532 ) - : .gt. 0.0001 ) then - call stopit( status, 'Error 12b' ) - end if - - if( abs( ast_getd( obj, 'TimeOrigin', status ) - 15020.0D0 ) - : .gt. 0.0001 ) then - call stopit( status, 'Error 12c' ) - end if - - - - - in(1,1) = 2.51126532207628 ! inside - in(1,2) = 1.22218015796595 - in(1,3) = 0.01 - in(1,4) = 4001 - - in(2,1) = 2.5094191311777 ! outside - in(2,2) = 1.22248014367694 - in(2,3) = 0.01 - in(2,4) = 4001 - - in(3,1) = 2.51126532207628 ! outside - in(3,2) = 1.22218015796595 - in(3,3) = 0.01 - in(3,4) = 3999 - - in(4,1) = 2.51126532207628 ! outside - in(4,2) = 1.22218015796595 - in(4,3) = -0.2 - in(4,4) = 4001 - - in(5,1) = 2.5094191311777 ! outside - in(5,2) = 1.22248014367694 - in(5,3) = -0.2 - in(5,4) = 4001 - - in(6,1) = 2.51126532207628 ! outside - in(6,2) = 1.22218015796595 - in(6,3) = -0.2 - in(6,4) = 3999 - - in(7,1) = 2.51682141503858 ! inside - in(7,2) = 1.18868060989363 - in(7,3) = 0.01 - in(7,4) = 6999 - - in(8,1) = 2.51524001365674 ! outside - in(8,2) = 1.18830732379242 - in(8,3) = 0.01 - in(8,4) = 6999 - - in(9,1) = 2.51682141503858 ! outside - in(9,2) = 1.18868060989363 - in(9,3) = 0.01 - in(9,4) = 7001 - - in(10,1) = 2.51682141503858 ! outside - in(10,2) = 1.18868060989363 - in(10,3) = -0.2 - in(10,4) = 6999 - - in(11,1) = 2.51524001365674 ! outside - in(11,2) = 1.18830732379242 - in(11,3) = -0.2 - in(11,4) = 6999 - - in(12,1) = 2.51682141503858 ! outside - in(12,2) = 1.18868060989363 - in(12,3) = -0.2 - in(12,4) = 7001 - - call ast_trann( obj, 12, 4, 12, in, .true., 4, 12, out, status ) - - do i = 1, 12 - if( i .eq. 1 .or. i .eq. 7 ) then ! inside points - do j = 1, 4 - if( out(i,j) .ne. in(i,j) ) then - if( status .eq. sai__ok ) then - write(*,*) i,j,out(i,j),in(i,j) - call stopit( status, 'Error 13c' ) - end if - end if - end do - else ! outside points - do j = 1, 4 - if( out(i,j) .ne. AST__BAD ) then - if( status .eq. sai__ok ) then - write(*,*) i,j,out(i,j),in(i,j) - call stopit( status, 'Error 14c' ) - end if - end if - end do - end if - end do - - - call ast_end( status ) - - if( status .ne. sai__ok ) write(*,*) 'teststc: example 4 '// - : 'tests failed' - - end - - - - - subroutine Example5( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - - integer status, obj2, obj, i, j, unc, frm - double precision in(12,4), out(12,4), lbnd(4), ubnd(4) - - if( status .ne. sai__ok ) return - - call ast_begin( status ) - -* Put an example of an STCSearchLocation into file 1. - call puteg( 'teststc_eg5', 1, status ) - -* Use a new XmlChan to read an object from file 1,and simplify it. - call xmlread( 1, obj, ' ', status ) - call checkdump( obj, 'checkdump 2', status ) - obj = ast_simplify( obj, status ) - -* Test simplify by negating and simplifying twice. - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - call ast_negate( obj, status ) - obj = ast_simplify( obj, status ) - call checkdump( obj, 'checkdump 1', status ) - -* Check it is a STCObsDataLocation - if( .not. ast_isastcobsdatalocation( obj, status ) ) - : call stopit( status, 'Error 1' ) - -* Check it contains a Prism. - if( .not. ast_isaprism( ast_getstcregion( obj, status ), - : status ) ) - : call stopit( status, 'Error 1a' ) - -* Other tests - if( ast_getd( obj, 'fillfactor', status ) .ne. 1.0D0 ) - : call stopit( status, 'Error 1b' ) - - if( ast_getc( obj, 'ident', status ) .ne. 'M81' ) - : call stopit( status, 'Error 1c' ) - - if( ast_getc( obj, 'domain(3)', status ) .ne. 'TIME' ) - : call stopit( status, 'Error 2' ) - - if( ast_getc( obj, 'label(3)', status ) .ne. - : 'Modified Julian Date offset from 2004-07-15 08:23:56' ) then - call stopit( status, 'Error 2b' ) - end if - - if( ast_getc( obj, 'domain(1)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 3' ) - - if( ast_getc( obj, 'system(1)', status ) .ne. 'ICRS' ) - : call stopit( status, 'Error 3a' ) - - if( ast_getc( obj, 'label(1)', status ) .ne. 'Right ascension' ) - : call stopit( status, 'Error 3b' ) - - if( ast_getc( obj, 'label(2)', status ) .ne. 'Declination' ) - : call stopit( status, 'Error 3c' ) - - if( ast_getc( obj, 'title(2)', status ) .ne. 'Equatorial' ) - : call stopit( status, 'Error 3d' ) - - if( ast_getc( obj, 'domain(2)', status ) .ne. 'SKY' ) - : call stopit( status, 'Error 4' ) - - if( ast_getc( obj, 'domain(4)', status ) .ne. 'SPECTRUM' ) - : call stopit( status, 'Error 5' ) - - if( ast_getc( obj, 'system(4)', status ) .ne. 'WAVE' ) - : call stopit( status, 'Error 5a' ) - - if( ast_getc( obj, 'stdofrest', status ) .ne. 'Topocentric' ) - : call stopit( status, 'Error 5b' ) - - if( ast_getc( obj, 'title(4)', status ) .ne. - : 'Wavelength' ) call stopit( status, 'Error 5c' ) - - if( ast_getc( obj, 'unit(4)', status ) .ne. 'Angstrom' ) - : call stopit( status, 'Error 5d' ) - - if( ast_geti( obj, 'naxes', status ) .ne. 4 ) - : call stopit( status, 'Error 6' ) - - call ast_getregionbounds( obj, lbnd, ubnd, status ) - - - - lbnd(1) = 0.5*(lbnd(1) + ubnd(1)) - lbnd(2) = 0.5*(lbnd(2) + ubnd(2)) - lbnd(3) = 0.5*(lbnd(3) + ubnd(3)) - lbnd(4) = 0.5*(lbnd(4) + ubnd(4)) - - if( abs( lbnd(1) - 2.59858948190075 ) .gt. 1E-06 ) - : call stopit( status, 'Error 10' ) - if( abs( lbnd(2) - 1.20541670934471 ) .gt. 1E-06 ) - : call stopit( status, 'Error 11' ) - if( abs( lbnd(3) ) .gt. 1E-5 ) - : call stopit( status, 'Error 12' ) - if( abs( lbnd(4) - 4600 ) .gt. 0.0001 ) - : call stopit( status, 'Error 13' ) - if( abs( ubnd(1) - 2.61080678666471 ) .gt. 1E-06 ) - : call stopit( status, 'Error 14' ) - if( abs( ubnd(2) - 1.2097800324747 ) .gt. 1E-06 ) - : call stopit( status, 'Error 15' ) - if( abs( ubnd(3) - 380.0D0 ) .gt. 1E-5 ) - : call stopit( status, 'Error 16' ) - if( abs( ubnd(4) - 4800 ) .gt. 0.0001 ) - : call stopit( status, 'Error 17' ) - if( ast_getc( obj, 'ObsLon', status ) .ne. 'W111:35:39.84' ) - : call stopit( status, 'Error 18' ) - if( ast_getc( obj, 'ObsLat', status ) .ne. 'N31:57:30.96' ) - : call stopit( status, 'Error 19' ) - - unc = ast_getunc( obj, .true., status ) - if( unc .eq. AST__NULL ) call stopit( status, 'Error 20' ) - - call ast_getregionbounds( unc, lbnd, ubnd, status ) - - lbnd(1) = 0.5*(lbnd(1) + ubnd(1)) - lbnd(2) = 0.5*(lbnd(2) + ubnd(2)) - lbnd(3) = 0.5*(lbnd(3) + ubnd(3)) - lbnd(4) = 0.5*(lbnd(4) + ubnd(4)) - - if( abs( lbnd(1) - 2.59858948190075D0) .gt. 1E-05 ) - : call stopit( status, 'Error 21' ) - if( abs( lbnd(2) - 1.20541670934471D0) .gt. 1E-05 ) - : call stopit( status, 'Error 22' ) - if( abs( lbnd(3) ) .gt. 1.0D-05 ) - : call stopit( status, 'Error 23' ) - if( abs( lbnd(4) - 4600.0D0) .gt. 0.0001 ) - : call stopit( status, 'Error 24' ) - if( abs( ubnd(1) - 2.59859209989462D0) .gt. 1E-05 ) - : call stopit( status, 'Error 25' ) - - if( abs( ubnd(2) - 1.20541932733859D0) .gt. 1E-05 ) - : call stopit( status, 'Error 26' ) - if( abs( ubnd(3) - 0.3803143212621760D-03 ) .gt. 1E-05 ) - : call stopit( status, 'Error 27' ) - if( abs( ubnd(4) - 4600.0002D0) .gt. 0.000001 ) - : call stopit( status, 'Error 28' ) - - if( status .ne. sai__ok ) write(*,*) 'teststc: example 5 '// - : 'tests failed' - - end - - - - - - - - - - - - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - - - - -* -* Read an object out of the specified internal file using an XmlChan. -* - subroutine xmlread( ifil, obj, opts, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - include 'teststc_com' - - external xmlSource - integer obj, ifil, status, ch - character opts*(*) - - if( status .ne. sai__ok ) return - - ifile = ifil - iline = 1 - - ch = ast_xmlchan( xmlSource, ast_null, opts, status ) - obj = ast_read( ch, status ) - if( obj .eq. ast__null ) then - call stopit( status, 'checkXmlChan: Failed to read STC '// - : 'object from XmlChan.' ) - end if - - warns = ast_warnings( ch, status ) - call ast_annul( ch, status ) - - end - - - - -* -* Reads line "iline" from internal file "ifile" and returns it to AST using -* the AST_PUTLINE routine. Then increments "iline" ready for next time. -* - subroutine xmlSource( status ) - implicit none - - include 'teststc_com' - - integer status, l, chr_len - - if( iline .le. filelen( ifile ) ) then - l = chr_len( files(ifile,iline) ) - call ast_putline( files(ifile,iline), l, status ) - iline = iline + 1 - else - call ast_putline( ' ', -1, status ) - end if - - end - -* -* Append a line obtained using ast_getline function to the end of the -* internal file indicated by "ifile", and increment the file length. -* - subroutine xmlSink( status ) - implicit none - - include 'teststc_com' - - integer status, l - character line*(linelen) - - call ast_getline( line, l, status ) - if( l .gt. 0 ) then - - if( filelen( ifile ) .ge. mxline ) then - call stopit( status, 'checkXmlChan: Too many lines sent '// - : 'to sink function' ) - - else if( l .gt. linelen ) then - call stopit( status, 'checkXmlChan: Text truncated in '// - : 'sink function' ) - - else - filelen( ifile ) = filelen( ifile ) + 1 - files( ifile, filelen( ifile ) ) = line(:l) - end if - - end if - - end - - - subroutine puteg( flnam, ifl, status ) - implicit none - - include 'SAE_PAR' - include 'AST_PAR' - include 'teststc_com' - - integer status, ifl - character flnam*(*) - - if( status .ne. sai__ok ) return - - open( file=flnam, status='old', unit=10 ) - - iline = 1 - 10 continue - if( iline .gt. mxline ) call stopit( status, - : 'mxline exceeded in puteg' ) - read( 10, '(A)', end=20 ) files( ifl, iline ) - - if( files( ifl, iline )( linelen : linelen ) .ne. ' ' ) then - call stopit( status, 'linelen exceeded in puteg' ) - end if - - iline = iline + 1 - go to 10 - - 20 continue - close( 10 ) - filelen( ifl ) = iline - 1 - - end - - -* -* Tests the dump function, the loader, and the astOverlap method. -* - subroutine checkdump( obj, text, status ) - - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*) - integer obj, status, next, end, ch, result, ll, overlap - external mysource, mysink - character buf*190000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - -* Create a Channel which reads and writes to an internal string buffer. - ch = ast_channel( mysource, mysink, ' ', status ) - -* Write the supplied Region out to this Channel. - ll = 160 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - -* Read an Object back from this Channel. - next = 1 - result = ast_read( ch, status ) - if( result .eq. ast__null ) then - write(*,*) text - call stopit( status, 'Cannot read object from channel' ) - end if - -* Check that it is a Region and its boundary is identical to the supplied -* Region. - overlap = ast_overlap( obj, result, status ) - if( overlap .ne. 5 ) then - write(*,*) 'obj result Overlap: ', overlap - write(*,*) 'obj self-Overlap: ', ast_overlap( obj, obj, - : status ) - write(*,*) 'result self-Overlap: ', ast_overlap( result, - : result, status ) - call ast_Show( obj, status ) - call ast_Show( result, status ) - write(*,*) text - call stopit( status, 'Object has changed' ) - end if - -* Return the new Region pointer in place of the old. - obj = result - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll - character buf*190000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - call ast_putline( buf( next : ), ll, status ) - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll - character buf*190000 - character line*1000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - - if( next + ll - 1 .ge. 190000 ) then - write(*,*) buf - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf( next : next + l) - write(*,*) 'Line length ',l,' greater than ',ll - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - endif - - next = next + ll - - end - - diff --git a/ast/ast_tester/teststc_com b/ast/ast_tester/teststc_com deleted file mode 100644 index f9a7fb1..0000000 --- a/ast/ast_tester/teststc_com +++ /dev/null @@ -1,13 +0,0 @@ -* -* Common block declaration used by teststc.f for storing internal -* files and associated info. -* - integer mxline - parameter ( mxline = 500 ) - - integer linelen - parameter ( linelen = 3000 ) - - character files( 3, mxline )*(linelen) - integer ifile,iline,filelen( 3 ),warns - common /files/ files, ifile, iline, filelen, warns diff --git a/ast/ast_tester/teststc_eg1 b/ast/ast_tester/teststc_eg1 deleted file mode 100644 index b1044c6..0000000 --- a/ast/ast_tester/teststc_eg1 +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - Time - TT - - - - Space - - - - - - Energy - - - - - - Time - 0.0001 - 0.000016 - 3.0 - 1000 - 170000 - - - Position - - 1.0 1.0 - - - 0.5 0.5 - - - 1000 1000 - - - 4000 4000 - - - - Energy - 0.1 - 0.02 - 2.0 - 2 - 10 - - - - - - TT - 1999-07-23T16:00:00 - - - - - - - 0.12 - 10.0 - - - diff --git a/ast/ast_tester/teststc_eg10 b/ast/ast_tester/teststc_eg10 deleted file mode 100644 index 977fa57..0000000 --- a/ast/ast_tester/teststc_eg10 +++ /dev/null @@ -1,18 +0,0 @@ - - - - Space - - - - - - - - - 143.0 42.0 - 1.0 1.0 - - - - diff --git a/ast/ast_tester/teststc_eg2 b/ast/ast_tester/teststc_eg2 deleted file mode 100644 index 6665676..0000000 --- a/ast/ast_tester/teststc_eg2 +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - ET - - - - PosEq - - B1950.0 - - - - - - - - - DopplerVelocity - OPTICAL - - - - - - - Time - ET - - - - SGC - - - - - - Optical - - - - DopplerVelocity - OPTICAL - - - - - - RA,Dec - Column3 - Column4 - Column5 - - - Vrad(barycenter) - Column6 - Column7 - - - - - SGLong,SGLat - Column8 - Column9 - Column10 - - - Vrad(Galcenter) - Column11 - Column12 - - - - - - ET - 2440000 - - - ET - 2441000 - - - - - - 270 20 - - - 90 20 - - - - 90 70 - - - 270 70 - - - - - - 5000 - 6500 - - - 10000 - - - diff --git a/ast/ast_tester/teststc_eg3 b/ast/ast_tester/teststc_eg3 deleted file mode 100644 index 028d484..0000000 --- a/ast/ast_tester/teststc_eg3 +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - ET - - - - PosEq - - B1950.0 - - - - - - - - - DopplerVelocity - OPTICAL - - - - - - Time - ET - - - - SGC - - - - - - Optical - - - - DopplerVelocity - OPTICAL - - - - - - RA,Dec - Column3 - Column4 - Column5 - - - Vrad(barycenter) - Column6 - Column7 - - - - - SGLong,SGLat - Column8 - Column9 - Column10 - - - Vrad(Galcenter) - Column11 - Column12 - - - - - - ET - 2440000 - - - ET - 2440000 - - - - - - 270 20 - - - 90 20 - - - - 90 70 - - - 270 70 - - - - - - 5000 - 5000 - - - 10000 - - - diff --git a/ast/ast_tester/teststc_eg4 b/ast/ast_tester/teststc_eg4 deleted file mode 100644 index 5b9d8ab..0000000 --- a/ast/ast_tester/teststc_eg4 +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Time - TT - - - - Equatorial - - - - - - Wavelength - - - - - - RA,Dec - 0.0001 0.0001 - 0.0003 0.0003 - 0.5 0.5 - 0.67 0.67 - 0.00005 0.00005 - 0.00015 0.00015 - - - Lambda - 300 - 600 - - - - - - TT - 1900-01-01T00:00:00 - - - - - 148.9 69.1 - 2 - - - - 4000 - 7000 - - - - diff --git a/ast/ast_tester/teststc_eg5 b/ast/ast_tester/teststc_eg5 deleted file mode 100644 index 97aad97..0000000 --- a/ast/ast_tester/teststc_eg5 +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - Time - TT - - - - GeoLongLatElev - - - - - - - - LongLatElev - 248.4056 31.9586 2158 - - - - - - - Time - TT - - - - Equatorial - - - - - - Wavelength - - - - - - Time - - TT - 2004-07-15T08:23:56 - - 1000 - - - RA,Dec - 148.88821 69.06529 - 0.0003 0.0003 - 0.00025 0.00025 - 0.0001 0.0001 - - - Lambda - 4600 - 400 - 400 - - - - - - TT - 2004-07-15T08:17:36 - - - TT - 2004-07-15T08:30:16 - - - - - 148.18821 68.81529 - 149.58821 69.31529 - - - - 4400 - 4800 - - - - - - - X - - - Y - - - - - 1 - 1024 - - - 1 - 1024 - - - - - diff --git a/ast/ast_tester/teststc_eg6 b/ast/ast_tester/teststc_eg6 deleted file mode 100644 index 7a291f6..0000000 --- a/ast/ast_tester/teststc_eg6 +++ /dev/null @@ -1,49 +0,0 @@ - - - - Time - TAI - - - - Space - - - - - - Energy - - - - - - - Position - - 1.0 1.0 - - - - Energy - 0.1 - - - - - - 1999-07-23T16:00:00 - - - - - - - 0.12 - 10.0 - - - diff --git a/ast/ast_tester/teststc_eg7 b/ast/ast_tester/teststc_eg7 deleted file mode 100644 index 0106c85..0000000 --- a/ast/ast_tester/teststc_eg7 +++ /dev/null @@ -1,52 +0,0 @@ - - - - Time - - TAI - - - Space - - - - - - Energy - - - - - - - Position - - 1.0 1.0 - - - - Energy - 0.1 - - - - - - 1998-07-23T16:00:00 - - - - -
0.0 90.0
- 2.0 -
-
- - 8.0 - 11.0 - -
-
diff --git a/ast/ast_tester/teststc_eg8 b/ast/ast_tester/teststc_eg8 deleted file mode 100644 index 17c6574..0000000 --- a/ast/ast_tester/teststc_eg8 +++ /dev/null @@ -1,52 +0,0 @@ - - - - Time - UTC - - - - Space - - - - - - Energy - - - - - - - Position - - 1.0 1.0 - - - - Energy - 0.1 - - - - - - 1999-09-23T16:00:00 - - - - -
0.0 90.0
- 2.0 -
-
- - 8.0 - 9.0 - -
-
diff --git a/ast/ast_tester/teststc_eg9 b/ast/ast_tester/teststc_eg9 deleted file mode 100644 index 195adb7..0000000 --- a/ast/ast_tester/teststc_eg9 +++ /dev/null @@ -1,49 +0,0 @@ - - - - Time - TCB - - - - Space - - - - - - Energy - - - - - - - Position - - 1.0 1.0 - - - - Energy - 0.1 - - - - - - 1999-06-23T16:00:00 - - - - - - - 0.12 - 10.0 - - - diff --git a/ast/ast_tester/teststcschan.f b/ast/ast_tester/teststcschan.f deleted file mode 100755 index 928b301..0000000 --- a/ast/ast_tester/teststcschan.f +++ /dev/null @@ -1,654 +0,0 @@ - program teststcschan - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer status - - status = sai__ok - - call ast_begin( status ) - -c call ast_watchmemory( 209814 ); - - call test2( status ) - call test1( status ) - - - - - call ast_end( status ) -c call ast_activememory( ' ' ) -c call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - call msg_out( ' ', ' All StcsChan tests passed', status ) - else - call err_rep( ' ', 'StcsChan tests failed', status ) - end if - - end - - - - - - subroutine test1( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - include 'PRM_PAR' - - integer iwrite - character buff(30)*300 - common /bbb/ iwrite, buff - - integer iread, idoc - common /aaa/ iread, idoc - - integer status, ch, obj, km, i, sb, iobj, nobj - external source, sink - - double precision lbnd(4), ubnd(4) - if( status .ne. sai__ok ) return - - call ast_begin( status ) - - ch = ast_stcschan( source, sink, 'ReportLevel=3', status ) - - - idoc = 4 - iread = 0 - obj = ast_read( ch, status ) - - idoc = 1 - iread = 0 - - call err_mark - obj = ast_read( ch, status ) - if( status .eq. AST__BADIN ) then - call err_annul( status ) - call err_rlse - else - call err_rlse - call error( 'Failed to report error about "fred"', status ) - end if - - - idoc = 2 - iread = 0 - obj = ast_read( ch, status ) - - km = ast_warnings( ch, status ) - if( km .eq. AST__NULL ) call error( 'No Warnings keymap', status ) - call asserti( 'Warnings mapsize', ast_mapsize( km, status ), 4, - : status ) - - call asserta( obj, 'Class', 'Prism', status ) - call asserta( obj, 'Naxes', '4', status ) - call asserta( obj, 'Label(1)', 'Modified Julian Date offset '// - : 'from 1900-01-01', status ) - call asserta( obj, 'Label(2)', 'Right ascension', status ) - call asserta( obj, 'Label(3)', 'Declination', status ) - call asserta( obj, 'Label(4)', 'Wavelength', status ) - call asserta( obj, 'Unit(1)', 'd', status ) - call asserta( obj, 'Unit(4)', 'Angstrom', status ) - - call ast_GetRegionBounds( obj, lbnd, ubnd, status ) - call ast_setc( obj, 'Format(1)', 'iso.2', status ) - call assertd( 'Time upper bounds', ubnd(1), VAL__MAXD, status ) - call assertc( 'Time lower bound', - : ast_format( obj, 1, lbnd(1), status ), - : '1900-01-01 00:00:00.00', status ) - call assertd( 'RA lower bound', lbnd(2), 2.50080939227851D0, - : status ) - call assertd( 'RA upper bound', ubnd(2), 2.6967811201606D0, - : status ) - call assertd( 'Dec lower bound', lbnd(3), 1.171115928088195D0, - : status ) - call assertd( 'Dec upper bound', ubnd(3), 1.24091013301998D0, - : status ) - call assertd( 'Wavelength lower bound', lbnd(4), 4000.0D0, - : status ) - call assertd( 'Wavelength upper bound', ubnd(4), 7000.0D0, - : status ) - - - - idoc = 3 - iread = 0 - obj = ast_read( ch, status ) - - call readast( 'stcschan-test1-doc3.ast', sb, status ) - if( .not. ast_equal( obj, sb, status ) ) then - call error( 'Object read from doc3 is not equal to the '// - : 'object read from file stcschan-test1-doc3.ast.', - : status ) - end if - - - call ast_setl( ch, 'StcsCoords', .true., status ) - call ast_setl( ch, 'StcsProps', .true., status ) - - idoc = 3 - iread = 0 - obj = ast_read( ch, status ) - - call asserta( obj, 'Class', 'KeyMap', status ) - call assert( 'Has PROPS entry', AST_MAPHASKEY( obj, 'PROPS', - : status ), status ) - call assert( 'Has COORDS entry', AST_MAPHASKEY( obj, 'COORDS', - : status ), status ) - - if( ast_mapget0a( obj, 'AREA', iobj, status ) ) then - call readast( 'stcschan-test1-doc3.ast', sb, status ) - if( .not. ast_equal( iobj, sb, status ) ) then - call error( 'AREA read from doc3 is not equal to the '// - : 'object read from file stcschan-test1-doc3.ast', - : status ) - end if - else - call error( 'No AREA entry found', status ) - end if - - if( ast_mapget0a( obj, 'PROPS', iobj, status ) ) then - call readast( 'stcschan-test1-doc3-props.ast', sb, status ) - if( .not. ast_equal( iobj, sb, status ) ) then - call error( 'PROPS read from doc3 is not equal to the '// - : 'object read from file stcschan-test1-doc3-props.ast', - : status ) - end if - else - call error( 'No PROPS entry found', status ) - end if - - - - idoc = 5 - iread = 0 - - call ast_setl( ch, 'Indent', .true., status ) - - obj = ast_read( ch, status ) - - iwrite = 0 - nobj = ast_write( ch, obj, status ) - call asserti( 'N obj', nobj, 1, status ) - - call assertc( 'line 1 3', buff(1), - : 'TimeInterval TT geocenter 1996-01-01T00:00:00 '// - : '1996-01-01T00:30:00', status ) - call assertc( 'line 2 3', buff(2), - : ' Time MJD 50814.0 Error 1.2 Resolution 0.8 '// - : 'PixSize 1024.0', status ) - call assertc( 'line 3 3', buff(3), - : 'Union ICRS GEOCENTER ( ', status ) - call assertc( 'line 4 3', buff(4), - : ' Circle 180 10 20 ', status ) - call assertc( 'line 5 3', buff(5), - : ' Circle 190 10 20 ', status ) - call assertc( 'line 6 3', buff(6), - : ' Intersection ( ', status ) - call assertc( 'line 7 3', buff(7), - : ' Circle 120 -10 20 ', status ) - call assertc( 'line 8 3', buff(8), - : ' Difference ( ', status ) - call assertc( 'line 9 3', buff(9), - : ' Circle 130 -10 20 ', status ) - call assertc( 'line 10 3', buff(10), - : ' Circle 115 -10 10 ', status ) - call assertc( 'line 11 3', buff(11), - : ' ) ', status ) - call assertc( 'line 12 3', buff(12), - : ' ) ', status ) - call assertc( 'line 13 3', buff(13), - : ' ) ', status ) - call assertc( 'line 14 3', buff(14), - : ' Position 179.0 -11.5 Error 0.000889 0.000889 '// - : 'Resolution 0.001778', status ) - call assertc( 'line 15 3', buff(15), - : ' Size 0.000333 0.000278 PixSize 0.000083 '// - : '0.000083', status ) - call assertc( 'line 16 3', buff(16), - : 'Spectral BARYCENTER 1420.4 unit MHz Resolution '// - : '10.0 ', status ) - call assertc( 'line 17 3', buff(17), - : 'RedshiftInterval BARYCENTER VELOCITY OPTICAL '// - : '200 2300 Redshift 300', status ) - - call ast_end( status ) - - if( status .ne. sai__ok ) call err_rep( ' ', 'test1 failed.', - : status ) - - end - - - subroutine test2( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - include 'PRM_PAR' - - integer iwrite - character buff(30)*300 - common /bbb/ iwrite, buff - - integer iread, idoc - common /aaa/ iread, idoc - - - - external source, sink - - integer status, ch, sf, unc, reg, nobj, obj, chr_len - double precision p1(2), p2(2), p3(3), lbnd(2), ubnd(2) - - if( status .ne. sai__ok ) return - - - call ast_begin( status ) - ch = ast_stcschan( source, sink, 'ReportLevel=3',status ) - call ast_setl( ch, 'Indent', .true., status ) - call ast_seti( ch, 'StcsLength', 60, status ) - - sf = ast_skyframe( ' ', status ); - p1( 1 ) = 0.0 - p1( 2 ) = 1.3 - p2( 1 ) = 0.01 - - unc = ast_circle( sf, 1, p1, p2, AST__NULL, ' ', status ) - - p1( 1 ) = 1.3 - p1( 2 ) = 0.5 - p2( 1 ) = 0.3 - p2( 2 ) = 0.1 - p3( 1 ) = 1.0 - reg = ast_ellipse( sf, 1, p1, p2, p3, unc, ' ', status ) - - iwrite = 0 - nobj = ast_write( ch, reg, status ) - call asserti( 'N obj', nobj, 1, status ) - call asserti( 'iwrite', iwrite, 2, status ) - call assertc( 'line 1', buff(1), 'Ellipse ICRS TOPOCENTER '// - : '74.48451 28.64789 17.18873 5.729578', status ) - call assertc( 'line 2', buff(2), ' 57.29578 Error 0.5729514 '// - : '0.5726735', status ) - - call ast_set( ch, 'StcsCoords=1,StcsProps=1', status ) - - idoc = 3 - iread = 0 - obj = ast_read( ch, status ) - - if( obj .ne. AST__NULL ) then - iwrite = 0 - nobj = ast_write( ch, obj, status ) - call asserti( 'N obj 2', nobj, 1, status ) - - call assertc( 'line 1 2', buff(1), 'TimeInterval TT '// - : 'GEoCENTER 1996-01-01T00:00:00', status ) - - call assertc( 'line 2 2', buff(2), ' 1996-01-01T00:30:00 '// - : 'Time MJD 50814.0 Error 1.2', status ); - - call assertc( 'line 3 2', buff(3), ' Resolution 0.8 '// - : 'PixSize 1024.0', status ) - - call assertc( 'line 4 2', buff(4), 'Circle ICRS GEOCENTER '// - : '179.0 -11.5 0.5 Position 179.0 -11.5', status ) - - call assertc( 'line 5 2', buff(5), ' Error 0.000889 '// - : '0.000889 Resolution 0.001778 Size 0.000333', - : status ) - - call assertc( 'line 6 2', buff(6), ' 0.000278 PixSize '// - : '0.000083 0.000083', status ) - - call assertc( 'line 7 2', buff(7), 'Spectral BARYCENTER '// - : '1420.4 unit MHz Resolution 10.0', status ) - - call assertc( 'line 8 2', buff(8), 'RedshiftInterval '// - : 'BARYCENTER VELOCITY OPTICAL 200 2300 ', - : status ) - - call assertc( 'line 9 2', buff(9), ' Redshift 300 '// - : 'Resolution 0.7 PixSize 0.3', status ) - - else - write(*,*) 'No object read from doc 3' - end if - - - call ast_end( status ) - - if( status .ne. sai__ok ) call err_rep( ' ', 'test2 failed.', - : status ) - - end - - - - - - - - - - - - - - - subroutine source( status ) - implicit none - - integer iread, idoc - common /aaa/ iread, idoc - - logical done - integer status, l, chr_len - character c*80 - - c = ' ' - done = .false. - - if( idoc .eq. 1 ) then - if( iread .eq. 0 ) then - c = 'StartTime 1900-01-01 Circle ICRS 148.9 69.1 2.0 fred' - else if( iread .eq. 1 ) then - c = 'SpectralInterval 4000 7000 unit Angstrom' - else - done = .true. - end if - - else if( idoc .eq. 2 ) then - if( iread .eq. 0 ) then - c = 'StartTime 1900-01-01 Circle ICRS 148.9 69.1 2.0 ' - else if( iread .eq. 1 ) then - c = 'SpeCtralInterval 4000 7000 unit Angstrom' - else - done = .true. - end if - - else if( idoc .eq. 3 ) then - if( iread .eq. 0 ) then - c = 'TimeInterVal TT GEoCENTER' - else if( iread .eq. 1 ) then - c = '1996-01-01T00:00:00 1996-01-01T00:30:00' - else if( iread .eq. 2 ) then - c = 'Time MJD 50814.0 Error 1.2' - else if( iread .eq. 3 ) then - c = 'Resolution 0.8 PixSize 1024.0' - else if( iread .eq. 4 ) then - c = 'Circle ICRS GEOCENTER 179.0 -11.5 0.5' - else if( iread .eq. 5 ) then - c = 'Position 179.0 -11.5 Error 0.000889' - else if( iread .eq. 6 ) then - c = 'Resolution 0.001778 Size 0.000333 0.000278' - else if( iread .eq. 7 ) then - c = 'PixSIZE 0.000083 0.000083' - else if( iread .eq. 8 ) then - c = 'Spectral BARYCENTER 1420.4 unit MHz' - else if( iread .eq. 9 ) then - c = 'Resolution 10.0' - else if( iread .eq. 10 ) then - c = 'RedshiftInterval BARYCENTER VELOCITY OPTICAL' - else if( iread .eq. 11 ) then - c = '200.0 2300.0 Redshift 300.0' - else if( iread .eq. 12 ) then - c = 'Resolution 0.7 PixSize 0.3' - else - done = .true. - end if - - else if( idoc .eq. 4 ) then - if( iread .eq. 0 ) then - c = 'TimeInterval TT GEOCENTER' - else if( iread .eq. 1 ) then - c = '1996-01-01T00:00:00 1996-01-01T00:30:00' - else if( iread .eq. 2 ) then - c = 'Time mjd 50814.0 ERROR 1.2' - else if( iread .eq. 3 ) then - c = 'Resolution 0.8 PixSize 1024.0' - else if( iread .eq. 4 ) then - c = 'Spectral barycenter 1420.4 UNIT MHz' - else if( iread .eq. 5 ) then - c = 'Resolution 10.0' - else - done = .true. - end if - -* Like doc 3 but with a compound spatial region - else if( idoc .eq. 5 ) then - if( iread .eq. 0 ) then - c = 'tIMEiNTERVAL tt geocenter' - else if( iread .eq. 1 ) then - c = '1996-01-01T00:00:00 1996-01-01T00:30:00' - else if( iread .eq. 2 ) then - c = 'Time MJD 50814.0 Error 1.2' - else if( iread .eq. 3 ) then - c = 'Resolution 0.8 PixSize 1024.0' - else if( iread .eq. 4 ) then - c = ' ' - else if( iread .eq. 5 ) then - c = 'Union ICRS GEOCENTER' - else if( iread .eq. 6 ) then - c = ' (Circle 180 10 20' - else if( iread .eq. 7 ) then - c = ' Circle 190 10 20' - else if( iread .eq. 8 ) then - c = ' Intersection (' - else if( iread .eq. 9 ) then - c = ' cIRCLE 120 -10 20 dIFFERENCE ' - else if( iread .eq. 10 ) then - c = ' ( Circle 130 -10 20 ' - else if( iread .eq. 11 ) then - c = ' Circle 115 -10 10 ' - else if( iread .eq. 12 ) then - c = ' )' - else if( iread .eq. 13 ) then - c = ' Not (Circle 118 -8 3)' - else if( iread .eq. 14 ) then - c = ' )' - else if( iread .eq. 15 ) then - c = ' )' - else if( iread .eq. 16 ) then - c = 'Position 179.0 -11.5 Error 0.000889' - else if( iread .eq. 17 ) then - c = 'Resolution 0.001778 Size 0.000333 0.000278' - else if( iread .eq. 18 ) then - c = 'PixSize 0.000083 0.000083' - else if( iread .eq. 19 ) then - c = 'Spectral BARYCENTER 1420.4 unit MHz' - else if( iread .eq. 20 ) then - c = 'rESOLUTION 10.0' - else if( iread .eq. 21 ) then - c = 'rEDSHIFTiNTERVAL barycenter velocity optical' - else if( iread .eq. 22 ) then - c = '200.0 2300.0 rEDSHIFT 300.0' - else if( iread .eq. 23 ) then - c = 'Resolution 0.7 PixSize 0.3' - else - done = .true. - end if - - end if - - l = max( chr_len( c ), 1 ) - if( .not. done ) then - call ast_putline( c, l, status ) - iread = iread + 1 - else - call ast_putline( ' ', -1, status ) - end if - - end - - - - - - - - subroutine sink( status ) - implicit none - - integer iwrite - character buff(30)*300 - common /bbb/ iwrite, buff - - integer status, l - character line*300 - - call ast_getline( line, l, status ) - if( l .gt. 0 ) then - if( iwrite .lt. 0 ) then - write(*,*) line( : l ) - else - iwrite = iwrite + 1 - buff( iwrite ) = ' ' - buff( iwrite ) = line( : l ) - end if - end if - - end - - - subroutine asserta( obj, anam, asb, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer obj, status - character anam*(*), asb*(*), aval*80 - - aval = ast_GetC( obj, anam, status ) - - if( aval .ne. asb ) then - call msg_setc( 'A', anam ) - call msg_setc( 'B', aval ) - call msg_setc( 'C', asb ) - call error( '^A (^B) should be "^C".', status ) - end if - - end - - subroutine assertc( name, val, sb, status ) - implicit none - include 'SAE_PAR' - integer status, i - character name*(*), val*(*), sb*(*) - character blank*500 - - if( val .ne. sb .and. status .eq. sai__ok ) then - call msg_setc( 'A', name ) - call msg_setc( 'B', val ) - call error( '^A (^B) should be:', status ) - - i = 1 - blank = ' ' - do while( val( i : i ) .eq. sb( i : i ) ) - i = i + 1 - end do - blank( i : i ) = '^' - - write(*,*) sb - write(*,*) blank( : i + 2 ) - - end if - - end - - subroutine asserti( name, val, sb, status ) - implicit none - include 'SAE_PAR' - integer status - character name*(*) - integer val, sb - - if( val .ne. sb ) then - call msg_setc( 'A', name ) - call msg_seti( 'B', val ) - call msg_seti( 'C', sb ) - call error( '^A (^B) should be ^C.', status ) - end if - - end - - subroutine assert( name, val, status ) - implicit none - include 'SAE_PAR' - integer status - character name*(*) - logical val - - if( .not. val ) then - call msg_setc( 'A', name ) - call error( '^A is not true.', status ) - end if - - end - - subroutine assertd( name, val, sb, status ) - implicit none - include 'SAE_PAR' - integer status - character name*(*) - double precision val, sb - - if( abs( val - sb ) .gt. 0.5E-8*( val + sb ) ) then - call msg_setc( 'A', name ) - call msg_setd( 'B', val ) - call msg_setd( 'C', sb ) - call error( '^A (^B) should be ^C.', status ) - end if - - end - - subroutine error( text, status ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .eq. sai__ok ) then - status = sai__error - call err_rep( ' ', text, status ) - end if - - end - - - subroutine readast( file, obj, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer obj, status, channel - character file*(*) - external rsource - - if( status .ne. sai__ok ) return - - open( 10, file=file, status='old' ) - channel = ast_channel( rsource, ast_null, ' ', status ) - obj = ast_read( channel, status ) - call ast_annul( channel, status ) - close( 10 ) - - end - - - subroutine rsource( status ) - integer status - character buffer*200 - - read( 10, '(a)', end = 99 ) buffer - call ast_putline( buffer, len( buffer ), status ) - return - - 99 call ast_putline( buffer, -1, status ) - end - - diff --git a/ast/ast_tester/testswitchmap.f b/ast/ast_tester/testswitchmap.f deleted file mode 100644 index 401447b..0000000 --- a/ast/ast_tester/testswitchmap.f +++ /dev/null @@ -1,794 +0,0 @@ - program testswitchmap - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer status, outperm(2), inperm(2), wm1, wm2, pm1, pm2, rm(2), - : fs, is, swm, i, swm2, cm, cm2, sm, oc, mc, fc, - : box(2), gridframe - double precision x1, x2, l1, l2, in(4,2), out(4,2), at(2), r, - : p1(2),p2(2), rmout(4,2), r1, r2 - character text*10, fwd(1)*40, inv(2)*40, card(10)*80 - - status = sai__ok - - call ast_begin( status ) - -c call ast_watchmemory(22617) - - oc = ast_tune( 'ObjectCaching', 1, status ) - mc = ast_tune( 'MemoryCaching', 1, status ) - - - -* A 2D input grid has 2 rows and 101 columns. Each row contains a spectrum. -* The two spectra cover overlaping regions of wavelength. The spectrum in -* row 1 has "wavelength = (gridx - 1)*10+1000", whilst the spectrum in -* row 2 has "wavelength = (gridx - 1)*11+1600". We use a (Nin=2,Nout=1) -* SwitchMap to describe the Mapping from grid (x,y) to wavelength. This -* SwitchMap contains 2 route Mappings, one for each row of the grid. -* -------------------------------------------------------------------- - -* Produce a 1D Mapping from gridx to wavelength for row 1. - x1 = 1.0 - x2 = 101.0 - l1 = 1000.0 - l2 = 2000.0 - wm1 = ast_winmap( 1, x1, x2, l1, l2, ' ', status ) - -* Since the SwicthMap has 2 inputs, each of the route Mappings must also -* have 2 inputs. Produce a PermMap which passes on its 1st input to its -* (one and only) output. The inverse transformation supplied a value of -* 1.0 for the missing 2nd input (1.0 is the grid Y value for the first -* row). - outperm( 1 ) = 1 - inperm( 1 ) = 1 - inperm( 2 ) = -1 - pm1 = ast_permmap( 2, inperm, 1, outperm, 1.0D0, ' ', status ) - -* Combine the PermMap and WinMap in series to get the total route -* Mapping for the first row. - rm(1) = ast_cmpmap( pm1, wm1, .true., ' ', status ) - -* Likewise, produce the route Mapping for the second row. The grid y -* value for the second row is 2.0, so use this as the constant in the -* PermMap (i.e. the value which the inverse transformation supplies for -* the missing second input). - l1 = 1600.0 - l2 = 2700.0 - wm2 = ast_winmap( 1, x1, x2, l1, l2, ' ', status ) - pm2 = ast_permmap( 2, inperm, 1, outperm, 2.0D0, ' ', status ) - rm(2) = ast_cmpmap( pm2, wm2, .true., ' ', status ) - -* The forward selector Mapping just uses the second input (the grid Y -* value) as the selector value (i.e. gridy=1 selects the first route -* Mapping and gridy=2 selects the second route Mapping). The inverse -* transformation of this Mapping is never used and so does not matter. - outperm( 1 ) = 2 - inperm( 2 ) = 1 - inperm( 1 ) = 0 - fs = ast_permmap( 2, inperm, 1, outperm, 0.0D0, ' ', status ) - -* The inverse selector function needs to decide which route Mapping to -* use for any supplied ("output") wavelength value. We arbitrarily -* decide to to use the first row for wavelengths less than or equal to -* 1800, and the second row for wavelengths larger than 1800 (1800 is the -* mid-point of the overlap between the two spectra). We use a MathMap to -* implement this transformation, which must be the *inverse* -* transformation of the MathMap. The forward transformation of the -* inverse slector Mapping is never used and so is left unspecified in -* the MathMap constructor. - is = ast_mathmap( 1, 1, 1, 'y', 1, 'x=qif(y>1800,2,1)', ' ', - : status ) - -* Now create the SwitchMap. - swm = ast_switchmap( fs, is, 2, rm, ' ', status ) - -* Test the forward transformation of the SwitchMap. To add complication, -* we first invert the SwitchMap and then use ast_trann in the inverse -* direction (the two inversions cancel resulting in the forward -* transformation being used). - call ast_invert( swm, status ) - - in(1,1) = 1.0 - in(1,2) = 1.0 - in(2,1) = 101.0 - in(2,2) = 2.0 - in(3,1) = 1.0 - in(3,2) = 2.0 - in(4,1) = 101.0 - in(4,2) = 1.0 - call ast_trann( swm, 4, 2, 4, in, .false., 1, 4, out, status ) - - do i = 1, 4 - if( out(i,1) .eq. ast__bad ) then - call stopit( i, out(i,1), status ) - end if - end do - - if( abs( out(1,1) - 1000.0 ) .gt. 1.0E-5 ) then - call stopit( 5, out(1,1), status ) - else if( abs( out(2,1) - 2700.0 ) .gt. 1.0E-5 ) then - call stopit( 6, out(2,1), status ) - else if( abs( out(3,1) - 1600.0 ) .gt. 1.0E-5 ) then - call stopit( 7, out(3,1), status ) - else if( abs( out(4,1) - 2000.0 ) .gt. 1.0E-5 ) then - call stopit( 8, out(4,1), status ) - end if - -* Test the inverse transformation of the SwitchMap. - call ast_trann( swm, 4, 1, 4, out, .true., 2, 4, in, status ) - - do i = 1, 4 - if( in(i,1) .eq. ast__bad ) then - call stopit( 7 + 2*i, in(i,1), status ) - else if( in(i,2) .eq. ast__bad ) then - call stopit( 8 + 2*i, in(i,2), status ) - end if - end do - - if( abs( in(1,1) - 1.0 ) .gt. 1.0E-5 ) then - call stopit( 17, in(1,1), status ) - else if( abs( in(1,2) - 1.0 ) .gt. 1.0E-5 ) then - call stopit( 18, in(1,2), status ) - else if( abs( in(2,1) - 101.0 ) .gt. 1.0E-5 ) then - call stopit( 19, in(2,1), status ) - else if( abs( in(2,2) - 2.0 ) .gt. 1.0E-5 ) then - call stopit( 20, in(2,2), status ) - else if( abs( in(3,1) - 61.0 ) .gt. 1.0E-5 ) then - call stopit( 21, in(3,1), status ) - else if( abs( in(3,2) - 1.0 ) .gt. 1.0E-5 ) then - call stopit( 22, in(3,2), status ) - else if( abs( in(4,1) - 37.3636364 ) .gt. 1.0E-5 ) then - call stopit( 23, in(4,1), status ) - else if( abs( in(4,2) - 2.0 ) .gt. 1.0E-5 ) then - call stopit( 24, in(4,2), status ) - end if - -* Check no simplification is done on a single non-inverted SwicthMap. - call ast_setl( swm, 'Invert', .false., status ) - swm2 = ast_simplify( swm, status ) - call compare( swm, swm2, 'ast_equal 1', status ) - -* Check an inverted SwitchMap simplies to an non-inverted switchmap. - call ast_setl( swm, 'Invert', .true., status ) - swm2 = ast_simplify( swm, status ) - if( ast_getl( swm2, 'Invert', status ) ) then - call stopit( 25, 1.0D0, status ) - end if - -* Check two adjacent opposite SwitchMaps cancel. - swm2 = ast_copy( swm, status ) - call ast_invert( swm2, status ) - cm = ast_cmpmap( swm, swm2, .true., ' ', status ) - cm2 = ast_simplify( cm, status ) - if( .not. ast_isaunitmap( cm2, status ) ) then - call stopit( 26, 1.0D0, status ) - end if - - cm = ast_cmpmap( swm2, swm, .true., ' ', status ) - cm2 = ast_simplify( cm, status ) - if( .not. ast_isaunitmap( cm2, status ) ) then - call stopit( 27, 1.0D0, status ) - end if - -* Check that the SwitchMap can be written out to a AstChannel and read -* back again succesfully. - call checkdump( swm, 'Channel test 1', status ) - -* Check the ast_rate function works OK. - call ast_setl( swm, 'Invert', .false., status ) - - at(1) = 20.0 - at(2) = 1.0 - r = ast_rate( swm, at, 1, 1, status ) - if( abs( r - 10.0 ) .gt. 1.0E-6 ) call stopit( 28, r, status ) - - at(1) = 20.0 - at(2) = 2.0 - r = ast_rate( swm, at, 1, 1, status ) - if( abs( r - 11.0 ) .gt. 1.0E-6 ) call stopit( 29, r, status ) - - call ast_setl( swm, 'Invert', .true., status ) - - at(1) = 1700.0 - r = ast_rate( swm, at, 1, 1, status ) - if( abs( r - 1.0/10.0 ) .gt. 1.0E-6 ) call stopit( 30, r, status ) - - at(1) = 1900.0 - r = ast_rate( swm, at, 1, 1, status ) - if( abs( r - 1.0/11.0 ) .gt. 1.0E-6 ) call stopit( 31, r, status ) - - call ast_setl( swm, 'Invert', .false., status ) - - -* A 1D input grid has 1 rows and 202 columns. Each half of the row -* (1:101 and 102:202) contains a spectrum. The two spectra cover -* overlaping regions of wavelength. The spectrum in thw lower half has -* "wavelength = (gridx - 1)*10+1000", whilst the spectrum in the upper -* half has "wavelength = (gridx - 1)*11+1600". We use a (Nin=1,Nout=1) -* SwitchMap to describe the Mapping from grid (x) to wavelength. This -* SwitchMap contains 2 route Mappings, one for each half of the row. -* -------------------------------------------------------------------- - -* Produce a 1D Mapping from gridx to wavelength for the lower half. - x1 = 1.0 - x2 = 101.0 - l1 = 1000.0 - l2 = 2000.0 - rm(1) = ast_winmap( 1, x1, x2, l1, l2, ' ', status ) - -* Likewise, produce a 1D Mapping from gridx to wavelength for the upper half. - x1 = 102.0 - x2 = 202.0 - l1 = 1600.0 - l2 = 2700.0 - rm(2) = ast_winmap( 1, x1, x2, l1, l2, ' ', status ) - -* We can use a single MathMap for both selector Mappings - the forward -* transformation (used as the forward selector) gives 1 for all gridx less -* than 101.5 and 2 for all gridx greater than 101.5. The inverse -* transformation (used as the inverse selector) gives 1 for all -* wavelengths les than 1800 and 2 for all wavelength greater than 1800 -* (1800 is the mid point of the overlap region). - sm = ast_mathmap( 1, 1, 1, 'y=qif(x>101.5,2,1)', - : 1, 'x=qif(y>1800,2,1)', - : ' ', status ) - -* Now create the SwitchMap. - swm = ast_switchmap( sm, sm, 2, rm, ' ', status ) - -* Test the forward transformation of the SwitchMap. To add complication, -* we first invert the SwitchMap and then use ast_trann in the inverse -* direction (the two inversions cancel resulting in the forward -* transformation being used). We alo invert the selector mapping (this -* should have no effect on the SwitchMap). - call ast_invert( swm, status ) - call ast_invert( sm, status ) - - in(1,1) = 1.0 - in(2,1) = 202.0 - in(3,1) = 102.0 - in(4,1) = 101.0 - call ast_trann( swm, 4, 1, 4, in, .false., 1, 4, out, status ) - - do i = 1, 4 - if( out(i,1) .eq. ast__bad ) then - call stopit( 100+i, out(i,1), status ) - end if - end do - - if( abs( out(1,1) - 1000.0 ) .gt. 1.0E-5 ) then - call stopit( 105, out(1,1), status ) - else if( abs( out(2,1) - 2700.0 ) .gt. 1.0E-5 ) then - call stopit( 106, out(2,1), status ) - else if( abs( out(3,1) - 1600.0 ) .gt. 1.0E-5 ) then - call stopit( 107, out(3,1), status ) - else if( abs( out(4,1) - 2000.0 ) .gt. 1.0E-5 ) then - call stopit( 108, out(4,1), status ) - end if - -* Test the inverse transformation of the SwitchMap. - call ast_trann( swm, 4, 1, 4, out, .true., 1, 4, in, status ) - - do i = 1, 4 - if( in(i,1) .eq. ast__bad ) then - call stopit( 107 + 2*i, in(i,1), status ) - end if - end do - - if( abs( in(1,1) - 1.0 ) .gt. 1.0E-5 ) then - call stopit( 117, in(1,1), status ) - else if( abs( in(2,1) - 202.0 ) .gt. 1.0E-5 ) then - call stopit( 119, in(2,1), status ) - else if( abs( in(3,1) - 61.0 ) .gt. 1.0E-5 ) then - call stopit( 121, in(3,1), status ) - else if( abs( in(4,1) - 138.3636364 ) .gt. 1.0E-5 ) then - call stopit( 123, in(4,1), status ) - end if - -* Check no simplification is done on a single non-inverted SwicthMap. - call ast_setl( swm, 'Invert', .false., status ) - swm2 = ast_simplify( swm, status ) - call compare( swm, swm2, 'ast_equal 2', status ) - -* Check an inverted SwitchMap simplies to an non-inverted switchmap. - call ast_setl( swm, 'Invert', .true., status ) - swm2 = ast_simplify( swm, status ) - if( ast_getl( swm2, 'Invert', status ) ) then - call stopit( 125, 1.0D0, status ) - end if - -* Check two adjacent opposite SwitchMaps cancel. - swm2 = ast_copy( swm, status ) - call ast_invert( swm2, status ) - cm = ast_cmpmap( swm, swm2, .true., ' ', status ) - cm2 = ast_simplify( cm, status ) - if( .not. ast_isaunitmap( cm2, status ) ) then - call stopit( 126, 1.0D0, status ) - end if - - cm = ast_cmpmap( swm2, swm, .true., ' ', status ) - cm2 = ast_simplify( cm, status ) - if( .not. ast_isaunitmap( cm2, status ) ) then - call stopit( 127, 1.0D0, status ) - end if - -* Check that the SwitchMap can be written out to a AstChannel and read -* back again succesfully. - call checkdump( swm, 'Channel test 2', status ) - -* Check the ast_rate function works OK. - call ast_setl( swm, 'Invert', .false., status ) - - at(1) = 20.0 - r = ast_rate( swm, at, 1, 1, status ) - if( abs( r - 10.0 ) .gt. 1.0E-6 ) call stopit( 128, r, status ) - - at(1) = 120.0 - r = ast_rate( swm, at, 1, 1, status ) - if( abs( r - 11.0 ) .gt. 1.0E-6 ) call stopit( 129, r, status ) - - call ast_setl( swm, 'Invert', .true., status ) - - at(1) = 1700.0 - r = ast_rate( swm, at, 1, 1, status ) - if( abs( r - 1.0/10.0 ) .gt. 1.0E-6 ) call stopit( 130, r, - : status ) - - at(1) = 1900.0 - r = ast_rate( swm, at, 1, 1, status ) - if( abs( r - 1.0/11.0 ) .gt. 1.0E-6 ) call stopit( 131, r, - : status ) - - call ast_setl( swm, 'Invert', .false., status ) - - -* A 2D input grid has bounds (1:180,1:100). The area (10:80,10:80) -* and the area (100:170,10:80) both contain images of a fixed part of -* the sky (e.g. in different polarisations). The WCS for each sub-region -* is derived from a single FITS-WCS header,with suitably shifted origin. -* -------------------------------------------------------------------- - card(1) = 'CRPIX1 = 45' - card(2) = 'CRPIX2 = 45' - card(3) = 'CRVAL1 = 45' - card(4) = 'CRVAL2 = 89.9' - card(5) = 'CDELT1 = -0.01' - card(6) = 'CDELT2 = 0.01' - card(7) = 'CTYPE1 = ''RA---TAN''' - card(8) = 'CTYPE2 = ''DEC--TAN''' - - fc = ast_fitschan( AST_NULL, AST_NULL, ' ', status ) - do i = 1, 8 - call ast_putfits( fc, card(i), .false., status ) - end do - call ast_clear( fc, 'Card', status ) - fs = ast_read( fc, status ) - rm(1) = ast_getMapping( fs, ast__base, ast__current, status ) - - card(1) = 'CRPIX1 = 135' - call ast_clear( fc, 'Card', status ) - do i = 1, 8 - call ast_putfits( fc, card(i), .true., status ) - end do - call ast_clear( fc, 'Card', status ) - fs = ast_read( fc, status ) - rm(2) = ast_getMapping( fs, ast__base, ast__current, status ) - -* Forward Selector Mapping: A SelectorMap which encapsulates the two Box -* Regions in GRID coords. - gridframe = ast_getframe( fs, AST__BASE, status ) - - p1(1) = 10 - p1(2) = 10 - p2(1) = 80 - p2(2) = 80 - box(1) = ast_box( gridframe, 1, p1, p2, AST__NULL, ' ', status ) - - p1(1) = 100 - p1(2) = 10 - p2(1) = 170 - p2(2) = 80 - box(2) = ast_box( gridframe, 1, p1, p2, AST__NULL, ' ', status ) - - fs = ast_selectormap( 2, box, AST__BAD, ' ', status ) - -* Inverse Selector Mapping: A PermMap which has an inverse transformation -* which gives an input value of 1 for all output values. This means that the -* inverse transformation of the SwitchMap always returns a GRID position in -* the lower (left-hand) of the two images. - inperm(1) = -1 - outperm(1) = 0 - outperm(2) = 0 - is = ast_permmap( 1, inperm, 2, outperm, 1.0D0, ' ', status ) - -* Now create the SwitchMap. - swm = ast_switchmap( fs, is, 2, rm, ' ', status ) - -* Test the forward transformation of the SwitchMap. To add complication, -* we first invert the SwitchMap and then use ast_trann in the inverse -* direction (the two inversions cancel resulting in the forward -* transformation being used). We alo invert the selector mapping (this -* should have no effect on the SwitchMap). - call ast_invert( swm, status ) - call ast_invert( fs, status ) - - in(1,1) = 5.0 - in(1,2) = 5.0 - - in(2,1) = 50.0 - in(2,2) = 50.0 - - in(3,1) = 90.0 - in(3,2) = 50.0 - - in(4,1) = 140.0 - in(4,2) = 50.0 - - call ast_trann( swm, 4, 2, 4, in, .false., 2, 4, out, status ) - -* Transform these same positions using the Mapping for the left hand -* image obtained from the FITS header - call ast_trann( rm(1), 4, 2, 4, in, .true., 2, 4, rmout, status ) - -* Check the SwitchMap results. Points 1 and 3 should be bad because they -* fall outside either image. points 2 and 4 should both be equal to the -* result of transforming point 2 using the FITS-WCS mapping. - - if( out(1,1) .ne. AST__BAD ) then - call stopit( 132, out(1,1), status ) - - else if( out(1,2) .ne. AST__BAD ) then - call stopit( 133, out(1,1), status ) - - else if( out(2,1) .ne. rmout(2,1) ) then - call stopit( 134, out(2,1), status ) - - else if( out(2,2) .ne. rmout(2,2) ) then - call stopit( 135, out(2,2), status ) - - else if( out(3,1) .ne. AST__BAD ) then - call stopit( 136, out(1,1), status ) - - else if( out(3,2) .ne. AST__BAD ) then - call stopit( 137, out(1,1), status ) - - else if( abs( out(4,1) - rmout(2,1) ) .gt. - : 1.0D-6*abs( rmout(2,1) ) ) then - call stopit( 138, out(2,1), status ) - - else if( abs( out(4,2) - rmout(2,2) ) .gt. - : 1.0D-6*abs( rmout(2,2) ) ) then - call stopit( 139, out(2,2), status ) - - end if - - -* Test the inverse transformation of the SwitchMap. - call ast_trann( swm, 4, 2, 4, out, .true., 2, 4, in, status ) - - if( in(1,1) .ne. AST__BAD ) then - call stopit( 140, in(1,1), status ) - - else if( in(1,2) .ne. AST__BAD ) then - call stopit( 141, in(1,1), status ) - - else if( abs( in(2,1) - 50.0 ) .gt. 1.0E-6 ) then - call stopit( 142, in(2,1), status ) - - else if( abs( in(2,2) - 50.0 ) .gt. 1.0E-6 ) then - call stopit( 143, in(2,2), status ) - - else if( in(3,1) .ne. AST__BAD ) then - call stopit( 144, in(1,1), status ) - - else if( in(3,2) .ne. AST__BAD ) then - call stopit( 145, in(1,1), status ) - - else if( abs( in(4,1) - 50.0 ) .gt. 1.0E-6 ) then - call stopit( 146, in(2,1), status ) - - else if( abs( in(4,2) - 50.0 ) .gt. 1.0E-6 ) then - call stopit( 147, in(2,2), status ) - - end if - -* Check no simplification is done on a single non-inverted SwicthMap. - call ast_setl( swm, 'Invert', .false., status ) - swm2 = ast_simplify( swm, status ) - call compare( swm, swm2, 'ast_equal 3', status ) - -* Check an inverted SwitchMap simplies to an non-inverted switchmap. - call ast_setl( swm, 'Invert', .true., status ) - swm2 = ast_simplify( swm, status ) - if( ast_getl( swm2, 'Invert', status ) ) then - call stopit( 148, 1.0D0, status ) - end if - -* Check two adjacent opposite SwitchMaps cancel. - swm2 = ast_copy( swm, status ) - call ast_invert( swm2, status ) - cm = ast_cmpmap( swm, swm2, .true., ' ', status ) - cm2 = ast_simplify( cm, status ) - if( .not. ast_isaunitmap( cm2, status ) ) then - call stopit( 149, 1.0D0, status ) - end if - - cm = ast_cmpmap( swm2, swm, .true., ' ', status ) - cm2 = ast_simplify( cm, status ) - if( .not. ast_isaunitmap( cm2, status ) ) then - call stopit( 150, 1.0D0, status ) - end if - -* Check that the SwitchMap can be written out to a AstChannel and read -* back again succesfully. - call checkdump( swm, 'Channel test 3', status ) - -* Check the ast_rate function works OK. - call ast_setl( swm, 'Invert', .false., status ) - - at(1) = 140.0 - at(2) = 50.0 - r1 = ast_rate( swm, at, 1, 1, status ) - - at(1) = 50.0 - r2 = ast_rate( rm(1), at, 1, 1, status ) - - if( abs( r1 - r2 ) .gt. abs( 1.0E-6*r2 ) ) call stopit( 151, r1, - : status ) - - at(1) = 140.0 - r1 = ast_rate( swm, at, 2, 2, status ) - - at(1) = 50.0 - r2 = ast_rate( rm(1), at, 2, 2, status ) - - if( abs( r1 - r2 ) .gt. abs( 1.0E-6*r2 ) ) call stopit( 152, r1, - : status ) - - at(1) = 140.0 - r1 = ast_rate( swm, at, 1, 2, status ) - - at(1) = 50.0 - r2 = ast_rate( rm(1), at, 1, 2, status ) - - if( abs( r1 - r2 ) .gt. abs( 1.0E-6*r2 ) ) call stopit( 153, r1, - : status ) - - at(1) = 140.0 - r1 = ast_rate( swm, at, 2, 1, status ) - - at(1) = 50.0 - r2 = ast_rate( rm(1), at, 2, 1, status ) - - if( abs( r1 - r2 ) .gt. abs( 1.0E-6*r2 ) ) call stopit( 154, r1, - : status ) - - - - - mc = ast_tune( 'MemoryCaching', mc, status ) - oc = ast_tune( 'ObjectCaching', oc, status ) - call ast_end( status ) - - call ast_activememory( 'testswitchmap' ) - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All SwitchMap tests passed' - else - write(*,*) 'SwitchMap tests failed' - end if - - end - - - subroutine stopit( i, r, status ) - implicit none - include 'SAE_PAR' - integer i, status - double precision r - if( status .eq. sai__ok ) then - write( *,* ) 'Error ',i,': ',r - status = sai__error - end if - end - - - - subroutine checkdump( obj, text, status ) - - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*) - integer obj, status, next, end, ch, result, ll, overlap, ibuf, - : len1, len2 - external mysource, mysink - character buf1*45000 - character buf2*45000 - - common /ss1/ buf1 - common /ss3/ buf2 - common /ss2/ next, end, ll, ibuf - - if( status .ne. sai__ok ) return - -* Create a Channel which reads and writes to an internal string buffer. - ch = ast_channel( mysource, mysink, ' ', status ) - -* Write the supplied Object out to this Channel. - ll = 160 - next = 1 - ibuf = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( 1000, 1.0D0, status ) - end if - len1 = next - -* Read an Object back from this Channel. - next = 1 - result = ast_read( ch, status ) - if( result .eq. ast__null ) then - write(*,*) text - call stopit( 1001, 1.0D0, status ) - end if - -* Check that it is of the same class as the supplied object. - if( ast_getc( result, 'Class', status ) .ne. - : ast_getc( obj, 'Class', status ) ) then - write(*,*) text - call stopit( 1002, 1.0D0, status ) - end if - -* Compare it to the suuplied object. - call compare( obj, result, text, status ) - - end - - - - - subroutine compare( obj1, obj2, text, status ) - - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*) - integer obj1, status, next, end, ch, result, ll, overlap, ibuf, - : len1, len2, obj2 - external mysource, mysink - character buf1*45000 - character buf2*45000 - - common /ss1/ buf1 - common /ss3/ buf2 - common /ss2/ next, end, ll, ibuf - - if( status .ne. sai__ok ) return - -* Create a Channel which reads and writes to an internal string buffer. - ch = ast_channel( mysource, mysink, ' ', status ) - -* Write the first supplied Object out to this Channel, using buf1 - ll = 160 - next = 1 - ibuf = 1 - if( ast_write( ch, obj1, status ) .ne.1 ) then - write(*,*) text - call stopit( 2000, 1.0D0, status ) - end if - len1 = next - -* Write the second object out to the second buffer. - ll = 160 - next = 1 - ibuf = 2 - if( ast_write( ch, obj2, status ) .ne.1 ) then - write(*,*) text - call stopit( 2001, 1.0D0, status ) - end if - len2 = next - -* Compare the contents of the two buffers. - if( buf1( : len1 ) .ne. buf2( : len2 ) ) then - write(*,*) text - write(*,*) len1, len2 - call ast_show( obj1, status ) - call ast_show( obj2, status ) - call stopit( 2002, 1.0D0, status ) - - end if - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll, ibuf - character buf1*45000 - character buf2*45000 - - common /ss1/ buf1 - common /ss3/ buf2 - common /ss2/ next, end, ll, ibuf - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - if( ibuf .eq. 1 ) then - call ast_putline( buf1, -1, status ) - else - call ast_putline( buf2, -1, status ) - endif - else - if( ibuf .eq. 1 ) then - call ast_putline( buf1( next : ), ll, status ) - else - call ast_putline( buf2( next : ), ll, status ) - endif - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll, ibuf - character line*1000 - character buf1*45000 - character buf2*45000 - - common /ss1/ buf1 - common /ss3/ buf2 - common /ss2/ next, end, ll, ibuf - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - - if( ibuf .eq. 1 ) then - buf1( next : ) = line( f : l ) - else - buf2( next : ) = line( f : l ) - end if - - l = l - f + 1 - - if( next + ll - 1 .ge. 45000 ) then - write(*,*) 'Buffer overflow in mysink!!' - status = SAI__ERROR - - else if( l .gt. ll ) then - write(*,*) - if( ibuf .eq. 1 ) then - write(*,*) buf1( next : next + l) - else - write(*,*) buf2( next : next + l) - end if - write(*,*) 'Line length ',l,' greater than ',ll - write(*,*) 'Line overflow in mysink!!' - status = SAI__ERROR - else - end = next + l - if( ibuf .eq. 1 ) then - buf1( end : next + ll - 1 ) = ' ' - else - buf2( end : next + ll - 1 ) = ' ' - end if - endif - - next = next + ll - - end - - - - diff --git a/ast/ast_tester/testtable.f b/ast/ast_tester/testtable.f deleted file mode 100644 index 907dd66..0000000 --- a/ast/ast_tester/testtable.f +++ /dev/null @@ -1,537 +0,0 @@ - program testtable - implicit none - - include 'AST_PAR' - include 'AST_ERR' - include 'SAE_PAR' - - integer status, table, table2, dims( 7 ), ival, l, nval - byte bytes(1,2),bval - real rval - character cval*30, text(2,2)*10 - - -c call ast_watchmemory(483) - - - status = sai__ok - call err_mark( status ) - call ast_begin( status ) - - table = ast_table( ' ', status ) - - call ast_mapput0i( table, 'Fred', 123, 'com 1', status ) - if( status .eq. AST__BADKEY ) then - call err_annul( status ) - else - if( status .ne. sai__ok ) call err_annul( status ) - call stopit( status, 'Table error 1' ) - endif - - call ast_mapput0i( table, 'Fred(2)', 123, 'com 1', status ) - if( status .eq. AST__BADKEY ) then - call err_annul( status ) - else - if( status .ne. sai__ok ) call err_annul( status ) - call stopit( status, 'Table error 2' ) - endif - - dims( 1 ) = 5 - dims( 2 ) = 2 - call ast_addcolumn( table, 'Fred', AST__FLOATTYPE, 2, dims, - : ' ', status ) - - if( ast_geti( table, 'NColumn', status ) .ne. 1 ) then - call stopit( status, 'Table error 2b' ) - endif - - if( ast_columnname( table, 1, status ) .ne. 'FRED' ) then - call stopit( status, 'Table error 2c' ) - endif - - if( ast_geti( table, 'ColumnType(Fred)', status ) .ne. - : AST__FLOATTYPE ) then - call stopit( status, 'Table error 2d' ) - endif - - call ast_columnshape( table, 'Fred', 2, nval, dims, status ) - if( nval .ne. 2 ) then - call stopit( status, 'Table error 2e' ) - else if( dims( 1 ) .ne. 5 ) then - call stopit( status, 'Table error 2f' ) - else if( dims( 2 ) .ne. 2 ) then - call stopit( status, 'Table error 2g' ) - endif - - if( ast_getc( table, 'ColumnUnit(Fred)', status ) .ne. ' ' ) then - call stopit( status, 'Table error 2h' ) - endif - - call ast_mapput0i( table, 'Fred(2)', 123, 'com 1', status ) - if( status .eq. AST__BADTYP ) then - call err_annul( status ) - else if( status .eq. sai__ok ) then - call stopit( status, 'Table error 3' ) - endif - - call ast_mapput0r( table, 'Fred(2)', 123, 'com 1', status ) - if( status .eq. AST__BADTYP ) then - call err_annul( status ) - else if( status .eq. sai__ok ) then - call stopit( status, 'Table error 4' ) - endif - - call ast_addcolumn( table, 'Fred', AST__FLOATTYPE, 0, 0, - : 'pW', status ) - if( status .eq. AST__OLDCOL ) then - call err_annul( status ) - else if( status .eq. sai__ok ) then - call stopit( status, 'Table error 5' ) - endif - - call ast_removecolumn( table, 'Fred', status ) - - if( ast_geti( table, 'NColumn', status ) .ne. 0 ) then - call stopit( status, 'Table error 5b' ) - endif - - call ast_addcolumn( table, 'Fred', AST__FLOATTYPE, 0, 0, - : 'pW', status ) - - call ast_mapput0r( table, 'Fred(1)', -123.0, 'com 1', status ) - call ast_mapput0r( table, 'Fred(2)', 123.0, 'com 2', status ) - - if( ast_mapget0r( table, 'Fred(2)', rval, status ) ) then - if( rval .ne. 123.0 ) call stopit( status, 'Table error 6' ) - else - call stopit( status, 'Table error 7' ) - endif - - if( ast_getc( table, 'ColumnUnit(Fred)', status ) .ne. 'pW' ) then - call stopit( status, 'Table error 7b' ) - endif - - call ast_addcolumn( table, 'Dick', AST__OBJECTTYPE, 0, 0, - : 'W/m**2', status ) - call ast_mapput0a( table, 'Dick(1)', table, 'com 1', status ) - if( status .eq. AST__KYCIR ) then - call err_annul( status ) - else if( status .eq. sai__ok ) then - call stopit( status, 'Table error 8' ) - endif - - if( ast_geti( table, 'NColumn', status ) .ne. 2 ) then - call stopit( status, 'Table error 8b' ) - endif - - if( ast_columnname( table, 1, status ) .ne. 'FRED' ) then - call stopit( status, 'Table error 8c' ) - endif - - if( ast_columnname( table, 2, status ) .ne. 'DICK' ) then - call stopit( status, 'Table error 8d' ) - endif - - call ast_removecolumn( table, 'Dick', status ) - - if( ast_geti( table, 'NRow', status ) .ne. 2 ) then - call stopit( status, 'Table error 9' ) - endif - - if( ast_mapget0r( table, 'Fred(3)', rval, status ) ) then - call stopit( status, 'Table error 10' ) - endif - - if( ast_mapget0i( table, 'Fred(2)', ival, status ) ) then - if( ival .ne. 123 ) call stopit( status, 'Table error 11' ) - else - call stopit( status, 'Table error 12' ) - endif - - if( ast_mapget0c( table, 'Fred(2)', cval, l, status ) ) then - if( cval .ne. '123' ) call stopit( status, 'Table error 13' ) - if( l .ne. 3 ) call stopit( status, 'Table error 14' ) - else - call stopit( status, 'Table error 15' ) - endif - - call ast_removerow( table, 3, status ) - if( ast_geti( table, 'NRow', status ) .ne. 2 ) then - call stopit( status, 'Table error 16' ) - endif - - call ast_removerow( table, 2, status ) - if( ast_geti( table, 'NRow', status ) .ne. 1 ) then - call stopit( status, 'Table error 17' ) - endif - - if( ast_mapget0r( table, 'Fred(2)', rval, status ) ) then - call stopit( status, 'Table error 18' ) - endif - - call ast_addparameter( table, 'COLOUR', status ) - if( .not. ast_hasparameter( table, 'COLOUR', status ) ) then - call stopit( status, 'Table error 18_1' ) - endif - - call ast_mapput0C( table, 'COLOUR', 'Red', ' ', status ) - if( ast_mapget0c( table, 'COLOUR', cval, l, status ) ) then - if( cval .ne. 'Red' ) call stopit( status, 'Table error 18_3' ) - if( l .ne. 3 ) call stopit( status, 'Table error 18_4' ) - else - call stopit( status, 'Table error 18_5' ) - endif - - call ast_removeparameter( table, 'COLOUR', status ) - if( ast_hasparameter( table, 'COLOUR', status ) ) then - call stopit( status, 'Table error 18_2' ) - endif - - call checkDump( table, 'checkDump 1 ', status ) - - table2 = ast_copy( table, status ) - - if( ast_mapget0c( table2, 'Fred(1)', cval, l, status ) ) then - if( cval .ne. '-123' ) call stopit( status, 'Table error 19' ) - if( l .ne. 4 ) call stopit( status, 'Table error 20' ) - else - call stopit( status, 'Table error 21' ) - endif - - dims( 1 ) = 2 - dims( 2 ) = 2 - call ast_addcolumn( table, 'Dick', AST__STRINGTYPE, 2, dims, - : ' ', status ) - - text(1,1) = 'One' - text(2,1) = 'two' - text(1,2) = 'three' - text(2,2) = 'FouR' - - call ast_mapput1c( table, 'Dick(4)', 4, text, 'jjjj', status ) - if( ast_mapget1c( table, 'Dick(4)', 4, nval, text, status ) ) then - - if( text(1,1) .ne. 'One' ) - : call stopit( status, 'Table error 22' ) - if( text(2,1) .ne. 'two' ) - : call stopit( status, 'Table error 23' ) - if( text(1,2) .ne. 'three' ) - : call stopit( status, 'Table error 24' ) - if( text(2,2) .ne. 'FouR' ) - : call stopit( status, 'Table error 25' ) - - if( nval .ne. 4 ) call stopit( status, 'Table error 26' ) - else - call stopit( status, 'Table error 27' ) - endif - - call ast_mapputelemc( table, 'Dick(4)', 3, 'OHOHOHOH', status ) - if( ast_mapgetelemc( table, 'Dick(4)', 3, cval, status ) ) then - if( cval .ne. 'OHOHOHOH' ) - : call stopit( status, 'Table error 28' ) - else - call stopit( status, 'Table error 29' ) - endif - - if( ast_geti( table, 'columnlenc(Dick)', status ) .ne. 10 ) then - call stopit( status, 'Table error 29b' ) - endif - - dims( 1 ) = 1 - dims( 2 ) = 2 - call ast_addcolumn( table, 'HeHe', AST__BYTETYPE, 2, dims, - : ' ', status ) - bytes(1,1) = 127 - bytes(1,2) = 255 - call ast_mapput1b( table, 'HeHe(2)', 2, bytes, 'jjjj', status ) - if( ast_mapget1b( table, 'HeHe(2)', 2, nval, bytes, - : status ) ) then - if( nval .ne. 2 ) call stopit( status, 'Table error 30' ) - if( bytes(1,1) .ne. 127 ) call stopit( status, - : 'Table error 31' ) - if( bytes(1,2) .ne. -1 ) call stopit( status, - : 'Table error 32' ) - else - call stopit( status, 'Table error 33' ) - endif - - call ast_addcolumn( table, 'GoGo', AST__BYTETYPE, 0, 0, - : ' ', status ) - call ast_mapput0b( table, 'GoGo(2)', -10, ' ', status ) - if( ast_mapget0b( table, 'GoGo(2)', bval, status ) ) then - if( bval .ne. -10 ) call stopit( status, 'Table error 33' ) - else - call stopit( status, 'Table error 34' ) - endif - - call checkpurge( status ) - - if( .not. ast_hascolumn( table, 'GoGo', status ) ) then - call stopit( status, 'Table error 35' ) - else if( ast_hascolumn( table, 'dodo', status ) ) then - call stopit( status, 'Table error 36' ) - endif - - call ast_removecolumn( table, 'GoGo', status ) - if( ast_hascolumn( table, 'GoGo', status ) ) then - call stopit( status, 'Table error 37' ) - endif - - - - call ast_end( status ) - call err_rlse( status ) - -c call ast_activememory( 'testtable' ) - call ast_flushmemory( 1 ); - - if( status .eq. sai__ok ) then - write(*,*) 'All Table tests passed' - else - write(*,*) 'Table tests failed' - end if - - end - - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - subroutine checkdump( obj, text, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*),key*30,txt1*50,txt2*50 - integer obj, status, next, end, ch, result, ll, overlap, size, - : i, type,obj1,obj2,l1,l2,nl,nrow,nrowold - external mysource, mysink - character buf*400000 - - common /ss1/ buf - common /ss2/ next, end, ll, nl - - if( status .ne. sai__ok ) return - - ch = ast_channel( mysource, mysink, ' ', status ) - - - - nl = 0 - ll = 110 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - - next = 1 - nl = 0 - result = ast_read( ch, status ) - - - - - if( result .eq. ast__null ) then - write(*,*) text - call stopit( status, 'Cannot read object from channel' ) - end if - - if( .not. ast_isatable( result, status ) ) then - call stopit( status, 'Object read from channel is not a table') - end if - - nrowold = ast_geti( obj, 'NRow', status ) - nrow = ast_geti( result, 'NRow', status ) - if( nrow .ne. nrowold ) then - write(*,*) nrow, nrowold - call stopit( status, 'checkDump 0' ) - endif - - size = ast_mapsize( result, status ) - if( ast_mapsize( obj, status ) .ne. size ) then - write(*,*) size, ast_mapsize( obj, status ) - call stopit( status, 'checkDump 1' ) - else - do i = 1, size - key = ast_mapkey( result, i, status ) - type = ast_maptype( result, key, status ) - if( ast_maptype( obj, key, status ) .ne. type ) then - write(*,*) type, ast_maptype( obj, key, status ) - call stopit( status, 'checkDump 4' ) - else - - if( type .eq. AST__OBJECTTYPE ) then - - if( .not. ast_mapGet0A( result, key, obj1, - : status ) ) call stopit( status, 'checkDump 5' ) - if( .not. ast_mapGet0A( obj, key, obj2, - : status ) ) call stopit( status, 'checkDump 6' ) - if( ast_GetC( obj1, 'class', status ) .ne. - : ast_GetC( obj2, 'class', status ) ) then - call stopit( status, 'checkDump 7' ) - end if - - else - - if( .not. ast_mapGet0C( result, key, txt1, l1, - : status ) ) call stopit( status, 'checkDump 8' ) - if( .not. ast_mapGet0C( obj, key, txt2, l2, - : status ) ) call stopit( status, 'checkDump 9' ) - if( txt1( : l1 ) .ne. txt2( : l2 ) .or. - : l1 .ne. l2 ) then - call stopit( status, 'checkDump 10' ) - end if - - end if - end if - end do - end if - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll, nl - character buf*400000 - - common /ss1/ buf - common /ss2/ next, end, ll,nl - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - -c write(*,*) buf( next : next + ll - 1 ) - call ast_putline( buf( next : ), ll, status ) - nl = nl + 1 - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll, nl - character buf*400000 - character line*1000 - - common /ss1/ buf - common /ss2/ next, end, ll, nl - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - - if( next + ll - 1 .ge. 400000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf( next : next + l) - write(*,*) 'Line length ',l - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - nl = nl + 1 - endif - - next = next + ll - - end - - - subroutine checkpurge( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, table, ival - - if( status .ne. sai__ok ) return - - table = ast_table( ' ', status ) - - call ast_addcolumn( table, 'Fred', AST__INTTYPE, 0, 0, ' ', - : status ) - call ast_addcolumn( table, 'Tom', AST__INTTYPE, 0, 0, ' ', - : status ) - - call ast_mapput0i( table, 'Fred(2)', 123, ' ', status ) - call ast_mapput0i( table, 'Fred(4)', 456, ' ', status ) - call ast_mapput0i( table, 'Tom(1)', -123, ' ', status ) - call ast_mapput0i( table, 'Tom(2)', -456, ' ', status ) - call ast_mapput0i( table, 'Tom(6)', 0, ' ', status ) - - if( ast_geti( table, 'NRow', status ) .ne. 6 ) then - call stopit( status, 'Table error purge-1' ) - endif - - call ast_mapremove( table, 'Tom(6)', status ) - if( ast_geti( table, 'NRow', status ) .ne. 6 ) then - call stopit( status, 'Table error purge-2' ) - endif - - call ast_purgerows( table, status ) - if( ast_geti( table, 'NRow', status ) .ne. 3 ) then - write(*,*) 'ZZ: ',ast_geti( table, 'NRow', status ) - call stopit( status, 'Table error purge-3' ) - endif - - if( ast_mapget0i( table, 'Tom(1)', ival, status ) ) then - if( ival .ne. -123 ) call stopit( status, - : 'Table error purge-4' ) - else - call stopit( status, 'Table error purge-5' ) - endif - - if( ast_mapget0i( table, 'Tom(2)', ival, status ) ) then - if( ival .ne. -456 ) call stopit( status, - : 'Table error purge-6' ) - else - call stopit( status, 'Table error purge-7' ) - endif - - if( ast_mapget0i( table, 'Fred(1)', ival, status ) ) then - call stopit( status, 'Table error purge-8' ) - endif - - if( ast_mapget0i( table, 'Fred(2)', ival, status ) ) then - if( ival .ne. 123 ) call stopit( status, - : 'Table error purge-9' ) - else - call stopit( status, 'Table error purge-10' ) - endif - - if( ast_mapget0i( table, 'Fred(3)', ival, status ) ) then - if( ival .ne. 456 ) call stopit( status, - : 'Table error purge-11' ) - else - call stopit( status, 'Table error purge-12' ) - endif - - call ast_annul( table, status ) - - end - diff --git a/ast/ast_tester/testtime.f b/ast/ast_tester/testtime.f deleted file mode 100644 index 39c4b9a..0000000 --- a/ast/ast_tester/testtime.f +++ /dev/null @@ -1,979 +0,0 @@ - program testtime - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'AST_ERR' - - character txt*40 - double precision xin, xout, xout2, ct, ctl, origin - integer status, tf, tf1, tf2, fs, n, chr_len, nc - status = sai__ok - - call ast_begin( status ) - -c call ast_SetWatchId( 740050 ) - -c -c Test default attribute values -c - tf = ast_timeframe( ' ', status ) - - if( ast_getc( tf, 'System', status ) .ne. 'MJD' ) then - write(*,*) ast_getc( tf, 'System', status ) - call stopit( status, 'error 1' ) - endif - - if( ast_getd( tf, 'TimeOrigin', status ) .ne. 0.0 ) then - write(*,*) ast_getd( tf, 'TimeOrigin', status ) - call stopit( status, 'error 2' ) - endif - - if( ast_getc( tf, 'ObsLon', status ) .ne. 'E0:00:00.00' ) then - write(*,*) ast_getc( tf, 'ObsLon', status ) - call stopit( status, 'error 3' ) - endif - - if( ast_getc( tf, 'ObsLat', status ) .ne. 'N0:00:00.00' ) then - write(*,*) ast_getc( tf, 'ObsLat', status ) - call stopit( status, 'error 4' ) - endif - - if( ast_getc( tf, 'TimeScale', status ) .ne. 'TAI' ) then - write(*,*) ast_getc( tf, 'TimeScale', status ) - call stopit( status, 'error 5' ) - endif - - if( ast_getc( tf, 'AlignTimeScale', status ) .ne. 'TAI' ) then - write(*,*) ast_getc( tf, 'AlignTimeScale', status ) - call stopit( status, 'error 6' ) - endif - - if( ast_geti( tf, 'naxes', status ) .ne. 1 ) then - write(*,*) ast_getc( tf, 'Naxes', status ) - call stopit( status, 'error 7' ) - endif - - if( ast_getd( tf, 'Epoch', status ) .ne. 2000.0 ) then - write(*,*) ast_getd( tf, 'Epoch', status ) - call stopit( status, 'error 8' ) - endif - - if( ast_getc( tf, 'Label', status ) .ne. - : 'Modified Julian Date' ) then - write(*,*) ast_getc( tf, 'Label', status ) - call stopit( status, 'error 9' ) - endif - - if( ast_getc( tf, 'Symbol', status ) .ne. 'MJD' ) then - write(*,*) ast_getc( tf, 'Symbol', status ) - call stopit( status, 'error 10' ) - endif - - if( ast_getc( tf, 'Title', status ) .ne. - : 'Modified Julian Date' ) then - write(*,*) ast_getc( tf, 'Title', status ) - call stopit( status, 'error 11' ) - endif - - if( ast_getc( tf, 'unit', status ) .ne. 'd' ) then - write(*,*) ast_getc( tf, 'unit', status ) - call stopit( status, 'error 12' ) - endif - - if( ast_getc( tf, ' domain ', status ) .ne. 'TIME' ) then - write(*,*) ast_getc( tf, ' domain ', status ) - call stopit( status, 'error 13' ) - endif - - if( ast_getc( tf, 'alignSystem', status ) .ne. 'MJD' ) then - write(*,*) ast_getc( tf, 'alignSystem', status ) - call stopit( status, 'error 14' ) - endif - -c -c Test dependency of default attribute values on System -c - call ast_setc( tf, 'system', 'jd', status ) - - if( ast_getc( tf, 'System', status ) .ne. 'JD' ) then - write(*,*) ast_getc( tf, 'System', status ) - call stopit( status, 'error 1b' ) - endif - - if( ast_getd( tf, 'TimeOrigin', status ) .ne. 0.0 ) then - write(*,*) ast_getd( tf, 'TimeOrigin', status ) - call stopit( status, 'error 2b' ) - endif - - if( ast_getc( tf, 'ObsLon', status ) .ne. 'E0:00:00.00' ) then - write(*,*) ast_getc( tf, 'ObsLon', status ) - call stopit( status, 'error 3b' ) - endif - - if( ast_getc( tf, 'ObsLat', status ) .ne. 'N0:00:00.00' ) then - write(*,*) ast_getc( tf, 'ObsLat', status ) - call stopit( status, 'error 4b' ) - endif - - if( ast_getc( tf, 'TimeScale', status ) .ne. 'TAI' ) then - write(*,*) ast_getc( tf, 'TimeScale', status ) - call stopit( status, 'error 5b' ) - endif - - if( ast_getc( tf, 'AlignTimeScale', status ) .ne. 'TAI' ) then - write(*,*) ast_getc( tf, 'AlignTimeScale', status ) - call stopit( status, 'error 6b' ) - endif - - if( ast_geti( tf, 'naxes', status ) .ne. 1 ) then - write(*,*) ast_getc( tf, 'Naxes', status ) - call stopit( status, 'error 7b' ) - endif - - if( ast_getd( tf, 'Epoch', status ) .ne. 2000.0 ) then - write(*,*) ast_getd( tf, 'Epoch', status ) - call stopit( status, 'error 8b' ) - endif - - if( ast_getc( tf, 'Label', status ) .ne. - : 'Julian Date' ) then - write(*,*) ast_getc( tf, 'Label', status ) - call stopit( status, 'error 9b' ) - endif - - if( ast_getc( tf, 'Symbol', status ) .ne. 'JD' ) then - write(*,*) ast_getc( tf, 'Symbol', status ) - call stopit( status, 'error 10b' ) - endif - - if( ast_getc( tf, 'Title', status ) .ne. - : 'Julian Date' ) then - write(*,*) ast_getc( tf, 'Title', status ) - call stopit( status, 'error 11b' ) - endif - - if( ast_getc( tf, 'unit', status ) .ne. 'd' ) then - write(*,*) ast_getc( tf, 'unit', status ) - call stopit( status, 'error 12b' ) - endif - - if( ast_getc( tf, ' domain ', status ) .ne. 'TIME' ) then - write(*,*) ast_getc( tf, ' domain ', status ) - call stopit( status, 'error 13b' ) - endif - - if( ast_getc( tf, 'alignSystem', status ) .ne. 'MJD' ) then - write(*,*) ast_getc( tf, 'alignSystem', status ) - call stopit( status, 'error 14b' ) - endif - - - - call ast_setc( tf, 'system', 'jepoch', status ) - - if( ast_getc( tf, 'System', status ) .ne. 'JEPOCH' ) then - write(*,*) ast_getc( tf, 'System', status ) - call stopit( status, 'error 1c' ) - endif - - if( ast_getd( tf, 'TimeOrigin', status ) .ne. 0.0 ) then - write(*,*) ast_getd( tf, 'TimeOrigin', status ) - call stopit( status, 'error 2c' ) - endif - - if( ast_getc( tf, 'ObsLon', status ) .ne. 'E0:00:00.00' ) then - write(*,*) ast_getc( tf, 'ObsLon', status ) - call stopit( status, 'error 3c' ) - endif - - if( ast_getc( tf, 'ObsLat', status ) .ne. 'N0:00:00.00' ) then - write(*,*) ast_getc( tf, 'ObsLat', status ) - call stopit( status, 'error 4c' ) - endif - - if( ast_getc( tf, 'TimeScale', status ) .ne. 'TAI' ) then - write(*,*) ast_getc( tf, 'TimeScale', status ) - call stopit( status, 'error 5c' ) - endif - - if( ast_getc( tf, 'AlignTimeScale', status ) .ne. 'TAI' ) then - write(*,*) ast_getc( tf, 'AlignTimeScale', status ) - call stopit( status, 'error 6c' ) - endif - - if( ast_geti( tf, 'naxes', status ) .ne. 1 ) then - write(*,*) ast_getc( tf, 'Naxes', status ) - call stopit( status, 'error 7c' ) - endif - - if( ast_getd( tf, 'Epoch', status ) .ne. 2000.0 ) then - write(*,*) ast_getd( tf, 'Epoch', status ) - call stopit( status, 'error 8c' ) - endif - - if( ast_getc( tf, 'Label', status ) .ne. - : 'Julian Epoch' ) then - write(*,*) ast_getc( tf, 'Label', status ) - call stopit( status, 'error 9c' ) - endif - - if( ast_getc( tf, 'Symbol', status ) .ne. 'JEP' ) then - write(*,*) ast_getc( tf, 'Symbol', status ) - call stopit( status, 'error 10c' ) - endif - - if( ast_getc( tf, 'Title', status ) .ne. - : 'Julian Epoch' ) then - write(*,*) ast_getc( tf, 'Title', status ) - call stopit( status, 'error 11c' ) - endif - - if( ast_getc( tf, 'unit', status ) .ne. 'yr' ) then - write(*,*) ast_getc( tf, 'unit', status ) - call stopit( status, 'error 12c' ) - endif - - if( ast_getc( tf, ' domain ', status ) .ne. 'TIME' ) then - write(*,*) ast_getc( tf, ' domain ', status ) - call stopit( status, 'error 13c' ) - endif - - if( ast_getc( tf, 'alignSystem', status ) .ne. 'MJD' ) then - write(*,*) ast_getc( tf, 'alignSystem', status ) - call stopit( status, 'error 14c' ) - endif - - - call ast_setc( tf, 'system', 'bepoch', status ) - - if( ast_getc( tf, 'System', status ) .ne. 'BEPOCH' ) then - write(*,*) ast_getc( tf, 'System', status ) - call stopit( status, 'error 1d' ) - endif - - if( ast_getd( tf, 'TimeOrigin', status ) .ne. 0.0 ) then - write(*,*) ast_getd( tf, 'TimeOrigin', status ) - call stopit( status, 'error 2d' ) - endif - - if( ast_getc( tf, 'ObsLon', status ) .ne. 'E0:00:00.00' ) then - write(*,*) ast_getc( tf, 'ObsLon', status ) - call stopit( status, 'error 3d' ) - endif - - if( ast_getc( tf, 'ObsLat', status ) .ne. 'N0:00:00.00' ) then - write(*,*) ast_getc( tf, 'ObsLat', status ) - call stopit( status, 'error 4d' ) - endif - - if( ast_getc( tf, 'TimeScale', status ) .ne. 'TT' ) then - write(*,*) ast_getc( tf, 'TimeScale', status ) - call stopit( status, 'error 5d' ) - endif - - if( ast_getc( tf, 'AlignTimeScale', status ) .ne. 'TAI' ) then - write(*,*) ast_getc( tf, 'AlignTimeScale', status ) - call stopit( status, 'error 6d' ) - endif - - if( ast_geti( tf, 'naxes', status ) .ne. 1 ) then - write(*,*) ast_getc( tf, 'Naxes', status ) - call stopit( status, 'error 7d' ) - endif - - if( ast_getd( tf, 'Epoch', status ) .ne. 2000.0 ) then - write(*,*) ast_getd( tf, 'Epoch', status ) - call stopit( status, 'error 8d' ) - endif - - if( ast_getc( tf, 'Label', status ) .ne. - : 'Besselian Epoch' ) then - write(*,*) ast_getc( tf, 'Label', status ) - call stopit( status, 'error 9d' ) - endif - - if( ast_getc( tf, 'Symbol', status ) .ne. 'BEP' ) then - write(*,*) ast_getc( tf, 'Symbol', status ) - call stopit( status, 'error 10d' ) - endif - - if( ast_getc( tf, 'Title', status ) .ne. - : 'Besselian Epoch' ) then - write(*,*) ast_getc( tf, 'Title', status ) - call stopit( status, 'error 11d' ) - endif - - if( ast_getc( tf, 'unit', status ) .ne. 'yr' ) then - write(*,*) ast_getc( tf, 'unit', status ) - call stopit( status, 'error 12d' ) - endif - - if( ast_getc( tf, ' domain ', status ) .ne. 'TIME' ) then - write(*,*) ast_getc( tf, ' domain ', status ) - call stopit( status, 'error 13d' ) - endif - - if( ast_getc( tf, 'alignSystem', status ) .ne. 'MJD' ) then - write(*,*) ast_getc( tf, 'alignSystem', status ) - call stopit( status, 'error 14d' ) - endif - -c -c Test dump and load -c - call checkDump( tf, 'CheckDump 1', status ) - -c -c Test CurrentTime method. -c - call ast_set( tf, 'system=jepoch,unit=yr,timescale=utc,'// - : 'timeorigin=0', status ) - n = 0 - - write(*,*) ' Testing astCurrentTime: approx 1 second pause '// - : 'following...' - ctl = ast_currenttime( tf, status ) + 1.0D0/(86400.0D0*365.25D0) - do while( ast_currenttime( tf, status ) .lt. ctl ) - n = n + 1 - if( n .gt. 2000000 ) then - call stopit( status, 'error 15' ) - return - end if - end do - write(*,*) ' 1 second pause finished.' - - -c -c Test behaviour of TimeOrigin attribute -c - tf = ast_timeframe( 'timescale=utc', status ) - origin = ast_currenttime( tf, status ) - call ast_setd( tf, 'TimeOrigin', origin, status ) - write(*,*) ' Testing TimeOrigin: approx 1 second pause '// - : 'following...' - n = 0 - do while( ast_currenttime( tf, status ) .lt. - : 1.0D0/(86400.0D0*364.25D0) ) - n = n + 1 - if( n .gt. 2000000 ) then - call stopit( status, 'error 16' ) - return - end if - end do - write(*,*) ' 1 second pause finished.' - - call ast_set( tf, 'unit=s', status ) - if( abs( ast_getd( tf, 'TimeOrigin', status ) - - : origin*86400.0D0 ) .gt. 0.01 ) then - write(*,*) abs( ast_getd( tf, 'TimeOrigin', status ) - - : origin*86400.0D0 ) - call stopit( status, 'error 17' ) - end if - - -c -c Test conversions between basic systems with arbitrary offsets -c - tf1 = ast_timeframe( 'system=mjd,timeorigin=53000', status ) - tf2 = ast_timeframe( 'system=jd,timeorigin=2453000.5', status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 18' ) - else if( .not. ast_isaunitmap( ast_getMapping( fs, AST__BASE, - : AST__CURRENT, - : status ), status ) ) then - call stopit( status, 'error 19' ) - end if - - - - tf1 = ast_timeframe( 'system=mjd,timescale=UTC,timeorigin=53000', - : status ) - tf2 = ast_timeframe( 'system=bepoch,timeorigin=2004', status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 20' ) - else - xin = 100.0D0 - call ast_tran1( fs, 1, xin, .true., xout, status ) - if( abs( xout - 0.2600974092354136D0 ) .gt. 1.0D-10 ) then - call stopit( status, 'error 21' ) - end if - call ast_tran1( fs, 1, xout, .false., xin, status ) - if( abs( xin - 100.0D0 ) .gt. 1.0D-6 ) then - call stopit( status, 'error 21b' ) - end if - end if - - - tf1 = ast_timeframe( 'system=bepoch,timeorigin=0', status ) - if( status .eq.sai__OK ) then - call err_mark - call ast_set( tf1, 'TimeScale=TAI', status ) - if( status .eq. AST__ATTIN ) then - call err_annul( status ) - else - call stopit( status, 'error 21b' ); - endif - - call ast_set( tf1, 'Unit=s', status ) - if( status .eq. AST__ATTIN ) then - call err_annul( status ) - else - call stopit( status, 'error 21c' ); - endif - call err_rlse - endif - - tf2 = ast_timeframe( 'system=jepoch,timescale=tai,'// - : 'timeorigin=100.0', status ) - call ast_set( tf2, 'unit=d', status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 22' ) - else - xin = 100.0D0 - call ast_tran1( fs, 1, xin, .true., xout, status ) - if( abs( xout - 14.35534169996282 ) .gt. 1.0D-6 ) then - call stopit( status, 'error 23' ) - end if - call ast_tran1( fs, 1, xout, .false., xin, status ) - if( abs( xin - 100.0D0 ) .gt. 1.0D-6 ) then - call stopit( status, 'error 23b' ) - end if - end if - -c Besselian epoch offset from B2000 [TT, yr] - call ast_set( tf1, 'timeorigin=2000', status ) - -c Julian date offset from 2450000.5 days [TDB, h] - call ast_set( tf2, 'system=JD,timescale=TDB,unit=h,'// - : 'timeorigin=2450000.5 d', status ) - - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 24' ) - else - xin = 0.1 - call ast_tran1( fs, 1, xin, .true., xout, status ) - if( abs( xout - 37933.38284478387D0) .gt. 1.0D-5 ) then - call stopit( status, 'error 25' ) - end if - call ast_tran1( fs, 1, xout, .false., xin, status ) - if( abs( xin - 0.1 ) .gt. 1.0D-10 ) then - call stopit( status, 'error 25b' ) - end if - end if - - -c -c Test Formatting and unformatting -c - tf1 = ast_timeframe( 'system=jepoch,timeorigin=2005.0', status ) - - txt = ast_format( tf1, 1, 100.0D0, status ) - if( txt .ne. '100' ) then - write(*,*) ast_format( tf1, 1, 100.0D0, status ) - call stopit( status, 'error 26' ) - end if - nc = ast_unformat( tf1, 1, txt, xout, status ) - if( nc .ne. len( txt ) .or. xout .ne. 100.0D0 ) then - write(*,*) nc, xout - call stopit( status, 'error 26b' ) - end if - - - - call ast_set( tf1, 'format=iso', status ) - txt = ast_format( tf1, 1, 1.0D0, status ) - if( txt .ne. '2006-01-01' ) then - write(*,*) ast_format( tf1, 1, 1.0D0, status ) - call stopit( status, 'error 27' ) - end if - - nc = ast_unformat( tf1, 1, txt, xout, status ) - if( nc .ne. len( txt ) .or. xout .ne. 1.0D0 ) then - write(*,*) nc, xout - call stopit( status, 'error 27b' ) - end if - - - - call ast_set( tf1, 'format=iso.0', status ) - txt = ast_format( tf1, 1, 1.0D0, status ) - if( txt .ne. '2006-01-01 00:00:00' ) then - write(*,*) ast_format( tf1, 1, 1.0D0, status ) - call stopit( status, 'error 28' ) - end if - - nc = ast_unformat( tf1, 1, txt, xout, status ) - if( nc .ne. len( txt ) .or. xout .ne. 1.0D0 ) then - write(*,*) nc, xout - call stopit( status, 'error 28b' ) - end if - - - - call ast_set( tf1, 'unit=s,format=iso.2', status ) - txt = ast_format( tf1, 1, 10.0D0, status ) - if( txt .ne. '2004-12-31 18:00:10.00' ) then - write(*,*) ast_format( tf1, 1, 10.0D0, status ) - call stopit( status, 'error 29' ) - end if - - nc = ast_unformat( tf1, 1, txt, xout, status ) - if( nc .ne. len( txt ) .or. - : abs( xout - 10.0D0 ) .gt. 1.0E-3 ) then - write(*,*) nc, xout - call stopit( status, 'error 29b' ) - end if - - - - txt = ast_format( tf1, 1, 10.12D0, status ) - if( txt .ne. '2004-12-31 18:00:10.12' ) then - write(*,*) ast_format( tf1, 1, 10.12D0, status ) - call stopit( status, 'error 30' ) - end if - - nc = ast_unformat( tf1, 1, txt, xout, status ) - if( nc .ne. len( txt ) .or. - : abs( xout - 10.12D0 ) .gt. 1.0E-3 ) then - write(*,*) nc, xout - call stopit( status, 'error 30b' ) - end if - - - call ast_set( tf1, 'timescale=utc', status ) - xin = ast_currenttime( tf1, status ) - txt = ast_format( tf1, 1, xin, status ) - write(*,*) ' Current system time (UTC): ', - : txt( : chr_len( txt ) ) - nc = ast_unformat( tf1, 1, txt(:20), xout, status ) - if( nc .ne. 20 .or. abs( xout - xin ) .gt. 1.0E-3 ) then - write(*,*) nc, xout - call stopit( status, 'error 30c' ) - end if - - tf1 = ast_timeframe( 'system=jepoch,timeorigin=2005.0', status ) - nc = ast_unformat( tf1, 1, 'J2005.0', xout, status ) - if( nc .ne. 7 .or. xout .ne. 0.0D0 ) then - write(*,*) nc, xout - call stopit( status, 'error 31' ) - end if - - nc = ast_unformat( tf1, 1, 'J2010.0', xout, status ) - if( nc .ne. 7 .or. xout .ne. 5.0D0 ) then - write(*,*) nc, xout - call stopit( status, 'error 32' ) - end if - - nc = ast_unformat( tf1, 1, '2005-jun-1 12:30 lunch time', xout, - : status ) - if( nc .ne. 17 .or. abs( xout - 0.415525896D0 ) .gt. 1.0E-7 ) then - write(*,*) nc, xout - call stopit( status, 'error 33' ) - end if - - call ast_set( tf1, 'timescale=utc', status ) - nc = ast_unformat( tf1, 1, 'B2001.5 lunch time', xout, - : status ) - if( nc .ne. 8 .or. - : abs( xout + 3.50131054408916D0 ) .gt. 1.0E-10 ) then - write(*,*) nc, xout, abs( xout + 3.50131054408916D0 ) - call stopit( status, 'error 34' ) - end if - - - - - - - tf1 = ast_timeframe( 'system=mjd,timescale=tai', status ) - nc = ast_unformat( tf1, 1, "1977-01-01 00:00:00", xin, status ) - - - tf2 = ast_timeframe( 'system=mjd,timescale=tai,format=iso.6', - : status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 35' ) - else - call ast_tran1( fs, 1, xin, .true., xout, status ) - txt = ast_format( tf2, 1, xout, status ) - if( txt .ne. '1977-01-01 00:00:00.000000' ) then - write(*,*) txt( :chr_len(txt) ) - call stopit( status, 'error 36' ) - end if - end if - - tf2 = ast_timeframe( 'system=mjd,timescale=utc,format=iso.6', - : status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 37' ) - else - call ast_tran1( fs, 1, xin, .true., xout, status ) - txt = ast_format( tf2, 1, xout, status ) - if( txt .ne. '1976-12-31 23:59:45.000000' ) then - write(*,*) txt( :chr_len(txt) ) - call stopit( status, 'error 38' ) - end if - end if - - tf2 = ast_timeframe( 'system=mjd,timescale=tt,format=iso.6', - : status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 39' ) - else - call ast_tran1( fs, 1, xin, .true., xout, status ) - txt = ast_format( tf2, 1, xout, status ) - if( txt .ne. '1977-01-01 00:00:32.184000' ) then - write(*,*) txt( :chr_len(txt) ) - call stopit( status, 'error 40' ) - end if - end if - - tf2 = ast_timeframe( 'system=mjd,timescale=tdb,format=iso.6', - : status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 41' ) - else - call ast_tran1( fs, 1, xin, .true., xout, status ) - txt = ast_format( tf2, 1, xout, status ) - if( txt .ne. '1977-01-01 00:00:32.183935' ) then - write(*,*) txt( :chr_len(txt) ) - call stopit( status, 'error 42' ) - end if - end if - - tf2 = ast_timeframe( 'system=mjd,timescale=tcb,format=iso.6', - : status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 43' ) - else - call ast_tran1( fs, 1, xin, .true., xout, status ) - txt = ast_format( tf2, 1, xout, status ) - if( txt .ne. '1977-01-01 00:00:32.184000' ) then - write(*,*) txt( :chr_len(txt) ) - call stopit( status, 'error 44' ) - end if - end if - - tf2 = ast_timeframe( 'system=mjd,timescale=tcg,format=iso.6', - : status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 45' ) - else - call ast_tran1( fs, 1, xin, .true., xout, status ) - txt = ast_format( tf2, 1, xout, status ) - if( txt .ne. '1977-01-01 00:00:32.184000' ) then - write(*,*) txt( :chr_len(txt) ) - call stopit( status, 'error 46' ) - end if - end if - - - - - tf1 = ast_timeframe( 'system=mjd,timescale=gmst,ObsLon=90,'// - : 'ObsLat=0,timeorigin=53000.0', status ) - tf2 = ast_timeframe( 'system=mjd,timescale=lmst,ObsLon=90,'// - : 'ObsLat=0,timeorigin=53000.0', status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 47' ) - else - xin = 1.0D0 - call ast_tran1( fs, 1, xin, .true., xout, status ) - if( xout .ne. 1.25D0 ) then - write(*,*) xout - call stopit( status, 'error 48' ) - end if - call ast_tran1( fs, 1, xout, .false., xin, status ) - if( xin .ne. 1.0D0 ) then - write(*,*) xin - call stopit( status, 'error 48b' ) - end if - end if - - -* Test use of DUT1 - tf1 = ast_timeframe( 'system=mjd,timescale=tdb,dut1=0.1', status ) - tf2 = ast_timeframe( 'system=mjd,timescale=last,dut1=0.1', - : status ) - fs = ast_convert( tf1, tf2, ' ', status ) - if( fs .eq. AST__NULL ) then - call stopit( status, 'error 49' ) - else - xin = 53991.675D0 - call ast_tran1( fs, 1, xin, .true., xout, status ) - if( abs(xout - 53998.65344633732D0) .gt. 1.0D-8 ) then - write(*,*) xout - call stopit( status, 'error 50' ) - end if - call ast_tran1( fs, 1, xout, .false., xin, status ) - if( abs( xin - 53991.675D0 ) .gt. 1.0D-8 ) then - write(*,*) xin - call stopit( status, 'error 51' ) - end if - end if - - -* Test use of DTAI - tf1 = ast_timeframe( 'system=mjd,timescale=tai', status ) - tf2 = ast_timeframe( 'system=mjd,timescale=utc', status ) - - fs = ast_convert( tf1, tf2, ' ', status ) - - xin = 57844.0D0 - - if (fs .eq. AST__NULL ) then - call stopit( status, 'error 52' ) - else - call ast_tran1( fs, 1, xin, .true., xout, status) - if (abs(((xin - xout) * 86400.0D0) - 37.0D0) .gt. 1.0D-3) then - write(*,*) xout - call stopit( status, 'error 53' ) - endif - call checkdump( fs, 'CheckDump 2', status ) - end if - - call ast_setd( tf2, 'dtai', 40.0D0, status ) - - fs = ast_convert( tf1, tf2, ' ', status ) - - if (fs .eq. AST__NULL ) then - call stopit( status, 'error 54' ) - else - call ast_tran1( fs, 1, xin, .true., xout, status) - if (abs(((xin - xout) * 86400.0D0) - 40.0D0) .gt. 1.0D-3) then - write(*,*) xout - call stopit( status, 'error 55' ) - endif - call checkdump( fs, 'CheckDump 3', status ) - end if - - - - tf1 = ast_timeframe( 'system=mjd,timescale=tt', status ) - tf2 = ast_timeframe( 'system=mjd,timescale=tdb,dtai=37.0', - : status ) - - fs = ast_convert( tf1, tf2, ' ', status ) - - if (fs .eq. AST__NULL ) then - call stopit( status, 'error 56' ) - else - call ast_tran1( fs, 1, xin, .true., xout, status) - call checkdump( fs, 'CheckDump 4', status ) - end if - - call ast_clear( tf2, 'dtai', status ) - - fs = ast_convert( tf1, tf2, ' ', status ) - - if (fs .eq. AST__NULL ) then - call stopit( status, 'error 57' ) - else - call ast_tran1( fs, 1, xin, .true., xout2, status) - if( xout .ne. xout2 ) then - call stopit( status, 'error 58' ) - end if - end if - - - - - - - call ast_end( status ) -c call ast_listissued( 'testtime' ) - - - - if( status .eq. sai__ok ) then - write(*,*) 'All timeFrame tests passed' - else - write(*,*) 'timeFrame tests failed' - end if - - end - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - - end - - - subroutine checkdump( obj, text, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - character text*(*) - integer obj, status, next, end, ch, result, ll, overlap, map, - : map1, map2 - external mysource, mysink - character buf*25000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - ch = ast_channel( mysource, mysink, ' ', status ) - - - ll = 110 - next = 1 - if( ast_write( ch, obj, status ) .ne.1 ) then - write(*,*) text - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - - next = 1 - result = ast_read( ch, status ) - if( result .eq. ast__null ) then - write(*,*) text - call stopit( status, 'Cannot read object from channel' ) - end if - - - if( ast_isatimeframe( obj, status ) ) then - if( ast_getd( obj, 'timeorigin', status ) .ne. - : ast_getd( result, 'timeorigin', status ) .or. - : ast_getc( obj, 'timescale', status ) .ne. - : ast_getc( result, 'timescale', status ) .or. - : ast_getc( obj, 'ObsLon', status ) .ne. - : ast_getc( result, 'ObsLon', status ) .or. - : ast_getc( obj, 'ObsLat', status ) .ne. - : ast_getc( result, 'ObsLat', status ) .or. - : ast_getc( obj, 'Dtai', status ) .ne. - : ast_getc( result, 'Dtai', status ) ) then - call ast_Show( obj, status ) - call ast_Show( result, status ) - write(*,*) text - call stopit( status, 'Object has changed' ) - end if - else if( ast_isamapping( obj, status ) ) then - if( ast_isaframeset( obj, status ) ) then - map1 = ast_getmapping( obj, ast__base, ast__current, - : status ) - map2 = ast_getmapping( result, ast__base, ast__current, - : status ) - else - map1 = ast_clone( obj, status ) - map2 = ast_clone( result, status ) - end if - - call ast_invert( map2, status ) - map = ast_simplify( ast_cmpmap( map1, map2, .true., ' ', - : status ), - : status ) - if( .not. ast_isaunitmap( map, status ) ) then - write(*,*) text - call ast_show( map1, status ) - call ast_invert( map2, status ) - call ast_show( map2, status ) - - call stopit( status, 'Mapping has changed' ) - endif - end if - - end - - subroutine sink1( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - logical fsfound, done - common /sink1com/ fsfound, done - - integer status, l - character line*200 - - if( status .ne. sai__ok ) return - call ast_getline( line, l, status ) - - if( index( line( : l ),'Unc =' ) .GT. 0 ) then - done = .true. - - else if( .not. done .and. - : index( line( : l ),'FrameSet' ) .GT. 0 ) then - fsfound= .true. - end if - - end - - subroutine mysource( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, ll - character buf*25000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - if( next .ge. end ) then - call ast_putline( buf, -1, status ) - else - call ast_putline( buf( next : ), ll, status ) - endif - - next = next + ll - - end - - subroutine mysink( status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer status, next, end, f, l, ll - character buf*25000 - character line*1000 - - common /ss1/ buf - common /ss2/ next, end, ll - - if( status .ne. sai__ok ) return - - line = ' ' - call ast_getline( line, l, status ) - call chr_fandl( line( : l ), f, l ) - buf( next : ) = line( f : l ) - l = l - f + 1 - - if( next + ll - 1 .ge. 25000 ) then - write(*,*) - call stopit( status, 'Buffer overflow in mysink!!' ) - else if( l .gt. ll ) then - write(*,*) - write(*,*) buf( next : next + l) - write(*,*) 'Line length ',l - call stopit( status, 'Line overflow in mysink!!' ) - else - end = next + l - buf( end : next + ll - 1 ) = ' ' - endif - - next = next + ll - - end - - diff --git a/ast/ast_tester/testtrangrid.f b/ast/ast_tester/testtrangrid.f deleted file mode 100644 index b867291..0000000 --- a/ast/ast_tester/testtrangrid.f +++ /dev/null @@ -1,276 +0,0 @@ - program testtrangrid - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'PRM_PAR' - - integer status, i, m, outp(4), inp(4), c1, c2, c3, c4, fc, fs - double precision at(4), r, mat(4), b1(2), b2(2), a1(2), - : a2(4) - character cards(9)*80 - - status = sai__ok - - at(1) = 10.0D0 - at(2) = 1.2D6 - -* UnitMap - m = ast_unitmap( 2, ' ', status ) - call testmap( m, 1, 0.5D0, status ) - -* ZoomMap - m = ast_zoommap( 2, 2.0D0, ' ', status ) - call testmap( m, 2, 0.5D0, status ) - -* MatrixMap - m = ast_matrixmap( 2, 2, 2, mat, ' ', status ) - call testmap( m, 3, 0.5D0, status ) - -* PermMap - outp(1)=2 - outp(2)=1 - inp(1)=2 - inp(2)=1 - m = ast_permmap( 2, inp, 2, outp, 0.0D0, ' ', status ) - call testmap( m, 4, 0.5D0, status ) - -* TranMap - a1( 1 ) = 0.0D0 - a1( 2 ) = 0.0D0 - a2( 1 ) = 1.0D0 - a2( 2 ) = 1.0D0 - b1( 1 ) = 0.5D0 - b1( 2 ) = 0.5D0 - b2( 1 ) = 2.5D0 - b2( 2 ) = 2.5D0 - c1 = ast_winmap( 2, a1, a2, b1, b2, ' ', status ) - c2 = ast_copy( c1, status ) - - m = ast_tranmap( c1, c2, ' ', status ) - call testmap( m, 5, 0.5D0, status ) - -* 3D CmpMap - mat(1) = -1.0D0 - c1 = ast_shiftmap( 1, mat, ' ', status ) - mat(1)= 1.0D0 - mat(2)= 2.0D0 - mat(3)= -2.0D0 - mat(4)= 3.0D0 - c2 = ast_matrixmap( 2, 2, 0, mat, ' ', status ) - c3 = ast_cmpmap( c1, c2, 0, ' ', status ) - - outp(1) = 3 - outp(2) = 2 - outp(3) = 1 - inp(1) = 3 - inp(2) = 2 - inp(3) = 1 - c1 = ast_permmap( 3, inp, 3, outp, 0.0D0, ' ', status ) - c2 = ast_ZoomMap( 3, 0.25D0, ' ', status ) - call ast_invert( c2, status ) - - c4 = ast_cmpmap( c1, c2, 1, ' ', status ) - call ast_invert( c4, status ) - - m = ast_cmpmap( c3, c4, 1, ' ', status ) - call testmap( m, 6, 0.5D0, status ) - - - -* 1D non-linear Mapping - m = ast_mathmap( 1, 1, 1, 'y=x**3', 1, - : 'x=sign((abs(y)**(1/3)),y)', ' ', status ) - call testmap( m, 7, 0.0001D0, status ) - - - -* A FITS-WCS pixel->sky mapping - cards(1) = 'CTYPE1 = ''RA---TAN''' - cards(2) = 'CTYPE2 = ''DEC--TAN''' - cards(3) = 'CRPIX1 = 20' - cards(4) = 'CRPIX2 = 20' - cards(5) = 'CRVAL1 = 0.0' - cards(6) = 'CRVAL2 = 0.0' - cards(7) = 'CROTA1 = 30.0' - cards(8) = 'CDELT1 = -0.001' - cards(9) = 'CDELT2 = 0.001' - - fc = ast_fitschan( ast_null, ast_null, ' ', status ) - do i = 1, 9 - call ast_putfits( fc, cards(i), .false., status ) - end do - call ast_clear( fc, 'card', status ) - fs = ast_read( fc, status ) - - call testmap( fs, 8, 0.0001D0, status ) - - - - - - - - - - if( status .eq. sai__ok ) then - write(*,*) 'All AST_TRANGRID tests passed' - else - write(*,*) 'AST_TRANGRID tests failed' - end if - - end - - - - - - subroutine testmap( map, itest, tol, status ) - implicit none - include 'SAE_PAR' - - integer status, maxpix, itest, map - double precision tol - - if( status .ne. sai__ok ) return - - maxpix = 100 - call testgridpair( map, tol, maxpix, itest*10, status ) - call testgridpair( map, 0.0D0, maxpix, itest*10+2, status ) - - maxpix = 4 - call testgridpair( map, tol, maxpix, itest*10+4, status ) - call testgridpair( map, 0.0D0, maxpix, itest*10+6, status ) - - end - - - - - subroutine testgridpair( map, tol, maxpix, itest, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - integer status, lbnd( 3 ), ubnd( 3 ), nin, nout, i, outdim, - : maxpix, itest, size, pos(3), j, map, lbndi(3), ubndi(3) - logical fwd - double precision tol, xl(3), xu(3), dlbndi(3), dubndi(3), - : dlbnd(3), dubnd(3) - - data lbnd / -6, 0, 10 / - data ubnd / 15, 30, 40/ - - if( status .ne. sai__ok ) return - - - nin = ast_geti( map, 'nin', status ) - nout = ast_geti( map, 'nout', status ) - - outdim = 1 - do i = 1, nin - outdim = outdim*( ubnd( i ) - lbnd( i ) + 1 ) - dlbnd( i ) = lbnd( i ) - dubnd( i ) = ubnd( i ) - end do - - call testgrid( map, nin, lbnd, ubnd, tol, maxpix, .true., nout, - : outdim, itest, status ) - - outdim = 1 - do i = 1, nout - call ast_mapbox( map, dlbnd, dubnd, .true., i, dlbndi(i), - : dubndi(i), xl, xu, status ) - lbndi( i ) = dlbndi( i ) - ubndi( i ) = dubndi( i ) - outdim = outdim*( ubndi( i ) - lbndi( i ) + 1 ) - end do - - call testgrid( map, nout, lbndi, ubndi, tol, maxpix, .false., nin, - : outdim, itest + 1, status ) - - - end - - - - - - subroutine testgrid( map, nin, lbnd, ubnd, tol, maxpix, fwd, nout, - : outdim, itest, status ) - implicit none - include 'SAE_PAR' - - integer MAXPNT - parameter( MAXPNT = 50000 ) - - integer status, lbnd( 3 ), ubnd( 3 ), nin, nout, i, outdim, - : maxpix, itest, pos(3), j, map - logical fwd - double precision tol, out( MAXPNT, 3 ), in( MAXPNT, 3 ) - - if( status .ne. sai__ok ) return - -* Check arrays are not over full - if( outdim .gt. MAXPNT ) then - status = sai__error - write(*,*) 'Array length exceeded in TESTTRANGRID:TESTGRID' - return - end if - -* Create a regular grid of positions within the input space of the -* Mapping, and transform it to the output space of the Mapping. - call ast_trangrid( map, nin, lbnd, ubnd, tol, maxpix, fwd, - : nout, MAXPNT, out, status ) - -* Convert the transformed output positions back into the input space. - call ast_trann( map, outdim, nout, MAXPNT, out, .not. fwd, nin, - : MAXPNT, in, status ) - -* Check the input space positions are close to a regular grid. - if( status .eq. sai__ok ) then - - do i = 1, nin - pos( i ) = lbnd( i ) - end do - - do j = 1, outdim - - do i = 1, nin - - if( pos( i ) .ne. 0 ) then - if( abs( in( j, i ) - pos( i ) ) .gt. - : 1.0E-6*abs( 0.5*( in( j, i ) + pos( i ) ) ) ) then - status = sai__error - write(*,*) 'Test ',itest,' failed at point ',j, - : ' axis ',i,': ',in( j, i ), - : ' should be ',pos(1) - return - end if - else - if( abs( in( j, i ) ) .gt. 1.0E-5 ) then - status = sai__error - write(*,*) 'Test ',itest,' failed at point ',j, - : ' axis ',i,': ',in( j, i ), - : ' should be ', pos(i) - return - end if - end if - end do - - pos( 1 ) = pos( 1 ) + 1 - if( pos( 1 ) .gt. ubnd( 1 ) ) then - pos( 1 ) = lbnd( 1 ) - if( nin .gt. 1 ) then - pos( 2 ) = pos( 2 ) + 1 - if( pos( 2 ) .gt. ubnd( 2 ) ) then - pos( 2 ) = lbnd( 2 ) - if( nin .gt. 2 ) then - pos( 3 ) = pos( 3 ) + 1 - end if - end if - end if - end if - end do - end if - - end diff --git a/ast/ast_tester/testunitnormmap.f b/ast/ast_tester/testunitnormmap.f deleted file mode 100644 index 4437f2c..0000000 --- a/ast/ast_tester/testunitnormmap.f +++ /dev/null @@ -1,324 +0,0 @@ - program testunitnormmap - implicit none - - include 'AST_PAR' - include 'SAE_PAR' - - integer status, map, cmpmap, smap, invmap, nin, i - logical good, differ - double precision norm, frompos(3), centre(3), topos(4) - - data centre /-1.0D0, 1.0D0, 2.0D0 /, - : frompos /-22.0D0, 3.0D0, 0.5D0/ - - - status = sai__ok - call err_mark( status ) - call ast_begin( status ) - - do nin = 1, 3 - map = ast_unitnormmap( nin, centre, ' ', status ) - - if( .not. ast_isaunitnormmap( map, status ) ) - : call stopit( status, 'Error 1' ) - if( .not. ast_isamapping( map, status ) ) - : call stopit( status, 'Error 2' ) - if( ast_geti( map, 'Nin', status ) .ne. nin ) - : call stopit( status, 'Error 3' ) - if( ast_geti( map, 'Nout', status ) .ne. nin+1 ) - : call stopit( status, 'Error 4' ) - if( ast_getl( map, 'IsLinear', status ) ) - : call stopit( status, 'Error 5' ) - - call checkdump( map, status ) - - call checkroundtrip( map, frompos, good, status ) - if( .not. good ) call stopit( status, 'Error 6' ) - - call checkroundtrip( map, centre, good, status ) - if( .not. good ) call stopit( status, 'Error 6' ) - - invmap = ast_copy( map, status ) - call ast_invert( invmap, status ) - cmpmap = ast_cmpmap( map, invmap, .true., ' ', status ) - smap = ast_simplify( cmpmap, status ) - if( .not. ast_isaunitmap( smap, status ) ) - : call stopit( status, 'Error 7' ) - if( ast_geti( smap, 'Nin', status ) .ne. nin ) - : call stopit( status, 'Error 8' ) - - cmpmap = ast_cmpmap( invmap, map, .true., ' ', status ) - smap = ast_simplify( cmpmap, status ) - if( .not. ast_isaunitmap( smap, status ) ) - : call stopit( status, 'Error 9' ) - if( ast_geti( smap, 'Nin', status ) .ne. nin+1 ) - : call stopit( status, 'Error 10' ) - - - call ast_trann( map, 1, nin, 1, frompos, .true., nin+1, - : 1, topos, status ); - - norm = 0.0D0 - do i = 1, nin - norm = norm + (frompos(i)-centre(i))**2 - end do - norm = sqrt( norm ) - - if( differ( norm, topos(nin+1) ) ) - : call stopit( status, 'Error 11' ) - - do i = 1, nin - if( differ( norm*topos(i), frompos(i)-centre(i) ) ) - : call stopit( status, 'Error 12' ) - end do - - end do - - call testsimplify( status ) - - call ast_end( status ) - call err_rlse( status ) - -c call ast_activememory( 'testunitnormmap' ) - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All UnitNormMap tests passed' - else - write(*,*) 'UnitNormMap tests failed' - end if - - end - - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - end - - - - - - subroutine checkdump( obj, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer obj, status, stat, ch, result, nin, i - logical differ - double precision in(3), out1(3), out2(3) - - data in /10.0D0, 5.0D0, -12.0D0 / - - if( status .ne. sai__ok ) return - - ch = ast_channel( AST_NULL, AST_NULL, 'SinkFile=testdmp', status ) - - if( ast_write( ch, obj, status ) .ne.1 ) then - call stopit( status, 'Cannot write supplied object to '// - : 'channel' ) - end if - - call ast_clear( ch, 'SinkFile', status ) - call ast_setc( ch, 'SourceFile', 'testdmp', status ) - result = ast_read( ch, status ) - - if( result .eq. ast__null ) then - call stopit( status, 'Cannot read object from channel' ) - end if - - if( .not. ast_isaunitnormmap( result, status ) ) then - call stopit( status, 'Object read from channel is not a '// - : 'UnitNormMap') - else if( ast_geti( result, 'Nin', status ) .ne. - : ast_geti( obj, 'Nin', status ) ) then - call stopit( status, 'UnitNormMap have different Nin values' ) - - else - nin = ast_geti( result, 'Nin', status ) - call ast_trann( result, 1, nin, 1, in, .TRUE., nin+1, 1, out1, - : status ); - call ast_trann( obj, 1, nin, 1, in, .TRUE., nin+1, 1, out2, - : status ); - - do i = 1, nin - if( differ( out2(i), out1(i) ) ) - : call stopit( status, 'Error - Recovered UnitNormMap '// - : 'differs from suppled UnitNormMap' ) - end do - - end if - - call ast_annul( result, status ) - - open( unit=1234, iostat=stat, file='testdmp', status='old') - if (stat == 0) close(1234, status='delete') - - end - - - - subroutine checkroundtrip( map, pos, good, status ) - - implicit none - - include 'SAE_PAR' - include 'AST_PAR' - - logical good, differ - integer status, map, mapinv, cmp, i, nin, nout - double precision pos(*), rtol, atol, out(7), in(7) - - good = .true. - - if( status .ne. sai__ok ) return - - nin = ast_geti( map, 'Nin', status ) - nout = ast_geti( map, 'Nout', status ) - call ast_trann( map, 1, nin, 1, pos, .TRUE., nout, 1, out, - : status ); - call ast_trann( map, 1, nout, 1, out, .FALSE., nin, 1, in, - : status ); - do i = 1, nin - if( differ( in(i), pos(i) ) ) good = .false. - end do - - mapinv = ast_copy( map, status ) - call ast_invert( mapinv, status ) - cmp = ast_cmpmap( map, mapinv, .TRUE., ' ', status ) - - call ast_trann( cmp, 1, nin, 1, pos, .true., nin, 1, in, - : status ); - do i = 1, nin - if( differ( in(i), pos(i) ) ) good = .false. - end do - - end - - - - subroutine testsimplify( status ) - implicit none - - include 'SAE_PAR' - include 'AST_PAR' - - integer status, unm1, unm1inv, unm2, unm2inv, shiftmap, - : winmap1, winmap2, i, j, k, nin, nout, cmpmap, - : cmpmap_simp - double precision centre1(3) - double precision centre2(3) - double precision shift(3) - double precision zeros(3) - double precision ones(3) - double precision a(3) - double precision testpoints(3,4) - double precision outpoints(3,4) - double precision outpoints_simp(3,4) - - integer map1(7), map2(7) - character class(7)*30 - logical differ - - data centre1 /2.0D0, -1.0D0, 0.0D0/, - : centre2 /-1.0D0, 6.0D0, 4.0D0/, - : shift /3.0D0, 7.0D0, -9.0D0/, - : zeros /0.0D0, 0.0D0, 0.0D0/, - : ones /1.0D0, 1.0D0, 1.0D0/, - : testpoints / 1.0D0, 3.0D0, -5.0D0, 2.0D0, 3.0D0, 99.0D0, - : -6.0D0, -5.0D0, -7.0D0, 30.0D0, 21.0D0, 37.0D0 / - - if( status .ne. sai__ok ) return - - unm1 = ast_unitnormmap( 3, centre1, ' ', status ) - unm1inv = ast_copy( unm1, status ) - call ast_setl( unm1inv, 'Invert', .TRUE., status ) - - unm2 = ast_unitnormmap( 3, centre2, ' ', status ) - unm2inv = ast_copy( unm2, status ) - call ast_setl( unm2inv, 'Invert', .TRUE., status ) - - shiftmap = ast_shiftmap(3, shift, ' ', status ) - - do i = 1, 3 - a(i) = ones(i) + shift(i) - end do - winmap1 = ast_winmap( 3, zeros, shift, ones, a, ' ', status ) - - do i = 1, 3 - a(i) = 2*ones(i) + shift(i) - end do - winmap2 = ast_winmap( 3, zeros, shift, ones, a, ' ', status ) - - map1(1) = unm1 - map2(1) = unm2inv - class(1) = 'WinMap' - - map1(2) = shiftmap - map2(2) = unm2 - class(2) = 'UnitNormMap' - - map1(3) = winmap1 - map2(3) = unm1 - class(3) = 'UnitNormMap' - - map1(4) = winmap2 - map2(4) = unm1 - class(4) = 'CmpMap' - - map1(5) = unm1inv - map2(5) = shiftmap - class(5) = 'UnitNormMap' - - map1(6) = unm1inv - map2(6) = winmap1 - class(6) = 'UnitNormMap' - - map1(7) = unm1inv - map2(7) = winmap2 - class(7) = 'CmpMap' - - do i = 1, 7 - cmpmap = ast_cmpmap( map1(i), map2(i), .true., ' ', status ) - cmpmap_simp = ast_simplify( cmpmap, status ) - - if( ast_getc( cmpmap_simp, 'Class', status ) .ne. class(i) ) - : call stopit( status, 'Simplify error 1' ) - - nin = ast_geti( cmpmap, 'Nin', status ) - if( nin .ne. ast_geti( cmpmap_simp, 'Nin', status ) ) - : call stopit( status, 'Simplify error 2' ) - - nout = ast_geti( cmpmap, 'Nout', status ) - if( nout .ne. ast_geti( cmpmap_simp, 'Nout', status ) ) - : call stopit( status, 'Simplify error 3' ) - - call ast_trann( cmpmap, 3, nin, 3, testpoints, .true., nout, - : 3, outpoints, status ) - call ast_trann( cmpmap_simp, 3, nin, 3, testpoints, .true., - : nout, 3, outpoints_simp, status ) - - do j = 1, nout - do k = 1, 3 - if( differ( outpoints(k,j), outpoints_simp(k,j) ) ) - : call stopit( status, 'Simplify error 4' ) - end do - end do - end do - - end - - - logical function differ( aa, bb ) - implicit none - double precision aa, bb, diff - differ = abs( (aa) - (bb) ) .gt. - : abs( 0.5D0*( (aa) + (bb) ) )*1.0D-14 - - end diff --git a/ast/ast_tester/testxmlchan.f b/ast/ast_tester/testxmlchan.f deleted file mode 100644 index 51e58ec..0000000 --- a/ast/ast_tester/testxmlchan.f +++ /dev/null @@ -1,246 +0,0 @@ - program testxmlchan - implicit none - include 'SAE_PAR' - include 'AST_PAR' - include 'testxmlchan_com' - - integer status, obj, i, ifmt, nfmt - character fmt(2)*30 - logical ok - - data nfmt /2/, - : fmt / 'native', 'quoted' / - - status = sai__ok - - call ast_begin( status ) - -* -* Create an AST object. -* - call makeobject( obj, status ) - -* -* Create a normal Channel and write the object out to file1 -* - call chanwrite( obj, 1, status ) - -* -* Test each XML format in turn. - do ifmt = 1, nfmt - -* -* Create an XmlChan and write the object out to file2 using the current -* format. -* - call xmlwrite( obj, 2, fmt( ifmt ), status ) - -* -* Use a new XmlChan to read an object from file2 -* - call xmlread( 2, obj, status ) - -* -* Write this object out to file 3 using a simple Channel. -* - call chanwrite( obj, 3, status ) - -* -* Report an error if the contents of files 1 and 3 differ. -* - ok = .true. - if( filelen( 1 ) .ne. filelen( 3 ) ) then - write(*,*) 'TestXmlChan: files 1 and 3 have different '// - : 'lengths (',filelen( 1 ),',',filelen( 3 ),').' - ok =.false. - else - do i = 1, filelen( 1 ) - if( files( 1, i ) .ne. files( 3, i ) ) then - write(*,*) 'TestXmlChan: Line ',i,' differs in '// - : 'files 1 and 3:' - write(*,*) files( 1, i ) - write(*,*) files( 3, i ) - ok = .false. - go to 10 - end if - end do - end if - - 10 continue - - if( .not. ok ) then - write(*,*) 'TestXmlChan: Test failed on XmlFormat ''', - : fmt(ifmt),'''.' - go to 20 - end if - - end do - - 20 continue - - call ast_end( status ) - - if( ok ) then - write(*,*) 'All XmlChan tests passed' - else - write(*,*) 'XmlChan tests failed' - end if - - end - -* -* Reads line "iline" from internal file "ifile" and returns it to AST using -* the AST_PULINE routine. Then increments "iline" ready for next time. -* - subroutine source( status ) - implicit none - - include 'testxmlchan_com' - - integer status, l, chr_len - - if( iline .le. filelen( ifile ) ) then - l = chr_len( files(ifile,iline) ) - call ast_putline( files(ifile,iline), l, status ) - iline = iline + 1 - else - call ast_putline( ' ', -1, status ) - end if - - end - -* -* Append a line obtained using ast_getline function to the end of the -* internal file indicated by "ifile", and increment the file length. -* - subroutine sink( status ) - implicit none - - include 'testxmlchan_com' - - integer status, l - character line*(linelen) - - call ast_getline( line, l, status ) - if( l .gt. 0 ) then - - if( filelen( ifile ) .ge. mxline ) then - stop 'TestXmlChan: Too many lines sent to sink function' - - else if( l .gt. linelen ) then - stop 'TestXmlChan: Text truncated in sink function' - - else - filelen( ifile ) = filelen( ifile ) + 1 - files( ifile, filelen( ifile ) ) = line(:l) - end if - - end if - - end - -* -* Create an AST object to be used as the test object. -* - subroutine makeobject( obj, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - integer obj, sf, f, m, status - - obj = ast__null - if( status .ne. sai__ok ) return - - sf = Ast_SkyFrame( ' ', status ) - f = Ast_Frame( 2, ' ', status ) - call ast_setc( f, 'title', 'A new title', status ) - m = ast_UnitMap( 2, ' ', status ) - obj = ast_FrameSet( f, ' ', status ) - call ast_addFrame( obj, 1, m, sf, status ) - - end - -* -* Write the supplied object out to the specified internal file using a -* basic Channel. -* - subroutine chanwrite( obj, ifil, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - include 'testxmlchan_com' - - external sink - integer obj, ifil, status, ch - - if( status .ne. sai__ok ) return - - ifile = ifil - filelen( ifil ) = 0 - - ch = ast_channel( ast_null, sink, ' ', status ) - if( ast_write( ch, obj, status ) .ne. 1 ) then - stop 'TestXmlChan: Failed to write object to Channel.' - end if - call ast_annul( ch, status ) - - end - -* -* Write the supplied object out to the specified internal file using an -* XmlChan. -* - subroutine xmlwrite( obj, ifil, fmt, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - include 'testxmlchan_com' - - external sink - integer obj, ifil, status, ch - character fmt*(*) - - if( status .ne. sai__ok ) return - - ifile = ifil - filelen( ifil ) = 0 - - ch = ast_xmlchan( ast_null, sink, 'indent=1,comment=1', - : status ) - call ast_seti( ch, 'xmllength', linelen, status ) - call ast_setc( ch, 'xmlformat', fmt, status ) - if( ast_write( ch, obj, status ) .ne. 1 ) then - stop 'TestXmlChan: Failed to write object to XmlChan.' - end if - call ast_annul( ch, status ) - - end - -* -* Read an object out of the specified internal file using an XmlChan. -* - subroutine xmlread( ifil, obj, status ) - implicit none - include 'SAE_PAR' - include 'AST_PAR' - - include 'testxmlchan_com' - - external source - integer obj, ifil, status, ch - - if( status .ne. sai__ok ) return - - ifile = ifil - iline = 1 - - ch = ast_xmlchan( source, ast_null, ' ', status ) - obj = ast_read( ch, status ) - if( obj .eq. ast__null ) then - stop 'TestXmlChan: Failed to read object from XmlChan.' - end if - call ast_annul( ch, status ) - - end diff --git a/ast/ast_tester/testxmlchan_com b/ast/ast_tester/testxmlchan_com deleted file mode 100644 index 3b7500e..0000000 --- a/ast/ast_tester/testxmlchan_com +++ /dev/null @@ -1,13 +0,0 @@ -* -* Common block declaration used by testxmlchan.f for storing internal -* files and associated info. -* - integer mxline - parameter ( mxline = 500 ) - - integer linelen - parameter ( linelen = 100 ) - - character files( 3, mxline )*(linelen) - integer ifile,iline,filelen( 3 ) - common /files/ files, ifile, iline, filelen diff --git a/ast/ast_tester/testzoommap.f b/ast/ast_tester/testzoommap.f deleted file mode 100644 index 0c2afd7..0000000 --- a/ast/ast_tester/testzoommap.f +++ /dev/null @@ -1,91 +0,0 @@ - program testzoommap - implicit none - - include 'AST_PAR' - include 'AST_ERR' - include 'SAE_PAR' - - integer zm, cm, status - - status = sai__ok - call ast_begin( status ) - - zm = ast_zoommap( 1, -1.0D0, ' ', status ) - if( .not. ast_test( zm, 'Zoom', status ) ) then - call stopit( status, "Error 1" ); - else if( ast_getd( zm, 'Zoom', status ) .ne. -1.0D0 ) then - call stopit( status, "Error 2" ); - end if - - call ast_clear( zm, 'Zoom', status ) - if( ast_test( zm, 'Zoom', status ) ) then - call stopit( status, "Error 3" ); - else if( ast_getd( zm, 'Zoom', status ) .ne. 1.0D0 ) then - call stopit( status, "Error 4" ); - end if - - call ast_setd( zm, 'Zoom', 2.5D0, status ) - if( .not. ast_test( zm, 'Zoom', status ) ) then - call stopit( status, "Error 5" ); - else if( ast_getd( zm, 'Zoom', status ) .ne. 2.5D0 ) then - call stopit( status, "Error 6" ); - end if - - cm = ast_cmpmap( zm, ast_unitmap( 1, ' ', status ), .TRUE., - : ' ', status ) - - if( .not. ast_test( zm, 'Zoom', status ) ) then - call stopit( status, "Error 7" ); - else if( ast_getd( zm, 'Zoom', status ) .ne. 2.5D0 ) then - call stopit( status, "Error 8" ); - end if - - call err_mark - - call ast_setd( zm, 'Zoom', 1.5D0, status ) - if( status .eq. ast__immut ) then - call err_annul( status ) - else if( status .eq. sai__ok ) then - call stopit( status, "Error 9" ); - else - call stopit( status, "Error 10" ); - end if - - call ast_clear( zm, 'Zoom', status ) - if( status .eq. ast__immut ) then - call err_annul( status ) - else if( status .eq. sai__ok ) then - call stopit( status, "Error 11" ); - else - call stopit( status, "Error 12" ); - end if - - call err_rlse - - call ast_end( status ) - -c call ast_activememory( 'testzoommap' ) - call ast_flushmemory( 1 ) - - if( status .eq. sai__ok ) then - write(*,*) 'All ZoomMap tests passed' - else - write(*,*) 'ZoomMap tests failed' - end if - - end - - - - subroutine stopit( status, text ) - implicit none - include 'SAE_PAR' - integer status - character text*(*) - if( status .ne. sai__ok ) return - status = sai__error - write(*,*) text - end - - - diff --git a/ast/ast_tester/timeplot.attr b/ast/ast_tester/timeplot.attr deleted file mode 100644 index 5b43238..0000000 --- a/ast/ast_tester/timeplot.attr +++ /dev/null @@ -1 +0,0 @@ -minticklen=0.02,majticklen=0.05,gap(2)=0.1,NumLabGap=0.05,textlabgap=0.1,size=0.9 diff --git a/ast/ast_tester/timeplot.box b/ast/ast_tester/timeplot.box deleted file mode 100644 index c2351b4..0000000 --- a/ast/ast_tester/timeplot.box +++ /dev/null @@ -1 +0,0 @@ -0.046 3.0 1.008 3.3 diff --git a/ast/ast_tester/timeplot.head b/ast/ast_tester/timeplot.head deleted file mode 100644 index 95ea8d5..0000000 --- a/ast/ast_tester/timeplot.head +++ /dev/null @@ -1,34 +0,0 @@ - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST Beginning of AST data for CmpFrame object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'CmpFrame' / Compound coordinate system description -DOMAIN_A= 'DATAPLOT' / Coordinate system domain -ACTUNT_A= 1 / Unit strings affects alignment -ISA_A = 'Frame ' / Coordinate system description -FRAMEA_A= ' ' / First component Frame -BEGAST_B= 'TimeFrame' / Description of time coordinate system -TITLE_A = 'KAPPA - Trandat' / Title of coordinate system -NAXES_A = 1 / Number of coordinate axes -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -FORMAT_A= 'iso.0 ' / Format specifier -ENDAST_A= 'Axis ' / End of object definition -ISA_B = 'Frame ' / Coordinate system description -TMORG_A = 57128.585856 / Time offset -ENDAST_B= 'TimeFrame' / End of object definition -FRAMEB_A= ' ' / Second component Frame -BEGAST_D= 'Frame ' / Coordinate system description -NAXES_B = 1 / Number of coordinate axes -ACTUNT_B= 1 / Unit strings affects alignment -AX1_B = ' ' / Axis number 1 -BEGAST_E= 'Axis ' / Coordinate axis -LABEL_A = 'Data up-loaded' / Axis Label -SYMBOL_A= 'Data ' / Axis symbol -UNIT_A = 'GB ' / Axis units -ENDAST_C= 'Axis ' / End of object definition -ENDAST_D= 'Frame ' / End of object definition -ENDAST_E= 'CmpFrame' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for CmpFrame object AST -COMMENT AST ---------------------------------------------------------------- AST diff --git a/ast/ast_tester/timj.ast b/ast/ast_tester/timj.ast deleted file mode 100644 index ed011dd..0000000 --- a/ast/ast_tester/timj.ast +++ /dev/null @@ -1,234 +0,0 @@ - Begin FrameSet -# Title = "FK5 equatorial coordinates; mean equinox J2000.0; gnomonic projection" # Title of coordinate system -# Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction - IsA Frame # Coordinate system description - Nframe = 4 # Number of Frames in FrameSet -# Base = 1 # Index of base Frame - Currnt = 4 # Index of current Frame - Nnode = 5 # Number of nodes in FrameSet - Nod1 = 3 # Frame 1 is associated with node 3 - Nod2 = 4 # Frame 2 is associated with node 4 - Nod3 = 5 # Frame 3 is associated with node 5 - Nod4 = 2 # Frame 4 is associated with node 2 - Lnk2 = 1 # Node 2 is derived from node 1 - Lnk3 = 1 # Node 3 is derived from node 1 - Lnk4 = 1 # Node 4 is derived from node 1 - Lnk5 = 1 # Node 5 is derived from node 1 - Frm1 = # Frame number 1 - Begin Frame - Title = "Data grid indices; first pixel at (1,1)" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "GRID" # Coordinate system domain -# Lbl1 = "Data grid index 1" # Label for axis 1 -# Lbl2 = "Data grid index 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - Ax1 = # Axis number 1 - Begin Axis - Label = "Data grid index 1" # Axis Label - Symbol = "g1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis - Label = "Data grid index 2" # Axis Label - Symbol = "g2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm2 = # Frame number 2 - Begin Frame - Title = "Pixel coordinates; first pixel at (-128.5,-127.5)" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "PIXEL" # Coordinate system domain -# Lbl1 = "Pixel coordinate 1" # Label for axis 1 -# Lbl2 = "Pixel coordinate 2" # Label for axis 2 -# Uni1 = "pixel" # Units for axis 1 -# Uni2 = "pixel" # Units for axis 2 - Ax1 = # Axis number 1 - Begin Axis - Label = "Pixel coordinate 1" # Axis Label - Symbol = "p1" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - Ax2 = # Axis number 2 - Begin Axis - Label = "Pixel coordinate 2" # Axis Label - Symbol = "p2" # Axis symbol - Unit = "pixel" # Axis units - Format = "%3.1f" # Format specifier - End Axis - End Frame - Frm3 = # Frame number 3 - Begin Frame - Title = "Axis coordinates; first pixel at (384,-381)" # Title of coordinate system - Naxes = 2 # Number of coordinate axes - Domain = "AXIS" # Coordinate system domain -# Lbl1 = "R.A. offset" # Label for axis 1 -# Lbl2 = "Declination offset" # Label for axis 2 -# Uni1 = "arcsec" # Units for axis 1 -# Uni2 = "arcsec" # Units for axis 2 - Ax1 = # Axis number 1 - Begin Axis - Label = "R.A. offset" # Axis Label - Symbol = "a1" # Axis symbol - Unit = "arcsec" # Axis units - End Axis - Ax2 = # Axis number 2 - Begin Axis - Label = "Declination offset" # Axis Label - Symbol = "a2" # Axis symbol - Unit = "arcsec" # Axis units - End Axis - End Frame - Frm4 = # Frame number 4 - Begin SkyFrame -# Title = "FK5 equatorial coordinates; mean equinox J2000.0; gnomonic projection" # Title of coordinate system - Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction - Ax1 = # Axis number 1 - Begin SkyAxis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis - End SkyAxis - IsA Frame # Coordinate system description - System = "FK5" # Celestial coordinate system type - Proj = "gnomonic" # Description of sky projection - Epoch = 2002.3821786502 # Julian epoch of observation - Eqnox = 2000 # Julian epoch of mean equinox - End SkyFrame - Map2 = # Mapping between nodes 1 and 2 - Begin CmpMap - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin WinMap - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - Sft1 = -129 # Shift for axis 1 - Sft2 = -128 # Shift for axis 2 - End WinMap - MapB = # Second component Mapping - Begin CmpMap - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap - Nin = 2 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = -1.45444097695548e-05 # Forward matrix value - M1 = 1.45444097695548e-05 # Forward matrix value - Form = "Diagonal" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin WcsMap - Nin = 2 # Number of input coordinates - Invert = 1 # Mapping inverted - IsA Mapping # Mapping between coordinate systems - Type = "TAN" # Gnomonic projection - End WcsMap - MapB = # Second component Mapping - Begin CmpMap - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - InvA = 1 # First Mapping used in inverse direction - MapA = # First component Mapping - Begin SphMap - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - End SphMap - MapB = # Second component Mapping - Begin CmpMap - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin MatrixMap - Nin = 3 # Number of input coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - M0 = 0.425569982779421 # Forward matrix value - M1 = 0.773738866158297 # Forward matrix value - M2 = 0.469274287334386 # Forward matrix value - M3 = -0.519775230563316 # Forward matrix value - M4 = 0.633504670066506 # Forward matrix value - M5 = -0.573154030516038 # Forward matrix value - M6 = -0.740759002274002 # Forward matrix value - M7 = 0 # Forward matrix value - M8 = 0.671770869084113 # Forward matrix value - Form = "Full" # Matrix storage form - End MatrixMap - MapB = # Second component Mapping - Begin CmpMap - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - IsA Mapping # Mapping between coordinate systems - MapA = # First component Mapping - Begin SphMap - Nin = 3 # Number of input coordinates - Nout = 2 # Number of output coordinates - Invert = 0 # Mapping not inverted - IsA Mapping # Mapping between coordinate systems - UntRd = 1 # All input vectors have unit length - End SphMap - MapB = # Second component Mapping - Begin SlaMap - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Nsla = 1 # Number of conversion steps - Sla1 = "FK45Z" # FK4 to FK5 J2000.0 (no PM or parallax) - Sla1a = 2002.38350704493 # Besselian epoch of FK4 coordinates - End SlaMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - End CmpMap - Map3 = # Mapping between nodes 1 and 3 - Begin UnitMap - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - End UnitMap - Map4 = # Mapping between nodes 1 and 4 - Begin WinMap - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Sft1 = -129.5 # Shift for axis 1 - Sft2 = -128.5 # Shift for axis 2 - End WinMap - Map5 = # Mapping between nodes 1 and 5 - Begin WinMap - Nin = 2 # Number of input coordinates - IsA Mapping # Mapping between coordinate systems - Sft1 = 387 # Shift for axis 1 - Scl1 = -3 # Scale factor for axis 1 - Sft2 = -384 # Shift for axis 2 - Scl2 = 3 # Scale factor for axis 2 - End WinMap - End FrameSet diff --git a/ast/ast_tester/timj.fits-aips b/ast/ast_tester/timj.fits-aips deleted file mode 100644 index 4fdd94b..0000000 --- a/ast/ast_tester/timj.fits-aips +++ /dev/null @@ -1,11 +0,0 @@ -CRPIX1 = 129.0 / Reference pixel on axis 1 -CRPIX2 = 128.0 / Reference pixel on axis 2 -CRVAL1 = 309.75469 / Value at ref. pixel on axis 1 -CRVAL2 = 42.381032 / Value at ref. pixel on axis 2 -CTYPE1 = 'RA---TAN' / Type of co-ordinate on axis 1 -CTYPE2 = 'DEC--TAN' / Type of co-ordinate on axis 2 -CDELT1 = -8.3333273E-4 / Pixel size -CDELT2 = 0.00083333273 / Pixel size -CROTA2 = 0.29013902 / Axis rotation -EPOCH = 2000.0 / Epoch of reference equinox -DATE-OBS= '2002-05-20T14:09:36.786' / Date of observation diff --git a/ast/ast_tester/timj.fits-iraf b/ast/ast_tester/timj.fits-iraf deleted file mode 100644 index 88c3d94..0000000 --- a/ast/ast_tester/timj.fits-iraf +++ /dev/null @@ -1,13 +0,0 @@ -CRPIX1 = 129.0 / Reference pixel on axis 1 -CRPIX2 = 128.0 / Reference pixel on axis 2 -CRVAL1 = 309.75469 / Value at ref. pixel on axis 1 -CRVAL2 = 42.381032 / Value at ref. pixel on axis 2 -CTYPE1 = 'RA---TAN' / Type of co-ordinate on axis 1 -CTYPE2 = 'DEC--TAN' / Type of co-ordinate on axis 2 -CD1_1 = -8.3332205E-4 / Transformation matrix element -CD1_2 = -4.2198799E-6 / Transformation matrix element -CD2_1 = -4.2198799E-6 / Transformation matrix element -CD2_2 = 0.00083332205 / Transformation matrix element -RADECSYS= 'FK5 ' / Reference frame for RA/DEC values -EQUINOX = 2000.0 / Epoch of reference equinox -DATE-OBS= '2002-05-20T14:09:36.786' / Date of observation diff --git a/ast/ast_tester/timj.fits-pc b/ast/ast_tester/timj.fits-pc deleted file mode 100644 index f3bfc6f..0000000 --- a/ast/ast_tester/timj.fits-pc +++ /dev/null @@ -1,16 +0,0 @@ -PC001001= 1.0 -PC001002= 0.0050638595 -PC002001= -0.0050638595 -PC002002= 1.0 -CDELT1 = -8.3333273E-4 / Pixel scale on axis 1 -CDELT2 = 0.00083333273 / Pixel scale on axis 2 -CRPIX1 = 129.0 / Reference pixel on axis 1 -CRPIX2 = 128.0 / Reference pixel on axis 2 -CRVAL1 = 309.75469 / Value at ref. pixel on axis 1 -CRVAL2 = 42.381032 / Value at ref. pixel on axis 2 -CTYPE1 = 'RA---TAN' / Type of co-ordinate on axis 1 -CTYPE2 = 'DEC--TAN' / Type of co-ordinate on axis 2 -RADECSYS= 'FK5 ' / Reference frame for RA/DEC values -EQUINOX = 2000.0 / Epoch of reference equinox -MJD-OBS = 52414.59 / Modified Julian Date of observation -DATE-OBS= '2002-05-20T14:09:36.786' / Date of observation diff --git a/ast/ast_tester/timj.fits-wcs b/ast/ast_tester/timj.fits-wcs deleted file mode 100644 index f8b3e8a..0000000 --- a/ast/ast_tester/timj.fits-wcs +++ /dev/null @@ -1,39 +0,0 @@ -WCSAXES = 2 / Number of WCS axes -CRPIX1 = 129.0 / Reference pixel on axis 1 -CRPIX2 = 128.0 / Reference pixel on axis 2 -CRVAL1 = 309.75469 / Value at ref. pixel on axis 1 -CRVAL2 = 42.381032 / Value at ref. pixel on axis 2 -CTYPE1 = 'RA---TAN' / Type of co-ordinate on axis 1 -CTYPE2 = 'DEC--TAN' / Type of co-ordinate on axis 2 -CD1_1 = -8.3332205E-4 / Transformation matrix element -CD1_2 = -4.2198799E-6 / Transformation matrix element -CD2_1 = -4.2198799E-6 / Transformation matrix element -CD2_2 = 0.00083332205 / Transformation matrix element -MJD-OBS = 52414.59 / Modified Julian Date of observation -DATE-OBS= '2002-05-20T14:09:36.786' / Date of observation -RADESYS = 'FK5 ' / Reference frame for RA/DEC values -EQUINOX = 2000.0 / [yr] Epoch of reference equinox -WCSAXESA= 2 / Number of WCS axes -WCSNAMEA= 'PIXEL ' / Reference name for the coord. frame -CRPIX1A = 1.0 / Reference pixel on axis 1 -CRPIX2A = 1.0 / Reference pixel on axis 2 -CRVAL1A = -128.5 / Value at ref. pixel on axis 1 -CRVAL2A = -127.5 / Value at ref. pixel on axis 2 -CTYPE1A = 'p1 ' / Pixel coordinate 1 -CTYPE2A = 'p2 ' / Pixel coordinate 2 -CD1_1A = 1.0 / Transformation matrix element -CD2_2A = 1.0 / Transformation matrix element -CUNIT1A = 'pixel ' / Units for axis 1 -CUNIT2A = 'pixel ' / Units for axis 2 -WCSAXESB= 2 / Number of WCS axes -WCSNAMEB= 'AXIS ' / Reference name for the coord. frame -CRPIX1B = 1.0 / Reference pixel on axis 1 -CRPIX2B = 1.0 / Reference pixel on axis 2 -CRVAL1B = 384.0 / Value at ref. pixel on axis 1 -CRVAL2B = -381.0 / Value at ref. pixel on axis 2 -CTYPE1B = 'a1 ' / R.A. offset -CTYPE2B = 'a2 ' / Declination offset -CD1_1B = -3.0 / Transformation matrix element -CD2_2B = 3.0 / Transformation matrix element -CUNIT1B = 'arcsec ' / Units for axis 1 -CUNIT2B = 'arcsec ' / Units for axis 2 diff --git a/ast/ast_tester/timj.native b/ast/ast_tester/timj.native deleted file mode 100644 index fb54315..0000000 --- a/ast/ast_tester/timj.native +++ /dev/null @@ -1,217 +0,0 @@ - -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST WCS information in AST format AST -COMMENT AST See http://www.starlink.ac.uk/ast/ AST -COMMENT AST Beginning of AST data for FrameSet object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'FrameSet' / Set of inter-related coordinate systems -NFRAME_A= 4 / Number of Frames in FrameSet -CURRNT_A= 4 / Index of current Frame -NNODE_A = 5 / Number of nodes in FrameSet -NOD1_A = 3 / Frame 1 is associated with node 3 -NOD2_A = 4 / Frame 2 is associated with node 4 -NOD3_A = 5 / Frame 3 is associated with node 5 -NOD4_A = 2 / Frame 4 is associated with node 2 -LNK2_A = 1 / Node 2 is derived from node 1 -LNK3_A = 1 / Node 3 is derived from node 1 -LNK4_A = 1 / Node 4 is derived from node 1 -LNK5_A = 1 / Node 5 is derived from node 1 -FRM1_A = ' ' / Frame number 1 -BEGAST_B= 'Frame ' / Coordinate system description -TITLE_A = 'Data grid indices; first pixel at (1&' / Title of coordinate system -CONTINUE ',1) ' -NAXES_A = 2 / Number of coordinate axes -DOMAIN_A= 'GRID ' / Coordinate system domain -AX1_A = ' ' / Axis number 1 -BEGAST_C= 'Axis ' / Coordinate axis -LABEL_A = 'Data grid index 1' / Axis Label -SYMBOL_A= 'g1 ' / Axis symbol -UNIT_A = 'pixel ' / Axis units -FORMAT_A= '%3.1f ' / Format specifier -ENDAST_A= 'Axis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_D= 'Axis ' / Coordinate axis -LABEL_B = 'Data grid index 2' / Axis Label -SYMBOL_B= 'g2 ' / Axis symbol -UNIT_B = 'pixel ' / Axis units -FORMAT_B= '%3.1f ' / Format specifier -ENDAST_B= 'Axis ' / End of object definition -ENDAST_C= 'Frame ' / End of object definition -FRM2_A = ' ' / Frame number 2 -BEGAST_E= 'Frame ' / Coordinate system description -TITLE_B = 'Pixel coordinates; first pixel at (-&' / Title of coordinate system -CONTINUE '128.5,-127.5)' -NAXES_B = 2 / Number of coordinate axes -DOMAIN_B= 'PIXEL ' / Coordinate system domain -AX1_B = ' ' / Axis number 1 -BEGAST_F= 'Axis ' / Coordinate axis -LABEL_C = 'Pixel coordinate 1' / Axis Label -SYMBOL_C= 'p1 ' / Axis symbol -UNIT_C = 'pixel ' / Axis units -FORMAT_C= '%3.1f ' / Format specifier -ENDAST_D= 'Axis ' / End of object definition -AX2_B = ' ' / Axis number 2 -BEGAST_G= 'Axis ' / Coordinate axis -LABEL_D = 'Pixel coordinate 2' / Axis Label -SYMBOL_D= 'p2 ' / Axis symbol -UNIT_D = 'pixel ' / Axis units -FORMAT_D= '%3.1f ' / Format specifier -ENDAST_E= 'Axis ' / End of object definition -ENDAST_F= 'Frame ' / End of object definition -FRM3_A = ' ' / Frame number 3 -BEGAST_H= 'Frame ' / Coordinate system description -TITLE_C = 'Axis coordinates; first pixel at (38&' / Title of coordinate system -CONTINUE '4,-381) ' -NAXES_C = 2 / Number of coordinate axes -DOMAIN_C= 'AXIS ' / Coordinate system domain -AX1_C = ' ' / Axis number 1 -BEGAST_I= 'Axis ' / Coordinate axis -LABEL_E = 'R.A. offset' / Axis Label -SYMBOL_E= 'a1 ' / Axis symbol -UNIT_E = 'arcsec ' / Axis units (arc-second) -ENDAST_G= 'Axis ' / End of object definition -AX2_C = ' ' / Axis number 2 -BEGAST_J= 'Axis ' / Coordinate axis -LABEL_F = 'Declination offset' / Axis Label -SYMBOL_F= 'a2 ' / Axis symbol -UNIT_F = 'arcsec ' / Axis units (arc-second) -ENDAST_H= 'Axis ' / End of object definition -ENDAST_I= 'Frame ' / End of object definition -FRM4_A = ' ' / Frame number 4 -BEGAST_K= 'SkyFrame' / Description of celestial coordinate system -NAXES_D = 2 / Number of coordinate axes -EPOCH_A = 2002.3822 / Julian epoch of observation -SYSTEM_A= 'FK5 ' / Coordinate system type -AX1_D = ' ' / Axis number 1 -BEGAST_L= 'SkyAxis ' / Celestial coordinate axis -ENDAST_J= 'SkyAxis ' / End of object definition -AX2_D = ' ' / Axis number 2 -BEGAST_M= 'SkyAxis ' / Celestial coordinate axis -ENDAST_K= 'SkyAxis ' / End of object definition -ISA_A = 'Frame ' / Coordinate system description -PROJ_A = 'gnomonic' / Description of sky projection -EQNOX_A = 2000.0 / Julian epoch of mean equinox -ENDAST_L= 'SkyFrame' / End of object definition -MAP2_A = ' ' / Mapping between nodes 1 and 2 -BEGAST_N= 'CmpMap ' / Compound Mapping -NIN_A = 2 / Number of input coordinates -ISA_B = 'Mapping ' / Mapping between coordinate systems -MAPA_A = ' ' / First component Mapping -BEGAST_O= 'WinMap ' / Map one window on to another -NIN_B = 2 / Number of input coordinates -INVERT_A= 0 / Mapping not inverted -ISA_C = 'Mapping ' / Mapping between coordinate systems -SFT1_A = -129.0 / Shift for axis 1 -SFT2_A = -128.0 / Shift for axis 2 -ENDAST_M= 'WinMap ' / End of object definition -MAPB_A = ' ' / Second component Mapping -BEGAST_P= 'CmpMap ' / Compound Mapping -NIN_C = 2 / Number of input coordinates -ISA_D = 'Mapping ' / Mapping between coordinate systems -MAPA_B = ' ' / First component Mapping -BEGAST_Q= 'MatrixMap' / Matrix transformation -NIN_D = 2 / Number of input coordinates -INVERT_B= 0 / Mapping not inverted -ISA_E = 'Mapping ' / Mapping between coordinate systems -M0_A = -1.454441E-5 / Forward matrix value -M1_A = 1.454441E-5 / Forward matrix value -FORM_A = 'Diagonal' / Matrix storage form -ENDAST_N= 'MatrixMap' / End of object definition -MAPB_B = ' ' / Second component Mapping -BEGAST_R= 'CmpMap ' / Compound Mapping -NIN_E = 2 / Number of input coordinates -ISA_F = 'Mapping ' / Mapping between coordinate systems -INVA_A = 1 / First Mapping used in inverse direction -MAPA_C = ' ' / First component Mapping -BEGAST_S= 'WcsMap ' / FITS-WCS sky projection -NIN_F = 2 / Number of input coordinates -INVERT_C= 1 / Mapping inverted -ISA_G = 'Mapping ' / Mapping between coordinate systems -TYPE_A = 'TAN ' / Gnomonic projection -ENDAST_O= 'WcsMap ' / End of object definition -MAPB_C = ' ' / Second component Mapping -BEGAST_T= 'CmpMap ' / Compound Mapping -NIN_G = 2 / Number of input coordinates -ISA_H = 'Mapping ' / Mapping between coordinate systems -INVA_B = 1 / First Mapping used in inverse direction -MAPA_D = ' ' / First component Mapping -BEGAST_U= 'SphMap ' / Cartesian to Spherical mapping -NIN_H = 3 / Number of input coordinates -NOUT_A = 2 / Number of output coordinates -INVERT_D= 0 / Mapping not inverted -ISA_I = 'Mapping ' / Mapping between coordinate systems -UNTRD_A = 1 / All input vectors have unit length -ENDAST_P= 'SphMap ' / End of object definition -MAPB_D = ' ' / Second component Mapping -BEGAST_V= 'CmpMap ' / Compound Mapping -NIN_I = 3 / Number of input coordinates -NOUT_B = 2 / Number of output coordinates -ISA_J = 'Mapping ' / Mapping between coordinate systems -MAPA_E = ' ' / First component Mapping -BEGAST_W= 'MatrixMap' / Matrix transformation -NIN_J = 3 / Number of input coordinates -INVERT_E= 0 / Mapping not inverted -ISA_K = 'Mapping ' / Mapping between coordinate systems -M0_B = 0.42556998 / Forward matrix value -M1_B = 0.77373887 / Forward matrix value -M2_A = 0.46927429 / Forward matrix value -M3_A = -0.51977523 / Forward matrix value -M4_A = 0.63350467 / Forward matrix value -M5_A = -0.57315403 / Forward matrix value -M6_A = -0.740759 / Forward matrix value -M7_A = 0.0 / Forward matrix value -M8_A = 0.67177087 / Forward matrix value -FORM_B = 'Full ' / Matrix storage form -ENDAST_Q= 'MatrixMap' / End of object definition -MAPB_E = ' ' / Second component Mapping -BEGAST_X= 'CmpMap ' / Compound Mapping -NIN_K = 3 / Number of input coordinates -NOUT_C = 2 / Number of output coordinates -ISA_L = 'Mapping ' / Mapping between coordinate systems -MAPA_F = ' ' / First component Mapping -BEGAST_Y= 'SphMap ' / Cartesian to Spherical mapping -NIN_L = 3 / Number of input coordinates -NOUT_D = 2 / Number of output coordinates -INVERT_F= 0 / Mapping not inverted -ISA_M = 'Mapping ' / Mapping between coordinate systems -UNTRD_B = 1 / All input vectors have unit length -ENDAST_R= 'SphMap ' / End of object definition -MAPB_F = ' ' / Second component Mapping -BEGAST_Z= 'SlaMap ' / Conversion between sky coordinate systems -NIN_M = 2 / Number of input coordinates -ISA_N = 'Mapping ' / Mapping between coordinate systems -NSLA_A = 1 / Number of conversion steps -SLA1_A = 'FK45Z ' / FK4 to FK5 J2000.0 (no PM or parallax) -SLA1A_A = 2002.3835 / Besselian epoch of FK4 coordinates -ENDAST_S= 'SlaMap ' / End of object definition -ENDAST_T= 'CmpMap ' / End of object definition -ENDAST_U= 'CmpMap ' / End of object definition -ENDAST_V= 'CmpMap ' / End of object definition -ENDAST_W= 'CmpMap ' / End of object definition -ENDAST_X= 'CmpMap ' / End of object definition -ENDAST_Y= 'CmpMap ' / End of object definition -MAP3_A = ' ' / Mapping between nodes 1 and 3 -BEGASTA_= 'UnitMap ' / Unit (null) Mapping -NIN_N = 2 / Number of input coordinates -ISA_O = 'Mapping ' / Mapping between coordinate systems -ENDAST_Z= 'UnitMap ' / End of object definition -MAP4_A = ' ' / Mapping between nodes 1 and 4 -BEGASTAA= 'WinMap ' / Map one window on to another -NIN_O = 2 / Number of input coordinates -ISA_P = 'Mapping ' / Mapping between coordinate systems -SFT1_B = -129.5 / Shift for axis 1 -SFT2_B = -128.5 / Shift for axis 2 -ENDASTA_= 'WinMap ' / End of object definition -MAP5_A = ' ' / Mapping between nodes 1 and 5 -BEGASTAB= 'WinMap ' / Map one window on to another -NIN_P = 2 / Number of input coordinates -ISA_Q = 'Mapping ' / Mapping between coordinate systems -SFT1_C = 387.0 / Shift for axis 1 -SCL1_A = -3.0 / Scale factor for axis 1 -SFT2_C = -384.0 / Shift for axis 2 -SCL2_A = 3.0 / Scale factor for axis 2 -ENDASTAA= 'WinMap ' / End of object definition -ENDASTAB= 'FrameSet' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for FrameSet object AST -COMMENT AST ---------------------------------------------------------------- AST diff --git a/ast/ast_tester/tnx.attr b/ast/ast_tester/tnx.attr deleted file mode 100644 index e5498b5..0000000 --- a/ast/ast_tester/tnx.attr +++ /dev/null @@ -1 +0,0 @@ -Grid=1,textlabgap=0.1,border=0 diff --git a/ast/ast_tester/tnx.box b/ast/ast_tester/tnx.box deleted file mode 100644 index f69daff..0000000 --- a/ast/ast_tester/tnx.box +++ /dev/null @@ -1 +0,0 @@ -0.0 0.0 2048.0 4096.0 diff --git a/ast/ast_tester/tnx.head b/ast/ast_tester/tnx.head deleted file mode 100644 index 58c6aa0..0000000 --- a/ast/ast_tester/tnx.head +++ /dev/null @@ -1,180 +0,0 @@ -SIMPLE = T / Fits standard -BITPIX = 16 / Bits per pixel -NAXIS = 2 / Number of axes -NAXIS1 = 2048 / Axis length -NAXIS2 = 4096 / Axis length -EXTEND = F / File may contain extensions -ORIGIN = 'NOAO-IRAF FITS Image Kernel July 1999' / FITS file originator -DATE = '2001-11-20T16:52:11' / Date FITS file was generated -IRAF-TLM= '16:52:09 (20/11/2001)' / Time of last modification -OBJECT = 'A576 R ' / Name of the object observed -NEXTEND = 8 / Number of extensions -FILENAME= 'obj214r ' / Original host filename -OBSTYPE = 'object ' / Observation type -EXPTIME = 350.000 / Exposure time (sec) -DARKTIME= 351.888 / Dark time (sec) -PREFLASH= 0.000000 / Preflash time (sec) -RADECSYS= 'FK5 ' / Default coordinate system -RA = '07:21:44.00 ' / RA of observation (hr) -DEC = '55:53:16.99 ' / DEC of observation (deg) -EQUINOX = 1.9998000490000E+03 / Equinox of coordinate system - -TIMESYS = 'UTC approximate' / Time system -DATE-OBS= '1999-10-09' / Date of observation start (UTC approximate) -TIME-OBS= '12:08:33.0' / Time of observation start -MJD-OBS = 51460.50593750 / MJD of observation start -MJDHDR = 51460.50591435 / MJD of header creation -LSTHDR = '05:52:50.00 ' / LST of header creation - -OBSERVAT= 'KPNO ' / Observatory -TELESCOP= 'KPNO 0.9 meter telescope' / Telescope -ZD = 2.8469999000000E+01 / Zenith distance -AIRMASS = 1.1400000000000E+00 / Airmass -TELFOCUS= 4414 / Telescope focus -CORRCTOR= 'KPNO 0.9m Corrector' / Corrector Identification -ADC = 'none ' / ADC Identification - -DETECTOR= 'CCDMosaThin1' / Detector -DETSIZE = '[1:8176,1:8192]' / Detector size for DETSEC -NCCDS = 8 / Number of CCDs -NAMPS = 8 / Number of Amplifiers -PIXSIZE1= 15. / Pixel size for axis 1 (microns) -PIXSIZE2= 15. / Pixel size for axis 2 (microns) -PIXSCAL1= 0.423 / Pixel scale for axis 1 (arcsec/pixel) -PIXSCAL2= 0.423 / Pixel scale for axis 2 (arcsec/pixel) -RAPANGL = 0. / Position angle of RA axis (deg) -DECPANGL= 270. / Position angle of DEC axis (deg) -FILPOS = 4 / Filter position -FILTER = 'R ' / Filter name(s) -SHUTSTAT= 'guide ' / Shutter status -TV1FOC = -5.9600000000000E-01 / North TV Camera focus position -TV2FOC = -1.6230000000000E+00 / South Camera focus position -ENVTEM = 1.7299999000000E+01 / Ambient temperature (C) -DEWAR = 'CCDMosaThin1 Dewar' / Dewar identification -DEWTEM1 = -1.7060000600000E+02 / Dewar temperature (C) -DEWTEM2 = -4.7000000000000E+00 / Fill Neck temperature (C) -CCDTEM = -9.5000000000000E+01 / CCD temperature (C) - -CONTROLR= 'Mosaic Arcon' / Controller identification -CONSWV = '2.000 13Feb96 (add mode and group to hdrs)' / Controller softwar -AMPINTEG= 3000 / (ns) Double Correlated Sample time -READTIME= 13200 / (ns) unbinned pixel read time -ARCONWD = 'Obs Thu Aug 19 10:45:52 1999' / Date waveforms last compiled -ARCONWM = 'OverlapXmit EarlyReset SplitShift ' / Waveform mode switches on -ARCONGI = 1 / Gain selection (index into Gain Table) - -OBSERVER= 'G.Wegner,M.Hudson' / Observer(s) -PROPOSER= '' / Proposer(s) -PROPOSAL= '' / Proposal title -PROPID = '99B-0020' / Proposal identification -OBSID = 'kp09m.19991009T120833' / Observation ID - -IMAGESWV= 'mosdca (Aug99), CCDMosaThin1V8.tcl (Aug99)' / Image creation software -KWDICT = 'MosaicV1.dic (Sep97)' / Keyword dictionary - -CHECKSUM= '' / Header checksum -DATASUM = '' / Data checksum -CHECKVER= '' / Checksum version -RECNO = 0 / NOAO archive sequence number -IMAGEID = 5 / Image identification - -TELRA = '07:21:44.00 ' / RA of observation (hr) -TELDEC = '55:53:16.99 ' / DEC of observation (deg) -TELEQUIN= 1.9998000490000E+03 / Equinox of coordinate system -TELRADEC= 'FK5 ' / Default coordinate system - -CCDNAME = 'SITe #7061FBR03-02 (NOAO 02)' / CCD name -AMPNAME = 'SITe #7061FBR03-02 (NOAO 02), upper left (Amp321)' / Amplifier name -GAIN = 2.3 / gain for amp 321 (e-/ADU) -RDNOISE = 9.5 / read noise for amp 321 (e-) -SATURATE= 22000 / Maximum good data value (ADU) -CONHWV = 'ACEB003_AMP21' / Controller hardware version -ARCONG = 2.3 / gain expected for amp 321 (e-/ADU) -ARCONRN = 5.1 / read noise expected for amp 321 (e-) -BPM = 'mscdb$noao/CCDMosaThin1/bpm_im5' / Bad pixel mask -CCDSIZE = '[1:2048,1:4096]' / CCD size -CCDSUM = '1 1 ' / CCD pixel summing -CCDSEC = '[1:2048,1:4096]' / CCD section -AMPSEC = '[1:2048,4096:1]' / Amplifier section -DETSEC = '[1:2048,4097:8192]' / Detector section - -ATM1_1 = 1. / CCD to amplifier transformation -ATM2_2 = -1. / CCD to amplifier transformation -ATV1 = 0. / CCD to amplifier transformation -ATV2 = 4097. / CCD to amplifier transformation -LTM1_1 = 1.0 / CCD to image transformation -LTM2_2 = 1.0 / CCD to image transformation -DTM1_1 = 1. / CCD to detector transformation -DTM2_2 = 1. / CCD to detector transformation -DTV1 = 0. / CCD to detector transformation -DTV2 = 4096. / CCD to detector transformation - -WCSASTRM= 'kp09m.19980909T031418 (Tr 37 V Mosaic) by L. Davis 1998-09-09' / WCS -WCSDIM = 2 / WCS dimensionality -CTYPE1 = 'RA---TNX' / Coordinate type -CTYPE2 = 'DEC--TNX' / Coordinate type -CRVAL1 = 110.52095558563 / Coordinate reference value -CRVAL2 = 55.842849490386 / Coordinate reference value -CRPIX1 = 4189.77390083542 / Coordinate reference pixel -CRPIX2 = -30.0894072403876 / Coordinate reference pixel -CD1_1 = -7.5733524638274E-7 / Coordinate matrix -CD2_1 = -1.1748235187739E-4 / Coordinate matrix -CD1_2 = 1.17677003379415E-4 / Coordinate matrix -CD2_2 = -1.2623022560872E-6 / Coordinate matrix -WAT0_001= 'system=image' / Coordinate system -WAT1_001= 'wtype=tnx axtype=ra lngcor = "3. 4. 4. 2. 0.005280549145776419 0.488' -WAT1_002= '7181432338267 0.2464122630921897 0.4920677651238937 -0.23529018838' -WAT1_003= '0298 0.004720134828570101 -0.001121960789613695 -0.01414958280730338' -WAT1_004= ' 0.01246754057675834 1.048124909467771E-4 0.007168575568475281 -0.02' -WAT1_005= '778217836490202 -0.01675668830707639 0.02500648596542957 "' -WAT2_001= 'wtype=tnx axtype=dec latcor = "3. 4. 4. 2. 0.005280549145776419 0.48' -WAT2_002= '87181432338267 0.2464122630921897 0.4920677651238937 0.1531926820' -WAT2_003= '595278 -0.002539369349529043 6.454692689700324E-4 4.863689582871599E-' -WAT2_004= '4 0.003549715563706861 -0.002061136945766966 -0.01644646641299351 0.' -WAT2_005= '009061645978984397 0.005570842598401512 -0.02240395721775152 "' -XTALKCOR= '03-Oct-2000 21:33:16 No crosstalk correction' -TRIM = 'Oct 3 21:34 Trim is [1:2048,1:4096]' -FIXPIX = 'Oct 3 21:35 Pixel mask is mscdb$noao/CCDMosaThin1/bpm_im5' -OVERSCAN= 'Oct 3 21:34 Overscan is [2063:2112,1:4096], mean 993.5216' -ZEROCOR = 'Oct 3 21:35 Zero is Zeromed[im5]' -FLATCOR = 'Oct 3 21:35 Flat is FlatR.fits[im5], scale 5081.475' -CCDMEAN = 255.7904 -CCDMEANT= 655076137 -CCDPROC = 'Oct 3 21:35 CCD processing done' -CHIPNUM = 5 -FZEROPT = 22.040344 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -END diff --git a/ast/ast_tester/tsc.attr b/ast/ast_tester/tsc.attr deleted file mode 100644 index 496403c..0000000 --- a/ast/ast_tester/tsc.attr +++ /dev/null @@ -1 +0,0 @@ -border=1 diff --git a/ast/ast_tester/tsc.box b/ast/ast_tester/tsc.box deleted file mode 100644 index 45cc65e..0000000 --- a/ast/ast_tester/tsc.box +++ /dev/null @@ -1 +0,0 @@ -1 1 1600 1600 diff --git a/ast/ast_tester/tsc.head b/ast/ast_tester/tsc.head deleted file mode 100644 index e41aefb..0000000 --- a/ast/ast_tester/tsc.head +++ /dev/null @@ -1,116 +0,0 @@ -SIMPLE = T -BITPIX = -32 / IEEE (big-endian) 32-bit floating point data -NAXIS = 2 -NAXIS1 = 1600 -NAXIS2 = 1600 -BUNIT = 'JY/BEAM ' -CTYPE1 = 'RA---TSC' -CRPIX1 = 1000 -CDELT1 = -3.666666666667E-01 -CRVAL1 = 0.000000000000E+00 -CTYPE2 = 'DEC--TSC' -CRPIX2 = 800 -CDELT2 = 3.666666666667E-01 -CRVAL2 = -9.000000000000E+01 -LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole -LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole -EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates -BMAJ = 2.399999936422E-01 / Beam major axis in degrees -BMIN = 2.399999936422E-01 / Beam minor axis in degrees -BPA = 0.000000000000E+00 / Beam position angle in degrees -RESTFREQ= 1.420405750000E+09 / Line rest frequency, Hz -HISTORY Parkes Multibeam continuum map -HISTORY Formed on Mon 2004/02/09 02:23:02 GMT by "pksgridzilla" which was -HISTORY compiled on Feb 9 2004 12:08:02 (local time) within -HISTORY AIPS++ version 19.405.00 dated . -HISTORY Polarization mode: A and B aggregated -HISTORY Gridding parameters: -HISTORY Method: WGTMED -HISTORY Clip fraction: 0.000 -HISTORY Tsys weighting: applied -HISTORY Beam weight order: 1 -HISTORY Beam FWHM: 14.4 arcmin -HISTORY Beam normalization: applied -HISTORY Smoothing kernel type: TOP-HAT -HISTORY Kernel FWHM: 12.0 arcmin -HISTORY Cutoff radius: 6.0 arcmin -HISTORY Beam RSS cutoff: 0.0 -HISTORY Input data sets: -HISTORY 97-10-09_0356_193558-66_206a.sdfits -HISTORY 97-10-12_0142_182123-66_193a.sdfits -HISTORY 97-10-12_0151_182707-66_194a.sdfits -HISTORY 97-10-12_0200_183252-66_195a.sdfits -HISTORY 97-11-07_0510_183836-66_196a.sdfits -HISTORY 97-11-07_0519_184420-66_197a.sdfits -HISTORY 97-11-07_0528_185004-66_198a.sdfits -HISTORY 97-11-07_0537_185548-66_199a.sdfits -HISTORY 97-11-07_0546_190132-66_200a.sdfits -HISTORY 97-11-07_0556_190717-66_201a.sdfits -HISTORY 97-11-07_0645_191301-66_202a.sdfits -HISTORY 97-11-07_0654_191845-66_203a.sdfits -HISTORY 97-11-07_0703_192429-66_204a.sdfits -HISTORY 97-11-07_0712_193013-66_205a.sdfits -HISTORY 97-11-07_0724_194142-66_207a.sdfits -HISTORY 97-11-18_0256_193815-66_206c.sdfits -HISTORY 97-11-18_0306_194359-66_207c.sdfits -HISTORY 97-11-19_0447_182341-66_193c.sdfits -HISTORY 97-11-19_0456_182925-66_194c.sdfits -HISTORY 97-11-19_0507_190350-66_200c.sdfits -HISTORY 97-11-19_0516_190934-66_201c.sdfits -HISTORY 97-11-19_0525_191519-66_202c.sdfits -HISTORY 97-11-19_0534_192103-66_203c.sdfits -HISTORY 97-11-19_0544_192647-66_204c.sdfits -HISTORY 97-11-19_0553_193231-66_205c.sdfits -HISTORY 97-11-19_0602_183509-66_195c.sdfits -HISTORY 97-11-19_0612_184053-66_196c.sdfits -HISTORY 97-11-19_0622_184638-66_197c.sdfits -HISTORY 97-11-19_0631_185222-66_198c.sdfits -HISTORY 97-11-19_0640_185806-66_199c.sdfits -HISTORY 98-03-24_2107_193706-66_206b.sdfits -HISTORY 98-03-24_2116_194251-66_207b.sdfits -HISTORY 98-03-25_2020_190826-66_201b.sdfits -HISTORY 98-03-25_2029_191410-66_202b.sdfits -HISTORY 98-03-25_2038_191954-66_203b.sdfits -HISTORY 98-03-25_2047_192538-66_204b.sdfits -HISTORY 98-03-25_2056_193122-66_205b.sdfits -HISTORY 98-03-26_2048_190459-66_200d.sdfits -HISTORY 98-03-27_2034_191627-66_202d.sdfits -HISTORY 98-03-27_2043_192212-66_203d.sdfits -HISTORY 98-03-27_2052_192756-66_204d.sdfits -HISTORY 98-03-27_2102_193340-66_205d.sdfits -HISTORY 98-03-27_2111_193924-66_206d.sdfits -HISTORY 98-03-27_2120_194508-66_207d.sdfits -HISTORY 98-03-27_2130_191043-66_201d.sdfits -HISTORY 98-05-10_2123_182232-66_193b.sdfits -HISTORY 98-05-10_2133_182816-66_194b.sdfits -HISTORY 98-05-10_2142_183400-66_195b.sdfits -HISTORY 98-05-10_2151_183945-66_196b.sdfits -HISTORY 98-05-10_2200_184529-66_197b.sdfits -HISTORY 98-05-10_2209_185113-66_198b.sdfits -HISTORY 98-05-10_2219_185657-66_199b.sdfits -HISTORY 98-05-10_2228_190241-66_200b.sdfits -HISTORY 98-05-13_2132_182450-66_193d.sdfits -HISTORY 98-05-13_2151_183034-66_194d.sdfits -HISTORY 98-05-13_2200_183618-66_195d.sdfits -HISTORY 98-05-13_2210_184202-66_196d.sdfits -HISTORY 98-05-13_2219_184746-66_197d.sdfits -HISTORY 98-05-13_2228_185331-66_198d.sdfits -HISTORY 98-05-13_2237_185915-66_199d.sdfits -HISTORY 98-05-25_1711_182559-66_193e.sdfits -HISTORY 98-05-25_1720_183143-66_194e.sdfits -HISTORY 98-05-25_1729_183727-66_195e.sdfits -HISTORY 98-05-25_1738_184311-66_196e.sdfits -HISTORY 98-05-25_1747_184855-66_197e.sdfits -HISTORY 98-05-25_1756_185439-66_198e.sdfits -HISTORY 98-05-25_1806_190024-66_199e.sdfits -HISTORY 98-05-25_1815_190608-66_200e.sdfits -HISTORY 98-05-25_1824_191152-66_201e.sdfits -HISTORY 98-05-25_1833_191736-66_202e.sdfits -HISTORY 98-05-25_1842_192320-66_203e.sdfits -HISTORY 98-05-25_1851_192905-66_204e.sdfits -HISTORY 98-05-25_1901_193449-66_205e.sdfits -HISTORY 98-05-25_1910_194033-66_206e.sdfits -HISTORY 98-05-25_1919_194617-66_207e.sdfits -HISTORY Original FITS filename "1904-66_TSC.continuum.fits". -HISTORY Noise level of continuum map: 61 mJy (RMS) -END diff --git a/ast/ast_tester/wcsconverter.f b/ast/ast_tester/wcsconverter.f deleted file mode 100644 index 9af2e30..0000000 --- a/ast/ast_tester/wcsconverter.f +++ /dev/null @@ -1,222 +0,0 @@ - PROGRAM WCSCONVERTER - -* Usage: -* WCSCONVERTER - -* Description: -* Reads a FrameSet from "in file" (as a FITS header if possible, -* otherwise as an AST dump of a FrameSet), and writes out the -* FrameSet to "out file" using the specified encoding. - -* Parameters: -* in file -* A text file containing fits headers or an AST dump of a FrameSet. -* encoding -* The name of a FITS encoding (e.g. "FITS-WCS", "NATIVE", etc), or -* "AST". -* out file -* The output file. Contains an AST dump of the FrameSet if -* "encoding" is "AST", or a set of FITS header cards otherwise. -* attrs -* A list of attribute settings to apply to the FitsChan before -* reading the input headers. - - - IMPLICIT NONE - INCLUDE 'AST_PAR' - EXTERNAL SOURCE, SINK - - INTEGER STATUS, FC, OBJECT, IARGC, CHAN, CHR_LEN, OC - CHARACTER FILE*80, OFILE*80, LINE*255, ENCODING*50 - CHARACTER ATTRS*200 - LOGICAL CDM - - STATUS = 0 -* -* Check command line arguments have been supplied. -* - IF( IARGC() .LT. 3 ) THEN - WRITE(*,*) 'Usage: wcsconverter '// - : ' ' - RETURN - END IF - -* -* Use object caching to minimise allocation of new memory -* - OC = AST_TUNE( 'ObjectCaching', 1, STATUS ) - IF( OC .NE. 0 ) THEN - WRITE(*,'(A,I6)') 'Default ObjectCaching VALUE is ',OC - END IF - - IF( AST_TUNE( 'ObjectCaching', AST__TUNULL, STATUS ) .NE. 1 ) THEN - WRITE(*,'(A,I6)') 'Set ObjectCaching VALUE is ',OC - END IF - -* -* Create a FitsChan to store the FITS headers. -* - FC = AST_FITSCHAN( AST_NULL, AST_NULL, ' ', STATUS ) - -* -* Apply any attribute settings to the FitsChan. -* - IF( IARGC() .EQ. 4 ) THEN - CALL GETARG( 4, ATTRS ) - CALL AST_SET( FC, ATTRS, STATUS ) - ELSE - ATTRS = ' ' - END IF - -* -* Open the input text file. -* - CALL GETARG( 1, FILE ) - OPEN( UNIT=10, FILE=FILE, STATUS='OLD' ) - -* -* Read each line out of the text file and store it in the FitsChan. -* - CALL ERR_MARK - DO WHILE( .TRUE. ) - READ( 10, '(A)', END = 10 ) LINE - CALL AST_PUTFITS( FC, LINE, 0, STATUS ) - END DO - - 10 CLOSE( 10 ) - -* -* Set the value of CDMatrix, unless it has already been set. -* - IF( .NOT. AST_TEST( FC, 'CDMATRIX', STATUS ) ) THEN - CDM = AST_GETL( FC, 'CDMATRIX', STATUS ) - CALL AST_SETL( FC, 'CDMATRIX', CDM, status ) - END IF - -* -* Attempt to read an Object form the FitsChan. -* - CALL AST_CLEAR( FC, 'CARD', STATUS ) - OBJECT = AST_READ( FC, STATUS ) - - IF( STATUS .NE. 0 ) CALL ERR_ANNUL( STATUS ) - CALL ERR_RLSE - -* If no object was read, attempt to read an object from the text file as -* an AST dump. - IF( OBJECT .EQ. AST__NULL ) THEN - CALL AST_ANNUL( FC, STATUS ) - OPEN( UNIT=10, FILE=FILE, STATUS='OLD' ) - CHAN = AST_CHANNEL( SOURCE, AST_NULL, ' ', STATUS ) - OBJECT = AST_READ( CHAN, STATUS ) - CALL AST_ANNUL( CHAN, STATUS ) - CLOSE( 10 ) - END IF - -* -* Abort if no object was read. -* - IF( OBJECT .EQ. AST__NULL ) THEN - WRITE(*,*) 'wcsconverter: no WCS could be read from ', - : file( : chr_len( file ) ) - RETURN - - -* -* Otherwise write out the object using the specified encoding. -* - ELSE - CALL GETARG( 3, OFILE ) - CALL DELETEFILE( OFILE ) - - CALL GETARG( 2, ENCODING ) - IF( ENCODING .EQ. 'AST' .OR. ENCODING .EQ. 'ast' ) THEN - OPEN( UNIT=10, FILE=OFILE, STATUS='NEW' ) - CHAN = AST_CHANNEL( AST_NULL, SINK, ' ', STATUS ) - IF( AST_WRITE( CHAN, OBJECT, STATUS ) .NE. 1 ) THEN - WRITE(*,*) 'wcsconverter: WCS read from ', - : file( : chr_len( file ) ),' could not be '// - : 'converted to ', - : encoding( : chr_len(encoding ) ),' format.' - END IF - CALL AST_ANNUL( CHAN, STATUS ) - CLOSE( 10 ) - - ELSE - OPEN( UNIT=10, FILE=OFILE, STATUS='NEW' ) - IF( FC .EQ. AST__NULL ) THEN - FC = AST_FITSCHAN( AST_NULL, AST_NULL, ATTRS, STATUS ) - END IF - CALL AST_SETC( FC, 'ENCODING', ENCODING, STATUS ) - CALL AST_CLEAR( FC, 'CARD', STATUS ) - - IF( AST_WRITE( FC, OBJECT, STATUS ) .NE. 1 ) THEN - WRITE(*,*) 'wcsconverter: WCS read from ', - : file( : chr_len( file ) ),' could not be '// - : 'converted to ', - : encoding( : chr_len(encoding ) ),' format.' - ELSE - CALL AST_CLEAR( FC, 'CARD', STATUS ) - DO WHILE( AST_FINDFITS( FC, '%f', LINE, .TRUE., - : STATUS ) ) - WRITE(10,'(A)') LINE( : 80 ) - END DO - END IF - CLOSE( 10 ) - - CALL AST_ANNUL( FC, STATUS ) - - - END IF - CALL AST_ANNUL( OBJECT, STATUS ) - END IF - - - END - - -* -* Delete a file if it exists. -* - SUBROUTINE DELETEFILE( FILNAM ) - IMPLICIT NONE - - CHARACTER FILNAM*(*) - LOGICAL EXISTS - - INQUIRE ( FILE = FILNAM, - : EXIST = EXISTS ) - - IF( EXISTS ) THEN - OPEN ( UNIT=10, FILE=FILNAM, STATUS='OLD' ) - CLOSE ( 10, STATUS='DELETE' ) - END IF - - END - - -* -* SOURCE FUNCTION FOR AST_CHANNEL. -* - SUBROUTINE SOURCE( STATUS ) - IMPLICIT NONE - INTEGER STATUS - CHARACTER BUFFER*200 - READ( 10, '(A)', END=99 ) BUFFER - CALL AST_PUTLINE( BUFFER, LEN( BUFFER ), STATUS ) - RETURN - 99 CALL AST_PUTLINE( BUFFER, -1, STATUS ) - END - -* -* SINK FUNCTION FOR AST_CHANNEL. -* - SUBROUTINE SINK( STATUS ) - IMPLICIT NONE - INTEGER STATUS, L - CHARACTER BUFFER*200 - - CALL AST_GETLINE( BUFFER, L, STATUS ) - IF( L .GT. 0 ) WRITE( 10, '(A)' ) BUFFER( : L ) - - END diff --git a/ast/ast_tester/zpn.attr b/ast/ast_tester/zpn.attr deleted file mode 100644 index d74badf..0000000 --- a/ast/ast_tester/zpn.attr +++ /dev/null @@ -1 +0,0 @@ -tol=0.0001 diff --git a/ast/ast_tester/zpn.box b/ast/ast_tester/zpn.box deleted file mode 100644 index ee14a3a..0000000 --- a/ast/ast_tester/zpn.box +++ /dev/null @@ -1 +0,0 @@ -1 1 200.0 200.0 diff --git a/ast/ast_tester/zpn.head b/ast/ast_tester/zpn.head deleted file mode 100644 index a5e90af..0000000 --- a/ast/ast_tester/zpn.head +++ /dev/null @@ -1,136 +0,0 @@ -SIMPLE = T -BITPIX = -32 / IEEE (big-endian) 32-bit floating point data -NAXIS = 2 -NAXIS1 = 200 -NAXIS2 = 200 -BUNIT = 'JY/BEAM ' -CTYPE1 = 'RA---ZPN' -CRPIX1 = 100 -CDELT1 = -6.666666666667E-02 -CRVAL1 = 0.000000000000E+00 -CTYPE2 = 'DEC--ZPN' -CRPIX2 = 100 -CDELT2 = 6.666666666667E-02 -CRVAL2 = -9.000000000000E+01 -LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole -LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole -PV2_0 = 10.000000000000E-02 / Projection parameter 0 -PV2_1 = 9.750000000000E-01 / Projection parameter 1 -COMMENT PV2_2 = -8.070000000000E-01 / Projection parameter 2 -COMMENT PV2_3 = 3.370000000000E-01 / Projection parameter 3 -COMMENT PV2_4 = -6.500000000000E-02 / Projection parameter 4 -COMMENT PV2_5 = 1.000000000000E-02 / Projection parameter 5 -COMMENT PV2_6 = 3.000000000000E-03 / Projection parameter 6 -COMMENT PV2_7 = -1.000000000000E-03 / Projection parameter 7 -COMMENT PV2_8 = 0.000000000000E+00 / Projection parameter 8 -COMMENT PV2_9 = 0.000000000000E+00 / Projection parameter 9 -COMMENT PV2_10 = 0.000000000000E+00 / Projection parameter 10 -COMMENT PV2_11 = 0.000000000000E+00 / Projection parameter 11 -COMMENT PV2_12 = 0.000000000000E+00 / Projection parameter 12 -COMMENT PV2_13 = 0.000000000000E+00 / Projection parameter 13 -COMMENT PV2_14 = 0.000000000000E+00 / Projection parameter 14 -COMMENT PV2_15 = 0.000000000000E+00 / Projection parameter 15 -COMMENT PV2_16 = 0.000000000000E+00 / Projection parameter 16 -COMMENT PV2_17 = 0.000000000000E+00 / Projection parameter 17 -COMMENT PV2_18 = 0.000000000000E+00 / Projection parameter 18 -COMMENT PV2_19 = 0.000000000000E+00 / Projection parameter 19 -EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates -BMAJ = 2.399999936422E-01 / Beam major axis in degrees -BMIN = 2.399999936422E-01 / Beam minor axis in degrees -BPA = 0.000000000000E+00 / Beam position angle in degrees -RESTFREQ= 1.420405750000E+09 / Line rest frequency, Hz -HISTORY Parkes Multibeam continuum map -HISTORY Formed on Mon 2004/02/09 01:38:20 GMT by "pksgridzilla" which was -HISTORY compiled on Feb 9 2004 12:08:02 (local time) within -HISTORY AIPS++ version 19.405.00 dated . -HISTORY Polarization mode: A and B aggregated -HISTORY Gridding parameters: -HISTORY Method: WGTMED -HISTORY Clip fraction: 0.000 -HISTORY Tsys weighting: applied -HISTORY Beam weight order: 1 -HISTORY Beam FWHM: 14.4 arcmin -HISTORY Beam normalization: applied -HISTORY Smoothing kernel type: TOP-HAT -HISTORY Kernel FWHM: 12.0 arcmin -HISTORY Cutoff radius: 6.0 arcmin -HISTORY Beam RSS cutoff: 0.0 -HISTORY Input data sets: -HISTORY 97-10-09_0356_193558-66_206a.sdfits -HISTORY 97-10-12_0142_182123-66_193a.sdfits -HISTORY 97-10-12_0151_182707-66_194a.sdfits -HISTORY 97-10-12_0200_183252-66_195a.sdfits -HISTORY 97-11-07_0510_183836-66_196a.sdfits -HISTORY 97-11-07_0519_184420-66_197a.sdfits -HISTORY 97-11-07_0528_185004-66_198a.sdfits -HISTORY 97-11-07_0537_185548-66_199a.sdfits -HISTORY 97-11-07_0546_190132-66_200a.sdfits -HISTORY 97-11-07_0556_190717-66_201a.sdfits -HISTORY 97-11-07_0645_191301-66_202a.sdfits -HISTORY 97-11-07_0654_191845-66_203a.sdfits -HISTORY 97-11-07_0703_192429-66_204a.sdfits -HISTORY 97-11-07_0712_193013-66_205a.sdfits -HISTORY 97-11-07_0724_194142-66_207a.sdfits -HISTORY 97-11-18_0256_193815-66_206c.sdfits -HISTORY 97-11-18_0306_194359-66_207c.sdfits -HISTORY 97-11-19_0447_182341-66_193c.sdfits -HISTORY 97-11-19_0456_182925-66_194c.sdfits -HISTORY 97-11-19_0507_190350-66_200c.sdfits -HISTORY 97-11-19_0516_190934-66_201c.sdfits -HISTORY 97-11-19_0525_191519-66_202c.sdfits -HISTORY 97-11-19_0534_192103-66_203c.sdfits -HISTORY 97-11-19_0544_192647-66_204c.sdfits -HISTORY 97-11-19_0553_193231-66_205c.sdfits -HISTORY 97-11-19_0602_183509-66_195c.sdfits -HISTORY 97-11-19_0612_184053-66_196c.sdfits -HISTORY 97-11-19_0622_184638-66_197c.sdfits -HISTORY 97-11-19_0631_185222-66_198c.sdfits -HISTORY 97-11-19_0640_185806-66_199c.sdfits -HISTORY 98-03-24_2107_193706-66_206b.sdfits -HISTORY 98-03-24_2116_194251-66_207b.sdfits -HISTORY 98-03-25_2020_190826-66_201b.sdfits -HISTORY 98-03-25_2029_191410-66_202b.sdfits -HISTORY 98-03-25_2038_191954-66_203b.sdfits -HISTORY 98-03-25_2047_192538-66_204b.sdfits -HISTORY 98-03-25_2056_193122-66_205b.sdfits -HISTORY 98-03-26_2048_190459-66_200d.sdfits -HISTORY 98-03-27_2034_191627-66_202d.sdfits -HISTORY 98-03-27_2043_192212-66_203d.sdfits -HISTORY 98-03-27_2052_192756-66_204d.sdfits -HISTORY 98-03-27_2102_193340-66_205d.sdfits -HISTORY 98-03-27_2111_193924-66_206d.sdfits -HISTORY 98-03-27_2120_194508-66_207d.sdfits -HISTORY 98-03-27_2130_191043-66_201d.sdfits -HISTORY 98-05-10_2123_182232-66_193b.sdfits -HISTORY 98-05-10_2133_182816-66_194b.sdfits -HISTORY 98-05-10_2142_183400-66_195b.sdfits -HISTORY 98-05-10_2151_183945-66_196b.sdfits -HISTORY 98-05-10_2200_184529-66_197b.sdfits -HISTORY 98-05-10_2209_185113-66_198b.sdfits -HISTORY 98-05-10_2219_185657-66_199b.sdfits -HISTORY 98-05-10_2228_190241-66_200b.sdfits -HISTORY 98-05-13_2132_182450-66_193d.sdfits -HISTORY 98-05-13_2151_183034-66_194d.sdfits -HISTORY 98-05-13_2200_183618-66_195d.sdfits -HISTORY 98-05-13_2210_184202-66_196d.sdfits -HISTORY 98-05-13_2219_184746-66_197d.sdfits -HISTORY 98-05-13_2228_185331-66_198d.sdfits -HISTORY 98-05-13_2237_185915-66_199d.sdfits -HISTORY 98-05-25_1711_182559-66_193e.sdfits -HISTORY 98-05-25_1720_183143-66_194e.sdfits -HISTORY 98-05-25_1729_183727-66_195e.sdfits -HISTORY 98-05-25_1738_184311-66_196e.sdfits -HISTORY 98-05-25_1747_184855-66_197e.sdfits -HISTORY 98-05-25_1756_185439-66_198e.sdfits -HISTORY 98-05-25_1806_190024-66_199e.sdfits -HISTORY 98-05-25_1815_190608-66_200e.sdfits -HISTORY 98-05-25_1824_191152-66_201e.sdfits -HISTORY 98-05-25_1833_191736-66_202e.sdfits -HISTORY 98-05-25_1842_192320-66_203e.sdfits -HISTORY 98-05-25_1851_192905-66_204e.sdfits -HISTORY 98-05-25_1901_193449-66_205e.sdfits -HISTORY 98-05-25_1910_194033-66_206e.sdfits -HISTORY 98-05-25_1919_194617-66_207e.sdfits -HISTORY Original FITS filename "1904-66_ZPN.continuum.fits". -HISTORY Noise level of continuum map: 61 mJy (RMS) -END diff --git a/ast/ast_tester/zpx.attr b/ast/ast_tester/zpx.attr deleted file mode 100644 index f073d5c..0000000 --- a/ast/ast_tester/zpx.attr +++ /dev/null @@ -1 +0,0 @@ -Grid=1,style(grid1)=2,size(textlab2)=2 diff --git a/ast/ast_tester/zpx.head b/ast/ast_tester/zpx.head deleted file mode 100644 index a69353a..0000000 --- a/ast/ast_tester/zpx.head +++ /dev/null @@ -1,153 +0,0 @@ -SIMPLE = T / Fits standard -BITPIX = 16 / Bits per pixel -NAXIS = 2 / Number of axes -NAXIS1 = 2048 / Axis length -NAXIS2 = 4100 / Axis length -BSCALE = 1.145669E0 / REAL = TAPE*BSCALE + BZERO -BZERO = 3.793600E4 / -EXTEND = F / File may contain extensions -IRAF-TLM= '14:31:18 (18/05/1999)' / Time of last modification -OBJECT = 'VIRGO311' / -ORIGIN = 'KPNO-IRAF' / -DATE = '19/05/99' / -IRAFNAME= 'iraf3432b' / NAME OF IRAF IMAGE FILE -IRAF-MAX= 7.546810E4 / DATA MAX -IRAF-MIN= 4.038996E2 / DATA MIN -IRAF-BPX= 64 / DATA BITS/PIXEL -IRAFTYPE= 'DOUBLE ' / PIXEL TYPE -ORIGIN = 'NOAO-IRAF FITS Image Kernel Aug 1 1997' / FITS file originator -DATE = '18/05/99' / Date FITS file was generated -RUN = 158500 / Run number -SYSVER = 's7-1 ' / Version of observing system -OBSERVAT= 'LAPALMA ' / Name of observatory (IRAF style) -OBSTYPE = 'TARGET ' / Type of observation, eg. ARC -IMAGETYP= 'TARGET ' / Type of observation, eg. ARC -CTYPE1 = 'RA---ZPX' / Type of coordinate on axis 1 -CTYPE2 = 'DEC--ZPX' / Type of coordinate on axis 2 -CRPIX1 = -319.077517318151 / Reference pixel on axis 1 -CRPIX2 = 3035.64982635572 / Reference pixel on axis 2 -CRVAL1 = 187.8708 / Value at ref. pixel on axis 1 -CRVAL2 = 12.40001 / Value at ref. pixel on axis 2 -CD1_1 = -1.5845078730445E-6 / Transformation matrix -CD1_2 = -9.2521190078722E-5 / Transformation matrix -CD2_1 = -9.2538856101295E-5 / Transformation matrix -CD2_2 = 1.63254208024377E-6 / Transformation matrix -LATITUDE= 28.762000 / Telescope latitude (degrees), +28:45:43.2 -LONGITUD= 17.877639 / Telescope longitude (degrees), +17:52:39.5 -HEIGHT = 2348 / [m] Height above sea level. -SLATEL = 'LPO2.5 ' / Telescope name known to SLALIB -TELESCOP= 'INT ' / 2.5m Isaac Newton Telescope -TELSTAT = 'GUIDING ' / Telescope status: TRACKING or GUIDING normally. -RA = ' 12:31:28.998' / RA (187.8708261822271200 degrees) -DEC = '+12:24:00.04' / DEC ( 12.4000109941873690 degrees) -EQUINOX = '2000. ' / Equinox of coordinates -RADECSYS= 'FK5 ' / mean place new (after the 1976 IAU) system -XAPNOM = 0.0000000000 / nominal aperture in x (0.00 arcsec) -YAPNOM = 0.0000000000 / nominal aperture in y (0.00 arcsec) -XAPOFF = 0.0000000000 / total aperture offset in x (0.00 arcsec) -YAPOFF = 0.0000000000 / total aperture offset in y (0.00 arcsec) -MJD-OBS = 51277.9941545 / Modified Julian Date of midtime of observation -JD = 2451278.4941545 / Julian Date of midtime of observation -STSTART = ' 11:44:54.8' / Local sidereal time at start of observation -ST = ' 11:44:54.8' / Local sidereal time at start of observation -AZIMUTH = 148.155505 / Mean azimuth of observation (degrees) -ZD = 18.907242 / Mean zenith-distance of observation (degrees) -FSTATION= 'PRIME ' / Focal station of observation -PLATESCA= 6.856013 / [d/m] Platescale ( 24.68arcsec/mm) -TELFOCUS= 0.045998 / Telescope focus (metres) -ROTTRACK= T / Rotator always tracks sky on equatorial mount -ROTSKYPA= 179.899970 / Turntable position angle (degrees) -PARANGLE= 331.834373 / Parallactic angle at observation midpoint -VIGNETTE= F / Can we see out? -DOMEAZ = 147.089879 / Mean dome azimuth during observation -AIRMASS = 1.056698 / Effective mean airmass -TEMPTUBE= 9.005279 / Truss Temperature (degrees Celsius) -CAT-NAME= 'VIRGO311' / Target input-catalogue name -CAT-RA = ' 12:31:29.000' / Target Right Ascension -CAT-DEC = '+12:24:00.00' / Target Declination -CAT-EQUI= 'J2000.00' / Equinox of target coordinates -CAT-EPOC= 2000.00 / Target epoch of proper motions -PM-RA = 0.000000 / Target proper-motion RA (sec time/year) -PM-DEC = 0.000000 / Target proper-motion (sec arc/year) -PARALLAX= 0.000000 / Target Parallax (arcsec) -RADVEL = 0.000000 / Target radial velocity (km/s) -RATRACK = 0.000000 / Differential-tracking rate RA (arcsec/sec) -DECTRACK= 0.000000 / Differential-tracking rate Dec (arcsec/sec) -INSTRUME= 'WFC ' / INT wide-field camera is in use. -WFFPOS = 1 / Position-number of deployed filter -WFFBAND = 'B ' / Waveband of filter -WFFPSYS = 'Kitt Peak ' / Photometric system of filter -WFFID = '210 ' / Unique identifier of filter -SECPPIX = 0.333 / Arcseconds per pixel -UTSTART = '23:45:20.1 ' / UTC of start of observation -ELAPSED = 749.340 / Length of observation including pauses -DARKTIME= 749.340 / Length of observation including pauses -EXPOSED = 749.340 / Length of observation excluding pauses -EXPTIME = 749.340 / Length of observation excluding pauses -DATE-OBS= '1999-04-09 ' / UTC date start of observation -DETECTOR= 'MOS1 ' / Name of the detector -PREFLASH= 0.000 / Length of Preflash in seconds -BUNIT = 'ADU ' / Unit of the array of image data -GAIN = 2.900 / Electrons per ADU -READNOIS= 12.000 / Readout noise in electrons per pix -CCDSPEED= 'TURBO ' / Readout speed of the CCD -CCDNCHIP= 1 / Number of CCDs in this head -CCDCHIP = 1 / Head number of this CCD -CCDTYPE = 'EEV42 ' / Type of CCD used in this detector -CCDXSIZE= 2148 / X Size in pixels of digitised frame -CCDYSIZE= 4128 / Y Size in pixels of digitised frame -CCDXIMSI= 2048 / X Size of useful imaging area -CCDYIMSI= 4100 / Y Size of useful imaging area -CCDXIMST= 50 / X Start pixel of useful imaging area -CCDYIMST= 0 / Y Start pixel of useful imaging area -CCDWMODE= F / True is windows are enabled -CCDWXO1 = 0 / Offset of window 1 in X -CCDWYO1 = 0 / Offset of window 1 in Y -CCDWXS1 = 0 / Size of window 1 in X -CCDWYS1 = 0 / Size of window 1 in Y -CCDWXO2 = 0 / Offset of window 2 in X -CCDWYO2 = 0 / Offset of window 2 in Y -CCDWXS2 = 0 / Size of window 2 in X -CCDWYS2 = 0 / Size of window 2 in Y -CCDWXO3 = 0 / Offset of window 3 in X -CCDWYO3 = 0 / Offset of window 3 in Y -CCDWXS3 = 0 / Size of window 3 in X -CCDWYS3 = 0 / Size of window 3 in Y -CCDWXO4 = 0 / Offset of window 4 in X -CCDWYO4 = 0 / Offset of window 4 in Y -CCDWXS4 = 0 / Size of window 4 in X -CCDWYS4 = 0 / Size of window 4 in Y -CCDXPIXE= 1.350000e-05 / Size in meters of the pixels, in X -CCDYPIXE= 1.350000e-05 / Size in meters of the pixels, in Y -CCDXBIN = 1 / Binning factor, in X -CCDYBIN = 1 / Binning factor, in Y -CCDSTEMP= 153 / Required temperature of CCD, in Kevlin -CCDATEMP= 154 / Actual temperature of CCD, in Kevlin -CHIPNAME= 'A5506-4 ' / Name of CCD chip -DASCHAN = 1 / DAS channel -WINSEC1 = '[0:0,0:0] ' / Readout window 1 -WINSEC2 = '[0:0,0:0] ' / Readout window 2 -WINSEC3 = '[0:0,0:0] ' / Readout window 3 -WINSEC4 = '[0:0,0:0] ' / Readout window 4 -HISTORY This is the end of the header written by the ING observing-system. -WAT0_001= 'system=image' -WAT1_001= 'wtype=zpx axtype=ra projp1=6.0 projp2=100.0 projp3=2059.8' -WAT2_001= 'wtype=zpx axtype=dec projp1=1.0 projp3=-1000.8' -WFCWCS = 'Done ' -IMDTOI = 'Done ' -WCSDIM = 2 -LTM1_1 = 1. -LTM2_2 = 1. -TRIM = 'May 18 13:12 Trim data section is [51:2098,1:4100]' -BP-FLAG = 'May 18 13:12 Bad pixel file is /home/jrl/wfcred/stds/A5506-4.bad' -BT-FLAG = 'May 18 13:12 Overscan section is [1:50,1:4128] with mean=1501.636' -BI-FLAG = 'May 18 13:12 Zero level correction image is /data/cass03a/was/mframe' -FF-FLAG = 'May 18 13:12 Flat field image is /data/cass03c/was/mframes/B_9269342' -ILLUMCOR= 'May 18 13:12 Illumination image is tmpill.pl with scale=0.9314932' -CCDSEC = '[51:2098,1:4100]' -LTV1 = -50. -CCDPROC = 'May 18 13:12 CCD processing done' -XIRMS = 0.3418021 -ETARMS = 0.2019652 -WFCREDVR= 'v0.1 ' -END diff --git a/ast/astbad.c b/ast/astbad.c deleted file mode 100644 index d79cdc3..0000000 --- a/ast/astbad.c +++ /dev/null @@ -1,181 +0,0 @@ -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ -#include "pointset.h" /* declaration of AST__BAD etc */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include - -/* Local Constants: */ -#define BUFF_LEN ( 2 * AST__DBL_DIG + 20 ) /* Buffer length */ -#define IEEE_DIG 17 /* Minimum number of digits required by - IEEE for conversion from binary to - string and back again to be an - identity. */ - -/* Prototypes for local functions */ -static void printdval( double ); -static void printfval( float ); - -/* Main function. */ -/* ============== */ -int main( int argc, char *argv[] ) { -/* -*+ -* Name: -* astbad - -* Purpose: -* Generate a string representing an AST floating point constant. - -* Invocation: -* astbad - -* Type: -* C program. - -* Description: -* This program writes a string to standard output containing -* a formatted decimal representation of a specified C floating point -* constant defined by AST. This is intended for use in defining these -* constants for use from languages other than C. -* -* The value written should contain sufficient decimal digits so -* that a routine that uses it to generate a value in another -* language will produce exactly the same value as a C program -* using the same macro. - -* Arguments: -* value = LITERAL -* The name of the constant to be printed: AST__BAD, AST__NAN or -* AST__NANF. If not supplied, AST__BAD is printed. - -* Copyright: -* Copyright (C) 2009-2011 Science & Technology Facilities Council. -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) -* TIMJ: Tim Jenness (JAC, Hawaii) - -* History: -* 18-NOV-1997 (RFWS); -* Original version. -* 24-OCT-2000 (DSB): -* Ensure that the number of digits used is at least the minimum -* required by IEEE for a conversion from binary to string and back -* to binary to be an identity. -* 31-MAR-2009 (TIMJ): -* Does not take any arguments so don't try to read arguments. -* 18-JAN-2011 (DSB): -* Extend to print other floating point constants as well as -* AST__BAD. -*- -*/ - -/* Local Variables; */ - const char *name; /* Pointer to name of constant to be printed */ - -/* Get the name of the constant to be printed. */ - if( argc > 1 ) { - name = argv[1]; - } else { - name = "AST__BAD"; - } - -/* Print it. */ - if( !strcmp( name, "AST__BAD" ) ) { - printdval( AST__BAD ); - - } else if( !strcmp( name, "AST__NAN" ) ) { - printdval( AST__NAN ); - - } else if( !strcmp( name, "AST__NANF" ) ) { - printfval( AST__NANF ); - -/* Issue an error message if the argument is unknown. */ - } else { - (void) fprintf( stderr, "astbad: Unknown constant requested: %s\n", - name ); - } - -/* Exit. */ - return 0; -} - - -/* Print a double precision value to standard output */ -static void printdval( double val ){ - -/* Local Variables: */ - char buff[ BUFF_LEN + 1 ]; /* Buffer for formatted string */ - double newval; /* Value read back from string */ - int digits; /* Number of digits of precision */ - -/* Vary the precision over a reasonable range to see how many decimal - digits are required. The initial number of digits is the larger of - AST__DBL_DIG and IEEE_DIG. */ - for ( digits = ( AST__DBL_DIG > IEEE_DIG )?AST__DBL_DIG:IEEE_DIG; - digits <= ( 2 * AST__DBL_DIG ); digits++ ) { - -/* Format the value using this precision and then read it back. */ - (void) sprintf( buff, "%.*G", digits, val ); - (void) sscanf( buff, "%lg", &newval ); - -/* Quit looping when the original value is read back. */ - if ( newval == val ) break; - } - -/* Write the value to standard output, with one extra digit for good - measure. */ - (void) printf( "%.*G\n", digits + 1, val ); -} - -/* Print a single precision value to standard output */ -static void printfval( float val ){ - -/* Local Variables: */ - char buff[ BUFF_LEN + 1 ]; /* Buffer for formatted string */ - float newval; /* Value read back from string */ - int digits; /* Number of digits of precision */ - -/* Vary the precision over a reasonable range to see how many decimal - digits are required. The initial number of digits is FLT_DIG. */ - for ( digits = FLT_DIG; digits <= ( 2 * FLT_DIG ); digits++ ) { - -/* Format the value using this precision and then read it back. */ - (void) sprintf( buff, "%.*G", digits, val ); - (void) sscanf( buff, "%g", &newval ); - -/* Quit looping when the original value is read back. */ - if ( newval == val ) break; - } - -/* Write the value to standard output, with one extra digit for good - measure. */ - (void) printf( "%.*G\n", digits + 1, val ); - -} - diff --git a/ast/axis.c b/ast/axis.c deleted file mode 100644 index 6f58b14..0000000 --- a/ast/axis.c +++ /dev/null @@ -1,3500 +0,0 @@ -/* -*class++ -* Name: -* Axis - -* Purpose: -* Store axis information. - -* Constructor Function: -* None. - -* Description: -* The Axis class is used to store information associated with a -* particular axis of a Frame. It is used internally by the AST -* library and has no constructor function. You should encounter it -c only within textual output (e.g. from astWrite). -f only within textual output (e.g. from AST_WRITE). - -* Inheritance: -* The Axis class inherits from the Object class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: B.S. Berry (Starlink) - -* History: -* 1-MAR-1996 (RFWS): -* Original version. -* 10-SEP-1996 (RFWS): -* Added I/O facilities. -* 11-SEP-1996 (RFWS): -* Added astAxisGap (written by DSB). -* 25-FEB-1998 (RFWS): -* Added astAxisUnformat. -* 29-AUG-2001 (DSB): -* Added AxisDistance and AxisOffset. -* 20-OCT-2002 (DSB): -* Added Top and Bottom attributes. -* 8-JAN-2003 (DSB): -* - Changed private InitVtab method to protected astInitAxisVtab -* method. -* - Include descriptive label for units string within a Dump. -* 24-JAN-2004 (DSB): -* - Added astAxisFields. -* - Added argument "fmt" to definition of AxisAbbrev. -* 3-FEB-2004 (DSB): -* - Added "log" formatting using the "&" flag character in the -* Format string. -* 15-SEP-2004 (DSB): -* - If a format string is set which includes a wildcard precision -* value (".*"), then use the Digits value to determine the precision -* to be used. -* - If the conversion code is of integer type (e.g. "%d") cast value -* to integer before printing. -* 2-FEB-2005 (DSB): -* - Avoid using astStore to allocate more storage than is supplied -* in the "data" pointer. This can cause access violations since -* astStore will then read beyond the end of the "data" area. -* 15-MAR-2005 (DSB): -* - Avoid exponents in log format labels which are close to zero but -* not quite zero. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 30-JUN-2006 (DSB): -* Guard against a null "str1" value in AxisAbbrev. -* 17-APR-2015 (DSB): -* Added astAxisCentre. -* 26-OCT-2016 (DSB): -* Added astAxisNormValues. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Axis - - -/* Header files. */ -/* ============= */ -#include "ast_err.h" /* Error code definitions */ - -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Object interface (parent class) */ -#include "pointset.h" /* Sets of coordinates (for AST__BAD) */ -#include "channel.h" /* I/O channels */ -#include "axis.h" /* Interface definition for this class */ -#include "unit.h" /* Definitions of physical units */ -#include "globals.h" /* Thread-safe global data access */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -/* Plain text equivalents. */ -static const char *log_txt = "10^"; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetDefaultFormat_Buff[ 0 ] = 0; \ - globals->AxisFormat_Buff[ 0 ] = 0; \ - globals->GetAxisNormUnit_Buff[ 0 ] = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Axis) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Axis,Class_Init) -#define class_vtab astGLOBAL(Axis,Class_Vtab) -#define getdefaultformat_buff astGLOBAL(Axis,GetDefaultFormat_Buff) -#define axisformat_buff astGLOBAL(Axis,AxisFormat_Buff) -#define getaxisnormunit_buff astGLOBAL(Axis,GetAxisNormUnit_Buff) -#define getattrib_buff astGLOBAL(Axis,GetAttrib_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getdefaultformat_buff[ AST__AXIS_GETDEFAULTFORMAT_BUFF_LEN + 1 ]; -static char axisformat_buff[ AST__AXIS_GETDEFAULTFORMAT_BUFF_LEN + 1 ]; -static char getaxisnormunit_buff[ AST__AXIS_GETAXISNORMUNIT_BUFF_LEN + 1 ]; -static char getattrib_buff[ AST__AXIS_GETATTRIB_BUFF_LEN + 1 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstAxisVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstAxis *astAxisId_( const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static const char *AxisAbbrev( AstAxis *, const char *, const char *, const char *, int * ); -static const char *AxisFormat( AstAxis *, double, int * ); -static int GetObjSize( AstObject *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetAxisFormat( AstAxis *, int * ); -static const char *GetAxisLabel( AstAxis *, int * ); -static const char *GetAxisSymbol( AstAxis *, int * ); -static const char *GetAxisUnit( AstAxis *, int * ); -static const char *GetAxisInternalUnit( AstAxis *, int * ); -static const char *GetAxisNormUnit( AstAxis *, int * ); -static const char *GetDefaultFormat( AstAxis *, int * ); -static char *ParseAxisFormat( const char *, int, int *, int *, int *, int *, int * ); -static double AxisDistance( AstAxis *, double, double, int * ); -static double AxisCentre( AstAxis *, double, double, int * ); -static double AxisGap( AstAxis *, double, int *, int * ); -static double AxisOffset( AstAxis *, double, double, int * ); -static int AxisFields( AstAxis *, const char *, const char *, int, char **, int *, double *, int * ); -static int AxisIn( AstAxis *, double, double, double, int, int * ); -static int AxisUnformat( AstAxis *, const char *, double *, int * ); -static int GetAxisDigits( AstAxis *, int * ); -static int GetAxisDirection( AstAxis *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestAxisDigits( AstAxis *, int * ); -static int TestAxisDirection( AstAxis *, int * ); -static int TestAxisFormat( AstAxis *, int * ); -static int TestAxisLabel( AstAxis *, int * ); -static int TestAxisSymbol( AstAxis *, int * ); -static int TestAxisUnit( AstAxis *, int * ); -static int TestAxisInternalUnit( AstAxis *, int * ); -static int TestAxisNormUnit( AstAxis *, int * ); -static void AxisNorm( AstAxis *, double *, int * ); -static void AxisNormValues( AstAxis *, int, int, double *, int * ); -static void AxisOverlay( AstAxis *, AstAxis *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearAxisDigits( AstAxis *, int * ); -static void ClearAxisDirection( AstAxis *, int * ); -static void ClearAxisFormat( AstAxis *, int * ); -static void ClearAxisLabel( AstAxis *, int * ); -static void ClearAxisSymbol( AstAxis *, int * ); -static void ClearAxisUnit( AstAxis *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetAxisDigits( AstAxis *, int, int * ); -static void SetAxisDirection( AstAxis *, int, int * ); -static void SetAxisFormat( AstAxis *, const char *, int * ); -static void SetAxisLabel( AstAxis *, const char *, int * ); -static void SetAxisSymbol( AstAxis *, const char *, int * ); -static void SetAxisUnit( AstAxis *, const char *, int * ); - -static double GetAxisTop( AstAxis *, int * ); -static int TestAxisTop( AstAxis *, int * ); -static void ClearAxisTop( AstAxis *, int * ); -static void SetAxisTop( AstAxis *, double, int * ); - -static double GetAxisBottom( AstAxis *, int * ); -static int TestAxisBottom( AstAxis *, int * ); -static void ClearAxisBottom( AstAxis *, int * ); -static void SetAxisBottom( AstAxis *, double, int * ); - - -/* Member functions. */ -/* ================= */ -static const char *AxisAbbrev( AstAxis *this, const char *fmt, - const char *str1, const char *str2, int *status ) { -/* -*+ -* Name: -* astAxisAbbrev - -* Purpose: -* Abbreviate a formatted Axis value by skipping leading fields. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* const char *astAxisAbbrev( AstAxis *this, const char *fmt, -* const char *str1, const char *str2 ) - -* Class Membership: -* Axis method. - -* Description: -* This function compares two Axis values that have been formatted -* (using astAxisFormat) and determines if they have any redundant -* leading fields (i.e. leading fields in common which can be -* suppressed when tabulating the values or plotting them on the -* axis of a graph). - -* Parameters: -* this -* Pointer to the Axis. -* fmt -* Pointer to a constant null-terminated string containing the -* format specifier used to format the two values. -* str1 -* Pointer to a constant null-terminated string containing the -* first formatted value. If this is null, the returned pointer -* points to the start of the final field in str2. -* str2 -* Pointer to a constant null-terminated string containing the -* second formatted value. - -* Returned Value: -* A pointer into the "str2" string which locates the first -* character in the first field that differs between the two -* formatted values. -* -* If the two values have no leading fields in common, the returned -* value will point at the start of string "str2". If the two -* values are equal, it will point at the terminating null at the -* end of this string. - -* Notes: -* - This function assumes that the format specification used was -* the same when both values were formatted. -* - A pointer to the start of "str2" will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -*- -*/ - -/* Local Variables: */ - const char *result; /* Result pointer to return */ - -/* Initialise. */ - result = str2; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* In the Axis class, there is only one field in a formatted value. - We return the value of "str2", unless the two strings are - identical, in which case we return a pointer to the final null in - "str2". */ - if( str1 && !strcmp( str1, str2 ) ) result += strlen( str2 ); - -/* Return the result. */ - return result; -} - -static double AxisDistance( AstAxis *this, double v1, double v2, int *status ) { -/* -*+ -* Name: -* astAxisDistance - -* Purpose: -* Find the distance between two axis values. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* AxisDistance( AstAxis *this, double v1, double v2 ) - -* Class Membership: -* Axis method. - -* Description: -* This function returns a signed value representing the axis increment -* from axis value v1 to axis value v2. -* -* For a simple Axis, this is a trivial operation. But for other -* derived classes of Axis (such as a SkyAxis) this is not the case. - -* Parameters: -* this -* Pointer to the Axis. -* v1 -* The first axis value -* v2 -* The second axis value - -* Returned Value: -* The axis increment from v1 to v2. - -* Notes: -* - A value of AST__BAD is returned if either axis value is AST__BAD. -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - double result; /* Returned gap size */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check both axis values are OK, and form the returned increment. */ - if( v1 != AST__BAD && v2 != AST__BAD ) result = v2 - v1; - -/* Return the result. */ - return result; -} - -static int AxisFields( AstAxis *this, const char *fmt0, const char *str, - int maxfld, char **fields, int *nc, double *val, int *status ) { -/* -*+ -* Name: -* astAxisFields - -* Purpose: -* Identify numerical fields within a formatted Axis value. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* int astAxisFields( AstAxis *this, const char *fmt0, const char *str, -* int maxfld, char **fields, int *nc, double *val ) - -* Class Membership: -* Axis member function. - -* Description: -* This function identifies the numerical fields within an Axis value -* that have been formatted using astAxisFormat. It assumes that the -* value was formatted using the supplied format string. It also -* returns the equivalent floating point value. - -* Parameters: -* this -* Pointer to the Axis. -* fmt0 -* Pointer to a constant null-terminated string containing the -* format used when creating "str". -* str -* Pointer to a constant null-terminated string containing the -* formatted value. -* maxfld -* The maximum number of fields to identify within "str". -* fields -* A pointer to an array of at least "maxfld" character pointers. -* Each element is returned holding a pointer to the start of the -* corresponding field in "str" (in the order in which they occur -* within "str"), or NULL if no corresponding field can be found. -* nc -* A pointer to an array of at least "maxfld" integers. Each -* element is returned holding the number of characters in the -* corresponding field, or zero if no corresponding field can be -* found. -* val -* Pointer to a location at which to store the value -* equivalent to the returned field values. If this is NULL, -* it is ignored. - -* Returned Value: -* The number of fields succesfully identified and returned. - -* Notes: -* - Leading and trailing spaces are ignored. -* - If the formatted value is not consistent with the supplied format -* string, then a value of zero will be returned, "fields" will be -* returned holding NULLs, "nc" will be returned holding zeros, and -* "val" is returned holding VAL__BAD. -* - Fields are counted from the start of the formatted string. If the -* string contains more than "maxfld" fields, then trailing fields are -* ignored. -* - If this function is invoked with the global error status set, or -* if it should fail for any reason, then a value of zero will be returned -* as the function value, and "fields", "nc" and "val" will be returned -* holding their supplied values -*- -*/ - -/* Local Variables: */ - char log_esc[ 50 ]; /* Buffer for graphical delimiter string */ - const char *fmt; /* Pointer to parsed Format string */ - const char *log_del; /* Pointer to delimiter string */ - const char *p; /* Pointer to next character */ - double value; /* Equivalent radians value */ - int ifld; /* Field index */ - int integ; /* Cast axis value to integer before printing? */ - int len; /* Length of formatted string */ - int log; /* Format as "10**x"? */ - int n; /* Number of characters read */ - int neg; /* Negate final value? */ - int result; /* Result fields count to return */ - int sign; /* Include leading sign in front of "10**x"? */ - int space; /* Include leading space in front of "10**x"? */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise. */ - result = 0; - for( ifld = 0; ifld < maxfld; ifld++ ) { - fields[ ifld ] = NULL; - nc[ ifld ] = 0; - } - if( val ) *val = AST__BAD; - -/* Parse the Format string. This returns a collection of flags indicating - if any AST specific formatting features are specified in the Format - string. It also returns a pointer to a new Format string which is a - standard C printf format specifier. Currently the only flags are "log" - which indicates if the value should be formatted as "10**x" using - the graphical escape sequences defined within the Plot class to produce - "x" as a superscript of "10", "sign" which is used with log to indicate - if a sign should always be included infront of the "10", and "space" - which indicates if a leading space should be included infronyt of "10" if - no sign is included. */ - fmt = ParseAxisFormat( fmt0, astGetAxisDigits( this ), &log, &sign, - &space, &integ, status ); - fmt = astFree( (void *) fmt ); - - if( astOK ) { - -/* Obtain the length of the formatted string. */ - len = (int) strlen( str ); - -/* First deal with "log" format. */ - if( log ) { - -/* We need room for at least 2 fields. */ - if( maxfld > 1 ) { - -/* Return a pointer to the first non-blank character. */ - p = str; - while( *p == ' ' ) p++; - fields[ 0 ] = (char *) p; - -/* If the first non-blank character is a minus sign, note it and skip it. */ - neg = 0; - if( *p == '-' ) { - neg = 1; - p++; - -/* If the first non-blank character is a plus sign, and skip it. */ - } else if( *p == '+' ) { - p++; - } - -/* Select the delimter.*/ - if( astEscapes( -1 ) ) { - astTuneC( "exdel", NULL, log_esc, sizeof( log_esc ) ); - log_del = log_esc; - } else { - log_del = log_txt; - } - -/* Check the remaining string starts with the correct delimiter. If - so, store the number of characters in the first field and skip over the - delimiter. */ - n = 0; - if( strstr( p, log_del ) == p ) { - nc[ 0 ] = p + 2 - fields[ 0 ]; - p += strlen( log_del ); - -/* Attempt to read a floating point value from the start of the remaining - string. */ - if( 1 == sscanf( p, "%lg%n", &value, &n ) ) { - -/* If succesfull, store the returned values. */ - result = 2; - fields[ 1 ] = (char *) p; - nc[ 1 ] = n; - if( val ) { - *val = pow( 10.0, value ); - if( neg ) *val = -(*val); - } - -/* Otherwise, see if the string starts with */ - } else if( strstr( p, "" ) == p ) { - -/* If succesfull, store the returned values. */ - result = 2; - fields[ 1 ] = (char *) p; - nc[ 1 ] = 5; - if( val ) *val = 0.0; - } - -/* Zero is never formatted as an exponent. If the string starts with zero, - return a single zero field. */ - } else if( 1 == sscanf( p, "%lg%n", &value, &n ) ) { - if( value == 0.0 ) { - result = 1; - nc[ 0 ] = p + n - fields[ 0 ]; - if( val ) *val = 0.0; - } - } - } - -/* Now deal with normal decimal format */ - } else { - -/* Attempt to read a floating point value from the formatted string. */ - if ( n = 0, - ( 1 == sscanf( str, "%lg %n", &value, &n ) ) - && ( n >= len ) && maxfld > 0 ) { - -/* If succesful, return a pointer to the first non-blank character. */ - p = str; - while( *p == ' ' ) p++; - fields[ 0 ] = (char *) p; - -/* Find the last non-blank character. */ - p += len; - while( p[ -1 ] == ' ' ) p--; - -/* Return the number of characters in the field. */ - nc[ 0 ] = p - fields[ 0 ]; - -/* Return the field value. */ - if( val ) *val = value; - -/* Indicate that we are returning one field. */ - result = 1; - } - } - } - -/* Return the result. */ - return result; -} - -static const char *AxisFormat( AstAxis *this, double value, int *status ) { -/* -*+ -* Name: -* astAxisFormat - -* Purpose: -* Format a coordinate value for an Axis. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "axis.h" -* const char *astAxisFormat( AstAxis *this, double value ) - -* Class Membership: -* Axis method. - -* Description: -* This function returns a pointer to a string containing the formatted -* (character) version of a coordinate value for an Axis. The formatting -* applied is that specified by a previous invocation of the -* astSetAxisFormat method. A suitable default format is applied if -* necessary. - -* Parameters: -* this -* Pointer to the Axis. -* value -* The coordinate value to be formatted. - -* Returned Value: -* A pointer to a null-terminated string containing the formatted value. - -* Notes: -* - The returned string pointer may point at memory allocated within -* the Axis object, or at static memory. The contents of the string may be -* over-written or the pointer may become invalid following a further -* invocation of the same function or deletion of the Axis. A copy of the -* string should therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Constants: */ -#define ERRBUF_LEN 80 - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char *errstat; /* Pointer for system error message */ - char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */ - char log_esc[ 50 ]; /* Buffer for graphical delimiter string */ - const char *fmt0; /* Pointer to original Format string */ - const char *fmt; /* Pointer to parsed Format string */ - const char *log_del; /* Pointer to delimiter string */ - const char *result; /* Pointer to formatted value */ - double x; /* The value to be formatted by sprintf */ - int integ; /* Cast axis value to integer before printing? */ - int log; /* Format as "10**x"? */ - int nc; /* Total number of characters written */ - int ncc; /* Number of characters written */ - int sign; /* Include leading sign in front of "10**x"? */ - int space; /* Include leading space in front of "10**x"? */ - int stat; /* Value of errno after error */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - nc = 0; - x = value; - -/* Check if a bad coordinate value was supplied and return a pointer to an - appropriate string if necessary. */ - if ( value == AST__BAD ) { - result = ""; - -/* Otherwise, obtain a pointer to the Format string. Note a private member - function is used here in preference to an object method. This is because the - syntax of the Format string may be extended by derived classes and we do not - want to obtain a string that we cannot interpret here (where we are - restricted to C format specifiers capable of formatting double values). - Classes that extend the syntax should provide their own astAxisFormat method - and may need to store the string in a separate location. The original - location should not be re-used as the string it contains may be needed by - the Axis astOverlay method when overlaying attributes on to another Axis - object. */ - } else { - fmt0 = GetAxisFormat( this, status ); - -/* Parse the Format string. This returns a collection of flags indicating - if any AST specific formatting features are specified in the Format - string. It also returns a pointer to a new Format string which is a - standard C printf format specifier. Currently the only flags are "log" - which indicates if the value should be formatted as "10**x" using - the graphical escape sequences defined within the Plot class to produce - "x" as a superscript of "10", "sign" which is used with log to indicate - if a sign should always be included infront of the "10", and "space" - which indicates if a leading space should be included infronyt of "10" - if no sign is included. It also modifies ".*" precision fields by - replacing the "*" by the current vale of the Digits attribute. */ - fmt = ParseAxisFormat( fmt0, astGetAxisDigits( this ), &log, &sign, - &space, &integ, status ); - if( astOK ) { - -/* Format zero normally. */ - if( value == 0.0 ) log = 0; - -/* If log format is required, find the value of the exponent "x", and - initialise the returned string to hold the exponent and the graphical - escape sequence which produces a superscript. Otherwise just format the - supplied value. */ - if( log ) { - - if( sign ) { - axisformat_buff[ 0 ] ='+'; - nc = 1; - - } else if( space ) { - axisformat_buff[ 0 ] =' '; - nc = 1; - } - - if( value > 0 ) { - x = log10( integ ? (int) value : value ); - - } else { - x = log10( integ ? (int) -value : -value ); - axisformat_buff[ 0 ] ='-'; - nc = 1; - } - - if( astEscapes( -1 ) ) { - astTuneC( "exdel", NULL, log_esc, sizeof( log_esc ) ); - log_del = log_esc; - } else { - log_del = log_txt; - } - - nc += sprintf( axisformat_buff + nc, "%s", log_del ); - -/* Round small exponents to zero. */ - if( fabs( x ) < 1.0E-10 ) x = 0.0; - } - } - -/* Clear errno and attempt to format the value as if the Format string were - a standard "sprintf" format. */ - if ( astOK ) { - errno = 0; - if( integ ) { - ncc = sprintf( axisformat_buff + nc, fmt, (int) x ); - } else { - ncc = sprintf( axisformat_buff + nc, fmt, x ); - } - nc += ncc; - -/* If log format is being used, terminate the string with an escape - sequence which resets the graphical attributes to what they were at the - start of the string. */ - if( log ) nc += sprintf( axisformat_buff + nc, "%%+" ); - -/* The possibilities for error detection are limited here, but check if an - error value was returned and report an error. Include information from - errno if it was set. */ - if ( ncc < 0 ) { - stat = errno; - if( stat ) { -#if HAVE_STRERROR_R - strerror_r( stat, errbuf, ERRBUF_LEN ); - errstat = errbuf; -#else - errstat = strerror( stat ); -#endif - } else { - *errbuf = 0; - errstat = errbuf; - } - astError( AST__FMTER, "astAxisFormat(%s): Error formatting a " - "coordinate value of %1.*G%s%s.", status, astGetClass( this ), - AST__DBL_DIG, value, stat? " - " : "", errstat ); - astError( AST__FMTER, "The format string was \"%s\".", status, fmt ); - -/* Also check that the result buffer did not overflow. If it did, memory will - probably have been corrupted but this cannot be prevented with "sprintf". - Report the error and abort. */ - } else if ( nc > AST__AXIS_AXISFORMAT_BUFF_LEN ) { - astError( AST__FMTER, "astAxisFormat(%s): Internal buffer " - "overflow while formatting a coordinate value of %1.*G " - "- result exceeds %d characters.", status, astGetClass( this ), - AST__DBL_DIG, value, AST__AXIS_AXISFORMAT_BUFF_LEN ); - astError( AST__FMTER, "The format string was \"%s\".", status, fmt ); - -/* If succesfull, return a pointer to the buffer. */ - } else { - result = axisformat_buff; - } - } - -/* Free resources. */ - fmt = astFree( (void *) fmt ); - - } - -/* Return the result. */ - return result; - -} -#undef ERRBUF_LEN - -static double AxisCentre( AstAxis *this, double value, double gap, int *status ) { -/* -*+ -* Name: -* astAxisCentre - -* Purpose: -* Find a "nice" central value for tabulating Axis values. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* double astAxisCentre( AstAxis *this, double value, double gap ) - -* Class Membership: -* Axis method. - -* Description: -* This function returns an axis value which produces a nice formatted -* value suitable for a major tick mark on a plot axis. - -* Parameters: -* this -* Pointer to the Axis. -* value -* An arbitrary axis value in the section that is being plotted. -* gap -* The gap size. - -* Returned Value: -* The nice central axis value. - -* Notes: -* - A value of zero is returned if the supplied gap size is zero. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - double result; /* Returned central axis value */ - -/* Initialise. */ - result = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* The returned central value is an integral number of gaps away from the - origin and is close to the supplied axis value. This would result in - the origin being at a major tick mark. */ - if( gap != 0.0 && gap != AST__BAD && value != AST__BAD ) { - result = gap*floor( 0.5 + value/gap ); - } - -/* Return the result. */ - return result; -} - -static double AxisGap( AstAxis *this, double gap, int *ntick, int *status ) { -/* -*+ -* Name: -* astAxisGap - -* Purpose: -* Find a "nice" gap for tabulating Axis values. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* double astAxisGap( AstAxis *this, double gap, int *ntick ) - -* Class Membership: -* Axis method. - -* Description: -* This function returns a gap size which produces a nicely spaced -* series of formatted Axis values, the returned gap size being as -* close as possible to the supplied target gap size. It also -* returns a convenient number of divisions into which the gap can -* be divided. - -* Parameters: -* this -* Pointer to the Axis. -* gap -* The target gap size. -* ntick -* Address of an int in which to return a convenient number of -* divisions into which the gap can be divided. - -* Returned Value: -* The nice gap size. - -* Notes: -* - A value of zero is returned if the supplied gap size is zero. -* - A negative gap size is returned if the supplied gap size is negative. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - double absgap; /* Absolute supplied gap size */ - double b; /* Decimal step size */ - double result; /* Returned gap size */ - int index; /* Index into tables */ - int positive; /* Value is positive (or zero)? */ - -/* Local Data: */ - static double table1[ 10 ] = /* Table of nice decimal gaps */ - { 1.0, 2.0, 2.0, 5.0, 5.0, 5.0, 5.0, 10.0, 10.0, 10.0 }; - static int table2[ 10 ] = /* Table giving number of divisions */ - { 5, 4, 4, 5, 5, 5, 5, 5, 5, 5 }; - -/* Initialise. */ - result = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check that the supplied gap size is not zero. */ - if ( gap != 0.0 ) { - -/* Determine if the supplied gap size is positive and obtain its - absolute value. */ - positive = ( gap >= 0.0 ); - absgap = positive ? gap : -gap; - -/* Obtain a value which has a 1 at the position of the most - significant decimal digit in the target gap size and zeros at all - other positions. */ - b = pow( 10.0, floor( log10( absgap ) ) ); - -/* This value is the basic "step size". Find the nearest whole number - of steps in the supplied gap, and then use the look-up-table in - "table1" to find the closest acceptable gap size. Convert this gap - size back to an absolute value by multiplying by the step size. */ - index = (int) ( absgap / b + 0.5 ) - 1; - result = b * table1[ index ]; - -/* If the target gap was negative, negate the result. */ - if( !positive ) result = -result; - -/* Store the number of divisions in the gap. */ - if ( ntick ) *ntick = table2[ index ]; - } - -/* Return the result. */ - return result; -} - -static int AxisIn( AstAxis *this, double lo, double hi, double val, int closed, int *status ){ -/* -*+ -* Name: -* astAxisIn - -* Purpose: -* Test if an axis value lies within a given interval. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* int AxisIn( AstAxis *this, double lo, double hi, double val, int closed ) - -* Class Membership: -* Axis member function. - -* Description: -* This function returns non-zero if a given axis values lies within a -* given axis interval. - -* Parameters: -* this -* Pointer to the Axis. -* lo -* The lower axis limit of the interval. -* hi -* The upper axis limit of the interval. -* val -* The axis value to be tested. -* closed -* If non-zero, then the lo and hi axis values are themselves -* considered to be within the interval. Otherwise they are outside. - -* Returned Value: -* Non-zero if the test value is inside the interval. - -* Class Applicability: -* Axis -* Uses simple Euclidean test -* SkyAxis -* All angles which are numerically between "lo" and "hi" are within -* the interval. Angle outside this range are also within the interval -* if they can be brought into the range by addition or subtraction -* of a multiple of 2.PI. -*- -*/ - -/* For speed, omit the astOK check since no pointers are being used. */ - if( closed ) { - return ( lo <= val && val <= hi ); - } else { - return ( lo < val && val < hi ); - } -} - -static void AxisNorm( AstAxis *this, double *value, int *status ) { -/* -*+ -* Name: -* astAxisNorm - -* Purpose: -* Normalise an Axis coordinate value. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "axis.h" -* void astAxisNorm( AstAxis *this, double *value ) - -* Class Membership: -* Axis method. - -* Description: -* This function converts an Axis coordinate value which might -* potentially be unsuitable for display to a user (for instance, -* may lie outside the expected range of values) into an acceptable -* alternative value suitable for display. -* -* Typically, for axes that represent cyclic values such as angles, -* this function wraps an arbitrary coordinate value so that it -* lies within the first cycle (say zero to 2*pi). For an ordinary -* linear Axis, without constraints, this function will typically -* return the original value unchanged. - -* Parameters: -* this -* Pointer to the Axis. -* value -* Pointer to the coordinate value to be normalised, which will -* be modified in place. -*- -*/ - -/* In the Axis class there are no constraints, so simply return - without action. */ - return; -} - -static void AxisNormValues( AstAxis *this, int oper, int nval, - double *values, int *status ){ -/* -*+ -* Name: -* astAxisNormValues - -* Purpose: -* Normalise an array of axis coordinate values. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "axis.h" -* void astAxisNormValues( AstAxis *this, int oper, int nval, -* double *values ) - -* Class Membership: -* Axis method. - -* Description: -* This function modifies a supplied array of axis values so that -* they are normalised in the manner indicated by parameter "oper". -* -* For a simple axis, the supplied values are always returned -* unchanged regardless of the value of "oper". - -* Parameters: -* this -* Pointer to the Axis. -* oper -* Indicates the type of normalisation to be applied. If zero is -* supplied, the normalisation will be the same as that performed by -* function astAxisNorm. If 1 is supplied, the normalisation will be -* chosen automatically so that the resulting list has the smallest -* range. -* nval -* The number of points in the values array. -* values -* On entry, the axis values to be normalised. Modified on exit to -* hold the normalised values. -*- -*/ - -/* In the Axis class there are no constraints, so simply return - without action. */ - return; -} - -static double AxisOffset( AstAxis *this, double v1, double dist, int *status ) { -/* -*+ -* Name: -* astAxisOffset - -* Purpose: -* Add an increment onto a supplied axis value. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* AxisOffset( AstAxis *this, double v1, double dist ) - -* Class Membership: -* Axis method. - -* Description: -* This function returns an axis value formed by adding a signed axis -* increment onto a supplied axis value. -* -* For a simple Axis, this is a trivial operation. But for other -* derived classes of Axis (such as a SkyAxis) this is not the case. - -* Parameters: -* this -* Pointer to the Axis. -* v1 -* The supplied axis value -* dist -* The axis increment - -* Returned Value: -* The axis value which is the specified increment away from v1. - -* Notes: -* - A value of AST__BAD is returned if either axis value is AST__BAD. -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - double result; /* Returned gap size */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check both axis values are OK, and form the returned axis value. */ - if( v1 != AST__BAD && dist != AST__BAD ) result = v1 + dist; - -/* Return the result. */ - return result; -} - -static void AxisOverlay( AstAxis *template, AstAxis *result, int *status ) { -/* -*+ -* Name: -* astAxisOverlay - -* Purpose: -* Overlay the attributes of a template Axis on to another Axis. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* void astAxisOverlay( AstAxis *template, AstAxis *result ) - -* Class Membership: -* Axis method. - -* Description: -* This function overlays attributes of one Axis (the "template") on to -* another Axis, so as to over-ride selected attributes of that second -* Axis. Normally only those attributes which have been specifically set -* in the template will be transferred. This implements a form of -* defaulting, in which an Axis acquires attributes from the template, but -* retains its original attributes (as the default) if new values have not -* previously been explicitly set in the template. - -* Parameters: -* template -* Pointer to the template Axis, for which values should have been -* explicitly set for any attribute which is to be transferred. -* result -* Pointer to the Axis which is to receive the new attribute values. - -* Returned Value: -* void -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Define a macro to overlay a single attribute. This tests if the attribute - is set in the template Axis. If it is, its value is obtained and set in the - result Axis also. */ -#define OVERLAY(par) \ - if ( astTestAxis##par( template ) ) { \ - astSetAxis##par( result, astGetAxis##par( template ) ); \ - } -/* Overlay each Axis attribute in turn. */ - OVERLAY(Digits); - OVERLAY(Direction); - OVERLAY(Label); - OVERLAY(Symbol); - OVERLAY(Unit); - -/* Handle the Format string slightly differently by using a private member - function to obtain it. This is necessary in case derived classes have - extended the string syntax (see the AxisFormat function for more - details). */ - if ( TestAxisFormat( template, status ) ) { - SetAxisFormat( result, GetAxisFormat( template, status ), status ); - } - -/* Undefine macros local to this function. */ -#undef OVERLAY -} - -static int AxisUnformat( AstAxis *this, const char *string, double *value, int *status ) { -/* -*+ -* Name: -* astAxisUnformat - -* Purpose: -* Read a formatted coordinate value for an Axis. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "axis.h" -* int astAxisUnformat( AstAxis *this, const char *string, double *value ) - -* Class Membership: -* Axis method. - -* Description: -* This function reads a formatted coordinate value for an Axis -* (supplied as a string) and returns the equivalent numerical -* value as a double. It also returns the number of characters read -* from the string. - -* Parameters: -* this -* Pointer to the Axis. -* string -* Pointer to a constant null-terminated string containing the -* formatted coordinate value. -* value -* Pointer to a double in which the coordinate value read will be -* returned. - -* Returned Value: -* The number of characters read from the string to obtain the -* coordinate value. - -* Notes: -* - Any white space at the beginning of the string will be -* skipped, as also will any trailing white space following the -* coordinate value read. The function's return value will reflect -* this. -* - A function value of zero (and no coordinate value) will be -* returned, without error, if the string supplied does not contain -* a suitably formatted value. -* - The string "" is recognised as a special case and will -* generate the value AST__BAD, without error. The test for this -* string is case-insensitive and permits embedded white space. -* - A function result of zero will be returned and no coordinate -* value will be returned via the "value" pointer if this function -* is invoked with the global error status set, or if it should -* fail for any reason. -*- -*/ - -/* Local Variables: */ - double coord; /* Coordinate value read */ - int nc; /* Number of characters read */ - -/* Initialise. */ - nc = 0; - -/* Check the global error status. */ - if ( !astOK ) return nc; - -/* See if the string can be read as a floating point number. If so, - return its value. Also obtain the number of characters read, - including any leading and trailing white space. */ - if ( 1 == astSscanf( string, "%lf %n", &coord, &nc ) ) { - *value = coord; - -/* Otherwise, see if the string starts with "", allowing mixed - case and leading, embedded and trailing white space. If so, return - the value AST__BAD. */ - } else if ( nc = 0, - ( 0 == astSscanf( string, " < %*1[Bb] %*1[Aa] %*1[Dd] > %n", &nc ) - && ( nc > 0 ) ) ) { - *value = AST__BAD; - -/* If the string cannot be read, return a function result of zero. */ - } else { - nc = 0; - } - -/* Return the number of characters read. */ - return nc; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for an Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Axis member function (over-rides the astClearAttrib protected -* method inherited from the Object class). - -* Description: -* This function clears the value of a specified attribute for an -* Axis, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Axis. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstAxis *this; /* Pointer to the Axis structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Axis structure. */ - this = (AstAxis *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Digits. */ -/* ------- */ - if ( !strcmp( attrib, "digits" ) ) { - astClearAxisDigits( this ); - -/* Direction. */ -/* ---------- */ - } else if ( !strcmp( attrib, "direction" ) ) { - astClearAxisDirection( this ); - -/* Format. */ -/* ------- */ - } else if ( !strcmp( attrib, "format" ) ) { - astClearAxisFormat( this ); - -/* Label. */ -/* ------ */ - } else if ( !strcmp( attrib, "label" ) ) { - astClearAxisLabel( this ); - -/* Top. */ -/* ---- */ - } else if ( !strcmp( attrib, "top" ) ) { - astClearAxisTop( this ); - -/* Bottom. */ -/* ------- */ - } else if ( !strcmp( attrib, "bottom" ) ) { - astClearAxisBottom( this ); - -/* Symbol. */ -/* ------- */ - } else if ( !strcmp( attrib, "symbol" ) ) { - astClearAxisSymbol( this ); - -/* Unit. */ -/* ----- */ - } else if ( !strcmp( attrib, "unit" ) ) { - astClearAxisUnit( this ); - -/* Read-only attributes. */ -/* --------------------- */ -/* Test if the attribute name matches any of the read-only attributes - of this class. If it does, then report an error. */ - } else if ( !strcmp( attrib, "normunit" ) || - !strcmp( attrib, "internalunit" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static const char *GetAxisInternalUnit( AstAxis *this, int *status ){ -/* -*+ -* Name: -* astGetAxisInternalUnit - -* Purpose: -* Return the unit string for unformatted Axis values - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* const char *astGetAxisInternalUnit( AstAxis *this ){ - -* Class Membership: -* Axis method. - -* Description: -* This function returns the axis InternalUnit attribute. For basic -* axes, the InternalUnit and Unit attributes are the same. - -* Parameters: -* this -* Pointer to the Axis. - -* Returned Value: -* - Pointer to a null-terminated string containing the internal -* unit string. - -* Notes: -* - The returned pointer points to a static memory buffer. The -* contents of this buffer will be over-written on each invocation of -* this function. A copy of the returned string should therefore be -* taken if it will be needed later. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - return astGetAxisUnit( this ); -} - -static const char *GetAxisNormUnit( AstAxis *this, int *status ){ -/* -*+ -* Name: -* astGetAxisNormUnit - -* Purpose: -* Return the normalised Unit attribute for an Axis. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "axis.h" -* const char *astGetAxisNormUnit( AstAxis *this ){ - -* Class Membership: -* Axis method. - -* Description: -* This function normalised and returns the axis Unit attribute. -* Normalisation refers to transformations such as "s*(m/s)" -> "m". - -* Parameters: -* this -* Pointer to the Axis. - -* Returned Value: -* - Pointer to a null-terminated string containing the normalised -* unit string. - -* Notes: -* - The returned pointer points to a static memory buffer. The -* contents of this buffer will be over-written on each invocation of -* this function. A copy of the returned string should therefore be -* taken if it will be needed later. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *result; /* Pointer to dynamic memory holding returned text */ - int nc; /* Length of normalised Unit string */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Get the Axis Unit attrribute and normalise it. */ - result = astUnitNormaliser( astGetAxisUnit( this ) ); - -/* If successful, check that the resulting string will fit in the buffer. - If not, report an error. */ - if( result ) { - nc = strlen( result ); - if( nc > AST__AXIS_GETAXISNORMUNIT_BUFF_LEN ) { - astError( AST__FMTER, "astGetAxisNormUnit(%s): Internal buffer " - "overflow while normalising the units string '%s' " - "- result exceeds %d characters.", status, astGetClass( this ), - result, AST__AXIS_GETAXISNORMUNIT_BUFF_LEN ); - result = astFree( (void *) result ); - -/* If so, copy it into the static buffer and free the dynamic memory returned - by astUnitNormaliser. */ - } else { - strcpy( getaxisnormunit_buff, result ); - } - astFree( (void *) result ); - - result = getaxisnormunit_buff; - } - -/* Return the answer. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* Axis member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied Axis, -* in bytes. - -* Parameters: -* this -* Pointer to the Axis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstAxis *this; /* Pointer to Axis structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the Axis structure. */ - this = (AstAxis *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astTSizeOf( this->label ); - result += astTSizeOf( this->format ); - result += astTSizeOf( this->symbol ); - result += astTSizeOf( this->unit ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for an Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Axis member function (over-rides the protected astGetAttrib -* method inherited from the Object class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for an Axis, formatted as a character string. - -* Parameters: -* this -* Pointer to the Axis. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Axis, or at static memory. The contents of the string -* may be over-written or the pointer may become invalid following -* a further invocation of the same function or any modification of -* the Axis. A copy of the string should therefore be made if -* necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstAxis*this; /* Pointer to the Axis structure */ - const char *result; /* Pointer value to return */ - double dval; /* Double attribute value */ - int digits; /* Digits attribute value */ - int direction; /* Direction attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Axis structure. */ - this = (AstAxis *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an - appropriate format. Set "result" to point at the result string. */ - -/* Digits. */ -/* ------- */ - if ( !strcmp( attrib, "digits" ) ) { - digits = astGetAxisDigits( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", digits ); - result = getattrib_buff; - } - -/* Direction. */ -/* ---------- */ - } else if ( !strcmp( attrib, "direction" ) ) { - direction = astGetAxisDirection( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", direction ); - result = getattrib_buff; - } - -/* Top. */ -/* ---- */ - } else if ( !strcmp( attrib, "top" ) ) { - dval = astGetAxisTop( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Bottom. */ -/* ------- */ - } else if ( !strcmp( attrib, "bottom" ) ) { - dval = astGetAxisBottom( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Format. */ -/* ------- */ - } else if ( !strcmp( attrib, "format" ) ) { - result = astGetAxisFormat( this ); - -/* Label. */ -/* ------ */ - } else if ( !strcmp( attrib, "label" ) ) { - result = astGetAxisLabel( this ); - -/* Symbol. */ -/* ------- */ - } else if ( !strcmp( attrib, "symbol" ) ) { - result = astGetAxisSymbol( this ); - -/* Unit. */ -/* ----- */ - } else if ( !strcmp( attrib, "unit" ) ) { - result = astGetAxisUnit( this ); - -/* NormUnit. */ -/* --------- */ - } else if ( !strcmp( attrib, "normunit" ) ) { - result = astGetAxisNormUnit( this ); - -/* InternalUnit. */ -/* ------------- */ - } else if ( !strcmp( attrib, "internalunit" ) ) { - result = astGetAxisInternalUnit( this ); - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; - -} - -static const char *GetDefaultFormat( AstAxis *this, int *status ){ -/* -* Name: -* GetDefaultFormat - -* Purpose: -* Return a pointer to a string holding the default Format value. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* const char *GetDefaultFormat( AstAxis *this, int *status ) - -* Class Membership: -* Axis member function - -* Description: -* This function returns a pointer to a string holding the default -* Format value, which is based on the current Digits value. - -* Parameters: -* this -* A pointer to the Axis structure. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a static null-terminated character string containing -* the default Format string. - -* Notes: -* - A null string will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Check the global error status. */ - if ( !astOK ) return ""; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Create the default format value and store it in the "format_buff" - static variable. */ - (void) sprintf( getdefaultformat_buff, "%%1.%dG", astGetAxisDigits( this ) ); - -/* Return a pointer to the "format_buff" static variable. */ - return getdefaultformat_buff; -} - -void astInitAxisVtab_( AstAxisVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitAxisVtab - -* Purpose: -* Initialise a virtual function table for an Axis. - -* Type: -* Protected function. - -* Synopsis: -* #include "axis.h" -* void astInitAxisVtab( AstAxisVtab *vtab, const char *name ) - -* Class Membership: -* Axis vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Axis class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitObjectVtab( (AstObjectVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAAxis) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstObjectVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->AxisAbbrev = AxisAbbrev; - vtab->AxisFields = AxisFields; - vtab->AxisFormat = AxisFormat; - vtab->AxisDistance = AxisDistance; - vtab->AxisOffset = AxisOffset; - vtab->AxisCentre = AxisCentre; - vtab->AxisGap = AxisGap; - vtab->AxisIn = AxisIn; - vtab->AxisNorm = AxisNorm; - vtab->AxisNormValues = AxisNormValues; - vtab->AxisOverlay = AxisOverlay; - vtab->AxisUnformat = AxisUnformat; - vtab->ClearAxisDigits = ClearAxisDigits; - vtab->ClearAxisDirection = ClearAxisDirection; - vtab->ClearAxisFormat = ClearAxisFormat; - vtab->ClearAxisLabel = ClearAxisLabel; - vtab->ClearAxisSymbol = ClearAxisSymbol; - vtab->ClearAxisUnit = ClearAxisUnit; - vtab->GetAxisDigits = GetAxisDigits; - vtab->GetAxisDirection = GetAxisDirection; - vtab->GetAxisFormat = GetAxisFormat; - vtab->GetAxisLabel = GetAxisLabel; - vtab->GetAxisSymbol = GetAxisSymbol; - vtab->GetAxisUnit = GetAxisUnit; - vtab->GetAxisInternalUnit = GetAxisInternalUnit; - vtab->GetAxisNormUnit = GetAxisNormUnit; - vtab->SetAxisDigits = SetAxisDigits; - vtab->SetAxisDirection = SetAxisDirection; - vtab->SetAxisFormat = SetAxisFormat; - vtab->SetAxisLabel = SetAxisLabel; - vtab->SetAxisSymbol = SetAxisSymbol; - vtab->SetAxisUnit = SetAxisUnit; - vtab->TestAxisDigits = TestAxisDigits; - vtab->TestAxisDirection = TestAxisDirection; - vtab->TestAxisFormat = TestAxisFormat; - vtab->TestAxisLabel = TestAxisLabel; - vtab->TestAxisSymbol = TestAxisSymbol; - vtab->TestAxisUnit = TestAxisUnit; - vtab->TestAxisInternalUnit = TestAxisInternalUnit; - vtab->TestAxisNormUnit = TestAxisNormUnit; - - vtab->ClearAxisTop = ClearAxisTop; - vtab->GetAxisTop = GetAxisTop; - vtab->SetAxisTop = SetAxisTop; - vtab->TestAxisTop = TestAxisTop; - - vtab->ClearAxisBottom = ClearAxisBottom; - vtab->GetAxisBottom = GetAxisBottom; - vtab->SetAxisBottom = SetAxisBottom; - vtab->TestAxisBottom = TestAxisBottom; - -/* Save the inherited pointers to methods that will be extended, and replace - them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - -/* Declare the destructor, copy constructor and dump function. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "Axis", "Coordinate axis" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static char *ParseAxisFormat( const char *fmt0, int digs, int *log, int *sign, - int *lspace, int *integ, int *status ){ -/* -* Name: -* ParseAxisFormat - -* Purpose: -* Parse the Format string for an Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* char *ParseAxisFormat( const char *fmt0, int digs, int *log, int *sign, -* int *lspace, int *integ, int *status ) - -* Class Membership: -* Axis member function - -* Description: -* This function returns a collection of flags indicating if any AST -* specific formatting features are specified in the supplied Format -* string. It also returns a pointer to a new Format string which is a -* standard C printf format specifier. - -* Parameters: -* fmt0 -* The value of the Format attribute. -* digs -* The default number of digits of precision to use. This is used -* if the given format specifier includes a wildcard precision (".*"). -* In this case, the returned format specifier will be modified to -* include an explicit precision value equal to the supplied value -* of "digs". -* log -* Pointer to an integer in which to store a flag indicating if the -* if the axis value should be formatted as "10**x" using the graphical -* escape sequences defined within the Plot class to produce "x" as a -* superscript of "10". A non-zero value will be returned if the -* supplied Format string has a '&' character in its printf -* field (that is, between the leading '%' sign and the optional -* printf field width). -* sign -* Pointer to an integer in which to store a flag indicating if a -* sign character ('+' or '-') should always be included in front -* of the "10" if "log" is returned non-zero. If "log" is returned -* zero, then "sign" will also be zero. If "log" is non-zero, then -* a non-zero value for "sign" will be returned if the supplied Format -* string has a '+' character in its printf field (that is, -* between the leading '%' sign and the optional printf field width). -* lspace -* Pointer to an integer in which to store a flag indicating if a -* leading space should be included in front of the "10" if "log" is -* returned non-zero and "sign" is returned zero. Otherwise, "lspace" -* will also be zero. If "log" is non-zero, then a non-zero value for -* "lspace" will be returned if the supplied Format string has a ' ' -* character in its printf field (that is, between the leading -* '%' sign and the optional printf field width). -* integ -* Pointer to an integer in which to store a flag indicating if the -* returned format specifier includes an integer conversion code -* (e.g. %d) or floating point conversion code (e.g. "%.7G"). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a dynamically allocated null-terminated string containing -* the modified Format string. This will be a copy of the supplied -* Format string, but with any '&' flag removed. Any '+' or ' ' flag will -* also be removed if "log" is returned as non-zero. An explicit -* precision field will be included if the supplied format includes a -* ".*" precision field. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - char *a; /* Pointer to next char read from original format */ - char *b; /* Pointer to next char to write to new format */ - char *c; /* Pointer to next char read from original format */ - char *new; /* Pointer to new returned string */ - char *perc; /* Pointer to percent sign */ - char *result; /* Pointer to the returned string */ - int hash; /* Was a '#' flag found? */ - int len; /* Used length of format string */ - int minus; /* Was a '-' flag found? */ - int plus; /* Was a '+' flag found? */ - int rlen; /* Length of result */ - int space; /* Was a ' ' flag found? */ - -/* Initialise. */ - result = NULL; - *log = 0; - *sign = 0; - *lspace = 0; - *integ = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Take a copy of the supplied string. Check the pointer can be used - safely. */ - len = astChrLen( fmt0 ); - result = astStore( NULL, fmt0, len + 1 ); - if( astOK ) { - result[ len ] = 0; - -/* Find the first percent sign. Do nothing if none is found. */ - perc = strchr( result, '%' ); - if( perc ) { - -/* Check each character following the percent sign until one is found - which is not a legal printf flag, or a legal AST extension flag. Note - which ones are present. */ - minus = 0; - plus = 0; - space = 0; - hash = 0; - - a = perc; - while( ++a ){ - if( *a == '-' ){ - minus = 1; - } else if( *a == '+' ){ - plus = 1; - } else if( *a == ' ' ){ - space = 1; - } else if( *a == '#' ){ - hash = 1; - } else if( *a == '&' ){ - *log = 1; - } else { - break; - } - } - -/* If no '&' flag was found just return the unaltered copy of the - supplied Format string. Otherwise, remove any '+' or ' ' flag. */ - if( *log ) { - if( plus ) *sign = 1; - if( space ) *lspace = 1; - -/* Append any remaining flag characters to the output string. */ - perc++; - if( minus ) *(perc++) = '-'; - if( hash ) *(perc++) = '#'; - -/* Copy the remaining characters down to fill up the gap left by the - removed flags. */ - while( *a ) *(perc++) = *(a++); - -/* Terminate the returned string. */ - *perc = 0; - - } - } - } - -/* If the format specifier being returned does include a ".*" precision, - replace the "*" with the value of the Digits attribute. */ - if( result ) { - -/* Find the first percent sign. Do nothing if none is found. */ - a = strchr( result, '%' ); - if( a ) { - -/* Check each character following the percent sign until one is found - which is not a legal printf flag. */ - while( ++a ){ - if( *a != '-' && *a != '+' && *a != ' ' && *a != '#' ) break; - } - -/* Skip any field width (a decimal integer) following the flags. */ - a--; - while( ++a ) { - if( !isdigit( *a ) ) break; - } - -/* Get a pointer to the next alphabetic character. This will be the - conversion code. If it an integer code, return *integ non-zero. */ - c = a - 1; - while( ++c ) { - if( isalpha( *c ) ) { - if( *c == 'd' || *c == 'i' || *c == 'u' || *c == 'o' || - *c == 'x' || *c == 'X' || *c == 'c' ) *integ = 1; - break; - } - } - -/* Go back to the end of the field width. If the next two characters are - "." and "*", change the asterisk to the supplied "digs" value. */ - if( a[ 0 ] == '.' && a[ 1 ] == '*' ) { - -/* Allocate memory to hold the extended format string (allowing 20 - characters for formatting the digs value - just in case something like - INT_MAX is supplied by mistake), and store the existing string in it. */ - rlen = strlen( result ); - new = astMalloc( rlen + 22 ); - if( new ) memcpy( new, result, rlen + 1 ); - -/* Put the precision into the new string, following the field width. */ - b = new + ( a - result ); - b += sprintf( b, ".%d", digs ); - -/* Copy the remainder of the original format string to the new format - string. */ - if( a[ 2 ] != 0 ) strcpy( b, a + 2 ); - -/* Use the new format string in place of the old.*/ - astFree( result ); - result = new; - } - } - } - -/* Return the result. */ - return result; - -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for an Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* Axis member function (over-rides the protected astSetAttrib -* method inherited from the Object class). - -* Description: -* This function assigns an attribute value for an Axis, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Axis. -* setting -* Pointer to a null terminated string specifying the new -* attribute value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstAxis *this; /* Pointer to Axis structure */ - double dval; /* Double attribute value */ - int digits; /* Number of digits of precision */ - int direction; /* Plot axis in normal direction? */ - int format; /* Offset of Format string */ - int label; /* Offset of Label string */ - int len; /* Length of setting string */ - int nc; /* Number of characters read from setting */ - int symbol; /* Offset of Symbol string */ - int unit; /* Offset of Unit string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Axis structure. */ - this = (AstAxis *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* Digits. */ -/* ------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "digits= %d %n", &digits, &nc ) ) - && ( nc >= len ) ) { - astSetAxisDigits( this, digits ); - -/* Direction. */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "direction= %d %n", &direction, &nc ) ) - && ( nc >= len ) ) { - astSetAxisDirection( this, direction ); - -/* Top. */ -/* ---- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "top= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetAxisTop( this, dval ); - -/* Bottom. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "bottom= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetAxisBottom( this, dval ); - -/* Format. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "format=%n%*[^\n]%n", &format, &nc ) ) - && ( nc >= len ) ) { - astSetAxisFormat( this, setting + format ); - -/* Label. */ -/* ------ */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "label=%n%*[^\n]%n", &label, &nc ) ) - && ( nc >= len ) ) { - astSetAxisLabel( this, setting + label ); - -/* Symbol. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "symbol=%n%*[^\n]%n", &symbol, &nc ) ) - && ( nc >= len ) ) { - astSetAxisSymbol( this, setting + symbol ); - -/* Unit. */ -/* ----- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "unit=%n%*[^\n]%n", &unit, &nc ) ) - && ( nc >= len ) ) { - astSetAxisUnit( this, setting + unit ); - -/* Read-only attributes. */ -/* --------------------- */ -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* Use this macro to report an error if a read-only attribute has been - specified. */ - } else if ( MATCH( "normunit" ) || - MATCH( "internalunit" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Pass any unrecognised attribute setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for an Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Axis member function (over-rides the astTestAttrib protected -* method inherited from the Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate -* whether a value has been set for one of an Axis' attributes. - -* Parameters: -* this -* Pointer to the Axis. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstAxis *this; /* Pointer to the Axis structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Axis structure. */ - this = (AstAxis *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* Digits. */ -/* ------- */ - if ( !strcmp( attrib, "digits" ) ) { - result = astTestAxisDigits( this ); - -/* Direction. */ -/* ---------- */ - } else if ( !strcmp( attrib, "direction" ) ) { - result = astTestAxisDirection( this ); - -/* Top. */ -/* ---- */ - } else if ( !strcmp( attrib, "top" ) ) { - result = astTestAxisTop( this ); - -/* Bottom. */ -/* ------- */ - } else if ( !strcmp( attrib, "bottom" ) ) { - result = astTestAxisBottom( this ); - -/* Format. */ -/* ------- */ - } else if ( !strcmp( attrib, "format" ) ) { - result = astTestAxisFormat( this ); - -/* Label. */ -/* ------ */ - } else if ( !strcmp( attrib, "label" ) ) { - result = astTestAxisLabel( this ); - -/* Symbol. */ -/* ------- */ - } else if ( !strcmp( attrib, "symbol" ) ) { - result = astTestAxisSymbol( this ); - -/* Unit. */ -/* ----- */ - } else if ( !strcmp( attrib, "unit" ) ) { - result = astTestAxisUnit( this ); - -/* InternalUnit. */ -/* --------- */ - } else if ( !strcmp( attrib, "internalunit" ) ) { - result = astTestAxisInternalUnit( this ); - -/* NormUnit. */ -/* --------- */ - } else if ( !strcmp( attrib, "normunit" ) ) { - result = astTestAxisNormUnit( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static int TestAxisInternalUnit( AstAxis *this, int *status ){ -/* -* Name: -* TestAxisInternalUnit - -* Purpose: -* Test if a InternalUnit attribute value is set for an Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* int TestAxisInternalUnit( AstAxis *this, int *status ) - -* Class Membership: -* Axis member function - -* Description: -* This function returns a boolean result (0 or 1) to indicate -* whether a value has been set for the InternalUnit string. - -* Parameters: -* this -* Pointer to the Axis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Tell the world that we know what value to use for InternalUnit if and - only if a value has been set for Unit. */ - return astTestAxisUnit( this ); -} - -static int TestAxisNormUnit( AstAxis *this, int *status ){ -/* -* Name: -* TestAxisNormUnit - -* Purpose: -* Test if a NormUnit attribute value is set for an Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* int TestAxisNormUnit( AstAxis *this, int *status ) - -* Class Membership: -* Axis member function - -* Description: -* This function returns a boolean result (0 or 1) to indicate -* whether a value has been set for the NormUnit string. - -* Parameters: -* this -* Pointer to the Axis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - - return astTestAxisUnit( this ); -} - - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with this - class using the macros defined for this purpose in the "object.h" file. For - a description of each attribute, see the class interface (in the associated - .h file). */ - -/* Digits. */ -/* ------- */ -/* Clear the Digits value by setting it to -INT_MAX. */ -astMAKE_CLEAR(Axis,AxisDigits,digits,-INT_MAX) - -/* Supply a default of 7 digits if no value has been set. */ -astMAKE_GET(Axis,AxisDigits,int,0,( this->digits != -INT_MAX ? - this->digits : 7 )) - -/* Constrain the Digits value being set to be at least 1. */ -astMAKE_SET(Axis,AxisDigits,int,digits,( value > 1 ? value : 1 )) - -/* The Digits value is set if it is not -INT_MAX. */ -astMAKE_TEST(Axis,AxisDigits,( this->digits != -INT_MAX )) - -/* Direction. */ -/* ---------- */ -/* Clear the Direction value by setting it to -INT_MAX. */ -astMAKE_CLEAR(Axis,AxisDirection,direction,-INT_MAX) - -/* Supply a default value of 1 if the Direction value is not set. */ -astMAKE_GET(Axis,AxisDirection,int,0,( this->direction != -INT_MAX ? - this->direction : 1 )) - -/* Set a Direction value of 1 if any non-zero value is supplied. */ -astMAKE_SET(Axis,AxisDirection,int,direction,( value != 0 )) - -/* The Direction value is set if it is not -INT_MAX. */ -astMAKE_TEST(Axis,AxisDirection,( this->direction != -INT_MAX )) - -/* Top. */ -/* -----*/ -/* Clear the Top Direction value by setting it to AST__BAD. */ -astMAKE_CLEAR(Axis,AxisTop,top,AST__BAD) - -/* Supply a default value of DBL_MAX if the Top value is not set.*/ -astMAKE_GET(Axis,AxisTop,double,0,( this->top != AST__BAD ? this->top : DBL_MAX)) - -/* Set the Top value. */ -astMAKE_SET(Axis,AxisTop,double,top,(value)) - -/* The Top value is set if it is not AST__BAD. */ -astMAKE_TEST(Axis,AxisTop,( this->top != AST__BAD )) - -/* Bottom. */ -/* --------*/ -/* Clear the Bottom Direction value by setting it to AST__BAD. */ -astMAKE_CLEAR(Axis,AxisBottom,bottom,AST__BAD) - -/* Supply a default value of -DBL_MAX if the Bottom value is not set.*/ -astMAKE_GET(Axis,AxisBottom,double,0.0,( this->bottom != AST__BAD ? this->bottom : -DBL_MAX)) - -/* Set the Bottom value. */ -astMAKE_SET(Axis,AxisBottom,double,bottom,(value)) - -/* The Bottom value is set if it is not AST__BAD. */ -astMAKE_TEST(Axis,AxisBottom,( this->bottom != AST__BAD )) - -/* Format. */ -/* ------- */ -/* Clear the Format value by freeing the allocated memory and assigning a NULL - pointer. */ -astMAKE_CLEAR(Axis,AxisFormat,format,astFree( this->format )) - -/* If the Format value is not set, return a pointer to a default Format - string. */ -astMAKE_GET(Axis,AxisFormat,const char *,NULL,( this->format ? this->format : - GetDefaultFormat( this, status ) ) ) - -/* Set a Format value by freeing any previously allocated memory, allocating - new memory, storing the string and saving the pointer to the copy. */ -astMAKE_SET(Axis,AxisFormat,const char *,format,astStore( this->format, value, - strlen( value ) + (size_t) 1 )) - -/* The Format value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Axis,AxisFormat,( this->format != NULL )) - -/* Label. */ -/* ------ */ -/* Clear the Label value by freeing the allocated memory and assigning a NULL - pointer. */ -astMAKE_CLEAR(Axis,AxisLabel,label,astFree( this->label )) - -/* If the Label value is not set, supply a default value by way of a pointer - to the constant string "Coordinate Axis". */ -astMAKE_GET(Axis,AxisLabel,const char *,NULL,( this->label ? this->label : - "Coordinate axis" )) - -/* Set a Label value by freeing any previously allocated memory, allocating - new memory, storing the string and saving the pointer to the copy. */ -astMAKE_SET(Axis,AxisLabel,const char *,label,astStore( this->label, value, - strlen( value ) + (size_t) 1 )) - -/* The Label value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Axis,AxisLabel,( this->label != NULL )) - -/* Symbol. */ -/* ------- */ -/* Clear the Symbol value by freeing the allocated memory and assigning a NULL - pointer. */ -astMAKE_CLEAR(Axis,AxisSymbol,symbol,astFree( this->symbol )) - -/* If the Symbol value is not set, supply a default value by way of a pointer - to the constant string "x". */ -astMAKE_GET(Axis,AxisSymbol,const char *,NULL,( this->symbol ? this->symbol : - "x" )) - -/* Set a Symbol value by freeing any previously allocated memory, allocating - new memory, storing the string and saving the pointer to the copy. */ -astMAKE_SET(Axis,AxisSymbol,const char *,symbol,astStore( this->symbol, value, - strlen( value ) + (size_t) 1 )) - -/* The Symbol value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Axis,AxisSymbol,( this->symbol != NULL )) - -/* Unit. */ -/* ----- */ -/* Clear the Unit value by freeing the allocated memory and assigning a NULL - pointer. */ -astMAKE_CLEAR(Axis,AxisUnit,unit,astFree( this->unit )) - -/* If the Unit value is not set, supply a default value by way of a pointer - to the constant string "". */ -astMAKE_GET(Axis,AxisUnit,const char *,NULL,( this->unit ? this->unit : "" )) - -/* Set a Unit value by freeing any previously allocated memory, allocating - new memory, storing the string and saving the pointer to the copy. */ -astMAKE_SET(Axis,AxisUnit,const char *,unit,astStore( this->unit, value, - strlen( value ) + (size_t) 1 )) - -/* The Unit value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Axis,AxisUnit,( this->unit != NULL )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Axis objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Axis objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstAxis *in; /* Pointer to input Axis */ - AstAxis *out; /* Pointer to output Axis */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Axis structures. */ - in = (AstAxis *) objin; - out = (AstAxis *) objout; - -/* For safety, first clear any references to the input memory from - the output Axis. */ - out->format = NULL; - out->label = NULL; - out->symbol = NULL; - out->unit = NULL; - -/* Make copies of the allocated strings and Objects. */ - if ( in->label ) out->label = astStore( NULL, in->label, - strlen( in->label ) + (size_t) 1 ); - if ( in->format ) out->format = astStore( NULL, in->format, - strlen( in->format ) + (size_t) 1 ); - if ( in->symbol ) out->symbol = astStore( NULL, in->symbol, - strlen( in->symbol ) + (size_t) 1 ); - if ( in->unit ) out->unit = astStore( NULL, in->unit, - strlen( in->unit ) + (size_t) 1 ); - -/* If an error occurred, clean up by freeing all memory allocated above. */ - if ( !astOK ) { - out->format = astFree( out->format ); - out->label = astFree( out->label ); - out->symbol = astFree( out->symbol ); - out->unit = astFree( out->unit ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Axis objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Axis objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstAxis *this; /* Pointer to Axis */ - -/* Obtain a pointer to the Axis structure. */ - this = (AstAxis *) obj; - -/* Free all allocated memory. */ - this->format = astFree( this->format ); - this->label = astFree( this->label ); - this->symbol = astFree( this->symbol ); - this->unit = astFree( this->unit ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Axis objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Axis class to an output Channel. - -* Parameters: -* this -* Pointer to the Axis whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstAxis *this; /* Pointer to the Axis structure */ - char comment[ 80 ]; /* Buffer for comment string */ - const char *sval; /* Pointer to string value */ - const char *lab; /* Pointer to unit label */ - double dval; /* Double value */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Axis structure. */ - this = (AstAxis *) this_object; - -/* Write out values representing the instance variables for the - Axis class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Label. */ -/* ------ */ - set = TestAxisLabel( this, status ); - sval = set ? GetAxisLabel( this, status ) : astGetAxisLabel( this ); - astWriteString( channel, "Label", set, 1, sval, "Axis Label" ); - -/* Symbol. */ -/* ------- */ - set = TestAxisSymbol( this, status ); - sval = set ? GetAxisSymbol( this, status ) : astGetAxisSymbol( this ); - astWriteString( channel, "Symbol", set, 1, sval, "Axis symbol" ); - -/* Unit. */ -/* ----- */ - set = TestAxisUnit( this, status ); - sval = set ? GetAxisUnit( this, status ) : astGetAxisUnit( this ); - -/* Get any label associated with the unit string. */ - lab = astUnitLabel( sval ); - -/* Construct a comment including the above label (but only if it is not - the same as the unit string) . */ - if( lab && strcmp( lab, sval ) ) { - (void) sprintf( comment, "Axis units (%s)", lab ); - } else { - (void) sprintf( comment, "Axis units" ); - } - -/* Write out the Unit value. */ - astWriteString( channel, "Unit", set, 0, sval, comment ); - -/* Digits. */ -/* ------- */ - set = TestAxisDigits( this, status ); - ival = set ? GetAxisDigits( this, status ) : astGetAxisDigits( this ); - astWriteInt( channel, "Digits", set, 0, ival, - "Default formatting precision" ); - -/* Format. */ -/* ------- */ - set = TestAxisFormat( this, status ); - sval = set ? GetAxisFormat( this, status ) : astGetAxisFormat( this ); - astWriteString( channel, "Format", set, 0, sval, "Format specifier" ); - -/* Direction. */ -/* ---------- */ - set = TestAxisDirection( this, status ); - ival = set ? GetAxisDirection( this, status ) : astGetAxisDirection( this ); - astWriteInt( channel, "Dirn", set, 0, ival, - ival ? "Plot in conventional direction (hint)" : - "Plot in reverse direction (hint)" ); -/* Top. */ -/* ---- */ - set = TestAxisTop( this, status ); - dval = set ? GetAxisTop( this, status ) : astGetAxisTop( this ); - astWriteDouble( channel, "Top", set, 0, dval, "Maximum legal axis value" ); - -/* Bottom. */ -/* ------- */ - set = TestAxisBottom( this, status ); - dval = set ? GetAxisBottom( this, status ) : astGetAxisBottom( this ); - astWriteDouble( channel, "Bottom", set, 0, dval, "Minimum legal axis value" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAAxis and astCheckAxis functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Axis,Object) -astMAKE_CHECK(Axis) - -AstAxis *astAxis_( const char *options, int *status, ...) { -/* -*+ -* Name: -* astAxis - -* Purpose: -* Create an Axis. - -* Type: -* Public function. - -* Synopsis: -* #include "axis.h" -* AstAxis *astAxis( const char *options, int *status, ... ) - -* Class Membership: -* Axis constructor. - -* Description: -* This function creates a new Axis and optionally initialises its -* attributes. - -* Parameters: -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new Axis. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new Axis. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstAxis *new; /* Pointer to new Axis */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the Axis, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitAxis( NULL, sizeof( AstAxis ), !class_init, &class_vtab, - "Axis" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new Axis' - attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Axis. */ - return new; -} - -AstAxis *astAxisId_( const char *options, ... ) { -/* -* Name: -* astAxisId_ - -* Purpose: -* Create an Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* AstAxis *astAxisId_( const char *options, ... ); - -* Class Membership: -* Axis constructor. - -* Description: -* This function implements the external (public) interface to the -* astAxis constructor function. It returns an ID value (instead of -* a true C pointer) to external users, and must be provided -* because astAxis_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astAxis_ directly, so it must be a re-implementation of -* it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astAxis_. - -* Returned Value: -* The ID value associated with the new Axis. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstAxis *new; /* Pointer to new Axis */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the Axis, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitAxis( NULL, sizeof( AstAxis ), !class_init, &class_vtab, - "Axis" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new Axis' - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Axis. */ - return astMakeId( new ); -} - -AstAxis *astInitAxis_( void *mem, size_t size, int init, - AstAxisVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitAxis - -* Purpose: -* Initialise an Axis. - -* Type: -* Protected function. - -* Synopsis: -* #include "axis.h" -* AstAxis *astInitAxis( void *mem, size_t size, int init, -* AstAxisVtab *vtab, const char *name ) - -* Class Membership: -* Axis initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Axis object. It allocates memory (if necessary) to accommodate -* the Axis plus any additional data associated with the derived class. -* It then initialises an Axis structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for an Axis at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Axis is to be created. This -* must be of sufficient size to accommodate the Axis data -* (sizeof(Axis)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Axis (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Axis -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Axis's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Axis. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astClass -* method). - -* Returned Value: -* A pointer to the new Axis. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstAxis *new; /* Pointer to new Axis */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitAxisVtab( vtab, name ); - -/* Initialise an Object structure (the parent class) as the first component - within the Axis structure, allocating memory if necessary. */ - new = (AstAxis *) astInitObject( mem, size, 0, (AstObjectVtab *) vtab, - name ); - - if ( astOK ) { - -/* Initialise the Axis data. */ -/* ------------------------- */ -/* Initialise all attributes to their "undefined" values. */ - new->digits = -INT_MAX; - new->direction = -INT_MAX; - new->format = NULL; - new->label = NULL; - new->symbol = NULL; - new->unit = NULL; - new->top = AST__BAD; - new->bottom = AST__BAD; - -/* If an error occurred, clean up by deleting the new Axis. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Axis. */ - return new; -} - -AstAxis *astLoadAxis_( void *mem, size_t size, - AstAxisVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadAxis - -* Purpose: -* Load an Axis. - -* Type: -* Protected function. - -* Synopsis: -* #include "axis.h" -* AstAxis *astLoadAxis( void *mem, size_t size, -* AstAxisVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* Axis loader. - -* Description: -* This function is provided to load a new Axis using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Axis structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Axis at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the Axis is to be -* loaded. This must be of sufficient size to accommodate the -* Axis data (sizeof(Axis)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Axis (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Axis structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstAxis) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Axis. If this is NULL, a pointer -* to the (static) virtual function table for the Axis class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Axis" is used instead. - -* Returned Value: -* A pointer to the new Axis. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstAxis *new; /* Pointer to the new Axis */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Axis. In this case the - Axis belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstAxis ); - vtab = &class_vtab; - name = "Axis"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitAxisVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Axis. */ - new = astLoadObject( mem, size, (AstObjectVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Axis" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Label. */ -/* ------ */ -/* Note that string values do not require any additional processing. */ - new->label = astReadString( channel, "label", NULL ); - -/* Symbol. */ -/* ------- */ - new->symbol = astReadString( channel, "symbol", NULL ); - -/* Unit. */ -/* ----- */ - new->unit = astReadString( channel, "unit", NULL ); - -/* Digits. */ -/* ------- */ - new->digits = astReadInt( channel, "digits", -INT_MAX ); - if ( TestAxisDigits( new, status ) ) SetAxisDigits( new, new->digits, status ); - -/* Format. */ -/* ------- */ - new->format = astReadString( channel, "format", NULL ); - -/* Direction. */ -/* ---------- */ - new->direction = astReadInt( channel, "dirn", -INT_MAX ); - if ( TestAxisDirection( new, status ) ) SetAxisDirection( new, new->direction, status ); - -/* Top. */ -/* ---- */ - new->top = astReadDouble( channel, "top", AST__BAD ); - if ( TestAxisTop( new, status ) ) SetAxisTop( new, new->top, status ); - -/* Bottom. */ -/* ---- */ - new->bottom = astReadDouble( channel, "bottom", AST__BAD ); - if ( TestAxisBottom( new, status ) ) SetAxisBottom( new, new->bottom, status ); - -/* If an error occurred, clean up by deleting the new Axis. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Axis pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -/* External interfaces for the attribute access functions are generated - automatically by the macros that implement the access functions themselves. - Hence, we need only provide external interfaces for a few additional - functions here. */ -const char *astAxisAbbrev_( AstAxis *this, const char *fmt, - const char *str1, const char *str2, int *status ) { - if ( !astOK ) return str2; - return (**astMEMBER(this,Axis,AxisAbbrev))( this, fmt, str1, str2, status ); -} -const char *astAxisFormat_( AstAxis *this, double value, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Axis,AxisFormat))( this, value, status ); -} -double astAxisDistance_( AstAxis *this, double v1, double v2, int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,Axis,AxisDistance))( this, v1, v2, status ); -} -double astAxisOffset_( AstAxis *this, double v1, double dist, int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,Axis,AxisOffset))( this, v1, dist, status ); -} -double astAxisCentre_( AstAxis *this, double value, double gap, int *status ) { - if ( !astOK ) return 0.0; - return (**astMEMBER(this,Axis,AxisCentre))( this, value, gap, status ); -} -double astAxisGap_( AstAxis *this, double gap, int *ntick, int *status ) { - if ( !astOK ) return 0.0; - return (**astMEMBER(this,Axis,AxisGap))( this, gap, ntick, status ); -} -void astAxisNorm_( AstAxis *this, double *value, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Axis,AxisNorm))( this, value, status ); -} -void astAxisOverlay_( AstAxis *template, AstAxis *result, int *status ) { - if ( !astOK ) return; - (**astMEMBER(template,Axis,AxisOverlay))( template, result, status ); -} -int astAxisUnformat_( AstAxis *this, const char *string, double *value, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Axis,AxisUnformat))( this, string, value, status ); -} -int astAxisFields_( AstAxis *this, const char *fmt, const char *str, - int maxfld, char **fields, int *nc, double *val, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Axis,AxisFields))( this, fmt, str, maxfld, fields, nc, val, status ); -} -int astAxisIn_( AstAxis *this, double lo, double hi, double val, int closed, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Axis,AxisIn))( this, lo, hi, val, closed, status ); -} -const char *astGetAxisNormUnit_( AstAxis *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Axis,GetAxisNormUnit))( this, status ); -} -int astTestAxisNormUnit_( AstAxis *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Axis,TestAxisNormUnit))( this, status ); -} -const char *astGetAxisInternalUnit_( AstAxis *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Axis,GetAxisInternalUnit))( this, status ); -} -int astTestAxisInternalUnit_( AstAxis *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Axis,TestAxisInternalUnit))( this, status ); -} -void astAxisNormValues_( AstAxis *this, int oper, int nval, double *values, - int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Axis,AxisNormValues))( this, oper, nval, values, status ); -} - - - - - - diff --git a/ast/axis.h b/ast/axis.h deleted file mode 100644 index 3b053c5..0000000 --- a/ast/axis.h +++ /dev/null @@ -1,625 +0,0 @@ -#if !defined( AXIS_INCLUDED ) /* Include this file only once */ -#define AXIS_INCLUDED -/* -*+ -* Name: -* axis.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Axis class. - -* Invocation: -* #include "axis.h" - -* Description: -* This include file defines the interface to the Axis class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The Axis class implements the basic behaviour of a coordinate -* axis, several of which may be assembled to represent a -* coordinate system. - -* Inheritance: -* The Axis class inherits from the Object class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* Bottom (double) -* Lowest legal value for axis. -* Digits (integer) -* Specifies how many digits of precision are required by -* default when a coordinate value for an Axis is formatted -* (e.g. using the astAxisFormat method). The Digits value acts -* as a default only and is over-ridden if a Format string is -* specified explicitly (using the astSetAxisFormat method). The -* default supplied by the Axis class for the Digits attribute -* itself is 7. -* Direction (integer) -* Specifies how coordinate values for an Axis should be -* displayed. By default, it has the value one, indicating that -* they should be shown in the conventional sense -* (i.e. increasing left to right for an abscissa and bottom to -* top for an ordinate). If set to zero, this attribute -* indicates that the direction should be reversed (as would -* often be done for an astronomical magnitude or a right -* ascension axis, for example). -* Format (string) -* Specifies the format to be used to display coordinate values -* for an Axis (i.e. to convert them from binary to character -* form). The interpretation of this string (e.g. by derived -* classes) is left to the astAxisFormat method, but the Axis -* class interprets this parameter as a C "printf" format string -* which should be capable of formatting a single coordinate -* value stored as a double (e.g. "%1.7G"). If no Format string -* is set, the default supplied by the Axis class is based on -* the value of the Digits attribute. -* Label (string) -* Specifies the label to be attached to an Axis when it is -* represented in (e.g.) a graph. It is intended purely for -* interpretation by human readers and not by software. The -* default supplied by the Axis class is the string "Coordinate -* Axis". -* Symbol (string) -* Specifies the symbol to be used to represent coordinate -* values for an Axis in "short form", such as in algebraic -* expressions where a full description of the Axis would be -* inappropriate. Examples include "RA" and "Dec" (for Right -* Ascension and Declination). The default supplied by the Axis -* class is the string "x". -* Top (double) -* Highest legal value for axis. -* Unit (string) -* Describes the units used to represent coordinate values on an -* Axis. The default supplied by the Axis class is an empty -* string "". - -* Methods Over-Ridden: -* Public: -* None. - -* Protected: -* astSetAttrib -* Set an attribute value for an Axis. - -* New Methods Defined: -* Public: -* astAxisFormat -* Format a coordinate value for an Axis. -* astAxisNorm -* Normalise an Axis coordinate value. -* astAxisUnformat -* Read a formatted coordinate value for an Axis. - -* Protected: -* astAxisAbbrev -* Abbreviate a formatted Axis value by skipping leading fields. -* astAxisDistance -* Find the distance between two axis values. -* astAxisFields -* Identify the fields within a formatted SkyAxis value. -* astAxisCentre -* Find a "nice" central axis value. -* astAxisGap -* Find a "nice" gap for tabulating Axis values. -* astAxisOffset -* Add an increment onto a supplied axis value. -* astAxisOverlay -* Overlay the attributes of a template Axis on to another Axis. -* astClearAxisDigits -* Clear the Digits attribute for an Axis. -* astClearAxisDirection -* Clear the Direction attribute for an Axis. -* astClearAxisFormat -* Clear the Format attribute for an Axis. -* astClearAxisLabel -* Clear the Label attribute for an Axis. -* astClearAxisSymbol -* Clear the Symbol attribute for an Axis. -* astClearAxisUnit -* Clear the Unit attribute for an Axis. -* astGetAxisDigits -* Get the value of the Digits attribute for an Axis. -* astGetAxisDirection -* Get the value of the Direction attribute for an Axis. -* astGetAxisFormat -* Get a pointer to the Format attribute for an Axis. -* astGetAxisLabel -* Get a pointer to the Label attribute for an Axis. -* astGetAxisSymbol -* Get a pointer to the Symbol attribute for an Axis. -* astGetAxisUnit -* Get a pointer to the Unit attribute for an Axis. -* astSetAxisDigits -* Set the value of the Digits attribute for an Axis. -* astSetAxisDirection -* Set the value of the Direction attribute for an Axis. -* astSetAxisFormat -* Set the value of the Format attribute for an Axis. -* astSetAxisLabel -* Set the value of the Label attribute for an Axis. -* astSetAxisSymbol -* Set the value of the Symbol attribute for an Axis. -* astSetAxisUnit -* Set the value of the Unit attribute for an Axis. -* astTestAxisDigits -* Test whether a value has been set for the Digits attribute of an -* Axis. -* astTestAxisDirection -* Test whether a value has been set for the Direction attribute of an -* Axis. -* astTestAxisFormat -* Test whether a value has been set for the Format attribute of an -* Axis. -* astTestAxisLabel -* Test whether a value has been set for the Label attribute of an -* Axis. -* astTestAxisSymbol -* Test whether a value has been set for the Symbol attribute of an -* Axis. -* astTestAxisUnit -* Test whether a value has been set for the Unit attribute of an -* Axis. - -* Other Class Functions: -* Public: -* astAxis -* Create an Axis. -* astIsAAxis -* Test class membership. - -* Protected: -* astCheckAxis -* Validate class membership. -* astInitAxis -* Initialise an Axis. -* astLoadAxis -* Load an Axis. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstAxis -* Axis object type. - -* Protected: -* AstAxisVtab -* Axis virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: B.S. Berry (Starlink) - -* History: -* 1-MAR-1996 (RFWS): -* Original version. -* 25-APR-1996 (RFWS): -* Made all attribute access functions protected. -* 10-SEP-1996 (RFWS): -* Added I/O facilities. -* 11-SEP-1996 (RFWS): -* Added astAxisGap (written by DSB). -* 25-FEB-1998 (RFWS): -* Added astAxisUnformat. -* 29-AUG-2001 (DSB): -* Added AxisDistance and AxisOffset. -* 10-OCT-2002 (DSB): -* Added Top and Bottom. -* 8-JAN-2003 (DSB): -* Added protected astInitAxisVtab method. -* 17-APR-2015 (DSB): -* Added astAxisCentre. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#if defined(astCLASS) /* Protected */ -#include "channel.h" -#endif - - -/* Macros */ -/* ====== */ -#if defined(astCLASS) -#define AST__AXIS_GETDEFAULTFORMAT_BUFF_LEN 50 -#define AST__AXIS_AXISFORMAT_BUFF_LEN 127 -#define AST__AXIS_GETAXISNORMUNIT_BUFF_LEN 127 -#define AST__AXIS_GETATTRIB_BUFF_LEN 50 -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* Axis structure. */ -/* --------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstAxis { - -/* Attributes inherited from the parent class. */ - AstObject object; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - char *label; /* Pointer to label string */ - char *format; /* Pointer to format string */ - char *symbol; /* Pointer to symbol string */ - char *unit; /* Pointer to unit string */ - int digits; /* Default digits of precision */ - int direction; /* Plot in conventional direction? */ - double top; /* Highest legal axis value */ - double bottom; /* Lowest legal axis value */ -} AstAxis; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ - -typedef struct AstAxisVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstObjectVtab object_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - const char *(* AxisAbbrev)( AstAxis *, const char *, const char *, const char *, int * ); - const char *(* AxisFormat)( AstAxis *, double, int * ); - const char *(* GetAxisFormat)( AstAxis *, int * ); - const char *(* GetAxisLabel)( AstAxis *, int * ); - const char *(* GetAxisSymbol)( AstAxis *, int * ); - const char *(* GetAxisUnit)( AstAxis *, int * ); - const char *(* GetAxisInternalUnit)( AstAxis *, int * ); - const char *(* GetAxisNormUnit)( AstAxis *, int * ); - double (* AxisCentre)( AstAxis *, double, double, int * ); - double (* AxisGap)( AstAxis *, double, int *, int * ); - double (* AxisDistance)( AstAxis *, double, double, int * ); - double (* AxisOffset)( AstAxis *, double, double, int * ); - int (* AxisIn)( AstAxis *, double, double, double, int, int * ); - int (* AxisFields)( AstAxis *, const char *, const char *, int, char **, int *, double *, int * ); - int (* AxisUnformat)( AstAxis *, const char *, double *, int * ); - int (* GetAxisDigits)( AstAxis *, int * ); - int (* GetAxisDirection)( AstAxis *, int * ); - int (* TestAxisDigits)( AstAxis *, int * ); - int (* TestAxisDirection)( AstAxis *, int * ); - int (* TestAxisFormat)( AstAxis *, int * ); - int (* TestAxisLabel)( AstAxis *, int * ); - int (* TestAxisSymbol)( AstAxis *, int * ); - int (* TestAxisUnit)( AstAxis *, int * ); - int (* TestAxisInternalUnit)( AstAxis *, int * ); - int (* TestAxisNormUnit)( AstAxis *, int * ); - void (* AxisNorm)( AstAxis *, double *, int * ); - void (* AxisNormValues)( AstAxis *, int, int, double *, int * ); - void (* AxisOverlay)( AstAxis *, AstAxis *, int * ); - void (* ClearAxisDigits)( AstAxis *, int * ); - void (* ClearAxisDirection)( AstAxis *, int * ); - void (* ClearAxisFormat)( AstAxis *, int * ); - void (* ClearAxisLabel)( AstAxis *, int * ); - void (* ClearAxisSymbol)( AstAxis *, int * ); - void (* ClearAxisUnit)( AstAxis *, int * ); - void (* SetAxisDigits)( AstAxis *, int, int * ); - void (* SetAxisDirection)( AstAxis *, int, int * ); - void (* SetAxisFormat)( AstAxis *, const char *, int * ); - void (* SetAxisLabel)( AstAxis *, const char *, int * ); - void (* SetAxisSymbol)( AstAxis *, const char *, int * ); - void (* SetAxisUnit)( AstAxis *, const char *, int * ); - - double (* GetAxisTop)( AstAxis *, int * ); - int (* TestAxisTop)( AstAxis *, int * ); - void (* ClearAxisTop)( AstAxis *, int * ); - void (* SetAxisTop)( AstAxis *, double, int * ); - - double (* GetAxisBottom)( AstAxis *, int * ); - int (* TestAxisBottom)( AstAxis *, int * ); - void (* ClearAxisBottom)( AstAxis *, int * ); - void (* SetAxisBottom)( AstAxis *, double, int * ); - -} AstAxisVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstAxisGlobals { - AstAxisVtab Class_Vtab; - int Class_Init; - char GetDefaultFormat_Buff[ AST__AXIS_GETDEFAULTFORMAT_BUFF_LEN + 1 ]; - char AxisFormat_Buff[ AST__AXIS_AXISFORMAT_BUFF_LEN + 1 ]; - char GetAxisNormUnit_Buff[ AST__AXIS_GETAXISNORMUNIT_BUFF_LEN + 1 ]; - char GetAttrib_Buff[ AST__AXIS_GETATTRIB_BUFF_LEN + 1 ]; -} AstAxisGlobals; - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Axis) /* Check class membership */ -astPROTO_ISA(Axis) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstAxis *astAxis_( const char *, int *, ...); -#else -AstAxis *astAxisId_( const char *, ... )__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstAxis *astInitAxis_( void *, size_t, int, AstAxisVtab *, const char *, int * ); - -/* Vtab initialiser. */ -void astInitAxisVtab_( AstAxisVtab *, const char *, int * ); - -/* Loader. */ -AstAxis *astLoadAxis_( void *, size_t, AstAxisVtab *, const char *, - AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitAxisGlobals_( AstAxisGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -const char *astAxisFormat_( AstAxis *, double, int * ); -int astAxisUnformat_( AstAxis *, const char *, double *, int * ); -void astAxisNorm_( AstAxis *, double *, int * ); -void astAxisNormValues_( AstAxis *, int, int, double *, int * ); - -#if defined(astCLASS) /* Protected */ -const char *astAxisAbbrev_( AstAxis *, const char *, const char *, const char *, int * ); -const char *astGetAxisFormat_( AstAxis *, int * ); -const char *astGetAxisLabel_( AstAxis *, int * ); -const char *astGetAxisSymbol_( AstAxis *, int * ); -const char *astGetAxisUnit_( AstAxis *, int * ); -const char *astGetAxisNormUnit_( AstAxis *, int * ); -const char *astGetAxisInternalUnit_( AstAxis *, int * ); -double astAxisCentre_( AstAxis *, double, double, int * ); -double astAxisGap_( AstAxis *, double, int *, int * ); -double astAxisDistance_( AstAxis *, double, double, int * ); -double astAxisOffset_( AstAxis *, double, double, int * ); -int astGetAxisDigits_( AstAxis *, int * ); -int astGetAxisDirection_( AstAxis *, int * ); -int astTestAxisDigits_( AstAxis *, int * ); -int astTestAxisDirection_( AstAxis *, int * ); -int astAxisFields_( AstAxis *, const char *, const char *, int, char **, int *, double *, int * ); -int astAxisIn_( AstAxis *, double, double, double, int, int * ); -int astTestAxisFormat_( AstAxis *, int * ); -int astTestAxisLabel_( AstAxis *, int * ); -int astTestAxisSymbol_( AstAxis *, int * ); -int astTestAxisUnit_( AstAxis *, int * ); -int astTestAxisNormUnit_( AstAxis *, int * ); -int astTestAxisInternalUnit_( AstAxis *, int * ); -void astAxisOverlay_( AstAxis *, AstAxis *, int * ); -void astClearAxisDigits_( AstAxis *, int * ); -void astClearAxisDirection_( AstAxis *, int * ); -void astClearAxisFormat_( AstAxis *, int * ); -void astClearAxisLabel_( AstAxis *, int * ); -void astClearAxisSymbol_( AstAxis *, int * ); -void astClearAxisUnit_( AstAxis *, int * ); -void astSetAxisDigits_( AstAxis *, int, int * ); -void astSetAxisDirection_( AstAxis *, int, int * ); -void astSetAxisFormat_( AstAxis *, const char *, int * ); -void astSetAxisLabel_( AstAxis *, const char *, int * ); -void astSetAxisSymbol_( AstAxis *, const char *, int * ); -void astSetAxisUnit_( AstAxis *, const char *, int * ); - -double astGetAxisTop_( AstAxis *, int * ); -int astTestAxisTop_( AstAxis *, int * ); -void astClearAxisTop_( AstAxis *, int * ); -void astSetAxisTop_( AstAxis *, double, int * ); - -double astGetAxisBottom_( AstAxis *, int * ); -int astTestAxisBottom_( AstAxis *, int * ); -void astClearAxisBottom_( AstAxis *, int * ); -void astSetAxisBottom_( AstAxis *, double, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckAxis(this) astINVOKE_CHECK(Axis,this,0) -#define astVerifyAxis(this) astINVOKE_CHECK(Axis,this,1) - -/* Test class membership. */ -#define astIsAAxis(this) astINVOKE_ISA(Axis,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astAxis astINVOKE(F,astAxis_) -#else -#define astAxis astINVOKE(F,astAxisId_) -#endif - -#if defined(astCLASS) /* Protected. */ - -/* Initialiser. */ -#define astInitAxis(mem,size,init,vtab,name) \ -astINVOKE(O,astInitAxis_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitAxisVtab(vtab,name) astINVOKE(V,astInitAxisVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadAxis(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadAxis_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckAxis to validate Axis pointers before - use. This provides a contextual error report if a pointer to the - wrong sort of object is supplied. */ -#define astAxisFormat(this,value) \ -astINVOKE(V,astAxisFormat_(astCheckAxis(this),value,STATUS_PTR)) -#define astAxisNorm(this,value) \ -astINVOKE(V,astAxisNorm_(astCheckAxis(this),value,STATUS_PTR)) -#define astAxisNormValues(this,oper,nval,values) \ -astINVOKE(V,astAxisNormValues_(astCheckAxis(this),oper,nval,values,STATUS_PTR)) -#define astAxisUnformat(this,string,value) \ -astINVOKE(V,astAxisUnformat_(astCheckAxis(this),string,value,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astAxisAbbrev(this,fmt,str1,str2) \ -astINVOKE(V,astAxisAbbrev_(astCheckAxis(this),fmt,str1,str2,STATUS_PTR)) -#define astAxisCentre(this,value,gap) \ -astINVOKE(V,astAxisCentre_(astCheckAxis(this),value,gap,STATUS_PTR)) -#define astAxisGap(this,gap,ntick) \ -astINVOKE(V,astAxisGap_(astCheckAxis(this),gap,ntick,STATUS_PTR)) -#define astAxisFields(this,fmt,str,maxfld,fields,nc,val) \ -astINVOKE(V,astAxisFields_(astCheckAxis(this),fmt,str,maxfld,fields,nc,val,STATUS_PTR)) -#define astAxisIn(this,lo,hi,val,closed) \ -astINVOKE(V,astAxisIn_(astCheckAxis(this),lo,hi,val,closed,STATUS_PTR)) -#define astAxisDistance(this,v1,v2) \ -astINVOKE(V,astAxisDistance_(astCheckAxis(this),v1,v2,STATUS_PTR)) -#define astAxisOffset(this,v1,dist) \ -astINVOKE(V,astAxisOffset_(astCheckAxis(this),v1,dist,STATUS_PTR)) -#define astAxisOverlay(template,result) \ -astINVOKE(V,astAxisOverlay_(astCheckAxis(template),astCheckAxis(result),STATUS_PTR)) -#define astClearAxisDigits(this) \ -astINVOKE(V,astClearAxisDigits_(astCheckAxis(this),STATUS_PTR)) -#define astClearAxisDirection(this) \ -astINVOKE(V,astClearAxisDirection_(astCheckAxis(this),STATUS_PTR)) -#define astClearAxisFormat(this) \ -astINVOKE(V,astClearAxisFormat_(astCheckAxis(this),STATUS_PTR)) -#define astClearAxisLabel(this) \ -astINVOKE(V,astClearAxisLabel_(astCheckAxis(this),STATUS_PTR)) -#define astClearAxisSymbol(this) \ -astINVOKE(V,astClearAxisSymbol_(astCheckAxis(this),STATUS_PTR)) -#define astClearAxisUnit(this) \ -astINVOKE(V,astClearAxisUnit_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisDigits(this) \ -astINVOKE(V,astGetAxisDigits_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisDirection(this) \ -astINVOKE(V,astGetAxisDirection_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisFormat(this) \ -astINVOKE(V,astGetAxisFormat_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisLabel(this) \ -astINVOKE(V,astGetAxisLabel_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisSymbol(this) \ -astINVOKE(V,astGetAxisSymbol_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisUnit(this) \ -astINVOKE(V,astGetAxisUnit_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisNormUnit(this) \ -astINVOKE(V,astGetAxisInternalUnit_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisInternalUnit(this) \ -astINVOKE(V,astGetAxisInternalUnit_(astCheckAxis(this),STATUS_PTR)) -#define astSetAxisDigits(this,digits) \ -astINVOKE(V,astSetAxisDigits_(astCheckAxis(this),digits,STATUS_PTR)) -#define astSetAxisDirection(this,direction) \ -astINVOKE(V,astSetAxisDirection_(astCheckAxis(this),direction,STATUS_PTR)) -#define astSetAxisFormat(this,format) \ -astINVOKE(V,astSetAxisFormat_(astCheckAxis(this),format,STATUS_PTR)) -#define astSetAxisLabel(this,label) \ -astINVOKE(V,astSetAxisLabel_(astCheckAxis(this),label,STATUS_PTR)) -#define astSetAxisSymbol(this,symbol) \ -astINVOKE(V,astSetAxisSymbol_(astCheckAxis(this),symbol,STATUS_PTR)) -#define astSetAxisUnit(this,unit) \ -astINVOKE(V,astSetAxisUnit_(astCheckAxis(this),unit,STATUS_PTR)) -#define astTestAxisDigits(this) \ -astINVOKE(V,astTestAxisDigits_(astCheckAxis(this),STATUS_PTR)) -#define astTestAxisDirection(this) \ -astINVOKE(V,astTestAxisDirection_(astCheckAxis(this),STATUS_PTR)) -#define astTestAxisFormat(this) \ -astINVOKE(V,astTestAxisFormat_(astCheckAxis(this),STATUS_PTR)) -#define astTestAxisLabel(this) \ -astINVOKE(V,astTestAxisLabel_(astCheckAxis(this),STATUS_PTR)) -#define astTestAxisSymbol(this) \ -astINVOKE(V,astTestAxisSymbol_(astCheckAxis(this),STATUS_PTR)) -#define astTestAxisUnit(this) \ -astINVOKE(V,astTestAxisUnit_(astCheckAxis(this),STATUS_PTR)) -#define astTestAxisNormUnit(this) \ -astINVOKE(V,astTestAxisNormUnit_(astCheckAxis(this),STATUS_PTR)) -#define astTestAxisInternalUnit(this) \ -astINVOKE(V,astTestAxisInternalUnit_(astCheckAxis(this),STATUS_PTR)) - -#define astClearAxisTop(this) \ -astINVOKE(V,astClearAxisTop_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisTop(this) \ -astINVOKE(V,astGetAxisTop_(astCheckAxis(this),STATUS_PTR)) -#define astSetAxisTop(this,top) \ -astINVOKE(V,astSetAxisTop_(astCheckAxis(this),top,STATUS_PTR)) -#define astTestAxisTop(this) \ -astINVOKE(V,astTestAxisTop_(astCheckAxis(this),STATUS_PTR)) - -#define astClearAxisBottom(this) \ -astINVOKE(V,astClearAxisBottom_(astCheckAxis(this),STATUS_PTR)) -#define astGetAxisBottom(this) \ -astINVOKE(V,astGetAxisBottom_(astCheckAxis(this),STATUS_PTR)) -#define astSetAxisBottom(this,bottom) \ -astINVOKE(V,astSetAxisBottom_(astCheckAxis(this),bottom,STATUS_PTR)) -#define astTestAxisBottom(this) \ -astINVOKE(V,astTestAxisBottom_(astCheckAxis(this),STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/bootstrap b/ast/bootstrap deleted file mode 100755 index b1b79e9..0000000 --- a/ast/bootstrap +++ /dev/null @@ -1,134 +0,0 @@ -#! /bin/sh - -# original bootstrap file, installed by starconf 1.3, rnum=1003000 -# If you _need_ to change this file, delete `original' in the line above, -# or else starconf may overwrite it with an updated version. -# -# bootstrap.installed. Generated from bootstrap.installed.in by configure. -# -# Bootstrap a checked-out component of the Starlink software tree. -# Run this script in a freshly checked-out directory to bring the -# system to the point where you can just type ./configure;make -# -# Usage: -# ./bootstrap - - -# This script should be installed, by starconf, in all `component -# directories'. A `component directory' is a directory which has a -# component.xml.in file in it. All component directories will have a -# manifest file created and installed in .../manifests; non-component -# directories will not have manifest files. Everything that's -# installed should be installed as part of some component -# or other. -# -# The ./bootstrap scripts will stop recursing when they find a -# component.xml.in file. They'll warn if they find a component.xml.in -# file in any AC_CONFIG_SUBDIRS directory, but ignore it, and exit -# with an error if they do not find a component.xml.in file and there -# are no AC_CONFIG_SUBDIRS directories in which to search further. -# That is, the tree of directories which the top-level bootstrap -# traverses should have component.xml.in files at or above all its -# leaves. - - -# The starconf below might update bootstrap, if a newer version is -# available. Unfortunately, this confuses sh, which appears _not_ to -# keep open the script it's reading, but to reopen it afresh, or reseek -# within the file, for each line (or something like that!?). -# So rewrite this script to a temporary file and exec it. -tempfile="${TMP-/tmp}/$0-$$.tmp" -rm -f $tempfile -echo "trap 'rm -f $tempfile' 0" >$tempfile # remove temporary at exit -sed '1,/^--TRAMPOLINE--/d' $0 >>$tempfile # strip out the trampoline -exec /bin/sh $tempfile # exec the temporary ---TRAMPOLINE-- - - -echo "Bootstrapping `pwd` ..." - -if test ! -f configure.ac; then - echo "bootstrap: No configure.ac in directory `pwd`" >&2 - exit 1 -fi - -subdirs=`autoconf --trace=AC_CONFIG_SUBDIRS:$% configure.ac` - -if test -f component.xml.in; then - - if starconf --show buildsupport >/dev/null 2>&1; then - - # starconf is in the path - echo "...using starconf in " `starconf --show buildsupport` - starconf || exit 1 - - else - - # The temptation here is to use ./starconf.status to find the - # starconf that it came from and invoke that explicitly. Don't do - # this, however: we don't want to be too clever, and it's better - # to be consistent with the way the autotools behave (the first - # one in your path is the one that works, and they don't have this - # sort of `phone home' cleverness in them). - - echo "bootstrap error: The starconf application is not in your path" - - # This doesn't stop us being helpful, however. - if test -f ./starconf.status; then - starconf_home=`./starconf.status --show buildsupport` - echo "This directory was last bootstrapped with $starconf_home/bin/starconf" - fi - - exit 1 - fi - - # Check that there are no component.xml.in files in any subdirectories - if test -n "$subdirs"; then - for d in $subdirs - do - if test -d "$d" && test -f "$d/component.xml.in"; then - echo "bootstrap: warning: ignoring child $d/component.xml.in" >&2 - fi - done - fi - - # If STAR_SUPPRESS_AUTORECONF is true in the environment, then we - # suppress the call of `autoreconf'. This is here _only_ so that - # the top-level bootstrap file can suppress multiple calls of this - # in bootstrap scripts in its children. This mechanism must not - # be used by users, as it is likely to change without warning. - if ${STAR_SUPPRESS_AUTORECONF-false}; then - echo "Suppressing autoreconf in" `pwd` - else - echo autoreconf --install --symlink - autoreconf --install --symlink || exit 1 - fi - -else - - # This is not a component directory, so simply recurse into the children. - - # ...if there are any, that is. - if test -z "$subdirs"; then - echo "bootstrap: error: non-component directory `pwd` has no subdirs" >&2 - exit 1 - fi - - # Bootstrap the child directories mentioned in AC_CONFIG_SUBDIRS. - # These bootstrap files must exist. - for d in $subdirs - do - if test -d "$d"; then - echo "Bootstrapping $d..." - if test -f $d/bootstrap; then - # good... - (cd $d; /bin/sh ./bootstrap) - else - echo "bootstrap: no file $d/bootstrap" >&2 - exit 1 - fi - fi - done - -fi - -exit 0 diff --git a/ast/box.c b/ast/box.c deleted file mode 100644 index 99aa780..0000000 --- a/ast/box.c +++ /dev/null @@ -1,5062 +0,0 @@ -/* -*class++ -* Name: -* Box - -* Purpose: -* A box region with sides parallel to the axes of a Frame. - -* Constructor Function: -c astBox -f AST_BOX - -* Description: -* The Box class implements a Region which represents a box with sides -* parallel to the axes of a Frame (i.e. an area which encloses a given -* range of values on each axis). A Box is similar to an Interval, the -* only real difference being that the Interval class allows some axis -* limits to be unspecified. Note, a Box will only look like a box if -* the Frame geometry is approximately flat. For instance, a Box centred -* close to a pole in a SkyFrame will look more like a fan than a box -* (the Polygon class can be used to create a box-like region close to a -* pole). - -* Inheritance: -* The Box class inherits from the Region class. - -* Attributes: -* The Box class does not define any new attributes beyond -* those which are applicable to all Regions. - -* Functions: -c The Box class does not define any new functions beyond those -f The Box class does not define any new routines beyond those -* which are applicable to all Regions. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2008-2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-MAR-2004 (DSB): -* Original version. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 5-JUN-2007 (DSB): -* Improve astSimplify algorithm. -* 6-JUN-2007 (DSB): -* Change the iterating algorithm in MakeGrid so that it uses -* pixel index rather than axis value. This is more robust against -* rounding errors. -* 9-OCT-2007 (DSB): -* - Fix bug in RegBaseMesh that could cause incorrect meshes for 2D -* Boxes. -* - In RegBaseMesh, use flat geometry if all axes come from simple -* frames or from 1-dimensional specialist frames. -* 26-MAY-2008 (DSB): -* Fix bug in RegBaseMesh that caused an error to be reported if -* the Box occupies a single point. -* 20-JAN-2009 (DSB): -* Over-ride astRegBasePick. -* 26-JAN-2009 (DSB): -* Over-ride astMapMerge. -* 12-JUL-2009 (DSB): -* Modify Simplify so that if a Box can be split into two -* simpler components and then joined together into a Prism, it -* does so. This is because being able to express a Region in -* its current Frame is more important than having the simplest -* possible structure. -* 28-FEB-2011 (DSB): -* Do not assume the first axis value is good in function BestBox. -* 22-MAR-2011 (DSB): -* Improve uniformity of points within grid produced by astRegBaseGrid. -* 16-JUL-2013 (DSB): -* Use a more robust algorithm for determining the order of the -* vertices whan a Box is simplified to a Polygon. The old method -* sometimes resulted in an unbounded "inside-out" polygon. -* 4-NOV-2013 (DSB): -* Modify RegPins so that it can handle uncertainty regions that straddle -* a discontinuity. Previously, such uncertainty Regions could have a huge -* bounding box resulting in matching region being far too big. -* 10-APR-2014 (DSB): -* More work (in function Cache() ) on handling uncertainty regions that straddle -* a discontinuity. This time ensure that the extent of the box on each axis takes -* account of the possibly cyclic nature of the base Frame. -* 25-4-2016 (DSB): -* Remove the unused box shrinking facility (a hang over from the -* days when the RegBaseGrid function operated by creating multiple -* meshes on the surface of the box, shrinking the box each time). -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Box - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "cmpmap.h" /* Compound Mappings */ -#include "cmpframe.h" /* Compound Frames */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "region.h" /* Coordinate regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "box.h" /* Interface definition for this class */ -#include "polygon.h" /* Interface definition for this class */ -#include "mapping.h" /* Position mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "permmap.h" /* Axis permutation Mappings */ -#include "interval.h" /* Axis interval regions */ -#include "nullregion.h" /* Empty regions */ -#include "pointlist.h" /* List of points in a Frame */ -#include "prism.h" /* Extruded regions */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstMapping *(* parent_simplify)( AstMapping *, int * ); -static void (* parent_setnegated)( AstRegion *, int, int * ); -static void (* parent_setclosed)( AstRegion *, int, int * ); -static void (* parent_clearnegated)( AstRegion *, int * ); -static void (* parent_clearclosed)( AstRegion *, int * ); -static void (* parent_setunc)( AstRegion *, AstRegion *, int * ); -static void (* parent_setregfs)( AstRegion *, AstFrame *, int * ); -static void (* parent_resetcache)( AstRegion *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Box) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Box,Class_Init) -#define class_vtab astGLOBAL(Box,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstBoxVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstBox *astBoxId_( void *, int, const double[], const double[], void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstBox *BestBox( AstFrame *, AstPointSet *, AstRegion *, int * ); -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *RegBaseGrid( AstRegion *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *MergeBox( AstBox *, AstRegion *, int, int * ); -static AstRegion *RegBasePick( AstRegion *this, int, const int *, int * ); -static double *GeoCorner( AstFrame *, int, double *, double *, double *, int * ); -static double *GeoLengths( AstFrame *, int, double *, double *, double *, int * ); -static double *RegCentre( AstRegion *this, double *, double **, int, int, int * ); -static int GetObjSize( AstObject *, int * ); -static int MakeGrid( int, double **, int, double *, double *, int *, int, int, double, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static int RegTrace( AstRegion *, int, double *, double **, int * ); -static void BoxPoints( AstBox *, double *, double *, int *); -static void Cache( AstBox *, int, int * ); -static void ClearClosed( AstRegion *, int * ); -static void ClearNegated( AstRegion *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void RegBaseBox( AstRegion *this, double *, double *, int * ); -static void ResetCache( AstRegion *this, int * ); -static void SetClosed( AstRegion *, int, int * ); -static void SetNegated( AstRegion *, int, int * ); -static void SetRegFS( AstRegion *, AstFrame *, int * ); -static void SetUnc( AstRegion *, AstRegion *, int * ); - -/* Member functions. */ -/* ================= */ - -void BoxPoints( AstBox *this, double *centre, double *corner, int *status) { -/* -*+ -* Name: -* astBoxPoints - -* Purpose: -* Return the defining points of a Box. - -* Type: -* Protected function. - -* Synopsis: -* #include "box.h" -* astBoxPoints( AstBox *this, double *centre, double *corner ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns the axis values at the points defining the -* supplied Box. - -* Parameters: -* this -* Pointer to the Box. -* centre -* A pointer to an array in which to return the centre position of -* the Box, in the base Frame of the encapsulated FrameSet. -* corner -* A pointer to an array in which to return the position of a corner -* of the Box, in the base Frame of the encapsulated FrameSet. - -* Notes: -* - It is assumed that the length of the supplied arrays is at least -* equal to the number of axes in the base frame of the encapsulated -* FrameSet. -*- -*/ - -/* Local Variables: */ - AstPointSet *pset; - double **ptr; - int nc; - int i; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Get a pointer to the PointSet holding the points defining the Box. */ - pset = ((AstRegion *) this)->points; - -/* Get a pointer to the PointSet's data arrays. */ - ptr = astGetPoints( pset ); - -/* See how many axes each point in the PointSet has. */ - nc = astGetNcoord( pset ); - -/* Copy the centre and corner positions form the PointSet into the - supplied arrays. */ - for( i = 0; i < nc; i++ ) { - centre[ i ] = ptr[ i ] [ 0 ]; - corner[ i ] = ptr[ i ] [ 1 ]; - } - -} - -static void ClearClosed( AstRegion *this, int *status ){ -/* -* Name: -* ClearClosed - -* Purpose: -* Clear the Closed attribute of a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* void ClearClosed( AstRegion *this, int *status ) - -* Class Membership: -* Box member function (over-rides the protected astClearClosed -* method inherited from the Region class). - -* Description: -* This function clears the Closed attribute of the supplied Region. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int old; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the original attribute value */ - old = astGetClosed( this ); - -/* Invoke the clear method inherited from the parent Region class */ - (*parent_clearclosed)( this, status ); - -/* If the new value is not the same as the old value, inidcatethat we - need to re-calculate the cached information in the Box. */ - if( astGetClosed( this ) != old ) astResetCache( this ); -} - -static void ClearNegated( AstRegion *this, int *status ){ -/* -* Name: -* ClearNegated - -* Purpose: -* Clear the Negated attribute of a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* void ClearNegated( AstRegion *this, int *status ) - -* Class Membership: -* Box member function (over-rides the protected astClearNegated -* method inherited from the Region class). - -* Description: -* This function clears the Negated attribute of the supplied Region. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int old; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the original attribute value */ - old = astGetNegated( this ); - -/* Invoke the clear method inherited from the parent Region class */ - (*parent_clearnegated)( this, status ); - -/* If the new value is not the same as the old value, inidcatethat we - need to re-calculate the cached information in the Box. */ - if( astGetNegated( this ) != old ) astResetCache( this ); -} - -static AstBox *BestBox( AstFrame *frm, AstPointSet *mesh, AstRegion *unc, int *status ){ -/* -* Name: -* BestBox - -* Purpose: -* Find the best fitting Box through a given mesh of points. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* AstBox *BestBox( AstFrame *frm, AstPointSet *mesh, AstRegion *unc, int *status ) - -* Class Membership: -* Box member function - -* Description: -* This function finds the best fitting Box through a given mesh of points. - -* Parameters: -* frm -* Defines the geometry of the axes. -* mesh -* Pointer to a PointSet holding the mesh of points. They are -* assumed to be in the Frame represented by "unc". -* unc -* A Region representing the uncertainty associated with each point -* on the mesh. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the best fitting Region. It will inherit the positional -* uncertainty and Frame represented by "unc". NULL is returned if all -* the supplied positions are bad. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - -/* Local Variables: */ - AstBox *result; - double **ptr; - double *axval; - double *blbnd; - double *bubnd; - double *lbnd; - double *p; - double *ubnd; - double eps; - double lb; - double lim2; - double lim; - double liml; - double limu; - double mxl; - double mxu; - double org; - double sxl2; - double sxl; - double sxu2; - double sxu; - double ub; - double p0; - double d; - double dinc; - int ic; - int ip; - int nc; - int np; - int nxl; - int nxu; - int ok; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get no. of points in the mesh, and the number of axis values per point. */ - np = astGetNpoint( mesh ); - nc = astGetNcoord( mesh ); - -/* Get pointers to the axis values. */ - ptr = astGetPoints( mesh ); - -/* Allocate work space. */ - lbnd = astMalloc( sizeof( double )*(size_t) nc ); - ubnd = astMalloc( sizeof( double )*(size_t) nc ); - - blbnd = astMalloc( sizeof( double )*(size_t) nc ); - bubnd = astMalloc( sizeof( double )*(size_t) nc ); - - axval = astMalloc( sizeof( double )*(size_t) np ); - -/* Check pointers can be used safely */ - if( axval ) { - -/* Get the bounding box of the uncertainty region. */ - astGetRegionBounds( unc, lbnd, ubnd ); - -/* We fit the box one axis at a time. */ - ok = 1; - for( ic = 0; ic < nc; ic++ ) { - -/* Find the first good value on this axis. */ - for( ip = 0; ip < np; ip++ ) { - org = ptr[ ic ][ ip ]; - axval[ ip ] = org; - if( org != AST__BAD ) break; - } - -/* Abort if all the axis values werebad. */ - if( ip >= np ) { - ok = 0; - break; - } - -/* Find the upper and lower limits of the supplied mesh on this axis. */ - lb = 0.0; - ub = 0.0; - ip++; - p = ptr[ ic ] + ip; - p0 = org; - d = 0.0; - for( ; ip < np; ip++, p++ ) { - dinc = astAxDistance( frm, ic + 1, p0, *p ); - if( dinc != AST__BAD ) { - d += dinc; - if( d < lb ) lb = d; - if( d > ub ) ub = d; - } - axval[ ip ] = org + d; - p0 = *p; - } - -/* Now convert these relative offsets to actual axis values. */ - lb += org; - ub += org; - -/* Now scan the list of axis values again, looking for values which are - "close to" either lower or upper bound. These will be the points which - are on the faces of the box which are orthogonal to the current axis. Here - "close to" means within 20 times the uncertainty associated with this - axis, or one tenth of the box size (which ever is smaller). We find the - mean and standard deviation of such "close" values, and then do a - single sigma-clipping iteration (at 3-sigma) to get rid of any values - which are on one of the other faces of the box. */ - - lim = 20*( ubnd[ ic ] - lbnd[ ic ] ); - lim2 = 0.1*( ub - lb ); - if( lim2 < lim ) lim = lim2; - - sxl = 0.0; - sxl2 = 0.0; - nxl = 0; - sxu = 0.0; - sxu2 = 0.0; - nxu = 0; - - p = axval; - for( ip = 0; ip < np; ip++, p++ ) { - if( *p != AST__BAD ) { - if( fabs( *p - lb ) <= lim ) { - sxl += *p; - sxl2 += (*p)*(*p); - nxl++; - } else if( fabs( *p - ub ) <= lim ) { - sxu += *p; - sxu2 += (*p)*(*p); - nxu++; - } - } - } - - if( nxl > 0 ) { - mxl = sxl/nxl; - liml = sxl2/nxl - mxl*mxl; - eps = 100*mxl*DBL_EPSILON; - if( liml < eps*eps ) { - liml = eps; - } else { - liml = 3.0*sqrt( liml ); - } - } else { - mxl = lb; - liml = 0.0; - } - - if( nxu > 0 ) { - mxu = sxu/nxu; - limu = sxu2/nxu - mxu*mxu; - eps = 100*mxu*DBL_EPSILON; - if( limu < eps*eps ) { - limu = eps; - } else { - limu = 3.0*sqrt( limu ); - } - - } else { - mxu = ub; - limu = 0.0; - } - - sxl = 0.0; - nxl = 0; - sxu = 0.0; - nxu = 0; - - p = axval; - for( ip = 0; ip < np; ip++, p++ ) { - if( *p != AST__BAD ) { - if( fabs( *p - mxl ) <= liml ) { - sxl += *p; - nxl++; - } else if( fabs( *p - mxu ) <= limu ) { - sxu += *p; - nxu++; - } - } - } - - if( nxl > 0 ) { - mxl = sxl/nxl; - } else { - mxl = lb; - } - - if( nxu > 0 ) { - mxu = sxu/nxu; - } else { - mxu = ub; - } - -/* The resulting mean axis values are the bounds of the required box on - the current axis.*/ - blbnd[ ic ] = mxl; - bubnd[ ic ] = mxu; - } - -/* If possible, create the returned Box. */ - if( ok ) result = astBox( unc, 1, blbnd, bubnd, unc, " ", status ); - } - -/* Free resources */ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - blbnd = astFree( blbnd ); - bubnd = astFree( bubnd ); - axval = astFree( axval ); - -/* Return NULL if anything went wrong. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result.*/ - return result; -} - -static void Cache( AstBox *this, int lohi, int *status ){ -/* -* Name: -* Cache - -* Purpose: -* Calculate intermediate values and cache them in the Box structure. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* void Cache( AstRegion *this, int lohi, int *status ) - -* Class Membership: -* Box member function - -* Description: -* This function uses the PointSet stored in the parent Region to calculate -* some intermediate values which are useful in other methods. These -* values are stored within the Box structure. - -* Parameters: -* this -* Pointer to the Box. -* lohi -* Are the lo and hi arrays to be used? -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *frm; - AstPointSet *pset; - AstRegion *unc; - double **ptr; - double *centre; - double *extent; - double *hi; - double *lbnd_unc; - double *geolen; - double *lo; - double *ubnd_unc; - double wid; - int i; - int nc; - -/* Check the global error status. Also return if the currently cached - information is usable. */ - if ( !astOK || !this->stale ) return; - -/* Get the number of base Frame axes. */ - nc = astGetNin( ((AstRegion *)this)->frameset ); - -/* Allocate memory to store the half-width of the box on each axis. */ - extent = (double *) astMalloc( sizeof( double )*(size_t) nc ); - -/* Allocate memory to store the centre of the box on each axis. */ - centre = (double *) astMalloc( sizeof( double )*(size_t) nc ); - -/* Allocate memory to store the high and low bounds. */ - hi = (double *) astMalloc( sizeof( double )*(size_t) nc ); - lo = (double *) astMalloc( sizeof( double )*(size_t) nc ); - -/* Memory to store the uncertainty bounding box */ - lbnd_unc = astMalloc( sizeof( double)*(size_t) nc ); - ubnd_unc = astMalloc( sizeof( double)*(size_t) nc ); - -/* Memory to store the geodesic half-dimensions of the box. */ - geolen = astMalloc( sizeof( double)*(size_t) nc ); - -/* Get pointers to the coordinate data in the parent Region structure. */ - pset = ((AstRegion *) this)->points; - ptr = astGetPoints( pset ); - -/* Check pointers can be used safely. */ - if( ptr ) { - -/* Store the centre and corner axis values. */ - for( i = 0; i < nc; i++ ) { - centre[ i ] = ptr[ i ][ 0 ]; - hi[ i ] = ptr[ i ][ 1 ]; - } - -/* Calculate the geodesic half-dimensions of the box. */ - frm = astGetFrame( ((AstRegion *) this)->frameset, AST__BASE ); - GeoLengths( frm, nc, centre, hi, geolen, status ); - -/* Calculate the half-width and store in the above array. Also store the - lower and upper bounds. */ - for( i = 0; i < nc; i++ ) { - extent[ i ] = fabs( astAxDistance( frm, i + 1, ptr[ i ][ 1 ], - centre[ i ] ) ); - lo[ i ] = centre[ i ] - extent[ i ]; - hi[ i ] = centre[ i ] + extent[ i ]; - } - - frm = astAnnul( frm ); - -/* Store the pointers to these arrays in the Box structure, and indicate - the information is usable. */ - if( astOK ) { - astFree( this->extent ); - astFree( this->centre ); - astFree( this->lo ); - astFree( this->hi ); - astFree( this->geolen ); - this->extent = extent; - this->centre = centre; - this->lo = lo; - this->hi = hi; - this->geolen = geolen; - this->stale = 0; - extent = NULL; - centre = NULL; - lo = NULL; - hi = NULL; - geolen = NULL; - } - -/* If lo and hi values are to be used, ensure they are expanded to at - least the width of an uncertainty box. */ - if( lohi ) { - -/* If we are dealing with an unnegated closed Box or a negated open - Box, ensure that the box does not have zero width on any axis. We do - this by ensuring that the extent on all axes is at least half the - width of the bounding box of the uncertainty Region. */ - if( astGetNegated( this ) != astGetClosed( this ) ) { - -/* Get the bounding box of the uncertainty Region in the base Frame of - the supplied Box. */ - unc = astGetUncFrm( this, AST__BASE ); - astGetRegionBounds( unc, lbnd_unc, ubnd_unc ); - -/* Ensure the extents are at least half the width of the uncertainty - bounding box. */ - for ( i = 0; i < nc; i++ ) { - wid = 0.5*( ubnd_unc[ i ] - lbnd_unc[ i ] ); - if( this->extent[ i ] < wid ) { - this->extent[ i ] = wid; - this->lo[ i ] = this->centre[ i ] - wid; - this->hi[ i ] = this->centre[ i ] + wid; - } - } - -/* Free resources. */ - unc = astAnnul( unc ); - } - } - } - -/* Annul the memory allocated above if an error occurred. */ - if( !astOK ) { - extent = astFree( extent ); - centre = astFree( centre ); - lo = astFree( lo ); - hi = astFree( hi ); - } - -/* Free other resources */ - lbnd_unc = astFree( lbnd_unc ); - ubnd_unc = astFree( ubnd_unc ); - -} - -static double *GeoCorner( AstFrame *frm, int nc, double *centre, - double *geolen, double *corner, int *status ){ -/* -* Name: -* GeoCorner - -* Purpose: -* Find the corner position implied by the supplied centre position -* and geodesic box dimensions. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* double *GeoCorner( AstFrame *frm, int nc, double *centre, -* double *geolen, double *corner, int *status ) - -* Class Membership: -* Box member function - -* Description: -* This function returns the corner position that is implied by the -* supplied centre position and geodesic box dimensions. The returned -* corner position is found by offsetting away from the supplied -* centre position along each axis in turn, by the geodesic distance -* specified in "geolen". - -* Parameters: -* frm -* Defines the geometry of the axes. -* nc -* The number of Frame axes. -* centre -* Pointer to an array holding the box centre axis values. -* geolen -* Pointer to an array holding the geodesic distance corresponding -* to each half axis of the box. -* corner -* Pointer to an array in which to store the axis values at the -* returned corner position. If this is NULL a new array is -* allocated and a pointer to it returned as the function value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the array holding the corner axis values. If a non-NULL -* value is supplied for parameter "corner", then the same value will -* be returned as the function value. Otherwise, the returned value -* will be a pointer to a newly allocated array that should be freed -* using astFree when no longer needed. - -*/ - -/* Local Variables: */ - double *p1; - double *p2; - double *p3; - double *pt; - double *result; - double *work1; - double *work2; - double off; - double off0; - int i; - -/* Initialise */ - result = corner; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Ensure we have a results array. */ - if( ! result ) result = astMalloc( sizeof( double )*nc ); - -/* Also allocate two work arrays to hold a single position. */ - work1 = astMalloc( sizeof( double )*nc ); - work2 = astMalloc( sizeof( double )*nc ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Select which array to use as the initial results array so that the - final results end up in the returned array. */ - if( ( nc % 2 ) == 0 ) { - p1 = result; - p2 = work1; - p3 = work2; - } else { - p1 = work2; - p2 = work1; - p3 = result; - } - -/* Initialise the current corner position to be at the centre of the box. */ - for( i = 0; i < nc; i++ ) p1[ i ] = centre[ i ]; - -/* Loop round offsetting along each side of the box. */ - for( i = 0; i < nc; i++ ) { - -/* In the p2 array put the axis values at a point which is offset - slightly along the current axis away from the current "corner" - position (p1). */ - memcpy( p2, p1, sizeof( double )*nc ); - - if( geolen[ i ] != 0.0 ) { - off = 0.0001*fabs( geolen[ i ] ); - } else { - off = 1.0E-6; - } - - off0 = fabs( 1.0E-10*centre[ i ] ); - if( off < off0 ) off = off0; - p2[ i ] += off; - -/* Offset away from the current corner position (p1) towards the position - found above (p2), moving by the geodesic distance supplied for this axis. - Put the resulting axis values in p3. */ - astOffset( frm, p1, p2, geolen[ i ], p3 ); - -/* Swap the p3 and p1 arrays so that the offset position found above (p3) - becomes the starting position (p1) for the next offset. */ - pt = p1; - p1 = p3; - p3 = pt; - } - } - -/* Free resources */ - work1 = astFree( work1 ); - work2 = astFree( work2 ); - -/* Return the result */ - return result; -} - -static double *GeoLengths( AstFrame *frm, int nc, double *centre, - double *corner, double *geolen, int *status ){ -/* -* Name: -* GeoLengths - -* Purpose: -* Find the geodesic dimensions of a box. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* double *GeoLengths( AstFrame *frm, int nc, double *centre, -* double *corner, double *geolen, int *status ) - -* Class Membership: -* Box member function - -* Description: -* This function returns half the geodesic distance along each edge of -* the supplied box. - -* Parameters: -* frm -* Defines the geometry of the axes. -* nc -* The number of Frame axes. -* centre -* Pointer to an array holding rhe box centre axis values. -* corner -* Pointer to an array holding the axis values at the corner -* position. -* geolen -* Pointer to an array in which to return the geodesic distances -* corresponding to each half axis of the box. If this is NULL a -* new array is allocated and a pointer to it returned as the -* function value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the array holding the geodesic half-dimensions of the box. -* If a non-NULL value is supplied for parameter "corner", then the same -* value will be returned as the function value. Otherwise, the -* returned value will be a pointer to a newly allocated array that -* should be freed using astFree when no longer needed. - -*/ - -/* Local Variables: */ - double *result; - double *p1; - double *p2; - int i; - -/* Initialise */ - result = geolen; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Ensure we have a results array. */ - if( ! result ) result = astMalloc( sizeof( double )*nc ); - -/* Also allocate two work arrays to hold a single position. */ - p1 = astMalloc( sizeof( double )*nc ); - p2 = astMalloc( sizeof( double )*nc ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Initialise the coords as the start and end of the line. */ - memcpy( p1, centre, sizeof( double )*nc ); - memcpy( p2, centre, sizeof( double )*nc ); - -/* Loop round finding the geodesic half-length of each side of the box. */ - for( i = 0; i < nc; i++ ) { - -/* The end of the line is the same as the start of the line, except that - it has the corner value for the current axis. */ - p2[ i ] = corner[ i ]; - -/* Find and return the geodesic distance along the line (i.e. from p1 to - p2). */ - result[ i ] = astDistance( frm, p1, p2 ); - -/* The start of the next line wil lbe at the end of the current line. */ - p1[ i ] = corner[ i ]; - } - } - -/* Free resources */ - p1 = astFree( p1 ); - p2 = astFree( p2 ); - -/* Return the result */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* Box member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied Box, -* in bytes. - -* Parameters: -* this -* Pointer to the Box. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstBox *this; /* Pointer to Box structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the Box structure. */ - this = (AstBox *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astTSizeOf( this->extent ); - result += astTSizeOf( this->centre ); - result += astTSizeOf( this->lo ); - result += astTSizeOf( this->hi ); - result += astTSizeOf( this->geolen ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -void astInitBoxVtab_( AstBoxVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitBoxVtab - -* Purpose: -* Initialise a virtual function table for a Box. - -* Type: -* Protected function. - -* Synopsis: -* #include "box.h" -* void astInitBoxVtab( AstBoxVtab *vtab, const char *name ) - -* Class Membership: -* Box vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Box class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsABox) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->BoxPoints = BoxPoints; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - - parent_setnegated = region->SetNegated; - region->SetNegated = SetNegated; - - parent_setunc = region->SetUnc; - region->SetUnc = SetUnc; - - parent_setclosed = region->SetClosed; - region->SetClosed = SetClosed; - - parent_clearnegated = region->ClearNegated; - region->ClearNegated = ClearNegated; - - parent_clearclosed = region->ClearClosed; - region->ClearClosed = ClearClosed; - - parent_setregfs = region->SetRegFS; - region->SetRegFS = SetRegFS; - - parent_resetcache = region->ResetCache; - region->ResetCache = ResetCache; - - mapping->MapMerge = MapMerge; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - region->RegBaseGrid = RegBaseGrid; - region->RegBaseMesh = RegBaseMesh; - region->RegBasePick = RegBasePick; - region->RegBaseBox = RegBaseBox; - region->RegPins = RegPins; - region->RegTrace = RegTrace; - region->RegCentre = RegCentre; - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "Box", "Axis intervals" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MakeGrid( int naxes, double **ptr, int ip, double *lbnd, - double *ubnd, int *np_axes, int np_axis, int iaxis, - double axval, int *status ){ -/* -* Name: -* MakeGrid - -* Purpose: -* Create a grid covering the entire volume of a specified box. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* int MakeGrid( int naxes, double **ptr, int ip, double *lbnd, -* double *ubnd, int *np_axes, int np_axis, int iaxis, -* double axval, int *status ) - -* Class Membership: -* Box member function - -* Description: -* This function creates an evenly sampled grid covering a given -* volume of n-D space, putting the coordinates at the sample points -* into a supplied array and returning the number of samples added. -* Optionally, the volume can be assumed to have a constant value on -* a specified axis. - -* Parameters: -* naxes -* The number of axes. -* ptr -* Pointer to an array with "naxes" elements. Each element is a -* pointer to an array in which to store the values for the axis. -* ip -* The index of the first point to be added to the "ptr" arrays. -* lbnd -* Pointer to an array containing the lower axis bounds of the -* volume to be sampled. -* ubnd -* Pointer to an array containing the upper axis bounds of the -* volume to be sampled. -* np_axes -* Pointer to an array with one element for every axis, giving the -* number of samples along each axis (except, optionally, the axis -* specified by "iaxis"). The first sample (sample 0) for each axis -* will be at the lower bound given in "lbnd" and the last sample -* (sample "np_axes[iax]-1") will be at the upper bound given in -* "ubnd". If NULL, then the single scalar avalue given by -* "np_axis" is used for all axes. -* np_axis -* The constant number of samples along every axis (except, optionally, -* the axis specified by "iaxis"). The first sample (sample 0) for each -* axis will be at the lower bound given in "lbnd" and the last sample -* (sample "np_axis-1") will be at the upper bound given in "ubnd". -* The supplied value is only used if "np_axes" is NULL. -* iaxis -* The index of an axis which has constant value in the volume, or -* -1 if all axes are to span the full volume given by lbnd/ubnd. -* The values in "lbnd" and "ubnd" are ignored for this axis and all -* sample positions will have the axis value given by "axval". -* axval -* The constant value for the axis with index "iaxis". Ignored if -* "iaxis" is -1. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of points added to the "ptr" arrays. - -*/ - -/* Local Variables: */ - double *step; /* Pointer to array holding axis step sizes */ - int *maxi; /* Pointer to array of maximum index values */ - int *pi; /* Pointer to array holding current sample indices */ - int i; /* Axis index */ - int ipp; /* Index of next point */ - int nsamp; /* Number of samples along the axis */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Allocate memory to hold the max indices on each axis. */ - maxi = astMalloc( sizeof( int )*(size_t) naxes ); - -/* Allocate memory to hold the indices of the current position.*/ - pi = astMalloc( sizeof( int )*(size_t) naxes ); - -/* Allocate memory to hold the step size for each axis. */ - step = astMalloc( sizeof( double )*(size_t) naxes ); - if( astOK ) { - -/* For every axis, set up the step size, initialise the current position to - the lower bound, and store a modified upper limit which includes some - safety marging to allow for rounding errors. */ - for( i = 0; i < naxes; i++ ) { - nsamp = np_axes ? np_axes[ i ] : np_axis; - step[ i ] = ( ubnd[ i ] - lbnd[ i ] )/( nsamp - 1 ); - pi[ i ] = 0; - maxi[ i ] = nsamp - 1; - } - - if( iaxis >= 0 ) { - maxi[ iaxis ] = 0; - step[ iaxis ] = 0.0; - pi[ iaxis ] = 0; - } - -/* Initialise the index of the next position to store. */ - ipp = ip; - -/* Loop round adding points to the array until the whole volume has been - done. */ - i = 0; - while( i < naxes ) { - -/* Add the current point to the supplied array,and increment the index of - the next point to add. */ - for( i = 0; i < naxes; i++ ) { - if( i == iaxis ) { - ptr[ i ][ ipp ] = axval; - } else { - ptr[ i ][ ipp ] = lbnd[ i ] + pi[ i ]*step[ i ]; - } - } - ipp++; - -/* We now move the current position on to the next sample */ - i = 0; - while( i < naxes ) { - pi[ i ]++; - if( pi[ i ] > maxi[ i ] ) { - pi[ i ] = 0; - i++; - } else { - break; - } - } - } - } else { - ipp = ip; - } - -/* Free resources. */ - maxi = astFree( maxi ); - pi = astFree( pi ); - step = astFree( step ); - -/* Return the result. */ - return astOK ? ( ipp - ip ): 0 ; -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a Box. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* Box method (over-rides the protected astMapMerge method -* inherited from the Region class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated Box in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated Box with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated Box which is to be merged with -* its neighbours. This should be a cloned copy of the Box -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* Box it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated Box resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstBox *oldbox; /* Pointer to supplied Box */ - AstMapping *map; /* Pointer to adjacent Mapping */ - AstMapping *new; /* Simplified or merged Region */ - int i1; /* Index of first Mapping merged */ - int i; /* Loop counter */ - int result; /* Result value to return */ - -/* Initialise. */ - result = -1; - i1 = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Box. */ - oldbox = (AstBox *) this; - -/* First of all, see if the Box can be replaced by a simpler Region, - without reference to the neighbouring Regions in the list. */ -/* =====================================================================*/ - -/* Try to simplify the box. If the pointer value has changed, we assume - some simplification took place. */ - new = astSimplify( oldbox ); - if( new != (AstMapping *) oldbox ) { - -/* Annul the Box pointer in the list and replace it with the new Region - pointer, and indicate that the forward transformation of the returned - Region should be used (not really needed but keeps things clean). */ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = new; - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - -/* If the Box itself could not be simplified, see if it can be merged - with the Regions on either side of it in the list. We can only merge - in parallel. */ -/* =====================================================================*/ - } else if( ! series ){ - new = astAnnul( new ); - -/* Attempt to merge the Box with its lower neighbour (if any). */ - if( where > 0 ) { - i1 = where - 1; - map = ( *map_list )[ where - 1 ]; - if( astIsARegion( map ) ) { - new = (AstMapping *) MergeBox( oldbox, (AstRegion *) map, 0, - status ); - } - } - -/* If this did not produced a merged Region, attempt to merge the Box with its - upper neighbour (if any). */ - if( !new && where < *nmap - 1 ) { - i1 = where; - map = ( *map_list )[ where + 1 ]; - if( astIsARegion( map ) ) { - new = (AstMapping *) MergeBox( oldbox, (AstRegion *) map, 1, - status ); - } - } - -/* If succesfull... */ - if( new ){ - -/* Annul the first of the two Mappings, and replace it with the merged - Region. Also clear the invert flag. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - ( *map_list )[ i1 ] = new; - ( *invert_list )[ i1 ] = 0; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ i1 + 1 ] ); - for ( i = i1 + 2; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = i1; - } - - } else { - new = astAnnul( new ); - } - -/* Return the result. */ - return result; -} - -static AstRegion *MergeBox( AstBox *this, AstRegion *reg, int boxfirst, - int *status ) { -/* -* Name: -* MergeBox - -* Purpose: -* Attempt to merge a Box with another Region to form a Region of higher -* dimensionality. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* AstRegion *MergeBox( AstBox *this, AstRegion *reg, int boxfirst, int *status ) - -* Class Membership: -* Box member function. - -* Description: -* This function attempts to combine the supplied Regions together -* into a Region of higher dimensionality. - -* Parameters: -* this -* Pointer to a Box. -* reg -* Pointer to another Region. -* boxfirst -* If non-zero, then the Box axes are put first in the new Region. -* Otherwise, the other Region's axes are put first. -* status -* Pointer to the inherited status value. - -* Returned Value: -* A pointer to a new region, or NULL if the supplied Regions could -* not be merged. -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* Pointer to base Frame for "result" */ - AstFrame *cfrm; /* Pointer to current Frame for "result" */ - AstFrame *frm_reg; /* Pointer to Frame from "reg" */ - AstFrame *frm_this; /* Pointer to Frame from "this" */ - AstMapping *bcmap; /* Base->current Mapping for "result" */ - AstMapping *map_reg; /* Base->current Mapping from "reg" */ - AstMapping *map_this; /* Base->current Mapping from "this" */ - AstMapping *sbunc; /* Simplified uncertainty */ - AstPointSet *pset_new; /* PointSet holding PointList axis values for new */ - AstPointSet *pset_reg; /* PointSet holding PointList axis values for reg */ - AstRegion *bunc; /* Base Frame uncertainty Region */ - AstRegion *new; /* Pointer to new Interval in base Frame */ - AstRegion *result; /* Pointer to returned Interval in current Frame */ - AstRegion *unc_reg; /* Current Frame uncertainty Region from "reg" */ - AstRegion *unc_this; /* Current Frame uncertainty Region from "this" */ - double **ptr_new; /* Pointers to arrays holding new axis values */ - double **ptr_reg; /* Pointers to arrays holding reg axis values */ - double *centre; /* Array to hold box centre axis values */ - double *corner; /* Array to hold box corner axis values */ - double *lbnd; /* Array to hold lower axis bounds */ - double *p; /* Pointer to next input value */ - double *q; /* Pointer to next output value */ - double *ubnd; /* Array to hold upper axis bounds */ - double fac_reg; /* Ratio of used to default MeshSize for "reg" */ - double fac_this; /* Ratio of used to default MeshSize for "this" */ - double temp; /* Temporary storage */ - int i; /* Loop count */ - int j; /* Loop count */ - int msz_reg; /* Original MeshSize for "reg" */ - int msz_reg_set; /* Was MeshSize originally set for "reg"? */ - int msz_this; /* Original MeshSize for "this" */ - int msz_this_set; /* Was MeshSize originally set for "this"? */ - int nax; /* Number of axes in "result" */ - int nax_reg; /* Number of axes in "reg" */ - int nax_this; /* Number of axes in "this" */ - int neg_reg; /* Negated attribute value for other supplied Region */ - int neg_this; /* Negated attribute value for supplied Box */ - int npnt; /* Number of points in PointList */ - int ok; /* Can supplied Regions be merged? */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get the Closed attributes of the two Regions. They must be the same in - each Region if we are to merge the Regions. In addition, in order to - merge, either both Regions must have a defined uncertainty, or neither - Region must have a defined Uncertainty. */ - if( astGetClosed( this ) == astGetClosed( reg ) && - astTestUnc( this ) == astTestUnc( reg ) ) { - -/* Get the Nagated attributes of the two Regions. */ - neg_this = astGetNegated( this ); - neg_reg = astGetNegated( reg ); - -/* Get the number of axes in the two supplied Regions. */ - nax_reg = astGetNaxes( reg ); - nax_this = astGetNaxes( this ); - -/* If the Regions can be combined, get the number of axes the - combination will have. */ - nax = nax_reg + nax_this; - -/* Get the base Frames from the two Region FrameSets, and combine them - into a single CmpFrame that will be used to create any new Region. */ - frm_this = astGetFrame( ((AstRegion *) this)->frameset, AST__BASE ); - frm_reg = astGetFrame( reg->frameset, AST__BASE ); - - if( boxfirst ) { - bfrm = (AstFrame *) astCmpFrame( frm_this, frm_reg, "", status ); - } else { - bfrm = (AstFrame *) astCmpFrame( frm_reg, frm_this, "", status ); - } - - frm_this = astAnnul( frm_this ); - frm_reg = astAnnul( frm_reg ); - -/* Indicate we do not yet have a merged Region. */ - new = NULL; - -/* First attempt to merge with another Box. The result will be a Box. Both - Boxes must be un-negated. */ - if( astIsABox( reg ) && !neg_this && !neg_reg ) { - -/* Allocate memory to store the centre and corner of the returned Box. */ - centre = astMalloc( sizeof( double )*(size_t) nax ); - corner = astMalloc( sizeof( double )*(size_t) nax ); - -/* Copy the centres and corners from the supplied Boxes into the above - arrays, in the requested order. */ - if( boxfirst ) { - astBoxPoints( this, centre, corner ); - astBoxPoints( reg, centre + nax_this, corner + nax_this ); - } else { - astBoxPoints( reg, centre, corner ); - astBoxPoints( this, centre + nax_reg, corner + nax_reg ); - } - -/* Create the new Box, initially with no uncertainty. */ - new = (AstRegion *) astBox( bfrm, 0, centre, corner, NULL, "", - status ); - -/* Free resources .*/ - centre = astFree( centre ); - corner = astFree( corner ); - -/* Now attempt to merge with an Interval. The result will be an Interval. - Both Intervals must be un-negated. */ - } else if( astIsAInterval( reg ) && !neg_this && !neg_reg ) { - -/* Allocate memory to store the bounds of the returned Interval. */ - lbnd = astMalloc( sizeof( double )*(size_t) nax ); - ubnd = astMalloc( sizeof( double )*(size_t) nax ); - -/* Copy the centre and corner from the supplied Box into the required part - of the above arrays. */ - if( boxfirst ) { - centre = lbnd; - corner = ubnd; - } else { - centre = lbnd + nax_reg; - corner = ubnd + nax_reg; - } - astBoxPoints( this, centre, corner ); - -/* Convert these centre and corner positions into upper and lower bounds. */ - if( astOK ) { - for( i = 0; i < nax_this; i++ ) { - centre[ i ] = 2*centre[ i ] - corner[ i ]; - if( centre[ i ] > corner[ i ] ) { - temp = centre[ i ]; - centre[ i ] = corner[ i ]; - corner[ i ] = temp; - } - } - } - -/* Get the bounds from the interval and add them into the above arrays. */ - if( boxfirst ) { - astIntervalPoints( reg, lbnd + nax_this, ubnd + nax_this ); - } else { - astIntervalPoints( reg, lbnd, ubnd ); - } - -/* Create the new Interval, initially with no uncertainty. */ - new = (AstRegion *) astInterval( bfrm, lbnd, ubnd, NULL, "", - status ); - -/* Free resources .*/ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - -/* Now attempt to merge with a NullRegion. The result will be an - Interval. The NullRegion must be negated and the Box must not. */ - } else if( astIsANullRegion( reg ) && !neg_this && neg_reg ) { - -/* Allocate memory to store the bounds of the returned Interval. */ - lbnd = astMalloc( sizeof( double )*(size_t) nax ); - ubnd = astMalloc( sizeof( double )*(size_t) nax ); - -/* Copy the centre and corner from the supplied Box into the required part - of the above arrays. */ - if( boxfirst ) { - centre = lbnd; - corner = ubnd; - } else { - centre = lbnd + nax_reg; - corner = ubnd + nax_reg; - } - astBoxPoints( this, centre, corner ); - -/* Convert these centre and corner positions into upper and lower bounds. */ - if( astOK ) { - for( i = 0; i < nax_this; i++ ) { - centre[ i ] = 2*centre[ i ] - corner[ i ]; - if( centre[ i ] > corner[ i ] ) { - temp = centre[ i ]; - centre[ i ] = corner[ i ]; - corner[ i ] = temp; - } - } - -/* Fill the other axes with bad values to indicate they are unbounded. */ - if( boxfirst ) { - for( i = nax_this; i < nax; i++ ) { - lbnd[ i ] = AST__BAD; - ubnd[ i ] = AST__BAD; - } - } else { - for( i = 0; i < nax_reg; i++ ) { - lbnd[ i ] = AST__BAD; - ubnd[ i ] = AST__BAD; - } - } - -/* Create the new Interval, initially with no uncertainty. */ - new = (AstRegion *) astInterval( bfrm, lbnd, ubnd, NULL, "", - status ); - } - -/* Free resources .*/ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - -/* Now attempt to merge with a PointList. The result will be a PointList. - Both Regions must be un-negated. */ - } else if( astIsAPointList( reg ) && !neg_this && !neg_reg ) { - -/* We can only do this if the Box has zero width on each axis (i.e. - represents a point). Get the Box centre and corner. */ - centre = astMalloc( sizeof( double )*(size_t) nax_this ); - corner = astMalloc( sizeof( double )*(size_t) nax_this ); - astBoxPoints( this, centre, corner ); - -/* Get the size of the Box's uncertainty region. */ - lbnd = astMalloc( sizeof( double )*(size_t) nax_this ); - ubnd = astMalloc( sizeof( double )*(size_t) nax_this ); - bunc = astGetUncFrm( this, AST__BASE ); - astGetRegionBounds( bunc, lbnd, ubnd ); - -/* Set "ok" to zero if the Box does not have zero width on any axis. Here - "zero width" means a width less than half the uncertainty on the axis. */ - if( astOK ) { - - ok = 1; - for( i = 0; i < nax_this; i++ ) { - if( fabs( centre[ i ] - corner[ i ] ) > - 0.25*fabs( ubnd[ i ] - lbnd[ i ] ) ) { - ok = 0; - break; - } - } - -/* If the Box is a point, we go on to create a new PointList. */ - if( ok ) { - -/* Get a PointSet holding the axis values in the supplied PointList data. - Also get the number of points in the PointSet and pointers to the arrays - holding the axis values. */ - astPointListPoints( reg, &pset_reg ); - npnt = astGetNpoint( pset_reg ); - ptr_reg = astGetPoints( pset_reg ); - -/* Create a new PointSet with room for the same number of points, but - with the extra required axes. Get pointers to its axis arrays. */ - pset_new = astPointSet( npnt, nax, "", status ); - ptr_new = astGetPoints( pset_new ); - -/* Copy the PointList axis values into the new PointSet, and then include - the extra axis values defined by the Box to each point. */ - if( astOK ) { - - for( j = 0; j < nax_reg; j++ ) { - p = ptr_reg[ j ]; - q = ptr_new[ boxfirst ? nax_this + j : j ]; - for( i = 0; i < npnt; i++ ) *(q++) = *(p++); - } - - for( j = 0; j < nax_this; j++ ) { - p = centre + j; - q = ptr_new[ boxfirst ? j : nax_reg + j ]; - for( i = 0; i < npnt; i++ ) *(q++) = *p; - } - -/* Create the new PointList, initially with no uncertainty. */ - new = (AstRegion *) astPointList( bfrm, pset_new, NULL, - "", status ); - } - -/* Free resources .*/ - pset_new = astAnnul( pset_new ); - pset_reg = astAnnul( pset_reg ); - } - } - centre = astFree( centre ); - corner = astFree( corner ); - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - bunc = astAnnul( bunc ); - - } - -/* If a new Region was created above, propagate remaining attributes of - the supplied Region to it. */ - if( new ) { - astRegOverlay( new, this, 1 ); - -/* The above Prism constructors create the Prism with the correct value - for the Nagated attribute (i.e. zero). Ensure the above call to - astRegOverlay has not changed this. */ - astClearNegated( new ); - -/* If both the supplied Regions have uncertainty, assign the new Region an - uncertainty. */ - if( astTestUnc( this ) && astTestUnc( reg ) ) { - -/* Get the uncertainties from the two supplied Regions. */ - unc_this = astGetUncFrm( this, AST__BASE ); - unc_reg = astGetUncFrm( reg, AST__BASE ); - -/* Combine them into a single Region (a Prism), in the correct order. */ - if( boxfirst ) { - bunc = (AstRegion *) astPrism( unc_this, unc_reg, "", status ); - } else { - bunc = (AstRegion *) astPrism( unc_reg, unc_this, "", status ); - } - -/* Attempt to simplify the Prism. */ - sbunc = astSimplify( bunc ); - -/* Use the simplified Prism as the uncertainty for the returned Region. */ - astSetUnc( new, sbunc ); - -/* Free resources. */ - sbunc = astAnnul( sbunc ); - bunc = astAnnul( bunc ); - unc_reg = astAnnul( unc_reg ); - unc_this = astAnnul( unc_this ); - } - -/* Get the current Frames from the two Region FrameSets, and combine them - into a single CmpFrame. */ - frm_this = astGetFrame( ((AstRegion *) this)->frameset, AST__CURRENT ); - frm_reg = astGetFrame( reg->frameset, AST__CURRENT ); - - if( boxfirst ) { - cfrm = (AstFrame *) astCmpFrame( frm_this, frm_reg, "", status ); - } else { - cfrm = (AstFrame *) astCmpFrame( frm_reg, frm_this, "", status ); - } - -/* Get the base -> current Mappings from the two Region FrameSets, and - combine them into a single parallel CmpMap that connects bfrm and cfrm. */ - map_this = astGetMapping( ((AstRegion *) this)->frameset, AST__BASE, - AST__CURRENT ); - map_reg = astGetMapping( reg->frameset, AST__BASE, AST__CURRENT ); - - if( boxfirst ) { - bcmap = (AstMapping *) astCmpMap( map_this, map_reg, 0, "", - status ); - } else { - bcmap = (AstMapping *) astCmpMap( map_reg, map_this, 0, "", - status ); - } - -/* Map the new Region into the new current Frame. */ - result = astMapRegion( new, bcmap, cfrm ); - -/* The filling factor in the returned is the product of the filling - factors for the two supplied Regions. */ - if( astTestFillFactor( reg ) || astTestFillFactor( this ) ) { - astSetFillFactor( result, astGetFillFactor( reg )* - astGetFillFactor( this ) ); - } - -/* If the MeshSize value is set in either supplied Region, set a value - for the returned Region which scales the default value by the - product of the scaling factors for the two supplied Regions. First see - if either MeshSize value is set. */ - msz_this_set = astTestMeshSize( this ); - msz_reg_set = astTestMeshSize( reg ); - if( msz_this_set || msz_reg_set ) { - -/* If so, get the two MeshSize values (one of which may be a default - value), and then clear them so that the default value will be returned - in future. */ - msz_this = astGetMeshSize( this ); - msz_reg = astGetMeshSize( reg ); - astClearMeshSize( this ); - astClearMeshSize( reg ); - -/* Get the ratio of the used MeshSize to the default MeshSize for both - Regions. */ - fac_this = (double)msz_this/(double)astGetMeshSize( this ); - fac_reg = (double)msz_reg/(double)astGetMeshSize( reg ); - -/* The MeshSize of the returned Returned is the default value scaled by - the product of the two ratios found above. */ - astSetMeshSize( result, fac_this*fac_reg*astGetMeshSize( result ) ); - -/* Re-instate the original MeshSize values for the supplied Regions (if - set) */ - if( msz_this_set ) astSetMeshSize( this, msz_this ); - if( msz_reg_set ) astSetMeshSize( reg, msz_reg ); - } - -/* Free remaining resources */ - frm_this = astAnnul( frm_this ); - frm_reg = astAnnul( frm_reg ); - map_this = astAnnul( map_this ); - map_reg = astAnnul( map_reg ); - bcmap = astAnnul( bcmap ); - new = astAnnul( new ); - cfrm = astAnnul( cfrm ); - } - bfrm = astAnnul( bfrm ); - } - -/* If an error has occurred, annul the returned pointer. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void RegBaseBox( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* Box member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstBox *this; /* Pointer to Box structure */ - double axcen; /* Central axis value */ - double axlen; /* Half width of box on axis */ - int i; /* Axis index */ - int nc; /* No. of axes in base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Box structure */ - this = (AstBox *) this_region; - -/* Ensure cached information is up to date. */ - Cache( this, 0, status ); - -/* Get the number of base Frame axes in the Region. */ - nc = astGetNin( this_region->frameset ); - -/* The first point is the centre of the box, the second point is the half - size of the box on each axis.*/ - for( i = 0; i < nc; i++ ) { - axcen = this->centre[ i ]; - axlen = this->extent[ i ]; - lbnd[ i ] = axcen - axlen; - ubnd[ i ] = axcen + axlen; - } -} - -static AstPointSet *RegBaseGrid( AstRegion *this, int *status ){ -/* -* Name: -* RegBaseGrid - -* Purpose: -* Return a PointSet containing points spread through the volume of a -* Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* AstPointSet *RegBaseGrid( AstRegion *this, int *status ) - -* Class Membership: -* Box member function (over-rides the astRegBaseGrid protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a set of points spread -* through the volume of the supplied Box. The points refer to the base -* Frame of the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. If the Region is unbounded, a NULL pointer -* will be returned. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Base Frame in encapsulated FrameSet */ - AstPointSet *result; /* Returned pointer */ - double *lbnd; /* Pointer to array of lower bounds of box */ - double *ubnd; /* Pointer to array of upper bounds of box */ - int meshsize; /* Requested size of grid */ - int naxes; /* No. of axes in base Frame */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return NULL; - -/* If the Region structure contains a pointer to a PointSet holding - a previously created grid, return it. */ - if( this->basegrid ) { - result = astClone( this->basegrid ); - -/* Otherwise, create a new one, but only if the Box is bounded. */ - } else if( astGetBounded( this ) ) { - -/* Get the base Frame in the Region's FrameSet. */ - frm = astGetFrame( this->frameset, AST__BASE ); - -/* Get the number of axes in the base Frame */ - naxes = astGetNaxes( frm ); - -/* Get the bounds of the Region in the base Frame. */ - lbnd = astMalloc( sizeof( double )*(size_t) naxes ); - ubnd = astMalloc( sizeof( double )*(size_t) naxes ); - astRegBaseBox( this, lbnd, ubnd ); - -/* Get the number of points which would be used to create a boundary - mesh. We use the same number to determine the number of points in the - grid. */ - meshsize = astGetMeshSize( this ); - -/* Create the PointSet holding the grid. */ - result = astFrameGrid( frm, meshsize, lbnd, ubnd ); - -/* Save the returned pointer in the Region structure so that it does not - need to be created again next time this function is called. */ - if( astOK && result ) this->basegrid = astClone( result ); - -/* Free remaining resources. */ - frm = astAnnul( frm ); - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - } - -/* Annul the result if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result */ - return result; -} - -static AstPointSet *RegBaseMesh( AstRegion *this, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Return a PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* AstPointSet *RegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* Box member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. The axis values in this PointSet will have -* associated accuracies derived from the accuracies which were -* supplied when the Region was created. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - -/* Local Constants: */ -#define NP_EDGE 50 /* No. of points for determining geodesic - length of each axis. */ - -/* Local Variables: */ - AstFrame *frm; /* Base Frame in encapsulated FrameSet */ - AstFrame *pfrm0; /* Primary Frame defining axis 0 */ - AstFrame *pfrm1; /* Primary Frame defining axis 1 */ - AstPointSet *result; /* Returned pointer */ - const char *class0; /* Pointer to class string from pfrm0 */ - const char *class1; /* Pointer to class string from pfrm1 */ - double **ptr; /* Pointers to data */ - double *ax; /* Pointer to next first axis value */ - double *ay; /* Pointer to next second axis value */ - double *lbnd; /* Pointer to array of lower bounds of box */ - double *ubnd; /* Pointer to array of lower bounds of box */ - double c[ 5 ][ 2 ]; /* Positions of corners for 2D boxes */ - double dx; /* Increment along first axis of 2D box */ - double dy; /* Increment along second axis of 2D box */ - double edge_len[ 4 ]; /* Length of each edge of 2D boundary */ - double lax; /* Previous value on first axis */ - double lay; /* Previous value on second axis */ - double len; /* Length of edge of 2D boundary */ - double p0[ 2 ]; /* Position in 2D Frame */ - double p1[ 2 ]; /* Position in 2D Frame */ - double ppd; /* Points per unit distance */ - double total_len; /* Total length of 2D boundary */ - int flat; /* Assume Frame geometry is flat? */ - int i; /* Point index */ - int iaxis; /* Axis index */ - int iedge; /* Edge index */ - int ip; /* Index of next point */ - int metric; /* Does Frame have a usable metric? */ - int nax0; /* No. of axes in first primary Frame */ - int nax1; /* No. of axes in second primary Frame */ - int naxes; /* No. of axes in base Frame */ - int np; /* No. of points in returned PointSet */ - int np0; /* No. of points per edge */ - int np_axis; /* No. of points per axis in ND box */ - int np_edge[ 4 ]; /* No. of points per edge in 2D box */ - int paxis; /* Axis index in primary Frame */ - int single; /* Does the Box occupy a single point? */ - -/* Initialise */ - result= NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the Region structure contains a pointer to a PointSet holding - a previously created mesh, return it. */ - if( this->basemesh ) { - result = astClone( this->basemesh ); - -/* Otherwise, create a new mesh. */ - } else { - -/* Get the base Frame in the Region's FrameSet. */ - frm = astGetFrame( this->frameset, AST__BASE ); - -/* Get the number of axes in the base Frame */ - naxes = astGetNaxes( frm ); - -/* Get the bounds of the Region in the base Frame. */ - lbnd = astMalloc( sizeof( double )*(size_t) naxes ); - ubnd = astMalloc( sizeof( double )*(size_t) naxes ); - astRegBaseBox( this, lbnd, ubnd ); - -/* Get the requested number of points to put on the mesh. */ - np = astGetMeshSize( this ); - -/* See if the box occupies a single point. */ - single = 1; - for( i = 0; i < naxes; i++ ) { - if( ubnd[ i ] > lbnd[ i ] ) { - single = 0; - break; - } - } - -/* If so, we return a PointSet holding a single point. */ - if( single ) { - result = astPointSet( 1, naxes, "", status ); - ptr = astGetPoints( result ); - if( astOK ) { - for( i = 0; i < naxes; i++ ) { - ptr[ i ][ 0 ] = 0.5*( lbnd[ 0 ] + ubnd[ 0 ] ); - } - } - -/* Otherwise, first deal with 1-D boxes. */ - } else if( naxes == 1 ) { - -/* The boundary of a 1-D box consists of 2 points - the two extreme values. - Create a PointSet to hold 2 1-D values, and store the extreme values. */ - result = astPointSet( 2, 1, "", status ); - ptr = astGetPoints( result ); - if( astOK ) { - ptr[ 0 ][ 0 ] = lbnd[ 0 ]; - ptr[ 0 ][ 1 ] = ubnd[ 0 ]; - } - -/* Now deal with 2-D boxes. */ - } else if( naxes == 2 ){ - -/* Store the coords of each corner for easy access. */ - c[ 0 ][ 0 ] = lbnd[ 0 ]; - c[ 0 ][ 1 ] = lbnd[ 1 ]; - c[ 1 ][ 0 ] = lbnd[ 0 ]; - c[ 1 ][ 1 ] = ubnd[ 1 ]; - c[ 2 ][ 0 ] = ubnd[ 0 ]; - c[ 2 ][ 1 ] = ubnd[ 1 ]; - c[ 3 ][ 0 ] = ubnd[ 0 ]; - c[ 3 ][ 1 ] = lbnd[ 1 ]; - c[ 4 ][ 0 ] = lbnd[ 0 ]; - c[ 4 ][ 1 ] = lbnd[ 1 ]; - -/* See if we can assume that the frame has flat geometry. This is the case - if both axes belong to simple Frames, or are 1D, but may not be the case - if either axis does not belong to a simple Frame that has more than 1 - axis. */ - astPrimaryFrame( frm, 0, &pfrm0, &paxis ); - astPrimaryFrame( frm, 1, &pfrm1, &paxis ); - class0 = astGetClass( pfrm0 ); - class1 = astGetClass( pfrm1 ); - nax0 = astGetNaxes( pfrm0 ); - nax1 = astGetNaxes( pfrm1 ); - if( astOK ) { - flat = ( !strcmp( class0, "Frame" ) || nax0 == 1 ) && - ( !strcmp( class1, "Frame" ) || nax1 == 1 ); - } else { - flat = 0; - } - -/* Our choice of distribution of points depends on whether the axes have the - same units or not. If the axes have the same units, or if they share the - same primary Frame, then we assume that the axes span some space in which - a single "distance" is defined. If not, (e.g. for a Frame representing - frequency in Hz on one axis - typical value 1.0E10, and slit position in - metres on the other axis - typical value 1.0E-2) we assume that "distance" - is defined differently for each axis. The primary frame requirement is - because some classes of Frame (e.g. SkyFrame) have a defined distance, - even though the Units attributes for its axes may differ (since Units - refers to the external representation - e.g. hours and degrees for a - SkyFrame - rather than the internal representation). */ - if( astOK && !strcmp( astGetUnit( frm, 0 ), astGetUnit( frm, 1 ) ) ) { - metric = 1; - } else { - metric = ( pfrm0 == pfrm1 ); - } - -/* If we have a usable metric, distribute the points according to the aspect - ratio of the box (i.e. the shorter box sides gets fewer points). */ - if( metric ){ - -/* Find the approximate geodesic length of each edge of the box. Since - the edges of the box may not correspond to single geodesic (e.g. a - line of constant latitude is not a geodesic), we do this by testing - a set of points along each edge of the box and finding the total of the - geodesic distances between each pair of adjacent points. Initialise the - total length round all edges. */ - total_len = 0.0; - -/* Do each edge in turn.*/ - for( iedge = 0; iedge < 4; iedge++ ) { - -/* Find the increment in x and y between adjacent points along this edge. - We put a point at each end of the edge. Note, one of dx or dy will be - zero since the edges are parallel to the axes. */ - dx = ( c[ iedge + 1 ][ 0 ] - c[ iedge ][ 0 ] )/( NP_EDGE - 1 ); - dy = ( c[ iedge + 1 ][ 1 ] - c[ iedge ][ 1 ] )/( NP_EDGE - 1 ); - -/* Store the coords of the first point. */ - p0[ 0 ] = c[ iedge ][ 0 ]; - p0[ 1 ] = c[ iedge ][ 1 ]; - -/* Initialise the length of this edge and loop round the remaining points. */ - len = 0.0; - for( i = 1; i < NP_EDGE; i++ ) { - -/* Save the position of the previous point. */ - p1[ 0 ] = p0[ 0 ]; - p1[ 1 ] = p0[ 1 ]; - -/* Find the position of the new point. */ - p0[ 0 ] = p1[ 0 ] + dx; - p0[ 1 ] = p1[ 1 ] + dy; - -/* Increment the length of the edge by the geodesic distance from this point - to the previous point. If the Frame is flat, this is simple (given that we - know that one of dx and dy must be zero). */ - if( flat ) { - len += fabs( dx + dy ); - } else { - len += astDistance( frm, p0, p1 ); - } - } - -/* Save the length of this edge, and also form the total length round all - edges. */ - edge_len[ iedge ] = len; - total_len += len; - } - -/* Find the average number of points per unit geodesic distance around the - boundary. */ - if( total_len > 0.0 ) { - ppd = np / total_len; - -/* Use this, with the geodesic length of each edge found above, to find the - number of points to put along each edge of the boundary, and update the - total number of points to use. In the returned boundary we put a point at - the start of each edge but not at the end (since the end of one edge will - be the start of the next edge). */ - np = 0; - for( iedge = 0; iedge < 4; iedge++ ) { - np_edge[ iedge ] = (int) ( edge_len[ iedge ]*ppd ); - if( np_edge[ iedge ] == 0 ) np_edge[ iedge ] = 1; - np += np_edge[ iedge ]; - } - -/* Report error if total length round box is zero. */ - } else if( astOK ) { - astError( AST__INTER, "astRegBaseMesh(%s): Distance around " - "box perimeter is zero (internal AST programming " - "error).", status, astGetClass( this ) ); - } - -/* If the Frame has no usable metric, give an equal number of points - (equal to a quarter of the total) to all 4 sides of the box. */ - } else { - np0 = (int) ( 0.25*np ); - np = 0; - for( iedge = 0; iedge < 4; iedge++ ) { - np_edge[ iedge ] = np0; - np += np_edge[ iedge ]; - } - } - -/* Create a PointSet with enough room and get a pointer to its data arrays. */ - result = astPointSet( np, 2, "", status ); - ptr = astGetPoints( result ); - if( astOK ) { - -/* Initialise pointers to the first element for each axis in the returned - PointSet. */ - ax = ptr[ 0 ]; - ay = ptr[ 1 ]; - -/* Loop round each edge. */ - for( iedge = 0; iedge < 4; iedge++ ) { - -/* Find the increment in x and y between adjacent points along this edge. */ - dx = ( c[ iedge + 1 ][ 0 ] - c[ iedge ][ 0 ] )/ np_edge[ iedge ]; - dy = ( c[ iedge + 1 ][ 1 ] - c[ iedge ][ 1 ] )/ np_edge[ iedge ]; - -/* Store the first point. */ - lax = c[ iedge ][ 0 ]; - lay = c[ iedge ][ 1 ]; - *(ax++) = lax; - *(ay++) = lay; - -/* Loop round the remaining points, incrementing the pointers at the same - time. */ - for( i = 1; i < np_edge[ iedge ]; i++, ax++, ay++ ) { - -/* Find the position of the new point and store it. */ - lax += dx; - lay += dy; - *ax = lax; - *ay = lay; - } - } - } - -/* Free resources. */ - pfrm0 = astAnnul( pfrm0 ); - pfrm1 = astAnnul( pfrm1 ); - -/* Now deal with boxes with more than 2 dimensions. */ - } else { - -/* Number of samples along each edge of the hyper-cube. */ - np_axis = 1 + (int) pow( np/(2*naxes), 1.0/(naxes-1) ); - if( np_axis < 2 ) np_axis = 2; - -/* Each face of the hyper-cube will have np_axis**(naxes-1) points, and there - are 2*naxes faces. Create a PointSet with the correct number of - points. */ - np = 2*naxes; - for( iaxis = 1; iaxis < naxes; iaxis++ ) np *= np_axis; - result = astPointSet( np, naxes, "", status ); - ptr = astGetPoints( result ); - if( astOK ) { - -/* Initialise the index of the next point to add into the PointSet. */ - ip = 0; - -/* Create the upper and lower faces for each axis in turn. */ - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - -/* First do the upper face for this axis. */ - ip += MakeGrid( naxes, ptr, ip, lbnd, ubnd, NULL, np_axis, - iaxis, ubnd[ iaxis ], status ); - -/* Now do the lower face for this axis. */ - ip += MakeGrid( naxes, ptr, ip, lbnd, ubnd, NULL, np_axis, - iaxis, lbnd[ iaxis ], status ); - } - -/* Remove any unused space at the end of the PointSet. */ - if( ip < np ) astSetNpoint( result, ip ); - } - } - -/* Same the returned pointer in the Region structure so that it does not - need to be created again next time this function is called. */ - if( astOK && result ) this->basemesh = astClone( result ); - -/* Free resources. */ - frm = astAnnul( frm ); - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - } - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; - -/* Undefine macros local to this function. */ -#undef NP_EDGE - -} - -static AstRegion *RegBasePick( AstRegion *this_region, int naxes, const int *axes, - int *status ){ -/* -* Name: -* RegBasePick - -* Purpose: -* Return a Region formed by picking selected base Frame axes from the -* supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* AstRegion *RegBasePick( AstRegion *this, int naxes, const int *axes, -* int *status ) - -* Class Membership: -* Box member function (over-rides the astRegBasePick protected -* method inherited from the Region class). - -* Description: -* This function attempts to return a Region that is spanned by selected -* axes from the base Frame of the encapsulated FrameSet of the supplied -* Region. This may or may not be possible, depending on the class of -* Region. If it is not possible a NULL pointer is returned. - -* Parameters: -* this -* Pointer to the Region. -* naxes -* The number of base Frame axes to select. -* axes -* An array holding the zero-based indices of the base Frame axes -* that are to be selected. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Region, or NULL if no region can be formed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* The base Frame in the supplied Region */ - AstFrame *frm; /* The base Frame in the returned Region */ - AstPointSet *pset; /* Holds axis values defining the supplied Region */ - AstRegion *bunc; /* The uncertainty in the supplied Region */ - AstRegion *result; /* Returned Region */ - AstRegion *unc; /* The uncertainty in the returned Region */ - double **ptr; /* Holds axis values defining the supplied Region */ - double *cen; /* Base Frm axis values at centre of returned Box */ - double *cor; /* Base Frm axis values at a corner of returned Box */ - int i; /* Index of axis within returned Region */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the base Frame of the encapsulated FrameSet. */ - bfrm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Create a Frame by picking the selected axes from the base Frame of the - encapsulated FrameSet. */ - frm = astPickAxes( bfrm, naxes, axes, NULL ); - -/* Get the uncertainty Region (if any) within the base Frame of the supplied - Region, and select the required axes from it. If the resulting Object - is not a Region, annul it so that the returned Region will have no - uncertainty. */ - if( astTestUnc( this_region ) ) { - bunc = astGetUncFrm( this_region, AST__BASE ); - unc = astPickAxes( bunc, naxes, axes, NULL ); - bunc = astAnnul( bunc ); - - if( ! astIsARegion( unc ) ) unc = astAnnul( unc ); - - } else { - unc = NULL; - } - -/* Get pointers to the coordinate data in the parent Region structure. */ - pset = this_region->points; - ptr = astGetPoints( pset ); - -/* Get space to hold the centre and corner of the Box in the new Frame. */ - cen = astMalloc( sizeof( *cen )*naxes ); - cor = astMalloc( sizeof( *cor )*naxes ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Copy the centre and corner axis values for the selected axes into the - arrays allocated above. */ - for( i = 0; i < naxes; i++ ) { - cen[ i ] = ptr[ axes[ i ] ][ 0 ]; - cor[ i ] = ptr[ axes[ i ] ][ 1 ]; - } - -/* Create the new Box. */ - result = (AstRegion *) astBox( frm, 0, cen, cor, unc, "", status ); - } - -/* Free resources */ - frm = astAnnul( frm ); - bfrm = astAnnul( bfrm ); - if( unc ) unc = astAnnul( unc ); - cen = astFree( cen ); - cor = astFree( cor ); - -/* Return a NULL pointer if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static double *RegCentre( AstRegion *this_region, double *cen, double **ptr, - int index, int ifrm, int *status ){ -/* -* Name: -* RegCentre - -* Purpose: -* Re-centre a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* double *RegCentre( AstRegion *this, double *cen, double **ptr, -* int index, int ifrm, int *status ) - -* Class Membership: -* Box member function (over-rides the astRegCentre protected -* method inherited from the Region class). - -* Description: -* This function shifts the centre of the supplied Region to a -* specified position, or returns the current centre of the Region. - -* Parameters: -* this -* Pointer to the Region. -* cen -* Pointer to an array of axis values, giving the new centre. -* Supply a NULL value for this in order to use "ptr" and "index" to -* specify the new centre. -* ptr -* Pointer to an array of points, one for each axis in the Region. -* Each pointer locates an array of axis values. This is the format -* returned by the PointSet method astGetPoints. Only used if "cen" -* is NULL. -* index -* The index of the point within the arrays identified by "ptr" at -* which is stored the coords for the new centre position. Only used -* if "cen" is NULL. -* ifrm -* Should be AST__BASE or AST__CURRENT. Indicates whether the centre -* position is supplied and returned in the base or current Frame of -* the FrameSet encapsulated within "this". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If both "cen" and "ptr" are NULL then a pointer to a newly -* allocated dynamic array is returned which contains the centre -* coords of the Region. This array should be freed using astFree when -* no longer needed. If either of "ptr" or "cen" is not NULL, then a -* NULL pointer is returned. - -* Notes: -* - Some Region sub-classes do not have a centre. Such classes will report -* an AST__INTER error code if this method is called with either "ptr" or -* "cen" not NULL. If "ptr" and "cen" are both NULL, then no error is -* reported if this method is invoked on a Region of an unsuitable class, -* but NULL is always returned. - -*/ - -/* Local Variables: */ - AstBox *this; /* Pointer to Box structure */ - AstFrame *frm; /* Pointer to Box's base Frame */ - double **rptr; /* Data pointers for Region PointSet */ - double *bc; /* Base Frame centre position */ - double *corner; /* Array holding corner axis values */ - double *result; /* Returned pointer */ - double *tmp; /* Temporary array pointer */ - double axval; /* Axis value */ - int ic; /* Coordinate index */ - int ncb; /* Number of base frame coordinate values per point */ - int ncc; /* Number of current frame coordinate values per point */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Box structure. */ - this = (AstBox *) this_region; - -/* First ensure cached information (which includes the centre coords) - is up to date. */ - Cache( this, 0, status ); - -/* Get the number of axis values per point in the base and current Frames. */ - ncb = astGetNin( this_region->frameset ); - ncc = astGetNout( this_region->frameset ); - -/* If the centre coords are to be returned, return either a copy of the - base Frame centre coords, or transform the base Frame centre coords - into the current Frame. First ensure cached information (which - includes the centre coords) is up to date. */ - if( !ptr && !cen ) { - if( ifrm == AST__CURRENT ) { - result = astRegTranPoint( this_region, this->centre, 1, 1 ); - } else { - result = astStore( NULL, this->centre, sizeof( double )*ncb ); - } - -/* Otherwise, we store the supplied new centre coords and return a NULL - pointer. */ - } else { - -/* Get a pointer to the axis values stored in the Region structure. */ - rptr = astGetPoints( this_region->points ); - -/* Check pointers can be used safely */ - if( astOK ) { - -/* If the centre position was supplied in the current Frame, find the - corresponding base Frame position... */ - if( ifrm == AST__CURRENT ) { - if( cen ) { - bc = astRegTranPoint( this_region, cen, 1, 0 ); - } else { - tmp = astMalloc( sizeof( double)*(size_t)ncc ); - if( astOK ) { - for( ic = 0; ic < ncc; ic++ ) tmp[ ic ] = ptr[ ic ][ index ]; - } - bc = astRegTranPoint( this_region, tmp, 1, 0 ); - tmp = astFree( tmp ); - } - -/* Replace any bad centre values with their current values. */ - for( ic = 0; ic < ncb; ic++ ) { - if( bc[ ic ] == AST__BAD ) bc[ ic ] = this->centre[ ic ]; - } - -/* If the centre position was supplied in the base Frame, store the - centre coords in this->centre, skipping bad values. */ - } else { - bc = this->centre; - for( ic = 0; ic < ncb; ic++ ) { - axval = cen ? cen[ ic ] : ptr[ ic ][ index ]; - if( axval != AST__BAD ) bc[ ic ] = axval; - } - } - -/* Find the coordinates at the new box corner. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - corner = GeoCorner( frm, ncb, bc, this->geolen, NULL, status ); - frm = astAnnul( frm ); - -/* ... and change the coords in the parent Region structure. */ - for( ic = 0; ic < ncb; ic++ ) { - rptr[ ic ][ 0 ] = bc[ ic ]; - rptr[ ic ][ 1 ] = corner[ ic ]; - } - -/* Free resources */ - if( ifrm == AST__CURRENT ) bc = astFree( bc ); - corner = astFree( corner ); - -/* Indicate the cached info in the Box structure is out of date. */ - astResetCache( this ); - -/* Any base Frame mesh or grid is now no good, so annul it. */ - if( this_region->basemesh ) this_region->basemesh = astAnnul( this_region->basemesh ); - if( this_region->basegrid ) this_region->basegrid = astAnnul( this_region->basegrid ); - - } - } - - -/* Return the result. */ - return result; -} - -static int RegPins( AstRegion *this_region, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -* Name: -* RegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given Box. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask, int *status ) - -* Class Membership: -* Box member function (over-rides the astRegPins protected -* method inherited from the Region class). - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given Box. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied Box "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the Box. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "pset". -* Each element in the returned array is set to 1 if the -* corresponding position in "pset" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*/ - -/* Local variables: */ - AstBox *large_box; /* Box slightly larger than "this" */ - AstBox *small_box; /* Box slightly smaller than "this" */ - AstBox *this; /* Pointer to the Box structure. */ - AstFrame *frm; /* Base Frame in supplied Box */ - AstPointSet *ps1; /* Points masked by larger Box */ - AstPointSet *ps2; /* Points masked by larger and smaller Boxes */ - AstRegion *tunc; /* Uncertainity Region from "this" */ - double **ptr; /* Pointer to axis values in "ps2" */ - double *large; /* A corner position in the larger Box */ - double *safe; /* An interior point in "this" */ - double *lbnd_tunc; /* Lower bounds of "this" uncertainty Region */ - double *lbnd_unc; /* Lower bounds of supplied uncertainty Region */ - double *p; /* Pointer to next axis value */ - double *small; /* A corner position in the smaller Box */ - double *ubnd_tunc; /* Upper bounds of "this" uncertainty Region */ - double *ubnd_unc; /* Upper bounds of supplied uncertainty Region */ - double *wid; /* Widths of "this" border */ - int i; /* Axis index */ - int j; /* Point index */ - int nc; /* No. of axes in Box base frame */ - int np; /* No. of supplied points */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - if( mask ) *mask = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the Box structure. */ - this = (AstBox *) this_region; - -/* Ensure cached information is up to date. */ - Cache( this, 0, status ); - -/* Get the number of base Frame axes in the Box, and check the supplied - PointSet has the same number of axis values per point. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - nc = astGetNaxes( frm ); - if( astGetNcoord( pset ) != nc && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axis " - "values per point (%d) in the supplied PointSet - should be " - "%d (internal AST programming error).", status, astGetClass( this ), - astGetNcoord( pset ), nc ); - } - -/* Get the number of axes in the uncertainty Region and check it is the - same as above. */ - if( unc && astGetNaxes( unc ) != nc && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axes (%d) " - "in the supplied uncertainty Region - should be " - "%d (internal AST programming error).", status, astGetClass( this ), - astGetNaxes( unc ), nc ); - } - -/* Get the centre of the region in the base Frame. We use this as a "safe" - interior point within the region. */ - safe = astRegCentre( this, NULL, NULL, 0, AST__BASE ); - -/* We now find the maximum distance on each axis that a point can be from the - boundary of the Box for it still to be considered to be on the boundary. - First get the Region which defines the uncertainty within the Box being - checked (in its base Frame), re-centre it on the interior point found - above (to avoid problems if the uncertainty region straddles a - discontinuity), and get its bounding box. */ - tunc = astGetUncFrm( this, AST__BASE ); - if( safe ) astRegCentre( tunc, safe, NULL, 0, AST__CURRENT ); - lbnd_tunc = astMalloc( sizeof( double )*(size_t) nc ); - ubnd_tunc = astMalloc( sizeof( double )*(size_t) nc ); - astGetRegionBounds( tunc, lbnd_tunc, ubnd_tunc ); - -/* Also get the Region which defines the uncertainty of the supplied - points and get its bounding box. First re-centre the uncertainty at the - interior position to avoid problems from uncertainties that straddle a - discontinuity. */ - if( unc ) { - if( safe ) astRegCentre( unc, safe, NULL, 0, AST__CURRENT ); - lbnd_unc = astMalloc( sizeof( double )*(size_t) nc ); - ubnd_unc = astMalloc( sizeof( double )*(size_t) nc ); - astGetRegionBounds( unc, lbnd_unc, ubnd_unc ); - } else { - lbnd_unc = NULL; - ubnd_unc = NULL; - } - -/* The required border width for each axis is half of the total width - of the two bounding boxes. Use a zero sized box "unc" if no box was - supplied. */ - wid = astMalloc( sizeof( double )*(size_t) nc ); - large = astMalloc( sizeof( double )*(size_t) nc ); - small = astMalloc( sizeof( double )*(size_t) nc ); - if( astOK ) { - if( unc ) { - for( i = 0; i < nc; i++ ) { - wid[ i ] = 0.5*( fabs( astAxDistance( frm, i + 1, lbnd_tunc[ i ], ubnd_tunc[ i ] ) ) - + fabs( astAxDistance( frm, i + 1, lbnd_unc[ i ], ubnd_unc[ i ] ) ) ); - } - } else { - for( i = 0; i < nc; i++ ) { - wid[ i ] = fabs( 0.5*astAxDistance( frm, i + 1, lbnd_tunc[ i ], ubnd_tunc[ i ] ) ); - } - } - -/* Create two new Boxes, one of which is larger than "this" by the widths - found above, and the other of which is smaller than "this" by the widths - found above. */ - for( i = 0; i < nc; i++ ) { - large[ i ] = this->centre[ i ] + this->extent[ i ] + wid[ i ]; - small[ i ] = this->extent[ i ] - wid[ i ]; - if( small[ i ] < 0.0 ) small[ i ] = 0.0; - small[ i ] += this->centre[ i ]; - } - - large_box = astBox( frm, 0, this->centre, large, NULL, "", status ); - small_box = astBox( frm, 0, this->centre, small, NULL, "", status ); - -/* Negate the smaller region.*/ - astNegate( small_box ); - -/* Points are on the boundary of "this" if they are inside both the large - box and the negated smallbox. First transform the supplied PointSet - using the large box, then transform them using the negated smaller Box. */ - ps1 = astTransform( large_box, pset, 1, NULL ); - ps2 = astTransform( small_box, ps1, 1, NULL ); - -/* Get a point to the resulting axis values, and the number of axis - values per axis. */ - ptr = astGetPoints( ps2 ); - np = astGetNpoint( ps2 ); - -/* If a mask array is to be returned, create one. */ - if( mask ) { - *mask = astMalloc( sizeof(int)*(size_t) np ); - -/* Check all the resulting points, setting mask values for all of them. */ - if( astOK ) { - -/* Initialise the mask elements on the basis of the first axis values */ - result = 1; - p = ptr[ 0 ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ j ] = 0; - } else { - (*mask)[ j ] = 1; - } - } - -/* Now check for bad values on other axes. */ - for( i = 1; i < nc; i++ ) { - p = ptr[ i ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ j ] = 0; - } - } - } - } - -/* If no output mask is to be made, we can break out of the check as soon - as the first bad value is found. */ - } else if( astOK ) { - result = 1; - for( i = 0; i < nc && result; i++ ) { - p = ptr[ i ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - break; - } - } - } - } - -/* Free resources. */ - large_box = astAnnul( large_box ); - small_box = astAnnul( small_box ); - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - } - - tunc = astAnnul( tunc ); - frm = astAnnul( frm ); - lbnd_tunc = astFree( lbnd_tunc ); - ubnd_tunc = astFree( ubnd_tunc ); - if( unc ) lbnd_unc = astFree( lbnd_unc ); - if( unc ) ubnd_unc = astFree( ubnd_unc ); - wid = astFree( wid ); - large = astFree( large ); - small = astFree( small ); - safe = astFree( safe ); - -/* If an error has occurred, return zero. */ - if( !astOK ) { - result = 0; - if( mask ) *mask = astAnnul( *mask ); - } - -/* Return the result. */ - return result; -} - -static int RegTrace( AstRegion *this_region, int n, double *dist, double **ptr, - int *status ){ -/* -*+ -* Name: -* RegTrace - -* Purpose: -* Return requested positions on the boundary of a 2D Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* int astTraceRegion( AstRegion *this, int n, double *dist, double **ptr ); - -* Class Membership: -* Box member function (overrides the astTraceRegion method -* inherited from the parent Region class). - -* Description: -* This function returns positions on the boundary of the supplied -* Region, if possible. The required positions are indicated by a -* supplied list of scalar parameter values in the range zero to one. -* Zero corresponds to some arbitrary starting point on the boundary, -* and one corresponds to the end (which for a closed region will be -* the same place as the start). - -* Parameters: -* this -* Pointer to the Region. -* n -* The number of positions to return. If this is zero, the function -* returns without action (but the returned function value still -* indicates if the method is supported or not). -* dist -* Pointer to an array of "n" scalar parameter values in the range -* 0 to 1.0. -* ptr -* A pointer to an array of pointers. The number of elements in -* this array should equal tthe number of axes in the Frame spanned -* by the Region. Each element of the array should be a pointer to -* an array of "n" doubles, in which to return the "n" values for -* the corresponding axis. The contents of the arrays are unchanged -* if the supplied Region belongs to a class that does not -* implement this method. - -* Returned Value: -* Non-zero if the astTraceRegion method is implemented by the class -* of Region supplied, and zero if not. - -*- -*/ - -/* Local Variables; */ - AstMapping *map; - AstPointSet *bpset; - AstPointSet *cpset; - double **bptr; - double d; - double lbnd[ 2 ]; - double ubnd[ 2 ]; - int i; - int ncur; - int result; - -/* Initialise */ - result = 0; - -/* Check inherited status. */ - if( ! astOK ) return result; - -/* Check it is 2-dimensional. */ - if( astGetNin( this_region->frameset ) == 2 ) result = 1; - -/* Check we have some points to find. */ - if( result && n > 0 ) { - -/* We first determine the required positions in the base Frame of the - Region, and then transform them into the current Frame. Get the - base->current Mapping, and the number of current Frame axes. */ - map = astGetMapping( this_region->frameset, AST__BASE, AST__CURRENT ); - -/* If it's a UnitMap we do not need to do the transformation, so put the - base Frame positions directly into the supplied arrays. */ - if( astIsAUnitMap( map ) ) { - bpset = NULL; - bptr = ptr; - ncur = 2; - -/* Otherwise, create a PointSet to hold the base Frame positions. */ - } else { - bpset = astPointSet( n, 2, " ", status ); - bptr = astGetPoints( bpset ); - ncur = astGetNout( map ); - } - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Get the bounds of the Region in the base Frame. */ - astRegBaseBox( this_region, lbnd, ubnd ); - -/* Loop round each point. Each edge of the box covers a parameteric - distance of 0.25, regardless of the aspect ratio of the box. */ - for( i = 0; i < n; i++ ) { - -/* The right hand edge starts at 0.75 (parameter increases top to bottom). */ - d = 4*dist[ i ] - 3; - if( d > 0 ) { - bptr[ 0 ][ i ] = ubnd[ 0 ]; - bptr[ 1 ][ i ] = ( 1.0 - d )*ubnd[ 1 ] + d*lbnd[ 1 ]; - -/* The top edge starts at 0.5 (parameter increases left to right). */ - } else { - d += 1.0; - if( d > 0 ) { - bptr[ 0 ][ i ] = ( 1.0 - d )*lbnd[ 0 ] + d*ubnd[ 0 ]; - bptr[ 1 ][ i ] = ubnd[ 1 ]; - -/* The left hand edge starts at 0.25 (parameter increases bottom to top). */ - } else { - d += 1.0; - if( d > 0 ) { - bptr[ 0 ][ i ] = lbnd[ 0 ]; - bptr[ 1 ][ i ] = ( 1.0 - d )*lbnd[ 1 ] + d*ubnd[ 1 ]; - -/* The bottom edge starts at 0.0 (parameter increases right to left). */ - } else { - d += 1.0; - bptr[ 0 ][ i ] = ( 1.0 - d )*ubnd[ 0 ] + d*lbnd[ 0 ]; - bptr[ 1 ][ i ] = lbnd[ 1 ]; - } - } - } - } - } - -/* If required, transform the base frame positions into the current - Frame, storing them in the supplied array. Then free resources. */ - if( bpset ) { - cpset = astPointSet( n, ncur, " ", status ); - astSetPoints( cpset, ptr ); - - (void) astTransform( map, bpset, 1, cpset ); - - cpset = astAnnul( cpset ); - bpset = astAnnul( bpset ); - } - -/* Free remaining resources. */ - map = astAnnul( map ); - } - -/* Return the result. */ - return result; -} - -static void ResetCache( AstRegion *this, int *status ){ -/* -* Name: -* ResetCache - -* Purpose: -* Clear cached information within the supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* void ResetCache( AstRegion *this, int *status ) - -* Class Membership: -* Region member function (overrides the astResetCache method -* inherited from the parent Region class). - -* Description: -* This function clears cached information from the supplied Region -* structure. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. -*/ - if( this ) { - ((AstBox *) this )->stale = 1; - (*parent_resetcache)( this, status ); - } -} - -static void SetClosed( AstRegion *this, int value, int *status ){ -/* -* Name: -* SetClosed - -* Purpose: -* Set a value for the Closed attribute of a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* void SetClosed( AstRegion *this, int value, int *status ) - -* Class Membership: -* Box member function (over-rides the protected astSetClosed -* method inherited from the Region class). - -* Description: -* This function sets a new value for the Closed attribute of a Region. - -* Parameters: -* this -* Pointer to the Region. -* value -* The new attribute value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int old; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the original attribute value */ - old = astGetClosed( this ); - -/* Invoke the set method inherited from the parent Region class */ - (*parent_setclosed)( this, value, status ); - -/* If the new value is not the same as the old value, indicate that we - need to re-calculate the cached information in the Box. */ - if( value != old ) astResetCache( this ); -} - -static void SetNegated( AstRegion *this, int value, int *status ){ -/* -* Name: -* SetNegated - -* Purpose: -* Set a value for the Negated attribute of a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* void SetNegated( AstRegion *this, int value, int *status ) - -* Class Membership: -* Box member function (over-rides the protected astSetNegated -* method inherited from the Region class). - -* Description: -* This function sets a new value for the Negated attribute of a Region. - -* Parameters: -* this -* Pointer to the Region. -* value -* The new attribute value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int old; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the original attribute value */ - old = astGetNegated( this ); - -/* Invoke the set method inherited from the parent Region class */ - (*parent_setnegated)( this, value, status ); - -/* If the new value is not the same as the old value, indicate that we - need to re-calculate the cached information in the Box. */ - if( value != old ) astResetCache( this ); -} - -static void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) { -/* -* Name: -* SetRegFS - -* Purpose: -* Stores a new FrameSet in a Region - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) - -* Class Membership: -* Box method (over-rides the astSetRegFS method inherited from -* the Region class). - -* Description: -* This function creates a new FrameSet and stores it in the supplied -* Region. The new FrameSet contains two copies of the supplied -* Frame, connected by a UnitMap. - -* Parameters: -* this -* Pointer to the Region. -* frm -* The Frame to use. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent method to store the FrameSet in the parent Region - structure. */ - (* parent_setregfs)( this_region, frm, status ); - -/* Indicate that we need to re-calculate the cached information in the Box. */ - astResetCache( this_region ); -} - -static void SetUnc( AstRegion *this, AstRegion *unc, int *status ){ -/* -* Name: -* SetUnc - -* Purpose: -* Store uncertainty information in a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* void SetUnc( AstRegion *this, AstRegion *unc, int *status ) - -* Class Membership: -* Box method (over-rides the astSetUnc method inherited from the -* Region class). - -* Description: -* Each Region (of any class) can have an "uncertainty" which specifies -* the uncertainties associated with the boundary of the Region. This -* information is supplied in the form of a second Region. The uncertainty -* in any point on the boundary of a Region is found by shifting the -* associated "uncertainty" Region so that it is centred at the boundary -* point being considered. The area covered by the shifted uncertainty -* Region then represents the uncertainty in the boundary position. -* The uncertainty is assumed to be the same for all points. -* -* The uncertainty is usually specified when the Region is created, but -* this function allows it to be changed at any time. - -* Parameters: -* this -* Pointer to the Region which is to be assigned a new uncertainty. -* unc -* Pointer to the new uncertainty Region. This must be either a Box, -* a Circle or an Ellipse. A deep copy of the supplied Region will be -* taken, so subsequent changes to the uncertainty Region using the -* supplied pointer will have no effect on the Region "this". -* status -* Pointer to the inherited status variable. -*/ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Invoke the astSetUnc method inherited from the parent Region class. */ - (*parent_setunc)( this, unc, status ); - -/* Indicate that we need to re-calculate the cached information in the Box. */ - astResetCache( this ); -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mapping represented by a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* Box method (over-rides the astSimplify method inherited -* from the Region class). - -* Description: -* This function invokes the parent Region Simplify method, and then -* performs any further region-specific simplification. -* -* If the Mapping from base to current Frame is not a UnitMap, this -* will include attempting to fit a new Region to the boundary defined -* in the current Frame. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the simplified Region. A cloned pointer to the -* supplied Region will be returned if no simplication could be -* performed. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstBox *box; /* Pointer to Box structure */ - AstBox *newbox; /* Pointer to simpler Box */ - AstFrame *frm; /* Pointer to current Frame */ - AstMapping *map; /* Base -> current Mapping */ - AstMapping *result; /* Result pointer to return */ - AstPointSet *basemesh; /* Mesh of base Frame positions */ - AstPointSet *mesh; /* Mesh of current Frame positions */ - AstPointSet *ps1; /* Box corners in base Frame */ - AstPointSet *ps2; /* Box corners in current Frame */ - AstPolygon *newpoly; /* New Polygon to replace Box */ - AstRegion *prism; /* Prism combining all axes */ - AstRegion *new; /* Pointer to simplified Region */ - AstRegion *this; /* Pointer to supplied Region structure */ - AstRegion *unc; /* Pointer to uncertainty Region */ - double **ptr1; /* Pointers to axis values in ps1 */ - double **ptr2; /* Pointers to axis values in ps2 */ - double *constants; /* Axis constants array */ - double *lbnd; /* Lower bounds for new Box */ - double *ubnd; /* Upper bounds for new Box */ - double corners[8]; /* Box corners in current Frame */ - double k; /* Axis constant value */ - double lb; /* Lower axis bound */ - double ub; /* Upper axis bound */ - int *inperm; /* Input axis permutation array */ - int *outperm; /* Output axis permutation array */ - int closed; /* Was original Region closed? */ - int feed; /* Source of value for current axis */ - int right_handed; /* Is the new Frame right handed? */ - int ic; /* Axis index */ - int isInterval; /* Is the simplified Box an Interval */ - int isNull; /* Is the simplified Box a NullRegion? */ - int neg; /* Was original Region negated? */ - int nin; /* No. of base Frame axes (Mapping inputs) */ - int nout; /* No. of current Frame axes (Mapping outputs) */ - int simpler; /* Has some simplication taken place? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_mapping; - -/* Invoke the parent Simplify method inherited from the Region class. This - will simplify the encapsulated FrameSet and uncertainty Region. */ - new = (AstRegion *) (*parent_simplify)( this_mapping, status ); - -/* Note if any simplification took place. This is assumed to be the case - if the pointer returned by the above call is different to the supplied - pointer. */ - simpler = ( new != this ); - -/* Get the Mapping from base to current Frame. */ - map = astGetMapping( new->frameset, AST__BASE, AST__CURRENT ); - -/* Get the number of inputs and outputs for the PermMap */ - nin = astGetNin( map ); - nout = astGetNout( map ); - -/* If the Mapping from base to current Frame is a PermMap, we now explicitly - how to swap the axes of the Box to produce either a new Box or an - Interval. */ - if( astIsAPermMap( map ) ){ - -/* See if the new Box is Negated and/or Closed.*/ - neg = astGetNegated( new ); - closed = astGetClosed( new ); - -/* Get a pointer to the Box structure. */ - newbox = (AstBox *) new; - -/* Ensure cached information is up to date. */ - Cache( newbox, 0, status ); - -/* Get the input and output permutation arrays and the array of constants - from the PermMap. */ - inperm = astGetInPerm( map ); - outperm = astGetOutPerm( map ); - constants = astGetConstants( map ); - -/* Allocate memory to hold the axis bounds for the box in the current - Frame. */ - lbnd = astMalloc( sizeof( double )*(size_t) nout ); - ubnd = astMalloc( sizeof( double )*(size_t) nout ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Set flags indicating that the Box can be simplified, and does not result - in a NullRegion or an Interval. */ - simpler = 1; - isNull = 0; - isInterval = 0; - -/* Check each output (which corresponds to an axis in the current Frame - of the Box). */ - for( ic = 0; ic < nout; ic++ ) { - -/* Find the input (a base Frame axis) which feeds this output when the - forward transformation of the PermMap is used. */ - feed = outperm[ ic ]; - -/* If this output is fed a constant (i.e. does not depend on any of the - inputs), then the output axis limits are equal to this constant. */ - if( feed < 0 ) { - lbnd[ ic ] = constants[ (-feed) - 1 ]; - ubnd[ ic ] = constants[ (-feed) - 1 ]; - -/* If this output is fed the constant AST__BAD (i.e. does not depend on any of - the inputs), then the output axis is unbounded and we will consequently - create an Interval rather than a Box. */ - } else if( feed >= nin ) { - lbnd[ ic ] = AST__BAD; - ubnd[ ic ] = AST__BAD; - -/* If this output is fed the value of an input, then the output limits - are equal to the corresponding input limits. */ - } else { - lbnd[ ic ] = newbox->centre[ feed ] - newbox->extent[ feed ]; - ubnd[ ic ] = newbox->centre[ feed ] + newbox->extent[ feed ]; - } - -/* If either bound is missing we will produce an Interval rather than a - Box. */ - if( lbnd[ ic ] == AST__BAD || ubnd[ ic ] == AST__BAD ) { - isInterval = 1; - } - } - -/* If any base Frame axes are not present in the current Frame, we need - to check that the PermMap selects a slice which intersects the base - Frame box. If the slice does not intersect the base Frame box, then - the resulting Region willbe NullRegion. To do this, we check each - element in the input axis permutation array, "inperm". */ - for( ic = 0; ic < nin; ic++ ) { - -/* Find the output (a current Frame axis) which feeds this input when the - inverse transformation of the PermMap is used. */ - feed = inperm[ ic ]; - -/* If this input is fed a constant (i.e. does not depend on any of the - outputs), then we must check that this constant is within the range of - axis values covered by the Box. If not then the simplified Box represents - a slice through the coordinate system which does not pass through the - original Box. In this case the simplified Region is a NullRegion - instead of a Box. */ - if( feed < 0 ) { - k = constants[ (-feed) - 1 ]; - lb = newbox->centre[ ic ] - newbox->extent[ ic ]; - ub = newbox->centre[ ic ] + newbox->extent[ ic ]; - - if( closed == neg ) { - isNull = ( k <= lb || k >= ub ); - } else { - isNull = ( k < lb || k > ub ); - } - -/* If this input is fed the constant AST__BAD (i.e. does not depend on any of - the outputs), then the input axis is unbounded and will consequently - extend beyond the Box. In this case the simplified Region will be a - NullRegion. */ - } else if( feed >= nout ) { - isNull = 1; - -/* If this input is fed the value of an output, then check that the - relationship is bi-directional. If it is not, we cannot simplify the - Box. */ - } else if( outperm[ feed ] != ic ) { - simpler = 0; - break; - } - } - -/* If the Box can be simplified, create a new Region of an appropriate - class. */ - if( simpler ) { - -/* Get any uncertainty from the supplied Box (it will already have been - simplified by the parent Simplify method). */ - unc = astTestUnc( new ) ? astGetUncFrm( new, AST__CURRENT ) : NULL; - -/* Get the Frame represented by the Region. */ - frm = astGetFrame( new->frameset, AST__CURRENT ); - -/* We can now replace the original Region with the simplified Region so annul - the original pointer. */ - new = astAnnul( new ); - -/* Create a new Region of the required class. */ - if( isNull ) { - new = (AstRegion *) astNullRegion( frm, unc, "", status ); - - } else if( isInterval ){ - new = (AstRegion *) astInterval( frm, lbnd, ubnd, unc, "", status ); - - } else { - new = (AstRegion *) astBox( frm, 1, lbnd, ubnd, unc, "", status ); - } - -/* If the original box was Negated. Negate the new one. */ - if( neg ) astNegate( new ); - -/* Free resources */ - if( unc ) unc = astAnnul( unc ); - frm = astAnnul( frm ); - - } - } - -/* Free resources */ - inperm = astFree( inperm ); - outperm = astFree( outperm ); - constants = astFree( constants ); - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - -/* If the Mapping from base to current Frame is not a PermMap or a UnitMap, we - attempt to simplify the Box by re-defining it within its current Frame. - Transforming the box from its base to its current FRame may result in - the region no longer being a box. We test this by transforming a set of - bounds on the box boundary. */ - } else if( !astIsAUnitMap( map ) ){ - -/* Get pointer to current Frame. */ - frm = astGetFrame( new->frameset, AST__CURRENT ); - -/* Get a mesh of points covering the Box in its current Frame. */ - mesh = astRegMesh( new ); - -/* Get the Region describing the positional uncertainty within the Box in - its current Frame. */ - unc = astGetUncFrm( new, AST__CURRENT ); - -/* Find the best fitting box (defined in the current Frame) through these - points */ - newbox = BestBox( frm, mesh, unc, status ); - -/* See if all points within this mesh fall on the boundary of the best - fitting Box, to within the uncertainty of the Region. */ - if( newbox && astRegPins( newbox, mesh, NULL, NULL ) ) { - -/* If so, check that the inverse is true (we need to transform the - simplified boxes mesh into the base Frame of he original box for use by - astRegPins). */ - (void) astAnnul( mesh ); - mesh = astRegMesh( newbox ); - basemesh = astTransform( map, mesh, 0, NULL ); - if( astRegPins( new, basemesh, NULL, NULL ) ) { - -/* If so, use the new Box in place of the original Box. */ - (void) astAnnul( new ); - new = astClone( newbox ); - simpler = 1; - } - -/* Free resources. */ - basemesh = astAnnul( basemesh ); - -/* If the transformed Box is not itself a Box, see if it can be - represented accurately by a Polygon. This is only possible for - 2-dimensional Boxes. */ - } else if( nin == 2 && nout == 2 ) { - -/* Create a PointSet holding the base Frame axis values at the four - corners of the Box. */ - ps1 = astPointSet( 4, 2, "", status ); - ptr1 = astGetPoints( ps1 ); - if( astOK ) { - box = (AstBox *) new; - Cache( box, 0, status ); - -/* The order in which the polygon vertices are stored determines whether - the interior or exterior of the polygon forms the inside of the - Region. We want the inside to be the interior. First create a Polygon - in which the vertices are stored in clockwise order within the - new coordinate Frame. If the new Polygon is not bounded, use - anti-clockwise order. */ - for( right_handed = 0; right_handed < 2; right_handed++ ) { - - if( right_handed ) { - ptr1[ 0 ][ 0 ] = box->centre[ 0 ] - box->extent[ 0 ]; - ptr1[ 1 ][ 0 ] = box->centre[ 1 ] + box->extent[ 1 ]; - - ptr1[ 0 ][ 1 ] = box->centre[ 0 ] - box->extent[ 0 ]; - ptr1[ 1 ][ 1 ] = box->centre[ 1 ] - box->extent[ 1 ]; - - ptr1[ 0 ][ 2 ] = box->centre[ 0 ] + box->extent[ 0 ]; - ptr1[ 1 ][ 2 ] = box->centre[ 1 ] - box->extent[ 1 ]; - - ptr1[ 0 ][ 3 ] = box->centre[ 0 ] + box->extent[ 0 ]; - ptr1[ 1 ][ 3 ] = box->centre[ 1 ] + box->extent[ 1 ]; - - } else { - ptr1[ 0 ][ 3 ] = box->centre[ 0 ] - box->extent[ 0 ]; - ptr1[ 1 ][ 3 ] = box->centre[ 1 ] + box->extent[ 1 ]; - - ptr1[ 0 ][ 2 ] = box->centre[ 0 ] - box->extent[ 0 ]; - ptr1[ 1 ][ 2 ] = box->centre[ 1 ] - box->extent[ 1 ]; - - ptr1[ 0 ][ 1 ] = box->centre[ 0 ] + box->extent[ 0 ]; - ptr1[ 1 ][ 1 ] = box->centre[ 1 ] - box->extent[ 1 ]; - - ptr1[ 0 ][ 0 ] = box->centre[ 0 ] + box->extent[ 0 ]; - ptr1[ 1 ][ 0 ] = box->centre[ 1 ] + box->extent[ 1 ]; - } - -/* Transform the Box corners into the current Frame. */ - ps2 = astTransform( map, ps1, 1, NULL ); - ptr2 = astGetPoints( ps2 ); - if( astOK ) { - -/* Create a Polygon from these points. */ - for( ic = 0; ic < 4; ic++ ) { - corners[ ic ] = ptr2[ 0 ][ ic ]; - corners[ 4 + ic ] = ptr2[ 1 ][ ic ]; - } - newpoly = astPolygon( frm, 4, 4, corners, unc, "", status ); - -/* If the Polygon is bounded, break out of the loop. */ - if( astGetBounded( newpoly ) ) break; - } - -/* Free resources. */ - newpoly = astAnnul( newpoly ); - ps2 = astAnnul( ps2 ); - } - -/* See if all points within the Box mesh fall on the boundary of this - Polygon, to within the uncertainty of the Region. */ - if( astRegPins( newpoly, mesh, NULL, NULL ) ) { - -/* If so, use the new Polygon in place of the original Box. */ - (void) astAnnul( new ); - new = astClone( newpoly ); - simpler = 1; - } - -/* Free resources. */ - newpoly = astAnnul( newpoly ); - } - - ps1 = astAnnul( ps1 ); - } - -/* If we have yet been able to produce a simpler region, we now try - splitting the Box into two separate Boxes defined in separate - coordinate Frames. If either of these two Boxes can be simplified, - create a Prism containing the two simplified Boxes, and attempt to - simplify the Prism. Otherwise a clone of "new" is returned by - astConvertToPrism. */ - if( !simpler ) { - prism = astConvertToPrism( new ); - - if( prism != new ) { - simpler = 1; - (void) astAnnul( new ); - new = prism; - - } else { - prism = astAnnul( prism ); - } - } - - frm = astAnnul( frm ); - mesh = astAnnul( mesh ); - unc = astAnnul( unc ); - if( newbox ) newbox = astAnnul( newbox ); - } - - map = astAnnul( map ); - -/* If any simplification could be performed, copy Region attributes from - the supplied Region to the returned Region, and return a pointer to it. - If the supplied Region had no uncertainty, ensure the returned Region - has no uncertainty. Otherwise, return a clone of the supplied pointer. */ - if( simpler ){ - astRegOverlay( new, this, 1 ); - result = (AstMapping *) new; - - } else { - new = astAnnul( new ); - result = astClone( this ); - } - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a Box to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* Box member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a Box and a set of points encapsulated in a -* PointSet and transforms the points by setting axis values to -* AST__BAD for all points which are outside the region. Points inside -* the region are copied unchanged from input to output. - -* Parameters: -* this -* Pointer to the Box. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - The forward and inverse transformations are identical for a -* Region. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of axes in the Frame represented by the Box. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstBox *box; /* Pointer to Box */ - AstFrame *frm; /* Pointer to base Frame in FrameSet */ - AstPointSet *pset_tmp; /* Pointer to PointSet holding base Frame positions*/ - AstPointSet *result; /* Pointer to output PointSet */ - AstRegion *reg; /* Pointer to Region */ - double **ptr_out; /* Pointer to output coordinate data */ - double **ptr_tmp; /* Pointer to base Frame coordinate data */ - double axval; /* Input axis value */ - int closed; /* Is the boundary part of the Region? */ - int coord; /* Zero-based index for coordinates */ - int ncoord_out; /* No. of coordinates per output point */ - int ncoord_tmp; /* No. of coordinates per base Frame point */ - int neg; /* Is the Box negated?*/ - int npoint; /* No. of points */ - int ok; /* Is the point inside the Region? */ - int point; /* Loop counter for points */ - - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain pointers to the Regionand to the Box. */ - reg = (AstRegion *) this; - box = (AstBox *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, - containing a copy of the input PointSet. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* First use the encapsulated FrameSet to transform the supplied positions - from the current Frame in the encapsulated FrameSet (the Frame - represented by the Region), to the base Frame (the Frame in which the - Region is defined). This call also returns a pointer to the base Frame - of the encapsulated FrameSet. Note, the returned pointer may be a - clone of the "in" pointer, and so we must be carefull not to modify the - contents of the returned PointSet. */ - pset_tmp = astRegTransform( reg, in, 0, NULL, &frm ); - -/* Determine the numbers of points and coordinates per point from the base - Frame PointSet and obtain pointers for accessing the base Frame and output - coordinate values. */ - npoint = astGetNpoint( pset_tmp ); - ncoord_tmp = astGetNcoord( pset_tmp ); - ptr_tmp = astGetPoints( pset_tmp ); - ncoord_out = astGetNcoord( result ); - ptr_out = astGetPoints( result ); - -/* See if the boundary is part of the Region. */ - closed = astGetClosed( reg ); - -/* See if the Box is negated */ - neg = astGetNegated( reg ); - -/* Ensire the cached information is up to date. */ - Cache( box, 1, status ); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - -/* The logic used to combine axis values for negated and un-negated boxes - is different. For negated boxes, a position is in the region if *any - one* axis is not "close" to the box centre. */ - if( neg ) { - -/* Loop round each point */ - for ( point = 0; point < npoint; point++ ) { - -/* Assume the point is outside the Region (since the Region is - negated, this means assuming it is within the box). */ - ok = 0; - -/* Loop round each axis value at this point. We break as soon as we find - a bad axis value or an axis value which is outside the box. */ - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - -/* The point is definiately not in the Region if any input axis value is bad. */ - axval = ptr_tmp[ coord ][ point ]; - if( axval == AST__BAD ) { - break; - -/* Otherwise check the current axis value, depending on whether the - boundary is included in the Region or not. Break as soon as an axis - value is found which is outside the box limits (i.e. in the Region). */ - } else if( !astAxIn( frm, coord, box->lo[ coord ], box->hi[ coord ], - axval, !closed ) ) { - ok = 1; - break; - } - } - -/* If this point is not inside the Region store bad output axis values. */ - if( !ok ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - -/* For un-negated boxes, a position is in the region if *all* axes are "close" - to the box centre. */ - } else { - -/* Loop round each point */ - for ( point = 0; point < npoint; point++ ) { - -/* Assume the point is within the Region (i.e.inside the box). */ - ok = 1; - -/* Loop round each axis value at this point. We break when we find a bad - input point or if any axis value is outside the box. */ - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - -/* The point is not in the Region if any input axis value is bad. */ - axval = ptr_tmp[ coord ][ point ]; - if( axval == AST__BAD ) { - ok = 0; - break; - -/* Otherwise check the current axis value, depending on whether the - boundary is included in the Region or not. Break as soon as an axis - value is found which is outside the box limits (i.e. outside the Region). */ - } else if( !astAxIn( frm, coord, box->lo[ coord ], box->hi[ coord ], - axval, closed ) ) { - ok = 0; - break; - } - } - -/* If this point is outside the Region store bad output axis values. */ - if( !ok ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - } - } - -/* Free resources */ - pset_tmp = astAnnul( pset_tmp ); - frm = astAnnul( frm ); - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Region objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Region objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstBox *in; /* Pointer to input Box */ - AstBox *out; /* Pointer to output Box */ - int nax; /* Number of base Frame axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Boxs. */ - in = (AstBox *) objin; - out = (AstBox *) objout; - -/* For safety, first clear any references to the input memory from - the output Box. */ - out->extent = NULL; - out->centre = NULL; - out->lo = NULL; - out->hi = NULL; - out->geolen = NULL; - -/* Copy dynamic memory contents */ - nax = astGetNin( ((AstRegion *) in)->frameset ); - out->extent = astStore( NULL, in->extent, - sizeof( double )*(size_t)nax ); - out->centre = astStore( NULL, in->centre, - sizeof( double )*(size_t)nax ); - out->lo = astStore( NULL, in->lo, - sizeof( double )*(size_t)nax ); - out->hi = astStore( NULL, in->hi, - sizeof( double )*(size_t)nax ); - out->geolen = astStore( NULL, in->geolen, - sizeof( double )*(size_t)nax ); -} - - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Box objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Box objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstBox *this; /* Pointer to Box */ - -/* Obtain a pointer to the Box structure. */ - this = (AstBox *) obj; - -/* Annul all resources. */ - this->extent = astFree( this->extent ); - this->centre = astFree( this->centre ); - this->lo = astFree( this->lo ); - this->hi = astFree( this->hi ); - this->geolen = astFree( this->geolen ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Box objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Box class to an output Channel. - -* Parameters: -* this -* Pointer to the Box whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Write out values representing the instance variables for the - Box class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* There are no values to write, so return without further action. */ -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsABox and astCheckBox functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Box,Region) -astMAKE_CHECK(Box) - -AstBox *astBox_( void *frame_void, int form, const double point1[], - const double point2[], AstRegion *unc, const char *options, int *status, ...) { -/* -*++ -* Name: -c astBox -f AST_BOX - -* Purpose: -* Create a Box. - -* Type: -* Public function. - -* Synopsis: -c #include "box.h" -c AstBox *astBox( AstFrame *frame, int form, const double point1[], -c const double point2[], AstRegion *unc, -c const char *options, ... ) -f RESULT = AST_BOX( FRAME, FORM, POINT1, POINT2, UNC, OPTIONS, STATUS ) - -* Class Membership: -* Box constructor. - -* Description: -* This function creates a new Box and optionally initialises its -* attributes. -* -* The Box class implements a Region which represents a box with sides -* parallel to the axes of a Frame (i.e. an area which encloses a given -* range of values on each axis). A Box is similar to an Interval, the -* only real difference being that the Interval class allows some axis -* limits to be unspecified. Note, a Box will only look like a box if -* the Frame geometry is approximately flat. For instance, a Box centred -* close to a pole in a SkyFrame will look more like a fan than a box -* (the Polygon class can be used to create a box-like region close to a -* pole). - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* A pointer to the Frame in which the region is defined. A deep -* copy is taken of the supplied Frame. This means that any -* subsequent changes made to the Frame using the supplied pointer -* will have no effect the Region. -c form -f FORM = INTEGER (Given) -* Indicates how the box is described by the remaining parameters. -* A value of zero indicates that the box is specified by a centre -* position and a corner position. A value of one indicates that the -* box is specified by a two opposite corner positions. -c point1 -f POINT1( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). If -c "form" -f FORM -* is zero, this array should contain the coordinates at the centre of -* the box. -c If "form" -f If FORM -* is one, it should contain the coordinates at the corner of the box -* which is diagonally opposite the corner specified by -c "point2". -f POINT2. -c point2 -f POINT2( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the coordinates at any corner of the -* box. -c unc -f UNC = INTEGER (Given) -* An optional pointer to an existing Region which specifies the -* uncertainties associated with the boundary of the Box being created. -* The uncertainty in any point on the boundary of the Box is found by -* shifting the supplied "uncertainty" Region so that it is centred at -* the boundary point being considered. The area covered by the -* shifted uncertainty Region then represents the uncertainty in the -* boundary position. The uncertainty is assumed to be the same for -* all points. -* -* If supplied, the uncertainty Region must be of a class for which -* all instances are centro-symetric (e.g. Box, Circle, Ellipse, etc.) -* or be a Prism containing centro-symetric component Regions. A deep -* copy of the supplied Region will be taken, so subsequent changes to -* the uncertainty Region using the supplied pointer will have no -* effect on the created Box. Alternatively, -f a null Object pointer (AST__NULL) -c a NULL Object pointer -* may be supplied, in which case a default uncertainty is used -* equivalent to a box 1.0E-6 of the size of the Box being created. -* -* The uncertainty Region has two uses: 1) when the -c astOverlap -f AST_OVERLAP -* function compares two Regions for equality the uncertainty -* Region is used to determine the tolerance on the comparison, and 2) -* when a Region is mapped into a different coordinate system and -* subsequently simplified (using -c astSimplify), -f AST_SIMPLIFY), -* the uncertainties are used to determine if the transformed boundary -* can be accurately represented by a specific shape of Region. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Box. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Box. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astBox() -f AST_BOX = INTEGER -* A pointer to the new Box. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstBox *new; /* Pointer to new Box */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the supplied Frame structure. */ - frame = astCheckFrame( frame_void ); - -/* Initialise the Box, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitBox( NULL, sizeof( AstBox ), !class_init, &class_vtab, - "Box", frame, form, point1, point2, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Box's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Box. */ - return new; -} - -AstBox *astBoxId_( void *frame_void, int form, const double point1[], - const double point2[], void *unc_void, const char *options, - ... ) { -/* -* Name: -* astBoxId_ - -* Purpose: -* Create a Box. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* AstBox *astBoxId_( AstFrame *frame, int form, const double point1[], -* const double point2[], AstRegion *unc, -* const char *options, ... ) - -* Class Membership: -* Box constructor. - -* Description: -* This function implements the external (public) interface to the -* astBox constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astBox_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astBox_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astBox_. - -* Returned Value: -* The ID value associated with the new Box. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstBox *new; /* Pointer to new Box */ - AstRegion *unc; /* Pointer to Region structure */ - va_list args; /* Variable argument list */ - - int *status; /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Frame pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Frame. */ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - -/* Obtain a Region pointer from the supplied "unc" ID and validate the - pointer to ensure it identifies a valid Region . */ - unc = unc_void ? astCheckRegion( astMakePointer( unc_void ) ) : NULL; - -/* Initialise the Box, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitBox( NULL, sizeof( AstBox ), !class_init, &class_vtab, - "Box", frame, form, point1, point2, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Box's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Box. */ - return astMakeId( new ); -} - -AstBox *astInitBox_( void *mem, size_t size, int init, AstBoxVtab *vtab, - const char *name, AstFrame *frame, int form, - const double point1[], const double point2[], - AstRegion *unc, int *status ) { -/* -*+ -* Name: -* astInitBox - -* Purpose: -* Initialise a Box. - -* Type: -* Protected function. - -* Synopsis: -* #include "box.h" -* AstBox *astInitBox_( void *mem, size_t size, int init, AstBoxVtab *vtab, -* const char *name, AstFrame *frame, int form, -* const double point1[], const double point2[], -* AstRegion *unc ) - -* Class Membership: -* Box initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Box object. It allocates memory (if necessary) to accommodate -* the Box plus any additional data associated with the derived class. -* It then initialises a Box structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Box at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Box is to be initialised. -* This must be of sufficient size to accommodate the Box data -* (sizeof(Box)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Box (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Box -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Box's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Box. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* A pointer to the Frame in which the region is defined. -* form -* Indicates how the box is described by the remaining parameters. -* A value of zero indicates that the box is specified by a centre -* position and a corner position. A value of one indicates that the -* box is specified by a two opposite corner positions. -* point1 -* An array of double, with one element for each Frame axis (Naxes -* attribute). If "form" is zero, this array should contain the -* coordinates at the centre of the box. If "form" is one, it should -* contain the coordinates at the corner of the box which is diagonally -* opposite the corner specified by "point2". -* point2 -* An array of double, with one element for each Frame axis (Naxes -* attribute) containing the coordinates at any of the corners of -* the box. -* unc -* A pointer to a Region which specifies the uncertainty in the -* supplied positions (all points on the boundary of the new Box -* being initialised are assumed to have the same uncertainty). A NULL -* pointer can be supplied, in which case default uncertainties equal to -* 1.0E-6 of the dimensions of the new Box's bounding box are used. -* If an uncertainty Region is supplied, it must be either a Box, a -* Circle or an Ellipse, and its encapsulated Frame must be related -* to the Frame supplied for parameter "frame" (i.e. astConvert -* should be able to find a Mapping between them). Two positions -* the "frame" Frame are considered to be co-incident if their -* uncertainty Regions overlap. The centre of the supplied -* uncertainty Region is immaterial since it will be re-centred on the -* point being tested before use. A deep copy is taken of the supplied -* Region. - -* Returned Value: -* A pointer to the new Box. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstBox *new; /* Pointer to new Box */ - AstPointSet *pset; /* PointSet to pass to Region initialiser */ - double **ptr; /* Pointer to coords data in pset */ - int i; /* axis index */ - int nc; /* No. of axes */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitBoxVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Get the number of axis values required for each position. */ - nc = astGetNaxes( frame ); - -/* Create a PointSet to hold the supplied values, and get points to the - data arrays. */ - pset = astPointSet( 2, nc, "", status ); - ptr = astGetPoints( pset ); - -/* Copy the supplied coordinates into the PointSet, checking that no bad - values have been supplied. */ - for( i = 0; astOK && i < nc; i++ ) { - if( point1[ i ] == AST__BAD ) { - astError( AST__BADIN, "astInitBox(%s): The value of axis %d is " - "undefined at point 1 of the box.", status, name, i + 1 ); - break; - } - if( point2[ i ] == AST__BAD ) { - astError( AST__BADIN, "astInitBox(%s): The value of axis %d is " - "undefined at point 2 of the box.", status, name, i + 1 ); - break; - } - ptr[ i ][ 0 ] = point1[ i ]; - ptr[ i ][ 1 ] = point2[ i ]; - } - -/* If two corners were supplied, find and store the centre. */ - if( form == 1 ) { - for( i = 0; i < nc; i++ ) { - ptr[ i ][ 0 ] = 0.5*( point1[ i ] + point2[ i ] ); - } - } - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Initialise a Region structure (the parent class) as the first component - within the Box structure, allocating memory if necessary. */ - new = (AstBox *) astInitRegion( mem, size, 0, (AstRegionVtab *) vtab, - name, frame, pset, unc ); - - if ( astOK ) { - -/* Initialise the Box data. */ -/* ------------------------ */ - new->extent = NULL; - new->centre = NULL; - new->lo = NULL; - new->hi = NULL; - new->geolen = NULL; - new->stale = 1; - -/* If an error occurred, clean up by deleting the new Box. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Free resources. */ - pset = astAnnul( pset ); - -/* Return a pointer to the new Box. */ - return new; -} - -AstBox *astLoadBox_( void *mem, size_t size, AstBoxVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadBox - -* Purpose: -* Load a Box. - -* Type: -* Protected function. - -* Synopsis: -* #include "box.h" -* AstBox *astLoadBox( void *mem, size_t size, AstBoxVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* Box loader. - -* Description: -* This function is provided to load a new Box using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Box structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Box at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the Box is to be -* loaded. This must be of sufficient size to accommodate the -* Box data (sizeof(Box)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Box (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Box structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstBox) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Box. If this is NULL, a pointer -* to the (static) virtual function table for the Box class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Box" is used instead. - -* Returned Value: -* A pointer to the new Box. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstBox *new; /* Pointer to the new Box */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Box. In this case the - Box belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstBox ); - vtab = &class_vtab; - name = "Box"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitBoxVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Box. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Box" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* There are no values to read. */ -/* ---------------------------- */ - -/* Initialise Box data */ - new->extent = NULL; - new->centre = NULL; - new->lo = NULL; - new->hi = NULL; - new->geolen = NULL; - new->stale = 1; - -/* If an error occurred, clean up by deleting the new Box. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Box pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - -void astBoxPoints_( AstBox *this, double *centre, double *corner, - int *status) { - if ( !astOK ) return; - (**astMEMBER(this,Box,BoxPoints))( this, centre, corner, status ); - return; -} - - - - - - - - - - - - - - - diff --git a/ast/box.h b/ast/box.h deleted file mode 100644 index 46dcf6c..0000000 --- a/ast/box.h +++ /dev/null @@ -1,234 +0,0 @@ -#if !defined( BOX_INCLUDED ) /* Include this file only once */ -#define BOX_INCLUDED -/* -*+ -* Name: -* box.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Box class. - -* Invocation: -* #include "box.h" - -* Description: -* This include file defines the interface to the Box class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The Box class implement a Region which represents a simple interval -* on each axis of the encapsulated Frame - -* Inheritance: -* The Box class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-MAR-2003 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "region.h" /* Coordinate regions (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* Box structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstBox { - -/* Attributes inherited from the parent class. */ - AstRegion region; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *extent; /* Original axis half-widths */ - double *centre; /* Box centre coords */ - double *lo; /* Low limits */ - double *hi; /* High limits */ - double *geolen; /* Geodesic half-dimensions of box */ - int stale; /* Is other info out of date? */ -} AstBox; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstBoxVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* BoxPoints)( AstBox *, double *, double *, int *); -} AstBoxVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstBoxGlobals { - AstBoxVtab Class_Vtab; - int Class_Init; -} AstBoxGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitBoxGlobals_( AstBoxGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Box) /* Check class membership */ -astPROTO_ISA(Box) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstBox *astBox_( void *, int, const double[], const double[], AstRegion *, const char *, int *, ...); -#else -AstBox *astBoxId_( void *, int, const double[], const double[], AstRegion *, const char *, ... )__attribute__((format(printf,6,7))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstBox *astInitBox_( void *, size_t, int, AstBoxVtab *, - const char *, AstFrame *, int, const double[], - const double[], AstRegion *, int * ); - -/* Vtab initialiser. */ -void astInitBoxVtab_( AstBoxVtab *, const char *, int * ); - -/* Loader. */ -AstBox *astLoadBox_( void *, size_t, AstBoxVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -void astBoxPoints_( AstBox *, double *, double *, int *); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckBox(this) astINVOKE_CHECK(Box,this,0) -#define astVerifyBox(this) astINVOKE_CHECK(Box,this,1) - -/* Test class membership. */ -#define astIsABox(this) astINVOKE_ISA(Box,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astBox astINVOKE(F,astBox_) -#else -#define astBox astINVOKE(F,astBoxId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitBox(mem,size,init,vtab,name,frame,form,p1,p2,unc) \ -astINVOKE(O,astInitBox_(mem,size,init,vtab,name,frame,form,p1,p2,unc,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitBoxVtab(vtab,name) astINVOKE(V,astInitBoxVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadBox(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadBox_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckBox to validate Box pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astBoxPoints(this,centre,corner) astINVOKE(V,astBoxPoints_(astCheckBox(this),centre,corner,STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/builddocs.in b/ast/builddocs.in deleted file mode 100644 index 5056ce0..0000000 --- a/ast/builddocs.in +++ /dev/null @@ -1,146 +0,0 @@ -#! /bin/sh - - -srcdir=. -perldir=`dirname @PERL@` -if test -z "$SST_DIR"; then - if test -x starconf.status; then - finder=`./starconf.status --show finder` - test -n "$finder" && prolat_path=`$finder --path prolat` - fi - if test -z "$prolat_path" -a -f $STARLINK/bin/sst/prolat; then - prolat_path=$STARLINK/bin/sst/prolat - fi - if test -z "$prolat_path"; then - # not all shells have the which builtin, but try anyway - prolat_path=`which prolat 2>/dev/null` - fi - if test -z "$prolat_path"; then - echo "SST_DIR isn't set, and can't find prolat" >&2 - exit 1 - fi - SST_DIR=`dirname $prolat_path` - export SST_DIR - echo "SST_DIR set to $SST_DIR" -fi -PATH="${srcdir}:${perldir}:${PATH}" -export PATH - -goodsource="${srcdir}/axis.c \ - ${srcdir}/box.c \ - ${srcdir}/channel.c \ - ${srcdir}/chebymap.c \ - ${srcdir}/circle.c \ - ${srcdir}/cmpframe.c \ - ${srcdir}/cmpmap.c \ - ${srcdir}/cmpregion.c \ - ${srcdir}/dsbspecframe.c \ - ${srcdir}/dssmap.c \ - ${srcdir}/ellipse.c \ - ${srcdir}/error.c \ - ${srcdir}/fchannel.c \ - ${srcdir}/fitschan.c \ - ${srcdir}/fitstable.c \ - ${srcdir}/fluxframe.c \ - ${srcdir}/frame.c \ - ${srcdir}/frameset.c \ - ${srcdir}/grismmap.c \ - ${srcdir}/interval.c \ - ${srcdir}/intramap.c \ - ${srcdir}/keymap.c \ - ${srcdir}/lutmap.c \ - ${srcdir}/mapping.c \ - ${srcdir}/mathmap.c \ - ${srcdir}/matrixmap.c \ - ${srcdir}/nullregion.c \ - ${srcdir}/object.c \ - ${srcdir}/pcdmap.c \ - ${srcdir}/permmap.c \ - ${srcdir}/plot.c \ - ${srcdir}/plot3d.c \ - ${srcdir}/pointlist.c \ - ${srcdir}/pointset.c \ - ${srcdir}/polygon.c \ - ${srcdir}/polymap.c \ - ${srcdir}/prism.c \ - ${srcdir}/normmap.c \ - ${srcdir}/ratemap.c \ - ${srcdir}/region.c \ - ${srcdir}/shiftmap.c \ - ${srcdir}/sphmap.c \ - ${srcdir}/skyaxis.c \ - ${srcdir}/skyframe.c \ - ${srcdir}/slamap.c \ - ${srcdir}/specframe.c \ - ${srcdir}/specfluxframe.c \ - ${srcdir}/specmap.c \ - ${srcdir}/stc.c \ - ${srcdir}/stcresourceprofile.c \ - ${srcdir}/stcsearchlocation.c \ - ${srcdir}/stccatalogentrylocation.c \ - ${srcdir}/stcobsdatalocation.c \ - ${srcdir}/stcschan.c \ - ${srcdir}/table.c \ - ${srcdir}/timeframe.c \ - ${srcdir}/timemap.c \ - ${srcdir}/tranmap.c \ - ${srcdir}/selectormap.c \ - ${srcdir}/switchmap.c \ - ${srcdir}/unitmap.c \ - ${srcdir}/unitnormmap.c \ - ${srcdir}/wcsmap.c \ - ${srcdir}/winmap.c \ - ${srcdir}/xmlchan.c \ - ${srcdir}/zoommap.c" - -goodsource="${goodsource} \ - ${srcdir}/ast_link \ - ${srcdir}/ast_link_adam" - -#chmod +x ${srcdir}/addcopyright -#chmod +x ${srcdir}/addlinks -#chmod +x ${srcdir}/addversion -#chmod +x ${srcdir}/doincludes -#chmod +x ${srcdir}/getatt -#chmod +x ${srcdir}/selectfc - -rm -f .sst.tmp - - getatt -class -f ${goodsource} >f_classes.tex - cat getatt.labels >global_f.labels; rm -f getatt.labels - getatt -class ${goodsource} >c_classes.tex - cat getatt.labels >global_c.labels; rm -f getatt.labels - getatt -att -f ${goodsource} >f_attribs.tex - cat getatt.labels >>global_f.labels; rm -f getatt.labels - getatt -att ${goodsource} >c_attribs.tex - cat getatt.labels >>global_c.labels; rm -f getatt.labels - getatt -f ${goodsource} >f_routines.tex - cat getatt.labels >>global_f.labels; rm -f getatt.labels - getatt ${goodsource} >c_routines.tex - cat getatt.labels >>global_c.labels; rm -f getatt.labels - - getatt memory.c > memory_routines.tex - cat getatt.labels >>global_c.labels; rm -f getatt.labels - - getatt -u -f ${goodsource} >f_commands.tex - cat getatt.labels >>global_f.labels; rm -f getatt.labels - getatt -u ${goodsource} >c_commands.tex - cat getatt.labels >>global_c.labels; rm -f getatt.labels - - ln -f global_f.labels global.labels - doincludes ${srcdir}/sun_master.tex \ - | selectfc -f | addlinks | addcopyright | addversion >sun210.tex - ln -f global_c.labels global.labels - doincludes ${srcdir}/sun_master.tex \ - | selectfc | addlinks | addcopyright | addversion >sun211.tex - - rm -f global.labels global_f.labels global_c.labels - rm -f c_attribs.tex c_classes.tex c_routines.tex c_commands.tex - rm -f f_attribs.tex f_classes.tex f_routines.tex f_commands.tex - rm -f memory_routines.tex - - - TEXINPUTS=@STARLINK@/share/latexsupport//:${TEXINPUTS} pdflatex -interaction=nonstopmode sun210 - TEXINPUTS=@STARLINK@/share/latexsupport//:${TEXINPUTS} pdflatex -interaction=nonstopmode sun210 - TEXINPUTS=@STARLINK@/share/latexsupport//:${TEXINPUTS} pdflatex -interaction=nonstopmode sun211 - TEXINPUTS=@STARLINK@/share/latexsupport//:${TEXINPUTS} pdflatex -interaction=nonstopmode sun211 - diff --git a/ast/buildhyperdocs b/ast/buildhyperdocs deleted file mode 100755 index 23a07e1..0000000 --- a/ast/buildhyperdocs +++ /dev/null @@ -1,11 +0,0 @@ - -chmod +x ${AST_REF}/addcopyright -copyright="`echo '' | ${AST_REF}/addcopyright`" - -rm -f -r sun210.htx sun211.htx -star2html -c "${copyright}" sun210 -star2html -c "${copyright}" sun211 - -export HTX_PATH -HTX_PATH=.:/star/docs:/star/help -hlink diff --git a/ast/c2f77.c b/ast/c2f77.c deleted file mode 100644 index 1801a55..0000000 --- a/ast/c2f77.c +++ /dev/null @@ -1,125 +0,0 @@ -/* -* Name: -* c2f77.c - -* Purpose: -* Implement the interface between the C and FORTRAN 77 languages. - -* Description: -* This file implements language-specific functions which support -* the FORTRAN 77 interface to the AST library. -* -* Note that this module is not a class implementation, although it -* resembles one. - -* Notes: -* - Some of the functions in this module are potentially platform -* dependent and may need to be re-implemented when porting the AST -* library to new platforms. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 15-NOV-1996 (RFWS): -* Original version (based on work by DSB and on code from the -* Starlink CNF library). -*/ - -/* Define the astCLASS macro (even although this is not a class - implementation) to obtain access to protected interfaces. */ -#define astCLASS - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "error.h" /* Error reporting facilities */ -#include "c2f77.h" /* Interface to this module */ - -/* Function implementations. */ -/* ========================= */ -void astStringExport_( const char *source_c, char *dest_f, int dest_len ) { -/* -*+ -* Name: -* astStringExport - -* Purpose: -* Export a C string to a FORTRAN string. - -* Type: -* Protected function. - -* Synopsis: -* #include "c2f77.h" -* void astStringExport( const char *source_c, char *dest_f, int dest_len ) - -* Description: -* This function creates a FORTRAN string from a C string, storing -* it in the supplied memory. If the C string is shorter than the -* space allocated for the FORTRAN string, then it is padded with -* blanks. If the C string is longer than the space allocated for -* the FORTRAN string, then the string is truncated. - -* Parameters: -* source_c -* A pointer to the input C string. -* dest_f -* A pointer to the output FORTRAN string. -* dest_len -* The length of the output FORTRAN string. - -* Notes: -* - This function is potentially platform-specific. For example, -* if FORTRAN strings were passed by descriptor, then the -* descriptor address would be passed as "dest_f" and this must -* then be used to locate the actual FORTRAN character data. -* - This function is described as protected but is in fact -* available through the public interface so that it may be used in -* constructing the FORTRAN 77 public interface. -* - This is the UNIX version of this function. -*- -*/ - -/* Local Variables:*/ - int i; /* Loop counter for characters */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Copy the characters of the input C string to the output FORTRAN - string, taking care not to go beyond the end of the FORTRAN - string.*/ - for ( i = 0; source_c[ i ] && ( i < dest_len ); i++ ) { - dest_f[ i ] = source_c[ i ]; - } - -/* Fill the rest of the output FORTRAN string with blanks. */ - for ( ; i < dest_len; i++ ) dest_f[ i ] = ' '; -} diff --git a/ast/c2f77.h b/ast/c2f77.h deleted file mode 100644 index c50edac..0000000 --- a/ast/c2f77.h +++ /dev/null @@ -1,166 +0,0 @@ -#if !defined( C2F77_INCLUDED ) /* Include this file only once */ -#define C2F77_INCLUDED -/* -*+ -* Name: -* c2f77.h - -* Purpose: -* Define the interface to the c2f77 module. - -* Description: -* This file defines language-specific functions which support the -* FORTRAN 77 interface to the AST library. -* -* Note that this module is not a class implementation, although it -* resembles one. - -* Functions Defined: -* Public: -* None. -* -* Protected: -* astStringExport -* Export a C string to a FORTRAN string. - -* Macros Defined: -* Public: -* None. -* -* Protected: -* astWatchSTATUS -* Execute C code while watching a FORTRAN STATUS variable. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 15-NOV-1996 (RFWS): -* Original version. -* 16-JUL-1997 (RFWS): -* Added astWatchSTATUS. -* 13-JUN-2001 (DSB): -* Make astStringExport available to F77 interface modules as well -* as AST classes. -*- -*/ - -/* Macros. */ -/* ======= */ -/* -*+ -* Name: -* astWatchSTATUS - -* Type: -* Protected macro. - -* Purpose: -* Execute C code while watching a FORTRAN STATUS variable. - -* Synopsis: -* #include "c2f77.h" -* astWatchSTATUS(code) - -* Description: -* This macro expands to code which executes the C code supplied -* via the "code" argument in a new C scope (delimited by -* {...}). The code supplied executes while the AST error status is -* equated to a variable called STATUS, which is an error status -* argument passed from a FORTRAN routine using the macros defined -* in the "f77.h" include file. -* -* The effect of this is roughly as if the astWatch function had -* been used to locally declare the FORTRAN STATUS argument as a -* new AST error status variable, except that this macro also works -* if STATUS is not an int. - -* Parameters: -* code -* The C code to be executed. - -* Examples: -* F77_SUBROUTINE(ast_doit)( INTEGER(STATUS) ) { -* astWatchSTATUS( -* astDoit(); -* ) -* } -* Causes the astDoit function to be invoked as if the AST error -* status were equated to the STATUS argument passed from -* FORTRAN. Typically, if STATUS is set to an error value, -* astDoit would detect this by means of the astOK macro and -* would not then execute. If an error occurs in astDoit, -* causing the AST error status to be set, then that value is -* transferred to STATUS after the C code has executed (i.e. at -* the end of the astWatchSTATUS macro). - -* Notes: -* - The FORTRAN argument must be called STATUS and must appear in -* the C function's parameter list as an argument of the INTEGER() -* macro defined in the "f77.h" include file. -* - The C code supplied executes in a new scope, in which -* automatic variables may be declared. However, such variables -* will not exist after the macro's expansion has been executed. -* - The AST error status variable and its value remain unchanged -* after the expansion of this macro has executed. -*- -*/ - -/* Define the macro. */ -#define astWatchSTATUS(code) \ -\ -/* Begin a new C scope. */ \ -{ \ -\ -/* Ensure that a pointer to the STATUS argument exists. */ \ - GENPTR_INTEGER(STATUS) \ -\ -/* Store the STATUS value in a local int. */ \ - int ast_local_status = *STATUS; \ - int *status = &ast_local_status; \ -\ -/* Make this int the AST error status variable, saving the address of \ - the previous variable. */ \ - int *ast_previous_status = astWatch( &ast_local_status ); \ -\ -/* Execute the code supplied using the new error status variable. */ \ - code \ -\ -/* Restore the original error status variable. */ \ - (void) astWatch( ast_previous_status ); \ -\ -/* Return the final error status to STATUS. */ \ - *STATUS = ast_local_status; \ -} - -/* Function prototypes. */ -/* ==================== */ -void astStringExport_( const char *, char *, int ); - -/* Function interfaces. */ -/* ==================== */ -/* These wrap up the functions defined by this module to make them - easier to use. */ -#define astStringExport astStringExport_ -#endif diff --git a/ast/cexpand b/ast/cexpand deleted file mode 100755 index b40957a..0000000 --- a/ast/cexpand +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/tcsh -#+ - -# Name: -# cexpand - -# Purpose: -# Expand a C source file using the C pre-processor and re-format it -# into a readable form. The output is written to a file with the same -# base-name as the input file, but with a file type of ".cpp". - -# Usage: -# % cexpand fred.c - -#- - -if( "$1" == "" ) then - echo "Usage: cexpand " - exit -endif - -set file = `basename $1 .c` -cpp -CC -P $file.c -DTHREAD_SAFE -DHAVE_CONFIG_H -I. -I.. -I/star/include > aaxx -indent aaxx -kr -o bbxx -cat bbxx | sed -e 's#/\*#\n/\*#g' > ccxx -cat ccxx | cexpand.pl > ddxx -indent ddxx -kr -o $file.cpp -rm aaxx bbxx ccxx ddxx - -echo "Output in $file.cpp" -echo "" - diff --git a/ast/cexpand.pl b/ast/cexpand.pl deleted file mode 100755 index 0795c04..0000000 --- a/ast/cexpand.pl +++ /dev/null @@ -1,22 +0,0 @@ -#!/star/Perl/bin/perl - while( $line = ) { - chomp( $line ); - if( $line =~ /^\/\*(.*)\*\/\s*$/ ) { - print "\n/*"; - $len = 0; - foreach $word ( split '\s+', $1 ) { - $len += length( $word ) + 1; - if( $len > 70 ) { - print "\n "; - $len = length( $word ) + 1; - } - print " $word"; - } - print " */\n"; - - } else { - print "$line\n"; - } - - } - diff --git a/ast/channel.c b/ast/channel.c deleted file mode 100644 index 9219502..0000000 --- a/ast/channel.c +++ /dev/null @@ -1,6458 +0,0 @@ -/* -*class++ -* Name: -* Channel - -* Purpose: -* Basic (textual) I/O channel. - -* Constructor Function: -c astChannel -f AST_CHANNEL - -* Description: -* The Channel class implements low-level input/output for the AST -* library. Writing an Object to a Channel will generate a textual -* representation of that Object, and reading from a Channel will -* create a new Object from its textual representation. -* -* Normally, when you use a Channel, you should provide "source" -c and "sink" functions which connect it to an external data store -f and "sink" routines which connect it to an external data store -* by reading and writing the resulting text. By default, however, -* a Channel will read from standard input and write to standard -* output. Alternatively, a Channel can be told to read or write from -* specific text files using the SinkFile and SourceFile attributes, -* in which case no sink or source function need be supplied. - -* Inheritance: -* The Channel class inherits from the Object class. - -* Attributes: -* In addition to those attributes common to all Objects, every -* Channel also has the following attributes: -* -* - Comment: Include textual comments in output? -* - Full: Set level of output detail -* - Indent: Indentation increment between objects -* - ReportLevel: Selects the level of error reporting -* - SinkFile: The path to a file to which the Channel should write -* - Skip: Skip irrelevant data? -* - SourceFile: The path to a file from which the Channel should read -* - Strict: Generate errors instead of warnings? - -* Functions: -c In addition to those functions applicable to all Objects, the -c following functions may also be applied to all Channels: -f In addition to those routines applicable to all Objects, the -f following routines may also be applied to all Channels: -* -c - astWarnings: Return warnings from the previous read or write -c - astPutChannelData: Store data to pass to source or sink functions -c - astRead: Read an Object from a Channel -c - astWrite: Write an Object to a Channel -f - AST_WARNINGS: Return warnings from the previous read or write -f - AST_READ: Read an Object from a Channel -f - AST_WRITE: Write an Object to a Channel - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 12-AUG-1996 (RFWS): -* Original version. -* 6-SEP-1996: -* Finished initial implementation. -* 11-DEC-1996 (RFWS): -* Added support for foreign language source and sink functions. -* 28-APR-1997 (RFWS): -* Prevent "-0" being written (use "0" instead). -* 27-NOV-2002 (DSB): -* Added astWriteInvocations. -* 8-JAN-2003 (DSB): -* - Changed private InitVtab method to protected astInitChannelVtab -* method. -* - Modified to use protected Vtab initialisation methods when -* loading an Object. -* 1-NOV-2003 (DSB): -* Change the initialiser so that it accepts source and sink -* wrapper functions as arguments (for use by derived classes). -* 16-AUG-2006 (DSB): -* - Document non-destructive nature of unsuccessful astRead calls -* on a FitsChan. -* 3-OCT-2008 (DSB): -* Added "Strict" attribute. -* 11-DEC-2008 (DSB): -* Added astPutChannelData and astChannelData functions. -* 16-JAN-2009 (DSB): -* Added astAddWarning and astWarnings. -* 11-JUN-2009 (DSB): -* Enable astChannelData to be used from within astRead. -* 7-DEC-2009 (DSB): -* Added Indent attribute. -* 12-FEB-2010 (DSB): -* Represent AST__BAD externally using the string "". -* 23-JUN-2011 (DSB): -* Added attributes SinkFile and SourceFile. -* 2-OCT-2012 (DSB): -* Report an error if an Inf or NaN value is read from the external -* source. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Channel - -/* Define a string containing the maximum length of keywords used to - identify values in the external representation of data. This is - deliberately kept small so as to simplify integration with - standards such as FITS. */ -#define MAX_NAME "8" - -/* Max length of string returned by GetAttrib */ -#define GETATTRIB_BUFF_LEN 50 - -/* String used to represent AST__BAD externally. */ -#define BAD_STRING "" - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "channel.h" /* Interface definition for this class */ -#include "loader.h" /* Interface to the global loader */ -#include "keymap.h" /* Storing arbitrary data in an AST Object */ -#include "pointset.h" /* For AST__BAD */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->AstReadClassData_Msg = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->Items_Written = 0; \ - globals->Current_Indent = 0; \ - globals->Nest = -1; \ - globals->Nwrite_Invoc = 0; \ - globals->Object_Class = NULL; \ - globals->Values_List = NULL; \ - globals->Values_Class = NULL; \ - globals->Values_OK = NULL; \ - globals->End_Of_Object = NULL; \ - globals->Channel_Data = NULL; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Channel) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Channel,Class_Init) -#define class_vtab astGLOBAL(Channel,Class_Vtab) -#define astreadclassdata_msg astGLOBAL(Channel,AstReadClassData_Msg) -#define getattrib_buff astGLOBAL(Channel,GetAttrib_Buff) -#define items_written astGLOBAL(Channel,Items_Written) -#define current_indent astGLOBAL(Channel,Current_Indent) -#define nest astGLOBAL(Channel,Nest) -#define nwrite_invoc astGLOBAL(Channel,Nwrite_Invoc) -#define object_class astGLOBAL(Channel,Object_Class) -#define values_list astGLOBAL(Channel,Values_List) -#define values_class astGLOBAL(Channel,Values_Class) -#define values_ok astGLOBAL(Channel,Values_OK) -#define end_of_object astGLOBAL(Channel,End_Of_Object) -#define channel_data astGLOBAL(Channel,Channel_Data) - - - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -static pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX3 pthread_mutex_lock( &mutex3 ); -#define UNLOCK_MUTEX3 pthread_mutex_unlock( &mutex3 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Contextual error message reported in astReadClassData? */ -static int astreadclassdata_msg = 0; - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ GETATTRIB_BUFF_LEN + 1 ]; - -/* Count of the number of output items written since the last "Begin" - or "IsA" item. */ -static int items_written = 0; - -/* Amount of indentation to be applied to the next output item. */ -static int current_indent = 0; - -/* Nesting level, used to keep track of data associated with building - Objects when they contain other Objects. */ -static int nest = -1; - -/* The number of times astWrite has been invoked. */ -static int nwrite_invoc = 0; - -/* Pointer to a user-supplied block of memory to be made available to - source or sink functions via the astChannelData function. */ -static void *channel_data = NULL; - -/*** - The following items are all pointers to dynamically allocated - arrays (stacks) that grow as necessary to accommodate one element - for each level of nesting (one more than the value of "nest"). -***/ - -/* Stack of pointers to null-terminated character strings giving the - names of the classes of the Objects being built at each nesting - level. */ -static char **object_class = NULL; - -/* Stack of pointers to the elements designated as the "heads" of - circular, doubly linked lists of name-value associations. */ -static AstChannelValue **values_list = NULL; - -/* Stack of pointers to null-terminated character strings giving the - names of the classes for which the values held in the values lists - are intended. */ -static char **values_class = NULL; - -/* Stack of flags indicating whether the values held in the values - lists are intended for the class loaders currently executing to - build Objects at each nesting level. */ -static int *values_ok = NULL; - -/* Stack of flags indicating whether "End" items have been read for - the Objects being built at each nesting level. */ -static int *end_of_object = NULL; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstChannelVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 -#define LOCK_MUTEX3 -#define UNLOCK_MUTEX3 - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstChannel *astChannelForId_( const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), - const char *, int * ), - const char *, ... ); -AstChannel *astChannelId_( const char *(*)( void ), void (*)( const char * ), const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstObject *Read( AstChannel *, int * ); -static AstObject *ReadObject( AstChannel *, const char *, AstObject *, int * ); -static AstChannelValue *FreeValue( AstChannelValue *, int * ); -static AstChannelValue *LookupValue( const char *, int * ); -static AstKeyMap *Warnings( AstChannel *, int * ); -static char *GetNextText( AstChannel *, int * ); -static char *InputTextItem( AstChannel *, int * ); -static char *ReadString( AstChannel *, const char *, const char *, int * ); -static char *SourceWrap( const char *(*)( void ), int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static double ReadDouble( AstChannel *, const char *, double, int * ); -static int GetComment( AstChannel *, int * ); -static int GetFull( AstChannel *, int * ); -static int GetSkip( AstChannel *, int * ); -static int GetStrict( AstChannel *, int * ); -static int ReadInt( AstChannel *, const char *, int, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestComment( AstChannel *, int * ); -static int TestFull( AstChannel *, int * ); -static int TestSkip( AstChannel *, int * ); -static int TestStrict( AstChannel *, int * ); -static int Use( AstChannel *, int, int, int * ); -static int Write( AstChannel *, AstObject *, int * ); -static void AddWarning( AstChannel *, int, const char *, const char *, int * ); -static void AppendValue( AstChannelValue *, AstChannelValue **, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearComment( AstChannel *, int * ); -static void ClearFull( AstChannel *, int * ); -static void ClearSkip( AstChannel *, int * ); -static void ClearStrict( AstChannel *, int * ); -static void ClearValues( AstChannel *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void GetNextData( AstChannel *, int, char **, char **, int * ); -static void OutputTextItem( AstChannel *, const char *, int * ); -static void PutChannelData( AstChannel *, void *, int * ); -static void PutNextText( AstChannel *, const char *, int * ); -static void ReadClassData( AstChannel *, const char *, int * ); -static void RemoveValue( AstChannelValue *, AstChannelValue **, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetComment( AstChannel *, int, int * ); -static void SetFull( AstChannel *, int, int * ); -static void SetSkip( AstChannel *, int, int * ); -static void SetStrict( AstChannel *, int, int * ); -static void SinkWrap( void (*)( const char * ), const char *, int * ); -static void Unquote( AstChannel *, char *, int * ); -static void WriteBegin( AstChannel *, const char *, const char *, int * ); -static void WriteDouble( AstChannel *, const char *, int, int, double, const char *, int * ); -static void WriteEnd( AstChannel *, const char *, int * ); -static void WriteInt( AstChannel *, const char *, int, int, int, const char *, int * ); -static void WriteIsA( AstChannel *, const char *, const char *, int * ); -static void WriteObject( AstChannel *, const char *, int, int, AstObject *, const char *, int * ); -static void WriteString( AstChannel *, const char *, int, int, const char *, const char *, int * ); - -static int GetReportLevel( AstChannel *, int * ); -static int TestReportLevel( AstChannel *, int * ); -static void ClearReportLevel( AstChannel *, int * ); -static void SetReportLevel( AstChannel *, int, int * ); - -static int GetIndent( AstChannel *, int * ); -static int TestIndent( AstChannel *, int * ); -static void ClearIndent( AstChannel *, int * ); -static void SetIndent( AstChannel *, int, int * ); - -static const char *GetSourceFile( AstChannel *, int * ); -static int TestSourceFile( AstChannel *, int * ); -static void ClearSourceFile( AstChannel *, int * ); -static void SetSourceFile( AstChannel *, const char *, int * ); - -static const char *GetSinkFile( AstChannel *, int * ); -static int TestSinkFile( AstChannel *, int * ); -static void ClearSinkFile( AstChannel *, int * ); -static void SetSinkFile( AstChannel *, const char *, int * ); - -/* Member functions. */ -/* ================= */ -static void AddWarning( AstChannel *this, int level, const char *msg, - const char *method, int *status ) { -/* -*+ -* Name: -* astAddWarning - -* Purpose: -* Add a warning to a Channel. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astAddWarning( AstChannel *this, int level, const char *msg, -* const char *method, int status, ... ) - -* Class Membership: -* Channel method. - -* Description: -* This function stores a warning message inside a Channel. These -* messages can be retirieved using astWarnings. - -* Parameters: -* this -* Pointer to the Channel. -* level -* Ignore the warning if the ReportLevel attribute value is less -* than "level". -* msg -* The wanting message to store. It may contain printf format -* specifiers. If a NULL pointer is supplied, all warnings -* currently stored in the Channel are removed. -* method -* The method name. -* status -* Inherited status value. -* ... -* Extra values to substitute into the message string as -* replacements for the printf format specifiers. -*- - -* Note: The expansion of the printf format specifiers is done in the -* astAddWarning_ wrapper function. The AddWarning functions defined by -* each class receives the fully expanded message and does not have a -* variable argument list. The variable argument list is included in the -* above prologue in order to document the wrapper function. - -*/ - -/* Local Variables: */ - int i; /* Message index */ - char *a; /* Pointer to copy of message */ - -/* If a NULL pointer was supplied, free all warnings currently in the - Channel. Do this before checking the inherited status so that it works - even if an error has occurred. */ - if( !msg ) { - for( i = 0; i < this->nwarn; i++ ) { - (this->warnings)[ i ] = astFree( (this->warnings)[ i ] ); - } - this->warnings = astFree( this->warnings ); - this->nwarn = 0; - return; - } - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Only proceed if the message level is sufficiently important. */ - if( astGetReportLevel( this ) >= level ) { - -/* If we are being strict, issue an error rather than a warning. */ - if( astGetStrict( this ) ) { - if( astOK ) { - astError( AST__BADIN, "%s(%s): %s", status, method, - astGetClass( this ), msg ); - } - -/* Otherwise, we store a copy of the message in the Channel. */ - } else { - -/* Allocate memory and store a copy of th supplied string in it. */ - a = astStore( NULL, msg, strlen( msg ) + 1 ); - -/* Expand the array of warning pointers in ther Channel structure. */ - this->warnings = astGrow( this->warnings, this->nwarn + 1, - sizeof( char * ) ); - -/* If all is OK so far, store the new warning pointer, and increment the - number of warnings in the Channel. */ - if( astOK ) { - (this->warnings)[ (this->nwarn)++ ] = a; - -/* Otherwise, attempt to free the memory holding the copy of the warning. */ - } else { - a = astFree( a ); - } - } - } -} - -static void AppendValue( AstChannelValue *value, AstChannelValue **head, int *status ) { -/* -* Name: -* AppendValue - -* Purpose: -* Append a Value structure to a list. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* void AppendValue( AstChannelValue *value, AstChannelValue **head, int *status ) - -* Class Membership: -* Channel member function. - -* Description: -* This function appends a Value structure to a doubly linked -* circular list of such structures. The new list element is -* inserted just in front of the element occupying the "head of -* list" position (i.e. it becomes the new last element in the -* list). - -* Parameters: -* value -* Pointer to the new element. This must not already be in the -* list. -* head -* Address of a pointer to the element at the head of the list -* (this pointer should be NULL if the list is initially -* empty). This pointer will only be updated if a new element is -* being added to an empty list. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error chacking and does not -* generate errors. -*/ - -/* If the list is initially empty, the sole new element points at - itself. */ - if ( !*head ) { - value->flink = value; - value->blink = value; - -/* Update the list head to identify the new element. */ - *head = value; - -/* Otherwise, insert the new element in front of the element at the - head of the list. */ - } else { - value->flink = *head; - value->blink = ( *head )->blink; - ( *head )->blink = value; - value->blink->flink = value; - } -} - -void *astChannelData_( void ) { -/* -c++ -* Name: -* astChannelData - -* Purpose: -* Return a pointer to user-supplied data stored with a Channel. - -* Type: -* Public macro. - -* Synopsis: -* #include "channel.h" -* void *astChannelData - -* Class Membership: -* Channel macro. - -* Description: -* This macro is intended to be used within the source or sink -* functions associated with a Channel. It returns any pointer -* previously stored in the Channel (that is, the Channel that has -* invoked the source or sink function) using astPutChannelData. -* -* This mechanism is a thread-safe alternative to passing file -* descriptors, etc, via static global variables. - -* Returned Value: -* astChannelData -* The pointer previously stored with the Channel using -* astPutChannelData. A NULL pointer will be returned if no such -* pointer has been stored with the Channel. - -* Applicability: -* Channel -* This macro applies to all Channels. - -* Notes: -* - This routine is not available in the Fortran 77 interface to -* the AST library. -c-- -*/ - astDECLARE_GLOBALS - astGET_GLOBALS(NULL); - return channel_data; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Channel. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Channel member function (over-rides the astClearAttrib protected -* method inherited from the Object class). - -* Description: -* This function clears the value of a specified attribute for a -* Channel, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Channel. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstChannel *this; /* Pointer to the Channel structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Channel structure. */ - this = (AstChannel *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Comment. */ -/* -------- */ - if ( !strcmp( attrib, "comment" ) ) { - astClearComment( this ); - -/* Full. */ -/* ----- */ - } else if ( !strcmp( attrib, "full" ) ) { - astClearFull( this ); - -/* Indent. */ -/* ------- */ - } else if ( !strcmp( attrib, "indent" ) ) { - astClearIndent( this ); - -/* ReportLevel. */ -/* ------------ */ - } else if ( !strcmp( attrib, "reportlevel" ) ) { - astClearReportLevel( this ); - -/* Skip. */ -/* ----- */ - } else if ( !strcmp( attrib, "skip" ) ) { - astClearSkip( this ); - -/* SourceFile. */ -/* ----------- */ - } else if ( !strcmp( attrib, "sourcefile" ) ) { - astClearSourceFile( this ); - -/* SinkFile. */ -/* --------- */ - } else if ( !strcmp( attrib, "sinkfile" ) ) { - astClearSinkFile( this ); - -/* Strict. */ -/* ------- */ - } else if ( !strcmp( attrib, "strict" ) ) { - astClearStrict( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearValues( AstChannel *this, int *status ) { -/* -* Name: -* ClearValues - -* Purpose: -* Clear the current values list. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* void ClearValues( AstChannel *this, int *status ) - -* Class Membership: -* Channel member function. - -* Description: -* This function clears any (un-read) Value structures remaining in -* the current values list (i.e. at the current nesting level). It -* should be invoked after all required values have been read. -* -* If the values list has not been read, or if any remaining values -* are found (i.e. the list is not empty) then this indicates an -* unrecognised input class or an input value that has not been -* read by a class loader. This implies an error in the loader, or -* bad input data, so an error is reported. -* -* All resources used by any remaining Value structures are freed -* and the values list is left in an empty state. - -* Parameters: -* this -* Pointer to the Channel being read. This is only used for -* constructing error messages. It must not be NULL. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function attempts to execute even if the global error -* status is set on entry, although no further error report will be -* made if it subsequently fails under these circumstances. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstChannelValue **head; /* Address of pointer to values list */ - AstChannelValue *value; /* Pointer to value list element */ - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* If "values_class" is non-NULL, then the values list has previously - been filled with Values for a class. */ - if ( values_class[ nest ] ) { - -/* If "values_ok" is zero, however, then these Values have not yet - been read by a class loader. This must be due to a bad class name - associated with them or because the class data are not available in - the correct order. If we are using strict error reporting, then report - an error (unless the error status is already set). */ - if ( astGetStrict( this ) && !values_ok[ nest ] && astOK ) { - astError( AST__BADIN, - "astRead(%s): Invalid class structure in input data.", status, - astGetClass( this ) ); - astError( AST__BADIN, - "Class \"%s\" is invalid or out of order within a %s.", status, - values_class[ nest ], object_class[ nest ] ); - } - -/* Free the memory holding the class string. */ - values_class[ nest ] = astFree( values_class[ nest ] ); - } - -/* Reset the "values_ok" flag. */ - values_ok[ nest ] = 0; - -/* Now clear any Values remaining in the values list. Obtain the - address of the pointer to the head of this list (at the current - nesting level) and loop to remove Values from the list while it is - not empty. */ - head = values_list + nest; - while ( *head ) { - -/* Obtain a pointer to the first element. */ - value = *head; - -/* Issue a warning. */ - if ( value->is_object ) { - astAddWarning( this, 1, "The Object \"%s = <%s>\" was " - "not recognised as valid input.", "astRead", status, - value->name, astGetClass( value->ptr.object ) ); - } else { - astAddWarning( this, 1, "The value \"%s = %s\" was not " - "recognised as valid input.", "astRead", status, - value->name, value->ptr.string ); - } - -/* Remove the Value structure from the list (which updates the head of - list pointer) and free its resources. */ - RemoveValue( value, head, status ); - value = FreeValue( value, status ); - } -} - -static AstChannelValue *FreeValue( AstChannelValue *value, int *status ) { -/* -* Name: -* FreeValue - -* Purpose: -* Free a dynamically allocated Value structure. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* AstChannelValue *FreeValue( AstChannelValue *value, int *status ) - -* Class Membership: -* Channel member function. - -* Description: -* This function frees a dynamically allocated Value structure, -* releasing all resources used by it. The structure contents must -* have been correctly initialised. - -* Parameters: -* value -* Pointer to the Value structure to be freed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A NULL pointer is always returned. - -* Notes: -* - This function attempts to execute even if the global error -* status is set on entry, although no further error report will be -* made if it subsequently fails under these circumstances. -*/ - -/* Check that a non-NULL pointer has been supplied. */ - if ( value ) { - -/* If the "name" component has been allocated, then free it. */ - if ( value->name ) value->name = astFree( value->name ); - -/* If the "ptr" component identifies an Object, then annul the Object - pointer. */ - if ( value->is_object ) { - if ( value->ptr.object ) { - value->ptr.object = astAnnul( value->ptr.object ); - } - -/* Otherwise, if it identifies a string, then free the string. */ - } else { - if ( value->ptr.string ) { - value->ptr.string = astFree( value->ptr.string ); - } - } - -/* Free the Value structure itself. */ - value = astFree( value ); - } - -/* Return a NULL pointer. */ - return NULL; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Channel. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Channel member function (over-rides the protected astGetAttrib -* method inherited from the Object class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Channel, formatted as a character string. - -* Parameters: -* this -* Pointer to the Channel. -* attrib -* Pointer to a null terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Channel, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Channel. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstChannel *this; /* Pointer to the Channel structure */ - const char *result; /* Pointer value to return */ - int comment; /* Comment attribute value */ - int full; /* Full attribute value */ - int indent; /* Indent attribute value */ - int report_level; /* ReportLevel attribute value */ - int skip; /* Skip attribute value */ - int strict; /* Report errors insead of warnings? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Channel structure. */ - this = (AstChannel *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* Comment. */ -/* -------- */ - if ( !strcmp( attrib, "comment" ) ) { - comment = astGetComment( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", comment ); - result = getattrib_buff; - } - -/* Full. */ -/* ----- */ - } else if ( !strcmp( attrib, "full" ) ) { - full = astGetFull( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", full ); - result = getattrib_buff; - } - -/* Indent. */ -/* ------- */ - } else if ( !strcmp( attrib, "indent" ) ) { - indent = astGetIndent( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", indent ); - result = getattrib_buff; - } - -/* ReportLevel. */ -/* ------------ */ - } else if ( !strcmp( attrib, "reportlevel" ) ) { - report_level = astGetReportLevel( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", report_level ); - result = getattrib_buff; - } - -/* Skip. */ -/* ----- */ - } else if ( !strcmp( attrib, "skip" ) ) { - skip = astGetSkip( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", skip ); - result = getattrib_buff; - } - -/* SourceFile. */ -/* ----------- */ - } else if ( !strcmp( attrib, "sourcefile" ) ) { - result = astGetSourceFile( this ); - -/* SinkFile. */ -/* --------- */ - } else if ( !strcmp( attrib, "sinkfile" ) ) { - result = astGetSinkFile( this ); - -/* Strict. */ -/* ------- */ - } else if ( !strcmp( attrib, "strict" ) ) { - strict = astGetStrict( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", strict ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; - -} - -static void GetNextData( AstChannel *this, int skip, char **name, - char **val, int *status ) { -/* -*+ -* Name: -* astGetNextData - -* Purpose: -* Read the next item of data from a data source. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astGetNextData( AstChannel *this, int skip, char **name, -* char **val ) - -* Class Membership: -* Channel method. - -* Description: -* This function reads the next item of input data from a data -* source associated with a Channel and returns the result. -* -* It is layered conceptually on the astGetNextText method, but -* instead of returning the raw input text, it decodes it and -* returns name/value pairs ready for use. Note that in some -* derived classes, where the data are not stored as text, this -* function may not actually use astGetNextText, but will access -* the data directly. - -* Parameters: -* this -* Pointer to the Channel. -* skip -* A non-zero value indicates that a new Object is to be read, -* and that all input data up to the next "Begin" item are to be -* skipped in order to locate it. This is useful if the data -* source contains AST objects interspersed with other data (but -* note that these other data cannot appear inside AST Objects, -* only between them). -* -* A zero value indicates that all input data are significant -* and the next item will therefore be read and an attempt made -* to interpret it whatever it contains. Any other data -* inter-mixed with AST Objects will then result in an error. -* name -* An address at which to store a pointer to a null-terminated -* dynamically allocated string containing the name of the next -* item in the input data stream. This name will be in lower -* case with no surrounding white space. It is the callers -* responsibilty to free the memory holding this string (using -* astFree) when it is no longer required. -* -* A NULL pointer value will be returned (without error) to -* indicate when there are no further input data items to be -* read. -* val -* An address at which to store a pointer to a null-terminated -* dynamically allocated string containing the value associated -* with the next item in the input data stream. No case -* conversion is performed on this string and all white space is -* potentially significant. It is the callers responsibilty to -* free the memory holding this string (using astFree) when it -* is no longer required. -* -* The returned pointer will be NULL if an Object data item is -* read (see the "Data Representation" section). - -* Data Representation: -* The returned data items fall into the following categories: -* -* - Begin: Identified by the name string "begin", this indicates -* the start of an Object definition. The associated value string -* gives the class name of the Object being defined. -* -* - IsA: Identified by the name string "isa", this indicates the -* end of the data associated with a particular class structure -* within the definiton of a larger Object. The associated value -* string gives the name of the class whose data have just been -* read. -* -* - End: Identified by the name string "end", this indicates the -* end of the data associated with a complete Object -* definition. The associated value string gives the class name of -* the Object whose definition is being ended. -* -* - Non-Object: Identified by any other name string plus a -* non-NULL "val" pointer, this gives the value of a non-Object -* structure component (instance variable). The name identifies -* which instance variable it is (within the context of the class -* whose data are being read) and the value is encoded as a string. -* -* - Object: Identified by any other name string plus a NULL "val" -* pointer, this identifies the value of an Object structure -* component (instance variable). The name identifies which -* instance variable it is (within the context of the class whose -* data are being read) and the value is given by subsequent data -* items (so the next item should be a "Begin" item). - -* Notes: -* - NULL pointer values will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -* - This method is provided primarily so that derived classes may -* over-ride it in order to read from alternative data sources. It -* provides a higher-level interface than astGetNextText, so is -* suitable for classes that either need to read textual data in a -* different format, or to read from non-textual data sources. -*- -*/ - -/* Local Variables: */ - char *line; /* Pointer to input text line */ - int done; /* Data item read? */ - int i; /* Loop counter for string characters */ - int len; /* Length of input text line */ - int nc1; /* Offset to start of first field */ - int nc2; /* Offset to end of first field */ - int nc3; /* Offset to start of second field */ - int nc; /* Number of charaters read by "astSscanf" */ - -/* Initialise the returned values. */ - *name = NULL; - *val = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Read the next input line as text (the loop is needed to allow - initial lines to be skipped if the "skip" flag is set). */ - done = 0; - while ( !done && ( line = InputTextItem( this, status ) ) && astOK ) { - -/* If OK, determine the line length. */ - len = strlen( line ); - -/* Non-Object value. */ -/* ----------------- */ -/* Test for lines of the form " name = value" (or similar), where the - name is no more than MAX_NAME characters long (the presence of a - value on the right hand side indicates that this is a non-Object - value, encoded as a string). Ignore these lines if the "skip" flag - is set. */ - if ( nc = 0, - ( !skip - && ( 0 == astSscanf( line, - " %n%*" MAX_NAME "[^ \t=]%n = %n%*[^\n]%n", - &nc1, &nc2, &nc3, &nc ) ) - && ( nc >= len ) ) ) { - -/* Note we have found a data item. */ - done = 1; - -/* Extract the name and value fields. */ - *name = astString( line + nc1, nc2 - nc1 ); - *val = astString( line + nc3, len - nc3 ); - -/* If OK, truncate the value to remove any trailing white space. */ - if ( astOK ) { - i = len - nc3 - 1; - while ( ( i >= 0 ) && isspace( ( *val )[ i ] ) ) i--; - ( *val )[ i + 1 ] = '\0'; - -/* Also remove any quotes from the string. */ - Unquote( this, *val, status ); - } - -/* Object value. */ -/* ------------- */ -/* Test for lines of the form " name = " (or similar), where the name - is no more than MAX_NAME characters long (the absence of a value on - the right hand side indicates that this is an Object, whose - definition follows on subsequent input lines). Ignore these lines - if the "skip" flag is set. */ - } else if ( nc = 0, - ( !skip - && ( 0 == astSscanf( line, - " %n%*" MAX_NAME "[^ \t=]%n = %n", - &nc1, &nc2, &nc ) ) - && ( nc >= len ) ) ) { - -/* Note we have found a data item. */ - done = 1; - -/* Extract the name field but leave the value pointer as NULL. */ - *name = astString( line + nc1, nc2 - nc1 ); - -/* Begin. */ -/* ------ */ -/* Test for lines of the form " Begin Class " (or similar). */ - } else if ( nc = 0, - ( ( 0 == astSscanf( line, - " %*1[Bb]%*1[Ee]%*1[Gg]%*1[Ii]%*1[Nn] %n%*s%n %n", - &nc1, &nc2, &nc ) ) - && ( nc >= len ) ) ) { - -/* Note we have found a data item. */ - done = 1; - -/* Set the returned name to "begin" and extract the associated class - name for the value. Store both of these in dynamically allocated - strings. */ - *name = astString( "begin", 5 ); - *val = astString( line + nc1, nc2 - nc1 ); - -/* IsA. */ -/* ---- */ -/* Test for lines of the form " IsA Class " (or similar). Ignore these - lies if the "skip" flag is set. */ - } else if ( nc = 0, - ( !skip - && ( 0 == astSscanf( line, - " %*1[Ii]%*1[Ss]%*1[Aa] %n%*s%n %n", - &nc1, &nc2, &nc ) ) - && ( nc >= len ) ) ) { - -/* Note we have found a data item. */ - done = 1; - -/* Set the returned name to "isa" and extract the associated class - name for the value. */ - *name = astString( "isa", 3 ); - *val = astString( line + nc1, nc2 - nc1 ); - -/* End. */ -/* ---- */ -/* Test for lines of the form " End Class " (or similar). Ignore these - lines if the "skip" flag is set. */ - } else if ( nc = 0, - ( !skip - && ( 0 == astSscanf( line, - " %*1[Ee]%*1[Nn]%*1[Dd] %n%*s%n %n", - &nc1, &nc2, &nc ) ) - && ( nc >= len ) ) ) { - -/* Note we have found a data item. */ - done = 1; - -/* If found, set the returned name to "end" and extract the associated - class name for the value. */ - *name = astString( "end", 3 ); - *val = astString( line + nc1, nc2 - nc1 ); - -/* If the input line didn't match any of the above and the "skip" flag - is not set, then report an error. */ - } else if ( !skip ) { - astError( AST__BADIN, - "astRead(%s): Cannot interpret the input data: \"%s\".", status, - astGetClass( this ), line ); - } - -/* Free the memory holding the input data as text. */ - line = astFree( line ); - } - -/* If successful, convert the name to lower case. */ - if ( astOK && *name ) { - for ( i = 0; ( *name )[ i ]; i++ ) { - ( *name )[ i ] = tolower( ( *name )[ i ] ); - } - } - -/* If an error occurred, ensure that any memory allocated is freed and - that NULL pointer values are returned. */ - if ( !astOK ) { - *name = astFree( *name ); - *val = astFree( *val ); - } -} - -static char *GetNextText( AstChannel *this, int *status ) { -/* -*+ -* Name: -* GetNextText - -* Purpose: -* Read the next line of input text from a data source. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* char *astGetNextText( AstChannel *this ) - -* Class Membership: -* Channel method. - -* Description: -* This function reads the next "raw" input line of text from the -* data source associated with a Channel. -* -* Each line is returned as a pointer to a null-terminated string -* held in dynamic memory, and it is the caller's responsibility to -* free this memory (using astFree) when it is no longer -* required. A NULL pointer is returned if there are no more input -* lines to be read. - -* Parameters: -* this -* Pointer to the Channel. - -* Returned Value: -* Pointer to a null-terminated string containing the input line -* (held in dynamically allocated memory, which must be freed by -* the caller when no longer required). A NULL pointer is returned -* if there are no more input lines to be read. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -* - This method is provided primarily so that derived classes may -* over-ride it in order to read from alternative (textual) data -* sources. -*- -*/ - -/* Local Constants: */ -#define MIN_CHARS 81 /* Initial size for allocating memory */ -#define ERRBUF_LEN 80 - -/* Local Variables: */ - FILE *fd; /* Input file descriptor */ - char *errstat; /* Pointer for system error message */ - char *line; /* Pointer to line data to be returned */ - char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */ - const char *sink_file; /* Path to output sink file */ - const char *source_file; /* Path to source file */ - int c; /* Input character */ - int len; /* Length of input line */ - int readstat; /* "errno" value set by "getchar" */ - int size; /* Size of allocated memory */ - -/* Initialise. */ - line = NULL; - -/* Check the global error status. */ - if ( !astOK ) return line; - -/* If the SourceFile attribute of the Channel specifies an input file, - but no input file has yet been opened, open it now. Report an error if - it is the same as the sink file. */ - if( astTestSourceFile( this ) && !this->fd_in ) { - source_file = astGetSourceFile( this ); - - if( this->fd_out ) { - sink_file = astGetSinkFile( this ); - if( astOK && !strcmp( sink_file, source_file ) ) { - astError( AST__RDERR, "astRead(%s): Failed to open input " - "SourceFile '%s' - the file is currently being used " - "as the output SinkFile.", status, astGetClass( this ), - source_file ); - } - } - - if( astOK ) { - this->fd_in = fopen( source_file, "r" ); - if( !this->fd_in ) { - if ( errno ) { -#if HAVE_STRERROR_R - strerror_r( errno, errbuf, ERRBUF_LEN ); - errstat = errbuf; -#else - errstat = strerror( errno ); -#endif - astError( AST__RDERR, "astRead(%s): Failed to open input " - "SourceFile '%s' - %s.", status, astGetClass( this ), - source_file, errstat ); - } else { - astError( AST__RDERR, "astRead(%s): Failed to open input " - "SourceFile '%s'.", status, astGetClass( this ), - source_file ); - } - } - - } - } - -/* Source function defined, but no input file. */ -/* ------------------------------------------- */ -/* If no active input file descriptor is stored in the Channel, but - a source function (and its wrapper function) is defined for the - Channel, use the wrapper function to invoke the source function to - read a line of input text. This is returned in a dynamically - allocated string. */ - if ( !this->fd_in && this->source && this->source_wrap ) { - -/* About to call an externally supplied function which may not be - thread-safe, so lock a mutex first. Also store the channel data - pointer in a global variable so that it can be accessed in the source - function using macro astChannelData. */ - astStoreChannelData( this ); - LOCK_MUTEX3; - line = ( *this->source_wrap )( this->source, status ); - UNLOCK_MUTEX3; - -/* Input file defined, or no source function. */ -/* ------------------------------------------ */ -/* Read the line from the input file or from standard input. */ - } else if( astOK ) { - c = '\0'; - len = 0; - size = 0; - -/* Choose the file descriptor to use. */ - fd = this->fd_in ? this->fd_in : stdin; - -/* Loop to read input characters, saving any "errno" value that may be - set by "getchar" if an error occurs. Quit if an end of file (or - error) occurs or if a newline character is read. */ - while ( errno = 0, c = getc( fd ), readstat = errno, - ( c != EOF ) && ( c != '\n' ) ) { - -/* If no memory has yet been allocated to hold the line, allocate some - now, using MIN_CHARS as the initial line length. */ - if ( !line ) { - line = astMalloc( sizeof( char ) * (size_t) MIN_CHARS ); - size = MIN_CHARS; - -/* If memory has previously been allocated, extend it when necessary - to hold the new input character (plus a terminating null) and note - the new size. */ - } else if ( ( len + 2 ) > size ) { - line = astGrow( line, len + 2, sizeof( char ) ); - if ( !astOK ) break; - size = (int) astSizeOf( line ); - } - -/* Store the character just read. */ - line[ len++ ] = c; - } - -/* If the above loop completed without setting the global error - status, check the last character read and use "ferror" to see if a - read error occurred. If so, report the error, using the saved - "errno" value (but only if one was set). */ - if ( astOK && ( c == EOF ) && ferror( fd ) ) { - if ( readstat ) { -#if HAVE_STRERROR_R - strerror_r( readstat, errbuf, ERRBUF_LEN ); - errstat = errbuf; -#else - errstat = strerror( readstat ); -#endif - astError( AST__RDERR, - "astRead(%s): Read error on standard input - %s.", status, - astGetClass( this ), errstat ); - } else { - astError( AST__RDERR, - "astRead(%s): Read error on standard input.", status, - astGetClass( this ) ); - } - } - -/* If an empty line has been read, allocate memory to hold an empty - string. */ - if ( !line && ( c == '\n' ) ) { - line = astMalloc( sizeof( char ) ); - } - -/* If memory has been allocated and there has been no error, - null-terminate the string of input characters. */ - if ( line ) { - if ( astOK ) { - line[ len ] = '\0'; - -/* If there has been an error, free the allocated memory. */ - } else { - line = astFree( line ); - } - } - } - - -/* Return the result pointer. */ - return line; - -/* Undefine macros local to this function. */ -#undef MIN_CHARS -#undef ERRBUF_LEN -} - -static AstKeyMap *Warnings( AstChannel *this, int *status ){ -/* -*++ -* Name: -c astWarnings -f AST_WARNINGS - -* Purpose: -* Returns any warnings issued by the previous read or write operation. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "channel.h" -c AstKeyMap *astWarnings( AstChannel *this ) -f RESULT = AST_WARNINGS( THIS, STATUS ) - -* Class Membership: -* Channel member function. - -* Description: -* This function returns an AST KeyMap object holding the text of any -* warnings issued as a result of the previous invocation of the -c astRead or astWrite -f AST_READ or AST_WRITE -* function on the Channel. If no warnings were issued, a -c a NULL value -f AST__NULL -* will be returned. -* -* Such warnings are non-fatal and will not prevent the -* read or write operation succeeding. However, the converted object -* may not be identical to the original object in all respects. -* Differences which would usually be deemed as insignificant in most -* usual cases will generate a warning, whereas more significant -* differences will generate an error. -* -* The "Strict" attribute allows this warning facility to be switched -* off, so that a fatal error is always reported for any conversion -* error. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Channel. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astWarnings() -f AST_WARNINGS = INTEGER -* A pointer to the KeyMap holding the warning messages, or -c NULL -f AST__NULL -* if no warnings were issued during the previous read operation. - -* Applicability: -* Channel -* The basic Channel class generates a warning when ever an -* un-recognised item is encountered whilst reading an Object from -* an external data source. If Strict is zero (the default), then -* unexpected items in the Object description are simply ignored, -* and any remaining items are used to construct the returned -* Object. If Strict is non-zero, an error will be reported and a -* NULL Object pointer returned if any unexpected items are -* encountered. -* -* As AST continues to be developed, new attributes are added -* occasionally to selected classes. If an older version of AST is -* used to read external Object descriptions created by a more -* recent version of AST, then the Channel class will, by default, -* ignore the new attributes, using the remaining attributes to -* construct the Object. This is usually a good thing. However, -* since external Object descriptions are often stored in plain -* text, it is possible to edit them using a text editor. This -* gives rise to the possibility of genuine errors in the -* description due to finger-slips, typos, or simple -* mis-understanding. Such inappropriate attributes will be ignored -* if Strict is left at its default zero value. This will cause the -* mis-spelled attribute to revert to its default value, -* potentially causing subtle changes in the behaviour of -* application software. If such an effect is suspected, the Strict -* attribute can be set non-zero, resulting in the erroneous -* attribute being identified in an error message. -* FitsChan -* The returned KeyMap will contain warnings for all conditions -* listed in the Warnings attribute. -* XmlChan -* Reports conversion errors that result in what are usally -* insignificant changes. - -* Notes: -* - The returned KeyMap uses keys of the form "Warning_1", -* "Warning_2", etc. -* - A value of -c NULL will be returned if this function is invoked with the AST -c error status set, -f AST__NULL will be returned if this function is invoked with STATUS -f set to an error value, -* or if it should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstKeyMap *result; - char key[ 20 ]; - int i; - -/* Check the global status, and supplied keyword name. */ - result = NULL; - if( !astOK ) return result; - -/* Check there are some warnings to return. */ - if( this->nwarn && this->warnings ) { - -/* Create the KeyMap. */ - result = astKeyMap( "", status ); - -/* Loop round all warnings, adding them into the KeyMap. */ - for( i = 0; i < this->nwarn; i++ ){ - sprintf( key, "Warning_%d", i + 1 ); - astMapPut0C( result, key, (this->warnings)[ i ], " " ); - } - } - -/* Return the KeyMap. */ - return result; -} - -AstChannel *astInitChannel_( void *mem, size_t size, int init, - AstChannelVtab *vtab, const char *name, - const char *(* source)( void ), - char *(* source_wrap)( const char *(*)( void ), int * ), - void (* sink)( const char * ), - void (* sink_wrap)( void (*)( const char * ), - const char *, int * ), int *status ) { -/* -*+ -* Name: -* astInitChannel - -* Purpose: -* Initialise a Channel. - -* Type: -* Protected function. - -* Synopsis: -* #include "channel.h" -* AstChannel *astInitChannel( void *mem, size_t size, int init, -* AstChannelVtab *vtab, const char *name, -* const char *(* source)( void ), -* char *(* source_wrap)( const char *(*)( void ), int * ), -* void (* sink)( const char * ), -* void (* sink_wrap)( void (*)( const char * ), -* const char *, int * ) ) - -* Class Membership: -* Channel initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new Channel object. It allocates memory (if -* necessary) to accommodate the Channel plus any additional data -* associated with the derived class. It then initialises a -* Channel structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual -* function table for a Channel at the start of the memory passed -* via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Channel is to be -* initialised. This must be of sufficient size to accommodate -* the Channel data (sizeof(Channel)) plus any data used by the -* derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Channel (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Channel structure, so a valid value must be -* supplied even if not required for allocating memory. -* init -* A boolean flag indicating if the Channel's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Channel. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* source -* Pointer to a "source" function which will be used to obtain -* lines of input text. Generally, this will be obtained by -* casting a pointer to a source function which is compatible -* with the "source_wrap" wrapper function (below). The pointer -* should later be cast back to its original type by the -* "source_wrap" function before the function is invoked. -* -* If "source" is NULL, the Channel will read from standard -* input instead. -* source_wrap -* Pointer to a function which can be used to invoke the -* "source" function supplied (above). This wrapper function is -* necessary in order to hide variations in the nature of the -* source function, such as may arise when it is supplied by a -* foreign (non-C) language interface. -* -* The single parameter of the "source_wrap" function is a -* pointer to the "source" function, and it should cast this -* function pointer (as necessary) and invoke the function with -* appropriate arguments to obtain the next line of input -* text. The "source_wrap" function should then return a pointer -* to a dynamically allocated, null terminated string containing -* the text that was read. The string will be freed (using -* astFree) when no longer required and the "source_wrap" -* function need not concern itself with this. A NULL pointer -* should be returned if there is no more input to read. -* -* If "source_wrap" is NULL, the Channel will read from standard -* input instead. -* sink -* Pointer to a "sink" function which will be used to deliver -* lines of output text. Generally, this will be obtained by -* casting a pointer to a sink function which is compatible with -* the "sink_wrap" wrapper function (below). The pointer should -* later be cast back to its original type by the "sink_wrap" -* function before the function is invoked. -* -* If "sink" is NULL, the Channel will write to standard output -* instead. -* sink_wrap -* Pointer to a function which can be used to invoke the "sink" -* function supplied (above). This wrapper function is necessary -* in order to hide variations in the nature of the sink -* function, such as may arise when it is supplied by a foreign -* (non-C) language interface. -* -* The first parameter of the "sink_wrap" function is a pointer -* to the "sink" function, and the second parameter is a pointer -* to a const, null-terminated character string containing the -* text to be written. The "sink_wrap" function should cast the -* "sink" function pointer (as necessary) and invoke the -* function with appropriate arguments to deliver the line of -* output text. The "sink_wrap" function then returns void. -* -* If "sink_wrap" is NULL, the Channel will write to standard -* output instead. - -* Returned Value: -* A pointer to the new Channel. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstChannel *new; /* Pointer to new Channel */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitChannelVtab( vtab, name ); - -/* Initialise an Object structure (the parent class) as the first - component within the Channel structure, allocating memory if - necessary. */ - new = (AstChannel *) astInitObject( mem, size, 0, - (AstObjectVtab *) vtab, name ); - - if ( astOK ) { - -/* Initialise the Channel data. */ -/* ---------------------------- */ -/* Save the pointers to the source and sink functions and the wrapper - functions that invoke them. */ - new->source = source; - new->source_wrap = source_wrap; - new->sink = sink; - new->sink_wrap = sink_wrap; - -/* Indicate no input or output files have been associated with the - Channel. */ - new->fd_in = NULL; - new->fn_in = NULL; - new->fd_out = NULL; - new->fn_out = NULL; - -/* Set all attributes to their undefined values. */ - new->comment = -INT_MAX; - new->full = -INT_MAX; - new->indent = -INT_MAX; - new->report_level = -INT_MAX; - new->skip = -INT_MAX; - new->strict = -INT_MAX; - new->data = NULL; - new->warnings = NULL; - new->nwarn = 0; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -void astInitChannelVtab_( AstChannelVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitChannelVtab - -* Purpose: -* Initialise a virtual function table for a Channel. - -* Type: -* Protected function. - -* Synopsis: -* #include "channel.h" -* void astInitChannelVtab( AstChannelVtab *vtab, const char *name ) - -* Class Membership: -* Channel vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Channel class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitObjectVtab( (AstObjectVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAChannel) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstObjectVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->AddWarning = AddWarning; - vtab->ClearComment = ClearComment; - vtab->ClearFull = ClearFull; - vtab->ClearSkip = ClearSkip; - vtab->ClearStrict = ClearStrict; - vtab->GetComment = GetComment; - vtab->GetFull = GetFull; - vtab->GetNextData = GetNextData; - vtab->GetNextText = GetNextText; - vtab->GetSkip = GetSkip; - vtab->GetStrict = GetStrict; - vtab->Warnings = Warnings; - vtab->PutNextText = PutNextText; - vtab->Read = Read; - vtab->ReadClassData = ReadClassData; - vtab->ReadDouble = ReadDouble; - vtab->ReadInt = ReadInt; - vtab->ReadObject = ReadObject; - vtab->ReadString = ReadString; - vtab->SetComment = SetComment; - vtab->SetFull = SetFull; - vtab->SetSkip = SetSkip; - vtab->SetStrict = SetStrict; - vtab->TestComment = TestComment; - vtab->TestFull = TestFull; - vtab->TestSkip = TestSkip; - vtab->TestStrict = TestStrict; - vtab->Write = Write; - vtab->WriteBegin = WriteBegin; - vtab->WriteDouble = WriteDouble; - vtab->WriteEnd = WriteEnd; - vtab->WriteInt = WriteInt; - vtab->WriteIsA = WriteIsA; - vtab->WriteObject = WriteObject; - vtab->WriteString = WriteString; - vtab->PutChannelData = PutChannelData; - - vtab->ClearReportLevel = ClearReportLevel; - vtab->GetReportLevel = GetReportLevel; - vtab->SetReportLevel = SetReportLevel; - vtab->TestReportLevel = TestReportLevel; - - vtab->ClearIndent = ClearIndent; - vtab->GetIndent = GetIndent; - vtab->SetIndent = SetIndent; - vtab->TestIndent = TestIndent; - - vtab->ClearSourceFile = ClearSourceFile; - vtab->GetSourceFile = GetSourceFile; - vtab->SetSourceFile = SetSourceFile; - vtab->TestSourceFile = TestSourceFile; - - vtab->ClearSinkFile = ClearSinkFile; - vtab->GetSinkFile = GetSinkFile; - vtab->SetSinkFile = SetSinkFile; - vtab->TestSinkFile = TestSinkFile; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - -/* Declare the destructor and copy constructor. */ - astSetDelete( (AstObjectVtab *) vtab, Delete ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - -/* Declare the Dump function for this class. There is no destructor or - copy constructor. */ - astSetDump( vtab, Dump, "Channel", "Basic I/O Channel" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static char *InputTextItem( AstChannel *this, int *status ) { -/* -* Name: -* InputTextItem - -* Purpose: -* Read the next item from a data source as text. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* char *InputTextItem( AstChannel *this ) - -* Class Membership: -* Channel member function. - -* Description: -* This function reads the next input data item as text from the -* data source associated with a Channel. It is similar to the -* astGetNextText method (which it invokes), except that it strips -* off any comments along with leading and trailing white -* space. Input lines which are empty or do not contain significant -* characters (e.g. all comment) are skipped, so that only -* significant lines are returned. -* -* Each line is returned as a pointer to a null-terminated string -* held in dynamic memory, and it is the caller's responsibility to -* free this memory (using astFree) when it is no longer -* required. A NULL pointer is returned if there are no more input -* lines to be read. - -* Parameters: -* this -* Pointer to the Channel. - -* Returned Value: -* Pointer to a null-terminated string containing the input line -* (held in dynamically allocated memory, which must be freed by -* the caller when no longer required). A NULL pointer is returned -* if there are no more input lines to be read. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - char *line; /* Pointer to line data to be returned */ - int i; /* Loop counter for line characters */ - int j; /* Counter for characters */ - int len; /* Length of result line */ - int nonspace; /* Non-space character encountered? */ - int quoted; /* Character is inside quotes? */ - -/* Initialise. */ - line = NULL; - -/* Check the global error status. */ - if ( !astOK ) return line; - -/* Loop to read input lines until one is found which contains useful - characters or end of file is reached (or a read error occurs). */ - while ( !line && ( line = astGetNextText( this ) ) && astOK ) { - -/* Loop to remove comments and leading and trailing white space. */ - len = 0; - nonspace = 0; - quoted = 0; - for ( i = j = 0; line[ i ]; i++ ) { - -/* Note quote characters and ignore all text after the first unquoted - comment character. */ - if ( line[ i ] == '"' ) quoted = !quoted; - if ( ( line[ i ] == '#' ) && !quoted ) break; - -/* Note the first non-space character and ignore everything before - it. */ - if ( ( nonspace = nonspace || !isspace( line[ i ] ) ) ) { - -/* Move each character to its new position in the string. */ - line[ j++ ] = line[ i ]; - -/* Note the final length of the string (ignoring trailing spaces). */ - if ( !isspace( line[ i ] ) ) len = j; - } - } - -/* If the string is not empty, terminate it. */ - if ( len ) { - line[ len ] = '\0'; - -/* Otherwise, free the memory used for the string so that another - input line will be read. */ - } else { - line = astFree( line ); - } - } - -/* Return the result pointer. */ - return line; - -/* Undefine macros local to this function. */ -#undef MIN_CHARS -} - -static AstChannelValue *LookupValue( const char *name, int *status ) { -/* -* Name: -* LookupValue - -* Purpose: -* Look up a Value structure by name. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* AstChannelValue *LookupValue( const char *name ) - -* Class Membership: -* Channel member function. - -* Description: -* This function searches the current values list (i.e. at the -* current nesting level) to identify a Value structure with a -* specified name. If one is found, it is removed from the list and -* a pointer to it is returned. If no suitable Value can be found, -* a NULL pointer is returned instead. - -* Parameters: -* name -* Pointer to a constant null-terminated character string -* containing the name of the required Value. This must be in -* lower case with no surrounding white space. Note that names -* longer than NAME_MAX characters will not match any Value. - -* Returned value: -* Pointer to the required Value structure, or NULL if no suitable -* Value exists. - -* Notes: -* - The returned pointer refers to a dynamically allocated -* structure and it is the callers responsibility to free this when -* no longer required. The FreeValue function must be used for this -* purpose. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstChannelValue **head; /* Address of head of list pointer */ - AstChannelValue *result; /* Pointer value to return */ - AstChannelValue *value; /* Pointer to list element */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Check that the "values_ok" flag is set. If not, the Values in the - values list belong to a different class to that of the current - class loader, so we cannot return any Value. */ - if ( values_ok[ nest ] ) { - -/* Obtain the address of the current "head of list" pointer for the - values list (at the current nesting level). */ - head = values_list + nest; - -/* Obtain the head of list pointer itself and check the list is not - empty. */ - if ( ( value = *head ) ) { - -/* Loop to inspect each list element. */ - while ( 1 ) { - -/* If a name match is found, remove the element from the list, return - a pointer to it and quit searching. */ - if ( !strcmp( name, value->name ) ) { - RemoveValue( value, head, status ); - result = value; - break; - } - -/* Follow the list until we return to the head. */ - value = value->flink; - if ( value == *head ) break; - } - } - } - -/* Return the result. */ - return result; -} - -static void OutputTextItem( AstChannel *this, const char *line, int *status ) { -/* -* Name: -* OutputTextItem - -* Purpose: -* Output a data item formatted as text. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* void OutputTextItem( AstChannel *this, const char *line, int *status ) - -* Class Membership: -* Channel member function. - -* Description: -* This function outputs a data item formatted as a text string to -* a data sink associated with a Channel. It keeps track of the -* number of items written. - -* Parameters: -* this -* Pointer to the Channel. -* line -* Pointer to a constant null-terminated string containing the -* data item to be output (no newline character should be -* appended). -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Write out the line of text using the astPutNextText method (which - may be over-ridden). */ - astPutNextText( this, line ); - -/* If successful, increment the count of items written. */ - if ( astOK ) items_written++; -} - -static void PutChannelData( AstChannel *this, void *data, int *status ) { -/* -c++ -* Name: -* astPutChannelData - -* Purpose: -* Store arbitrary data to be passed to a source or sink function. - -* Type: -* Public function. - -* Synopsis: -* #include "channel.h" -* void astPutChannelData( AstChannel *this, void *data ) - -* Class Membership: -* Channel method. - -* Description: -* This function stores a supplied arbitrary pointer in the Channel. -* When a source or sink function is invoked by the Channel, the -* invoked function can use the astChannelData macro to retrieve the -* pointer. This provides a thread-safe alternative to passing file -* descriptors, etc, via global static variables. - -* Parameters: -* this -* Pointer to the Channel. -* data -* A pointer to be made available to the source and sink functions -* via the astChannelData macro. May be NULL. - -* Applicability: -* Channel -* All Channels have this function. - -* Notes: -* - This routine is not available in the Fortran 77 interface to -* the AST library. -c-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the pointer. */ - this->data = data; -} - -static void PutNextText( AstChannel *this, const char *line, int *status ) { -/* -*+ -* Name: -* astPutNextText - -* Purpose: -* Write a line of output text to a data sink. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astPutNextText( AstChannel *this, const char *line ) - -* Class Membership: -* Channel method. - -* Description: -* This function writes an output line of text to a data sink -* associated with a Channel. - -* Parameters: -* this -* Pointer to the Channel. -* line -* Pointer to a constant null-terminated string containing the -* line of output text to be written (no newline character -* should be appended). - -* Notes: -* - This method is provided primarily so that derived classes may -* over-ride it in order to write to alternative (textual) data -* sinks. -*- -*/ - -/* Local Constants: */ -#define ERRBUF_LEN 80 - -/* Local Variables: */ - char *errstat; /* Pointer for system error message */ - char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */ - const char *sink_file; /* Path to output sink file */ - const char *source_file; /* Path to output source file */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If the SinkFile attribute of the Channel specifies an output file, - but no output file has yet been opened, open it now. Report an error - if it is the same as the source file. */ - if( astTestSinkFile( this ) && !this->fd_out ) { - sink_file = astGetSinkFile( this ); - - if( this->fd_out ) { - source_file = astGetSourceFile( this ); - if( astOK && !strcmp( sink_file, source_file ) ) { - astError( AST__WRERR, "astWrite(%s): Failed to open output " - "SinkFile '%s' - the file is currently being used " - "as the input SourceFile.", status, astGetClass( this ), - sink_file ); - } - } - - if( astOK ) { - this->fd_out = fopen( sink_file, "w" ); - if( !this->fd_out ) { - if ( errno ) { -#if HAVE_STRERROR_R - strerror_r( errno, errbuf, ERRBUF_LEN ); - errstat = errbuf; -#else - errstat = strerror( errno ); -#endif - astError( AST__WRERR, "astWrite(%s): Failed to open output " - "SinkFile '%s' - %s.", status, astGetClass( this ), - sink_file, errstat ); - } else { - astError( AST__WRERR, "astWrite(%s): Failed to open output " - "SinkFile '%s'.", status, astGetClass( this ), - sink_file ); - } - } - } - } - -/* Check no error occurred above. */ - if( astOK ) { - -/* If an active output file descriptor is stored in the channel, write - the text to it, with a newline appended. */ - if( this->fd_out ) { - (void) fprintf( this->fd_out, "%s\n", line ); - -/* Otherwise, if a sink function (and its wrapper function) is defined for - the Channel, use the wrapper function to invoke the sink function to - output the text line. Since we are about to call an externally supplied - function which may not be thread-safe, lock a mutex first. Also store - the channel data pointer in a global variable so that it can be accessed - in the source function using macro astChannelData. */ - } else if ( this->sink && this->sink_wrap ) { - astStoreChannelData( this ); - LOCK_MUTEX2; - ( *this->sink_wrap )( *this->sink, line, status ); - UNLOCK_MUTEX2; - -/* Otherwise, simply write the text to standard output with a newline - appended. */ - } else { - (void) printf( "%s\n", line ); - } - } -} - -static AstObject *Read( AstChannel *this, int *status ) { -/* -*++ -* Name: -c astRead -f AST_READ - -* Purpose: -* Read an Object from a Channel. - -* Type: -* Public function. - -* Synopsis: -c #include "channel.h" -c AstObject *astRead( AstChannel *this ) -f RESULT = AST_READ( THIS, STATUS ) - -* Class Membership: -* Channel method. - -* Description: -* This function reads the next Object from a Channel and returns a -* pointer to the new Object. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Channel. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astRead() -f AST_READ = INTEGER -* A pointer to the new Object. The class to which this will -* belong is determined by the input data, so is not known in -* advance. - -* Applicability: -* FitsChan -c All successful use of astRead on a FitsChan is destructive, so that -f All successful use of AST_READ on a FitsChan is destructive, so that -* FITS header cards are consumed in the process of reading an Object, -* and are removed from the FitsChan (this deletion can be prevented -* for specific cards by calling the FitsChan -c astRetainFits function). -f AST_RETAINFITS routine). -* An unsuccessful call of -c astRead -f AST_READ -* (for instance, caused by the FitsChan not containing the necessary -* FITS headers cards needed to create an Object) results in the -* contents of the FitsChan being left unchanged. -* StcsChan -* The AST Object returned by a successful use of -c astRead -f AST_READ -* on an StcsChan, will be either a Region or a KeyMap, depending -* on the values of the StcsArea, StcsCoords and StcsProps -* attributes. See the documentation for these attributes for further -* information. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned, without -* error, if the Channel contains no further Objects to be read. -* - A null Object pointer will also be returned if this function -c is invoked with the AST error status set, or if it should fail -f is invoked with STATUS set to an error value, or if it should fail -* for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstLoaderType *loader; /* Pointer to loader for Object */ - AstObject *new; /* Pointer to new Object */ - char *class; /* Pointer to Object class name string */ - char *name; /* Pointer to data item name */ - int skip; /* Skip non-AST data? */ - int top; /* Reading top-level Object definition? */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Determine if we are reading a top-level (i.e. user-level) Object - definition, as opposed to the definition of an Object contained - within another Object. This is indicated by the current nesting - level. */ - top = ( nest == -1 ); - -/* If reading a top-level object, determine if data lying in between - Object definitions in the input data stream are to be skipped. */ - skip = ( top && astGetSkip( this ) ); - -/* Read the next input data item. If we are reading a top-level Object - definition, skip any unrelated data beforehand. Otherwise read the - data strictly as it comes (there should be no unrelated data - embedded within Object definitions themselves). */ - astGetNextData( this, skip, &name, &class ); - -/* If no suitable data item was found (and no error occurred), we have - reached the end of data. For a top-level Object a NULL Object - pointer is simply returned, but for a nested Object this indicates - that part of the Object definition is missing, so report an - error. */ - if ( astOK ) { - if ( !name ) { - if ( !top ) { - astError( AST__EOCHN, - "astRead(%s): End of input encountered while trying to " - "read an AST Object.", status, astGetClass( this ) ); - } - -/* If a data item was found, check it is a "Begin" item. If not, there - is a data item missing, so report an error and free all memory. */ - } else if ( strcmp( name, "begin" ) ) { - astError( AST__BADIN, - "astRead(%s): Missing \"Begin\" when expecting an Object.", status, - astGetClass( this ) ); - name = astFree( name ); - if ( class ) class = astFree( class ); - -/* If the required "Begin" item was found, free the memory used for the - name string. */ - } else { - name = astFree( name ); - -/* Use the associated class name to locate the loader for that - class. This function will then be used to build the Object. */ - loader = astGetLoader( class, status ); - -/* Extend all necessary stack arrays to accommodate entries for the - next nesting level (this allocates space if none has yet been - allocated). */ - end_of_object = astGrow( end_of_object, nest + 2, sizeof( int ) ); - object_class = astGrow( object_class, nest + 2, sizeof( char * ) ); - values_class = astGrow( values_class, nest + 2, sizeof( char * ) ); - values_list = astGrow( values_list, nest + 2, sizeof( AstChannelValue * ) ); - values_ok = astGrow( values_ok, nest + 2, sizeof( int ) ); - -/* If an error occurred, free the memory used by the class string, - which will not now be used. */ - if ( !astOK ) { - class = astFree( class ); - -/* Otherwise, increment the nesting level and initialise the new stack - elements for this new level. This includes clearing the - "end_of_object" flag so that ReadClassData can read more data, and - storing the class name of the object we are about to read. */ - } else { - nest++; - end_of_object[ nest ] = 0; - object_class[ nest ] = class; - values_class[ nest ] = NULL; - values_list[ nest ] = NULL; - values_ok[ nest ] = 0; - -/* Invoke the loader, which reads the Object definition from the input - data stream and builds the Object. Supply NULL/zero values to the - loader so that it will substitute values appropriate to its own - class. */ - new = (*loader)( NULL, (size_t) 0, NULL, NULL, this, status ); - -/* Clear the values list for the current nesting level. If the list - has not been read or any Values remain in it, an error will - result. */ - ClearValues( this, status ); - -/* If no error has yet occurred, check that the "end_of_object" flag - has been set. If not, the input data were not correctly terminated, - so report an error. */ - if ( astOK && !end_of_object[ nest ] ) { - astError( AST__BADIN, - "astRead(%s): Unexpected end of input (missing end " - "of %s).", status, - astGetClass( this ), object_class[ nest ] ); - } - -/* If an error occurred, report contextual information. Only do this - for top-level Objects to avoid multple messages. */ - if ( !astOK && top ) { - astError( astStatus, "Error while reading a %s from a %s.", status, - class, astGetClass( this ) ); - } - -/* Clear the Object's class string, freeing the associated memory - (note this is the memory allocated for the "class" string - earlier). */ - object_class[ nest ] = astFree( object_class[ nest ] ); - -/* Restore the previous nesting level. */ - nest--; - } - -/* Once the top-level Object has been built, free the memory used by - the stack arrays. */ - if ( top ) { - end_of_object = astFree( end_of_object ); - object_class = astFree( object_class ); - values_class = astFree( values_class ); - values_list = astFree( values_list ); - values_ok = astFree( values_ok ); - } - } - } - -/* If an error occurred, clean up by deleting the new Object and - return a NULL pointer. */ - if ( !astOK ) new = astDelete( new ); - -/* Return the pointer to the new Object. */ - return new; -} - -static void ReadClassData( AstChannel *this, const char *class, int *status ) { -/* -*+ -* Name: -* astReadClassData - -* Purpose: -* Read values from a data source for a class loader. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astReadClassData( AstChannel *this, const char *class ) - -* Class Membership: -* Channel method. - -* Description: -* This function reads the data for a class from the data source -* associated with a Channel, so as to provide values for -* initialising the instance variables of that class as part of -* building a complete Object. This function should be invoked by -* the loader for each class immediately before it attempts to read -* these values. -* -* The values read are placed into the current values list by this -* function. They may then be read from this list by the class -* loader making calls to astReadDouble, astReadInt, astReadObject -* and astReadString. The order in which values are read by the -* loader is unimportant (although using the same order for reading -* as for writing will usually be more efficient) and values are -* removed from the list as they are read. - -* Parameters: -* this -* Pointer to the Channel. -* class -* A pointer to a constant null-terminated string containing the -* name of the class whose loader is requesting the data (note -* this is not usually the same as the class name of the Object -* being built). This value allows the class structure of the -* input data to be validated. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstObject *object; /* Pointer to new Object */ - AstChannelValue *value; /* Pointer to Value structure */ - char *name; /* Pointer to data item name string */ - char *val; /* Pointer to data item value string */ - int done; /* All class data read? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* If the "values_ok" flag is set, this indicates that the values list - (at the current nesting level) has been filled by a previous - invocation of this function and has then been read by the - appropriate class loader. In this case, clear any entries which may - remain in the current values list. If any such entries are found, - they represent input data that were not read, so an error will - result. */ - if ( values_ok[ nest ] ) ClearValues( this, status ); - -/* If "values_class" is non-NULL, this indicates that the values list - (at the current nesting level) has been filled by a previous - invocation of this function, but that the values belong to a class - whose loader has not yet tried to read them. In this case, we must - continue to keep the values until they are needed, so we do not - read any more input data this time. */ - if ( values_class[ nest ] ) { - -/* If the class to which the previously saved values belong matches - the class we now want values for, set the "values_ok" flag. This - then allows the values to be accessed (by LookupValue). */ - values_ok[ nest ] = !strcmp( values_class[ nest ], class ); - -/* If the current values list is empty, we must read in values for the - next class that appears in the input data. However, first check - that the "end_of_object" flag has not been set. If it has, we have - already reached the end of this Object's data, so there is some - kind of problem with the order in which class loaders have been - invoked. This will probably never happen, but report an error if - necessary. */ - } else if ( end_of_object[ nest ] ) { - astError( AST__LDERR, - "astRead(%s): Invalid attempt to read further %s data " - "following an end of %s.", status, - astGetClass( this ), class, object_class[ nest ] ); - astError( AST__LDERR, - "Perhaps the wrong class loader has been invoked?" , status); - -/* If we need new values, loop to read input data items until the end - of the data for a class is reached. */ - } else { - done = 0; - while ( astOK && !done ) { - -/* Read the next input data item. */ - astGetNextData( this, 0, &name, &val ); - if ( astOK ) { - -/* Unexpected end of input. */ -/* ------------------------ */ -/* If no "name" value is returned, we have reached the end of the - input data stream without finding the required end of class - terminator, so report an error. */ - if ( !name ) { - astError( AST__EOCHN, - "astRead(%s): Unexpected end of input (missing end " - "of %s).", status, - astGetClass( this ), object_class[ nest ] ); - -/* "IsA" item. */ -/* ----------- */ -/* Otherwise, if an "IsA" item was read, it indicates the end of the - data for a class. Store the pointer to the name of this class in - "values_class" and note whether this is the class whose data we - wanted in "values_ok". If the data we have read do not belong to - the class we wanted, they will simply be kept until the right class - comes looking for them. */ - } else if ( !strcmp( name, "isa" ) ) { - values_class[ nest ] = val; - values_ok[ nest ] = !strcmp( val, class ); - -/* Free the memory holding the name string. */ - name = astFree( name ); - -/* Note we have finished reading class data. */ - done = 1; - -/* "End" item. */ -/* ----------- */ -/* If an "End" item was read, it indicates the end of the data both - for a class and for the current Object definition as a whole. Set - the "end_of_object" flag (for the current nesting level) which - prevents any further data being read for this Object. This flag is - also used (by Read) to check that an "End" item was actually - read. */ - } else if ( !strcmp( name, "end" ) ) { - end_of_object[ nest ] = 1; - -/* Check that the class name in the "End" item matches that of the - Object being built. If so, store the pointer to the name of this - class in "values_class" and note whether this is the class whose - data we wanted in "values_ok". If the data we have read do not - belong to the class we wanted, they will simply be kept until the - right class comes looking for them. */ - if ( !strcmp( val, object_class[ nest ] ) ) { - values_class[ nest ] = val; - values_ok[ nest ] = !strcmp( class, val ); - -/* If the "End" item contains the wrong class name (i.e. not matching - the corresponding "Begin" item), then report an error. */ - } else { - astError( AST__BADIN, - "astRead(%s): Bad class structure in input data.", status, - astGetClass( this ) ); - astError( AST__BADIN, - "End of %s read when expecting end of %s.", status, - val, object_class[ nest ] ); - -/* Free the memory used by the class string, which will not now be - used. */ - val = astFree( val ); - } - -/* Free the memory holding the name string. */ - name = astFree( name ); - -/* Note we have finished reading class data. */ - done = 1; - -/* String value. */ -/* ------------- */ -/* If any other name is obtained and "val" is not NULL, we have read a - non-Object value, encoded as a string. Allocate memory for a Value - structure to describe it. */ - } else if ( val ) { - value = astMalloc( sizeof( AstChannelValue ) ); - if ( astOK ) { - -/* Store pointers to the name and value string in the Value structure - and note this is not an Object value. */ - value->name = name; - value->ptr.string = val; - value->is_object = 0; - -/* Append the Value structure to the values list for the current - nesting level. */ - AppendValue( value, values_list + nest, status ); - -/* If an error occurred, free the memory holding the "name" and "val" - strings. */ - } else { - name = astFree( name ); - val = astFree( val ); - } - -/* Object value. */ -/* ------------- */ -/* If "val" is NULL, we have read an Object item, and the Object - definition should follow. Allocate memory for a Value structure to - describe it. */ - } else { - value = astMalloc( sizeof( AstChannelValue ) ); - -/* Invoke astRead to read the Object definition from subsequent data - items and to build the Object, returning a pointer to it. This will - result in recursive calls to the current function, but as these - will use higher nesting levels they will not interfere with the - current invocation. */ - astreadclassdata_msg = 0; - object = astRead( this ); - if ( astOK ) { - -/* Store pointers to the name and Object in the Value structure and - note this is an Object value. */ - value->name = name; - value->ptr.object = object; - value->is_object = 1; - -/* Append the Value structure to the values list for the current - nesting level. */ - AppendValue( value, values_list + nest, status ); - -/* If an error occurred, report a contextual error maessage and set - the "astreadclassdata_msg" flag (this prevents multiple messages if this function is - invoked recursively to deal with nested Objects). */ - } else { - if ( !astreadclassdata_msg ) { - astError( astStatus, - "Failed to read the \"%s\" Object value.", status, - name ); - astreadclassdata_msg = 1; - } - -/* Free the memory holding the "name" string and any Value structure - that was allocated. */ - name = astFree( name ); - value = astFree( value ); - } - } - } - } - } -} - -static double ReadDouble( AstChannel *this, const char *name, double def, int *status ) { -/* -*+ -* Name: -* astReadDouble - -* Purpose: -* Read a double value as part of loading a class. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* double astReadDouble( AstChannel *this, const char *name, double def ) - -* Class Membership: -* Channel method. - -* Description: -* This function searches the current values list of a Channel to -* identify a double value with a specified name. If such a value -* is found, it is returned, otherwise a default value is returned -* instead. -* -* This function should only be invoked from within the loader -* function associated with a class, in order to return a double -* value to be assigned to an instance variable. It must be -* preceded by a call to the astReadClassData function, which loads -* the values associated with the class into the current values -* list from the input data source. - -* Parameters: -* this -* Pointer to the Channel. -* name -* Pointer to a constant null-terminated character string -* containing the name of the required value. This must be in -* lower case with no surrounding white space. Note that names -* longer than 6 characters will not match any value. -* def -* If no suitable value can be found (e.g. it is absent from the -* data stream being read), then this value will be returned -* instead. - -* Returned Value: -* The required value, or the default if the value was not found. - -* Notes: -* - A value of 0.0 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstChannelValue *value; /* Pointer to required Value structure */ - double result; /* Value to be returned */ - int nc; /* Number of characters read by astSscanf */ - -/* Initialise. */ - result = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Search for a Value structure with the required name in the current - values list.*/ - value = LookupValue( name, status ); - if ( astOK ) { - -/* If a Value was found, check that it describes a string (as opposed - to an Object). */ - if ( value ) { - if ( !value->is_object ) { - -/* If so, then attempt to decode the string to give a double value, - checking that the entire string is read (and checking for the magic string - used to represent bad values). If this fails, then the wrong name has - probably been given, or the input data are corrupt, so report an error. */ - nc = 0; - if ( ( 0 == astSscanf( value->ptr.string, " " BAD_STRING " %n", - &nc ) ) - && ( nc >= (int) strlen( value->ptr.string ) ) ) { - result = AST__BAD; - - } else if ( !( ( 1 == astSscanf( value->ptr.string, " %lf %n", - &result, &nc ) ) - && ( nc >= (int) strlen( value->ptr.string ) ) ) ) { - astError( AST__BADIN, - "astRead(%s): The value \"%s = %s\" cannot " - "be read as a double precision floating point " - "number.", status, astGetClass( this ), - value->name, value->ptr.string ); - - } else if( !astISFINITE( result ) ) { - astError( AST__BADIN, - "astRead(%s): Illegal double precision floating " - "point value \"%s\" read for \"%s\".", status, - astGetClass( this ), value->ptr.string, value->name ); - - } - -/* Report a similar error if the Value does not describe a string. */ - } else { - astError( AST__BADIN, - "astRead(%s): The Object \"%s = <%s>\" cannot " - "be read as a double precision floating point number.", status, - astGetClass( this ), - value->name, astGetClass( value->ptr.object ) ); - } - -/* Free the Value structure and the resources it points at. */ - value = FreeValue( value, status ); - -/* If no suitable Value structure was found, then use the default - value instead. */ - } else { - result = def; - } - } - -/* Return the result. */ - return result; -} - -static int ReadInt( AstChannel *this, const char *name, int def, int *status ) { -/* -*+ -* Name: -* astReadInt - -* Purpose: -* Read an int value as part of loading a class. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* int astReadInt( AstChannel *this, const char *name, int def ) - -* Class Membership: -* Channel method. - -* Description: -* This function searches the current values list of a Channel to -* identify an int value with a specified name. If such a value is -* found, it is returned, otherwise a default value is returned -* instead. -* -* This function should only be invoked from within the loader -* function associated with a class, in order to return an int -* value to be assigned to an instance variable. It must be -* preceded by a call to the astReadClassData function, which loads -* the values associated with the class into the current values -* list from the input data source. - -* Parameters: -* this -* Pointer to the Channel. -* name -* Pointer to a constant null-terminated character string -* containing the name of the required value. This must be in -* lower case with no surrounding white space. Note that names -* longer than 6 characters will not match any value. -* def -* If no suitable value can be found (e.g. it is absent from the -* data stream being read), then this value will be returned -* instead. - -* Returned Value: -* The required value, or the default if the value was not found. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstChannelValue *value; /* Pointer to required Value structure */ - int nc; /* Number of characters read by astSscanf */ - int result; /* Value to be returned */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Search for a Value structure with the required name in the current - values list.*/ - value = LookupValue( name, status ); - if ( astOK ) { - -/* If a Value was found, check that it describes a string (as opposed - to an Object). */ - if ( value ) { - if ( !value->is_object ) { - -/* If so, then attempt to decode the string to give an int value, - checking that the entire string is read. If this fails, then the - wrong name has probably been given, or the input data are corrupt, - so report an error. */ - nc = 0; - if ( !( ( 1 == astSscanf( value->ptr.string, " %d %n", - &result, &nc ) ) - && ( nc >= (int) strlen( value->ptr.string ) ) ) ) { - astError( AST__BADIN, - "astRead(%s): The value \"%s = %s\" cannot " - "be read as an integer.", status, astGetClass( this ), - value->name, value->ptr.string ); - } - -/* Report a similar error if the Value does not describe a string. */ - } else { - astError( AST__BADIN, - "astRead(%s): The Object \"%s = <%s>\" cannot " - "be read as an integer.", status, astGetClass( this ), - value->name, astGetClass( value->ptr.object ) ); - } - -/* Free the Value structure and the resources it points at. */ - value = FreeValue( value, status ); - -/* If no suitable Value structure was found, then use the default - value instead. */ - } else { - result = def; - } - } - -/* Return the result. */ - return result; -} - -static AstObject *ReadObject( AstChannel *this, const char *name, - AstObject *def, int *status ) { -/* -*+ -* Name: -* astReadObject - -* Purpose: -* Read a (sub)Object as part of loading a class. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* AstObject *astReadObject( AstChannel *this, const char *name, -* AstObject *def ) - -* Class Membership: -* Channel method. - -* Description: -* This function searches the current values list of a Channel to -* identify an Object with a specified name. If such an Object is -* found, a pointer to it is returned, otherwise a default pointer -* is returned instead. -* -* This function should only be invoked from within the loader -* function associated with a class, in order to return an Object -* pointer value to be assigned to an instance variable. It must be -* preceded by a call to the astReadClassData function, which loads -* the values associated with the class into the current values -* list from the input data source. - -* Parameters: -* this -* Pointer to the Channel. -* name -* Pointer to a constant null-terminated character string -* containing the name of the required Object. This must be in -* lower case with no surrounding white space. Note that names -* longer than 6 characters will not match any Object. -* def -* If no suitable Object can be found (e.g. the Object is absent -* from the data stream being read), then a clone of this -* default Object pointer will be returned instead (or NULL if -* this default pointer is NULL). - -* Returned Value: -* A pointer to the Object, or a clone of the default pointer if -* the Object was not found. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstObject *result; /* Pointer value to return */ - AstChannelValue *value; /* Pointer to required Value structure */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Search for a Value structure with the required name in the current - values list.*/ - value = LookupValue( name, status ); - if ( astOK ) { - -/* If a Value was found, check that it describes an Object (as opposed to - a string). */ - if ( value ) { - if ( value->is_object ) { - -/* If so, then extract the Object pointer, replacing it with NULL. */ - result = value->ptr.object; - value->ptr.object = NULL; - -/* If the Value does not describe an Object, then the wrong name has - probably been given, or the input data are corrupt, so report an - error. */ - } else { - astError( AST__BADIN, - "astRead(%s): The value \"%s = %s\" cannot be " - "read as an Object.", status, astGetClass( this ), - value->name, value->ptr.string ); - } - -/* Free the Value structure and the resources it points at. */ - value = FreeValue( value, status ); - -/* If no suitable Value structure was found, clone the default - pointer, if given. */ - } else if ( def ) { - result = astClone( def ); - } - } - -/* Return the result. */ - return result; -} - -static char *ReadString( AstChannel *this, const char *name, - const char *def, int *status ) { -/* -*+ -* Name: -* astReadString - -* Purpose: -* Read a string value as part of loading a class. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* char *astReadString( AstChannel *this, const char *name, -* const char *def ) - -* Class Membership: -* Channel method. - -* Description: -* This function searches the current values list of a Channel to -* identify a string value with a specified name. If such a value -* is found, a pointer to the string is returned, otherwise a -* pointer to a copy of a default string is returned instead. -* -* This function should only be invoked from within the loader -* function associated with a class, in order to return a string -* pointer value to be assigned to an instance variable. It must be -* preceded by a call to the astReadClassData function, which loads -* the values associated with the class into the current values -* list from the input data source. - -* Parameters: -* this -* Pointer to the Channel. -* name -* Pointer to a constant null-terminated character string -* containing the name of the required value. This must be in -* lower case with no surrounding white space. Note that names -* longer than 6 characters will not match any value. -* def -* If no suitable string can be found (e.g. the value is absent -* from the data stream being read), then a dynamically -* allocated copy of the null-terminated string pointed at by -* "def" will be made, and a pointer to this copy will be -* returned instead (or NULL if this default pointer is NULL). - -* Returned Value: -* A pointer to a dynamically allocated null-terminated string -* containing the value required, or to a copy of the default -* string if the value was not found (or NULL if the "def" pointer -* was NULL). - -* Notes: -* - It is the caller's responsibility to arrange for the memory -* holding the returned string to be freed (using astFree) when it -* is no longer required. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstChannelValue *value; /* Pointer to required Value structure */ - char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Search for a Value structure with the required name in the current - values list.*/ - value = LookupValue( name, status ); - if ( astOK ) { - -/* If a Value was found, check that it describes a string (as opposed - to an Object). */ - if ( value ) { - if ( !value->is_object ) { - -/* If so, then extract the string pointer, replacing it with NULL. */ - result = value->ptr.string; - value->ptr.string = NULL; - -/* If the Value does not describe a string, then the wrong name has - probably been given, or the input data are corrupt, so report an - error. */ - } else { - astError( AST__BADIN, - "astRead(%s): The Object \"%s = <%s>\" cannot " - "be read as a string.", status, astGetClass( this ), - value->name, astGetClass( value->ptr.object ) ); - } - -/* Free the Value structure and the resources it points at. */ - value = FreeValue( value, status ); - -/* If no suitable Value structure was found, then make a dynamic copy - of the default string (if given) and return a pointer to this. */ - } else if ( def ) { - result = astStore( NULL, def, strlen( def ) + (size_t) 1 ); - } - } - -/* Return the result. */ - return result; -} - -static void RemoveValue( AstChannelValue *value, AstChannelValue **head, int *status ) { -/* -* Name: -* RemoveValue - -* Purpose: -* Remove a Value structure from a circular linked list. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* void RemoveValue( AstChannelValue *value, AstChannelValue **head, int *status ); - -* Class Membership: -* Channel member function. - -* Description: -* This function removes a Value structure from a doubly linked -* circular list of such structures. The "head of list" pointer is -* updated to point at the element following the one removed. - -* Parameters: -* value -* Pointer to the structure to be removed (note that this must -* actually be in the list, although this function does not -* check). -* head -* Address of a pointer to the element at the head of the -* list. This pointer will be updated to point at the list -* element that follows the one removed. If the list becomes -* empty, the pointer will be set to NULL. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error chacking and does not -* generate errors. -*/ - -/* Remove the Value structure from the list by re-establishing links - between the elements on either side of it. */ - value->blink->flink = value->flink; - value->flink->blink = value->blink; - -/* Update the head of list pointer to identify the following - element. */ - *head = value->flink; - -/* If the head of list identifies the removed element, then note that - the list is now empty. */ - if ( *head == value ) *head = NULL; - -/* Make the removed element point at itself. */ - value->flink = value; - value->blink = value; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Channel. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* Channel member function (over-rides the astSetAttrib protected -* method inherited from the Object class). - -* Description: -* This function assigns an attribute value for a Channel, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Channel. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstChannel *this; /* Pointer to the Channel structure */ - int comment; /* Comment attribute value */ - int full; /* Full attribute value */ - int indent; /* Indent attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by "astSscanf" */ - int report_level; /* Skip attribute value */ - int skip; /* Skip attribute value */ - int sourcefile; /* Offset of SourceFile string */ - int sinkfile; /* Offset of SinkFile string */ - int strict; /* Report errors instead of warnings? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Channel structure. */ - this = (AstChannel *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* Comment. */ -/* ---------*/ - if ( nc = 0, - ( 1 == astSscanf( setting, "comment= %d %n", &comment, &nc ) ) - && ( nc >= len ) ) { - astSetComment( this, comment ); - -/* Full. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "full= %d %n", &full, &nc ) ) - && ( nc >= len ) ) { - astSetFull( this, full ); - -/* Indent. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "indent= %d %n", &indent, &nc ) ) - && ( nc >= len ) ) { - astSetIndent( this, indent ); - -/* ReportLavel. */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "reportlevel= %d %n", &report_level, &nc ) ) - && ( nc >= len ) ) { - astSetReportLevel( this, report_level ); - -/* Skip. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "skip= %d %n", &skip, &nc ) ) - && ( nc >= len ) ) { - astSetSkip( this, skip ); - -/* SinkFile. */ -/* --------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "sinkfile=%n%*[^\n]%n", &sinkfile, &nc ) ) - && ( nc >= len ) ) { - astSetSinkFile( this, setting + sinkfile ); - -/* SourceFile. */ -/* ----------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "sourcefile=%n%*[^\n]%n", &sourcefile, &nc ) ) - && ( nc >= len ) ) { - astSetSourceFile( this, setting + sourcefile ); - -/* Strict. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "strict= %d %n", &strict, &nc ) ) - && ( nc >= len ) ) { - astSetStrict( this, strict ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SinkWrap( void (* sink)( const char * ), const char *line, int *status ) { -/* -* Name: -* SinkWrap - -* Purpose: -* Wrapper function to invoke a C Channel sink function. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* void SinkWrap( void (* sink)( const char * ), const char *line, int *status ) - -* Class Membership: -* Channel member function. - -* Description: -* This function invokes the sink function whose pointer is -* supplied in order to write an output line to an external data -* store. - -* Parameters: -* sink -* Pointer to a sink function, whose single parameter is a -* pointer to a const, null-terminated string containing the -* text to be written, and which returns void. This is the form -* of Channel sink function employed by the C language interface -* to the AST library. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the sink function. */ - ( *sink )( line ); -} - -static char *SourceWrap( const char *(* source)( void ), int *status ) { -/* -* Name: -* SourceWrap - -* Purpose: -* Wrapper function to invoke a C Channel source function. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* char *SourceWrap( const char *, int *status(* source)( void ) ) - -* Class Membership: -* Channel member function. - -* Description: -* This function invokes the source function whose pointer is -* supplied in order to read the next input line from an external -* data store. It then returns a pointer to a dynamic string -* containing a copy of the text that was read. - -* Parameters: -* source -* Pointer to a source function, with no parameters, that -* returns a pointer to a const, null-terminated string -* containing the text that it read. This is the form of Channel -* source function employed by the C language interface to the -* AST library. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated, null terminated string -* containing a copy of the text that was read. This string must be -* freed by the caller (using astFree) when no longer required. -* -* A NULL pointer will be returned if there is no more input text -* to read. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - char *result; /* Pointer value to return */ - const char *line; /* Pointer to input line */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the source function to read the next input line and return a - pointer to the resulting string. */ - line = ( *source )(); - -/* If a string was obtained, make a dynamic copy of it and save the - resulting pointer. */ - if ( line ) result = astString( line, (int) strlen( line ) ); - -/* Return the result. */ - return result; -} - -void astStoreChannelData_( AstChannel *this, int *status ) { -/* -*+ -* Name: -* astStoreChannelData - -* Purpose: -* Store the Channel's channel-data pointer in a thread-specific -* global variable. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* astStoreChannelData( AstChannel *this ) - -* Class Membership: -* Channel method. - -* Description: -* This function stores the Channel's channel-data pointer (if any) -* established by the previous call to astPutChannelData, in a -* thread-specific global variable from where the astChannelData macro -* can access it. - -* Parameters: -* this -* Pointer to the Channel. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Store the pointer int he global variable. */ - channel_data = this->data; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Channel. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Channel member function (over-rides the astTestAttrib protected -* method inherited from the Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Channel's attributes. - -* Parameters: -* this -* Pointer to the Channel. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstChannel *this; /* Pointer to the Channel structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Channel structure. */ - this = (AstChannel *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* Comment. */ -/* -------- */ - if ( !strcmp( attrib, "comment" ) ) { - result = astTestComment( this ); - -/* Full. */ -/* ----- */ - } else if ( !strcmp( attrib, "full" ) ) { - result = astTestFull( this ); - -/* Indent. */ -/* ------- */ - } else if ( !strcmp( attrib, "indent" ) ) { - result = astTestIndent( this ); - -/* ReportLevel. */ -/* ------------ */ - } else if ( !strcmp( attrib, "reportlevel" ) ) { - result = astTestReportLevel( this ); - -/* Skip. */ -/* ----- */ - } else if ( !strcmp( attrib, "skip" ) ) { - result = astTestSkip( this ); - -/* SourceFile. */ -/* ----------- */ - } else if ( !strcmp( attrib, "sourcefile" ) ) { - result = astTestSourceFile( this ); - -/* SinkFile. */ -/* ----------- */ - } else if ( !strcmp( attrib, "sinkfile" ) ) { - result = astTestSinkFile( this ); - -/* Strict. */ -/* ------- */ - } else if ( !strcmp( attrib, "strict" ) ) { - result = astTestStrict( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static void Unquote( AstChannel *this, char *str, int *status ) { -/* -* Name: -* Unquote - -* Purpose: -* Remove quotes from a (possibly) quoted string. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* void Unquote( AstChannel *this, char *str, int *status ) - -* Class Membership: -* Channel member function. - -* Description: -* This function removes one layer of quote characters (") from a -* string which is possibly quoted. Any quotes within quotes (which -* should have been doubled when the string was originally quoted) -* are also converted back to single quotes again. -* -* The quotes need not start or end at the ends of the string, and -* there may be any number of quoted sections within the string. No -* error results if the string does not contain any quotes at all -* (it is simply returned unchanged), but an error results if any -* unmatched quotes are found. - -* Parameters: -* this -* Pointer to a Channel. This is only used for constructing error -* messages and has no influence on the string processing. -* str -* Pointer to the null-terminated string to be processed. This -* is modified in place. The new string starts at the same -* location as the original but has a new null character -* appended if necessary (it will usually be shorter than the -* original). -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int i; /* Loop counter for "input" characters */ - int j; /* Counter for "output" characters */ - int quoted; /* Inside a quoted string? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Loop to inspect each character in the string. */ - quoted = 0; - for ( i = j = 0; str[ i ]; i++ ) { - -/* Non-quote characters are simply copied to their new location in the - string. */ - if ( str[ i ] != '"' ) { - str[ j++ ] = str[ i ]; - -/* If a quote character '"' is encountered and we are not already in a - quoted string, then note the start of a quoted string (and discard - the quote). */ - } else if ( !quoted ) { - quoted = 1; - -/* If a quote character is encountered inside a quoted string, then - check if the next character is also a quote. If so, convert this - double quote to a single one. */ - } else if ( str[ i + 1 ] == '"' ) { - str[ j++ ] = '"'; - i++; - -/* If a single quote character is encountered inside a quoted string, - then note the end of the quoted string (and discard the quote). */ - } else { - quoted = 0; - } - } - -/* Append a null to terminate the processed string. */ - str[ j ] = '\0'; - -/* If the "quoted" flag is still set, then there were unmatched - quotes, so report an error. */ - if ( quoted ) { - astError( AST__UNMQT, - "astRead(%s): Unmatched quotes in input data: %s.", status, - astGetClass( this ), str ); - } -} - -static int Use( AstChannel *this, int set, int helpful, int *status ) { -/* -* Name: -* Use - -* Purpose: -* Decide whether to write a value to a data sink. - -* Type: -* Private function. - -* Synopsis: -* #include "channel.h" -* int Use( AstChannel *this, int set, int helpful, int *status ) - -* Class Membership: -* Channel member function. - -* Description: -* This function decides whether a value supplied by a class "Dump" -* function, via a call to one of the astWrite... protected -* methods, should actually be written to the data sink associated -* with a Channel. -* -* This decision is based on the settings of the "set" and -* "helpful" flags supplied to the astWrite... method, plus the -* attribute settings of the Channel. - -* Parameters: -* this -* A pointer to the Channel. -* set -* The "set" flag supplied. -* helpful -* The "helpful" value supplied. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the value should be written out, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - int full; /* Full attribute value */ - int result; /* Result value to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* If "set" is non-zero, then so is the result ("set" values must - always be written out). */ - result = ( set != 0 ); - -/* Otherwise, obtain the value of the Channel's Full attribute. */ - if ( !set ) { - full = astGetFull( this ); - -/* If Full is positive, display all values, if zero, display only - "helpful" values, if negative, display no (un-"set") values. */ - if ( astOK ) result = ( ( helpful && ( full > -1 ) ) || ( full > 0 ) ); - } - -/* Return the result. */ - return result; -} - -static int Write( AstChannel *this, AstObject *object, int *status ) { -/* -*++ -* Name: -c astWrite -f AST_WRITE - -* Purpose: -* Write an Object to a Channel. - -* Type: -* Public function. - -* Synopsis: -c #include "channel.h" -c int astWrite( AstChannel *this, AstObject *object ) -f RESULT = AST_WRITE( THIS, OBJECT, STATUS ) - -* Class Membership: -* Channel method. - -* Description: -* This function writes an Object to a Channel, appending it to any -* previous Objects written to that Channel. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Channel. -c object -f OBJECT = INTEGER (Given) -* Pointer to the Object which is to be written. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astWrite() -f AST_WRITE = INTEGER -* The number of Objects written to the Channel by this -c invocation of astWrite (normally, this will be one). -f invocation of AST_WRITE (normally, this will be one). - -* Applicability: -* FitsChan -* If the FitsChan uses a foreign encoding (e.g. FITS-WCS) rather -* than the native AST encoding, then storing values in the -* FitsChan for keywords NAXIS1, NAXIS2, etc., before invoking -c astWrite -f AST_WRITE -* can help to produce a successful write. - -* Notes: -* - A value of zero will be returned if this function is invoked -c with the AST error status set, or if it should fail for any -f with STATUS set to an error value, or if it should fail for any -* reason. -* - Invoking this function will usually cause the sink function -* associated with the channel to be called in order to transfer a -* textual description of the supplied object to some external data -* store. However, the FitsChan class behaves differently. Invoking -* this function on a FitsChan causes new FITS header cards to be -* added to an internal buffer (the sink function is not invoked). -* This buffer is written out through the sink function only when the -* FitsChan is deleted. -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* The work of this function is actually performed by the protected - astDump method of the Object. The fact that this is further - encapsulated within the astWrite method (which belongs to the - Channel) is simply a trick to allow it to be over-ridden either by - a derived Channel, or a derived Object (or both), and hence to - adapt to the nature of either argument. */ - astDump( object, this ); - -/* Return the number of Objects written. */ - return astOK ? 1 : 0; -} - -static void WriteBegin( AstChannel *this, const char *class, - const char *comment, int *status ) { -/* -*+ -* Name: -* astWriteBegin - -* Purpose: -* Write a "Begin" data item to a data sink. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astWriteBegin( AstChannel *this, const char *class, -* const char *comment ) - -* Class Membership: -* Channel method. - -* Description: -* This function writes a "Begin" data item to the data sink -* associated with a Channel, so as to begin the output of a new -* Object definition. - -* Parameters: -* this -* Pointer to the Channel. -* class -* Pointer to a constant null-terminated string containing the -* name of the class to which the Object belongs. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the "Begin" -* item. Normally, this will describe the purpose of the Object. - -* Notes: -* - The comment supplied may not actually be used, depending on -* the nature of the Channel supplied. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *line; /* Pointer to dynamic output string */ - int i; /* Loop counter for indentation characters */ - int nc; /* Number of output characters */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Start building a dynamic string with an initial space. Then add - further spaces to suit the current indentation level. */ - line = astAppendString( NULL, &nc, " " ); - for ( i = 0; i < current_indent; i++ ) { - line = astAppendString( line, &nc, " " ); - } - -/* Append the "Begin" keyword followed by the class name. */ - line = astAppendString( line, &nc, "Begin " ); - line = astAppendString( line, &nc, class ); - -/* If required, also append the comment. */ - if ( astGetComment( this ) && *comment ) { - line = astAppendString( line, &nc, " \t# " ); - line = astAppendString( line, &nc, comment ); - } - -/* Write out the resulting line of text. */ - OutputTextItem( this, line, status ); - -/* Free the dynamic string. */ - line = astFree( line ); - -/* Increment the indentation level and clear the count of items written - for this Object. */ - current_indent += astGetIndent( this ); - items_written = 0; -} - -static void WriteDouble( AstChannel *this, const char *name, - int set, int helpful, - double value, const char *comment, int *status ) { -/* -*+ -* Name: -* astWriteDouble - -* Purpose: -* Write a double value to a data sink. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astWriteDouble( AstChannel *this, const char *name, -* int set, int helpful, -* double value, const char *comment ) - -* Class Membership: -* Channel method. - -* Description: -* This function writes a named double value, representing the -* value of a class instance variable, to the data sink associated -* with a Channel. It is intended for use by class "Dump" functions -* when writing out class information which will subsequently be -* re-read. - -* Parameters: -* this -* Pointer to the Channel. -* name -* Pointer to a constant null-terminated string containing the -* name to be used to identify the value in the external -* representation. This will form the key for identifying it -* again when it is re-read. The name supplied should be unique -* within its class. -* -* Mixed case may be used and will be preserved in the external -* representation (where possible) for cosmetic effect. However, -* case is not significant when re-reading values. -* -* It is recommended that a maximum of 6 alphanumeric characters -* (starting with an alphabetic character) be used. This permits -* maximum flexibility in adapting to standard external data -* representations (e.g. FITS). -* set -* If this is zero, it indicates that the value being written is -* a default value (or can be re-generated from other values) so -* need not necessarily be written out. Such values will -* typically be included in the external representation with -* (e.g.) a comment character so that they are available to -* human readers but will be ignored when re-read. They may also -* be completely omitted in some circumstances. -* -* If "set" is non-zero, the value will always be explicitly -* included in the external representation so that it can be -* re-read. -* helpful -* This flag provides a hint about whether a value whose "set" -* flag is zero (above) should actually appear at all in the -* external representaton. -* -* If the external representation allows values to be "commented -* out" then, by default, values will be included in this form -* only if their "helpful" flag is non-zero. Otherwise, they -* will be omitted entirely. When possible, omitting the more -* obscure values associated with a class is recommended in -* order to improve readability. -* -* This default behaviour may be further modified if the -* Channel's Full attribute is set - either to permit all values -* to be shown, or to suppress non-essential information -* entirely. -* value -* The value to be written. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the value. -* -* Note that this comment may not actually be used, depending on -* the nature of the Channel supplied and the setting of its -* Comment attribute. -*- -*/ - -/* Local Constants: */ -#define BUFF_LEN 100 /* Size of local formatting buffer */ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *line; /* Pointer to dynamic output string */ - char buff[ BUFF_LEN + 1 ]; /* Local formatting buffer */ - int i; /* Loop counter for indentation characters */ - int nc; /* Number of output characters */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Use the "set" and "helpful" flags, along with the Channel's - attributes to decide whether this value should actually be - written. */ - if ( Use( this, set, helpful, status ) ) { - -/* Start building a dynamic string with an initial space, or a comment - character if "set" is zero. Then add further spaces to suit the - current indentation level. */ - line = astAppendString( NULL, &nc, set ? " " : "#" ); - for ( i = 0; i < current_indent; i++ ) { - line = astAppendString( line, &nc, " " ); - } - -/* Append the name string followed by " = ". */ - line = astAppendString( line, &nc, name ); - line = astAppendString( line, &nc, " = " ); - -/* Format the value as a string and append this. Make sure "-0" isn't - produced. Use a magic string to represent bad values. */ - if( value != AST__BAD ) { - (void) sprintf( buff, "%.*g", AST__DBL_DIG, value ); - if ( !strcmp( buff, "-0" ) ) { - buff[ 0 ] = '0'; - buff[ 1 ] = '\0'; - } - } else { - strcpy( buff, BAD_STRING ); - } - line = astAppendString( line, &nc, buff ); - -/* If required, also append the comment. */ - if ( astGetComment( this ) && *comment ) { - line = astAppendString( line, &nc, " \t# " ); - line = astAppendString( line, &nc, comment ); - } - -/* Write out the resulting line of text. */ - OutputTextItem( this, line, status ); - -/* Free the dynamic string. */ - line = astFree( line ); - } - -/* Undefine macros local to this function. */ -#undef BUFF_LEN -} - -static void WriteEnd( AstChannel *this, const char *class, int *status ) { -/* -*+ -* Name: -* astWriteEnd - -* Purpose: -* Write an "End" data item to a data sink. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astWriteEnd( AstChannel *this, const char *class ) - -* Class Membership: -* Channel method. - -* Description: -* This function writes an "End" data item to the data sink -* associated with a Channel. This item delimits the end of an -* Object definition. - -* Parameters: -* this -* Pointer to the Channel. -* class -* Pointer to a constant null-terminated string containing the -* class name of the Object whose definition is being terminated -* by the "End" item. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *line; /* Pointer to dynamic output string */ - int i; /* Loop counter for indentation characters */ - int nc; /* Number of output characters */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Decrement the indentation level so that the "End" item matches the - corresponding "Begin" item. */ - current_indent -= astGetIndent( this ); - -/* Start building a dynamic string with an initial space. Then add - further spaces to suit the current indentation level. */ - line = astAppendString( NULL, &nc, " " ); - for ( i = 0; i < current_indent; i++ ) { - line = astAppendString( line, &nc, " " ); - } - -/* Append the "End" keyword followed by the class name. */ - line = astAppendString( line, &nc, "End " ); - line = astAppendString( line, &nc, class ); - -/* Write out the resulting line of text. */ - OutputTextItem( this, line, status ); - -/* Free the dynamic string. */ - line = astFree( line ); -} - -static void WriteInt( AstChannel *this, const char *name, int set, int helpful, - int value, const char *comment, int *status ) { -/* -*+ -* Name: -* astWriteInt - -* Purpose: -* Write an integer value to a data sink. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astWriteInt( AstChannel *this, const char *name, -* int set, int helpful, -* int value, const char *comment ) - -* Class Membership: -* Channel method. - -* Description: -* This function writes a named integer value, representing the -* value of a class instance variable, to the data sink associated -* with a Channel. It is intended for use by class "Dump" functions -* when writing out class information which will subsequently be -* re-read. - -* Parameters: -* this -* Pointer to the Channel. -* name -* Pointer to a constant null-terminated string containing the -* name to be used to identify the value in the external -* representation. This will form the key for identifying it -* again when it is re-read. The name supplied should be unique -* within its class. -* -* Mixed case may be used and will be preserved in the external -* representation (where possible) for cosmetic effect. However, -* case is not significant when re-reading values. -* -* It is recommended that a maximum of 6 alphanumeric characters -* (starting with an alphabetic character) be used. This permits -* maximum flexibility in adapting to standard external data -* representations (e.g. FITS). -* set -* If this is zero, it indicates that the value being written is -* a default value (or can be re-generated from other values) so -* need not necessarily be written out. Such values will -* typically be included in the external representation with -* (e.g.) a comment character so that they are available to -* human readers but will be ignored when re-read. They may also -* be completely omitted in some circumstances. -* -* If "set" is non-zero, the value will always be explicitly -* included in the external representation so that it can be -* re-read. -* helpful -* This flag provides a hint about whether a value whose "set" -* flag is zero (above) should actually appear at all in the -* external representaton. -* -* If the external representation allows values to be "commented -* out" then, by default, values will be included in this form -* only if their "helpful" flag is non-zero. Otherwise, they -* will be omitted entirely. When possible, omitting the more -* obscure values associated with a class is recommended in -* order to improve readability. -* -* This default behaviour may be further modified if the -* Channel's Full attribute is set - either to permit all values -* to be shown, or to suppress non-essential information -* entirely. -* value -* The value to be written. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the value. -* -* Note that this comment may not actually be used, depending on -* the nature of the Channel supplied and the setting of its -* Comment attribute. -*- -*/ - -/* Local Constants: */ -#define BUFF_LEN 50 /* Size of local formatting buffer */ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *line; /* Pointer to dynamic output string */ - char buff[ BUFF_LEN + 1 ]; /* Local formatting buffer */ - int i; /* Loop counter for indentation characters */ - int nc; /* Number of output characters */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Use the "set" and "helpful" flags, along with the Channel's - attributes to decide whether this value should actually be - written. */ - if ( Use( this, set, helpful, status ) ) { - -/* Start building a dynamic string with an initial space, or a comment - character if "set" is zero. Then add further spaces to suit the - current indentation level. */ - line = astAppendString( NULL, &nc, set ? " " : "#" ); - for ( i = 0; i < current_indent; i++ ) { - line = astAppendString( line, &nc, " " ); - } - -/* Append the name string followed by " = ". */ - line = astAppendString( line, &nc, name ); - line = astAppendString( line, &nc, " = " ); - -/* Format the value as a decimal string and append this. */ - (void) sprintf( buff, "%d", value ); - line = astAppendString( line, &nc, buff ); - -/* If required, also append the comment. */ - if ( astGetComment( this ) && *comment ) { - line = astAppendString( line, &nc, " \t# " ); - line = astAppendString( line, &nc, comment ); - } - -/* Write out the resulting line of text. */ - OutputTextItem( this, line, status ); - -/* Free the dynamic string. */ - line = astFree( line ); - } - -/* Undefine macros local to this function. */ -#undef BUFF_LEN -} - -int astWriteInvocations_( int *status ){ -/* -*+ -* Name: -* astWriteInvocations - -* Purpose: -* Returns the number of invocations of the astWrite method. - -* Type: -* Protected function. - -* Synopsis: -* #include "channel.h" -* int astWriteInvocations - -* Class Membership: -* Channel method. - -* Description: -* This function returns the number of invocations of astWrite which -* have been made so far, excluding those made from within the -* astWriteObject method. An example of its use is to allow a Dump -* function to determine if a sub-object has already been dumped -* during the current invocation of astWrite. See the Dump method for -* the AstUnit class as an example. -*- -*/ - astDECLARE_GLOBALS - astGET_GLOBALS(NULL); - return nwrite_invoc; -} - -static void WriteIsA( AstChannel *this, const char *class, - const char *comment, int *status ) { -/* -*+ -* Name: -* astWriteIsA - -* Purpose: -* Write an "IsA" data item to a data sink. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astWriteIsA( AstChannel *this, const char *class, -* const char *comment ) - -* Class Membership: -* Channel method. - -* Description: -* This function writes an "IsA" data item to the data sink -* associated with a Channel. This item delimits the end of the -* data associated with the instance variables of a class, as part -* of an overall Object definition. - -* Parameters: -* this -* Pointer to the Channel. -* class -* Pointer to a constant null-terminated string containing the -* name of the class whose data are terminated by the "IsA" -* item. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the "IsA" -* item. Normally, this will describe the purpose of the class -* whose data are being terminated. - -* Notes: -* - The comment supplied may not actually be used, depending on -* the nature of the Channel supplied. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *line; /* Pointer to dynamic output string */ - int i; /* Loop counter for indentation characters */ - int indent_inc; /* Indentation increment */ - int nc; /* Number of output characters */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Output an "IsA" item only if there has been at least one item - written since the last "Begin" or "IsA" item, or if the Full - attribute for the Channel is greater than zero (requesting maximum - information). */ - if ( items_written || astGetFull( this ) > 0 ) { - -/* Start building a dynamic string with an initial space. Then add - further spaces to suit the current indentation level, but reduced - by one to allow the "IsA" item to match the "Begin" and "End" items - which enclose it. */ - indent_inc = astGetIndent( this ); - line = astAppendString( NULL, &nc, " " ); - for ( i = 0; i < ( current_indent - indent_inc ); i++ ) { - line = astAppendString( line, &nc, " " ); - } - -/* Append the "IsA" keyword followed by the class name. */ - line = astAppendString( line, &nc, "IsA " ); - line = astAppendString( line, &nc, class ); - -/* If required, also append the comment. */ - if ( astGetComment( this ) && *comment ) { - line = astAppendString( line, &nc, " \t# " ); - line = astAppendString( line, &nc, comment ); - } - -/* Write out the resulting line of text. */ - OutputTextItem( this, line, status ); - -/* Free the dynamic string. */ - line = astFree( line ); - -/* Clear the count of items written for this class. */ - items_written = 0; - } -} - -static void WriteObject( AstChannel *this, const char *name, - int set, int helpful, - AstObject *value, const char *comment, int *status ) { -/* -*+ -* Name: -* astWriteObject - -* Purpose: -* Write an Object as a value to a data sink. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astWriteObject( AstChannel *this, const char *name, -* int set, int helpful, -* AstObject *value, const char *comment ) - -* Class Membership: -* Channel method. - -* Description: -* This function writes an Object as a named value, representing -* the value of a class instance variable, to the data sink -* associated with a Channel. It is intended for use by class -* "Dump" functions when writing out class information which will -* subsequently be re-read. - -* Parameters: -* this -* Pointer to the Channel. -* name -* Pointer to a constant null-terminated string containing the -* name to be used to identify the value in the external -* representation. This will form the key for identifying it -* again when it is re-read. The name supplied should be unique -* within its class. -* -* Mixed case may be used and will be preserved in the external -* representation (where possible) for cosmetic effect. However, -* case is not significant when re-reading values. -* -* It is recommended that a maximum of 6 alphanumeric characters -* (starting with an alphabetic character) be used. This permits -* maximum flexibility in adapting to standard external data -* representations (e.g. FITS). -* set -* If this is zero, it indicates that the value being written is -* a default value (or can be re-generated from other values) so -* need not necessarily be written out. Such values will -* typically be included in the external representation with -* (e.g.) a comment character so that they are available to -* human readers but will be ignored when re-read. They may also -* be completely omitted in some circumstances. -* -* If "set" is non-zero, the value will always be explicitly -* included in the external representation so that it can be -* re-read. -* helpful -* This flag provides a hint about whether a value whose "set" -* flag is zero (above) should actually appear at all in the -* external representaton. -* -* If the external representation allows values to be "commented -* out" then, by default, values will be included in this form -* only if their "helpful" flag is non-zero. Otherwise, they -* will be omitted entirely. When possible, omitting the more -* obscure values associated with a class is recommended in -* order to improve readability. -* -* This default behaviour may be further modified if the -* Channel's Full attribute is set - either to permit all values -* to be shown, or to suppress non-essential information -* entirely. -* value -* A Pointer to the Object to be written. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the value. -* -* Note that this comment may not actually be used, depending on -* the nature of the Channel supplied and the setting of its -* Comment attribute. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *line; /* Pointer to dynamic output string */ - int i; /* Loop counter for indentation characters */ - int indent_inc; /* Indentation increment */ - int nc; /* Number of output characters */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Use the "set" and "helpful" flags, along with the Channel's - attributes to decide whether this value should actually be - written. */ - if ( Use( this, set, helpful, status ) ) { - -/* Start building a dynamic string with an initial space, or a comment - character if "set" is zero. Then add further spaces to suit the - current indentation level. */ - line = astAppendString( NULL, &nc, set ? " " : "#" ); - for ( i = 0; i < current_indent; i++ ) { - line = astAppendString( line, &nc, " " ); - } - -/* Append the name string followed by " =". The absence of a value on - the right hand side indicates an Object value, whose definition - follows. */ - line = astAppendString( line, &nc, name ); - line = astAppendString( line, &nc, " =" ); - -/* If required, also append the comment. */ - if ( astGetComment( this ) && *comment ) { - line = astAppendString( line, &nc, " \t# " ); - line = astAppendString( line, &nc, comment ); - } - -/* Write out the resulting line of text. */ - OutputTextItem( this, line, status ); - -/* Free the dynamic string. */ - line = astFree( line ); - -/* If the value is not a default, write the Object to the Channel as - well, suitably indented (this is omitted if the value is commented - out). */ - if ( set ) { - indent_inc = astGetIndent( this ); - current_indent += indent_inc; - (void) astWrite( this, value ); - current_indent -= indent_inc; - } - } -} - -static void WriteString( AstChannel *this, const char *name, - int set, int helpful, - const char *value, const char *comment, int *status ) { -/* -*+ -* Name: -* astWriteString - -* Purpose: -* Write a string value to a data sink. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "channel.h" -* void astWriteString( AstChannel *this, const char *name, -* int set, int helpful, -* const char *value, const char *comment ) - -* Class Membership: -* Channel method. - -* Description: -* This function writes a named string value, representing the -* value of a class instance variable, to the data sink associated -* with a Channel. It is intended for use by class "Dump" functions -* when writing out class information which will subsequently be -* re-read. - -* Parameters: -* this -* Pointer to the Channel. -* name -* Pointer to a constant null-terminated string containing the -* name to be used to identify the value in the external -* representation. This will form the key for identifying it -* again when it is re-read. The name supplied should be unique -* within its class. -* -* Mixed case may be used and will be preserved in the external -* representation (where possible) for cosmetic effect. However, -* case is not significant when re-reading values. -* -* It is recommended that a maximum of 6 alphanumeric characters -* (starting with an alphabetic character) be used. This permits -* maximum flexibility in adapting to standard external data -* representations (e.g. FITS). -* set -* If this is zero, it indicates that the value being written is -* a default value (or can be re-generated from other values) so -* need not necessarily be written out. Such values will -* typically be included in the external representation with -* (e.g.) a comment character so that they are available to -* human readers but will be ignored when re-read. They may also -* be completely omitted in some circumstances. -* -* If "set" is non-zero, the value will always be explicitly -* included in the external representation so that it can be -* re-read. -* helpful -* This flag provides a hint about whether a value whose "set" -* flag is zero (above) should actually appear at all in the -* external representaton. -* -* If the external representation allows values to be "commented -* out" then, by default, values will be included in this form -* only if their "helpful" flag is non-zero. Otherwise, they -* will be omitted entirely. When possible, omitting the more -* obscure values associated with a class is recommended in -* order to improve readability. -* -* This default behaviour may be further modified if the -* Channel's Full attribute is set - either to permit all values -* to be shown, or to suppress non-essential information -* entirely. -* value -* Pointer to a constant null-terminated string containing the -* value to be written. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the value. -* -* Note that this comment may not actually be used, depending on -* the nature of the Channel supplied and the setting of its -* Comment attribute. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *line; /* Pointer to dynamic output string */ - int i; /* Loop counter for characters */ - int nc; /* Number of output characters */ - int quote; /* Quote character found? */ - int size; /* Size of allocated memory */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Use the "set" and "helpful" flags, along with the Channel's - attributes to decide whether this value should actually be - written. */ - if ( Use( this, set, helpful, status ) ) { - -/* Start building a dynamic string with an initial space, or a comment - character if "set" is zero. Then add further spaces to suit the - current indentation level. */ - line = astAppendString( NULL, &nc, set ? " " : "#" ); - for ( i = 0; i < current_indent; i++ ) { - line = astAppendString( line, &nc, " " ); - } - -/* Append the name string followed by " = " and an opening quote - character (the string will be quoted to protect leading and - trailing spaces). */ - line = astAppendString( line, &nc, name ); - line = astAppendString( line, &nc, " = \"" ); - -/* We now append the value string, but must inspect each character so - that quotes (appearing inside quotes) can be doubled. Determine the - current size of memory allocated for the dynamic string. */ - size = (int) astSizeOf( line ); - -/* Loop to inspect each character and see if it is a quote. */ - for ( i = 0; value[ i ]; i++ ) { - quote = ( value[ i ] == '"' ); - -/* If more memory is required, extend the dynamic string (allowing for - doubling of quotes and the final null) and save its new size. */ - if ( nc + 2 + quote > size ) { - line = astGrow( line, nc + 2 + quote, sizeof( char ) ); - if ( astOK ) { - size = (int) astSizeOf( line ); - -/* Quit if an error occurs. */ - } else { - break; - } - } - -/* Append the value character to the dynamic string, duplicating each - quote character. */ - line[ nc++ ] = value[ i ]; - if ( quote ) line[ nc++ ] = '"'; - } - -/* Append the closing quote. */ - line = astAppendString( line, &nc, "\"" ); - -/* If required, also append the comment. */ - if ( astGetComment( this ) && *comment ) { - line = astAppendString( line, &nc, " \t# " ); - line = astAppendString( line, &nc, comment ); - } - -/* Write out the resulting line of text. */ - OutputTextItem( this, line, status ); - -/* Free the dynamic string. */ - line = astFree( line ); - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. */ - -/* -*att++ -* Name: -* SourceFile - -* Purpose: -* Input file from which to read data. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies the name of a file from which the Channel -* should read data. If specified it is used in preference to any source -* function specified when the Channel was created. -* -* Assigning a new value to this attribute will cause any previously -* opened SourceFile to be closed. The first subsequent call to -c astRead -f AST_READ -* will attempt to open the new file (an error will be reported if the -* file cannot be opened), and read data from it. All subsequent call to -c astRead -f AST_READ -* will read data from the new file, until the SourceFile attribute is -* cleared or changed. -* -* Clearing the attribute causes any open SourceFile to be closed. All -* subsequent data reads will use the source function specified when the -* Channel was created, or will read from standard input if no source -* function was specified. -* -* If no value has been assigned to SourceFile, a null string will be -* returned if an attempt is made to get the attribute value. - -* Notes: -* - Any open SourceFile is closed when the Channel is deleted. -* - If the Channel is copied or dumped -c (using astCopy or astShow) -f (using AST_COPY or AST_SHOW) -* the SourceFile attribute is left in a cleared state in the output -* Channel (i.e. the value of the SourceFile attribute is not copied). - -* Applicability: -* FitsChan -* In the case of a FitsChan, the specified SourceFile supplements -* the source function specified when the FitsChan was created, -* rather than replacing the source function. The source file -* should be a text file (not a FITS file) containing one header per -* line. When a value is assigned to SourceFile, the file is opened -* and read immediately, and all headers read from the file are -* appended to the end of any header already in the FitsChan. The file -* is then closed. Clearing the SourceFile attribute has no further -* effect, other than nullifying the string (i.e. the file name) -* associated with the attribute. - -*att-- -*/ - -/* Clear the SourceFile value by closing any open file, freeing the - allocated memory and assigning a NULL pointer. */ -astMAKE_CLEAR(Channel,SourceFile,fn_in,((this->fd_in=(this->fd_in?(fclose(this->fd_in),NULL):NULL)),astFree(this->fn_in))) - -/* If the SourceFile value is not set, supply a default in the form of a - pointer to the constant string "". */ -astMAKE_GET(Channel,SourceFile,const char *,NULL,( this->fn_in ? this->fn_in : "" )) - -/* Set a SourceFile value by closing any open file, freeing any previously - allocated memory, allocating new memory, storing the string and saving - the pointer to the copy. */ -astMAKE_SET(Channel,SourceFile,const char *,fn_in,((this->fd_in=(this->fd_in?(fclose(this->fd_in),NULL):NULL)),astStore( this->fn_in, value, strlen( value ) + (size_t) 1 ))) - -/* The SourceFile value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Channel,SourceFile,( this->fn_in != NULL )) - -/* -*att++ -* Name: -* SinkFile - -* Purpose: -* Output file to which to data should be written. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies the name of a file to which the Channel -* should write data. If specified it is used in preference to any sink -* function specified when the Channel was created. -* -* Assigning a new value to this attribute will cause any previously -* opened SinkFile to be closed. The first subsequent call to -c astWrite -f AST_WRITE -* will attempt to open the new file (an error will be reported if the -* file cannot be opened), and write data to it. All subsequent call to -c astWrite -f AST_WRITE -* will write data to the new file, until the SinkFile attribute is -* cleared or changed. -* -* Clearing the attribute causes any open SinkFile to be closed. All -* subsequent data writes will use the sink function specified when the -* Channel was created, or will write to standard output if no sink -* function was specified. -* -* If no value has been assigned to SinkFile, a null string will be -* returned if an attempt is made to get the attribute value. - -* Notes: -* - A new SinkFile will over-write any existing file with the same -* name unless the existing file is write protected, in which case an -* error will be reported. -* - Any open SinkFile is closed when the Channel is deleted. -* - If the Channel is copied or dumped -c (using astCopy or astShow) -f (using AST_COPY or AST_SHOW) -* the SinkFile attribute is left in a cleared state in the output -* Channel (i.e. the value of the SinkFile attribute is not copied). - -* Applicability: -* FitsChan -* When the FitsChan is destroyed, any headers in the FitsChan will be -* written out to the sink file, if one is specified (if not, the -* sink function used when the FitsChan was created is used). The -* sink file is a text file (not a FITS file) containing one header -* per line. - -*att-- -*/ - -/* Clear the SinkFile value by closing any open file, freeing the allocated - memory and assigning a NULL pointer. */ -astMAKE_CLEAR(Channel,SinkFile,fn_out,((this->fd_out=(this->fd_out?(fclose(this->fd_out),NULL):NULL)),astFree(this->fn_out))) - -/* If the SinkFile value is not set, supply a default in the form of a - pointer to the constant string "". */ -astMAKE_GET(Channel,SinkFile,const char *,NULL,( this->fn_out ? this->fn_out : "" )) - -/* Set a SinkFile value by closing any open file, freeing any previously - allocated memory, allocating new memory, storing the string and saving - the pointer to the copy. */ -astMAKE_SET(Channel,SinkFile,const char *,fn_out,((this->fd_out=(this->fd_out?(fclose(this->fd_out),NULL):NULL)),astStore( this->fn_out, value, strlen( value ) + (size_t) 1 ))) - -/* The SinkFile value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Channel,SinkFile,( this->fn_out != NULL )) - - -/* -*att++ -* Name: -* Comment - -* Purpose: -* Include textual comments in output? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This is a boolean attribute which controls whether textual -* comments are to be included in the output generated by a -* Channel. If included, they will describe what each item of -* output represents. -* -* If Comment is non-zero, then comments will be included. If -* it is zero, comments will be omitted. - -* Applicability: -* Channel -* The default value is non-zero for a normal Channel. -* FitsChan -* The default value is non-zero for a FitsChan. -* XmlChan -* The default value is zero for an XmlChan. - -*att-- -*/ - -/* This is a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of one. */ -astMAKE_CLEAR(Channel,Comment,comment,-INT_MAX) -astMAKE_GET(Channel,Comment,int,0,( this->comment != -INT_MAX ? this->comment : 1 )) -astMAKE_SET(Channel,Comment,int,comment,( value != 0 )) -astMAKE_TEST(Channel,Comment,( this->comment != -INT_MAX )) - -/* -*att++ -* Name: -* Full - -* Purpose: -* Set level of output detail. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute is a three-state flag and takes values of -1, 0 -* or +1. It controls the amount of information included in the -* output generated by a Channel. -* -* If Full is zero, then a modest amount of -* non-essential but useful information will be included in the -* output. If Full is negative, all non-essential information will -* be suppressed to minimise the amount of output, while if it is -* positive, the output will include the maximum amount of detailed -* information about the Object being written. - -* Applicability: -* Channel -* The default value is zero for a normal Channel. -* FitsChan -* The default value is zero for a FitsChan. -* XmlChan -* The default value is -1 for an XmlChan. -* StcsChan -* The default value is zero for an StcsChan. Set a positive value -* to cause default values to be included in STC-S descriptions. - -* Notes: -* - All positive values supplied for this attribute are converted -* to +1 and all negative values are converted to -1. -*att-- -*/ - -/* This ia a 3-state value (-1, 0 or +1) with a value of -INT_MAX when - undefined but yielding a default of zero. */ -astMAKE_CLEAR(Channel,Full,full,-INT_MAX) -astMAKE_GET(Channel,Full,int,0,( this->full != -INT_MAX ? this->full : 0 )) -astMAKE_SET(Channel,Full,int,full,( value > 0 ? 1 : ( value < 0 ? -1 : 0 ) )) -astMAKE_TEST(Channel,Full,( this->full != -INT_MAX )) - -/* -*att++ -* Name: -* Indent - -* Purpose: -* Specifies the indentation to use in text produced by a Channel. - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the indentation within the output text produced by -f the AST_WRITE function. -c the astWrite function. -* It gives the increase in the indentation for each level in the object -* heirarchy. If it is set to zero, no indentation will be used. [3] - -* Applicability: -* Channel -* The default value is zero for a basic Channel. -* FitsChan -* The FitsChan class ignores this attribute. -* StcsChan -* The default value for an StcsChan is zero, which causes the entire -* STC-S description is written out by a single invocation of the sink -* function. The text supplied to the sink function will not contain -* any linefeed characters, and each pair of adjacent words will be -* separated by a single space. The text may thus be arbitrarily large -* and the StcsLength attribute is ignored. -* -* If Indent is non-zero, then the text is written out via multiple -* calls to the sink function, each call corresponding to a single -* "line" of text (although no line feed characters will be inserted -* by AST). The complete STC-S description is broken into lines so that: -* -* - the line length specified by attribute StcsLength is not exceeded -* - each sub-phrase (time, space, etc.) starts on a new line -* - each argument in a compound spatial region starts on a new line -* -* If this causes a sub-phrase to extend to two or more lines, then the -* second and subsequent lines will be indented by three spaces compared -* to the first line. In addition, lines within a compound spatial region -* will have extra indentation to highlight the nesting produced by the -* parentheses. Each new level of nesting will be indented by a further -* three spaces. -f -f Note, the default value of zero is unlikely to be appropriate when -f an StcsChan is used within Fortran code. In this case, Indent -f should usually be set non-zero, and the StcsLength attribute set to -f the size of the CHARACTER variable used to -f receive the text returned by AST_GETLINE within the sink function. -f This avoids the possibility of long lines being truncated invisibly -f within AST_GETLINE. -* XmlChan -* The default value for an XmlChan is zero, which results in no -* linefeeds or indentation strings being added to output text. -* If any non-zero value is assigned to Indent, then extra linefeed and -* space characters will be inserted as necessary to ensure that each -* XML tag starts on a new line, and each tag will be indented by -* a further 3 spaces to show its depth in the containment hierarchy. -*att-- -*/ - -/* This is an integer value with a value of -INT_MAX when undefined, - yielding a default of 3. Sub-classes may over-ride theis default. */ -astMAKE_CLEAR(Channel,Indent,indent,-INT_MAX) -astMAKE_GET(Channel,Indent,int,3,( this->indent != -INT_MAX ? this->indent : 3 )) -astMAKE_SET(Channel,Indent,int,indent,value) -astMAKE_TEST(Channel,Indent,( this->indent != -INT_MAX )) - -/* -*att++ -* Name: -* ReportLevel - -* Purpose: -* Determines which read/write conditions are reported. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute determines which, if any, of the conditions that occur -* whilst reading or writing an Object should be reported. These -* conditions will generate either a fatal error or a warning, as -* determined by attribute Strict. ReportLevel can take any of the -* following values: -* -* 0 - Do not report any conditions. -* -* 1 - Report only conditions where significant information content has been -* changed. For instance, an unsupported time-scale has been replaced by a -* supported near-equivalent time-scale. Another example is if a basic -* Channel unexpected encounters data items that may have been introduced -* by later versions of AST. -* -* 2 - Report the above, and in addition report significant default -* values. For instance, if no time-scale was specified when reading an -* Object from an external data source, report the default time-scale -* that is being used. -* -* 3 - Report the above, and in addition report any other potentially -* interesting conditions that have no significant effect on the -* conversion. For instance, report if a time-scale of "TT" -* (terrestrial time) is used in place of "ET" (ephemeris time). This -* change has no signficiant effect because ET is the predecessor of, -* and is continuous with, TT. Synonyms such as "IAT" and "TAI" are -* another example. -* -* The default value is 1. Note, there are many other conditions that -* can occur whilst reading or writing an Object that completely -* prevent the conversion taking place. Such conditions will always -* generate errors, irrespective of the ReportLevel and Strict attributes. - -* Applicability: -* Channel -* All Channels have this attribute. -* FitsChan -* All the conditions selected by the FitsChan Warnings attribute are -* reported at level 1. -*att-- -*/ - -/* This is an integer value with a value of -INT_MAX when undefined, - yielding a default of one. */ -astMAKE_CLEAR(Channel,ReportLevel,report_level,-INT_MAX) -astMAKE_GET(Channel,ReportLevel,int,1,( this->report_level != -INT_MAX ? this->report_level : 1 )) -astMAKE_SET(Channel,ReportLevel,int,report_level,value) -astMAKE_TEST(Channel,ReportLevel,( this->report_level != -INT_MAX )) - -/* -*att++ -* Name: -* Skip - -* Purpose: -* Skip irrelevant data? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This is a boolean attribute which indicates whether the Object -* data being read through a Channel are inter-mixed with other, -* irrelevant, external data. -* -* If Skip is zero (the default), then the source of input data is -* expected to contain descriptions of AST Objects and comments and -* nothing else (if anything else is read, an error will -* result). If Skip is non-zero, then any non-Object data -* encountered between Objects will be ignored and simply skipped -* over in order to reach the next Object. - -* Applicability: -* Channel -* All Channels have this attribute. -* FitsChan -* The FitsChan class sets the default value of this attribute -* to 1, so that all irrelevant FITS headers will normally be -* ignored. -*att-- -*/ - -/* This ia a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of zero. */ -astMAKE_CLEAR(Channel,Skip,skip,-INT_MAX) -astMAKE_GET(Channel,Skip,int,0,( this->skip != -INT_MAX ? this->skip : 0 )) -astMAKE_SET(Channel,Skip,int,skip,( value != 0 )) -astMAKE_TEST(Channel,Skip,( this->skip != -INT_MAX )) - -/* -*att++ -* Name: -* Strict - -* Purpose: -* Report an error if any unexpeted data items are found? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This is a boolean attribute which indicates whether a warning -* rather than an error should be issed for insignificant conversion -* problems. If it is set non-zero, then fatal errors are issued -* instead of warnings, resulting in the -c AST error status being set. -f inherited STATUS variable being set to an error value. -* If Strict is zero (the default), then execution continues after minor -* conversion problems, and a warning message is added to the Channel -* structure. Such messages can be retrieved using the -c astWarnings -f AST_WARNINGS -* function. - -* Notes: -* - This attribute was introduced in AST version 5.0. Prior to this -* version of AST unexpected data items read by a basic Channel always -* caused an error to be reported. So applications linked against -* versions of AST prior to version 5.0 may not be able to read Object -* descriptions created by later versions of AST, if the Object's class -* description has changed. - -* Applicability: -* Channel -* All Channels have this attribute. -*att-- -*/ - -/* This ia a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of zero. */ -astMAKE_CLEAR(Channel,Strict,strict,-INT_MAX) -astMAKE_GET(Channel,Strict,int,0,( this->strict != -INT_MAX ? this->strict : 0 )) -astMAKE_SET(Channel,Strict,int,strict,( value != 0 )) -astMAKE_TEST(Channel,Strict,( this->strict != -INT_MAX )) - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Channel objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Channel objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstChannel *this; /* Pointer to Channel */ - -/* Obtain a pointer to the Channel structure. */ - this = (AstChannel *) obj; - -/* Free memory used to store warnings. */ - astAddWarning( this, 0, NULL, NULL, status ); - -/* Close any open input or output files. */ - if( this->fd_in ) fclose( this->fd_in ); - if( this->fd_out ) fclose( this->fd_out ); - -/* Free file name memory. */ - this->fn_in = astFree( this->fn_in ); - this->fn_out = astFree( this->fn_out ); -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Channel objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Channel objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstChannel *out; /* Pointer to output Channel */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Channels. */ - out = (AstChannel *) objout; - -/* Just clear any references to the input memory from the output Channel. */ - out->warnings = NULL; - out->nwarn = 0; - out->fd_in = NULL; - out->fn_in = NULL; - out->fd_out = NULL; - out->fn_out = NULL; -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Channel objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Channel class to an output Channel. - -* Parameters: -* this -* Pointer to the Object whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstChannel *this; /* Pointer to the Channel structure */ - const char *comment; /* Pointer to comment string */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Channel structure. */ - this = (AstChannel *) this_object; - -/* Write out values representing the instance variables for the - Channel class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Indent */ -/* ------------ */ - set = TestIndent( this, status ); - ival = set ? GetIndent( this, status ) : astGetIndent( this ); - astWriteInt( channel, "Indnt", set, 0, ival, "Indentation increment" ); - -/* ReportLevel. */ -/* ------------ */ - set = TestReportLevel( this, status ); - ival = set ? GetReportLevel( this, status ) : astGetReportLevel( this ); - astWriteInt( channel, "RpLev", set, 0, ival, "Error reporting level" ); - -/* Skip. */ -/* ----- */ - set = TestSkip( this, status ); - ival = set ? GetSkip( this, status ) : astGetSkip( this ); - astWriteInt( channel, "Skip", set, 0, ival, - ival ? "Ignore data between Objects" : - "No data allowed between Objects" ); - -/* Strict. */ -/* ------- */ - set = TestStrict( this, status ); - ival = set ? GetStrict( this, status ) : astGetStrict( this ); - astWriteInt( channel, "Strict", set, 0, ival, - ival ? "Report errors insead of warnings" : - "Report warnings instead of errors" ); - -/* Full. */ -/* ----- */ - set = TestFull( this, status ); - ival = set ? GetFull( this, status ) : astGetFull( this ); - if ( ival < 0 ) { - comment = "Suppress non-essential output"; - }else if ( ival == 0 ) { - comment = "Output standard information"; - } else { - comment = "Output maximum information"; - } - astWriteInt( channel, "Full", set, 0, ival, comment ); - -/* Comment. */ -/* -------- */ - set = TestComment( this, status ); - ival = set ? GetComment( this, status ) : astGetComment( this ); - astWriteInt( channel, "Comm", set, 0, ival, - ival ? "Display comments" : - "Omit comments" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAChannel and astCheckChannel functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Channel,Object) -astMAKE_CHECK(Channel) - -AstChannel *astChannel_( const char *(* source)( void ), - void (* sink)( const char * ), - const char *options, int *status, ...) { -/* -*+ -* Name: -* astChannel - -* Purpose: -* Create a Channel. - -* Type: -* Protected function. - -* Synopsis: -* #include "channel.h" -* AstChannel *astChannel( const char *(* source)( void ), -* void (* sink)( const char * ), -* const char *options, ..., int *status ) - -* Class Membership: -* Channel constructor. - -* Description: -* This function creates a new Channel and optionally initialises -* its attributes. -* -* A Channel implements low-level input/output for the AST library. -* Writing an Object to a Channel (using astWrite) will generate a -* textual representation of that Object, and reading from a -* Channel (using astRead) will create a new Object from its -* textual representation. -* -* Normally, when you use a Channel, you should provide "source" -* and "sink" functions which connect it to an external data store -* by reading and writing the resulting text. By default, however, -* a Channel will read from standard input and write to standard -* output. - -* Parameters: -* source -* Pointer to a "source" function that takes no arguments and -* returns a pointer to a null-terminated string. -* -* This function will be used by the Channel to obtain lines of -* input text. On each invocation, it should return a pointer to -* the next input line read from some external data store, and a -* NULL pointer when there are no more lines to read. -* -* If "source" is NULL, the Channel will read from standard -* input instead. -* sink -* Pointer to a "sink" function that takes a pointer to a -* null-terminated string as an argument and returns void. -* -* This function will be used by the Channel to deliver lines of -* output text. On each invocation, it should deliver the -* contents of the string supplied to some external data store. -* -* If "sink" is NULL, the Channel will write to standard output -* instead. -* options -* Pointer to a null-terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new Channel. The syntax used is identical to -* that for the astSet function and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of additional arguments may follow it in -* order to supply values to be substituted for these -* specifiers. The rules for supplying these are identical to -* those for the astSet function (and for the C "printf" -* function). - -* Returned Value: -* astChannel() -* A pointer to the new Channel. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*- - -* Implementation Notes: -* - This function implements the basic Channel constructor which -* is available via the protected interface to the Channel class. -* A public interface is provided by the astChannelId_ function. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstChannel *new; /* Pointer to new Channel */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the Channel, allocating memory and initialising the - virtual function table as well if necessary. Supply pointers to - (local) wrapper functions that can invoke the source and sink - functions with appropriate arguments for the C language. */ - new = astInitChannel( NULL, sizeof( AstChannel ), !class_init, &class_vtab, - "Channel", source, SourceWrap, sink, SinkWrap ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - Channel's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Channel. */ - return new; -} - -AstChannel *astChannelId_( const char *(* source)( void ), - void (* sink)( const char * ), - const char *options, ... ) { -/* -*++ -* Name: -c astChannel -f AST_CHANNEL - -* Purpose: -* Create a Channel. - -* Type: -* Public function. - -* Synopsis: -c #include "channel.h" -c AstChannel *astChannel( const char *(* source)( void ), -c void (* sink)( const char * ), -c const char *options, ... ) -f RESULT = AST_CHANNEL( SOURCE, SINK, OPTIONS, STATUS ) - -* Class Membership: -* Channel constructor. - -* Description: -* This function creates a new Channel and optionally initialises -* its attributes. -* -* A Channel implements low-level input/output for the AST library. -c Writing an Object to a Channel (using astWrite) will generate a -f Writing an Object to a Channel (using AST_WRITE) will generate a -* textual representation of that Object, and reading from a -c Channel (using astRead) will create a new Object from its -f Channel (using AST_READ) will create a new Object from its -* textual representation. -* -* Normally, when you use a Channel, you should provide "source" -c and "sink" functions which connect it to an external data store -f and "sink" routines which connect it to an external data store -* by reading and writing the resulting text. By default, however, -* a Channel will read from standard input and write to standard -* output. Alternatively, a Channel can be told to read or write from -* specific text files using the SinkFile and SourceFile attributes, -* in which case no sink or source function need be supplied. - -* Parameters: -c source -f SOURCE = SUBROUTINE (Given) -c Pointer to a source function that takes no arguments and -c returns a pointer to a null-terminated string. If no value -c has been set for the SourceFile attribute, this function -c will be used by the Channel to obtain lines of input text. On -c each invocation, it should return a pointer to the next input -c line read from some external data store, and a NULL pointer -c when there are no more lines to read. -c -c If "source" is NULL and no value has been set for the SourceFile -c attribute, the Channel will read from standard input instead. -f A source routine, which is a subroutine which takes a single -f integer error status argument. If no value has been set -f for the SourceFile attribute, this routine will be used by -f the Channel to obtain lines of input text. On each -f invocation, it should read the next input line from some -f external data store, and then return the resulting text to -f the AST library by calling AST_PUTLINE. It should supply a -f negative line length when there are no more lines to read. -f If an error occurs, it should set its own error status -f argument to an error value before returning. -f -f If the null routine AST_NULL is suppied as the SOURCE value, -f and no value has been set for the SourceFile attribute, -f the Channel will read from standard input instead. -c sink -f SINK = SUBROUTINE (Given) -c Pointer to a sink function that takes a pointer to a -c null-terminated string as an argument and returns void. -c If no value has been set for the SinkFile attribute, this -c function will be used by the Channel to deliver lines of -c output text. On each invocation, it should deliver the -c contents of the string supplied to some external data store. -c -c If "sink" is NULL, and no value has been set for the SinkFile -c attribute, the Channel will write to standard output instead. -f A sink routine, which is a subroutine which takes a single -f integer error status argument. If no value has been set -f for the SinkFile attribute, this routine will be used by -f the Channel to deliver lines of output text. On each -f invocation, it should obtain the next output line from the -f AST library by calling AST_GETLINE, and then deliver the -f resulting text to some external data store. If an error -f occurs, it should set its own error status argument to an -f error value before returning. -f -f If the null routine AST_NULL is suppied as the SINK value, -f and no value has been set for the SinkFile attribute, -f the Channel will write to standard output instead. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Channel. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Channel. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astChannel() -f AST_CHANNEL = INTEGER -* A pointer to the new Channel. - -* Notes: -c - Application code can pass arbitrary data (such as file -c descriptors, etc) to source and sink functions using the -c astPutChannelData function. The source or sink function should use -c the astChannelData macro to retrieve this data. -f - The names of the routines supplied for the SOURCE and SINK -f arguments should appear in EXTERNAL statements in the Fortran -f routine which invokes AST_CHANNEL. However, this is not generally -f necessary for the null routine AST_NULL (so long as the AST_PAR -f include file has been used). -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -f - Note that the null routine AST_NULL (one underscore) is -f different to AST__NULL (two underscores), which is the null Object -f pointer. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astChannel constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astChannel_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - The variable argument list also prevents this function from -* invoking astChanel_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstChannel *new; /* Pointer to new Channel */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the Channel, allocating memory and initialising the - virtual function table as well if necessary. Supply pointers to - (local) wrapper functions that can invoke the source and sink - functions with appropriate arguments for the C language. */ - new = astInitChannel( NULL, sizeof( AstChannel ), !class_init, &class_vtab, - "Channel", source, SourceWrap, sink, SinkWrap ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - Channel's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Channel. */ - return astMakeId( new ); -} - -AstChannel *astChannelForId_( const char *(* source)( void ), - char *(* source_wrap)( const char *(*)( void ), int * ), - void (* sink)( const char * ), - void (* sink_wrap)( void (*)( const char * ), - const char *, int * ), - const char *options, ... ) { -/* -*+ -* Name: -* astChannelFor - -* Purpose: -* Initialise a Channel from a foreign language interface. - -* Type: -* Public function. - -* Synopsis: -* #include "channel.h" -* AstChannel *astChannelFor( const char *(* source)( void ), -* char *(* source_wrap)( const char *(*) -* ( void ), int * ), -* void (* sink)( const char * ), -* void (* sink_wrap)( void (*)( const char * ), -* const char *, int * ), -* const char *options, ... ) - -* Class Membership: -* Channel constructor. - -* Description: -* This function creates a new Channel from a foreign language -* interface and optionally initialises its attributes. -* -* A Channel implements low-level input/output for the AST library. -* Writing an Object to a Channel (using astWrite) will generate a -* textual representation of that Object, and reading from a -* Channel (using astRead) will create a new Object from its -* textual representation. -* -* Normally, when you use a Channel, you should provide "source" -* and "sink" functions which connect it to an external data store -* by reading and writing the resulting text. This function also -* requires you to provide "wrapper" functions which will invoke -* the source and sink functions. By default, however, a Channel -* will read from standard input and write to standard output. - -* Parameters: -* source -* Pointer to a "source" function which will be used to obtain -* lines of input text. Generally, this will be obtained by -* casting a pointer to a source function which is compatible -* with the "source_wrap" wrapper function (below). The pointer -* should later be cast back to its original type by the -* "source_wrap" function before the function is invoked. -* -* If "source" is NULL, the Channel will read from standard -* input instead. -* source_wrap -* Pointer to a function which can be used to invoke the -* "source" function supplied (above). This wrapper function is -* necessary in order to hide variations in the nature of the -* source function, such as may arise when it is supplied by a -* foreign (non-C) language interface. -* -* The single parameter of the "source_wrap" function is a -* pointer to the "source" function, and it should cast this -* function pointer (as necessary) and invoke the function with -* appropriate arguments to obtain the next line of input -* text. The "source_wrap" function should then return a pointer -* to a dynamically allocated, null terminated string containing -* the text that was read. The string will be freed (using -* astFree) when no longer required and the "source_wrap" -* function need not concern itself with this. A NULL pointer -* should be returned if there is no more input to read. -* -* If "source_wrap" is NULL, the Channel will read from standard -* input instead. -* sink -* Pointer to a "sink" function which will be used to deliver -* lines of output text. Generally, this will be obtained by -* casting a pointer to a sink function which is compatible with -* the "sink_wrap" wrapper function (below). The pointer should -* later be cast back to its original type by the "sink_wrap" -* function before the function is invoked. -* -* If "sink" is NULL, the Channel will write to standard output -* instead. -* sink_wrap -* Pointer to a function which can be used to invoke the "sink" -* function supplied (above). This wrapper function is necessary -* in order to hide variations in the nature of the sink -* function, such as may arise when it is supplied by a foreign -* (non-C) language interface. -* -* The first parameter of the "sink_wrap" function is a pointer -* to the "sink" function, and the second parameter is a pointer -* to a const, null-terminated character string containing the -* text to be written. The "sink_wrap" function should cast the -* "sink" function pointer (as necessary) and invoke the -* function with appropriate arguments to deliver the line of -* output text. The "sink_wrap" function then returns void. -* -* If "sink_wrap" is NULL, the Channel will write to standard -* output instead. -* options -* Pointer to a null-terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new Channel. The syntax used is identical to -* that for the astSet function and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of additional arguments may follow it in -* order to supply values to be substituted for these -* specifiers. The rules for supplying these are identical to -* those for the astSet function (and for the C "printf" -* function). - -* Returned Value: -* astChannelFor() -* A pointer to the new Channel. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -* - This function is only available through the public interface -* to the Channel class (not the protected interface) and is -* intended solely for use in implementing foreign language -* interfaces to this class. -*- - -* Implememtation Notes: -* - This function behaves exactly like astChannelId_, in that it -* returns ID values and not true C pointers, but it has two -* additional arguments. These are pointers to the "wrapper -* functions" which are needed to accommodate foreign language -* interfaces. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstChannel *new; /* Pointer to new Channel */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise the Channel, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitChannel( NULL, sizeof( AstChannel ), !class_init, &class_vtab, - "Channel", source, source_wrap, sink, sink_wrap ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - Channel's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Channel. */ - return astMakeId( new ); -} - -AstChannel *astLoadChannel_( void *mem, size_t size, - AstChannelVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadChannel - -* Purpose: -* Load a Channel. - -* Type: -* Protected function. - -* Synopsis: -* #include "channel.h" -* AstChannel *astLoadChannel( void *mem, size_t size, -* AstChannelVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* Channel loader. - -* Description: -* This function is provided to load a new Channel using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Channel structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Channel at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the Channel is to be -* loaded. This must be of sufficient size to accommodate the -* Channel data (sizeof(Channel)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Channel (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Channel structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstChannel) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Channel. If this is NULL, a pointer -* to the (static) virtual function table for the Channel class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Channel" is used instead. - -* Returned Value: -* A pointer to the new Channel. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstChannel *new; /* Pointer to the new Channel */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Channel. In this case the - Channel belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstChannel ); - vtab = &class_vtab; - name = "Channel"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitChannelVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Channel. */ - new = astLoadObject( mem, size, (AstObjectVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Channel" ); - -/* Set the pointers to the source and sink functions, and their - wrapper functions, to NULL (we cannot restore these since they - refer to process-specific addresses). */ - new->source = NULL; - new->source_wrap = NULL; - new->sink = NULL; - new->sink_wrap = NULL; - -/* We do not have any data to pass to the source and sink functions. */ - new->data = NULL; - -/* No warnings yet. */ - new->warnings = NULL; - new->nwarn = 0; - -/* Indicate no input or output files have been associated with the - Channel. */ - new->fd_in = NULL; - new->fn_in = NULL; - new->fd_out = NULL; - new->fn_out = NULL; - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Indent. */ -/* ------- */ - new->indent = astReadInt( channel, "indnt", -INT_MAX ); - if ( TestIndent( new, status ) ) SetIndent( new, new->indent, status ); - -/* ReportLevel. */ -/* ------------ */ - new->report_level = astReadInt( channel, "rplev", -INT_MAX ); - if ( TestReportLevel( new, status ) ) SetReportLevel( new, - new->report_level, - status ); - -/* Skip. */ -/* ----- */ - new->skip = astReadInt( channel, "skip", -INT_MAX ); - if ( TestSkip( new, status ) ) SetSkip( new, new->skip, status ); - -/* Strict. */ -/* ------- */ - new->strict = astReadInt( channel, "strict", -INT_MAX ); - if ( TestStrict( new, status ) ) SetStrict( new, new->strict, status ); - -/* Full. */ -/* ----- */ - new->full = astReadInt( channel, "full", -INT_MAX ); - if ( TestFull( new, status ) ) SetFull( new, new->full, status ); - -/* Comment. */ -/* -------- */ - new->comment = astReadInt( channel, "comm", -INT_MAX ); - if ( TestComment( new, status ) ) SetComment( new, new->comment, status ); - -/* If an error occurred, clean up by deleting the new Channel. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Channel pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions - defined by this class. Each simply checks the global error status - and then locates and executes the appropriate member function, - using the function pointer stored in the object's virtual function - table (this pointer is located using the astMEMBER macro defined in - "object.h"). - - Note that the member function may not be the one defined here, as - it may have been over-ridden by a derived class. However, it should - still have the same interface. */ -void astGetNextData_( AstChannel *this, int begin, char **name, char **val, int *status ) { - *name = NULL; - *val = NULL; - if ( !astOK ) return; - (**astMEMBER(this,Channel,GetNextData))( this, begin, name, val, status ); -} -char *astGetNextText_( AstChannel *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Channel,GetNextText))( this, status ); -} -void astPutNextText_( AstChannel *this, const char *line, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Channel,PutNextText))( this, line, status ); -} -AstObject *astRead_( AstChannel *this, int *status ) { - if ( !astOK ) return NULL; - astAddWarning( this, 0, NULL, NULL, status ); - return (**astMEMBER(this,Channel,Read))( this, status ); -} -void astReadClassData_( AstChannel *this, const char *class, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Channel,ReadClassData))( this, class, status ); -} -double astReadDouble_( AstChannel *this, const char *name, double def, int *status ) { - if ( !astOK ) return 0.0; - return (**astMEMBER(this,Channel,ReadDouble))( this, name, def, status ); -} -int astReadInt_( AstChannel *this, const char *name, int def, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Channel,ReadInt))( this, name, def, status ); -} -AstObject *astReadObject_( AstChannel *this, const char *name, - AstObject *def, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Channel,ReadObject))( this, name, def, status ); -} -char *astReadString_( AstChannel *this, const char *name, const char *def, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Channel,ReadString))( this, name, def, status ); -} -void astWriteBegin_( AstChannel *this, const char *class, - const char *comment, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Channel,WriteBegin))( this, class, comment, status ); -} -void astWriteDouble_( AstChannel *this, const char *name, int set, int helpful, - double value, const char *comment, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Channel,WriteDouble))( this, name, set, helpful, value, - comment, status ); -} -void astWriteEnd_( AstChannel *this, const char *class, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Channel,WriteEnd))( this, class, status ); -} -void astWriteInt_( AstChannel *this, const char *name, int set, int helpful, - int value, const char *comment, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Channel,WriteInt))( this, name, set, helpful, value, - comment, status ); -} -void astWriteIsA_( AstChannel *this, const char *class, const char *comment, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Channel,WriteIsA))( this, class, comment, status ); -} -void astWriteString_( AstChannel *this, const char *name, int set, int helpful, - const char *value, const char *comment, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Channel,WriteString))( this, name, set, helpful, value, - comment, status ); -} -void astPutChannelData_( AstChannel *this, void *data, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Channel,PutChannelData))( this, data, status ); -} - -AstKeyMap *astWarnings_( AstChannel *this, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,Channel,Warnings))( this, status ); -} - -/* Because of the variable argument list, we need to work a bit harder on - astAddWarning. Functions that provide implementations of the - astAddWarning method recieve the fully expanded message and so do not - need a variable argument list. */ - -void astAddWarning_( void *this_void, int level, const char *fmt, - const char *method, int *status, ... ) { - AstChannel *this; - char buff[ 201 ]; - va_list args; - int nc; - - this = astCheckChannel( this_void ); - - if( fmt ) { - if( astOK ) { - va_start( args, status ); - nc = vsprintf( buff, fmt, args ); - va_end( args ); - if( nc > 200 ) { - astError( AST__INTER, "astAddWarning(%s): Message buffer size " - "exceeded (internal AST programming error).", - status, astGetClass( this ) ); - } else { - (**astMEMBER(this,Channel,AddWarning))( this, level, buff, method, status ); - } - } - } else { - (**astMEMBER(this,Channel,AddWarning))( this, level, NULL, method, status ); - } -} - -/* Count the number of times astWrite is invoked (excluding invocations - made from within the astWriteObject method - see below). The count is - done here so that invocations of astWrite within a sub-class will be - included. */ -int astWrite_( AstChannel *this, AstObject *object, int *status ) { - astDECLARE_GLOBALS - if ( !astOK ) return 0; - astGET_GLOBALS(this); - nwrite_invoc++; - astAddWarning( this, 0, NULL, NULL, status ); - return (**astMEMBER(this,Channel,Write))( this, object, status ); -} - -/* We do not want to count invocations of astWrite made from within the - astWriteObject method. So decrement the number of invocations first - (this assumes that each invocation of astWriteObject will only invoke - astWrite once). */ -void astWriteObject_( AstChannel *this, const char *name, int set, - int helpful, AstObject *value, const char *comment, int *status ) { - astDECLARE_GLOBALS - if ( !astOK ) return; - astGET_GLOBALS(this); - nwrite_invoc--; - (**astMEMBER(this,Channel,WriteObject))( this, name, set, helpful, value, - comment, status ); -} - - - - - diff --git a/ast/channel.h b/ast/channel.h deleted file mode 100644 index 1969ea3..0000000 --- a/ast/channel.h +++ /dev/null @@ -1,687 +0,0 @@ -/* -*+ -* Name: -* channel.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Channel class. - -* Invocation: -* #include "channel.h" - -* Description: -* This include file defines the interface to the Channel class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* A Channel is the basic form of AST I/O channel, through which -* Objects may be written and later read back. It causes I/O to -* take place using a textual format via standard input and -* standard output. -* -* Writing to a Channel will result in a textual representation of -* an Object being produced on standard output. Reading from a -* Channel will causes a textual description of an Object to be -* read from standard input, and that Object to be -* re-created. Channel I/O is stream based, and multiple objects -* may be written or read in succession through the same Channel. A -* null Object pointer is returned if there is no more input to -* read. - -* Inheritance: -* The Channel class inherits from the Object class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* Comment (integer) -* A boolean value (0 or 1) which controls whether comments are -* to be included in textual output generated by a Channel. If -* this value is non-zero (the default), then comments will be -* included. If it is zero, comments will be omitted. -* Full (integer) -* A three-state flag (taking values -1, 0 or +1) which controls -* the amount of information included in textual output -* generated by a Channel. If this value is zero (the default), -* then a modest amount of non-essential but useful information -* will be included along with the output. If Full is negative, -* all non-essential information will be suppressed, while if it -* is positive, the output will include the maximum amount of -* information about the Object being written. -* Skip (integer) -* A boolean value which indicates whether the Objects being -* read through a Channel are inter-mixed with other external -* data. If this value is zero (the default), then the source of -* input data is expected to contain descriptions of AST Objects -* and comments and nothing else (if anything else is read, an -* error will result). If Skip is non-zero, then any non-Object -* data encountered between Objects will simply be skipped over -* in order to reach the next Object. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astClearAttrib -* Clear an attribute value for a Mapping. -* astGetAttrib -* Get an attribute value for a Mapping. -* astSetAttrib -* Set an attribute value for a Mapping. -* astTestAttrib -* Test if an attribute value has been set for a Mapping. - -* New Methods Defined: -* Public: -* astRead -* Read an Object from a Channel. -* astWrite -* Write an Object to a Channel. -* -* Protected: -* astClearComment -* Clear the Comment attribute for a Channel. -* astClearFull -* Clear the Full attribute for a Channel. -* astClearSkip -* Clear the Skip attribute for a Channel. -* astGetComment -* Get the value of the Comment attribute for a Channel. -* astGetFull -* Get the value of the Full attribute for a Channel. -* astGetNextData -* Read the next item of data from a data source. -* astGetNextText -* Read the next line of input text from a data source. -* astGetSkip -* Get the value of the Skip attribute for a Channel. -* astPutNextText -* Write a line of output text to a data sink. -* astReadClassData -* Read values from a data source for a class loader. -* astReadDouble -* Read a double value as part of loading a class. -* astReadInt -* Read an int value as part of loading a class. -* astReadObject -* Read a (sub)Object as part of loading a class. -* astReadString -* Read a string value as part of loading a class. -* astSetComment -* Set the value of the Comment attribute for a Channel. -* astSetFull -* Set the value of the Full attribute for a Channel. -* astSetSkip -* Set the value of the Skip attribute for a Channel. -* astTestComment -* Test whether a value has been set for the Comment attribute of a -* Channel. -* astTestFull -* Test whether a value has been set for the Full attribute of a -* Channel. -* astTestSkip -* Test whether a value has been set for the Skip attribute of a -* Channel. -* astWriteBegin -* Write a "Begin" data item to a data sink. -* astWriteDouble -* Write a double value to a data sink. -* astWriteEnd -* Write an "End" data item to a data sink. -* astWriteInt -* Write an integer value to a data sink. -* astWriteIsA -* Write an "IsA" data item to a data sink. -* astWriteObject -* Write an Object as a value to a data sink. -* astWriteString -* Write a string value to a data sink. - -* Other Class Functions: -* Public: -* astChannel -* Create a Channel. -* astChannelFor -* Create a Channel from a foreign language interface. -* astIsAChannel -* Test class membership. -* -* Protected: -* astCheckChannel -* Validate class membership. -* astInitChannel -* Initialise a Channel. -* astInitChannelVtab -* Initialise the virtual function table for the Channel class. -* astLoadChannel -* Load a Channel. - -* Type Definitions: -* Public: -* AstChannel -* Channel object type. -* -* Protected: -* AstChannelVtab -* Channel virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 12-AUG-1996 (RFWS): -* Original version. -* 12-DEC-1996 (RFWS): -* Added the astChannelFor function. -* 11-NOV-2002 (DSB): -* Added astWriteInvocations. -* 8-JAN-2003 (DSB): -* Added protected astInitAxisVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ - -/* Note that the usual setting of the CHANNEL_INCLUDED flag, which - prevents this file being included more than once, must be deferred - until after including the "object.h" file. This is because - "object.h" needs to include the present interface definition (as a - form of "forward reference") in order to have access to I/O - Channels itself. */ -#if !defined( CHANNEL_INCLUDED ) -#define CHANNEL_INCLUDED - -/* C header files. */ -/* --------------- */ -#include - -/* Macros */ -/* ====== */ -/* Define constants used to size global arrays in this module. */ -#define AST__CHANNEL_GETATTRIB_BUFF_LEN 50 - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ - -/* The astWarnings function returns a KeyMap pointer, but we cannot - include keymap.h here to define the AstKeyMap type since keymap.h - itself include sthis file. So we make a temporary declaration which - will be replaced by the full one when the keymap.h file is included. */ -struct AstKeyMap; - -/* Channel structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstChannel { - -/* Attributes inherited from the parent class. */ - AstObject object; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - const char *(* source)( void ); /* Pointer to source function */ - char *(* source_wrap)( const char *(*)(void), int * ); - /* Source wrapper function pointer */ - void (* sink)( const char * ); /* Pointer to sink function */ - void (* sink_wrap)( void (*)( const char *), const char *, int * ); - /* Sink wrapper function pointer */ - int comment; /* Output comments? */ - int full; /* Set max/normal/min information level */ - int skip; /* Skip data between Objects? */ - int indent; /* Indentation increment in astWrite output */ - int report_level; /* Skip data between Objects? */ - int strict; /* Report unexpected data items? */ - void *data; /* Data to pass to source/sink functions */ - char **warnings; /* Array of warning strings */ - int nwarn; /* Size of warnings array */ - FILE *fd_in; /* Descriptor for source text file */ - char *fn_in; /* Full path for source text file */ - FILE *fd_out; /* Descriptor for sink text file */ - char *fn_out; /* Full path for sink text file */ -} AstChannel; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstChannelVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstObjectVtab object_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - struct AstKeyMap *(* Warnings)( AstChannel *, int * ); - AstObject *(* Read)( AstChannel *, int * ); - AstObject *(* ReadObject)( AstChannel *, const char *, AstObject *, int * ); - char *(* GetNextText)( AstChannel *, int * ); - char *(* ReadString)( AstChannel *, const char *, const char *, int * ); - double (* ReadDouble)( AstChannel *, const char *, double, int * ); - int (* GetComment)( AstChannel *, int * ); - int (* GetFull)( AstChannel *, int * ); - int (* GetStrict)( AstChannel *, int * ); - int (* ReadInt)( AstChannel *, const char *, int, int * ); - int (* TestComment)( AstChannel *, int * ); - int (* TestFull)( AstChannel *, int * ); - int (* TestStrict)( AstChannel *, int * ); - int (* Write)( AstChannel *, AstObject *, int * ); - void (* AddWarning)( AstChannel *, int, const char *, const char *, int * ); - void (* ClearComment)( AstChannel *, int * ); - void (* ClearFull)( AstChannel *, int * ); - void (* ClearStrict)( AstChannel *, int * ); - void (* GetNextData)( AstChannel *, int, char **, char **, int * ); - void (* PutChannelData)( AstChannel *, void *, int * ); - void (* PutNextText)( AstChannel *, const char *, int * ); - void (* ReadClassData)( AstChannel *, const char *, int * ); - void (* SetComment)( AstChannel *, int, int * ); - void (* SetFull)( AstChannel *, int, int * ); - void (* SetStrict)( AstChannel *, int, int * ); - void (* WriteBegin)( AstChannel *, const char *, const char *, int * ); - void (* WriteDouble)( AstChannel *, const char *, int, int, double, const char *, int * ); - void (* WriteEnd)( AstChannel *, const char *, int * ); - void (* WriteInt)( AstChannel *, const char *, int, int, int, const char *, int * ); - void (* WriteIsA)( AstChannel *, const char *, const char *, int * ); - void (* WriteObject)( AstChannel *, const char *, int, int, AstObject *, const char *, int * ); - void (* WriteString)( AstChannel *, const char *, int, int, const char *, const char *, int * ); - - int (* GetSkip)( AstChannel *, int * ); - int (* TestSkip)( AstChannel *, int * ); - void (* ClearSkip)( AstChannel *, int * ); - void (* SetSkip)( AstChannel *, int, int * ); - - int (* GetReportLevel)( AstChannel *, int * ); - int (* TestReportLevel)( AstChannel *, int * ); - void (* ClearReportLevel)( AstChannel *, int * ); - void (* SetReportLevel)( AstChannel *, int, int * ); - - int (* GetIndent)( AstChannel *, int * ); - int (* TestIndent)( AstChannel *, int * ); - void (* ClearIndent)( AstChannel *, int * ); - void (* SetIndent)( AstChannel *, int, int * ); - - const char *(* GetSourceFile)( AstChannel *, int * ); - int (* TestSourceFile)( AstChannel *, int * ); - void (* ClearSourceFile)( AstChannel *, int * ); - void (* SetSourceFile)( AstChannel *, const char *, int * ); - - const char *(* GetSinkFile)( AstChannel *, int * ); - int (* TestSinkFile)( AstChannel *, int * ); - void (* ClearSinkFile)( AstChannel *, int * ); - void (* SetSinkFile)( AstChannel *, const char *, int * ); -} AstChannelVtab; - -/* Define a private structure type used to store linked lists of - name-value associations. */ -typedef struct AstChannelValue { - struct AstChannelValue *flink; /* Link to next element */ - struct AstChannelValue *blink; /* Link to previous element */ - char *name; /* Pointer to name string */ - union { /* Holds pointer to value */ - char *string; /* Pointer to string value */ - AstObject *object; /* Pointer to Object value */ - } ptr; - int is_object; /* Whether value is an Object (else string) */ -} AstChannelValue; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstChannelGlobals { - AstChannelVtab Class_Vtab; - int Class_Init; - int AstReadClassData_Msg; - char GetAttrib_Buff[ AST__CHANNEL_GETATTRIB_BUFF_LEN + 1 ]; - int Items_Written; - int Current_Indent; - int Nest; - int Nwrite_Invoc; - char **Object_Class; - AstChannelValue **Values_List; - char **Values_Class; - int *Values_OK; - int *End_Of_Object; - void *Channel_Data; -} AstChannelGlobals; - -#endif - - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Channel) /* Check class membership */ -astPROTO_ISA(Channel) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstChannel *astChannel_( const char *(*)( void ), void (*)( const char * ), - const char *, int *, ...); -#else -AstChannel *astChannelId_( const char *(*)( void ), void (*)( const char * ), - const char *, ... )__attribute__((format(printf,3,4))); -AstChannel *astChannelForId_( const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), - const char *, int * ), - const char *, ... ); -#endif - - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstChannel *astInitChannel_( void *, size_t, int, AstChannelVtab *, - const char *, const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), - const char *, int * ), int * ); - - -/* Vtab initialiser. */ -void astInitChannelVtab_( AstChannelVtab *, const char *, int * ); - -/* Loader. */ -AstChannel *astLoadChannel_( void *, size_t, AstChannelVtab *, - const char *, AstChannel *channel, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitChannelGlobals_( AstChannelGlobals * ); -#endif -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -AstObject *astRead_( AstChannel *, int * ); -int astWrite_( AstChannel *, AstObject *, int * ); -void astPutChannelData_( AstChannel *, void *, int * ); -void *astChannelData_( void ); -struct AstKeyMap *astWarnings_( AstChannel *, int * ); - -char *astSourceWrap_( const char *(*)( void ), int * ); -void astSinkWrap_( void (*)( const char * ), const char *, int * ); - -# if defined(astCLASS) /* Protected */ -void astStoreChannelData_( AstChannel *, int * ); -AstObject *astReadObject_( AstChannel *, const char *, AstObject *, int * ); -char *astGetNextText_( AstChannel *, int * ); -char *astReadString_( AstChannel *, const char *, const char *, int * ); -double astReadDouble_( AstChannel *, const char *, double, int * ); -int astGetComment_( AstChannel *, int * ); -int astGetFull_( AstChannel *, int * ); -int astGetStrict_( AstChannel *, int * ); -int astReadInt_( AstChannel *, const char *, int, int * ); -int astTestComment_( AstChannel *, int * ); -int astTestFull_( AstChannel *, int * ); -int astTestStrict_( AstChannel *, int * ); -void astAddWarning_( void *, int, const char *, const char *, int *, ... )__attribute__((format(printf,3,6))); -void astClearComment_( AstChannel *, int * ); -void astClearFull_( AstChannel *, int * ); -void astClearStrict_( AstChannel *, int * ); -void astGetNextData_( AstChannel *, int, char **, char **, int * ); -void astPutNextText_( AstChannel *, const char *, int * ); -void astReadClassData_( AstChannel *, const char *, int * ); -void astSetComment_( AstChannel *, int, int * ); -void astSetFull_( AstChannel *, int, int * ); -void astSetStrict_( AstChannel *, int, int * ); -void astWriteBegin_( AstChannel *, const char *, const char *, int * ); -void astWriteDouble_( AstChannel *, const char *, int, int, double, const char *, int * ); -void astWriteEnd_( AstChannel *, const char *, int * ); -void astWriteInt_( AstChannel *, const char *, int, int, int, const char *, int * ); -int astWriteInvocations_( int * ); -void astWriteIsA_( AstChannel *, const char *, const char *, int * ); -void astWriteObject_( AstChannel *, const char *, int, int, AstObject *, const char *, int * ); -void astWriteString_( AstChannel *, const char *, int, int, const char *, const char *, int * ); - -int astGetSkip_( AstChannel *, int * ); -int astTestSkip_( AstChannel *, int * ); -void astClearSkip_( AstChannel *, int * ); -void astSetSkip_( AstChannel *, int, int * ); - -int astGetReportLevel_( AstChannel *, int * ); -int astTestReportLevel_( AstChannel *, int * ); -void astClearReportLevel_( AstChannel *, int * ); -void astSetReportLevel_( AstChannel *, int, int * ); - -int astGetIndent_( AstChannel *, int * ); -int astTestIndent_( AstChannel *, int * ); -void astClearIndent_( AstChannel *, int * ); -void astSetIndent_( AstChannel *, int, int * ); - -const char *astGetSourceFile_( AstChannel *, int * ); -int astTestSourceFile_( AstChannel *, int * ); -void astClearSourceFile_( AstChannel *, int * ); -void astSetSourceFile_( AstChannel *, const char *, int * ); - -const char *astGetSinkFile_( AstChannel *, int * ); -int astTestSinkFile_( AstChannel *, int * ); -void astClearSinkFile_( AstChannel *, int * ); -void astSetSinkFile_( AstChannel *, const char *, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them to - validate their own arguments. We must use a cast when passing object - pointers (so that they can accept objects from derived classes). */ - -/* Check class membership. */ -#define astCheckChannel(this) astINVOKE_CHECK(Channel,this,0) -#define astVerifyChannel(this) astINVOKE_CHECK(Channel,this,1) - -/* Test class membership. */ -#define astIsAChannel(this) astINVOKE_ISA(Channel,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astChannel astINVOKE(F,astChannel_) -#else -#define astChannel astINVOKE(F,astChannelId_) -#define astChannelFor astINVOKE(F,astChannelForId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitChannel(mem,size,init,vtab,name,source,source_wrap,sink,sink_wrap) \ -astINVOKE(O,astInitChannel_(mem,size,init,vtab,name,source,source_wrap,sink,sink_wrap,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitChannelVtab(vtab,name) astINVOKE(V,astInitChannelVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadChannel(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadChannel_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to member functions. */ -/* ------------------------------- */ -/* Here we make use of astCheckChannel to validate Channel pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astRead(this) \ -astINVOKE(O,astRead_(astCheckChannel(this),STATUS_PTR)) -#define astWrite(this,object) \ -astINVOKE(V,astWrite_(astCheckChannel(this),astCheckObject(object),STATUS_PTR)) -#define astPutChannelData(this,data) \ -astINVOKE(V,astPutChannelData_(astCheckChannel(this),data,STATUS_PTR)) -#define astWarnings(this) \ -astINVOKE(O,astWarnings_(astCheckChannel(this),STATUS_PTR)) - -#define astSourceWrap astSourceWrap_ -#define astSinkWrap astSinkWrap_ -#define astChannelData astChannelData_() - -#if defined(astCLASS) /* Protected */ -#define astAddWarning astAddWarning_ -#define astStoreChannelData(this) \ -astStoreChannelData_(astCheckChannel(this),STATUS_PTR) - -#define astClearComment(this) \ -astINVOKE(V,astClearComment_(astCheckChannel(this),STATUS_PTR)) -#define astClearFull(this) \ -astINVOKE(V,astClearFull_(astCheckChannel(this),STATUS_PTR)) -#define astClearStrict(this) \ -astINVOKE(V,astClearStrict_(astCheckChannel(this),STATUS_PTR)) -#define astGetComment(this) \ -astINVOKE(V,astGetComment_(astCheckChannel(this),STATUS_PTR)) -#define astGetFull(this) \ -astINVOKE(V,astGetFull_(astCheckChannel(this),STATUS_PTR)) -#define astGetNextData(this,begin,name,val) \ -astINVOKE(V,astGetNextData_(astCheckChannel(this),begin,name,val,STATUS_PTR)) -#define astGetNextText(this) \ -astINVOKE(V,astGetNextText_(astCheckChannel(this),STATUS_PTR)) -#define astGetStrict(this) \ -astINVOKE(V,astGetStrict_(astCheckChannel(this),STATUS_PTR)) -#define astPutNextText(this,line) \ -astINVOKE(V,astPutNextText_(astCheckChannel(this),line,STATUS_PTR)) -#define astReadClassData(this,class) \ -astINVOKE(V,astReadClassData_(astCheckChannel(this),class,STATUS_PTR)) -#define astReadDouble(this,name,def) \ -astINVOKE(V,astReadDouble_(astCheckChannel(this),name,def,STATUS_PTR)) -#define astReadInt(this,name,def) \ -astINVOKE(V,astReadInt_(astCheckChannel(this),name,def,STATUS_PTR)) -#define astReadObject(this,name,def) \ -astINVOKE(O,astReadObject_(astCheckChannel(this),name,(def)?astCheckObject(def):NULL,STATUS_PTR)) -#define astReadString(this,name,def) \ -astINVOKE(V,astReadString_(astCheckChannel(this),name,def,STATUS_PTR)) -#define astSetComment(this,value) \ -astINVOKE(V,astSetComment_(astCheckChannel(this),value,STATUS_PTR)) -#define astSetFull(this,value) \ -astINVOKE(V,astSetFull_(astCheckChannel(this),value,STATUS_PTR)) -#define astSetStrict(this,value) \ -astINVOKE(V,astSetStrict_(astCheckChannel(this),value,STATUS_PTR)) -#define astTestComment(this) \ -astINVOKE(V,astTestComment_(astCheckChannel(this),STATUS_PTR)) -#define astTestFull(this) \ -astINVOKE(V,astTestFull_(astCheckChannel(this),STATUS_PTR)) -#define astTestStrict(this) \ -astINVOKE(V,astTestStrict_(astCheckChannel(this),STATUS_PTR)) -#define astWriteBegin(this,class,comment) \ -astINVOKE(V,astWriteBegin_(astCheckChannel(this),class,comment,STATUS_PTR)) -#define astWriteDouble(this,name,set,helpful,value,comment) \ -astINVOKE(V,astWriteDouble_(astCheckChannel(this),name,set,helpful,value,comment,STATUS_PTR)) -#define astWriteEnd(this,class) \ -astINVOKE(V,astWriteEnd_(astCheckChannel(this),class,STATUS_PTR)) -#define astWriteInt(this,name,set,helpful,value,comment) \ -astINVOKE(V,astWriteInt_(astCheckChannel(this),name,set,helpful,value,comment,STATUS_PTR)) -#define astWriteIsA(this,class,comment) \ -astINVOKE(V,astWriteIsA_(astCheckChannel(this),class,comment,STATUS_PTR)) -#define astWriteObject(this,name,set,helpful,value,comment) \ -astINVOKE(V,astWriteObject_(astCheckChannel(this),name,set,helpful,astCheckObject(value),comment,STATUS_PTR)) -#define astWriteString(this,name,set,helpful,value,comment) \ -astINVOKE(V,astWriteString_(astCheckChannel(this),name,set,helpful,value,comment,STATUS_PTR)) - -#define astWriteInvocations astWriteInvocations_(STATUS_PTR) - -#define astClearSkip(this) \ -astINVOKE(V,astClearSkip_(astCheckChannel(this),STATUS_PTR)) -#define astGetSkip(this) \ -astINVOKE(V,astGetSkip_(astCheckChannel(this),STATUS_PTR)) -#define astSetSkip(this,value) \ -astINVOKE(V,astSetSkip_(astCheckChannel(this),value,STATUS_PTR)) -#define astTestSkip(this) \ -astINVOKE(V,astTestSkip_(astCheckChannel(this),STATUS_PTR)) - -#define astClearReportLevel(this) \ -astINVOKE(V,astClearReportLevel_(astCheckChannel(this),STATUS_PTR)) -#define astGetReportLevel(this) \ -astINVOKE(V,astGetReportLevel_(astCheckChannel(this),STATUS_PTR)) -#define astSetReportLevel(this,value) \ -astINVOKE(V,astSetReportLevel_(astCheckChannel(this),value,STATUS_PTR)) -#define astTestReportLevel(this) \ -astINVOKE(V,astTestReportLevel_(astCheckChannel(this),STATUS_PTR)) - -#define astClearIndent(this) \ -astINVOKE(V,astClearIndent_(astCheckChannel(this),STATUS_PTR)) -#define astGetIndent(this) \ -astINVOKE(V,astGetIndent_(astCheckChannel(this),STATUS_PTR)) -#define astSetIndent(this,value) \ -astINVOKE(V,astSetIndent_(astCheckChannel(this),value,STATUS_PTR)) -#define astTestIndent(this) \ -astINVOKE(V,astTestIndent_(astCheckChannel(this),STATUS_PTR)) - -#define astClearSourceFile(this) \ -astINVOKE(V,astClearSourceFile_(astCheckChannel(this),STATUS_PTR)) -#define astGetSourceFile(this) \ -astINVOKE(V,astGetSourceFile_(astCheckChannel(this),STATUS_PTR)) -#define astSetSourceFile(this,value) \ -astINVOKE(V,astSetSourceFile_(astCheckChannel(this),value,STATUS_PTR)) -#define astTestSourceFile(this) \ -astINVOKE(V,astTestSourceFile_(astCheckChannel(this),STATUS_PTR)) - -#define astClearSinkFile(this) \ -astINVOKE(V,astClearSinkFile_(astCheckChannel(this),STATUS_PTR)) -#define astGetSinkFile(this) \ -astINVOKE(V,astGetSinkFile_(astCheckChannel(this),STATUS_PTR)) -#define astSetSinkFile(this,value) \ -astINVOKE(V,astSetSinkFile_(astCheckChannel(this),value,STATUS_PTR)) -#define astTestSinkFile(this) \ -astINVOKE(V,astTestSinkFile_(astCheckChannel(this),STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/chebymap.c b/ast/chebymap.c deleted file mode 100644 index 29f544b..0000000 --- a/ast/chebymap.c +++ /dev/null @@ -1,2404 +0,0 @@ -/* To do: - - - what to do about input positions that fall outside the bounding box. - Have an attribute that can be used to select "set bad" or "extrapolate"? - - - what about overriding astRate ? - - - Providing an iterative inverse requires the Jacobian to be defined. - - for a PolyMap: if y = C.x^n then y' = n.C.x^n-1 - for a ChebyMap: if y = C.Tn(x) then y' = n.C.Un-1(x) - - where Un-1(x) is the Chebyshev polynomial of the second kind, degree - (n-1), evaluated at x. Since PolyMap.GetJacobian function uses PolyMaps - to express the Jacobian of a PolyMap, it would need to use ChebyMaps - to express the Jacobian of a ChebyMap. But this would mean that - ChebyMap needs to be able to represent Chebyshev polynomials of the - second type. In fact the set of powers associated with each coefficient - would need to indicate somehow whether to use type 1 or type 2 for - each power. Could use negative powers to indicate type 2, but PolyMap.StoreArrays - objects to negative powers. StoreArrays could just store them - without checking, and then call a virtual function to verify the powers - are OK. - - Simpler for the moment just to disable iterative inverses in - ChebyMap. - -*/ - - -/* -*class++ -* Name: -* ChebyMap - -* Purpose: -* Map coordinates using Chebyshev polynomial functions. - -* Constructor Function: -c astChebyMap -f AST_CHEBYMAP - -* Description: -* A ChebyMap is a form of Mapping which performs a Chebyshev polynomial -* transformation. Each output coordinate is a linear combination of -* Chebyshev polynomials of the first kind, of order zero up to a -* specified maximum order, evaluated at the input coordinates. The -* coefficients to be used in the linear combination are specified -* separately for each output coordinate. -* -* For a 1-dimensional ChebyMap, the forward transformation is defined -* as follows: -* -* f(x) = c0.T0(x') + c1.T1(x') + c2.T2(x') + ... -* -* where: -* - Tn(x') is the nth Chebyshev polynomial of the first kind: -* - T0(x') = 1 -* - T1(x') = x' -* - Tn+1(x') = 2.x'.Tn(x') + Tn-1(x') -* - x' is the inpux axis value, x, offset and scaled to the range -* [-1, 1] as x ranges over a specified bounding box, given when the -* ChebyMap is created. The input positions, x, supplied to the -* forward transformation must fall within the bounding box - bad -* axis values (AST__BAD) are generated for points outside the -* bounding box. -* -* For an N-dimensional ChebyMap, the forward transformation is a -* generalisation of the above form. Each output axis value is the sum -c of "ncoeff" -f of NCOEFF -* terms, where each term is the product of a single coefficient -* value and N factors of the form Tn(x'_i), where "x'_i" is the -* normalised value of the i'th input axis value. -* -* The forward and inverse transformations are defined independantly -* by separate sets of coefficients, supplied when the ChebyMap is -* created. If no coefficients are supplied to define the inverse -* transformation, the -c astPolyTran -f AST_POLYTRAN -* method of the parent PolyMap class can instead be used to create an -* inverse transformation. The inverse transformation so generated -* will be a Chebyshev polynomial with coefficients chosen to minimise -* the residuals left by a round trip (forward transformation followed -* by inverse transformation). - -* Inheritance: -* The ChebyMap class inherits from the PolyMap class. - -* Attributes: -* The ChebyMap class does not define any new attributes beyond those -* which are applicable to all PolyMaps. - -* Functions: -c In addition to those functions applicable to all PolyMap, the -c following functions may also be applied to all ChebyMaps: -f In addition to those routines applicable to all PolyMap, the -f following routines may also be applied to all ChebyMaps: -* -c - astChebyDomain: Get the bounds of the domain of the ChebyMap -f - AST_CHEBYDOMAIN: Get the bounds of the domain of the ChebyMap - -* Copyright: -* Copyright (C) 2017 East Asian Observatory. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (EAO) - -* History: -* 1-MAR-2017 (DSB): -* Original version. -* 30-MAR-2017 (DSB): -* Over-ride the astFitPoly1DInit and astFitPoly2DInit virtual -* functions inherited form the PolyMap class. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS ChebyMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "polymap.h" /* Polynomial mappings (parent class) */ -#include "cmpmap.h" /* Compound mappings */ -#include "chebymap.h" /* Interface definition for this class */ -#include "unitmap.h" /* Unit mappings */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static int (* parent_equal)( AstObject *, AstObject *, int * ); -static void (* parent_polypowers)( AstPolyMap *, double **, int, const int *, double **, int, int, int * ); -static AstPolyMap *(*parent_polytran)( AstPolyMap *, int, double, double, int, const double *, const double *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(ChebyMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(ChebyMap,Class_Init) -#define class_vtab astGLOBAL(ChebyMap,Class_Vtab) - -#include - - -#else - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstChebyMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstChebyMap *astChebyMapId_( int, int, int, const double[], int, const double[], - const double[], const double[], const double[], - const double[], const char *, ... ); - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPolyMap *PolyTran( AstPolyMap *, int, double, double, int, const double *, const double *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetIterInverse( AstPolyMap *, int * ); -static int GetObjSize( AstObject *, int * ); -static void ChebyDomain( AstChebyMap *, int, double *, double *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *obj, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void PolyPowers( AstPolyMap *, double **, int, const int *, double **, int, int, int *); -static void FitPoly1DInit( AstPolyMap *, int, double **, AstMinPackData *, double *, int *); -static void FitPoly2DInit( AstPolyMap *, int, double **, AstMinPackData *, double *, int *); - -/* Member functions. */ -/* ================= */ - -static void ChebyDomain( AstChebyMap *this, int forward, double *lbnd, - double *ubnd, int *status ){ -/* -*++ -* Name: -c astChebyDomain -f AST_CHEBYDOMAIN - -* Purpose: -* Returns the bounding box of the domain of a ChebyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "chebymap.h" -c void astChebyDomain( AstChebyMap *this, int forward, double *lbnd, -c double *ubnd ) -f CALL AST_CHEBYDOMAIN( THIS, FORWARD, LBND, UBND, STATUS ) - -* Class Membership: -* ChebyMap method. - -* Description: -c This function -f This routine -* returns the upper and lower limits of the box defining the domain -* of either the forward or inverse transformation of a ChebyMap. These -* are the values that were supplied when the ChebyMap was created. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the ChebyMap. -c forward -f FORWARD = LOGICAL (Given) -c A non-zero -f A .TRUE. -* value indicates that the domain of the ChebyMap's -* forward transformation is to be returned, while a zero -* value indicates that the domain of the inverse transformation -* should be returned. -c lbnd -f LBND() = DOUBLE PRECISION (Returned) -c Pointer to an -f An -* array in which to return the lower axis bounds of the ChebyMap -* domain. The number of elements should be at least equal to the -* number of ChebyMap inputs (if -c "forward" is non-zero), or outputs (if "forward" is zero). -f FORWARD is .TRUE.), or outputs (if FORWARD is .FALSE.). -c ubnd -f UBND() = DOUBLE PRECISION (Returned) -c Pointer to an -f An -* array in which to return the upper axis bounds of the ChebyMap -* domain. The number of elements should be at least equal to the -* number of ChebyMap inputs (if -c "forward" is non-zero), or outputs (if "forward" is zero). -f FORWARD is .TRUE.), or outputs (if FORWARD is .FALSE.). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the requested transformation is undefined (i.e. no -* transformation coefficients were specified when the ChebyMap was -* created), this method returns a box determined using the -c astMapBox -f AST_MAPBOX -* method on the opposite transformation, if the opposite -* transformation is defined. -* - If the above procedure fails to determine a bounding box, the supplied -* arrays are filled with AST__BAD values but no error is reported. - -*-- -*/ - -/* Local Variables: */ - double *lbnd_o; - double *offset_o; - double *offset; - double *scale_o; - double *scale; - double *ubnd_o; - int fwd_o; - int iax; - int nax; - int nax_o; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Get the scales and offsets to use, depending on the value of "forward" - and whether the ChebyMap has been inverted. */ - if( forward != astGetInvert( this ) ) { - scale = this->scale_f; - offset = this->offset_f; - nax = astGetNin( this ); - scale_o = this->scale_i; - offset_o = this->offset_i; - nax_o = astGetNout( this ); - fwd_o = 0; - } else { - scale = this->scale_i; - offset = this->offset_i; - nax = astGetNout( this ); - scale_o = this->scale_f; - offset_o = this->offset_f; - nax_o = astGetNin( this ); - fwd_o = 1; - } - -/* Check the domain is defined. */ - if( scale && offset ) { - for( iax = 0; iax < nax; iax++ ) { - if( scale[ iax ] != 0.0 ) { - lbnd[ iax ] = ( -1.0 - offset[ iax ] ) / scale[ iax ]; - ubnd[ iax ] = ( 1.0 - offset[ iax ] ) / scale[ iax ]; - } else { - lbnd[ iax ] = AST__BAD; - ubnd[ iax ] = AST__BAD; - } - } - -/* If the requested domain is not defined, see if it can be determined - by transforming the domain of the other transformation into the - requested input ot putput space. */ - } else if( scale_o && offset_o ){ - -/* Allocate memory to hold the bounding box in the other space (input or - output), and then store the bounding box values. */ - lbnd_o = astMalloc( nax_o*sizeof( *lbnd_o ) ); - ubnd_o = astMalloc( nax_o*sizeof( *ubnd_o ) ); - if( astOK ) { - for( iax = 0; iax < nax_o; iax++ ) { - if( scale_o[ iax ] != 0.0 ) { - lbnd_o[ iax ] = ( -1.0 - offset_o[ iax ] ) / scale_o[ iax ]; - ubnd_o[ iax ] = ( 1.0 - offset_o[ iax ] ) / scale_o[ iax ]; - } else { - lbnd_o[ iax ] = AST__BAD; - ubnd_o[ iax ] = AST__BAD; - } - } - -/* Loop round finding the bounds on each input axis of the requested - transformation. */ - for( iax = 0; iax < nax; iax++ ) { - astMapBox( this, lbnd_o, ubnd_o, fwd_o, iax, lbnd + iax, - ubnd + iax, NULL, NULL ); - } - -/* Free resources */ - lbnd_o = astFree( lbnd_o ); - ubnd_o = astFree( ubnd_o ); - } - - -/* If the domain of the other transformation is not defined, return bad values. */ - } else { - for( iax = 0; iax < nax; iax++ ) { - lbnd[ iax ] = AST__BAD; - ubnd[ iax ] = AST__BAD; - } - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two ChebyMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "chebymap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* ChebyMap member function (over-rides the astEqual protected -* method inherited from the astPolyMap class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two ChebyMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a ChebyMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the ChebyMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstChebyMap *that; - AstChebyMap *this; - int i; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the Equal method inherited from the parent PolyMap class. This - checks that the PolyMaps are equal. */ - result = (*parent_equal)( this_object, that_object, status ); - if( result ) { - -/* Obtain pointers to the two ChebyMap structures. */ - this = (AstChebyMap *) this_object; - that = (AstChebyMap *) that_object; - -/* Check the second object is a ChebyMap. We know the first is a - ChebyMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAChebyMap( that ) ) { - -/* Get the number of axes in the input bounding box (the original input space). */ - nin = astGetInvert( this ) ? astGetNout( this ) : astGetNin( this ); - -/* Check the bounding box is the same for both ChebyMaps. */ - if( this->scale_f && that->scale_f && - this->offset_f && that->offset_f ) { - for( i = 0; i < nin && result; i++ ) { - if( !astEQUAL( this->scale_f[ i ], that->scale_f[ i ] ) || - !astEQUAL( this->offset_f[ i ], that->offset_f[ i ] )){ - result = 0; - } - } - } else if( this->scale_f || that->scale_f || - this->offset_f || that->offset_f ) { - result = 0; - } - -/* Get the number of axes in the output bounding box (the original output space). */ - nout = astGetInvert( this ) ? astGetNin( this ) : astGetNout( this ); - -/* Check the bounding box is the same for both ChebyMaps. */ - if( this->scale_i && that->scale_i && - this->offset_i && that->offset_i ) { - for( i = 0; i < nout && result; i++ ) { - if( !astEQUAL( this->scale_i[ i ], that->scale_i[ i ] ) || - !astEQUAL( this->offset_i[ i ], that->offset_i[ i ] )){ - result = 0; - } - } - } else if( this->scale_i || that->scale_i || - this->offset_i || that->offset_i ) { - result = 0; - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void FitPoly1DInit( AstPolyMap *this_polymap, int forward, double **table, - AstMinPackData *data, double *scales, int *status ){ -/* -* Name: -* FitPoly1DInit - -* Purpose: -* Perform initialisation needed for FitPoly1D - -* Type: -* Private function. - -* Synopsis: -* #include "chebymap.h" -* void FitPoly1DInit( AstPolyMap *this, int forward, double **table, -* AstMinPackData *data, double *scales, int *status ) - -* Class Membership: -* ChebyMap member function (over-rides the astFitPoly1DInit protected -* method inherited from the PolyMap class). - -* Description: -* This function performs initialisation needed for FitPoly1D in the -* PolyMap class. - -* Parameters: -* this -* Pointer to the PolyMap. -* forward -* Non-zero if the forward transformation of "this" is being -* replaced. Zero if the inverse transformation of "this" is being -* replaced. -* table -* Pointer to an array of 2 pointers. Each of these pointers points -* to an array of "nsamp" doubles, being the scaled and sampled values -* for x1 and y1 in that order. -* data -* Pointer to a structure holding information to pass the the -* service function invoked by the minimisation function. -* scales -* Array holding the scaling factors for the two columns of the table. -* Multiplying the table values by the scale factor produces PolyMap -* input or output axis values. The scales are modified on exit to -* take account of the scaling performed by the ChebyMap Transform -* method. -*/ - -/* Local Variables; */ - AstChebyMap *this; - double *px1; - double *pxp1; - double maxx; - double minx; - double off; - double pmax; - double pmin; - double scl; - double x1; - int k; - int w1; - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the ChebyMap structure. */ - this = (AstChebyMap *) this_polymap; - -/* Find the bounds of the supplied x1 values. */ - px1 = table[ 0 ]; - minx = *px1; - maxx = *px1; - px1++; - for( k = 1; k < data->nsamp; k++,px1++ ) { - if( *px1 > maxx ) { - maxx = *px1; - } else if( *px1 < minx ) { - minx = *px1; - } - } - -/* Transform the above limits from table values into PolyMap axis values. */ - pmax = maxx*scales[ 0 ]; - pmin = minx*scales[ 0 ]; - -/* Calculate the scale and offset that map the above bounds onto the range - [-1,+1], and store them in the ChebyMap. */ - if( pmax != pmin ) { - scl = 2.0/( pmax - pmin ); - off = -( pmax + pmin )/( pmax - pmin ); - } else if( astOK ){ - astError( AST__BADBX, "astPolyTran(%s): New bounding box has zero width " - "on axis 1.", status, astGetClass(this)); - } - - if( forward ) { - this->scale_f = (double *) astFree( this->scale_f ); - this->offset_f = (double *) astFree( this->offset_f ); - - this->scale_f = (double *) astMalloc( sizeof( double ) ); - this->offset_f = (double *) astMalloc( sizeof( double ) ); - if( astOK ) { - this->scale_f[ 0 ] = scl; - this->offset_f[ 0 ] = off; - } - } else { - this->scale_i = (double *) astFree( this->scale_i ); - this->offset_i = (double *) astFree( this->offset_i ); - - this->scale_i = (double *) astMalloc( sizeof( double ) ); - this->offset_i = (double *) astMalloc( sizeof( double ) ); - if( astOK ) { - this->scale_i[ 0 ] = scl; - this->offset_i[ 0 ] = off; - } - } - -/* Get pointers to the supplied x1 values. */ - px1 = table[ 0 ]; - -/* Get pointers to the location for the next "power" of x1. Here "X to - the power N" is a metaphor for Tn(x). */ - pxp1 = data->xp1; - -/* Loop round all samples. */ - for( k = 0; k < data->nsamp; k++ ) { - -/* Get the current x1 value, and scale it into the range [-1,+1]. */ - x1 = *(px1++)*scl*scales[0] + off; - -/* Find all the required "powers" of x1 and store them in the "xp1" - component of the data structure. */ - *(pxp1++) = 1.0; - *(pxp1++) = x1; - for( w1 = 2; w1 < data->order; w1++,pxp1++ ) { - pxp1[ 0 ] = 2.0*x1*pxp1[ -1 ] - pxp1[ -2 ]; - } - } - -/* The scaling representing by the scales[0] value will be performed by - the astTransform method of the ChebyMap class, so reset teh scales[0] - value to unity, to avoid the scaling being applied twice. */ - scales[ 0 ] = 1.0; - -} - -static void FitPoly2DInit( AstPolyMap *this_polymap, int forward, double **table, - AstMinPackData *data, double *scales, int *status ){ -/* -* Name: -* FitPoly2DInit - -* Purpose: -* Perform initialisation needed for FitPoly2D - -* Type: -* Private function. - -* Synopsis: -* #include "chebymap.h" -* void FitPoly2DInit( AstPolyMap *this, int forward, double **table, -* AstMinPackData *data, double *scales, int *status ) - -* Class Membership: -* ChebyMap member function (over-rides the astFitPoly2DInit protected -* method inherited from the PolyMap class). - -* Description: -* This function performs initialisation needed for FitPoly2D in the -* PolyMap class.. - -* Parameters: -* this -* Pointer to the PolyMap. -* forward -* Non-zero if the forward transformation of "this" is being -* replaced. Zero if the inverse transformation of "this" is being -* replaced. -* table -* Pointer to an array of 4 pointers. Each of these pointers points -* to an array of "nsamp" doubles, being the scaled and sampled values -* for x1, x2, y1 or y2 in that order. -* data -* Pointer to a structure holding information to pass the the -* service function invoked by the minimisation function. -* scales -* Array holding the scaling factors for the four columns of the table. -* Multiplying the table values by the scale factor produces PolyMap -* input or output axis values. -*/ - -/* Local Variables; */ - AstChebyMap *this; - double *px1; - double *px2; - double *pxp1; - double *pxp2; - double maxx; - double maxy; - double minx; - double miny; - double off[ 2 ]; - double pxmax; - double pxmin; - double pymax; - double pymin; - double scl[ 2 ]; - double x1; - double x2; - int k; - int w1; - int w2; - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the ChebyMap structure. */ - this = (AstChebyMap *) this_polymap; - -/* Find the bounds of the supplied x1 and x2 values. */ - px1 = table[ 0 ]; - px2 = table[ 1 ]; - minx = *px1; - maxx = *px1; - miny = *px2; - maxy = *px2; - px1++; - px2++; - for( k = 1; k < data->nsamp; k++,px1++,px2++ ) { - if( *px1 > maxx ) { - maxx = *px1; - } else if( *px1 < minx ) { - minx = *px1; - } - if( *px2 > maxy ) { - maxy = *px2; - } else if( *px2 < miny ) { - miny = *px2; - } - } - -/* Transform the above limits from table values into PolyMap axis values. */ - pxmax = maxx*scales[ 0 ]; - pxmin = minx*scales[ 0 ]; - pymax = maxy*scales[ 1 ]; - pymin = miny*scales[ 1 ]; - -/* Calculate the scale and offset that map the above bounds onto the range - [-1,+1], and store them in the ChebyMap. */ - if( pxmax != pxmin && pymax != pymin ) { - scl[ 0 ] = 2.0/( pxmax - pxmin ); - off[ 0 ] = -( pxmax + pxmin )/( pxmax - pxmin ); - scl[ 1 ] = 2.0/( pymax - pymin ); - off[ 1 ] = -( pymax + pymin )/( pymax - pymin ); - } else if( astOK ){ - astError( AST__BADBX, "astPolyTran(%s): New bounding box has zero width " - "on or both axes.", status, astGetClass(this)); - } - - if( forward ) { - this->scale_f = (double *) astFree( this->scale_f ); - this->offset_f = (double *) astFree( this->offset_f ); - - this->scale_f = (double *) astMalloc( 2*sizeof( double ) ); - this->offset_f = (double *) astMalloc( 2*sizeof( double ) ); - if( astOK ) { - this->scale_f[ 0 ] = scl[ 0 ]; - this->offset_f[ 0 ] = off[ 0 ]; - this->scale_f[ 1 ] = scl[ 1 ]; - this->offset_f[ 1 ] = off[ 1 ]; - } - } else { - this->scale_i = (double *) astFree( this->scale_i ); - this->offset_i = (double *) astFree( this->offset_i ); - - this->scale_i = (double *) astMalloc( 2*sizeof( double ) ); - this->offset_i = (double *) astMalloc( 2*sizeof( double ) ); - if( astOK ) { - this->scale_i[ 0 ] = scl[ 0 ]; - this->offset_i[ 0 ] = off[ 0 ]; - this->scale_i[ 1 ] = scl[ 1 ]; - this->offset_i[ 1 ] = off[ 1 ]; - } - } - -/* Get pointers to the supplied x1 and x2 values. */ - px1 = table[ 0 ]; - px2 = table[ 1 ]; - -/* Get pointers to the location for the next "power" of x1 anmd x2. Here "X to - the power N" is a metaphor for Tn(x). */ - pxp1 = data->xp1; - pxp2 = data->xp2; - -/* Loop round all samples. */ - for( k = 0; k < data->nsamp; k++ ) { - -/* Get the current x1 and x2 values, and scale them into the range [-1,+1]. */ - x1 = *(px1++)*scl[0]*scales[0] + off[0]; - x2 = *(px2++)*scl[1]*scales[1] + off[1]; - -/* Find all the required "powers" of x1 and store them in the "xp1" - component of the data structure. */ - *(pxp1++) = 1.0; - *(pxp1++) = x1; - for( w1 = 2; w1 < data->order; w1++,pxp1++ ) { - pxp1[ 0 ] = 2.0*x1*pxp1[ -1 ] - pxp1[ -2 ]; - } - -/* Find all the required "powers" of x2 and store them in the "xp2" - component of the data structure. */ - *(pxp2++) = 1.0; - *(pxp2++) = x2; - for( w2 = 2; w2 < data->order; w2++,pxp2++ ) { - pxp2[ 0 ] = 2.0*x2*pxp2[ -1 ] - pxp2[ -2 ]; - } - } - -/* The scaling representing by the scales[0] and scales[1] values will be - performed by the astTransform method of the ChebyMap class, so reset the - scales[0] and scales[1] values to unity, to avoid the scaling being - applied twice. */ - scales[ 0 ] = 1.0; - scales[ 1 ] = 1.0; - -} - -static int GetIterInverse( AstPolyMap *this, int *status ) { -/* -* Name: -* GetIterInverse - -* Purpose: -* Return the value of the IterInverse attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* int GetIterInverse( AstObject *this, int *status ) - -* Class Membership: -* ChebyMap member function (over-rides the astGetIterInverse protected -* method inherited from the parent PolyMap class). - -* Description: -* This function returns the value of the IterInverse attribute, which -* is always zero for a ChebyMap. - -* Parameters: -* this -* Pointer to the ChebyMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The IterInverse value. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - - return 0; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "chebymap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* ChebyMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied ChebyMap, -* in bytes. - -* Parameters: -* this -* Pointer to the ChebyMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstChebyMap *this; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the ChebyMap structure. */ - this = (AstChebyMap *) this_object; - -/* Get the number of input and output axes. */ - nin = astGetInvert( this ) ? astGetNout( this ) : astGetNin( this ); - nout = astGetInvert( this ) ? astGetNin( this ) : astGetNout( this ); - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - if( this->scale_f ) result += nin*sizeof( *this->scale_f ); - if( this->offset_f ) result += nin*sizeof( *this->offset_f ); - if( this->scale_i ) result += nout*sizeof( *this->scale_i ); - if( this->offset_i ) result += nout*sizeof( *this->offset_i ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -void astInitChebyMapVtab_( AstChebyMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitChebyMapVtab - -* Purpose: -* Initialise a virtual function table for a ChebyMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "chebymap.h" -* void astInitChebyMapVtab( AstChebyMapVtab *vtab, const char *name ) - -* Class Membership: -* ChebyMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the ChebyMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstPolyMapVtab *polymap; /* Pointer to PolyMap component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitPolyMapVtab( (AstPolyMapVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAChebyMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstPolyMapVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ -/* none */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - polymap = (AstPolyMapVtab *) vtab; - - polymap->GetIterInverse = GetIterInverse; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_polypowers = polymap->PolyPowers; - polymap->PolyPowers = PolyPowers; - - parent_polytran = polymap->PolyTran; - polymap->PolyTran = PolyTran; - - parent_equal = object->Equal; - object->Equal = Equal; - - polymap->FitPoly1DInit = FitPoly1DInit; - polymap->FitPoly2DInit = FitPoly2DInit; - -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->ChebyDomain = ChebyDomain; - -/* Declare the destructor and copy constructor. */ - astSetDelete( (AstObjectVtab *) vtab, Delete ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - -/* Declare the class dump function. */ - astSetDump( vtab, Dump, "ChebyMap", "Chebyshev polynomial transformation" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void PolyPowers( AstPolyMap *this_polymap, double **work, int ncoord, - const int *mxpow, double **ptr, int point, int fwd, - int *status ){ -/* -* Name: -* PolyPowers - -* Purpose: -* Find the required powers of the input axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "chebymap.h" -* void PolyPowers( AstPolyMap *this, double **work, int ncoord, -* const int *mxpow, double **ptr, int point, -* int fwd, int *status ) - -* Class Membership: -* ChebyMap member function (over-rides the astPolyPowers protected -* method inherited from the PolyMap class). - -* Description: -* This function is used by astTransform to calculate the powers of -* the axis values for a single input position. In the case of -* sub-classes, the powers may not be simply powers of the supplied -* axis values but may be more complex quantities such as a Chebyshev -* polynomial of the required degree evaluated at the input axis values. - -* Parameters: -* this -* Pointer to the PolyMap. -* work -* An array of "ncoord" pointers, each pointing to an array of -* length "max(2,mxpow)". The required values are placed in this -* array on exit. -* ncoord -* The number of axes. -* mxpow -* Pointer to an array holding the maximum power required of each -* axis value. Should have "ncoord" elements. -* ptr -* An array of "ncoord" pointers, each pointing to an array holding -* the axis values. Each of these arrays of axis values must have -* at least "point+1" elements. -* point -* The zero based index of the point within "ptr" that holds the -* axis values to be exponentiated. -* fwd -* Do the supplied coefficients define the foward transformation of -* the PolyMap? -*/ - -/* Local Variables; */ - AstChebyMap *this; - double *scales; - double *offsets; - double *pwork; - double *t; - double x; - int coord; - int ip; - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the ChebyMap structure. */ - this = (AstChebyMap *) this_polymap; - -/* Either transformation of a ChebyMap (forward or inverse) can be - defined either as Chebyshev polynomial or as a standard polynomial. - Chebyshev polynomials always have non-NULL scale array pointers. - If the scale array pointer is NULL, then the transformation is a - standard polynomial. If the coefficients relate to a standard - polynomial, then invoke the astPolyPowers implementation of the parent - class (PolyMap). */ - if( (fwd && !this->scale_f) || (!fwd && !this->scale_i) ) { - (*parent_polypowers)( this_polymap, work, ncoord, mxpow, ptr, point, - fwd, status ); - -/* If the coefficients relate to a Chebyshev polynomial... */ - } else { - scales = fwd ? this->scale_f : this->scale_i; - offsets = fwd ? this->offset_f : this->offset_i; - -/* This method uses a Chebyshev polynomial of the first kind of degree "i" - evaluated at "x'" instead of "x raised to the power i". Here, "x'" is - the input axis value scaled and shifted into the range [-1,+1] on each - axis. Loop over all input axes. */ - for( coord = 0; coord < ncoord; coord++ ) { - -/* Get a pointer to the array in which the powers of the current axis - value are to be returned. */ - pwork = work[ coord ]; - -/* The Chebyshev function (type 1) of degree zero is always 1.0, regardless - of the value of x. */ - pwork[ 0 ] = 1.0; - -/* Get the input axis value. If it is bad, store bad values for all - remaining powers. */ - x = ptr[ coord ][ point ]; - if( x == AST__BAD ) { - for( ip = 1; ip <= mxpow[ coord ]; ip++ ) pwork[ ip ] = AST__BAD; - -/* Otherwise, apply the required scaling to the input */ - } else { - x = x*scales[ coord ] + offsets[ coord ]; - -/* Return bad values for input positions outside the bounding box - associated with the transformation. */ - if( fabs( x ) <= 1.0 ) { - -/* The Chebyshev function of degree one is equal to x. */ - t = pwork + 1; - *t = x; - -/* Form and store the remaining Chebyshev polynomial values at the input axis value. - Use the standard recurrence relation: Tn+1(x') = 2.x'.Tn(x') + Tn-1(x'). */ - for( ip = 2; ip <= mxpow[ coord ]; ip++,t++ ) { - t[ 1 ] = 2.0*x*t[ 0 ] - t[ -1 ]; - } - } else { - for( ip = 1; ip <= mxpow[ coord ]; ip++ ) pwork[ ip ] = AST__BAD; - } - } - } - } -} - -static AstPolyMap *PolyTran( AstPolyMap *this_polymap, int forward, double acc, - double maxacc, int maxorder, const double *lbnd, - const double *ubnd, int *status ){ -/* -* Name: -* PolyTran - -* Purpose: -* Fit a PolyMap inverse or forward transformation. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* AstPolyMap *PolyTran( AstPolyMap *this, int forward, double acc, -* double maxacc, int maxorder, const double *lbnd, -* const double *ubnd ) - -* Class Membership: -* ChebyMap member function (over-rides the astPolyTran method inherited -* from the PolyMap class). - -* Description: -* This function creates a new PolyMap which is a copy of the supplied -* PolyMap, in which a specified transformation (forward or inverse) -* has been replaced by a new polynomial transformation. The -* coefficients of the new transformation are estimated by sampling -* the other transformation and performing a least squares polynomial -* fit in the opposite direction to the sampled positions and values. -* -* This method can only be used on (1-input,1-output) or (2-input,2-output) -* PolyMaps. -* -* The transformation to create is specified by the "forward" parameter. -* In what follows "X" refers to the inputs of the PolyMap, and "Y" to -* the outputs of the PolyMap. The forward transformation transforms -* input values (X) into output values (Y), and the inverse transformation -* transforms output values (Y) into input values (X). Within a PolyMap, -* each transformation is represented by an independent set of -* polynomials, P_f or P_i: Y=P_f(X) for the forward transformation and -* X=P_i(Y) for the inverse transformation. -* -* The "forward" parameter specifies the transformation to be replaced. If -* it is non-zero, a new forward transformation is created by first finding -* the input values (X) using the inverse transformation -* (which must be available) at a regular grid of points (Y) covering a -* rectangular region of the PolyMap's output space. The coefficients of -* the required forward polynomial, Y=P_f(X), are chosen in order to -* minimise the sum of the squared residuals between the sampled values -* of Y and P_f(X). -* -* If "forward" is zero (probably the most likely case), -* a new inverse transformation is created by -* first finding the output values (Y) using the forward transformation -* (which must be available) at a regular grid of points (X) covering a -* rectangular region of the PolyMap's input space. The coefficients of -* the required inverse polynomial, X=P_i(Y), are chosen in order to -* minimise the sum of the squared residuals between the sampled values -* of X and P_i(Y). -* -* This fitting process is performed repeatedly with increasing -* polynomial orders (starting with linear) until the target -* accuracy is achieved, or a specified maximum order is reached. If -* the target accuracy cannot be achieved even with this maximum-order -* polynomial, the best fitting maximum-order polynomial is returned so -* long as its accuracy is better than "maxacc". -* If it is not, an error is reported. - -* Parameters: -* this -* Pointer to the original Mapping. -* forward -* If non-zero, the forward PolyMap transformation is replaced. -* Otherwise the inverse transformation is replaced. -* acc -* The target accuracy, expressed as a geodesic distance within -* the PolyMap's input space (if "forward" is zero) or output -* space (if "forward" is non-zero). -* maxacc -* The maximum allowed accuracy for an acceptable polynomial, -* expressed as a geodesic distance within the PolyMap's input -* space (if "forward" is zero) or output space (if "forward" is -* non-zero). -* maxorder -* The maximum allowed polynomial order. This is one more than the -* maximum power of either input axis. So for instance, a value of -* 3 refers to a quadratic polynomial. Note, cross terms with total -* powers greater than or equal to maxorder are not inlcuded in the -* fit. So the maximum number of terms in each of the fitted -* polynomials is maxorder*(maxorder+1)/2. -* lbnd -* Pointer to an array holding the lower bounds of a rectangular -* region within the PolyMap's input space (if "forward" is zero) -* or output space (if "forward" is non-zero). The new polynomial -* will be evaluated over this rectangle. The length of this array -* should equal the value of the PolyMap's Nin or Nout attribute, -* depending on "forward". If a NULL pointer is supplied, the lower -* bounds of the box supplied when the ChebyMap was constructed is -* used. -* ubnd -* Pointer to an -* array holding the upper bounds of a rectangular region within -* the PolyMap's input space (if "forward" is zero) or output space -* (if "forward" is non-zero). The new polynomial will be evaluated -* over this rectangle. The length of this array should equal the -* value of the PolyMap's Nin or Nout attribute, depending on "forward". -* If a NULL pointer is supplied, the upper bounds of the box supplied -* when the ChebyMap was constructed is used. - -* Returned Value: -* astPolyTran() -* A pointer to the new PolyMap. A NULL pointer will be returned if -* the fit fails to achieve the accuracy specified by "maxacc", but -* no error will be reported. - -* Notes: -* - This function can only be used on 1D or 2D PolyMaps which have -* the same number of inputs and outputs. -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - AstChebyMap *this; - AstPolyMap *result; - const char *word; - double *offset; - double *scale; - double this_lbnd[ 2 ]; - double this_ubnd[ 2 ]; - int inverted; - int nax; - -/* Initialise. */ - result = NULL; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Get a pointer to the CHebyMap structure. */ - this = (AstChebyMap *) this_polymap; - -/* Select the ChebyMap scales and offsets to be used. */ - inverted = astGetInvert( this ); - if( ( inverted && !forward ) || ( !inverted && forward ) ) { - word = "inverse"; - scale = this->scale_i; - offset = this->offset_i; - nax = ((AstMapping *)this)->nout; - } else { - word = "forward"; - scale = this->scale_f; - offset = this->offset_f; - nax = ((AstMapping *)this)->nin; - } - -/* The scaled box for a Chebyshev polynomial spans [-1,+1] on each axis. - Create the corresponding unscaled box. If the user supplies any bounds, - use them in preference to the bounds in the ChebyMap. */ - if( lbnd ) { - this_lbnd[ 0 ] = lbnd[ 0 ]; - if( nax > 1 ) this_lbnd[ 1 ] = lbnd[ 1 ]; - - } else if( scale && offset ) { - this_lbnd[ 0 ] = ( -1.0 - offset[ 0 ] )/scale[ 0 ]; - if( nax > 1 ) this_lbnd[ 1 ] = ( -1.0 - offset[ 1 ] )/scale[ 1 ]; - - } else if( astOK ) { - astError( AST__NOBOX, "astPolyTran(%s): The %s transformation is " - "not a Chebyshev polynomial and therefore requires a " - "user-supplied bounding box. But no lower bounds were " - "supplied. ", status, astGetClass( this ), word ); - } - - - if( ubnd ) { - this_ubnd[ 0 ] = ubnd[ 0 ]; - if( nax > 1 ) this_ubnd[ 1 ] = ubnd[ 1 ]; - } else if( scale && offset ) { - this_ubnd[ 0 ] = ( 1.0 - offset[ 0 ] )/scale[ 0 ]; - if( nax > 1 ) this_ubnd[ 1 ] = ( 1.0 - offset[ 1 ] )/scale[ 1 ]; - } else if( astOK ) { - astError( AST__NOBOX, "astPolyTran(%s): The %s transformation is " - "not a Chebyshev polynomial and therefore requires a " - "user-supplied bounding box. But no upper bounds were " - "supplied. ", status, astGetClass( this ), word ); - } - -/* Invoke the parent astPolyMap method, using the bounding box selected - above. */ - result = (*parent_polytran)( this_polymap, forward, acc, maxacc, maxorder, - this_lbnd, this_ubnd, status ); - -/* Return the new ChebyMap. */ - return result; -} - - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for ChebyMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for ChebyMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the -* coefficients associated with the input ChebyMap. -*/ - - -/* Local Variables: */ - AstChebyMap *in; /* Pointer to input ChebyMap */ - AstChebyMap *out; /* Pointer to output ChebyMap */ - int nin; /* No. of input coordinates */ - int nout; /* No. of output coordinates */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output ChebyMaps. */ - in = (AstChebyMap *) objin; - out = (AstChebyMap *) objout; - -/* Nullify the pointers stored in the output object since these will - currently be pointing at the input data (since the output is a simple - byte-for-byte copy of the input). Otherwise, the input data could be - freed by accidient if the output object is deleted due to an error - occuring in this function. */ - out->scale_f = NULL; - out->offset_f = NULL; - out->scale_i = NULL; - out->offset_i = NULL; - -/* Get the number of inputs and outputs of the uninverted Mapping. */ - nin = ( (AstMapping *) in )->nin; - nout = ( (AstMapping *) in )->nout; - -/* Copy the bounding box arrays. */ - if( in->scale_f ) out->scale_f = (double *) astStore( NULL, - (void *) in->scale_f, - sizeof( double )*nin ); - if( in->offset_f ) out->offset_f = (double *) astStore( NULL, - (void *) in->offset_f, - sizeof( double )*nin ); - if( in->scale_i ) out->scale_i = (double *) astStore( NULL, - (void *) in->scale_i, - sizeof( double )*nout ); - if( in->offset_i ) out->offset_i = (double *) astStore( NULL, - (void *) in->offset_i, - sizeof( double )*nout ); -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for ChebyMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for ChebyMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstChebyMap *this; - -/* Obtain a pointer to the ChebyMap structure. */ - this = (AstChebyMap *) obj; - -/* Free the boundib box arrays. */ - this->scale_f = astFree( this->scale_f ); - this->offset_f = astFree( this->offset_f ); - this->scale_i = astFree( this->scale_i ); - this->offset_i = astFree( this->offset_i ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for ChebyMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the ChebyMap class to an output Channel. - -* Parameters: -* this -* Pointer to the ChebyMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstChebyMap *this; /* Pointer to the ChebyMap structure */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char comm[ 100 ]; /* Buffer for comment string */ - int i; /* Loop index */ - int nin; /* No. of input coords */ - int nout; /* No. of output coords */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the ChebyMap structure. */ - this = (AstChebyMap *) this_object; - -/* Find the number of inputs and outputs of the uninverted Mapping. */ - nin = ( (AstMapping *) this )->nin; - nout = ( (AstMapping *) this )->nout; - -/* Write out values representing the instance variables for the - ChebyMap class. */ - -/* The input axis scale factors. */ - if( this->scale_f ){ - for( i = 0; i < nin; i++ ){ - (void) sprintf( buff, "FSCL%d", i + 1 ); - (void) sprintf( comm, "Scale factor on input %d", i + 1 ); - astWriteDouble( channel, buff, 1, 1, (this->scale_f)[ i ], comm ); - } - } - -/* The input axis offsets. */ - if( this->offset_f ){ - for( i = 0; i < nin; i++ ){ - (void) sprintf( buff, "FOFF%d", i + 1 ); - (void) sprintf( comm, "Offset on input %d", i + 1 ); - astWriteDouble( channel, buff, 1, 1, (this->offset_f)[ i ], comm ); - } - } - -/* The output axis scale factors. */ - if( this->scale_i ){ - for( i = 0; i < nout; i++ ){ - (void) sprintf( buff, "ISCL%d", i + 1 ); - (void) sprintf( comm, "Scale factor on output %d", i + 1 ); - astWriteDouble( channel, buff, 1, 1, (this->scale_i)[ i ], comm ); - } - } - -/* The output axis offsets. */ - if( this->offset_i ){ - for( i = 0; i < nout; i++ ){ - (void) sprintf( buff, "IOFF%d", i + 1 ); - (void) sprintf( comm, "Offset on output %d", i + 1 ); - astWriteDouble( channel, buff, 1, 1, (this->offset_i)[ i ], comm ); - } - } - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAChebyMap and astCheckChebyMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(ChebyMap,Mapping) -astMAKE_CHECK(ChebyMap) - -AstChebyMap *astChebyMap_( int nin, int nout, int ncoeff_f, const double coeff_f[], - int ncoeff_i, const double coeff_i[], - const double lbnd_f[], const double ubnd_f[], - const double lbnd_i[], const double ubnd_i[], - const char *options, int *status, ...){ -/* -*++ -* Name: -c astChebyMap -f AST_CHEBYMAP - -* Purpose: -* Create a ChebyMap. - -* Type: -* Public function. - -* Synopsis: -c #include "chebymap.h" -c AstChebyMap *astChebyMap( int nin, int nout, int ncoeff_f, const double coeff_f[], -c int ncoeff_i, const double coeff_i[], -c const double lbnd_f[], const double ubnd_f[], -c const double lbnd_i[], const double ubnd_i[], -c const char *options, ... ) -f RESULT = AST_CHEBYMAP( NIN, NOUT, NCOEFF_F, COEFF_F, NCOEFF_I, COEFF_I, -f LBND_F, UBND_F, LBND_I, UBND_I, OPTIONS, STATUS ) - -* Class Membership: -* ChebyMap constructor. - -* Description: -* This function creates a new ChebyMap and optionally initialises -* its attributes. -* -* A ChebyMap is a form of Mapping which performs a Chebyshev polynomial -* transformation. Each output coordinate is a linear combination of -* Chebyshev polynomials of the first kind, of order zero up to a -* specified maximum order, evaluated at the input coordinates. The -* coefficients to be used in the linear combination are specified -* separately for each output coordinate. -* -* For a 1-dimensional ChebyMap, the forward transformation is defined -* as follows: -* -* f(x) = c0.T0(x') + c1.T1(x') + c2.T2(x') + ... -* -* where: -* - Tn(x') is the nth Chebyshev polynomial of the first kind: -* - T0(x') = 1 -* - T1(x') = x' -* - Tn+1(x') = 2.x'.Tn(x') + Tn-1(x') -* - x' is the inpux axis value, x, offset and scaled to the range -* [-1, 1] as x ranges over a specified bounding box, given when the -* ChebyMap is created. The input positions, x, supplied to the -* forward transformation must fall within the bounding box - bad -* axis values (AST__BAD) are generated for points outside the -* bounding box. -* -* For an N-dimensional ChebyMap, the forward transformation is a -* generalisation of the above form. Each output axis value is the sum -c of "ncoeff" -f of NCOEFF -* terms, where each term is the product of a single coefficient -* value and N factors of the form Tn(x'_i), where "x'_i" is the -* normalised value of the i'th input axis value. -* -* The forward and inverse transformations are defined independantly -* by separate sets of coefficients, supplied when the ChebyMap is -* created. If no coefficients are supplied to define the inverse -* transformation, the -c astPolyTran -f AST_POLYTRAN -* method of the parent PolyMap class can instead be used to create an -* inverse transformation. The inverse transformation so generated -* will be a Chebyshev polynomial with coefficients chosen to minimise -* the residuals left by a round trip (forward transformation followed -* by inverse transformation). - -* Parameters: -c nin -f NIN = INTEGER (Given) -* The number of input coordinates. -c nout -f NOUT = INTEGER (Given) -* The number of output coordinates. -c ncoeff_f -f NCOEFF_F = INTEGER (Given) -* The number of non-zero coefficients necessary to define the -* forward transformation of the ChebyMap. If zero is supplied, the -* forward transformation will be undefined. -c coeff_f -f COEFF_F( * ) = DOUBLE PRECISION (Given) -* An array containing -c "ncoeff_f*( 2 + nin )" elements. Each group of "2 + nin" -f "NCOEFF_F*( 2 + NIN )" elements. Each group of "2 + NIN" -* adjacent elements describe a single coefficient of the forward -* transformation. Within each such group, the first element is the -* coefficient value; the next element is the integer index of the -* ChebyMap output which uses the coefficient within its defining -* expression (the first output has index 1); the remaining elements -* of the group give the integer powers to use with each input -* coordinate value (powers must not be negative, and floating -* point values are rounded to the nearest integer). -c If "ncoeff_f" is zero, a NULL pointer may be supplied for "coeff_f". -* -* For instance, if the ChebyMap has 3 inputs and 2 outputs, each group -* consisting of 5 elements, A groups such as "(1.2, 2.0, 1.0, 3.0, 0.0)" -* describes a coefficient with value 1.2 which is used within the -* definition of output 2. The output value is incremented by the -* product of the coefficient value, the value of the Chebyshev -* polynomial of power 1 evaluated at input coordinate 1, and the -* value of the Chebyshev polynomial of power 3 evaluated at input -* coordinate 2. Input coordinate 3 is not used since its power is -* specified as zero. As another example, the group "(-1.0, 1.0, -* 0.0, 0.0, 0.0 )" adds a constant value -1.0 onto output 1 (it is -* a constant value since the power for every input axis is given as -* zero). -* -c Each final output coordinate value is the sum of the "ncoeff_f" terms -c described by the "ncoeff_f" groups within the supplied array. -f Each final output coordinate value is the sum of the "NCOEFF_F" terms -f described by the "NCOEFF_F" groups within the supplied array. -c ncoeff_i -f NCOEFF_I = INTEGER (Given) -* The number of non-zero coefficients necessary to define the -* inverse transformation of the ChebyMap. If zero is supplied, the -* inverse transformation will be undefined. -c coeff_i -f COEFF_I( * ) = DOUBLE PRECISION (Given) -* An array containing -c "ncoeff_i*( 2 + nout )" elements. Each group of "2 + nout" -f "NCOEFF_I*( 2 + NOUT )" elements. Each group of "2 + NOUT" -* adjacent elements describe a single coefficient of the inverse -c transformation, using the same schame as "coeff_f", -f transformation, using the same schame as "COEFF_F", -* except that "inputs" and "outputs" are transposed. -c If "ncoeff_i" is zero, a NULL pointer may be supplied for "coeff_i". -c lbnd_f -f LBND_F( * ) = DOUBLE PRECISION (Given) -* An array containing the lower bounds of the input bounding box within -* which the ChebyMap is defined. This argument is not used or -* accessed if -c ncoeff_f is zero, and so a NULL pointer may be supplied. -f NCOEFF_F is zero. -* If supplied, the array should contain -c "nin" elements. -f "NIN" elements. -c ubnd_f -f UBND_F( * ) = DOUBLE PRECISION (Given) -* An array containing the upper bounds of the input bounding box within -* which the ChebyMap is defined. This argument is not used or -* accessed if -c ncoeff_f is zero, and so a NULL pointer may be supplied. -f NCOEFF_F is zero. -* If supplied, the array should contain -c "nin" elements. -f "NIN" elements. -c lbnd_i -f LBND_I( * ) = DOUBLE PRECISION (Given) -* An array containing the lower bounds of the output bounding box within -* which the ChebyMap is defined. This argument is not used or -* accessed if -c ncoeff_i is zero, and so a NULL pointer may be supplied. -f NCOEFF_I is zero. -* If supplied, the array should contain -c "nout" elements. -f "NOUT" elements. -c ubnd_i -f UBND_I( * ) = DOUBLE PRECISION (Given) -* An array containing the upper bounds of the output bounding box within -* which the ChebyMap is defined. This argument is not used or -* accessed if -c ncoeff_i is zero, and so a NULL pointer may be supplied. -f NCOEFF_I is zero. -* If supplied, the array should contain -c "nout" elements. -f "NOUT" elements. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new ChebyMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new ChebyMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astChebyMap() -f AST_CHEBYMAP = INTEGER -* A pointer to the new ChebyMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstChebyMap *new; /* Pointer to new ChebyMap */ - va_list args; /* Variable argument list */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise the ChebyMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitChebyMap( NULL, sizeof( AstChebyMap ), !class_init, - &class_vtab, "ChebyMap", nin, nout, - ncoeff_f, coeff_f, ncoeff_i, coeff_i, - lbnd_f, ubnd_f, lbnd_i, ubnd_i ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new ChebyMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new ChebyMap. */ - return new; -} - -AstChebyMap *astChebyMapId_( int nin, int nout, int ncoeff_f, const double coeff_f[], - int ncoeff_i, const double coeff_i[], - const double lbnd_f[], const double ubnd_f[], - const double lbnd_i[], const double ubnd_i[], - const char *options, ... ){ -/* -* Name: -* astChebyMapId_ - -* Purpose: -* Create a ChebyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "chebymap.h" -* AstChebyMap *astChebyMap( int nin, int nout, int ncoeff_f, const double coeff_f[], -* int ncoeff_i, const double coeff_i[], const -* double lbnd_f[], const double ubnd_f[], -* double lbnd_i[], const double ubnd_i[], -* const char *options, ... ) - -* Class Membership: -* ChebyMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astChebyMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astChebyMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astChebyMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astChebyMap_. - -* Returned Value: -* The ID value associated with the new ChebyMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstChebyMap *new; /* Pointer to new ChebyMap */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the ChebyMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitChebyMap( NULL, sizeof( AstChebyMap ), !class_init, - &class_vtab, "ChebyMap", nin, nout, - ncoeff_f, coeff_f, ncoeff_i, coeff_i, - lbnd_f, ubnd_f, lbnd_i, ubnd_i ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new ChebyMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new ChebyMap. */ - return astMakeId( new ); -} - -AstChebyMap *astInitChebyMap_( void *mem, size_t size, int init, - AstChebyMapVtab *vtab, const char *name, - int nin, int nout, int ncoeff_f, const double coeff_f[], - int ncoeff_i, const double coeff_i[], - const double lbnd_f[], const double ubnd_f[], - const double lbnd_i[], const double ubnd_i[], - int *status ){ -/* -*+ -* Name: -* astInitChebyMap - -* Purpose: -* Initialise a ChebyMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "chebymap.h" -* AstChebyMap *astInitChebyMap( void *mem, size_t size, int init, -* AstChebyMapVtab *vtab, const char *name, -* int nin, int nout, int ncoeff_f, -* const double coeff_f[], int ncoeff_i, -* const double coeff_i[] -* const double lbnd_f[], const double ubnd_f[], -* const double lbnd_i[], const double ubnd_i[] ) - -* Class Membership: -* ChebyMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new ChebyMap object. It allocates memory (if necessary) to accommodate -* the ChebyMap plus any additional data associated with the derived class. -* It then initialises a ChebyMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a ChebyMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the ChebyMap is to be initialised. -* This must be of sufficient size to accommodate the ChebyMap data -* (sizeof(ChebyMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the ChebyMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the ChebyMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the ChebyMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new ChebyMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* nin -* The number of input coordinate values per point. This is the -* same as the number of columns in the matrix. -* nout -* The number of output coordinate values per point. This is the -* same as the number of rows in the matrix. -* ncoeff_f -* The number of non-zero coefficients necessary to define the -* forward transformation of the ChebyMap. If zero is supplied, the -* forward transformation will be undefined. -* coeff_f -* An array containing "ncoeff_f*( 2 + nin )" elements. Each group -* of "2 + nin" adjacent elements describe a single coefficient of -* the forward transformation. Within each such group, the first -* element is the coefficient value; the next element is the -* integer index of the ChebyMap output which uses the coefficient -* within its defining polynomial (the first output has index 1); -* the remaining elements of the group give the integer powers to -* use with each input coordinate value (powers must not be -* negative) -* -* For instance, if the ChebyMap has 3 inputs and 2 outputs, each group -* consisting of 5 elements, A groups such as "(1.2, 2.0, 1.0, 3.0, 0.0)" -* describes a coefficient with value 1.2 which is used within the -* definition of output 2. The output value is incremented by the -* product of the coefficient value, the value of input coordinate -* 1 raised to the power 1, and the value of input coordinate 2 raised -* to the power 3. Input coordinate 3 is not used since its power is -* specified as zero. As another example, the group "(-1.0, 1.0, -* 0.0, 0.0, 0.0 )" describes adds a constant value -1.0 onto -* output 1 (it is a constant value since the power for every input -* axis is given as zero). -* -* Each final output coordinate value is the sum of the "ncoeff_f" terms -* described by the "ncoeff_f" groups within the supplied array. -* ncoeff_i -* The number of non-zero coefficients necessary to define the -* inverse transformation of the ChebyMap. If zero is supplied, the -* inverse transformation will be undefined. -* coeff_i -* An array containing -* "ncoeff_i*( 2 + nout )" elements. Each group of "2 + nout" -* adjacent elements describe a single coefficient of the inverse -* transformation, using the same schame as "coeff_f", except that -* "inputs" and "outputs" are transposed. -* lbnd_f -* An array containing the lower bounds of the input bounding box within -* which the ChebyMap is defined. The array should contain "nin" elements. -* ubnd_f -* An array containing the upper bounds of the input bounding box within -* which the ChebyMap is defined. The array should contain "nin" elements. -* lbnd_i -* An array containing the lower bounds of the output bounding box within -* which the ChebyMap is defined. The array should contain "nout" elements. -* ubnd_i -* An array containing the upper bounds of the output bounding box within -* which the ChebyMap is defined. The array should contain "nout" elements. - -* Returned Value: -* A pointer to the new ChebyMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstChebyMap *new; - int i; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitChebyMapVtab( vtab, name ); - -/* Initialise a PolyMap structure (the parent class) as the first component - within the ChebyMap structure, allocating memory if necessary. */ - new = (AstChebyMap *) astInitPolyMap( mem, size, 0, - (AstPolyMapVtab *) vtab, name, - nin, nout, ncoeff_f, coeff_f, - ncoeff_i, coeff_i ); - if ( astOK ) { - -/* Initialise the ChebyMap data. */ -/* ---------------------------- */ - -/* First initialise the pointers in case of errors. */ - new->scale_f = NULL; - new->offset_f = NULL; - new->scale_i = NULL; - new->offset_i = NULL; - -/* Calculate the scales and offsets that map the supplied input bounding box - onto the range [-1,+1] on each input axis, and store them. */ - if( ncoeff_f > 0 ) { - new->scale_f = (double *) astMalloc( sizeof( double )*nin ); - new->offset_f = (double *) astMalloc( sizeof( double )*nin ); - if( astOK ) { - for( i = 0; i < nin; i++ ) { - if( ubnd_f[ i ] != lbnd_f[ i ] ) { - new->scale_f[ i ] = 2.0/( ubnd_f[ i ] - lbnd_f[ i ] ); - new->offset_f[ i ] = -( ubnd_f[ i ] + lbnd_f[ i ] )/( ubnd_f[ i ] - lbnd_f[ i ] ); - } else if( astOK ){ - astError( AST__BADBX, "astInitChebyMap(%s): Input bounding box " - "has zero width on input axis %d.", status, name, i + 1 ); - break; - } - } - } - } - -/* Calculate the scales and offsets that map the supplied output bounding box - onto the range [-1,+1] on each output axis, and store them. */ - if( ncoeff_i > 0 ) { - new->scale_i = (double *) astMalloc( sizeof( double )*nout ); - new->offset_i = (double *) astMalloc( sizeof( double )*nout ); - if( astOK ) { - for( i = 0; i < nout; i++ ) { - if( ubnd_i[ i ] != lbnd_i[ i ] ) { - new->scale_i[ i ] = 2.0/( ubnd_i[ i ] - lbnd_i[ i ] ); - new->offset_i[ i ] = -( ubnd_i[ i ] + lbnd_i[ i ] )/( ubnd_i[ i ] - lbnd_i[ i ] ); - } else if( astOK ){ - astError( AST__BADBX, "astInitChebyMap(%s): Output bounding box " - "has zero width on output axis %d.", status, name, i + 1 ); - break; - } - } - } - } - -/* If an error occurred, clean up by deleting the new ChebyMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new ChebyMap. */ - return new; -} - -AstChebyMap *astLoadChebyMap_( void *mem, size_t size, - AstChebyMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadChebyMap - -* Purpose: -* Load a ChebyMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "chebymap.h" -* AstChebyMap *astLoadChebyMap( void *mem, size_t size, -* AstChebyMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* ChebyMap loader. - -* Description: -* This function is provided to load a new ChebyMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* ChebyMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a ChebyMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the ChebyMap is to be -* loaded. This must be of sufficient size to accommodate the -* ChebyMap data (sizeof(ChebyMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the ChebyMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the ChebyMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstChebyMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new ChebyMap. If this is NULL, a pointer -* to the (static) virtual function table for the ChebyMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "ChebyMap" is used instead. - -* Returned Value: -* A pointer to the new ChebyMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -/* Local Variables: */ - AstChebyMap *new; /* Pointer to the new ChebyMap */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int i; /* Loop index */ - int ngood; /* No. of non-bad values */ - int nin; /* No. of input coords */ - int nout; /* No. of output coords */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this ChebyMap. In this case the - ChebyMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstChebyMap ); - vtab = &class_vtab; - name = "ChebyMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitChebyMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built ChebyMap. */ - new = astLoadPolyMap( mem, size, (AstPolyMapVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Get the number of inputs and outputs for the uninverted Mapping. */ - nin = ( (AstMapping *) new )->nin; - nout = ( (AstMapping *) new )->nout; - -/* Initialise values */ - new->scale_f = NULL; - new->offset_f = NULL; - new->scale_i = NULL; - new->offset_i = NULL; - -/* Read input data. */ -/* ================ */ - -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "ChebyMap" ); - -/* Is the forward transformation defined? */ - if( ((AstPolyMap *) new)->ncoeff_f ) { - -/* Allocate memory to hold the scales and offsets for the input axes. */ - new->scale_f = astMalloc( sizeof( double )*(size_t) nin ); - new->offset_f = astMalloc( sizeof( double )*(size_t) nin ); - if( astOK ) { - -/* Get the scale factors. */ - ngood = 0; - for( i = 0; i < nin; i++ ){ - (void) sprintf( buff, "fscl%d", i + 1 ); - (new->scale_f)[ i ] = astReadDouble( channel, buff, AST__BAD ); - if( (new->scale_f)[ i ] != AST__BAD ) ngood++; - } - -/* Get the offsets of the bounding box. */ - for( i = 0; i < nin; i++ ){ - (void) sprintf( buff, "foff%d", i + 1 ); - (new->offset_f)[ i ] = astReadDouble( channel, buff, AST__BAD ); - if( (new->offset_f)[ i ] != AST__BAD ) ngood++; - } - -/* The scale and offset values should all be AST__BAD if the transformation - is a standard polynomial. Anull the scale and offset arrays to - indicate this. */ - if( ngood == 0 ) { - new->scale_f = astFree( new->scale_f ); - new->offset_f = astFree( new->offset_f ); - -/* Otherwise, there should be no bad values. */ - } else if( ngood != 2*nin && astOK ) { - astError( AST__OBJIN, "astLoadChebyMap: insufficient scale " - "and offset values for the forward transformation " - "in loaded ChebyMap.", status ); - } - } - } - -/* Is the inverse transformation defined? */ - if( ((AstPolyMap *) new)->ncoeff_i ) { - -/* Allocate memory to hold the scales and offsets for the output axes. */ - new->scale_i = astMalloc( sizeof( double )*(size_t) nout ); - new->offset_i = astMalloc( sizeof( double )*(size_t) nout ); - if( astOK ) { - -/* Get the scale factors. */ - ngood = 0; - for( i = 0; i < nout; i++ ){ - (void) sprintf( buff, "iscl%d", i + 1 ); - (new->scale_i)[ i ] = astReadDouble( channel, buff, AST__BAD ); - if( (new->scale_i)[ i ] != AST__BAD ) ngood++; - } - -/* Get the offsets of the bounding box. */ - for( i = 0; i < nout; i++ ){ - (void) sprintf( buff, "ioff%d", i + 1 ); - (new->offset_i)[ i ] = astReadDouble( channel, buff, AST__BAD ); - if( (new->offset_i)[ i ] != AST__BAD ) ngood++; - } - -/* The scale and offset values should all be AST__BAD if the transformation - is a standard polynomial. Anull the scale and offset arrays to - indicate this. */ - if( ngood == 0 ) { - new->scale_i = astFree( new->scale_i ); - new->offset_i = astFree( new->offset_i ); - -/* Otherwise, there should be no bad values. */ - } else if( ngood != 2*nout && astOK ) { - astError( AST__OBJIN, "astLoadChebyMap: insufficient scale " - "and offset values for the inverse transformation " - "in loaded ChebyMap.", status ); - } - } - } - -/* If an error occurred, clean up by deleting the new ChebyMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new ChebyMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - -void astChebyDomain_( AstChebyMap *this, int forward, double *lbnd, double *ubnd, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,ChebyMap,ChebyDomain))( this, forward, lbnd, ubnd, status ); -} - - diff --git a/ast/chebymap.h b/ast/chebymap.h deleted file mode 100644 index fff75a6..0000000 --- a/ast/chebymap.h +++ /dev/null @@ -1,234 +0,0 @@ -#if !defined( CHEBYMAP_INCLUDED ) /* Include this file only once */ -#define CHEBYMAP_INCLUDED -/* -*+ -* Name: -* chebymap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the ChebyMap class. - -* Invocation: -* #include "chebymap.h" - -* Description: -* This include file defines the interface to the ChebyMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. - -* Inheritance: -* The ChebyMap class inherits from the PolyMap class. - -* Copyright: -* Copyright (C) 2017 East Asian Observatory. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 2-MAR-2017 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "polymap.h" /* Polynomial mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* ChebyMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstChebyMap { - -/* Attributes inherited from the parent class. */ - AstPolyMap polymap; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int cheby_f; /* Is fwd transformation a Cheby poly? */ - int cheby_i; /* Is inv transformation a Cheby poly? */ - double *scale_f; /* Pointer to array of input axis scales */ - double *offset_f; /* Pointer to array of input axis offsets */ - double *scale_i; /* Pointer to array of input axis scales */ - double *offset_i; /* Pointer to array of input axis offsets */ -} AstChebyMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstChebyMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstPolyMapVtab polymap_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* ChebyDomain)( AstChebyMap *, int, double *, double *, int * ); - -} AstChebyMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstChebyMapGlobals { - AstChebyMapVtab Class_Vtab; - int Class_Init; -} AstChebyMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitChebyMapGlobals_( AstChebyMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(ChebyMap) /* Check class membership */ -astPROTO_ISA(ChebyMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstChebyMap *astChebyMap_( int, int, int, const double[], int, const double[], - const double[], const double[], const double[], const double[], - const char *, int *, ...); -#else -AstChebyMap *astChebyMapId_( int, int, int, const double[], int, const double[], const double[], const double[], const double[], const double[], const char *, ... )__attribute__((format(printf,11,12))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstChebyMap *astInitChebyMap_( void *, size_t, int, AstChebyMapVtab *, - const char *, int, int, int, const double[], - int, const double[], const double[], const double[], - const double[], const double[], int * ); - -/* Vtab initialiser. */ -void astInitChebyMapVtab_( AstChebyMapVtab *, const char *, int * ); - -/* Loader. */ -AstChebyMap *astLoadChebyMap_( void *, size_t, AstChebyMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -void astChebyDomain_( AstChebyMap *, int, double *, double *, int * ); - -# if defined(astCLASS) /* Protected */ -#endif - - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckChebyMap(this) astINVOKE_CHECK(ChebyMap,this,0) -#define astVerifyChebyMap(this) astINVOKE_CHECK(ChebyMap,this,1) - -/* Test class membership. */ -#define astIsAChebyMap(this) astINVOKE_ISA(ChebyMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astChebyMap astINVOKE(F,astChebyMap_) -#else -#define astChebyMap astINVOKE(F,astChebyMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitChebyMap(mem,size,init,vtab,name,nin,nout,ncoeff_f,coeff_f,ncoeff_i,coeff_i,lbnd_f,ubnd_f,lbnd_i,ubnd_i) \ -astINVOKE(O,astInitChebyMap_(mem,size,init,vtab,name,nin,nout,ncoeff_f,coeff_f,ncoeff_i,coeff_i,lbnd_f,ubnd_f,lbnd_i,ubnd_i,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitChebyMapVtab(vtab,name) astINVOKE(V,astInitChebyMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadChebyMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadChebyMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckChebyMap to validate ChebyMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astChebyDomain(this,forward,lbnd,ubnd) \ -astINVOKE(V,astChebyDomain_(astCheckChebyMap(this),forward,lbnd,ubnd,STATUS_PTR)) - - -#if defined(astCLASS) /* Protected */ - -#endif -#endif - - - - - diff --git a/ast/circle.c b/ast/circle.c deleted file mode 100644 index c795b98..0000000 --- a/ast/circle.c +++ /dev/null @@ -1,2900 +0,0 @@ -/* -*class++ -* Name: -* Circle - -* Purpose: -* A circular or spherical region within a Frame. - -* Constructor Function: -c astCircle -f AST_CIRCLE - -* Description: -* The Circle class implements a Region which represents a circle or -* sphere within a Frame. - -* Inheritance: -* The Circle class inherits from the Region class. - -* Attributes: -* The Circle class does not define any new attributes beyond -* those which are applicable to all Regions. - -* Functions: -c In addition to those functions applicable to all Regions, the -c following functions may also be applied to all Circles: -f In addition to those routines applicable to all Regions, the -f following routines may also be applied to all Circles: -* -c - astCirclePars: Get the geometric parameters of the Circle -f - AST_CIRCLEPARS: Get the geometric parameters of the Circle - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 31-AUG-2004 (DSB): -* Original version. -* 4-NOV-2013 (DSB): -* Modify RegPins so that it can handle uncertainty regions that straddle -* a discontinuity. Previously, such uncertainty Regions could have a huge -* bounding box resulting in matching region being far too big. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Circle - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "region.h" /* Coordinate regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "box.h" /* Box Regions */ -#include "wcsmap.h" /* Definitons of AST__DPI etc */ -#include "circle.h" /* Interface definition for this class */ -#include "ellipse.h" /* Interface definition for ellipse class */ -#include "mapping.h" /* Position mappings */ -#include "unitmap.h" /* Unit Mapping */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstMapping *(* parent_simplify)( AstMapping *, int * ); -static void (* parent_setregfs)( AstRegion *, AstFrame *, int * ); -static void (* parent_resetcache)( AstRegion *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Circle) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Circle,Class_Init) -#define class_vtab astGLOBAL(Circle,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstCircleVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstCircle *astCircleId_( void *, int, const double[], const double[], void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double *CircumPoint( AstFrame *, int, const double *, double, int * ); -static double *RegCentre( AstRegion *this, double *, double **, int, int, int * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static int RegTrace( AstRegion *, int, double *, double **, int * ); -static void Cache( AstCircle *, int * ); -static void CalcPars( AstFrame *, AstPointSet *, double *, double *, double *, int * ); -static void CirclePars( AstCircle *, double *, double *, double *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void RegBaseBox( AstRegion *this, double *, double *, int * ); -static void ResetCache( AstRegion *this, int * ); -static void SetRegFS( AstRegion *, AstFrame *, int * ); - -/* Member functions. */ -/* ================= */ - -AstRegion *astBestCircle_( AstPointSet *mesh, double *cen, AstRegion *unc, int *status ){ -/* -*+ -* Name: -* astBestCircle - -* Purpose: -* Find the best fitting Circle through a given mesh of points. - -* Type: -* Protected function. - -* Synopsis: -* #include "circle.h" -* AstRegion *astBestCircle( AstPointSet *mesh, double *cen, AstRegion *unc ) - -* Class Membership: -* Circle member function - -* Description: -* This function finds the best fitting Circle through a given mesh of -* points. - -* Parameters: -* mesh -* Pointer to a PointSet holding the mesh of points. They are -* assumed to be in the Frame represented by "unc". -* cen -* Pointer to an array holding the coordinates of the new Circle -* centre. -* unc -* A Region representing the uncertainty associated with each point -* on the mesh. - -* Returned Value: -* Pointer to the best fitting Circle. It will inherit the positional -* uncertainty and Frame represented by "unc". - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - AstRegion *result; - double *p; - double rad; - double **ptr; - double d; - double s2r; - double p0; - int ic; - int ip; - int n; - int nc; - int np; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get no. of points in the mesh, and the number of axis values per point. */ - np = astGetNpoint( mesh ); - nc = astGetNcoord( mesh ); - -/* Get pointers to the axis values. */ - ptr = astGetPoints( mesh ); - -/* Check pointers can be used safely */ - if( astOK ) { - -/* We find ther sum of the squared axis increments from the supplied - centre to each of the supplied points. Initialise the sum to zero. */ - s2r = 0.0; - n = 0; - -/* Loop round all axes. */ - for( ic = 0; ic < nc; ic++ ) { - p = ptr[ ic ]; - p0 = cen[ ic ]; - -/* Loop round all values for this axis. */ - for( ip = 0; ip < np; ip++, p++ ) { - if( *p != AST__BAD ) { - -/* Increment the sums */ - d = *p - p0; - s2r += d*d; - n++; - - } - } - } - -/* Find the RMS distance of the points from the supplied centre. This is - the radius of the best fitting circle. */ - if( n > 0 ) { - rad = sqrt( nc*s2r/n ); - -/* Create the returned Region. */ - result = (AstRegion *) astCircle( unc, 1, cen, &rad, unc, "", status ); - } - } - -/* Return NULL if anything went wrong. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result.*/ - return result; -} - -static void Cache( AstCircle *this, int *status ){ -/* -* Name: -* Cache - -* Purpose: -* Calculate intermediate values and cache them in the Circle structure. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* void Cache( AstCircle *this, int *status ) - -* Class Membership: -* Circle member function - -* Description: -* This function uses the PointSet stored in the parent Region to calculate -* some intermediate values which are useful in other methods. These -* values are stored within the Circle structure. - -* Parameters: -* this -* Pointer to the Circle. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *frm; - double *centre; - double *lb; - double *ub; - double radius; - int i; - int nc; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do Nothing if the cached information is up to date. */ - if( this->stale ) { - -/* Get a pointer to the base Frame and the number of base axes. */ - frm = astGetFrame( ((AstRegion *) this)->frameset, AST__BASE ); - nc = astGetNaxes( frm ); - -/* Allocate memory to hold the centre coords. */ - centre = astMalloc( sizeof( double )*astGetNaxes( frm ) ); - -/* Get the radius and centre of the Circle in the base Frame, using the - centre and circumference positions stored in the parent Region structure. */ - CalcPars( frm, ( (AstRegion *) this)->points, centre, &radius, NULL, - status ); - -/* Allocate memory to store the base frame bounding box. This is just - initialised here. It is set properly when the astRegBaseMesh - function is called. This box should not be used unless the "basemesh" - component of the parent Region structure is set to a non-null value. */ - lb = (double *) astMalloc( sizeof( double )*(size_t) nc ); - ub = (double *) astMalloc( sizeof( double )*(size_t) nc ); - -/* Initialise the bounding box. */ - for( i = 0; astOK && i < nc; i++ ) { - lb[ i ] = -DBL_MAX; - ub[ i ] = DBL_MAX; - } - -/* If everything went OK, store these values in the Circle structure. */ - if( astOK ) { - this->radius = radius; - - astFree( this->centre ); - this->centre = centre; - centre = NULL; - - astFree( this->lb ); - this->lb = lb; - lb = NULL; - - astFree( this->ub ); - this->ub = ub; - ub = NULL; - } - -/* Free resources */ - frm = astAnnul( frm ); - if( centre ) centre = astFree( centre ); - -/* Indicate cached information is up to date. */ - this->stale = 0; - } -} - -static void CalcPars( AstFrame *frm, AstPointSet *pset, double *centre, - double *radius, double *p1, int *status ){ -/* -* Name: -* CalcPars - -* Purpose: -* Calculate the geometric parameters of the supplied Circle. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* double *CalcPars( AstFrame *frm, AstPointSet *pset, double *centre, -* double *radius, double *p1, int *status ) - -* Class Membership: -* Circle member function - -* Description: -* This function uses the supplied PointSet to calculate the geometric -* parameters that describe the a crcle. These values are returned in -* a newly allocated dynamic array. - -* Parameters: -* frm -* Pointer to the Frame in which the circle is defined. -* pset -* Pointer to a PointSet. The first point should be the circle -* centre, and the second point should be a point on the circle -* circumference. -* centre -* An array in which to return the axis values at the circle centre. -* The length of this array should be no less than the number of -* axes in "frm". -* radius -* Pointer to a double in which to return the circle radius, -* expressed as a geodesic distance in the supplied Frame. -* p1 -* An array in which to return the coordinates of a point on the -* circumference of the circle. The length of this array should be -* no less than the number of axes in "frm". Can be NULL if the -* circumference position is not needed. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double **ptr; - double *circum; - int i; - int nc; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get and the number of axes. */ - nc = astGetNaxes( frm ); - -/* Get pointers to the coordinate data in the supplied PointSet. */ - ptr = astGetPoints( pset ); - -/* If no p1 array was supplied, create a temporary work array to hold the - circumference position. */ - if( !p1 ) { - circum = astMalloc( sizeof( double )*nc ); - } else { - circum = p1; - } - -/* Check pointers can be used safely. */ - if( ptr ) { - -/* Copy the two points in to the allocated memory. */ - for( i = 0; i < nc; i++ ) { - centre[ i ] = ptr[ i ][ 0 ]; - circum[ i ] = ptr[ i ][ 1 ]; - } - -/* Return the geodesic distance between these two points as the radius. */ - *radius = astDistance( frm, centre, circum ); - } - -/* Free any work array. */ - if( !p1 ) circum = astFree( circum ); -} - -static void CirclePars( AstCircle *this, double *centre, double *radius, - double *p1, int *status ){ -/* -*++ -* Name: -c astCirclePars -f AST_CIRCLEPARS - -* Purpose: -* Returns the geometric parameters of an Circle. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "circle.h" -c void astCirclePars( AstCircle *this, double *centre, double *radius, -c double *p1 ) -f CALL AST_CIRCLEPARS( THIS, CENTRE, RADIUS, P1, STATUS ) - -* Class Membership: -* Region method. - -* Description: -c This function -f This routine -* returns the geometric parameters describing the supplied Circle. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -c centre -f CENTRE( * ) = DOUBLE PRECISION (Returned) -c Pointer to an array -f An array -* in which to return the coordinates of the Circle centre. -* The length of this array should be no less than the number of -* axes in the associated coordinate system. -c radius -f RADIUS = DOUBLE PRECISION (Returned) -* Returned holding the radius of the Circle, as an geodesic -* distance in the associated coordinate system. -c p1 -f P1( * ) = DOUBLE PRECISION (Returned) -c Pointer to an array -f An array -* in which to return the coordinates of a point on the -* circumference of the Circle. The length of this array should be -* no less than the number of axes in the associated coordinate system. -c A NULL pointer can be supplied if the circumference position is -c not needed. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the coordinate system represented by the Circle has been -* changed since it was first created, the returned parameters refer -* to the new (changed) coordinate system, rather than the original -* coordinate system. Note however that if the transformation from -* original to new coordinate system is non-linear, the shape -* represented by the supplied Circle object may not be an accurate -* circle. -*-- -*/ - -/* Local Variables: */ - AstRegion *this_region; /* Parent Region pointer */ - AstFrame *frm; /* Current Frame represented by the Circle */ - AstPointSet *pset; /* PointSet holding PointList axis values */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Store a pointer to the parent region structure. */ - this_region = (AstRegion *) this; - -/* Transform the base Frame axis values into the current Frame. */ - pset = astTransform( this_region->frameset, this_region->points, 1, NULL ); - -/* Get the Circle frame. */ - frm = astGetFrame( this_region->frameset, AST__CURRENT ); - -/* Calculate the required parameters. */ - CalcPars( frm, pset, centre, radius, p1, status ); - -/* Free resources */ - frm = astAnnul( frm ); - pset = astAnnul( pset ); -} - -static double *CircumPoint( AstFrame *frm, int nax, const double *centre, - double radius, int *status ){ -/* -* Name: -* CircumPoint - -* Purpose: -* Find a point on the circumference of the circle. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* double *CircumPoint( AstFrame *frm, int nax, const double *centre, -* double radius, int *status ) - -* Class Membership: -* Circle member function - -* Description: -* This function returns a dynamically allocated array containing the -* axis values at a point on the circumference of the circle specified -* by a given centre and radius. The returned point is the point at -* which the circle crosses the first axis. - -* Parameters: -* frm -* Pointer to the Frame in which the circle is defined. -* nax -* The number of axes in the Frame. -* centre -* An array holding the axis values at the circle centre. -* radius -* The circle radius, expressed as a geodesic distance in the -* supplied Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a 1D array holding the axis values at the point where -* the circle crosses the first frame axis. The length of this array -* will equal the number of axes in the supsplied Frame. It should be -* freed using astFree when no longer needed. - -*/ - -/* Local Variables: */ - double *circum; - double *work; - int i; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Allocate the returned array. */ - circum = astMalloc( sizeof( double)*(size_t) nax ); - -/* Allocate work space */ - work = astMalloc( sizeof( double)*(size_t) nax ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Find the coords of a point that is offset away from the centre - position along the first axis. We use the supplied radius value as a - convenient offset length, but the actual length used is not critical. */ - for( i = 0; i < nax; i++ ) work[ i ] = centre[ i ]; - work[ 0 ] = astAxOffset( frm, 1, work[ 0 ], radius ); - -/* Offset away from the centre position, towards the position found - above, going the distance specified by the supplied radius. */ - astOffset( frm, centre, work, radius, (double *) circum ); - } - -/* Free resources. */ - work = astFree( work ); - -/* Return the result. */ - return circum; -} - -void astInitCircleVtab_( AstCircleVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitCircleVtab - -* Purpose: -* Initialise a virtual function table for a Circle. - -* Type: -* Protected function. - -* Synopsis: -* #include "circle.h" -* void astInitCircleVtab( AstCircleVtab *vtab, const char *name ) - -* Class Membership: -* Circle vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Circle class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsACircle) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->CirclePars = CirclePars; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - - parent_setregfs = region->SetRegFS; - region->SetRegFS = SetRegFS; - - parent_resetcache = region->ResetCache; - region->ResetCache = ResetCache; - - region->RegPins = RegPins; - region->RegTrace = RegTrace; - region->RegBaseMesh = RegBaseMesh; - region->RegBaseBox = RegBaseBox; - region->RegCentre = RegCentre; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "Circle", "Circular or spherical region" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void RegBaseBox( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* Circle member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCircle *this; /* Pointer to Circle structure */ - AstFrame *frm; /* Pointer to base Frame */ - const char *class; /* Pointer to class name */ - int i; /* Axis index */ - int nb; /* No. of axes in base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Circle structure */ - this = (AstCircle *) this_region; - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* Get a pointer to the base Frame in the Region, and get the number of - axes. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - nb = astGetNaxes( frm ); - -/* If the Frame is a simple Frame, we can assume plane geometry. */ - class = astGetClass( frm ); - if( class && !strcmp( class, "Frame" ) ) { - for( i = 0; i < nb; i++ ) { - lbnd[ i ] = ( this->centre )[ i ] - this->radius; - ubnd[ i ] = ( this->centre )[ i ] + this->radius; - } - -/* If the Frame is not a simple Frame we cannot assume plane geometry. */ - } else { - -/* The bounding box of the mesh returned by astRegBaseMesh is used as the - bounding box of the Circle. These bounds are cached in the Circle - structure by astRegBaseMesh. Ensure astRegBaseMesh has been invoked, - so that it is safe to use the cached bounding box. */ - if( !this_region->basemesh ) (void) astAnnul( astRegBaseMesh( this ) ); - -/* Store the bounding box. */ - for( i = 0; i < nb; i++ ) { - lbnd[ i ] = this->lb[ i ]; - ubnd[ i ] = this->ub[ i ]; - } - } - -/* Free resources. */ - frm = astAnnul( frm ); -} - -static AstPointSet *RegBaseMesh( AstRegion *this_region, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Return a PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* AstPointSet *astRegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* Circle member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. The axis values in this PointSet will have -* associated accuracies derived from the accuracies which were -* supplied when the Region was created. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - -/* Local Constants: */ -#define NP_EDGE 50 /* No. of points for determining geodesic */ - -/* Local Variables: */ - AstBox *box; /* Bounding box for this Circle */ - AstCircle *this; /* The Circle structure */ - AstRegion *reg; /* Copy of supplied Circle */ - AstFrame *frm; /* Base Frame in encapsulated FrameSet */ - AstPointSet *result; /* Returned pointer */ - double **ptr; /* Pointers to data */ - double *p1; /* Pointer to array holding a single point */ - double *p2; /* Pointer to array holding a single point */ - double angle; /* Angular position of point */ - double delta; /* Angular separation of points */ - double dist; /* Offset along an axis */ - double lbx; /* Lower x bound of mesh bounding box */ - double lby; /* Lower y bound of mesh bounding box */ - double p[ 2 ]; /* Position in 2D Frame */ - double ubx; /* Upper x bound of mesh bounding box */ - double uby; /* Upper y bound of mesh bounding box */ - int i; /* Point index */ - int j; /* Axis index */ - int naxes; /* No. of axes in base Frame */ - int np; /* No. of points in returned PointSet */ - -/* Initialise */ - result= NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the Region structure contains a pointer to a PointSet holding - a previously created mesh, return it. */ - if( this_region->basemesh ) { - result = astClone( this_region->basemesh ); - -/* Otherwise, create a new mesh. */ - } else { - -/* Get a pointer to the Circle structure. */ - this = (AstCircle *) this_region; - -/* Get a pointer to the base Frame in the encapsulated FrameSet. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Get the number of axes in the base Frame */ - naxes = astGetNaxes( frm ); - -/* Get the requested number of points to put on the mesh. */ - np = astGetMeshSize( this ); - -/* Ensure cached information is available. */ - Cache( (AstCircle *) this, status ); - -/* First deal with 1-D "circles" (where we ignore MeshSize). */ - if( naxes == 1 ) { - -/* The boundary of a 1-D circle consists of 2 points - the two extreme values. - Create a PointSet to hold 2 1-D values, and store the extreme values. */ - result = astPointSet( 2, 1, "", status ); - ptr = astGetPoints( result ); - if( astOK ) { - ptr[ 0 ][ 0 ] = ( this->centre )[ 0 ] - this->radius; - ptr[ 0 ][ 1 ] = ( this->centre )[ 0 ] + this->radius; - } - -/* Store the bounding box in the Circle structure. */ - this->lb[ 0 ] = ptr[ 0 ][ 0 ]; - this->ub[ 0 ] = ptr[ 0 ][ 1 ]; - -/* Now deal with 2-D circles. */ - } else if( naxes == 2 ){ - -/* Store the angular increment between points. */ - delta = 2*AST__DPI/np; - -/* Create a suitable PointSet to hold the returned positions. */ - result = astPointSet( np, 2, "", status ); - ptr = astGetPoints( result ); - if( astOK ) { - -/* Initialise the bounding box of the mesh points. */ - lbx = DBL_MAX; - ubx = -DBL_MAX; - lby = DBL_MAX; - uby = -DBL_MAX; - -/* Loop round each point. */ - angle = 0.0; - for( i = 0; i < np; i++ ) { - -/* Work out where the end of the radius vector at this angle is, and - store in the returned PointSet. */ - astOffset2( frm, this->centre, angle, this->radius, p ); - ptr[ 0 ][ i ] = p[ 0 ]; - ptr[ 1 ][ i ] = p[ 1 ]; - -/* Update the bounds of the mesh bounding box. The box is expressed in - terms of axis offsets from the centre, in order to avoid problems with - boxes that cross RA=0 or RA=12h */ - if( p[ 0 ] != AST__BAD && p[ 1 ] != AST__BAD ){ - dist = astAxDistance( frm, 1, this->centre[ 0 ], p[ 0 ] ); - if( dist < lbx ) { - lbx = dist; - } else if( dist > ubx ) { - ubx = dist; - } - dist = astAxDistance( frm, 2, this->centre[ 1 ], p[ 1 ] ); - if( dist < lby ) { - lby = dist; - } else if( dist > uby ) { - uby = dist; - } - } - -/* Increment the angular position of the next mesh point. */ - angle += delta; - } - -/* Store the bounding box in the Circle structure. */ - this->lb[ 0 ] = this->centre[ 0 ] + lbx; - this->lb[ 1 ] = this->centre[ 1 ] + lby; - this->ub[ 0 ] = this->centre[ 0 ] + ubx; - this->ub[ 1 ] = this->centre[ 1 ] + uby; - } - -/* Now deal with circles with more than 2 dimensions. Producing an evenly - spread mesh of points over a sphere is a complex task (see e.g. - http://www.eso.org/science/healpix/ ). This implementation does not - attempt to produce a genuinely even spread. Instead it simply uses the - mesh for the bounding box of the sphere, and projects each point on to - the surface of the sphere. */ - } else { - -/* Allocate memory to hold an approximation of the circle bounding box. */ - p1 = astMalloc( sizeof( double )*(size_t) naxes ); - p2 = astMalloc( sizeof( double )*(size_t) naxes ); - -/* Get an approximation to the bounding box, and initialise the real - bounding box of the mesh points. */ - if( astOK ) { - memcpy( p1, this->centre, sizeof( double )*(size_t) naxes ); - for( j = 0; j < naxes; j++ ) { - p1[ j ] += this->radius; - astOffset( frm, this->centre, p1, this->radius, p2 ); - p1[ j ] = this->centre[ j ]; - this->ub[ j ] = p2[ j ]; - } - } - -/* Create a Box region which just encompasses the circle. */ - box = astBox( frm, 0, this->centre, this->ub, NULL, "", status ); - -/* Get a mesh covering this box. */ - astSetMeshSize( box, np ); - result = astRegBaseMesh( box ); - ptr = astGetPoints( result ); - np = astGetNpoint( result ); - -/* Allocate memory for a single point */ - if( astOK ) { - -/* Initialise the real bounding box of the mesh points. */ - for( j = 0; j < naxes; j++ ) { - this->lb[ j ] = DBL_MAX; - this->ub[ j ] = -DBL_MAX; - } - -/* Move each point in this mesh radially so that its distance from the centre - equals the radius of this Circle. */ - for( i = 0; i < np; i++ ) { - for( j = 0; j < naxes; j++ ) p1[ j ] = ptr[ j ][ i ]; - astOffset( frm, this->centre, p1, this->radius, p2 ); - - for( j = 0; j < naxes; j++ ) { - ptr[ j ][ i ] = p2[ j ]; - -/* Update the bounds of the mesh bounding box. */ - if( p2[ j ] != AST__BAD ){ - if( p2[ j ] < this->lb[ j ] ) { - this->lb[ j ] = p2[ j ]; - } else if( p2[ j ] > this->ub[ j ] ) { - this->ub[ j ] = p2[ j ]; - } - } - } - } - } - -/* Same the returned pointer in the Region structure so that it does not - need to be created again next time this function is called. */ - if( astOK && result ) this_region->basemesh = astClone( result ); - -/* Free resources. */ - p1 = astFree( p1 ); - p2 = astFree( p2 ); - box = astAnnul( box ); - } - -/* Extend the bounding box if it contains any singularies. The astNormBox - requires a Mapping which can be used to test points in the base Frame. - Create a copy of the Circle and then set its FrameSet so that the current - Frame in the copy is the same as the base Frame in the original. */ - reg = astCopy( this ); - astSetRegFS( reg, frm ); - astSetNegated( reg, 0 ); - -/* Normalise this box. */ - astNormBox( frm, this->lb, this->ub, reg ); - -/* Free resources. */ - reg = astAnnul( reg ); - frm = astAnnul( frm ); - } - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static double *RegCentre( AstRegion *this_region, double *cen, double **ptr, - int index, int ifrm, int *status ){ -/* -* Name: -* RegCentre - -* Purpose: -* Re-centre a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* double *RegCentre( AstRegion *this, double *cen, double **ptr, -* int index, int ifrm, int *status ) - -* Class Membership: -* Circle member function (over-rides the astRegCentre protected -* method inherited from the Region class). - -* Description: -* This function shifts the centre of the supplied Region to a -* specified position, or returns the current centre of the Region. - -* Parameters: -* this -* Pointer to the Region. -* cen -* Pointer to an array of axis values, giving the new centre. -* Supply a NULL value for this in order to use "ptr" and "index" to -* specify the new centre. -* ptr -* Pointer to an array of pointers, one for each axis in the Region. -* Each pointer locates an array of axis values. This is the format -* returned by the PointSet method astGetPoints. Only used if "cen" -* is NULL. -* index -* The index of the point within the arrays identified by "ptr" at -* which is stored the coords for the new centre position. Only used -* if "cen" is NULL. -* ifrm -* Should be AST__BASE or AST__CURRENT. Indicates whether the centre -* position is supplied and returned in the base or current Frame of -* the FrameSet encapsulated within "this". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If both "cen" and "ptr" are NULL then a pointer to a newly -* allocated dynamic array is returned which contains the centre -* coords of the Region. This array should be freed using astFree when -* no longer needed. If either of "ptr" or "cen" is not NULL, then a -* NULL pointer is returned. - -* Notes: -* - Some Region sub-classes do not have a centre. Such classes will report -* an AST__INTER error code if this method is called. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to base Frame */ - AstCircle *this; /* Pointer to Circle structure */ - double **rptr; /* Data pointers for Region PointSet */ - double *bc; /* Base Frame centre position */ - double *circum; /* Base frame circumference position */ - double *result; /* Returned pointer */ - double *tmp; /* Temporary array pointer */ - double axval; /* Axis value */ - int ic; /* Coordinate index */ - int ncb; /* Number of base frame coordinate values per point */ - int ncc; /* Number of current frame coordinate values per point */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Circle structure. */ - this = (AstCircle *) this_region; - -/* Get the number of axis values per point in the base and current Frames. */ - ncb = astGetNin( this_region->frameset ); - ncc = astGetNout( this_region->frameset ); - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* If the centre coords are to be returned, return either a copy of the - base Frame centre coords, or transform the base Frame centre coords - into the current Frame. */ - if( !ptr && !cen ) { - if( ifrm == AST__CURRENT ) { - result = astRegTranPoint( this_region, this->centre, 1, 1 ); - } else { - result = astStore( NULL, this->centre, sizeof( double )*ncb ); - } - -/* Otherwise, we store the supplied new centre coords and return a NULL - pointer. */ - } else { - -/* Get a pointer to the base Frame in the Region's FrameSet. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Get a pointer to the axis values stored in the Region structure. */ - rptr = astGetPoints( this_region->points ); - -/* Check pointers can be used safely */ - if( astOK ) { - -/* If the centre position was supplied in the current Frame, find the - corresponding base Frame position... */ - if( ifrm == AST__CURRENT ) { - if( cen ) { - bc = astRegTranPoint( this_region, cen, 1, 0 ); - } else { - tmp = astMalloc( sizeof( double)*(size_t)ncc ); - if( astOK ) { - for( ic = 0; ic < ncc; ic++ ) tmp[ ic ] = ptr[ ic ][ index ]; - } - bc = astRegTranPoint( this_region, tmp, 1, 0 ); - tmp = astFree( tmp ); - } - -/* Replace any bad centre values with their current values. */ - for( ic = 0; ic < ncb; ic++ ) { - if( bc[ ic ] == AST__BAD ) bc[ ic ] = this->centre[ ic ]; - } - -/* ... and change the coords in the parent Region structure and the cached - coords in the Circle structure. */ - circum = CircumPoint( frm, ncb, bc, this->radius, status ); - if( circum ) { - for( ic = 0; ic < ncb; ic++ ) { - rptr[ ic ][ 0 ] = bc[ ic ]; - rptr[ ic ][ 1 ] = circum[ ic ]; - this->centre[ ic ] = bc[ ic ]; - } - } - -/* Free resources */ - circum = astFree( circum ); - bc = astFree( bc ); - -/* If the centre position was supplied in the base Frame, use the - supplied "cen" or "ptr" pointer directly to change the coords in the - parent Region structure and the cached coords in the Circle structure. */ - } else { - for( ic = 0; ic < ncb; ic++ ) { - axval = cen ? cen[ ic ] : ptr[ ic ][ index ]; - if( axval != AST__BAD ) this->centre[ ic ] = axval; - } - - circum = CircumPoint( frm, ncb, this->centre, this->radius, - status ); - if( circum ) { - for( ic = 0; ic < ncb; ic++ ) { - rptr[ ic ][ 0 ] = this->centre[ ic ]; - rptr[ ic ][ 1 ] = circum[ ic ]; - } - circum = astFree( circum ); - } - } - } - -/* Free resources */ - frm = astAnnul( frm ); - } - -/* Return the result. */ - return result; -} - -static int RegPins( AstRegion *this_region, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -* Name: -* RegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given Circle. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask, int *status ){ - -* Class Membership: -* Circle member function (over-rides the astRegPins protected -* method inherited from the Region class). - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given Circle. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied Circle "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the Circle. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "pset". -* Each element in the returned array is set to 1 if the -* corresponding position in "pset" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*/ - -/* Local variables: */ - AstCircle *large_circle; /* Circle slightly larger than "this" */ - AstCircle *small_circle; /* Circle slightly smaller than "this" */ - AstCircle *this; /* Pointer to the Circle structure. */ - AstFrame *frm; /* Base Frame in supplied Circle */ - AstPointSet *ps1; /* Points masked by larger Circle */ - AstPointSet *ps2; /* Points masked by larger and smaller Circlees */ - AstRegion *tunc; /* Uncertainity Region from "this" */ - double **ptr; /* Pointer to axis values in "ps2" */ - double *lbnd_tunc; /* Lower bounds of "this" uncertainty Region */ - double *lbnd_unc; /* Lower bounds of supplied uncertainty Region */ - double *p; /* Pointer to next axis value */ - double *safe; /* An interior point in "this" */ - double *ubnd_tunc; /* Upper bounds of "this" uncertainty Region */ - double *ubnd_unc; /* Upper bounds of supplied uncertainty Region */ - double drad; /* Radius increment corresponding to border width */ - double l1; /* Length of bounding box diagonal */ - double l2; /* Length of bounding box diagonal */ - double rad; /* Radius of Circle */ - int i; /* Axis index */ - int j; /* Point index */ - int nc; /* No. of axes in Circle base frame */ - int np; /* No. of supplied points */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - if( mask ) *mask = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the Circle structure. */ - this = (AstCircle *) this_region; - -/* Get the number of base Frame axes in the Circle, and check the supplied - PointSet has the same number of axis values per point. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - nc = astGetNaxes( frm ); - if( astGetNcoord( pset ) != nc && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axis " - "values per point (%d) in the supplied PointSet - should be " - "%d (internal AST programming error).", status, astGetClass( this ), - astGetNcoord( pset ), nc ); - } - -/* Get the number of axes in the uncertainty Region and check it is the - same as above. */ - if( unc && astGetNaxes( unc ) != nc && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axes (%d) " - "in the supplied uncertainty Region - should be " - "%d (internal AST programming error).", status, astGetClass( this ), - astGetNaxes( unc ), nc ); - } - -/* Get the centre of the region in the base Frame. We use this as a "safe" - interior point within the region. */ - safe = astRegCentre( this, NULL, NULL, 0, AST__BASE ); - -/* We now find the maximum distance on each axis that a point can be from the - boundary of the Circle for it still to be considered to be on the boundary. - First get the Region which defines the uncertainty within the Circle being - checked (in its base Frame), re-centre it on the interior point found - above (to avoid problems if the uncertainty region straddles a - discontinuity), and get its bounding box. */ - tunc = astGetUncFrm( this, AST__BASE ); - if( safe ) astRegCentre( tunc, safe, NULL, 0, AST__CURRENT ); - lbnd_tunc = astMalloc( sizeof( double )*(size_t) nc ); - ubnd_tunc = astMalloc( sizeof( double )*(size_t) nc ); - astGetRegionBounds( tunc, lbnd_tunc, ubnd_tunc ); - -/* Find the geodesic length within the base Frame of "this" of the diagonal of - the bounding box. */ - l1 = astDistance( frm, lbnd_tunc, ubnd_tunc ); - -/* Also get the Region which defines the uncertainty of the supplied - points and get its bounding box. First re-centre the uncertainty at the - interior position to avoid problems from uncertainties that straddle a - discontinuity. */ - if( unc ) { - if( safe ) astRegCentre( unc, safe, NULL, 0, AST__CURRENT ); - lbnd_unc = astMalloc( sizeof( double )*(size_t) nc ); - ubnd_unc = astMalloc( sizeof( double )*(size_t) nc ); - astGetRegionBounds( unc, lbnd_unc, ubnd_unc ); - -/* Find the geodesic length of the diagonal of this bounding box. */ - l2 = astDistance( frm, lbnd_unc, ubnd_unc ); - -/* Use a zero sized box "unc" if no box was supplied. */ - } else { - lbnd_unc = NULL; - ubnd_unc = NULL; - l2 = 0.0; - } - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* The required border width is half of the total diagonal of the two bounding - boxes. */ - if( astOK ) { - drad = 0.5*( l1 + l2 ); - -/* Create two new Circle, one of which is larger than "this" by the amount - found above, and the other of which is smaller than "this" by the amount - found above. */ - rad = this->radius + 0.5*drad; - large_circle = astCircle( frm, 1, this->centre, &rad, NULL, "", status ); - rad = this->radius - 0.5*drad; - small_circle = astCircle( frm, 1, this->centre, &rad, NULL, "", status ); - -/* Negate the smaller region.*/ - astNegate( small_circle ); - -/* Points are on the boundary of "this" if they are inside both the large - Circle and the negated small Circle. First transform the supplied PointSet - using the large Circle, then transform them using the negated smaller - Circle. */ - ps1 = astTransform( large_circle, pset, 1, NULL ); - ps2 = astTransform( small_circle, ps1, 1, NULL ); - -/* Get a point to the resulting axis values, and the number of axis - values per axis. */ - ptr = astGetPoints( ps2 ); - np = astGetNpoint( ps2 ); - -/* If a mask array is to be returned, create one. */ - if( mask ) { - *mask = astMalloc( sizeof(int)*(size_t) np ); - -/* Check all the resulting points, setting mask values for all of them. */ - if( astOK ) { - -/* Initialise the mask elements on the basis of the first axis values */ - result = 1; - p = ptr[ 0 ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ j ] = 0; - } else { - (*mask)[ j ] = 1; - } - } - -/* Now check for bad values on other axes. */ - for( i = 1; i < nc; i++ ) { - p = ptr[ i ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ j ] = 0; - } - } - } - } - -/* If no output mask is to be made, we can break out of the check as soon - as the first bad value is found. */ - } else if( astOK ) { - result = 1; - for( i = 0; i < nc && result; i++ ) { - p = ptr[ i ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - break; - } - } - } - } - -/* Free resources. */ - large_circle = astAnnul( large_circle ); - small_circle = astAnnul( small_circle ); - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - } - - tunc = astAnnul( tunc ); - frm = astAnnul( frm ); - lbnd_tunc = astFree( lbnd_tunc ); - ubnd_tunc = astFree( ubnd_tunc ); - if( unc ) lbnd_unc = astFree( lbnd_unc ); - if( unc ) ubnd_unc = astFree( ubnd_unc ); - safe = astFree( safe ); - -/* If an error has occurred, return zero. */ - if( !astOK ) { - result = 0; - if( mask ) *mask = astAnnul( *mask ); - } - -/* Return the result. */ - return result; -} - -static int RegTrace( AstRegion *this_region, int n, double *dist, double **ptr, - int *status ){ -/* -*+ -* Name: -* RegTrace - -* Purpose: -* Return requested positions on the boundary of a 2D Region. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* int astTraceRegion( AstRegion *this, int n, double *dist, double **ptr ); - -* Class Membership: -* Circle member function (overrides the astTraceRegion method -* inherited from the parent Region class). - -* Description: -* This function returns positions on the boundary of the supplied -* Region, if possible. The required positions are indicated by a -* supplied list of scalar parameter values in the range zero to one. -* Zero corresponds to some arbitrary starting point on the boundary, -* and one corresponds to the end (which for a closed region will be -* the same place as the start). - -* Parameters: -* this -* Pointer to the Region. -* n -* The number of positions to return. If this is zero, the function -* returns without action (but the returned function value still -* indicates if the method is supported or not). -* dist -* Pointer to an array of "n" scalar parameter values in the range -* 0 to 1.0. -* ptr -* A pointer to an array of pointers. The number of elements in -* this array should equal tthe number of axes in the Frame spanned -* by the Region. Each element of the array should be a pointer to -* an array of "n" doubles, in which to return the "n" values for -* the corresponding axis. The contents of the arrays are unchanged -* if the supplied Region belongs to a class that does not -* implement this method. - -* Returned Value: -* Non-zero if the astTraceRegion method is implemented by the class -* of Region supplied, and zero if not. - -*- -*/ - -/* Local Variables; */ - AstCircle *this; - AstFrame *frm; - AstMapping *map; - AstPointSet *bpset; - AstPointSet *cpset; - double **bptr; - double angle; - double p[ 2 ]; - int i; - int ncur; - int result; - -/* Initialise */ - result = 0; - -/* Check inherited status. */ - if( ! astOK ) return result; - -/* Get a pointer to the base Frame in the encapsulated FrameSet. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Check it is 2-dimensional. */ - if( astGetNaxes( frm ) == 2 ) result = 1; - -/* Check we have some points to find. */ - if( result && n > 0 ) { - -/* Get a pointer to the Circle structure. */ - this = (AstCircle *) this_region; - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* We first determine the required positions in the base Frame of the - Region, and then transform them into the current Frame. Get the - base->current Mapping, and the number of current Frame axes. */ - map = astGetMapping( this_region->frameset, AST__BASE, AST__CURRENT ); - -/* If it's a UnitMap we do not need to do the transformation, so put the - base Frame positions directly into the supplied arrays. */ - if( astIsAUnitMap( map ) ) { - bpset = NULL; - bptr = ptr; - ncur = 2; - -/* Otherwise, create a PointSet to hold the base Frame positions. */ - } else { - bpset = astPointSet( n, 2, " ", status ); - bptr = astGetPoints( bpset ); - ncur = astGetNout( map ); - } - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Loop round each point. Get the angle around the circle, and offset - along that angle to find the point that is one radius away from the - centre. Copy the results into the required arrays. */ - for( i = 0; i < n; i++ ) { - angle = dist[ i ]*2*AST__DPI; - astOffset2( frm, this->centre, angle, this->radius, p ); - bptr[ 0 ][ i ] = p[ 0 ]; - bptr[ 1 ][ i ] = p[ 1 ]; - } - - } - -/* If required, transform the base frame positions into the current - Frame, storing them in the supplied array. Then free resources. */ - if( bpset ) { - cpset = astPointSet( n, ncur, " ", status ); - astSetPoints( cpset, ptr ); - - (void) astTransform( map, bpset, 1, cpset ); - - cpset = astAnnul( cpset ); - bpset = astAnnul( bpset ); - } - -/* Free remaining resources. */ - map = astAnnul( map ); - } - frm = astAnnul( frm ); - -/* Return the result. */ - return result; -} - -static void ResetCache( AstRegion *this, int *status ){ -/* -* Name: -* ResetCache - -* Purpose: -* Clear cached information within the supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* void ResetCache( AstRegion *this, int *status ) - -* Class Membership: -* Region member function (overrides the astResetCache method -* inherited from the parent Region class). - -* Description: -* This function clears cached information from the supplied Region -* structure. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. -*/ - if( this ) { - ( (AstCircle *) this )->stale = 1; - (*parent_resetcache)( this, status ); - } -} - -static void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) { -/* -* Name: -* SetRegFS - -* Purpose: -* Stores a new FrameSet in a Region - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) - -* Class Membership: -* Circle method (over-rides the astSetRegFS method inherited from -* the Region class). - -* Description: -* This function creates a new FrameSet and stores it in the supplied -* Region. The new FrameSet contains two copies of the supplied -* Frame, connected by a UnitMap. - -* Parameters: -* this -* Pointer to the Region. -* frm -* The Frame to use. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent method to store the FrameSet in the parent Region - structure. */ - (* parent_setregfs)( this_region, frm, status ); - -/* Re-calculate cached information. */ - astResetCache( this_region ); -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mapping represented by a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* Circle method (over-rides the astSimplify method inherited -* from the Region class). - -* Description: -* This function invokes the parent Region Simplify method, and then -* performs any further region-specific simplification. -* -* If the Mapping from base to current Frame is not a UnitMap, this -* will include attempting to fit a new Region to the boundary defined -* in the current Frame. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the simplified Region. A cloned pointer to the -* supplied Region will be returned if no simplication could be -* performed. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstMapping *map; /* Base -> current Mapping */ - AstMapping *result; /* Result pointer to return */ - AstPointSet *mesh; /* Mesh of current Frame positions */ - AstPointSet *ps2; /* Circle PointSet in current Frame */ - AstRegion *new; /* Pointer to simplified Region */ - AstRegion *newreg; /* Equivalent circle or ellipse */ - AstRegion *this; /* Pointer to supplied Region structure */ - AstRegion *unc; /* Pointer to uncertainty Region */ - double **ptr2; /* Pointer axis values in "ps2" */ - double *cen; /* Pointer to array holding new centre coords */ - int ic; /* Axis index */ - int nc; /* No. of axis values per point */ - int ok; /* Was the new centre found OK? */ - int simpler; /* Has some simplication taken place? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the supplied Region structure. */ - this = (AstRegion *) this_mapping; - -/* Invoke the parent Simplify method inherited from the Region class. This - will simplify the encapsulated FrameSet and uncertainty Region. */ - new = (AstRegion *) (*parent_simplify)( this_mapping, status ); - -/* Note if any simplification took place. This is assumed to be the case - if the pointer returned by the above call is different to the supplied - pointer. */ - simpler = ( new != this ); - -/* If the Mapping from base to current Frame is not a UnitMap, we attempt - to simplify the Circle by re-defining it within its current Frame. - Transforming the Circle from its base to its current Frame may result in - the region no longer being a circle. We test this by transforming a set of - bounds on the Circle boundary. */ - map = astGetMapping( new->frameset, AST__BASE, AST__CURRENT ); - if( !astIsAUnitMap( map ) ){ - -/* Get a mesh of points covering the Circle in its current Frame. */ - mesh = astRegMesh( new ); - -/* Get the Region describing the positional uncertainty within the Circle in - its current Frame. */ - unc = astGetUncFrm( new, AST__CURRENT ); - -/* Transform the PointSet holding the circle centre into the current - Frame, and copy the axis values into a new array. */ - ps2 = astRegTransform( this, this->points, 1, NULL, NULL ); - nc = astGetNcoord( ps2 ); - cen = astMalloc( sizeof( double )*(size_t) nc ); - ptr2 = astGetPoints( ps2 ); - if( astOK ) { - - ok = 1; - for( ic = 0; ic < nc; ic++ ) { - cen[ ic ] = ptr2[ ic ][ 0 ]; - if( cen[ ic ] == AST__BAD ) ok = 0; - } - -/* Find the best fitting Circle (defined in the current Frame) through these - points */ - newreg = ok ? astBestCircle( mesh, cen, unc ) : NULL; - -/* See if all points within this mesh fall on the boundary of the best - fitting Circle, to within the uncertainty of the Region. */ - if( newreg && astRegPins( newreg, mesh, NULL, NULL ) ) { - -/* If so, use the new Circle in place of the original. */ - (void) astAnnul( new ); - new = astClone( newreg ); - -/* Otherwise, if the region is 2-d we see if an Ellipse can represent the - mesh. */ - } else if( ok && nc == 2 ){ - -/* Find the best fitting Ellipse (defined in the current Frame) through these - points */ - if( newreg ) (void) astAnnul( newreg ); - newreg = astBestEllipse( mesh, cen, unc ); - -/* See if all points within this mesh fall on the boundary of the best - fitting Ellipse, to within the uncertainty of the Region. */ - if( newreg && astRegPins( newreg, mesh, NULL, NULL ) ) { - -/* If so, use the new Ellipse in place of the original. */ - (void) astAnnul( new ); - new = astClone( newreg ); - simpler = 1; - } - } - -/* Free resources. */ - if( newreg ) newreg = astAnnul( newreg ); - } - - ps2 = astAnnul( ps2 ); - cen = astFree( cen ); - mesh = astAnnul( mesh ); - unc = astAnnul( unc ); - } - map = astAnnul( map ); - -/* If any simplification could be performed, copy Region attributes from - the supplied Region to the returned Region, and return a pointer to it. - If the supplied Region had no uncertainty, ensure the returned Region - has no uncertainty. Otherwise, return a clone of the supplied pointer. */ - if( simpler ){ - astRegOverlay( new, this, 1 ); - result = (AstMapping *) new; - - } else { - new = astAnnul( new ); - result = astClone( this ); - } - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a Circle to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* Circle member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a Circle and a set of points encapsulated in a -* PointSet and transforms the points by setting axis values to -* AST__BAD for all points which are outside the region. Points inside -* the region are copied unchanged from input to output. - -* Parameters: -* this -* Pointer to the Circle. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - The forward and inverse transformations are identical for a -* Region. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of axes in the Frame represented by the Circle. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstCircle *this; /* Pointer to Circle */ - AstFrame *frm; /* Pointer to base Frame in FrameSet */ - AstPointSet *pset_tmp; /* Pointer to PointSet holding base Frame positions*/ - AstPointSet *result; /* Pointer to output PointSet */ - double **ptr_out; /* Pointer to output coordinate data */ - double **ptr_tmp; /* Pointer to base Frame coordinate data */ - double *work; /* Pointer to array holding single base point */ - double d; /* Base-Frame distance from centre to point */ - int closed; /* Is the boundary part of the Region? */ - int coord; /* Zero-based index for coordinates */ - int inside; /* Is the point inside the Region? */ - int ncoord_out; /* No. of coordinates per output point */ - int ncoord_tmp; /* No. of coordinates per base Frame point */ - int neg; /* Has the Region been negated? */ - int npoint; /* No. of points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the Circle structure. */ - this = (AstCircle *) this_mapping; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, - containing a copy of the input PointSet. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* First use the encapsulated FrameSet to transform the supplied positions - from the current Frame in the encapsulated FrameSet (the Frame - represented by the Region), to the base Frame (the Frame in which the - Region is defined). This call also returns a pointer to the base Frame - of the encapsulated FrameSet. Note, the returned pointer may be a - clone of the "in" pointer, and so we must be carefull not to modify the - contents of the returned PointSet. */ - pset_tmp = astRegTransform( this, in, 0, NULL, &frm ); - -/* Determine the numbers of points and coordinates per point from the base - Frame PointSet and obtain pointers for accessing the base Frame and output - coordinate values. */ - npoint = astGetNpoint( pset_tmp ); - ncoord_tmp = astGetNcoord( pset_tmp ); - ptr_tmp = astGetPoints( pset_tmp ); - ncoord_out = astGetNcoord( result ); - ptr_out = astGetPoints( result ); - -/* Get work space for one base Frame position */ - work = astMalloc( sizeof( double )*(size_t) ncoord_tmp ); - -/* See if the boundary is part of the Region. */ - closed = astGetClosed( this ); - -/* See if the Region has been negated. */ - neg = astGetNegated( this ); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* Loop round each point */ - for ( point = 0; point < npoint; point++ ) { - -/* Copy the base Frame position into a work array. */ - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - work[ coord ] = ptr_tmp[ coord ][ point ]; - } - -/* Find the geodesic distance from the centre of the Circle in the base - Frame. */ - d = astDistance( frm, this->centre, work ); - -/* Now consider whether this radius value puts the point in or out of the - Circle. */ - if( d != AST__BAD ){ - if( neg ) { - if( closed ) { - inside = ( d >= this->radius ); - } else { - inside = ( d > this->radius ); - } - } else { - if( closed ) { - inside = ( d <= this->radius ); - } else { - inside = ( d < this->radius ); - } - } - } else { - inside = 0; - } - -/* If the point is outside, store bad output values. */ - if( !inside ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - } - -/* Free resources */ - work = astFree( work ); - pset_tmp = astAnnul( pset_tmp ); - frm = astAnnul( frm ); - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Region objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Region objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstCircle *in; /* Pointer to input Circle */ - AstCircle *out; /* Pointer to output Circle */ - int nax; /* Number of base Frame axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Circles. */ - in = (AstCircle *) objin; - out = (AstCircle *) objout; - -/* For safety, first clear any references to the input memory from - the output Circle. */ - out->centre = NULL; - out->lb = NULL; - out->ub = NULL; - -/* Copy dynamic memory contents */ - nax = astGetNin( ((AstRegion *) in)->frameset ); - out->centre = astStore( NULL, in->centre, - sizeof( double )*(size_t)nax ); - out->lb = astStore( NULL, in->lb, sizeof( double )*(size_t)nax ); - out->ub = astStore( NULL, in->ub, sizeof( double )*(size_t)nax ); -} - - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Circle objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Circle objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstCircle *this; /* Pointer to Circle */ - -/* Obtain a pointer to the Circle structure. */ - this = (AstCircle *) obj; - -/* Annul all resources. */ - this->centre = astFree( this->centre ); - this->lb = astFree( this->lb ); - this->ub = astFree( this->ub ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Circle objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Circle class to an output Channel. - -* Parameters: -* this -* Pointer to the Circle whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstCircle *this; /* Pointer to the Circle structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Circle structure. */ - this = (AstCircle *) this_object; - -/* Write out values representing the instance variables for the - Circle class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* There are no values to write, so return without further action. */ -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsACircle and astCheckCircle functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Circle,Region) -astMAKE_CHECK(Circle) - -AstCircle *astCircle_( void *frame_void, int form, const double centre[], - const double point[], AstRegion *unc, - const char *options, int *status, ...) { -/* -*++ -* Name: -c astCircle -f AST_CIRCLE - -* Purpose: -* Create a Circle. - -* Type: -* Public function. - -* Synopsis: -c #include "circle.h" -c AstCircle *astCircle( AstFrame *frame, int form, const double centre[], -c const double point[], AstRegion *unc, -c const char *options, ... ) -f RESULT = AST_CIRCLE( FRAME, FORM, CENTRE, POINT, UNC, OPTIONS, STATUS ) - -* Class Membership: -* Circle constructor. - -* Description: -* This function creates a new Circle and optionally initialises its -* attributes. -* -* A Circle is a Region which represents a circle or sphere within the -* supplied Frame. - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* A pointer to the Frame in which the region is defined. A deep -* copy is taken of the supplied Frame. This means that any -* subsequent changes made to the Frame using the supplied pointer -* will have no effect the Region. -c form -f FORM = INTEGER (Given) -* Indicates how the circle is described by the remaining parameters. -* A value of zero indicates that the circle is specified by a -* centre position and a position on the circumference. A value of one -* indicates that the circle is specified by a centre position and a -* scalar radius. -c centre -f CENTRE( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the coordinates at the centre of -* the circle or sphere. -c point -f POINT( * ) = DOUBLE PRECISION (Given) -c If "form" -f If FORM -* is zero, then this array should have one element for each Frame -* axis (Naxes attribute), and should be supplied holding the -* coordinates at a point on the circumference of the circle or sphere. -c If "form" -f If FORM -* is one, then this array should have one element only which should -* be supplied holding the scalar radius of the circle or sphere, -* as a geodesic distance within the Frame. -c unc -f UNC = INTEGER (Given) -* An optional pointer to an existing Region which specifies the -* uncertainties associated with the boundary of the Circle being created. -* The uncertainty in any point on the boundary of the Circle is found by -* shifting the supplied "uncertainty" Region so that it is centred at -* the boundary point being considered. The area covered by the -* shifted uncertainty Region then represents the uncertainty in the -* boundary position. The uncertainty is assumed to be the same for -* all points. -* -* If supplied, the uncertainty Region must be of a class for which -* all instances are centro-symetric (e.g. Box, Circle, Ellipse, etc.) -* or be a Prism containing centro-symetric component Regions. A deep -* copy of the supplied Region will be taken, so subsequent changes to -* the uncertainty Region using the supplied pointer will have no -* effect on the created Circle. Alternatively, -f a null Object pointer (AST__NULL) -c a NULL Object pointer -* may be supplied, in which case a default uncertainty is used -* equivalent to a box 1.0E-6 of the size of the Circle being created. -* -* The uncertainty Region has two uses: 1) when the -c astOverlap -f AST_OVERLAP -* function compares two Regions for equality the uncertainty -* Region is used to determine the tolerance on the comparison, and 2) -* when a Region is mapped into a different coordinate system and -* subsequently simplified (using -c astSimplify), -f AST_SIMPLIFY), -* the uncertainties are used to determine if the transformed boundary -* can be accurately represented by a specific shape of Region. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Circle. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Circle. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astCircle() -f AST_CIRCLE = INTEGER -* A pointer to the new Circle. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstCircle *new; /* Pointer to new Circle */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the supplied Frame structure. */ - frame = astCheckFrame( frame_void ); - -/* Initialise the Circle, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitCircle( NULL, sizeof( AstCircle ), !class_init, &class_vtab, - "Circle", frame, form, centre, point, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Circle's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Circle. */ - return new; -} - -AstCircle *astCircleId_( void *frame_void, int form, const double centre[], - const double point[], void *unc_void, - const char *options, ... ) { -/* -* Name: -* astCircleId_ - -* Purpose: -* Create a Circle. - -* Type: -* Private function. - -* Synopsis: -* #include "circle.h" -* AstCircle *astCircleId_( AstFrame *frame, int form, const double centre[], -* const double point[], AstRegion *unc, -* const char *options, ... ) - -* Class Membership: -* Circle constructor. - -* Description: -* This function implements the external (public) interface to the -* astCircle constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astCircle_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astCircle_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astCircle_. - -* Returned Value: -* The ID value associated with the new Circle. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstCircle *new; /* Pointer to new Circle */ - AstRegion *unc; /* Pointer to Region structure */ - va_list args; /* Variable argument list */ - - int *status; /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Frame pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Frame. */ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - -/* Obtain a Region pointer from the supplied "unc" ID and validate the - pointer to ensure it identifies a valid Region . */ - unc = unc_void ? astCheckRegion( astMakePointer( unc_void ) ) : NULL; - -/* Initialise the Circle, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitCircle( NULL, sizeof( AstCircle ), !class_init, &class_vtab, - "Circle", frame, form, centre, point, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Circle's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Circle. */ - return astMakeId( new ); -} - -AstCircle *astInitCircle_( void *mem, size_t size, int init, AstCircleVtab *vtab, - const char *name, AstFrame *frame, int form, - const double centre[], const double point[], - AstRegion *unc, int *status ) { -/* -*+ -* Name: -* astInitCircle - -* Purpose: -* Initialise a Circle. - -* Type: -* Protected function. - -* Synopsis: -* #include "circle.h" -* AstCircle *astInitCircle_( void *mem, size_t size, int init, AstCircleVtab *vtab, -* const char *name, AstFrame *frame, int form, -* const double centre[], const double point[], -* AstRegion *unc ) - -* Class Membership: -* Circle initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Circle object. It allocates memory (if necessary) to accommodate -* the Circle plus any additional data associated with the derived class. -* It then initialises a Circle structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Circle at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Circle is to be initialised. -* This must be of sufficient size to accommodate the Circle data -* (sizeof(Circle)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Circle (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Circle -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Circle's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Circle. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* A pointer to the Frame in which the region is defined. -* form -* Indicates how the "point" parameter should be interpreted. -* Should be either 0 or 1. -* centre -* An array of double, with one element for each Frame axis (Naxes -* attribute) containing the coordinates of the circle centre. -* point -* If "form" is zero, this should be an array of double, with one -* element for each Frame axis (Naxes attribute) containing the -* coordinates at any point on the circumference. If "form" is one, -* this should be the address of a double containing the scalar -* radius of the circle or sphere. -* unc -* A pointer to a Region which specifies the uncertainty in the -* supplied positions (all points on the boundary of the new Circle -* being initialised are assumed to have the same uncertainty). A NULL -* pointer can be supplied, in which case default uncertainties equal to -* 1.0E-6 of the dimensions of the new Circle's bounding box are used. -* If an uncertainty Region is supplied, it must be either a Box, a -* Circle or an Ellipse, and its encapsulated Frame must be related -* to the Frame supplied for parameter "frame" (i.e. astConvert -* should be able to find a Mapping between them). Two positions -* the "frame" Frame are considered to be co-incident if their -* uncertainty Regions overlap. The centre of the supplied -* uncertainty Region is immaterial since it will be re-centred on the -* point being tested before use. A deep copy is taken of the supplied -* Region. - -* Returned Value: -* A pointer to the new Circle. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstCircle *new; /* Pointer to new Circle */ - AstPointSet *pset; /* PointSet to pass to Region initialiser */ - const double *circum; /* Pointer to circumference position */ - double **ptr; /* Pointer to coords data in pset */ - int i; /* Axis index */ - int nc; /* No. of axes */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitCircleVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check the supplied value for "form" is legal. */ - if( form != 0 && form != 1 && astOK ) { - astError( AST__BADIN, "astInitCircle(%s): The value supplied for " - "parameter \"form\" (%d) is illegal - it should be 0 or 1 " - "(programming error).", status, name, form ); - } - -/* Get the number of axis values required for each position. */ - nc = astGetNaxes( frame ); - -/* If the circle radius has been supplied, find a point on the circle - circumference. */ - if( form == 1 ) { - circum = CircumPoint( frame, nc, centre, *point, status ); - -/* Otherwise, use the supplied circumference point. */ - } else { - circum = point; - } - -/* Create a PointSet to hold the centre position, and a point on the - circumference, and get points to the data arrays. */ - pset = astPointSet( 2, nc, "", status ); - ptr = astGetPoints( pset ); - -/* Copy the centre and circumference coordinates into the PointSet, checking - that no bad values have been supplied. */ - for( i = 0; astOK && i < nc; i++ ) { - if( centre[ i ] == AST__BAD ) { - astError( AST__BADIN, "astInitCircle(%s): The value of axis %d is " - "undefined at the circle centre.", status, name, i + 1 ); - } - if( astOK && circum[ i ] == AST__BAD ) { - astError( AST__BADIN, "astInitCircle(%s): The value of axis %d is " - "undefined on the circumference of the circle.", status, name, i + 1 ); - } - ptr[ i ][ 0 ] = centre[ i ]; - ptr[ i ][ 1 ] = circum[ i ]; - } - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Initialise a Region structure (the parent class) as the first component - within the Circle structure, allocating memory if necessary. */ - new = (AstCircle *) astInitRegion( mem, size, 0, (AstRegionVtab *) vtab, - name, frame, pset, unc ); - - if ( astOK ) { - -/* Initialise the Circle data. */ -/* ------------------------ */ - new->stale = 1; - new->centre = NULL; - new->lb = NULL; - new->ub = NULL; - Cache( new, status ); - -/* If an error occurred, clean up by deleting the new Circle. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Free resources. */ - pset = astAnnul( pset ); - if( form == 1 ) circum = astFree( (void *) circum ); - -/* Return a pointer to the new Circle. */ - return new; -} - -AstCircle *astLoadCircle_( void *mem, size_t size, AstCircleVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadCircle - -* Purpose: -* Load a Circle. - -* Type: -* Protected function. - -* Synopsis: -* #include "circle.h" -* AstCircle *astLoadCircle( void *mem, size_t size, AstCircleVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* Circle loader. - -* Description: -* This function is provided to load a new Circle using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Circle structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Circle at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the Circle is to be -* loaded. This must be of sufficient size to accommodate the -* Circle data (sizeof(Circle)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Circle (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Circle structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstCircle) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Circle. If this is NULL, a pointer -* to the (static) virtual function table for the Circle class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Circle" is used instead. - -* Returned Value: -* A pointer to the new Circle. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstCircle *new; /* Pointer to the new Circle */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Circle. In this case the - Circle belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstCircle ); - vtab = &class_vtab; - name = "Circle"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitCircleVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Circle. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Circle" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* There are no values to read. */ -/* ---------------------------- */ - -/* Cache intermediate results in the Circle structure */ - new->centre = NULL; - new->lb = NULL; - new->ub = NULL; - new->stale = 1; - Cache( new, status ); - -/* If an error occurred, clean up by deleting the new Circle. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Circle pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - -void astCirclePars_( AstCircle *this, double *centre, double *radius, - double *p1, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Circle,CirclePars))( this, centre, radius, - p1, status ); -} - - - - - - diff --git a/ast/circle.h b/ast/circle.h deleted file mode 100644 index a69f8ea..0000000 --- a/ast/circle.h +++ /dev/null @@ -1,241 +0,0 @@ -#if !defined( CIRCLE_INCLUDED ) /* Include this file only once */ -#define CIRCLE_INCLUDED -/* -*+ -* Name: -* circle.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Circle class. - -* Invocation: -* #include "circle.h" - -* Description: -* This include file defines the interface to the Circle class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The Circle class implement a Region which represents a simple interval -* on each axis of the encapsulated Frame - -* Inheritance: -* The Circle class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 31-AUG-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "region.h" /* Coordinate regions (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* Circle structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstCircle { - -/* Attributes inherited from the parent class. */ - AstRegion region; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *centre; /* Circle centre coords */ - double radius; /* Circle radius */ - double *lb; /* Lower limits of mesh bounding box */ - double *ub; /* Upper limit of mesh bounding box */ - int stale; /* Is Cached information stale? */ - -} AstCircle; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstCircleVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* CirclePars)( AstCircle *, double *, double *, double *, int * ); -} AstCircleVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstCircleGlobals { - AstCircleVtab Class_Vtab; - int Class_Init; -} AstCircleGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitCircleGlobals_( AstCircleGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Circle) /* Check class membership */ -astPROTO_ISA(Circle) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstCircle *astCircle_( void *, int, const double[], const double[], AstRegion *, const char *, int *, ...); -#else -AstCircle *astCircleId_( void *, int, const double[], const double[], - AstRegion *, const char *, ... )__attribute__((format(printf,6,7))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstCircle *astInitCircle_( void *, size_t, int, AstCircleVtab *, - const char *, AstFrame *, int, const double[], - const double[], AstRegion *, int * ); - -/* Vtab initialiser. */ -void astInitCircleVtab_( AstCircleVtab *, const char *, int * ); - -/* Loader. */ -AstCircle *astLoadCircle_( void *, size_t, AstCircleVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -void astCirclePars_( AstCircle *, double *, double *, double *, int * ); - -# if defined(astCLASS) /* Protected */ -AstRegion *astBestCircle_( AstPointSet *, double *, AstRegion *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckCircle(this) astINVOKE_CHECK(Circle,this,0) -#define astVerifyCircle(this) astINVOKE_CHECK(Circle,this,1) - -/* Test class membership. */ -#define astIsACircle(this) astINVOKE_ISA(Circle,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astCircle astINVOKE(F,astCircle_) -#else -#define astCircle astINVOKE(F,astCircleId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitCircle(mem,size,init,vtab,name,frame,form,p1,p2,unc) \ -astINVOKE(O,astInitCircle_(mem,size,init,vtab,name,frame,form,p1,p2,unc,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitCircleVtab(vtab,name) astINVOKE(V,astInitCircleVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadCircle(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadCircle_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckCircle to validate Circle pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astCirclePars(this,centre,radius,p1) \ -astINVOKE(V,astCirclePars_(astCheckCircle(this),centre,radius,p1,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astBestCircle(pset,cen,unc) astBestCircle_(pset,cen,unc,STATUS_PTR) -#endif -#endif - - - - - diff --git a/ast/cminpack/CopyrightMINPACK.txt b/ast/cminpack/CopyrightMINPACK.txt deleted file mode 100644 index ae7984d..0000000 --- a/ast/cminpack/CopyrightMINPACK.txt +++ /dev/null @@ -1,52 +0,0 @@ -Minpack Copyright Notice (1999) University of Chicago. All rights reserved - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the -following conditions are met: - -1. Redistributions of source code must retain the above -copyright notice, this list of conditions and the following -disclaimer. - -2. Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following -disclaimer in the documentation and/or other materials -provided with the distribution. - -3. The end-user documentation included with the -redistribution, if any, must include the following -acknowledgment: - - "This product includes software developed by the - University of Chicago, as Operator of Argonne National - Laboratory. - -Alternately, this acknowledgment may appear in the software -itself, if and wherever such third-party acknowledgments -normally appear. - -4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" -WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE -UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND -THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE -OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY -OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR -USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF -THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) -DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION -UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL -BE CORRECTED. - -5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT -HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF -ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, -INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF -ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF -PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER -SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT -(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, -EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE -POSSIBILITY OF SUCH LOSS OR DAMAGES. - diff --git a/ast/cminpack/README.md b/ast/cminpack/README.md deleted file mode 100644 index 66bbc6f..0000000 --- a/ast/cminpack/README.md +++ /dev/null @@ -1,128 +0,0 @@ -C/C++ Minpack [![Build Status](https://api.travis-ci.org/devernay/cminpack.png?branch=master)](https://travis-ci.org/devernay/cminpack) -========== - -This is a C version of the minpack minimization package. -It has been derived from the fortran code using f2c and -some limited manual editing. Note that you need to link -against libf2c to use this version of minpack. Extern "C" -linkage permits the package routines to be called from C++. -Check ftp://netlib.bell-labs.com/netlib/f2c for the latest -f2c version. For general minpack info and test programs, see -the accompanying readme.txt and http://www.netlib.org/minpack/. - -Type `make` to compile and `make install` to install in /usr/local -or modify the makefile to suit your needs. - -This software has been tested on a RedHat 7.3 Linux machine - -usual 'use at your own risk' warnings apply. - -Manolis Lourakis -- lourakis at ics forth gr, July 2002 - Institute of Computer Science, - Foundation for Research and Technology - Hellas - Heraklion, Crete, Greece - -Repackaging by Frederic Devernay -- frederic dot devernay at m4x dot org - -The project home page is at http://devernay.free.fr/hacks/cminpack/ - -History ------- - -* version 1.3.3 (04/02/2014):: - - Add documentation and examples abouts how to add box constraints to the variables. - - continuous integration https://travis-ci.org/devernay/cminpack - -* version 1.3.2 (27/10/2013): - - Minor change in the CMake build: also set SOVERSION. - -* version 1.3.1 (02/10/2013): - - Fix CUDA examples compilation, and remove non-free files. - -* version 1.3.0 (09/06/2012): - - Optionally use LAPACK and CBLAS in lmpar, qrfac, and qrsolv. Added - "make lapack" to build the LAPACK-based cminpack and "make - checklapack" to test it (results of the test may depend on the - underlying LAPACK and BLAS implementations). - On 64-bits architectures, the preprocessor symbol __LP64__ must be - defined (see cminpackP.h) if the LAPACK library uses the LP64 - interface (i.e. 32-bits integer, vhereas the ILP interface uses 64 - bits integers). - -* version 1.2.2 (16/05/2012): - - Update Makefiles and documentation (see "Using CMinpack" above) for - easier building and testing. - -* version 1.2.1 (15/05/2012): - - The library can now be built as double, float or half - versions. Standard tests in the "examples" directory can now be - lauched using "make check" (to run common tests, including against - the float version), "make checkhalf" (to test the half version) and - "make checkfail" (to run all the tests, even those that fail). - -* version 1.2.0 (14/05/2012): -- Added original FORTRAN sources for better testing (type "make" in - directory fortran, then "make" in examples and follow the - instructions). Added driver tests lmsdrv, chkdrv, hyjdrv, - hybdrv. Typing "make alltest" in the examples directory will run all - possible test combinations (make sure you have gfortran installed). - -* version 1.1.5 (04/05/2012): - - cminpack now works in CUDA, thanks to Jordi Bataller Mascarell, type - "make" in the "cuda" subdir (be careful, though: this is a - straightforward port from C, and each problem is solved using a - single thread). cminpack can now also be compiled with - single-precision floating point computation (define - __cminpack_real__ to float when compiling and using the - library). Fix cmake support for CMINPACK_LIB_INSTALL_DIR. Update the - reference files for tests. - -* version 1.1.4 (30/10/2011): - - Translated all the Levenberg-Marquardt code (lmder, lmdif, lmstr, - lmder1, lmdif1, lmstr1, lmpar, qrfac, qrsolv, fdjac2, chkder) to use - C-style indices. - -* version 1.1.3 (16/03/2011): - - Minor fix: Change non-standard strnstr() to strstr() in - genf77tests.c. - -* version 1.1.2 (07/01/2011): - - Fix Windows DLL building (David Graeff) and document covar in - cminpack.h. - -* version 1.1.1 (04/12/2010): - - Complete rewrite of the C functions (without trailing underscore in - the function name). Using the original FORTRAN code, the original - algorithms structure was recovered, and many goto's were converted - to if...then...else. The code should now be both more readable and - easier to optimize, both for humans and for compilers. Added lmddrv - and lmfdrv test drivers, which test a lot of difficult functions - (these functions are explained in Testing Unconstrained Optimization - Software by Moré et al.). Also added the pkg-config files to the - cmake build, as well as an "uninstall" target, contributed by - Geoffrey Biggs. - -* version 1.0.4 (18/10/2010): - - Support for shared library building using CMake, thanks to Goeffrey - Biggs and Radu Bogdan Rusu from Willow Garage. Shared libraries can be - enabled using cmake options, as in; - cmake -DUSE_FPIC=ON -DSHARED_LIBS=ON -DBUILD_EXAMPLES=OFF path_to_sources - -* version 1.0.3 (18/03/2010): - - Added CMake support. - - XCode build is now Universal. - - Added tfdjac2_ and tfdjac2c examples, which test the accuracy of a - finite-differences approximation of the Jacobian. - - Bug fix in tlmstr1 (signaled by Thomas Capricelli). - -* version 1.0.2 (27/02/2009): - - Added Xcode and Visual Studio project files - -* version 1.0.1 (17/12/2007): - - bug fix in covar() and covar_(), the computation of tolr caused a - segfault (signaled by Timo Hartmann). - -* version 1.0.0 (24/04/2007): - - Added fortran and C examples - - Added documentation from Debian man pages - - Wrote pure C version - - Added covar() and covar_(), and use it in tlmdef/tlmdif diff --git a/ast/cminpack/cminpack.h b/ast/cminpack/cminpack.h deleted file mode 100644 index 6d3f757..0000000 --- a/ast/cminpack/cminpack.h +++ /dev/null @@ -1,370 +0,0 @@ -/* Header file for cminpack, by Frederic Devernay. - The documentation for all functions can be found in the file - minpack-documentation.txt from the distribution, or in the source - code of each function. */ - -#ifndef __CMINPACK_H__ -#define __CMINPACK_H__ - -/* The default floating-point type is "double" for C/C++ and "float" for CUDA, - but you can change this by defining one of the following symbols when - compiling the library, and before including cminpack.h when using it: - __cminpack_double__ for double - __cminpack_float__ for float - __cminpack_half__ for half from the OpenEXR library (in this case, you must - compile cminpack with a C++ compiler) -*/ -#ifdef __cminpack_double__ -#define __cminpack_real__ double -#endif - -#ifdef __cminpack_float__ -#define __cminpack_real__ float -#endif - -#ifdef __cminpack_half__ -#include -#define __cminpack_real__ half -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Cmake will define cminpack_EXPORTS on Windows when it -configures to build a shared library. If you are going to use -another build system on windows or create the visual studio -projects by hand you need to define cminpack_EXPORTS when -building a DLL on windows. -*/ -#if defined (__GNUC__) -#define CMINPACK_DECLSPEC_EXPORT __declspec(__dllexport__) -#define CMINPACK_DECLSPEC_IMPORT __declspec(__dllimport__) -#endif -#if defined (_MSC_VER) || defined (__BORLANDC__) -#define CMINPACK_DECLSPEC_EXPORT __declspec(dllexport) -#define CMINPACK_DECLSPEC_IMPORT __declspec(dllimport) -#endif -#ifdef __WATCOMC__ -#define CMINPACK_DECLSPEC_EXPORT __export -#define CMINPACK_DECLSPEC_IMPORT __import -#endif -#ifdef __IBMC__ -#define CMINPACK_DECLSPEC_EXPORT _Export -#define CMINPACK_DECLSPEC_IMPORT _Import -#endif - -#if !defined(CMINPACK_NO_DLL) && (defined(__WIN32__) || defined(WIN32) || defined (_WIN32)) -#if defined(cminpack_EXPORTS) || defined(CMINPACK_EXPORTS) || defined(CMINPACK_DLL_EXPORTS) - #define CMINPACK_EXPORT CMINPACK_DECLSPEC_EXPORT - #else - #define CMINPACK_EXPORT CMINPACK_DECLSPEC_IMPORT - #endif /* cminpack_EXPORTS */ -#else /* defined (_WIN32) */ - #define CMINPACK_EXPORT -#endif - -#if defined(__CUDA_ARCH__) || defined(__CUDACC__) -#define __cminpack_attr__ __device__ -#ifndef __cminpack_real__ -#define __cminpack_float__ -#define __cminpack_real__ float -#endif -#define __cminpack_type_fcn_nn__ __cminpack_attr__ int fcn_nn -#define __cminpack_type_fcnder_nn__ __cminpack_attr__ int fcnder_nn -#define __cminpack_type_fcn_mn__ __cminpack_attr__ int fcn_mn -#define __cminpack_type_fcnder_mn__ __cminpack_attr__ int fcnder_mn -#define __cminpack_type_fcnderstr_mn__ __cminpack_attr__ int fcnderstr_mn -#define __cminpack_decl_fcn_nn__ -#define __cminpack_decl_fcnder_nn__ -#define __cminpack_decl_fcn_mn__ -#define __cminpack_decl_fcnder_mn__ -#define __cminpack_decl_fcnderstr_mn__ -#define __cminpack_param_fcn_nn__ -#define __cminpack_param_fcnder_nn__ -#define __cminpack_param_fcn_mn__ -#define __cminpack_param_fcnder_mn__ -#define __cminpack_param_fcnderstr_mn__ -#else -#define __cminpack_attr__ -#ifndef __cminpack_real__ -#define __cminpack_double__ -#define __cminpack_real__ double -#endif -#define __cminpack_type_fcn_nn__ typedef int (*cminpack_func_nn) -#define __cminpack_type_fcnder_nn__ typedef int (*cminpack_funcder_nn) -#define __cminpack_type_fcn_mn__ typedef int (*cminpack_func_mn) -#define __cminpack_type_fcnder_mn__ typedef int (*cminpack_funcder_mn) -#define __cminpack_type_fcnderstr_mn__ typedef int (*cminpack_funcderstr_mn) -#define __cminpack_decl_fcn_nn__ cminpack_func_nn fcn_nn, -#define __cminpack_decl_fcnder_nn__ cminpack_funcder_nn fcnder_nn, -#define __cminpack_decl_fcn_mn__ cminpack_func_mn fcn_mn, -#define __cminpack_decl_fcnder_mn__ cminpack_funcder_mn fcnder_mn, -#define __cminpack_decl_fcnderstr_mn__ cminpack_funcderstr_mn fcnderstr_mn, -#define __cminpack_param_fcn_nn__ fcn_nn, -#define __cminpack_param_fcnder_nn__ fcnder_nn, -#define __cminpack_param_fcn_mn__ fcn_mn, -#define __cminpack_param_fcnder_mn__ fcnder_mn, -#define __cminpack_param_fcnderstr_mn__ fcnderstr_mn, -#endif - -#ifdef __cminpack_double__ -#define __cminpack_func__(func) func -#endif - -#ifdef __cminpack_float__ -#define __cminpack_func__(func) s ## func -#endif - -#ifdef __cminpack_half__ -#define __cminpack_func__(func) h ## func -#endif - -/* Declarations for minpack */ - -/* Function types: */ -/* The first argument can be used to store extra function parameters, thus */ -/* avoiding the use of global variables. */ -/* the iflag parameter is input-only (with respect to the FORTRAN */ -/* version), the output iflag value is the return value of the function. */ -/* If iflag=0, the function shoulkd just print the current values (see */ -/* the nprint parameters below). */ - -/* for hybrd1 and hybrd: */ -/* calculate the functions at x and */ -/* return this vector in fvec. */ -/* return a negative value to terminate hybrd1/hybrd */ -__cminpack_type_fcn_nn__(void *p, int n, const __cminpack_real__ *x, __cminpack_real__ *fvec, int iflag ); - -/* for hybrj1 and hybrj */ -/* if iflag = 1 calculate the functions at x and */ -/* return this vector in fvec. do not alter fjac. */ -/* if iflag = 2 calculate the jacobian at x and */ -/* return this matrix in fjac. do not alter fvec. */ -/* return a negative value to terminate hybrj1/hybrj */ -__cminpack_type_fcnder_nn__(void *p, int n, const __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ *fjac, - int ldfjac, int iflag ); - -/* for lmdif1 and lmdif */ -/* calculate the functions at x and */ -/* return this vector in fvec. */ -/* if iflag = 1 the result is used to compute the residuals. */ -/* if iflag = 2 the result is used to compute the Jacobian by finite differences. */ -/* Jacobian computation requires exactly n function calls with iflag = 2. */ -/* return a negative value to terminate lmdif1/lmdif */ -__cminpack_type_fcn_mn__(void *p, int m, int n, const __cminpack_real__ *x, __cminpack_real__ *fvec, - int iflag ); - -/* for lmder1 and lmder */ -/* if iflag = 1 calculate the functions at x and */ -/* return this vector in fvec. do not alter fjac. */ -/* if iflag = 2 calculate the jacobian at x and */ -/* return this matrix in fjac. do not alter fvec. */ -/* return a negative value to terminate lmder1/lmder */ -__cminpack_type_fcnder_mn__(void *p, int m, int n, const __cminpack_real__ *x, __cminpack_real__ *fvec, - __cminpack_real__ *fjac, int ldfjac, int iflag ); - -/* for lmstr1 and lmstr */ -/* if iflag = 1 calculate the functions at x and */ -/* return this vector in fvec. */ -/* if iflag = i calculate the (i-1)-st row of the */ -/* jacobian at x and return this vector in fjrow. */ -/* return a negative value to terminate lmstr1/lmstr */ -__cminpack_type_fcnderstr_mn__(void *p, int m, int n, const __cminpack_real__ *x, __cminpack_real__ *fvec, - __cminpack_real__ *fjrow, int iflag ); - - - - - - -/* MINPACK functions: */ -/* the info parameter was removed from most functions: the return */ -/* value of the function is used instead. */ -/* The argument 'p' can be used to store extra function parameters, thus */ -/* avoiding the use of global variables. You can also think of it as a */ -/* 'this' pointer a la C++. */ - -/* find a zero of a system of N nonlinear functions in N variables by - a modification of the Powell hybrid method (Jacobian calculated by - a forward-difference approximation) */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(hybrd1)( __cminpack_decl_fcn_nn__ - void *p, int n, __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ tol, - __cminpack_real__ *wa, int lwa ); - -/* find a zero of a system of N nonlinear functions in N variables by - a modification of the Powell hybrid method (Jacobian calculated by - a forward-difference approximation, more general). */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(hybrd)( __cminpack_decl_fcn_nn__ - void *p, int n, __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ xtol, int maxfev, - int ml, int mu, __cminpack_real__ epsfcn, __cminpack_real__ *diag, int mode, - __cminpack_real__ factor, int nprint, int *nfev, - __cminpack_real__ *fjac, int ldfjac, __cminpack_real__ *r, int lr, __cminpack_real__ *qtf, - __cminpack_real__ *wa1, __cminpack_real__ *wa2, __cminpack_real__ *wa3, __cminpack_real__ *wa4); - -/* find a zero of a system of N nonlinear functions in N variables by - a modification of the Powell hybrid method (user-supplied Jacobian) */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(hybrj1)( __cminpack_decl_fcnder_nn__ void *p, int n, __cminpack_real__ *x, - __cminpack_real__ *fvec, __cminpack_real__ *fjac, int ldfjac, __cminpack_real__ tol, - __cminpack_real__ *wa, int lwa ); - -/* find a zero of a system of N nonlinear functions in N variables by - a modification of the Powell hybrid method (user-supplied Jacobian, - more general) */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(hybrj)( __cminpack_decl_fcnder_nn__ void *p, int n, __cminpack_real__ *x, - __cminpack_real__ *fvec, __cminpack_real__ *fjac, int ldfjac, __cminpack_real__ xtol, - int maxfev, __cminpack_real__ *diag, int mode, __cminpack_real__ factor, - int nprint, int *nfev, int *njev, __cminpack_real__ *r, - int lr, __cminpack_real__ *qtf, __cminpack_real__ *wa1, __cminpack_real__ *wa2, - __cminpack_real__ *wa3, __cminpack_real__ *wa4 ); - -/* minimize the sum of the squares of nonlinear functions in N - variables by a modification of the Levenberg-Marquardt algorithm - (Jacobian calculated by a forward-difference approximation) */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(lmdif1)( __cminpack_decl_fcn_mn__ - void *p, int m, int n, __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ tol, - int *iwa, __cminpack_real__ *wa, int lwa ); - -/* minimize the sum of the squares of nonlinear functions in N - variables by a modification of the Levenberg-Marquardt algorithm - (Jacobian calculated by a forward-difference approximation, more - general) */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(lmdif)( __cminpack_decl_fcn_mn__ - void *p, int m, int n, __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ ftol, - __cminpack_real__ xtol, __cminpack_real__ gtol, int maxfev, __cminpack_real__ epsfcn, - __cminpack_real__ *diag, int mode, __cminpack_real__ factor, int nprint, - int *nfev, __cminpack_real__ *fjac, int ldfjac, int *ipvt, - __cminpack_real__ *qtf, __cminpack_real__ *wa1, __cminpack_real__ *wa2, __cminpack_real__ *wa3, - __cminpack_real__ *wa4 ); - -/* minimize the sum of the squares of nonlinear functions in N - variables by a modification of the Levenberg-Marquardt algorithm - (user-supplied Jacobian) */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(lmder1)( __cminpack_decl_fcnder_mn__ - void *p, int m, int n, __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ *fjac, - int ldfjac, __cminpack_real__ tol, int *ipvt, - __cminpack_real__ *wa, int lwa ); - -/* minimize the sum of the squares of nonlinear functions in N - variables by a modification of the Levenberg-Marquardt algorithm - (user-supplied Jacobian, more general) */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(lmder)( __cminpack_decl_fcnder_mn__ - void *p, int m, int n, __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ *fjac, - int ldfjac, __cminpack_real__ ftol, __cminpack_real__ xtol, __cminpack_real__ gtol, - int maxfev, __cminpack_real__ *diag, int mode, __cminpack_real__ factor, - int nprint, int *nfev, int *njev, int *ipvt, - __cminpack_real__ *qtf, __cminpack_real__ *wa1, __cminpack_real__ *wa2, __cminpack_real__ *wa3, - __cminpack_real__ *wa4 ); - -/* minimize the sum of the squares of nonlinear functions in N - variables by a modification of the Levenberg-Marquardt algorithm - (user-supplied Jacobian, minimal storage) */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(lmstr1)( __cminpack_decl_fcnderstr_mn__ void *p, int m, int n, - __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ *fjac, int ldfjac, - __cminpack_real__ tol, int *ipvt, __cminpack_real__ *wa, int lwa ); - -/* minimize the sum of the squares of nonlinear functions in N - variables by a modification of the Levenberg-Marquardt algorithm - (user-supplied Jacobian, minimal storage, more general) */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(lmstr)( __cminpack_decl_fcnderstr_mn__ void *p, int m, - int n, __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ *fjac, - int ldfjac, __cminpack_real__ ftol, __cminpack_real__ xtol, __cminpack_real__ gtol, - int maxfev, __cminpack_real__ *diag, int mode, __cminpack_real__ factor, - int nprint, int *nfev, int *njev, int *ipvt, - __cminpack_real__ *qtf, __cminpack_real__ *wa1, __cminpack_real__ *wa2, __cminpack_real__ *wa3, - __cminpack_real__ *wa4 ); - -__cminpack_attr__ -void CMINPACK_EXPORT __cminpack_func__(chkder)( int m, int n, const __cminpack_real__ *x, __cminpack_real__ *fvec, __cminpack_real__ *fjac, - int ldfjac, __cminpack_real__ *xp, __cminpack_real__ *fvecp, int mode, - __cminpack_real__ *err ); - -__cminpack_attr__ -__cminpack_real__ CMINPACK_EXPORT __cminpack_func__(dpmpar)( int i ); - -__cminpack_attr__ -__cminpack_real__ CMINPACK_EXPORT __cminpack_func__(enorm)( int n, const __cminpack_real__ *x ); - -/* compute a forward-difference approximation to the m by n jacobian - matrix associated with a specified problem of m functions in n - variables. */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(fdjac2)(__cminpack_decl_fcn_mn__ - void *p, int m, int n, __cminpack_real__ *x, const __cminpack_real__ *fvec, __cminpack_real__ *fjac, - int ldfjac, __cminpack_real__ epsfcn, __cminpack_real__ *wa); - -/* compute a forward-difference approximation to the n by n jacobian - matrix associated with a specified problem of n functions in n - variables. if the jacobian has a banded form, then function - evaluations are saved by only approximating the nonzero terms. */ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(fdjac1)(__cminpack_decl_fcn_nn__ - void *p, int n, __cminpack_real__ *x, const __cminpack_real__ *fvec, __cminpack_real__ *fjac, int ldfjac, - int ml, int mu, __cminpack_real__ epsfcn, __cminpack_real__ *wa1, - __cminpack_real__ *wa2); - -/* compute inverse(JtJ) after a run of lmdif or lmder. The covariance matrix is obtained - by scaling the result by enorm(y)**2/(m-n). If JtJ is singular and k = rank(J), the - pseudo-inverse is computed, and the result has to be scaled by enorm(y)**2/(m-k). */ -__cminpack_attr__ -void CMINPACK_EXPORT __cminpack_func__(covar)(int n, __cminpack_real__ *r, int ldr, - const int *ipvt, __cminpack_real__ tol, __cminpack_real__ *wa); - -/* covar1 estimates the variance-covariance matrix: - C = sigma**2 (JtJ)**+ - where (JtJ)**+ is the inverse of JtJ or the pseudo-inverse of JtJ (in case J does not have full rank), - and sigma**2 = fsumsq / (m - k) - where fsumsq is the residual sum of squares and k is the rank of J. - The function returns 0 if J has full rank, else the rank of J. -*/ -__cminpack_attr__ -int CMINPACK_EXPORT __cminpack_func__(covar1)(int m, int n, __cminpack_real__ fsumsq, __cminpack_real__ *r, int ldr, - const int *ipvt, __cminpack_real__ tol, __cminpack_real__ *wa); - -/* internal MINPACK subroutines */ -__cminpack_attr__ -void __cminpack_func__(dogleg)(int n, const __cminpack_real__ *r, int lr, - const __cminpack_real__ *diag, const __cminpack_real__ *qtb, __cminpack_real__ delta, __cminpack_real__ *x, - __cminpack_real__ *wa1, __cminpack_real__ *wa2); -__cminpack_attr__ -void __cminpack_func__(qrfac)(int m, int n, __cminpack_real__ *a, int - lda, int pivot, int *ipvt, int lipvt, __cminpack_real__ *rdiag, - __cminpack_real__ *acnorm, __cminpack_real__ *wa); -__cminpack_attr__ -void __cminpack_func__(qrsolv)(int n, __cminpack_real__ *r, int ldr, - const int *ipvt, const __cminpack_real__ *diag, const __cminpack_real__ *qtb, __cminpack_real__ *x, - __cminpack_real__ *sdiag, __cminpack_real__ *wa); -__cminpack_attr__ -void __cminpack_func__(qform)(int m, int n, __cminpack_real__ *q, int - ldq, __cminpack_real__ *wa); -__cminpack_attr__ -void __cminpack_func__(r1updt)(int m, int n, __cminpack_real__ *s, int - ls, const __cminpack_real__ *u, __cminpack_real__ *v, __cminpack_real__ *w, int *sing); -__cminpack_attr__ -void __cminpack_func__(r1mpyq)(int m, int n, __cminpack_real__ *a, int - lda, const __cminpack_real__ *v, const __cminpack_real__ *w); -__cminpack_attr__ -void __cminpack_func__(lmpar)(int n, __cminpack_real__ *r, int ldr, - const int *ipvt, const __cminpack_real__ *diag, const __cminpack_real__ *qtb, __cminpack_real__ delta, - __cminpack_real__ *par, __cminpack_real__ *x, __cminpack_real__ *sdiag, __cminpack_real__ *wa1, - __cminpack_real__ *wa2); -__cminpack_attr__ -void __cminpack_func__(rwupdt)(int n, __cminpack_real__ *r, int ldr, - const __cminpack_real__ *w, __cminpack_real__ *b, __cminpack_real__ *alpha, __cminpack_real__ *cos, - __cminpack_real__ *sin); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __CMINPACK_H__ */ diff --git a/ast/cminpack/cminpackP.h b/ast/cminpack/cminpackP.h deleted file mode 100644 index 4e8ba7b..0000000 --- a/ast/cminpack/cminpackP.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Internal header file for cminpack, by Frederic Devernay. */ -#ifndef __CMINPACKP_H__ -#define __CMINPACKP_H__ - -#ifndef __CMINPACK_H__ -#error "cminpackP.h in an internal cminpack header, and must be included after all other headers (including cminpack.h)" -#endif - -#if (defined (USE_CBLAS) || defined (USE_LAPACK)) && !defined (__cminpack_double__) -#error "cminpack can use cblas and lapack only in double precision mode" -#endif - -#ifdef USE_CBLAS -#ifdef __APPLE__ -#include -#else -#include -#endif -#define __cminpack_enorm__(n,x) cblas_dnrm2(n,x,1) -#else -#define __cminpack_enorm__(n,x) __cminpack_func__(enorm)(n,x) -#endif - -#ifdef USE_LAPACK -#ifdef __APPLE__ -#include -#else -#if defined(__LP64__) /* In LP64 match sizes with the 32 bit ABI */ -typedef int __CLPK_integer; -typedef int __CLPK_logical; -typedef float __CLPK_real; -typedef double __CLPK_doublereal; -typedef __CLPK_logical (*__CLPK_L_fp)(); -typedef int __CLPK_ftnlen; -#else -typedef long int __CLPK_integer; -typedef long int __CLPK_logical; -typedef float __CLPK_real; -typedef double __CLPK_doublereal; -typedef __CLPK_logical (*__CLPK_L_fp)(); -typedef long int __CLPK_ftnlen; -#endif -//extern void dlartg_(double *f, double *g, double *cs, double *sn, double *r__); -int dlartg_(__CLPK_doublereal *f, __CLPK_doublereal *g, __CLPK_doublereal *cs, - __CLPK_doublereal *sn, __CLPK_doublereal *r__) -//extern void dgeqp3_(int *m, int *n, double *a, int *lda, int *jpvt, double *tau, double *work, int *lwork, int *info); -int dgeqp3_(__CLPK_integer *m, __CLPK_integer *n, __CLPK_doublereal *a, __CLPK_integer * - lda, __CLPK_integer *jpvt, __CLPK_doublereal *tau, __CLPK_doublereal *work, __CLPK_integer *lwork, - __CLPK_integer *info) -//extern void dgeqrf_(int *m, int *n, double *a, int *lda, double *tau, double *work, int *lwork, int *info); -int dgeqrf_(__CLPK_integer *m, __CLPK_integer *n, __CLPK_doublereal *a, __CLPK_integer * - lda, __CLPK_doublereal *tau, __CLPK_doublereal *work, __CLPK_integer *lwork, __CLPK_integer *info) -#endif -#endif - -#define real __cminpack_real__ -#define min(a,b) ((a) <= (b) ? (a) : (b)) -#define max(a,b) ((a) >= (b) ? (a) : (b)) -#define TRUE_ (1) -#define FALSE_ (0) - -#endif /* !__CMINPACKP_H__ */ diff --git a/ast/cminpack/dpmpar.c b/ast/cminpack/dpmpar.c deleted file mode 100644 index 81c6fcd..0000000 --- a/ast/cminpack/dpmpar.c +++ /dev/null @@ -1,201 +0,0 @@ -#include "cminpack.h" -#include -#include "cminpackP.h" - -#define double_EPSILON DBL_EPSILON -#define double_MIN DBL_MIN -#define double_MAX DBL_MAX -#define float_EPSILON FLT_EPSILON -#define float_MIN FLT_MIN -#define float_MAX FLT_MAX -#define half_EPSILON HALF_EPSILON -#define half_MIN HALF_NRM_MIN -#define half_MAX HALF_MAX - -#define DPMPAR(type,X) _DPMPAR(type,X) -#define _DPMPAR(type,X) type ## _ ## X - -__cminpack_attr__ -real __cminpack_func__(dpmpar)(int i) -{ -/* ********** */ - -/* Function dpmpar */ - -/* This function provides double precision machine parameters */ -/* when the appropriate set of data statements is activated (by */ -/* removing the c from column 1) and all other data statements are */ -/* rendered inactive. Most of the parameter values were obtained */ -/* from the corresponding Bell Laboratories Port Library function. */ - -/* The function statement is */ - -/* double precision function dpmpar(i) */ - -/* where */ - -/* i is an integer input variable set to 1, 2, or 3 which */ -/* selects the desired machine parameter. If the machine has */ -/* t base b digits and its smallest and largest exponents are */ -/* emin and emax, respectively, then these parameters are */ - -/* dpmpar(1) = b**(1 - t), the machine precision, */ - -/* dpmpar(2) = b**(emin - 1), the smallest magnitude, */ - -/* dpmpar(3) = b**emax*(1 - b**(-t)), the largest magnitude. */ - -/* Argonne National Laboratory. MINPACK Project. November 1996. */ -/* Burton S. Garbow, Kenneth E. Hillstrom, Jorge J. More' */ - -/* ********** */ - -/* Machine constants for the IBM 360/370 series, */ -/* the Amdahl 470/V6, the ICL 2900, the Itel AS/6, */ -/* the Xerox Sigma 5/7/9 and the Sel systems 85/86. */ - -/* data mcheps(1),mcheps(2) / z34100000, z00000000 / */ -/* data minmag(1),minmag(2) / z00100000, z00000000 / */ -/* data maxmag(1),maxmag(2) / z7fffffff, zffffffff / */ - -/* Machine constants for the Honeywell 600/6000 series. */ - -/* data mcheps(1),mcheps(2) / o606400000000, o000000000000 / */ -/* data minmag(1),minmag(2) / o402400000000, o000000000000 / */ -/* data maxmag(1),maxmag(2) / o376777777777, o777777777777 / */ - -/* Machine constants for the CDC 6000/7000 series. */ - -/* data mcheps(1) / 15614000000000000000b / */ -/* data mcheps(2) / 15010000000000000000b / */ - -/* data minmag(1) / 00604000000000000000b / */ -/* data minmag(2) / 00000000000000000000b / */ - -/* data maxmag(1) / 37767777777777777777b / */ -/* data maxmag(2) / 37167777777777777777b / */ - -/* Machine constants for the PDP-10 (KA processor). */ - -/* data mcheps(1),mcheps(2) / "114400000000, "000000000000 / */ -/* data minmag(1),minmag(2) / "033400000000, "000000000000 / */ -/* data maxmag(1),maxmag(2) / "377777777777, "344777777777 / */ - -/* Machine constants for the PDP-10 (KI processor). */ - -/* data mcheps(1),mcheps(2) / "104400000000, "000000000000 / */ -/* data minmag(1),minmag(2) / "000400000000, "000000000000 / */ -/* data maxmag(1),maxmag(2) / "377777777777, "377777777777 / */ - -/* Machine constants for the PDP-11. */ - -/* data mcheps(1),mcheps(2) / 9472, 0 / */ -/* data mcheps(3),mcheps(4) / 0, 0 / */ - -/* data minmag(1),minmag(2) / 128, 0 / */ -/* data minmag(3),minmag(4) / 0, 0 / */ - -/* data maxmag(1),maxmag(2) / 32767, -1 / */ -/* data maxmag(3),maxmag(4) / -1, -1 / */ - -/* Machine constants for the Burroughs 6700/7700 systems. */ - -/* data mcheps(1) / o1451000000000000 / */ -/* data mcheps(2) / o0000000000000000 / */ - -/* data minmag(1) / o1771000000000000 / */ -/* data minmag(2) / o7770000000000000 / */ - -/* data maxmag(1) / o0777777777777777 / */ -/* data maxmag(2) / o7777777777777777 / */ - -/* Machine constants for the Burroughs 5700 system. */ - -/* data mcheps(1) / o1451000000000000 / */ -/* data mcheps(2) / o0000000000000000 / */ - -/* data minmag(1) / o1771000000000000 / */ -/* data minmag(2) / o0000000000000000 / */ - -/* data maxmag(1) / o0777777777777777 / */ -/* data maxmag(2) / o0007777777777777 / */ - -/* Machine constants for the Burroughs 1700 system. */ - -/* data mcheps(1) / zcc6800000 / */ -/* data mcheps(2) / z000000000 / */ - -/* data minmag(1) / zc00800000 / */ -/* data minmag(2) / z000000000 / */ - -/* data maxmag(1) / zdffffffff / */ -/* data maxmag(2) / zfffffffff / */ - -/* Machine constants for the Univac 1100 series. */ - -/* data mcheps(1),mcheps(2) / o170640000000, o000000000000 / */ -/* data minmag(1),minmag(2) / o000040000000, o000000000000 / */ -/* data maxmag(1),maxmag(2) / o377777777777, o777777777777 / */ - -/* Machine constants for the Data General Eclipse S/200. */ - -/* Note - it may be appropriate to include the following card - */ -/* static dmach(3) */ - -/* data minmag/20k,3*0/,maxmag/77777k,3*177777k/ */ -/* data mcheps/32020k,3*0/ */ - -/* Machine constants for the Harris 220. */ - -/* data mcheps(1),mcheps(2) / '20000000, '00000334 / */ -/* data minmag(1),minmag(2) / '20000000, '00000201 / */ -/* data maxmag(1),maxmag(2) / '37777777, '37777577 / */ - -/* Machine constants for the Cray-1. */ - -/* data mcheps(1) / 0376424000000000000000b / */ -/* data mcheps(2) / 0000000000000000000000b / */ - -/* data minmag(1) / 0200034000000000000000b / */ -/* data minmag(2) / 0000000000000000000000b / */ - -/* data maxmag(1) / 0577777777777777777777b / */ -/* data maxmag(2) / 0000007777777777777776b / */ - -/* Machine constants for the Prime 400. */ - -/* data mcheps(1),mcheps(2) / :10000000000, :00000000123 / */ -/* data minmag(1),minmag(2) / :10000000000, :00000100000 / */ -/* data maxmag(1),maxmag(2) / :17777777777, :37777677776 / */ - -/* Machine constants for the VAX-11. */ - -/* data mcheps(1),mcheps(2) / 9472, 0 / */ -/* data minmag(1),minmag(2) / 128, 0 / */ -/* data maxmag(1),maxmag(2) / -32769, -1 / */ - -/* Machine constants for IEEE machines. */ - -/* data dmach(1) /2.22044604926d-16/ */ -/* data dmach(2) /2.22507385852d-308/ */ -/* data dmach(3) /1.79769313485d+308/ */ - - switch(i) { - case 1: - return DPMPAR(real,EPSILON); /* 2.2204460492503131e-16 | 1.19209290e-07F */ - case 2: - return DPMPAR(real,MIN); /* 2.2250738585072014e-308 | 1.17549435e-38F */ - default: - return DPMPAR(real,MAX); /* 1.7976931348623157e+308 | 3.40282347e+38F */ - } - -/* Last card of function dpmpar. */ - -} /* dpmpar_ */ - -#undef mcheps -#undef maxmag -#undef minmag -#undef dmach - - diff --git a/ast/cminpack/enorm.c b/ast/cminpack/enorm.c deleted file mode 100644 index ad10824..0000000 --- a/ast/cminpack/enorm.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "cminpack.h" -#include -#include "cminpackP.h" - -/* - About the values for rdwarf and rgiant. - - The original values, both in signe-precision FORTRAN source code and in double-precision code were: -#define rdwarf 3.834e-20 -#define rgiant 1.304e19 - See for example: - http://www.netlib.org/slatec/src/denorm.f - http://www.netlib.org/slatec/src/enorm.f - However, rdwarf is smaller than sqrt(FLT_MIN) = 1.0842021724855044e-19, so that rdwarf**2 will - underflow. This contradicts the constraints expressed in the comments below. - - We changed these constants to be sqrt(dpmpar(2))*0.9 and sqrt(dpmpar(3))*0.9, as proposed by the - implementation found in MPFIT http://cow.physics.wisc.edu/~craigm/idl/fitting.html -*/ - -#define double_dwarf (1.4916681462400413e-154*0.9) -#define double_giant (1.3407807929942596e+154*0.9) -#define float_dwarf (1.0842021724855044e-19f*0.9f) -#define float_giant (1.8446743523953730e+19f*0.9f) -#define half_dwarf (2.4414062505039999e-4f*0.9f) -#define half_giant (255.93749236874225497222f*0.9f) - -#define dwarf(type) _dwarf(type) -#define _dwarf(type) type ## _dwarf -#define giant(type) _giant(type) -#define _giant(type) type ## _giant - -#define rdwarf dwarf(real) -#define rgiant giant(real) - -__cminpack_attr__ -real __cminpack_func__(enorm)(int n, const real *x) -{ -#ifdef USE_CBLAS - return cblas_dnrm2(n, x, 1); -#else /* !USE_CBLAS */ - /* System generated locals */ - real ret_val, d1; - - /* Local variables */ - int i; - real s1, s2, s3, xabs, x1max, x3max, agiant, floatn; - -/* ********** */ - -/* function enorm */ - -/* given an n-vector x, this function calculates the */ -/* euclidean norm of x. */ - -/* the euclidean norm is computed by accumulating the sum of */ -/* squares in three different sums. the sums of squares for the */ -/* small and large components are scaled so that no overflows */ -/* occur. non-destructive underflows are permitted. underflows */ -/* and overflows do not occur in the computation of the unscaled */ -/* sum of squares for the intermediate components. */ -/* the definitions of small, intermediate and large components */ -/* depend on two constants, rdwarf and rgiant. the main */ -/* restrictions on these constants are that rdwarf**2 not */ -/* underflow and rgiant**2 not overflow. the constants */ -/* given here are suitable for every known computer. */ - -/* the function statement is */ - -/* double precision function enorm(n,x) */ - -/* where */ - -/* n is a positive integer input variable. */ - -/* x is an input array of length n. */ - -/* subprograms called */ - -/* fortran-supplied ... dabs,dsqrt */ - -/* argonne national laboratory. minpack project. march 1980. */ -/* burton s. garbow, kenneth e. hillstrom, jorge j. more */ - -/* ********** */ - - s1 = 0.; - s2 = 0.; - s3 = 0.; - x1max = 0.; - x3max = 0.; - floatn = (real) (n); - agiant = rgiant / floatn; - for (i = 0; i < n; ++i) { - xabs = fabs(x[i]); - if (xabs <= rdwarf || xabs >= agiant) { - if (xabs > rdwarf) { - -/* sum for large components. */ - - if (xabs > x1max) { - /* Computing 2nd power */ - d1 = x1max / xabs; - s1 = 1. + s1 * (d1 * d1); - x1max = xabs; - } else { - /* Computing 2nd power */ - d1 = xabs / x1max; - s1 += d1 * d1; - } - } else { - -/* sum for small components. */ - - if (xabs > x3max) { - /* Computing 2nd power */ - d1 = x3max / xabs; - s3 = 1. + s3 * (d1 * d1); - x3max = xabs; - } else { - if (xabs != 0.) { - /* Computing 2nd power */ - d1 = xabs / x3max; - s3 += d1 * d1; - } - } - } - } else { - -/* sum for intermediate components. */ - - /* Computing 2nd power */ - s2 += xabs * xabs; - } - } - -/* calculation of norm. */ - - if (s1 != 0.) { - ret_val = x1max * sqrt(s1 + (s2 / x1max) / x1max); - } else { - if (s2 != 0.) { - if (s2 >= x3max) { - ret_val = sqrt(s2 * (1. + (x3max / s2) * (x3max * s3))); - } else { - ret_val = sqrt(x3max * ((s2 / x3max) + (x3max * s3))); - } - } else { - ret_val = x3max * sqrt(s3); - } - } - return ret_val; - -/* last card of function enorm. */ -#endif /* !USE_CBLAS */ -} /* enorm_ */ - diff --git a/ast/cminpack/lmder.c b/ast/cminpack/lmder.c deleted file mode 100644 index 7f57428..0000000 --- a/ast/cminpack/lmder.c +++ /dev/null @@ -1,526 +0,0 @@ -#include "cminpack.h" -#include -#include "cminpackP.h" - -__cminpack_attr__ -int __cminpack_func__(lmder)(__cminpack_decl_fcnder_mn__ void *p, int m, int n, real *x, - real *fvec, real *fjac, int ldfjac, real ftol, - real xtol, real gtol, int maxfev, real * - diag, int mode, real factor, int nprint, - int *nfev, int *njev, int *ipvt, real *qtf, - real *wa1, real *wa2, real *wa3, real *wa4) -{ - /* Initialized data */ - -#define p1 .1 -#define p5 .5 -#define p25 .25 -#define p75 .75 -#define p0001 1e-4 - - /* System generated locals */ - real d1, d2; - - /* Local variables */ - int i, j, l; - real par, sum; - int iter; - real temp, temp1, temp2; - int iflag; - real delta = 0.; - real ratio; - real fnorm, gnorm, pnorm, xnorm = 0., fnorm1, actred, dirder, - epsmch, prered; - int info; - -/* ********** */ - -/* subroutine lmder */ - -/* the purpose of lmder is to minimize the sum of the squares of */ -/* m nonlinear functions in n variables by a modification of */ -/* the levenberg-marquardt algorithm. the user must provide a */ -/* subroutine which calculates the functions and the jacobian. */ - -/* the subroutine statement is */ - -/* subroutine lmder(fcn,m,n,x,fvec,fjac,ldfjac,ftol,xtol,gtol, */ -/* maxfev,diag,mode,factor,nprint,info,nfev, */ -/* njev,ipvt,qtf,wa1,wa2,wa3,wa4) */ - -/* where */ - -/* fcn is the name of the user-supplied subroutine which */ -/* calculates the functions and the jacobian. fcn must */ -/* be declared in an external statement in the user */ -/* calling program, and should be written as follows. */ - -/* subroutine fcn(m,n,x,fvec,fjac,ldfjac,iflag) */ -/* integer m,n,ldfjac,iflag */ -/* double precision x(n),fvec(m),fjac(ldfjac,n) */ -/* ---------- */ -/* if iflag = 1 calculate the functions at x and */ -/* return this vector in fvec. do not alter fjac. */ -/* if iflag = 2 calculate the jacobian at x and */ -/* return this matrix in fjac. do not alter fvec. */ -/* ---------- */ -/* return */ -/* end */ - -/* the value of iflag should not be changed by fcn unless */ -/* the user wants to terminate execution of lmder. */ -/* in this case set iflag to a negative integer. */ - -/* m is a positive integer input variable set to the number */ -/* of functions. */ - -/* n is a positive integer input variable set to the number */ -/* of variables. n must not exceed m. */ - -/* x is an array of length n. on input x must contain */ -/* an initial estimate of the solution vector. on output x */ -/* contains the final estimate of the solution vector. */ - -/* fvec is an output array of length m which contains */ -/* the functions evaluated at the output x. */ - -/* fjac is an output m by n array. the upper n by n submatrix */ -/* of fjac contains an upper triangular matrix r with */ -/* diagonal elements of nonincreasing magnitude such that */ - -/* t t t */ -/* p *(jac *jac)*p = r *r, */ - -/* where p is a permutation matrix and jac is the final */ -/* calculated jacobian. column j of p is column ipvt(j) */ -/* (see below) of the identity matrix. the lower trapezoidal */ -/* part of fjac contains information generated during */ -/* the computation of r. */ - -/* ldfjac is a positive integer input variable not less than m */ -/* which specifies the leading dimension of the array fjac. */ - -/* ftol is a nonnegative input variable. termination */ -/* occurs when both the actual and predicted relative */ -/* reductions in the sum of squares are at most ftol. */ -/* therefore, ftol measures the relative error desired */ -/* in the sum of squares. */ - -/* xtol is a nonnegative input variable. termination */ -/* occurs when the relative error between two consecutive */ -/* iterates is at most xtol. therefore, xtol measures the */ -/* relative error desired in the approximate solution. */ - -/* gtol is a nonnegative input variable. termination */ -/* occurs when the cosine of the angle between fvec and */ -/* any column of the jacobian is at most gtol in absolute */ -/* value. therefore, gtol measures the orthogonality */ -/* desired between the function vector and the columns */ -/* of the jacobian. */ - -/* maxfev is a positive integer input variable. termination */ -/* occurs when the number of calls to fcn with iflag = 1 */ -/* has reached maxfev. */ - -/* diag is an array of length n. if mode = 1 (see */ -/* below), diag is internally set. if mode = 2, diag */ -/* must contain positive entries that serve as */ -/* multiplicative scale factors for the variables. */ - -/* mode is an integer input variable. if mode = 1, the */ -/* variables will be scaled internally. if mode = 2, */ -/* the scaling is specified by the input diag. other */ -/* values of mode are equivalent to mode = 1. */ - -/* factor is a positive input variable used in determining the */ -/* initial step bound. this bound is set to the product of */ -/* factor and the euclidean norm of diag*x if nonzero, or else */ -/* to factor itself. in most cases factor should lie in the */ -/* interval (.1,100.).100. is a generally recommended value. */ - -/* nprint is an integer input variable that enables controlled */ -/* printing of iterates if it is positive. in this case, */ -/* fcn is called with iflag = 0 at the beginning of the first */ -/* iteration and every nprint iterations thereafter and */ -/* immediately prior to return, with x, fvec, and fjac */ -/* available for printing. fvec and fjac should not be */ -/* altered. if nprint is not positive, no special calls */ -/* of fcn with iflag = 0 are made. */ - -/* info is an integer output variable. if the user has */ -/* terminated execution, info is set to the (negative) */ -/* value of iflag. see description of fcn. otherwise, */ -/* info is set as follows. */ - -/* info = 0 improper input parameters. */ - -/* info = 1 both actual and predicted relative reductions */ -/* in the sum of squares are at most ftol. */ - -/* info = 2 relative error between two consecutive iterates */ -/* is at most xtol. */ - -/* info = 3 conditions for info = 1 and info = 2 both hold. */ - -/* info = 4 the cosine of the angle between fvec and any */ -/* column of the jacobian is at most gtol in */ -/* absolute value. */ - -/* info = 5 number of calls to fcn with iflag = 1 has */ -/* reached maxfev. */ - -/* info = 6 ftol is too small. no further reduction in */ -/* the sum of squares is possible. */ - -/* info = 7 xtol is too small. no further improvement in */ -/* the approximate solution x is possible. */ - -/* info = 8 gtol is too small. fvec is orthogonal to the */ -/* columns of the jacobian to machine precision. */ - -/* nfev is an integer output variable set to the number of */ -/* calls to fcn with iflag = 1. */ - -/* njev is an integer output variable set to the number of */ -/* calls to fcn with iflag = 2. */ - -/* ipvt is an integer output array of length n. ipvt */ -/* defines a permutation matrix p such that jac*p = q*r, */ -/* where jac is the final calculated jacobian, q is */ -/* orthogonal (not stored), and r is upper triangular */ -/* with diagonal elements of nonincreasing magnitude. */ -/* column j of p is column ipvt(j) of the identity matrix. */ - -/* qtf is an output array of length n which contains */ -/* the first n elements of the vector (q transpose)*fvec. */ - -/* wa1, wa2, and wa3 are work arrays of length n. */ - -/* wa4 is a work array of length m. */ - -/* subprograms called */ - -/* user-supplied ...... fcn */ - -/* minpack-supplied ... dpmpar,enorm,lmpar,qrfac */ - -/* fortran-supplied ... dabs,dmax1,dmin1,dsqrt,mod */ - -/* argonne national laboratory. minpack project. march 1980. */ -/* burton s. garbow, kenneth e. hillstrom, jorge j. more */ - -/* ********** */ - -/* epsmch is the machine precision. */ - - epsmch = __cminpack_func__(dpmpar)(1); - - info = 0; - iflag = 0; - *nfev = 0; - *njev = 0; - -/* check the input parameters for errors. */ - - if (n <= 0 || m < n || ldfjac < m || ftol < 0. || xtol < 0. || - gtol < 0. || maxfev <= 0 || factor <= 0.) { - goto TERMINATE; - } - if (mode == 2) { - for (j = 0; j < n; ++j) { - if (diag[j] <= 0.) { - goto TERMINATE; - } - } - } - -/* evaluate the function at the starting point */ -/* and calculate its norm. */ - - iflag = fcnder_mn(p, m, n, x, fvec, fjac, ldfjac, 1); - *nfev = 1; - if (iflag < 0) { - goto TERMINATE; - } - fnorm = __cminpack_enorm__(m, fvec); - -/* initialize levenberg-marquardt parameter and iteration counter. */ - - par = 0.; - iter = 1; - -/* beginning of the outer loop. */ - - for (;;) { - -/* calculate the jacobian matrix. */ - - iflag = fcnder_mn(p, m, n, x, fvec, fjac, ldfjac, 2); - ++(*njev); - if (iflag < 0) { - goto TERMINATE; - } - -/* if requested, call fcn to enable printing of iterates. */ - - if (nprint > 0) { - iflag = 0; - if ((iter - 1) % nprint == 0) { - iflag = fcnder_mn(p, m, n, x, fvec, fjac, ldfjac, 0); - } - if (iflag < 0) { - goto TERMINATE; - } - } - -/* compute the qr factorization of the jacobian. */ - - __cminpack_func__(qrfac)(m, n, fjac, ldfjac, TRUE_, ipvt, n, - wa1, wa2, wa3); - -/* on the first iteration and if mode is 1, scale according */ -/* to the norms of the columns of the initial jacobian. */ - - if (iter == 1) { - if (mode != 2) { - for (j = 0; j < n; ++j) { - diag[j] = wa2[j]; - if (wa2[j] == 0.) { - diag[j] = 1.; - } - } - } - -/* on the first iteration, calculate the norm of the scaled x */ -/* and initialize the step bound delta. */ - - for (j = 0; j < n; ++j) { - wa3[j] = diag[j] * x[j]; - } - xnorm = __cminpack_enorm__(n, wa3); - delta = factor * xnorm; - if (delta == 0.) { - delta = factor; - } - } - -/* form (q transpose)*fvec and store the first n components in */ -/* qtf. */ - - for (i = 0; i < m; ++i) { - wa4[i] = fvec[i]; - } - for (j = 0; j < n; ++j) { - if (fjac[j + j * ldfjac] != 0.) { - sum = 0.; - for (i = j; i < m; ++i) { - sum += fjac[i + j * ldfjac] * wa4[i]; - } - temp = -sum / fjac[j + j * ldfjac]; - for (i = j; i < m; ++i) { - wa4[i] += fjac[i + j * ldfjac] * temp; - } - } - fjac[j + j * ldfjac] = wa1[j]; - qtf[j] = wa4[j]; - } - -/* compute the norm of the scaled gradient. */ - - gnorm = 0.; - if (fnorm != 0.) { - for (j = 0; j < n; ++j) { - l = ipvt[j]-1; - if (wa2[l] != 0.) { - sum = 0.; - for (i = 0; i <= j; ++i) { - sum += fjac[i + j * ldfjac] * (qtf[i] / fnorm); - } - /* Computing MAX */ - d1 = fabs(sum / wa2[l]); - gnorm = max(gnorm,d1); - } - } - } - -/* test for convergence of the gradient norm. */ - - if (gnorm <= gtol) { - info = 4; - } - if (info != 0) { - goto TERMINATE; - } - -/* rescale if necessary. */ - - if (mode != 2) { - for (j = 0; j < n; ++j) { - /* Computing MAX */ - d1 = diag[j], d2 = wa2[j]; - diag[j] = max(d1,d2); - } - } - -/* beginning of the inner loop. */ - - do { - -/* determine the levenberg-marquardt parameter. */ - - __cminpack_func__(lmpar)(n, fjac, ldfjac, ipvt, diag, qtf, delta, - &par, wa1, wa2, wa3, wa4); - -/* store the direction p and x + p. calculate the norm of p. */ - - for (j = 0; j < n; ++j) { - wa1[j] = -wa1[j]; - wa2[j] = x[j] + wa1[j]; - wa3[j] = diag[j] * wa1[j]; - } - pnorm = __cminpack_enorm__(n, wa3); - -/* on the first iteration, adjust the initial step bound. */ - - if (iter == 1) { - delta = min(delta,pnorm); - } - -/* evaluate the function at x + p and calculate its norm. */ - - iflag = fcnder_mn(p, m, n, wa2, wa4, fjac, ldfjac, 1); - ++(*nfev); - if (iflag < 0) { - goto TERMINATE; - } - fnorm1 = __cminpack_enorm__(m, wa4); - -/* compute the scaled actual reduction. */ - - actred = -1.; - if (p1 * fnorm1 < fnorm) { - /* Computing 2nd power */ - d1 = fnorm1 / fnorm; - actred = 1. - d1 * d1; - } - -/* compute the scaled predicted reduction and */ -/* the scaled directional derivative. */ - - for (j = 0; j < n; ++j) { - wa3[j] = 0.; - l = ipvt[j]-1; - temp = wa1[l]; - for (i = 0; i <= j; ++i) { - wa3[i] += fjac[i + j * ldfjac] * temp; - } - } - temp1 = __cminpack_enorm__(n, wa3) / fnorm; - temp2 = (sqrt(par) * pnorm) / fnorm; - prered = temp1 * temp1 + temp2 * temp2 / p5; - dirder = -(temp1 * temp1 + temp2 * temp2); - -/* compute the ratio of the actual to the predicted */ -/* reduction. */ - - ratio = 0.; - if (prered != 0.) { - ratio = actred / prered; - } - -/* update the step bound. */ - - if (ratio <= p25) { - if (actred >= 0.) { - temp = p5; - } else { - temp = p5 * dirder / (dirder + p5 * actred); - } - if (p1 * fnorm1 >= fnorm || temp < p1) { - temp = p1; - } - /* Computing MIN */ - d1 = pnorm / p1; - delta = temp * min(delta,d1); - par /= temp; - } else { - if (par == 0. || ratio >= p75) { - delta = pnorm / p5; - par = p5 * par; - } - } - -/* test for successful iteration. */ - - if (ratio >= p0001) { - -/* successful iteration. update x, fvec, and their norms. */ - - for (j = 0; j < n; ++j) { - x[j] = wa2[j]; - wa2[j] = diag[j] * x[j]; - } - for (i = 0; i < m; ++i) { - fvec[i] = wa4[i]; - } - xnorm = __cminpack_enorm__(n, wa2); - fnorm = fnorm1; - ++iter; - } - -/* tests for convergence. */ - - if (fabs(actred) <= ftol && prered <= ftol && p5 * ratio <= 1.) { - info = 1; - } - if (delta <= xtol * xnorm) { - info = 2; - } - if (fabs(actred) <= ftol && prered <= ftol && p5 * ratio <= 1. && info == 2) { - info = 3; - } - if (info != 0) { - goto TERMINATE; - } - -/* tests for termination and stringent tolerances. */ - - if (*nfev >= maxfev) { - info = 5; - } - if (fabs(actred) <= epsmch && prered <= epsmch && p5 * ratio <= 1.) { - info = 6; - } - if (delta <= epsmch * xnorm) { - info = 7; - } - if (gnorm <= epsmch) { - info = 8; - } - if (info != 0) { - goto TERMINATE; - } - -/* end of the inner loop. repeat if iteration unsuccessful. */ - - } while (ratio < p0001); - -/* end of the outer loop. */ - - } -TERMINATE: - -/* termination, either normal or user imposed. */ - - if (iflag < 0) { - info = iflag; - } - if (nprint > 0) { - fcnder_mn(p, m, n, x, fvec, fjac, ldfjac, 0); - } - return info; - -/* last card of subroutine lmder. */ - -} /* lmder_ */ - diff --git a/ast/cminpack/lmder1.c b/ast/cminpack/lmder1.c deleted file mode 100644 index 581462e..0000000 --- a/ast/cminpack/lmder1.c +++ /dev/null @@ -1,167 +0,0 @@ -#include "cminpack.h" -#include "cminpackP.h" - -__cminpack_attr__ -int __cminpack_func__(lmder1)(__cminpack_decl_fcnder_mn__ void *p, int m, int n, real *x, - real *fvec, real *fjac, int ldfjac, real tol, - int *ipvt, real *wa, int lwa) -{ - /* Initialized data */ - - const real factor = 100.; - - /* Local variables */ - int mode, nfev, njev; - real ftol, gtol, xtol; - int maxfev, nprint; - int info; - -/* ********** */ - -/* subroutine lmder1 */ - -/* the purpose of lmder1 is to minimize the sum of the squares of */ -/* m nonlinear functions in n variables by a modification of the */ -/* levenberg-marquardt algorithm. this is done by using the more */ -/* general least-squares solver lmder. the user must provide a */ -/* subroutine which calculates the functions and the jacobian. */ - -/* the subroutine statement is */ - -/* subroutine lmder1(fcn,m,n,x,fvec,fjac,ldfjac,tol,info, */ -/* ipvt,wa,lwa) */ - -/* where */ - -/* fcn is the name of the user-supplied subroutine which */ -/* calculates the functions and the jacobian. fcn must */ -/* be declared in an external statement in the user */ -/* calling program, and should be written as follows. */ - -/* subroutine fcn(m,n,x,fvec,fjac,ldfjac,iflag) */ -/* integer m,n,ldfjac,iflag */ -/* double precision x(n),fvec(m),fjac(ldfjac,n) */ -/* ---------- */ -/* if iflag = 1 calculate the functions at x and */ -/* return this vector in fvec. do not alter fjac. */ -/* if iflag = 2 calculate the jacobian at x and */ -/* return this matrix in fjac. do not alter fvec. */ -/* ---------- */ -/* return */ -/* end */ - -/* the value of iflag should not be changed by fcn unless */ -/* the user wants to terminate execution of lmder1. */ -/* in this case set iflag to a negative integer. */ - -/* m is a positive integer input variable set to the number */ -/* of functions. */ - -/* n is a positive integer input variable set to the number */ -/* of variables. n must not exceed m. */ - -/* x is an array of length n. on input x must contain */ -/* an initial estimate of the solution vector. on output x */ -/* contains the final estimate of the solution vector. */ - -/* fvec is an output array of length m which contains */ -/* the functions evaluated at the output x. */ - -/* fjac is an output m by n array. the upper n by n submatrix */ -/* of fjac contains an upper triangular matrix r with */ -/* diagonal elements of nonincreasing magnitude such that */ - -/* t t t */ -/* p *(jac *jac)*p = r *r, */ - -/* where p is a permutation matrix and jac is the final */ -/* calculated jacobian. column j of p is column ipvt(j) */ -/* (see below) of the identity matrix. the lower trapezoidal */ -/* part of fjac contains information generated during */ -/* the computation of r. */ - -/* ldfjac is a positive integer input variable not less than m */ -/* which specifies the leading dimension of the array fjac. */ - -/* tol is a nonnegative input variable. termination occurs */ -/* when the algorithm estimates either that the relative */ -/* error in the sum of squares is at most tol or that */ -/* the relative error between x and the solution is at */ -/* most tol. */ - -/* info is an integer output variable. if the user has */ -/* terminated execution, info is set to the (negative) */ -/* value of iflag. see description of fcn. otherwise, */ -/* info is set as follows. */ - -/* info = 0 improper input parameters. */ - -/* info = 1 algorithm estimates that the relative error */ -/* in the sum of squares is at most tol. */ - -/* info = 2 algorithm estimates that the relative error */ -/* between x and the solution is at most tol. */ - -/* info = 3 conditions for info = 1 and info = 2 both hold. */ - -/* info = 4 fvec is orthogonal to the columns of the */ -/* jacobian to machine precision. */ - -/* info = 5 number of calls to fcn with iflag = 1 has */ -/* reached 100*(n+1). */ - -/* info = 6 tol is too small. no further reduction in */ -/* the sum of squares is possible. */ - -/* info = 7 tol is too small. no further improvement in */ -/* the approximate solution x is possible. */ - -/* ipvt is an integer output array of length n. ipvt */ -/* defines a permutation matrix p such that jac*p = q*r, */ -/* where jac is the final calculated jacobian, q is */ -/* orthogonal (not stored), and r is upper triangular */ -/* with diagonal elements of nonincreasing magnitude. */ -/* column j of p is column ipvt(j) of the identity matrix. */ - -/* wa is a work array of length lwa. */ - -/* lwa is a positive integer input variable not less than 5*n+m. */ - -/* subprograms called */ - -/* user-supplied ...... fcn */ - -/* minpack-supplied ... lmder */ - -/* argonne national laboratory. minpack project. march 1980. */ -/* burton s. garbow, kenneth e. hillstrom, jorge j. more */ - -/* ********** */ - -/* check the input parameters for errors. */ - - if (n <= 0 || m < n || ldfjac < m || tol < 0. || lwa < n * 5 + m) { - return 0; - } - -/* call lmder. */ - - maxfev = (n + 1) * 100; - ftol = tol; - xtol = tol; - gtol = 0.; - mode = 1; - nprint = 0; - info = __cminpack_func__(lmder)(__cminpack_param_fcnder_mn__ p, m, n, x, fvec, fjac, ldfjac, - ftol, xtol, gtol, maxfev, wa, mode, factor, nprint, - &nfev, &njev, ipvt, &wa[n], &wa[(n << 1)], & - wa[n * 3], &wa[(n << 2)], &wa[n * 5]); - if (info == 8) { - info = 4; - } - return info; - -/* last card of subroutine lmder1. */ - -} /* lmder1_ */ - diff --git a/ast/cminpack/lmpar.c b/ast/cminpack/lmpar.c deleted file mode 100644 index 108e687..0000000 --- a/ast/cminpack/lmpar.c +++ /dev/null @@ -1,338 +0,0 @@ -/* lmpar.f -- translated by f2c (version 20020621). - You must link the resulting object file with the libraries: - -lf2c -lm (in that order) -*/ - -#include "cminpack.h" -#include -#include "cminpackP.h" - -__cminpack_attr__ -void __cminpack_func__(lmpar)(int n, real *r, int ldr, - const int *ipvt, const real *diag, const real *qtb, real delta, - real *par, real *x, real *sdiag, real *wa1, - real *wa2) -{ - /* Initialized data */ - -#define p1 .1 -#define p001 .001 - - /* System generated locals */ - real d1, d2; - - /* Local variables */ - int j, l; - real fp; - real parc, parl; - int iter; - real temp, paru, dwarf; - int nsing; - real gnorm; - real dxnorm; - -/* ********** */ - -/* subroutine lmpar */ - -/* given an m by n matrix a, an n by n nonsingular diagonal */ -/* matrix d, an m-vector b, and a positive number delta, */ -/* the problem is to determine a value for the parameter */ -/* par such that if x solves the system */ - -/* a*x = b , sqrt(par)*d*x = 0 , */ - -/* in the least squares sense, and dxnorm is the euclidean */ -/* norm of d*x, then either par is zero and */ - -/* (dxnorm-delta) .le. 0.1*delta , */ - -/* or par is positive and */ - -/* abs(dxnorm-delta) .le. 0.1*delta . */ - -/* this subroutine completes the solution of the problem */ -/* if it is provided with the necessary information from the */ -/* qr factorization, with column pivoting, of a. that is, if */ -/* a*p = q*r, where p is a permutation matrix, q has orthogonal */ -/* columns, and r is an upper triangular matrix with diagonal */ -/* elements of nonincreasing magnitude, then lmpar expects */ -/* the full upper triangle of r, the permutation matrix p, */ -/* and the first n components of (q transpose)*b. on output */ -/* lmpar also provides an upper triangular matrix s such that */ - -/* t t t */ -/* p *(a *a + par*d*d)*p = s *s . */ - -/* s is employed within lmpar and may be of separate interest. */ - -/* only a few iterations are generally needed for convergence */ -/* of the algorithm. if, however, the limit of 10 iterations */ -/* is reached, then the output par will contain the best */ -/* value obtained so far. */ - -/* the subroutine statement is */ - -/* subroutine lmpar(n,r,ldr,ipvt,diag,qtb,delta,par,x,sdiag, */ -/* wa1,wa2) */ - -/* where */ - -/* n is a positive integer input variable set to the order of r. */ - -/* r is an n by n array. on input the full upper triangle */ -/* must contain the full upper triangle of the matrix r. */ -/* on output the full upper triangle is unaltered, and the */ -/* strict lower triangle contains the strict upper triangle */ -/* (transposed) of the upper triangular matrix s. */ - -/* ldr is a positive integer input variable not less than n */ -/* which specifies the leading dimension of the array r. */ - -/* ipvt is an integer input array of length n which defines the */ -/* permutation matrix p such that a*p = q*r. column j of p */ -/* is column ipvt(j) of the identity matrix. */ - -/* diag is an input array of length n which must contain the */ -/* diagonal elements of the matrix d. */ - -/* qtb is an input array of length n which must contain the first */ -/* n elements of the vector (q transpose)*b. */ - -/* delta is a positive input variable which specifies an upper */ -/* bound on the euclidean norm of d*x. */ - -/* par is a nonnegative variable. on input par contains an */ -/* initial estimate of the levenberg-marquardt parameter. */ -/* on output par contains the final estimate. */ - -/* x is an output array of length n which contains the least */ -/* squares solution of the system a*x = b, sqrt(par)*d*x = 0, */ -/* for the output par. */ - -/* sdiag is an output array of length n which contains the */ -/* diagonal elements of the upper triangular matrix s. */ - -/* wa1 and wa2 are work arrays of length n. */ - -/* subprograms called */ - -/* minpack-supplied ... dpmpar,enorm,qrsolv */ - -/* fortran-supplied ... dabs,dmax1,dmin1,dsqrt */ - -/* argonne national laboratory. minpack project. march 1980. */ -/* burton s. garbow, kenneth e. hillstrom, jorge j. more */ - -/* ********** */ - -/* dwarf is the smallest positive magnitude. */ - - dwarf = __cminpack_func__(dpmpar)(2); - -/* compute and store in x the gauss-newton direction. if the */ -/* jacobian is rank-deficient, obtain a least squares solution. */ - - nsing = n; - for (j = 0; j < n; ++j) { - wa1[j] = qtb[j]; - if (r[j + j * ldr] == 0. && nsing == n) { - nsing = j; - } - if (nsing < n) { - wa1[j] = 0.; - } - } -# ifdef USE_CBLAS - cblas_dtrsv(CblasColMajor, CblasUpper, CblasNoTrans, CblasNonUnit, nsing, r, ldr, wa1, 1); -# else - if (nsing >= 1) { - int k; - for (k = 1; k <= nsing; ++k) { - j = nsing - k; - wa1[j] /= r[j + j * ldr]; - temp = wa1[j]; - if (j >= 1) { - int i; - for (i = 0; i < j; ++i) { - wa1[i] -= r[i + j * ldr] * temp; - } - } - } - } -# endif - for (j = 0; j < n; ++j) { - l = ipvt[j]-1; - x[l] = wa1[j]; - } - -/* initialize the iteration counter. */ -/* evaluate the function at the origin, and test */ -/* for acceptance of the gauss-newton direction. */ - - iter = 0; - for (j = 0; j < n; ++j) { - wa2[j] = diag[j] * x[j]; - } - dxnorm = __cminpack_enorm__(n, wa2); - fp = dxnorm - delta; - if (fp <= p1 * delta) { - goto TERMINATE; - } - -/* if the jacobian is not rank deficient, the newton */ -/* step provides a lower bound, parl, for the zero of */ -/* the function. otherwise set this bound to zero. */ - - parl = 0.; - if (nsing >= n) { - for (j = 0; j < n; ++j) { - l = ipvt[j]-1; - wa1[j] = diag[l] * (wa2[l] / dxnorm); - } -# ifdef USE_CBLAS - cblas_dtrsv(CblasColMajor, CblasUpper, CblasTrans, CblasNonUnit, n, r, ldr, wa1, 1); -# else - for (j = 0; j < n; ++j) { - real sum = 0.; - if (j >= 1) { - int i; - for (i = 0; i < j; ++i) { - sum += r[i + j * ldr] * wa1[i]; - } - } - wa1[j] = (wa1[j] - sum) / r[j + j * ldr]; - } -# endif - temp = __cminpack_enorm__(n, wa1); - parl = fp / delta / temp / temp; - } - -/* calculate an upper bound, paru, for the zero of the function. */ - - for (j = 0; j < n; ++j) { - real sum; -# ifdef USE_CBLAS - sum = cblas_ddot(j+1, &r[j*ldr], 1, qtb, 1); -# else - int i; - sum = 0.; - for (i = 0; i <= j; ++i) { - sum += r[i + j * ldr] * qtb[i]; - } -# endif - l = ipvt[j]-1; - wa1[j] = sum / diag[l]; - } - gnorm = __cminpack_enorm__(n, wa1); - paru = gnorm / delta; - if (paru == 0.) { - paru = dwarf / min(delta,(real)p1) /* / p001 ??? */; - } - -/* if the input par lies outside of the interval (parl,paru), */ -/* set par to the closer endpoint. */ - - *par = max(*par,parl); - *par = min(*par,paru); - if (*par == 0.) { - *par = gnorm / dxnorm; - } - -/* beginning of an iteration. */ - - for (;;) { - ++iter; - -/* evaluate the function at the current value of par. */ - - if (*par == 0.) { - /* Computing MAX */ - d1 = dwarf, d2 = p001 * paru; - *par = max(d1,d2); - } - temp = sqrt(*par); - for (j = 0; j < n; ++j) { - wa1[j] = temp * diag[j]; - } - __cminpack_func__(qrsolv)(n, r, ldr, ipvt, wa1, qtb, x, sdiag, wa2); - for (j = 0; j < n; ++j) { - wa2[j] = diag[j] * x[j]; - } - dxnorm = __cminpack_enorm__(n, wa2); - temp = fp; - fp = dxnorm - delta; - -/* if the function is small enough, accept the current value */ -/* of par. also test for the exceptional cases where parl */ -/* is zero or the number of iterations has reached 10. */ - - if (fabs(fp) <= p1 * delta || (parl == 0. && fp <= temp && temp < 0.) || iter == 10) { - goto TERMINATE; - } - -/* compute the newton correction. */ - -# ifdef USE_CBLAS - for (j = 0; j < nsing; ++j) { - l = ipvt[j]-1; - wa1[j] = diag[l] * (wa2[l] / dxnorm); - } - for (j = nsing; j < n; ++j) { - wa1[j] = 0.; - } - /* exchange the diagonal of r with sdiag */ - cblas_dswap(n, r, ldr+1, sdiag, 1); - /* solve lower(r).x = wa1, result id put in wa1 */ - cblas_dtrsv(CblasColMajor, CblasLower, CblasNoTrans, CblasNonUnit, nsing, r, ldr, wa1, 1); - /* exchange the diagonal of r with sdiag */ - cblas_dswap( n, r, ldr+1, sdiag, 1); -# else /* !USE_CBLAS */ - for (j = 0; j < n; ++j) { - l = ipvt[j]-1; - wa1[j] = diag[l] * (wa2[l] / dxnorm); - } - for (j = 0; j < n; ++j) { - wa1[j] /= sdiag[j]; - temp = wa1[j]; - if (n > j+1) { - int i; - for (i = j+1; i < n; ++i) { - wa1[i] -= r[i + j * ldr] * temp; - } - } - } -# endif /* !USE_CBLAS */ - temp = __cminpack_enorm__(n, wa1); - parc = fp / delta / temp / temp; - -/* depending on the sign of the function, update parl or paru. */ - - if (fp > 0.) { - parl = max(parl,*par); - } - if (fp < 0.) { - paru = min(paru,*par); - } - -/* compute an improved estimate for par. */ - - /* Computing MAX */ - d1 = parl, d2 = *par + parc; - *par = max(d1,d2); - -/* end of an iteration. */ - - } -TERMINATE: - -/* termination. */ - - if (iter == 0) { - *par = 0.; - } - -/* last card of subroutine lmpar. */ - -} /* lmpar_ */ - diff --git a/ast/cminpack/qrfac.c b/ast/cminpack/qrfac.c deleted file mode 100644 index 1573772..0000000 --- a/ast/cminpack/qrfac.c +++ /dev/null @@ -1,285 +0,0 @@ -#include "cminpack.h" -#include -#ifdef USE_LAPACK -#include -#include -#include -#endif -#include "cminpackP.h" - -__cminpack_attr__ -void __cminpack_func__(qrfac)(int m, int n, real *a, int - lda, int pivot, int *ipvt, int lipvt, real *rdiag, - real *acnorm, real *wa) -{ -#ifdef USE_LAPACK - __CLPK_integer m_ = m; - __CLPK_integer n_ = n; - __CLPK_integer lda_ = lda; - __CLPK_integer *jpvt; - - int i, j, k; - double t; - double* tau = wa; - const __CLPK_integer ltau = m > n ? n : m; - __CLPK_integer lwork = -1; - __CLPK_integer info = 0; - double* work; - - if (pivot) { - assert( lipvt >= n ); - if (sizeof(__CLPK_integer) != sizeof(ipvt[0])) { - jpvt = malloc(n*sizeof(__CLPK_integer)); - } else { - /* __CLPK_integer is actually an int, just do a cast */ - jpvt = (__CLPK_integer *)ipvt; - } - /* set all columns free */ - memset(jpvt, 0, sizeof(int)*n); - } - - /* query optimal size of work */ - lwork = -1; - if (pivot) { - dgeqp3_(&m_,&n_,a,&lda_,jpvt,tau,tau,&lwork,&info); - lwork = (int)tau[0]; - assert( lwork >= 3*n+1 ); - } else { - dgeqrf_(&m_,&n_,a,&lda_,tau,tau,&lwork,&info); - lwork = (int)tau[0]; - assert( lwork >= 1 && lwork >= n ); - } - - assert( info == 0 ); - - /* alloc work area */ - work = (double *)malloc(sizeof(double)*lwork); - assert(work != NULL); - - /* set acnorm first (from the doc of qrfac, acnorm may point to the same area as rdiag) */ - if (acnorm != rdiag) { - for (j = 0; j < n; ++j) { - acnorm[j] = __cminpack_enorm__(m, &a[j * lda]); - } - } - - /* QR decomposition */ - if (pivot) { - dgeqp3_(&m_,&n_,a,&lda_,jpvt,tau,work,&lwork,&info); - } else { - dgeqrf_(&m_,&n_,a,&lda_,tau,work,&lwork,&info); - } - assert(info == 0); - - /* set rdiag, before the diagonal is replaced */ - memset(rdiag, 0, sizeof(double)*n); - for(i=0 ; i rdiag[kmax]) { - kmax = k; - } - } - if (kmax != j) { - for (i = 0; i < m; ++i) { - temp = a[i + j * lda]; - a[i + j * lda] = a[i + kmax * lda]; - a[i + kmax * lda] = temp; - } - rdiag[kmax] = rdiag[j]; - wa[kmax] = wa[j]; - k = ipvt[j]; - ipvt[j] = ipvt[kmax]; - ipvt[kmax] = k; - } - } - -/* compute the householder transformation to reduce the */ -/* j-th column of a to a multiple of the j-th unit vector. */ - - ajnorm = __cminpack_enorm__(m - (j+1) + 1, &a[j + j * lda]); - if (ajnorm != 0.) { - if (a[j + j * lda] < 0.) { - ajnorm = -ajnorm; - } - for (i = j; i < m; ++i) { - a[i + j * lda] /= ajnorm; - } - a[j + j * lda] += 1.; - -/* apply the transformation to the remaining columns */ -/* and update the norms. */ - - jp1 = j + 1; - if (n > jp1) { - for (k = jp1; k < n; ++k) { - sum = 0.; - for (i = j; i < m; ++i) { - sum += a[i + j * lda] * a[i + k * lda]; - } - temp = sum / a[j + j * lda]; - for (i = j; i < m; ++i) { - a[i + k * lda] -= temp * a[i + j * lda]; - } - if (pivot && rdiag[k] != 0.) { - temp = a[j + k * lda] / rdiag[k]; - /* Computing MAX */ - d1 = 1. - temp * temp; - rdiag[k] *= sqrt((max((real)0.,d1))); - /* Computing 2nd power */ - d1 = rdiag[k] / wa[k]; - if (p05 * (d1 * d1) <= epsmch) { - rdiag[k] = __cminpack_enorm__(m - (j+1), &a[jp1 + k * lda]); - wa[k] = rdiag[k]; - } - } - } - } - } - rdiag[j] = -ajnorm; - } - -/* last card of subroutine qrfac. */ -#endif /* !USE_LAPACK */ -} /* qrfac_ */ - diff --git a/ast/cminpack/qrsolv.c b/ast/cminpack/qrsolv.c deleted file mode 100644 index 6ab9e98..0000000 --- a/ast/cminpack/qrsolv.c +++ /dev/null @@ -1,218 +0,0 @@ -#include "cminpack.h" -#include -#include "cminpackP.h" - -__cminpack_attr__ -void __cminpack_func__(qrsolv)(int n, real *r, int ldr, - const int *ipvt, const real *diag, const real *qtb, real *x, - real *sdiag, real *wa) -{ - /* Initialized data */ - -#define p5 .5 -#define p25 .25 - - /* Local variables */ - int i, j, k, l; - real cos, sin, sum, temp; - int nsing; - real qtbpj; - -/* ********** */ - -/* subroutine qrsolv */ - -/* given an m by n matrix a, an n by n diagonal matrix d, */ -/* and an m-vector b, the problem is to determine an x which */ -/* solves the system */ - -/* a*x = b , d*x = 0 , */ - -/* in the least squares sense. */ - -/* this subroutine completes the solution of the problem */ -/* if it is provided with the necessary information from the */ -/* qr factorization, with column pivoting, of a. that is, if */ -/* a*p = q*r, where p is a permutation matrix, q has orthogonal */ -/* columns, and r is an upper triangular matrix with diagonal */ -/* elements of nonincreasing magnitude, then qrsolv expects */ -/* the full upper triangle of r, the permutation matrix p, */ -/* and the first n components of (q transpose)*b. the system */ -/* a*x = b, d*x = 0, is then equivalent to */ - -/* t t */ -/* r*z = q *b , p *d*p*z = 0 , */ - -/* where x = p*z. if this system does not have full rank, */ -/* then a least squares solution is obtained. on output qrsolv */ -/* also provides an upper triangular matrix s such that */ - -/* t t t */ -/* p *(a *a + d*d)*p = s *s . */ - -/* s is computed within qrsolv and may be of separate interest. */ - -/* the subroutine statement is */ - -/* subroutine qrsolv(n,r,ldr,ipvt,diag,qtb,x,sdiag,wa) */ - -/* where */ - -/* n is a positive integer input variable set to the order of r. */ - -/* r is an n by n array. on input the full upper triangle */ -/* must contain the full upper triangle of the matrix r. */ -/* on output the full upper triangle is unaltered, and the */ -/* strict lower triangle contains the strict upper triangle */ -/* (transposed) of the upper triangular matrix s. */ - -/* ldr is a positive integer input variable not less than n */ -/* which specifies the leading dimension of the array r. */ - -/* ipvt is an integer input array of length n which defines the */ -/* permutation matrix p such that a*p = q*r. column j of p */ -/* is column ipvt(j) of the identity matrix. */ - -/* diag is an input array of length n which must contain the */ -/* diagonal elements of the matrix d. */ - -/* qtb is an input array of length n which must contain the first */ -/* n elements of the vector (q transpose)*b. */ - -/* x is an output array of length n which contains the least */ -/* squares solution of the system a*x = b, d*x = 0. */ - -/* sdiag is an output array of length n which contains the */ -/* diagonal elements of the upper triangular matrix s. */ - -/* wa is a work array of length n. */ - -/* subprograms called */ - -/* fortran-supplied ... dabs,dsqrt */ - -/* argonne national laboratory. minpack project. march 1980. */ -/* burton s. garbow, kenneth e. hillstrom, jorge j. more */ - -/* ********** */ - -/* copy r and (q transpose)*b to preserve input and initialize s. */ -/* in particular, save the diagonal elements of r in x. */ - - for (j = 0; j < n; ++j) { - for (i = j; i < n; ++i) { - r[i + j * ldr] = r[j + i * ldr]; - } - x[j] = r[j + j * ldr]; - wa[j] = qtb[j]; - } - -/* eliminate the diagonal matrix d using a givens rotation. */ - - for (j = 0; j < n; ++j) { - -/* prepare the row of d to be eliminated, locating the */ -/* diagonal element using p from the qr factorization. */ - - l = ipvt[j]-1; - if (diag[l] != 0.) { - for (k = j; k < n; ++k) { - sdiag[k] = 0.; - } - sdiag[j] = diag[l]; - -/* the transformations to eliminate the row of d */ -/* modify only a single element of (q transpose)*b */ -/* beyond the first n, which is initially zero. */ - - qtbpj = 0.; - for (k = j; k < n; ++k) { - -/* determine a givens rotation which eliminates the */ -/* appropriate element in the current row of d. */ - - if (sdiag[k] != 0.) { -# ifdef USE_LAPACK - dlartg_( &r[k + k * ldr], &sdiag[k], &cos, &sin, &temp ); -# else /* !USE_LAPACK */ - if (fabs(r[k + k * ldr]) < fabs(sdiag[k])) { - real cotan; - cotan = r[k + k * ldr] / sdiag[k]; - sin = p5 / sqrt(p25 + p25 * (cotan * cotan)); - cos = sin * cotan; - } else { - real tan; - tan = sdiag[k] / r[k + k * ldr]; - cos = p5 / sqrt(p25 + p25 * (tan * tan)); - sin = cos * tan; - } - -/* compute the modified diagonal element of r and */ -/* the modified element of ((q transpose)*b,0). */ - -# endif /* !USE_LAPACK */ - temp = cos * wa[k] + sin * qtbpj; - qtbpj = -sin * wa[k] + cos * qtbpj; - wa[k] = temp; - -/* accumulate the tranformation in the row of s. */ -# ifdef USE_CBLAS - cblas_drot( n-k, &r[k + k * ldr], 1, &sdiag[k], 1, cos, sin ); -# else /* !USE_CBLAS */ - r[k + k * ldr] = cos * r[k + k * ldr] + sin * sdiag[k]; - if (n > k+1) { - for (i = k+1; i < n; ++i) { - temp = cos * r[i + k * ldr] + sin * sdiag[i]; - sdiag[i] = -sin * r[i + k * ldr] + cos * sdiag[i]; - r[i + k * ldr] = temp; - } - } -# endif /* !USE_CBLAS */ - } - } - } - -/* store the diagonal element of s and restore */ -/* the corresponding diagonal element of r. */ - - sdiag[j] = r[j + j * ldr]; - r[j + j * ldr] = x[j]; - } - -/* solve the triangular system for z. if the system is */ -/* singular, then obtain a least squares solution. */ - - nsing = n; - for (j = 0; j < n; ++j) { - if (sdiag[j] == 0. && nsing == n) { - nsing = j; - } - if (nsing < n) { - wa[j] = 0.; - } - } - if (nsing >= 1) { - for (k = 1; k <= nsing; ++k) { - j = nsing - k; - sum = 0.; - if (nsing > j+1) { - for (i = j+1; i < nsing; ++i) { - sum += r[i + j * ldr] * wa[i]; - } - } - wa[j] = (wa[j] - sum) / sdiag[j]; - } - } - -/* permute the components of z back to components of x. */ - - for (j = 0; j < n; ++j) { - l = ipvt[j]-1; - x[l] = wa[j]; - } - return; - -/* last card of subroutine qrsolv. */ - -} /* qrsolv_ */ - diff --git a/ast/cmpframe.c b/ast/cmpframe.c deleted file mode 100644 index 48e971a..0000000 --- a/ast/cmpframe.c +++ /dev/null @@ -1,10846 +0,0 @@ -/* -*class++ -* Name: -* CmpFrame - -* Purpose: -* Compound Frame. - -* Constructor Function: -c astCmpFrame -f AST_CMPFRAME - -* Description: -* A CmpFrame is a compound Frame which allows two component Frames -* (of any class) to be merged together to form a more complex -* Frame. The axes of the two component Frames then appear together -* in the resulting CmpFrame (those of the first Frame, followed by -* those of the second Frame). -* -* Since a CmpFrame is itself a Frame, it can be used as a -* component in forming further CmpFrames. Frames of arbitrary -* complexity may be built from simple individual Frames in this -* way. -* -* Also since a Frame is a Mapping, a CmpFrame can also be used as a -* Mapping. Normally, a CmpFrame is simply equivalent to a UnitMap, -* but if either of the component Frames within a CmpFrame is a Region -* (a sub-class of Frame), then the CmpFrame will use the Region as a -* Mapping when transforming values for axes described by the Region. -* Thus input axis values corresponding to positions which are outside the -* Region will result in bad output axis values. - -* Inheritance: -* The CmpFrame class inherits from the Frame class. - -* Attributes: -* The CmpFrame class does not define any new attributes beyond -* those which are applicable to all Frames. However, the attributes -* of the component Frames can be accessed as if they were attributes -* of the CmpFrame. For instance, if a CmpFrame contains a SpecFrame -* and a SkyFrame, then the CmpFrame will recognise the "Equinox" -* attribute and forward access requests to the component SkyFrame. -* Likewise, it will recognise the "RestFreq" attribute and forward -* access requests to the component SpecFrame. An axis index can -* optionally be appended to the end of any attribute name, in which -* case the request to access the attribute will be forwarded to the -* primary Frame defining the specified axis. - -* Functions: -c The CmpFrame class does not define any new functions beyond those -f The CmpFrame class does not define any new routines beyond those -* which are applicable to all Frames. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 4-MAR-1996 (RFWS): -* Original version. -* 27-FEB-1997 (RFWS): -* Improved public prologues. -* 25-FEB-1998 (RFWS): -* Over-ride the astUnformat method. -* 6-APR-1998 (RFWS): -* Fixed bug in returned value of GenAxisSelection. -* 22-SEP-1998 (RFWS): -* Fixed bug in Match function - was not checking Domain values -* for equality. -* 11-JUN-1999 (RFWS): -* Fixed bug in GenAxisSelection- some selections were being omitted. -* 5-FEB-2001 (DSB): -* Ensure that Title and Domain values appropriate to a CmpFrame -* are preserved if a CmpFrame result is generated by SubFrame. -* 27-FEB-2001 (DSB): -* Modified Match so that all the frames have some axes in order to -* match. Otherwise, null pointers are created (for zero axes), -* resulting in a seg vio. -* 21-JUN-2001 (DSB): -* Added astAngle. -* 7-SEP-2001 (DSB): -* Added astResolve. -* 26-SEP-2001 (DSB): -* Over-ride the astDecompose method. -* 20-DEC-2002 (DSB): -* Allows any attribute of a component frame to be accessed as though -* it were an attribute of the CmpFrame by including an axis index in -* the attribute name (e.g. "System(3)"). -* 8-JAN-2003 (DSB): -* - Changed private InitVtab method to protected astInitCmpFrameVtab -* method. -* - Override astGetAttrib, astClearAttrib, astTestAttrib, -* astSetAttrib to allow attributes to be set for individual -* axes. -* - Override astGetEpoch astGetSystem, astGetAlignSystem. -* astValidateSystem, astSystemString, astSystemCode. -* 27-FEB-2003 (DSB): -* - Modify the default Domain name for a CmpFrame to be the -* domains of the two subFrames separated by a "-". -* 24-JAN-2004 (DSB): -* o Override the astFields method. -* o Added argument "fmt" to Abbrev. -* 24-MAR-2004 (DSB): -* Over-ride the astSimplify and astTransform methods. -* 8-SEP-2004 (DSB): -* Over-ride astResolvePoints method. -* 21-JAN-2005 (DSB): -* Over-ride the astGetActiveUnit and astSetActiveUnit methods. -* 23-FEB-2005 (DSB): -* Modify GetDomain to avoid over-writing the static "buff" array -* if called recursively. -* 29-MAR-2005 (DSB): -* Override astSetEpoch and astClearEpoch by implementations which -* propagate the changed epoch value to the component Frames. -* 5-APR-2005 (DSB): -* Correct error checking in Clear/Get/Set/TestAttrib. -* 12-MAY-2005 (DSB): -* Override astNormBox method. -* 12-AUG-2005 (DSB): -* Override astSetObsLat/Lon and astClearObslat/Lon by implementations -* which propagate the changed value to the component Frames. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 3-APR-2006 (DSB): -* Modify Match so that an attempt is made to align the target with -* each of the two component Frames if the target cannot be matched -* with the CmpFrame as a whole. -* 3-MAY-2006 (DSB): -* Fix bug in Match that could cause segvio when matching a target -* against the second component of a CmpFrame. -* 31-OCT-2006 (DSB): -* Over-ride the SetFrameFlags method. -* 1-NOV-2005 (DSB): -* Override astSetDut1, astGetDut1 and astClearDut1. -* 15-MAR-2007 (DSB): -* Override astClearAlignSystem by an implementation that clears -* AlignSystem in the component Frames. -* 7-FEB-2008 (DSB): -* Allow the MaxAxes and MinAxes attributes to be specified for a -* CmpFrame (rather than just being the sum of the attribute values -* in the component frames). This enables, for instance, a (detector -* index,mjd) frame to match with a ((velocity,detector index),mjd) -* frame. -* 5-MAY-2009 (DSB): -* In GetAttrib, if an index is included in the attribute name, attempt -* to use the GetAttrib method of the primary frame before using the -* parent GetAttrib method. This is because the Frame getattrib -* method will dissociate axes from their parent class. Thus, a -* SkyAxis attribute such as AsTime will come out wrong since its -* value is managed by the SkyFrame class rather than the SkyAxis -* class. -* 18-JUN-2009 (DSB): -* Override astSetObsAlt and astClearObsAlt. -* 29-SEP-2009 (DSB): -* Ensure the astMatch method provided by this class honours the -* PreserveAxes, MaxAxes and MinAxes attribute settings. -* 22-MAR-2011 (DSB): -* Override astFrameGrid method. -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -* 10-FEB-2015 (DSB): -* When checking attribute settings for attribute names that end with -* an axis index, stop looking for the axis index when the first equals -* sign is encountered. -* 26-MAR-2015 (DSB): -* Increase size of "buf2" buffer in SetAttrib, and trap buffer overflow. -* 11-JAN-2017 (GSB): -* Override astSetDtai, astGetDtai and astClearDtai. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS CmpFrame - -/* Define the first and last acceptable System values. */ -#define FIRST_SYSTEM AST__COMP -#define LAST_SYSTEM AST__COMP - -/* Define macros to implement member functions for accessing axis - attributes. */ -/* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a function to clear an attribute value for a CmpFrame axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "cmpframe.h" -* MAKE_CLEAR(attribute) - -* Class Membership: -* Defined by the CmpFrame class. - -* Description: -* This macro expands to an implementation of a private member -* function of the form: -* -* static void Clear( AstFrame *this, int axis ) -* -* which clears an attribute value for a specified axis of a CmpFrame. - -* Parameters: -* attribute -* The name of the attribute to be cleared, as it appears in the -* function name (e.g. Label in "ClearLabel"). - -* Notes: -* - This macro assumes the existence of a method of the form: -* -* void astClear( AstFrame *this, int axis ) -* -* which clears the required attribute for a Frame object. -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attribute) \ -static void Clear##attribute( AstFrame *this_frame, int axis, int *status ) { \ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ \ - int naxes1; /* Number of axes in frame1 */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the CmpFrame structure. */ \ - this = (AstCmpFrame *) this_frame; \ -\ -/* Validate and alidateAxispermute the axis index supplied. */ \ - axis = astValidateAxis( this, axis, 1, "astSet" #attribute ); \ -\ -/* Determine the number of axes in the first component Frame. */ \ - naxes1 = astGetNaxes( this->frame1 ); \ - if ( astOK ) { \ -\ -/* Decide which Frame contains the axis and invoke its astClear... method to \ - clear the attribute value. */ \ - if ( axis < naxes1 ) { \ - astClear##attribute( this->frame1, axis ); \ - } else { \ - astClear##attribute( this->frame2, axis - naxes1 ); \ - } \ - } \ -} - -/* -* Name: -* MAKE_GET - -* Purpose: -* Implement a function to get an attribute value for a CmpFrame axis. - -* Type: -* Private macro. - -* Synopsis: -# #include "cmpframe.h" -* MAKE_GET(attribute,type,bad_value,default,assign_default) - -* Class Membership: -* Defined by the CmpFrame class. - -* Description: -* This macro expands to an implementation of a private member -* function of the form: -* -* static Get( AstFrame *this, int axis ) -* -* which gets an attribute value for a specified axis of a -* CmpFrame. - -* Parameters: -* attribute -* The name of the attribute whose value is to be obtained, as -* it appears in the function name (e.g. Label in "GetLabel"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, -* or if the function fails. -* default -* A boolean (int) value that indicates whether a new default -* value should be returned if the requested attribute has not -* been set for the appropriate axis of the appropriate -* component Frame. If this value is zero, the component Frame's -* default (for the appropriate axis) will be used instead. -* assign_default -* An expression that evaluates to the new default value to be -* assigned. This value is ignored if "default" is zero, but a -* valid (e.g. constant) value should nevertheless be supplied. - -* Notes: -* - This macro assumes the existence of a method of the form: -* -* astGet( AstFrame *this, int axis ) -* -* which gets the required attribute for a Frame object. -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_GET(attribute,type,bad_value,default,assign_default) \ -static type Get##attribute( AstFrame *this_frame, int axis, int *status ) { \ - astDECLARE_GLOBALS /* Declare the thread specific global data */ \ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ \ - AstFrame *frame; /* Pointer to Frame containing axis */\ - int axis_p; /* Permuted axis index */ \ - int naxes1; /* Number of axes in frame1 */ \ - int set; /* Digits attribute set? */ \ - type result; /* Result value to return */ \ - \ -/* Initialise. */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Get a pointer to the structure holding thread-specific global data. */ \ - astGET_GLOBALS(this_frame); \ -\ -/* Obtain a pointer to the CmpFrame structure. */ \ - this = (AstCmpFrame *) this_frame; \ -\ -/* Validate and permute the axis index supplied. */ \ - axis_p = astValidateAxis( this, axis, 1, "astGet" #attribute ); \ -\ -/* Determine the number of axes in the first component Frame. */ \ - naxes1 = astGetNaxes( this->frame1 ); \ - if ( astOK ) { \ -\ -/* Decide which Frame contains the axis and adjust the axis index if \ - necessary. */ \ - frame = ( axis_p < naxes1 ) ? this->frame1 : this->frame2; \ - axis_p = ( axis_p < naxes1 ) ? axis_p : axis_p - naxes1; \ -\ -/* Since the component Frame is "managed" by the enclosing CmpFrame, we next \ - test if any Frame attributes which may affect the result are undefined \ - (i.e. have not been explicitly set). If so, we over-ride them, giving \ - them temporary values dictated by the CmpFrame. Only the Digits attribute \ - is relevant here. */ \ - set = astTestDigits( frame ); \ - if ( !set ) astSetDigits( frame, astGetDigits( this ) ); \ -\ -/* If the default value is to be over-ridden, test if the Frame's axis \ - attribute has been set. Then, if required, obtain the attribute value from \ - the Frame. */ \ - if ( !(default) || astTest##attribute( frame, axis_p ) ) { \ - result = astGet##attribute( frame, axis_p ); \ -\ -/* If required, assign the new default value. */ \ - } else { \ - result = (assign_default); \ - } \ -\ -/* Clear Frame attributes which were temporarily over-ridden. */ \ - if ( !set ) astClearDigits( frame ); \ - } \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* Name: -* MAKE_SET - -* Purpose: -* Implement a function to set an attribute value for a CmpFrame axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "cmpframe.h" -* MAKE_SET(attribute,type) - -* Class Membership: -* Defined by the CmpFrame class. - -* Description: -* This macro expands to an implementation of a private member -* function of the form: -* -* static void Set( AstFrame *this, int axis, value ) -* -* which sets an attribute value for a specified axis of a CmpFrame. - -* Parameters: -* attribute -* The name of the attribute to be set, as it appears in the -* function name (e.g. Label in "SetLabel"). -* type -* The C type of the attribute. - -* Notes: -* - This macro assumes the existence of a method of the form: -* -* void astSet( AstFrame *this, int axis, value ) -* -* which sets the required attribute for a Frame object. -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_SET(attribute,type) \ -static void Set##attribute( AstFrame *this_frame, int axis, type value, int *status ) { \ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ \ - int naxes1; /* Number of axes in frame1 */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the CmpFrame structure. */ \ - this = (AstCmpFrame *) this_frame; \ -\ -/* Validate and permute the axis index supplied. */ \ - axis = astValidateAxis( this, axis, 1, "astSet" #attribute ); \ -\ -/* Determine the number of axes in the first component Frame. */ \ - naxes1 = astGetNaxes( this->frame1 ); \ - if ( astOK ) { \ -\ -/* Decide which Frame contains the axis and invoke its astSet... method to \ - set the attribute value. */ \ - if ( axis < naxes1 ) { \ - astSet##attribute( this->frame1, axis, value ); \ - } else { \ - astSet##attribute( this->frame2, axis - naxes1, value ); \ - } \ - } \ -} - -/* -* Name: -* MAKE_TEST - -* Purpose: -* Implement a function to test if an attribute is set for a CmpFrame axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "cmpframe.h" -* MAKE_TEST(attribute) - -* Class Membership: -* Defined by the CmpFrame class. - -* Description: -* This macro expands to an implementation of a private member -* function of the form: -* -* static int Test( AstFrame *this, int axis ) -* -* which tests whether an attribute value is set for a specified -* axis of a CmpFrame. - -* Parameters: -* attribute -* The name of the attribute to be tested, as it appears in the -* function name (e.g. Label in "TestLabel"). - -* Notes: -* - This macro assumes the existence of a method of the form: -* -* int astTest( AstFrame *this, int axis ) -* -* which tests the required attribute for a Frame object. -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_TEST(attribute) \ -static int Test##attribute( AstFrame *this_frame, int axis, int *status ) { \ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ \ - int naxes1; /* Number of axes in frame1 */ \ - int result; /* Result value to return */ \ -\ -/* Initialise. */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Obtain a pointer to the CmpFrame structure. */ \ - this = (AstCmpFrame *) this_frame; \ -\ -/* Validate and permute the axis index supplied. */ \ - axis = astValidateAxis( this, axis, 1, "astSet" #attribute ); \ -\ -/* Determine the number of axes in the first component Frame. */ \ - naxes1 = astGetNaxes( this->frame1 ); \ - if ( astOK ) { \ -\ -/* Decide which Frame contains the axis and invoke its astTest... method to \ - test the attribute. */ \ - if ( axis < naxes1 ) { \ - result = astTest##attribute( this->frame1, axis ); \ - } else { \ - result = astTest##attribute( this->frame2, axis - naxes1 ); \ - } \ - } \ -\ -/* Return the result. */ \ - return result; \ -} - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "pointset.h" /* Sets of points */ -#include "object.h" /* Base Object class */ -#include "mapping.h" /* Coordinate Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "permmap.h" /* Coordinate permutation Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "axis.h" /* Coordinate axes */ -#include "frame.h" /* Parent Frame class */ -#include "cmpframe.h" /* Interface definition for this class */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstSystemType (* parent_getalignsystem)( AstFrame *, int * ); -static AstSystemType (* parent_getsystem)( AstFrame *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static const char *(* parent_getdomain)( AstFrame *, int * ); -static const char *(* parent_gettitle)( AstFrame *, int * ); -static double (* parent_angle)( AstFrame *, const double[], const double[], const double[], int * ); -static double (* parent_getdtai)( AstFrame *, int * ); -static double (* parent_getdut1)( AstFrame *, int * ); -static double (* parent_getepoch)( AstFrame *, int * ); -static double (* parent_getobsalt)( AstFrame *, int * ); -static double (* parent_getobslat)( AstFrame *, int * ); -static double (* parent_getobslon)( AstFrame *, int * ); -static int (* parent_getactiveunit)( AstFrame *, int * ); -static int (* parent_getmaxaxes)( AstFrame *, int * ); -static int (* parent_getminaxes)( AstFrame *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); -static int (* parent_getusedefs)( AstObject *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearalignsystem)( AstFrame *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_cleardtai)( AstFrame *, int * ); -static void (* parent_cleardut1)( AstFrame *, int * ); -static void (* parent_clearepoch)( AstFrame *, int * ); -static void (* parent_clearobsalt)( AstFrame *, int * ); -static void (* parent_clearobslat)( AstFrame *, int * ); -static void (* parent_clearobslon)( AstFrame *, int * ); -static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * ); -static void (* parent_setactiveunit)( AstFrame *, int, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_setdtai)( AstFrame *, double, int * ); -static void (* parent_setdut1)( AstFrame *, double, int * ); -static void (* parent_setepoch)( AstFrame *, double, int * ); -static void (* parent_setframeflags)( AstFrame *, int, int * ); -static void (* parent_setobsalt)( AstFrame *, double, int * ); -static void (* parent_setobslat)( AstFrame *, double, int * ); -static void (* parent_setobslon)( AstFrame *, double, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->Label_Buff[ 0 ] = 0; \ - globals->Symbol_Buff[ 0 ] = 0; \ - globals->GetDomain_Buff[ 0 ] = 0; \ - globals->GetTitle_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(CmpFrame) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(CmpFrame,Class_Init) -#define class_vtab astGLOBAL(CmpFrame,Class_Vtab) -#define getdomain_buff astGLOBAL(CmpFrame,GetDomain_Buff) -#define gettitle_buff astGLOBAL(CmpFrame,GetTitle_Buff) -#define label_buff astGLOBAL(CmpFrame,Label_Buff) -#define symbol_buff astGLOBAL(CmpFrame,Symbol_Buff) -#define qsort_axes astGLOBAL(CmpFrame,qsort_axes) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Pointer to axis index array accessed by "qsort". */ -static int *qsort_axes; - -/* Default Label string buffer */ -static char label_buff[ 101 ]; - -/* Default Symbol buffer */ -static char symbol_buff[ 51 ]; - -/* Buffer for returned domain name in GetDomain */ -static char getdomain_buff[ 101 ]; - -/* Buffer for returned title in GetTitle */ -static char gettitle_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstCmpFrameVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstCmpFrame *astCmpFrameId_( void *, void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstAxis *GetAxis( AstFrame *, int, int * ); -static AstMapping *RemoveRegions( AstMapping *, int * ); -static AstMapping *Simplify( AstMapping *, int * ); -static AstObject *Cast( AstObject *, AstObject *, int * ); -static AstPointSet *FrameGrid( AstFrame *, int, const double *, const double *, int * ); -static AstPointSet *ResolvePoints( AstFrame *, const double [], const double [], AstPointSet *, AstPointSet *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstSystemType GetAlignSystem( AstFrame *, int * ); -static AstSystemType GetSystem( AstFrame *, int * ); -static AstSystemType SystemCode( AstFrame *, const char *, int * ); -static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * ); -static const char *Abbrev( AstFrame *, int, const char *, const char *, const char *, int * ); -static const char *Format( AstFrame *, int, double, int * ); -static const char *GetDomain( AstFrame *, int * ); -static const char *GetFormat( AstFrame *, int, int * ); -static const char *GetLabel( AstFrame *, int, int * ); -static const char *GetSymbol( AstFrame *, int, int * ); -static const char *GetTitle( AstFrame *, int * ); -static const char *GetUnit( AstFrame *, int, int * ); -static const char *SystemString( AstFrame *, AstSystemType, int * ); -static const int *GetPerm( AstFrame *, int * ); -static double Angle( AstFrame *, const double[], const double[], const double[], int * ); -static double Distance( AstFrame *, const double[], const double[], int * ); -static double Centre( AstFrame *, int, double, double, int * ); -static double Gap( AstFrame *, int, double, int *, int * ); -static int ComponentMatch( AstCmpFrame *, AstFrame *, int, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int Fields( AstFrame *, int, const char *, const char *, int, char **, int *, double *, int * ); -static int GenAxisSelection( int, int, int [], int * ); -static int GetActiveUnit( AstFrame *, int * ); -static int GetDirection( AstFrame *, int, int * ); -static int GetMaxAxes( AstFrame *, int * ); -static int GetMinAxes( AstFrame *, int * ); -static int GetNaxes( AstFrame *, int * ); -static int GetObjSize( AstObject *, int * ); -static int GetUseDefs( AstObject *, int * ); -static int GoodPerm( int, const int [], int, const int [], int * ); -static int IsUnitFrame( AstFrame *, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int PartMatch( AstCmpFrame *, AstFrame *, int, int, const int [], int, const int [], int **, int **, AstMapping **, AstFrame **, int * ); -static int QsortCmpAxes( const void *, const void * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int TestDirection( AstFrame *, int, int * ); -static int TestFormat( AstFrame *, int, int * ); -static int TestLabel( AstFrame *, int, int * ); -static int TestSymbol( AstFrame *, int, int * ); -static int TestUnit( AstFrame *, int, int * ); -static int Unformat( AstFrame *, int, const char *, double *, int * ); -static void AddExtraAxes( int, int [], int, int, int, int * ); -static void ClearDirection( AstFrame *, int, int * ); -static void ClearFormat( AstFrame *, int, int * ); -static void ClearLabel( AstFrame *, int, int * ); -static void ClearSymbol( AstFrame *, int, int * ); -static void ClearUnit( AstFrame *, int, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Decompose( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void MatchAxesX( AstFrame *, AstFrame *, int *, int * ); -static void Norm( AstFrame *, double [], int * ); -static void NormBox( AstFrame *, double[], double[], AstMapping *, int * ); -static void Offset( AstFrame *, const double [], const double [], double, double [], int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void PartitionSelection( int, const int [], const int [], int, int, int [], int, int * ); -static void PermAxes( AstFrame *, const int[], int * ); -static void PrimaryFrame( AstFrame *, int, AstFrame **, int *, int * ); -static void RenumberAxes( int, int [], int * ); -static void Resolve( AstFrame *, const double [], const double [], const double [], double [], double *, double *, int * ); -static void SetActiveUnit( AstFrame *, int, int * ); -static void SetAxis( AstFrame *, int, AstAxis *, int * ); -static void SetDirection( AstFrame *, int, int, int * ); -static void SetFormat( AstFrame *, int, const char *, int * ); -static void SetFrameFlags( AstFrame *, int, int * ); -static void SetLabel( AstFrame *, int, const char *, int * ); -static void SetSymbol( AstFrame *, int, const char *, int * ); -static void SetUnit( AstFrame *, int, const char *, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static double GetEpoch( AstFrame *, int * ); -static void ClearEpoch( AstFrame *, int * ); -static void SetEpoch( AstFrame *, double, int * ); - -static double GetDtai( AstFrame *, int * ); -static void ClearDtai( AstFrame *, int * ); -static void SetDtai( AstFrame *, double, int * ); - -static double GetDut1( AstFrame *, int * ); -static void ClearDut1( AstFrame *, int * ); -static void SetDut1( AstFrame *, double, int * ); - -static double GetObsLon( AstFrame *, int * ); -static void ClearObsLon( AstFrame *, int * ); -static void SetObsLon( AstFrame *, double, int * ); - -static double GetObsLat( AstFrame *, int * ); -static void ClearObsLat( AstFrame *, int * ); -static void SetObsLat( AstFrame *, double, int * ); - -static double GetObsAlt( AstFrame *, int * ); -static void ClearObsAlt( AstFrame *, int * ); -static void SetObsAlt( AstFrame *, double, int * ); - -static void ClearAlignSystem( AstFrame *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ -static const char *Abbrev( AstFrame *this_frame, int axis, const char *fmt, - const char *str1, const char *str2, int *status ) { -/* -* Name: -* Abbrev - -* Purpose: -* Abbreviate a formatted CmpFrame axis value by skipping leading fields. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* const char *Abbrev( AstFrame *this, int axis, const char *fmt, -* const char *str1, const char *str2, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astAbbrev -* method inherited from the Frame class). - -* Description: -* This function compares two CmpFrame axis values that have been -* formatted (using astFormat) and determines if they have any -* redundant leading fields (i.e. leading fields in common which -* can be suppressed when tabulating the values or plotting them on -* the axis of a graph). - -* Parameters: -* this -* Pointer to the CmpFrame. -* axis -* The number of the CmpFrame axis for which the values have -* been formatted (axis numbering starts at zero for the first -* axis). -* fmt -* Pointer to a constant null-terminated string containing the -* format specification used to format the two values. -* str1 -* Pointer to a constant null-terminated string containing the -* first formatted value. If this is null, the returned pointer -* points to the start of the final field in str2. -* str2 -* Pointer to a constant null-terminated string containing the -* second formatted value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer into the "str2" string which locates the first -* character in the first field that differs between the two -* formatted values. -* -* If the two values have no leading fields in common, the returned -* value will point at the start of string "str2". If the two -* values are equal, it will point at the terminating null at the -* end of this string. - -* Notes: -* - This function assumes that the format specification used was -* the same when both values were formatted and that they both -* apply to the same CmpFrame axis. -* - A pointer to the start of "str2" will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - AstFrame *frame; /* Pointer to Frame containing axis */ - const char *result; /* Pointer value to return */ - int naxes1; /* Number of axes in frame1 */ - int set; /* Digits attribute set? */ - -/* Initialise. */ - result = str2; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate and permute the axis index supplied. */ - axis = astValidateAxis( this, axis, 1, "astAbbrev" ); - -/* Determine the number of axes in the first component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - if ( astOK ) { - -/* Decide which component Frame contains the axis and adjust the axis - index if necessary. */ - frame = ( axis < naxes1 ) ? this->frame1 : this->frame2; - axis = ( axis < naxes1 ) ? axis : axis - naxes1; - -/* Since the component Frame is "managed" by the enclosing CmpFrame, - we next test if any Frame attributes which may affect the result - are undefined (i.e. have not been explicitly set). If so, we - over-ride them, giving them temporary values dictated by the - CmpFrame. Only the Digits attribute is relevant here. */ - set = astTestDigits( frame ); - if ( !set ) astSetDigits( frame, astGetDigits( this ) ); - -/* Invoke the Frame's astAbbrev method to perform the processing. */ - result = astAbbrev( frame, axis, fmt, str1, str2 ); - -/* Clear Frame attributes which were temporarily over-ridden. */ - if ( !set ) astClearDigits( frame ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = str2; - -/* Return the result. */ - return result; -} - -static void AddExtraAxes( int naxes, int axes[], int i1, int i2, - int following, int *status ) { -/* -* Name: -* AddExtraAxes - -* Purpose: -* Add extra axis indices in place of missing ones. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void AddExtraAxes( int naxes, int axes[], int i1, int i2, -* int following, int *status ) - -* Class Membership: -* CmpFrame member function. - -* Description: -* This function takes an array of axis indices that refer to the -* axes of a Frame, and which may have values missing (denoted by -* an index of -1). It replaces each occurrence of -1 by a new axis -* index (and re-numbers the others to avoid duplication) in such a -* way that the new indices introduced are "associated" with -* certain of the pre-existing indices, by virtue of being numbered -* consecutively with them. -* -* The purpose of this operation is to establish the relative -* location of new axes in relation to the pre-existing ones. -* -* Normally, each new axis will be associated with (i.e. numbered -* one more than) the pre-existing index which precedes -* it. However, if the "following" parameter is non-zero, it will -* instead be associated with (numbered one less than) the one -* which follows it. If there is no preceding (or following) -* pre-existing index, the following (or preceding) one is used -* instead. If several adjacent occurrences of -1 must be replaced, -* they are numbered consecutively in their order of occurrence. - -* Parameters: -* naxes -* The number of axis indices in the array. -* axes -* The array containing the axis indices. -* i1 -* Index of the first element of the array to be processed. -* i2 -* Index of the last element of the array to be processed. -* following -* Boolean flag to determine if new indices are associated with -* the preceding index (if zero) or the following index (if -* non-zero). -* status -* Pointer to the inherited status variable. - -* Notes: -* - The values of "i1" and "i2" dictate the range of array -* elements where values of -1 will be replaced, but all array -* elements are candidates for renumbering in order to avoid -* duplicate axis indices. -* - This function aims to establish the location of new axes only -* by means of the relative numerical value of the indices assigned -* to them. It does not constrain the actual indices assigned in -* any further way. -* - Because axis indices are always incremented (never -* decremented) in order to avoid duplicates, where a number of new -* indices have been introduced, the maximum index present in the -* result array may exceed the original maximum. -* - Some axis indices may remain unused (i.e. not present) in the -* result array. -*/ - -/* Local Variables: */ - int end; /* Loop termination value */ - int extra; /* Index to apply to next "extra" axis */ - int found; /* Default value found? */ - int i; /* Main loop counter */ - int inc; /* Loop increment value */ - int j; /* Loop counter for eliminating duplicates */ - int start; /* Loop starting value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise the default index of the next extra axis to add. This - will apply only if there are no valid axis indices from which to - obtain a better default. */ - extra = 0; - -/* Initialise loop parameters so as to scan the axis indices provided - in either the forward or reverse direction, according to the value - of "following". Start with the section of the array being processed, - but continue looking for a default right up to the end of the array - (this prevents the current section being numbered inconsistently - with respect to adjacent ones that may already have been - processed). */ - start = following ? i2 : i1; - end = following ? -1 : naxes; - inc = following ? -1 : 1; - -/* Search for the first (in whichever direction this is) valid axis - index and use it to set a new default index for the next extra axis - to add. If scanning forward, use the valid axis index (causing any - preceding extra axis to displace it upwards). If scanning - backwards, use one more than the valid axis index (causing any - following extra axis to tag on the end). */ - found = 0; - for ( i = start; i != end; i += inc ) { - if ( axes[ i ] != -1 ) { - found = 1; - extra = axes[ i ] + ( following ? 1 : 0 ); - break; - } - } - -/* If no default has yet been found, repeat the above process by - scanning in the opposite direction (by inverting the "following" - value used). Again, this prevents inconsistency with neighbouring - regions. This time a default must be found unless the entire array - is filled with -1's (in which case a default of zero is used). */ - if ( !found ) { - start = !following ? i2 : i1; - end = !following ? -1 : naxes; - inc = !following ? -1 : 1; - for ( i = start; i != end; i += inc ) { - if ( axes[ i ] != -1 ) { - extra = axes[ i ] + ( !following ? 1 : 0 ); - break; - } - } - } - -/* Reset the loop parameters to scan just the region of interest in - the original (correct) direction. */ - start = following ? i2 : i1; - end = following ? i1 - 1 : i2 + 1; - inc = following ? -1 : 1; - -/* Identify those indices which are not valid. */ - for ( i = start; i != end; i += inc ) { - if ( axes[ i ] == -1 ) { - -/* We wish to assign the value "extra" in place of this invalid axis - index. However, this may duplicate an index already present, so - increment by one all valid indices which are not less than the new - index. This eliminates any possibility duplication, although it may - leave an axis index value unused (if no duplication would actually - have occurred). */ - for ( j = 0; j < naxes; j++ ) { - if ( axes[ j ] != -1 ) { - if ( axes[ j ] >= extra ) axes[ j ]++; - } - } - -/* We can now assign the new axis index. */ - axes[ i ] = extra; - -/* Assign the value to be used for the next extra axis index. If - scanning forward, this will be one more than the last one used (so - it will follow it). If scanning backwards, it is equal to the last - one (so that it will displace the last one upwards). */ - extra += ( following ? 0 : 1 ); - -/* When a valid axis index is encountered, reset the value to be used - for the next extra axis index. If scanning forward, this is one - more than the last valid index (so the extra axis will follow - it). If scanning backwards, it is equal to the last valid index (so - it will displace the valid index upwards). */ - } else { - extra = axes[ i ] + ( following ? 0 : 1 ); - } - } -} - -static double Angle( AstFrame *this_frame, const double a[], - const double b[], const double c[], int *status ) { -/* -* Name: -* Angle - -* Purpose: -* Calculate the angle subtended by two points at a third point. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double Angle( AstFrame *this_frame, const double a[], -* const double b[], const double c[], int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astAngle method -* inherited from the Frame class). - -* Description: -* This function finds the angle at point B between the line joining -* points A and B, and the line joining points C and B, in the context -* of a CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* a -* An array of double, with one element for each CmpFrame axis, -* containing the coordinates of the first point. -* b -* An array of double, with one element for each CmpFrame axis, -* containing the coordinates of the second point. -* c -* An array of double, with one element for each CmpFrame axis, -* containing the coordinates of the third point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The required angle, or AST__BAD if the angle is undefined. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - AstFrame *pframe; /* Pointer to the primary Frame for an axis */ - const int *perm; /* Pointer to axis permutation array */ - double *pa; /* Permuted coordinates for point a */ - double *pb; /* Permuted coordinates for point b */ - double *pc; /* Permuted coordinates for point c */ - double ang1; /* Angle between input points in frame1 */ - double ang2; /* Angle between input points in frame2 */ - double result; /* Required angle */ - int axis; /* Loop counter for axes */ - int iscart; /* Is the CmpFrame a Cartesian system? */ - int naxes1; /* Number of axes in frame1 */ - int naxes; /* Total number of axes in CmpFrame */ - int paxis; /* Axis index within primary Frame */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Obtain the number of axes in the CmpFrame. */ - naxes = astGetNaxes( this ); - -/* See if all axes within the CmpFrame belong to a simple Frame, in which - case we assume that the CmpFrame describes a Cartesian coordinate system. */ - iscart = 1; - for( axis = 0; axis < naxes; axis++ ){ - PrimaryFrame( this_frame, axis, &pframe, &paxis, status ); - if( strcmp( astGetClass( pframe ), "Frame" ) ) { - iscart = 0; - pframe = astAnnul( pframe ); - break; - } - pframe = astAnnul( pframe ); - } - -/* If the CmpFrame describes a Cartesian coordinate system, we can use the - Angle method from the parent Frame class. */ - if( iscart ) { - result = (*parent_angle)( this_frame, a, b, c, status ); - -/* If the CmpFrame is not Cartesian... */ - } else { - -/* Obtain a pointer to the CmpFrame's axis permutation array. */ - perm = astGetPerm( this ); - -/* Get workspace. */ - pa = (double *) astMalloc( sizeof(double)*naxes ); - pb = (double *) astMalloc( sizeof(double)*naxes ); - pc = (double *) astMalloc( sizeof(double)*naxes ); - -/* If OK, apply the axis permutation array to obtain the coordinates in the - required order. */ - if( astOK ) { - for( axis = 0; axis < naxes; axis++ ) { - pa[ perm[ axis ] ] = a[ axis ]; - pb[ perm[ axis ] ] = b[ axis ]; - pc[ perm[ axis ] ] = c[ axis ]; - } - -/* Obtain the number of axes in the first component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - -/* Project the two input points into the two component Frames and - determine the angle between the points in each Frame. */ - ang1 = astAngle( this->frame1, pa, pb, pc ); - ang2 = astAngle( this->frame2, pa + naxes1, pb + naxes1, - pc + naxes1 ); - -/* The required angle is defined if one and only one of the two component - frames gives a defined angle between the two points. */ - if( ang1 == AST__BAD ) { - result = ang2; - } else if( ang2 == AST__BAD ) { - result = ang1; - } - } - -/* Free the workspace */ - pa = (double *) astFree( (void *) pa ); - pb = (double *) astFree( (void *) pb ); - pc = (double *) astFree( (void *) pc ); - } - -/* Return the result. */ - return result; -} - -static AstObject *Cast( AstObject *this_object, AstObject *obj, int *status ) { -/* -* Name: -* Cast - -* Purpose: -* Cast an Object into an instance of a sub-class. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstObject *Cast( AstObject *this, AstObject *obj, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astCast -* method inherited from the Frame class). - -* Description: -* This function returns a deep copy of an ancestral component of the -* supplied object. The required class of the ancestral component is -* specified by another object. Specifically, if "this" and "new" are -* of the same class, a copy of "this" is returned. If "this" is an -* instance of a subclass of "obj", then a copy of the component -* of "this" that matches the class of "obj" is returned. Otherwise, -* a NULL pointer is returned without error. - -* Parameters: -* this -* Pointer to the Object to be cast. -* obj -* Pointer to an Object that defines the class of the returned Object. -* The returned Object will be of the same class as "obj". - -* Returned Value: -* A pointer to the new Object. NULL if "this" is not a sub-class of -* "obj", or if an error occurs. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables; */ - AstAxis *newaxis; - AstFrame *cfrm; - AstFrame *this; - AstObject *new; - astDECLARE_GLOBALS - int generation_gap; - int i; - int naxes; - -/* Initialise */ - new = NULL; - -/* Check inherited status */ - if( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* See how many steps up the class inheritance ladder it is from "obj" - to this class (CmpFrame). A positive value is returned if CmpFrame - is a sub-class of "obj". A negative value is returned if "obj" is - a sub-class of CmpFrame. Zero is returned if "obj" is a CmpFrame. - AST__COUSIN is returned if "obj" is not on the same line of descent - as CmpFrame. */ - generation_gap = astClassCompare( (AstObjectVtab *) &class_vtab, - astVTAB( obj ) ); - -/* If "obj" is a CmpFrame or a sub-class of CmpFrame, we can cast by - truncating the vtab for "this" so that it matches the vtab of "obJ", - and then taking a deep copy of "this". */ - if( generation_gap <= 0 && generation_gap != AST__COUSIN ) { - new = astCastCopy( this_object, obj ); - -/* If "obj" is not a CmpFrame or a sub-class of CmpFrame (e.g. it's a - Frame), we create a basic Frame containing the same axes and attributes - as the CmpFrame, and then attempt to cast this Frame into the class - indicated by "obj". */ - } else { - this = (AstFrame *) this_object; - -/* Create a basic Frame with the right number of axes. */ - naxes = astGetNaxes( this ); - cfrm = astFrame( naxes, " ", status ); - -/* Replace the Axis structures in the basic Frame with those in the - CmpFrame. */ - for( i = 0; i < naxes; i++ ) { - newaxis = astGetAxis( this, i ); - astSetAxis( cfrm, i, newaxis ); - newaxis = astAnnul( newaxis ); - } - -/* Overlay the properties of the CmpFrame onto the basic Frame. */ - astOverlay( this, NULL, cfrm ); - -/* Try to cast the basic Frame to the class of "obj". */ - new = astCast( cfrm, obj ); - -/* Annull the basic Frame. */ - cfrm = astAnnul( cfrm ); - } - -/* Return the new pointer. */ - return new; -} - -static double Centre( AstFrame *this_frame, int axis, double value, double gap, int *status ) { -/* -* Name: -* Centre - -* Purpose: -* Find a "nice" central value for tabulating CmpFrame axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double Centre( AstFrame *this_frame, int axis, double value, -* double gap, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astCentre method -* inherited from the Frame class). - -* Description: -* This function returns an axis value which produces a nice formatted -* value suitable for a major tick mark on a plot axis, close to the -* supplied axis value. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which a central value -* is to be found. -* value -* An arbitrary axis value in the section that is being plotted. -* gap -* The gap size. - -* Returned Value: -* The nice central axis value. - -* Notes: -* - A value of zero is returned if the supplied gap size is zero. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - AstFrame *frame; /* Pointer to Frame containing axis */ - double result; /* Result value to return */ - int naxes1; /* Number of axes in frame1 */ - int set1; /* Digits attribute set? */ - int set2; /* Format attribute set? */ - -/* Initialise. */ - result = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate and permute the axis index supplied. */ - axis = astValidateAxis( this, axis, 1, "astCentre" ); - -/* Determine the number of axes in the first component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - if ( astOK ) { - -/* Decide which component Frame contains the axis and adjust the axis - index if necessary. */ - frame = ( axis < naxes1 ) ? this->frame1 : this->frame2; - axis = ( axis < naxes1 ) ? axis : axis - naxes1; - -/* Since the component Frame is "managed" by the enclosing CmpFrame, - we next test if any Frame attributes which may affect the result - are undefined (i.e. have not been explicitly set). If so, we - over-ride them, giving them temporary values dictated by the - CmpFrame. Only the Digits and Format attributes are relevant here. */ - set1 = astTestDigits( frame ); - if ( !set1 ) astSetDigits( frame, astGetDigits( this ) ); - - set2 = astTestFormat( frame, axis ); - if ( !set2 ) astSetFormat( frame, axis, astGetFormat( this, axis ) ); - -/* Invoke the Frame's astCentre method to find the central value. */ - result = astCentre( frame, axis, value, gap ); - -/* Clear Frame attributes which were temporarily over-ridden. */ - if ( !set1 ) astClearDigits( frame ); - if ( !set2 ) astClearFormat( frame, axis ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static void ClearAlignSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearAlignSystem - -* Purpose: -* Clear the value of the AlignSystem attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void ClearAlignSystem( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astClearAlignSystem method -* inherited from the Frame class). - -* Description: -* This function clears the AlignSystem value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to clear the CmpFrame AlignSystem value. */ - (*parent_clearalignsystem)( this_frame, status ); - -/* Now clear the AlignSystem attribute in the two component Frames. */ - astClearAlignSystem( this->frame1 ); - astClearAlignSystem( this->frame2 ); -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astClearAttrib protected -* method inherited from the Frame class). - -* Description: -* This function clears the value of a specified attribute for a -* CmpFrame, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the CmpFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - AstFrame *pfrm; /* Pointer to primary Frame containing axis */ - char buf1[80]; /* For for un-indexed attribute name */ - char buf2[80]; /* For for indexed attribute name */ - int axis; /* Sipplied (1-based) axis index */ - int len; /* Length of attrib string */ - int nc; /* Number of characters used so dar */ - int oldrep; /* Original error reporting state */ - int paxis; /* Index of primary Frame axis */ - int ok; /* Has the attribute been accessed succesfully? */ - - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Indicate we have not yet acessed the attribute succesfully. */ - ok = 0; - -/* First check the supplied attribute name against each of the attribute - names defined by this class. In fact there is nothing to do here - since the CmpFrame class currently defines no extra attributes, but - this may change in the future. */ - if( 0 ) { - - - -/* If the attribute is not a CmpFrame specific attribute... */ - } else if( astOK ) { - -/* We want to allow easy access to the attributes of the component Frames. - That is, we do not want it to be necessary to extract a Frame from - its parent CmpFrame in order to access its attributes. For this reason - we first temporarily switch off error reporting so that if an attempt - to access the attribute fails, we can try a different approach. */ - oldrep = astReporting( 0 ); - -/* Our first attempt is to see if the attribute is recognised by the parent - class (Frame). */ - (*parent_clearattrib)( this_object, attrib, status ); - -/* Indicate success. */ - if( astOK ) { - ok = 1; - -/* Otherwise, clear the error condition so that we can try a different - approach. */ - } else { - astClearStatus; - -/* If the attribute is qualified by an axis index, try accessing it as an - attribute of the primary Frame containing the specified index. */ - if ( nc = 0, - ( 2 == astSscanf( attrib, "%[^(](%d)%n", buf1, &axis, &nc ) ) - && ( nc >= len ) ) { - -/* Find the primary Frame containing the specified axis. */ - astPrimaryFrame( this, axis - 1, &pfrm, &paxis ); - if( astOK ) { - -/* astPrimaryFrame returns the original - unpermuted - axis index within - the primary Frame. So we need to take into account any axis permutation - which has been applied to the primary Frame when forming the attribute name - to use below. Find the permuted (external) axis index which corresponds to - the internal (unpermuted) axis index "paxis". */ - paxis = astValidateAxis( pfrm, paxis, 0, "astClear" ); - -/* Create a new attribute with the same name but with the axis index - appropriate to the primary Frame. */ - sprintf( buf2, "%s(%d)", buf1, paxis + 1 ); - -/* Attempt to access the attribute. */ - astClearAttrib( pfrm, buf2 ); - -/* Indicate success. */ - if( astOK ) { - ok = 1; - -/* Otherwise clear the status value, and try again without any axis index. */ - } else { - astClearStatus; - astClearAttrib( pfrm, buf1 ); - -/* Indicate success, or clear the status value. */ - if( astOK ) { - ok = 1; - } else { - astClearStatus; - } - } - -/* Free the primary frame pointer. */ - pfrm = astAnnul( pfrm ); - } - -/* If the attribute is not qualified by an axis index, try accessing it - using the primary Frame of each axis in turn. */ - } else { - -/* Loop round all axes attribute. */ - for( axis = 0; axis < astGetNaxes( this ); axis++ ) { - -/* Get the primary Frame containing this axis. */ - astPrimaryFrame( this, axis, &pfrm, &paxis ); - -/* Attempt to access the attribute as an attribute of the primary Frame. */ - astClearAttrib( pfrm, attrib ); - -/* Free the primary Frame pointer. */ - pfrm = astAnnul( pfrm ); - -/* Indicate success, or clear the status value. */ - if( astOK ) { - ok = 1; - } else { - astClearStatus; - } - } - } - } - -/* Re-instate the original error reporting state. */ - astReporting( oldrep ); - - } - -/* Report an error if the attribute could not be accessed. */ - if( !ok && astOK ) { - astError( AST__BADAT, "astClear: The %s given does not have an attribute " - "called \"%s\".", status, astGetClass( this ), attrib ); - } - -} - -static void ClearDtai( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearDtai - -* Purpose: -* Clear the value of the Dtai attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void ClearDtai( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astClearDtai method -* inherited from the Frame class). - -* Description: -* This function clears the Dtai value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to clear the CmpFrame Dtai value. */ - (*parent_cleardtai)( this_frame, status ); - -/* Now clear the Dtai attribute in the two component Frames. */ - astClearDtai( this->frame1 ); - astClearDtai( this->frame2 ); -} - -static void ClearDut1( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearDut1 - -* Purpose: -* Clear the value of the Dut1 attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void ClearDut1( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astClearDut1 method -* inherited from the Frame class). - -* Description: -* This function clears the Dut1 value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to clear the CmpFrame Dut1 value. */ - (*parent_cleardut1)( this_frame, status ); - -/* Now clear the Dut1 attribute in the two component Frames. */ - astClearDut1( this->frame1 ); - astClearDut1( this->frame2 ); -} - -static void ClearEpoch( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearEpoch - -* Purpose: -* Clear the value of the Epoch attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void ClearEpoch( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astClearEpoch method -* inherited from the Frame class). - -* Description: -* This function clears the Epoch value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to clear the CmpFrame epoch. */ - (*parent_clearepoch)( this_frame, status ); - -/* Now clear the Epoch attribute in the two component Frames. */ - astClearEpoch( this->frame1 ); - astClearEpoch( this->frame2 ); -} - -static void ClearObsAlt( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearObsAlt - -* Purpose: -* Clear the value of the ObsAlt attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void ClearObsAlt( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astClearObsAlt method -* inherited from the Frame class). - -* Description: -* This function clears the ObsAlt value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to clear the CmpFrame ObsAlt. */ - (*parent_clearobsalt)( this_frame, status ); - -/* Now clear the ObsAlt attribute in the two component Frames. */ - astClearObsAlt( this->frame1 ); - astClearObsAlt( this->frame2 ); -} - -static void ClearObsLat( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearObsLat - -* Purpose: -* Clear the value of the ObsLat attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void ClearObsLat( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astClearObsLat method -* inherited from the Frame class). - -* Description: -* This function clears the ObsLat value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to clear the CmpFrame ObsLat. */ - (*parent_clearobslat)( this_frame, status ); - -/* Now clear the ObsLat attribute in the two component Frames. */ - astClearObsLat( this->frame1 ); - astClearObsLat( this->frame2 ); -} - -static void ClearObsLon( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearObsLon - -* Purpose: -* Clear the value of the ObsLon attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void ClearObsLon( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astClearObsLon method -* inherited from the Frame class). - -* Description: -* This function clears the ObsLon value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to clear the CmpFrame ObsLon. */ - (*parent_clearobslon)( this_frame, status ); - -/* Now clear the ObsLon attribute in the two component Frames. */ - astClearObsLon( this->frame1 ); - astClearObsLon( this->frame2 ); -} - -static int ComponentMatch( AstCmpFrame *template, AstFrame *target, int matchsub, - int icomp, int **template_axes, int **target_axes, - AstMapping **map, AstFrame **result, int *status ) { -/* -* Name: -* ComponentMatch - -* Purpose: -* Determine if conversion is possible between a component Frame in a -* template CmpFrame and another target Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int ComponentMatch( AstCmpFrame *template, AstFrame *target, int matchsub, -* int icomp, int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* CmpFrame member function - -* Description: -* This function is like astMatch, but it compares the supplied target -* Frame with a specified component Frame of the supplied template -* CmpFrame, rather than with the entire template CmpFrame. If a match -* is found, the returned Mapping, Frame and axis lists are adjusted so -* that they refer to the entire template CmpFrame. - -* Parameters: -* template -* Pointer to the template CmpFrame. This describes the -* coordinate system (or set of possible coordinate systems) -* into which we wish to convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate -* system in which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case (i.e. if the -* target is of a more specialised class than the template). In -* this latter case, the target is cast down to the class of the -* template. -* icomp -* The index of the component Frame to use within the template -* CmpFrame; 0 or 1. -* template_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* template CmpFrame axis from which it is derived. If it is not -* derived from any template axis, a value of -1 will be -* returned instead. -* target_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* target Frame axis from which it is derived. If it is not -* derived from any target axis, a value of -1 will be returned -* instead. -* map -* Address of a location where a pointer to a new Mapping will -* be returned if the requested coordinate conversion is -* possible. If returned, the forward transformation of this -* Mapping may be used to convert coordinates between the -* "target" Frame and the "result" Frame (see below) and the -* inverse transformation will convert in the opposite -* direction. -* result -* Address of a location where a pointer to a new Frame will be -* returned if the requested coordinate conversion is -* possible. If returned, this Frame describes the coordinate -* system that results from applying the returned Mapping -* (above) to the "target" coordinate system. In general, this -* Frame will combine attributes from (and will therefore be -* more specific than) both the target Frame and the template -* CmpFrame. In particular, when the template allows the -* possibility of transformaing to any one of a set of -* alternative coordinate systems, the "result" Frame will -* indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate -* conversion is possible. Otherwise zero is returned (this will -* not in itself result in an error condition). - -* Notes: -* - By default, the "result" Frame will have its number of axes -* and axis order determined by the "template" CmpFrame. However, -* if the PreserveAxes attribute of the template CmpFrame is -* non-zero, then the axis count and axis order of the "target" -* Frame will be used instead. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *ctemplate; - AstFrame *fother; - AstFrame *fresult; - AstMapping *fmap; - AstPermMap *pm; - const int *perm; - int *ftarget_axes; - int *ftemplate_axes; - int *inperm; - int *operm; - int *outperm; - int axis; - int match; - int nax1; - int nax2; - int naxr; - int prax; - int praxo; - int result_naxes; - int template_naxes; - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Get a pointer to the requested component Frame of the template CmpFrame. */ - ctemplate = icomp ? template->frame2 :template->frame1; - -/* Temporarily set the component Frame PreserveAxes value to that of the - template CmpFrame. PreserveAxes determines whether astMatch returns a - result Frame that looks like the template or the target. */ - if( astTestPreserveAxes( ctemplate ) ) { - praxo = astGetPreserveAxes( ctemplate ) ? 1 : 0; - } else { - praxo = -1; - } - prax = astGetPreserveAxes( template ); - astSetPreserveAxes( ctemplate, prax ); - -/* Attempt to find a match between the axes of the supplied target Frame - and the axes of the selected component Frame in the template. */ - match = astMatch( ctemplate, target, matchsub, &ftemplate_axes, &ftarget_axes, - &fmap, &fresult ); - -/* Restore the original PreserveAxes value in the component template - Frame. */ - if( praxo == -1 ) { - astClearPreserveAxes( ctemplate ); - } else { - astSetPreserveAxes( ctemplate, praxo ); - } - -/* If a match was found, we need to adjust the Mapping, Frame and axis - lists returned by the above call to astMatch so that they refer to the - full template CmpFrame or target (depending on PreserveAxes). */ - if( match ) { - -/* Get the number of axes in each component Frame and the total number of - axes in the template CmpFrame. */ - nax1 = astGetNaxes( template->frame1 ); - nax2 = astGetNaxes( template->frame2 ); - template_naxes = nax1 + nax2; - -/* Get the axis permutation array from the template and get its inverse. - The "perm" array holds the internal axis index at each external axis - index. The "operm" array holds the external axis index at each - internal axis index. */ - perm = astGetPerm( template ); - operm = astMalloc( sizeof( int )*(size_t)template_naxes ); - if( astOK) { - for( axis = 0; axis < template_naxes; axis++ ) { - operm[ perm[ axis ] ] = axis; - } - -/* The PreserveAxes attribute is used by astMatch to decide whether the - result Frame should inherit its axes from the target frame or the - template frame. First deal with cases where the order and count of axes - in the result frame is the same as the target. */ - if( prax ) { - -/* Return the result Frame and Mapping unchanged since they already refer - to the full target Frame used in the above call to astMatch. */ - *result = astClone( fresult ); - *map = astClone( fmap ); - -/* Also return the lists of target axes unchanged. */ - *target_axes = ftarget_axes; - -/* The values in the template axes list refer to the component template - Frame, but we want to return values that refer to the full template - CmpFrame. This involve sup to two setps 1) for the second component - Frame only, increase the axis numbers by the number of axes in the - first component Frame, and 2) take account of any axis permutation in - the template. First allocate memory for the returned list (which, - because PreserveAxes is zero, will have an entry for each template axis). */ - *template_axes = astMalloc( sizeof( int )*template_naxes ); - -/* Now, if the second component of the template has been selected, increment - the template axes so that they give the internal axis indices of the - second component Frame within the CmpFrame. The first component axes - will be unchanged. */ - result_naxes = astGetNaxes( fresult ); - if( icomp ) { - for( axis = 0; axis < result_naxes; axis++ ) { - ftemplate_axes[ axis ] += nax1; - } - } - -/* Now copy the internal axis value into the returned array, modifying them - in the process from internal to external axis ordering. */ - for( axis = 0; axis < result_naxes; axis++ ) { - (*template_axes)[ axis ] = operm[ ftemplate_axes[ axis ] ]; - } - -/* If the order and count of axes in the result frame is the same as the - template CmpFrame... */ - } else { - -/* We need to adjust the Mapping, Frame and axis lists returned by the - above call to astMatch so that they refer to the supplied template - CmpFrame rather than to the selected component Frame. Get the number - of axes in the result Frame returned by astMatch (naxr) and the number - in the result Frame returned by this function (result-naxes). */ - naxr = astGetNaxes( fresult ); - result_naxes = ( icomp ? nax1 : nax2 ) + naxr; - -/* Create the full result Frame by combining the partial result Frame - returned by astMatch above with the other component Frame from the - template. */ - if( icomp ) { - fother = astCopy( template->frame1 ); - *result = (AstFrame *) astCmpFrame( fother, fresult, "", status ); - } else { - fother = astCopy( template->frame2 ); - *result = (AstFrame *) astCmpFrame( fresult, fother, "", status ); - } - fother = astAnnul( fother ); - -/* Modify the Mapping returned by the above call to astMatch so that it - produces positions within the full result Frame created above. */ - if( icomp ) { - inperm = astMalloc( sizeof( int )*(size_t) naxr ); - outperm = astMalloc( sizeof( int )*(size_t) result_naxes ); - if( astOK ) { - for( axis = 0; axis < nax1; axis++ ) outperm[ axis ] = -1; - for( axis = 0; axis < naxr; axis++ ) { - outperm[ axis + nax1 ] = axis; - inperm[ axis ] = axis + nax1; - } - } - - } else { - inperm = NULL; - outperm = NULL; - } - - pm = astPermMap( naxr, inperm, result_naxes, outperm, NULL, "", status ); - *map = (AstMapping *) astCmpMap( fmap, pm, 1, "", status ); - -/* Free resources. */ - pm = astAnnul( pm ); - if( inperm ) inperm = astFree( inperm ); - if( outperm ) outperm = astFree( outperm ); - -/* Allocate memory for the returned list of axes. */ - *template_axes = astMalloc( sizeof( int )*(size_t)result_naxes ); - *target_axes = astMalloc( sizeof( int )*(size_t)result_naxes ); - -/* The axis indices returned by astMatch above will refer to the selected - component Frame rather than the permuted (i.e. external) axis indices for - the template CmpFrame. Change the template axes list so that they describe - the axes in the full result Frame in terms of the external template axis - numbering. This involves shifting the indices for the second component - Frame to leave room for the axes of the first component Frame, and - also permuting the axis indices from internal to external order. */ - if( icomp ) { - for( axis = 0; axis < nax1; axis++ ) { - (*template_axes)[ axis ] = operm[ axis ]; - } - - for( ; axis < result_naxes; axis++ ) { - (*template_axes)[ axis ] = operm[ nax1 + ftemplate_axes[ axis - nax1 ] ]; - } - - } else { - for( axis = 0; axis < nax1; axis++ ) { - (*template_axes)[ axis ] = operm[ ftemplate_axes[ axis ] ]; - } - - for( ; axis < result_naxes; axis++ ) { - (*template_axes)[ axis ] = operm[ axis ]; - } - } - -/* Change the target axes list so that they describe the axes in the - full result Frame (this just means padding with -1 to indicate that - the extra axes do not correspond to any axis in the target). */ - for( axis = 0; axis < naxr; axis++ ) { - (*target_axes)[ axis ] = ftarget_axes[ axis ]; - } - - for( ; axis < result_naxes; axis++ ) { - (*target_axes)[ axis ] = -1; - } - -/* Free resources */ - ftarget_axes = astFree( ftarget_axes ); - } - } - - operm = astFree( operm ); - ftemplate_axes = astFree( ftemplate_axes ); - fmap = astAnnul( fmap ); - fresult = astAnnul( fresult ); - - } - -/* If an error occurred, free all allocated memory, annul the result - Object pointers and clear all returned values. */ - if ( !astOK ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - *map = astAnnul( *map ); - *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static void Decompose( AstMapping *this_cmpframe, AstMapping **map1, - AstMapping **map2, int *series, int *invert1, - int *invert2, int *status ) { -/* -* -* Name: -* Decompose - -* Purpose: -* Decompose a CmpFrame into two component CmpFrames. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void Decompose( AstMapping *this, AstMapping **map1, -* AstMapping **map2, int *series, -* int *invert1, int *invert2, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astDecompose -* method inherited from the Mapping class). - -* Description: -* This function returns pointers to two Mappings which, when applied -* either in series or parallel, are equivalent to the supplied Mapping. -* -* Since the Frame class inherits from the Mapping class, Frames can -* be considered as special types of Mappings and so this method can -* be used to decompose either CmpMaps or CmpFrames. - -* Parameters: -* this -* Pointer to the Mapping. -* map1 -* Address of a location to receive a pointer to first component -* Mapping. -* map2 -* Address of a location to receive a pointer to second component -* Mapping. -* series -* Address of a location to receive a value indicating if the -* component Mappings are applied in series or parallel. A non-zero -* value means that the supplied Mapping is equivalent to applying map1 -* followed by map2 in series. A zero value means that the supplied -* Mapping is equivalent to applying map1 to the lower numbered axes -* and map2 to the higher numbered axes, in parallel. -* invert1 -* The value of the Invert attribute to be used with map1. -* invert2 -* The value of the Invert attribute to be used with map2. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Any changes made to the component rames using the returned -* pointers will be reflected in the supplied CmpFrame. - -*- -*/ - - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpMap structure. */ - this = (AstCmpFrame *) this_cmpframe; - -/* The components Frames of a CmpFrame are considered to be parallel - Mappings. */ - if( series ) *series = 0; - -/* The Frames are returned in their original order whether or not the - CmpFrame has been inverted. */ - if( map1 ) *map1 = astClone( this->frame1 ); - if( map2 ) *map2 = astClone( this->frame2 ); - -/* If the CmpFrame has been inverted, return inverted Invert flags. */ - if( astGetInvert( this ) ) { - if( invert1 ) *invert1 = astGetInvert( this->frame1 ) ? 0 : 1; - if( invert2 ) *invert2 = astGetInvert( this->frame2 ) ? 0 : 1; - -/* If the CmpFrame has not been inverted, return the current Invert flags. */ - } else { - if( invert1 ) *invert1 = astGetInvert( this->frame1 ); - if( invert2 ) *invert2 = astGetInvert( this->frame2 ); - } -} - -static double Distance( AstFrame *this_frame, - const double point1[], const double point2[], int *status ) { -/* -* Name: -* Distance - -* Purpose: -* Calculate the distance between two points. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double Distance( AstFrame *this, -* const double point1[], const double point2[], int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astDistance method -* inherited from the Frame class). - -* Description: -* This function finds the distance between two points whose -* CmpFrame coordinates are given. The distance calculated is that -* along the geodesic curve that joins the two points. This is -* computed as the Cartesian sum of the distances between the -* points when their coordinates are projected into each of the -* CmpFrame's component Frames. - -* Parameters: -* this -* Pointer to the CmpFrame. -* point1 -* An array of double, with one element for each CmpFrame axis, -* containing the coordinates of the first point. -* point2 -* An array of double, with one element for each CmpFrame axis, -* containing the coordinates of the second point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The distance between the two points. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input coordinates has this value. -* - A "bad" value will also be returned if this function is -* invoked with the AST error status set or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - const int *perm; /* Axis permutation array */ - double *p1; /* Pointer to permuted point1 coordinates */ - double *p2; /* Pointer to permuted point2 coordinates */ - double dist1; /* Distance in frame1 */ - double dist2; /* Distance in frame2 */ - double result; /* Value to return */ - int axis; /* Loop counter for axes */ - int naxes1; /* Number of axes in frame1 */ - int naxes; /* Number of axes in CmpFrame */ - int ok; /* No "bad" coordinates found? */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Obtain a pointer to the CmpFrame's axis permutation array. */ - perm = astGetPerm( this ); - -/* Obtain the number of axes in the CmpFrame and in the first - component Frame. */ - naxes = astGetNaxes( this ); - naxes1 = astGetNaxes( this->frame1 ); - -/* Allocate memory to hold the permuted coordinates of each point. */ - p1 = astMalloc( sizeof( double ) * (size_t) naxes ); - p2 = astMalloc( sizeof( double ) * (size_t) naxes ); - if ( astOK ) { - -/* Examine the coordinates of both points and note if any coordinate - value is "bad". */ - ok = 1; - for ( axis = 0; axis < naxes; axis++ ) { - if ( ( point1[ axis ] == AST__BAD ) || - ( point2[ axis ] == AST__BAD ) ) { - ok = 0; - break; - -/* Permute good coordinates using the CmpFrame's axis permutation - array to put them into the order required internally (i.e. by the - two component Frames). */ - } else { - p1[ perm[ axis ] ] = point1[ axis ]; - p2[ perm[ axis ] ] = point2[ axis ]; - } - } - -/* If no "bad" coordinates were found, obtain the distance between the - two points when their coordinates are projected into each component - Frame. */ - if ( ok ) { - dist1 = astDistance( this->frame1, p1, p2 ); - dist2 = astDistance( this->frame2, p1 + naxes1, p2 + naxes1 ); - -/* If the distances found were OK, compute the distance between the - two points as the Cartesian sum of the two component distances. */ - if ( astOK && ( dist1 != AST__BAD ) && ( dist2 != AST__BAD ) ) { - result = sqrt( ( dist1 * dist1 ) + ( dist2 * dist2 ) ); - } - } - } - -/* Free the memory used for the permuted coordinates. */ - p1 = astFree( p1 ); - p2 = astFree( p2 ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static int Fields( AstFrame *this_frame, int axis, const char *fmt, - const char *str, int maxfld, char **fields, - int *nc, double *val, int *status ) { -/* -*+ -* Name: -* astFields - -* Purpose: -* Identify numerical fields within a formatted CmpFrame axis value. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "cmpframe.h" -* int astFields( AstFrame *this, int axis, const char *fmt, -* const char *str, int maxfld, char **fields, -* int *nc, double *val ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astFields -* method inherited from the Frame class). - -* Description: -* This function identifies the numerical fields within a CmpFrame axis -* value that has been formatted using astAxisFormat. It assumes that -* the value was formatted using the supplied format string. It also -* returns the equivalent floating point value. - -* Parameters: -* this -* Pointer to the CmpFrame. -* axis -* The number of the CmpFrame axis for which the values have been -* formatted (axis numbering starts at zero for the first axis). -* fmt -* Pointer to a constant null-terminated string containing the -* format used when creating "str". -* str -* Pointer to a constant null-terminated string containing the -* formatted value. -* maxfld -* The maximum number of fields to identify within "str". -* fields -* A pointer to an array of at least "maxfld" character pointers. -* Each element is returned holding a pointer to the start of the -* corresponding field in "str" (in the order in which they occur -* within "str"), or NULL if no corresponding field can be found. -* nc -* A pointer to an array of at least "maxfld" integers. Each -* element is returned holding the number of characters in the -* corresponding field, or zero if no corresponding field can be -* found. -* val -* Pointer to a location at which to store the value -* equivalent to the returned field values. If this is NULL, -* it is ignored. - -* Returned Value: -* The number of fields succesfully identified and returned. - -* Notes: -* - Leading and trailing spaces are ignored. -* - If the formatted value is not consistent with the supplied format -* string, then a value of zero will be returned, "fields" will be -* returned holding NULLs, "nc" will be returned holding zeros, and -* "val" is returned holding VAL__BAD. -* - Fields are counted from the start of the formatted string. If the -* string contains more than "maxfld" fields, then trailing fields are -* ignored. -* - If this function is invoked with the global error status set, or -* if it should fail for any reason, then a value of zero will be returned -* as the function value, and "fields", "nc" and "val" will be returned -* holding their supplied values -*- -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - AstFrame *frame; /* Pointer to Frame containing axis */ - int naxes1; /* Number of axes in frame1 */ - int result; /* Result field count to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate and permute the axis index supplied. */ - axis = astValidateAxis( this, axis, 1, "astFields" ); - -/* Determine the number of axes in the first component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - if ( astOK ) { - -/* Decide which component Frame contains the axis and adjust the axis - index if necessary. */ - frame = ( axis < naxes1 ) ? this->frame1 : this->frame2; - axis = ( axis < naxes1 ) ? axis : axis - naxes1; - -/* Invoke the Frame's astFields method to perform the processing. */ - result = astFields( frame, axis, fmt, str, maxfld, fields, - nc, val ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static const char *Format( AstFrame *this_frame, int axis, double value, int *status ) { -/* -* Name: -* Format - -* Purpose: -* Format a coordinate value for a CmpFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* const char *Format( AstFrame *this, int axis, double value, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astFormat method -* inherited from the Frame class). - -* Description: -* This function returns a pointer to a string containing the -* formatted (character) version of a coordinate value for a -* CmpFrame axis. The formatting applied is that specified by a -* previous invocation of the astSetFormat method (or a default -* format appropriate to the axis in question). - -* Parameters: -* this -* Pointer to the CmpFrame. -* axis -* The number of the axis (zero-based) for which formatting is -* to be performed. -* value -* The coordinate value to be formatted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a null-terminated string containing the formatted -* value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - AstFrame *frame; /* Pointer to Frame containing axis */ - const char *result; /* Pointer value to return */ - int naxes1; /* Number of axes in frame1 */ - int set; /* Digits attribute set? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate and permute the axis index supplied. */ - axis = astValidateAxis( this, axis, 1, "astFormat" ); - -/* Determine the number of axes in the first component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - if ( astOK ) { - -/* Decide which component Frame contains the axis and adjust the axis - index if necessary. */ - frame = ( axis < naxes1 ) ? this->frame1 : this->frame2; - axis = ( axis < naxes1 ) ? axis : axis - naxes1; - -/* Since the component Frame is "managed" by the enclosing CmpFrame, - we next test if any Frame attributes which may affect the result - are undefined (i.e. have not been explicitly set). If so, we - over-ride them, giving them temporary values dictated by the - CmpFrame. Only the Digits attribute is relevant here. */ - set = astTestDigits( frame ); - if ( !set ) astSetDigits( frame, astGetDigits( this ) ); - -/* Invoke the Frame's astFormat method to format the value. */ - result = astFormat( frame, axis, value ); - -/* Clear Frame attributes which were temporarily over-ridden. */ - if ( !set ) astClearDigits( frame ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static AstPointSet *FrameGrid( AstFrame *this_object, int size, const double *lbnd, - const double *ubnd, int *status ){ -/* -* Name: -* FrameGrid - -* Purpose: -* Return a grid of points covering a rectangular area of a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstPointSet *FrameGrid( AstFrame *this_frame, int size, -* const double *lbnd, const double *ubnd, -* int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astFrameGrid -* method inherited from the Frame class). - -* Description: -* This function returns a PointSet containing positions spread -* approximately evenly throughtout a specified rectangular area of -* the Frame. - -* Parameters: -* this -* Pointer to the Frame. -* size -* The preferred number of points in the returned PointSet. The -* actual number of points in the returned PointSet may be -* different, but an attempt is made to stick reasonably closely to -* the supplied value. -* lbnd -* Pointer to an array holding the lower bound of the rectangular -* area on each Frame axis. The array should have one element for -* each Frame axis. -* ubnd -* Pointer to an array holding the upper bound of the rectangular -* area on each Frame axis. The array should have one element for -* each Frame axis. - -* Returned Value: -* A pointer to a new PointSet holding the grid of points. - -* Notes: -* - A NULL pointer is returned if an error occurs. -*/ - -/* Local Variables: */ - AstCmpFrame *this; - AstPointSet *ps1; - AstPointSet *ps2; - AstPointSet *result; - const int *perm; - double **ptr1; - double **ptr2; - double **ptr; - double *lbnd1; - double *lbnd2; - double *p; - double *ubnd1; - double *ubnd2; - double v; - int axis; - int iax1; - int iax2; - int iaxis; - int ip1; - int ip2; - int nax1; - int nax2; - int naxes; - int npoint1; - int npoint2; - int npoint; - int size1; - int size2; - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_object; - -/* Get the number of axes in each component Frame, and the total number - of axes. */ - nax1 = astGetNaxes( this->frame1 ); - nax2 = astGetNaxes( this->frame2 ); - naxes = nax1 + nax2; - -/* Allocate memory to hold bounds for each component Frame */ - lbnd1 = astMalloc( nax1*sizeof( double ) ); - ubnd1 = astMalloc( nax1*sizeof( double ) ); - lbnd2 = astMalloc( nax2*sizeof( double ) ); - ubnd2 = astMalloc( nax2*sizeof( double ) ); - -/* Obtain a pointer to the CmpFrame's axis permutation array. This array - holds the original axis index for each current Frame axis index. */ - perm = astGetPerm( this ); - -/* Check pointers can be used safely, and check the supplied size value - is good. */ - if( astOK && size > 0 ) { - -/* Copy the supplied bounds into the work arrays, permuting them in the - process so that they use the internal axis numbering of the two - component Frames. */ - for( axis = 0; axis < naxes; axis++ ) { - iaxis = perm[ axis ]; - if( iaxis < nax1 ) { - lbnd1[ iaxis ] = lbnd[ axis ]; - ubnd1[ iaxis ] = ubnd[ axis ]; - } else { - iaxis -= nax1; - lbnd2[ iaxis ] = lbnd[ axis ]; - ubnd2[ iaxis ] = ubnd[ axis ]; - } - } - -/* Get the target number of points to be used in the grid that covers the - first Frame. */ - size1 = (int)( pow( size, (double)nax1/(double)naxes ) + 0.5 ); - -/* Get the target number of points to be used in the grid that covers the - second Frame. */ - size2 = (int)( (double)size/(double)size1 + 0.5 ); - -/* Get the grids covering the two component Frames, and get the actual sizes - of the resulting PointSets. */ - ps1 = astFrameGrid( this->frame1, size1, lbnd1, ubnd1 ); - ptr1 = astGetPoints( ps1 ); - npoint1 = astGetNpoint( ps1 ); - - ps2 = astFrameGrid( this->frame2, size2, lbnd2, ubnd2 ); - ptr2 = astGetPoints( ps2 ); - npoint2 = astGetNpoint( ps2 ); - -/* Get the number of points in the returned FrameSet, and then create a - PointSet large enough to hold them. */ - npoint = npoint1*npoint2; - result = astPointSet( npoint, naxes, " ", status ); - ptr = astGetPoints( result ); - if( astOK ) { - -/* For every point in the first Frame's PointSet, duplicate the second - Frame's entire PointSet, using the first Frame's axis values. */ - for( ip1 = 0; ip1 < npoint1; ip1++ ) { - for( iax1 = 0; iax1 < nax1; iax1++ ) { - p = ptr[ iax1 ]; - v = ptr1[ iax1 ][ ip1 ]; - for( ip2 = 0; ip2 < npoint2; ip2++ ) { - *(p++) = v; - } - ptr[ iax1 ] = p; - } - for( iax2 = 0; iax2 < nax2; iax2++ ) { - memcpy( ptr[ iax2 + nax1 ], ptr2[ iax2 ], npoint2*sizeof( double ) ); - ptr[ iax2 + nax1 ] += npoint2*sizeof( double ); - } - } - -/* Permute the returned PointSet so that it uses external axis numbering. */ - astPermPoints( result, 1, perm ); - } - -/* Free resources. */ - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - -/* Report error if supplied values were bad. */ - } else if( astOK ) { - astError( AST__ATTIN, "astFrameGrid(%s): The supplied grid " - "size (%d) is invalid (programming error).", - status, astGetClass( this ), size ); - } - -/* Free resources. */ - lbnd1 = astFree( lbnd1 ); - ubnd1 = astFree( ubnd1 ); - lbnd2 = astFree( lbnd2 ); - ubnd2 = astFree( ubnd2 ); - -/* Annul the returned PointSet if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the PointSet holding the grid. */ - return result; -} - -static double Gap( AstFrame *this_frame, int axis, double gap, int *ntick, int *status ) { -/* -* Name: -* Gap - -* Purpose: -* Find a "nice" gap for tabulating CmpFrame axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double Gap( AstFrame *this, int axis, double gap, int *ntick, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astGap method -* inherited from the Frame class). - -* Description: -* This function returns a gap size which produces a nicely spaced -* series of formatted values for a CmpFrame axis, the returned gap -* size being as close as possible to the supplied target gap -* size. It also returns a convenient number of divisions into -* which the gap can be divided. - -* Parameters: -* this -* Pointer to the CmpFrame. -* axis -* The number of the axis (zero-based) for which a gap is to be found. -* gap -* The target gap size. -* ntick -* Address of an int in which to return a convenient number of -* divisions into which the gap can be divided. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The nice gap size. - -* Notes: -* - A value of zero is returned if the target gap size is zero. -* - A negative gap size is returned if the supplied gap size is negative. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - AstFrame *frame; /* Pointer to Frame containing axis */ - double result; /* Result value to return */ - int naxes1; /* Number of axes in frame1 */ - int set; /* Digits attribute set? */ - -/* Initialise. */ - result = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate and permute the axis index supplied. */ - axis = astValidateAxis( this, axis, 1, "astGap" ); - -/* Determine the number of axes in the first component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - if ( astOK ) { - -/* Decide which component Frame contains the axis and adjust the axis - index if necessary. */ - frame = ( axis < naxes1 ) ? this->frame1 : this->frame2; - axis = ( axis < naxes1 ) ? axis : axis - naxes1; - -/* Since the component Frame is "managed" by the enclosing CmpFrame, - we next test if any Frame attributes which may affect the result - are undefined (i.e. have not been explicitly set). If so, we - over-ride them, giving them temporary values dictated by the - CmpFrame. Only the Digits attribute is relevant here. */ - set = astTestDigits( frame ); - if ( !set ) astSetDigits( frame, astGetDigits( this ) ); - -/* Invoke the Frame's astGap method to find the gap size. */ - result = astGap( frame, axis, gap, ntick ); - -/* Clear Frame attributes which were temporarily over-ridden. */ - if ( !set ) astClearDigits( frame ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied CmpFrame, -* in bytes. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the CmpFrame structure. */ - this = (AstCmpFrame *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astGetObjSize( this->frame1 ); - result += astGetObjSize( this->frame2 ); - result += astTSizeOf( this->perm ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetAlignSystem - -* Purpose: -* Obtain the AlignSystem attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetAlignSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the AlignSystem attribute for a CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The AlignSystem value. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If a AlignSystem attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestAlignSystem( this ) ) { - result = (*parent_getalignsystem)( this_frame, status ); - -/* Otherwise, provide a suitable default. */ - } else { - result = AST__COMP; - } - -/* Return the result. */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "CmpFrame.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astGetAttrib -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a CmpFrame, formatted as a character string. - -* Parameters: -* this -* Pointer to the CmpFrame. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - The returned string pointer may point at memory allocated -* within the CmpFrame, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the CmpFrame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - AstFrame *pfrm; /* Pointer to primary Frame containing axis */ - char buf1[80]; /* For for un-indexed attribute name */ - char buf2[80]; /* For for indexed attribute name */ - const char *result; /* Pointer value to return */ - int axis; /* Supplied (1-base) axis index */ - int len; /* Length of attrib string */ - int nc; /* Length of string used so far */ - int ok; /* Has the attribute been accessed succesfully? */ - int oldrep; /* Original error reporting state */ - int paxis; /* Index of primary Frame axis */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Indicate we have not yet acessed the attribute succesfully. */ - ok = 0; - -/* First check the supplied attribute name against each of the attribute - names defined by this class. In fact there is nothing to do here - since the CmpFrame class currently defines no extra attributes, but - this may change in the future. */ - if( 0 ) { - -/* If the attribute is not a CmpFrame specific attribute... */ - } else if( astOK ) { - -/* We want to allow easy access to the attributes of the component Frames. - That is, we do not want it to be necessary to extract a Frame from - its parent CmpFrame in order to access its attributes. For this reason - we first temporarily switch off error reporting so that if an attempt - to access the attribute fails, we can try a different approach. */ - oldrep = astReporting( 0 ); - -/* If the attribute is qualified by an axis index, try accessing it as an - attribute of the primary Frame containing the specified index. */ - if ( nc = 0, - ( 2 == astSscanf( attrib, "%[^(](%d)%n", buf1, &axis, &nc ) ) - && ( nc >= len ) ) { - -/* Find the primary Frame containing the specified axis. */ - astPrimaryFrame( this, axis - 1, &pfrm, &paxis ); - if( astOK ) { - -/* astPrimaryFrame returns the original - unpermuted - axis index within - the primary Frame. So we need to take into account any axis permutation - which has been applied to the primary Frame when forming the attribute name - to use below. Find the permuted (external) axis index which corresponds to - the internal (unpermuted) axis index "paxis". */ - paxis = astValidateAxis( pfrm, paxis, 0, "astGet" ); - -/* Create a new attribute with the same name but with the axis index - appropriate to the primary Frame. */ - sprintf( buf2, "%s(%d)", buf1, paxis + 1 ); - -/* Attempt to access the attribute. */ - result = astGetAttrib( pfrm, buf2 ); - -/* Indicate success. */ - if( astOK ) { - ok = 1; - -/* Otherwise clear the status value, and try again without any axis index. */ - } else { - astClearStatus; - result = astGetAttrib( pfrm, buf1 ); - -/* Indicate success, or clear the status value. */ - if( astOK ) { - ok = 1; - } else { - astClearStatus; - } - } - -/* Free the primary frame pointer. */ - pfrm = astAnnul( pfrm ); - } - -/* If the attribute is not qualified by an axis index, try accessing it - using the parent Frame method. */ - } else if( astOK ){ - result = (*parent_getattrib)( this_object, attrib, status ); - -/* Indicate success. */ - if( astOK ) { - ok = 1; - -/* Otherwise, clear the error condition so that we can try a different - approach. */ - } else { - astClearStatus; - -/* Next try accessing it using the primary Frame of each axis in turn. - Loop round all axes, until one is found which defines the specified - attribute. */ - for( axis = 0; axis < astGetNaxes( this ) && !ok; axis++ ) { - -/* Get the primary Frame containing this axis. */ - astPrimaryFrame( this, axis, &pfrm, &paxis ); - -/* Attempt to access the attribute as an attribute of the primary Frame. */ - result = astGetAttrib( pfrm, attrib ); - -/* Indicate success, or clear the status value. */ - if( astOK ) { - ok = 1; - } else { - astClearStatus; - } - -/* Free the primary Frame pointer. */ - pfrm = astAnnul( pfrm ); - - } - } - } - -/* Re-instate the original error reporting state. */ - astReporting( oldrep ); - - } - -/* Report an error if the attribute could not be accessed. */ - if( !ok && astOK ) { - astError( AST__BADAT, "astGet: The %s given does not have an attribute " - "called \"%s\".", status, astGetClass( this ), attrib ); - } - -/* Return the result. */ - return result; - -} - -static int GenAxisSelection( int naxes, int nselect, int axes[], int *status ) { -/* -* Name: -* GenAxisSelection - -* Purpose: -* Generate a sequence of axis selections. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int GenAxisSelection( int naxes, int nselect, int axes[], int *status ) - -* Class Membership: -* CmpFrame member function. - -* Description: -* This function generates a sequence of axis selections covering -* all possible ways of selecting a specified number of axes from a -* Frame. - -* Parameters: -* naxes -* The number of axes in the Frame. -* nselect -* The number of axes to be selected (between zero and "naxes"). -* axes -* An array with "nselect" elements. On entry it should contain -* the (zero-based) indices of the initial set of distinct axes -* to be selected, in increasing order (initiallly this should -* just be the sequence [0,1,...nselect-1]). On exit, these -* indices will be updated to identify the next possible axis -* selection. -* -* By invoking the function repeatedly, and passing this array -* each time, all possible selections will be covered. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a new axis selection has been returned. Zero if all -* possible selections have already been returned (in which case -* the selection returned this time is not valid and should not be -* used). - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - int i; /* Loop counter for axes */ - int iselect; /* Selection index */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Start with the first axis index and loop until the selection has - been updated. */ - iselect = 0; - while ( 1 ) { - -/* Increment the current axis index if it is the final one or it can - be incremented without equalling the one which follows (this ensures - the indices remain in increasing order). */ - if ( ( iselect == ( nselect - 1 ) ) || - ( axes[ iselect + 1 ] > ( axes[ iselect ] + 1 ) ) ) { - axes[ iselect ]++; - -/* After incrementing an index, reset all previous indices to their - starting values. */ - for ( i = 0; i < iselect; i++ ) axes[ i ] = i; - break; - -/* If this axis index can't be incremented, consider the next one. - Quit if we go beyond the end of the selection array. */ - } else if ( ++iselect >= nselect ) { - break; - } - } - -/* Return a result to indicate if we've reached the final selection - (when the final axis index goes out of range). */ - return ( nselect > 0 ) && ( axes[ nselect - 1 ] < naxes ); -} - -static AstAxis *GetAxis( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetAxis - -* Purpose: -* Obtain a pointer to a specified Axis from a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstAxis *GetAxis( AstFrame *this, int axis, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetAxis method -* inherited from the Frame class). - -* Description: -* This function returns a pointer to the Axis object associated -* with one of the axes of a CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* axis -* The number of the axis (zero-based) for which an Axis pointer -* is required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the requested Axis object. - -* Notes: -* - The reference count of the requested Axis object will be -* incremented by one to reflect the additional pointer returned by -* this function. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Vaiables: */ - AstAxis *result; /* Pointer value to return */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - int naxes1; /* Number of axes for frame1 */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate and permute the axis index supplied. */ - axis = astValidateAxis( this, axis, 1, "astGetAxis" ); - -/* Obtain the number of axes for frame1. */ - naxes1 = astGetNaxes( this->frame1 ); - -/* Decide which Frame the axis belongs to and obtain the required - Axis pointer. */ - if ( axis < naxes1 ) { - result = astGetAxis( this->frame1, axis ); - } else { - result = astGetAxis( this->frame2, axis - naxes1 ); - } - -/* Return the result. */ - return result; -} - -static const char *GetDomain( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetDomain - -* Purpose: -* Obtain a pointer to the Domain attribute string for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* const char *GetDomain( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetDomain protected -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the Domain attribute string -* for a CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a constant null-terminated string containing the -* Domain value. - -* Notes: -* - The returned pointer or the string it refers to may become -* invalid following further invocation of this function or -* modification of the CmpFrame. -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - char *dom1; /* Pointer to first sub domain */ - char *dom2; /* Pointer to second sub domain */ - const char *result; /* Pointer value to return */ - const char *t; /* Temporary pointer */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_frame); - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If a Domain attribute string has been set, invoke the parent method - to obtain a pointer to it. */ - if ( astTestDomain( this ) ) { - result = (*parent_getdomain)( this_frame, status ); - -/* Otherwise, provide a pointer to a suitable default string. */ - } else { - -/* Get the Domain value for the two component Frames and store new - copies of them. This is necessary because the component Frames may - themselves be CmpFrames, resulting in this function being called - recursively and so causing the static "getdomain_buff" array to be used in - multiple contexts. */ - t = astGetDomain( this->frame1 ); - dom1 = t ? astStore( NULL, t, strlen(t) + 1 ) : NULL; - t = astGetDomain( this->frame2 ); - dom2 = t ? astStore( NULL, t, strlen(t) + 1 ) : NULL; - - if( dom2 ) { - if( strlen( dom1 ) > 0 || strlen( dom2 ) > 0 ) { - sprintf( (char *) getdomain_buff, "%s-%s", dom1, dom2 ); - result = getdomain_buff; - } else { - result = "CMP"; - } - } - - dom1 = astFree( dom1 ); - dom2 = astFree( dom2 ); - } - -/* Return the result. */ - return result; -} - -static int GetMaxAxes( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetMaxAxes - -* Purpose: -* Get a value for the MaxAxes attribute of a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int GetMaxAxes( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetMaxAxes method -* inherited from the Frame class). - -* Description: -* This function returns a value for the MaxAxes attribute of a -* CmpFrame. A large default value is supplied that is much larger -* than the maximum likely number of axes in a Frame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The MaxAxes attribute value. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If a value has been set explicitly for the CmpFrame, return it. - Otherwise returned a large default value. */ - if( astTestMaxAxes( this ) ) { - result = (*parent_getmaxaxes)( this_frame, status ); - } else { - result = 1000000; - } - -/* Return the result. */ - return result; -} - -static int GetMinAxes( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetMinAxes - -* Purpose: -* Get a value for the MinAxes attribute of a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int GetMinAxes( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetMinAxes method -* inherited from the Frame class). - -* Description: -* This function returns a value for the MinAxes attribute of a -* CmpFrame. A default value of zero is used. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The MinAxes attribute value. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If a value has been set explicitly for the CmpFrame, return it. - Otherwise returned a default value of zero. */ - if( astTestMinAxes( this ) ) { - result = (*parent_getminaxes)( this_frame, status ); - } else { - result = 0; - } - -/* Return the result. */ - return result; -} - -static double GetDtai( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetDtai - -* Purpose: -* Get a value for the Dtai attribute of a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double GetDtai( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetDtai method -* inherited from the Frame class). - -* Description: -* This function returns a value for the Dtai attribute of a -* CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Dtai attribute value. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - double result; /* Result value to return */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If an Dtai attribute value has been set, invoke the parent method - to obtain it. */ - if ( astTestDtai( this ) ) { - result = (*parent_getdtai)( this_frame, status ); - -/* Otherwise, if the Dtai value is set in the first component Frame, - return it. */ - } else if( astTestDtai( this->frame1 ) ){ - result = astGetDtai( this->frame1 ); - -/* Otherwise, if the Dtai value is set in the second component Frame, - return it. */ - } else if( astTestDtai( this->frame2 ) ){ - result = astGetDtai( this->frame2 ); - -/* Otherwise, return the default Dtai value from the first component - Frame. */ - } else { - result = astGetDtai( this->frame1 ); - } - -/* Return the result. */ - return result; -} - -static double GetDut1( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetDut1 - -* Purpose: -* Get a value for the Dut1 attribute of a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double GetDut1( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetDut1 method -* inherited from the Frame class). - -* Description: -* This function returns a value for the Dut1 attribute of a -* CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Dut1 attribute value. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - double result; /* Result value to return */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If an Dut1 attribute value has been set, invoke the parent method - to obtain it. */ - if ( astTestDut1( this ) ) { - result = (*parent_getdut1)( this_frame, status ); - -/* Otherwise, if the Dut1 value is set in the first component Frame, - return it. */ - } else if( astTestDut1( this->frame1 ) ){ - result = astGetDut1( this->frame1 ); - -/* Otherwise, if the Dut1 value is set in the second component Frame, - return it. */ - } else if( astTestDut1( this->frame2 ) ){ - result = astGetDut1( this->frame2 ); - -/* Otherwise, return the default Dut1 value from the first component - Frame. */ - } else { - result = astGetDut1( this->frame1 ); - } - -/* Return the result. */ - return result; -} - -static double GetEpoch( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetEpoch - -* Purpose: -* Get a value for the Epoch attribute of a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double GetEpoch( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetEpoch method -* inherited from the Frame class). - -* Description: -* This function returns a value for the Epoch attribute of a -* CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Epoch attribute value. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - double result; /* Result value to return */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If an Epoch attribute value has been set, invoke the parent method - to obtain it. */ - if ( astTestEpoch( this ) ) { - result = (*parent_getepoch)( this_frame, status ); - -/* Otherwise, if the Epoch value is set in the first component Frame, - return it. */ - } else if( astTestEpoch( this->frame1 ) ){ - result = astGetEpoch( this->frame1 ); - -/* Otherwise, if the Epoch value is set in the second component Frame, - return it. */ - } else if( astTestEpoch( this->frame2 ) ){ - result = astGetEpoch( this->frame2 ); - -/* Otherwise, return the default Epoch value from the first component - Frame. */ - } else { - result = astGetEpoch( this->frame1 ); - } - -/* Return the result. */ - return result; -} - -static double GetObsAlt( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetObsAlt - -* Purpose: -* Get a value for the ObsAlt attribute of a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double GetObsAlt( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetObsAlt method -* inherited from the Frame class). - -* Description: -* This function returns a value for the ObsAlt attribute of a -* CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The ObsAlt attribute value. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - double result; /* Result value to return */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If an ObsAlt attribute value has been set, invoke the parent method - to obtain it. */ - if ( astTestObsAlt( this ) ) { - result = (*parent_getobsalt)( this_frame, status ); - -/* Otherwise, if the ObsAlt value is set in the first component Frame, - return it. */ - } else if( astTestObsAlt( this->frame1 ) ){ - result = astGetObsAlt( this->frame1 ); - -/* Otherwise, if the ObsAlt value is set in the second component Frame, - return it. */ - } else if( astTestObsAlt( this->frame2 ) ){ - result = astGetObsAlt( this->frame2 ); - -/* Otherwise, return the default ObsAlt value from the first component - Frame. */ - } else { - result = astGetObsAlt( this->frame1 ); - } - -/* Return the result. */ - return result; -} - -static double GetObsLat( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetObsLat - -* Purpose: -* Get a value for the ObsLat attribute of a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double GetObsLat( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetObsLat method -* inherited from the Frame class). - -* Description: -* This function returns a value for the ObsLat attribute of a -* CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The ObsLat attribute value. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - double result; /* Result value to return */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If an ObsLat attribute value has been set, invoke the parent method - to obtain it. */ - if ( astTestObsLat( this ) ) { - result = (*parent_getobslat)( this_frame, status ); - -/* Otherwise, if the ObsLat value is set in the first component Frame, - return it. */ - } else if( astTestObsLat( this->frame1 ) ){ - result = astGetObsLat( this->frame1 ); - -/* Otherwise, if the ObsLat value is set in the second component Frame, - return it. */ - } else if( astTestObsLat( this->frame2 ) ){ - result = astGetObsLat( this->frame2 ); - -/* Otherwise, return the default ObsLat value from the first component - Frame. */ - } else { - result = astGetObsLat( this->frame1 ); - } - -/* Return the result. */ - return result; -} - -static double GetObsLon( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetObsLon - -* Purpose: -* Get a value for the ObsLon attribute of a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* double GetObsLon( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetObsLon method -* inherited from the Frame class). - -* Description: -* This function returns a value for the ObsLon attribute of a -* CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The ObsLon attribute value. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - double result; /* Result value to return */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If an ObsLon attribute value has been set, invoke the parent method - to obtain it. */ - if ( astTestObsLon( this ) ) { - result = (*parent_getobslon)( this_frame, status ); - -/* Otherwise, if the ObsLon value is set in the first component Frame, - return it. */ - } else if( astTestObsLon( this->frame1 ) ){ - result = astGetObsLon( this->frame1 ); - -/* Otherwise, if the ObsLon value is set in the second component Frame, - return it. */ - } else if( astTestObsLon( this->frame2 ) ){ - result = astGetObsLon( this->frame2 ); - -/* Otherwise, return the default ObsLon value from the first component - Frame. */ - } else { - result = astGetObsLon( this->frame1 ); - } - -/* Return the result. */ - return result; -} - -static int GetNaxes( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetNaxes - -* Purpose: -* Determine how many axes a CmpFrame has. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int GetNaxes( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetNaxes method -* inherited from the Frame class). - -* Description: -* This function returns the number of axes for a CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of CmpFrame axes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - int naxes1; /* Number of axes for frame1 */ - int naxes2; /* Number of axes for frame2 */ - int result; /* Number of CmpFrame axes */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Obtain the number of axes for each component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - naxes2 = astGetNaxes( this->frame2 ); - -/* If OK, calculate the total number of axes. */ - if ( astOK ) result = naxes1 + naxes2; - -/* Return the result. */ - return result; -} - -static const int *GetPerm( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetPerm - -* Purpose: -* Access the axis permutation array for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* const int *astGetPerm( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astGetPerm -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the axis permutation array -* for a CmpFrame. This array constitutes a lookup-table that -* converts between an axis number supplied externally and the -* corresponding index in the CmpFrame's internal data. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the CmpFrame's axis permutation array (a constant -* array of int). Each element of this contains the (zero-based) -* internal axis index to be used in place of the external index -* which is used to address the permutation array. If the CmpFrame -* has zero axes, this pointer will be NULL. - -* Notes: -* - This protected method is provided to assist class -* implementations which need to implement axis-dependent -* extensions to CmpFrame methods, and which therefore need to know -* how a CmpFrames's external axis index is converted for internal -* use. -* - The pointer returned by this function gives direct access to -* data internal to the CmpFrame object. It remains valid only so -* long as the CmpFrame exists. The permutation array contents may -* be modified by other functions which operate on the CmpFrame and -* this may render the returned pointer invalid. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. - -* Implementation Notes: -* - This function performs essentially the same operation as the -* Frame member function which it over-rides. However, it returns a -* pointer to the "perm" array held in the CmpFrame structure -* (rather than the one in the parent Frame structure). This -* duplication of the array is necessary because the one in the -* Frame structure is of zero length, the number of axes in the -* Frame structure having been set to zero to prevent unnecessary -* allocation of Axis objects which are not needed by the CmpFrame. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Return a pointer to the axis permutation array. */ - return this->perm; -} - -static AstSystemType GetSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetSystem - -* Purpose: -* Obtain the System attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstSystemType GetSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the System attribute for a CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System value. - -* Notes: -* - AST__BADSYSTEM is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If a System attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestSystem( this ) ) { - result = (*parent_getsystem)( this_frame, status ); - -/* Otherwise, provide a suitable default. */ - } else { - result = AST__COMP; - } - -/* Return the result. */ - return result; -} - -static const char *GetTitle( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetTitle - -* Purpose: -* Obtain a pointer to the Title attribute string for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* const char *GetTitle( AstFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetTitle protected -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the Title attribute string for -* a CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a constant null-terminated string containing the -* Title value. - -* Notes: -* - The returned pointer or the string it refers to may become -* invalid following further invocation of this function or -* modification of the CmpFrame. -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_frame); - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* If a Title attribute string has been set, invoke the parent method - to obtain a pointer to it. */ - if ( astTestTitle( this ) ) { - result = (*parent_gettitle)( this_frame, status ); - -/* Otherwise, create a suitable default string and return a pointer to - this. */ - } else { - (void) sprintf( gettitle_buff, "%d-d compound coordinate system", - astGetNaxes( this ) ); - if ( astOK ) result = gettitle_buff; - } - -/* Return the result. */ - return result; - -} - -static int GetUseDefs( AstObject *this_object, int *status ) { -/* -* Name: -* GetUseDefs - -* Purpose: -* Get a value for the UseDefs attribute of a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int GetUseDefs( AstCmpFrame *this, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetUseDefs method -* inherited from the Frame class). - -* Description: -* This function returns a value for the UseDefs attribute of a -* CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The UseDefs attribute value. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_object; - -/* If an UseDefs attribute value has been set, invoke the parent method - to obtain it. */ - if ( astTestUseDefs( this ) ) { - result = (*parent_getusedefs)( this_object, status ); - -/* Otherwise, use the UseDefs value in the first component Frame as the - default. */ - } else { - result = (*parent_getusedefs)( (AstObject *) this->frame1, status ); - } - -/* Return the result. */ - return result; -} - -static int GoodPerm( int ncoord_in, const int inperm[], - int ncoord_out, const int outperm[], int *status ) { -/* -* Name: -* GoodPerm - -* Purpose: -* Test if a PermMap will be non-null. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int GoodPerm( int ncoord_in, const int inperm[], -* int ncoord_out, const int outperm[], int *status ) - -* Class Membership: -* CmpFrame member function. - -* Description: -* This function tests if a pair of permutation arrays will, when -* used to create a PermMap, result in a PermMap which has a -* non-null effect (i.e. one which is not simply equivalent to a -* unit Mapping). - -* Parameters: -* ncoord_in -* The number of input coordinates for the PermMap. -* inperm -* The input permutation array for the PermMap (with "ncoord_in" -* elements). -* ncoord_out -* The number of output coordinates for the PermMap. -* outperm -* The output permutation array for the PermMap (with -* "ncoord_out" elements). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the PermMap would be equivalent to a unit Mapping, -* otherwise one. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - int axis; /* Loop counter for axes */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* First test if the number of input and output coordinates are - different. */ - result = ( ncoord_in != ncoord_out ); - -/* If they are not, examine the contents of the "inperm" array. */ - if ( !result ) { - for ( axis = 0; axis < ncoord_in; axis++ ) { - -/* We have a non-null Mapping if any element of this array selects an - output axis with a different index to the input axis (or selects an - invalid axis or a constant). */ - if ( inperm[ axis ] != axis ) { - result = 1; - break; - } - } - } - -/* If the Mapping still appears to be null, also examine the "outperm" - array in the same way. */ - if ( !result ) { - for ( axis = 0; axis < ncoord_out; axis++ ) { - if ( outperm[ axis ] != axis ) { - result = 1; - break; - } - } - } - -/* Return the result. */ - return result; -} - -void astInitCmpFrameVtab_( AstCmpFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitCmpFrameVtab - -* Purpose: -* Initialise a virtual function table for a CmpFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpframe.h" -* void astInitCmpFrameVtab( AstCmpFrameVtab *vtab, const char *name ) - -* Class Membership: -* CmpFrame vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the CmpFrame class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameVtab( (AstFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsACmpFrame) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - frame = (AstFrameVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - mapping = (AstMappingVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_getusedefs = object->GetUseDefs; - object->GetUseDefs = GetUseDefs; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - mapping->RemoveRegions = RemoveRegions; - mapping->Simplify = Simplify; - mapping->Transform = Transform; - - parent_getdomain = frame->GetDomain; - frame->GetDomain = GetDomain; - - parent_gettitle = frame->GetTitle; - frame->GetTitle = GetTitle; - - parent_getepoch = frame->GetEpoch; - frame->GetEpoch = GetEpoch; - - parent_setepoch = frame->SetEpoch; - frame->SetEpoch = SetEpoch; - - parent_clearepoch = frame->ClearEpoch; - frame->ClearEpoch = ClearEpoch; - - parent_getdtai = frame->GetDtai; - frame->GetDtai = GetDtai; - - parent_setdtai = frame->SetDtai; - frame->SetDtai = SetDtai; - - parent_cleardtai = frame->ClearDtai; - frame->ClearDtai = ClearDtai; - - parent_getdut1 = frame->GetDut1; - frame->GetDut1 = GetDut1; - - parent_setdut1 = frame->SetDut1; - frame->SetDut1 = SetDut1; - - parent_cleardut1 = frame->ClearDut1; - frame->ClearDut1 = ClearDut1; - - parent_getobslon = frame->GetObsLon; - frame->GetObsLon = GetObsLon; - - parent_setobslon = frame->SetObsLon; - frame->SetObsLon = SetObsLon; - - parent_clearobslon = frame->ClearObsLon; - frame->ClearObsLon = ClearObsLon; - - parent_getobslat = frame->GetObsLat; - frame->GetObsLat = GetObsLat; - - parent_setobslat = frame->SetObsLat; - frame->SetObsLat = SetObsLat; - - parent_clearobslat = frame->ClearObsLat; - frame->ClearObsLat = ClearObsLat; - - parent_getobsalt = frame->GetObsAlt; - frame->GetObsAlt = GetObsAlt; - - parent_setobsalt = frame->SetObsAlt; - frame->SetObsAlt = SetObsAlt; - - parent_clearobsalt = frame->ClearObsAlt; - frame->ClearObsAlt = ClearObsAlt; - - parent_angle = frame->Angle; - frame->Angle = Angle; - - parent_getsystem = frame->GetSystem; - frame->GetSystem = GetSystem; - - parent_getalignsystem = frame->GetAlignSystem; - frame->GetAlignSystem = GetAlignSystem; - - parent_clearalignsystem = frame->ClearAlignSystem; - frame->ClearAlignSystem = ClearAlignSystem; - - parent_overlay = frame->Overlay; - frame->Overlay = Overlay; - - parent_setactiveunit = frame->SetActiveUnit; - frame->SetActiveUnit = SetActiveUnit; - - parent_getactiveunit = frame->GetActiveUnit; - frame->GetActiveUnit = GetActiveUnit; - - parent_setframeflags = frame->SetFrameFlags; - frame->SetFrameFlags = SetFrameFlags; - - parent_getmaxaxes = frame->GetMaxAxes; - frame->GetMaxAxes = GetMaxAxes; - - parent_getminaxes = frame->GetMinAxes; - frame->GetMinAxes = GetMinAxes; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Cast = Cast; - mapping->Decompose = Decompose; - frame->Abbrev = Abbrev; - frame->ClearDirection = ClearDirection; - frame->ClearFormat = ClearFormat; - frame->ClearLabel = ClearLabel; - frame->ClearSymbol = ClearSymbol; - frame->ClearUnit = ClearUnit; - frame->Distance = Distance; - frame->Fields = Fields; - frame->Format = Format; - frame->FrameGrid = FrameGrid; - frame->Centre = Centre; - frame->Gap = Gap; - frame->GetAxis = GetAxis; - frame->GetDirection = GetDirection; - frame->GetFormat = GetFormat; - frame->GetLabel = GetLabel; - frame->GetNaxes = GetNaxes; - frame->GetPerm = GetPerm; - frame->GetSymbol = GetSymbol; - frame->GetUnit = GetUnit; - frame->IsUnitFrame = IsUnitFrame; - frame->Match = Match; - frame->Norm = Norm; - frame->NormBox = NormBox; - frame->Offset = Offset; - frame->PermAxes = PermAxes; - frame->PrimaryFrame = PrimaryFrame; - frame->Resolve = Resolve; - frame->ResolvePoints = ResolvePoints; - frame->SetAxis = SetAxis; - frame->SetDirection = SetDirection; - frame->SetFormat = SetFormat; - frame->SetLabel = SetLabel; - frame->SetSymbol = SetSymbol; - frame->SetUnit = SetUnit; - frame->SubFrame = SubFrame; - frame->TestDirection = TestDirection; - frame->TestFormat = TestFormat; - frame->TestLabel = TestLabel; - frame->TestSymbol = TestSymbol; - frame->TestUnit = TestUnit; - frame->Unformat = Unformat; - frame->ValidateSystem = ValidateSystem; - frame->SystemString = SystemString; - frame->SystemCode = SystemCode; - frame->MatchAxesX = MatchAxesX; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "CmpFrame", - "Compound coordinate system description" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int IsUnitFrame( AstFrame *this_frame, int *status ){ -/* -* Name: -* IsUnitFrame - -* Purpose: -* Is this Frame equivalent to a UnitMap? - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int IsUnitFrame( AstFrame *this, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astIsUnitFrame -* method inherited from the Frame class). - -* Description: -* This function returns a flag indicating if the supplied Frame is -* equivalent to a UnitMap when treated as a Mapping (note, the Frame -* class inherits from Mapping and therefore every Frame is also a Mapping). - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the supplied Frame is equivalent to -* a UnitMap when treated as a Mapping. - -*- -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Return the result. */ - return astIsUnitFrame( this->frame1 ) && astIsUnitFrame( this->frame2 ); -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the CmpFrame structure. */ - this = (AstCmpFrame *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->frame1, mode, extra, fail ); - if( !result ) result = astManageLock( this->frame2, mode, extra, fail ); - - return result; - -} -#endif - -static int Match( AstFrame *template_frame, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, - AstMapping **map, AstFrame **result, int *status ) { -/* -* Name: -* Match - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astMatch -* method inherited from the Frame class). - -* Description: -* This function matches a "template" CmpFrame to a "target" Frame -* and determines whether it is possible to convert coordinates -* between them. If it is, a Mapping that performs the -* transformation is returned along with a new Frame that describes -* the coordinate system that results when this Mapping is applied -* to the "target" coordinate system. In addition, information is -* returned to allow the axes in this "result" Frame to be -* associated with the corresponding axes in the "target" Frame and -* "template" CmpFrame from which they are derived. - -* Parameters: -* template -* Pointer to the template CmpFrame. This describes the -* coordinate system (or set of possible coordinate systems) -* into which we wish to convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate -* system in which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case (i.e. if the -* target is of a more specialised class than the template). In -* this latter case, the target is cast down to the class of the -* template. NOTE, this argument is handled by the global method -* wrapper function "astMatch_", rather than by the class-specific -* implementations of this method. -* template_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* template CmpFrame axis from which it is derived. If it is not -* derived from any template axis, a value of -1 will be -* returned instead. -* target_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* target Frame axis from which it is derived. If it is not -* derived from any target axis, a value of -1 will be returned -* instead. -* map -* Address of a location where a pointer to a new Mapping will -* be returned if the requested coordinate conversion is -* possible. If returned, the forward transformation of this -* Mapping may be used to convert coordinates between the -* "target" Frame and the "result" Frame (see below) and the -* inverse transformation will convert in the opposite -* direction. -* result -* Address of a location where a pointer to a new Frame will be -* returned if the requested coordinate conversion is -* possible. If returned, this Frame describes the coordinate -* system that results from applying the returned Mapping -* (above) to the "target" coordinate system. In general, this -* Frame will combine attributes from (and will therefore be -* more specific than) both the target Frame and the template -* CmpFrame. In particular, when the template allows the -* possibility of transformaing to any one of a set of -* alternative coordinate systems, the "result" Frame will -* indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate -* conversion is possible. Otherwise zero is returned (this will -* not in itself result in an error condition). - -* Notes: -* - By default, the "result" Frame will have its number of axes -* and axis order determined by the "template" CmpFrame. However, -* if the PreserveAxes attribute of the template CmpFrame is -* non-zero, then the axis count and axis order of the "target" -* Frame will be used instead. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *template; /* Pointer to template CmpFrame structure */ - char *template_domain; /* Pointer to copy of template domain */ - const char *ptr; /* Pointer to domain string */ - const char *target_domain; /* Pointer to target domain string */ - int *axes1; /* Pointer to axis selection 1 */ - int *axes2; /* Pointer to axis selection 2 */ - int *used; /* Pointer to flags array */ - int axis2; /* Index for axis selection 2 */ - int axis; /* Index for axis arrays */ - int last_target; /* Last target axis association */ - int last_template; /* Last template axis associateion */ - int match; /* Match obtained (returned result)? */ - int maxax1; /* MaxAxes attribute for component 1 */ - int maxax2; /* MaxAxes attribute for component 2 */ - int maxax; /* Max axes that can be matched by template */ - int minax1; /* MinAxes attribute for component 1 */ - int minax2; /* MinAxes attribute for component 2 */ - int minax; /* Min axes that can be matched by template */ - int naxes1; /* Number of axes assigned to component 1 */ - int naxes2; /* Number of axes assigned to component 2 */ - int naxes; /* Total number of target axes */ - int naxes_max1; /* First estimate of naxes_max */ - int naxes_max2; /* Second estimate of naxes_max */ - int naxes_max; /* Max number of axes to match component 1 */ - int naxes_min1; /* First estimate of naxes_min */ - int naxes_min2; /* Second estimate of naxes_min */ - int naxes_min; /* Min number of axes to match component 1 */ - int permute; /* Permute attribute for template */ - int result_naxes; /* Number of result Frame axes */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the template CmpFrame structure. */ - template = (AstCmpFrame *) template_frame; - -/* Further initialisation to avoid compiler warnings. */ - naxes_min = 0; - naxes_max = 0; - -/* Obtain the maximum number of axes that the template CmpFrame, and each - component Frame of the template CmpFrame, can match. If the MaxAxes - attribute is set for the template, use it and assume that each - component Frame can match any number of axes. */ - if( astTestMaxAxes( template ) ) { - maxax = astGetMaxAxes( template ); - maxax1 = 100000; - maxax2 = 100000; - } else { - maxax1 = astGetMaxAxes( template->frame1 ); - maxax2 = astGetMaxAxes( template->frame2 ); - maxax = maxax1 + maxax2; - } - -/* Do the same for the minimum number of axes that can be matched by the - template CmpFrame. */ - if( astTestMinAxes( template ) ) { - minax = astGetMinAxes( template ); - minax1 = 1; - minax2 = 1; - } else { - minax1 = astGetMinAxes( template->frame1 ); - minax2 = astGetMinAxes( template->frame2 ); - minax = minax1 + minax2; - } - -/* Obtain the number of axes in the target Frame and test to see if it - is possible for the template to match it on the basis of axis - counts. */ - naxes = astGetNaxes( target ); - match = ( naxes >= minax && naxes <= maxax ); - -/* The next requirement is that all the frames have some axes. */ - if( naxes == 0 || maxax1 == 0 || maxax2 == 0 ) match = 0; - -/* The next requirement is that if the template CmpFrame has its - Domain attribute defined, then the target Frame must also have the - same Domain (although it need not be set - the default will - do). First check if the template has a domain. */ - if ( astOK && match ) { - if ( astTestDomain( template ) ) { - -/* Obtain a pointer to the template domain. Then allocate memory and - make a copy of it (this is necessary as we will next inquire the - domain of the target and may over-write the buffer holding the - template's domain). */ - ptr = astGetDomain( template ); - if ( astOK ) { - template_domain = astStore( NULL, ptr, - strlen( ptr ) + (size_t) 1 ); - -/* Obtain a pointer to the target domain. */ - target_domain = astGetDomain( target ); - -/* Compare the domain strings for equality. Then free the memory - allocated above. */ - match = astOK && !strcmp( template_domain, target_domain ); - template_domain = astFree( template_domain ); - } - } - } - -/* If a match still appears possible, determine the minimum number of - target axes that will have to match the first component Frame of - the template CmpFrame. */ - if ( astOK && match ) { - naxes_min1 = minax1; - naxes_min2 = naxes - maxax2; - naxes_min = ( naxes_min1 > naxes_min2 ) ? naxes_min1 : naxes_min2; - -/* Also determine the maximum number of target axes that may match - this component of the template. */ - naxes_max1 = maxax1; - naxes_max2 = naxes - minax2; - naxes_max = ( naxes_max1 < naxes_max2 ) ? naxes_max1 : naxes_max2; - -/* No match possible if the number of axes are inconsistent. */ - if( naxes_min > naxes_max ) match = 0; - } - -/* If a match is still possible, allocate workspace. */ - if( match ) { - axes1 = astMalloc( sizeof( int ) * (size_t) naxes ); - axes2 = astMalloc( sizeof( int ) * (size_t) naxes ); - used = astMalloc( sizeof( int ) * (size_t) naxes ); - -/* Obtain the value of the template's Permute attribute. */ - permute = astGetPermute( template ); - if ( astOK ) { - -/* Loop to consider all possible choices of the number of template - axes that might match the first component Frame of the template, - and derive the corresponding number of axes that must match the - second component at the same time. */ - for ( naxes1 = naxes_max; naxes1 >= naxes_min; naxes1-- ) { - naxes2 = naxes - naxes1; - -/* Initialise the selection of target axes that we will attempt to - match against the first template component (to [0,1,2,...]). */ - for ( axis = 0; axis < naxes1; axis++ ) axes1[ axis ] = axis; - -/* Loop to consider all possible selections with this number of axes, - until a match is found. */ - while ( 1 ) { - -/* Initialise an array of flags to zero for each target axis. Then set - the flag to 1 for each axis which is in the first selection.*/ - for ( axis = 0; axis < naxes; axis++ ) used[ axis ] = 0; - for( axis = 0; axis < naxes1; axis++ ) { - used[ axes1[ axis ] ] = 1; - } - -/* Generate the second selection by including all target axes that are - not in the first selection. */ - axis2 = 0; - for ( axis = 0; axis < naxes; axis++ ) { - if ( !used[ axis ] ) axes2[ axis2++ ] = axis; - } - -/* Attempt to match the target axes partitioned in this way to the two - template components. */ - match = PartMatch( template, target, matchsub, - naxes1, axes1, naxes2, axes2, - template_axes, target_axes, map, result, status ); - -/* If a match was obtained but the template's Permute attribute is zero, - then we must check to see if the match involves permuting the target - axes. */ - if ( astOK && match && !permute ) { - -/* Obtain the number of result Frame axes. */ - result_naxes = astGetNaxes( *result ); - -/* Loop to check the target and template axis associations for all the - result Frame axes. The match will only be accepted if both of these - are monotonically increasing (indicating no axis permutation) after - allowing for any absent associations . */ - last_template = -1; - last_target = -1; - for ( axis = 0; axis < result_naxes; axis++ ) { - -/* Check the template axis association against the previous value, - omitting any axes witout valid associations. */ - if ( ( *template_axes )[ axis ] != -1 ) { - if ( ( *template_axes )[ axis ] <= last_template ) { - match = 0; - break; - -/* Update the previous association value. */ - } else { - last_template = ( *template_axes )[ axis ]; - } - } - -/* Repeat this process for the target axis associations. */ - if ( ( *target_axes )[ axis ] != -1 ) { - if ( ( *target_axes )[ axis ] <= last_target ) { - match = 0; - break; - } else { - last_target = ( *target_axes )[ axis ]; - } - } - } - -/* If the match was rejected because it involves an axis permutation, - then free the allocated memory and annul the Object pointers - associated with the match. */ - if ( !match ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - *map = astAnnul( *map ); - *result = astAnnul( *result ); - } - } - -/* If an error occurred or a match was found, quit searching, - otherwise generate the next axis selection and try that - instead. Quit if there are no more selections to try. */ - if ( !astOK || match || - !GenAxisSelection( naxes, naxes1, axes1, status ) ) break; - } - -/* Quit the outer loop if an error occurs or a match is found. */ - if ( !astOK || match ) break; - } - } - -/* Free the workspace arrays. */ - axes1 = astFree( axes1 ); - axes2 = astFree( axes2 ); - used = astFree( used ); - } - -/* If the target did not match the supplied template CmpFrame, see if it - will match either of the component Frames. First try matching it against - the first component Frame. */ - if( !match ) match = ComponentMatch( template, target, matchsub, 0, - template_axes, target_axes, map, result, - status ); - -/* If we still dont have a mcth, try matching it against the second - component Frame. */ - if( !match ) match = ComponentMatch( template, target, matchsub, 1, - template_axes, target_axes, map, - result, status ); - -/* If an error occurred, free all allocated memory, annul the result - Object pointers and clear all returned values. */ - if ( !astOK ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - *map = astAnnul( *map ); - *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static void MatchAxesX( AstFrame *frm2_frame, AstFrame *frm1, int *axes, - int *status ) { -/* -* Name: -* MatchAxesX - -* Purpose: -* Find any corresponding axes in two Frames. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void MatchAxesX( AstFrame *frm2, AstFrame *frm1, int *axes ) -* int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astMatchAxesX -* method inherited from the Frame class). - -* Description: -* This function looks for corresponding axes within two supplied -* Frames. An array of integers is returned that contains an element -* for each axis in the second supplied Frame. An element in this array -* will be set to zero if the associated axis within the second Frame -* has no corresponding axis within the first Frame. Otherwise, it -* will be set to the index (a non-zero positive integer) of the -* corresponding axis within the first supplied Frame. - -* Parameters: -* frm2 -* Pointer to the second Frame. -* frm1 -* Pointer to the first Frame. -* axes -* Pointer to an integer array in which to return the indices of -* the axes (within the first Frame) that correspond to each axis -* within the second Frame. Axis indices start at 1. A value of zero -* will be stored in the returned array for each axis in the second -* Frame that has no corresponding axis in the first Frame. -* -* The number of elements in this array must be greater than or -* equal to the number of axes in the second Frame. -* status -* Pointer to inherited status value. - -* Notes: -* - Corresponding axes are identified by the fact that a Mapping -* can be found between them using astFindFrame or astConvert. Thus, -* "corresponding axes" are not necessarily identical. For instance, -* SkyFrame axes in two Frames will match even if they describe -* different celestial coordinate systems -*/ - -/* Local Variables: */ - AstCmpFrame *frm2; - const int *perm; - int *work; - int i; - int nax2; - int nax1; - int nax; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the CmpFrame. */ - frm2 = (AstCmpFrame *) frm2_frame; - -/* Get the number of axes in the two component Frames, and the total - number of axes in the CmpFrame. */ - nax2 = astGetNaxes( frm2->frame1 ); - nax1 = astGetNaxes( frm2->frame2 ); - nax = nax2 + nax1; - -/* Allocate a work array to hold the unpermuted axis indices */ - work = astMalloc( sizeof( int )*nax ); - if( astOK ) { - -/* Use the astMatchAxes method to match axes in the first component Frame - within CmpFrame "frm2". Write the associated axis indices into the first - part of the work array. */ - astMatchAxes( frm1, frm2->frame1, work ); - -/* Use the MatchAxes method to match axes in the second component - Frame. Write the associated axis indices into the work array - following the end of the values already in there. */ - astMatchAxes( frm1, frm2->frame2, work + nax2 ); - -/* Obtain a pointer to the CmpFrame's axis permutation array. The index - into "perm" represents the external axis index, and the value held in - each element of "perm" represents the corresponding internal axis index. */ - perm = astGetPerm( frm2 ); - if( astOK ) { - -/* Copy the frm2 axis indices from the work array into the returned "axes" - array, permuting their order into the external axis order of the - CmpFrame. */ - for( i = 0; i < nax; i++ ) axes[ i ] = work[ perm[ i ] ]; - } - -/* Free resources */ - work = astFree( work ); - } -} - -static void Norm( AstFrame *this_frame, double value[], int *status ) { -/* -* Name: -* Norm - -* Purpose: -* Normalise a set of CmpFrame coordinates. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void Norm( AstAxis *this, double value[], int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astNorm method -* inherited from the Frame class). - -* Description: -* This function converts a set of CmpFrame coordinate values, -* which might potentially be unsuitable for display to a user (for -* instance, may lie outside the expected range of values) into a -* set of acceptable alternative values suitable for display. - -* Parameters: -* this -* Pointer to the CmpFrame. -* value -* An array of double, with one element for each CmpFrame axis. -* This should contain the initial set of coordinate values, -* which will be modified in place. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - const int *perm; /* Axis permutation array */ - double *v; /* Pointer to permuted coordinates */ - int axis; /* Loop counter for axes */ - int naxes1; /* Number of axes in frame1 */ - int naxes; /* Number of axes in CmpFrame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Obtain a pointer to the CmpFrame's axis permutation array. */ - perm = astGetPerm( this ); - -/* Obtain the number of axes in the CmpFrame and in the first - component Frame. */ - naxes = astGetNaxes( this ); - naxes1 = astGetNaxes( this->frame1 ); - -/* Allocate memory to hold the permuted coordinates. */ - v = astMalloc( sizeof( double ) * (size_t) naxes ); - if ( astOK ) { - -/* Permute the coordinates using the CmpFrame's axis permutation array - to put them into the order required internally (i.e. by the two - component Frames). */ - for ( axis = 0; axis < naxes; axis++ ) v[ perm[ axis ] ] = value[ axis ]; - -/* Invoke the astNorm method of both component Frames, passing the - relevant (permuted) coordinate values for normalisation. */ - astNorm( this->frame1, v ); - astNorm( this->frame2, v + naxes1 ); - -/* Copy the normalised values back into the original coordinate array, - un-permuting them in the process. */ - for ( axis = 0; axis < naxes; axis++ ) value[ axis ] = v[ perm[ axis ] ]; - } - -/* Free the memory used for the permuted coordinates. */ - v = astFree( v ); -} - -static void NormBox( AstFrame *this_frame, double lbnd[], double ubnd[], - AstMapping *reg, int *status ) { -/* -* Name: -* NormBox - -* Purpose: -* Extend a box to include effect of any singularities in the Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void astNormBox( AstFrame *this, double lbnd[], double ubnd[], -* AstMapping *reg, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astNormBox method inherited -* from the Frame class). - -* Description: -* This function modifies a supplied box to include the effect of any -* singularities in the co-ordinate system represented by the Frame. -* For a normal Cartesian coordinate system, the box will be returned -* unchanged. Other classes of Frame may do other things. For instance, -* a SkyFrame will check to see if the box contains either the north -* or south pole and extend the box appropriately. - -* Parameters: -* this -* Pointer to the Frame. -* lbnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* lower axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* ubnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* upper axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* reg -* A Mapping which should be used to test if any singular points are -* inside or outside the box. The Mapping should leave an input -* position unchanged if the point is inside the box, and should -* set all bad if the point is outside the box. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstCmpFrame *this; - AstCmpMap *m1; - AstCmpMap *m2; - AstCmpMap *m3; - AstCmpMap *m4; - AstCmpMap *m5; - AstCmpMap *m6; - AstPermMap *pm1; - AstPermMap *pm2; - AstPermMap *pm3; - const int *perm; - double *vl; - double *vu; - int *inperm; - int axis; - int naxes1; - int naxes; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Obtain a pointer to the CmpFrame's axis permutation array. */ - perm = astGetPerm( this ); - -/* Obtain the number of axes in the CmpFrame and in the first - component Frame. */ - naxes = astGetNaxes( this ); - naxes1 = astGetNaxes( this->frame1 ); - -/* Allocate memory to hold the permuted coordinates. */ - vl = astMalloc( sizeof( double ) * (size_t) naxes ); - vu = astMalloc( sizeof( double ) * (size_t) naxes ); - inperm = astMalloc( sizeof( int ) * (size_t) naxes ); - if( inperm ) { - -/* Permute the coordinates using the CmpFrame's axis permutation array - to put them into the order required internally (i.e. by the two - component Frames). */ - for ( axis = 0; axis < naxes; axis++ ) { - vl[ perm[ axis ] ] = lbnd[ axis ]; - vu[ perm[ axis ] ] = ubnd[ axis ]; - } - -/* Create a PermMap with a forward transformation which reorders a position - which uses internal axis ordering into a position which uses external axis - ordering. */ - pm1 = astPermMap( naxes, NULL, naxes, perm, NULL, "", status ); - -/* Put it in front of the supplied Mapping. The combination transforms an - input internal position into an output external position. */ - m1 = astCmpMap( pm1, reg, 1, "", status ); - -/* Invert it and add it to the end. This combination now transforms an - input internal position into an output internal position. */ - astInvert( pm1 ); - m2 = astCmpMap( m1, pm1, 1, "", status ); - -/* Create a PermMap with a forward transformation which copies the lower - naxes1 inputs to the same outputs, and supplies AST__BAD for the other - outputs. */ - for( axis = 0; axis < naxes1; axis++ ) inperm[ axis ] = axis; - pm2 = astPermMap( naxes1, inperm, naxes, NULL, NULL, "", status ); - -/* Put it in front of the Mapping created above, then invert it and add - it at the end. */ - m3 = astCmpMap( pm2, m2, 1, "", status ); - astInvert( pm2 ); - m4 = astCmpMap( m3, pm2, 1, "", status ); - -/* Invoke the astNormBox method of the first component Frame, passing the - relevant (permuted) coordinate values for normalisation. */ - astNormBox( this->frame1, vl, vu, m4 ); - -/* Create a PermMap with a forward transformation which copies the upper - inputs to the same outputs, and supplied AST__BAD for the other - outputs. */ - for( axis = 0; axis < naxes - naxes1; axis++ ) inperm[ axis ] = naxes1 + axis; - pm3 = astPermMap( naxes1, inperm, naxes, NULL, NULL, "", status ); - -/* Put it in front of the Mapping created above, then invert it and add - it at the end. */ - m5 = astCmpMap( pm3, m2, 1, "", status ); - astInvert( pm3 ); - m6 = astCmpMap( m5, pm3, 1, "", status ); - -/* Invoke the astNormBox method of the seond component Frame, passing the - relevant (permuted) coordinate values for normalisation. */ - astNormBox( this->frame2, vl + naxes1, vu + naxes1, m6 ); - -/* Copy the normalised values back into the original coordinate array, - un-permuting them in the process. */ - for ( axis = 0; axis < naxes; axis++ ) { - lbnd[ axis ] = vl[ perm[ axis ] ]; - ubnd[ axis ] = vu[ perm[ axis ] ]; - } - -/* Free resources. */ - pm1 = astAnnul( pm1 ); - pm2 = astAnnul( pm2 ); - pm3 = astAnnul( pm3 ); - m1 = astAnnul( m1 ); - m2 = astAnnul( m2 ); - m3 = astAnnul( m3 ); - m4 = astAnnul( m4 ); - m5 = astAnnul( m5 ); - m6 = astAnnul( m6 ); - } - inperm = astFree( inperm ); - vl = astFree( vl ); - vu = astFree( vu ); -} - -static void Offset( AstFrame *this_frame, const double point1[], - const double point2[], double offset, double point3[], int *status ) { -/* -* Name: -* Offset - -* Purpose: -* Calculate an offset along a geodesic curve. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void Offset( AstFrame *this, -* const double point1[], const double point2[], -* double offset, double point3[], int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astOffset method -* inherited from the Frame class). - -* Description: -* This function finds the CmpFrame coordinate values of a point -* which is offset a specified distance along the geodesic curve -* between two other points. - -* Parameters: -* this -* Pointer to the CmpFrame. -* point1 -* An array of double, with one element for each CmpFrame axis. -* This should contain the coordinates of the point marking the -* start of the geodesic curve. -* point2 -* An array of double, with one element for each CmpFrame axis. -* This should contain the coordinates of the point marking the -* end of the geodesic curve. -* offset -* The required offset from the first point along the geodesic -* curve. If this is positive, it will be towards the second -* point. If it is negative, it will be in the opposite -* direction. This offset need not imply a position lying -* between the two points given, as the curve will be -* extrapolated if necessary. -* point3 -* An array of double, with one element for each CmpFrame axis -* in which the coordinates of the required point will be -* returned. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -* - "Bad" coordinate values will also be returned if the two -* points supplied are coincident (or otherwise fail to uniquely -* specify a geodesic curve) but the requested offset is non-zero. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - const int *perm; /* Pointer to axis permutation array */ - double *p1; /* Permuted coordinates for point1 */ - double *p2; /* Permuted coordinates for point2 */ - double *p3; /* Permuted coordinates for point3 */ - double dist1; /* Distance between input points in frame1 */ - double dist2; /* Distance between input points in frame2 */ - double dist; /* Total distance between input points */ - double offset1; /* Offset distance required in frame1 */ - double offset2; /* Offset distance required in frame2 */ - int axis; /* Loop counter for axes */ - int bad; /* Set bad output coordinates? */ - int naxes1; /* Number of axes in frame1 */ - int naxes; /* Total number of axes in CmpFrame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Obtain the number of axes in the CmpFrame. */ - naxes = astGetNaxes( this ); - -/* Obtain a pointer to the CmpFrame's axis permutation array. */ - perm = astGetPerm( this ); - -/* Allocate workspace. */ - p1 = astMalloc( sizeof( double ) * (size_t) naxes ); - p2 = astMalloc( sizeof( double ) * (size_t) naxes ); - p3 = astMalloc( sizeof( double ) * (size_t) naxes ); - -/* Initialise variables to avoid compiler warnings. */ - dist1 = 0.0; - dist2 = 0.0; - offset1 = 0.0; - offset2 = 0.0; - naxes1 = 0; - -/* Initialise a flag to indicate whether "bad" coordinates should be - returned. */ - bad = 0; - -/* Check that all the coordinates of both input points are OK. If not, - set the "bad" flag and quit checking. */ - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) { - if ( ( point1[ axis ] == AST__BAD ) || - ( point2[ axis ] == AST__BAD ) ) { - bad = 1; - break; - -/* If the coordinates are OK, apply the axis permutation array to - obtain them in the required order. */ - } else { - p1[ perm[ axis ] ] = point1[ axis ]; - p2[ perm[ axis ] ] = point2[ axis ]; - } - } - } - -/* If OK, obtain the number of axes in the first component Frame. */ - if ( astOK && !bad ) { - naxes1 = astGetNaxes( this->frame1 ); - -/* Project the two input points into the two component Frames and - determine the distance between the points in each Frame. */ - dist1 = astDistance( this->frame1, p1, p2 ); - dist2 = astDistance( this->frame2, p1 + naxes1, p2 + naxes1 ); - -/* Check that the returned distances are not bad. */ - if ( astOK ) bad = ( ( dist1 == AST__BAD ) || ( dist2 == AST__BAD ) ); - } - -/* If OK, calculate the total distance between the two points. */ - if ( astOK && !bad ) { - dist = sqrt( dist1 * dist1 + dist2 * dist2 ); - -/* If the points are co-incident, but "offset" is non-zero, then set - the "bad" flag. */ - if ( dist == 0.0 ) { - if ( offset != 0.0 ) { - bad = 1; - -/* Otherwise, set the offset distance required in each Frame to - zero. */ - } else { - offset1 = 0.0; - offset2 = 0.0; - } - -/* If the points are not co-incident, divide the total offset required - between each component Frame in such a way that the path being - followed will pass through the second point. */ - } else { - offset1 = offset * dist1 / dist; - offset2 = offset * dist2 / dist; - } - } - -/* If OK, apply the separate offsets to each component Frame. */ - if ( astOK && !bad ) { - astOffset( this->frame1, p1, p2, offset1, p3 ); - astOffset( this->frame2, p1 + naxes1, p2 + naxes1, offset2, - p3 + naxes1 ); - -/* Copy the resulting coordinates into the output array "point3", - permuting them back into the required order. */ - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) { - point3[ axis ] = p3[ perm[ axis ] ]; - -/* If any of the result coordinates is bad, set the "bad" flag and - quit copying. */ - if ( point3[ axis ] == AST__BAD ) { - bad = 1; - break; - } - } - } - } - -/* Free the workspace arrays. */ - p1 = astFree( p1 ); - p2 = astFree( p2 ); - p3 = astFree( p3 ); - -/* If no error has occurred, but bad coordinates must be returned, - then set these in the output array. */ - if ( astOK && bad ) { - for ( axis = 0; axis < naxes; axis++ ) point3[ axis ] = AST__BAD; - } -} - -static void Overlay( AstFrame *template_frame, const int *template_axes, - AstFrame *result, int *status ) { -/* -* Name: -* Overlay - -* Purpose: -* Overlay the attributes of a template CmpFrame on to another Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void Overlay( AstFrame *template, const int *template_axes, -* AstFrame *result, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astOverlay -* method inherited from the Frame class). - -* Description: -* This function overlays attributes from a CmpFrame on to another Frame, -* so as to over-ride selected attributes of that second Frame. Normally -* only those attributes which have been specifically set in the template -* will be transferred. This implements a form of defaulting, in which -* a Frame acquires attributes from the template, but retains its -* original attributes (as the default) if new values have not previously -* been explicitly set in the template. - -* Parameters: -* template -* Pointer to the template CmpFrame, for whose current Frame -* values should have been explicitly set for any attribute -* which is to be transferred. -* template_axes -* Pointer to an array of int, with one element for each axis of -* the "result" Frame (see below). For each axis in the result -* frame, the corresponding element of this array should contain -* the (zero-based) index of the axis in the current Frame of -* the template CmpFrame to which it corresponds. This array is -* used to establish from which template Frame axis any -* axis-dependent attributes should be obtained. -* -* If any axis in the result Frame is not associated with a -* template Frame axis, the corresponding element of this array -* should be set to -1. -* -* If a NULL pointer is supplied, the template and result axis -* indices are assumed to be identical. -* result -* Pointer to the Frame which is to receive the new attribute values. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstCmpFrame *res; /* Pointer to the result CmpFrame structure */ - AstCmpFrame *template; /* Pointer to the template CmpFrame structure */ - AstFrame *sub1; /* Template subframe for 1st result subframe */ - AstFrame *sub2; /* Template subframe for 2nd result subframe */ - const int *perm; /* Template axis permutation array */ - const int *rperm; /* Result axis permutation array */ - int *axes1; /* Axis associations with template frame1 */ - int *axes2; /* Axis associations with template frame2 */ - int done; /* Have attributes been overlayed yet? */ - int i; /* Index of result axis */ - int icmp; /* Internal template axis number */ - int isfirst; /* Res. subframe -> 1st template subframe? */ - int issecond; /* Res. subframe -> 2nd template subframe? */ - int j; /* Index of template axis */ - int nc1; /* Number of axes in template frame1 */ - int nres1; /* Number of axes in first result subframe */ - int nres2; /* Number of axes in second result subframe */ - int nres; /* Number of axes in result Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - template = (AstCmpFrame *) template_frame; - -/* Get the axis permutation array for the template CmpFrame. */ - perm = astGetPerm( template ); - -/* Get the number of axes in the first component Frame in the template - CmpFrame. */ - nc1 = astGetNaxes( template->frame1 ); - -/* Indicate we have not yet overlayed any attributes. */ - done = 0; - -/* If the result Frame is a CmpFrame... */ - if( astIsACmpFrame( result ) ) { - -/* Get the number of axes in the two component Frames of the result CmpFrame. */ - res = (AstCmpFrame *) result; - nres1 = astGetNaxes( res->frame1 ); - nres2 = astGetNaxes( res->frame2 ); - -/* Get the total number of axes in the result CmpFrame. */ - nres = nres1 + nres2; - -/* Get the axis permutation array for the result CmpFrame. */ - rperm = astGetPerm( result ); - -/* Allocate memory for two new axes arrays, one for each result sub-frame. */ - axes1 = astMalloc( sizeof(int)*(size_t)nres1 ); - axes2 = astMalloc( sizeof(int)*(size_t)nres2 ); - if( astOK ) { - -/* Assume that there is a 1-to-1 correspondence between axes in the - subframes of the result and template CmpFrame. That is, all the axes - in each result sub-frame are overlayed from the same template sub-frame. */ - done = 1; - -/* Loop round each axis in the first result sub-frame. */ - isfirst = 0; - issecond = 0; - for( i = 0; i < nres1; i++ ) { - -/* Find the external result CmpFrame axis index (j) for internal axis i. */ - for( j = 0; j < nres; j++ ) { - if( rperm[ j ] == i ) break; - } - -/* Get the internal axis number within the template CmpFrame which - provides attribute values for the current result axis. */ - icmp = perm[ template_axes ? template_axes[ j ] : j ]; - -/* If this template axis is in the first template subframe, store the - corresponding internal frame axis index in "axes1" and set a flag - indicating that the first result subframe corresponds to the first - template subframe. If the correspondance has already been established, - but is broken by this axis, then set "done" false and exit the axis - loop. */ - if( icmp < nc1 ) { - if( issecond ) { - done = 0; - break; - } else { - isfirst = 1; - axes1[ i ] = icmp; - } - - } else { - if( isfirst ) { - done = 0; - break; - } else { - issecond = 1; - axes1[ i ] = icmp - nc1; - } - } - } - -/* Save a pointer to the template subframe which is associated with the first - result subframe.*/ - sub1 = isfirst ? template->frame1 :template->frame2; - -/* Now do the same for the axes in the second result sub-frame. */ - isfirst = 0; - issecond = 0; - for( i = 0; i < nres2; i++ ) { - for( j = 0; j < nres; j++ ) { - if( rperm[ j ] == i + nres1 ) break; - } - - icmp = perm[ template_axes ? template_axes[ j ] : j ]; - - if( icmp < nc1 ) { - if( issecond ) { - done = 0; - break; - } else { - isfirst = 1; - axes2[ i ] = icmp; - } - - } else { - if( isfirst ) { - done = 0; - break; - } else { - issecond = 1; - axes2[ i ] = icmp - nc1; - } - } - } - -/* Save a pointer to the template subframe which is associated with the - second result subframe.*/ - sub2 = isfirst ? template->frame1 :template->frame2; - -/* If the two used template subframes are the same, something has gone - wrong. */ - if( sub1 == sub2 ) done = 0; - -/* If all axes within each result subframe are associated with the same - template subframe we continue to use the subframe astOverlay methods. */ - if( done ) { - -/* Overlay the first result subframe. */ - astOverlay( sub1, axes1, res->frame1 ); - astOverlay( sub2, axes2, res->frame2 ); - } - } - -/* Free the axes arrays. */ - axes1 = astFree( axes1 ); - axes2 = astFree( axes2 ); - } - -/* If we have not yet overlayed any attributes... */ - if( !done ) { - -/* Get the number of axes in the result Frame. */ - nres = astGetNaxes( result ); - -/* Allocate memory for two new template_axes arrays. */ - axes1 = astMalloc( sizeof(int)*(size_t)nres ); - axes2 = astMalloc( sizeof(int)*(size_t)nres ); - if( astOK ) { - -/* Set elements to -1 in "axes1" if they do not refer to the first component - Frame in the template CmpFrame. Likewise, set elements to -1 in "axes2" if - they do not refer to the second component Frame in the template CmpFrame. */ - for( i = 0; i < nres; i++ ) { - -/* Get the internal axis number within the template CmpFrame which - provides attribute values for the current results axis. */ - icmp = perm[ template_axes ? template_axes[ i ] : i ]; - -/* If this template axis is in the first component Frame, store the - corresponding internal frame axis index in "axes1" and set "axis2" to - -1. */ - if( icmp < nc1 ) { - axes1[ i ] = icmp; - axes2[ i ] = -1; - -/* If this template axis is in the second component Frame, store the - corresponding internal frame axis index in "axes2" and set "axis1" to - -1. */ - } else { - axes1[ i ] = -1; - axes2[ i ] = icmp - nc1; - } - } - -/* Now use the astOverlay methods of the two component Frames to overlay - attributes onto the appropriate axes of the results Frame. */ - astOverlay( template->frame1, axes1, result ); - astOverlay( template->frame2, axes2, result ); - } - -/* Free the axes arrays. */ - axes1 = astFree( axes1 ); - axes2 = astFree( axes2 ); - } -} - -static void PartitionSelection( int nselect, const int select[], - const int perm[], int naxes1, int naxes2, - int iframe[], int following, int *status ) { -/* -* Name: -* PartitionSelection - -* Purpose: -* Partition a CmpFrame axis selection into two component Frame selections. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void PartitionSelection( int nselect, const int select[], -* const int perm[], int naxes1, int naxes2, -* int iframe[], int following, int *status ) - -* Class Membership: -* CmpFrame member function. - -* Description: -* This function accepts an array containing the indices of axes -* which are to be selected from a CmpFrame, and partitions these -* indices to indicate which must be selected from each of the -* CmpFrame's two component Frames. -* -* This operation is trivial if all the axis indices supplied refer -* to valid CmpFrame axes. However, if some of them do not (these -* should generally be set to -1), this function assigns these -* "extra" axes to one or other of the component Frames by -* associating them with the axes selected immediately before (or -* after). Allowance is made for the possibility that several -* consecutive selected axes may be "extra" ones, or even that they -* may all be. The CmpFrame's axis permutation array is also taken -* into account. - -* Parameters: -* nselect -* The number of axes to be selected. -* select -* An array containing the (zero-based) indices of the CmpFrame -* axes to be selected, or -1 where "extra" axes are required. -* perm -* The CmpFrame's axis permutation array. -* naxes1 -* The number of axes in the CmpFrame's first component Frame. -* naxes2 -* The number of axes in the CmpFrame's second component Frame. -* iframe -* An array with "nselect" elements in which to return a number -* (either 1 or 2) to indicate to which component Frame (frame1 -* or frame2) each selected axis belongs. -* following -* If this is zero, "extra" axes will be associated with the -* preceding normal selected axis which appears in the "select" -* array (if any), otherwise they will be associated with the -* following normal selected axis. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int end; /* Loop termination value */ - int ifr; /* Choice of Frame for next "extra" axis */ - int inc; /* Loop increment value */ - int iselect; /* Loop counter for axis selections */ - int naxes; /* Total number of CmpFrame axes */ - int start; /* Loop starting value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the total number of CmpFrame axes. */ - naxes = naxes1 + naxes2; - -/* Loop through each axis selection and identify those which refer to - valid CmpFrame axes. */ - for ( iselect = 0; iselect < nselect; iselect++ ) { - if ( ( select[ iselect ] >= 0 ) && ( select[ iselect ] < naxes ) ) { - -/* For these selections (only), enter a flag into the "iframe" array - which indicates which component Frame the selected axis resides - in. Permute each axis index before deciding this. */ - iframe[ iselect ] = 1 + ( perm[ select[ iselect ] ] >= naxes1 ); - } - } - -/* Set up a start, end, and increment value for looping through the - array of axis selections forward (if "following" is 0) or backwards - (otherwise). */ - start = following ? nselect - 1 : 0; - end = following ? -1 : nselect; - inc = following ? -1 : 1; - -/* Set the default choice of component Frame. This will be used if - there are no normal axis selections to guide the choice at all. */ - ifr = following ? 2 : 1; - -/* Search for the first normal axis selection so that we can replace - this default, if possible. (Here, "first" actually means "last" if - "following" is set, because we will then be scanning the array of - selections in reverse.) */ - for ( iselect = start; iselect != end; iselect += inc ) { - -/* Identify normal axis selections and obtain the choice of component - Frame for the first one found. The resulting value "ifr" will be - used for initial (or final, if "following" is set) "extra" - selections for which no earlier normal selection exists - see - below. */ - if ( ( select[ iselect ] >= 0 ) && ( select[ iselect ] < naxes ) ) { - ifr = iframe[ iselect ]; - break; - } - } - -/* Loop through the selections again to allocate a choice of Frame to - the "extra" selected axes. */ - for ( iselect = start; iselect != end; iselect += inc ) { - -/* Remember the component Frame used by the most recently encountered - normal axis selection. */ - if ( ( select[ iselect ] >= 0 ) && ( select[ iselect ] < naxes ) ) { - ifr = iframe[ iselect ]; - -/* For "extra" axes, allocate the most recent Frame choice. The - default choice (found above) will apply if no "most recent" choice - has been encountered. */ - } else { - iframe[ iselect ] = ifr; - } - } -} - -static int PartMatch( AstCmpFrame *template, AstFrame *target, - int matchsub, int naxes1, const int axes1[], - int naxes2, const int axes2[], - int **template_axes, int **target_axes, - AstMapping **map, AstFrame **result, int *status ) { -/* -* Name: -* PartMatch - -* Purpose: -* Match a CmpFrame template to partitioned target axes. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int PartMatch( AstCmpFrame *template, AstFrame *target, -* int matchsub, int naxes1, const int axes1[], -* int naxes2, const int axes2[], -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* CmpFrame member function. - -* Description: -* This function matches a "template" CmpFrame to a "target" Frame -* and determines whether it is possible to convert coordinates -* between them. If it is, a Mapping that performs the -* transformation is returned along with a new Frame that describes -* the coordinate system that results when this Mapping is applied -* to the "target" coordinate system. In addition, information is -* returned to allow the axes in this "result" Frame to be -* associated with the corresponding axes in the "target" Frame and -* "template" CmpFrame from which they are derived. -* -* To simplify the matching process for a CmpFrame template, this -* function requires the caller to specify how the axes of the -* target Frame should be partitioned between the two component -* Frames of the template. The function attempts to find a match -* using this axis partitioning only. In general, the way in which -* the target axes must be partitioned is not known in advance, so -* this function must be invoked several times with alternative -* partitioning before a match will be found. - -* Parameters: -* template -* Pointer to the template CmpFrame. This describes the -* coordinate system (or set of possible coordinate systems) -* into which we wish to convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate -* system in which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case (i.e. if the -* target is of a more specialised class than the template). In -* this latter case, the target is cast down to the class of the -* template. -* naxes1 -* The number of target axes to be matched against the first -* component Frame of the template CmpFrame. -* axes1 -* An array with "naxes1" elements containing the (zero-based) -* indices of the target axes to be matched against the first -* component Frame. Order is not significant. -* naxes2 -* The number of target axes to be matched against the second -* component Frame of the template CmpFrame. -* axes2 -* An array with "naxes2" elements containing the (zero-based) -* indices of the target axes to be matched against the second -* component Frame. Order is not significant. -* template_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* template CmpFrame axis from which it is derived. If it is not -* derived from any template axis, a value of -1 will be -* returned instead. -* target_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* target Frame axis from which it is derived. If it is not -* derived from any target Frame axis, a value of -1 will be -* returned instead. -* map -* Address of a location where a pointer to a new Mapping will -* be returned if the requested coordinate conversion is -* possible. If returned, the forward transformation of this -* Mapping may be used to convert coordinates between the -* "target" Frame and the "result" Frame (see below) and the -* inverse transformation will convert in the opposite -* direction. -* result -* Address of a location where a pointer to a new Frame will be -* returned if the requested coordinate conversion is -* possible. If returned, this Frame describes the coordinate -* system that results from applying the returned Mapping -* (above) to the "target" coordinate system. In general, this -* Frame will combine attributes from (and will therefore be -* more specific than) both the target Frame and the template -* CmpFrame. In particular, when the template allows the -* possibility of transformaing to any one of a set of -* alternative coordinate systems, the "result" Frame will -* indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate -* conversion is possible. Otherwise zero is returned (this will -* not in itself result in an error condition). - -* Notes: -* - The "axes1" and "axes2" arrays should not contain any axis -* indices in common and should, taken together, list all the axes -* of the target Frame. -* - By default, the "result" Frame will have its number of axes -* and axis order determined by the "template" CmpFrame. However, -* if the PreserveAxes attribute of the template is non-zero, then -* the axis count and axis order of the "target" Frame will be used -* instead. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *frame1; /* Pointer to first sub-Frame from target */ - AstFrame *frame2; /* Pointer to second sub-Frame from target */ - AstFrame *result1; /* Result Frame pointer from first match */ - AstFrame *result2; /* Result Frame pointer from second match */ - AstFrame *tmp_frame; /* Temporary Frame pointer */ - AstMapping *junk_map; /* Mapping pointer returned by astSubFrame */ - AstMapping *map1; /* Mapping pointer from first match */ - AstMapping *map2; /* Mapping pointer from second match */ - AstMapping *permmap; /* Pointer to PermMap */ - AstMapping *tmp_map; /* Temporary Mapping pointer */ - const int *perm; /* Template axis permutation array pointer */ - int *inperm; /* Pointer to temporary permutation array */ - int *invperm; /* Inverse axis permutation array pointer */ - int *outperm; /* Pointer to temporary permutation array */ - int *pick; /* Pointer to array of axis selections */ - int *result_order; /* Relative result axis order array pointer */ - int *result_perm; /* Result axis permutation array pointer */ - int *target_assoc; /* Target axis association array pointer */ - int *target_axes1; /* Target axis associations from 1st match */ - int *target_axes2; /* Target axis associations from 2nd match */ - int *template_assoc; /* Template axis association array pointer */ - int *template_axes1; /* Template axis associations, 1st match */ - int *template_axes2; /* Template axis associations, 2nd match */ - int first; /* Axis in 1st component? */ - int full_axis; /* Result Frame axis index, before sub-set */ - int match1; /* First match successful? */ - int match2; /* Second match successful? */ - int match; /* Both matches successful? (result) */ - int match_end1; /* MatchEnd attribute for component 1 */ - int match_end2; /* MatchEnd attribute for component 2 */ - int match_end; /* MatchEnd attribute for template */ - int match_end_set; /* Component MatchEnd attribute set? */ - int output_axis; /* Output axis index */ - int part_result_axis; /* Result Frame component axis index */ - int part_target_axis; /* Target Frame component axis index */ - int part_template_axis; /* Template CmpFrame component axis index */ - int permute_set; /* Component Permute attribute set? */ - int permute_value; /* Component Permute attribute value */ - int preserve_axes; /* Template PreserveAxes attribute value */ - int preserve_axes_set; /* Component PreserveAxes attribute set? */ - int ref_naxes; /* Number of reference Frame axes */ - int result_axis; /* Result Frame axis index */ - int result_naxes1; /* Number of result Frame axes, component 1 */ - int result_naxes2; /* Number of result Frame axes, component 2 */ - int result_naxes; /* Total number of result Frame axes */ - int target_axis; /* Target Frame axis index */ - int target_naxes; /* Number of target Frame axes */ - int template_axis; /* Template CmpFrame axis index */ - int template_naxes1; /* Number of template axes, component 1 */ - int template_naxes; /* Total number of template axes */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Initialise other variables to avoid compiler errors. */ - ref_naxes = 0; - -/* Select the required sub-Frames from the target. */ -/* ----------------------------------------------- */ -/* We first create two sub-Frames (that can be matched against the two - template component Frames) by selecting the two specified sets of - axes from the target. This is done without overlaying any template - attributes. Annul the Mappings produced by this process, as these - are not needed. */ - - frame1 = NULL; - junk_map = NULL; - (void) astSubFrame( target, NULL, naxes1, axes1, NULL, &junk_map, &frame1 ); - if( junk_map ) junk_map = astAnnul( junk_map ); - - frame2 = NULL; - junk_map = NULL; - (void) astSubFrame( target, NULL, naxes2, axes2, NULL, &junk_map, &frame2 ); - if( junk_map ) junk_map = astAnnul( junk_map ); - -/* Match the sub-Frames with the template component Frames. */ -/* -------------------------------------------------------- */ -/* We now have two sub-Frames obtained from the target, and will - attempt to match these with the component Frames contained within - the template CmpFrame. */ - -/* Before using each template component Frame, see whether any of its - attributes that control matching is "un-set". If so, over-ride it - with the attribute value of the template CmpFrame as a whole. */ - match_end_set = astTestMatchEnd( template->frame1 ); - if ( !match_end_set ) { - astSetMatchEnd( template->frame1, astGetMatchEnd( template ) ); - } - preserve_axes_set = astTestPreserveAxes( template->frame1 ); - if ( !preserve_axes_set ) { - astSetPreserveAxes( template->frame1, astGetPreserveAxes( template ) ); - } - -/* We must also temporarily set the Permute attribute to 1 (this is - normally the default, but might have been set otherwise). This is - needed so that permutations of the target axes will be considered. - Without this, the order in which the axes are presented is - significant and we would have to test all the permutations. If the - Permute attribute of the template CmpFrame as a whole is zero, then - the resulting match may still have to be rejected, but this must be - done at a higher level. */ - permute_set = astTestPermute( template->frame1 ); - permute_value = ( permute_set ) ? astGetPermute( template->frame1 ) : 0; - astSetPermute( template->frame1, 1 ); - -/* Test for a match with the first template component Frame. */ - match1 = astMatch( template->frame1, frame1, matchsub, - &template_axes1, &target_axes1, &map1, &result1 ); - -/* Clear the attribute values again afterwards if necessary. */ - if ( !match_end_set ) astClearMatchEnd( template->frame1 ); - if ( !preserve_axes_set ) astClearPreserveAxes( template->frame1 ); - -/* Also restore the original Permute attribute setting. */ - if ( permute_set ) { - astSetPermute( template->frame1, permute_value ); - } else { - astClearPermute( template->frame1 ); - } - -/* Repeat the whole process for the second component Frame. */ - match_end_set = astTestMatchEnd( template->frame2 ); - if ( !match_end_set ) { - astSetMatchEnd( template->frame2, astGetMatchEnd( template ) ); - } - preserve_axes_set = astTestPreserveAxes( template->frame2 ); - if ( !preserve_axes_set ) { - astSetPreserveAxes( template->frame2, astGetPreserveAxes( template ) ); - } - permute_set = astTestPermute( template->frame2 ); - if ( permute_set ) permute_value = astGetPermute( template->frame2 ); - astSetPermute( template->frame2, 1 ); - - match2 = astMatch( template->frame2, frame2, matchsub, - &template_axes2, &target_axes2, &map2, &result2 ); - - if ( !match_end_set ) astClearMatchEnd( template->frame2 ); - if ( !preserve_axes_set ) astClearPreserveAxes( template->frame2 ); - if ( permute_set ) { - astSetPermute( template->frame2, permute_value ); - } else { - astClearPermute( template->frame2 ); - } - -/* See if both matches were successful. */ - if ( astOK && match1 && match2 ) { - match = 1; - -/* Obtain the number of target axes. */ - target_naxes = astGetNaxes( target ); - -/* Obtain the number of axes in each of the result Frames produced by - the matching operation. */ - result_naxes1 = astGetNaxes( result1 ); - result_naxes2 = astGetNaxes( result2 ); - -/* Obtain the number of axes in the first template component Frame and - in the template CmpFrame as a whole. */ - template_naxes1 = astGetNaxes( template->frame1 ); - template_naxes = astGetNaxes( template ); - -/* Obtain the value of the MatchEnd attribute for each of the - template's component Frames and for the template CmpFrame as a - whole. */ - match_end1 = astGetMatchEnd( template->frame1 ); - match_end2 = astGetMatchEnd( template->frame2 ); - match_end = astGetMatchEnd( template ); - -/* Obtain a pointer to the template CmpFrame's axis permutation - array. Allocate space for a further array and fill it with the - inverse of this axis permutation. */ - perm = astGetPerm( template ); - invperm = astMalloc( sizeof( int ) * (size_t) template_naxes ); - if ( astOK ) { - for ( template_axis = 0; template_axis < template_naxes; - template_axis++ ) { - invperm[ perm[ template_axis ] ] = template_axis; - } - } - -/* Generate template and target axis associations. */ -/* ----------------------------------------------- */ -/* We now construct two arrays which identify the axis associations - between the result axes (in the order obtained from the matching - process above) and the axes of the template and target. This - involves tracing back through several steps. */ - -/* First calculate the total number of result axes and allocate memory - for the association arrays. */ - result_naxes = result_naxes1 + result_naxes2; - template_assoc = astMalloc( sizeof( int ) * (size_t) result_naxes ); - target_assoc = astMalloc( sizeof( int ) * (size_t) result_naxes ); - if ( astOK ) { - -/* Produce associations for each result axis in turn. */ - for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) { - -/* Decide whether this result axis is contained in the first (or - second) individual result Frame. */ - first = ( result_axis < result_naxes1 ); - -/* Obtain the index of the axis within the individual result Frame. - This involves adjusting for the axis numbering offset of the second - result Frame if necessary. */ - part_result_axis = first ? result_axis : - result_axis - result_naxes1; - -/* Find the template and target axis associations for this axis by - looking them up in the association arrays returned from the - matching process. This gives axis indices that apply to the - individual template/target Frames supplied as input to the matching - process. */ - part_template_axis = first ? template_axes1[ part_result_axis ] : - template_axes2[ part_result_axis ]; - part_target_axis = first ? target_axes1[ part_result_axis ] : - target_axes2[ part_result_axis ]; - -/* Check that the resulting template association identifies a valid - template axis. */ - if ( part_template_axis != -1 ) { - -/* If so, obtain the template axis index. This involves adjusting for - the axis numbering offset of the second template component Frame - (if necessary) and then applying the inverse template axis - permutation to convert to the external template axis - numbering. Store the result in the template association array. */ - template_assoc[ result_axis ] = - invperm[ first ? part_template_axis : - part_template_axis + template_naxes1 ]; - -/* Indicate if there is no template axis association by storing an - index of -1. */ - } else { - template_assoc[ result_axis ] = -1; - } - -/* Similarly, check that the target association identifies a valid - target axis. */ - if ( part_target_axis != -1 ) { - -/* If so, obtain the target axis index. This simply involves using the - axis selection arrays provided by the caller to look up which - target axes were involved in the matching process. */ - target_assoc[ result_axis ] = - first ? axes1[ part_target_axis ] : - axes2[ part_target_axis ]; - -/* Indicate if there is no target axis association by storing an index - of -1. */ - } else { - target_assoc[ result_axis ] = -1; - } - } - } - -/* Free the inverse axis permutation array. */ - invperm = astFree( invperm ); - -/* Create the output Frame. */ -/* ------------------------ */ -/* Initialise. */ - result_order = NULL; - result_perm = NULL; - -/* Construct the basis of the final result Frame by combining the two - individual result Frames (from the matching process) using a - CmpFrame. */ - if ( astOK ) { - *result = (AstFrame *) astCmpFrame( result1, result2, "", status ); - -/* The next step is to permute the result Frame's axis order so that - it corresponds with the axis order of the "reference Frame". The - reference Frame is either the template or the target, depending on - whether the template's PreserveAxes attribute is non-zero. Obtain - the value of this attribute. */ - preserve_axes = astGetPreserveAxes( template ); - -/* Decide how many axes the reference Frame contains. */ - ref_naxes = preserve_axes ? target_naxes : template_naxes; - -/* Make a copy of the axis association array that refers to the - reference Frame. */ - result_order = astStore( NULL, - preserve_axes ? target_assoc : - template_assoc, - sizeof( int ) * (size_t) result_naxes ); - -/* The intention is to use this axis association array to permute the - result axes into the same order as the reference Frame's axes. It - is not that simple, however, because some of the axis associations - may be null (i.e. result axes may exist that are not associated - with reference axes) and they may also be incomplete (i.e. not - every reference axis may be associated with a result axis). - - This prevents us from permuting the result axis order using this - array directly, essentially because we haven't yet defined where - any "extra" result axes (those with no association) should appear - in the final axis order. */ - -/* To overcome this, we replace all the null (-1) entries in the - "result_order" array with new values which define their position - relative to the other entries. This also involves re-numbering - other entries to avoid clashes. The new numbers assigned depend on - the MatchEnd attribute for each of the template component Frames, - so we handle the associations for each of these components - separately. */ - AddExtraAxes( result_naxes, result_order, - 0, result_naxes1 - 1, match_end1, status ); - AddExtraAxes( result_naxes, result_order, - result_naxes1, result_naxes - 1, match_end2, status ); - -/* There may now be some reference Frame axes which are not referenced - in this array, so we renumber the entries starting at zero (but - preserving their relative order) so that there are no missing - values due to these. */ - RenumberAxes( result_naxes, result_order, status ); - -/* The resulting "result_order" array no longer describes the original - reference Frame axis associations, but is now suitable for - permuting the result axes into the required order. However, we - require the inverse of this permutation, so allocate an array and - fill it with the inverse. */ - result_perm = astMalloc( sizeof( int ) * (size_t) result_naxes ); - if ( astOK ) { - for ( result_axis = 0; result_axis < result_naxes; - result_axis++ ) { - result_perm[ result_order[ result_axis ] ] = result_axis; - } - } - -/* Apply the inverse permutation to the result CmpFrame to put its - axes into the required order. */ - astPermAxes( *result, result_perm ); - -/* Check if the number of result Frame axes differs from the number of - reference axes. This can arise if the PreserveAxes attribute of - either template component Frame is set to a value that differs from - that of the template CmpFrame as a whole. If this is the case, we - must select a sub-set (or super-set) of the result axes, so that we - end up with the same number of axes as the reference Frame. */ - if ( ref_naxes != result_naxes ) { - -/* Allocate an array to hold the indices of the axes required. */ - pick = astMalloc( sizeof( int ) * (size_t) ref_naxes ); - if ( astOK ) { - -/* Generate the axis indices, using the template CmpFrame's MatchEnd - attribute to decide which ones to use. */ - for ( output_axis = 0; output_axis < ref_naxes; - output_axis++ ) { - full_axis = - match_end ? output_axis + ( result_naxes - ref_naxes ) : - output_axis; - -/* If the index is valid (i.e. the required axis is available), store - it. Otherwise, use an index of -1, which requests that new - (default) axes be supplied where needed. */ - if ( ( full_axis >= 0 ) && ( full_axis < result_naxes ) ) { - pick[ output_axis ] = full_axis; - } else { - pick[ output_axis ] = -1; - } - } - } - -/* Pick the required axes from the result Frame and replace it with - the new one. */ - tmp_frame = astPickAxes( *result, ref_naxes, pick, NULL ); - *result = astAnnul( *result ); - *result = tmp_frame; - -/* Free the array of axis indices. */ - pick = astFree( pick ); - } - } - -/* Create output axis association arrays. */ -/* -------------------------------------- */ -/* We now construct the two arrays that are returned to identify which - template and target axes (if any) are associated with each final - result Frame axis. Allocate memory for these arrays. */ - if ( astOK ) { - *target_axes = astMalloc( sizeof( int ) * (size_t) ref_naxes ); - *template_axes = astMalloc( sizeof( int ) * (size_t) ref_naxes ); - if ( astOK ) { - -/* For each output axis, obtain the original result axis index (before - any sub-set or super-set of the output axes was selected). */ - for ( output_axis = 0; output_axis < ref_naxes; output_axis++ ) { - full_axis = - match_end ? output_axis + ( result_naxes - ref_naxes ) : - output_axis; - -/* Derive the result axis index before the axes were permuted into - their final order. */ - if ( ( full_axis >= 0 ) && ( full_axis < result_naxes ) ) { - result_axis = result_perm[ full_axis ]; - -/* Use this axis index and the axis association arrays generated - earlier to obtain the required associations, and store these in the - output arrays. */ - ( *template_axes )[ output_axis ] = - template_assoc[ result_axis ]; - ( *target_axes )[ output_axis ] = - target_assoc[ result_axis ]; - -/* Store a value of -1 if there is no association. */ - } else { - ( *template_axes )[ output_axis ] = -1; - ( *target_axes )[ output_axis ] = -1; - } - } - } - } - -/* Free the original (un-permuted) axis association arrays. */ - template_assoc = astFree( template_assoc ); - target_assoc = astFree( target_assoc ); - -/* Create the output Mapping. */ -/* -------------------------- */ -/* Construct the basis of the final output Mapping by combining the - Mappings produced by the individual matching processes in parallel, - using a CmpMap. */ - *map = (AstMapping *) astCmpMap( map1, map2, 0, "", status ); - -/* It is now necessary to prefix and suffix this CmpMap with two - PermMaps, which correct the input and output axis order to - correspond with the target and result Frame axes. - - At the target end, this reflects the partitioning of the target - axes into two groups, as specified by the caller. At the result - end, it reflects the axis permutation applied (above) to put the - final result Frame axes into the required order, together with the - selection of any sub-set or super-set of these axes. */ - -/* Allocate memory for permutation arrays to describe the prefix - PermMap. */ - inperm = astMalloc( sizeof( int ) * (size_t) target_naxes ); - outperm = astMalloc( sizeof( int ) * (size_t) target_naxes ); - if ( astOK ) { - -/* Consider the target axes in the order that they were supplied to - the matching processes (i.e. the order that corresponds with the - input coordinates of the CmpMap produced above). */ - for ( target_axis = 0; target_axis < target_naxes; target_axis++ ) { - -/* Decide whether each axis belongs to the first (or second) selected - group of target axes. */ - first = ( target_axis < naxes1 ); - -/* Obtain the index of the target axis within the group. This involves - allowing for the numbering offset of the second group if - necessary. */ - part_target_axis = first ? target_axis : - target_axis - naxes1; - -/* Obtain the original target axis index by looking up the axis in the - appropriate axis selection array provided by the caller. */ - outperm[ target_axis ] = first ? axes1[ part_target_axis ] : - axes2[ part_target_axis ]; - -/* Fill the "inperm" array with the inverse of this permutation. */ - inperm[ outperm[ target_axis ] ] = target_axis; - } - } - -/* If the permutation is not null, use these permutation arrays to - construct the required prefix PermMap. */ - if ( GoodPerm( target_naxes, inperm, target_naxes, outperm, status ) ) { - permmap = (AstMapping *) astPermMap( target_naxes, inperm, - target_naxes, outperm, - NULL, "", status ); - -/* Add the PermMap as a prefix to the result Mapping and then annul - the original Mapping pointers. */ - tmp_map = (AstMapping *) astCmpMap( permmap, *map, 1, "", status ); - (void) astAnnul( *map ); - *map = tmp_map; - permmap = astAnnul( permmap ); - } - -/* Free the permutation arrays. */ - inperm = astFree( inperm ); - outperm = astFree( outperm ); - -/* Allocate memory for permutation arrays to describe the suffix - PermMap. */ - inperm = astMalloc( sizeof( int ) * (size_t) result_naxes ); - outperm = astMalloc( sizeof( int ) * (size_t) ref_naxes ); - if ( astOK ) { - -/* Initialise the "inperm" array. */ - for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) { - inperm[ result_axis ] = -1; - } - -/* For each output axis, obtain the index of the corresponding result - axis before any sub-set or super-set was selected. */ - for ( output_axis = 0; output_axis < ref_naxes; output_axis++ ) { - full_axis = - match_end ? output_axis + ( result_naxes - ref_naxes ) : - output_axis; - -/* Store the axis index before the result axes were permuted, and also - construct the inverse permutation. */ - if ( ( full_axis >= 0 ) && ( full_axis < result_naxes ) ) { - outperm[ output_axis ] = result_perm[ full_axis ]; - inperm[ outperm[ output_axis ] ] = output_axis; - -/* Note which output axes do not exist in the result Frame - (e.g. because a super-set was selected). */ - } else { - outperm[ output_axis ] = -1; - } - } - } - -/* If the permutation is not null, use these permutation arrays to - construct the required suffix PermMap. */ - if ( GoodPerm( target_naxes, inperm, target_naxes, outperm, status ) ) { - permmap = (AstMapping *) astPermMap( result_naxes, inperm, - ref_naxes, outperm, - NULL, "", status ); - -/* Add the PermMap as a suffix to the result Mapping and then annul - the original Mapping pointers. */ - tmp_map = (AstMapping *) astCmpMap( *map, permmap, 1, "", status ); - (void) astAnnul( *map ); - *map = tmp_map; - permmap = astAnnul( permmap ); - } - -/* Free the permutation arrays. */ - inperm = astFree( inperm ); - outperm = astFree( outperm ); - -/* Free the result axis permutation arrays. */ - result_order = astFree( result_order ); - result_perm = astFree( result_perm ); - } - -/* If necessary, free the results of the first matching process. */ - if ( match1 ) { - template_axes1 = astFree( template_axes1 ); - target_axes1 = astFree( target_axes1 ); - map1 = astAnnul( map1 ); - result1 = astAnnul( result1 ); - } - -/* If necessary, free the results of the second matching process. */ - if ( match2 ) { - template_axes2 = astFree( template_axes2 ); - target_axes2 = astFree( target_axes2 ); - map2 = astAnnul( map2 ); - result2 = astAnnul( result2 ); - } - -/* Annul the pointers to the sub-Frames selected from the target. */ - frame1 = astAnnul( frame1 ); - frame2 = astAnnul( frame2 ); - -/* If an error occurred, free all allocated memory, annul the result - Object pointers and clear all returned values. */ - if ( !astOK ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - *map = astAnnul( *map );; - *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static void PermAxes( AstFrame *this_frame, const int perm[], int *status ) { -/* -* Name: -* PermAxes - -* Purpose: -* Permute the order of a CmpFrame's axes. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void astPermAxes( AstFrame *this, const int perm[], int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astPermAxes method -* inherited from the Frame class). - -* Description: -* This function permutes the order in which a CmpFrame's axes occur. - -* Parameters: -* this -* Pointer to the CmpFrame. -* perm -* An array of int (with one element for each axis of the -* CmpFrame) which lists the axes in their new order. Each -* element of this array should be a (zero-based) axis index -* identifying the axes according to their old (un-permuted) -* order. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Only genuine permutations of the axis order are permitted, so -* each axis must be referenced exactly once in the "perm" array. -* - If more than one axis permutation is applied to a CmpFrame, -* the effects are cumulative. - -* Implementation Notes: -* - This function performs essentially the same operation as the -* Frame member function which it over-rides. However, it operates -* on a "perm" array held in the CmpFrame structure (rather than -* the one in the parent Frame structure). This duplication of the -* array is necessary because the one in the Frame structure is of -* zero length, the number of axes in the Frame structure having -* been set to zero to prevent unnecessary allocation of Axis -* objects which are not needed by the CmpFrame. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - int *old; /* Pointer to copy of old permutation array */ - int axis; /* Loop counter for CmpFrame axes */ - int naxes; /* Number of CmpFrame axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate the permutation array, to check that it describes a - genuine permutation. */ - astCheckPerm( this, perm, "astPermAxes" ); - -/* Obtain the number of CmpFrame axes. */ - naxes = astGetNaxes( this ); - -/* Allocate memory and use it to store a copy of the old permutation - array for the CmpFrame. */ - old = astStore( NULL, this->perm, sizeof( int ) * (size_t) naxes ); - -/* Apply the new axis permutation cumulatively to the old one and - store the result in the CmpFrame. */ - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) { - this->perm[ axis ] = old[ perm[ axis ] ]; - } - } - -/* Free the temporary copy of the old array. */ - old = astFree( old ); -} - -static void PrimaryFrame( AstFrame *this_frame, int axis1, - AstFrame **frame, int *axis2, int *status ) { -/* -* Name: -* PrimaryFrame - -* Purpose: -* Uniquely identify a primary Frame and one of its axes. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void astPrimaryFrame( AstFrame *this, int axis1, AstFrame **frame, -* int *axis2, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected -* astPrimaryFrame method inherited from the Frame class). - -* Description: -* This function returns information about the underlying (primary) -* Frame corresponding to a specified CmpFrame axis. - -* Parameters: -* this -* Pointer to the CmpFrame. -* axis1 -* An axis index (zero-based) identifying the CmpFrame axis for -* which information is required. -* frame -* Address of a location to receive a pointer to the underlying -* (primary) Frame to which the requested axis belongs -* (i.e. this will not be a compound Frame). -* axis2 -* Pointer to an int which is to receive the (zero-based) axis -* index within "frame" which identifies the axis being referred -* to, using the axis order that applied when the primary Frame -* was originally constructed (i.e. this function undoes all -* subsequent axis pemutations and the effects of combining -* Frames, in order to reveal the original underlying axis -* order). -* status -* Pointer to the inherited status variable. - -* Notes: -* - This protected method is provided so that class -* implementations can distinguish the axes of Frames from one -* another (e.g. can distinguish a longitude axis as being -* different from a latitide axis) even after their order has been -* permuted and they have been combined with axes from other -* Frames. -* - The reference count of the primary Frame will be incremented -* by one to reflect the new pointer returned. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - int naxes1; /* Number of axes in frame1 */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate and permute the axis index supplied. */ - axis1 = astValidateAxis( this, axis1, 1, "astPrimaryFrame" ); - -/* Obtain the number of axes in the first component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - if ( astOK ) { - -/* Decide which Frame contains the axis and invoke its astPrimaryFrame - method to obtain the required information. */ - if ( axis1 < naxes1 ) { - astPrimaryFrame( this->frame1, axis1, frame, axis2 ); - } else { - astPrimaryFrame( this->frame2, axis1 - naxes1, frame, axis2 ); - } - } -} - -static int QsortCmpAxes( const void *a, const void *b ) { -/* -* Name: -* QsortCmpAxes - -* Purpose: -* Compare two axis indices for "qsort". - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int QsortCmpAxes( const void *a, const void *b ) - -* Class Membership: -* CmpFrame member function. - -* Description: -* This is a service function for the C RTL routine "qsort". It -* takes the two values supplied and interprets them as integer -* indices into the static "qsort_axes" array. It compares the -* values of these two array elements and returns the result -* required by "qsort". -* -* This function is used when sorting an array of indices so that -* they access the "qsort_axes" array in ascending order. - -* Parameters: -* As required by "qsort". - -* Returned Value: -* As required by "qsort". -*/ - -/* Local Variables. */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - int result; /* Result value to return */ - int val_a; /* First axis index */ - int val_b; /* Second axis index */ - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Convert the values passed by "qsort" into integer array indices and - use these to access the "qsort_axes" array (this pointer to the - array being assigned by the caller of "qsort"). Extract the two - values being compared. */ - val_a = qsort_axes[ *( (const int *) a ) ]; - val_b = qsort_axes[ *( (const int *) b ) ]; - -/* Compare the two values as required by "qsort". */ - if ( val_a < val_b ) { - result = -1; - } else if ( val_a == val_b ) { - result = 0; - } else { - result = 1; - } - -/* Return the result. */ - return result; -} - -static AstMapping *RemoveRegions( AstMapping *this_mapping, int *status ) { -/* -* Name: -* RemoveRegions - -* Purpose: -* Remove any Regions from a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstMapping *RemoveRegions( AstMapping *this, int *status ) - -* Class Membership: -* CmpFrame method (over-rides the astRemoveRegions method inherited -* from the Frame class). - -* Description: -* This function searches the supplied Mapping (which may be a -* compound Mapping such as a CmpMap) for any component Mappings -* that are instances of the AST Region class. It then creates a new -* Mapping from which all Regions have been removed. If a Region -* cannot simply be removed (for instance, if it is a component of a -* parallel CmpMap), then it is replaced with an equivalent UnitMap -* in the returned Mapping. -* -* The implementation provided by the CmpFrame class invokes the -* astRemoveRegions method on the two component Frames, and joins -* the results together into a new CmpFrame. This replaces any Regions -* with their equivalent Frames. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the modified mapping. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstCmpFrame *new; /* Pointer to new CmpFrame */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - AstFrame *newfrm1; /* New first component Frame */ - AstFrame *newfrm2; /* New second component Frame */ - AstMapping *result; /* Result pointer to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the CmpFrame. */ - this = (AstCmpFrame *) this_mapping; - -/* Invoke the astRemoveRegions method on the two component Frames. */ - newfrm1 = astRemoveRegions( this->frame1 ); - newfrm2 = astRemoveRegions( this->frame2 ); - -/* If neither component was modified, just return a clone of the supplied - pointer. */ - if( this->frame1 == newfrm1 && this->frame2 == newfrm2 ) { - result = astClone( this ); - -/* Annul new new Frame pointers. */ - newfrm1 = astAnnul( newfrm1 ); - newfrm2 = astAnnul( newfrm2 ); - -/* Otherwise, we need to create a new CmpFrame to return. */ - } else { - -/* Make a copy of the supplied CmpFrame so that the new CmpFrame retains - any attribute settings of the supplied CmpFrame. */ - new = astCopy( this ); - result = (AstMapping *) new; - -/* Replace the two component Frames with the simplified Frames. */ - (void) astAnnul( new->frame1 ); - (void) astAnnul( new->frame2 ); - new->frame1 = (AstFrame *) newfrm1; - new->frame2 = (AstFrame *) newfrm2; - } - -/* Annul the returned Mapping if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void RenumberAxes( int naxes, int axes[], int *status ) { -/* -* Name: -* RenumberAxes - -* Purpose: -* Renumber axis indices to eliminate missing ones. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void RenumberAxes( int naxes, int axes[], int *status ) - -* Class Membership: -* CmpFrame member function. - -* Description: -* This function takes an array containing a list of (zero-based) -* axis indices referring to the axes of a Frame, some of whose -* axes may not be referenced. It renumbers the axis indices, to -* eliminate any which are missing (i.e. not referenced), while -* preserving the original order. It does this by replacing each -* axis index by its rank (starting at zero) when the indices are -* sorted into ascending order. - -* Parameters: -* naxes -* The number of axis indices present. -* axes -* An array, with "naxes" elements, containing the indices. This -* is modified by this function to contain the new indices. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - int *work; /* Pointer to workspace array */ - int i; /* Loop counter */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Allocate workspace. */ - work = astMalloc( sizeof( int ) * (size_t) naxes ); - if ( astOK ) { - -/* Fill the workspace with indices which address the axis index values - in their natural order. */ - for ( i = 0; i < naxes; i++ ) work[ i ] = i; - -/* Make the "axes" values available to the C RTL function "qsort" via - the static "qsort_axes" pointer. Then use "qsort" to permute the - contents of "work" so that it addresses the axis indices in - ascending order. */ - qsort_axes = axes; - qsort( work, (size_t) naxes, sizeof( int ), QsortCmpAxes ); - -/* Use the result to replace each axis index by its rank when sorted - into ascending order (starting with zero). */ - for ( i = 0; i < naxes; i++ ) axes[ work[ i ] ] = i; - } - -/* Free the workspace array. */ - work = astFree( work ); -} - -static void Resolve( AstFrame *this_frame, const double point1[], - const double point2[], const double point3[], - double point4[], double *d1, double *d2, int *status ){ -/* -* Name: -* Resolve - -* Purpose: -* Resolve a vector into two orthogonal components - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void Resolve( AstFrame *this, const double point1[], -* const double point2[], const double point3[], -* double point4[], double *d1, double *d2, int *status ); - -* Class Membership: -* CmpFrame member function (over-rides the astOffset method -* inherited from the Frame class). - -* Description: -* This function resolves a vector into two perpendicular components. -* The vector from point 1 to point 2 is used as the basis vector. -* The vector from point 1 to point 3 is resolved into components -* parallel and perpendicular to this basis vector. The lengths of the -* two components are returned, together with the position of closest -* aproach of the basis vector to point 3. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vector to be resolved. -* point2 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -* point3 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the vector to be -* resolved. -* point4 -* An array of double, with one element for each Frame axis -* in which the coordinates of the point of closest approach of the -* basis vector to point 3 will be returned. -* d1 -* The address of a location at which to return the distance from -* point 1 to point 4 (that is, the length of the component parallel -* to the basis vector). Positive values are in the same sense as -* movement from point 1 to point 2. -* d2 -* The address of a location at which to return the distance from -* point 4 to point 3 (that is, the length of the component -* perpendicular to the basis vector). The returned value is always -* positive. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Each vector used in this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value, or if the required -* output values are undefined. -*-- -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - const int *perm; /* Pointer to axis permutation array */ - double *p1; /* Permuted coordinates for point1 */ - double *p2; /* Permuted coordinates for point2 */ - double *p3; /* Permuted coordinates for point3 */ - double *p4; /* Permuted coordinates for point4 */ - double d1a; /* Parallel distance in frame1 */ - double d1b; /* Parallel distance in frame2 */ - double d2a; /* Perpendicular distance in frame1 */ - double d2b; /* Perpendicular distance in frame2 */ - double d; /* Total length of basis vector */ - double da; /* Length of basis vector in frame1 */ - double db; /* Length of basis vector in frame2 */ - int axis; /* Loop counter for axes */ - int bad; /* Set bad output coordinates? */ - int naxes1; /* Number of axes in frame1 */ - int naxes; /* Total number of axes in CmpFrame */ - -/* Check the global error status. */ - *d1 = AST__BAD; - *d2 = AST__BAD; - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Obtain the number of axes in the CmpFrame. */ - naxes = astGetNaxes( this ); - -/* Obtain a pointer to the CmpFrame's axis permutation array. */ - perm = astGetPerm( this ); - -/* Allocate workspace. */ - p1 = astMalloc( sizeof( double ) * (size_t) naxes ); - p2 = astMalloc( sizeof( double ) * (size_t) naxes ); - p3 = astMalloc( sizeof( double ) * (size_t) naxes ); - p4 = astMalloc( sizeof( double ) * (size_t) naxes ); - -/* Initialise a flag to indicate whether "bad" coordinates should be - returned. */ - bad = 0; - -/* Initialise ther variables to avoid compiler warnings. */ - da = 0.0; - db = 0.0; - -/* Check that all the coordinates of both input points are OK. If not, - set the "bad" flag and quit checking. */ - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) { - if ( ( point1[ axis ] == AST__BAD ) || - ( point2[ axis ] == AST__BAD ) || - ( point3[ axis ] == AST__BAD ) ) { - bad = 1; - break; - -/* If the coordinates are OK, apply the axis permutation array to - obtain them in the required order. */ - } else { - p1[ perm[ axis ] ] = point1[ axis ]; - p2[ perm[ axis ] ] = point2[ axis ]; - p3[ perm[ axis ] ] = point3[ axis ]; - } - } - } - -/* If OK, obtain the number of axes in the first component Frame. */ - if ( astOK && !bad ) { - naxes1 = astGetNaxes( this->frame1 ); - -/* Find the projection of the required parallel distance into each of the - two Frames. */ - astResolve( this->frame1, p1, p2, p3, p4, &d1a, &d2a ); - astResolve( this->frame2, p1 + naxes1, p2 + naxes1, p3 + naxes1, - p4 + naxes1, &d1b, &d2b ); - -/* Project the first two input points into the two component Frames and - determine the length of the basis vector in each Frame. */ - da = astDistance( this->frame1, p1, p2 ); - db = astDistance( this->frame2, p1 + naxes1, p2 + naxes1 ); - -/* Check that the returned distances are not bad. */ - if ( astOK ) bad = ( bad || ( da == AST__BAD ) || ( db == AST__BAD ) ); - -/* We can tolerate a bad parallel distance within a sub-Frame if the - basis vector has zero length in the sub-Frame, because the bad - parallel distance will have zero weight in the calculation. Set such - bad parallel distanced arbitrarily to zero. */ - if( d1a == AST__BAD && da == 0.0 ) d1a = 0.0; - if( d1b == AST__BAD && db == 0.0 ) d1b = 0.0; - -/* Check that the final parallel distances are not bad. */ - if ( astOK ) bad = ( bad || ( d1a == AST__BAD ) || ( d1b == AST__BAD ) ); - - } - -/* If OK, calculate the total distance between the two points. */ - if ( astOK && !bad ) { - d = sqrt( da * da + db * db ); - -/* If the points are co-incident, then set the "bad" flag. */ - if ( d == 0.0 ) { - bad = 1; - -/* If the points are not co-incident, combine the parallel distances for - the individual Frames into a single parallel distance for the entire - CmpFrame. */ - } else { - *d1 = ( da*d1a + db*d1b )/d; - -/* Offset this distance away from point 1 towards point 2 to get point 4. */ - astOffset( this, point1, point2, *d1, point4 ); - -/* Now find the perpendicular distance (the distance between point4 and - point3). */ - *d2 = astDistance( this, point4, point3 ); - - } - } - -/* Free the workspace arrays. */ - p1 = astFree( p1 ); - p2 = astFree( p2 ); - p3 = astFree( p3 ); - p4 = astFree( p4 ); - -/* If no error has occurred, but bad coordinates must be returned, - then set these in the output array. */ - if ( astOK && bad ) { - *d1 = AST__BAD; - *d2 = AST__BAD; - for ( axis = 0; axis < naxes; axis++ ) point4[ axis ] = AST__BAD; - } - -} - -static AstPointSet *ResolvePoints( AstFrame *this_frame, const double point1[], - const double point2[], AstPointSet *in, - AstPointSet *out, int *status ) { -/* -* Name: -* ResolvePoints - -* Purpose: -* Resolve a set of vectors into orthogonal components - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstPointSet *ResolvePoints( AstFrame *this, const double point1[], -* const double point2[], AstPointSet *in, -* AstPointSet *out ) - -* Class Membership: -* CmpFrame member function (over-rides the astResolvePoints method -* inherited from the Frame class). - -* Description: -* This function takes a CmpFrame and a set of vectors encapsulated -* in a PointSet, and resolves each one into two orthogonal components, -* returning these two components in another PointSet. -* -* This is exactly the same as the public astResolve method, except -* that this method allows many vectors to be processed in a single call, -* thus reducing the computational cost of overheads of many -* individual calls to astResolve. - -* Parameters: -* this -* Pointer to the CmpFrame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vectors to be resolved. -* point2 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -* in -* Pointer to the PointSet holding the ends of the vectors to be -* resolved. -* out -* Pointer to a PointSet which will hold the length of the two -* resolved components. A NULL value may also be given, in which -* case a new PointSet will be created by this function. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. The first axis will -* hold the lengths of the vector components parallel to the basis vector. -* These values will be signed (positive values are in the same sense as -* movement from point 1 to point 2. The second axis will hold the lengths -* of the vector components perpendicular to the basis vector. These -* values will always be positive. - -* Notes: -* - The number of coordinate values per point in the input -* PointSet must match the number of axes in the supplied Frame. -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and 2 coordinate values per point. -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - AstPointSet *in1; /* Pointer to input PointSet for frame1 */ - AstPointSet *in2; /* Pointer to input PointSet for frame2 */ - AstPointSet *out1; /* Pointer to output PointSet for frame1 */ - AstPointSet *out2; /* Pointer to output PointSet for frame2 */ - AstPointSet *result; /* Pointer to output PointSet */ - const int *perm; /* Pointer to axis permutation array */ - double **ptr_in; /* Pointers to input axis values */ - double **ptr_out1; /* Pointers to frame1 component lengths */ - double **ptr_out2; /* Pointers to frame2 component lengths */ - double **ptr_out; /* Pointers to returned component lengths */ - double *d1; /* Pointer to next parallel component value */ - double *d1_1; /* arallel distance in frame1 */ - double *d1_2; /* Parallel distance in frame2 */ - double *d2; /* Pointer to next perpendicular component value */ - double *d2_1; /* Perpendicular distance in frame1 */ - double *d2_2; /* Perpendicular distance in frame2 */ - double *p1; /* Permuted coordinates for point1 */ - double *p2; /* Permuted coordinates for point2 */ - double *p3; /* Supplied vector */ - double *p4; /* Closest approach to supplied vector */ - double b1; /* Length of basis vector in frame1 */ - double b2; /* Length of basis vector in frame2 */ - double b; /* Length of basis vector */ - int axis; /* Loop counter for axes */ - int ipoint; /* Index of next point */ - int nax; /* Number of Frame axes */ - int naxes1; /* Number of axes in frame1 */ - int naxes2; /* Number of axes in frame2 */ - int ncoord_in; /* Number of input PointSet coordinates */ - int ncoord_out; /* Number of coordinates in output PointSet */ - int npoint; /* Number of points to transform */ - int npoint_out; /* Number of points in output PointSet */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialise to prevent compiler "uninitialised use" messages. */ - d1 = NULL; - d2 = NULL; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Obtain the number of axes in the two component Frames */ - naxes1 = astGetNaxes( this->frame1 ); - naxes2 = astGetNaxes( this->frame2 ); - -/* For the total number of axes. */ - nax = naxes1 + naxes2; - -/* Obtain the number of input vectors to resolve and the number of coordinate - values per vector. */ - npoint = astGetNpoint( in ); - ncoord_in = astGetNcoord( in ); - -/* If OK, check that the number of input coordinates matches the number - required by the Frame. Report an error if these numbers do not match. */ - if ( astOK && ( ncoord_in != nax ) ) { - astError( AST__NCPIN, "astResolvePoints(%s): Bad number of coordinate " - "values (%d) in input %s.", status, astGetClass( this ), ncoord_in, - astGetClass( in ) ); - astError( AST__NCPIN, "The %s given requires %d coordinate value(s) for " - "each input point.", status, astGetClass( this ), nax ); - } - -/* If still OK, and a non-NULL pointer has been given for the output PointSet, - then obtain the number of points and number of coordinates per point for - this PointSet. */ - if ( astOK && out ) { - npoint_out = astGetNpoint( out ); - ncoord_out = astGetNcoord( out ); - -/* Check that the dimensions of this PointSet are adequate to accommodate the - output coordinate values and report an error if they are not. */ - if ( astOK ) { - if ( npoint_out < npoint ) { - astError( AST__NOPTS, "astResolvePoints(%s): Too few points (%d) in " - "output %s.", status, astGetClass( this ), npoint_out, - astGetClass( out ) ); - astError( AST__NOPTS, "The %s needs space to hold %d transformed " - "point(s).", status, astGetClass( this ), npoint ); - } else if ( ncoord_out < 2 ) { - astError( AST__NOCTS, "astResolvePoints(%s): Too few coordinate " - "values per point (%d) in output %s.", status, - astGetClass( this ), ncoord_out, astGetClass( out ) ); - astError( AST__NOCTS, "The %s supplied needs space to store 2 " - "coordinate value(s) per transformed point.", status, - astGetClass( this ) ); - } - } - } - -/* If all the validation stages are passed successfully, and a NULL output - pointer was given, then create a new PointSet to encapsulate the output - coordinate data. */ - if ( astOK ) { - if ( !out ) { - result = astPointSet( npoint, 2, "", status ); - -/* Otherwise, use the PointSet supplied. */ - } else { - result = out; - } - } - -/* Store points to the first two axis arrays in the returned PointSet. */ - ptr_out = astGetPoints( result ); - if( astOK ) { - d1 = ptr_out[ 0 ]; - d2 = ptr_out[ 1 ]; - } - -/* Obtain a pointer to the CmpFrame's axis permutation array. This array - holds the original axis index for each current Frame axis index. */ - perm = astGetPerm( this ); - -/* Temporarily permute the coordinates within the supplied PointSet back - in to the axis order which existed when the CmpFrame was created. */ - astPermPoints( in, 0, perm ); - -/* Extract the axis values relevant to each of the two sub-Frames from the - point1 and point2 arrays, at the same time undoing any axis permutation - applied to the CmpFrame as a whole. */ - p1 = astMalloc( sizeof( double )*( size_t )nax ); - p2 = astMalloc( sizeof( double )*( size_t )nax ); - if( astOK ) { - for( axis = 0; axis < nax; axis++ ) { - p1[ perm[ axis ] ] = point1[ axis ]; - p2[ perm[ axis ] ] = point2[ axis ]; - } - } - -/* Project the first two input points into the two component Frames and - determine the length of the basis vector in each Frame. */ - b1 = astDistance( this->frame1, p1, p2 ); - b2 = astDistance( this->frame2, p1 + naxes1, p2 + naxes1 ); - -/* If either of these distances is bad or if both are zero, then fill the - returned PointSet with bad values. */ - if( b1 == AST__BAD || b2 == AST__BAD || ( b1 == 0.0 && b2 == 0.0 ) ) { - for( ipoint = 0; ipoint < npoint; ipoint++, d1++, d2++ ) { - *d1 = AST__BAD; - *d2 = AST__BAD; - } - -/* Otherwise we continue to calculate the resolved components */ - } else if( astOK ){ - -/* Calculate the total distance between the two points. */ - b = sqrt( b1*b1 + b2*b2 ); - -/* Create PointSets holding the input values which refer to each of the - two component Frames. */ - in1 = astPointSet( npoint, naxes1, "", status ); - in2 = astPointSet( npoint, naxes2, "", status ); - -/* Associated the appropriate subset of the data in the supplied input - PointSet with each of these two PointSets. */ - astSetSubPoints( in, 0, 0, in1 ); - astSetSubPoints( in, 0, naxes1, in2 ); - -/* Invoke the astResolvePoints method on each of the sub-Frames. These - invocations create two new PointSets containing the output values. */ - out1 = astResolvePoints( this->frame1, p1, p2, in1, NULL ); - out2 = astResolvePoints( this->frame2, p1 + naxes1, p2 + naxes1, in2, NULL ); - -/* Get pointers to the axis values in these pointsets. */ - ptr_out1 = astGetPoints( out1 ); - ptr_out2 = astGetPoints( out2 ); - -/* More work space */ - p3 = astMalloc( sizeof( double )*( size_t )nax ); - p4 = astMalloc( sizeof( double )*( size_t )nax ); - -/* Get pointers to the input axis values (these are still permuted to - undo any axis permutation applied to the CmpFrame). */ - ptr_in = astGetPoints( in ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Get pointers to the parallel (d1) and perpendiclar (d2) components - within the two sub-Frames (_1 and _2). */ - d1_1 = ptr_out1[ 0 ]; - d2_1 = ptr_out1[ 1 ]; - d1_2 = ptr_out2[ 0 ]; - d2_2 = ptr_out2[ 1 ]; - -/* Loop round each supplied vector. */ - for( ipoint = 0; ipoint < npoint; ipoint++, d1++, d2++, - d1_1++, d2_1++, - d1_2++, d2_2++ ) { - -/* We can tolerate a bad parallel distance within a sub-Frame if the - basis vector has zero length in the sub-Frame, because the bad - parallel distance will have zero weight in the calculation. Set such - bad parallel distanced arbitrarily to zero. */ - if( *d1_1 == AST__BAD && b1 == 0.0 ) *d1_1 = 0.0; - if( *d1_2 == AST__BAD && b2 == 0.0 ) *d1_2 = 0.0; - -/* Combine the parallel distances for the individual Frames into a single - parallel distance for the entire CmpFrame. */ - if( *d1_1 != AST__BAD && *d1_2 != AST__BAD ) { - *d1 = ( b1*(*d1_1) + b2*(*d1_2) )/b; - -/* Offset this distance away from point 1 towards point 2 to get point 4. */ - astOffset( this, p1, p2, *d1, p4 ); - -/* Now find the perpendicular distance (the distance between point4 and - point3). */ - for( axis = 0; axis < nax; axis++ ) p3[ axis ] = ptr_in[ axis ][ ipoint ]; - *d2 = astDistance( this, p4, p3 ); - - } else { - *d1 = AST__BAD; - *d2 = AST__BAD; - } - } - } - -/* Free resources */ - in1 = astAnnul( in1 ); - in2 = astAnnul( in2 ); - out1 = astAnnul( out1 ); - out2 = astAnnul( out2 ); - p3 = astFree( p3 ); - p4 = astFree( p4 ); - } - -/* Free resources */ - p1 = astFree( p1 ); - p2 = astFree( p2 ); - -/* Re-instate the original ordering of the coordinates within the - supplied PointSet. */ - astPermPoints( in, 1, perm ); - -/* Annul the returned PointSet if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static void SetActiveUnit( AstFrame *this_frame, int value, int *status ){ -/* -* Name: -* SetActiveUnit - -* Purpose: -* Specify how the Unit attribute should be used. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void SetActiveUnit( AstFrame *this, int value, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSetActiveUnit method -* inherited from the Frame class). - -* Description: -* This function sets the current value of the ActiveUnit flag for a -* CmpFrame, which controls how the Frame behaves when it is used (by -* astFindFrame) as a template to match another (target) Frame, or is -* used as the "to" Frame by astConvert. It determines if the Mapping -* between the template and target Frames should take differences in -* axis units into account. - -* Parameters: -* this -* Pointer to the CmpFrame. -* value -* The new value to use. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent method to set the ActiveUnitFlag for the CmpFrame, - then set the same value for the component Frames. */ - (*parent_setactiveunit)( this_frame, value, status ); - astSetActiveUnit( ((AstCmpFrame *)this_frame)->frame1, value ); - astSetActiveUnit( ((AstCmpFrame *)this_frame)->frame2, value ); -} - -static void SetFrameFlags( AstFrame *this_frame, int value, int *status ){ -/* -* Name: -* SetFrameFlags - -* Purpose: -* Set flags that control current Frame behaviour. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void SetFrameFlags( AstFrame *this, int value, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSetFrameFlags method -* inherited from the Frame class). - -* Description: -* This function sets values for the bit mask of flags that control -* how the CmpFrame behaves. It ensures that both component Frames use -* the the same bitmask as the parent CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* value -* The new value to use. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent method to set the FrameFlags for the CmpFrame, - then set the same value for the component Frames. */ - (*parent_setframeflags)( this_frame, value, status ); - astSetFrameFlags( ((AstCmpFrame *)this_frame)->frame1, value ); - astSetFrameFlags( ((AstCmpFrame *)this_frame)->frame2, value ); -} - -static int GetActiveUnit( AstFrame *this_frame, int *status ){ -/* -* Name: -* GetActiveUnit - -* Purpose: -* Determines how the Unit attribute will be used. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int GetActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astGetActiveUnit method -* inherited from the Frame class). - -* Description: -* This function returns the current value of the ActiveUnit flag for a -* CmpFrame. See the description of the astSetActiveUnit function -* for a description of the ActiveUnit flag. - -* Parameters: -* this -* Pointer to the CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The current value of the ActiveUnit flag. - -*/ - -/* Local Variables; */ - int result; /* The ActiveUnit flag for the CmpFrame */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* If the ActiveUnit value has been set for the CmpFrame use the parent - implementation to get its value. */ - if( astTestActiveUnit( this_frame ) ) { - result = (*parent_getactiveunit)( this_frame, status ); - -/* Otherwise, the default is determined by the component Frames. If both - components have active units, the default for the CmpFrame is "on" */ - } else { - result = astGetActiveUnit( ((AstCmpFrame *)this_frame)->frame1 ) || - astGetActiveUnit( ((AstCmpFrame *)this_frame)->frame2 ); - } - -/* Return the result */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* CmpFrame member function (extends the astSetAttrib method inherited from -* the Mapping class). - -* Description: -* This function assigns an attribute value for a CmpFrame, the attribute -* and its value being specified by means of a string of the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in lower -* case with no white space present. The value to the right of the "=" -* should be a suitable textual representation of the value to be assigned -* and this will be interpreted according to the attribute's data type. -* White space surrounding the value is only significant for string -* attributes. - -* Parameters: -* this -* Pointer to the CmpFrame. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This protected method is intended to be invoked by the Object astSet -* method and makes additional attributes accessible to it. -*/ - -#define BUF_LEN 1024 - -/* Local Vaiables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - AstFrame *pfrm; /* Pointer to primary Frame containing axis */ - char buf1[BUF_LEN]; /* For for un-indexed attribute name */ - char buf2[BUF_LEN]; /* For for indexed attribute name */ - int axis; /* Supplied (1-base) axis index */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - int oldrep; /* Original error reporting state */ - int paxis; /* Index of primary Frame axis */ - int ok; /* Have we accessed the attribute succesfully? */ - int value; /* Offset to start fo value string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Indicate we have not yet acessed the attribute succesfully. */ - ok = 0; - -/* First check the supplied attribute name against each of the attribute - names defined by this class. In fact there is nothing to do here - since the CmpFrame class currently defines no extra attributes, but - this may change in the future. */ - if( 0 ) { - - - -/* If the attribute is not a CmpFrame specific attribute... */ - } else if( astOK ) { - -/* We want to allow easy access to the attributes of the component Frames. - That is, we do not want it to be necessary to extract a Frame from - its parent CmpFrame in order to access its attributes. For this reason - we first temporarily switch off error reporting so that if an attempt - to access the attribute fails, we can try a different approach. */ - oldrep = astReporting( 0 ); - -/* Our first attempt is to see if the attribute is recognised by the parent - class (Frame). */ - (*parent_setattrib)( this_object, setting, status ); - -/* Indicate success. */ - if( astOK ) { - ok = 1; - -/* Otherwise, clear the error condition so that we can try a different - approach. */ - } else { - astClearStatus; - -/* If the attribute is qualified by an axis index, try accessing it as an - attribute of the primary Frame containing the specified index. */ - if ( nc = 0, - ( 2 == astSscanf( setting, "%[^(=](%d)= %n%*s %n", buf1, &axis, - &value, &nc ) ) && ( nc >= len ) ) { - -/* Find the primary Frame containing the specified axis. */ - astPrimaryFrame( this, axis - 1, &pfrm, &paxis ); - if( astOK ) { - -/* astPrimaryFrame returns the original - unpermuted - axis index within - the primary Frame. So we need to take into account any axis permutation - which has been applied to the primary Frame when forming the attribute name - to use below. Find the permuted (external) axis index which corresponds to - the internal (unpermuted) axis index "paxis". */ - paxis = astValidateAxis( pfrm, paxis, 0, "astSet" ); - -/* Create a new setting with the same name but with the axis index - appropriate to the primary Frame. */ - nc = sprintf( buf2, "%s(%d)=%s", buf1, paxis + 1, - setting+value ); - if( nc < BUF_LEN ) { - -/* Attempt to access the attribute. */ - astSetAttrib( pfrm, buf2 ); - -/* Indicate success. */ - if( astOK ) { - ok = 1; - -/* Otherwise clear the status value, and try again without any axis index. */ - } else { - astClearStatus; - sprintf( buf2, "%s=%s", buf1, setting+value ); - astSetAttrib( pfrm, buf2 ); - -/* Indicate success, or clear the status value. */ - if( astOK ) { - ok = 1; - } else { - astClearStatus; - } - } - -/* Buffer overflow */ - } else if( astOK ) { - astError( AST__INTER, "SetAttrib(CmpFrame): Buffer " - "over-flow (internal AST programming error).", - status ); - } - -/* Free the primary frame pointer. */ - pfrm = astAnnul( pfrm ); - } - -/* If the attribute is not qualified by an axis index, try accessing it - using the primary Frame of each axis in turn. */ - } else { - -/* Loop round all axes attribute. */ - for( axis = 0; axis < astGetNaxes( this ); axis++ ) { - -/* Get the primary Frame containing this axis. */ - astPrimaryFrame( this, axis, &pfrm, &paxis ); - -/* Attempt to access the attribute as an attribute of the primary Frame. */ - astSetAttrib( pfrm, setting ); - -/* Free the primary Frame pointer. */ - pfrm = astAnnul( pfrm ); - -/* Indicate success, or clear the status value. */ - if( astOK ) { - ok = 1; - } else { - astClearStatus; - } - } - } - } - -/* Re-instate the original error reporting state. */ - astReporting( oldrep ); - - } - -/* Report an error if the attribute could not be accessed. */ - if( !ok && astOK ) { - astError( AST__BADAT, "astSet: The attribute setting \"%s\" is invalid " - "for the given %s.", status, setting, astGetClass( this ) ); - } - -#undef BUF_LEN -} - -static void SetAxis( AstFrame *this_frame, int axis, AstAxis *newaxis, int *status ) { -/* -* Name: -* SetAxis - -* Purpose: -* Set a new Axis for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void astSetAxis( AstFrame *this, int axis, AstAxis *newaxis, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSetAxis method -* inherited from the Frame class). - -* Description: -* This function allows a new Axis object to be associated with one -* of the axes of a CmpFrame, replacing the previous one. Each Axis -* object contains a description of the quantity represented along -* one of the CmpFrame's axes, so this function allows this -* description to be exchanged for another one. - -* Parameters: -* this -* Pointer to the CmpFrame. -* axis -* The index (zero-based) of the CmpFrame axis whose associated -* Axis object is to be replaced. -* newaxis -* Pointer to the new Axis object. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - int naxes1; /* Number of axes in frame1 */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate and permute the axis index supplied. */ - axis = astValidateAxis( this, axis, 1, "astSetAxis" ); - -/* Determine the number of axes in the first component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - if ( astOK ) { - -/* Decide which Frame contains the axis and invoke its astSetAxis - method to set the new Axis. */ - if ( axis < naxes1 ) { - astSetAxis( this->frame1, axis, newaxis ); - } else { - astSetAxis( this->frame2, axis - naxes1, newaxis ); - } - } -} - -static void SetDtai( AstFrame *this_frame, double val, int *status ) { -/* -* Name: -* SetDtai - -* Purpose: -* Set the value of the Dtai attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void SetDtai( AstFrame *this, double val, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSetDtai method -* inherited from the Frame class). - -* Description: -* This function sets the Dtai value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* val -* New Dtai value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to set the CmpFrame Dtai value. */ - (*parent_setdtai)( this_frame, val, status ); - -/* Now set the Dtai attribute in the two component Frames. */ - astSetDtai( this->frame1, val ); - astSetDtai( this->frame2, val ); -} - -static void SetDut1( AstFrame *this_frame, double val, int *status ) { -/* -* Name: -* SetDut1 - -* Purpose: -* Set the value of the Dut1 attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void SetDut1( AstFrame *this, double val, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSetDut1 method -* inherited from the Frame class). - -* Description: -* This function sets the Dut1 value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* val -* New Dut1 value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to set the CmpFrame Dut1 value. */ - (*parent_setdut1)( this_frame, val, status ); - -/* Now set the Dut1 attribute in the two component Frames. */ - astSetDut1( this->frame1, val ); - astSetDut1( this->frame2, val ); -} - -static void SetEpoch( AstFrame *this_frame, double val, int *status ) { -/* -* Name: -* SetEpoch - -* Purpose: -* Set the value of the Epoch attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void SetEpoch( AstFrame *this, double val, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSetEpoch method -* inherited from the Frame class). - -* Description: -* This function sets the Epoch value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* val -* New Epoch value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to set the CmpFrame epoch. */ - (*parent_setepoch)( this_frame, val, status ); - -/* Now set the Epoch attribute in the two component Frames. */ - astSetEpoch( this->frame1, val ); - astSetEpoch( this->frame2, val ); -} - -static void SetObsAlt( AstFrame *this_frame, double val, int *status ) { -/* -* Name: -* SetObsAlt - -* Purpose: -* Set the value of the ObsAlt attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void SetObsAlt( AstFrame *this, double val, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSetObsAlt method -* inherited from the Frame class). - -* Description: -* This function sets the ObsAlt value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* val -* New ObsAlt value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to set the CmpFrame ObsAlt. */ - (*parent_setobsalt)( this_frame, val, status ); - -/* Now set the ObsAlt attribute in the two component Frames. */ - astSetObsAlt( this->frame1, val ); - astSetObsAlt( this->frame2, val ); -} - -static void SetObsLat( AstFrame *this_frame, double val, int *status ) { -/* -* Name: -* SetObsLat - -* Purpose: -* Set the value of the ObsLat attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void SetObsLat( AstFrame *this, double val, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSetObsLat method -* inherited from the Frame class). - -* Description: -* This function sets the ObsLat value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* val -* New ObsLat value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to set the CmpFrame ObsLat. */ - (*parent_setobslat)( this_frame, val, status ); - -/* Now set the ObsLat attribute in the two component Frames. */ - astSetObsLat( this->frame1, val ); - astSetObsLat( this->frame2, val ); -} - -static void SetObsLon( AstFrame *this_frame, double val, int *status ) { -/* -* Name: -* SetObsLon - -* Purpose: -* Set the value of the ObsLon attribute for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* void SetObsLon( AstFrame *this, double val, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSetObsLon method -* inherited from the Frame class). - -* Description: -* This function sets the ObsLon value in the component Frames as -* well as this CmpFrame. - -* Parameters: -* this -* Pointer to the CmpFrame. -* val -* New ObsLon value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Invoke the parent method to set the CmpFrame ObsLon. */ - (*parent_setobslon)( this_frame, val, status ); - -/* Now set the ObsLon attribute in the two component Frames. */ - astSetObsLon( this->frame1, val ); - astSetObsLon( this->frame2, val ); -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mapping represented by a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* CmpFrame method (over-rides the astSimplify method inherited -* from the Frame class). - -* Description: -* This function simplifies the Mapping represented by a CmpFrame, -* by using the astSimplify method on each of the component Frames and -* combining the resulting Mappings together. - -* Parameters: -* this -* Pointer to the original CmpFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A new pointer to the simplified CmpFrame. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstCmpFrame *new; /* Pointer to new CmpFrame structure */ - AstCmpFrame *this; /* Pointer to original CmpFrame structure */ - AstMapping *map1; /* Intermediate Mapping */ - AstMapping *map2; /* Intermediate Mapping */ - AstMapping *result; /* Result pointer to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_mapping; - -/* Simplify each of the component Frames. */ - map1 = astSimplify( this->frame1 ); - map2 = astSimplify( this->frame2 ); - -/* Did any usable simplification occur? */ - if( astIsAFrame( map1 ) && astIsAFrame( map2 ) && - ( map1 != (AstMapping *) this->frame1 || - map2 != (AstMapping *) this->frame2 ) ) { - -/* Make a copy of the supplied CmpFrame. */ - new = astCopy( this ); - result = (AstMapping *) new; - -/* Replace the two component Frames with the simplified Frames. */ - (void) astAnnul( new->frame1 ); - (void) astAnnul( new->frame2 ); - new->frame1 = (AstFrame *) map1; - new->frame2 = (AstFrame *) map2; - -/* If no simplication took place, annul the Mapping pointers and return a - clone of the supplied pointer. */ - } else { - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - result= astClone( this ); - } - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) { -/* -* Name: -* SystemCode - -* Purpose: -* Convert a string into a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSystemCode method -* inherited from the Frame class). - -* Description: -* This function converts a string used for the external -* description of a coordinate system into a CmpFrame -* coordinate system type code (System attribute value). It is the -* inverse of the astSystemString function. - -* Parameters: -* this -* The Frame. -* system -* Pointer to a constant null-terminated string containing the -* external description of the coordinate system. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System type code. - -* Notes: -* - A value of AST__BADSYSTEM is returned if the coordinate -* system description was not recognised. This does not produce an -* error. -* - A value of AST__BADSYSTEM is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" string against each possibility and assign the - result. The CmpFrame class only supports a single system "Compound". */ - if ( astChrMatch( "Compound", system ) ) { - result = AST__COMP; - } - -/* Return the result. */ - return result; -} - -static const char *SystemString( AstFrame *this, AstSystemType system, int *status ) { -/* -* Name: -* SystemString - -* Purpose: -* Convert a coordinate system type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* const char *SystemString( AstFrame *this, AstSystemType system, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astSystemString method -* inherited from the Frame class). - -* Description: -* This function converts a CmpFrame coordinate system type code -* (System attribute value) into a string suitable for use as an -* external representation of the coordinate system type. - -* Parameters: -* this -* The Frame. -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. (Where possible, return the same string as would be - used in the FITS WCS representation of the coordinate system). A - CmpFrame only allows a single System value, "Compound". */ - switch ( system ) { - case AST__COMP: - result = "Compound"; - break; - } - -/* Return the result pointer. */ - return result; -} - -static int SubFrame( AstFrame *target_frame, AstFrame *template, - int result_naxes, const int *target_axes, - const int *template_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* SubFrame - -* Purpose: -* Select axes from a CmpFrame and convert to the new coordinate system. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int SubFrame( AstFrame *target, AstFrame *template, -* int result_naxes, const int *target_axes, -* const int *template_axes, AstMapping **map, -* AstFrame **result, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the protected astSubFrame -* method inherited from the Frame class). - -* Description: -* This function selects a requested sub-set (or super-set) of the -* axes from a "target" CmpFrame and creates a new Frame with -* copies of the selected axes assembled in the requested order. It -* then optionally overlays the attributes of a "template" Frame on -* to the result. It returns both the resulting Frame and a Mapping -* that describes how to convert between the coordinate systems -* described by the target and result Frames. If necessary, this -* Mapping takes account of any differences in the Frames' -* attributes due to the influence of the template. - -* Parameters: -* target -* Pointer to the target CmpFrame, from which axes are to be selected. -* template -* Pointer to the template Frame, from which new attributes for -* the result Frame are to be obtained. Optionally, this may be -* NULL, in which case no overlaying of template attributes will -* be performed. -* result_naxes -* Number of axes to be selected from the target Frame. This -* number may be greater than or less than the number of axes in -* this Frame (or equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving -* a list of the (zero-based) axis indices of the axes to be -* selected from the target CmpFrame. The order in which these -* are given determines the order in which the axes appear in -* the result Frame. If any of the values in this array is set -* to -1, the corresponding result axis will not be derived from -* the target Frame, but will be assigned default attributes -* instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This -* should contain a list of the template axes (given as -* zero-based axis indices) with which the axes of the result -* Frame are to be associated. This array determines which axes -* are used when overlaying axis-dependent attributes of the -* template on to the result. If any element of this array is -* set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not -* used and a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned -* Mapping. The forward transformation of this Mapping will -* describe how to convert coordinates from the coordinate -* system described by the target CmpFrame to that described by -* the result Frame. The inverse transformation will convert in -* the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is -* possible between the target and the result Frame. Otherwise zero -* is returned and *map and *result are returned as NULL (but this -* will not in itself result in an error condition). In general, -* coordinate conversion should always be possible if no template -* Frame is supplied but may not always be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. - -* Implementation Deficiencies: -* - It is not clear that the method of handling "extra" axes is -* the best one, nor is the method of setting the "following" flag -* necessarily correct. However, it is also not obvious that this -* feature will ever be needed, so improvements have been left -* until the requirement is clearer. -*/ - -/* Local Variables: */ - AstCmpFrame *target; /* Pointer to target CmpFrame structure */ - AstFrame *sub_result1; /* Pointer to result Frame for frame1 */ - AstFrame *sub_result2; /* Pointer to result Frame for frame2 */ - AstMapping *permmap_pref; /* Pointer to PermMap used as a prefix */ - AstMapping *permmap_suff; /* Pointer to PermMap used as a suffix */ - AstMapping *sub_map1; /* Pointer to Mapping from frame1 */ - AstMapping *sub_map2; /* Pointer to Mapping from frame2 */ - AstMapping *sub_map; /* Pointer to combined component Mappings */ - AstMapping *tmp_map; /* Temporary Mapping pointer */ - const int *perm; /* Pointer to axis permutation array */ - int *frame_choice; /* Pointer to flag array for partitioning */ - int *inperm_pref; /* Pointer to prefix permutation array */ - int *inperm_suff; /* Pointer to suffix permutation array */ - int *outperm_pref; /* Pointer to prefix permutation array */ - int *outperm_suff; /* Pointer to suffix permutation array */ - int *target_axes1; /* Pointer to frame1 axis selection array */ - int *target_axes2; /* Pointer to frame2 axis selection array */ - int *template_axes1; /* Pointer to frame1 template axis array */ - int *template_axes2; /* Pointer to frame2 template axis array */ - int axis_p; /* Permuted axis index */ - int following; /* Associate extra axis and following axis? */ - int i1; /* Count of axes obtained from frame1 */ - int i2; /* Count of axes obtained from frame2 */ - int match; /* Result value to return */ - int n1; /* Number of axes obtained from frame1 */ - int n2; /* Number of axes obtained from frame2 */ - int naxes1; /* Number of axes in frame1 */ - int naxes2; /* Number of axes in frame2 */ - int naxes; /* Number of axes in target */ - int result_axis; /* Result axis index */ - int target_axis; /* Target axis index */ - -/* Initialise the returned values. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the target CmpFrame structure. */ - target = (AstCmpFrame *) target_frame; - -/* Obtain the number of axes in the target CmpFrame and in each of its - component Frames. */ - naxes = astGetNaxes( target ); - naxes1 = astGetNaxes( target->frame1 ); - naxes2 = astGetNaxes( target->frame2 ); - -/* Iinitialise variables to avoid compiler warnings. */ - template_axes1 = NULL; - template_axes2 = NULL; - n1 = 0; - n2 = 0; - -/* Obtain the axis permutation array for the target CmpFrame. */ - perm = astGetPerm( target ); - -/* Determine how any "extra" axes should be associated with existing - axes (i.e. whether to associate with the preceding or following - axis). */ - following = astGetMatchEnd( target ); - -/* Split selected axes into two groups. */ -/* ------------------------------------ */ -/* Allocate a workspace array to hold the choice of component Frame - for each selected target axis. */ - frame_choice = astMalloc( sizeof( int ) * (size_t) result_naxes ); - -/* Obtain an array of flags indicating whether each selected target - axis should be obtained from the first or second component - Frame. */ - PartitionSelection( result_naxes, target_axes, perm, naxes1, naxes2, - frame_choice, following, status ); - -/* Allocate two arrays to hold the axis indices that refer to each of - the component Frames. The maximum number of indices is given by - "result_naxes" (if all the selected axes come from one component - Frame alone). */ - target_axes1 = astMalloc( sizeof( int ) * (size_t) result_naxes ); - target_axes2 = astMalloc( sizeof( int ) * (size_t) result_naxes ); - -/* If a template Frame has been provided, allocate similar arrays to - hold the indices of the two groups of template axes. */ - if ( template ) { - template_axes1 = astMalloc( sizeof( int ) * (size_t) result_naxes ); - template_axes2 = astMalloc( sizeof( int ) * (size_t) result_naxes ); - } - -/* Initialise the count of axes selected from each component Frame. */ - if ( astOK ) { - n1 = n2 = 0; - -/* Loop through each axis index to be selected from the CmpFrame. */ - for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) { - target_axis = target_axes[ result_axis ]; - -/* Determine if the index refers to a valid CmpFrame axis. If it does, - then permute the index, otherwise set it to -1. */ - if ( ( target_axis >= 0 ) && ( target_axis < naxes ) ) { - axis_p = perm[ target_axis ]; - } else { - axis_p = -1; - } - -/* If the axis is to be selected from the first component Frame, store - the index of the axis to be selected. Also store the associated - template axis index (if any). */ - if ( frame_choice[ result_axis ] == 1 ) { - target_axes1[ n1 ] = axis_p; - if ( template ) { - template_axes1[ n1 ] = template_axes[ result_axis ]; - } - -/* Count the axes selected from the first component Frame. */ - n1++; - -/* If the axis is to be selected from the second component Frame, - store the index of the index to be selected (adjusting for the - offset in axis numbering). Also store the associated template axis - index (if any) and count the axes selected. */ - } else { - target_axes2[ n2 ] = ( axis_p == -1 ) ? -1 : axis_p - naxes1; - if ( template ) { - template_axes2[ n2 ] = template_axes[ result_axis ]; - } - n2++; - } - } - } - -/* Select from first component Frame only. */ -/* --------------------------------------- */ -/* If all the selected axes come from the first component Frame, use - that Frame's astSubFrame method to select them (and overlay the - template attributes if required). */ - if ( astOK ) { - if ( n1 && !n2 ) { - sub_map1 = NULL; - match = astSubFrame( target->frame1, template, n1, target_axes1, - template_axes1, &sub_map1, result ); - -/* If this is successful, the "result" Frame will be ready to return - and "sub_map1" will point at a Mapping that converts from the first - component Frame to the "result" Frame. We must now modify this - mapping to account for the CmpFrame's axis permutation array - (i.e. make it refer back to the CmpFrame's original axis order). */ - if ( astOK && match ) { - -/* To do this we must prefix the Mapping with a PermMap which converts - between the target CmpFrame axes and those of the first component - Frame. Allocate space for the permutation arrays required. */ - inperm_pref = astMalloc( sizeof( int ) * (size_t) naxes ); - outperm_pref = astMalloc( sizeof( int ) * (size_t) naxes1 ); - if ( astOK ) { - -/* Permute each target axis index. */ - for ( target_axis = 0; target_axis < naxes; target_axis++ ) { - axis_p = perm[ target_axis ]; - -/* Set up arrays that describe this permutation and its inverse. */ - if ( axis_p < naxes1 ) { - inperm_pref[ target_axis ] = axis_p; - outperm_pref[ axis_p ] = target_axis; - -/* Note which target axes do not correspond with axes in the first - component Frame and assign -1 (so the PermMap will assign "bad" - coordinate values to these axes). */ - } else { - inperm_pref[ target_axis ] = -1; - } - } - -/* Use these permutation arrays to construct the PermMap. Prefix this - to the Mapping obtained earlier to give the final Mapping to be - returned. */ - permmap_pref = - (AstMapping *) astPermMap( naxes, inperm_pref, - naxes1, outperm_pref, NULL, "", status ); - *map = (AstMapping *) astCmpMap( permmap_pref, sub_map1, 1, "", status ); - -/* Annul the PermMap pointer. */ - permmap_pref = astAnnul( permmap_pref ); - } - -/* Free the permutation arrays and annul the original Mapping pointer. */ - inperm_pref = astFree( inperm_pref ); - outperm_pref = astFree( outperm_pref ); - sub_map1 = astAnnul( sub_map1 ); - } - -/* Select from second component Frame only. */ -/* ---------------------------------------- */ -/* If all the selected axes come from the second component Frame, use - that Frame's astSubFrame method to select them (and overlay the - template attributes if required). */ - } else if ( n2 && !n1 ) { - sub_map2 = NULL; - match = astSubFrame( target->frame2, template, n2, target_axes2, - template_axes2, &sub_map2, result ); - -/* If this is successful, the "result" Frame will be ready to return - and "sub_map2" will point at a Mapping that converts from the second - component Frame to the "result" Frame. We must now modify this - mapping to account for the CmpFrame's axis permutation array - (i.e. make it refer back to the CmpFrame's original axis order). */ - if ( astOK && match ) { - -/* To do this we must prefix the Mapping with a PermMap which converts - between the target CmpFrame axes and those of the second component - Frame. Allocate space for the permutation arrays required. */ - inperm_pref = astMalloc( sizeof( int ) * (size_t) naxes ); - outperm_pref = astMalloc( sizeof( int ) * (size_t) naxes2 ); - if ( astOK ) { - -/* Permute each target axis index. */ - for ( target_axis = 0; target_axis < naxes; target_axis++ ) { - axis_p = perm[ target_axis ]; - -/* Set up arrays that describe this permutation and its inverse, - allowing for the shift in axis numbering for the second component - Frame. */ - if ( axis_p >= naxes1 ) { - inperm_pref[ target_axis ] = axis_p - naxes1; - outperm_pref[ axis_p - naxes1 ] = target_axis; - -/* Note which target axes do not correspond with axes in the second - component Frame and assign -1 (so the PermMap will assign "bad" - coordinate values to these axes). */ - } else { - inperm_pref[ target_axis ] = -1; - } - } - -/* Use these permutation arrays to construct the PermMap. Prefix this - to the Mapping obtained earlier to give the final Mapping to be - returned. */ - permmap_pref = - (AstMapping *) astPermMap( naxes, inperm_pref, - naxes2, outperm_pref, NULL, "", status ); - - *map = (AstMapping *) astCmpMap( permmap_pref, sub_map2, 1, "", status ); - -/* Annul the PermMap pointer. */ - permmap_pref = astAnnul( permmap_pref ); - } - -/* Free the permutation arrays and annul the original Mapping pointer. */ - inperm_pref = astFree( inperm_pref ); - outperm_pref = astFree( outperm_pref ); - sub_map2 = astAnnul( sub_map2 ); - } - -/* Select from both component Frames. */ -/* ---------------------------------- */ -/* If the selected axes come from both component Frames, then use both - Frames' astSubFrame methods to select the required axes from each - of them (and overlay the template attributes if required). */ - } else { - sub_map1 = NULL; - sub_map2 = NULL; - sub_result1 = NULL; - sub_result2 = NULL; - match = astSubFrame( target->frame1, template, n1, target_axes1, - template_axes1, &sub_map1, &sub_result1 ); - if ( match ) { - match = astSubFrame( target->frame2, template, n2, target_axes2, - template_axes2, &sub_map2, &sub_result2 ); - } - -/* If this is successful, the two "result" Frames will need to be - combined together (in a CmpFrame) in order to produce the required - result, and the two accompanying Mappings will also need to be - applied in parallel (in a CmpMap). However, the axis order - resulting from this will still not match that required. - - On the target side, this is because of the target's axis - permutation array. On the result side, it is because the result - axes cannot be inter-mingled (as may be required) simply by joining - the Frames and Mappings in parallel. The resulting CmpFrame axes - will therefore need permuting into the required final order. */ - if ( astOK && match ) { - -/* In addition, the Mappings will need to be both prefixed and - suffixed with suitable PermMaps which re-order the axes. Allocate - space for the permutation arrays required. */ - inperm_pref = astMalloc( sizeof( int ) * (size_t) naxes ); - outperm_pref = astMalloc( sizeof( int ) * (size_t) naxes ); - inperm_suff = astMalloc( sizeof( int ) * (size_t) result_naxes ); - outperm_suff = astMalloc( sizeof( int ) * (size_t) result_naxes ); - if ( astOK ) { - -/* Set up permutation arrays to construct the prefix PermMap. This - simply represents the target CmpFrame's axis permutation array and - its inverse. */ - for ( target_axis = 0; target_axis < naxes; target_axis++ ) { - axis_p = perm[ target_axis ]; - inperm_pref[ target_axis ] = axis_p; - outperm_pref[ axis_p ] = target_axis; - } - -/* Set up permutation arrays to construct the suffix PermMap. This - represents the way the original axis selections were partitioned - between the two component frames. */ - i1 = i2 = 0; - for ( result_axis = 0; result_axis < result_naxes; - result_axis++ ) { - -/* For each result axis derived from the first component Frame, set up - permutation array elements to link the output axis with the next - component Frame axis. Count the number of component Frame axes - used. */ - if ( frame_choice[ result_axis ] == 1 ) { - inperm_suff[ i1 ] = result_axis; - outperm_suff[ result_axis ] = i1; - i1++; - -/* Similarly link the axes derived from the second component Frame - with the appropriate axes of that Frame. */ - } else { - inperm_suff[ n1 + i2 ] = result_axis; - outperm_suff[ result_axis ] = n1 + i2; - i2++; - } - } - -/* Combine the Mappings supplied by the two component Frames in - parallel. */ - sub_map = (AstMapping *) astCmpMap( sub_map1, sub_map2, 0, "", status ); - -/* Create the PermMaps which are to be used as a prefix and a suffix. */ - permmap_pref = - (AstMapping *) astPermMap( naxes, inperm_pref, - naxes, outperm_pref, NULL, "", status ); - permmap_suff = - (AstMapping *) astPermMap( result_naxes, inperm_suff, - result_naxes, outperm_suff, - NULL, "", status ); - -/* Add the prefix and suffix PermMaps. */ - tmp_map = (AstMapping *) astCmpMap( permmap_pref, sub_map, - 1, "", status ); - *map = (AstMapping *) astCmpMap( tmp_map, permmap_suff, 1, "", status ); - -/* Annul the Mapping pointers that are no longer required. */ - sub_map = astAnnul( sub_map ); - permmap_pref = astAnnul( permmap_pref ); - permmap_suff = astAnnul( permmap_suff ); - tmp_map = astAnnul( tmp_map ); - -/* Create the result CmpFrame by combining the two component result - Frames and permuting the resulting axes into the required order. */ - *result = (AstFrame *) astCmpFrame( sub_result1, sub_result2, - "", status ); - astPermAxes( *result, outperm_suff ); - -/* ADDED BY DSB (5-FEB-2001). Without this, properties of the target frame - (most importantly, Domain) are not transferred to the result frame. - This results in Frames not matching which should match. - =================================================================== */ - -/* If the result CmpFrame includes all the axes of the target CmpFrame, - then it should inherit any Domain and Title attributes set in the target - CmpFrame. */ - if( result_naxes == naxes ) { - - if( astTestDomain( target ) ) { - astSetDomain( *result, astGetDomain( target ) ); - } - - if( astTestTitle( target ) ) { - astSetTitle( *result, astGetTitle( target ) ); - } - } - -/* End of DSB insertion (5/2/01). - =================================================================== */ - } - -/* Free the temporary permutation arrays. */ - inperm_pref = astFree( inperm_pref ); - inperm_suff = astFree( inperm_suff ); - outperm_pref = astFree( outperm_pref ); - outperm_suff = astFree( outperm_suff ); - } - -/* Annul the Mapping and Frame pointers obtained from each component - Frame. */ - if( sub_map1 ) sub_map1 = astAnnul( sub_map1 ); - if( sub_map2 ) sub_map2 = astAnnul( sub_map2 ); - if( sub_result1 ) sub_result1 = astAnnul( sub_result1 ); - if( sub_result2 ) sub_result2 = astAnnul( sub_result2 ); - } - } - -/* Free the workspace used to store the choice of component Frame and the - axis indices for each component Frame. */ - frame_choice = astFree( frame_choice ); - target_axes1 = astFree( target_axes1 ); - target_axes2 = astFree( target_axes2 ); - -/* If necessary, also free the memory used for the template axis - indices. */ - if ( template ) { - template_axes1 = astFree( template_axes1 ); - template_axes2 = astFree( template_axes2 ); - } - -/* If an error occurred, clean up by annulling the result pointers and - returning appropriate null values. */ - if ( !astOK ) { - *map = astAnnul( *map ); - *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astTestAttrib protected -* method inherited from the Frame class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a CmpFrame's attributes. - -* Parameters: -* this -* Pointer to the CmpFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - AstFrame *pfrm; /* Pointer to primary Frame containing axis */ - char buf1[80]; /* For for un-indexed attribute name */ - char buf2[80]; /* For for indexed attribute name */ - int axis; /* Supplied (1-base) axis index */ - int len; /* Length of attrib string */ - int nc; /* Length of string used so far */ - int oldrep; /* Original error reporting state */ - int paxis; /* Index of primary Frame axis */ - int result; /* Result value to return */ - int ok; /* Has the attribute been accessed succesfully? */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Indicate we have not yet acessed the attribute succesfully. */ - ok = 0; - -/* First check the supplied attribute name against each of the attribute - names defined by this class. In fact there is nothing to do here - since the CmpFrame class currently defines no extra attributes, but - this may change in the future. */ - if( 0 ) { - - - -/* If the attribute is not a CmpFrame specific attribute... */ - } else if( astOK ) { - -/* We want to allow easy access to the attributes of the component Frames. - That is, we do not want it to be necessary to extract a Frame from - its parent CmpFrame in order to access its attributes. For this reason - we first temporarily switch off error reporting so that if an attempt - to access the attribute fails, we can try a different approach. */ - oldrep = astReporting( 0 ); - -/* Our first attempt is to see if the attribute is recognised by the parent - class (Frame). */ - result = (*parent_testattrib)( this_object, attrib, status ); - -/* Indicate success. */ - if( astOK ) { - ok = 1; - -/* Otherwise, clear the error condition so that we can try a different - approach. */ - } else { - astClearStatus; - -/* If the attribute is qualified by an axis index, try accessing it as an - attribute of the primary Frame containing the specified index. */ - if ( nc = 0, - ( 2 == astSscanf( attrib, "%[^(](%d)%n", buf1, &axis, &nc ) ) - && ( nc >= len ) ) { - -/* Find the primary Frame containing the specified axis. */ - astPrimaryFrame( this, axis - 1, &pfrm, &paxis ); - if( astOK ) { - -/* astPrimaryFrame returns the original - unpermuted - axis index within - the primary Frame. So we need to take into account any axis permutation - which has been applied to the primary Frame when forming the attribute name - to use below. Find the permuted (external) axis index which corresponds to - the internal (unpermuted) axis index "paxis". */ - paxis = astValidateAxis( pfrm, paxis, 0, "astTest" ); - -/* Create a new attribute with the same name but with the axis index - appropriate to the primary Frame. */ - sprintf( buf2, "%s(%d)", buf1, paxis + 1 ); - -/* Attempt to access the attribute. */ - result = astTestAttrib( pfrm, buf2 ); - -/* Indicate success. */ - if( astOK ) { - ok = 1; - -/* Otherwise clear the status value, and try again without any axis index. */ - } else { - astClearStatus; - result = astTestAttrib( pfrm, buf1 ); - -/* Indicate success, or clear the status value. */ - if( astOK ) { - ok = 1; - } else { - astClearStatus; - } - } - -/* Free the primary frame pointer. */ - pfrm = astAnnul( pfrm ); - } - -/* If the attribute is not qualified by an axis index, try accessing it - using the primary Frame of each axis in turn. */ - } else { - -/* Loop round all axes, until one is found which defines the specified - attribute. */ - for( axis = 0; axis < astGetNaxes( this ) && !ok; axis++ ) { - -/* Get the primary Frame containing this axis. */ - astPrimaryFrame( this, axis, &pfrm, &paxis ); - -/* Attempt to access the attribute as an attribute of the primary Frame. */ - result = astTestAttrib( pfrm, attrib ); - -/* Indicate success, or clear the status value. */ - if( astOK ) { - ok = 1; - } else { - astClearStatus; - } - -/* Free the primary Frame pointer. */ - pfrm = astAnnul( pfrm ); - - } - } - } - -/* Re-instate the original error reporting state. */ - astReporting( oldrep ); - - } - -/* Report an error if the attribute could not be accessed. */ - if( !ok && astOK ) { - astError( AST__BADAT, "astTest: The %s given does not have an attribute " - "called \"%s\".", status, astGetClass( this ), attrib ); - } - -/* Return the result. */ - return result; - -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astTransform method -* inherited from the Frame class). - -* Description: -* This function takes a CmpFrame and a set of points encapsulated -* in a PointSet, and applies the coordinate transformation equivalent -* to the CmpFrame (this will normally be a UnitMap but may not be if -* the CmpFrame contains any Regions). - -* Parameters: -* this -* Pointer to the CmpFrame. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - The number of coordinate values per point in the input -* PointSet must match the number of axes in the CmpFrame. -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and coordinate values per point to -* accommodate the result (e.g. the number of CmpFrame axes). Any -* excess space will be ignored. -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to original CmpFrame structure */ - AstCmpMap *map2; /* Intermediate Mapping */ - AstCmpMap *map; /* Equivalent Mapping */ - AstPermMap *pmap; /* Intermediate PermMap */ - AstPointSet *result; /* Pointer value to return */ - const int *inperm; /* Pointer to axis permutation array */ - int *outperm; /* Pointer to inverse axis permutation array */ - int i; /* External axis index */ - int naxes; /* Number of axes in CmpFrame */ - int perm; /* Is there an axis permutation to undo? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_mapping; - -/* Form a parallel CmpMap from the two component Frames. */ - map = astCmpMap( this->frame1, this->frame2, 0, "", status ); - -/* The above CmpMap does not take into account any axis permutation - which has been applied to the CmpFrame as a whole (as opposed to axis - permutations applied to the individual component Frames, which are taken - care of by the Transform methods of the individual Frames). Therefore - we need to modify the Mapping by adding a PermMap at the start which - converts from external axis numbering to internal axis numbering, and a - corresponding PermMap at the end which converts from internal to external - axis numbering. Obtain the number of axes in the CmpFrame */ - naxes = astGetNaxes( this ); - -/* Obtain a pointer to the CmpFrame's axis permutation array. This - contains internal axis numbers and is indexed by external axis number. */ - inperm = astGetPerm( this ); - -/* Check if there is any axis permutation to be performed. */ - perm = 0; - for( i = 0; i < naxes; i++ ) { - if( inperm[ i ] != i ) { - perm = 1; - break; - } - } - -/* If so, create an array holding the inverse permutation - one which - contains external axis numbers and is indexed by internal axis number. */ - if( perm ) { - outperm = astMalloc( sizeof( int )*(size_t) naxes ); - if( astOK ) for( i = 0; i < naxes; i++ ) outperm[ inperm[ i ] ] = i; - -/* Create a PermMap from these permutation arrays. The forward - transformation maps from external axis indices to internal axis - indices. */ - pmap = astPermMap( naxes, inperm, naxes, outperm, NULL, "", status ); - outperm = astFree( outperm ); - -/* Combine this PermMap with the CmpMap created above, adding it in the - forward direction at the start and in the inverse direction at the end. */ - map2 = astCmpMap( pmap, map, 1, "", status ); - map = astAnnul( map ); - astInvert( pmap ); - map = astCmpMap( map2, pmap, 1, "", status ); - map2 = astAnnul( map2 ); - pmap = astAnnul( pmap ); - - } - -/* Apply the Mapping to the input PointSet. */ - result = astTransform( map, in, forward, out ); - -/* Annul the Mapping pointer. */ - map = astAnnul( map ); - -/* If an error has occurred and a new PointSet may have been created, then - clean up by annulling it. In any case, ensure that a NULL result is - returned.*/ - if ( !astOK ) { - if ( !out ) result = astAnnul( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -static int Unformat( AstFrame *this_frame, int axis, const char *string, - double *value, int *status ) { -/* -* Name: -* Unformat - -* Purpose: -* Read a formatted coordinate value for a CmpFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* int Unformat( AstFrame *this, int axis, const char *string, -* double *value, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the public astUnformat -* method inherited from the Frame class). - -* Description: -* This function reads a formatted coordinate value for a CmpFrame -* axis (supplied as a string) and returns the equivalent numerical -* value as a double. It also returns the number of characters read -* from the string. - -* Parameters: -* this -* Pointer to the CmpFrame. -* axis -* The number of the CmpFrame axis for which the coordinate -* value is to be read (axis numbering starts at zero for the -* first axis). -* string -* Pointer to a constant null-terminated string containing the -* formatted coordinate value. -* value -* Pointer to a double in which the coordinate value read will be -* returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of characters read from the string to obtain the -* coordinate value. - -* Notes: -* - Any white space at the beginning of the string will be -* skipped, as also will any trailing white space following the -* coordinate value read. The function's return value will reflect -* this. -* - A function value of zero (and no coordinate value) will be -* returned, without error, if the string supplied does not contain -* a suitably formatted value. -* - The string "" is recognised as a special case and will -* generate the value AST__BAD, without error. The test for this -* string is case-insensitive and permits embedded white space. -* - A function result of zero will be returned and no coordinate -* value will be returned via the "value" pointer if this function -* is invoked with the global error status set, or if it should -* fail for any reason. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - AstFrame *frame; /* Pointer to Frame containing axis */ - double coord; /* Coordinate value read */ - int naxes1; /* Number of axes in frame1 */ - int nc; /* Number of characters read */ - int set; /* Digits attribute set? */ - -/* Initialise. */ - nc = 0; - -/* Check the global error status. */ - if ( !astOK ) return nc; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_frame; - -/* Validate and permute the axis index supplied. */ - axis = astValidateAxis( this, axis, 1, "astUnformat" ); - -/* Determine the number of axes in the first component Frame. */ - naxes1 = astGetNaxes( this->frame1 ); - if ( astOK ) { - -/* Decide which component Frame contains the axis and adjust the axis - index if necessary. */ - frame = ( axis < naxes1 ) ? this->frame1 : this->frame2; - axis = ( axis < naxes1 ) ? axis : axis - naxes1; - -/* Since the component Frame is "managed" by the enclosing CmpFrame, - we next test if any Frame attributes which may affect the result - are undefined (i.e. have not been explicitly set). If so, we - over-ride them, giving them temporary values dictated by the - CmpFrame. Only the Digits attribute is potentially relevant - here. */ - set = astTestDigits( frame ); - if ( !set ) astSetDigits( frame, astGetDigits( this ) ); - -/* Invoke the Frame's astUnformat method to read the coordinate value. */ - nc = astUnformat( frame, axis, string, &coord ); - -/* Clear Frame attributes which were temporarily over-ridden. */ - if ( !set ) astClearDigits( frame ); - } - -/* If an error occurred, clear the number of characters read. */ - if ( !astOK ) { - nc = 0; - -/* Otherwise, if characters were read, return the coordinate value. */ - } else if ( nc ) { - *value = coord; - } - -/* Return the number of chracters read. */ - return nc; -} - -static int ValidateSystem( AstFrame *this, AstSystemType system, const char *method, int *status ) { -/* -* -* Name: -* ValidateSystem - -* Purpose: -* Validate a value for a CmpFrame's System attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "cmpframe.h" -* int ValidateSystem( AstFrame *this, AstSystemType system, -* const char *method, int *status ) - -* Class Membership: -* CmpFrame member function (over-rides the astValidateSystem method -* inherited from the Frame class). - -* Description: -* This function checks the validity of the supplied system value. -* If the value is valid, it is returned unchanged. Otherwise, an -* error is reported and a value of AST__BADSYSTEM is returned. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The system value to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The validated system value. - -* Notes: -* - A value of AST__BADSYSTEM will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Validated system value */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the value is out of bounds, report an error. */ - if ( system < FIRST_SYSTEM || system > LAST_SYSTEM ) { - astError( AST__AXIIN, "%s(%s): Bad value (%d) given for the System " - "or AlignSystem attribute of a %s.", status, method, - astGetClass( this ), (int) system, astGetClass( this ) ); - -/* Otherwise, return the supplied value. */ - } else { - result = system; - } - -/* Return the result. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - the axes of a CmpFrame using the private macros defined for this - purpose at the start of this file. */ - -/* Direction(axis). */ -/* ---------------- */ -MAKE_CLEAR(Direction) -MAKE_GET(Direction,int,0,0,0) -MAKE_SET(Direction,int) -MAKE_TEST(Direction) - -/* Format(axis). */ -/* ------------- */ -MAKE_CLEAR(Format) -MAKE_GET(Format,const char *,NULL,0,NULL) -MAKE_SET(Format,const char *) -MAKE_TEST(Format) - -/* Label(axis). */ -/* ------------ */ -MAKE_CLEAR(Label) - -/* Over-ride the default axis labels produced by Frame class objects - and substitute the axis numbering of the enclosing CmpFrame - instead. */ -static const char *label_class; -MAKE_GET(Label,const char *,NULL,( label_class = astGetClass( frame ), - ( astOK && !strcmp( label_class, - "Frame" ) ) ), - ( (void) sprintf( label_buff, "Axis %d", axis + 1 ), label_buff )) -MAKE_SET(Label,const char *) -MAKE_TEST(Label) - -/* Symbol(axis). */ -/* ------------- */ -MAKE_CLEAR(Symbol) - -/* Over-ride the default axis symbols produced by Frame class objects - and substitute the axis numbering of the enclosing CmpFrame - instead. */ -static const char *symbol_class; -MAKE_GET(Symbol,const char *,NULL,( symbol_class = astGetClass( frame ), - ( astOK && !strcmp( symbol_class, - "Frame" ) ) ), - ( (void) sprintf( symbol_buff, "x%d", axis + 1 ), symbol_buff )) -MAKE_SET(Symbol,const char *) -MAKE_TEST(Symbol) - -/* Unit(axis). */ -/* ----------- */ -MAKE_CLEAR(Unit) -MAKE_GET(Unit,const char *,NULL,0,NULL) -MAKE_SET(Unit,const char *) -MAKE_TEST(Unit) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for CmpFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for CmpFrame objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstCmpFrame *in; /* Pointer to input CmpFrame */ - AstCmpFrame *out; /* Pointer to output CmpFrame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output CmpFrames. */ - in = (AstCmpFrame *) objin; - out = (AstCmpFrame *) objout; - -/* Copy the two component Frames. */ - out->frame1 = astCopy( in->frame1 ); - out->frame2 = astCopy( in->frame2 ); - -/* Determine the number of axes and copy the axis permutation - array. */ - out->perm = astStore( NULL, in->perm, sizeof( int ) * - (size_t) GetNaxes( (AstFrame *) in, status ) ); -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for CmpFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for CmpFrame objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error -* status is set. -*/ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to CmpFrame structure */ - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) obj; - -/* Annul the two component Frame pointers. */ - if ( this->frame1 ) this->frame1 = astAnnul( this->frame1 ); - if ( this->frame2 ) this->frame2 = astAnnul( this->frame2 ); - -/* Free the axis permutation array. */ - if ( this->perm ) this->perm = astFree( this->perm ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for CmpFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the CmpFrame class to an output Channel. - -* Parameters: -* this -* Pointer to the CmpFrame whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define COMMENT_LEN 150 /* Maximum length of a comment string */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstCmpFrame *this; /* Pointer to the CmpFrame structure */ - char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment strings */ - char key[ KEY_LEN + 1 ]; /* Buffer for keywords */ - int axis; /* Loop counter for CmpFrame axes */ - int full; /* Full attribute value */ - int full_set; /* Full attribute set? */ - int ival; /* Integer value */ - int naxes; /* Number of CmpFrame axes */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpFrame structure. */ - this = (AstCmpFrame *) this_object; - -/* Write out values representing the instance variables for the - CmpFrame class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Axis permutation array. */ -/* ----------------------- */ -/* Obtain the number of CmpFrame axes. */ - naxes = GetNaxes( (AstFrame *) this, status ); - -/* Write out the CmpFrame axis permutation array value for each axis, - converting to 1-based axis numbering. */ - for ( axis = 0; axis < naxes; axis++ ) { - set = ( this->perm[ axis ] != axis ); - ival = this->perm[ axis ] + 1; - -/* Create a keyword and comment appropriate to the axis. */ - (void) sprintf( key, "Axp%d", axis + 1 ); - if ( set ) { - (void) sprintf( comment, - "Axis %d permuted to use internal axis %d", - axis + 1, ival ); - } else { - (void) sprintf( comment, "Axis %d not permuted", axis + 1 ); - } - astWriteInt( channel, key, set, 0, ival, comment ); - } - -/* Component Frames. */ -/* ----------------- */ -/* Temporarily set the Channel's Full attribute to -1 (unless it is +1 - to start with), remembering the original setting. This prevents any - unnecessary "un-set" Frame values being output that would otherwise - simply duplicate the CmpFrame's attributes which have already been - written. "Set" Frame values are still written, however (and all - values are written if Full is set to 1). */ - full_set = astTestFull( channel ); - full = astGetFull( channel ); - if ( full <= 0 ) astSetFull( channel, -1 ); - -/* Write out Object descriptions for the two component Frames. */ - astWriteObject( channel, "FrameA", 1, 1, this->frame1, - "First component Frame" ); - astWriteObject( channel, "FrameB", 1, 1, this->frame2, - "Second component Frame" ); - -/* Restore the Channel's original Full attribute setting. */ - if ( full_set ) { - astSetFull( channel, full ); - } else { - astClearFull( channel ); - } - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsACmpFrame and astCheckCmpFrame functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(CmpFrame,Frame) -astMAKE_CHECK(CmpFrame) - -AstCmpFrame *astCmpFrame_( void *frame1_void, void *frame2_void, - const char *options, int *status, ...) { -/* -*++ -* Name: -c astCmpFrame -f AST_CMPFRAME - -* Purpose: -* Create a CmpFrame. - -* Type: -* Public function. - -* Synopsis: -c #include "cmpframe.h" -c AstCmpFrame *astCmpFrame( AstFrame *frame1, AstFrame *frame2, -c const char *options, ... ) -f RESULT = AST_CMPFRAME( FRAME1, FRAME2, OPTIONS, STATUS ) - -* Class Membership: -* CmpFrame constructor. - -* Description: -* This function creates a new CmpFrame and optionally initialises -* its attributes. -* -* A CmpFrame is a compound Frame which allows two component Frames -* (of any class) to be merged together to form a more complex -* Frame. The axes of the two component Frames then appear together -* in the resulting CmpFrame (those of the first Frame, followed by -* those of the second Frame). -* -* Since a CmpFrame is itself a Frame, it can be used as a -* component in forming further CmpFrames. Frames of arbitrary -* complexity may be built from simple individual Frames in this -* way. -* -* Also since a Frame is a Mapping, a CmpFrame can also be used as a -* Mapping. Normally, a CmpFrame is simply equivalent to a UnitMap, -* but if either of the component Frames within a CmpFrame is a Region -* (a sub-class of Frame), then the CmpFrame will use the Region as a -* Mapping when transforming values for axes described by the Region. -* Thus input axis values corresponding to positions which are outside the -* Region will result in bad output axis values. - -* Parameters: -c frame1 -f FRAME1 = INTEGER (Given) -* Pointer to the first component Frame. -c frame2 -f FRAME2 = INTEGER (Given) -* Pointer to the second component Frame. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new CmpFrame. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new CmpFrame. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astCmpFrame() -f AST_CMPFRAME = INTEGER -* A pointer to the new CmpFrame. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- - -* Implementation Notes: -* - This function implements the basic CmpFrame constructor which -* is available via the protected interface to the CmpFrame class. -* A public interface is provided by the astCmpFrameId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "frame1" and "frame2" parameters are of type (void *) and are -* converted and validated within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstCmpFrame *new; /* Pointer to new CmpFrame */ - AstFrame *frame1; /* Pointer to first Frame structure */ - AstFrame *frame2; /* Pointer to second Frame structure */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - new = NULL; - if ( !astOK ) return new; - -/* Obtain and validate pointers to the Frame structures provided. */ - frame1 = astCheckFrame( frame1_void ); - frame2 = astCheckFrame( frame2_void ); - if ( astOK ) { - -/* Initialise the CmpFrame, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitCmpFrame( NULL, sizeof( AstCmpFrame ), !class_init, - &class_vtab, "CmpFrame", frame1, frame2 ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - CmpFrame's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new CmpFrame. */ - return new; -} - -AstCmpFrame *astCmpFrameId_( void *frame1_void, void *frame2_void, - const char *options, ... ) { -/* -* Name: -* astCmpFrameId_ - -* Purpose: -* Create a CmpFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpframe.h" -* AstCmpFrame *astCmpFrameId_( void *frame1_void, void *frame2_void, -* const char *options, ... ) - -* Class Membership: -* CmpFrame constructor. - -* Description: -* This function implements the external (public) interface to the -* astCmpFrame constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astCmpFrame_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). For the same reason, the "frame1" and "frame2" -* parameters are of type (void *) and are converted and validated -* within the function itself. -* -* The variable argument list also prevents this function from -* invoking astCmpFrame_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. - -* Parameters: -* As for astCmpFrame_. - -* Returned Value: -* The ID value associated with the new CmpFrame. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstCmpFrame *new; /* Pointer to new CmpFrame */ - AstFrame *frame1; /* Pointer to first Frame structure */ - AstFrame *frame2; /* Pointer to second Frame structure */ - va_list args; /* Variable argument list */ - - int *status; /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - new = NULL; - if ( !astOK ) return new; - -/* Obtain the Frame pointers from the ID's supplied and validate the - pointers to ensure they identify valid Frames. */ - frame1 = astVerifyFrame( astMakePointer( frame1_void ) ); - frame2 = astVerifyFrame( astMakePointer( frame2_void ) ); - if ( astOK ) { - -/* Initialise the CmpFrame, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitCmpFrame( NULL, sizeof( AstCmpFrame ), !class_init, - &class_vtab, "CmpFrame", frame1, frame2 ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - CmpFrame's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new CmpFrame. */ - return astMakeId( new ); -} - -AstCmpFrame *astInitCmpFrame_( void *mem, size_t size, int init, - AstCmpFrameVtab *vtab, const char *name, - AstFrame *frame1, AstFrame *frame2, int *status ) { -/* -*+ -* Name: -* astInitCmpFrame - -* Purpose: -* Initialise a CmpFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpframe.h" -* AstCmpFrame *astInitCmpFrame( void *mem, size_t size, int init, -* AstCmpFrameVtab *vtab, const char *name, -* AstFrame *frame1, AstFrame *frame2 ) - -* Class Membership: -* CmpFrame initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new CmpFrame object. It allocates memory (if -* necessary) to accommodate the CmpFrame plus any additional data -* associated with the derived class. It then initialises a -* CmpFrame structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual -* function table for a CmpFrame at the start of the memory passed -* via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the CmpFrame is to be -* created. This must be of sufficient size to accommodate the -* CmpFrame data (sizeof(CmpFrame)) plus any data used by the -* derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the CmpFrame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the CmpFrame structure, so a valid value must be -* supplied even if not required for allocating memory. -* init -* A logical flag indicating if the CmpFrame's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new CmpFrame. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the Object astClass function). -* frame1 -* Pointer to the first Frame to be included in the new CmpFrame. -* frame2 -* Pointer to the second Frame to be included in the new CmpFrame. - -* Returned Value: -* A pointer to the new CmpFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstCmpFrame *new; /* Pointer to new CmpFrame */ - int axis; /* Loop counter for axes */ - int naxes; /* Number of CmpFrame axes */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitCmpFrameVtab( vtab, name ); - -/* Initialise a Frame structure (the parent class) as the first - component within the CmpFrame structure, allocating memory if - necessary. Set the number of Frame axes to zero, since all axis - information is stored within the component Frames. */ - new = (AstCmpFrame *) astInitFrame( mem, size, 0, (AstFrameVtab *) vtab, - name, 0 ); - - if ( astOK ) { - -/* Initialise the CmpFrame data. */ -/* ----------------------------- */ -/* Clone the component Frame pointers. */ - new->frame1 = astClone( frame1 ); - new->frame2 = astClone( frame2 ); - -/* Determine the number of CmpFrame axes. */ - naxes = astGetNaxes( frame1 ) + astGetNaxes( frame2 ); - -/* Allocate memory to hold the axis permutation array and initialise - this array. */ - new->perm = astMalloc( sizeof( int ) * (size_t) naxes ); - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) new->perm[ axis ] = axis; - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstCmpFrame *astLoadCmpFrame_( void *mem, size_t size, - AstCmpFrameVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadCmpFrame - -* Purpose: -* Load a CmpFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpframe.h" -* AstCmpFrame *astLoadCmpFrame( void *mem, size_t size, -* AstCmpFrameVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* CmpFrame loader. - -* Description: -* This function is provided to load a new CmpFrame using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* CmpFrame structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the CmpFrame is to be -* loaded. This must be of sufficient size to accommodate the -* CmpFrame data (sizeof(CmpFrame)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the CmpFrame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the CmpFrame structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstCmpFrame) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new CmpFrame. If this is NULL, a pointer -* to the (static) virtual function table for the CmpFrame class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "CmpFrame" is used instead. - -* Returned Value: -* A pointer to the new CmpFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstCmpFrame *new; /* Pointer to the new CmpFrame */ - char key[ KEY_LEN + 1 ]; /* Buffer for keywords */ - int axis; /* Loop counter for axes */ - int naxes; /* Number of CmpFrame axes */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this CmpFrame. In this case the - CmpFrame belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstCmpFrame ); - vtab = &class_vtab; - name = "CmpFrame"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitCmpFrameVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built CmpFrame. */ - new = astLoadFrame( mem, size, (AstFrameVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "CmpFrame" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Component Frames. */ -/* ----------------- */ -/* Read both component Frames, supplying a default 1-dimensional Frame - if necessary. */ - new->frame1 = astReadObject( channel, "framea", NULL ); - if ( !new->frame1 ) new->frame1 = astFrame( 1, "", status ); - - new->frame2 = astReadObject( channel, "frameb", NULL ); - if ( !new->frame2 ) new->frame2 = astFrame( 1, "", status ); - -/* Axis permutation array. */ -/* ----------------------- */ -/* Obtain the number of CmpFrame axes and allocate memory to hold the - axis permutation array. */ - naxes = GetNaxes( (AstFrame *) new, status ); - new->perm = astMalloc( sizeof( int ) * (size_t) naxes ); - -/* If OK, loop to read the array value for each axis. */ - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) { - -/* Convert from 1-based to zero-based axis numbering at this - point. The default is the "un-permuted" value. */ - sprintf( key, "axp%d", axis + 1 ); - new->perm[ axis ] = astReadInt( channel, key, axis + 1 ) - 1; - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - } - -/* If an error occurred, clean up by deleting the new CmpFrame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new CmpFrame pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - diff --git a/ast/cmpframe.h b/ast/cmpframe.h deleted file mode 100644 index f692aa1..0000000 --- a/ast/cmpframe.h +++ /dev/null @@ -1,428 +0,0 @@ -#if !defined( CMPFRAME_INCLUDED ) /* Include this file only once */ -#define CMPFRAME_INCLUDED -/* -*+ -* Name: -* cmpframe.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the CmpFrame class. - -* Invocation: -* #include "cmpframe.h" - -* Description: -* This include file defines the interface to the CmpFrame class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. -* -* A CmpFrame is a compound Frame which allows two component Frames -* (of any class) to be merged together to form a more complex -* Frame. The axes of the two component Frames then appear together -* in the resulting CmpFrame (those of the first Frame, followed by -* those of the second Frame). -* -* Since a CmpFrame is itself a Frame, it can be used as a -* component in forming further CmpFrames. Frames of arbitrary -* complexity may be built from simple individual Frames in this -* way. - -* Inheritance: -* The CmpFrame class inherits from the Frame class. - -* Attributes Over-Ridden: -* Domain (string) -* A string which may be used to identify a CmpFrame and used as -* an additional key when matching a target CmpFrame with a -* template. The CmpFrame class re-defines the default value to -* "CMP". -* MaxAxes (integer) -* Specifies the maximum number of axes in a target Frame that -* can be matched when using the CmpFrame as a template. The -* CmpFrame class sets this to be the sum of the MaxAxes -* attribute values for the two component Frames contained by -* the CmpFrame. Any attempt to alter this value (other than -* through the component Frames) is simply ignored. -* MinAxes (integer) -* Specifies the minimum number of axes in a target Frame that -* can be matched when using the CmpFrame as a template. The -* CmpFrame class sets this to be the sum of the MinAxes -* attribute values for the two component Frames contained by -* the CmpFrame. Any attempt to alter this value (other than -* through the component Frames) is simply ignored. -* Naxes (integer) -* A read-only attribute that gives the number of axes in a -* CmpFrame (i.e. the number of dimensions of the space which -* the CmpFrame describes). This value is determined when the -* CmpFrame is created and is equal to the sum of the Naxes -* attributes of the two component Frames. -* Title (string) -* Specifies a string to be used as a title on (e.g.) graphs to -* describe the coordinate system which the CmpFrame -* represents. The CmpFrame class re-defines the default value -* to "-D Compound Coordinate System", where is the -* number of CmpFrame axes. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* astDistance -* Calculate the distance between two points. -* astFormat -* Format a coordinate value for a CmpFrame axis. -* astNorm -* Normalise a set of CmpFrame coordinates. -* astOffset -* Calculate an offset along a geodesic curve. -* astPermAxes -* Permute the order of a CmpFrame's axes. -* astUnformat -* Read a formatted coordinate value for a CmpFrame axis. -* -* Protected: -* astAbbrev -* Abbreviate a formatted CmpFrame axis value by skipping leading -* fields. -* astClearDirection -* Clear the value of the Direction attribute for a CmpFrame axis. -* astClearFormat -* Clear the value of the Format attribute for a CmpFrame axis. -* astClearLabel -* Clear the value of the Label attribute for a CmpFrame axis. -* astClearMaxAxes -* Clear the value of the MaxAxes attribute for a CmpFrame. -* astClearMinAxes -* Clear the value of the MinAxes attribute for a CmpFrame. -* astClearSymbol -* Clear the value of the Symbol attribute for a CmpFrame axis. -* astClearUnit -* Clear the value of the Unit attribute for a CmpFrame axis. -* astGap -* Find a "nice" gap for tabulating CmpFrame axis values. -* astGetAxis -* Obtain a pointer to a specified Axis from a CmpFrame. -* astGetDirection -* Obtain the value of the Direction attribute for a CmpFrame axis. -* astGetDomain -* Obtain a pointer to the Domain attribute string for a CmpFrame. -* astGetFormat -* Obtain the value of the Format attribute for a CmpFrame axis. -* astGetLabel -* Obtain the value of the Label attribute for a CmpFrame axis. -* astGetMaxAxes -* Obtain the value of the MaxAxes attribute for a CmpFrame. -* astGetMinAxes -* Obtain the value of the MinAxes attribute for a CmpFrame. -* astGetNaxes -* Obtain the value of the Naxes attribute for a CmpFrame. -* astGetPerm -* Access the axis permutation array for a CmpFrame. -* astGetSymbol -* Obtain the value of the Symbol attribute for a CmpFrame axis. -* astGetTitle -* Obtain a pointer to the Title attribute string for a CmpFrame. -* astGetUnit -* Obtain the value of the Unit attribute for a CmpFrame axis. -* astMatch -* Determine if conversion is possible between two coordinate -* systems. -* astPrimaryFrame -* Uniquely identify a primary Frame and one of its axes. -* astSetAxis -* Set a new Axis for a CmpFrame. -* astSetDirection -* Set the value of the Direction attribute for a CmpFrame axis. -* astSetFormat -* Set the value of the Format attribute for a CmpFrame axis. -* astSetLabel -* Set the value of the Label attribute for a CmpFrame axis. -* astSetMaxAxes -* Set a value for the MaxAxes attribute of a CmpFrame. -* astSetMinAxes -* Set a value for the MinAxes attribute of a CmpFrame. -* astSetSymbol -* Set the value of the Symbol attribute for a CmpFrame axis. -* astSetUnit -* Set the value of the Unit attribute for a CmpFrame axis. -* astSubFrame -* Select axes from a CmpFrame and convert to the new coordinate -* system. -* astTestDirection -* Test if a Direction attribute value has been set for a CmpFrame -* axis. -* astTestFormat -* Test if a Format attribute value has been set for a CmpFrame axis. -* astTestLabel -* Test if a Label attribute value has been set for a CmpFrame axis. -* astTestMaxAxes -* Test if a value has been set for the MaxAxes attribute of a -* CmpFrame. -* astTestMinAxes -* Test if a value has been set for the MinAxes attribute of a -* CmpFrame. -* astTestSymbol -* Test if a Symbol attribute value has been set for a CmpFrame axis. -* astTestUnit -* Test if a Unit attribute value has been set for a CmpFrame axis. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsACmpFrame -* Test class membership. -* astCmpFrame -* Create a CmpFrame. -* -* Protected: -* astCheckCmpFrame -* Validate class membership. -* astInitCmpFrame -* Initialise a CmpFrame. -* astInitCmpFrameVtab -* Initialise the virtual function table for the CmpFrame class. -* astLoadCmpFrame -* Load a CmpFrame. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstCmpFrame -* CmpFrame object type. -* -* Protected: -* AstCmpFrameVtab -* CmpFrame virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 6-MAR-1996 (RFWS): -* Original version. -* 27-FEB-1997 (RFWS): -* Improved the prologue. -* 25-FEB-1998 (RFWS): -* Over-ride the astUnformat method. -* 8-JAN-2003 (DSB): -* Added protected astInitCmpFrameVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "frame.h" /* Parent Frame class */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros. */ -/* ------- */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -#if defined(astCLASS) /* Protected */ - -/* The legal System values recognized by this class of Frame. */ -#define AST__COMP 0 - -#endif - -/* Type Definitions. */ -/* ================= */ -/* CmpFrame structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstCmpFrame { - -/* Attributes inherited from the parent class. */ - AstFrame frame; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstFrame *frame1; /* First component frame */ - AstFrame *frame2; /* Second component Frame */ - int *perm; /* Pointer to axis permutation array */ -} AstCmpFrame; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstCmpFrameVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstFrameVtab frame_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - -} AstCmpFrameVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstCmpFrameGlobals { - AstCmpFrameVtab Class_Vtab; - int Class_Init; - int *qsort_axes; - char Label_Buff[ 101 ]; - char Symbol_Buff[ 51 ]; - char GetDomain_Buff[ 101 ]; - char GetTitle_Buff[ 101 ]; -} AstCmpFrameGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(CmpFrame) /* Check class membership */ -astPROTO_ISA(CmpFrame) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstCmpFrame *astCmpFrame_( void *, void *, const char *, int *, ...); -#else -AstCmpFrame *astCmpFrameId_( void *, void *, const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstCmpFrame *astInitCmpFrame_( void *, size_t, int, AstCmpFrameVtab *, - const char *, AstFrame *, AstFrame *, int * ); - -/* Vtab initialiser. */ -void astInitCmpFrameVtab_( AstCmpFrameVtab *, const char *, int * ); - -/* Loader. */ -AstCmpFrame *astLoadCmpFrame_( void *, size_t, AstCmpFrameVtab *, - const char *, AstChannel *, int * ); -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitCmpFrameGlobals_( AstCmpFrameGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckCmpFrame(this) astINVOKE_CHECK(CmpFrame,this,0) -#define astVerifyCmpFrame(this) astINVOKE_CHECK(CmpFrame,this,1) - -/* Test class membership. */ -#define astIsACmpFrame(this) astINVOKE_ISA(CmpFrame,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astCmpFrame astINVOKE(F,astCmpFrame_) -#else -#define astCmpFrame astINVOKE(F,astCmpFrameId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitCmpFrame(mem,size,init,vtab,name,frame1,frame2) \ -astINVOKE(O,astInitCmpFrame_(mem,size,init,vtab,name,astCheckFrame(frame1),astCheckFrame(frame2),STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitCmpFrameVtab(vtab,name) astINVOKE(V,astInitCmpFrameVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadCmpFrame(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadCmpFrame_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckCmpFrame to validate CmpFrame pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#endif - - - - - diff --git a/ast/cmpframe.pdf b/ast/cmpframe.pdf deleted file mode 100644 index 8d81909..0000000 Binary files a/ast/cmpframe.pdf and /dev/null differ diff --git a/ast/cmpmap.c b/ast/cmpmap.c deleted file mode 100644 index d0210ec..0000000 --- a/ast/cmpmap.c +++ /dev/null @@ -1,4739 +0,0 @@ -/* -*class++ -* Name: -* CmpMap - -* Purpose: -* Compound Mapping. - -* Constructor Function: -c astCmpMap -f AST_CMPMAP - -* Description: -* A CmpMap is a compound Mapping which allows two component -* Mappings (of any class) to be connected together to form a more -* complex Mapping. This connection may either be "in series" -* (where the first Mapping is used to transform the coordinates of -* each point and the second mapping is then applied to the -* result), or "in parallel" (where one Mapping transforms the -* earlier coordinates for each point and the second Mapping -* simultaneously transforms the later coordinates). -* -* Since a CmpMap is itself a Mapping, it can be used as a -* component in forming further CmpMaps. Mappings of arbitrary -* complexity may be built from simple individual Mappings in this -* way. - -* Inheritance: -* The CmpMap class inherits from the Mapping class. - -* Attributes: -* The CmpMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c The CmpMap class does not define any new functions beyond those -f The CmpMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 1-FEB-1996 (RFWS): -* Original version. -* 25-SEP-1996 (RFWS): -* Implemented external interface and I/O facilities. -* 12-DEC-1996 (RFWS): -* Over-ride the astMapList method. -* 13-DEC-1996 (RFWS): -* Over-ride the astSimplify method. -* 4-JUN-1997 (RFWS): -* Eliminate any simplification when MapList is used. Instead, -* over-ride the MapMerge method and implement all -* simplification in this. -* 24-MAR-1998 (RFWS): -* Fixed bug in testing of simplified invert flag in Simplify. -* 15-APR-1998 (RFWS): -* Improved the MapMerge method to allow parallel combinations -* of series CmpMaps to be replaced by series combinations of -* parallel CmpMaps, and vice versa. -* 26-SEP-2001 (DSB): -* Over-ride the astDecompose method. -* 8-JAN-2003 (DSB): -* - Changed private InitVtab method to protected astInitCmpMapVtab -* method. -* 8-JAN-2003 (DSB): -* - Modified MapMerge so that a parallel CmpMap can swap with a -* suitable PermMap lower neighbour. -* 23-APR-2004 (DSB): -* - Modified Simplify to avoid infinite loops. -* 27-APR-2004 (DSB): -* - Correction to MapMerge to prevent segvio if CmpMap and PermMap -* cannot be swapped. -* 4-OCT-2004 (DSB): -* Modify astMapList to return flag indicating presence of inverted -* CmpMaps in supplied Mapping. -* 20-APR-2005 (DSB): -* Modify MapMerge so that it will attempt to merge the first -* and second CmpMaps in a list of series CmpMaps. -* 8-FEB-2006 (DSB): -* Corrected logic within MapMerge for cases where a PermMap is -* followed by a parallel CmpMap. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 14-MAR-2006 (DSB): -* - When checking for patterns in the simplification process, -* require at least 30 samples in the waveform for evidence of a -* pattern. -* - Override astEqual. -* - The constructor no longer reports an error if the resulting -* CmpMap cannot transform points in either direction. This is -* because it may be possible to simplify such a CmpMap and the -* simplified Mapping may have defined transformations. E.g. if a -* Mapping which has only a forward transformation is combined in -* series with its own inverse, the combination will simplify to a -* UnitMap (usually). -* 9-MAY-2006 (DSB): -* - In Simplify, remove checks for patterns in the number of atomic -* mappings when calling astSimplify recursively. -* 23-AUG-2006 (DSB): -* - In Simplify, add checks for re-appearance of a Mapping that is -* already being simplified at a higher levelin the call stack. -* 18-APR-2007 (DSB): -* In Simplify: if the returned Mapping is not a CmpMap, always copy -* the returned component Mapping (rather than cloning it) so that -* the returned Mapping is not affected if user code subsequently -* inverts the component Mapping via some other pointer. -* 12-MAR-2008 (DSB): -* Modify MapSplit so that attempts to split the inverse -* transformation if it cannot split the forward transformation. -* 30-JUL-2009 (DSB): -* Ensure the PermMap has equal number of inputs and outputs when -* swapping a PermMap and a CmpMap in astMapMerge. -* 3-JAN-2011 (DSB): -* In MapSplit, certain classes of Mapping (e.g. PermMaps) can -* produce a returned Mapping with zero outputs. Consider such -* Mappings to be unsplitable. -* 11-JAN-2011 (DSB): -* Improve simplification of serial combinations of parellel CmpMaps. -* 25-JAN-2011 (DSB): -* Big improvement to the efficiency of the astMapSplit method. -* 24-JAN-2012 (DSB): -* If efficient MapSplit fails to split (e.g. due to the presence -* of PermMaps), then revert to the older slower method. -* 5-FEB-2013 (DSB): -* Take account of Invert flags when combining parallel CmpMaps in -* series. -* 29-APR-2013 (DSB): -* In MapList, use the astDoNotSimplify method to check that it is -* OK to expand the CmpMap. -* 23-APR-2015 (DSB): -* In Simplify, prevent mappings that are known to cause infinite -* loops from being nominated for simplification. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS CmpMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "permmap.h" /* Coordinate permutation Mappings */ -#include "unitmap.h" /* Unit transformations */ -#include "cmpmap.h" /* Interface definition for this class */ -#include "frameset.h" /* Interface definition for FrameSets */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int (* parent_maplist)( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int *(* parent_mapsplit)( AstMapping *, int, const int *, AstMapping **, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->Simplify_Depth = 0; \ - globals->Simplify_Stackmaps = NULL; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(CmpMap) - -#define class_init astGLOBAL(CmpMap,Class_Init) -#define class_vtab astGLOBAL(CmpMap,Class_Vtab) -#define simplify_depth astGLOBAL(CmpMap,Simplify_Depth) -#define simplify_stackmaps astGLOBAL(CmpMap,Simplify_Stackmaps) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static int simplify_depth = 0; -static AstMapping **simplify_stackmaps = NULL; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstCmpMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstCmpMap *astCmpMapId_( void *, void *, int, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *CombineMaps( AstMapping *, int, AstMapping *, int, int, int * ); -static AstMapping *RemoveRegions( AstMapping *, int * ); -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); -static int *MapSplit0( AstMapping *, int, const int *, AstMapping **, int, int * ); -static int *MapSplit1( AstMapping *, int, const int *, AstMapping **, int * ); -static int *MapSplit2( AstMapping *, int, const int *, AstMapping **, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetIsLinear( AstMapping *, int * ); -static int MapList( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int PatternCheck( int, int, int **, int *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Decompose( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static int GetObjSize( AstObject *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Member functions. */ -/* ================= */ -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two CmpMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* CmpMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two CmpMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a CmpMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the CmpMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpMap *that; - AstCmpMap *this; - AstMapping **that_map_list; - AstMapping **this_map_list; - int *that_invert_list; - int *this_invert_list; - int i; - int result; - int that_inv; - int that_nmap; - int this_inv; - int this_nmap; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two CmpMap structures. */ - this = (AstCmpMap *) this_object; - that = (AstCmpMap *) that_object; - -/* Check the second object is a CmpMap. We know the first is a - CmpMap since we have arrived at this implementation of the virtual - function. */ - if( astIsACmpMap( that ) ) { - -/* Check they are both either parallel or series. */ - if( that->series == that->series ) { - -/* Decompose the first CmpMap into a sequence of Mappings to be applied in - series or parallel, as appropriate, and an associated list of - Invert flags. */ - this_nmap = 0; - this_map_list = NULL; - this_invert_list = NULL; - astMapList( (AstMapping *) this, this->series, astGetInvert( this ), - &this_nmap, &this_map_list, &this_invert_list ); - -/* Similarly decompose the second CmpMap. */ - that_nmap = 0; - that_map_list = NULL; - that_invert_list = NULL; - astMapList( (AstMapping *) that, that->series, astGetInvert( that ), - &that_nmap, &that_map_list, &that_invert_list ); - -/* Check the decompositions yielded the same number of component - Mappings. */ - if( that_nmap == this_nmap ) { - -/* Check equality of every component. */ - for( i = 0; i < this_nmap; i++ ) { - -/* Temporarily set the Mapping Invert flags to the required values, - saving the original values so that they can be re-instated later.*/ - this_inv = astGetInvert( this_map_list[ i ] ); - astSetInvert( this_map_list[ i ], this_invert_list[ i ] ); - that_inv = astGetInvert( that_map_list[ i ] ); - astSetInvert( that_map_list[ i ], that_invert_list[ i ] ); - -/* Compare the two component Mappings for equality. */ - result = astEqual( this_map_list[ i ], that_map_list[ i ] ); - -/* Re-instate the original Invert flags. */ - astSetInvert( this_map_list[ i ], this_inv ); - astSetInvert( that_map_list[ i ], that_inv ); - -/* Leave the loop if the Mappings are not equal. */ - if( !result ) break; - } - } - -/* Free resources */ - for( i = 0; i < this_nmap; i++ ) { - this_map_list[ i ] = astAnnul( this_map_list[ i ] ); - } - this_map_list = astFree( this_map_list ); - this_invert_list = astFree( this_invert_list ); - - for( i = 0; i < that_nmap; i++ ) { - that_map_list[ i ] = astAnnul( that_map_list[ i ] ); - } - that_map_list = astFree( that_map_list ); - that_invert_list = astFree( that_invert_list ); - - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetIsLinear( AstMapping *this_mapping, int *status ){ -/* -* Name: -* GetIsLinear - -* Purpose: -* Return the value of the IsLinear attribute for a CmpMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GetIsLinear( AstMapping *this, int *status ) - -* Class Membership: -* CmpMap member function (over-rides the protected astGetIsLinear -* method inherited from the Mapping class). - -* Description: -* This function returns the value of the IsLinear attribute for a -* Frame, which is one if both component Mappings have a value of 1 -* for the IsLinear attribute. - -* Parameters: -* this -* Pointer to the CmpqMap. -* status -* Pointer to the inherited status variable. -*/ - AstCmpMap *this; - this = (AstCmpMap *) this_mapping; - return astGetIsLinear( this->map1 ) && astGetIsLinear( this->map2 ); -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* CmpMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied CmpMap, -* in bytes. - -* Parameters: -* this -* Pointer to the CmpMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpMap *this; /* Pointer to CmpMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the CmpMap structure. */ - this = (AstCmpMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astGetObjSize( this->map1 ); - result += astGetObjSize( this->map2 ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static AstMapping *CombineMaps( AstMapping *mapping1, int invert1, - AstMapping *mapping2, int invert2, - int series, int *status ) { -/* -* Name: -* CombineMaps - -* Purpose: -* Combine two Mappings with specified Invert flags into a CmpMap. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* AstMapping *CombineMaps( AstMapping *mapping1, int invert1, -* AstMapping *mapping2, int invert2, -* int series, int *status ) - -* Class Membership: -* CmpMap member function. - -* Description: -* This function combines two Mappings into a CmpMap (compound -* Mapping) as if their Invert flags were set to specified values -* when the CmpMap is created. However, the individual Mappings are -* returned with their Invert flag values unchanged from their -* original state. - -* Parameters: -* mapping1 -* Pointer to the first Mapping. -* invert1 -* The (boolean) Invert flag value required for the first Mapping. -* mapping2 -* Pointer to the second Mapping. -* invert2 -* The (boolean) Invert flag value required for the second Mapping. -* series -* Whether the Mappings are to be combined in series (as opposed to -* in parallel). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the resulting compound Mapping (a CmpMap). - -* Notes: -* - This function is a wrap-up for the astCmpMap constructor and -* temporarily assigns the required Invert flag values while -* creating the required CmpMap. However, it also takes account of -* the possibility that the two Mapping pointers supplied may point -* at the same Mapping. -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *map1; /* First temporary Mapping pointer */ - AstMapping *map2; /* Second temporary Mapping pointer */ - AstMapping *result; /* Pointer to result Mapping */ - int copy; /* Copy needed? */ - int inv1; /* First original Invert flag value */ - int inv2; /* Second original Invert flag value */ - int set1; /* First Invert flag originally set? */ - int set2; /* Second Invert flag originally set? */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Limit incoming values to 0 or 1. */ - invert1 = ( invert1 != 0 ); - invert2 = ( invert2 != 0 ); - -/* Obtain the Invert flag values for each Mapping. */ - inv1 = astGetInvert( mapping1 ); - inv2 = astGetInvert( mapping2 ); - -/* Also determine if these values are explicitly set. */ - set1 = astTestInvert( mapping1 ); - set2 = astTestInvert( mapping2 ); - -/* If both Mappings are actually the same but we need different Invert - flag values to be set, then this can only be achieved by making a - copy. Note if this is necessary. */ - copy = ( ( mapping1 == mapping2 ) && ( invert1 != invert2 ) ); - -/* Clone the first Mapping pointer. Do likewise for the second but - make a copy instead if necessary. */ - map1 = astClone( mapping1 ); - map2 = copy ? astCopy( mapping2 ) : astClone( mapping2 ); - -/* If the Invert value for the first Mapping needs changing, make the - change. */ - if ( invert1 != inv1 ) { - if ( invert1 ) { - astSetInvert( map1, 1 ); - } else { - astClearInvert( map1 ); - } - } - -/* Similarly, change the Invert flag for the second Mapping if - necessary. */ - if ( invert2 != inv2 ) { - if ( invert2 ) { - astSetInvert( map2, 1 ); - } else { - astClearInvert( map2 ); - } - } - -/* Combine the two Mappings into a CmpMap. */ - result = (AstMapping *) astCmpMap( map1, map2, series, "", status ); - -/* If the first Mapping's Invert value was changed, restore it to its - original state. */ - if ( invert1 != inv1 ) { - if ( set1 ) { - astSetInvert( map1, inv1 ); - } else { - astClearInvert( map1 ); - } - } - -/* Similarly, restore the second Mapping's Invert value if - necessary. This step is not needed, however, if a copy was made. */ - if ( ( invert2 != inv2 ) && !copy ) { - if ( set2 ) { - astSetInvert( map2, inv2 ); - } else { - astClearInvert( map2 ); - } - } - -/* Annul the temporary Mapping pointers. */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - -/* If an error occurred, then annul the result pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void Decompose( AstMapping *this_mapping, AstMapping **map1, - AstMapping **map2, int *series, int *invert1, - int *invert2, int *status ) { -/* -* -* Name: -* Decompose - -* Purpose: -* Decompose a Mapping into two component Mappings. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void Decompose( AstMapping *this, AstMapping **map1, -* AstMapping **map2, int *series, -* int *invert1, int *invert2, int *status ) - -* Class Membership: -* CmpMap member function (over-rides the protected astDecompose -* method inherited from the Mapping class). - -* Description: -* This function returns pointers to two Mappings which, when applied -* either in series or parallel, are equivalent to the supplied Mapping. -* -* Since the Frame class inherits from the Mapping class, Frames can -* be considered as special types of Mappings and so this method can -* be used to decompose either CmpMaps or CmpFrames. - -* Parameters: -* this -* Pointer to the Mapping. -* map1 -* Address of a location to receive a pointer to first component -* Mapping. -* map2 -* Address of a location to receive a pointer to second component -* Mapping. -* series -* Address of a location to receive a value indicating if the -* component Mappings are applied in series or parallel. A non-zero -* value means that the supplied Mapping is equivalent to applying map1 -* followed by map2 in series. A zero value means that the supplied -* Mapping is equivalent to applying map1 to the lower numbered axes -* and map2 to the higher numbered axes, in parallel. -* invert1 -* The value of the Invert attribute to be used with map1. -* invert2 -* The value of the Invert attribute to be used with map2. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Any changes made to the component Mappings using the returned -* pointers will be reflected in the supplied Mapping. - -*- -*/ - - -/* Local Variables: */ - AstCmpMap *this; /* Pointer to CmpMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpMap structure. */ - this = (AstCmpMap *) this_mapping; - -/* First deal with series mappings. */ - if( this->series ) { - if( series ) *series = 1; - -/* If the CmpMap has been inverted, return the Mappings in reverse - order with inverted Invert falgs. */ - if( astGetInvert( this ) ) { - if( map1 ) *map1 = astClone( this->map2 ); - if( map2 ) *map2 = astClone( this->map1 ); - if( invert1 ) *invert1 = this->invert2 ? 0 : 1; - if( invert2 ) *invert2 = this->invert1 ? 0 : 1; - -/* If the CmpMap has not been inverted, return the Mappings in their - original order with their original Invert flags. */ - } else { - if( map1 ) *map1 = astClone( this->map1 ); - if( map2 ) *map2 = astClone( this->map2 ); - if( invert1 ) *invert1 = this->invert1; - if( invert2 ) *invert2 = this->invert2; - } - -/* Now deal with parallel mappings. */ - } else { - if( series ) *series = 0; - -/* The mappings are returned in their original order whether or not the - CmpMap has been inverted. */ - if( map1 ) *map1 = astClone( this->map1 ); - if( map2 ) *map2 = astClone( this->map2 ); - -/* If the CmpMap has been inverted, return inverted Invert flags. */ - if( astGetInvert( this ) ) { - if( invert1 ) *invert1 = this->invert1 ? 0 : 1; - if( invert2 ) *invert2 = this->invert2 ? 0 : 1; - -/* If the CmpMap has not been inverted, return the original Invert flags. */ - } else { - if( invert1 ) *invert1 = this->invert1; - if( invert2 ) *invert2 = this->invert2; - } - - } -} - -void astInitCmpMapVtab_( AstCmpMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitCmpMapVtab - -* Purpose: -* Initialise a virtual function table for a CmpMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpmap.h" -* void astInitCmpMapVtab( AstCmpMapVtab *vtab, const char *name ) - -* Class Membership: -* CmpMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the CmpMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsACmpMap) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -/* None. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_maplist = mapping->MapList; - mapping->MapList = MapList; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_mapsplit = mapping->MapSplit; - mapping->MapSplit = MapSplit; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->Decompose = Decompose; - mapping->MapMerge = MapMerge; - mapping->Simplify = Simplify; - mapping->RemoveRegions = RemoveRegions; - mapping->GetIsLinear = GetIsLinear; - -/* For some reason the CmpMap implementation of astRate can be immensely - slow for complex Mapping, so it's currently disable until such time as - I have time to sort it out. - - mapping->Rate = Rate; -*/ - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "CmpMap", "Compound Mapping" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* CmpMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstCmpMap *this; /* Pointer to CmpMap structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the CmpMap structure. */ - this = (AstCmpMap *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->map1, mode, extra, fail ); - if( !result ) result = astManageLock( this->map2, mode, extra, fail ); - - return result; - -} -#endif - -static int MapList( AstMapping *this_mapping, int series, int invert, - int *nmap, AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapList - -* Purpose: -* Decompose a CmpMap into a sequence of simpler Mappings. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapList( AstMapping *this, int series, int invert, int *nmap, -* AstMapping ***map_list, int **invert_list ) - -* Class Membership: -* CmpMap member function (over-rides the protected astMapList -* method inherited from the Maping class). - -* Description: -* This function decomposes a CmpMap into a sequence of simpler -* Mappings which may be applied in sequence to achieve the same -* effect. The CmpMap is decomposed as far as possible, but it is -* not guaranteed that this will necessarily yield any more than -* one Mapping, which may actually be the original CmpMap supplied. -* -* This function is provided to support both the simplification of -* CmpMaps, and the analysis of CmpMap structure so that particular -* forms can be recognised. - -* Parameters: -* this -* Pointer to the CmpMap to be decomposed (the CmpMap is not -* actually modified by this function). -* series -* If this value is non-zero, an attempt will be made to -* decompose the CmpMap into a sequence of equivalent Mappings -* which can be applied in series (i.e. one after the other). If -* it is zero, the decomposition will instead yield Mappings -* which can be applied in parallel (i.e. on successive sub-sets -* of the input/output coordinates). -* invert -* The value to which the CmpMap's Invert attribute is to be -* (notionally) set before performing the -* decomposition. Normally, the value supplied here will be the -* actual Invert value obtained from the CmpMap (e.g. using -* astGetInvert). Sometimes, however, when a CmpMap is -* encapsulated within another structure, that structure may -* retain an Invert value (in order to prevent external -* interference) which should be used instead. -* -* Note that the actual Invert value of the CmpMap supplied is -* not used (or modified) by this function. -* nmap -* The address of an int which holds a count of the number of -* individual Mappings in the decomposition. On entry, this -* should count the number of Mappings already in the -* "*map_list" array (below). On exit, it is updated to include -* any new Mappings appended by this function. -* map_list -* Address of a pointer to an array of Mapping pointers. On -* entry, this array pointer should either be NULL (if no -* Mappings have yet been obtained) or should point at a -* dynamically allocated array containing Mapping pointers -* ("*nmap" in number) which have been obtained from a previous -* invocation of this function. -* -* On exit, the dynamic array will be enlarged to contain any -* new Mapping pointers that result from the decomposition -* requested. These pointers will be appended to any previously -* present, and the array pointer will be updated as necessary -* to refer to the enlarged array (any space released by the -* original array will be freed automatically). -* -* The new Mapping pointers returned will identify a sequence of -* Mappings which, when applied in order, will perform a forward -* transformation equivalent to that of the original CmpMap -* (after its Invert flag has first been set to the value -* requested above). The Mappings should be applied in series or -* in parallel according to the type of decomposition requested. -* -* All the Mapping pointers returned by this function should be -* annulled by the caller, using astAnnul, when no longer -* required. The dynamic array holding these pointers should -* also be freed, using astFree. -* invert_list -* Address of a pointer to an array of int. On entry, this array -* pointer should either be NULL (if no Mappings have yet been -* obtained) or should point at a dynamically allocated array -* containing Invert attribute values ("*nmap" in number) which -* have been obtained from a previous invocation of this -* function. -* -* On exit, the dynamic array will be enlarged to contain any -* new Invert attribute values that result from the -* decomposition requested. These values will be appended to any -* previously present, and the array pointer will be updated as -* necessary to refer to the enlarged array (any space released -* by the original array will be freed automatically). -* -* The new Invert values returned identify the values which must -* be assigned to the Invert attributes of the corresponding -* Mappings (whose pointers are in the "*map_list" array) before -* they are applied. Note that these values may differ from the -* actual Invert attribute values of these Mappings, which are -* not relevant. -* -* The dynamic array holding these values should be freed by the -* caller, using astFree, when no longer required. - -* Returned Value: -* A non-zero value is returned if the supplied Mapping contained any -* inverted CmpMaps. - -* Notes: -* - It is unspecified to what extent the original CmpMap and the -* individual (decomposed) Mappings are -* inter-dependent. Consequently, the individual Mappings cannot be -* modified without risking modification of the original CmpMap. -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then the *nmap value, the -* list of Mapping pointers and the list of Invert values will all -* be returned unchanged. -*/ - -/* Local Variables: */ - AstCmpMap *this; /* Pointer to CmpMap structure */ - int invert1; /* Invert flag for first component Mapping */ - int invert2; /* Invert flag for second component Mapping */ - int r1; /* Value returned from first map list */ - int r2; /* Value returned from second map list */ - int result; /* Returned value */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the CmpMap structure. */ - this = (AstCmpMap *) this_mapping; - -/* Check if the CmpMap combines its component Mappings in the same way - (series or parallel) as the decomposition requires. Also, do not - expand CmpMaps that are not appropriate for simplification. */ - if ( this->series == series && !astDoNotSimplify( this ) ) { - -/* If so, obtain the Invert attribute values to be applied to each - component Mapping. */ - invert1 = this->invert1; - invert2 = this->invert2; - -/* If the CmpMap itself is inverted, also invert the Invert values to be - applied to its components. */ - if ( invert ) { - invert1 = !invert1; - invert2 = !invert2; - } - -/* If the component Mappings are applied in series, then concatenate - the Mapping lists obtained from each of them. Do this in reverse - order if the CmpMap is inverted, since the second Mapping would be - applied first in this case. */ - if ( series ) { - if ( !invert ) { - r1 = astMapList( this->map1, series, invert1, - nmap, map_list, invert_list ); - r2 = astMapList( this->map2, series, invert2, - nmap, map_list, invert_list ); - } else { - r1 = astMapList( this->map2, series, invert2, - nmap, map_list, invert_list ); - r2 = astMapList( this->map1, series, invert1, - nmap, map_list, invert_list ); - } - -/* If the component Mappings are applied in parallel, then concatenate - the Mapping lists obtained from each of them. In this case, - inverting the CmpMap has no effect on the order in which they are - applied. */ - } else { - r1 = astMapList( this->map1, series, invert1, - nmap, map_list, invert_list ); - r2 = astMapList( this->map2, series, invert2, - nmap, map_list, invert_list ); - } - -/* Did we find any inverted CmpMaps? */ - result = invert || r1 || r2; - -/* If the CmpMap does not combine its components in the way required - by the decomposition (series or parallel), then we cannot decompose - it. In this case it must be appended to the Mapping list as a - single entity. We can use the parent class method to do this. */ - } else { - result = ( *parent_maplist )( this_mapping, series, invert, nmap, - map_list, invert_list, status ); - } - - return result; -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a CmpMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list ) - -* Class Membership: -* CmpMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated CmpMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated CmpMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated CmpMap which is to be merged with -* its neighbours. This should be a cloned copy of the CmpMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* CmpMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated CmpMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpMap *cmpmap1; /* Pointer to first CmpMap */ - AstCmpMap *cmpmap2; /* Pointer to second CmpMap */ - AstCmpMap *cmpmap; /* Pointer to nominated CmpMap */ - AstCmpMap *new_cm; /* Pointer to new CmpMap */ - AstMapping **map_list1; /* Pointer to list of cmpmap1 component Mappings */ - AstMapping **map_list2; /* Pointer to list of cmpmap2 component Mappings */ - AstMapping **new_map_list; /* Extended Mapping list */ - AstMapping *map; /* Pointer to nominated CmpMap */ - AstMapping *new1; /* Pointer to new CmpMap */ - AstMapping *new2; /* Pointer to new CmpMap */ - AstMapping *new; /* Pointer to replacement Mapping */ - AstMapping *simp1; /* Pointer to simplified Mapping */ - AstMapping *simp2; /* Pointer to simplified Mapping */ - AstMapping *submap1; /* A subset of mappings from cmpmap1 */ - AstMapping *submap2; /* A subset of mappings from cmpmap2 */ - AstMapping *tmap2; /* Temporary Mapping */ - AstMapping *tmap; /* Temporary Mapping */ - AstPermMap *new_pm; /* Pointer to new PermMap */ - AstPermMap *permmap1; /* Pointer to first PermMap */ - AstUnitMap *unit; /* UnitMap that feeds const PermMap i/p's */ - const char *class; /* Pointer to Mapping class string */ - double *conperm; /* Pointer to PermMap constants array */ - double *const_new; /* Pointer to new PermMap constants array */ - double *p; /* Pointer to PermMap input position */ - double *q; /* Pointer to PermMap output position */ - double *qa; /* Pointer to 1st component output position */ - double *qb; /* Pointer to 2nd component output position */ - int *inperm; /* Pointer to copy of PermMap inperm array */ - int *inperm_new; /* Pointer to new PermMap inperm array */ - int *invert_list1; /* Pointer to list of cmpmap1 invert values */ - int *invert_list2; /* Pointer to list of cmpmap2 invert values */ - int *new_invert_list; /* Extended Invert flag list */ - int *outperm; /* Pointer to copy of PermMap outperm array */ - int *outperm_new; /* Pointer to new PermMap outperm array */ - int aconstants; /* Are all 1st component outputs constant? */ - int bconstants; /* Are all 2nd component outputs constant? */ - int canswap; /* Can nominated Mapping swap with lower neighbour? */ - int i; /* Coordinate index */ - int iconid; /* Constant identifier in supplied PermMap */ - int imap1; /* Index of first Mapping */ - int imap2; /* Index of second Mapping */ - int imap; /* Loop counter for Mappings */ - int invert1; /* Invert flag for first CmpMap */ - int invert1a; /* Invert flag for sub-Mapping */ - int invert1b; /* Invert flag for sub-Mapping */ - int invert2; /* Invert flag for second CmpMap */ - int invert2a; /* Invert flag for sub-Mapping */ - int invert2b; /* Invert flag for sub-Mapping */ - int invert; /* Invert attribute value */ - int j; /* Coordinate index */ - int jmap1; /* Index of next component Mapping in cmpmap1 */ - int jmap2; /* Index of next component Mapping in cmpmap2 */ - int new_invert; /* New Invert attribute value */ - int nin2a; /* No. input coordinates for sub-Mapping */ - int nin2b; /* No. input coordinates for sub-Mapping */ - int nmap1; /* Number of Mappings in cmpmap1 */ - int nmap2; /* Number of Mappings in cmpmap2 */ - int nout2a; /* No. of outputs for 1st component Mapping */ - int nout2b; /* No. of outputs for 2nd component Mapping */ - int npin; /* No. of inputs for original PermMap */ - int npin_new; /* No. of inputs for new PermMap */ - int npout; /* No. of outputs for original PermMap */ - int npout_new; /* No. of outputs for new PermMap */ - int nunit; /* No. of PermMap i/p's fed by UnitMap */ - int oconid; /* Constant identifier in returned PermMap */ - int result; /* Result value to return */ - int set; /* Invert attribute set? */ - int simpler; /* Simplification possible? */ - int subin2; /* Number of inputs of submap2 */ - int subinv1; /* Invert attribute to use with submap1 */ - int subinv2; /* Invert attribute to use with submap2 */ - int subout1; /* Number of outputs of submap1 */ - -/* Initialise.*/ - result = -1; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Simplify the CmpMap on its own. */ -/* =============================== */ -/* Obtain a pointer to the nominated Mapping (which is a CmpMap). */ - map = ( *map_list )[ where ]; - cmpmap = (AstCmpMap *) map; - -/* Determine if the Mapping's Invert attribute is set and obtain its - value. */ - set = astTestInvert( map ); - invert = astGetInvert( map ); - -/* If necessary, change the Invert attribute to the value we want. We - do this so that simplification (below) has a chance to absorb a - non-zero Invert value into the implementation of the simplified - Mapping (the preference being to have an Invert value of zero after - simplification, if possible). */ - if ( invert != ( *invert_list )[ where ] ) { - astSetInvert( map, ( *invert_list )[ where ] ); - } - -/* Simplify the Mapping and obtain the new Invert value. */ - new = astSimplify( map ); - new_invert = astGetInvert( new ); - -/* If necessary, restore the original Mapping's Invert attribute to - its initial state. */ - if ( invert != ( *invert_list )[ where ] ) { - if ( set ) { - astSetInvert( map, invert ); - } else { - astClearInvert( map ); - } - } - -/* We must now determine if simplification has occurred. Since this is - internal code, we can compare the two Mapping pointers directly to - see whether "astSimplify" just cloned the pointer we gave it. If it - did, then simplification was probably not possible, but check to - see if the Invert attribute has changed to be sure. */ - if ( astOK ) { - simpler = ( new != map ) || ( new_invert != ( *invert_list )[ where ] ); - -/* If simplification was successful, annul the original pointer in the - Mapping list and replace it with the new one, together with its - invert flag. */ - if ( simpler ) { - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = new; - ( *invert_list )[ where ] = new_invert; - -/* Return the result. */ - result = where; - -/* Otherwise, annul the new Mapping pointer. */ - } else { - new = astAnnul( new ); - -/* If the nominated CmpMap is a series CmpMap and the sequence of - Mappings are being combined in series, or if the nominated CmpMap is - a parallel CmpMap and the sequence of Mappings are being combined in - parallel, replace the single CmpMap with the two component Mappings. */ - if( ( series && cmpmap->series ) || - ( !series && !cmpmap->series ) ) { - -/* We are increasing the number of Mappings in the list, so we need to create - new, larger, arrays to hold the list of Mapping pointers and invert flags. */ - new_map_list = astMalloc( ( *nmap + 1 )*sizeof( AstMapping * ) ); - new_invert_list = astMalloc( ( *nmap + 1 )*sizeof( int ) ); - if( astOK ) { - -/* Copy the values prior to the nominated CmpMap. */ - for( i = 0; i < where; i++ ) { - new_map_list[ i ] = astClone( ( *map_list )[ i ] ); - new_invert_list[ i ] = ( *invert_list )[ i ]; - } - -/* Next insert the two components of the nominated CmpMap */ - new_map_list[ where ] = astClone( cmpmap->map1 ); - new_invert_list[ where ] = cmpmap->invert1; - new_map_list[ where + 1 ] = astClone( cmpmap->map2 ); - new_invert_list[ where + 1 ] = cmpmap->invert2; - -/* Now copy any values after the nominated CmpMap. */ - for( i = where + 1; i < *nmap; i++ ) { - new_map_list[ i + 1 ] = astClone( ( *map_list )[ i ] ); - new_invert_list[ i + 1 ] = ( *invert_list )[ i ]; - } - -/* Now annul the Object pointers in the supplied map list. */ - for( i = 0; i < *nmap; i++ ) { - (* map_list )[ i ] = astAnnul( ( *map_list )[ i ] ); - } - -/* Free the memory holding the supplied Mapping and invert flag lists. */ - astFree( *map_list ); - astFree( *invert_list ); - -/* Return pointers to the new extended lists. */ - *map_list = new_map_list; - *invert_list = new_invert_list; - -/* Increase the number of Mappings in the list, and the index of - the first modified Mapping. */ - (*nmap)++; - result = where; - -/* Indicate some simplification has taken place */ - simpler = 1; - } - } - } - -/* If no simplification has been done, merge adjacent CmpMaps. */ -/* ========================================================== */ -/* If the CmpMap would not simplify on its own, we now look for a - neighbouring CmpMap with which it might merge. We use the previous - Mapping, if suitable, since this will normally also have been fully - simplified on its own. Check if a previous Mapping exists. */ - if( !simpler ) { - if ( astOK && *nmap > 1 ) { - -/* Obtain the indices of the two potential Mappings to be merged. imap1 - is the first Mapping, imap2 is the second. imapc is the CmpMap, imapn is - the neighbouring Mapping. */ - if( where == 0 ) { - imap1 = 0; - imap2 = 1; - } else { - imap1 = where - 1; - imap2 = where; - } - -/* Obtain the Class string of the neighbouring Mapping and determine if it - is a CmpMap. */ - class = astGetClass( ( *map_list )[ (where>0)?where-1:1 ] ); - if ( astOK && !strcmp( class, "CmpMap" ) ) { - -/* If suitable, obtain pointers to the two CmpMaps. */ - cmpmap1 = (AstCmpMap *) ( *map_list )[ imap1 ]; - cmpmap2 = (AstCmpMap *) ( *map_list )[ imap2 ]; - -/* Obtain the associated invert flag values. */ - invert1 = ( *invert_list )[ imap1 ]; - invert2 = ( *invert_list )[ imap2 ]; - -/* Extract the invert flags associated with each CmpMap sub-Mapping - and combine these with the flag values obtained above so as to give - the invert flag to be used with each individual sub-Mapping. */ - invert1a = cmpmap1->invert1; - invert1b = cmpmap1->invert2; - if ( invert1 ) { - invert1a = !invert1a; - invert1b = !invert1b; - } - invert2a = cmpmap2->invert1; - invert2b = cmpmap2->invert2; - if ( invert2 ) { - invert2a = !invert2a; - invert2b = !invert2b; - } - -/* Series CmpMaps in parallel. */ -/* =========================== */ -/* Now check if the CmpMaps can be merged. This may be possible if we - are examining a list of Mappings combined in parallel and the two - adjacent CmpMaps both combine their sub-Mappings in series. */ - if ( !series && cmpmap1->series && cmpmap2->series ) { - -/* Form two new parallel CmpMaps with the sub-Mappings re-arranged so - that when combined in series these new CmpMaps are equivalent to - the original ones. In doing this, we must take account of the - invert flags which apply to each sub-Mapping and also of the fact - that the order in which the sub-Mappings are applied depends on the - invert flags of the original CmpMaps. */ - new1 = CombineMaps( invert1 ? cmpmap1->map2 : cmpmap1->map1, - invert1 ? invert1b : invert1a, - invert2 ? cmpmap2->map2 : cmpmap2->map1, - invert2 ? invert2b : invert2a, 0, status ); - new2 = CombineMaps( invert1 ? cmpmap1->map1 : cmpmap1->map2, - invert1 ? invert1a : invert1b, - invert2 ? cmpmap2->map1 : cmpmap2->map2, - invert2 ? invert2a : invert2b, 0, status ); - -/* Having converted the parallel combination of series CmpMaps into a - pair of equivalent parallel CmpMaps that can be combined in series, - try and simplify each of these new CmpMaps. */ - simp1 = astSimplify( new1 ); - simp2 = astSimplify( new2 ); - -/* Test if either could be simplified by checking if its pointer value - has changed. Also check if the Invert attribute has changed (not - strictly necessary, but a useful safety feature in case of any - rogue code which just changes this attribute instead of issuing a - new pointer). */ - simpler = ( simp1 != new1 ) || ( simp2 != new2 ) || - astGetInvert( simp1 ) || astGetInvert( simp2 ); - -/* If either CmpMap was simplified, then combine the resulting - Mappings in series to give the replacement CmpMap. */ - if ( simpler ) new = - (AstMapping *) astCmpMap( simp1, simp2, 1, "", status ); - -/* Annul the temporary Mapping pointers. */ - new1 = astAnnul( new1 ); - new2 = astAnnul( new2 ); - simp1 = astAnnul( simp1 ); - simp2 = astAnnul( simp2 ); - -/* Parallel CmpMaps in series. */ -/* =========================== */ -/* A pair of adjacent CmpMaps can also potentially be merged if we are - examining a list of Mappings combined in series and the two - adjacent CmpMaps both combine their sub-Mappings in parallel. */ - } else if ( series && !cmpmap1->series && !cmpmap2->series ) { - -/* Expand each of the two adjacent CmpMaps into a list of Mappings to be - combined in parallel. */ - map_list1 = map_list2 = NULL; - invert_list1 = invert_list2 = NULL; - nmap1 = nmap2 = 0; - (void) astMapList( (AstMapping *) cmpmap1, 0, invert1, - &nmap1, &map_list1, &invert_list1 ); - (void) astMapList( (AstMapping *) cmpmap2, 0, invert2, - &nmap2, &map_list2, &invert_list2 ); - -/* We want to divide each of these lists into N sub-lists so that the - outputs of the Mappings in the i'th sub-list from cmpmap1 can feed - (i.e. equal in number) the inputs of the Mappings in the i'th sub-list - from cmpmap2. If such a sub-list contains more than one Mapping we - combine them together into a parallel CmpMap. Initialise a flag to - indicate that we have not yet found any genuine simplification. */ - simpler = 0; - -/* Initialise the index of the next Mapping to be added into each - sublist. */ - jmap1 = jmap2 = 0; - -/* Indicate both sublists are currently empty. */ - subout1 = subin2 = 0; - new = submap1 = submap2 = NULL; - subinv1 = subinv2 = 0; - -/* Loop round untill all Mappings have been used. */ - while( jmap1 <= nmap1 && jmap2 <= nmap2 && astOK ) { - -/* Note the number of outputs from submap1 and the number of inputs to - submap2. If the Invert flag is not set to the required value for - either Mapping, then inputs become outputs and vice-versa, so swap Nin - and Nout. */ - if( !submap1 ) { - subout1 = 0; - } else if( subinv1 == astGetInvert( submap1 ) ) { - subout1 = astGetNout( submap1 ); - } else { - subout1 = astGetNin( submap1 ); - } - - if( !submap2 ) { - subin2 = 0; - } else if( subinv2 == astGetInvert( submap2 ) ) { - subin2 = astGetNin( submap2 ); - } else { - subin2 = astGetNout( submap2 ); - } - -/* If sublist for cmpmap1 has too few outputs, add the next Mapping from - the cmpmap1 list into the submap1 sublist. */ - if( subout1 < subin2 ) { - tmap = CombineMaps( submap1, subinv1, - map_list1[ jmap1 ], - invert_list1[ jmap1 ], 0, status ); - (void) astAnnul( submap1 ); - submap1 = tmap; - subinv1 = 0; - jmap1++; - -/* If sublist for cmpmap2 has too few inputs, add the next Mapping from - the cmpmap2 list into the submap2 sublist. */ - } else if( subin2 < subout1 ) { - tmap = CombineMaps( submap2, subinv2, - map_list2[ jmap2 ], - invert_list2[ jmap2 ], 0, status ); - (void) astAnnul( submap2 ); - submap2 = tmap; - subinv2 = 0; - jmap2++; - -/* If submap1 can now feed submap2, combine them in series, and attempt to - simplify it. */ - } else { - -/* Check this is not the first pass (when we do not have a submap1 or - submap2). */ - if( submap1 && submap2 ) { - -/* Combine the Mappings in series and simplify. */ - tmap = CombineMaps( submap1, subinv1, submap2, - subinv2, 1, status ); - submap1 = astAnnul( submap1 ); - submap2 = astAnnul( submap2 ); - tmap2 = astSimplify( tmap ); - tmap = astAnnul( tmap ); - -/* Note if any simplification took place. */ - if( tmap != tmap2 || - astGetInvert( tmap ) != astGetInvert( tmap2 ) ) - simpler = 1; - -/* Add the simplifed Mapping into the total merged Mapping (a parallel - CmpMap). */ - if( !new ) { - new = tmap2; - } else { - tmap = (AstMapping *) astCmpMap( new, tmap2, 0, - " ", status ); - tmap2 = astAnnul( tmap2 ); - (void) astAnnul( new ); - new = tmap; - } - } - -/* Reset submap1 to be the next Mapping from the cmpmap1 map list. First, - save its old Invert flag and set it to the required value. */ - if( jmap1 < nmap1 ) { - submap1 = astClone( map_list1[ jmap1 ] ); - subinv1 = invert_list1[ jmap1 ]; - jmap1++; - } else { - break; - } - -/* Do the same for the second list. */ - if( jmap2 < nmap2 ) { - submap2 = astClone( map_list2[ jmap2 ] ); - subinv2 = invert_list2[ jmap2 ]; - jmap2++; - } else { - break; - } - } - } - -/* Free the lists of Mapping pointers and invert flags. */ - if( map_list1 ) { - for( jmap1 = 0; jmap1 < nmap1; jmap1++ ) { - map_list1[ jmap1 ] = astAnnul( map_list1[ jmap1 ] ); - } - map_list1 = astFree( map_list1 ); - } - invert_list1 = astFree( invert_list1 ); - - if( map_list2 ) { - for( jmap2 = 0; jmap2 < nmap2; jmap2++ ) { - map_list2[ jmap2 ] = astAnnul( map_list2[ jmap2 ] ); - } - map_list2 = astFree( map_list2 ); - } - invert_list2 = astFree( invert_list2 ); - - } - } - -/* Update Mapping list. */ -/* ==================== */ -/* If adjacent CmpMaps can be combined, then annul the original pointers. */ - if ( astOK && simpler ) { - ( *map_list )[ imap1 ] = astAnnul( ( *map_list )[ imap1 ] ); - ( *map_list )[ imap2 ] = astAnnul( ( *map_list )[ imap2 ] ); - -/* Insert the pointer to the replacement CmpMap and initialise its - invert flag. */ - ( *map_list )[ imap1 ] = new; - ( *invert_list )[ imap1 ] = 0; - -/* Loop to close the resulting gap by moving subsequent elements down - in the arrays. */ - for ( imap = imap2 + 1; imap < *nmap; imap++ ) { - ( *map_list )[ imap - 1 ] = ( *map_list )[ imap ]; - ( *invert_list )[ imap - 1 ] = ( *invert_list )[ imap ]; - } - -/* Clear the vacated elements at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = imap1; - } - } - } - } - -/* If we are merging the Mappings in series, and if the nominated CmpMap - is a parallel CmpMap, and if the lower neighbour is a PermMap, it may - be possible to swap the PermMap and the CmpMap. This may allow one of - the two swapped Mappings to merge with its new neighbour. - ==================================================================== */ - -/* Only do this if no simplification occurred above, and if the Mappings - are being merged in series, and if the nominated Mapping is not the - first in the list. */ - if( result == -1 && where > 0 ){ - -/* Obtain the indices of the two potential Mappings to be swapped. */ - imap1 = where - 1; - imap2 = where; - -/* Obtain a pointer to the CmpMap. */ - cmpmap2 = (AstCmpMap *) ( *map_list )[ imap2 ]; - -/* Obtain the Class string of the first (previous) Mapping and - determine if it is a PermMap. Also check that the nominated Mapping is - a parallel CmpMap. */ - class = astGetClass( ( *map_list )[ imap1 ] ); - if ( astOK && !strcmp( class, "PermMap" ) && !cmpmap2->series) { - -/* Indicate we have no new Mapping to store. */ - new = NULL; - -/* If suitable, obtain a pointer to the PermMap. */ - permmap1 = (AstPermMap *) ( *map_list )[ imap1 ]; - -/* Obtain the current values of the Invert attribute in the Mappings. */ - invert1 = astGetInvert( permmap1 ); - invert2 = astGetInvert( cmpmap2 ); - -/* Temporarily set the Invert attributes of both Mappings to the values - supplied in the "invert_list" parameter. */ - astSetInvert( permmap1, ( *invert_list )[ imap1 ] ); - astSetInvert( cmpmap2, ( *invert_list )[ imap2 ] ); - -/* Get the number of inputs and outputs for the PermMap.*/ - npout = astGetNout( permmap1 ); - npin = astGetNin( permmap1 ); - -/* Get the number of inputs and outputs for the two components of the - nominated parallel CmpMap. */ - nin2a = astGetNin( cmpmap2->map1 ); - nin2b = astGetNin( cmpmap2->map2 ); - nout2a = astGetNout( cmpmap2->map1 ); - nout2b = astGetNout( cmpmap2->map2 ); - -/* Get the input and output axis permutation arrays and the constants - array from the PermMap */ - inperm =astGetInPerm( permmap1 ); - outperm =astGetOutPerm( permmap1 ); - conperm = astGetConstants( permmap1 ); - -/* In order to swap the Mappings, the PermMap outputs which feed the - inputs of the first component of the parallel CmpMap must be copied - from a contiguous block at the end of the list of PermMap inputs, or - must all be assigned constant values. Likewise, the PermMap outputs which - feed the inputs of the second component of the parallel CmpMap must be - copied from a contiguous block at the beggining of the list of PermMap - inputs or must be assigned constant values. Also, there must be a - one-to-one correspondance between inputs and outputs in the PermMap. - Check that the first block of nin2a PermMap outputs are copied from - the last block of nin2a PermMap inputs (and vica-versa) or are constant. */ - canswap = ( npin == npout ); - aconstants = ( outperm[ 0 ] < 0 ); - - for( i = 0, j = npin - nin2a; i < nin2a; i++, j++ ) { - if( aconstants ) { - if( outperm[ i ] >= 0 ) { - canswap = 0; - break; - } - - } else if( outperm[ i ] != j || inperm[ j ] != i ) { - canswap = 0; - break; - } - } - -/* Check that the first block of nin2b PermMap inputs are copied from - the last block of nin2b PermMap outputs, and vica-versa. */ - bconstants = ( outperm[ nin2a ] < 0 ); - for( i = 0, j = npout - nin2b; i < nin2b; i++, j++ ) { - if( bconstants ) { - if( outperm[ j ] >= 0 ) { - canswap = 0; - break; - } - } else if( inperm[ i ] != j || outperm[ j ] != i ) { - canswap = 0; - break; - } - } - -/* If the Mappings can be swapped.. */ - new_pm = NULL; - new_cm = NULL; - qa = NULL; - qb = NULL; - if( canswap ) { - -/* Temporarily set the Invert attributes of the component Mappings to the - values they had when the CmpMap was created. */ - invert2a = astGetInvert( cmpmap2->map1 ); - invert2b = astGetInvert( cmpmap2->map2 ); - astSetInvert( cmpmap2->map1, cmpmap2->invert1 ); - astSetInvert( cmpmap2->map2, cmpmap2->invert2 ); - -/* If any PermMap outputs are constant, we will need the results of - transforming these constants using the CmpMap which follows. */ - if( aconstants || bconstants ) { - -/* Transform a set of bad inputs using the PermMap. This will assign the - PermMap constant to any fixed outputs. */ - p = astMalloc( sizeof( double )*(size_t) npin ); - q = astMalloc( sizeof( double )*(size_t) npout ); - qa = astMalloc( sizeof( double )*(size_t) nout2a ); - qb = astMalloc( sizeof( double )*(size_t) nout2b ); - if( astOK ) { - for( i = 0; i < npin; i++ ) p[ i ] = AST__BAD; - astTranN( permmap1, 1, npin, 1, p, 1, npout, 1, q ); - -/* Transform the PermMap outputs using the two component Mappings in the - CmpMap. */ - astTranN( cmpmap2->map1, 1, nin2a, 1, q, 1, nout2a, 1, qa ); - astTranN( cmpmap2->map2, 1, nin2b, 1, q + nin2a, 1, nout2b, 1, qb ); - - } - p = astFree( p ); - q = astFree( q ); - } - -/* If necessary, create a UnitMap to replace a Mapping which has constant - outputs. The number of axes for the UnitMap is chosen to give the - correct total number of inputs for the final parallel CmpMap. At the - same time determine the number of inputs needed by the final PermMap. */ - if( aconstants ) { - nunit = npin - nin2b; - npin_new = nout2b + nunit; - } else if( bconstants ) { - nunit = npin - nin2a; - npin_new = nout2a + nunit; - } else { - nunit = 0; - npin_new = nout2a + nout2b; - } - unit = nunit ? astUnitMap( nunit, "", status ) : NULL; - -/* Determine the number of outputs for the final PermMap and allocate memory - for its permutation arrays. */ - npout_new = nout2a + nout2b; - outperm_new = astMalloc( sizeof( int )*(size_t) npout_new ); - inperm_new = astMalloc( sizeof( int )*(size_t) npin_new ); - const_new = astMalloc( sizeof( double )*(size_t) ( npout_new + npin_new ) ); - if( astOK ) { - oconid = 0; - -/* First assign permutations for the second component Mapping, if used. */ - if( !bconstants ) { - for( i = 0, j = npout_new - nout2b; i < nout2b; i++,j++ ) { - inperm_new[ i ] = j; - outperm_new[ j ] = i; - } - -/* Otherwise, store constants */ - } else { - - for( i = 0; i < nunit; i++ ){ - iconid = inperm[ i ]; - if( iconid >= npout ) { - inperm_new[ i ] = npout_new; - - } else if( iconid >= 0 ) { - astError( AST__INTER, "astMapMerge(CmpMap): Swapped PermMap " - "input is not constant (internal AST programming " - "error)." , status); - break; - - } else { - inperm_new[ i ] = --oconid; - const_new[ -( oconid + 1 ) ] = conperm[ -( iconid + 1 ) ]; - } - } - - for( i = 0, j = npout_new - nout2b; i < nout2b; i++,j++ ) { - outperm_new[ j ] = --oconid; - const_new[ -( oconid + 1 ) ] = qb[ i ]; - } - - } - -/* Now assign permutations for the first component Mapping, if used. */ - if( !aconstants ) { - for( i = 0, j = npin_new - nout2a; i < nout2a; i++,j++ ) { - inperm_new[ j ] = i; - outperm_new[ i ] = j; - } - -/* Otherwise, store constants */ - } else { - - for( i = nout2b; i < npin_new; i++ ){ - iconid = inperm[ i - nout2b + nin2b ]; - if( iconid >= npout ) { - inperm_new[ i ] = npout_new; - - } else if( iconid >= 0 ) { - astError( AST__INTER, "astMapMerge(CmpMap): Swapped PermMap " - "input is not constant (internal AST programming " - "error)." , status); - break; - - } else { - inperm_new[ i ] = --oconid; - const_new[ -( oconid + 1 ) ] = conperm[ -( iconid + 1 ) ]; - } - } - - for( i = 0; i < nout2a; i++ ) { - outperm_new[ i ] = --oconid; - const_new[ -( oconid + 1 ) ] = qa[ i ]; - } - - } - -/* Create the new PermMap */ - new_pm = astPermMap( npin_new, inperm_new, npout_new, - outperm_new, const_new, "", status ); - -/* Create the new CmpMap.*/ - if( aconstants ) { - if( unit ) { - new_cm = astCmpMap( cmpmap2->map2, unit, 0, "", status ); - } else { - new_cm = astCopy( cmpmap2->map2 ); - } - - } else if( bconstants ) { - if( unit ) { - new_cm = astCmpMap( unit, cmpmap2->map1, 0, "", status ); - } else { - new_cm = astCopy( cmpmap2->map1 ); - } - - } else{ - new_cm = astCmpMap( cmpmap2->map2, cmpmap2->map1, 0, "", status ); - } - - } - -/* Free Memory. */ - if( unit ) unit = astAnnul( unit ); - outperm_new = astFree( outperm_new ); - inperm_new = astFree( inperm_new ); - const_new = astFree( const_new ); - if( aconstants || bconstants ) { - qa = astFree( qa ); - qb = astFree( qb ); - } - -/* Re-instate the original Invert attributes in the component Mappings. */ - astSetInvert( cmpmap2->map1, invert2a ); - astSetInvert( cmpmap2->map2, invert2b ); - - } - -/* Release the arrays holding the input and output permutation arrays - and constants copied from the PermMap. */ - inperm = astFree( inperm ); - outperm = astFree( outperm ); - conperm = astFree( conperm ); - -/* Re-instate the original values of the Invert attributes of both - Mappings. */ - astSetInvert( permmap1, invert1 ); - astSetInvert( cmpmap2, invert2 ); - -/* If the Mappings can be swapped... */ - if( astOK && canswap ) { - -/* Annul the supplied pointer to the two Mappings. */ - ( *map_list )[ imap1 ] = astAnnul( ( *map_list )[ imap1 ] ); - ( *map_list )[ imap2 ] = astAnnul( ( *map_list )[ imap2 ] ); - -/* Store the new PermMap pointer in the slot previously occupied by the - nominated CmpMap pointer. Likewise, store the invert flag. */ - ( *map_list )[ imap2 ] = (AstMapping *) new_pm; - ( *invert_list )[ imap2 ] = astGetInvert( new_pm ); - -/* Store the new PermMap pointer in the slot previously occupied by the - nominated CmpMap pointer. Likewise, store the invert flag. */ - ( *map_list )[ imap1 ] = (AstMapping *) new_cm; - ( *invert_list )[ imap1 ] = astGetInvert( new_cm ); - -/* Return the index of the first modified element. */ - result = imap1; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static int *MapSplit1( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit1 - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* int *MapSplit1( AstMapping *this, int nin, const int *in, AstMapping **map ) - -* Class Membership: -* CmpMap method - -* Description: -* This function performs the work for the astMapSplit method. It -* first invokes the astMapSplit method to see if the forward -* transformation of the supplied Mapping (not necessarily a CmpMap) -* can be split as requested. If this is not possible it invokes MapSplit2 -* which attempts an inverse approach to the problem. For each possible -* sub-sets of the Mapping outputs it call astMapSplit to see if the -* sub-set of outputs are generated from the selected inputs. - -* Parameters: -* this -* Pointer to the Mapping to be split. It is not assumed to be a CmpMap. -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied Mapping, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied Mapping has no subset of outputs which -* depend only on the selected inputs. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied Mapping. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - int *result; /* Axis order to return */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* First see if the forward transformation can be split as requested. */ - result = astMapSplit( this, nin, in, map ); - -/* If forward transformation could not be split, we attempt to split the - inverse transformation by selecting every possible sub-set of Mapping - outputs until one is found which is fed by the requested mapping inputs. */ - if( !result ) result = MapSplit2( this, nin, in, map, status ); - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static int *MapSplit2( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit2 - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* int *MapSplit2( AstMapping *this, int nin, const int *in, AstMapping **map ) - -* Class Membership: -* CmpMap method - -* Description: -* This function attempts to split the supplied Mapping using an -* inverse approach to the problem. For each possible sub-sets of the -* Mapping outputs it call astMapSplit to see if the sub-set of outputs -* are generated from the selected inputs. - -* Parameters: -* this -* Pointer to the Mapping to be split. It is not assumed to be a CmpMap. -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied Mapping, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied Mapping has no subset of outputs which -* depend only on the selected inputs. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied Mapping. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstMapping *map2; /* Subset Mapping */ - AstMapping *this2; /* Inverted copy of the supplied Mapping */ - int *out; /* Selected output indices */ - int *result; /* Axis order to return */ - int *result2; /* Axis order for current output subset */ - int i; /* Loop count */ - int iscmp; /* Is "this" a CmpMap? */ - int j; /* Loop count */ - int mout; /* Number of selected outputs */ - int nin2; /* Number of inputs fed by current outputs */ - int nout; /* The number of outputs from the supplied Mapping */ - int ok; /* Are all required inputs fed by current outputs? */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the number of Mapping outputs. */ - nout = astGetNout( this ); - -/* Get an inverted copy of the Mapping. We do this rather than inverting - the supplied Maping in case an error occurs which may leave the - supplied Mapping inverted. */ - this2 = astCopy( this ); - astInvert( this2 ); - -/* Note if the Mapping is a CmpMap. */ - iscmp = astIsACmpMap( this ); - -/* Allocate memory to hold the selected output indices. */ - out = astMalloc( nout*sizeof( int ) ); - -/* Loop round all useful subset sizes. */ - if( out ) { - for( mout = 1; mout < nout && !result; mout++ ) { - -/* Initialise the first subset of outputs to check at the current subset - size. */ - for( i = 0; i < mout; i++ ) out[ i ] = 0; - -/* Loop round all ways of picking a subset of "mout" outputs from the total - available "nout" outputs. */ - while( ! result ) { - -/* Skip this subset if it refers to any axis index more than once. */ - ok = 1; - for( i = 1; i < mout && ok; i++ ) { - for( j = 0; j < i; j++ ) { - if( out[ i ] == out[ j ] ) { - ok = 0; - break; - } - } - } - if( ok ) { - -/* Attempt to split the inverted Mapping using the current subset of - outputs. Take care to avoid an infinite loop if "this" is a CmpMap. */ - if( iscmp ) { - result2 = MapSplit0( this2, mout, out, &map2, 1, status ); - } else { - result2 = astMapSplit( this2, mout, out, &map2 ); - } - -/* If succesful... */ - if( result2 ) { - -/* See if the inputs that feed the current subset of outputs are the same - as the inputs specified by the caller (and in the same order). */ - nin2 = astGetNout( map2 ); - ok = ( nin2 == nin ); - if( ok ) { - for( i = 0; i < nin; i++ ) { - if( in[ i ] != result2[ i ] ) { - ok = 0; - break; - } - } - } - -/* If so, set up the values returned to the caller. */ - if( ok ) { - result = astStore( result, out, mout*sizeof(int) ); - astInvert( map2 ); - *map = astClone( map2 ); - } - -/* Free resources. */ - result2 = astFree( result2 ); - map2 = astAnnul( map2 ); - } - } - -/* Increment the first axis index. */ - i = 0; - out[ i ]++; - -/* If the incremented axis index is now too high, reset it to zero and - increment the next higher axis index. Do this until an incremented axis - index is not too high. */ - while( out[ i ] == nout ) { - out[ i++ ] = 0; - - if( i < mout ) { - out[ i ]++; - } else { - break; - } - } - -/* If all subsets have been checked break out of the loop. */ - if( i == mout ) break; - - } - } - } - -/* Free resources. */ - out = astFree( out ); - this2 = astAnnul( this2 ); - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static int *MapSplit0( AstMapping *this_mapping, int nin, const int *in, - AstMapping **map, int reentry, int *status ){ -/* -* Name: -* MapSplit0 - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* CmpMap. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* int *MapSplit0( AstMapping *this, int nin, const int *in, -* AstMapping **map, int reentry, int *status ) - -* Class Membership: -* CmpMap method - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing CmpMap. This is only possible if the specified inputs -* correspond to some subset of the CmpMap outputs. That is, there -* must exist a subset of the CmpMap outputs for which each output -* depends only on the selected CmpMap inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied CmpMap, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the CmpMap to be split (the CmpMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied CmpMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied CmpMap has no subset of outputs which -* depend only on the selected inputs. -* reentry -* Set to zero if this is a top level entry, and non-zero if it is -* a recursive entry. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied CmpMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstCmpMap *this; - AstMapping **map_list; - AstMapping *amap; - AstMapping *bmap; - AstPermMap *pmap; - int *aout; - int *cin; - int *cout; - int *inp; - int *invert_list; - int *outp; - int *p; - int *result; - int doperm; - int i; - int ibot; - int ibotout; - int iin; - int imap; - int iout; - int itop; - int j; - int naout; - int ncin; - int ncout; - int nmap; - int npin; - int npout; - int ok; - int old_inv; - int t; - - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the CmpMap structure. */ - this = (AstCmpMap *) this_mapping; - -/* Get the number of inputs and outputs in the supplied CmpMap. */ - npin = astGetNin( this ); - npout = astGetNout( this ); - -/* Check all input axis indices are valid. */ - ok = 1; - for( i = 0; i < nin; i++ ) { - if( in[ i ] < 0 || in[ i ] >= npin ) { - ok = 0; - break; - } - } - -/* If OK, proceed. */ - if( ok ) { - -/* Initialise dynamic arrays of Mapping pointers and associated Invert - flags. */ - nmap = 0; - map_list = NULL; - invert_list = NULL; - -/* Decompose the CmpMap into a sequence of Mappings to be applied in - series or parallel, as appropriate, and an associated list of - Invert flags. */ - (void) astMapList( this_mapping, this->series, astGetInvert( this ), - &nmap, &map_list, &invert_list ); - -/* First handle lists of Mapping in series. */ - if( this->series ) { - -/* Initialise the array of inputs to be split from the next component - Mapping. */ - ncin = nin; - cin = astStore( NULL, in, sizeof( int )*nin ); - -/* Loop round all the component Mappings that are combined in series to form - the supplied CmpMap. */ - for( imap = 0; imap < nmap && cin; imap++ ) { - -/* Temporarily reset the Invert attribute within the commponent Mapping back - to the value it had when the CmpMap was created. */ - old_inv = astGetInvert( map_list[ imap ] ); - astSetInvert( map_list[ imap ], invert_list[ imap ] ); - -/* Attempt to split the component Mapping using the current list of - inputs. */ - cout = MapSplit1( map_list[ imap ], ncin, cin, &amap, status ); - -/* If the split could be done... */ - if( amap ) { - -/* The outputs that correspond to the picked inputs become the inputs to - be picked from the next component Mapping. */ - (void) astFree( cin ); - cin = cout; - ncin = astGetNout( amap ); - -/* Combine the split Mapping in series with the earlier split Mappings. */ - if( *map ) { - bmap = (AstMapping *) astCmpMap( *map, amap, 1, " ", status ); - amap = astAnnul( amap ); - (void) astAnnul( *map ); - *map = bmap; - } else { - *map = amap; - } - -/* If the split could not be done, free the array of Mapping inputs to - indicate that no more component Mappings need be checked. */ - } else { - cin = astFree( cin ); - cout = astFree( cout ); - } - -/* Re-instate the original value of the Invert attribute within the - commponent Mapping. */ - astSetInvert( map_list[ imap ], old_inv ); - } - -/* Return the final array of output indices. */ - result = cin; - -/* Now handle lists of Mapping in parallel. */ - } else { - -/* Allocate work space. */ - outp = astMalloc( sizeof(int)*(size_t)nin ); - inp = astMalloc( sizeof(int)*(size_t)nin ); - cin = astMalloc( sizeof(int)*(size_t)npin ); - cout = astMalloc( sizeof(int)*(size_t)npout ); - if( astOK ) { - -/* The caller may have selected the Mapping inputs in any order, so we - need to create a PermMap which will permute the inputs from the - requested order to the order used by the CmpMap. First fill the outperm - work array with its own indices. */ - for( i = 0; i < nin; i++ ) outp[ i ] = i; - -/* Sort the outperm work array so that it accesses the array of input indices - in ascending order */ - for( j = nin - 1; j > 0; j-- ) { - p = outp; - for( i = 0; i < j; i++,p++ ) { - if( in[ p[0] ] > in[ p[1] ] ) { - t = p[0]; - p[0] = p[1]; - p[1] = t; - } - } - } - -/* Create the inperm array which is the inverse of the above outperm - array. Note if the permutation is necessary. */ - doperm = 0; - for( i = 0; i < nin; i++ ) { - if( outp[ i ] != i ) doperm = 1; - inp[ outp[ i ] ] = i; - } - -/* Create a PermMap which reorders the inputs into ascending order. */ - pmap = doperm ? astPermMap( nin, inp, nin, outp, NULL, "", status ) : NULL; - -/* Store the sorted input indices in the inp work array. */ - for( i = 0; i < nin; i++ ) { - inp[ i ] = in[ outp[ i ] ]; - } - -/* Initialise the index within the supplied CmpMap of the last (highest) - input in the current component Mapping. */ - itop = -1; - -/* Initialise the index within the supplied CmpMap of the first (lowest) - output for the current component Mapping. */ - ibotout = 0; - -/* Initialise the index within the supplied CmpMap of the current picked input. */ - iin = 0; - -/* Initialise the index of the next returned output index. */ - ncout = 0; - -/* Loop round all the component Mappings that are combined in series to form - the supplied CmpMap. */ - for( imap = 0; imap < nmap && cout; imap++ ) { - -/* Temporarily reset the Invert attribute within the component Mapping back - to the value it had when the CmpMap was created. */ - old_inv = astGetInvert( map_list[ imap ] ); - astSetInvert( map_list[ imap ], invert_list[ imap ] ); - -/* Get the index within the supplied CmpMap of the first (lowest) input in - the current component Mapping. */ - ibot = itop + 1; - -/* Get the index within the supplied CmpMap of the last (highest) input in - the current component Mapping. */ - itop += astGetNin( map_list[ imap ] ); - -/* Get the zero-based indices of the required inputs that feed the current - component Mapping. */ - ncin = 0; - while( iin < nin && inp[ iin ] <= itop ) { - cin[ ncin++ ] = inp[ iin++ ] - ibot; - } - -/* Skip components from which no inputs are being picked. */ - if( ncin > 0 ) { - -/* Attempt to split the component Mapping using the current list of inputs. */ - aout = MapSplit1( map_list[ imap ], ncin, cin, &amap, - status ); - -/* If successful... */ - if( amap ) { - -/* Correct the output indices so that they refer to the numbering scheme - of the total CmpMap, and append to the total list of output indices. */ - naout = astGetNout( amap ); - for( iout = 0; iout < naout; iout++ ) { - cout[ ncout++ ] = aout[ iout ] + ibotout; - } - -/* Combine the split Mapping in parallel with the earlier split Mappings. */ - if( *map ) { - bmap = (AstMapping *) astCmpMap( *map, amap, 0, " ", - status ); - amap = astAnnul( amap ); - (void) astAnnul( *map ); - *map = bmap; - } else { - *map = amap; - } - -/* If the component Mapping could not be split, free the cout array to - indicate that no more component Mappings need be considered. */ - } else { - cout = astFree( cout ); - } - -/* Free remaining resources. */ - aout = astFree( aout ); - } - -/* Update the index within the supplied CmpMap of the first (lowest) output in - the next component Mapping. */ - ibotout += astGetNout( map_list[ imap ] ); - -/* Re-instate the original value of the Invert attribute within the - commponent Mapping. */ - astSetInvert( map_list[ imap ], old_inv ); - } - -/* If the requested inputs could be split from the total CmpMap, add in any - PermMap needed to re-order the inputs. */ - if( cout && ncout ){ - if( doperm ) { - bmap = (AstMapping *) astCmpMap( pmap, *map, 1, "", status ); - (void) astAnnul( *map ); - *map = bmap; - } - -/* Also return the list of output indices. */ - result = cout; - cout = NULL; - } - -/* Free remaining resources. */ - if( pmap ) pmap = astAnnul( pmap ); - } - outp = astFree( outp ); - inp = astFree( inp ); - cin = astFree( cin ); - cout = astFree( cout ); - } - -/* Loop to annul all the Mapping pointers in the list. */ - for ( i = 0; i < nmap; i++ ) map_list[ i ] = astAnnul( map_list[ i ] ); - -/* Free the dynamic arrays. */ - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - - } - -/* Mappings that have no outputs cannot be used. */ - if( !result && *map ) *map = astAnnul( *map ); - -/* If the above method failed to split the CmpMap, we attempt to split the - inverse transformation by selecting every possible sub-set of Mapping - outputs until one is found which is fed by the requested mapping inputs. */ - if( !result && !reentry ) result = MapSplit2( this_mapping, nin, in, map, - status ); - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static int *MapSplit( AstMapping *this, int nin, const int *in, - AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* CmpMap. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, -* AstMapping **map, int *status ) - -* Class Membership: -* CmpMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function is the main entry point for the astMapSplit method. -* It is a simple wrapper for MapSplit0 which calls MapSplit0 -* indicating that this is a top-level entry. - -* Parameters: -* this -* Pointer to the CmpMap to be split (the CmpMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied CmpMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied CmpMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied CmpMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - return MapSplit0( this, nin, in, map, 0, status ); -} - -static int PatternCheck( int val, int check, int **list, int *list_len, int *status ){ -/* -* Name: -* Looping - -* Purpose: -* Check for repeating patterns in a set of integer values. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* int PatternCheck( int val, int nmap, int **mlist, int **nlist, int *list_len ) - -* Class Membership: -* CmpMap member function. - -* Description: -* This function appends a supplied integer to a dynamic list, creating -* or expanding the list if necessary.It then optionally, check the -* list for evidence of repeating patterns. If such a pattern is -* found, its wavelength is returned. - -* Parameters: -* val -* The integer value to add to the list. -* check -* Should a check for reating patterns be performed? -* list -* Address of a location at which is stored a pointer to an array -* holding the values supplied on previous invocations of this -* function. If a NULL pointer is supplied a new array is allocated. -* On exit, the supplied value is appended to the end of the array. The -* array is extended as necessary. The returned pointer should be -* freed using astFree when no longer needed. -* list_len -* Address of a location at which is stored the number of elements -* in the "list" array. - -* Returned Value: -* A non-zero "wavelength" value is returned if there is a repeating -* pattern is found in the "list" array. Otherwise, zero is returned. -* The "wavelength" is the number of integer values which constitute a -* single instance of the pattern. - -* Notes: -* - A value of 1 is returned if this function is invoked with the AST -* error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - int *wave[ 30 ]; /* Pointers to start of waves */ - int iat; /* Index of elements added by this invocation */ - int jat; /* Index of element condiered next */ - int jlo; /* Earliest "mlist" entry to consider */ - int k; /* Index of element within pattern */ - int mxwave; /* Max pattern length to consider */ - int iwave; /* Index of current wave */ - int nwave; /* Number of waves required to mark a pattern */ - int result; /* Returned flag */ - int wavelen; /* Current pattern length */ - -/* Check the global status. */ - if ( !astOK ) return 1; - -/* Initialise */ - result = 0; - -/* If no array has been supplied, create a new array. */ - if( !(*list) ) { - *list = astMalloc( 100*sizeof( int ) ); - *list_len = 0; - } - -/* Store the new value in the array, extending it if necessary. */ - iat = (*list_len)++; - *list = astGrow( *list, *list_len, sizeof( int ) ); - if( astOK ) { - (*list)[ iat ] = val; - -/* If required, determine the maximum "wavelength" for looping patterns to be - checked, and store the earliest list entry to consider. We take 3 complete - patterns as evidence of looping, but we only do the check when the - list length is at least 30. */ - if( check && *list_len > 29 ){ - mxwave = iat/3; - if( mxwave > 50 ) mxwave = 50; - jlo = iat - 3*mxwave; - -/* Search backwards from the end of "list" looking for the most recent - occurence of the supplied "val" value. Limit the search to - wavelengths of no more than the above limit. */ - jat = iat - 1; - while( jat >= jlo ) { - if( (*list)[ jat ] == val ) { - -/* When an earlier occurrence of "val" is found, see if the values - which precede it are the same as the values which precede the new - element if "list" added by this invocation. We use 3 complete - patterns as evidence of looping, unless the wavelength is 1 in which - case we use 30 patterns (this is because wavelengths of 1 can occur - in short sequences legitamately). */ - wavelen = iat - jat; - - if( wavelen == 1 ) { - nwave = 30; - if( nwave > iat ) nwave = iat; - } else { - nwave = 3; - } - - if( nwave*wavelen <= *list_len ) { - result = wavelen; - wave[ 0 ] = *list + *list_len - wavelen; - for( iwave = 1; iwave < nwave; iwave++ ) { - wave[ iwave ] = wave[ iwave - 1 ] - wavelen; - } - - for( k = 0; k < wavelen; k++ ) { - for( iwave = 1; iwave < nwave; iwave++ ) { - if( *wave[ iwave ] != *wave[ 0 ] ) { - result = 0; - break; - } - wave[ iwave ]++; - } - wave[ 0 ]++; - } - } - -/* Break if we have found a repeating pattern. */ - if( result ) break; - - } - jat--; - } - } - } - - if( !astOK ) result= 1; - -/* Return the result.*/ - return result; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* CmpMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -*/ - -/* Local Variables: */ - AstMapping *c1; - AstMapping *c2; - AstCmpMap *map; - double result; - int old_inv1; - int old_inv2; - int nin1; - int nin2; - double *at2; - double r1; - double r2; - int nout1; - int i; - -/* Check inherited status */ - if( !astOK ) return AST__BAD; - -/* Get a pointer to the CmpMap structure. */ - map = (AstCmpMap *) this; - -/* Note the current Invert flags of the two component Mappings. */ - old_inv1 = astGetInvert( map->map1 ); - old_inv2 = astGetInvert( map->map2 ); - -/* Temporarily reset them to the values they had when the CmpMap was - created. */ - astSetInvert( map->map1, map->invert1 ); - astSetInvert( map->map2, map->invert2 ); - -/* If the CmpMap itself has been inverted, invert the component Mappings. - Also note the order in which the Mappings should be applied if in series. */ - if( !astGetInvert( this ) ) { - c1 = map->map1; - c2 = map->map2; - } else { - c1 = map->map2; - c2 = map->map1; - astInvert( c1 ); - astInvert( c2 ); - } - -/* First deal with Mappings in series. */ - if( map->series ) { - -/* Get the number of inputs to the two component Mappings. */ - nin1 = astGetNin( c1 ); - nin2 = astGetNin( c2 ); - -/* Allocate workspace to hold the result of transforming the supplied "at" - position using the first component. */ - at2 = astMalloc( sizeof( double )*(size_t) nin2 ); - -/* Transform the supplied "at" position using the first component. */ - astTranN( c1, 1, nin1, 1, at, 1, nin2, 1, at2 ); - -/* The required rate of change is the sum of the products of the rate of - changes of the two component mappings, summed over all the output axes - of the first componment. */ - result = 0.0; - for( i = 0; i < nin2; i++ ) { - -/* Find the rate of change of output "i" of the first component with - respect to input "ax2" at the supplied "at" position. */ - r1 = astRate( c1, at, i, ax2 ); - -/* Find the rate of change of output "ax1" of the second component with - respect to input "i" at the transformed "at2" position. */ - r2 = astRate( c2, at2, ax1, i ); - -/* If both are good, increment the ryunning total by the product of the - two rates. Otherwise, break. */ - if( r1 != AST__BAD && r2 != AST__BAD ) { - result += r1*r2; - } else { - result = AST__BAD; - break; - } - } - -/* Free the workspace. */ - at2 = astFree( at2 ); - -/* Now deal with Mappings in parallel. */ - } else { - -/* Get the number of inputs and outputs for the lower component Mappings. */ - nin1 = astGetNin( map->map1 ); - nout1 = astGetNout( map->map1 ); - -/* If both input and output relate to the lower component Mappings, use its - astRate method. */ - if( ax1 < nout1 && ax2 < nin1 ) { - result = astRate( map->map1, at, ax1, ax2 ); - -/* If both input and output relate to the upper component Mappings, use its - astRate method. */ - } else if( ax1 >= nout1 && ax2 >= nin1 ) { - result = astRate( map->map2, at + nin1, ax1 - nout1, ax2 - nin1 ); - -/* If input and output relate to different component Mappings, return - zero. */ - } else { - result = 0.0; - } - } - -/* Reinstate the original Invert flags of the component Mappings .*/ - astSetInvert( map->map1, old_inv1 ); - astSetInvert( map->map2, old_inv2 ); - -/* Return the result. */ - return result; -} - -static AstMapping *RemoveRegions( AstMapping *this_mapping, int *status ) { -/* -* Name: -* RemoveRegions - -* Purpose: -* Remove any Regions from a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* AstMapping *RemoveRegions( AstMapping *this, int *status ) - -* Class Membership: -* CmpMap method (over-rides the astRemoveRegions method inherited -* from the Mapping class). - -* Description: -* This function searches the supplied Mapping (which may be a -* compound Mapping such as a CmpMap) for any component Mappings -* that are instances of the AST Region class. It then creates a new -* Mapping from which all Regions have been removed. If a Region -* cannot simply be removed (for instance, if it is a component of a -* parallel CmpMap), then it is replaced with an equivalent UnitMap -* in the returned Mapping. -* -* The implementation provided by the CmpMap class invokes the -* astRemoveRegions method on the two component Mappings, and joins -* the results together into a new CmpMap. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the modified mapping. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstCmpMap *new; /* Pointer to new CmpMap */ - AstCmpMap *this; /* Pointer to CmpMap structure */ - AstMapping *newmap1; /* New first component Mapping */ - AstMapping *newmap2; /* New second component Mapping */ - AstMapping *result; /* Result pointer to return */ - int nax; /* Number of Frame axes */ - int unit1; /* Is new first Mapping a UnitMap? */ - int unit2; /* Is new second Mapping a UnitMap? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the CmpMap. */ - this = (AstCmpMap *) this_mapping; - -/* Invoke the astRemoveRegions method on the two component Mappings. */ - newmap1 = astRemoveRegions( this->map1 ); - newmap2 = astRemoveRegions( this->map2 ); - -/* If neither component was modified, just return a clone of the supplied - pointer. */ - if( this->map1 == newmap1 && this->map2 == newmap2 ) { - result = astClone( this ); - -/* Otherwise, we need to create a new Mapping to return. */ - } else { - -/* The implementation of the astRemoveRegions method provided by the - Region class returns a Frame rather than a UnitMap. But we need - Mappings here, not Frames. So if either of these new Mappings is - a Frame, replace it with an equivalent UnitMap. Also, get flags - indicating if either Mapping is a UnitMap.*/ - if( astIsAFrame( newmap1 ) ) { - nax = astGetNin( newmap1 ); - (void) astAnnul( newmap1 ); - newmap1 = (AstMapping *) astUnitMap( nax, " ", status ); - unit1 = 1; - } else { - unit1 = astIsAUnitMap( newmap1 ); - } - - if( astIsAFrame( newmap2 ) ) { - nax = astGetNin( newmap2 ); - (void) astAnnul( newmap2 ); - newmap2 = (AstMapping *) astUnitMap( nax, " ", status ); - unit2 = 1; - } else { - unit2 = astIsAUnitMap( newmap2 ); - } - -/* First handle series CmpMaps. */ - if( this->series ) { - -/* Otherwise, if the second new Mapping is a UnitMap, return a copy of the - first new Mapping (with the original Invert attribute) since the second - one will have no effect. */ - if( unit1 ) { - result = astCopy( newmap2 ); - astSetInvert( result, this->invert2 ); - if( astGetInvert( this ) ) astInvert( result ); - -/* Otherwise, if the second new Mapping is a UnitMap, return a copy of the - first new Mapping (with the original Invert attribute) since the second - one will have no effect. */ - } else if( unit2 ) { - result = astCopy( newmap1 ); - astSetInvert( result, this->invert1 ); - if( astGetInvert( this ) ) astInvert( result ); - -/* If neither of the new Mappings is a UnitMap, return a new CmpMap - containing the two new Mappings. We take a deep copy of the supplied - CmpMap and then modify the Mappings os that we retain any extra - information (such as invert flags) in the supplied CmpMap. */ - } else { - new = astCopy( this ); - (void) astAnnul( new->map1 ); - (void) astAnnul( new->map2 ); - new->map1 = astClone( newmap1 ); - new->map2 = astClone( newmap2 ); - result = (AstMapping *) new; - } - -/* Now handle parallel CmpMaps. */ - } else { - -/* If both new Mappings are UnitMaps, return an equivalent UnitMap. */ - if( unit1 && unit2 ) { - result = (AstMapping *) astUnitMap( astGetNin( newmap1 ) + - astGetNin( newmap2 ), " ", - status ); - -/* Otherwise, return a new CmpMap containing the two new Mappings. */ - } else { - new = astCopy( this ); - (void) astAnnul( new->map1 ); - (void) astAnnul( new->map2 ); - new->map1 = astClone( newmap1 ); - new->map2 = astClone( newmap2 ); - result = (AstMapping *) new; - } - } - } - -/* Free resources. */ - newmap1 = astAnnul( newmap1 ); - newmap2 = astAnnul( newmap2 ); - -/* Annul the returned Mapping if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* CmpMap method (over-rides the astSimplify method inherited from -* the Mapping class). - -* Description: -* This function simplifies a CmpMap to eliminate redundant -* computational steps, or to merge separate steps which can be -* performed more efficiently in a single operation. - -* Parameters: -* this -* Pointer to the original Mapping. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A new pointer to the (possibly simplified) Mapping. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstCmpMap *this; /* Pointer to CmpMap structure */ - AstMapping **map_list; /* Mapping array pointer */ - AstMapping *map; /* Pointer to cloned Mapping pointer */ - AstMapping *result; /* Result pointer to return */ - AstMapping *tmp; /* Temporary Mapping pointer */ - int *invert_list; /* Invert array pointer */ - int *mlist; /* Point to list of modified Mapping indices */ - int *nlist; /* Point to list of Mapping counts */ - int i; /* Loop counter for Mappings */ - int improved; /* Simplification achieved? */ - int invert; /* Invert attribute value */ - int invert_n; /* Invert value for final Mapping */ - int mlist_len; /* No. of entries in mlist */ - int nlist_len; /* No. of entries in nlist */ - int modified; /* Index of first modified Mapping */ - int nmap; /* Mapping count */ - int nominated; /* Index of nominated Mapping */ - int set; /* Invert attribute set? */ - int set_n; /* Invert set for final Mapping? */ - int simpler; /* Simplification possible? */ - int t; /* Temporary storage */ - int wlen1; /* Pattern wavelength for "modified" values */ - int wlen2; /* Pattern wavelength for "nmap" values */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_mapping); - -/* It is possible for the astSimplify method to be called recursively from - within astSimplify. It is also possible that the Mapping being - simplified by the current invocation is the same as the Mapping being - simplified by some recursive invocation higher up the call stack. If - this happens we will get into an infinite loop, since we already know - that simplifying the supplied Mapping will involve (eventually) a - recursive call to astSimplify with the same Mapping. To avoid this - looping, we note the Mappings supplied at each depth and first compare - the supplied Mapping with the Mappings which are currently being - simplified higher up the call stack. If the supplied Mapping is - already being simplified at a higher level, then we return immediately - without doing any simplification. Otherwise, we record the supplied - Mapping pointer in a static list so that it is available to subsequent - recursive invocations of this function. First compare the supplied - Mapping with the Mappingsbeing simpliied higher up. Return without - action if a match is found. */ - for( i = 0; i < simplify_depth; i++ ) { - if( astEqual( this_mapping, simplify_stackmaps[ i ] ) ) { - return astClone( this_mapping ); - } - } - -/* We have further work to do, so increment the recursion depth, extend - the simplify_stackmaps array, and store the new Mapping in it for future use. */ - simplify_depth++; - simplify_stackmaps = astGrow( simplify_stackmaps, simplify_depth, sizeof( AstMapping * ) ); - if( astOK ) { - simplify_stackmaps[ simplify_depth - 1 ] = astClone( this_mapping ); - } - -/* Obtain a pointer to the CmpMap structure. */ - this = (AstCmpMap *) this_mapping; - -/* Initialise dynamic arrays of Mapping pointers and associated Invert - flags. */ - nmap = 0; - map_list = NULL; - invert_list = NULL; - -/* Decompose the CmpMap into a sequence of Mappings to be applied in - series or parallel, as appropriate, and an associated list of - Invert flags. If any inverted CmpMaps are found in the Mapping, then - we can at least simplify the returned Mapping by swapping and - inverting the components. Set "simpler" to indicate this. */ - simpler = astMapList( this_mapping, this->series, astGetInvert( this ), &nmap, - &map_list, &invert_list ); - -/* Each Mapping has a flag that indicates if the mapping is frozen (i.e. cannot - be nominated for simplification). Mappings become frozen if nominating them - would create an infinite loop in which neighbouring mappings argue as to - their form. Freezing a mapping prevents the frozen mapping contributing any - further to the argument, so the other Mapping "wins" the argument. - Ensure no Mappings are frozen to begin with. */ - for( i = 0; i < nmap; i++ ) { - map_list[ i ]->flags &= ~AST__FROZEN_FLAG; - } - -/* Initialise pointers to memory used to hold lists of the modified - Mapping index and the number of mappings after each call of - astMapMerge. */ - mlist = NULL; - nlist = NULL; - -/* Loop to simplify the sequence until a complete pass through it has - been made without producing any improvement. */ - improved = 1; - while ( astOK && improved ) { - improved = 0; - -/* Loop to nominate each Mapping in the sequence in turn. */ - nominated = 0; - while ( astOK && ( nominated < nmap ) ) { - -/* If the current nominated mapping has been frozen, then we do not allow - it to suggest changes to the mapping sequence. Instead, just increment - the index of the next mapping to be checked and continue on to the next - pass round the while loop. */ - if( map_list[ nominated ]->flags & AST__FROZEN_FLAG ) { - nominated++; - continue; - } - -/* Clone a pointer to the nominated Mapping and attempt to merge it - with its neighbours. Annul the cloned pointer afterwards. */ - map = astClone( map_list[ nominated ] ); - modified = astMapMerge( map, nominated, this->series, - &nmap, &map_list, &invert_list ); - map = astAnnul( map ); - -/* Move on to nominate the next Mapping in the sequence. */ - nominated++; - -/* Note if any simplification occurred above. */ - if( modified >= 0 && astOK ) { - -/* Append the index of the first modified Mapping in the list and and check - that there is no repreating pattern in the list. If there is, we are - probably in a loop where one mapping class is making a change, and another - is undoing the change. The Looping function returns the "wavelength" - of any pattern found. If a pattern was discovered, we ignore it unless - there is also a pattern in the "nmap" values - the wavelengths of the - two patterns must be related by a integer factor. */ - wlen1 = PatternCheck( modified, 1, &mlist, &mlist_len, status ); - wlen2 = PatternCheck( nmap, wlen1, &nlist, &nlist_len, status ); - if( wlen1 && wlen2 ) { - -/* Ensure wlen2 is larger than or equal to wlen1. */ - if( wlen1 > wlen2 ) { - t = wlen1; - wlen1 = wlen2; - wlen2 = t; - } - -/* See if wlen2 is an integer multiple of wlen1. If not, ignore the - patterns. */ - if( ( wlen2 % wlen1 ) != 0 ) wlen1 = 0; - } - -/* If a repeating pattern is occurring, set the frozen flag in order to - prevent the modified mapping from being modified any more. */ - if( wlen1 > 0 ) { - map_list[ modified ]->flags |= AST__FROZEN_FLAG; - -/* Otherwise, indicate we have improved the mapping and go round to test - the next nominated mapping. */ - } else { - improved = 1; - simpler = 1; - -/* If the simplification resulted in modification of an earlier - Mapping than would normally be considered next, then go back to - consider the modified one first. */ - if ( modified < nominated ) nominated = modified; - } - } - } - } - -/* Free resources */ - mlist = astFree( mlist ); - nlist = astFree( nlist ); - -/* Construct the output Mapping. */ -/* ============================= */ -/* If no simplification occurred above, then simply clone a pointer to - the original Mapping. */ - if ( astOK ) { - if ( !simpler ) { - result = astClone( this ); - -/* Otherwise, we must construct the result from the contents of the - Mapping list. */ - } else { - -/* If the simplified Mapping list has only a single element, then the - output Mapping will not be a CmpMap. In this case, we cannot - necessarily set the Invert flag of the Mapping to the value we want - (because we must not modify the Mapping itself. */ - if ( nmap == 1 ) { - -/* We must make a copy. Cloning is no good (even if the Mapping already - has the Invert attribute value we want), since we want the returned - Mapping to be independent of the original component Mappings, so that - if user code inverts a component Mapping (via some other pre-existing - pointer), the returned simplified Mapping is not affected. */ - result = astCopy( map_list[ 0 ] ); - -/* Either clear the copy's Invert attribute, or set it to 1, as - required. */ - if ( invert_list[ 0 ] ) { - astSetInvert( result, 1 ); - } else { - astClearInvert( result ); - } - -/* If the simplified Mapping sequence has more than one element, the - output Mapping will be a CmpMap. In this case, we can set each - individual Mapping element to have the Invert attribute value we - want, so long as we return these attribute values to their original - state again afterwards (once a Mapping is encapsulated inside a - CmpMap, further external changes to its Invert attribute do not - affect the behaviour of the CmpMap). */ - } else { - -/* Determine if the Invert attribute for the last Mapping is set, and - obtain its value. */ - set_n = astTestInvert( map_list[ nmap - 1 ] ); - invert_n = astGetInvert( map_list[ nmap - 1 ] ); - -/* Set this attribute to the value we want. */ - astSetInvert( map_list[ nmap - 1 ], invert_list[ nmap - 1 ] ); - -/* Loop through the Mapping sequence in reverse to merge it into an - equivalent CmpMap. */ - for ( i = nmap - 1; i >= 0; i-- ) { - -/* Simply clone the pointer to the last Mapping in the sequence (which - will be encountered first). */ - if ( !result ) { - result = astClone( map_list[ i ] ); - -/* For subsequent Mappings, test if the Invert attribute is set and - save its value. */ - } else { - set = astTestInvert( map_list[ i ] ); - invert = astGetInvert( map_list[ i ] ); - -/* Set this attribute to the value required. */ - astSetInvert( map_list[ i ], invert_list[ i ] ); - -/* Combine the Mapping with the CmpMap formed so far and replace the - result pointer with the new pointer this produces, annulling the - previous pointer. */ - tmp = (AstMapping *) astCmpMap( map_list[ i ], result, - this->series, "", status ); - (void) astAnnul( result ); - result = tmp; - -/* Restore the Invert attribute of the Mapping to its original - state. */ - if ( !set ) { - astClearInvert( map_list[ i ] ); - } else { - astSetInvert( map_list[ i ], invert ); - } - } - } - -/* When all the Mappings have been merged into the CmpMap, restore the - state of the Invert attribute for the final Mapping in the - sequence. */ - if ( !set_n ) { - astClearInvert( map_list[ nmap - 1 ] ); - } else { - astSetInvert( map_list[ nmap - 1 ], invert_n ); - } - } - } - } - -/* Clean up. */ -/* ========= */ -/* Loop to annul all the Mapping pointers in the simplified list. */ - for ( i = 0; i < nmap; i++ ) map_list[ i ] = astAnnul( map_list[ i ] ); - -/* Free the dynamic arrays. */ - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - -/* Decrement the recursion depth and free the pointer to the supplied - Mapping currently stored at the end of the simplify_stackmaps array. */ - simplify_depth--; - if( astOK ) { - simplify_stackmaps[ simplify_depth ] = astAnnul( simplify_stackmaps[ simplify_depth ] ); - } - -/* If we are now at depth zero, free the simplify_stackmaps array. */ - if( simplify_depth == 0 ) simplify_stackmaps = astFree( simplify_stackmaps ); - -/* If an error occurred, annul the returned Mapping. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a CmpMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* CmpMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a CmpMap and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required Mapping. -* This implies applying each of the CmpMap's component Mappings in turn, -* either in series or in parallel. - -* Parameters: -* this -* Pointer to the CmpMap. -* in -* Pointer to the PointSet associated with the input coordinate values. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the CmpMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstCmpMap *map; /* Pointer to CmpMap to be applied */ - AstPointSet *result; /* Pointer to output PointSet */ - AstPointSet *temp1; /* Pointer to temporary PointSet */ - AstPointSet *temp2; /* Pointer to temporary PointSet */ - AstPointSet *temp; /* Pointer to temporary PointSet */ - int forward1; /* Use forward direction for Mapping 1? */ - int forward2; /* Use forward direction for Mapping 2? */ - int ipoint1; /* Index of first point in batch */ - int ipoint2; /* Index of last point in batch */ - int nin1; /* No. input coordinates for Mapping 1 */ - int nin2; /* No. input coordinates for Mapping 2 */ - int nin; /* No. input coordinates supplied */ - int nout1; /* No. output coordinates for Mapping 1 */ - int nout2; /* No. output coordinates for Mapping 2 */ - int nout; /* No. output coordinates supplied */ - int np; /* Number of points in batch */ - int npoint; /* Number of points to be transformed */ - -/* Local Constants: */ - const int nbatch = 2048; /* Maximum points in a batch */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the CmpMap. */ - map = (AstCmpMap *) this; - -/* Apply the parent Mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We now extend the parent astTransform method by applying the component - Mappings of the CmpMap to generate the output coordinate values. */ - -/* Determine whether to apply the forward or inverse Mapping, according to the - direction specified and whether the Mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Check if either component Mapping's inversion flag has changed since it was - used to construct the CmpMap. Set a "forward" flag for each Mapping to - change the direction we will use, to compensate if necessary. (Such changes - may have occurred if other pointers to the component Mappings are in - circulation). */ - forward1 = forward; - forward2 = forward; - if ( map->invert1 != astGetInvert( map->map1 ) ) forward1 = !forward1; - if ( map->invert2 != astGetInvert( map->map2 ) ) forward2 = !forward2; - -/* Determine the number of points being transformed. */ - npoint = astGetNpoint( in ); - -/* Mappings in series. */ -/* ------------------- */ -/* If required, use the two component Mappings in series. To do this, we must - apply one Mapping followed by the other, which means storing an intermediate - result. Since this function may be invoked recursively and have to store an - intermediate result on each occasion, the memory required may become - excessive when transforming large numbers of points. To overcome this, we - split the points up into smaller batches. */ - if ( astOK ) { - if ( map->series ) { - -/* Obtain the numbers of input and output coordinates. */ - nin = astGetNcoord( in ); - nout = astGetNcoord( result ); - -/* Loop to process all the points in batches, of maximum size nbatch points. */ - for ( ipoint1 = 0; ipoint1 < npoint; ipoint1 += nbatch ) { - -/* Calculate the index of the final point in the batch and deduce the number of - points (np) to be processed in this batch. */ - ipoint2 = ipoint1 + nbatch - 1; - if ( ipoint2 > npoint - 1 ) ipoint2 = npoint - 1; - np = ipoint2 - ipoint1 + 1; - -/* Create temporary PointSets to describe the input and output points for this - batch. */ - temp1 = astPointSet( np, nin, "", status ); - temp2 = astPointSet( np, nout, "", status ); - -/* Associate the required subsets of the input and output coordinates with the - two PointSets. */ - astSetSubPoints( in, ipoint1, 0, temp1 ); - astSetSubPoints( result, ipoint1, 0, temp2 ); - -/* Apply the two Mappings in sequence and in the required order and direction. - Store the intermediate result in a temporary PointSet (temp) which is - created by the first Mapping applied. */ - if ( forward ) { - temp = astTransform( map->map1, temp1, forward1, NULL ); - (void) astTransform( map->map2, temp, forward2, temp2 ); - } else { - temp = astTransform( map->map2, temp1, forward2, NULL ); - (void) astTransform( map->map1, temp, forward1, temp2 ); - } - -/* Delete the temporary PointSets after processing each batch of points. */ - temp = astDelete( temp ); - temp1 = astDelete( temp1 ); - temp2 = astDelete( temp2 ); - -/* Quit processing batches if an error occurs. */ - if ( !astOK ) break; - } - -/* Mappings in parallel. */ -/* --------------------- */ -/* If required, use the two component Mappings in parallel. Since we do not - need to allocate any memory to hold intermediate coordinate values here, - there is no need to process the points in batches. */ - } else { - -/* Get the effective number of input and output coordinates per point for each - Mapping (taking account of the direction in which each will be used to - transform points). */ - nin1 = forward1 ? astGetNin( map->map1 ) : astGetNout( map->map1 ); - nout1 = forward1 ? astGetNout( map->map1 ) : astGetNin( map->map1 ); - nin2 = forward2 ? astGetNin( map->map2 ) : astGetNout( map->map2 ); - nout2 = forward2 ? astGetNout( map->map2 ) : astGetNin( map->map2 ); - -/* Create temporary PointSets to describe the input and output coordinates for - the first Mapping. */ - temp1 = astPointSet( npoint, nin1, "", status ); - temp2 = astPointSet( npoint, nout1, "", status ); - -/* Associate the required subsets of the input and output coordinates with - these PointSets. */ - astSetSubPoints( in, 0, 0, temp1 ); - astSetSubPoints( result, 0, 0, temp2 ); - -/* Use the astTransform method to apply the coordinate transformation described - by the first Mapping. */ - (void) astTransform( map->map1, temp1, forward1, temp2 ); - -/* Delete the temporary PointSets. */ - temp1 = astDelete( temp1 ); - temp2 = astDelete( temp2 ); - -/* Create a new pair of temporary PointSets to describe the input and output - coordinates for the second Mapping, and associate the required subsets of - the input and output coordinates with these PointSets. */ - temp1 = astPointSet( npoint, nin2, "", status ); - temp2 = astPointSet( npoint, nout2, "", status ); - astSetSubPoints( in, 0, nin1, temp1 ); - astSetSubPoints( result, 0, nout1, temp2 ); - -/* Apply the coordinate transformation described by the second Mapping. */ - (void) astTransform( map->map2, temp1, forward2, temp2 ); - -/* Delete the two temporary PointSets. */ - temp1 = astDelete( temp1 ); - temp2 = astDelete( temp2 ); - } - } - -/* If an error occurred, clean up by deleting the output PointSet (if - allocated by this function) and setting a NULL result pointer. */ - if ( !astOK ) { - if ( !out ) result = astDelete( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for CmpMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for CmpMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Mappings within the CmpMap. -*/ - -/* Local Variables: */ - AstCmpMap *in; /* Pointer to input CmpMap */ - AstCmpMap *out; /* Pointer to output CmpMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output CmpMaps. */ - in = (AstCmpMap *) objin; - out = (AstCmpMap *) objout; - -/* For safety, start by clearing any references to the input component - Mappings from the output CmpMap. */ - out->map1 = NULL; - out->map2 = NULL; - -/* Make copies of these Mappings and store pointers to them in the output - CmpMap structure. */ - out->map1 = astCopy( in->map1 ); - out->map2 = astCopy( in->map2 ); -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for CmpMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for CmpMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstCmpMap *this; /* Pointer to CmpMap */ - -/* Obtain a pointer to the CmpMap structure. */ - this = (AstCmpMap *) obj; - -/* Annul the pointers to the component Mappings. */ - this->map1 = astAnnul( this->map1 ); - this->map2 = astAnnul( this->map2 ); - -/* Clear the remaining CmpMap variables. */ - this->invert1 = 0; - this->invert2 = 0; - this->series = 0; -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for CmpMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the CmpMap class to an output Channel. - -* Parameters: -* this -* Pointer to the CmpMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstCmpMap *this; /* Pointer to the CmpMap structure */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpMap structure. */ - this = (AstCmpMap *) this_object; - -/* Write out values representing the instance variables for the CmpMap - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Series. */ -/* ------- */ - ival = this->series; - set = ( ival == 0 ); - astWriteInt( channel, "Series", set, 0, ival, - ival ? "Component Mappings applied in series" : - "Component Mappings applied in parallel" ); - -/* First Invert flag. */ -/* ------------------ */ - ival = this->invert1; - set = ( ival != 0 ); - astWriteInt( channel, "InvA", set, 0, ival, - ival ? "First Mapping used in inverse direction" : - "First Mapping used in forward direction" ); - -/* Second Invert flag. */ -/* ------------------- */ - ival = this->invert2; - set = ( ival != 0 ); - astWriteInt( channel, "InvB", set, 0, ival, - ival ? "Second Mapping used in inverse direction" : - "Second Mapping used in forward direction" ); - -/* First Mapping. */ -/* -------------- */ - astWriteObject( channel, "MapA", 1, 1, this->map1, - "First component Mapping" ); - -/* Second Mapping. */ -/* --------------- */ - astWriteObject( channel, "MapB", 1, 1, this->map2, - "Second component Mapping" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsACmpMap and astCheckCmpMap functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(CmpMap,Mapping) -astMAKE_CHECK(CmpMap) - -AstCmpMap *astCmpMap_( void *map1_void, void *map2_void, int series, - const char *options, int *status, ...) { -/* -*+ -* Name: -* astCmpMap - -* Purpose: -* Create a CmpMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpmap.h" -* AstCmpMap *astCmpMap( AstMapping *map1, AstMapping *map2, int series, -* const char *options, ... ) - -* Class Membership: -* CmpMap constructor. - -* Description: -* This function creates a new CmpMap and optionally initialises its -* attributes. - -* Parameters: -* map1 -* Pointer to the first Mapping. -* map2 -* Pointer to the second Mapping. -* series -* If a non-zero value is given, the two Mappings will be connected -* together in series. A zero value requests that they be connected in -* parallel. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new CmpMap. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new CmpMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic CmpMap constructor which is -* available via the protected interface to the CmpMap class. A -* public interface is provided by the astCmpMapId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "map1" and "map2" parameters are of type (void *) and are -* converted and validated within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstCmpMap *new; /* Pointer to new CmpMap */ - AstMapping *map1; /* Pointer to first Mapping structure */ - AstMapping *map2; /* Pointer to second Mapping structure */ - va_list args; /* Variable argument list */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain and validate pointers to the Mapping structures provided. */ - map1 = astCheckMapping( map1_void ); - map2 = astCheckMapping( map2_void ); - if ( astOK ) { - -/* Initialise the CmpMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitCmpMap( NULL, sizeof( AstCmpMap ), !class_init, &class_vtab, - "CmpMap", map1, map2, series ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new CmpMap's - attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new CmpMap. */ - return new; -} - -AstCmpMap *astCmpMapId_( void *map1_void, void *map2_void, int series, - const char *options, ... ) { -/* -*++ -* Name: -c astCmpMap -f AST_CMPMAP - -* Purpose: -* Create a CmpMap. - -* Type: -* Public function. - -* Synopsis: -c #include "cmpmap.h" -c AstCmpMap *astCmpMap( AstMapping *map1, AstMapping *map2, int series, -c const char *options, ... ) -f RESULT = AST_CMPMAP( MAP1, MAP2, SERIES, OPTIONS, STATUS ) - -* Class Membership: -* CmpMap constructor. - -* Description: -* This function creates a new CmpMap and optionally initialises -* its attributes. -* -* A CmpMap is a compound Mapping which allows two component -* Mappings (of any class) to be connected together to form a more -* complex Mapping. This connection may either be "in series" -* (where the first Mapping is used to transform the coordinates of -* each point and the second mapping is then applied to the -* result), or "in parallel" (where one Mapping transforms the -* earlier coordinates for each point and the second Mapping -* simultaneously transforms the later coordinates). -* -* Since a CmpMap is itself a Mapping, it can be used as a -* component in forming further CmpMaps. Mappings of arbitrary -* complexity may be built from simple individual Mappings in this -* way. - -* Parameters: -c map1 -f MAP1 = INTEGER (Given) -* Pointer to the first component Mapping. -c map2 -f MAP2 = INTEGER (Given) -* Pointer to the second component Mapping. -c series -f SERIES = LOGICAL (Given) -c If a non-zero value is given for this parameter, the two -c component Mappings will be connected in series. A zero -c value requests that they are connected in parallel. -f If a .TRUE. value is given for this argument, the two -f component Mappings will be connected in series. A -f .FALSE. value requests that they are connected in parallel. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new CmpMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new CmpMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astCmpMap() -f AST_CMPMAP = INTEGER -* A pointer to the new CmpMap. - -* Notes: -* - If the component Mappings are connected in series, then using -* the resulting CmpMap to transform coordinates will cause the -* first Mapping to be applied, followed by the second Mapping. If -* the inverse CmpMap transformation is requested, the two -* component Mappings will be applied in both the reverse order and -* the reverse direction. -* - When connecting two component Mappings in series, the number -* of output coordinates generated by the first Mapping (its Nout -* attribute) must equal the number of input coordinates accepted -* by the second Mapping (its Nin attribute). -* - If the component Mappings of a CmpMap are connected in -* parallel, then the first Mapping will be used to transform the -* earlier input coordinates for each point (and to produce the -* earlier output coordinates) and the second Mapping will be used -* simultaneously to transform the remaining input coordinates (to -* produce the remaining output coordinates for each point). If the -* inverse transformation is requested, each Mapping will still be -* applied to the same coordinates, but in the reverse direction. -* - When connecting two component Mappings in parallel, there is -* no restriction on the number of input and output coordinates for -* each Mapping. -c - Note that the component Mappings supplied are not copied by -c astCmpMap (the new CmpMap simply retains a reference to -c them). They may continue to be used for other purposes, but -c should not be deleted. If a CmpMap containing a copy of its -c component Mappings is required, then a copy of the CmpMap should -c be made using astCopy. -f - Note that the component Mappings supplied are not copied by -f AST_CMPMAP (the new CmpMap simply retains a reference to -f them). They may continue to be used for other purposes, but -f should not be deleted. If a CmpMap containing a copy of its -f component Mappings is required, then a copy of the CmpMap should -f be made using AST_COPY. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astCmpMap constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astCmpMap_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "map1" and "map2" parameters -* are of type (void *) and are converted from an ID value to a -* pointer and validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astCmpMap_ directly, so it must be a re-implementation -* of it in all respects, except for the conversions between IDs -* and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstCmpMap *new; /* Pointer to new CmpMap */ - AstMapping *map1; /* Pointer to first Mapping structure */ - AstMapping *map2; /* Pointer to second Mapping structure */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain the Mapping pointers from the ID's supplied and validate the - pointers to ensure they identify valid Mappings. */ - map1 = astVerifyMapping( astMakePointer( map1_void ) ); - map2 = astVerifyMapping( astMakePointer( map2_void ) ); - if ( astOK ) { - -/* Initialise the CmpMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitCmpMap( NULL, sizeof( AstCmpMap ), !class_init, &class_vtab, - "CmpMap", map1, map2, series ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new CmpMap's - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new CmpMap. */ - return astMakeId( new ); -} - -AstCmpMap *astInitCmpMap_( void *mem, size_t size, int init, - AstCmpMapVtab *vtab, const char *name, - AstMapping *map1, AstMapping *map2, int series, int *status ) { -/* -*+ -* Name: -* astInitCmpMap - -* Purpose: -* Initialise a CmpMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpmap.h" -* AstCmpMap *astInitCmpMap( void *mem, size_t size, int init, -* AstCmpMapVtab *vtab, const char *name, -* AstMapping *map1, AstMapping *map2, -* int series ) - -* Class Membership: -* CmpMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new CmpMap object. It allocates memory (if necessary) to -* accommodate the CmpMap plus any additional data associated with the -* derived class. It then initialises a CmpMap structure at the start -* of this memory. If the "init" flag is set, it also initialises the -* contents of a virtual function table for a CmpMap at the start of -* the memory passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the CmpMap is to be initialised. -* This must be of sufficient size to accommodate the CmpMap data -* (sizeof(CmpMap)) plus any data used by the derived class. If a -* value of NULL is given, this function will allocate the memory itself -* using the "size" parameter to determine its size. -* size -* The amount of memory used by the CmpMap (plus derived class -* data). This will be used to allocate memory if a value of NULL is -* given for the "mem" parameter. This value is also stored in the -* CmpMap structure, so a valid value must be supplied even if not -* required for allocating memory. -* init -* A logical flag indicating if the CmpMap's virtual function table -* is to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new CmpMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* map1 -* Pointer to the first Mapping. -* map2 -* Pointer to the second Mapping. -* series -* If a non-zero value is given, the two Mappings will be connected -* together in series. A zero value requests that they be connected in -* parallel. - -* Returned Value: -* A pointer to the new CmpMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstCmpMap *new; /* Pointer to new CmpMap */ - int map_f; /* Forward transformation defined? */ - int map_i; /* Inverse transformation defined? */ - int nin2; /* No. input coordinates for Mapping 2 */ - int nin; /* No. input coordinates for CmpMap */ - int nout1; /* No. output coordinates for Mapping 1 */ - int nout; /* No. output coordinates for CmpMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitCmpMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Determine in which directions each component Mapping is able to transform - coordinates. Combine these results to obtain a result for the overall - CmpMap. */ - map_f = astGetTranForward( map1 ) && astGetTranForward( map2 ); - map_i = astGetTranInverse( map1 ) && astGetTranInverse( map2 ); - if ( astOK ) { - -/* If connecting the Mappings in series, check that the number of coordinates - are compatible and report an error if they are not. */ - if ( series ) { - nout1 = astGetNout( map1 ); - nin2 = astGetNin( map2 ); - if ( astOK && ( nout1 != nin2 ) ) { - astError( AST__INNCO, "astInitCmpMap(%s): The number of output " - "coordinates per point (%d) for the first Mapping " - "supplied does not match the number of input " - "coordinates (%d) for the second Mapping.", status, name, nout1, - nin2 ); - } - } - } - -/* If OK, determine the total number of input and output coordinates per point - for the CmpMap. */ - if ( astOK ) { - if ( series ) { - nin = astGetNin( map1 ); - nout = astGetNout( map2 ); - } else { - nin = astGetNin( map1 ) + astGetNin( map2 ); - nout = astGetNout( map1 ) + astGetNout( map2 ); - } - - } else { - nin = 0; - nout = 0; - } - -/* Initialise a Mapping structure (the parent class) as the first component - within the CmpMap structure, allocating memory if necessary. Specify - the number of input and output coordinates and in which directions the - Mapping should be defined. */ - if ( astOK ) { - new = (AstCmpMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, nout, map_f, map_i ); - - if ( astOK ) { - -/* Initialise the CmpMap data. */ -/* --------------------------- */ -/* Store pointers to the component Mappings. Extract Mappings if - FrameSets are provided. */ - if( astIsAFrameSet( map1 ) ) { - new->map1 = astGetMapping( (AstFrameSet *) map1, AST__BASE, - AST__CURRENT ); - } else { - new->map1 = astClone( map1 ); - } - - if( astIsAFrameSet( map2 ) ) { - new->map2 = astGetMapping( (AstFrameSet *) map2, AST__BASE, - AST__CURRENT ); - } else { - new->map2 = astClone( map2 ); - } - - -/* Save the initial values of the inversion flags for these Mappings. */ - new->invert1 = astGetInvert( new->map1 ); - new->invert2 = astGetInvert( new->map2 ); - -/* Note whether the Mappings are joined in series (instead of in parallel), - constraining this flag to be 0 or 1. */ - new->series = ( series != 0 ); - -/* If an error occurred, clean up by annulling the Mapping pointers and - deleting the new object. */ - if ( !astOK ) { - new->map1 = astAnnul( new->map1 ); - new->map2 = astAnnul( new->map2 ); - new = astDelete( new ); - } - } - } - -/* Return a pointer to the new object. */ - return new; -} - -AstCmpMap *astLoadCmpMap_( void *mem, size_t size, - AstCmpMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadCmpMap - -* Purpose: -* Load a CmpMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpmap.h" -* AstCmpMap *astLoadCmpMap( void *mem, size_t size, -* AstCmpMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* CmpMap loader. - -* Description: -* This function is provided to load a new CmpMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* CmpMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a CmpMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the CmpMap is to be -* loaded. This must be of sufficient size to accommodate the -* CmpMap data (sizeof(CmpMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the CmpMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the CmpMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstCmpMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new CmpMap. If this is NULL, a pointer to -* the (static) virtual function table for the CmpMap class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "CmpMap" is used instead. - -* Returned Value: -* A pointer to the new CmpMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstCmpMap *new; /* Pointer to the new CmpMap */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this CmpMap. In this case the - CmpMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstCmpMap ); - vtab = &class_vtab; - name = "CmpMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitCmpMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built CmpMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "CmpMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Series. */ -/* ------- */ - new->series = astReadInt( channel, "series", 1 ); - new->series = ( new->series != 0 ); - -/* First Invert flag. */ -/* ------------------ */ - new->invert1 = astReadInt( channel, "inva", 0 ); - new->invert1 = ( new->invert1 != 0 ); - -/* Second Invert flag. */ -/* ------------------- */ - new->invert2 = astReadInt( channel, "invb", 0 ); - new->invert2 = ( new->invert2 != 0 ); - -/* First Mapping. */ -/* -------------- */ - new->map1 = astReadObject( channel, "mapa", NULL ); - -/* Second Mapping. */ -/* --------------- */ - new->map2 = astReadObject( channel, "mapb", NULL ); - -/* If an error occurred, clean up by deleting the new CmpMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new CmpMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -/* None. */ - - - - - - - - diff --git a/ast/cmpmap.h b/ast/cmpmap.h deleted file mode 100644 index ed305bb..0000000 --- a/ast/cmpmap.h +++ /dev/null @@ -1,300 +0,0 @@ -#if !defined( CMPMAP_INCLUDED ) /* Include this file only once */ -#define CMPMAP_INCLUDED -/* -*+ -* Name: -* cmpmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the CmpMap class. - -* Invocation: -* #include "cmpmap.h" - -* Description: -* This include file defines the interface to the CmpMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* A CmpMap is a compound Mapping which allows two component -* Mappings (of any class) to be connected together to form a more -* complex Mapping. This connection may either be "in series" -* (where the first Mapping is used to transform the coordinates of -* each point and the second mapping is then applied to the -* result), or "in parallel" (where one Mapping transforms the -* earlier coordinates for each point and the second Mapping -* simultaneously transforms the later coordinates). -* -* Since a CmpMap is itself a Mapping, it can be used as a -* component in forming further CmpMaps. Mappings of arbitrary -* complexity may be built from simple individual Mappings in this -* way. - -* Inheritance: -* The CmpMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* astSimplify -* Simplify a CmpMap. -* -* Protected: -* astMapList -* Decompose a CmpMap into a sequence of simpler Mappings. -* astTransform -* Transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsACmpMap -* Test class membership. -* astCmpMap -* Create a CmpMap. -* -* Protected: -* astCheckCmpMap -* Validate class membership. -* astInitCmpMap -* Initialise a CmpMap. -* astInitCmpMapVtab -* Initialise the virtual function table for the CmpMap class. -* astLoadCmpMap -* Load a CmpMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstCmpMap -* CmpMap object type. -* -* Protected: -* AstCmpMapVtab -* CmpMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 6-FEB-1996 (RFWS): -* Original version. -* 25-SEP-1996 (RFWS): -* Implemented external interface and I/O facilities. -* 13-DEC-1996 (RFWS): -* Over-ride the astSimplify method. -* 8-JAN-2003 (DSB): -* Added protected astInitCmpMapVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* CmpMap structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstCmpMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstMapping *map1; /* Pointer to first Mapping */ - AstMapping *map2; /* Pointer to second Mapping */ - char invert1; /* Inversion flag for first Mapping */ - char invert2; /* Inversion flag for second Mapping */ - char series; /* Connect in series (else in parallel)? */ -} AstCmpMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstCmpMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -/* None. */ -} AstCmpMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstCmpMapGlobals { - AstCmpMapVtab Class_Vtab; - int Class_Init; - int Simplify_Depth; - AstMapping **Simplify_Stackmaps; -} AstCmpMapGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(CmpMap) /* Check class membership */ -astPROTO_ISA(CmpMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstCmpMap *astCmpMap_( void *, void *, int, const char *, int *, ...); -#else -AstCmpMap *astCmpMapId_( void *, void *, int, const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstCmpMap *astInitCmpMap_( void *, size_t, int, AstCmpMapVtab *, - const char *, AstMapping *, AstMapping *, int, int * ); - -/* Vtab initialiser. */ -void astInitCmpMapVtab_( AstCmpMapVtab *, const char *, int * ); - -/* Loader. */ -AstCmpMap *astLoadCmpMap_( void *, size_t, AstCmpMapVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitCmpMapGlobals_( AstCmpMapGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -/* None. */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckCmpMap(this) astINVOKE_CHECK(CmpMap,this,0) -#define astVerifyCmpMap(this) astINVOKE_CHECK(CmpMap,this,1) - -/* Test class membership. */ -#define astIsACmpMap(this) astINVOKE_ISA(CmpMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astCmpMap astINVOKE(F,astCmpMap_) -#else -#define astCmpMap astINVOKE(F,astCmpMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitCmpMap(mem,size,init,vtab,name,map1,map2,series) \ -astINVOKE(O,astInitCmpMap_(mem,size,init,vtab,name,astCheckMapping(map1),astCheckMapping(map2),series,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitCmpMapVtab(vtab,name) astINVOKE(V,astInitCmpMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadCmpMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadCmpMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckCmpMap to validate CmpMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -/* None. */ -#endif - - - - - diff --git a/ast/cmpregion.c b/ast/cmpregion.c deleted file mode 100644 index c3b5b07..0000000 --- a/ast/cmpregion.c +++ /dev/null @@ -1,5127 +0,0 @@ -/* -*class++ -* Name: -* CmpRegion - -* Purpose: -* A combination of two regions within a single Frame - -* Constructor Function: -c astCmpRegion -f AST_CMPREGION - -* Description: -* A CmpRegion is a Region which allows two component -* Regions (of any class) to be combined to form a more complex -* Region. This combination may be performed a boolean AND, OR -* or XOR (exclusive OR) operator. If the AND operator is -* used, then a position is inside the CmpRegion only if it is -* inside both of its two component Regions. If the OR operator is -* used, then a position is inside the CmpRegion if it is inside -* either (or both) of its two component Regions. If the XOR operator -* is used, then a position is inside the CmpRegion if it is inside -* one but not both of its two component Regions. Other operators can -* be formed by negating one or both component Regions before using -* them to construct a new CmpRegion. -* -* The two component Region need not refer to the same coordinate -* Frame, but it must be possible for the -c astConvert -f AST_CONVERT -* function to determine a Mapping between them (an error will be -* reported otherwise when the CmpRegion is created). For instance, -* a CmpRegion may combine a Region defined within an ICRS SkyFrame -* with a Region defined within a Galactic SkyFrame. This is -* acceptable because the SkyFrame class knows how to convert between -* these two systems, and consequently the -c astConvert -f AST_CONVERT -* function will also be able to convert between them. In such cases, -* the second component Region will be mapped into the coordinate Frame -* of the first component Region, and the Frame represented by the -* CmpRegion as a whole will be the Frame of the first component Region. -* -* Since a CmpRegion is itself a Region, it can be used as a -* component in forming further CmpRegions. Regions of arbitrary -* complexity may be built from simple individual Regions in this -* way. - -* Inheritance: -* The CmpRegion class inherits from the Region class. - -* Attributes: -* The CmpRegion class does not define any new attributes beyond those -* which are applicable to all Regions. - -* Functions: -c The CmpRegion class does not define any new functions beyond those -f The CmpRegion class does not define any new routines beyond those -* which are applicable to all Regions. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 7-OCT-2004 (DSB): -* Original version. -* 28-MAY-2007 (DSB): -* - Corrected RegBaseMesh. -* - In RegBaseBox, if the CmpRegion is bounded find the box by -* finding the extreme position sin a mesh covering the boundary. -* 20-JAN-2009 (DSB): -* Over-ride astRegBasePick. -* 19-MAR-2009 (DSB): -* Over-ride the astDecompose method. -* 8-SEP-2009 (DSB): -* Fix logic in RegTrace. -* 9-SEP-2009 (DSB): -* - Added astCmpRegionList -* - Added support for XOR -* - Override astGetObjSize. -* 27-APR-2012 (DSB): -* - Cache the bounded property. -* - Speed up plotting of CmpRegions by using the cached negation -* of a Region instead of setting the Regions's Negated flag (which -* causes the Region's cache to be cleared). -* 30-APR-2012 (DSB): -* Use geodesic distance to measure distances around the two component -* Regions when tracing the border. Previously, a distance normalised -* from zero to one was used for both component Regions, but this gives -* greater priority to Regions higher in the CmpRegion nesting order, -* resulting in a high chance that lower Regions will not be seen. -* 7-JUN-2012 (DSB): -* Override astRegSplit method. -* 21-NOV-2012 (DSB): -* Map the regions returned by RegSplit into the current Frame of the -* CmpRegion. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS CmpRegion - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "region.h" /* Regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "nullregion.h" /* Boundless Regions */ -#include "cmpregion.h" /* Interface definition for this class */ -#include "unitmap.h" /* Unit Mapings */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *(* parent_getdefunc)( AstRegion *, int * ); -static void (* parent_setregfs)( AstRegion *, AstFrame *, int * ); -static AstMapping *(* parent_simplify)( AstMapping *, int * ); -static int (* parent_equal)( AstObject *, AstObject *, int * ); -static void (* parent_setclosed)( AstRegion *, int, int * ); -static void (* parent_setmeshsize)( AstRegion *, int, int * ); -static void (* parent_clearclosed)( AstRegion *, int * ); -static void (* parent_clearmeshsize)( AstRegion *, int * ); -static double (*parent_getfillfactor)( AstRegion *, int * ); -static void (*parent_regsetattrib)( AstRegion *, const char *, char **, int * ); -static void (*parent_regclearattrib)( AstRegion *, const char *, char **, int * ); -static void (* parent_resetcache)( AstRegion *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(CmpRegion) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(CmpRegion,Class_Init) -#define class_vtab astGLOBAL(CmpRegion,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstCmpRegionVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstCmpRegion *astCmpRegionId_( void *, void *, int, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *GetDefUnc( AstRegion *, int * ); -static AstRegion *MatchRegion( AstRegion *, int, AstRegion *, const char *, int * ); -static AstRegion *RegBasePick( AstRegion *this, int, const int *, int * ); -static AstRegion **RegSplit( AstRegion *, int *, int * ); -static double GetFillFactor( AstRegion *, int * ); -static int CmpRegionList( AstCmpRegion *, int *, AstRegion ***, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetBounded( AstRegion *, int * ); -static int GetObjSize( AstObject *, int * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static int RegTrace( AstRegion *, int, double *, double **, int * ); -static void ClearClosed( AstRegion *, int * ); -static void ClearMeshSize( AstRegion *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Decompose( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void GetRegions( AstCmpRegion *, AstRegion **, AstRegion **, int *, int *, int *, int * ); -static void RegBaseBox( AstRegion *, double *, double *, int * ); -static void RegBaseBox2( AstRegion *, double *, double *, int * ); -static void RegClearAttrib( AstRegion *, const char *, char **, int * ); -static void RegSetAttrib( AstRegion *, const char *, char **, int * ); -static void ResetCache( AstRegion *this, int * ); -static void SetBreakInfo( AstCmpRegion *, int, int * ); -static void SetClosed( AstRegion *, int, int * ); -static void SetMeshSize( AstRegion *, int, int * ); -static void SetRegFS( AstRegion *, AstFrame *, int * ); -static void XORCheck( AstCmpRegion *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Member functions. */ -/* ================= */ -int CmpRegionList( AstCmpRegion *this, int *nreg, AstRegion ***reg_list, - int *status ) { -/* -*+ -* Name: -* astCmpRegionList - -* Purpose: -* Decompose a CmpRegion into a sequence of simpler Regions. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "cmpregion.h" -* int astCmpRegionList( AstCmpRegion *this, int *nreg, -* AstRegion ***reg_list, int *status ) - -* Class Membership: -* CmpRegion method. - -* Description: -* This function decomposes a CmpRegion into a sequence of simpler -* Regions which may be applied in sequence to achieve the same -* effect. - -* Parameters: -* this -* Pointer to the CmpRegion to be decomposed (the CmpRegion is not -* actually modified by this function). -* nreg -* The address of an int which holds a count of the number of -* individual Regions in the decomposition. On entry, this -* should count the number of Regions already in the -* "*reg_list" array (below). On exit, it is updated to include -* any new Regions appended by this function. -* reg_list -* Address of a pointer to an array of Region pointers. On -* entry, this array pointer should either be NULL (if no -* Regions have yet been obtained) or should point at a -* dynamically allocated array containing Region pointers -* ("*nreg" in number) which have been obtained from a previous -* invocation of this function. -* -* On exit, the dynamic array will be enlarged to contain any -* new Region pointers that result from the decomposition -* requested. These pointers will be appended to any previously -* present, and the array pointer will be updated as necessary -* to refer to the enlarged array (any space released by the -* original array will be freed automatically). -* -* The new Region pointers returned will identify a sequence of -* Region which, when applied in order, will represent an area -* equivalent to that of the original Region. -* -* All the Region pointers returned by this function should be -* annulled by the caller, using astAnnul, when no longer -* required. The dynamic array holding these pointers should -* also be freed, using astFree. - -* Returned Value: -* An integer identifying the boolean operation that should be used to -* combine the Regions returned in "reg_list". This will be AST__AND -* or AST__OR. - -*- -*/ - -/* Local Variables: */ - AstCmpRegion *cmpreg; - int add; - int result; - -/* Check the global error status. */ - if ( !astOK ) return AST__AND; - -/* Check if this CmpRegion has an equivalent XOR representation. Is so, - store details of the XOR representation in the CmpRegion. */ - XORCheck( this, status ); - -/* The CmpRegion class only has full support for AND and OR operators. - However, it can also represent XOR operators, but it does this by - an equivalent set of AND and OR operators. When an XOR CmpRegion is - created, the original supplied argument regions are stored in - "this->xor1" and "this->xor2", and the component Regions placed in the - new CmpRegion are actually CmpRegions that implement the equivalent - of an XOR operation, using AND and OR operators. We want to hide this - to the outside world, so if the supplied CmpRegion represents an XOR - operation, add the XOR regions to the returned list, and return an - XOR operator. */ - if( this->xor1 ) { - *reg_list = astGrow( *reg_list, *nreg + 2, sizeof( AstRegion * ) ); - if( astOK ) { - ( *reg_list )[ (*nreg)++ ] = astClone( this->xor1 ); - ( *reg_list )[ (*nreg)++ ] = astClone( this->xor2 ); - } - result = AST__XOR; - -/* For AND and OR operators, we deal with the component Regions directly. */ - } else { - -/* If the first component of the supplied CmpRegion is itself a CmpRegion - that uses the same boolean operator as "this", call this function - recursively to add its component Regions to the returned list. */ - add = 1; - if( astIsACmpRegion( this->region1 ) ) { - cmpreg = (AstCmpRegion *) this->region1; - if( cmpreg->oper == this->oper ) { - (void) CmpRegionList( cmpreg, nreg, reg_list, status ); - add = 0; - } - } - -/* Otherwise, add the component Region directly into the returned list of - Regions. */ - if( add ) { - *reg_list = astGrow( *reg_list, *nreg + 1, sizeof( AstRegion * ) ); - if( astOK ) { - ( *reg_list )[ *nreg ] = astClone( this->region1 ); - ( *nreg )++; - } - } - -/* Do the same for the second component region */ - add = 1; - if( astIsACmpRegion( this->region2 ) ) { - cmpreg = (AstCmpRegion *) this->region2; - if( cmpreg->oper == this->oper ) { - (void) CmpRegionList( cmpreg, nreg, reg_list, status ); - add = 0; - } - } - - if( add ) { - *reg_list = astGrow( *reg_list, *nreg + 1, sizeof( AstRegion * ) ); - if( astOK ) { - ( *reg_list )[ *nreg ] = astClone( this->region2 ); - ( *nreg )++; - } - } - - result = this->oper; - } - -/* Return the boolean operator used to combine the regions in the - returned array. */ - return result; -} - -static void Decompose( AstMapping *this_mapping, AstMapping **map1, - AstMapping **map2, int *series, int *invert1, - int *invert2, int *status ) { -/* -* -* Name: -* Decompose - -* Purpose: -* Decompose a CmpRegion into two component Regions. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void Decompose( AstMapping *this, AstMapping **map1, -* AstMapping **map2, int *series, -* int *invert1, int *invert2, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the protected astDecompose -* method inherited from the Mapping class). - -* Description: -* This function returns pointers to two Mappings which, when applied -* either in series or parallel, are equivalent to the supplied Mapping. -* -* Since the Frame class inherits from the Mapping class, Frames can -* be considered as special types of Mappings and so this method can -* be used to decompose either CmpMaps, CmpFrames, CmpRegions or Prisms. - -* Parameters: -* this -* Pointer to the Mapping. -* map1 -* Address of a location to receive a pointer to first component -* Mapping. -* map2 -* Address of a location to receive a pointer to second component -* Mapping. -* series -* Address of a location to receive a value indicating if the -* component Mappings are applied in series or parallel. A non-zero -* value means that the supplied Mapping is equivalent to applying map1 -* followed by map2 in series. A zero value means that the supplied -* Mapping is equivalent to applying map1 to the lower numbered axes -* and map2 to the higher numbered axes, in parallel. -* invert1 -* The value of the Invert attribute to be used with map1. -* invert2 -* The value of the Invert attribute to be used with map2. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Any changes made to the component rames using the returned -* pointers will be reflected in the supplied CmpFrame. - -*- -*/ - - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to CmpRegion structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpMap structure. */ - this = (AstCmpRegion *) this_mapping; - -/* The components Frames of a CmpRegion are considered to be series - Mappings. */ - if( series ) *series = 1; - -/* The Frames are returned in their original order whether or not the - CmpRegion has been inverted. */ - if( map1 ) *map1 = astClone( this->region1 ); - if( map2 ) *map2 = astClone( this->region2 ); - -/* The invert flags dont mean anything for a Region, but we return them - anyway. If the CmpRegion has been inverted, return inverted Invert flags. */ - if( astGetInvert( this ) ) { - if( invert1 ) *invert1 = astGetInvert( this->region1 ) ? 0 : 1; - if( invert2 ) *invert2 = astGetInvert( this->region2 ) ? 0 : 1; - -/* If the CmpRegion has not been inverted, return the current Invert flags. */ - } else { - if( invert1 ) *invert1 = astGetInvert( this->region1 ); - if( invert2 ) *invert2 = astGetInvert( this->region2 ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two Objects are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* int Equal( AstObject *this_object, AstObject *that_object, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astEqual protected -* method inherited from the Region class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two CmpRegions are equivalent. - -* Parameters: -* this -* Pointer to the first CmpRegion. -* that -* Pointer to the second CmpRegion. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the CmpRegions are equivalent, zero otherwise. - -* Notes: -* - The CmpRegions are equivalent if their component Regions are -* equivalent and if they have the same boolean operation, negation -* and closed flags. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpRegion *that; - AstCmpRegion *this; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the Equal method inherited from the parent Region class. This checks - that the Objects are both of the same class, and have the same Negated - and Closed flags (amongst other things). */ - if( (*parent_equal)( this_object, that_object, status ) ) { - -/* Obtain pointers to the two CmpRegion structures. */ - this = (AstCmpRegion *) this_object; - that = (AstCmpRegion *) that_object; - -/* Test their first component Regions for equality. */ - if( astEqual( this->region1, that->region1 ) ) { - -/* Test their second component Regions for equality. */ - if( astEqual( this->region2, that->region2 ) ) { - -/* Test their boolean operator for equality. */ - if( this->oper == that->oper ) result = 1; - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -/* -* Name: -* MAKE_SET - -* Purpose: -* Define a function to set an attribute value for a CmpRegion. - -* Type: -* Private macro. - -* Synopsis: -* #include "cmpregion.h" -* MAKE_SET(attribute,lattribute,type) - -* Class Membership: -* Defined by the CmpRegion class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Set( AstRegion *this, value ) -* -* that sets the value of a specified Region attribute in the parent -* Region structure and also in the component Regions. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* lattribute -* Name of the attribute, all in lower case. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_SET(attribute,lattribute,type) \ -static void Set##attribute( AstRegion *this_region, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstCmpRegion *this; /* Pointer to the CmpRegion structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Use the parent method to set the value in the parent Region structure. */ \ - (*parent_set##lattribute)( this_region, value, status ); \ -\ -/* Also set the value in the two component Regions. */ \ - this = (AstCmpRegion *) this_region; \ - astSet##attribute( this->region1, value ); \ - astSet##attribute( this->region2, value ); \ -} - -/* Use the above macro to create accessors for the MeshSize and Closed attributes. */ -MAKE_SET(MeshSize,meshsize,int) -MAKE_SET(Closed,closed,int) - -/* Undefine the macro. */ -#undef MAKE_SET - -/* -* Name: -* MAKE_CLEAR - -* Purpose: -* Define a function to clear an attribute value for a CmpRegion. - -* Type: -* Private macro. - -* Synopsis: -* #include "cmpregion.h" -* MAKE_CLEAR(attribute,lattribute) - -* Class Membership: -* Defined by the CmpRegion class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Clear( AstRegion *this ) -* -* that sets the value of a specified Region attribute in the parent -* Region structure and also in the component Regions. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* lattribute -* Name of the attribute, all in lower case. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attribute,lattribute) \ -static void Clear##attribute( AstRegion *this_region, int *status ) { \ -\ -/* Local Variables: */ \ - AstCmpRegion *this; /* Pointer to the CmpRegion structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Use the parent method to clear the value in the parent Region structure. */ \ - (*parent_clear##lattribute)( this_region, status ); \ -\ -/* Also clear the value in the two component Regions. */ \ - this = (AstCmpRegion *) this_region; \ - astClear##attribute( this->region1 ); \ - astClear##attribute( this->region2 ); \ -} - -/* Use the above macro to create accessors for the MeshSize and Closed attributes. */ -MAKE_CLEAR(MeshSize,meshsize) -MAKE_CLEAR(Closed,closed) - -/* Undefine the macro. */ -#undef MAKE_CLEAR - -static int GetBounded( AstRegion *this_region, int *status ) { -/* -* Name: -* GetBounded - -* Purpose: -* Is the Region bounded? - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* int GetBounded( AstRegion *this, int *status ) - -* Class Membership: -* CmpRegion method (over-rides the astGetBounded method inherited from -* the Region class). - -* Description: -* This function returns a flag indicating if the Region is bounded. -* The implementation provided by the base Region class is suitable -* for Region sub-classes representing the inside of a single closed -* curve (e.g. Circle, Ellipse, Box, etc). Other sub-classes (such as -* CmpRegion, PointList, etc ) may need to provide their own -* implementations. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Region is bounded. Zero otherwise. - -*/ - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to CmpRegion structure */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - int neg1; /* Negated flag to use with first component */ - int neg2; /* Negated flag to use with second component */ - int oper; /* Combination operator */ - int overlap; /* Nature of overlap between components */ - int reg1b; /* Is the first component Region bounded?*/ - int reg2b; /* Is the second component Region bounded?*/ - int result; /* Returned result */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* Only calculated a new value if there is no cached value in the Region. */ - if( this->bounded == -INT_MAX ) { - -/* Get the component Regions, how they should be combined, and the - Negated values which should be used with them. The returned values - take account of whether the supplied CmpRegion has itself been Negated - or not. The returned Regions represent regions within the base Frame - of the FrameSet encapsulated by the parent Region structure. */ - GetRegions( this, ®1, ®2, &oper, &neg1, &neg2, status ); - -/* If the first component Region does not have the required value for - its "Negated" attribute, use the negation of "reg1" in place of "reg1" - itself. */ - if( neg1 != astGetNegated( reg1 ) ) { - AstRegion *tmp = astGetNegation( reg1 ); - (void) astAnnul( reg1 ); - reg1 = tmp; - } - -/* If the second component Region does not have the required value for - its "Negated" attribute, use the negation of "reg2" in place of "reg2" - itself. */ - if( neg2 != astGetNegated( reg2 ) ) { - AstRegion *tmp = astGetNegation( reg2 ); - (void) astAnnul( reg2 ); - reg2 = tmp; - } - -/* See if either of the component Regions is bounded. */ - reg1b = astGetBounded( reg1 ); - reg2b = astGetBounded( reg2 ); - -/* If the regions are ANDed... */ - if( oper == AST__AND ) { - -/* If either one of the two components are bounded, then the AND region is - bounded. */ - if( reg1b || reg2b ) { - result = 1; - -/* If neither of the two components is bounded, then the AND region is - unbounded if there is partial or no overlap between them and is bounded - otherwise. */ - } else { - overlap = astOverlap( reg1, reg2 ); - if( overlap == 1 || overlap == 4 || overlap == 6 ) { - result = 0; - } else { - result = 1; - } - } - -/* If the regions are ORed... */ - } else { - -/* If either one of the two components is unbounded, then the OR region is - unbounded. */ - if( !reg1b || !reg2b ) { - result = 0; - -/* If both of the two components are bounded, then the OR region is also - bounded. */ - } else { - result = 1; - } - } - -/* Free resources. */ - reg1 = astAnnul( reg1 ); - reg2 = astAnnul( reg2 ); - -/* Cache the value in the CmpRegion. */ - this->bounded = astOK ? result : -INT_MAX; - } - -/* Return zero if an error occurred. Otherwise, return the cached value. */ - if( astOK ) { - result = ( this->bounded == -INT_MAX ) ? 0 : this->bounded; - } else { - result = 0; - } - -/* Return the required pointer. */ - return result; -} - -static double GetFillFactor( AstRegion *this_region, int *status ) { -/* -* Name: -* GetFillFactor - -* Purpose: -* Obtain the value of the FillFactor attribute for a CmpRegion. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* double GetFillFactor( AstRegion *this, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astGetFillFactor method inherited -* from the Region class). - -* Description: -* This function returns the value of the FillFactor attribute for a -* CmpRegion. A suitable default value is returned if no value has -* previously been set. - -* Parameters: -* this -* Pointer to the CmpRegion. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The FillFactor value to use. - -*/ - -/* Local Variables: */ - AstCmpRegion *this; - double result; - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Initialise. */ - result = AST__BAD; - -/* Obtain a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* See if a FillFactor value has been set. If so, use the parent - astGetFillFactor method to obtain it. */ - if ( astTestFillFactor( this ) ) { - result = (*parent_getfillfactor)( this_region, status ); - -/* Otherwise, we will generate a default value equal to the FillFactor values - of the first component Region. */ - } else { - result = astGetFillFactor( this->region1 ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied CmpRegion, -* in bytes. - -* Parameters: -* this -* Pointer to the CmpRegion. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to CmpRegion structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the CmpRegion structure. */ - this = (AstCmpRegion *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astGetObjSize( this->region1 ); - result += astGetObjSize( this->region2 ); - if( this->xor1 ) result += astGetObjSize( this->xor1 ); - if( this->xor2 ) result += astGetObjSize( this->xor2 ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void GetRegions( AstCmpRegion *this, AstRegion **reg1, AstRegion **reg2, - int *oper, int *neg1, int *neg2, int *status ) { -/* -* -* Name: -* GetRegions - -* Purpose: -* Get the component Regions of a CmpRegion. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void GetRegions( AstCmpRegion *this, AstRegion **reg1, AstRegion **reg2, -* int *oper, int *neg1, int *neg2, int *status ) - -* Class Membership: -* CmpRegion member function - -* Description: -* This function returns pointers to two Regions which, when applied -* using the returned boolean operator, are equivalent to the supplied -* Region. If the CmpRegion has been negated, then the returned operator -* and "negated" flags will be set such that they represent the -* negated CmpRegion. -* -* The current Frames in both the returned component Regions will be -* equivalent to the base Frame in the FrameSet encapsulated by the -* parent Region structure. - -* Parameters: -* this -* Pointer to the CmpRegion. -* reg1 -* Address of a location to receive a pointer to first component -* Region. The current Frame in this region will be equivalent to -* the base Frame in the FrameSet -* reg2 -* Address of a location to receive a pointer to second component -* Region. -* oper -* Address of a location to receive a value indicating how the -* component Regions are combined together. This will be one of -* AST__AND or AST__OR -* neg1 -* The value of the Negated attribute to be used with reg1. -* neg2 -* The value of the Negated attribute to be used with reg2. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Any changes made to the component Regions using the returned -* pointers will be reflected in the supplied CmpRegion. - -*- -*/ - -/* Initialise */ - if( reg1 ) *reg1 = NULL; - if( reg2 ) *reg2 = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Return the component Region pointers. */ - if( reg1 ) *reg1 = astClone( this->region1 ); - if( reg2 ) *reg2 = astClone( this->region2 ); - -/* Initialise the other returned items. Note, the CmpRegion initialiser - stored a deep copy of the supplied component Regions, and so we do not - need to worry about attributes of the components having been changed - after the creation of the CmpRegion. This is different to the CmpMap - class which merely clones its supplied component pointers and so has - to save copies of the original Invert settings within the CmpMap - structure. */ - if( oper ) *oper = this->oper; - if( neg1 ) *neg1 = astGetNegated( this->region1 ); - if( neg2 ) *neg2 = astGetNegated( this->region2 ); - -/* If the CmpRegion has been inverted, we modify the boolean operator and - negation flags so that they reflect the inverted CmpRegion. */ - if( astGetNegated( this ) ) { - -/* If the component Regions are combined using AND, then the negated - CmpRegion combines its negated components using OR. */ - if( this->oper == AST__AND ){ - if( oper ) *oper = AST__OR; - if( neg1 ) *neg1 = *neg1 ? 0 : 1; - if( neg2 ) *neg2 = *neg2 ? 0 : 1; - -/* If the component Regions are combined using OR, then the negated CmpRegion - combines its negated components using AND. */ - } else if( this->oper == AST__OR ){ - if( oper ) *oper = AST__AND; - if( neg1 ) *neg1 = *neg1 ? 0 : 1; - if( neg2 ) *neg2 = *neg2 ? 0 : 1; - - } else if( astOK ) { - astError( AST__INTER, "GetRegions(%s): The %s refers to an unknown " - "boolean operator with identifier %d (internal AST " - "programming error).", status, astGetClass( this ), - astGetClass( this ), this->oper ); - } - } -} - -static AstRegion *GetDefUnc( AstRegion *this_region, int *status ) { -/* -* Name: -* GetDefUnc - -* Purpose: -* Obtain a pointer to the default uncertainty Region for a given Region. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* AstRegion *GetDefUnc( AstRegion *this ) - -* Class Membership: -* CmpRegion method (over-rides the astGetDefUnc method inherited from -* the Region class). - -* This function returns a pointer to a Region which represents the -* default uncertainty associated with a position on the boundary of the -* given Region. The returned Region refers to the base Frame within the -* FrameSet encapsulated by the supplied Region. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* A pointer to the Region. This should be annulled (using astAnnul) -* when no longer needed. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to CmpRegion structure */ - AstRegion *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* If the first component region has non-default uncertainty, use it as - the default uncertainty for the CmpRegion. Note, the current Frame of - an uncertainty Region is assumed to be the same as the base Frame in the - CmpRegion. */ - if( astTestUnc( this->region1 ) ) { - result = astGetUncFrm( this->region1, AST__CURRENT ); - -/* Otherwise, if the second component region has non-default uncertainty, - use it as the default uncertainty for the CmpRegion. */ - } else if( astTestUnc( this->region2 ) ) { - result = astGetUncFrm( this->region2, AST__CURRENT ); - -/* Otherwise, use the parent method to determine the default uncertainty. */ - } else { - result = (* parent_getdefunc)( this_region, status ); - } - -/* Return NULL if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the required pointer. */ - return result; -} - -void astInitCmpRegionVtab_( AstCmpRegionVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitCmpRegionVtab - -* Purpose: -* Initialise a virtual function table for a CmpRegion. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpregion.h" -* void astInitCmpRegionVtab( AstCmpRegionVtab *vtab, const char *name ) - -* Class Membership: -* CmpRegion vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the CmpRegion class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsACmpRegion) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - - vtab->CmpRegionList = CmpRegionList; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - - parent_getdefunc = region->GetDefUnc; - region->GetDefUnc = GetDefUnc; - - parent_setregfs = region->SetRegFS; - region->SetRegFS = SetRegFS; - - parent_resetcache = region->ResetCache; - region->ResetCache = ResetCache; - - parent_equal = object->Equal; - object->Equal = Equal; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_clearclosed = region->ClearClosed; - region->ClearClosed = ClearClosed; - - parent_clearmeshsize = region->ClearMeshSize; - region->ClearMeshSize = ClearMeshSize; - - parent_setclosed = region->SetClosed; - region->SetClosed = SetClosed; - - parent_setmeshsize = region->SetMeshSize; - region->SetMeshSize = SetMeshSize; - - parent_getfillfactor = region->GetFillFactor; - region->GetFillFactor = GetFillFactor; - - parent_regsetattrib = region->RegSetAttrib; - region->RegSetAttrib = RegSetAttrib; - - parent_regclearattrib = region->RegClearAttrib; - region->RegClearAttrib = RegClearAttrib; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - mapping->Decompose = Decompose; - region->RegBaseBox = RegBaseBox; - region->RegBaseBox2 = RegBaseBox2; - region->RegBaseMesh = RegBaseMesh; - region->RegSplit = RegSplit; - region->RegPins = RegPins; - region->RegTrace = RegTrace; - region->GetBounded = GetBounded; - region->RegBasePick = RegBasePick; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "CmpRegion", "Combination of two Regions" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to CmpRegion structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the CmpRegion structure. */ - this = (AstCmpRegion *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->region1, mode, extra, fail ); - if( !result ) result = astManageLock( this->region2, mode, extra, fail ); - - return result; - -} -#endif - -static AstRegion *MatchRegion( AstRegion *this, int ifrm, AstRegion *that, - const char *method, int *status ) { -/* -* Name: -* MatchRegion - -* Purpose: -* Map a Region into the Frame of another Region. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* AstRegion *MatchRegion( AstRegion *this, int ifrm, AstRegion *that, -* const char *method, int *status ) - -* Class Membership: -* CmpRegion method. - -* Description: -* This function returns a pointer to a new Region which is a copy of -* "that" mapped into either the base or current Frame of "this". - -* Parameters: -* this -* Pointer to a Region defining the Frame of the returned Region. -* ifrm -* The index of a Frame within the FrameSet encapsulated by "this". -* The returned Region will refer to the requested Frame. It should -* be either AST__CURRENT or AST__BASE. -* that -* Pointer to a Region defining the shape and extent of the -* returned Region. -* method -* Pointer to a string holding the calling method.This is only used -* in error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a new Region. This should be annulled (using astAnnul) -* when no longer needed. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Current Frame from "fs" */ - AstFrameSet *fs; /* FrameSet connecting that to this */ - AstMapping *map; /* Base->Current Mapping from "fs" */ - AstRegion *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. Also return NULL if no Regions were - supplied. */ - if ( !astOK || !this || !that ) return result; - -/* Temporarily invert "this" if we are matching its base Frame (since the - astConvert method matches current Frames). */ - if( ifrm == AST__BASE ) astInvert( this ); - -/* Find a FrameSet connecting the current Frames of the two Regions */ - fs = astConvert( that, this, "" ); - -/* Re-instate the original Frame indices in "this" if required. */ - if( ifrm == AST__BASE ) astInvert( this ); - -/* Check a conversion path was found. */ - if( fs ) { - -/* Get the Frame and Mapping form the FrameSet. */ - frm = astGetFrame( fs, AST__CURRENT ); - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - -/* Re-map the Region. */ - result = astMapRegion( that, map, frm ); - -/* Free resources. */ - frm = astAnnul( frm ); - map = astAnnul( map ); - fs = astAnnul( fs ); - -/* Report an error if there is no conversion between the two Frames. */ - } else { - astError( AST__INTER, "%s(%s): MatchRegion cannot convert between " - "the two supplied coordinate Frames (internal AST " - "programming error).", status, method, astGetClass( this ) ); - } - -/* Annul the returned pointer if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void RegBaseBox( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to CmpRegion structure */ - AstPointSet *ps; /* Mesh pointset */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - double **ptr; /* Pointer to mesh data */ - double *clbnd1; /* Point to 1st comp lower bounds array */ - double *clbnd2; /* Point to 2nd comp lower bounds array */ - double *cubnd1; /* Point to 1st comp upper bounds array */ - double *cubnd2; /* Point to 2nd comp upper bounds array */ - double *p; /* Pointer to next coordinate value */ - double lb; /* Lower limit */ - double ub; /* Upper limit */ - int i; /* Axis index */ - int icoord; /* Coordinate index */ - int inc1; /* First component interval is included? */ - int inc2; /* Second component interval is included? */ - int ipoint; /* Point index */ - int nax; /* Number of axes in Frame */ - int ncoord; /* Number of coords */ - int neg1; /* First component negated? */ - int neg2; /* Second component negated? */ - int npoint; /* Number of points */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the CmpRegion structure */ - this = (AstCmpRegion *) this_region; - -/* If the CmpRegion is bounded, we find the bounding box using a mesh of - points spread evenly over the boundary of the CmpRegion. */ - if( astGetBounded( this ) ) { - ps = astRegBaseMesh( this_region ); - ptr = astGetPoints( ps ); - ncoord = astGetNcoord( ps ); - npoint = astGetNpoint( ps ); - - if( astOK ) { - for( icoord = 0; icoord < ncoord; icoord++ ) { - lbnd[ icoord ] = DBL_MAX; - ubnd[ icoord ] = -DBL_MAX; - p = ptr[ icoord ]; - for( ipoint = 0; ipoint < npoint; ipoint++, p++ ) { - if( *p != AST__BAD ) { - if( *p < lbnd[ icoord ] ) lbnd[ icoord ] = *p; - if( *p > ubnd[ icoord ] ) ubnd[ icoord ] = *p; - } - } - } - } - ps = astAnnul( ps ); - -/* If the CmpRegion is not bounded we look at each axis individually. */ - } else { - -/* Get pointers to the component Regions. */ - reg1 = this->region1; - reg2 = this->region2; - -/* Get their negated flags */ - neg1 = astGetNegated( reg1 ); - neg2 = astGetNegated( reg2 ); - -/* The base Frame of the parent Region structure is the current Frame of - the component Regions. Get the no. of axes in this Frame. */ - nax = astGetNaxes( reg1 ); - -/* Get the bounding boxes of the component Regions in this Frame. */ - clbnd1 = astMalloc( sizeof( double )*(size_t) nax ); - cubnd1 = astMalloc( sizeof( double )*(size_t) nax ); - clbnd2 = astMalloc( sizeof( double )*(size_t) nax ); - cubnd2 = astMalloc( sizeof( double )*(size_t) nax ); - if( astOK ) { - astGetRegionBounds( reg1, clbnd1, cubnd1 ); - astGetRegionBounds( reg2, clbnd2, cubnd2 ); - -/* Loop round every axis. */ - for( i = 0; i < nax; i++ ) { - -/* If the first component Region has been negated, the lower and upper - bounds from the first component are the bounds of an *excluded* axis - interval, not an included interval. If either of the bounds are - infinite, we can swap it to an included interval. If both bounds are - finite, we cannot convert to an included interval. In this case, we - assume that the gap will be filled at some point on another axis, if - there is more than 1 axis, and convert it to an unbouded included - interval. */ - inc1 = 1; - if( neg1 ) { - lb = clbnd1[ i ]; - ub = cubnd1[ i ]; - if( lb == -DBL_MAX ) clbnd1[ i ] = ub; - if( ub == DBL_MAX ) cubnd1[ i ] = lb; - if( lb != -DBL_MAX && ub != DBL_MAX ) { - if( nax == 1 ) { - inc1 = 0; - } else { - clbnd1[ i ] = -DBL_MAX; - cubnd1[ i ] = DBL_MAX; - } - } - } - -/* Likewise attempt to convert an excluded interval into an included - interval for the second component Region. */ - inc2 = 1; - if( neg2 ) { - lb = clbnd2[ i ]; - ub = cubnd2[ i ]; - if( lb == -DBL_MAX ) clbnd2[ i ] = ub; - if( ub == DBL_MAX ) cubnd2[ i ] = lb; - if( lb != -DBL_MAX && ub != DBL_MAX ) { - if( nax == 1 ) { - inc2 = 0; - } else { - clbnd2[ i ] = -DBL_MAX; - cubnd2[ i ] = DBL_MAX; - } - } - } - -/* If the component Regions are combined using AND, find the overlap of - the axis intervals. This depends on whether the intervals are included - or excluded. */ - if( this->oper == AST__AND ) { - - if( inc1 ) { - if( inc2 ) { - lbnd[ i ] = astMAX( clbnd1[ i ], clbnd2[ i ] ); - ubnd[ i ] = astMIN( cubnd1[ i ], cubnd2[ i ] ); - } else { - lbnd[ i ] = clbnd1[ i ] < clbnd2[ i ] ? clbnd1[ i ] : cubnd2[ i ]; - ubnd[ i ] = cubnd1[ i ] > cubnd2[ i ] ? cubnd1[ i ] : clbnd2[ i ]; - } - } else { - if( inc2 ) { - lbnd[ i ] = clbnd2[ i ] < clbnd1[ i ] ? clbnd2[ i ] : cubnd1[ i ]; - ubnd[ i ] = cubnd2[ i ] > cubnd1[ i ] ? cubnd2[ i ] : clbnd1[ i ]; - } else { - lbnd[ i ] = clbnd1[ i ] < clbnd2[ i ] ? clbnd1[ i ] : cubnd2[ i ]; - ubnd[ i ] = cubnd1[ i ] > cubnd2[ i ] ? cubnd1[ i ] : clbnd2[ i ]; - } - } - -/* If the component Regions are not combined using AND, find the union of - the axis intervals. */ - } else { - if( inc1 && inc2 ) { - lbnd[ i ] = astMIN( clbnd1[ i ], clbnd2[ i ] ); - ubnd[ i ] = astMAX( cubnd1[ i ], cubnd2[ i ] ); - } else { - lbnd[ i ] = -DBL_MAX; - ubnd[ i ] = DBL_MAX; - } - } - } - } - -/* Free resources. */ - clbnd1 = astFree( clbnd1 ); - cubnd1 = astFree( cubnd1 ); - clbnd2 = astFree( clbnd2 ); - cubnd2 = astFree( cubnd2 ); - } -} - -static void RegBaseBox2( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox2 - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void RegBaseBox2( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astRegBaseBox2 protected -* method inherited from the Region class). - -* Description: -* This function is similar to astRegBaseBox in that it returns the -* upper and lower axis bounds of a Region in the base Frame of the -* encapsulated FrameSet. But, in addition to assuming that the -* supplied Region has not been negated, it also assumes that any -* component Regions contained within the supplied Region have not been -* negated. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to CmpRegion structure */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - double *clbnd1; /* Point to 1st comp lower bounds array */ - double *clbnd2; /* Point to 2nd comp lower bounds array */ - double *cubnd1; /* Point to 1st comp upper bounds array */ - double *cubnd2; /* Point to 2nd comp upper bounds array */ - int i; /* Axis index */ - int nax; /* Number of axes in Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the CmpRegion structure */ - this = (AstCmpRegion *) this_region; - -/* Get pointers to the component Regions. */ - reg1 = this->region1; - reg2 = this->region2; - -/* The base Frame of the parent Region structure is the current Frame of - the component Regions. Get the no. of axes in this Frame. */ - nax = astGetNaxes( reg1 ); - -/* Get the bounding boxes of the component Regions in this Frame. */ - clbnd1 = astMalloc( sizeof( double )*(size_t) nax ); - cubnd1 = astMalloc( sizeof( double )*(size_t) nax ); - clbnd2 = astMalloc( sizeof( double )*(size_t) nax ); - cubnd2 = astMalloc( sizeof( double )*(size_t) nax ); - if( astOK ) { - astGetRegionBounds2( reg1, clbnd1, cubnd1 ); - astGetRegionBounds2( reg2, clbnd2, cubnd2 ); - -/* How we combine the two bounding boxes depends on the boolean operator - associated with this CmpRegion. For AND find the overlap of the two - bounding boxes. For other operators find the union. */ - if( this->oper == AST__AND ) { - for( i = 0; i < nax; i++ ) { - lbnd[ i ]= astMAX( clbnd1[ i ], clbnd2[ i ] ); - ubnd[ i ]= astMIN( cubnd1[ i ], cubnd2[ i ] ); - } - - } else { - for( i = 0; i < nax; i++ ) { - lbnd[ i ]= astMIN( clbnd1[ i ], clbnd2[ i ] ); - ubnd[ i ]= astMAX( cubnd1[ i ], cubnd2[ i ] ); - } - } - } - -/* Free resources. */ - clbnd1 = astFree( clbnd1 ); - cubnd1 = astFree( cubnd1 ); - clbnd2 = astFree( clbnd2 ); - cubnd2 = astFree( cubnd2 ); - -} - -static AstPointSet *RegBaseMesh( AstRegion *this_region, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Return a PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* AstPointSet *astRegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. Annul the pointer using astAnnul when it -* is no longer needed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - - -/* Local Variables: */ - AstCmpRegion *this; /* The CmpRegion structure */ - AstPointSet *mesh1; /* PointSet holding mesh for 1st component */ - AstPointSet *mesh1b; /* Mesh for 1st component mapped by 2nd comp. */ - AstPointSet *mesh2; /* PointSet holding mesh for 2nd component */ - AstPointSet *mesh2b; /* Mesh for 2nd component mapped by 1st comp. */ - AstPointSet *result; /* Returned pointer */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - double **ptr1; /* Pointer to array of mesh1b axis value pointers */ - double **ptr2; /* Pointer to array of mesh2b axis value pointers */ - double **ptr; /* Pointer to array of total axis value pointers */ - double *lbnd; /* Pointer to array of bounding box lower bounds */ - double *ubnd; /* Pointer to array of bounding box upper bounds */ - double v; /* Axis value */ - int hasMesh1; /* Does 1st component Region have a mesh? */ - int hasMesh2; /* Does 2nd component Region have a mesh? */ - int ic; /* Axis index */ - int ip; /* Input point index */ - int jp; /* Output point index */ - int nc; /* No. of axis values per point */ - int np1; /* No. of points in mesh1b */ - int np2; /* No. of points in mesh2b */ - int np; /* No. of points in returned PointSet */ - int ok; /* Were all axis values good at this point? */ - -/* Initialise */ - result= NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* If the Region structure contains a pointer to a PointSet holding - a previously created mesh, return it. */ - if( this_region->basemesh ) { - result = astClone( this_region->basemesh ); - -/* Otherwise, create a new mesh. */ - } else { - -/* Get pointers to the component regions. */ - reg1 = this->region1; - reg2 = this->region2; - -/* A mesh can only be produced for a Region if it is bounded when either - negated or un-negated. See if meshes can be produced for the component - Regions. */ - hasMesh1 = astGetBounded( reg1 ); - if( !hasMesh1 ){ - astNegate( reg1 ); - hasMesh1 = astGetBounded( reg1 ); - astNegate( reg1 ); - } - - hasMesh2 = astGetBounded( reg2 ); - if( !hasMesh2 ){ - astNegate( reg2 ); - hasMesh2 = astGetBounded( reg2 ); - astNegate( reg2 ); - } - -/* If neither Region has a mesh we cannot produce a mesh. */ - if( !hasMesh1 && !hasMesh2 && astOK ) { - astError( AST__INTER, "astRegBaseMesh(%s): No mesh can be " - "produced for the %s bacause neither of its component " - "Regions has a mesh (internal AST programming error).", status, - astGetClass( this ), astGetClass( this ) ); - -/* If only one Region has a mesh, we can produce a mesh so long as the - boolean operator is not OR. */ - } else if( ( !hasMesh1 || !hasMesh2 ) && this->oper == AST__OR && astOK ) { - astError( AST__INTER, "astRegBaseMesh(%s): No mesh can be produced " - "for the %s bacause one its component Regions has no " - "mesh and the union of the Regions is required (internal " - "AST programming error).", status, astGetClass( this ), astGetClass( this ) ); - } - -/* Allocate memory to hold a bounding box in the base Frame of the CmpRegion. */ - nc = astGetNin( this_region->frameset ); - lbnd = astMalloc( sizeof( double )*(size_t) nc ); - ubnd = astMalloc( sizeof( double )*(size_t) nc ); - -/* Get current Frame meshes covering the two component Regions (the current - Frame of the component Regions is the same as the base Frame of the parent - Region). We now know that at least one Region has a mesh. If the other - one does not have a mesh we may be able to create a mesh by taking the - intersection of the Region with the bounding box of the bounded Region. */ - if( hasMesh1 ) { - mesh1 = astRegMesh( reg1 ); - if( hasMesh2 ) { - mesh2 = astRegMesh( reg2 ); - } else { - astGetRegionBounds( reg1, lbnd, ubnd ); - mesh2 = astBndMesh( reg2, lbnd, ubnd ); - } - - } else { - mesh2 = astRegMesh( reg2 ); - astGetRegionBounds( reg2, lbnd, ubnd ); - mesh1 = astBndMesh( reg1, lbnd, ubnd ); - } - -/* If the CmpRegion represents the intersection of the two component Regions - (AND operator), the total mesh is the sum of the component mesh points - which are inside the other component region. If the CmpRegion represents - the union of the two component Regions (OR operator), the total mesh is - the sum of the component mesh points which are outside the other component - region. So temporarily negate the component Regions if they are - combined using OR. */ - if( this->oper == AST__OR ) { - astNegate( reg1 ); - astNegate( reg2 ); - } - -/* Transform the mesh for the first component using the second component - as a Mapping. Mesh points outside (or inside if "oper" is OR) the bounds - of the second component will be set bad. */ - mesh1b = astTransform( reg2, mesh1, 1, NULL ); - -/* Transform the mesh for the second component using the first component - as a Mapping. Mesh points outside (or inside if "oper" is OR) the bounds - of the first component will be set bad. */ - mesh2b = astTransform( reg1, mesh2, 1, NULL ); - -/* If required, negate them again to bring them back to their original state.*/ - if( this->oper == AST__OR ) { - astNegate( reg1 ); - astNegate( reg2 ); - } - -/* The required mesh contains all the good points form both mesh1b and - mesh2b (i.e. all boundary points which are inside -or inside if "oper" - is OR- the other component Region). Create a PointSet assuming that all - points are good. First allocate an array to hold pointers to the arrays - holding coordinate values for each axis. */ - nc = astGetNcoord( mesh1b ); - np1 = astGetNpoint( mesh1b ); - np2 = astGetNpoint( mesh2b ); - np = np1 + np2; - result = astPointSet( np, nc, "", status ); - ptr = astGetPoints( result ); - -/* Get points to the axis values of the mapped meshes. */ - ptr1 = astGetPoints( mesh1b ); - ptr2 = astGetPoints( mesh2b ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Initialise the index of the next point in the total mesh. */ - jp = 0; - -/* Loop round all the points in the transformed mesh for the first - component. */ - for( ip = 0; ip < np1; ip++ ) { - -/* Assume this point has good axis values */ - ok = 1; - -/* Copy the axis values into the total mesh. Break if a bad axis value is - found. */ - for( ic = 0; ic < nc; ic++ ) { - v = ptr1[ ic ][ ip ]; - if( v != AST__BAD ) { - ptr[ ic ][ jp ] = v; - } else { - ok = 0; - break; - } - } - -/* If no bad axis values were found, increment the index of the next - point in the total mesh. */ - if( ok ) jp++; - } - -/* Now similarly copy the good values from the second transformed mesh onto - the end of the total mesh array. */ - for( ip = 0; ip < np2; ip++ ) { - ok = 1; - for( ic = 0; ic < nc; ic++ ) { - v = ptr2[ ic ][ ip ]; - if( v != AST__BAD ) { - ptr[ ic ][ jp ] = v; - } else { - ok = 0; - break; - } - } - if( ok ) jp++; - } - -/* If the total mesh contains no good points, we will create a PointSet - holding a single bad position. */ - if( jp == 0 ) { - np = 1; - for( ic = 0; ic < nc; ic++ ) ptr[ ic ][ 0 ] = AST__BAD; - } else { - np = jp; - } - -/* Adjust the size of the returned PointSet to exclude the extra space - caused by any axis values being bad in the transformed meshes. */ - astSetNpoint( result, np ); - - } - -/* Free resources. */ - mesh1 = astAnnul( mesh1 ); - mesh2 = astAnnul( mesh2 ); - mesh1b = astAnnul( mesh1b ); - mesh2b = astAnnul( mesh2b ); - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - -/* Save the returned pointer in the Region structure so that it does not - need to be created again next time this function is called. */ - if( astOK && result ) this_region->basemesh = astClone( result ); - } - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static AstRegion *RegBasePick( AstRegion *this_region, int naxes, - const int *axes, int *status ){ -/* -* Name: -* RegBasePick - -* Purpose: -* Return a Region formed by picking selected base Frame axes from the -* supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* AstRegion *RegBasePick( AstRegion *this, int naxes, const int *axes, -* int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astRegBasePick protected -* method inherited from the Region class). - -* Description: -* This function attempts to return a Region that is spanned by selected -* axes from the base Frame of the encapsulated FrameSet of the supplied -* Region. This may or may not be possible, depending on the class of -* Region. If it is not possible a NULL pointer is returned. - -* Parameters: -* this -* Pointer to the Region. -* naxes -* The number of base Frame axes to select. -* axes -* An array holding the zero-based indices of the base Frame axes -* that are to be selected. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Region, or NULL if no region can be formed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to CmpRegion structure */ - AstFrame *frm1; /* Axes picked from the 1st encapsulated Region */ - AstFrame *frm2; /* Axes picked from the 2nd encapsulated Region */ - AstRegion *result; /* Returned Region */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the CmpRegion information. */ - this = (AstCmpRegion *) this_region; - -/* Both encapsulated regions refer to the same Frame (the base Frame of - the parent Region), so attempt to pick the requested axs from them. - If the resulting Frames are not Regions, we cannot pick the requested - axes so return the NULL Frame pointer initialised above. */ - frm1 = astPickAxes( this->region1, naxes, axes, NULL ); - if( astIsARegion( frm1 ) ) { - frm2 = astPickAxes( this->region2, naxes, axes, NULL ); - if( astIsARegion( frm2 ) ) { - -/* Create the new CmpRegion. */ - result = (AstRegion *) astCmpRegion( (AstRegion *) frm1, - (AstRegion *) frm2, - this->oper, "", status ); - } - -/* Free resources */ - frm2 = astAnnul( frm2 ); - } - frm1 = astAnnul( frm1 ); - -/* Return a NULL pointer if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int RegPins( AstRegion *this_region, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -* Name: -* RegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given CmpRegion. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astRegPins protected -* method inherited from the Region class). - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given CmpRegion. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied CmpRegion "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the CmpRegion. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "pset". -* Each element in the returned array is set to 1 if the -* corresponding position in "pset" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*/ - -/* Local variables: */ - AstCmpRegion *this; /* Pointer to the CmpRegion structure. */ - AstPointSet *pset1; /* Points masked by 1st component Region */ - AstPointSet *pset2; /* Points masked by 2nd component Region */ - AstPointSet *psetb1; /* Points in base Frame of 1st component Region */ - AstPointSet *psetb2; /* Points in base Frame of 2nd component Region */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - AstRegion *unc1; /* Base Frame uncertainty in 1st component Region */ - AstRegion *unc2; /* Base Frame uncertainty in 2nd component Region */ - double **ptr1; /* Pointer to axis values in "pset1" */ - double **ptr2; /* Pointer to axis values in "pset2" */ - double *p1; /* Pointer to next axis zero value for pset1 */ - double *p2; /* Pointer to next axis zero value for pset2 */ - int *mask1; /* Mask for first component boundary */ - int *mask2; /* Mask for second component boundary */ - int ip; /* Point index */ - int np; /* Number of points */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - if( mask ) *mask = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* Get pointers to the two component Regions. */ - reg1 = this->region1; - reg2 = this->region2; - -/* Get a mask which indicates if each supplied point is on or off the - boundary of the first component Region. astRegPins expects its "pset" - argument to contain positions in the base Frame of the Region, so - we must first transform the supplied points into the base Frame of - "reg1". We must also map the uncertainty into the base Frame of the - component Region. */ - psetb1 = astRegTransform( reg1, pset, 0, NULL, NULL ); - unc1 = MatchRegion( reg1, AST__BASE, unc, "astRegPins", status ); - astRegPins( reg1, psetb1, unc1, &mask1 ); - -/* Likewise, get a mask which indicates if each supplied point is on or off - the boundary of the second component Region. */ - psetb2 = astRegTransform( reg2, pset, 0, NULL, NULL ); - unc2 = MatchRegion( reg2, AST__BASE, unc, "astRegPins", status ); - astRegPins( reg2, psetb2, unc2, &mask2 ); - -/* The criteria for a point to be on the boundary of the CmpRegion depend - on the boolean operator being used. If component regions A and B are - ANDed together, then a point is on the boundary of the CmpRegion if - either 1) it is on the boundary of A and inside B, or 2) it is on the - boundary of B and inside A. If the component regions are ORed together, - then a point is on the boundary of the CmpRegion if either 1) it is on - the boundary of A and outside B, or 2) it is on the boundary of B and - outside A. Either we need to transform the supplied PointSet using each - component Region as a Mapping. But if using OR we temporarily negate - the Regions. */ - if( this->oper == AST__OR ) { - astNegate( reg1 ); - astNegate( reg2 ); - } - pset1 = astTransform( reg1, pset, 1, NULL ); - pset2 = astTransform( reg2, pset, 1, NULL ); - if( this->oper == AST__OR ) { - astNegate( reg1 ); - astNegate( reg2 ); - } - -/* Get pointers to the axis values in these PointSets */ - ptr1 = astGetPoints( pset1 ); - ptr2 = astGetPoints( pset2 ); - -/* If required, create an output mask array */ - np = astGetNpoint( pset ); - if( mask ) *mask = astMalloc( sizeof(int)*(size_t) np ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* We can use the values for the first axis to indicate if a point is - inside or outside a Region. So store pointers to the first axis arrays. */ - p1 = ptr1[ 0 ]; - p2 = ptr2[ 0 ]; - -/* Assume all points are on the boundary of the CmpRegion. */ - result = 1; - -/* If we are creating an output mask, we must check every point. Otherwise - we can stop checking when we find the first point which is not on the - boundary of the CmpRegion. */ - if( mask ) { - - for( ip = 0; ip < np; ip++ ) { - if( ( mask1[ ip ] && p2[ ip ] != AST__BAD ) || - ( mask2[ ip ] && p1[ ip ] != AST__BAD ) ){ - (*mask)[ ip ] = 1; - } else { - (*mask)[ ip ] = 0; - result = 0; - } - } - - } else { - - for( ip = 0; ip < np; ip++ ) { - if( ( !mask1[ ip ] || p2[ ip ] == AST__BAD ) && - ( !mask2[ ip ] || p1[ ip ] == AST__BAD ) ){ - result = 0; - break; - } - } - } - } - -/* Free resources */ - mask1 = astFree( mask1 ); - mask2 = astFree( mask2 ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - psetb1 = astAnnul( psetb1 ); - psetb2 = astAnnul( psetb2 ); - if( unc1 ) unc1 = astAnnul( unc1 ); - if( unc2 ) unc2 = astAnnul( unc2 ); - -/* If an error has occurred, return zero. */ - if( !astOK ) { - result = 0; - if( mask ) *mask = astAnnul( *mask ); - } - -/* Return the result. */ - return result; -} - -static void RegSetAttrib( AstRegion *this_region, const char *setting, - char **base_setting, int *status ) { -/* -* Name: -* RegSetAttrib - -* Purpose: -* Set an attribute value for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void RegSetAttrib( AstRegion *this, const char *setting, -* char **base_setting, int *status ) - -* Class Membership: -* CmpRegion method (over-rides the astRegSetAttrib method inherited from -* the Region class). - -* Description: -* This function assigns an attribute value to both the base and -* current Frame in the FrameSet encapsulated within a Region, without -* remapping either Frame. -* -* No error is reported if the attribute is not recognised by the base -* Frame. - -* Parameters: -* this -* Pointer to the Region. -* setting -* Pointer to a null terminated attribute setting string. NOTE, IT -* SHOULD BE ENTIRELY LOWER CASE. The supplied string will be -* interpreted using the public interpretation implemented by -* astSetAttrib. This can be different to the interpretation of the -* protected accessor functions. For instance, the public -* interpretation of an unqualified floating point value for the -* Epoch attribute is to interpet the value as a gregorian year, -* but the protected interpretation is to interpret the value as an -* MJD. -* base_setting -* Address of a location at which to return a pointer to the null -* terminated attribute setting string which was applied to the -* base Frame of the encapsulated FrameSet. This may differ from -* the supplied setting if the supplied setting contains an axis -* index and the current->base Mapping in the FrameSet produces an -* axis permutation. The returned pointer should be freed using -* astFree when no longer needed. A NULL pointer may be supplied in -* which case no pointer is returned. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpRegion *this; - char *bset; - int rep; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* Use the RegSetAttrib method inherited from the parent class to apply the - setting to the current and base Frames in the FrameSet encapsulated by the - parent Region structure. */ - (*parent_regsetattrib)( this_region, setting, &bset, status ); - -/* Now apply the base Frame setting to the component Regions (the current - Frame within the component Regions is equivalent to the base Frame in the - parent Region structure). Annul any "attribute unknown" error that results - from attempting to do this. */ - if( astOK ) { - rep = astReporting( 0 ); - astRegSetAttrib( this->region1, bset, NULL ); - astRegSetAttrib( this->region2, bset, NULL ); - if( astStatus == AST__BADAT ) astClearStatus; - astReporting( rep ); - } - -/* If required, return the base Frame setting string, otherwise free it. */ - if( base_setting ) { - *base_setting = bset; - } else { - bset = astFree( bset ); - } -} - -static AstRegion **RegSplit( AstRegion *this_region, int *nlist, int *status ){ -/* -*+ -* Name: -* RegSplit - -* Purpose: -* Split a Region into a list of disjoint component Regions. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstRegion **astRegSplit( AstRegion *this, int *nlist ) - -* Class Membership: -* CmpRegion member function (overrides the astRegSplit method -* inherited from the parent Region class). - -* Description: -* This function splits the supplied Region into a set of disjoint -* component Regions. If the Region cannot be split, then the returned -* array contains only one pointer - a clone of the supplied Region -* pointer. - -* Parameters: -* this -* Pointer to the Region. -* nlist -* Pointer to an int in which to return the number of elements in -* the returned array. - -* Returned Value: -* Pointer to dynamically alloctaed memory holding an array of Region -* pointers. The length of this array is given by the value returned -* in "*nlist". The pointers in the returned array should be annulled -* using astAnnul when no longer needed, and the memory used to hold -* the array should be freed using astFree. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*- -*/ - -/* Local Variables; */ - AstCmpRegion *new; - AstCmpRegion *this; - AstFrame *frm; - AstFrameSet *fs; - AstMapping *map; - AstRegion **cmplist; - AstRegion **result; - AstRegion *cmpreg; - AstRegion *new_reg; - int icomp; - int ifirst; - int ilist; - int iw; - int jcomp; - int ncomp; - int nn; - int unbounded; - -/* Initialise. */ - result = NULL; - *nlist = 0; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* Indicate we have not yet found any unbounded component regions. */ - unbounded = 0; - -/* Can only split non-inverted CmpRegions that combine their components - using the OR operator. */ - if( this->oper == AST__OR && !astGetNegated( this->region1 ) && - !astGetNegated( this->region2 ) ) { - -/* Process each of the two component Regions in turn. */ - for( icomp = 0; icomp < 2 && !unbounded; icomp++ ) { - cmpreg = icomp ? this->region2 : this->region1; - -/* Create a set of disjoint Regions that are equivalent to the current - component Region, and loop round them. */ - cmplist = astRegSplit( cmpreg, &ncomp ); - for( jcomp = 0; jcomp < ncomp; jcomp++ ) { - -/* If any of the components are unbounds, we cannot split the supplied - Region. */ - unbounded = unbounded || !astGetBounded( cmplist[ jcomp ] ); - if( ! unbounded ) { - -/* Initialise the index within the returned list of the first Region that - overlaps the current disjoint component Region. */ - ifirst = -1; - -/* Loop round all the Regions currently in the returned list. */ - for( ilist = 0; ilist < *nlist; ilist++ ) { - if( result[ ilist ] ) { - -/* See if the current disjoint component overlaps the current entry in - the returned list. */ - if( astOverlap( cmplist[ jcomp ], result[ ilist ] ) > 1 ) { - -/* If this is the first overlap found for the current disjoint component, - form a CmpRegion that combines the two overlapping Regions, and use it - to replace the current entry in the returned list. */ - if( ifirst == -1 ) { - new = astCmpRegion( cmplist[ jcomp ], result[ ilist ], - AST__OR, " ", status ); - (void) astAnnul( result[ ilist ] ); - result[ ilist ] = (AstRegion *) new; - -/* Note the index within the returned list of the first Region that overlaps - the current disjoint component Region. */ - ifirst = ilist; - -/* If this is the second or later overlap, add the overlapping returned Region - into the CmpRegion that it is stored at index "ifirsT" in the returned - list. */ - } else { - new = astCmpRegion( result[ ilist ], result[ ifirst ], - AST__OR, " ", status ); - result[ ilist ] = astAnnul( result[ ilist ] ); - (void) astAnnul( result[ ifirst ] ); - result[ ifirst ] = (AstRegion *) new; - } - } - } - } - -/* If the current disjoint component does not overlap any of the Regions - already in the returned list, append the current disjoint component to - the end of the returned list. */ - if( ifirst == -1 ) { - ilist = (*nlist)++; - result = astGrow( result, *nlist, sizeof( *result ) ); - if( astOK ) result[ ilist ] = astClone( cmplist[ jcomp ] ); - } - } - -/* Annul the pointer to the disjoint component Region. */ - cmplist[ jcomp ] = astAnnul( cmplist[ jcomp ] ); - } - -/* Free the mnemory holding the list of disjoint components. */ - cmplist = astFree( cmplist ); - } - } - -/* If any unbounded components were found, ensure the returned list is - empty. */ - if( unbounded && result ) { - for( ilist = 0; ilist < *nlist; ilist++ ) { - if( result[ ilist ] ) result[ ilist ] = astAnnul( result[ ilist ] ); - } - result = astFree( result ); - *nlist = 0; - -/* Otherwise, shuffle later entries down to fill any NULL slots in the returned - list. */ - } else if( result ){ - nn = *nlist; - iw = 0; - for( ilist = 0; ilist < nn; ilist++ ) { - if( result[ ilist ] ) result[ iw++ ] = result[ ilist ]; - } - *nlist = iw; - } - -/* If this CmpRegion cannot be split, the returned list just holds a - clone of the Region pointer. */ - if( !result ) { - result = astMalloc( sizeof( *result ) ); - if( astOK ) { - result[ 0 ] = astClone( this ); - *nlist = 1; - } - } - -/* Remap any returned Regions so that they are defined within the same - coordinate system as the supplied Region. */ - if( result && *nlist > 0 ) { - fs = this_region->frameset; - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - frm = astGetFrame( fs, AST__CURRENT ); - for( ilist = 0; ilist < *nlist; ilist++ ) { - new_reg = astMapRegion( result[ ilist ], map, frm ); - (void) astAnnul( result[ ilist ] ); - result[ ilist ] = new_reg; - } - map = astAnnul( map ); - frm = astAnnul( frm ); - } - -/* Free all returned pointers if an error has occurred. */ - if( !astOK && result ) { - for( ilist = 0; ilist < *nlist; ilist++ ) { - result[ ilist ] = astAnnul( result[ ilist ] ); - } - result = astFree( result ); - *nlist = 0; - } - -/* Return the result. */ - return result; -} - -static int RegTrace( AstRegion *this_region, int n, double *dist, double **ptr, - int *status ){ -/* -*+ -* Name: -* RegTrace - -* Purpose: -* Return requested positions on the boundary of a 2D Region. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* int astRegTrace( AstRegion *this, int n, double *dist, double **ptr ); - -* Class Membership: -* CmpRegion member function (overrides the astRegTrace method -* inherited from the parent Region class). - -* Description: -* This function returns positions on the boundary of the supplied -* Region, if possible. The required positions are indicated by a -* supplied list of scalar parameter values in the range zero to one. -* Zero corresponds to some arbitrary starting point on the boundary, -* and one corresponds to the end (which for a closed region will be -* the same place as the start). - -* Parameters: -* this -* Pointer to the Region. -* n -* The number of positions to return. If this is zero, the function -* returns without action (but the returned function value still -* indicates if the method is supported or not). -* dist -* Pointer to an array of "n" scalar parameter values in the range -* 0 to 1.0. -* ptr -* A pointer to an array of pointers. The number of elements in -* this array should equal tthe number of axes in the Frame spanned -* by the Region. Each element of the array should be a pointer to -* an array of "n" doubles, in which to return the "n" values for -* the corresponding axis. The contents of the arrays are unchanged -* if the supplied Region belongs to a class that does not -* implement this method. - -* Returned Value: -* Non-zero if the astRegTrace method is implemented by the class -* of Region supplied, and zero if not. - -* Notes: -* - The current algorithm results in the boundary of the CmpRegion -* being dis-contiguous - supplied distance values from zero up to some -* mid-value correspond to positions on the first component Region, and -* higher distance (up to 1.0) correspond to points on the second -* component Region. - -*- -*/ - -/* Local Variables; */ - AstCmpRegion *this; - AstFrame *frm; - AstMapping *map; - AstPointSet *bpset; - AstPointSet *cpset; - AstRegion *ureg1; - AstRegion *ureg2; - double **bptr; - int i; - int j; - int ncur; - int result; - double *rval; - double *off; - double *r1d; - double *r2d; - double *r1ptr[ 2 ]; - double *r2ptr[ 2 ]; - double **r1ptrb; - double **r2ptrb; - double dbreak; - double dtot; - double x; - double x0; - int r1n; - int r2n; - AstPointSet *r1pset; - AstPointSet *r2pset; - AstPointSet *r1psetb; - AstPointSet *r2psetb; - -/* Initialise */ - result = 0; - -/* Check inherited status. */ - if( ! astOK ) return result; - -/* Get a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* Get a pointer to the base Frame in the encapsulated FrameSet. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Check it is 2-dimensional. */ - result = 1; - if( astGetNaxes( frm ) != 2 ) result = 0; - -/* Check the component Regions can be traced. */ - if( !astRegTrace( this->region1, 0, NULL, NULL ) || - !astRegTrace( this->region1, 0, NULL, NULL ) ) result = 0; - -/* Check we have some points to find. */ - if( result && n > 0 ) { - -/* We first determine the required positions in the base Frame of the - Region, and then transform them into the current Frame. Get the - base->current Mapping, and the number of current Frame axes. */ - map = astGetMapping( this_region->frameset, AST__BASE, AST__CURRENT ); - -/* If it's a UnitMap we do not need to do the transformation, so put the - base Frame positions directly into the supplied arrays. */ - if( astIsAUnitMap( map ) ) { - bpset = NULL; - bptr = ptr; - ncur = 2; - -/* Otherwise, create a PointSet to hold the base Frame positions. */ - } else { - bpset = astPointSet( n, 2, " ", status ); - bptr = astGetPoints( bpset ); - ncur = astGetNout( map ); - } - - r1d = astMalloc( sizeof( double )*n ); - r2d = astMalloc( sizeof( double )*n ); - -/* Ensure information about the breaks in the boundary of each component - region is available within the CmpRegion structure. These breaks are - the points at which the two boundaries cross. */ - SetBreakInfo( this, 0, status ); - SetBreakInfo( this, 1, status ); - -/* Get the constants needed to convert the supplied distances (normalised - so that the border of the entire CmpRegion has a length of 1.0), into - geodesic distances around the border of each component Region. */ - dtot = this->d0[ 0 ] + this->d0[ 1 ]; - dbreak = this->d0[ 0 ]/dtot; - -/* Initialise here to avoid compiler warnings. */ - r1n = 0; - r2n = 0; - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Loop round all supplied distances, determining if they represent a - position on the first or second component Region. */ - for( i = 0; i < n; i++ ) { - -/* If the current distance represents a point in the second component - Region... */ - if( dist[ i ] > dbreak ) { - -/* Find the correspond distance around the used sections of the second - component region (normalised so that the entire border of the - component region has a length of "this->d0[1]"). */ - x0 = ( dist[ i ] - dbreak )*dtot; - x = x0; - -/* Convert this into the correspond distance around the entire border of - the second component region (normalised so that the entire border of the - component region has unit length). */ - rval = this->rvals[ 1 ]; - off = this->offs[ 1 ]; - - for( j = 0; j < this->nbreak[ 1 ]; j++,rval++,off++ ) { - if( *rval >= x0 ) break; - x += *off; - } - -/* Store this as the next distance to move around the second component - Region, normalising it to the range 0 to 1 as required by astRegTrace. */ - r2d[ r2n++ ] = x/this->dtot[ 1 ]; - -/* Now we do the same if the current distance corresponds to a position - in the first component Region. */ - } else { - - x0 = dist[ i ]*dtot; - x = x0; - - rval = this->rvals[ 0 ]; - off = this->offs[ 0 ]; - - for( j = 0; j < this->nbreak[ 0 ]; j++,rval++,off++ ) { - if( *rval >= x0 ) break; - x += *off; - } - - r1d[ r1n++ ] = x/this->dtot[ 0 ]; - - } - - } - } - -/* Allocate memory to hold the axis values at the corresponding positions - in the first component Region. */ - r1ptr[ 0 ] = astMalloc( sizeof( double )*r1n ); - r1ptr[ 1 ] = astMalloc( sizeof( double )*r1n ); - -/* Allocate memory to hold the axis values at the corresponding positions - in the second component Region. */ - r2ptr[ 0 ] = astMalloc( sizeof( double )*r2n ); - r2ptr[ 1 ] = astMalloc( sizeof( double )*r2n ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Find the axis values at each of the required positions that fall in - the first component Region. Negate it first if needed to ensure the - Region is bounded (not guaranteed, but likely). */ - if( astGetBounded( this->region1 ) ) { - (void) astRegTrace( this->region1, r1n, r1d, r1ptr ); - } else { - AstRegion *negation = astGetNegation( this->region1 ); - (void) astRegTrace( negation, r1n, r1d, r1ptr ); - negation = astAnnul( negation ); - } - -/* Do the same for the second component Region. */ - if( astGetBounded( this->region2 ) ) { - (void) astRegTrace( this->region2, r2n, r2d, r2ptr ); - } else { - AstRegion *negation = astGetNegation( this->region2 ); - (void) astRegTrace( negation, r2n, r2d, r2ptr ); - negation = astAnnul( negation ); - } - -/* The arrays of positions returned by the above calls to astRegTrace may - include points that should not be there (e.g. points on the boundary - of one component region that should have been blanked due to being inside - the second component region - if the regions are ORed together). This - is a consequence of the relatively low value of the "NP" local constant - in function SetBreakInfo. So we now refine the positions to exclude - any such unwanted positions. - - If the two component Regions are ANDed together, we want to remove the - positions from the boundary of the required component Region that fall - outside the other region. We can do this by simply using the other Region - as a Mapping. If the two component Regions are ORed together, we want to - remove the position that fall within (rather than outside) the other - Region. To do this we need to negate the other region first. */ - if( this->oper == AST__OR ) { - ureg1 = astGetNegation( this->region1 ); - ureg2 = astGetNegation( this->region2 ); - } else { - ureg1 = astClone( this->region1 ); - ureg2 = astClone( this->region2 ); - } - -/* Now transform the points on the boundary of the first Region in order - to set invalid those positions which are not on the boundary of the - supplied CmpRegion. */ - if( r1n > 0 ) { - r1pset = astPointSet( r1n, 2, " ", status ); - astSetPoints( r1pset, r1ptr ); - r1psetb = astTransform( ureg2, r1pset, 1, NULL ); - r1ptrb = astGetPoints( r1psetb ); - } else { - r1pset = NULL; - r1psetb = NULL; - r1ptrb = NULL; - } - -/* Now transform the points on the boundary of the second Region in order - to set invalid those positions which are not on the boundary of the - supplied CmpRegion. */ - if( r2n > 0 ) { - r2pset = astPointSet( r2n, 2, " ", status ); - astSetPoints( r2pset, r2ptr ); - r2psetb = astTransform( ureg1, r2pset, 1, NULL ); - r2ptrb = astGetPoints( r2psetb ); - } else { - r2pset = NULL; - r2psetb = NULL; - r2ptrb = NULL; - } - -/* Free the begation pointers. */ - ureg1 = astAnnul( ureg1 ); - ureg2 = astAnnul( ureg2 ); - -/* Check pointer can be used safely. */ - if( astOK ) { - -/* Copy the boundary positions from each component Region into a single - PointSet. These positions are in the base Frame of the CmpRegion. */ - r1n = 0; - r2n = 0; - for( i = 0; i < n; i++ ) { - if( dist[ i ] > dbreak ) { - bptr[ 0 ][ i ] = r2ptrb[ 0 ][ r2n ]; - bptr[ 1 ][ i ] = r2ptrb[ 1 ][ r2n++ ]; - } else { - bptr[ 0 ][ i ] = r1ptrb[ 0 ][ r1n ]; - bptr[ 1 ][ i ] = r1ptrb[ 1 ][ r1n++ ]; - } - } - - } - -/* Free resources. */ - if( r1pset ) r1pset = astAnnul( r1pset ); - if( r2pset ) r2pset = astAnnul( r2pset ); - if( r1psetb ) r1psetb = astAnnul( r1psetb ); - if( r2psetb ) r2psetb = astAnnul( r2psetb ); - - } - -/* If required, transform the base frame positions into the current - Frame of the CmpRegion, storing them in the supplied array. Then - free resources. */ - if( bpset ) { - cpset = astPointSet( n, ncur, " ", status ); - astSetPoints( cpset, ptr ); - - (void) astTransform( map, bpset, 1, cpset ); - - cpset = astAnnul( cpset ); - bpset = astAnnul( bpset ); - } - -/* Free remaining resources. */ - map = astAnnul( map ); - } - frm = astAnnul( frm ); - -/* Return the result. */ - return result; -} - -static void RegClearAttrib( AstRegion *this_region, const char *attrib, - char **base_attrib, int *status ) { -/* -* Name: -* RegClearAttrib - -* Purpose: -* Clear an attribute value for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void RegClearAttrib( AstRegion *this, const char *attrib, -* char **base_attrib, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astRegClearAttrib method -* inherited from the Region class). - -* Description: -* This function clears the value of a named attribute in both the base -* and current Frame in the FrameSet encapsulated within a Region, without -* remapping either Frame. -* -* No error is reported if the attribute is not recognised by the base -* Frame. - -* Parameters: -* this -* Pointer to the Region. -* attrib -* Pointer to a null terminated string holding the attribute name. -* NOTE, IT SHOULD BE ENTIRELY LOWER CASE. -* base_attrib -* Address of a location at which to return a pointer to the null -* terminated string holding the attribute name which was cleared in -* the base Frame of the encapsulated FrameSet. This may differ from -* the supplied attribute if the supplied attribute contains an axis -* index and the current->base Mapping in the FrameSet produces an -* axis permutation. The returned pointer should be freed using -* astFree when no longer needed. A NULL pointer may be supplied in -* which case no pointer is returned. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpRegion *this; - char *batt; - int rep; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* Use the RegClearAttrib method inherited from the parent class to clear the - attribute in the current and base Frames in the FrameSet encapsulated by - the parent Region structure. */ - (*parent_regclearattrib)( this_region, attrib, &batt, status ); - -/* Now clear the base Frame attribute to the component Regions (the current - Frame within the component Regions is equivalent to the base Frame in the - parent Region structure). Annul any "attribute unknown" error that results - from attempting to do this. */ - if( astOK ) { - rep = astReporting( 0 ); - astRegClearAttrib( this->region1, batt, NULL ); - astRegClearAttrib( this->region2, batt, NULL ); - if( astStatus == AST__BADAT ) astClearStatus; - astReporting( rep ); - } - -/* If required, return the base Frame attribute name, otherwise free it. */ - if( base_attrib ) { - *base_attrib = batt; - } else { - batt = astFree( batt ); - } -} - -static void ResetCache( AstRegion *this_region, int *status ){ -/* -* Name: -* ResetCache - -* Purpose: -* Clear cached information within the supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void ResetCache( AstRegion *this, int *status ) - -* Class Membership: -* Region member function (overrides the astResetCache method -* inherited from the parent Region class). - -* Description: -* This function clears cached information from the supplied Region -* structure. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables *: */ - AstCmpRegion *this; - int i; - -/* Check a Region was supplied. */ - if( this_region ) { - -/* Get a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_region; - -/* Clear information cached in the CmpRegion structure. */ - for( i = 0; i < 2; i++ ) { - this->rvals[ i ] = astFree( this->rvals[ i ] ); - this->offs[ i ] = astFree( this->offs[ i ] ); - this->nbreak[ i ] = 0; - this->d0[ i ] = AST__BAD; - this->dtot[ i ] = AST__BAD; - } - - this->bounded = -INT_MAX; - -/* Clear information cached in the component regions. */ - if( this->region1 ) astResetCache( this->region1 ); - if( this->region2 ) astResetCache( this->region2 ); - -/* Clear information cached in the parent Region structure. */ - (*parent_resetcache)( this_region, status ); - } -} - -static void SetBreakInfo( AstCmpRegion *this, int comp, int *status ){ -/* -* Name: -* SetBreakInfo - -* Purpose: -* Ensure that a CmpRegion has information about the breaks in the -* boundaries of one of the two component Regions. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void SetBreakInfo( AstCmpRegion *this, int comp, int *status ) - -* Class Membership: -* CmpRegion method. - -* Description: -* This function returns without action if the supplied CmpRegion -* already contains break information for the specified component Region. -* Otherwise, it creates the required information and stores it in the -* CmpRegion. -* -* Each component Region in the CmpRegion has a boundary. But in -* general only part of the boundary of a component Region will also -* be included in the CmpRegion boundary. Thus the component Region -* boundary can be broken up into sections; sections that form part -* of the CmpRegion boundary, and sections that do not. This function -* stores information about the breaks between these sections. -* -* The complete boundary of a component Region is parameterised by a -* geodesic distance that goes from 0.0 to the value found by this -* function and stored in this->dtot (the total geodesic distance -* around the border). This function find the ranges of this parameter -* that correspond to the sections of the boundary that are also on the -* CmpRegion boundary, and thus finds the total length that the component -* boundary contributes to the CmpRegion boundary. This length is stored -* in "this->d0" (a two element array, one for each component Region). -* -* It also find two arrays "this->rvals" and "this->offs" that allow a -* distance value in the range 0.0 to "this->d0" (i.e. a distance -* measured by skipping over the parts of the component boundary that -* are not on the CmpRegion boundary), to be converted into the -* corresponding distance value in the range 0.0 to "this->dtot" (i.e. a -* distance measured round the complete component boundary, including the -* parts not on the CmpRegion boundary). - -* Parameters: -* this -* Pointer to a CmpRegion. -* comp -* Zero or one, indicating which component Region is to be checked. -* status -* Pointer to the inherited status variable. - -*/ - -/* The number of points to be spread evenly over the entire boundary of the - component Region. */ -#define NP 101 - -/* Local Variables: */ - AstFrame *frm; - AstPointSet *pset1; - AstPointSet *pset2; - AstRegion *other; - AstRegion *reg; - AstRegion *uother; - double **ptr2; - double **ptr1; - double *d; - double *offs; - double *p0; - double *p1; - double *p; - double *q; - double *rvals; - double delta; - double dist; - double pnt1[ 2 ]; - double pnt2[ 2 ]; - double rbad; - double rval; - double totdist; - int i; - int j; - int nn; - int prevgood; - -/* Check inherited status */ - if( !astOK ) return; - -/* If the information describing breaks in the component boundary has not - yet been set up, do so now. */ - if( this->d0[ comp ] == AST__BAD ) { - -/* Get a pointer to the component Region for which break information is - required. */ - reg = comp ? this->region2 : this->region1; - -/* Check the component class implements the astRegTrace method. */ - if( astRegTrace( reg, 0, NULL, NULL ) ) { - -/* Create a pointSet to hold axis values at evenly spaced positions along - the entire boundary of the selected component region. */ - pset1 = astPointSet( NP, 2, " ", status ); - ptr1 = astGetPoints( pset1 ); - -/* Allocate memory to hold an array of corresponding scalar distances around - the boundary. */ - d = astMalloc( NP*sizeof( double ) ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Get the distance increment between points (at this point the distances - are normalised so that the entire boundary has unit length, as - required by astRegTrace). */ - delta = 1.0/( NP - 1 ); - -/* Set up the array of evenly spaced distances around the boundary of the - component region. */ - for( i = 0; i < NP; i++ ) d[ i ] = i*delta; - -/* Get the corresponding Frame positions. If the Region is unbounded - (e.g. a negated circle, etc), then negate it first in the hope that - this may produced a bounded Region. */ - if( astGetBounded( reg ) ) { - (void) astRegTrace( reg, NP, d, ptr1 ); - } else { - AstRegion *negation = astGetNegation( reg ); - (void) astRegTrace( negation, NP, d, ptr1 ); - negation = astAnnul( negation ); - } - -/* Get a pointer to the other component Region. */ - other = comp ? this->region1 : this->region2; - -/* If the two component Regions are ANDed together, we want to remove the - positions from the boundary of the required component Region that fall - outside the other region. We can do this by simply using the other Region - as a Mapping. If the two component Regions are ORed together, we want to - remove the position that fall within (rather than outside) the other - Region. To do this we need to negate the other region first. */ - if( this->oper == AST__OR ) { - uother = astGetNegation( other ); - } else { - uother = astClone( other ); - } - -/* Now transform the points on the boundary of the selected Region in - order to set invalid those positions which are not on the boundary of - the supplied CmpRegion. */ - pset2 = astTransform( uother, pset1, 1, NULL ); - -/* Annul the negation pointer */ - uother = astAnnul( uother ); - -/* Modify the distance array by setting invalid each element that is not - on the boundary of the CmpRegion. */ - ptr2 = astGetPoints( pset2 ); - if( astOK ) { - p = ptr2[ 0 ]; - q = ptr2[ 1 ]; - for( i = 0; i < NP; i++,p++,q++ ) { - if( *p == AST__BAD || *q == AST__BAD ) d[ i ] = AST__BAD; - } - -/* At each good/bad junction in this list, extend the good section by one - point. This ensures that the good sections of the curve do in fact - touch each other (they may in fact overlap a little but that does not - matter). */ - prevgood = ( d[ 0 ] != AST__BAD ); - for( i = 1; i < NP; i++,p++,q++ ) { - if( d[ i ] == AST__BAD ) { - if( prevgood ) d[ i ] = i*delta; - prevgood = 0; - - } else { - if( !prevgood ) d[ i - 1 ] = ( i - 1 )*delta; - prevgood = 1; - } - } - -/* Find the total geodesic distance around the border. This is only an - approximation but it is only used to give a relative weight to this - component within the CmpFrame, and so does not need to be very accurate. */ - frm = astGetFrame( reg->frameset, AST__CURRENT ); - p0 = ptr1[ 0 ]; - p1 = ptr1[ 1 ]; - totdist = 0; - pnt1[ 0 ] = *(p0++); - pnt1[ 1 ] = *(p1++); - for( i = 1; i < NP; i++ ) { - pnt2[ 0 ] = *(p0++); - pnt2[ 1 ] = *(p1++); - dist = astDistance( frm, pnt1, pnt2 ); - if( dist != AST__BAD ) totdist += dist; - pnt1[ 0 ] = pnt2[ 0 ]; - pnt1[ 1 ] = pnt2[ 1 ]; - } - -/* Change delta so that it represents a geodesic distance, rather than a - normalised distance in the range zero to one. Working in geodesic distance - (e.g. Radians on a SkyFrame) prevents Regions higher up in a complex nested - CmpRegion being given higher priority than a lower Region. */ - delta *= totdist; - -/* Now create two arrays - "rvals" holds the distance travelled around - the used parts of the border at which breaks occur, "offs" holds the jump - in distance around the complete border at each break. The distance - around the complete border is normalised to the range [0.0,1.0]. - Therefore the total distance around the used parts of the border will in - general be less than 1.0 */ - if( d[ 0 ] == AST__BAD ) { - nn = 1; - j = 0; - rvals = astMalloc( sizeof( double ) ); - offs = astMalloc( sizeof( double ) ); - if( astOK ) rvals[ 0 ] = -0.5*delta; - rbad = 0.5; - prevgood = 0; - rval = -0.5*delta; - - } else { - nn = 0; - rvals = NULL; - offs = NULL; - prevgood = 1; - rbad = 0.0; - rval = 0.0; - } - - for( i = 1; i < NP; i++,p++,q++ ) { - - if( d[ i ] == AST__BAD ) { - if( prevgood ) { - j = nn++; - rvals = astGrow( rvals, nn, sizeof( double ) ); - offs = astGrow( offs, nn, sizeof( double ) ); - if( astOK ) { - rvals[ j ] = rval + 0.5*delta; - rbad = 0.0; - } else { - break; - } - prevgood = 0; - } - - rbad += 1.0; - - } else { - if( !prevgood ) { - offs[ j ] = rbad*delta; - prevgood = 1; - } - rval += delta; - } - } - - if( !prevgood ) { - rval += 0.5*delta; - offs[ j ] = rbad*delta; - } - -/* Record the information in the CmpRegion structure. */ - this->rvals[ comp ] = rvals; - this->offs[ comp ] = offs; - this->nbreak[ comp ] = nn; - this->d0[ comp ] = rval; - this->dtot[ comp ] = totdist; - } - -/* Free resources. */ - pset2 = astAnnul( pset2 ); - } - - pset1 = astAnnul( pset1 ); - d = astFree( d ); - - } - } -} - -#undef NP - -static void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) { -/* -* Name: -* SetRegFS - -* Purpose: -* Stores a new FrameSet in a Region - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) - -* Class Membership: -* CmpRegion method (over-rides the astSetRegFS method inherited from -* the Region class). - -* Description: -* This function creates a new FrameSet and stores it in the supplied -* Region. The new FrameSet contains two copies of the supplied -* Frame, connected by a UnitMap. - -* Parameters: -* this -* Pointer to the Region. -* frm -* The Frame to use. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstRegion *creg; /* Pointer to component Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent method to store the FrameSet in the parent Region - structure. */ - (* parent_setregfs)( this_region, frm, status ); - -/* If either component Region has a dummy FrameSet use this method - recursively to give them the same FrameSet. */ - creg = ((AstCmpRegion *) this_region )->region1; - if( creg && !astGetRegionFS( creg ) ) astSetRegFS( creg, frm ); - - creg = ((AstCmpRegion *) this_region )->region2; - if( creg && !astGetRegionFS( creg ) ) astSetRegFS( creg, frm ); - -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* CmpRegion method (over-rides the astSimplify method inherited from -* the Region class). - -* Description: -* This function simplifies a CmpRegion to eliminate redundant -* computational steps, or to merge separate steps which can be -* performed more efficiently in a single operation. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A new pointer to the (possibly simplified) Region. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. - -* Deficiencies: -* - Currently, this function does not attempt to map the component -* Regions into the current Frame of the parent Region structure. -* Both components should be mapped into the current Frame, and if the -* resulting base->current Mappings in *both* remapped component Regions are -* UnitMaps, then a new CmpRegion should be created from the re-mapped -* Regions. -*/ - -/* Local Variables: */ - AstCmpRegion *newb; /* New CmpRegion defined in base Frame */ - AstCmpRegion *newc; /* New CmpRegion defined in current Frame */ - AstFrame *frm; /* Current Frame */ - AstMapping *map; /* Base->current Mapping */ - AstMapping *result; /* Result pointer to return */ - AstRegion *csreg1; /* Copy of simplified first component Region */ - AstRegion *csreg2; /* Copy of simplified second component Region */ - AstRegion *nullreg; /* Null or infinfite Region */ - AstRegion *othereg; /* Non-Null and non-infinfite Region */ - AstRegion *reg1; /* First component Region */ - AstRegion *reg2; /* Second component Region */ - AstRegion *sreg1; /* Simplified first component Region */ - AstRegion *sreg2; /* Simplified second component Region */ - int neg1; /* Negated flag to use with first component */ - int neg2; /* Negated flag to use with second component */ - int oper; /* Boolean operator used to combine components */ - int overlap; /* Nature of overlap between components */ - int simpler; /* Has any simplification taken place? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the parent Simplify method inherited from the Region class. This - will simplify the encapsulated FrameSet and uncertainty Region. The - returned pointer identifies a region within the current Frame of the - FrameSet encapsulated by the parent Region structure. Note this by - storing the pointer in the "newc" ("c" for "current") variable. */ - newc = (AstCmpRegion *) (*parent_simplify)( this_mapping, status ); - -/* Note if any simplification took place. This is assumed to be the case - if the pointer returned by the above call is different to the supplied - pointer. */ - simpler = ( (AstMapping *) newc != this_mapping ); - -/* Below we may create a new simplified region which identifies a region - within the base Frame of the FrameSet encapsulated by the parent Region - structure. Such a result will need to be mapped into the current Frame - before being returned. The "newb" variable ("b" for "base") will be - used to store a pointer to such a result. Initialise this variable to - indicate that we do not yet have a base Frame result. */ - newb = NULL; - -/* Get the component Regions, how they should be combined, and the - Negated values which should be used with them. The returned values - take account of whether the supplied CmpRegion has itself been Negated - or not. The returned Regions represent regions within the base Frame - of the FrameSet encapsulated by the parent Region structure. */ - GetRegions( newc, ®1, ®2, &oper, &neg1, &neg2, status ); - -/* If the first component Region does not have the required value for - its "Negated" attribute, use the negation of "reg1" in place of "reg1" - itself. */ - if( neg1 != astGetNegated( reg1 ) ) { - AstRegion *tmp = astGetNegation( reg1 ); - (void) astAnnul( reg1 ); - reg1 = tmp; - } - -/* If the second component Region does not have the required value for - its "Negated" attribute, use the negation of "reg2" in place of "reg2" - itself. */ - if( neg2 != astGetNegated( reg2 ) ) { - AstRegion *tmp = astGetNegation( reg2 ); - (void) astAnnul( reg2 ); - reg2 = tmp; - } - -/* Simplify each of the two components. */ - sreg1 = astSimplify( reg1 ); - sreg2 = astSimplify( reg2 ); - -/* Note if any simplification took place. */ - simpler = simpler || ( sreg1 != reg1 || sreg2 != reg2 ); - -/* If either component is null or infinite we can exclude it from the - returned Region. */ - if( astIsANullRegion( sreg1 ) || astIsANullRegion( sreg2 ) ) { - -/* Get a pointer to the non-null Region. The following is still valid - even if both regions are null or infinite. */ - if( astIsANullRegion( sreg1 ) ){ - nullreg = sreg1; - othereg = sreg2; - } else { - nullreg = sreg2; - othereg = sreg1; - } - -/* If null.. */ - if( !astGetNegated( nullreg ) ){ - if( oper == AST__AND ) { - newb = (AstCmpRegion *) astNullRegion( othereg, - astGetUnc( othereg, 0 ), "", status ); - - } else if( oper == AST__OR ) { - newb = astCopy( othereg ); - - } else { - astError( AST__INTER, "astSimplify(%s): The %s refers to an " - "unknown boolean operator with identifier %d (internal " - "AST programming error).", status, astGetClass( newc ), - astGetClass( newc ), oper ); - } - -/* If infinite.. */ - } else { - if( oper == AST__AND ) { - newb = astCopy( othereg ); - - } else if( oper == AST__OR ) { - newb = (AstCmpRegion *) astNullRegion( othereg, - astGetUnc( othereg, 0 ), "negated=1", status ); - - } else { - astError( AST__INTER, "astSimplify(%s): The %s refers to an " - "unknown boolean operator with identifier %d (internal " - "AST programming error).", status, astGetClass( newc ), - astGetClass( newc ), oper ); - } - } - -/* Flag that we have done some simplication.*/ - simpler = 1; - -/* If neither component is null or infinite, see if it is possible to - remove one or both of the components on the basis of the overlap - between them. */ - } else { - overlap = astOverlap( sreg1, sreg2 ); - -/* If the components have no overlap, and they are combined using AND, then - the CmpRegion is null. */ - if( ( overlap == 1 || overlap == 6 ) && oper == AST__AND ) { - newb = (AstCmpRegion *) astNullRegion( sreg1, astGetUnc( sreg1, 0 ), - "", status ); - simpler = 1; - -/* If one component is the negation of the other component, and they are - combined using OR, then the CmpRegion is infinite. This is represented - by a negated null region.*/ - } else if( overlap == 6 && oper == AST__OR ) { - newb = (AstCmpRegion *) astNullRegion( sreg1, astGetUnc( sreg1, 0 ), - "negated=1", status ); - simpler = 1; - -/* If the two components are identical... */ - } else if( overlap == 5 ) { - simpler = 1; - -/* If combined with AND or OR, the CmpRegion can be replaced by the first - (or second) component Region. */ - if( oper == AST__AND || oper == AST__OR ) { - newb = astCopy( sreg1 ); - } else { - astError( AST__INTER, "astSimplify(%s): The %s refers to an " - "unknown boolean operator with identifier %d (internal " - "AST programming error).", status, astGetClass( newc ), - astGetClass( newc ), oper ); - } - -/* If the first component is entirely contained within the second - component, and they are combined using AND or OR, then the CmpRegion - can be replaced by the first or second component. */ - } else if( overlap == 2 && ( oper == AST__AND || oper == AST__OR ) ){ - newb = astCopy( ( oper == AST__AND ) ? sreg1 : sreg2 ); - simpler = 1; - -/* If the second component is entirely contained within the first - component, and they are combined using AND or OR, then the CmpRegion - can be replaced by the second or first component. */ - } else if( overlap == 3 && ( oper == AST__AND || oper == AST__OR ) ){ - newb = astCopy( ( oper == AST__AND ) ? sreg2 : sreg1 ); - simpler = 1; - -/* Otherwise, no further simplication is possible, so either create a new - CmpRegion or leave the "newb" pointer NULL (which will cause "newc" to - be used), depending on whether the components were simplified. */ - } else if( simpler ){ - csreg1 = astCopy( sreg1 ); - csreg2 = astCopy( sreg2 ); - newb = astCmpRegion( csreg1, csreg2, oper, "", status ); - csreg1 = astAnnul( csreg1 ); - csreg2 = astAnnul( csreg2 ); - - } - } - -/* If any simplification took place, decide whether to use the "newc" or - "newb" pointer for the returned Mapping. If "newb" is non-NULL we use - it, otherwise we use "newc". If "newb" is used we must first map the - result Region from the base Frame of the FrameSet encapsulated - by the parent Region structure, to the current Frame. */ - if( simpler ) { - if( newb ){ - frm = astGetFrame( ((AstRegion *) newc)->frameset, AST__CURRENT ); - map = astGetMapping( ((AstRegion *) newc)->frameset, AST__BASE, AST__CURRENT ); - result = astMapRegion( newb, map, frm ); - frm = astAnnul( frm ); - map = astAnnul( map ); - newb = astAnnul( newb ); - } else { - result = astClone( newc ); - } - -/* If no simplification took place, return a clone of the supplied pointer. */ - } else { - result = astClone( this_mapping ); - } - -/* Free resources. */ - reg1 = astAnnul( reg1 ); - reg2 = astAnnul( reg2 ); - sreg1 = astAnnul( sreg1 ); - sreg2 = astAnnul( sreg2 ); - newc = astAnnul( newc ); - -/* If an error occurred, annul the returned Mapping. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a CmpRegion to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* CmpRegion member function (over-rides the astTransform method inherited -* from the Region class). - -* Description: -* This function takes a CmpRegion and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required Region. -* This implies applying each of the CmpRegion's component Regions in turn, -* either in series or in parallel. - -* Parameters: -* this -* Pointer to the CmpRegion. -* in -* Pointer to the PointSet associated with the input coordinate values. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the CmpRegion being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to the CmpRegion structure */ - AstPointSet *ps1; /* Pointer to PointSet for first component */ - AstPointSet *ps2; /* Pointer to PointSet for second component */ - AstPointSet *pset_tmp; /* Pointer to PointSet holding base Frame positions*/ - AstPointSet *result; /* Pointer to output PointSet */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - double **ptr1; /* Pointer to first component axis values */ - double **ptr2; /* Pointer to second component axis values */ - double **ptr_out; /* Pointer to output coordinate data */ - int coord; /* Zero-based index for coordinates */ - int good; /* Is the point inside the CmpRegion? */ - int ncoord_out; /* No. of coordinates per output point */ - int ncoord_tmp; /* No. of coordinates per base Frame point */ - int neg1; /* Negated value for first component Region */ - int neg2; /* Negated value for second component Region */ - int npoint; /* No. of points */ - int oper; /* Boolean operator to use */ - int point; /* Loop counter for points */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a Pointer to the CmpRegion structure */ - this = (AstCmpRegion *) this_mapping; - -/* Get the component Regions, how they should be combined, and the - Negated values which should be used with them. The returned values - take account of whether the supplied CmpRegion has itself been Negated - or not. The returned Regions represent regions within the base Frame - of the FrameSet encapsulated by the parent Region structure. */ - GetRegions( this, ®1, ®2, &oper, &neg1, &neg2, status ); - -/* If the first component Region does not have the required value for - its "Negated" attribute, use the negation of "reg1" in place of "reg1" - itself. */ - if( neg1 != astGetNegated( reg1 ) ) { - AstRegion *tmp = astGetNegation( reg1 ); - (void) astAnnul( reg1 ); - reg1 = tmp; - } - -/* If the second component Region does not have the required value for - its "Negated" attribute, use the negation of "reg2" in place of "reg2" - itself. */ - if( neg2 != astGetNegated( reg2 ) ) { - AstRegion *tmp = astGetNegation( reg2 ); - (void) astAnnul( reg2 ); - reg2 = tmp; - } - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, containing - a copy of the input PointSet. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* First use the encapsulated FrameSet in the parent Region structure to - transform the supplied positions from the current Frame in the - encapsulated FrameSet (the Frame represented by the CmpRegion), to the - base Frame (the Frame in which the component Regions are defined). Note, - the returned pointer may be a clone of the "in" pointer, and so we - must be carefull not to modify the contents of the returned PointSet. */ - pset_tmp = astRegTransform( this, in, 0, NULL, NULL ); - -/* Now transform this PointSet using each of the two component Regions in - turn. */ - ps1 = astTransform( reg1, pset_tmp, 0, NULL ); - ps2 = astTransform( reg2, pset_tmp, 0, NULL ); - -/* Determine the numbers of points and coordinates per point for these base - Frame PointSets and obtain pointers for accessing the base Frame and output - coordinate values. */ - npoint = astGetNpoint( pset_tmp ); - ncoord_tmp = astGetNcoord( pset_tmp ); - ptr1 = astGetPoints( ps1 ); - ptr2 = astGetPoints( ps2 ); - ncoord_out = astGetNcoord( result ); - ptr_out = astGetPoints( result ); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - -/* First deal with ANDed Regions */ - if( oper == AST__AND ) { - for ( point = 0; point < npoint; point++ ) { - good = 0; - - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - if( ptr1[ coord ][ point ] != AST__BAD && - ptr2[ coord ][ point ] != AST__BAD ) { - good = 1; - break; - } - } - - if( !good ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - -/* Now deal with ORed Regions */ - } else if( oper == AST__OR ) { - for ( point = 0; point < npoint; point++ ) { - good = 0; - - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - if( ptr1[ coord ][ point ] != AST__BAD || - ptr2[ coord ][ point ] != AST__BAD ) { - good = 1; - break; - } - } - - if( !good ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - -/* Report error for any unknown operator. */ - } else if( astOK ) { - astError( AST__INTER, "astTransform(%s): The %s refers to an unknown " - "boolean operator with identifier %d (internal AST " - "programming error).", status, astGetClass( this ), - astGetClass( this ), oper ); - } - } - -/* Free resources. */ - reg1 = astAnnul( reg1 ); - reg2 = astAnnul( reg2 ); - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - pset_tmp = astAnnul( pset_tmp ); - -/* If an error occurred, clean up by deleting the output PointSet (if - allocated by this function) and setting a NULL result pointer. */ - if ( !astOK ) { - if ( !out ) result = astDelete( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -static void XORCheck( AstCmpRegion *this, int *status ) { -/* -* Name: -* XORCheck - -* Purpose: -* Check if the supplied CmpRegion represents an XOR operation. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void XORCheck( AstCmpRegion *this, int *status ) - -* Class Membership: -* CmpRegion method - -* Decription: -* This function analyses the component Regions within the supplied -* CmpRegion to see if the CmpRegion is equivalent to an XOR operation -* on two other Regions. If it is, teh Regions that are XORed are -* stored in the supplied CmpRegion. - -* Parameters: -* this -* Pointer to the CmpRegion. - -*/ - -/* Local Variables: */ - AstCmpRegion *cmpreg1; - AstCmpRegion *cmpreg2; - int xor; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If the CmpRegion is already known to be an XOR operation, return - without action. */ - if( this->xor1 ) return; - -/* To be equivalent to an XOR operation, the supplied CmpRegion must be an - OR operation and each component Region must be a CmpRegion. */ - if( this->oper == AST__OR && astIsACmpRegion( this->region1 ) - && astIsACmpRegion( this->region2 ) ) { - cmpreg1 = (AstCmpRegion *) this->region1; - cmpreg2 = (AstCmpRegion *) this->region2; - -/* Each component CmpRegion must be an AND operation. */ - if( cmpreg1->oper == AST__AND && cmpreg2->oper == AST__AND ) { - -/* Temporarily negate the first component of the first CmpRegion. */ - astNegate( cmpreg1->region1 ); - -/* Initially, assume the supplied CmpRegion is not equivalent to an XOR - operation. */ - xor = 0; - -/* This negated region must be equal to one of the two component Regions - in the second component CmpRegion. Check the first. */ - if( astEqual( cmpreg1->region1, cmpreg2->region1 ) ) { - -/* We now check that the other two Regions are equal (after negating the - first). If so, set "xor" non-zero. */ - astNegate( cmpreg1->region2 ); - if( astEqual( cmpreg1->region2, cmpreg2->region2 ) ) xor = 1; - astNegate( cmpreg1->region2 ); - -/* Do equiovalent checks the other way round. */ - } else if( astEqual( cmpreg1->region1, cmpreg2->region2 ) ) { - astNegate( cmpreg1->region2 ); - if( astEqual( cmpreg1->region2, cmpreg2->region1 ) ) xor = 1; - astNegate( cmpreg1->region2 ); - } - -/* Re-instate the original state of the Negated attribute in the first - component of the first CmpRegion. */ - astNegate( cmpreg1->region1 ); - -/* If the supplied CmpRegion is equivalent to an XOR operation, store - copies of the components in the supplied CmpRegion. */ - if( xor ) { - this->xor1 = astCopy( cmpreg1->region1 ); - this->xor2 = astCopy( cmpreg1->region2 ); - -/* We need to negate one of these two Region (it doesn't matter which), - and we choose to negate which ever of them is already negated (so that - it becomes un-negated). */ - if( astGetNegated( this->xor1 ) ) { - astNegate( this->xor1 ); - } else { - astNegate( this->xor2 ); - } - } - } - } -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for CmpRegion objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for CmpRegion objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Regions within the CmpRegion. -*/ - -/* Local Variables: */ - AstCmpRegion *in; /* Pointer to input CmpRegion */ - AstCmpRegion *out; /* Pointer to output CmpRegion */ - int i; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output CmpRegions. */ - in = (AstCmpRegion *) objin; - out = (AstCmpRegion *) objout; - -/* For safety, start by clearing any memory references in the output - Region that were copied from the input Region. */ - out->region1 = NULL; - out->region2 = NULL; - out->xor1 = NULL; - out->xor2 = NULL; - - for( i = 0; i < 2; i++ ) { - out->rvals[ i ] = NULL; - out->offs[ i ] = NULL; - } - -/* Make copies of these Regions and store pointers to them in the output - CmpRegion structure. */ - out->region1 = astCopy( in->region1 ); - out->region2 = astCopy( in->region2 ); - if( in->xor1 ) out->xor1 = astCopy( in->xor1 ); - if( in->xor2 ) out->xor2 = astCopy( in->xor2 ); - -/* Copy cached arrays. */ - for( i = 0; i < 2; i++ ) { - out->rvals[ i ] = astStore( NULL, in->rvals[ i ], in->nbreak[ i ]*sizeof( **in->rvals ) ); - out->offs[ i ] = astStore( NULL, in->offs[ i ], in->nbreak[ i ]*sizeof( **in->offs ) ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for CmpRegion objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for CmpRegion objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstCmpRegion *this; /* Pointer to CmpRegion */ - int i; - -/* Obtain a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) obj; - -/* Free arrays holding cached information. */ - for( i = 0; i < 2; i++ ) { - this->rvals[ i ] = astFree( this->rvals[ i ] ); - this->offs[ i ] = astFree( this->offs[ i ] ); - } - -/* Annul the pointers to the component Regions. */ - this->region1 = astAnnul( this->region1 ); - this->region2 = astAnnul( this->region2 ); - if( this->xor1 ) this->xor1 = astAnnul( this->xor1 ); - if( this->xor2 ) this->xor2 = astAnnul( this->xor2 ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for CmpRegion objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the CmpRegion class to an output Channel. - -* Parameters: -* this -* Pointer to the CmpRegion whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstRegion *reg1; /* First Region to include in dump */ - AstRegion *reg2; /* Second Region to include in dump */ - AstCmpRegion *this; /* Pointer to the CmpRegion structure */ - const char *comment; /* Pointer to comment string */ - int ival; /* Integer value */ - int oper; /* The operator to include in the dump */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpRegion structure. */ - this = (AstCmpRegion *) this_object; - -/* Check if this CmpRegion has an equivalent XOR representation. Is so, - store details of the XOR representation in the CmpRegion. */ - XORCheck( this, status ); - -/* Choose the operator and component regions to include in the dump. If - the CmpRegion originally used an XOR operator, then save the XORed - regions. Otherwise, store the real component Regions. */ - if( this->xor1 ) { - oper = AST__XOR; - reg1 = this->xor1; - reg2 = this->xor2; - } else { - oper = this->oper; - reg1 = this->region1; - reg2 = this->region2; - } - -/* Write out values representing the instance variables for the CmpRegion - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Oper */ -/* ------- */ - ival = oper; - if( ival == AST__AND ) { - comment = "Regions combined using Boolean AND"; - } else if( ival == AST__OR ) { - comment = "Regions combined using Boolean OR"; - } else if( ival == AST__XOR ) { - comment = "Regions combined using Boolean XOR"; - } else { - comment = "Regions combined using unknown operator"; - } - astWriteInt( channel, "Operator", 1, 0, ival, comment ); - -/* First Region. */ -/* -------------- */ - astWriteObject( channel, "RegionA", 1, 1, reg1, - "First component Region" ); - -/* Second Region. */ -/* --------------- */ - astWriteObject( channel, "RegionB", 1, 1, reg2, - "Second component Region" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsACmpRegion and astCheckCmpRegion functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(CmpRegion,Region) -astMAKE_CHECK(CmpRegion) - -AstCmpRegion *astCmpRegion_( void *region1_void, void *region2_void, int oper, - const char *options, int *status, ...) { -/* -*+ -* Name: -* astCmpRegion - -* Purpose: -* Create a CmpRegion. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpregion.h" -* AstCmpRegion *astCmpRegion( AstRegion *region1, AstRegion *region2, -* int oper, const char *options, ..., int *status ) - -* Class Membership: -* CmpRegion constructor. - -* Description: -* This function creates a new CmpRegion and optionally initialises its -* attributes. - -* Parameters: -* region1 -* Pointer to the first Region. -* region2 -* Pointer to the second Region. -* oper -* The boolean operator with which to combine the two Regions. Either -* AST__AND or AST__OR. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new CmpRegion. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new CmpRegion. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic CmpRegion constructor which is -* available via the protected interface to the CmpRegion class. A -* public interface is provided by the astCmpRegionId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "region1" and "region2" parameters are of type (void *) and are -* converted and validated within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstCmpRegion *new; /* Pointer to new CmpRegion */ - AstRegion *region1; /* Pointer to first Region structure */ - AstRegion *region2; /* Pointer to second Region structure */ - va_list args; /* Variable argument list */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain and validate pointers to the Region structures provided. */ - region1 = astCheckRegion( region1_void ); - region2 = astCheckRegion( region2_void ); - if ( astOK ) { - -/* Initialise the CmpRegion, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitCmpRegion( NULL, sizeof( AstCmpRegion ), !class_init, - &class_vtab, "CmpRegion", region1, region2, - oper ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new CmpRegion's - attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new CmpRegion. */ - return new; -} - -AstCmpRegion *astCmpRegionId_( void *region1_void, void *region2_void, - int oper, const char *options, ... ) { -/* -*++ -* Name: -c astCmpRegion -f AST_CMPREGION - -* Purpose: -* Create a CmpRegion. - -* Type: -* Public function. - -* Synopsis: -c #include "cmpregion.h" -c AstCmpRegion *astCmpRegion( AstRegion *region1, AstRegion *region2, -c int oper, const char *options, ... ) -f RESULT = AST_CMPREGION( REGION1, REGION2, OPER, OPTIONS, STATUS ) - -* Class Membership: -* CmpRegion constructor. - -* Description: -* This function creates a new CmpRegion and optionally initialises -* its attributes. -* -* A CmpRegion is a Region which allows two component -* Regions (of any class) to be combined to form a more complex -* Region. This combination may be performed a boolean AND, OR -* or XOR (exclusive OR) operator. If the AND operator is -* used, then a position is inside the CmpRegion only if it is -* inside both of its two component Regions. If the OR operator is -* used, then a position is inside the CmpRegion if it is inside -* either (or both) of its two component Regions. If the XOR operator -* is used, then a position is inside the CmpRegion if it is inside -* one but not both of its two component Regions. Other operators can -* be formed by negating one or both component Regions before using -* them to construct a new CmpRegion. -* -* The two component Region need not refer to the same coordinate -* Frame, but it must be possible for the -c astConvert -f AST_CONVERT -* function to determine a Mapping between them (an error will be -* reported otherwise when the CmpRegion is created). For instance, -* a CmpRegion may combine a Region defined within an ICRS SkyFrame -* with a Region defined within a Galactic SkyFrame. This is -* acceptable because the SkyFrame class knows how to convert between -* these two systems, and consequently the -c astConvert -f AST_CONVERT -* function will also be able to convert between them. In such cases, -* the second component Region will be mapped into the coordinate Frame -* of the first component Region, and the Frame represented by the -* CmpRegion as a whole will be the Frame of the first component Region. -* -* Since a CmpRegion is itself a Region, it can be used as a -* component in forming further CmpRegions. Regions of arbitrary -* complexity may be built from simple individual Regions in this -* way. - -* Parameters: -c region1 -f REGION1 = INTEGER (Given) -* Pointer to the first component Region. -c region2 -f REGION2 = INTEGER (Given) -* Pointer to the second component Region. This Region will be -* transformed into the coordinate Frame of the first region before -* use. An error will be reported if this is not possible. -c oper -f OPER = INTEGER (Given) -* The boolean operator with which to combine the two Regions. This -* must be one of the symbolic constants AST__AND, AST__OR or AST__XOR. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new CmpRegion. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new CmpRegion. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astCmpRegion() -f AST_CMPREGION = INTEGER -* A pointer to the new CmpRegion. - -* Notes: -* - If one of the supplied Regions has an associated uncertainty, -* that uncertainty will also be used for the returned CmpRegion. -* If both supplied Regions have associated uncertainties, the -* uncertainty associated with the first Region will be used for the -* returned CmpRegion. -* - Deep copies are taken of the supplied Regions. This means that -* any subsequent changes made to the component Regions using the -* supplied pointers will have no effect on the CmpRegion. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astCmpRegion constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astCmpRegion_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "region1" and "region2" parameters -* are of type (void *) and are converted from an ID value to a -* pointer and validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astCmpRegion_ directly, so it must be a re-implementation -* of it in all respects, except for the conversions between IDs -* and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstCmpRegion *new; /* Pointer to new CmpRegion */ - AstRegion *region1; /* Pointer to first Region structure */ - AstRegion *region2; /* Pointer to second Region structure */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain the Region pointers from the ID's supplied and validate the - pointers to ensure they identify valid Regions. */ - region1 = astVerifyRegion( astMakePointer( region1_void ) ); - region2 = astVerifyRegion( astMakePointer( region2_void ) ); - if ( astOK ) { - -/* Initialise the CmpRegion, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitCmpRegion( NULL, sizeof( AstCmpRegion ), !class_init, - &class_vtab, "CmpRegion", region1, region2, - oper ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new CmpRegion's - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new CmpRegion. */ - return astMakeId( new ); -} - -AstCmpRegion *astInitCmpRegion_( void *mem, size_t size, int init, - AstCmpRegionVtab *vtab, const char *name, - AstRegion *region1, AstRegion *region2, - int oper, int *status ) { -/* -*+ -* Name: -* astInitCmpRegion - -* Purpose: -* Initialise a CmpRegion. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpregion.h" -* AstCmpRegion *astInitCmpRegion_( void *mem, size_t size, int init, -* AstCmpRegionVtab *vtab, const char *name, -* AstRegion *region1, AstRegion *region2, -* int oper ) - -* Class Membership: -* CmpRegion initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new CmpRegion object. It allocates memory (if necessary) to -* accommodate the CmpRegion plus any additional data associated with the -* derived class. It then initialises a CmpRegion structure at the start -* of this memory. If the "init" flag is set, it also initialises the -* contents of a virtual function table for a CmpRegion at the start of -* the memory passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the CmpRegion is to be initialised. -* This must be of sufficient size to accommodate the CmpRegion data -* (sizeof(CmpRegion)) plus any data used by the derived class. If a -* value of NULL is given, this function will allocate the memory itself -* using the "size" parameter to determine its size. -* size -* The amount of memory used by the CmpRegion (plus derived class -* data). This will be used to allocate memory if a value of NULL is -* given for the "mem" parameter. This value is also stored in the -* CmpRegion structure, so a valid value must be supplied even if not -* required for allocating memory. -* init -* A logical flag indicating if the CmpRegion's virtual function table -* is to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new CmpRegion. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* region1 -* Pointer to the first Region. -* region2 -* Pointer to the second Region. -* oper -* The boolean operator to use. Must be one of AST__AND, AST__OR or -* AST__XOR. - -* Returned Value: -* A pointer to the new CmpRegion. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstCmpRegion *new; /* Pointer to new CmpRegion */ - AstFrame *frm; /* Frame encapsulated by first Region */ - AstFrameSet *fs; /* FrameSet connecting supplied Regions */ - AstMapping *map; /* Mapping between two supplied Regions */ - AstMapping *smap; /* Simplified Mapping between two supplied Regions */ - AstRegion *new_reg1; /* Replacement for first region */ - AstRegion *new_reg2; /* Replacement for second region */ - AstRegion *reg1; /* First Region to store in the CmpRegion */ - AstRegion *reg2; /* Second Region to store in the CmpRegion */ - AstRegion *xor1; /* Copy of first supplied Region or NULL */ - AstRegion *xor2; /* Copy of second supplied Region or NULL */ - int i; /* Loop count */ - int used_oper; /* The boolean operation actually used */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitCmpRegionVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check the supplied oper value. */ - if( oper != AST__AND && oper != AST__OR && oper != AST__XOR && astOK ) { - astError( AST__INTRD, "astInitCmpRegion(%s): Illegal " - "boolean operator value (%d) supplied.", status, name, oper ); - } - -/* Take copies of the supplied Regions. */ - reg1 = astCopy( region1 ); - reg2 = astCopy( region2 ); - -/* Get the Mapping from the second to the first Region. */ - fs = astConvert( reg2, reg1, "" ); - -/* Report an error if not possible. */ - if( fs == NULL ) { - frm = NULL; - if( astOK ) astError( AST__INTRD, "astInitCmpRegion(%s): No Mapping can " - "be found between the two supplied Regions.", status, name ); - -/* Otherwise, map the second Region into the Frame of the first (unless - they are already in the same Frame). This results in both component - Frames having the same current Frame. This current Frame is used as the - encapsulated Frame within the parent Region structure. */ - } else { - frm = astGetFrame( fs, AST__CURRENT ); - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - smap = astSimplify( map ); - if( !astIsAUnitMap( smap ) ) { - new_reg2 = astMapRegion( reg2, smap, frm ); - (void) astAnnul( reg2 ); - reg2 = new_reg2; - } - smap = astAnnul( smap ); - map = astAnnul( map ); - fs = astAnnul( fs ); - } - -/* The CmpRegion class does not implement XOR directly (as it does for - AND and OR). Instead, when requested to create an XOR CmpRegion, it - creates a CmpRegion that uses AND and OR to simulate XOR. The top - level XOR CmpRegion actually uses AST__OR and the two component - regions within it are CmpRegions formed by combing the two supplied - Regions (one being negated first) using AND. Create the required - component Regions. */ - if( oper == AST__XOR ) { - astNegate( reg1 ); - new_reg1 = (AstRegion *) astCmpRegion( reg1, reg2, AST__AND, " ", - status ); - astNegate( reg1 ); - - astNegate( reg2 ); - new_reg2 = (AstRegion *) astCmpRegion( reg1, reg2, AST__AND, " ", - status ); - astNegate( reg2 ); - - xor1 = reg1; - xor2 = reg2; - - reg1 = new_reg1; - reg2 = new_reg2; - - used_oper = AST__OR; - -/* For AND and OR, use the supplied operator. */ - } else { - xor1 = NULL; - xor2 = NULL; - used_oper = oper; - } - -/* Initialise a Region structure (the parent class) as the first component - within the CmpRegion structure, allocating memory if necessary. A NULL - PointSet is suppled as the two component Regions will perform the function - of defining the Region shape. The base Frame of the FrameSet in the - parent Region structure will be the same as the current Frames of the - FrameSets in the two component Regions. */ - if ( astOK ) { - new = (AstCmpRegion *) astInitRegion( mem, size, 0, - (AstRegionVtab *) vtab, name, - frm, NULL, NULL ); - -/* Initialise the CmpRegion data. */ -/* --------------------------- */ -/* Store pointers to the component Regions. */ - new->region1 = astClone( reg1 ); - new->region2 = astClone( reg2 ); - -/* Note the operator used to combine the somponent Regions. */ - new->oper = used_oper; - -/* If we are creating an XOR CmpRegion, save copies of the supplied - Regions (i.e. the supplied Regions which are XORed). These will not - be the same as "reg1" and "reg2" since each of those two regions will - be CmpRegions that combine the supplied Regions using AST__AND. */ - if( oper == AST__XOR ) { - new->xor1 = xor1; - new->xor2 = xor2; - } else { - new->xor1 = NULL; - new->xor2 = NULL; - } - -/* Initialised cached values to show they have not yet been found. */ - for( i = 0; i < 2; i++ ) { - new->rvals[ i ] = NULL; - new->offs[ i ] = NULL; - new->nbreak[ i ] = 0; - new->d0[ i ] = AST__BAD; - new->dtot[ i ] = AST__BAD; - } - new->bounded = -INT_MAX; - -/* If the base->current Mapping in the FrameSet within each component Region - is a UnitMap, then the FrameSet does not need to be included in the - Dump of the new CmpRegion. Set the RegionFS attribute of the component - Region to zero to flag this. */ - map = astGetMapping( reg1->frameset, AST__BASE, AST__CURRENT ); - if( astIsAUnitMap( map ) ) astSetRegionFS( reg1, 0 ); - map = astAnnul( map ); - - map = astGetMapping( reg2->frameset, AST__BASE, AST__CURRENT ); - if( astIsAUnitMap( map ) ) astSetRegionFS( reg2, 0 ); - map = astAnnul( map ); - -/* Copy attribute values from the first component Region to the parent - Region. */ - if( astTestMeshSize( new->region1 ) ) { - astSetMeshSize( new, astGetMeshSize( new->region1 ) ); - } - if( astTestClosed( new->region1 ) ) { - astSetClosed( new, astGetClosed( new->region1 ) ); - } - -/* If an error occurred, clean up by annulling the Region pointers and - deleting the new object. */ - if ( !astOK ) { - new->region1 = astAnnul( new->region1 ); - new->region2 = astAnnul( new->region2 ); - new = astDelete( new ); - } - } - -/* Free resources */ - reg1 = astAnnul( reg1 ); - reg2 = astAnnul( reg2 ); - if( frm ) frm = astAnnul( frm ); - -/* Return a pointer to the new object. */ - return new; -} - -AstCmpRegion *astLoadCmpRegion_( void *mem, size_t size, - AstCmpRegionVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadCmpRegion - -* Purpose: -* Load a CmpRegion. - -* Type: -* Protected function. - -* Synopsis: -* #include "cmpregion.h" -* AstCmpRegion *astLoadCmpRegion( void *mem, size_t size, -* AstCmpRegionVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* CmpRegion loader. - -* Description: -* This function is provided to load a new CmpRegion using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* CmpRegion structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a CmpRegion at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the CmpRegion is to be -* loaded. This must be of sufficient size to accommodate the -* CmpRegion data (sizeof(CmpRegion)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the CmpRegion (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the CmpRegion structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstCmpRegion) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new CmpRegion. If this is NULL, a pointer to -* the (static) virtual function table for the CmpRegion class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "CmpRegion" is used instead. - -* Returned Value: -* A pointer to the new CmpRegion. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstCmpRegion *new; /* Pointer to the new CmpRegion */ - AstRegion *reg1; /* First Region read from dump */ - AstRegion *reg2; /* Second Region read from dump */ - AstFrame *f1; /* Base Frame in parent Region */ - AstRegion *creg; /* Pointer to component Region */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int i; /* Loop count */ - int oper; /* The operator to include in the dump */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this CmpRegion. In this case the - CmpRegion belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstCmpRegion ); - vtab = &class_vtab; - name = "CmpRegion"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitCmpRegionVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built CmpRegion. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "CmpRegion" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Operator */ -/* -------- */ - oper = astReadInt( channel, "operator", AST__AND ); - -/* First Region. */ -/* -------------- */ - reg1 = astReadObject( channel, "regiona", NULL ); - -/* Second Region. */ -/* --------------- */ - reg2 = astReadObject( channel, "regionb", NULL ); - -/* Initialised cached values to show they have not yet been found. */ - for( i = 0; i < 2; i++ ) { - new->rvals[ i ] = NULL; - new->offs[ i ] = NULL; - new->nbreak[ i ] = 0; - new->d0[ i ] = AST__BAD; - new->dtot[ i ] = AST__BAD; - } - new->bounded = -INT_MAX; - -/* The CmpRegion class does not implement XOR directly (as it does for - AND and OR). Instead, when requested to create an XOR CmpRegion, it - creates a CmpRegion that uses AND and OR to simulate XOR. The top - level XOR CmpRegion actually uses AST__OR and the two component - regions within it are CmpRegions formed by combing the two supplied - Regions (one being negated first) using AND. Create the required - component Regions. */ - if( oper == AST__XOR ) { - astNegate( reg1 ); - new->region1 = (AstRegion *) astCmpRegion( reg1, reg2, AST__AND, - " ", status ); - astNegate( reg1 ); - - astNegate( reg2 ); - new->region2 = (AstRegion *) astCmpRegion( reg1, reg2, AST__AND, - " ", status ); - astNegate( reg2 ); - - new->xor1 = reg1; - new->xor2 = reg2; - - new->oper = AST__OR; - -/* For AND and OR, use the supplied Regions and operator. */ - } else { - new->region1 = reg1; - new->region2 = reg2; - new->xor1 = NULL; - new->xor2 = NULL; - new->oper = oper; - } - -/* If either component Region has a dummy FrameSet rather than the correct - FrameSet, the correct FrameSet will have copies of the base Frame of the - new CmpRegion as both its current and base Frames, connected by a UnitMap - (this is equivalent to a FrameSet containing a single Frame). However if - the new CmpRegion being loaded has itself got a dummy FrameSet, then we do - not do this since we do not yet know what the correct FrameSet is. In this - case we wait until the parent Region invokes the astSetRegFS method on the - new CmpRegion. */ - if( !astRegDummyFS( new ) ) { - f1 = astGetFrame( ((AstRegion *) new)->frameset, AST__BASE ); - creg = new->region1; - if( astRegDummyFS( creg ) ) astSetRegFS( creg, f1 ); - creg = new->region2; - if( astRegDummyFS( creg ) ) astSetRegFS( creg, f1 ); - f1 = astAnnul( f1 ); - } - -/* If an error occurred, clean up by deleting the new CmpRegion. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new CmpRegion pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -int astCmpRegionList_( AstCmpRegion *this, int *nreg, AstRegion ***reg_list, - int *status ) { - if ( !astOK ) return AST__AND; - return (**astMEMBER(this,CmpRegion,CmpRegionList))( this, nreg, reg_list, - status ); -} - - - - - - diff --git a/ast/cmpregion.h b/ast/cmpregion.h deleted file mode 100644 index 92d7898..0000000 --- a/ast/cmpregion.h +++ /dev/null @@ -1,251 +0,0 @@ -#if !defined( CMPREGION_INCLUDED ) /* Include this file only once */ -#define CMPREGION_INCLUDED -/* -*+ -* Name: -* cmpregion.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the CmpRegion class. - -* Invocation: -* #include "cmpregion.h" - -* Description: -* This include file defines the interface to the CmpRegion class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The CmpRegion class implement a Region which represents a simple interval -* on each axis of the encapsulated Frame - -* Inheritance: -* The CmpRegion class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 11-OCT-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "region.h" /* Coordinate regions (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros. */ -/* ------- */ -/* Boolean operators */ - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif -#define AST__AND 1 -#define AST__OR 2 -#define AST__XOR 3 - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* CmpRegion structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstCmpRegion { - -/* Attributes inherited from the parent class. */ - AstRegion region; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstRegion *region1; /* First component Region */ - AstRegion *region2; /* Second component Region */ - int oper; /* Boolean operator */ - double *rvals[ 2 ]; /* Used boundary length at each break */ - double *offs[ 2 ]; /* Jump at each break */ - int nbreak[ 2 ]; /* Number of breaks */ - double d0[ 2 ]; /* Total used boundary length */ - double dtot[ 2 ]; /* Total boundary length */ - AstRegion *xor1; /* First XORed Region */ - AstRegion *xor2; /* Second XORed Region */ - int bounded; /* Is this CmpRegion bounded? */ -} AstCmpRegion; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstCmpRegionVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - int (* CmpRegionList)( AstCmpRegion *, int *, AstRegion ***, int * ); - -} AstCmpRegionVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstCmpRegionGlobals { - AstCmpRegionVtab Class_Vtab; - int Class_Init; -} AstCmpRegionGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitCmpRegionGlobals_( AstCmpRegionGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(CmpRegion) /* Check class membership */ -astPROTO_ISA(CmpRegion) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstCmpRegion *astCmpRegion_( void *, void *, int, const char *, int *, ...); -#else -AstCmpRegion *astCmpRegionId_( void *, void *, int, const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstCmpRegion *astInitCmpRegion_( void *, size_t, int, AstCmpRegionVtab *, - const char *, AstRegion *, AstRegion *, int, int * ); - -/* Vtab initialiser. */ -void astInitCmpRegionVtab_( AstCmpRegionVtab *, const char *, int * ); - -/* Loader. */ -AstCmpRegion *astLoadCmpRegion_( void *, size_t, AstCmpRegionVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -int astCmpRegionList_( AstCmpRegion *, int *, AstRegion ***, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckCmpRegion(this) astINVOKE_CHECK(CmpRegion,this,0) -#define astVerifyCmpRegion(this) astINVOKE_CHECK(CmpRegion,this,1) - -/* Test class membership. */ -#define astIsACmpRegion(this) astINVOKE_ISA(CmpRegion,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astCmpRegion astINVOKE(F,astCmpRegion_) -#else -#define astCmpRegion astINVOKE(F,astCmpRegionId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitCmpRegion(mem,size,init,vtab,name,reg1,reg2,oper) \ -astINVOKE(O,astInitCmpRegion_(mem,size,init,vtab,name,reg1,reg2,oper,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitCmpRegionVtab(vtab,name) astINVOKE(V,astInitCmpRegionVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadCmpRegion(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadCmpRegion_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckCmpRegion to validate CmpRegion pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astCmpRegionList(this,nreg,reg_list) \ -astINVOKE(V,astCmpRegionList_(this,nreg,reg_list,STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/complex.pdf b/ast/complex.pdf deleted file mode 100644 index 2d16739..0000000 Binary files a/ast/complex.pdf and /dev/null differ diff --git a/ast/component.xml b/ast/component.xml deleted file mode 100644 index e133a00..0000000 --- a/ast/component.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - 8.6.2 - libext/ast - WCS library - -

The AST library provides a comprehensive range of facilities for - attaching world coordinate systems to astronomical data, for - retrieving and interpreting that information in a variety of formats, - including FITS-WCS, and for generating graphical output based on it.

-

This library should be of interest to anyone writing - astronomical applications which need to manipulate coordinate system - data, especially celestial or spectral coordinate systems. AST - is portable and environment-independent.

-
- - ssthtxmessgen - - - - Rodney Warren-Smith - rfws - - - David Berry - dsb - dsb@ast.man.ac.uk - owner - - - Norman Gray - nxg - norman@astro.gla.ac.uk - - - sun210 sun211 - starlink@jiscmail.ac.uk - - - Council for the Central Laboratory of the Research Councils - -
diff --git a/ast/component.xml.in b/ast/component.xml.in deleted file mode 100644 index d59bb5a..0000000 --- a/ast/component.xml.in +++ /dev/null @@ -1,44 +0,0 @@ - - - - - @PACKAGE_VERSION@ - libext/ast - WCS library - -

The AST library provides a comprehensive range of facilities for - attaching world coordinate systems to astronomical data, for - retrieving and interpreting that information in a variety of formats, - including FITS-WCS, and for generating graphical output based on it.

-

This library should be of interest to anyone writing - astronomical applications which need to manipulate coordinate system - data, especially celestial or spectral coordinate systems. AST - is portable and environment-independent.

-
- - @STAR_DEPENDENCIES_CHILDREN@ - - - - Rodney Warren-Smith - rfws - - - David Berry - dsb - dsb@ast.man.ac.uk - owner - - - Norman Gray - nxg - norman@astro.gla.ac.uk - - - @STAR_DOCUMENTATION@ - @PACKAGE_BUGREPORT@ - - - Council for the Central Laboratory of the Research Councils - -
diff --git a/ast/configure.ac b/ast/configure.ac deleted file mode 100644 index a923657..0000000 --- a/ast/configure.ac +++ /dev/null @@ -1,243 +0,0 @@ -dnl Process this file with autoconf to produce a configure script -AC_REVISION($Revision$) - -dnl This configure file is known to work with autoconf-2.57, -dnl automake versions 1.6.3 and 1.7.5, and libtool versions 1.4.2 and -dnl 1.5. It should work with autoconf versions 2.50 or better, and -dnl automake 1.6 or better. - -dnl Initialisation: package name and version number -AC_INIT([ast],[8.6.2],[starlink@jiscmail.ac.uk]) -AC_CONFIG_AUX_DIR([build-aux]) - -dnl Require autoconf-2.50 at least -AC_PREREQ([2.69]) -dnl Require Starlink automake -AM_INIT_AUTOMAKE([1.8.2-starlink subdir-objects]) - -dnl Sanity-check: name a file in the source directory -AC_CONFIG_SRCDIR([ast_link.in]) - -# Include defaults for Starlink configurations -STAR_DEFAULTS - -# See if the --with-starmem option has been provided. This sets the -# preprocesor macro HAVE_STAR_MEM_H. -AC_ARG_WITH( - [starmem], - AS_HELP_STRING([--with-starmem],[use starmem library for memory management]), - AC_DEFINE([HAVE_STAR_MEM_H],[1],[Use the starmem library for memory management]), -) - -# See if the --with-memdebug option has been provided. This sets the -# preprocesor macro MEM_DEBUG which enables facilities used to track -# down memory leaks, etc. -AC_ARG_WITH( - [memdebug], - AS_HELP_STRING([--with-memdebug],[enable AST memory leak debugging functions]), - AC_DEFINE([MEM_DEBUG],[1],[enable AST memory leak debugging functions in memory.c]), -) - -# See if the --with-external_pal option has been provided. This sets the -# preprocesor macro EXTERNAL_PAL which prevents use of the PAL & ERFA -# library functions that are included in the AST distribution. Suitable -# link options are used within ast_link(_adam) scripts to pull in libpal. -AC_ARG_WITH([external_pal], - [ --with-external_pal Use external PAL and ERFA libraries], - if test "$withval" = "yes"; then - external_pal="1" - else - external_pal="0" - fi, - external_pal="0") -AC_SUBST( EXTERNAL_PAL, $external_pal ) -if test "$external_pal" = "1"; then - AC_SUBST( LIBPAL, "-lpal" ) - AC_DEFINE([EXTERNAL_PAL],[1],[use external PAL and ERFA libraries]), -else - AC_SUBST( LIBPAL, "" ) -fi -AM_CONDITIONAL(EXTERNAL_PAL, test x$external_pal = x1) - - -# Checks for programs -AC_PROG_CC -AC_PROG_CPP -LT_INIT -AC_PROG_LN_S - -# If --with-pic=no is set we should honour that. -AM_CONDITIONAL(NOPIC, test x$pic_mode = xno) - -# Conditional defining whether we build with POSIX thread support. -AC_ARG_WITH([pthreads], - [ --without-pthreads Build package without POSIX threads support], - if test "$withval" = "yes"; then - use_pthreads="1" - else - use_pthreads="0" - fi, - use_pthreads="1") -if test "$use_pthreads" = "1"; then -AC_CHECK_LIB([pthread], [pthread_create], ,[use_pthreads="0"]) -fi -AM_CONDITIONAL(NOTHREADS, test x$use_pthreads = x0) -AC_SUBST(THREADS, $use_pthreads) - -# See which variadic function API to use -AC_CHECK_HEADERS(stdarg.h varargs.h, break) - -# Can we use backtrace? -AC_CHECK_HEADERS([execinfo.h]) -AC_CHECK_FUNCS([backtrace]) - -# Do we have reentrant strerror and strtok? -AC_CHECK_FUNCS([strerror_r strtok_r]) - -# Do we have vsnprintf? -AC_CHECK_FUNCS([vsnprintf]) - -# See if we have long doubles (used by the Mapping and Region classes) -AC_CHECK_TYPES([long double]) - -# See if we have 64 bit integers. -AC_CHECK_TYPES([int64_t, uint64_t]) - -# Calculate alternative 64 bit integer sizes -AC_CHECK_SIZEOF(long) -AC_CHECK_SIZEOF(long long) - - -# Decide how to get the name of the curently executing function. -# ------------------------------------------------------------- -AC_DEFUN([CIT_FUNCTIONSTRING], [ - set_function_name=no - - - - AC_MSG_CHECKING([whether C compiler defines __func__]) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[]], [[const char* name = __func__;]])], - [AC_MSG_RESULT(yes) - set_function_name=yes - AC_DEFINE([FUNCTION_NAME], [__func__], [Variable holding current function name.])], - [AC_MSG_RESULT(no)]) - if test "$set_function_name" == no; then - AC_MSG_CHECKING([whether C compiler defines __FUNCTION__]) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[]], [[const char* name = __FUNCTION__;]])], - [AC_MSG_RESULT(yes) - set_function_name=yes - AC_DEFINE([FUNCTION_NAME], [__FUNCTION__], [Variable holding current function name.])], - [AC_MSG_RESULT(no)]) - fi -]) - -CIT_FUNCTIONSTRING - -# Conditional defining whether we want to support Fortran libraries -# (e.g. pgplot) and applications. -AC_ARG_WITH([fortran], - [ --without-fortran Build package without Fortran support], - if test "$withval" = "yes"; then - use_fortran="1" - else - use_fortran="0" - fi, - use_fortran="1") -AM_CONDITIONAL(NOFORTRAN, test x$use_fortran = x0) -AC_SUBST(FORTRAN, $use_fortran) - -# ast_link needs to be able to link against the Fortran runtime if -# necessary -if test "$use_fortran" = "1"; then -AC_PROG_FC -AC_FC_LIBRARY_LDFLAGS -fi - -# Find an absolute path to the Perl binary, augmenting the path with the -# location of the Starlink Perl build. If this fails, then set @PERL@ -# to the backup `/usr/bin/env perl', which will find Perl if it exists -# in the path at runtime. -AC_PATH_PROG(PERL, perl, [/usr/bin/env perl], [$STARLINK/Perl/bin:$PATH]) - -# Function and declaration checks -AC_CHECK_FUNCS([isnan]) -AC_CHECK_DECLS([isnan],,,[#include - ]) -AC_CHECK_FUNCS([isfinite]) -AC_CHECK_DECLS([isfinite],,,[#include - ]) -STAR_DECLARE_DEPENDENCIES(sourceset, [sst htx]) - -# Perform the check that configures f77.h.in for the return type of REAL -# Fortran functions. On 64-bit g77 with f2c compatibility this is double -# not float. -if test "$use_fortran" = "1"; then -STAR_CNF_F2C_COMPATIBLE - -# Determine the type of Fortran character string lengths. -STAR_CNF_TRAIL_TYPE -fi - -# Declare the message file. -STAR_MESSGEN(ast_err.msg) - -# Test for non-ANSI behaviour in sscanf on some platforms, reported by -# Bill Joye. Also check for bad MINGW sscanf. That returns nc=0 in the -# System test. -AC_MSG_CHECKING([whether the sscanf function is ANSI-compatible]) -AC_RUN_IFELSE([AC_LANG_SOURCE([[ - -#include -#include - -int main() { - char foo[] = " name 1111.1 "; - char mingw[] = "system= FK4_NO_E"; - - char bar[8]; - float ff; - int system; - int nc; - int r; - - nc = 0; - r = sscanf(foo, " %s %f %n", bar, &ff, &nc); - - if ( nc == 13 ) { - nc = 0; - r = sscanf( mingw, "system= %n%*s %n", &system, &nc ); - if ( nc != 0 ) nc = 13; - } - exit( ( nc != 13 ) ? 0 : 1 ); -} - -]])],[ - AC_MSG_RESULT([no]);AC_DEFINE([HAVE_NONANSI_SSCANF],[1],[The sscanf shows the non-ANSI behaviour reported by Bill Joye]) -],[AC_MSG_RESULT([yes])],[ - AC_DEFINE([HAVE_NONANSI_SSCANF],[1],[The sscanf may show the non-ANSI behaviour reported by Bill Joye]) -]) - -# Declare the documentation. We need to do complicated things to -# satisfy these targets, so give a non-null value -# for the second argument, to suppress automatic generation of -# rules. -STAR_LATEX_DOCUMENTATION([sun210 sun211], [sun210.pdf sun210.tex sun211.pdf sun211.tex sun210.htx_tar sun211.htx_tar]) -STAR_PREDIST_SOURCES(sun_master.tex) -STAR_CHECK_PROGS(star2html) -STAR_CHECK_PROGS(prolat, sst) # prolat is part of SST - -AC_CONFIG_HEADERS(config.h) - -AC_CONFIG_FILES(Makefile component.xml ast_link ast_link_adam object.h) -if test "$use_fortran" = "1"; then -AC_CONFIG_FILES(f77.h) -fi - -AC_CONFIG_FILES([ast_cpp], [chmod +x ast_cpp]) -# Following are files which are substituted by the Makefile at -# distribution time, rather than by configure. They are not distributed. -STAR_PREDIST_SOURCES(version.h.in builddocs.in addversion.in) - -AC_OUTPUT diff --git a/ast/devtools/make_simtest b/ast/devtools/make_simtest deleted file mode 100644 index 87412ed..0000000 --- a/ast/devtools/make_simtest +++ /dev/null @@ -1,4 +0,0 @@ -gcc -g -o simtest simtest.c -DTHREAD_SAFE -I$MYGIT/libraries/ast \ - -L$GITSTAR/lib `chr_link` `ast_link -ems` `err_link` - - diff --git a/ast/devtools/simtest.c b/ast/devtools/simtest.c deleted file mode 100644 index e36634c..0000000 --- a/ast/devtools/simtest.c +++ /dev/null @@ -1,864 +0,0 @@ -#define astCLASS simtest - -#include -#include -#include "globals.h" -#include "object.h" -#include "fitschan.h" -#include "mapping.h" -#include "cmpmap.h" -#include "error.h" -#include "winmap.h" -#include "tranmap.h" -#include "frameset.h" -#include "pointset.h" -#include "f77.h" -#include "memory.h" -#include "switchmap.h" -#include "unitmap.h" - -void DisplayList( AstMapping *, int, int, int * ); -void sink( const char * ); -const char *source( void ); -void tran( AstMapping *, int * ); -void diff( AstMapping *, int * ); -void tranm( AstMapping **, int *, int, int, int * ); - -extern F77_SUBROUTINE(kpg1_asreg)( INTEGER(status) ); - - -FILE *fd=NULL; - -main(){ - char file[ 50 ], text[ 100 ]; - const char *class, *enc0; - char *attrs, *kvalue; - AstWinMap *winmap; - AstFitsChan *fc, *fc2; - AstChannel *ch, *channel; - AstMapping *map, *map2, *tmap; - AstObject *obj, *obj2; - int opt, nin, nout, i; - DECLARE_INTEGER(lstatus); - int *status; - - lstatus = 0; - status = &lstatus; - -/* F77_CALL(kpg1_asreg)( INTEGER_ARG(&lstatus) ); */ - - printf( "Input FITS or AST file [| fitschan attrs] > "); - scanf( "%s", file ); - - attrs = strchr( file, '|' ); - if( attrs ) { - *attrs = 0; - attrs++; - } else { - attrs = "Carlin=0"; - } - - fd = fopen( file, "r" ); - if( fd ){ - ch = (AstChannel *) astFitsChan( NULL, sink, attrs, status ); - if( astOK ) { - fc = (AstFitsChan *) ch; - while( astOK && fgets( text, 100, fd ) ){ - astPutFits( fc, text, 0 ); - } - astClearCard( fc ); - - enc0 = astGetC( fc, "encoding" ); - printf("Using %s encoding\n", enc0 ); - obj = astRead( fc ); - } - if( !obj || !astOK ){ - printf("Attempting to read file %s as an AST file...\n", file ); - astClearStatus; - ch = astChannel( source, NULL, "", status ); - - fclose( fd ); - fd = NULL; - fd = fopen( file, "r" ); - obj = astRead( ch ); - if( obj != NULL ) { - fc = NULL; - } else { - astClearStatus; - printf("Reverting to FitsChan and using a dummy UnitMap. \n", file ); - obj = (AstObject *) astUnitMap( 1, "", status ); - astAnnul( ch ); - ch = (AstChannel *) fc; - } - - } - fclose( fd ); - fd = NULL; - } else { - astError( 1, "Cannot open file '%s'.", status, file ); - } - - class = obj ? astGetClass( obj ) : NULL; - if( obj && class ){ - printf( "%s %s has been read from file '%s'.\n", - strspn( class, "AEIOUaeiou" )?"An":"A", class, file ); - } - - if( obj && astIsAFitsChan( obj ) ) { - fc = (AstFitsChan *) obj; - astClearCard( fc ); - enc0 = astGetC( fc, "encoding" ); - printf("Using %s encoding\n", enc0 ); - obj = astRead( fc ); - } - - if( obj && astIsAMapping( obj ) ){ - map = (AstMapping *) obj; - - while( astOK ){ - printf("\n" - "0 - Quit\n" - "1 - Transform points\n" - "2 - Simplify\n" - "3 - Display\n" - "4 - Write\n" - "5 - Shift and scale\n" - "6 - Set mapping attributes\n" - "7 - Get mapping attributes\n" - "8 - Dump the FitsChan\n" - "9 - Differentiate\n" - "10 - Find a FITS keyword\n" - "\n" - "Option > " ); - opt = 0; - scanf( "%d", &opt ); - - if( opt == 0 ){ - break; - - } else if( opt == 1 ){ - tran( map, status ); - - } else if( opt == 2 ){ - map2 = astSimplify( map ); - map = astAnnul( map ); - map = map2; - obj = (AstObject *) map2; - - } else if( opt == 3 ){ - if( astIsAFrameSet( map ) ) { - tmap = astGetMapping( map, AST__BASE, AST__CURRENT ); - } else { - tmap = astClone( map ); - } - DisplayList( tmap, 1, astGetInvert( tmap ), status ); - tmap = astAnnul( tmap ); - - } else if( opt == 4 ){ - printf( "\n Output FITS file > "); - scanf( "%s", file ); - fd = fopen( file, "w" ); - if( fd ){ - if( fc ) { - printf(" Encoding (orig=%s)> ",enc0 ); - scanf( "%s", text ); - if( !strcmp( enc0, text ) && fc != NULL ){ - printf("Using existing FitsChan.\n"); - fc2 = astClone( fc ); - fc = astAnnul( fc ); - ch = NULL; - astClearCard( fc2 ); - astSet( fc2, "encoding=%s", status, text ); - } else { - printf("Creating new FitsChan.\n"); - fc2 = astFitsChan( NULL, sink, "encoding=%s", status, text ); - astPutFits( fc2, "NAXIS1 = 1", 1 ); - astPutFits( fc2, "NAXIS2 = 1", 1 ); - astPutFits( fc2, "NAXIS3 = 1", 1 ); - astPutFits( fc2, "NAXIS4 = 1", 1 ); - } - } else { - printf(" Encoding for new FitsChan > " ); - scanf( "%s", text ); - fc2 = astFitsChan( NULL, sink, "encoding=%s", status, text ); - astPutFits( fc2, "NAXIS1 = 1", 1 ); - astPutFits( fc2, "NAXIS2 = 1", 1 ); - astPutFits( fc2, "NAXIS3 = 1", 1 ); - astPutFits( fc2, "NAXIS4 = 1", 1 ); - } - if( !astWrite( fc2, obj ) ){ - printf("No object written to file '%s'.\n", file ); - } - fc2 = astAnnul( fc2 ); - fclose( fd ); - fd = NULL; - } else { - astError( 1, "Cannot open file '%s'.", status, file ); - } - - } else if( opt == 5 ){ - nin = astGetNin( map ); - winmap = astWinMap( nin, NULL, NULL, NULL, NULL, "", status ); - - printf( "\n Enter %d axis shift values > ", nin ); - for( i = 0; i < nin; i++ ) scanf( "%lg", (winmap->a) + i ); - - printf( "\n Enter %d axis scale values > ", nin ); - for( i = 0; i < nin; i++ ) scanf( "%lg", (winmap->b) + i ); - - if( !strcmp( class, "FrameSet" ) ){ - astInvert( winmap ); - astRemapFrame( obj, AST__BASE, winmap ); - } else { - map2 = (AstMapping *) astCmpMap( winmap, map, 1, "", status ); - map = astAnnul( map ); - map = map2; - obj = (AstObject *) map2; - } - winmap = astAnnul( winmap ); - - } else if( opt == 6 ) { - printf("Enter attribute specifications: "); - scanf( "%s", text ); - astSet( map, text, status ); - if( !astOK ) astClearStatus; - - } else if( opt == 7 ) { - printf("Enter attribute name: "); - scanf( "%s", text ); - printf( "%s = %s\n", text, astGetC( map, text ) ); - if( !astOK ) astClearStatus; - - } else if( opt == 8 ) { - printf( "\n Output text file > "); - scanf( "%s", file ); - fd = fopen( file, "w" ); - if( fd ){ - channel = astChannel( NULL, sink, "Full=1", status ); - astDump( ch, channel ); - channel = astAnnul( channel ); - fclose( fd ); - fd = NULL; - } else { - printf("Failed to open output file '%s'.\n", file ); - perror(" "); - } - - } else if( opt == 9 ){ - diff( map, status ); - - } else if( opt == 10 ){ - if( fc ) { - printf("Enter FITS keyword: "); - scanf( "%s", text ); - if( astGetFitsS( fc, text, &kvalue ) ) { - printf("%s = '%s'\n", text, kvalue ); - } else { - printf("%s not found\n", text ); - } - } else { - printf("No FITS keywords are available\n", text ); - } - } - } - - } else { - astError( 1, "Object should be a Mapping).", status ); - } - - if( ch ) ch = astAnnul( ch ); - obj = astAnnul( obj ); - -} - -void DisplayList( AstMapping *map0, int series, int invert, int *status ){ - int nmap, i, inv, res, junk; - AstMapping *mi, *mf, **map_list, *m, *m2, *map, *smap, *tm1, *tm2; - AstCmpMap *cm; - AstTranMap *tm; - AstChannel *channel; - int invi, invf, *invert_list, opt, old_inv, nin, in[20], *out, nout; - int isswitch, tfwd, tinv; - const char *class; - char file[ 50 ]; - double dv; - - nmap = 0; - map_list = NULL; - invert_list = NULL; - map = astClone( map0 ); - - isswitch = astIsASwitchMap( map ); - if( isswitch ) { - astSwitchList( (AstSwitchMap *) map, invert, &nmap, &map_list, - &invert_list, status ); - } else { - astMapList( map, series, invert, &nmap, &map_list, &invert_list ); - } - - while( 1 ){ - if( isswitch ) { - printf("\nSwitchMap: (fwd selector, inv selector, routes )\n" ); - printf(" -3 - \n"); - } else { - printf("\nMappings in %s:\n", series?"series":"parallel" ); - printf(" -8 - \n"); - printf(" -7 - \n"); - printf(" -6 - \n"); - printf(" -5 - \n"); - printf(" -4 - \n"); - printf(" -3 - \n"); - printf(" -2 - \n"); - printf(" -1 - \n"); - } - printf(" 0 - \n"); - for( i = 0; i < nmap; i++ ){ - m = map_list[ i ]; - class = m ? astGetClass( m ) :"(NULL)"; - printf( " %d - %s\n", i + 1, class ); - } - printf("\n Option > ", 0 ); - opt = 0; - scanf("%d", &opt ); - - if ( opt == -8 ) { - - for( i = 0; i < nmap; i++ ) map_list[ i ] = astAnnul( map_list[ i ] ); - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - nmap = 0; - - invert = ( invert == 0 ); - if( isswitch ) { - astSwitchList( (AstSwitchMap *) map, invert, &nmap, - &map_list, &invert_list, status ); - } else { - astMapList( map, series, invert, &nmap, &map_list, &invert_list ); - } - - } else if ( opt == -7 && !isswitch ) { - printf( "\n Output text file > "); - scanf( "%s", file ); - fd = fopen( file, "w" ); - if( fd ){ - channel = astChannel( NULL, sink, "", status ); - for( i = 0; i < nmap; i++ ) { - inv = astGetInvert( map_list[ i ] ); - astSetInvert( map_list[ i ], invert_list[ i ] ); - astDump( map_list[ i ], channel ); - astSetInvert( map_list[ i ], inv ); - } - channel = astAnnul( channel ); - fclose( fd ); - fd = NULL; - } else { - printf("Failed to open output file.\n" ); - } - - } else if( opt == -6 && !isswitch ) { - old_inv = astGetInvert( map ); - astSetInvert( map, invert ); - - printf( "\n Pick how many input axes (max=%d)? > ", - astGetNin( map ) ); - scanf( "%lg", &dv ); - nin = dv; - - printf( "\n Enter %d zero-based axis indices > ", nin ); - for( i = 0; i < nin; i++ ) { - scanf( "%lg", &dv ); - in[ i ] = dv; - } - - out = astMapSplit( map, nin, in, &smap ); - astSetInvert( map, old_inv ); - - if( out ) { - printf( "Corresponding outputs are: " ); - nout = astGetNout( smap ); - for( i = 0; i < nout; i++ ) printf( "%d ", out[ i ] ); - printf("\n"); - out = astFree( out ); - map = astAnnul( map ); - map = smap; - } else { - printf( "Selected inputs do not correspond to a subset of outputs\n"); - } - - for( i = 0; i < nmap; i++ ) map_list[ i ] = astAnnul( map_list[ i ] ); - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - - nmap = 0; - astMapList( map, series, invert, &nmap, &map_list, &invert_list ); - - } else if( opt == -5 && !isswitch ) { - old_inv = astGetInvert( map ); - astSetInvert( map, invert ); - smap = astSimplify( map ); - if( smap == map ) printf("\n No simplification performed\n" ); - astSetInvert( map, old_inv ); - map = astAnnul( map ); - map = smap; - - for( i = 0; i < nmap; i++ ) map_list[ i ] = astAnnul( map_list[ i ] ); - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - - nmap = 0; - astMapList( map, series, invert, &nmap, &map_list, &invert_list ); - - } else if( opt == -4 && !isswitch ) { - printf("\n Mapping index > ", 0 ); - scanf("%d", &i ); - i--; - res = astMapMerge( map_list[ i ], i, series, &nmap, - &map_list, &invert_list ); - if( res != -1 ) { - printf( "Index of first modified Mapping: %d\n", res + 1 ); - } else { - printf( "No mappings modified\n" ); - } - - } else if( opt == -3 && series && !isswitch ) { - - if( invert == astGetInvert( map ) ) { - tfwd = astGetTranForward( map ); - tinv = astGetTranInverse( map ); - } else { - tinv = astGetTranForward( map ); - tfwd = astGetTranInverse( map ); - } - - if( !tfwd ) { - printf( "\n No forward transformation available\n" ); - - } else if( !tinv ) { - printf( "\n No inverse transformation available\n" ); - tranm( map_list, invert_list, nmap, 0, status ); - - } else { - tranm( map_list, invert_list, nmap, 1, status ); - - } - - } else if( opt == -3 && isswitch ) { - - if( invert == astGetInvert( map ) ) { - tfwd = astGetTranForward( map ); - tinv = astGetTranInverse( map ); - } else { - tinv = astGetTranForward( map ); - tfwd = astGetTranInverse( map ); - } - - if( !tfwd ) { - printf( "\n No forward transformation available\n" ); - - } else if( !tinv ) { - printf( "\n No inverse transformation available\n" ); - tranm( &map, &invert, 1, 0, status ); - - } else { - tranm( &map, &invert, 1, 1, status ); - - } - - } else if( opt == -3 && !series && !isswitch ) { - old_inv = astGetInvert( map ); - astSetInvert( map, invert ); - tran( map, status ); - astSetInvert( map, old_inv ); - - } else if ( opt == -2 && !isswitch ) { - - for( i = 0; i < nmap; i++ ) { - inv = astGetInvert( map_list[ i ] ); - astSetInvert( map_list[ i ], invert_list[ i ] ); - if( i == 0 ) { - tm1 = astClone( map_list[ 0 ] ); - } else { - tm2 = (AstMapping *) astCmpMap( tm1, map_list[ i ], series, "", status ); - tm1 = astAnnul( tm1 ); - tm1 = tm2; - } - astSetInvert( map_list[ i ], inv ); - } - - printf( "\n Output text file > "); - scanf( "%s", file ); - fd = fopen( file, "w" ); - if( fd ){ - channel = astChannel( NULL, sink, "", status ); - old_inv = astGetInvert( tm1 ); - astSetInvert( tm1, invert ); - astDump( tm1, channel ); - astSetInvert( tm1, old_inv ); - channel = astAnnul( channel ); - fclose( fd ); - fd = NULL; - } else { - printf("Failed to open output file.\n" ); - } - tm1= astAnnul( tm1 ); - - } else if ( opt == -1 && !isswitch ) { - - - for( i = 0; i < nmap; i++ ) { - inv = astGetInvert( map_list[ i ] ); - astSetInvert( map_list[ i ], invert_list[ i ] ); - if( i == 0 ) { - tm1 = astClone( map_list[ 0 ] ); - } else { - tm2 = (AstMapping *) astCmpMap( tm1, map_list[ i ], - series, "", status ); - tm1 = astAnnul( tm1 ); - tm1 = tm2; - } - astSetInvert( map_list[ i ], inv ); - } - - channel = astChannel( NULL, NULL, "Full=1", status ); - old_inv = astGetInvert( tm1); - astSetInvert( tm1, invert ); - astDump( tm1, channel ); - astSetInvert( tm1, old_inv ); - channel = astAnnul( channel ); - tm1= astAnnul( tm1 ); - - } else if( opt > 0 && opt <= nmap && map_list[ opt - 1 ] ){ - m2 = map_list[ opt - 1 ]; - inv = invert_list[ opt - 1 ]; - class = astGetClass( m2 ); - - if( m2 && astIsAFrameSet( m2 ) ){ - m = astGetMapping( m2, AST__BASE, AST__CURRENT ); - class = astGetClass( m ); - - } else if( astIsATranMap( m2 ) ){ - - astDecompose( m2, &mf, &mi, &invf, &invi, &junk ); - - if( inv ) { - m = mi; - inv = invi; - } else { - m = mf; - inv = invf; - } - class = astGetClass( m ); - - } else { - m = astClone( m2 ); - } - - if( strcmp( class, "CmpMap" ) ){ - DisplayList( m, 1, inv, status ); - } else { - cm = (AstCmpMap *) m; - DisplayList( m, cm->series, inv, status ); - } - } else { - break; - } - } - - for( i = 0; i < nmap; i++ ) map_list[ i ] = astAnnul( map_list[ i ] ); - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - nmap = 0; - -} - - -void sink( const char *text ){ - if( fd && text ) fprintf( fd, "%s\n", text ); -} - -const char *source( void ){ - static char text[2000]; - static char *ptext; - if( fd ) { - ptext = fgets( text, 2000, fd ); - } else { - ptext = NULL; - } - return ptext; -} - -void tran( AstMapping *map, int *status ){ - char text[2000]; - AstFrame *infrm, *outfrm; - AstPointSet *pset1, *pset2; - double **ptr1, **ptr2; - int nin, nout, i, ok; - - if( !astGetTranForward( map ) ) { - printf( "\n No forward transformation available\n" ); - return; - } - - if( !astGetTranInverse( map ) ) { - printf( "\n No inverse transformation available\n" ); - } - - nin = astGetNin( map ); - nout = astGetNout( map ); - pset1 = astPointSet( 1, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - pset2 = astPointSet( 1, nout, "", status ); - ptr2 = astGetPoints( pset2 ); - - if( astIsAFrameSet( map ) ) { - infrm = astGetFrame( map, AST__BASE ); - outfrm = astGetFrame( map, AST__CURRENT ); - } else if( astIsAFrame( map ) ) { - infrm = (AstFrame *) map; - outfrm = (AstFrame *) map; - } else { - infrm = NULL; - outfrm = NULL; - } - - if( astOK ){ - ok = 0; - if( infrm != NULL ) { - ok = 1; - for( i = 0; i < nin; i++ ) { - printf( "\n Enter %s value (or ) > ", astGetLabel( infrm, i ) ); - scanf( "%s", text ); - if( !astUnformat( infrm, i, text, ptr1[ i ] ) ) { - ok = 0; - printf( "Bad formatted value supplied! Now try unformatted axis values...\n"); - break; - } - } - } - - if( !ok ) { - printf( "\n Enter %d axis values (BAD=999) > ", nin ); - for( i = 0; i < nin; i++ ) { - scanf( "%lg", ptr1[ i ] ); - if( ptr1[ i ][ 0 ] == 999.0 ) ptr1[ i ][ 0 ] = AST__BAD; - } - } - - astTransform( map, pset1, 1, pset2 ); - printf( "\n Forward: [ " ); - for( i = 0; i < nin; i++ ) { - if( ptr1[ i ][ 0 ] == AST__BAD ) { - printf( "999.0 " ); - } else { - printf( "%.*g ", DBL_DIG, ptr1[ i ][ 0 ] ); - } - } - - printf( "] -> [ " ); - for( i = 0; i < nout; i++ ) { - if( ptr2[ i ][ 0 ] == AST__BAD ) { - printf( "999.0 " ); - } else { - printf( "%.*g ", DBL_DIG, ptr2[ i ][ 0 ] ); - } - } - printf( "]\n" ); - - if( infrm != NULL && outfrm != NULL ) { - printf( " ( " ); - for( i = 0; i < nin; i++ ) { - printf( "%s ", astFormat( infrm, i, ptr1[ i ][ 0 ] ) ); - } - printf( ") -> ( " ); - for( i = 0; i < nout; i++ ) { - printf( "%s ", astFormat( outfrm, i, ptr2[ i ][ 0 ] ) ); - } - printf( ") formatted\n" ); - } - - - if( astGetTranInverse( map ) ) { - astTransform( map, pset2, 0, pset1 ); - printf( "\n Inverse: [ " ); - for( i = 0; i < nout; i++ ) { - if( ptr2[ i ][ 0 ] == AST__BAD ) { - printf( "999.0 " ); - } else { - printf( "%.*g ", DBL_DIG, ptr2[ i ][ 0 ] ); - } - } - - printf( "] -> [ " ); - for( i = 0; i < nin; i++ ) { - if( ptr1[ i ][ 0 ] == AST__BAD ) { - printf( "999.0 " ); - } else { - printf( "%.*g ", DBL_DIG, ptr1[ i ][ 0 ] ); - } - } - printf( "]\n" ); - - - if( infrm != NULL && outfrm != NULL ) { - printf( " ( " ); - for( i = 0; i < nout; i++ ) { - printf( "%s ", astFormat( outfrm, i, ptr2[ i ][ 0 ] ) ); - } - printf( ") -> ( " ); - for( i = 0; i < nin; i++ ) { - printf( "%s ", astFormat( infrm, i, ptr1[ i ][ 0 ] ) ); - } - printf( ") formatted\n" ); - } - } - } - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); -} - -void tranm( AstMapping **map, int *inv_list, int nmap, int inv, int *status ){ - AstPointSet *pset1, *pset2; - double **ptr1, **ptr2; - int nin, nout, i, j, inv0; - - inv0 = astGetInvert( map[ 0 ] ); - astSetInvert( map[ 0 ], inv_list[ 0 ] ); - nin = astGetNin( map[ 0 ] ); - astSetInvert( map[ 0 ], inv0 ); - - pset1 = astPointSet( 1, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - - if( astOK ){ - printf( "\n Enter %d axis values (BAD=999) > ", nin ); - for( i = 0; i < nin; i++ ) { - scanf( "%lg", ptr1[ i ] ); - if( ptr1[ i ][ 0 ] == 999.0 ) ptr1[ i ][ 0 ] = AST__BAD; - } - - printf("Forward...\n"); - for( j=0; j=0 && inv; j-- ) { - inv0 = astGetInvert( map[ j ] ); - astSetInvert( map[ j ], inv_list[ j ] ); - - nin = astGetNin( map[ j ] ); - pset2 = astPointSet( 1, nin, "", status ); - ptr2 = astGetPoints( pset2 ); - - astTransform( map[ j ], pset1, 0, pset2 ); - - printf( " Mapping %d gave [ ", j+1 ); - for( i = 0; i < nin; i++ ) { - if( ptr2[ i ][ 0 ] == AST__BAD ) { - printf( "999.0 " ); - } else { - printf( "%.*g ", DBL_DIG, ptr2[ i ][ 0 ] ); - } - } - printf( "]\n" ); - - pset1 = astAnnul( pset1 ); - astSetInvert( map[ j ], inv0 ); - - pset1 = pset2; - ptr1 = ptr2; - nout = nin; - } - - pset1 = astAnnul( pset1 ); - - } -} - - - - -void diff( AstMapping *map, int *status ){ - char text[200]; - AstFrame *infrm, *outfrm; - int nin, nout, i, ok, ax1, ax2; - double at[2000]; - - - nin = astGetNin( map ); - nout = astGetNout( map ); - - if( astIsAFrameSet( map ) ) { - infrm = astGetFrame( map, AST__BASE ); - outfrm = astGetFrame( map, AST__CURRENT ); - } else if( astIsAFrame( map ) ) { - infrm = (AstFrame *) map; - outfrm = (AstFrame *) map; - } else { - infrm = NULL; - outfrm = NULL; - } - - if( astOK ){ - ok = 0; - if( infrm != NULL ) { - ok = 1; - for( i = 0; i < nin; i++ ) { - printf( "\n Enter %s value (or ) > ", astGetLabel( infrm, i ) ); - scanf( "%s", text ); - if( !astUnformat( infrm, i, text, at + i ) ) { - ok = 0; - printf( "Bad formatted value supplied! Now try unformatted axis values...\n"); - break; - } - } - } - - if( !ok ) { - printf( "\n Enter %d axis values (BAD=999) > ", nin ); - for( i = 0; i < nin; i++ ) { - scanf( "%lg", at + i ); - if( at[ i ] == 999.0 ) at[ i ] = AST__BAD; - printf("(got %.*g)\n", DBL_DIG, at[ i ] ); - } - - } - - for( i = 0; i < nin; i++ ) { - printf("(%d: got %.*g)\n", i, DBL_DIG, at[ i ] ); - } - - printf( "\n Enter output to differentiate (zero-based index): > " ); - scanf( "%d", &ax1 ); - printf( "\n Enter input to vary (zero-based index): > " ); - scanf( "%d", &ax2 ); - printf( "%.*g \n", DBL_DIG, astRate( map, at, ax1, ax2 ) ); - } -} - diff --git a/ast/doincludes b/ast/doincludes deleted file mode 100755 index 656b0ac..0000000 --- a/ast/doincludes +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env perl - -# Reads a Latex file which contains \include{file} commands and writes -# the document to standard output with the text of the included files -# inserted. - -# Read input lines. - while ( <> ) { - -# Spot the \include{file} lines and extract the file name. - if ( ( $file ) = /^ *\\include{(.*)} *$/ ) { - -# Read the contents of the included file. - open( INCLUDE, $file . ".tex" ); - while ( ) { print; } - close( INCLUDE ); - -# Output other lines unchanged. - } else { - print; - } - } diff --git a/ast/dsbspecframe.c b/ast/dsbspecframe.c deleted file mode 100644 index 576f5b9..0000000 --- a/ast/dsbspecframe.c +++ /dev/null @@ -1,3266 +0,0 @@ -/* -*class++ -* Name: -* DSBSpecFrame - -* Purpose: -* Dual sideband spectral coordinate system description. - -* Constructor Function: -c astDSBSpecFrame -f AST_DSBSPECFRAME - -* Description: -* A DSBSpecFrame is a specialised form of SpecFrame which represents -* positions in a spectrum obtained using a dual sideband instrument. -* Such an instrument produces a spectrum in which each point contains -* contributions from two distinctly different frequencies, one from -* the "lower side band" (LSB) and one from the "upper side band" (USB). -* Corresponding LSB and USB frequencies are connected by the fact -* that they are an equal distance on either side of a fixed central -* frequency known as the "Local Oscillator" (LO) frequency. -* -* When quoting a position within such a spectrum, it is necessary to -* indicate whether the quoted position is the USB position or the -* corresponding LSB position. The SideBand attribute provides this -* indication. Another option that the SideBand attribute provides is -* to represent a spectral position by its topocentric offset from the -* LO frequency. -* -* In practice, the LO frequency is specified by giving the distance -* from the LO frequency to some "central" spectral position. Typically -* this central position is that of some interesting spectral feature. -* The distance from this central position to the LO frequency is known -* as the "intermediate frequency" (IF). The value supplied for IF can -* be a signed value in order to indicate whether the LO frequency is -* above or below the central position. - -* Inheritance: -* The DSBSpecFrame class inherits from the SpecFrame class. - -* Attributes: -* In addition to those attributes common to all SpecFrames, every -* DSBSpecFrame also has the following attributes: -* -* - AlignSideBand: Should alignment occur between sidebands? -* - DSBCentre: The central position of interest. -* - IF: The intermediate frequency used to define the LO frequency. -* - ImagFreq: The image sideband equivalent of the rest frequency. -* - SideBand: Indicates which sideband the DSBSpecFrame represents. - -* Functions: -c The DSBSpecFrame class does not define any new functions beyond those -f The DSBSpecFrame class does not define any new routines beyond those -* which are applicable to all SpecFrames. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David Berry (Starlink) - -* History: -* 5-AUG-2004 (DSB): -* Original version. -* 7-OCT-2004 (DSB): -* Fixed SetAttrib code which assigns values to SideBand. Previously -* all supplied values were ignored, leaving SideBand unchanged. -* 2-SEP-2005 (DSB): -* Allow conversion in any Domain within TopoMap (sometimes -* SpecFrames have a new Domain set which is not equal to SPECTRUM"). -* 12-SEP-2005 (DSB): -* Set all attributes required to described the RestFreq value -* before determining Mapping from RestFreq to ImagFreq in -* GetImageFreq. -* 2-DEC-2005 (DSB): -* Change default Domain from SPECTRUM to DSBSPECTRUM -* 3-APR-2006 (DSB): -* Fix memory leak in astLoadDSBSpecFrame. -* 6-OCT-2006 (DSB): -* Guard against annulling null pointers in subFrame. -* 27-OCT-2006 (DSB): -* Added AlignSideBand attribute. -* 31-OCT-2006 (DSB): -* Use AlignSideBand attribute in SubFrame only if we are not -* currently restoring a FrameSet's integrity. -* 31-JAN-2007 (DSB): -* Modified so that a DSBSpecFrame can be used as a template to find a -* DSBSpecFrame (or SpecFrame) contained within a CmpFrame. This -* involves changes in Match. -* 1-MAY-2007 (DSB): -* The default for AlignSideband has been changed from 1 to 0. -* 8-MAY-2007 (DSB): -* Correct initialisation of alignsideband in astInitDSBSpecFrame_. -* 19-OCT-2007 (DSB): -* Ignore SideBand alignment if the AlignSideBand attribute is zero -* in either the target or the template. -* 16-JAN-2007 (DSB): -* Modify SubFrame so that DSBSpecFrames are aligned in the -* observed sideband (LSB or USB) rather than always being aligned -* in the USB. -* 12-FEB-2010 (DSB): -* Report an error if the local oscillator frequency looks silly -* (specifically, if it less than the absolute intermediate frequency). -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -*class-- - -* Implementation Deficiencies: -* - The default values for System and StdOfRest inherited from the -* SpecFrame class are "Wave" and "Heliocentric". These are not -* usually what is wanted for a DSB instrument. Defaults such as -* "Freq" and "Topo" may be more appropriate. However, changing the -* defaults inherited from SpecFrame may cause problems in the -* astConvert algorithm. The astConvertX function in frame.c includes -* the following implementation deficiency warning: "One likely -* problem is with attributes which default in both the source and -* destination Frames. This means they also default in the common -* coordinate system. If these default values were to differ when -* matching different target Frames, however, we would be in trouble, -* because the common coordinate system would not then be remaining -* constant. The longer-term solution to this is probably to provide -* some mechanism to "fix" all attribute values for a Frame, by taking -* any attributes that are un-set and explicitly setting a firm value -* (equal to the default) so they cannot then change". So the defaults -* should probably be left unchanged until this fix is made. - -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS DSBSpecFrame - -#define BADSB -9999 -#define FIRST_SB -1 -#define LSB -1 -#define LO 0 -#define USB 1 -#define LAST_SB 1 - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "object.h" /* Base Object class */ -#include "channel.h" /* I/O channels */ -#include "specframe.h" /* Spectral frames (parent class) */ -#include "unit.h" /* Unit handling */ -#include "cmpmap.h" /* Compound Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "winmap.h" /* Window Mappings */ -#include "dsbspecframe.h" /* Interface definition for this class */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static const char *(* parent_getlabel)( AstFrame *, int, int * ); -static int (* parent_match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int (* parent_subframe)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * ); -static const char *(* parent_getdomain)( AstFrame *, int * ); - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->GetLabel_Buff[ 0 ] = 0; \ - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(DSBSpecFrame) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(DSBSpecFrame,Class_Init) -#define class_vtab astGLOBAL(DSBSpecFrame,Class_Vtab) -#define getattrib_buff astGLOBAL(DSBSpecFrame,GetAttrib_Buff) -#define getlabel_buff astGLOBAL(DSBSpecFrame,GetLabel_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Define the thread-specific globals for this class. */ - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ 101 ]; - -/* Default Label string buffer */ -static char getlabel_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstDSBSpecFrameVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstDSBSpecFrame *astDSBSpecFrameId_( const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ - -static AstMapping *TopoMap( AstDSBSpecFrame *, int, const char *, int * ); -static AstMapping *ToLOMapping( AstDSBSpecFrame *, const char *, int * )__attribute__((unused)); -static AstMapping *ToLSBMapping( AstDSBSpecFrame *, const char *, int * ); -static AstMapping *ToUSBMapping( AstDSBSpecFrame *, const char *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetLabel( AstFrame *, int, int * ); -static double GetImagFreq( AstDSBSpecFrame *, int * ); -static double GetLO( AstDSBSpecFrame *, const char *, const char *, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void VerifyAttrs( AstDSBSpecFrame *, const char *, const char *, const char *, int * ); -static const char *GetDomain( AstFrame *, int * ); - -static double GetIF( AstDSBSpecFrame *, int * ); -static int TestIF( AstDSBSpecFrame *, int * ); -static void ClearIF( AstDSBSpecFrame *, int * ); -static void SetIF( AstDSBSpecFrame *, double, int * ); - -static double GetDSBCentre( AstDSBSpecFrame *, int * ); -static int TestDSBCentre( AstDSBSpecFrame *, int * ); -static void ClearDSBCentre( AstDSBSpecFrame *, int * ); -static void SetDSBCentre( AstDSBSpecFrame *, double, int * ); - -static int GetSideBand( AstDSBSpecFrame *, int * ); -static int TestSideBand( AstDSBSpecFrame *, int * ); -static void ClearSideBand( AstDSBSpecFrame *, int * ); -static void SetSideBand( AstDSBSpecFrame *, int, int * ); - -static int GetAlignSideBand( AstDSBSpecFrame *, int * ); -static int TestAlignSideBand( AstDSBSpecFrame *, int * ); -static void ClearAlignSideBand( AstDSBSpecFrame *, int * ); -static void SetAlignSideBand( AstDSBSpecFrame *, int, int * ); - - -/* Member functions. */ -/* ================= */ -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a DSBSpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* DSBSpecFrame member function (over-rides the astClearAttrib protected -* method inherited from the SpecFrame class). - -* Description: -* This function clears the value of a specified attribute for a -* DSBSpecFrame, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstDSBSpecFrame *this; /* Pointer to the DSBSpecFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the DSBSpecFrame structure. */ - this = (AstDSBSpecFrame *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* DSBCentre. */ -/* ---------- */ - if ( !strcmp( attrib, "dsbcentre" ) ) { - astClearDSBCentre( this ); - -/* IF */ -/* -- */ - } else if ( !strcmp( attrib, "if" ) ) { - astClearIF( this ); - -/* SideBand */ -/* -------- */ - } else if ( !strcmp( attrib, "sideband" ) ) { - astClearSideBand( this ); - -/* AlignSideBand */ -/* ------------- */ - } else if ( !strcmp( attrib, "alignsideband" ) ) { - astClearAlignSideBand( this ); - -/* Read-only attributes. */ -/* --------------------- */ -/* Test if the attribute name matches any of the read-only attributes - of this class. If it does, then report an error. */ - } else if ( !strcmp( attrib, "imagfreq" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a DSBSpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* DSBSpecFrame member function (over-rides the protected astGetAttrib -* method inherited from the SpecFrame class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a DSBSpecFrame, formatted as a character string. - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the DSBSpecFrame, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the DSBSpecFrame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstDSBSpecFrame *this; /* Pointer to the DSBSpecFrame structure */ - AstMapping *tmap; /* Ptr to Mapping from topofreq to this */ - const char *result; /* Pointer value to return */ - double dval; /* Attribute value */ - double dtemp; /* Attribute value */ - int ival; /* Attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstDSBSpecFrame *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* DSBCentre */ -/* --------- */ - if ( !strcmp( attrib, "dsbcentre" ) ) { - -/* Get the value as topocentric frequency in Hz. */ - dval = astGetDSBCentre( this ); - -/* Find the Mapping from topocentric frequency in Hz to the spectral system - described by this SpecFrame. */ - tmap = TopoMap( this, 0, "astGetAttrib", status ); - if ( astOK ) { - -/* Transform the internal value from topocentric frequency into the required - system. */ - astTran1( tmap, 1, &dval, 1, &dtemp ); - if( dtemp == AST__BAD ) { - astError( AST__INTER, "astGetAttrib(%s): Cannot convert DSBCentre " - "value from topocentric frequency to the required " - "system.", status, astGetClass( this ) ); - } else { - -/* Format it. */ - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dtemp ); - result = getattrib_buff; - } - tmap = astAnnul( tmap ); - } - -/* IF */ -/* -- */ - } else if ( !strcmp( attrib, "if" ) ) { - dval = astGetIF( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval*1.0E-9 ); - result = getattrib_buff; - } - -/* ImagFreq */ -/* -------- */ - } else if ( !strcmp( attrib, "imagfreq" ) ) { - dval = astGetImagFreq( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval*1.0E-9 ); - result = getattrib_buff; - } - -/* SideBand */ -/* -------- */ - } else if ( !strcmp( attrib, "sideband" ) ) { - ival = astGetSideBand( this ); - if ( astOK ) { - result = ( ival == USB ) ? "USB" : (( ival == LO ) ? "LO" : "LSB" ); - } - -/* AlignSideBand */ -/* ------------- */ - } else if ( !strcmp( attrib, "alignsideband" ) ) { - ival = astGetAlignSideBand( this ) ? 1 : 0; - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; - -} - -static const char *GetDomain( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetDomain - -* Purpose: -* Obtain a pointer to the Domain attribute string for a DSBSpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* const char *GetDomain( AstFrame *this, int *status ) - -* Class Membership: -* DSBSpecFrame member function (over-rides the astGetDomain protected -* method inherited from the SpecFrame class). - -* Description: -* This function returns a pointer to the Domain attribute string -* for a DSBSpecFrame. - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a constant null-terminated string containing the -* Domain value. - -* Notes: -* - The returned pointer or the string it refers to may become -* invalid following further invocation of this function or -* modification of the DSBSpecFrame. -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstDSBSpecFrame *this; /* Pointer to DSBSpecFrame structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the DSBSpecFrame structure. */ - this = (AstDSBSpecFrame *) this_frame; - -/* If a Domain attribute string has been set, invoke the parent method - to obtain a pointer to it. */ - if ( astTestDomain( this ) ) { - result = (*parent_getdomain)( this_frame, status ); - -/* Otherwise, provide a pointer to a suitable default string. */ - } else { - result = "DSBSPECTRUM"; - } - -/* Return the result. */ - return result; -} - -static double GetImagFreq( AstDSBSpecFrame *this, int *status ) { -/* -*+ -* Name: -* astGetImagFreq - -* Purpose: -* Get the value of the ImagFreq attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "dsbspecframe.h" -* double GetImagFreq( AstDSBSpecFrame *this ) - -* Class Membership: -* DSBSpecFrame method. - -* Description: -* This function returns the image sideband frequency corresponding to -* the rest frequency. - -* Parameters: -* this -* Pointer to the Frame. - -* Returned Value: -* The required frequency, in Hz. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstDSBSpecFrame *rf_frame;/* DSBSpecFrame describing the rest frequency */ - AstMapping *map; /* Pointer to "Observed to Image" mapping */ - double result; /* The returned frequency */ - double rf; /* Rest frequency in observed sideband */ - int sb; /* SideBand value */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* The RestFreq attribute is an observed sideband frequency in the - source's standard of rest, measured in Hz. Temporaily set attributes - to these values. Create a copy of the supplied DSBSpecFrame and set - its attributes to these values. */ - rf_frame = astCopy( this ); - astSetStdOfRest( rf_frame, AST__SCSOR ); - astSetSystem( rf_frame, AST__FREQ ); - astSetUnit( rf_frame, 0, "Hz" ); - astSetC( rf_frame, "SideBand", "observed" ); - -/* Create a Mapping which transforms positions from the observed to the - image sideband. */ - sb = astGetSideBand( rf_frame ); - if( sb == USB ) { - map = ToLSBMapping( rf_frame, "astGetImagFreq", status ); - - } else if( sb == LSB ) { - map = ToUSBMapping( rf_frame, "astGetImagFreq", status ); - - } else { - map = NULL; - astError( AST__INTER, "astGetImagFreq(%s): Illegal sideband value " - "(%d) encountered (internal AST programming error).", status, - astGetClass( this ), sb ); - } - -/* Get the rest frequency in Hz, and transform it using the above Mapping. */ - rf = astGetRestFreq( rf_frame ); - astTran1( map, 1, &rf, 1, &result ); - -/* Free resources */ - map = astAnnul( map ); - rf_frame = astAnnul( rf_frame ); - -/* If an error has occurrred, return AST__BAD. */ - if( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; - -} - -static const char *GetLabel( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetLabel - -* Purpose: -* Access the Label string for a DSBSpecFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* const char *GetLabel( AstFrame *this, int axis, int *status ) - -* Class Membership: -* DSBSpecFrame member function (over-rides the astGetLabel method inherited -* from the SpecFrame class). - -* Description: -* This function returns a pointer to the Label string for a specified axis -* of a DSBSpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *result; /* Pointer to label string */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetLabel" ); - -/* Invoke the parent astGetLabel method to obtain a pointer to it. */ - result = (*parent_getlabel)( this, axis, status ); - -/* Check if this is a default value. If so, append a string indicating - the sideband. */ - if ( !astTestLabel( this, axis ) ) { - -/* If OK, supply a pointer to a suitable default label string. */ - sprintf( getlabel_buff, "%s (%s)", result, astGetAttrib( this, "sideband" ) ); - result = getlabel_buff; - } - -/* Return the result. */ - return result; - -} - -static double GetLO( AstDSBSpecFrame *this, const char *check_msg, - const char *method, int *status ) { -/* -* Name: -* GetLO - -* Purpose: -* Get the Local Oscillator frequency. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* double GetLO( AstDSBSpecFrame *this, const char *check_msg, -* const char *method, int *status ) - -* Class Membership: -* DSBSpecFrame method. - -* Description: -* This function returns the local oscillator frequency in topocentric -* frequency. - -* Parameters: -* this -* Pointer to the Frame. -* check_msg -* If not NULL, an error will be reported if either the DSBCentre -* or IF attribute has not been set to an explicit value. In this -* case, the error message will include the supplied text. -* method -* The name of the calling method - used in error messages. -* status -* Pointer to the inherited status value. - -* Returned Value: -* The local oscillator frequency, in Hz. - -* Notes: -* - An error is reported if the local oscillator frequency looks -* un-physical (specifically, if it is less than the absolute value of -* the intermediate frequency). -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - double f_if; /* Intermediate frequency (topo,HZ) */ - double result; /* The returned frequency */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* If required, check that explicit values have been assigned to the required - attributes (i.e. report an error if a default value would be used for - either attribute). */ - if( check_msg ) VerifyAttrs( this, check_msg, "IF DSBCentre", method, - status ); - -/* The local oscillator is the sum of the intermediate frequency and the - observation centre frequency. */ - f_if = astGetIF( this ); - result = astGetDSBCentre( this ) + f_if; - -/* Check the local oscillator frequency is no smaller than the absolute - intermediate frequency. */ - if( result < fabs( f_if ) && astOK ) { - astError( AST__ATTIN, "%s(%s): The local oscillator frequency (%g Hz) " - "is too low (less than the intermediate frequency: %g Hz).", - status, method, astGetClass( this ), result, fabs( f_if ) ); - astError( AST__ATTIN, " This could be caused by a bad value for" - " either the IF attribute (currently %g Hz) or the DSBCentre " - "attribute (currently %g Hz).", status, f_if, - astGetDSBCentre( this ) ); - } - -/* If an error has occurrred, return AST__BAD. */ - if( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -void astInitDSBSpecFrameVtab_( AstDSBSpecFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitDSBSpecFrameVtab - -* Purpose: -* Initialise a virtual function table for a DSBSpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "dsbspecframe.h" -* void astInitDSBSpecFrameVtab( AstDSBSpecFrameVtab *vtab, const char *name ) - -* Class Membership: -* DSBSpecFrame vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the DSBSpecFrame class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitSpecFrameVtab( (AstSpecFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsADSBSpecFrame) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstSpecFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->ClearDSBCentre = ClearDSBCentre; - vtab->TestDSBCentre = TestDSBCentre; - vtab->GetDSBCentre = GetDSBCentre; - vtab->SetDSBCentre = SetDSBCentre; - - vtab->ClearIF = ClearIF; - vtab->TestIF = TestIF; - vtab->GetIF = GetIF; - vtab->SetIF = SetIF; - - vtab->ClearSideBand = ClearSideBand; - vtab->TestSideBand = TestSideBand; - vtab->GetSideBand = GetSideBand; - vtab->SetSideBand = SetSideBand; - - vtab->ClearAlignSideBand = ClearAlignSideBand; - vtab->TestAlignSideBand = TestAlignSideBand; - vtab->GetAlignSideBand = GetAlignSideBand; - vtab->SetAlignSideBand = SetAlignSideBand; - - vtab->GetImagFreq = GetImagFreq; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - frame = (AstFrameVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_getdomain = frame->GetDomain; - frame->GetDomain = GetDomain; - - parent_overlay = frame->Overlay; - frame->Overlay = Overlay; - - parent_match = frame->Match; - frame->Match = Match; - - parent_subframe = frame->SubFrame; - frame->SubFrame = SubFrame; - - parent_getlabel = frame->GetLabel; - frame->GetLabel = GetLabel; - -/* Declare the class delete function.*/ - astSetDump( vtab, Dump, "DSBSpecFrame", "Dual sideband spectral axis" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int Match( AstFrame *template_frame, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* Match - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* DSBSpecFrame member function (over-rides the protected astMatch method -* inherited from the SpecFrame class). - -* Description: -* This function matches a "template" DSBSpecFrame to a "target" Frame and -* determines whether it is possible to convert coordinates between them. -* If it is, a mapping that performs the transformation is returned along -* with a new Frame that describes the coordinate system that results when -* this mapping is applied to the "target" coordinate system. In addition, -* information is returned to allow the axes in this "result" Frame to be -* associated with the corresponding axes in the "target" and "template" -* Frames from which they are derived. - -* Parameters: -* template -* Pointer to the template DSBSpecFrame. This describes the coordinate -* system (or set of possible coordinate systems) into which we wish to -* convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate system in -* which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case. -* template_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the template DSBSpecFrame axis from -* which it is derived. If it is not derived from any template -* DSBSpecFrame axis, a value of -1 will be returned instead. -* target_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the target Frame axis from which it -* is derived. If it is not derived from any target Frame axis, a value -* of -1 will be returned instead. -* map -* Address of a location where a pointer to a new Mapping will be -* returned if the requested coordinate conversion is possible. If -* returned, the forward transformation of this Mapping may be used to -* convert coordinates between the "target" Frame and the "result" -* Frame (see below) and the inverse transformation will convert in the -* opposite direction. -* result -* Address of a location where a pointer to a new Frame will be returned -* if the requested coordinate conversion is possible. If returned, this -* Frame describes the coordinate system that results from applying the -* returned Mapping (above) to the "target" coordinate system. In -* general, this Frame will combine attributes from (and will therefore -* be more specific than) both the target and the template Frames. In -* particular, when the template allows the possibility of transformaing -* to any one of a set of alternative coordinate systems, the "result" -* Frame will indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate conversion is -* possible. Otherwise zero is returned (this will not in itself result in -* an error condition). - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* This implementation addresses the matching of a DSBSpecFrame class -* object to any other class of Frame. A DSBSpecFrame will match any class -* of DSBSpecFrame (i.e. possibly from a derived class) but will not match -* a less specialised class of Frame (except for a SpecFrame). -*/ - -/* Local Variables: */ - AstDSBSpecFrame *template; /* Pointer to template DSBSpecFrame structure */ - AstFrame *frame0; /* Pointer to Frame underlying axis 0 */ - int iaxis0; /* Axis index underlying axis 0 */ - int match; /* Coordinate conversion possible? */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the template DSBSpecFrame structure. */ - template = (AstDSBSpecFrame *) template_frame; - -/* The first criterion for a match is that the template matches as a - SpecFrame class object. This ensures that the number of axes (1) and - domain, class, etc. of the target Frame are suitable. Invoke the parent - "astMatch" method to verify this. */ - match = (*parent_match)( template_frame, target, matchsub, - template_axes, target_axes, map, result, status ); - -/* If a match was found, the target Frame must be (or contain) a SpecFrame, - but this target SpecFrame may be a simple SpecFrame rather than a - DSBSpecFrame. We use the returned objects directly if the target - SpecFrame is not a DSBSpecFrame. So if a DSBSpecFrame and a base - SpecFrame are aligned, this will result in the DSBSpecFrame behaving as - a normal SpecFrame. */ - if ( astOK && match ) { - -/* Get the primary Frame associated with the matching target axis. */ - astPrimaryFrame( target, (*target_axes)[ 0 ], &frame0, &iaxis0 ); - -/* Skip this next section, thus retaining the values returned by the - parent Match method above, if the target axis is not a DSBSpecFrame. */ - if( astIsADSBSpecFrame( frame0 ) ) { - -/* Annul the returned objects, which are not needed, but keep the axis - association arrays which already hold the correct values. */ - *map = astAnnul( *map ); - *result = astAnnul( *result ); - -/* Use the target's "astSubFrame" method to create a new Frame (the - result Frame) with a copy of of the target axis. This process also - overlays the template attributes on to the target Frame and returns a - Mapping between the target and result Frames which effects the required - coordinate conversion. */ - match = astSubFrame( target, template, 1, *target_axes, *template_axes, - map, result ); - } - -/* Free resources. */ - frame0 = astAnnul( frame0 ); - - } - -/* If an error occurred, or conversion to the result Frame's coordinate - system was not possible, then free all memory, annul the returned - objects, and reset the returned value. */ - if ( !astOK || !match ) { - if( *template_axes ) *template_axes = astFree( *template_axes ); - if( *target_axes ) *target_axes = astFree( *target_axes ); - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static void Overlay( AstFrame *template, const int *template_axes, - AstFrame *result, int *status ) { -/* -* Name: -* Overlay - -* Purpose: -* Overlay the attributes of a template DSBSpecFrame on to another Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void Overlay( AstFrame *template, const int *template_axes, -* AstFrame *result, int *status ) - -* Class Membership: -* DSBSpecFrame member function (over-rides the protected astOverlay method -* inherited from the SpecFrame class). - -* Description: -* This function overlays attributes of a DSBSpecFrame (the "template") on to -* another Frame, so as to over-ride selected attributes of that second -* Frame. Normally only those attributes which have been specifically set -* in the template will be transferred. This implements a form of -* defaulting, in which a Frame acquires attributes from the template, but -* retains its original attributes (as the default) if new values have not -* previously been explicitly set in the template. -* -* Note that if the result Frame is a DSBSpecFrame and a change of spectral -* coordinate system occurs as a result of overlaying its System -* attribute, then some of its original attribute values may no -* longer be appropriate (e.g. the Title, or attributes describing -* its axes). In this case, these will be cleared before overlaying -* any new values. - -* Parameters: -* template -* Pointer to the template DSBSpecFrame, for which values should have been -* explicitly set for any attribute which is to be transferred. -* template_axes -* Pointer to an array of int, with one element for each axis of the -* "result" Frame (see below). For each axis in the result frame, the -* corresponding element of this array should contain the (zero-based) -* index of the template axis to which it corresponds. This array is used -* to establish from which template axis any axis-dependent attributes -* should be obtained. -* -* If any axis in the result Frame is not associated with a template -* axis, the corresponding element of this array should be set to -1. -* -* If a NULL pointer is supplied, the template and result axis -* indices are assumed to be identical. -* result -* Pointer to the Frame which is to receive the new attribute values. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - In general, if the result Frame is not from the same class as the -* template DSBSpecFrame, or from a class derived from it, then attributes may -* exist in the template DSBSpecFrame which do not exist in the result Frame. -* In this case, these attributes will not be transferred. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent class astOverlay method to transfer attributes inherited - from the parent class. */ - (*parent_overlay)( template, template_axes, result, status ); - -/* Check if the result Frame is a DSBSpecFrame or from a class derived from - DSBSpecFrame. If not, we cannot transfer DSBSpecFrame attributes to it as it is - insufficiently specialised. In this case simply omit these attributes. */ - if( astIsADSBSpecFrame( result ) && astOK ) { - -/* Define macros that test whether an attribute is set in the template and, - if so, transfers its value to the result. */ -#define OVERLAY(attribute) \ - if ( astTest##attribute( template ) ) { \ - astSet##attribute( result, astGet##attribute( template ) ); \ - } - -/* Use the macro to transfer each DSBSpecFrame attribute in turn. */ - OVERLAY(DSBCentre) - OVERLAY(IF) - OVERLAY(SideBand) - OVERLAY(AlignSideBand) - } - -/* Undefine macros local to this function. */ -#undef OVERLAY -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a DSBSpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* DSBSpecFrame member function (over-rides the astSetAttrib protected -* method inherited from the SpecFrame class). - -* Description: -* This function assigns an attribute value for a DSBSpecFrame, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstDSBSpecFrame *this; /* Pointer to the DSBSpecFrame structure */ - AstMapping *tmap; /* Ptr to Mapping from this to topofreq */ - AstMapping *umap; /* Ptr to Mapping between units */ - double dtemp; /* Attribute value */ - double dval; /* Attribute value */ - int ival; /* Attribute value */ - int len; /* Length of setting string */ - int nc; /* Used length */ - int off; /* Offset to start of string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the DSBSpecFrame structure. */ - this = (AstDSBSpecFrame *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* DSBCentre */ -/* --------- */ - if ( strstr( setting, "dsbcentre=" ) ) { - -/* Without any units indication - assume it is supplied in the system of - the DSBSpecFrame. */ - int ok = 0; - if( nc = 0, - ( 1 == astSscanf( setting, "dsbcentre= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - ok = 1; - -/* With units indication. Is there a Mapping from the supplied units to the - units used by the DSBSpecFrame? If so, use the Mapping to convert the - supplied value to the required units. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "dsbcentre= %lg %n%*s %n", &dval, &off, &nc ) ) - && ( nc >= len ) ) { - - if( ( umap = astUnitMapper( setting + off, astGetUnit( this, 0 ), NULL, NULL ) ) ) { - astTran1( umap, 1, &dval, 1, &dtemp ); - dval = dtemp; - umap = astAnnul( umap ); - if( astOK && dval != AST__BAD ) ok = 1; - -/* Otherwise report an error. */ - } else if( astOK ) { - astError( AST__ATTIN, "astSetAttrib(%s): Value supplied for " - "attribute \"DSBCentre\" (%s) uses units which are " - "inappropriate for the current spectral system (%s).", status, - astGetClass( this ), setting + 10, - astGetTitle( this ) ); - } - } - -/* Convert the value from the supplied system to topocentric frequency in - Hx, and store. */ - if( ok ) { - -/* Find the Mapping from the spectral system described by this SpecFrame to - topocentric frequency in Hz. */ - tmap = TopoMap( this, 1, "astSetAttrib", status ); - if ( astOK ) { - -/* Transform the supplied value to topocentric frequency. */ - astTran1( tmap, 1, &dval, 1, &dtemp ); - if( dtemp == AST__BAD ) { - astError( AST__ATTIN, "astSetAttrib(%s): The setting \"%s\" is " - "invalid for a %s.", status, astGetClass( this ), setting, - astGetClass( this ) ); - } else { - -/* Store it. */ - astSetDSBCentre( this, dtemp ); - - } - tmap = astAnnul( tmap ); - } - - } else if( astOK ) { - astError( AST__ATTIN, "astSetAttrib(%s): The setting \"%s\" is " - "invalid for a %s.", status, astGetClass( this ), setting, - astGetClass( this ) ); - } - -/* IF */ -/* -- */ -/* Without any units indication - assume GHz. Convert to Hz for storage. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "if= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetIF( this, dval*1.0E9 ); - -/* With units indication. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "if= %lg %n%*s %n", &dval, &off, &nc ) ) - && ( nc >= len ) ) { - -/* Is there a Mapping from the supplied units to Hz? If so, use the - Mapping to convert the supplied value to Hz. */ - if( ( umap = astUnitMapper( setting + off, "Hz", NULL, NULL ) ) ) { - astTran1( umap, 1, &dval, 1, &dtemp ); - umap = astAnnul( umap ); - -/* Set the intermediate frequency. */ - astSetIF( this, dtemp ); - -/* Otherwise report an error. */ - } else if( astOK ) { - astError( AST__ATTIN, "astSetAttrib(%s): Intermediate frequency given " - "in an inappropriate system of units \"%g %s\".", status, - astGetClass( this ), dval, setting + off ); - } - -/* SideBand */ -/* -------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "sideband= %n%*s %n", &ival, &nc ) ) - && ( nc >= len ) ) { - - if( astChrMatch( "usb", setting+ival ) ) { - astSetSideBand( this, USB ); - - } else if( astChrMatch( "lsb", setting+ival ) ) { - astSetSideBand( this, LSB ); - - } else if( astChrMatch( "lo", setting+ival ) ) { - astSetSideBand( this, LO ); - - } else if( astChrMatch( "observed", setting+ival ) ) { - astSetSideBand( this, ( astGetIF( this ) > 0 ) ? LSB : USB ); - - } else if( astChrMatch( "image", setting+ival ) ) { - astSetSideBand( this, ( astGetIF( this ) <= 0 ) ? LSB : USB ); - - } else { - astError( AST__ATTIN, "astSetAttrib(%s): The setting \"%s\" is " - "invalid for a %s.", status, astGetClass( this ), setting, - astGetClass( this ) ); - } - -/* AlignSideBand */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "alignsideband= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetAlignSideBand( this, ival ); - -/* Read-only attributes. */ -/* --------------------- */ -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* Use this macro to report an error if a read-only attribute has been - specified. */ - } else if ( MATCH( "imagfreq" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Pass any unrecognised setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static int SubFrame( AstFrame *target_frame, AstFrame *template, - int result_naxes, const int *target_axes, - const int *template_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* SubFrame - -* Purpose: -* Select axes from a DSBSpecFrame and convert to the new coordinate -* system. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* int SubFrame( AstFrame *target, AstFrame *template, -* int result_naxes, const int *target_axes, -* const int *template_axes, AstMapping **map, -* AstFrame **result, int *status ) - -* Class Membership: -* DSBSpecFrame member function (over-rides the protected astSubFrame -* method inherited from the SpecFrame class). - -* Description: -* This function selects a requested sub-set (or super-set) of the axes -* from a "target" DSBSpecFrame and creates a new Frame with copies of -* the selected axes assembled in the requested order. It then -* optionally overlays the attributes of a "template" Frame on to the -* result. It returns both the resulting Frame and a Mapping that -* describes how to convert between the coordinate systems described by -* the target and result Frames. If necessary, this Mapping takes -* account of any differences in the Frames' attributes due to the -* influence of the template. - -* Parameters: -* target -* Pointer to the target DSBSpecFrame, from which axes are to be -* selected. -* template -* Pointer to the template Frame, from which new attributes for the -* result Frame are to be obtained. Optionally, this may be NULL, in -* which case no overlaying of template attributes will be performed. -* result_naxes -* Number of axes to be selected from the target Frame. This number may -* be greater than or less than the number of axes in this Frame (or -* equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving a list -* of the (zero-based) axis indices of the axes to be selected from the -* target DSBSpecFrame. The order in which these are given determines -* the order in which the axes appear in the result Frame. If any of the -* values in this array is set to -1, the corresponding result axis will -* not be derived from the target Frame, but will be assigned default -* attributes instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This should -* contain a list of the template axes (given as zero-based axis indices) -* with which the axes of the result Frame are to be associated. This -* array determines which axes are used when overlaying axis-dependent -* attributes of the template on to the result. If any element of this -* array is set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not used and -* a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned Mapping. -* The forward transformation of this Mapping will describe how to -* convert coordinates from the coordinate system described by the target -* DSBSpecFrame to that described by the result Frame. The inverse -* transformation will convert in the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is possible -* between the target and the result Frame. Otherwise zero is returned and -* *map and *result are returned as NULL (but this will not in itself -* result in an error condition). In general, coordinate conversion should -* always be possible if no template Frame is supplied but may not always -* be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* - This implementation addresses the selection of axes from a -* DSBSpecFrame object. This results in another object of the same class -* only if the single DSBSpecFrame axis is selected exactly once. -* Otherwise, the result is a Frame class object which inherits the -* DSBSpecFrame's axis information (if appropriate) but none of the other -* properties of a DSBSpecFrame. -* - In the event that a DSBSpecFrame results, the returned Mapping will -* take proper account of the relationship between the target and result -* coordinate systems. -* - In the event that a Frame class object results, the returned Mapping -* will only represent a selection/permutation of axes. - -* Implementation Deficiencies: -* - Any axis selection is currently permitted. Probably this should be -* restricted so that each axis can only be selected once. The -* astValidateAxisSelection method will do this but currently there are bugs -* in the CmpFrame class that cause axis selections which will not pass this -* test. Install the validation when these are fixed. -*/ - -/* Local Variables: */ - AstDSBSpecFrame *dsbresult;/* Pointer to the DSBSpecFrame result Frame */ - AstDSBSpecFrame *dsbtarget;/* Pointer to the DSBSpecFrame target Frame */ - AstMapping *map1; /* Intermediate Mapping */ - AstMapping *map2; /* Intermediate Mapping */ - AstMapping *map3; /* Intermediate Mapping */ - int alignsb; /* Use sidebands to align the Frames? */ - int match; /* Coordinate conversion is possible? */ - int obs_sb; /* The observed sideband value */ - int old_sb; /* The original Sideband value */ - -/* Initialise the returned values. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Invoke the astSubFrame method inherited from the parent SpecFrame - class. This will (if possible) create a result Frame which is a - DSBSpecFrame (since the supplied target Frame is a DSBSpecFrame). - However, the Mapping from target to result Frame will take no account - of any differences in the values of the attributes specific to the - DSBSpecFrame class. */ - match = (*parent_subframe)( target_frame, template, result_naxes, - target_axes, template_axes, map, result, status ); - -/* If a match occurred, and the result and template Frames are both - DSBSpecFrames, we now modify the Mapping to take account of - DSBSpecFrame-specific attributes. */ - if( match && template && astIsADSBSpecFrame( template ) && - astIsADSBSpecFrame( *result ) ) { - -/* Get pointers to the two DSBSpecFrames */ - dsbtarget = (AstDSBSpecFrame *) target_frame; - -/* See whether alignment occurs between sidebands. If the current call to - this function is part of the process of restoring a FrameSet's integrity - following changes to the FrameSet's current Frame, then we ignore the - setting of the AlignSideBand attributes and use 1. This ensures that - when the SideBand attribute (for instance) is changed via a FrameSet - pointer, the Mappings within the FrameSet are modified to produce - frequencies in the new SideBand. In most other cases, astronomers - usually want to align the DSBSpecFrames as if they were basic SpecFrames - (that is, ignoring the setting of the SideBand attribute). */ - if( astGetFrameFlags( target_frame ) & AST__INTFLAG ) { - alignsb = 1; - } else { - alignsb = astGetAlignSideBand( dsbtarget ) && - astGetAlignSideBand( (AstDSBSpecFrame *) template ); - } - -/* If we are aligning the sidebands we need to modify the Mapping - returned above by the parent SubFrame method. The existing Mapping - will convert between the spectral systems represented by the two - DSBSpecFrames but will not take account of any difference in - sidebands. */ - if( alignsb ) { - -/* We assume that alignment occurs in the observed sideband. Determine - which side band is the observed sideband in the target. */ - old_sb = astGetSideBand( dsbtarget ); - astSetC( dsbtarget, "SideBand", "observed" ); - obs_sb = astGetSideBand( dsbtarget ); - astSetSideBand( dsbtarget, old_sb ); - -/* Create a Mapping which transforms positions from the target to an exact - copy of the target in which the SideBand attribute is set to the - observed (USB or LSB) sideband. This will be a UnitMap if the target - already represents the observed sideband. */ - if( obs_sb == USB ) { - map1 = ToUSBMapping( dsbtarget, "astSubFrame", status ); - - } else if( obs_sb == LSB ) { - map1 = ToLSBMapping( dsbtarget, "astSubFrame", status ); - - } else { - map1 = NULL; - astError( AST__INTER, "astGetImagFreq(%s): Illegal sideband value " - "(%d) encountered (internal AST programming error).", status, - astGetClass( target_frame ), obs_sb ); - } - -/* Determine which side band is the observed sideband in the result. */ - dsbresult = (AstDSBSpecFrame *) *result; - old_sb = astGetSideBand( dsbresult ); - astSetC( dsbresult, "SideBand", "observed" ); - obs_sb = astGetSideBand( dsbresult ); - astSetSideBand( dsbresult, old_sb ); - -/* Create a Mapping which transforms positions from the result to an exact - copy of the result in which the SideBand attribute is set to the - obserfed sideband. This will be a UnitMap if the target already represents - the observed sideband. */ - if( obs_sb == USB ) { - map2 = ToUSBMapping( dsbresult, "astSubFrame", status ); - - } else if( obs_sb == LSB ) { - map2 = ToLSBMapping( dsbresult, "astSubFrame", status ); - - } else { - map2 = NULL; - astError( AST__INTER, "astGetImagFreq(%s): Illegal sideband value " - "(%d) encountered (internal AST programming error).", status, - astGetClass( target_frame ), obs_sb ); - } - -/* Invert it to get the mapping from the observed sideband to the result. */ - astInvert( map2 ); - -/* Form a Mapping which first maps target values to the observed sideband, - then applies the Mapping returned by the parent SubFrame method in - order to convert between spectral systems, and then converts from the - observed sideband to the SideBand of the result. */ - map3 = (AstMapping *) astCmpMap( map1, *map, 1, "", status ); - map1 = astAnnul( map1 ); - *map = astAnnul( *map ); - map1 = (AstMapping *) astCmpMap( map3, map2, 1, "", status ); - map3 = astAnnul( map3 ); - map2 = astAnnul( map2 ); - -/* Returned the simplified Mapping. */ - *map = astSimplify( map1 ); - map1 = astAnnul( map1 ); - } - } - -/* If an error occurred or no match was found, annul the returned - objects and reset the returned result. */ - if ( !astOK || !match ) { - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; - -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a DSBSpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* DSBSpecFrame member function (over-rides the astTestAttrib protected -* method inherited from the SpecFrame class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a DSBSpecFrame's attributes. - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstDSBSpecFrame *this; /* Pointer to the DSBSpecFrame structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the DSBSpecFrame structure. */ - this = (AstDSBSpecFrame *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* DSBCentre */ -/* --------- */ - if ( !strcmp( attrib, "dsbcentre" ) ) { - result = astTestDSBCentre( this ); - -/* IF */ -/* -- */ - } else if ( !strcmp( attrib, "if" ) ) { - result = astTestIF( this ); - -/* SideBand */ -/* -------- */ - } else if ( !strcmp( attrib, "sideband" ) ) { - result = astTestSideBand( this ); - -/* AlignSideBand */ -/* ------------- */ - } else if ( !strcmp( attrib, "alignsideband" ) ) { - result = astTestAlignSideBand( this ); - -/* Read-only attributes. */ -/* --------------------- */ -/* Test if the attribute name matches any of the read-only attributes - of this class. If it does, then return zero. */ - } else if ( !strcmp( attrib, "imagfreq" ) ) { - result = 0; - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstMapping *ToLOMapping( AstDSBSpecFrame *this, const char *method, int *status ){ -/* -* Name: -* ToLOMapping - -* Purpose: -* Create a Mapping which transforms a DSBSpecFrame to offset from the -* local oscillator frequency. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* AstMapping *ToLOMapping( AstDSBSpecFrame *this, const char *method, int *status ) - -* Class Membership: -* DSBSpecFrame member function - -* Description: -* This function returns a pointer to a new Mapping which transforms -* positions in the supplied DSBSpecFrame into an offset from the local -* oscillator frequency. This will be a UnitMap if the DSBSpecFrame -* already represents offset from the local oscillator frequency. - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* method -* Pointer to a null-terminated string containing the name of the -* public invoking method. This is only used in the construction of -* error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a new Mapping. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *fmap; /* LSB to USB (topo freq) */ - AstMapping *map1; /* This to USB (topo freq) */ - AstMapping *map2; /* This (LSB) to This (USB) */ - AstMapping *result; /* Pointer to the returned Mapping */ - AstMapping *tmap; /* This to topocentric freq */ - double f_lo; /* Local oscillator freq (topo Hz) */ - double f_in_a; /* First LSB or USB freq */ - double f_in_b; /* Second LSB or USB freq */ - double f_out_a; /* First LO freq */ - double f_out_b; /* Second LO freq */ - int sb; /* SideBand value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the DSBSpecFrame already represents LO offset, return a UnitMap.*/ - sb = astGetSideBand( this ); - if( sb == LO ) { - result = (AstMapping *) astUnitMap( 1, "", status ); - -/* If the DSBSpecFrame represents the USB or LSB, create a suitable WinMap. */ - } else { - -/* Find the Mapping from the spectral system described by this SpecFrame to - topocentric frequency in Hz. */ - tmap = TopoMap( this, 1, method, status ); - -/* Calculate the local oscillator frequency (topocentric in Hertz). */ - f_lo = GetLO( this, "create a Mapping to upper sideband", - "astGetImagFreq", status ); - -/* Create a 1D WinMap which converts f_in to f_out. */ - if( sb == LSB ) { - f_in_a = 0.0; - f_in_b = f_lo; - f_out_a = f_lo; - f_out_b = 0.0; - } else { - f_in_a = 0.0; - f_in_b = -f_lo; - f_out_a = f_lo; - f_out_b = 0.0; - } - - fmap = (AstMapping *) astWinMap( 1, &f_in_a, &f_in_b, &f_out_a, &f_out_b, "", status ); - -/* Construct the Mapping: input to f_in, f_in to f_out, f_out to input */ - map1 = (AstMapping *) astCmpMap( tmap, fmap, 1, "", status ); - astInvert( tmap ); - map2 = (AstMapping *) astCmpMap( map1, tmap, 1, "", status ); - -/* Simplify */ - result = astSimplify( map2 ); - -/* Free resources */ - tmap = astAnnul( tmap ); - fmap = astAnnul( fmap ); - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - } - -/* Return NULL if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; - -} - -static AstMapping *ToLSBMapping( AstDSBSpecFrame *this, const char *method, int *status ){ -/* -* Name: -* ToLSBMapping - -* Purpose: -* Create a Mapping which transforms a DSBSpecFrame to the lower -* sideband. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* AstMapping *ToLSBMapping( AstDSBSpecFrame *this, const char *method, int *status ) - -* Class Membership: -* DSBSpecFrame member function - -* Description: -* This function returns a pointer to a new Mapping which transforms -* positions in the supplied DSBSpecFrame to the lower sideband. This -* will be a UnitMap if the DSBSpecFrame already represents the lower -* sideband. - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* method -* Pointer to a null-terminated string containing the name of the -* public invoking method. This is only used in the construction of -* error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a new Mapping. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *fmap; /* LSB to USB (topo freq) */ - AstMapping *map1; /* This to USB (topo freq) */ - AstMapping *map2; /* This (LSB) to This (USB) */ - AstMapping *result; /* Pointer to the returned Mapping */ - AstMapping *tmap; /* This to topocentric freq */ - double f_lo; /* Local oscillator freq (topo Hz) */ - double f_out_a; /* First LSB freq */ - double f_out_b; /* Second LSB freq */ - double f_in_a; /* First USB or LO freq */ - double f_in_b; /* Second USB or LO freq */ - int sb; /* SideBand value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the DSBSpecFrame already represents the LSB, return a UnitMap.*/ - sb = astGetSideBand( this ); - if( sb == LSB ) { - result = (AstMapping *) astUnitMap( 1, "", status ); - -/* If the DSBSpecFrame represents the USB or LO offset, create a suitable - WinMap. */ - } else { - -/* Find the Mapping from the spectral system described by this SpecFrame to - topocentric frequency in Hz. */ - tmap = TopoMap( this, 1, method, status ); - -/* Calculate the local oscillator frequency (topocentric in Hertz). */ - f_lo = GetLO( this, "create a Mapping to lower sideband", - "astGetImagFreq", status ); - -/* Create a 1D WinMap which converts USB or LO to LSB. */ - if( sb == USB ) { - f_in_a = 0.0; - f_in_b = 2*f_lo; - f_out_a = 2*f_lo; - f_out_b = 0.0; - } else { - f_in_a = 0.0; - f_in_b = f_lo; - f_out_a = f_lo; - f_out_b = 0.0; - } - - fmap = (AstMapping *) astWinMap( 1, &f_in_a, &f_in_b, &f_out_a, &f_out_b, "", status ); - -/* Construct the Mapping: input to f_in, f_in to f_out, f_out to input */ - map1 = (AstMapping *) astCmpMap( tmap, fmap, 1, "", status ); - astInvert( tmap ); - map2 = (AstMapping *) astCmpMap( map1, tmap, 1, "", status ); - -/* Simplify */ - result = astSimplify( map2 ); - -/* Free resources */ - tmap = astAnnul( tmap ); - fmap = astAnnul( fmap ); - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - } - -/* Return NULL if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; - -} - -static AstMapping *TopoMap( AstDSBSpecFrame *this, int forward, - const char *method, int *status ){ -/* -* Name: -* TopoMap - -* Purpose: -* Create a Mapping which transforms a DSBSpecFrame to topocentric -* frequency. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* AstMapping *TopoMap( AstDSBSpecFrame *this, int forward, -* const char *method, int *status ) - -* Class Membership: -* DSBSpecFrame member function - -* Description: -* This function returns a pointer to a new Mapping which transforms -* positions in the supplied DSBSpecFrame to the corresponding -* topocentric frequency values in Hz (or the inverse of this). - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* forward -* If zero, the calcuated Mapping is inverted before being returned. -* method -* Pointer to a null-terminated string containing the name of the -* public invoking method. This is only used in the construction of -* error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a new Mapping. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *result; /* The returned Mapping */ - AstFrameSet *fs; /* FrameSet connecting tf1 and tf2 */ - AstSpecFrame *tf1; /* SpecFrame corresponding to this DSBSpecFrame */ - AstSpecFrame *tf2; /* Topocentric frequency SpecFrame */ - int template_axis; /* The axis to overlay */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Make a SpecFrame and then overlay the SpecFrame attributes of this - DSBSpecFrame onto the new SpecFrame. This means it inherits the current - values of things like ObsLon and ObsLat. */ - tf1 = astSpecFrame( "", status ); - template_axis = 0; - (*parent_overlay)( (AstFrame *) this, &template_axis, (AstFrame *) tf1, status ); - -/* Copy this new SpecFrame and set its attributes to describe topocentric - frequency in Hz. Ensure that alignment occurs in the topocentric Frame. */ - astSetAlignStdOfRest( tf1, AST__TPSOR); - tf2 = astCopy( tf1 ); - astSetSystem( tf2, AST__FREQ ); - astSetStdOfRest( tf2, AST__TPSOR ); - astSetUnit( tf2, 0, "Hz" ); - -/* Find the Mapping from the spectral system described by this SpecFrame to - topocentric frequency in Hz. */ - fs = astConvert( tf1, tf2, "" ); - if ( astOK ) { - if( !fs ) { - astError( AST__INTER, "%s(%s): Cannot convert DSBCentre " - "value from the supplied system to topocentric frequency " - "(internal AST programming error).", status, method, - astGetClass( this ) ); - } else { - result = astGetMapping( fs, AST__BASE, AST__CURRENT ); - if( !forward ) astInvert( result ); - } - fs = astAnnul( fs ); - } - -/* Free resources */ - tf1 = astAnnul( tf1 ); - tf2 = astAnnul( tf2 ); - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; - -} - -static AstMapping *ToUSBMapping( AstDSBSpecFrame *this, const char *method, int *status ){ -/* -* Name: -* ToUSBMapping - -* Purpose: -* Create a Mapping which transforms a DSBSpecFrame to the upper -* sideband. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* AstMapping *ToUSBMapping( AstDSBSpecFrame *this, const char *method, int *status ) - -* Class Membership: -* DSBSpecFrame member function - -* Description: -* This function returns a pointer to a new Mapping which transforms -* positions in the supplied DSBSpecFrame to the upper sideband. This -* will be a UnitMap if the DSBSpecFrame already represents the upper -* sideband. - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* method -* Pointer to a null-terminated string containing the name of the -* public invoking method. This is only used in the construction of -* error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a new Mapping. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *fmap; /* LSB to USB (topo freq) */ - AstMapping *map1; /* This to USB (topo freq) */ - AstMapping *map2; /* This (LSB) to This (USB) */ - AstMapping *result; /* Pointer to the returned Mapping */ - AstMapping *tmap; /* This to topocentric freq */ - double f_lo; /* Local oscillator freq (topo Hz) */ - double f_in_a; /* First LSB or LO freq */ - double f_in_b; /* Second LSB or LO freq */ - double f_out_a; /* First USB freq */ - double f_out_b; /* Second USB freq */ - int sb; /* SideBand value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the DSBSpecFrame already represents the USB, return a UnitMap.*/ - sb = astGetSideBand( this ); - if( sb == USB ) { - result = (AstMapping *) astUnitMap( 1, "", status ); - -/* If the DSBSpecFrame represents the LSB, or LO offset, create a suitable - WinMap. */ - } else { - -/* Find the Mapping from the spectral system described by this SpecFrame to - topocentric frequency in Hz. */ - tmap = TopoMap( this, 1, method, status ); - -/* Calculate the local oscillator frequency (topocentric in Hertz). */ - f_lo = GetLO( this, "create a Mapping to upper sideband", - "astGetImagFreq", status ); - -/* Create a 1D WinMap which converts f_in to f_out. */ - if( sb == LSB ) { - f_in_a = 0.0; - f_in_b = 2*f_lo; - f_out_a = 2*f_lo; - f_out_b = 0.0; - } else { - f_in_a = 0.0; - f_in_b = -f_lo; - f_out_a = f_lo; - f_out_b = 0.0; - } - - fmap = (AstMapping *) astWinMap( 1, &f_in_a, &f_in_b, &f_out_a, &f_out_b, "", status ); - -/* Construct the Mapping: input to f_in, f_in to f_out, f_out to input */ - map1 = (AstMapping *) astCmpMap( tmap, fmap, 1, "", status ); - astInvert( tmap ); - map2 = (AstMapping *) astCmpMap( map1, tmap, 1, "", status ); - -/* Simplify */ - result = astSimplify( map2 ); - -/* Free resources */ - tmap = astAnnul( tmap ); - fmap = astAnnul( fmap ); - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - } - -/* Return NULL if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; - -} - -static void VerifyAttrs( AstDSBSpecFrame *this, const char *purp, - const char *attrs, const char *method, int *status ) { -/* -* Name: -* VerifyAttrs - -* Purpose: -* Verify that usable attribute values are available. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* void VerifyAttrs( AstDSBSpecFrame *this, const char *purp, -* const char *attrs, const char *method, int *status ) - -* Class Membership: -* DSBSpecFrame member function - -* Description: -* This function tests each attribute listed in "attrs". It returns -* without action if 1) an explicit value has been set for each attribute -* or 2) the UseDefs attribute of the supplied DSBSpecFrame is non-zero. -* -* If UseDefs is zero (indicating that default values should not be -* used for attributes), and any of the named attributes does not have -* an explicitly set value, then an error is reported. - -* Parameters: -* this -* Pointer to the DSBSpecFrame. -* purp -* Pointer to a text string containing a message which will be -* included in any error report. This shouldindicate the purpose -* for which the attribute value is required. -* attrs -* A string holding a space separated list of attribute names. -* method -* A string holding the name of the calling method for use in error -* messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - const char *a; - const char *desc; - const char *p; - int len; - int set; - int state; - -/* Check inherited status */ - if( !astOK ) return; - -/* If the DSBSpecFrame has a non-zero value for its UseDefs attribute, then - all attributes are assumed to have usable values, since the defaults - will be used if no explicit value has been set. So we only need to do - any checks if UseDefs is zero. */ - if( !astGetUseDefs( this ) ) { - -/* Initialise variables to avoid compiler warnings. */ - a = NULL; - desc = NULL; - len = 0; - set = 0; - -/* Loop round the "attrs" string identifying the start and length of each - non-blank word in the string. */ - state = 0; - p = attrs; - while( 1 ) { - if( state == 0 ) { - if( !isspace( *p ) ) { - a = p; - len = 1; - state = 1; - } - } else { - if( isspace( *p ) || !*p ) { - -/* The end of a word has just been reached. Compare it to each known - attribute value. Get a flag indicating if the attribute has a set - value, and a string describing the attribute.*/ - if( len > 0 ) { - - if( !strncmp( "DSBCentre", a, len ) ) { - set = astTestDSBCentre( this ); - desc = "central position of interest"; - - } else if( !strncmp( "IF", a, len ) ) { - set = astTestIF( this ); - desc = "intermediate frequency"; - - } else { - astError( AST__INTER, "VerifyAttrs(DSBSpecFrame): " - "Unknown attribute name \"%.*s\" supplied (AST " - "internal programming error).", status, len, a ); - } - -/* If the attribute does not have a set value, report an error. */ - if( !set && astOK ) { - astError( AST__NOVAL, "%s(%s): Cannot %s.", status, method, - astGetClass( this ), purp ); - astError( AST__NOVAL, "No value has been set for " - "the AST \"%.*s\" attribute (%s).", status, len, a, - desc ); - } - -/* Continue the word search algorithm. */ - } - len = 0; - state = 0; - } else { - len++; - } - } - if( !*(p++) ) break; - } - } -} - - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* ImagFreq - -* Purpose: -* The image sideband equivalent of the rest frequency. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point, read-only. - -* Description: -* This is a read-only attribute giving the frequency which -* corresponds to the rest frequency but is in the opposite sideband. - -* The value is calculated by first transforming the rest frequency -* (given by the RestFreq attribute) from the standard of rest of the -* source (given by the SourceVel and SourceVRF attributes) to the -* standard of rest of the observer (i.e. the topocentric standard of -* rest). The resulting topocentric frequency is assumed to be in the -* same sideband as the value given for the DSBCentre attribute (the -* "observed" sideband), and is transformed to the other sideband (the -* "image" sideband). The new frequency is converted back to the standard -* of rest of the source, and the resulting value is returned as the -* attribute value, in units of GHz. - -* Applicability: -* DSBSpecFrame -* All DSBSpecFrames have this attribute. - -*att-- -*/ - - -/* -*att++ -* Name: -* DSBCentre - -* Purpose: -* The central position of interest in a dual sideband spectrum. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the central position of interest in a dual -* sideband spectrum. Its sole use is to determine the local oscillator -* frequency (the frequency which marks the boundary between the lower -* and upper sidebands). See the description of the IF (intermediate -* frequency) attribute for details of how the local oscillator frequency -* is calculated. The sideband containing this central position is -* referred to as the "observed" sideband, and the other sideband as -* the "image" sideband. -* -* The value is accessed as a position in the spectral system -* represented by the SpecFrame attributes inherited by this class, but -* is stored internally as topocentric frequency. Thus, if the System -* attribute of the DSBSpecFrame is set to "VRAD", the Unit attribute -* set to "m/s" and the StdOfRest attribute set to "LSRK", then values -* for the DSBCentre attribute should be supplied as radio velocity in -* units of "m/s" relative to the kinematic LSR (alternative units may -* be used by appending a suitable units string to the end of the value). -* This value is then converted to topocentric frequency and stored. If -* (say) the Unit attribute is subsequently changed to "km/s" before -* retrieving the current value of the DSBCentre attribute, the stored -* topocentric frequency will be converted back to LSRK radio velocity, -* this time in units of "km/s", before being returned. -* -* The default value for this attribute is 30 GHz. - -* Applicability: -* DSBSpecFrame -* All DSBSpecFrames have this attribute. - -* Note: -* - The attributes which define the transformation to or from topocentric -* frequency should be assigned their correct values before accessing -* this attribute. These potentially include System, Unit, StdOfRest, -* ObsLon, ObsLat, ObsAlt, Epoch, RefRA, RefDec and RestFreq. - -*att-- -*/ -/* The central frequency (topocentric frequency in Hz). */ -astMAKE_CLEAR(DSBSpecFrame,DSBCentre,dsbcentre,AST__BAD) -astMAKE_GET(DSBSpecFrame,DSBCentre,double,3.0E10,((this->dsbcentre!=AST__BAD)?this->dsbcentre:3.0E10)) -astMAKE_SET(DSBSpecFrame,DSBCentre,double,dsbcentre,value) -astMAKE_TEST(DSBSpecFrame,DSBCentre,( this->dsbcentre != AST__BAD )) - - -/* -*att++ -* Name: -* IF - -* Purpose: -* The intermediate frequency in a dual sideband spectrum. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the (topocentric) intermediate frequency in -* a dual sideband spectrum. Its sole use is to determine the local -* oscillator (LO) frequency (the frequency which marks the boundary -* between the lower and upper sidebands). The LO frequency is -* equal to the sum of the centre frequency and the intermediate -* frequency. Here, the "centre frequency" is the topocentric -* frequency in Hz corresponding to the current value of the DSBCentre -* attribute. The value of the IF attribute may be positive or -* negative: a positive value results in the LO frequency being above -* the central frequency, whilst a negative IF value results in the LO -* frequency being below the central frequency. The sign of the IF -* attribute value determines the default value for the SideBand -* attribute. -* -* When setting a new value for this attribute, the units in which the -* frequency value is supplied may be indicated by appending a suitable -* string to the end of the formatted value. If the units are not -* specified, then the supplied value is assumed to be in units of GHz. -* For instance, the following strings all result in an IF of 4 GHz being -* used: "4.0", "4.0 GHz", "4.0E9 Hz", etc. -* -* When getting the value of this attribute, the returned value is -* always in units of GHz. The default value for this attribute is 4 GHz. - -* Applicability: -* DSBSpecFrame -* All DSBSpecFrames have this attribute. - -*att-- -*/ -/* The intermediate frequency (topocentric in Hz). */ -astMAKE_CLEAR(DSBSpecFrame,IF,ifr,AST__BAD) -astMAKE_GET(DSBSpecFrame,IF,double,4.0E9,((this->ifr!=AST__BAD)?this->ifr:4.0E9)) -astMAKE_SET(DSBSpecFrame,IF,double,ifr,value) -astMAKE_TEST(DSBSpecFrame,IF,( this->ifr != AST__BAD )) - -/* -*att++ -* Name: -* SideBand - -* Purpose: -* Indicates which sideband a dual sideband spectrum represents. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute indicates whether the DSBSpecFrame currently -* represents its lower or upper sideband, or an offset from the local -* oscillator frequency. When querying the current value, the returned -* string is always one of "usb" (for upper sideband), "lsb" (for lower -* sideband), or "lo" (for offset from the local oscillator frequency). -* When setting a new value, any of the strings "lsb", "usb", "observed", -* "image" or "lo" may be supplied (case insensitive). The "observed" -* sideband is which ever sideband (upper or lower) contains the central -* spectral position given by attribute DSBCentre, and the "image" -* sideband is the other sideband. It is the sign of the IF attribute -* which determines if the observed sideband is the upper or lower -* sideband. The default value for SideBand is the observed sideband. - -* Applicability: -* DSBSpecFrame -* All DSBSpecFrames have this attribute. - -*att-- -*/ -/* Protected access to the SideBand attribute uses BADSB to indicate - "unset". Other negative values mean "LSB", zero means "LO" and - positive values mean "USB". */ -astMAKE_CLEAR(DSBSpecFrame,SideBand,sideband,BADSB) -astMAKE_SET(DSBSpecFrame,SideBand,int,sideband,((value<0)?LSB:((value==0)?LO:USB))) -astMAKE_TEST(DSBSpecFrame,SideBand,( this->sideband != BADSB )) -astMAKE_GET(DSBSpecFrame,SideBand,int,USB,(this->sideband == BADSB ? ((astGetIF( this )>0)?LSB:USB):this->sideband)) - -/* -*att++ -* Name: -* AlignSideBand - -* Purpose: -* Should the SideBand attribute be taken into account when aligning -* this DSBSpecFrame with another DSBSpecFrame? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls how a DSBSpecFrame behaves when an attempt -* is made to align it with another DSBSpecFrame using -c astFindFrame or astConvert. -f AST_FINDFRAME or AST_CONVERT. -* If both DSBSpecFrames have a non-zero value for AlignSideBand, the -* value of the SideBand attribute in each DSBSpecFrame is used so that -* alignment occurs between sidebands. That is, if one DSBSpecFrame -* represents USB and the other represents LSB then -c astFindFrame and astConvert -f AST_FINDFRAME and AST_CONVERT -* will recognise that the DSBSpecFrames represent different sidebands -* and will take this into account when constructing the Mapping that -* maps positions in one DSBSpecFrame into the other. If AlignSideBand -* in either DSBSpecFrame is set to zero, then the values of the SideBand -* attributes are ignored. In the above example, this would result in a -* frequency in the first DSBSpecFrame being mapped onto the same -* frequency in the second DSBSpecFrame, even though those frequencies -* refer to different sidebands. In other words, if either AlignSideBand -* attribute is zero, then the two DSBSpecFrames aligns like basic -* SpecFrames. The default value for AlignSideBand is zero. -* -c When astFindFrame or astConvert -f When AST_FINDFRAME or AST_CONVERT -* is used on two DSBSpecFrames (potentially describing different spectral -* coordinate systems and/or sidebands), it returns a Mapping which can be -* used to transform a position in one DSBSpecFrame into the corresponding -* position in the other. The Mapping is made up of the following steps in -* the indicated order: -* -* - If both DSBSpecFrames have a value of 1 for the AlignSideBand -* attribute, map values from the target's current sideband (given by its -* SideBand attribute) to the observed sideband (whether USB or LSB). If -* the target already represents the observed sideband, this step will -* leave the values unchanged. If either of the two DSBSpecFrames have a -* value of zero for its AlignSideBand attribute, then this step is omitted. -* -* - Map the values from the spectral system of the target to the spectral -* system of the template. This Mapping takes into account all the -* inherited SpecFrame attributes such as System, StdOfRest, Unit, etc. -* -* - If both DSBSpecFrames have a value of 1 for the AlignSideBand -* attribute, map values from the result's observed sideband to the -* result's current sideband (given by its SideBand attribute). If the -* result already represents the observed sideband, this step will leave -* the values unchanged. If either of the two DSBSpecFrames have a value -* of zero for its AlignSideBand attribute, then this step is omitted. - -* Applicability: -* DSBSpecFrame -* All DSBSpecFrames have this attribute. - -*att-- -*/ -/* The AlignSideBand value has a value of -1 when not set yielding a - default of 0. */ -astMAKE_TEST(DSBSpecFrame,AlignSideBand,( this->alignsideband != -1 )) -astMAKE_CLEAR(DSBSpecFrame,AlignSideBand,alignsideband,-1) -astMAKE_GET(DSBSpecFrame,AlignSideBand,int,-1,((this->alignsideband==-1)?0:this->alignsideband) ) -astMAKE_SET(DSBSpecFrame,AlignSideBand,int,alignsideband,(value?1:0)) - -/* Copy constructor. */ -/* ----------------- */ -/* None needed */ - -/* Destructor. */ -/* ----------- */ -/* None needed */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for DSBSpecFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the DSBSpecFrame class to an output Channel. - -* Parameters: -* this -* Pointer to the DSBSpecFrame whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstDSBSpecFrame *this; /* Pointer to the DSBSpecFrame structure */ - const char *cval; /* Attribute value */ - const char *comm; /* Attribute comment */ - double dval; /* Attribute value */ - int ival; /* Attribute value */ - int set; /* Is attribute set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the DSBSpecFrame structure. */ - this = (AstDSBSpecFrame *) this_object; - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* DSBCentre */ -/* --------- */ - set = TestDSBCentre( this, status ); - dval = set ? GetDSBCentre( this, status ) : astGetDSBCentre( this ); - astWriteDouble( channel, "DSBCen", set, 1, dval, "Central frequency (Hz topo)" ); - -/* IF */ -/* -- */ - set = TestIF( this, status ); - dval = set ? GetIF( this, status ) : astGetIF( this ); - astWriteDouble( channel, "IF", set, 1, dval, "Intermediate frequency (Hz)" ); - -/* SideBand */ -/* -------- */ - set = TestSideBand( this, status ); - ival = set ? GetSideBand( this, status ) : astGetSideBand( this ); - if( ival == LSB ) { - cval = "LSB"; - comm = "Represents lower sideband"; - - } else if( ival == LO ) { - cval = "LO"; - comm = "Represents offset from LO frequency"; - - } else { - cval = "USB"; - comm = "Represents upper sideband"; - } - astWriteString( channel, "SideBn", set, 1, cval, comm ); - -/* AlignSideBand */ -/* ------------- */ - set = TestAlignSideBand( this, status ); - ival = set ? GetAlignSideBand( this, status ) : astGetAlignSideBand( this ); - astWriteInt( channel, "AlSdBn", set, 1, ival, "Align sidebands?" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsADSBSpecFrame and astCheckDSBSpecFrame functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(DSBSpecFrame,SpecFrame) -astMAKE_CHECK(DSBSpecFrame) - -AstDSBSpecFrame *astDSBSpecFrame_( const char *options, int *status, ...) { -/* -*++ -* Name: -c astDSBSpecFrame -f AST_DSBSPECFRAME - -* Purpose: -* Create a DSBSpecFrame. - -* Type: -* Public function. - -* Synopsis: -c #include "dsbspecframe.h" -c AstDSBSpecFrame *astDSBSpecFrame( const char *options, ... ) -f RESULT = AST_DSBSPECFRAME( OPTIONS, STATUS ) - -* Class Membership: -* DSBSpecFrame constructor. - -* Description: -* This function creates a new DSBSpecFrame and optionally initialises its -* attributes. -* -* A DSBSpecFrame is a specialised form of SpecFrame which represents -* positions in a spectrum obtained using a dual sideband instrument. -* Such an instrument produces a spectrum in which each point contains -* contributions from two distinctly different frequencies, one from -* the "lower side band" (LSB) and one from the "upper side band" (USB). -* Corresponding LSB and USB frequencies are connected by the fact -* that they are an equal distance on either side of a fixed central -* frequency known as the "Local Oscillator" (LO) frequency. -* -* When quoting a position within such a spectrum, it is necessary to -* indicate whether the quoted position is the USB position or the -* corresponding LSB position. The SideBand attribute provides this -* indication. Another option that the SideBand attribute provides is -* to represent a spectral position by its topocentric offset from the -* LO frequency. -* -* In practice, the LO frequency is specified by giving the distance -* from the LO frequency to some "central" spectral position. Typically -* this central position is that of some interesting spectral feature. -* The distance from this central position to the LO frequency is known -* as the "intermediate frequency" (IF). The value supplied for IF can -* be a signed value in order to indicate whether the LO frequency is -* above or below the central position. - -* Parameters: -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new DSBSpecFrame. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new DSBSpecFrame. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astDSBSpecFrame() -f AST_DSBSPECFRAME = INTEGER -* A pointer to the new DSBSpecFrame. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstDSBSpecFrame *new; /* Pointer to new DSBSpecFrame */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the DSBSpecFrame, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitDSBSpecFrame( NULL, sizeof( AstDSBSpecFrame ), !class_init, &class_vtab, - "DSBSpecFrame" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new DSBSpecFrame's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new DSBSpecFrame. */ - return new; -} - -AstDSBSpecFrame *astDSBSpecFrameId_( const char *options, ... ) { -/* -* Name: -* astDSBSpecFrameId_ - -* Purpose: -* Create a DSBSpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "dsbspecframe.h" -* AstDSBSpecFrame *astDSBSpecFrameId_( const char *options, ... ) - -* Class Membership: -* DSBSpecFrame constructor. - -* Description: -* This function implements the external (public) interface to the -* astDSBSpecFrame constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astDSBSpecFrame_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astDSBSpecFrame_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astDSBSpecFrame_. - -* Returned Value: -* The ID value associated with the new DSBSpecFrame. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstDSBSpecFrame *new; /* Pointer to new DSBSpecFrame */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the DSBSpecFrame, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitDSBSpecFrame( NULL, sizeof( AstDSBSpecFrame ), !class_init, &class_vtab, - "DSBSpecFrame" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new DSBSpecFrame's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new DSBSpecFrame. */ - return astMakeId( new ); -} - -AstDSBSpecFrame *astInitDSBSpecFrame_( void *mem, size_t size, int init, - AstDSBSpecFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitDSBSpecFrame - -* Purpose: -* Initialise a DSBSpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "dsbspecframe.h" -* AstDSBSpecFrame *astInitDSBSpecFrame( void *mem, size_t size, int init, -* AstDSBSpecFrameVtab *vtab, const char *name ) - -* Class Membership: -* DSBSpecFrame initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new DSBSpecFrame object. It allocates memory (if necessary) to accommodate -* the DSBSpecFrame plus any additional data associated with the derived class. -* It then initialises a DSBSpecFrame structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a DSBSpecFrame at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the DSBSpecFrame is to be initialised. -* This must be of sufficient size to accommodate the DSBSpecFrame data -* (sizeof(DSBSpecFrame)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the DSBSpecFrame (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the DSBSpecFrame -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the DSBSpecFrame's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new DSBSpecFrame. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). - -* Returned Value: -* A pointer to the new DSBSpecFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstDSBSpecFrame *new; /* Pointer to new DSBSpecFrame */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitDSBSpecFrameVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a SpecFrame structure (the parent class) as the first component - within the DSBSpecFrame structure, allocating memory if necessary. Specify that - the SpecFrame should be defined in both the forward and inverse directions. */ - new = (AstDSBSpecFrame *) astInitSpecFrame( mem, size, 0, - (AstSpecFrameVtab *) vtab, name ); - if ( astOK ) { - -/* Initialise the DSBSpecFrame data. */ -/* --------------------------------- */ - new->dsbcentre = AST__BAD; - new->ifr = AST__BAD; - new->sideband = BADSB; - new->alignsideband = -1; - -/* If an error occurred, clean up by deleting the new DSBSpecFrame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new DSBSpecFrame. */ - return new; -} - -AstDSBSpecFrame *astLoadDSBSpecFrame_( void *mem, size_t size, - AstDSBSpecFrameVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadDSBSpecFrame - -* Purpose: -* Load a DSBSpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "dsbspecframe.h" -* AstDSBSpecFrame *astLoadDSBSpecFrame( void *mem, size_t size, -* AstDSBSpecFrameVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* DSBSpecFrame loader. - -* Description: -* This function is provided to load a new DSBSpecFrame using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* DSBSpecFrame structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a DSBSpecFrame at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the DSBSpecFrame is to be -* loaded. This must be of sufficient size to accommodate the -* DSBSpecFrame data (sizeof(DSBSpecFrame)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the DSBSpecFrame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the DSBSpecFrame structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstDSBSpecFrame) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new DSBSpecFrame. If this is NULL, a pointer -* to the (static) virtual function table for the DSBSpecFrame class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "DSBSpecFrame" is used instead. - -* Returned Value: -* A pointer to the new DSBSpecFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants. */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstDSBSpecFrame *new; /* Pointer to the new DSBSpecFrame */ - char *text; /* Pointer to string value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this DSBSpecFrame. In this case the - DSBSpecFrame belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstDSBSpecFrame ); - vtab = &class_vtab; - name = "DSBSpecFrame"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitDSBSpecFrameVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built DSBSpecFrame. */ - new = astLoadSpecFrame( mem, size, (AstSpecFrameVtab *) vtab, name, - channel ); - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "DSBSpecFrame" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* DSBCentre */ -/* --------- */ - new->dsbcentre = astReadDouble( channel, "dsbcen", AST__BAD ); - if ( TestDSBCentre( new, status ) ) SetDSBCentre( new, new->dsbcentre, status ); - -/* IF */ -/* -- */ - new->ifr = astReadDouble( channel, "if", AST__BAD ); - if ( TestIF( new, status ) ) SetIF( new, new->ifr, status ); - -/* SideBand */ -/* -------- */ - text = astReadString( channel, "sidebn", " " ); - if( astOK ) { - if( !strcmp( text, " " ) ) { - new->sideband = BADSB; - } else if( !strcmp( text, "USB" ) ) { - new->sideband = USB; - } else if( !strcmp( text, "LSB" ) ) { - new->sideband = LSB; - } else if( !strcmp( text, "LO" ) ) { - new->sideband = LO; - } else { - astError( AST__ATTIN, "astRead(%s): Invalid SideBand description " - "\"%s\".", status, astGetClass( channel ), text ); - } - if ( TestSideBand( new, status ) ) SetSideBand( new, new->sideband, status ); - text = astFree( text ); - } - -/* AlignSideBand */ -/* ------------- */ - new->alignsideband = astReadInt( channel, "alsdbn", -1 ); - if( TestAlignSideBand( new, status ) ) SetAlignSideBand( new, new->alignsideband, status ); - -/* If an error occurred, clean up by deleting the new DSBSpecFrame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new DSBSpecFrame pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -double astGetImagFreq_( AstDSBSpecFrame *this, int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,DSBSpecFrame,GetImagFreq))( this, status ); -} - - - - - - diff --git a/ast/dsbspecframe.h b/ast/dsbspecframe.h deleted file mode 100644 index 87617f5..0000000 --- a/ast/dsbspecframe.h +++ /dev/null @@ -1,298 +0,0 @@ -#if !defined( DSBSPECFRAME_INCLUDED ) /* Include this file only once */ -#define DSBSPECFRAME_INCLUDED -/* -*+ -* Name: -* dsbspecframe.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the DSBSpecFrame class. - -* Invocation: -* #include "dsbspecframe.h" - -* Description: -* This include file defines the interface to the DSBSpecFrame class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. - -* Inheritance: -* The DSBSpecFrame class inherits from the SpecFrame class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 5-AUG-2004 (DSB): -* Original version. -* 27-OCT-2006 (DSB): -* Added AlignSideBand. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "specframe.h" /* Spectral coord systems (parent class) */ - -/* C header files. */ -/* --------------- */ - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* DSBSpecFrame structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstDSBSpecFrame { - -/* Attributes inherited from the parent class. */ - AstSpecFrame specframe; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double dsbcentre; /* Centre frequency */ - double ifr; /* Intermediate frequency */ - int sideband; /* Current sideband */ - int alignsideband; /* Aligns sidebands? */ - -} AstDSBSpecFrame; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstDSBSpecFrameVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstSpecFrameVtab specframe_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - double (* GetDSBCentre)( AstDSBSpecFrame *, int * ); - int (* TestDSBCentre)( AstDSBSpecFrame *, int * ); - void (* ClearDSBCentre)( AstDSBSpecFrame *, int * ); - void (* SetDSBCentre)( AstDSBSpecFrame *, double, int * ); - - double (* GetIF)( AstDSBSpecFrame *, int * ); - int (* TestIF)( AstDSBSpecFrame *, int * ); - void (* ClearIF)( AstDSBSpecFrame *, int * ); - void (* SetIF)( AstDSBSpecFrame *, double, int * ); - - int (* GetSideBand)( AstDSBSpecFrame *, int * ); - int (* TestSideBand)( AstDSBSpecFrame *, int * ); - void (* ClearSideBand)( AstDSBSpecFrame *, int * ); - void (* SetSideBand)( AstDSBSpecFrame *, int, int * ); - - int (* GetAlignSideBand)( AstDSBSpecFrame *, int * ); - int (* TestAlignSideBand)( AstDSBSpecFrame *, int * ); - void (* ClearAlignSideBand)( AstDSBSpecFrame *, int * ); - void (* SetAlignSideBand)( AstDSBSpecFrame *, int, int * ); - - double (* GetImagFreq)( AstDSBSpecFrame *, int * ); - -} AstDSBSpecFrameVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstDSBSpecFrameGlobals { - AstDSBSpecFrameVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 101 ]; - char GetLabel_Buff[ 101 ]; -} AstDSBSpecFrameGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(DSBSpecFrame) /* Check class membership */ -astPROTO_ISA(DSBSpecFrame) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstDSBSpecFrame *astDSBSpecFrame_( const char *, int *, ...); -#else -AstDSBSpecFrame *astDSBSpecFrameId_( const char *, ... )__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstDSBSpecFrame *astInitDSBSpecFrame_( void *, size_t, int, AstDSBSpecFrameVtab *, - const char *, int * ); - -/* Vtab initialiser. */ -void astInitDSBSpecFrameVtab_( AstDSBSpecFrameVtab *, const char *, int * ); - -/* Loader. */ -AstDSBSpecFrame *astLoadDSBSpecFrame_( void *, size_t, AstDSBSpecFrameVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitDSBSpecFrameGlobals_( AstDSBSpecFrameGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ - double astGetDSBCentre_( AstDSBSpecFrame *, int * ); - int astTestDSBCentre_( AstDSBSpecFrame *, int * ); - void astClearDSBCentre_( AstDSBSpecFrame *, int * ); - void astSetDSBCentre_( AstDSBSpecFrame *, double, int * ); - - double astGetIF_( AstDSBSpecFrame *, int * ); - int astTestIF_( AstDSBSpecFrame *, int * ); - void astClearIF_( AstDSBSpecFrame *, int * ); - void astSetIF_( AstDSBSpecFrame *, double, int * ); - - int astGetSideBand_( AstDSBSpecFrame *, int * ); - int astTestSideBand_( AstDSBSpecFrame *, int * ); - void astClearSideBand_( AstDSBSpecFrame *, int * ); - void astSetSideBand_( AstDSBSpecFrame *, int, int * ); - - int astGetAlignSideBand_( AstDSBSpecFrame *, int * ); - int astTestAlignSideBand_( AstDSBSpecFrame *, int * ); - void astClearAlignSideBand_( AstDSBSpecFrame *, int * ); - void astSetAlignSideBand_( AstDSBSpecFrame *, int, int * ); - - double astGetImagFreq_( AstDSBSpecFrame *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckDSBSpecFrame(this) astINVOKE_CHECK(DSBSpecFrame,this,0) -#define astVerifyDSBSpecFrame(this) astINVOKE_CHECK(DSBSpecFrame,this,1) - -/* Test class membership. */ -#define astIsADSBSpecFrame(this) astINVOKE_ISA(DSBSpecFrame,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astDSBSpecFrame astINVOKE(F,astDSBSpecFrame_) -#else -#define astDSBSpecFrame astINVOKE(F,astDSBSpecFrameId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define \ -astInitDSBSpecFrame(mem,size,init,vtab,name) \ -astINVOKE(O,astInitDSBSpecFrame_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitDSBSpecFrameVtab(vtab,name) astINVOKE(V,astInitDSBSpecFrameVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadDSBSpecFrame(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadDSBSpecFrame_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckDSBSpecFrame to validate DSBSpecFrame pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ - -#define astGetDSBCentre(this) \ -astINVOKE(V,astGetDSBCentre_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astTestDSBCentre(this) \ -astINVOKE(V,astTestDSBCentre_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astClearDSBCentre(this) \ -astINVOKE(V,astClearDSBCentre_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astSetDSBCentre(this,val) \ -astINVOKE(V,astSetDSBCentre_(astCheckDSBSpecFrame(this),val,STATUS_PTR)) - -#define astGetIF(this) \ -astINVOKE(V,astGetIF_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astTestIF(this) \ -astINVOKE(V,astTestIF_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astClearIF(this) \ -astINVOKE(V,astClearIF_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astSetIF(this,val) \ -astINVOKE(V,astSetIF_(astCheckDSBSpecFrame(this),val,STATUS_PTR)) - -#define astGetSideBand(this) \ -astINVOKE(V,astGetSideBand_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astTestSideBand(this) \ -astINVOKE(V,astTestSideBand_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astClearSideBand(this) \ -astINVOKE(V,astClearSideBand_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astSetSideBand(this,val) \ -astINVOKE(V,astSetSideBand_(astCheckDSBSpecFrame(this),val,STATUS_PTR)) - -#define astGetAlignSideBand(this) \ -astINVOKE(V,astGetAlignSideBand_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astTestAlignSideBand(this) \ -astINVOKE(V,astTestAlignSideBand_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astClearAlignSideBand(this) \ -astINVOKE(V,astClearAlignSideBand_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#define astSetAlignSideBand(this,val) \ -astINVOKE(V,astSetAlignSideBand_(astCheckDSBSpecFrame(this),val,STATUS_PTR)) - -#define astGetImagFreq(this) \ -astINVOKE(V,astGetImagFreq_(astCheckDSBSpecFrame(this),STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/dssmap.c b/ast/dssmap.c deleted file mode 100644 index b869d57..0000000 --- a/ast/dssmap.c +++ /dev/null @@ -1,2283 +0,0 @@ -/* -*class++ -* Name: -* DssMap - -* Purpose: -* Map points using a Digitised Sky Survey plate solution. - -* Constructor Function: -* The DssMap class does not have a constructor function. A DssMap -* is created only as a by-product of reading a FrameSet (using -c astRead) from a FitsChan which contains FITS header cards -f AST_READ) from a FitsChan which contains FITS header cards -* describing a DSS plate solution, and whose Encoding attribute is -* set to "DSS". The result of such a read, if successful, is a -* FrameSet whose base and current Frames are related by a DssMap. - -* Description: -* The DssMap class implements a Mapping which transforms between -* 2-dimensional pixel coordinates and an equatorial sky coordinate -* system (right ascension and declination) using a Digitised Sky -* Survey (DSS) astrometric plate solution. -* -* The input coordinates are pixel numbers along the first and -* second dimensions of an image, where the centre of the first -* pixel is located at (1,1) and the spacing between pixel centres -* is unity. -* -* The output coordinates are right ascension and declination in -* radians. The celestial coordinate system used (FK4, FK5, etc.) -* is unspecified, and will usually be indicated by appropriate -* keywords in a FITS header. - -* Inheritance: -* The DssMap class inherits from the Mapping class. - -* Attributes: -* The DssMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c The DssMap class does not define any new functions beyond those -f The DssMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . -* (except for code supplied by Doug Mink, as noted in this file) - -* Authors: -* DSB: D.S. Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink, RAL) - -* History: -* 18-FEB-1997 (DSB): -* Original version. -* 30-JUN-1997 (DSB): -* astDssFits and astDssMap made protected instead of public. -* 15-JUL-1997 (RFWS): -* Tidied public prologues. -* 5-SEP-197 (RFWS): -* Added prototypes for platepos and platepix. -* 4-NOV-1997 (DSB): -* o A copy of the supplied FitsChan is no longer stored inside -* the DssMap. The FitsChan returned by DssFits is now derived from -* the wcs information stored in the SAOimage "WorldCoor" structure -* (stored within the DssMap), and only contains the keywords -* necessary to reconstruct the DssMap. -* o The external representation of a DssMap is now stored in a set -* of scalar values, rather than a FitsChan. -* 22-DEC-1997 (DSB): -* Bug fixed in MapMerge which caused a core dump when a -* DssMap/WinMap combination is succesfully simplified. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitDssMapVtab -* method. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 10-MAY-2006 (DSB): -* Override astEqual. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS DssMap - -/* Macro which returns the nearest integer to a given floating point - value. */ -#define NINT(x) (int)((x)+(((x)>0.0)?0.5:-0.5)) - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "memory.h" /* Memory allocation facilities */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "fitschan.h" /* Manipulation of FITS header cards */ -#include "wcsmap.h" /* Degrees/radians conversion factors */ -#include "winmap.h" /* Shift and scale mappings */ -#include "dssmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(DssMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(DssMap,Class_Init) -#define class_vtab astGLOBAL(DssMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstDssMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstFitsChan *DssFits( AstDssMap *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int platepix( double, double, struct WorldCoor *, double *, double * ); -static int platepos( double, double, struct WorldCoor *, double *, double * ); -static struct WorldCoor *BuildWcs( AstFitsChan *, const char *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *obj, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static int Equal( AstObject *, AstObject *, int * ); - -static int GetObjSize( AstObject *, int * ); -/* Member functions. */ -/* ================= */ -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two DssMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "dssmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* DssMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two DssMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a DssMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the DssMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstDssMap *that; - AstDssMap *this; - int i; - int nin; - int nout; - int result; - struct WorldCoor *this_wcs; - struct WorldCoor *that_wcs; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two DssMap structures. */ - this = (AstDssMap *) this_object; - that = (AstDssMap *) that_object; - -/* Check the second object is a DssMap. We know the first is a - DssMap since we have arrived at this implementation of the virtual - function. */ - if( astIsADssMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two DssMaps differ, it may still be possible - for them to be equivalent. First compare the DssMaps if their Invert - flags are the same. In this case all the attributes of the two DssMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - - this_wcs = ( struct WorldCoor *) this->wcs; - that_wcs = ( struct WorldCoor *) that->wcs; - - if( this_wcs->x_pixel_offset == that_wcs->x_pixel_offset && - this_wcs->y_pixel_offset == that_wcs->y_pixel_offset && - this_wcs->ppo_coeff[2] == that_wcs->ppo_coeff[2] && - this_wcs->ppo_coeff[5] == that_wcs->ppo_coeff[5] && - this_wcs->x_pixel_size == that_wcs->x_pixel_size && - this_wcs->y_pixel_size == that_wcs->y_pixel_size && - this_wcs->plate_dec == that_wcs->plate_dec && - this_wcs->plate_ra == that_wcs->plate_ra ) { - - result = 1; - for( i = 0; i < 13; i++ ) { - if( this_wcs->amd_x_coeff[i] != that_wcs->amd_x_coeff[i] || - this_wcs->amd_y_coeff[i] != that_wcs->amd_y_coeff[i] ) { - result = 0; - break; - } - } - - } - -/* If the Invert flags for the two DssMaps differ, the attributes of the two - DssMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a DssMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "dssmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* DssMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied DssMap, -* in bytes. - -* Parameters: -* this -* Pointer to the DssMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstDssMap *this; /* Pointer to DssMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the DssMap structure. */ - this = (AstDssMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astTSizeOf( this->wcs ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - - -static struct WorldCoor *BuildWcs( AstFitsChan *fits, const char *method, - const char *class, int *status ) { -/* -* Name: -* BuildWcs - -* Purpose: -* Copy DSS plate fit information from a FitsChan to a SAOimage -* WorldCoor structure. - -* Type: -* Private function. - -* Synopsis: -* #include "dssmap.h" -* struct WorldCoor *BuildWcs( AstFitsChan *fits, const char *method, -* const char *class ) - -* Class Membership: -* DssMap member function. - -* Description: -* This creates a WorldCoor structure and copies the required data -* from the supplied FitsChan into the new WorldCoor structure. Note, -* only those components of the WorldCoor structure which are needed to -* transform between pixel and sky coordinates are initialised in the -* returned structure. - -* Parameters: -* fits -* Pointer to the FitsChan containing the FITS header describing -* the DSS plate fit. -* method -* The calling method (for error messages). -* class -* The object class (for error messages). - -* Returned Value: -* A pointer to the new WorldCoor structure. This should be freed -* using astFree when no longer needed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or -* if this function should fail for any reason. - -*/ - -/* Local Variables: */ - char name_buff[ 10 ]; /* Buffer for keyword name */ - char *name; /* Pointer to jeyword name string */ - char *ckeyval; /* Pointer to string keyword value */ - struct WorldCoor *ret; /* Pointer to the returned structure */ - double rah,ram,ras; /* Centre RA hours, minutes and seconds */ - double dsign; /* Sign of centre dec */ - double decd,decm,decs; /* Centre Dec degrees, minutes, seconds */ - double dec_deg; /* Centre Dec in degrees */ - double ra_hours; /* Centre RA in hours */ - int i; /* Coefficient index */ - -/* Check the local error status. */ - if ( !astOK ) return NULL; - -/* Get memory to hold the returned structure. */ - ret = (struct WorldCoor *) astMalloc( sizeof( struct WorldCoor ) ); - -/* Check the memory can be used. */ - if( astOK ){ - -/* The following code is based on the "wcsinit" function in SAOimage file - wcs.c. Note, only the values needed in the platepos and platepix - functions are set up. The FITS keywords are accessed in the order in - which they are usually stored in a FITS file. This will cut down the - time spent searching for keywords. Report an error if any required - keyword is not found. */ - -/* Plate center RA */ - rah = 0.0; - ram = 0.0; - ras = 0.0; - - name = "PLTRAH"; - if( !astGetFitsF( fits, name, &rah ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - - name = "PLTRAM"; - if( !astGetFitsF( fits, name, &ram ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - - name = "PLTRAS"; - if( !astGetFitsF( fits, name, &ras ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - - ra_hours = rah + (ram / (double)60.0) + (ras / (double)3600.0); - ret->plate_ra = AST__DD2R*15.0*ra_hours; - - -/* Plate center Dec */ - name = "PLTDECSN"; - if( !astGetFitsS( fits, name, &ckeyval ) && astOK ){ - dsign = 1.0; - - } else { - if( *ckeyval == '-' ){ - dsign = -1.0; - } else { - dsign = 1.0; - } - - } - - decd = 0.0; - decm = 0.0; - decs = 0.0; - - name = "PLTDECD"; - if( !astGetFitsF( fits, name, &decd ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - - name = "PLTDECM"; - if( !astGetFitsF( fits, name, &decm ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - - name = "PLTDECS"; - if( !astGetFitsF( fits, name, &decs ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - - dec_deg = dsign * (decd+(decm/(double)60.0)+(decs/(double)3600.0)); - ret->plate_dec = AST__DD2R*dec_deg; - -/* Plate Scale arcsec per mm */ - name = "PLTSCALE"; - if( !astGetFitsF( fits, name, &ret->plate_scale ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - -/* X and Y corners (in pixels) */ - name = "CNPIX1"; - if( !astGetFitsF( fits, name, &ret->x_pixel_offset ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - - name = "CNPIX2"; - if( !astGetFitsF( fits, name, &ret->y_pixel_offset ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - -/* X and Y pixel sizes (microns). */ - name = "XPIXELSZ"; - if( !astGetFitsF( fits, name, &ret->x_pixel_size ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - - name = "YPIXELSZ"; - if( !astGetFitsF( fits, name, &ret->y_pixel_size ) && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied for the " - "FITS keyword '%s'.", status, method, class, name ); - } - -/* Orientation Coefficients. Only report an error if PPO3 or PPO6 are - missing (these are the only two which are actually used). Assume a - value of zero for any of the others which are missing. */ - name = name_buff; - for ( i = 0; i < 6; i++ ) { - sprintf( name_buff, "PPO%d", i + 1 ); - if( !astGetFitsF( fits, name, &ret->ppo_coeff[i] ) ) { - ret->ppo_coeff[i] = 0.0; - if( ( i == 2 || i == 5 ) && astOK ) { - astError( AST__BDFTS, "%s(%s): No value has been supplied " - "for the FITS keyword '%s'.", status, method, class, - name ); - break; - } - } - } - -/* Plate solution x and y coefficients. Report an error if any of - coefficients 1 to 14 are missing. Assume a value of zero for any - others which are missing. */ - name = name_buff; - for( i = 0; i < 19; i++ ){ - sprintf( name_buff, "AMDX%d", i + 1 ); - if( !astGetFitsF( fits, name, &ret->amd_x_coeff[i] ) ) { - ret->amd_x_coeff[i] = 0.0; - if( i < 13 && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied " - "for the FITS keyword '%s'.", status, method, class, name ); - break; - } - } - } - - for( i = 0; i < 19; i++ ){ - sprintf( name_buff, "AMDY%d", i + 1 ); - if( !astGetFitsF( fits, name, &ret->amd_y_coeff[i] ) ){ - ret->amd_y_coeff[i] = 0.0; - if( i < 13 && astOK ){ - astError( AST__BDFTS, "%s(%s): No value has been supplied " - "for the FITS keyword '%s'.", status, method, class, name ); - break; - } - } - } - -/* If anything went wrong, free the returned structure. */ - if( !astOK ) ret = (struct WorldCoor *) astFree( (void *) ret ); - } - -/* Return the pointer. */ - return ret; -} - -static AstFitsChan *DssFits( AstDssMap *this, int *status ) { -/* -*+ -* Name: -* astDssFits - -* Purpose: -* Return a pointer to a FitsChan describing a DssMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "dssmap.h" -* AstFitsChan *DssFits( AstDssMap *this ) - -* Class Membership: -* DssMap method. - -* Description: -* This function returns a pointer to a DSS-encoded FitsChan containing -* cards generated from the information stored with the DssMap. The -* keywords contained in the FitsChan are those which would ne needed to -* re-create the DssMap (see astDSSMap). - -* Parameters: -* this -* Pointer to the DssMap. - -* Returned Value: -* astDssFits() -* A pointer to the FitsChan. - -* Notes: -* - The returned pointer should be annuled using astAnnul when no longer -* needed. -* - A value of NULL will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstFitsChan *ret; /* Pointer to the returned FitsChan */ - char *comm; /* Pointer to keyword comment string */ - char *name; /* Pointer to keyword name string */ - char name_buff[ 10 ]; /* Buffer for keyword name */ - double dec; /* Centre Dec in degrees */ - double decd,decm,decs; /* Centre Dec degrees, minutes, seconds */ - double ra; /* Centre RA in hours */ - double rah,ram,ras; /* Centre RA hours, minutes and seconds */ - int i; /* Coefficient index */ - struct WorldCoor *wcs; /* WCS information from the DssMap */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Store a pointer to the WCS information stored in the DSSMap. */ - wcs = (struct WorldCoor *) this->wcs, - -/* Create a new empty FitsChan, using DSS encoding. */ - ret = astFitsChan( NULL, NULL, "Encoding=DSS", status ); - -/* Create the keyword values and stored them in the returned FitsChan... */ - -/* Plate centre RA. */ - ra = wcs->plate_ra/( AST__DD2R*15.0 ); - ra = modf( ra, &rah ); - ra = modf( 60.0*ra, &ram ); - ras = 60.0*ra; - - astSetFitsI( ret, "PLTRAH", NINT( rah ), "Plate centre RA", 0 ); - astSetFitsI( ret, "PLTRAM", NINT( ram ), " ", 0 ); - astSetFitsF( ret, "PLTRAS", ras, " ", 0 ); - -/* Plate centre DEC. */ - dec = wcs->plate_dec/AST__DD2R; - if( dec < 0.0 ) { - dec = -dec; - astSetFitsS( ret, "PLTDECSN", "-", "Plate centre DEC", 0 ); - } else { - astSetFitsS( ret, "PLTDECSN", "+", "Plate centre DEC", 0 ); - } - - dec = modf( dec, &decd ); - dec = modf( 60.0*dec, &decm ); - decs = 60.0*dec; - - astSetFitsI( ret, "PLTDECD", NINT( decd ), " ", 0 ); - astSetFitsI( ret, "PLTDECM", NINT( decm ), " ", 0 ); - astSetFitsF( ret, "PLTDECS", decs, " ", 0 ); - -/* Plate Scale arcsec per mm */ - astSetFitsF( ret, "PLTSCALE", wcs->plate_scale, "Plate Scale arcsec per mm", - 0 ); - -/* X and Y corners (in pixels) */ - astSetFitsI( ret, "CNPIX1", NINT( wcs->x_pixel_offset ), - "X corner (pixels)", 0 ); - astSetFitsI( ret, "CNPIX2", NINT( wcs->y_pixel_offset ), - "Y corner", 0 ); - -/* X and Y pixel sizes (microns). */ - astSetFitsF( ret, "XPIXELSZ", wcs->x_pixel_size, - "X pixel size (microns)", 0 ); - astSetFitsF( ret, "YPIXELSZ", wcs->y_pixel_size, - "Y pixel size (microns)", 0 ); - -/* Orientation Coefficients. */ - name = name_buff; - comm = "Orientation Coefficients"; - for ( i = 0; i < 6; i++ ) { - sprintf( name_buff, "PPO%d", i + 1 ); - astSetFitsF( ret, name, wcs->ppo_coeff[i], comm, 0 ); - comm = " "; - } - -/* Plate solution x and y coefficients. */ - comm = "Plate solution x coefficients"; - for( i = 0; i < 19; i++ ){ - sprintf( name_buff, "AMDX%d", i + 1 ); - astSetFitsF( ret, name, wcs->amd_x_coeff[i], comm, 0 ); - comm = " "; - } - - comm = "Plate solution y coefficients"; - for( i = 0; i < 19; i++ ){ - sprintf( name_buff, "AMDY%d", i + 1 ); - astSetFitsF( ret, name, wcs->amd_y_coeff[i], comm, 0 ); - comm = " "; - } - -/* Return a pointer to the FitsChan. */ - return ret; -} - -void astInitDssMapVtab_( AstDssMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitDssMapVtab - -* Purpose: -* Initialise a virtual function table for a DssMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "dssmap.h" -* void astInitDssMapVtab( AstDssMapVtab *vtab, const char *name ) - -* Class Membership: -* DssMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the DssMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsADssMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->DssFits = DssFits; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - mapping = (AstMappingVtab *) vtab; - object = (AstObjectVtab *) vtab; - - parent_transform = mapping->Transform; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the class dump, copy and delete function. */ - astSetDump( object, Dump, "DssMap", "DSS plate fit mapping" ); - astSetCopy( object, Copy ); - astSetDelete( object, Delete ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a DssMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* DssMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated DssMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated DssMap with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated DssMap which is to be merged with -* its neighbours. This should be a cloned copy of the DssMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* DssMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated DssMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstDssMap *dm; /* Pointer to supplied DssMap */ - AstDssMap *dmnew; /* Pointer to replacement DssMap */ - AstFitsChan *fits; /* FITS headers for replacement DssMap */ - AstFitsChan *fits_dss;/* FITS headers for supplied DssMap */ - AstWinMap *wm; /* Pointer to the adjacent WinMap */ - double *a; /* Pointer to shift terms */ - double *b; /* Pointer to scale terms */ - double cnpix1; /* X pixel origin */ - double cnpix2; /* Y pixel origin */ - double xpixelsz; /* X pixel size */ - double ypixelsz; /* Y pixel size */ - int i; /* Loop counter */ - int ok; /* All FITS keywords found? */ - int old_winv; /* original Invert value for supplied WinMap */ - int result; /* Result value to return */ - int wmi; /* Index of adjacent WinMap in map list */ - struct WorldCoor *wcs;/* Pointer to SAOimage wcs structure */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* The only simplification easily possible is if a WinMap maps the pixel - coordinates prior to a DssMap. If the DssMap has not been inverted, the - WinMap must be applied before the DssMap, otherwise the WinMap must be - applied after the DssMap. */ - if( series ){ - - if( !( *invert_list )[ where ] ){ - wmi = where - 1; - } else { - wmi = where + 1; - } - - if( wmi >= 0 && wmi < *nmap ){ - if( !strcmp( astGetClass( ( *map_list )[ wmi ] ), "WinMap" ) ){ - -/* Temporarily set the Invert attribute of the WinMap to the supplied value. */ - wm = (AstWinMap *) ( *map_list )[ wmi ]; - old_winv = astGetInvert( wm ); - astSetInvert( wm, ( *invert_list )[ wmi ] ); - -/* Get a copy of the scale and shift terms from the WinMap. */ - astWinTerms( wm, &a, &b ); - -/* Check that the scale and shift terms are usable. */ - if( astOK && - a[ 0 ] != AST__BAD && b[ 0 ] != AST__BAD && b[ 0 ] != 0.0 && - a[ 1 ] != AST__BAD && b[ 1 ] != AST__BAD && b[ 1 ] != 0.0 ){ - -/* Get the values of the keywords which define the origin and scales of - the DssMap pixel coordinate system. */ - dm = (AstDssMap *) ( *map_list )[ where ]; - wcs = (struct WorldCoor *) ( dm->wcs ); - - cnpix1 = wcs->x_pixel_offset; - cnpix2 = wcs->y_pixel_offset; - xpixelsz = wcs->x_pixel_size; - ypixelsz = wcs->y_pixel_size; - -/* Calculate new values which take into account the WinMap. */ - if( wmi == where - 1 ){ - xpixelsz *= b[ 0 ]; - ypixelsz *= b[ 1 ]; - cnpix1 = 0.5 + ( cnpix1 + a[ 0 ] - 0.5 )/b[ 0 ]; - cnpix2 = 0.5 + ( cnpix2 + a[ 1 ] - 0.5 )/b[ 1 ]; - - } else { - xpixelsz /= b[ 0 ]; - ypixelsz /= b[ 1 ]; - cnpix1 = b[ 0 ]*( cnpix1 - 0.5 ) - a[ 0 ] + 0.5; - cnpix2 = b[ 1 ]*( cnpix2 - 0.5 ) - a[ 1 ] + 0.5; - } - -/* The CNPIX1 and CNPIX2 keywords are integer keywords. Therefore, we can - only do the simplification if the new values are integer to a good - approximation. We use one hundredth of a pixel. */ - if( fabs( cnpix1 - NINT( cnpix1 ) ) < 0.01 && - fabs( cnpix2 - NINT( cnpix2 ) ) < 0.01 ){ - -/* Get a copy of the FitsChan holding the header cards which define the - DssMap. */ - fits_dss = astDssFits( dm ); - fits = astCopy( fits_dss ); - fits_dss = astAnnul( fits_dss ); - -/* Update the value of each of the changed keywords. */ - ok = 1; - - astClearCard( fits ); - if( astFindFits( fits, "CNPIX1", NULL, 0 ) ){ - astSetFitsI( fits, "CNPIX1", NINT( cnpix1 ), NULL, 1 ); - } else { - ok = 0; - } - - astClearCard( fits ); - if( astFindFits( fits, "CNPIX2", NULL, 0 ) ){ - astSetFitsI( fits, "CNPIX2", NINT( cnpix2 ), NULL, 1 ); - } else { - ok = 0; - } - - astClearCard( fits ); - if( astFindFits( fits, "XPIXELSZ", NULL, 0 ) ){ - astSetFitsF( fits, "XPIXELSZ", xpixelsz, NULL, 1 ); - } else { - ok = 0; - } - - astClearCard( fits ); - if( astFindFits( fits, "YPIXELSZ", NULL, 0 ) ){ - astSetFitsF( fits, "YPIXELSZ", ypixelsz, NULL, 1 ); - } else { - ok = 0; - } - -/* If all the keywords were updated succesfully, create the new DssMap - based on the modified FITS header cards. */ - if( ok ){ - dmnew = astDssMap( fits, "", status ); - -/* Anull the DssMap pointer in the list and replace it with the new one. - The invert flag is left unchanged. */ - dm = astAnnul( dm ); - ( *map_list )[ where ] = (AstMapping *) dmnew; - -/* Annul the WinMap pointer in the list, and shuffle any remaining - Mappings down to fill the gap. */ - wm = astAnnul( wm ); - for ( i = wmi + 1; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = astMIN( wmi, where ); - - } - -/* Annul the FitsChan holding the modified header cards. */ - fits = astAnnul( fits ); - } - } - -/* Free the arrays holding scale and shift terms from the WinMap. */ - a = (double *) astFree( (void *) a ); - b = (double *) astFree( (void *) b ); - -/* Reinstate the original setting of the Invert attribute of the WinMap (if - it still exists). */ - if( wm ) astSetInvert( wm, old_winv ); - - } - } - } - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a DssMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "dssmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* DssMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a DssMap and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required DSS -* plate fit. - -* Parameters: -* this -* Pointer to the DssMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* be 2. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstDssMap *map; /* Pointer to DssMap to be applied */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *aa; /* Pointer to next longitude value */ - double *bb; /* Pointer to next latitude value */ - double *xx; /* Pointer to next pixel X value */ - double *yy; /* Pointer to next pixel Y value */ - int npoint; /* Number of points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the DssMap. */ - map = (AstDssMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points from the input PointSet and obtain - pointers for accessing the input and output coordinate values. */ - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse mapping, according to the - direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - -/* First deal with forward transformations. */ - if( forward ){ - -/* Store pointers to the next value on each axis. */ - xx = ptr_in[ 0 ]; - yy = ptr_in[ 1 ]; - aa = ptr_out[ 0 ]; - bb = ptr_out[ 1 ]; - -/* Loop to apply the plate fit to all the points, checking for (and - propagating) bad values in the process. */ - for ( point = 0; point < npoint; point++ ) { - if( *xx != AST__BAD && *yy != AST__BAD ){ - -/* If the pixel position is transformed succesfully, convert the returned - RA/DEC from degrees to radians. Otherwise, store bad values. NB, - platepos returns zero for success. */ - if( !platepos( *xx, *yy, (struct WorldCoor *) map->wcs, - aa, bb ) ){ - (*aa) *= AST__DD2R; - (*bb) *= AST__DD2R; - - } else { - *aa = AST__BAD; - *bb = AST__BAD; - } - - } else { - *aa = AST__BAD; - *bb = AST__BAD; - } - -/* Move on to the next point. */ - xx++; - yy++; - aa++; - bb++; - } - -/* Now deal with inverse transformations in the same way. */ - } else { - aa = ptr_in[ 0 ]; - bb = ptr_in[ 1 ]; - xx = ptr_out[ 0 ]; - yy = ptr_out[ 1 ]; - - for ( point = 0; point < npoint; point++ ) { - if( *aa != AST__BAD && *bb != AST__BAD ){ - - if( platepix( AST__DR2D*(*aa), AST__DR2D*(*bb), - (struct WorldCoor *) map->wcs, xx, yy ) ){ - *xx = AST__BAD; - *yy = AST__BAD; - } - - } else { - *xx = AST__BAD; - *yy = AST__BAD; - } - - xx++; - yy++; - aa++; - bb++; - } - } - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for DssMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for DssMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy. -*/ - - -/* Local Variables: */ - AstDssMap *in; /* Pointer to input DssMap */ - AstDssMap *out; /* Pointer to output DssMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output DssMaps. */ - in = (AstDssMap *) objin; - out = (AstDssMap *) objout; - -/* Store a copy of the input SAOIMAGE WorldCoor structure in the output. */ - out->wcs = astStore( NULL, in->wcs, sizeof( struct WorldCoor ) ); - - return; - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for DssMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for DssMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstDssMap *this; /* Pointer to DssMap */ - -/* Obtain a pointer to the DssMap structure. */ - this = (AstDssMap *) obj; - -/* Free the SAOIMAGE WorldCoor structure. */ - this->wcs = astFree( this->wcs ); - -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for DssMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the DssMap class to an output Channel. - -* Parameters: -* this -* Pointer to the DssMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - - AstDssMap *this; /* Pointer to the DssMap structure */ - struct WorldCoor *wcs; /* Pointer to SAOimage wcs structure */ - char name_buff[ 11 ]; /* Buffer for keyword string */ - int i; /* Coefficient index */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the DssMap structure. */ - this = (AstDssMap *) this_object; - -/* Get a pointer to the WorldCoor structure holding the description of the - DssMap. */ - wcs = (struct WorldCoor *) ( this->wcs ); - -/* Write out values representing the contents of the WorldCoor structure. - Only the components which are required to re-create the DssMap are - written out. */ - astWriteDouble( channel, "PltRA", 1, 1, wcs->plate_ra, "Plate centre RA (radians)" ); - astWriteDouble( channel, "PltDec", 1, 1, wcs->plate_dec, "Plate centre Dec (radians)" ); - astWriteDouble( channel, "PltScl", 1, 1, wcs->plate_scale, "Plate scale (arcsec/mm)" ); - astWriteDouble( channel, "CNPix1", 1, 1, wcs->x_pixel_offset, "X Pixel offset (pixels)" ); - astWriteDouble( channel, "CNPix2", 1, 1, wcs->y_pixel_offset, "Y Pixel offset (pixels)" ); - astWriteDouble( channel, "XPixSz", 1, 1, wcs->x_pixel_size, "X Pixel size (microns)" ); - astWriteDouble( channel, "YPixSz", 1, 1, wcs->y_pixel_size, "Y Pixel size (microns)" ); - - for( i = 0; i < 6; i++ ) { - sprintf( name_buff, "PPO%d", i + 1 ); - astWriteDouble( channel, name_buff, 1, 1, wcs->ppo_coeff[i], - "Orientation coefficients" ); - } - - for( i = 0; i < 19; i++ ) { - sprintf( name_buff, "AMDX%d", i + 1 ); - astWriteDouble( channel, name_buff, 1, 1, wcs->amd_x_coeff[i], - "Plate solution X coefficients" ); - } - - for( i = 0; i < 19; i++ ) { - sprintf( name_buff, "AMDY%d", i + 1 ); - astWriteDouble( channel, name_buff, 1, 1, wcs->amd_y_coeff[i], - "Plate solution Y coefficients" ); - } - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsADssMap and astCheckDssMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(DssMap,Mapping) -astMAKE_CHECK(DssMap) - -AstDssMap *astDssMap_( void *fits_void, const char *options, int *status, ...) { -/* -*+ -* Name: -* astDssMap - -* Purpose: -* Create a DssMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "dssmap.h" -* AstDssMap *astDssMap( AstFitsChan *fits, const char *options, int *status, ... ) - -* Class Membership: -* DssMap constructor. - -* Description: -* This function creates a new DssMap and optionally initialises its -* attributes. -* -* A DssMap is a Mapping which uses a Digitised Sky Survey plate fit to -* transform a set of points from pixel coordinates to equatorial -* coordinates (i.e. Right Ascension and Declination). - -* Parameters: -* fits -* A pointer to a FitsChan holding a set of FITS header cards -* describing the plate fit to be used. The FitsChan may contain -* other header cards which will be ignored, and it is unchanged on -* exit. The required information is copied from the FitsChan, and -* so the supplied FitsChan may subsequently be changed or deleted -* without changing the DssMap. -* options -* Pointer to a null-terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new DssMap. The syntax used is identical to -* that for the astSet function and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of additional arguments may follow it in -* order to supply values to be substituted for these -* specifiers. The rules for supplying these are identical to -* those for the astSet function (and for the C "printf" -* function). - -* Returned Value: -* astDssMap() -* A pointer to the new DssMap. - -* Attributes: -* The DssMap class has no additional attributes over and above those -* common to all Mappings. - -* Notes: -* - The supplied FitsChan must contain values for the following FITS -* keywords: CNPIX1, CNPIX2, PPO3, PPO6, XPIXELSZ, YPIXELSZ, PLTRAH, -* PLTRAM, PLTRAS, PLTDECD, PLTDECM, PLTDECS, PLTDECSN, PLTSCALE, -* AMDX1, AMDX2, ..., AMDX13, AMDY1, AMDY2, ..., AMDY13. -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFitsChan *fits; /* Pointer to supplied FitsChan */ - AstDssMap *new; /* Pointer to new DssMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - new = NULL; - if ( !astOK ) return new; - -/* Obtain and validate a pointer to the FitsChan structure provided. */ - fits = astCheckFitsChan( fits_void ); - if ( astOK ) { - -/* Initialise the DssMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitDssMap( NULL, sizeof( AstDssMap ), !class_init, &class_vtab, - "DssMap", fits ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new DssMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new DssMap. */ - return new; -} - -AstDssMap *astInitDssMap_( void *mem, size_t size, int init, - AstDssMapVtab *vtab, const char *name, - AstFitsChan *fits, int *status ) { -/* -*+ -* Name: -* astInitDssMap - -* Purpose: -* Initialise a DssMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "dssmap.h" -* AstDssMap *astInitDssMap( void *mem, size_t size, int init, -* AstDssMapVtab *vtab, const char *name, -* AstFitsChan *fits ) - -* Class Membership: -* DssMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new DssMap object. It allocates memory (if necessary) to accommodate -* the DssMap plus any additional data associated with the derived class. -* It then initialises a DssMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a DssMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the DssMap is to be initialised. -* This must be of sufficient size to accommodate the DssMap data -* (sizeof(DssMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the DssMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the DssMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the DssMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new DssMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* fits -* Pointer to a FitsChan containing the DSS FITS Header. - -* Returned Value: -* A pointer to the new DssMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstDssMap *new; /* Pointer to new DssMap */ - struct WorldCoor *wcs; /* Pointer to SAOIMAGE wcs structure */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitDssMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Create a structure holding the information required by the SAOIMAGE - "platepos" function. The required values are extracted from the - supplied FitsChan. An error is reported and NULL returned if any required - keywords are missing or unusable. */ - if ( ( wcs = BuildWcs( fits, "astInitDssMap", name, status ) ) ) { - -/* Initialise a 2-D Mapping structure (the parent class) as the first component - within the DssMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstDssMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - 2, 2, 1, 1 ); - - if ( astOK ) { - -/* Initialise the DssMap data. */ -/* --------------------------- */ -/* Store a copy of the SAOIMAGE wcs structure. */ - new->wcs = astStore( NULL, (void *) wcs, sizeof( struct WorldCoor ) ); - -/* If an error occurred, clean up by deleting the new DssMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Free the SAOIMAGE wcs structure. */ - wcs = (struct WorldCoor *) astFree( (void *) wcs ); - - } - -/* Return a pointer to the new DssMap. */ - return new; -} - -AstDssMap *astLoadDssMap_( void *mem, size_t size, - AstDssMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadDssMap - -* Purpose: -* Load a DssMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "dssmap.h" -* AstDssMap *astLoadDssMap( void *mem, size_t size, -* AstDssMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* DssMap loader. - -* Description: -* This function is provided to load a new DssMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* DssMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a DssMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the DssMap is to be -* loaded. This must be of sufficient size to accommodate the -* DssMap data (sizeof(DssMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the DssMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the DssMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstDssMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new DssMap. If this is NULL, a pointer -* to the (static) virtual function table for the DssMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "DssMap" is used instead. - -* Returned Value: -* A pointer to the new DssMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstDssMap *new; /* Pointer to the new DssMap */ - char name_buff[ 11 ]; /* Buffer for item name */ - int i; /* Coefficient index */ - struct WorldCoor *wcs; /* Pointer to Wcs information */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this DssMap. In this case the - DssMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstDssMap ); - vtab = &class_vtab; - name = "DssMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitDssMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built DssMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "DssMap" ); - -/* Allocate memory to hold the WorldCoor structure which holds the wcs - information in a form usable by the SAOimage projection functions. */ - new->wcs = astMalloc( sizeof(struct WorldCoor) ); - if( astOK ) { - -/* Get a pointer to the WorldCoor structure holding the description of the - DssMap. */ - wcs = (struct WorldCoor *) ( new->wcs ); - -/* Read the values representing the contents of the WorldCoor structure. - Only the components which are required to re-create the DssMap are - read. */ - wcs->plate_ra = astReadDouble( channel, "pltra", AST__BAD ); - if( wcs->plate_ra == AST__BAD && astOK ){ - astError( AST__RDERR, "astRead(DssMap): 'PltRA' object (Plate " - "centre RA) missing from input." , status); - } - - wcs->plate_dec = astReadDouble( channel, "pltdec", AST__BAD ); - if( wcs->plate_dec == AST__BAD && astOK ){ - astError( AST__RDERR, "astRead(DssMap): 'PltDec' object (Plate " - "centre Dec) missing from input." , status); - } - - wcs->plate_scale = astReadDouble( channel, "pltscl", AST__BAD ); - if( wcs->plate_scale == AST__BAD && astOK ){ - astError( AST__RDERR, "astRead(DssMap): 'PltScl' object (Plate " - "scale) missing from input." , status); - } - - wcs->x_pixel_offset = astReadDouble( channel, "cnpix1", AST__BAD ); - if( wcs->x_pixel_offset == AST__BAD && astOK ){ - astError( AST__RDERR, "astRead(DssMap): 'CNPix1' object (X pixel " - "offset) missing from input." , status); - } - - wcs->y_pixel_offset = astReadDouble( channel, "cnpix2", AST__BAD ); - if( wcs->y_pixel_offset == AST__BAD && astOK ){ - astError( AST__RDERR, "astRead(DssMap): 'CNPix2' object (Y pixel " - "offset) missing from input." , status); - } - - wcs->x_pixel_size = astReadDouble( channel, "xpixsz", AST__BAD ); - if( wcs->x_pixel_size == AST__BAD && astOK ){ - astError( AST__RDERR, "astRead(DssMap): 'XPixSz' object (X pixel " - "size) missing from input." , status); - } - - wcs->y_pixel_size = astReadDouble( channel, "ypixsz", AST__BAD ); - if( wcs->y_pixel_size == AST__BAD && astOK ){ - astError( AST__RDERR, "astRead(DssMap): 'YPixSz' object (Y pixel " - "size) missing from input." , status); - } - - for( i = 0; i < 6 && astOK; i++ ) { - sprintf( name_buff, "ppo%d", i + 1 ); - wcs->ppo_coeff[i] = astReadDouble( channel, name_buff, AST__BAD ); - if( wcs->ppo_coeff[i] == AST__BAD ){ - if( i == 2 || i == 5 ) { - if( astOK ) astError( AST__RDERR, "astRead(DssMap): 'PPO%d' " - "object (orientation coefficient %d) " - "missing from input.", status, i + 1, i + 1 ); - } else { - wcs->ppo_coeff[i] = 0.0; - } - } - } - - for( i = 0; i < 19 && astOK; i++ ) { - sprintf( name_buff, "amdx%d", i + 1 ); - wcs->amd_x_coeff[i] = astReadDouble( channel, name_buff, AST__BAD ); - if( wcs->amd_x_coeff[i] == AST__BAD ){ - if( i < 13 ){ - if( astOK ) astError( AST__RDERR, "astRead(DssMap): 'AMDX%d' " - "object (plate solution X coefficient " - "%d) missing from input.", status, i + 1, i + 1 ); - } else { - wcs->amd_x_coeff[i] = 0.0; - } - } - } - - for( i = 0; i < 19 && astOK; i++ ) { - sprintf( name_buff, "amdy%d", i + 1 ); - wcs->amd_y_coeff[i] = astReadDouble( channel, name_buff, AST__BAD ); - if( wcs->amd_y_coeff[i] == AST__BAD ){ - if( i < 13 ){ - if( astOK ) astError( AST__RDERR, "astRead(DssMap): 'AMDY%d' " - "object (plate solution Y coefficient " - "%d) missing from input.", status, i + 1, i + 1 ); - } else { - wcs->amd_y_coeff[i] = 0.0; - } - } - } - } - -/* If an error occurred, clean up by deleting the new DssMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new DssMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -AstFitsChan *astDssFits_( AstDssMap *this, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,DssMap,DssFits))( this, status ); -} - -/* The code which follows in this file is covered by the following - statement of terms and conditions, which differ from the terms and - conditions which apply above. - -*************************************************************************** -* -* Copyright: 1988 Smithsonian Astrophysical Observatory -* You may do anything you like with these files except remove -* this copyright. The Smithsonian Astrophysical Observatory -* makes no representations about the suitability of this -* software for any purpose. It is provided "as is" without -* express or implied warranty. -* -***************************************************************************** -*/ - -/* >>>>>>>>>>>>>>>>>>>>>> platepos.c <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ - -/* File saoimage/wcslib/platepos.c - * February 25, 1996 - * By Doug Mink, Harvard-Smithsonian Center for Astrophysics - - * Module: platepos.c (Plate solution WCS conversion - * Purpose: Compute WCS from Digital Sky Survey plate fit - * Subroutine: platepos() converts from pixel location to RA,Dec - * Subroutine: platepix() converts from RA,Dec to pixel location - - These functions are based on the astrmcal.c portion of GETIMAGE by - J. Doggett and the documentation distributed with the Digital Sky Survey. - - >>>>>>> STARLINK VERSION <<<<<<<< - -*/ - -/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - - Changed by R.F. Warren-Smith (Starlink) to make the function static. */ - -static int -platepos (xpix, ypix, wcs, xpos, ypos) - -/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */ - -/* Routine to determine accurate position for pixel coordinates */ -/* returns 0 if successful otherwise 1 = angle too large for projection; */ -/* based on amdpos() from getimage */ - -/* Input: */ -double xpix; /* x pixel number (RA or long without rotation) */ -double ypix; /* y pixel number (dec or lat without rotation) */ -struct WorldCoor *wcs; /* WCS parameter structure */ - -/* Output: */ -double *xpos; /* Right ascension or longitude in degrees */ -double *ypos; /* Declination or latitude in degrees */ - -{ - double x, y, xmm, ymm, xmm2, ymm2, xmm3, ymm3, x2y2; - double xi, xir, eta, etar, raoff, ra, dec; - double cond2r = 1.745329252e-2; - double cons2r = 206264.8062470964; - double twopi = 6.28318530717959; - double ctan, ccos; - -/* Ignore magnitude and color terms - double mag = 0.0; - double color = 0.0; */ - -/* Convert from image pixels to plate pixels */ - x = xpix + wcs->x_pixel_offset - 1.0 + 0.5; - y = ypix + wcs->y_pixel_offset - 1.0 + 0.5; - -/* Convert from pixels to millimeters */ - xmm = (wcs->ppo_coeff[2] - x * wcs->x_pixel_size) / 1000.0; - ymm = (y * wcs->y_pixel_size - wcs->ppo_coeff[5]) / 1000.0; - xmm2 = xmm * xmm; - ymm2 = ymm * ymm; - xmm3 = xmm * xmm2; - ymm3 = ymm * ymm2; - x2y2 = xmm2 + ymm2; - -/* Compute coordinates from x,y and plate model */ - - xi = wcs->amd_x_coeff[ 0]*xmm + wcs->amd_x_coeff[ 1]*ymm + - wcs->amd_x_coeff[ 2] + wcs->amd_x_coeff[ 3]*xmm2 + - wcs->amd_x_coeff[ 4]*xmm*ymm + wcs->amd_x_coeff[ 5]*ymm2 + - wcs->amd_x_coeff[ 6]*(x2y2) + wcs->amd_x_coeff[ 7]*xmm3 + - wcs->amd_x_coeff[ 8]*xmm2*ymm + wcs->amd_x_coeff[ 9]*xmm*ymm2 + - wcs->amd_x_coeff[10]*ymm3 + wcs->amd_x_coeff[11]*xmm*(x2y2) + - wcs->amd_x_coeff[12]*xmm*x2y2*x2y2; - -/* Ignore magnitude and color terms - + wcs->amd_x_coeff[13]*mag + wcs->amd_x_coeff[14]*mag*mag + - wcs->amd_x_coeff[15]*mag*mag*mag + wcs->amd_x_coeff[16]*mag*xmm + - wcs->amd_x_coeff[17]*mag*x2y2 + wcs->amd_x_coeff[18]*mag*xmm*x2y2 + - wcs->amd_x_coeff[19]*color; */ - - eta = wcs->amd_y_coeff[ 0]*ymm + wcs->amd_y_coeff[ 1]*xmm + - wcs->amd_y_coeff[ 2] + wcs->amd_y_coeff[ 3]*ymm2 + - wcs->amd_y_coeff[ 4]*xmm*ymm + wcs->amd_y_coeff[ 5]*xmm2 + - wcs->amd_y_coeff[ 6]*(x2y2) + wcs->amd_y_coeff[ 7]*ymm3 + - wcs->amd_y_coeff[ 8]*ymm2*xmm + wcs->amd_y_coeff[ 9]*ymm*xmm2 + - wcs->amd_y_coeff[10]*xmm3 + wcs->amd_y_coeff[11]*ymm*(x2y2) + - wcs->amd_y_coeff[12]*ymm*x2y2*x2y2; - -/* Ignore magnitude and color terms - + wcs->amd_y_coeff[13]*mag + wcs->amd_y_coeff[14]*mag*mag + - wcs->amd_y_coeff[15]*mag*mag*mag + wcs->amd_y_coeff[16]*mag*ymm + - wcs->amd_y_coeff[17]*mag*x2y2) + wcs->amd_y_coeff[18]*mag*ymm*x2y2 + - wcs->amd_y_coeff[19]*color; */ - -/* Convert to radians */ - - xir = xi / cons2r; - etar = eta / cons2r; - -/* Convert to RA and Dec */ - - ctan = tan (wcs->plate_dec); - ccos = cos (wcs->plate_dec); - raoff = atan2 (xir / ccos, 1.0 - etar * ctan); - ra = raoff + wcs->plate_ra; - if (ra < 0.0) ra = ra + twopi; - *xpos = ra / cond2r; - - dec = atan (cos (raoff) / ((1.0 - (etar * ctan)) / (etar + ctan))); - *ypos = dec / cond2r; - return 0; -} - - -/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - - Changed by R.F. Warren-Smith (Starlink) to make the function static. */ - -static int -platepix (xpos, ypos, wcs, xpix, ypix) - -/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */ - -/* Routine to determine pixel coordinates for sky position */ -/* returns 0 if successful otherwise 1 = angle too large for projection; */ -/* based on amdinv() from getimage */ - -/* Input: */ -double xpos; /* Right ascension or longitude in degrees */ -double ypos; /* Declination or latitude in degrees */ -struct WorldCoor *wcs; /* WCS parameter structure */ - -/* Output: */ -double *xpix; /* x pixel number (RA or long without rotation) */ -double *ypix; /* y pixel number (dec or lat without rotation) */ - -{ - double div,xi,eta,x,y,xy,x2,y2,x2y,y2x,x3,y3,x4,y4,x2y2,cjunk,dx,dy; - double sypos,cypos,syplate,cyplate,sxdiff,cxdiff; - double f,fx,fy,g,gx,gy, xmm, ymm; - double conr2s = 206264.8062470964; - double tolerance = 0.0000005; - int max_iterations = 50; - int i; - double xr, yr; /* position in radians */ - double cond2r = 1.745329252e-2; - -/* Convert RA and Dec in radians to standard coordinates on a plate */ - xr = xpos * cond2r; - yr = ypos * cond2r; - sypos = sin (yr); - cypos = cos (yr); - syplate = sin (wcs->plate_dec); - cyplate = cos (wcs->plate_dec); - sxdiff = sin (xr - wcs->plate_ra); - cxdiff = cos (xr - wcs->plate_ra); - div = (sypos * syplate) + (cypos * cyplate * cxdiff); - xi = cypos * sxdiff * conr2s / div; - eta = ((sypos * cyplate) - (cypos * syplate * cxdiff)) * conr2s / div; - -/* Set initial value for x,y */ - xmm = xi / wcs->plate_scale; - ymm = eta / wcs->plate_scale; - -/* Iterate by Newton's method */ - for (i = 0; i < max_iterations; i++) { - - /* X plate model */ - xy = xmm * ymm; - x2 = xmm * xmm; - y2 = ymm * ymm; - x2y = x2 * ymm; - y2x = y2 * xmm; - x2y2 = x2 + y2; - cjunk = x2y2 * x2y2; - x3 = x2 * xmm; - y3 = y2 * ymm; - x4 = x2 * x2; - y4 = y2 * y2; - f = wcs->amd_x_coeff[0]*xmm + wcs->amd_x_coeff[1]*ymm + - wcs->amd_x_coeff[2] + wcs->amd_x_coeff[3]*x2 + - wcs->amd_x_coeff[4]*xy + wcs->amd_x_coeff[5]*y2 + - wcs->amd_x_coeff[6]*x2y2 + wcs->amd_x_coeff[7]*x3 + - wcs->amd_x_coeff[8]*x2y + wcs->amd_x_coeff[9]*y2x + - wcs->amd_x_coeff[10]*y3 + wcs->amd_x_coeff[11]*xmm*x2y2 + - wcs->amd_x_coeff[12]*xmm*cjunk; - /* magnitude and color terms ignored - + wcs->amd_x_coeff[13]*mag + - wcs->amd_x_coeff[14]*mag*mag + wcs->amd_x_coeff[15]*mag*mag*mag + - wcs->amd_x_coeff[16]*mag*xmm + wcs->amd_x_coeff[17]*mag*(x2+y2) + - wcs->amd_x_coeff[18]*mag*xmm*(x2+y2) + wcs->amd_x_coeff[19]*color; - */ - - /* Derivative of X model wrt x */ - fx = wcs->amd_x_coeff[0] + wcs->amd_x_coeff[3]*2.0*xmm + - wcs->amd_x_coeff[4]*ymm + wcs->amd_x_coeff[6]*2.0*xmm + - wcs->amd_x_coeff[7]*3.0*x2 + wcs->amd_x_coeff[8]*2.0*xy + - wcs->amd_x_coeff[9]*y2 + wcs->amd_x_coeff[11]*(3.0*x2+y2) + - wcs->amd_x_coeff[12]*(5.0*x4 +6.0*x2*y2+y4); - /* magnitude and color terms ignored - wcs->amd_x_coeff[16]*mag + wcs->amd_x_coeff[17]*mag*2.0*xmm + - wcs->amd_x_coeff[18]*mag*(3.0*x2+y2); - */ - - /* Derivative of X model wrt y */ - fy = wcs->amd_x_coeff[1] + wcs->amd_x_coeff[4]*xmm + - wcs->amd_x_coeff[5]*2.0*ymm + wcs->amd_x_coeff[6]*2.0*ymm + - wcs->amd_x_coeff[8]*x2 + wcs->amd_x_coeff[9]*2.0*xy + - wcs->amd_x_coeff[10]*3.0*y2 + wcs->amd_x_coeff[11]*2.0*xy + - wcs->amd_x_coeff[12]*4.0*xy*x2y2; - /* magnitude and color terms ignored - wcs->amd_x_coeff[17]*mag*2.0*ymm + - wcs->amd_x_coeff[18]*mag*2.0*xy; - */ - - /* Y plate model */ - g = wcs->amd_y_coeff[0]*ymm + wcs->amd_y_coeff[1]*xmm + - wcs->amd_y_coeff[2] + wcs->amd_y_coeff[3]*y2 + - wcs->amd_y_coeff[4]*xy + wcs->amd_y_coeff[5]*x2 + - wcs->amd_y_coeff[6]*x2y2 + wcs->amd_y_coeff[7]*y3 + - wcs->amd_y_coeff[8]*y2x + wcs->amd_y_coeff[9]*x2y + - wcs->amd_y_coeff[10]*x3 + wcs->amd_y_coeff[11]*ymm*x2y2 + - wcs->amd_y_coeff[12]*ymm*cjunk; - /* magnitude and color terms ignored - wcs->amd_y_coeff[13]*mag + wcs->amd_y_coeff[14]*mag*mag + - wcs->amd_y_coeff[15]*mag*mag*mag + wcs->amd_y_coeff[16]*mag*ymm + - wcs->amd_y_coeff[17]*mag*x2y2 + - wcs->amd_y_coeff[18]*mag*ymm*x2y2 + wcs->amd_y_coeff[19]*color; - */ - - /* Derivative of Y model wrt x */ - gx = wcs->amd_y_coeff[1] + wcs->amd_y_coeff[4]*ymm + - wcs->amd_y_coeff[5]*2.0*xmm + wcs->amd_y_coeff[6]*2.0*xmm + - wcs->amd_y_coeff[8]*y2 + wcs->amd_y_coeff[9]*2.0*xy + - wcs->amd_y_coeff[10]*3.0*x2 + wcs->amd_y_coeff[11]*2.0*xy + - wcs->amd_y_coeff[12]*4.0*xy*x2y2; - /* magnitude and color terms ignored - wcs->amd_y_coeff[17]*mag*2.0*xmm + - wcs->amd_y_coeff[18]*mag*ymm*2.0*xmm; - */ - - /* Derivative of Y model wrt y */ - gy = wcs->amd_y_coeff[0] + wcs->amd_y_coeff[3]*2.0*ymm + - wcs->amd_y_coeff[4]*xmm + wcs->amd_y_coeff[6]*2.0*ymm + - wcs->amd_y_coeff[7]*3.0*y2 + wcs->amd_y_coeff[8]*2.0*xy + - wcs->amd_y_coeff[9]*x2 + wcs->amd_y_coeff[11]*(x2+3.0*y2) + - wcs->amd_y_coeff[12]*(5.0*y4 + 6.0*x2*y2 + x4); - /* magnitude and color terms ignored - wcs->amd_y_coeff[16]*mag + wcs->amd_y_coeff[17]*mag*2.0*ymm + - wcs->amd_y_coeff[18]*mag*(x2+3.0*y2); - */ - - f = f - xi; - g = g - eta; - dx = ((-f * gy) + (g * fy)) / ((fx * gy) - (fy * gx)); - dy = ((-g * fx) + (f * gx)) / ((fx * gy) - (fy * gx)); - xmm = xmm + dx; - ymm = ymm + dy; - if ((fabs(dx) < tolerance) && (fabs(dy) < tolerance)) break; - } - -/* Convert mm from plate center to plate pixels */ - x = (wcs->ppo_coeff[2] - xmm*1000.0) / wcs->x_pixel_size; - y = (wcs->ppo_coeff[5] + ymm*1000.0) / wcs->y_pixel_size; - -/* Convert from plate pixels to image pixels */ - *xpix = x - wcs->x_pixel_offset + 1.0 - 0.5; - *ypix = y - wcs->y_pixel_offset + 1.0 - 0.5; - -/* If position is off of the image, return offscale code */ - -/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - - Commented out by D.Berry (Starlink) in order to remove dependancy - on NAXIS1/NAXIS2 keywords >>>>>>>> - - if (*xpix < 0.5 || *xpix > wcs->nxpix+0.5) - return -1; - if (*ypix < 0.5 || *ypix > wcs->nypix+0.5) - return -1; - ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */ - - return 0; -} -/* Mar 6 1995 Original version of this code - May 4 1995 Fix eta cross terms which were all in y - Jun 21 1995 Add inverse routine - Oct 17 1995 Fix inverse routine (degrees -> radians) - Nov 7 1995 Add half pixel to image coordinates to get astrometric - plate coordinates - Feb 26 1996 Fix plate to image pixel conversion error - Feb 18 1997 Modified by D.S. Berry (Starlink) to avoid use of the image - dimensions stored in wcs->nxpix and wcs->nypix. - Sep 5 1997 Modified by R.F. Warren-Smith (Starlink) to make the - platepos and platepix functions static. - */ - - - - diff --git a/ast/dssmap.h b/ast/dssmap.h deleted file mode 100644 index b7550de..0000000 --- a/ast/dssmap.h +++ /dev/null @@ -1,401 +0,0 @@ -#if !defined( DSSMAP_INCLUDED ) /* Include this file only once */ -#define DSSMAP_INCLUDED -/* -*+ -* Name: -* dssmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the DssMap class. - -* Invocation: -* #include "dssmap.h" - -* Description: -* This include file defines the interface to the DssMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The DssMap class implements Mappings which use a Digitised Sky -* Survey plate fit to transform between pixel coordinates and -* Equatorial coordinates. - -* Inheritance: -* The DssMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astTransform -* Apply a DssMap to transform a set of points. - -* New Methods Defined: -* Public: -* astDssFits -* Create a FitsChan holding a FITS description of the DSS plate fit. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsADssMap -* Test class membership. -* astDssMap -* Create a DssMap. -* -* Protected: -* astCheckDssMap -* Validate class membership. -* astInitDssMap -* Initialise a DssMap. -* astInitDssMapVtab -* Initialise the virtual function table for the DssMap class. -* astLoadDssMap -* Load a DssMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstDssMap -* DssMap object type. -* -* Protected: -* AstDssMapVtab -* DssMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . -* (except for code supplied by Doug Mink, as noted in this file) - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 18-FEB-1997 (DSB): -* Original version. -* 30-JUN-1997 (DSB): -* All public functions made protected. -* 4-NOV-1997 (DSB): -* Removed copy of supplied FitsChan from DssMap structure. -* 8-JAN-2003 (DSB): -* Added protected astInitDssMapVtab method. -* 21-OCT-2004 (DSB): -* Removed wcstools prototypes which clash with the MS Windows -* runtime library. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#if defined(astCLASS) /* Protected */ - -/* The code within this #if...#endif block is covered by the following - statement of terms and conditions, which differ from the terms and - conditions which apply elsewhere in this file. - -*************************************************************************** -* -* Copyright: 1988 Smithsonian Astrophysical Observatory -* You may do anything you like with these files except remove -* this copyright. The Smithsonian Astrophysical Observatory -* makes no representations about the suitability of this -* software for any purpose. It is provided "as is" without -* express or implied warranty. -* -***************************************************************************** -*/ - -/* >>>>>>>>>>>>>>>>>> SAOimage wcs.h header file <<<<<<<<<<<<<<<<<< */ - -/* libwcs/wcs.h - November 1, 1996 - By Doug Mink, Harvard-Smithsonian Center for Astrophysics */ - -struct WorldCoor { - double xref; /* x reference coordinate value (deg) */ - double yref; /* y reference coordinate value (deg) */ - double xrefpix; /* x reference pixel */ - double yrefpix; /* y reference pixel */ - double xinc; /* x coordinate increment (deg) */ - double yinc; /* y coordinate increment (deg) */ - double rot; /* rotation (deg) (from N through E) */ - double crot,srot; /* Cosine and sine of rotation angle */ - double cd11,cd12,cd21,cd22; - /* rotation matrix */ - double dc11,dc12,dc21,dc22; - /* inverse rotation matrix */ - double equinox; /* Equinox of coordinates default to 1950.0 */ - double epoch; /* Epoch of coordinates default to equinox */ - double nxpix; /* Number of pixels in X-dimension of image */ - double nypix; /* Number of pixels in Y-dimension of image */ - double plate_ra; /* Right ascension of plate center */ - double plate_dec; /* Declination of plate center */ - double plate_scale; /* Plate scale in arcsec/mm */ - double x_pixel_offset; /* X pixel offset of image lower right */ - double y_pixel_offset; /* Y pixel offset of image lower right */ - double x_pixel_size; /* X pixel_size */ - double y_pixel_size; /* Y pixel_size */ - double ppo_coeff[6]; - double amd_x_coeff[20]; /* X coefficients for plate model */ - double amd_y_coeff[20]; /* Y coefficients for plate model */ - double xpix; /* x (RA) coordinate (pixels) */ - double ypix; /* y (dec) coordinate (pixels) */ - double xpos; /* x (RA) coordinate (deg) */ - double ypos; /* y (dec) coordinate (deg) */ - int pcode; /* projection code (1-8) */ - int changesys; /* 1 for FK4->FK5, 2 for FK5->FK4 */ - /* 3 for FK4->galactic, 4 for FK5->galactic */ - int printsys; /* 1 to print coordinate system, else 0 */ - int ndec; /* Number of decimal places in PIX2WCST */ - int degout; /* 1 to always print degrees in PIX2WCST */ - int tabsys; /* 1 to put tab between RA & Dec, else 0 */ - int rotmat; /* 0 if CDELT, CROTA; 1 if CD */ - int coorflip; /* 0 if x=RA, y=Dec; 1 if x=Dec, y=RA */ - int offscl; /* 0 if OK, 1 if offscale */ - int plate_fit; /* 1 if plate fit, else 0 */ - int wcson; /* 1 if WCS is set, else 0 */ - char c1type[8]; /* 1st coordinate type code: - RA--, GLON, ELON */ - char c2type[8]; /* 2nd coordinate type code: - DEC-, GLAT, ELAT */ - char ptype[8]; /* projection type code: - -SIN, -TAN, -ARC, -NCP, -GLS, -MER, -AIT */ - char radecsys[16]; /* Reference frame: FK4, FK4-NO-E, FK5, GAPPT*/ - char sysout[16]; /* Reference frame for output: FK4, FK5 */ - char center[32]; /* Center coordinates (with frame) */ - char search_format[120]; /* search command format */ - /* where %s is replaced by WCS coordinates */ -}; - -#ifndef PI -#define PI 3.141592653589793 -#endif - -/* Conversions among hours of RA, degrees and radians. */ -#define degrad(x) ((x)*PI/180.) -#define raddeg(x) ((x)*180./PI) -#define hrdeg(x) ((x)*15.) -#define deghr(x) ((x)/15.) -#define hrrad(x) degrad(hrdeg(x)) -#define radhr(x) deghr(raddeg(x)) - - -/* WCS subroutines in wcs.c */ - -/* >>>>> DSB: Prototypes for "subroutines in wcs.c" have been removed since - they clash with prototypes defined by the MS windows runtime library and - are not needed by AST. */ - -/* Oct 26 1994 New file - * Dec 21 1994 Add rotation matrix - * Dec 22 1994 Add flag for coordinate reversal - - * Mar 6 1995 Add parameters for Digital Sky Survey plate fit - * Jun 8 1995 Add parameters for coordinate system change - * Jun 21 1995 Add parameter for plate scale - * Jul 6 1995 Add parameter to note whether WCS is set - * Aug 8 1995 Add parameter to note whether to print coordinate system - * Oct 16 1995 Add parameters to save image dimensions and center coordinates - - * Feb 15 1996 Add coordinate conversion functions - * Feb 20 1996 Add flag for tab tables - * Apr 26 1996 Add epoch of positions (actual date of image) - * Jul 5 1996 Add subroutine declarations - * Jul 19 1996 Add WCSFULL declaration - * Aug 5 1996 Add WCSNINIT to initialize WCS for non-terminated header - * Oct 31 1996 Add DCnn inverse rotation matrix - * Nov 1 1996 Add NDEC number of decimal places in output - */ -/* >>>>>>>>>>>>>>>>>>>> End of SAOimage wcs.h header file <<<<<<<<<<<<<<<< */ -#endif - -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "fitschan.h" /* Storage for FITS header cards */ - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Type Definitions. */ -/* ================= */ -/* DssMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstDssMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - void *wcs; /* Pointer to structure holding plate fit info */ - -} AstDssMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstDssMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstFitsChan *(* DssFits)( AstDssMap *, int * ); - -} AstDssMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstDssMapGlobals { - AstDssMapVtab Class_Vtab; - int Class_Init; -} AstDssMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitDssMapGlobals_( AstDssMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(DssMap) /* Check class membership */ -astPROTO_ISA(DssMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstDssMap *astDssMap_( void *, const char *, int *, ...); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstDssMap *astInitDssMap_( void *, size_t, int, AstDssMapVtab *, - const char *, AstFitsChan *, int * ); - -/* Vtab initialiser. */ -void astInitDssMapVtab_( AstDssMapVtab *, const char *, int * ); - -/* Loader. */ -AstDssMap *astLoadDssMap_( void *, size_t, AstDssMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -AstFitsChan *astDssFits_( AstDssMap *, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckDssMap(this) astINVOKE_CHECK(DssMap,this,0) -#define astVerifyDssMap(this) astINVOKE_CHECK(DssMap,this,1) - -/* Test class membership. */ -#define astIsADssMap(this) astINVOKE_ISA(DssMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astDssMap astINVOKE(F,astDssMap_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitDssMap(mem,size,init,vtab,name,fits) \ -astINVOKE(O,astInitDssMap_(mem,size,init,vtab,name,astCheckFitsChan(fits),STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitDssMapVtab(vtab,name) astINVOKE(V,astInitDssMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadDssMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadDssMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckDssMap to validate DssMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astDssFits(this) astINVOKE(O,astDssFits_(astCheckDssMap(this),STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/ellipse.c b/ast/ellipse.c deleted file mode 100644 index 1e23724..0000000 --- a/ast/ellipse.c +++ /dev/null @@ -1,3055 +0,0 @@ -/* -*class++ -* Name: -* Ellipse - -* Purpose: -* An elliptical region within a 2-dimensional Frame. - -* Constructor Function: -c astEllipse -f AST_ELLIPSE - -* Description: -* The Ellipse class implements a Region which represents a ellipse -* within a 2-dimensional Frame. - -* Inheritance: -* The Ellipse class inherits from the Region class. - -* Attributes: -* The Ellipse class does not define any new attributes beyond -* those which are applicable to all Regions. - -* Functions: -c In addition to those functions applicable to all Regions, the -c following functions may also be applied to all Ellipses: -f In addition to those routines applicable to all Regions, the -f following routines may also be applied to all Ellipses: -* -c - astEllipsePars: Get the geometric parameters of the Ellipse -f - AST_ELLIPSEPARS: Get the geometric parameters of the Ellipse - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 7-SEP-2004 (DSB): -* Original version. -* 4-NOV-2013 (DSB): -* Modify RegPins so that it can handle uncertainty regions that straddle -* a discontinuity. Previously, such uncertainty Regions could have a huge -* bounding box resulting in matching region being far too big. -* 6-JAN-2014 (DSB): -* Ensure cached information is available in RegCentre even if no new -* centre is supplied. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Ellipse - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "region.h" /* Coordinate regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "box.h" /* Box Regions */ -#include "wcsmap.h" /* Definitons of AST__DPI etc */ -#include "circle.h" /* Interface definition for circle class */ -#include "ellipse.h" /* Interface definition for this class */ -#include "mapping.h" /* Position mappings */ -#include "unitmap.h" /* Unit Mapping */ -#include "pal.h" /* Positional astronomy library */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstMapping *(* parent_simplify)( AstMapping *, int * ); -static void (* parent_setregfs)( AstRegion *, AstFrame *, int * ); -static void (* parent_resetcache)( AstRegion *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Ellipse) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Ellipse,Class_Init) -#define class_vtab astGLOBAL(Ellipse,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstEllipseVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstEllipse *astEllipseId_( void *, int, const double[2], const double[2], const double[2], void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double *RegCentre( AstRegion *this, double *, double **, int, int, int * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static int RegTrace( AstRegion *, int, double *, double **, int * ); -static void Cache( AstEllipse *, int * ); -static void CalcPars( AstFrame *, double[2], double[2], double[2], double *, double *, double *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void EllipsePars( AstEllipse *, double[2], double *, double *, double *, double[2], double[2], int * ); -static void RegBaseBox( AstRegion *this, double *, double *, int * ); -static void ResetCache( AstRegion *this, int * ); -static void SetRegFS( AstRegion *, AstFrame *, int * ); - -/* Member functions. */ -/* ================= */ - -AstRegion *astBestEllipse_( AstPointSet *mesh, double *cen, AstRegion *unc, int *status ){ -/* -*+ -* Name: -* astBestEllipse - -* Purpose: -* Find the best fitting Ellipse through a given mesh of points. - -* Type: -* Protected function. - -* Synopsis: -* #include "ellipse.h" -* AstRegion *astBestEllipse( AstPointSet *mesh, double *cen, AstRegion *unc ) - -* Class Membership: -* Ellipse member function - -* Description: -* This function finds the best fitting Ellipse through a given mesh of -* points. Ellispes are always 2-dimensional. - -* Parameters: -* mesh -* Pointer to a PointSet holding the mesh of points. They are -* assumed to be in the Frame represented by "unc". -* cen -* Pointer to an array holding the coordinates of the new Ellipse -* centre. -* unc -* A Region representing the uncertainty associated with each point -* on the mesh. - -* Returned Value: -* Pointer to the best fitting Ellipse. It will inherit the positional -* uncertainty and Frame represented by "unc". - -* Implementation Deficiencies: -* - The method used by this function is not very accurate, and assumes -* that the supplied mesh provides uniform coverage of the entire ellipse. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - AstFrame *frm; - AstPointSet *ps2; - AstRegion *result; - double **ptr2; - double **ptr; - double *ang; - double *dist; - double *px; - double *py; - double a0; - double a; - double aa[2]; - double at; - double b; - double c0; - double c1; - double c2; - double c; - double d; - double den; - double e; - double f; - double mn; - double mx; - double p[2]; - double pa[2]; - double pb[2]; - double r1; - double r2; - double r3; - double smn; - double t1; - double t2; - double t3; - int ip; - int maxat; - int np; - double sw; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get no. of points in the mesh. */ - np = astGetNpoint( mesh ); - -/* Get pointers to the axis values. */ - ptr = astGetPoints( mesh ); - -/* Allocate work space */ - dist = astMalloc( sizeof( double )*(size_t) np ); - ang = astMalloc( sizeof( double )*(size_t) np ); - -/* Get a pointer to the Frame represented by "unc". This is the Frame to - which the supplied mesh points refer. */ - frm = astGetFrame( unc->frameset, AST__CURRENT ); - -/* Check pointers can be used safely */ - if( astOK ) { - -/* Find the first mesh point which is at a non-zero distance from the - centre. */ - px = ptr[ 0 ]; - py = ptr[ 1 ]; - for( ip = 0; ip < np; ip++, px++, py++ ) { - p[ 0 ] = *px; - p[ 1 ] = *py; - dist[ ip ] = astDistance( frm, cen, p ); - if( dist[ ip ] != AST__BAD && dist[ ip ] != 0.0 ) { - break; - } else { - ang[ ip ] = AST__BAD; - dist[ ip ] = AST__BAD; - } - } - -/* Find a point which is this distance away from the centre along the second - axis. This point is used to define zero angle when calling astAngle - below. */ - astOffset2( frm, cen, 0.0, dist[ ip ], aa ); - ang[ ip ] = astAngle( frm, aa, cen, p ); - -/* Get the distance from the centre to each of the remaining mesh points. Also - find the orientation of the radial lines through the centre to each mesh - point. At the same time, find the index of the point with the largest - radial distance. */ - maxat = ip; - r2 = dist[ maxat ]; - ip++; - px++; - py++; - for( ; ip < np; ip++, px++, py++ ) { - p[ 0 ] = *px; - p[ 1 ] = *py; - dist[ ip ] = astDistance( frm, cen, p ); - ang[ ip ] = astAngle( frm, aa, cen, p ); - if( dist[ ip ] != AST__BAD && dist[ ip ] > r2 ) { - r2 = dist[ ip ]; - maxat = ip; - } - } - -/* Find the higher index neighbouring point, wrapping back to the start - of the list when the end is reached. Note the radius and position angle - at this neighbouring point. */ - t2 = 0.0; - r3 = AST__BAD; - t3 = AST__BAD; - a0 = ang[ maxat ]; - for( ip = maxat + 1; ip < np; ip++ ) { - if( dist[ ip ] != AST__BAD ) { - r3 = dist[ ip ]; - t3 = palDrange( ang[ ip ] - a0 ); - break; - } - } - if( r3 == AST__BAD ) { - for( ip = 0; ip < maxat; ip++ ) { - if( dist[ ip ] != AST__BAD ) { - r3 = dist[ ip ]; - t3 = palDrange( ang[ ip ] - a0 ); - break; - } - } - } - -/* Find the lower index neighbouring point, wrapping back to the end - of the list when the start is reached. Note the radius and position angle - at this neighbouring point. */ - r1 = AST__BAD; - t1 = AST__BAD; - for( ip = maxat - 1; ip > -1; ip-- ) { - if( dist[ ip ] != AST__BAD ) { - r1 = dist[ ip ]; - t1 = palDrange( ang[ ip ] - a0 ); - break; - } - } - if( r1 == AST__BAD ) { - for( ip = np - 1; ip > maxat; ip-- ) { - if( dist[ ip ] != AST__BAD ) { - r1 = dist[ ip ]; - t1 = palDrange( ang[ ip ] - a0 ); - break; - } - } - } - -/* Fit a quadratic through the three pairs of (radius,angle) values. The - centre point (r2,t2) is the point which is furthest from the centre, - and the other two are the neighbouring points found above. */ - a = r2 - r1; - b = t2 - t1; - c = t2*t2 - t1*t1; - d = r3 - r2; - e = t3 - t2; - f = t3*t3 - t2*t2; - - den = c*e - b*f; - if( den != 0.0 ) { - -/* The co-efficients of the interpolating polynomial... */ - c1 = ( d*c - a*f )/den; - c2 = ( a*e - d*b )/den; - c0 = r1 - c1*t1 - c2*t1*t1; - -/* Find the largest radius (the turning point of the quadratic), and the - angle at which it occurs. */ - if( c2 < 0.0 ) { - mx = ( 4*c0*c2 - c1*c1 )/( 4*c2 ); - at = a0 - c1/( 2*c2 ); - } else { - mx = r2; - at = a0 - t2; - } - -/* This point is the end of the ellipse primary axis. Find its (x,y) - coords, and store in "pa". */ - astOffset2( frm, cen, at, mx, pa ); - -/* Resolve all the supplied points into components parallel and - perpendicular to the line joining the centre and "pa". */ - ps2 = astResolvePoints( frm, cen, pa, mesh, NULL ); - ptr2 = astGetPoints( ps2 ); - if( astOK ) { - -/* For each other mesh point, work out the length of the secondary - axis which would result if we used that point to define the ellipse. - Find the mean of these secondary axis lengths, weighted by the length - of the y component to reduce influence of poor conditioning at very - low y. */ - smn = 0.0; - sw = 0.0; - px = ptr2[ 0 ]; - py = ptr2[ 1 ]; - for( ip = 0; ip < np; ip++, px++, py++ ) { - if( *px != AST__BAD && *py != AST__BAD ) { - den = mx*mx - (*px)*(*px); - if( den > 0.0 ) { - smn += fabs( mx*(*py)*(*py) )/sqrt( den ); - sw += fabs( *py ); - } - } - } - - if( sw > 0 ) { - mn = smn/sw; - -/* Find the coords at the end of the mean secondary axis. */ - astOffset2( frm, cen, at + AST__DPIBY2, mn, pb ); - -/* Create the Ellipse to return. */ - result = (AstRegion *) astEllipse( frm, 0, cen, pa, pb, unc, "", status ); - } - } - -/* Free resources. */ - ps2 = astAnnul( ps2 ); - - } - } - - dist = astFree( dist ); - ang = astFree( ang ); - frm = astAnnul( frm ); - -/* Return NULL if anything went wrong. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result.*/ - return result; -} - -void astInitEllipseVtab_( AstEllipseVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitEllipseVtab - -* Purpose: -* Initialise a virtual function table for a Ellipse. - -* Type: -* Protected function. - -* Synopsis: -* #include "ellipse.h" -* void astInitEllipseVtab( AstEllipseVtab *vtab, const char *name ) - -* Class Membership: -* Ellipse vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Ellipse class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAEllipse) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->EllipsePars = EllipsePars; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - - parent_setregfs = region->SetRegFS; - region->SetRegFS = SetRegFS; - - parent_resetcache = region->ResetCache; - region->ResetCache = ResetCache; - - region->RegPins = RegPins; - region->RegBaseMesh = RegBaseMesh; - region->RegBaseBox = RegBaseBox; - region->RegCentre = RegCentre; - region->RegTrace = RegTrace; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "Ellipse", "Elliptical region" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void Cache( AstEllipse *this, int *status ){ -/* -* Name: -* Cache - -* Purpose: -* Calculate intermediate values and cache them in the Ellipse structure. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* void Cache( AstEllipse *this, int *status ) - -* Class Membership: -* Ellipse member function - -* Description: -* This function uses the PointSet stored in the parent Region to calculate -* some intermediate values which are useful in other methods. These -* values are stored within the Ellipse structure. - -* Parameters: -* this -* Pointer to the Ellipse. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to base Frame in Ellipse */ - double **ptr; /* Pointer to data in the encapsulated PointSet */ - double *centre; /* Array holding centre coords */ - double *point1; /* Array holding coords at end of primary axis */ - double *point2; /* Array holding coords at another point on ellipse */ - double a; /* The half-length of the primary axis */ - double angle; /* Orientation of primary axis */ - double b; /* The half-length of the secondary axis */ - int i; /* Axis index */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do Nothing if the cached information is up to date. */ - if( this->stale ) { - -/* Get a pointer to the base Frame. */ - frm = astGetFrame( ((AstRegion *) this)->frameset, AST__BASE ); - -/* Allocate memory. */ - centre = (double *) astMalloc( sizeof( double )*2 ); - point1 = (double *) astMalloc( sizeof( double )*2 ); - point2 = (double *) astMalloc( sizeof( double )*2 ); - -/* Get pointers to the coordinate data in the parent Region structure. */ - ptr = astGetPoints( ((AstRegion *) this)->points ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Copy the points in to the allocated memory. */ - for( i = 0; i < 2; i++ ) { - centre[ i ] = ptr[ i ][ 0 ]; - point1[ i ] = ptr[ i ][ 1 ]; - point2[ i ] = ptr[ i ][ 2 ]; - } - -/* Calculate the geometric parameters of the ellipse. */ - CalcPars( frm, centre, point1, point2, &a, &b, &angle, status ); - -/* Check the returned values. */ - if( a <= 0.0 || a == AST__BAD || b <= 0.0 || b == AST__BAD ) { - if( astOK ) astError( AST__BADIN, "astInitEllipse(%s): The " - "supplied points do not determine an " - "ellipse.", status, astGetClass( this ) ); - } - -/* Store useful things in the Ellipse structure. */ - if( astOK ) { - astFree( this->centre ); - this->centre = centre; - centre = NULL; - - astFree( this->point1 ); - this->point1 = point1; - point1 = NULL; - - this->a = a; - this->b = b; - this->angle = angle; - } - } - -/* Initialise the bounding box. This is set properly when the astRegBaseMesh - function is called. These variables should not be used unless the - "basemesh" component of the parent Region structure is set to a non-null - value. */ - this->lbx = -DBL_MAX; - this->ubx = DBL_MAX; - this->lby = -DBL_MAX; - this->uby = DBL_MAX; - -/* Free resources */ - frm = astAnnul( frm ); - if( centre ) centre = astFree( centre ); - if( point1 ) point1 = astFree( point1 ); - point2 = astFree( point2 ); - -/* Indicate cached information is up to date. */ - this->stale = 0; - - } -} - -static void CalcPars( AstFrame *frm, double centre[2], double point1[2], - double point2[2], double *a, double *b, - double *angle, int *status ){ -/* -* Name: -* CalcPars - -* Purpose: -* Calculate ellipse parameters. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* void CalcPars( AstFrame *frm, double centre[2], double point1[2], -* double point2[2], double *a, double *b, double *angle, -* int *status ) - -* Class Membership: -* Ellipse member function - -* Description: -* This function uses the supplied positions to calculate the -* geometric parameters of an ellipse. - -* Parameters: -* frm -* Pointer to the Frame in which the positions are defined. -* centre; -* Array holding centre coords. -* point1 -* Array holding coords at end of primary axis -* point2 -* Array holding coords at another point on ellipse. On exit it -* holds the coords at the end of the secondary axis. -* a -* Pointer to location at which to store the half-length of the -* primary axis. -* b -* Pointer to location at which to store the half-length of the -* secondary axis. -* angle -* Pointer to location at which to store the angle from the -* positive direction of the second Frame axis to the primary -* ellipse axis, in radians. Rotation from the second to the first -* Frame axis is positive. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double point3[ 2 ]; /* Array holding a point on the primary axis */ - double x; /* The offset parallel to the primary axis */ - double y; /* The offset perpendicular to the primary axis */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the geodesic distance between the centre and point 1 (the end of - the primary axis of the ellipse). This is the half length of the - primary axis of the ellipse (the axis which joins the centre position to - point 1). */ - *a = astDistance( frm, centre, point1 ); - -/* Find the point (point3) on the primary axis which is closest to point 2, - and thus get the geodesic offsets (resolved parallel and perpendicular to - the primary axis) between the centre and point 2. */ - if( *a > 0.0 ) { - astResolve( frm, centre, point1, point2, point3, &x, &y ); - -/* Find the half-length of the secondary ellipse axis. */ - if( astOK ) { - *b = (*a)*(*a) - x*x; - if( *b > 0.0 ) *b = (*a)*y/sqrt( *b ); - } else { - *b = *a; - } - -/* Find the angle from the positive direction of the second axis to the - primary ellipse axis. */ - point3[ 0 ] = centre[ 0 ]; - point3[ 1 ] = centre[ 1 ] + fabs( 0.1*(*a) ); - *angle = astAngle( frm, point3, centre, point1 ); - -/* Find the end point of the secondary axis. */ - (void) astOffset2( frm, centre, *angle + AST__DPIBY2, *b, point2 ); - } -} - -static void EllipsePars( AstEllipse *this, double centre[2], double *a, - double *b, double *angle, double p1[2], - double p2[2], int *status ){ -/* -*++ -* Name: -c astEllipsePars -f AST_ELLIPSEPARS - -* Purpose: -* Returns the geometric parameters of an Ellipse. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ellipse.h" -c void astEllipsePars( AstEllipse *this, double centre[2], double *a, -c double *b, double *angle, double p1[2], double p2[2] ) -f CALL AST_ELLIPSEPARS( THIS, CENTRE, A, B, ANGLE, P1, P2, STATUS ) - -* Class Membership: -* Region method. - -* Description: -c This function -f This routine -* returns the geometric parameters describing the supplied ellipse. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -c centre -f CENTRE( 2 ) = DOUBLE PRECISION (Returned) -* The coordinates of the Ellipse centre are returned in this arrays. -c a -f A = DOUBLE PRECISION (Returned) -* Returned holding the half-length of the first axis of the -* ellipse. -c b -f B = DOUBLE PRECISION (Returned) -* Returned holding the half-length of the second axis of the -* ellipse. -c angle -f ANGLE = DOUBLE PRECISION (Returned) -* If the coordinate system in which the Ellipse is defined has -* axes (X,Y), then -c "*angle" -f ANGLE -* is returned holding the angle from the positive direction of -* the Y axis to the first axis of the ellipse, in radians. -* Positive rotation is in the same sense as rotation from the -* positive direction of Y to the positive direction of X. -c p1 -f P1( 2 ) = DOUBLE PRECISION (Returned) -* An array in which to return the coordinates at one of the two ends -* of the first axis of the ellipse. -c A NULL pointer can be supplied if these coordinates are not needed. -c p2 -f P2( 2 ) = DOUBLE PRECISION (Returned) -* An array in which to return the coordinates at one of the two ends -* of the second axis of the ellipse. -c A NULL pointer can be supplied if these coordinates are not needed. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the coordinate system represented by the Ellipse has been -* changed since it was first created, the returned parameters refer -* to the new (changed) coordinate system, rather than the original -* coordinate system. Note however that if the transformation from -* original to new coordinate system is non-linear, the shape -* represented by the supplied Ellipse object may not be an accurate -* ellipse. -* - Values of AST__BAD are returned for the parameters without error -* if the ellipse is degenerate or undefined. -*-- -*/ - -/* Local Variables: */ - AstFrame *frm; /* Current Frame represented by the Ellipse */ - AstPointSet *pset; /* PointSet holding PointList axis values */ - AstRegion *this_region; /* Parent Region pointer */ - double **ptr; /* Pointer to axes values in the PointList */ - double *point1; /* Pointer to "p1" or "buf1" */ - double *point2; /* Pointer to "p2" or "buf2" */ - double buf1[2]; /* Local substitute array for "p1" */ - double buf2[2]; /* Local substitute array for "p2" */ - int i; /* Axis index */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Store a pointer to the parent region structure. */ - this_region = (AstRegion *) this; - -/* Transform the base Frame axis values into the current Frame. */ - pset = astTransform( this_region->frameset, this_region->points, 1, NULL ); - -/* Get pointers to the coordinate data. */ - ptr = astGetPoints( pset ); - -/* Choose the arrays to use - supplied arrays if possible, local arrays - otherwise. */ - if( p1 ) { - point1 = p1; - } else { - point1 = buf1; - } - if( p2 ) { - point2 = p2; - } else { - point2 = buf2; - } - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Copy the points in to separate arrays. */ - for( i = 0; i < 2; i++ ) { - centre[ i ] = ptr[ i ][ 0 ]; - point1[ i ] = ptr[ i ][ 1 ]; - point2[ i ] = ptr[ i ][ 2 ]; - } - -/* Get the Ellipse frame. */ - frm = astGetFrame( this_region->frameset, AST__CURRENT ); - -/* Calculate the geometric parameters of the ellipse. */ - CalcPars( frm, centre, point1, point2, a, b, angle, status ); - -/* Ensure no zero values are returned. */ - if( *a <= 0.0 || *b <= 0.0 ) { - *a = AST__BAD; - *b = AST__BAD; - *angle = AST__BAD; - } - -/* Free resources */ - frm = astAnnul( frm ); - } - pset = astAnnul( pset ); -} - -static void RegBaseBox( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* Ellipse member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstEllipse *this; /* Pointer to Ellipse structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Ellipse structure */ - this = (AstEllipse *) this_region; - -/* The bounding box of the mesh returned by astRegBaseMesh is used as the - bounding box of the Ellipse. These bounds are cached in the Ellipse - structure by astRegBaseMesh. Ensure astRegBaseMesh has been invoked, - so that it is safe to use the cached bounding box. */ - if( !this_region->basemesh ) (void) astAnnul( astRegBaseMesh( this ) ); - -/* Store the bounding box. */ - lbnd[ 0 ] = this->lbx; - ubnd[ 0 ] = this->ubx; - lbnd[ 1 ] = this->lby; - ubnd[ 1 ] = this->uby; - -} - -static AstPointSet *RegBaseMesh( AstRegion *this_region, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Return a PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* AstPointSet *astRegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* Ellipse member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. Annul the pointer using astAnnul when it -* is no longer needed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - -/* Local Constants: */ -#define NP_EDGE 50 /* No. of points for determining geodesic */ - -/* Local Variables: */ - AstEllipse *this; /* The Ellipse structure */ - AstFrame *frm; /* Base Frame in encapsulated FrameSet */ - AstPointSet *result; /* Returned pointer */ - AstRegion *reg; /* Copy of supplied Ellipse */ - double **ptr; /* Pointers to data */ - double ang; /* Position angular of primary axis at "dx" */ - double angle; /* Ellipse parametric angle at point */ - double delta; /* Angular separation of points */ - double dist; /* Offset along an axis */ - double dx; /* Primary axis offset */ - double dy; /* Secondary axis offset */ - double lbnd[2]; /* Lower bounding box bounds */ - double lbx; /* Lower x bound of mesh bounding box */ - double lby; /* Lower y bound of mesh bounding box */ - double p2[ 2 ]; /* Position in 2D Frame */ - double p[ 2 ]; /* Position in 2D Frame */ - double ubnd[2]; /* Upper bounding box bounds */ - double ubx; /* Upper x bound of mesh bounding box */ - double uby; /* Upper y bound of mesh bounding box */ - int i; /* Point index */ - int np; /* No. of points in returned PointSet */ - -/* Initialise */ - result= NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the Region structure contains a pointer to a PointSet holding - a previously created mesh, return it. */ - if( this_region->basemesh ) { - result = astClone( this_region->basemesh ); - -/* Otherwise, create a new mesh. */ - } else { - -/* Initialise the bounding box of the mesh points. */ - lbx = DBL_MAX; - ubx = -DBL_MAX; - lby = DBL_MAX; - uby = -DBL_MAX; - -/* Get a pointer to the Ellipse structure. */ - this = (AstEllipse *) this_region; - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* Get a pointer to the base Frame in the encapsulated FrameSet. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Get the requested number of points to put on the mesh. */ - np = astGetMeshSize( this ); - -/* Store the angular increment between points. */ - delta = 2*AST__DPI/np; - -/* Create a suitable PointSet to hold the returned positions. */ - result = astPointSet( np, 2, "", status ); - ptr = astGetPoints( result ); - if( astOK ) { - -/* Loop round each point. The angle is the parametric angle, phi, where - the ellipse is defined by: - - dx = a.cos( phi ) - dy = a.sin( phi ) - - measured from the primary ellipse. Positive in the sense of rotation from - axis 2 to axis 1. */ - angle = 0.0; - for( i = 0; i < np; i++ ) { - -/* Find the offsets from the centre. "dx" is geodesic distance along the - primary axis, and dy is geodesic distance along the secondary axis. */ - dx = this->a*cos( angle ); - dy = this->b*sin( angle ); - -/* Now find the point which corresponds to this dx and dy, taking account - of the potential spherical geometry of hte coordinate system. First - move a distance "dx" from the centre along the primary axis. The - function value returned is the direction of the geodesic curve at the - end point. That is, the angle (in radians) between the positive direction - of the second axis and the continuation of the geodesic curve at the - requested end point. */ - ang = astOffset2( frm, this->centre, this->angle, dx, p ); - -/* Now move a distance "dy" from the point found above at right angles to - the primary axis. */ - astOffset2( frm, p, ang + AST__DPIBY2, dy, p2 ); - -/* Store the resulting axis values. */ - ptr[ 0 ][ i ] = p2[ 0 ]; - ptr[ 1 ][ i ] = p2[ 1 ]; - -/* Update the bounds of the mesh bounding box. The box is expressed in - terms of axis offsets from the centre, in order to avoid problems with - boxes that cross RA=0 or RA=12h */ - if( p2[ 0 ] != AST__BAD && p2[ 1 ] != AST__BAD ){ - - dist = astAxDistance( frm, 1, this->centre[ 0 ], p2[ 0 ] ); - if( dist < lbx ) { - lbx = dist; - } else if( dist > ubx ) { - ubx = dist; - } - - dist = astAxDistance( frm, 1, this->centre[ 1 ], p2[ 1 ] ); - if( dist < lby ) { - lby = dist; - } else if( dist > uby ) { - uby = dist; - } - } - -/* Increment the angular position of the next mesh point. */ - angle += delta; - } - } - -/* Save the returned pointer in the Region structure so that it does not - need to be created again next time this function is called. Also cache - the bounding box in the Ellipse structure. */ - if( astOK && result ) { - this_region->basemesh = astClone( result ); - -/* Extend the bounding box if it contains any singularies. The astNormBox - requires a Mapping which can be used to test points in the base Frame. - Create a copy of the Circle and then set its FrameSet so that the current - Frame in the copy is the same as the base Frame in the original. */ - reg = astCopy( this ); - astSetRegFS( reg, frm ); - astSetNegated( reg, 0 ); - -/* Normalise this box. */ - lbnd[ 0 ] = this->centre[ 0 ] + lbx; - lbnd[ 1 ] = this->centre[ 1 ] + lby; - ubnd[ 0 ] = this->centre[ 0 ] + ubx; - ubnd[ 1 ] = this->centre[ 1 ] + uby; - astNormBox( frm, lbnd, ubnd, reg ); - -/* Save this box */ - this->lbx = lbnd[ 0 ]; - this->ubx = ubnd[ 0 ]; - this->lby = lbnd[ 1 ]; - this->uby = ubnd[ 1 ]; - -/* Free resources. */ - reg = astAnnul( reg ); - } - frm = astAnnul( frm ); - - } - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static double *RegCentre( AstRegion *this_region, double *cen, double **ptr, - int index, int ifrm, int *status ){ -/* -* Name: -* RegCentre - -* Purpose: -* Re-centre a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* double *RegCentre( AstRegion *this, double *cen, double **ptr, -* int index, int ifrm, int *status ) - -* Class Membership: -* Ellipse member function (over-rides the astRegCentre protected -* method inherited from the Region class). - -* Description: -* This function shifts the centre of the supplied Region to a -* specified position, or returns the current centre of the Region. - -* Parameters: -* this -* Pointer to the Region. -* cen -* Pointer to an array of axis values, giving the new centre. -* Supply a NULL value for this in order to use "ptr" and "index" to -* specify the new centre. -* ptr -* Pointer to an array of points, one for each axis in the Region. -* Each pointer locates an array of axis values. This is the format -* returned by the PointSet method astGetPoints. Only used if "cen" -* is NULL. -* index -* The index of the point within the arrays identified by "ptr" at -* which is stored the coords for the new centre position. Only used -* if "cen" is NULL. -* ifrm -* Should be AST__BASE or AST__CURRENT. Indicates whether the centre -* position is supplied and returned in the base or current Frame of -* the FrameSet encapsulated within "this". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If both "cen" and "ptr" are NULL then a pointer to a newly -* allocated dynamic array is returned which contains the centre -* coords of the Region. This array should be freed using astFree when -* no longer needed. If either of "ptr" or "cen" is not NULL, then a -* NULL pointer is returned. - -* Notes: -* - Some Region sub-classes do not have a centre. Such classes will report -* an AST__INTER error code if this method is called. -*/ - -/* Local Variables: */ - AstEllipse *this; /* Pointer to Ellipse structure */ - AstFrame *frm; /* Base Frame */ - double **rptr; /* Data pointers for Region PointSet */ - double *bc; /* Base Frame centre position */ - double *result; /* Returned pointer */ - double *tmp; /* Temporary array pointer */ - double a[ 2 ]; /* Original position */ - double angle; /* Orietentation of offset from old to new centre */ - double axval; /* Axis value */ - double b[ 2 ]; /* New position */ - double dist; /* Distance from old to new centre */ - double newcen[ 2 ]; /* New centre */ - int ic; /* Coordinate index */ - int ip; /* Position index */ - int ncb; /* Number of base frame coordinate values per point */ - int ncc; /* Number of current frame coordinate values per point */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Ellipse structure. */ - this = (AstEllipse *) this_region; - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* Get the number of axis values per point in the current Frame. */ - ncc = astGetNout( this_region->frameset ); - -/* An ellipse always has 2 base frame axes. */ - ncb = 2; - -/* If the centre coords are to be returned, return either a copy of the - base Frame centre coords, or transform the base Frame centre coords - into the current Frame. */ - if( !ptr && !cen ) { - if( ifrm == AST__CURRENT ) { - result = astRegTranPoint( this_region, this->centre, 1, 1 ); - } else { - result = astStore( NULL, this->centre, sizeof( double )*ncb ); - } - -/* Otherwise, we store the supplied new centre coords and return a NULL - pointer. */ - } else { - -/* Get a pointer to the axis values stored in the Region structure. */ - rptr = astGetPoints( this_region->points ); - -/* Check pointers can be used safely */ - if( astOK ) { - -/* If the centre position was supplied in the current Frame, find the - corresponding base Frame position... */ - if( ifrm == AST__CURRENT ) { - if( cen ) { - bc = astRegTranPoint( this_region, cen, 1, 0 ); - } else { - tmp = astMalloc( sizeof( double)*(size_t)ncc ); - if( astOK ) { - for( ic = 0; ic < ncc; ic++ ) tmp[ ic ] = ptr[ ic ][ index ]; - } - bc = astRegTranPoint( this_region, tmp, 1, 0 ); - tmp = astFree( tmp ); - } - -/* Replace any bad centre values with their current values. */ - for( ic = 0; ic < ncb; ic++ ) { - if( bc[ ic ] == AST__BAD ) bc[ ic ] = this->centre[ ic ]; - } - -/* If the centre position was supplied in the base Frame, use the - supplied "cen" or "ptr" pointer directly to change the coords in the - parent Region structure and the cached coords in the Ellipse structure. */ - } else { - bc = newcen; - for( ic = 0; ic < ncb; ic++ ) { - axval = cen ? cen[ ic ] : ptr[ ic ][ index ]; - newcen[ ic ] = ( axval != AST__BAD ) ? axval : this->centre[ ic ]; - } - } - -/* Find the direction and length of the offset between the old and new - centre. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - angle = astAxAngle( frm, this->centre, bc, 2 ); - dist = astDistance( frm, this->centre, bc ); - -/* Shift each point in the parent Region structure by the same length and - direction. */ - for( ip = 0; ip < 3; ip++ ) { - a[ 0 ] = rptr[ ip ][ 0 ]; - a[ 1 ] = rptr[ ip ][ 1 ]; - astOffset2( frm, a, angle, dist, b ); - rptr[ ip ][ 0 ] = b[ 0 ]; - rptr[ ip ][ 1 ] = b[ 1 ]; - } - -/* Indicate that the cache is stale. */ - astResetCache( this ); - -/* Free resources */ - frm = astAnnul( frm ); - if( bc != newcen ) bc = astFree( bc ); - } - } - -/* Return the result. */ - return result; -} - -static int RegPins( AstRegion *this_region, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -* Name: -* RegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given Ellipse. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask, int *status ) - -* Class Membership: -* Ellipse member function (over-rides the astRegPins protected -* method inherited from the Region class). - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given Ellipse. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied Ellipse "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the Ellipse. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "pset". -* Each element in the returned array is set to 1 if the -* corresponding position in "pset" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*/ - -/* Local variables: */ - AstEllipse *large_ellipse; /* Ellipse slightly larger than "this" */ - AstEllipse *small_ellipse; /* Ellipse slightly smaller than "this" */ - AstEllipse *this; /* Pointer to the Ellipse structure. */ - AstFrame *frm; /* Base Frame in supplied Ellipse */ - AstPointSet *ps1; /* Points masked by larger Ellipse */ - AstPointSet *ps2; /* Points masked by larger and smaller Ellipsees */ - AstRegion *tunc; /* Uncertainity Region from "this" */ - double **ptr; /* Pointer to axis values in "ps2" */ - double *p; /* Pointer to next axis value */ - double *safe; /* An interior point in "this" */ - double drad; /* Radius increment corresponding to border width */ - double l1; /* Length of bounding box diagonal */ - double l2; /* Length of bounding box diagonal */ - double lbnd_tunc[2]; /* Lower bounds of "this" uncertainty Region */ - double lbnd_unc[2]; /* Lower bounds of supplied uncertainty Region */ - double lim; /* Smallest semi-minor/major axis length */ - double p1[2]; /* New ellipse axis lengths */ - double ubnd_tunc[2]; /* Upper bounds of "this" uncertainty Region */ - double ubnd_unc[2]; /* Upper bounds of supplied uncertainty Region */ - int i; /* Axis index */ - int j; /* Point index */ - int np; /* No. of supplied points */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - if( mask ) *mask = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the Ellipse structure. */ - this = (AstEllipse *) this_region; - -/* Check the supplied PointSet has 2 axis values per point. */ - if( astGetNcoord( pset ) != 2 && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axis " - "values per point (%d) in the supplied PointSet - should be " - "2 (internal AST programming error).", status, astGetClass( this ), - astGetNcoord( pset ) ); - } - -/* Get the number of axes in the uncertainty Region and check it is also 2. */ - if( unc && astGetNaxes( unc ) != 2 && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axes (%d) " - "in the supplied uncertainty Region - should be 2 " - "(internal AST programming error).", status, astGetClass( this ), - astGetNaxes( unc ) ); - } - -/* Get the centre of the region in the base Frame. We use this as a "safe" - interior point within the region. */ - safe = astRegCentre( this, NULL, NULL, 0, AST__BASE ); - -/* We now find the maximum distance on each axis that a point can be from the - boundary of the Ellipse for it still to be considered to be on the boundary. - First get the Region which defines the uncertainty within the Ellipse being - checked (in its base Frame), re-centre it on the interior point found - above (to avoid problems if the uncertainty region straddles a - discontinuity), and get its bounding box. */ - tunc = astGetUncFrm( this, AST__BASE ); - if( safe ) astRegCentre( tunc, safe, NULL, 0, AST__CURRENT ); - astGetRegionBounds( tunc, lbnd_tunc, ubnd_tunc ); - -/* Find the geodesic length within the base Frame of "this" of the diagonal of - the bounding box. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - l1 = astDistance( frm, lbnd_tunc, ubnd_tunc ); - -/* Also get the Region which defines the uncertainty of the supplied - points and get its bounding box. First re-centre the uncertainty at the - interior position to avoid problems from uncertainties that straddle a - discontinuity. */ - if( unc ) { - if( safe ) astRegCentre( unc, safe, NULL, 0, AST__CURRENT ); - astGetRegionBounds( unc, lbnd_unc, ubnd_unc ); - -/* Find the geodesic length of the diagonal of this bounding box. */ - l2 = astDistance( frm, lbnd_unc, ubnd_unc ); - -/* Assume zero uncertainty if no "unc" Region was supplied. */ - } else { - l2 = 0.0; - } - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* The required border width is half of the total diagonal of the two bounding - boxes. */ - if( astOK ) { - drad = 0.5*( l1 + l2 ); - -/* Create two new Ellipse, one of which is larger than "this" by the amount - found above, and the other of which is smaller than "this" by the amount - found above. */ - p1[ 0 ] = this->a + 0.5*drad; - p1[ 1 ] = this->b + 0.5*drad; - large_ellipse = astEllipse( frm, 1, this->centre, p1, &(this->angle), - NULL, " ", status ); - - p1[ 0 ] = this->a - 0.5*drad; - p1[ 1 ] = this->b - 0.5*drad; - lim = 1.0E-6*drad; - if( p1[ 0 ] < lim ) p1[ 0 ] = lim; - if( p1[ 1 ] < lim ) p1[ 1 ] = lim; - small_ellipse = astEllipse( frm, 1, this->centre, p1, &(this->angle), - NULL, " ", status ); - -/* Negate the smaller region.*/ - astNegate( small_ellipse ); - -/* Points are on the boundary of "this" if they are inside both the large - Ellipse and the negated small Ellipse. First transform the supplied PointSet - using the large Ellipse, then transform them using the negated smaller - Ellipse. */ - ps1 = astTransform( large_ellipse, pset, 1, NULL ); - ps2 = astTransform( small_ellipse, ps1, 1, NULL ); - -/* Get a point to the resulting axis values, and the number of axis - values per axis. */ - ptr = astGetPoints( ps2 ); - np = astGetNpoint( ps2 ); - -/* If a mask array is to be returned, create one. */ - if( mask ) { - *mask = astMalloc( sizeof(int)*(size_t) np ); - -/* Check all the resulting points, setting mask values for all of them. */ - if( astOK ) { - -/* Initialise the mask elements on the basis of the first axis values */ - result = 1; - p = ptr[ 0 ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ j ] = 0; - } else { - (*mask)[ j ] = 1; - } - } - -/* Now check for bad values on other axes. */ - for( i = 1; i < 2; i++ ) { - p = ptr[ i ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ j ] = 0; - } - } - } - } - -/* If no output mask is to be made, we can break out of the check as soon - as the first bad value is found. */ - } else if( astOK ) { - result = 1; - for( i = 0; i < 2 && result; i++ ) { - p = ptr[ i ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - break; - } - } - } - } - -/* Free resources. */ - large_ellipse = astAnnul( large_ellipse ); - small_ellipse = astAnnul( small_ellipse ); - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - } - - tunc = astAnnul( tunc ); - frm = astAnnul( frm ); - safe = astFree( safe ); - -/* If an error has occurred, return zero. */ - if( !astOK ) { - result = 0; - if( mask ) *mask = astAnnul( *mask ); - } - -/* Return the result. */ - return result; -} - -static int RegTrace( AstRegion *this_region, int n, double *dist, double **ptr, - int *status ){ -/* -*+ -* Name: -* RegTrace - -* Purpose: -* Return requested positions on the boundary of a 2D Region. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* int astTraceRegion( AstRegion *this, int n, double *dist, double **ptr ); - -* Class Membership: -* Ellipse member function (overrides the astTraceRegion method -* inherited from the parent Region class). - -* Description: -* This function returns positions on the boundary of the supplied -* Region, if possible. The required positions are indicated by a -* supplied list of scalar parameter values in the range zero to one. -* Zero corresponds to some arbitrary starting point on the boundary, -* and one corresponds to the end (which for a closed region will be -* the same place as the start). - -* Parameters: -* this -* Pointer to the Region. -* n -* The number of positions to return. If this is zero, the function -* returns without action (but the returned function value still -* indicates if the method is supported or not). -* dist -* Pointer to an array of "n" scalar parameter values in the range -* 0 to 1.0. -* ptr -* A pointer to an array of pointers. The number of elements in -* this array should equal tthe number of axes in the Frame spanned -* by the Region. Each element of the array should be a pointer to -* an array of "n" doubles, in which to return the "n" values for -* the corresponding axis. The contents of the arrays are unchanged -* if the supplied Region belongs to a class that does not -* implement this method. - -* Returned Value: -* Non-zero if the astTraceRegion method is implemented by the class -* of Region supplied, and zero if not. - -*- -*/ - -/* Local Variables; */ - AstEllipse *this; - AstFrame *frm; - AstMapping *map; - AstPointSet *bpset; - AstPointSet *cpset; - double **bptr; - double ang; - double angle; - double dx; - double dy; - double p2[ 2 ]; - double p[ 2 ]; - int i; - int ncur; - -/* Check inherited status, and the number of points to return, returning - a non-zero value to indicate that this class supports the astRegTrace - method. */ - if( ! astOK || n == 0 ) return 1; - -/* Get a pointer to the Ellipse structure. */ - this = (AstEllipse *) this_region; - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* Get a pointer to the base Frame in the encapsulated FrameSet. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* We first determine the required positions in the base Frame of the - Region, and then transform them into the current Frame. Get the - base->current Mapping, and the number of current Frame axes. */ - map = astGetMapping( this_region->frameset, AST__BASE, AST__CURRENT ); - -/* If it's a UnitMap we do not need to do the transformation, so put the - base Frame positions directly into the supplied arrays. */ - if( astIsAUnitMap( map ) ) { - bpset = NULL; - bptr = ptr; - ncur = 2; - -/* Otherwise, create a PointSet to hold the base Frame positions (known - to be 2D since this is an ellipse). */ - } else { - bpset = astPointSet( n, 2, " ", status ); - bptr = astGetPoints( bpset ); - ncur = astGetNout( map ); - } - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Loop round each point. */ - for( i = 0; i < n; i++ ) { - -/* The supplied scalar parameter values are the parametric angles, phi, - where the ellipse is defined by: - - dx = a.cos( phi ) - dy = a.sin( phi ) - - measured from the primary ellipse. Positive in the sense of rotation from - axis 2 to axis 1. */ - angle = dist[ i ]*2*AST__DPI; - -/* Find the offsets from the centre. "dx" is geodesic distance along the - primary axis, and dy is geodesic distance along the secondary axis. */ - dx = this->a*cos( angle ); - dy = this->b*sin( angle ); - -/* Now find the point which corresponds to this dx and dy, taking account - of the potential spherical geometry of hte coordinate system. First - move a distance "dx" from the centre along the primary axis. The - function value returned is the direction of the geodesic curve at the - end point. That is, the angle (in radians) between the positive direction - of the second axis and the continuation of the geodesic curve at the - requested end point. */ - ang = astOffset2( frm, this->centre, this->angle, dx, p ); - -/* Now move a distance "dy" from the point found above at right angles to - the primary axis. */ - astOffset2( frm, p, ang + AST__DPIBY2, dy, p2 ); - -/* Store the resulting axis values. */ - bptr[ 0 ][ i ] = p2[ 0 ]; - bptr[ 1 ][ i ] = p2[ 1 ]; - } - } - -/* If required, transform the base frame positions into the current - Frame, storing them in the supplied array. Then free resources. */ - if( bpset ) { - cpset = astPointSet( n, ncur, " ", status ); - astSetPoints( cpset, ptr ); - - (void) astTransform( map, bpset, 1, cpset ); - - cpset = astAnnul( cpset ); - bpset = astAnnul( bpset ); - } - -/* Free remaining resources. */ - map = astAnnul( map ); - frm = astAnnul( frm ); - -/* Return a non-zero value to indicate that this class supports the - astRegTrace method. */ - return 1; -} - -static void ResetCache( AstRegion *this, int *status ){ -/* -* Name: -* ResetCache - -* Purpose: -* Clear cached information within the supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* void ResetCache( AstRegion *this, int *status ) - -* Class Membership: -* Region member function (overrides the astResetCache method -* inherited from the parent Region class). - -* Description: -* This function clears cached information from the supplied Region -* structure. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. -*/ - if( this ) { - ( (AstEllipse *) this )->stale = 1; - (*parent_resetcache)( this, status ); - } -} - -static void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) { -/* -* Name: -* SetRegFS - -* Purpose: -* Stores a new FrameSet in a Region - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) - -* Class Membership: -* Ellipse method (over-rides the astSetRegFS method inherited from -* the Region class). - -* Description: -* This function creates a new FrameSet and stores it in the supplied -* Region. The new FrameSet contains two copies of the supplied -* Frame, connected by a UnitMap. - -* Parameters: -* this -* Pointer to the Region. -* frm -* The Frame to use. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent method to store the FrameSet in the parent Region - structure. */ - (* parent_setregfs)( this_region, frm, status ); - -/* Indicate that cached information will need to be re-calculated before - it is next used. */ - astResetCache( this_region ); -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mapping represented by a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* Ellipse method (over-rides the astSimplify method inherited -* from the Region class). - -* Description: -* This function invokes the parent Region Simplify method, and then -* performs any further region-specific simplification. -* -* If the Mapping from base to current Frame is not a UnitMap, this -* will include attempting to fit a new Region to the boundary defined -* in the current Frame. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the simplified Region. A cloned pointer to the -* supplied Region will be returned if no simplication could be -* performed. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstMapping *map; /* Base -> current Mapping */ - AstMapping *result; /* Result pointer to return */ - AstPointSet *mesh; /* Mesh of current Frame positions */ - AstPointSet *ps2; /* Ellipse PointSet in current Frame */ - AstRegion *new; /* Pointer to simplified Region */ - AstRegion *newreg; /* Equivalent circle or ellipse */ - AstRegion *this; /* Pointer to supplied Region structure */ - AstRegion *unc; /* Pointer to uncertainty Region */ - double **ptr2; /* Pointer axis values in "ps2" */ - double *cen; /* Pointer to array holding new centre coords */ - int ic; /* Axis index */ - int nc; /* No. of axis values per point */ - int ok; /* Was the new centre found OK? */ - int simpler; /* Has some simplication taken place? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the supplied Region structure. */ - this = (AstRegion *) this_mapping; - -/* Invoke the parent Simplify method inherited from the Region class. This - will simplify the encapsulated FrameSet and uncertainty Region. */ - new = (AstRegion *) (*parent_simplify)( this_mapping, status ); - -/* Note if any simplification took place. This is assumed to be the case - if the pointer returned by the above call is different to the supplied - pointer. */ - simpler = ( new != this ); - -/* We attempt to simplify the Ellipse by re-defining it within its current - Frame. Transforming the Ellipse from its base to its current Frame may - result in the region no longer being an ellipse. We test this by - transforming a set of bounds on the Ellipse boundary. */ - map = astGetMapping( new->frameset, AST__BASE, AST__CURRENT ); - -/* Get a mesh of points covering the Ellipse in its current Frame. */ - mesh = astRegMesh( new ); - -/* Get the Region describing the positional uncertainty within the Ellipse in - its current Frame. */ - unc = astGetUncFrm( new, AST__CURRENT ); - -/* Transform the PointSet holding the ellipse centre into the current - Frame, and copy the axis values into a new array. */ - ps2 = astRegTransform( this, this->points, 1, NULL, NULL ); - nc = astGetNcoord( ps2 ); - cen = astMalloc( sizeof( double )*(size_t) nc ); - ptr2 = astGetPoints( ps2 ); - if( astOK ) { - ok = 1; - for( ic = 0; ic < nc; ic++ ) { - cen[ ic ] = ptr2[ ic ][ 0 ]; - if( cen[ ic ] == AST__BAD ) ok = 0; - } - -/* Find the best fitting Circle (defined in the current Frame) through these - points */ - newreg = ok ? astBestCircle( mesh, cen, unc ) : NULL; - -/* See if all points within this mesh fall on the boundary of the best - fitting Circle, to within the uncertainty of the Region. */ - if( newreg && astRegPins( newreg, mesh, NULL, NULL ) ) { - -/* If so, use the new Circle in place of the original Region. */ - (void) astAnnul( new ); - new = astClone( newreg ); - simpler =1; - -/* Otherwise, if the region is 2-d we see if an Ellipse can represent the - mesh. */ - } else if( ok && nc == 2 ){ - -/* Find the best fitting Ellipse (defined in the current Frame) through these - points */ - if( newreg ) (void) astAnnul( newreg ); - newreg = astBestEllipse( mesh, cen, unc ); - -/* See if all points within this mesh fall on the boundary of the best - fitting Ellipse, to within the uncertainty of the Region. */ - if( newreg && astRegPins( newreg, mesh, NULL, NULL ) ) { - -/* If so, use the new Ellipse in place of the original Region. */ - (void) astAnnul( new ); - new = astClone( newreg ); - simpler = 1; - } - } - -/* Free resources. */ - if( newreg ) newreg = astAnnul( newreg ); - } - - ps2 = astAnnul( ps2 ); - cen = astFree( cen ); - mesh = astAnnul( mesh ); - unc = astAnnul( unc ); - map = astAnnul( map ); - -/* If any simplification could be performed, copy Region attributes from - the supplied Region to the returned Region, and return a pointer to it. - If the supplied Region had no uncertainty, ensure the returned Region - has no uncertainty. Otherwise, return a clone of the supplied pointer. */ - if( simpler ){ - astRegOverlay( new, this, 1 ); - result = (AstMapping *) new; - - } else { - new = astAnnul( new ); - result = astClone( this ); - } - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a Ellipse to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* Ellipse member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a Ellipse and a set of points encapsulated in a -* PointSet and transforms the points by setting axis values to -* AST__BAD for all points which are outside the region. Points inside -* the region are copied unchanged from input to output. - -* Parameters: -* this -* Pointer to the Ellipse. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - The forward and inverse transformations are identical for a -* Region. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of axes in the Frame represented by the Ellipse. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstEllipse *this; /* Pointer to Ellipse */ - AstFrame *frm; /* Pointer to base Frame in FrameSet */ - AstPointSet *pset_res; /* Pointer to PointSet holding resolved components */ - AstPointSet *pset_tmp; /* Pointer to PointSet holding base Frame positions*/ - AstPointSet *result; /* Pointer to output PointSet */ - double **ptr_out; /* Pointer to output coordinate data */ - double **ptr_res; /* Pointer to resolved components coordinate data */ - double *px; /* Pointer to array of primary axis components */ - double *py; /* Pointer to array of secondary axis components */ - double c1; /* Constant */ - double c2; /* Constant */ - double d; /* Elliptical distance to current point */ - int closed; /* Is the boundary part of the Region? */ - int coord; /* Zero-based index for coordinates */ - int inside; /* Is the point inside the Region? */ - int ncoord_out; /* No. of coordinates per output point */ - int neg; /* Has the Region been negated? */ - int npoint; /* No. of points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the Ellipse structure. */ - this = (AstEllipse *) this_mapping; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, - containing a copy of the input PointSet. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* First use the encapsulated FrameSet to transform the supplied positions - from the current Frame in the encapsulated FrameSet (the Frame - represented by the Region), to the base Frame (the Frame in which the - Region is defined). This call also returns a pointer to the base Frame - of the encapsulated FrameSet. Note, the returned pointer may be a - clone of the "in" pointer, and so we must be carefull not to modify the - contents of the returned PointSet. */ - pset_tmp = astRegTransform( this, in, 0, NULL, &frm ); - -/* Resolve all the base Frame positions into components parallel to and - perpendicular to the primary axis, relative to the ellipse centre. The - components are returned in a new PointSet. */ - pset_res = astResolvePoints( frm, this->centre, this->point1, pset_tmp, NULL ); - -/* Determine the numbers of points from the component PointSet and obtain - pointers for accessing the component and output coordinate values. */ - npoint = astGetNpoint( pset_res ); - ptr_res = astGetPoints( pset_res ); - ncoord_out = astGetNcoord( result ); - ptr_out = astGetPoints( result ); - -/* See if the boundary is part of the Region. */ - closed = astGetClosed( this ); - -/* See if the Region has been negated. */ - neg = astGetNegated( this ); - -/* Form some frequently needed constants. */ - c1 = 1.0/(this->a*this->a); - c2 = 1.0/(this->b*this->b); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - px = ptr_res[ 0 ]; - py = ptr_res[ 1 ]; - -/* Loop round each point */ - for ( point = 0; point < npoint; point++, px++, py++ ) { - -/* Bad input points result in bad output points */ - if( *px == AST__BAD || *py == AST__BAD ) { - inside = 0; - -/* If the input points are good... */ - } else { - -/* Find the elliptical distance from the centre to the supplied point (the - ellipse circumference has an "elliptical distance" of 1.0 at all points).*/ - d = c1*(*px)*(*px) + c2*(*py)*(*py); - -/* Now consider whether this radius value puts the point in or out of the - Ellipse. */ - if( d != AST__BAD ){ - if( neg ) { - if( closed ) { - inside = ( d >= 1.0 ); - } else { - inside = ( d > 1.0 ); - } - } else { - if( closed ) { - inside = ( d <= 1.0 ); - } else { - inside = ( d < 1.0 ); - } - } - } else { - inside = 0; - } - } - -/* If the point is outside, store bad output values. */ - if( !inside ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - } - -/* Free resources */ - pset_tmp = astAnnul( pset_tmp ); - pset_res = astAnnul( pset_res ); - frm = astAnnul( frm ); - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Ellipse objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Ellipse objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstEllipse *in; /* Pointer to input Ellipse */ - AstEllipse *out; /* Pointer to output Ellipse */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Ellipses. */ - in = (AstEllipse *) objin; - out = (AstEllipse *) objout; - -/* For safety, first clear any references to the input memory from - the output Ellipse. */ - out->centre = NULL; - out->point1 = NULL; - -/* Copy dynamic memory contents */ - out->centre = astStore( NULL, in->centre, sizeof( double )*2 ); - out->point1 = astStore( NULL, in->point1, sizeof( double )*2 ); -} - - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Ellipse objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Ellipse objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstEllipse *this; /* Pointer to Ellipse */ - -/* Obtain a pointer to the Ellipse structure. */ - this = (AstEllipse *) obj; - -/* Annul all resources. */ - this->centre = astFree( this->centre ); - this->point1 = astFree( this->point1 ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Ellipse objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Ellipse class to an output Channel. - -* Parameters: -* this -* Pointer to the Ellipse whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstEllipse *this; /* Pointer to the Ellipse structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Ellipse structure. */ - this = (AstEllipse *) this_object; - -/* Write out values representing the instance variables for the - Ellipse class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* There are no values to write, so return without further action. */ -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAEllipse and astCheckEllipse functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Ellipse,Region) -astMAKE_CHECK(Ellipse) - -AstEllipse *astEllipse_( void *frame_void, int form, const double centre[2], - const double point1[2], const double point2[2], - AstRegion *unc, const char *options, int *status, ...) { -/* -*++ -* Name: -c astEllipse -f AST_ELLIPSE - -* Purpose: -* Create a Ellipse. - -* Type: -* Public function. - -* Synopsis: -c #include "ellipse.h" -c AstEllipse *astEllipse( AstFrame *frame, int form, const double centre[2], -c const double point1[2], const double point2[2], -c AstRegion *unc, const char *options, ... ) -f RESULT = AST_ELLIPSE( FRAME, FORM, CENTRE, POINT1, POINT2, UNC, OPTIONS, -f STATUS ) - -* Class Membership: -* Ellipse constructor. - -* Description: -* This function creates a new Ellipse and optionally initialises its -* attributes. -* -* A Ellipse is a Region which represents a elliptical area within the -* supplied 2-dimensional Frame. - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* A pointer to the Frame in which the region is defined. It must -* have exactly 2 axes. A deep copy is taken of the supplied Frame. -* This means that any subsequent changes made to the Frame using the -* supplied pointer will have no effect the Region. -c form -f FORM = INTEGER (Given) -* Indicates how the ellipse is described by the remaining parameters. -* A value of zero indicates that the ellipse is specified by a -* centre position and two positions on the circumference. A value of -* one indicates that the ellipse is specified by its centre position, -* the half-lengths of its two axes, and the orientation of its first -* axis. -c centre -f CENTRE( 2 ) = DOUBLE PRECISION (Given) -c An array of 2 doubles, -f An array -* containing the coordinates at the centre of -* the ellipse. -c point1 -f POINT1( 2 ) = DOUBLE PRECISION (Given) -c An array of 2 doubles. If "form" -f If FORM -* is zero, this array should contain the coordinates of one of the four -* points where an axis of the ellipse crosses the circumference of the -* ellipse. -c If "form" -f If FORM -* is one, it should contain the lengths of semi-major and -* semi-minor axes of the ellipse, given as geodesic distances -* within the Frame. -c point2 -f POINT2( 2 ) = DOUBLE PRECISION (Given) -c An array of 2 doubles. If "form" -f If FORM -* is zero, this array should containing the coordinates at some other -* point on the circumference of the ellipse, distinct from -c "point1". If "form" -f POINT1. If FORM -* is one, the first element of this array should hold the angle -* between the second axis of the Frame and the first ellipse axis -* (i.e. the ellipse axis which is specified first in the -c "point1" -f POINT1 -* array), and the second element will be ignored. The angle should be -* given in radians, measured positive in the same sense as rotation -* from the positive direction of the second Frame axis to the positive -* direction of the first Frame axis. -c unc -f UNC = INTEGER (Given) -* An optional pointer to an existing Region which specifies the -* uncertainties associated with the boundary of the Ellipse being created. -* The uncertainty in any point on the boundary of the Ellipse is found by -* shifting the supplied "uncertainty" Region so that it is centred at -* the boundary point being considered. The area covered by the -* shifted uncertainty Region then represents the uncertainty in the -* boundary position. The uncertainty is assumed to be the same for -* all points. -* -* If supplied, the uncertainty Region must be of a class for which -* all instances are centro-symetric (e.g. Box, Circle, Ellipse, etc.) -* or be a Prism containing centro-symetric component Regions. A deep -* copy of the supplied Region will be taken, so subsequent changes to -* the uncertainty Region using the supplied pointer will have no -* effect on the created Ellipse. Alternatively, -f a null Object pointer (AST__NULL) -c a NULL Object pointer -* may be supplied, in which case a default uncertainty is used -* equivalent to a box 1.0E-6 of the size of the Ellipse being created. -* -* The uncertainty Region has two uses: 1) when the -c astOverlap -f AST_OVERLAP -* function compares two Regions for equality the uncertainty -* Region is used to determine the tolerance on the comparison, and 2) -* when a Region is mapped into a different coordinate system and -* subsequently simplified (using -c astSimplify), -f AST_SIMPLIFY), -* the uncertainties are used to determine if the transformed boundary -* can be accurately represented by a specific shape of Region. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Ellipse. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Ellipse. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astEllipse() -f AST_ELLIPSE = INTEGER -* A pointer to the new Ellipse. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstEllipse *new; /* Pointer to new Ellipse */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the supplied Frame structure. */ - frame = astCheckFrame( frame_void ); - -/* Initialise the Ellipse, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitEllipse( NULL, sizeof( AstEllipse ), !class_init, &class_vtab, - "Ellipse", frame, form, centre, point1, point2, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Ellipse's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Ellipse. */ - return new; -} - -AstEllipse *astEllipseId_( void *frame_void, int form, const double centre[2], - const double point1[2], const double point2[2], - void *unc_void, const char *options, ... ) { -/* -* Name: -* astEllipseId_ - -* Purpose: -* Create a Ellipse. - -* Type: -* Private function. - -* Synopsis: -* #include "ellipse.h" -* AstEllipse *astEllipseId( void *frame_void, int form, const double centre[2], -* const double point1[2], const double point2[2], -* void *unc_void, const char *options, ..., int *status ) - -* Class Membership: -* Ellipse constructor. - -* Description: -* This function implements the external (public) interface to the -* astEllipse constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astEllipse_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astEllipse_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astEllipse_. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The ID value associated with the new Ellipse. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstEllipse *new; /* Pointer to new Ellipse */ - AstRegion *unc; /* Pointer to Region structure */ - va_list args; /* Variable argument list */ - - int *status; /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Frame pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Frame. */ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - -/* Obtain a Region pointer from the supplied "unc" ID and validate the - pointer to ensure it identifies a valid Region . */ - unc = unc_void ? astCheckRegion( astMakePointer( unc_void ) ) : NULL; - -/* Initialise the Ellipse, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitEllipse( NULL, sizeof( AstEllipse ), !class_init, &class_vtab, - "Ellipse", frame, form, centre, point1, point2, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Ellipse's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Ellipse. */ - return astMakeId( new ); -} - -AstEllipse *astInitEllipse_( void *mem, size_t size, int init, AstEllipseVtab *vtab, - const char *name, AstFrame *frame, int form, - const double centre[2], const double point1[2], - const double point2[2], AstRegion *unc, int *status ){ -/* -*+ -* Name: -* astInitEllipse - -* Purpose: -* Initialise a Ellipse. - -* Type: -* Protected function. - -* Synopsis: -* #include "ellipse.h" -* AstEllipse *astInitEllipse( void *mem, size_t size, int init, -* AstEllipseVtab *vtab, const char *name, -* AstFrame *frame, const double centre[2], -* const double point1[2], const double point2[2], -* AstRegion *unc ) - -* Class Membership: -* Ellipse initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Ellipse object. It allocates memory (if necessary) to accommodate -* the Ellipse plus any additional data associated with the derived class. -* It then initialises a Ellipse structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Ellipse at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Ellipse is to be initialised. -* This must be of sufficient size to accommodate the Ellipse data -* (sizeof(Ellipse)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Ellipse (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Ellipse -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Ellipse's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Ellipse. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* A pointer to the Frame in which the region is defined. -* form -* Indicates how the "point" parameter should be interpreted. -* Should be either 0 or 1. -* centre -* An array of double, with one element for each Frame axis (Naxes -* attribute) containing the coordinates of the ellipse centre. -* point1 -* An array of double, with one element for each Frame axis (Naxes -* attribute). If "form" is zero, it should contain the coordinates at -* the end of one of the axes of the ellipse. If "form" is one, it -* should contain the semi-major and semi-minor axes of the ellipse. -* point2 -* An array of double, with one element for each Frame axis (Naxes -* attribute). If "form" is zero, it should contain the coordinates at -* some other point on the circumference of the ellipse. If "form" is -* one, element [1] is ignored and element [0] should contain the -* angle from the second frame axis to the first ellipse axis, given in -* radians, measured positive in the same sense as rotation from the -* positive direction of the second Frame axis to the positive -* direction of the first Frame axis. The "first" ellipse axis is -* whichever of the semi-major or semi-minor axis is specified first in -* the "point1" array. -* unc -* A pointer to a Region which specifies the uncertainty in the -* supplied positions (all points on the boundary of the new Ellipse -* being initialised are assumed to have the same uncertainty). A NULL -* pointer can be supplied, in which case default uncertainties equal to -* 1.0E-6 of the dimensions of the new Ellipse's bounding box are used. -* If an uncertainty Region is supplied, it must be either a Box, a -* Circle or an Ellipse, and its encapsulated Frame must be related -* to the Frame supplied for parameter "frame" (i.e. astConvert -* should be able to find a Mapping between them). Two positions -* the "frame" Frame are considered to be co-incident if their -* uncertainty Regions overlap. The centre of the supplied -* uncertainty Region is immaterial since it will be re-centred on the -* point being tested before use. A deep copy is taken of the supplied -* Region. - -* Returned Value: -* A pointer to the new Ellipse. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstEllipse *new; /* Pointer to new Ellipse */ - AstPointSet *pset; /* PointSet to pass to Region initialiser */ - double **ptr; /* Pointer to coords data in pset */ - const double *p1; /* Pointer to circumference point 1 */ - const double *p2; /* Pointer to circumference point 2 */ - int i; /* axis index */ - int nc; /* No. of axes */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitEllipseVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check the supplied value for "form" is legal. */ - if( form != 0 && form != 1 && astOK ) { - astError( AST__BADIN, "astInitEllipse(%s): The value supplied for " - "parameter \"form\" (%d) is illegal - it should be 0 or 1 " - "(programming error).", status, name, form ); - } - -/* Get the number of axis values required for each position. */ - nc = astGetNaxes( frame ); - -/* Report an error if the Frame is not 2-dimensional. */ - if( nc != 2 ) { - astError( AST__BADIN, "astInitEllipse(%s): The supplied %s has %d " - "axes - ellipses must have exactly 2 axes.", status, name, - astGetClass( frame ), nc ); - } - -/* If the ellipse is specified by axis lengths and orientation, find two - points on the circumference (ends of the two ellipse axes). */ - if( form == 1 ) { - p1 = astMalloc( sizeof( double )*2 ); - p2 = astMalloc( sizeof( double )*2 ); - if( astOK ) { - astOffset2( frame, centre, *point2, point1[ 0 ], (double *) p1 ); - astOffset2( frame, centre, *point2 + AST__DPIBY2, point1[ 1 ], - (double *) p2 ); - } - -/* If the ellipse is specified by two points on the circumference, use - them. */ - } else { - p1 = point1; - p2 = point2; - } - -/* Create a PointSet to hold the supplied values, and get points to the - data arrays. */ - pset = astPointSet( 3, nc, " ", status ); - ptr = astGetPoints( pset ); - -/* Copy the supplied coordinates into the PointSet, checking that no bad - values have been supplied. */ - for( i = 0; astOK && i < nc; i++ ) { - if( centre[ i ] == AST__BAD ) { - astError( AST__BADIN, "astInitEllipse(%s): The value of axis %d is " - "undefined at the ellipse centre.", status, name, i + 1 ); - } - if( astOK && p1[ i ] == AST__BAD ) { - astError( AST__BADIN, "astInitEllipse(%s): The value of axis %d is " - "undefined at point 1 on the circumference of " - "the ellipse.", status, name, i + 1 ); - } - if( astOK && p2[ i ] == AST__BAD ) { - astError( AST__BADIN, "astInitEllipse(%s): The value of axis %d is " - "undefined at point 2 on the circumference of " - "the ellipse.", status, name, i + 1 ); - } - ptr[ i ][ 0 ] = centre[ i ]; - ptr[ i ][ 1 ] = p1[ i ]; - ptr[ i ][ 2 ] = p2[ i ]; - } - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Initialise a Region structure (the parent class) as the first component - within the Ellipse structure, allocating memory if necessary. */ - new = (AstEllipse *) astInitRegion( mem, size, 0, (AstRegionVtab *) vtab, - name, frame, pset, unc ); - - if ( astOK ) { - -/* Initialise the Ellipse data. */ -/* ------------------------ */ - new->stale = 1; - -/* If an error occurred, clean up by deleting the new Ellipse. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Free resources. */ - pset = astAnnul( pset ); - if( form == 1 ) { - p1 = astFree( (void *) p1 ); - p2 = astFree( (void *) p2 ); - } - -/* Return a pointer to the new Ellipse. */ - return new; -} - -AstEllipse *astLoadEllipse_( void *mem, size_t size, AstEllipseVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadEllipse - -* Purpose: -* Load a Ellipse. - -* Type: -* Protected function. - -* Synopsis: -* #include "ellipse.h" -* AstEllipse *astLoadEllipse( void *mem, size_t size, AstEllipseVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* Ellipse loader. - -* Description: -* This function is provided to load a new Ellipse using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Ellipse structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Ellipse at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the Ellipse is to be -* loaded. This must be of sufficient size to accommodate the -* Ellipse data (sizeof(Ellipse)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Ellipse (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Ellipse structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstEllipse) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Ellipse. If this is NULL, a pointer -* to the (static) virtual function table for the Ellipse class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Ellipse" is used instead. - -* Returned Value: -* A pointer to the new Ellipse. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstEllipse *new; /* Pointer to the new Ellipse */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Ellipse. In this case the - Ellipse belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstEllipse ); - vtab = &class_vtab; - name = "Ellipse"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitEllipseVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Ellipse. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Ellipse" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* There are no values to read. */ -/* ---------------------------- */ - -/* Indicate that no cache intermediate results are yet available in the - Ellipse structure */ - new->stale = 1; - -/* If an error occurred, clean up by deleting the new Ellipse. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Ellipse pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astEllipsePars_( AstEllipse *this, double centre[2], double *a, - double *b, double *angle, double p1[2], double p2[2], - int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Ellipse,EllipsePars))( this, centre, a, b, - angle, p1, p2, status ); -} - - - - - - diff --git a/ast/ellipse.h b/ast/ellipse.h deleted file mode 100644 index cdd46f7..0000000 --- a/ast/ellipse.h +++ /dev/null @@ -1,244 +0,0 @@ -#if !defined( ELLIPSE_INCLUDED ) /* Include this file only once */ -#define ELLIPSE_INCLUDED -/* -*+ -* Name: -* ellipse.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Ellipse class. - -* Invocation: -* #include "ellipse.h" - -* Description: -* This include file defines the interface to the Ellipse class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The Ellipse class implement a Region which represents a simple interval -* on each axis of the encapsulated Frame - -* Inheritance: -* The Ellipse class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 7-SEP-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "region.h" /* Coordinate regions (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* Ellipse structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstEllipse { - -/* Attributes inherited from the parent class. */ - AstRegion region; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *centre; /* Ellipse centre coords */ - double *point1; /* Point at end of primary axis */ - double angle; /* Orientation of primary axis */ - double a; /* Half-length of primary axis */ - double b; /* Half-length of secondary axis */ - double lbx; /* Lower x limit of mesh bounding box */ - double ubx; /* Upper y limit of mesh bounding box */ - double lby; /* Lower x limit of mesh bounding box */ - double uby; /* Upper y limit of mesh bounding box */ - int stale; /* Is cached information stale? */ - -} AstEllipse; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstEllipseVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* EllipsePars)( AstEllipse *, double[2], double *, double *, double *, double[2], double[2], int * ); - -} AstEllipseVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstEllipseGlobals { - AstEllipseVtab Class_Vtab; - int Class_Init; -} AstEllipseGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitEllipseGlobals_( AstEllipseGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Ellipse) /* Check class membership */ -astPROTO_ISA(Ellipse) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstEllipse *astEllipse_( void *, int, const double[2], const double[2], const double[2], AstRegion *, const char *, int *, ...); -#else -AstEllipse *astEllipseId_( void *, int, const double[2], const double[2], const double[2], AstRegion *, const char *, ... )__attribute__((format(printf,7,8))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstEllipse *astInitEllipse_( void *, size_t, int, AstEllipseVtab *, - const char *, AstFrame *, int, const double[2], - const double[2], const double[2], AstRegion *, int * ); - -/* Vtab initialiser. */ -void astInitEllipseVtab_( AstEllipseVtab *, const char *, int * ); - -/* Loader. */ -AstEllipse *astLoadEllipse_( void *, size_t, AstEllipseVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -void astEllipsePars_( AstEllipse *, double[2], double *, double *, double *, double[2], double[2], int * ); -# if defined(astCLASS) /* Protected */ -AstRegion *astBestEllipse_( AstPointSet *, double *, AstRegion *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckEllipse(this) astINVOKE_CHECK(Ellipse,this,0) -#define astVerifyEllipse(this) astINVOKE_CHECK(Ellipse,this,1) - -/* Test class membership. */ -#define astIsAEllipse(this) astINVOKE_ISA(Ellipse,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astEllipse astINVOKE(F,astEllipse_) -#else -#define astEllipse astINVOKE(F,astEllipseId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitEllipse(mem,size,init,vtab,name,frame,form,p1,p2,p3,unc) \ -astINVOKE(O,astInitEllipse_(mem,size,init,vtab,name,frame,form,p1,p2,p3,unc,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitEllipseVtab(vtab,name) astINVOKE(V,astInitEllipseVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadEllipse(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadEllipse_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckEllipse to validate Ellipse pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -#define astEllipsePars(this,centre,a,b,angle,p1,p2) \ -astINVOKE(V,astEllipsePars_(astCheckEllipse(this),centre,a,b,angle,p1,p2,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astBestEllipse(pset,cen,unc) astBestEllipse_(pset,cen,unc,STATUS_PTR) -#endif -#endif - - - - - diff --git a/ast/ems.h b/ast/ems.h deleted file mode 100644 index 5b6fef3..0000000 --- a/ast/ems.h +++ /dev/null @@ -1,185 +0,0 @@ -/*+ - * Name: - * ems.h - - * Purpose: - * EMS_ C interface header file. - - * Language: - * Starlink ANSI C - - * Description: - * This include file contains the function prototypes for all - * EMS C interface routines and defines EMS__VERSN to be the major - * version number - - * Authors: - * PCTR: P.C.T. Rees (STARLINK) - * AJC: A.J.Chipperfield (STARLINK) - * TIMJ: Tim Jenness (JAC, Hawaii) - * {enter_new_authors_here} - - * History: - * 19-SEP-1990 (PCTR): - * Original version. - * 21-JUN-1991 (PCTR): - * Made all given character strings type "const". - * 5-OCT-1993 (PCTR): - * Updated for Vn. 1.2-3 - * 28-SEP-1994 (AJC): - * V1.4 Added ems_facer_c and ems_errno_c - * 21-JUN-1995 (AJC): - * V1.5 Added ems1_starf_c - * 13-MAY-1999 (AJC): - * Added the emsXxx form of name - * and #define old_names = new_names - * Removed ems_tune/gtune/show/_c - * Added ems1_get_facility_error - * 27-JUL-2001 (AJC): - * Removed emsFmtx - * Add emsExpnd, emsTune - * 13-AUG-2001 (AJC): - * Removed emsFioer - * #define EMS__VERSN - * 20-SEP-2001 (AJC): - * Added emsSetnc and point ems_setc_c at it - * 3-MAR-2006 (TIMJ): - * Add emsSetu / emsSetp / emsSeti64 - * 30-JUL-2008 (PWD): - * Added emsGtune. - * 31-JUL-2008 (PWD): - * Added emsStune and changed emsGtune to return the value as a result. - * Marked emsTune as deprecated. - * 10-SEP-2008 (TIMJ): - * Remove fortran prototypes. Should not be in a public include file. - * 16-SEP-2008 (TIMJ): - * Remove 3 arg version of emsSetc - * {enter_changes_here} - - * Bugs: - * {note_any_bugs_here} - - *- */ - -#ifndef EMS_DEFINED -#define EMS_DEFINED - -/* ANSI types */ -#include -#include -#include - - -/* EMS Major Version */ -#define EMS__VERSN 2 - -/* Function Prototypes: */ -void emsAnnul( int *status ); - -void emsBegin( int *status ); - -void emsEload( char *param, - int *parlen, - char *opstr, - int *oplen, - int *status ); - -void emsEnd( int * status ); - -void emsErrno( const char *token, - int errval ); - -void emsExpnd( const char *text, - char *opstr, - const int maxlen, - int *oplen, - int *status ); - -void emsFacer( const char *token, - int status ); - -int emsGtune( const char *key, - int *status ); - -void emsLevel( int *level ); - -void emsMark( void ); - -void emsMload( const char *msg, - const char *text, - char *opstr, - int *oplen, - int *status ); - -void emsRenew( void ); - -void emsRep( const char *err, - const char *text, - int *status ); - -void emsRlse( void ); - -void emsSetc( const char *token, - const char *cvalue ); - -void emsSetnc( const char *token, - const char *cvalue, - int mxchar ); - -void emsSetd( const char *token, - double dvalue ); - -void emsSeti( const char *token, - int ivalue ); - -void emsSeti64( const char *token, - int64_t ivalue ); - -void emsSetl( const char *token, - int lvalue ); - -void emsSetr( const char *token, - float rvalue ); - -void emsSetp( const char *token, - void * pvalue ); - -void emsSetu( const char *token, - unsigned int ivalue ); - -void emsStat( int *status ); - -void emsSyser( const char *token, - int systat ); - -int emsStune( const char *key, - const int value, - int *status ); - -/* Deprecated function. */ -void emsTune( const char *key, - const int value, - int *status ); - -/* Internal Functions */ -/* Not for general use */ -int ems1Starf( const char *envar, - const char *relpath, - const char *acmode, - char **filename, - int *pathlen ); - -void ems1_get_facility_error( unsigned int errcode, - char **facility_name, - char **error_ident, - char **error_text ); - -/* Required by MERS. Not to be used by anyone else */ - -void ems1Rform( const char *text, const int maxlen, int *iposn, char *string, int *strlength ); - -void ems1Gesc( const char *escchr, const char *string, int *iposn ); - -void ems1Gnam( const char *string, int *iposn, char *name, int *namlen, int *status); - -#endif /* EMS_DEFINED */ diff --git a/ast/erfa.h b/ast/erfa.h deleted file mode 100644 index 1f98296..0000000 --- a/ast/erfa.h +++ /dev/null @@ -1,72 +0,0 @@ -#if !defined( ERFA_INCLUDED ) /* Include this file only once */ -#define ERFA_INCLUDED -/* -*+ -* Name: -* erfa.h - -* Purpose: -* Function prototypes for ERFA routines. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Include file - -* Description: -* Function prototypes for ERFA routines. Note, the -* --with-external_pal configuration option implies that an external -* ERFA library will also be used. - -* Authors: -* DSBJ: David S Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 23-FEB-2012 (DSB): -* Initial version. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 3 of -* the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be -* useful, but WITHOUT ANY WARRANTY; without even the implied -* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 -* USA. - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -/* Include configuration results in order to get any definition for the - EXTERNAL_PAL macro. This macro is set if the --with-external_pal - option was set when AST was configured. */ -#if HAVE_CONFIG_H -#include -#endif - -/* If we not using an external ERFA library, rename all ERFA functions so - that references to "iauXxx" below get translated to "astIauXxx". */ -#ifndef EXTERNAL_PAL -#include "erfa2ast.h" -#endif - -/* Include the prototypes defined in the erfa header file. */ -#include "erfa/erfa.h" - -#endif diff --git a/ast/erfa/INFO b/ast/erfa/INFO deleted file mode 100644 index 0719bcc..0000000 --- a/ast/erfa/INFO +++ /dev/null @@ -1,19 +0,0 @@ -ERFA has received explicit permission from the IAU SOFA Board to re-license -and re-copyright ERFA from SOFA. The email providing permission is shown here: - -> The IAU Standards Of Fundamental Astronomy Board approves the -> relicensing of a changed SOFA library by the NumFOCUS Foundation to use -> a "Three Clause BSD" license. The changed, relicensed version shall -> differ from the SOFA version in that all function names shall change to -> use "era" as a prefix in place of "iau", and that the SOFA Board shall -> be removed as a copyright holder in the relicensed version. - -> Catherine -> Chair, IAU SOFA Board -> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -> HM Nautical Almanac Office -> United Kingdom Hydrographic Office -> Admiralty Way -> Taunton TA1 2DN -> Catherine.Hohenkerk@UKHO.gov.uk -> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/ast/erfa/LICENSE b/ast/erfa/LICENSE deleted file mode 100644 index 8b3e92c..0000000 --- a/ast/erfa/LICENSE +++ /dev/null @@ -1,53 +0,0 @@ -Copyright (C) 2013-2014, NumFOCUS Foundation. -All rights reserved. - -This library is derived, with permission, from the International -Astronomical Union's "Standards of Fundamental Astronomy" library, -available from http://www.iausofa.org. - -The ERFA version is intended to retain identical -functionality to the SOFA library, but made distinct through -different function and file names, as set out in the SOFA license -conditions. The SOFA original has a role as a reference standard -for the IAU and IERS, and consequently redistribution is permitted only -in its unaltered state. The ERFA version is not subject to this -restriction and therefore can be included in distributions which do not -support the concept of "read only" software. - -Although the intent is to replicate the SOFA API (other than replacement of -prefix names) and results (with the exception of bugs; any that are -discovered will be fixed), SOFA is not responsible for any errors found -in this version of the library. - -If you wish to acknowledge the SOFA heritage, please acknowledge that -you are using a library derived from SOFA, rather than SOFA itself. - - -TERMS AND CONDITIONS - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1 Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2 Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3 Neither the name of the Standards Of Fundamental Astronomy Board, the - International Astronomical Union nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ast/erfa/Makefile.am b/ast/erfa/Makefile.am deleted file mode 100644 index e0dce1b..0000000 --- a/ast/erfa/Makefile.am +++ /dev/null @@ -1,47 +0,0 @@ -lib_LTLIBRARIES = liberfa.la -liberfa_la_SOURCES = a2af.c a2tf.c ab.c af2a.c anp.c anpm.c apcg13.c \ -apcg.c apci13.c apci.c apco13.c apco.c apcs13.c apcs.c aper13.c \ -aper.c apio13.c apio.c atci13.c atciq.c atciqn.c atciqz.c atco13.c \ -atic13.c aticq.c aticqn.c atio13.c atioq.c atoc13.c atoi13.c atoiq.c \ -bi00.c bp00.c bp06.c bpn2xy.c c2i00a.c c2i00b.c c2i06a.c c2ibpn.c \ -c2ixy.c c2ixys.c c2s.c c2t00a.c c2t00b.c c2t06a.c c2tcio.c c2teqx.c \ -c2tpe.c c2txy.c cal2jd.c cp.c cpv.c cr.c d2dtf.c d2tf.c dat.c dtdb.c \ -dtf2d.c eceq06.c ee00a.c ee00.c eect00.c eo06a.c epb2jd.c epj2jd.c epv00.c \ -eqeq94.c ecm06.c ee00b.c ee06a.c eform.c eors.c epb.c epj.c eqec06.c \ -era00.c fad03.c fae03.c faf03.c faju03.c fal03.c falp03.c fama03.c \ -fame03.c fane03.c faom03.c fapa03.c fasa03.c faur03.c fave03.c \ -fk52h.c fk5hip.c fk5hz.c fw2m.c fw2xy.c g2icrs.c gc2gd.c gc2gde.c gd2gc.c \ -gd2gce.c gmst00.c gmst06.c gmst82.c gst00a.c gst00b.c gst06a.c \ -gst06.c gst94.c h2fk5.c hfk5z.c icrs2g.c ir.c jd2cal.c jdcalf.c ld.c \ -ldn.c ldsun.c lteceq.c ltecm.c lteqec.c ltpb.c ltp.c ltpecl.c ltpequ.c \ -num00a.c num00b.c num06a.c numat.c nut00a.c nut00b.c \ -nut06a.c nut80.c nutm80.c obl06.c obl80.c p06e.c p2pv.c p2s.c pap.c \ -pas.c pb06.c pdp.c pfw06.c plan94.c pmat00.c pmat06.c pmat76.c \ -pm.c pmp.c pmpx.c pmsafe.c pn00a.c pn00b.c pn00.c pn06a.c \ -pn06.c pn.c pnm00a.c pnm00b.c pnm06a.c pnm80.c pom00.c ppp.c \ -ppsp.c pr00.c prec76.c pv2p.c pv2s.c pvdpv.c pvm.c pvmpv.c pvppv.c \ -pvstar.c pvtob.c pvu.c pvup.c pvxpv.c pxp.c refco.c rm2v.c rv2m.c \ -rx.c rxp.c rxpv.c rxr.c ry.c rz.c s00a.c s00b.c s00.c \ -s06a.c s06.c s2c.c s2p.c s2pv.c s2xpv.c sepp.c seps.c sp00.c \ -starpm.c starpv.c sxp.c sxpv.c taitt.c taiut1.c taiutc.c tcbtdb.c \ -tcgtt.c tdbtcb.c tdbtt.c tf2a.c tf2d.c tr.c trxp.c trxpv.c tttai.c \ -tttcg.c tttdb.c ttut1.c ut1tai.c ut1tt.c ut1utc.c utctai.c utcut1.c \ -xy06.c xys00a.c xys00b.c xys06a.c zp.c zpv.c zr.c - -include_HEADERS = erfa.h erfam.h - -## Version info is in current : revision : age form -## A library supports interfaces from current downto current - age -## Revision is the version of the current interface - -## VI_ALL is set in the macro ERFA_LIB_VERSION_INFO in configure.ac - -liberfa_la_LDFLAGS = -version-info $(VI_ALL) - - -## Check program -TESTS = t_erfa_c -check_PROGRAMS = t_erfa_c -t_erfa_c_SOURCES = t_erfa_c.c -AM_CPPFLAGS = -I$(top_srcdir) -LDADD = $(top_builddir)/src/liberfa.la diff --git a/ast/erfa/README.rst b/ast/erfa/README.rst deleted file mode 100644 index 418d138..0000000 --- a/ast/erfa/README.rst +++ /dev/null @@ -1,93 +0,0 @@ -This is the source code repository for ERFA (Essential Routines for -Fundamental Astronomy). ERFA is a C library containing key algorithms for -astronomy, and is based on the `SOFA library `_ published by the International -Astronomical Union (IAU). - -ERFA is intended to replicate the functionality of SOFA (aside from possible -bugfixes in ERFA that have not yet been included in SOFA), but is licensed -under a three-clause BSD license to enable its compatibility with a wide -range of open source licenses. Permission for this release has been -obtained from the SOFA board, and is avilable in the ``LICENSE`` file included -in this source distribution. - -Differences from SOFA ---------------------- - -This version of ERFA (v1.3.0) is based on SOFA version "20160503_a", with the -differences outlined below. - -ERFA branding -^^^^^^^^^^^^^ - -All references to "SOFA" in the source code have been changed to ERFA, and -functions have the prefix ``era`` instead of ``iau``. - -C macro prefixes -^^^^^^^^^^^^^^^^ - -All C macros used in ERFA are the same as their SOFA equivalents, but with an -``ERFA_`` prefix to prevent namespace collisions. - -Bugfixes -^^^^^^^^ - -ERFA includes smaller changes that may or may not eventually make it into SOFA, -addressing localized bugs or similar smaller issues: - -* ERFA 1.3.0 and SOFA "20160503_a" - - + There are no differences between ERFA 1.3.0 and SOFA "20160503_a". - -* ERFA 1.2.0 and SOFA "20150209_a" - - + Typos have been corrected in the documentation of atco13 and atio13 (see https://github.com/liberfa/erfa/issues/29). - -Note that issues identified in ERFA should generally also be reported upstream to SOFA at sofa@ukho.gov.uk. - -Building and installing ERFA ----------------------------- - -To build and install a released version of ERFA in your OS's standard -location, simply do:: - - ./configure - make - make install - -If you want to run the tests to make sure ERFA built correctly, before -installing do:: - - make check - - -For developers -^^^^^^^^^^^^^^ - -If you are using a developer version from github, you will need to first do -``./bootstrap.sh`` before the above commands. This requires ``autoconf`` and -``libtool``. - -If you wish to build against the ERFA static library without installing, you -will find it in ``$ERFAROOT/src/.libs/liberfa.a`` after running ``make``. - -Creating a single-file version of the source code -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Alternatively, if you wish to bundle the ERFA source code with a separate -package, you can use the ``source_flattener.py`` script from the -`erfa-fetch repository`_ to combine -the ERFA source code into just two files: a ``erfa.c`` source file, and an -``erfa.h`` include file. You should run this script like this:: - - cd /path/to/erfa-source-code - python /path/to/erfa-fetch/source_flattener.py src -n erfa - -If possible, however, it is recommended that you provide an option to use any -copy of the ERFA library that is already installed on the system. - -Travis build status -------------------- -.. image:: https://travis-ci.org/liberfa/erfa.png - :target: https://travis-ci.org/liberfa/erfa - -.. _erfa-fetch repository: https://github.com/liberfa/erfa-fetch diff --git a/ast/erfa/RELEASE.rst b/ast/erfa/RELEASE.rst deleted file mode 100644 index 3726fdc..0000000 --- a/ast/erfa/RELEASE.rst +++ /dev/null @@ -1,180 +0,0 @@ -Instructions for releasing ERFA -=============================== - -* Clone the ERFA repository from github (if you haven't already done so), - and change to the ERFA directory. - -* Make sure you are on the "master" branch from the "liberfa" github - repository and have the latest version (if you have a fresh clone, this - should already be the case). - -* If a new version of SOFA exists, run `sofa_deriver.py` from the `erfa-fetch - repository`_ in its own directory. That will create a directory called `erfa` - inside the `erfa-fetch` directory, and you should copy its contents to the - `src` directory of `erfa`. Add any new C files or header files added by SOFA - to ``src/Makefile.am``, as appropriate. Use ``git diff`` in `erfa` to inspect - the changes, and then commit and push them to github. - -* Update the version number in the `AC_INIT` macro of `configure.ac` to - the version number you are about to release, and also update the version - mentioned in `README.rst`. Follow the instructions in - `Version numbering` below. - -* Update the version info of the shared library in the `ERFA_LIB_VERSION_INFO` - macro of `configure.ac`. Follow the instructions in `Version numbering` below. - -* Commit these changes using ``git commit``, with a commit message like - ``Preparing release v0.0.1``. - -* Run `./bootstrap.sh`: you need `automake`, `autoconf` and `libtool` - installed. If no errors appear, this will create a new `./configure` - file. - -* Run ``./configure``, which should create a `Makefile` in the top level - directory and in ./src - -* Run ``make check``, which will build the library and run the tests - - make sure they pass before proceeding. - -* Run ``make distcheck``: this creates the distribution tarball, - unpackages it and runs the check inside the untarred directory. - The resulting tarball will be named e.g., `erfa-0.0.1.tar.gz` and - will be placed in the working directory. - -* Tag the current commit with the version number. A signed tag is preferred if - you have an a signing key (e.g., do ``git tag -s v0.0.1``). - -* Push up your changes and the new tag to github: - ``git push --tags origin master``. (The command here assumes the git remote - "origin" points to the "liberfa/erfa" repository. If not, substitute the - appropriate name.) - -* Go to the "liberfa/erfa" repository for the github page, and click on the - "releases" button, and then the release corresponding to the tag you just - made. - -* Click on the "Draft release notes or downloads" button (or it might be - "Edit release"). Put the version number as the title (e.g., ``v0.0.1``)and - for the description put ``See `README.rst` for release notes.`` - -* Upload the tarball you created (e.g., `erfa-0.0.1.tar.gz`) by dropping it - in the area that says "Attach binaries for this release by dropping them - here." - -* Click the "Publish release" button. - -* Update the release listing on Github Pages to include this release: - Do ``git checkout gh-pages``, add a new ``
  • ...
  • `` entry for the - release in `index.html`, do ``git commit``, and then - ``git push origin gh-pages``. - -Version numbering -================= - -ERFA needs to provide two different version numbers. You need to update both. -The first is the -**package version number** or **version number** proper. ERFA uses -`semantic versioning `_ to create this number. -For more on this choice, see -`liberfa/erfa#6 `_. - -The second number is `shared library version info`. When a program has been -linked with the ERFA shared library, the dynamic linker checks the version -info of the library requested by the program with those of the libraries -present if the system. This version info is important to binary distributions -(such as Linux distributions). ERFA uses `libtool versioning `_. - - -Package version number ----------------------- - -Semantic versioning dictates how to change the version number according to -changes to the API of the library. In the case of ERFA the API is: - - * The public C macros defined in erfam.h - * The names, return types, number of arguments and types of the functions in erfa.h - -To update the package version, the release manager has to check the relevant -information about the release, such as: - - * upstream SOFA documentation in http://www.iausofa.org/current_changes.html - * relevant bug reports in the github project page - -If the version is given in the form MAJOR.MINOR.PATCH, then - - * if there is a backwards incompatible change (function removed, types of - arguments altered, macros renamed...) then increase MAJOR by one and set - the others to zero. - * else if there is backwards compatible change (new function added or - new macro added) then do not change MAJOR, increase MINOR by one and - set PATCH to zero. - * else - you are either fixing a bug or making other improvements. Increase - patch by one and do not change the others. - -Change the version number in the `AC_INIT` macro and in `README.rst` - -Shared library version info ---------------------------- - -For the shared library version info, we are only interested in a subset of -the API, the **interfaces of the shared library**. As the C macros are -interpolated away at compile time, the interfaces in the ERFA -shared library are: - - * The names, return types, number of arguments and types of the functions - -Again, the release manager has to review the relevant information: - - * upstream SOFA documentation in http://www.iausofa.org/current_changes.html - * relevant bug reports in the github project page - -The shared library version info is stored in three numbers called *current*, -*revision* and *age*. These numbers appear in the macro `ERFA_LIB_VERSION_INFO` -in the mentioned order. - -If the version is given in the form CURRENT,REVISION,AGE then - - * if there is a backwards incompatible change (function removed, types of - arguments altered...) then increase CURRENT by one and set - the others to zero (c,r,a -> c+1,0,0). - * else if there is backwards compatible change (new function added) - then increase both CURRENT and AGE by one, set REVISON to zero - (c,r,a -> c+1,0,a+1). - * else if the library code has been modified at all - then increase REVISION by one (c,r,a -> c,r+1,a) - * else - do not change the version info (c,r,a -> c,r,a) - -Change the verion info in `ERFA_LIB_VERSION_INFO` - -Examples ---------- -We start with ERFA version 1.0.0 and library version info 0,0,0 - -* SOFA makes a new release. A function is added and two functions change their - arguments. This is a backawars incompatible change, so the new package will - have version 2.0.0 and the shared library version info will be 1,0,0 - -* We forgot to add README.rst to the release. We make a new one. The change - is a bugfix (no API changes), the new release will be 2.0.1. The shared - library version is not modified (no changes in the library source code). - -* SOFA makes a new release. They just add a new function. The new package - version will be 2.1.0. The shared library info will be 2,0,1 (both current - and age are incremented). - -* SOFA makes a new relase fixing some bugs in the code without changing the - API. New package version is 2.1.1. The shared library version is 2,1,1 - -* A contributor finds a bug in ERFA. The fix doesn't change the API. New - package version is 2.1.2. The shared library version is 2,2,1 - -* SOFA makes a new release incorporating the bug fix and adding new functions. - The new package version is 2.2.0. The shared library version is 3,0,2 - -* SOFA makes a new release removing functions. This is a backawars - incompatible change, so the new package will - have version 3.0.0 and the shared library version info will be 4,0,0 - -.. _erfa-fetch repository: https://github.com/liberfa/erfa-fetch diff --git a/ast/erfa/a2af.c b/ast/erfa/a2af.c deleted file mode 100644 index 0101630..0000000 --- a/ast/erfa/a2af.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "erfa.h" - -void eraA2af(int ndp, double angle, char *sign, int idmsf[4]) -/* -** - - - - - - - - -** e r a A 2 a f -** - - - - - - - - -** -** Decompose radians into degrees, arcminutes, arcseconds, fraction. -** -** Given: -** ndp int resolution (Note 1) -** angle double angle in radians -** -** Returned: -** sign char '+' or '-' -** idmsf int[4] degrees, arcminutes, arcseconds, fraction -** -** Called: -** eraD2tf decompose days to hms -** -** Notes: -** -** 1) The argument ndp is interpreted as follows: -** -** ndp resolution -** : ...0000 00 00 -** -7 1000 00 00 -** -6 100 00 00 -** -5 10 00 00 -** -4 1 00 00 -** -3 0 10 00 -** -2 0 01 00 -** -1 0 00 10 -** 0 0 00 01 -** 1 0 00 00.1 -** 2 0 00 00.01 -** 3 0 00 00.001 -** : 0 00 00.000... -** -** 2) The largest positive useful value for ndp is determined by the -** size of angle, the format of doubles on the target platform, and -** the risk of overflowing idmsf[3]. On a typical platform, for -** angle up to 2pi, the available floating-point precision might -** correspond to ndp=12. However, the practical limit is typically -** ndp=9, set by the capacity of a 32-bit int, or ndp=4 if int is -** only 16 bits. -** -** 3) The absolute value of angle may exceed 2pi. In cases where it -** does not, it is up to the caller to test for and handle the -** case where angle is very nearly 2pi and rounds up to 360 degrees, -** by testing for idmsf[0]=360 and setting idmsf[0-3] to zero. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Hours to degrees * radians to turns */ - const double F = 15.0 / ERFA_D2PI; - - -/* Scale then use days to h,m,s function. */ - eraD2tf(ndp, angle*F, sign, idmsf); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/a2tf.c b/ast/erfa/a2tf.c deleted file mode 100644 index ac3aa98..0000000 --- a/ast/erfa/a2tf.c +++ /dev/null @@ -1,125 +0,0 @@ -#include "erfa.h" - -void eraA2tf(int ndp, double angle, char *sign, int ihmsf[4]) -/* -** - - - - - - - - -** e r a A 2 t f -** - - - - - - - - -** -** Decompose radians into hours, minutes, seconds, fraction. -** -** Given: -** ndp int resolution (Note 1) -** angle double angle in radians -** -** Returned: -** sign char '+' or '-' -** ihmsf int[4] hours, minutes, seconds, fraction -** -** Called: -** eraD2tf decompose days to hms -** -** Notes: -** -** 1) The argument ndp is interpreted as follows: -** -** ndp resolution -** : ...0000 00 00 -** -7 1000 00 00 -** -6 100 00 00 -** -5 10 00 00 -** -4 1 00 00 -** -3 0 10 00 -** -2 0 01 00 -** -1 0 00 10 -** 0 0 00 01 -** 1 0 00 00.1 -** 2 0 00 00.01 -** 3 0 00 00.001 -** : 0 00 00.000... -** -** 2) The largest positive useful value for ndp is determined by the -** size of angle, the format of doubles on the target platform, and -** the risk of overflowing ihmsf[3]. On a typical platform, for -** angle up to 2pi, the available floating-point precision might -** correspond to ndp=12. However, the practical limit is typically -** ndp=9, set by the capacity of a 32-bit int, or ndp=4 if int is -** only 16 bits. -** -** 3) The absolute value of angle may exceed 2pi. In cases where it -** does not, it is up to the caller to test for and handle the -** case where angle is very nearly 2pi and rounds up to 24 hours, -** by testing for ihmsf[0]=24 and setting ihmsf[0-3] to zero. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Scale then use days to h,m,s function. */ - eraD2tf(ndp, angle/ERFA_D2PI, sign, ihmsf); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ab.c b/ast/erfa/ab.c deleted file mode 100644 index 5d56656..0000000 --- a/ast/erfa/ab.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "erfa.h" - -void eraAb(double pnat[3], double v[3], double s, double bm1, - double ppr[3]) -/* -** - - - - - - -** e r a A b -** - - - - - - -** -** Apply aberration to transform natural direction into proper -** direction. -** -** Given: -** pnat double[3] natural direction to the source (unit vector) -** v double[3] observer barycentric velocity in units of c -** s double distance between the Sun and the observer (au) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** -** Returned: -** ppr double[3] proper direction to source (unit vector) -** -** Notes: -** -** 1) The algorithm is based on Expr. (7.40) in the Explanatory -** Supplement (Urban & Seidelmann 2013), but with the following -** changes: -** -** o Rigorous rather than approximate normalization is applied. -** -** o The gravitational potential term from Expr. (7) in -** Klioner (2003) is added, taking into account only the Sun's -** contribution. This has a maximum effect of about -** 0.4 microarcsecond. -** -** 2) In almost all cases, the maximum accuracy will be limited by the -** supplied velocity. For example, if the ERFA eraEpv00 function is -** used, errors of up to 5 microarcseconds could occur. -** -** References: -** -** Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to -** the Astronomical Almanac, 3rd ed., University Science Books -** (2013). -** -** Klioner, Sergei A., "A practical relativistic model for micro- -** arcsecond astrometry in space", Astr. J. 125, 1580-1597 (2003). -** -** Called: -** eraPdp scalar product of two p-vectors -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int i; - double pdv, w1, w2, r2, w, p[3], r; - - - pdv = eraPdp(pnat, v); - w1 = 1.0 + pdv/(1.0 + bm1); - w2 = ERFA_SRS/s; - r2 = 0.0; - for (i = 0; i < 3; i++) { - w = pnat[i]*bm1 + w1*v[i] + w2*(v[i] - pdv*pnat[i]); - p[i] = w; - r2 = r2 + w*w; - } - r = sqrt(r2); - for (i = 0; i < 3; i++) { - ppr[i] = p[i]/r; - } - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/af2a.c b/ast/erfa/af2a.c deleted file mode 100644 index b74dd75..0000000 --- a/ast/erfa/af2a.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "erfa.h" -#include - -int eraAf2a(char s, int ideg, int iamin, double asec, double *rad) -/* -** - - - - - - - - -** e r a A f 2 a -** - - - - - - - - -** -** Convert degrees, arcminutes, arcseconds to radians. -** -** Given: -** s char sign: '-' = negative, otherwise positive -** ideg int degrees -** iamin int arcminutes -** asec double arcseconds -** -** Returned: -** rad double angle in radians -** -** Returned (function value): -** int status: 0 = OK -** 1 = ideg outside range 0-359 -** 2 = iamin outside range 0-59 -** 3 = asec outside range 0-59.999... -** -** Notes: -** -** 1) The result is computed even if any of the range checks fail. -** -** 2) Negative ideg, iamin and/or asec produce a warning status, but -** the absolute value is used in the conversion. -** -** 3) If there are multiple errors, the status value reflects only the -** first, the smallest taking precedence. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* Compute the interval. */ - *rad = ( s == '-' ? -1.0 : 1.0 ) * - ( 60.0 * ( 60.0 * ( (double) abs(ideg) ) + - ( (double) abs(iamin) ) ) + - fabs(asec) ) * ERFA_DAS2R; - -/* Validate arguments and return status. */ - if ( ideg < 0 || ideg > 359 ) return 1; - if ( iamin < 0 || iamin > 59 ) return 2; - if ( asec < 0.0 || asec >= 60.0 ) return 3; - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/anp.c b/ast/erfa/anp.c deleted file mode 100644 index dcd678e..0000000 --- a/ast/erfa/anp.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "erfa.h" - -double eraAnp(double a) -/* -** - - - - - - - -** e r a A n p -** - - - - - - - -** -** Normalize angle into the range 0 <= a < 2pi. -** -** Given: -** a double angle (radians) -** -** Returned (function value): -** double angle in range 0-2pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double w; - - - w = fmod(a, ERFA_D2PI); - if (w < 0) w += ERFA_D2PI; - - return w; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/anpm.c b/ast/erfa/anpm.c deleted file mode 100644 index bd1e059..0000000 --- a/ast/erfa/anpm.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "erfa.h" - -double eraAnpm(double a) -/* -** - - - - - - - - -** e r a A n p m -** - - - - - - - - -** -** Normalize angle into the range -pi <= a < +pi. -** -** Given: -** a double angle (radians) -** -** Returned (function value): -** double angle in range +/-pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double w; - - - w = fmod(a, ERFA_D2PI); - if (fabs(w) >= ERFA_DPI) w -= ERFA_DSIGN(ERFA_D2PI, a); - - return w; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apcg.c b/ast/erfa/apcg.c deleted file mode 100644 index e49d4ae..0000000 --- a/ast/erfa/apcg.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "erfa.h" - -void eraApcg(double date1, double date2, - double ebpv[2][3], double ehp[3], - eraASTROM *astrom) -/* -** - - - - - - - - -** e r a A p c g -** - - - - - - - - -** -** For a geocentric observer, prepare star-independent astrometry -** parameters for transformations between ICRS and GCRS coordinates. -** The Earth ephemeris is supplied by the caller. -** -** The parameters produced by this function are required in the -** parallax, light deflection and aberration parts of the astrometric -** transformation chain. -** -** Given: -** date1 double TDB as a 2-part... -** date2 double ...Julian Date (Note 1) -** ebpv double[2][3] Earth barycentric pos/vel (au, au/day) -** ehp double[3] Earth heliocentric position (au) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double unchanged -** xpl double unchanged -** ypl double unchanged -** sphi double unchanged -** cphi double unchanged -** diurab double unchanged -** eral double unchanged -** refa double unchanged -** refb double unchanged -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. For most -** applications of this function the choice will not be at all -** critical. -** -** TT can be used instead of TDB without any significant impact on -** accuracy. -** -** 2) All the vectors are with respect to BCRS axes. -** -** 3) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 4) The context structure astrom produced by this function is used by -** eraAtciq* and eraAticq*. -** -** Called: -** eraApcs astrometry parameters, ICRS-GCRS, space observer -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Geocentric observer */ - double pv[2][3] = { { 0.0, 0.0, 0.0 }, - { 0.0, 0.0, 0.0 } }; - - -/* Compute the star-independent astrometry parameters. */ - eraApcs(date1, date2, pv, ebpv, ehp, astrom); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apcg13.c b/ast/erfa/apcg13.c deleted file mode 100644 index 4157785..0000000 --- a/ast/erfa/apcg13.c +++ /dev/null @@ -1,184 +0,0 @@ -#include "erfa.h" - -void eraApcg13(double date1, double date2, eraASTROM *astrom) -/* -** - - - - - - - - - - -** e r a A p c g 1 3 -** - - - - - - - - - - -** -** For a geocentric observer, prepare star-independent astrometry -** parameters for transformations between ICRS and GCRS coordinates. -** The caller supplies the date, and ERFA models are used to predict -** the Earth ephemeris. -** -** The parameters produced by this function are required in the -** parallax, light deflection and aberration parts of the astrometric -** transformation chain. -** -** Given: -** date1 double TDB as a 2-part... -** date2 double ...Julian Date (Note 1) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double unchanged -** xpl double unchanged -** ypl double unchanged -** sphi double unchanged -** cphi double unchanged -** diurab double unchanged -** eral double unchanged -** refa double unchanged -** refb double unchanged -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. For most -** applications of this function the choice will not be at all -** critical. -** -** TT can be used instead of TDB without any significant impact on -** accuracy. -** -** 2) All the vectors are with respect to BCRS axes. -** -** 3) In cases where the caller wishes to supply his own Earth -** ephemeris, the function eraApcg can be used instead of the present -** function. -** -** 4) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 5) The context structure astrom produced by this function is used by -** eraAtciq* and eraAticq*. -** -** Called: -** eraEpv00 Earth position and velocity -** eraApcg astrometry parameters, ICRS-GCRS, geocenter -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double ehpv[2][3], ebpv[2][3]; - - -/* Earth barycentric & heliocentric position/velocity (au, au/d). */ - (void) eraEpv00(date1, date2, ehpv, ebpv); - -/* Compute the star-independent astrometry parameters. */ - eraApcg(date1, date2, ebpv, ehpv[0], astrom); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apci.c b/ast/erfa/apci.c deleted file mode 100644 index 74dbc3b..0000000 --- a/ast/erfa/apci.c +++ /dev/null @@ -1,190 +0,0 @@ -#include "erfa.h" - -void eraApci(double date1, double date2, - double ebpv[2][3], double ehp[3], - double x, double y, double s, - eraASTROM *astrom) -/* -** - - - - - - - - -** e r a A p c i -** - - - - - - - - -** -** For a terrestrial observer, prepare star-independent astrometry -** parameters for transformations between ICRS and geocentric CIRS -** coordinates. The Earth ephemeris and CIP/CIO are supplied by the -** caller. -** -** The parameters produced by this function are required in the -** parallax, light deflection, aberration, and bias-precession-nutation -** parts of the astrometric transformation chain. -** -** Given: -** date1 double TDB as a 2-part... -** date2 double ...Julian Date (Note 1) -** ebpv double[2][3] Earth barycentric position/velocity (au, au/day) -** ehp double[3] Earth heliocentric position (au) -** x,y double CIP X,Y (components of unit vector) -** s double the CIO locator s (radians) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double unchanged -** xpl double unchanged -** ypl double unchanged -** sphi double unchanged -** cphi double unchanged -** diurab double unchanged -** eral double unchanged -** refa double unchanged -** refb double unchanged -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. For most -** applications of this function the choice will not be at all -** critical. -** -** TT can be used instead of TDB without any significant impact on -** accuracy. -** -** 2) All the vectors are with respect to BCRS axes. -** -** 3) In cases where the caller does not wish to provide the Earth -** ephemeris and CIP/CIO, the function eraApci13 can be used instead -** of the present function. This computes the required quantities -** using other ERFA functions. -** -** 4) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 5) The context structure astrom produced by this function is used by -** eraAtciq* and eraAticq*. -** -** Called: -** eraApcg astrometry parameters, ICRS-GCRS, geocenter -** eraC2ixys celestial-to-intermediate matrix, given X,Y and s -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* Star-independent astrometry parameters for geocenter. */ - eraApcg(date1, date2, ebpv, ehp, astrom); - -/* CIO based BPN matrix. */ - eraC2ixys(x, y, s, astrom->bpn); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apci13.c b/ast/erfa/apci13.c deleted file mode 100644 index c041652..0000000 --- a/ast/erfa/apci13.c +++ /dev/null @@ -1,202 +0,0 @@ -#include "erfa.h" - -void eraApci13(double date1, double date2, - eraASTROM *astrom, double *eo) -/* -** - - - - - - - - - - -** e r a A p c i 1 3 -** - - - - - - - - - - -** -** For a terrestrial observer, prepare star-independent astrometry -** parameters for transformations between ICRS and geocentric CIRS -** coordinates. The caller supplies the date, and ERFA models are used -** to predict the Earth ephemeris and CIP/CIO. -** -** The parameters produced by this function are required in the -** parallax, light deflection, aberration, and bias-precession-nutation -** parts of the astrometric transformation chain. -** -** Given: -** date1 double TDB as a 2-part... -** date2 double ...Julian Date (Note 1) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double unchanged -** xpl double unchanged -** ypl double unchanged -** sphi double unchanged -** cphi double unchanged -** diurab double unchanged -** eral double unchanged -** refa double unchanged -** refb double unchanged -** eo double* equation of the origins (ERA-GST) -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. For most -** applications of this function the choice will not be at all -** critical. -** -** TT can be used instead of TDB without any significant impact on -** accuracy. -** -** 2) All the vectors are with respect to BCRS axes. -** -** 3) In cases where the caller wishes to supply his own Earth -** ephemeris and CIP/CIO, the function eraApci can be used instead -** of the present function. -** -** 4) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 5) The context structure astrom produced by this function is used by -** eraAtciq* and eraAticq*. -** -** Called: -** eraEpv00 Earth position and velocity -** eraPnm06a classical NPB matrix, IAU 2006/2000A -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraS06 the CIO locator s, given X,Y, IAU 2006 -** eraApci astrometry parameters, ICRS-CIRS -** eraEors equation of the origins, given NPB matrix and s -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double ehpv[2][3], ebpv[2][3], r[3][3], x, y, s; - - -/* Earth barycentric & heliocentric position/velocity (au, au/d). */ - (void) eraEpv00(date1, date2, ehpv, ebpv); - -/* Form the equinox based BPN matrix, IAU 2006/2000A. */ - eraPnm06a(date1, date2, r); - -/* Extract CIP X,Y. */ - eraBpn2xy(r, &x, &y); - -/* Obtain CIO locator s. */ - s = eraS06(date1, date2, x, y); - -/* Compute the star-independent astrometry parameters. */ - eraApci(date1, date2, ebpv, ehpv[0], x, y, s, astrom); - -/* Equation of the origins. */ - *eo = eraEors(r, s); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apco.c b/ast/erfa/apco.c deleted file mode 100644 index 1b61ab8..0000000 --- a/ast/erfa/apco.c +++ /dev/null @@ -1,264 +0,0 @@ -#include "erfa.h" - -void eraApco(double date1, double date2, - double ebpv[2][3], double ehp[3], - double x, double y, double s, double theta, - double elong, double phi, double hm, - double xp, double yp, double sp, - double refa, double refb, - eraASTROM *astrom) -/* -** - - - - - - - - -** e r a A p c o -** - - - - - - - - -** -** For a terrestrial observer, prepare star-independent astrometry -** parameters for transformations between ICRS and observed -** coordinates. The caller supplies the Earth ephemeris, the Earth -** rotation information and the refraction constants as well as the -** site coordinates. -** -** Given: -** date1 double TDB as a 2-part... -** date2 double ...Julian Date (Note 1) -** ebpv double[2][3] Earth barycentric PV (au, au/day, Note 2) -** ehp double[3] Earth heliocentric P (au, Note 2) -** x,y double CIP X,Y (components of unit vector) -** s double the CIO locator s (radians) -** theta double Earth rotation angle (radians) -** elong double longitude (radians, east +ve, Note 3) -** phi double latitude (geodetic, radians, Note 3) -** hm double height above ellipsoid (m, geodetic, Note 3) -** xp,yp double polar motion coordinates (radians, Note 4) -** sp double the TIO locator s' (radians, Note 4) -** refa double refraction constant A (radians, Note 5) -** refb double refraction constant B (radians, Note 5) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. For most -** applications of this function the choice will not be at all -** critical. -** -** TT can be used instead of TDB without any significant impact on -** accuracy. -** -** 2) The vectors eb, eh, and all the astrom vectors, are with respect -** to BCRS axes. -** -** 3) The geographical coordinates are with respect to the ERFA_WGS84 -** reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN -** CONVENTION: the longitude required by the present function is -** right-handed, i.e. east-positive, in accordance with geographical -** convention. -** -** 4) xp and yp are the coordinates (in radians) of the Celestial -** Intermediate Pole with respect to the International Terrestrial -** Reference System (see IERS Conventions), measured along the -** meridians 0 and 90 deg west respectively. sp is the TIO locator -** s', in radians, which positions the Terrestrial Intermediate -** Origin on the equator. For many applications, xp, yp and -** (especially) sp can be set to zero. -** -** Internally, the polar motion is stored in a form rotated onto the -** local meridian. -** -** 5) The refraction constants refa and refb are for use in a -** dZ = A*tan(Z)+B*tan^3(Z) model, where Z is the observed -** (i.e. refracted) zenith distance and dZ is the amount of -** refraction. -** -** 6) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** 7) In cases where the caller does not wish to provide the Earth -** Ephemeris, the Earth rotation information and refraction -** constants, the function eraApco13 can be used instead of the -** present function. This starts from UTC and weather readings etc. -** and computes suitable values using other ERFA functions. -** -** 8) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 9) The context structure astrom produced by this function is used by -** eraAtioq, eraAtoiq, eraAtciq* and eraAticq*. -** -** Called: -** eraAper astrometry parameters: update ERA -** eraC2ixys celestial-to-intermediate matrix, given X,Y and s -** eraPvtob position/velocity of terrestrial station -** eraTrxpv product of transpose of r-matrix and pv-vector -** eraApcs astrometry parameters, ICRS-GCRS, space observer -** eraCr copy r-matrix -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double sl, cl, r[3][3], pvc[2][3], pv[2][3]; - - -/* Longitude with adjustment for TIO locator s'. */ - astrom->along = elong + sp; - -/* Polar motion, rotated onto the local meridian. */ - sl = sin(astrom->along); - cl = cos(astrom->along); - astrom->xpl = xp*cl - yp*sl; - astrom->ypl = xp*sl + yp*cl; - -/* Functions of latitude. */ - astrom->sphi = sin(phi); - astrom->cphi = cos(phi); - -/* Refraction constants. */ - astrom->refa = refa; - astrom->refb = refb; - -/* Local Earth rotation angle. */ - eraAper(theta, astrom); - -/* Disable the (redundant) diurnal aberration step. */ - astrom->diurab = 0.0; - -/* CIO based BPN matrix. */ - eraC2ixys(x, y, s, r); - -/* Observer's geocentric position and velocity (m, m/s, CIRS). */ - eraPvtob(elong, phi, hm, xp, yp, sp, theta, pvc); - -/* Rotate into GCRS. */ - eraTrxpv(r, pvc, pv); - -/* ICRS <-> GCRS parameters. */ - eraApcs(date1, date2, pv, ebpv, ehp, astrom); - -/* Store the CIO based BPN matrix. */ - eraCr(r, astrom->bpn ); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apco13.c b/ast/erfa/apco13.c deleted file mode 100644 index cdd4d4f..0000000 --- a/ast/erfa/apco13.c +++ /dev/null @@ -1,287 +0,0 @@ -#include "erfa.h" - -int eraApco13(double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - eraASTROM *astrom, double *eo) -/* -** - - - - - - - - - - -** e r a A p c o 1 3 -** - - - - - - - - - - -** -** For a terrestrial observer, prepare star-independent astrometry -** parameters for transformations between ICRS and observed -** coordinates. The caller supplies UTC, site coordinates, ambient air -** conditions and observing wavelength, and ERFA models are used to -** obtain the Earth ephemeris, CIP/CIO and refraction constants. -** -** The parameters produced by this function are required in the -** parallax, light deflection, aberration, and bias-precession-nutation -** parts of the ICRS/CIRS transformations. -** -** Given: -** utc1 double UTC as a 2-part... -** utc2 double ...quasi Julian Date (Notes 1,2) -** dut1 double UT1-UTC (seconds, Note 3) -** elong double longitude (radians, east +ve, Note 4) -** phi double latitude (geodetic, radians, Note 4) -** hm double height above ellipsoid (m, geodetic, Notes 4,6) -** xp,yp double polar motion coordinates (radians, Note 5) -** phpa double pressure at the observer (hPa = mB, Note 6) -** tc double ambient temperature at the observer (deg C) -** rh double relative humidity at the observer (range 0-1) -** wl double wavelength (micrometers, Note 7) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** eo double* equation of the origins (ERA-GST) -** -** Returned (function value): -** int status: +1 = dubious year (Note 2) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any -** convenient way between the two arguments, for example where utc1 -** is the Julian Day Number and utc2 is the fraction of a day. -** -** However, JD cannot unambiguously represent UTC during a leap -** second unless special measures are taken. The convention in the -** present function is that the JD day represents UTC days whether -** the length is 86399, 86400 or 86401 SI seconds. -** -** Applications should use the function eraDtf2d to convert from -** calendar date and time of day into 2-part quasi Julian Date, as -** it implements the leap-second-ambiguity convention just -** described. -** -** 2) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the -** future to be trusted. See eraDat for further details. -** -** 3) UT1-UTC is tabulated in IERS bulletins. It increases by exactly -** one second at the end of each positive UTC leap second, -** introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This -** practice is under review, and in the future UT1-UTC may grow -** essentially without limit. -** -** 4) The geographical coordinates are with respect to the ERFA_WGS84 -** reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the -** longitude required by the present function is east-positive -** (i.e. right-handed), in accordance with geographical convention. -** -** 5) The polar motion xp,yp can be obtained from IERS bulletins. The -** values are the coordinates (in radians) of the Celestial -** Intermediate Pole with respect to the International Terrestrial -** Reference System (see IERS Conventions 2003), measured along the -** meridians 0 and 90 deg west respectively. For many -** applications, xp and yp can be set to zero. -** -** Internally, the polar motion is stored in a form rotated onto -** the local meridian. -** -** 6) If hm, the height above the ellipsoid of the observing station -** in meters, is not known but phpa, the pressure in hPa (=mB), is -** available, an adequate estimate of hm can be obtained from the -** expression -** -** hm = -29.3 * tsl * log ( phpa / 1013.25 ); -** -** where tsl is the approximate sea-level air temperature in K -** (See Astrophysical Quantities, C.W.Allen, 3rd edition, section -** 52). Similarly, if the pressure phpa is not known, it can be -** estimated from the height of the observing station, hm, as -** follows: -** -** phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) ); -** -** Note, however, that the refraction is nearly proportional to -** the pressure and that an accurate phpa value is important for -** precise work. -** -** 7) The argument wl specifies the observing wavelength in -** micrometers. The transition from optical to radio is assumed to -** occur at 100 micrometers (about 3000 GHz). -** -** 8) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** 9) In cases where the caller wishes to supply his own Earth -** ephemeris, Earth rotation information and refraction constants, -** the function eraApco can be used instead of the present function. -** -** 10) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 11) The context structure astrom produced by this function is used -** by eraAtioq, eraAtoiq, eraAtciq* and eraAticq*. -** -** Called: -** eraUtctai UTC to TAI -** eraTaitt TAI to TT -** eraUtcut1 UTC to UT1 -** eraEpv00 Earth position and velocity -** eraPnm06a classical NPB matrix, IAU 2006/2000A -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraS06 the CIO locator s, given X,Y, IAU 2006 -** eraEra00 Earth rotation angle, IAU 2000 -** eraSp00 the TIO locator s', IERS 2000 -** eraRefco refraction constants for given ambient conditions -** eraApco astrometry parameters, ICRS-observed -** eraEors equation of the origins, given NPB matrix and s -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j; - double tai1, tai2, tt1, tt2, ut11, ut12, ehpv[2][3], ebpv[2][3], - r[3][3], x, y, s, theta, sp, refa, refb; - - -/* UTC to other time scales. */ - j = eraUtctai(utc1, utc2, &tai1, &tai2); - if ( j < 0 ) return -1; - j = eraTaitt(tai1, tai2, &tt1, &tt2); - j = eraUtcut1(utc1, utc2, dut1, &ut11, &ut12); - if ( j < 0 ) return -1; - -/* Earth barycentric & heliocentric position/velocity (au, au/d). */ - (void) eraEpv00(tt1, tt2, ehpv, ebpv); - -/* Form the equinox based BPN matrix, IAU 2006/2000A. */ - eraPnm06a(tt1, tt2, r); - -/* Extract CIP X,Y. */ - eraBpn2xy(r, &x, &y); - -/* Obtain CIO locator s. */ - s = eraS06(tt1, tt2, x, y); - -/* Earth rotation angle. */ - theta = eraEra00(ut11, ut12); - -/* TIO locator s'. */ - sp = eraSp00(tt1, tt2); - -/* Refraction constants A and B. */ - eraRefco(phpa, tc, rh, wl, &refa, &refb); - -/* Compute the star-independent astrometry parameters. */ - eraApco(tt1, tt2, ebpv, ehpv[0], x, y, s, theta, - elong, phi, hm, xp, yp, sp, refa, refb, astrom); - -/* Equation of the origins. */ - *eo = eraEors(r, s); - -/* Return any warning status. */ - return j; - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apcs.c b/ast/erfa/apcs.c deleted file mode 100644 index 0a34f14..0000000 --- a/ast/erfa/apcs.c +++ /dev/null @@ -1,233 +0,0 @@ -#include "erfa.h" - -void eraApcs(double date1, double date2, double pv[2][3], - double ebpv[2][3], double ehp[3], - eraASTROM *astrom) -/* -** - - - - - - - - -** e r a A p c s -** - - - - - - - - -** -** For an observer whose geocentric position and velocity are known, -** prepare star-independent astrometry parameters for transformations -** between ICRS and GCRS. The Earth ephemeris is supplied by the -** caller. -** -** The parameters produced by this function are required in the space -** motion, parallax, light deflection and aberration parts of the -** astrometric transformation chain. -** -** Given: -** date1 double TDB as a 2-part... -** date2 double ...Julian Date (Note 1) -** pv double[2][3] observer's geocentric pos/vel (m, m/s) -** ebpv double[2][3] Earth barycentric PV (au, au/day) -** ehp double[3] Earth heliocentric P (au) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double unchanged -** xpl double unchanged -** ypl double unchanged -** sphi double unchanged -** cphi double unchanged -** diurab double unchanged -** eral double unchanged -** refa double unchanged -** refb double unchanged -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. For most -** applications of this function the choice will not be at all -** critical. -** -** TT can be used instead of TDB without any significant impact on -** accuracy. -** -** 2) All the vectors are with respect to BCRS axes. -** -** 3) Providing separate arguments for (i) the observer's geocentric -** position and velocity and (ii) the Earth ephemeris is done for -** convenience in the geocentric, terrestrial and Earth orbit cases. -** For deep space applications it maybe more convenient to specify -** zero geocentric position and velocity and to supply the -** observer's position and velocity information directly instead of -** with respect to the Earth. However, note the different units: -** m and m/s for the geocentric vectors, au and au/day for the -** heliocentric and barycentric vectors. -** -** 4) In cases where the caller does not wish to provide the Earth -** ephemeris, the function eraApcs13 can be used instead of the -** present function. This computes the Earth ephemeris using the -** ERFA function eraEpv00. -** -** 5) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 6) The context structure astrom produced by this function is used by -** eraAtciq* and eraAticq*. -** -** Called: -** eraCp copy p-vector -** eraPm modulus of p-vector -** eraPn decompose p-vector into modulus and direction -** eraIr initialize r-matrix to identity -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* au/d to m/s */ - const double AUDMS = ERFA_DAU/ERFA_DAYSEC; - -/* Light time for 1 AU (day) */ - const double CR = ERFA_AULT/ERFA_DAYSEC; - - int i; - double dp, dv, pb[3], vb[3], ph[3], v2, w; - - -/* Time since reference epoch, years (for proper motion calculation). */ - astrom->pmt = ( (date1 - ERFA_DJ00) + date2 ) / ERFA_DJY; - -/* Adjust Earth ephemeris to observer. */ - for (i = 0; i < 3; i++) { - dp = pv[0][i] / ERFA_DAU; - dv = pv[1][i] / AUDMS; - pb[i] = ebpv[0][i] + dp; - vb[i] = ebpv[1][i] + dv; - ph[i] = ehp[i] + dp; - } - -/* Barycentric position of observer (au). */ - eraCp(pb, astrom->eb); - -/* Heliocentric direction and distance (unit vector and au). */ - eraPn(ph, &astrom->em, astrom->eh); - -/* Barycentric vel. in units of c, and reciprocal of Lorenz factor. */ - v2 = 0.0; - for (i = 0; i < 3; i++) { - w = vb[i] * CR; - astrom->v[i] = w; - v2 += w*w; - } - astrom->bm1 = sqrt(1.0 - v2); - -/* Reset the NPB matrix. */ - eraIr(astrom->bpn); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apcs13.c b/ast/erfa/apcs13.c deleted file mode 100644 index 0eb2d72..0000000 --- a/ast/erfa/apcs13.c +++ /dev/null @@ -1,191 +0,0 @@ -#include "erfa.h" - -void eraApcs13(double date1, double date2, double pv[2][3], - eraASTROM *astrom) -/* -** - - - - - - - - - - -** e r a A p c s 1 3 -** - - - - - - - - - - -** -** For an observer whose geocentric position and velocity are known, -** prepare star-independent astrometry parameters for transformations -** between ICRS and GCRS. The Earth ephemeris is from ERFA models. -** -** The parameters produced by this function are required in the space -** motion, parallax, light deflection and aberration parts of the -** astrometric transformation chain. -** -** Given: -** date1 double TDB as a 2-part... -** date2 double ...Julian Date (Note 1) -** pv double[2][3] observer's geocentric pos/vel (Note 3) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double unchanged -** xpl double unchanged -** ypl double unchanged -** sphi double unchanged -** cphi double unchanged -** diurab double unchanged -** eral double unchanged -** refa double unchanged -** refb double unchanged -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. For most -** applications of this function the choice will not be at all -** critical. -** -** TT can be used instead of TDB without any significant impact on -** accuracy. -** -** 2) All the vectors are with respect to BCRS axes. -** -** 3) The observer's position and velocity pv are geocentric but with -** respect to BCRS axes, and in units of m and m/s. No assumptions -** are made about proximity to the Earth, and the function can be -** used for deep space applications as well as Earth orbit and -** terrestrial. -** -** 4) In cases where the caller wishes to supply his own Earth -** ephemeris, the function eraApcs can be used instead of the present -** function. -** -** 5) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 6) The context structure astrom produced by this function is used by -** eraAtciq* and eraAticq*. -** -** Called: -** eraEpv00 Earth position and velocity -** eraApcs astrometry parameters, ICRS-GCRS, space observer -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double ehpv[2][3], ebpv[2][3]; - - -/* Earth barycentric & heliocentric position/velocity (au, au/d). */ - (void) eraEpv00(date1, date2, ehpv, ebpv); - -/* Compute the star-independent astrometry parameters. */ - eraApcs(date1, date2, pv, ebpv, ehpv[0], astrom); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/aper.c b/ast/erfa/aper.c deleted file mode 100644 index 372c565..0000000 --- a/ast/erfa/aper.c +++ /dev/null @@ -1,162 +0,0 @@ -#include "erfa.h" - -void eraAper(double theta, eraASTROM *astrom) -/* -** - - - - - - - - -** e r a A p e r -** - - - - - - - - -** -** In the star-independent astrometry parameters, update only the -** Earth rotation angle, supplied by the caller explicitly. -** -** Given: -** theta double Earth rotation angle (radians, Note 2) -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double not used -** eb double[3] not used -** eh double[3] not used -** em double not used -** v double[3] not used -** bm1 double not used -** bpn double[3][3] not used -** along double longitude + s' (radians) -** xpl double not used -** ypl double not used -** sphi double not used -** cphi double not used -** diurab double not used -** eral double not used -** refa double not used -** refb double not used -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double unchanged -** eb double[3] unchanged -** eh double[3] unchanged -** em double unchanged -** v double[3] unchanged -** bm1 double unchanged -** bpn double[3][3] unchanged -** along double unchanged -** xpl double unchanged -** ypl double unchanged -** sphi double unchanged -** cphi double unchanged -** diurab double unchanged -** eral double "local" Earth rotation angle (radians) -** refa double unchanged -** refb double unchanged -** -** Notes: -** -** 1) This function exists to enable sidereal-tracking applications to -** avoid wasteful recomputation of the bulk of the astrometry -** parameters: only the Earth rotation is updated. -** -** 2) For targets expressed as equinox based positions, such as -** classical geocentric apparent (RA,Dec), the supplied theta can be -** Greenwich apparent sidereal time rather than Earth rotation -** angle. -** -** 3) The function eraAper13 can be used instead of the present -** function, and starts from UT1 rather than ERA itself. -** -** 4) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - astrom->eral = theta + astrom->along; - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/aper13.c b/ast/erfa/aper13.c deleted file mode 100644 index e2b019c..0000000 --- a/ast/erfa/aper13.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "erfa.h" - -void eraAper13(double ut11, double ut12, eraASTROM *astrom) -/* -** - - - - - - - - - - -** e r a A p e r 1 3 -** - - - - - - - - - - -** -** In the star-independent astrometry parameters, update only the -** Earth rotation angle. The caller provides UT1, (n.b. not UTC). -** -** Given: -** ut11 double UT1 as a 2-part... -** ut12 double ...Julian Date (Note 1) -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double not used -** eb double[3] not used -** eh double[3] not used -** em double not used -** v double[3] not used -** bm1 double not used -** bpn double[3][3] not used -** along double longitude + s' (radians) -** xpl double not used -** ypl double not used -** sphi double not used -** cphi double not used -** diurab double not used -** eral double not used -** refa double not used -** refb double not used -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double unchanged -** eb double[3] unchanged -** eh double[3] unchanged -** em double unchanged -** v double[3] unchanged -** bm1 double unchanged -** bpn double[3][3] unchanged -** along double unchanged -** xpl double unchanged -** ypl double unchanged -** sphi double unchanged -** cphi double unchanged -** diurab double unchanged -** eral double "local" Earth rotation angle (radians) -** refa double unchanged -** refb double unchanged -** -** Notes: -** -** 1) The UT1 date (n.b. not UTC) ut11+ut12 is a Julian Date, -** apportioned in any convenient way between the arguments ut11 and -** ut12. For example, JD(UT1)=2450123.7 could be expressed in any -** of these ways, among others: -** -** ut11 ut12 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. The date & time method is -** best matched to the algorithm used: maximum precision is -** delivered when the ut11 argument is for 0hrs UT1 on the day in -** question and the ut12 argument lies in the range 0 to 1, or vice -** versa. -** -** 2) If the caller wishes to provide the Earth rotation angle itself, -** the function eraAper can be used instead. One use of this -** technique is to substitute Greenwich apparent sidereal time and -** thereby to support equinox based transformations directly. -** -** 3) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** Called: -** eraAper astrometry parameters: update ERA -** eraEra00 Earth rotation angle, IAU 2000 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraAper(eraEra00(ut11,ut12), astrom); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apio.c b/ast/erfa/apio.c deleted file mode 100644 index ebc5569..0000000 --- a/ast/erfa/apio.c +++ /dev/null @@ -1,213 +0,0 @@ -#include "erfa.h" - -void eraApio(double sp, double theta, - double elong, double phi, double hm, double xp, double yp, - double refa, double refb, - eraASTROM *astrom) -/* -** - - - - - - - - -** e r a A p i o -** - - - - - - - - -** -** For a terrestrial observer, prepare star-independent astrometry -** parameters for transformations between CIRS and observed -** coordinates. The caller supplies the Earth orientation information -** and the refraction constants as well as the site coordinates. -** -** Given: -** sp double the TIO locator s' (radians, Note 1) -** theta double Earth rotation angle (radians) -** elong double longitude (radians, east +ve, Note 2) -** phi double geodetic latitude (radians, Note 2) -** hm double height above ellipsoid (m, geodetic Note 2) -** xp,yp double polar motion coordinates (radians, Note 3) -** refa double refraction constant A (radians, Note 4) -** refb double refraction constant B (radians, Note 4) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double unchanged -** eb double[3] unchanged -** eh double[3] unchanged -** em double unchanged -** v double[3] unchanged -** bm1 double unchanged -** bpn double[3][3] unchanged -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** -** Notes: -** -** 1) sp, the TIO locator s', is a tiny quantity needed only by the -** most precise applications. It can either be set to zero or -** predicted using the ERFA function eraSp00. -** -** 2) The geographical coordinates are with respect to the ERFA_WGS84 -** reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the -** longitude required by the present function is east-positive -** (i.e. right-handed), in accordance with geographical convention. -** -** 3) The polar motion xp,yp can be obtained from IERS bulletins. The -** values are the coordinates (in radians) of the Celestial -** Intermediate Pole with respect to the International Terrestrial -** Reference System (see IERS Conventions 2003), measured along the -** meridians 0 and 90 deg west respectively. For many applications, -** xp and yp can be set to zero. -** -** Internally, the polar motion is stored in a form rotated onto the -** local meridian. -** -** 4) The refraction constants refa and refb are for use in a -** dZ = A*tan(Z)+B*tan^3(Z) model, where Z is the observed -** (i.e. refracted) zenith distance and dZ is the amount of -** refraction. -** -** 5) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** 6) In cases where the caller does not wish to provide the Earth -** rotation information and refraction constants, the function -** eraApio13 can be used instead of the present function. This -** starts from UTC and weather readings etc. and computes suitable -** values using other ERFA functions. -** -** 7) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 8) The context structure astrom produced by this function is used by -** eraAtioq and eraAtoiq. -** -** Called: -** eraPvtob position/velocity of terrestrial station -** eraAper astrometry parameters: update ERA -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double sl, cl, pv[2][3]; - - -/* Longitude with adjustment for TIO locator s'. */ - astrom->along = elong + sp; - -/* Polar motion, rotated onto the local meridian. */ - sl = sin(astrom->along); - cl = cos(astrom->along); - astrom->xpl = xp*cl - yp*sl; - astrom->ypl = xp*sl + yp*cl; - -/* Functions of latitude. */ - astrom->sphi = sin(phi); - astrom->cphi = cos(phi); - -/* Observer's geocentric position and velocity (m, m/s, CIRS). */ - eraPvtob(elong, phi, hm, xp, yp, sp, theta, pv); - -/* Magnitude of diurnal aberration vector. */ - astrom->diurab = sqrt(pv[1][0]*pv[1][0]+pv[1][1]*pv[1][1]) / ERFA_CMPS; - -/* Refraction constants. */ - astrom->refa = refa; - astrom->refb = refb; - -/* Local Earth rotation angle. */ - eraAper(theta, astrom); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/apio13.c b/ast/erfa/apio13.c deleted file mode 100644 index 4544c9e..0000000 --- a/ast/erfa/apio13.c +++ /dev/null @@ -1,259 +0,0 @@ -#include "erfa.h" - -int eraApio13(double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - eraASTROM *astrom) -/* -** - - - - - - - - - - -** e r a A p i o 1 3 -** - - - - - - - - - - -** -** For a terrestrial observer, prepare star-independent astrometry -** parameters for transformations between CIRS and observed -** coordinates. The caller supplies UTC, site coordinates, ambient air -** conditions and observing wavelength. -** -** Given: -** utc1 double UTC as a 2-part... -** utc2 double ...quasi Julian Date (Notes 1,2) -** dut1 double UT1-UTC (seconds) -** elong double longitude (radians, east +ve, Note 3) -** phi double geodetic latitude (radians, Note 3) -** hm double height above ellipsoid (m, geodetic Notes 4,6) -** xp,yp double polar motion coordinates (radians, Note 5) -** phpa double pressure at the observer (hPa = mB, Note 6) -** tc double ambient temperature at the observer (deg C) -** rh double relative humidity at the observer (range 0-1) -** wl double wavelength (micrometers, Note 7) -** -** Returned: -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double unchanged -** eb double[3] unchanged -** eh double[3] unchanged -** em double unchanged -** v double[3] unchanged -** bm1 double unchanged -** bpn double[3][3] unchanged -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** -** Returned (function value): -** int status: +1 = dubious year (Note 2) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any -** convenient way between the two arguments, for example where utc1 -** is the Julian Day Number and utc2 is the fraction of a day. -** -** However, JD cannot unambiguously represent UTC during a leap -** second unless special measures are taken. The convention in the -** present function is that the JD day represents UTC days whether -** the length is 86399, 86400 or 86401 SI seconds. -** -** Applications should use the function eraDtf2d to convert from -** calendar date and time of day into 2-part quasi Julian Date, as -** it implements the leap-second-ambiguity convention just -** described. -** -** 2) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the future -** to be trusted. See eraDat for further details. -** -** 3) UT1-UTC is tabulated in IERS bulletins. It increases by exactly -** one second at the end of each positive UTC leap second, -** introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This -** practice is under review, and in the future UT1-UTC may grow -** essentially without limit. -** -** 4) The geographical coordinates are with respect to the ERFA_WGS84 -** reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the -** longitude required by the present function is east-positive -** (i.e. right-handed), in accordance with geographical convention. -** -** 5) The polar motion xp,yp can be obtained from IERS bulletins. The -** values are the coordinates (in radians) of the Celestial -** Intermediate Pole with respect to the International Terrestrial -** Reference System (see IERS Conventions 2003), measured along the -** meridians 0 and 90 deg west respectively. For many applications, -** xp and yp can be set to zero. -** -** Internally, the polar motion is stored in a form rotated onto -** the local meridian. -** -** 6) If hm, the height above the ellipsoid of the observing station -** in meters, is not known but phpa, the pressure in hPa (=mB), is -** available, an adequate estimate of hm can be obtained from the -** expression -** -** hm = -29.3 * tsl * log ( phpa / 1013.25 ); -** -** where tsl is the approximate sea-level air temperature in K -** (See Astrophysical Quantities, C.W.Allen, 3rd edition, section -** 52). Similarly, if the pressure phpa is not known, it can be -** estimated from the height of the observing station, hm, as -** follows: -** -** phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) ); -** -** Note, however, that the refraction is nearly proportional to the -** pressure and that an accurate phpa value is important for -** precise work. -** -** 7) The argument wl specifies the observing wavelength in -** micrometers. The transition from optical to radio is assumed to -** occur at 100 micrometers (about 3000 GHz). -** -** 8) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** 9) In cases where the caller wishes to supply his own Earth -** rotation information and refraction constants, the function -** eraApc can be used instead of the present function. -** -** 10) This is one of several functions that inserts into the astrom -** structure star-independent parameters needed for the chain of -** astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed. -** -** The various functions support different classes of observer and -** portions of the transformation chain: -** -** functions observer transformation -** -** eraApcg eraApcg13 geocentric ICRS <-> GCRS -** eraApci eraApci13 terrestrial ICRS <-> CIRS -** eraApco eraApco13 terrestrial ICRS <-> observed -** eraApcs eraApcs13 space ICRS <-> GCRS -** eraAper eraAper13 terrestrial update Earth rotation -** eraApio eraApio13 terrestrial CIRS <-> observed -** -** Those with names ending in "13" use contemporary ERFA models to -** compute the various ephemerides. The others accept ephemerides -** supplied by the caller. -** -** The transformation from ICRS to GCRS covers space motion, -** parallax, light deflection, and aberration. From GCRS to CIRS -** comprises frame bias and precession-nutation. From CIRS to -** observed takes account of Earth rotation, polar motion, diurnal -** aberration and parallax (unless subsumed into the ICRS <-> GCRS -** transformation), and atmospheric refraction. -** -** 11) The context structure astrom produced by this function is used -** by eraAtioq and eraAtoiq. -** -** Called: -** eraUtctai UTC to TAI -** eraTaitt TAI to TT -** eraUtcut1 UTC to UT1 -** eraSp00 the TIO locator s', IERS 2000 -** eraEra00 Earth rotation angle, IAU 2000 -** eraRefco refraction constants for given ambient conditions -** eraApio astrometry parameters, CIRS-observed -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j; - double tai1, tai2, tt1, tt2, ut11, ut12, sp, theta, refa, refb; - - -/* UTC to other time scales. */ - j = eraUtctai(utc1, utc2, &tai1, &tai2); - if ( j < 0 ) return -1; - j = eraTaitt(tai1, tai2, &tt1, &tt2); - j = eraUtcut1(utc1, utc2, dut1, &ut11, &ut12); - if ( j < 0 ) return -1; - -/* TIO locator s'. */ - sp = eraSp00(tt1, tt2); - -/* Earth rotation angle. */ - theta = eraEra00(ut11, ut12); - -/* Refraction constants A and B. */ - eraRefco(phpa, tc, rh, wl, &refa, &refb); - -/* CIRS <-> observed astrometry parameters. */ - eraApio(sp, theta, elong, phi, hm, xp, yp, refa, refb, astrom); - -/* Return any warning status. */ - return j; - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atci13.c b/ast/erfa/atci13.c deleted file mode 100644 index 40a3a04..0000000 --- a/ast/erfa/atci13.c +++ /dev/null @@ -1,159 +0,0 @@ -#include "erfa.h" - -void eraAtci13(double rc, double dc, - double pr, double pd, double px, double rv, - double date1, double date2, - double *ri, double *di, double *eo) -/* -** - - - - - - - - - - -** e r a A t c i 1 3 -** - - - - - - - - - - -** -** Transform ICRS star data, epoch J2000.0, to CIRS. -** -** Given: -** rc double ICRS right ascension at J2000.0 (radians, Note 1) -** dc double ICRS declination at J2000.0 (radians, Note 1) -** pr double RA proper motion (radians/year; Note 2) -** pd double Dec proper motion (radians/year) -** px double parallax (arcsec) -** rv double radial velocity (km/s, +ve if receding) -** date1 double TDB as a 2-part... -** date2 double ...Julian Date (Note 3) -** -** Returned: -** ri,di double* CIRS geocentric RA,Dec (radians) -** eo double* equation of the origins (ERA-GST, Note 5) -** -** Notes: -** -** 1) Star data for an epoch other than J2000.0 (for example from the -** Hipparcos catalog, which has an epoch of J1991.25) will require a -** preliminary call to eraPmsafe before use. -** -** 2) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt. -** -** 3) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.8g could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.8g 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. For most -** applications of this function the choice will not be at all -** critical. -** -** TT can be used instead of TDB without any significant impact on -** accuracy. -** -** 4) The available accuracy is better than 1 milliarcsecond, limited -** mainly by the precession-nutation model that is used, namely -** IAU 2000A/2006. Very close to solar system bodies, additional -** errors of up to several milliarcseconds can occur because of -** unmodeled light deflection; however, the Sun's contribution is -** taken into account, to first order. The accuracy limitations of -** the ERFA function eraEpv00 (used to compute Earth position and -** velocity) can contribute aberration errors of up to -** 5 microarcseconds. Light deflection at the Sun's limb is -** uncertain at the 0.4 mas level. -** -** 5) Should the transformation to (equinox based) apparent place be -** required rather than (CIO based) intermediate place, subtract the -** equation of the origins from the returned right ascension: -** RA = RI - EO. (The eraAnp function can then be applied, as -** required, to keep the result in the conventional 0-2pi range.) -** -** Called: -** eraApci13 astrometry parameters, ICRS-CIRS, 2013 -** eraAtciq quick ICRS to CIRS -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Star-independent astrometry parameters */ - eraASTROM astrom; - - -/* The transformation parameters. */ - eraApci13(date1, date2, &astrom, eo); - -/* ICRS (epoch J2000.0) to CIRS. */ - eraAtciq(rc, dc, pr, pd, px, rv, &astrom, ri, di); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atciq.c b/ast/erfa/atciq.c deleted file mode 100644 index 68947ba..0000000 --- a/ast/erfa/atciq.c +++ /dev/null @@ -1,154 +0,0 @@ -#include "erfa.h" - -void eraAtciq(double rc, double dc, - double pr, double pd, double px, double rv, - eraASTROM *astrom, double *ri, double *di) -/* -** - - - - - - - - - -** e r a A t c i q -** - - - - - - - - - -** -** Quick ICRS, epoch J2000.0, to CIRS transformation, given precomputed -** star-independent astrometry parameters. -** -** Use of this function is appropriate when efficiency is important and -** where many star positions are to be transformed for one date. The -** star-independent parameters can be obtained by calling one of the -** functions eraApci[13], eraApcg[13], eraApco[13] or eraApcs[13]. -** -** If the parallax and proper motions are zero the eraAtciqz function -** can be used instead. -** -** Given: -** rc,dc double ICRS RA,Dec at J2000.0 (radians) -** pr double RA proper motion (radians/year; Note 3) -** pd double Dec proper motion (radians/year) -** px double parallax (arcsec) -** rv double radial velocity (km/s, +ve if receding) -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** -** Returned: -** ri,di double CIRS RA,Dec (radians) -** -** Notes: -** -** 1) All the vectors are with respect to BCRS axes. -** -** 2) Star data for an epoch other than J2000.0 (for example from the -** Hipparcos catalog, which has an epoch of J1991.25) will require a -** preliminary call to eraPmsafe before use. -** -** 3) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt. -** -** Called: -** eraPmpx proper motion and parallax -** eraLdsun light deflection by the Sun -** eraAb stellar aberration -** eraRxp product of r-matrix and pv-vector -** eraC2s p-vector to spherical -** eraAnp normalize angle into range 0 to 2pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double pco[3], pnat[3], ppr[3], pi[3], w; - - -/* Proper motion and parallax, giving BCRS coordinate direction. */ - eraPmpx(rc, dc, pr, pd, px, rv, astrom->pmt, astrom->eb, pco); - -/* Light deflection by the Sun, giving BCRS natural direction. */ - eraLdsun(pco, astrom->eh, astrom->em, pnat); - -/* Aberration, giving GCRS proper direction. */ - eraAb(pnat, astrom->v, astrom->em, astrom->bm1, ppr); - -/* Bias-precession-nutation, giving CIRS proper direction. */ - eraRxp(astrom->bpn, ppr, pi); - -/* CIRS RA,Dec. */ - eraC2s(pi, &w, di); - *ri = eraAnp(w); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atciqn.c b/ast/erfa/atciqn.c deleted file mode 100644 index 0ad89a0..0000000 --- a/ast/erfa/atciqn.c +++ /dev/null @@ -1,191 +0,0 @@ -#include "erfa.h" - -void eraAtciqn(double rc, double dc, double pr, double pd, - double px, double rv, eraASTROM *astrom, - int n, eraLDBODY b[], double *ri, double *di) -/* -** - - - - - - - - - - -** e r a A t c i q n -** - - - - - - - - - - -** -** Quick ICRS, epoch J2000.0, to CIRS transformation, given precomputed -** star-independent astrometry parameters plus a list of light- -** deflecting bodies. -** -** Use of this function is appropriate when efficiency is important and -** where many star positions are to be transformed for one date. The -** star-independent parameters can be obtained by calling one of the -** functions eraApci[13], eraApcg[13], eraApco[13] or eraApcs[13]. -** -** -** If the only light-deflecting body to be taken into account is the -** Sun, the eraAtciq function can be used instead. If in addition the -** parallax and proper motions are zero, the eraAtciqz function can be -** used. -** -** Given: -** rc,dc double ICRS RA,Dec at J2000.0 (radians) -** pr double RA proper motion (radians/year; Note 3) -** pd double Dec proper motion (radians/year) -** px double parallax (arcsec) -** rv double radial velocity (km/s, +ve if receding) -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** n int number of bodies (Note 3) -** b eraLDBODY[n] data for each of the n bodies (Notes 3,4): -** bm double mass of the body (solar masses, Note 5) -** dl double deflection limiter (Note 6) -** pv [2][3] barycentric PV of the body (au, au/day) -** -** Returned: -** ri,di double CIRS RA,Dec (radians) -** -** Notes: -** -** 1) Star data for an epoch other than J2000.0 (for example from the -** Hipparcos catalog, which has an epoch of J1991.25) will require a -** preliminary call to eraPmsafe before use. -** -** 2) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt. -** -** 3) The struct b contains n entries, one for each body to be -** considered. If n = 0, no gravitational light deflection will be -** applied, not even for the Sun. -** -** 4) The struct b should include an entry for the Sun as well as for -** any planet or other body to be taken into account. The entries -** should be in the order in which the light passes the body. -** -** 5) In the entry in the b struct for body i, the mass parameter -** b[i].bm can, as required, be adjusted in order to allow for such -** effects as quadrupole field. -** -** 6) The deflection limiter parameter b[i].dl is phi^2/2, where phi is -** the angular separation (in radians) between star and body at -** which limiting is applied. As phi shrinks below the chosen -** threshold, the deflection is artificially reduced, reaching zero -** for phi = 0. Example values suitable for a terrestrial -** observer, together with masses, are as follows: -** -** body i b[i].bm b[i].dl -** -** Sun 1.0 6e-6 -** Jupiter 0.00095435 3e-9 -** Saturn 0.00028574 3e-10 -** -** 7) For efficiency, validation of the contents of the b array is -** omitted. The supplied masses must be greater than zero, the -** position and velocity vectors must be right, and the deflection -** limiter greater than zero. -** -** Called: -** eraPmpx proper motion and parallax -** eraLdn light deflection by n bodies -** eraAb stellar aberration -** eraRxp product of r-matrix and pv-vector -** eraC2s p-vector to spherical -** eraAnp normalize angle into range 0 to 2pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double pco[3], pnat[3], ppr[3], pi[3], w; - - -/* Proper motion and parallax, giving BCRS coordinate direction. */ - eraPmpx(rc, dc, pr, pd, px, rv, astrom->pmt, astrom->eb, pco); - -/* Light deflection, giving BCRS natural direction. */ - eraLdn(n, b, astrom->eb, pco, pnat); - -/* Aberration, giving GCRS proper direction. */ - eraAb(pnat, astrom->v, astrom->em, astrom->bm1, ppr); - -/* Bias-precession-nutation, giving CIRS proper direction. */ - eraRxp(astrom->bpn, ppr, pi); - -/* CIRS RA,Dec. */ - eraC2s(pi, &w, di); - *ri = eraAnp(w); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atciqz.c b/ast/erfa/atciqz.c deleted file mode 100644 index d141b91..0000000 --- a/ast/erfa/atciqz.c +++ /dev/null @@ -1,153 +0,0 @@ -#include "erfa.h" - -void eraAtciqz(double rc, double dc, eraASTROM *astrom, - double *ri, double *di) -/* -** - - - - - - - - - - -** e r a A t c i q z -** - - - - - - - - - - -** -** Quick ICRS to CIRS transformation, given precomputed star- -** independent astrometry parameters, and assuming zero parallax and -** proper motion. -** -** Use of this function is appropriate when efficiency is important and -** where many star positions are to be transformed for one date. The -** star-independent parameters can be obtained by calling one of the -** functions eraApci[13], eraApcg[13], eraApco[13] or eraApcs[13]. -** -** The corresponding function for the case of non-zero parallax and -** proper motion is eraAtciq. -** -** Given: -** rc,dc double ICRS astrometric RA,Dec (radians) -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** -** Returned: -** ri,di double CIRS RA,Dec (radians) -** -** Note: -** -** All the vectors are with respect to BCRS axes. -** -** References: -** -** Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to -** the Astronomical Almanac, 3rd ed., University Science Books -** (2013). -** -** Klioner, Sergei A., "A practical relativistic model for micro- -** arcsecond astrometry in space", Astr. J. 125, 1580-1597 (2003). -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraLdsun light deflection due to Sun -** eraAb stellar aberration -** eraRxp product of r-matrix and p-vector -** eraC2s p-vector to spherical -** eraAnp normalize angle into range +/- pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double pco[3], pnat[3], ppr[3], pi[3], w; - - -/* BCRS coordinate direction (unit vector). */ - eraS2c(rc, dc, pco); - -/* Light deflection by the Sun, giving BCRS natural direction. */ - eraLdsun(pco, astrom->eh, astrom->em, pnat); - -/* Aberration, giving GCRS proper direction. */ - eraAb(pnat, astrom->v, astrom->em, astrom->bm1, ppr); - -/* Bias-precession-nutation, giving CIRS proper direction. */ - eraRxp(astrom->bpn, ppr, pi); - -/* CIRS RA,Dec. */ - eraC2s(pi, &w, di); - *ri = eraAnp(w); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atco13.c b/ast/erfa/atco13.c deleted file mode 100644 index eaaabe8..0000000 --- a/ast/erfa/atco13.c +++ /dev/null @@ -1,243 +0,0 @@ -#include "erfa.h" - -int eraAtco13(double rc, double dc, - double pr, double pd, double px, double rv, - double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - double *aob, double *zob, double *hob, - double *dob, double *rob, double *eo) -/* -** - - - - - - - - - - -** e r a A t c o 1 3 -** - - - - - - - - - - -** -** ICRS RA,Dec to observed place. The caller supplies UTC, site -** coordinates, ambient air conditions and observing wavelength. -** -** ERFA models are used for the Earth ephemeris, bias-precession- -** nutation, Earth orientation and refraction. -** -** Given: -** rc,dc double ICRS right ascension at J2000.0 (radians, Note 1) -** pr double RA proper motion (radians/year; Note 2) -** pd double Dec proper motion (radians/year) -** px double parallax (arcsec) -** rv double radial velocity (km/s, +ve if receding) -** utc1 double UTC as a 2-part... -** utc2 double ...quasi Julian Date (Notes 3-4) -** dut1 double UT1-UTC (seconds, Note 5) -** elong double longitude (radians, east +ve, Note 6) -** phi double latitude (geodetic, radians, Note 6) -** hm double height above ellipsoid (m, geodetic, Notes 6,8) -** xp,yp double polar motion coordinates (radians, Note 7) -** phpa double pressure at the observer (hPa = mB, Note 8) -** tc double ambient temperature at the observer (deg C) -** rh double relative humidity at the observer (range 0-1) -** wl double wavelength (micrometers, Note 9) -** -** Returned: -** aob double* observed azimuth (radians: N=0,E=90) -** zob double* observed zenith distance (radians) -** hob double* observed hour angle (radians) -** dob double* observed declination (radians) -** rob double* observed right ascension (CIO-based, radians) -** eo double* equation of the origins (ERA-GST) -** -** Returned (function value): -** int status: +1 = dubious year (Note 4) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) Star data for an epoch other than J2000.0 (for example from the -** Hipparcos catalog, which has an epoch of J1991.25) will require -** a preliminary call to eraPmsafe before use. -** -** 2) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt. -** -** 3) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any -** convenient way between the two arguments, for example where utc1 -** is the Julian Day Number and utc2 is the fraction of a day. -** -** However, JD cannot unambiguously represent UTC during a leap -** second unless special measures are taken. The convention in the -** present function is that the JD day represents UTC days whether -** the length is 86399, 86400 or 86401 SI seconds. -** -** Applications should use the function eraDtf2d to convert from -** calendar date and time of day into 2-part quasi Julian Date, as -** it implements the leap-second-ambiguity convention just -** described. -** -** 4) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the -** future to be trusted. See eraDat for further details. -** -** 5) UT1-UTC is tabulated in IERS bulletins. It increases by exactly -** one second at the end of each positive UTC leap second, -** introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This -** practice is under review, and in the future UT1-UTC may grow -** essentially without limit. -** -** 6) The geographical coordinates are with respect to the ERFA_WGS84 -** reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the -** longitude required by the present function is east-positive -** (i.e. right-handed), in accordance with geographical convention. -** -** 7) The polar motion xp,yp can be obtained from IERS bulletins. The -** values are the coordinates (in radians) of the Celestial -** Intermediate Pole with respect to the International Terrestrial -** Reference System (see IERS Conventions 2003), measured along the -** meridians 0 and 90 deg west respectively. For many -** applications, xp and yp can be set to zero. -** -** 8) If hm, the height above the ellipsoid of the observing station -** in meters, is not known but phpa, the pressure in hPa (=mB), -** is available, an adequate estimate of hm can be obtained from -** the expression -** -** hm = -29.3 * tsl * log ( phpa / 1013.25 ); -** -** where tsl is the approximate sea-level air temperature in K -** (See Astrophysical Quantities, C.W.Allen, 3rd edition, section -** 52). Similarly, if the pressure phpa is not known, it can be -** estimated from the height of the observing station, hm, as -** follows: -** -** phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) ); -** -** Note, however, that the refraction is nearly proportional to -** the pressure and that an accurate phpa value is important for -** precise work. -** -** 9) The argument wl specifies the observing wavelength in -** micrometers. The transition from optical to radio is assumed to -** occur at 100 micrometers (about 3000 GHz). -** -** 10) The accuracy of the result is limited by the corrections for -** refraction, which use a simple A*tan(z) + B*tan^3(z) model. -** Providing the meteorological parameters are known accurately and -** there are no gross local effects, the predicted observed -** coordinates should be within 0.05 arcsec (optical) or 1 arcsec -** (radio) for a zenith distance of less than 70 degrees, better -** than 30 arcsec (optical or radio) at 85 degrees and better -** than 20 arcmin (optical) or 30 arcmin (radio) at the horizon. -** -** Without refraction, the complementary functions eraAtco13 and -** eraAtoc13 are self-consistent to better than 1 microarcsecond -** all over the celestial sphere. With refraction included, -** consistency falls off at high zenith distances, but is still -** better than 0.05 arcsec at 85 degrees. -** -** 11) "Observed" Az,ZD means the position that would be seen by a -** perfect geodetically aligned theodolite. (Zenith distance is -** used rather than altitude in order to reflect the fact that no -** allowance is made for depression of the horizon.) This is -** related to the observed HA,Dec via the standard rotation, using -** the geodetic latitude (corrected for polar motion), while the -** observed HA and RA are related simply through the Earth rotation -** angle and the site longitude. "Observed" RA,Dec or HA,Dec thus -** means the position that would be seen by a perfect equatorial -** with its polar axis aligned to the Earth's axis of rotation. -** -** 12) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** Called: -** eraApco13 astrometry parameters, ICRS-observed, 2013 -** eraAtciq quick ICRS to CIRS -** eraAtioq quick CIRS to observed -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j; - eraASTROM astrom; - double ri, di; - - -/* Star-independent astrometry parameters. */ - j = eraApco13(utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, &astrom, eo); - -/* Abort if bad UTC. */ - if ( j < 0 ) return j; - -/* Transform ICRS to CIRS. */ - eraAtciq(rc, dc, pr, pd, px, rv, &astrom, &ri, &di); - -/* Transform CIRS to observed. */ - eraAtioq(ri, di, &astrom, aob, zob, hob, dob, rob); - -/* Return OK/warning status. */ - return j; - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atic13.c b/ast/erfa/atic13.c deleted file mode 100644 index bd70ce5..0000000 --- a/ast/erfa/atic13.c +++ /dev/null @@ -1,152 +0,0 @@ -#include "erfa.h" - -void eraAtic13(double ri, double di, double date1, double date2, - double *rc, double *dc, double *eo) -/* -** - - - - - - - - - - -** e r a A t i c 1 3 -** - - - - - - - - - - -** -** Transform star RA,Dec from geocentric CIRS to ICRS astrometric. -** -** Given: -** ri,di double CIRS geocentric RA,Dec (radians) -** date1 double TDB as a 2-part... -** date2 double ...Julian Date (Note 1) -** -** Returned: -** rc,dc double ICRS astrometric RA,Dec (radians) -** eo double equation of the origins (ERA-GST, Note 4) -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. For most -** applications of this function the choice will not be at all -** critical. -** -** TT can be used instead of TDB without any significant impact on -** accuracy. -** -** 2) Iterative techniques are used for the aberration and light -** deflection corrections so that the functions eraAtic13 (or -** eraAticq) and eraAtci13 (or eraAtciq) are accurate inverses; -** even at the edge of the Sun's disk the discrepancy is only about -** 1 nanoarcsecond. -** -** 3) The available accuracy is better than 1 milliarcsecond, limited -** mainly by the precession-nutation model that is used, namely -** IAU 2000A/2006. Very close to solar system bodies, additional -** errors of up to several milliarcseconds can occur because of -** unmodeled light deflection; however, the Sun's contribution is -** taken into account, to first order. The accuracy limitations of -** the ERFA function eraEpv00 (used to compute Earth position and -** velocity) can contribute aberration errors of up to -** 5 microarcseconds. Light deflection at the Sun's limb is -** uncertain at the 0.4 mas level. -** -** 4) Should the transformation to (equinox based) J2000.0 mean place -** be required rather than (CIO based) ICRS coordinates, subtract the -** equation of the origins from the returned right ascension: -** RA = RI - EO. (The eraAnp function can then be applied, as -** required, to keep the result in the conventional 0-2pi range.) -** -** Called: -** eraApci13 astrometry parameters, ICRS-CIRS, 2013 -** eraAticq quick CIRS to ICRS astrometric -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Star-independent astrometry parameters */ - eraASTROM astrom; - - -/* Star-independent astrometry parameters. */ - eraApci13(date1, date2, &astrom, eo); - -/* CIRS to ICRS astrometric. */ - eraAticq(ri, di, &astrom, rc, dc); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/aticq.c b/ast/erfa/aticq.c deleted file mode 100644 index 1e205b8..0000000 --- a/ast/erfa/aticq.c +++ /dev/null @@ -1,199 +0,0 @@ -#include "erfa.h" - -void eraAticq(double ri, double di, eraASTROM *astrom, - double *rc, double *dc) -/* -** - - - - - - - - - -** e r a A t i c q -** - - - - - - - - - -** -** Quick CIRS RA,Dec to ICRS astrometric place, given the star- -** independent astrometry parameters. -** -** Use of this function is appropriate when efficiency is important and -** where many star positions are all to be transformed for one date. -** The star-independent astrometry parameters can be obtained by -** calling one of the functions eraApci[13], eraApcg[13], eraApco[13] -** or eraApcs[13]. -** -** Given: -** ri,di double CIRS RA,Dec (radians) -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** -** Returned: -** rc,dc double ICRS astrometric RA,Dec (radians) -** -** Notes: -** -** 1) Only the Sun is taken into account in the light deflection -** correction. -** -** 2) Iterative techniques are used for the aberration and light -** deflection corrections so that the functions eraAtic13 (or -** eraAticq) and eraAtci13 (or eraAtciq) are accurate inverses; -** even at the edge of the Sun's disk the discrepancy is only about -** 1 nanoarcsecond. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraTrxp product of transpose of r-matrix and p-vector -** eraZp zero p-vector -** eraAb stellar aberration -** eraLdsun light deflection by the Sun -** eraC2s p-vector to spherical -** eraAnp normalize angle into range +/- pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j, i; - double pi[3], ppr[3], pnat[3], pco[3], w, d[3], before[3], r2, r, - after[3]; - - -/* CIRS RA,Dec to Cartesian. */ - eraS2c(ri, di, pi); - -/* Bias-precession-nutation, giving GCRS proper direction. */ - eraTrxp(astrom->bpn, pi, ppr); - -/* Aberration, giving GCRS natural direction. */ - eraZp(d); - for (j = 0; j < 2; j++) { - r2 = 0.0; - for (i = 0; i < 3; i++) { - w = ppr[i] - d[i]; - before[i] = w; - r2 += w*w; - } - r = sqrt(r2); - for (i = 0; i < 3; i++) { - before[i] /= r; - } - eraAb(before, astrom->v, astrom->em, astrom->bm1, after); - r2 = 0.0; - for (i = 0; i < 3; i++) { - d[i] = after[i] - before[i]; - w = ppr[i] - d[i]; - pnat[i] = w; - r2 += w*w; - } - r = sqrt(r2); - for (i = 0; i < 3; i++) { - pnat[i] /= r; - } - } - -/* Light deflection by the Sun, giving BCRS coordinate direction. */ - eraZp(d); - for (j = 0; j < 5; j++) { - r2 = 0.0; - for (i = 0; i < 3; i++) { - w = pnat[i] - d[i]; - before[i] = w; - r2 += w*w; - } - r = sqrt(r2); - for (i = 0; i < 3; i++) { - before[i] /= r; - } - eraLdsun(before, astrom->eh, astrom->em, after); - r2 = 0.0; - for (i = 0; i < 3; i++) { - d[i] = after[i] - before[i]; - w = pnat[i] - d[i]; - pco[i] = w; - r2 += w*w; - } - r = sqrt(r2); - for (i = 0; i < 3; i++) { - pco[i] /= r; - } - } - -/* ICRS astrometric RA,Dec. */ - eraC2s(pco, &w, dc); - *rc = eraAnp(w); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/aticqn.c b/ast/erfa/aticqn.c deleted file mode 100644 index d69119e..0000000 --- a/ast/erfa/aticqn.c +++ /dev/null @@ -1,237 +0,0 @@ -#include "erfa.h" - -void eraAticqn(double ri, double di, eraASTROM *astrom, - int n, eraLDBODY b[], double *rc, double *dc) -/* -** - - - - - - - - - -** e r a A t i c q n -** - - - - - - - - - -** -** Quick CIRS to ICRS astrometric place transformation, given the star- -** independent astrometry parameters plus a list of light-deflecting -** bodies. -** -** Use of this function is appropriate when efficiency is important and -** where many star positions are all to be transformed for one date. -** The star-independent astrometry parameters can be obtained by -** calling one of the functions eraApci[13], eraApcg[13], eraApco[13] -** or eraApcs[13]. -* -* If the only light-deflecting body to be taken into account is the -* Sun, the eraAticq function can be used instead. -** -** Given: -** ri,di double CIRS RA,Dec (radians) -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** n int number of bodies (Note 3) -** b eraLDBODY[n] data for each of the n bodies (Notes 3,4): -** bm double mass of the body (solar masses, Note 5) -** dl double deflection limiter (Note 6) -** pv [2][3] barycentric PV of the body (au, au/day) -** -** Returned: -** rc,dc double ICRS astrometric RA,Dec (radians) -** -** Notes: -** -** 1) Iterative techniques are used for the aberration and light -** deflection corrections so that the functions eraAticqn and -** eraAtciqn are accurate inverses; even at the edge of the Sun's -** disk the discrepancy is only about 1 nanoarcsecond. -** -** 2) If the only light-deflecting body to be taken into account is the -** Sun, the eraAticq function can be used instead. -** -** 3) The struct b contains n entries, one for each body to be -** considered. If n = 0, no gravitational light deflection will be -** applied, not even for the Sun. -** -** 4) The struct b should include an entry for the Sun as well as for -** any planet or other body to be taken into account. The entries -** should be in the order in which the light passes the body. -** -** 5) In the entry in the b struct for body i, the mass parameter -** b[i].bm can, as required, be adjusted in order to allow for such -** effects as quadrupole field. -** -** 6) The deflection limiter parameter b[i].dl is phi^2/2, where phi is -** the angular separation (in radians) between star and body at -** which limiting is applied. As phi shrinks below the chosen -** threshold, the deflection is artificially reduced, reaching zero -** for phi = 0. Example values suitable for a terrestrial -** observer, together with masses, are as follows: -** -** body i b[i].bm b[i].dl -** -** Sun 1.0 6e-6 -** Jupiter 0.00095435 3e-9 -** Saturn 0.00028574 3e-10 -** -** 7) For efficiency, validation of the contents of the b array is -** omitted. The supplied masses must be greater than zero, the -** position and velocity vectors must be right, and the deflection -** limiter greater than zero. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraTrxp product of transpose of r-matrix and p-vector -** eraZp zero p-vector -** eraAb stellar aberration -** eraLdn light deflection by n bodies -** eraC2s p-vector to spherical -** eraAnp normalize angle into range +/- pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j, i; - double pi[3], ppr[3], pnat[3], pco[3], w, d[3], before[3], r2, r, - after[3]; - - -/* CIRS RA,Dec to Cartesian. */ - eraS2c(ri, di, pi); - -/* Bias-precession-nutation, giving GCRS proper direction. */ - eraTrxp(astrom->bpn, pi, ppr); - -/* Aberration, giving GCRS natural direction. */ - eraZp(d); - for (j = 0; j < 2; j++) { - r2 = 0.0; - for (i = 0; i < 3; i++) { - w = ppr[i] - d[i]; - before[i] = w; - r2 += w*w; - } - r = sqrt(r2); - for (i = 0; i < 3; i++) { - before[i] /= r; - } - eraAb(before, astrom->v, astrom->em, astrom->bm1, after); - r2 = 0.0; - for (i = 0; i < 3; i++) { - d[i] = after[i] - before[i]; - w = ppr[i] - d[i]; - pnat[i] = w; - r2 += w*w; - } - r = sqrt(r2); - for (i = 0; i < 3; i++) { - pnat[i] /= r; - } - } - -/* Light deflection, giving BCRS coordinate direction. */ - eraZp(d); - for (j = 0; j < 5; j++) { - r2 = 0.0; - for (i = 0; i < 3; i++) { - w = pnat[i] - d[i]; - before[i] = w; - r2 += w*w; - } - r = sqrt(r2); - for (i = 0; i < 3; i++) { - before[i] /= r; - } - eraLdn(n, b, astrom->eb, before, after); - r2 = 0.0; - for (i = 0; i < 3; i++) { - d[i] = after[i] - before[i]; - w = pnat[i] - d[i]; - pco[i] = w; - r2 += w*w; - } - r = sqrt(r2); - for (i = 0; i < 3; i++) { - pco[i] /= r; - } - } - -/* ICRS astrometric RA,Dec. */ - eraC2s(pco, &w, dc); - *rc = eraAnp(w); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atio13.c b/ast/erfa/atio13.c deleted file mode 100644 index 6201776..0000000 --- a/ast/erfa/atio13.c +++ /dev/null @@ -1,222 +0,0 @@ -#include "erfa.h" - -int eraAtio13(double ri, double di, - double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - double *aob, double *zob, double *hob, - double *dob, double *rob) -/* -** - - - - - - - - - - -** e r a A t i o 1 3 -** - - - - - - - - - - -** -** CIRS RA,Dec to observed place. The caller supplies UTC, site -** coordinates, ambient air conditions and observing wavelength. -** -** Given: -** ri double CIRS right ascension (CIO-based, radians) -** di double CIRS declination (radians) -** utc1 double UTC as a 2-part... -** utc2 double ...quasi Julian Date (Notes 1,2) -** dut1 double UT1-UTC (seconds, Note 3) -** elong double longitude (radians, east +ve, Note 4) -** phi double geodetic latitude (radians, Note 4) -** hm double height above ellipsoid (m, geodetic Notes 4,6) -** xp,yp double polar motion coordinates (radians, Note 5) -** phpa double pressure at the observer (hPa = mB, Note 6) -** tc double ambient temperature at the observer (deg C) -** rh double relative humidity at the observer (range 0-1) -** wl double wavelength (micrometers, Note 7) -** -** Returned: -** aob double* observed azimuth (radians: N=0,E=90) -** zob double* observed zenith distance (radians) -** hob double* observed hour angle (radians) -** dob double* observed declination (radians) -** rob double* observed right ascension (CIO-based, radians) -** -** Returned (function value): -** int status: +1 = dubious year (Note 2) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any -** convenient way between the two arguments, for example where utc1 -** is the Julian Day Number and utc2 is the fraction of a day. -** -** However, JD cannot unambiguously represent UTC during a leap -** second unless special measures are taken. The convention in the -** present function is that the JD day represents UTC days whether -** the length is 86399, 86400 or 86401 SI seconds. -** -** Applications should use the function eraDtf2d to convert from -** calendar date and time of day into 2-part quasi Julian Date, as -** it implements the leap-second-ambiguity convention just -** described. -** -** 2) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the -** future to be trusted. See eraDat for further details. -** -** 3) UT1-UTC is tabulated in IERS bulletins. It increases by exactly -** one second at the end of each positive UTC leap second, -** introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This -** practice is under review, and in the future UT1-UTC may grow -** essentially without limit. -** -** 4) The geographical coordinates are with respect to the ERFA_WGS84 -** reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the -** longitude required by the present function is east-positive -** (i.e. right-handed), in accordance with geographical convention. -** -** 5) The polar motion xp,yp can be obtained from IERS bulletins. The -** values are the coordinates (in radians) of the Celestial -** Intermediate Pole with respect to the International Terrestrial -** Reference System (see IERS Conventions 2003), measured along the -** meridians 0 and 90 deg west respectively. For many -** applications, xp and yp can be set to zero. -** -** 6) If hm, the height above the ellipsoid of the observing station -** in meters, is not known but phpa, the pressure in hPa (=mB), is -** available, an adequate estimate of hm can be obtained from the -** expression -** -** hm = -29.3 * tsl * log ( phpa / 1013.25 ); -** -** where tsl is the approximate sea-level air temperature in K -** (See Astrophysical Quantities, C.W.Allen, 3rd edition, section -** 52). Similarly, if the pressure phpa is not known, it can be -** estimated from the height of the observing station, hm, as -** follows: -** -** phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) ); -** -** Note, however, that the refraction is nearly proportional to -** the pressure and that an accurate phpa value is important for -** precise work. -** -** 7) The argument wl specifies the observing wavelength in -** micrometers. The transition from optical to radio is assumed to -** occur at 100 micrometers (about 3000 GHz). -** -** 8) "Observed" Az,ZD means the position that would be seen by a -** perfect geodetically aligned theodolite. (Zenith distance is -** used rather than altitude in order to reflect the fact that no -** allowance is made for depression of the horizon.) This is -** related to the observed HA,Dec via the standard rotation, using -** the geodetic latitude (corrected for polar motion), while the -** observed HA and RA are related simply through the Earth rotation -** angle and the site longitude. "Observed" RA,Dec or HA,Dec thus -** means the position that would be seen by a perfect equatorial -** with its polar axis aligned to the Earth's axis of rotation. -** -** 9) The accuracy of the result is limited by the corrections for -** refraction, which use a simple A*tan(z) + B*tan^3(z) model. -** Providing the meteorological parameters are known accurately and -** there are no gross local effects, the predicted astrometric -** coordinates should be within 0.05 arcsec (optical) or 1 arcsec -** (radio) for a zenith distance of less than 70 degrees, better -** than 30 arcsec (optical or radio) at 85 degrees and better -** than 20 arcmin (optical) or 30 arcmin (radio) at the horizon. -** -** 10) The complementary functions eraAtio13 and eraAtoi13 are self- -** consistent to better than 1 microarcsecond all over the -** celestial sphere. -** -** 11) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** Called: -** eraApio13 astrometry parameters, CIRS-observed, 2013 -** eraAtioq quick CIRS to observed -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j; - eraASTROM astrom; - - -/* Star-independent astrometry parameters for CIRS->observed. */ - j = eraApio13(utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, &astrom); - -/* Abort if bad UTC. */ - if ( j < 0 ) return j; - -/* Transform CIRS to observed. */ - eraAtioq(ri, di, &astrom, aob, zob, hob, dob, rob); - -/* Return OK/warning status. */ - return j; - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atioq.c b/ast/erfa/atioq.c deleted file mode 100644 index d8a1f7b..0000000 --- a/ast/erfa/atioq.c +++ /dev/null @@ -1,243 +0,0 @@ -#include "erfa.h" - -void eraAtioq(double ri, double di, eraASTROM *astrom, - double *aob, double *zob, - double *hob, double *dob, double *rob) -/* -** - - - - - - - - - -** e r a A t i o q -** - - - - - - - - - -** -** Quick CIRS to observed place transformation. -** -** Use of this function is appropriate when efficiency is important and -** where many star positions are all to be transformed for one date. -** The star-independent astrometry parameters can be obtained by -** calling eraApio[13] or eraApco[13]. -** -** Given: -** ri double CIRS right ascension -** di double CIRS declination -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** -** Returned: -** aob double* observed azimuth (radians: N=0,E=90) -** zob double* observed zenith distance (radians) -** hob double* observed hour angle (radians) -** dob double* observed declination (radians) -** rob double* observed right ascension (CIO-based, radians) -** -** Notes: -** -** 1) This function returns zenith distance rather than altitude in -** order to reflect the fact that no allowance is made for -** depression of the horizon. -** -** 2) The accuracy of the result is limited by the corrections for -** refraction, which use a simple A*tan(z) + B*tan^3(z) model. -** Providing the meteorological parameters are known accurately and -** there are no gross local effects, the predicted observed -** coordinates should be within 0.05 arcsec (optical) or 1 arcsec -** (radio) for a zenith distance of less than 70 degrees, better -** than 30 arcsec (optical or radio) at 85 degrees and better -** than 20 arcmin (optical) or 30 arcmin (radio) at the horizon. -** -** Without refraction, the complementary functions eraAtioq and -** eraAtoiq are self-consistent to better than 1 microarcsecond all -** over the celestial sphere. With refraction included, consistency -** falls off at high zenith distances, but is still better than -** 0.05 arcsec at 85 degrees. -** -** 3) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** 4) The CIRS RA,Dec is obtained from a star catalog mean place by -** allowing for space motion, parallax, the Sun's gravitational lens -** effect, annual aberration and precession-nutation. For star -** positions in the ICRS, these effects can be applied by means of -** the eraAtci13 (etc.) functions. Starting from classical "mean -** place" systems, additional transformations will be needed first. -** -** 5) "Observed" Az,El means the position that would be seen by a -** perfect geodetically aligned theodolite. This is obtained from -** the CIRS RA,Dec by allowing for Earth orientation and diurnal -** aberration, rotating from equator to horizon coordinates, and -** then adjusting for refraction. The HA,Dec is obtained by -** rotating back into equatorial coordinates, and is the position -** that would be seen by a perfect equatorial with its polar axis -** aligned to the Earth's axis of rotation. Finally, the RA is -** obtained by subtracting the HA from the local ERA. -** -** 6) The star-independent CIRS-to-observed-place parameters in ASTROM -** may be computed with eraApio[13] or eraApco[13]. If nothing has -** changed significantly except the time, eraAper[13] may be used to -** perform the requisite adjustment to the astrom structure. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraC2s p-vector to spherical -** eraAnp normalize angle into range 0 to 2pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Minimum cos(alt) and sin(alt) for refraction purposes */ - const double CELMIN = 1e-6; - const double SELMIN = 0.05; - - double v[3], x, y, z, xhd, yhd, zhd, f, xhdt, yhdt, zhdt, - xaet, yaet, zaet, azobs, r, tz, w, del, cosdel, - xaeo, yaeo, zaeo, zdobs, hmobs, dcobs, raobs; - - -/* CIRS RA,Dec to Cartesian -HA,Dec. */ - eraS2c(ri-astrom->eral, di, v); - x = v[0]; - y = v[1]; - z = v[2]; - -/* Polar motion. */ - xhd = x + astrom->xpl*z; - yhd = y - astrom->ypl*z; - zhd = z - astrom->xpl*x + astrom->ypl*y; - -/* Diurnal aberration. */ - f = ( 1.0 - astrom->diurab*yhd ); - xhdt = f * xhd; - yhdt = f * ( yhd + astrom->diurab ); - zhdt = f * zhd; - -/* Cartesian -HA,Dec to Cartesian Az,El (S=0,E=90). */ - xaet = astrom->sphi*xhdt - astrom->cphi*zhdt; - yaet = yhdt; - zaet = astrom->cphi*xhdt + astrom->sphi*zhdt; - -/* Azimuth (N=0,E=90). */ - azobs = ( xaet != 0.0 || yaet != 0.0 ) ? atan2(yaet,-xaet) : 0.0; - -/* ---------- */ -/* Refraction */ -/* ---------- */ - -/* Cosine and sine of altitude, with precautions. */ - r = sqrt(xaet*xaet + yaet*yaet); - r = r > CELMIN ? r : CELMIN; - z = zaet > SELMIN ? zaet : SELMIN; - -/* A*tan(z)+B*tan^3(z) model, with Newton-Raphson correction. */ - tz = r/z; - w = astrom->refb*tz*tz; - del = ( astrom->refa + w ) * tz / - ( 1.0 + ( astrom->refa + 3.0*w ) / ( z*z ) ); - -/* Apply the change, giving observed vector. */ - cosdel = 1.0 - del*del/2.0; - f = cosdel - del*z/r; - xaeo = xaet*f; - yaeo = yaet*f; - zaeo = cosdel*zaet + del*r; - -/* Observed ZD. */ - zdobs = atan2(sqrt(xaeo*xaeo+yaeo*yaeo), zaeo); - -/* Az/El vector to HA,Dec vector (both right-handed). */ - v[0] = astrom->sphi*xaeo + astrom->cphi*zaeo; - v[1] = yaeo; - v[2] = - astrom->cphi*xaeo + astrom->sphi*zaeo; - -/* To spherical -HA,Dec. */ - eraC2s ( v, &hmobs, &dcobs ); - -/* Right ascension (with respect to CIO). */ - raobs = astrom->eral + hmobs; - -/* Return the results. */ - *aob = eraAnp(azobs); - *zob = zdobs; - *hob = -hmobs; - *dob = dcobs; - *rob = eraAnp(raobs); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atoc13.c b/ast/erfa/atoc13.c deleted file mode 100644 index 8f0932c..0000000 --- a/ast/erfa/atoc13.c +++ /dev/null @@ -1,233 +0,0 @@ -#include "erfa.h" - -int eraAtoc13(const char *type, double ob1, double ob2, - double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - double *rc, double *dc) -/* -** - - - - - - - - - - -** e r a A t o c 1 3 -** - - - - - - - - - - -** -** Observed place at a groundbased site to to ICRS astrometric RA,Dec. -** The caller supplies UTC, site coordinates, ambient air conditions -** and observing wavelength. -** -** Given: -** type char[] type of coordinates - "R", "H" or "A" (Notes 1,2) -** ob1 double observed Az, HA or RA (radians; Az is N=0,E=90) -** ob2 double observed ZD or Dec (radians) -** utc1 double UTC as a 2-part... -** utc2 double ...quasi Julian Date (Notes 3,4) -** dut1 double UT1-UTC (seconds, Note 5) -** elong double longitude (radians, east +ve, Note 6) -** phi double geodetic latitude (radians, Note 6) -** hm double height above ellipsoid (m, geodetic Notes 6,8) -** xp,yp double polar motion coordinates (radians, Note 7) -** phpa double pressure at the observer (hPa = mB, Note 8) -** tc double ambient temperature at the observer (deg C) -** rh double relative humidity at the observer (range 0-1) -** wl double wavelength (micrometers, Note 9) -** -** Returned: -** rc,dc double ICRS astrometric RA,Dec (radians) -** -** Returned (function value): -** int status: +1 = dubious year (Note 4) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) "Observed" Az,ZD means the position that would be seen by a -** perfect geodetically aligned theodolite. (Zenith distance is -** used rather than altitude in order to reflect the fact that no -** allowance is made for depression of the horizon.) This is -** related to the observed HA,Dec via the standard rotation, using -** the geodetic latitude (corrected for polar motion), while the -** observed HA and RA are related simply through the Earth rotation -** angle and the site longitude. "Observed" RA,Dec or HA,Dec thus -** means the position that would be seen by a perfect equatorial -** with its polar axis aligned to the Earth's axis of rotation. -** -** 2) Only the first character of the type argument is significant. -** "R" or "r" indicates that ob1 and ob2 are the observed right -** ascension and declination; "H" or "h" indicates that they are -** hour angle (west +ve) and declination; anything else ("A" or -** "a" is recommended) indicates that ob1 and ob2 are azimuth -** (north zero, east 90 deg) and zenith distance. -** -** 3) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any -** convenient way between the two arguments, for example where utc1 -** is the Julian Day Number and utc2 is the fraction of a day. -** -** However, JD cannot unambiguously represent UTC during a leap -** second unless special measures are taken. The convention in the -** present function is that the JD day represents UTC days whether -** the length is 86399, 86400 or 86401 SI seconds. -** -** Applications should use the function eraDtf2d to convert from -** calendar date and time of day into 2-part quasi Julian Date, as -** it implements the leap-second-ambiguity convention just -** described. -** -** 4) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the -** future to be trusted. See eraDat for further details. -** -** 5) UT1-UTC is tabulated in IERS bulletins. It increases by exactly -** one second at the end of each positive UTC leap second, -** introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This -** practice is under review, and in the future UT1-UTC may grow -** essentially without limit. -** -** 6) The geographical coordinates are with respect to the ERFA_WGS84 -** reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the -** longitude required by the present function is east-positive -** (i.e. right-handed), in accordance with geographical convention. -** -** 7) The polar motion xp,yp can be obtained from IERS bulletins. The -** values are the coordinates (in radians) of the Celestial -** Intermediate Pole with respect to the International Terrestrial -** Reference System (see IERS Conventions 2003), measured along the -** meridians 0 and 90 deg west respectively. For many -** applications, xp and yp can be set to zero. -** -** 8) If hm, the height above the ellipsoid of the observing station -** in meters, is not known but phpa, the pressure in hPa (=mB), is -** available, an adequate estimate of hm can be obtained from the -** expression -** -** hm = -29.3 * tsl * log ( phpa / 1013.25 ); -** -** where tsl is the approximate sea-level air temperature in K -** (See Astrophysical Quantities, C.W.Allen, 3rd edition, section -** 52). Similarly, if the pressure phpa is not known, it can be -** estimated from the height of the observing station, hm, as -** follows: -** -** phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) ); -** -** Note, however, that the refraction is nearly proportional to -** the pressure and that an accurate phpa value is important for -** precise work. -** -** 9) The argument wl specifies the observing wavelength in -** micrometers. The transition from optical to radio is assumed to -** occur at 100 micrometers (about 3000 GHz). -** -** 10) The accuracy of the result is limited by the corrections for -** refraction, which use a simple A*tan(z) + B*tan^3(z) model. -** Providing the meteorological parameters are known accurately and -** there are no gross local effects, the predicted astrometric -** coordinates should be within 0.05 arcsec (optical) or 1 arcsec -** (radio) for a zenith distance of less than 70 degrees, better -** than 30 arcsec (optical or radio) at 85 degrees and better -** than 20 arcmin (optical) or 30 arcmin (radio) at the horizon. -** -** Without refraction, the complementary functions eraAtco13 and -** eraAtoc13 are self-consistent to better than 1 microarcsecond -** all over the celestial sphere. With refraction included, -** consistency falls off at high zenith distances, but is still -** better than 0.05 arcsec at 85 degrees. -** -** 11) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** Called: -** eraApco13 astrometry parameters, ICRS-observed -** eraAtoiq quick observed to CIRS -** eraAticq quick CIRS to ICRS -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j; - eraASTROM astrom; - double eo, ri, di; - - -/* Star-independent astrometry parameters. */ - j = eraApco13(utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, &astrom, &eo); - -/* Abort if bad UTC. */ - if ( j < 0 ) return j; - -/* Transform observed to CIRS. */ - eraAtoiq(type, ob1, ob2, &astrom, &ri, &di); - -/* Transform CIRS to ICRS. */ - eraAticq(ri, di, &astrom, rc, dc); - -/* Return OK/warning status. */ - return j; - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atoi13.c b/ast/erfa/atoi13.c deleted file mode 100644 index 41f2632..0000000 --- a/ast/erfa/atoi13.c +++ /dev/null @@ -1,228 +0,0 @@ -#include "erfa.h" - -int eraAtoi13(const char *type, double ob1, double ob2, - double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - double *ri, double *di) -/* -** - - - - - - - - - - -** e r a A t o i 1 3 -** - - - - - - - - - - -** -** Observed place to CIRS. The caller supplies UTC, site coordinates, -** ambient air conditions and observing wavelength. -** -** Given: -** type char[] type of coordinates - "R", "H" or "A" (Notes 1,2) -** ob1 double observed Az, HA or RA (radians; Az is N=0,E=90) -** ob2 double observed ZD or Dec (radians) -** utc1 double UTC as a 2-part... -** utc2 double ...quasi Julian Date (Notes 3,4) -** dut1 double UT1-UTC (seconds, Note 5) -** elong double longitude (radians, east +ve, Note 6) -** phi double geodetic latitude (radians, Note 6) -** hm double height above the ellipsoid (meters, Notes 6,8) -** xp,yp double polar motion coordinates (radians, Note 7) -** phpa double pressure at the observer (hPa = mB, Note 8) -** tc double ambient temperature at the observer (deg C) -** rh double relative humidity at the observer (range 0-1) -** wl double wavelength (micrometers, Note 9) -** -** Returned: -** ri double* CIRS right ascension (CIO-based, radians) -** di double* CIRS declination (radians) -** -** Returned (function value): -** int status: +1 = dubious year (Note 2) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) "Observed" Az,ZD means the position that would be seen by a -** perfect geodetically aligned theodolite. (Zenith distance is -** used rather than altitude in order to reflect the fact that no -** allowance is made for depression of the horizon.) This is -** related to the observed HA,Dec via the standard rotation, using -** the geodetic latitude (corrected for polar motion), while the -** observed HA and RA are related simply through the Earth rotation -** angle and the site longitude. "Observed" RA,Dec or HA,Dec thus -** means the position that would be seen by a perfect equatorial -** with its polar axis aligned to the Earth's axis of rotation. -** -** 2) Only the first character of the type argument is significant. -** "R" or "r" indicates that ob1 and ob2 are the observed right -** ascension and declination; "H" or "h" indicates that they are -** hour angle (west +ve) and declination; anything else ("A" or -** "a" is recommended) indicates that ob1 and ob2 are azimuth -** (north zero, east 90 deg) and zenith distance. -** -** 3) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any -** convenient way between the two arguments, for example where utc1 -** is the Julian Day Number and utc2 is the fraction of a day. -** -** However, JD cannot unambiguously represent UTC during a leap -** second unless special measures are taken. The convention in the -** present function is that the JD day represents UTC days whether -** the length is 86399, 86400 or 86401 SI seconds. -** -** Applications should use the function eraDtf2d to convert from -** calendar date and time of day into 2-part quasi Julian Date, as -** it implements the leap-second-ambiguity convention just -** described. -** -** 4) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the -** future to be trusted. See eraDat for further details. -** -** 5) UT1-UTC is tabulated in IERS bulletins. It increases by exactly -** one second at the end of each positive UTC leap second, -** introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This -** practice is under review, and in the future UT1-UTC may grow -** essentially without limit. -** -** 6) The geographical coordinates are with respect to the ERFA_WGS84 -** reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the -** longitude required by the present function is east-positive -** (i.e. right-handed), in accordance with geographical convention. -** -** 7) The polar motion xp,yp can be obtained from IERS bulletins. The -** values are the coordinates (in radians) of the Celestial -** Intermediate Pole with respect to the International Terrestrial -** Reference System (see IERS Conventions 2003), measured along the -** meridians 0 and 90 deg west respectively. For many -** applications, xp and yp can be set to zero. -** -** 8) If hm, the height above the ellipsoid of the observing station -** in meters, is not known but phpa, the pressure in hPa (=mB), is -** available, an adequate estimate of hm can be obtained from the -** expression -** -** hm = -29.3 * tsl * log ( phpa / 1013.25 ); -** -** where tsl is the approximate sea-level air temperature in K -** (See Astrophysical Quantities, C.W.Allen, 3rd edition, section -** 52). Similarly, if the pressure phpa is not known, it can be -** estimated from the height of the observing station, hm, as -** follows: -** -** phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) ); -** -** Note, however, that the refraction is nearly proportional to -** the pressure and that an accurate phpa value is important for -** precise work. -** -** 9) The argument wl specifies the observing wavelength in -** micrometers. The transition from optical to radio is assumed to -** occur at 100 micrometers (about 3000 GHz). -** -** 10) The accuracy of the result is limited by the corrections for -** refraction, which use a simple A*tan(z) + B*tan^3(z) model. -** Providing the meteorological parameters are known accurately and -** there are no gross local effects, the predicted astrometric -** coordinates should be within 0.05 arcsec (optical) or 1 arcsec -** (radio) for a zenith distance of less than 70 degrees, better -** than 30 arcsec (optical or radio) at 85 degrees and better -** than 20 arcmin (optical) or 30 arcmin (radio) at the horizon. -** -** Without refraction, the complementary functions eraAtio13 and -** eraAtoi13 are self-consistent to better than 1 microarcsecond -** all over the celestial sphere. With refraction included, -** consistency falls off at high zenith distances, but is still -** better than 0.05 arcsec at 85 degrees. -** -** 12) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** Called: -** eraApio13 astrometry parameters, CIRS-observed, 2013 -** eraAtoiq quick observed to CIRS -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j; - eraASTROM astrom; - - -/* Star-independent astrometry parameters for CIRS->observed. */ - j = eraApio13(utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, &astrom); - -/* Abort if bad UTC. */ - if ( j < 0 ) return j; - -/* Transform observed to CIRS. */ - eraAtoiq(type, ob1, ob2, &astrom, ri, di); - -/* Return OK/warning status. */ - return j; - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/atoiq.c b/ast/erfa/atoiq.c deleted file mode 100644 index d5501a7..0000000 --- a/ast/erfa/atoiq.c +++ /dev/null @@ -1,260 +0,0 @@ -#include "erfa.h" - -void eraAtoiq(const char *type, - double ob1, double ob2, eraASTROM *astrom, - double *ri, double *di) -/* -** - - - - - - - - - -** e r a A t o i q -** - - - - - - - - - -** -** Quick observed place to CIRS, given the star-independent astrometry -** parameters. -** -** Use of this function is appropriate when efficiency is important and -** where many star positions are all to be transformed for one date. -** The star-independent astrometry parameters can be obtained by -** calling eraApio[13] or eraApco[13]. -** -** Given: -** type char[] type of coordinates: "R", "H" or "A" (Note 1) -** ob1 double observed Az, HA or RA (radians; Az is N=0,E=90) -** ob2 double observed ZD or Dec (radians) -** astrom eraASTROM* star-independent astrometry parameters: -** pmt double PM time interval (SSB, Julian years) -** eb double[3] SSB to observer (vector, au) -** eh double[3] Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** v double[3] barycentric observer velocity (vector, c) -** bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor -** bpn double[3][3] bias-precession-nutation matrix -** along double longitude + s' (radians) -** xpl double polar motion xp wrt local meridian (radians) -** ypl double polar motion yp wrt local meridian (radians) -** sphi double sine of geodetic latitude -** cphi double cosine of geodetic latitude -** diurab double magnitude of diurnal aberration vector -** eral double "local" Earth rotation angle (radians) -** refa double refraction constant A (radians) -** refb double refraction constant B (radians) -** -** Returned: -** ri double* CIRS right ascension (CIO-based, radians) -** di double* CIRS declination (radians) -** -** Notes: -** -** 1) "Observed" Az,El means the position that would be seen by a -** perfect geodetically aligned theodolite. This is related to -** the observed HA,Dec via the standard rotation, using the geodetic -** latitude (corrected for polar motion), while the observed HA and -** RA are related simply through the Earth rotation angle and the -** site longitude. "Observed" RA,Dec or HA,Dec thus means the -** position that would be seen by a perfect equatorial with its -** polar axis aligned to the Earth's axis of rotation. By removing -** from the observed place the effects of atmospheric refraction and -** diurnal aberration, the CIRS RA,Dec is obtained. -** -** 2) Only the first character of the type argument is significant. -** "R" or "r" indicates that ob1 and ob2 are the observed right -** ascension and declination; "H" or "h" indicates that they are -** hour angle (west +ve) and declination; anything else ("A" or -** "a" is recommended) indicates that ob1 and ob2 are azimuth (north -** zero, east 90 deg) and zenith distance. (Zenith distance is used -** rather than altitude in order to reflect the fact that no -** allowance is made for depression of the horizon.) -** -** 3) The accuracy of the result is limited by the corrections for -** refraction, which use a simple A*tan(z) + B*tan^3(z) model. -** Providing the meteorological parameters are known accurately and -** there are no gross local effects, the predicted observed -** coordinates should be within 0.05 arcsec (optical) or 1 arcsec -** (radio) for a zenith distance of less than 70 degrees, better -** than 30 arcsec (optical or radio) at 85 degrees and better than -** 20 arcmin (optical) or 30 arcmin (radio) at the horizon. -** -** Without refraction, the complementary functions eraAtioq and -** eraAtoiq are self-consistent to better than 1 microarcsecond all -** over the celestial sphere. With refraction included, consistency -** falls off at high zenith distances, but is still better than -** 0.05 arcsec at 85 degrees. -** -** 4) It is advisable to take great care with units, as even unlikely -** values of the input parameters are accepted and processed in -** accordance with the models used. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraC2s p-vector to spherical -** eraAnp normalize angle into range 0 to 2pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int c; - double c1, c2, sphi, cphi, ce, xaeo, yaeo, zaeo, v[3], - xmhdo, ymhdo, zmhdo, az, sz, zdo, refa, refb, tz, dref, - zdt, xaet, yaet, zaet, xmhda, ymhda, zmhda, - f, xhd, yhd, zhd, xpl, ypl, w, hma; - - -/* Coordinate type. */ - c = (int) type[0]; - -/* Coordinates. */ - c1 = ob1; - c2 = ob2; - -/* Sin, cos of latitude. */ - sphi = astrom->sphi; - cphi = astrom->cphi; - -/* Standardize coordinate type. */ - if ( c == 'r' || c == 'R' ) { - c = 'R'; - } else if ( c == 'h' || c == 'H' ) { - c = 'H'; - } else { - c = 'A'; - } - -/* If Az,ZD, convert to Cartesian (S=0,E=90). */ - if ( c == 'A' ) { - ce = sin(c2); - xaeo = - cos(c1) * ce; - yaeo = sin(c1) * ce; - zaeo = cos(c2); - - } else { - - /* If RA,Dec, convert to HA,Dec. */ - if ( c == 'R' ) c1 = astrom->eral - c1; - - /* To Cartesian -HA,Dec. */ - eraS2c ( -c1, c2, v ); - xmhdo = v[0]; - ymhdo = v[1]; - zmhdo = v[2]; - - /* To Cartesian Az,El (S=0,E=90). */ - xaeo = sphi*xmhdo - cphi*zmhdo; - yaeo = ymhdo; - zaeo = cphi*xmhdo + sphi*zmhdo; - } - -/* Azimuth (S=0,E=90). */ - az = ( xaeo != 0.0 || yaeo != 0.0 ) ? atan2(yaeo,xaeo) : 0.0; - -/* Sine of observed ZD, and observed ZD. */ - sz = sqrt ( xaeo*xaeo + yaeo*yaeo ); - zdo = atan2 ( sz, zaeo ); - -/* -** Refraction -** ---------- -*/ - -/* Fast algorithm using two constant model. */ - refa = astrom->refa; - refb = astrom->refb; - tz = sz / zaeo; - dref = ( refa + refb*tz*tz ) * tz; - zdt = zdo + dref; - -/* To Cartesian Az,ZD. */ - ce = sin(zdt); - xaet = cos(az) * ce; - yaet = sin(az) * ce; - zaet = cos(zdt); - -/* Cartesian Az,ZD to Cartesian -HA,Dec. */ - xmhda = sphi*xaet + cphi*zaet; - ymhda = yaet; - zmhda = - cphi*xaet + sphi*zaet; - -/* Diurnal aberration. */ - f = ( 1.0 + astrom->diurab*ymhda ); - xhd = f * xmhda; - yhd = f * ( ymhda - astrom->diurab ); - zhd = f * zmhda; - -/* Polar motion. */ - xpl = astrom->xpl; - ypl = astrom->ypl; - w = xpl*xhd - ypl*yhd + zhd; - v[0] = xhd - xpl*w; - v[1] = yhd + ypl*w; - v[2] = w - ( xpl*xpl + ypl*ypl ) * zhd; - -/* To spherical -HA,Dec. */ - eraC2s(v, &hma, di); - -/* Right ascension. */ - *ri = eraAnp(astrom->eral + hma); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/bi00.c b/ast/erfa/bi00.c deleted file mode 100644 index 9000221..0000000 --- a/ast/erfa/bi00.c +++ /dev/null @@ -1,125 +0,0 @@ -#include "erfa.h" - -void eraBi00(double *dpsibi, double *depsbi, double *dra) -/* -** - - - - - - - - -** e r a B i 0 0 -** - - - - - - - - -** -** Frame bias components of IAU 2000 precession-nutation models (part -** of MHB2000 with additions). -** -** Returned: -** dpsibi,depsbi double longitude and obliquity corrections -** dra double the ICRS RA of the J2000.0 mean equinox -** -** Notes: -** -** 1) The frame bias corrections in longitude and obliquity (radians) -** are required in order to correct for the offset between the GCRS -** pole and the mean J2000.0 pole. They define, with respect to the -** GCRS frame, a J2000.0 mean pole that is consistent with the rest -** of the IAU 2000A precession-nutation model. -** -** 2) In addition to the displacement of the pole, the complete -** description of the frame bias requires also an offset in right -** ascension. This is not part of the IAU 2000A model, and is from -** Chapront et al. (2002). It is returned in radians. -** -** 3) This is a supplemented implementation of one aspect of the IAU -** 2000A nutation model, formally adopted by the IAU General -** Assembly in 2000, namely MHB2000 (Mathews et al. 2002). -** -** References: -** -** Chapront, J., Chapront-Touze, M. & Francou, G., Astron. -** Astrophys., 387, 700, 2002. -** -** Mathews, P.M., Herring, T.A., Buffet, B.A., "Modeling of nutation -** and precession New nutation series for nonrigid Earth and -** insights into the Earth's interior", J.Geophys.Res., 107, B4, -** 2002. The MHB2000 code itself was obtained on 9th September 2002 -** from ftp://maia.usno.navy.mil/conv2000/chapter5/IAU2000A. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* The frame bias corrections in longitude and obliquity */ - const double DPBIAS = -0.041775 * ERFA_DAS2R, - DEBIAS = -0.0068192 * ERFA_DAS2R; - -/* The ICRS RA of the J2000.0 equinox (Chapront et al., 2002) */ - const double DRA0 = -0.0146 * ERFA_DAS2R; - - -/* Return the results (which are fixed). */ - *dpsibi = DPBIAS; - *depsbi = DEBIAS; - *dra = DRA0; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/bp00.c b/ast/erfa/bp00.c deleted file mode 100644 index dd387ea..0000000 --- a/ast/erfa/bp00.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "erfa.h" - -void eraBp00(double date1, double date2, - double rb[3][3], double rp[3][3], double rbp[3][3]) -/* -** - - - - - - - - -** e r a B p 0 0 -** - - - - - - - - -** -** Frame bias and precession, IAU 2000. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rb double[3][3] frame bias matrix (Note 2) -** rp double[3][3] precession matrix (Note 3) -** rbp double[3][3] bias-precession matrix (Note 4) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix rb transforms vectors from GCRS to mean J2000.0 by -** applying frame bias. -** -** 3) The matrix rp transforms vectors from J2000.0 mean equator and -** equinox to mean equator and equinox of date by applying -** precession. -** -** 4) The matrix rbp transforms vectors from GCRS to mean equator and -** equinox of date by applying frame bias then precession. It is -** the product rp x rb. -** -** 5) It is permissible to re-use the same array in the returned -** arguments. The arrays are filled in the order given. -** -** Called: -** eraBi00 frame bias components, IAU 2000 -** eraPr00 IAU 2000 precession adjustments -** eraIr initialize r-matrix to identity -** eraRx rotate around X-axis -** eraRy rotate around Y-axis -** eraRz rotate around Z-axis -** eraCr copy r-matrix -** eraRxr product of two r-matrices -** -** Reference: -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* J2000.0 obliquity (Lieske et al. 1977) */ - const double EPS0 = 84381.448 * ERFA_DAS2R; - - double t, dpsibi, depsbi, dra0, psia77, oma77, chia, - dpsipr, depspr, psia, oma, rbw[3][3]; - - -/* Interval between fundamental epoch J2000.0 and current date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Frame bias. */ - eraBi00(&dpsibi, &depsbi, &dra0); - -/* Precession angles (Lieske et al. 1977) */ - psia77 = (5038.7784 + (-1.07259 + (-0.001147) * t) * t) * t * ERFA_DAS2R; - oma77 = EPS0 + ((0.05127 + (-0.007726) * t) * t) * t * ERFA_DAS2R; - chia = ( 10.5526 + (-2.38064 + (-0.001125) * t) * t) * t * ERFA_DAS2R; - -/* Apply IAU 2000 precession corrections. */ - eraPr00(date1, date2, &dpsipr, &depspr); - psia = psia77 + dpsipr; - oma = oma77 + depspr; - -/* Frame bias matrix: GCRS to J2000.0. */ - eraIr(rbw); - eraRz(dra0, rbw); - eraRy(dpsibi*sin(EPS0), rbw); - eraRx(-depsbi, rbw); - eraCr(rbw, rb); - -/* Precession matrix: J2000.0 to mean of date. */ - eraIr(rp); - eraRx(EPS0, rp); - eraRz(-psia, rp); - eraRx(-oma, rp); - eraRz(chia, rp); - -/* Bias-precession matrix: GCRS to mean of date. */ - eraRxr(rp, rbw, rbp); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/bp06.c b/ast/erfa/bp06.c deleted file mode 100644 index b5a60c4..0000000 --- a/ast/erfa/bp06.c +++ /dev/null @@ -1,152 +0,0 @@ -#include "erfa.h" - -void eraBp06(double date1, double date2, - double rb[3][3], double rp[3][3], double rbp[3][3]) -/* -** - - - - - - - - -** e r a B p 0 6 -** - - - - - - - - -** -** Frame bias and precession, IAU 2006. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rb double[3][3] frame bias matrix (Note 2) -** rp double[3][3] precession matrix (Note 3) -** rbp double[3][3] bias-precession matrix (Note 4) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix rb transforms vectors from GCRS to mean J2000.0 by -** applying frame bias. -** -** 3) The matrix rp transforms vectors from mean J2000.0 to mean of -** date by applying precession. -** -** 4) The matrix rbp transforms vectors from GCRS to mean of date by -** applying frame bias then precession. It is the product rp x rb. -** -** 5) It is permissible to re-use the same array in the returned -** arguments. The arrays are filled in the order given. -** -** Called: -** eraPfw06 bias-precession F-W angles, IAU 2006 -** eraFw2m F-W angles to r-matrix -** eraPmat06 PB matrix, IAU 2006 -** eraTr transpose r-matrix -** eraRxr product of two r-matrices -** eraCr copy r-matrix -** -** References: -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855 -** -** Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double gamb, phib, psib, epsa, rbpw[3][3], rbt[3][3]; - - -/* B matrix. */ - eraPfw06(ERFA_DJM0, ERFA_DJM00, &gamb, &phib, &psib, &epsa); - eraFw2m(gamb, phib, psib, epsa, rb); - -/* PxB matrix (temporary). */ - eraPmat06(date1, date2, rbpw); - -/* P matrix. */ - eraTr(rb, rbt); - eraRxr(rbpw, rbt, rp); - -/* PxB matrix. */ - eraCr(rbpw, rbp); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/bpn2xy.c b/ast/erfa/bpn2xy.c deleted file mode 100644 index 769bd33..0000000 --- a/ast/erfa/bpn2xy.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "erfa.h" - -void eraBpn2xy(double rbpn[3][3], double *x, double *y) -/* -** - - - - - - - - - - -** e r a B p n 2 x y -** - - - - - - - - - - -** -** Extract from the bias-precession-nutation matrix the X,Y coordinates -** of the Celestial Intermediate Pole. -** -** Given: -** rbpn double[3][3] celestial-to-true matrix (Note 1) -** -** Returned: -** x,y double Celestial Intermediate Pole (Note 2) -** -** Notes: -** -** 1) The matrix rbpn transforms vectors from GCRS to true equator (and -** CIO or equinox) of date, and therefore the Celestial Intermediate -** Pole unit vector is the bottom row of the matrix. -** -** 2) The arguments x,y are components of the Celestial Intermediate -** Pole unit vector in the Geocentric Celestial Reference System. -** -** Reference: -** -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 -** (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Extract the X,Y coordinates. */ - *x = rbpn[2][0]; - *y = rbpn[2][1]; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2i00a.c b/ast/erfa/c2i00a.c deleted file mode 100644 index a83b12b..0000000 --- a/ast/erfa/c2i00a.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "erfa.h" - -void eraC2i00a(double date1, double date2, double rc2i[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 i 0 0 a -** - - - - - - - - - - -** -** Form the celestial-to-intermediate matrix for a given date using the -** IAU 2000A precession-nutation model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rc2i double[3][3] celestial-to-intermediate matrix (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix rc2i is the first stage in the transformation from -** celestial to terrestrial coordinates: -** -** [TRS] = RPOM * R_3(ERA) * rc2i * [CRS] -** -** = rc2t * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), ERA is the Earth -** Rotation Angle and RPOM is the polar motion matrix. -** -** 3) A faster, but slightly less accurate result (about 1 mas), can be -** obtained by using instead the eraC2i00b function. -** -** Called: -** eraPnm00a classical NPB matrix, IAU 2000A -** eraC2ibpn celestial-to-intermediate matrix, given NPB matrix -** -** References: -** -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 -** (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rbpn[3][3]; - - -/* Obtain the celestial-to-true matrix (IAU 2000A). */ - eraPnm00a(date1, date2, rbpn); - -/* Form the celestial-to-intermediate matrix. */ - eraC2ibpn(date1, date2, rbpn, rc2i); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2i00b.c b/ast/erfa/c2i00b.c deleted file mode 100644 index 7969a34..0000000 --- a/ast/erfa/c2i00b.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "erfa.h" - -void eraC2i00b(double date1, double date2, double rc2i[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 i 0 0 b -** - - - - - - - - - - -** -** Form the celestial-to-intermediate matrix for a given date using the -** IAU 2000B precession-nutation model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rc2i double[3][3] celestial-to-intermediate matrix (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix rc2i is the first stage in the transformation from -** celestial to terrestrial coordinates: -** -** [TRS] = RPOM * R_3(ERA) * rc2i * [CRS] -** -** = rc2t * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), ERA is the Earth -** Rotation Angle and RPOM is the polar motion matrix. -** -** 3) The present function is faster, but slightly less accurate (about -** 1 mas), than the eraC2i00a function. -** -** Called: -** eraPnm00b classical NPB matrix, IAU 2000B -** eraC2ibpn celestial-to-intermediate matrix, given NPB matrix -** -** References: -** -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 -** (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rbpn[3][3]; - - -/* Obtain the celestial-to-true matrix (IAU 2000B). */ - eraPnm00b(date1, date2, rbpn); - -/* Form the celestial-to-intermediate matrix. */ - eraC2ibpn(date1, date2, rbpn, rc2i); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2i06a.c b/ast/erfa/c2i06a.c deleted file mode 100644 index 9fd6bfe..0000000 --- a/ast/erfa/c2i06a.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "erfa.h" - -void eraC2i06a(double date1, double date2, double rc2i[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 i 0 6 a -** - - - - - - - - - - -** -** Form the celestial-to-intermediate matrix for a given date using the -** IAU 2006 precession and IAU 2000A nutation models. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rc2i double[3][3] celestial-to-intermediate matrix (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix rc2i is the first stage in the transformation from -** celestial to terrestrial coordinates: -** -** [TRS] = RPOM * R_3(ERA) * rc2i * [CRS] -** -** = RC2T * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), ERA is the Earth -** Rotation Angle and RPOM is the polar motion matrix. -** -** Called: -** eraPnm06a classical NPB matrix, IAU 2006/2000A -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraS06 the CIO locator s, given X,Y, IAU 2006 -** eraC2ixys celestial-to-intermediate matrix, given X,Y and s -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003), -** IERS Technical Note No. 32, BKG -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rbpn[3][3], x, y, s; - - -/* Obtain the celestial-to-true matrix (IAU 2006/2000A). */ - eraPnm06a(date1, date2, rbpn); - -/* Extract the X,Y coordinates. */ - eraBpn2xy(rbpn, &x, &y); - -/* Obtain the CIO locator. */ - s = eraS06(date1, date2, x, y); - -/* Form the celestial-to-intermediate matrix. */ - eraC2ixys(x, y, s, rc2i); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2ibpn.c b/ast/erfa/c2ibpn.c deleted file mode 100644 index 62f34a2..0000000 --- a/ast/erfa/c2ibpn.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "erfa.h" - -void eraC2ibpn(double date1, double date2, double rbpn[3][3], - double rc2i[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 i b p n -** - - - - - - - - - - -** -** Form the celestial-to-intermediate matrix for a given date given -** the bias-precession-nutation matrix. IAU 2000. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** rbpn double[3][3] celestial-to-true matrix (Note 2) -** -** Returned: -** rc2i double[3][3] celestial-to-intermediate matrix (Note 3) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix rbpn transforms vectors from GCRS to true equator (and -** CIO or equinox) of date. Only the CIP (bottom row) is used. -** -** 3) The matrix rc2i is the first stage in the transformation from -** celestial to terrestrial coordinates: -** -** [TRS] = RPOM * R_3(ERA) * rc2i * [CRS] -** -** = RC2T * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), ERA is the Earth -** Rotation Angle and RPOM is the polar motion matrix. -** -** 4) Although its name does not include "00", This function is in fact -** specific to the IAU 2000 models. -** -** Called: -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraC2ixy celestial-to-intermediate matrix, given X,Y -** -** References: -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double x, y; - - -/* Extract the X,Y coordinates. */ - eraBpn2xy(rbpn, &x, &y); - -/* Form the celestial-to-intermediate matrix (n.b. IAU 2000 specific). */ - eraC2ixy(date1, date2, x, y, rc2i); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2ixy.c b/ast/erfa/c2ixy.c deleted file mode 100644 index a488f20..0000000 --- a/ast/erfa/c2ixy.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "erfa.h" - -void eraC2ixy(double date1, double date2, double x, double y, - double rc2i[3][3]) -/* -** - - - - - - - - - -** e r a C 2 i x y -** - - - - - - - - - -** -** Form the celestial to intermediate-frame-of-date matrix for a given -** date when the CIP X,Y coordinates are known. IAU 2000. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** x,y double Celestial Intermediate Pole (Note 2) -** -** Returned: -** rc2i double[3][3] celestial-to-intermediate matrix (Note 3) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The Celestial Intermediate Pole coordinates are the x,y components -** of the unit vector in the Geocentric Celestial Reference System. -** -** 3) The matrix rc2i is the first stage in the transformation from -** celestial to terrestrial coordinates: -** -** [TRS] = RPOM * R_3(ERA) * rc2i * [CRS] -** -** = RC2T * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), ERA is the Earth -** Rotation Angle and RPOM is the polar motion matrix. -** -** 4) Although its name does not include "00", This function is in fact -** specific to the IAU 2000 models. -** -** Called: -** eraC2ixys celestial-to-intermediate matrix, given X,Y and s -** eraS00 the CIO locator s, given X,Y, IAU 2000A -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ - -{ -/* Compute s and then the matrix. */ - eraC2ixys(x, y, eraS00(date1, date2, x, y), rc2i); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2ixys.c b/ast/erfa/c2ixys.c deleted file mode 100644 index 1c92687..0000000 --- a/ast/erfa/c2ixys.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "erfa.h" - -void eraC2ixys(double x, double y, double s, double rc2i[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 i x y s -** - - - - - - - - - - -** -** Form the celestial to intermediate-frame-of-date matrix given the CIP -** X,Y and the CIO locator s. -** -** Given: -** x,y double Celestial Intermediate Pole (Note 1) -** s double the CIO locator s (Note 2) -** -** Returned: -** rc2i double[3][3] celestial-to-intermediate matrix (Note 3) -** -** Notes: -** -** 1) The Celestial Intermediate Pole coordinates are the x,y -** components of the unit vector in the Geocentric Celestial -** Reference System. -** -** 2) The CIO locator s (in radians) positions the Celestial -** Intermediate Origin on the equator of the CIP. -** -** 3) The matrix rc2i is the first stage in the transformation from -** celestial to terrestrial coordinates: -** -** [TRS] = RPOM * R_3(ERA) * rc2i * [CRS] -** -** = RC2T * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), ERA is the Earth -** Rotation Angle and RPOM is the polar motion matrix. -** -** Called: -** eraIr initialize r-matrix to identity -** eraRz rotate around Z-axis -** eraRy rotate around Y-axis -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double r2, e, d; - - -/* Obtain the spherical angles E and d. */ - r2 = x*x + y*y; - e = (r2 > 0.0) ? atan2(y, x) : 0.0; - d = atan(sqrt(r2 / (1.0 - r2))); - -/* Form the matrix. */ - eraIr(rc2i); - eraRz(e, rc2i); - eraRy(d, rc2i); - eraRz(-(e+s), rc2i); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2s.c b/ast/erfa/c2s.c deleted file mode 100644 index 6f31a2b..0000000 --- a/ast/erfa/c2s.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "erfa.h" - -void eraC2s(double p[3], double *theta, double *phi) -/* -** - - - - - - - -** e r a C 2 s -** - - - - - - - -** -** P-vector to spherical coordinates. -** -** Given: -** p double[3] p-vector -** -** Returned: -** theta double longitude angle (radians) -** phi double latitude angle (radians) -** -** Notes: -** -** 1) The vector p can have any magnitude; only its direction is used. -** -** 2) If p is null, zero theta and phi are returned. -** -** 3) At either pole, zero theta is returned. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double x, y, z, d2; - - - x = p[0]; - y = p[1]; - z = p[2]; - d2 = x*x + y*y; - - *theta = (d2 == 0.0) ? 0.0 : atan2(y, x); - *phi = (z == 0.0) ? 0.0 : atan2(z, sqrt(d2)); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2t00a.c b/ast/erfa/c2t00a.c deleted file mode 100644 index 94439fa..0000000 --- a/ast/erfa/c2t00a.c +++ /dev/null @@ -1,163 +0,0 @@ -#include "erfa.h" - -void eraC2t00a(double tta, double ttb, double uta, double utb, - double xp, double yp, double rc2t[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 t 0 0 a -** - - - - - - - - - - -** -** Form the celestial to terrestrial matrix given the date, the UT1 and -** the polar motion, using the IAU 2000A nutation model. -** -** Given: -** tta,ttb double TT as a 2-part Julian Date (Note 1) -** uta,utb double UT1 as a 2-part Julian Date (Note 1) -** xp,yp double coordinates of the pole (radians, Note 2) -** -** Returned: -** rc2t double[3][3] celestial-to-terrestrial matrix (Note 3) -** -** Notes: -** -** 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates, -** apportioned in any convenient way between the arguments uta and -** utb. For example, JD(UT1)=2450123.7 could be expressed in any of -** these ways, among others: -** -** uta utb -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution is -** acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. In the case of uta,utb, the -** date & time method is best matched to the Earth rotation angle -** algorithm used: maximum precision is delivered when the uta -** argument is for 0hrs UT1 on the day in question and the utb -** argument lies in the range 0 to 1, or vice versa. -** -** 2) The arguments xp and yp are the coordinates (in radians) of the -** Celestial Intermediate Pole with respect to the International -** Terrestrial Reference System (see IERS Conventions 2003), -** measured along the meridians to 0 and 90 deg west respectively. -** -** 3) The matrix rc2t transforms from celestial to terrestrial -** coordinates: -** -** [TRS] = RPOM * R_3(ERA) * RC2I * [CRS] -** -** = rc2t * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), RC2I is the -** celestial-to-intermediate matrix, ERA is the Earth rotation -** angle and RPOM is the polar motion matrix. -** -** 4) A faster, but slightly less accurate result (about 1 mas), can -** be obtained by using instead the eraC2t00b function. -** -** Called: -** eraC2i00a celestial-to-intermediate matrix, IAU 2000A -** eraEra00 Earth rotation angle, IAU 2000 -** eraSp00 the TIO locator s', IERS 2000 -** eraPom00 polar motion matrix -** eraC2tcio form CIO-based celestial-to-terrestrial matrix -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rc2i[3][3], era, sp, rpom[3][3]; - - -/* Form the celestial-to-intermediate matrix for this TT (IAU 2000A). */ - eraC2i00a(tta, ttb, rc2i ); - -/* Predict the Earth rotation angle for this UT1. */ - era = eraEra00(uta, utb); - -/* Estimate s'. */ - sp = eraSp00(tta, ttb); - -/* Form the polar motion matrix. */ - eraPom00(xp, yp, sp, rpom); - -/* Combine to form the celestial-to-terrestrial matrix. */ - eraC2tcio(rc2i, era, rpom, rc2t); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2t00b.c b/ast/erfa/c2t00b.c deleted file mode 100644 index fe19504..0000000 --- a/ast/erfa/c2t00b.c +++ /dev/null @@ -1,159 +0,0 @@ -#include "erfa.h" - -void eraC2t00b(double tta, double ttb, double uta, double utb, - double xp, double yp, double rc2t[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 t 0 0 b -** - - - - - - - - - - -** -** Form the celestial to terrestrial matrix given the date, the UT1 and -** the polar motion, using the IAU 2000B nutation model. -** -** Given: -** tta,ttb double TT as a 2-part Julian Date (Note 1) -** uta,utb double UT1 as a 2-part Julian Date (Note 1) -** xp,yp double coordinates of the pole (radians, Note 2) -** -** Returned: -** rc2t double[3][3] celestial-to-terrestrial matrix (Note 3) -** -** Notes: -** -** 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates, -** apportioned in any convenient way between the arguments uta and -** utb. For example, JD(UT1)=2450123.7 could be expressed in any of -** these ways, among others: -** -** uta utb -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution is -** acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. In the case of uta,utb, the -** date & time method is best matched to the Earth rotation angle -** algorithm used: maximum precision is delivered when the uta -** argument is for 0hrs UT1 on the day in question and the utb -** argument lies in the range 0 to 1, or vice versa. -** -** 2) The arguments xp and yp are the coordinates (in radians) of the -** Celestial Intermediate Pole with respect to the International -** Terrestrial Reference System (see IERS Conventions 2003), -** measured along the meridians to 0 and 90 deg west respectively. -** -** 3) The matrix rc2t transforms from celestial to terrestrial -** coordinates: -** -** [TRS] = RPOM * R_3(ERA) * RC2I * [CRS] -** -** = rc2t * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), RC2I is the -** celestial-to-intermediate matrix, ERA is the Earth rotation -** angle and RPOM is the polar motion matrix. -** -** 4) The present function is faster, but slightly less accurate (about -** 1 mas), than the eraC2t00a function. -** -** Called: -** eraC2i00b celestial-to-intermediate matrix, IAU 2000B -** eraEra00 Earth rotation angle, IAU 2000 -** eraPom00 polar motion matrix -** eraC2tcio form CIO-based celestial-to-terrestrial matrix -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rc2i[3][3], era, rpom[3][3]; - - -/* Form the celestial-to-intermediate matrix for this TT (IAU 2000B). */ - eraC2i00b(tta, ttb, rc2i); - -/* Predict the Earth rotation angle for this UT1. */ - era = eraEra00(uta, utb); - -/* Form the polar motion matrix (neglecting s'). */ - eraPom00(xp, yp, 0.0, rpom); - -/* Combine to form the celestial-to-terrestrial matrix. */ - eraC2tcio(rc2i, era, rpom, rc2t); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2t06a.c b/ast/erfa/c2t06a.c deleted file mode 100644 index 3b8b2ff..0000000 --- a/ast/erfa/c2t06a.c +++ /dev/null @@ -1,161 +0,0 @@ -#include "erfa.h" - -void eraC2t06a(double tta, double ttb, double uta, double utb, - double xp, double yp, double rc2t[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 t 0 6 a -** - - - - - - - - - - -** -** Form the celestial to terrestrial matrix given the date, the UT1 and -** the polar motion, using the IAU 2006 precession and IAU 2000A -** nutation models. -** -** Given: -** tta,ttb double TT as a 2-part Julian Date (Note 1) -** uta,utb double UT1 as a 2-part Julian Date (Note 1) -** xp,yp double coordinates of the pole (radians, Note 2) -** -** Returned: -** rc2t double[3][3] celestial-to-terrestrial matrix (Note 3) -** -** Notes: -** -** 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates, -** apportioned in any convenient way between the arguments uta and -** utb. For example, JD(UT1)=2450123.7 could be expressed in any of -** these ways, among others: -** -** uta utb -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution is -** acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. In the case of uta,utb, the -** date & time method is best matched to the Earth rotation angle -** algorithm used: maximum precision is delivered when the uta -** argument is for 0hrs UT1 on the day in question and the utb -** argument lies in the range 0 to 1, or vice versa. -** -** 2) The arguments xp and yp are the coordinates (in radians) of the -** Celestial Intermediate Pole with respect to the International -** Terrestrial Reference System (see IERS Conventions 2003), -** measured along the meridians to 0 and 90 deg west respectively. -** -** 3) The matrix rc2t transforms from celestial to terrestrial -** coordinates: -** -** [TRS] = RPOM * R_3(ERA) * RC2I * [CRS] -** -** = rc2t * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), RC2I is the -** celestial-to-intermediate matrix, ERA is the Earth rotation -** angle and RPOM is the polar motion matrix. -** -** Called: -** eraC2i06a celestial-to-intermediate matrix, IAU 2006/2000A -** eraEra00 Earth rotation angle, IAU 2000 -** eraSp00 the TIO locator s', IERS 2000 -** eraPom00 polar motion matrix -** eraC2tcio form CIO-based celestial-to-terrestrial matrix -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003), -** IERS Technical Note No. 32, BKG -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rc2i[3][3], era, sp, rpom[3][3]; - - -/* Form the celestial-to-intermediate matrix for this TT. */ - eraC2i06a(tta, ttb, rc2i); - -/* Predict the Earth rotation angle for this UT1. */ - era = eraEra00(uta, utb); - -/* Estimate s'. */ - sp = eraSp00(tta, ttb); - -/* Form the polar motion matrix. */ - eraPom00(xp, yp, sp, rpom); - -/* Combine to form the celestial-to-terrestrial matrix. */ - eraC2tcio(rc2i, era, rpom, rc2t); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2tcio.c b/ast/erfa/c2tcio.c deleted file mode 100644 index 2bdd004..0000000 --- a/ast/erfa/c2tcio.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "erfa.h" - -void eraC2tcio(double rc2i[3][3], double era, double rpom[3][3], - double rc2t[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 t c i o -** - - - - - - - - - - -** -** Assemble the celestial to terrestrial matrix from CIO-based -** components (the celestial-to-intermediate matrix, the Earth Rotation -** Angle and the polar motion matrix). -** -** Given: -** rc2i double[3][3] celestial-to-intermediate matrix -** era double Earth rotation angle (radians) -** rpom double[3][3] polar-motion matrix -** -** Returned: -** rc2t double[3][3] celestial-to-terrestrial matrix -** -** Notes: -** -** 1) This function constructs the rotation matrix that transforms -** vectors in the celestial system into vectors in the terrestrial -** system. It does so starting from precomputed components, namely -** the matrix which rotates from celestial coordinates to the -** intermediate frame, the Earth rotation angle and the polar motion -** matrix. One use of the present function is when generating a -** series of celestial-to-terrestrial matrices where only the Earth -** Rotation Angle changes, avoiding the considerable overhead of -** recomputing the precession-nutation more often than necessary to -** achieve given accuracy objectives. -** -** 2) The relationship between the arguments is as follows: -** -** [TRS] = RPOM * R_3(ERA) * rc2i * [CRS] -** -** = rc2t * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003). -** -** Called: -** eraCr copy r-matrix -** eraRz rotate around Z-axis -** eraRxr product of two r-matrices -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003), -** IERS Technical Note No. 32, BKG -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double r[3][3]; - - -/* Construct the matrix. */ - eraCr(rc2i, r); - eraRz(era, r); - eraRxr(rpom, r, rc2t); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2teqx.c b/ast/erfa/c2teqx.c deleted file mode 100644 index c86e76c..0000000 --- a/ast/erfa/c2teqx.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "erfa.h" - -void eraC2teqx(double rbpn[3][3], double gst, double rpom[3][3], - double rc2t[3][3]) -/* -** - - - - - - - - - - -** e r a C 2 t e q x -** - - - - - - - - - - -** -** Assemble the celestial to terrestrial matrix from equinox-based -** components (the celestial-to-true matrix, the Greenwich Apparent -** Sidereal Time and the polar motion matrix). -** -** Given: -** rbpn double[3][3] celestial-to-true matrix -** gst double Greenwich (apparent) Sidereal Time (radians) -** rpom double[3][3] polar-motion matrix -** -** Returned: -** rc2t double[3][3] celestial-to-terrestrial matrix (Note 2) -** -** Notes: -** -** 1) This function constructs the rotation matrix that transforms -** vectors in the celestial system into vectors in the terrestrial -** system. It does so starting from precomputed components, namely -** the matrix which rotates from celestial coordinates to the -** true equator and equinox of date, the Greenwich Apparent Sidereal -** Time and the polar motion matrix. One use of the present function -** is when generating a series of celestial-to-terrestrial matrices -** where only the Sidereal Time changes, avoiding the considerable -** overhead of recomputing the precession-nutation more often than -** necessary to achieve given accuracy objectives. -** -** 2) The relationship between the arguments is as follows: -** -** [TRS] = rpom * R_3(gst) * rbpn * [CRS] -** -** = rc2t * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003). -** -** Called: -** eraCr copy r-matrix -** eraRz rotate around Z-axis -** eraRxr product of two r-matrices -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double r[3][3]; - - -/* Construct the matrix. */ - eraCr(rbpn, r); - eraRz(gst, r); - eraRxr(rpom, r, rc2t); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2tpe.c b/ast/erfa/c2tpe.c deleted file mode 100644 index c6e4bda..0000000 --- a/ast/erfa/c2tpe.c +++ /dev/null @@ -1,176 +0,0 @@ -#include "erfa.h" - -void eraC2tpe(double tta, double ttb, double uta, double utb, - double dpsi, double deps, double xp, double yp, - double rc2t[3][3]) -/* -** - - - - - - - - - -** e r a C 2 t p e -** - - - - - - - - - -** -** Form the celestial to terrestrial matrix given the date, the UT1, -** the nutation and the polar motion. IAU 2000. -** -** Given: -** tta,ttb double TT as a 2-part Julian Date (Note 1) -** uta,utb double UT1 as a 2-part Julian Date (Note 1) -** dpsi,deps double nutation (Note 2) -** xp,yp double coordinates of the pole (radians, Note 3) -** -** Returned: -** rc2t double[3][3] celestial-to-terrestrial matrix (Note 4) -** -** Notes: -** -** 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates, -** apportioned in any convenient way between the arguments uta and -** utb. For example, JD(UT1)=2450123.7 could be expressed in any of -** these ways, among others: -** -** uta utb -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution is -** acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. In the case of uta,utb, the -** date & time method is best matched to the Earth rotation angle -** algorithm used: maximum precision is delivered when the uta -** argument is for 0hrs UT1 on the day in question and the utb -** argument lies in the range 0 to 1, or vice versa. -** -** 2) The caller is responsible for providing the nutation components; -** they are in longitude and obliquity, in radians and are with -** respect to the equinox and ecliptic of date. For high-accuracy -** applications, free core nutation should be included as well as -** any other relevant corrections to the position of the CIP. -** -** 3) The arguments xp and yp are the coordinates (in radians) of the -** Celestial Intermediate Pole with respect to the International -** Terrestrial Reference System (see IERS Conventions 2003), -** measured along the meridians to 0 and 90 deg west respectively. -** -** 4) The matrix rc2t transforms from celestial to terrestrial -** coordinates: -** -** [TRS] = RPOM * R_3(GST) * RBPN * [CRS] -** -** = rc2t * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), RBPN is the -** bias-precession-nutation matrix, GST is the Greenwich (apparent) -** Sidereal Time and RPOM is the polar motion matrix. -** -** 5) Although its name does not include "00", This function is in fact -** specific to the IAU 2000 models. -** -** Called: -** eraPn00 bias/precession/nutation results, IAU 2000 -** eraGmst00 Greenwich mean sidereal time, IAU 2000 -** eraSp00 the TIO locator s', IERS 2000 -** eraEe00 equation of the equinoxes, IAU 2000 -** eraPom00 polar motion matrix -** eraC2teqx form equinox-based celestial-to-terrestrial matrix -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double epsa, rb[3][3], rp[3][3], rbp[3][3], rn[3][3], - rbpn[3][3], gmst, ee, sp, rpom[3][3]; - - -/* Form the celestial-to-true matrix for this TT. */ - eraPn00(tta, ttb, dpsi, deps, &epsa, rb, rp, rbp, rn, rbpn); - -/* Predict the Greenwich Mean Sidereal Time for this UT1 and TT. */ - gmst = eraGmst00(uta, utb, tta, ttb); - -/* Predict the equation of the equinoxes given TT and nutation. */ - ee = eraEe00(tta, ttb, epsa, dpsi); - -/* Estimate s'. */ - sp = eraSp00(tta, ttb); - -/* Form the polar motion matrix. */ - eraPom00(xp, yp, sp, rpom); - -/* Combine to form the celestial-to-terrestrial matrix. */ - eraC2teqx(rbpn, gmst + ee, rpom, rc2t); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/c2txy.c b/ast/erfa/c2txy.c deleted file mode 100644 index 198c7a8..0000000 --- a/ast/erfa/c2txy.c +++ /dev/null @@ -1,168 +0,0 @@ -#include "erfa.h" - -void eraC2txy(double tta, double ttb, double uta, double utb, - double x, double y, double xp, double yp, - double rc2t[3][3]) -/* -** - - - - - - - - - -** e r a C 2 t x y -** - - - - - - - - - -** -** Form the celestial to terrestrial matrix given the date, the UT1, -** the CIP coordinates and the polar motion. IAU 2000. -** -** Given: -** tta,ttb double TT as a 2-part Julian Date (Note 1) -** uta,utb double UT1 as a 2-part Julian Date (Note 1) -** x,y double Celestial Intermediate Pole (Note 2) -** xp,yp double coordinates of the pole (radians, Note 3) -** -** Returned: -** rc2t double[3][3] celestial-to-terrestrial matrix (Note 4) -** -** Notes: -** -** 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates, -** apportioned in any convenient way between the arguments uta and -** utb. For example, JD(UT1)=2450123.7 could be expressed in any o -** these ways, among others: -** -** uta utb -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution is -** acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. In the case of uta,utb, the -** date & time method is best matched to the Earth rotation angle -** algorithm used: maximum precision is delivered when the uta -** argument is for 0hrs UT1 on the day in question and the utb -** argument lies in the range 0 to 1, or vice versa. -** -** 2) The Celestial Intermediate Pole coordinates are the x,y -** components of the unit vector in the Geocentric Celestial -** Reference System. -** -** 3) The arguments xp and yp are the coordinates (in radians) of the -** Celestial Intermediate Pole with respect to the International -** Terrestrial Reference System (see IERS Conventions 2003), -** measured along the meridians to 0 and 90 deg west respectively. -** -** 4) The matrix rc2t transforms from celestial to terrestrial -** coordinates: -** -** [TRS] = RPOM * R_3(ERA) * RC2I * [CRS] -** -** = rc2t * [CRS] -** -** where [CRS] is a vector in the Geocentric Celestial Reference -** System and [TRS] is a vector in the International Terrestrial -** Reference System (see IERS Conventions 2003), ERA is the Earth -** Rotation Angle and RPOM is the polar motion matrix. -** -** 5) Although its name does not include "00", This function is in fact -** specific to the IAU 2000 models. -** -** Called: -** eraC2ixy celestial-to-intermediate matrix, given X,Y -** eraEra00 Earth rotation angle, IAU 2000 -** eraSp00 the TIO locator s', IERS 2000 -** eraPom00 polar motion matrix -** eraC2tcio form CIO-based celestial-to-terrestrial matrix -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rc2i[3][3], era, sp, rpom[3][3]; - - -/* Form the celestial-to-intermediate matrix for this TT. */ - eraC2ixy(tta, ttb, x, y, rc2i); - -/* Predict the Earth rotation angle for this UT1. */ - era = eraEra00(uta, utb); - -/* Estimate s'. */ - sp = eraSp00(tta, ttb); - -/* Form the polar motion matrix. */ - eraPom00(xp, yp, sp, rpom); - -/* Combine to form the celestial-to-terrestrial matrix. */ - eraC2tcio(rc2i, era, rpom, rc2t); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/cal2jd.c b/ast/erfa/cal2jd.c deleted file mode 100644 index 5d4d689..0000000 --- a/ast/erfa/cal2jd.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "erfa.h" - -int eraCal2jd(int iy, int im, int id, double *djm0, double *djm) -/* -** - - - - - - - - - - -** e r a C a l 2 j d -** - - - - - - - - - - -** -** Gregorian Calendar to Julian Date. -** -** Given: -** iy,im,id int year, month, day in Gregorian calendar (Note 1) -** -** Returned: -** djm0 double MJD zero-point: always 2400000.5 -** djm double Modified Julian Date for 0 hrs -** -** Returned (function value): -** int status: -** 0 = OK -** -1 = bad year (Note 3: JD not computed) -** -2 = bad month (JD not computed) -** -3 = bad day (JD computed) -** -** Notes: -** -** 1) The algorithm used is valid from -4800 March 1, but this -** implementation rejects dates before -4799 January 1. -** -** 2) The Julian Date is returned in two pieces, in the usual ERFA -** manner, which is designed to preserve time resolution. The -** Julian Date is available as a single number by adding djm0 and -** djm. -** -** 3) In early eras the conversion is from the "Proleptic Gregorian -** Calendar"; no account is taken of the date(s) of adoption of -** the Gregorian Calendar, nor is the AD/BC numbering convention -** observed. -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 12.92 (p604). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j, ly, my; - long iypmy; - -/* Earliest year allowed (4800BC) */ - const int IYMIN = -4799; - -/* Month lengths in days */ - static const int mtab[] - = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - - -/* Preset status. */ - j = 0; - -/* Validate year and month. */ - if (iy < IYMIN) return -1; - if (im < 1 || im > 12) return -2; - -/* If February in a leap year, 1, otherwise 0. */ - ly = ((im == 2) && !(iy%4) && (iy%100 || !(iy%400))); - -/* Validate day, taking into account leap years. */ - if ( (id < 1) || (id > (mtab[im-1] + ly))) j = -3; - -/* Return result. */ - my = (im - 14) / 12; - iypmy = (long) (iy + my); - *djm0 = ERFA_DJM0; - *djm = (double)((1461L * (iypmy + 4800L)) / 4L - + (367L * (long) (im - 2 - 12 * my)) / 12L - - (3L * ((iypmy + 4900L) / 100L)) / 4L - + (long) id - 2432076L); - -/* Return status. */ - return j; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/cp.c b/ast/erfa/cp.c deleted file mode 100644 index cf3ab90..0000000 --- a/ast/erfa/cp.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "erfa.h" - -void eraCp(double p[3], double c[3]) -/* -** - - - - - - -** e r a C p -** - - - - - - -** -** Copy a p-vector. -** -** Given: -** p double[3] p-vector to be copied -** -** Returned: -** c double[3] copy -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - c[0] = p[0]; - c[1] = p[1]; - c[2] = p[2]; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/cpv.c b/ast/erfa/cpv.c deleted file mode 100644 index 05204f5..0000000 --- a/ast/erfa/cpv.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "erfa.h" - -void eraCpv(double pv[2][3], double c[2][3]) -/* -** - - - - - - - -** e r a C p v -** - - - - - - - -** -** Copy a position/velocity vector. -** -** Given: -** pv double[2][3] position/velocity vector to be copied -** -** Returned: -** c double[2][3] copy -** -** Called: -** eraCp copy p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraCp(pv[0], c[0]); - eraCp(pv[1], c[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/cr.c b/ast/erfa/cr.c deleted file mode 100644 index 721781d..0000000 --- a/ast/erfa/cr.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "erfa.h" - -void eraCr(double r[3][3], double c[3][3]) -/* -** - - - - - - -** e r a C r -** - - - - - - -** -** Copy an r-matrix. -** -** Given: -** r double[3][3] r-matrix to be copied -** -** Returned: -** c double[3][3] copy -** -** Called: -** eraCp copy p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraCp(r[0], c[0]); - eraCp(r[1], c[1]); - eraCp(r[2], c[2]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/d2dtf.c b/ast/erfa/d2dtf.c deleted file mode 100644 index 4476970..0000000 --- a/ast/erfa/d2dtf.c +++ /dev/null @@ -1,245 +0,0 @@ -#include "erfa.h" -#include - -int eraD2dtf(const char *scale, int ndp, double d1, double d2, - int *iy, int *im, int *id, int ihmsf[4]) -/* -** - - - - - - - - - -** e r a D 2 d t f -** - - - - - - - - - -** -** Format for output a 2-part Julian Date (or in the case of UTC a -** quasi-JD form that includes special provision for leap seconds). -** -** Given: -** scale char[] time scale ID (Note 1) -** ndp int resolution (Note 2) -** d1,d2 double time as a 2-part Julian Date (Notes 3,4) -** -** Returned: -** iy,im,id int year, month, day in Gregorian calendar (Note 5) -** ihmsf int[4] hours, minutes, seconds, fraction (Note 1) -** -** Returned (function value): -** int status: +1 = dubious year (Note 5) -** 0 = OK -** -1 = unacceptable date (Note 6) -** -** Notes: -** -** 1) scale identifies the time scale. Only the value "UTC" (in upper -** case) is significant, and enables handling of leap seconds (see -** Note 4). -** -** 2) ndp is the number of decimal places in the seconds field, and can -** have negative as well as positive values, such as: -** -** ndp resolution -** -4 1 00 00 -** -3 0 10 00 -** -2 0 01 00 -** -1 0 00 10 -** 0 0 00 01 -** 1 0 00 00.1 -** 2 0 00 00.01 -** 3 0 00 00.001 -** -** The limits are platform dependent, but a safe range is -5 to +9. -** -** 3) d1+d2 is Julian Date, apportioned in any convenient way between -** the two arguments, for example where d1 is the Julian Day Number -** and d2 is the fraction of a day. In the case of UTC, where the -** use of JD is problematical, special conventions apply: see the -** next note. -** -** 4) JD cannot unambiguously represent UTC during a leap second unless -** special measures are taken. The ERFA internal convention is that -** the quasi-JD day represents UTC days whether the length is 86399, -** 86400 or 86401 SI seconds. In the 1960-1972 era there were -** smaller jumps (in either direction) each time the linear UTC(TAI) -** expression was changed, and these "mini-leaps" are also included -** in the ERFA convention. -** -** 5) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the future -** to be trusted. See eraDat for further details. -** -** 6) For calendar conventions and limitations, see eraCal2jd. -** -** Called: -** eraJd2cal JD to Gregorian calendar -** eraD2tf decompose days to hms -** eraDat delta(AT) = TAI-UTC -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int leap; - char s; - int iy1, im1, id1, js, iy2, im2, id2, ihmsf1[4], i; - double a1, b1, fd, dat0, dat12, w, dat24, dleap; - - -/* The two-part JD. */ - a1 = d1; - b1 = d2; - -/* Provisional calendar date. */ - js = eraJd2cal(a1, b1, &iy1, &im1, &id1, &fd); - if ( js ) return -1; - -/* Is this a leap second day? */ - leap = 0; - if ( ! strcmp(scale,"UTC") ) { - - /* TAI-UTC at 0h today. */ - js = eraDat(iy1, im1, id1, 0.0, &dat0); - if ( js < 0 ) return -1; - - /* TAI-UTC at 12h today (to detect drift). */ - js = eraDat(iy1, im1, id1, 0.5, &dat12); - if ( js < 0 ) return -1; - - /* TAI-UTC at 0h tomorrow (to detect jumps). */ - js = eraJd2cal(a1+1.5, b1-fd, &iy2, &im2, &id2, &w); - if ( js ) return -1; - js = eraDat(iy2, im2, id2, 0.0, &dat24); - if ( js < 0 ) return -1; - - /* Any sudden change in TAI-UTC (seconds). */ - dleap = dat24 - (2.0*dat12 - dat0); - - /* If leap second day, scale the fraction of a day into SI. */ - leap = (dleap != 0.0); - if (leap) fd += fd * dleap/ERFA_DAYSEC; - } - -/* Provisional time of day. */ - eraD2tf ( ndp, fd, &s, ihmsf1 ); - -/* Has the (rounded) time gone past 24h? */ - if ( ihmsf1[0] > 23 ) { - - /* Yes. We probably need tomorrow's calendar date. */ - js = eraJd2cal(a1+1.5, b1-fd, &iy2, &im2, &id2, &w); - if ( js ) return -1; - - /* Is today a leap second day? */ - if ( ! leap ) { - - /* No. Use 0h tomorrow. */ - iy1 = iy2; - im1 = im2; - id1 = id2; - ihmsf1[0] = 0; - ihmsf1[1] = 0; - ihmsf1[2] = 0; - - } else { - - /* Yes. Are we past the leap second itself? */ - if ( ihmsf1[2] > 0 ) { - - /* Yes. Use tomorrow but allow for the leap second. */ - iy1 = iy2; - im1 = im2; - id1 = id2; - ihmsf1[0] = 0; - ihmsf1[1] = 0; - ihmsf1[2] = 0; - - } else { - - /* No. Use 23 59 60... today. */ - ihmsf1[0] = 23; - ihmsf1[1] = 59; - ihmsf1[2] = 60; - } - - /* If rounding to 10s or coarser always go up to new day. */ - if ( ndp < 0 && ihmsf1[2] == 60 ) { - iy1 = iy2; - im1 = im2; - id1 = id2; - ihmsf1[0] = 0; - ihmsf1[1] = 0; - ihmsf1[2] = 0; - } - } - } - -/* Results. */ - *iy = iy1; - *im = im1; - *id = id1; - for ( i = 0; i < 4; i++ ) { - ihmsf[i] = ihmsf1[i]; - } - -/* Status. */ - return js; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/d2tf.c b/ast/erfa/d2tf.c deleted file mode 100644 index 3608f7f..0000000 --- a/ast/erfa/d2tf.c +++ /dev/null @@ -1,169 +0,0 @@ -#include "erfa.h" - -void eraD2tf(int ndp, double days, char *sign, int ihmsf[4]) -/* -** - - - - - - - - -** e r a D 2 t f -** - - - - - - - - -** -** Decompose days to hours, minutes, seconds, fraction. -** -** Given: -** ndp int resolution (Note 1) -** days double interval in days -** -** Returned: -** sign char '+' or '-' -** ihmsf int[4] hours, minutes, seconds, fraction -** -** Notes: -** -** 1) The argument ndp is interpreted as follows: -** -** ndp resolution -** : ...0000 00 00 -** -7 1000 00 00 -** -6 100 00 00 -** -5 10 00 00 -** -4 1 00 00 -** -3 0 10 00 -** -2 0 01 00 -** -1 0 00 10 -** 0 0 00 01 -** 1 0 00 00.1 -** 2 0 00 00.01 -** 3 0 00 00.001 -** : 0 00 00.000... -** -** 2) The largest positive useful value for ndp is determined by the -** size of days, the format of double on the target platform, and -** the risk of overflowing ihmsf[3]. On a typical platform, for -** days up to 1.0, the available floating-point precision might -** correspond to ndp=12. However, the practical limit is typically -** ndp=9, set by the capacity of a 32-bit int, or ndp=4 if int is -** only 16 bits. -** -** 3) The absolute value of days may exceed 1.0. In cases where it -** does not, it is up to the caller to test for and handle the -** case where days is very nearly 1.0 and rounds up to 24 hours, -** by testing for ihmsf[0]=24 and setting ihmsf[0-3] to zero. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int nrs, n; - double rs, rm, rh, a, w, ah, am, as, af; - - -/* Handle sign. */ - *sign = (char) ( ( days >= 0.0 ) ? '+' : '-' ); - -/* Interval in seconds. */ - a = ERFA_DAYSEC * fabs(days); - -/* Pre-round if resolution coarser than 1s (then pretend ndp=1). */ - if (ndp < 0) { - nrs = 1; - for (n = 1; n <= -ndp; n++) { - nrs *= (n == 2 || n == 4) ? 6 : 10; - } - rs = (double) nrs; - w = a / rs; - a = rs * ERFA_DNINT(w); - } - -/* Express the unit of each field in resolution units. */ - nrs = 1; - for (n = 1; n <= ndp; n++) { - nrs *= 10; - } - rs = (double) nrs; - rm = rs * 60.0; - rh = rm * 60.0; - -/* Round the interval and express in resolution units. */ - a = ERFA_DNINT(rs * a); - -/* Break into fields. */ - ah = a / rh; - ah = ERFA_DINT(ah); - a -= ah * rh; - am = a / rm; - am = ERFA_DINT(am); - a -= am * rm; - as = a / rs; - as = ERFA_DINT(as); - af = a - as * rs; - -/* Return results. */ - ihmsf[0] = (int) ah; - ihmsf[1] = (int) am; - ihmsf[2] = (int) as; - ihmsf[3] = (int) af; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/dat.c b/ast/erfa/dat.c deleted file mode 100644 index c3b1836..0000000 --- a/ast/erfa/dat.c +++ /dev/null @@ -1,306 +0,0 @@ -#include "erfa.h" - -int eraDat(int iy, int im, int id, double fd, double *deltat ) -/* -** - - - - - - - -** e r a D a t -** - - - - - - - -** -** For a given UTC date, calculate delta(AT) = TAI-UTC. -** -** :------------------------------------------: -** : : -** : IMPORTANT : -** : : -** : A new version of this function must be : -** : produced whenever a new leap second is : -** : announced. There are four items to : -** : change on each such occasion: : -** : : -** : 1) A new line must be added to the set : -** : of statements that initialize the : -** : array "changes". : -** : : -** : 2) The constant IYV must be set to the : -** : current year. : -** : : -** : 3) The "Latest leap second" comment : -** : below must be set to the new leap : -** : second date. : -** : : -** : 4) The "This revision" comment, later, : -** : must be set to the current date. : -** : : -** : Change (2) must also be carried out : -** : whenever the function is re-issued, : -** : even if no leap seconds have been : -** : added. : -** : : -** : Latest leap second: 2016 December 31 : -** : : -** :__________________________________________: -** -** Given: -** iy int UTC: year (Notes 1 and 2) -** im int month (Note 2) -** id int day (Notes 2 and 3) -** fd double fraction of day (Note 4) -** -** Returned: -** deltat double TAI minus UTC, seconds -** -** Returned (function value): -** int status (Note 5): -** 1 = dubious year (Note 1) -** 0 = OK -** -1 = bad year -** -2 = bad month -** -3 = bad day (Note 3) -** -4 = bad fraction (Note 4) -** -5 = internal error (Note 5) -** -** Notes: -** -** 1) UTC began at 1960 January 1.0 (JD 2436934.5) and it is improper -** to call the function with an earlier date. If this is attempted, -** zero is returned together with a warning status. -** -** Because leap seconds cannot, in principle, be predicted in -** advance, a reliable check for dates beyond the valid range is -** impossible. To guard against gross errors, a year five or more -** after the release year of the present function (see the constant -** IYV) is considered dubious. In this case a warning status is -** returned but the result is computed in the normal way. -** -** For both too-early and too-late years, the warning status is +1. -** This is distinct from the error status -1, which signifies a year -** so early that JD could not be computed. -** -** 2) If the specified date is for a day which ends with a leap second, -** the UTC-TAI value returned is for the period leading up to the -** leap second. If the date is for a day which begins as a leap -** second ends, the UTC-TAI returned is for the period following the -** leap second. -** -** 3) The day number must be in the normal calendar range, for example -** 1 through 30 for April. The "almanac" convention of allowing -** such dates as January 0 and December 32 is not supported in this -** function, in order to avoid confusion near leap seconds. -** -** 4) The fraction of day is used only for dates before the -** introduction of leap seconds, the first of which occurred at the -** end of 1971. It is tested for validity (0 to 1 is the valid -** range) even if not used; if invalid, zero is used and status -4 -** is returned. For many applications, setting fd to zero is -** acceptable; the resulting error is always less than 3 ms (and -** occurs only pre-1972). -** -** 5) The status value returned in the case where there are multiple -** errors refers to the first error detected. For example, if the -** month and day are 13 and 32 respectively, status -2 (bad month) -** will be returned. The "internal error" status refers to a -** case that is impossible but causes some compilers to issue a -** warning. -** -** 6) In cases where a valid result is not available, zero is returned. -** -** References: -** -** 1) For dates from 1961 January 1 onwards, the expressions from the -** file ftp://maia.usno.navy.mil/ser7/tai-utc.dat are used. -** -** 2) The 5ms timestep at 1961 January 1 is taken from 2.58.1 (p87) of -** the 1992 Explanatory Supplement. -** -** Called: -** eraCal2jd Gregorian calendar to JD -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Release year for this version of eraDat */ - enum { IYV = 2016}; - -/* Reference dates (MJD) and drift rates (s/day), pre leap seconds */ - static const double drift[][2] = { - { 37300.0, 0.0012960 }, - { 37300.0, 0.0012960 }, - { 37300.0, 0.0012960 }, - { 37665.0, 0.0011232 }, - { 37665.0, 0.0011232 }, - { 38761.0, 0.0012960 }, - { 38761.0, 0.0012960 }, - { 38761.0, 0.0012960 }, - { 38761.0, 0.0012960 }, - { 38761.0, 0.0012960 }, - { 38761.0, 0.0012960 }, - { 38761.0, 0.0012960 }, - { 39126.0, 0.0025920 }, - { 39126.0, 0.0025920 } - }; - -/* Number of Delta(AT) expressions before leap seconds were introduced */ - enum { NERA1 = (int) (sizeof drift / sizeof (double) / 2) }; - -/* Dates and Delta(AT)s */ - static const struct { - int iyear, month; - double delat; - } changes[] = { - { 1960, 1, 1.4178180 }, - { 1961, 1, 1.4228180 }, - { 1961, 8, 1.3728180 }, - { 1962, 1, 1.8458580 }, - { 1963, 11, 1.9458580 }, - { 1964, 1, 3.2401300 }, - { 1964, 4, 3.3401300 }, - { 1964, 9, 3.4401300 }, - { 1965, 1, 3.5401300 }, - { 1965, 3, 3.6401300 }, - { 1965, 7, 3.7401300 }, - { 1965, 9, 3.8401300 }, - { 1966, 1, 4.3131700 }, - { 1968, 2, 4.2131700 }, - { 1972, 1, 10.0 }, - { 1972, 7, 11.0 }, - { 1973, 1, 12.0 }, - { 1974, 1, 13.0 }, - { 1975, 1, 14.0 }, - { 1976, 1, 15.0 }, - { 1977, 1, 16.0 }, - { 1978, 1, 17.0 }, - { 1979, 1, 18.0 }, - { 1980, 1, 19.0 }, - { 1981, 7, 20.0 }, - { 1982, 7, 21.0 }, - { 1983, 7, 22.0 }, - { 1985, 7, 23.0 }, - { 1988, 1, 24.0 }, - { 1990, 1, 25.0 }, - { 1991, 1, 26.0 }, - { 1992, 7, 27.0 }, - { 1993, 7, 28.0 }, - { 1994, 7, 29.0 }, - { 1996, 1, 30.0 }, - { 1997, 7, 31.0 }, - { 1999, 1, 32.0 }, - { 2006, 1, 33.0 }, - { 2009, 1, 34.0 }, - { 2012, 7, 35.0 }, - { 2015, 7, 36.0 }, - { 2017, 1, 37.0 } - }; - -/* Number of Delta(AT) changes */ - enum { NDAT = (int) (sizeof changes / sizeof changes[0]) }; - -/* Miscellaneous local variables */ - int j, i, m; - double da, djm0, djm; - - -/* Initialize the result to zero. */ - *deltat = da = 0.0; - -/* If invalid fraction of a day, set error status and give up. */ - if (fd < 0.0 || fd > 1.0) return -4; - -/* Convert the date into an MJD. */ - j = eraCal2jd(iy, im, id, &djm0, &djm); - -/* If invalid year, month, or day, give up. */ - if (j < 0) return j; - -/* If pre-UTC year, set warning status and give up. */ - if (iy < changes[0].iyear) return 1; - -/* If suspiciously late year, set warning status but proceed. */ - if (iy > IYV + 5) j = 1; - -/* Combine year and month to form a date-ordered integer... */ - m = 12*iy + im; - -/* ...and use it to find the preceding table entry. */ - for (i = NDAT-1; i >=0; i--) { - if (m >= (12 * changes[i].iyear + changes[i].month)) break; - } - -/* Prevent underflow warnings. */ - if (i < 0) return -5; - -/* Get the Delta(AT). */ - da = changes[i].delat; - -/* If pre-1972, adjust for drift. */ - if (i < NERA1) da += (djm + fd - drift[i][0]) * drift[i][1]; - -/* Return the Delta(AT) value. */ - *deltat = da; - -/* Return the status. */ - return j; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/dtdb.c b/ast/erfa/dtdb.c deleted file mode 100644 index 1ac4f43..0000000 --- a/ast/erfa/dtdb.c +++ /dev/null @@ -1,1222 +0,0 @@ -#include "erfa.h" - -double eraDtdb(double date1, double date2, - double ut, double elong, double u, double v) -/* -** - - - - - - - - -** e r a D t d b -** - - - - - - - - -** -** An approximation to TDB-TT, the difference between barycentric -** dynamical time and terrestrial time, for an observer on the Earth. -** -** The different time scales - proper, coordinate and realized - are -** related to each other: -** -** TAI <- physically realized -** : -** offset <- observed (nominally +32.184s) -** : -** TT <- terrestrial time -** : -** rate adjustment (L_G) <- definition of TT -** : -** TCG <- time scale for GCRS -** : -** "periodic" terms <- eraDtdb is an implementation -** : -** rate adjustment (L_C) <- function of solar-system ephemeris -** : -** TCB <- time scale for BCRS -** : -** rate adjustment (-L_B) <- definition of TDB -** : -** TDB <- TCB scaled to track TT -** : -** "periodic" terms <- -eraDtdb is an approximation -** : -** TT <- terrestrial time -** -** Adopted values for the various constants can be found in the IERS -** Conventions (McCarthy & Petit 2003). -** -** Given: -** date1,date2 double date, TDB (Notes 1-3) -** ut double universal time (UT1, fraction of one day) -** elong double longitude (east positive, radians) -** u double distance from Earth spin axis (km) -** v double distance north of equatorial plane (km) -** -** Returned (function value): -** double TDB-TT (seconds) -** -** Notes: -** -** 1) The date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** Although the date is, formally, barycentric dynamical time (TDB), -** the terrestrial dynamical time (TT) can be used with no practical -** effect on the accuracy of the prediction. -** -** 2) TT can be regarded as a coordinate time that is realized as an -** offset of 32.184s from International Atomic Time, TAI. TT is a -** specific linear transformation of geocentric coordinate time TCG, -** which is the time scale for the Geocentric Celestial Reference -** System, GCRS. -** -** 3) TDB is a coordinate time, and is a specific linear transformation -** of barycentric coordinate time TCB, which is the time scale for -** the Barycentric Celestial Reference System, BCRS. -** -** 4) The difference TCG-TCB depends on the masses and positions of the -** bodies of the solar system and the velocity of the Earth. It is -** dominated by a rate difference, the residual being of a periodic -** character. The latter, which is modeled by the present function, -** comprises a main (annual) sinusoidal term of amplitude -** approximately 0.00166 seconds, plus planetary terms up to about -** 20 microseconds, and lunar and diurnal terms up to 2 microseconds. -** These effects come from the changing transverse Doppler effect -** and gravitational red-shift as the observer (on the Earth's -** surface) experiences variations in speed (with respect to the -** BCRS) and gravitational potential. -** -** 5) TDB can be regarded as the same as TCB but with a rate adjustment -** to keep it close to TT, which is convenient for many applications. -** The history of successive attempts to define TDB is set out in -** Resolution 3 adopted by the IAU General Assembly in 2006, which -** defines a fixed TDB(TCB) transformation that is consistent with -** contemporary solar-system ephemerides. Future ephemerides will -** imply slightly changed transformations between TCG and TCB, which -** could introduce a linear drift between TDB and TT; however, any -** such drift is unlikely to exceed 1 nanosecond per century. -** -** 6) The geocentric TDB-TT model used in the present function is that of -** Fairhead & Bretagnon (1990), in its full form. It was originally -** supplied by Fairhead (private communications with P.T.Wallace, -** 1990) as a Fortran subroutine. The present C function contains an -** adaptation of the Fairhead code. The numerical results are -** essentially unaffected by the changes, the differences with -** respect to the Fairhead & Bretagnon original being at the 1e-20 s -** level. -** -** The topocentric part of the model is from Moyer (1981) and -** Murray (1983), with fundamental arguments adapted from -** Simon et al. 1994. It is an approximation to the expression -** ( v / c ) . ( r / c ), where v is the barycentric velocity of -** the Earth, r is the geocentric position of the observer and -** c is the speed of light. -** -** By supplying zeroes for u and v, the topocentric part of the -** model can be nullified, and the function will return the Fairhead -** & Bretagnon result alone. -** -** 7) During the interval 1950-2050, the absolute accuracy is better -** than +/- 3 nanoseconds relative to time ephemerides obtained by -** direct numerical integrations based on the JPL DE405 solar system -** ephemeris. -** -** 8) It must be stressed that the present function is merely a model, -** and that numerical integration of solar-system ephemerides is the -** definitive method for predicting the relationship between TCG and -** TCB and hence between TT and TDB. -** -** References: -** -** Fairhead, L., & Bretagnon, P., Astron.Astrophys., 229, 240-247 -** (1990). -** -** IAU 2006 Resolution 3. -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Moyer, T.D., Cel.Mech., 23, 33 (1981). -** -** Murray, C.A., Vectorial Astrometry, Adam Hilger (1983). -** -** Seidelmann, P.K. et al., Explanatory Supplement to the -** Astronomical Almanac, Chapter 2, University Science Books (1992). -** -** Simon, J.L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G. & Laskar, J., Astron.Astrophys., 282, 663-683 (1994). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, tsol, w, elsun, emsun, d, elj, els, wt, w0, w1, w2, w3, w4, - wf, wj; - int j; - -/* -** ===================== -** Fairhead et al. model -** ===================== -** -** 787 sets of three coefficients. -** -** Each set is -** amplitude (microseconds) -** frequency (radians per Julian millennium since J2000.0) -** phase (radians) -** -** Sets 1-474 are the T**0 terms -** " 475-679 " " T**1 -** " 680-764 " " T**2 -** " 765-784 " " T**3 -** " 785-787 " " T**4 -*/ - - static const double fairhd[787][3] = { - /* 1, 10 */ - { 1656.674564e-6, 6283.075849991, 6.240054195 }, - { 22.417471e-6, 5753.384884897, 4.296977442 }, - { 13.839792e-6, 12566.151699983, 6.196904410 }, - { 4.770086e-6, 529.690965095, 0.444401603 }, - { 4.676740e-6, 6069.776754553, 4.021195093 }, - { 2.256707e-6, 213.299095438, 5.543113262 }, - { 1.694205e-6, -3.523118349, 5.025132748 }, - { 1.554905e-6, 77713.771467920, 5.198467090 }, - { 1.276839e-6, 7860.419392439, 5.988822341 }, - { 1.193379e-6, 5223.693919802, 3.649823730 }, - /* 11, 20 */ - { 1.115322e-6, 3930.209696220, 1.422745069 }, - { 0.794185e-6, 11506.769769794, 2.322313077 }, - { 0.447061e-6, 26.298319800, 3.615796498 }, - { 0.435206e-6, -398.149003408, 4.349338347 }, - { 0.600309e-6, 1577.343542448, 2.678271909 }, - { 0.496817e-6, 6208.294251424, 5.696701824 }, - { 0.486306e-6, 5884.926846583, 0.520007179 }, - { 0.432392e-6, 74.781598567, 2.435898309 }, - { 0.468597e-6, 6244.942814354, 5.866398759 }, - { 0.375510e-6, 5507.553238667, 4.103476804 }, - /* 21, 30 */ - { 0.243085e-6, -775.522611324, 3.651837925 }, - { 0.173435e-6, 18849.227549974, 6.153743485 }, - { 0.230685e-6, 5856.477659115, 4.773852582 }, - { 0.203747e-6, 12036.460734888, 4.333987818 }, - { 0.143935e-6, -796.298006816, 5.957517795 }, - { 0.159080e-6, 10977.078804699, 1.890075226 }, - { 0.119979e-6, 38.133035638, 4.551585768 }, - { 0.118971e-6, 5486.777843175, 1.914547226 }, - { 0.116120e-6, 1059.381930189, 0.873504123 }, - { 0.137927e-6, 11790.629088659, 1.135934669 }, - /* 31, 40 */ - { 0.098358e-6, 2544.314419883, 0.092793886 }, - { 0.101868e-6, -5573.142801634, 5.984503847 }, - { 0.080164e-6, 206.185548437, 2.095377709 }, - { 0.079645e-6, 4694.002954708, 2.949233637 }, - { 0.062617e-6, 20.775395492, 2.654394814 }, - { 0.075019e-6, 2942.463423292, 4.980931759 }, - { 0.064397e-6, 5746.271337896, 1.280308748 }, - { 0.063814e-6, 5760.498431898, 4.167901731 }, - { 0.048042e-6, 2146.165416475, 1.495846011 }, - { 0.048373e-6, 155.420399434, 2.251573730 }, - /* 41, 50 */ - { 0.058844e-6, 426.598190876, 4.839650148 }, - { 0.046551e-6, -0.980321068, 0.921573539 }, - { 0.054139e-6, 17260.154654690, 3.411091093 }, - { 0.042411e-6, 6275.962302991, 2.869567043 }, - { 0.040184e-6, -7.113547001, 3.565975565 }, - { 0.036564e-6, 5088.628839767, 3.324679049 }, - { 0.040759e-6, 12352.852604545, 3.981496998 }, - { 0.036507e-6, 801.820931124, 6.248866009 }, - { 0.036955e-6, 3154.687084896, 5.071801441 }, - { 0.042732e-6, 632.783739313, 5.720622217 }, - /* 51, 60 */ - { 0.042560e-6, 161000.685737473, 1.270837679 }, - { 0.040480e-6, 15720.838784878, 2.546610123 }, - { 0.028244e-6, -6286.598968340, 5.069663519 }, - { 0.033477e-6, 6062.663207553, 4.144987272 }, - { 0.034867e-6, 522.577418094, 5.210064075 }, - { 0.032438e-6, 6076.890301554, 0.749317412 }, - { 0.030215e-6, 7084.896781115, 3.389610345 }, - { 0.029247e-6, -71430.695617928, 4.183178762 }, - { 0.033529e-6, 9437.762934887, 2.404714239 }, - { 0.032423e-6, 8827.390269875, 5.541473556 }, - /* 61, 70 */ - { 0.027567e-6, 6279.552731642, 5.040846034 }, - { 0.029862e-6, 12139.553509107, 1.770181024 }, - { 0.022509e-6, 10447.387839604, 1.460726241 }, - { 0.020937e-6, 8429.241266467, 0.652303414 }, - { 0.020322e-6, 419.484643875, 3.735430632 }, - { 0.024816e-6, -1194.447010225, 1.087136918 }, - { 0.025196e-6, 1748.016413067, 2.901883301 }, - { 0.021691e-6, 14143.495242431, 5.952658009 }, - { 0.017673e-6, 6812.766815086, 3.186129845 }, - { 0.022567e-6, 6133.512652857, 3.307984806 }, - /* 71, 80 */ - { 0.016155e-6, 10213.285546211, 1.331103168 }, - { 0.014751e-6, 1349.867409659, 4.308933301 }, - { 0.015949e-6, -220.412642439, 4.005298270 }, - { 0.015974e-6, -2352.866153772, 6.145309371 }, - { 0.014223e-6, 17789.845619785, 2.104551349 }, - { 0.017806e-6, 73.297125859, 3.475975097 }, - { 0.013671e-6, -536.804512095, 5.971672571 }, - { 0.011942e-6, 8031.092263058, 2.053414715 }, - { 0.014318e-6, 16730.463689596, 3.016058075 }, - { 0.012462e-6, 103.092774219, 1.737438797 }, - /* 81, 90 */ - { 0.010962e-6, 3.590428652, 2.196567739 }, - { 0.015078e-6, 19651.048481098, 3.969480770 }, - { 0.010396e-6, 951.718406251, 5.717799605 }, - { 0.011707e-6, -4705.732307544, 2.654125618 }, - { 0.010453e-6, 5863.591206116, 1.913704550 }, - { 0.012420e-6, 4690.479836359, 4.734090399 }, - { 0.011847e-6, 5643.178563677, 5.489005403 }, - { 0.008610e-6, 3340.612426700, 3.661698944 }, - { 0.011622e-6, 5120.601145584, 4.863931876 }, - { 0.010825e-6, 553.569402842, 0.842715011 }, - /* 91, 100 */ - { 0.008666e-6, -135.065080035, 3.293406547 }, - { 0.009963e-6, 149.563197135, 4.870690598 }, - { 0.009858e-6, 6309.374169791, 1.061816410 }, - { 0.007959e-6, 316.391869657, 2.465042647 }, - { 0.010099e-6, 283.859318865, 1.942176992 }, - { 0.007147e-6, -242.728603974, 3.661486981 }, - { 0.007505e-6, 5230.807466803, 4.920937029 }, - { 0.008323e-6, 11769.853693166, 1.229392026 }, - { 0.007490e-6, -6256.777530192, 3.658444681 }, - { 0.009370e-6, 149854.400134205, 0.673880395 }, - /* 101, 110 */ - { 0.007117e-6, 38.027672636, 5.294249518 }, - { 0.007857e-6, 12168.002696575, 0.525733528 }, - { 0.007019e-6, 6206.809778716, 0.837688810 }, - { 0.006056e-6, 955.599741609, 4.194535082 }, - { 0.008107e-6, 13367.972631107, 3.793235253 }, - { 0.006731e-6, 5650.292110678, 5.639906583 }, - { 0.007332e-6, 36.648562930, 0.114858677 }, - { 0.006366e-6, 4164.311989613, 2.262081818 }, - { 0.006858e-6, 5216.580372801, 0.642063318 }, - { 0.006919e-6, 6681.224853400, 6.018501522 }, - /* 111, 120 */ - { 0.006826e-6, 7632.943259650, 3.458654112 }, - { 0.005308e-6, -1592.596013633, 2.500382359 }, - { 0.005096e-6, 11371.704689758, 2.547107806 }, - { 0.004841e-6, 5333.900241022, 0.437078094 }, - { 0.005582e-6, 5966.683980335, 2.246174308 }, - { 0.006304e-6, 11926.254413669, 2.512929171 }, - { 0.006603e-6, 23581.258177318, 5.393136889 }, - { 0.005123e-6, -1.484472708, 2.999641028 }, - { 0.004648e-6, 1589.072895284, 1.275847090 }, - { 0.005119e-6, 6438.496249426, 1.486539246 }, - /* 121, 130 */ - { 0.004521e-6, 4292.330832950, 6.140635794 }, - { 0.005680e-6, 23013.539539587, 4.557814849 }, - { 0.005488e-6, -3.455808046, 0.090675389 }, - { 0.004193e-6, 7234.794256242, 4.869091389 }, - { 0.003742e-6, 7238.675591600, 4.691976180 }, - { 0.004148e-6, -110.206321219, 3.016173439 }, - { 0.004553e-6, 11499.656222793, 5.554998314 }, - { 0.004892e-6, 5436.993015240, 1.475415597 }, - { 0.004044e-6, 4732.030627343, 1.398784824 }, - { 0.004164e-6, 12491.370101415, 5.650931916 }, - /* 131, 140 */ - { 0.004349e-6, 11513.883316794, 2.181745369 }, - { 0.003919e-6, 12528.018664345, 5.823319737 }, - { 0.003129e-6, 6836.645252834, 0.003844094 }, - { 0.004080e-6, -7058.598461315, 3.690360123 }, - { 0.003270e-6, 76.266071276, 1.517189902 }, - { 0.002954e-6, 6283.143160294, 4.447203799 }, - { 0.002872e-6, 28.449187468, 1.158692983 }, - { 0.002881e-6, 735.876513532, 0.349250250 }, - { 0.003279e-6, 5849.364112115, 4.893384368 }, - { 0.003625e-6, 6209.778724132, 1.473760578 }, - /* 141, 150 */ - { 0.003074e-6, 949.175608970, 5.185878737 }, - { 0.002775e-6, 9917.696874510, 1.030026325 }, - { 0.002646e-6, 10973.555686350, 3.918259169 }, - { 0.002575e-6, 25132.303399966, 6.109659023 }, - { 0.003500e-6, 263.083923373, 1.892100742 }, - { 0.002740e-6, 18319.536584880, 4.320519510 }, - { 0.002464e-6, 202.253395174, 4.698203059 }, - { 0.002409e-6, 2.542797281, 5.325009315 }, - { 0.003354e-6, -90955.551694697, 1.942656623 }, - { 0.002296e-6, 6496.374945429, 5.061810696 }, - /* 151, 160 */ - { 0.003002e-6, 6172.869528772, 2.797822767 }, - { 0.003202e-6, 27511.467873537, 0.531673101 }, - { 0.002954e-6, -6283.008539689, 4.533471191 }, - { 0.002353e-6, 639.897286314, 3.734548088 }, - { 0.002401e-6, 16200.772724501, 2.605547070 }, - { 0.003053e-6, 233141.314403759, 3.029030662 }, - { 0.003024e-6, 83286.914269554, 2.355556099 }, - { 0.002863e-6, 17298.182327326, 5.240963796 }, - { 0.002103e-6, -7079.373856808, 5.756641637 }, - { 0.002303e-6, 83996.847317911, 2.013686814 }, - /* 161, 170 */ - { 0.002303e-6, 18073.704938650, 1.089100410 }, - { 0.002381e-6, 63.735898303, 0.759188178 }, - { 0.002493e-6, 6386.168624210, 0.645026535 }, - { 0.002366e-6, 3.932153263, 6.215885448 }, - { 0.002169e-6, 11015.106477335, 4.845297676 }, - { 0.002397e-6, 6243.458341645, 3.809290043 }, - { 0.002183e-6, 1162.474704408, 6.179611691 }, - { 0.002353e-6, 6246.427287062, 4.781719760 }, - { 0.002199e-6, -245.831646229, 5.956152284 }, - { 0.001729e-6, 3894.181829542, 1.264976635 }, - /* 171, 180 */ - { 0.001896e-6, -3128.388765096, 4.914231596 }, - { 0.002085e-6, 35.164090221, 1.405158503 }, - { 0.002024e-6, 14712.317116458, 2.752035928 }, - { 0.001737e-6, 6290.189396992, 5.280820144 }, - { 0.002229e-6, 491.557929457, 1.571007057 }, - { 0.001602e-6, 14314.168113050, 4.203664806 }, - { 0.002186e-6, 454.909366527, 1.402101526 }, - { 0.001897e-6, 22483.848574493, 4.167932508 }, - { 0.001825e-6, -3738.761430108, 0.545828785 }, - { 0.001894e-6, 1052.268383188, 5.817167450 }, - /* 181, 190 */ - { 0.001421e-6, 20.355319399, 2.419886601 }, - { 0.001408e-6, 10984.192351700, 2.732084787 }, - { 0.001847e-6, 10873.986030480, 2.903477885 }, - { 0.001391e-6, -8635.942003763, 0.593891500 }, - { 0.001388e-6, -7.046236698, 1.166145902 }, - { 0.001810e-6, -88860.057071188, 0.487355242 }, - { 0.001288e-6, -1990.745017041, 3.913022880 }, - { 0.001297e-6, 23543.230504682, 3.063805171 }, - { 0.001335e-6, -266.607041722, 3.995764039 }, - { 0.001376e-6, 10969.965257698, 5.152914309 }, - /* 191, 200 */ - { 0.001745e-6, 244287.600007027, 3.626395673 }, - { 0.001649e-6, 31441.677569757, 1.952049260 }, - { 0.001416e-6, 9225.539273283, 4.996408389 }, - { 0.001238e-6, 4804.209275927, 5.503379738 }, - { 0.001472e-6, 4590.910180489, 4.164913291 }, - { 0.001169e-6, 6040.347246017, 5.841719038 }, - { 0.001039e-6, 5540.085789459, 2.769753519 }, - { 0.001004e-6, -170.672870619, 0.755008103 }, - { 0.001284e-6, 10575.406682942, 5.306538209 }, - { 0.001278e-6, 71.812653151, 4.713486491 }, - /* 201, 210 */ - { 0.001321e-6, 18209.330263660, 2.624866359 }, - { 0.001297e-6, 21228.392023546, 0.382603541 }, - { 0.000954e-6, 6282.095528923, 0.882213514 }, - { 0.001145e-6, 6058.731054289, 1.169483931 }, - { 0.000979e-6, 5547.199336460, 5.448375984 }, - { 0.000987e-6, -6262.300454499, 2.656486959 }, - { 0.001070e-6, -154717.609887482, 1.827624012 }, - { 0.000991e-6, 4701.116501708, 4.387001801 }, - { 0.001155e-6, -14.227094002, 3.042700750 }, - { 0.001176e-6, 277.034993741, 3.335519004 }, - /* 211, 220 */ - { 0.000890e-6, 13916.019109642, 5.601498297 }, - { 0.000884e-6, -1551.045222648, 1.088831705 }, - { 0.000876e-6, 5017.508371365, 3.969902609 }, - { 0.000806e-6, 15110.466119866, 5.142876744 }, - { 0.000773e-6, -4136.910433516, 0.022067765 }, - { 0.001077e-6, 175.166059800, 1.844913056 }, - { 0.000954e-6, -6284.056171060, 0.968480906 }, - { 0.000737e-6, 5326.786694021, 4.923831588 }, - { 0.000845e-6, -433.711737877, 4.749245231 }, - { 0.000819e-6, 8662.240323563, 5.991247817 }, - /* 221, 230 */ - { 0.000852e-6, 199.072001436, 2.189604979 }, - { 0.000723e-6, 17256.631536341, 6.068719637 }, - { 0.000940e-6, 6037.244203762, 6.197428148 }, - { 0.000885e-6, 11712.955318231, 3.280414875 }, - { 0.000706e-6, 12559.038152982, 2.824848947 }, - { 0.000732e-6, 2379.164473572, 2.501813417 }, - { 0.000764e-6, -6127.655450557, 2.236346329 }, - { 0.000908e-6, 131.541961686, 2.521257490 }, - { 0.000907e-6, 35371.887265976, 3.370195967 }, - { 0.000673e-6, 1066.495477190, 3.876512374 }, - /* 231, 240 */ - { 0.000814e-6, 17654.780539750, 4.627122566 }, - { 0.000630e-6, 36.027866677, 0.156368499 }, - { 0.000798e-6, 515.463871093, 5.151962502 }, - { 0.000798e-6, 148.078724426, 5.909225055 }, - { 0.000806e-6, 309.278322656, 6.054064447 }, - { 0.000607e-6, -39.617508346, 2.839021623 }, - { 0.000601e-6, 412.371096874, 3.984225404 }, - { 0.000646e-6, 11403.676995575, 3.852959484 }, - { 0.000704e-6, 13521.751441591, 2.300991267 }, - { 0.000603e-6, -65147.619767937, 4.140083146 }, - /* 241, 250 */ - { 0.000609e-6, 10177.257679534, 0.437122327 }, - { 0.000631e-6, 5767.611978898, 4.026532329 }, - { 0.000576e-6, 11087.285125918, 4.760293101 }, - { 0.000674e-6, 14945.316173554, 6.270510511 }, - { 0.000726e-6, 5429.879468239, 6.039606892 }, - { 0.000710e-6, 28766.924424484, 5.672617711 }, - { 0.000647e-6, 11856.218651625, 3.397132627 }, - { 0.000678e-6, -5481.254918868, 6.249666675 }, - { 0.000618e-6, 22003.914634870, 2.466427018 }, - { 0.000738e-6, 6134.997125565, 2.242668890 }, - /* 251, 260 */ - { 0.000660e-6, 625.670192312, 5.864091907 }, - { 0.000694e-6, 3496.032826134, 2.668309141 }, - { 0.000531e-6, 6489.261398429, 1.681888780 }, - { 0.000611e-6, -143571.324284214, 2.424978312 }, - { 0.000575e-6, 12043.574281889, 4.216492400 }, - { 0.000553e-6, 12416.588502848, 4.772158039 }, - { 0.000689e-6, 4686.889407707, 6.224271088 }, - { 0.000495e-6, 7342.457780181, 3.817285811 }, - { 0.000567e-6, 3634.621024518, 1.649264690 }, - { 0.000515e-6, 18635.928454536, 3.945345892 }, - /* 261, 270 */ - { 0.000486e-6, -323.505416657, 4.061673868 }, - { 0.000662e-6, 25158.601719765, 1.794058369 }, - { 0.000509e-6, 846.082834751, 3.053874588 }, - { 0.000472e-6, -12569.674818332, 5.112133338 }, - { 0.000461e-6, 6179.983075773, 0.513669325 }, - { 0.000641e-6, 83467.156352816, 3.210727723 }, - { 0.000520e-6, 10344.295065386, 2.445597761 }, - { 0.000493e-6, 18422.629359098, 1.676939306 }, - { 0.000478e-6, 1265.567478626, 5.487314569 }, - { 0.000472e-6, -18.159247265, 1.999707589 }, - /* 271, 280 */ - { 0.000559e-6, 11190.377900137, 5.783236356 }, - { 0.000494e-6, 9623.688276691, 3.022645053 }, - { 0.000463e-6, 5739.157790895, 1.411223013 }, - { 0.000432e-6, 16858.482532933, 1.179256434 }, - { 0.000574e-6, 72140.628666286, 1.758191830 }, - { 0.000484e-6, 17267.268201691, 3.290589143 }, - { 0.000550e-6, 4907.302050146, 0.864024298 }, - { 0.000399e-6, 14.977853527, 2.094441910 }, - { 0.000491e-6, 224.344795702, 0.878372791 }, - { 0.000432e-6, 20426.571092422, 6.003829241 }, - /* 281, 290 */ - { 0.000481e-6, 5749.452731634, 4.309591964 }, - { 0.000480e-6, 5757.317038160, 1.142348571 }, - { 0.000485e-6, 6702.560493867, 0.210580917 }, - { 0.000426e-6, 6055.549660552, 4.274476529 }, - { 0.000480e-6, 5959.570433334, 5.031351030 }, - { 0.000466e-6, 12562.628581634, 4.959581597 }, - { 0.000520e-6, 39302.096962196, 4.788002889 }, - { 0.000458e-6, 12132.439962106, 1.880103788 }, - { 0.000470e-6, 12029.347187887, 1.405611197 }, - { 0.000416e-6, -7477.522860216, 1.082356330 }, - /* 291, 300 */ - { 0.000449e-6, 11609.862544012, 4.179989585 }, - { 0.000465e-6, 17253.041107690, 0.353496295 }, - { 0.000362e-6, -4535.059436924, 1.583849576 }, - { 0.000383e-6, 21954.157609398, 3.747376371 }, - { 0.000389e-6, 17.252277143, 1.395753179 }, - { 0.000331e-6, 18052.929543158, 0.566790582 }, - { 0.000430e-6, 13517.870106233, 0.685827538 }, - { 0.000368e-6, -5756.908003246, 0.731374317 }, - { 0.000330e-6, 10557.594160824, 3.710043680 }, - { 0.000332e-6, 20199.094959633, 1.652901407 }, - /* 301, 310 */ - { 0.000384e-6, 11933.367960670, 5.827781531 }, - { 0.000387e-6, 10454.501386605, 2.541182564 }, - { 0.000325e-6, 15671.081759407, 2.178850542 }, - { 0.000318e-6, 138.517496871, 2.253253037 }, - { 0.000305e-6, 9388.005909415, 0.578340206 }, - { 0.000352e-6, 5749.861766548, 3.000297967 }, - { 0.000311e-6, 6915.859589305, 1.693574249 }, - { 0.000297e-6, 24072.921469776, 1.997249392 }, - { 0.000363e-6, -640.877607382, 5.071820966 }, - { 0.000323e-6, 12592.450019783, 1.072262823 }, - /* 311, 320 */ - { 0.000341e-6, 12146.667056108, 4.700657997 }, - { 0.000290e-6, 9779.108676125, 1.812320441 }, - { 0.000342e-6, 6132.028180148, 4.322238614 }, - { 0.000329e-6, 6268.848755990, 3.033827743 }, - { 0.000374e-6, 17996.031168222, 3.388716544 }, - { 0.000285e-6, -533.214083444, 4.687313233 }, - { 0.000338e-6, 6065.844601290, 0.877776108 }, - { 0.000276e-6, 24.298513841, 0.770299429 }, - { 0.000336e-6, -2388.894020449, 5.353796034 }, - { 0.000290e-6, 3097.883822726, 4.075291557 }, - /* 321, 330 */ - { 0.000318e-6, 709.933048357, 5.941207518 }, - { 0.000271e-6, 13095.842665077, 3.208912203 }, - { 0.000331e-6, 6073.708907816, 4.007881169 }, - { 0.000292e-6, 742.990060533, 2.714333592 }, - { 0.000362e-6, 29088.811415985, 3.215977013 }, - { 0.000280e-6, 12359.966151546, 0.710872502 }, - { 0.000267e-6, 10440.274292604, 4.730108488 }, - { 0.000262e-6, 838.969287750, 1.327720272 }, - { 0.000250e-6, 16496.361396202, 0.898769761 }, - { 0.000325e-6, 20597.243963041, 0.180044365 }, - /* 331, 340 */ - { 0.000268e-6, 6148.010769956, 5.152666276 }, - { 0.000284e-6, 5636.065016677, 5.655385808 }, - { 0.000301e-6, 6080.822454817, 2.135396205 }, - { 0.000294e-6, -377.373607916, 3.708784168 }, - { 0.000236e-6, 2118.763860378, 1.733578756 }, - { 0.000234e-6, 5867.523359379, 5.575209112 }, - { 0.000268e-6, -226858.238553767, 0.069432392 }, - { 0.000265e-6, 167283.761587465, 4.369302826 }, - { 0.000280e-6, 28237.233459389, 5.304829118 }, - { 0.000292e-6, 12345.739057544, 4.096094132 }, - /* 341, 350 */ - { 0.000223e-6, 19800.945956225, 3.069327406 }, - { 0.000301e-6, 43232.306658416, 6.205311188 }, - { 0.000264e-6, 18875.525869774, 1.417263408 }, - { 0.000304e-6, -1823.175188677, 3.409035232 }, - { 0.000301e-6, 109.945688789, 0.510922054 }, - { 0.000260e-6, 813.550283960, 2.389438934 }, - { 0.000299e-6, 316428.228673312, 5.384595078 }, - { 0.000211e-6, 5756.566278634, 3.789392838 }, - { 0.000209e-6, 5750.203491159, 1.661943545 }, - { 0.000240e-6, 12489.885628707, 5.684549045 }, - /* 351, 360 */ - { 0.000216e-6, 6303.851245484, 3.862942261 }, - { 0.000203e-6, 1581.959348283, 5.549853589 }, - { 0.000200e-6, 5642.198242609, 1.016115785 }, - { 0.000197e-6, -70.849445304, 4.690702525 }, - { 0.000227e-6, 6287.008003254, 2.911891613 }, - { 0.000197e-6, 533.623118358, 1.048982898 }, - { 0.000205e-6, -6279.485421340, 1.829362730 }, - { 0.000209e-6, -10988.808157535, 2.636140084 }, - { 0.000208e-6, -227.526189440, 4.127883842 }, - { 0.000191e-6, 415.552490612, 4.401165650 }, - /* 361, 370 */ - { 0.000190e-6, 29296.615389579, 4.175658539 }, - { 0.000264e-6, 66567.485864652, 4.601102551 }, - { 0.000256e-6, -3646.350377354, 0.506364778 }, - { 0.000188e-6, 13119.721102825, 2.032195842 }, - { 0.000185e-6, -209.366942175, 4.694756586 }, - { 0.000198e-6, 25934.124331089, 3.832703118 }, - { 0.000195e-6, 4061.219215394, 3.308463427 }, - { 0.000234e-6, 5113.487598583, 1.716090661 }, - { 0.000188e-6, 1478.866574064, 5.686865780 }, - { 0.000222e-6, 11823.161639450, 1.942386641 }, - /* 371, 380 */ - { 0.000181e-6, 10770.893256262, 1.999482059 }, - { 0.000171e-6, 6546.159773364, 1.182807992 }, - { 0.000206e-6, 70.328180442, 5.934076062 }, - { 0.000169e-6, 20995.392966449, 2.169080622 }, - { 0.000191e-6, 10660.686935042, 5.405515999 }, - { 0.000228e-6, 33019.021112205, 4.656985514 }, - { 0.000184e-6, -4933.208440333, 3.327476868 }, - { 0.000220e-6, -135.625325010, 1.765430262 }, - { 0.000166e-6, 23141.558382925, 3.454132746 }, - { 0.000191e-6, 6144.558353121, 5.020393445 }, - /* 381, 390 */ - { 0.000180e-6, 6084.003848555, 0.602182191 }, - { 0.000163e-6, 17782.732072784, 4.960593133 }, - { 0.000225e-6, 16460.333529525, 2.596451817 }, - { 0.000222e-6, 5905.702242076, 3.731990323 }, - { 0.000204e-6, 227.476132789, 5.636192701 }, - { 0.000159e-6, 16737.577236597, 3.600691544 }, - { 0.000200e-6, 6805.653268085, 0.868220961 }, - { 0.000187e-6, 11919.140866668, 2.629456641 }, - { 0.000161e-6, 127.471796607, 2.862574720 }, - { 0.000205e-6, 6286.666278643, 1.742882331 }, - /* 391, 400 */ - { 0.000189e-6, 153.778810485, 4.812372643 }, - { 0.000168e-6, 16723.350142595, 0.027860588 }, - { 0.000149e-6, 11720.068865232, 0.659721876 }, - { 0.000189e-6, 5237.921013804, 5.245313000 }, - { 0.000143e-6, 6709.674040867, 4.317625647 }, - { 0.000146e-6, 4487.817406270, 4.815297007 }, - { 0.000144e-6, -664.756045130, 5.381366880 }, - { 0.000175e-6, 5127.714692584, 4.728443327 }, - { 0.000162e-6, 6254.626662524, 1.435132069 }, - { 0.000187e-6, 47162.516354635, 1.354371923 }, - /* 401, 410 */ - { 0.000146e-6, 11080.171578918, 3.369695406 }, - { 0.000180e-6, -348.924420448, 2.490902145 }, - { 0.000148e-6, 151.047669843, 3.799109588 }, - { 0.000157e-6, 6197.248551160, 1.284375887 }, - { 0.000167e-6, 146.594251718, 0.759969109 }, - { 0.000133e-6, -5331.357443741, 5.409701889 }, - { 0.000154e-6, 95.979227218, 3.366890614 }, - { 0.000148e-6, -6418.140930027, 3.384104996 }, - { 0.000128e-6, -6525.804453965, 3.803419985 }, - { 0.000130e-6, 11293.470674356, 0.939039445 }, - /* 411, 420 */ - { 0.000152e-6, -5729.506447149, 0.734117523 }, - { 0.000138e-6, 210.117701700, 2.564216078 }, - { 0.000123e-6, 6066.595360816, 4.517099537 }, - { 0.000140e-6, 18451.078546566, 0.642049130 }, - { 0.000126e-6, 11300.584221356, 3.485280663 }, - { 0.000119e-6, 10027.903195729, 3.217431161 }, - { 0.000151e-6, 4274.518310832, 4.404359108 }, - { 0.000117e-6, 6072.958148291, 0.366324650 }, - { 0.000165e-6, -7668.637425143, 4.298212528 }, - { 0.000117e-6, -6245.048177356, 5.379518958 }, - /* 421, 430 */ - { 0.000130e-6, -5888.449964932, 4.527681115 }, - { 0.000121e-6, -543.918059096, 6.109429504 }, - { 0.000162e-6, 9683.594581116, 5.720092446 }, - { 0.000141e-6, 6219.339951688, 0.679068671 }, - { 0.000118e-6, 22743.409379516, 4.881123092 }, - { 0.000129e-6, 1692.165669502, 0.351407289 }, - { 0.000126e-6, 5657.405657679, 5.146592349 }, - { 0.000114e-6, 728.762966531, 0.520791814 }, - { 0.000120e-6, 52.596639600, 0.948516300 }, - { 0.000115e-6, 65.220371012, 3.504914846 }, - /* 431, 440 */ - { 0.000126e-6, 5881.403728234, 5.577502482 }, - { 0.000158e-6, 163096.180360983, 2.957128968 }, - { 0.000134e-6, 12341.806904281, 2.598576764 }, - { 0.000151e-6, 16627.370915377, 3.985702050 }, - { 0.000109e-6, 1368.660252845, 0.014730471 }, - { 0.000131e-6, 6211.263196841, 0.085077024 }, - { 0.000146e-6, 5792.741760812, 0.708426604 }, - { 0.000146e-6, -77.750543984, 3.121576600 }, - { 0.000107e-6, 5341.013788022, 0.288231904 }, - { 0.000138e-6, 6281.591377283, 2.797450317 }, - /* 441, 450 */ - { 0.000113e-6, -6277.552925684, 2.788904128 }, - { 0.000115e-6, -525.758811831, 5.895222200 }, - { 0.000138e-6, 6016.468808270, 6.096188999 }, - { 0.000139e-6, 23539.707386333, 2.028195445 }, - { 0.000146e-6, -4176.041342449, 4.660008502 }, - { 0.000107e-6, 16062.184526117, 4.066520001 }, - { 0.000142e-6, 83783.548222473, 2.936315115 }, - { 0.000128e-6, 9380.959672717, 3.223844306 }, - { 0.000135e-6, 6205.325306007, 1.638054048 }, - { 0.000101e-6, 2699.734819318, 5.481603249 }, - /* 451, 460 */ - { 0.000104e-6, -568.821874027, 2.205734493 }, - { 0.000103e-6, 6321.103522627, 2.440421099 }, - { 0.000119e-6, 6321.208885629, 2.547496264 }, - { 0.000138e-6, 1975.492545856, 2.314608466 }, - { 0.000121e-6, 137.033024162, 4.539108237 }, - { 0.000123e-6, 19402.796952817, 4.538074405 }, - { 0.000119e-6, 22805.735565994, 2.869040566 }, - { 0.000133e-6, 64471.991241142, 6.056405489 }, - { 0.000129e-6, -85.827298831, 2.540635083 }, - { 0.000131e-6, 13613.804277336, 4.005732868 }, - /* 461, 470 */ - { 0.000104e-6, 9814.604100291, 1.959967212 }, - { 0.000112e-6, 16097.679950283, 3.589026260 }, - { 0.000123e-6, 2107.034507542, 1.728627253 }, - { 0.000121e-6, 36949.230808424, 6.072332087 }, - { 0.000108e-6, -12539.853380183, 3.716133846 }, - { 0.000113e-6, -7875.671863624, 2.725771122 }, - { 0.000109e-6, 4171.425536614, 4.033338079 }, - { 0.000101e-6, 6247.911759770, 3.441347021 }, - { 0.000113e-6, 7330.728427345, 0.656372122 }, - { 0.000113e-6, 51092.726050855, 2.791483066 }, - /* 471, 480 */ - { 0.000106e-6, 5621.842923210, 1.815323326 }, - { 0.000101e-6, 111.430161497, 5.711033677 }, - { 0.000103e-6, 909.818733055, 2.812745443 }, - { 0.000101e-6, 1790.642637886, 1.965746028 }, - - /* T */ - { 102.156724e-6, 6283.075849991, 4.249032005 }, - { 1.706807e-6, 12566.151699983, 4.205904248 }, - { 0.269668e-6, 213.299095438, 3.400290479 }, - { 0.265919e-6, 529.690965095, 5.836047367 }, - { 0.210568e-6, -3.523118349, 6.262738348 }, - { 0.077996e-6, 5223.693919802, 4.670344204 }, - /* 481, 490 */ - { 0.054764e-6, 1577.343542448, 4.534800170 }, - { 0.059146e-6, 26.298319800, 1.083044735 }, - { 0.034420e-6, -398.149003408, 5.980077351 }, - { 0.032088e-6, 18849.227549974, 4.162913471 }, - { 0.033595e-6, 5507.553238667, 5.980162321 }, - { 0.029198e-6, 5856.477659115, 0.623811863 }, - { 0.027764e-6, 155.420399434, 3.745318113 }, - { 0.025190e-6, 5746.271337896, 2.980330535 }, - { 0.022997e-6, -796.298006816, 1.174411803 }, - { 0.024976e-6, 5760.498431898, 2.467913690 }, - /* 491, 500 */ - { 0.021774e-6, 206.185548437, 3.854787540 }, - { 0.017925e-6, -775.522611324, 1.092065955 }, - { 0.013794e-6, 426.598190876, 2.699831988 }, - { 0.013276e-6, 6062.663207553, 5.845801920 }, - { 0.011774e-6, 12036.460734888, 2.292832062 }, - { 0.012869e-6, 6076.890301554, 5.333425680 }, - { 0.012152e-6, 1059.381930189, 6.222874454 }, - { 0.011081e-6, -7.113547001, 5.154724984 }, - { 0.010143e-6, 4694.002954708, 4.044013795 }, - { 0.009357e-6, 5486.777843175, 3.416081409 }, - /* 501, 510 */ - { 0.010084e-6, 522.577418094, 0.749320262 }, - { 0.008587e-6, 10977.078804699, 2.777152598 }, - { 0.008628e-6, 6275.962302991, 4.562060226 }, - { 0.008158e-6, -220.412642439, 5.806891533 }, - { 0.007746e-6, 2544.314419883, 1.603197066 }, - { 0.007670e-6, 2146.165416475, 3.000200440 }, - { 0.007098e-6, 74.781598567, 0.443725817 }, - { 0.006180e-6, -536.804512095, 1.302642751 }, - { 0.005818e-6, 5088.628839767, 4.827723531 }, - { 0.004945e-6, -6286.598968340, 0.268305170 }, - /* 511, 520 */ - { 0.004774e-6, 1349.867409659, 5.808636673 }, - { 0.004687e-6, -242.728603974, 5.154890570 }, - { 0.006089e-6, 1748.016413067, 4.403765209 }, - { 0.005975e-6, -1194.447010225, 2.583472591 }, - { 0.004229e-6, 951.718406251, 0.931172179 }, - { 0.005264e-6, 553.569402842, 2.336107252 }, - { 0.003049e-6, 5643.178563677, 1.362634430 }, - { 0.002974e-6, 6812.766815086, 1.583012668 }, - { 0.003403e-6, -2352.866153772, 2.552189886 }, - { 0.003030e-6, 419.484643875, 5.286473844 }, - /* 521, 530 */ - { 0.003210e-6, -7.046236698, 1.863796539 }, - { 0.003058e-6, 9437.762934887, 4.226420633 }, - { 0.002589e-6, 12352.852604545, 1.991935820 }, - { 0.002927e-6, 5216.580372801, 2.319951253 }, - { 0.002425e-6, 5230.807466803, 3.084752833 }, - { 0.002656e-6, 3154.687084896, 2.487447866 }, - { 0.002445e-6, 10447.387839604, 2.347139160 }, - { 0.002990e-6, 4690.479836359, 6.235872050 }, - { 0.002890e-6, 5863.591206116, 0.095197563 }, - { 0.002498e-6, 6438.496249426, 2.994779800 }, - /* 531, 540 */ - { 0.001889e-6, 8031.092263058, 3.569003717 }, - { 0.002567e-6, 801.820931124, 3.425611498 }, - { 0.001803e-6, -71430.695617928, 2.192295512 }, - { 0.001782e-6, 3.932153263, 5.180433689 }, - { 0.001694e-6, -4705.732307544, 4.641779174 }, - { 0.001704e-6, -1592.596013633, 3.997097652 }, - { 0.001735e-6, 5849.364112115, 0.417558428 }, - { 0.001643e-6, 8429.241266467, 2.180619584 }, - { 0.001680e-6, 38.133035638, 4.164529426 }, - { 0.002045e-6, 7084.896781115, 0.526323854 }, - /* 541, 550 */ - { 0.001458e-6, 4292.330832950, 1.356098141 }, - { 0.001437e-6, 20.355319399, 3.895439360 }, - { 0.001738e-6, 6279.552731642, 0.087484036 }, - { 0.001367e-6, 14143.495242431, 3.987576591 }, - { 0.001344e-6, 7234.794256242, 0.090454338 }, - { 0.001438e-6, 11499.656222793, 0.974387904 }, - { 0.001257e-6, 6836.645252834, 1.509069366 }, - { 0.001358e-6, 11513.883316794, 0.495572260 }, - { 0.001628e-6, 7632.943259650, 4.968445721 }, - { 0.001169e-6, 103.092774219, 2.838496795 }, - /* 551, 560 */ - { 0.001162e-6, 4164.311989613, 3.408387778 }, - { 0.001092e-6, 6069.776754553, 3.617942651 }, - { 0.001008e-6, 17789.845619785, 0.286350174 }, - { 0.001008e-6, 639.897286314, 1.610762073 }, - { 0.000918e-6, 10213.285546211, 5.532798067 }, - { 0.001011e-6, -6256.777530192, 0.661826484 }, - { 0.000753e-6, 16730.463689596, 3.905030235 }, - { 0.000737e-6, 11926.254413669, 4.641956361 }, - { 0.000694e-6, 3340.612426700, 2.111120332 }, - { 0.000701e-6, 3894.181829542, 2.760823491 }, - /* 561, 570 */ - { 0.000689e-6, -135.065080035, 4.768800780 }, - { 0.000700e-6, 13367.972631107, 5.760439898 }, - { 0.000664e-6, 6040.347246017, 1.051215840 }, - { 0.000654e-6, 5650.292110678, 4.911332503 }, - { 0.000788e-6, 6681.224853400, 4.699648011 }, - { 0.000628e-6, 5333.900241022, 5.024608847 }, - { 0.000755e-6, -110.206321219, 4.370971253 }, - { 0.000628e-6, 6290.189396992, 3.660478857 }, - { 0.000635e-6, 25132.303399966, 4.121051532 }, - { 0.000534e-6, 5966.683980335, 1.173284524 }, - /* 571, 580 */ - { 0.000543e-6, -433.711737877, 0.345585464 }, - { 0.000517e-6, -1990.745017041, 5.414571768 }, - { 0.000504e-6, 5767.611978898, 2.328281115 }, - { 0.000485e-6, 5753.384884897, 1.685874771 }, - { 0.000463e-6, 7860.419392439, 5.297703006 }, - { 0.000604e-6, 515.463871093, 0.591998446 }, - { 0.000443e-6, 12168.002696575, 4.830881244 }, - { 0.000570e-6, 199.072001436, 3.899190272 }, - { 0.000465e-6, 10969.965257698, 0.476681802 }, - { 0.000424e-6, -7079.373856808, 1.112242763 }, - /* 581, 590 */ - { 0.000427e-6, 735.876513532, 1.994214480 }, - { 0.000478e-6, -6127.655450557, 3.778025483 }, - { 0.000414e-6, 10973.555686350, 5.441088327 }, - { 0.000512e-6, 1589.072895284, 0.107123853 }, - { 0.000378e-6, 10984.192351700, 0.915087231 }, - { 0.000402e-6, 11371.704689758, 4.107281715 }, - { 0.000453e-6, 9917.696874510, 1.917490952 }, - { 0.000395e-6, 149.563197135, 2.763124165 }, - { 0.000371e-6, 5739.157790895, 3.112111866 }, - { 0.000350e-6, 11790.629088659, 0.440639857 }, - /* 591, 600 */ - { 0.000356e-6, 6133.512652857, 5.444568842 }, - { 0.000344e-6, 412.371096874, 5.676832684 }, - { 0.000383e-6, 955.599741609, 5.559734846 }, - { 0.000333e-6, 6496.374945429, 0.261537984 }, - { 0.000340e-6, 6055.549660552, 5.975534987 }, - { 0.000334e-6, 1066.495477190, 2.335063907 }, - { 0.000399e-6, 11506.769769794, 5.321230910 }, - { 0.000314e-6, 18319.536584880, 2.313312404 }, - { 0.000424e-6, 1052.268383188, 1.211961766 }, - { 0.000307e-6, 63.735898303, 3.169551388 }, - /* 601, 610 */ - { 0.000329e-6, 29.821438149, 6.106912080 }, - { 0.000357e-6, 6309.374169791, 4.223760346 }, - { 0.000312e-6, -3738.761430108, 2.180556645 }, - { 0.000301e-6, 309.278322656, 1.499984572 }, - { 0.000268e-6, 12043.574281889, 2.447520648 }, - { 0.000257e-6, 12491.370101415, 3.662331761 }, - { 0.000290e-6, 625.670192312, 1.272834584 }, - { 0.000256e-6, 5429.879468239, 1.913426912 }, - { 0.000339e-6, 3496.032826134, 4.165930011 }, - { 0.000283e-6, 3930.209696220, 4.325565754 }, - /* 611, 620 */ - { 0.000241e-6, 12528.018664345, 3.832324536 }, - { 0.000304e-6, 4686.889407707, 1.612348468 }, - { 0.000259e-6, 16200.772724501, 3.470173146 }, - { 0.000238e-6, 12139.553509107, 1.147977842 }, - { 0.000236e-6, 6172.869528772, 3.776271728 }, - { 0.000296e-6, -7058.598461315, 0.460368852 }, - { 0.000306e-6, 10575.406682942, 0.554749016 }, - { 0.000251e-6, 17298.182327326, 0.834332510 }, - { 0.000290e-6, 4732.030627343, 4.759564091 }, - { 0.000261e-6, 5884.926846583, 0.298259862 }, - /* 621, 630 */ - { 0.000249e-6, 5547.199336460, 3.749366406 }, - { 0.000213e-6, 11712.955318231, 5.415666119 }, - { 0.000223e-6, 4701.116501708, 2.703203558 }, - { 0.000268e-6, -640.877607382, 0.283670793 }, - { 0.000209e-6, 5636.065016677, 1.238477199 }, - { 0.000193e-6, 10177.257679534, 1.943251340 }, - { 0.000182e-6, 6283.143160294, 2.456157599 }, - { 0.000184e-6, -227.526189440, 5.888038582 }, - { 0.000182e-6, -6283.008539689, 0.241332086 }, - { 0.000228e-6, -6284.056171060, 2.657323816 }, - /* 631, 640 */ - { 0.000166e-6, 7238.675591600, 5.930629110 }, - { 0.000167e-6, 3097.883822726, 5.570955333 }, - { 0.000159e-6, -323.505416657, 5.786670700 }, - { 0.000154e-6, -4136.910433516, 1.517805532 }, - { 0.000176e-6, 12029.347187887, 3.139266834 }, - { 0.000167e-6, 12132.439962106, 3.556352289 }, - { 0.000153e-6, 202.253395174, 1.463313961 }, - { 0.000157e-6, 17267.268201691, 1.586837396 }, - { 0.000142e-6, 83996.847317911, 0.022670115 }, - { 0.000152e-6, 17260.154654690, 0.708528947 }, - /* 641, 650 */ - { 0.000144e-6, 6084.003848555, 5.187075177 }, - { 0.000135e-6, 5756.566278634, 1.993229262 }, - { 0.000134e-6, 5750.203491159, 3.457197134 }, - { 0.000144e-6, 5326.786694021, 6.066193291 }, - { 0.000160e-6, 11015.106477335, 1.710431974 }, - { 0.000133e-6, 3634.621024518, 2.836451652 }, - { 0.000134e-6, 18073.704938650, 5.453106665 }, - { 0.000134e-6, 1162.474704408, 5.326898811 }, - { 0.000128e-6, 5642.198242609, 2.511652591 }, - { 0.000160e-6, 632.783739313, 5.628785365 }, - /* 651, 660 */ - { 0.000132e-6, 13916.019109642, 0.819294053 }, - { 0.000122e-6, 14314.168113050, 5.677408071 }, - { 0.000125e-6, 12359.966151546, 5.251984735 }, - { 0.000121e-6, 5749.452731634, 2.210924603 }, - { 0.000136e-6, -245.831646229, 1.646502367 }, - { 0.000120e-6, 5757.317038160, 3.240883049 }, - { 0.000134e-6, 12146.667056108, 3.059480037 }, - { 0.000137e-6, 6206.809778716, 1.867105418 }, - { 0.000141e-6, 17253.041107690, 2.069217456 }, - { 0.000129e-6, -7477.522860216, 2.781469314 }, - /* 661, 670 */ - { 0.000116e-6, 5540.085789459, 4.281176991 }, - { 0.000116e-6, 9779.108676125, 3.320925381 }, - { 0.000129e-6, 5237.921013804, 3.497704076 }, - { 0.000113e-6, 5959.570433334, 0.983210840 }, - { 0.000122e-6, 6282.095528923, 2.674938860 }, - { 0.000140e-6, -11.045700264, 4.957936982 }, - { 0.000108e-6, 23543.230504682, 1.390113589 }, - { 0.000106e-6, -12569.674818332, 0.429631317 }, - { 0.000110e-6, -266.607041722, 5.501340197 }, - { 0.000115e-6, 12559.038152982, 4.691456618 }, - /* 671, 680 */ - { 0.000134e-6, -2388.894020449, 0.577313584 }, - { 0.000109e-6, 10440.274292604, 6.218148717 }, - { 0.000102e-6, -543.918059096, 1.477842615 }, - { 0.000108e-6, 21228.392023546, 2.237753948 }, - { 0.000101e-6, -4535.059436924, 3.100492232 }, - { 0.000103e-6, 76.266071276, 5.594294322 }, - { 0.000104e-6, 949.175608970, 5.674287810 }, - { 0.000101e-6, 13517.870106233, 2.196632348 }, - { 0.000100e-6, 11933.367960670, 4.056084160 }, - - /* T^2 */ - { 4.322990e-6, 6283.075849991, 2.642893748 }, - /* 681, 690 */ - { 0.406495e-6, 0.000000000, 4.712388980 }, - { 0.122605e-6, 12566.151699983, 2.438140634 }, - { 0.019476e-6, 213.299095438, 1.642186981 }, - { 0.016916e-6, 529.690965095, 4.510959344 }, - { 0.013374e-6, -3.523118349, 1.502210314 }, - { 0.008042e-6, 26.298319800, 0.478549024 }, - { 0.007824e-6, 155.420399434, 5.254710405 }, - { 0.004894e-6, 5746.271337896, 4.683210850 }, - { 0.004875e-6, 5760.498431898, 0.759507698 }, - { 0.004416e-6, 5223.693919802, 6.028853166 }, - /* 691, 700 */ - { 0.004088e-6, -7.113547001, 0.060926389 }, - { 0.004433e-6, 77713.771467920, 3.627734103 }, - { 0.003277e-6, 18849.227549974, 2.327912542 }, - { 0.002703e-6, 6062.663207553, 1.271941729 }, - { 0.003435e-6, -775.522611324, 0.747446224 }, - { 0.002618e-6, 6076.890301554, 3.633715689 }, - { 0.003146e-6, 206.185548437, 5.647874613 }, - { 0.002544e-6, 1577.343542448, 6.232904270 }, - { 0.002218e-6, -220.412642439, 1.309509946 }, - { 0.002197e-6, 5856.477659115, 2.407212349 }, - /* 701, 710 */ - { 0.002897e-6, 5753.384884897, 5.863842246 }, - { 0.001766e-6, 426.598190876, 0.754113147 }, - { 0.001738e-6, -796.298006816, 2.714942671 }, - { 0.001695e-6, 522.577418094, 2.629369842 }, - { 0.001584e-6, 5507.553238667, 1.341138229 }, - { 0.001503e-6, -242.728603974, 0.377699736 }, - { 0.001552e-6, -536.804512095, 2.904684667 }, - { 0.001370e-6, -398.149003408, 1.265599125 }, - { 0.001889e-6, -5573.142801634, 4.413514859 }, - { 0.001722e-6, 6069.776754553, 2.445966339 }, - /* 711, 720 */ - { 0.001124e-6, 1059.381930189, 5.041799657 }, - { 0.001258e-6, 553.569402842, 3.849557278 }, - { 0.000831e-6, 951.718406251, 2.471094709 }, - { 0.000767e-6, 4694.002954708, 5.363125422 }, - { 0.000756e-6, 1349.867409659, 1.046195744 }, - { 0.000775e-6, -11.045700264, 0.245548001 }, - { 0.000597e-6, 2146.165416475, 4.543268798 }, - { 0.000568e-6, 5216.580372801, 4.178853144 }, - { 0.000711e-6, 1748.016413067, 5.934271972 }, - { 0.000499e-6, 12036.460734888, 0.624434410 }, - /* 721, 730 */ - { 0.000671e-6, -1194.447010225, 4.136047594 }, - { 0.000488e-6, 5849.364112115, 2.209679987 }, - { 0.000621e-6, 6438.496249426, 4.518860804 }, - { 0.000495e-6, -6286.598968340, 1.868201275 }, - { 0.000456e-6, 5230.807466803, 1.271231591 }, - { 0.000451e-6, 5088.628839767, 0.084060889 }, - { 0.000435e-6, 5643.178563677, 3.324456609 }, - { 0.000387e-6, 10977.078804699, 4.052488477 }, - { 0.000547e-6, 161000.685737473, 2.841633844 }, - { 0.000522e-6, 3154.687084896, 2.171979966 }, - /* 731, 740 */ - { 0.000375e-6, 5486.777843175, 4.983027306 }, - { 0.000421e-6, 5863.591206116, 4.546432249 }, - { 0.000439e-6, 7084.896781115, 0.522967921 }, - { 0.000309e-6, 2544.314419883, 3.172606705 }, - { 0.000347e-6, 4690.479836359, 1.479586566 }, - { 0.000317e-6, 801.820931124, 3.553088096 }, - { 0.000262e-6, 419.484643875, 0.606635550 }, - { 0.000248e-6, 6836.645252834, 3.014082064 }, - { 0.000245e-6, -1592.596013633, 5.519526220 }, - { 0.000225e-6, 4292.330832950, 2.877956536 }, - /* 741, 750 */ - { 0.000214e-6, 7234.794256242, 1.605227587 }, - { 0.000205e-6, 5767.611978898, 0.625804796 }, - { 0.000180e-6, 10447.387839604, 3.499954526 }, - { 0.000229e-6, 199.072001436, 5.632304604 }, - { 0.000214e-6, 639.897286314, 5.960227667 }, - { 0.000175e-6, -433.711737877, 2.162417992 }, - { 0.000209e-6, 515.463871093, 2.322150893 }, - { 0.000173e-6, 6040.347246017, 2.556183691 }, - { 0.000184e-6, 6309.374169791, 4.732296790 }, - { 0.000227e-6, 149854.400134205, 5.385812217 }, - /* 751, 760 */ - { 0.000154e-6, 8031.092263058, 5.120720920 }, - { 0.000151e-6, 5739.157790895, 4.815000443 }, - { 0.000197e-6, 7632.943259650, 0.222827271 }, - { 0.000197e-6, 74.781598567, 3.910456770 }, - { 0.000138e-6, 6055.549660552, 1.397484253 }, - { 0.000149e-6, -6127.655450557, 5.333727496 }, - { 0.000137e-6, 3894.181829542, 4.281749907 }, - { 0.000135e-6, 9437.762934887, 5.979971885 }, - { 0.000139e-6, -2352.866153772, 4.715630782 }, - { 0.000142e-6, 6812.766815086, 0.513330157 }, - /* 761, 770 */ - { 0.000120e-6, -4705.732307544, 0.194160689 }, - { 0.000131e-6, -71430.695617928, 0.000379226 }, - { 0.000124e-6, 6279.552731642, 2.122264908 }, - { 0.000108e-6, -6256.777530192, 0.883445696 }, - - /* T^3 */ - { 0.143388e-6, 6283.075849991, 1.131453581 }, - { 0.006671e-6, 12566.151699983, 0.775148887 }, - { 0.001480e-6, 155.420399434, 0.480016880 }, - { 0.000934e-6, 213.299095438, 6.144453084 }, - { 0.000795e-6, 529.690965095, 2.941595619 }, - { 0.000673e-6, 5746.271337896, 0.120415406 }, - /* 771, 780 */ - { 0.000672e-6, 5760.498431898, 5.317009738 }, - { 0.000389e-6, -220.412642439, 3.090323467 }, - { 0.000373e-6, 6062.663207553, 3.003551964 }, - { 0.000360e-6, 6076.890301554, 1.918913041 }, - { 0.000316e-6, -21.340641002, 5.545798121 }, - { 0.000315e-6, -242.728603974, 1.884932563 }, - { 0.000278e-6, 206.185548437, 1.266254859 }, - { 0.000238e-6, -536.804512095, 4.532664830 }, - { 0.000185e-6, 522.577418094, 4.578313856 }, - { 0.000245e-6, 18849.227549974, 0.587467082 }, - /* 781, 787 */ - { 0.000180e-6, 426.598190876, 5.151178553 }, - { 0.000200e-6, 553.569402842, 5.355983739 }, - { 0.000141e-6, 5223.693919802, 1.336556009 }, - { 0.000104e-6, 5856.477659115, 4.239842759 }, - - /* T^4 */ - { 0.003826e-6, 6283.075849991, 5.705257275 }, - { 0.000303e-6, 12566.151699983, 5.407132842 }, - { 0.000209e-6, 155.420399434, 1.989815753 } - }; - - -/* Time since J2000.0 in Julian millennia. */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJM; - -/* ================= */ -/* Topocentric terms */ -/* ================= */ - -/* Convert UT to local solar time in radians. */ - tsol = fmod(ut, 1.0) * ERFA_D2PI + elong; - -/* FUNDAMENTAL ARGUMENTS: Simon et al. 1994. */ - -/* Combine time argument (millennia) with deg/arcsec factor. */ - w = t / 3600.0; - -/* Sun Mean Longitude. */ - elsun = fmod(280.46645683 + 1296027711.03429 * w, 360.0) * ERFA_DD2R; - -/* Sun Mean Anomaly. */ - emsun = fmod(357.52910918 + 1295965810.481 * w, 360.0) * ERFA_DD2R; - -/* Mean Elongation of Moon from Sun. */ - d = fmod(297.85019547 + 16029616012.090 * w, 360.0) * ERFA_DD2R; - -/* Mean Longitude of Jupiter. */ - elj = fmod(34.35151874 + 109306899.89453 * w, 360.0) * ERFA_DD2R; - -/* Mean Longitude of Saturn. */ - els = fmod(50.07744430 + 44046398.47038 * w, 360.0) * ERFA_DD2R; - -/* TOPOCENTRIC TERMS: Moyer 1981 and Murray 1983. */ - wt = + 0.00029e-10 * u * sin(tsol + elsun - els) - + 0.00100e-10 * u * sin(tsol - 2.0 * emsun) - + 0.00133e-10 * u * sin(tsol - d) - + 0.00133e-10 * u * sin(tsol + elsun - elj) - - 0.00229e-10 * u * sin(tsol + 2.0 * elsun + emsun) - - 0.02200e-10 * v * cos(elsun + emsun) - + 0.05312e-10 * u * sin(tsol - emsun) - - 0.13677e-10 * u * sin(tsol + 2.0 * elsun) - - 1.31840e-10 * v * cos(elsun) - + 3.17679e-10 * u * sin(tsol); - -/* ===================== */ -/* Fairhead et al. model */ -/* ===================== */ - -/* T**0 */ - w0 = 0; - for (j = 473; j >= 0; j--) { - w0 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]); - } - -/* T**1 */ - w1 = 0; - for (j = 678; j >= 474; j--) { - w1 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]); - } - -/* T**2 */ - w2 = 0; - for (j = 763; j >= 679; j--) { - w2 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]); - } - -/* T**3 */ - w3 = 0; - for (j = 783; j >= 764; j--) { - w3 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]); - } - -/* T**4 */ - w4 = 0; - for (j = 786; j >= 784; j--) { - w4 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]); - } - -/* Multiply by powers of T and combine. */ - wf = t * (t * (t * (t * w4 + w3) + w2) + w1) + w0; - -/* Adjustments to use JPL planetary masses instead of IAU. */ - wj = 0.00065e-6 * sin(6069.776754 * t + 4.021194) + - 0.00033e-6 * sin( 213.299095 * t + 5.543132) + - (-0.00196e-6 * sin(6208.294251 * t + 5.696701)) + - (-0.00173e-6 * sin( 74.781599 * t + 2.435900)) + - 0.03638e-6 * t * t; - -/* ============ */ -/* Final result */ -/* ============ */ - -/* TDB-TT in seconds. */ - w = wt + wf + wj; - - return w; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/dtf2d.c b/ast/erfa/dtf2d.c deleted file mode 100644 index 70d6b25..0000000 --- a/ast/erfa/dtf2d.c +++ /dev/null @@ -1,212 +0,0 @@ -#include "erfa.h" -#include - -int eraDtf2d(const char *scale, int iy, int im, int id, - int ihr, int imn, double sec, double *d1, double *d2) -/* -** - - - - - - - - - -** e r a D t f 2 d -** - - - - - - - - - -** -** Encode date and time fields into 2-part Julian Date (or in the case -** of UTC a quasi-JD form that includes special provision for leap -** seconds). -** -** Given: -** scale char[] time scale ID (Note 1) -** iy,im,id int year, month, day in Gregorian calendar (Note 2) -** ihr,imn int hour, minute -** sec double seconds -** -** Returned: -** d1,d2 double 2-part Julian Date (Notes 3,4) -** -** Returned (function value): -** int status: +3 = both of next two -** +2 = time is after end of day (Note 5) -** +1 = dubious year (Note 6) -** 0 = OK -** -1 = bad year -** -2 = bad month -** -3 = bad day -** -4 = bad hour -** -5 = bad minute -** -6 = bad second (<0) -** -** Notes: -** -** 1) scale identifies the time scale. Only the value "UTC" (in upper -** case) is significant, and enables handling of leap seconds (see -** Note 4). -** -** 2) For calendar conventions and limitations, see eraCal2jd. -** -** 3) The sum of the results, d1+d2, is Julian Date, where normally d1 -** is the Julian Day Number and d2 is the fraction of a day. In the -** case of UTC, where the use of JD is problematical, special -** conventions apply: see the next note. -** -** 4) JD cannot unambiguously represent UTC during a leap second unless -** special measures are taken. The ERFA internal convention is that -** the quasi-JD day represents UTC days whether the length is 86399, -** 86400 or 86401 SI seconds. In the 1960-1972 era there were -** smaller jumps (in either direction) each time the linear UTC(TAI) -** expression was changed, and these "mini-leaps" are also included -** in the ERFA convention. -** -** 5) The warning status "time is after end of day" usually means that -** the sec argument is greater than 60.0. However, in a day ending -** in a leap second the limit changes to 61.0 (or 59.0 in the case -** of a negative leap second). -** -** 6) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the future -** to be trusted. See eraDat for further details. -** -** 7) Only in the case of continuous and regular time scales (TAI, TT, -** TCG, TCB and TDB) is the result d1+d2 a Julian Date, strictly -** speaking. In the other cases (UT1 and UTC) the result must be -** used with circumspection; in particular the difference between -** two such results cannot be interpreted as a precise time -** interval. -** -** Called: -** eraCal2jd Gregorian calendar to JD -** eraDat delta(AT) = TAI-UTC -** eraJd2cal JD to Gregorian calendar -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int js, iy2, im2, id2; - double dj, w, day, seclim, dat0, dat12, dat24, dleap, time; - - -/* Today's Julian Day Number. */ - js = eraCal2jd(iy, im, id, &dj, &w); - if ( js ) return js; - dj += w; - -/* Day length and final minute length in seconds (provisional). */ - day = ERFA_DAYSEC; - seclim = 60.0; - -/* Deal with the UTC leap second case. */ - if ( ! strcmp(scale,"UTC") ) { - - /* TAI-UTC at 0h today. */ - js = eraDat(iy, im, id, 0.0, &dat0); - if ( js < 0 ) return js; - - /* TAI-UTC at 12h today (to detect drift). */ - js = eraDat(iy, im, id, 0.5, &dat12); - if ( js < 0 ) return js; - - /* TAI-UTC at 0h tomorrow (to detect jumps). */ - js = eraJd2cal ( dj, 1.5, &iy2, &im2, &id2, &w); - if ( js ) return js; - js = eraDat(iy2, im2, id2, 0.0, &dat24); - if ( js < 0 ) return js; - - /* Any sudden change in TAI-UTC between today and tomorrow. */ - dleap = dat24 - (2.0*dat12 - dat0); - - /* If leap second day, correct the day and final minute lengths. */ - day += dleap; - if ( ihr == 23 && imn == 59 ) seclim += dleap; - - /* End of UTC-specific actions. */ - } - -/* Validate the time. */ - if ( ihr >= 0 && ihr <= 23 ) { - if ( imn >= 0 && imn <= 59 ) { - if ( sec >= 0 ) { - if ( sec >= seclim ) { - js += 2; - } - } else { - js = -6; - } - } else { - js = -5; - } - } else { - js = -4; - } - if ( js < 0 ) return js; - -/* The time in days. */ - time = ( 60.0 * ( (double) ( 60 * ihr + imn ) ) + sec ) / day; - -/* Return the date and time. */ - *d1 = dj; - *d2 = time; - -/* Status. */ - return js; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/eceq06.c b/ast/erfa/eceq06.c deleted file mode 100644 index e1ba72d..0000000 --- a/ast/erfa/eceq06.c +++ /dev/null @@ -1,141 +0,0 @@ -#include "erfa.h" - -void eraEceq06(double date1, double date2, double dl, double db, - double *dr, double *dd) -/* -** - - - - - - - - - - -** e r a E c e q 0 6 -** - - - - - - - - - - -** -** Transformation from ecliptic coordinates (mean equinox and ecliptic -** of date) to ICRS RA,Dec, using the IAU 2006 precession model. -** -** Given: -** date1,date2 double TT as a 2-part Julian date (Note 1) -** dl,db double ecliptic longitude and latitude (radians) -** -** Returned: -** dr,dd double ICRS right ascension and declination (radians) -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) No assumptions are made about whether the coordinates represent -** starlight and embody astrometric effects such as parallax or -** aberration. -** -** 3) The transformation is approximately that from ecliptic longitude -** and latitude (mean equinox and ecliptic of date) to mean J2000.0 -** right ascension and declination, with only frame bias (always -** less than 25 mas) to disturb this classical picture. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraEcm06 J2000.0 to ecliptic rotation matrix, IAU 2006 -** eraTrxp product of transpose of r-matrix and p-vector -** eraC2s unit vector to spherical coordinates -** eraAnp normalize angle into range 0 to 2pi -** eraAnpm normalize angle into range +/- pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rm[3][3], v1[3], v2[3], a, b; - - -/* Spherical to Cartesian. */ - eraS2c(dl, db, v1); - -/* Rotation matrix, ICRS equatorial to ecliptic. */ - eraEcm06(date1, date2, rm); - -/* The transformation from ecliptic to ICRS. */ - eraTrxp(rm, v1, v2); - -/* Cartesian to spherical. */ - eraC2s(v2, &a, &b); - -/* Express in conventional ranges. */ - *dr = eraAnp(a); - *dd = eraAnpm(b); - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ecm06.c b/ast/erfa/ecm06.c deleted file mode 100644 index ce19ba2..0000000 --- a/ast/erfa/ecm06.c +++ /dev/null @@ -1,144 +0,0 @@ -#include "erfa.h" - -void eraEcm06(double date1, double date2, double rm[3][3]) -/* -** - - - - - - - - - -** e r a E c m 0 6 -** - - - - - - - - - -** -** ICRS equatorial to ecliptic rotation matrix, IAU 2006. -** -** Given: -** date1,date2 double TT as a 2-part Julian date (Note 1) -** -** Returned: -** rm double[3][3] ICRS to ecliptic rotation matrix -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 1) The matrix is in the sense -** -** E_ep = rm x P_ICRS, -** -** where P_ICRS is a vector with respect to ICRS right ascension -** and declination axes and E_ep is the same vector with respect to -** the (inertial) ecliptic and equinox of date. -** -** 2) P_ICRS is a free vector, merely a direction, typically of unit -** magnitude, and not bound to any particular spatial origin, such -** as the Earth, Sun or SSB. No assumptions are made about whether -** it represents starlight and embodies astrometric effects such as -** parallax or aberration. The transformation is approximately that -** between mean J2000.0 right ascension and declination and ecliptic -** longitude and latitude, with only frame bias (always less than -** 25 mas) to disturb this classical picture. -** -** Called: -** eraObl06 mean obliquity, IAU 2006 -** eraPmat06 PB matrix, IAU 2006 -** eraIr initialize r-matrix to identity -** eraRx rotate around X-axis -** eraRxr product of two r-matrices -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double ob, bp[3][3], e[3][3]; - - -/* Obliquity, IAU 2006. */ - ob = eraObl06(date1, date2); - -/* Precession-bias matrix, IAU 2006. */ - eraPmat06(date1, date2, bp); - -/* Equatorial of date to ecliptic matrix. */ - eraIr(e); - eraRx(ob, e); - -/* ICRS to ecliptic coordinates rotation matrix, IAU 2006. */ - eraRxr(e, bp, rm); - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ee00.c b/ast/erfa/ee00.c deleted file mode 100644 index de1b6b9..0000000 --- a/ast/erfa/ee00.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "erfa.h" - -double eraEe00(double date1, double date2, double epsa, double dpsi) -/* -** - - - - - - - - -** e r a E e 0 0 -** - - - - - - - - -** -** The equation of the equinoxes, compatible with IAU 2000 resolutions, -** given the nutation in longitude and the mean obliquity. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** epsa double mean obliquity (Note 2) -** dpsi double nutation in longitude (Note 3) -** -** Returned (function value): -** double equation of the equinoxes (Note 4) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The obliquity, in radians, is mean of date. -** -** 3) The result, which is in radians, operates in the following sense: -** -** Greenwich apparent ST = GMST + equation of the equinoxes -** -** 4) The result is compatible with the IAU 2000 resolutions. For -** further details, see IERS Conventions 2003 and Capitaine et al. -** (2002). -** -** Called: -** eraEect00 equation of the equinoxes complementary terms -** -** References: -** -** Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to -** implement the IAU 2000 definition of UT1", Astronomy & -** Astrophysics, 406, 1135-1149 (2003) -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double ee; - - -/* Equation of the equinoxes. */ - ee = dpsi * cos(epsa) + eraEect00(date1, date2); - - return ee; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ee00a.c b/ast/erfa/ee00a.c deleted file mode 100644 index 90eade7..0000000 --- a/ast/erfa/ee00a.c +++ /dev/null @@ -1,144 +0,0 @@ -#include "erfa.h" - -double eraEe00a(double date1, double date2) -/* -** - - - - - - - - - -** e r a E e 0 0 a -** - - - - - - - - - -** -** Equation of the equinoxes, compatible with IAU 2000 resolutions. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double equation of the equinoxes (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The result, which is in radians, operates in the following sense: -** -** Greenwich apparent ST = GMST + equation of the equinoxes -** -** 3) The result is compatible with the IAU 2000 resolutions. For -** further details, see IERS Conventions 2003 and Capitaine et al. -** (2002). -** -** Called: -** eraPr00 IAU 2000 precession adjustments -** eraObl80 mean obliquity, IAU 1980 -** eraNut00a nutation, IAU 2000A -** eraEe00 equation of the equinoxes, IAU 2000 -** -** References: -** -** Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to -** implement the IAU 2000 definition of UT1", Astronomy & -** Astrophysics, 406, 1135-1149 (2003). -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dpsipr, depspr, epsa, dpsi, deps, ee; - - -/* IAU 2000 precession-rate adjustments. */ - eraPr00(date1, date2, &dpsipr, &depspr); - -/* Mean obliquity, consistent with IAU 2000 precession-nutation. */ - epsa = eraObl80(date1, date2) + depspr; - -/* Nutation in longitude. */ - eraNut00a(date1, date2, &dpsi, &deps); - -/* Equation of the equinoxes. */ - ee = eraEe00(date1, date2, epsa, dpsi); - - return ee; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ee00b.c b/ast/erfa/ee00b.c deleted file mode 100644 index 2bed962..0000000 --- a/ast/erfa/ee00b.c +++ /dev/null @@ -1,150 +0,0 @@ -#include "erfa.h" - -double eraEe00b(double date1, double date2) -/* -** - - - - - - - - - -** e r a E e 0 0 b -** - - - - - - - - - -** -** Equation of the equinoxes, compatible with IAU 2000 resolutions but -** using the truncated nutation model IAU 2000B. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double equation of the equinoxes (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The result, which is in radians, operates in the following sense: -** -** Greenwich apparent ST = GMST + equation of the equinoxes -** -** 3) The result is compatible with the IAU 2000 resolutions except -** that accuracy has been compromised for the sake of speed. For -** further details, see McCarthy & Luzum (2001), IERS Conventions -** 2003 and Capitaine et al. (2003). -** -** Called: -** eraPr00 IAU 2000 precession adjustments -** eraObl80 mean obliquity, IAU 1980 -** eraNut00b nutation, IAU 2000B -** eraEe00 equation of the equinoxes, IAU 2000 -** -** References: -** -** Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to -** implement the IAU 2000 definition of UT1", Astronomy & -** Astrophysics, 406, 1135-1149 (2003) -** -** McCarthy, D.D. & Luzum, B.J., "An abridged model of the -** precession-nutation of the celestial pole", Celestial Mechanics & -** Dynamical Astronomy, 85, 37-49 (2003) -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dpsipr, depspr, epsa, dpsi, deps, ee; - - -/* IAU 2000 precession-rate adjustments. */ - eraPr00(date1, date2, &dpsipr, &depspr); - -/* Mean obliquity, consistent with IAU 2000 precession-nutation. */ - epsa = eraObl80(date1, date2) + depspr; - -/* Nutation in longitude. */ - eraNut00b(date1, date2, &dpsi, &deps); - -/* Equation of the equinoxes. */ - ee = eraEe00(date1, date2, epsa, dpsi); - - return ee; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ee06a.c b/ast/erfa/ee06a.c deleted file mode 100644 index c64a65f..0000000 --- a/ast/erfa/ee06a.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "erfa.h" - -double eraEe06a(double date1, double date2) -/* -** - - - - - - - - - -** e r a E e 0 6 a -** - - - - - - - - - -** -** Equation of the equinoxes, compatible with IAU 2000 resolutions and -** IAU 2006/2000A precession-nutation. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double equation of the equinoxes (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The result, which is in radians, operates in the following sense: -** -** Greenwich apparent ST = GMST + equation of the equinoxes -** -** Called: -** eraAnpm normalize angle into range +/- pi -** eraGst06a Greenwich apparent sidereal time, IAU 2006/2000A -** eraGmst06 Greenwich mean sidereal time, IAU 2006 -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003), -** IERS Technical Note No. 32, BKG -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double gst06a, gmst06, ee; - - -/* Apparent and mean sidereal times. */ - gst06a = eraGst06a(0.0, 0.0, date1, date2); - gmst06 = eraGmst06(0.0, 0.0, date1, date2); - -/* Equation of the equinoxes. */ - ee = eraAnpm(gst06a - gmst06); - - return ee; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/eect00.c b/ast/erfa/eect00.c deleted file mode 100644 index b8e4bf3..0000000 --- a/ast/erfa/eect00.c +++ /dev/null @@ -1,291 +0,0 @@ -#include "erfa.h" - -double eraEect00(double date1, double date2) -/* -** - - - - - - - - - - -** e r a E e c t 0 0 -** - - - - - - - - - - -** -** Equation of the equinoxes complementary terms, consistent with -** IAU 2000 resolutions. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double complementary terms (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The "complementary terms" are part of the equation of the -** equinoxes (EE), classically the difference between apparent and -** mean Sidereal Time: -** -** GAST = GMST + EE -** -** with: -** -** EE = dpsi * cos(eps) -** -** where dpsi is the nutation in longitude and eps is the obliquity -** of date. However, if the rotation of the Earth were constant in -** an inertial frame the classical formulation would lead to -** apparent irregularities in the UT1 timescale traceable to side- -** effects of precession-nutation. In order to eliminate these -** effects from UT1, "complementary terms" were introduced in 1994 -** (IAU, 1994) and took effect from 1997 (Capitaine and Gontier, -** 1993): -** -** GAST = GMST + CT + EE -** -** By convention, the complementary terms are included as part of -** the equation of the equinoxes rather than as part of the mean -** Sidereal Time. This slightly compromises the "geometrical" -** interpretation of mean sidereal time but is otherwise -** inconsequential. -** -** The present function computes CT in the above expression, -** compatible with IAU 2000 resolutions (Capitaine et al., 2002, and -** IERS Conventions 2003). -** -** Called: -** eraFal03 mean anomaly of the Moon -** eraFalp03 mean anomaly of the Sun -** eraFaf03 mean argument of the latitude of the Moon -** eraFad03 mean elongation of the Moon from the Sun -** eraFaom03 mean longitude of the Moon's ascending node -** eraFave03 mean longitude of Venus -** eraFae03 mean longitude of Earth -** eraFapa03 general accumulated precession in longitude -** -** References: -** -** Capitaine, N. & Gontier, A.-M., Astron. Astrophys., 275, -** 645-650 (1993) -** -** Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to -** implement the IAU 2000 definition of UT1", Astronomy & -** Astrophysics, 406, 1135-1149 (2003) -** -** IAU Resolution C7, Recommendation 3 (1994) -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Time since J2000.0, in Julian centuries */ - double t; - -/* Miscellaneous */ - int i, j; - double a, s0, s1; - -/* Fundamental arguments */ - double fa[14]; - -/* Returned value. */ - double eect; - -/* ----------------------------------------- */ -/* The series for the EE complementary terms */ -/* ----------------------------------------- */ - - typedef struct { - int nfa[8]; /* coefficients of l,l',F,D,Om,LVe,LE,pA */ - double s, c; /* sine and cosine coefficients */ - } TERM; - -/* Terms of order t^0 */ - static const TERM e0[] = { - - /* 1-10 */ - {{ 0, 0, 0, 0, 1, 0, 0, 0}, 2640.96e-6, -0.39e-6 }, - {{ 0, 0, 0, 0, 2, 0, 0, 0}, 63.52e-6, -0.02e-6 }, - {{ 0, 0, 2, -2, 3, 0, 0, 0}, 11.75e-6, 0.01e-6 }, - {{ 0, 0, 2, -2, 1, 0, 0, 0}, 11.21e-6, 0.01e-6 }, - {{ 0, 0, 2, -2, 2, 0, 0, 0}, -4.55e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 3, 0, 0, 0}, 2.02e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 1, 0, 0, 0}, 1.98e-6, 0.00e-6 }, - {{ 0, 0, 0, 0, 3, 0, 0, 0}, -1.72e-6, 0.00e-6 }, - {{ 0, 1, 0, 0, 1, 0, 0, 0}, -1.41e-6, -0.01e-6 }, - {{ 0, 1, 0, 0, -1, 0, 0, 0}, -1.26e-6, -0.01e-6 }, - - /* 11-20 */ - {{ 1, 0, 0, 0, -1, 0, 0, 0}, -0.63e-6, 0.00e-6 }, - {{ 1, 0, 0, 0, 1, 0, 0, 0}, -0.63e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 3, 0, 0, 0}, 0.46e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 1, 0, 0, 0}, 0.45e-6, 0.00e-6 }, - {{ 0, 0, 4, -4, 4, 0, 0, 0}, 0.36e-6, 0.00e-6 }, - {{ 0, 0, 1, -1, 1, -8, 12, 0}, -0.24e-6, -0.12e-6 }, - {{ 0, 0, 2, 0, 0, 0, 0, 0}, 0.32e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 2, 0, 0, 0}, 0.28e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 3, 0, 0, 0}, 0.27e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 1, 0, 0, 0}, 0.26e-6, 0.00e-6 }, - - /* 21-30 */ - {{ 0, 0, 2, -2, 0, 0, 0, 0}, -0.21e-6, 0.00e-6 }, - {{ 0, 1, -2, 2, -3, 0, 0, 0}, 0.19e-6, 0.00e-6 }, - {{ 0, 1, -2, 2, -1, 0, 0, 0}, 0.18e-6, 0.00e-6 }, - {{ 0, 0, 0, 0, 0, 8,-13, -1}, -0.10e-6, 0.05e-6 }, - {{ 0, 0, 0, 2, 0, 0, 0, 0}, 0.15e-6, 0.00e-6 }, - {{ 2, 0, -2, 0, -1, 0, 0, 0}, -0.14e-6, 0.00e-6 }, - {{ 1, 0, 0, -2, 1, 0, 0, 0}, 0.14e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 2, 0, 0, 0}, -0.14e-6, 0.00e-6 }, - {{ 1, 0, 0, -2, -1, 0, 0, 0}, 0.14e-6, 0.00e-6 }, - {{ 0, 0, 4, -2, 4, 0, 0, 0}, 0.13e-6, 0.00e-6 }, - - /* 31-33 */ - {{ 0, 0, 2, -2, 4, 0, 0, 0}, -0.11e-6, 0.00e-6 }, - {{ 1, 0, -2, 0, -3, 0, 0, 0}, 0.11e-6, 0.00e-6 }, - {{ 1, 0, -2, 0, -1, 0, 0, 0}, 0.11e-6, 0.00e-6 } - }; - -/* Terms of order t^1 */ - static const TERM e1[] = { - {{ 0, 0, 0, 0, 1, 0, 0, 0}, -0.87e-6, 0.00e-6 } - }; - -/* Number of terms in the series */ - const int NE0 = (int) (sizeof e0 / sizeof (TERM)); - const int NE1 = (int) (sizeof e1 / sizeof (TERM)); - -/*--------------------------------------------------------------------*/ - -/* Interval between fundamental epoch J2000.0 and current date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Fundamental Arguments (from IERS Conventions 2003) */ - -/* Mean anomaly of the Moon. */ - fa[0] = eraFal03(t); - -/* Mean anomaly of the Sun. */ - fa[1] = eraFalp03(t); - -/* Mean longitude of the Moon minus that of the ascending node. */ - fa[2] = eraFaf03(t); - -/* Mean elongation of the Moon from the Sun. */ - fa[3] = eraFad03(t); - -/* Mean longitude of the ascending node of the Moon. */ - fa[4] = eraFaom03(t); - -/* Mean longitude of Venus. */ - fa[5] = eraFave03(t); - -/* Mean longitude of Earth. */ - fa[6] = eraFae03(t); - -/* General precession in longitude. */ - fa[7] = eraFapa03(t); - -/* Evaluate the EE complementary terms. */ - s0 = 0.0; - s1 = 0.0; - - for (i = NE0-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)(e0[i].nfa[j]) * fa[j]; - } - s0 += e0[i].s * sin(a) + e0[i].c * cos(a); - } - - for (i = NE1-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)(e1[i].nfa[j]) * fa[j]; - } - s1 += e1[i].s * sin(a) + e1[i].c * cos(a); - } - - eect = (s0 + s1 * t ) * ERFA_DAS2R; - - return eect; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/eform.c b/ast/erfa/eform.c deleted file mode 100644 index 0982ab4..0000000 --- a/ast/erfa/eform.c +++ /dev/null @@ -1,155 +0,0 @@ -#include "erfa.h" - -int eraEform ( int n, double *a, double *f ) -/* -** - - - - - - - - - -** e r a E f o r m -** - - - - - - - - - -** -** Earth reference ellipsoids. -** -** Given: -** n int ellipsoid identifier (Note 1) -** -** Returned: -** a double equatorial radius (meters, Note 2) -** f double flattening (Note 2) -** -** Returned (function value): -** int status: 0 = OK -** -1 = illegal identifier (Note 3) -** -** Notes: -** -** 1) The identifier n is a number that specifies the choice of -** reference ellipsoid. The following are supported: -** -** n ellipsoid -** -** 1 ERFA_WGS84 -** 2 ERFA_GRS80 -** 3 ERFA_WGS72 -** -** The n value has no significance outside the ERFA software. For -** convenience, symbols ERFA_WGS84 etc. are defined in erfam.h. -** -** 2) The ellipsoid parameters are returned in the form of equatorial -** radius in meters (a) and flattening (f). The latter is a number -** around 0.00335, i.e. around 1/298. -** -** 3) For the case where an unsupported n value is supplied, zero a and -** f are returned, as well as error status. -** -** References: -** -** Department of Defense World Geodetic System 1984, National -** Imagery and Mapping Agency Technical Report 8350.2, Third -** Edition, p3-2. -** -** Moritz, H., Bull. Geodesique 66-2, 187 (1992). -** -** The Department of Defense World Geodetic System 1972, World -** Geodetic System Committee, May 1974. -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** p220. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* Look up a and f for the specified reference ellipsoid. */ - switch ( n ) { - - case ERFA_WGS84: - *a = 6378137.0; - *f = 1.0 / 298.257223563; - break; - - case ERFA_GRS80: - *a = 6378137.0; - *f = 1.0 / 298.257222101; - break; - - case ERFA_WGS72: - *a = 6378135.0; - *f = 1.0 / 298.26; - break; - - default: - - /* Invalid identifier. */ - *a = 0.0; - *f = 0.0; - return -1; - - } - -/* OK status. */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/eo06a.c b/ast/erfa/eo06a.c deleted file mode 100644 index 6fd27c9..0000000 --- a/ast/erfa/eo06a.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "erfa.h" - -double eraEo06a(double date1, double date2) -/* -** - - - - - - - - - -** e r a E o 0 6 a -** - - - - - - - - - -** -** Equation of the origins, IAU 2006 precession and IAU 2000A nutation. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double equation of the origins in radians -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The equation of the origins is the distance between the true -** equinox and the celestial intermediate origin and, equivalently, -** the difference between Earth rotation angle and Greenwich -** apparent sidereal time (ERA-GST). It comprises the precession -** (since J2000.0) in right ascension plus the equation of the -** equinoxes (including the small correction terms). -** -** Called: -** eraPnm06a classical NPB matrix, IAU 2006/2000A -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraS06 the CIO locator s, given X,Y, IAU 2006 -** eraEors equation of the origins, given NPB matrix and s -** -** References: -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855 -** -** Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double r[3][3], x, y, s, eo; - - -/* Classical nutation x precession x bias matrix. */ - eraPnm06a(date1, date2, r); - -/* Extract CIP coordinates. */ - eraBpn2xy(r, &x, &y); - -/* The CIO locator, s. */ - s = eraS06(date1, date2, x, y); - -/* Solve for the EO. */ - eo = eraEors(r, s); - - return eo; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/eors.c b/ast/erfa/eors.c deleted file mode 100644 index c1b5557..0000000 --- a/ast/erfa/eors.c +++ /dev/null @@ -1,117 +0,0 @@ -#include "erfa.h" - -double eraEors(double rnpb[3][3], double s) -/* -** - - - - - - - - -** e r a E o r s -** - - - - - - - - -** -** Equation of the origins, given the classical NPB matrix and the -** quantity s. -** -** Given: -** rnpb double[3][3] classical nutation x precession x bias matrix -** s double the quantity s (the CIO locator) -** -** Returned (function value): -** double the equation of the origins in radians. -** -** Notes: -** -** 1) The equation of the origins is the distance between the true -** equinox and the celestial intermediate origin and, equivalently, -** the difference between Earth rotation angle and Greenwich -** apparent sidereal time (ERA-GST). It comprises the precession -** (since J2000.0) in right ascension plus the equation of the -** equinoxes (including the small correction terms). -** -** 2) The algorithm is from Wallace & Capitaine (2006). -** -** References: -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855 -** -** Wallace, P. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double x, ax, xs, ys, zs, p, q, eo; - - -/* Evaluate Wallace & Capitaine (2006) expression (16). */ - x = rnpb[2][0]; - ax = x / (1.0 + rnpb[2][2]); - xs = 1.0 - ax * x; - ys = -ax * rnpb[2][1]; - zs = -x; - p = rnpb[0][0] * xs + rnpb[0][1] * ys + rnpb[0][2] * zs; - q = rnpb[1][0] * xs + rnpb[1][1] * ys + rnpb[1][2] * zs; - eo = ((p != 0) || (q != 0)) ? s - atan2(q, p) : s; - - return eo; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/epb.c b/ast/erfa/epb.c deleted file mode 100644 index 3d06508..0000000 --- a/ast/erfa/epb.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "erfa.h" - -double eraEpb(double dj1, double dj2) -/* -** - - - - - - - -** e r a E p b -** - - - - - - - -** -** Julian Date to Besselian Epoch. -** -** Given: -** dj1,dj2 double Julian Date (see note) -** -** Returned (function value): -** double Besselian Epoch. -** -** Note: -** -** The Julian Date is supplied in two pieces, in the usual ERFA -** manner, which is designed to preserve time resolution. The -** Julian Date is available as a single number by adding dj1 and -** dj2. The maximum resolution is achieved if dj1 is 2451545.0 -** (J2000.0). -** -** Reference: -** -** Lieske, J.H., 1979. Astron.Astrophys., 73, 282. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* J2000.0-B1900.0 (2415019.81352) in days */ - const double D1900 = 36524.68648; - - return 1900.0 + ((dj1 - ERFA_DJ00) + (dj2 + D1900)) / ERFA_DTY; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/epb2jd.c b/ast/erfa/epb2jd.c deleted file mode 100644 index 4dca8c9..0000000 --- a/ast/erfa/epb2jd.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "erfa.h" - -void eraEpb2jd(double epb, double *djm0, double *djm) -/* -** - - - - - - - - - - -** e r a E p b 2 j d -** - - - - - - - - - - -** -** Besselian Epoch to Julian Date. -** -** Given: -** epb double Besselian Epoch (e.g. 1957.3) -** -** Returned: -** djm0 double MJD zero-point: always 2400000.5 -** djm double Modified Julian Date -** -** Note: -** -** The Julian Date is returned in two pieces, in the usual ERFA -** manner, which is designed to preserve time resolution. The -** Julian Date is available as a single number by adding djm0 and -** djm. -** -** Reference: -** -** Lieske, J.H., 1979, Astron.Astrophys. 73, 282. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - *djm0 = ERFA_DJM0; - *djm = 15019.81352 + (epb - 1900.0) * ERFA_DTY; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/epj.c b/ast/erfa/epj.c deleted file mode 100644 index 059853d..0000000 --- a/ast/erfa/epj.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "erfa.h" - -double eraEpj(double dj1, double dj2) -/* -** - - - - - - - -** e r a E p j -** - - - - - - - -** -** Julian Date to Julian Epoch. -** -** Given: -** dj1,dj2 double Julian Date (see note) -** -** Returned (function value): -** double Julian Epoch -** -** Note: -** -** The Julian Date is supplied in two pieces, in the usual ERFA -** manner, which is designed to preserve time resolution. The -** Julian Date is available as a single number by adding dj1 and -** dj2. The maximum resolution is achieved if dj1 is 2451545.0 -** (J2000.0). -** -** Reference: -** -** Lieske, J.H., 1979, Astron.Astrophys. 73, 282. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double epj; - - - epj = 2000.0 + ((dj1 - ERFA_DJ00) + dj2) / ERFA_DJY; - - return epj; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/epj2jd.c b/ast/erfa/epj2jd.c deleted file mode 100644 index 751eb15..0000000 --- a/ast/erfa/epj2jd.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "erfa.h" - -void eraEpj2jd(double epj, double *djm0, double *djm) -/* -** - - - - - - - - - - -** e r a E p j 2 j d -** - - - - - - - - - - -** -** Julian Epoch to Julian Date. -** -** Given: -** epj double Julian Epoch (e.g. 1996.8) -** -** Returned: -** djm0 double MJD zero-point: always 2400000.5 -** djm double Modified Julian Date -** -** Note: -** -** The Julian Date is returned in two pieces, in the usual ERFA -** manner, which is designed to preserve time resolution. The -** Julian Date is available as a single number by adding djm0 and -** djm. -** -** Reference: -** -** Lieske, J.H., 1979, Astron.Astrophys. 73, 282. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - *djm0 = ERFA_DJM0; - *djm = ERFA_DJM00 + (epj - 2000.0) * 365.25; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/epv00.c b/ast/erfa/epv00.c deleted file mode 100644 index 4f37b9c..0000000 --- a/ast/erfa/epv00.c +++ /dev/null @@ -1,2598 +0,0 @@ -#include "erfa.h" - -int eraEpv00(double date1, double date2, - double pvh[2][3], double pvb[2][3]) -/* -** - - - - - - - - - -** e r a E p v 0 0 -** - - - - - - - - - -** -** Earth position and velocity, heliocentric and barycentric, with -** respect to the Barycentric Celestial Reference System. -** -** Given: -** date1,date2 double TDB date (Note 1) -** -** Returned: -** pvh double[2][3] heliocentric Earth position/velocity -** pvb double[2][3] barycentric Earth position/velocity -** -** Returned (function value): -** int status: 0 = OK -** +1 = warning: date outside -** the range 1900-2100 AD -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, among -** others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. However, -** the accuracy of the result is more likely to be limited by the -** algorithm itself than the way the date has been expressed. -** -** n.b. TT can be used instead of TDB in most applications. -** -** 2) On return, the arrays pvh and pvb contain the following: -** -** pvh[0][0] x } -** pvh[0][1] y } heliocentric position, AU -** pvh[0][2] z } -** -** pvh[1][0] xdot } -** pvh[1][1] ydot } heliocentric velocity, AU/d -** pvh[1][2] zdot } -** -** pvb[0][0] x } -** pvb[0][1] y } barycentric position, AU -** pvb[0][2] z } -** -** pvb[1][0] xdot } -** pvb[1][1] ydot } barycentric velocity, AU/d -** pvb[1][2] zdot } -** -** The vectors are with respect to the Barycentric Celestial -** Reference System. The time unit is one day in TDB. -** -** 3) The function is a SIMPLIFIED SOLUTION from the planetary theory -** VSOP2000 (X. Moisson, P. Bretagnon, 2001, Celes. Mechanics & -** Dyn. Astron., 80, 3/4, 205-213) and is an adaptation of original -** Fortran code supplied by P. Bretagnon (private comm., 2000). -** -** 4) Comparisons over the time span 1900-2100 with this simplified -** solution and the JPL DE405 ephemeris give the following results: -** -** RMS max -** Heliocentric: -** position error 3.7 11.2 km -** velocity error 1.4 5.0 mm/s -** -** Barycentric: -** position error 4.6 13.4 km -** velocity error 1.4 4.9 mm/s -** -** Comparisons with the JPL DE406 ephemeris show that by 1800 and -** 2200 the position errors are approximately double their 1900-2100 -** size. By 1500 and 2500 the deterioration is a factor of 10 and -** by 1000 and 3000 a factor of 60. The velocity accuracy falls off -** at about half that rate. -** -** 5) It is permissible to use the same array for pvh and pvb, which -** will receive the barycentric values. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* -** Matrix elements for orienting the analytical model to DE405. -** -** The corresponding Euler angles are: -** -** d ' " -** 1st rotation - 23 26 21.4091 about the x-axis (obliquity) -** 2nd rotation + 0.0475 about the z-axis (RA offset) -** -** These were obtained empirically, by comparisons with DE405 over -** 1900-2100. -*/ - static const double am12 = 0.000000211284, - am13 = -0.000000091603, - am21 = -0.000000230286, - am22 = 0.917482137087, - am23 = -0.397776982902, - am32 = 0.397776982902, - am33 = 0.917482137087; - -/* -** ---------------------- -** Ephemeris Coefficients -** ---------------------- -** -** The ephemeris consists of harmonic terms for predicting (i) the Sun -** to Earth vector and (ii) the Solar-System-barycenter to Sun vector -** respectively. The coefficients are stored in arrays which, although -** 1-demensional, contain groups of three. Each triplet of -** coefficients is the amplitude, phase and frequency for one term in -** the model, and each array contains the number of terms called for by -** the model. -** -** There are eighteen such arrays, named as follows: -** -** array model power of T component -** -** e0x Sun-to-Earth 0 x -** e0y Sun-to-Earth 0 y -** e0z Sun-to-Earth 0 z -** -** e1x Sun-to-Earth 1 x -** e1y Sun-to-Earth 1 y -** e1z Sun-to-Earth 1 z -** -** e2x Sun-to-Earth 2 x -** e2y Sun-to-Earth 2 y -** e2z Sun-to-Earth 2 z -** -** s0x SSB-to-Sun 0 x -** s0y SSB-to-Sun 0 y -** s0z SSB-to-Sun 0 z -** -** s1x SSB-to-Sun 1 x -** s1y SSB-to-Sun 1 y -** s1z SSB-to-Sun 1 z -** -** s2x SSB-to-Sun 2 x -** s2y SSB-to-Sun 2 y -** s2z SSB-to-Sun 2 z -*/ - -/* Sun-to-Earth, T^0, X */ - static const double e0x[] = { - 0.9998292878132e+00, 0.1753485171504e+01, 0.6283075850446e+01, - 0.8352579567414e-02, 0.1710344404582e+01, 0.1256615170089e+02, - 0.5611445335148e-02, 0.0000000000000e+00, 0.0000000000000e+00, - 0.1046664295572e-03, 0.1667225416770e+01, 0.1884922755134e+02, - 0.3110842534677e-04, 0.6687513390251e+00, 0.8399684731857e+02, - 0.2552413503550e-04, 0.5830637358413e+00, 0.5296909721118e+00, - 0.2137207845781e-04, 0.1092330954011e+01, 0.1577343543434e+01, - 0.1680240182951e-04, 0.4955366134987e+00, 0.6279552690824e+01, - 0.1679012370795e-04, 0.6153014091901e+01, 0.6286599010068e+01, - 0.1445526946777e-04, 0.3472744100492e+01, 0.2352866153506e+01, - - 0.1091038246184e-04, 0.3689845786119e+01, 0.5223693906222e+01, - 0.9344399733932e-05, 0.6073934645672e+01, 0.1203646072878e+02, - 0.8993182910652e-05, 0.3175705249069e+01, 0.1021328554739e+02, - 0.5665546034116e-05, 0.2152484672246e+01, 0.1059381944224e+01, - 0.6844146703035e-05, 0.1306964099750e+01, 0.5753384878334e+01, - 0.7346610905565e-05, 0.4354980070466e+01, 0.3981490189893e+00, - 0.6815396474414e-05, 0.2218229211267e+01, 0.4705732307012e+01, - 0.6112787253053e-05, 0.5384788425458e+01, 0.6812766822558e+01, - 0.4518120711239e-05, 0.6087604012291e+01, 0.5884926831456e+01, - 0.4521963430706e-05, 0.1279424524906e+01, 0.6256777527156e+01, - - 0.4497426764085e-05, 0.5369129144266e+01, 0.6309374173736e+01, - 0.4062190566959e-05, 0.5436473303367e+00, 0.6681224869435e+01, - 0.5412193480192e-05, 0.7867838528395e+00, 0.7755226100720e+00, - 0.5469839049386e-05, 0.1461440311134e+01, 0.1414349524433e+02, - 0.5205264083477e-05, 0.4432944696116e+01, 0.7860419393880e+01, - 0.2149759935455e-05, 0.4502237496846e+01, 0.1150676975667e+02, - 0.2279109618501e-05, 0.1239441308815e+01, 0.7058598460518e+01, - 0.2259282939683e-05, 0.3272430985331e+01, 0.4694002934110e+01, - 0.2558950271319e-05, 0.2265471086404e+01, 0.1216800268190e+02, - 0.2561581447555e-05, 0.1454740653245e+01, 0.7099330490126e+00, - - 0.1781441115440e-05, 0.2962068630206e+01, 0.7962980379786e+00, - 0.1612005874644e-05, 0.1473255041006e+01, 0.5486777812467e+01, - 0.1818630667105e-05, 0.3743903293447e+00, 0.6283008715021e+01, - 0.1818601377529e-05, 0.6274174354554e+01, 0.6283142985870e+01, - 0.1554475925257e-05, 0.1624110906816e+01, 0.2513230340178e+02, - 0.2090948029241e-05, 0.5852052276256e+01, 0.1179062909082e+02, - 0.2000176345460e-05, 0.4072093298513e+01, 0.1778984560711e+02, - 0.1289535917759e-05, 0.5217019331069e+01, 0.7079373888424e+01, - 0.1281135307881e-05, 0.4802054538934e+01, 0.3738761453707e+01, - 0.1518229005692e-05, 0.8691914742502e+00, 0.2132990797783e+00, - - 0.9450128579027e-06, 0.4601859529950e+01, 0.1097707878456e+02, - 0.7781119494996e-06, 0.1844352816694e+01, 0.8827390247185e+01, - 0.7733407759912e-06, 0.3582790154750e+01, 0.5507553240374e+01, - 0.7350644318120e-06, 0.2695277788230e+01, 0.1589072916335e+01, - 0.6535928827023e-06, 0.3651327986142e+01, 0.1176985366291e+02, - 0.6324624183656e-06, 0.2241302375862e+01, 0.6262300422539e+01, - 0.6298565300557e-06, 0.4407122406081e+01, 0.6303851278352e+01, - 0.8587037089179e-06, 0.3024307223119e+01, 0.1672837615881e+03, - 0.8299954491035e-06, 0.6192539428237e+01, 0.3340612434717e+01, - 0.6311263503401e-06, 0.2014758795416e+01, 0.7113454667900e-02, - - 0.6005646745452e-06, 0.3399500503397e+01, 0.4136910472696e+01, - 0.7917715109929e-06, 0.2493386877837e+01, 0.6069776770667e+01, - 0.7556958099685e-06, 0.4159491740143e+01, 0.6496374930224e+01, - 0.6773228244949e-06, 0.4034162934230e+01, 0.9437762937313e+01, - 0.5370708577847e-06, 0.1562219163734e+01, 0.1194447056968e+01, - 0.5710804266203e-06, 0.2662730803386e+01, 0.6282095334605e+01, - 0.5709824583726e-06, 0.3985828430833e+01, 0.6284056366286e+01, - 0.5143950896447e-06, 0.1308144688689e+01, 0.6290189305114e+01, - 0.5088010604546e-06, 0.5352817214804e+01, 0.6275962395778e+01, - 0.4960369085172e-06, 0.2644267922349e+01, 0.6127655567643e+01, - - 0.4803137891183e-06, 0.4008844192080e+01, 0.6438496133249e+01, - 0.5731747768225e-06, 0.3794550174597e+01, 0.3154687086868e+01, - 0.4735947960579e-06, 0.6107118308982e+01, 0.3128388763578e+01, - 0.4808348796625e-06, 0.4771458618163e+01, 0.8018209333619e+00, - 0.4115073743137e-06, 0.3327111335159e+01, 0.8429241228195e+01, - 0.5230575889287e-06, 0.5305708551694e+01, 0.1336797263425e+02, - 0.5133977889215e-06, 0.5784230738814e+01, 0.1235285262111e+02, - 0.5065815825327e-06, 0.2052064793679e+01, 0.1185621865188e+02, - 0.4339831593868e-06, 0.3644994195830e+01, 0.1726015463500e+02, - 0.3952928638953e-06, 0.4930376436758e+01, 0.5481254917084e+01, - - 0.4898498111942e-06, 0.4542084219731e+00, 0.9225539266174e+01, - 0.4757490209328e-06, 0.3161126388878e+01, 0.5856477690889e+01, - 0.4727701669749e-06, 0.6214993845446e+00, 0.2544314396739e+01, - 0.3800966681863e-06, 0.3040132339297e+01, 0.4265981595566e+00, - 0.3257301077939e-06, 0.8064977360087e+00, 0.3930209696940e+01, - 0.3255810528674e-06, 0.1974147981034e+01, 0.2146165377750e+01, - 0.3252029748187e-06, 0.2845924913135e+01, 0.4164311961999e+01, - 0.3255505635308e-06, 0.3017900824120e+01, 0.5088628793478e+01, - 0.2801345211990e-06, 0.6109717793179e+01, 0.1256967486051e+02, - 0.3688987740970e-06, 0.2911550235289e+01, 0.1807370494127e+02, - - 0.2475153429458e-06, 0.2179146025856e+01, 0.2629832328990e-01, - 0.3033457749150e-06, 0.1994161050744e+01, 0.4535059491685e+01, - 0.2186743763110e-06, 0.5125687237936e+01, 0.1137170464392e+02, - 0.2764777032774e-06, 0.4822646860252e+00, 0.1256262854127e+02, - 0.2199028768592e-06, 0.4637633293831e+01, 0.1255903824622e+02, - 0.2046482824760e-06, 0.1467038733093e+01, 0.7084896783808e+01, - 0.2611209147507e-06, 0.3044718783485e+00, 0.7143069561767e+02, - 0.2286079656818e-06, 0.4764220356805e+01, 0.8031092209206e+01, - 0.1855071202587e-06, 0.3383637774428e+01, 0.1748016358760e+01, - 0.2324669506784e-06, 0.6189088449251e+01, 0.1831953657923e+02, - - 0.1709528015688e-06, 0.5874966729774e+00, 0.4933208510675e+01, - 0.2168156875828e-06, 0.4302994009132e+01, 0.1044738781244e+02, - 0.2106675556535e-06, 0.3800475419891e+01, 0.7477522907414e+01, - 0.1430213830465e-06, 0.1294660846502e+01, 0.2942463415728e+01, - 0.1388396901944e-06, 0.4594797202114e+01, 0.8635942003952e+01, - 0.1922258844190e-06, 0.4943044543591e+00, 0.1729818233119e+02, - 0.1888460058292e-06, 0.2426943912028e+01, 0.1561374759853e+03, - 0.1789449386107e-06, 0.1582973303499e+00, 0.1592596075957e+01, - 0.1360803685374e-06, 0.5197240440504e+01, 0.1309584267300e+02, - 0.1504038014709e-06, 0.3120360916217e+01, 0.1649636139783e+02, - - 0.1382769533389e-06, 0.6164702888205e+01, 0.7632943190217e+01, - 0.1438059769079e-06, 0.1437423770979e+01, 0.2042657109477e+02, - 0.1326303260037e-06, 0.3609688799679e+01, 0.1213955354133e+02, - 0.1159244950540e-06, 0.5463018167225e+01, 0.5331357529664e+01, - 0.1433118149136e-06, 0.6028909912097e+01, 0.7342457794669e+01, - 0.1234623148594e-06, 0.3109645574997e+01, 0.6279485555400e+01, - 0.1233949875344e-06, 0.3539359332866e+01, 0.6286666145492e+01, - 0.9927196061299e-07, 0.1259321569772e+01, 0.7234794171227e+01, - 0.1242302191316e-06, 0.1065949392609e+01, 0.1511046609763e+02, - 0.1098402195201e-06, 0.2192508743837e+01, 0.1098880815746e+02, - - 0.1158191395315e-06, 0.4054411278650e+01, 0.5729506548653e+01, - 0.9048475596241e-07, 0.5429764748518e+01, 0.9623688285163e+01, - 0.8889853269023e-07, 0.5046586206575e+01, 0.6148010737701e+01, - 0.1048694242164e-06, 0.2628858030806e+01, 0.6836645152238e+01, - 0.1112308378646e-06, 0.4177292719907e+01, 0.1572083878776e+02, - 0.8631729709901e-07, 0.1601345232557e+01, 0.6418140963190e+01, - 0.8527816951664e-07, 0.2463888997513e+01, 0.1471231707864e+02, - 0.7892139456991e-07, 0.3154022088718e+01, 0.2118763888447e+01, - 0.1051782905236e-06, 0.4795035816088e+01, 0.1349867339771e+01, - 0.1048219943164e-06, 0.2952983395230e+01, 0.5999216516294e+01, - - 0.7435760775143e-07, 0.5420547991464e+01, 0.6040347114260e+01, - 0.9869574106949e-07, 0.3695646753667e+01, 0.6566935184597e+01, - 0.9156886364226e-07, 0.3922675306609e+01, 0.5643178611111e+01, - 0.7006834356188e-07, 0.1233968624861e+01, 0.6525804586632e+01, - 0.9806170182601e-07, 0.1919542280684e+01, 0.2122839202813e+02, - 0.9052289673607e-07, 0.4615902724369e+01, 0.4690479774488e+01, - 0.7554200867893e-07, 0.1236863719072e+01, 0.1253985337760e+02, - 0.8215741286498e-07, 0.3286800101559e+00, 0.1097355562493e+02, - 0.7185178575397e-07, 0.5880942158367e+01, 0.6245048154254e+01, - 0.7130726476180e-07, 0.7674871987661e+00, 0.6321103546637e+01, - - 0.6650894461162e-07, 0.6987129150116e+00, 0.5327476111629e+01, - 0.7396888823688e-07, 0.3576824794443e+01, 0.5368044267797e+00, - 0.7420588884775e-07, 0.5033615245369e+01, 0.2354323048545e+02, - 0.6141181642908e-07, 0.9449927045673e+00, 0.1296430071988e+02, - 0.6373557924058e-07, 0.6206342280341e+01, 0.9517183207817e+00, - 0.6359474329261e-07, 0.5036079095757e+01, 0.1990745094947e+01, - 0.5740173582646e-07, 0.6105106371350e+01, 0.9555997388169e+00, - 0.7019864084602e-07, 0.7237747359018e+00, 0.5225775174439e+00, - 0.6398054487042e-07, 0.3976367969666e+01, 0.2407292145756e+02, - 0.7797092650498e-07, 0.4305423910623e+01, 0.2200391463820e+02, - - 0.6466760000900e-07, 0.3500136825200e+01, 0.5230807360890e+01, - 0.7529417043890e-07, 0.3514779246100e+01, 0.1842262939178e+02, - 0.6924571140892e-07, 0.2743457928679e+01, 0.1554202828031e+00, - 0.6220798650222e-07, 0.2242598118209e+01, 0.1845107853235e+02, - 0.5870209391853e-07, 0.2332832707527e+01, 0.6398972393349e+00, - 0.6263953473888e-07, 0.2191105358956e+01, 0.6277552955062e+01, - 0.6257781390012e-07, 0.4457559396698e+01, 0.6288598745829e+01, - 0.5697304945123e-07, 0.3499234761404e+01, 0.1551045220144e+01, - 0.6335438746791e-07, 0.6441691079251e+00, 0.5216580451554e+01, - 0.6377258441152e-07, 0.2252599151092e+01, 0.5650292065779e+01, - - 0.6484841818165e-07, 0.1992812417646e+01, 0.1030928125552e+00, - 0.4735551485250e-07, 0.3744672082942e+01, 0.1431416805965e+02, - 0.4628595996170e-07, 0.1334226211745e+01, 0.5535693017924e+00, - 0.6258152336933e-07, 0.4395836159154e+01, 0.2608790314060e+02, - 0.6196171366594e-07, 0.2587043007997e+01, 0.8467247584405e+02, - 0.6159556952126e-07, 0.4782499769128e+01, 0.2394243902548e+03, - 0.4987741172394e-07, 0.7312257619924e+00, 0.7771377146812e+02, - 0.5459280703142e-07, 0.3001376372532e+01, 0.6179983037890e+01, - 0.4863461189999e-07, 0.3767222128541e+01, 0.9027992316901e+02, - 0.5349912093158e-07, 0.3663594450273e+01, 0.6386168663001e+01, - - 0.5673725607806e-07, 0.4331187919049e+01, 0.6915859635113e+01, - 0.4745485060512e-07, 0.5816195745518e+01, 0.6282970628506e+01, - 0.4745379005326e-07, 0.8323672435672e+00, 0.6283181072386e+01, - 0.4049002796321e-07, 0.3785023976293e+01, 0.6254626709878e+01, - 0.4247084014515e-07, 0.2378220728783e+01, 0.7875671926403e+01, - 0.4026912363055e-07, 0.2864103423269e+01, 0.6311524991013e+01, - 0.4062935011774e-07, 0.2415408595975e+01, 0.3634620989887e+01, - 0.5347771048509e-07, 0.3343479309801e+01, 0.2515860172507e+02, - 0.4829494136505e-07, 0.2821742398262e+01, 0.5760498333002e+01, - 0.4342554404599e-07, 0.5624662458712e+01, 0.7238675589263e+01, - - 0.4021599184361e-07, 0.5557250275009e+00, 0.1101510648075e+02, - 0.4104900474558e-07, 0.3296691780005e+01, 0.6709674010002e+01, - 0.4376532905131e-07, 0.3814443999443e+01, 0.6805653367890e+01, - 0.3314590480650e-07, 0.3560229189250e+01, 0.1259245002418e+02, - 0.3232421839643e-07, 0.5185389180568e+01, 0.1066495398892e+01, - 0.3541176318876e-07, 0.3921381909679e+01, 0.9917696840332e+01, - 0.3689831242681e-07, 0.4190658955386e+01, 0.1192625446156e+02, - 0.3890605376774e-07, 0.5546023371097e+01, 0.7478166569050e-01, - 0.3038559339780e-07, 0.6231032794494e+01, 0.1256621883632e+02, - 0.3137083969782e-07, 0.6207063419190e+01, 0.4292330755499e+01, - - 0.4024004081854e-07, 0.1195257375713e+01, 0.1334167431096e+02, - 0.3300234879283e-07, 0.1804694240998e+01, 0.1057540660594e+02, - 0.3635399155575e-07, 0.5597811343500e+01, 0.6208294184755e+01, - 0.3032668691356e-07, 0.3191059366530e+01, 0.1805292951336e+02, - 0.2809652069058e-07, 0.4094348032570e+01, 0.3523159621801e-02, - 0.3696955383823e-07, 0.5219282738794e+01, 0.5966683958112e+01, - 0.3562894142503e-07, 0.1037247544554e+01, 0.6357857516136e+01, - 0.3510598524148e-07, 0.1430020816116e+01, 0.6599467742779e+01, - 0.3617736142953e-07, 0.3002911403677e+01, 0.6019991944201e+01, - 0.2624524910730e-07, 0.2437046757292e+01, 0.6702560555334e+01, - - 0.2535824204490e-07, 0.1581594689647e+01, 0.3141537925223e+02, - 0.3519787226257e-07, 0.5379863121521e+01, 0.2505706758577e+03, - 0.2578406709982e-07, 0.4904222639329e+01, 0.1673046366289e+02, - 0.3423887981473e-07, 0.3646448997315e+01, 0.6546159756691e+01, - 0.2776083886467e-07, 0.3307829300144e+01, 0.1272157198369e+02, - 0.3379592818379e-07, 0.1747541251125e+01, 0.1494531617769e+02, - 0.3050255426284e-07, 0.1784689432607e-01, 0.4732030630302e+01, - 0.2652378350236e-07, 0.4420055276260e+01, 0.5863591145557e+01, - 0.2374498173768e-07, 0.3629773929208e+01, 0.2388894113936e+01, - 0.2716451255140e-07, 0.3079623706780e+01, 0.1202934727411e+02, - - 0.3038583699229e-07, 0.3312487903507e+00, 0.1256608456547e+02, - 0.2220681228760e-07, 0.5265520401774e+01, 0.1336244973887e+02, - 0.3044156540912e-07, 0.4766664081250e+01, 0.2908881142201e+02, - 0.2731859923561e-07, 0.5069146530691e+01, 0.1391601904066e+02, - 0.2285603018171e-07, 0.5954935112271e+01, 0.6076890225335e+01, - 0.2025006454555e-07, 0.4061789589267e+01, 0.4701116388778e+01, - 0.2012597519804e-07, 0.2485047705241e+01, 0.6262720680387e+01, - 0.2003406962258e-07, 0.4163779209320e+01, 0.6303431020504e+01, - 0.2207863441371e-07, 0.6923839133828e+00, 0.6489261475556e+01, - 0.2481374305624e-07, 0.5944173595676e+01, 0.1204357418345e+02, - - 0.2130923288870e-07, 0.4641013671967e+01, 0.5746271423666e+01, - 0.2446370543391e-07, 0.6125796518757e+01, 0.1495633313810e+00, - 0.1932492759052e-07, 0.2234572324504e+00, 0.1352175143971e+02, - 0.2600122568049e-07, 0.4281012405440e+01, 0.4590910121555e+01, - 0.2431754047488e-07, 0.1429943874870e+00, 0.1162474756779e+01, - 0.1875902869209e-07, 0.9781803816948e+00, 0.6279194432410e+01, - 0.1874381139426e-07, 0.5670368130173e+01, 0.6286957268481e+01, - 0.2156696047173e-07, 0.2008985006833e+01, 0.1813929450232e+02, - 0.1965076182484e-07, 0.2566186202453e+00, 0.4686889479442e+01, - 0.2334816372359e-07, 0.4408121891493e+01, 0.1002183730415e+02, - - 0.1869937408802e-07, 0.5272745038656e+01, 0.2427287361862e+00, - 0.2436236460883e-07, 0.4407720479029e+01, 0.9514313292143e+02, - 0.1761365216611e-07, 0.1943892315074e+00, 0.1351787002167e+02, - 0.2156289480503e-07, 0.1418570924545e+01, 0.6037244212485e+01, - 0.2164748979255e-07, 0.4724603439430e+01, 0.2301353951334e+02, - 0.2222286670853e-07, 0.2400266874598e+01, 0.1266924451345e+02, - 0.2070901414929e-07, 0.5230348028732e+01, 0.6528907488406e+01, - 0.1792745177020e-07, 0.2099190328945e+01, 0.6819880277225e+01, - 0.1841802068445e-07, 0.3467527844848e+00, 0.6514761976723e+02, - 0.1578401631718e-07, 0.7098642356340e+00, 0.2077542790660e-01, - - 0.1561690152531e-07, 0.5943349620372e+01, 0.6272439236156e+01, - 0.1558591045463e-07, 0.7040653478980e+00, 0.6293712464735e+01, - 0.1737356469576e-07, 0.4487064760345e+01, 0.1765478049437e+02, - 0.1434755619991e-07, 0.2993391570995e+01, 0.1102062672231e+00, - 0.1482187806654e-07, 0.2278049198251e+01, 0.1052268489556e+01, - 0.1424812827089e-07, 0.1682114725827e+01, 0.1311972100268e+02, - 0.1380282448623e-07, 0.3262668602579e+01, 0.1017725758696e+02, - 0.1811481244566e-07, 0.3187771221777e+01, 0.1887552587463e+02, - 0.1504446185696e-07, 0.5650162308647e+01, 0.7626583626240e-01, - 0.1740776154137e-07, 0.5487068607507e+01, 0.1965104848470e+02, - - 0.1374339536251e-07, 0.5745688172201e+01, 0.6016468784579e+01, - 0.1761377477704e-07, 0.5748060203659e+01, 0.2593412433514e+02, - 0.1535138225795e-07, 0.6226848505790e+01, 0.9411464614024e+01, - 0.1788140543676e-07, 0.6189318878563e+01, 0.3301902111895e+02, - 0.1375002807996e-07, 0.5371812884394e+01, 0.6327837846670e+00, - 0.1242115758632e-07, 0.1471687569712e+01, 0.3894181736510e+01, - 0.1450977333938e-07, 0.4143836662127e+01, 0.1277945078067e+02, - 0.1297579575023e-07, 0.9003477661957e+00, 0.6549682916313e+01, - 0.1462667934821e-07, 0.5760505536428e+01, 0.1863592847156e+02, - 0.1381774374799e-07, 0.1085471729463e+01, 0.2379164476796e+01, - - 0.1682333169307e-07, 0.5409870870133e+01, 0.1620077269078e+02, - 0.1190812918837e-07, 0.1397205174601e+01, 0.1149965630200e+02, - 0.1221434762106e-07, 0.9001804809095e+00, 0.1257326515556e+02, - 0.1549934644860e-07, 0.4262528275544e+01, 0.1820933031200e+02, - 0.1252138953050e-07, 0.1411642012027e+01, 0.6993008899458e+01, - 0.1237078905387e-07, 0.2844472403615e+01, 0.2435678079171e+02, - 0.1446953389615e-07, 0.5295835522223e+01, 0.3813291813120e-01, - 0.1388446457170e-07, 0.4969428135497e+01, 0.2458316379602e+00, - 0.1019339179228e-07, 0.2491369561806e+01, 0.6112403035119e+01, - 0.1258880815343e-07, 0.4679426248976e+01, 0.5429879531333e+01, - - 0.1297768238261e-07, 0.1074509953328e+01, 0.1249137003520e+02, - 0.9913505718094e-08, 0.4735097918224e+01, 0.6247047890016e+01, - 0.9830453155969e-08, 0.4158649187338e+01, 0.6453748665772e+01, - 0.1192615865309e-07, 0.3438208613699e+01, 0.6290122169689e+01, - 0.9835874798277e-08, 0.1913300781229e+01, 0.6319103810876e+01, - 0.9639087569277e-08, 0.9487683644125e+00, 0.8273820945392e+01, - 0.1175716107001e-07, 0.3228141664287e+01, 0.6276029531202e+01, - 0.1018926508678e-07, 0.2216607854300e+01, 0.1254537627298e+02, - 0.9500087869225e-08, 0.2625116459733e+01, 0.1256517118505e+02, - 0.9664192916575e-08, 0.5860562449214e+01, 0.6259197520765e+01, - - 0.9612858712203e-08, 0.7885682917381e+00, 0.6306954180126e+01, - 0.1117645675413e-07, 0.3932148831189e+01, 0.1779695906178e+02, - 0.1158864052160e-07, 0.9995605521691e+00, 0.1778273215245e+02, - 0.9021043467028e-08, 0.5263769742673e+01, 0.6172869583223e+01, - 0.8836134773563e-08, 0.1496843220365e+01, 0.1692165728891e+01, - 0.1045872200691e-07, 0.7009039517214e+00, 0.2204125344462e+00, - 0.1211463487798e-07, 0.4041544938511e+01, 0.8257698122054e+02, - 0.8541990804094e-08, 0.1447586692316e+01, 0.6393282117669e+01, - 0.1038720703636e-07, 0.4594249718112e+00, 0.1550861511662e+02, - 0.1126722351445e-07, 0.3925550579036e+01, 0.2061856251104e+00, - - 0.8697373859631e-08, 0.4411341856037e+01, 0.9491756770005e+00, - 0.8869380028441e-08, 0.2402659724813e+01, 0.3903911373650e+01, - 0.9247014693258e-08, 0.1401579743423e+01, 0.6267823317922e+01, - 0.9205062930950e-08, 0.5245978000814e+01, 0.6298328382969e+01, - 0.8000745038049e-08, 0.3590803356945e+01, 0.2648454860559e+01, - 0.9168973650819e-08, 0.2470150501679e+01, 0.1498544001348e+03, - 0.1075444949238e-07, 0.1328606161230e+01, 0.3694923081589e+02, - 0.7817298525817e-08, 0.6162256225998e+01, 0.4804209201333e+01, - 0.9541469226356e-08, 0.3942568967039e+01, 0.1256713221673e+02, - 0.9821910122027e-08, 0.2360246287233e+00, 0.1140367694411e+02, - - 0.9897822023777e-08, 0.4619805634280e+01, 0.2280573557157e+02, - 0.7737289283765e-08, 0.3784727847451e+01, 0.7834121070590e+01, - 0.9260204034710e-08, 0.2223352487601e+01, 0.2787043132925e+01, - 0.7320252888486e-08, 0.1288694636874e+01, 0.6282655592598e+01, - 0.7319785780946e-08, 0.5359869567774e+01, 0.6283496108294e+01, - 0.7147219933778e-08, 0.5516616675856e+01, 0.1725663147538e+02, - 0.7946502829878e-08, 0.2630459984567e+01, 0.1241073141809e+02, - 0.9001711808932e-08, 0.2849815827227e+01, 0.6281591679874e+01, - 0.8994041507257e-08, 0.3795244450750e+01, 0.6284560021018e+01, - 0.8298582787358e-08, 0.5236413127363e+00, 0.1241658836951e+02, - - 0.8526596520710e-08, 0.4794605424426e+01, 0.1098419223922e+02, - 0.8209822103197e-08, 0.1578752370328e+01, 0.1096996532989e+02, - 0.6357049861094e-08, 0.5708926113761e+01, 0.1596186371003e+01, - 0.7370473179049e-08, 0.3842402530241e+01, 0.4061219149443e+01, - 0.7232154664726e-08, 0.3067548981535e+01, 0.1610006857377e+03, - 0.6328765494903e-08, 0.1313930030069e+01, 0.1193336791622e+02, - 0.8030064908595e-08, 0.3488500408886e+01, 0.8460828644453e+00, - 0.6275464259232e-08, 0.1532061626198e+01, 0.8531963191132e+00, - 0.7051897446325e-08, 0.3285859929993e+01, 0.5849364236221e+01, - 0.6161593705428e-08, 0.1477341999464e+01, 0.5573142801433e+01, - - 0.7754683957278e-08, 0.1586118663096e+01, 0.8662240327241e+01, - 0.5889928990701e-08, 0.1304887868803e+01, 0.1232342296471e+02, - 0.5705756047075e-08, 0.4555333589350e+01, 0.1258692712880e+02, - 0.5964178808332e-08, 0.3001762842062e+01, 0.5333900173445e+01, - 0.6712446027467e-08, 0.4886780007595e+01, 0.1171295538178e+02, - 0.5941809275464e-08, 0.4701509603824e+01, 0.9779108567966e+01, - 0.5466993627395e-08, 0.4588357817278e+01, 0.1884211409667e+02, - 0.6340512090980e-08, 0.1164543038893e+01, 0.5217580628120e+02, - 0.6325505710045e-08, 0.3919171259645e+01, 0.1041998632314e+02, - 0.6164789509685e-08, 0.2143828253542e+01, 0.6151533897323e+01, - - 0.5263330812430e-08, 0.6066564434241e+01, 0.1885275071096e+02, - 0.5597087780221e-08, 0.2926316429472e+01, 0.4337116142245e+00, - 0.5396556236817e-08, 0.3244303591505e+01, 0.6286362197481e+01, - 0.5396615148223e-08, 0.3404304703662e+01, 0.6279789503410e+01, - 0.7091832443341e-08, 0.8532377803192e+00, 0.4907302013889e+01, - 0.6572352589782e-08, 0.4901966774419e+01, 0.1176433076753e+02, - 0.5960236060795e-08, 0.1874672315797e+01, 0.1422690933580e-01, - 0.5125480043511e-08, 0.3735726064334e+01, 0.1245594543367e+02, - 0.5928241866410e-08, 0.4502033899935e+01, 0.6414617803568e+01, - 0.5249600357424e-08, 0.4372334799878e+01, 0.1151388321134e+02, - - 0.6059171276087e-08, 0.2581617302908e+01, 0.6062663316000e+01, - 0.5295235081662e-08, 0.2974811513158e+01, 0.3496032717521e+01, - 0.5820561875933e-08, 0.1796073748244e+00, 0.2838593341516e+00, - 0.4754696606440e-08, 0.1981998136973e+01, 0.3104930017775e+01, - 0.6385053548955e-08, 0.2559174171605e+00, 0.6133512519065e+01, - 0.6589828273941e-08, 0.2750967106776e+01, 0.4087944051283e+02, - 0.5383376567189e-08, 0.6325947523578e+00, 0.2248384854122e+02, - 0.5928941683538e-08, 0.1672304519067e+01, 0.1581959461667e+01, - 0.4816060709794e-08, 0.3512566172575e+01, 0.9388005868221e+01, - 0.6003381586512e-08, 0.5610932219189e+01, 0.5326786718777e+01, - - 0.5504225393105e-08, 0.4037501131256e+01, 0.6503488384892e+01, - 0.5353772620129e-08, 0.6122774968240e+01, 0.1735668374386e+03, - 0.5786253768544e-08, 0.5527984999515e+01, 0.1350651127443e+00, - 0.5065706702002e-08, 0.9980765573624e+00, 0.1248988586463e+02, - 0.5972838885276e-08, 0.6044489493203e+01, 0.2673594526851e+02, - 0.5323585877961e-08, 0.3924265998147e+01, 0.4171425416666e+01, - 0.5210772682858e-08, 0.6220111376901e+01, 0.2460261242967e+02, - 0.4726549040535e-08, 0.3716043206862e+01, 0.7232251527446e+01, - 0.6029425105059e-08, 0.8548704071116e+00, 0.3227113045244e+03, - 0.4481542826513e-08, 0.1426925072829e+01, 0.5547199253223e+01, - - 0.5836024505068e-08, 0.7135651752625e-01, 0.7285056171570e+02, - 0.4137046613272e-08, 0.5330767643283e+01, 0.1087398597200e+02, - 0.5171977473924e-08, 0.4494262335353e+00, 0.1884570439172e+02, - 0.5694429833732e-08, 0.2952369582215e+01, 0.9723862754494e+02, - 0.4009158925298e-08, 0.3500003416535e+01, 0.6244942932314e+01, - 0.4784939596873e-08, 0.6196709413181e+01, 0.2929661536378e+02, - 0.3983725022610e-08, 0.5103690031897e+01, 0.4274518229222e+01, - 0.3870535232462e-08, 0.3187569587401e+01, 0.6321208768577e+01, - 0.5140501213951e-08, 0.1668924357457e+01, 0.1232032006293e+02, - 0.3849034819355e-08, 0.4445722510309e+01, 0.1726726808967e+02, - - 0.4002383075060e-08, 0.5226224152423e+01, 0.7018952447668e+01, - 0.3890719543549e-08, 0.4371166550274e+01, 0.1491901785440e+02, - 0.4887084607881e-08, 0.5973556689693e+01, 0.1478866649112e+01, - 0.3739939287592e-08, 0.2089084714600e+01, 0.6922973089781e+01, - 0.5031925918209e-08, 0.4658371936827e+01, 0.1715706182245e+02, - 0.4387748764954e-08, 0.4825580552819e+01, 0.2331413144044e+03, - 0.4147398098865e-08, 0.3739003524998e+01, 0.1376059875786e+02, - 0.3719089993586e-08, 0.1148941386536e+01, 0.6297302759782e+01, - 0.3934238461056e-08, 0.1559893008343e+01, 0.7872148766781e+01, - 0.3672471375622e-08, 0.5516145383612e+01, 0.6268848941110e+01, - - 0.3768911277583e-08, 0.6116053700563e+01, 0.4157198507331e+01, - 0.4033388417295e-08, 0.5076821746017e+01, 0.1567108171867e+02, - 0.3764194617832e-08, 0.8164676232075e+00, 0.3185192151914e+01, - 0.4840628226284e-08, 0.1360479453671e+01, 0.1252801878276e+02, - 0.4949443923785e-08, 0.2725622229926e+01, 0.1617106187867e+03, - 0.4117393089971e-08, 0.6054459628492e+00, 0.5642198095270e+01, - 0.3925754020428e-08, 0.8570462135210e+00, 0.2139354194808e+02, - 0.3630551757923e-08, 0.3552067338279e+01, 0.6294805223347e+01, - 0.3627274802357e-08, 0.3096565085313e+01, 0.6271346477544e+01, - 0.3806143885093e-08, 0.6367751709777e+00, 0.1725304118033e+02, - - 0.4433254641565e-08, 0.4848461503937e+01, 0.7445550607224e+01, - 0.3712319846576e-08, 0.1331950643655e+01, 0.4194847048887e+00, - 0.3849847534783e-08, 0.4958368297746e+00, 0.9562891316684e+00, - 0.3483955430165e-08, 0.2237215515707e+01, 0.1161697602389e+02, - 0.3961912730982e-08, 0.3332402188575e+01, 0.2277943724828e+02, - 0.3419978244481e-08, 0.5785600576016e+01, 0.1362553364512e+02, - 0.3329417758177e-08, 0.9812676559709e-01, 0.1685848245639e+02, - 0.4207206893193e-08, 0.9494780468236e+00, 0.2986433403208e+02, - 0.3268548976410e-08, 0.1739332095686e+00, 0.5749861718712e+01, - 0.3321880082685e-08, 0.1423354800666e+01, 0.6279143387820e+01, - - 0.4503173010852e-08, 0.2314972675293e+00, 0.1385561574497e+01, - 0.4316599090954e-08, 0.1012646782616e+00, 0.4176041334900e+01, - 0.3283493323850e-08, 0.5233306881265e+01, 0.6287008313071e+01, - 0.3164033542343e-08, 0.4005597257511e+01, 0.2099539292909e+02, - 0.4159720956725e-08, 0.5365676242020e+01, 0.5905702259363e+01, - 0.3565176892217e-08, 0.4284440620612e+01, 0.3932462625300e-02, - 0.3514440950221e-08, 0.4270562636575e+01, 0.7335344340001e+01, - 0.3540596871909e-08, 0.5953553201060e+01, 0.1234573916645e+02, - 0.2960769905118e-08, 0.1115180417718e+01, 0.2670964694522e+02, - 0.2962213739684e-08, 0.3863811918186e+01, 0.6408777551755e+00, - - 0.3883556700251e-08, 0.1268617928302e+01, 0.6660449441528e+01, - 0.2919225516346e-08, 0.4908605223265e+01, 0.1375773836557e+01, - 0.3115158863370e-08, 0.3744519976885e+01, 0.3802769619140e-01, - 0.4099438144212e-08, 0.4173244670532e+01, 0.4480965020977e+02, - 0.2899531858964e-08, 0.5910601428850e+01, 0.2059724391010e+02, - 0.3289733429855e-08, 0.2488050078239e+01, 0.1081813534213e+02, - 0.3933075612875e-08, 0.1122363652883e+01, 0.3773735910827e+00, - 0.3021403764467e-08, 0.4951973724904e+01, 0.2982630633589e+02, - 0.2798598949757e-08, 0.5117057845513e+01, 0.1937891852345e+02, - 0.3397421302707e-08, 0.6104159180476e+01, 0.6923953605621e+01, - - 0.3720398002179e-08, 0.1184933429829e+01, 0.3066615496545e+02, - 0.3598484186267e-08, 0.3505282086105e+01, 0.6147450479709e+01, - 0.3694594027310e-08, 0.2286651088141e+01, 0.2636725487657e+01, - 0.2680444152969e-08, 0.1871816775482e+00, 0.6816289982179e+01, - 0.3497574865641e-08, 0.3143251755431e+01, 0.6418701221183e+01, - 0.3130274129494e-08, 0.2462167316018e+01, 0.1235996607578e+02, - 0.3241119069551e-08, 0.4256374004686e+01, 0.1652265972112e+02, - 0.2601960842061e-08, 0.4970362941425e+01, 0.1045450126711e+02, - 0.2690601527504e-08, 0.2372657824898e+01, 0.3163918923335e+00, - 0.2908688152664e-08, 0.4232652627721e+01, 0.2828699048865e+02, - - 0.3120456131875e-08, 0.3925747001137e+00, 0.2195415756911e+02, - 0.3148855423384e-08, 0.3093478330445e+01, 0.1172006883645e+02, - 0.3051044261017e-08, 0.5560948248212e+01, 0.6055599646783e+01, - 0.2826006876660e-08, 0.5072790310072e+01, 0.5120601093667e+01, - 0.3100034191711e-08, 0.4998530231096e+01, 0.1799603123222e+02, - 0.2398771640101e-08, 0.2561739802176e+01, 0.6255674361143e+01, - 0.2384002842728e-08, 0.4087420284111e+01, 0.6310477339748e+01, - 0.2842146517568e-08, 0.2515048217955e+01, 0.5469525544182e+01, - 0.2847674371340e-08, 0.5235326497443e+01, 0.1034429499989e+02, - 0.2903722140764e-08, 0.1088200795797e+01, 0.6510552054109e+01, - - 0.3187610710605e-08, 0.4710624424816e+01, 0.1693792562116e+03, - 0.3048869992813e-08, 0.2857975896445e+00, 0.8390110365991e+01, - 0.2860216950984e-08, 0.2241619020815e+01, 0.2243449970715e+00, - 0.2701117683113e-08, 0.6651573305272e-01, 0.6129297044991e+01, - 0.2509891590152e-08, 0.1285135324585e+01, 0.1044027435778e+02, - 0.2623200252223e-08, 0.2981229834530e+00, 0.6436854655901e+01, - 0.2622541669202e-08, 0.6122470726189e+01, 0.9380959548977e+01, - 0.2818435667099e-08, 0.4251087148947e+01, 0.5934151399930e+01, - 0.2365196797465e-08, 0.3465070460790e+01, 0.2470570524223e+02, - 0.2358704646143e-08, 0.5791603815350e+01, 0.8671969964381e+01, - - 0.2388299481390e-08, 0.4142483772941e+01, 0.7096626156709e+01, - 0.1996041217224e-08, 0.2101901889496e+01, 0.1727188400790e+02, - 0.2687593060336e-08, 0.1526689456959e+01, 0.7075506709219e+02, - 0.2618913670810e-08, 0.2397684236095e+01, 0.6632000300961e+01, - 0.2571523050364e-08, 0.5751929456787e+00, 0.6206810014183e+01, - 0.2582135006946e-08, 0.5595464352926e+01, 0.4873985990671e+02, - 0.2372530190361e-08, 0.5092689490655e+01, 0.1590676413561e+02, - 0.2357178484712e-08, 0.4444363527851e+01, 0.3097883698531e+01, - 0.2451590394723e-08, 0.3108251687661e+01, 0.6612329252343e+00, - 0.2370045949608e-08, 0.2608133861079e+01, 0.3459636466239e+02, - - 0.2268997267358e-08, 0.3639717753384e+01, 0.2844914056730e-01, - 0.1731432137906e-08, 0.1741898445707e+00, 0.2019909489111e+02, - 0.1629869741622e-08, 0.3902225646724e+01, 0.3035599730800e+02, - 0.2206215801974e-08, 0.4971131250731e+01, 0.6281667977667e+01, - 0.2205469554680e-08, 0.1677462357110e+01, 0.6284483723224e+01, - 0.2148792362509e-08, 0.4236259604006e+01, 0.1980482729015e+02, - 0.1873733657847e-08, 0.5926814998687e+01, 0.2876692439167e+02, - 0.2026573758959e-08, 0.4349643351962e+01, 0.2449240616245e+02, - 0.1807770325110e-08, 0.5700940482701e+01, 0.2045286941806e+02, - 0.1881174408581e-08, 0.6601286363430e+00, 0.2358125818164e+02, - - 0.1368023671690e-08, 0.2211098592752e+01, 0.2473415438279e+02, - 0.1720017916280e-08, 0.4942488551129e+01, 0.1679593901136e+03, - 0.1702427665131e-08, 0.1452233856386e+01, 0.3338575901272e+03, - 0.1414032510054e-08, 0.5525357721439e+01, 0.1624205518357e+03, - 0.1652626045364e-08, 0.4108794283624e+01, 0.8956999012000e+02, - 0.1642957769686e-08, 0.7344335209984e+00, 0.5267006960365e+02, - 0.1614952403624e-08, 0.3541213951363e+01, 0.3332657872986e+02, - 0.1535988291188e-08, 0.4031094072151e+01, 0.3852657435933e+02, - 0.1593193738177e-08, 0.4185136203609e+01, 0.2282781046519e+03, - 0.1074569126382e-08, 0.1720485636868e+01, 0.8397383534231e+02, - - 0.1074408214509e-08, 0.2758613420318e+01, 0.8401985929482e+02, - 0.9700199670465e-09, 0.4216686842097e+01, 0.7826370942180e+02, - 0.1258433517061e-08, 0.2575068876639e+00, 0.3115650189215e+03, - 0.1240303229539e-08, 0.4800844956756e+00, 0.1784300471910e+03, - 0.9018345948127e-09, 0.3896756361552e+00, 0.5886454391678e+02, - 0.1135301432805e-08, 0.3700805023550e+00, 0.7842370451713e+02, - 0.9215887951370e-09, 0.4364579276638e+01, 0.1014262087719e+03, - 0.1055401054147e-08, 0.2156564222111e+01, 0.5660027930059e+02, - 0.1008725979831e-08, 0.5454015785234e+01, 0.4245678405627e+02, - 0.7217398104321e-09, 0.1597772562175e+01, 0.2457074661053e+03, - - 0.6912033134447e-09, 0.5824090621461e+01, 0.1679936946371e+03, - 0.6833881523549e-09, 0.3578778482835e+01, 0.6053048899753e+02, - 0.4887304205142e-09, 0.3724362812423e+01, 0.9656299901946e+02, - 0.5173709754788e-09, 0.5422427507933e+01, 0.2442876000072e+03, - 0.4671353097145e-09, 0.2396106924439e+01, 0.1435713242844e+03, - 0.5652608439480e-09, 0.2804028838685e+01, 0.8365903305582e+02, - 0.5604061331253e-09, 0.1638816006247e+01, 0.8433466158131e+02, - 0.4712723365400e-09, 0.8979003224474e+00, 0.3164282286739e+03, - 0.4909967465112e-09, 0.3210426725516e+01, 0.4059982187939e+03, - 0.4771358267658e-09, 0.5308027211629e+01, 0.1805255418145e+03, - - 0.3943451445989e-09, 0.2195145341074e+01, 0.2568537517081e+03, - 0.3952109120244e-09, 0.5081189491586e+01, 0.2449975330562e+03, - 0.3788134594789e-09, 0.4345171264441e+01, 0.1568131045107e+03, - 0.3738330190479e-09, 0.2613062847997e+01, 0.3948519331910e+03, - 0.3099866678136e-09, 0.2846760817689e+01, 0.1547176098872e+03, - 0.2002962716768e-09, 0.4921360989412e+01, 0.2268582385539e+03, - 0.2198291338754e-09, 0.1130360117454e+00, 0.1658638954901e+03, - 0.1491958330784e-09, 0.4228195232278e+01, 0.2219950288015e+03, - 0.1475384076173e-09, 0.3005721811604e+00, 0.3052819430710e+03, - 0.1661626624624e-09, 0.7830125621203e+00, 0.2526661704812e+03, - - 0.9015823460025e-10, 0.3807792942715e+01, 0.4171445043968e+03 }; - -/* Sun-to-Earth, T^0, Y */ - static const double e0y[] = { - 0.9998921098898e+00, 0.1826583913846e+00, 0.6283075850446e+01, - -0.2442700893735e-01, 0.0000000000000e+00, 0.0000000000000e+00, - 0.8352929742915e-02, 0.1395277998680e+00, 0.1256615170089e+02, - 0.1046697300177e-03, 0.9641423109763e-01, 0.1884922755134e+02, - 0.3110841876663e-04, 0.5381140401712e+01, 0.8399684731857e+02, - 0.2570269094593e-04, 0.5301016407128e+01, 0.5296909721118e+00, - 0.2147389623610e-04, 0.2662510869850e+01, 0.1577343543434e+01, - 0.1680344384050e-04, 0.5207904119704e+01, 0.6279552690824e+01, - 0.1679117312193e-04, 0.4582187486968e+01, 0.6286599010068e+01, - 0.1440512068440e-04, 0.1900688517726e+01, 0.2352866153506e+01, - - 0.1135139664999e-04, 0.5273108538556e+01, 0.5223693906222e+01, - 0.9345482571018e-05, 0.4503047687738e+01, 0.1203646072878e+02, - 0.9007418719568e-05, 0.1605621059637e+01, 0.1021328554739e+02, - 0.5671536712314e-05, 0.5812849070861e+00, 0.1059381944224e+01, - 0.7451401861666e-05, 0.2807346794836e+01, 0.3981490189893e+00, - 0.6393470057114e-05, 0.6029224133855e+01, 0.5753384878334e+01, - 0.6814275881697e-05, 0.6472990145974e+00, 0.4705732307012e+01, - 0.6113705628887e-05, 0.3813843419700e+01, 0.6812766822558e+01, - 0.4503851367273e-05, 0.4527804370996e+01, 0.5884926831456e+01, - 0.4522249141926e-05, 0.5991783029224e+01, 0.6256777527156e+01, - - 0.4501794307018e-05, 0.3798703844397e+01, 0.6309374173736e+01, - 0.5514927480180e-05, 0.3961257833388e+01, 0.5507553240374e+01, - 0.4062862799995e-05, 0.5256247296369e+01, 0.6681224869435e+01, - 0.5414900429712e-05, 0.5499032014097e+01, 0.7755226100720e+00, - 0.5463153987424e-05, 0.6173092454097e+01, 0.1414349524433e+02, - 0.5071611859329e-05, 0.2870244247651e+01, 0.7860419393880e+01, - 0.2195112094455e-05, 0.2952338617201e+01, 0.1150676975667e+02, - 0.2279139233919e-05, 0.5951775132933e+01, 0.7058598460518e+01, - 0.2278386100876e-05, 0.4845456398785e+01, 0.4694002934110e+01, - 0.2559088003308e-05, 0.6945321117311e+00, 0.1216800268190e+02, - - 0.2561079286856e-05, 0.6167224608301e+01, 0.7099330490126e+00, - 0.1792755796387e-05, 0.1400122509632e+01, 0.7962980379786e+00, - 0.1818715656502e-05, 0.4703347611830e+01, 0.6283142985870e+01, - 0.1818744924791e-05, 0.5086748900237e+01, 0.6283008715021e+01, - 0.1554518791390e-05, 0.5331008042713e-01, 0.2513230340178e+02, - 0.2063265737239e-05, 0.4283680484178e+01, 0.1179062909082e+02, - 0.1497613520041e-05, 0.6074207826073e+01, 0.5486777812467e+01, - 0.2000617940427e-05, 0.2501426281450e+01, 0.1778984560711e+02, - 0.1289731195580e-05, 0.3646340599536e+01, 0.7079373888424e+01, - 0.1282657998934e-05, 0.3232864804902e+01, 0.3738761453707e+01, - - 0.1528915968658e-05, 0.5581433416669e+01, 0.2132990797783e+00, - 0.1187304098432e-05, 0.5453576453694e+01, 0.9437762937313e+01, - 0.7842782928118e-06, 0.2823953922273e+00, 0.8827390247185e+01, - 0.7352892280868e-06, 0.1124369580175e+01, 0.1589072916335e+01, - 0.6570189360797e-06, 0.2089154042840e+01, 0.1176985366291e+02, - 0.6324967590410e-06, 0.6704855581230e+00, 0.6262300422539e+01, - 0.6298289872283e-06, 0.2836414855840e+01, 0.6303851278352e+01, - 0.6476686465855e-06, 0.4852433866467e+00, 0.7113454667900e-02, - 0.8587034651234e-06, 0.1453511005668e+01, 0.1672837615881e+03, - 0.8068948788113e-06, 0.9224087798609e+00, 0.6069776770667e+01, - - 0.8353786011661e-06, 0.4631707184895e+01, 0.3340612434717e+01, - 0.6009324532132e-06, 0.1829498827726e+01, 0.4136910472696e+01, - 0.7558158559566e-06, 0.2588596800317e+01, 0.6496374930224e+01, - 0.5809279504503e-06, 0.5516818853476e+00, 0.1097707878456e+02, - 0.5374131950254e-06, 0.6275674734960e+01, 0.1194447056968e+01, - 0.5711160507326e-06, 0.1091905956872e+01, 0.6282095334605e+01, - 0.5710183170746e-06, 0.2415001635090e+01, 0.6284056366286e+01, - 0.5144373590610e-06, 0.6020336443438e+01, 0.6290189305114e+01, - 0.5103108927267e-06, 0.3775634564605e+01, 0.6275962395778e+01, - 0.4960654697891e-06, 0.1073450946756e+01, 0.6127655567643e+01, - - 0.4786385689280e-06, 0.2431178012310e+01, 0.6438496133249e+01, - 0.6109911263665e-06, 0.5343356157914e+01, 0.3154687086868e+01, - 0.4839898944024e-06, 0.5830833594047e-01, 0.8018209333619e+00, - 0.4734822623919e-06, 0.4536080134821e+01, 0.3128388763578e+01, - 0.4834741473290e-06, 0.2585090489754e+00, 0.7084896783808e+01, - 0.5134858581156e-06, 0.4213317172603e+01, 0.1235285262111e+02, - 0.5064004264978e-06, 0.4814418806478e+00, 0.1185621865188e+02, - 0.3753476772761e-06, 0.1599953399788e+01, 0.8429241228195e+01, - 0.4935264014283e-06, 0.2157417556873e+01, 0.2544314396739e+01, - 0.3950929600897e-06, 0.3359394184254e+01, 0.5481254917084e+01, - - 0.4895849789777e-06, 0.5165704376558e+01, 0.9225539266174e+01, - 0.4215241688886e-06, 0.2065368800993e+01, 0.1726015463500e+02, - 0.3796773731132e-06, 0.1468606346612e+01, 0.4265981595566e+00, - 0.3114178142515e-06, 0.3615638079474e+01, 0.2146165377750e+01, - 0.3260664220838e-06, 0.4417134922435e+01, 0.4164311961999e+01, - 0.3976996123008e-06, 0.4700866883004e+01, 0.5856477690889e+01, - 0.2801459672924e-06, 0.4538902060922e+01, 0.1256967486051e+02, - 0.3638931868861e-06, 0.1334197991475e+01, 0.1807370494127e+02, - 0.2487013269476e-06, 0.3749275558275e+01, 0.2629832328990e-01, - 0.3034165481994e-06, 0.4236622030873e+00, 0.4535059491685e+01, - - 0.2676278825586e-06, 0.5970848007811e+01, 0.3930209696940e+01, - 0.2764903818918e-06, 0.5194636754501e+01, 0.1256262854127e+02, - 0.2485149930507e-06, 0.1002434207846e+01, 0.5088628793478e+01, - 0.2199305540941e-06, 0.3066773098403e+01, 0.1255903824622e+02, - 0.2571106500435e-06, 0.7588312459063e+00, 0.1336797263425e+02, - 0.2049751817158e-06, 0.3444977434856e+01, 0.1137170464392e+02, - 0.2599707296297e-06, 0.1873128542205e+01, 0.7143069561767e+02, - 0.1785018072217e-06, 0.5015891306615e+01, 0.1748016358760e+01, - 0.2324833891115e-06, 0.4618271239730e+01, 0.1831953657923e+02, - 0.1709711119545e-06, 0.5300003455669e+01, 0.4933208510675e+01, - - 0.2107159351716e-06, 0.2229819815115e+01, 0.7477522907414e+01, - 0.1750333080295e-06, 0.6161485880008e+01, 0.1044738781244e+02, - 0.2000598210339e-06, 0.2967357299999e+01, 0.8031092209206e+01, - 0.1380920248681e-06, 0.3027007923917e+01, 0.8635942003952e+01, - 0.1412460470299e-06, 0.6037597163798e+01, 0.2942463415728e+01, - 0.1888459803001e-06, 0.8561476243374e+00, 0.1561374759853e+03, - 0.1788370542585e-06, 0.4869736290209e+01, 0.1592596075957e+01, - 0.1360893296167e-06, 0.3626411886436e+01, 0.1309584267300e+02, - 0.1506846530160e-06, 0.1550975377427e+01, 0.1649636139783e+02, - 0.1800913376176e-06, 0.2075826033190e+01, 0.1729818233119e+02, - - 0.1436261390649e-06, 0.6148876420255e+01, 0.2042657109477e+02, - 0.1220227114151e-06, 0.4382583879906e+01, 0.7632943190217e+01, - 0.1337883603592e-06, 0.2036644327361e+01, 0.1213955354133e+02, - 0.1159326650738e-06, 0.3892276994687e+01, 0.5331357529664e+01, - 0.1352853128569e-06, 0.1447950649744e+01, 0.1673046366289e+02, - 0.1433408296083e-06, 0.4457854692961e+01, 0.7342457794669e+01, - 0.1234701666518e-06, 0.1538818147151e+01, 0.6279485555400e+01, - 0.1234027192007e-06, 0.1968523220760e+01, 0.6286666145492e+01, - 0.1244024091797e-06, 0.5779803499985e+01, 0.1511046609763e+02, - 0.1097934945516e-06, 0.6210975221388e+00, 0.1098880815746e+02, - - 0.1254611329856e-06, 0.2591963807998e+01, 0.1572083878776e+02, - 0.1158247286784e-06, 0.2483612812670e+01, 0.5729506548653e+01, - 0.9039078252960e-07, 0.3857554579796e+01, 0.9623688285163e+01, - 0.9108024978836e-07, 0.5826368512984e+01, 0.7234794171227e+01, - 0.8887068108436e-07, 0.3475694573987e+01, 0.6148010737701e+01, - 0.8632374035438e-07, 0.3059070488983e-01, 0.6418140963190e+01, - 0.7893186992967e-07, 0.1583194837728e+01, 0.2118763888447e+01, - 0.8297650201172e-07, 0.8519770534637e+00, 0.1471231707864e+02, - 0.1019759578988e-06, 0.1319598738732e+00, 0.1349867339771e+01, - 0.1010037696236e-06, 0.9937860115618e+00, 0.6836645152238e+01, - - 0.1047727548266e-06, 0.1382138405399e+01, 0.5999216516294e+01, - 0.7351993881086e-07, 0.3833397851735e+01, 0.6040347114260e+01, - 0.9868771092341e-07, 0.2124913814390e+01, 0.6566935184597e+01, - 0.7007321959390e-07, 0.5946305343763e+01, 0.6525804586632e+01, - 0.6861411679709e-07, 0.4574654977089e+01, 0.7238675589263e+01, - 0.7554519809614e-07, 0.5949232686844e+01, 0.1253985337760e+02, - 0.9541880448335e-07, 0.3495242990564e+01, 0.2122839202813e+02, - 0.7185606722155e-07, 0.4310113471661e+01, 0.6245048154254e+01, - 0.7131360871710e-07, 0.5480309323650e+01, 0.6321103546637e+01, - 0.6651142021039e-07, 0.5411097713654e+01, 0.5327476111629e+01, - - 0.8538618213667e-07, 0.1827849973951e+01, 0.1101510648075e+02, - 0.8634954288044e-07, 0.5443584943349e+01, 0.5643178611111e+01, - 0.7449415051484e-07, 0.2011535459060e+01, 0.5368044267797e+00, - 0.7421047599169e-07, 0.3464562529249e+01, 0.2354323048545e+02, - 0.6140694354424e-07, 0.5657556228815e+01, 0.1296430071988e+02, - 0.6353525143033e-07, 0.3463816593821e+01, 0.1990745094947e+01, - 0.6221964013447e-07, 0.1532259498697e+01, 0.9517183207817e+00, - 0.5852480257244e-07, 0.1375396598875e+01, 0.9555997388169e+00, - 0.6398637498911e-07, 0.2405645801972e+01, 0.2407292145756e+02, - 0.7039744069878e-07, 0.5397541799027e+01, 0.5225775174439e+00, - - 0.6977997694382e-07, 0.4762347105419e+01, 0.1097355562493e+02, - 0.7460629558396e-07, 0.2711944692164e+01, 0.2200391463820e+02, - 0.5376577536101e-07, 0.2352980430239e+01, 0.1431416805965e+02, - 0.7530607893556e-07, 0.1943940180699e+01, 0.1842262939178e+02, - 0.6822928971605e-07, 0.4337651846959e+01, 0.1554202828031e+00, - 0.6220772380094e-07, 0.6716871369278e+00, 0.1845107853235e+02, - 0.6586950799043e-07, 0.2229714460505e+01, 0.5216580451554e+01, - 0.5873800565771e-07, 0.7627013920580e+00, 0.6398972393349e+00, - 0.6264346929745e-07, 0.6202785478961e+00, 0.6277552955062e+01, - 0.6257929115669e-07, 0.2886775596668e+01, 0.6288598745829e+01, - - 0.5343536033409e-07, 0.1977241012051e+01, 0.4690479774488e+01, - 0.5587849781714e-07, 0.1922923484825e+01, 0.1551045220144e+01, - 0.6905100845603e-07, 0.3570757164631e+01, 0.1030928125552e+00, - 0.6178957066649e-07, 0.5197558947765e+01, 0.5230807360890e+01, - 0.6187270224331e-07, 0.8193497368922e+00, 0.5650292065779e+01, - 0.5385664291426e-07, 0.5406336665586e+01, 0.7771377146812e+02, - 0.6329363917926e-07, 0.2837760654536e+01, 0.2608790314060e+02, - 0.4546018761604e-07, 0.2933580297050e+01, 0.5535693017924e+00, - 0.6196091049375e-07, 0.4157871494377e+01, 0.8467247584405e+02, - 0.6159555108218e-07, 0.3211703561703e+01, 0.2394243902548e+03, - - 0.4995340539317e-07, 0.1459098102922e+01, 0.4732030630302e+01, - 0.5457031243572e-07, 0.1430457676136e+01, 0.6179983037890e+01, - 0.4863461418397e-07, 0.2196425916730e+01, 0.9027992316901e+02, - 0.5342947626870e-07, 0.2086612890268e+01, 0.6386168663001e+01, - 0.5674296648439e-07, 0.2760204966535e+01, 0.6915859635113e+01, - 0.4745783120161e-07, 0.4245368971862e+01, 0.6282970628506e+01, - 0.4745676961198e-07, 0.5544725787016e+01, 0.6283181072386e+01, - 0.4049796869973e-07, 0.2213984363586e+01, 0.6254626709878e+01, - 0.4248333596940e-07, 0.8075781952896e+00, 0.7875671926403e+01, - 0.4027178070205e-07, 0.1293268540378e+01, 0.6311524991013e+01, - - 0.4066543943476e-07, 0.3986141175804e+01, 0.3634620989887e+01, - 0.4858863787880e-07, 0.1276112738231e+01, 0.5760498333002e+01, - 0.5277398263530e-07, 0.4916111741527e+01, 0.2515860172507e+02, - 0.4105635656559e-07, 0.1725805864426e+01, 0.6709674010002e+01, - 0.4376781925772e-07, 0.2243642442106e+01, 0.6805653367890e+01, - 0.3235827894693e-07, 0.3614135118271e+01, 0.1066495398892e+01, - 0.3073244740308e-07, 0.2460873393460e+01, 0.5863591145557e+01, - 0.3088609271373e-07, 0.5678431771790e+01, 0.9917696840332e+01, - 0.3393022279836e-07, 0.3814017477291e+01, 0.1391601904066e+02, - 0.3038686508802e-07, 0.4660216229171e+01, 0.1256621883632e+02, - - 0.4019677752497e-07, 0.5906906243735e+01, 0.1334167431096e+02, - 0.3288834998232e-07, 0.9536146445882e+00, 0.1620077269078e+02, - 0.3889973794631e-07, 0.3942205097644e+01, 0.7478166569050e-01, - 0.3050438987141e-07, 0.1624810271286e+01, 0.1805292951336e+02, - 0.3601142564638e-07, 0.4030467142575e+01, 0.6208294184755e+01, - 0.3689015557141e-07, 0.3648878818694e+01, 0.5966683958112e+01, - 0.3563471893565e-07, 0.5749584017096e+01, 0.6357857516136e+01, - 0.2776183170667e-07, 0.2630124187070e+01, 0.3523159621801e-02, - 0.2922350530341e-07, 0.1790346403629e+01, 0.1272157198369e+02, - 0.3511076917302e-07, 0.6142198301611e+01, 0.6599467742779e+01, - - 0.3619351007632e-07, 0.1432421386492e+01, 0.6019991944201e+01, - 0.2561254711098e-07, 0.2302822475792e+01, 0.1259245002418e+02, - 0.2626903942920e-07, 0.8660470994571e+00, 0.6702560555334e+01, - 0.2550187397083e-07, 0.6069721995383e+01, 0.1057540660594e+02, - 0.2535873526138e-07, 0.1079020331795e-01, 0.3141537925223e+02, - 0.3519786153847e-07, 0.3809066902283e+01, 0.2505706758577e+03, - 0.3424651492873e-07, 0.2075435114417e+01, 0.6546159756691e+01, - 0.2372676630861e-07, 0.2057803120154e+01, 0.2388894113936e+01, - 0.2710980779541e-07, 0.1510068488010e+01, 0.1202934727411e+02, - 0.3038710889704e-07, 0.5043617528901e+01, 0.1256608456547e+02, - - 0.2220364130585e-07, 0.3694793218205e+01, 0.1336244973887e+02, - 0.3025880825460e-07, 0.5450618999049e-01, 0.2908881142201e+02, - 0.2784493486864e-07, 0.3381164084502e+01, 0.1494531617769e+02, - 0.2294414142438e-07, 0.4382309025210e+01, 0.6076890225335e+01, - 0.2012723294724e-07, 0.9142212256518e+00, 0.6262720680387e+01, - 0.2036357831958e-07, 0.5676172293154e+01, 0.4701116388778e+01, - 0.2003474823288e-07, 0.2592767977625e+01, 0.6303431020504e+01, - 0.2207144900109e-07, 0.5404976271180e+01, 0.6489261475556e+01, - 0.2481664905135e-07, 0.4373284587027e+01, 0.1204357418345e+02, - 0.2674949182295e-07, 0.5859182188482e+01, 0.4590910121555e+01, - - 0.2450554720322e-07, 0.4555381557451e+01, 0.1495633313810e+00, - 0.2601975986457e-07, 0.3933165584959e+01, 0.1965104848470e+02, - 0.2199860022848e-07, 0.5227977189087e+01, 0.1351787002167e+02, - 0.2448121172316e-07, 0.4858060353949e+01, 0.1162474756779e+01, - 0.1876014864049e-07, 0.5690546553605e+01, 0.6279194432410e+01, - 0.1874513219396e-07, 0.4099539297446e+01, 0.6286957268481e+01, - 0.2156380842559e-07, 0.4382594769913e+00, 0.1813929450232e+02, - 0.1981691240061e-07, 0.1829784152444e+01, 0.4686889479442e+01, - 0.2329992648539e-07, 0.2836254278973e+01, 0.1002183730415e+02, - 0.1765184135302e-07, 0.2803494925833e+01, 0.4292330755499e+01, - - 0.2436368366085e-07, 0.2836897959677e+01, 0.9514313292143e+02, - 0.2164089203889e-07, 0.6127522446024e+01, 0.6037244212485e+01, - 0.1847755034221e-07, 0.3683163635008e+01, 0.2427287361862e+00, - 0.1674798769966e-07, 0.3316993867246e+00, 0.1311972100268e+02, - 0.2222542124356e-07, 0.8294097805480e+00, 0.1266924451345e+02, - 0.2071074505925e-07, 0.3659492220261e+01, 0.6528907488406e+01, - 0.1608224471835e-07, 0.4774492067182e+01, 0.1352175143971e+02, - 0.1857583439071e-07, 0.2873120597682e+01, 0.8662240327241e+01, - 0.1793018836159e-07, 0.5282441177929e+00, 0.6819880277225e+01, - 0.1575391221692e-07, 0.1320789654258e+01, 0.1102062672231e+00, - - 0.1840132009557e-07, 0.1917110916256e+01, 0.6514761976723e+02, - 0.1760917288281e-07, 0.2972635937132e+01, 0.5746271423666e+01, - 0.1561779518516e-07, 0.4372569261981e+01, 0.6272439236156e+01, - 0.1558687885205e-07, 0.5416424926425e+01, 0.6293712464735e+01, - 0.1951359382579e-07, 0.3094448898752e+01, 0.2301353951334e+02, - 0.1569144275614e-07, 0.2802103689808e+01, 0.1765478049437e+02, - 0.1479130389462e-07, 0.2136435020467e+01, 0.2077542790660e-01, - 0.1467828510764e-07, 0.7072627435674e+00, 0.1052268489556e+01, - 0.1627627337440e-07, 0.3947607143237e+01, 0.6327837846670e+00, - 0.1503498479758e-07, 0.4079248909190e+01, 0.7626583626240e-01, - - 0.1297967708237e-07, 0.6269637122840e+01, 0.1149965630200e+02, - 0.1374416896634e-07, 0.4175657970702e+01, 0.6016468784579e+01, - 0.1783812325219e-07, 0.1476540547560e+01, 0.3301902111895e+02, - 0.1525884228756e-07, 0.4653477715241e+01, 0.9411464614024e+01, - 0.1451067396763e-07, 0.2573001128225e+01, 0.1277945078067e+02, - 0.1297713111950e-07, 0.5612799618771e+01, 0.6549682916313e+01, - 0.1462784012820e-07, 0.4189661623870e+01, 0.1863592847156e+02, - 0.1384185980007e-07, 0.2656915472196e+01, 0.2379164476796e+01, - 0.1221497599801e-07, 0.5612515760138e+01, 0.1257326515556e+02, - 0.1560574525896e-07, 0.4783414317919e+01, 0.1887552587463e+02, - - 0.1544598372036e-07, 0.2694431138063e+01, 0.1820933031200e+02, - 0.1531678928696e-07, 0.4105103489666e+01, 0.2593412433514e+02, - 0.1349321503795e-07, 0.3082437194015e+00, 0.5120601093667e+01, - 0.1252030290917e-07, 0.6124072334087e+01, 0.6993008899458e+01, - 0.1459243816687e-07, 0.3733103981697e+01, 0.3813291813120e-01, - 0.1226103625262e-07, 0.1267127706817e+01, 0.2435678079171e+02, - 0.1019449641504e-07, 0.4367790112269e+01, 0.1725663147538e+02, - 0.1380789433607e-07, 0.3387201768700e+01, 0.2458316379602e+00, - 0.1019453421658e-07, 0.9204143073737e+00, 0.6112403035119e+01, - 0.1297929434405e-07, 0.5786874896426e+01, 0.1249137003520e+02, - - 0.9912677786097e-08, 0.3164232870746e+01, 0.6247047890016e+01, - 0.9829386098599e-08, 0.2586762413351e+01, 0.6453748665772e+01, - 0.1226807746104e-07, 0.6239068436607e+01, 0.5429879531333e+01, - 0.1192691755997e-07, 0.1867380051424e+01, 0.6290122169689e+01, - 0.9836499227081e-08, 0.3424716293727e+00, 0.6319103810876e+01, - 0.9642862564285e-08, 0.5661372990657e+01, 0.8273820945392e+01, - 0.1165184404862e-07, 0.5768367239093e+01, 0.1778273215245e+02, - 0.1175794418818e-07, 0.1657351222943e+01, 0.6276029531202e+01, - 0.1018948635601e-07, 0.6458292350865e+00, 0.1254537627298e+02, - 0.9500383606676e-08, 0.1054306140741e+01, 0.1256517118505e+02, - - 0.1227512202906e-07, 0.2505278379114e+01, 0.2248384854122e+02, - 0.9664792009993e-08, 0.4289737277000e+01, 0.6259197520765e+01, - 0.9613285666331e-08, 0.5500597673141e+01, 0.6306954180126e+01, - 0.1117906736211e-07, 0.2361405953468e+01, 0.1779695906178e+02, - 0.9611378640782e-08, 0.2851310576269e+01, 0.2061856251104e+00, - 0.8845354852370e-08, 0.6208777705343e+01, 0.1692165728891e+01, - 0.1054046966600e-07, 0.5413091423934e+01, 0.2204125344462e+00, - 0.1215539124483e-07, 0.5613969479755e+01, 0.8257698122054e+02, - 0.9932460955209e-08, 0.1106124877015e+01, 0.1017725758696e+02, - 0.8785804715043e-08, 0.2869224476477e+01, 0.9491756770005e+00, - - 0.8538084097562e-08, 0.6159640899344e+01, 0.6393282117669e+01, - 0.8648994369529e-08, 0.1374901198784e+01, 0.4804209201333e+01, - 0.1039063219067e-07, 0.5171080641327e+01, 0.1550861511662e+02, - 0.8867983926439e-08, 0.8317320304902e+00, 0.3903911373650e+01, - 0.8327495955244e-08, 0.3605591969180e+01, 0.6172869583223e+01, - 0.9243088356133e-08, 0.6114299196843e+01, 0.6267823317922e+01, - 0.9205657357835e-08, 0.3675153683737e+01, 0.6298328382969e+01, - 0.1033269714606e-07, 0.3313328813024e+01, 0.5573142801433e+01, - 0.8001706275552e-08, 0.2019980960053e+01, 0.2648454860559e+01, - 0.9171858254191e-08, 0.8992015524177e+00, 0.1498544001348e+03, - - 0.1075327150242e-07, 0.2898669963648e+01, 0.3694923081589e+02, - 0.9884866689828e-08, 0.4946715904478e+01, 0.1140367694411e+02, - 0.9541835576677e-08, 0.2371787888469e+01, 0.1256713221673e+02, - 0.7739903376237e-08, 0.2213775190612e+01, 0.7834121070590e+01, - 0.7311962684106e-08, 0.3429378787739e+01, 0.1192625446156e+02, - 0.9724904869624e-08, 0.6195878564404e+01, 0.2280573557157e+02, - 0.9251628983612e-08, 0.6511509527390e+00, 0.2787043132925e+01, - 0.7320763787842e-08, 0.6001083639421e+01, 0.6282655592598e+01, - 0.7320296650962e-08, 0.3789073265087e+01, 0.6283496108294e+01, - 0.7947032271039e-08, 0.1059659582204e+01, 0.1241073141809e+02, - - 0.9005277053115e-08, 0.1280315624361e+01, 0.6281591679874e+01, - 0.8995601652048e-08, 0.2224439106766e+01, 0.6284560021018e+01, - 0.8288040568796e-08, 0.5234914433867e+01, 0.1241658836951e+02, - 0.6359381347255e-08, 0.4137989441490e+01, 0.1596186371003e+01, - 0.8699572228626e-08, 0.1758411009497e+01, 0.6133512519065e+01, - 0.6456797542736e-08, 0.5919285089994e+01, 0.1685848245639e+02, - 0.7424573475452e-08, 0.5414616938827e+01, 0.4061219149443e+01, - 0.7235671196168e-08, 0.1496516557134e+01, 0.1610006857377e+03, - 0.8104015182733e-08, 0.1919918242764e+01, 0.8460828644453e+00, - 0.8098576535937e-08, 0.3819615855458e+01, 0.3894181736510e+01, - - 0.6275292346625e-08, 0.6244264115141e+01, 0.8531963191132e+00, - 0.6052432989112e-08, 0.5037731872610e+00, 0.1567108171867e+02, - 0.5705651535817e-08, 0.2984557271995e+01, 0.1258692712880e+02, - 0.5789650115138e-08, 0.6087038140697e+01, 0.1193336791622e+02, - 0.5512132153377e-08, 0.5855668994076e+01, 0.1232342296471e+02, - 0.7388890819102e-08, 0.2443128574740e+01, 0.4907302013889e+01, - 0.5467593991798e-08, 0.3017561234194e+01, 0.1884211409667e+02, - 0.6388519802999e-08, 0.5887386712935e+01, 0.5217580628120e+02, - 0.6106777149944e-08, 0.3483461059895e+00, 0.1422690933580e-01, - 0.7383420275489e-08, 0.5417387056707e+01, 0.2358125818164e+02, - - 0.5505208141738e-08, 0.2848193644783e+01, 0.1151388321134e+02, - 0.6310757462877e-08, 0.2349882520828e+01, 0.1041998632314e+02, - 0.6166904929691e-08, 0.5728575944077e+00, 0.6151533897323e+01, - 0.5263442042754e-08, 0.4495796125937e+01, 0.1885275071096e+02, - 0.5591828082629e-08, 0.1355441967677e+01, 0.4337116142245e+00, - 0.5397051680497e-08, 0.1673422864307e+01, 0.6286362197481e+01, - 0.5396992745159e-08, 0.1833502206373e+01, 0.6279789503410e+01, - 0.6572913000726e-08, 0.3331122065824e+01, 0.1176433076753e+02, - 0.5123421866413e-08, 0.2165327142679e+01, 0.1245594543367e+02, - 0.5930495725999e-08, 0.2931146089284e+01, 0.6414617803568e+01, - - 0.6431797403933e-08, 0.4134407994088e+01, 0.1350651127443e+00, - 0.5003182207604e-08, 0.3805420303749e+01, 0.1096996532989e+02, - 0.5587731032504e-08, 0.1082469260599e+01, 0.6062663316000e+01, - 0.5935263407816e-08, 0.8384333678401e+00, 0.5326786718777e+01, - 0.4756019827760e-08, 0.3552588749309e+01, 0.3104930017775e+01, - 0.6599951172637e-08, 0.4320826409528e+01, 0.4087944051283e+02, - 0.5902606868464e-08, 0.4811879454445e+01, 0.5849364236221e+01, - 0.5921147809031e-08, 0.9942628922396e-01, 0.1581959461667e+01, - 0.5505382581266e-08, 0.2466557607764e+01, 0.6503488384892e+01, - 0.5353771071862e-08, 0.4551978748683e+01, 0.1735668374386e+03, - - 0.5063282210946e-08, 0.5710812312425e+01, 0.1248988586463e+02, - 0.5926120403383e-08, 0.1333998428358e+01, 0.2673594526851e+02, - 0.5211016176149e-08, 0.4649315360760e+01, 0.2460261242967e+02, - 0.5347075084894e-08, 0.5512754081205e+01, 0.4171425416666e+01, - 0.4872609773574e-08, 0.1308025299938e+01, 0.5333900173445e+01, - 0.4727711321420e-08, 0.2144908368062e+01, 0.7232251527446e+01, - 0.6029426018652e-08, 0.5567259412084e+01, 0.3227113045244e+03, - 0.4321485284369e-08, 0.5230667156451e+01, 0.9388005868221e+01, - 0.4476406760553e-08, 0.6134081115303e+01, 0.5547199253223e+01, - 0.5835268277420e-08, 0.4783808492071e+01, 0.7285056171570e+02, - - 0.5172183602748e-08, 0.5161817911099e+01, 0.1884570439172e+02, - 0.5693571465184e-08, 0.1381646203111e+01, 0.9723862754494e+02, - 0.4060634965349e-08, 0.3876705259495e+00, 0.4274518229222e+01, - 0.3967398770473e-08, 0.5029491776223e+01, 0.3496032717521e+01, - 0.3943754005255e-08, 0.1923162955490e+01, 0.6244942932314e+01, - 0.4781323427824e-08, 0.4633332586423e+01, 0.2929661536378e+02, - 0.3871483781204e-08, 0.1616650009743e+01, 0.6321208768577e+01, - 0.5141741733997e-08, 0.9817316704659e-01, 0.1232032006293e+02, - 0.4002385978497e-08, 0.3656161212139e+01, 0.7018952447668e+01, - 0.4901092604097e-08, 0.4404098713092e+01, 0.1478866649112e+01, - - 0.3740932630345e-08, 0.5181188732639e+00, 0.6922973089781e+01, - 0.4387283718538e-08, 0.3254859566869e+01, 0.2331413144044e+03, - 0.5019197802033e-08, 0.3086773224677e+01, 0.1715706182245e+02, - 0.3834931695175e-08, 0.2797882673542e+01, 0.1491901785440e+02, - 0.3760413942497e-08, 0.2892676280217e+01, 0.1726726808967e+02, - 0.3719717204628e-08, 0.5861046025739e+01, 0.6297302759782e+01, - 0.4145623530149e-08, 0.2168239627033e+01, 0.1376059875786e+02, - 0.3932788425380e-08, 0.6271811124181e+01, 0.7872148766781e+01, - 0.3686377476857e-08, 0.3936853151404e+01, 0.6268848941110e+01, - 0.3779077950339e-08, 0.1404148734043e+01, 0.4157198507331e+01, - - 0.4091334550598e-08, 0.2452436180854e+01, 0.9779108567966e+01, - 0.3926694536146e-08, 0.6102292739040e+01, 0.1098419223922e+02, - 0.4841000253289e-08, 0.6072760457276e+01, 0.1252801878276e+02, - 0.4949340130240e-08, 0.1154832815171e+01, 0.1617106187867e+03, - 0.3761557737360e-08, 0.5527545321897e+01, 0.3185192151914e+01, - 0.3647396268188e-08, 0.1525035688629e+01, 0.6271346477544e+01, - 0.3932405074189e-08, 0.5570681040569e+01, 0.2139354194808e+02, - 0.3631322501141e-08, 0.1981240601160e+01, 0.6294805223347e+01, - 0.4130007425139e-08, 0.2050060880201e+01, 0.2195415756911e+02, - 0.4433905965176e-08, 0.3277477970321e+01, 0.7445550607224e+01, - - 0.3851814176947e-08, 0.5210690074886e+01, 0.9562891316684e+00, - 0.3485807052785e-08, 0.6653274904611e+00, 0.1161697602389e+02, - 0.3979772816991e-08, 0.1767941436148e+01, 0.2277943724828e+02, - 0.3402607460500e-08, 0.3421746306465e+01, 0.1087398597200e+02, - 0.4049993000926e-08, 0.1127144787547e+01, 0.3163918923335e+00, - 0.3420511182382e-08, 0.4214794779161e+01, 0.1362553364512e+02, - 0.3640772365012e-08, 0.5324905497687e+01, 0.1725304118033e+02, - 0.3323037987501e-08, 0.6135761838271e+01, 0.6279143387820e+01, - 0.4503141663637e-08, 0.1802305450666e+01, 0.1385561574497e+01, - 0.4314560055588e-08, 0.4812299731574e+01, 0.4176041334900e+01, - - 0.3294226949110e-08, 0.3657547059723e+01, 0.6287008313071e+01, - 0.3215657197281e-08, 0.4866676894425e+01, 0.5749861718712e+01, - 0.4129362656266e-08, 0.3809342558906e+01, 0.5905702259363e+01, - 0.3137762976388e-08, 0.2494635174443e+01, 0.2099539292909e+02, - 0.3514010952384e-08, 0.2699961831678e+01, 0.7335344340001e+01, - 0.3327607571530e-08, 0.3318457714816e+01, 0.5436992986000e+01, - 0.3541066946675e-08, 0.4382703582466e+01, 0.1234573916645e+02, - 0.3216179847052e-08, 0.5271066317054e+01, 0.3802769619140e-01, - 0.2959045059570e-08, 0.5819591585302e+01, 0.2670964694522e+02, - 0.3884040326665e-08, 0.5980934960428e+01, 0.6660449441528e+01, - - 0.2922027539886e-08, 0.3337290282483e+01, 0.1375773836557e+01, - 0.4110846382042e-08, 0.5742978187327e+01, 0.4480965020977e+02, - 0.2934508411032e-08, 0.2278075804200e+01, 0.6408777551755e+00, - 0.3966896193000e-08, 0.5835747858477e+01, 0.3773735910827e+00, - 0.3286695827610e-08, 0.5838898193902e+01, 0.3932462625300e-02, - 0.3720643094196e-08, 0.1122212337858e+01, 0.1646033343740e+02, - 0.3285508906174e-08, 0.9182250996416e+00, 0.1081813534213e+02, - 0.3753880575973e-08, 0.5174761973266e+01, 0.5642198095270e+01, - 0.3022129385587e-08, 0.3381611020639e+01, 0.2982630633589e+02, - 0.2798569205621e-08, 0.3546193723922e+01, 0.1937891852345e+02, - - 0.3397872070505e-08, 0.4533203197934e+01, 0.6923953605621e+01, - 0.3708099772977e-08, 0.2756168198616e+01, 0.3066615496545e+02, - 0.3599283541510e-08, 0.1934395469918e+01, 0.6147450479709e+01, - 0.3688702753059e-08, 0.7149920971109e+00, 0.2636725487657e+01, - 0.2681084724003e-08, 0.4899819493154e+01, 0.6816289982179e+01, - 0.3495993460759e-08, 0.1572418915115e+01, 0.6418701221183e+01, - 0.3130770324995e-08, 0.8912190180489e+00, 0.1235996607578e+02, - 0.2744353821941e-08, 0.3800821940055e+01, 0.2059724391010e+02, - 0.2842732906341e-08, 0.2644717440029e+01, 0.2828699048865e+02, - 0.3046882682154e-08, 0.3987793020179e+01, 0.6055599646783e+01, - - 0.2399072455143e-08, 0.9908826440764e+00, 0.6255674361143e+01, - 0.2384306274204e-08, 0.2516149752220e+01, 0.6310477339748e+01, - 0.2977324500559e-08, 0.5849195642118e+01, 0.1652265972112e+02, - 0.3062835258972e-08, 0.1681660100162e+01, 0.1172006883645e+02, - 0.3109682589231e-08, 0.5804143987737e+00, 0.2751146787858e+02, - 0.2903920355299e-08, 0.5800768280123e+01, 0.6510552054109e+01, - 0.2823221989212e-08, 0.9241118370216e+00, 0.5469525544182e+01, - 0.3187949696649e-08, 0.3139776445735e+01, 0.1693792562116e+03, - 0.2922559771655e-08, 0.3549440782984e+01, 0.2630839062450e+00, - 0.2436302066603e-08, 0.4735540696319e+01, 0.3946258593675e+00, - - 0.3049473043606e-08, 0.4998289124561e+01, 0.8390110365991e+01, - 0.2863682575784e-08, 0.6709515671102e+00, 0.2243449970715e+00, - 0.2641750517966e-08, 0.5410978257284e+01, 0.2986433403208e+02, - 0.2704093466243e-08, 0.4778317207821e+01, 0.6129297044991e+01, - 0.2445522177011e-08, 0.6009020662222e+01, 0.1171295538178e+02, - 0.2623608810230e-08, 0.5010449777147e+01, 0.6436854655901e+01, - 0.2079259704053e-08, 0.5980943768809e+01, 0.2019909489111e+02, - 0.2820225596771e-08, 0.2679965110468e+01, 0.5934151399930e+01, - 0.2365221950927e-08, 0.1894231148810e+01, 0.2470570524223e+02, - 0.2359682077149e-08, 0.4220752950780e+01, 0.8671969964381e+01, - - 0.2387577137206e-08, 0.2571783940617e+01, 0.7096626156709e+01, - 0.1982102089816e-08, 0.5169765997119e+00, 0.1727188400790e+02, - 0.2687502389925e-08, 0.6239078264579e+01, 0.7075506709219e+02, - 0.2207751669135e-08, 0.2031184412677e+01, 0.4377611041777e+01, - 0.2618370214274e-08, 0.8266079985979e+00, 0.6632000300961e+01, - 0.2591951887361e-08, 0.8819350522008e+00, 0.4873985990671e+02, - 0.2375055656248e-08, 0.3520944177789e+01, 0.1590676413561e+02, - 0.2472019978911e-08, 0.1551431908671e+01, 0.6612329252343e+00, - 0.2368157127199e-08, 0.4178610147412e+01, 0.3459636466239e+02, - 0.1764846605693e-08, 0.1506764000157e+01, 0.1980094587212e+02, - - 0.2291769608798e-08, 0.2118250611782e+01, 0.2844914056730e-01, - 0.2209997316943e-08, 0.3363255261678e+01, 0.2666070658668e+00, - 0.2292699097923e-08, 0.4200423956460e+00, 0.1484170571900e-02, - 0.1629683015329e-08, 0.2331362582487e+01, 0.3035599730800e+02, - 0.2206492862426e-08, 0.3400274026992e+01, 0.6281667977667e+01, - 0.2205746568257e-08, 0.1066051230724e+00, 0.6284483723224e+01, - 0.2026310767991e-08, 0.2779066487979e+01, 0.2449240616245e+02, - 0.1762977622163e-08, 0.9951450691840e+00, 0.2045286941806e+02, - 0.1368535049606e-08, 0.6402447365817e+00, 0.2473415438279e+02, - 0.1720598775450e-08, 0.2303524214705e+00, 0.1679593901136e+03, - - 0.1702429015449e-08, 0.6164622655048e+01, 0.3338575901272e+03, - 0.1414033197685e-08, 0.3954561185580e+01, 0.1624205518357e+03, - 0.1573768958043e-08, 0.2028286308984e+01, 0.3144167757552e+02, - 0.1650705184447e-08, 0.2304040666128e+01, 0.5267006960365e+02, - 0.1651087618855e-08, 0.2538461057280e+01, 0.8956999012000e+02, - 0.1616409518983e-08, 0.5111054348152e+01, 0.3332657872986e+02, - 0.1537175173581e-08, 0.5601130666603e+01, 0.3852657435933e+02, - 0.1593191980553e-08, 0.2614340453411e+01, 0.2282781046519e+03, - 0.1499480170643e-08, 0.3624721577264e+01, 0.2823723341956e+02, - 0.1493807843235e-08, 0.4214569879008e+01, 0.2876692439167e+02, - - 0.1074571199328e-08, 0.1496911744704e+00, 0.8397383534231e+02, - 0.1074406983417e-08, 0.1187817671922e+01, 0.8401985929482e+02, - 0.9757576855851e-09, 0.2655703035858e+01, 0.7826370942180e+02, - 0.1258432887565e-08, 0.4969896184844e+01, 0.3115650189215e+03, - 0.1240336343282e-08, 0.5192460776926e+01, 0.1784300471910e+03, - 0.9016107005164e-09, 0.1960356923057e+01, 0.5886454391678e+02, - 0.1135392360918e-08, 0.5082427809068e+01, 0.7842370451713e+02, - 0.9216046089565e-09, 0.2793775037273e+01, 0.1014262087719e+03, - 0.1061276615030e-08, 0.3726144311409e+01, 0.5660027930059e+02, - 0.1010110596263e-08, 0.7404080708937e+00, 0.4245678405627e+02, - - 0.7217424756199e-09, 0.2697449980577e-01, 0.2457074661053e+03, - 0.6912003846756e-09, 0.4253296276335e+01, 0.1679936946371e+03, - 0.6871814664847e-09, 0.5148072412354e+01, 0.6053048899753e+02, - 0.4887158016343e-09, 0.2153581148294e+01, 0.9656299901946e+02, - 0.5161802866314e-09, 0.3852750634351e+01, 0.2442876000072e+03, - 0.5652599559057e-09, 0.1233233356270e+01, 0.8365903305582e+02, - 0.4710812608586e-09, 0.5610486976767e+01, 0.3164282286739e+03, - 0.4909977500324e-09, 0.1639629524123e+01, 0.4059982187939e+03, - 0.4772641839378e-09, 0.3737100368583e+01, 0.1805255418145e+03, - 0.4487562567153e-09, 0.1158417054478e+00, 0.8433466158131e+02, - - 0.3943441230497e-09, 0.6243502862796e+00, 0.2568537517081e+03, - 0.3952236913598e-09, 0.3510377382385e+01, 0.2449975330562e+03, - 0.3788898363417e-09, 0.5916128302299e+01, 0.1568131045107e+03, - 0.3738329328831e-09, 0.1042266763456e+01, 0.3948519331910e+03, - 0.2451199165151e-09, 0.1166788435700e+01, 0.1435713242844e+03, - 0.2436734402904e-09, 0.3254726114901e+01, 0.2268582385539e+03, - 0.2213605274325e-09, 0.1687210598530e+01, 0.1658638954901e+03, - 0.1491521204829e-09, 0.2657541786794e+01, 0.2219950288015e+03, - 0.1474995329744e-09, 0.5013089805819e+01, 0.3052819430710e+03, - 0.1661939475656e-09, 0.5495315428418e+01, 0.2526661704812e+03, - - 0.9015946748003e-10, 0.2236989966505e+01, 0.4171445043968e+03 }; - -/* Sun-to-Earth, T^0, Z */ - static const double e0z[] = { - 0.2796207639075e-05, 0.3198701560209e+01, 0.8433466158131e+02, - 0.1016042198142e-05, 0.5422360395913e+01, 0.5507553240374e+01, - 0.8044305033647e-06, 0.3880222866652e+01, 0.5223693906222e+01, - 0.4385347909274e-06, 0.3704369937468e+01, 0.2352866153506e+01, - 0.3186156414906e-06, 0.3999639363235e+01, 0.1577343543434e+01, - 0.2272412285792e-06, 0.3984738315952e+01, 0.1047747311755e+01, - 0.1645620103007e-06, 0.3565412516841e+01, 0.5856477690889e+01, - 0.1815836921166e-06, 0.4984507059020e+01, 0.6283075850446e+01, - 0.1447461676364e-06, 0.3702753570108e+01, 0.9437762937313e+01, - 0.1430760876382e-06, 0.3409658712357e+01, 0.1021328554739e+02, - - 0.1120445753226e-06, 0.4829561570246e+01, 0.1414349524433e+02, - 0.1090232840797e-06, 0.2080729178066e+01, 0.6812766822558e+01, - 0.9715727346551e-07, 0.3476295881948e+01, 0.4694002934110e+01, - 0.1036267136217e-06, 0.4056639536648e+01, 0.7109288135493e+02, - 0.8752665271340e-07, 0.4448159519911e+01, 0.5753384878334e+01, - 0.8331864956004e-07, 0.4991704044208e+01, 0.7084896783808e+01, - 0.6901658670245e-07, 0.4325358994219e+01, 0.6275962395778e+01, - 0.9144536848998e-07, 0.1141826375363e+01, 0.6620890113188e+01, - 0.7205085037435e-07, 0.3624344170143e+01, 0.5296909721118e+00, - 0.7697874654176e-07, 0.5554257458998e+01, 0.1676215758509e+03, - - 0.5197545738384e-07, 0.6251760961735e+01, 0.1807370494127e+02, - 0.5031345378608e-07, 0.2497341091913e+01, 0.4705732307012e+01, - 0.4527110205840e-07, 0.2335079920992e+01, 0.6309374173736e+01, - 0.4753355798089e-07, 0.7094148987474e+00, 0.5884926831456e+01, - 0.4296951977516e-07, 0.1101916352091e+01, 0.6681224869435e+01, - 0.3855341568387e-07, 0.1825495405486e+01, 0.5486777812467e+01, - 0.5253930970990e-07, 0.4424740687208e+01, 0.7860419393880e+01, - 0.4024630496471e-07, 0.5120498157053e+01, 0.1336797263425e+02, - 0.4061069791453e-07, 0.6029771435451e+01, 0.3930209696940e+01, - 0.3797883804205e-07, 0.4435193600836e+00, 0.3154687086868e+01, - - 0.2933033225587e-07, 0.5124157356507e+01, 0.1059381944224e+01, - 0.3503000930426e-07, 0.5421830162065e+01, 0.6069776770667e+01, - 0.3670096214050e-07, 0.4582101667297e+01, 0.1219403291462e+02, - 0.2905609437008e-07, 0.1926566420072e+01, 0.1097707878456e+02, - 0.2466827821713e-07, 0.6090174539834e+00, 0.6496374930224e+01, - 0.2691647295332e-07, 0.1393432595077e+01, 0.2200391463820e+02, - 0.2150554667946e-07, 0.4308671715951e+01, 0.5643178611111e+01, - 0.2237481922680e-07, 0.8133968269414e+00, 0.8635942003952e+01, - 0.1817741038157e-07, 0.3755205127454e+01, 0.3340612434717e+01, - 0.2227820762132e-07, 0.2759558596664e+01, 0.1203646072878e+02, - - 0.1944713772307e-07, 0.5699645869121e+01, 0.1179062909082e+02, - 0.1527340520662e-07, 0.1986749091746e+01, 0.3981490189893e+00, - 0.1577282574914e-07, 0.3205017217983e+01, 0.5088628793478e+01, - 0.1424738825424e-07, 0.6256747903666e+01, 0.2544314396739e+01, - 0.1616563121701e-07, 0.2601671259394e+00, 0.1729818233119e+02, - 0.1401210391692e-07, 0.4686939173506e+01, 0.7058598460518e+01, - 0.1488726974214e-07, 0.2815862451372e+01, 0.2593412433514e+02, - 0.1692626442388e-07, 0.4956894109797e+01, 0.1564752902480e+03, - 0.1123571582910e-07, 0.2381192697696e+01, 0.3738761453707e+01, - 0.9903308606317e-08, 0.4294851657684e+01, 0.9225539266174e+01, - - 0.9174533187191e-08, 0.3075171510642e+01, 0.4164311961999e+01, - 0.8645985631457e-08, 0.5477534821633e+00, 0.8429241228195e+01, - -0.1085876492688e-07, 0.0000000000000e+00, 0.0000000000000e+00, - 0.9264309077815e-08, 0.5968571670097e+01, 0.7079373888424e+01, - 0.8243116984954e-08, 0.1489098777643e+01, 0.1044738781244e+02, - 0.8268102113708e-08, 0.3512977691983e+01, 0.1150676975667e+02, - 0.9043613988227e-08, 0.1290704408221e+00, 0.1101510648075e+02, - 0.7432912038789e-08, 0.1991086893337e+01, 0.2608790314060e+02, - 0.8586233727285e-08, 0.4238357924414e+01, 0.2986433403208e+02, - 0.7612230060131e-08, 0.2911090150166e+01, 0.4732030630302e+01, - - 0.7097787751408e-08, 0.1908938392390e+01, 0.8031092209206e+01, - 0.7640237040175e-08, 0.6129219000168e+00, 0.7962980379786e+00, - 0.7070445688081e-08, 0.1380417036651e+01, 0.2146165377750e+01, - 0.7690770957702e-08, 0.1680504249084e+01, 0.2122839202813e+02, - 0.8051292542594e-08, 0.5127423484511e+01, 0.2942463415728e+01, - 0.5902709104515e-08, 0.2020274190917e+01, 0.7755226100720e+00, - 0.5134567496462e-08, 0.2606778676418e+01, 0.1256615170089e+02, - 0.5525802046102e-08, 0.1613011769663e+01, 0.8018209333619e+00, - 0.5880724784221e-08, 0.4604483417236e+01, 0.4690479774488e+01, - 0.5211699081370e-08, 0.5718964114193e+01, 0.8827390247185e+01, - - 0.4891849573562e-08, 0.3689658932196e+01, 0.2132990797783e+00, - 0.5150246069997e-08, 0.4099769855122e+01, 0.6480980550449e+02, - 0.5102434319633e-08, 0.5660834602509e+01, 0.3379454372902e+02, - 0.5083405254252e-08, 0.9842221218974e+00, 0.4136910472696e+01, - 0.4206562585682e-08, 0.1341363634163e+00, 0.3128388763578e+01, - 0.4663249683579e-08, 0.8130132735866e+00, 0.5216580451554e+01, - 0.4099474416530e-08, 0.5791497770644e+01, 0.4265981595566e+00, - 0.4628251220767e-08, 0.1249802769331e+01, 0.1572083878776e+02, - 0.5024068728142e-08, 0.4795684802743e+01, 0.6290189305114e+01, - 0.5120234327758e-08, 0.3810420387208e+01, 0.5230807360890e+01, - - 0.5524029815280e-08, 0.1029264714351e+01, 0.2397622045175e+03, - 0.4757415718860e-08, 0.3528044781779e+01, 0.1649636139783e+02, - 0.3915786131127e-08, 0.5593889282646e+01, 0.1589072916335e+01, - 0.4869053149991e-08, 0.3299636454433e+01, 0.7632943190217e+01, - 0.3649365703729e-08, 0.1286049002584e+01, 0.6206810014183e+01, - 0.3992493949002e-08, 0.3100307589464e+01, 0.2515860172507e+02, - 0.3320247477418e-08, 0.6212683940807e+01, 0.1216800268190e+02, - 0.3287123739696e-08, 0.4699118445928e+01, 0.7234794171227e+01, - 0.3472776811103e-08, 0.2630507142004e+01, 0.7342457794669e+01, - 0.3423253294767e-08, 0.2946432844305e+01, 0.9623688285163e+01, - - 0.3896173898244e-08, 0.1224834179264e+01, 0.6438496133249e+01, - 0.3388455337924e-08, 0.1543807616351e+01, 0.1494531617769e+02, - 0.3062704716523e-08, 0.1191777572310e+01, 0.8662240327241e+01, - 0.3270075600400e-08, 0.5483498767737e+01, 0.1194447056968e+01, - 0.3101209215259e-08, 0.8000833804348e+00, 0.3772475342596e+02, - 0.2780883347311e-08, 0.4077980721888e+00, 0.5863591145557e+01, - 0.2903605931824e-08, 0.2617490302147e+01, 0.1965104848470e+02, - 0.2682014743119e-08, 0.2634703158290e+01, 0.7238675589263e+01, - 0.2534360108492e-08, 0.6102446114873e+01, 0.6836645152238e+01, - 0.2392564882509e-08, 0.3681820208691e+01, 0.5849364236221e+01, - - 0.2656667254856e-08, 0.6216045388886e+01, 0.6133512519065e+01, - 0.2331242096773e-08, 0.5864949777744e+01, 0.4535059491685e+01, - 0.2287898363668e-08, 0.4566628532802e+01, 0.7477522907414e+01, - 0.2336944521306e-08, 0.2442722126930e+01, 0.1137170464392e+02, - 0.3156632236269e-08, 0.1626628050682e+01, 0.2509084901204e+03, - 0.2982612402766e-08, 0.2803604512609e+01, 0.1748016358760e+01, - 0.2774031674807e-08, 0.4654002897158e+01, 0.8223916695780e+02, - 0.2295236548638e-08, 0.4326518333253e+01, 0.3378142627421e+00, - 0.2190714699873e-08, 0.4519614578328e+01, 0.2908881142201e+02, - 0.2191495845045e-08, 0.3012626912549e+01, 0.1673046366289e+02, - - 0.2492901628386e-08, 0.1290101424052e+00, 0.1543797956245e+03, - 0.1993778064319e-08, 0.3864046799414e+01, 0.1778984560711e+02, - 0.1898146479022e-08, 0.5053777235891e+01, 0.2042657109477e+02, - 0.1918280127634e-08, 0.2222470192548e+01, 0.4165496312290e+02, - 0.1916351061607e-08, 0.8719067257774e+00, 0.7737595720538e+02, - 0.1834720181466e-08, 0.4031491098040e+01, 0.2358125818164e+02, - 0.1249201523806e-08, 0.5938379466835e+01, 0.3301902111895e+02, - 0.1477304050539e-08, 0.6544722606797e+00, 0.9548094718417e+02, - 0.1264316431249e-08, 0.2059072853236e+01, 0.8399684731857e+02, - 0.1203526495039e-08, 0.3644813532605e+01, 0.4558517281984e+02, - - 0.9221681059831e-09, 0.3241815055602e+01, 0.7805158573086e+02, - 0.7849278367646e-09, 0.5043812342457e+01, 0.5217580628120e+02, - 0.7983392077387e-09, 0.5000024502753e+01, 0.1501922143975e+03, - 0.7925395431654e-09, 0.1398734871821e-01, 0.9061773743175e+02, - 0.7640473285886e-09, 0.5067111723130e+01, 0.4951538251678e+02, - 0.5398937754482e-09, 0.5597382200075e+01, 0.1613385000004e+03, - 0.5626247550193e-09, 0.2601338209422e+01, 0.7318837597844e+02, - 0.5525197197855e-09, 0.5814832109256e+01, 0.1432335100216e+03, - 0.5407629837898e-09, 0.3384820609076e+01, 0.3230491187871e+03, - 0.3856739119801e-09, 0.1072391840473e+01, 0.2334791286671e+03, - - 0.3856425239987e-09, 0.2369540393327e+01, 0.1739046517013e+03, - 0.4350867755983e-09, 0.5255575751082e+01, 0.1620484330494e+03, - 0.3844113924996e-09, 0.5482356246182e+01, 0.9757644180768e+02, - 0.2854869155431e-09, 0.9573634763143e+00, 0.1697170704744e+03, - 0.1719227671416e-09, 0.1887203025202e+01, 0.2265204242912e+03, - 0.1527846879755e-09, 0.3982183931157e+01, 0.3341954043900e+03, - 0.1128229264847e-09, 0.2787457156298e+01, 0.3119028331842e+03 }; - -/* Sun-to-Earth, T^1, X */ - static const double e1x[] = { - 0.1234046326004e-05, 0.0000000000000e+00, 0.0000000000000e+00, - 0.5150068824701e-06, 0.6002664557501e+01, 0.1256615170089e+02, - 0.1290743923245e-07, 0.5959437664199e+01, 0.1884922755134e+02, - 0.1068615564952e-07, 0.2015529654209e+01, 0.6283075850446e+01, - 0.2079619142538e-08, 0.1732960531432e+01, 0.6279552690824e+01, - 0.2078009243969e-08, 0.4915604476996e+01, 0.6286599010068e+01, - 0.6206330058856e-09, 0.3616457953824e+00, 0.4705732307012e+01, - 0.5989335313746e-09, 0.3802607304474e+01, 0.6256777527156e+01, - 0.5958495663840e-09, 0.2845866560031e+01, 0.6309374173736e+01, - 0.4866923261539e-09, 0.5213203771824e+01, 0.7755226100720e+00, - - 0.4267785823142e-09, 0.4368189727818e+00, 0.1059381944224e+01, - 0.4610675141648e-09, 0.1837249181372e-01, 0.7860419393880e+01, - 0.3626989993973e-09, 0.2161590545326e+01, 0.5753384878334e+01, - 0.3563071194389e-09, 0.1452631954746e+01, 0.5884926831456e+01, - 0.3557015642807e-09, 0.4470593393054e+01, 0.6812766822558e+01, - 0.3210412089122e-09, 0.5195926078314e+01, 0.6681224869435e+01, - 0.2875473577986e-09, 0.5916256610193e+01, 0.2513230340178e+02, - 0.2842913681629e-09, 0.1149902426047e+01, 0.6127655567643e+01, - 0.2751248215916e-09, 0.5502088574662e+01, 0.6438496133249e+01, - 0.2481432881127e-09, 0.2921989846637e+01, 0.5486777812467e+01, - - 0.2059885976560e-09, 0.3718070376585e+01, 0.7079373888424e+01, - 0.2015522342591e-09, 0.5979395259740e+01, 0.6290189305114e+01, - 0.1995364084253e-09, 0.6772087985494e+00, 0.6275962395778e+01, - 0.1957436436943e-09, 0.2899210654665e+01, 0.5507553240374e+01, - 0.1651609818948e-09, 0.6228206482192e+01, 0.1150676975667e+02, - 0.1822980550699e-09, 0.1469348746179e+01, 0.1179062909082e+02, - 0.1675223159760e-09, 0.3813910555688e+01, 0.7058598460518e+01, - 0.1706491764745e-09, 0.3004380506684e+00, 0.7113454667900e-02, - 0.1392952362615e-09, 0.1440393973406e+01, 0.7962980379786e+00, - 0.1209868266342e-09, 0.4150425791727e+01, 0.4694002934110e+01, - - 0.1009827202611e-09, 0.3290040429843e+01, 0.3738761453707e+01, - 0.1047261388602e-09, 0.4229590090227e+01, 0.6282095334605e+01, - 0.1047006652004e-09, 0.2418967680575e+01, 0.6284056366286e+01, - 0.9609993143095e-10, 0.4627943659201e+01, 0.6069776770667e+01, - 0.9590900593873e-10, 0.1894393939924e+01, 0.4136910472696e+01, - 0.9146249188071e-10, 0.2010647519562e+01, 0.6496374930224e+01, - 0.8545274480290e-10, 0.5529846956226e-01, 0.1194447056968e+01, - 0.8224377881194e-10, 0.1254304102174e+01, 0.1589072916335e+01, - 0.6183529510410e-10, 0.3360862168815e+01, 0.8827390247185e+01, - 0.6259255147141e-10, 0.4755628243179e+01, 0.8429241228195e+01, - - 0.5539291694151e-10, 0.5371746955142e+01, 0.4933208510675e+01, - 0.7328259466314e-10, 0.4927699613906e+00, 0.4535059491685e+01, - 0.6017835843560e-10, 0.5776682001734e-01, 0.1255903824622e+02, - 0.7079827775243e-10, 0.4395059432251e+01, 0.5088628793478e+01, - 0.5170358878213e-10, 0.5154062619954e+01, 0.1176985366291e+02, - 0.4872301838682e-10, 0.6289611648973e+00, 0.6040347114260e+01, - 0.5249869411058e-10, 0.5617272046949e+01, 0.3154687086868e+01, - 0.4716172354411e-10, 0.3965901800877e+01, 0.5331357529664e+01, - 0.4871214940964e-10, 0.4627507050093e+01, 0.1256967486051e+02, - 0.4598076850751e-10, 0.6023631226459e+01, 0.6525804586632e+01, - - 0.4562196089485e-10, 0.4138562084068e+01, 0.3930209696940e+01, - 0.4325493872224e-10, 0.1330845906564e+01, 0.7632943190217e+01, - 0.5673781176748e-10, 0.2558752615657e+01, 0.5729506548653e+01, - 0.3961436642503e-10, 0.2728071734630e+01, 0.7234794171227e+01, - 0.5101868209058e-10, 0.4113444965144e+01, 0.6836645152238e+01, - 0.5257043167676e-10, 0.6195089830590e+01, 0.8031092209206e+01, - 0.5076613989393e-10, 0.2305124132918e+01, 0.7477522907414e+01, - 0.3342169352778e-10, 0.5415998155071e+01, 0.1097707878456e+02, - 0.3545881983591e-10, 0.3727160564574e+01, 0.4164311961999e+01, - 0.3364063738599e-10, 0.2901121049204e+00, 0.1137170464392e+02, - - 0.3357039670776e-10, 0.1652229354331e+01, 0.5223693906222e+01, - 0.4307412268687e-10, 0.4938909587445e+01, 0.1592596075957e+01, - 0.3405769115435e-10, 0.2408890766511e+01, 0.3128388763578e+01, - 0.3001926198480e-10, 0.4862239006386e+01, 0.1748016358760e+01, - 0.2778264787325e-10, 0.5241168661353e+01, 0.7342457794669e+01, - 0.2676159480666e-10, 0.3423593942199e+01, 0.2146165377750e+01, - 0.2954273399939e-10, 0.1881721265406e+01, 0.5368044267797e+00, - 0.3309362888795e-10, 0.1931525677349e+01, 0.8018209333619e+00, - 0.2810283608438e-10, 0.2414659495050e+01, 0.5225775174439e+00, - 0.3378045637764e-10, 0.4238019163430e+01, 0.1554202828031e+00, - - 0.2558134979840e-10, 0.1828225235805e+01, 0.5230807360890e+01, - 0.2273755578447e-10, 0.5858184283998e+01, 0.7084896783808e+01, - 0.2294176037690e-10, 0.4514589779057e+01, 0.1726015463500e+02, - 0.2533506099435e-10, 0.2355717851551e+01, 0.5216580451554e+01, - 0.2716685375812e-10, 0.2221003625100e+01, 0.8635942003952e+01, - 0.2419043435198e-10, 0.5955704951635e+01, 0.4690479774488e+01, - 0.2521232544812e-10, 0.1395676848521e+01, 0.5481254917084e+01, - 0.2630195021491e-10, 0.5727468918743e+01, 0.2629832328990e-01, - 0.2548395840944e-10, 0.2628351859400e-03, 0.1349867339771e+01 }; - -/* Sun-to-Earth, T^1, Y */ - static const double e1y[] = { - 0.9304690546528e-06, 0.0000000000000e+00, 0.0000000000000e+00, - 0.5150715570663e-06, 0.4431807116294e+01, 0.1256615170089e+02, - 0.1290825411056e-07, 0.4388610039678e+01, 0.1884922755134e+02, - 0.4645466665386e-08, 0.5827263376034e+01, 0.6283075850446e+01, - 0.2079625310718e-08, 0.1621698662282e+00, 0.6279552690824e+01, - 0.2078189850907e-08, 0.3344713435140e+01, 0.6286599010068e+01, - 0.6207190138027e-09, 0.5074049319576e+01, 0.4705732307012e+01, - 0.5989826532569e-09, 0.2231842216620e+01, 0.6256777527156e+01, - 0.5961360812618e-09, 0.1274975769045e+01, 0.6309374173736e+01, - 0.4874165471016e-09, 0.3642277426779e+01, 0.7755226100720e+00, - - 0.4283834034360e-09, 0.5148765510106e+01, 0.1059381944224e+01, - 0.4652389287529e-09, 0.4715794792175e+01, 0.7860419393880e+01, - 0.3751707476401e-09, 0.6617207370325e+00, 0.5753384878334e+01, - 0.3559998806198e-09, 0.6155548875404e+01, 0.5884926831456e+01, - 0.3558447558857e-09, 0.2898827297664e+01, 0.6812766822558e+01, - 0.3211116927106e-09, 0.3625813502509e+01, 0.6681224869435e+01, - 0.2875609914672e-09, 0.4345435813134e+01, 0.2513230340178e+02, - 0.2843109704069e-09, 0.5862263940038e+01, 0.6127655567643e+01, - 0.2744676468427e-09, 0.3926419475089e+01, 0.6438496133249e+01, - 0.2481285237789e-09, 0.1351976572828e+01, 0.5486777812467e+01, - - 0.2060338481033e-09, 0.2147556998591e+01, 0.7079373888424e+01, - 0.2015822358331e-09, 0.4408358972216e+01, 0.6290189305114e+01, - 0.2001195944195e-09, 0.5385829822531e+01, 0.6275962395778e+01, - 0.1953667642377e-09, 0.1304933746120e+01, 0.5507553240374e+01, - 0.1839744078713e-09, 0.6173567228835e+01, 0.1179062909082e+02, - 0.1643334294845e-09, 0.4635942997523e+01, 0.1150676975667e+02, - 0.1768051018652e-09, 0.5086283558874e+01, 0.7113454667900e-02, - 0.1674874205489e-09, 0.2243332137241e+01, 0.7058598460518e+01, - 0.1421445397609e-09, 0.6186899771515e+01, 0.7962980379786e+00, - 0.1255163958267e-09, 0.5730238465658e+01, 0.4694002934110e+01, - - 0.1013945281961e-09, 0.1726055228402e+01, 0.3738761453707e+01, - 0.1047294335852e-09, 0.2658801228129e+01, 0.6282095334605e+01, - 0.1047103879392e-09, 0.8481047835035e+00, 0.6284056366286e+01, - 0.9530343962826e-10, 0.3079267149859e+01, 0.6069776770667e+01, - 0.9604637611690e-10, 0.3258679792918e+00, 0.4136910472696e+01, - 0.9153518537177e-10, 0.4398599886584e+00, 0.6496374930224e+01, - 0.8562458214922e-10, 0.4772686794145e+01, 0.1194447056968e+01, - 0.8232525360654e-10, 0.5966220721679e+01, 0.1589072916335e+01, - 0.6150223411438e-10, 0.1780985591923e+01, 0.8827390247185e+01, - 0.6272087858000e-10, 0.3184305429012e+01, 0.8429241228195e+01, - - 0.5540476311040e-10, 0.3801260595433e+01, 0.4933208510675e+01, - 0.7331901699361e-10, 0.5205948591865e+01, 0.4535059491685e+01, - 0.6018528702791e-10, 0.4770139083623e+01, 0.1255903824622e+02, - 0.5150530724804e-10, 0.3574796899585e+01, 0.1176985366291e+02, - 0.6471933741811e-10, 0.2679787266521e+01, 0.5088628793478e+01, - 0.5317460644174e-10, 0.9528763345494e+00, 0.3154687086868e+01, - 0.4832187748783e-10, 0.5329322498232e+01, 0.6040347114260e+01, - 0.4716763555110e-10, 0.2395235316466e+01, 0.5331357529664e+01, - 0.4871509139861e-10, 0.3056663648823e+01, 0.1256967486051e+02, - 0.4598417696768e-10, 0.4452762609019e+01, 0.6525804586632e+01, - - 0.5674189533175e-10, 0.9879680872193e+00, 0.5729506548653e+01, - 0.4073560328195e-10, 0.5939127696986e+01, 0.7632943190217e+01, - 0.5040994945359e-10, 0.4549875824510e+01, 0.8031092209206e+01, - 0.5078185134679e-10, 0.7346659893982e+00, 0.7477522907414e+01, - 0.3769343537061e-10, 0.1071317188367e+01, 0.7234794171227e+01, - 0.4980331365299e-10, 0.2500345341784e+01, 0.6836645152238e+01, - 0.3458236594757e-10, 0.3825159450711e+01, 0.1097707878456e+02, - 0.3578859493602e-10, 0.5299664791549e+01, 0.4164311961999e+01, - 0.3370504646419e-10, 0.5002316301593e+01, 0.1137170464392e+02, - 0.3299873338428e-10, 0.2526123275282e+01, 0.3930209696940e+01, - - 0.4304917318409e-10, 0.3368078557132e+01, 0.1592596075957e+01, - 0.3402418753455e-10, 0.8385495425800e+00, 0.3128388763578e+01, - 0.2778460572146e-10, 0.3669905203240e+01, 0.7342457794669e+01, - 0.2782710128902e-10, 0.2691664812170e+00, 0.1748016358760e+01, - 0.2711725179646e-10, 0.4707487217718e+01, 0.5296909721118e+00, - 0.2981760946340e-10, 0.3190260867816e+00, 0.5368044267797e+00, - 0.2811672977772e-10, 0.3196532315372e+01, 0.7084896783808e+01, - 0.2863454474467e-10, 0.2263240324780e+00, 0.5223693906222e+01, - 0.3333464634051e-10, 0.3498451685065e+01, 0.8018209333619e+00, - 0.3312991747609e-10, 0.5839154477412e+01, 0.1554202828031e+00, - - 0.2813255564006e-10, 0.8268044346621e+00, 0.5225775174439e+00, - 0.2665098083966e-10, 0.3934021725360e+01, 0.5216580451554e+01, - 0.2349795705216e-10, 0.5197620913779e+01, 0.2146165377750e+01, - 0.2330352293961e-10, 0.2984999231807e+01, 0.1726015463500e+02, - 0.2728001683419e-10, 0.6521679638544e+00, 0.8635942003952e+01, - 0.2484061007669e-10, 0.3468955561097e+01, 0.5230807360890e+01, - 0.2646328768427e-10, 0.1013724533516e+01, 0.2629832328990e-01, - 0.2518630264831e-10, 0.6108081057122e+01, 0.5481254917084e+01, - 0.2421901455384e-10, 0.1651097776260e+01, 0.1349867339771e+01, - 0.6348533267831e-11, 0.3220226560321e+01, 0.8433466158131e+02 }; - -/* Sun-to-Earth, T^1, Z */ - static const double e1z[] = { - 0.2278290449966e-05, 0.3413716033863e+01, 0.6283075850446e+01, - 0.5429458209830e-07, 0.0000000000000e+00, 0.0000000000000e+00, - 0.1903240492525e-07, 0.3370592358297e+01, 0.1256615170089e+02, - 0.2385409276743e-09, 0.3327914718416e+01, 0.1884922755134e+02, - 0.8676928342573e-10, 0.1824006811264e+01, 0.5223693906222e+01, - 0.7765442593544e-10, 0.3888564279247e+01, 0.5507553240374e+01, - 0.7066158332715e-10, 0.5194267231944e+01, 0.2352866153506e+01, - 0.7092175288657e-10, 0.2333246960021e+01, 0.8399684731857e+02, - 0.5357582213535e-10, 0.2224031176619e+01, 0.5296909721118e+00, - 0.3828035865021e-10, 0.2156710933584e+01, 0.6279552690824e+01, - - 0.3824857220427e-10, 0.1529755219915e+01, 0.6286599010068e+01, - 0.3286995181628e-10, 0.4879512900483e+01, 0.1021328554739e+02 }; - -/* Sun-to-Earth, T^2, X */ - static const double e2x[] = { - -0.4143818297913e-10, 0.0000000000000e+00, 0.0000000000000e+00, - 0.2171497694435e-10, 0.4398225628264e+01, 0.1256615170089e+02, - 0.9845398442516e-11, 0.2079720838384e+00, 0.6283075850446e+01, - 0.9256833552682e-12, 0.4191264694361e+01, 0.1884922755134e+02, - 0.1022049384115e-12, 0.5381133195658e+01, 0.8399684731857e+02 }; - -/* Sun-to-Earth, T^2, Y */ - static const double e2y[] = { - 0.5063375872532e-10, 0.0000000000000e+00, 0.0000000000000e+00, - 0.2173815785980e-10, 0.2827805833053e+01, 0.1256615170089e+02, - 0.1010231999920e-10, 0.4634612377133e+01, 0.6283075850446e+01, - 0.9259745317636e-12, 0.2620612076189e+01, 0.1884922755134e+02, - 0.1022202095812e-12, 0.3809562326066e+01, 0.8399684731857e+02 }; - -/* Sun-to-Earth, T^2, Z */ - static const double e2z[] = { - 0.9722666114891e-10, 0.5152219582658e+01, 0.6283075850446e+01, - -0.3494819171909e-11, 0.0000000000000e+00, 0.0000000000000e+00, - 0.6713034376076e-12, 0.6440188750495e+00, 0.1256615170089e+02 }; - -/* SSB-to-Sun, T^0, X */ - static const double s0x[] = { - 0.4956757536410e-02, 0.3741073751789e+01, 0.5296909721118e+00, - 0.2718490072522e-02, 0.4016011511425e+01, 0.2132990797783e+00, - 0.1546493974344e-02, 0.2170528330642e+01, 0.3813291813120e-01, - 0.8366855276341e-03, 0.2339614075294e+01, 0.7478166569050e-01, - 0.2936777942117e-03, 0.0000000000000e+00, 0.0000000000000e+00, - 0.1201317439469e-03, 0.4090736353305e+01, 0.1059381944224e+01, - 0.7578550887230e-04, 0.3241518088140e+01, 0.4265981595566e+00, - 0.1941787367773e-04, 0.1012202064330e+01, 0.2061856251104e+00, - 0.1889227765991e-04, 0.3892520416440e+01, 0.2204125344462e+00, - 0.1937896968613e-04, 0.4797779441161e+01, 0.1495633313810e+00, - - 0.1434506110873e-04, 0.3868960697933e+01, 0.5225775174439e+00, - 0.1406659911580e-04, 0.4759766557397e+00, 0.5368044267797e+00, - 0.1179022300202e-04, 0.7774961520598e+00, 0.7626583626240e-01, - 0.8085864460959e-05, 0.3254654471465e+01, 0.3664874755930e-01, - 0.7622752967615e-05, 0.4227633103489e+01, 0.3961708870310e-01, - 0.6209171139066e-05, 0.2791828325711e+00, 0.7329749511860e-01, - 0.4366435633970e-05, 0.4440454875925e+01, 0.1589072916335e+01, - 0.3792124889348e-05, 0.5156393842356e+01, 0.7113454667900e-02, - 0.3154548963402e-05, 0.6157005730093e+01, 0.4194847048887e+00, - 0.3088359882942e-05, 0.2494567553163e+01, 0.6398972393349e+00, - - 0.2788440902136e-05, 0.4934318747989e+01, 0.1102062672231e+00, - 0.3039928456376e-05, 0.4895077702640e+01, 0.6283075850446e+01, - 0.2272258457679e-05, 0.5278394064764e+01, 0.1030928125552e+00, - 0.2162007057957e-05, 0.5802978019099e+01, 0.3163918923335e+00, - 0.1767632855737e-05, 0.3415346595193e-01, 0.1021328554739e+02, - 0.1349413459362e-05, 0.2001643230755e+01, 0.1484170571900e-02, - 0.1170141900476e-05, 0.2424750491620e+01, 0.6327837846670e+00, - 0.1054355266820e-05, 0.3123311487576e+01, 0.4337116142245e+00, - 0.9800822461610e-06, 0.3026258088130e+01, 0.1052268489556e+01, - 0.1091203749931e-05, 0.3157811670347e+01, 0.1162474756779e+01, - - 0.6960236715913e-06, 0.8219570542313e+00, 0.1066495398892e+01, - 0.5689257296909e-06, 0.1323052375236e+01, 0.9491756770005e+00, - 0.6613172135802e-06, 0.2765348881598e+00, 0.8460828644453e+00, - 0.6277702517571e-06, 0.5794064466382e+01, 0.1480791608091e+00, - 0.6304884066699e-06, 0.7323555380787e+00, 0.2243449970715e+00, - 0.4897850467382e-06, 0.3062464235399e+01, 0.3340612434717e+01, - 0.3759148598786e-06, 0.4588290469664e+01, 0.3516457698740e-01, - 0.3110520548195e-06, 0.1374299536572e+01, 0.6373574839730e-01, - 0.3064708359780e-06, 0.4222267485047e+01, 0.1104591729320e-01, - 0.2856347168241e-06, 0.3714202944973e+01, 0.1510475019529e+00, - - 0.2840945514288e-06, 0.2847972875882e+01, 0.4110125927500e-01, - 0.2378951599405e-06, 0.3762072563388e+01, 0.2275259891141e+00, - 0.2714229481417e-06, 0.1036049980031e+01, 0.2535050500000e-01, - 0.2323551717307e-06, 0.4682388599076e+00, 0.8582758298370e-01, - 0.1881790512219e-06, 0.4790565425418e+01, 0.2118763888447e+01, - 0.2261353968371e-06, 0.1669144912212e+01, 0.7181332454670e-01, - 0.2214546389848e-06, 0.3937717281614e+01, 0.2968341143800e-02, - 0.2184915594933e-06, 0.1129169845099e+00, 0.7775000683430e-01, - 0.2000164937936e-06, 0.4030009638488e+01, 0.2093666171530e+00, - 0.1966105136719e-06, 0.8745955786834e+00, 0.2172315424036e+00, - - 0.1904742332624e-06, 0.5919743598964e+01, 0.2022531624851e+00, - 0.1657399705031e-06, 0.2549141484884e+01, 0.7358765972222e+00, - 0.1574070533987e-06, 0.5277533020230e+01, 0.7429900518901e+00, - 0.1832261651039e-06, 0.3064688127777e+01, 0.3235053470014e+00, - 0.1733615346569e-06, 0.3011432799094e+01, 0.1385174140878e+00, - 0.1549124014496e-06, 0.4005569132359e+01, 0.5154640627760e+00, - 0.1637044713838e-06, 0.1831375966632e+01, 0.8531963191132e+00, - 0.1123420082383e-06, 0.1180270407578e+01, 0.1990721704425e+00, - 0.1083754165740e-06, 0.3414101320863e+00, 0.5439178814476e+00, - 0.1156638012655e-06, 0.6130479452594e+00, 0.5257585094865e+00, - - 0.1142548785134e-06, 0.3724761948846e+01, 0.5336234347371e+00, - 0.7921463895965e-07, 0.2435425589361e+01, 0.1478866649112e+01, - 0.7428600285231e-07, 0.3542144398753e+01, 0.2164800718209e+00, - 0.8323211246747e-07, 0.3525058072354e+01, 0.1692165728891e+01, - 0.7257595116312e-07, 0.1364299431982e+01, 0.2101180877357e+00, - 0.7111185833236e-07, 0.2460478875808e+01, 0.4155522422634e+00, - 0.6868090383716e-07, 0.4397327670704e+01, 0.1173197218910e+00, - 0.7226419974175e-07, 0.4042647308905e+01, 0.1265567569334e+01, - 0.6955642383177e-07, 0.2865047906085e+01, 0.9562891316684e+00, - 0.7492139296331e-07, 0.5014278994215e+01, 0.1422690933580e-01, - - 0.6598363128857e-07, 0.2376730020492e+01, 0.6470106940028e+00, - 0.7381147293385e-07, 0.3272990384244e+01, 0.1581959461667e+01, - 0.6402909624032e-07, 0.5302290955138e+01, 0.9597935788730e-01, - 0.6237454263857e-07, 0.5444144425332e+01, 0.7084920306520e-01, - 0.5241198544016e-07, 0.4215359579205e+01, 0.5265099800692e+00, - 0.5144463853918e-07, 0.1218916689916e+00, 0.5328719641544e+00, - 0.5868164772299e-07, 0.2369402002213e+01, 0.7871412831580e-01, - 0.6233195669151e-07, 0.1254922242403e+01, 0.2608790314060e+02, - 0.6068463791422e-07, 0.5679713760431e+01, 0.1114304132498e+00, - 0.4359361135065e-07, 0.6097219641646e+00, 0.1375773836557e+01, - - 0.4686510366826e-07, 0.4786231041431e+01, 0.1143987543936e+00, - 0.3758977287225e-07, 0.1167368068139e+01, 0.1596186371003e+01, - 0.4282051974778e-07, 0.1519471064319e+01, 0.2770348281756e+00, - 0.5153765386113e-07, 0.1860532322984e+01, 0.2228608264996e+00, - 0.4575129387188e-07, 0.7632857887158e+00, 0.1465949902372e+00, - 0.3326844933286e-07, 0.1298219485285e+01, 0.5070101000000e-01, - 0.3748617450984e-07, 0.1046510321062e+01, 0.4903339079539e+00, - 0.2816756661499e-07, 0.3434522346190e+01, 0.2991266627620e+00, - 0.3412750405039e-07, 0.2523766270318e+01, 0.3518164938661e+00, - 0.2655796761776e-07, 0.2904422260194e+01, 0.6256703299991e+00, - - 0.2963597929458e-07, 0.5923900431149e+00, 0.1099462426779e+00, - 0.2539523734781e-07, 0.4851947722567e+01, 0.1256615170089e+02, - 0.2283087914139e-07, 0.3400498595496e+01, 0.6681224869435e+01, - 0.2321309799331e-07, 0.5789099148673e+01, 0.3368040641550e-01, - 0.2549657649750e-07, 0.3991856479792e-01, 0.1169588211447e+01, - 0.2290462303977e-07, 0.2788567577052e+01, 0.1045155034888e+01, - 0.1945398522914e-07, 0.3290896998176e+01, 0.1155361302111e+01, - 0.1849171512638e-07, 0.2698060129367e+01, 0.4452511715700e-02, - 0.1647199834254e-07, 0.3016735644085e+01, 0.4408250688924e+00, - 0.1529530765273e-07, 0.5573043116178e+01, 0.6521991896920e-01, - - 0.1433199339978e-07, 0.1481192356147e+01, 0.9420622223326e+00, - 0.1729134193602e-07, 0.1422817538933e+01, 0.2108507877249e+00, - 0.1716463931346e-07, 0.3469468901855e+01, 0.2157473718317e+00, - 0.1391206061378e-07, 0.6122436220547e+01, 0.4123712502208e+00, - 0.1404746661924e-07, 0.1647765641936e+01, 0.4258542984690e-01, - 0.1410452399455e-07, 0.5989729161964e+01, 0.2258291676434e+00, - 0.1089828772168e-07, 0.2833705509371e+01, 0.4226656969313e+00, - 0.1047374564948e-07, 0.5090690007331e+00, 0.3092784376656e+00, - 0.1358279126532e-07, 0.5128990262836e+01, 0.7923417740620e-01, - 0.1020456476148e-07, 0.9632772880808e+00, 0.1456308687557e+00, - - 0.1033428735328e-07, 0.3223779318418e+01, 0.1795258541446e+01, - 0.1412435841540e-07, 0.2410271572721e+01, 0.1525316725248e+00, - 0.9722759371574e-08, 0.2333531395690e+01, 0.8434341241180e-01, - 0.9657334084704e-08, 0.6199270974168e+01, 0.1272681024002e+01, - 0.1083641148690e-07, 0.2864222292929e+01, 0.7032915397480e-01, - 0.1067318403838e-07, 0.5833458866568e+00, 0.2123349582968e+00, - 0.1062366201976e-07, 0.4307753989494e+01, 0.2142632012598e+00, - 0.1236364149266e-07, 0.2873917870593e+01, 0.1847279083684e+00, - 0.1092759489593e-07, 0.2959887266733e+01, 0.1370332435159e+00, - 0.8912069362899e-08, 0.5141213702562e+01, 0.2648454860559e+01, - - 0.9656467707970e-08, 0.4532182462323e+01, 0.4376440768498e+00, - 0.8098386150135e-08, 0.2268906338379e+01, 0.2880807454688e+00, - 0.7857714675000e-08, 0.4055544260745e+01, 0.2037373330570e+00, - 0.7288455940646e-08, 0.5357901655142e+01, 0.1129145838217e+00, - 0.9450595950552e-08, 0.4264926963939e+01, 0.5272426800584e+00, - 0.9381718247537e-08, 0.7489366976576e-01, 0.5321392641652e+00, - 0.7079052646038e-08, 0.1923311052874e+01, 0.6288513220417e+00, - 0.9259004415344e-08, 0.2970256853438e+01, 0.1606092486742e+00, - 0.8259801499742e-08, 0.3327056314697e+01, 0.8389694097774e+00, - 0.6476334355779e-08, 0.2954925505727e+01, 0.2008557621224e+01, - - 0.5984021492007e-08, 0.9138753105829e+00, 0.2042657109477e+02, - 0.5989546863181e-08, 0.3244464082031e+01, 0.2111650433779e+01, - 0.6233108606023e-08, 0.4995232638403e+00, 0.4305306221819e+00, - 0.6877299149965e-08, 0.2834987233449e+01, 0.9561746721300e-02, - 0.8311234227190e-08, 0.2202951835758e+01, 0.3801276407308e+00, - 0.6599472832414e-08, 0.4478581462618e+01, 0.1063314406849e+01, - 0.6160491096549e-08, 0.5145858696411e+01, 0.1368660381889e+01, - 0.6164772043891e-08, 0.3762976697911e+00, 0.4234171675140e+00, - 0.6363248684450e-08, 0.3162246718685e+01, 0.1253008786510e-01, - 0.6448587520999e-08, 0.3442693302119e+01, 0.5287268506303e+00, - - 0.6431662283977e-08, 0.8977549136606e+00, 0.5306550935933e+00, - 0.6351223158474e-08, 0.4306447410369e+01, 0.5217580628120e+02, - 0.5476721393451e-08, 0.3888529177855e+01, 0.2221856701002e+01, - 0.5341772572619e-08, 0.2655560662512e+01, 0.7466759693650e-01, - 0.5337055758302e-08, 0.5164990735946e+01, 0.7489573444450e-01, - 0.5373120816787e-08, 0.6041214553456e+01, 0.1274714967946e+00, - 0.5392351705426e-08, 0.9177763485932e+00, 0.1055449481598e+01, - 0.6688495850205e-08, 0.3089608126937e+01, 0.2213766559277e+00, - 0.5072003660362e-08, 0.4311316541553e+01, 0.2132517061319e+00, - 0.5070726650455e-08, 0.5790675464444e+00, 0.2133464534247e+00, - - 0.5658012950032e-08, 0.2703945510675e+01, 0.7287631425543e+00, - 0.4835509924854e-08, 0.2975422976065e+01, 0.7160067364790e-01, - 0.6479821978012e-08, 0.1324168733114e+01, 0.2209183458640e-01, - 0.6230636494980e-08, 0.2860103632836e+01, 0.3306188016693e+00, - 0.4649239516213e-08, 0.4832259763403e+01, 0.7796265773310e-01, - 0.6487325792700e-08, 0.2726165825042e+01, 0.3884652414254e+00, - 0.4682823682770e-08, 0.6966602455408e+00, 0.1073608853559e+01, - 0.5704230804976e-08, 0.5669634104606e+01, 0.8731175355560e-01, - 0.6125413585489e-08, 0.1513386538915e+01, 0.7605151500000e-01, - 0.6035825038187e-08, 0.1983509168227e+01, 0.9846002785331e+00, - - 0.4331123462303e-08, 0.2782892992807e+01, 0.4297791515992e+00, - 0.4681107685143e-08, 0.5337232886836e+01, 0.2127790306879e+00, - 0.4669105829655e-08, 0.5837133792160e+01, 0.2138191288687e+00, - 0.5138823602365e-08, 0.3080560200507e+01, 0.7233337363710e-01, - 0.4615856664534e-08, 0.1661747897471e+01, 0.8603097737811e+00, - 0.4496916702197e-08, 0.2112508027068e+01, 0.7381754420900e-01, - 0.4278479042945e-08, 0.5716528462627e+01, 0.7574578717200e-01, - 0.3840525503932e-08, 0.6424172726492e+00, 0.3407705765729e+00, - 0.4866636509685e-08, 0.4919244697715e+01, 0.7722995774390e-01, - 0.3526100639296e-08, 0.2550821052734e+01, 0.6225157782540e-01, - - 0.3939558488075e-08, 0.3939331491710e+01, 0.5268983110410e-01, - 0.4041268772576e-08, 0.2275337571218e+01, 0.3503323232942e+00, - 0.3948761842853e-08, 0.1999324200790e+01, 0.1451108196653e+00, - 0.3258394550029e-08, 0.9121001378200e+00, 0.5296435984654e+00, - 0.3257897048761e-08, 0.3428428660869e+01, 0.5297383457582e+00, - 0.3842559031298e-08, 0.6132927720035e+01, 0.9098186128426e+00, - 0.3109920095448e-08, 0.7693650193003e+00, 0.3932462625300e-02, - 0.3132237775119e-08, 0.3621293854908e+01, 0.2346394437820e+00, - 0.3942189421510e-08, 0.4841863659733e+01, 0.3180992042600e-02, - 0.3796972285340e-08, 0.1814174994268e+01, 0.1862120789403e+00, - - 0.3995640233688e-08, 0.1386990406091e+01, 0.4549093064213e+00, - 0.2875013727414e-08, 0.9178318587177e+00, 0.1905464808669e+01, - 0.3073719932844e-08, 0.2688923811835e+01, 0.3628624111593e+00, - 0.2731016580075e-08, 0.1188259127584e+01, 0.2131850110243e+00, - 0.2729549896546e-08, 0.3702160634273e+01, 0.2134131485323e+00, - 0.3339372892449e-08, 0.7199163960331e+00, 0.2007689919132e+00, - 0.2898833764204e-08, 0.1916709364999e+01, 0.5291709230214e+00, - 0.2894536549362e-08, 0.2424043195547e+01, 0.5302110212022e+00, - 0.3096872473843e-08, 0.4445894977497e+01, 0.2976424921901e+00, - 0.2635672326810e-08, 0.3814366984117e+01, 0.1485980103780e+01, - - 0.3649302697001e-08, 0.2924200596084e+01, 0.6044726378023e+00, - 0.3127954585895e-08, 0.1842251648327e+01, 0.1084620721060e+00, - 0.2616040173947e-08, 0.4155841921984e+01, 0.1258454114666e+01, - 0.2597395859860e-08, 0.1158045978874e+00, 0.2103781122809e+00, - 0.2593286172210e-08, 0.4771850408691e+01, 0.2162200472757e+00, - 0.2481823585747e-08, 0.4608842558889e+00, 0.1062562936266e+01, - 0.2742219550725e-08, 0.1538781127028e+01, 0.5651155736444e+00, - 0.3199558469610e-08, 0.3226647822878e+00, 0.7036329877322e+00, - 0.2666088542957e-08, 0.1967991731219e+00, 0.1400015846597e+00, - 0.2397067430580e-08, 0.3707036669873e+01, 0.2125476091956e+00, - - 0.2376570772738e-08, 0.1182086628042e+01, 0.2140505503610e+00, - 0.2547228007887e-08, 0.4906256820629e+01, 0.1534957940063e+00, - 0.2265575594114e-08, 0.3414949866857e+01, 0.2235935264888e+00, - 0.2464381430585e-08, 0.4599122275378e+01, 0.2091065926078e+00, - 0.2433408527044e-08, 0.2830751145445e+00, 0.2174915669488e+00, - 0.2443605509076e-08, 0.4212046432538e+01, 0.1739420156204e+00, - 0.2319779262465e-08, 0.9881978408630e+00, 0.7530171478090e-01, - 0.2284622835465e-08, 0.5565347331588e+00, 0.7426161660010e-01, - 0.2467268750783e-08, 0.5655708150766e+00, 0.2526561439362e+00, - 0.2808513492782e-08, 0.1418405053408e+01, 0.5636314030725e+00, - - 0.2329528932532e-08, 0.4069557545675e+01, 0.1056200952181e+01, - 0.9698639532817e-09, 0.1074134313634e+01, 0.7826370942180e+02 }; - -/* SSB-to-Sun, T^0, Y */ - static const double s0y[] = { - 0.4955392320126e-02, 0.2170467313679e+01, 0.5296909721118e+00, - 0.2722325167392e-02, 0.2444433682196e+01, 0.2132990797783e+00, - 0.1546579925346e-02, 0.5992779281546e+00, 0.3813291813120e-01, - 0.8363140252966e-03, 0.7687356310801e+00, 0.7478166569050e-01, - 0.3385792683603e-03, 0.0000000000000e+00, 0.0000000000000e+00, - 0.1201192221613e-03, 0.2520035601514e+01, 0.1059381944224e+01, - 0.7587125720554e-04, 0.1669954006449e+01, 0.4265981595566e+00, - 0.1964155361250e-04, 0.5707743963343e+01, 0.2061856251104e+00, - 0.1891900364909e-04, 0.2320960679937e+01, 0.2204125344462e+00, - 0.1937373433356e-04, 0.3226940689555e+01, 0.1495633313810e+00, - - 0.1437139941351e-04, 0.2301626908096e+01, 0.5225775174439e+00, - 0.1406267683099e-04, 0.5188579265542e+01, 0.5368044267797e+00, - 0.1178703080346e-04, 0.5489483248476e+01, 0.7626583626240e-01, - 0.8079835186041e-05, 0.1683751835264e+01, 0.3664874755930e-01, - 0.7623253594652e-05, 0.2656400462961e+01, 0.3961708870310e-01, - 0.6248667483971e-05, 0.4992775362055e+01, 0.7329749511860e-01, - 0.4366353695038e-05, 0.2869706279678e+01, 0.1589072916335e+01, - 0.3829101568895e-05, 0.3572131359950e+01, 0.7113454667900e-02, - 0.3175733773908e-05, 0.4535372530045e+01, 0.4194847048887e+00, - 0.3092437902159e-05, 0.9230153317909e+00, 0.6398972393349e+00, - - 0.2874168812154e-05, 0.3363143761101e+01, 0.1102062672231e+00, - 0.3040119321826e-05, 0.3324250895675e+01, 0.6283075850446e+01, - 0.2699723308006e-05, 0.2917882441928e+00, 0.1030928125552e+00, - 0.2134832683534e-05, 0.4220997202487e+01, 0.3163918923335e+00, - 0.1770412139433e-05, 0.4747318496462e+01, 0.1021328554739e+02, - 0.1377264209373e-05, 0.4305058462401e+00, 0.1484170571900e-02, - 0.1127814538960e-05, 0.8538177240740e+00, 0.6327837846670e+00, - 0.1055608090130e-05, 0.1551800742580e+01, 0.4337116142245e+00, - 0.9802673861420e-06, 0.1459646735377e+01, 0.1052268489556e+01, - 0.1090329461951e-05, 0.1587351228711e+01, 0.1162474756779e+01, - - 0.6959590025090e-06, 0.5534442628766e+01, 0.1066495398892e+01, - 0.5664914529542e-06, 0.6030673003297e+01, 0.9491756770005e+00, - 0.6607787763599e-06, 0.4989507233927e+01, 0.8460828644453e+00, - 0.6269725742838e-06, 0.4222951804572e+01, 0.1480791608091e+00, - 0.6301889697863e-06, 0.5444316669126e+01, 0.2243449970715e+00, - 0.4891042662861e-06, 0.1490552839784e+01, 0.3340612434717e+01, - 0.3457083123290e-06, 0.3030475486049e+01, 0.3516457698740e-01, - 0.3032559967314e-06, 0.2652038793632e+01, 0.1104591729320e-01, - 0.2841133988903e-06, 0.1276744786829e+01, 0.4110125927500e-01, - 0.2855564444432e-06, 0.2143368674733e+01, 0.1510475019529e+00, - - 0.2765157135038e-06, 0.5444186109077e+01, 0.6373574839730e-01, - 0.2382312465034e-06, 0.2190521137593e+01, 0.2275259891141e+00, - 0.2808060365077e-06, 0.5735195064841e+01, 0.2535050500000e-01, - 0.2332175234405e-06, 0.9481985524859e-01, 0.7181332454670e-01, - 0.2322488199659e-06, 0.5180499361533e+01, 0.8582758298370e-01, - 0.1881850258423e-06, 0.3219788273885e+01, 0.2118763888447e+01, - 0.2196111392808e-06, 0.2366941159761e+01, 0.2968341143800e-02, - 0.2183810335519e-06, 0.4825445110915e+01, 0.7775000683430e-01, - 0.2002733093326e-06, 0.2457148995307e+01, 0.2093666171530e+00, - 0.1967111767229e-06, 0.5586291545459e+01, 0.2172315424036e+00, - - 0.1568473250543e-06, 0.3708003123320e+01, 0.7429900518901e+00, - 0.1852528314300e-06, 0.4310638151560e+01, 0.2022531624851e+00, - 0.1832111226447e-06, 0.1494665322656e+01, 0.3235053470014e+00, - 0.1746805502310e-06, 0.1451378500784e+01, 0.1385174140878e+00, - 0.1555730966650e-06, 0.1068040418198e+01, 0.7358765972222e+00, - 0.1554883462559e-06, 0.2442579035461e+01, 0.5154640627760e+00, - 0.1638380568746e-06, 0.2597913420625e+00, 0.8531963191132e+00, - 0.1159938593640e-06, 0.5834512021280e+01, 0.1990721704425e+00, - 0.1083427965695e-06, 0.5054033177950e+01, 0.5439178814476e+00, - 0.1156480369431e-06, 0.5325677432457e+01, 0.5257585094865e+00, - - 0.1141308860095e-06, 0.2153403923857e+01, 0.5336234347371e+00, - 0.7913146470946e-07, 0.8642846847027e+00, 0.1478866649112e+01, - 0.7439752463733e-07, 0.1970628496213e+01, 0.2164800718209e+00, - 0.7280277104079e-07, 0.6073307250609e+01, 0.2101180877357e+00, - 0.8319567719136e-07, 0.1954371928334e+01, 0.1692165728891e+01, - 0.7137705549290e-07, 0.8904989440909e+00, 0.4155522422634e+00, - 0.6900825396225e-07, 0.2825717714977e+01, 0.1173197218910e+00, - 0.7245757216635e-07, 0.2481677513331e+01, 0.1265567569334e+01, - 0.6961165696255e-07, 0.1292955312978e+01, 0.9562891316684e+00, - 0.7571804456890e-07, 0.3427517575069e+01, 0.1422690933580e-01, - - 0.6605425721904e-07, 0.8052192701492e+00, 0.6470106940028e+00, - 0.7375477357248e-07, 0.1705076390088e+01, 0.1581959461667e+01, - 0.7041664951470e-07, 0.4848356967891e+00, 0.9597935788730e-01, - 0.6322199535763e-07, 0.3878069473909e+01, 0.7084920306520e-01, - 0.5244380279191e-07, 0.2645560544125e+01, 0.5265099800692e+00, - 0.5143125704988e-07, 0.4834486101370e+01, 0.5328719641544e+00, - 0.5871866319373e-07, 0.7981472548900e+00, 0.7871412831580e-01, - 0.6300822573871e-07, 0.5979398788281e+01, 0.2608790314060e+02, - 0.6062154271548e-07, 0.4108655402756e+01, 0.1114304132498e+00, - 0.4361912339976e-07, 0.5322624319280e+01, 0.1375773836557e+01, - - 0.4417005920067e-07, 0.6240817359284e+01, 0.2770348281756e+00, - 0.4686806749936e-07, 0.3214977301156e+01, 0.1143987543936e+00, - 0.3758892132305e-07, 0.5879809634765e+01, 0.1596186371003e+01, - 0.5151351332319e-07, 0.2893377688007e+00, 0.2228608264996e+00, - 0.4554683578572e-07, 0.5475427144122e+01, 0.1465949902372e+00, - 0.3442381385338e-07, 0.5992034796640e+01, 0.5070101000000e-01, - 0.2831093954933e-07, 0.5367350273914e+01, 0.3092784376656e+00, - 0.3756267090084e-07, 0.5758171285420e+01, 0.4903339079539e+00, - 0.2816374679892e-07, 0.1863718700923e+01, 0.2991266627620e+00, - 0.3419307025569e-07, 0.9524347534130e+00, 0.3518164938661e+00, - - 0.2904250494239e-07, 0.5304471615602e+01, 0.1099462426779e+00, - 0.2471734511206e-07, 0.1297069793530e+01, 0.6256703299991e+00, - 0.2539620831872e-07, 0.3281126083375e+01, 0.1256615170089e+02, - 0.2281017868007e-07, 0.1829122133165e+01, 0.6681224869435e+01, - 0.2275319473335e-07, 0.5797198160181e+01, 0.3932462625300e-02, - 0.2547755368442e-07, 0.4752697708330e+01, 0.1169588211447e+01, - 0.2285979669317e-07, 0.1223205292886e+01, 0.1045155034888e+01, - 0.1913386560994e-07, 0.1757532993389e+01, 0.1155361302111e+01, - 0.1809020525147e-07, 0.4246116108791e+01, 0.3368040641550e-01, - 0.1649213300201e-07, 0.1445162890627e+01, 0.4408250688924e+00, - - 0.1834972793932e-07, 0.1126917567225e+01, 0.4452511715700e-02, - 0.1439550648138e-07, 0.6160756834764e+01, 0.9420622223326e+00, - 0.1487645457041e-07, 0.4358761931792e+01, 0.4123712502208e+00, - 0.1731729516660e-07, 0.6134456753344e+01, 0.2108507877249e+00, - 0.1717747163567e-07, 0.1898186084455e+01, 0.2157473718317e+00, - 0.1418190430374e-07, 0.4180286741266e+01, 0.6521991896920e-01, - 0.1404844134873e-07, 0.7654053565412e-01, 0.4258542984690e-01, - 0.1409842846538e-07, 0.4418612420312e+01, 0.2258291676434e+00, - 0.1090948346291e-07, 0.1260615686131e+01, 0.4226656969313e+00, - 0.1357577323612e-07, 0.3558248818690e+01, 0.7923417740620e-01, - - 0.1018154061960e-07, 0.5676087241256e+01, 0.1456308687557e+00, - 0.1412073972109e-07, 0.8394392632422e+00, 0.1525316725248e+00, - 0.1030938326496e-07, 0.1653593274064e+01, 0.1795258541446e+01, - 0.1180081567104e-07, 0.1285802592036e+01, 0.7032915397480e-01, - 0.9708510575650e-08, 0.7631889488106e+00, 0.8434341241180e-01, - 0.9637689663447e-08, 0.4630642649176e+01, 0.1272681024002e+01, - 0.1068910429389e-07, 0.5294934032165e+01, 0.2123349582968e+00, - 0.1063716179336e-07, 0.2736266800832e+01, 0.2142632012598e+00, - 0.1234858713814e-07, 0.1302891146570e+01, 0.1847279083684e+00, - 0.8912631189738e-08, 0.3570415993621e+01, 0.2648454860559e+01, - - 0.1036378285534e-07, 0.4236693440949e+01, 0.1370332435159e+00, - 0.9667798501561e-08, 0.2960768892398e+01, 0.4376440768498e+00, - 0.8108314201902e-08, 0.6987781646841e+00, 0.2880807454688e+00, - 0.7648364324628e-08, 0.2499017863863e+01, 0.2037373330570e+00, - 0.7286136828406e-08, 0.3787426951665e+01, 0.1129145838217e+00, - 0.9448237743913e-08, 0.2694354332983e+01, 0.5272426800584e+00, - 0.9374276106428e-08, 0.4787121277064e+01, 0.5321392641652e+00, - 0.7100226287462e-08, 0.3530238792101e+00, 0.6288513220417e+00, - 0.9253056659571e-08, 0.1399478925664e+01, 0.1606092486742e+00, - 0.6636432145504e-08, 0.3479575438447e+01, 0.1368660381889e+01, - - 0.6469975312932e-08, 0.1383669964800e+01, 0.2008557621224e+01, - 0.7335849729765e-08, 0.1243698166898e+01, 0.9561746721300e-02, - 0.8743421205855e-08, 0.3776164289301e+01, 0.3801276407308e+00, - 0.5993635744494e-08, 0.5627122113596e+01, 0.2042657109477e+02, - 0.5981008479693e-08, 0.1674336636752e+01, 0.2111650433779e+01, - 0.6188535145838e-08, 0.5214925208672e+01, 0.4305306221819e+00, - 0.6596074017566e-08, 0.2907653268124e+01, 0.1063314406849e+01, - 0.6630815126226e-08, 0.2127643669658e+01, 0.8389694097774e+00, - 0.6156772830040e-08, 0.5082160803295e+01, 0.4234171675140e+00, - 0.6446960563014e-08, 0.1872100916905e+01, 0.5287268506303e+00, - - 0.6429324424668e-08, 0.5610276103577e+01, 0.5306550935933e+00, - 0.6302232396465e-08, 0.1592152049607e+01, 0.1253008786510e-01, - 0.6399244436159e-08, 0.2746214421532e+01, 0.5217580628120e+02, - 0.5474965172558e-08, 0.2317666374383e+01, 0.2221856701002e+01, - 0.5339293190692e-08, 0.1084724961156e+01, 0.7466759693650e-01, - 0.5334733683389e-08, 0.3594106067745e+01, 0.7489573444450e-01, - 0.5392665782110e-08, 0.5630254365606e+01, 0.1055449481598e+01, - 0.6682075673789e-08, 0.1518480041732e+01, 0.2213766559277e+00, - 0.5079130495960e-08, 0.2739765115711e+01, 0.2132517061319e+00, - 0.5077759793261e-08, 0.5290711290094e+01, 0.2133464534247e+00, - - 0.4832037368310e-08, 0.1404473217200e+01, 0.7160067364790e-01, - 0.6463279674802e-08, 0.6038381695210e+01, 0.2209183458640e-01, - 0.6240592771560e-08, 0.1290170653666e+01, 0.3306188016693e+00, - 0.4672013521493e-08, 0.3261895939677e+01, 0.7796265773310e-01, - 0.6500650750348e-08, 0.1154522312095e+01, 0.3884652414254e+00, - 0.6344161389053e-08, 0.6206111545062e+01, 0.7605151500000e-01, - 0.4682518370646e-08, 0.5409118796685e+01, 0.1073608853559e+01, - 0.5329460015591e-08, 0.1202985784864e+01, 0.7287631425543e+00, - 0.5701588675898e-08, 0.4098715257064e+01, 0.8731175355560e-01, - 0.6030690867211e-08, 0.4132033218460e+00, 0.9846002785331e+00, - - 0.4336256312655e-08, 0.1211415991827e+01, 0.4297791515992e+00, - 0.4688498808975e-08, 0.3765479072409e+01, 0.2127790306879e+00, - 0.4675578609335e-08, 0.4265540037226e+01, 0.2138191288687e+00, - 0.4225578112158e-08, 0.5237566010676e+01, 0.3407705765729e+00, - 0.5139422230028e-08, 0.1507173079513e+01, 0.7233337363710e-01, - 0.4619995093571e-08, 0.9023957449848e-01, 0.8603097737811e+00, - 0.4494776255461e-08, 0.5414930552139e+00, 0.7381754420900e-01, - 0.4274026276788e-08, 0.4145735303659e+01, 0.7574578717200e-01, - 0.5018141789353e-08, 0.3344408829055e+01, 0.3180992042600e-02, - 0.4866163952181e-08, 0.3348534657607e+01, 0.7722995774390e-01, - - 0.4111986020501e-08, 0.4198823597220e+00, 0.1451108196653e+00, - 0.3356142784950e-08, 0.5609144747180e+01, 0.1274714967946e+00, - 0.4070575554551e-08, 0.7028411059224e+00, 0.3503323232942e+00, - 0.3257451857278e-08, 0.5624697983086e+01, 0.5296435984654e+00, - 0.3256973703026e-08, 0.1857842076707e+01, 0.5297383457582e+00, - 0.3830771508640e-08, 0.4562887279931e+01, 0.9098186128426e+00, - 0.3725024005962e-08, 0.2358058692652e+00, 0.1084620721060e+00, - 0.3136763921756e-08, 0.2049731526845e+01, 0.2346394437820e+00, - 0.3795147256194e-08, 0.2432356296933e+00, 0.1862120789403e+00, - 0.2877342229911e-08, 0.5631101279387e+01, 0.1905464808669e+01, - - 0.3076931798805e-08, 0.1117615737392e+01, 0.3628624111593e+00, - 0.2734765945273e-08, 0.5899826516955e+01, 0.2131850110243e+00, - 0.2733405296885e-08, 0.2130562964070e+01, 0.2134131485323e+00, - 0.2898552353410e-08, 0.3462387048225e+00, 0.5291709230214e+00, - 0.2893736103681e-08, 0.8534352781543e+00, 0.5302110212022e+00, - 0.3095717734137e-08, 0.2875061429041e+01, 0.2976424921901e+00, - 0.2636190425832e-08, 0.2242512846659e+01, 0.1485980103780e+01, - 0.3645512095537e-08, 0.1354016903958e+01, 0.6044726378023e+00, - 0.2808173547723e-08, 0.6705114365631e-01, 0.6225157782540e-01, - 0.2625012866888e-08, 0.4775705748482e+01, 0.5268983110410e-01, - - 0.2572233995651e-08, 0.2638924216139e+01, 0.1258454114666e+01, - 0.2604238824792e-08, 0.4826358927373e+01, 0.2103781122809e+00, - 0.2596886385239e-08, 0.3200388483118e+01, 0.2162200472757e+00, - 0.3228057304264e-08, 0.5384848409563e+01, 0.2007689919132e+00, - 0.2481601798252e-08, 0.5173373487744e+01, 0.1062562936266e+01, - 0.2745977498864e-08, 0.6250966149853e+01, 0.5651155736444e+00, - 0.2669878833811e-08, 0.4906001352499e+01, 0.1400015846597e+00, - 0.3203986611711e-08, 0.5034333010005e+01, 0.7036329877322e+00, - 0.3354961227212e-08, 0.6108262423137e+01, 0.4549093064213e+00, - 0.2400407324558e-08, 0.2135399294955e+01, 0.2125476091956e+00, - - 0.2379905859802e-08, 0.5893721933961e+01, 0.2140505503610e+00, - 0.2550844302187e-08, 0.3331940762063e+01, 0.1534957940063e+00, - 0.2268824211001e-08, 0.1843418461035e+01, 0.2235935264888e+00, - 0.2464700891204e-08, 0.3029548547230e+01, 0.2091065926078e+00, - 0.2436814726024e-08, 0.4994717970364e+01, 0.2174915669488e+00, - 0.2443623894745e-08, 0.2645102591375e+01, 0.1739420156204e+00, - 0.2318701783838e-08, 0.5700547397897e+01, 0.7530171478090e-01, - 0.2284448700256e-08, 0.5268898905872e+01, 0.7426161660010e-01, - 0.2468848123510e-08, 0.5276280575078e+01, 0.2526561439362e+00, - 0.2814052350303e-08, 0.6130168623475e+01, 0.5636314030725e+00, - - 0.2243662755220e-08, 0.6631692457995e+00, 0.8886590321940e-01, - 0.2330795855941e-08, 0.2499435487702e+01, 0.1056200952181e+01, - 0.9757679038404e-09, 0.5796846023126e+01, 0.7826370942180e+02 }; - -/* SSB-to-Sun, T^0, Z */ - static const double s0z[] = { - 0.1181255122986e-03, 0.4607918989164e+00, 0.2132990797783e+00, - 0.1127777651095e-03, 0.4169146331296e+00, 0.5296909721118e+00, - 0.4777754401806e-04, 0.4582657007130e+01, 0.3813291813120e-01, - 0.1129354285772e-04, 0.5758735142480e+01, 0.7478166569050e-01, - -0.1149543637123e-04, 0.0000000000000e+00, 0.0000000000000e+00, - 0.3298730512306e-05, 0.5978801994625e+01, 0.4265981595566e+00, - 0.2733376706079e-05, 0.7665413691040e+00, 0.1059381944224e+01, - 0.9426389657270e-06, 0.3710201265838e+01, 0.2061856251104e+00, - 0.8187517749552e-06, 0.3390675605802e+00, 0.2204125344462e+00, - 0.4080447871819e-06, 0.4552296640088e+00, 0.5225775174439e+00, - - 0.3169973017028e-06, 0.3445455899321e+01, 0.5368044267797e+00, - 0.2438098615549e-06, 0.5664675150648e+01, 0.3664874755930e-01, - 0.2601897517235e-06, 0.1931894095697e+01, 0.1495633313810e+00, - 0.2314558080079e-06, 0.3666319115574e+00, 0.3961708870310e-01, - 0.1962549548002e-06, 0.3167411699020e+01, 0.7626583626240e-01, - 0.2180518287925e-06, 0.1544420746580e+01, 0.7113454667900e-02, - 0.1451382442868e-06, 0.1583756740070e+01, 0.1102062672231e+00, - 0.1358439007389e-06, 0.5239941758280e+01, 0.6398972393349e+00, - 0.1050585898028e-06, 0.2266958352859e+01, 0.3163918923335e+00, - 0.1050029870186e-06, 0.2711495250354e+01, 0.4194847048887e+00, - - 0.9934920679800e-07, 0.1116208151396e+01, 0.1589072916335e+01, - 0.1048395331560e-06, 0.3408619600206e+01, 0.1021328554739e+02, - 0.8370147196668e-07, 0.3810459401087e+01, 0.2535050500000e-01, - 0.7989856510998e-07, 0.3769910473647e+01, 0.7329749511860e-01, - 0.5441221655233e-07, 0.2416994903374e+01, 0.1030928125552e+00, - 0.4610812906784e-07, 0.5858503336994e+01, 0.4337116142245e+00, - 0.3923022803444e-07, 0.3354170010125e+00, 0.1484170571900e-02, - 0.2610725582128e-07, 0.5410600646324e+01, 0.6327837846670e+00, - 0.2455279767721e-07, 0.6120216681403e+01, 0.1162474756779e+01, - 0.2375530706525e-07, 0.6055443426143e+01, 0.1052268489556e+01, - - 0.1782967577553e-07, 0.3146108708004e+01, 0.8460828644453e+00, - 0.1581687095238e-07, 0.6255496089819e+00, 0.3340612434717e+01, - 0.1594657672461e-07, 0.3782604300261e+01, 0.1066495398892e+01, - 0.1563448615040e-07, 0.1997775733196e+01, 0.2022531624851e+00, - 0.1463624258525e-07, 0.1736316792088e+00, 0.3516457698740e-01, - 0.1331585056673e-07, 0.4331941830747e+01, 0.9491756770005e+00, - 0.1130634557637e-07, 0.6152017751825e+01, 0.2968341143800e-02, - 0.1028949607145e-07, 0.2101792614637e+00, 0.2275259891141e+00, - 0.1024074971618e-07, 0.4071833211074e+01, 0.5070101000000e-01, - 0.8826956060303e-08, 0.4861633688145e+00, 0.2093666171530e+00, - - 0.8572230171541e-08, 0.5268190724302e+01, 0.4110125927500e-01, - 0.7649332643544e-08, 0.5134543417106e+01, 0.2608790314060e+02, - 0.8581673291033e-08, 0.2920218146681e+01, 0.1480791608091e+00, - 0.8430589300938e-08, 0.3604576619108e+01, 0.2172315424036e+00, - 0.7776165501012e-08, 0.3772942249792e+01, 0.6373574839730e-01, - 0.8311070234408e-08, 0.6200412329888e+01, 0.3235053470014e+00, - 0.6927365212582e-08, 0.4543353113437e+01, 0.8531963191132e+00, - 0.6791574208598e-08, 0.2882188406238e+01, 0.7181332454670e-01, - 0.5593100811839e-08, 0.1776646892780e+01, 0.7429900518901e+00, - 0.4553381853021e-08, 0.3949617611240e+01, 0.7775000683430e-01, - - 0.5758000450068e-08, 0.3859251775075e+01, 0.1990721704425e+00, - 0.4281283457133e-08, 0.1466294631206e+01, 0.2118763888447e+01, - 0.4206935661097e-08, 0.5421776011706e+01, 0.1104591729320e-01, - 0.4213751641837e-08, 0.3412048993322e+01, 0.2243449970715e+00, - 0.5310506239878e-08, 0.5421641370995e+00, 0.5154640627760e+00, - 0.3827450341320e-08, 0.8887314524995e+00, 0.1510475019529e+00, - 0.4292435241187e-08, 0.1405043757194e+01, 0.1422690933580e-01, - 0.3189780702289e-08, 0.1060049293445e+01, 0.1173197218910e+00, - 0.3226611928069e-08, 0.6270858897442e+01, 0.2164800718209e+00, - 0.2893897608830e-08, 0.5117563223301e+01, 0.6470106940028e+00, - - 0.3239852024578e-08, 0.4079092237983e+01, 0.2101180877357e+00, - 0.2956892222200e-08, 0.1594917021704e+01, 0.3092784376656e+00, - 0.2980177912437e-08, 0.5258787667564e+01, 0.4155522422634e+00, - 0.3163725690776e-08, 0.3854589225479e+01, 0.8582758298370e-01, - 0.2662262399118e-08, 0.3561326430187e+01, 0.5257585094865e+00, - 0.2766689135729e-08, 0.3180732086830e+00, 0.1385174140878e+00, - 0.2411600278464e-08, 0.3324798335058e+01, 0.5439178814476e+00, - 0.2483527695131e-08, 0.4169069291947e+00, 0.5336234347371e+00, - 0.7788777276590e-09, 0.1900569908215e+01, 0.5217580628120e+02 }; - -/* SSB-to-Sun, T^1, X */ - static const double s1x[] = { - -0.1296310361520e-07, 0.0000000000000e+00, 0.0000000000000e+00, - 0.8975769009438e-08, 0.1128891609250e+01, 0.4265981595566e+00, - 0.7771113441307e-08, 0.2706039877077e+01, 0.2061856251104e+00, - 0.7538303866642e-08, 0.2191281289498e+01, 0.2204125344462e+00, - 0.6061384579336e-08, 0.3248167319958e+01, 0.1059381944224e+01, - 0.5726994235594e-08, 0.5569981398610e+01, 0.5225775174439e+00, - 0.5616492836424e-08, 0.5057386614909e+01, 0.5368044267797e+00, - 0.1010881584769e-08, 0.3473577116095e+01, 0.7113454667900e-02, - 0.7259606157626e-09, 0.3651858593665e+00, 0.6398972393349e+00, - 0.8755095026935e-09, 0.1662835408338e+01, 0.4194847048887e+00, - - 0.5370491182812e-09, 0.1327673878077e+01, 0.4337116142245e+00, - 0.5743773887665e-09, 0.4250200846687e+01, 0.2132990797783e+00, - 0.4408103140300e-09, 0.3598752574277e+01, 0.1589072916335e+01, - 0.3101892374445e-09, 0.4887822983319e+01, 0.1052268489556e+01, - 0.3209453713578e-09, 0.9702272295114e+00, 0.5296909721118e+00, - 0.3017228286064e-09, 0.5484462275949e+01, 0.1066495398892e+01, - 0.3200700038601e-09, 0.2846613338643e+01, 0.1495633313810e+00, - 0.2137637279911e-09, 0.5692163292729e+00, 0.3163918923335e+00, - 0.1899686386727e-09, 0.2061077157189e+01, 0.2275259891141e+00, - 0.1401994545308e-09, 0.4177771136967e+01, 0.1102062672231e+00, - - 0.1578057810499e-09, 0.5782460597335e+01, 0.7626583626240e-01, - 0.1237713253351e-09, 0.5705900866881e+01, 0.5154640627760e+00, - 0.1313076837395e-09, 0.5163438179576e+01, 0.3664874755930e-01, - 0.1184963304860e-09, 0.3054804427242e+01, 0.6327837846670e+00, - 0.1238130878565e-09, 0.2317292575962e+01, 0.3961708870310e-01, - 0.1015959527736e-09, 0.2194643645526e+01, 0.7329749511860e-01, - 0.9017954423714e-10, 0.2868603545435e+01, 0.1990721704425e+00, - 0.8668024955603e-10, 0.4923849675082e+01, 0.5439178814476e+00, - 0.7756083930103e-10, 0.3014334135200e+01, 0.9491756770005e+00, - 0.7536503401741e-10, 0.2704886279769e+01, 0.1030928125552e+00, - - 0.5483308679332e-10, 0.6010983673799e+01, 0.8531963191132e+00, - 0.5184339620428e-10, 0.1952704573291e+01, 0.2093666171530e+00, - 0.5108658712030e-10, 0.2958575786649e+01, 0.2172315424036e+00, - 0.5019424524650e-10, 0.1736317621318e+01, 0.2164800718209e+00, - 0.4909312625978e-10, 0.3167216416257e+01, 0.2101180877357e+00, - 0.4456638901107e-10, 0.7697579923471e+00, 0.3235053470014e+00, - 0.4227030350925e-10, 0.3490910137928e+01, 0.6373574839730e-01, - 0.4095456040093e-10, 0.5178888984491e+00, 0.6470106940028e+00, - 0.4990537041422e-10, 0.3323887668974e+01, 0.1422690933580e-01, - 0.4321170010845e-10, 0.4288484987118e+01, 0.7358765972222e+00, - - 0.3544072091802e-10, 0.6021051579251e+01, 0.5265099800692e+00, - 0.3480198638687e-10, 0.4600027054714e+01, 0.5328719641544e+00, - 0.3440287244435e-10, 0.4349525970742e+01, 0.8582758298370e-01, - 0.3330628322713e-10, 0.2347391505082e+01, 0.1104591729320e-01, - 0.2973060707184e-10, 0.4789409286400e+01, 0.5257585094865e+00, - 0.2932606766089e-10, 0.5831693799927e+01, 0.5336234347371e+00, - 0.2876972310953e-10, 0.2692638514771e+01, 0.1173197218910e+00, - 0.2827488278556e-10, 0.2056052487960e+01, 0.2022531624851e+00, - 0.2515028239756e-10, 0.7411863262449e+00, 0.9597935788730e-01, - 0.2853033744415e-10, 0.3948481024894e+01, 0.2118763888447e+01 }; - -/* SSB-to-Sun, T^1, Y */ - static const double s1y[] = { - 0.8989047573576e-08, 0.5840593672122e+01, 0.4265981595566e+00, - 0.7815938401048e-08, 0.1129664707133e+01, 0.2061856251104e+00, - 0.7550926713280e-08, 0.6196589104845e+00, 0.2204125344462e+00, - 0.6056556925895e-08, 0.1677494667846e+01, 0.1059381944224e+01, - 0.5734142698204e-08, 0.4000920852962e+01, 0.5225775174439e+00, - 0.5614341822459e-08, 0.3486722577328e+01, 0.5368044267797e+00, - 0.1028678147656e-08, 0.1877141024787e+01, 0.7113454667900e-02, - 0.7270792075266e-09, 0.5077167301739e+01, 0.6398972393349e+00, - 0.8734141726040e-09, 0.9069550282609e-01, 0.4194847048887e+00, - 0.5377371402113e-09, 0.6039381844671e+01, 0.4337116142245e+00, - - 0.4729719431571e-09, 0.2153086311760e+01, 0.2132990797783e+00, - 0.4458052820973e-09, 0.5059830025565e+01, 0.5296909721118e+00, - 0.4406855467908e-09, 0.2027971692630e+01, 0.1589072916335e+01, - 0.3101659310977e-09, 0.3317677981860e+01, 0.1052268489556e+01, - 0.3016749232545e-09, 0.3913703482532e+01, 0.1066495398892e+01, - 0.3198541352656e-09, 0.1275513098525e+01, 0.1495633313810e+00, - 0.2142065389871e-09, 0.5301351614597e+01, 0.3163918923335e+00, - 0.1902615247592e-09, 0.4894943352736e+00, 0.2275259891141e+00, - 0.1613410990871e-09, 0.2449891130437e+01, 0.1102062672231e+00, - 0.1576992165097e-09, 0.4211421447633e+01, 0.7626583626240e-01, - - 0.1241637259894e-09, 0.4140803368133e+01, 0.5154640627760e+00, - 0.1313974830355e-09, 0.3591920305503e+01, 0.3664874755930e-01, - 0.1181697118258e-09, 0.1506314382788e+01, 0.6327837846670e+00, - 0.1238239742779e-09, 0.7461405378404e+00, 0.3961708870310e-01, - 0.1010107068241e-09, 0.6271010795475e+00, 0.7329749511860e-01, - 0.9226316616509e-10, 0.1259158839583e+01, 0.1990721704425e+00, - 0.8664946419555e-10, 0.3353244696934e+01, 0.5439178814476e+00, - 0.7757230468978e-10, 0.1447677295196e+01, 0.9491756770005e+00, - 0.7693168628139e-10, 0.1120509896721e+01, 0.1030928125552e+00, - 0.5487897454612e-10, 0.4439380426795e+01, 0.8531963191132e+00, - - 0.5196118677218e-10, 0.3788856619137e+00, 0.2093666171530e+00, - 0.5110853339935e-10, 0.1386879372016e+01, 0.2172315424036e+00, - 0.5027804534813e-10, 0.1647881805466e+00, 0.2164800718209e+00, - 0.4922485922674e-10, 0.1594315079862e+01, 0.2101180877357e+00, - 0.6155599524400e-10, 0.0000000000000e+00, 0.0000000000000e+00, - 0.4447147832161e-10, 0.5480720918976e+01, 0.3235053470014e+00, - 0.4144691276422e-10, 0.1931371033660e+01, 0.6373574839730e-01, - 0.4099950625452e-10, 0.5229611294335e+01, 0.6470106940028e+00, - 0.5060541682953e-10, 0.1731112486298e+01, 0.1422690933580e-01, - 0.4293615946300e-10, 0.2714571038925e+01, 0.7358765972222e+00, - - 0.3545659845763e-10, 0.4451041444634e+01, 0.5265099800692e+00, - 0.3479112041196e-10, 0.3029385448081e+01, 0.5328719641544e+00, - 0.3438516493570e-10, 0.2778507143731e+01, 0.8582758298370e-01, - 0.3297341285033e-10, 0.7898709807584e+00, 0.1104591729320e-01, - 0.2972585818015e-10, 0.3218785316973e+01, 0.5257585094865e+00, - 0.2931707295017e-10, 0.4260731012098e+01, 0.5336234347371e+00, - 0.2897198149403e-10, 0.1120753978101e+01, 0.1173197218910e+00, - 0.2832293240878e-10, 0.4597682717827e+00, 0.2022531624851e+00, - 0.2864348326612e-10, 0.2169939928448e+01, 0.9597935788730e-01, - 0.2852714675471e-10, 0.2377659870578e+01, 0.2118763888447e+01 }; - -/* SSB-to-Sun, T^1, Z */ - static const double s1z[] = { - 0.5444220475678e-08, 0.1803825509310e+01, 0.2132990797783e+00, - 0.3883412695596e-08, 0.4668616389392e+01, 0.5296909721118e+00, - 0.1334341434551e-08, 0.0000000000000e+00, 0.0000000000000e+00, - 0.3730001266883e-09, 0.5401405918943e+01, 0.2061856251104e+00, - 0.2894929197956e-09, 0.4932415609852e+01, 0.2204125344462e+00, - 0.2857950357701e-09, 0.3154625362131e+01, 0.7478166569050e-01, - 0.2499226432292e-09, 0.3657486128988e+01, 0.4265981595566e+00, - 0.1937705443593e-09, 0.5740434679002e+01, 0.1059381944224e+01, - 0.1374894396320e-09, 0.1712857366891e+01, 0.5368044267797e+00, - 0.1217248678408e-09, 0.2312090870932e+01, 0.5225775174439e+00, - - 0.7961052740870e-10, 0.5283368554163e+01, 0.3813291813120e-01, - 0.4979225949689e-10, 0.4298290471860e+01, 0.4194847048887e+00, - 0.4388552286597e-10, 0.6145515047406e+01, 0.7113454667900e-02, - 0.2586835212560e-10, 0.3019448001809e+01, 0.6398972393349e+00 }; - -/* SSB-to-Sun, T^2, X */ - static const double s2x[] = { - 0.1603551636587e-11, 0.4404109410481e+01, 0.2061856251104e+00, - 0.1556935889384e-11, 0.4818040873603e+00, 0.2204125344462e+00, - 0.1182594414915e-11, 0.9935762734472e+00, 0.5225775174439e+00, - 0.1158794583180e-11, 0.3353180966450e+01, 0.5368044267797e+00, - 0.9597358943932e-12, 0.5567045358298e+01, 0.2132990797783e+00, - 0.6511516579605e-12, 0.5630872420788e+01, 0.4265981595566e+00, - 0.7419792747688e-12, 0.2156188581957e+01, 0.5296909721118e+00, - 0.3951972655848e-12, 0.1981022541805e+01, 0.1059381944224e+01, - 0.4478223877045e-12, 0.0000000000000e+00, 0.0000000000000e+00 }; - -/* SSB-to-Sun, T^2, Y */ - static const double s2y[] = { - 0.1609114495091e-11, 0.2831096993481e+01, 0.2061856251104e+00, - 0.1560330784946e-11, 0.5193058213906e+01, 0.2204125344462e+00, - 0.1183535479202e-11, 0.5707003443890e+01, 0.5225775174439e+00, - 0.1158183066182e-11, 0.1782400404928e+01, 0.5368044267797e+00, - 0.1032868027407e-11, 0.4036925452011e+01, 0.2132990797783e+00, - 0.6540142847741e-12, 0.4058241056717e+01, 0.4265981595566e+00, - 0.7305236491596e-12, 0.6175401942957e+00, 0.5296909721118e+00, - -0.5580725052968e-12, 0.0000000000000e+00, 0.0000000000000e+00, - 0.3946122651015e-12, 0.4108265279171e+00, 0.1059381944224e+01 }; - -/* SSB-to-Sun, T^2, Z */ - static const double s2z[] = { - 0.3749920358054e-12, 0.3230285558668e+01, 0.2132990797783e+00, - 0.2735037220939e-12, 0.6154322683046e+01, 0.5296909721118e+00 }; - -/* Pointers to coefficient arrays, in x,y,z sets */ - static const double *ce0[] = { e0x, e0y, e0z }, - *ce1[] = { e1x, e1y, e1z }, - *ce2[] = { e2x, e2y, e2z }, - *cs0[] = { s0x, s0y, s0z }, - *cs1[] = { s1x, s1y, s1z }, - *cs2[] = { s2x, s2y, s2z }; - const double *coeffs; - -/* Numbers of terms for each component of the model, in x,y,z sets */ - static const int ne0[3] = {(int)(sizeof e0x / sizeof (double) / 3), - (int)(sizeof e0y / sizeof (double) / 3), - (int)(sizeof e0z / sizeof (double) / 3) }, - ne1[3] = {(int)(sizeof e1x / sizeof (double) / 3), - (int)(sizeof e1y / sizeof (double) / 3), - (int)(sizeof e1z / sizeof (double) / 3) }, - ne2[3] = {(int)(sizeof e2x / sizeof (double) / 3), - (int)(sizeof e2y / sizeof (double) / 3), - (int)(sizeof e2z / sizeof (double) / 3) }, - ns0[3] = {(int)(sizeof s0x / sizeof (double) / 3), - (int)(sizeof s0y / sizeof (double) / 3), - (int)(sizeof s0z / sizeof (double) / 3) }, - ns1[3] = {(int)(sizeof s1x / sizeof (double) / 3), - (int)(sizeof s1y / sizeof (double) / 3), - (int)(sizeof s1z / sizeof (double) / 3) }, - ns2[3] = {(int)(sizeof s2x / sizeof (double) / 3), - (int)(sizeof s2y / sizeof (double) / 3), - (int)(sizeof s2z / sizeof (double) / 3) }; - int nterms; - -/* Miscellaneous */ - int jstat, i, j; - double t, t2, xyz, xyzd, a, b, c, ct, p, cp, - ph[3], vh[3], pb[3], vb[3], x, y, z; - -/*--------------------------------------------------------------------*/ - -/* Time since reference epoch, Julian years. */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJY; - t2 = t*t; - -/* Set status. */ - jstat = fabs(t) <= 100.0 ? 0 : 1; - -/* X then Y then Z. */ - for (i = 0; i < 3; i++) { - - /* Initialize position and velocity component. */ - xyz = 0.0; - xyzd = 0.0; - - /* ------------------------------------------------ */ - /* Obtain component of Sun to Earth ecliptic vector */ - /* ------------------------------------------------ */ - - /* Sun to Earth, T^0 terms. */ - coeffs = ce0[i]; - nterms = ne0[i]; - for (j = 0; j < nterms; j++) { - a = *coeffs++; - b = *coeffs++; - c = *coeffs++; - p = b + c*t; - xyz += a*cos(p); - xyzd -= a*c*sin(p); - } - - /* Sun to Earth, T^1 terms. */ - coeffs = ce1[i]; - nterms = ne1[i]; - for (j = 0; j < nterms; j++) { - a = *coeffs++; - b = *coeffs++; - c = *coeffs++; - ct = c*t; - p = b + ct; - cp = cos(p); - xyz += a*t*cp; - xyzd += a*( cp - ct*sin(p) ); - } - - /* Sun to Earth, T^2 terms. */ - coeffs = ce2[i]; - nterms = ne2[i]; - for (j = 0; j < nterms; j++) { - a = *coeffs++; - b = *coeffs++; - c = *coeffs++; - ct = c*t; - p = b + ct; - cp = cos(p); - xyz += a*t2*cp; - xyzd += a*t*( 2.0*cp - ct*sin(p) ); - } - - /* Heliocentric Earth position and velocity component. */ - ph[i] = xyz; - vh[i] = xyzd / ERFA_DJY; - - /* ------------------------------------------------ */ - /* Obtain component of SSB to Earth ecliptic vector */ - /* ------------------------------------------------ */ - - /* SSB to Sun, T^0 terms. */ - coeffs = cs0[i]; - nterms = ns0[i]; - for (j = 0; j < nterms; j++) { - a = *coeffs++; - b = *coeffs++; - c = *coeffs++; - p = b + c*t; - xyz += a*cos(p); - xyzd -= a*c*sin(p); - } - - /* SSB to Sun, T^1 terms. */ - coeffs = cs1[i]; - nterms = ns1[i]; - for (j = 0; j < nterms; j++) { - a = *coeffs++; - b = *coeffs++; - c = *coeffs++; - ct = c*t; - p = b + ct; - cp = cos(p); - xyz += a*t*cp; - xyzd += a*(cp - ct*sin(p)); - } - - /* SSB to Sun, T^2 terms. */ - coeffs = cs2[i]; - nterms = ns2[i]; - for (j = 0; j < nterms; j++) { - a = *coeffs++; - b = *coeffs++; - c = *coeffs++; - ct = c*t; - p = b + ct; - cp = cos(p); - xyz += a*t2*cp; - xyzd += a*t*(2.0*cp - ct*sin(p)); - } - - /* Barycentric Earth position and velocity component. */ - pb[i] = xyz; - vb[i] = xyzd / ERFA_DJY; - - /* Next Cartesian component. */ - } - -/* Rotate from ecliptic to BCRS coordinates. */ - - x = ph[0]; - y = ph[1]; - z = ph[2]; - pvh[0][0] = x + am12*y + am13*z; - pvh[0][1] = am21*x + am22*y + am23*z; - pvh[0][2] = am32*y + am33*z; - - x = vh[0]; - y = vh[1]; - z = vh[2]; - pvh[1][0] = x + am12*y + am13*z; - pvh[1][1] = am21*x + am22*y + am23*z; - pvh[1][2] = am32*y + am33*z; - - x = pb[0]; - y = pb[1]; - z = pb[2]; - pvb[0][0] = x + am12*y + am13*z; - pvb[0][1] = am21*x + am22*y + am23*z; - pvb[0][2] = am32*y + am33*z; - - x = vb[0]; - y = vb[1]; - z = vb[2]; - pvb[1][0] = x + am12*y + am13*z; - pvb[1][1] = am21*x + am22*y + am23*z; - pvb[1][2] = am32*y + am33*z; - -/* Return the status. */ - return jstat; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/eqec06.c b/ast/erfa/eqec06.c deleted file mode 100644 index 6a667c9..0000000 --- a/ast/erfa/eqec06.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "erfa.h" - -void eraEqec06(double date1, double date2, double dr, double dd, - double *dl, double *db) -/* -** - - - - - - - - - - -** e r a E q e c 0 6 -** - - - - - - - - - - -** -** Transformation from ICRS equatorial coordinates to ecliptic -** coordinates (mean equinox and ecliptic of date) using IAU 2006 -** precession model. -** -** Given: -** date1,date2 double TT as a 2-part Julian date (Note 1) -** dr,dd double ICRS right ascension and declination (radians) -** -** Returned: -** dl,db double ecliptic longitude and latitude (radians) -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) No assumptions are made about whether the coordinates represent -** starlight and embody astrometric effects such as parallax or -** aberration. -** -** 3) The transformation is approximately that from mean J2000.0 right -** ascension and declination to ecliptic longitude and latitude -** (mean equinox and ecliptic of date), with only frame bias (always -** less than 25 mas) to disturb this classical picture. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraEcm06 J2000.0 to ecliptic rotation matrix, IAU 2006 -** eraRxp product of r-matrix and p-vector -** eraC2s unit vector to spherical coordinates -** eraAnp normalize angle into range 0 to 2pi -** eraAnpm normalize angle into range +/- pi -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rm[3][3], v1[3], v2[3], a, b; - - -/* Spherical to Cartesian. */ - eraS2c(dr, dd, v1); - -/* Rotation matrix, ICRS equatorial to ecliptic. */ - eraEcm06(date1, date2, rm); - -/* The transformation from ICRS to ecliptic. */ - eraRxp(rm, v1, v2); - -/* Cartesian to spherical. */ - eraC2s(v2, &a, &b); - -/* Express in conventional ranges. */ - *dl = eraAnp(a); - *db = eraAnpm(b); - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/eqeq94.c b/ast/erfa/eqeq94.c deleted file mode 100644 index 00076b1..0000000 --- a/ast/erfa/eqeq94.c +++ /dev/null @@ -1,141 +0,0 @@ -#include "erfa.h" - -double eraEqeq94(double date1, double date2) -/* -** - - - - - - - - - - -** e r a E q e q 9 4 -** - - - - - - - - - - -** -** Equation of the equinoxes, IAU 1994 model. -** -** Given: -** date1,date2 double TDB date (Note 1) -** -** Returned (function value): -** double equation of the equinoxes (Note 2) -** -** Notes: -** -** 1) The date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The result, which is in radians, operates in the following sense: -** -** Greenwich apparent ST = GMST + equation of the equinoxes -** -** Called: -** eraAnpm normalize angle into range +/- pi -** eraNut80 nutation, IAU 1980 -** eraObl80 mean obliquity, IAU 1980 -** -** References: -** -** IAU Resolution C7, Recommendation 3 (1994). -** -** Capitaine, N. & Gontier, A.-M., 1993, Astron. Astrophys., 275, -** 645-650. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, om, dpsi, deps, eps0, ee; - - -/* Interval between fundamental epoch J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Longitude of the mean ascending node of the lunar orbit on the */ -/* ecliptic, measured from the mean equinox of date. */ - om = eraAnpm((450160.280 + (-482890.539 - + (7.455 + 0.008 * t) * t) * t) * ERFA_DAS2R - + fmod(-5.0 * t, 1.0) * ERFA_D2PI); - -/* Nutation components and mean obliquity. */ - eraNut80(date1, date2, &dpsi, &deps); - eps0 = eraObl80(date1, date2); - -/* Equation of the equinoxes. */ - ee = dpsi*cos(eps0) + ERFA_DAS2R*(0.00264*sin(om) + 0.000063*sin(om+om)); - - return ee; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/era00.c b/ast/erfa/era00.c deleted file mode 100644 index 01e06f5..0000000 --- a/ast/erfa/era00.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "erfa.h" - -double eraEra00(double dj1, double dj2) -/* -** - - - - - - - - - -** e r a E r a 0 0 -** - - - - - - - - - -** -** Earth rotation angle (IAU 2000 model). -** -** Given: -** dj1,dj2 double UT1 as a 2-part Julian Date (see note) -** -** Returned (function value): -** double Earth rotation angle (radians), range 0-2pi -** -** Notes: -** -** 1) The UT1 date dj1+dj2 is a Julian Date, apportioned in any -** convenient way between the arguments dj1 and dj2. For example, -** JD(UT1)=2450123.7 could be expressed in any of these ways, -** among others: -** -** dj1 dj2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. The date & time method is -** best matched to the algorithm used: maximum precision is -** delivered when the dj1 argument is for 0hrs UT1 on the day in -** question and the dj2 argument lies in the range 0 to 1, or vice -** versa. -** -** 2) The algorithm is adapted from Expression 22 of Capitaine et al. -** 2000. The time argument has been expressed in days directly, -** and, to retain precision, integer contributions have been -** eliminated. The same formulation is given in IERS Conventions -** (2003), Chap. 5, Eq. 14. -** -** Called: -** eraAnp normalize angle into range 0 to 2pi -** -** References: -** -** Capitaine N., Guinot B. and McCarthy D.D, 2000, Astron. -** Astrophys., 355, 398-405. -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double d1, d2, t, f, theta; - - -/* Days since fundamental epoch. */ - if (dj1 < dj2) { - d1 = dj1; - d2 = dj2; - } else { - d1 = dj2; - d2 = dj1; - } - t = d1 + (d2- ERFA_DJ00); - -/* Fractional part of T (days). */ - f = fmod(d1, 1.0) + fmod(d2, 1.0); - -/* Earth rotation angle at this UT1. */ - theta = eraAnp(ERFA_D2PI * (f + 0.7790572732640 - + 0.00273781191135448 * t)); - - return theta; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/erfa.h b/ast/erfa/erfa.h deleted file mode 100644 index c22f470..0000000 --- a/ast/erfa/erfa.h +++ /dev/null @@ -1,517 +0,0 @@ -#ifndef ERFAHDEF -#define ERFAHDEF - -/* -** - - - - - - - -** e r f a . h -** - - - - - - - -** -** Prototype function declarations for ERFA library. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ - -#include "erfam.h" -#include "math.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Astronomy/Calendars */ -int eraCal2jd(int iy, int im, int id, double *djm0, double *djm); -double eraEpb(double dj1, double dj2); -void eraEpb2jd(double epb, double *djm0, double *djm); -double eraEpj(double dj1, double dj2); -void eraEpj2jd(double epj, double *djm0, double *djm); -int eraJd2cal(double dj1, double dj2, - int *iy, int *im, int *id, double *fd); -int eraJdcalf(int ndp, double dj1, double dj2, int iymdf[4]); - -/* Astronomy/Astrometry */ -void eraAb(double pnat[3], double v[3], double s, double bm1, - double ppr[3]); -void eraApcg(double date1, double date2, - double ebpv[2][3], double ehp[3], - eraASTROM *astrom); -void eraApcg13(double date1, double date2, eraASTROM *astrom); -void eraApci(double date1, double date2, - double ebpv[2][3], double ehp[3], - double x, double y, double s, - eraASTROM *astrom); -void eraApci13(double date1, double date2, - eraASTROM *astrom, double *eo); -void eraApco(double date1, double date2, - double ebpv[2][3], double ehp[3], - double x, double y, double s, double theta, - double elong, double phi, double hm, - double xp, double yp, double sp, - double refa, double refb, - eraASTROM *astrom); -int eraApco13(double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - eraASTROM *astrom, double *eo); -void eraApcs(double date1, double date2, double pv[2][3], - double ebpv[2][3], double ehp[3], - eraASTROM *astrom); -void eraApcs13(double date1, double date2, double pv[2][3], - eraASTROM *astrom); -void eraAper(double theta, eraASTROM *astrom); -void eraAper13(double ut11, double ut12, eraASTROM *astrom); -void eraApio(double sp, double theta, - double elong, double phi, double hm, double xp, double yp, - double refa, double refb, - eraASTROM *astrom); -int eraApio13(double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - eraASTROM *astrom); -void eraAtci13(double rc, double dc, - double pr, double pd, double px, double rv, - double date1, double date2, - double *ri, double *di, double *eo); -void eraAtciq(double rc, double dc, double pr, double pd, - double px, double rv, eraASTROM *astrom, - double *ri, double *di); -void eraAtciqn(double rc, double dc, double pr, double pd, - double px, double rv, eraASTROM *astrom, - int n, eraLDBODY b[], double *ri, double *di); -void eraAtciqz(double rc, double dc, eraASTROM *astrom, - double *ri, double *di); -int eraAtco13(double rc, double dc, - double pr, double pd, double px, double rv, - double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - double *aob, double *zob, double *hob, - double *dob, double *rob, double *eo); -void eraAtic13(double ri, double di, - double date1, double date2, - double *rc, double *dc, double *eo); -void eraAticq(double ri, double di, eraASTROM *astrom, - double *rc, double *dc); -void eraAticqn(double ri, double di, eraASTROM *astrom, - int n, eraLDBODY b[], double *rc, double *dc); -int eraAtio13(double ri, double di, - double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - double *aob, double *zob, double *hob, - double *dob, double *rob); -void eraAtioq(double ri, double di, eraASTROM *astrom, - double *aob, double *zob, - double *hob, double *dob, double *rob); -int eraAtoc13(const char *type, double ob1, double ob2, - double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - double *rc, double *dc); -int eraAtoi13(const char *type, double ob1, double ob2, - double utc1, double utc2, double dut1, - double elong, double phi, double hm, double xp, double yp, - double phpa, double tc, double rh, double wl, - double *ri, double *di); -void eraAtoiq(const char *type, - double ob1, double ob2, eraASTROM *astrom, - double *ri, double *di); -void eraLd(double bm, double p[3], double q[3], double e[3], - double em, double dlim, double p1[3]); -void eraLdn(int n, eraLDBODY b[], double ob[3], double sc[3], - double sn[3]); -void eraLdsun(double p[3], double e[3], double em, double p1[3]); -void eraPmpx(double rc, double dc, double pr, double pd, - double px, double rv, double pmt, double pob[3], - double pco[3]); -int eraPmsafe(double ra1, double dec1, double pmr1, double pmd1, - double px1, double rv1, - double ep1a, double ep1b, double ep2a, double ep2b, - double *ra2, double *dec2, double *pmr2, double *pmd2, - double *px2, double *rv2); -void eraPvtob(double elong, double phi, double height, double xp, - double yp, double sp, double theta, double pv[2][3]); -void eraRefco(double phpa, double tc, double rh, double wl, - double *refa, double *refb); - -/* Astronomy/Ephemerides */ -int eraEpv00(double date1, double date2, - double pvh[2][3], double pvb[2][3]); -int eraPlan94(double date1, double date2, int np, double pv[2][3]); - -/* Astronomy/FundamentalArgs */ -double eraFad03(double t); -double eraFae03(double t); -double eraFaf03(double t); -double eraFaju03(double t); -double eraFal03(double t); -double eraFalp03(double t); -double eraFama03(double t); -double eraFame03(double t); -double eraFane03(double t); -double eraFaom03(double t); -double eraFapa03(double t); -double eraFasa03(double t); -double eraFaur03(double t); -double eraFave03(double t); - -/* Astronomy/PrecNutPolar */ -void eraBi00(double *dpsibi, double *depsbi, double *dra); -void eraBp00(double date1, double date2, - double rb[3][3], double rp[3][3], double rbp[3][3]); -void eraBp06(double date1, double date2, - double rb[3][3], double rp[3][3], double rbp[3][3]); -void eraBpn2xy(double rbpn[3][3], double *x, double *y); -void eraC2i00a(double date1, double date2, double rc2i[3][3]); -void eraC2i00b(double date1, double date2, double rc2i[3][3]); -void eraC2i06a(double date1, double date2, double rc2i[3][3]); -void eraC2ibpn(double date1, double date2, double rbpn[3][3], - double rc2i[3][3]); -void eraC2ixy(double date1, double date2, double x, double y, - double rc2i[3][3]); -void eraC2ixys(double x, double y, double s, double rc2i[3][3]); -void eraC2t00a(double tta, double ttb, double uta, double utb, - double xp, double yp, double rc2t[3][3]); -void eraC2t00b(double tta, double ttb, double uta, double utb, - double xp, double yp, double rc2t[3][3]); -void eraC2t06a(double tta, double ttb, double uta, double utb, - double xp, double yp, double rc2t[3][3]); -void eraC2tcio(double rc2i[3][3], double era, double rpom[3][3], - double rc2t[3][3]); -void eraC2teqx(double rbpn[3][3], double gst, double rpom[3][3], - double rc2t[3][3]); -void eraC2tpe(double tta, double ttb, double uta, double utb, - double dpsi, double deps, double xp, double yp, - double rc2t[3][3]); -void eraC2txy(double tta, double ttb, double uta, double utb, - double x, double y, double xp, double yp, - double rc2t[3][3]); -double eraEo06a(double date1, double date2); -double eraEors(double rnpb[3][3], double s); -void eraFw2m(double gamb, double phib, double psi, double eps, - double r[3][3]); -void eraFw2xy(double gamb, double phib, double psi, double eps, - double *x, double *y); -void eraLtp(double epj, double rp[3][3]); -void eraLtpb(double epj, double rpb[3][3]); -void eraLtpecl(double epj, double vec[3]); -void eraLtpequ(double epj, double veq[3]); -void eraNum00a(double date1, double date2, double rmatn[3][3]); -void eraNum00b(double date1, double date2, double rmatn[3][3]); -void eraNum06a(double date1, double date2, double rmatn[3][3]); -void eraNumat(double epsa, double dpsi, double deps, double rmatn[3][3]); -void eraNut00a(double date1, double date2, double *dpsi, double *deps); -void eraNut00b(double date1, double date2, double *dpsi, double *deps); -void eraNut06a(double date1, double date2, double *dpsi, double *deps); -void eraNut80(double date1, double date2, double *dpsi, double *deps); -void eraNutm80(double date1, double date2, double rmatn[3][3]); -double eraObl06(double date1, double date2); -double eraObl80(double date1, double date2); -void eraP06e(double date1, double date2, - double *eps0, double *psia, double *oma, double *bpa, - double *bqa, double *pia, double *bpia, - double *epsa, double *chia, double *za, double *zetaa, - double *thetaa, double *pa, - double *gam, double *phi, double *psi); -void eraPb06(double date1, double date2, - double *bzeta, double *bz, double *btheta); -void eraPfw06(double date1, double date2, - double *gamb, double *phib, double *psib, double *epsa); -void eraPmat00(double date1, double date2, double rbp[3][3]); -void eraPmat06(double date1, double date2, double rbp[3][3]); -void eraPmat76(double date1, double date2, double rmatp[3][3]); -void eraPn00(double date1, double date2, double dpsi, double deps, - double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]); -void eraPn00a(double date1, double date2, - double *dpsi, double *deps, double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]); -void eraPn00b(double date1, double date2, - double *dpsi, double *deps, double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]); -void eraPn06(double date1, double date2, double dpsi, double deps, - double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]); -void eraPn06a(double date1, double date2, - double *dpsi, double *deps, double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]); -void eraPnm00a(double date1, double date2, double rbpn[3][3]); -void eraPnm00b(double date1, double date2, double rbpn[3][3]); -void eraPnm06a(double date1, double date2, double rnpb[3][3]); -void eraPnm80(double date1, double date2, double rmatpn[3][3]); -void eraPom00(double xp, double yp, double sp, double rpom[3][3]); -void eraPr00(double date1, double date2, - double *dpsipr, double *depspr); -void eraPrec76(double date01, double date02, - double date11, double date12, - double *zeta, double *z, double *theta); -double eraS00(double date1, double date2, double x, double y); -double eraS00a(double date1, double date2); -double eraS00b(double date1, double date2); -double eraS06(double date1, double date2, double x, double y); -double eraS06a(double date1, double date2); -double eraSp00(double date1, double date2); -void eraXy06(double date1, double date2, double *x, double *y); -void eraXys00a(double date1, double date2, - double *x, double *y, double *s); -void eraXys00b(double date1, double date2, - double *x, double *y, double *s); -void eraXys06a(double date1, double date2, - double *x, double *y, double *s); - -/* Astronomy/RotationAndTime */ -double eraEe00(double date1, double date2, double epsa, double dpsi); -double eraEe00a(double date1, double date2); -double eraEe00b(double date1, double date2); -double eraEe06a(double date1, double date2); -double eraEect00(double date1, double date2); -double eraEqeq94(double date1, double date2); -double eraEra00(double dj1, double dj2); -double eraGmst00(double uta, double utb, double tta, double ttb); -double eraGmst06(double uta, double utb, double tta, double ttb); -double eraGmst82(double dj1, double dj2); -double eraGst00a(double uta, double utb, double tta, double ttb); -double eraGst00b(double uta, double utb); -double eraGst06(double uta, double utb, double tta, double ttb, - double rnpb[3][3]); -double eraGst06a(double uta, double utb, double tta, double ttb); -double eraGst94(double uta, double utb); - -/* Astronomy/SpaceMotion */ -int eraPvstar(double pv[2][3], double *ra, double *dec, - double *pmr, double *pmd, double *px, double *rv); -int eraStarpv(double ra, double dec, - double pmr, double pmd, double px, double rv, - double pv[2][3]); - -/* Astronomy/StarCatalogs */ -void eraFk52h(double r5, double d5, - double dr5, double dd5, double px5, double rv5, - double *rh, double *dh, - double *drh, double *ddh, double *pxh, double *rvh); -void eraFk5hip(double r5h[3][3], double s5h[3]); -void eraFk5hz(double r5, double d5, double date1, double date2, - double *rh, double *dh); -void eraH2fk5(double rh, double dh, - double drh, double ddh, double pxh, double rvh, - double *r5, double *d5, - double *dr5, double *dd5, double *px5, double *rv5); -void eraHfk5z(double rh, double dh, double date1, double date2, - double *r5, double *d5, double *dr5, double *dd5); -int eraStarpm(double ra1, double dec1, - double pmr1, double pmd1, double px1, double rv1, - double ep1a, double ep1b, double ep2a, double ep2b, - double *ra2, double *dec2, - double *pmr2, double *pmd2, double *px2, double *rv2); - -/* Astronomy/EclipticCoordinates */ -void eraEceq06(double date1, double date2, double dl, double db, - double *dr, double *dd); -void eraEcm06(double date1, double date2, double rm[3][3]); -void eraEqec06(double date1, double date2, double dr, double dd, - double *dl, double *db); -void eraLteceq(double epj, double dl, double db, double *dr, double *dd); -void eraLtecm(double epj, double rm[3][3]); -void eraLteqec(double epj, double dr, double dd, double *dl, double *db); - -/* Astronomy/GalacticCoordinates */ -void eraG2icrs(double dl, double db, double *dr, double *dd); -void eraIcrs2g(double dr, double dd, double *dl, double *db); - -/* Astronomy/GeodeticGeocentric */ -int eraEform(int n, double *a, double *f); -int eraGc2gd(int n, double xyz[3], - double *elong, double *phi, double *height); -int eraGc2gde(double a, double f, double xyz[3], - double *elong, double *phi, double *height); -int eraGd2gc(int n, double elong, double phi, double height, - double xyz[3]); -int eraGd2gce(double a, double f, - double elong, double phi, double height, double xyz[3]); - -/* Astronomy/Timescales */ -int eraD2dtf(const char *scale, int ndp, double d1, double d2, - int *iy, int *im, int *id, int ihmsf[4]); -int eraDat(int iy, int im, int id, double fd, double *deltat); -double eraDtdb(double date1, double date2, - double ut, double elong, double u, double v); -int eraDtf2d(const char *scale, int iy, int im, int id, - int ihr, int imn, double sec, double *d1, double *d2); -int eraTaitt(double tai1, double tai2, double *tt1, double *tt2); -int eraTaiut1(double tai1, double tai2, double dta, - double *ut11, double *ut12); -int eraTaiutc(double tai1, double tai2, double *utc1, double *utc2); -int eraTcbtdb(double tcb1, double tcb2, double *tdb1, double *tdb2); -int eraTcgtt(double tcg1, double tcg2, double *tt1, double *tt2); -int eraTdbtcb(double tdb1, double tdb2, double *tcb1, double *tcb2); -int eraTdbtt(double tdb1, double tdb2, double dtr, - double *tt1, double *tt2); -int eraTttai(double tt1, double tt2, double *tai1, double *tai2); -int eraTttcg(double tt1, double tt2, double *tcg1, double *tcg2); -int eraTttdb(double tt1, double tt2, double dtr, - double *tdb1, double *tdb2); -int eraTtut1(double tt1, double tt2, double dt, - double *ut11, double *ut12); -int eraUt1tai(double ut11, double ut12, double dta, - double *tai1, double *tai2); -int eraUt1tt(double ut11, double ut12, double dt, - double *tt1, double *tt2); -int eraUt1utc(double ut11, double ut12, double dut1, - double *utc1, double *utc2); -int eraUtctai(double utc1, double utc2, double *tai1, double *tai2); -int eraUtcut1(double utc1, double utc2, double dut1, - double *ut11, double *ut12); - -/* VectorMatrix/AngleOps */ -void eraA2af(int ndp, double angle, char *sign, int idmsf[4]); -void eraA2tf(int ndp, double angle, char *sign, int ihmsf[4]); -int eraAf2a(char s, int ideg, int iamin, double asec, double *rad); -double eraAnp(double a); -double eraAnpm(double a); -void eraD2tf(int ndp, double days, char *sign, int ihmsf[4]); -int eraTf2a(char s, int ihour, int imin, double sec, double *rad); -int eraTf2d(char s, int ihour, int imin, double sec, double *days); - -/* VectorMatrix/BuildRotations */ -void eraRx(double phi, double r[3][3]); -void eraRy(double theta, double r[3][3]); -void eraRz(double psi, double r[3][3]); - -/* VectorMatrix/CopyExtendExtract */ -void eraCp(double p[3], double c[3]); -void eraCpv(double pv[2][3], double c[2][3]); -void eraCr(double r[3][3], double c[3][3]); -void eraP2pv(double p[3], double pv[2][3]); -void eraPv2p(double pv[2][3], double p[3]); - -/* VectorMatrix/Initialization */ -void eraIr(double r[3][3]); -void eraZp(double p[3]); -void eraZpv(double pv[2][3]); -void eraZr(double r[3][3]); - -/* VectorMatrix/MatrixOps */ -void eraRxr(double a[3][3], double b[3][3], double atb[3][3]); -void eraTr(double r[3][3], double rt[3][3]); - -/* VectorMatrix/MatrixVectorProducts */ -void eraRxp(double r[3][3], double p[3], double rp[3]); -void eraRxpv(double r[3][3], double pv[2][3], double rpv[2][3]); -void eraTrxp(double r[3][3], double p[3], double trp[3]); -void eraTrxpv(double r[3][3], double pv[2][3], double trpv[2][3]); - -/* VectorMatrix/RotationVectors */ -void eraRm2v(double r[3][3], double w[3]); -void eraRv2m(double w[3], double r[3][3]); - -/* VectorMatrix/SeparationAndAngle */ -double eraPap(double a[3], double b[3]); -double eraPas(double al, double ap, double bl, double bp); -double eraSepp(double a[3], double b[3]); -double eraSeps(double al, double ap, double bl, double bp); - -/* VectorMatrix/SphericalCartesian */ -void eraC2s(double p[3], double *theta, double *phi); -void eraP2s(double p[3], double *theta, double *phi, double *r); -void eraPv2s(double pv[2][3], - double *theta, double *phi, double *r, - double *td, double *pd, double *rd); -void eraS2c(double theta, double phi, double c[3]); -void eraS2p(double theta, double phi, double r, double p[3]); -void eraS2pv(double theta, double phi, double r, - double td, double pd, double rd, - double pv[2][3]); - -/* VectorMatrix/VectorOps */ -double eraPdp(double a[3], double b[3]); -double eraPm(double p[3]); -void eraPmp(double a[3], double b[3], double amb[3]); -void eraPn(double p[3], double *r, double u[3]); -void eraPpp(double a[3], double b[3], double apb[3]); -void eraPpsp(double a[3], double s, double b[3], double apsb[3]); -void eraPvdpv(double a[2][3], double b[2][3], double adb[2]); -void eraPvm(double pv[2][3], double *r, double *s); -void eraPvmpv(double a[2][3], double b[2][3], double amb[2][3]); -void eraPvppv(double a[2][3], double b[2][3], double apb[2][3]); -void eraPvu(double dt, double pv[2][3], double upv[2][3]); -void eraPvup(double dt, double pv[2][3], double p[3]); -void eraPvxpv(double a[2][3], double b[2][3], double axb[2][3]); -void eraPxp(double a[3], double b[3], double axb[3]); -void eraS2xpv(double s1, double s2, double pv[2][3], double spv[2][3]); -void eraSxp(double s, double p[3], double sp[3]); -void eraSxpv(double s, double pv[2][3], double spv[2][3]); - -#ifdef __cplusplus -} -#endif - -#endif - - -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/erfam.h b/ast/erfa/erfam.h deleted file mode 100644 index 750c4c2..0000000 --- a/ast/erfa/erfam.h +++ /dev/null @@ -1,208 +0,0 @@ -#ifndef ERFAMHDEF -#define ERFAMHDEF - -/* -** - - - - - - - - -** e r f a m . h -** - - - - - - - - -** -** Macros used by ERFA library. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ - -/* Star-independent astrometry parameters */ -typedef struct { - double pmt; /* PM time interval (SSB, Julian years) */ - double eb[3]; /* SSB to observer (vector, au) */ - double eh[3]; /* Sun to observer (unit vector) */ - double em; /* distance from Sun to observer (au) */ - double v[3]; /* barycentric observer velocity (vector, c) */ - double bm1; /* sqrt(1-|v|^2): reciprocal of Lorenz factor */ - double bpn[3][3]; /* bias-precession-nutation matrix */ - double along; /* longitude + s' + dERA(DUT) (radians) */ - double phi; /* geodetic latitude (radians) */ - double xpl; /* polar motion xp wrt local meridian (radians) */ - double ypl; /* polar motion yp wrt local meridian (radians) */ - double sphi; /* sine of geodetic latitude */ - double cphi; /* cosine of geodetic latitude */ - double diurab; /* magnitude of diurnal aberration vector */ - double eral; /* "local" Earth rotation angle (radians) */ - double refa; /* refraction constant A (radians) */ - double refb; /* refraction constant B (radians) */ -} eraASTROM; -/* (Vectors eb, eh, em and v are all with respect to BCRS axes.) */ - -/* Body parameters for light deflection */ -typedef struct { - double bm; /* mass of the body (solar masses) */ - double dl; /* deflection limiter (radians^2/2) */ - double pv[2][3]; /* barycentric PV of the body (au, au/day) */ -} eraLDBODY; - -/* Pi */ -#define ERFA_DPI (3.141592653589793238462643) - -/* 2Pi */ -#define ERFA_D2PI (6.283185307179586476925287) - -/* Radians to degrees */ -#define ERFA_DR2D (57.29577951308232087679815) - -/* Degrees to radians */ -#define ERFA_DD2R (1.745329251994329576923691e-2) - -/* Radians to arcseconds */ -#define ERFA_DR2AS (206264.8062470963551564734) - -/* Arcseconds to radians */ -#define ERFA_DAS2R (4.848136811095359935899141e-6) - -/* Seconds of time to radians */ -#define ERFA_DS2R (7.272205216643039903848712e-5) - -/* Arcseconds in a full circle */ -#define ERFA_TURNAS (1296000.0) - -/* Milliarcseconds to radians */ -#define ERFA_DMAS2R (ERFA_DAS2R / 1e3) - -/* Length of tropical year B1900 (days) */ -#define ERFA_DTY (365.242198781) - -/* Seconds per day. */ -#define ERFA_DAYSEC (86400.0) - -/* Days per Julian year */ -#define ERFA_DJY (365.25) - -/* Days per Julian century */ -#define ERFA_DJC (36525.0) - -/* Days per Julian millennium */ -#define ERFA_DJM (365250.0) - -/* Reference epoch (J2000.0), Julian Date */ -#define ERFA_DJ00 (2451545.0) - -/* Julian Date of Modified Julian Date zero */ -#define ERFA_DJM0 (2400000.5) - -/* Reference epoch (J2000.0), Modified Julian Date */ -#define ERFA_DJM00 (51544.5) - -/* 1977 Jan 1.0 as MJD */ -#define ERFA_DJM77 (43144.0) - -/* TT minus TAI (s) */ -#define ERFA_TTMTAI (32.184) - -/* Astronomical unit (m) */ -#define ERFA_DAU (149597870e3) - -/* Speed of light (m/s) */ -#define ERFA_CMPS 299792458.0 - -/* Light time for 1 au (s) */ -#define ERFA_AULT 499.004782 - -/* Speed of light (AU per day) */ -#define ERFA_DC (ERFA_DAYSEC / ERFA_AULT) - -/* L_G = 1 - d(TT)/d(TCG) */ -#define ERFA_ELG (6.969290134e-10) - -/* L_B = 1 - d(TDB)/d(TCB), and TDB (s) at TAI 1977/1/1.0 */ -#define ERFA_ELB (1.550519768e-8) -#define ERFA_TDB0 (-6.55e-5) - -/* Schwarzschild radius of the Sun (au) */ -/* = 2 * 1.32712440041e20 / (2.99792458e8)^2 / 1.49597870700e11 */ -#define ERFA_SRS 1.97412574336e-8 - -/* ERFA_DINT(A) - truncate to nearest whole number towards zero (double) */ -#define ERFA_DINT(A) ((A)<0.0?ceil(A):floor(A)) - -/* ERFA_DNINT(A) - round to nearest whole number (double) */ -#define ERFA_DNINT(A) ((A)<0.0?ceil((A)-0.5):floor((A)+0.5)) - -/* ERFA_DSIGN(A,B) - magnitude of A with sign of B (double) */ -#define ERFA_DSIGN(A,B) ((B)<0.0?-fabs(A):fabs(A)) - -/* max(A,B) - larger (most +ve) of two numbers (generic) */ -#define ERFA_GMAX(A,B) (((A)>(B))?(A):(B)) - -/* min(A,B) - smaller (least +ve) of two numbers (generic) */ -#define ERFA_GMIN(A,B) (((A)<(B))?(A):(B)) - -/* Reference ellipsoids */ -#define ERFA_WGS84 1 -#define ERFA_GRS80 2 -#define ERFA_WGS72 3 - -#endif - - -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fad03.c b/ast/erfa/fad03.c deleted file mode 100644 index 421f937..0000000 --- a/ast/erfa/fad03.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "erfa.h" - -double eraFad03(double t) -/* -** - - - - - - - - - -** e r a F a d 0 3 -** - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean elongation of the Moon from the Sun. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double D, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** is from Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean elongation of the Moon from the Sun (IERS Conventions 2003). */ - a = fmod( 1072260.703692 + - t * ( 1602961601.2090 + - t * ( - 6.3706 + - t * ( 0.006593 + - t * ( - 0.00003169 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R; - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fae03.c b/ast/erfa/fae03.c deleted file mode 100644 index e40b1c9..0000000 --- a/ast/erfa/fae03.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "erfa.h" - -double eraFae03(double t) -/* -** - - - - - - - - - -** e r a F a e 0 3 -** - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of Earth. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double mean longitude of Earth, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** comes from Souchay et al. (1999) after Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999, -** Astron.Astrophys.Supp.Ser. 135, 111 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of Earth (IERS Conventions 2003). */ - a = fmod(1.753470314 + 628.3075849991 * t, ERFA_D2PI); - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/faf03.c b/ast/erfa/faf03.c deleted file mode 100644 index aa7850a..0000000 --- a/ast/erfa/faf03.c +++ /dev/null @@ -1,115 +0,0 @@ -#include "erfa.h" - -double eraFaf03(double t) -/* -** - - - - - - - - - -** e r a F a f 0 3 -** - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of the Moon minus mean longitude of the ascending -** node. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double F, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** is from Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of the Moon minus that of the ascending node */ -/* (IERS Conventions 2003). */ - a = fmod( 335779.526232 + - t * ( 1739527262.8478 + - t * ( - 12.7512 + - t * ( - 0.001037 + - t * ( 0.00000417 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R; - - return a; - - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/faju03.c b/ast/erfa/faju03.c deleted file mode 100644 index 9b9298f..0000000 --- a/ast/erfa/faju03.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "erfa.h" - -double eraFaju03(double t) -/* -** - - - - - - - - - - -** e r a F a j u 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of Jupiter. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double mean longitude of Jupiter, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** comes from Souchay et al. (1999) after Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999, -** Astron.Astrophys.Supp.Ser. 135, 111 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of Jupiter (IERS Conventions 2003). */ - a = fmod(0.599546497 + 52.9690962641 * t, ERFA_D2PI); - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fal03.c b/ast/erfa/fal03.c deleted file mode 100644 index 1d80d20..0000000 --- a/ast/erfa/fal03.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "erfa.h" - -double eraFal03(double t) -/* -** - - - - - - - - - -** e r a F a l 0 3 -** - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean anomaly of the Moon. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double l, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** is from Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean anomaly of the Moon (IERS Conventions 2003). */ - a = fmod( 485868.249036 + - t * ( 1717915923.2178 + - t * ( 31.8792 + - t * ( 0.051635 + - t * ( - 0.00024470 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R; - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/falp03.c b/ast/erfa/falp03.c deleted file mode 100644 index 4080809..0000000 --- a/ast/erfa/falp03.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "erfa.h" - -double eraFalp03(double t) -/* -** - - - - - - - - - - -** e r a F a l p 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean anomaly of the Sun. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double l', radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** is from Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean anomaly of the Sun (IERS Conventions 2003). */ - a = fmod( 1287104.793048 + - t * ( 129596581.0481 + - t * ( - 0.5532 + - t * ( 0.000136 + - t * ( - 0.00001149 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R; - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fama03.c b/ast/erfa/fama03.c deleted file mode 100644 index 21bff75..0000000 --- a/ast/erfa/fama03.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "erfa.h" - -double eraFama03(double t) -/* -** - - - - - - - - - - -** e r a F a m a 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of Mars. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double mean longitude of Mars, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** comes from Souchay et al. (1999) after Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999, -** Astron.Astrophys.Supp.Ser. 135, 111 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of Mars (IERS Conventions 2003). */ - a = fmod(6.203480913 + 334.0612426700 * t, ERFA_D2PI); - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fame03.c b/ast/erfa/fame03.c deleted file mode 100644 index c28ab0b..0000000 --- a/ast/erfa/fame03.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "erfa.h" - -double eraFame03(double t) -/* -** - - - - - - - - - - -** e r a F a m e 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of Mercury. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double mean longitude of Mercury, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** comes from Souchay et al. (1999) after Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999, -** Astron.Astrophys.Supp.Ser. 135, 111 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of Mercury (IERS Conventions 2003). */ - a = fmod(4.402608842 + 2608.7903141574 * t, ERFA_D2PI); - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fane03.c b/ast/erfa/fane03.c deleted file mode 100644 index 682e7bf..0000000 --- a/ast/erfa/fane03.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "erfa.h" - -double eraFane03(double t) -/* -** - - - - - - - - - - -** e r a F a n e 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of Neptune. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double mean longitude of Neptune, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** is adapted from Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of Neptune (IERS Conventions 2003). */ - a = fmod(5.311886287 + 3.8133035638 * t, ERFA_D2PI); - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/faom03.c b/ast/erfa/faom03.c deleted file mode 100644 index ff6b3e9..0000000 --- a/ast/erfa/faom03.c +++ /dev/null @@ -1,113 +0,0 @@ -#include "erfa.h" - -double eraFaom03(double t) -/* -** - - - - - - - - - - -** e r a F a o m 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of the Moon's ascending node. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double Omega, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** is from Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of the Moon's ascending node */ -/* (IERS Conventions 2003). */ - a = fmod( 450160.398036 + - t * ( - 6962890.5431 + - t * ( 7.4722 + - t * ( 0.007702 + - t * ( - 0.00005939 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R; - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fapa03.c b/ast/erfa/fapa03.c deleted file mode 100644 index aae2af4..0000000 --- a/ast/erfa/fapa03.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "erfa.h" - -double eraFapa03(double t) -/* -** - - - - - - - - - - -** e r a F a p a 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** general accumulated precession in longitude. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double general precession in longitude, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003). It -** is taken from Kinoshita & Souchay (1990) and comes originally -** from Lieske et al. (1977). -** -** References: -** -** Kinoshita, H. and Souchay J. 1990, Celest.Mech. and Dyn.Astron. -** 48, 187 -** -** Lieske, J.H., Lederle, T., Fricke, W. & Morando, B. 1977, -** Astron.Astrophys. 58, 1-16 -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* General accumulated precession in longitude. */ - a = (0.024381750 + 0.00000538691 * t) * t; - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fasa03.c b/ast/erfa/fasa03.c deleted file mode 100644 index d5e8cbe..0000000 --- a/ast/erfa/fasa03.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "erfa.h" - -double eraFasa03(double t) -/* -** - - - - - - - - - - -** e r a F a s a 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of Saturn. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double mean longitude of Saturn, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** comes from Souchay et al. (1999) after Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999, -** Astron.Astrophys.Supp.Ser. 135, 111 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of Saturn (IERS Conventions 2003). */ - a = fmod(0.874016757 + 21.3299104960 * t, ERFA_D2PI); - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/faur03.c b/ast/erfa/faur03.c deleted file mode 100644 index cce0f83..0000000 --- a/ast/erfa/faur03.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "erfa.h" - -double eraFaur03(double t) -/* -** - - - - - - - - - - -** e r a F a u r 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of Uranus. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double mean longitude of Uranus, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** is adapted from Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of Uranus (IERS Conventions 2003). */ - a = fmod(5.481293872 + 7.4781598567 * t, ERFA_D2PI); - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fave03.c b/ast/erfa/fave03.c deleted file mode 100644 index b91678c..0000000 --- a/ast/erfa/fave03.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "erfa.h" - -double eraFave03(double t) -/* -** - - - - - - - - - - -** e r a F a v e 0 3 -** - - - - - - - - - - -** -** Fundamental argument, IERS Conventions (2003): -** mean longitude of Venus. -** -** Given: -** t double TDB, Julian centuries since J2000.0 (Note 1) -** -** Returned (function value): -** double mean longitude of Venus, radians (Note 2) -** -** Notes: -** -** 1) Though t is strictly TDB, it is usually more convenient to use -** TT, which makes no significant difference. -** -** 2) The expression used is as adopted in IERS Conventions (2003) and -** comes from Souchay et al. (1999) after Simon et al. (1994). -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999, -** Astron.Astrophys.Supp.Ser. 135, 111 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double a; - - -/* Mean longitude of Venus (IERS Conventions 2003). */ - a = fmod(3.176146697 + 1021.3285546211 * t, ERFA_D2PI); - - return a; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fk52h.c b/ast/erfa/fk52h.c deleted file mode 100644 index e169cbe..0000000 --- a/ast/erfa/fk52h.c +++ /dev/null @@ -1,152 +0,0 @@ -#include "erfa.h" - -void eraFk52h(double r5, double d5, - double dr5, double dd5, double px5, double rv5, - double *rh, double *dh, - double *drh, double *ddh, double *pxh, double *rvh) -/* -** - - - - - - - - - -** e r a F k 5 2 h -** - - - - - - - - - -** -** Transform FK5 (J2000.0) star data into the Hipparcos system. -** -** Given (all FK5, equinox J2000.0, epoch J2000.0): -** r5 double RA (radians) -** d5 double Dec (radians) -** dr5 double proper motion in RA (dRA/dt, rad/Jyear) -** dd5 double proper motion in Dec (dDec/dt, rad/Jyear) -** px5 double parallax (arcsec) -** rv5 double radial velocity (km/s, positive = receding) -** -** Returned (all Hipparcos, epoch J2000.0): -** rh double RA (radians) -** dh double Dec (radians) -** drh double proper motion in RA (dRA/dt, rad/Jyear) -** ddh double proper motion in Dec (dDec/dt, rad/Jyear) -** pxh double parallax (arcsec) -** rvh double radial velocity (km/s, positive = receding) -** -** Notes: -** -** 1) This function transforms FK5 star positions and proper motions -** into the system of the Hipparcos catalog. -** -** 2) The proper motions in RA are dRA/dt rather than -** cos(Dec)*dRA/dt, and are per year rather than per century. -** -** 3) The FK5 to Hipparcos transformation is modeled as a pure -** rotation and spin; zonal errors in the FK5 catalog are not -** taken into account. -** -** 4) See also eraH2fk5, eraFk5hz, eraHfk5z. -** -** Called: -** eraStarpv star catalog data to space motion pv-vector -** eraFk5hip FK5 to Hipparcos rotation and spin -** eraRxp product of r-matrix and p-vector -** eraPxp vector product of two p-vectors -** eraPpp p-vector plus p-vector -** eraPvstar space motion pv-vector to star catalog data -** -** Reference: -** -** F.Mignard & M.Froeschle, Astron. Astrophys. 354, 732-739 (2000). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int i; - double pv5[2][3], r5h[3][3], s5h[3], wxp[3], vv[3], pvh[2][3]; - - -/* FK5 barycentric position/velocity pv-vector (normalized). */ - eraStarpv(r5, d5, dr5, dd5, px5, rv5, pv5); - -/* FK5 to Hipparcos orientation matrix and spin vector. */ - eraFk5hip(r5h, s5h); - -/* Make spin units per day instead of per year. */ - for ( i = 0; i < 3; s5h[i++] /= 365.25 ); - -/* Orient the FK5 position into the Hipparcos system. */ - eraRxp(r5h, pv5[0], pvh[0]); - -/* Apply spin to the position giving an extra space motion component. */ - eraPxp(pv5[0], s5h, wxp); - -/* Add this component to the FK5 space motion. */ - eraPpp(wxp, pv5[1], vv); - -/* Orient the FK5 space motion into the Hipparcos system. */ - eraRxp(r5h, vv, pvh[1]); - -/* Hipparcos pv-vector to spherical. */ - eraPvstar(pvh, rh, dh, drh, ddh, pxh, rvh); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fk5hip.c b/ast/erfa/fk5hip.c deleted file mode 100644 index 5a05d4d..0000000 --- a/ast/erfa/fk5hip.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "erfa.h" - -void eraFk5hip(double r5h[3][3], double s5h[3]) -/* -** - - - - - - - - - - -** e r a F k 5 h i p -** - - - - - - - - - - -** -** FK5 to Hipparcos rotation and spin. -** -** Returned: -** r5h double[3][3] r-matrix: FK5 rotation wrt Hipparcos (Note 2) -** s5h double[3] r-vector: FK5 spin wrt Hipparcos (Note 3) -** -** Notes: -** -** 1) This function models the FK5 to Hipparcos transformation as a -** pure rotation and spin; zonal errors in the FK5 catalogue are -** not taken into account. -** -** 2) The r-matrix r5h operates in the sense: -** -** P_Hipparcos = r5h x P_FK5 -** -** where P_FK5 is a p-vector in the FK5 frame, and P_Hipparcos is -** the equivalent Hipparcos p-vector. -** -** 3) The r-vector s5h represents the time derivative of the FK5 to -** Hipparcos rotation. The units are radians per year (Julian, -** TDB). -** -** Called: -** eraRv2m r-vector to r-matrix -** -** Reference: -** -** F.Mignard & M.Froeschle, Astron. Astrophys. 354, 732-739 (2000). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double v[3]; - -/* FK5 wrt Hipparcos orientation and spin (radians, radians/year) */ - double epx, epy, epz; - double omx, omy, omz; - - - epx = -19.9e-3 * ERFA_DAS2R; - epy = -9.1e-3 * ERFA_DAS2R; - epz = 22.9e-3 * ERFA_DAS2R; - - omx = -0.30e-3 * ERFA_DAS2R; - omy = 0.60e-3 * ERFA_DAS2R; - omz = 0.70e-3 * ERFA_DAS2R; - -/* FK5 to Hipparcos orientation expressed as an r-vector. */ - v[0] = epx; - v[1] = epy; - v[2] = epz; - -/* Re-express as an r-matrix. */ - eraRv2m(v, r5h); - -/* Hipparcos wrt FK5 spin expressed as an r-vector. */ - s5h[0] = omx; - s5h[1] = omy; - s5h[2] = omz; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fk5hz.c b/ast/erfa/fk5hz.c deleted file mode 100644 index 4134f7c..0000000 --- a/ast/erfa/fk5hz.c +++ /dev/null @@ -1,169 +0,0 @@ -#include "erfa.h" - -void eraFk5hz(double r5, double d5, double date1, double date2, - double *rh, double *dh) -/* -** - - - - - - - - - -** e r a F k 5 h z -** - - - - - - - - - -** -** Transform an FK5 (J2000.0) star position into the system of the -** Hipparcos catalogue, assuming zero Hipparcos proper motion. -** -** Given: -** r5 double FK5 RA (radians), equinox J2000.0, at date -** d5 double FK5 Dec (radians), equinox J2000.0, at date -** date1,date2 double TDB date (Notes 1,2) -** -** Returned: -** rh double Hipparcos RA (radians) -** dh double Hipparcos Dec (radians) -** -** Notes: -** -** 1) This function converts a star position from the FK5 system to -** the Hipparcos system, in such a way that the Hipparcos proper -** motion is zero. Because such a star has, in general, a non-zero -** proper motion in the FK5 system, the function requires the date -** at which the position in the FK5 system was determined. -** -** 2) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 3) The FK5 to Hipparcos transformation is modeled as a pure -** rotation and spin; zonal errors in the FK5 catalogue are not -** taken into account. -** -** 4) The position returned by this function is in the Hipparcos -** reference system but at date date1+date2. -** -** 5) See also eraFk52h, eraH2fk5, eraHfk5z. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraFk5hip FK5 to Hipparcos rotation and spin -** eraSxp multiply p-vector by scalar -** eraRv2m r-vector to r-matrix -** eraTrxp product of transpose of r-matrix and p-vector -** eraPxp vector product of two p-vectors -** eraC2s p-vector to spherical -** eraAnp normalize angle into range 0 to 2pi -** -** Reference: -** -** F.Mignard & M.Froeschle, 2000, Astron.Astrophys. 354, 732-739. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, p5e[3], r5h[3][3], s5h[3], vst[3], rst[3][3], p5[3], - ph[3], w; - - -/* Interval from given date to fundamental epoch J2000.0 (JY). */ - t = - ((date1 - ERFA_DJ00) + date2) / ERFA_DJY; - -/* FK5 barycentric position vector. */ - eraS2c(r5, d5, p5e); - -/* FK5 to Hipparcos orientation matrix and spin vector. */ - eraFk5hip(r5h, s5h); - -/* Accumulated Hipparcos wrt FK5 spin over that interval. */ - eraSxp(t, s5h, vst); - -/* Express the accumulated spin as a rotation matrix. */ - eraRv2m(vst, rst); - -/* Derotate the vector's FK5 axes back to date. */ - eraTrxp(rst, p5e, p5); - -/* Rotate the vector into the Hipparcos system. */ - eraRxp(r5h, p5, ph); - -/* Hipparcos vector to spherical. */ - eraC2s(ph, &w, dh); - *rh = eraAnp(w); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fw2m.c b/ast/erfa/fw2m.c deleted file mode 100644 index d1b73d2..0000000 --- a/ast/erfa/fw2m.c +++ /dev/null @@ -1,143 +0,0 @@ -#include "erfa.h" - -void eraFw2m(double gamb, double phib, double psi, double eps, - double r[3][3]) -/* -** - - - - - - - - -** e r a F w 2 m -** - - - - - - - - -** -** Form rotation matrix given the Fukushima-Williams angles. -** -** Given: -** gamb double F-W angle gamma_bar (radians) -** phib double F-W angle phi_bar (radians) -** psi double F-W angle psi (radians) -** eps double F-W angle epsilon (radians) -** -** Returned: -** r double[3][3] rotation matrix -** -** Notes: -** -** 1) Naming the following points: -** -** e = J2000.0 ecliptic pole, -** p = GCRS pole, -** E = ecliptic pole of date, -** and P = CIP, -** -** the four Fukushima-Williams angles are as follows: -** -** gamb = gamma = epE -** phib = phi = pE -** psi = psi = pEP -** eps = epsilon = EP -** -** 2) The matrix representing the combined effects of frame bias, -** precession and nutation is: -** -** NxPxB = R_1(-eps).R_3(-psi).R_1(phib).R_3(gamb) -** -** 3) Three different matrices can be constructed, depending on the -** supplied angles: -** -** o To obtain the nutation x precession x frame bias matrix, -** generate the four precession angles, generate the nutation -** components and add them to the psi_bar and epsilon_A angles, -** and call the present function. -** -** o To obtain the precession x frame bias matrix, generate the -** four precession angles and call the present function. -** -** o To obtain the frame bias matrix, generate the four precession -** angles for date J2000.0 and call the present function. -** -** The nutation-only and precession-only matrices can if necessary -** be obtained by combining these three appropriately. -** -** Called: -** eraIr initialize r-matrix to identity -** eraRz rotate around Z-axis -** eraRx rotate around X-axis -** -** Reference: -** -** Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Construct the matrix. */ - eraIr(r); - eraRz(gamb, r); - eraRx(phib, r); - eraRz(-psi, r); - eraRx(-eps, r); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/fw2xy.c b/ast/erfa/fw2xy.c deleted file mode 100644 index b4e0693..0000000 --- a/ast/erfa/fw2xy.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "erfa.h" - -void eraFw2xy(double gamb, double phib, double psi, double eps, - double *x, double *y) -/* -** - - - - - - - - - -** e r a F w 2 x y -** - - - - - - - - - -** -** CIP X,Y given Fukushima-Williams bias-precession-nutation angles. -** -** Given: -** gamb double F-W angle gamma_bar (radians) -** phib double F-W angle phi_bar (radians) -** psi double F-W angle psi (radians) -** eps double F-W angle epsilon (radians) -** -** Returned: -** x,y double CIP unit vector X,Y -** -** Notes: -** -** 1) Naming the following points: -** -** e = J2000.0 ecliptic pole, -** p = GCRS pole -** E = ecliptic pole of date, -** and P = CIP, -** -** the four Fukushima-Williams angles are as follows: -** -** gamb = gamma = epE -** phib = phi = pE -** psi = psi = pEP -** eps = epsilon = EP -** -** 2) The matrix representing the combined effects of frame bias, -** precession and nutation is: -** -** NxPxB = R_1(-epsA).R_3(-psi).R_1(phib).R_3(gamb) -** -** The returned values x,y are elements [2][0] and [2][1] of the -** matrix. Near J2000.0, they are essentially angles in radians. -** -** Called: -** eraFw2m F-W angles to r-matrix -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** -** Reference: -** -** Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double r[3][3]; - - -/* Form NxPxB matrix. */ - eraFw2m(gamb, phib, psi, eps, r); - -/* Extract CIP X,Y. */ - eraBpn2xy(r, x, y); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/g2icrs.c b/ast/erfa/g2icrs.c deleted file mode 100644 index 4612726..0000000 --- a/ast/erfa/g2icrs.c +++ /dev/null @@ -1,170 +0,0 @@ -#include "erfa.h" - -void eraG2icrs ( double dl, double db, double *dr, double *dd ) -/* -** - - - - - - - - - - -** e r a G 2 i c r s -** - - - - - - - - - - -** -** Transformation from Galactic Coordinates to ICRS. -** -** Given: -** dl double galactic longitude (radians) -** db double galactic latitude (radians) -** -** Returned: -** dr double ICRS right ascension (radians) -** dd double ICRS declination (radians) -** -** Notes: -** -** 1) The IAU 1958 system of Galactic coordinates was defined with -** respect to the now obsolete reference system FK4 B1950.0. When -** interpreting the system in a modern context, several factors have -** to be taken into account: -** -** . The inclusion in FK4 positions of the E-terms of aberration. -** -** . The distortion of the FK4 proper motion system by differential -** Galactic rotation. -** -** . The use of the B1950.0 equinox rather than the now-standard -** J2000.0. -** -** . The frame bias between ICRS and the J2000.0 mean place system. -** -** The Hipparcos Catalogue (Perryman & ESA 1997) provides a rotation -** matrix that transforms directly between ICRS and Galactic -** coordinates with the above factors taken into account. The -** matrix is derived from three angles, namely the ICRS coordinates -** of the Galactic pole and the longitude of the ascending node of -** the galactic equator on the ICRS equator. They are given in -** degrees to five decimal places and for canonical purposes are -** regarded as exact. In the Hipparcos Catalogue the matrix -** elements are given to 10 decimal places (about 20 microarcsec). -** In the present ERFA function the matrix elements have been -** recomputed from the canonical three angles and are given to 30 -** decimal places. -** -** 2) The inverse transformation is performed by the function eraIcrs2g. -** -** Called: -** eraAnp normalize angle into range 0 to 2pi -** eraAnpm normalize angle into range +/- pi -** eraS2c spherical coordinates to unit vector -** eraTrxp product of transpose of r-matrix and p-vector -** eraC2s p-vector to spherical -** -** Reference: -** Perryman M.A.C. & ESA, 1997, ESA SP-1200, The Hipparcos and Tycho -** catalogues. Astrometric and photometric star catalogues -** derived from the ESA Hipparcos Space Astrometry Mission. ESA -** Publications Division, Noordwijk, Netherlands. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double v1[3], v2[3]; - -/* -** L2,B2 system of galactic coordinates in the form presented in the -** Hipparcos Catalogue. In degrees: -** -** P = 192.85948 right ascension of the Galactic north pole in ICRS -** Q = 27.12825 declination of the Galactic north pole in ICRS -** R = 32.93192 longitude of the ascending node of the Galactic -** plane on the ICRS equator -** -** ICRS to galactic rotation matrix, obtained by computing -** R_3(-R) R_1(pi/2-Q) R_3(pi/2+P) to the full precision shown: -*/ - double r[3][3] = { { -0.054875560416215368492398900454, - -0.873437090234885048760383168409, - -0.483835015548713226831774175116 }, - { +0.494109427875583673525222371358, - -0.444829629960011178146614061616, - +0.746982244497218890527388004556 }, - { -0.867666149019004701181616534570, - -0.198076373431201528180486091412, - +0.455983776175066922272100478348 } }; - - -/* Spherical to Cartesian. */ - eraS2c(dl, db, v1); - -/* Galactic to ICRS. */ - eraTrxp(r, v1, v2); - -/* Cartesian to spherical. */ - eraC2s(v2, dr, dd); - -/* Express in conventional ranges. */ - *dr = eraAnp(*dr); - *dd = eraAnpm(*dd); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gc2gd.c b/ast/erfa/gc2gd.c deleted file mode 100644 index 385e7d5..0000000 --- a/ast/erfa/gc2gd.c +++ /dev/null @@ -1,143 +0,0 @@ -#include "erfa.h" - -int eraGc2gd ( int n, double xyz[3], - double *elong, double *phi, double *height ) -/* -** - - - - - - - - - -** e r a G c 2 g d -** - - - - - - - - - -** -** Transform geocentric coordinates to geodetic using the specified -** reference ellipsoid. -** -** Given: -** n int ellipsoid identifier (Note 1) -** xyz double[3] geocentric vector (Note 2) -** -** Returned: -** elong double longitude (radians, east +ve, Note 3) -** phi double latitude (geodetic, radians, Note 3) -** height double height above ellipsoid (geodetic, Notes 2,3) -** -** Returned (function value): -** int status: 0 = OK -** -1 = illegal identifier (Note 3) -** -2 = internal error (Note 3) -** -** Notes: -** -** 1) The identifier n is a number that specifies the choice of -** reference ellipsoid. The following are supported: -** -** n ellipsoid -** -** 1 ERFA_WGS84 -** 2 ERFA_GRS80 -** 3 ERFA_WGS72 -** -** The n value has no significance outside the ERFA software. For -** convenience, symbols ERFA_WGS84 etc. are defined in erfam.h. -** -** 2) The geocentric vector (xyz, given) and height (height, returned) -** are in meters. -** -** 3) An error status -1 means that the identifier n is illegal. An -** error status -2 is theoretically impossible. In all error cases, -** all three results are set to -1e9. -** -** 4) The inverse transformation is performed in the function eraGd2gc. -** -** Called: -** eraEform Earth reference ellipsoids -** eraGc2gde geocentric to geodetic transformation, general -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j; - double a, f; - - -/* Obtain reference ellipsoid parameters. */ - j = eraEform ( n, &a, &f ); - -/* If OK, transform x,y,z to longitude, geodetic latitude, height. */ - if ( j == 0 ) { - j = eraGc2gde ( a, f, xyz, elong, phi, height ); - if ( j < 0 ) j = -2; - } - -/* Deal with any errors. */ - if ( j < 0 ) { - *elong = -1e9; - *phi = -1e9; - *height = -1e9; - } - -/* Return the status. */ - return j; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gc2gde.c b/ast/erfa/gc2gde.c deleted file mode 100644 index 43ed61d..0000000 --- a/ast/erfa/gc2gde.c +++ /dev/null @@ -1,208 +0,0 @@ -#include "erfa.h" - -int eraGc2gde ( double a, double f, double xyz[3], - double *elong, double *phi, double *height ) -/* -** - - - - - - - - - - -** e r a G c 2 g d e -** - - - - - - - - - - -** -** Transform geocentric coordinates to geodetic for a reference -** ellipsoid of specified form. -** -** Given: -** a double equatorial radius (Notes 2,4) -** f double flattening (Note 3) -** xyz double[3] geocentric vector (Note 4) -** -** Returned: -** elong double longitude (radians, east +ve) -** phi double latitude (geodetic, radians) -** height double height above ellipsoid (geodetic, Note 4) -** -** Returned (function value): -** int status: 0 = OK -** -1 = illegal f -** -2 = illegal a -** -** Notes: -** -** 1) This function is based on the GCONV2H Fortran subroutine by -** Toshio Fukushima (see reference). -** -** 2) The equatorial radius, a, can be in any units, but meters is -** the conventional choice. -** -** 3) The flattening, f, is (for the Earth) a value around 0.00335, -** i.e. around 1/298. -** -** 4) The equatorial radius, a, and the geocentric vector, xyz, -** must be given in the same units, and determine the units of -** the returned height, height. -** -** 5) If an error occurs (status < 0), elong, phi and height are -** unchanged. -** -** 6) The inverse transformation is performed in the function -** eraGd2gce. -** -** 7) The transformation for a standard ellipsoid (such as ERFA_WGS84) can -** more conveniently be performed by calling eraGc2gd, which uses a -** numerical code to identify the required A and F values. -** -** Reference: -** -** Fukushima, T., "Transformation from Cartesian to geodetic -** coordinates accelerated by Halley's method", J.Geodesy (2006) -** 79: 689-693 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double aeps2, e2, e4t, ec2, ec, b, x, y, z, p2, absz, p, s0, pn, zc, - c0, c02, c03, s02, s03, a02, a0, a03, d0, f0, b0, s1, - cc, s12, cc2; - - -/* ------------- */ -/* Preliminaries */ -/* ------------- */ - -/* Validate ellipsoid parameters. */ - if ( f < 0.0 || f >= 1.0 ) return -1; - if ( a <= 0.0 ) return -2; - -/* Functions of ellipsoid parameters (with further validation of f). */ - aeps2 = a*a * 1e-32; - e2 = (2.0 - f) * f; - e4t = e2*e2 * 1.5; - ec2 = 1.0 - e2; - if ( ec2 <= 0.0 ) return -1; - ec = sqrt(ec2); - b = a * ec; - -/* Cartesian components. */ - x = xyz[0]; - y = xyz[1]; - z = xyz[2]; - -/* Distance from polar axis squared. */ - p2 = x*x + y*y; - -/* Longitude. */ - *elong = p2 > 0.0 ? atan2(y, x) : 0.0; - -/* Unsigned z-coordinate. */ - absz = fabs(z); - -/* Proceed unless polar case. */ - if ( p2 > aeps2 ) { - - /* Distance from polar axis. */ - p = sqrt(p2); - - /* Normalization. */ - s0 = absz / a; - pn = p / a; - zc = ec * s0; - - /* Prepare Newton correction factors. */ - c0 = ec * pn; - c02 = c0 * c0; - c03 = c02 * c0; - s02 = s0 * s0; - s03 = s02 * s0; - a02 = c02 + s02; - a0 = sqrt(a02); - a03 = a02 * a0; - d0 = zc*a03 + e2*s03; - f0 = pn*a03 - e2*c03; - - /* Prepare Halley correction factor. */ - b0 = e4t * s02 * c02 * pn * (a0 - ec); - s1 = d0*f0 - b0*s0; - cc = ec * (f0*f0 - b0*c0); - - /* Evaluate latitude and height. */ - *phi = atan(s1/cc); - s12 = s1 * s1; - cc2 = cc * cc; - *height = (p*cc + absz*s1 - a * sqrt(ec2*s12 + cc2)) / - sqrt(s12 + cc2); - } else { - - /* Exception: pole. */ - *phi = ERFA_DPI / 2.0; - *height = absz - b; - } - -/* Restore sign of latitude. */ - if ( z < 0 ) *phi = -*phi; - -/* OK status. */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gd2gc.c b/ast/erfa/gd2gc.c deleted file mode 100644 index 383c928..0000000 --- a/ast/erfa/gd2gc.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "erfa.h" - -int eraGd2gc ( int n, double elong, double phi, double height, - double xyz[3] ) -/* -** - - - - - - - - - -** e r a G d 2 g c -** - - - - - - - - - -** -** Transform geodetic coordinates to geocentric using the specified -** reference ellipsoid. -** -** Given: -** n int ellipsoid identifier (Note 1) -** elong double longitude (radians, east +ve) -** phi double latitude (geodetic, radians, Note 3) -** height double height above ellipsoid (geodetic, Notes 2,3) -** -** Returned: -** xyz double[3] geocentric vector (Note 2) -** -** Returned (function value): -** int status: 0 = OK -** -1 = illegal identifier (Note 3) -** -2 = illegal case (Note 3) -** -** Notes: -** -** 1) The identifier n is a number that specifies the choice of -** reference ellipsoid. The following are supported: -** -** n ellipsoid -** -** 1 ERFA_WGS84 -** 2 ERFA_GRS80 -** 3 ERFA_WGS72 -** -** The n value has no significance outside the ERFA software. For -** convenience, symbols ERFA_WGS84 etc. are defined in erfam.h. -** -** 2) The height (height, given) and the geocentric vector (xyz, -** returned) are in meters. -** -** 3) No validation is performed on the arguments elong, phi and -** height. An error status -1 means that the identifier n is -** illegal. An error status -2 protects against cases that would -** lead to arithmetic exceptions. In all error cases, xyz is set -** to zeros. -** -** 4) The inverse transformation is performed in the function eraGc2gd. -** -** Called: -** eraEform Earth reference ellipsoids -** eraGd2gce geodetic to geocentric transformation, general -** eraZp zero p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j; - double a, f; - - -/* Obtain reference ellipsoid parameters. */ - j = eraEform ( n, &a, &f ); - -/* If OK, transform longitude, geodetic latitude, height to x,y,z. */ - if ( j == 0 ) { - j = eraGd2gce ( a, f, elong, phi, height, xyz ); - if ( j != 0 ) j = -2; - } - -/* Deal with any errors. */ - if ( j != 0 ) eraZp ( xyz ); - -/* Return the status. */ - return j; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gd2gce.c b/ast/erfa/gd2gce.c deleted file mode 100644 index 52b9f0e..0000000 --- a/ast/erfa/gd2gce.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "erfa.h" - -int eraGd2gce ( double a, double f, double elong, double phi, - double height, double xyz[3] ) -/* -** - - - - - - - - - - -** e r a G d 2 g c e -** - - - - - - - - - - -** -** Transform geodetic coordinates to geocentric for a reference -** ellipsoid of specified form. -** -** Given: -** a double equatorial radius (Notes 1,4) -** f double flattening (Notes 2,4) -** elong double longitude (radians, east +ve) -** phi double latitude (geodetic, radians, Note 4) -** height double height above ellipsoid (geodetic, Notes 3,4) -** -** Returned: -** xyz double[3] geocentric vector (Note 3) -** -** Returned (function value): -** int status: 0 = OK -** -1 = illegal case (Note 4) -** Notes: -** -** 1) The equatorial radius, a, can be in any units, but meters is -** the conventional choice. -** -** 2) The flattening, f, is (for the Earth) a value around 0.00335, -** i.e. around 1/298. -** -** 3) The equatorial radius, a, and the height, height, must be -** given in the same units, and determine the units of the -** returned geocentric vector, xyz. -** -** 4) No validation is performed on individual arguments. The error -** status -1 protects against (unrealistic) cases that would lead -** to arithmetic exceptions. If an error occurs, xyz is unchanged. -** -** 5) The inverse transformation is performed in the function -** eraGc2gde. -** -** 6) The transformation for a standard ellipsoid (such as ERFA_WGS84) can -** more conveniently be performed by calling eraGd2gc, which uses a -** numerical code to identify the required a and f values. -** -** References: -** -** Green, R.M., Spherical Astronomy, Cambridge University Press, -** (1985) Section 4.5, p96. -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 4.22, p202. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double sp, cp, w, d, ac, as, r; - - -/* Functions of geodetic latitude. */ - sp = sin(phi); - cp = cos(phi); - w = 1.0 - f; - w = w * w; - d = cp*cp + w*sp*sp; - if ( d <= 0.0 ) return -1; - ac = a / sqrt(d); - as = w * ac; - -/* Geocentric vector. */ - r = (ac + height) * cp; - xyz[0] = r * cos(elong); - xyz[1] = r * sin(elong); - xyz[2] = (as + height) * sp; - -/* Success. */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gmst00.c b/ast/erfa/gmst00.c deleted file mode 100644 index 6b598bb..0000000 --- a/ast/erfa/gmst00.c +++ /dev/null @@ -1,154 +0,0 @@ -#include "erfa.h" - -double eraGmst00(double uta, double utb, double tta, double ttb) -/* -** - - - - - - - - - - -** e r a G m s t 0 0 -** - - - - - - - - - - -** -** Greenwich mean sidereal time (model consistent with IAU 2000 -** resolutions). -** -** Given: -** uta,utb double UT1 as a 2-part Julian Date (Notes 1,2) -** tta,ttb double TT as a 2-part Julian Date (Notes 1,2) -** -** Returned (function value): -** double Greenwich mean sidereal time (radians) -** -** Notes: -** -** 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both -** Julian Dates, apportioned in any convenient way between the -** argument pairs. For example, JD=2450123.7 could be expressed in -** any of these ways, among others: -** -** Part A Part B -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable (in the case of UT; the TT is not at all critical -** in this respect). The J2000 and MJD methods are good compromises -** between resolution and convenience. For UT, the date & time -** method is best matched to the algorithm that is used by the Earth -** Rotation Angle function, called internally: maximum precision is -** delivered when the uta argument is for 0hrs UT1 on the day in -** question and the utb argument lies in the range 0 to 1, or vice -** versa. -** -** 2) Both UT1 and TT are required, UT1 to predict the Earth rotation -** and TT to predict the effects of precession. If UT1 is used for -** both purposes, errors of order 100 microarcseconds result. -** -** 3) This GMST is compatible with the IAU 2000 resolutions and must be -** used only in conjunction with other IAU 2000 compatible -** components such as precession-nutation and equation of the -** equinoxes. -** -** 4) The result is returned in the range 0 to 2pi. -** -** 5) The algorithm is from Capitaine et al. (2003) and IERS -** Conventions 2003. -** -** Called: -** eraEra00 Earth rotation angle, IAU 2000 -** eraAnp normalize angle into range 0 to 2pi -** -** References: -** -** Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to -** implement the IAU 2000 definition of UT1", Astronomy & -** Astrophysics, 406, 1135-1149 (2003) -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, gmst; - - -/* TT Julian centuries since J2000.0. */ - t = ((tta - ERFA_DJ00) + ttb) / ERFA_DJC; - -/* Greenwich Mean Sidereal Time, IAU 2000. */ - gmst = eraAnp(eraEra00(uta, utb) + - ( 0.014506 + - ( 4612.15739966 + - ( 1.39667721 + - ( -0.00009344 + - ( 0.00001882 ) - * t) * t) * t) * t) * ERFA_DAS2R); - - return gmst; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gmst06.c b/ast/erfa/gmst06.c deleted file mode 100644 index 2fcb1a5..0000000 --- a/ast/erfa/gmst06.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "erfa.h" - -double eraGmst06(double uta, double utb, double tta, double ttb) -/* -** - - - - - - - - - - -** e r a G m s t 0 6 -** - - - - - - - - - - -** -** Greenwich mean sidereal time (consistent with IAU 2006 precession). -** -** Given: -** uta,utb double UT1 as a 2-part Julian Date (Notes 1,2) -** tta,ttb double TT as a 2-part Julian Date (Notes 1,2) -** -** Returned (function value): -** double Greenwich mean sidereal time (radians) -** -** Notes: -** -** 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both -** Julian Dates, apportioned in any convenient way between the -** argument pairs. For example, JD=2450123.7 could be expressed in -** any of these ways, among others: -** -** Part A Part B -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable (in the case of UT; the TT is not at all critical -** in this respect). The J2000 and MJD methods are good compromises -** between resolution and convenience. For UT, the date & time -** method is best matched to the algorithm that is used by the Earth -** rotation angle function, called internally: maximum precision is -** delivered when the uta argument is for 0hrs UT1 on the day in -** question and the utb argument lies in the range 0 to 1, or vice -** versa. -** -** 2) Both UT1 and TT are required, UT1 to predict the Earth rotation -** and TT to predict the effects of precession. If UT1 is used for -** both purposes, errors of order 100 microarcseconds result. -** -** 3) This GMST is compatible with the IAU 2006 precession and must not -** be used with other precession models. -** -** 4) The result is returned in the range 0 to 2pi. -** -** Called: -** eraEra00 Earth rotation angle, IAU 2000 -** eraAnp normalize angle into range 0 to 2pi -** -** Reference: -** -** Capitaine, N., Wallace, P.T. & Chapront, J., 2005, -** Astron.Astrophys. 432, 355 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, gmst; - - -/* TT Julian centuries since J2000.0. */ - t = ((tta - ERFA_DJ00) + ttb) / ERFA_DJC; - -/* Greenwich mean sidereal time, IAU 2006. */ - gmst = eraAnp(eraEra00(uta, utb) + - ( 0.014506 + - ( 4612.156534 + - ( 1.3915817 + - ( -0.00000044 + - ( -0.000029956 + - ( -0.0000000368 ) - * t) * t) * t) * t) * t) * ERFA_DAS2R); - - return gmst; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gmst82.c b/ast/erfa/gmst82.c deleted file mode 100644 index 9484b66..0000000 --- a/ast/erfa/gmst82.c +++ /dev/null @@ -1,160 +0,0 @@ -#include "erfa.h" - -double eraGmst82(double dj1, double dj2) -/* -** - - - - - - - - - - -** e r a G m s t 8 2 -** - - - - - - - - - - -** -** Universal Time to Greenwich mean sidereal time (IAU 1982 model). -** -** Given: -** dj1,dj2 double UT1 Julian Date (see note) -** -** Returned (function value): -** double Greenwich mean sidereal time (radians) -** -** Notes: -** -** 1) The UT1 date dj1+dj2 is a Julian Date, apportioned in any -** convenient way between the arguments dj1 and dj2. For example, -** JD(UT1)=2450123.7 could be expressed in any of these ways, -** among others: -** -** dj1 dj2 -** -** 2450123.7 0 (JD method) -** 2451545 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. The date & time method is -** best matched to the algorithm used: maximum accuracy (or, at -** least, minimum noise) is delivered when the dj1 argument is for -** 0hrs UT1 on the day in question and the dj2 argument lies in the -** range 0 to 1, or vice versa. -** -** 2) The algorithm is based on the IAU 1982 expression. This is -** always described as giving the GMST at 0 hours UT1. In fact, it -** gives the difference between the GMST and the UT, the steady -** 4-minutes-per-day drawing-ahead of ST with respect to UT. When -** whole days are ignored, the expression happens to equal the GMST -** at 0 hours UT1 each day. -** -** 3) In this function, the entire UT1 (the sum of the two arguments -** dj1 and dj2) is used directly as the argument for the standard -** formula, the constant term of which is adjusted by 12 hours to -** take account of the noon phasing of Julian Date. The UT1 is then -** added, but omitting whole days to conserve accuracy. -** -** Called: -** eraAnp normalize angle into range 0 to 2pi -** -** References: -** -** Transactions of the International Astronomical Union, -** XVIII B, 67 (1983). -** -** Aoki et al., Astron. Astrophys. 105, 359-361 (1982). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Coefficients of IAU 1982 GMST-UT1 model */ - double A = 24110.54841 - ERFA_DAYSEC / 2.0; - double B = 8640184.812866; - double C = 0.093104; - double D = -6.2e-6; - -/* Note: the first constant, A, has to be adjusted by 12 hours */ -/* because the UT1 is supplied as a Julian date, which begins */ -/* at noon. */ - - double d1, d2, t, f, gmst; - - -/* Julian centuries since fundamental epoch. */ - if (dj1 < dj2) { - d1 = dj1; - d2 = dj2; - } else { - d1 = dj2; - d2 = dj1; - } - t = (d1 + (d2 - ERFA_DJ00)) / ERFA_DJC; - -/* Fractional part of JD(UT1), in seconds. */ - f = ERFA_DAYSEC * (fmod(d1, 1.0) + fmod(d2, 1.0)); - -/* GMST at this UT1. */ - gmst = eraAnp(ERFA_DS2R * ((A + (B + (C + D * t) * t) * t) + f)); - - return gmst; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gst00a.c b/ast/erfa/gst00a.c deleted file mode 100644 index e185576..0000000 --- a/ast/erfa/gst00a.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "erfa.h" - -double eraGst00a(double uta, double utb, double tta, double ttb) -/* -** - - - - - - - - - - -** e r a G s t 0 0 a -** - - - - - - - - - - -** -** Greenwich apparent sidereal time (consistent with IAU 2000 -** resolutions). -** -** Given: -** uta,utb double UT1 as a 2-part Julian Date (Notes 1,2) -** tta,ttb double TT as a 2-part Julian Date (Notes 1,2) -** -** Returned (function value): -** double Greenwich apparent sidereal time (radians) -** -** Notes: -** -** 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both -** Julian Dates, apportioned in any convenient way between the -** argument pairs. For example, JD=2450123.7 could be expressed in -** any of these ways, among others: -** -** Part A Part B -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable (in the case of UT; the TT is not at all critical -** in this respect). The J2000 and MJD methods are good compromises -** between resolution and convenience. For UT, the date & time -** method is best matched to the algorithm that is used by the Earth -** Rotation Angle function, called internally: maximum precision is -** delivered when the uta argument is for 0hrs UT1 on the day in -** question and the utb argument lies in the range 0 to 1, or vice -** versa. -** -** 2) Both UT1 and TT are required, UT1 to predict the Earth rotation -** and TT to predict the effects of precession-nutation. If UT1 is -** used for both purposes, errors of order 100 microarcseconds -** result. -** -** 3) This GAST is compatible with the IAU 2000 resolutions and must be -** used only in conjunction with other IAU 2000 compatible -** components such as precession-nutation. -** -** 4) The result is returned in the range 0 to 2pi. -** -** 5) The algorithm is from Capitaine et al. (2003) and IERS -** Conventions 2003. -** -** Called: -** eraGmst00 Greenwich mean sidereal time, IAU 2000 -** eraEe00a equation of the equinoxes, IAU 2000A -** eraAnp normalize angle into range 0 to 2pi -** -** References: -** -** Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to -** implement the IAU 2000 definition of UT1", Astronomy & -** Astrophysics, 406, 1135-1149 (2003) -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double gmst00, ee00a, gst; - - - gmst00 = eraGmst00(uta, utb, tta, ttb); - ee00a = eraEe00a(tta, ttb); - gst = eraAnp(gmst00 + ee00a); - - return gst; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gst00b.c b/ast/erfa/gst00b.c deleted file mode 100644 index cfb5293..0000000 --- a/ast/erfa/gst00b.c +++ /dev/null @@ -1,155 +0,0 @@ -#include "erfa.h" - -double eraGst00b(double uta, double utb) -/* -** - - - - - - - - - - -** e r a G s t 0 0 b -** - - - - - - - - - - -** -** Greenwich apparent sidereal time (consistent with IAU 2000 -** resolutions but using the truncated nutation model IAU 2000B). -** -** Given: -** uta,utb double UT1 as a 2-part Julian Date (Notes 1,2) -** -** Returned (function value): -** double Greenwich apparent sidereal time (radians) -** -** Notes: -** -** 1) The UT1 date uta+utb is a Julian Date, apportioned in any -** convenient way between the argument pair. For example, -** JD=2450123.7 could be expressed in any of these ways, among -** others: -** -** uta utb -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. For UT, the date & time -** method is best matched to the algorithm that is used by the Earth -** Rotation Angle function, called internally: maximum precision is -** delivered when the uta argument is for 0hrs UT1 on the day in -** question and the utb argument lies in the range 0 to 1, or vice -** versa. -** -** 2) The result is compatible with the IAU 2000 resolutions, except -** that accuracy has been compromised for the sake of speed and -** convenience in two respects: -** -** . UT is used instead of TDB (or TT) to compute the precession -** component of GMST and the equation of the equinoxes. This -** results in errors of order 0.1 mas at present. -** -** . The IAU 2000B abridged nutation model (McCarthy & Luzum, 2001) -** is used, introducing errors of up to 1 mas. -** -** 3) This GAST is compatible with the IAU 2000 resolutions and must be -** used only in conjunction with other IAU 2000 compatible -** components such as precession-nutation. -** -** 4) The result is returned in the range 0 to 2pi. -** -** 5) The algorithm is from Capitaine et al. (2003) and IERS -** Conventions 2003. -** -** Called: -** eraGmst00 Greenwich mean sidereal time, IAU 2000 -** eraEe00b equation of the equinoxes, IAU 2000B -** eraAnp normalize angle into range 0 to 2pi -** -** References: -** -** Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to -** implement the IAU 2000 definition of UT1", Astronomy & -** Astrophysics, 406, 1135-1149 (2003) -** -** McCarthy, D.D. & Luzum, B.J., "An abridged model of the -** precession-nutation of the celestial pole", Celestial Mechanics & -** Dynamical Astronomy, 85, 37-49 (2003) -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double gmst00, ee00b, gst; - - - gmst00 = eraGmst00(uta, utb, uta, utb); - ee00b = eraEe00b(uta, utb); - gst = eraAnp(gmst00 + ee00b); - - return gst; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gst06.c b/ast/erfa/gst06.c deleted file mode 100644 index c4c85df..0000000 --- a/ast/erfa/gst06.c +++ /dev/null @@ -1,149 +0,0 @@ -#include "erfa.h" - -double eraGst06(double uta, double utb, double tta, double ttb, - double rnpb[3][3]) -/* -** - - - - - - - - - -** e r a G s t 0 6 -** - - - - - - - - - -** -** Greenwich apparent sidereal time, IAU 2006, given the NPB matrix. -** -** Given: -** uta,utb double UT1 as a 2-part Julian Date (Notes 1,2) -** tta,ttb double TT as a 2-part Julian Date (Notes 1,2) -** rnpb double[3][3] nutation x precession x bias matrix -** -** Returned (function value): -** double Greenwich apparent sidereal time (radians) -** -** Notes: -** -** 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both -** Julian Dates, apportioned in any convenient way between the -** argument pairs. For example, JD=2450123.7 could be expressed in -** any of these ways, among others: -** -** Part A Part B -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable (in the case of UT; the TT is not at all critical -** in this respect). The J2000 and MJD methods are good compromises -** between resolution and convenience. For UT, the date & time -** method is best matched to the algorithm that is used by the Earth -** rotation angle function, called internally: maximum precision is -** delivered when the uta argument is for 0hrs UT1 on the day in -** question and the utb argument lies in the range 0 to 1, or vice -** versa. -** -** 2) Both UT1 and TT are required, UT1 to predict the Earth rotation -** and TT to predict the effects of precession-nutation. If UT1 is -** used for both purposes, errors of order 100 microarcseconds -** result. -** -** 3) Although the function uses the IAU 2006 series for s+XY/2, it is -** otherwise independent of the precession-nutation model and can in -** practice be used with any equinox-based NPB matrix. -** -** 4) The result is returned in the range 0 to 2pi. -** -** Called: -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraS06 the CIO locator s, given X,Y, IAU 2006 -** eraAnp normalize angle into range 0 to 2pi -** eraEra00 Earth rotation angle, IAU 2000 -** eraEors equation of the origins, given NPB matrix and s -** -** Reference: -** -** Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double x, y, s, era, eors, gst; - - -/* Extract CIP coordinates. */ - eraBpn2xy(rnpb, &x, &y); - -/* The CIO locator, s. */ - s = eraS06(tta, ttb, x, y); - -/* Greenwich apparent sidereal time. */ - era = eraEra00(uta, utb); - eors = eraEors(rnpb, s); - gst = eraAnp(era - eors); - - return gst; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gst06a.c b/ast/erfa/gst06a.c deleted file mode 100644 index e80fd83..0000000 --- a/ast/erfa/gst06a.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "erfa.h" - -double eraGst06a(double uta, double utb, double tta, double ttb) -/* -** - - - - - - - - - - -** e r a G s t 0 6 a -** - - - - - - - - - - -** -** Greenwich apparent sidereal time (consistent with IAU 2000 and 2006 -** resolutions). -** -** Given: -** uta,utb double UT1 as a 2-part Julian Date (Notes 1,2) -** tta,ttb double TT as a 2-part Julian Date (Notes 1,2) -** -** Returned (function value): -** double Greenwich apparent sidereal time (radians) -** -** Notes: -** -** 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both -** Julian Dates, apportioned in any convenient way between the -** argument pairs. For example, JD=2450123.7 could be expressed in -** any of these ways, among others: -** -** Part A Part B -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable (in the case of UT; the TT is not at all critical -** in this respect). The J2000 and MJD methods are good compromises -** between resolution and convenience. For UT, the date & time -** method is best matched to the algorithm that is used by the Earth -** rotation angle function, called internally: maximum precision is -** delivered when the uta argument is for 0hrs UT1 on the day in -** question and the utb argument lies in the range 0 to 1, or vice -** versa. -** -** 2) Both UT1 and TT are required, UT1 to predict the Earth rotation -** and TT to predict the effects of precession-nutation. If UT1 is -** used for both purposes, errors of order 100 microarcseconds -** result. -** -** 3) This GAST is compatible with the IAU 2000/2006 resolutions and -** must be used only in conjunction with IAU 2006 precession and -** IAU 2000A nutation. -** -** 4) The result is returned in the range 0 to 2pi. -** -** Called: -** eraPnm06a classical NPB matrix, IAU 2006/2000A -** eraGst06 Greenwich apparent ST, IAU 2006, given NPB matrix -** -** Reference: -** -** Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rnpb[3][3], gst; - - -/* Classical nutation x precession x bias matrix, IAU 2000A. */ - eraPnm06a(tta, ttb, rnpb); - -/* Greenwich apparent sidereal time. */ - gst = eraGst06(uta, utb, tta, ttb, rnpb); - - return gst; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/gst94.c b/ast/erfa/gst94.c deleted file mode 100644 index 112cf61..0000000 --- a/ast/erfa/gst94.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "erfa.h" - -double eraGst94(double uta, double utb) -/* -** - - - - - - - - - -** e r a G s t 9 4 -** - - - - - - - - - -** -** Greenwich apparent sidereal time (consistent with IAU 1982/94 -** resolutions). -** -** Given: -** uta,utb double UT1 as a 2-part Julian Date (Notes 1,2) -** -** Returned (function value): -** double Greenwich apparent sidereal time (radians) -** -** Notes: -** -** 1) The UT1 date uta+utb is a Julian Date, apportioned in any -** convenient way between the argument pair. For example, -** JD=2450123.7 could be expressed in any of these ways, among -** others: -** -** uta utb -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 and MJD methods are good compromises -** between resolution and convenience. For UT, the date & time -** method is best matched to the algorithm that is used by the Earth -** Rotation Angle function, called internally: maximum precision is -** delivered when the uta argument is for 0hrs UT1 on the day in -** question and the utb argument lies in the range 0 to 1, or vice -** versa. -** -** 2) The result is compatible with the IAU 1982 and 1994 resolutions, -** except that accuracy has been compromised for the sake of -** convenience in that UT is used instead of TDB (or TT) to compute -** the equation of the equinoxes. -** -** 3) This GAST must be used only in conjunction with contemporaneous -** IAU standards such as 1976 precession, 1980 obliquity and 1982 -** nutation. It is not compatible with the IAU 2000 resolutions. -** -** 4) The result is returned in the range 0 to 2pi. -** -** Called: -** eraGmst82 Greenwich mean sidereal time, IAU 1982 -** eraEqeq94 equation of the equinoxes, IAU 1994 -** eraAnp normalize angle into range 0 to 2pi -** -** References: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** IAU Resolution C7, Recommendation 3 (1994) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double gmst82, eqeq94, gst; - - - gmst82 = eraGmst82(uta, utb); - eqeq94 = eraEqeq94(uta, utb); - gst = eraAnp(gmst82 + eqeq94); - - return gst; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/h2fk5.c b/ast/erfa/h2fk5.c deleted file mode 100644 index ad7e9a6..0000000 --- a/ast/erfa/h2fk5.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "erfa.h" - -void eraH2fk5(double rh, double dh, - double drh, double ddh, double pxh, double rvh, - double *r5, double *d5, - double *dr5, double *dd5, double *px5, double *rv5) -/* -** - - - - - - - - - -** e r a H 2 f k 5 -** - - - - - - - - - -** -** Transform Hipparcos star data into the FK5 (J2000.0) system. -** -** Given (all Hipparcos, epoch J2000.0): -** rh double RA (radians) -** dh double Dec (radians) -** drh double proper motion in RA (dRA/dt, rad/Jyear) -** ddh double proper motion in Dec (dDec/dt, rad/Jyear) -** pxh double parallax (arcsec) -** rvh double radial velocity (km/s, positive = receding) -** -** Returned (all FK5, equinox J2000.0, epoch J2000.0): -** r5 double RA (radians) -** d5 double Dec (radians) -** dr5 double proper motion in RA (dRA/dt, rad/Jyear) -** dd5 double proper motion in Dec (dDec/dt, rad/Jyear) -** px5 double parallax (arcsec) -** rv5 double radial velocity (km/s, positive = receding) -** -** Notes: -** -** 1) This function transforms Hipparcos star positions and proper -** motions into FK5 J2000.0. -** -** 2) The proper motions in RA are dRA/dt rather than -** cos(Dec)*dRA/dt, and are per year rather than per century. -** -** 3) The FK5 to Hipparcos transformation is modeled as a pure -** rotation and spin; zonal errors in the FK5 catalog are not -** taken into account. -** -** 4) See also eraFk52h, eraFk5hz, eraHfk5z. -** -** Called: -** eraStarpv star catalog data to space motion pv-vector -** eraFk5hip FK5 to Hipparcos rotation and spin -** eraRv2m r-vector to r-matrix -** eraRxp product of r-matrix and p-vector -** eraTrxp product of transpose of r-matrix and p-vector -** eraPxp vector product of two p-vectors -** eraPmp p-vector minus p-vector -** eraPvstar space motion pv-vector to star catalog data -** -** Reference: -** -** F.Mignard & M.Froeschle, Astron. Astrophys. 354, 732-739 (2000). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int i; - double pvh[2][3], r5h[3][3], s5h[3], sh[3], wxp[3], vv[3], pv5[2][3]; - - -/* Hipparcos barycentric position/velocity pv-vector (normalized). */ - eraStarpv(rh, dh, drh, ddh, pxh, rvh, pvh); - -/* FK5 to Hipparcos orientation matrix and spin vector. */ - eraFk5hip(r5h, s5h); - -/* Make spin units per day instead of per year. */ - for ( i = 0; i < 3; s5h[i++] /= 365.25 ); - -/* Orient the spin into the Hipparcos system. */ - eraRxp(r5h, s5h, sh); - -/* De-orient the Hipparcos position into the FK5 system. */ - eraTrxp(r5h, pvh[0], pv5[0]); - -/* Apply spin to the position giving an extra space motion component. */ - eraPxp(pvh[0], sh, wxp); - -/* Subtract this component from the Hipparcos space motion. */ - eraPmp(pvh[1], wxp, vv); - -/* De-orient the Hipparcos space motion into the FK5 system. */ - eraTrxp(r5h, vv, pv5[1]); - -/* FK5 pv-vector to spherical. */ - eraPvstar(pv5, r5, d5, dr5, dd5, px5, rv5); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/hfk5z.c b/ast/erfa/hfk5z.c deleted file mode 100644 index 8824e96..0000000 --- a/ast/erfa/hfk5z.c +++ /dev/null @@ -1,184 +0,0 @@ -#include "erfa.h" - -void eraHfk5z(double rh, double dh, double date1, double date2, - double *r5, double *d5, double *dr5, double *dd5) -/* -** - - - - - - - - - -** e r a H f k 5 z -** - - - - - - - - - -** -** Transform a Hipparcos star position into FK5 J2000.0, assuming -** zero Hipparcos proper motion. -** -** Given: -** rh double Hipparcos RA (radians) -** dh double Hipparcos Dec (radians) -** date1,date2 double TDB date (Note 1) -** -** Returned (all FK5, equinox J2000.0, date date1+date2): -** r5 double RA (radians) -** d5 double Dec (radians) -** dr5 double FK5 RA proper motion (rad/year, Note 4) -** dd5 double Dec proper motion (rad/year, Note 4) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt. -** -** 3) The FK5 to Hipparcos transformation is modeled as a pure rotation -** and spin; zonal errors in the FK5 catalogue are not taken into -** account. -** -** 4) It was the intention that Hipparcos should be a close -** approximation to an inertial frame, so that distant objects have -** zero proper motion; such objects have (in general) non-zero -** proper motion in FK5, and this function returns those fictitious -** proper motions. -** -** 5) The position returned by this function is in the FK5 J2000.0 -** reference system but at date date1+date2. -** -** 6) See also eraFk52h, eraH2fk5, eraFk5zhz. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraFk5hip FK5 to Hipparcos rotation and spin -** eraRxp product of r-matrix and p-vector -** eraSxp multiply p-vector by scalar -** eraRxr product of two r-matrices -** eraTrxp product of transpose of r-matrix and p-vector -** eraPxp vector product of two p-vectors -** eraPv2s pv-vector to spherical -** eraAnp normalize angle into range 0 to 2pi -** -** Reference: -** -** F.Mignard & M.Froeschle, 2000, Astron.Astrophys. 354, 732-739. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, ph[3], r5h[3][3], s5h[3], sh[3], vst[3], - rst[3][3], r5ht[3][3], pv5e[2][3], vv[3], - w, r, v; - - -/* Time interval from fundamental epoch J2000.0 to given date (JY). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJY; - -/* Hipparcos barycentric position vector (normalized). */ - eraS2c(rh, dh, ph); - -/* FK5 to Hipparcos orientation matrix and spin vector. */ - eraFk5hip(r5h, s5h); - -/* Rotate the spin into the Hipparcos system. */ - eraRxp(r5h, s5h, sh); - -/* Accumulated Hipparcos wrt FK5 spin over that interval. */ - eraSxp(t, s5h, vst); - -/* Express the accumulated spin as a rotation matrix. */ - eraRv2m(vst, rst); - -/* Rotation matrix: accumulated spin, then FK5 to Hipparcos. */ - eraRxr(r5h, rst, r5ht); - -/* De-orient & de-spin the Hipparcos position into FK5 J2000.0. */ - eraTrxp(r5ht, ph, pv5e[0]); - -/* Apply spin to the position giving a space motion. */ - eraPxp(sh, ph, vv); - -/* De-orient & de-spin the Hipparcos space motion into FK5 J2000.0. */ - eraTrxp(r5ht, vv, pv5e[1]); - -/* FK5 position/velocity pv-vector to spherical. */ - eraPv2s(pv5e, &w, d5, &r, dr5, dd5, &v); - *r5 = eraAnp(w); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/icrs2g.c b/ast/erfa/icrs2g.c deleted file mode 100644 index cf59118..0000000 --- a/ast/erfa/icrs2g.c +++ /dev/null @@ -1,170 +0,0 @@ -#include "erfa.h" - -void eraIcrs2g ( double dr, double dd, double *dl, double *db ) -/* -** - - - - - - - - - - -** e r a I c r s 2 g -** - - - - - - - - - - -** -** Transformation from ICRS to Galactic Coordinates. -** -** Given: -** dr double ICRS right ascension (radians) -** dd double ICRS declination (radians) -** -** Returned: -** dl double galactic longitude (radians) -** db double galactic latitude (radians) -** -** Notes: -** -** 1) The IAU 1958 system of Galactic coordinates was defined with -** respect to the now obsolete reference system FK4 B1950.0. When -** interpreting the system in a modern context, several factors have -** to be taken into account: -** -** . The inclusion in FK4 positions of the E-terms of aberration. -** -** . The distortion of the FK4 proper motion system by differential -** Galactic rotation. -** -** . The use of the B1950.0 equinox rather than the now-standard -** J2000.0. -** -** . The frame bias between ICRS and the J2000.0 mean place system. -** -** The Hipparcos Catalogue (Perryman & ESA 1997) provides a rotation -** matrix that transforms directly between ICRS and Galactic -** coordinates with the above factors taken into account. The -** matrix is derived from three angles, namely the ICRS coordinates -** of the Galactic pole and the longitude of the ascending node of -** the galactic equator on the ICRS equator. They are given in -** degrees to five decimal places and for canonical purposes are -** regarded as exact. In the Hipparcos Catalogue the matrix -** elements are given to 10 decimal places (about 20 microarcsec). -** In the present ERFA function the matrix elements have been -** recomputed from the canonical three angles and are given to 30 -** decimal places. -** -** 2) The inverse transformation is performed by the function eraG2icrs. -** -** Called: -** eraAnp normalize angle into range 0 to 2pi -** eraAnpm normalize angle into range +/- pi -** eraS2c spherical coordinates to unit vector -** eraRxp product of r-matrix and p-vector -** eraC2s p-vector to spherical -** -** Reference: -** Perryman M.A.C. & ESA, 1997, ESA SP-1200, The Hipparcos and Tycho -** catalogues. Astrometric and photometric star catalogues -** derived from the ESA Hipparcos Space Astrometry Mission. ESA -** Publications Division, Noordwijk, Netherlands. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double v1[3], v2[3]; - -/* -** L2,B2 system of galactic coordinates in the form presented in the -** Hipparcos Catalogue. In degrees: -** -** P = 192.85948 right ascension of the Galactic north pole in ICRS -** Q = 27.12825 declination of the Galactic north pole in ICRS -** R = 32.93192 longitude of the ascending node of the Galactic -** plane on the ICRS equator -** -** ICRS to galactic rotation matrix, obtained by computing -** R_3(-R) R_1(pi/2-Q) R_3(pi/2+P) to the full precision shown: -*/ - double r[3][3] = { { -0.054875560416215368492398900454, - -0.873437090234885048760383168409, - -0.483835015548713226831774175116 }, - { +0.494109427875583673525222371358, - -0.444829629960011178146614061616, - +0.746982244497218890527388004556 }, - { -0.867666149019004701181616534570, - -0.198076373431201528180486091412, - +0.455983776175066922272100478348 } }; - - -/* Spherical to Cartesian. */ - eraS2c(dr, dd, v1); - -/* ICRS to Galactic. */ - eraRxp(r, v1, v2); - -/* Cartesian to spherical. */ - eraC2s(v2, dl, db); - -/* Express in conventional ranges. */ - *dl = eraAnp(*dl); - *db = eraAnpm(*db); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ir.c b/ast/erfa/ir.c deleted file mode 100644 index 8c7cd1e..0000000 --- a/ast/erfa/ir.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "erfa.h" - -void eraIr(double r[3][3]) -/* -** - - - - - - -** e r a I r -** - - - - - - -** -** Initialize an r-matrix to the identity matrix. -** -** Returned: -** r double[3][3] r-matrix -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - r[0][0] = 1.0; - r[0][1] = 0.0; - r[0][2] = 0.0; - r[1][0] = 0.0; - r[1][1] = 1.0; - r[1][2] = 0.0; - r[2][0] = 0.0; - r[2][1] = 0.0; - r[2][2] = 1.0; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/jd2cal.c b/ast/erfa/jd2cal.c deleted file mode 100644 index abe2b8f..0000000 --- a/ast/erfa/jd2cal.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "erfa.h" - -int eraJd2cal(double dj1, double dj2, - int *iy, int *im, int *id, double *fd) -/* -** - - - - - - - - - - -** e r a J d 2 c a l -** - - - - - - - - - - -** -** Julian Date to Gregorian year, month, day, and fraction of a day. -** -** Given: -** dj1,dj2 double Julian Date (Notes 1, 2) -** -** Returned (arguments): -** iy int year -** im int month -** id int day -** fd double fraction of day -** -** Returned (function value): -** int status: -** 0 = OK -** -1 = unacceptable date (Note 3) -** -** Notes: -** -** 1) The earliest valid date is -68569.5 (-4900 March 1). The -** largest value accepted is 1e9. -** -** 2) The Julian Date is apportioned in any convenient way between -** the arguments dj1 and dj2. For example, JD=2450123.7 could -** be expressed in any of these ways, among others: -** -** dj1 dj2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** 3) In early eras the conversion is from the "proleptic Gregorian -** calendar"; no account is taken of the date(s) of adoption of -** the Gregorian calendar, nor is the AD/BC numbering convention -** observed. -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 12.92 (p604). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Minimum and maximum allowed JD */ - const double DJMIN = -68569.5; - const double DJMAX = 1e9; - - long jd, l, n, i, k; - double dj, d1, d2, f1, f2, f, d; - - -/* Verify date is acceptable. */ - dj = dj1 + dj2; - if (dj < DJMIN || dj > DJMAX) return -1; - -/* Copy the date, big then small, and re-align to midnight. */ - if (dj1 >= dj2) { - d1 = dj1; - d2 = dj2; - } else { - d1 = dj2; - d2 = dj1; - } - d2 -= 0.5; - -/* Separate day and fraction. */ - f1 = fmod(d1, 1.0); - f2 = fmod(d2, 1.0); - f = fmod(f1 + f2, 1.0); - if (f < 0.0) f += 1.0; - d = floor(d1 - f1) + floor(d2 - f2) + floor(f1 + f2 - f); - jd = (long) floor(d) + 1L; - -/* Express day in Gregorian calendar. */ - l = jd + 68569L; - n = (4L * l) / 146097L; - l -= (146097L * n + 3L) / 4L; - i = (4000L * (l + 1L)) / 1461001L; - l -= (1461L * i) / 4L - 31L; - k = (80L * l) / 2447L; - *id = (int) (l - (2447L * k) / 80L); - l = k / 11L; - *im = (int) (k + 2L - 12L * l); - *iy = (int) (100L * (n - 49L) + i + l); - *fd = f; - - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/jdcalf.c b/ast/erfa/jdcalf.c deleted file mode 100644 index 85efb68..0000000 --- a/ast/erfa/jdcalf.c +++ /dev/null @@ -1,170 +0,0 @@ -#include "erfa.h" - -int eraJdcalf(int ndp, double dj1, double dj2, int iymdf[4]) -/* -** - - - - - - - - - - -** e r a J d c a l f -** - - - - - - - - - - -** -** Julian Date to Gregorian Calendar, expressed in a form convenient -** for formatting messages: rounded to a specified precision. -** -** Given: -** ndp int number of decimal places of days in fraction -** dj1,dj2 double dj1+dj2 = Julian Date (Note 1) -** -** Returned: -** iymdf int[4] year, month, day, fraction in Gregorian -** calendar -** -** Returned (function value): -** int status: -** -1 = date out of range -** 0 = OK -** +1 = NDP not 0-9 (interpreted as 0) -** -** Notes: -** -** 1) The Julian Date is apportioned in any convenient way between -** the arguments dj1 and dj2. For example, JD=2450123.7 could -** be expressed in any of these ways, among others: -** -** dj1 dj2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** 2) In early eras the conversion is from the "Proleptic Gregorian -** Calendar"; no account is taken of the date(s) of adoption of -** the Gregorian Calendar, nor is the AD/BC numbering convention -** observed. -** -** 3) Refer to the function eraJd2cal. -** -** 4) NDP should be 4 or less if internal overflows are to be -** avoided on machines which use 16-bit integers. -** -** Called: -** eraJd2cal JD to Gregorian calendar -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 12.92 (p604). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int j, js; - double denom, d1, d2, f1, f2, f; - - -/* Denominator of fraction (e.g. 100 for 2 decimal places). */ - if ((ndp >= 0) && (ndp <= 9)) { - j = 0; - denom = pow(10.0, ndp); - } else { - j = 1; - denom = 1.0; - } - -/* Copy the date, big then small, and realign to midnight. */ - if (dj1 >= dj2) { - d1 = dj1; - d2 = dj2; - } else { - d1 = dj2; - d2 = dj1; - } - d2 -= 0.5; - -/* Separate days and fractions. */ - f1 = fmod(d1, 1.0); - f2 = fmod(d2, 1.0); - d1 = floor(d1 - f1); - d2 = floor(d2 - f2); - -/* Round the total fraction to the specified number of places. */ - f = floor((f1+f2)*denom + 0.5) / denom; - -/* Re-assemble the rounded date and re-align to noon. */ - d2 += f + 0.5; - -/* Convert to Gregorian calendar. */ - js = eraJd2cal(d1, d2, &iymdf[0], &iymdf[1], &iymdf[2], &f); - if (js == 0) { - iymdf[3] = (int) (f * denom); - } else { - j = js; - } - -/* Return the status. */ - return j; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ld.c b/ast/erfa/ld.c deleted file mode 100644 index c1569fd..0000000 --- a/ast/erfa/ld.c +++ /dev/null @@ -1,161 +0,0 @@ -#include "erfa.h" - -void eraLd(double bm, double p[3], double q[3], double e[3], - double em, double dlim, double p1[3]) -/* -** - - - - - - -** e r a L d -** - - - - - - -** -** Apply light deflection by a solar-system body, as part of -** transforming coordinate direction into natural direction. -** -** Given: -** bm double mass of the gravitating body (solar masses) -** p double[3] direction from observer to source (unit vector) -** q double[3] direction from body to source (unit vector) -** e double[3] direction from body to observer (unit vector) -** em double distance from body to observer (au) -** dlim double deflection limiter (Note 4) -** -** Returned: -** p1 double[3] observer to deflected source (unit vector) -** -** Notes: -** -** 1) The algorithm is based on Expr. (70) in Klioner (2003) and -** Expr. (7.63) in the Explanatory Supplement (Urban & Seidelmann -** 2013), with some rearrangement to minimize the effects of machine -** precision. -** -** 2) The mass parameter bm can, as required, be adjusted in order to -** allow for such effects as quadrupole field. -** -** 3) The barycentric position of the deflecting body should ideally -** correspond to the time of closest approach of the light ray to -** the body. -** -** 4) The deflection limiter parameter dlim is phi^2/2, where phi is -** the angular separation (in radians) between source and body at -** which limiting is applied. As phi shrinks below the chosen -** threshold, the deflection is artificially reduced, reaching zero -** for phi = 0. -** -** 5) The returned vector p1 is not normalized, but the consequential -** departure from unit magnitude is always negligible. -** -** 6) The arguments p and p1 can be the same array. -** -** 7) To accumulate total light deflection taking into account the -** contributions from several bodies, call the present function for -** each body in succession, in decreasing order of distance from the -** observer. -** -** 8) For efficiency, validation is omitted. The supplied vectors must -** be of unit magnitude, and the deflection limiter non-zero and -** positive. -** -** References: -** -** Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to -** the Astronomical Almanac, 3rd ed., University Science Books -** (2013). -** -** Klioner, Sergei A., "A practical relativistic model for micro- -** arcsecond astrometry in space", Astr. J. 125, 1580-1597 (2003). -** -** Called: -** eraPdp scalar product of two p-vectors -** eraPxp vector product of two p-vectors -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int i; - double qpe[3], qdqpe, w, eq[3], peq[3]; - - -/* q . (q + e). */ - for (i = 0; i < 3; i++) { - qpe[i] = q[i] + e[i]; - } - qdqpe = eraPdp(q, qpe); - -/* 2 x G x bm / ( em x c^2 x ( q . (q + e) ) ). */ - w = bm * ERFA_SRS / em / ERFA_GMAX(qdqpe,dlim); - -/* p x (e x q). */ - eraPxp(e, q, eq); - eraPxp(p, eq, peq); - -/* Apply the deflection. */ - for (i = 0; i < 3; i++) { - p1[i] = p[i] + w*peq[i]; - } - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ldn.c b/ast/erfa/ldn.c deleted file mode 100644 index 5ad0a50..0000000 --- a/ast/erfa/ldn.c +++ /dev/null @@ -1,183 +0,0 @@ -#include "erfa.h" - -void eraLdn(int n, eraLDBODY b[], double ob[3], double sc[3], - double sn[3]) -/*+ -** - - - - - - - -** e r a L d n -** - - - - - - - -** -** For a star, apply light deflection by multiple solar-system bodies, -** as part of transforming coordinate direction into natural direction. -** -** Given: -** n int number of bodies (note 1) -** b eraLDBODY[n] data for each of the n bodies (Notes 1,2): -** bm double mass of the body (solar masses, Note 3) -** dl double deflection limiter (Note 4) -** pv [2][3] barycentric PV of the body (au, au/day) -** ob double[3] barycentric position of the observer (au) -** sc double[3] observer to star coord direction (unit vector) -** -** Returned: -** sn double[3] observer to deflected star (unit vector) -** -** 1) The array b contains n entries, one for each body to be -** considered. If n = 0, no gravitational light deflection will be -** applied, not even for the Sun. -** -** 2) The array b should include an entry for the Sun as well as for -** any planet or other body to be taken into account. The entries -** should be in the order in which the light passes the body. -** -** 3) In the entry in the b array for body i, the mass parameter -** b[i].bm can, as required, be adjusted in order to allow for such -** effects as quadrupole field. -** -** 4) The deflection limiter parameter b[i].dl is phi^2/2, where phi is -** the angular separation (in radians) between star and body at -** which limiting is applied. As phi shrinks below the chosen -** threshold, the deflection is artificially reduced, reaching zero -** for phi = 0. Example values suitable for a terrestrial -** observer, together with masses, are as follows: -** -** body i b[i].bm b[i].dl -** -** Sun 1.0 6e-6 -** Jupiter 0.00095435 3e-9 -** Saturn 0.00028574 3e-10 -** -** 5) For cases where the starlight passes the body before reaching the -** observer, the body is placed back along its barycentric track by -** the light time from that point to the observer. For cases where -** the body is "behind" the observer no such shift is applied. If -** a different treatment is preferred, the user has the option of -** instead using the eraLd function. Similarly, eraLd can be used -** for cases where the source is nearby, not a star. -** -** 6) The returned vector sn is not normalized, but the consequential -** departure from unit magnitude is always negligible. -** -** 7) The arguments sc and sn can be the same array. -** -** 8) For efficiency, validation is omitted. The supplied masses must -** be greater than zero, the position and velocity vectors must be -** right, and the deflection limiter greater than zero. -** -** Reference: -** -** Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to -** the Astronomical Almanac, 3rd ed., University Science Books -** (2013), Section 7.2.4. -** -** Called: -** eraCp copy p-vector -** eraPdp scalar product of two p-vectors -** eraPmp p-vector minus p-vector -** eraPpsp p-vector plus scaled p-vector -** eraPn decompose p-vector into modulus and direction -** eraLd light deflection by a solar-system body -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Light time for 1 AU (days) */ - const double CR = ERFA_AULT/ERFA_DAYSEC; - - int i; - double v[3], dt, ev[3], em, e[3]; - - -/* Star direction prior to deflection. */ - eraCp(sc, sn); - -/* Body by body. */ - for ( i = 0; i < n; i++ ) { - - /* Body to observer vector at epoch of observation (au). */ - eraPmp ( ob, b[i].pv[0], v ); - - /* Minus the time since the light passed the body (days). */ - dt = eraPdp(sn,v) * CR; - - /* Neutralize if the star is "behind" the observer. */ - dt = ERFA_GMIN(dt, 0.0); - - /* Backtrack the body to the time the light was passing the body. */ - eraPpsp(v, -dt, b[i].pv[1], ev); - - /* Body to observer vector as magnitude and direction. */ - eraPn(ev, &em, e); - - /* Apply light deflection for this body. */ - eraLd ( b[i].bm, sn, sn, e, em, b[i].dl, sn ); - - /* Next body. */ - } - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ldsun.c b/ast/erfa/ldsun.c deleted file mode 100644 index 62ed117..0000000 --- a/ast/erfa/ldsun.c +++ /dev/null @@ -1,115 +0,0 @@ -#include "erfa.h" - -void eraLdsun(double p[3], double e[3], double em, double p1[3]) -/* -** - - - - - - - - - -** e r a L d s u n -** - - - - - - - - - -** -** Deflection of starlight by the Sun. -** -** Given: -** p double[3] direction from observer to star (unit vector) -** e double[3] direction from Sun to observer (unit vector) -** em double distance from Sun to observer (au) -** -** Returned: -** p1 double[3] observer to deflected star (unit vector) -** -** Notes: -** -** 1) The source is presumed to be sufficiently distant that its -** directions seen from the Sun and the observer are essentially -** the same. -** -** 2) The deflection is restrained when the angle between the star and -** the center of the Sun is less than a threshold value, falling to -** zero deflection for zero separation. The chosen threshold value -** is within the solar limb for all solar-system applications, and -** is about 5 arcminutes for the case of a terrestrial observer. -** -** 3) The arguments p and p1 can be the same array. -** -** Called: -** eraLd light deflection by a solar-system body -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double em2, dlim; - - -/* Deflection limiter (smaller for distant observers). */ - em2 = em*em; - if ( em2 < 1.0 ) em2 = 1.0; - dlim = 1e-6 / (em2 > 1.0 ? em2 : 1.0); - -/* Apply the deflection. */ - eraLd(1.0, p, p, e, em, dlim, p1); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/lteceq.c b/ast/erfa/lteceq.c deleted file mode 100644 index 9ba725d..0000000 --- a/ast/erfa/lteceq.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "erfa.h" - -void eraLteceq(double epj, double dl, double db, double *dr, double *dd) -/* -** - - - - - - - - - - -** e r a L t e c e q -** - - - - - - - - - - -** -** Transformation from ecliptic coordinates (mean equinox and ecliptic -** of date) to ICRS RA,Dec, using a long-term precession model. -** -** Given: -** epj double Julian epoch (TT) -** dl,db double ecliptic longitude and latitude (radians) -** -** Returned: -** dr,dd double ICRS right ascension and declination (radians) -** -** 1) No assumptions are made about whether the coordinates represent -** starlight and embody astrometric effects such as parallax or -** aberration. -** -** 2) The transformation is approximately that from ecliptic longitude -** and latitude (mean equinox and ecliptic of date) to mean J2000.0 -** right ascension and declination, with only frame bias (always -** less than 25 mas) to disturb this classical picture. -** -** 3) The Vondrak et al. (2011, 2012) 400 millennia precession model -** agrees with the IAU 2006 precession at J2000.0 and stays within -** 100 microarcseconds during the 20th and 21st centuries. It is -** accurate to a few arcseconds throughout the historical period, -** worsening to a few tenths of a degree at the end of the -** +/- 200,000 year time span. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraLtecm J2000.0 to ecliptic rotation matrix, long term -** eraTrxp product of transpose of r-matrix and p-vector -** eraC2s unit vector to spherical coordinates -** eraAnp normalize angle into range 0 to 2pi -** eraAnpm normalize angle into range +/- pi -** -** References: -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession -** expressions, valid for long time intervals, Astron.Astrophys. 534, -** A22 -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession -** expressions, valid for long time intervals (Corrigendum), -** Astron.Astrophys. 541, C1 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rm[3][3], v1[3], v2[3], a, b; - - -/* Spherical to Cartesian. */ - eraS2c(dl, db, v1); - -/* Rotation matrix, ICRS equatorial to ecliptic. */ - eraLtecm(epj, rm); - -/* The transformation from ecliptic to ICRS. */ - eraTrxp(rm, v1, v2); - -/* Cartesian to spherical. */ - eraC2s(v2, &a, &b); - -/* Express in conventional ranges. */ - *dr = eraAnp(a); - *dd = eraAnpm(b); - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ltecm.c b/ast/erfa/ltecm.c deleted file mode 100644 index c0bf28b..0000000 --- a/ast/erfa/ltecm.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "erfa.h" - -void eraLtecm(double epj, double rm[3][3]) -/* -** - - - - - - - - - -** e r a L t e c m -** - - - - - - - - - -** -** ICRS equatorial to ecliptic rotation matrix, long-term. -** -** Given: -** epj double Julian epoch (TT) -** -** Returned: -** rm double[3][3] ICRS to ecliptic rotation matrix -** -** Notes: -** -** 1) The matrix is in the sense -** -** E_ep = rm x P_ICRS, -** -** where P_ICRS is a vector with respect to ICRS right ascension -** and declination axes and E_ep is the same vector with respect to -** the (inertial) ecliptic and equinox of epoch epj. -** -** 2) P_ICRS is a free vector, merely a direction, typically of unit -** magnitude, and not bound to any particular spatial origin, such -** as the Earth, Sun or SSB. No assumptions are made about whether -** it represents starlight and embodies astrometric effects such as -** parallax or aberration. The transformation is approximately that -** between mean J2000.0 right ascension and declination and ecliptic -** longitude and latitude, with only frame bias (always less than -** 25 mas) to disturb this classical picture. -** -** 3) The Vondrak et al. (2011, 2012) 400 millennia precession model -** agrees with the IAU 2006 precession at J2000.0 and stays within -** 100 microarcseconds during the 20th and 21st centuries. It is -** accurate to a few arcseconds throughout the historical period, -** worsening to a few tenths of a degree at the end of the -** +/- 200,000 year time span. -** -** Called: -** eraLtpequ equator pole, long term -** eraLtpecl ecliptic pole, long term -** eraPxp vector product -** eraPn normalize vector -** -** References: -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession -** expressions, valid for long time intervals, Astron.Astrophys. 534, -** A22 -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession -** expressions, valid for long time intervals (Corrigendum), -** Astron.Astrophys. 541, C1 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Frame bias (IERS Conventions 2010, Eqs. 5.21 and 5.33) */ - const double dx = -0.016617 * ERFA_DAS2R, - de = -0.0068192 * ERFA_DAS2R, - dr = -0.0146 * ERFA_DAS2R; - - double p[3], z[3], w[3], s, x[3], y[3]; - - -/* Equator pole. */ - eraLtpequ(epj, p); - -/* Ecliptic pole (bottom row of equatorial to ecliptic matrix). */ - eraLtpecl(epj, z); - -/* Equinox (top row of matrix). */ - eraPxp(p, z, w); - eraPn(w, &s, x); - -/* Middle row of matrix. */ - eraPxp(z, x, y); - -/* Combine with frame bias. */ - rm[0][0] = x[0] - x[1]*dr + x[2]*dx; - rm[0][1] = x[0]*dr + x[1] + x[2]*de; - rm[0][2] = - x[0]*dx - x[1]*de + x[2]; - rm[1][0] = y[0] - y[1]*dr + y[2]*dx; - rm[1][1] = y[0]*dr + y[1] + y[2]*de; - rm[1][2] = - y[0]*dx - y[1]*de + y[2]; - rm[2][0] = z[0] - z[1]*dr + z[2]*dx; - rm[2][1] = z[0]*dr + z[1] + z[2]*de; - rm[2][2] = - z[0]*dx - z[1]*de + z[2]; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/lteqec.c b/ast/erfa/lteqec.c deleted file mode 100644 index a93ec0f..0000000 --- a/ast/erfa/lteqec.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "erfa.h" - -void eraLteqec(double epj, double dr, double dd, double *dl, double *db) -/* -** - - - - - - - - - - -** e r a L t e q e c -** - - - - - - - - - - -** -** Transformation from ICRS equatorial coordinates to ecliptic -** coordinates (mean equinox and ecliptic of date) using a long-term -** precession model. -** -** Given: -** epj double Julian epoch (TT) -** dr,dd double ICRS right ascension and declination (radians) -** -** Returned: -** dl,db double ecliptic longitude and latitude (radians) -** -** 1) No assumptions are made about whether the coordinates represent -** starlight and embody astrometric effects such as parallax or -** aberration. -** -** 2) The transformation is approximately that from mean J2000.0 right -** ascension and declination to ecliptic longitude and latitude -** (mean equinox and ecliptic of date), with only frame bias (always -** less than 25 mas) to disturb this classical picture. -** -** 3) The Vondrak et al. (2011, 2012) 400 millennia precession model -** agrees with the IAU 2006 precession at J2000.0 and stays within -** 100 microarcseconds during the 20th and 21st centuries. It is -** accurate to a few arcseconds throughout the historical period, -** worsening to a few tenths of a degree at the end of the -** +/- 200,000 year time span. -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraLtecm J2000.0 to ecliptic rotation matrix, long term -** eraRxp product of r-matrix and p-vector -** eraC2s unit vector to spherical coordinates -** eraAnp normalize angle into range 0 to 2pi -** eraAnpm normalize angle into range +/- pi -** -** References: -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession -** expressions, valid for long time intervals, Astron.Astrophys. 534, -** A22 -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession -** expressions, valid for long time intervals (Corrigendum), -** Astron.Astrophys. 541, C1 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rm[3][3], v1[3], v2[3], a, b; - - -/* Spherical to Cartesian. */ - eraS2c(dr, dd, v1); - -/* Rotation matrix, ICRS equatorial to ecliptic. */ - eraLtecm(epj, rm); - -/* The transformation from ICRS to ecliptic. */ - eraRxp(rm, v1, v2); - -/* Cartesian to spherical. */ - eraC2s(v2, &a, &b); - -/* Express in conventional ranges. */ - *dl = eraAnp(a); - *db = eraAnpm(b); - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ltp.c b/ast/erfa/ltp.c deleted file mode 100644 index 2b8249c..0000000 --- a/ast/erfa/ltp.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "erfa.h" - -void eraLtp(double epj, double rp[3][3]) -/* -** - - - - - - - -** e r a L t p -** - - - - - - - -** -** Long-term precession matrix. -** -** Given: -** epj double Julian epoch (TT) -** -** Returned: -** rp double[3][3] precession matrix, J2000.0 to date -** -** Notes: -** -** 1) The matrix is in the sense -** -** P_date = rp x P_J2000, -** -** where P_J2000 is a vector with respect to the J2000.0 mean -** equator and equinox and P_date is the same vector with respect to -** the equator and equinox of epoch epj. -** -** 2) The Vondrak et al. (2011, 2012) 400 millennia precession model -** agrees with the IAU 2006 precession at J2000.0 and stays within -** 100 microarcseconds during the 20th and 21st centuries. It is -** accurate to a few arcseconds throughout the historical period, -** worsening to a few tenths of a degree at the end of the -** +/- 200,000 year time span. -** -** Called: -** eraLtpequ equator pole, long term -** eraLtpecl ecliptic pole, long term -** eraPxp vector product -** eraPn normalize vector -** -** References: -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession -** expressions, valid for long time intervals, Astron.Astrophys. 534, -** A22 -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession -** expressions, valid for long time intervals (Corrigendum), -** Astron.Astrophys. 541, C1 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int i; - double peqr[3], pecl[3], v[3], w, eqx[3]; - - -/* Equator pole (bottom row of matrix). */ - eraLtpequ(epj, peqr); - -/* Ecliptic pole. */ - eraLtpecl(epj, pecl); - -/* Equinox (top row of matrix). */ - eraPxp(peqr, pecl, v); - eraPn(v, &w, eqx); - -/* Middle row of matrix. */ - eraPxp(peqr, eqx, v); - -/* Assemble the matrix. */ - for ( i = 0; i < 3; i++ ) { - rp[0][i] = eqx[i]; - rp[1][i] = v[i]; - rp[2][i] = peqr[i]; - } - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ltpb.c b/ast/erfa/ltpb.c deleted file mode 100644 index 6818f19..0000000 --- a/ast/erfa/ltpb.c +++ /dev/null @@ -1,133 +0,0 @@ -#include "erfa.h" - -void eraLtpb(double epj, double rpb[3][3]) -/* -** - - - - - - - - -** e r a L t p b -** - - - - - - - - -** -** Long-term precession matrix, including ICRS frame bias. -** -** Given: -** epj double Julian epoch (TT) -** -** Returned: -** rpb double[3][3] precession-bias matrix, J2000.0 to date -** -** Notes: -** -** 1) The matrix is in the sense -** -** P_date = rpb x P_ICRS, -** -** where P_ICRS is a vector in the Geocentric Celestial Reference -** System, and P_date is the vector with respect to the Celestial -** Intermediate Reference System at that date but with nutation -** neglected. -** -** 2) A first order frame bias formulation is used, of sub- -** microarcsecond accuracy compared with a full 3D rotation. -** -** 3) The Vondrak et al. (2011, 2012) 400 millennia precession model -** agrees with the IAU 2006 precession at J2000.0 and stays within -** 100 microarcseconds during the 20th and 21st centuries. It is -** accurate to a few arcseconds throughout the historical period, -** worsening to a few tenths of a degree at the end of the -** +/- 200,000 year time span. -** -** References: -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession -** expressions, valid for long time intervals, Astron.Astrophys. 534, -** A22 -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession -** expressions, valid for long time intervals (Corrigendum), -** Astron.Astrophys. 541, C1 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Frame bias (IERS Conventions 2010, Eqs. 5.21 and 5.33) */ - const double dx = -0.016617 * ERFA_DAS2R, - de = -0.0068192 * ERFA_DAS2R, - dr = -0.0146 * ERFA_DAS2R; - - int i; - double rp[3][3]; - - -/* Precession matrix. */ - eraLtp(epj, rp); - -/* Apply the bias. */ - for ( i = 0; i < 3; i++ ) { - rpb[i][0] = rp[i][0] - rp[i][1]*dr + rp[i][2]*dx; - rpb[i][1] = rp[i][0]*dr + rp[i][1] + rp[i][2]*de; - rpb[i][2] = -rp[i][0]*dx - rp[i][1]*de + rp[i][2]; - } - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ltpecl.c b/ast/erfa/ltpecl.c deleted file mode 100644 index feb3d55..0000000 --- a/ast/erfa/ltpecl.c +++ /dev/null @@ -1,177 +0,0 @@ -#include "erfa.h" - -void eraLtpecl(double epj, double vec[3]) -/* -** - - - - - - - - - - -** e r a L t p e c l -** - - - - - - - - - - -** -** Long-term precession of the ecliptic. -** -** Given: -** epj double Julian epoch (TT) -** -** Returned: -** vec double[3] ecliptic pole unit vector -** -** Notes: -** -** 1) The returned vector is with respect to the J2000.0 mean equator -** and equinox. -** -** 2) The Vondrak et al. (2011, 2012) 400 millennia precession model -** agrees with the IAU 2006 precession at J2000.0 and stays within -** 100 microarcseconds during the 20th and 21st centuries. It is -** accurate to a few arcseconds throughout the historical period, -** worsening to a few tenths of a degree at the end of the -** +/- 200,000 year time span. -** -** References: -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession -** expressions, valid for long time intervals, Astron.Astrophys. 534, -** A22 -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession -** expressions, valid for long time intervals (Corrigendum), -** Astron.Astrophys. 541, C1 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Obliquity at J2000.0 (radians). */ - static const double eps0 = 84381.406 * ERFA_DAS2R; - -/* Polynomial coefficients */ - enum { NPOL = 4 }; - static const double pqpol[2][NPOL] = { - { 5851.607687, - -0.1189000, - -0.00028913, - 0.000000101}, - {-1600.886300, - 1.1689818, - -0.00000020, - -0.000000437} - }; - -/* Periodic coefficients */ - static const double pqper[][5] = { - { 708.15,-5486.751211,-684.661560, 667.666730,-5523.863691}, - {2309.00, -17.127623,2446.283880,-2354.886252, -549.747450}, - {1620.00, -617.517403, 399.671049, -428.152441, -310.998056}, - { 492.20, 413.442940,-356.652376, 376.202861, 421.535876}, - {1183.00, 78.614193,-186.387003, 184.778874, -36.776172}, - { 622.00, -180.732815,-316.800070, 335.321713, -145.278396}, - { 882.00, -87.676083, 198.296701, -185.138669, -34.744450}, - { 547.00, 46.140315, 101.135679, -120.972830, 22.885731} - }; - static const int NPER = (int) ( sizeof pqper / 5 / sizeof (double) ); - -/* Miscellaneous */ - int i; - double t, p, q, w, a, s, c; - - -/* Centuries since J2000. */ - t = ( epj - 2000.0 ) / 100.0; - -/* Initialize P_A and Q_A accumulators. */ - p = 0.0; - q = 0.0; - -/* Periodic terms. */ - w = ERFA_D2PI*t; - for ( i = 0; i < NPER; i++ ) { - a = w/pqper[i][0]; - s = sin(a); - c = cos(a); - p += c*pqper[i][1] + s*pqper[i][3]; - q += c*pqper[i][2] + s*pqper[i][4]; - } - -/* Polynomial terms. */ - w = 1.0; - for ( i = 0; i < NPOL; i++ ) { - p += pqpol[0][i]*w; - q += pqpol[1][i]*w; - w *= t; - } - -/* P_A and Q_A (radians). */ - p *= ERFA_DAS2R; - q *= ERFA_DAS2R; - -/* Form the ecliptic pole vector. */ - w = 1.0 - p*p - q*q; - w = w < 0.0 ? 0.0 : sqrt(w); - s = sin(eps0); - c = cos(eps0); - vec[0] = p; - vec[1] = - q*c - w*s; - vec[2] = - q*s + w*c; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ltpequ.c b/ast/erfa/ltpequ.c deleted file mode 100644 index 354ce32..0000000 --- a/ast/erfa/ltpequ.c +++ /dev/null @@ -1,177 +0,0 @@ -#include "erfa.h" - -void eraLtpequ(double epj, double veq[3]) -/* -** - - - - - - - - - - -** e r a L t p e q u -** - - - - - - - - - - -** -** Long-term precession of the equator. -** -** Given: -** epj double Julian epoch (TT) -** -** Returned: -** veq double[3] equator pole unit vector -** -** Notes: -** -** 1) The returned vector is with respect to the J2000.0 mean equator -** and equinox. -** -** 2) The Vondrak et al. (2011, 2012) 400 millennia precession model -** agrees with the IAU 2006 precession at J2000.0 and stays within -** 100 microarcseconds during the 20th and 21st centuries. It is -** accurate to a few arcseconds throughout the historical period, -** worsening to a few tenths of a degree at the end of the -** +/- 200,000 year time span. -** -** References: -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession -** expressions, valid for long time intervals, Astron.Astrophys. 534, -** A22 -** -** Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession -** expressions, valid for long time intervals (Corrigendum), -** Astron.Astrophys. 541, C1 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Polynomial coefficients */ - enum { NPOL = 4 }; - static const double xypol[2][NPOL] = { - { 5453.282155, - 0.4252841, - -0.00037173, - -0.000000152}, - {-73750.930350, - -0.7675452, - -0.00018725, - 0.000000231} - }; - -/* Periodic coefficients */ - static const double xyper[][5] = { - { 256.75, -819.940624,75004.344875,81491.287984, 1558.515853}, - { 708.15,-8444.676815, 624.033993, 787.163481, 7774.939698}, - { 274.20, 2600.009459, 1251.136893, 1251.296102,-2219.534038}, - { 241.45, 2755.175630,-1102.212834,-1257.950837,-2523.969396}, - {2309.00, -167.659835,-2660.664980,-2966.799730, 247.850422}, - { 492.20, 871.855056, 699.291817, 639.744522, -846.485643}, - { 396.10, 44.769698, 153.167220, 131.600209,-1393.124055}, - { 288.90, -512.313065, -950.865637, -445.040117, 368.526116}, - { 231.10, -819.415595, 499.754645, 584.522874, 749.045012}, - {1610.00, -538.071099, -145.188210, -89.756563, 444.704518}, - { 620.00, -189.793622, 558.116553, 524.429630, 235.934465}, - { 157.87, -402.922932, -23.923029, -13.549067, 374.049623}, - { 220.30, 179.516345, -165.405086, -210.157124, -171.330180}, - {1200.00, -9.814756, 9.344131, -44.919798, -22.899655} - }; - static const int NPER = (int) ( sizeof xyper / 5 / sizeof (double) ); - -/* Miscellaneous */ - int i; - double t, x, y, w, a, s, c; - - -/* Centuries since J2000. */ - t = ( epj - 2000.0 ) / 100.0; - -/* Initialize X and Y accumulators. */ - x = 0.0; - y = 0.0; - -/* Periodic terms. */ - w = ERFA_D2PI * t; - for ( i = 0; i < NPER; i++ ) { - a = w / xyper[i][0]; - s = sin(a); - c = cos(a); - x += c*xyper[i][1] + s*xyper[i][3]; - y += c*xyper[i][2] + s*xyper[i][4]; - } - -/* Polynomial terms. */ - w = 1.0; - for ( i = 0; i < NPOL; i++ ) { - x += xypol[0][i]*w; - y += xypol[1][i]*w; - w *= t; - } - -/* X and Y (direction cosines). */ - x *= ERFA_DAS2R; - y *= ERFA_DAS2R; - -/* Form the equator pole vector. */ - veq[0] = x; - veq[1] = y; - w = 1.0 - x*x - y*y; - veq[2] = w < 0.0 ? 0.0 : sqrt(w); - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/num00a.c b/ast/erfa/num00a.c deleted file mode 100644 index 24964e3..0000000 --- a/ast/erfa/num00a.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "erfa.h" - -void eraNum00a(double date1, double date2, double rmatn[3][3]) -/* -** - - - - - - - - - - -** e r a N u m 0 0 a -** - - - - - - - - - - -** -** Form the matrix of nutation for a given date, IAU 2000A model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rmatn double[3][3] nutation matrix -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(true) = rmatn * V(mean), where -** the p-vector V(true) is with respect to the true equatorial triad -** of date and the p-vector V(mean) is with respect to the mean -** equatorial triad of date. -** -** 3) A faster, but slightly less accurate result (about 1 mas), can be -** obtained by using instead the eraNum00b function. -** -** Called: -** eraPn00a bias/precession/nutation, IAU 2000A -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 3.222-3 (p114). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rbpn[3][3]; - - -/* Obtain the required matrix (discarding other results). */ - eraPn00a(date1, date2, - &dpsi, &deps, &epsa, rb, rp, rbp, rmatn, rbpn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/num00b.c b/ast/erfa/num00b.c deleted file mode 100644 index f006257..0000000 --- a/ast/erfa/num00b.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "erfa.h" - -void eraNum00b(double date1, double date2, double rmatn[3][3]) -/* -** - - - - - - - - - - -** e r a N u m 0 0 b -** - - - - - - - - - - -** -** Form the matrix of nutation for a given date, IAU 2000B model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rmatn double[3][3] nutation matrix -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(true) = rmatn * V(mean), where -** the p-vector V(true) is with respect to the true equatorial triad -** of date and the p-vector V(mean) is with respect to the mean -** equatorial triad of date. -** -** 3) The present function is faster, but slightly less accurate (about -** 1 mas), than the eraNum00a function. -** -** Called: -** eraPn00b bias/precession/nutation, IAU 2000B -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 3.222-3 (p114). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rbpn[3][3]; - - -/* Obtain the required matrix (discarding other results). */ - eraPn00b(date1, date2, - &dpsi, &deps, &epsa, rb, rp, rbp, rmatn, rbpn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/num06a.c b/ast/erfa/num06a.c deleted file mode 100644 index a27d23a..0000000 --- a/ast/erfa/num06a.c +++ /dev/null @@ -1,134 +0,0 @@ -#include "erfa.h" - -void eraNum06a(double date1, double date2, double rmatn[3][3]) -/* -** - - - - - - - - - - -** e r a N u m 0 6 a -** - - - - - - - - - - -** -** Form the matrix of nutation for a given date, IAU 2006/2000A model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rmatn double[3][3] nutation matrix -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(true) = rmatn * V(mean), where -** the p-vector V(true) is with respect to the true equatorial triad -** of date and the p-vector V(mean) is with respect to the mean -** equatorial triad of date. -** -** Called: -** eraObl06 mean obliquity, IAU 2006 -** eraNut06a nutation, IAU 2006/2000A -** eraNumat form nutation matrix -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 3.222-3 (p114). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double eps, dp, de; - - -/* Mean obliquity. */ - eps = eraObl06(date1, date2); - -/* Nutation components. */ - eraNut06a(date1, date2, &dp, &de); - -/* Nutation matrix. */ - eraNumat(eps, dp, de, rmatn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/numat.c b/ast/erfa/numat.c deleted file mode 100644 index 43a3b00..0000000 --- a/ast/erfa/numat.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "erfa.h" - -void eraNumat(double epsa, double dpsi, double deps, double rmatn[3][3]) -/* -** - - - - - - - - - -** e r a N u m a t -** - - - - - - - - - -** -** Form the matrix of nutation. -** -** Given: -** epsa double mean obliquity of date (Note 1) -** dpsi,deps double nutation (Note 2) -** -** Returned: -** rmatn double[3][3] nutation matrix (Note 3) -** -** Notes: -** -** -** 1) The supplied mean obliquity epsa, must be consistent with the -** precession-nutation models from which dpsi and deps were obtained. -** -** 2) The caller is responsible for providing the nutation components; -** they are in longitude and obliquity, in radians and are with -** respect to the equinox and ecliptic of date. -** -** 3) The matrix operates in the sense V(true) = rmatn * V(mean), -** where the p-vector V(true) is with respect to the true -** equatorial triad of date and the p-vector V(mean) is with -** respect to the mean equatorial triad of date. -** -** Called: -** eraIr initialize r-matrix to identity -** eraRx rotate around X-axis -** eraRz rotate around Z-axis -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 3.222-3 (p114). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Build the rotation matrix. */ - eraIr(rmatn); - eraRx(epsa, rmatn); - eraRz(-dpsi, rmatn); - eraRx(-(epsa + deps), rmatn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/nut00a.c b/ast/erfa/nut00a.c deleted file mode 100644 index 4c4e89a..0000000 --- a/ast/erfa/nut00a.c +++ /dev/null @@ -1,2056 +0,0 @@ -#include "erfa.h" - -void eraNut00a(double date1, double date2, double *dpsi, double *deps) -/* -** - - - - - - - - - - -** e r a N u t 0 0 a -** - - - - - - - - - - -** -** Nutation, IAU 2000A model (MHB2000 luni-solar and planetary nutation -** with free core nutation omitted). -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** dpsi,deps double nutation, luni-solar + planetary (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The nutation components in longitude and obliquity are in radians -** and with respect to the equinox and ecliptic of date. The -** obliquity at J2000.0 is assumed to be the Lieske et al. (1977) -** value of 84381.448 arcsec. -** -** Both the luni-solar and planetary nutations are included. The -** latter are due to direct planetary nutations and the -** perturbations of the lunar and terrestrial orbits. -** -** 3) The function computes the MHB2000 nutation series with the -** associated corrections for planetary nutations. It is an -** implementation of the nutation part of the IAU 2000A precession- -** nutation model, formally adopted by the IAU General Assembly in -** 2000, namely MHB2000 (Mathews et al. 2002), but with the free -** core nutation (FCN - see Note 4) omitted. -** -** 4) The full MHB2000 model also contains contributions to the -** nutations in longitude and obliquity due to the free-excitation -** of the free-core-nutation during the period 1979-2000. These FCN -** terms, which are time-dependent and unpredictable, are NOT -** included in the present function and, if required, must be -** independently computed. With the FCN corrections included, the -** present function delivers a pole which is at current epochs -** accurate to a few hundred microarcseconds. The omission of FCN -** introduces further errors of about that size. -** -** 5) The present function provides classical nutation. The MHB2000 -** algorithm, from which it is adapted, deals also with (i) the -** offsets between the GCRS and mean poles and (ii) the adjustments -** in longitude and obliquity due to the changed precession rates. -** These additional functions, namely frame bias and precession -** adjustments, are supported by the ERFA functions eraBi00 and -** eraPr00. -** -** 6) The MHB2000 algorithm also provides "total" nutations, comprising -** the arithmetic sum of the frame bias, precession adjustments, -** luni-solar nutation and planetary nutation. These total -** nutations can be used in combination with an existing IAU 1976 -** precession implementation, such as eraPmat76, to deliver GCRS- -** to-true predictions of sub-mas accuracy at current dates. -** However, there are three shortcomings in the MHB2000 model that -** must be taken into account if more accurate or definitive results -** are required (see Wallace 2002): -** -** (i) The MHB2000 total nutations are simply arithmetic sums, -** yet in reality the various components are successive Euler -** rotations. This slight lack of rigor leads to cross terms -** that exceed 1 mas after a century. The rigorous procedure -** is to form the GCRS-to-true rotation matrix by applying the -** bias, precession and nutation in that order. -** -** (ii) Although the precession adjustments are stated to be with -** respect to Lieske et al. (1977), the MHB2000 model does -** not specify which set of Euler angles are to be used and -** how the adjustments are to be applied. The most literal -** and straightforward procedure is to adopt the 4-rotation -** epsilon_0, psi_A, omega_A, xi_A option, and to add DPSIPR -** to psi_A and DEPSPR to both omega_A and eps_A. -** -** (iii) The MHB2000 model predates the determination by Chapront -** et al. (2002) of a 14.6 mas displacement between the -** J2000.0 mean equinox and the origin of the ICRS frame. It -** should, however, be noted that neglecting this displacement -** when calculating star coordinates does not lead to a -** 14.6 mas change in right ascension, only a small second- -** order distortion in the pattern of the precession-nutation -** effect. -** -** For these reasons, the ERFA functions do not generate the "total -** nutations" directly, though they can of course easily be -** generated by calling eraBi00, eraPr00 and the present function -** and adding the results. -** -** 7) The MHB2000 model contains 41 instances where the same frequency -** appears multiple times, of which 38 are duplicates and three are -** triplicates. To keep the present code close to the original MHB -** algorithm, this small inefficiency has not been corrected. -** -** Called: -** eraFal03 mean anomaly of the Moon -** eraFaf03 mean argument of the latitude of the Moon -** eraFaom03 mean longitude of the Moon's ascending node -** eraFame03 mean longitude of Mercury -** eraFave03 mean longitude of Venus -** eraFae03 mean longitude of Earth -** eraFama03 mean longitude of Mars -** eraFaju03 mean longitude of Jupiter -** eraFasa03 mean longitude of Saturn -** eraFaur03 mean longitude of Uranus -** eraFapa03 general accumulated precession in longitude -** -** References: -** -** Chapront, J., Chapront-Touze, M. & Francou, G. 2002, -** Astron.Astrophys. 387, 700 -** -** Lieske, J.H., Lederle, T., Fricke, W. & Morando, B. 1977, -** Astron.Astrophys. 58, 1-16 -** -** Mathews, P.M., Herring, T.A., Buffet, B.A. 2002, J.Geophys.Res. -** 107, B4. The MHB_2000 code itself was obtained on 9th September -** 2002 from ftp//maia.usno.navy.mil/conv2000/chapter5/IAU2000A. -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999, -** Astron.Astrophys.Supp.Ser. 135, 111 -** -** Wallace, P.T., "Software for Implementing the IAU 2000 -** Resolutions", in IERS Workshop 5.1 (2002) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int i; - double t, el, elp, f, d, om, arg, dp, de, sarg, carg, - al, af, ad, aom, alme, alve, alea, alma, - alju, alsa, alur, alne, apa, dpsils, depsls, - dpsipl, depspl; - -/* Units of 0.1 microarcsecond to radians */ - const double U2R = ERFA_DAS2R / 1e7; - -/* ------------------------- */ -/* Luni-Solar nutation model */ -/* ------------------------- */ - -/* The units for the sine and cosine coefficients are */ -/* 0.1 microarcsecond and the same per Julian century */ - - static const struct { - int nl,nlp,nf,nd,nom; /* coefficients of l,l',F,D,Om */ - double sp,spt,cp; /* longitude sin, t*sin, cos coefficients */ - double ce,cet,se; /* obliquity cos, t*cos, sin coefficients */ - } xls[] = { - - /* 1- 10 */ - { 0, 0, 0, 0, 1, - -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0}, - { 0, 0, 2,-2, 2, - -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0}, - { 0, 0, 2, 0, 2,-2276413.0,-234.0,2796.0,978459.0,-485.0, 1374.0}, - { 0, 0, 0, 0, 2,2074554.0, 207.0, -698.0,-897492.0,470.0, -291.0}, - { 0, 1, 0, 0, 0,1475877.0,-3633.0,11817.0,73871.0,-184.0,-1924.0}, - { 0, 1, 2,-2, 2,-516821.0,1226.0, -524.0,224386.0,-677.0, -174.0}, - { 1, 0, 0, 0, 0, 711159.0, 73.0, -872.0, -6750.0, 0.0, 358.0}, - { 0, 0, 2, 0, 1,-387298.0,-367.0, 380.0, 200728.0, 18.0, 318.0}, - { 1, 0, 2, 0, 2,-301461.0, -36.0, 816.0, 129025.0,-63.0, 367.0}, - { 0,-1, 2,-2, 2, 215829.0,-494.0, 111.0, -95929.0,299.0, 132.0}, - - /* 11-20 */ - { 0, 0, 2,-2, 1, 128227.0, 137.0, 181.0, -68982.0, -9.0, 39.0}, - {-1, 0, 2, 0, 2, 123457.0, 11.0, 19.0, -53311.0, 32.0, -4.0}, - {-1, 0, 0, 2, 0, 156994.0, 10.0, -168.0, -1235.0, 0.0, 82.0}, - { 1, 0, 0, 0, 1, 63110.0, 63.0, 27.0, -33228.0, 0.0, -9.0}, - {-1, 0, 0, 0, 1, -57976.0, -63.0, -189.0, 31429.0, 0.0, -75.0}, - {-1, 0, 2, 2, 2, -59641.0, -11.0, 149.0, 25543.0,-11.0, 66.0}, - { 1, 0, 2, 0, 1, -51613.0, -42.0, 129.0, 26366.0, 0.0, 78.0}, - {-2, 0, 2, 0, 1, 45893.0, 50.0, 31.0, -24236.0,-10.0, 20.0}, - { 0, 0, 0, 2, 0, 63384.0, 11.0, -150.0, -1220.0, 0.0, 29.0}, - { 0, 0, 2, 2, 2, -38571.0, -1.0, 158.0, 16452.0,-11.0, 68.0}, - - /* 21-30 */ - { 0,-2, 2,-2, 2, 32481.0, 0.0, 0.0, -13870.0, 0.0, 0.0}, - {-2, 0, 0, 2, 0, -47722.0, 0.0, -18.0, 477.0, 0.0, -25.0}, - { 2, 0, 2, 0, 2, -31046.0, -1.0, 131.0, 13238.0,-11.0, 59.0}, - { 1, 0, 2,-2, 2, 28593.0, 0.0, -1.0, -12338.0, 10.0, -3.0}, - {-1, 0, 2, 0, 1, 20441.0, 21.0, 10.0, -10758.0, 0.0, -3.0}, - { 2, 0, 0, 0, 0, 29243.0, 0.0, -74.0, -609.0, 0.0, 13.0}, - { 0, 0, 2, 0, 0, 25887.0, 0.0, -66.0, -550.0, 0.0, 11.0}, - { 0, 1, 0, 0, 1, -14053.0, -25.0, 79.0, 8551.0, -2.0, -45.0}, - {-1, 0, 0, 2, 1, 15164.0, 10.0, 11.0, -8001.0, 0.0, -1.0}, - { 0, 2, 2,-2, 2, -15794.0, 72.0, -16.0, 6850.0,-42.0, -5.0}, - - /* 31-40 */ - { 0, 0,-2, 2, 0, 21783.0, 0.0, 13.0, -167.0, 0.0, 13.0}, - { 1, 0, 0,-2, 1, -12873.0, -10.0, -37.0, 6953.0, 0.0, -14.0}, - { 0,-1, 0, 0, 1, -12654.0, 11.0, 63.0, 6415.0, 0.0, 26.0}, - {-1, 0, 2, 2, 1, -10204.0, 0.0, 25.0, 5222.0, 0.0, 15.0}, - { 0, 2, 0, 0, 0, 16707.0, -85.0, -10.0, 168.0, -1.0, 10.0}, - { 1, 0, 2, 2, 2, -7691.0, 0.0, 44.0, 3268.0, 0.0, 19.0}, - {-2, 0, 2, 0, 0, -11024.0, 0.0, -14.0, 104.0, 0.0, 2.0}, - { 0, 1, 2, 0, 2, 7566.0, -21.0, -11.0, -3250.0, 0.0, -5.0}, - { 0, 0, 2, 2, 1, -6637.0, -11.0, 25.0, 3353.0, 0.0, 14.0}, - { 0,-1, 2, 0, 2, -7141.0, 21.0, 8.0, 3070.0, 0.0, 4.0}, - - /* 41-50 */ - { 0, 0, 0, 2, 1, -6302.0, -11.0, 2.0, 3272.0, 0.0, 4.0}, - { 1, 0, 2,-2, 1, 5800.0, 10.0, 2.0, -3045.0, 0.0, -1.0}, - { 2, 0, 2,-2, 2, 6443.0, 0.0, -7.0, -2768.0, 0.0, -4.0}, - {-2, 0, 0, 2, 1, -5774.0, -11.0, -15.0, 3041.0, 0.0, -5.0}, - { 2, 0, 2, 0, 1, -5350.0, 0.0, 21.0, 2695.0, 0.0, 12.0}, - { 0,-1, 2,-2, 1, -4752.0, -11.0, -3.0, 2719.0, 0.0, -3.0}, - { 0, 0, 0,-2, 1, -4940.0, -11.0, -21.0, 2720.0, 0.0, -9.0}, - {-1,-1, 0, 2, 0, 7350.0, 0.0, -8.0, -51.0, 0.0, 4.0}, - { 2, 0, 0,-2, 1, 4065.0, 0.0, 6.0, -2206.0, 0.0, 1.0}, - { 1, 0, 0, 2, 0, 6579.0, 0.0, -24.0, -199.0, 0.0, 2.0}, - - /* 51-60 */ - { 0, 1, 2,-2, 1, 3579.0, 0.0, 5.0, -1900.0, 0.0, 1.0}, - { 1,-1, 0, 0, 0, 4725.0, 0.0, -6.0, -41.0, 0.0, 3.0}, - {-2, 0, 2, 0, 2, -3075.0, 0.0, -2.0, 1313.0, 0.0, -1.0}, - { 3, 0, 2, 0, 2, -2904.0, 0.0, 15.0, 1233.0, 0.0, 7.0}, - { 0,-1, 0, 2, 0, 4348.0, 0.0, -10.0, -81.0, 0.0, 2.0}, - { 1,-1, 2, 0, 2, -2878.0, 0.0, 8.0, 1232.0, 0.0, 4.0}, - { 0, 0, 0, 1, 0, -4230.0, 0.0, 5.0, -20.0, 0.0, -2.0}, - {-1,-1, 2, 2, 2, -2819.0, 0.0, 7.0, 1207.0, 0.0, 3.0}, - {-1, 0, 2, 0, 0, -4056.0, 0.0, 5.0, 40.0, 0.0, -2.0}, - { 0,-1, 2, 2, 2, -2647.0, 0.0, 11.0, 1129.0, 0.0, 5.0}, - - /* 61-70 */ - {-2, 0, 0, 0, 1, -2294.0, 0.0, -10.0, 1266.0, 0.0, -4.0}, - { 1, 1, 2, 0, 2, 2481.0, 0.0, -7.0, -1062.0, 0.0, -3.0}, - { 2, 0, 0, 0, 1, 2179.0, 0.0, -2.0, -1129.0, 0.0, -2.0}, - {-1, 1, 0, 1, 0, 3276.0, 0.0, 1.0, -9.0, 0.0, 0.0}, - { 1, 1, 0, 0, 0, -3389.0, 0.0, 5.0, 35.0, 0.0, -2.0}, - { 1, 0, 2, 0, 0, 3339.0, 0.0, -13.0, -107.0, 0.0, 1.0}, - {-1, 0, 2,-2, 1, -1987.0, 0.0, -6.0, 1073.0, 0.0, -2.0}, - { 1, 0, 0, 0, 2, -1981.0, 0.0, 0.0, 854.0, 0.0, 0.0}, - {-1, 0, 0, 1, 0, 4026.0, 0.0, -353.0, -553.0, 0.0, -139.0}, - { 0, 0, 2, 1, 2, 1660.0, 0.0, -5.0, -710.0, 0.0, -2.0}, - - /* 71-80 */ - {-1, 0, 2, 4, 2, -1521.0, 0.0, 9.0, 647.0, 0.0, 4.0}, - {-1, 1, 0, 1, 1, 1314.0, 0.0, 0.0, -700.0, 0.0, 0.0}, - { 0,-2, 2,-2, 1, -1283.0, 0.0, 0.0, 672.0, 0.0, 0.0}, - { 1, 0, 2, 2, 1, -1331.0, 0.0, 8.0, 663.0, 0.0, 4.0}, - {-2, 0, 2, 2, 2, 1383.0, 0.0, -2.0, -594.0, 0.0, -2.0}, - {-1, 0, 0, 0, 2, 1405.0, 0.0, 4.0, -610.0, 0.0, 2.0}, - { 1, 1, 2,-2, 2, 1290.0, 0.0, 0.0, -556.0, 0.0, 0.0}, - {-2, 0, 2, 4, 2, -1214.0, 0.0, 5.0, 518.0, 0.0, 2.0}, - {-1, 0, 4, 0, 2, 1146.0, 0.0, -3.0, -490.0, 0.0, -1.0}, - { 2, 0, 2,-2, 1, 1019.0, 0.0, -1.0, -527.0, 0.0, -1.0}, - - /* 81-90 */ - { 2, 0, 2, 2, 2, -1100.0, 0.0, 9.0, 465.0, 0.0, 4.0}, - { 1, 0, 0, 2, 1, -970.0, 0.0, 2.0, 496.0, 0.0, 1.0}, - { 3, 0, 0, 0, 0, 1575.0, 0.0, -6.0, -50.0, 0.0, 0.0}, - { 3, 0, 2,-2, 2, 934.0, 0.0, -3.0, -399.0, 0.0, -1.0}, - { 0, 0, 4,-2, 2, 922.0, 0.0, -1.0, -395.0, 0.0, -1.0}, - { 0, 1, 2, 0, 1, 815.0, 0.0, -1.0, -422.0, 0.0, -1.0}, - { 0, 0,-2, 2, 1, 834.0, 0.0, 2.0, -440.0, 0.0, 1.0}, - { 0, 0, 2,-2, 3, 1248.0, 0.0, 0.0, -170.0, 0.0, 1.0}, - {-1, 0, 0, 4, 0, 1338.0, 0.0, -5.0, -39.0, 0.0, 0.0}, - { 2, 0,-2, 0, 1, 716.0, 0.0, -2.0, -389.0, 0.0, -1.0}, - - /* 91-100 */ - {-2, 0, 0, 4, 0, 1282.0, 0.0, -3.0, -23.0, 0.0, 1.0}, - {-1,-1, 0, 2, 1, 742.0, 0.0, 1.0, -391.0, 0.0, 0.0}, - {-1, 0, 0, 1, 1, 1020.0, 0.0, -25.0, -495.0, 0.0, -10.0}, - { 0, 1, 0, 0, 2, 715.0, 0.0, -4.0, -326.0, 0.0, 2.0}, - { 0, 0,-2, 0, 1, -666.0, 0.0, -3.0, 369.0, 0.0, -1.0}, - { 0,-1, 2, 0, 1, -667.0, 0.0, 1.0, 346.0, 0.0, 1.0}, - { 0, 0, 2,-1, 2, -704.0, 0.0, 0.0, 304.0, 0.0, 0.0}, - { 0, 0, 2, 4, 2, -694.0, 0.0, 5.0, 294.0, 0.0, 2.0}, - {-2,-1, 0, 2, 0, -1014.0, 0.0, -1.0, 4.0, 0.0, -1.0}, - { 1, 1, 0,-2, 1, -585.0, 0.0, -2.0, 316.0, 0.0, -1.0}, - - /* 101-110 */ - {-1, 1, 0, 2, 0, -949.0, 0.0, 1.0, 8.0, 0.0, -1.0}, - {-1, 1, 0, 1, 2, -595.0, 0.0, 0.0, 258.0, 0.0, 0.0}, - { 1,-1, 0, 0, 1, 528.0, 0.0, 0.0, -279.0, 0.0, 0.0}, - { 1,-1, 2, 2, 2, -590.0, 0.0, 4.0, 252.0, 0.0, 2.0}, - {-1, 1, 2, 2, 2, 570.0, 0.0, -2.0, -244.0, 0.0, -1.0}, - { 3, 0, 2, 0, 1, -502.0, 0.0, 3.0, 250.0, 0.0, 2.0}, - { 0, 1,-2, 2, 0, -875.0, 0.0, 1.0, 29.0, 0.0, 0.0}, - {-1, 0, 0,-2, 1, -492.0, 0.0, -3.0, 275.0, 0.0, -1.0}, - { 0, 1, 2, 2, 2, 535.0, 0.0, -2.0, -228.0, 0.0, -1.0}, - {-1,-1, 2, 2, 1, -467.0, 0.0, 1.0, 240.0, 0.0, 1.0}, - - /* 111-120 */ - { 0,-1, 0, 0, 2, 591.0, 0.0, 0.0, -253.0, 0.0, 0.0}, - { 1, 0, 2,-4, 1, -453.0, 0.0, -1.0, 244.0, 0.0, -1.0}, - {-1, 0,-2, 2, 0, 766.0, 0.0, 1.0, 9.0, 0.0, 0.0}, - { 0,-1, 2, 2, 1, -446.0, 0.0, 2.0, 225.0, 0.0, 1.0}, - { 2,-1, 2, 0, 2, -488.0, 0.0, 2.0, 207.0, 0.0, 1.0}, - { 0, 0, 0, 2, 2, -468.0, 0.0, 0.0, 201.0, 0.0, 0.0}, - { 1,-1, 2, 0, 1, -421.0, 0.0, 1.0, 216.0, 0.0, 1.0}, - {-1, 1, 2, 0, 2, 463.0, 0.0, 0.0, -200.0, 0.0, 0.0}, - { 0, 1, 0, 2, 0, -673.0, 0.0, 2.0, 14.0, 0.0, 0.0}, - { 0,-1,-2, 2, 0, 658.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - - /* 121-130 */ - { 0, 3, 2,-2, 2, -438.0, 0.0, 0.0, 188.0, 0.0, 0.0}, - { 0, 0, 0, 1, 1, -390.0, 0.0, 0.0, 205.0, 0.0, 0.0}, - {-1, 0, 2, 2, 0, 639.0, -11.0, -2.0, -19.0, 0.0, 0.0}, - { 2, 1, 2, 0, 2, 412.0, 0.0, -2.0, -176.0, 0.0, -1.0}, - { 1, 1, 0, 0, 1, -361.0, 0.0, 0.0, 189.0, 0.0, 0.0}, - { 1, 1, 2, 0, 1, 360.0, 0.0, -1.0, -185.0, 0.0, -1.0}, - { 2, 0, 0, 2, 0, 588.0, 0.0, -3.0, -24.0, 0.0, 0.0}, - { 1, 0,-2, 2, 0, -578.0, 0.0, 1.0, 5.0, 0.0, 0.0}, - {-1, 0, 0, 2, 2, -396.0, 0.0, 0.0, 171.0, 0.0, 0.0}, - { 0, 1, 0, 1, 0, 565.0, 0.0, -1.0, -6.0, 0.0, 0.0}, - - /* 131-140 */ - { 0, 1, 0,-2, 1, -335.0, 0.0, -1.0, 184.0, 0.0, -1.0}, - {-1, 0, 2,-2, 2, 357.0, 0.0, 1.0, -154.0, 0.0, 0.0}, - { 0, 0, 0,-1, 1, 321.0, 0.0, 1.0, -174.0, 0.0, 0.0}, - {-1, 1, 0, 0, 1, -301.0, 0.0, -1.0, 162.0, 0.0, 0.0}, - { 1, 0, 2,-1, 2, -334.0, 0.0, 0.0, 144.0, 0.0, 0.0}, - { 1,-1, 0, 2, 0, 493.0, 0.0, -2.0, -15.0, 0.0, 0.0}, - { 0, 0, 0, 4, 0, 494.0, 0.0, -2.0, -19.0, 0.0, 0.0}, - { 1, 0, 2, 1, 2, 337.0, 0.0, -1.0, -143.0, 0.0, -1.0}, - { 0, 0, 2, 1, 1, 280.0, 0.0, -1.0, -144.0, 0.0, 0.0}, - { 1, 0, 0,-2, 2, 309.0, 0.0, 1.0, -134.0, 0.0, 0.0}, - - /* 141-150 */ - {-1, 0, 2, 4, 1, -263.0, 0.0, 2.0, 131.0, 0.0, 1.0}, - { 1, 0,-2, 0, 1, 253.0, 0.0, 1.0, -138.0, 0.0, 0.0}, - { 1, 1, 2,-2, 1, 245.0, 0.0, 0.0, -128.0, 0.0, 0.0}, - { 0, 0, 2, 2, 0, 416.0, 0.0, -2.0, -17.0, 0.0, 0.0}, - {-1, 0, 2,-1, 1, -229.0, 0.0, 0.0, 128.0, 0.0, 0.0}, - {-2, 0, 2, 2, 1, 231.0, 0.0, 0.0, -120.0, 0.0, 0.0}, - { 4, 0, 2, 0, 2, -259.0, 0.0, 2.0, 109.0, 0.0, 1.0}, - { 2,-1, 0, 0, 0, 375.0, 0.0, -1.0, -8.0, 0.0, 0.0}, - { 2, 1, 2,-2, 2, 252.0, 0.0, 0.0, -108.0, 0.0, 0.0}, - { 0, 1, 2, 1, 2, -245.0, 0.0, 1.0, 104.0, 0.0, 0.0}, - - /* 151-160 */ - { 1, 0, 4,-2, 2, 243.0, 0.0, -1.0, -104.0, 0.0, 0.0}, - {-1,-1, 0, 0, 1, 208.0, 0.0, 1.0, -112.0, 0.0, 0.0}, - { 0, 1, 0, 2, 1, 199.0, 0.0, 0.0, -102.0, 0.0, 0.0}, - {-2, 0, 2, 4, 1, -208.0, 0.0, 1.0, 105.0, 0.0, 0.0}, - { 2, 0, 2, 0, 0, 335.0, 0.0, -2.0, -14.0, 0.0, 0.0}, - { 1, 0, 0, 1, 0, -325.0, 0.0, 1.0, 7.0, 0.0, 0.0}, - {-1, 0, 0, 4, 1, -187.0, 0.0, 0.0, 96.0, 0.0, 0.0}, - {-1, 0, 4, 0, 1, 197.0, 0.0, -1.0, -100.0, 0.0, 0.0}, - { 2, 0, 2, 2, 1, -192.0, 0.0, 2.0, 94.0, 0.0, 1.0}, - { 0, 0, 2,-3, 2, -188.0, 0.0, 0.0, 83.0, 0.0, 0.0}, - - /* 161-170 */ - {-1,-2, 0, 2, 0, 276.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 2, 1, 0, 0, 0, -286.0, 0.0, 1.0, 6.0, 0.0, 0.0}, - { 0, 0, 4, 0, 2, 186.0, 0.0, -1.0, -79.0, 0.0, 0.0}, - { 0, 0, 0, 0, 3, -219.0, 0.0, 0.0, 43.0, 0.0, 0.0}, - { 0, 3, 0, 0, 0, 276.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 0, 0, 2,-4, 1, -153.0, 0.0, -1.0, 84.0, 0.0, 0.0}, - { 0,-1, 0, 2, 1, -156.0, 0.0, 0.0, 81.0, 0.0, 0.0}, - { 0, 0, 0, 4, 1, -154.0, 0.0, 1.0, 78.0, 0.0, 0.0}, - {-1,-1, 2, 4, 2, -174.0, 0.0, 1.0, 75.0, 0.0, 0.0}, - { 1, 0, 2, 4, 2, -163.0, 0.0, 2.0, 69.0, 0.0, 1.0}, - - /* 171-180 */ - {-2, 2, 0, 2, 0, -228.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - {-2,-1, 2, 0, 1, 91.0, 0.0, -4.0, -54.0, 0.0, -2.0}, - {-2, 0, 0, 2, 2, 175.0, 0.0, 0.0, -75.0, 0.0, 0.0}, - {-1,-1, 2, 0, 2, -159.0, 0.0, 0.0, 69.0, 0.0, 0.0}, - { 0, 0, 4,-2, 1, 141.0, 0.0, 0.0, -72.0, 0.0, 0.0}, - { 3, 0, 2,-2, 1, 147.0, 0.0, 0.0, -75.0, 0.0, 0.0}, - {-2,-1, 0, 2, 1, -132.0, 0.0, 0.0, 69.0, 0.0, 0.0}, - { 1, 0, 0,-1, 1, 159.0, 0.0, -28.0, -54.0, 0.0, 11.0}, - { 0,-2, 0, 2, 0, 213.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - {-2, 0, 0, 4, 1, 123.0, 0.0, 0.0, -64.0, 0.0, 0.0}, - - /* 181-190 */ - {-3, 0, 0, 0, 1, -118.0, 0.0, -1.0, 66.0, 0.0, 0.0}, - { 1, 1, 2, 2, 2, 144.0, 0.0, -1.0, -61.0, 0.0, 0.0}, - { 0, 0, 2, 4, 1, -121.0, 0.0, 1.0, 60.0, 0.0, 0.0}, - { 3, 0, 2, 2, 2, -134.0, 0.0, 1.0, 56.0, 0.0, 1.0}, - {-1, 1, 2,-2, 1, -105.0, 0.0, 0.0, 57.0, 0.0, 0.0}, - { 2, 0, 0,-4, 1, -102.0, 0.0, 0.0, 56.0, 0.0, 0.0}, - { 0, 0, 0,-2, 2, 120.0, 0.0, 0.0, -52.0, 0.0, 0.0}, - { 2, 0, 2,-4, 1, 101.0, 0.0, 0.0, -54.0, 0.0, 0.0}, - {-1, 1, 0, 2, 1, -113.0, 0.0, 0.0, 59.0, 0.0, 0.0}, - { 0, 0, 2,-1, 1, -106.0, 0.0, 0.0, 61.0, 0.0, 0.0}, - - /* 191-200 */ - { 0,-2, 2, 2, 2, -129.0, 0.0, 1.0, 55.0, 0.0, 0.0}, - { 2, 0, 0, 2, 1, -114.0, 0.0, 0.0, 57.0, 0.0, 0.0}, - { 4, 0, 2,-2, 2, 113.0, 0.0, -1.0, -49.0, 0.0, 0.0}, - { 2, 0, 0,-2, 2, -102.0, 0.0, 0.0, 44.0, 0.0, 0.0}, - { 0, 2, 0, 0, 1, -94.0, 0.0, 0.0, 51.0, 0.0, 0.0}, - { 1, 0, 0,-4, 1, -100.0, 0.0, -1.0, 56.0, 0.0, 0.0}, - { 0, 2, 2,-2, 1, 87.0, 0.0, 0.0, -47.0, 0.0, 0.0}, - {-3, 0, 0, 4, 0, 161.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-1, 1, 2, 0, 1, 96.0, 0.0, 0.0, -50.0, 0.0, 0.0}, - {-1,-1, 0, 4, 0, 151.0, 0.0, -1.0, -5.0, 0.0, 0.0}, - - /* 201-210 */ - {-1,-2, 2, 2, 2, -104.0, 0.0, 0.0, 44.0, 0.0, 0.0}, - {-2,-1, 2, 4, 2, -110.0, 0.0, 0.0, 48.0, 0.0, 0.0}, - { 1,-1, 2, 2, 1, -100.0, 0.0, 1.0, 50.0, 0.0, 0.0}, - {-2, 1, 0, 2, 0, 92.0, 0.0, -5.0, 12.0, 0.0, -2.0}, - {-2, 1, 2, 0, 1, 82.0, 0.0, 0.0, -45.0, 0.0, 0.0}, - { 2, 1, 0,-2, 1, 82.0, 0.0, 0.0, -45.0, 0.0, 0.0}, - {-3, 0, 2, 0, 1, -78.0, 0.0, 0.0, 41.0, 0.0, 0.0}, - {-2, 0, 2,-2, 1, -77.0, 0.0, 0.0, 43.0, 0.0, 0.0}, - {-1, 1, 0, 2, 2, 2.0, 0.0, 0.0, 54.0, 0.0, 0.0}, - { 0,-1, 2,-1, 2, 94.0, 0.0, 0.0, -40.0, 0.0, 0.0}, - - /* 211-220 */ - {-1, 0, 4,-2, 2, -93.0, 0.0, 0.0, 40.0, 0.0, 0.0}, - { 0,-2, 2, 0, 2, -83.0, 0.0, 10.0, 40.0, 0.0, -2.0}, - {-1, 0, 2, 1, 2, 83.0, 0.0, 0.0, -36.0, 0.0, 0.0}, - { 2, 0, 0, 0, 2, -91.0, 0.0, 0.0, 39.0, 0.0, 0.0}, - { 0, 0, 2, 0, 3, 128.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-2, 0, 4, 0, 2, -79.0, 0.0, 0.0, 34.0, 0.0, 0.0}, - {-1, 0,-2, 0, 1, -83.0, 0.0, 0.0, 47.0, 0.0, 0.0}, - {-1, 1, 2, 2, 1, 84.0, 0.0, 0.0, -44.0, 0.0, 0.0}, - { 3, 0, 0, 0, 1, 83.0, 0.0, 0.0, -43.0, 0.0, 0.0}, - {-1, 0, 2, 3, 2, 91.0, 0.0, 0.0, -39.0, 0.0, 0.0}, - - /* 221-230 */ - { 2,-1, 2, 0, 1, -77.0, 0.0, 0.0, 39.0, 0.0, 0.0}, - { 0, 1, 2, 2, 1, 84.0, 0.0, 0.0, -43.0, 0.0, 0.0}, - { 0,-1, 2, 4, 2, -92.0, 0.0, 1.0, 39.0, 0.0, 0.0}, - { 2,-1, 2, 2, 2, -92.0, 0.0, 1.0, 39.0, 0.0, 0.0}, - { 0, 2,-2, 2, 0, -94.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-1, 2,-1, 1, 68.0, 0.0, 0.0, -36.0, 0.0, 0.0}, - { 0,-2, 0, 0, 1, -61.0, 0.0, 0.0, 32.0, 0.0, 0.0}, - { 1, 0, 2,-4, 2, 71.0, 0.0, 0.0, -31.0, 0.0, 0.0}, - { 1,-1, 0,-2, 1, 62.0, 0.0, 0.0, -34.0, 0.0, 0.0}, - {-1,-1, 2, 0, 1, -63.0, 0.0, 0.0, 33.0, 0.0, 0.0}, - - /* 231-240 */ - { 1,-1, 2,-2, 2, -73.0, 0.0, 0.0, 32.0, 0.0, 0.0}, - {-2,-1, 0, 4, 0, 115.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-1, 0, 0, 3, 0, -103.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-2,-1, 2, 2, 2, 63.0, 0.0, 0.0, -28.0, 0.0, 0.0}, - { 0, 2, 2, 0, 2, 74.0, 0.0, 0.0, -32.0, 0.0, 0.0}, - { 1, 1, 0, 2, 0, -103.0, 0.0, -3.0, 3.0, 0.0, -1.0}, - { 2, 0, 2,-1, 2, -69.0, 0.0, 0.0, 30.0, 0.0, 0.0}, - { 1, 0, 2, 1, 1, 57.0, 0.0, 0.0, -29.0, 0.0, 0.0}, - { 4, 0, 0, 0, 0, 94.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - { 2, 1, 2, 0, 1, 64.0, 0.0, 0.0, -33.0, 0.0, 0.0}, - - /* 241-250 */ - { 3,-1, 2, 0, 2, -63.0, 0.0, 0.0, 26.0, 0.0, 0.0}, - {-2, 2, 0, 2, 1, -38.0, 0.0, 0.0, 20.0, 0.0, 0.0}, - { 1, 0, 2,-3, 1, -43.0, 0.0, 0.0, 24.0, 0.0, 0.0}, - { 1, 1, 2,-4, 1, -45.0, 0.0, 0.0, 23.0, 0.0, 0.0}, - {-1,-1, 2,-2, 1, 47.0, 0.0, 0.0, -24.0, 0.0, 0.0}, - { 0,-1, 0,-1, 1, -48.0, 0.0, 0.0, 25.0, 0.0, 0.0}, - { 0,-1, 0,-2, 1, 45.0, 0.0, 0.0, -26.0, 0.0, 0.0}, - {-2, 0, 0, 0, 2, 56.0, 0.0, 0.0, -25.0, 0.0, 0.0}, - {-2, 0,-2, 2, 0, 88.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-1, 0,-2, 4, 0, -75.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 251-260 */ - { 1,-2, 0, 0, 0, 85.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 1, 0, 1, 1, 49.0, 0.0, 0.0, -26.0, 0.0, 0.0}, - {-1, 2, 0, 2, 0, -74.0, 0.0, -3.0, -1.0, 0.0, -1.0}, - { 1,-1, 2,-2, 1, -39.0, 0.0, 0.0, 21.0, 0.0, 0.0}, - { 1, 2, 2,-2, 2, 45.0, 0.0, 0.0, -20.0, 0.0, 0.0}, - { 2,-1, 2,-2, 2, 51.0, 0.0, 0.0, -22.0, 0.0, 0.0}, - { 1, 0, 2,-1, 1, -40.0, 0.0, 0.0, 21.0, 0.0, 0.0}, - { 2, 1, 2,-2, 1, 41.0, 0.0, 0.0, -21.0, 0.0, 0.0}, - {-2, 0, 0,-2, 1, -42.0, 0.0, 0.0, 24.0, 0.0, 0.0}, - { 1,-2, 2, 0, 2, -51.0, 0.0, 0.0, 22.0, 0.0, 0.0}, - - /* 261-270 */ - { 0, 1, 2, 1, 1, -42.0, 0.0, 0.0, 22.0, 0.0, 0.0}, - { 1, 0, 4,-2, 1, 39.0, 0.0, 0.0, -21.0, 0.0, 0.0}, - {-2, 0, 4, 2, 2, 46.0, 0.0, 0.0, -18.0, 0.0, 0.0}, - { 1, 1, 2, 1, 2, -53.0, 0.0, 0.0, 22.0, 0.0, 0.0}, - { 1, 0, 0, 4, 0, 82.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - { 1, 0, 2, 2, 0, 81.0, 0.0, -1.0, -4.0, 0.0, 0.0}, - { 2, 0, 2, 1, 2, 47.0, 0.0, 0.0, -19.0, 0.0, 0.0}, - { 3, 1, 2, 0, 2, 53.0, 0.0, 0.0, -23.0, 0.0, 0.0}, - { 4, 0, 2, 0, 1, -45.0, 0.0, 0.0, 22.0, 0.0, 0.0}, - {-2,-1, 2, 0, 0, -44.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - - /* 271-280 */ - { 0, 1,-2, 2, 1, -33.0, 0.0, 0.0, 16.0, 0.0, 0.0}, - { 1, 0,-2, 1, 0, -61.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 0,-1,-2, 2, 1, 28.0, 0.0, 0.0, -15.0, 0.0, 0.0}, - { 2,-1, 0,-2, 1, -38.0, 0.0, 0.0, 19.0, 0.0, 0.0}, - {-1, 0, 2,-1, 2, -33.0, 0.0, 0.0, 21.0, 0.0, 0.0}, - { 1, 0, 2,-3, 2, -60.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 1, 2,-2, 3, 48.0, 0.0, 0.0, -10.0, 0.0, 0.0}, - { 0, 0, 2,-3, 1, 27.0, 0.0, 0.0, -14.0, 0.0, 0.0}, - {-1, 0,-2, 2, 1, 38.0, 0.0, 0.0, -20.0, 0.0, 0.0}, - { 0, 0, 2,-4, 2, 31.0, 0.0, 0.0, -13.0, 0.0, 0.0}, - - /* 281-290 */ - {-2, 1, 0, 0, 1, -29.0, 0.0, 0.0, 15.0, 0.0, 0.0}, - {-1, 0, 0,-1, 1, 28.0, 0.0, 0.0, -15.0, 0.0, 0.0}, - { 2, 0, 2,-4, 2, -32.0, 0.0, 0.0, 15.0, 0.0, 0.0}, - { 0, 0, 4,-4, 4, 45.0, 0.0, 0.0, -8.0, 0.0, 0.0}, - { 0, 0, 4,-4, 2, -44.0, 0.0, 0.0, 19.0, 0.0, 0.0}, - {-1,-2, 0, 2, 1, 28.0, 0.0, 0.0, -15.0, 0.0, 0.0}, - {-2, 0, 0, 3, 0, -51.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 0,-2, 2, 1, -36.0, 0.0, 0.0, 20.0, 0.0, 0.0}, - {-3, 0, 2, 2, 2, 44.0, 0.0, 0.0, -19.0, 0.0, 0.0}, - {-3, 0, 2, 2, 1, 26.0, 0.0, 0.0, -14.0, 0.0, 0.0}, - - /* 291-300 */ - {-2, 0, 2, 2, 0, -60.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 2,-1, 0, 0, 1, 35.0, 0.0, 0.0, -18.0, 0.0, 0.0}, - {-2, 1, 2, 2, 2, -27.0, 0.0, 0.0, 11.0, 0.0, 0.0}, - { 1, 1, 0, 1, 0, 47.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 0, 1, 4,-2, 2, 36.0, 0.0, 0.0, -15.0, 0.0, 0.0}, - {-1, 1, 0,-2, 1, -36.0, 0.0, 0.0, 20.0, 0.0, 0.0}, - { 0, 0, 0,-4, 1, -35.0, 0.0, 0.0, 19.0, 0.0, 0.0}, - { 1,-1, 0, 2, 1, -37.0, 0.0, 0.0, 19.0, 0.0, 0.0}, - { 1, 1, 0, 2, 1, 32.0, 0.0, 0.0, -16.0, 0.0, 0.0}, - {-1, 2, 2, 2, 2, 35.0, 0.0, 0.0, -14.0, 0.0, 0.0}, - - /* 301-310 */ - { 3, 1, 2,-2, 2, 32.0, 0.0, 0.0, -13.0, 0.0, 0.0}, - { 0,-1, 0, 4, 0, 65.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 2,-1, 0, 2, 0, 47.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 0, 0, 4, 0, 1, 32.0, 0.0, 0.0, -16.0, 0.0, 0.0}, - { 2, 0, 4,-2, 2, 37.0, 0.0, 0.0, -16.0, 0.0, 0.0}, - {-1,-1, 2, 4, 1, -30.0, 0.0, 0.0, 15.0, 0.0, 0.0}, - { 1, 0, 0, 4, 1, -32.0, 0.0, 0.0, 16.0, 0.0, 0.0}, - { 1,-2, 2, 2, 2, -31.0, 0.0, 0.0, 13.0, 0.0, 0.0}, - { 0, 0, 2, 3, 2, 37.0, 0.0, 0.0, -16.0, 0.0, 0.0}, - {-1, 1, 2, 4, 2, 31.0, 0.0, 0.0, -13.0, 0.0, 0.0}, - - /* 311-320 */ - { 3, 0, 0, 2, 0, 49.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-1, 0, 4, 2, 2, 32.0, 0.0, 0.0, -13.0, 0.0, 0.0}, - { 1, 1, 2, 2, 1, 23.0, 0.0, 0.0, -12.0, 0.0, 0.0}, - {-2, 0, 2, 6, 2, -43.0, 0.0, 0.0, 18.0, 0.0, 0.0}, - { 2, 1, 2, 2, 2, 26.0, 0.0, 0.0, -11.0, 0.0, 0.0}, - {-1, 0, 2, 6, 2, -32.0, 0.0, 0.0, 14.0, 0.0, 0.0}, - { 1, 0, 2, 4, 1, -29.0, 0.0, 0.0, 14.0, 0.0, 0.0}, - { 2, 0, 2, 4, 2, -27.0, 0.0, 0.0, 12.0, 0.0, 0.0}, - { 1, 1,-2, 1, 0, 30.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-3, 1, 2, 1, 2, -11.0, 0.0, 0.0, 5.0, 0.0, 0.0}, - - /* 321-330 */ - { 2, 0,-2, 0, 2, -21.0, 0.0, 0.0, 10.0, 0.0, 0.0}, - {-1, 0, 0, 1, 2, -34.0, 0.0, 0.0, 15.0, 0.0, 0.0}, - {-4, 0, 2, 2, 1, -10.0, 0.0, 0.0, 6.0, 0.0, 0.0}, - {-1,-1, 0, 1, 0, -36.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 0,-2, 2, 2, -9.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - { 1, 0, 0,-1, 2, -12.0, 0.0, 0.0, 5.0, 0.0, 0.0}, - { 0,-1, 2,-2, 3, -21.0, 0.0, 0.0, 5.0, 0.0, 0.0}, - {-2, 1, 2, 0, 0, -29.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 0, 0, 2,-2, 4, -15.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - {-2,-2, 0, 2, 0, -20.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 331-340 */ - {-2, 0,-2, 4, 0, 28.0, 0.0, 0.0, 0.0, 0.0, -2.0}, - { 0,-2,-2, 2, 0, 17.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 2, 0,-2, 1, -22.0, 0.0, 0.0, 12.0, 0.0, 0.0}, - { 3, 0, 0,-4, 1, -14.0, 0.0, 0.0, 7.0, 0.0, 0.0}, - {-1, 1, 2,-2, 2, 24.0, 0.0, 0.0, -11.0, 0.0, 0.0}, - { 1,-1, 2,-4, 1, 11.0, 0.0, 0.0, -6.0, 0.0, 0.0}, - { 1, 1, 0,-2, 2, 14.0, 0.0, 0.0, -6.0, 0.0, 0.0}, - {-3, 0, 2, 0, 0, 24.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-3, 0, 2, 0, 2, 18.0, 0.0, 0.0, -8.0, 0.0, 0.0}, - {-2, 0, 0, 1, 0, -38.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 341-350 */ - { 0, 0,-2, 1, 0, -31.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-3, 0, 0, 2, 1, -16.0, 0.0, 0.0, 8.0, 0.0, 0.0}, - {-1,-1,-2, 2, 0, 29.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 1, 2,-4, 1, -18.0, 0.0, 0.0, 10.0, 0.0, 0.0}, - { 2, 1, 0,-4, 1, -10.0, 0.0, 0.0, 5.0, 0.0, 0.0}, - { 0, 2, 0,-2, 1, -17.0, 0.0, 0.0, 10.0, 0.0, 0.0}, - { 1, 0, 0,-3, 1, 9.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - {-2, 0, 2,-2, 2, 16.0, 0.0, 0.0, -6.0, 0.0, 0.0}, - {-2,-1, 0, 0, 1, 22.0, 0.0, 0.0, -12.0, 0.0, 0.0}, - {-4, 0, 0, 2, 0, 20.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 351-360 */ - { 1, 1, 0,-4, 1, -13.0, 0.0, 0.0, 6.0, 0.0, 0.0}, - {-1, 0, 2,-4, 1, -17.0, 0.0, 0.0, 9.0, 0.0, 0.0}, - { 0, 0, 4,-4, 1, -14.0, 0.0, 0.0, 8.0, 0.0, 0.0}, - { 0, 3, 2,-2, 2, 0.0, 0.0, 0.0, -7.0, 0.0, 0.0}, - {-3,-1, 0, 4, 0, 14.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-3, 0, 0, 4, 1, 19.0, 0.0, 0.0, -10.0, 0.0, 0.0}, - { 1,-1,-2, 2, 0, -34.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-1, 0, 2, 2, -20.0, 0.0, 0.0, 8.0, 0.0, 0.0}, - { 1,-2, 0, 0, 1, 9.0, 0.0, 0.0, -5.0, 0.0, 0.0}, - { 1,-1, 0, 0, 2, -18.0, 0.0, 0.0, 7.0, 0.0, 0.0}, - - /* 361-370 */ - { 0, 0, 0, 1, 2, 13.0, 0.0, 0.0, -6.0, 0.0, 0.0}, - {-1,-1, 2, 0, 0, 17.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1,-2, 2,-2, 2, -12.0, 0.0, 0.0, 5.0, 0.0, 0.0}, - { 0,-1, 2,-1, 1, 15.0, 0.0, 0.0, -8.0, 0.0, 0.0}, - {-1, 0, 2, 0, 3, -11.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - { 1, 1, 0, 0, 2, 13.0, 0.0, 0.0, -5.0, 0.0, 0.0}, - {-1, 1, 2, 0, 0, -18.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 2, 0, 0, 0, -35.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 2, 2, 0, 2, 9.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - {-1, 0, 4,-2, 1, -19.0, 0.0, 0.0, 10.0, 0.0, 0.0}, - - /* 371-380 */ - { 3, 0, 2,-4, 2, -26.0, 0.0, 0.0, 11.0, 0.0, 0.0}, - { 1, 2, 2,-2, 1, 8.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - { 1, 0, 4,-4, 2, -10.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - {-2,-1, 0, 4, 1, 10.0, 0.0, 0.0, -6.0, 0.0, 0.0}, - { 0,-1, 0, 2, 2, -21.0, 0.0, 0.0, 9.0, 0.0, 0.0}, - {-2, 1, 0, 4, 0, -15.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-2,-1, 2, 2, 1, 9.0, 0.0, 0.0, -5.0, 0.0, 0.0}, - { 2, 0,-2, 2, 0, -29.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 0, 0, 1, 1, -19.0, 0.0, 0.0, 10.0, 0.0, 0.0}, - { 0, 1, 0, 2, 2, 12.0, 0.0, 0.0, -5.0, 0.0, 0.0}, - - /* 381-390 */ - { 1,-1, 2,-1, 2, 22.0, 0.0, 0.0, -9.0, 0.0, 0.0}, - {-2, 0, 4, 0, 1, -10.0, 0.0, 0.0, 5.0, 0.0, 0.0}, - { 2, 1, 0, 0, 1, -20.0, 0.0, 0.0, 11.0, 0.0, 0.0}, - { 0, 1, 2, 0, 0, -20.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0,-1, 4,-2, 2, -17.0, 0.0, 0.0, 7.0, 0.0, 0.0}, - { 0, 0, 4,-2, 4, 15.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 0, 2, 2, 0, 1, 8.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - {-3, 0, 0, 6, 0, 14.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-1, 0, 4, 1, -12.0, 0.0, 0.0, 6.0, 0.0, 0.0}, - { 1,-2, 0, 2, 0, 25.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 391-400 */ - {-1, 0, 0, 4, 2, -13.0, 0.0, 0.0, 6.0, 0.0, 0.0}, - {-1,-2, 2, 2, 1, -14.0, 0.0, 0.0, 8.0, 0.0, 0.0}, - {-1, 0, 0,-2, 2, 13.0, 0.0, 0.0, -5.0, 0.0, 0.0}, - { 1, 0,-2,-2, 1, -17.0, 0.0, 0.0, 9.0, 0.0, 0.0}, - { 0, 0,-2,-2, 1, -12.0, 0.0, 0.0, 6.0, 0.0, 0.0}, - {-2, 0,-2, 0, 1, -10.0, 0.0, 0.0, 5.0, 0.0, 0.0}, - { 0, 0, 0, 3, 1, 10.0, 0.0, 0.0, -6.0, 0.0, 0.0}, - { 0, 0, 0, 3, 0, -15.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 1, 0, 4, 0, -22.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-1, 2, 2, 0, 28.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - - /* 401-410 */ - {-2, 0, 2, 3, 2, 15.0, 0.0, 0.0, -7.0, 0.0, 0.0}, - { 1, 0, 0, 2, 2, 23.0, 0.0, 0.0, -10.0, 0.0, 0.0}, - { 0,-1, 2, 1, 2, 12.0, 0.0, 0.0, -5.0, 0.0, 0.0}, - { 3,-1, 0, 0, 0, 29.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 2, 0, 0, 1, 0, -25.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 1,-1, 2, 0, 0, 22.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 0, 2, 1, 0, -18.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 0, 2, 0, 3, 15.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - { 3, 1, 0, 0, 0, -23.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 3,-1, 2,-2, 2, 12.0, 0.0, 0.0, -5.0, 0.0, 0.0}, - - /* 411-420 */ - { 2, 0, 2,-1, 1, -8.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - { 1, 1, 2, 0, 0, -19.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 0, 4,-1, 2, -10.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - { 1, 2, 2, 0, 2, 21.0, 0.0, 0.0, -9.0, 0.0, 0.0}, - {-2, 0, 0, 6, 0, 23.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 0,-1, 0, 4, 1, -16.0, 0.0, 0.0, 8.0, 0.0, 0.0}, - {-2,-1, 2, 4, 1, -19.0, 0.0, 0.0, 9.0, 0.0, 0.0}, - { 0,-2, 2, 2, 1, -22.0, 0.0, 0.0, 10.0, 0.0, 0.0}, - { 0,-1, 2, 2, 0, 27.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-1, 0, 2, 3, 1, 16.0, 0.0, 0.0, -8.0, 0.0, 0.0}, - - /* 421-430 */ - {-2, 1, 2, 4, 2, 19.0, 0.0, 0.0, -8.0, 0.0, 0.0}, - { 2, 0, 0, 2, 2, 9.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - { 2,-2, 2, 0, 2, -9.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - {-1, 1, 2, 3, 2, -9.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - { 3, 0, 2,-1, 2, -8.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - { 4, 0, 2,-2, 1, 18.0, 0.0, 0.0, -9.0, 0.0, 0.0}, - {-1, 0, 0, 6, 0, 16.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-1,-2, 2, 4, 2, -10.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - {-3, 0, 2, 6, 2, -23.0, 0.0, 0.0, 9.0, 0.0, 0.0}, - {-1, 0, 2, 4, 0, 16.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - - /* 431-440 */ - { 3, 0, 0, 2, 1, -12.0, 0.0, 0.0, 6.0, 0.0, 0.0}, - { 3,-1, 2, 0, 1, -8.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - { 3, 0, 2, 0, 0, 30.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 1, 0, 4, 0, 2, 24.0, 0.0, 0.0, -10.0, 0.0, 0.0}, - { 5, 0, 2,-2, 2, 10.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - { 0,-1, 2, 4, 1, -16.0, 0.0, 0.0, 7.0, 0.0, 0.0}, - { 2,-1, 2, 2, 1, -16.0, 0.0, 0.0, 7.0, 0.0, 0.0}, - { 0, 1, 2, 4, 2, 17.0, 0.0, 0.0, -7.0, 0.0, 0.0}, - { 1,-1, 2, 4, 2, -24.0, 0.0, 0.0, 10.0, 0.0, 0.0}, - { 3,-1, 2, 2, 2, -12.0, 0.0, 0.0, 5.0, 0.0, 0.0}, - - /* 441-450 */ - { 3, 0, 2, 2, 1, -24.0, 0.0, 0.0, 11.0, 0.0, 0.0}, - { 5, 0, 2, 0, 2, -23.0, 0.0, 0.0, 9.0, 0.0, 0.0}, - { 0, 0, 2, 6, 2, -13.0, 0.0, 0.0, 5.0, 0.0, 0.0}, - { 4, 0, 2, 2, 2, -15.0, 0.0, 0.0, 7.0, 0.0, 0.0}, - { 0,-1, 1,-1, 1, 0.0, 0.0,-1988.0, 0.0, 0.0,-1679.0}, - {-1, 0, 1, 0, 3, 0.0, 0.0, -63.0, 0.0, 0.0, -27.0}, - { 0,-2, 2,-2, 3, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 0,-1, 0, 1, 0.0, 0.0, 5.0, 0.0, 0.0, 4.0}, - { 2,-2, 0,-2, 1, 5.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - {-1, 0, 1, 0, 2, 0.0, 0.0, 364.0, 0.0, 0.0, 176.0}, - - /* 451-460 */ - {-1, 0, 1, 0, 1, 0.0, 0.0,-1044.0, 0.0, 0.0, -891.0}, - {-1,-1, 2,-1, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - {-2, 2, 0, 2, 2, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-1, 0, 1, 0, 0, 0.0, 0.0, 330.0, 0.0, 0.0, 0.0}, - {-4, 1, 2, 2, 2, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-3, 0, 2, 1, 1, 3.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-2,-1, 2, 0, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 1, 0,-2, 1, 1, -5.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 2,-1,-2, 0, 1, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-4, 0, 2, 2, 0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 461-470 */ - {-3, 1, 0, 3, 0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 0,-1, 2, 0, 0.0, 0.0, 5.0, 0.0, 0.0, 0.0}, - { 0,-2, 0, 0, 2, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 0,-2, 0, 0, 2, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-3, 0, 0, 3, 0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-2,-1, 0, 2, 2, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-1, 0,-2, 3, 0, -7.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-4, 0, 0, 4, 0, -12.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2, 1,-2, 0, 1, 5.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 2,-1, 0,-2, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - - /* 471-480 */ - { 0, 0, 1,-1, 0, -5.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 2, 0, 1, 0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-2, 1, 2, 0, 2, -7.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - { 1, 1, 0,-1, 1, 7.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - { 1, 0, 1,-2, 1, 0.0, 0.0, -12.0, 0.0, 0.0, -10.0}, - { 0, 2, 0, 0, 2, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 1,-1, 2,-3, 1, 3.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-1, 1, 2,-1, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-2, 0, 4,-2, 2, -7.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - {-2, 0, 4,-2, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - - /* 481-490 */ - {-2,-2, 0, 2, 1, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - {-2, 0,-2, 4, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 2, 2,-4, 1, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 1, 1, 2,-4, 2, 7.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - {-1, 2, 2,-2, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 2, 0, 0,-3, 1, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-1, 2, 0, 0, 1, -5.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - { 0, 0, 0,-2, 0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-1, 2,-2, 2, -5.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-1, 1, 0, 0, 2, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - - /* 491-500 */ - { 0, 0, 0,-1, 2, -8.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - {-2, 1, 0, 1, 0, 9.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1,-2, 0,-2, 1, 6.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 1, 0,-2, 0, 2, -5.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-3, 1, 0, 2, 0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 1,-2, 2, 0, -7.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-1, 0, 0, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - {-3, 0, 0, 2, 0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-3,-1, 0, 2, 0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2, 0, 2,-6, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - - /* 501-510 */ - { 0, 1, 2,-4, 2, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 2, 0, 0,-4, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-2, 1, 2,-2, 1, -5.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 0,-1, 2,-4, 1, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 0, 1, 0,-2, 2, 9.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - {-1, 0, 0,-2, 0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2, 0,-2,-2, 1, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-4, 0, 2, 0, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-1,-1, 0,-1, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 0, 0,-2, 0, 2, 9.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - - /* 511-520 */ - {-3, 0, 0, 1, 0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 0,-2, 1, 0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-2, 0,-2, 2, 1, 3.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 0, 0,-4, 2, 0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-2,-1,-2, 2, 0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 0, 2,-6, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-1, 0, 2,-4, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 1, 0, 0,-4, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 2, 1, 2,-4, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 2, 1, 2,-4, 1, 6.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - - /* 521-530 */ - { 0, 1, 4,-4, 4, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 1, 4,-4, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - {-1,-1,-2, 4, 0, -7.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-3, 0, 2, 0, 9.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 0,-2, 4, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-2,-1, 0, 3, 0, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 0,-2, 3, 0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-2, 0, 0, 3, 1, -5.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - { 0,-1, 0, 1, 0, -13.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-3, 0, 2, 2, 0, -7.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 531-540 */ - { 1, 1,-2, 2, 0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 1, 0, 2, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 1,-2, 2,-2, 1, 10.0, 0.0, 13.0, 6.0, 0.0, -5.0}, - { 0, 0, 1, 0, 2, 0.0, 0.0, 30.0, 0.0, 0.0, 14.0}, - { 0, 0, 1, 0, 1, 0.0, 0.0, -162.0, 0.0, 0.0, -138.0}, - { 0, 0, 1, 0, 0, 0.0, 0.0, 75.0, 0.0, 0.0, 0.0}, - {-1, 2, 0, 2, 1, -7.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - { 0, 0, 2, 0, 2, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-2, 0, 2, 0, 2, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 2, 0, 0,-1, 1, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - - /* 541-550 */ - { 3, 0, 0,-2, 1, 5.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 1, 0, 2,-2, 3, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 2, 0, 0, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 2, 0, 2,-3, 2, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-1, 1, 4,-2, 2, -5.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-2,-2, 0, 4, 0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0,-3, 0, 2, 0, 9.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 0,-2, 4, 0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-1, 0, 3, 0, -7.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-2, 0, 0, 4, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - - /* 551-560 */ - {-1, 0, 0, 3, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 2,-2, 0, 0, 0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1,-1, 0, 1, 0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 0, 0, 2, 0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0,-2, 2, 0, 1, -6.0, 0.0, -3.0, 3.0, 0.0, 1.0}, - {-1, 0, 1, 2, 1, 0.0, 0.0, -3.0, 0.0, 0.0, -2.0}, - {-1, 1, 0, 3, 0, 11.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-1, 2, 1, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 0,-1, 2, 0, 0, 11.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-2, 1, 2, 2, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - - /* 561-570 */ - { 2,-2, 2,-2, 2, -1.0, 0.0, 3.0, 3.0, 0.0, -1.0}, - { 1, 1, 0, 1, 1, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 1, 0, 1, 0, 1, 0.0, 0.0, -13.0, 0.0, 0.0, -11.0}, - { 1, 0, 1, 0, 0, 3.0, 0.0, 6.0, 0.0, 0.0, 0.0}, - { 0, 2, 0, 2, 0, -7.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2,-1, 2,-2, 1, 5.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 0,-1, 4,-2, 1, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 0, 0, 4,-2, 3, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 1, 4,-2, 1, 5.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 4, 0, 2,-4, 2, -7.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - - /* 571-580 */ - { 2, 2, 2,-2, 2, 8.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 2, 0, 4,-4, 2, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-1,-2, 0, 4, 0, 11.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1,-3, 2, 2, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - {-3, 0, 2, 4, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-3, 0, 2,-2, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-1,-1, 0,-2, 1, 8.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - {-3, 0, 0, 0, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-3, 0,-2, 2, 0, 11.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 1, 0,-4, 1, -6.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - - /* 581-590 */ - {-2, 1, 0,-2, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-4, 0, 0, 0, 1, -8.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - {-1, 0, 0,-4, 1, -7.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - {-3, 0, 0,-2, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 0, 0, 0, 3, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-1, 1, 0, 4, 1, 6.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 1,-2, 2, 0, 1, -6.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - { 0, 1, 0, 3, 0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-1, 0, 2, 2, 3, 6.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 0, 0, 2, 2, 2, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - - /* 591-600 */ - {-2, 0, 2, 2, 2, -5.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-1, 1, 2, 2, 0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 3, 0, 0, 0, 2, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 2, 1, 0, 1, 0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2,-1, 2,-1, 2, 6.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 0, 0, 2, 0, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 0, 0, 3, 0, 3, 0.0, 0.0, -26.0, 0.0, 0.0, -11.0}, - { 0, 0, 3, 0, 2, 0.0, 0.0, -10.0, 0.0, 0.0, -5.0}, - {-1, 2, 2, 2, 1, 5.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - {-1, 0, 4, 0, 0, -13.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 601-610 */ - { 1, 2, 2, 0, 1, 3.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 3, 1, 2,-2, 1, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 1, 1, 4,-2, 2, 7.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - {-2,-1, 0, 6, 0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0,-2, 0, 4, 0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-2, 0, 0, 6, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-2,-2, 2, 4, 2, -6.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 0,-3, 2, 2, 2, -5.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 0, 0, 0, 4, 2, -7.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - {-1,-1, 2, 3, 2, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - - /* 611-620 */ - {-2, 0, 2, 4, 0, 13.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2,-1, 0, 2, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 1, 0, 0, 3, 0, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 1, 0, 4, 1, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 0, 1, 0, 4, 0, -11.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1,-1, 2, 1, 2, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 0, 0, 2, 2, 3, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 0, 2, 2, 2, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-1, 0, 2, 2, 2, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-2, 0, 4, 2, 1, 6.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - - /* 621-630 */ - { 2, 1, 0, 2, 1, 3.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 2, 1, 0, 2, 0, -12.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2,-1, 2, 0, 0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 0, 2, 1, 0, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 1, 2, 2, 0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2, 0, 2, 0, 3, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 3, 0, 2, 0, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 1, 0, 2, 0, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 1, 0, 3, 0, 3, 0.0, 0.0, -5.0, 0.0, 0.0, -2.0}, - { 1, 1, 2, 1, 1, -7.0, 0.0, 0.0, 4.0, 0.0, 0.0}, - - /* 631-640 */ - { 0, 2, 2, 2, 2, 6.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 2, 1, 2, 0, 0, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2, 0, 4,-2, 1, 5.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 4, 1, 2,-2, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - {-1,-1, 0, 6, 0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {-3,-1, 2, 6, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - {-1, 0, 0, 6, 1, -5.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - {-3, 0, 2, 6, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 1,-1, 0, 4, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 1,-1, 0, 4, 0, 12.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 641-650 */ - {-2, 0, 2, 5, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 1,-2, 2, 2, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 3,-1, 0, 2, 0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1,-1, 2, 2, 0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 0, 2, 3, 1, 5.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - {-1, 1, 2, 4, 1, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 0, 1, 2, 3, 2, -6.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - {-1, 0, 4, 2, 1, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 2, 0, 2, 1, 1, 6.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 5, 0, 0, 0, 0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 651-660 */ - { 2, 1, 2, 1, 2, -6.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - { 1, 0, 4, 0, 1, 3.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 3, 1, 2, 0, 1, 7.0, 0.0, 0.0, -4.0, 0.0, 0.0}, - { 3, 0, 4,-2, 2, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - {-2,-1, 2, 6, 2, -5.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 0, 0, 0, 6, 0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0,-2, 2, 4, 2, -6.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - {-2, 0, 2, 6, 1, -6.0, 0.0, 0.0, 3.0, 0.0, 0.0}, - { 2, 0, 0, 4, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 2, 0, 0, 4, 0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - - /* 661-670 */ - { 2,-2, 2, 2, 2, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 0, 0, 2, 4, 0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 1, 0, 2, 3, 2, 7.0, 0.0, 0.0, -3.0, 0.0, 0.0}, - { 4, 0, 0, 2, 0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 2, 0, 2, 2, 0, 11.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - { 0, 0, 4, 2, 2, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 4,-1, 2, 0, 2, -6.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 3, 0, 2, 1, 2, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 2, 1, 2, 2, 1, 3.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 4, 1, 2, 0, 2, 5.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - - /* 671-678 */ - {-1,-1, 2, 6, 2, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - {-1, 0, 2, 6, 1, -4.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 1,-1, 2, 4, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0}, - { 1, 1, 2, 4, 2, 4.0, 0.0, 0.0, -2.0, 0.0, 0.0}, - { 3, 1, 2, 2, 2, 3.0, 0.0, 0.0, -1.0, 0.0, 0.0}, - { 5, 0, 2, 0, 1, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 2,-1, 2, 4, 2, -3.0, 0.0, 0.0, 1.0, 0.0, 0.0}, - { 2, 0, 2, 4, 1, -3.0, 0.0, 0.0, 2.0, 0.0, 0.0} - }; - -/* Number of terms in the luni-solar nutation model */ - const int NLS = (int) (sizeof xls / sizeof xls[0]); - -/* ------------------------ */ -/* Planetary nutation model */ -/* ------------------------ */ - -/* The units for the sine and cosine coefficients are */ -/* 0.1 microarcsecond */ - - static const struct { - int nl, /* coefficients of l, F, D and Omega */ - nf, - nd, - nom, - nme, /* coefficients of planetary longitudes */ - nve, - nea, - nma, - nju, - nsa, - nur, - nne, - npa; /* coefficient of general precession */ - int sp,cp; /* longitude sin, cos coefficients */ - int se,ce; /* obliquity sin, cos coefficients */ - } xpl[] = { - - /* 1-10 */ - { 0, 0, 0, 0, 0, 0, 8,-16, 4, 5, 0, 0, 0, 1440, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, -8, 16,-4,-5, 0, 0, 2, 56,-117, -42, -40}, - { 0, 0, 0, 0, 0, 0, 8,-16, 4, 5, 0, 0, 2, 125, -43, 0, -54}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1, 2, 2, 0, 5, 0, 0}, - { 0, 0, 0, 0, 0, 0, -4, 8,-1,-5, 0, 0, 2, 3, -7, -3, 0}, - { 0, 0, 0, 0, 0, 0, 4, -8, 3, 0, 0, 0, 1, 3, 0, 0, -2}, - { 0, 1,-1, 1, 0, 0, 3, -8, 3, 0, 0, 0, 0, -114, 0, 0, 61}, - {-1, 0, 0, 0, 0, 10, -3, 0, 0, 0, 0, 0, 0, -219, 89, 0, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0,-2, 6,-3, 0, 2, -3, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 4, -8, 3, 0, 0, 0, 0, -462,1604, 0, 0}, - - /* 11-20 */ - { 0, 1,-1, 1, 0, 0, -5, 8,-3, 0, 0, 0, 0, 99, 0, 0, -53}, - { 0, 0, 0, 0, 0, 0, -4, 8,-3, 0, 0, 0, 1, -3, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, 4, -8, 1, 5, 0, 0, 2, 0, 6, 2, 0}, - { 0, 0, 0, 0, 0, -5, 6, 4, 0, 0, 0, 0, 2, 3, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 2,-5, 0, 0, 2, -12, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 2,-5, 0, 0, 1, 14,-218, 117, 8}, - { 0, 1,-1, 1, 0, 0, -1, 0, 2,-5, 0, 0, 0, 31,-481, -257, -17}, - { 0, 0, 0, 0, 0, 0, 0, 0, 2,-5, 0, 0, 0, -491, 128, 0, 0}, - { 0, 1,-1, 1, 0, 0, -1, 0,-2, 5, 0, 0, 0,-3084,5123, 2735,1647}, - { 0, 0, 0, 0, 0, 0, 0, 0,-2, 5, 0, 0, 1,-1444,2409,-1286,-771}, - - /* 21-30 */ - { 0, 0, 0, 0, 0, 0, 0, 0,-2, 5, 0, 0, 2, 11, -24, -11, -9}, - { 2,-1,-1, 0, 0, 0, 3, -7, 0, 0, 0, 0, 0, 26, -9, 0, 0}, - { 1, 0,-2, 0, 0, 19,-21, 3, 0, 0, 0, 0, 0, 103, -60, 0, 0}, - { 0, 1,-1, 1, 0, 2, -4, 0,-3, 0, 0, 0, 0, 0, -13, -7, 0}, - { 1, 0,-1, 1, 0, 0, -1, 0, 2, 0, 0, 0, 0, -26, -29, -16, 14}, - { 0, 1,-1, 1, 0, 0, -1, 0,-4,10, 0, 0, 0, 9, -27, -14, -5}, - {-2, 0, 2, 1, 0, 0, 2, 0, 0,-5, 0, 0, 0, 12, 0, 0, -6}, - { 0, 0, 0, 0, 0, 3, -7, 4, 0, 0, 0, 0, 0, -7, 0, 0, 0}, - { 0,-1, 1, 0, 0, 0, 1, 0, 1,-1, 0, 0, 0, 0, 24, 0, 0}, - {-2, 0, 2, 1, 0, 0, 2, 0,-2, 0, 0, 0, 0, 284, 0, 0,-151}, - - /* 31-40 */ - {-1, 0, 0, 0, 0, 18,-16, 0, 0, 0, 0, 0, 0, 226, 101, 0, 0}, - {-2, 1, 1, 2, 0, 0, 1, 0,-2, 0, 0, 0, 0, 0, -8, -2, 0}, - {-1, 1,-1, 1, 0, 18,-17, 0, 0, 0, 0, 0, 0, 0, -6, -3, 0}, - {-1, 0, 1, 1, 0, 0, 2, -2, 0, 0, 0, 0, 0, 5, 0, 0, -3}, - { 0, 0, 0, 0, 0, -8, 13, 0, 0, 0, 0, 0, 2, -41, 175, 76, 17}, - { 0, 2,-2, 2, 0, -8, 11, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0}, - { 0, 0, 0, 0, 0, -8, 13, 0, 0, 0, 0, 0, 1, 425, 212, -133, 269}, - { 0, 1,-1, 1, 0, -8, 12, 0, 0, 0, 0, 0, 0, 1200, 598, 319,-641}, - { 0, 0, 0, 0, 0, 8,-13, 0, 0, 0, 0, 0, 0, 235, 334, 0, 0}, - { 0, 1,-1, 1, 0, 8,-14, 0, 0, 0, 0, 0, 0, 11, -12, -7, -6}, - - /* 41-50 */ - { 0, 0, 0, 0, 0, 8,-13, 0, 0, 0, 0, 0, 1, 5, -6, 3, 3}, - {-2, 0, 2, 1, 0, 0, 2, 0,-4, 5, 0, 0, 0, -5, 0, 0, 3}, - {-2, 0, 2, 2, 0, 3, -3, 0, 0, 0, 0, 0, 0, 6, 0, 0, -3}, - {-2, 0, 2, 0, 0, 0, 2, 0,-3, 1, 0, 0, 0, 15, 0, 0, 0}, - { 0, 0, 0, 1, 0, 3, -5, 0, 2, 0, 0, 0, 0, 13, 0, 0, -7}, - {-2, 0, 2, 0, 0, 0, 2, 0,-4, 3, 0, 0, 0, -6, -9, 0, 0}, - { 0,-1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 266, -78, 0, 0}, - { 0, 0, 0, 1, 0, 0, -1, 2, 0, 0, 0, 0, 0, -460,-435, -232, 246}, - { 0, 1,-1, 2, 0, 0, -2, 2, 0, 0, 0, 0, 0, 0, 15, 7, 0}, - {-1, 1, 0, 1, 0, 3, -5, 0, 0, 0, 0, 0, 0, -3, 0, 0, 2}, - - /* 51-60 */ - {-1, 0, 1, 0, 0, 3, -4, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0}, - {-2, 0, 2, 0, 0, 0, 2, 0,-2,-2, 0, 0, 0, 4, 0, 0, 0}, - {-2, 2, 0, 2, 0, 0, -5, 9, 0, 0, 0, 0, 0, 0, 3, 0, 0}, - { 0, 1,-1, 1, 0, 0, -1, 0, 0, 0,-1, 0, 0, 0, 4, 2, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0}, - { 0, 1,-1, 1, 0, 0, -1, 0, 0, 0, 0, 2, 0, -17, -19, -10, 9}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, -9, -11, 6, -5}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, -6, 0, 0, 3}, - {-1, 0, 1, 0, 0, 0, 3, -4, 0, 0, 0, 0, 0, -16, 8, 0, 0}, - { 0,-1, 1, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0}, - - /* 61-70 */ - { 0, 1,-1, 2, 0, 0, -1, 0, 0, 2, 0, 0, 0, 11, 24, 11, -5}, - { 0, 0, 0, 1, 0, 0, -9, 17, 0, 0, 0, 0, 0, -3, -4, -2, 1}, - { 0, 0, 0, 2, 0, -3, 5, 0, 0, 0, 0, 0, 0, 3, 0, 0, -1}, - { 0, 1,-1, 1, 0, 0, -1, 0,-1, 2, 0, 0, 0, 0, -8, -4, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 1,-2, 0, 0, 0, 0, 3, 0, 0}, - { 1, 0,-2, 0, 0, 17,-16, 0,-2, 0, 0, 0, 0, 0, 5, 0, 0}, - { 0, 1,-1, 1, 0, 0, -1, 0, 1,-3, 0, 0, 0, 0, 3, 2, 0}, - {-2, 0, 2, 1, 0, 0, 5, -6, 0, 0, 0, 0, 0, -6, 4, 2, 3}, - { 0,-2, 2, 0, 0, 0, 9,-13, 0, 0, 0, 0, 0, -3, -5, 0, 0}, - { 0, 1,-1, 2, 0, 0, -1, 0, 0, 1, 0, 0, 0, -5, 0, 0, 2}, - - /* 71-80 */ - { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 24, 13, -2}, - { 0,-1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, -42, 20, 0, 0}, - { 0,-2, 2, 0, 0, 5, -6, 0, 0, 0, 0, 0, 0, -10, 233, 0, 0}, - { 0,-1, 1, 1, 0, 5, -7, 0, 0, 0, 0, 0, 0, -3, 0, 0, 1}, - {-2, 0, 2, 0, 0, 6, -8, 0, 0, 0, 0, 0, 0, 78, -18, 0, 0}, - { 2, 1,-3, 1, 0, -6, 7, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0}, - { 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -3, -1, 0}, - { 0,-1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, -4, -2, 1}, - { 0, 1,-1, 1, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, -8, -4, -1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, -5, 3, 0}, - - /* 81-90 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, -7, 0, 0, 3}, - { 0, 0, 0, 0, 0, 0, -8, 15, 0, 0, 0, 0, 2, -14, 8, 3, 6}, - { 0, 0, 0, 0, 0, 0, -8, 15, 0, 0, 0, 0, 1, 0, 8, -4, 0}, - { 0, 1,-1, 1, 0, 0, -9, 15, 0, 0, 0, 0, 0, 0, 19, 10, 0}, - { 0, 0, 0, 0, 0, 0, 8,-15, 0, 0, 0, 0, 0, 45, -22, 0, 0}, - { 1,-1,-1, 0, 0, 0, 8,-15, 0, 0, 0, 0, 0, -3, 0, 0, 0}, - { 2, 0,-2, 0, 0, 2, -5, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0}, - {-2, 0, 2, 0, 0, 0, 2, 0,-5, 5, 0, 0, 0, 0, 3, 0, 0}, - { 2, 0,-2, 1, 0, 0, -6, 8, 0, 0, 0, 0, 0, 3, 5, 3, -2}, - { 2, 0,-2, 1, 0, 0, -2, 0, 3, 0, 0, 0, 0, 89, -16, -9, -48}, - - /* 91-100 */ - {-2, 1, 1, 0, 0, 0, 1, 0,-3, 0, 0, 0, 0, 0, 3, 0, 0}, - {-2, 1, 1, 1, 0, 0, 1, 0,-3, 0, 0, 0, 0, -3, 7, 4, 2}, - {-2, 0, 2, 0, 0, 0, 2, 0,-3, 0, 0, 0, 0, -349, -62, 0, 0}, - {-2, 0, 2, 0, 0, 0, 6, -8, 0, 0, 0, 0, 0, -15, 22, 0, 0}, - {-2, 0, 2, 0, 0, 0, 2, 0,-1,-5, 0, 0, 0, -3, 0, 0, 0}, - {-1, 0, 1, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, -53, 0, 0, 0}, - {-1, 1, 1, 1, 0,-20, 20, 0, 0, 0, 0, 0, 0, 5, 0, 0, -3}, - { 1, 0,-2, 0, 0, 20,-21, 0, 0, 0, 0, 0, 0, 0, -8, 0, 0}, - { 0, 0, 0, 1, 0, 0, 8,-15, 0, 0, 0, 0, 0, 15, -7, -4, -8}, - { 0, 2,-2, 1, 0, 0,-10, 15, 0, 0, 0, 0, 0, -3, 0, 0, 1}, - - /* 101-110 */ - { 0,-1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -21, -78, 0, 0}, - { 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 20, -70, -37, -11}, - { 0, 1,-1, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 6, 3, 0}, - { 0, 1,-1, 1, 0, 0, -1, 0,-2, 4, 0, 0, 0, 5, 3, 2, -2}, - { 2, 0,-2, 1, 0, -6, 8, 0, 0, 0, 0, 0, 0, -17, -4, -2, 9}, - { 0,-2, 2, 1, 0, 5, -6, 0, 0, 0, 0, 0, 0, 0, 6, 3, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,-1, 0, 0, 1, 32, 15, -8, 17}, - { 0, 1,-1, 1, 0, 0, -1, 0, 0,-1, 0, 0, 0, 174, 84, 45, -93}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 56, 0, 0}, - { 0, 1,-1, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -66, -12, -6, 35}, - - /* 111-120 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 47, 8, 4, -25}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 8, 4, 0}, - { 0, 2,-2, 1, 0, 0, -9, 13, 0, 0, 0, 0, 0, 10, -22, -12, -5}, - { 0, 0, 0, 1, 0, 0, 7,-13, 0, 0, 0, 0, 0, -3, 0, 0, 2}, - {-2, 0, 2, 0, 0, 0, 5, -6, 0, 0, 0, 0, 0, -24, 12, 0, 0}, - { 0, 0, 0, 0, 0, 0, 9,-17, 0, 0, 0, 0, 0, 5, -6, 0, 0}, - { 0, 0, 0, 0, 0, 0, -9, 17, 0, 0, 0, 0, 2, 3, 0, 0, -2}, - { 1, 0,-1, 1, 0, 0, -3, 4, 0, 0, 0, 0, 0, 4, 3, 1, -2}, - { 1, 0,-1, 1, 0, -3, 4, 0, 0, 0, 0, 0, 0, 0, 29, 15, 0}, - { 0, 0, 0, 2, 0, 0, -1, 2, 0, 0, 0, 0, 0, -5, -4, -2, 2}, - - /* 121-130 */ - { 0,-1, 1, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 8, -3, -1, -5}, - { 0,-2, 2, 0, 1, 0, -2, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0}, - { 0, 0, 0, 0, 0, 3, -5, 0, 2, 0, 0, 0, 0, 10, 0, 0, 0}, - {-2, 0, 2, 1, 0, 0, 2, 0,-3, 1, 0, 0, 0, 3, 0, 0, -2}, - {-2, 0, 2, 1, 0, 3, -3, 0, 0, 0, 0, 0, 0, -5, 0, 0, 3}, - { 0, 0, 0, 1, 0, 8,-13, 0, 0, 0, 0, 0, 0, 46, 66, 35, -25}, - { 0,-1, 1, 0, 0, 8,-12, 0, 0, 0, 0, 0, 0, -14, 7, 0, 0}, - { 0, 2,-2, 1, 0, -8, 11, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0}, - {-1, 0, 1, 0, 0, 0, 2, -2, 0, 0, 0, 0, 0, -5, 0, 0, 0}, - {-1, 0, 0, 1, 0, 18,-16, 0, 0, 0, 0, 0, 0, -68, -34, -18, 36}, - - /* 131-140 */ - { 0, 1,-1, 1, 0, 0, -1, 0,-1, 1, 0, 0, 0, 0, 14, 7, 0}, - { 0, 0, 0, 1, 0, 3, -7, 4, 0, 0, 0, 0, 0, 10, -6, -3, -5}, - {-2, 1, 1, 1, 0, 0, -3, 7, 0, 0, 0, 0, 0, -5, -4, -2, 3}, - { 0, 1,-1, 2, 0, 0, -1, 0,-2, 5, 0, 0, 0, -3, 5, 2, 1}, - { 0, 0, 0, 1, 0, 0, 0, 0,-2, 5, 0, 0, 0, 76, 17, 9, -41}, - { 0, 0, 0, 1, 0, 0, -4, 8,-3, 0, 0, 0, 0, 84, 298, 159, -45}, - { 1, 0, 0, 1, 0,-10, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, -1}, - { 0, 2,-2, 1, 0, 0, -2, 0, 0, 0, 0, 0, 0, -3, 0, 0, 2}, - {-1, 0, 0, 1, 0, 10, -3, 0, 0, 0, 0, 0, 0, -3, 0, 0, 1}, - { 0, 0, 0, 1, 0, 0, 4, -8, 3, 0, 0, 0, 0, -82, 292, 156, 44}, - - /* 141-150 */ - { 0, 0, 0, 1, 0, 0, 0, 0, 2,-5, 0, 0, 0, -73, 17, 9, 39}, - { 0,-1, 1, 0, 0, 0, 1, 0, 2,-5, 0, 0, 0, -9, -16, 0, 0}, - { 2,-1,-1, 1, 0, 0, 3, -7, 0, 0, 0, 0, 0, 3, 0, -1, -2}, - {-2, 0, 2, 0, 0, 0, 2, 0, 0,-5, 0, 0, 0, -3, 0, 0, 0}, - { 0, 0, 0, 1, 0, -3, 7, -4, 0, 0, 0, 0, 0, -9, -5, -3, 5}, - {-2, 0, 2, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, -439, 0, 0, 0}, - { 1, 0, 0, 1, 0,-18, 16, 0, 0, 0, 0, 0, 0, 57, -28, -15, -30}, - {-2, 1, 1, 1, 0, 0, 1, 0,-2, 0, 0, 0, 0, 0, -6, -3, 0}, - { 0, 1,-1, 2, 0, -8, 12, 0, 0, 0, 0, 0, 0, -4, 0, 0, 2}, - { 0, 0, 0, 1, 0, -8, 13, 0, 0, 0, 0, 0, 0, -40, 57, 30, 21}, - - /* 151-160 */ - { 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 1, 23, 7, 3, -13}, - { 0, 1,-1, 1, 0, 0, 0, -2, 0, 0, 0, 0, 0, 273, 80, 43,-146}, - { 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 0, -449, 430, 0, 0}, - { 0, 1,-1, 1, 0, 0, -2, 2, 0, 0, 0, 0, 0, -8, -47, -25, 4}, - { 0, 0, 0, 0, 0, 0, -1, 2, 0, 0, 0, 0, 1, 6, 47, 25, -3}, - {-1, 0, 1, 1, 0, 3, -4, 0, 0, 0, 0, 0, 0, 0, 23, 13, 0}, - {-1, 0, 1, 1, 0, 0, 3, -4, 0, 0, 0, 0, 0, -3, 0, 0, 2}, - { 0, 1,-1, 1, 0, 0, -1, 0, 0,-2, 0, 0, 0, 3, -4, -2, -2}, - { 0, 1,-1, 1, 0, 0, -1, 0, 0, 2, 0, 0, 0, -48,-110, -59, 26}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 51, 114, 61, -27}, - - /* 161-170 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, -133, 0, 0, 57}, - { 0, 1,-1, 0, 0, 3, -6, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0}, - { 0, 0, 0, 1, 0, -3, 5, 0, 0, 0, 0, 0, 0, -21, -6, -3, 11}, - { 0, 1,-1, 2, 0, -3, 4, 0, 0, 0, 0, 0, 0, 0, -3, -1, 0}, - { 0, 0, 0, 1, 0, 0, -2, 4, 0, 0, 0, 0, 0, -11, -21, -11, 6}, - { 0, 2,-2, 1, 0, -5, 6, 0, 0, 0, 0, 0, 0, -18,-436, -233, 9}, - { 0,-1, 1, 0, 0, 5, -7, 0, 0, 0, 0, 0, 0, 35, -7, 0, 0}, - { 0, 0, 0, 1, 0, 5, -8, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0}, - {-2, 0, 2, 1, 0, 6, -8, 0, 0, 0, 0, 0, 0, 11, -3, -1, -6}, - { 0, 0, 0, 1, 0, 0, -8, 15, 0, 0, 0, 0, 0, -5, -3, -1, 3}, - - /* 171-180 */ - {-2, 0, 2, 1, 0, 0, 2, 0,-3, 0, 0, 0, 0, -53, -9, -5, 28}, - {-2, 0, 2, 1, 0, 0, 6, -8, 0, 0, 0, 0, 0, 0, 3, 2, 1}, - { 1, 0,-1, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0, 4, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, 0, 0, 3,-5, 0, 0, 0, 0, -4, 0, 0}, - { 0, 1,-1, 1, 0, 0, -1, 0,-1, 0, 0, 0, 0, -50, 194, 103, 27}, - { 0, 0, 0, 0, 0, 0, 0, 0,-1, 0, 0, 0, 1, -13, 52, 28, 7}, - { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -91, 248, 0, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 6, 49, 26, -3}, - { 0, 1,-1, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0, -6, -47, -25, 3}, - { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, 3, 0}, - - /* 181-190 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 52, 23, 10, -23}, - { 0, 1,-1, 2, 0, 0, -1, 0, 0,-1, 0, 0, 0, -3, 0, 0, 1}, - { 0, 0, 0, 1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 5, 3, 0}, - { 0,-1, 1, 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, -4, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, -7, 13, 0, 0, 0, 0, 2, -4, 8, 3, 2}, - { 0, 0, 0, 0, 0, 0, 7,-13, 0, 0, 0, 0, 0, 10, 0, 0, 0}, - { 2, 0,-2, 1, 0, 0, -5, 6, 0, 0, 0, 0, 0, 3, 0, 0, -2}, - { 0, 2,-2, 1, 0, 0, -8, 11, 0, 0, 0, 0, 0, 0, 8, 4, 0}, - { 0, 2,-2, 1,-1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 4, 1}, - {-2, 0, 2, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0, -4, 0, 0, 0}, - - /* 191-200 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 0, -4, 0, 0, 0}, - { 0, 1,-1, 1, 0, 0, -1, 0, 0, 3, 0, 0, 0, -8, 4, 2, 4}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 8, -4, -2, -4}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 15, 7, 0}, - {-2, 0, 2, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0, -138, 0, 0, 0}, - { 0, 0, 0, 2, 0, 0, -4, 8,-3, 0, 0, 0, 0, 0, -7, -3, 0}, - { 0, 0, 0, 2, 0, 0, 4, -8, 3, 0, 0, 0, 0, 0, -7, -3, 0}, - { 2, 0,-2, 1, 0, 0, -2, 0, 2, 0, 0, 0, 0, 54, 0, 0, -29}, - { 0, 1,-1, 2, 0, 0, -1, 0, 2, 0, 0, 0, 0, 0, 10, 4, 0}, - { 0, 1,-1, 2, 0, 0, 0, -2, 0, 0, 0, 0, 0, -7, 0, 0, 3}, - - /* 201-210 */ - { 0, 0, 0, 1, 0, 0, 1, -2, 0, 0, 0, 0, 0, -37, 35, 19, 20}, - { 0,-1, 1, 0, 0, 0, 2, -2, 0, 0, 0, 0, 0, 0, 4, 0, 0}, - { 0,-1, 1, 0, 0, 0, 1, 0, 0,-2, 0, 0, 0, -4, 9, 0, 0}, - { 0, 2,-2, 1, 0, 0, -2, 0, 0, 2, 0, 0, 0, 8, 0, 0, -4}, - { 0, 1,-1, 1, 0, 3, -6, 0, 0, 0, 0, 0, 0, -9, -14, -8, 5}, - { 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, 0, 1, -3, -9, -5, 3}, - { 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, 0, 0, -145, 47, 0, 0}, - { 0, 1,-1, 1, 0, -3, 4, 0, 0, 0, 0, 0, 0, -10, 40, 21, 5}, - { 0, 0, 0, 0, 0, -3, 5, 0, 0, 0, 0, 0, 1, 11, -49, -26, -7}, - { 0, 0, 0, 0, 0, -3, 5, 0, 0, 0, 0, 0, 2,-2150, 0, 0, 932}, - - /* 211-220 */ - { 0, 2,-2, 2, 0, -3, 3, 0, 0, 0, 0, 0, 0, -12, 0, 0, 5}, - { 0, 0, 0, 0, 0, -3, 5, 0, 0, 0, 0, 0, 2, 85, 0, 0, -37}, - { 0, 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, 1, 4, 0, 0, -2}, - { 0, 1,-1, 1, 0, 0, 1, -4, 0, 0, 0, 0, 0, 3, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, 0, -86, 153, 0, 0}, - { 0, 0, 0, 0, 0, 0, -2, 4, 0, 0, 0, 0, 1, -6, 9, 5, 3}, - { 0, 1,-1, 1, 0, 0, -3, 4, 0, 0, 0, 0, 0, 9, -13, -7, -5}, - { 0, 0, 0, 0, 0, 0, -2, 4, 0, 0, 0, 0, 1, -8, 12, 6, 4}, - { 0, 0, 0, 0, 0, 0, -2, 4, 0, 0, 0, 0, 2, -51, 0, 0, 22}, - { 0, 0, 0, 0, 0, -5, 8, 0, 0, 0, 0, 0, 2, -11,-268, -116, 5}, - - /* 221-230 */ - { 0, 2,-2, 2, 0, -5, 6, 0, 0, 0, 0, 0, 0, 0, 12, 5, 0}, - { 0, 0, 0, 0, 0, -5, 8, 0, 0, 0, 0, 0, 2, 0, 7, 3, 0}, - { 0, 0, 0, 0, 0, -5, 8, 0, 0, 0, 0, 0, 1, 31, 6, 3, -17}, - { 0, 1,-1, 1, 0, -5, 7, 0, 0, 0, 0, 0, 0, 140, 27, 14, -75}, - { 0, 0, 0, 0, 0, -5, 8, 0, 0, 0, 0, 0, 1, 57, 11, 6, -30}, - { 0, 0, 0, 0, 0, 5, -8, 0, 0, 0, 0, 0, 0, -14, -39, 0, 0}, - { 0, 1,-1, 2, 0, 0, -1, 0,-1, 0, 0, 0, 0, 0, -6, -2, 0}, - { 0, 0, 0, 1, 0, 0, 0, 0,-1, 0, 0, 0, 0, 4, 15, 8, -2}, - { 0,-1, 1, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 0, 4, 0, 0}, - { 0, 2,-2, 1, 0, 0, -2, 0, 1, 0, 0, 0, 0, -3, 0, 0, 1}, - - /* 231-240 */ - { 0, 0, 0, 0, 0, 0, -6, 11, 0, 0, 0, 0, 2, 0, 11, 5, 0}, - { 0, 0, 0, 0, 0, 0, 6,-11, 0, 0, 0, 0, 0, 9, 6, 0, 0}, - { 0, 0, 0, 0,-1, 0, 4, 0, 0, 0, 0, 0, 2, -4, 10, 4, 2}, - { 0, 0, 0, 0, 1, 0, -4, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0}, - { 2, 0,-2, 1, 0, -3, 3, 0, 0, 0, 0, 0, 0, 16, 0, 0, -9}, - {-2, 0, 2, 0, 0, 0, 2, 0, 0,-2, 0, 0, 0, -3, 0, 0, 0}, - { 0, 2,-2, 1, 0, 0, -7, 9, 0, 0, 0, 0, 0, 0, 3, 2, -1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 4,-5, 0, 0, 2, 7, 0, 0, -3}, - { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, -25, 22, 0, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 42, 223, 119, -22}, - - /* 241-250 */ - { 0, 1,-1, 1, 0, 0, -1, 0, 2, 0, 0, 0, 0, -27,-143, -77, 14}, - { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 9, 49, 26, -5}, - { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2,-1166, 0, 0, 505}, - { 0, 2,-2, 2, 0, 0, -2, 0, 2, 0, 0, 0, 0, -5, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 2, -6, 0, 0, 3}, - { 0, 0, 0, 1, 0, 3, -5, 0, 0, 0, 0, 0, 0, -8, 0, 1, 4}, - { 0,-1, 1, 0, 0, 3, -4, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0}, - { 0, 2,-2, 1, 0, -3, 3, 0, 0, 0, 0, 0, 0, 117, 0, 0, -63}, - { 0, 0, 0, 1, 0, 0, 2, -4, 0, 0, 0, 0, 0, -4, 8, 4, 2}, - { 0, 2,-2, 1, 0, 0, -4, 4, 0, 0, 0, 0, 0, 3, 0, 0, -2}, - - /* 251-260 */ - { 0, 1,-1, 2, 0, -5, 7, 0, 0, 0, 0, 0, 0, -5, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, 3, -6, 0, 0, 0, 0, 0, 0, 31, 0, 0}, - { 0, 0, 0, 0, 0, 0, -3, 6, 0, 0, 0, 0, 1, -5, 0, 1, 3}, - { 0, 1,-1, 1, 0, 0, -4, 6, 0, 0, 0, 0, 0, 4, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, -3, 6, 0, 0, 0, 0, 1, -4, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, -3, 6, 0, 0, 0, 0, 2, -24, -13, -6, 10}, - { 0,-1, 1, 0, 0, 2, -2, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0}, - { 0, 0, 0, 1, 0, 2, -3, 0, 0, 0, 0, 0, 0, 0, -32, -17, 0}, - { 0, 0, 0, 0, 0, 0, -5, 9, 0, 0, 0, 0, 2, 8, 12, 5, -3}, - { 0, 0, 0, 0, 0, 0, -5, 9, 0, 0, 0, 0, 1, 3, 0, 0, -1}, - - /* 261-270 */ - { 0, 0, 0, 0, 0, 0, 5, -9, 0, 0, 0, 0, 0, 7, 13, 0, 0}, - { 0,-1, 1, 0, 0, 0, 1, 0,-2, 0, 0, 0, 0, -3, 16, 0, 0}, - { 0, 2,-2, 1, 0, 0, -2, 0, 2, 0, 0, 0, 0, 50, 0, 0, -27}, - {-2, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -5, -3, 0}, - { 0,-2, 2, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0}, - { 0, 0, 0, 0, 0, -6, 10, 0, 0, 0, 0, 0, 1, 0, 5, 3, 1}, - { 0, 0, 0, 0, 0, -6, 10, 0, 0, 0, 0, 0, 2, 24, 5, 2, -11}, - { 0, 0, 0, 0, 0, -2, 3, 0, 0, 0, 0, 0, 2, 5, -11, -5, -2}, - { 0, 0, 0, 0, 0, -2, 3, 0, 0, 0, 0, 0, 1, 30, -3, -2, -16}, - { 0, 1,-1, 1, 0, -2, 2, 0, 0, 0, 0, 0, 0, 18, 0, 0, -9}, - - /* 271-280 */ - { 0, 0, 0, 0, 0, 2, -3, 0, 0, 0, 0, 0, 0, 8, 614, 0, 0}, - { 0, 0, 0, 0, 0, 2, -3, 0, 0, 0, 0, 0, 1, 3, -3, -1, -2}, - { 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 6, 17, 9, -3}, - { 0, 1,-1, 1, 0, 0, -1, 0, 3, 0, 0, 0, 0, -3, -9, -5, 2}, - { 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 6, 3, -1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, -127, 21, 9, 55}, - { 0, 0, 0, 0, 0, 0, 4, -8, 0, 0, 0, 0, 0, 3, 5, 0, 0}, - { 0, 0, 0, 0, 0, 0, -4, 8, 0, 0, 0, 0, 2, -6, -10, -4, 3}, - { 0,-2, 2, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 5, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, -4, 7, 0, 0, 0, 0, 2, 16, 9, 4, -7}, - - /* 281-290 */ - { 0, 0, 0, 0, 0, 0, -4, 7, 0, 0, 0, 0, 1, 3, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, 4, -7, 0, 0, 0, 0, 0, 0, 22, 0, 0}, - { 0, 0, 0, 1, 0, -2, 3, 0, 0, 0, 0, 0, 0, 0, 19, 10, 0}, - { 0, 2,-2, 1, 0, 0, -2, 0, 3, 0, 0, 0, 0, 7, 0, 0, -4}, - { 0, 0, 0, 0, 0, 0, -5, 10, 0, 0, 0, 0, 2, 0, -5, -2, 0}, - { 0, 0, 0, 1, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, -9, 3, 1, 4}, - { 0, 0, 0, 0, 0, 0, -3, 5, 0, 0, 0, 0, 2, 17, 0, 0, -7}, - { 0, 0, 0, 0, 0, 0, -3, 5, 0, 0, 0, 0, 1, 0, -3, -2, -1}, - { 0, 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, 0, -20, 34, 0, 0}, - - /* 291-300 */ - { 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 0, 1, -10, 0, 1, 5}, - { 0, 1,-1, 1, 0, 1, -3, 0, 0, 0, 0, 0, 0, -4, 0, 0, 2}, - { 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 0, 0, 22, -87, 0, 0}, - { 0, 0, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 1, -4, 0, 0, 2}, - { 0, 0, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 2, -3, -6, -2, 1}, - { 0, 0, 0, 0, 0, -7, 11, 0, 0, 0, 0, 0, 2, -16, -3, -1, 7}, - { 0, 0, 0, 0, 0, -7, 11, 0, 0, 0, 0, 0, 1, 0, -3, -2, 0}, - { 0,-2, 2, 0, 0, 4, -4, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 2, -3, 0, 0, 0, 0, 0, -68, 39, 0, 0}, - { 0, 2,-2, 1, 0, -4, 4, 0, 0, 0, 0, 0, 0, 27, 0, 0, -14}, - - /* 301-310 */ - { 0,-1, 1, 0, 0, 4, -5, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0}, - { 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, -25, 0, 0, 0}, - { 0, 0, 0, 0, 0, -4, 7, 0, 0, 0, 0, 0, 1, -12, -3, -2, 6}, - { 0, 1,-1, 1, 0, -4, 6, 0, 0, 0, 0, 0, 0, 3, 0, 0, -1}, - { 0, 0, 0, 0, 0, -4, 7, 0, 0, 0, 0, 0, 2, 3, 66, 29, -1}, - { 0, 0, 0, 0, 0, -4, 6, 0, 0, 0, 0, 0, 2, 490, 0, 0,-213}, - { 0, 0, 0, 0, 0, -4, 6, 0, 0, 0, 0, 0, 1, -22, 93, 49, 12}, - { 0, 1,-1, 1, 0, -4, 5, 0, 0, 0, 0, 0, 0, -7, 28, 15, 4}, - { 0, 0, 0, 0, 0, -4, 6, 0, 0, 0, 0, 0, 1, -3, 13, 7, 2}, - { 0, 0, 0, 0, 0, 4, -6, 0, 0, 0, 0, 0, 0, -46, 14, 0, 0}, - - /* 311-320 */ - {-2, 0, 2, 0, 0, 2, -2, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 1, 0, 0}, - { 0,-1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0}, - { 0, 0, 0, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, -28, 0, 0, 15}, - { 0, 0, 0, 0, 0, 0, -1, 0, 5, 0, 0, 0, 2, 5, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, 1, -3, 0, 0, 0, 0, 0, 0, 3, 0, 0}, - { 0, 0, 0, 0, 0, 0, -1, 3, 0, 0, 0, 0, 2, -11, 0, 0, 5}, - { 0, 0, 0, 0, 0, 0, -7, 12, 0, 0, 0, 0, 2, 0, 3, 1, 0}, - { 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 2, -3, 0, 0, 1}, - { 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 1, 25, 106, 57, -13}, - - /* 321-330 */ - { 0, 1,-1, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 5, 21, 11, -3}, - { 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 1485, 0, 0, 0}, - { 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 1, -7, -32, -17, 4}, - { 0, 1,-1, 1, 0, 1, -2, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0}, - { 0, 0, 0, 0, 0, 0, -2, 5, 0, 0, 0, 0, 2, -6, -3, -2, 3}, - { 0, 0, 0, 0, 0, 0, -1, 0, 4, 0, 0, 0, 2, 30, -6, -2, -13}, - { 0, 0, 0, 0, 0, 0, 1, 0,-4, 0, 0, 0, 0, -4, 4, 0, 0}, - { 0, 0, 0, 1, 0, -1, 1, 0, 0, 0, 0, 0, 0, -19, 0, 0, 10}, - { 0, 0, 0, 0, 0, 0, -6, 10, 0, 0, 0, 0, 2, 0, 4, 2, -1}, - { 0, 0, 0, 0, 0, 0, -6, 10, 0, 0, 0, 0, 0, 0, 3, 0, 0}, - - /* 331-340 */ - { 0, 2,-2, 1, 0, 0, -3, 0, 3, 0, 0, 0, 0, 4, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, -3, 7, 0, 0, 0, 0, 2, 0, -3, -1, 0}, - {-2, 0, 2, 0, 0, 4, -4, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, -5, 8, 0, 0, 0, 0, 2, 5, 3, 1, -2}, - { 0, 0, 0, 0, 0, 0, 5, -8, 0, 0, 0, 0, 0, 0, 11, 0, 0}, - { 0, 0, 0, 0, 0, 0, -1, 0, 3, 0, 0, 0, 2, 118, 0, 0, -52}, - { 0, 0, 0, 0, 0, 0, -1, 0, 3, 0, 0, 0, 1, 0, -5, -3, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0,-3, 0, 0, 0, 0, -28, 36, 0, 0}, - { 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, 0, 0, 5, -5, 0, 0}, - { 0, 0, 0, 0, 0, -2, 4, 0, 0, 0, 0, 0, 1, 14, -59, -31, -8}, - - /* 341-350 */ - { 0, 1,-1, 1, 0, -2, 3, 0, 0, 0, 0, 0, 0, 0, 9, 5, 1}, - { 0, 0, 0, 0, 0, -2, 4, 0, 0, 0, 0, 0, 2, -458, 0, 0, 198}, - { 0, 0, 0, 0, 0, -6, 9, 0, 0, 0, 0, 0, 2, 0, -45, -20, 0}, - { 0, 0, 0, 0, 0, -6, 9, 0, 0, 0, 0, 0, 1, 9, 0, 0, -5}, - { 0, 0, 0, 0, 0, 6, -9, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0}, - { 0, 0, 0, 1, 0, 0, 1, 0,-2, 0, 0, 0, 0, 0, -4, -2, -1}, - { 0, 2,-2, 1, 0, -2, 2, 0, 0, 0, 0, 0, 0, 11, 0, 0, -6}, - { 0, 0, 0, 0, 0, 0, -4, 6, 0, 0, 0, 0, 2, 6, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, 4, -6, 0, 0, 0, 0, 0, -16, 23, 0, 0}, - { 0, 0, 0, 1, 0, 3, -4, 0, 0, 0, 0, 0, 0, 0, -4, -2, 0}, - - /* 351-360 */ - { 0, 0, 0, 0, 0, 0, -1, 0, 2, 0, 0, 0, 2, -5, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, 1, 0,-2, 0, 0, 0, 0, -166, 269, 0, 0}, - { 0, 0, 0, 1, 0, 0, 1, 0,-1, 0, 0, 0, 0, 15, 0, 0, -8}, - { 0, 0, 0, 0, 0, -5, 9, 0, 0, 0, 0, 0, 2, 10, 0, 0, -4}, - { 0, 0, 0, 0, 0, 0, 3, -4, 0, 0, 0, 0, 0, -78, 45, 0, 0}, - { 0, 0, 0, 0, 0, -3, 4, 0, 0, 0, 0, 0, 2, 0, -5, -2, 0}, - { 0, 0, 0, 0, 0, -3, 4, 0, 0, 0, 0, 0, 1, 7, 0, 0, -4}, - { 0, 0, 0, 0, 0, 3, -4, 0, 0, 0, 0, 0, 0, -5, 328, 0, 0}, - { 0, 0, 0, 0, 0, 3, -4, 0, 0, 0, 0, 0, 1, 3, 0, 0, -2}, - { 0, 0, 0, 1, 0, 0, 2, -2, 0, 0, 0, 0, 0, 5, 0, 0, -2}, - - /* 361-370 */ - { 0, 0, 0, 1, 0, 0, -1, 0, 2, 0, 0, 0, 0, 0, 3, 1, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0, 0,-3, 0, 0, 0, -3, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0, 1,-5, 0, 0, 0, -3, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, -4, -2, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0,-1223, -26, 0, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 1, 0, 7, 3, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0,-3, 5, 0, 0, 0, 3, 0, 0, 0}, - { 0, 0, 0, 1, 0, -3, 4, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0, 0,-2, 0, 0, 0, -6, 20, 0, 0}, - { 0, 0, 0, 0, 0, 0, 2, -2, 0, 0, 0, 0, 0, -368, 0, 0, 0}, - - /* 371-380 */ - { 0, 0, 0, 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, -75, 0, 0, 0}, - { 0, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0, 11, 0, 0, -6}, - { 0, 0, 0, 1, 0, 0, -2, 2, 0, 0, 0, 0, 0, 3, 0, 0, -2}, - { 0, 0, 0, 0, 0, -8, 14, 0, 0, 0, 0, 0, 2, -3, 0, 0, 1}, - { 0, 0, 0, 0, 0, 0, 1, 0, 2,-5, 0, 0, 0, -13, -30, 0, 0}, - { 0, 0, 0, 0, 0, 0, 5, -8, 3, 0, 0, 0, 0, 21, 3, 0, 0}, - { 0, 0, 0, 0, 0, 0, 5, -8, 3, 0, 0, 0, 2, -3, 0, 0, 1}, - { 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, -4, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 8, -27, 0, 0}, - { 0, 0, 0, 0, 0, 0, 3, -8, 3, 0, 0, 0, 0, -19, -11, 0, 0}, - - /* 381-390 */ - { 0, 0, 0, 0, 0, 0, -3, 8,-3, 0, 0, 0, 2, -4, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, 1, 0,-2, 5, 0, 0, 2, 0, 5, 2, 0}, - { 0, 0, 0, 0, 0, -8, 12, 0, 0, 0, 0, 0, 2, -6, 0, 0, 2}, - { 0, 0, 0, 0, 0, -8, 12, 0, 0, 0, 0, 0, 0, -8, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0, 1,-2, 0, 0, 0, -1, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 2, -14, 0, 0, 6}, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 6, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, -74, 0, 0, 32}, - { 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 2, 0, -3, -1, 0}, - { 0, 2,-2, 1, 0, -5, 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, -2}, - - /* 391-400 */ - { 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 11, 0, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 3, 2, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, -262, 0, 0, 114}, - { 0, 0, 0, 0, 0, 3, -6, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0}, - { 0, 0, 0, 0, 0, -3, 6, 0, 0, 0, 0, 0, 1, -7, 0, 0, 4}, - { 0, 0, 0, 0, 0, -3, 6, 0, 0, 0, 0, 0, 2, 0, -27, -12, 0}, - { 0, 0, 0, 0, 0, 0, -1, 4, 0, 0, 0, 0, 2, -19, -8, -4, 8}, - { 0, 0, 0, 0, 0, -5, 7, 0, 0, 0, 0, 0, 2, 202, 0, 0, -87}, - { 0, 0, 0, 0, 0, -5, 7, 0, 0, 0, 0, 0, 1, -8, 35, 19, 5}, - { 0, 1,-1, 1, 0, -5, 6, 0, 0, 0, 0, 0, 0, 0, 4, 2, 0}, - - /* 401-410 */ - { 0, 0, 0, 0, 0, 5, -7, 0, 0, 0, 0, 0, 0, 16, -5, 0, 0}, - { 0, 2,-2, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0, 5, 0, 0, -3}, - { 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, -3, 0, 0}, - { 0, 0, 0, 0,-1, 0, 3, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 2, -35, -48, -21, 15}, - { 0, 0, 0, 0, 0, 0, -2, 6, 0, 0, 0, 0, 2, -3, -5, -2, 1}, - { 0, 0, 0, 1, 0, 2, -2, 0, 0, 0, 0, 0, 0, 6, 0, 0, -3}, - { 0, 0, 0, 0, 0, 0, -6, 9, 0, 0, 0, 0, 2, 3, 0, 0, -1}, - { 0, 0, 0, 0, 0, 0, 6, -9, 0, 0, 0, 0, 0, 0, -5, 0, 0}, - { 0, 0, 0, 0, 0, -2, 2, 0, 0, 0, 0, 0, 1, 12, 55, 29, -6}, - - /* 411-420 */ - { 0, 1,-1, 1, 0, -2, 1, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0}, - { 0, 0, 0, 0, 0, 2, -2, 0, 0, 0, 0, 0, 0, -598, 0, 0, 0}, - { 0, 0, 0, 0, 0, 2, -2, 0, 0, 0, 0, 0, 1, -3, -13, -7, 1}, - { 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 2, -5, -7, -3, 2}, - { 0, 0, 0, 0, 0, 0, -5, 7, 0, 0, 0, 0, 2, 3, 0, 0, -1}, - { 0, 0, 0, 0, 0, 0, 5, -7, 0, 0, 0, 0, 0, 5, -7, 0, 0}, - { 0, 0, 0, 1, 0, -2, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, 4, -5, 0, 0, 0, 0, 0, 16, -6, 0, 0}, - { 0, 0, 0, 0, 0, 1, -3, 0, 0, 0, 0, 0, 0, 8, -3, 0, 0}, - { 0, 0, 0, 0, 0, -1, 3, 0, 0, 0, 0, 0, 1, 8, -31, -16, -4}, - - /* 421-430 */ - { 0, 1,-1, 1, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0}, - { 0, 0, 0, 0, 0, -1, 3, 0, 0, 0, 0, 0, 2, 113, 0, 0, -49}, - { 0, 0, 0, 0, 0, -7, 10, 0, 0, 0, 0, 0, 2, 0, -24, -10, 0}, - { 0, 0, 0, 0, 0, -7, 10, 0, 0, 0, 0, 0, 1, 4, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 27, 0, 0, 0}, - { 0, 0, 0, 0, 0, -4, 8, 0, 0, 0, 0, 0, 2, -3, 0, 0, 1}, - { 0, 0, 0, 0, 0, -4, 5, 0, 0, 0, 0, 0, 2, 0, -4, -2, 0}, - { 0, 0, 0, 0, 0, -4, 5, 0, 0, 0, 0, 0, 1, 5, 0, 0, -2}, - { 0, 0, 0, 0, 0, 4, -5, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0}, - { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 2, -13, 0, 0, 6}, - - /* 431-440 */ - { 0, 0, 0, 0, 0, 0, -2, 0, 5, 0, 0, 0, 2, 5, 0, 0, -2}, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 2, -18, -10, -4, 8}, - { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -4, -28, 0, 0}, - { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, -5, 6, 3, 2}, - { 0, 0, 0, 0, 0, -9, 13, 0, 0, 0, 0, 0, 2, -3, 0, 0, 1}, - { 0, 0, 0, 0, 0, 0, -1, 5, 0, 0, 0, 0, 2, -5, -9, -4, 2}, - { 0, 0, 0, 0, 0, 0, -2, 0, 4, 0, 0, 0, 2, 17, 0, 0, -7}, - { 0, 0, 0, 0, 0, 0, 2, 0,-4, 0, 0, 0, 0, 11, 4, 0, 0}, - { 0, 0, 0, 0, 0, 0, -2, 7, 0, 0, 0, 0, 2, 0, -6, -2, 0}, - { 0, 0, 0, 0, 0, 0, 2, 0,-3, 0, 0, 0, 0, 83, 15, 0, 0}, - - /* 441-450 */ - { 0, 0, 0, 0, 0, -2, 5, 0, 0, 0, 0, 0, 1, -4, 0, 0, 2}, - { 0, 0, 0, 0, 0, -2, 5, 0, 0, 0, 0, 0, 2, 0,-114, -49, 0}, - { 0, 0, 0, 0, 0, -6, 8, 0, 0, 0, 0, 0, 2, 117, 0, 0, -51}, - { 0, 0, 0, 0, 0, -6, 8, 0, 0, 0, 0, 0, 1, -5, 19, 10, 2}, - { 0, 0, 0, 0, 0, 6, -8, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0}, - { 0, 0, 0, 1, 0, 0, 2, 0,-2, 0, 0, 0, 0, -3, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, -3, 9, 0, 0, 0, 0, 2, 0, -3, -1, 0}, - { 0, 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 0, 3, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 2, 0, -6, -2, 0}, - { 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 393, 3, 0, 0}, - - /* 451-460 */ - { 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 1, -4, 21, 11, 2}, - { 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 2, -6, 0, -1, 3}, - { 0, 0, 0, 0, 0, -5, 10, 0, 0, 0, 0, 0, 2, -3, 8, 4, 1}, - { 0, 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0, 8, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 2, 18, -29, -13, -8}, - { 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0, 0, 1, 8, 34, 18, -4}, - { 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0}, - { 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 1, 3, 12, 6, -1}, - { 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 2, 54, -15, -7, -24}, - { 0, 0, 0, 0, 0, 0, 2, 0, 0,-3, 0, 0, 0, 0, 3, 0, 0}, - - /* 461-470 */ - { 0, 0, 0, 0, 0, 0, -5, 13, 0, 0, 0, 0, 2, 3, 0, 0, -1}, - { 0, 0, 0, 0, 0, 0, 2, 0,-1, 0, 0, 0, 0, 0, 35, 0, 0}, - { 0, 0, 0, 0, 0, 0, 2, 0,-1, 0, 0, 0, 2, -154, -30, -13, 67}, - { 0, 0, 0, 0, 0, 0, 2, 0, 0,-2, 0, 0, 0, 15, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 2, 0, 0,-2, 0, 0, 1, 0, 4, 2, 0}, - { 0, 0, 0, 0, 0, 0, 3, -2, 0, 0, 0, 0, 0, 0, 9, 0, 0}, - { 0, 0, 0, 0, 0, 0, 3, -2, 0, 0, 0, 0, 2, 80, -71, -31, -35}, - { 0, 0, 0, 0, 0, 0, 2, 0, 0,-1, 0, 0, 2, 0, -20, -9, 0}, - { 0, 0, 0, 0, 0, 0, -6, 15, 0, 0, 0, 0, 2, 11, 5, 2, -5}, - { 0, 0, 0, 0, 0, -8, 15, 0, 0, 0, 0, 0, 2, 61, -96, -42, -27}, - - /* 471-480 */ - { 0, 0, 0, 0, 0, -3, 9, -4, 0, 0, 0, 0, 2, 14, 9, 4, -6}, - { 0, 0, 0, 0, 0, 0, 2, 0, 2,-5, 0, 0, 2, -11, -6, -3, 5}, - { 0, 0, 0, 0, 0, 0, -2, 8,-1,-5, 0, 0, 2, 0, -3, -1, 0}, - { 0, 0, 0, 0, 0, 0, 6, -8, 3, 0, 0, 0, 2, 123,-415, -180, -53}, - { 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, -35}, - { 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 7, -32, -17, -4}, - { 0, 1,-1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -9, -5, 0}, - { 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, -4, 2, 0}, - { 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, -89, 0, 0, 38}, - - /* 481-490 */ - { 0, 0, 0, 0, 0, 0, -6, 16,-4,-5, 0, 0, 2, 0, -86, -19, -6}, - { 0, 0, 0, 0, 0, 0, -2, 8,-3, 0, 0, 0, 2, 0, 0, -19, 6}, - { 0, 0, 0, 0, 0, 0, -2, 8,-3, 0, 0, 0, 2, -123,-416, -180, 53}, - { 0, 0, 0, 0, 0, 0, 6, -8, 1, 5, 0, 0, 2, 0, -3, -1, 0}, - { 0, 0, 0, 0, 0, 0, 2, 0,-2, 5, 0, 0, 2, 12, -6, -3, -5}, - { 0, 0, 0, 0, 0, 3, -5, 4, 0, 0, 0, 0, 2, -13, 9, 4, 6}, - { 0, 0, 0, 0, 0, -8, 11, 0, 0, 0, 0, 0, 2, 0, -15, -7, 0}, - { 0, 0, 0, 0, 0, -8, 11, 0, 0, 0, 0, 0, 1, 3, 0, 0, -1}, - { 0, 0, 0, 0, 0, -8, 11, 0, 0, 0, 0, 0, 2, -62, -97, -42, 27}, - { 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 2, -11, 5, 2, 5}, - - /* 491-500 */ - { 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 2, 0, -19, -8, 0}, - { 0, 0, 0, 0, 0, 3, -3, 0, 2, 0, 0, 0, 2, -3, 0, 0, 1}, - { 0, 2,-2, 1, 0, 0, 4, -8, 3, 0, 0, 0, 0, 0, 4, 2, 0}, - { 0, 1,-1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0}, - { 0, 2,-2, 1, 0, 0, -4, 8,-3, 0, 0, 0, 0, 0, 4, 2, 0}, - { 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 2, -85, -70, -31, 37}, - { 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 2, 163, -12, -5, -72}, - { 0, 0, 0, 0, 0, -3, 7, 0, 0, 0, 0, 0, 2, -63, -16, -7, 28}, - { 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 2, -21, -32, -14, 9}, - { 0, 0, 0, 0, 0, -5, 6, 0, 0, 0, 0, 0, 2, 0, -3, -1, 0}, - - /* 501-510 */ - { 0, 0, 0, 0, 0, -5, 6, 0, 0, 0, 0, 0, 1, 3, 0, 0, -2}, - { 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0}, - { 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 0, 2, 3, 10, 4, -1}, - { 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 3, 0, 0, -1}, - { 0, 0, 0, 0, 0, 0, -1, 6, 0, 0, 0, 0, 2, 0, -7, -3, 0}, - { 0, 0, 0, 0, 0, 0, 7, -9, 0, 0, 0, 0, 2, 0, -4, -2, 0}, - { 0, 0, 0, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0, 6, 19, 0, 0}, - { 0, 0, 0, 0, 0, 2, -1, 0, 0, 0, 0, 0, 2, 5,-173, -75, -2}, - { 0, 0, 0, 0, 0, 0, 6, -7, 0, 0, 0, 0, 2, 0, -7, -3, 0}, - { 0, 0, 0, 0, 0, 0, 5, -5, 0, 0, 0, 0, 2, 7, -12, -5, -3}, - - /* 511-520 */ - { 0, 0, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 1, -3, 0, 0, 2}, - { 0, 0, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 2, 3, -4, -2, -1}, - { 0, 0, 0, 0, 0, -7, 9, 0, 0, 0, 0, 0, 2, 74, 0, 0, -32}, - { 0, 0, 0, 0, 0, -7, 9, 0, 0, 0, 0, 0, 1, -3, 12, 6, 2}, - { 0, 0, 0, 0, 0, 0, 4, -3, 0, 0, 0, 0, 2, 26, -14, -6, -11}, - { 0, 0, 0, 0, 0, 0, 3, -1, 0, 0, 0, 0, 2, 19, 0, 0, -8}, - { 0, 0, 0, 0, 0, -4, 4, 0, 0, 0, 0, 0, 1, 6, 24, 13, -3}, - { 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0}, - { 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0, 1, 0, -10, -5, 0}, - { 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0, 2, 11, -3, -1, -5}, - - /* 521-530 */ - { 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 2, 3, 0, 1, -1}, - { 0, 0, 0, 0, 0, 0, -3, 0, 5, 0, 0, 0, 2, 3, 0, 0, -1}, - { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0}, - { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 5, -23, -12, -3}, - { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 2, -339, 0, 0, 147}, - { 0, 0, 0, 0, 0, -9, 12, 0, 0, 0, 0, 0, 2, 0, -10, -5, 0}, - { 0, 0, 0, 0, 0, 0, 3, 0,-4, 0, 0, 0, 0, 5, 0, 0, 0}, - { 0, 2,-2, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 3, 0, 0, -1}, - { 0, 0, 0, 0, 0, 0, 7, -8, 0, 0, 0, 0, 2, 0, -4, -2, 0}, - { 0, 0, 0, 0, 0, 0, 3, 0,-3, 0, 0, 0, 0, 18, -3, 0, 0}, - - /* 531-540 */ - { 0, 0, 0, 0, 0, 0, 3, 0,-3, 0, 0, 0, 2, 9, -11, -5, -4}, - { 0, 0, 0, 0, 0, -2, 6, 0, 0, 0, 0, 0, 2, -8, 0, 0, 4}, - { 0, 0, 0, 0, 0, -6, 7, 0, 0, 0, 0, 0, 1, 3, 0, 0, -1}, - { 0, 0, 0, 0, 0, 6, -7, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0}, - { 0, 0, 0, 0, 0, 0, 6, -6, 0, 0, 0, 0, 2, 6, -9, -4, -2}, - { 0, 0, 0, 0, 0, 0, 3, 0,-2, 0, 0, 0, 0, -4, -12, 0, 0}, - { 0, 0, 0, 0, 0, 0, 3, 0,-2, 0, 0, 0, 2, 67, -91, -39, -29}, - { 0, 0, 0, 0, 0, 0, 5, -4, 0, 0, 0, 0, 2, 30, -18, -8, -13}, - { 0, 0, 0, 0, 0, 3, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 3, -2, 0, 0, 0, 0, 0, 2, 0,-114, -50, 0}, - - /* 541-550 */ - { 0, 0, 0, 0, 0, 0, 3, 0,-1, 0, 0, 0, 2, 0, 0, 0, 23}, - { 0, 0, 0, 0, 0, 0, 3, 0,-1, 0, 0, 0, 2, 517, 16, 7,-224}, - { 0, 0, 0, 0, 0, 0, 3, 0, 0,-2, 0, 0, 2, 0, -7, -3, 0}, - { 0, 0, 0, 0, 0, 0, 4, -2, 0, 0, 0, 0, 2, 143, -3, -1, -62}, - { 0, 0, 0, 0, 0, 0, 3, 0, 0,-1, 0, 0, 2, 29, 0, 0, -13}, - { 0, 2,-2, 1, 0, 0, 1, 0,-1, 0, 0, 0, 0, -4, 0, 0, 2}, - { 0, 0, 0, 0, 0, -8, 16, 0, 0, 0, 0, 0, 2, -6, 0, 0, 3}, - { 0, 0, 0, 0, 0, 0, 3, 0, 2,-5, 0, 0, 2, 5, 12, 5, -2}, - { 0, 0, 0, 0, 0, 0, 7, -8, 3, 0, 0, 0, 2, -25, 0, 0, 11}, - { 0, 0, 0, 0, 0, 0, -5, 16,-4,-5, 0, 0, 2, -3, 0, 0, 1}, - - /* 551-560 */ - { 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 2, 0, 4, 2, 0}, - { 0, 0, 0, 0, 0, 0, -1, 8,-3, 0, 0, 0, 2, -22, 12, 5, 10}, - { 0, 0, 0, 0, 0, -8, 10, 0, 0, 0, 0, 0, 2, 50, 0, 0, -22}, - { 0, 0, 0, 0, 0, -8, 10, 0, 0, 0, 0, 0, 1, 0, 7, 4, 0}, - { 0, 0, 0, 0, 0, -8, 10, 0, 0, 0, 0, 0, 2, 0, 3, 1, 0}, - { 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, -4, 4, 2, 2}, - { 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 2, -5, -11, -5, 2}, - { 0, 0, 0, 0, 0, -3, 8, 0, 0, 0, 0, 0, 2, 0, 4, 2, 0}, - { 0, 0, 0, 0, 0, -5, 5, 0, 0, 0, 0, 0, 1, 4, 17, 9, -2}, - { 0, 0, 0, 0, 0, 5, -5, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0}, - - /* 561-570 */ - { 0, 0, 0, 0, 0, 5, -5, 0, 0, 0, 0, 0, 1, 0, -4, -2, 0}, - { 0, 0, 0, 0, 0, 5, -5, 0, 0, 0, 0, 0, 2, -8, 0, 0, 4}, - { 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0}, - { 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 4, -15, -8, -2}, - { 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 370, -8, 0,-160}, - { 0, 0, 0, 0, 0, 0, 7, -7, 0, 0, 0, 0, 2, 0, 0, -3, 0}, - { 0, 0, 0, 0, 0, 0, 7, -7, 0, 0, 0, 0, 2, 0, 3, 1, 0}, - { 0, 0, 0, 0, 0, 0, 6, -5, 0, 0, 0, 0, 2, -6, 3, 1, 3}, - { 0, 0, 0, 0, 0, 7, -8, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0}, - { 0, 0, 0, 0, 0, 0, 5, -3, 0, 0, 0, 0, 2, -10, 0, 0, 4}, - - /* 571-580 */ - { 0, 0, 0, 0, 0, 4, -3, 0, 0, 0, 0, 0, 2, 0, 9, 4, 0}, - { 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 2, 4, 17, 7, -2}, - { 0, 0, 0, 0, 0, -9, 11, 0, 0, 0, 0, 0, 2, 34, 0, 0, -15}, - { 0, 0, 0, 0, 0, -9, 11, 0, 0, 0, 0, 0, 1, 0, 5, 3, 0}, - { 0, 0, 0, 0, 0, 0, 4, 0,-4, 0, 0, 0, 2, -5, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, 4, 0,-3, 0, 0, 0, 2, -37, -7, -3, 16}, - { 0, 0, 0, 0, 0, -6, 6, 0, 0, 0, 0, 0, 1, 3, 13, 7, -2}, - { 0, 0, 0, 0, 0, 6, -6, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0}, - { 0, 0, 0, 0, 0, 6, -6, 0, 0, 0, 0, 0, 1, 0, -3, -2, 0}, - { 0, 0, 0, 0, 0, 0, 4, 0,-2, 0, 0, 0, 2, -184, -3, -1, 80}, - - /* 581-590 */ - { 0, 0, 0, 0, 0, 0, 6, -4, 0, 0, 0, 0, 2, -3, 0, 0, 1}, - { 0, 0, 0, 0, 0, 3, -1, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0}, - { 0, 0, 0, 0, 0, 3, -1, 0, 0, 0, 0, 0, 1, 0, -10, -6, -1}, - { 0, 0, 0, 0, 0, 3, -1, 0, 0, 0, 0, 0, 2, 31, -6, 0, -13}, - { 0, 0, 0, 0, 0, 0, 4, 0,-1, 0, 0, 0, 2, -3, -32, -14, 1}, - { 0, 0, 0, 0, 0, 0, 4, 0, 0,-2, 0, 0, 2, -7, 0, 0, 3}, - { 0, 0, 0, 0, 0, 0, 5, -2, 0, 0, 0, 0, 2, 0, -8, -4, 0}, - { 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 3, -4, 0, 0}, - { 0, 0, 0, 0, 0, 8, -9, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0}, - { 0, 0, 0, 0, 0, 5, -4, 0, 0, 0, 0, 0, 2, 0, 3, 1, 0}, - - /* 591-600 */ - { 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 2, 19, -23, -10, 2}, - { 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, -10}, - { 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 1, 0, 3, 2, 0}, - { 0, 0, 0, 0, 0, -7, 7, 0, 0, 0, 0, 0, 1, 0, 9, 5, -1}, - { 0, 0, 0, 0, 0, 7, -7, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0}, - { 0, 0, 0, 0, 0, 4, -2, 0, 0, 0, 0, 0, 1, 0, -7, -4, 0}, - { 0, 0, 0, 0, 0, 4, -2, 0, 0, 0, 0, 0, 2, 8, -4, 0, -4}, - { 0, 0, 0, 0, 0, 4, -2, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0}, - { 0, 0, 0, 0, 0, 4, -2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0}, - { 0, 0, 0, 0, 0, 0, 5, 0,-4, 0, 0, 0, 2, -3, 0, 0, 1}, - - /* 601-610 */ - { 0, 0, 0, 0, 0, 0, 5, 0,-3, 0, 0, 0, 2, -9, 0, 1, 4}, - { 0, 0, 0, 0, 0, 0, 5, 0,-2, 0, 0, 0, 2, 3, 12, 5, -1}, - { 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 17, -3, -1, 0}, - { 0, 0, 0, 0, 0, -8, 8, 0, 0, 0, 0, 0, 1, 0, 7, 4, 0}, - { 0, 0, 0, 0, 0, 8, -8, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0}, - { 0, 0, 0, 0, 0, 5, -3, 0, 0, 0, 0, 0, 1, 0, -5, -3, 0}, - { 0, 0, 0, 0, 0, 5, -3, 0, 0, 0, 0, 0, 2, 14, -3, 0, -1}, - { 0, 0, 0, 0, 0, -9, 9, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0}, - { 0, 0, 0, 0, 0, -9, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, -5}, - { 0, 0, 0, 0, 0, -9, 9, 0, 0, 0, 0, 0, 1, 0, 5, 3, 0}, - - /* 611-620 */ - { 0, 0, 0, 0, 0, 9, -9, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0}, - { 0, 0, 0, 0, 0, 6, -4, 0, 0, 0, 0, 0, 1, 0, -3, -2, 0}, - { 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 2, 2, 9, 4, 3}, - { 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4}, - { 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 4, 2, 0}, - { 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 2, 6, 0, 0, -3}, - { 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 3, 1, 0}, - { 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 2, 5, 0, 0, -2}, - - /* 621-630 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, -1}, - { 1, 0,-2, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, -3, 0, 0, 0}, - { 1, 0,-2, 0, 0, 2, -2, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0}, - { 1, 0,-2, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 7, 0, 0, 0}, - { 1, 0,-2, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0}, - {-1, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0}, - {-1, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 6, 0, 0, 0}, - {-1, 0, 2, 0, 0, 0, 4, -8, 3, 0, 0, 0, 0, 0, -4, 0, 0}, - { 1, 0,-2, 0, 0, 0, 4, -8, 3, 0, 0, 0, 0, 0, -4, 0, 0}, - {-2, 0, 2, 0, 0, 0, 4, -8, 3, 0, 0, 0, 0, 5, 0, 0, 0}, - - /* 631-640 */ - {-1, 0, 0, 0, 0, 0, 2, 0,-3, 0, 0, 0, 0, -3, 0, 0, 0}, - {-1, 0, 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 4, 0, 0, 0}, - {-1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0}, - {-1, 0, 2, 0, 0, 2, -2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0}, - { 1,-1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0}, - {-1, 0, 2, 0, 0, 0, 2, 0,-3, 0, 0, 0, 0, 13, 0, 0, 0}, - {-2, 0, 0, 0, 0, 0, 2, 0,-3, 0, 0, 0, 0, 21, 11, 0, 0}, - { 1, 0, 0, 0, 0, 0, 4, -8, 3, 0, 0, 0, 0, 0, -5, 0, 0}, - {-1, 1,-1, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -5, -2, 0}, - { 1, 1,-1, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0}, - - /* 641-650 */ - {-1, 0, 0, 0, 0, 0, 4, -8, 3, 0, 0, 0, 0, 0, -5, 0, 0}, - {-1, 0, 2, 1, 0, 0, 2, 0,-2, 0, 0, 0, 0, -3, 0, 0, 2}, - { 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 20, 10, 0, 0}, - {-1, 0, 2, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, -34, 0, 0, 0}, - {-1, 0, 2, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0, -19, 0, 0, 0}, - { 1, 0,-2, 1, 0, 0, -2, 0, 2, 0, 0, 0, 0, 3, 0, 0, -2}, - { 1, 2,-2, 2, 0, -3, 3, 0, 0, 0, 0, 0, 0, -3, 0, 0, 1}, - { 1, 2,-2, 2, 0, 0, -2, 0, 2, 0, 0, 0, 0, -6, 0, 0, 3}, - { 1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0}, - { 1, 0, 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 3, 0, 0, 0}, - - /* 651-660 */ - { 0, 0,-2, 0, 0, 2, -2, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0}, - { 0, 0,-2, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 4, 0, 0, 0}, - { 0, 2, 0, 2, 0, -2, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0, -1}, - { 0, 2, 0, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0, 6, 0, 0, -3}, - { 0, 2, 0, 2, 0, -1, 1, 0, 0, 0, 0, 0, 0, -8, 0, 0, 3}, - { 0, 2, 0, 2, 0, -2, 3, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0}, - { 0, 0, 2, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, -3, 0, 0, 0}, - { 0, 1, 1, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -3, -2, 0}, - { 1, 2, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 126, -63, -27, -55}, - {-1, 2, 0, 2, 0, 10, -3, 0, 0, 0, 0, 0, 0, -5, 0, 1, 2}, - - /* 661-670 */ - { 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, -3, 28, 15, 2}, - { 1, 2, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 5, 0, 1, -2}, - { 0, 2, 0, 2, 0, 0, 4, -8, 3, 0, 0, 0, 0, 0, 9, 4, 1}, - { 0, 2, 0, 2, 0, 0, -4, 8,-3, 0, 0, 0, 0, 0, 9, 4, -1}, - {-1, 2, 0, 2, 0, 0, -4, 8,-3, 0, 0, 0, 0, -126, -63, -27, 55}, - { 2, 2,-2, 2, 0, 0, -2, 0, 3, 0, 0, 0, 0, 3, 0, 0, -1}, - { 1, 2, 0, 1, 0, 0, -2, 0, 3, 0, 0, 0, 0, 21, -11, -6, -11}, - { 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0}, - {-1, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, -21, -11, -6, 11}, - {-2, 2, 2, 2, 0, 0, 2, 0,-2, 0, 0, 0, 0, -3, 0, 0, 1}, - - /* 671-680 */ - { 0, 2, 0, 2, 0, 2, -3, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0}, - { 0, 2, 0, 2, 0, 1, -1, 0, 0, 0, 0, 0, 0, 8, 0, 0, -4}, - { 0, 2, 0, 2, 0, 0, 1, 0,-1, 0, 0, 0, 0, -6, 0, 0, 3}, - { 0, 2, 0, 2, 0, 2, -2, 0, 0, 0, 0, 0, 0, -3, 0, 0, 1}, - {-1, 2, 2, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0, 3, 0, 0, -1}, - { 1, 2, 0, 2, 0, -1, 1, 0, 0, 0, 0, 0, 0, -3, 0, 0, 1}, - {-1, 2, 2, 2, 0, 0, 2, 0,-3, 0, 0, 0, 0, -5, 0, 0, 2}, - { 2, 2, 0, 2, 0, 0, 2, 0,-3, 0, 0, 0, 0, 24, -12, -5, -11}, - { 1, 2, 0, 2, 0, 0, -4, 8,-3, 0, 0, 0, 0, 0, 3, 1, 0}, - { 1, 2, 0, 2, 0, 0, 4, -8, 3, 0, 0, 0, 0, 0, 3, 1, 0}, - - /* 681-687 */ - { 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0}, - { 0, 2, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, -24, -12, -5, 10}, - { 2, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4, 0, -1, -2}, - {-1, 2, 2, 2, 0, 0, 2, 0,-2, 0, 0, 0, 0, 13, 0, 0, -6}, - {-1, 2, 2, 2, 0, 3, -3, 0, 0, 0, 0, 0, 0, 7, 0, 0, -3}, - { 1, 2, 0, 2, 0, 1, -1, 0, 0, 0, 0, 0, 0, 3, 0, 0, -1}, - { 0, 2, 2, 2, 0, 0, 2, 0,-2, 0, 0, 0, 0, 3, 0, 0, -1} - }; - -/* Number of terms in the planetary nutation model */ - const int NPL = (int) (sizeof xpl / sizeof xpl[0]); - -/*--------------------------------------------------------------------*/ - -/* Interval between fundamental date J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* ------------------- */ -/* LUNI-SOLAR NUTATION */ -/* ------------------- */ - -/* Fundamental (Delaunay) arguments */ - -/* Mean anomaly of the Moon (IERS 2003). */ - el = eraFal03(t); - -/* Mean anomaly of the Sun (MHB2000). */ - elp = fmod(1287104.79305 + - t * (129596581.0481 + - t * (-0.5532 + - t * (0.000136 + - t * (-0.00001149)))), ERFA_TURNAS) * ERFA_DAS2R; - -/* Mean longitude of the Moon minus that of the ascending node */ -/* (IERS 2003. */ - f = eraFaf03(t); - -/* Mean elongation of the Moon from the Sun (MHB2000). */ - d = fmod(1072260.70369 + - t * (1602961601.2090 + - t * (-6.3706 + - t * (0.006593 + - t * (-0.00003169)))), ERFA_TURNAS) * ERFA_DAS2R; - -/* Mean longitude of the ascending node of the Moon (IERS 2003). */ - om = eraFaom03(t); - -/* Initialize the nutation values. */ - dp = 0.0; - de = 0.0; - -/* Summation of luni-solar nutation series (in reverse order). */ - for (i = NLS-1; i >= 0; i--) { - - /* Argument and functions. */ - arg = fmod((double)xls[i].nl * el + - (double)xls[i].nlp * elp + - (double)xls[i].nf * f + - (double)xls[i].nd * d + - (double)xls[i].nom * om, ERFA_D2PI); - sarg = sin(arg); - carg = cos(arg); - - /* Term. */ - dp += (xls[i].sp + xls[i].spt * t) * sarg + xls[i].cp * carg; - de += (xls[i].ce + xls[i].cet * t) * carg + xls[i].se * sarg; - } - -/* Convert from 0.1 microarcsec units to radians. */ - dpsils = dp * U2R; - depsls = de * U2R; - -/* ------------------ */ -/* PLANETARY NUTATION */ -/* ------------------ */ - -/* n.b. The MHB2000 code computes the luni-solar and planetary nutation */ -/* in different functions, using slightly different Delaunay */ -/* arguments in the two cases. This behaviour is faithfully */ -/* reproduced here. Use of the IERS 2003 expressions for both */ -/* cases leads to negligible changes, well below */ -/* 0.1 microarcsecond. */ - -/* Mean anomaly of the Moon (MHB2000). */ - al = fmod(2.35555598 + 8328.6914269554 * t, ERFA_D2PI); - -/* Mean longitude of the Moon minus that of the ascending node */ -/*(MHB2000). */ - af = fmod(1.627905234 + 8433.466158131 * t, ERFA_D2PI); - -/* Mean elongation of the Moon from the Sun (MHB2000). */ - ad = fmod(5.198466741 + 7771.3771468121 * t, ERFA_D2PI); - -/* Mean longitude of the ascending node of the Moon (MHB2000). */ - aom = fmod(2.18243920 - 33.757045 * t, ERFA_D2PI); - -/* General accumulated precession in longitude (IERS 2003). */ - apa = eraFapa03(t); - -/* Planetary longitudes, Mercury through Uranus (IERS 2003). */ - alme = eraFame03(t); - alve = eraFave03(t); - alea = eraFae03(t); - alma = eraFama03(t); - alju = eraFaju03(t); - alsa = eraFasa03(t); - alur = eraFaur03(t); - -/* Neptune longitude (MHB2000). */ - alne = fmod(5.321159000 + 3.8127774000 * t, ERFA_D2PI); - -/* Initialize the nutation values. */ - dp = 0.0; - de = 0.0; - -/* Summation of planetary nutation series (in reverse order). */ - for (i = NPL-1; i >= 0; i--) { - - /* Argument and functions. */ - arg = fmod((double)xpl[i].nl * al + - (double)xpl[i].nf * af + - (double)xpl[i].nd * ad + - (double)xpl[i].nom * aom + - (double)xpl[i].nme * alme + - (double)xpl[i].nve * alve + - (double)xpl[i].nea * alea + - (double)xpl[i].nma * alma + - (double)xpl[i].nju * alju + - (double)xpl[i].nsa * alsa + - (double)xpl[i].nur * alur + - (double)xpl[i].nne * alne + - (double)xpl[i].npa * apa, ERFA_D2PI); - sarg = sin(arg); - carg = cos(arg); - - /* Term. */ - dp += (double)xpl[i].sp * sarg + (double)xpl[i].cp * carg; - de += (double)xpl[i].se * sarg + (double)xpl[i].ce * carg; - - } - -/* Convert from 0.1 microarcsec units to radians. */ - dpsipl = dp * U2R; - depspl = de * U2R; - -/* ------- */ -/* RESULTS */ -/* ------- */ - -/* Add luni-solar and planetary components. */ - *dpsi = dpsils + dpsipl; - *deps = depsls + depspl; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/nut00b.c b/ast/erfa/nut00b.c deleted file mode 100644 index 775613f..0000000 --- a/ast/erfa/nut00b.c +++ /dev/null @@ -1,381 +0,0 @@ -#include "erfa.h" - -void eraNut00b(double date1, double date2, double *dpsi, double *deps) -/* -** - - - - - - - - - - -** e r a N u t 0 0 b -** - - - - - - - - - - -** -** Nutation, IAU 2000B model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** dpsi,deps double nutation, luni-solar + planetary (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The nutation components in longitude and obliquity are in radians -** and with respect to the equinox and ecliptic of date. The -** obliquity at J2000.0 is assumed to be the Lieske et al. (1977) -** value of 84381.448 arcsec. (The errors that result from using -** this function with the IAU 2006 value of 84381.406 arcsec can be -** neglected.) -** -** The nutation model consists only of luni-solar terms, but -** includes also a fixed offset which compensates for certain long- -** period planetary terms (Note 7). -** -** 3) This function is an implementation of the IAU 2000B abridged -** nutation model formally adopted by the IAU General Assembly in -** 2000. The function computes the MHB_2000_SHORT luni-solar -** nutation series (Luzum 2001), but without the associated -** corrections for the precession rate adjustments and the offset -** between the GCRS and J2000.0 mean poles. -** -** 4) The full IAU 2000A (MHB2000) nutation model contains nearly 1400 -** terms. The IAU 2000B model (McCarthy & Luzum 2003) contains only -** 77 terms, plus additional simplifications, yet still delivers -** results of 1 mas accuracy at present epochs. This combination of -** accuracy and size makes the IAU 2000B abridged nutation model -** suitable for most practical applications. -** -** The function delivers a pole accurate to 1 mas from 1900 to 2100 -** (usually better than 1 mas, very occasionally just outside -** 1 mas). The full IAU 2000A model, which is implemented in the -** function eraNut00a (q.v.), delivers considerably greater accuracy -** at current dates; however, to realize this improved accuracy, -** corrections for the essentially unpredictable free-core-nutation -** (FCN) must also be included. -** -** 5) The present function provides classical nutation. The -** MHB_2000_SHORT algorithm, from which it is adapted, deals also -** with (i) the offsets between the GCRS and mean poles and (ii) the -** adjustments in longitude and obliquity due to the changed -** precession rates. These additional functions, namely frame bias -** and precession adjustments, are supported by the ERFA functions -** eraBi00 and eraPr00. -** -** 6) The MHB_2000_SHORT algorithm also provides "total" nutations, -** comprising the arithmetic sum of the frame bias, precession -** adjustments, and nutation (luni-solar + planetary). These total -** nutations can be used in combination with an existing IAU 1976 -** precession implementation, such as eraPmat76, to deliver GCRS- -** to-true predictions of mas accuracy at current epochs. However, -** for symmetry with the eraNut00a function (q.v. for the reasons), -** the ERFA functions do not generate the "total nutations" -** directly. Should they be required, they could of course easily -** be generated by calling eraBi00, eraPr00 and the present function -** and adding the results. -** -** 7) The IAU 2000B model includes "planetary bias" terms that are -** fixed in size but compensate for long-period nutations. The -** amplitudes quoted in McCarthy & Luzum (2003), namely -** Dpsi = -1.5835 mas and Depsilon = +1.6339 mas, are optimized for -** the "total nutations" method described in Note 6. The Luzum -** (2001) values used in this ERFA implementation, namely -0.135 mas -** and +0.388 mas, are optimized for the "rigorous" method, where -** frame bias, precession and nutation are applied separately and in -** that order. During the interval 1995-2050, the ERFA -** implementation delivers a maximum error of 1.001 mas (not -** including FCN). -** -** References: -** -** Lieske, J.H., Lederle, T., Fricke, W., Morando, B., "Expressions -** for the precession quantities based upon the IAU /1976/ system of -** astronomical constants", Astron.Astrophys. 58, 1-2, 1-16. (1977) -** -** Luzum, B., private communication, 2001 (Fortran code -** MHB_2000_SHORT) -** -** McCarthy, D.D. & Luzum, B.J., "An abridged model of the -** precession-nutation of the celestial pole", Cel.Mech.Dyn.Astron. -** 85, 37-49 (2003) -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J., Astron.Astrophys. 282, 663-683 (1994) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, el, elp, f, d, om, arg, dp, de, sarg, carg, - dpsils, depsls, dpsipl, depspl; - int i; - -/* Units of 0.1 microarcsecond to radians */ - static const double U2R = ERFA_DAS2R / 1e7; - -/* ---------------------------------------- */ -/* Fixed offsets in lieu of planetary terms */ -/* ---------------------------------------- */ - - static const double DPPLAN = -0.135 * ERFA_DMAS2R; - static const double DEPLAN = 0.388 * ERFA_DMAS2R; - -/* --------------------------------------------------- */ -/* Luni-solar nutation: argument and term coefficients */ -/* --------------------------------------------------- */ - -/* The units for the sine and cosine coefficients are */ -/* 0.1 microarcsec and the same per Julian century */ - - static const struct { - int nl,nlp,nf,nd,nom; /* coefficients of l,l',F,D,Om */ - double ps,pst,pc; /* longitude sin, t*sin, cos coefficients */ - double ec,ect,es; /* obliquity cos, t*cos, sin coefficients */ - - } x[] = { - - /* 1-10 */ - { 0, 0, 0, 0,1, - -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0}, - { 0, 0, 2,-2,2, - -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0}, - { 0, 0, 2, 0,2,-2276413.0,-234.0, 2796.0, 978459.0,-485.0,1374.0}, - { 0, 0, 0, 0,2,2074554.0, 207.0, -698.0,-897492.0, 470.0,-291.0}, - { 0, 1, 0, 0,0,1475877.0,-3633.0,11817.0, 73871.0,-184.0,-1924.0}, - { 0, 1, 2,-2,2,-516821.0, 1226.0, -524.0, 224386.0,-677.0,-174.0}, - { 1, 0, 0, 0,0, 711159.0, 73.0, -872.0, -6750.0, 0.0, 358.0}, - { 0, 0, 2, 0,1,-387298.0, -367.0, 380.0, 200728.0, 18.0, 318.0}, - { 1, 0, 2, 0,2,-301461.0, -36.0, 816.0, 129025.0, -63.0, 367.0}, - { 0,-1, 2,-2,2, 215829.0, -494.0, 111.0, -95929.0, 299.0, 132.0}, - - /* 11-20 */ - { 0, 0, 2,-2,1, 128227.0, 137.0, 181.0, -68982.0, -9.0, 39.0}, - {-1, 0, 2, 0,2, 123457.0, 11.0, 19.0, -53311.0, 32.0, -4.0}, - {-1, 0, 0, 2,0, 156994.0, 10.0, -168.0, -1235.0, 0.0, 82.0}, - { 1, 0, 0, 0,1, 63110.0, 63.0, 27.0, -33228.0, 0.0, -9.0}, - {-1, 0, 0, 0,1, -57976.0, -63.0, -189.0, 31429.0, 0.0, -75.0}, - {-1, 0, 2, 2,2, -59641.0, -11.0, 149.0, 25543.0, -11.0, 66.0}, - { 1, 0, 2, 0,1, -51613.0, -42.0, 129.0, 26366.0, 0.0, 78.0}, - {-2, 0, 2, 0,1, 45893.0, 50.0, 31.0, -24236.0, -10.0, 20.0}, - { 0, 0, 0, 2,0, 63384.0, 11.0, -150.0, -1220.0, 0.0, 29.0}, - { 0, 0, 2, 2,2, -38571.0, -1.0, 158.0, 16452.0, -11.0, 68.0}, - - /* 21-30 */ - { 0,-2, 2,-2,2, 32481.0, 0.0, 0.0, -13870.0, 0.0, 0.0}, - {-2, 0, 0, 2,0, -47722.0, 0.0, -18.0, 477.0, 0.0, -25.0}, - { 2, 0, 2, 0,2, -31046.0, -1.0, 131.0, 13238.0, -11.0, 59.0}, - { 1, 0, 2,-2,2, 28593.0, 0.0, -1.0, -12338.0, 10.0, -3.0}, - {-1, 0, 2, 0,1, 20441.0, 21.0, 10.0, -10758.0, 0.0, -3.0}, - { 2, 0, 0, 0,0, 29243.0, 0.0, -74.0, -609.0, 0.0, 13.0}, - { 0, 0, 2, 0,0, 25887.0, 0.0, -66.0, -550.0, 0.0, 11.0}, - { 0, 1, 0, 0,1, -14053.0, -25.0, 79.0, 8551.0, -2.0, -45.0}, - {-1, 0, 0, 2,1, 15164.0, 10.0, 11.0, -8001.0, 0.0, -1.0}, - { 0, 2, 2,-2,2, -15794.0, 72.0, -16.0, 6850.0, -42.0, -5.0}, - - /* 31-40 */ - { 0, 0,-2, 2,0, 21783.0, 0.0, 13.0, -167.0, 0.0, 13.0}, - { 1, 0, 0,-2,1, -12873.0, -10.0, -37.0, 6953.0, 0.0, -14.0}, - { 0,-1, 0, 0,1, -12654.0, 11.0, 63.0, 6415.0, 0.0, 26.0}, - {-1, 0, 2, 2,1, -10204.0, 0.0, 25.0, 5222.0, 0.0, 15.0}, - { 0, 2, 0, 0,0, 16707.0, -85.0, -10.0, 168.0, -1.0, 10.0}, - { 1, 0, 2, 2,2, -7691.0, 0.0, 44.0, 3268.0, 0.0, 19.0}, - {-2, 0, 2, 0,0, -11024.0, 0.0, -14.0, 104.0, 0.0, 2.0}, - { 0, 1, 2, 0,2, 7566.0, -21.0, -11.0, -3250.0, 0.0, -5.0}, - { 0, 0, 2, 2,1, -6637.0, -11.0, 25.0, 3353.0, 0.0, 14.0}, - { 0,-1, 2, 0,2, -7141.0, 21.0, 8.0, 3070.0, 0.0, 4.0}, - - /* 41-50 */ - { 0, 0, 0, 2,1, -6302.0, -11.0, 2.0, 3272.0, 0.0, 4.0}, - { 1, 0, 2,-2,1, 5800.0, 10.0, 2.0, -3045.0, 0.0, -1.0}, - { 2, 0, 2,-2,2, 6443.0, 0.0, -7.0, -2768.0, 0.0, -4.0}, - {-2, 0, 0, 2,1, -5774.0, -11.0, -15.0, 3041.0, 0.0, -5.0}, - { 2, 0, 2, 0,1, -5350.0, 0.0, 21.0, 2695.0, 0.0, 12.0}, - { 0,-1, 2,-2,1, -4752.0, -11.0, -3.0, 2719.0, 0.0, -3.0}, - { 0, 0, 0,-2,1, -4940.0, -11.0, -21.0, 2720.0, 0.0, -9.0}, - {-1,-1, 0, 2,0, 7350.0, 0.0, -8.0, -51.0, 0.0, 4.0}, - { 2, 0, 0,-2,1, 4065.0, 0.0, 6.0, -2206.0, 0.0, 1.0}, - { 1, 0, 0, 2,0, 6579.0, 0.0, -24.0, -199.0, 0.0, 2.0}, - - /* 51-60 */ - { 0, 1, 2,-2,1, 3579.0, 0.0, 5.0, -1900.0, 0.0, 1.0}, - { 1,-1, 0, 0,0, 4725.0, 0.0, -6.0, -41.0, 0.0, 3.0}, - {-2, 0, 2, 0,2, -3075.0, 0.0, -2.0, 1313.0, 0.0, -1.0}, - { 3, 0, 2, 0,2, -2904.0, 0.0, 15.0, 1233.0, 0.0, 7.0}, - { 0,-1, 0, 2,0, 4348.0, 0.0, -10.0, -81.0, 0.0, 2.0}, - { 1,-1, 2, 0,2, -2878.0, 0.0, 8.0, 1232.0, 0.0, 4.0}, - { 0, 0, 0, 1,0, -4230.0, 0.0, 5.0, -20.0, 0.0, -2.0}, - {-1,-1, 2, 2,2, -2819.0, 0.0, 7.0, 1207.0, 0.0, 3.0}, - {-1, 0, 2, 0,0, -4056.0, 0.0, 5.0, 40.0, 0.0, -2.0}, - { 0,-1, 2, 2,2, -2647.0, 0.0, 11.0, 1129.0, 0.0, 5.0}, - - /* 61-70 */ - {-2, 0, 0, 0,1, -2294.0, 0.0, -10.0, 1266.0, 0.0, -4.0}, - { 1, 1, 2, 0,2, 2481.0, 0.0, -7.0, -1062.0, 0.0, -3.0}, - { 2, 0, 0, 0,1, 2179.0, 0.0, -2.0, -1129.0, 0.0, -2.0}, - {-1, 1, 0, 1,0, 3276.0, 0.0, 1.0, -9.0, 0.0, 0.0}, - { 1, 1, 0, 0,0, -3389.0, 0.0, 5.0, 35.0, 0.0, -2.0}, - { 1, 0, 2, 0,0, 3339.0, 0.0, -13.0, -107.0, 0.0, 1.0}, - {-1, 0, 2,-2,1, -1987.0, 0.0, -6.0, 1073.0, 0.0, -2.0}, - { 1, 0, 0, 0,2, -1981.0, 0.0, 0.0, 854.0, 0.0, 0.0}, - {-1, 0, 0, 1,0, 4026.0, 0.0, -353.0, -553.0, 0.0,-139.0}, - { 0, 0, 2, 1,2, 1660.0, 0.0, -5.0, -710.0, 0.0, -2.0}, - - /* 71-77 */ - {-1, 0, 2, 4,2, -1521.0, 0.0, 9.0, 647.0, 0.0, 4.0}, - {-1, 1, 0, 1,1, 1314.0, 0.0, 0.0, -700.0, 0.0, 0.0}, - { 0,-2, 2,-2,1, -1283.0, 0.0, 0.0, 672.0, 0.0, 0.0}, - { 1, 0, 2, 2,1, -1331.0, 0.0, 8.0, 663.0, 0.0, 4.0}, - {-2, 0, 2, 2,2, 1383.0, 0.0, -2.0, -594.0, 0.0, -2.0}, - {-1, 0, 0, 0,2, 1405.0, 0.0, 4.0, -610.0, 0.0, 2.0}, - { 1, 1, 2,-2,2, 1290.0, 0.0, 0.0, -556.0, 0.0, 0.0} - }; - -/* Number of terms in the series */ - const int NLS = (int) (sizeof x / sizeof x[0]); - -/*--------------------------------------------------------------------*/ - -/* Interval between fundamental epoch J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* --------------------*/ -/* LUNI-SOLAR NUTATION */ -/* --------------------*/ - -/* Fundamental (Delaunay) arguments from Simon et al. (1994) */ - -/* Mean anomaly of the Moon. */ - el = fmod(485868.249036 + (1717915923.2178) * t, ERFA_TURNAS) * ERFA_DAS2R; - -/* Mean anomaly of the Sun. */ - elp = fmod(1287104.79305 + (129596581.0481) * t, ERFA_TURNAS) * ERFA_DAS2R; - -/* Mean argument of the latitude of the Moon. */ - f = fmod(335779.526232 + (1739527262.8478) * t, ERFA_TURNAS) * ERFA_DAS2R; - -/* Mean elongation of the Moon from the Sun. */ - d = fmod(1072260.70369 + (1602961601.2090) * t, ERFA_TURNAS) * ERFA_DAS2R; - -/* Mean longitude of the ascending node of the Moon. */ - om = fmod(450160.398036 + (-6962890.5431) * t, ERFA_TURNAS) * ERFA_DAS2R; - -/* Initialize the nutation values. */ - dp = 0.0; - de = 0.0; - -/* Summation of luni-solar nutation series (smallest terms first). */ - for (i = NLS-1; i >= 0; i--) { - - /* Argument and functions. */ - arg = fmod( (double)x[i].nl * el + - (double)x[i].nlp * elp + - (double)x[i].nf * f + - (double)x[i].nd * d + - (double)x[i].nom * om, ERFA_D2PI ); - sarg = sin(arg); - carg = cos(arg); - - /* Term. */ - dp += (x[i].ps + x[i].pst * t) * sarg + x[i].pc * carg; - de += (x[i].ec + x[i].ect * t) * carg + x[i].es * sarg; - } - -/* Convert from 0.1 microarcsec units to radians. */ - dpsils = dp * U2R; - depsls = de * U2R; - -/* ------------------------------*/ -/* IN LIEU OF PLANETARY NUTATION */ -/* ------------------------------*/ - -/* Fixed offset to correct for missing terms in truncated series. */ - dpsipl = DPPLAN; - depspl = DEPLAN; - -/* --------*/ -/* RESULTS */ -/* --------*/ - -/* Add luni-solar and planetary components. */ - *dpsi = dpsils + dpsipl; - *deps = depsls + depspl; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/nut06a.c b/ast/erfa/nut06a.c deleted file mode 100644 index c4d945e..0000000 --- a/ast/erfa/nut06a.c +++ /dev/null @@ -1,162 +0,0 @@ -#include "erfa.h" - -void eraNut06a(double date1, double date2, double *dpsi, double *deps) -/* -** - - - - - - - - - - -** e r a N u t 0 6 a -** - - - - - - - - - - -** -** IAU 2000A nutation with adjustments to match the IAU 2006 -** precession. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** dpsi,deps double nutation, luni-solar + planetary (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The nutation components in longitude and obliquity are in radians -** and with respect to the mean equinox and ecliptic of date, -** IAU 2006 precession model (Hilton et al. 2006, Capitaine et al. -** 2005). -** -** 3) The function first computes the IAU 2000A nutation, then applies -** adjustments for (i) the consequences of the change in obliquity -** from the IAU 1980 ecliptic to the IAU 2006 ecliptic and (ii) the -** secular variation in the Earth's dynamical form factor J2. -** -** 4) The present function provides classical nutation, complementing -** the IAU 2000 frame bias and IAU 2006 precession. It delivers a -** pole which is at current epochs accurate to a few tens of -** microarcseconds, apart from the free core nutation. -** -** Called: -** eraNut00a nutation, IAU 2000A -** -** References: -** -** Chapront, J., Chapront-Touze, M. & Francou, G. 2002, -** Astron.Astrophys. 387, 700 -** -** Lieske, J.H., Lederle, T., Fricke, W. & Morando, B. 1977, -** Astron.Astrophys. 58, 1-16 -** -** Mathews, P.M., Herring, T.A., Buffet, B.A. 2002, J.Geophys.Res. -** 107, B4. The MHB_2000 code itself was obtained on 9th September -** 2002 from ftp//maia.usno.navy.mil/conv2000/chapter5/IAU2000A. -** -** Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683 -** -** Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999, -** Astron.Astrophys.Supp.Ser. 135, 111 -** -** Wallace, P.T., "Software for Implementing the IAU 2000 -** Resolutions", in IERS Workshop 5.1 (2002) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, fj2, dp, de; - - -/* Interval between fundamental date J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Factor correcting for secular variation of J2. */ - fj2 = -2.7774e-6 * t; - -/* Obtain IAU 2000A nutation. */ - eraNut00a(date1, date2, &dp, &de); - -/* Apply P03 adjustments (Wallace & Capitaine, 2006, Eqs.5). */ - *dpsi = dp + dp * (0.4697e-6 + fj2); - *deps = de + de * fj2; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/nut80.c b/ast/erfa/nut80.c deleted file mode 100644 index 5ffb23c..0000000 --- a/ast/erfa/nut80.c +++ /dev/null @@ -1,334 +0,0 @@ -#include "erfa.h" - -void eraNut80(double date1, double date2, double *dpsi, double *deps) -/* -** - - - - - - - - - -** e r a N u t 8 0 -** - - - - - - - - - -** -** Nutation, IAU 1980 model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** dpsi double nutation in longitude (radians) -** deps double nutation in obliquity (radians) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The nutation components are with respect to the ecliptic of -** date. -** -** Called: -** eraAnpm normalize angle into range +/- pi -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 3.222 (p111). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, el, elp, f, d, om, dp, de, arg, s, c; - int j; - -/* Units of 0.1 milliarcsecond to radians */ - const double U2R = ERFA_DAS2R / 1e4; - -/* ------------------------------------------------ */ -/* Table of multiples of arguments and coefficients */ -/* ------------------------------------------------ */ - -/* The units for the sine and cosine coefficients are 0.1 mas and */ -/* the same per Julian century */ - - static const struct { - int nl,nlp,nf,nd,nom; /* coefficients of l,l',F,D,Om */ - double sp,spt; /* longitude sine, 1 and t coefficients */ - double ce,cet; /* obliquity cosine, 1 and t coefficients */ - } x[] = { - - /* 1-10 */ - { 0, 0, 0, 0, 1, -171996.0, -174.2, 92025.0, 8.9 }, - { 0, 0, 0, 0, 2, 2062.0, 0.2, -895.0, 0.5 }, - { -2, 0, 2, 0, 1, 46.0, 0.0, -24.0, 0.0 }, - { 2, 0, -2, 0, 0, 11.0, 0.0, 0.0, 0.0 }, - { -2, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 }, - { 1, -1, 0, -1, 0, -3.0, 0.0, 0.0, 0.0 }, - { 0, -2, 2, -2, 1, -2.0, 0.0, 1.0, 0.0 }, - { 2, 0, -2, 0, 1, 1.0, 0.0, 0.0, 0.0 }, - { 0, 0, 2, -2, 2, -13187.0, -1.6, 5736.0, -3.1 }, - { 0, 1, 0, 0, 0, 1426.0, -3.4, 54.0, -0.1 }, - - /* 11-20 */ - { 0, 1, 2, -2, 2, -517.0, 1.2, 224.0, -0.6 }, - { 0, -1, 2, -2, 2, 217.0, -0.5, -95.0, 0.3 }, - { 0, 0, 2, -2, 1, 129.0, 0.1, -70.0, 0.0 }, - { 2, 0, 0, -2, 0, 48.0, 0.0, 1.0, 0.0 }, - { 0, 0, 2, -2, 0, -22.0, 0.0, 0.0, 0.0 }, - { 0, 2, 0, 0, 0, 17.0, -0.1, 0.0, 0.0 }, - { 0, 1, 0, 0, 1, -15.0, 0.0, 9.0, 0.0 }, - { 0, 2, 2, -2, 2, -16.0, 0.1, 7.0, 0.0 }, - { 0, -1, 0, 0, 1, -12.0, 0.0, 6.0, 0.0 }, - { -2, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0 }, - - /* 21-30 */ - { 0, -1, 2, -2, 1, -5.0, 0.0, 3.0, 0.0 }, - { 2, 0, 0, -2, 1, 4.0, 0.0, -2.0, 0.0 }, - { 0, 1, 2, -2, 1, 4.0, 0.0, -2.0, 0.0 }, - { 1, 0, 0, -1, 0, -4.0, 0.0, 0.0, 0.0 }, - { 2, 1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0 }, - { 0, 0, -2, 2, 1, 1.0, 0.0, 0.0, 0.0 }, - { 0, 1, -2, 2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 0, 0, 2, 1.0, 0.0, 0.0, 0.0 }, - { -1, 0, 0, 1, 1, 1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 2, -2, 0, -1.0, 0.0, 0.0, 0.0 }, - - /* 31-40 */ - { 0, 0, 2, 0, 2, -2274.0, -0.2, 977.0, -0.5 }, - { 1, 0, 0, 0, 0, 712.0, 0.1, -7.0, 0.0 }, - { 0, 0, 2, 0, 1, -386.0, -0.4, 200.0, 0.0 }, - { 1, 0, 2, 0, 2, -301.0, 0.0, 129.0, -0.1 }, - { 1, 0, 0, -2, 0, -158.0, 0.0, -1.0, 0.0 }, - { -1, 0, 2, 0, 2, 123.0, 0.0, -53.0, 0.0 }, - { 0, 0, 0, 2, 0, 63.0, 0.0, -2.0, 0.0 }, - { 1, 0, 0, 0, 1, 63.0, 0.1, -33.0, 0.0 }, - { -1, 0, 0, 0, 1, -58.0, -0.1, 32.0, 0.0 }, - { -1, 0, 2, 2, 2, -59.0, 0.0, 26.0, 0.0 }, - - /* 41-50 */ - { 1, 0, 2, 0, 1, -51.0, 0.0, 27.0, 0.0 }, - { 0, 0, 2, 2, 2, -38.0, 0.0, 16.0, 0.0 }, - { 2, 0, 0, 0, 0, 29.0, 0.0, -1.0, 0.0 }, - { 1, 0, 2, -2, 2, 29.0, 0.0, -12.0, 0.0 }, - { 2, 0, 2, 0, 2, -31.0, 0.0, 13.0, 0.0 }, - { 0, 0, 2, 0, 0, 26.0, 0.0, -1.0, 0.0 }, - { -1, 0, 2, 0, 1, 21.0, 0.0, -10.0, 0.0 }, - { -1, 0, 0, 2, 1, 16.0, 0.0, -8.0, 0.0 }, - { 1, 0, 0, -2, 1, -13.0, 0.0, 7.0, 0.0 }, - { -1, 0, 2, 2, 1, -10.0, 0.0, 5.0, 0.0 }, - - /* 51-60 */ - { 1, 1, 0, -2, 0, -7.0, 0.0, 0.0, 0.0 }, - { 0, 1, 2, 0, 2, 7.0, 0.0, -3.0, 0.0 }, - { 0, -1, 2, 0, 2, -7.0, 0.0, 3.0, 0.0 }, - { 1, 0, 2, 2, 2, -8.0, 0.0, 3.0, 0.0 }, - { 1, 0, 0, 2, 0, 6.0, 0.0, 0.0, 0.0 }, - { 2, 0, 2, -2, 2, 6.0, 0.0, -3.0, 0.0 }, - { 0, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0 }, - { 0, 0, 2, 2, 1, -7.0, 0.0, 3.0, 0.0 }, - { 1, 0, 2, -2, 1, 6.0, 0.0, -3.0, 0.0 }, - { 0, 0, 0, -2, 1, -5.0, 0.0, 3.0, 0.0 }, - - /* 61-70 */ - { 1, -1, 0, 0, 0, 5.0, 0.0, 0.0, 0.0 }, - { 2, 0, 2, 0, 1, -5.0, 0.0, 3.0, 0.0 }, - { 0, 1, 0, -2, 0, -4.0, 0.0, 0.0, 0.0 }, - { 1, 0, -2, 0, 0, 4.0, 0.0, 0.0, 0.0 }, - { 0, 0, 0, 1, 0, -4.0, 0.0, 0.0, 0.0 }, - { 1, 1, 0, 0, 0, -3.0, 0.0, 0.0, 0.0 }, - { 1, 0, 2, 0, 0, 3.0, 0.0, 0.0, 0.0 }, - { 1, -1, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 }, - { -1, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0 }, - { -2, 0, 0, 0, 1, -2.0, 0.0, 1.0, 0.0 }, - - /* 71-80 */ - { 3, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 }, - { 0, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0 }, - { 1, 1, 2, 0, 2, 2.0, 0.0, -1.0, 0.0 }, - { -1, 0, 2, -2, 1, -2.0, 0.0, 1.0, 0.0 }, - { 2, 0, 0, 0, 1, 2.0, 0.0, -1.0, 0.0 }, - { 1, 0, 0, 0, 2, -2.0, 0.0, 1.0, 0.0 }, - { 3, 0, 0, 0, 0, 2.0, 0.0, 0.0, 0.0 }, - { 0, 0, 2, 1, 2, 2.0, 0.0, -1.0, 0.0 }, - { -1, 0, 0, 0, 2, 1.0, 0.0, -1.0, 0.0 }, - { 1, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0 }, - - /* 81-90 */ - { -2, 0, 2, 2, 2, 1.0, 0.0, -1.0, 0.0 }, - { -1, 0, 2, 4, 2, -2.0, 0.0, 1.0, 0.0 }, - { 2, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0 }, - { 1, 1, 2, -2, 2, 1.0, 0.0, -1.0, 0.0 }, - { 1, 0, 2, 2, 1, -1.0, 0.0, 1.0, 0.0 }, - { -2, 0, 2, 4, 2, -1.0, 0.0, 1.0, 0.0 }, - { -1, 0, 4, 0, 2, 1.0, 0.0, 0.0, 0.0 }, - { 1, -1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0 }, - { 2, 0, 2, -2, 1, 1.0, 0.0, -1.0, 0.0 }, - { 2, 0, 2, 2, 2, -1.0, 0.0, 0.0, 0.0 }, - - /* 91-100 */ - { 1, 0, 0, 2, 1, -1.0, 0.0, 0.0, 0.0 }, - { 0, 0, 4, -2, 2, 1.0, 0.0, 0.0, 0.0 }, - { 3, 0, 2, -2, 2, 1.0, 0.0, 0.0, 0.0 }, - { 1, 0, 2, -2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 2, 0, 1, 1.0, 0.0, 0.0, 0.0 }, - { -1, -1, 0, 2, 1, 1.0, 0.0, 0.0, 0.0 }, - { 0, 0, -2, 0, 1, -1.0, 0.0, 0.0, 0.0 }, - { 0, 0, 2, -1, 2, -1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 0, 2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 1, 0, -2, -2, 0, -1.0, 0.0, 0.0, 0.0 }, - - /* 101-106 */ - { 0, -1, 2, 0, 1, -1.0, 0.0, 0.0, 0.0 }, - { 1, 1, 0, -2, 1, -1.0, 0.0, 0.0, 0.0 }, - { 1, 0, -2, 2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 2, 0, 0, 2, 0, 1.0, 0.0, 0.0, 0.0 }, - { 0, 0, 2, 4, 2, -1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 0, 1, 0, 1.0, 0.0, 0.0, 0.0 } - }; - -/* Number of terms in the series */ - const int NT = (int) (sizeof x / sizeof x[0]); - -/*--------------------------------------------------------------------*/ - -/* Interval between fundamental epoch J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* --------------------- */ -/* Fundamental arguments */ -/* --------------------- */ - -/* Mean longitude of Moon minus mean longitude of Moon's perigee. */ - el = eraAnpm( - (485866.733 + (715922.633 + (31.310 + 0.064 * t) * t) * t) - * ERFA_DAS2R + fmod(1325.0 * t, 1.0) * ERFA_D2PI); - -/* Mean longitude of Sun minus mean longitude of Sun's perigee. */ - elp = eraAnpm( - (1287099.804 + (1292581.224 + (-0.577 - 0.012 * t) * t) * t) - * ERFA_DAS2R + fmod(99.0 * t, 1.0) * ERFA_D2PI); - -/* Mean longitude of Moon minus mean longitude of Moon's node. */ - f = eraAnpm( - (335778.877 + (295263.137 + (-13.257 + 0.011 * t) * t) * t) - * ERFA_DAS2R + fmod(1342.0 * t, 1.0) * ERFA_D2PI); - -/* Mean elongation of Moon from Sun. */ - d = eraAnpm( - (1072261.307 + (1105601.328 + (-6.891 + 0.019 * t) * t) * t) - * ERFA_DAS2R + fmod(1236.0 * t, 1.0) * ERFA_D2PI); - -/* Longitude of the mean ascending node of the lunar orbit on the */ -/* ecliptic, measured from the mean equinox of date. */ - om = eraAnpm( - (450160.280 + (-482890.539 + (7.455 + 0.008 * t) * t) * t) - * ERFA_DAS2R + fmod(-5.0 * t, 1.0) * ERFA_D2PI); - -/* --------------- */ -/* Nutation series */ -/* --------------- */ - -/* Initialize nutation components. */ - dp = 0.0; - de = 0.0; - -/* Sum the nutation terms, ending with the biggest. */ - for (j = NT-1; j >= 0; j--) { - - /* Form argument for current term. */ - arg = (double)x[j].nl * el - + (double)x[j].nlp * elp - + (double)x[j].nf * f - + (double)x[j].nd * d - + (double)x[j].nom * om; - - /* Accumulate current nutation term. */ - s = x[j].sp + x[j].spt * t; - c = x[j].ce + x[j].cet * t; - if (s != 0.0) dp += s * sin(arg); - if (c != 0.0) de += c * cos(arg); - } - -/* Convert results from 0.1 mas units to radians. */ - *dpsi = dp * U2R; - *deps = de * U2R; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/nutm80.c b/ast/erfa/nutm80.c deleted file mode 100644 index c526da2..0000000 --- a/ast/erfa/nutm80.c +++ /dev/null @@ -1,126 +0,0 @@ -#include "erfa.h" - -void eraNutm80(double date1, double date2, double rmatn[3][3]) -/* -** - - - - - - - - - - -** e r a N u t m 8 0 -** - - - - - - - - - - -** -** Form the matrix of nutation for a given date, IAU 1980 model. -** -** Given: -** date1,date2 double TDB date (Note 1) -** -** Returned: -** rmatn double[3][3] nutation matrix -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(true) = rmatn * V(mean), -** where the p-vector V(true) is with respect to the true -** equatorial triad of date and the p-vector V(mean) is with -** respect to the mean equatorial triad of date. -** -** Called: -** eraNut80 nutation, IAU 1980 -** eraObl80 mean obliquity, IAU 1980 -** eraNumat form nutation matrix -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dpsi, deps, epsa; - - -/* Nutation components and mean obliquity. */ - eraNut80(date1, date2, &dpsi, &deps); - epsa = eraObl80(date1, date2); - -/* Build the rotation matrix. */ - eraNumat(epsa, dpsi, deps, rmatn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/obl06.c b/ast/erfa/obl06.c deleted file mode 100644 index 9b93626..0000000 --- a/ast/erfa/obl06.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "erfa.h" - -double eraObl06(double date1, double date2) -/* -** - - - - - - - - - -** e r a O b l 0 6 -** - - - - - - - - - -** -** Mean obliquity of the ecliptic, IAU 2006 precession model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double obliquity of the ecliptic (radians, Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The result is the angle between the ecliptic and mean equator of -** date date1+date2. -** -** Reference: -** -** Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, eps0; - - -/* Interval between fundamental date J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Mean obliquity. */ - eps0 = (84381.406 + - (-46.836769 + - ( -0.0001831 + - ( 0.00200340 + - ( -0.000000576 + - ( -0.0000000434) * t) * t) * t) * t) * t) * ERFA_DAS2R; - - return eps0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/obl80.c b/ast/erfa/obl80.c deleted file mode 100644 index 1b5e288..0000000 --- a/ast/erfa/obl80.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "erfa.h" - -double eraObl80(double date1, double date2) -/* -** - - - - - - - - - -** e r a O b l 8 0 -** - - - - - - - - - -** -** Mean obliquity of the ecliptic, IAU 1980 model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double obliquity of the ecliptic (radians, Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The result is the angle between the ecliptic and mean equator of -** date date1+date2. -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Expression 3.222-1 (p114). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, eps0; - - -/* Interval between fundamental epoch J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Mean obliquity of date. */ - eps0 = ERFA_DAS2R * (84381.448 + - (-46.8150 + - (-0.00059 + - ( 0.001813) * t) * t) * t); - - return eps0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/p06e.c b/ast/erfa/p06e.c deleted file mode 100644 index 24f9f2b..0000000 --- a/ast/erfa/p06e.c +++ /dev/null @@ -1,330 +0,0 @@ -#include "erfa.h" - -void eraP06e(double date1, double date2, - double *eps0, double *psia, double *oma, double *bpa, - double *bqa, double *pia, double *bpia, - double *epsa, double *chia, double *za, double *zetaa, - double *thetaa, double *pa, - double *gam, double *phi, double *psi) -/* -** - - - - - - - - -** e r a P 0 6 e -** - - - - - - - - -** -** Precession angles, IAU 2006, equinox based. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (see Note 2): -** eps0 double epsilon_0 -** psia double psi_A -** oma double omega_A -** bpa double P_A -** bqa double Q_A -** pia double pi_A -** bpia double Pi_A -** epsa double obliquity epsilon_A -** chia double chi_A -** za double z_A -** zetaa double zeta_A -** thetaa double theta_A -** pa double p_A -** gam double F-W angle gamma_J2000 -** phi double F-W angle phi_J2000 -** psi double F-W angle psi_J2000 -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) This function returns the set of equinox based angles for the -** Capitaine et al. "P03" precession theory, adopted by the IAU in -** 2006. The angles are set out in Table 1 of Hilton et al. (2006): -** -** eps0 epsilon_0 obliquity at J2000.0 -** psia psi_A luni-solar precession -** oma omega_A inclination of equator wrt J2000.0 ecliptic -** bpa P_A ecliptic pole x, J2000.0 ecliptic triad -** bqa Q_A ecliptic pole -y, J2000.0 ecliptic triad -** pia pi_A angle between moving and J2000.0 ecliptics -** bpia Pi_A longitude of ascending node of the ecliptic -** epsa epsilon_A obliquity of the ecliptic -** chia chi_A planetary precession -** za z_A equatorial precession: -3rd 323 Euler angle -** zetaa zeta_A equatorial precession: -1st 323 Euler angle -** thetaa theta_A equatorial precession: 2nd 323 Euler angle -** pa p_A general precession -** gam gamma_J2000 J2000.0 RA difference of ecliptic poles -** phi phi_J2000 J2000.0 codeclination of ecliptic pole -** psi psi_J2000 longitude difference of equator poles, J2000.0 -** -** The returned values are all radians. -** -** 3) Hilton et al. (2006) Table 1 also contains angles that depend on -** models distinct from the P03 precession theory itself, namely the -** IAU 2000A frame bias and nutation. The quoted polynomials are -** used in other ERFA functions: -** -** . eraXy06 contains the polynomial parts of the X and Y series. -** -** . eraS06 contains the polynomial part of the s+XY/2 series. -** -** . eraPfw06 implements the series for the Fukushima-Williams -** angles that are with respect to the GCRS pole (i.e. the variants -** that include frame bias). -** -** 4) The IAU resolution stipulated that the choice of parameterization -** was left to the user, and so an IAU compliant precession -** implementation can be constructed using various combinations of -** the angles returned by the present function. -** -** 5) The parameterization used by ERFA is the version of the Fukushima- -** Williams angles that refers directly to the GCRS pole. These -** angles may be calculated by calling the function eraPfw06. ERFA -** also supports the direct computation of the CIP GCRS X,Y by -** series, available by calling eraXy06. -** -** 6) The agreement between the different parameterizations is at the -** 1 microarcsecond level in the present era. -** -** 7) When constructing a precession formulation that refers to the GCRS -** pole rather than the dynamical pole, it may (depending on the -** choice of angles) be necessary to introduce the frame bias -** explicitly. -** -** 8) It is permissible to re-use the same variable in the returned -** arguments. The quantities are stored in the stated order. -** -** Reference: -** -** Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351 -** -** Called: -** eraObl06 mean obliquity, IAU 2006 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t; - - -/* Interval between fundamental date J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Obliquity at J2000.0. */ - - *eps0 = 84381.406 * ERFA_DAS2R; - -/* Luni-solar precession. */ - - *psia = ( 5038.481507 + - ( -1.0790069 + - ( -0.00114045 + - ( 0.000132851 + - ( -0.0000000951 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - -/* Inclination of mean equator with respect to the J2000.0 ecliptic. */ - - *oma = *eps0 + ( -0.025754 + - ( 0.0512623 + - ( -0.00772503 + - ( -0.000000467 + - ( 0.0000003337 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - -/* Ecliptic pole x, J2000.0 ecliptic triad. */ - - *bpa = ( 4.199094 + - ( 0.1939873 + - ( -0.00022466 + - ( -0.000000912 + - ( 0.0000000120 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - -/* Ecliptic pole -y, J2000.0 ecliptic triad. */ - - *bqa = ( -46.811015 + - ( 0.0510283 + - ( 0.00052413 + - ( -0.000000646 + - ( -0.0000000172 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - -/* Angle between moving and J2000.0 ecliptics. */ - - *pia = ( 46.998973 + - ( -0.0334926 + - ( -0.00012559 + - ( 0.000000113 + - ( -0.0000000022 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - -/* Longitude of ascending node of the moving ecliptic. */ - - *bpia = ( 629546.7936 + - ( -867.95758 + - ( 0.157992 + - ( -0.0005371 + - ( -0.00004797 + - ( 0.000000072 ) - * t) * t) * t) * t) * t) * ERFA_DAS2R; - -/* Mean obliquity of the ecliptic. */ - - *epsa = eraObl06(date1, date2); - -/* Planetary precession. */ - - *chia = ( 10.556403 + - ( -2.3814292 + - ( -0.00121197 + - ( 0.000170663 + - ( -0.0000000560 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - -/* Equatorial precession: minus the third of the 323 Euler angles. */ - - *za = ( -2.650545 + - ( 2306.077181 + - ( 1.0927348 + - ( 0.01826837 + - ( -0.000028596 + - ( -0.0000002904 ) - * t) * t) * t) * t) * t) * ERFA_DAS2R; - -/* Equatorial precession: minus the first of the 323 Euler angles. */ - - *zetaa = ( 2.650545 + - ( 2306.083227 + - ( 0.2988499 + - ( 0.01801828 + - ( -0.000005971 + - ( -0.0000003173 ) - * t) * t) * t) * t) * t) * ERFA_DAS2R; - -/* Equatorial precession: second of the 323 Euler angles. */ - - *thetaa = ( 2004.191903 + - ( -0.4294934 + - ( -0.04182264 + - ( -0.000007089 + - ( -0.0000001274 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - -/* General precession. */ - - *pa = ( 5028.796195 + - ( 1.1054348 + - ( 0.00007964 + - ( -0.000023857 + - ( 0.0000000383 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - -/* Fukushima-Williams angles for precession. */ - - *gam = ( 10.556403 + - ( 0.4932044 + - ( -0.00031238 + - ( -0.000002788 + - ( 0.0000000260 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - - *phi = *eps0 + ( -46.811015 + - ( 0.0511269 + - ( 0.00053289 + - ( -0.000000440 + - ( -0.0000000176 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - - *psi = ( 5038.481507 + - ( 1.5584176 + - ( -0.00018522 + - ( -0.000026452 + - ( -0.0000000148 ) - * t) * t) * t) * t) * t * ERFA_DAS2R; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/p2pv.c b/ast/erfa/p2pv.c deleted file mode 100644 index b5d2081..0000000 --- a/ast/erfa/p2pv.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "erfa.h" - -void eraP2pv(double p[3], double pv[2][3]) -/* -** - - - - - - - - -** e r a P 2 p v -** - - - - - - - - -** -** Extend a p-vector to a pv-vector by appending a zero velocity. -** -** Given: -** p double[3] p-vector -** -** Returned: -** pv double[2][3] pv-vector -** -** Called: -** eraCp copy p-vector -** eraZp zero p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraCp(p, pv[0]); - eraZp(pv[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/p2s.c b/ast/erfa/p2s.c deleted file mode 100644 index 14da5f0..0000000 --- a/ast/erfa/p2s.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "erfa.h" - -void eraP2s(double p[3], double *theta, double *phi, double *r) -/* -** - - - - - - - -** e r a P 2 s -** - - - - - - - -** -** P-vector to spherical polar coordinates. -** -** Given: -** p double[3] p-vector -** -** Returned: -** theta double longitude angle (radians) -** phi double latitude angle (radians) -** r double radial distance -** -** Notes: -** -** 1) If P is null, zero theta, phi and r are returned. -** -** 2) At either pole, zero theta is returned. -** -** Called: -** eraC2s p-vector to spherical -** eraPm modulus of p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraC2s(p, theta, phi); - *r = eraPm(p); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pap.c b/ast/erfa/pap.c deleted file mode 100644 index afd8651..0000000 --- a/ast/erfa/pap.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "erfa.h" - -double eraPap(double a[3], double b[3]) -/* -** - - - - - - - -** e r a P a p -** - - - - - - - -** -** Position-angle from two p-vectors. -** -** Given: -** a double[3] direction of reference point -** b double[3] direction of point whose PA is required -** -** Returned (function value): -** double position angle of b with respect to a (radians) -** -** Notes: -** -** 1) The result is the position angle, in radians, of direction b with -** respect to direction a. It is in the range -pi to +pi. The -** sense is such that if b is a small distance "north" of a the -** position angle is approximately zero, and if b is a small -** distance "east" of a the position angle is approximately +pi/2. -** -** 2) The vectors a and b need not be of unit length. -** -** 3) Zero is returned if the two directions are the same or if either -** vector is null. -** -** 4) If vector a is at a pole, the result is ill-defined. -** -** Called: -** eraPn decompose p-vector into modulus and direction -** eraPm modulus of p-vector -** eraPxp vector product of two p-vectors -** eraPmp p-vector minus p-vector -** eraPdp scalar product of two p-vectors -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double am, au[3], bm, st, ct, xa, ya, za, eta[3], xi[3], a2b[3], pa; - - -/* Modulus and direction of the a vector. */ - eraPn(a, &am, au); - -/* Modulus of the b vector. */ - bm = eraPm(b); - -/* Deal with the case of a null vector. */ - if ((am == 0.0) || (bm == 0.0)) { - st = 0.0; - ct = 1.0; - } else { - - /* The "north" axis tangential from a (arbitrary length). */ - xa = a[0]; - ya = a[1]; - za = a[2]; - eta[0] = -xa * za; - eta[1] = -ya * za; - eta[2] = xa*xa + ya*ya; - - /* The "east" axis tangential from a (same length). */ - eraPxp(eta, au, xi); - - /* The vector from a to b. */ - eraPmp(b, a, a2b); - - /* Resolve into components along the north and east axes. */ - st = eraPdp(a2b, xi); - ct = eraPdp(a2b, eta); - - /* Deal with degenerate cases. */ - if ((st == 0.0) && (ct == 0.0)) ct = 1.0; - } - -/* Position angle. */ - pa = atan2(st, ct); - - return pa; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pas.c b/ast/erfa/pas.c deleted file mode 100644 index 52b3264..0000000 --- a/ast/erfa/pas.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "erfa.h" - -double eraPas(double al, double ap, double bl, double bp) -/* -** - - - - - - - -** e r a P a s -** - - - - - - - -** -** Position-angle from spherical coordinates. -** -** Given: -** al double longitude of point A (e.g. RA) in radians -** ap double latitude of point A (e.g. Dec) in radians -** bl double longitude of point B -** bp double latitude of point B -** -** Returned (function value): -** double position angle of B with respect to A -** -** Notes: -** -** 1) The result is the bearing (position angle), in radians, of point -** B with respect to point A. It is in the range -pi to +pi. The -** sense is such that if B is a small distance "east" of point A, -** the bearing is approximately +pi/2. -** -** 2) Zero is returned if the two points are coincident. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dl, x, y, pa; - - - dl = bl - al; - y = sin(dl) * cos(bp); - x = sin(bp) * cos(ap) - cos(bp) * sin(ap) * cos(dl); - pa = ((x != 0.0) || (y != 0.0)) ? atan2(y, x) : 0.0; - - return pa; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pb06.c b/ast/erfa/pb06.c deleted file mode 100644 index 7b14279..0000000 --- a/ast/erfa/pb06.c +++ /dev/null @@ -1,153 +0,0 @@ -#include "erfa.h" - -void eraPb06(double date1, double date2, - double *bzeta, double *bz, double *btheta) -/* -** - - - - - - - - -** e r a P b 0 6 -** - - - - - - - - -** -** This function forms three Euler angles which implement general -** precession from epoch J2000.0, using the IAU 2006 model. Frame -** bias (the offset between ICRS and mean J2000.0) is included. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** bzeta double 1st rotation: radians cw around z -** bz double 3rd rotation: radians cw around z -** btheta double 2nd rotation: radians ccw around y -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The traditional accumulated precession angles zeta_A, z_A, -** theta_A cannot be obtained in the usual way, namely through -** polynomial expressions, because of the frame bias. The latter -** means that two of the angles undergo rapid changes near this -** date. They are instead the results of decomposing the -** precession-bias matrix obtained by using the Fukushima-Williams -** method, which does not suffer from the problem. The -** decomposition returns values which can be used in the -** conventional formulation and which include frame bias. -** -** 3) The three angles are returned in the conventional order, which -** is not the same as the order of the corresponding Euler -** rotations. The precession-bias matrix is -** R_3(-z) x R_2(+theta) x R_3(-zeta). -** -** 4) Should zeta_A, z_A, theta_A angles be required that do not -** contain frame bias, they are available by calling the ERFA -** function eraP06e. -** -** Called: -** eraPmat06 PB matrix, IAU 2006 -** eraRz rotate around Z-axis -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double r[3][3], r31, r32; - - -/* Precession matrix via Fukushima-Williams angles. */ - eraPmat06(date1, date2, r); - -/* Solve for z. */ - *bz = atan2(r[1][2], r[0][2]); - -/* Remove it from the matrix. */ - eraRz(*bz, r); - -/* Solve for the remaining two angles. */ - *bzeta = atan2 (r[1][0], r[1][1]); - r31 = r[2][0]; - r32 = r[2][1]; - *btheta = atan2(-ERFA_DSIGN(sqrt(r31 * r31 + r32 * r32), r[0][2]), - r[2][2]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pdp.c b/ast/erfa/pdp.c deleted file mode 100644 index 72f1cc0..0000000 --- a/ast/erfa/pdp.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "erfa.h" - -double eraPdp(double a[3], double b[3]) -/* -** - - - - - - - -** e r a P d p -** - - - - - - - -** -** p-vector inner (=scalar=dot) product. -** -** Given: -** a double[3] first p-vector -** b double[3] second p-vector -** -** Returned (function value): -** double a . b -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double w; - - - w = a[0] * b[0] - + a[1] * b[1] - + a[2] * b[2]; - - return w; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pfw06.c b/ast/erfa/pfw06.c deleted file mode 100644 index b510f0a..0000000 --- a/ast/erfa/pfw06.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "erfa.h" - -void eraPfw06(double date1, double date2, - double *gamb, double *phib, double *psib, double *epsa) -/* -** - - - - - - - - - -** e r a P f w 0 6 -** - - - - - - - - - -** -** Precession angles, IAU 2006 (Fukushima-Williams 4-angle formulation). -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** gamb double F-W angle gamma_bar (radians) -** phib double F-W angle phi_bar (radians) -** psib double F-W angle psi_bar (radians) -** epsa double F-W angle epsilon_A (radians) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) Naming the following points: -** -** e = J2000.0 ecliptic pole, -** p = GCRS pole, -** E = mean ecliptic pole of date, -** and P = mean pole of date, -** -** the four Fukushima-Williams angles are as follows: -** -** gamb = gamma_bar = epE -** phib = phi_bar = pE -** psib = psi_bar = pEP -** epsa = epsilon_A = EP -** -** 3) The matrix representing the combined effects of frame bias and -** precession is: -** -** PxB = R_1(-epsa).R_3(-psib).R_1(phib).R_3(gamb) -** -** 4) The matrix representing the combined effects of frame bias, -** precession and nutation is simply: -** -** NxPxB = R_1(-epsa-dE).R_3(-psib-dP).R_1(phib).R_3(gamb) -** -** where dP and dE are the nutation components with respect to the -** ecliptic of date. -** -** Reference: -** -** Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351 -** -** Called: -** eraObl06 mean obliquity, IAU 2006 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t; - - -/* Interval between fundamental date J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* P03 bias+precession angles. */ - *gamb = ( -0.052928 + - ( 10.556378 + - ( 0.4932044 + - ( -0.00031238 + - ( -0.000002788 + - ( 0.0000000260 ) - * t) * t) * t) * t) * t) * ERFA_DAS2R; - *phib = ( 84381.412819 + - ( -46.811016 + - ( 0.0511268 + - ( 0.00053289 + - ( -0.000000440 + - ( -0.0000000176 ) - * t) * t) * t) * t) * t) * ERFA_DAS2R; - *psib = ( -0.041775 + - ( 5038.481484 + - ( 1.5584175 + - ( -0.00018522 + - ( -0.000026452 + - ( -0.0000000148 ) - * t) * t) * t) * t) * t) * ERFA_DAS2R; - *epsa = eraObl06(date1, date2); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/plan94.c b/ast/erfa/plan94.c deleted file mode 100644 index ef878dd..0000000 --- a/ast/erfa/plan94.c +++ /dev/null @@ -1,523 +0,0 @@ -#include "erfa.h" - -int eraPlan94(double date1, double date2, int np, double pv[2][3]) -/* -** - - - - - - - - - - -** e r a P l a n 9 4 -** - - - - - - - - - - -** -** Approximate heliocentric position and velocity of a nominated major -** planet: Mercury, Venus, EMB, Mars, Jupiter, Saturn, Uranus or -** Neptune (but not the Earth itself). -** -** Given: -** date1 double TDB date part A (Note 1) -** date2 double TDB date part B (Note 1) -** np int planet (1=Mercury, 2=Venus, 3=EMB, 4=Mars, -** 5=Jupiter, 6=Saturn, 7=Uranus, 8=Neptune) -** -** Returned (argument): -** pv double[2][3] planet p,v (heliocentric, J2000.0, AU,AU/d) -** -** Returned (function value): -** int status: -1 = illegal NP (outside 1-8) -** 0 = OK -** +1 = warning: year outside 1000-3000 -** +2 = warning: failed to converge -** -** Notes: -** -** 1) The date date1+date2 is in the TDB time scale (in practice TT can -** be used) and is a Julian Date, apportioned in any convenient way -** between the two arguments. For example, JD(TDB)=2450123.7 could -** be expressed in any of these ways, among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. The limited -** accuracy of the present algorithm is such that any of the methods -** is satisfactory. -** -** 2) If an np value outside the range 1-8 is supplied, an error status -** (function value -1) is returned and the pv vector set to zeroes. -** -** 3) For np=3 the result is for the Earth-Moon Barycenter. To obtain -** the heliocentric position and velocity of the Earth, use instead -** the ERFA function eraEpv00. -** -** 4) On successful return, the array pv contains the following: -** -** pv[0][0] x } -** pv[0][1] y } heliocentric position, AU -** pv[0][2] z } -** -** pv[1][0] xdot } -** pv[1][1] ydot } heliocentric velocity, AU/d -** pv[1][2] zdot } -** -** The reference frame is equatorial and is with respect to the -** mean equator and equinox of epoch J2000.0. -** -** 5) The algorithm is due to J.L. Simon, P. Bretagnon, J. Chapront, -** M. Chapront-Touze, G. Francou and J. Laskar (Bureau des -** Longitudes, Paris, France). From comparisons with JPL -** ephemeris DE102, they quote the following maximum errors -** over the interval 1800-2050: -** -** L (arcsec) B (arcsec) R (km) -** -** Mercury 4 1 300 -** Venus 5 1 800 -** EMB 6 1 1000 -** Mars 17 1 7700 -** Jupiter 71 5 76000 -** Saturn 81 13 267000 -** Uranus 86 7 712000 -** Neptune 11 1 253000 -** -** Over the interval 1000-3000, they report that the accuracy is no -** worse than 1.5 times that over 1800-2050. Outside 1000-3000 the -** accuracy declines. -** -** Comparisons of the present function with the JPL DE200 ephemeris -** give the following RMS errors over the interval 1960-2025: -** -** position (km) velocity (m/s) -** -** Mercury 334 0.437 -** Venus 1060 0.855 -** EMB 2010 0.815 -** Mars 7690 1.98 -** Jupiter 71700 7.70 -** Saturn 199000 19.4 -** Uranus 564000 16.4 -** Neptune 158000 14.4 -** -** Comparisons against DE200 over the interval 1800-2100 gave the -** following maximum absolute differences. (The results using -** DE406 were essentially the same.) -** -** L (arcsec) B (arcsec) R (km) Rdot (m/s) -** -** Mercury 7 1 500 0.7 -** Venus 7 1 1100 0.9 -** EMB 9 1 1300 1.0 -** Mars 26 1 9000 2.5 -** Jupiter 78 6 82000 8.2 -** Saturn 87 14 263000 24.6 -** Uranus 86 7 661000 27.4 -** Neptune 11 2 248000 21.4 -** -** 6) The present ERFA re-implementation of the original Simon et al. -** Fortran code differs from the original in the following respects: -** -** * C instead of Fortran. -** -** * The date is supplied in two parts. -** -** * The result is returned only in equatorial Cartesian form; -** the ecliptic longitude, latitude and radius vector are not -** returned. -** -** * The result is in the J2000.0 equatorial frame, not ecliptic. -** -** * More is done in-line: there are fewer calls to subroutines. -** -** * Different error/warning status values are used. -** -** * A different Kepler's-equation-solver is used (avoiding -** use of double precision complex). -** -** * Polynomials in t are nested to minimize rounding errors. -** -** * Explicit double constants are used to avoid mixed-mode -** expressions. -** -** None of the above changes affects the result significantly. -** -** 7) The returned status indicates the most serious condition -** encountered during execution of the function. Illegal np is -** considered the most serious, overriding failure to converge, -** which in turn takes precedence over the remote date warning. -** -** Called: -** eraAnp normalize angle into range 0 to 2pi -** -** Reference: Simon, J.L, Bretagnon, P., Chapront, J., -** Chapront-Touze, M., Francou, G., and Laskar, J., -** Astron. Astrophys. 282, 663 (1994). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Gaussian constant */ - static const double GK = 0.017202098950; - -/* Sin and cos of J2000.0 mean obliquity (IAU 1976) */ - static const double SINEPS = 0.3977771559319137; - static const double COSEPS = 0.9174820620691818; - -/* Maximum number of iterations allowed to solve Kepler's equation */ - static const int KMAX = 10; - - int jstat, i, k; - double t, da, dl, de, dp, di, dom, dmu, arga, argl, am, - ae, dae, ae2, at, r, v, si2, xq, xp, tl, xsw, - xcw, xm2, xf, ci2, xms, xmc, xpxq2, x, y, z; - -/* Planetary inverse masses */ - static const double amas[] = { 6023600.0, /* Mercury */ - 408523.5, /* Venus */ - 328900.5, /* EMB */ - 3098710.0, /* Mars */ - 1047.355, /* Jupiter */ - 3498.5, /* Saturn */ - 22869.0, /* Uranus */ - 19314.0 }; /* Neptune */ - -/* -** Tables giving the mean Keplerian elements, limited to t^2 terms: -** -** a semi-major axis (AU) -** dlm mean longitude (degree and arcsecond) -** e eccentricity -** pi longitude of the perihelion (degree and arcsecond) -** dinc inclination (degree and arcsecond) -** omega longitude of the ascending node (degree and arcsecond) -*/ - - static const double a[][3] = { - { 0.3870983098, 0.0, 0.0 }, /* Mercury */ - { 0.7233298200, 0.0, 0.0 }, /* Venus */ - { 1.0000010178, 0.0, 0.0 }, /* EMB */ - { 1.5236793419, 3e-10, 0.0 }, /* Mars */ - { 5.2026032092, 19132e-10, -39e-10 }, /* Jupiter */ - { 9.5549091915, -0.0000213896, 444e-10 }, /* Saturn */ - { 19.2184460618, -3716e-10, 979e-10 }, /* Uranus */ - { 30.1103868694, -16635e-10, 686e-10 } /* Neptune */ - }; - - static const double dlm[][3] = { - { 252.25090552, 5381016286.88982, -1.92789 }, - { 181.97980085, 2106641364.33548, 0.59381 }, - { 100.46645683, 1295977422.83429, -2.04411 }, - { 355.43299958, 689050774.93988, 0.94264 }, - { 34.35151874, 109256603.77991, -30.60378 }, - { 50.07744430, 43996098.55732, 75.61614 }, - { 314.05500511, 15424811.93933, -1.75083 }, - { 304.34866548, 7865503.20744, 0.21103 } - }; - - static const double e[][3] = { - { 0.2056317526, 0.0002040653, -28349e-10 }, - { 0.0067719164, -0.0004776521, 98127e-10 }, - { 0.0167086342, -0.0004203654, -0.0000126734 }, - { 0.0934006477, 0.0009048438, -80641e-10 }, - { 0.0484979255, 0.0016322542, -0.0000471366 }, - { 0.0555481426, -0.0034664062, -0.0000643639 }, - { 0.0463812221, -0.0002729293, 0.0000078913 }, - { 0.0094557470, 0.0000603263, 0.0 } - }; - - static const double pi[][3] = { - { 77.45611904, 5719.11590, -4.83016 }, - { 131.56370300, 175.48640, -498.48184 }, - { 102.93734808, 11612.35290, 53.27577 }, - { 336.06023395, 15980.45908, -62.32800 }, - { 14.33120687, 7758.75163, 259.95938 }, - { 93.05723748, 20395.49439, 190.25952 }, - { 173.00529106, 3215.56238, -34.09288 }, - { 48.12027554, 1050.71912, 27.39717 } - }; - - static const double dinc[][3] = { - { 7.00498625, -214.25629, 0.28977 }, - { 3.39466189, -30.84437, -11.67836 }, - { 0.0, 469.97289, -3.35053 }, - { 1.84972648, -293.31722, -8.11830 }, - { 1.30326698, -71.55890, 11.95297 }, - { 2.48887878, 91.85195, -17.66225 }, - { 0.77319689, -60.72723, 1.25759 }, - { 1.76995259, 8.12333, 0.08135 } - }; - - static const double omega[][3] = { - { 48.33089304, -4515.21727, -31.79892 }, - { 76.67992019, -10008.48154, -51.32614 }, - { 174.87317577, -8679.27034, 15.34191 }, - { 49.55809321, -10620.90088, -230.57416 }, - { 100.46440702, 6362.03561, 326.52178 }, - { 113.66550252, -9240.19942, -66.23743 }, - { 74.00595701, 2669.15033, 145.93964 }, - { 131.78405702, -221.94322, -0.78728 } - }; - -/* Tables for trigonometric terms to be added to the mean elements of */ -/* the semi-major axes */ - - static const double kp[][9] = { - { 69613, 75645, 88306, 59899, 15746, 71087, 142173, 3086, 0 }, - { 21863, 32794, 26934, 10931, 26250, 43725, 53867, 28939, 0 }, - { 16002, 21863, 32004, 10931, 14529, 16368, 15318, 32794, 0 }, - { 6345, 7818, 15636, 7077, 8184, 14163, 1107, 4872, 0 }, - { 1760, 1454, 1167, 880, 287, 2640, 19, 2047, 1454 }, - { 574, 0, 880, 287, 19, 1760, 1167, 306, 574 }, - { 204, 0, 177, 1265, 4, 385, 200, 208, 204 }, - { 0, 102, 106, 4, 98, 1367, 487, 204, 0 } - }; - - static const double ca[][9] = { - { 4, -13, 11, -9, -9, -3, -1, 4, 0 }, - { -156, 59, -42, 6, 19, -20, -10, -12, 0 }, - { 64, -152, 62, -8, 32, -41, 19, -11, 0 }, - { 124, 621, -145, 208, 54, -57, 30, 15, 0 }, - { -23437, -2634, 6601, 6259, -1507,-1821, 2620, -2115, -1489 }, - { 62911,-119919, 79336,17814,-24241,12068, 8306, -4893, 8902 }, - { 389061,-262125,-44088, 8387,-22976,-2093, -615, -9720, 6633 }, - { -412235,-157046,-31430,37817, -9740, -13, -7449, 9644, 0 } - }; - - static const double sa[][9] = { - { -29, -1, 9, 6, -6, 5, 4, 0, 0 }, - { -48, -125, -26, -37, 18, -13, -20, -2, 0 }, - { -150, -46, 68, 54, 14, 24, -28, 22, 0 }, - { -621, 532, -694, -20, 192, -94, 71, -73, 0 }, - { -14614,-19828, -5869, 1881, -4372, -2255, 782, 930, 913 }, - { 139737, 0, 24667, 51123, -5102, 7429, -4095, -1976, -9566 }, - { -138081, 0, 37205,-49039,-41901,-33872,-27037,-12474, 18797 }, - { 0, 28492,133236, 69654, 52322,-49577,-26430, -3593, 0 } - }; - -/* Tables giving the trigonometric terms to be added to the mean */ -/* elements of the mean longitudes */ - - static const double kq[][10] = { - { 3086,15746,69613,59899,75645,88306, 12661, 2658, 0, 0 }, - { 21863,32794,10931, 73, 4387,26934, 1473, 2157, 0, 0 }, - { 10,16002,21863,10931, 1473,32004, 4387, 73, 0, 0 }, - { 10, 6345, 7818, 1107,15636, 7077, 8184, 532, 10, 0 }, - { 19, 1760, 1454, 287, 1167, 880, 574, 2640, 19, 1454 }, - { 19, 574, 287, 306, 1760, 12, 31, 38, 19, 574 }, - { 4, 204, 177, 8, 31, 200, 1265, 102, 4, 204 }, - { 4, 102, 106, 8, 98, 1367, 487, 204, 4, 102 } - }; - - static const double cl[][10] = { - { 21, -95, -157, 41, -5, 42, 23, 30, 0, 0 }, - { -160, -313, -235, 60, -74, -76, -27, 34, 0, 0 }, - { -325, -322, -79, 232, -52, 97, 55, -41, 0, 0 }, - { 2268, -979, 802, 602, -668, -33, 345, 201, -55, 0 }, - { 7610, -4997,-7689,-5841,-2617, 1115,-748,-607, 6074, 354 }, - { -18549, 30125,20012, -730, 824, 23,1289,-352, -14767, -2062 }, - { -135245,-14594, 4197,-4030,-5630,-2898,2540,-306, 2939, 1986 }, - { 89948, 2103, 8963, 2695, 3682, 1648, 866,-154, -1963, -283 } - }; - - static const double sl[][10] = { - { -342, 136, -23, 62, 66, -52, -33, 17, 0, 0 }, - { 524, -149, -35, 117, 151, 122, -71, -62, 0, 0 }, - { -105, -137, 258, 35, -116, -88,-112, -80, 0, 0 }, - { 854, -205, -936, -240, 140, -341, -97, -232, 536, 0 }, - { -56980, 8016, 1012, 1448,-3024,-3710, 318, 503, 3767, 577 }, - { 138606,-13478,-4964, 1441,-1319,-1482, 427, 1236, -9167, -1918 }, - { 71234,-41116, 5334,-4935,-1848, 66, 434, -1748, 3780, -701 }, - { -47645, 11647, 2166, 3194, 679, 0,-244, -419, -2531, 48 } - }; - -/*--------------------------------------------------------------------*/ - -/* Validate the planet number. */ - if ((np < 1) || (np > 8)) { - jstat = -1; - - /* Reset the result in case of failure. */ - for (k = 0; k < 2; k++) { - for (i = 0; i < 3; i++) { - pv[k][i] = 0.0; - } - } - - } else { - - /* Decrement the planet number to start at zero. */ - np--; - - /* Time: Julian millennia since J2000.0. */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJM; - - /* OK status unless remote date. */ - jstat = fabs(t) <= 1.0 ? 0 : 1; - - /* Compute the mean elements. */ - da = a[np][0] + - (a[np][1] + - a[np][2] * t) * t; - dl = (3600.0 * dlm[np][0] + - (dlm[np][1] + - dlm[np][2] * t) * t) * ERFA_DAS2R; - de = e[np][0] + - ( e[np][1] + - e[np][2] * t) * t; - dp = eraAnpm((3600.0 * pi[np][0] + - (pi[np][1] + - pi[np][2] * t) * t) * ERFA_DAS2R); - di = (3600.0 * dinc[np][0] + - (dinc[np][1] + - dinc[np][2] * t) * t) * ERFA_DAS2R; - dom = eraAnpm((3600.0 * omega[np][0] + - (omega[np][1] + - omega[np][2] * t) * t) * ERFA_DAS2R); - - /* Apply the trigonometric terms. */ - dmu = 0.35953620 * t; - for (k = 0; k < 8; k++) { - arga = kp[np][k] * dmu; - argl = kq[np][k] * dmu; - da += (ca[np][k] * cos(arga) + - sa[np][k] * sin(arga)) * 1e-7; - dl += (cl[np][k] * cos(argl) + - sl[np][k] * sin(argl)) * 1e-7; - } - arga = kp[np][8] * dmu; - da += t * (ca[np][8] * cos(arga) + - sa[np][8] * sin(arga)) * 1e-7; - for (k = 8; k < 10; k++) { - argl = kq[np][k] * dmu; - dl += t * (cl[np][k] * cos(argl) + - sl[np][k] * sin(argl)) * 1e-7; - } - dl = fmod(dl, ERFA_D2PI); - - /* Iterative soln. of Kepler's equation to get eccentric anomaly. */ - am = dl - dp; - ae = am + de * sin(am); - k = 0; - dae = 1.0; - while (k < KMAX && fabs(dae) > 1e-12) { - dae = (am - ae + de * sin(ae)) / (1.0 - de * cos(ae)); - ae += dae; - k++; - if (k == KMAX-1) jstat = 2; - } - - /* True anomaly. */ - ae2 = ae / 2.0; - at = 2.0 * atan2(sqrt((1.0 + de) / (1.0 - de)) * sin(ae2), - cos(ae2)); - - /* Distance (AU) and speed (radians per day). */ - r = da * (1.0 - de * cos(ae)); - v = GK * sqrt((1.0 + 1.0 / amas[np]) / (da * da * da)); - - si2 = sin(di / 2.0); - xq = si2 * cos(dom); - xp = si2 * sin(dom); - tl = at + dp; - xsw = sin(tl); - xcw = cos(tl); - xm2 = 2.0 * (xp * xcw - xq * xsw); - xf = da / sqrt(1 - de * de); - ci2 = cos(di / 2.0); - xms = (de * sin(dp) + xsw) * xf; - xmc = (de * cos(dp) + xcw) * xf; - xpxq2 = 2 * xp * xq; - - /* Position (J2000.0 ecliptic x,y,z in AU). */ - x = r * (xcw - xm2 * xp); - y = r * (xsw + xm2 * xq); - z = r * (-xm2 * ci2); - - /* Rotate to equatorial. */ - pv[0][0] = x; - pv[0][1] = y * COSEPS - z * SINEPS; - pv[0][2] = y * SINEPS + z * COSEPS; - - /* Velocity (J2000.0 ecliptic xdot,ydot,zdot in AU/d). */ - x = v * (( -1.0 + 2.0 * xp * xp) * xms + xpxq2 * xmc); - y = v * (( 1.0 - 2.0 * xq * xq) * xmc - xpxq2 * xms); - z = v * (2.0 * ci2 * (xp * xms + xq * xmc)); - - /* Rotate to equatorial. */ - pv[1][0] = x; - pv[1][1] = y * COSEPS - z * SINEPS; - pv[1][2] = y * SINEPS + z * COSEPS; - - } - -/* Return the status. */ - return jstat; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pm.c b/ast/erfa/pm.c deleted file mode 100644 index 6b08fa7..0000000 --- a/ast/erfa/pm.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "erfa.h" - -double eraPm(double p[3]) -/* -** - - - - - - -** e r a P m -** - - - - - - -** -** Modulus of p-vector. -** -** Given: -** p double[3] p-vector -** -** Returned (function value): -** double modulus -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - return sqrt( p[0]*p[0] + p[1]*p[1] + p[2]*p[2] ); - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pmat00.c b/ast/erfa/pmat00.c deleted file mode 100644 index e25315a..0000000 --- a/ast/erfa/pmat00.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "erfa.h" - -void eraPmat00(double date1, double date2, double rbp[3][3]) -/* -** - - - - - - - - - - -** e r a P m a t 0 0 -** - - - - - - - - - - -** -** Precession matrix (including frame bias) from GCRS to a specified -** date, IAU 2000 model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rbp double[3][3] bias-precession matrix (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(date) = rbp * V(GCRS), where -** the p-vector V(GCRS) is with respect to the Geocentric Celestial -** Reference System (IAU, 2000) and the p-vector V(date) is with -** respect to the mean equatorial triad of the given date. -** -** Called: -** eraBp00 frame bias and precession matrices, IAU 2000 -** -** Reference: -** -** IAU: Trans. International Astronomical Union, Vol. XXIVB; Proc. -** 24th General Assembly, Manchester, UK. Resolutions B1.3, B1.6. -** (2000) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rb[3][3], rp[3][3]; - - -/* Obtain the required matrix (discarding others). */ - eraBp00(date1, date2, rb, rp, rbp); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pmat06.c b/ast/erfa/pmat06.c deleted file mode 100644 index 364211a..0000000 --- a/ast/erfa/pmat06.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "erfa.h" - -void eraPmat06(double date1, double date2, double rbp[3][3]) -/* -** - - - - - - - - - - -** e r a P m a t 0 6 -** - - - - - - - - - - -** -** Precession matrix (including frame bias) from GCRS to a specified -** date, IAU 2006 model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rbp double[3][3] bias-precession matrix (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(date) = rbp * V(GCRS), where -** the p-vector V(GCRS) is with respect to the Geocentric Celestial -** Reference System (IAU, 2000) and the p-vector V(date) is with -** respect to the mean equatorial triad of the given date. -** -** Called: -** eraPfw06 bias-precession F-W angles, IAU 2006 -** eraFw2m F-W angles to r-matrix -** -** References: -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855 -** -** Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double gamb, phib, psib, epsa; - - -/* Bias-precession Fukushima-Williams angles. */ - eraPfw06(date1, date2, &gamb, &phib, &psib, &epsa); - -/* Form the matrix. */ - eraFw2m(gamb, phib, psib, epsa, rbp); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pmat76.c b/ast/erfa/pmat76.c deleted file mode 100644 index c38e6c4..0000000 --- a/ast/erfa/pmat76.c +++ /dev/null @@ -1,150 +0,0 @@ -#include "erfa.h" - -void eraPmat76(double date1, double date2, double rmatp[3][3]) -/* -** - - - - - - - - - - -** e r a P m a t 7 6 -** - - - - - - - - - - -** -** Precession matrix from J2000.0 to a specified date, IAU 1976 model. -** -** Given: -** date1,date2 double ending date, TT (Note 1) -** -** Returned: -** rmatp double[3][3] precession matrix, J2000.0 -> date1+date2 -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(date) = RMATP * V(J2000), -** where the p-vector V(J2000) is with respect to the mean -** equatorial triad of epoch J2000.0 and the p-vector V(date) -** is with respect to the mean equatorial triad of the given -** date. -** -** 3) Though the matrix method itself is rigorous, the precession -** angles are expressed through canonical polynomials which are -** valid only for a limited time span. In addition, the IAU 1976 -** precession rate is known to be imperfect. The absolute accuracy -** of the present formulation is better than 0.1 arcsec from -** 1960AD to 2040AD, better than 1 arcsec from 1640AD to 2360AD, -** and remains below 3 arcsec for the whole of the period -** 500BC to 3000AD. The errors exceed 10 arcsec outside the -** range 1200BC to 3900AD, exceed 100 arcsec outside 4200BC to -** 5600AD and exceed 1000 arcsec outside 6800BC to 8200AD. -** -** Called: -** eraPrec76 accumulated precession angles, IAU 1976 -** eraIr initialize r-matrix to identity -** eraRz rotate around Z-axis -** eraRy rotate around Y-axis -** eraCr copy r-matrix -** -** References: -** -** Lieske, J.H., 1979, Astron.Astrophys. 73, 282. -** equations (6) & (7), p283. -** -** Kaplan,G.H., 1981. USNO circular no. 163, pA2. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double zeta, z, theta, wmat[3][3]; - - -/* Precession Euler angles, J2000.0 to specified date. */ - eraPrec76(ERFA_DJ00, 0.0, date1, date2, &zeta, &z, &theta); - -/* Form the rotation matrix. */ - eraIr( wmat); - eraRz( -zeta, wmat); - eraRy( theta, wmat); - eraRz( -z, wmat); - eraCr( wmat, rmatp); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pmp.c b/ast/erfa/pmp.c deleted file mode 100644 index e11c12e..0000000 --- a/ast/erfa/pmp.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "erfa.h" - -void eraPmp(double a[3], double b[3], double amb[3]) -/* -** - - - - - - - -** e r a P m p -** - - - - - - - -** -** P-vector subtraction. -** -** Given: -** a double[3] first p-vector -** b double[3] second p-vector -** -** Returned: -** amb double[3] a - b -** -** Note: -** It is permissible to re-use the same array for any of the -** arguments. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - amb[0] = a[0] - b[0]; - amb[1] = a[1] - b[1]; - amb[2] = a[2] - b[2]; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pmpx.c b/ast/erfa/pmpx.c deleted file mode 100644 index 034e8f0..0000000 --- a/ast/erfa/pmpx.c +++ /dev/null @@ -1,153 +0,0 @@ -#include "erfa.h" - -void eraPmpx(double rc, double dc, double pr, double pd, - double px, double rv, double pmt, double pob[3], - double pco[3]) -/* -** - - - - - - - - -** e r a P m p x -** - - - - - - - - -** -** Proper motion and parallax. -** -** Given: -** rc,dc double ICRS RA,Dec at catalog epoch (radians) -** pr double RA proper motion (radians/year; Note 1) -** pd double Dec proper motion (radians/year) -** px double parallax (arcsec) -** rv double radial velocity (km/s, +ve if receding) -** pmt double proper motion time interval (SSB, Julian years) -** pob double[3] SSB to observer vector (au) -** -** Returned: -** pco double[3] coordinate direction (BCRS unit vector) -** -** Notes: -** -** 1) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt. -** -** 2) The proper motion time interval is for when the starlight -** reaches the solar system barycenter. -** -** 3) To avoid the need for iteration, the Roemer effect (i.e. the -** small annual modulation of the proper motion coming from the -** changing light time) is applied approximately, using the -** direction of the star at the catalog epoch. -** -** References: -** -** 1984 Astronomical Almanac, pp B39-B41. -** -** Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to -** the Astronomical Almanac, 3rd ed., University Science Books -** (2013), Section 7.2. -** -** Called: -** eraPdp scalar product of two p-vectors -** eraPn decompose p-vector into modulus and direction -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Km/s to au/year */ - const double VF = ERFA_DAYSEC*ERFA_DJM/ERFA_DAU; - -/* Light time for 1 au, Julian years */ - const double AULTY = ERFA_AULT/ERFA_DAYSEC/ERFA_DJY; - - int i; - double sr, cr, sd, cd, x, y, z, p[3], dt, pxr, w, pdz, pm[3]; - - -/* Spherical coordinates to unit vector (and useful functions). */ - sr = sin(rc); - cr = cos(rc); - sd = sin(dc); - cd = cos(dc); - p[0] = x = cr*cd; - p[1] = y = sr*cd; - p[2] = z = sd; - -/* Proper motion time interval (y) including Roemer effect. */ - dt = pmt + eraPdp(p,pob)*AULTY; - -/* Space motion (radians per year). */ - pxr = px * ERFA_DAS2R; - w = VF * rv * pxr; - pdz = pd * z; - pm[0] = - pr*y - pdz*cr + w*x; - pm[1] = pr*x - pdz*sr + w*y; - pm[2] = pd*cd + w*z; - -/* Coordinate direction of star (unit vector, BCRS). */ - for (i = 0; i < 3; i++) { - p[i] += dt*pm[i] - pxr*pob[i]; - } - eraPn(p, &w, pco); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pmsafe.c b/ast/erfa/pmsafe.c deleted file mode 100644 index 02e5824..0000000 --- a/ast/erfa/pmsafe.c +++ /dev/null @@ -1,206 +0,0 @@ -#include "erfa.h" - -int eraPmsafe(double ra1, double dec1, double pmr1, double pmd1, - double px1, double rv1, - double ep1a, double ep1b, double ep2a, double ep2b, - double *ra2, double *dec2, double *pmr2, double *pmd2, - double *px2, double *rv2) -/* -** - - - - - - - - - - -** e r a P m s a f e -** - - - - - - - - - - -** -** Star proper motion: update star catalog data for space motion, with -** special handling to handle the zero parallax case. -** -** Given: -** ra1 double right ascension (radians), before -** dec1 double declination (radians), before -** pmr1 double RA proper motion (radians/year), before -** pmd1 double Dec proper motion (radians/year), before -** px1 double parallax (arcseconds), before -** rv1 double radial velocity (km/s, +ve = receding), before -** ep1a double "before" epoch, part A (Note 1) -** ep1b double "before" epoch, part B (Note 1) -** ep2a double "after" epoch, part A (Note 1) -** ep2b double "after" epoch, part B (Note 1) -** -** Returned: -** ra2 double right ascension (radians), after -** dec2 double declination (radians), after -** pmr2 double RA proper motion (radians/year), after -** pmd2 double Dec proper motion (radians/year), after -** px2 double parallax (arcseconds), after -** rv2 double radial velocity (km/s, +ve = receding), after -** -** Returned (function value): -** int status: -** -1 = system error (should not occur) -** 0 = no warnings or errors -** 1 = distance overridden (Note 6) -** 2 = excessive velocity (Note 7) -** 4 = solution didn't converge (Note 8) -** else = binary logical OR of the above warnings -** -** Notes: -** -** 1) The starting and ending TDB epochs ep1a+ep1b and ep2a+ep2b are -** Julian Dates, apportioned in any convenient way between the two -** parts (A and B). For example, JD(TDB)=2450123.7 could be -** expressed in any of these ways, among others: -** -** epNa epNb -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** resolution. The MJD method and the date & time methods are both -** good compromises between resolution and convenience. -** -** 2) In accordance with normal star-catalog conventions, the object's -** right ascension and declination are freed from the effects of -** secular aberration. The frame, which is aligned to the catalog -** equator and equinox, is Lorentzian and centered on the SSB. -** -** The proper motions are the rate of change of the right ascension -** and declination at the catalog epoch and are in radians per TDB -** Julian year. -** -** The parallax and radial velocity are in the same frame. -** -** 3) Care is needed with units. The star coordinates are in radians -** and the proper motions in radians per Julian year, but the -** parallax is in arcseconds. -** -** 4) The RA proper motion is in terms of coordinate angle, not true -** angle. If the catalog uses arcseconds for both RA and Dec proper -** motions, the RA proper motion will need to be divided by cos(Dec) -** before use. -** -** 5) Straight-line motion at constant speed, in the inertial frame, is -** assumed. -** -** 6) An extremely small (or zero or negative) parallax is overridden -** to ensure that the object is at a finite but very large distance, -** but not so large that the proper motion is equivalent to a large -** but safe speed (about 0.1c using the chosen constant). A warning -** status of 1 is added to the status if this action has been taken. -** -** 7) If the space velocity is a significant fraction of c (see the -** constant VMAX in the function eraStarpv), it is arbitrarily set -** to zero. When this action occurs, 2 is added to the status. -** -** 8) The relativistic adjustment carried out in the eraStarpv function -** involves an iterative calculation. If the process fails to -** converge within a set number of iterations, 4 is added to the -** status. -** -** Called: -** eraSeps angle between two points -** eraStarpm update star catalog data for space motion -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* Minimum allowed parallax (arcsec) */ - const double PXMIN = 5e-7; - -/* Factor giving maximum allowed transverse speed of about 1% c */ - const double F = 326.0; - - int jpx, j; - double pm, px1a; - - -/* Proper motion in one year (radians). */ - pm = eraSeps(ra1, dec1, ra1+pmr1, dec1+pmd1); - -/* Override the parallax to reduce the chances of a warning status. */ - jpx = 0; - px1a = px1; - pm *= F; - if (px1a < pm) {jpx = 1; px1a = pm;} - if (px1a < PXMIN) {jpx = 1; px1a = PXMIN;} - -/* Carry out the transformation using the modified parallax. */ - j = eraStarpm(ra1, dec1, pmr1, pmd1, px1a, rv1, - ep1a, ep1b, ep2a, ep2b, - ra2, dec2, pmr2, pmd2, px2, rv2); - -/* Revise and return the status. */ - if ( !(j%2) ) j += jpx; - return j; - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pn.c b/ast/erfa/pn.c deleted file mode 100644 index 7bdebbb..0000000 --- a/ast/erfa/pn.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "erfa.h" - -void eraPn(double p[3], double *r, double u[3]) -/* -** - - - - - - -** e r a P n -** - - - - - - -** -** Convert a p-vector into modulus and unit vector. -** -** Given: -** p double[3] p-vector -** -** Returned: -** r double modulus -** u double[3] unit vector -** -** Notes: -** -** 1) If p is null, the result is null. Otherwise the result is a unit -** vector. -** -** 2) It is permissible to re-use the same array for any of the -** arguments. -** -** Called: -** eraPm modulus of p-vector -** eraZp zero p-vector -** eraSxp multiply p-vector by scalar -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double w; - - -/* Obtain the modulus and test for zero. */ - w = eraPm(p); - if (w == 0.0) { - - /* Null vector. */ - eraZp(u); - - } else { - - /* Unit vector. */ - eraSxp(1.0/w, p, u); - } - -/* Return the modulus. */ - *r = w; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pn00.c b/ast/erfa/pn00.c deleted file mode 100644 index f088649..0000000 --- a/ast/erfa/pn00.c +++ /dev/null @@ -1,186 +0,0 @@ -#include "erfa.h" - -void eraPn00(double date1, double date2, double dpsi, double deps, - double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]) -/* -** - - - - - - - - -** e r a P n 0 0 -** - - - - - - - - -** -** Precession-nutation, IAU 2000 model: a multi-purpose function, -** supporting classical (equinox-based) use directly and CIO-based -** use indirectly. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** dpsi,deps double nutation (Note 2) -** -** Returned: -** epsa double mean obliquity (Note 3) -** rb double[3][3] frame bias matrix (Note 4) -** rp double[3][3] precession matrix (Note 5) -** rbp double[3][3] bias-precession matrix (Note 6) -** rn double[3][3] nutation matrix (Note 7) -** rbpn double[3][3] GCRS-to-true matrix (Note 8) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The caller is responsible for providing the nutation components; -** they are in longitude and obliquity, in radians and are with -** respect to the equinox and ecliptic of date. For high-accuracy -** applications, free core nutation should be included as well as -** any other relevant corrections to the position of the CIP. -** -** 3) The returned mean obliquity is consistent with the IAU 2000 -** precession-nutation models. -** -** 4) The matrix rb transforms vectors from GCRS to J2000.0 mean -** equator and equinox by applying frame bias. -** -** 5) The matrix rp transforms vectors from J2000.0 mean equator and -** equinox to mean equator and equinox of date by applying -** precession. -** -** 6) The matrix rbp transforms vectors from GCRS to mean equator and -** equinox of date by applying frame bias then precession. It is -** the product rp x rb. -** -** 7) The matrix rn transforms vectors from mean equator and equinox of -** date to true equator and equinox of date by applying the nutation -** (luni-solar + planetary). -** -** 8) The matrix rbpn transforms vectors from GCRS to true equator and -** equinox of date. It is the product rn x rbp, applying frame -** bias, precession and nutation in that order. -** -** 9) It is permissible to re-use the same array in the returned -** arguments. The arrays are filled in the order given. -** -** Called: -** eraPr00 IAU 2000 precession adjustments -** eraObl80 mean obliquity, IAU 1980 -** eraBp00 frame bias and precession matrices, IAU 2000 -** eraCr copy r-matrix -** eraNumat form nutation matrix -** eraRxr product of two r-matrices -** -** Reference: -** -** Capitaine, N., Chapront, J., Lambert, S. and Wallace, P., -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dpsipr, depspr, rbpw[3][3], rnw[3][3]; - - -/* IAU 2000 precession-rate adjustments. */ - eraPr00(date1, date2, &dpsipr, &depspr); - -/* Mean obliquity, consistent with IAU 2000 precession-nutation. */ - *epsa = eraObl80(date1, date2) + depspr; - -/* Frame bias and precession matrices and their product. */ - eraBp00(date1, date2, rb, rp, rbpw); - eraCr(rbpw, rbp); - -/* Nutation matrix. */ - eraNumat(*epsa, dpsi, deps, rnw); - eraCr(rnw, rn); - -/* Bias-precession-nutation matrix (classical). */ - eraRxr(rnw, rbpw, rbpn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pn00a.c b/ast/erfa/pn00a.c deleted file mode 100644 index 3e47f0e..0000000 --- a/ast/erfa/pn00a.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "erfa.h" - -void eraPn00a(double date1, double date2, - double *dpsi, double *deps, double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]) -/* -** - - - - - - - - - -** e r a P n 0 0 a -** - - - - - - - - - -** -** Precession-nutation, IAU 2000A model: a multi-purpose function, -** supporting classical (equinox-based) use directly and CIO-based -** use indirectly. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** dpsi,deps double nutation (Note 2) -** epsa double mean obliquity (Note 3) -** rb double[3][3] frame bias matrix (Note 4) -** rp double[3][3] precession matrix (Note 5) -** rbp double[3][3] bias-precession matrix (Note 6) -** rn double[3][3] nutation matrix (Note 7) -** rbpn double[3][3] GCRS-to-true matrix (Notes 8,9) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The nutation components (luni-solar + planetary, IAU 2000A) in -** longitude and obliquity are in radians and with respect to the -** equinox and ecliptic of date. Free core nutation is omitted; -** for the utmost accuracy, use the eraPn00 function, where the -** nutation components are caller-specified. For faster but -** slightly less accurate results, use the eraPn00b function. -** -** 3) The mean obliquity is consistent with the IAU 2000 precession. -** -** 4) The matrix rb transforms vectors from GCRS to J2000.0 mean -** equator and equinox by applying frame bias. -** -** 5) The matrix rp transforms vectors from J2000.0 mean equator and -** equinox to mean equator and equinox of date by applying -** precession. -** -** 6) The matrix rbp transforms vectors from GCRS to mean equator and -** equinox of date by applying frame bias then precession. It is -** the product rp x rb. -** -** 7) The matrix rn transforms vectors from mean equator and equinox -** of date to true equator and equinox of date by applying the -** nutation (luni-solar + planetary). -** -** 8) The matrix rbpn transforms vectors from GCRS to true equator and -** equinox of date. It is the product rn x rbp, applying frame -** bias, precession and nutation in that order. -** -** 9) The X,Y,Z coordinates of the IAU 2000A Celestial Intermediate -** Pole are elements (3,1-3) of the GCRS-to-true matrix, -** i.e. rbpn[2][0-2]. -** -** 10) It is permissible to re-use the same array in the returned -** arguments. The arrays are filled in the order given. -** -** Called: -** eraNut00a nutation, IAU 2000A -** eraPn00 bias/precession/nutation results, IAU 2000 -** -** Reference: -** -** Capitaine, N., Chapront, J., Lambert, S. and Wallace, P., -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Nutation. */ - eraNut00a(date1, date2, dpsi, deps); - -/* Remaining results. */ - eraPn00(date1, date2, *dpsi, *deps, epsa, rb, rp, rbp, rn, rbpn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pn00b.c b/ast/erfa/pn00b.c deleted file mode 100644 index d93376f..0000000 --- a/ast/erfa/pn00b.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "erfa.h" - -void eraPn00b(double date1, double date2, - double *dpsi, double *deps, double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]) -/* -** - - - - - - - - - -** e r a P n 0 0 b -** - - - - - - - - - -** -** Precession-nutation, IAU 2000B model: a multi-purpose function, -** supporting classical (equinox-based) use directly and CIO-based -** use indirectly. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** dpsi,deps double nutation (Note 2) -** epsa double mean obliquity (Note 3) -** rb double[3][3] frame bias matrix (Note 4) -** rp double[3][3] precession matrix (Note 5) -** rbp double[3][3] bias-precession matrix (Note 6) -** rn double[3][3] nutation matrix (Note 7) -** rbpn double[3][3] GCRS-to-true matrix (Notes 8,9) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The nutation components (luni-solar + planetary, IAU 2000B) in -** longitude and obliquity are in radians and with respect to the -** equinox and ecliptic of date. For more accurate results, but -** at the cost of increased computation, use the eraPn00a function. -** For the utmost accuracy, use the eraPn00 function, where the -** nutation components are caller-specified. -** -** 3) The mean obliquity is consistent with the IAU 2000 precession. -** -** 4) The matrix rb transforms vectors from GCRS to J2000.0 mean -** equator and equinox by applying frame bias. -** -** 5) The matrix rp transforms vectors from J2000.0 mean equator and -** equinox to mean equator and equinox of date by applying -** precession. -** -** 6) The matrix rbp transforms vectors from GCRS to mean equator and -** equinox of date by applying frame bias then precession. It is -** the product rp x rb. -** -** 7) The matrix rn transforms vectors from mean equator and equinox -** of date to true equator and equinox of date by applying the -** nutation (luni-solar + planetary). -** -** 8) The matrix rbpn transforms vectors from GCRS to true equator and -** equinox of date. It is the product rn x rbp, applying frame -** bias, precession and nutation in that order. -** -** 9) The X,Y,Z coordinates of the IAU 2000B Celestial Intermediate -** Pole are elements (3,1-3) of the GCRS-to-true matrix, -** i.e. rbpn[2][0-2]. -** -** 10) It is permissible to re-use the same array in the returned -** arguments. The arrays are filled in the stated order. -** -** Called: -** eraNut00b nutation, IAU 2000B -** eraPn00 bias/precession/nutation results, IAU 2000 -** -** Reference: -** -** Capitaine, N., Chapront, J., Lambert, S. and Wallace, P., -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 (2003). -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Nutation. */ - eraNut00b(date1, date2, dpsi, deps); - -/* Remaining results. */ - eraPn00(date1, date2, *dpsi, *deps, epsa, rb, rp, rbp, rn, rbpn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pn06.c b/ast/erfa/pn06.c deleted file mode 100644 index 63cf117..0000000 --- a/ast/erfa/pn06.c +++ /dev/null @@ -1,196 +0,0 @@ -#include "erfa.h" - -void eraPn06(double date1, double date2, double dpsi, double deps, - double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]) -/* -** - - - - - - - - -** e r a P n 0 6 -** - - - - - - - - -** -** Precession-nutation, IAU 2006 model: a multi-purpose function, -** supporting classical (equinox-based) use directly and CIO-based use -** indirectly. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** dpsi,deps double nutation (Note 2) -** -** Returned: -** epsa double mean obliquity (Note 3) -** rb double[3][3] frame bias matrix (Note 4) -** rp double[3][3] precession matrix (Note 5) -** rbp double[3][3] bias-precession matrix (Note 6) -** rn double[3][3] nutation matrix (Note 7) -** rbpn double[3][3] GCRS-to-true matrix (Note 8) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The caller is responsible for providing the nutation components; -** they are in longitude and obliquity, in radians and are with -** respect to the equinox and ecliptic of date. For high-accuracy -** applications, free core nutation should be included as well as -** any other relevant corrections to the position of the CIP. -** -** 3) The returned mean obliquity is consistent with the IAU 2006 -** precession. -** -** 4) The matrix rb transforms vectors from GCRS to J2000.0 mean -** equator and equinox by applying frame bias. -** -** 5) The matrix rp transforms vectors from J2000.0 mean equator and -** equinox to mean equator and equinox of date by applying -** precession. -** -** 6) The matrix rbp transforms vectors from GCRS to mean equator and -** equinox of date by applying frame bias then precession. It is -** the product rp x rb. -** -** 7) The matrix rn transforms vectors from mean equator and equinox -** of date to true equator and equinox of date by applying the -** nutation (luni-solar + planetary). -** -** 8) The matrix rbpn transforms vectors from GCRS to true equator and -** equinox of date. It is the product rn x rbp, applying frame -** bias, precession and nutation in that order. -** -** 9) The X,Y,Z coordinates of the Celestial Intermediate Pole are -** elements (3,1-3) of the GCRS-to-true matrix, i.e. rbpn[2][0-2]. -** -** 10) It is permissible to re-use the same array in the returned -** arguments. The arrays are filled in the stated order. -** -** Called: -** eraPfw06 bias-precession F-W angles, IAU 2006 -** eraFw2m F-W angles to r-matrix -** eraCr copy r-matrix -** eraTr transpose r-matrix -** eraRxr product of two r-matrices -** -** References: -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855 -** -** Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double gamb, phib, psib, eps, r1[3][3], r2[3][3], rt[3][3]; - - -/* Bias-precession Fukushima-Williams angles of J2000.0 = frame bias. */ - eraPfw06(ERFA_DJM0, ERFA_DJM00, &gamb, &phib, &psib, &eps); - -/* B matrix. */ - eraFw2m(gamb, phib, psib, eps, r1); - eraCr(r1, rb); - -/* Bias-precession Fukushima-Williams angles of date. */ - eraPfw06(date1, date2, &gamb, &phib, &psib, &eps); - -/* Bias-precession matrix. */ - eraFw2m(gamb, phib, psib, eps, r2); - eraCr(r2, rbp); - -/* Solve for precession matrix. */ - eraTr(r1, rt); - eraRxr(r2, rt, rp); - -/* Equinox-based bias-precession-nutation matrix. */ - eraFw2m(gamb, phib, psib + dpsi, eps + deps, r1); - eraCr(r1, rbpn); - -/* Solve for nutation matrix. */ - eraTr(r2, rt); - eraRxr(r1, rt, rn); - -/* Obliquity, mean of date. */ - *epsa = eps; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pn06a.c b/ast/erfa/pn06a.c deleted file mode 100644 index 69948a3..0000000 --- a/ast/erfa/pn06a.c +++ /dev/null @@ -1,162 +0,0 @@ -#include "erfa.h" - -void eraPn06a(double date1, double date2, - double *dpsi, double *deps, double *epsa, - double rb[3][3], double rp[3][3], double rbp[3][3], - double rn[3][3], double rbpn[3][3]) -/* -** - - - - - - - - - -** e r a P n 0 6 a -** - - - - - - - - - -** -** Precession-nutation, IAU 2006/2000A models: a multi-purpose function, -** supporting classical (equinox-based) use directly and CIO-based use -** indirectly. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** dpsi,deps double nutation (Note 2) -** epsa double mean obliquity (Note 3) -** rb double[3][3] frame bias matrix (Note 4) -** rp double[3][3] precession matrix (Note 5) -** rbp double[3][3] bias-precession matrix (Note 6) -** rn double[3][3] nutation matrix (Note 7) -** rbpn double[3][3] GCRS-to-true matrix (Notes 8,9) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The nutation components (luni-solar + planetary, IAU 2000A) in -** longitude and obliquity are in radians and with respect to the -** equinox and ecliptic of date. Free core nutation is omitted; -** for the utmost accuracy, use the eraPn06 function, where the -** nutation components are caller-specified. -** -** 3) The mean obliquity is consistent with the IAU 2006 precession. -** -** 4) The matrix rb transforms vectors from GCRS to mean J2000.0 by -** applying frame bias. -** -** 5) The matrix rp transforms vectors from mean J2000.0 to mean of -** date by applying precession. -** -** 6) The matrix rbp transforms vectors from GCRS to mean of date by -** applying frame bias then precession. It is the product rp x rb. -** -** 7) The matrix rn transforms vectors from mean of date to true of -** date by applying the nutation (luni-solar + planetary). -** -** 8) The matrix rbpn transforms vectors from GCRS to true of date -** (CIP/equinox). It is the product rn x rbp, applying frame bias, -** precession and nutation in that order. -** -** 9) The X,Y,Z coordinates of the IAU 2006/2000A Celestial -** Intermediate Pole are elements (3,1-3) of the GCRS-to-true -** matrix, i.e. rbpn[2][0-2]. -** -** 10) It is permissible to re-use the same array in the returned -** arguments. The arrays are filled in the stated order. -** -** Called: -** eraNut06a nutation, IAU 2006/2000A -** eraPn06 bias/precession/nutation results, IAU 2006 -** -** Reference: -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Nutation. */ - eraNut06a(date1, date2, dpsi, deps); - -/* Remaining results. */ - eraPn06(date1, date2, *dpsi, *deps, epsa, rb, rp, rbp, rn, rbpn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pnm00a.c b/ast/erfa/pnm00a.c deleted file mode 100644 index 9e70aa9..0000000 --- a/ast/erfa/pnm00a.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "erfa.h" - -void eraPnm00a(double date1, double date2, double rbpn[3][3]) -/* -** - - - - - - - - - - -** e r a P n m 0 0 a -** - - - - - - - - - - -** -** Form the matrix of precession-nutation for a given date (including -** frame bias), equinox-based, IAU 2000A model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rbpn double[3][3] classical NPB matrix (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(date) = rbpn * V(GCRS), where -** the p-vector V(date) is with respect to the true equatorial triad -** of date date1+date2 and the p-vector V(GCRS) is with respect to -** the Geocentric Celestial Reference System (IAU, 2000). -** -** 3) A faster, but slightly less accurate result (about 1 mas), can be -** obtained by using instead the eraPnm00b function. -** -** Called: -** eraPn00a bias/precession/nutation, IAU 2000A -** -** Reference: -** -** IAU: Trans. International Astronomical Union, Vol. XXIVB; Proc. -** 24th General Assembly, Manchester, UK. Resolutions B1.3, B1.6. -** (2000) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rn[3][3]; - - -/* Obtain the required matrix (discarding other results). */ - eraPn00a(date1, date2, &dpsi, &deps, &epsa, rb, rp, rbp, rn, rbpn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pnm00b.c b/ast/erfa/pnm00b.c deleted file mode 100644 index 5989b85..0000000 --- a/ast/erfa/pnm00b.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "erfa.h" - -void eraPnm00b(double date1, double date2, double rbpn[3][3]) -/* -** - - - - - - - - - - -** e r a P n m 0 0 b -** - - - - - - - - - - -** -** Form the matrix of precession-nutation for a given date (including -** frame bias), equinox-based, IAU 2000B model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rbpn double[3][3] bias-precession-nutation matrix (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(date) = rbpn * V(GCRS), where -** the p-vector V(date) is with respect to the true equatorial triad -** of date date1+date2 and the p-vector V(GCRS) is with respect to -** the Geocentric Celestial Reference System (IAU, 2000). -** -** 3) The present function is faster, but slightly less accurate (about -** 1 mas), than the eraPnm00a function. -** -** Called: -** eraPn00b bias/precession/nutation, IAU 2000B -** -** Reference: -** -** IAU: Trans. International Astronomical Union, Vol. XXIVB; Proc. -** 24th General Assembly, Manchester, UK. Resolutions B1.3, B1.6. -** (2000) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rn[3][3]; - - -/* Obtain the required matrix (discarding other results). */ - eraPn00b(date1, date2, &dpsi, &deps, &epsa, rb, rp, rbp, rn, rbpn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pnm06a.c b/ast/erfa/pnm06a.c deleted file mode 100644 index f587721..0000000 --- a/ast/erfa/pnm06a.c +++ /dev/null @@ -1,133 +0,0 @@ -#include "erfa.h" - -void eraPnm06a(double date1, double date2, double rnpb[3][3]) -/* -** - - - - - - - - - - -** e r a P n m 0 6 a -** - - - - - - - - - - -** -** Form the matrix of precession-nutation for a given date (including -** frame bias), IAU 2006 precession and IAU 2000A nutation models. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** rnpb double[3][3] bias-precession-nutation matrix (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(date) = rnpb * V(GCRS), where -** the p-vector V(date) is with respect to the true equatorial triad -** of date date1+date2 and the p-vector V(GCRS) is with respect to -** the Geocentric Celestial Reference System (IAU, 2000). -** -** Called: -** eraPfw06 bias-precession F-W angles, IAU 2006 -** eraNut06a nutation, IAU 2006/2000A -** eraFw2m F-W angles to r-matrix -** -** Reference: -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double gamb, phib, psib, epsa, dp, de; - - -/* Fukushima-Williams angles for frame bias and precession. */ - eraPfw06(date1, date2, &gamb, &phib, &psib, &epsa); - -/* Nutation components. */ - eraNut06a(date1, date2, &dp, &de); - -/* Equinox based nutation x precession x bias matrix. */ - eraFw2m(gamb, phib, psib + dp, epsa + de, rnpb); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pnm80.c b/ast/erfa/pnm80.c deleted file mode 100644 index a62f937..0000000 --- a/ast/erfa/pnm80.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "erfa.h" - -void eraPnm80(double date1, double date2, double rmatpn[3][3]) -/* -** - - - - - - - - - -** e r a P n m 8 0 -** - - - - - - - - - -** -** Form the matrix of precession/nutation for a given date, IAU 1976 -** precession model, IAU 1980 nutation model. -** -** Given: -** date1,date2 double TDB date (Note 1) -** -** Returned: -** rmatpn double[3][3] combined precession/nutation matrix -** -** Notes: -** -** 1) The TDB date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TDB)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The matrix operates in the sense V(date) = rmatpn * V(J2000), -** where the p-vector V(date) is with respect to the true equatorial -** triad of date date1+date2 and the p-vector V(J2000) is with -** respect to the mean equatorial triad of epoch J2000.0. -** -** Called: -** eraPmat76 precession matrix, IAU 1976 -** eraNutm80 nutation matrix, IAU 1980 -** eraRxr product of two r-matrices -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992), -** Section 3.3 (p145). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rmatp[3][3], rmatn[3][3]; - - -/* Precession matrix, J2000.0 to date. */ - eraPmat76(date1, date2, rmatp); - -/* Nutation matrix. */ - eraNutm80(date1, date2, rmatn); - -/* Combine the matrices: PN = N x P. */ - eraRxr(rmatn, rmatp, rmatpn); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pom00.c b/ast/erfa/pom00.c deleted file mode 100644 index 0f61496..0000000 --- a/ast/erfa/pom00.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "erfa.h" - -void eraPom00(double xp, double yp, double sp, double rpom[3][3]) -/* -** - - - - - - - - - - -** e r a P o m 0 0 -** - - - - - - - - - - -** -** Form the matrix of polar motion for a given date, IAU 2000. -** -** Given: -** xp,yp double coordinates of the pole (radians, Note 1) -** sp double the TIO locator s' (radians, Note 2) -** -** Returned: -** rpom double[3][3] polar-motion matrix (Note 3) -** -** Notes: -** -** 1) The arguments xp and yp are the coordinates (in radians) of the -** Celestial Intermediate Pole with respect to the International -** Terrestrial Reference System (see IERS Conventions 2003), -** measured along the meridians to 0 and 90 deg west respectively. -** -** 2) The argument sp is the TIO locator s', in radians, which -** positions the Terrestrial Intermediate Origin on the equator. It -** is obtained from polar motion observations by numerical -** integration, and so is in essence unpredictable. However, it is -** dominated by a secular drift of about 47 microarcseconds per -** century, and so can be taken into account by using s' = -47*t, -** where t is centuries since J2000.0. The function eraSp00 -** implements this approximation. -** -** 3) The matrix operates in the sense V(TRS) = rpom * V(CIP), meaning -** that it is the final rotation when computing the pointing -** direction to a celestial source. -** -** Called: -** eraIr initialize r-matrix to identity -** eraRz rotate around Z-axis -** eraRy rotate around Y-axis -** eraRx rotate around X-axis -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* Construct the matrix. */ - eraIr(rpom); - eraRz(sp, rpom); - eraRy(-xp, rpom); - eraRx(-yp, rpom); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ppp.c b/ast/erfa/ppp.c deleted file mode 100644 index 26cb957..0000000 --- a/ast/erfa/ppp.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "erfa.h" - -void eraPpp(double a[3], double b[3], double apb[3]) -/* -** - - - - - - - -** e r a P p p -** - - - - - - - -** -** P-vector addition. -** -** Given: -** a double[3] first p-vector -** b double[3] second p-vector -** -** Returned: -** apb double[3] a + b -** -** Note: -** It is permissible to re-use the same array for any of the -** arguments. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - apb[0] = a[0] + b[0]; - apb[1] = a[1] + b[1]; - apb[2] = a[2] + b[2]; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ppsp.c b/ast/erfa/ppsp.c deleted file mode 100644 index c58cbcb..0000000 --- a/ast/erfa/ppsp.c +++ /dev/null @@ -1,103 +0,0 @@ -#include "erfa.h" - -void eraPpsp(double a[3], double s, double b[3], double apsb[3]) -/* -** - - - - - - - - -** e r a P p s p -** - - - - - - - - -** -** P-vector plus scaled p-vector. -** -** Given: -** a double[3] first p-vector -** s double scalar (multiplier for b) -** b double[3] second p-vector -** -** Returned: -** apsb double[3] a + s*b -** -** Note: -** It is permissible for any of a, b and apsb to be the same array. -** -** Called: -** eraSxp multiply p-vector by scalar -** eraPpp p-vector plus p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double sb[3]; - - -/* s*b. */ - eraSxp(s, b, sb); - -/* a + s*b. */ - eraPpp(a, sb, apsb); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pr00.c b/ast/erfa/pr00.c deleted file mode 100644 index 0cdf7d3..0000000 --- a/ast/erfa/pr00.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "erfa.h" - -void eraPr00(double date1, double date2, double *dpsipr, double *depspr) -/* -** - - - - - - - - -** e r a P r 0 0 -** - - - - - - - - -** -** Precession-rate part of the IAU 2000 precession-nutation models -** (part of MHB2000). -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** dpsipr,depspr double precession corrections (Notes 2,3) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The precession adjustments are expressed as "nutation -** components", corrections in longitude and obliquity with respect -** to the J2000.0 equinox and ecliptic. -** -** 3) Although the precession adjustments are stated to be with respect -** to Lieske et al. (1977), the MHB2000 model does not specify which -** set of Euler angles are to be used and how the adjustments are to -** be applied. The most literal and straightforward procedure is to -** adopt the 4-rotation epsilon_0, psi_A, omega_A, xi_A option, and -** to add dpsipr to psi_A and depspr to both omega_A and eps_A. -** -** 4) This is an implementation of one aspect of the IAU 2000A nutation -** model, formally adopted by the IAU General Assembly in 2000, -** namely MHB2000 (Mathews et al. 2002). -** -** References: -** -** Lieske, J.H., Lederle, T., Fricke, W. & Morando, B., "Expressions -** for the precession quantities based upon the IAU (1976) System of -** Astronomical Constants", Astron.Astrophys., 58, 1-16 (1977) -** -** Mathews, P.M., Herring, T.A., Buffet, B.A., "Modeling of nutation -** and precession New nutation series for nonrigid Earth and -** insights into the Earth's interior", J.Geophys.Res., 107, B4, -** 2002. The MHB2000 code itself was obtained on 9th September 2002 -** from ftp://maia.usno.navy.mil/conv2000/chapter5/IAU2000A. -** -** Wallace, P.T., "Software for Implementing the IAU 2000 -** Resolutions", in IERS Workshop 5.1 (2002). -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t; - -/* Precession and obliquity corrections (radians per century) */ - static const double PRECOR = -0.29965 * ERFA_DAS2R, - OBLCOR = -0.02524 * ERFA_DAS2R; - - -/* Interval between fundamental epoch J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Precession rate contributions with respect to IAU 1976/80. */ - *dpsipr = PRECOR * t; - *depspr = OBLCOR * t; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/prec76.c b/ast/erfa/prec76.c deleted file mode 100644 index 4c47985..0000000 --- a/ast/erfa/prec76.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "erfa.h" - -void eraPrec76(double date01, double date02, double date11, double date12, - double *zeta, double *z, double *theta) -/* -** - - - - - - - - - - -** e r a P r e c 7 6 -** - - - - - - - - - - -** -** IAU 1976 precession model. -** -** This function forms the three Euler angles which implement general -** precession between two dates, using the IAU 1976 model (as for the -** FK5 catalog). -** -** Given: -** date01,date02 double TDB starting date (Note 1) -** date11,date12 double TDB ending date (Note 1) -** -** Returned: -** zeta double 1st rotation: radians cw around z -** z double 3rd rotation: radians cw around z -** theta double 2nd rotation: radians ccw around y -** -** Notes: -** -** 1) The dates date01+date02 and date11+date12 are Julian Dates, -** apportioned in any convenient way between the arguments daten1 -** and daten2. For example, JD(TDB)=2450123.7 could be expressed in -** any of these ways, among others: -** -** daten1 daten2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in cases -** where the loss of several decimal digits of resolution is -** acceptable. The J2000 method is best matched to the way the -** argument is handled internally and will deliver the optimum -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** The two dates may be expressed using different methods, but at -** the risk of losing some resolution. -** -** 2) The accumulated precession angles zeta, z, theta are expressed -** through canonical polynomials which are valid only for a limited -** time span. In addition, the IAU 1976 precession rate is known to -** be imperfect. The absolute accuracy of the present formulation -** is better than 0.1 arcsec from 1960AD to 2040AD, better than -** 1 arcsec from 1640AD to 2360AD, and remains below 3 arcsec for -** the whole of the period 500BC to 3000AD. The errors exceed -** 10 arcsec outside the range 1200BC to 3900AD, exceed 100 arcsec -** outside 4200BC to 5600AD and exceed 1000 arcsec outside 6800BC to -** 8200AD. -** -** 3) The three angles are returned in the conventional order, which -** is not the same as the order of the corresponding Euler -** rotations. The precession matrix is -** R_3(-z) x R_2(+theta) x R_3(-zeta). -** -** Reference: -** -** Lieske, J.H., 1979, Astron.Astrophys. 73, 282, equations -** (6) & (7), p283. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t0, t, tas2r, w; - - -/* Interval between fundamental epoch J2000.0 and start date (JC). */ - t0 = ((date01 - ERFA_DJ00) + date02) / ERFA_DJC; - -/* Interval over which precession required (JC). */ - t = ((date11 - date01) + (date12 - date02)) / ERFA_DJC; - -/* Euler angles. */ - tas2r = t * ERFA_DAS2R; - w = 2306.2181 + (1.39656 - 0.000139 * t0) * t0; - - *zeta = (w + ((0.30188 - 0.000344 * t0) + 0.017998 * t) * t) * tas2r; - - *z = (w + ((1.09468 + 0.000066 * t0) + 0.018203 * t) * t) * tas2r; - - *theta = ((2004.3109 + (-0.85330 - 0.000217 * t0) * t0) - + ((-0.42665 - 0.000217 * t0) - 0.041833 * t) * t) * tas2r; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pv2p.c b/ast/erfa/pv2p.c deleted file mode 100644 index b6ea164..0000000 --- a/ast/erfa/pv2p.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "erfa.h" - -void eraPv2p(double pv[2][3], double p[3]) -/* -** - - - - - - - - -** e r a P v 2 p -** - - - - - - - - -** -** Discard velocity component of a pv-vector. -** -** Given: -** pv double[2][3] pv-vector -** -** Returned: -** p double[3] p-vector -** -** Called: -** eraCp copy p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraCp(pv[0], p); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pv2s.c b/ast/erfa/pv2s.c deleted file mode 100644 index 58d86a9..0000000 --- a/ast/erfa/pv2s.c +++ /dev/null @@ -1,153 +0,0 @@ -#include "erfa.h" - -void eraPv2s(double pv[2][3], - double *theta, double *phi, double *r, - double *td, double *pd, double *rd) -/* -** - - - - - - - - -** e r a P v 2 s -** - - - - - - - - -** -** Convert position/velocity from Cartesian to spherical coordinates. -** -** Given: -** pv double[2][3] pv-vector -** -** Returned: -** theta double longitude angle (radians) -** phi double latitude angle (radians) -** r double radial distance -** td double rate of change of theta -** pd double rate of change of phi -** rd double rate of change of r -** -** Notes: -** -** 1) If the position part of pv is null, theta, phi, td and pd -** are indeterminate. This is handled by extrapolating the -** position through unit time by using the velocity part of -** pv. This moves the origin without changing the direction -** of the velocity component. If the position and velocity -** components of pv are both null, zeroes are returned for all -** six results. -** -** 2) If the position is a pole, theta, td and pd are indeterminate. -** In such cases zeroes are returned for all three. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double x, y, z, xd, yd, zd, rxy2, rxy, r2, rtrue, rw, xyp; - - -/* Components of position/velocity vector. */ - x = pv[0][0]; - y = pv[0][1]; - z = pv[0][2]; - xd = pv[1][0]; - yd = pv[1][1]; - zd = pv[1][2]; - -/* Component of r in XY plane squared. */ - rxy2 = x*x + y*y; - -/* Modulus squared. */ - r2 = rxy2 + z*z; - -/* Modulus. */ - rtrue = sqrt(r2); - -/* If null vector, move the origin along the direction of movement. */ - rw = rtrue; - if (rtrue == 0.0) { - x = xd; - y = yd; - z = zd; - rxy2 = x*x + y*y; - r2 = rxy2 + z*z; - rw = sqrt(r2); - } - -/* Position and velocity in spherical coordinates. */ - rxy = sqrt(rxy2); - xyp = x*xd + y*yd; - if (rxy2 != 0.0) { - *theta = atan2(y, x); - *phi = atan2(z, rxy); - *td = (x*yd - y*xd) / rxy2; - *pd = (zd*rxy2 - z*xyp) / (r2*rxy); - } else { - *theta = 0.0; - *phi = (z != 0.0) ? atan2(z, rxy) : 0.0; - *td = 0.0; - *pd = 0.0; - } - *r = rtrue; - *rd = (rw != 0.0) ? (xyp + z*zd) / rw : 0.0; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pvdpv.c b/ast/erfa/pvdpv.c deleted file mode 100644 index 103c308..0000000 --- a/ast/erfa/pvdpv.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "erfa.h" - -void eraPvdpv(double a[2][3], double b[2][3], double adb[2]) -/* -** - - - - - - - - - -** e r a P v d p v -** - - - - - - - - - -** -** Inner (=scalar=dot) product of two pv-vectors. -** -** Given: -** a double[2][3] first pv-vector -** b double[2][3] second pv-vector -** -** Returned: -** adb double[2] a . b (see note) -** -** Note: -** -** If the position and velocity components of the two pv-vectors are -** ( ap, av ) and ( bp, bv ), the result, a . b, is the pair of -** numbers ( ap . bp , ap . bv + av . bp ). The two numbers are the -** dot-product of the two p-vectors and its derivative. -** -** Called: -** eraPdp scalar product of two p-vectors -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double adbd, addb; - - -/* a . b = constant part of result. */ - adb[0] = eraPdp(a[0], b[0]); - -/* a . bdot */ - adbd = eraPdp(a[0], b[1]); - -/* adot . b */ - addb = eraPdp(a[1], b[0]); - -/* Velocity part of result. */ - adb[1] = adbd + addb; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pvm.c b/ast/erfa/pvm.c deleted file mode 100644 index fcb94c5..0000000 --- a/ast/erfa/pvm.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "erfa.h" - -void eraPvm(double pv[2][3], double *r, double *s) -/* -** - - - - - - - -** e r a P v m -** - - - - - - - -** -** Modulus of pv-vector. -** -** Given: -** pv double[2][3] pv-vector -** -** Returned: -** r double modulus of position component -** s double modulus of velocity component -** -** Called: -** eraPm modulus of p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Distance. */ - *r = eraPm(pv[0]); - -/* Speed. */ - *s = eraPm(pv[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pvmpv.c b/ast/erfa/pvmpv.c deleted file mode 100644 index dda99ee..0000000 --- a/ast/erfa/pvmpv.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "erfa.h" - -void eraPvmpv(double a[2][3], double b[2][3], double amb[2][3]) -/* -** - - - - - - - - - -** e r a P v m p v -** - - - - - - - - - -** -** Subtract one pv-vector from another. -** -** Given: -** a double[2][3] first pv-vector -** b double[2][3] second pv-vector -** -** Returned: -** amb double[2][3] a - b -** -** Note: -** It is permissible to re-use the same array for any of the -** arguments. -** -** Called: -** eraPmp p-vector minus p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraPmp(a[0], b[0], amb[0]); - eraPmp(a[1], b[1], amb[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pvppv.c b/ast/erfa/pvppv.c deleted file mode 100644 index 19c2875..0000000 --- a/ast/erfa/pvppv.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "erfa.h" - -void eraPvppv(double a[2][3], double b[2][3], double apb[2][3]) -/* -** - - - - - - - - - -** e r a P v p p v -** - - - - - - - - - -** -** Add one pv-vector to another. -** -** Given: -** a double[2][3] first pv-vector -** b double[2][3] second pv-vector -** -** Returned: -** apb double[2][3] a + b -** -** Note: -** It is permissible to re-use the same array for any of the -** arguments. -** -** Called: -** eraPpp p-vector plus p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraPpp(a[0], b[0], apb[0]); - eraPpp(a[1], b[1], apb[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pvstar.c b/ast/erfa/pvstar.c deleted file mode 100644 index 3a4e00b..0000000 --- a/ast/erfa/pvstar.c +++ /dev/null @@ -1,216 +0,0 @@ -#include "erfa.h" - -int eraPvstar(double pv[2][3], double *ra, double *dec, - double *pmr, double *pmd, double *px, double *rv) -/* -** - - - - - - - - - - -** e r a P v s t a r -** - - - - - - - - - - -** -** Convert star position+velocity vector to catalog coordinates. -** -** Given (Note 1): -** pv double[2][3] pv-vector (AU, AU/day) -** -** Returned (Note 2): -** ra double right ascension (radians) -** dec double declination (radians) -** pmr double RA proper motion (radians/year) -** pmd double Dec proper motion (radians/year) -** px double parallax (arcsec) -** rv double radial velocity (km/s, positive = receding) -** -** Returned (function value): -** int status: -** 0 = OK -** -1 = superluminal speed (Note 5) -** -2 = null position vector -** -** Notes: -** -** 1) The specified pv-vector is the coordinate direction (and its rate -** of change) for the date at which the light leaving the star -** reached the solar-system barycenter. -** -** 2) The star data returned by this function are "observables" for an -** imaginary observer at the solar-system barycenter. Proper motion -** and radial velocity are, strictly, in terms of barycentric -** coordinate time, TCB. For most practical applications, it is -** permissible to neglect the distinction between TCB and ordinary -** "proper" time on Earth (TT/TAI). The result will, as a rule, be -** limited by the intrinsic accuracy of the proper-motion and -** radial-velocity data; moreover, the supplied pv-vector is likely -** to be merely an intermediate result (for example generated by the -** function eraStarpv), so that a change of time unit will cancel -** out overall. -** -** In accordance with normal star-catalog conventions, the object's -** right ascension and declination are freed from the effects of -** secular aberration. The frame, which is aligned to the catalog -** equator and equinox, is Lorentzian and centered on the SSB. -** -** Summarizing, the specified pv-vector is for most stars almost -** identical to the result of applying the standard geometrical -** "space motion" transformation to the catalog data. The -** differences, which are the subject of the Stumpff paper cited -** below, are: -** -** (i) In stars with significant radial velocity and proper motion, -** the constantly changing light-time distorts the apparent proper -** motion. Note that this is a classical, not a relativistic, -** effect. -** -** (ii) The transformation complies with special relativity. -** -** 3) Care is needed with units. The star coordinates are in radians -** and the proper motions in radians per Julian year, but the -** parallax is in arcseconds; the radial velocity is in km/s, but -** the pv-vector result is in AU and AU/day. -** -** 4) The proper motions are the rate of change of the right ascension -** and declination at the catalog epoch and are in radians per Julian -** year. The RA proper motion is in terms of coordinate angle, not -** true angle, and will thus be numerically larger at high -** declinations. -** -** 5) Straight-line motion at constant speed in the inertial frame is -** assumed. If the speed is greater than or equal to the speed of -** light, the function aborts with an error status. -** -** 6) The inverse transformation is performed by the function eraStarpv. -** -** Called: -** eraPn decompose p-vector into modulus and direction -** eraPdp scalar product of two p-vectors -** eraSxp multiply p-vector by scalar -** eraPmp p-vector minus p-vector -** eraPm modulus of p-vector -** eraPpp p-vector plus p-vector -** eraPv2s pv-vector to spherical -** eraAnp normalize angle into range 0 to 2pi -** -** Reference: -** -** Stumpff, P., 1985, Astron.Astrophys. 144, 232-240. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double r, x[3], vr, ur[3], vt, ut[3], bett, betr, d, w, del, - usr[3], ust[3], a, rad, decd, rd; - - -/* Isolate the radial component of the velocity (AU/day, inertial). */ - eraPn(pv[0], &r, x); - vr = eraPdp(x, pv[1]); - eraSxp(vr, x, ur); - -/* Isolate the transverse component of the velocity (AU/day, inertial). */ - eraPmp(pv[1], ur, ut); - vt = eraPm(ut); - -/* Special-relativity dimensionless parameters. */ - bett = vt / ERFA_DC; - betr = vr / ERFA_DC; - -/* The inertial-to-observed correction terms. */ - d = 1.0 + betr; - w = 1.0 - betr*betr - bett*bett; - if (d == 0.0 || w < 0) return -1; - del = sqrt(w) - 1.0; - -/* Apply relativistic correction factor to radial velocity component. */ - w = (betr != 0) ? (betr - del) / (betr * d) : 1.0; - eraSxp(w, ur, usr); - -/* Apply relativistic correction factor to tangential velocity */ -/* component. */ - eraSxp(1.0/d, ut, ust); - -/* Combine the two to obtain the observed velocity vector (AU/day). */ - eraPpp(usr, ust, pv[1]); - -/* Cartesian to spherical. */ - eraPv2s(pv, &a, dec, &r, &rad, &decd, &rd); - if (r == 0.0) return -2; - -/* Return RA in range 0 to 2pi. */ - *ra = eraAnp(a); - -/* Return proper motions in radians per year. */ - *pmr = rad * ERFA_DJY; - *pmd = decd * ERFA_DJY; - -/* Return parallax in arcsec. */ - *px = ERFA_DR2AS / r; - -/* Return radial velocity in km/s. */ - *rv = 1e-3 * rd * ERFA_DAU / ERFA_DAYSEC; - -/* OK status. */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pvtob.c b/ast/erfa/pvtob.c deleted file mode 100644 index 943a63c..0000000 --- a/ast/erfa/pvtob.c +++ /dev/null @@ -1,162 +0,0 @@ -#include "erfa.h" - -void eraPvtob(double elong, double phi, double hm, - double xp, double yp, double sp, double theta, - double pv[2][3]) -/* -** - - - - - - - - - -** e r a P v t o b -** - - - - - - - - - -** -** Position and velocity of a terrestrial observing station. -** -** Given: -** elong double longitude (radians, east +ve, Note 1) -** phi double latitude (geodetic, radians, Note 1) -** hm double height above ref. ellipsoid (geodetic, m) -** xp,yp double coordinates of the pole (radians, Note 2) -** sp double the TIO locator s' (radians, Note 2) -** theta double Earth rotation angle (radians, Note 3) -** -** Returned: -** pv double[2][3] position/velocity vector (m, m/s, CIRS) -** -** Notes: -** -** 1) The terrestrial coordinates are with respect to the ERFA_WGS84 -** reference ellipsoid. -** -** 2) xp and yp are the coordinates (in radians) of the Celestial -** Intermediate Pole with respect to the International Terrestrial -** Reference System (see IERS Conventions), measured along the -** meridians 0 and 90 deg west respectively. sp is the TIO locator -** s', in radians, which positions the Terrestrial Intermediate -** Origin on the equator. For many applications, xp, yp and -** (especially) sp can be set to zero. -** -** 3) If theta is Greenwich apparent sidereal time instead of Earth -** rotation angle, the result is with respect to the true equator -** and equinox of date, i.e. with the x-axis at the equinox rather -** than the celestial intermediate origin. -** -** 4) The velocity units are meters per UT1 second, not per SI second. -** This is unlikely to have any practical consequences in the modern -** era. -** -** 5) No validation is performed on the arguments. Error cases that -** could lead to arithmetic exceptions are trapped by the eraGd2gc -** function, and the result set to zeros. -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to -** the Astronomical Almanac, 3rd ed., University Science Books -** (2013), Section 7.4.3.3. -** -** Called: -** eraGd2gc geodetic to geocentric transformation -** eraPom00 polar motion matrix -** eraTrxp product of transpose of r-matrix and p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Earth rotation rate in radians per UT1 second */ - const double OM = 1.00273781191135448 * ERFA_D2PI / ERFA_DAYSEC; - - double xyzm[3], rpm[3][3], xyz[3], x, y, z, s, c; - - -/* Geodetic to geocentric transformation (ERFA_WGS84). */ - (void) eraGd2gc(1, elong, phi, hm, xyzm); - -/* Polar motion and TIO position. */ - eraPom00(xp, yp, sp, rpm); - eraTrxp(rpm, xyzm, xyz); - x = xyz[0]; - y = xyz[1]; - z = xyz[2]; - -/* Functions of ERA. */ - s = sin(theta); - c = cos(theta); - -/* Position. */ - pv[0][0] = c*x - s*y; - pv[0][1] = s*x + c*y; - pv[0][2] = z; - -/* Velocity. */ - pv[1][0] = OM * ( -s*x - c*y ); - pv[1][1] = OM * ( c*x - s*y ); - pv[1][2] = 0.0; - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pvu.c b/ast/erfa/pvu.c deleted file mode 100644 index 34d9db2..0000000 --- a/ast/erfa/pvu.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "erfa.h" - -void eraPvu(double dt, double pv[2][3], double upv[2][3]) -/* -** - - - - - - - -** e r a P v u -** - - - - - - - -** -** Update a pv-vector. -** -** Given: -** dt double time interval -** pv double[2][3] pv-vector -** -** Returned: -** upv double[2][3] p updated, v unchanged -** -** Notes: -** -** 1) "Update" means "refer the position component of the vector -** to a new date dt time units from the existing date". -** -** 2) The time units of dt must match those of the velocity. -** -** 3) It is permissible for pv and upv to be the same array. -** -** Called: -** eraPpsp p-vector plus scaled p-vector -** eraCp copy p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraPpsp(pv[0], dt, pv[1], upv[0]); - eraCp(pv[1], upv[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pvup.c b/ast/erfa/pvup.c deleted file mode 100644 index 7f50e6c..0000000 --- a/ast/erfa/pvup.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "erfa.h" - -void eraPvup(double dt, double pv[2][3], double p[3]) -/* -** - - - - - - - - -** e r a P v u p -** - - - - - - - - -** -** Update a pv-vector, discarding the velocity component. -** -** Given: -** dt double time interval -** pv double[2][3] pv-vector -** -** Returned: -** p double[3] p-vector -** -** Notes: -** -** 1) "Update" means "refer the position component of the vector to a -** new date dt time units from the existing date". -** -** 2) The time units of dt must match those of the velocity. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - p[0] = pv[0][0] + dt * pv[1][0]; - p[1] = pv[0][1] + dt * pv[1][1]; - p[2] = pv[0][2] + dt * pv[1][2]; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pvxpv.c b/ast/erfa/pvxpv.c deleted file mode 100644 index 0d87479..0000000 --- a/ast/erfa/pvxpv.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "erfa.h" - -void eraPvxpv(double a[2][3], double b[2][3], double axb[2][3]) -/* -** - - - - - - - - - -** e r a P v x p v -** - - - - - - - - - -** -** Outer (=vector=cross) product of two pv-vectors. -** -** Given: -** a double[2][3] first pv-vector -** b double[2][3] second pv-vector -** -** Returned: -** axb double[2][3] a x b -** -** Notes: -** -** 1) If the position and velocity components of the two pv-vectors are -** ( ap, av ) and ( bp, bv ), the result, a x b, is the pair of -** vectors ( ap x bp, ap x bv + av x bp ). The two vectors are the -** cross-product of the two p-vectors and its derivative. -** -** 2) It is permissible to re-use the same array for any of the -** arguments. -** -** Called: -** eraCpv copy pv-vector -** eraPxp vector product of two p-vectors -** eraPpp p-vector plus p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double wa[2][3], wb[2][3], axbd[3], adxb[3]; - - -/* Make copies of the inputs. */ - eraCpv(a, wa); - eraCpv(b, wb); - -/* a x b = position part of result. */ - eraPxp(wa[0], wb[0], axb[0]); - -/* a x bdot + adot x b = velocity part of result. */ - eraPxp(wa[0], wb[1], axbd); - eraPxp(wa[1], wb[0], adxb); - eraPpp(axbd, adxb, axb[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/pxp.c b/ast/erfa/pxp.c deleted file mode 100644 index 5b5a98b..0000000 --- a/ast/erfa/pxp.c +++ /dev/null @@ -1,103 +0,0 @@ -#include "erfa.h" - -void eraPxp(double a[3], double b[3], double axb[3]) -/* -** - - - - - - - -** e r a P x p -** - - - - - - - -** -** p-vector outer (=vector=cross) product. -** -** Given: -** a double[3] first p-vector -** b double[3] second p-vector -** -** Returned: -** axb double[3] a x b -** -** Note: -** It is permissible to re-use the same array for any of the -** arguments. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double xa, ya, za, xb, yb, zb; - - - xa = a[0]; - ya = a[1]; - za = a[2]; - xb = b[0]; - yb = b[1]; - zb = b[2]; - axb[0] = ya*zb - za*yb; - axb[1] = za*xb - xa*zb; - axb[2] = xa*yb - ya*xb; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/refco.c b/ast/erfa/refco.c deleted file mode 100644 index 918d990..0000000 --- a/ast/erfa/refco.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "erfa.h" - -void eraRefco(double phpa, double tc, double rh, double wl, - double *refa, double *refb) -/* -** - - - - - - - - - -** e r a R e f c o -** - - - - - - - - - -** -** Determine the constants A and B in the atmospheric refraction model -** dZ = A tan Z + B tan^3 Z. -** -** Z is the "observed" zenith distance (i.e. affected by refraction) -** and dZ is what to add to Z to give the "topocentric" (i.e. in vacuo) -** zenith distance. -** -** Given: -** phpa double pressure at the observer (hPa = millibar) -** tc double ambient temperature at the observer (deg C) -** rh double relative humidity at the observer (range 0-1) -** wl double wavelength (micrometers) -** -** Returned: -** refa double* tan Z coefficient (radians) -** refb double* tan^3 Z coefficient (radians) -** -** Notes: -** -** 1) The model balances speed and accuracy to give good results in -** applications where performance at low altitudes is not paramount. -** Performance is maintained across a range of conditions, and -** applies to both optical/IR and radio. -** -** 2) The model omits the effects of (i) height above sea level (apart -** from the reduced pressure itself), (ii) latitude (i.e. the -** flattening of the Earth), (iii) variations in tropospheric lapse -** rate and (iv) dispersive effects in the radio. -** -** The model was tested using the following range of conditions: -** -** lapse rates 0.0055, 0.0065, 0.0075 deg/meter -** latitudes 0, 25, 50, 75 degrees -** heights 0, 2500, 5000 meters ASL -** pressures mean for height -10% to +5% in steps of 5% -** temperatures -10 deg to +20 deg with respect to 280 deg at SL -** relative humidity 0, 0.5, 1 -** wavelengths 0.4, 0.6, ... 2 micron, + radio -** zenith distances 15, 45, 75 degrees -** -** The accuracy with respect to raytracing through a model -** atmosphere was as follows: -** -** worst RMS -** -** optical/IR 62 mas 8 mas -** radio 319 mas 49 mas -** -** For this particular set of conditions: -** -** lapse rate 0.0065 K/meter -** latitude 50 degrees -** sea level -** pressure 1005 mb -** temperature 280.15 K -** humidity 80% -** wavelength 5740 Angstroms -** -** the results were as follows: -** -** ZD raytrace eraRefco Saastamoinen -** -** 10 10.27 10.27 10.27 -** 20 21.19 21.20 21.19 -** 30 33.61 33.61 33.60 -** 40 48.82 48.83 48.81 -** 45 58.16 58.18 58.16 -** 50 69.28 69.30 69.27 -** 55 82.97 82.99 82.95 -** 60 100.51 100.54 100.50 -** 65 124.23 124.26 124.20 -** 70 158.63 158.68 158.61 -** 72 177.32 177.37 177.31 -** 74 200.35 200.38 200.32 -** 76 229.45 229.43 229.42 -** 78 267.44 267.29 267.41 -** 80 319.13 318.55 319.10 -** -** deg arcsec arcsec arcsec -** -** The values for Saastamoinen's formula (which includes terms -** up to tan^5) are taken from Hohenkerk and Sinclair (1985). -** -** 3) A wl value in the range 0-100 selects the optical/IR case and is -** wavelength in micrometers. Any value outside this range selects -** the radio case. -** -** 4) Outlandish input parameters are silently limited to -** mathematically safe values. Zero pressure is permissible, and -** causes zeroes to be returned. -** -** 5) The algorithm draws on several sources, as follows: -** -** a) The formula for the saturation vapour pressure of water as -** a function of temperature and temperature is taken from -** Equations (A4.5-A4.7) of Gill (1982). -** -** b) The formula for the water vapour pressure, given the -** saturation pressure and the relative humidity, is from -** Crane (1976), Equation (2.5.5). -** -** c) The refractivity of air is a function of temperature, -** total pressure, water-vapour pressure and, in the case -** of optical/IR, wavelength. The formulae for the two cases are -** developed from Hohenkerk & Sinclair (1985) and Rueger (2002). -** -** d) The formula for beta, the ratio of the scale height of the -** atmosphere to the geocentric distance of the observer, is -** an adaption of Equation (9) from Stone (1996). The -** adaptations, arrived at empirically, consist of (i) a small -** adjustment to the coefficient and (ii) a humidity term for the -** radio case only. -** -** e) The formulae for the refraction constants as a function of -** n-1 and beta are from Green (1987), Equation (4.31). -** -** References: -** -** Crane, R.K., Meeks, M.L. (ed), "Refraction Effects in the Neutral -** Atmosphere", Methods of Experimental Physics: Astrophysics 12B, -** Academic Press, 1976. -** -** Gill, Adrian E., "Atmosphere-Ocean Dynamics", Academic Press, -** 1982. -** -** Green, R.M., "Spherical Astronomy", Cambridge University Press, -** 1987. -** -** Hohenkerk, C.Y., & Sinclair, A.T., NAO Technical Note No. 63, -** 1985. -** -** Rueger, J.M., "Refractive Index Formulae for Electronic Distance -** Measurement with Radio and Millimetre Waves", in Unisurv Report -** S-68, School of Surveying and Spatial Information Systems, -** University of New South Wales, Sydney, Australia, 2002. -** -** Stone, Ronald C., P.A.S.P. 108, 1051-1058, 1996. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int optic; - double p, t, r, w, ps, pw, tk, wlsq, gamma, beta; - - -/* Decide whether optical/IR or radio case: switch at 100 microns. */ - optic = ( wl <= 100.0 ); - -/* Restrict parameters to safe values. */ - t = ERFA_GMAX ( tc, -150.0 ); - t = ERFA_GMIN ( t, 200.0 ); - p = ERFA_GMAX ( phpa, 0.0 ); - p = ERFA_GMIN ( p, 10000.0 ); - r = ERFA_GMAX ( rh, 0.0 ); - r = ERFA_GMIN ( r, 1.0 ); - w = ERFA_GMAX ( wl, 0.1 ); - w = ERFA_GMIN ( w, 1e6 ); - -/* Water vapour pressure at the observer. */ - if ( p > 0.0 ) { - ps = pow ( 10.0, ( 0.7859 + 0.03477*t ) / - ( 1.0 + 0.00412*t ) ) * - ( 1.0 + p * ( 4.5e-6 + 6e-10*t*t ) ); - pw = r * ps / ( 1.0 - (1.0-r)*ps/p ); - } else { - pw = 0.0; - } - -/* Refractive index minus 1 at the observer. */ - tk = t + 273.15; - if ( optic ) { - wlsq = w * w; - gamma = ( ( 77.53484e-6 + - ( 4.39108e-7 + 3.666e-9/wlsq ) / wlsq ) * p - - 11.2684e-6*pw ) / tk; - } else { - gamma = ( 77.6890e-6*p - ( 6.3938e-6 - 0.375463/tk ) * pw ) / tk; - } - -/* Formula for beta from Stone, with empirical adjustments. */ - beta = 4.4474e-6 * tk; - if ( ! optic ) beta -= 0.0074 * pw * beta; - -/* Refraction constants from Green. */ - *refa = gamma * ( 1.0 - beta ); - *refb = - gamma * ( beta - gamma / 2.0 ); - -/* Finished. */ - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/rm2v.c b/ast/erfa/rm2v.c deleted file mode 100644 index 2de16ce..0000000 --- a/ast/erfa/rm2v.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "erfa.h" - -void eraRm2v(double r[3][3], double w[3]) -/* -** - - - - - - - - -** e r a R m 2 v -** - - - - - - - - -** -** Express an r-matrix as an r-vector. -** -** Given: -** r double[3][3] rotation matrix -** -** Returned: -** w double[3] rotation vector (Note 1) -** -** Notes: -** -** 1) A rotation matrix describes a rotation through some angle about -** some arbitrary axis called the Euler axis. The "rotation vector" -** returned by this function has the same direction as the Euler axis, -** and its magnitude is the angle in radians. (The magnitude and -** direction can be separated by means of the function eraPn.) -** -** 2) If r is null, so is the result. If r is not a rotation matrix -** the result is undefined; r must be proper (i.e. have a positive -** determinant) and real orthogonal (inverse = transpose). -** -** 3) The reference frame rotates clockwise as seen looking along -** the rotation vector from the origin. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double x, y, z, s2, c2, phi, f; - - - x = r[1][2] - r[2][1]; - y = r[2][0] - r[0][2]; - z = r[0][1] - r[1][0]; - s2 = sqrt(x*x + y*y + z*z); - if (s2 > 0) { - c2 = r[0][0] + r[1][1] + r[2][2] - 1.0; - phi = atan2(s2, c2); - f = phi / s2; - w[0] = x * f; - w[1] = y * f; - w[2] = z * f; - } else { - w[0] = 0.0; - w[1] = 0.0; - w[2] = 0.0; - } - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/rv2m.c b/ast/erfa/rv2m.c deleted file mode 100644 index 9fe3c4b..0000000 --- a/ast/erfa/rv2m.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "erfa.h" - -void eraRv2m(double w[3], double r[3][3]) -/* -** - - - - - - - - -** e r a R v 2 m -** - - - - - - - - -** -** Form the r-matrix corresponding to a given r-vector. -** -** Given: -** w double[3] rotation vector (Note 1) -** -** Returned: -** r double[3][3] rotation matrix -** -** Notes: -** -** 1) A rotation matrix describes a rotation through some angle about -** some arbitrary axis called the Euler axis. The "rotation vector" -** supplied to This function has the same direction as the Euler -** axis, and its magnitude is the angle in radians. -** -** 2) If w is null, the unit matrix is returned. -** -** 3) The reference frame rotates clockwise as seen looking along the -** rotation vector from the origin. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double x, y, z, phi, s, c, f; - - -/* Euler angle (magnitude of rotation vector) and functions. */ - x = w[0]; - y = w[1]; - z = w[2]; - phi = sqrt(x*x + y*y + z*z); - s = sin(phi); - c = cos(phi); - f = 1.0 - c; - -/* Euler axis (direction of rotation vector), perhaps null. */ - if (phi > 0.0) { - x /= phi; - y /= phi; - z /= phi; - } - -/* Form the rotation matrix. */ - r[0][0] = x*x*f + c; - r[0][1] = x*y*f + z*s; - r[0][2] = x*z*f - y*s; - r[1][0] = y*x*f - z*s; - r[1][1] = y*y*f + c; - r[1][2] = y*z*f + x*s; - r[2][0] = z*x*f + y*s; - r[2][1] = z*y*f - x*s; - r[2][2] = z*z*f + c; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/rx.c b/ast/erfa/rx.c deleted file mode 100644 index df080d5..0000000 --- a/ast/erfa/rx.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "erfa.h" - -void eraRx(double phi, double r[3][3]) -/* -** - - - - - - -** e r a R x -** - - - - - - -** -** Rotate an r-matrix about the x-axis. -** -** Given: -** phi double angle (radians) -** -** Given and returned: -** r double[3][3] r-matrix, rotated -** -** Notes: -** -** 1) Calling this function with positive phi incorporates in the -** supplied r-matrix r an additional rotation, about the x-axis, -** anticlockwise as seen looking towards the origin from positive x. -** -** 2) The additional rotation can be represented by this matrix: -** -** ( 1 0 0 ) -** ( ) -** ( 0 + cos(phi) + sin(phi) ) -** ( ) -** ( 0 - sin(phi) + cos(phi) ) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double s, c, a10, a11, a12, a20, a21, a22; - - - s = sin(phi); - c = cos(phi); - - a10 = c*r[1][0] + s*r[2][0]; - a11 = c*r[1][1] + s*r[2][1]; - a12 = c*r[1][2] + s*r[2][2]; - a20 = - s*r[1][0] + c*r[2][0]; - a21 = - s*r[1][1] + c*r[2][1]; - a22 = - s*r[1][2] + c*r[2][2]; - - r[1][0] = a10; - r[1][1] = a11; - r[1][2] = a12; - r[2][0] = a20; - r[2][1] = a21; - r[2][2] = a22; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/rxp.c b/ast/erfa/rxp.c deleted file mode 100644 index f1dbe82..0000000 --- a/ast/erfa/rxp.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "erfa.h" - -void eraRxp(double r[3][3], double p[3], double rp[3]) -/* -** - - - - - - - -** e r a R x p -** - - - - - - - -** -** Multiply a p-vector by an r-matrix. -** -** Given: -** r double[3][3] r-matrix -** p double[3] p-vector -** -** Returned: -** rp double[3] r * p -** -** Note: -** It is permissible for p and rp to be the same array. -** -** Called: -** eraCp copy p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double w, wrp[3]; - int i, j; - - -/* Matrix r * vector p. */ - for (j = 0; j < 3; j++) { - w = 0.0; - for (i = 0; i < 3; i++) { - w += r[j][i] * p[i]; - } - wrp[j] = w; - } - -/* Return the result. */ - eraCp(wrp, rp); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/rxpv.c b/ast/erfa/rxpv.c deleted file mode 100644 index f7bb53d..0000000 --- a/ast/erfa/rxpv.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "erfa.h" - -void eraRxpv(double r[3][3], double pv[2][3], double rpv[2][3]) -/* -** - - - - - - - - -** e r a R x p v -** - - - - - - - - -** -** Multiply a pv-vector by an r-matrix. -** -** Given: -** r double[3][3] r-matrix -** pv double[2][3] pv-vector -** -** Returned: -** rpv double[2][3] r * pv -** -** Note: -** It is permissible for pv and rpv to be the same array. -** -** Called: -** eraRxp product of r-matrix and p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraRxp(r, pv[0], rpv[0]); - eraRxp(r, pv[1], rpv[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/rxr.c b/ast/erfa/rxr.c deleted file mode 100644 index ff0485b..0000000 --- a/ast/erfa/rxr.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "erfa.h" - -void eraRxr(double a[3][3], double b[3][3], double atb[3][3]) -/* -** - - - - - - - -** e r a R x r -** - - - - - - - -** -** Multiply two r-matrices. -** -** Given: -** a double[3][3] first r-matrix -** b double[3][3] second r-matrix -** -** Returned: -** atb double[3][3] a * b -** -** Note: -** It is permissible to re-use the same array for any of the -** arguments. -** -** Called: -** eraCr copy r-matrix -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int i, j, k; - double w, wm[3][3]; - - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - w = 0.0; - for (k = 0; k < 3; k++) { - w += a[i][k] * b[k][j]; - } - wm[i][j] = w; - } - } - eraCr(wm, atb); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ry.c b/ast/erfa/ry.c deleted file mode 100644 index 193d7a9..0000000 --- a/ast/erfa/ry.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "erfa.h" - -void eraRy(double theta, double r[3][3]) -/* -** - - - - - - -** e r a R y -** - - - - - - -** -** Rotate an r-matrix about the y-axis. -** -** Given: -** theta double angle (radians) -** -** Given and returned: -** r double[3][3] r-matrix, rotated -** -** Notes: -** -** 1) Calling this function with positive theta incorporates in the -** supplied r-matrix r an additional rotation, about the y-axis, -** anticlockwise as seen looking towards the origin from positive y. -** -** 2) The additional rotation can be represented by this matrix: -** -** ( + cos(theta) 0 - sin(theta) ) -** ( ) -** ( 0 1 0 ) -** ( ) -** ( + sin(theta) 0 + cos(theta) ) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double s, c, a00, a01, a02, a20, a21, a22; - - - s = sin(theta); - c = cos(theta); - - a00 = c*r[0][0] - s*r[2][0]; - a01 = c*r[0][1] - s*r[2][1]; - a02 = c*r[0][2] - s*r[2][2]; - a20 = s*r[0][0] + c*r[2][0]; - a21 = s*r[0][1] + c*r[2][1]; - a22 = s*r[0][2] + c*r[2][2]; - - r[0][0] = a00; - r[0][1] = a01; - r[0][2] = a02; - r[2][0] = a20; - r[2][1] = a21; - r[2][2] = a22; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/rz.c b/ast/erfa/rz.c deleted file mode 100644 index 58a26e7..0000000 --- a/ast/erfa/rz.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "erfa.h" - -void eraRz(double psi, double r[3][3]) -/* -** - - - - - - -** e r a R z -** - - - - - - -** -** Rotate an r-matrix about the z-axis. -** -** Given: -** psi double angle (radians) -** -** Given and returned: -** r double[3][3] r-matrix, rotated -** -** Notes: -** -** 1) Calling this function with positive psi incorporates in the -** supplied r-matrix r an additional rotation, about the z-axis, -** anticlockwise as seen looking towards the origin from positive z. -** -** 2) The additional rotation can be represented by this matrix: -** -** ( + cos(psi) + sin(psi) 0 ) -** ( ) -** ( - sin(psi) + cos(psi) 0 ) -** ( ) -** ( 0 0 1 ) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double s, c, a00, a01, a02, a10, a11, a12; - - - s = sin(psi); - c = cos(psi); - - a00 = c*r[0][0] + s*r[1][0]; - a01 = c*r[0][1] + s*r[1][1]; - a02 = c*r[0][2] + s*r[1][2]; - a10 = - s*r[0][0] + c*r[1][0]; - a11 = - s*r[0][1] + c*r[1][1]; - a12 = - s*r[0][2] + c*r[1][2]; - - r[0][0] = a00; - r[0][1] = a01; - r[0][2] = a02; - r[1][0] = a10; - r[1][1] = a11; - r[1][2] = a12; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/s00.c b/ast/erfa/s00.c deleted file mode 100644 index 82d0a5f..0000000 --- a/ast/erfa/s00.c +++ /dev/null @@ -1,380 +0,0 @@ -#include "erfa.h" - -double eraS00(double date1, double date2, double x, double y) -/* -** - - - - - - - -** e r a S 0 0 -** - - - - - - - -** -** The CIO locator s, positioning the Celestial Intermediate Origin on -** the equator of the Celestial Intermediate Pole, given the CIP's X,Y -** coordinates. Compatible with IAU 2000A precession-nutation. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** x,y double CIP coordinates (Note 3) -** -** Returned (function value): -** double the CIO locator s in radians (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The CIO locator s is the difference between the right ascensions -** of the same point in two systems: the two systems are the GCRS -** and the CIP,CIO, and the point is the ascending node of the -** CIP equator. The quantity s remains below 0.1 arcsecond -** throughout 1900-2100. -** -** 3) The series used to compute s is in fact for s+XY/2, where X and Y -** are the x and y components of the CIP unit vector; this series -** is more compact than a direct series for s would be. This -** function requires X,Y to be supplied by the caller, who is -** responsible for providing values that are consistent with the -** supplied date. -** -** 4) The model is consistent with the IAU 2000A precession-nutation. -** -** Called: -** eraFal03 mean anomaly of the Moon -** eraFalp03 mean anomaly of the Sun -** eraFaf03 mean argument of the latitude of the Moon -** eraFad03 mean elongation of the Moon from the Sun -** eraFaom03 mean longitude of the Moon's ascending node -** eraFave03 mean longitude of Venus -** eraFae03 mean longitude of Earth -** eraFapa03 general accumulated precession in longitude -** -** References: -** -** Capitaine, N., Chapront, J., Lambert, S. and Wallace, P., -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Time since J2000.0, in Julian centuries */ - double t; - -/* Miscellaneous */ - int i, j; - double a, w0, w1, w2, w3, w4, w5; - -/* Fundamental arguments */ - double fa[8]; - -/* Returned value */ - double s; - -/* --------------------- */ -/* The series for s+XY/2 */ -/* --------------------- */ - - typedef struct { - int nfa[8]; /* coefficients of l,l',F,D,Om,LVe,LE,pA */ - double s, c; /* sine and cosine coefficients */ - } TERM; - -/* Polynomial coefficients */ - static const double sp[] = { - - /* 1-6 */ - 94.00e-6, - 3808.35e-6, - -119.94e-6, - -72574.09e-6, - 27.70e-6, - 15.61e-6 - }; - -/* Terms of order t^0 */ - static const TERM s0[] = { - - /* 1-10 */ - {{ 0, 0, 0, 0, 1, 0, 0, 0}, -2640.73e-6, 0.39e-6 }, - {{ 0, 0, 0, 0, 2, 0, 0, 0}, -63.53e-6, 0.02e-6 }, - {{ 0, 0, 2, -2, 3, 0, 0, 0}, -11.75e-6, -0.01e-6 }, - {{ 0, 0, 2, -2, 1, 0, 0, 0}, -11.21e-6, -0.01e-6 }, - {{ 0, 0, 2, -2, 2, 0, 0, 0}, 4.57e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 3, 0, 0, 0}, -2.02e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 1, 0, 0, 0}, -1.98e-6, 0.00e-6 }, - {{ 0, 0, 0, 0, 3, 0, 0, 0}, 1.72e-6, 0.00e-6 }, - {{ 0, 1, 0, 0, 1, 0, 0, 0}, 1.41e-6, 0.01e-6 }, - {{ 0, 1, 0, 0, -1, 0, 0, 0}, 1.26e-6, 0.01e-6 }, - - /* 11-20 */ - {{ 1, 0, 0, 0, -1, 0, 0, 0}, 0.63e-6, 0.00e-6 }, - {{ 1, 0, 0, 0, 1, 0, 0, 0}, 0.63e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 3, 0, 0, 0}, -0.46e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 1, 0, 0, 0}, -0.45e-6, 0.00e-6 }, - {{ 0, 0, 4, -4, 4, 0, 0, 0}, -0.36e-6, 0.00e-6 }, - {{ 0, 0, 1, -1, 1, -8, 12, 0}, 0.24e-6, 0.12e-6 }, - {{ 0, 0, 2, 0, 0, 0, 0, 0}, -0.32e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 2, 0, 0, 0}, -0.28e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 3, 0, 0, 0}, -0.27e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 1, 0, 0, 0}, -0.26e-6, 0.00e-6 }, - - /* 21-30 */ - {{ 0, 0, 2, -2, 0, 0, 0, 0}, 0.21e-6, 0.00e-6 }, - {{ 0, 1, -2, 2, -3, 0, 0, 0}, -0.19e-6, 0.00e-6 }, - {{ 0, 1, -2, 2, -1, 0, 0, 0}, -0.18e-6, 0.00e-6 }, - {{ 0, 0, 0, 0, 0, 8,-13, -1}, 0.10e-6, -0.05e-6 }, - {{ 0, 0, 0, 2, 0, 0, 0, 0}, -0.15e-6, 0.00e-6 }, - {{ 2, 0, -2, 0, -1, 0, 0, 0}, 0.14e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 2, 0, 0, 0}, 0.14e-6, 0.00e-6 }, - {{ 1, 0, 0, -2, 1, 0, 0, 0}, -0.14e-6, 0.00e-6 }, - {{ 1, 0, 0, -2, -1, 0, 0, 0}, -0.14e-6, 0.00e-6 }, - {{ 0, 0, 4, -2, 4, 0, 0, 0}, -0.13e-6, 0.00e-6 }, - - /* 31-33 */ - {{ 0, 0, 2, -2, 4, 0, 0, 0}, 0.11e-6, 0.00e-6 }, - {{ 1, 0, -2, 0, -3, 0, 0, 0}, -0.11e-6, 0.00e-6 }, - {{ 1, 0, -2, 0, -1, 0, 0, 0}, -0.11e-6, 0.00e-6 } - }; - -/* Terms of order t^1 */ - static const TERM s1[] ={ - - /* 1-3 */ - {{ 0, 0, 0, 0, 2, 0, 0, 0}, -0.07e-6, 3.57e-6 }, - {{ 0, 0, 0, 0, 1, 0, 0, 0}, 1.71e-6, -0.03e-6 }, - {{ 0, 0, 2, -2, 3, 0, 0, 0}, 0.00e-6, 0.48e-6 } - }; - -/* Terms of order t^2 */ - static const TERM s2[] ={ - - /* 1-10 */ - {{ 0, 0, 0, 0, 1, 0, 0, 0}, 743.53e-6, -0.17e-6 }, - {{ 0, 0, 2, -2, 2, 0, 0, 0}, 56.91e-6, 0.06e-6 }, - {{ 0, 0, 2, 0, 2, 0, 0, 0}, 9.84e-6, -0.01e-6 }, - {{ 0, 0, 0, 0, 2, 0, 0, 0}, -8.85e-6, 0.01e-6 }, - {{ 0, 1, 0, 0, 0, 0, 0, 0}, -6.38e-6, -0.05e-6 }, - {{ 1, 0, 0, 0, 0, 0, 0, 0}, -3.07e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 2, 0, 0, 0}, 2.23e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 1, 0, 0, 0}, 1.67e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 2, 0, 0, 0}, 1.30e-6, 0.00e-6 }, - {{ 0, 1, -2, 2, -2, 0, 0, 0}, 0.93e-6, 0.00e-6 }, - - /* 11-20 */ - {{ 1, 0, 0, -2, 0, 0, 0, 0}, 0.68e-6, 0.00e-6 }, - {{ 0, 0, 2, -2, 1, 0, 0, 0}, -0.55e-6, 0.00e-6 }, - {{ 1, 0, -2, 0, -2, 0, 0, 0}, 0.53e-6, 0.00e-6 }, - {{ 0, 0, 0, 2, 0, 0, 0, 0}, -0.27e-6, 0.00e-6 }, - {{ 1, 0, 0, 0, 1, 0, 0, 0}, -0.27e-6, 0.00e-6 }, - {{ 1, 0, -2, -2, -2, 0, 0, 0}, -0.26e-6, 0.00e-6 }, - {{ 1, 0, 0, 0, -1, 0, 0, 0}, -0.25e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 1, 0, 0, 0}, 0.22e-6, 0.00e-6 }, - {{ 2, 0, 0, -2, 0, 0, 0, 0}, -0.21e-6, 0.00e-6 }, - {{ 2, 0, -2, 0, -1, 0, 0, 0}, 0.20e-6, 0.00e-6 }, - - /* 21-25 */ - {{ 0, 0, 2, 2, 2, 0, 0, 0}, 0.17e-6, 0.00e-6 }, - {{ 2, 0, 2, 0, 2, 0, 0, 0}, 0.13e-6, 0.00e-6 }, - {{ 2, 0, 0, 0, 0, 0, 0, 0}, -0.13e-6, 0.00e-6 }, - {{ 1, 0, 2, -2, 2, 0, 0, 0}, -0.12e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 0, 0, 0, 0}, -0.11e-6, 0.00e-6 } - }; - -/* Terms of order t^3 */ - static const TERM s3[] ={ - - /* 1-4 */ - {{ 0, 0, 0, 0, 1, 0, 0, 0}, 0.30e-6, -23.51e-6 }, - {{ 0, 0, 2, -2, 2, 0, 0, 0}, -0.03e-6, -1.39e-6 }, - {{ 0, 0, 2, 0, 2, 0, 0, 0}, -0.01e-6, -0.24e-6 }, - {{ 0, 0, 0, 0, 2, 0, 0, 0}, 0.00e-6, 0.22e-6 } - }; - -/* Terms of order t^4 */ - static const TERM s4[] ={ - - /* 1-1 */ - {{ 0, 0, 0, 0, 1, 0, 0, 0}, -0.26e-6, -0.01e-6 } - }; - -/* Number of terms in the series */ - const int NS0 = (int) (sizeof s0 / sizeof (TERM)); - const int NS1 = (int) (sizeof s1 / sizeof (TERM)); - const int NS2 = (int) (sizeof s2 / sizeof (TERM)); - const int NS3 = (int) (sizeof s3 / sizeof (TERM)); - const int NS4 = (int) (sizeof s4 / sizeof (TERM)); - -/*--------------------------------------------------------------------*/ - -/* Interval between fundamental epoch J2000.0 and current date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Fundamental Arguments (from IERS Conventions 2003) */ - -/* Mean anomaly of the Moon. */ - fa[0] = eraFal03(t); - -/* Mean anomaly of the Sun. */ - fa[1] = eraFalp03(t); - -/* Mean longitude of the Moon minus that of the ascending node. */ - fa[2] = eraFaf03(t); - -/* Mean elongation of the Moon from the Sun. */ - fa[3] = eraFad03(t); - -/* Mean longitude of the ascending node of the Moon. */ - fa[4] = eraFaom03(t); - -/* Mean longitude of Venus. */ - fa[5] = eraFave03(t); - -/* Mean longitude of Earth. */ - fa[6] = eraFae03(t); - -/* General precession in longitude. */ - fa[7] = eraFapa03(t); - -/* Evaluate s. */ - w0 = sp[0]; - w1 = sp[1]; - w2 = sp[2]; - w3 = sp[3]; - w4 = sp[4]; - w5 = sp[5]; - - for (i = NS0-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s0[i].nfa[j] * fa[j]; - } - w0 += s0[i].s * sin(a) + s0[i].c * cos(a); - } - - for (i = NS1-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s1[i].nfa[j] * fa[j]; - } - w1 += s1[i].s * sin(a) + s1[i].c * cos(a); - } - - for (i = NS2-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s2[i].nfa[j] * fa[j]; - } - w2 += s2[i].s * sin(a) + s2[i].c * cos(a); - } - - for (i = NS3-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s3[i].nfa[j] * fa[j]; - } - w3 += s3[i].s * sin(a) + s3[i].c * cos(a); - } - - for (i = NS4-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s4[i].nfa[j] * fa[j]; - } - w4 += s4[i].s * sin(a) + s4[i].c * cos(a); - } - - s = (w0 + - (w1 + - (w2 + - (w3 + - (w4 + - w5 * t) * t) * t) * t) * t) * ERFA_DAS2R - x*y/2.0; - - return s; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/s00a.c b/ast/erfa/s00a.c deleted file mode 100644 index a65bb30..0000000 --- a/ast/erfa/s00a.c +++ /dev/null @@ -1,152 +0,0 @@ -#include "erfa.h" - -double eraS00a(double date1, double date2) -/* -** - - - - - - - - -** e r a S 0 0 a -** - - - - - - - - -** -** The CIO locator s, positioning the Celestial Intermediate Origin on -** the equator of the Celestial Intermediate Pole, using the IAU 2000A -** precession-nutation model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double the CIO locator s in radians (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The CIO locator s is the difference between the right ascensions -** of the same point in two systems. The two systems are the GCRS -** and the CIP,CIO, and the point is the ascending node of the -** CIP equator. The CIO locator s remains a small fraction of -** 1 arcsecond throughout 1900-2100. -** -** 3) The series used to compute s is in fact for s+XY/2, where X and Y -** are the x and y components of the CIP unit vector; this series -** is more compact than a direct series for s would be. The present -** function uses the full IAU 2000A nutation model when predicting -** the CIP position. Faster results, with no significant loss of -** accuracy, can be obtained via the function eraS00b, which uses -** instead the IAU 2000B truncated model. -** -** Called: -** eraPnm00a classical NPB matrix, IAU 2000A -** eraBnp2xy extract CIP X,Y from the BPN matrix -** eraS00 the CIO locator s, given X,Y, IAU 2000A -** -** References: -** -** Capitaine, N., Chapront, J., Lambert, S. and Wallace, P., -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rbpn[3][3], x, y, s; - - -/* Bias-precession-nutation-matrix, IAU 2000A. */ - eraPnm00a(date1, date2, rbpn); - -/* Extract the CIP coordinates. */ - eraBpn2xy(rbpn, &x, &y); - -/* Compute the CIO locator s, given the CIP coordinates. */ - s = eraS00(date1, date2, x, y); - - return s; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/s00b.c b/ast/erfa/s00b.c deleted file mode 100644 index 370f95b..0000000 --- a/ast/erfa/s00b.c +++ /dev/null @@ -1,152 +0,0 @@ -#include "erfa.h" - -double eraS00b(double date1, double date2) -/* -** - - - - - - - - -** e r a S 0 0 b -** - - - - - - - - -** -** The CIO locator s, positioning the Celestial Intermediate Origin on -** the equator of the Celestial Intermediate Pole, using the IAU 2000B -** precession-nutation model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double the CIO locator s in radians (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The CIO locator s is the difference between the right ascensions -** of the same point in two systems. The two systems are the GCRS -** and the CIP,CIO, and the point is the ascending node of the -** CIP equator. The CIO locator s remains a small fraction of -** 1 arcsecond throughout 1900-2100. -** -** 3) The series used to compute s is in fact for s+XY/2, where X and Y -** are the x and y components of the CIP unit vector; this series -** is more compact than a direct series for s would be. The present -** function uses the IAU 2000B truncated nutation model when -** predicting the CIP position. The function eraS00a uses instead -** the full IAU 2000A model, but with no significant increase in -** accuracy and at some cost in speed. -** -** Called: -** eraPnm00b classical NPB matrix, IAU 2000B -** eraBnp2xy extract CIP X,Y from the BPN matrix -** eraS00 the CIO locator s, given X,Y, IAU 2000A -** -** References: -** -** Capitaine, N., Chapront, J., Lambert, S. and Wallace, P., -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rbpn[3][3], x, y, s; - - -/* Bias-precession-nutation-matrix, IAU 2000B. */ - eraPnm00b(date1, date2, rbpn); - -/* Extract the CIP coordinates. */ - eraBpn2xy(rbpn, &x, &y); - -/* Compute the CIO locator s, given the CIP coordinates. */ - s = eraS00(date1, date2, x, y); - - return s; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/s06.c b/ast/erfa/s06.c deleted file mode 100644 index 21546c5..0000000 --- a/ast/erfa/s06.c +++ /dev/null @@ -1,377 +0,0 @@ -#include "erfa.h" - -double eraS06(double date1, double date2, double x, double y) -/* -** - - - - - - - -** e r a S 0 6 -** - - - - - - - -** -** The CIO locator s, positioning the Celestial Intermediate Origin on -** the equator of the Celestial Intermediate Pole, given the CIP's X,Y -** coordinates. Compatible with IAU 2006/2000A precession-nutation. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** x,y double CIP coordinates (Note 3) -** -** Returned (function value): -** double the CIO locator s in radians (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The CIO locator s is the difference between the right ascensions -** of the same point in two systems: the two systems are the GCRS -** and the CIP,CIO, and the point is the ascending node of the -** CIP equator. The quantity s remains below 0.1 arcsecond -** throughout 1900-2100. -** -** 3) The series used to compute s is in fact for s+XY/2, where X and Y -** are the x and y components of the CIP unit vector; this series -** is more compact than a direct series for s would be. This -** function requires X,Y to be supplied by the caller, who is -** responsible for providing values that are consistent with the -** supplied date. -** -** 4) The model is consistent with the "P03" precession (Capitaine et -** al. 2003), adopted by IAU 2006 Resolution 1, 2006, and the -** IAU 2000A nutation (with P03 adjustments). -** -** Called: -** eraFal03 mean anomaly of the Moon -** eraFalp03 mean anomaly of the Sun -** eraFaf03 mean argument of the latitude of the Moon -** eraFad03 mean elongation of the Moon from the Sun -** eraFaom03 mean longitude of the Moon's ascending node -** eraFave03 mean longitude of Venus -** eraFae03 mean longitude of Earth -** eraFapa03 general accumulated precession in longitude -** -** References: -** -** Capitaine, N., Wallace, P.T. & Chapront, J., 2003, Astron. -** Astrophys. 432, 355 -** -** McCarthy, D.D., Petit, G. (eds.) 2004, IERS Conventions (2003), -** IERS Technical Note No. 32, BKG -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Time since J2000.0, in Julian centuries */ - double t; - -/* Miscellaneous */ - int i, j; - double a, w0, w1, w2, w3, w4, w5; - -/* Fundamental arguments */ - double fa[8]; - -/* Returned value */ - double s; - -/* --------------------- */ -/* The series for s+XY/2 */ -/* --------------------- */ - - typedef struct { - int nfa[8]; /* coefficients of l,l',F,D,Om,LVe,LE,pA */ - double s, c; /* sine and cosine coefficients */ - } TERM; - -/* Polynomial coefficients */ - static const double sp[] = { - - /* 1-6 */ - 94.00e-6, - 3808.65e-6, - -122.68e-6, - -72574.11e-6, - 27.98e-6, - 15.62e-6 - }; - -/* Terms of order t^0 */ - static const TERM s0[] = { - - /* 1-10 */ - {{ 0, 0, 0, 0, 1, 0, 0, 0}, -2640.73e-6, 0.39e-6 }, - {{ 0, 0, 0, 0, 2, 0, 0, 0}, -63.53e-6, 0.02e-6 }, - {{ 0, 0, 2, -2, 3, 0, 0, 0}, -11.75e-6, -0.01e-6 }, - {{ 0, 0, 2, -2, 1, 0, 0, 0}, -11.21e-6, -0.01e-6 }, - {{ 0, 0, 2, -2, 2, 0, 0, 0}, 4.57e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 3, 0, 0, 0}, -2.02e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 1, 0, 0, 0}, -1.98e-6, 0.00e-6 }, - {{ 0, 0, 0, 0, 3, 0, 0, 0}, 1.72e-6, 0.00e-6 }, - {{ 0, 1, 0, 0, 1, 0, 0, 0}, 1.41e-6, 0.01e-6 }, - {{ 0, 1, 0, 0, -1, 0, 0, 0}, 1.26e-6, 0.01e-6 }, - - /* 11-20 */ - {{ 1, 0, 0, 0, -1, 0, 0, 0}, 0.63e-6, 0.00e-6 }, - {{ 1, 0, 0, 0, 1, 0, 0, 0}, 0.63e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 3, 0, 0, 0}, -0.46e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 1, 0, 0, 0}, -0.45e-6, 0.00e-6 }, - {{ 0, 0, 4, -4, 4, 0, 0, 0}, -0.36e-6, 0.00e-6 }, - {{ 0, 0, 1, -1, 1, -8, 12, 0}, 0.24e-6, 0.12e-6 }, - {{ 0, 0, 2, 0, 0, 0, 0, 0}, -0.32e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 2, 0, 0, 0}, -0.28e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 3, 0, 0, 0}, -0.27e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 1, 0, 0, 0}, -0.26e-6, 0.00e-6 }, - - /* 21-30 */ - {{ 0, 0, 2, -2, 0, 0, 0, 0}, 0.21e-6, 0.00e-6 }, - {{ 0, 1, -2, 2, -3, 0, 0, 0}, -0.19e-6, 0.00e-6 }, - {{ 0, 1, -2, 2, -1, 0, 0, 0}, -0.18e-6, 0.00e-6 }, - {{ 0, 0, 0, 0, 0, 8,-13, -1}, 0.10e-6, -0.05e-6 }, - {{ 0, 0, 0, 2, 0, 0, 0, 0}, -0.15e-6, 0.00e-6 }, - {{ 2, 0, -2, 0, -1, 0, 0, 0}, 0.14e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 2, 0, 0, 0}, 0.14e-6, 0.00e-6 }, - {{ 1, 0, 0, -2, 1, 0, 0, 0}, -0.14e-6, 0.00e-6 }, - {{ 1, 0, 0, -2, -1, 0, 0, 0}, -0.14e-6, 0.00e-6 }, - {{ 0, 0, 4, -2, 4, 0, 0, 0}, -0.13e-6, 0.00e-6 }, - - /* 31-33 */ - {{ 0, 0, 2, -2, 4, 0, 0, 0}, 0.11e-6, 0.00e-6 }, - {{ 1, 0, -2, 0, -3, 0, 0, 0}, -0.11e-6, 0.00e-6 }, - {{ 1, 0, -2, 0, -1, 0, 0, 0}, -0.11e-6, 0.00e-6 } - }; - -/* Terms of order t^1 */ - static const TERM s1[] = { - - /* 1 - 3 */ - {{ 0, 0, 0, 0, 2, 0, 0, 0}, -0.07e-6, 3.57e-6 }, - {{ 0, 0, 0, 0, 1, 0, 0, 0}, 1.73e-6, -0.03e-6 }, - {{ 0, 0, 2, -2, 3, 0, 0, 0}, 0.00e-6, 0.48e-6 } - }; - -/* Terms of order t^2 */ - static const TERM s2[] = { - - /* 1-10 */ - {{ 0, 0, 0, 0, 1, 0, 0, 0}, 743.52e-6, -0.17e-6 }, - {{ 0, 0, 2, -2, 2, 0, 0, 0}, 56.91e-6, 0.06e-6 }, - {{ 0, 0, 2, 0, 2, 0, 0, 0}, 9.84e-6, -0.01e-6 }, - {{ 0, 0, 0, 0, 2, 0, 0, 0}, -8.85e-6, 0.01e-6 }, - {{ 0, 1, 0, 0, 0, 0, 0, 0}, -6.38e-6, -0.05e-6 }, - {{ 1, 0, 0, 0, 0, 0, 0, 0}, -3.07e-6, 0.00e-6 }, - {{ 0, 1, 2, -2, 2, 0, 0, 0}, 2.23e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 1, 0, 0, 0}, 1.67e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 2, 0, 0, 0}, 1.30e-6, 0.00e-6 }, - {{ 0, 1, -2, 2, -2, 0, 0, 0}, 0.93e-6, 0.00e-6 }, - - /* 11-20 */ - {{ 1, 0, 0, -2, 0, 0, 0, 0}, 0.68e-6, 0.00e-6 }, - {{ 0, 0, 2, -2, 1, 0, 0, 0}, -0.55e-6, 0.00e-6 }, - {{ 1, 0, -2, 0, -2, 0, 0, 0}, 0.53e-6, 0.00e-6 }, - {{ 0, 0, 0, 2, 0, 0, 0, 0}, -0.27e-6, 0.00e-6 }, - {{ 1, 0, 0, 0, 1, 0, 0, 0}, -0.27e-6, 0.00e-6 }, - {{ 1, 0, -2, -2, -2, 0, 0, 0}, -0.26e-6, 0.00e-6 }, - {{ 1, 0, 0, 0, -1, 0, 0, 0}, -0.25e-6, 0.00e-6 }, - {{ 1, 0, 2, 0, 1, 0, 0, 0}, 0.22e-6, 0.00e-6 }, - {{ 2, 0, 0, -2, 0, 0, 0, 0}, -0.21e-6, 0.00e-6 }, - {{ 2, 0, -2, 0, -1, 0, 0, 0}, 0.20e-6, 0.00e-6 }, - - /* 21-25 */ - {{ 0, 0, 2, 2, 2, 0, 0, 0}, 0.17e-6, 0.00e-6 }, - {{ 2, 0, 2, 0, 2, 0, 0, 0}, 0.13e-6, 0.00e-6 }, - {{ 2, 0, 0, 0, 0, 0, 0, 0}, -0.13e-6, 0.00e-6 }, - {{ 1, 0, 2, -2, 2, 0, 0, 0}, -0.12e-6, 0.00e-6 }, - {{ 0, 0, 2, 0, 0, 0, 0, 0}, -0.11e-6, 0.00e-6 } - }; - -/* Terms of order t^3 */ - static const TERM s3[] = { - - /* 1-4 */ - {{ 0, 0, 0, 0, 1, 0, 0, 0}, 0.30e-6, -23.42e-6 }, - {{ 0, 0, 2, -2, 2, 0, 0, 0}, -0.03e-6, -1.46e-6 }, - {{ 0, 0, 2, 0, 2, 0, 0, 0}, -0.01e-6, -0.25e-6 }, - {{ 0, 0, 0, 0, 2, 0, 0, 0}, 0.00e-6, 0.23e-6 } - }; - -/* Terms of order t^4 */ - static const TERM s4[] = { - - /* 1-1 */ - {{ 0, 0, 0, 0, 1, 0, 0, 0}, -0.26e-6, -0.01e-6 } - }; - -/* Number of terms in the series */ - static const int NS0 = (int) (sizeof s0 / sizeof (TERM)); - static const int NS1 = (int) (sizeof s1 / sizeof (TERM)); - static const int NS2 = (int) (sizeof s2 / sizeof (TERM)); - static const int NS3 = (int) (sizeof s3 / sizeof (TERM)); - static const int NS4 = (int) (sizeof s4 / sizeof (TERM)); - -/*--------------------------------------------------------------------*/ - -/* Interval between fundamental epoch J2000.0 and current date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Fundamental Arguments (from IERS Conventions 2003) */ - -/* Mean anomaly of the Moon. */ - fa[0] = eraFal03(t); - -/* Mean anomaly of the Sun. */ - fa[1] = eraFalp03(t); - -/* Mean longitude of the Moon minus that of the ascending node. */ - fa[2] = eraFaf03(t); - -/* Mean elongation of the Moon from the Sun. */ - fa[3] = eraFad03(t); - -/* Mean longitude of the ascending node of the Moon. */ - fa[4] = eraFaom03(t); - -/* Mean longitude of Venus. */ - fa[5] = eraFave03(t); - -/* Mean longitude of Earth. */ - fa[6] = eraFae03(t); - -/* General precession in longitude. */ - fa[7] = eraFapa03(t); - -/* Evaluate s. */ - w0 = sp[0]; - w1 = sp[1]; - w2 = sp[2]; - w3 = sp[3]; - w4 = sp[4]; - w5 = sp[5]; - - for (i = NS0-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s0[i].nfa[j] * fa[j]; - } - w0 += s0[i].s * sin(a) + s0[i].c * cos(a); - } - - for (i = NS1-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s1[i].nfa[j] * fa[j]; - } - w1 += s1[i].s * sin(a) + s1[i].c * cos(a); - } - - for (i = NS2-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s2[i].nfa[j] * fa[j]; - } - w2 += s2[i].s * sin(a) + s2[i].c * cos(a); - } - - for (i = NS3-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s3[i].nfa[j] * fa[j]; - } - w3 += s3[i].s * sin(a) + s3[i].c * cos(a); - } - - for (i = NS4-1; i >= 0; i--) { - a = 0.0; - for (j = 0; j < 8; j++) { - a += (double)s4[i].nfa[j] * fa[j]; - } - w4 += s4[i].s * sin(a) + s4[i].c * cos(a); - } - - s = (w0 + - (w1 + - (w2 + - (w3 + - (w4 + - w5 * t) * t) * t) * t) * t) * ERFA_DAS2R - x*y/2.0; - - return s; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/s06a.c b/ast/erfa/s06a.c deleted file mode 100644 index 575c3dd..0000000 --- a/ast/erfa/s06a.c +++ /dev/null @@ -1,154 +0,0 @@ -#include "erfa.h" - -double eraS06a(double date1, double date2) -/* -** - - - - - - - - -** e r a S 0 6 a -** - - - - - - - - -** -** The CIO locator s, positioning the Celestial Intermediate Origin on -** the equator of the Celestial Intermediate Pole, using the IAU 2006 -** precession and IAU 2000A nutation models. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double the CIO locator s in radians (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The CIO locator s is the difference between the right ascensions -** of the same point in two systems. The two systems are the GCRS -** and the CIP,CIO, and the point is the ascending node of the -** CIP equator. The CIO locator s remains a small fraction of -** 1 arcsecond throughout 1900-2100. -** -** 3) The series used to compute s is in fact for s+XY/2, where X and Y -** are the x and y components of the CIP unit vector; this series is -** more compact than a direct series for s would be. The present -** function uses the full IAU 2000A nutation model when predicting -** the CIP position. -** -** Called: -** eraPnm06a classical NPB matrix, IAU 2006/2000A -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraS06 the CIO locator s, given X,Y, IAU 2006 -** -** References: -** -** Capitaine, N., Chapront, J., Lambert, S. and Wallace, P., -** "Expressions for the Celestial Intermediate Pole and Celestial -** Ephemeris Origin consistent with the IAU 2000A precession- -** nutation model", Astron.Astrophys. 400, 1145-1154 (2003) -** -** n.b. The celestial ephemeris origin (CEO) was renamed "celestial -** intermediate origin" (CIO) by IAU 2006 Resolution 2. -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855 -** -** McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003), -** IERS Technical Note No. 32, BKG -** -** Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rnpb[3][3], x, y, s; - - -/* Bias-precession-nutation-matrix, IAU 20006/2000A. */ - eraPnm06a(date1, date2, rnpb); - -/* Extract the CIP coordinates. */ - eraBpn2xy(rnpb, &x, &y); - -/* Compute the CIO locator s, given the CIP coordinates. */ - s = eraS06(date1, date2, x, y); - - return s; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/s2c.c b/ast/erfa/s2c.c deleted file mode 100644 index 067cec1..0000000 --- a/ast/erfa/s2c.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "erfa.h" - -void eraS2c(double theta, double phi, double c[3]) -/* -** - - - - - - - -** e r a S 2 c -** - - - - - - - -** -** Convert spherical coordinates to Cartesian. -** -** Given: -** theta double longitude angle (radians) -** phi double latitude angle (radians) -** -** Returned: -** c double[3] direction cosines -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double cp; - - - cp = cos(phi); - c[0] = cos(theta) * cp; - c[1] = sin(theta) * cp; - c[2] = sin(phi); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/s2p.c b/ast/erfa/s2p.c deleted file mode 100644 index a9b02bb..0000000 --- a/ast/erfa/s2p.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "erfa.h" - -void eraS2p(double theta, double phi, double r, double p[3]) -/* -** - - - - - - - -** e r a S 2 p -** - - - - - - - -** -** Convert spherical polar coordinates to p-vector. -** -** Given: -** theta double longitude angle (radians) -** phi double latitude angle (radians) -** r double radial distance -** -** Returned: -** p double[3] Cartesian coordinates -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraSxp multiply p-vector by scalar -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double u[3]; - - - eraS2c(theta, phi, u); - eraSxp(r, u, p); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/s2pv.c b/ast/erfa/s2pv.c deleted file mode 100644 index df6e1c7..0000000 --- a/ast/erfa/s2pv.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "erfa.h" - -void eraS2pv(double theta, double phi, double r, - double td, double pd, double rd, - double pv[2][3]) -/* -** - - - - - - - - -** e r a S 2 p v -** - - - - - - - - -** -** Convert position/velocity from spherical to Cartesian coordinates. -** -** Given: -** theta double longitude angle (radians) -** phi double latitude angle (radians) -** r double radial distance -** td double rate of change of theta -** pd double rate of change of phi -** rd double rate of change of r -** -** Returned: -** pv double[2][3] pv-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double st, ct, sp, cp, rcp, x, y, rpd, w; - - - st = sin(theta); - ct = cos(theta); - sp = sin(phi); - cp = cos(phi); - rcp = r * cp; - x = rcp * ct; - y = rcp * st; - rpd = r * pd; - w = rpd*sp - cp*rd; - - pv[0][0] = x; - pv[0][1] = y; - pv[0][2] = r * sp; - pv[1][0] = -y*td - w*ct; - pv[1][1] = x*td - w*st; - pv[1][2] = rpd*cp + sp*rd; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/s2xpv.c b/ast/erfa/s2xpv.c deleted file mode 100644 index 9b554da..0000000 --- a/ast/erfa/s2xpv.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "erfa.h" - -void eraS2xpv(double s1, double s2, double pv[2][3], double spv[2][3]) -/* -** - - - - - - - - - -** e r a S 2 x p v -** - - - - - - - - - -** -** Multiply a pv-vector by two scalars. -** -** Given: -** s1 double scalar to multiply position component by -** s2 double scalar to multiply velocity component by -** pv double[2][3] pv-vector -** -** Returned: -** spv double[2][3] pv-vector: p scaled by s1, v scaled by s2 -** -** Note: -** It is permissible for pv and spv to be the same array. -** -** Called: -** eraSxp multiply p-vector by scalar -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraSxp(s1, pv[0], spv[0]); - eraSxp(s2, pv[1], spv[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/sepp.c b/ast/erfa/sepp.c deleted file mode 100644 index 98f2671..0000000 --- a/ast/erfa/sepp.c +++ /dev/null @@ -1,114 +0,0 @@ -#include "erfa.h" - -double eraSepp(double a[3], double b[3]) -/* -** - - - - - - - - -** e r a S e p p -** - - - - - - - - -** -** Angular separation between two p-vectors. -** -** Given: -** a double[3] first p-vector (not necessarily unit length) -** b double[3] second p-vector (not necessarily unit length) -** -** Returned (function value): -** double angular separation (radians, always positive) -** -** Notes: -** -** 1) If either vector is null, a zero result is returned. -** -** 2) The angular separation is most simply formulated in terms of -** scalar product. However, this gives poor accuracy for angles -** near zero and pi. The present algorithm uses both cross product -** and dot product, to deliver full accuracy whatever the size of -** the angle. -** -** Called: -** eraPxp vector product of two p-vectors -** eraPm modulus of p-vector -** eraPdp scalar product of two p-vectors -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double axb[3], ss, cs, s; - - -/* Sine of angle between the vectors, multiplied by the two moduli. */ - eraPxp(a, b, axb); - ss = eraPm(axb); - -/* Cosine of the angle, multiplied by the two moduli. */ - cs = eraPdp(a, b); - -/* The angle. */ - s = ((ss != 0.0) || (cs != 0.0)) ? atan2(ss, cs) : 0.0; - - return s; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/seps.c b/ast/erfa/seps.c deleted file mode 100644 index f97fc58..0000000 --- a/ast/erfa/seps.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "erfa.h" - -double eraSeps(double al, double ap, double bl, double bp) -/* -** - - - - - - - - -** e r a S e p s -** - - - - - - - - -** -** Angular separation between two sets of spherical coordinates. -** -** Given: -** al double first longitude (radians) -** ap double first latitude (radians) -** bl double second longitude (radians) -** bp double second latitude (radians) -** -** Returned (function value): -** double angular separation (radians) -** -** Called: -** eraS2c spherical coordinates to unit vector -** eraSepp angular separation between two p-vectors -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double ac[3], bc[3], s; - - -/* Spherical to Cartesian. */ - eraS2c(al, ap, ac); - eraS2c(bl, bp, bc); - -/* Angle between the vectors. */ - s = eraSepp(ac, bc); - - return s; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/sp00.c b/ast/erfa/sp00.c deleted file mode 100644 index 7c57abd..0000000 --- a/ast/erfa/sp00.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "erfa.h" - -double eraSp00(double date1, double date2) -/* -** - - - - - - - - -** e r a S p 0 0 -** - - - - - - - - -** -** The TIO locator s', positioning the Terrestrial Intermediate Origin -** on the equator of the Celestial Intermediate Pole. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned (function value): -** double the TIO locator s' in radians (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The TIO locator s' is obtained from polar motion observations by -** numerical integration, and so is in essence unpredictable. -** However, it is dominated by a secular drift of about -** 47 microarcseconds per century, which is the approximation -** evaluated by the present function. -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double t, sp; - - -/* Interval between fundamental epoch J2000.0 and current date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Approximate s'. */ - sp = -47e-6 * t * ERFA_DAS2R; - - return sp; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/starpm.c b/ast/erfa/starpm.c deleted file mode 100644 index 69b7708..0000000 --- a/ast/erfa/starpm.c +++ /dev/null @@ -1,214 +0,0 @@ -#include "erfa.h" - -int eraStarpm(double ra1, double dec1, - double pmr1, double pmd1, double px1, double rv1, - double ep1a, double ep1b, double ep2a, double ep2b, - double *ra2, double *dec2, - double *pmr2, double *pmd2, double *px2, double *rv2) -/* -** - - - - - - - - - - -** e r a S t a r p m -** - - - - - - - - - - -** -** Star proper motion: update star catalog data for space motion. -** -** Given: -** ra1 double right ascension (radians), before -** dec1 double declination (radians), before -** pmr1 double RA proper motion (radians/year), before -** pmd1 double Dec proper motion (radians/year), before -** px1 double parallax (arcseconds), before -** rv1 double radial velocity (km/s, +ve = receding), before -** ep1a double "before" epoch, part A (Note 1) -** ep1b double "before" epoch, part B (Note 1) -** ep2a double "after" epoch, part A (Note 1) -** ep2b double "after" epoch, part B (Note 1) -** -** Returned: -** ra2 double right ascension (radians), after -** dec2 double declination (radians), after -** pmr2 double RA proper motion (radians/year), after -** pmd2 double Dec proper motion (radians/year), after -** px2 double parallax (arcseconds), after -** rv2 double radial velocity (km/s, +ve = receding), after -** -** Returned (function value): -** int status: -** -1 = system error (should not occur) -** 0 = no warnings or errors -** 1 = distance overridden (Note 6) -** 2 = excessive velocity (Note 7) -** 4 = solution didn't converge (Note 8) -** else = binary logical OR of the above warnings -** -** Notes: -** -** 1) The starting and ending TDB dates ep1a+ep1b and ep2a+ep2b are -** Julian Dates, apportioned in any convenient way between the two -** parts (A and B). For example, JD(TDB)=2450123.7 could be -** expressed in any of these ways, among others: -** -** epna epnb -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) In accordance with normal star-catalog conventions, the object's -** right ascension and declination are freed from the effects of -** secular aberration. The frame, which is aligned to the catalog -** equator and equinox, is Lorentzian and centered on the SSB. -** -** The proper motions are the rate of change of the right ascension -** and declination at the catalog epoch and are in radians per TDB -** Julian year. -** -** The parallax and radial velocity are in the same frame. -** -** 3) Care is needed with units. The star coordinates are in radians -** and the proper motions in radians per Julian year, but the -** parallax is in arcseconds. -** -** 4) The RA proper motion is in terms of coordinate angle, not true -** angle. If the catalog uses arcseconds for both RA and Dec proper -** motions, the RA proper motion will need to be divided by cos(Dec) -** before use. -** -** 5) Straight-line motion at constant speed, in the inertial frame, -** is assumed. -** -** 6) An extremely small (or zero or negative) parallax is interpreted -** to mean that the object is on the "celestial sphere", the radius -** of which is an arbitrary (large) value (see the eraStarpv -** function for the value used). When the distance is overridden in -** this way, the status, initially zero, has 1 added to it. -** -** 7) If the space velocity is a significant fraction of c (see the -** constant VMAX in the function eraStarpv), it is arbitrarily set -** to zero. When this action occurs, 2 is added to the status. -** -** 8) The relativistic adjustment carried out in the eraStarpv function -** involves an iterative calculation. If the process fails to -** converge within a set number of iterations, 4 is added to the -** status. -** -** Called: -** eraStarpv star catalog data to space motion pv-vector -** eraPvu update a pv-vector -** eraPdp scalar product of two p-vectors -** eraPvstar space motion pv-vector to star catalog data -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double pv1[2][3], tl1, dt, pv[2][3], r2, rdv, v2, c2mv2, tl2, - pv2[2][3]; - int j1, j2, j; - - -/* RA,Dec etc. at the "before" epoch to space motion pv-vector. */ - j1 = eraStarpv(ra1, dec1, pmr1, pmd1, px1, rv1, pv1); - -/* Light time when observed (days). */ - tl1 = eraPm(pv1[0]) / ERFA_DC; - -/* Time interval, "before" to "after" (days). */ - dt = (ep2a - ep1a) + (ep2b - ep1b); - -/* Move star along track from the "before" observed position to the */ -/* "after" geometric position. */ - eraPvu(dt + tl1, pv1, pv); - -/* From this geometric position, deduce the observed light time (days) */ -/* at the "after" epoch (with theoretically unneccessary error check). */ - r2 = eraPdp(pv[0], pv[0]); - rdv = eraPdp(pv[0], pv[1]); - v2 = eraPdp(pv[1], pv[1]); - c2mv2 = ERFA_DC*ERFA_DC - v2; - if (c2mv2 <= 0) return -1; - tl2 = (-rdv + sqrt(rdv*rdv + c2mv2*r2)) / c2mv2; - -/* Move the position along track from the observed place at the */ -/* "before" epoch to the observed place at the "after" epoch. */ - eraPvu(dt + (tl1 - tl2), pv1, pv2); - -/* Space motion pv-vector to RA,Dec etc. at the "after" epoch. */ - j2 = eraPvstar(pv2, ra2, dec2, pmr2, pmd2, px2, rv2); - -/* Final status. */ - j = (j2 == 0) ? j1 : -1; - - return j; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/starpv.c b/ast/erfa/starpv.c deleted file mode 100644 index 77173ed..0000000 --- a/ast/erfa/starpv.c +++ /dev/null @@ -1,273 +0,0 @@ -#include "erfa.h" - -int eraStarpv(double ra, double dec, - double pmr, double pmd, double px, double rv, - double pv[2][3]) -/* -** - - - - - - - - - - -** e r a S t a r p v -** - - - - - - - - - - -** -** Convert star catalog coordinates to position+velocity vector. -** -** Given (Note 1): -** ra double right ascension (radians) -** dec double declination (radians) -** pmr double RA proper motion (radians/year) -** pmd double Dec proper motion (radians/year) -** px double parallax (arcseconds) -** rv double radial velocity (km/s, positive = receding) -** -** Returned (Note 2): -** pv double[2][3] pv-vector (AU, AU/day) -** -** Returned (function value): -** int status: -** 0 = no warnings -** 1 = distance overridden (Note 6) -** 2 = excessive speed (Note 7) -** 4 = solution didn't converge (Note 8) -** else = binary logical OR of the above -** -** Notes: -** -** 1) The star data accepted by this function are "observables" for an -** imaginary observer at the solar-system barycenter. Proper motion -** and radial velocity are, strictly, in terms of barycentric -** coordinate time, TCB. For most practical applications, it is -** permissible to neglect the distinction between TCB and ordinary -** "proper" time on Earth (TT/TAI). The result will, as a rule, be -** limited by the intrinsic accuracy of the proper-motion and -** radial-velocity data; moreover, the pv-vector is likely to be -** merely an intermediate result, so that a change of time unit -** would cancel out overall. -** -** In accordance with normal star-catalog conventions, the object's -** right ascension and declination are freed from the effects of -** secular aberration. The frame, which is aligned to the catalog -** equator and equinox, is Lorentzian and centered on the SSB. -** -** 2) The resulting position and velocity pv-vector is with respect to -** the same frame and, like the catalog coordinates, is freed from -** the effects of secular aberration. Should the "coordinate -** direction", where the object was located at the catalog epoch, be -** required, it may be obtained by calculating the magnitude of the -** position vector pv[0][0-2] dividing by the speed of light in -** AU/day to give the light-time, and then multiplying the space -** velocity pv[1][0-2] by this light-time and adding the result to -** pv[0][0-2]. -** -** Summarizing, the pv-vector returned is for most stars almost -** identical to the result of applying the standard geometrical -** "space motion" transformation. The differences, which are the -** subject of the Stumpff paper referenced below, are: -** -** (i) In stars with significant radial velocity and proper motion, -** the constantly changing light-time distorts the apparent proper -** motion. Note that this is a classical, not a relativistic, -** effect. -** -** (ii) The transformation complies with special relativity. -** -** 3) Care is needed with units. The star coordinates are in radians -** and the proper motions in radians per Julian year, but the -** parallax is in arcseconds; the radial velocity is in km/s, but -** the pv-vector result is in AU and AU/day. -** -** 4) The RA proper motion is in terms of coordinate angle, not true -** angle. If the catalog uses arcseconds for both RA and Dec proper -** motions, the RA proper motion will need to be divided by cos(Dec) -** before use. -** -** 5) Straight-line motion at constant speed, in the inertial frame, -** is assumed. -** -** 6) An extremely small (or zero or negative) parallax is interpreted -** to mean that the object is on the "celestial sphere", the radius -** of which is an arbitrary (large) value (see the constant PXMIN). -** When the distance is overridden in this way, the status, -** initially zero, has 1 added to it. -** -** 7) If the space velocity is a significant fraction of c (see the -** constant VMAX), it is arbitrarily set to zero. When this action -** occurs, 2 is added to the status. -** -** 8) The relativistic adjustment involves an iterative calculation. -** If the process fails to converge within a set number (IMAX) of -** iterations, 4 is added to the status. -** -** 9) The inverse transformation is performed by the function -** eraPvstar. -** -** Called: -** eraS2pv spherical coordinates to pv-vector -** eraPm modulus of p-vector -** eraZp zero p-vector -** eraPn decompose p-vector into modulus and direction -** eraPdp scalar product of two p-vectors -** eraSxp multiply p-vector by scalar -** eraPmp p-vector minus p-vector -** eraPpp p-vector plus p-vector -** -** Reference: -** -** Stumpff, P., 1985, Astron.Astrophys. 144, 232-240. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ -/* Smallest allowed parallax */ - static const double PXMIN = 1e-7; - -/* Largest allowed speed (fraction of c) */ - static const double VMAX = 0.5; - -/* Maximum number of iterations for relativistic solution */ - static const int IMAX = 100; - - int i, iwarn; - double w, r, rd, rad, decd, v, x[3], usr[3], ust[3], - vsr, vst, betst, betsr, bett, betr, - dd, ddel, ur[3], ut[3], - d = 0.0, del = 0.0, /* to prevent */ - odd = 0.0, oddel = 0.0, /* compiler */ - od = 0.0, odel = 0.0; /* warnings */ - - -/* Distance (AU). */ - if (px >= PXMIN) { - w = px; - iwarn = 0; - } else { - w = PXMIN; - iwarn = 1; - } - r = ERFA_DR2AS / w; - -/* Radial velocity (AU/day). */ - rd = ERFA_DAYSEC * rv * 1e3 / ERFA_DAU; - -/* Proper motion (radian/day). */ - rad = pmr / ERFA_DJY; - decd = pmd / ERFA_DJY; - -/* To pv-vector (AU,AU/day). */ - eraS2pv(ra, dec, r, rad, decd, rd, pv); - -/* If excessive velocity, arbitrarily set it to zero. */ - v = eraPm(pv[1]); - if (v / ERFA_DC > VMAX) { - eraZp(pv[1]); - iwarn += 2; - } - -/* Isolate the radial component of the velocity (AU/day). */ - eraPn(pv[0], &w, x); - vsr = eraPdp(x, pv[1]); - eraSxp(vsr, x, usr); - -/* Isolate the transverse component of the velocity (AU/day). */ - eraPmp(pv[1], usr, ust); - vst = eraPm(ust); - -/* Special-relativity dimensionless parameters. */ - betsr = vsr / ERFA_DC; - betst = vst / ERFA_DC; - -/* Determine the inertial-to-observed relativistic correction terms. */ - bett = betst; - betr = betsr; - for (i = 0; i < IMAX; i++) { - d = 1.0 + betr; - del = sqrt(1.0 - betr*betr - bett*bett) - 1.0; - betr = d * betsr + del; - bett = d * betst; - if (i > 0) { - dd = fabs(d - od); - ddel = fabs(del - odel); - if ((i > 1) && (dd >= odd) && (ddel >= oddel)) break; - odd = dd; - oddel = ddel; - } - od = d; - odel = del; - } - if (i >= IMAX) iwarn += 4; - -/* Replace observed radial velocity with inertial value. */ - w = (betsr != 0.0) ? d + del / betsr : 1.0; - eraSxp(w, usr, ur); - -/* Replace observed tangential velocity with inertial value. */ - eraSxp(d, ust, ut); - -/* Combine the two to obtain the inertial space velocity. */ - eraPpp(ur, ut, pv[1]); - -/* Return the status. */ - return iwarn; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/sxp.c b/ast/erfa/sxp.c deleted file mode 100644 index 3bd311f..0000000 --- a/ast/erfa/sxp.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "erfa.h" - -void eraSxp(double s, double p[3], double sp[3]) -/* -** - - - - - - - -** e r a S x p -** - - - - - - - -** -** Multiply a p-vector by a scalar. -** -** Given: -** s double scalar -** p double[3] p-vector -** -** Returned: -** sp double[3] s * p -** -** Note: -** It is permissible for p and sp to be the same array. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - sp[0] = s * p[0]; - sp[1] = s * p[1]; - sp[2] = s * p[2]; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/sxpv.c b/ast/erfa/sxpv.c deleted file mode 100644 index 6b497cf..0000000 --- a/ast/erfa/sxpv.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "erfa.h" - -void eraSxpv(double s, double pv[2][3], double spv[2][3]) -/* -** - - - - - - - - -** e r a S x p v -** - - - - - - - - -** -** Multiply a pv-vector by a scalar. -** -** Given: -** s double scalar -** pv double[2][3] pv-vector -** -** Returned: -** spv double[2][3] s * pv -** -** Note: -** It is permissible for pv and spv to be the same array -** -** Called: -** eraS2xpv multiply pv-vector by two scalars -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraS2xpv(s, s, pv, spv); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/t_erfa_c.c b/ast/erfa/t_erfa_c.c deleted file mode 100644 index e32ce1e..0000000 --- a/ast/erfa/t_erfa_c.c +++ /dev/null @@ -1,9742 +0,0 @@ -#include -#include - -static int verbose = 0; - -/* -** - - - - - - - - - -** t _ e r f a _ c -** - - - - - - - - - -** -** Validate the ERFA C functions. -** -** Each ERFA function is at least called and a usually quite basic test -** is performed. Successful completion is signalled by a confirming -** message. Failure of a given function or group of functions results -** in error messages. -** -** All messages go to stdout. -** -** This revision: 2016 July 11 -** -*/ - -static void viv(int ival, int ivalok, - const char *func, const char *test, int *status) -/* -** - - - - -** v i v -** - - - - -** -** Validate an integer result. -** -** Internal function used by t_erfa_c program. -** -** Given: -** ival int value computed by function under test -** ivalok int correct value -** func char[] name of function under test -** test char[] name of individual test -** -** Given and returned: -** status int set to TRUE if test fails -** -** This revision: 2013 August 7 -*/ -{ - if (ival != ivalok) { - *status = 1; - printf("%s failed: %s want %d got %d\n", - func, test, ivalok, ival); - } else if (verbose) { - printf("%s passed: %s want %d got %d\n", - func, test, ivalok, ival); - } - -} - -static void vvd(double val, double valok, double dval, - const char *func, const char *test, int *status) -/* -** - - - - -** v v d -** - - - - -** -** Validate a double result. -** -** Internal function used by t_erfa_c program. -** -** Given: -** val double value computed by function under test -** valok double expected value -** dval double maximum allowable error -** func char[] name of function under test -** test char[] name of individual test -** -** Given and returned: -** status int set to TRUE if test fails -** -** This revision: 2016 April 21 -*/ -{ - double a, f; /* absolute and fractional error */ - - - a = val - valok; - if (a != 0.0 && fabs(a) > fabs(dval)) { - f = fabs(valok / a); - *status = 1; - printf("%s failed: %s want %.20g got %.20g (1/%.3g)\n", - func, test, valok, val, f); - } else if (verbose) { - printf("%s passed: %s want %.20g got %.20g\n", - func, test, valok, val); - } - -} - -static void t_a2af(int *status) -/* -** - - - - - - - -** t _ a 2 a f -** - - - - - - - -** -** Test eraA2af function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraA2af, viv -** -** This revision: 2013 August 7 -*/ -{ - int idmsf[4]; - char s; - - - eraA2af(4, 2.345, &s, idmsf); - - viv(s, '+', "eraA2af", "s", status); - - viv(idmsf[0], 134, "eraA2af", "0", status); - viv(idmsf[1], 21, "eraA2af", "1", status); - viv(idmsf[2], 30, "eraA2af", "2", status); - viv(idmsf[3], 9706, "eraA2af", "3", status); - -} - -static void t_a2tf(int *status) -/* -** - - - - - - - -** t _ a 2 t f -** - - - - - - - -** -** Test eraA2tf function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraA2tf, viv -** -** This revision: 2013 August 7 -*/ -{ - int ihmsf[4]; - char s; - - - eraA2tf(4, -3.01234, &s, ihmsf); - - viv((int)s, '-', "eraA2tf", "s", status); - - viv(ihmsf[0], 11, "eraA2tf", "0", status); - viv(ihmsf[1], 30, "eraA2tf", "1", status); - viv(ihmsf[2], 22, "eraA2tf", "2", status); - viv(ihmsf[3], 6484, "eraA2tf", "3", status); - -} - -static void t_ab(int *status) -/* -** - - - - - -** t _ a b -** - - - - - -** -** Test eraAb function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAb, vvd -** -** This revision: 2013 October 1 -*/ -{ - double pnat[3], v[3], s, bm1, ppr[3]; - - - pnat[0] = -0.76321968546737951; - pnat[1] = -0.60869453983060384; - pnat[2] = -0.21676408580639883; - v[0] = 2.1044018893653786e-5; - v[1] = -8.9108923304429319e-5; - v[2] = -3.8633714797716569e-5; - s = 0.99980921395708788; - bm1 = 0.99999999506209258; - - eraAb(pnat, v, s, bm1, ppr); - - vvd(ppr[0], -0.7631631094219556269, 1e-12, "eraAb", "1", status); - vvd(ppr[1], -0.6087553082505590832, 1e-12, "eraAb", "2", status); - vvd(ppr[2], -0.2167926269368471279, 1e-12, "eraAb", "3", status); - -} - -static void t_af2a(int *status) -/* -** - - - - - - - -** t _ a f 2 a -** - - - - - - - -** -** Test eraAf2a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAf2a, viv -** -** This revision: 2013 August 7 -*/ -{ - double a; - int j; - - - j = eraAf2a('-', 45, 13, 27.2, &a); - - vvd(a, -0.7893115794313644842, 1e-12, "eraAf2a", "a", status); - viv(j, 0, "eraAf2a", "j", status); - -} - -static void t_anp(int *status) -/* -** - - - - - - -** t _ a n p -** - - - - - - -** -** Test eraAnp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAnp, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraAnp(-0.1), 6.183185307179586477, 1e-12, "eraAnp", "", status); -} - -static void t_anpm(int *status) -/* -** - - - - - - - -** t _ a n p m -** - - - - - - - -** -** Test eraAnpm function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAnpm, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraAnpm(-4.0), 2.283185307179586477, 1e-12, "eraAnpm", "", status); -} - -static void t_apcg(int *status) -/* -** - - - - - - - -** t _ a p c g -** - - - - - - - -** -** Test eraApcg function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApcg, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, ebpv[2][3], ehp[3]; - eraASTROM astrom; - - - date1 = 2456165.5; - date2 = 0.401182685; - ebpv[0][0] = 0.901310875; - ebpv[0][1] = -0.417402664; - ebpv[0][2] = -0.180982288; - ebpv[1][0] = 0.00742727954; - ebpv[1][1] = 0.0140507459; - ebpv[1][2] = 0.00609045792; - ehp[0] = 0.903358544; - ehp[1] = -0.415395237; - ehp[2] = -0.180084014; - - eraApcg(date1, date2, ebpv, ehp, &astrom); - - vvd(astrom.pmt, 12.65133794027378508, 1e-11, - "eraApcg", "pmt", status); - vvd(astrom.eb[0], 0.901310875, 1e-12, - "eraApcg", "eb(1)", status); - vvd(astrom.eb[1], -0.417402664, 1e-12, - "eraApcg", "eb(2)", status); - vvd(astrom.eb[2], -0.180982288, 1e-12, - "eraApcg", "eb(3)", status); - vvd(astrom.eh[0], 0.8940025429324143045, 1e-12, - "eraApcg", "eh(1)", status); - vvd(astrom.eh[1], -0.4110930268679817955, 1e-12, - "eraApcg", "eh(2)", status); - vvd(astrom.eh[2], -0.1782189004872870264, 1e-12, - "eraApcg", "eh(3)", status); - vvd(astrom.em, 1.010465295811013146, 1e-12, - "eraApcg", "em", status); - vvd(astrom.v[0], 0.4289638897813379954e-4, 1e-16, - "eraApcg", "v(1_", status); - vvd(astrom.v[1], 0.8115034021720941898e-4, 1e-16, - "eraApcg", "v(2)", status); - vvd(astrom.v[2], 0.3517555123437237778e-4, 1e-16, - "eraApcg", "v(3)", status); - vvd(astrom.bm1, 0.9999999951686013336, 1e-12, - "eraApcg", "bm1", status); - vvd(astrom.bpn[0][0], 1.0, 0.0, - "eraApcg", "bpn(1,1)", status); - vvd(astrom.bpn[1][0], 0.0, 0.0, - "eraApcg", "bpn(2,1)", status); - vvd(astrom.bpn[2][0], 0.0, 0.0, - "eraApcg", "bpn(3,1)", status); - vvd(astrom.bpn[0][1], 0.0, 0.0, - "eraApcg", "bpn(1,2)", status); - vvd(astrom.bpn[1][1], 1.0, 0.0, - "eraApcg", "bpn(2,2)", status); - vvd(astrom.bpn[2][1], 0.0, 0.0, - "eraApcg", "bpn(3,2)", status); - vvd(astrom.bpn[0][2], 0.0, 0.0, - "eraApcg", "bpn(1,3)", status); - vvd(astrom.bpn[1][2], 0.0, 0.0, - "eraApcg", "bpn(2,3)", status); - vvd(astrom.bpn[2][2], 1.0, 0.0, - "eraApcg", "bpn(3,3)", status); - -} - -static void t_apcg13(int *status) -/* -** - - - - - - - - - -** t _ a p c g 1 3 -** - - - - - - - - - -** -** Test eraApcg13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApcg13, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2; - eraASTROM astrom; - - - date1 = 2456165.5; - date2 = 0.401182685; - - eraApcg13(date1, date2, &astrom); - - vvd(astrom.pmt, 12.65133794027378508, 1e-11, - "eraApcg13", "pmt", status); - vvd(astrom.eb[0], 0.9013108747340644755, 1e-12, - "eraApcg13", "eb(1)", status); - vvd(astrom.eb[1], -0.4174026640406119957, 1e-12, - "eraApcg13", "eb(2)", status); - vvd(astrom.eb[2], -0.1809822877867817771, 1e-12, - "eraApcg13", "eb(3)", status); - vvd(astrom.eh[0], 0.8940025429255499549, 1e-12, - "eraApcg13", "eh(1)", status); - vvd(astrom.eh[1], -0.4110930268331896318, 1e-12, - "eraApcg13", "eh(2)", status); - vvd(astrom.eh[2], -0.1782189006019749850, 1e-12, - "eraApcg13", "eh(3)", status); - vvd(astrom.em, 1.010465295964664178, 1e-12, - "eraApcg13", "em", status); - vvd(astrom.v[0], 0.4289638897157027528e-4, 1e-16, - "eraApcg13", "v(1)", status); - vvd(astrom.v[1], 0.8115034002544663526e-4, 1e-16, - "eraApcg13", "v(2)", status); - vvd(astrom.v[2], 0.3517555122593144633e-4, 1e-16, - "eraApcg13", "v(3)", status); - vvd(astrom.bm1, 0.9999999951686013498, 1e-12, - "eraApcg13", "bm1", status); - vvd(astrom.bpn[0][0], 1.0, 0.0, - "eraApcg13", "bpn(1,1)", status); - vvd(astrom.bpn[1][0], 0.0, 0.0, - "eraApcg13", "bpn(2,1)", status); - vvd(astrom.bpn[2][0], 0.0, 0.0, - "eraApcg13", "bpn(3,1)", status); - vvd(astrom.bpn[0][1], 0.0, 0.0, - "eraApcg13", "bpn(1,2)", status); - vvd(astrom.bpn[1][1], 1.0, 0.0, - "eraApcg13", "bpn(2,2)", status); - vvd(astrom.bpn[2][1], 0.0, 0.0, - "eraApcg13", "bpn(3,2)", status); - vvd(astrom.bpn[0][2], 0.0, 0.0, - "eraApcg13", "bpn(1,3)", status); - vvd(astrom.bpn[1][2], 0.0, 0.0, - "eraApcg13", "bpn(2,3)", status); - vvd(astrom.bpn[2][2], 1.0, 0.0, - "eraApcg13", "bpn(3,3)", status); - -} - -static void t_apci(int *status) -/* -** - - - - - - - -** t _ a p c i -** - - - - - - - -** -** Test eraApci function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApci, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, ebpv[2][3], ehp[3], x, y, s; - eraASTROM astrom; - - - date1 = 2456165.5; - date2 = 0.401182685; - ebpv[0][0] = 0.901310875; - ebpv[0][1] = -0.417402664; - ebpv[0][2] = -0.180982288; - ebpv[1][0] = 0.00742727954; - ebpv[1][1] = 0.0140507459; - ebpv[1][2] = 0.00609045792; - ehp[0] = 0.903358544; - ehp[1] = -0.415395237; - ehp[2] = -0.180084014; - x = 0.0013122272; - y = -2.92808623e-5; - s = 3.05749468e-8; - - eraApci(date1, date2, ebpv, ehp, x, y, s, &astrom); - - vvd(astrom.pmt, 12.65133794027378508, 1e-11, - "eraApci", "pmt", status); - vvd(astrom.eb[0], 0.901310875, 1e-12, - "eraApci", "eb(1)", status); - vvd(astrom.eb[1], -0.417402664, 1e-12, - "eraApci", "eb(2)", status); - vvd(astrom.eb[2], -0.180982288, 1e-12, - "eraApci", "eb(3)", status); - vvd(astrom.eh[0], 0.8940025429324143045, 1e-12, - "eraApci", "eh(1)", status); - vvd(astrom.eh[1], -0.4110930268679817955, 1e-12, - "eraApci", "eh(2)", status); - vvd(astrom.eh[2], -0.1782189004872870264, 1e-12, - "eraApci", "eh(3)", status); - vvd(astrom.em, 1.010465295811013146, 1e-12, - "eraApci", "em", status); - vvd(astrom.v[0], 0.4289638897813379954e-4, 1e-16, - "eraApci", "v(1)", status); - vvd(astrom.v[1], 0.8115034021720941898e-4, 1e-16, - "eraApci", "v(2)", status); - vvd(astrom.v[2], 0.3517555123437237778e-4, 1e-16, - "eraApci", "v(3)", status); - vvd(astrom.bm1, 0.9999999951686013336, 1e-12, - "eraApci", "bm1", status); - vvd(astrom.bpn[0][0], 0.9999991390295159156, 1e-12, - "eraApci", "bpn(1,1)", status); - vvd(astrom.bpn[1][0], 0.4978650072505016932e-7, 1e-12, - "eraApci", "bpn(2,1)", status); - vvd(astrom.bpn[2][0], 0.1312227200000000000e-2, 1e-12, - "eraApci", "bpn(3,1)", status); - vvd(astrom.bpn[0][1], -0.1136336653771609630e-7, 1e-12, - "eraApci", "bpn(1,2)", status); - vvd(astrom.bpn[1][1], 0.9999999995713154868, 1e-12, - "eraApci", "bpn(2,2)", status); - vvd(astrom.bpn[2][1], -0.2928086230000000000e-4, 1e-12, - "eraApci", "bpn(3,2)", status); - vvd(astrom.bpn[0][2], -0.1312227200895260194e-2, 1e-12, - "eraApci", "bpn(1,3)", status); - vvd(astrom.bpn[1][2], 0.2928082217872315680e-4, 1e-12, - "eraApci", "bpn(2,3)", status); - vvd(astrom.bpn[2][2], 0.9999991386008323373, 1e-12, - "eraApci", "bpn(3,3)", status); - -} - -static void t_apci13(int *status) -/* -** - - - - - - - - - -** t _ a p c i 1 3 -** - - - - - - - - - -** -** Test eraApci13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApci13, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, eo; - eraASTROM astrom; - - - date1 = 2456165.5; - date2 = 0.401182685; - - eraApci13(date1, date2, &astrom, &eo); - - vvd(astrom.pmt, 12.65133794027378508, 1e-11, - "eraApci13", "pmt", status); - vvd(astrom.eb[0], 0.9013108747340644755, 1e-12, - "eraApci13", "eb(1)", status); - vvd(astrom.eb[1], -0.4174026640406119957, 1e-12, - "eraApci13", "eb(2)", status); - vvd(astrom.eb[2], -0.1809822877867817771, 1e-12, - "eraApci13", "eb(3)", status); - vvd(astrom.eh[0], 0.8940025429255499549, 1e-12, - "eraApci13", "eh(1)", status); - vvd(astrom.eh[1], -0.4110930268331896318, 1e-12, - "eraApci13", "eh(2)", status); - vvd(astrom.eh[2], -0.1782189006019749850, 1e-12, - "eraApci13", "eh(3)", status); - vvd(astrom.em, 1.010465295964664178, 1e-12, - "eraApci13", "em", status); - vvd(astrom.v[0], 0.4289638897157027528e-4, 1e-16, - "eraApci13", "v(1)", status); - vvd(astrom.v[1], 0.8115034002544663526e-4, 1e-16, - "eraApci13", "v(2)", status); - vvd(astrom.v[2], 0.3517555122593144633e-4, 1e-16, - "eraApci13", "v(3)", status); - vvd(astrom.bm1, 0.9999999951686013498, 1e-12, - "eraApci13", "bm1", status); - vvd(astrom.bpn[0][0], 0.9999992060376761710, 1e-12, - "eraApci13", "bpn(1,1)", status); - vvd(astrom.bpn[1][0], 0.4124244860106037157e-7, 1e-12, - "eraApci13", "bpn(2,1)", status); - vvd(astrom.bpn[2][0], 0.1260128571051709670e-2, 1e-12, - "eraApci13", "bpn(3,1)", status); - vvd(astrom.bpn[0][1], -0.1282291987222130690e-7, 1e-12, - "eraApci13", "bpn(1,2)", status); - vvd(astrom.bpn[1][1], 0.9999999997456835325, 1e-12, - "eraApci13", "bpn(2,2)", status); - vvd(astrom.bpn[2][1], -0.2255288829420524935e-4, 1e-12, - "eraApci13", "bpn(3,2)", status); - vvd(astrom.bpn[0][2], -0.1260128571661374559e-2, 1e-12, - "eraApci13", "bpn(1,3)", status); - vvd(astrom.bpn[1][2], 0.2255285422953395494e-4, 1e-12, - "eraApci13", "bpn(2,3)", status); - vvd(astrom.bpn[2][2], 0.9999992057833604343, 1e-12, - "eraApci13", "bpn(3,3)", status); - vvd(eo, -0.2900618712657375647e-2, 1e-12, - "eraApci13", "eo", status); - -} - -static void t_apco(int *status) -/* -** - - - - - - - -** t _ a p c o -** - - - - - - - -** -** Test eraApco function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApco, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, ebpv[2][3], ehp[3], x, y, s, - theta, elong, phi, hm, xp, yp, sp, refa, refb; - eraASTROM astrom; - - - date1 = 2456384.5; - date2 = 0.970031644; - ebpv[0][0] = -0.974170438; - ebpv[0][1] = -0.211520082; - ebpv[0][2] = -0.0917583024; - ebpv[1][0] = 0.00364365824; - ebpv[1][1] = -0.0154287319; - ebpv[1][2] = -0.00668922024; - ehp[0] = -0.973458265; - ehp[1] = -0.209215307; - ehp[2] = -0.0906996477; - x = 0.0013122272; - y = -2.92808623e-5; - s = 3.05749468e-8; - theta = 3.14540971; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - sp = -3.01974337e-11; - refa = 0.000201418779; - refb = -2.36140831e-7; - - eraApco(date1, date2, ebpv, ehp, x, y, s, - theta, elong, phi, hm, xp, yp, sp, - refa, refb, &astrom); - - vvd(astrom.pmt, 13.25248468622587269, 1e-11, - "eraApco", "pmt", status); - vvd(astrom.eb[0], -0.9741827110630897003, 1e-12, - "eraApco", "eb(1)", status); - vvd(astrom.eb[1], -0.2115130190135014340, 1e-12, - "eraApco", "eb(2)", status); - vvd(astrom.eb[2], -0.09179840186968295686, 1e-12, - "eraApco", "eb(3)", status); - vvd(astrom.eh[0], -0.9736425571689670428, 1e-12, - "eraApco", "eh(1)", status); - vvd(astrom.eh[1], -0.2092452125848862201, 1e-12, - "eraApco", "eh(2)", status); - vvd(astrom.eh[2], -0.09075578152261439954, 1e-12, - "eraApco", "eh(3)", status); - vvd(astrom.em, 0.9998233241710617934, 1e-12, - "eraApco", "em", status); - vvd(astrom.v[0], 0.2078704985147609823e-4, 1e-16, - "eraApco", "v(1)", status); - vvd(astrom.v[1], -0.8955360074407552709e-4, 1e-16, - "eraApco", "v(2)", status); - vvd(astrom.v[2], -0.3863338980073114703e-4, 1e-16, - "eraApco", "v(3)", status); - vvd(astrom.bm1, 0.9999999950277561600, 1e-12, - "eraApco", "bm1", status); - vvd(astrom.bpn[0][0], 0.9999991390295159156, 1e-12, - "eraApco", "bpn(1,1)", status); - vvd(astrom.bpn[1][0], 0.4978650072505016932e-7, 1e-12, - "eraApco", "bpn(2,1)", status); - vvd(astrom.bpn[2][0], 0.1312227200000000000e-2, 1e-12, - "eraApco", "bpn(3,1)", status); - vvd(astrom.bpn[0][1], -0.1136336653771609630e-7, 1e-12, - "eraApco", "bpn(1,2)", status); - vvd(astrom.bpn[1][1], 0.9999999995713154868, 1e-12, - "eraApco", "bpn(2,2)", status); - vvd(astrom.bpn[2][1], -0.2928086230000000000e-4, 1e-12, - "eraApco", "bpn(3,2)", status); - vvd(astrom.bpn[0][2], -0.1312227200895260194e-2, 1e-12, - "eraApco", "bpn(1,3)", status); - vvd(astrom.bpn[1][2], 0.2928082217872315680e-4, 1e-12, - "eraApco", "bpn(2,3)", status); - vvd(astrom.bpn[2][2], 0.9999991386008323373, 1e-12, - "eraApco", "bpn(3,3)", status); - vvd(astrom.along, -0.5278008060301974337, 1e-12, - "eraApco", "along", status); - vvd(astrom.xpl, 0.1133427418174939329e-5, 1e-17, - "eraApco", "xpl", status); - vvd(astrom.ypl, 0.1453347595745898629e-5, 1e-17, - "eraApco", "ypl", status); - vvd(astrom.sphi, -0.9440115679003211329, 1e-12, - "eraApco", "sphi", status); - vvd(astrom.cphi, 0.3299123514971474711, 1e-12, - "eraApco", "cphi", status); - vvd(astrom.diurab, 0, 0, - "eraApco", "diurab", status); - vvd(astrom.eral, 2.617608903969802566, 1e-12, - "eraApco", "eral", status); - vvd(astrom.refa, 0.2014187790000000000e-3, 1e-15, - "eraApco", "refa", status); - vvd(astrom.refb, -0.2361408310000000000e-6, 1e-18, - "eraApco", "refb", status); - -} - -static void t_apco13(int *status) -/* -** - - - - - - - - - -** t _ a p c o 1 3 -** - - - - - - - - - -** -** Test eraApco13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApco13, vvd, viv -** -** This revision: 2013 October 4 -*/ -{ - double utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, eo; - eraASTROM astrom; - int j; - - - utc1 = 2456384.5; - utc2 = 0.969254051; - dut1 = 0.1550675; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - phpa = 731.0; - tc = 12.8; - rh = 0.59; - wl = 0.55; - - j = eraApco13(utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, &astrom, &eo); - - vvd(astrom.pmt, 13.25248468622475727, 1e-11, - "eraApco13", "pmt", status); - vvd(astrom.eb[0], -0.9741827107321449445, 1e-12, - "eraApco13", "eb(1)", status); - vvd(astrom.eb[1], -0.2115130190489386190, 1e-12, - "eraApco13", "eb(2)", status); - vvd(astrom.eb[2], -0.09179840189515518726, 1e-12, - "eraApco13", "eb(3)", status); - vvd(astrom.eh[0], -0.9736425572586866640, 1e-12, - "eraApco13", "eh(1)", status); - vvd(astrom.eh[1], -0.2092452121602867431, 1e-12, - "eraApco13", "eh(2)", status); - vvd(astrom.eh[2], -0.09075578153903832650, 1e-12, - "eraApco13", "eh(3)", status); - vvd(astrom.em, 0.9998233240914558422, 1e-12, - "eraApco13", "em", status); - vvd(astrom.v[0], 0.2078704986751370303e-4, 1e-16, - "eraApco13", "v(1)", status); - vvd(astrom.v[1], -0.8955360100494469232e-4, 1e-16, - "eraApco13", "v(2)", status); - vvd(astrom.v[2], -0.3863338978840051024e-4, 1e-16, - "eraApco13", "v(3)", status); - vvd(astrom.bm1, 0.9999999950277561368, 1e-12, - "eraApco13", "bm1", status); - vvd(astrom.bpn[0][0], 0.9999991390295147999, 1e-12, - "eraApco13", "bpn(1,1)", status); - vvd(astrom.bpn[1][0], 0.4978650075315529277e-7, 1e-12, - "eraApco13", "bpn(2,1)", status); - vvd(astrom.bpn[2][0], 0.001312227200850293372, 1e-12, - "eraApco13", "bpn(3,1)", status); - vvd(astrom.bpn[0][1], -0.1136336652812486604e-7, 1e-12, - "eraApco13", "bpn(1,2)", status); - vvd(astrom.bpn[1][1], 0.9999999995713154865, 1e-12, - "eraApco13", "bpn(2,2)", status); - vvd(astrom.bpn[2][1], -0.2928086230975367296e-4, 1e-12, - "eraApco13", "bpn(3,2)", status); - vvd(astrom.bpn[0][2], -0.001312227201745553566, 1e-12, - "eraApco13", "bpn(1,3)", status); - vvd(astrom.bpn[1][2], 0.2928082218847679162e-4, 1e-12, - "eraApco13", "bpn(2,3)", status); - vvd(astrom.bpn[2][2], 0.9999991386008312212, 1e-12, - "eraApco13", "bpn(3,3)", status); - vvd(astrom.along, -0.5278008060301974337, 1e-12, - "eraApco13", "along", status); - vvd(astrom.xpl, 0.1133427418174939329e-5, 1e-17, - "eraApco13", "xpl", status); - vvd(astrom.ypl, 0.1453347595745898629e-5, 1e-17, - "eraApco13", "ypl", status); - vvd(astrom.sphi, -0.9440115679003211329, 1e-12, - "eraApco13", "sphi", status); - vvd(astrom.cphi, 0.3299123514971474711, 1e-12, - "eraApco13", "cphi", status); - vvd(astrom.diurab, 0, 0, - "eraApco13", "diurab", status); - vvd(astrom.eral, 2.617608909189066140, 1e-12, - "eraApco13", "eral", status); - vvd(astrom.refa, 0.2014187785940396921e-3, 1e-15, - "eraApco13", "refa", status); - vvd(astrom.refb, -0.2361408314943696227e-6, 1e-18, - "eraApco13", "refb", status); - vvd(eo, -0.003020548354802412839, 1e-14, - "eraApco13", "eo", status); - viv(j, 0, "eraApco13", "j", status); - -} - -static void t_apcs(int *status) -/* -** - - - - - - - -** t _ a p c s -** - - - - - - - -** -** Test eraApcs function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApcs, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, pv[2][3], ebpv[2][3], ehp[3]; - eraASTROM astrom; - - - date1 = 2456384.5; - date2 = 0.970031644; - pv[0][0] = -1836024.09; - pv[0][1] = 1056607.72; - pv[0][2] = -5998795.26; - pv[1][0] = -77.0361767; - pv[1][1] = -133.310856; - pv[1][2] = 0.0971855934; - ebpv[0][0] = -0.974170438; - ebpv[0][1] = -0.211520082; - ebpv[0][2] = -0.0917583024; - ebpv[1][0] = 0.00364365824; - ebpv[1][1] = -0.0154287319; - ebpv[1][2] = -0.00668922024; - ehp[0] = -0.973458265; - ehp[1] = -0.209215307; - ehp[2] = -0.0906996477; - - eraApcs(date1, date2, pv, ebpv, ehp, &astrom); - - vvd(astrom.pmt, 13.25248468622587269, 1e-11, - "eraApcs", "pmt", status); - vvd(astrom.eb[0], -0.9741827110630456169, 1e-12, - "eraApcs", "eb(1)", status); - vvd(astrom.eb[1], -0.2115130190136085494, 1e-12, - "eraApcs", "eb(2)", status); - vvd(astrom.eb[2], -0.09179840186973175487, 1e-12, - "eraApcs", "eb(3)", status); - vvd(astrom.eh[0], -0.9736425571689386099, 1e-12, - "eraApcs", "eh(1)", status); - vvd(astrom.eh[1], -0.2092452125849967195, 1e-12, - "eraApcs", "eh(2)", status); - vvd(astrom.eh[2], -0.09075578152266466572, 1e-12, - "eraApcs", "eh(3)", status); - vvd(astrom.em, 0.9998233241710457140, 1e-12, - "eraApcs", "em", status); - vvd(astrom.v[0], 0.2078704985513566571e-4, 1e-16, - "eraApcs", "v(1)", status); - vvd(astrom.v[1], -0.8955360074245006073e-4, 1e-16, - "eraApcs", "v(2)", status); - vvd(astrom.v[2], -0.3863338980073572719e-4, 1e-16, - "eraApcs", "v(3)", status); - vvd(astrom.bm1, 0.9999999950277561601, 1e-12, - "eraApcs", "bm1", status); - vvd(astrom.bpn[0][0], 1, 0, - "eraApcs", "bpn(1,1)", status); - vvd(astrom.bpn[1][0], 0, 0, - "eraApcs", "bpn(2,1)", status); - vvd(astrom.bpn[2][0], 0, 0, - "eraApcs", "bpn(3,1)", status); - vvd(astrom.bpn[0][1], 0, 0, - "eraApcs", "bpn(1,2)", status); - vvd(astrom.bpn[1][1], 1, 0, - "eraApcs", "bpn(2,2)", status); - vvd(astrom.bpn[2][1], 0, 0, - "eraApcs", "bpn(3,2)", status); - vvd(astrom.bpn[0][2], 0, 0, - "eraApcs", "bpn(1,3)", status); - vvd(astrom.bpn[1][2], 0, 0, - "eraApcs", "bpn(2,3)", status); - vvd(astrom.bpn[2][2], 1, 0, - "eraApcs", "bpn(3,3)", status); - -} - -static void t_apcs13(int *status) -/* -** - - - - - - - - - -** t _ a p c s 1 3 -** - - - - - - - - - -** -** Test eraApcs13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApcs13, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, pv[2][3]; - eraASTROM astrom; - - - date1 = 2456165.5; - date2 = 0.401182685; - pv[0][0] = -6241497.16; - pv[0][1] = 401346.896; - pv[0][2] = -1251136.04; - pv[1][0] = -29.264597; - pv[1][1] = -455.021831; - pv[1][2] = 0.0266151194; - - eraApcs13(date1, date2, pv, &astrom); - - vvd(astrom.pmt, 12.65133794027378508, 1e-11, - "eraApcs13", "pmt", status); - vvd(astrom.eb[0], 0.9012691529023298391, 1e-12, - "eraApcs13", "eb(1)", status); - vvd(astrom.eb[1], -0.4173999812023068781, 1e-12, - "eraApcs13", "eb(2)", status); - vvd(astrom.eb[2], -0.1809906511146821008, 1e-12, - "eraApcs13", "eb(3)", status); - vvd(astrom.eh[0], 0.8939939101759726824, 1e-12, - "eraApcs13", "eh(1)", status); - vvd(astrom.eh[1], -0.4111053891734599955, 1e-12, - "eraApcs13", "eh(2)", status); - vvd(astrom.eh[2], -0.1782336880637689334, 1e-12, - "eraApcs13", "eh(3)", status); - vvd(astrom.em, 1.010428384373318379, 1e-12, - "eraApcs13", "em", status); - vvd(astrom.v[0], 0.4279877278327626511e-4, 1e-16, - "eraApcs13", "v(1)", status); - vvd(astrom.v[1], 0.7963255057040027770e-4, 1e-16, - "eraApcs13", "v(2)", status); - vvd(astrom.v[2], 0.3517564000441374759e-4, 1e-16, - "eraApcs13", "v(3)", status); - vvd(astrom.bm1, 0.9999999952947981330, 1e-12, - "eraApcs13", "bm1", status); - vvd(astrom.bpn[0][0], 1, 0, - "eraApcs13", "bpn(1,1)", status); - vvd(astrom.bpn[1][0], 0, 0, - "eraApcs13", "bpn(2,1)", status); - vvd(astrom.bpn[2][0], 0, 0, - "eraApcs13", "bpn(3,1)", status); - vvd(astrom.bpn[0][1], 0, 0, - "eraApcs13", "bpn(1,2)", status); - vvd(astrom.bpn[1][1], 1, 0, - "eraApcs13", "bpn(2,2)", status); - vvd(astrom.bpn[2][1], 0, 0, - "eraApcs13", "bpn(3,2)", status); - vvd(astrom.bpn[0][2], 0, 0, - "eraApcs13", "bpn(1,3)", status); - vvd(astrom.bpn[1][2], 0, 0, - "eraApcs13", "bpn(2,3)", status); - vvd(astrom.bpn[2][2], 1, 0, - "eraApcs13", "bpn(3,3)", status); - -} - -static void t_aper(int *status) -/* -** - - - - - - - -** t _ a p e r -** - - - - - - - -* -** Test eraAper function. -* -** Returned: -** status int FALSE = success, TRUE = fail -* -** Called: eraAper, vvd -* -** This revision: 2013 October 3 -*/ -{ - double theta; - eraASTROM astrom; - - - astrom.along = 1.234; - theta = 5.678; - - eraAper(theta, &astrom); - - vvd(astrom.eral, 6.912000000000000000, 1e-12, - "eraAper", "pmt", status); - -} - -static void t_aper13(int *status) -/* -** - - - - - - - - - -** t _ a p e r 1 3 -** - - - - - - - - - -** -** Test eraAper13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAper13, vvd -** -** This revision: 2013 October 3 -*/ -{ - double ut11, ut12; - eraASTROM astrom; - - - astrom.along = 1.234; - ut11 = 2456165.5; - ut12 = 0.401182685; - - eraAper13(ut11, ut12, &astrom); - - vvd(astrom.eral, 3.316236661789694933, 1e-12, - "eraAper13", "pmt", status); - -} - -static void t_apio(int *status) -/* -** - - - - - - - -** t _ a p i o -** - - - - - - - -** -** Test eraApio function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApio, vvd -** -** This revision: 2013 October 3 -*/ -{ - double sp, theta, elong, phi, hm, xp, yp, refa, refb; - eraASTROM astrom; - - - sp = -3.01974337e-11; - theta = 3.14540971; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - refa = 0.000201418779; - refb = -2.36140831e-7; - - eraApio(sp, theta, elong, phi, hm, xp, yp, refa, refb, &astrom); - - vvd(astrom.along, -0.5278008060301974337, 1e-12, - "eraApio", "along", status); - vvd(astrom.xpl, 0.1133427418174939329e-5, 1e-17, - "eraApio", "xpl", status); - vvd(astrom.ypl, 0.1453347595745898629e-5, 1e-17, - "eraApio", "ypl", status); - vvd(astrom.sphi, -0.9440115679003211329, 1e-12, - "eraApio", "sphi", status); - vvd(astrom.cphi, 0.3299123514971474711, 1e-12, - "eraApio", "cphi", status); - vvd(astrom.diurab, 0.5135843661699913529e-6, 1e-12, - "eraApio", "diurab", status); - vvd(astrom.eral, 2.617608903969802566, 1e-12, - "eraApio", "eral", status); - vvd(astrom.refa, 0.2014187790000000000e-3, 1e-15, - "eraApio", "refa", status); - vvd(astrom.refb, -0.2361408310000000000e-6, 1e-18, - "eraApio", "refb", status); - -} - -static void t_apio13(int *status) -/* -** - - - - - - - - - -** t _ a p i o 1 3 -** - - - - - - - - - -** -** Test eraApio13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApio13, vvd, viv -** -** This revision: 2013 October 4 -*/ -{ - double utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl; - int j; - eraASTROM astrom; - - - utc1 = 2456384.5; - utc2 = 0.969254051; - dut1 = 0.1550675; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - phpa = 731.0; - tc = 12.8; - rh = 0.59; - wl = 0.55; - - j = eraApio13(utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, &astrom); - - vvd(astrom.along, -0.5278008060301974337, 1e-12, - "eraApio13", "along", status); - vvd(astrom.xpl, 0.1133427418174939329e-5, 1e-17, - "eraApio13", "xpl", status); - vvd(astrom.ypl, 0.1453347595745898629e-5, 1e-17, - "eraApio13", "ypl", status); - vvd(astrom.sphi, -0.9440115679003211329, 1e-12, - "eraApio13", "sphi", status); - vvd(astrom.cphi, 0.3299123514971474711, 1e-12, - "eraApio13", "cphi", status); - vvd(astrom.diurab, 0.5135843661699913529e-6, 1e-12, - "eraApio13", "diurab", status); - vvd(astrom.eral, 2.617608909189066140, 1e-12, - "eraApio13", "eral", status); - vvd(astrom.refa, 0.2014187785940396921e-3, 1e-15, - "eraApio13", "refa", status); - vvd(astrom.refb, -0.2361408314943696227e-6, 1e-18, - "eraApio13", "refb", status); - viv(j, 0, "eraApio13", "j", status); - -} - -static void t_atci13(int *status) -/* -** - - - - - - - - - -** t _ a t c i 1 3 -** - - - - - - - - - -** -** Test eraAtci13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAtci13, vvd -** -** This revision: 2013 October 3 -*/ -{ - double rc, dc, pr, pd, px, rv, date1, date2, ri, di, eo; - - - rc = 2.71; - dc = 0.174; - pr = 1e-5; - pd = 5e-6; - px = 0.1; - rv = 55.0; - date1 = 2456165.5; - date2 = 0.401182685; - - eraAtci13(rc, dc, pr, pd, px, rv, date1, date2, &ri, &di, &eo); - - vvd(ri, 2.710121572969038991, 1e-12, - "eraAtci13", "ri", status); - vvd(di, 0.1729371367218230438, 1e-12, - "eraAtci13", "di", status); - vvd(eo, -0.002900618712657375647, 1e-14, - "eraAtci13", "eo", status); - -} - -static void t_atciq(int *status) -/* -** - - - - - - - - -** t _ a t c i q -** - - - - - - - - -** -** Test eraAtciq function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApci13, eraAtciq, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, eo, rc, dc, pr, pd, px, rv, ri, di; - eraASTROM astrom; - - date1 = 2456165.5; - date2 = 0.401182685; - eraApci13(date1, date2, &astrom, &eo); - rc = 2.71; - dc = 0.174; - pr = 1e-5; - pd = 5e-6; - px = 0.1; - rv = 55.0; - - eraAtciq(rc, dc, pr, pd, px, rv, &astrom, &ri, &di); - - vvd(ri, 2.710121572969038991, 1e-12, "eraAtciq", "ri", status); - vvd(di, 0.1729371367218230438, 1e-12, "eraAtciq", "di", status); - -} - -static void t_atciqn(int *status) -/* -** - - - - - - - - - -** t _ a t c i q n -** - - - - - - - - - -** -** Test eraAtciqn function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApci13, eraAtciqn, vvd -** -** This revision: 2013 October 3 -*/ -{ - eraLDBODY b[3]; - double date1, date2, eo, rc, dc, pr, pd, px, rv, ri, di; - eraASTROM astrom; - - date1 = 2456165.5; - date2 = 0.401182685; - eraApci13(date1, date2, &astrom, &eo); - rc = 2.71; - dc = 0.174; - pr = 1e-5; - pd = 5e-6; - px = 0.1; - rv = 55.0; - b[0].bm = 0.00028574; - b[0].dl = 3e-10; - b[0].pv[0][0] = -7.81014427; - b[0].pv[0][1] = -5.60956681; - b[0].pv[0][2] = -1.98079819; - b[0].pv[1][0] = 0.0030723249; - b[0].pv[1][1] = -0.00406995477; - b[0].pv[1][2] = -0.00181335842; - b[1].bm = 0.00095435; - b[1].dl = 3e-9; - b[1].pv[0][0] = 0.738098796; - b[1].pv[0][1] = 4.63658692; - b[1].pv[0][2] = 1.9693136; - b[1].pv[1][0] = -0.00755816922; - b[1].pv[1][1] = 0.00126913722; - b[1].pv[1][2] = 0.000727999001; - b[2].bm = 1.0; - b[2].dl = 6e-6; - b[2].pv[0][0] = -0.000712174377; - b[2].pv[0][1] = -0.00230478303; - b[2].pv[0][2] = -0.00105865966; - b[2].pv[1][0] = 6.29235213e-6; - b[2].pv[1][1] = -3.30888387e-7; - b[2].pv[1][2] = -2.96486623e-7; - - eraAtciqn ( rc, dc, pr, pd, px, rv, &astrom, 3, b, &ri, &di); - - vvd(ri, 2.710122008105325582, 1e-12, "eraAtciqn", "ri", status); - vvd(di, 0.1729371916491459122, 1e-12, "eraAtciqn", "di", status); - -} - -static void t_atciqz(int *status) -/* -** - - - - - - - - - -** t _ a t c i q z -** - - - - - - - - - -** -** Test eraAtciqz function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApci13, eraAtciqz, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, eo, rc, dc, ri, di; - eraASTROM astrom; - - - date1 = 2456165.5; - date2 = 0.401182685; - eraApci13(date1, date2, &astrom, &eo); - rc = 2.71; - dc = 0.174; - - eraAtciqz(rc, dc, &astrom, &ri, &di); - - vvd(ri, 2.709994899247599271, 1e-12, "eraAtciqz", "ri", status); - vvd(di, 0.1728740720983623469, 1e-12, "eraAtciqz", "di", status); - -} - -static void t_atco13(int *status) -/* -** - - - - - - - - - -** t _ a t c o 1 3 -** - - - - - - - - - -** -** Test eraAtco13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAtco13, vvd, viv -** -** This revision: 2013 October 4 -*/ -{ - double rc, dc, pr, pd, px, rv, utc1, utc2, dut1, - elong, phi, hm, xp, yp, phpa, tc, rh, wl, - aob, zob, hob, dob, rob, eo; - int j; - - - rc = 2.71; - dc = 0.174; - pr = 1e-5; - pd = 5e-6; - px = 0.1; - rv = 55.0; - utc1 = 2456384.5; - utc2 = 0.969254051; - dut1 = 0.1550675; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - phpa = 731.0; - tc = 12.8; - rh = 0.59; - wl = 0.55; - - j = eraAtco13(rc, dc, pr, pd, px, rv, - utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, - &aob, &zob, &hob, &dob, &rob, &eo); - - vvd(aob, 0.09251774485358230653, 1e-12, "eraAtco13", "aob", status); - vvd(zob, 1.407661405256767021, 1e-12, "eraAtco13", "zob", status); - vvd(hob, -0.09265154431403157925, 1e-12, "eraAtco13", "hob", status); - vvd(dob, 0.1716626560075591655, 1e-12, "eraAtco13", "dob", status); - vvd(rob, 2.710260453503097719, 1e-12, "eraAtco13", "rob", status); - vvd(eo, -0.003020548354802412839, 1e-14, "eraAtco13", "eo", status); - viv(j, 0, "eraAtco13", "j", status); - -} - -static void t_atic13(int *status) -/* -** - - - - - - - - - -** t _ a t i c 1 3 -** - - - - - - - - - -** -** Test eraAtic13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAtic13, vvd -** -** This revision: 2013 October 3 -*/ -{ - double ri, di, date1, date2, rc, dc, eo; - - - ri = 2.710121572969038991; - di = 0.1729371367218230438; - date1 = 2456165.5; - date2 = 0.401182685; - - eraAtic13(ri, di, date1, date2, &rc, &dc, &eo); - - vvd(rc, 2.710126504531374930, 1e-12, "eraAtic13", "rc", status); - vvd(dc, 0.1740632537628342320, 1e-12, "eraAtic13", "dc", status); - vvd(eo, -0.002900618712657375647, 1e-14, "eraAtic13", "eo", status); - -} - -static void t_aticq(int *status) -/* -** - - - - - - - - -** t _ a t i c q -** - - - - - - - - -** -** Test eraAticq function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApci13, eraAticq, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, eo, ri, di, rc, dc; - eraASTROM astrom; - - - date1 = 2456165.5; - date2 = 0.401182685; - eraApci13(date1, date2, &astrom, &eo); - ri = 2.710121572969038991; - di = 0.1729371367218230438; - - eraAticq(ri, di, &astrom, &rc, &dc); - - vvd(rc, 2.710126504531374930, 1e-12, "eraAticq", "rc", status); - vvd(dc, 0.1740632537628342320, 1e-12, "eraAticq", "dc", status); - -} - -static void t_aticqn(int *status) -/* -** - - - - - - - - - -** t _ a t i c q n -** - - - - - - - - - -** -** Test eraAticqn function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApci13, eraAticqn, vvd -** -** This revision: 2013 October 3 -*/ -{ - double date1, date2, eo, ri, di, rc, dc; - eraLDBODY b[3]; - eraASTROM astrom; - - - date1 = 2456165.5; - date2 = 0.401182685; - eraApci13(date1, date2, &astrom, &eo); - ri = 2.709994899247599271; - di = 0.1728740720983623469; - b[0].bm = 0.00028574; - b[0].dl = 3e-10; - b[0].pv[0][0] = -7.81014427; - b[0].pv[0][1] = -5.60956681; - b[0].pv[0][2] = -1.98079819; - b[0].pv[1][0] = 0.0030723249; - b[0].pv[1][1] = -0.00406995477; - b[0].pv[1][2] = -0.00181335842; - b[1].bm = 0.00095435; - b[1].dl = 3e-9; - b[1].pv[0][0] = 0.738098796; - b[1].pv[0][1] = 4.63658692; - b[1].pv[0][2] = 1.9693136; - b[1].pv[1][0] = -0.00755816922; - b[1].pv[1][1] = 0.00126913722; - b[1].pv[1][2] = 0.000727999001; - b[2].bm = 1.0; - b[2].dl = 6e-6; - b[2].pv[0][0] = -0.000712174377; - b[2].pv[0][1] = -0.00230478303; - b[2].pv[0][2] = -0.00105865966; - b[2].pv[1][0] = 6.29235213e-6; - b[2].pv[1][1] = -3.30888387e-7; - b[2].pv[1][2] = -2.96486623e-7; - - eraAticqn(ri, di, &astrom, 3, b, &rc, &dc); - - vvd(rc, 2.709999575032685412, 1e-12, "eraAtciqn", "rc", status); - vvd(dc, 0.1739999656317778034, 1e-12, "eraAtciqn", "dc", status); - -} - -static void t_atio13(int *status) -/* -** - - - - - - - - - -** t _ a t i o 1 3 -** - - - - - - - - - -** -** Test eraAtio13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAtio13, vvd, viv -** -** This revision: 2013 October 3 -*/ -{ - double ri, di, utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, aob, zob, hob, dob, rob; - int j; - - - ri = 2.710121572969038991; - di = 0.1729371367218230438; - utc1 = 2456384.5; - utc2 = 0.969254051; - dut1 = 0.1550675; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - phpa = 731.0; - tc = 12.8; - rh = 0.59; - wl = 0.55; - - j = eraAtio13(ri, di, utc1, utc2, dut1, elong, phi, hm, - xp, yp, phpa, tc, rh, wl, - &aob, &zob, &hob, &dob, &rob); - - vvd(aob, 0.09233952224794989993, 1e-12, "eraAtio13", "aob", status); - vvd(zob, 1.407758704513722461, 1e-12, "eraAtio13", "zob", status); - vvd(hob, -0.09247619879782006106, 1e-12, "eraAtio13", "hob", status); - vvd(dob, 0.1717653435758265198, 1e-12, "eraAtio13", "dob", status); - vvd(rob, 2.710085107986886201, 1e-12, "eraAtio13", "rob", status); - viv(j, 0, "eraAtio13", "j", status); - -} - -static void t_atioq(int *status) -/* -** - - - - - - - - -** t _ a t i o q -** - - - - - - - - -** -** Test eraAtioq function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraApio13, eraAtioq, vvd, viv -** -** This revision: 2013 October 4 -*/ -{ - double utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, ri, di, aob, zob, hob, dob, rob; - eraASTROM astrom; - - - utc1 = 2456384.5; - utc2 = 0.969254051; - dut1 = 0.1550675; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - phpa = 731.0; - tc = 12.8; - rh = 0.59; - wl = 0.55; - (void) eraApio13(utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, &astrom); - ri = 2.710121572969038991; - di = 0.1729371367218230438; - - eraAtioq(ri, di, &astrom, &aob, &zob, &hob, &dob, &rob); - - vvd(aob, 0.09233952224794989993, 1e-12, "eraAtioq", "aob", status); - vvd(zob, 1.407758704513722461, 1e-12, "eraAtioq", "zob", status); - vvd(hob, -0.09247619879782006106, 1e-12, "eraAtioq", "hob", status); - vvd(dob, 0.1717653435758265198, 1e-12, "eraAtioq", "dob", status); - vvd(rob, 2.710085107986886201, 1e-12, "eraAtioq", "rob", status); - -} - -static void t_atoc13(int *status) -/* -** - - - - - - - - - -** t _ a t o c 1 3 -** - - - - - - - - - -** -** Test eraAtoc13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAtoc13, vvd, viv -** -** This revision: 2013 October 3 -*/ -{ - double utc1, utc2, dut1, - elong, phi, hm, xp, yp, phpa, tc, rh, wl, - ob1, ob2, rc, dc; - int j; - - - utc1 = 2456384.5; - utc2 = 0.969254051; - dut1 = 0.1550675; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - phpa = 731.0; - tc = 12.8; - rh = 0.59; - wl = 0.55; - - ob1 = 2.710085107986886201; - ob2 = 0.1717653435758265198; - j = eraAtoc13 ( "R", ob1, ob2, utc1, utc2, dut1, - elong, phi, hm, xp, yp, phpa, tc, rh, wl, - &rc, &dc); - vvd(rc, 2.709956744661000609, 1e-12, "eraAtoc13", "R/rc", status); - vvd(dc, 0.1741696500895398562, 1e-12, "eraAtoc13", "R/dc", status); - viv(j, 0, "eraAtoc13", "R/j", status); - - ob1 = -0.09247619879782006106; - ob2 = 0.1717653435758265198; - j = eraAtoc13 ( "H", ob1, ob2, utc1, utc2, dut1, - elong, phi, hm, xp, yp, phpa, tc, rh, wl, - &rc, &dc); - vvd(rc, 2.709956744661000609, 1e-12, "eraAtoc13", "H/rc", status); - vvd(dc, 0.1741696500895398562, 1e-12, "eraAtoc13", "H/dc", status); - viv(j, 0, "eraAtoc13", "H/j", status); - - ob1 = 0.09233952224794989993; - ob2 = 1.407758704513722461; - j = eraAtoc13 ( "A", ob1, ob2, utc1, utc2, dut1, - elong, phi, hm, xp, yp, phpa, tc, rh, wl, - &rc, &dc); - vvd(rc, 2.709956744661000609, 1e-12, "eraAtoc13", "A/rc", status); - vvd(dc, 0.1741696500895398565, 1e-12, "eraAtoc13", "A/dc", status); - viv(j, 0, "eraAtoc13", "A/j", status); - -} - -static void t_atoi13(int *status) -/* -** - - - - - - - - - -** t _ a t o i 1 3 -** - - - - - - - - - -** -** Test eraAtoi13 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraAtoi13, vvd, viv -** -** This revision: 2013 October 3 -*/ -{ - double utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl, - ob1, ob2, ri, di; - int j; - - - utc1 = 2456384.5; - utc2 = 0.969254051; - dut1 = 0.1550675; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - phpa = 731.0; - tc = 12.8; - rh = 0.59; - wl = 0.55; - - ob1 = 2.710085107986886201; - ob2 = 0.1717653435758265198; - j = eraAtoi13 ( "R", ob1, ob2, utc1, utc2, dut1, - elong, phi, hm, xp, yp, phpa, tc, rh, wl, - &ri, &di); - vvd(ri, 2.710121574449135955, 1e-12, "eraAtoi13", "R/ri", status); - vvd(di, 0.1729371839114567725, 1e-12, "eraAtoi13", "R/di", status); - viv(j, 0, "eraAtoi13", "R/J", status); - - ob1 = -0.09247619879782006106; - ob2 = 0.1717653435758265198; - j = eraAtoi13 ( "H", ob1, ob2, utc1, utc2, dut1, - elong, phi, hm, xp, yp, phpa, tc, rh, wl, - &ri, &di); - vvd(ri, 2.710121574449135955, 1e-12, "eraAtoi13", "H/ri", status); - vvd(di, 0.1729371839114567725, 1e-12, "eraAtoi13", "H/di", status); - viv(j, 0, "eraAtoi13", "H/J", status); - - ob1 = 0.09233952224794989993; - ob2 = 1.407758704513722461; - j = eraAtoi13 ( "A", ob1, ob2, utc1, utc2, dut1, - elong, phi, hm, xp, yp, phpa, tc, rh, wl, - &ri, &di); - vvd(ri, 2.710121574449135955, 1e-12, "eraAtoi13", "A/ri", status); - vvd(di, 0.1729371839114567728, 1e-12, "eraAtoi13", "A/di", status); - viv(j, 0, "eraAtoi13", "A/J", status); - -} - -static void t_atoiq(int *status) -/* -** - - - - - - - - -** t _ a t o i q -** - - - - - - - - -* -** Test eraAtoiq function. -* -** Returned: -** status int FALSE = success, TRUE = fail -* -** Called: eraApio13, eraAtoiq, vvd -* -** This revision: 2013 October 4 -*/ -{ - double utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl, - ob1, ob2, ri, di; - eraASTROM astrom; - - - utc1 = 2456384.5; - utc2 = 0.969254051; - dut1 = 0.1550675; - elong = -0.527800806; - phi = -1.2345856; - hm = 2738.0; - xp = 2.47230737e-7; - yp = 1.82640464e-6; - phpa = 731.0; - tc = 12.8; - rh = 0.59; - wl = 0.55; - (void) eraApio13(utc1, utc2, dut1, elong, phi, hm, xp, yp, - phpa, tc, rh, wl, &astrom); - - ob1 = 2.710085107986886201; - ob2 = 0.1717653435758265198; - eraAtoiq("R", ob1, ob2, &astrom, &ri, &di); - vvd(ri, 2.710121574449135955, 1e-12, - "eraAtoiq", "R/ri", status); - vvd(di, 0.1729371839114567725, 1e-12, - "eraAtoiq", "R/di", status); - - ob1 = -0.09247619879782006106; - ob2 = 0.1717653435758265198; - eraAtoiq("H", ob1, ob2, &astrom, &ri, &di); - vvd(ri, 2.710121574449135955, 1e-12, - "eraAtoiq", "H/ri", status); - vvd(di, 0.1729371839114567725, 1e-12, - "eraAtoiq", "H/di", status); - - ob1 = 0.09233952224794989993; - ob2 = 1.407758704513722461; - eraAtoiq("A", ob1, ob2, &astrom, &ri, &di); - vvd(ri, 2.710121574449135955, 1e-12, - "eraAtoiq", "A/ri", status); - vvd(di, 0.1729371839114567728, 1e-12, - "eraAtoiq", "A/di", status); - -} - -static void t_bi00(int *status) -/* -** - - - - - - - -** t _ b i 0 0 -** - - - - - - - -** -** Test eraBi00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraBi00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsibi, depsbi, dra; - - eraBi00(&dpsibi, &depsbi, &dra); - - vvd(dpsibi, -0.2025309152835086613e-6, 1e-12, - "eraBi00", "dpsibi", status); - vvd(depsbi, -0.3306041454222147847e-7, 1e-12, - "eraBi00", "depsbi", status); - vvd(dra, -0.7078279744199225506e-7, 1e-12, - "eraBi00", "dra", status); -} - -static void t_bp00(int *status) -/* -** - - - - - - - -** t _ b p 0 0 -** - - - - - - - -** -** Test eraBp00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraBp00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rb[3][3], rp[3][3], rbp[3][3]; - - - eraBp00(2400000.5, 50123.9999, rb, rp, rbp); - - vvd(rb[0][0], 0.9999999999999942498, 1e-12, - "eraBp00", "rb11", status); - vvd(rb[0][1], -0.7078279744199196626e-7, 1e-16, - "eraBp00", "rb12", status); - vvd(rb[0][2], 0.8056217146976134152e-7, 1e-16, - "eraBp00", "rb13", status); - vvd(rb[1][0], 0.7078279477857337206e-7, 1e-16, - "eraBp00", "rb21", status); - vvd(rb[1][1], 0.9999999999999969484, 1e-12, - "eraBp00", "rb22", status); - vvd(rb[1][2], 0.3306041454222136517e-7, 1e-16, - "eraBp00", "rb23", status); - vvd(rb[2][0], -0.8056217380986972157e-7, 1e-16, - "eraBp00", "rb31", status); - vvd(rb[2][1], -0.3306040883980552500e-7, 1e-16, - "eraBp00", "rb32", status); - vvd(rb[2][2], 0.9999999999999962084, 1e-12, - "eraBp00", "rb33", status); - - vvd(rp[0][0], 0.9999995504864048241, 1e-12, - "eraBp00", "rp11", status); - vvd(rp[0][1], 0.8696113836207084411e-3, 1e-14, - "eraBp00", "rp12", status); - vvd(rp[0][2], 0.3778928813389333402e-3, 1e-14, - "eraBp00", "rp13", status); - vvd(rp[1][0], -0.8696113818227265968e-3, 1e-14, - "eraBp00", "rp21", status); - vvd(rp[1][1], 0.9999996218879365258, 1e-12, - "eraBp00", "rp22", status); - vvd(rp[1][2], -0.1690679263009242066e-6, 1e-14, - "eraBp00", "rp23", status); - vvd(rp[2][0], -0.3778928854764695214e-3, 1e-14, - "eraBp00", "rp31", status); - vvd(rp[2][1], -0.1595521004195286491e-6, 1e-14, - "eraBp00", "rp32", status); - vvd(rp[2][2], 0.9999999285984682756, 1e-12, - "eraBp00", "rp33", status); - - vvd(rbp[0][0], 0.9999995505175087260, 1e-12, - "eraBp00", "rbp11", status); - vvd(rbp[0][1], 0.8695405883617884705e-3, 1e-14, - "eraBp00", "rbp12", status); - vvd(rbp[0][2], 0.3779734722239007105e-3, 1e-14, - "eraBp00", "rbp13", status); - vvd(rbp[1][0], -0.8695405990410863719e-3, 1e-14, - "eraBp00", "rbp21", status); - vvd(rbp[1][1], 0.9999996219494925900, 1e-12, - "eraBp00", "rbp22", status); - vvd(rbp[1][2], -0.1360775820404982209e-6, 1e-14, - "eraBp00", "rbp23", status); - vvd(rbp[2][0], -0.3779734476558184991e-3, 1e-14, - "eraBp00", "rbp31", status); - vvd(rbp[2][1], -0.1925857585832024058e-6, 1e-14, - "eraBp00", "rbp32", status); - vvd(rbp[2][2], 0.9999999285680153377, 1e-12, - "eraBp00", "rbp33", status); -} - -static void t_bp06(int *status) -/* -** - - - - - - - -** t _ b p 0 6 -** - - - - - - - -** -** Test eraBp06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraBp06, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rb[3][3], rp[3][3], rbp[3][3]; - - - eraBp06(2400000.5, 50123.9999, rb, rp, rbp); - - vvd(rb[0][0], 0.9999999999999942497, 1e-12, - "eraBp06", "rb11", status); - vvd(rb[0][1], -0.7078368960971557145e-7, 1e-14, - "eraBp06", "rb12", status); - vvd(rb[0][2], 0.8056213977613185606e-7, 1e-14, - "eraBp06", "rb13", status); - vvd(rb[1][0], 0.7078368694637674333e-7, 1e-14, - "eraBp06", "rb21", status); - vvd(rb[1][1], 0.9999999999999969484, 1e-12, - "eraBp06", "rb22", status); - vvd(rb[1][2], 0.3305943742989134124e-7, 1e-14, - "eraBp06", "rb23", status); - vvd(rb[2][0], -0.8056214211620056792e-7, 1e-14, - "eraBp06", "rb31", status); - vvd(rb[2][1], -0.3305943172740586950e-7, 1e-14, - "eraBp06", "rb32", status); - vvd(rb[2][2], 0.9999999999999962084, 1e-12, - "eraBp06", "rb33", status); - - vvd(rp[0][0], 0.9999995504864960278, 1e-12, - "eraBp06", "rp11", status); - vvd(rp[0][1], 0.8696112578855404832e-3, 1e-14, - "eraBp06", "rp12", status); - vvd(rp[0][2], 0.3778929293341390127e-3, 1e-14, - "eraBp06", "rp13", status); - vvd(rp[1][0], -0.8696112560510186244e-3, 1e-14, - "eraBp06", "rp21", status); - vvd(rp[1][1], 0.9999996218880458820, 1e-12, - "eraBp06", "rp22", status); - vvd(rp[1][2], -0.1691646168941896285e-6, 1e-14, - "eraBp06", "rp23", status); - vvd(rp[2][0], -0.3778929335557603418e-3, 1e-14, - "eraBp06", "rp31", status); - vvd(rp[2][1], -0.1594554040786495076e-6, 1e-14, - "eraBp06", "rp32", status); - vvd(rp[2][2], 0.9999999285984501222, 1e-12, - "eraBp06", "rp33", status); - - vvd(rbp[0][0], 0.9999995505176007047, 1e-12, - "eraBp06", "rbp11", status); - vvd(rbp[0][1], 0.8695404617348208406e-3, 1e-14, - "eraBp06", "rbp12", status); - vvd(rbp[0][2], 0.3779735201865589104e-3, 1e-14, - "eraBp06", "rbp13", status); - vvd(rbp[1][0], -0.8695404723772031414e-3, 1e-14, - "eraBp06", "rbp21", status); - vvd(rbp[1][1], 0.9999996219496027161, 1e-12, - "eraBp06", "rbp22", status); - vvd(rbp[1][2], -0.1361752497080270143e-6, 1e-14, - "eraBp06", "rbp23", status); - vvd(rbp[2][0], -0.3779734957034089490e-3, 1e-14, - "eraBp06", "rbp31", status); - vvd(rbp[2][1], -0.1924880847894457113e-6, 1e-14, - "eraBp06", "rbp32", status); - vvd(rbp[2][2], 0.9999999285679971958, 1e-12, - "eraBp06", "rbp33", status); -} - -static void t_bpn2xy(int *status) -/* -** - - - - - - - - - -** t _ b p n 2 x y -** - - - - - - - - - -** -** Test eraBpn2xy function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraBpn2xy, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rbpn[3][3], x, y; - - - rbpn[0][0] = 9.999962358680738e-1; - rbpn[0][1] = -2.516417057665452e-3; - rbpn[0][2] = -1.093569785342370e-3; - - rbpn[1][0] = 2.516462370370876e-3; - rbpn[1][1] = 9.999968329010883e-1; - rbpn[1][2] = 4.006159587358310e-5; - - rbpn[2][0] = 1.093465510215479e-3; - rbpn[2][1] = -4.281337229063151e-5; - rbpn[2][2] = 9.999994012499173e-1; - - eraBpn2xy(rbpn, &x, &y); - - vvd(x, 1.093465510215479e-3, 1e-12, "eraBpn2xy", "x", status); - vvd(y, -4.281337229063151e-5, 1e-12, "eraBpn2xy", "y", status); - -} - -static void t_c2i00a(int *status) -/* -** - - - - - - - - - -** t _ c 2 i 0 0 a -** - - - - - - - - - -** -** Test eraC2i00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2i00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rc2i[3][3]; - - - eraC2i00a(2400000.5, 53736.0, rc2i); - - vvd(rc2i[0][0], 0.9999998323037165557, 1e-12, - "eraC2i00a", "11", status); - vvd(rc2i[0][1], 0.5581526348992140183e-9, 1e-12, - "eraC2i00a", "12", status); - vvd(rc2i[0][2], -0.5791308477073443415e-3, 1e-12, - "eraC2i00a", "13", status); - - vvd(rc2i[1][0], -0.2384266227870752452e-7, 1e-12, - "eraC2i00a", "21", status); - vvd(rc2i[1][1], 0.9999999991917405258, 1e-12, - "eraC2i00a", "22", status); - vvd(rc2i[1][2], -0.4020594955028209745e-4, 1e-12, - "eraC2i00a", "23", status); - - vvd(rc2i[2][0], 0.5791308472168152904e-3, 1e-12, - "eraC2i00a", "31", status); - vvd(rc2i[2][1], 0.4020595661591500259e-4, 1e-12, - "eraC2i00a", "32", status); - vvd(rc2i[2][2], 0.9999998314954572304, 1e-12, - "eraC2i00a", "33", status); - -} - -static void t_c2i00b(int *status) -/* -** - - - - - - - - - -** t _ c 2 i 0 0 b -** - - - - - - - - - -** -** Test eraC2i00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2i00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rc2i[3][3]; - - - eraC2i00b(2400000.5, 53736.0, rc2i); - - vvd(rc2i[0][0], 0.9999998323040954356, 1e-12, - "eraC2i00b", "11", status); - vvd(rc2i[0][1], 0.5581526349131823372e-9, 1e-12, - "eraC2i00b", "12", status); - vvd(rc2i[0][2], -0.5791301934855394005e-3, 1e-12, - "eraC2i00b", "13", status); - - vvd(rc2i[1][0], -0.2384239285499175543e-7, 1e-12, - "eraC2i00b", "21", status); - vvd(rc2i[1][1], 0.9999999991917574043, 1e-12, - "eraC2i00b", "22", status); - vvd(rc2i[1][2], -0.4020552974819030066e-4, 1e-12, - "eraC2i00b", "23", status); - - vvd(rc2i[2][0], 0.5791301929950208873e-3, 1e-12, - "eraC2i00b", "31", status); - vvd(rc2i[2][1], 0.4020553681373720832e-4, 1e-12, - "eraC2i00b", "32", status); - vvd(rc2i[2][2], 0.9999998314958529887, 1e-12, - "eraC2i00b", "33", status); - -} - -static void t_c2i06a(int *status) -/* -** - - - - - - - - - -** t _ c 2 i 0 6 a -** - - - - - - - - - -** -** Test eraC2i06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2i06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rc2i[3][3]; - - - eraC2i06a(2400000.5, 53736.0, rc2i); - - vvd(rc2i[0][0], 0.9999998323037159379, 1e-12, - "eraC2i06a", "11", status); - vvd(rc2i[0][1], 0.5581121329587613787e-9, 1e-12, - "eraC2i06a", "12", status); - vvd(rc2i[0][2], -0.5791308487740529749e-3, 1e-12, - "eraC2i06a", "13", status); - - vvd(rc2i[1][0], -0.2384253169452306581e-7, 1e-12, - "eraC2i06a", "21", status); - vvd(rc2i[1][1], 0.9999999991917467827, 1e-12, - "eraC2i06a", "22", status); - vvd(rc2i[1][2], -0.4020579392895682558e-4, 1e-12, - "eraC2i06a", "23", status); - - vvd(rc2i[2][0], 0.5791308482835292617e-3, 1e-12, - "eraC2i06a", "31", status); - vvd(rc2i[2][1], 0.4020580099454020310e-4, 1e-12, - "eraC2i06a", "32", status); - vvd(rc2i[2][2], 0.9999998314954628695, 1e-12, - "eraC2i06a", "33", status); - -} - -static void t_c2ibpn(int *status) -/* -** - - - - - - - - - -** t _ c 2 i b p n -** - - - - - - - - - -** -** Test eraC2ibpn function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2ibpn, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rbpn[3][3], rc2i[3][3]; - - - rbpn[0][0] = 9.999962358680738e-1; - rbpn[0][1] = -2.516417057665452e-3; - rbpn[0][2] = -1.093569785342370e-3; - - rbpn[1][0] = 2.516462370370876e-3; - rbpn[1][1] = 9.999968329010883e-1; - rbpn[1][2] = 4.006159587358310e-5; - - rbpn[2][0] = 1.093465510215479e-3; - rbpn[2][1] = -4.281337229063151e-5; - rbpn[2][2] = 9.999994012499173e-1; - - eraC2ibpn(2400000.5, 50123.9999, rbpn, rc2i); - - vvd(rc2i[0][0], 0.9999994021664089977, 1e-12, - "eraC2ibpn", "11", status); - vvd(rc2i[0][1], -0.3869195948017503664e-8, 1e-12, - "eraC2ibpn", "12", status); - vvd(rc2i[0][2], -0.1093465511383285076e-2, 1e-12, - "eraC2ibpn", "13", status); - - vvd(rc2i[1][0], 0.5068413965715446111e-7, 1e-12, - "eraC2ibpn", "21", status); - vvd(rc2i[1][1], 0.9999999990835075686, 1e-12, - "eraC2ibpn", "22", status); - vvd(rc2i[1][2], 0.4281334246452708915e-4, 1e-12, - "eraC2ibpn", "23", status); - - vvd(rc2i[2][0], 0.1093465510215479000e-2, 1e-12, - "eraC2ibpn", "31", status); - vvd(rc2i[2][1], -0.4281337229063151000e-4, 1e-12, - "eraC2ibpn", "32", status); - vvd(rc2i[2][2], 0.9999994012499173103, 1e-12, - "eraC2ibpn", "33", status); - -} - -static void t_c2ixy(int *status) -/* -** - - - - - - - - -** t _ c 2 i x y -** - - - - - - - - -** -** Test eraC2ixy function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2ixy, vvd -** -** This revision: 2013 August 7 -*/ -{ - double x, y, rc2i[3][3]; - - - x = 0.5791308486706011000e-3; - y = 0.4020579816732961219e-4; - - eraC2ixy(2400000.5, 53736, x, y, rc2i); - - vvd(rc2i[0][0], 0.9999998323037157138, 1e-12, - "eraC2ixy", "11", status); - vvd(rc2i[0][1], 0.5581526349032241205e-9, 1e-12, - "eraC2ixy", "12", status); - vvd(rc2i[0][2], -0.5791308491611263745e-3, 1e-12, - "eraC2ixy", "13", status); - - vvd(rc2i[1][0], -0.2384257057469842953e-7, 1e-12, - "eraC2ixy", "21", status); - vvd(rc2i[1][1], 0.9999999991917468964, 1e-12, - "eraC2ixy", "22", status); - vvd(rc2i[1][2], -0.4020579110172324363e-4, 1e-12, - "eraC2ixy", "23", status); - - vvd(rc2i[2][0], 0.5791308486706011000e-3, 1e-12, - "eraC2ixy", "31", status); - vvd(rc2i[2][1], 0.4020579816732961219e-4, 1e-12, - "eraC2ixy", "32", status); - vvd(rc2i[2][2], 0.9999998314954627590, 1e-12, - "eraC2ixy", "33", status); - -} - -static void t_c2ixys(int *status) -/* -** - - - - - - - - - -** t _ c 2 i x y s -** - - - - - - - - - -** -** Test eraC2ixys function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2ixys, vvd -** -** This revision: 2013 August 7 -*/ -{ - double x, y, s, rc2i[3][3]; - - - x = 0.5791308486706011000e-3; - y = 0.4020579816732961219e-4; - s = -0.1220040848472271978e-7; - - eraC2ixys(x, y, s, rc2i); - - vvd(rc2i[0][0], 0.9999998323037157138, 1e-12, - "eraC2ixys", "11", status); - vvd(rc2i[0][1], 0.5581984869168499149e-9, 1e-12, - "eraC2ixys", "12", status); - vvd(rc2i[0][2], -0.5791308491611282180e-3, 1e-12, - "eraC2ixys", "13", status); - - vvd(rc2i[1][0], -0.2384261642670440317e-7, 1e-12, - "eraC2ixys", "21", status); - vvd(rc2i[1][1], 0.9999999991917468964, 1e-12, - "eraC2ixys", "22", status); - vvd(rc2i[1][2], -0.4020579110169668931e-4, 1e-12, - "eraC2ixys", "23", status); - - vvd(rc2i[2][0], 0.5791308486706011000e-3, 1e-12, - "eraC2ixys", "31", status); - vvd(rc2i[2][1], 0.4020579816732961219e-4, 1e-12, - "eraC2ixys", "32", status); - vvd(rc2i[2][2], 0.9999998314954627590, 1e-12, - "eraC2ixys", "33", status); - -} - -static void t_c2s(int *status) -/* -** - - - - - - -** t _ c 2 s -** - - - - - - -** -** Test eraC2s function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2s, vvd -** -** This revision: 2013 August 7 -*/ -{ - double p[3], theta, phi; - - - p[0] = 100.0; - p[1] = -50.0; - p[2] = 25.0; - - eraC2s(p, &theta, &phi); - - vvd(theta, -0.4636476090008061162, 1e-14, "eraC2s", "theta", status); - vvd(phi, 0.2199879773954594463, 1e-14, "eraC2s", "phi", status); - -} - -static void t_c2t00a(int *status) -/* -** - - - - - - - - - -** t _ c 2 t 0 0 a -** - - - - - - - - - -** -** Test eraC2t00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2t00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double tta, ttb, uta, utb, xp, yp, rc2t[3][3]; - - - tta = 2400000.5; - uta = 2400000.5; - ttb = 53736.0; - utb = 53736.0; - xp = 2.55060238e-7; - yp = 1.860359247e-6; - - eraC2t00a(tta, ttb, uta, utb, xp, yp, rc2t); - - vvd(rc2t[0][0], -0.1810332128307182668, 1e-12, - "eraC2t00a", "11", status); - vvd(rc2t[0][1], 0.9834769806938457836, 1e-12, - "eraC2t00a", "12", status); - vvd(rc2t[0][2], 0.6555535638688341725e-4, 1e-12, - "eraC2t00a", "13", status); - - vvd(rc2t[1][0], -0.9834768134135984552, 1e-12, - "eraC2t00a", "21", status); - vvd(rc2t[1][1], -0.1810332203649520727, 1e-12, - "eraC2t00a", "22", status); - vvd(rc2t[1][2], 0.5749801116141056317e-3, 1e-12, - "eraC2t00a", "23", status); - - vvd(rc2t[2][0], 0.5773474014081406921e-3, 1e-12, - "eraC2t00a", "31", status); - vvd(rc2t[2][1], 0.3961832391770163647e-4, 1e-12, - "eraC2t00a", "32", status); - vvd(rc2t[2][2], 0.9999998325501692289, 1e-12, - "eraC2t00a", "33", status); - -} - -static void t_c2t00b(int *status) -/* -** - - - - - - - - - -** t _ c 2 t 0 0 b -** - - - - - - - - - -** -** Test eraC2t00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2t00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double tta, ttb, uta, utb, xp, yp, rc2t[3][3]; - - - tta = 2400000.5; - uta = 2400000.5; - ttb = 53736.0; - utb = 53736.0; - xp = 2.55060238e-7; - yp = 1.860359247e-6; - - eraC2t00b(tta, ttb, uta, utb, xp, yp, rc2t); - - vvd(rc2t[0][0], -0.1810332128439678965, 1e-12, - "eraC2t00b", "11", status); - vvd(rc2t[0][1], 0.9834769806913872359, 1e-12, - "eraC2t00b", "12", status); - vvd(rc2t[0][2], 0.6555565082458415611e-4, 1e-12, - "eraC2t00b", "13", status); - - vvd(rc2t[1][0], -0.9834768134115435923, 1e-12, - "eraC2t00b", "21", status); - vvd(rc2t[1][1], -0.1810332203784001946, 1e-12, - "eraC2t00b", "22", status); - vvd(rc2t[1][2], 0.5749793922030017230e-3, 1e-12, - "eraC2t00b", "23", status); - - vvd(rc2t[2][0], 0.5773467471863534901e-3, 1e-12, - "eraC2t00b", "31", status); - vvd(rc2t[2][1], 0.3961790411549945020e-4, 1e-12, - "eraC2t00b", "32", status); - vvd(rc2t[2][2], 0.9999998325505635738, 1e-12, - "eraC2t00b", "33", status); - -} - -static void t_c2t06a(int *status) -/* -** - - - - - - - - - -** t _ c 2 t 0 6 a -** - - - - - - - - - -** -** Test eraC2t06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2t06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double tta, ttb, uta, utb, xp, yp, rc2t[3][3]; - - - tta = 2400000.5; - uta = 2400000.5; - ttb = 53736.0; - utb = 53736.0; - xp = 2.55060238e-7; - yp = 1.860359247e-6; - - eraC2t06a(tta, ttb, uta, utb, xp, yp, rc2t); - - vvd(rc2t[0][0], -0.1810332128305897282, 1e-12, - "eraC2t06a", "11", status); - vvd(rc2t[0][1], 0.9834769806938592296, 1e-12, - "eraC2t06a", "12", status); - vvd(rc2t[0][2], 0.6555550962998436505e-4, 1e-12, - "eraC2t06a", "13", status); - - vvd(rc2t[1][0], -0.9834768134136214897, 1e-12, - "eraC2t06a", "21", status); - vvd(rc2t[1][1], -0.1810332203649130832, 1e-12, - "eraC2t06a", "22", status); - vvd(rc2t[1][2], 0.5749800844905594110e-3, 1e-12, - "eraC2t06a", "23", status); - - vvd(rc2t[2][0], 0.5773474024748545878e-3, 1e-12, - "eraC2t06a", "31", status); - vvd(rc2t[2][1], 0.3961816829632690581e-4, 1e-12, - "eraC2t06a", "32", status); - vvd(rc2t[2][2], 0.9999998325501747785, 1e-12, - "eraC2t06a", "33", status); - -} - -static void t_c2tcio(int *status) -/* -** - - - - - - - - - -** t _ c 2 t c i o -** - - - - - - - - - -** -** Test eraC2tcio function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2tcio, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rc2i[3][3], era, rpom[3][3], rc2t[3][3]; - - - rc2i[0][0] = 0.9999998323037164738; - rc2i[0][1] = 0.5581526271714303683e-9; - rc2i[0][2] = -0.5791308477073443903e-3; - - rc2i[1][0] = -0.2384266227524722273e-7; - rc2i[1][1] = 0.9999999991917404296; - rc2i[1][2] = -0.4020594955030704125e-4; - - rc2i[2][0] = 0.5791308472168153320e-3; - rc2i[2][1] = 0.4020595661593994396e-4; - rc2i[2][2] = 0.9999998314954572365; - - era = 1.75283325530307; - - rpom[0][0] = 0.9999999999999674705; - rpom[0][1] = -0.1367174580728847031e-10; - rpom[0][2] = 0.2550602379999972723e-6; - - rpom[1][0] = 0.1414624947957029721e-10; - rpom[1][1] = 0.9999999999982694954; - rpom[1][2] = -0.1860359246998866338e-5; - - rpom[2][0] = -0.2550602379741215275e-6; - rpom[2][1] = 0.1860359247002413923e-5; - rpom[2][2] = 0.9999999999982369658; - - - eraC2tcio(rc2i, era, rpom, rc2t); - - vvd(rc2t[0][0], -0.1810332128307110439, 1e-12, - "eraC2tcio", "11", status); - vvd(rc2t[0][1], 0.9834769806938470149, 1e-12, - "eraC2tcio", "12", status); - vvd(rc2t[0][2], 0.6555535638685466874e-4, 1e-12, - "eraC2tcio", "13", status); - - vvd(rc2t[1][0], -0.9834768134135996657, 1e-12, - "eraC2tcio", "21", status); - vvd(rc2t[1][1], -0.1810332203649448367, 1e-12, - "eraC2tcio", "22", status); - vvd(rc2t[1][2], 0.5749801116141106528e-3, 1e-12, - "eraC2tcio", "23", status); - - vvd(rc2t[2][0], 0.5773474014081407076e-3, 1e-12, - "eraC2tcio", "31", status); - vvd(rc2t[2][1], 0.3961832391772658944e-4, 1e-12, - "eraC2tcio", "32", status); - vvd(rc2t[2][2], 0.9999998325501691969, 1e-12, - "eraC2tcio", "33", status); - -} - -static void t_c2teqx(int *status) -/* -** - - - - - - - - - -** t _ c 2 t e q x -** - - - - - - - - - -** -** Test eraC2teqx function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2teqx, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rbpn[3][3], gst, rpom[3][3], rc2t[3][3]; - - - rbpn[0][0] = 0.9999989440476103608; - rbpn[0][1] = -0.1332881761240011518e-2; - rbpn[0][2] = -0.5790767434730085097e-3; - - rbpn[1][0] = 0.1332858254308954453e-2; - rbpn[1][1] = 0.9999991109044505944; - rbpn[1][2] = -0.4097782710401555759e-4; - - rbpn[2][0] = 0.5791308472168153320e-3; - rbpn[2][1] = 0.4020595661593994396e-4; - rbpn[2][2] = 0.9999998314954572365; - - gst = 1.754166138040730516; - - rpom[0][0] = 0.9999999999999674705; - rpom[0][1] = -0.1367174580728847031e-10; - rpom[0][2] = 0.2550602379999972723e-6; - - rpom[1][0] = 0.1414624947957029721e-10; - rpom[1][1] = 0.9999999999982694954; - rpom[1][2] = -0.1860359246998866338e-5; - - rpom[2][0] = -0.2550602379741215275e-6; - rpom[2][1] = 0.1860359247002413923e-5; - rpom[2][2] = 0.9999999999982369658; - - eraC2teqx(rbpn, gst, rpom, rc2t); - - vvd(rc2t[0][0], -0.1810332128528685730, 1e-12, - "eraC2teqx", "11", status); - vvd(rc2t[0][1], 0.9834769806897685071, 1e-12, - "eraC2teqx", "12", status); - vvd(rc2t[0][2], 0.6555535639982634449e-4, 1e-12, - "eraC2teqx", "13", status); - - vvd(rc2t[1][0], -0.9834768134095211257, 1e-12, - "eraC2teqx", "21", status); - vvd(rc2t[1][1], -0.1810332203871023800, 1e-12, - "eraC2teqx", "22", status); - vvd(rc2t[1][2], 0.5749801116126438962e-3, 1e-12, - "eraC2teqx", "23", status); - - vvd(rc2t[2][0], 0.5773474014081539467e-3, 1e-12, - "eraC2teqx", "31", status); - vvd(rc2t[2][1], 0.3961832391768640871e-4, 1e-12, - "eraC2teqx", "32", status); - vvd(rc2t[2][2], 0.9999998325501691969, 1e-12, - "eraC2teqx", "33", status); - -} - -static void t_c2tpe(int *status) -/* -** - - - - - - - - -** t _ c 2 t p e -** - - - - - - - - -** -** Test eraC2tpe function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2tpe, vvd -** -** This revision: 2013 August 7 -*/ -{ - double tta, ttb, uta, utb, dpsi, deps, xp, yp, rc2t[3][3]; - - - tta = 2400000.5; - uta = 2400000.5; - ttb = 53736.0; - utb = 53736.0; - deps = 0.4090789763356509900; - dpsi = -0.9630909107115582393e-5; - xp = 2.55060238e-7; - yp = 1.860359247e-6; - - eraC2tpe(tta, ttb, uta, utb, dpsi, deps, xp, yp, rc2t); - - vvd(rc2t[0][0], -0.1813677995763029394, 1e-12, - "eraC2tpe", "11", status); - vvd(rc2t[0][1], 0.9023482206891683275, 1e-12, - "eraC2tpe", "12", status); - vvd(rc2t[0][2], -0.3909902938641085751, 1e-12, - "eraC2tpe", "13", status); - - vvd(rc2t[1][0], -0.9834147641476804807, 1e-12, - "eraC2tpe", "21", status); - vvd(rc2t[1][1], -0.1659883635434995121, 1e-12, - "eraC2tpe", "22", status); - vvd(rc2t[1][2], 0.7309763898042819705e-1, 1e-12, - "eraC2tpe", "23", status); - - vvd(rc2t[2][0], 0.1059685430673215247e-2, 1e-12, - "eraC2tpe", "31", status); - vvd(rc2t[2][1], 0.3977631855605078674, 1e-12, - "eraC2tpe", "32", status); - vvd(rc2t[2][2], 0.9174875068792735362, 1e-12, - "eraC2tpe", "33", status); - -} - -static void t_c2txy(int *status) -/* -** - - - - - - - - -** t _ c 2 t x y -** - - - - - - - - -** -** Test eraC2txy function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraC2txy, vvd -** -** This revision: 2013 August 7 -*/ -{ - double tta, ttb, uta, utb, x, y, xp, yp, rc2t[3][3]; - - - tta = 2400000.5; - uta = 2400000.5; - ttb = 53736.0; - utb = 53736.0; - x = 0.5791308486706011000e-3; - y = 0.4020579816732961219e-4; - xp = 2.55060238e-7; - yp = 1.860359247e-6; - - eraC2txy(tta, ttb, uta, utb, x, y, xp, yp, rc2t); - - vvd(rc2t[0][0], -0.1810332128306279253, 1e-12, - "eraC2txy", "11", status); - vvd(rc2t[0][1], 0.9834769806938520084, 1e-12, - "eraC2txy", "12", status); - vvd(rc2t[0][2], 0.6555551248057665829e-4, 1e-12, - "eraC2txy", "13", status); - - vvd(rc2t[1][0], -0.9834768134136142314, 1e-12, - "eraC2txy", "21", status); - vvd(rc2t[1][1], -0.1810332203649529312, 1e-12, - "eraC2txy", "22", status); - vvd(rc2t[1][2], 0.5749800843594139912e-3, 1e-12, - "eraC2txy", "23", status); - - vvd(rc2t[2][0], 0.5773474028619264494e-3, 1e-12, - "eraC2txy", "31", status); - vvd(rc2t[2][1], 0.3961816546911624260e-4, 1e-12, - "eraC2txy", "32", status); - vvd(rc2t[2][2], 0.9999998325501746670, 1e-12, - "eraC2txy", "33", status); - -} - -static void t_cal2jd(int *status) -/* -** - - - - - - - - - -** t _ c a l 2 j d -** - - - - - - - - - -** -** Test eraCal2jd function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraCal2jd, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - int j; - double djm0, djm; - - - j = eraCal2jd(2003, 06, 01, &djm0, &djm); - - vvd(djm0, 2400000.5, 0.0, "eraCal2jd", "djm0", status); - vvd(djm, 52791.0, 0.0, "eraCal2jd", "djm", status); - - viv(j, 0, "eraCal2jd", "j", status); - -} - -static void t_cp(int *status) -/* -** - - - - - -** t _ c p -** - - - - - -** -** Test eraCp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraCp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double p[3], c[3]; - - - p[0] = 0.3; - p[1] = 1.2; - p[2] = -2.5; - - eraCp(p, c); - - vvd(c[0], 0.3, 0.0, "eraCp", "1", status); - vvd(c[1], 1.2, 0.0, "eraCp", "2", status); - vvd(c[2], -2.5, 0.0, "eraCp", "3", status); -} - -static void t_cpv(int *status) -/* -** - - - - - - -** t _ c p v -** - - - - - - -** -** Test eraCpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraCpv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double pv[2][3], c[2][3]; - - - pv[0][0] = 0.3; - pv[0][1] = 1.2; - pv[0][2] = -2.5; - - pv[1][0] = -0.5; - pv[1][1] = 3.1; - pv[1][2] = 0.9; - - eraCpv(pv, c); - - vvd(c[0][0], 0.3, 0.0, "eraCpv", "p1", status); - vvd(c[0][1], 1.2, 0.0, "eraCpv", "p2", status); - vvd(c[0][2], -2.5, 0.0, "eraCpv", "p3", status); - - vvd(c[1][0], -0.5, 0.0, "eraCpv", "v1", status); - vvd(c[1][1], 3.1, 0.0, "eraCpv", "v2", status); - vvd(c[1][2], 0.9, 0.0, "eraCpv", "v3", status); - -} - -static void t_cr(int *status) -/* -** - - - - - -** t _ c r -** - - - - - -** -** Test eraCr function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraCr, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r[3][3], c[3][3]; - - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - eraCr(r, c); - - vvd(c[0][0], 2.0, 0.0, "eraCr", "11", status); - vvd(c[0][1], 3.0, 0.0, "eraCr", "12", status); - vvd(c[0][2], 2.0, 0.0, "eraCr", "13", status); - - vvd(c[1][0], 3.0, 0.0, "eraCr", "21", status); - vvd(c[1][1], 2.0, 0.0, "eraCr", "22", status); - vvd(c[1][2], 3.0, 0.0, "eraCr", "23", status); - - vvd(c[2][0], 3.0, 0.0, "eraCr", "31", status); - vvd(c[2][1], 4.0, 0.0, "eraCr", "32", status); - vvd(c[2][2], 5.0, 0.0, "eraCr", "33", status); -} - -static void t_d2dtf(int *status ) -/* -** - - - - - - - - -** t _ d 2 d t f -** - - - - - - - - -** -** Test eraD2dtf function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraD2dtf, viv -** -** This revision: 2013 August 7 -*/ -{ - int j, iy, im, id, ihmsf[4]; - - - j = eraD2dtf("UTC", 5, 2400000.5, 49533.99999, &iy, &im, &id, ihmsf); - - viv(iy, 1994, "eraD2dtf", "y", status); - viv(im, 6, "eraD2dtf", "mo", status); - viv(id, 30, "eraD2dtf", "d", status); - viv(ihmsf[0], 23, "eraD2dtf", "h", status); - viv(ihmsf[1], 59, "eraD2dtf", "m", status); - viv(ihmsf[2], 60, "eraD2dtf", "s", status); - viv(ihmsf[3], 13599, "eraD2dtf", "f", status); - viv(j, 0, "eraD2dtf", "j", status); - -} - -static void t_d2tf(int *status) -/* -** - - - - - - - -** t _ d 2 t f -** - - - - - - - -** -** Test eraD2tf function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraD2tf, viv, vvd -** -** This revision: 2013 August 7 -*/ -{ - int ihmsf[4]; - char s; - - - eraD2tf(4, -0.987654321, &s, ihmsf); - - viv((int)s, '-', "eraD2tf", "s", status); - - viv(ihmsf[0], 23, "eraD2tf", "0", status); - viv(ihmsf[1], 42, "eraD2tf", "1", status); - viv(ihmsf[2], 13, "eraD2tf", "2", status); - viv(ihmsf[3], 3333, "eraD2tf", "3", status); - -} - -static void t_dat(int *status) -/* -** - - - - - - -** t _ d a t -** - - - - - - -** -** Test eraDat function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraDat, vvd, viv -** -** This revision: 2016 July 11 -*/ -{ - int j; - double deltat; - - - j = eraDat(2003, 6, 1, 0.0, &deltat); - - vvd(deltat, 32.0, 0.0, "eraDat", "d1", status); - viv(j, 0, "eraDat", "j1", status); - - j = eraDat(2008, 1, 17, 0.0, &deltat); - - vvd(deltat, 33.0, 0.0, "eraDat", "d2", status); - viv(j, 0, "eraDat", "j2", status); - - j = eraDat(2017, 9, 1, 0.0, &deltat); - - vvd(deltat, 37.0, 0.0, "eraDat", "d3", status); - viv(j, 0, "eraDat", "j3", status); - -} - -static void t_dtdb(int *status) -/* -** - - - - - - - -** t _ d t d b -** - - - - - - - -** -** Test eraDtdb function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraDtdb, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dtdb; - - - dtdb = eraDtdb(2448939.5, 0.123, 0.76543, 5.0123, 5525.242, 3190.0); - - vvd(dtdb, -0.1280368005936998991e-2, 1e-15, "eraDtdb", "", status); - -} - -static void t_dtf2d(int *status) -/* -** - - - - - - - - -** t _ d t f 2 d -** - - - - - - - - -** -** Test eraDtf2d function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraDtf2d, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double u1, u2; - int j; - - - j = eraDtf2d("UTC", 1994, 6, 30, 23, 59, 60.13599, &u1, &u2); - - vvd(u1+u2, 2449534.49999, 1e-6, "eraDtf2d", "u", status); - viv(j, 0, "eraDtf2d", "j", status); - -} - -static void t_eceq06(int *status) -/* -** - - - - - -** t _ e c e q 0 6 -** - - - - - -** -** Test eraEceq06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEceq06, vvd -** -** This revision: 2016 March 12 -*/ -{ - double date1, date2, dl, db, dr, dd; - - - date1 = 2456165.5; - date2 = 0.401182685; - dl = 5.1; - db = -0.9; - - eraEceq06(date1, date2, dl, db, &dr, &dd); - - vvd(dr, 5.533459733613627767, 1e-14, "eraEceq06", "dr", status); - vvd(dd, -1.246542932554480576, 1e-14, "eraEceq06", "dd", status); - -} - -static void t_ecm06(int *status) -/* -** - - - - - - - - -** t _ e c m 0 6 -** - - - - - - - - -** -** Test eraEcm06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEcm06, vvd -** -** This revision: 2016 March 12 -*/ -{ - double date1, date2, rm[3][3]; - - - date1 = 2456165.5; - date2 = 0.401182685; - - eraEcm06(date1, date2, rm); - - vvd(rm[0][0], 0.9999952427708701137, 1e-14, - "eraEcm06", "rm11", status); - vvd(rm[0][1], -0.2829062057663042347e-2, 1e-14, - "eraEcm06", "rm12", status); - vvd(rm[0][2], -0.1229163741100017629e-2, 1e-14, - "eraEcm06", "rm13", status); - vvd(rm[1][0], 0.3084546876908653562e-2, 1e-14, - "eraEcm06", "rm21", status); - vvd(rm[1][1], 0.9174891871550392514, 1e-14, - "eraEcm06", "rm22", status); - vvd(rm[1][2], 0.3977487611849338124, 1e-14, - "eraEcm06", "rm23", status); - vvd(rm[2][0], 0.2488512951527405928e-5, 1e-14, - "eraEcm06", "rm31", status); - vvd(rm[2][1], -0.3977506604161195467, 1e-14, - "eraEcm06", "rm32", status); - vvd(rm[2][2], 0.9174935488232863071, 1e-14, - "eraEcm06", "rm33", status); - -} - -static void t_ee00(int *status) -/* -** - - - - - - - -** t _ e e 0 0 -** - - - - - - - -** -** Test eraEe00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEe00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double epsa, dpsi, ee; - - - epsa = 0.4090789763356509900; - dpsi = -0.9630909107115582393e-5; - - ee = eraEe00(2400000.5, 53736.0, epsa, dpsi); - - vvd(ee, -0.8834193235367965479e-5, 1e-18, "eraEe00", "", status); - -} - -static void t_ee00a(int *status) -/* -** - - - - - - - - -** t _ e e 0 0 a -** - - - - - - - - -** -** Test eraEe00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEe00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double ee; - - - ee = eraEe00a(2400000.5, 53736.0); - - vvd(ee, -0.8834192459222588227e-5, 1e-18, "eraEe00a", "", status); - -} - -static void t_ee00b(int *status) -/* -** - - - - - - - - -** t _ e e 0 0 b -** - - - - - - - - -** -** Test eraEe00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEe00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double ee; - - - ee = eraEe00b(2400000.5, 53736.0); - - vvd(ee, -0.8835700060003032831e-5, 1e-18, "eraEe00b", "", status); - -} - -static void t_ee06a(int *status) -/* -** - - - - - - - - -** t _ e e 0 6 a -** - - - - - - - - -** -** Test eraEe06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEe06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double ee; - - - ee = eraEe06a(2400000.5, 53736.0); - - vvd(ee, -0.8834195072043790156e-5, 1e-15, "eraEe06a", "", status); -} - -static void t_eect00(int *status) -/* -** - - - - - - - - - -** t _ e e c t 0 0 -** - - - - - - - - - -** -** Test eraEect00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEect00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double eect; - - - eect = eraEect00(2400000.5, 53736.0); - - vvd(eect, 0.2046085004885125264e-8, 1e-20, "eraEect00", "", status); - -} - -static void t_eform(int *status) -/* -** - - - - - - - - -** t _ e f o r m -** - - - - - - - - -** -** Test eraEform function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEform, viv, vvd -** -** This revision: 2016 March 12 -*/ -{ - int j; - double a, f; - - j = eraEform(0, &a, &f); - - viv(j, -1, "eraEform", "j0", status); - - j = eraEform(ERFA_WGS84, &a, &f); - - viv(j, 0, "eraEform", "j1", status); - vvd(a, 6378137.0, 1e-10, "eraEform", "a1", status); - vvd(f, 0.3352810664747480720e-2, 1e-18, "eraEform", "f1", status); - - j = eraEform(ERFA_GRS80, &a, &f); - - viv(j, 0, "eraEform", "j2", status); - vvd(a, 6378137.0, 1e-10, "eraEform", "a2", status); - vvd(f, 0.3352810681182318935e-2, 1e-18, "eraEform", "f2", status); - - j = eraEform(ERFA_WGS72, &a, &f); - - viv(j, 0, "eraEform", "j2", status); - vvd(a, 6378135.0, 1e-10, "eraEform", "a3", status); - vvd(f, 0.3352779454167504862e-2, 1e-18, "eraEform", "f3", status); - - j = eraEform(4, &a, &f); - viv(j, -1, "eraEform", "j3", status); -} - -static void t_eo06a(int *status) -/* -** - - - - - - - - -** t _ e o 0 6 a -** - - - - - - - - -** -** Test eraEo06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEo06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double eo; - - - eo = eraEo06a(2400000.5, 53736.0); - - vvd(eo, -0.1332882371941833644e-2, 1e-15, "eraEo06a", "", status); - -} - -static void t_eors(int *status) -/* -** - - - - - - - -** t _ e o r s -** - - - - - - - -** -** Test eraEors function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEors, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rnpb[3][3], s, eo; - - - rnpb[0][0] = 0.9999989440476103608; - rnpb[0][1] = -0.1332881761240011518e-2; - rnpb[0][2] = -0.5790767434730085097e-3; - - rnpb[1][0] = 0.1332858254308954453e-2; - rnpb[1][1] = 0.9999991109044505944; - rnpb[1][2] = -0.4097782710401555759e-4; - - rnpb[2][0] = 0.5791308472168153320e-3; - rnpb[2][1] = 0.4020595661593994396e-4; - rnpb[2][2] = 0.9999998314954572365; - - s = -0.1220040848472271978e-7; - - eo = eraEors(rnpb, s); - - vvd(eo, -0.1332882715130744606e-2, 1e-14, "eraEors", "", status); - -} - -static void t_epb(int *status) -/* -** - - - - - - -** t _ e p b -** - - - - - - -** -** Test eraEpb function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEpb, vvd -** -** This revision: 2013 August 7 -*/ -{ - double epb; - - - epb = eraEpb(2415019.8135, 30103.18648); - - vvd(epb, 1982.418424159278580, 1e-12, "eraEpb", "", status); - -} - -static void t_epb2jd(int *status) -/* -** - - - - - - - - - -** t _ e p b 2 j d -** - - - - - - - - - -** -** Test eraEpb2jd function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEpb2jd, vvd -** -** This revision: 2013 August 7 -*/ -{ - double epb, djm0, djm; - - - epb = 1957.3; - - eraEpb2jd(epb, &djm0, &djm); - - vvd(djm0, 2400000.5, 1e-9, "eraEpb2jd", "djm0", status); - vvd(djm, 35948.1915101513, 1e-9, "eraEpb2jd", "mjd", status); - -} - -static void t_epj(int *status) -/* -** - - - - - - -** t _ e p j -** - - - - - - -** -** Test eraEpj function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEpj, vvd -** -** This revision: 2013 August 7 -*/ -{ - double epj; - - - epj = eraEpj(2451545, -7392.5); - - vvd(epj, 1979.760438056125941, 1e-12, "eraEpj", "", status); - -} - -static void t_epj2jd(int *status) -/* -** - - - - - - - - - -** t _ e p j 2 j d -** - - - - - - - - - -** -** Test eraEpj2jd function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEpj2jd, vvd -** -** This revision: 2013 August 7 -*/ -{ - double epj, djm0, djm; - - - epj = 1996.8; - - eraEpj2jd(epj, &djm0, &djm); - - vvd(djm0, 2400000.5, 1e-9, "eraEpj2jd", "djm0", status); - vvd(djm, 50375.7, 1e-9, "eraEpj2jd", "mjd", status); - -} - -static void t_epv00(int *status) -/* -** - - - - - - - - -** t _ e p v 0 0 -** - - - - - - - - -** -** Test eraEpv00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEpv00, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double pvh[2][3], pvb[2][3]; - int j; - - - j = eraEpv00(2400000.5, 53411.52501161, pvh, pvb); - - vvd(pvh[0][0], -0.7757238809297706813, 1e-14, - "eraEpv00", "ph(x)", status); - vvd(pvh[0][1], 0.5598052241363340596, 1e-14, - "eraEpv00", "ph(y)", status); - vvd(pvh[0][2], 0.2426998466481686993, 1e-14, - "eraEpv00", "ph(z)", status); - - vvd(pvh[1][0], -0.1091891824147313846e-1, 1e-15, - "eraEpv00", "vh(x)", status); - vvd(pvh[1][1], -0.1247187268440845008e-1, 1e-15, - "eraEpv00", "vh(y)", status); - vvd(pvh[1][2], -0.5407569418065039061e-2, 1e-15, - "eraEpv00", "vh(z)", status); - - vvd(pvb[0][0], -0.7714104440491111971, 1e-14, - "eraEpv00", "pb(x)", status); - vvd(pvb[0][1], 0.5598412061824171323, 1e-14, - "eraEpv00", "pb(y)", status); - vvd(pvb[0][2], 0.2425996277722452400, 1e-14, - "eraEpv00", "pb(z)", status); - - vvd(pvb[1][0], -0.1091874268116823295e-1, 1e-15, - "eraEpv00", "vb(x)", status); - vvd(pvb[1][1], -0.1246525461732861538e-1, 1e-15, - "eraEpv00", "vb(y)", status); - vvd(pvb[1][2], -0.5404773180966231279e-2, 1e-15, - "eraEpv00", "vb(z)", status); - - viv(j, 0, "eraEpv00", "j", status); - -} - -static void t_eqec06(int *status) -/* -** - - - - - - - - - -** t _ e q e c 0 6 -** - - - - - - - - - -** -** Test eraEqec06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEqec06, vvd -** -** This revision: 2016 March 12 -*/ -{ - double date1, date2, dr, dd, dl, db; - - - date1 = 1234.5; - date2 = 2440000.5; - dr = 1.234; - dd = 0.987; - - eraEqec06(date1, date2, dr, dd, &dl, &db); - - vvd(dl, 1.342509918994654619, 1e-14, "eraEqec06", "dl", status); - vvd(db, 0.5926215259704608132, 1e-14, "eraEqec06", "db", status); - -} - -static void t_eqeq94(int *status) -/* -** - - - - - - - - - -** t _ e q e q 9 4 -** - - - - - - - - - -** -** Test eraEqeq94 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEqeq94, vvd -** -** This revision: 2013 August 7 -*/ -{ - double eqeq; - - - eqeq = eraEqeq94(2400000.5, 41234.0); - - vvd(eqeq, 0.5357758254609256894e-4, 1e-17, "eraEqeq94", "", status); - -} - -static void t_era00(int *status) -/* -** - - - - - - - - -** t _ e r a 0 0 -** - - - - - - - - -** -** Test eraEra00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraEra00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double era00; - - - era00 = eraEra00(2400000.5, 54388.0); - - vvd(era00, 0.4022837240028158102, 1e-12, "eraEra00", "", status); - -} - -static void t_fad03(int *status) -/* -** - - - - - - - - -** t _ f a d 0 3 -** - - - - - - - - -** -** Test eraFad03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFad03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFad03(0.80), 1.946709205396925672, 1e-12, - "eraFad03", "", status); -} - -static void t_fae03(int *status) -/* -** - - - - - - - - -** t _ f a e 0 3 -** - - - - - - - - -** -** Test eraFae03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFae03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFae03(0.80), 1.744713738913081846, 1e-12, - "eraFae03", "", status); -} - -static void t_faf03(int *status) -/* -** - - - - - - - - -** t _ f a f 0 3 -** - - - - - - - - -** -** Test eraFaf03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFaf03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFaf03(0.80), 0.2597711366745499518, 1e-12, - "eraFaf03", "", status); -} - -static void t_faju03(int *status) -/* -** - - - - - - - - - -** t _ f a j u 0 3 -** - - - - - - - - - -** -** Test eraFaju03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFaju03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFaju03(0.80), 5.275711665202481138, 1e-12, - "eraFaju03", "", status); -} - -static void t_fal03(int *status) -/* -** - - - - - - - - -** t _ f a l 0 3 -** - - - - - - - - -** -** Test eraFal03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFal03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFal03(0.80), 5.132369751108684150, 1e-12, - "eraFal03", "", status); -} - -static void t_falp03(int *status) -/* -** - - - - - - - - - -** t _ f a l p 0 3 -** - - - - - - - - - -** -** Test eraFalp03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFalp03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFalp03(0.80), 6.226797973505507345, 1e-12, - "eraFalp03", "", status); -} - -static void t_fama03(int *status) -/* -** - - - - - - - - - -** t _ f a m a 0 3 -** - - - - - - - - - -** -** Test eraFama03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFama03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFama03(0.80), 3.275506840277781492, 1e-12, - "eraFama03", "", status); -} - -static void t_fame03(int *status) -/* -** - - - - - - - - - -** t _ f a m e 0 3 -** - - - - - - - - - -** -** Test eraFame03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFame03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFame03(0.80), 5.417338184297289661, 1e-12, - "eraFame03", "", status); -} - -static void t_fane03(int *status) -/* -** - - - - - - - - - -** t _ f a n e 0 3 -** - - - - - - - - - -** -** Test eraFane03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFane03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFane03(0.80), 2.079343830860413523, 1e-12, - "eraFane03", "", status); -} - -static void t_faom03(int *status) -/* -** - - - - - - - - - -** t _ f a o m 0 3 -** - - - - - - - - - -** -** Test eraFaom03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFaom03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFaom03(0.80), -5.973618440951302183, 1e-12, - "eraFaom03", "", status); -} - -static void t_fapa03(int *status) -/* -** - - - - - - - - - -** t _ f a p a 0 3 -** - - - - - - - - - -** -** Test eraFapa03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFapa03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFapa03(0.80), 0.1950884762240000000e-1, 1e-12, - "eraFapa03", "", status); -} - -static void t_fasa03(int *status) -/* -** - - - - - - - - - -** t _ f a s a 0 3 -** - - - - - - - - - -** -** Test eraFasa03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFasa03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFasa03(0.80), 5.371574539440827046, 1e-12, - "eraFasa03", "", status); -} - -static void t_faur03(int *status) -/* -** - - - - - - - - - -** t _ f a u r 0 3 -** - - - - - - - - - -** -** Test eraFaur03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFaur03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFaur03(0.80), 5.180636450180413523, 1e-12, - "eraFaur03", "", status); -} - -static void t_fave03(int *status) -/* -** - - - - - - - - - -** t _ f a v e 0 3 -** - - - - - - - - - -** -** Test eraFave03 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFave03, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraFave03(0.80), 3.424900460533758000, 1e-12, - "eraFave03", "", status); -} - -static void t_fk52h(int *status) -/* -** - - - - - - - - -** t _ f k 5 2 h -** - - - - - - - - -** -** Test eraFk52h function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFk52h, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r5, d5, dr5, dd5, px5, rv5, rh, dh, drh, ddh, pxh, rvh; - - - r5 = 1.76779433; - d5 = -0.2917517103; - dr5 = -1.91851572e-7; - dd5 = -5.8468475e-6; - px5 = 0.379210; - rv5 = -7.6; - - eraFk52h(r5, d5, dr5, dd5, px5, rv5, - &rh, &dh, &drh, &ddh, &pxh, &rvh); - - vvd(rh, 1.767794226299947632, 1e-14, - "eraFk52h", "ra", status); - vvd(dh, -0.2917516070530391757, 1e-14, - "eraFk52h", "dec", status); - vvd(drh, -0.19618741256057224e-6,1e-19, - "eraFk52h", "dr5", status); - vvd(ddh, -0.58459905176693911e-5, 1e-19, - "eraFk52h", "dd5", status); - vvd(pxh, 0.37921, 1e-14, - "eraFk52h", "px", status); - vvd(rvh, -7.6000000940000254, 1e-11, - "eraFk52h", "rv", status); - -} - -static void t_fk5hip(int *status) -/* -** - - - - - - - - - -** t _ f k 5 h i p -** - - - - - - - - - -** -** Test eraFk5hip function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFk5hip, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r5h[3][3], s5h[3]; - - - eraFk5hip(r5h, s5h); - - vvd(r5h[0][0], 0.9999999999999928638, 1e-14, - "eraFk5hip", "11", status); - vvd(r5h[0][1], 0.1110223351022919694e-6, 1e-17, - "eraFk5hip", "12", status); - vvd(r5h[0][2], 0.4411803962536558154e-7, 1e-17, - "eraFk5hip", "13", status); - vvd(r5h[1][0], -0.1110223308458746430e-6, 1e-17, - "eraFk5hip", "21", status); - vvd(r5h[1][1], 0.9999999999999891830, 1e-14, - "eraFk5hip", "22", status); - vvd(r5h[1][2], -0.9647792498984142358e-7, 1e-17, - "eraFk5hip", "23", status); - vvd(r5h[2][0], -0.4411805033656962252e-7, 1e-17, - "eraFk5hip", "31", status); - vvd(r5h[2][1], 0.9647792009175314354e-7, 1e-17, - "eraFk5hip", "32", status); - vvd(r5h[2][2], 0.9999999999999943728, 1e-14, - "eraFk5hip", "33", status); - vvd(s5h[0], -0.1454441043328607981e-8, 1e-17, - "eraFk5hip", "s1", status); - vvd(s5h[1], 0.2908882086657215962e-8, 1e-17, - "eraFk5hip", "s2", status); - vvd(s5h[2], 0.3393695767766751955e-8, 1e-17, - "eraFk5hip", "s3", status); - -} - -static void t_fk5hz(int *status) -/* -** - - - - - - - - -** t _ f k 5 h z -** - - - - - - - - -** -** Test eraFk5hz function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFk5hz, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r5, d5, rh, dh; - - - r5 = 1.76779433; - d5 = -0.2917517103; - - eraFk5hz(r5, d5, 2400000.5, 54479.0, &rh, &dh); - - vvd(rh, 1.767794191464423978, 1e-12, "eraFk5hz", "ra", status); - vvd(dh, -0.2917516001679884419, 1e-12, "eraFk5hz", "dec", status); - -} - -static void t_fw2m(int *status) -/* -** - - - - - - - -** t _ f w 2 m -** - - - - - - - -** -** Test eraFw2m function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFw2m, vvd -** -** This revision: 2013 August 7 -*/ -{ - double gamb, phib, psi, eps, r[3][3]; - - - gamb = -0.2243387670997992368e-5; - phib = 0.4091014602391312982; - psi = -0.9501954178013015092e-3; - eps = 0.4091014316587367472; - - eraFw2m(gamb, phib, psi, eps, r); - - vvd(r[0][0], 0.9999995505176007047, 1e-12, - "eraFw2m", "11", status); - vvd(r[0][1], 0.8695404617348192957e-3, 1e-12, - "eraFw2m", "12", status); - vvd(r[0][2], 0.3779735201865582571e-3, 1e-12, - "eraFw2m", "13", status); - - vvd(r[1][0], -0.8695404723772016038e-3, 1e-12, - "eraFw2m", "21", status); - vvd(r[1][1], 0.9999996219496027161, 1e-12, - "eraFw2m", "22", status); - vvd(r[1][2], -0.1361752496887100026e-6, 1e-12, - "eraFw2m", "23", status); - - vvd(r[2][0], -0.3779734957034082790e-3, 1e-12, - "eraFw2m", "31", status); - vvd(r[2][1], -0.1924880848087615651e-6, 1e-12, - "eraFw2m", "32", status); - vvd(r[2][2], 0.9999999285679971958, 1e-12, - "eraFw2m", "33", status); - -} - -static void t_fw2xy(int *status) -/* -** - - - - - - - - -** t _ f w 2 x y -** - - - - - - - - -** -** Test eraFw2xy function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraFw2xy, vvd -** -** This revision: 2013 August 7 -*/ -{ - double gamb, phib, psi, eps, x, y; - - - gamb = -0.2243387670997992368e-5; - phib = 0.4091014602391312982; - psi = -0.9501954178013015092e-3; - eps = 0.4091014316587367472; - - eraFw2xy(gamb, phib, psi, eps, &x, &y); - - vvd(x, -0.3779734957034082790e-3, 1e-14, "eraFw2xy", "x", status); - vvd(y, -0.1924880848087615651e-6, 1e-14, "eraFw2xy", "y", status); - -} - -static void t_g2icrs(int *status) -/* -** - - - - - - - - - -** t _ g 2 i c r s -** - - - - - - - - - -** -** Test eraG2icrs function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraG2icrs, vvd -** -** This revision: 2015 January 30 -*/ -{ - double dl, db, dr, dd; - - - dl = 5.5850536063818546461558105; - db = -0.7853981633974483096156608; - eraG2icrs (dl, db, &dr, &dd); - vvd(dr, 5.9338074302227188048671, 1e-14, "eraG2icrs", "R", status); - vvd(dd, -1.1784870613579944551541, 1e-14, "eraG2icrs", "D", status); - } - -static void t_gc2gd(int *status) -/* -** - - - - - - - - -** t _ g c 2 g d -** - - - - - - - - -** -** Test eraGc2gd function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGc2gd, viv, vvd -** -** This revision: 2016 March 12 -*/ -{ - int j; - double xyz[] = {2e6, 3e6, 5.244e6}; - double e, p, h; - - j = eraGc2gd(0, xyz, &e, &p, &h); - - viv(j, -1, "eraGc2gd", "j0", status); - - j = eraGc2gd(ERFA_WGS84, xyz, &e, &p, &h); - - viv(j, 0, "eraGc2gd", "j1", status); - vvd(e, 0.9827937232473290680, 1e-14, "eraGc2gd", "e1", status); - vvd(p, 0.97160184819075459, 1e-14, "eraGc2gd", "p1", status); - vvd(h, 331.4172461426059892, 1e-8, "eraGc2gd", "h1", status); - - j = eraGc2gd(ERFA_GRS80, xyz, &e, &p, &h); - - viv(j, 0, "eraGc2gd", "j2", status); - vvd(e, 0.9827937232473290680, 1e-14, "eraGc2gd", "e2", status); - vvd(p, 0.97160184820607853, 1e-14, "eraGc2gd", "p2", status); - vvd(h, 331.41731754844348, 1e-8, "eraGc2gd", "h2", status); - - j = eraGc2gd(ERFA_WGS72, xyz, &e, &p, &h); - - viv(j, 0, "eraGc2gd", "j3", status); - vvd(e, 0.9827937232473290680, 1e-14, "eraGc2gd", "e3", status); - vvd(p, 0.9716018181101511937, 1e-14, "eraGc2gd", "p3", status); - vvd(h, 333.2770726130318123, 1e-8, "eraGc2gd", "h3", status); - - j = eraGc2gd(4, xyz, &e, &p, &h); - - viv(j, -1, "eraGc2gd", "j4", status); -} - -static void t_gc2gde(int *status) -/* -** - - - - - - - - - -** t _ g c 2 g d e -** - - - - - - - - - -** -** Test eraGc2gde function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGc2gde, viv, vvd -** -** This revision: 2016 March 12 -*/ -{ - int j; - double a = 6378136.0, f = 0.0033528; - double xyz[] = {2e6, 3e6, 5.244e6}; - double e, p, h; - - j = eraGc2gde(a, f, xyz, &e, &p, &h); - - viv(j, 0, "eraGc2gde", "j", status); - vvd(e, 0.9827937232473290680, 1e-14, "eraGc2gde", "e", status); - vvd(p, 0.9716018377570411532, 1e-14, "eraGc2gde", "p", status); - vvd(h, 332.36862495764397, 1e-8, "eraGc2gde", "h", status); -} - -static void t_gd2gc(int *status) -/* -** - - - - - - - - -** t _ g d 2 g c -** - - - - - - - - -** -** Test eraGd2gc function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGd2gc, viv, vvd -** -** This revision: 2016 March 12 -*/ -{ - int j; - double e = 3.1, p = -0.5, h = 2500.0; - double xyz[3]; - - j = eraGd2gc(0, e, p, h, xyz); - - viv(j, -1, "eraGd2gc", "j0", status); - - j = eraGd2gc(ERFA_WGS84, e, p, h, xyz); - - viv(j, 0, "eraGd2gc", "j1", status); - vvd(xyz[0], -5599000.5577049947, 1e-7, "eraGd2gc", "1/1", status); - vvd(xyz[1], 233011.67223479203, 1e-7, "eraGd2gc", "2/1", status); - vvd(xyz[2], -3040909.4706983363, 1e-7, "eraGd2gc", "3/1", status); - - j = eraGd2gc(ERFA_GRS80, e, p, h, xyz); - - viv(j, 0, "eraGd2gc", "j2", status); - vvd(xyz[0], -5599000.5577260984, 1e-7, "eraGd2gc", "1/2", status); - vvd(xyz[1], 233011.6722356702949, 1e-7, "eraGd2gc", "2/2", status); - vvd(xyz[2], -3040909.4706095476, 1e-7, "eraGd2gc", "3/2", status); - - j = eraGd2gc(ERFA_WGS72, e, p, h, xyz); - - viv(j, 0, "eraGd2gc", "j3", status); - vvd(xyz[0], -5598998.7626301490, 1e-7, "eraGd2gc", "1/3", status); - vvd(xyz[1], 233011.5975297822211, 1e-7, "eraGd2gc", "2/3", status); - vvd(xyz[2], -3040908.6861467111, 1e-7, "eraGd2gc", "3/3", status); - - j = eraGd2gc(4, e, p, h, xyz); - - viv(j, -1, "eraGd2gc", "j4", status); -} - -static void t_gd2gce(int *status) -/* -** - - - - - - - - - -** t _ g d 2 g c e -** - - - - - - - - - -** -** Test eraGd2gce function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGd2gce, viv, vvd -** -** This revision: 2016 March 12 -*/ -{ - int j; - double a = 6378136.0, f = 0.0033528; - double e = 3.1, p = -0.5, h = 2500.0; - double xyz[3]; - - j = eraGd2gce(a, f, e, p, h, xyz); - - viv(j, 0, "eraGd2gce", "j", status); - vvd(xyz[0], -5598999.6665116328, 1e-7, "eraGd2gce", "1", status); - vvd(xyz[1], 233011.6351463057189, 1e-7, "eraGd2gce", "2", status); - vvd(xyz[2], -3040909.0517314132, 1e-7, "eraGd2gce", "3", status); -} - -static void t_gmst00(int *status) -/* -** - - - - - - - - - -** t _ g m s t 0 0 -** - - - - - - - - - -** -** Test eraGmst00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGmst00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double theta; - - - theta = eraGmst00(2400000.5, 53736.0, 2400000.5, 53736.0); - - vvd(theta, 1.754174972210740592, 1e-12, "eraGmst00", "", status); - -} - -static void t_gmst06(int *status) -/* -** - - - - - - - - - -** t _ g m s t 0 6 -** - - - - - - - - - -** -** Test eraGmst06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGmst06, vvd -** -** This revision: 2013 August 7 -*/ -{ - double theta; - - - theta = eraGmst06(2400000.5, 53736.0, 2400000.5, 53736.0); - - vvd(theta, 1.754174971870091203, 1e-12, "eraGmst06", "", status); - -} - -static void t_gmst82(int *status) -/* -** - - - - - - - - - -** t _ g m s t 8 2 -** - - - - - - - - - -** -** Test eraGmst82 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGmst82, vvd -** -** This revision: 2013 August 7 -*/ -{ - double theta; - - - theta = eraGmst82(2400000.5, 53736.0); - - vvd(theta, 1.754174981860675096, 1e-12, "eraGmst82", "", status); - -} - -static void t_gst00a(int *status) -/* -** - - - - - - - - - -** t _ g s t 0 0 a -** - - - - - - - - - -** -** Test eraGst00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGst00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double theta; - - - theta = eraGst00a(2400000.5, 53736.0, 2400000.5, 53736.0); - - vvd(theta, 1.754166138018281369, 1e-12, "eraGst00a", "", status); - -} - -static void t_gst00b(int *status) -/* -** - - - - - - - - - -** t _ g s t 0 0 b -** - - - - - - - - - -** -** Test eraGst00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGst00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double theta; - - - theta = eraGst00b(2400000.5, 53736.0); - - vvd(theta, 1.754166136510680589, 1e-12, "eraGst00b", "", status); - -} - -static void t_gst06(int *status) -/* -** - - - - - - - - -** t _ g s t 0 6 -** - - - - - - - - -** -** Test eraGst06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGst06, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rnpb[3][3], theta; - - - rnpb[0][0] = 0.9999989440476103608; - rnpb[0][1] = -0.1332881761240011518e-2; - rnpb[0][2] = -0.5790767434730085097e-3; - - rnpb[1][0] = 0.1332858254308954453e-2; - rnpb[1][1] = 0.9999991109044505944; - rnpb[1][2] = -0.4097782710401555759e-4; - - rnpb[2][0] = 0.5791308472168153320e-3; - rnpb[2][1] = 0.4020595661593994396e-4; - rnpb[2][2] = 0.9999998314954572365; - - theta = eraGst06(2400000.5, 53736.0, 2400000.5, 53736.0, rnpb); - - vvd(theta, 1.754166138018167568, 1e-12, "eraGst06", "", status); - -} - -static void t_gst06a(int *status) -/* -** - - - - - - - - - -** t _ g s t 0 6 a -** - - - - - - - - - -** -** Test eraGst06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGst06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double theta; - - - theta = eraGst06a(2400000.5, 53736.0, 2400000.5, 53736.0); - - vvd(theta, 1.754166137675019159, 1e-12, "eraGst06a", "", status); - -} - -static void t_gst94(int *status) -/* -** - - - - - - - - -** t _ g s t 9 4 -** - - - - - - - - -** -** Test eraGst94 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraGst94, vvd -** -** This revision: 2013 August 7 -*/ -{ - double theta; - - - theta = eraGst94(2400000.5, 53736.0); - - vvd(theta, 1.754166136020645203, 1e-12, "eraGst94", "", status); - -} - -static void t_icrs2g(int *status) -/* -** - - - - - - - - - -** t _ i c r s 2 g -** - - - - - - - - - -** -** Test eraIcrs2g function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraIcrs2g, vvd -** -** This revision: 2015 January 30 -*/ -{ - double dr, dd, dl, db; - - dr = 5.9338074302227188048671087; - dd = -1.1784870613579944551540570; - eraIcrs2g (dr, dd, &dl, &db); - vvd(dl, 5.5850536063818546461558, 1e-14, "eraIcrs2g", "L", status); - vvd(db, -0.7853981633974483096157, 1e-14, "eraIcrs2g", "B", status); - } - -static void t_h2fk5(int *status) -/* -** - - - - - - - - -** t _ h 2 f k 5 -** - - - - - - - - -** -** Test eraH2fk5 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraH2fk5, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rh, dh, drh, ddh, pxh, rvh, r5, d5, dr5, dd5, px5, rv5; - - - rh = 1.767794352; - dh = -0.2917512594; - drh = -2.76413026e-6; - ddh = -5.92994449e-6; - pxh = 0.379210; - rvh = -7.6; - - eraH2fk5(rh, dh, drh, ddh, pxh, rvh, - &r5, &d5, &dr5, &dd5, &px5, &rv5); - - vvd(r5, 1.767794455700065506, 1e-13, - "eraH2fk5", "ra", status); - vvd(d5, -0.2917513626469638890, 1e-13, - "eraH2fk5", "dec", status); - vvd(dr5, -0.27597945024511204e-5, 1e-18, - "eraH2fk5", "dr5", status); - vvd(dd5, -0.59308014093262838e-5, 1e-18, - "eraH2fk5", "dd5", status); - vvd(px5, 0.37921, 1e-13, - "eraH2fk5", "px", status); - vvd(rv5, -7.6000001309071126, 1e-10, - "eraH2fk5", "rv", status); - -} - -static void t_hfk5z(int *status) -/* -** - - - - - - - - -** t _ h f k 5 z -** - - - - - - - - -** -** Test eraHfk5z function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraHfk5z, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rh, dh, r5, d5, dr5, dd5; - - - - rh = 1.767794352; - dh = -0.2917512594; - - eraHfk5z(rh, dh, 2400000.5, 54479.0, &r5, &d5, &dr5, &dd5); - - vvd(r5, 1.767794490535581026, 1e-13, - "eraHfk5z", "ra", status); - vvd(d5, -0.2917513695320114258, 1e-14, - "eraHfk5z", "dec", status); - vvd(dr5, 0.4335890983539243029e-8, 1e-22, - "eraHfk5z", "dr5", status); - vvd(dd5, -0.8569648841237745902e-9, 1e-23, - "eraHfk5z", "dd5", status); - -} - -static void t_ir(int *status) -/* -** - - - - - -** t _ i r -** - - - - - -** -** Test eraIr function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraIr, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r[3][3]; - - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - eraIr(r); - - vvd(r[0][0], 1.0, 0.0, "eraIr", "11", status); - vvd(r[0][1], 0.0, 0.0, "eraIr", "12", status); - vvd(r[0][2], 0.0, 0.0, "eraIr", "13", status); - - vvd(r[1][0], 0.0, 0.0, "eraIr", "21", status); - vvd(r[1][1], 1.0, 0.0, "eraIr", "22", status); - vvd(r[1][2], 0.0, 0.0, "eraIr", "23", status); - - vvd(r[2][0], 0.0, 0.0, "eraIr", "31", status); - vvd(r[2][1], 0.0, 0.0, "eraIr", "32", status); - vvd(r[2][2], 1.0, 0.0, "eraIr", "33", status); - -} - -static void t_jd2cal(int *status) -/* -** - - - - - - - - - -** t _ j d 2 c a l -** - - - - - - - - - -** -** Test eraJd2cal function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraJd2cal, viv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dj1, dj2, fd; - int iy, im, id, j; - - - dj1 = 2400000.5; - dj2 = 50123.9999; - - j = eraJd2cal(dj1, dj2, &iy, &im, &id, &fd); - - viv(iy, 1996, "eraJd2cal", "y", status); - viv(im, 2, "eraJd2cal", "m", status); - viv(id, 10, "eraJd2cal", "d", status); - vvd(fd, 0.9999, 1e-7, "eraJd2cal", "fd", status); - viv(j, 0, "eraJd2cal", "j", status); - -} - -static void t_jdcalf(int *status) -/* -** - - - - - - - - - -** t _ j d c a l f -** - - - - - - - - - -** -** Test eraJdcalf function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraJdcalf, viv -** -** This revision: 2013 August 7 -*/ -{ - double dj1, dj2; - int iydmf[4], j; - - - dj1 = 2400000.5; - dj2 = 50123.9999; - - j = eraJdcalf(4, dj1, dj2, iydmf); - - viv(iydmf[0], 1996, "eraJdcalf", "y", status); - viv(iydmf[1], 2, "eraJdcalf", "m", status); - viv(iydmf[2], 10, "eraJdcalf", "d", status); - viv(iydmf[3], 9999, "eraJdcalf", "f", status); - - viv(j, 0, "eraJdcalf", "j", status); - -} - -static void t_ld(int *status) -/* -** - - - - - -** t _ l d -** - - - - - -** -** Test eraLd function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLd, vvd -* -** This revision: 2013 October 2 -*/ -{ - double bm, p[3], q[3], e[3], em, dlim, p1[3]; - - - bm = 0.00028574; - p[0] = -0.763276255; - p[1] = -0.608633767; - p[2] = -0.216735543; - q[0] = -0.763276255; - q[1] = -0.608633767; - q[2] = -0.216735543; - e[0] = 0.76700421; - e[1] = 0.605629598; - e[2] = 0.211937094; - em = 8.91276983; - dlim = 3e-10; - - eraLd(bm, p, q, e, em, dlim, p1); - - vvd(p1[0], -0.7632762548968159627, 1e-12, - "eraLd", "1", status); - vvd(p1[1], -0.6086337670823762701, 1e-12, - "eraLd", "2", status); - vvd(p1[2], -0.2167355431320546947, 1e-12, - "eraLd", "3", status); - -} - -static void t_ldn(int *status) -/* -** - - - - - - -** t _ l d n -** - - - - - - -** -** Test eraLdn function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLdn, vvd -** -** This revision: 2013 October 2 -*/ -{ - int n; - eraLDBODY b[3]; - double ob[3], sc[3], sn[3]; - - - n = 3; - b[0].bm = 0.00028574; - b[0].dl = 3e-10; - b[0].pv[0][0] = -7.81014427; - b[0].pv[0][1] = -5.60956681; - b[0].pv[0][2] = -1.98079819; - b[0].pv[1][0] = 0.0030723249; - b[0].pv[1][1] = -0.00406995477; - b[0].pv[1][2] = -0.00181335842; - b[1].bm = 0.00095435; - b[1].dl = 3e-9; - b[1].pv[0][0] = 0.738098796; - b[1].pv[0][1] = 4.63658692; - b[1].pv[0][2] = 1.9693136; - b[1].pv[1][0] = -0.00755816922; - b[1].pv[1][1] = 0.00126913722; - b[1].pv[1][2] = 0.000727999001; - b[2].bm = 1.0; - b[2].dl = 6e-6; - b[2].pv[0][0] = -0.000712174377; - b[2].pv[0][1] = -0.00230478303; - b[2].pv[0][2] = -0.00105865966; - b[2].pv[1][0] = 6.29235213e-6; - b[2].pv[1][1] = -3.30888387e-7; - b[2].pv[1][2] = -2.96486623e-7; - ob[0] = -0.974170437; - ob[1] = -0.2115201; - ob[2] = -0.0917583114; - sc[0] = -0.763276255; - sc[1] = -0.608633767; - sc[2] = -0.216735543; - - eraLdn(n, b, ob, sc, sn); - - vvd(sn[0], -0.7632762579693333866, 1e-12, - "eraLdn", "1", status); - vvd(sn[1], -0.6086337636093002660, 1e-12, - "eraLdn", "2", status); - vvd(sn[2], -0.2167355420646328159, 1e-12, - "eraLdn", "3", status); - -} - -static void t_ldsun(int *status) -/* -** - - - - - - - - -** t _ l d s u n -** - - - - - - - - -** -** Test eraLdsun function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLdsun, vvd -** -** This revision: 2013 October 2 -*/ -{ - double p[3], e[3], em, p1[3]; - - - p[0] = -0.763276255; - p[1] = -0.608633767; - p[2] = -0.216735543; - e[0] = -0.973644023; - e[1] = -0.20925523; - e[2] = -0.0907169552; - em = 0.999809214; - - eraLdsun(p, e, em, p1); - - vvd(p1[0], -0.7632762580731413169, 1e-12, - "eraLdsun", "1", status); - vvd(p1[1], -0.6086337635262647900, 1e-12, - "eraLdsun", "2", status); - vvd(p1[2], -0.2167355419322321302, 1e-12, - "eraLdsun", "3", status); - -} - -static void t_lteceq(int *status) -/* -** - - - - - - - - - -** t _ l t e c e q -** - - - - - - - - - -** -** Test eraLteceq function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLteceq, vvd -** -** This revision: 2016 March 12 -*/ -{ - double epj, dl, db, dr, dd; - - - epj = 2500.0; - dl = 1.5; - db = 0.6; - - eraLteceq(epj, dl, db, &dr, &dd); - - vvd(dr, 1.275156021861921167, 1e-14, "eraLteceq", "dr", status); - vvd(dd, 0.9966573543519204791, 1e-14, "eraLteceq", "dd", status); - -} - -static void t_ltecm(int *status) -/* -** - - - - - - - - -** t _ l t e c m -** - - - - - - - - -** -** Test eraLtecm function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLtecm, vvd -** -** This revision: 2016 March 12 -*/ -{ - double epj, rm[3][3]; - - - epj = -3000.0; - - eraLtecm(epj, rm); - - vvd(rm[0][0], 0.3564105644859788825, 1e-14, - "eraLtecm", "rm11", status); - vvd(rm[0][1], 0.8530575738617682284, 1e-14, - "eraLtecm", "rm12", status); - vvd(rm[0][2], 0.3811355207795060435, 1e-14, - "eraLtecm", "rm13", status); - vvd(rm[1][0], -0.9343283469640709942, 1e-14, - "eraLtecm", "rm21", status); - vvd(rm[1][1], 0.3247830597681745976, 1e-14, - "eraLtecm", "rm22", status); - vvd(rm[1][2], 0.1467872751535940865, 1e-14, - "eraLtecm", "rm23", status); - vvd(rm[2][0], 0.1431636191201167793e-2, 1e-14, - "eraLtecm", "rm31", status); - vvd(rm[2][1], -0.4084222566960599342, 1e-14, - "eraLtecm", "rm32", status); - vvd(rm[2][2], 0.9127919865189030899, 1e-14, - "eraLtecm", "rm33", status); - -} - -static void t_lteqec(int *status) -/* -** - - - - - - - - - -** t _ l t e q e c -** - - - - - - - - - -** -** Test eraLteqec function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLteqec, vvd -** -** This revision: 2016 March 12 -*/ -{ - double epj, dr, dd, dl, db; - - - epj = -1500.0; - dr = 1.234; - dd = 0.987; - - eraLteqec(epj, dr, dd, &dl, &db); - - vvd(dl, 0.5039483649047114859, 1e-14, "eraLteqec", "dl", status); - vvd(db, 0.5848534459726224882, 1e-14, "eraLteqec", "db", status); - -} - -static void t_ltp(int *status) -/* -** - - - - - - -** t _ l t p -** - - - - - - -** -** Test eraLtp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLtp, vvd -** -** This revision: 2016 March 12 -*/ -{ - double epj, rp[3][3]; - - - epj = 1666.666; - - eraLtp(epj, rp); - - vvd(rp[0][0], 0.9967044141159213819, 1e-14, - "eraLtp", "rp11", status); - vvd(rp[0][1], 0.7437801893193210840e-1, 1e-14, - "eraLtp", "rp12", status); - vvd(rp[0][2], 0.3237624409345603401e-1, 1e-14, - "eraLtp", "rp13", status); - vvd(rp[1][0], -0.7437802731819618167e-1, 1e-14, - "eraLtp", "rp21", status); - vvd(rp[1][1], 0.9972293894454533070, 1e-14, - "eraLtp", "rp22", status); - vvd(rp[1][2], -0.1205768842723593346e-2, 1e-14, - "eraLtp", "rp23", status); - vvd(rp[2][0], -0.3237622482766575399e-1, 1e-14, - "eraLtp", "rp31", status); - vvd(rp[2][1], -0.1206286039697609008e-2, 1e-14, - "eraLtp", "rp32", status); - vvd(rp[2][2], 0.9994750246704010914, 1e-14, - "eraLtp", "rp33", status); - -} - -static void t_ltpb(int *status) -/* -** - - - - - - - -** t _ l t p b -** - - - - - - - -** -** Test eraLtpb function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLtpb, vvd -** -** This revision: 2016 March 12 -*/ -{ - double epj, rpb[3][3]; - - - epj = 1666.666; - - eraLtpb(epj, rpb); - - vvd(rpb[0][0], 0.9967044167723271851, 1e-14, - "eraLtpb", "rpb11", status); - vvd(rpb[0][1], 0.7437794731203340345e-1, 1e-14, - "eraLtpb", "rpb12", status); - vvd(rpb[0][2], 0.3237632684841625547e-1, 1e-14, - "eraLtpb", "rpb13", status); - vvd(rpb[1][0], -0.7437795663437177152e-1, 1e-14, - "eraLtpb", "rpb21", status); - vvd(rpb[1][1], 0.9972293947500013666, 1e-14, - "eraLtpb", "rpb22", status); - vvd(rpb[1][2], -0.1205741865911243235e-2, 1e-14, - "eraLtpb", "rpb23", status); - vvd(rpb[2][0], -0.3237630543224664992e-1, 1e-14, - "eraLtpb", "rpb31", status); - vvd(rpb[2][1], -0.1206316791076485295e-2, 1e-14, - "eraLtpb", "rpb32", status); - vvd(rpb[2][2], 0.9994750220222438819, 1e-14, - "eraLtpb", "rpb33", status); - -} - -static void t_ltpecl(int *status) -/* -** - - - - - - - - - -** t _ l t p e c l -** - - - - - - - - - -** -** Test eraLtpecl function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLtpecl, vvd -** -** This revision: 2016 March 12 -*/ -{ - double epj, vec[3]; - - - epj = -1500.0; - - eraLtpecl(epj, vec); - - vvd(vec[0], 0.4768625676477096525e-3, 1e-14, - "eraLtpecl", "vec1", status); - vvd(vec[1], -0.4052259533091875112, 1e-14, - "eraLtpecl", "vec2", status); - vvd(vec[2], 0.9142164401096448012, 1e-14, - "eraLtpecl", "vec3", status); - -} - -static void t_ltpequ(int *status) -/* -** - - - - - - - - - -** t _ l t p e q u -** - - - - - - - - - -** -** Test eraLtpequ function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraLtpequ, vvd -** -** This revision: 2016 March 12 -*/ -{ - double epj, veq[3]; - - - epj = -2500.0; - - eraLtpequ(epj, veq); - - vvd(veq[0], -0.3586652560237326659, 1e-14, - "eraLtpequ", "veq1", status); - vvd(veq[1], -0.1996978910771128475, 1e-14, - "eraLtpequ", "veq2", status); - vvd(veq[2], 0.9118552442250819624, 1e-14, - "eraLtpequ", "veq3", status); - -} - -static void t_num00a(int *status) -/* -** - - - - - - - - - -** t _ n u m 0 0 a -** - - - - - - - - - -** -** Test eraNum00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraNum00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rmatn[3][3]; - - - eraNum00a(2400000.5, 53736.0, rmatn); - - vvd(rmatn[0][0], 0.9999999999536227949, 1e-12, - "eraNum00a", "11", status); - vvd(rmatn[0][1], 0.8836238544090873336e-5, 1e-12, - "eraNum00a", "12", status); - vvd(rmatn[0][2], 0.3830835237722400669e-5, 1e-12, - "eraNum00a", "13", status); - - vvd(rmatn[1][0], -0.8836082880798569274e-5, 1e-12, - "eraNum00a", "21", status); - vvd(rmatn[1][1], 0.9999999991354655028, 1e-12, - "eraNum00a", "22", status); - vvd(rmatn[1][2], -0.4063240865362499850e-4, 1e-12, - "eraNum00a", "23", status); - - vvd(rmatn[2][0], -0.3831194272065995866e-5, 1e-12, - "eraNum00a", "31", status); - vvd(rmatn[2][1], 0.4063237480216291775e-4, 1e-12, - "eraNum00a", "32", status); - vvd(rmatn[2][2], 0.9999999991671660338, 1e-12, - "eraNum00a", "33", status); - -} - -static void t_num00b(int *status) -/* -** - - - - - - - - - -** t _ n u m 0 0 b -** - - - - - - - - - -** -** Test eraNum00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraNum00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rmatn[3][3]; - - eraNum00b(2400000.5, 53736, rmatn); - - vvd(rmatn[0][0], 0.9999999999536069682, 1e-12, - "eraNum00b", "11", status); - vvd(rmatn[0][1], 0.8837746144871248011e-5, 1e-12, - "eraNum00b", "12", status); - vvd(rmatn[0][2], 0.3831488838252202945e-5, 1e-12, - "eraNum00b", "13", status); - - vvd(rmatn[1][0], -0.8837590456632304720e-5, 1e-12, - "eraNum00b", "21", status); - vvd(rmatn[1][1], 0.9999999991354692733, 1e-12, - "eraNum00b", "22", status); - vvd(rmatn[1][2], -0.4063198798559591654e-4, 1e-12, - "eraNum00b", "23", status); - - vvd(rmatn[2][0], -0.3831847930134941271e-5, 1e-12, - "eraNum00b", "31", status); - vvd(rmatn[2][1], 0.4063195412258168380e-4, 1e-12, - "eraNum00b", "32", status); - vvd(rmatn[2][2], 0.9999999991671806225, 1e-12, - "eraNum00b", "33", status); - -} - -static void t_num06a(int *status) -/* -** - - - - - - - - - -** t _ n u m 0 6 a -** - - - - - - - - - -** -** Test eraNum06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraNum06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rmatn[3][3]; - - eraNum06a(2400000.5, 53736, rmatn); - - vvd(rmatn[0][0], 0.9999999999536227668, 1e-12, - "eraNum06a", "11", status); - vvd(rmatn[0][1], 0.8836241998111535233e-5, 1e-12, - "eraNum06a", "12", status); - vvd(rmatn[0][2], 0.3830834608415287707e-5, 1e-12, - "eraNum06a", "13", status); - - vvd(rmatn[1][0], -0.8836086334870740138e-5, 1e-12, - "eraNum06a", "21", status); - vvd(rmatn[1][1], 0.9999999991354657474, 1e-12, - "eraNum06a", "22", status); - vvd(rmatn[1][2], -0.4063240188248455065e-4, 1e-12, - "eraNum06a", "23", status); - - vvd(rmatn[2][0], -0.3831193642839398128e-5, 1e-12, - "eraNum06a", "31", status); - vvd(rmatn[2][1], 0.4063236803101479770e-4, 1e-12, - "eraNum06a", "32", status); - vvd(rmatn[2][2], 0.9999999991671663114, 1e-12, - "eraNum06a", "33", status); - -} - -static void t_numat(int *status) -/* -** - - - - - - - - -** t _ n u m a t -** - - - - - - - - -** -** Test eraNumat function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraNumat, vvd -** -** This revision: 2013 August 7 -*/ -{ - double epsa, dpsi, deps, rmatn[3][3]; - - - epsa = 0.4090789763356509900; - dpsi = -0.9630909107115582393e-5; - deps = 0.4063239174001678826e-4; - - eraNumat(epsa, dpsi, deps, rmatn); - - vvd(rmatn[0][0], 0.9999999999536227949, 1e-12, - "eraNumat", "11", status); - vvd(rmatn[0][1], 0.8836239320236250577e-5, 1e-12, - "eraNumat", "12", status); - vvd(rmatn[0][2], 0.3830833447458251908e-5, 1e-12, - "eraNumat", "13", status); - - vvd(rmatn[1][0], -0.8836083657016688588e-5, 1e-12, - "eraNumat", "21", status); - vvd(rmatn[1][1], 0.9999999991354654959, 1e-12, - "eraNumat", "22", status); - vvd(rmatn[1][2], -0.4063240865361857698e-4, 1e-12, - "eraNumat", "23", status); - - vvd(rmatn[2][0], -0.3831192481833385226e-5, 1e-12, - "eraNumat", "31", status); - vvd(rmatn[2][1], 0.4063237480216934159e-4, 1e-12, - "eraNumat", "32", status); - vvd(rmatn[2][2], 0.9999999991671660407, 1e-12, - "eraNumat", "33", status); - -} - -static void t_nut00a(int *status) -/* -** - - - - - - - - - -** t _ n u t 0 0 a -** - - - - - - - - - -** -** Test eraNut00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraNut00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsi, deps; - - - eraNut00a(2400000.5, 53736.0, &dpsi, &deps); - - vvd(dpsi, -0.9630909107115518431e-5, 1e-13, - "eraNut00a", "dpsi", status); - vvd(deps, 0.4063239174001678710e-4, 1e-13, - "eraNut00a", "deps", status); - -} - -static void t_nut00b(int *status) -/* -** - - - - - - - - - -** t _ n u t 0 0 b -** - - - - - - - - - -** -** Test eraNut00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraNut00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsi, deps; - - - eraNut00b(2400000.5, 53736.0, &dpsi, &deps); - - vvd(dpsi, -0.9632552291148362783e-5, 1e-13, - "eraNut00b", "dpsi", status); - vvd(deps, 0.4063197106621159367e-4, 1e-13, - "eraNut00b", "deps", status); - -} - -static void t_nut06a(int *status) -/* -** - - - - - - - - - -** t _ n u t 0 6 a -** - - - - - - - - - -** -** Test eraNut06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraNut06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsi, deps; - - - eraNut06a(2400000.5, 53736.0, &dpsi, &deps); - - vvd(dpsi, -0.9630912025820308797e-5, 1e-13, - "eraNut06a", "dpsi", status); - vvd(deps, 0.4063238496887249798e-4, 1e-13, - "eraNut06a", "deps", status); - -} - -static void t_nut80(int *status) -/* -** - - - - - - - - -** t _ n u t 8 0 -** - - - - - - - - -** -** Test eraNut80 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraNut80, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsi, deps; - - - eraNut80(2400000.5, 53736.0, &dpsi, &deps); - - vvd(dpsi, -0.9643658353226563966e-5, 1e-13, - "eraNut80", "dpsi", status); - vvd(deps, 0.4060051006879713322e-4, 1e-13, - "eraNut80", "deps", status); - -} - -static void t_nutm80(int *status) -/* -** - - - - - - - - - -** t _ n u t m 8 0 -** - - - - - - - - - -** -** Test eraNutm80 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraNutm80, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rmatn[3][3]; - - - eraNutm80(2400000.5, 53736.0, rmatn); - - vvd(rmatn[0][0], 0.9999999999534999268, 1e-12, - "eraNutm80", "11", status); - vvd(rmatn[0][1], 0.8847935789636432161e-5, 1e-12, - "eraNutm80", "12", status); - vvd(rmatn[0][2], 0.3835906502164019142e-5, 1e-12, - "eraNutm80", "13", status); - - vvd(rmatn[1][0], -0.8847780042583435924e-5, 1e-12, - "eraNutm80", "21", status); - vvd(rmatn[1][1], 0.9999999991366569963, 1e-12, - "eraNutm80", "22", status); - vvd(rmatn[1][2], -0.4060052702727130809e-4, 1e-12, - "eraNutm80", "23", status); - - vvd(rmatn[2][0], -0.3836265729708478796e-5, 1e-12, - "eraNutm80", "31", status); - vvd(rmatn[2][1], 0.4060049308612638555e-4, 1e-12, - "eraNutm80", "32", status); - vvd(rmatn[2][2], 0.9999999991684415129, 1e-12, - "eraNutm80", "33", status); - -} - -static void t_obl06(int *status) -/* -** - - - - - - - - -** t _ o b l 0 6 -** - - - - - - - - -** -** Test eraObl06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraObl06, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraObl06(2400000.5, 54388.0), 0.4090749229387258204, 1e-14, - "eraObl06", "", status); -} - -static void t_obl80(int *status) -/* -** - - - - - - - - -** t _ o b l 8 0 -** - - - - - - - - -** -** Test eraObl80 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraObl80, vvd -** -** This revision: 2013 August 7 -*/ -{ - double eps0; - - - eps0 = eraObl80(2400000.5, 54388.0); - - vvd(eps0, 0.4090751347643816218, 1e-14, "eraObl80", "", status); - -} - -static void t_p06e(int *status) -/* -** - - - - - - - -** t _ p 0 6 e -** - - - - - - - -** -** Test eraP06e function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraP06e, vvd -** -** This revision: 2013 August 7 -*/ -{ - double eps0, psia, oma, bpa, bqa, pia, bpia, - epsa, chia, za, zetaa, thetaa, pa, gam, phi, psi; - - - eraP06e(2400000.5, 52541.0, &eps0, &psia, &oma, &bpa, - &bqa, &pia, &bpia, &epsa, &chia, &za, - &zetaa, &thetaa, &pa, &gam, &phi, &psi); - - vvd(eps0, 0.4090926006005828715, 1e-14, - "eraP06e", "eps0", status); - vvd(psia, 0.6664369630191613431e-3, 1e-14, - "eraP06e", "psia", status); - vvd(oma , 0.4090925973783255982, 1e-14, - "eraP06e", "oma", status); - vvd(bpa, 0.5561149371265209445e-6, 1e-14, - "eraP06e", "bpa", status); - vvd(bqa, -0.6191517193290621270e-5, 1e-14, - "eraP06e", "bqa", status); - vvd(pia, 0.6216441751884382923e-5, 1e-14, - "eraP06e", "pia", status); - vvd(bpia, 3.052014180023779882, 1e-14, - "eraP06e", "bpia", status); - vvd(epsa, 0.4090864054922431688, 1e-14, - "eraP06e", "epsa", status); - vvd(chia, 0.1387703379530915364e-5, 1e-14, - "eraP06e", "chia", status); - vvd(za, 0.2921789846651790546e-3, 1e-14, - "eraP06e", "za", status); - vvd(zetaa, 0.3178773290332009310e-3, 1e-14, - "eraP06e", "zetaa", status); - vvd(thetaa, 0.2650932701657497181e-3, 1e-14, - "eraP06e", "thetaa", status); - vvd(pa, 0.6651637681381016344e-3, 1e-14, - "eraP06e", "pa", status); - vvd(gam, 0.1398077115963754987e-5, 1e-14, - "eraP06e", "gam", status); - vvd(phi, 0.4090864090837462602, 1e-14, - "eraP06e", "phi", status); - vvd(psi, 0.6664464807480920325e-3, 1e-14, - "eraP06e", "psi", status); - -} - -static void t_p2pv(int *status) -/* -** - - - - - - - -** t _ p 2 p v -** - - - - - - - -** -** Test eraP2pv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraP2pv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double p[3], pv[2][3]; - - - p[0] = 0.25; - p[1] = 1.2; - p[2] = 3.0; - - pv[0][0] = 0.3; - pv[0][1] = 1.2; - pv[0][2] = -2.5; - - pv[1][0] = -0.5; - pv[1][1] = 3.1; - pv[1][2] = 0.9; - - eraP2pv(p, pv); - - vvd(pv[0][0], 0.25, 0.0, "eraP2pv", "p1", status); - vvd(pv[0][1], 1.2, 0.0, "eraP2pv", "p2", status); - vvd(pv[0][2], 3.0, 0.0, "eraP2pv", "p3", status); - - vvd(pv[1][0], 0.0, 0.0, "eraP2pv", "v1", status); - vvd(pv[1][1], 0.0, 0.0, "eraP2pv", "v2", status); - vvd(pv[1][2], 0.0, 0.0, "eraP2pv", "v3", status); - -} - -static void t_p2s(int *status) -/* -** - - - - - - -** t _ p 2 s -** - - - - - - -** -** Test eraP2s function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraP2s, vvd -** -** This revision: 2013 August 7 -*/ -{ - double p[3], theta, phi, r; - - - p[0] = 100.0; - p[1] = -50.0; - p[2] = 25.0; - - eraP2s(p, &theta, &phi, &r); - - vvd(theta, -0.4636476090008061162, 1e-12, "eraP2s", "theta", status); - vvd(phi, 0.2199879773954594463, 1e-12, "eraP2s", "phi", status); - vvd(r, 114.5643923738960002, 1e-9, "eraP2s", "r", status); - -} - -static void t_pap(int *status) -/* -** - - - - - - -** t _ p a p -** - - - - - - -** -** Test eraPap function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPap, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[3], b[3], theta; - - - a[0] = 1.0; - a[1] = 0.1; - a[2] = 0.2; - - b[0] = -3.0; - b[1] = 1e-3; - b[2] = 0.2; - - theta = eraPap(a, b); - - vvd(theta, 0.3671514267841113674, 1e-12, "eraPap", "", status); - -} - -static void t_pas(int *status) -/* -** - - - - - - -** t _ p a s -** - - - - - - -** -** Test eraPas function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPas, vvd -** -** This revision: 2013 August 7 -*/ -{ - double al, ap, bl, bp, theta; - - - al = 1.0; - ap = 0.1; - bl = 0.2; - bp = -1.0; - - theta = eraPas(al, ap, bl, bp); - - vvd(theta, -2.724544922932270424, 1e-12, "eraPas", "", status); - -} - -static void t_pb06(int *status) -/* -** - - - - - - - -** t _ p b 0 6 -** - - - - - - - -** -** Test eraPb06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPb06, vvd -** -** This revision: 2013 August 7 -*/ -{ - double bzeta, bz, btheta; - - - eraPb06(2400000.5, 50123.9999, &bzeta, &bz, &btheta); - - vvd(bzeta, -0.5092634016326478238e-3, 1e-12, - "eraPb06", "bzeta", status); - vvd(bz, -0.3602772060566044413e-3, 1e-12, - "eraPb06", "bz", status); - vvd(btheta, -0.3779735537167811177e-3, 1e-12, - "eraPb06", "btheta", status); - -} - -static void t_pdp(int *status) -/* -** - - - - - - -** t _ p d p -** - - - - - - -** -** Test eraPdp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPdp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[3], b[3], adb; - - - a[0] = 2.0; - a[1] = 2.0; - a[2] = 3.0; - - b[0] = 1.0; - b[1] = 3.0; - b[2] = 4.0; - - adb = eraPdp(a, b); - - vvd(adb, 20, 1e-12, "eraPdp", "", status); - -} - -static void t_pfw06(int *status) -/* -** - - - - - - - - -** t _ p f w 0 6 -** - - - - - - - - -** -** Test eraPfw06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPfw06, vvd -** -** This revision: 2013 August 7 -*/ -{ - double gamb, phib, psib, epsa; - - - eraPfw06(2400000.5, 50123.9999, &gamb, &phib, &psib, &epsa); - - vvd(gamb, -0.2243387670997995690e-5, 1e-16, - "eraPfw06", "gamb", status); - vvd(phib, 0.4091014602391312808, 1e-12, - "eraPfw06", "phib", status); - vvd(psib, -0.9501954178013031895e-3, 1e-14, - "eraPfw06", "psib", status); - vvd(epsa, 0.4091014316587367491, 1e-12, - "eraPfw06", "epsa", status); - -} - -static void t_plan94(int *status) -/* -** - - - - - - - - - -** t _ p l a n 9 4 -** - - - - - - - - - -** -** Test eraPlan94 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPlan94, vvd, viv -** -** This revision: 2013 October 2 -*/ -{ - double pv[2][3]; - int j; - - - j = eraPlan94(2400000.5, 1e6, 0, pv); - - vvd(pv[0][0], 0.0, 0.0, "eraPlan94", "x 1", status); - vvd(pv[0][1], 0.0, 0.0, "eraPlan94", "y 1", status); - vvd(pv[0][2], 0.0, 0.0, "eraPlan94", "z 1", status); - - vvd(pv[1][0], 0.0, 0.0, "eraPlan94", "xd 1", status); - vvd(pv[1][1], 0.0, 0.0, "eraPlan94", "yd 1", status); - vvd(pv[1][2], 0.0, 0.0, "eraPlan94", "zd 1", status); - - viv(j, -1, "eraPlan94", "j 1", status); - - j = eraPlan94(2400000.5, 1e6, 10, pv); - - viv(j, -1, "eraPlan94", "j 2", status); - - j = eraPlan94(2400000.5, -320000, 3, pv); - - vvd(pv[0][0], 0.9308038666832975759, 1e-11, - "eraPlan94", "x 3", status); - vvd(pv[0][1], 0.3258319040261346000, 1e-11, - "eraPlan94", "y 3", status); - vvd(pv[0][2], 0.1422794544481140560, 1e-11, - "eraPlan94", "z 3", status); - - vvd(pv[1][0], -0.6429458958255170006e-2, 1e-11, - "eraPlan94", "xd 3", status); - vvd(pv[1][1], 0.1468570657704237764e-1, 1e-11, - "eraPlan94", "yd 3", status); - vvd(pv[1][2], 0.6406996426270981189e-2, 1e-11, - "eraPlan94", "zd 3", status); - - viv(j, 1, "eraPlan94", "j 3", status); - - j = eraPlan94(2400000.5, 43999.9, 1, pv); - - vvd(pv[0][0], 0.2945293959257430832, 1e-11, - "eraPlan94", "x 4", status); - vvd(pv[0][1], -0.2452204176601049596, 1e-11, - "eraPlan94", "y 4", status); - vvd(pv[0][2], -0.1615427700571978153, 1e-11, - "eraPlan94", "z 4", status); - - vvd(pv[1][0], 0.1413867871404614441e-1, 1e-11, - "eraPlan94", "xd 4", status); - vvd(pv[1][1], 0.1946548301104706582e-1, 1e-11, - "eraPlan94", "yd 4", status); - vvd(pv[1][2], 0.8929809783898904786e-2, 1e-11, - "eraPlan94", "zd 4", status); - - viv(j, 0, "eraPlan94", "j 4", status); - -} - -static void t_pmat00(int *status) -/* -** - - - - - - - - - -** t _ p m a t 0 0 -** - - - - - - - - - -** -** Test eraPmat00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPmat00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rbp[3][3]; - - - eraPmat00(2400000.5, 50123.9999, rbp); - - vvd(rbp[0][0], 0.9999995505175087260, 1e-12, - "eraPmat00", "11", status); - vvd(rbp[0][1], 0.8695405883617884705e-3, 1e-14, - "eraPmat00", "12", status); - vvd(rbp[0][2], 0.3779734722239007105e-3, 1e-14, - "eraPmat00", "13", status); - - vvd(rbp[1][0], -0.8695405990410863719e-3, 1e-14, - "eraPmat00", "21", status); - vvd(rbp[1][1], 0.9999996219494925900, 1e-12, - "eraPmat00", "22", status); - vvd(rbp[1][2], -0.1360775820404982209e-6, 1e-14, - "eraPmat00", "23", status); - - vvd(rbp[2][0], -0.3779734476558184991e-3, 1e-14, - "eraPmat00", "31", status); - vvd(rbp[2][1], -0.1925857585832024058e-6, 1e-14, - "eraPmat00", "32", status); - vvd(rbp[2][2], 0.9999999285680153377, 1e-12, - "eraPmat00", "33", status); - -} - -static void t_pmat06(int *status) -/* -** - - - - - - - - - -** t _ p m a t 0 6 -** - - - - - - - - - -** -** Test eraPmat06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPmat06, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rbp[3][3]; - - - eraPmat06(2400000.5, 50123.9999, rbp); - - vvd(rbp[0][0], 0.9999995505176007047, 1e-12, - "eraPmat06", "11", status); - vvd(rbp[0][1], 0.8695404617348208406e-3, 1e-14, - "eraPmat06", "12", status); - vvd(rbp[0][2], 0.3779735201865589104e-3, 1e-14, - "eraPmat06", "13", status); - - vvd(rbp[1][0], -0.8695404723772031414e-3, 1e-14, - "eraPmat06", "21", status); - vvd(rbp[1][1], 0.9999996219496027161, 1e-12, - "eraPmat06", "22", status); - vvd(rbp[1][2], -0.1361752497080270143e-6, 1e-14, - "eraPmat06", "23", status); - - vvd(rbp[2][0], -0.3779734957034089490e-3, 1e-14, - "eraPmat06", "31", status); - vvd(rbp[2][1], -0.1924880847894457113e-6, 1e-14, - "eraPmat06", "32", status); - vvd(rbp[2][2], 0.9999999285679971958, 1e-12, - "eraPmat06", "33", status); - -} - -static void t_pmat76(int *status) -/* -** - - - - - - - - - -** t _ p m a t 7 6 -** - - - - - - - - - -** -** Test eraPmat76 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPmat76, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rmatp[3][3]; - - - eraPmat76(2400000.5, 50123.9999, rmatp); - - vvd(rmatp[0][0], 0.9999995504328350733, 1e-12, - "eraPmat76", "11", status); - vvd(rmatp[0][1], 0.8696632209480960785e-3, 1e-14, - "eraPmat76", "12", status); - vvd(rmatp[0][2], 0.3779153474959888345e-3, 1e-14, - "eraPmat76", "13", status); - - vvd(rmatp[1][0], -0.8696632209485112192e-3, 1e-14, - "eraPmat76", "21", status); - vvd(rmatp[1][1], 0.9999996218428560614, 1e-12, - "eraPmat76", "22", status); - vvd(rmatp[1][2], -0.1643284776111886407e-6, 1e-14, - "eraPmat76", "23", status); - - vvd(rmatp[2][0], -0.3779153474950335077e-3, 1e-14, - "eraPmat76", "31", status); - vvd(rmatp[2][1], -0.1643306746147366896e-6, 1e-14, - "eraPmat76", "32", status); - vvd(rmatp[2][2], 0.9999999285899790119, 1e-12, - "eraPmat76", "33", status); - -} - -static void t_pm(int *status) -/* -** - - - - - -** t _ p m -** - - - - - -** -** Test eraPm function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPm, vvd -** -** This revision: 2013 August 7 -*/ -{ - double p[3], r; - - - p[0] = 0.3; - p[1] = 1.2; - p[2] = -2.5; - - r = eraPm(p); - - vvd(r, 2.789265136196270604, 1e-12, "eraPm", "", status); - -} - -static void t_pmp(int *status) -/* -** - - - - - - -** t _ p m p -** - - - - - - -** -** Test eraPmp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPmp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[3], b[3], amb[3]; - - - a[0] = 2.0; - a[1] = 2.0; - a[2] = 3.0; - - b[0] = 1.0; - b[1] = 3.0; - b[2] = 4.0; - - eraPmp(a, b, amb); - - vvd(amb[0], 1.0, 1e-12, "eraPmp", "0", status); - vvd(amb[1], -1.0, 1e-12, "eraPmp", "1", status); - vvd(amb[2], -1.0, 1e-12, "eraPmp", "2", status); - -} - -static void t_pmpx(int *status) -/* -** - - - - - - - -** t _ p m p x -** - - - - - - - -** -** Test eraPmpx function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPmpx, vvd -** -** This revision: 2013 October 2 -*/ -{ - double rc, dc, pr, pd, px, rv, pmt, pob[3], pco[3]; - - - rc = 1.234; - dc = 0.789; - pr = 1e-5; - pd = -2e-5; - px = 1e-2; - rv = 10.0; - pmt = 8.75; - pob[0] = 0.9; - pob[1] = 0.4; - pob[2] = 0.1; - - eraPmpx(rc, dc, pr, pd, px, rv, pmt, pob, pco); - - vvd(pco[0], 0.2328137623960308440, 1e-12, - "eraPmpx", "1", status); - vvd(pco[1], 0.6651097085397855317, 1e-12, - "eraPmpx", "2", status); - vvd(pco[2], 0.7095257765896359847, 1e-12, - "eraPmpx", "3", status); - -} - -static void t_pmsafe(int *status) -/* -** - - - - - - - - - -** t _ p m s a f e -** - - - - - - - - - -** -** Test eraPmsafe function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPmsafe, vvd, viv -** -** This revision: 2013 October 2 -*/ -{ - int j; - double ra1, dec1, pmr1, pmd1, px1, rv1, ep1a, ep1b, ep2a, ep2b, - ra2, dec2, pmr2, pmd2, px2, rv2; - - - ra1 = 1.234; - dec1 = 0.789; - pmr1 = 1e-5; - pmd1 = -2e-5; - px1 = 1e-2; - rv1 = 10.0; - ep1a = 2400000.5; - ep1b = 48348.5625; - ep2a = 2400000.5; - ep2b = 51544.5; - - j = eraPmsafe(ra1, dec1, pmr1, pmd1, px1, rv1, - ep1a, ep1b, ep2a, ep2b, - &ra2, &dec2, &pmr2, &pmd2, &px2, &rv2); - - vvd(ra2, 1.234087484501017061, 1e-12, - "eraPmsafe", "ra2", status); - vvd(dec2, 0.7888249982450468574, 1e-12, - "eraPmsafe", "dec2", status); - vvd(pmr2, 0.9996457663586073988e-5, 1e-12, - "eraPmsafe", "pmr2", status); - vvd(pmd2, -0.2000040085106737816e-4, 1e-16, - "eraPmsafe", "pmd2", status); - vvd(px2, 0.9999997295356765185e-2, 1e-12, - "eraPmsafe", "px2", status); - vvd(rv2, 10.38468380113917014, 1e-10, - "eraPmsafe", "rv2", status); - viv ( j, 0, "eraPmsafe", "j", status); - -} - -static void t_pn(int *status) -/* -** - - - - - -** t _ p n -** - - - - - -** -** Test eraPn function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPn, vvd -** -** This revision: 2013 August 7 -*/ -{ - double p[3], r, u[3]; - - - p[0] = 0.3; - p[1] = 1.2; - p[2] = -2.5; - - eraPn(p, &r, u); - - vvd(r, 2.789265136196270604, 1e-12, "eraPn", "r", status); - - vvd(u[0], 0.1075552109073112058, 1e-12, "eraPn", "u1", status); - vvd(u[1], 0.4302208436292448232, 1e-12, "eraPn", "u2", status); - vvd(u[2], -0.8962934242275933816, 1e-12, "eraPn", "u3", status); - -} - -static void t_pn00(int *status) -/* -** - - - - - - - -** t _ p n 0 0 -** - - - - - - - -** -** Test eraPn00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPn00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsi, deps, epsa, - rb[3][3], rp[3][3], rbp[3][3], rn[3][3], rbpn[3][3]; - - - dpsi = -0.9632552291149335877e-5; - deps = 0.4063197106621141414e-4; - - eraPn00(2400000.5, 53736.0, dpsi, deps, - &epsa, rb, rp, rbp, rn, rbpn); - - vvd(epsa, 0.4090791789404229916, 1e-12, "eraPn00", "epsa", status); - - vvd(rb[0][0], 0.9999999999999942498, 1e-12, - "eraPn00", "rb11", status); - vvd(rb[0][1], -0.7078279744199196626e-7, 1e-18, - "eraPn00", "rb12", status); - vvd(rb[0][2], 0.8056217146976134152e-7, 1e-18, - "eraPn00", "rb13", status); - - vvd(rb[1][0], 0.7078279477857337206e-7, 1e-18, - "eraPn00", "rb21", status); - vvd(rb[1][1], 0.9999999999999969484, 1e-12, - "eraPn00", "rb22", status); - vvd(rb[1][2], 0.3306041454222136517e-7, 1e-18, - "eraPn00", "rb23", status); - - vvd(rb[2][0], -0.8056217380986972157e-7, 1e-18, - "eraPn00", "rb31", status); - vvd(rb[2][1], -0.3306040883980552500e-7, 1e-18, - "eraPn00", "rb32", status); - vvd(rb[2][2], 0.9999999999999962084, 1e-12, - "eraPn00", "rb33", status); - - vvd(rp[0][0], 0.9999989300532289018, 1e-12, - "eraPn00", "rp11", status); - vvd(rp[0][1], -0.1341647226791824349e-2, 1e-14, - "eraPn00", "rp12", status); - vvd(rp[0][2], -0.5829880927190296547e-3, 1e-14, - "eraPn00", "rp13", status); - - vvd(rp[1][0], 0.1341647231069759008e-2, 1e-14, - "eraPn00", "rp21", status); - vvd(rp[1][1], 0.9999990999908750433, 1e-12, - "eraPn00", "rp22", status); - vvd(rp[1][2], -0.3837444441583715468e-6, 1e-14, - "eraPn00", "rp23", status); - - vvd(rp[2][0], 0.5829880828740957684e-3, 1e-14, - "eraPn00", "rp31", status); - vvd(rp[2][1], -0.3984203267708834759e-6, 1e-14, - "eraPn00", "rp32", status); - vvd(rp[2][2], 0.9999998300623538046, 1e-12, - "eraPn00", "rp33", status); - - vvd(rbp[0][0], 0.9999989300052243993, 1e-12, - "eraPn00", "rbp11", status); - vvd(rbp[0][1], -0.1341717990239703727e-2, 1e-14, - "eraPn00", "rbp12", status); - vvd(rbp[0][2], -0.5829075749891684053e-3, 1e-14, - "eraPn00", "rbp13", status); - - vvd(rbp[1][0], 0.1341718013831739992e-2, 1e-14, - "eraPn00", "rbp21", status); - vvd(rbp[1][1], 0.9999990998959191343, 1e-12, - "eraPn00", "rbp22", status); - vvd(rbp[1][2], -0.3505759733565421170e-6, 1e-14, - "eraPn00", "rbp23", status); - - vvd(rbp[2][0], 0.5829075206857717883e-3, 1e-14, - "eraPn00", "rbp31", status); - vvd(rbp[2][1], -0.4315219955198608970e-6, 1e-14, - "eraPn00", "rbp32", status); - vvd(rbp[2][2], 0.9999998301093036269, 1e-12, - "eraPn00", "rbp33", status); - - vvd(rn[0][0], 0.9999999999536069682, 1e-12, - "eraPn00", "rn11", status); - vvd(rn[0][1], 0.8837746144872140812e-5, 1e-16, - "eraPn00", "rn12", status); - vvd(rn[0][2], 0.3831488838252590008e-5, 1e-16, - "eraPn00", "rn13", status); - - vvd(rn[1][0], -0.8837590456633197506e-5, 1e-16, - "eraPn00", "rn21", status); - vvd(rn[1][1], 0.9999999991354692733, 1e-12, - "eraPn00", "rn22", status); - vvd(rn[1][2], -0.4063198798559573702e-4, 1e-16, - "eraPn00", "rn23", status); - - vvd(rn[2][0], -0.3831847930135328368e-5, 1e-16, - "eraPn00", "rn31", status); - vvd(rn[2][1], 0.4063195412258150427e-4, 1e-16, - "eraPn00", "rn32", status); - vvd(rn[2][2], 0.9999999991671806225, 1e-12, - "eraPn00", "rn33", status); - - vvd(rbpn[0][0], 0.9999989440499982806, 1e-12, - "eraPn00", "rbpn11", status); - vvd(rbpn[0][1], -0.1332880253640848301e-2, 1e-14, - "eraPn00", "rbpn12", status); - vvd(rbpn[0][2], -0.5790760898731087295e-3, 1e-14, - "eraPn00", "rbpn13", status); - - vvd(rbpn[1][0], 0.1332856746979948745e-2, 1e-14, - "eraPn00", "rbpn21", status); - vvd(rbpn[1][1], 0.9999991109064768883, 1e-12, - "eraPn00", "rbpn22", status); - vvd(rbpn[1][2], -0.4097740555723063806e-4, 1e-14, - "eraPn00", "rbpn23", status); - - vvd(rbpn[2][0], 0.5791301929950205000e-3, 1e-14, - "eraPn00", "rbpn31", status); - vvd(rbpn[2][1], 0.4020553681373702931e-4, 1e-14, - "eraPn00", "rbpn32", status); - vvd(rbpn[2][2], 0.9999998314958529887, 1e-12, - "eraPn00", "rbpn33", status); - -} - -static void t_pn00a(int *status) -/* -** - - - - - - - - -** t _ p n 0 0 a -** - - - - - - - - -** -** Test eraPn00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPn00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsi, deps, epsa, - rb[3][3], rp[3][3], rbp[3][3], rn[3][3], rbpn[3][3]; - - - eraPn00a(2400000.5, 53736.0, - &dpsi, &deps, &epsa, rb, rp, rbp, rn, rbpn); - - vvd(dpsi, -0.9630909107115518431e-5, 1e-12, - "eraPn00a", "dpsi", status); - vvd(deps, 0.4063239174001678710e-4, 1e-12, - "eraPn00a", "deps", status); - vvd(epsa, 0.4090791789404229916, 1e-12, "eraPn00a", "epsa", status); - - vvd(rb[0][0], 0.9999999999999942498, 1e-12, - "eraPn00a", "rb11", status); - vvd(rb[0][1], -0.7078279744199196626e-7, 1e-16, - "eraPn00a", "rb12", status); - vvd(rb[0][2], 0.8056217146976134152e-7, 1e-16, - "eraPn00a", "rb13", status); - - vvd(rb[1][0], 0.7078279477857337206e-7, 1e-16, - "eraPn00a", "rb21", status); - vvd(rb[1][1], 0.9999999999999969484, 1e-12, - "eraPn00a", "rb22", status); - vvd(rb[1][2], 0.3306041454222136517e-7, 1e-16, - "eraPn00a", "rb23", status); - - vvd(rb[2][0], -0.8056217380986972157e-7, 1e-16, - "eraPn00a", "rb31", status); - vvd(rb[2][1], -0.3306040883980552500e-7, 1e-16, - "eraPn00a", "rb32", status); - vvd(rb[2][2], 0.9999999999999962084, 1e-12, - "eraPn00a", "rb33", status); - - vvd(rp[0][0], 0.9999989300532289018, 1e-12, - "eraPn00a", "rp11", status); - vvd(rp[0][1], -0.1341647226791824349e-2, 1e-14, - "eraPn00a", "rp12", status); - vvd(rp[0][2], -0.5829880927190296547e-3, 1e-14, - "eraPn00a", "rp13", status); - - vvd(rp[1][0], 0.1341647231069759008e-2, 1e-14, - "eraPn00a", "rp21", status); - vvd(rp[1][1], 0.9999990999908750433, 1e-12, - "eraPn00a", "rp22", status); - vvd(rp[1][2], -0.3837444441583715468e-6, 1e-14, - "eraPn00a", "rp23", status); - - vvd(rp[2][0], 0.5829880828740957684e-3, 1e-14, - "eraPn00a", "rp31", status); - vvd(rp[2][1], -0.3984203267708834759e-6, 1e-14, - "eraPn00a", "rp32", status); - vvd(rp[2][2], 0.9999998300623538046, 1e-12, - "eraPn00a", "rp33", status); - - vvd(rbp[0][0], 0.9999989300052243993, 1e-12, - "eraPn00a", "rbp11", status); - vvd(rbp[0][1], -0.1341717990239703727e-2, 1e-14, - "eraPn00a", "rbp12", status); - vvd(rbp[0][2], -0.5829075749891684053e-3, 1e-14, - "eraPn00a", "rbp13", status); - - vvd(rbp[1][0], 0.1341718013831739992e-2, 1e-14, - "eraPn00a", "rbp21", status); - vvd(rbp[1][1], 0.9999990998959191343, 1e-12, - "eraPn00a", "rbp22", status); - vvd(rbp[1][2], -0.3505759733565421170e-6, 1e-14, - "eraPn00a", "rbp23", status); - - vvd(rbp[2][0], 0.5829075206857717883e-3, 1e-14, - "eraPn00a", "rbp31", status); - vvd(rbp[2][1], -0.4315219955198608970e-6, 1e-14, - "eraPn00a", "rbp32", status); - vvd(rbp[2][2], 0.9999998301093036269, 1e-12, - "eraPn00a", "rbp33", status); - - vvd(rn[0][0], 0.9999999999536227949, 1e-12, - "eraPn00a", "rn11", status); - vvd(rn[0][1], 0.8836238544090873336e-5, 1e-14, - "eraPn00a", "rn12", status); - vvd(rn[0][2], 0.3830835237722400669e-5, 1e-14, - "eraPn00a", "rn13", status); - - vvd(rn[1][0], -0.8836082880798569274e-5, 1e-14, - "eraPn00a", "rn21", status); - vvd(rn[1][1], 0.9999999991354655028, 1e-12, - "eraPn00a", "rn22", status); - vvd(rn[1][2], -0.4063240865362499850e-4, 1e-14, - "eraPn00a", "rn23", status); - - vvd(rn[2][0], -0.3831194272065995866e-5, 1e-14, - "eraPn00a", "rn31", status); - vvd(rn[2][1], 0.4063237480216291775e-4, 1e-14, - "eraPn00a", "rn32", status); - vvd(rn[2][2], 0.9999999991671660338, 1e-12, - "eraPn00a", "rn33", status); - - vvd(rbpn[0][0], 0.9999989440476103435, 1e-12, - "eraPn00a", "rbpn11", status); - vvd(rbpn[0][1], -0.1332881761240011763e-2, 1e-14, - "eraPn00a", "rbpn12", status); - vvd(rbpn[0][2], -0.5790767434730085751e-3, 1e-14, - "eraPn00a", "rbpn13", status); - - vvd(rbpn[1][0], 0.1332858254308954658e-2, 1e-14, - "eraPn00a", "rbpn21", status); - vvd(rbpn[1][1], 0.9999991109044505577, 1e-12, - "eraPn00a", "rbpn22", status); - vvd(rbpn[1][2], -0.4097782710396580452e-4, 1e-14, - "eraPn00a", "rbpn23", status); - - vvd(rbpn[2][0], 0.5791308472168152904e-3, 1e-14, - "eraPn00a", "rbpn31", status); - vvd(rbpn[2][1], 0.4020595661591500259e-4, 1e-14, - "eraPn00a", "rbpn32", status); - vvd(rbpn[2][2], 0.9999998314954572304, 1e-12, - "eraPn00a", "rbpn33", status); - -} - -static void t_pn00b(int *status) -/* -** - - - - - - - - -** t _ p n 0 0 b -** - - - - - - - - -** -** Test eraPn00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPn00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsi, deps, epsa, - rb[3][3], rp[3][3], rbp[3][3], rn[3][3], rbpn[3][3]; - - - eraPn00b(2400000.5, 53736.0, &dpsi, &deps, &epsa, - rb, rp, rbp, rn, rbpn); - - vvd(dpsi, -0.9632552291148362783e-5, 1e-12, - "eraPn00b", "dpsi", status); - vvd(deps, 0.4063197106621159367e-4, 1e-12, - "eraPn00b", "deps", status); - vvd(epsa, 0.4090791789404229916, 1e-12, "eraPn00b", "epsa", status); - - vvd(rb[0][0], 0.9999999999999942498, 1e-12, - "eraPn00b", "rb11", status); - vvd(rb[0][1], -0.7078279744199196626e-7, 1e-16, - "eraPn00b", "rb12", status); - vvd(rb[0][2], 0.8056217146976134152e-7, 1e-16, - "eraPn00b", "rb13", status); - - vvd(rb[1][0], 0.7078279477857337206e-7, 1e-16, - "eraPn00b", "rb21", status); - vvd(rb[1][1], 0.9999999999999969484, 1e-12, - "eraPn00b", "rb22", status); - vvd(rb[1][2], 0.3306041454222136517e-7, 1e-16, - "eraPn00b", "rb23", status); - - vvd(rb[2][0], -0.8056217380986972157e-7, 1e-16, - "eraPn00b", "rb31", status); - vvd(rb[2][1], -0.3306040883980552500e-7, 1e-16, - "eraPn00b", "rb32", status); - vvd(rb[2][2], 0.9999999999999962084, 1e-12, - "eraPn00b", "rb33", status); - - vvd(rp[0][0], 0.9999989300532289018, 1e-12, - "eraPn00b", "rp11", status); - vvd(rp[0][1], -0.1341647226791824349e-2, 1e-14, - "eraPn00b", "rp12", status); - vvd(rp[0][2], -0.5829880927190296547e-3, 1e-14, - "eraPn00b", "rp13", status); - - vvd(rp[1][0], 0.1341647231069759008e-2, 1e-14, - "eraPn00b", "rp21", status); - vvd(rp[1][1], 0.9999990999908750433, 1e-12, - "eraPn00b", "rp22", status); - vvd(rp[1][2], -0.3837444441583715468e-6, 1e-14, - "eraPn00b", "rp23", status); - - vvd(rp[2][0], 0.5829880828740957684e-3, 1e-14, - "eraPn00b", "rp31", status); - vvd(rp[2][1], -0.3984203267708834759e-6, 1e-14, - "eraPn00b", "rp32", status); - vvd(rp[2][2], 0.9999998300623538046, 1e-12, - "eraPn00b", "rp33", status); - - vvd(rbp[0][0], 0.9999989300052243993, 1e-12, - "eraPn00b", "rbp11", status); - vvd(rbp[0][1], -0.1341717990239703727e-2, 1e-14, - "eraPn00b", "rbp12", status); - vvd(rbp[0][2], -0.5829075749891684053e-3, 1e-14, - "eraPn00b", "rbp13", status); - - vvd(rbp[1][0], 0.1341718013831739992e-2, 1e-14, - "eraPn00b", "rbp21", status); - vvd(rbp[1][1], 0.9999990998959191343, 1e-12, - "eraPn00b", "rbp22", status); - vvd(rbp[1][2], -0.3505759733565421170e-6, 1e-14, - "eraPn00b", "rbp23", status); - - vvd(rbp[2][0], 0.5829075206857717883e-3, 1e-14, - "eraPn00b", "rbp31", status); - vvd(rbp[2][1], -0.4315219955198608970e-6, 1e-14, - "eraPn00b", "rbp32", status); - vvd(rbp[2][2], 0.9999998301093036269, 1e-12, - "eraPn00b", "rbp33", status); - - vvd(rn[0][0], 0.9999999999536069682, 1e-12, - "eraPn00b", "rn11", status); - vvd(rn[0][1], 0.8837746144871248011e-5, 1e-14, - "eraPn00b", "rn12", status); - vvd(rn[0][2], 0.3831488838252202945e-5, 1e-14, - "eraPn00b", "rn13", status); - - vvd(rn[1][0], -0.8837590456632304720e-5, 1e-14, - "eraPn00b", "rn21", status); - vvd(rn[1][1], 0.9999999991354692733, 1e-12, - "eraPn00b", "rn22", status); - vvd(rn[1][2], -0.4063198798559591654e-4, 1e-14, - "eraPn00b", "rn23", status); - - vvd(rn[2][0], -0.3831847930134941271e-5, 1e-14, - "eraPn00b", "rn31", status); - vvd(rn[2][1], 0.4063195412258168380e-4, 1e-14, - "eraPn00b", "rn32", status); - vvd(rn[2][2], 0.9999999991671806225, 1e-12, - "eraPn00b", "rn33", status); - - vvd(rbpn[0][0], 0.9999989440499982806, 1e-12, - "eraPn00b", "rbpn11", status); - vvd(rbpn[0][1], -0.1332880253640849194e-2, 1e-14, - "eraPn00b", "rbpn12", status); - vvd(rbpn[0][2], -0.5790760898731091166e-3, 1e-14, - "eraPn00b", "rbpn13", status); - - vvd(rbpn[1][0], 0.1332856746979949638e-2, 1e-14, - "eraPn00b", "rbpn21", status); - vvd(rbpn[1][1], 0.9999991109064768883, 1e-12, - "eraPn00b", "rbpn22", status); - vvd(rbpn[1][2], -0.4097740555723081811e-4, 1e-14, - "eraPn00b", "rbpn23", status); - - vvd(rbpn[2][0], 0.5791301929950208873e-3, 1e-14, - "eraPn00b", "rbpn31", status); - vvd(rbpn[2][1], 0.4020553681373720832e-4, 1e-14, - "eraPn00b", "rbpn32", status); - vvd(rbpn[2][2], 0.9999998314958529887, 1e-12, - "eraPn00b", "rbpn33", status); - -} - -static void t_pn06a(int *status) -/* -** - - - - - - - - -** t _ p n 0 6 a -** - - - - - - - - -** -** Test eraPn06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPn06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsi, deps, epsa; - double rb[3][3], rp[3][3], rbp[3][3], rn[3][3], rbpn[3][3]; - - - eraPn06a(2400000.5, 53736.0, &dpsi, &deps, &epsa, - rb, rp, rbp, rn, rbpn); - - vvd(dpsi, -0.9630912025820308797e-5, 1e-12, - "eraPn06a", "dpsi", status); - vvd(deps, 0.4063238496887249798e-4, 1e-12, - "eraPn06a", "deps", status); - vvd(epsa, 0.4090789763356509926, 1e-12, "eraPn06a", "epsa", status); - - vvd(rb[0][0], 0.9999999999999942497, 1e-12, - "eraPn06a", "rb11", status); - vvd(rb[0][1], -0.7078368960971557145e-7, 1e-14, - "eraPn06a", "rb12", status); - vvd(rb[0][2], 0.8056213977613185606e-7, 1e-14, - "eraPn06a", "rb13", status); - - vvd(rb[1][0], 0.7078368694637674333e-7, 1e-14, - "eraPn06a", "rb21", status); - vvd(rb[1][1], 0.9999999999999969484, 1e-12, - "eraPn06a", "rb22", status); - vvd(rb[1][2], 0.3305943742989134124e-7, 1e-14, - "eraPn06a", "rb23", status); - - vvd(rb[2][0], -0.8056214211620056792e-7, 1e-14, - "eraPn06a", "rb31", status); - vvd(rb[2][1], -0.3305943172740586950e-7, 1e-14, - "eraPn06a", "rb32", status); - vvd(rb[2][2], 0.9999999999999962084, 1e-12, - "eraPn06a", "rb33", status); - - vvd(rp[0][0], 0.9999989300536854831, 1e-12, - "eraPn06a", "rp11", status); - vvd(rp[0][1], -0.1341646886204443795e-2, 1e-14, - "eraPn06a", "rp12", status); - vvd(rp[0][2], -0.5829880933488627759e-3, 1e-14, - "eraPn06a", "rp13", status); - - vvd(rp[1][0], 0.1341646890569782183e-2, 1e-14, - "eraPn06a", "rp21", status); - vvd(rp[1][1], 0.9999990999913319321, 1e-12, - "eraPn06a", "rp22", status); - vvd(rp[1][2], -0.3835944216374477457e-6, 1e-14, - "eraPn06a", "rp23", status); - - vvd(rp[2][0], 0.5829880833027867368e-3, 1e-14, - "eraPn06a", "rp31", status); - vvd(rp[2][1], -0.3985701514686976112e-6, 1e-14, - "eraPn06a", "rp32", status); - vvd(rp[2][2], 0.9999998300623534950, 1e-12, - "eraPn06a", "rp33", status); - - vvd(rbp[0][0], 0.9999989300056797893, 1e-12, - "eraPn06a", "rbp11", status); - vvd(rbp[0][1], -0.1341717650545059598e-2, 1e-14, - "eraPn06a", "rbp12", status); - vvd(rbp[0][2], -0.5829075756493728856e-3, 1e-14, - "eraPn06a", "rbp13", status); - - vvd(rbp[1][0], 0.1341717674223918101e-2, 1e-14, - "eraPn06a", "rbp21", status); - vvd(rbp[1][1], 0.9999990998963748448, 1e-12, - "eraPn06a", "rbp22", status); - vvd(rbp[1][2], -0.3504269280170069029e-6, 1e-14, - "eraPn06a", "rbp23", status); - - vvd(rbp[2][0], 0.5829075211461454599e-3, 1e-14, - "eraPn06a", "rbp31", status); - vvd(rbp[2][1], -0.4316708436255949093e-6, 1e-14, - "eraPn06a", "rbp32", status); - vvd(rbp[2][2], 0.9999998301093032943, 1e-12, - "eraPn06a", "rbp33", status); - - vvd(rn[0][0], 0.9999999999536227668, 1e-12, - "eraPn06a", "rn11", status); - vvd(rn[0][1], 0.8836241998111535233e-5, 1e-14, - "eraPn06a", "rn12", status); - vvd(rn[0][2], 0.3830834608415287707e-5, 1e-14, - "eraPn06a", "rn13", status); - - vvd(rn[1][0], -0.8836086334870740138e-5, 1e-14, - "eraPn06a", "rn21", status); - vvd(rn[1][1], 0.9999999991354657474, 1e-12, - "eraPn06a", "rn22", status); - vvd(rn[1][2], -0.4063240188248455065e-4, 1e-14, - "eraPn06a", "rn23", status); - - vvd(rn[2][0], -0.3831193642839398128e-5, 1e-14, - "eraPn06a", "rn31", status); - vvd(rn[2][1], 0.4063236803101479770e-4, 1e-14, - "eraPn06a", "rn32", status); - vvd(rn[2][2], 0.9999999991671663114, 1e-12, - "eraPn06a", "rn33", status); - - vvd(rbpn[0][0], 0.9999989440480669738, 1e-12, - "eraPn06a", "rbpn11", status); - vvd(rbpn[0][1], -0.1332881418091915973e-2, 1e-14, - "eraPn06a", "rbpn12", status); - vvd(rbpn[0][2], -0.5790767447612042565e-3, 1e-14, - "eraPn06a", "rbpn13", status); - - vvd(rbpn[1][0], 0.1332857911250989133e-2, 1e-14, - "eraPn06a", "rbpn21", status); - vvd(rbpn[1][1], 0.9999991109049141908, 1e-12, - "eraPn06a", "rbpn22", status); - vvd(rbpn[1][2], -0.4097767128546784878e-4, 1e-14, - "eraPn06a", "rbpn23", status); - - vvd(rbpn[2][0], 0.5791308482835292617e-3, 1e-14, - "eraPn06a", "rbpn31", status); - vvd(rbpn[2][1], 0.4020580099454020310e-4, 1e-14, - "eraPn06a", "rbpn32", status); - vvd(rbpn[2][2], 0.9999998314954628695, 1e-12, - "eraPn06a", "rbpn33", status); - -} - -static void t_pn06(int *status) -/* -** - - - - - - - -** t _ p n 0 6 -** - - - - - - - -** -** Test eraPn06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPn06, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsi, deps, epsa, - rb[3][3], rp[3][3], rbp[3][3], rn[3][3], rbpn[3][3]; - - - dpsi = -0.9632552291149335877e-5; - deps = 0.4063197106621141414e-4; - - eraPn06(2400000.5, 53736.0, dpsi, deps, - &epsa, rb, rp, rbp, rn, rbpn); - - vvd(epsa, 0.4090789763356509926, 1e-12, "eraPn06", "epsa", status); - - vvd(rb[0][0], 0.9999999999999942497, 1e-12, - "eraPn06", "rb11", status); - vvd(rb[0][1], -0.7078368960971557145e-7, 1e-14, - "eraPn06", "rb12", status); - vvd(rb[0][2], 0.8056213977613185606e-7, 1e-14, - "eraPn06", "rb13", status); - - vvd(rb[1][0], 0.7078368694637674333e-7, 1e-14, - "eraPn06", "rb21", status); - vvd(rb[1][1], 0.9999999999999969484, 1e-12, - "eraPn06", "rb22", status); - vvd(rb[1][2], 0.3305943742989134124e-7, 1e-14, - "eraPn06", "rb23", status); - - vvd(rb[2][0], -0.8056214211620056792e-7, 1e-14, - "eraPn06", "rb31", status); - vvd(rb[2][1], -0.3305943172740586950e-7, 1e-14, - "eraPn06", "rb32", status); - vvd(rb[2][2], 0.9999999999999962084, 1e-12, - "eraPn06", "rb33", status); - - vvd(rp[0][0], 0.9999989300536854831, 1e-12, - "eraPn06", "rp11", status); - vvd(rp[0][1], -0.1341646886204443795e-2, 1e-14, - "eraPn06", "rp12", status); - vvd(rp[0][2], -0.5829880933488627759e-3, 1e-14, - "eraPn06", "rp13", status); - - vvd(rp[1][0], 0.1341646890569782183e-2, 1e-14, - "eraPn06", "rp21", status); - vvd(rp[1][1], 0.9999990999913319321, 1e-12, - "eraPn06", "rp22", status); - vvd(rp[1][2], -0.3835944216374477457e-6, 1e-14, - "eraPn06", "rp23", status); - - vvd(rp[2][0], 0.5829880833027867368e-3, 1e-14, - "eraPn06", "rp31", status); - vvd(rp[2][1], -0.3985701514686976112e-6, 1e-14, - "eraPn06", "rp32", status); - vvd(rp[2][2], 0.9999998300623534950, 1e-12, - "eraPn06", "rp33", status); - - vvd(rbp[0][0], 0.9999989300056797893, 1e-12, - "eraPn06", "rbp11", status); - vvd(rbp[0][1], -0.1341717650545059598e-2, 1e-14, - "eraPn06", "rbp12", status); - vvd(rbp[0][2], -0.5829075756493728856e-3, 1e-14, - "eraPn06", "rbp13", status); - - vvd(rbp[1][0], 0.1341717674223918101e-2, 1e-14, - "eraPn06", "rbp21", status); - vvd(rbp[1][1], 0.9999990998963748448, 1e-12, - "eraPn06", "rbp22", status); - vvd(rbp[1][2], -0.3504269280170069029e-6, 1e-14, - "eraPn06", "rbp23", status); - - vvd(rbp[2][0], 0.5829075211461454599e-3, 1e-14, - "eraPn06", "rbp31", status); - vvd(rbp[2][1], -0.4316708436255949093e-6, 1e-14, - "eraPn06", "rbp32", status); - vvd(rbp[2][2], 0.9999998301093032943, 1e-12, - "eraPn06", "rbp33", status); - - vvd(rn[0][0], 0.9999999999536069682, 1e-12, - "eraPn06", "rn11", status); - vvd(rn[0][1], 0.8837746921149881914e-5, 1e-14, - "eraPn06", "rn12", status); - vvd(rn[0][2], 0.3831487047682968703e-5, 1e-14, - "eraPn06", "rn13", status); - - vvd(rn[1][0], -0.8837591232983692340e-5, 1e-14, - "eraPn06", "rn21", status); - vvd(rn[1][1], 0.9999999991354692664, 1e-12, - "eraPn06", "rn22", status); - vvd(rn[1][2], -0.4063198798558931215e-4, 1e-14, - "eraPn06", "rn23", status); - - vvd(rn[2][0], -0.3831846139597250235e-5, 1e-14, - "eraPn06", "rn31", status); - vvd(rn[2][1], 0.4063195412258792914e-4, 1e-14, - "eraPn06", "rn32", status); - vvd(rn[2][2], 0.9999999991671806293, 1e-12, - "eraPn06", "rn33", status); - - vvd(rbpn[0][0], 0.9999989440504506688, 1e-12, - "eraPn06", "rbpn11", status); - vvd(rbpn[0][1], -0.1332879913170492655e-2, 1e-14, - "eraPn06", "rbpn12", status); - vvd(rbpn[0][2], -0.5790760923225655753e-3, 1e-14, - "eraPn06", "rbpn13", status); - - vvd(rbpn[1][0], 0.1332856406595754748e-2, 1e-14, - "eraPn06", "rbpn21", status); - vvd(rbpn[1][1], 0.9999991109069366795, 1e-12, - "eraPn06", "rbpn22", status); - vvd(rbpn[1][2], -0.4097725651142641812e-4, 1e-14, - "eraPn06", "rbpn23", status); - - vvd(rbpn[2][0], 0.5791301952321296716e-3, 1e-14, - "eraPn06", "rbpn31", status); - vvd(rbpn[2][1], 0.4020538796195230577e-4, 1e-14, - "eraPn06", "rbpn32", status); - vvd(rbpn[2][2], 0.9999998314958576778, 1e-12, - "eraPn06", "rbpn33", status); - -} - -static void t_pnm00a(int *status) -/* -** - - - - - - - - - -** t _ p n m 0 0 a -** - - - - - - - - - -** -** Test eraPnm00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPnm00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rbpn[3][3]; - - - eraPnm00a(2400000.5, 50123.9999, rbpn); - - vvd(rbpn[0][0], 0.9999995832793134257, 1e-12, - "eraPnm00a", "11", status); - vvd(rbpn[0][1], 0.8372384254137809439e-3, 1e-14, - "eraPnm00a", "12", status); - vvd(rbpn[0][2], 0.3639684306407150645e-3, 1e-14, - "eraPnm00a", "13", status); - - vvd(rbpn[1][0], -0.8372535226570394543e-3, 1e-14, - "eraPnm00a", "21", status); - vvd(rbpn[1][1], 0.9999996486491582471, 1e-12, - "eraPnm00a", "22", status); - vvd(rbpn[1][2], 0.4132915262664072381e-4, 1e-14, - "eraPnm00a", "23", status); - - vvd(rbpn[2][0], -0.3639337004054317729e-3, 1e-14, - "eraPnm00a", "31", status); - vvd(rbpn[2][1], -0.4163386925461775873e-4, 1e-14, - "eraPnm00a", "32", status); - vvd(rbpn[2][2], 0.9999999329094390695, 1e-12, - "eraPnm00a", "33", status); - -} - -static void t_pnm00b(int *status) -/* -** - - - - - - - - - -** t _ p n m 0 0 b -** - - - - - - - - - -** -** Test eraPnm00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPnm00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rbpn[3][3]; - - - eraPnm00b(2400000.5, 50123.9999, rbpn); - - vvd(rbpn[0][0], 0.9999995832776208280, 1e-12, - "eraPnm00b", "11", status); - vvd(rbpn[0][1], 0.8372401264429654837e-3, 1e-14, - "eraPnm00b", "12", status); - vvd(rbpn[0][2], 0.3639691681450271771e-3, 1e-14, - "eraPnm00b", "13", status); - - vvd(rbpn[1][0], -0.8372552234147137424e-3, 1e-14, - "eraPnm00b", "21", status); - vvd(rbpn[1][1], 0.9999996486477686123, 1e-12, - "eraPnm00b", "22", status); - vvd(rbpn[1][2], 0.4132832190946052890e-4, 1e-14, - "eraPnm00b", "23", status); - - vvd(rbpn[2][0], -0.3639344385341866407e-3, 1e-14, - "eraPnm00b", "31", status); - vvd(rbpn[2][1], -0.4163303977421522785e-4, 1e-14, - "eraPnm00b", "32", status); - vvd(rbpn[2][2], 0.9999999329092049734, 1e-12, - "eraPnm00b", "33", status); - -} - -static void t_pnm06a(int *status) -/* -** - - - - - - - - - -** t _ p n m 0 6 a -** - - - - - - - - - -** -** Test eraPnm06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPnm06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rbpn[3][3]; - - - eraPnm06a(2400000.5, 50123.9999, rbpn); - - vvd(rbpn[0][0], 0.9999995832794205484, 1e-12, - "eraPnm06a", "11", status); - vvd(rbpn[0][1], 0.8372382772630962111e-3, 1e-14, - "eraPnm06a", "12", status); - vvd(rbpn[0][2], 0.3639684771140623099e-3, 1e-14, - "eraPnm06a", "13", status); - - vvd(rbpn[1][0], -0.8372533744743683605e-3, 1e-14, - "eraPnm06a", "21", status); - vvd(rbpn[1][1], 0.9999996486492861646, 1e-12, - "eraPnm06a", "22", status); - vvd(rbpn[1][2], 0.4132905944611019498e-4, 1e-14, - "eraPnm06a", "23", status); - - vvd(rbpn[2][0], -0.3639337469629464969e-3, 1e-14, - "eraPnm06a", "31", status); - vvd(rbpn[2][1], -0.4163377605910663999e-4, 1e-14, - "eraPnm06a", "32", status); - vvd(rbpn[2][2], 0.9999999329094260057, 1e-12, - "eraPnm06a", "33", status); - -} - -static void t_pnm80(int *status) -/* -** - - - - - - - - -** t _ p n m 8 0 -** - - - - - - - - -** -** Test eraPnm80 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPnm80, vvd -** -** This revision: 2013 August 7 -*/ -{ - double rmatpn[3][3]; - - - eraPnm80(2400000.5, 50123.9999, rmatpn); - - vvd(rmatpn[0][0], 0.9999995831934611169, 1e-12, - "eraPnm80", "11", status); - vvd(rmatpn[0][1], 0.8373654045728124011e-3, 1e-14, - "eraPnm80", "12", status); - vvd(rmatpn[0][2], 0.3639121916933106191e-3, 1e-14, - "eraPnm80", "13", status); - - vvd(rmatpn[1][0], -0.8373804896118301316e-3, 1e-14, - "eraPnm80", "21", status); - vvd(rmatpn[1][1], 0.9999996485439674092, 1e-12, - "eraPnm80", "22", status); - vvd(rmatpn[1][2], 0.4130202510421549752e-4, 1e-14, - "eraPnm80", "23", status); - - vvd(rmatpn[2][0], -0.3638774789072144473e-3, 1e-14, - "eraPnm80", "31", status); - vvd(rmatpn[2][1], -0.4160674085851722359e-4, 1e-14, - "eraPnm80", "32", status); - vvd(rmatpn[2][2], 0.9999999329310274805, 1e-12, - "eraPnm80", "33", status); - -} - -static void t_pom00(int *status) -/* -** - - - - - - - - -** t _ p o m 0 0 -** - - - - - - - - -** -** Test eraPom00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPom00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double xp, yp, sp, rpom[3][3]; - - - xp = 2.55060238e-7; - yp = 1.860359247e-6; - sp = -0.1367174580728891460e-10; - - eraPom00(xp, yp, sp, rpom); - - vvd(rpom[0][0], 0.9999999999999674721, 1e-12, - "eraPom00", "11", status); - vvd(rpom[0][1], -0.1367174580728846989e-10, 1e-16, - "eraPom00", "12", status); - vvd(rpom[0][2], 0.2550602379999972345e-6, 1e-16, - "eraPom00", "13", status); - - vvd(rpom[1][0], 0.1414624947957029801e-10, 1e-16, - "eraPom00", "21", status); - vvd(rpom[1][1], 0.9999999999982695317, 1e-12, - "eraPom00", "22", status); - vvd(rpom[1][2], -0.1860359246998866389e-5, 1e-16, - "eraPom00", "23", status); - - vvd(rpom[2][0], -0.2550602379741215021e-6, 1e-16, - "eraPom00", "31", status); - vvd(rpom[2][1], 0.1860359247002414021e-5, 1e-16, - "eraPom00", "32", status); - vvd(rpom[2][2], 0.9999999999982370039, 1e-12, - "eraPom00", "33", status); - -} - -static void t_ppp(int *status) -/* -** - - - - - - -** t _ p p p -** - - - - - - -** -** Test eraPpp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPpp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[3], b[3], apb[3]; - - - a[0] = 2.0; - a[1] = 2.0; - a[2] = 3.0; - - b[0] = 1.0; - b[1] = 3.0; - b[2] = 4.0; - - eraPpp(a, b, apb); - - vvd(apb[0], 3.0, 1e-12, "eraPpp", "0", status); - vvd(apb[1], 5.0, 1e-12, "eraPpp", "1", status); - vvd(apb[2], 7.0, 1e-12, "eraPpp", "2", status); - -} - -static void t_ppsp(int *status) -/* -** - - - - - - - -** t _ p p s p -** - - - - - - - -** -** Test eraPpsp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPpsp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[3], s, b[3], apsb[3]; - - - a[0] = 2.0; - a[1] = 2.0; - a[2] = 3.0; - - s = 5.0; - - b[0] = 1.0; - b[1] = 3.0; - b[2] = 4.0; - - eraPpsp(a, s, b, apsb); - - vvd(apsb[0], 7.0, 1e-12, "eraPpsp", "0", status); - vvd(apsb[1], 17.0, 1e-12, "eraPpsp", "1", status); - vvd(apsb[2], 23.0, 1e-12, "eraPpsp", "2", status); - -} - -static void t_pr00(int *status) -/* -** - - - - - - - -** t _ p r 0 0 -** - - - - - - - -** -** Test eraPr00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPr00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double dpsipr, depspr; - - eraPr00(2400000.5, 53736, &dpsipr, &depspr); - - vvd(dpsipr, -0.8716465172668347629e-7, 1e-22, - "eraPr00", "dpsipr", status); - vvd(depspr, -0.7342018386722813087e-8, 1e-22, - "eraPr00", "depspr", status); - -} - -static void t_prec76(int *status) -/* -** - - - - - - - - - -** t _ p r e c 7 6 -** - - - - - - - - - -** -** Test eraPrec76 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPrec76, vvd -** -** This revision: 2013 August 7 -*/ -{ - double ep01, ep02, ep11, ep12, zeta, z, theta; - - - ep01 = 2400000.5; - ep02 = 33282.0; - ep11 = 2400000.5; - ep12 = 51544.0; - - eraPrec76(ep01, ep02, ep11, ep12, &zeta, &z, &theta); - - vvd(zeta, 0.5588961642000161243e-2, 1e-12, - "eraPrec76", "zeta", status); - vvd(z, 0.5589922365870680624e-2, 1e-12, - "eraPrec76", "z", status); - vvd(theta, 0.4858945471687296760e-2, 1e-12, - "eraPrec76", "theta", status); - -} - -static void t_pv2p(int *status) -/* -** - - - - - - - -** t _ p v 2 p -** - - - - - - - -** -** Test eraPv2p function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPv2p, vvd -** -** This revision: 2013 August 7 -*/ -{ - double pv[2][3], p[3]; - - - pv[0][0] = 0.3; - pv[0][1] = 1.2; - pv[0][2] = -2.5; - - pv[1][0] = -0.5; - pv[1][1] = 3.1; - pv[1][2] = 0.9; - - eraPv2p(pv, p); - - vvd(p[0], 0.3, 0.0, "eraPv2p", "1", status); - vvd(p[1], 1.2, 0.0, "eraPv2p", "2", status); - vvd(p[2], -2.5, 0.0, "eraPv2p", "3", status); - -} - -static void t_pv2s(int *status) -/* -** - - - - - - - -** t _ p v 2 s -** - - - - - - - -** -** Test eraPv2s function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPv2s, vvd -** -** This revision: 2013 August 7 -*/ -{ - double pv[2][3], theta, phi, r, td, pd, rd; - - - pv[0][0] = -0.4514964673880165; - pv[0][1] = 0.03093394277342585; - pv[0][2] = 0.05594668105108779; - - pv[1][0] = 1.292270850663260e-5; - pv[1][1] = 2.652814182060692e-6; - pv[1][2] = 2.568431853930293e-6; - - eraPv2s(pv, &theta, &phi, &r, &td, &pd, &rd); - - vvd(theta, 3.073185307179586515, 1e-12, "eraPv2s", "theta", status); - vvd(phi, 0.1229999999999999992, 1e-12, "eraPv2s", "phi", status); - vvd(r, 0.4559999999999999757, 1e-12, "eraPv2s", "r", status); - vvd(td, -0.7800000000000000364e-5, 1e-16, "eraPv2s", "td", status); - vvd(pd, 0.9010000000000001639e-5, 1e-16, "eraPv2s", "pd", status); - vvd(rd, -0.1229999999999999832e-4, 1e-16, "eraPv2s", "rd", status); - -} - -static void t_pvdpv(int *status) -/* -** - - - - - - - - -** t _ p v d p v -** - - - - - - - - -** -** Test eraPvdpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPvdpv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[2][3], b[2][3], adb[2]; - - - a[0][0] = 2.0; - a[0][1] = 2.0; - a[0][2] = 3.0; - - a[1][0] = 6.0; - a[1][1] = 0.0; - a[1][2] = 4.0; - - b[0][0] = 1.0; - b[0][1] = 3.0; - b[0][2] = 4.0; - - b[1][0] = 0.0; - b[1][1] = 2.0; - b[1][2] = 8.0; - - eraPvdpv(a, b, adb); - - vvd(adb[0], 20.0, 1e-12, "eraPvdpv", "1", status); - vvd(adb[1], 50.0, 1e-12, "eraPvdpv", "2", status); - -} - -static void t_pvm(int *status) -/* -** - - - - - - -** t _ p v m -** - - - - - - -** -** Test eraPvm function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPvm, vvd -** -** This revision: 2013 August 7 -*/ -{ - double pv[2][3], r, s; - - - pv[0][0] = 0.3; - pv[0][1] = 1.2; - pv[0][2] = -2.5; - - pv[1][0] = 0.45; - pv[1][1] = -0.25; - pv[1][2] = 1.1; - - eraPvm(pv, &r, &s); - - vvd(r, 2.789265136196270604, 1e-12, "eraPvm", "r", status); - vvd(s, 1.214495780149111922, 1e-12, "eraPvm", "s", status); - -} - -static void t_pvmpv(int *status) -/* -** - - - - - - - - -** t _ p v m p v -** - - - - - - - - -** -** Test eraPvmpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPvmpv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[2][3], b[2][3], amb[2][3]; - - - a[0][0] = 2.0; - a[0][1] = 2.0; - a[0][2] = 3.0; - - a[1][0] = 5.0; - a[1][1] = 6.0; - a[1][2] = 3.0; - - b[0][0] = 1.0; - b[0][1] = 3.0; - b[0][2] = 4.0; - - b[1][0] = 3.0; - b[1][1] = 2.0; - b[1][2] = 1.0; - - eraPvmpv(a, b, amb); - - vvd(amb[0][0], 1.0, 1e-12, "eraPvmpv", "11", status); - vvd(amb[0][1], -1.0, 1e-12, "eraPvmpv", "21", status); - vvd(amb[0][2], -1.0, 1e-12, "eraPvmpv", "31", status); - - vvd(amb[1][0], 2.0, 1e-12, "eraPvmpv", "12", status); - vvd(amb[1][1], 4.0, 1e-12, "eraPvmpv", "22", status); - vvd(amb[1][2], 2.0, 1e-12, "eraPvmpv", "32", status); - -} - -static void t_pvppv(int *status) -/* -** - - - - - - - - -** t _ p v p p v -** - - - - - - - - -** -** Test eraPvppv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPvppv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[2][3], b[2][3], apb[2][3]; - - - a[0][0] = 2.0; - a[0][1] = 2.0; - a[0][2] = 3.0; - - a[1][0] = 5.0; - a[1][1] = 6.0; - a[1][2] = 3.0; - - b[0][0] = 1.0; - b[0][1] = 3.0; - b[0][2] = 4.0; - - b[1][0] = 3.0; - b[1][1] = 2.0; - b[1][2] = 1.0; - - eraPvppv(a, b, apb); - - vvd(apb[0][0], 3.0, 1e-12, "eraPvppv", "p1", status); - vvd(apb[0][1], 5.0, 1e-12, "eraPvppv", "p2", status); - vvd(apb[0][2], 7.0, 1e-12, "eraPvppv", "p3", status); - - vvd(apb[1][0], 8.0, 1e-12, "eraPvppv", "v1", status); - vvd(apb[1][1], 8.0, 1e-12, "eraPvppv", "v2", status); - vvd(apb[1][2], 4.0, 1e-12, "eraPvppv", "v3", status); - -} - -static void t_pvstar(int *status) -/* -** - - - - - - - - - -** t _ p v s t a r -** - - - - - - - - - -** -** Test eraPvstar function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPvstar, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double pv[2][3], ra, dec, pmr, pmd, px, rv; - int j; - - - pv[0][0] = 126668.5912743160601; - pv[0][1] = 2136.792716839935195; - pv[0][2] = -245251.2339876830091; - - pv[1][0] = -0.4051854035740712739e-2; - pv[1][1] = -0.6253919754866173866e-2; - pv[1][2] = 0.1189353719774107189e-1; - - j = eraPvstar(pv, &ra, &dec, &pmr, &pmd, &px, &rv); - - vvd(ra, 0.1686756e-1, 1e-12, "eraPvstar", "ra", status); - vvd(dec, -1.093989828, 1e-12, "eraPvstar", "dec", status); - vvd(pmr, -0.178323516e-4, 1e-16, "eraPvstar", "pmr", status); - vvd(pmd, 0.2336024047e-5, 1e-16, "eraPvstar", "pmd", status); - vvd(px, 0.74723, 1e-12, "eraPvstar", "px", status); - vvd(rv, -21.6, 1e-11, "eraPvstar", "rv", status); - - viv(j, 0, "eraPvstar", "j", status); - -} - -static void t_pvtob(int *status) -/* -** - - - - - - - - -** t _ p v t o b -** - - - - - - - - -** -** Test eraPvtob function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPvtob, vvd -** -** This revision: 2013 October 2 -*/ -{ - double elong, phi, hm, xp, yp, sp, theta, pv[2][3]; - - - elong = 2.0; - phi = 0.5; - hm = 3000.0; - xp = 1e-6; - yp = -0.5e-6; - sp = 1e-8; - theta = 5.0; - - eraPvtob(elong, phi, hm, xp, yp, sp, theta, pv); - - vvd(pv[0][0], 4225081.367071159207, 1e-5, - "eraPvtob", "p(1)", status); - vvd(pv[0][1], 3681943.215856198144, 1e-5, - "eraPvtob", "p(2)", status); - vvd(pv[0][2], 3041149.399241260785, 1e-5, - "eraPvtob", "p(3)", status); - vvd(pv[1][0], -268.4915389365998787, 1e-9, - "eraPvtob", "v(1)", status); - vvd(pv[1][1], 308.0977983288903123, 1e-9, - "eraPvtob", "v(2)", status); - vvd(pv[1][2], 0, 0, - "eraPvtob", "v(3)", status); - -} - -static void t_pvu(int *status) -/* -** - - - - - - -** t _ p v u -** - - - - - - -** -** Test eraPvu function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPvu, vvd -** -** This revision: 2013 August 7 -*/ -{ - double pv[2][3], upv[2][3]; - - - pv[0][0] = 126668.5912743160734; - pv[0][1] = 2136.792716839935565; - pv[0][2] = -245251.2339876830229; - - pv[1][0] = -0.4051854035740713039e-2; - pv[1][1] = -0.6253919754866175788e-2; - pv[1][2] = 0.1189353719774107615e-1; - - eraPvu(2920.0, pv, upv); - - vvd(upv[0][0], 126656.7598605317105, 1e-12, - "eraPvu", "p1", status); - vvd(upv[0][1], 2118.531271155726332, 1e-12, - "eraPvu", "p2", status); - vvd(upv[0][2], -245216.5048590656190, 1e-12, - "eraPvu", "p3", status); - - vvd(upv[1][0], -0.4051854035740713039e-2, 1e-12, - "eraPvu", "v1", status); - vvd(upv[1][1], -0.6253919754866175788e-2, 1e-12, - "eraPvu", "v2", status); - vvd(upv[1][2], 0.1189353719774107615e-1, 1e-12, - "eraPvu", "v3", status); - -} - -static void t_pvup(int *status) -/* -** - - - - - - - -** t _ p v u p -** - - - - - - - -** -** Test eraPvup function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPvup, vvd -** -** This revision: 2013 August 7 -*/ -{ - double pv[2][3], p[3]; - - - pv[0][0] = 126668.5912743160734; - pv[0][1] = 2136.792716839935565; - pv[0][2] = -245251.2339876830229; - - pv[1][0] = -0.4051854035740713039e-2; - pv[1][1] = -0.6253919754866175788e-2; - pv[1][2] = 0.1189353719774107615e-1; - - eraPvup(2920.0, pv, p); - - vvd(p[0], 126656.7598605317105, 1e-12, "eraPvup", "1", status); - vvd(p[1], 2118.531271155726332, 1e-12, "eraPvup", "2", status); - vvd(p[2], -245216.5048590656190, 1e-12, "eraPvup", "3", status); - -} - -static void t_pvxpv(int *status) -/* -** - - - - - - - - -** t _ p v x p v -** - - - - - - - - -** -** Test eraPvxpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPvxpv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[2][3], b[2][3], axb[2][3]; - - - a[0][0] = 2.0; - a[0][1] = 2.0; - a[0][2] = 3.0; - - a[1][0] = 6.0; - a[1][1] = 0.0; - a[1][2] = 4.0; - - b[0][0] = 1.0; - b[0][1] = 3.0; - b[0][2] = 4.0; - - b[1][0] = 0.0; - b[1][1] = 2.0; - b[1][2] = 8.0; - - eraPvxpv(a, b, axb); - - vvd(axb[0][0], -1.0, 1e-12, "eraPvxpv", "p1", status); - vvd(axb[0][1], -5.0, 1e-12, "eraPvxpv", "p2", status); - vvd(axb[0][2], 4.0, 1e-12, "eraPvxpv", "p3", status); - - vvd(axb[1][0], -2.0, 1e-12, "eraPvxpv", "v1", status); - vvd(axb[1][1], -36.0, 1e-12, "eraPvxpv", "v2", status); - vvd(axb[1][2], 22.0, 1e-12, "eraPvxpv", "v3", status); - -} - -static void t_pxp(int *status) -/* -** - - - - - - -** t _ p x p -** - - - - - - -** -** Test eraPxp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraPxp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[3], b[3], axb[3]; - - - a[0] = 2.0; - a[1] = 2.0; - a[2] = 3.0; - - b[0] = 1.0; - b[1] = 3.0; - b[2] = 4.0; - - eraPxp(a, b, axb); - - vvd(axb[0], -1.0, 1e-12, "eraPxp", "1", status); - vvd(axb[1], -5.0, 1e-12, "eraPxp", "2", status); - vvd(axb[2], 4.0, 1e-12, "eraPxp", "3", status); - -} - -static void t_refco(int *status) -/* -** - - - - - - - - -** t _ r e f c o -** - - - - - - - - -** -** Test eraRefco function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraRefco, vvd -** -** This revision: 2013 October 2 -*/ -{ - double phpa, tc, rh, wl, refa, refb; - - - phpa = 800.0; - tc = 10.0; - rh = 0.9; - wl = 0.4; - - eraRefco(phpa, tc, rh, wl, &refa, &refb); - - vvd(refa, 0.2264949956241415009e-3, 1e-15, - "eraRefco", "refa", status); - vvd(refb, -0.2598658261729343970e-6, 1e-18, - "eraRefco", "refb", status); - -} - -static void t_rm2v(int *status) -/* -** - - - - - - - -** t _ r m 2 v -** - - - - - - - -** -** Test eraRm2v function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraRm2v, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r[3][3], w[3]; - - - r[0][0] = 0.00; - r[0][1] = -0.80; - r[0][2] = -0.60; - - r[1][0] = 0.80; - r[1][1] = -0.36; - r[1][2] = 0.48; - - r[2][0] = 0.60; - r[2][1] = 0.48; - r[2][2] = -0.64; - - eraRm2v(r, w); - - vvd(w[0], 0.0, 1e-12, "eraRm2v", "1", status); - vvd(w[1], 1.413716694115406957, 1e-12, "eraRm2v", "2", status); - vvd(w[2], -1.884955592153875943, 1e-12, "eraRm2v", "3", status); - -} - -static void t_rv2m(int *status) -/* -** - - - - - - - -** t _ r v 2 m -** - - - - - - - -** -** Test eraRv2m function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraRv2m, vvd -** -** This revision: 2013 August 7 -*/ -{ - double w[3], r[3][3]; - - - w[0] = 0.0; - w[1] = 1.41371669; - w[2] = -1.88495559; - - eraRv2m(w, r); - - vvd(r[0][0], -0.7071067782221119905, 1e-14, "eraRv2m", "11", status); - vvd(r[0][1], -0.5656854276809129651, 1e-14, "eraRv2m", "12", status); - vvd(r[0][2], -0.4242640700104211225, 1e-14, "eraRv2m", "13", status); - - vvd(r[1][0], 0.5656854276809129651, 1e-14, "eraRv2m", "21", status); - vvd(r[1][1], -0.0925483394532274246, 1e-14, "eraRv2m", "22", status); - vvd(r[1][2], -0.8194112531408833269, 1e-14, "eraRv2m", "23", status); - - vvd(r[2][0], 0.4242640700104211225, 1e-14, "eraRv2m", "31", status); - vvd(r[2][1], -0.8194112531408833269, 1e-14, "eraRv2m", "32", status); - vvd(r[2][2], 0.3854415612311154341, 1e-14, "eraRv2m", "33", status); - -} - -static void t_rx(int *status) -/* -** - - - - - -** t _ r x -** - - - - - -** -** Test eraRx function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraRx, vvd -** -** This revision: 2013 August 7 -*/ -{ - double phi, r[3][3]; - - - phi = 0.3456789; - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - eraRx(phi, r); - - vvd(r[0][0], 2.0, 0.0, "eraRx", "11", status); - vvd(r[0][1], 3.0, 0.0, "eraRx", "12", status); - vvd(r[0][2], 2.0, 0.0, "eraRx", "13", status); - - vvd(r[1][0], 3.839043388235612460, 1e-12, "eraRx", "21", status); - vvd(r[1][1], 3.237033249594111899, 1e-12, "eraRx", "22", status); - vvd(r[1][2], 4.516714379005982719, 1e-12, "eraRx", "23", status); - - vvd(r[2][0], 1.806030415924501684, 1e-12, "eraRx", "31", status); - vvd(r[2][1], 3.085711545336372503, 1e-12, "eraRx", "32", status); - vvd(r[2][2], 3.687721683977873065, 1e-12, "eraRx", "33", status); - -} - -static void t_rxp(int *status) -/* -** - - - - - - -** t _ r x p -** - - - - - - -** -** Test eraRxp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraRxp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r[3][3], p[3], rp[3]; - - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - p[0] = 0.2; - p[1] = 1.5; - p[2] = 0.1; - - eraRxp(r, p, rp); - - vvd(rp[0], 5.1, 1e-12, "eraRxp", "1", status); - vvd(rp[1], 3.9, 1e-12, "eraRxp", "2", status); - vvd(rp[2], 7.1, 1e-12, "eraRxp", "3", status); - -} - -static void t_rxpv(int *status) -/* -** - - - - - - - -** t _ r x p v -** - - - - - - - -** -** Test eraRxpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraRxpv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r[3][3], pv[2][3], rpv[2][3]; - - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - pv[0][0] = 0.2; - pv[0][1] = 1.5; - pv[0][2] = 0.1; - - pv[1][0] = 1.5; - pv[1][1] = 0.2; - pv[1][2] = 0.1; - - eraRxpv(r, pv, rpv); - - vvd(rpv[0][0], 5.1, 1e-12, "eraRxpv", "11", status); - vvd(rpv[1][0], 3.8, 1e-12, "eraRxpv", "12", status); - - vvd(rpv[0][1], 3.9, 1e-12, "eraRxpv", "21", status); - vvd(rpv[1][1], 5.2, 1e-12, "eraRxpv", "22", status); - - vvd(rpv[0][2], 7.1, 1e-12, "eraRxpv", "31", status); - vvd(rpv[1][2], 5.8, 1e-12, "eraRxpv", "32", status); - -} - -static void t_rxr(int *status) -/* -** - - - - - - -** t _ r x r -** - - - - - - -** -** Test eraRxr function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraRxr, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[3][3], b[3][3], atb[3][3]; - - - a[0][0] = 2.0; - a[0][1] = 3.0; - a[0][2] = 2.0; - - a[1][0] = 3.0; - a[1][1] = 2.0; - a[1][2] = 3.0; - - a[2][0] = 3.0; - a[2][1] = 4.0; - a[2][2] = 5.0; - - b[0][0] = 1.0; - b[0][1] = 2.0; - b[0][2] = 2.0; - - b[1][0] = 4.0; - b[1][1] = 1.0; - b[1][2] = 1.0; - - b[2][0] = 3.0; - b[2][1] = 0.0; - b[2][2] = 1.0; - - eraRxr(a, b, atb); - - vvd(atb[0][0], 20.0, 1e-12, "eraRxr", "11", status); - vvd(atb[0][1], 7.0, 1e-12, "eraRxr", "12", status); - vvd(atb[0][2], 9.0, 1e-12, "eraRxr", "13", status); - - vvd(atb[1][0], 20.0, 1e-12, "eraRxr", "21", status); - vvd(atb[1][1], 8.0, 1e-12, "eraRxr", "22", status); - vvd(atb[1][2], 11.0, 1e-12, "eraRxr", "23", status); - - vvd(atb[2][0], 34.0, 1e-12, "eraRxr", "31", status); - vvd(atb[2][1], 10.0, 1e-12, "eraRxr", "32", status); - vvd(atb[2][2], 15.0, 1e-12, "eraRxr", "33", status); - -} - -static void t_ry(int *status) -/* -** - - - - - -** t _ r y -** - - - - - -** -** Test eraRy function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraRy, vvd -** -** This revision: 2013 August 7 -*/ -{ - double theta, r[3][3]; - - - theta = 0.3456789; - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - eraRy(theta, r); - - vvd(r[0][0], 0.8651847818978159930, 1e-12, "eraRy", "11", status); - vvd(r[0][1], 1.467194920539316554, 1e-12, "eraRy", "12", status); - vvd(r[0][2], 0.1875137911274457342, 1e-12, "eraRy", "13", status); - - vvd(r[1][0], 3, 1e-12, "eraRy", "21", status); - vvd(r[1][1], 2, 1e-12, "eraRy", "22", status); - vvd(r[1][2], 3, 1e-12, "eraRy", "23", status); - - vvd(r[2][0], 3.500207892850427330, 1e-12, "eraRy", "31", status); - vvd(r[2][1], 4.779889022262298150, 1e-12, "eraRy", "32", status); - vvd(r[2][2], 5.381899160903798712, 1e-12, "eraRy", "33", status); - -} - -static void t_rz(int *status) -/* -** - - - - - -** t _ r z -** - - - - - -** -** Test eraRz function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraRz, vvd -** -** This revision: 2013 August 7 -*/ -{ - double psi, r[3][3]; - - - psi = 0.3456789; - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - eraRz(psi, r); - - vvd(r[0][0], 2.898197754208926769, 1e-12, "eraRz", "11", status); - vvd(r[0][1], 3.500207892850427330, 1e-12, "eraRz", "12", status); - vvd(r[0][2], 2.898197754208926769, 1e-12, "eraRz", "13", status); - - vvd(r[1][0], 2.144865911309686813, 1e-12, "eraRz", "21", status); - vvd(r[1][1], 0.865184781897815993, 1e-12, "eraRz", "22", status); - vvd(r[1][2], 2.144865911309686813, 1e-12, "eraRz", "23", status); - - vvd(r[2][0], 3.0, 1e-12, "eraRz", "31", status); - vvd(r[2][1], 4.0, 1e-12, "eraRz", "32", status); - vvd(r[2][2], 5.0, 1e-12, "eraRz", "33", status); - -} - -static void t_s00a(int *status) -/* -** - - - - - - - -** t _ s 0 0 a -** - - - - - - - -** -** Test eraS00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraS00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double s; - - - s = eraS00a(2400000.5, 52541.0); - - vvd(s, -0.1340684448919163584e-7, 1e-18, "eraS00a", "", status); - -} - -static void t_s00b(int *status) -/* -** - - - - - - - -** t _ s 0 0 b -** - - - - - - - -** -** Test eraS00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraS00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double s; - - - s = eraS00b(2400000.5, 52541.0); - - vvd(s, -0.1340695782951026584e-7, 1e-18, "eraS00b", "", status); - -} - -static void t_s00(int *status) -/* -** - - - - - - -** t _ s 0 0 -** - - - - - - -** -** Test eraS00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraS00, vvd -** -** This revision: 2013 August 7 -*/ -{ - double x, y, s; - - - x = 0.5791308486706011000e-3; - y = 0.4020579816732961219e-4; - - s = eraS00(2400000.5, 53736.0, x, y); - - vvd(s, -0.1220036263270905693e-7, 1e-18, "eraS00", "", status); - -} - -static void t_s06a(int *status) -/* -** - - - - - - - -** t _ s 0 6 a -** - - - - - - - -** -** Test eraS06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraS06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double s; - - - s = eraS06a(2400000.5, 52541.0); - - vvd(s, -0.1340680437291812383e-7, 1e-18, "eraS06a", "", status); - -} - -static void t_s06(int *status) -/* -** - - - - - - -** t _ s 0 6 -** - - - - - - -** -** Test eraS06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraS06, vvd -** -** This revision: 2013 August 7 -*/ -{ - double x, y, s; - - - x = 0.5791308486706011000e-3; - y = 0.4020579816732961219e-4; - - s = eraS06(2400000.5, 53736.0, x, y); - - vvd(s, -0.1220032213076463117e-7, 1e-18, "eraS06", "", status); - -} - -static void t_s2c(int *status) -/* -** - - - - - - -** t _ s 2 c -** - - - - - - -** -** Test eraS2c function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraS2c, vvd -** -** This revision: 2013 August 7 -*/ -{ - double c[3]; - - - eraS2c(3.0123, -0.999, c); - - vvd(c[0], -0.5366267667260523906, 1e-12, "eraS2c", "1", status); - vvd(c[1], 0.0697711109765145365, 1e-12, "eraS2c", "2", status); - vvd(c[2], -0.8409302618566214041, 1e-12, "eraS2c", "3", status); - -} - -static void t_s2p(int *status) -/* -** - - - - - - -** t _ s 2 p -** - - - - - - -** -** Test eraS2p function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraS2p, vvd -** -** This revision: 2013 August 7 -*/ -{ - double p[3]; - - - eraS2p(-3.21, 0.123, 0.456, p); - - vvd(p[0], -0.4514964673880165228, 1e-12, "eraS2p", "x", status); - vvd(p[1], 0.0309339427734258688, 1e-12, "eraS2p", "y", status); - vvd(p[2], 0.0559466810510877933, 1e-12, "eraS2p", "z", status); - -} - -static void t_s2pv(int *status) -/* -** - - - - - - - -** t _ s 2 p v -** - - - - - - - -** -** Test eraS2pv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraS2pv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double pv[2][3]; - - - eraS2pv(-3.21, 0.123, 0.456, -7.8e-6, 9.01e-6, -1.23e-5, pv); - - vvd(pv[0][0], -0.4514964673880165228, 1e-12, "eraS2pv", "x", status); - vvd(pv[0][1], 0.0309339427734258688, 1e-12, "eraS2pv", "y", status); - vvd(pv[0][2], 0.0559466810510877933, 1e-12, "eraS2pv", "z", status); - - vvd(pv[1][0], 0.1292270850663260170e-4, 1e-16, - "eraS2pv", "vx", status); - vvd(pv[1][1], 0.2652814182060691422e-5, 1e-16, - "eraS2pv", "vy", status); - vvd(pv[1][2], 0.2568431853930292259e-5, 1e-16, - "eraS2pv", "vz", status); - -} - -static void t_s2xpv(int *status) -/* -** - - - - - - - - -** t _ s 2 x p v -** - - - - - - - - -** -** Test eraS2xpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraS2xpv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double s1, s2, pv[2][3], spv[2][3]; - - - s1 = 2.0; - s2 = 3.0; - - pv[0][0] = 0.3; - pv[0][1] = 1.2; - pv[0][2] = -2.5; - - pv[1][0] = 0.5; - pv[1][1] = 2.3; - pv[1][2] = -0.4; - - eraS2xpv(s1, s2, pv, spv); - - vvd(spv[0][0], 0.6, 1e-12, "eraS2xpv", "p1", status); - vvd(spv[0][1], 2.4, 1e-12, "eraS2xpv", "p2", status); - vvd(spv[0][2], -5.0, 1e-12, "eraS2xpv", "p3", status); - - vvd(spv[1][0], 1.5, 1e-12, "eraS2xpv", "v1", status); - vvd(spv[1][1], 6.9, 1e-12, "eraS2xpv", "v2", status); - vvd(spv[1][2], -1.2, 1e-12, "eraS2xpv", "v3", status); - -} - -static void t_sepp(int *status) -/* -** - - - - - - - -** t _ s e p p -** - - - - - - - -** -** Test eraSepp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraSepp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double a[3], b[3], s; - - - a[0] = 1.0; - a[1] = 0.1; - a[2] = 0.2; - - b[0] = -3.0; - b[1] = 1e-3; - b[2] = 0.2; - - s = eraSepp(a, b); - - vvd(s, 2.860391919024660768, 1e-12, "eraSepp", "", status); - -} - -static void t_seps(int *status) -/* -** - - - - - - - -** t _ s e p s -** - - - - - - - -** -** Test eraSeps function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraSeps, vvd -** -** This revision: 2013 August 7 -*/ -{ - double al, ap, bl, bp, s; - - - al = 1.0; - ap = 0.1; - - bl = 0.2; - bp = -3.0; - - s = eraSeps(al, ap, bl, bp); - - vvd(s, 2.346722016996998842, 1e-14, "eraSeps", "", status); - -} - -static void t_sp00(int *status) -/* -** - - - - - - - -** t _ s p 0 0 -** - - - - - - - -** -** Test eraSp00 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraSp00, vvd -** -** This revision: 2013 August 7 -*/ -{ - vvd(eraSp00(2400000.5, 52541.0), - -0.6216698469981019309e-11, 1e-12, "eraSp00", "", status); - -} - -static void t_starpm(int *status) -/* -** - - - - - - - - - -** t _ s t a r p m -** - - - - - - - - - -** -** Test eraStarpm function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraStarpm, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double ra1, dec1, pmr1, pmd1, px1, rv1; - double ra2, dec2, pmr2, pmd2, px2, rv2; - int j; - - - ra1 = 0.01686756; - dec1 = -1.093989828; - pmr1 = -1.78323516e-5; - pmd1 = 2.336024047e-6; - px1 = 0.74723; - rv1 = -21.6; - - j = eraStarpm(ra1, dec1, pmr1, pmd1, px1, rv1, - 2400000.5, 50083.0, 2400000.5, 53736.0, - &ra2, &dec2, &pmr2, &pmd2, &px2, &rv2); - - vvd(ra2, 0.01668919069414242368, 1e-13, - "eraStarpm", "ra", status); - vvd(dec2, -1.093966454217127879, 1e-13, - "eraStarpm", "dec", status); - vvd(pmr2, -0.1783662682155932702e-4, 1e-17, - "eraStarpm", "pmr", status); - vvd(pmd2, 0.2338092915987603664e-5, 1e-17, - "eraStarpm", "pmd", status); - vvd(px2, 0.7473533835323493644, 1e-13, - "eraStarpm", "px", status); - vvd(rv2, -21.59905170476860786, 1e-11, - "eraStarpm", "rv", status); - - viv(j, 0, "eraStarpm", "j", status); - -} - -static void t_starpv(int *status) -/* -** - - - - - - - - - -** t _ s t a r p v -** - - - - - - - - - -** -** Test eraStarpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraStarpv, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double ra, dec, pmr, pmd, px, rv, pv[2][3]; - int j; - - - ra = 0.01686756; - dec = -1.093989828; - pmr = -1.78323516e-5; - pmd = 2.336024047e-6; - px = 0.74723; - rv = -21.6; - - j = eraStarpv(ra, dec, pmr, pmd, px, rv, pv); - - vvd(pv[0][0], 126668.5912743160601, 1e-10, - "eraStarpv", "11", status); - vvd(pv[0][1], 2136.792716839935195, 1e-12, - "eraStarpv", "12", status); - vvd(pv[0][2], -245251.2339876830091, 1e-10, - "eraStarpv", "13", status); - - vvd(pv[1][0], -0.4051854035740712739e-2, 1e-13, - "eraStarpv", "21", status); - vvd(pv[1][1], -0.6253919754866173866e-2, 1e-15, - "eraStarpv", "22", status); - vvd(pv[1][2], 0.1189353719774107189e-1, 1e-13, - "eraStarpv", "23", status); - - viv(j, 0, "eraStarpv", "j", status); - -} - -static void t_sxp(int *status) -/* -** - - - - - - -** t _ s x p -** - - - - - - -** -** Test eraSxp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraSxp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double s, p[3], sp[3]; - - - s = 2.0; - - p[0] = 0.3; - p[1] = 1.2; - p[2] = -2.5; - - eraSxp(s, p, sp); - - vvd(sp[0], 0.6, 0.0, "eraSxp", "1", status); - vvd(sp[1], 2.4, 0.0, "eraSxp", "2", status); - vvd(sp[2], -5.0, 0.0, "eraSxp", "3", status); - -} - - -static void t_sxpv(int *status) -/* -** - - - - - - - -** t _ s x p v -** - - - - - - - -** -** Test eraSxpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraSxpv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double s, pv[2][3], spv[2][3]; - - - s = 2.0; - - pv[0][0] = 0.3; - pv[0][1] = 1.2; - pv[0][2] = -2.5; - - pv[1][0] = 0.5; - pv[1][1] = 3.2; - pv[1][2] = -0.7; - - eraSxpv(s, pv, spv); - - vvd(spv[0][0], 0.6, 0.0, "eraSxpv", "p1", status); - vvd(spv[0][1], 2.4, 0.0, "eraSxpv", "p2", status); - vvd(spv[0][2], -5.0, 0.0, "eraSxpv", "p3", status); - - vvd(spv[1][0], 1.0, 0.0, "eraSxpv", "v1", status); - vvd(spv[1][1], 6.4, 0.0, "eraSxpv", "v2", status); - vvd(spv[1][2], -1.4, 0.0, "eraSxpv", "v3", status); - -} - -static void t_taitt(int *status) -/* -** - - - - - - - - -** t _ t a i t t -** - - - - - - - - -** -** Test eraTaitt function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTaitt, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double t1, t2; - int j; - - - j = eraTaitt(2453750.5, 0.892482639, &t1, &t2); - - vvd(t1, 2453750.5, 1e-6, "eraTaitt", "t1", status); - vvd(t2, 0.892855139, 1e-12, "eraTaitt", "t2", status); - viv(j, 0, "eraTaitt", "j", status); - -} - -static void t_taiut1(int *status) -/* -** - - - - - - - - - -** t _ t a i u t 1 -** - - - - - - - - - -** -** Test eraTaiut1 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTaiut1, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double u1, u2; - int j; - - - j = eraTaiut1(2453750.5, 0.892482639, -32.6659, &u1, &u2); - - vvd(u1, 2453750.5, 1e-6, "eraTaiut1", "u1", status); - vvd(u2, 0.8921045614537037037, 1e-12, "eraTaiut1", "u2", status); - viv(j, 0, "eraTaiut1", "j", status); - -} - -static void t_taiutc(int *status) -/* -** - - - - - - - - - -** t _ t a i u t c -** - - - - - - - - - -** -** Test eraTaiutc function. -** -** Returned: -** status LOGICAL TRUE = success, FALSE = fail -** -** Called: eraTaiutc, vvd, viv -** -** This revision: 2013 October 3 -*/ -{ - double u1, u2; - int j; - - - j = eraTaiutc(2453750.5, 0.892482639, &u1, &u2); - - vvd(u1, 2453750.5, 1e-6, "eraTaiutc", "u1", status); - vvd(u2, 0.8921006945555555556, 1e-12, "eraTaiutc", "u2", status); - viv(j, 0, "eraTaiutc", "j", status); - -} - -static void t_tcbtdb(int *status) -/* -** - - - - - - - - - -** t _ t c b t d b -** - - - - - - - - - -** -** Test eraTcbtdb function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTcbtdb, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double b1, b2; - int j; - - - j = eraTcbtdb(2453750.5, 0.893019599, &b1, &b2); - - vvd(b1, 2453750.5, 1e-6, "eraTcbtdb", "b1", status); - vvd(b2, 0.8928551362746343397, 1e-12, "eraTcbtdb", "b2", status); - viv(j, 0, "eraTcbtdb", "j", status); - -} - -static void t_tcgtt(int *status) -/* -** - - - - - - - - -** t _ t c g t t -** - - - - - - - - -** -** Test eraTcgtt function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTcgtt, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double t1, t2; - int j; - - - j = eraTcgtt(2453750.5, 0.892862531, &t1, &t2); - - vvd(t1, 2453750.5, 1e-6, "eraTcgtt", "t1", status); - vvd(t2, 0.8928551387488816828, 1e-12, "eraTcgtt", "t2", status); - viv(j, 0, "eraTcgtt", "j", status); - -} - -static void t_tdbtcb(int *status) -/* -** - - - - - - - - - -** t _ t d b t c b -** - - - - - - - - - -** -** Test eraTdbtcb function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTdbtcb, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double b1, b2; - int j; - - - j = eraTdbtcb(2453750.5, 0.892855137, &b1, &b2); - - vvd( b1, 2453750.5, 1e-6, "eraTdbtcb", "b1", status); - vvd( b2, 0.8930195997253656716, 1e-12, "eraTdbtcb", "b2", status); - viv(j, 0, "eraTdbtcb", "j", status); - -} - -static void t_tdbtt(int *status) -/* -** - - - - - - - - -** t _ t d b t t -** - - - - - - - - -** -** Test eraTdbtt function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTdbtt, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double t1, t2; - int j; - - - j = eraTdbtt(2453750.5, 0.892855137, -0.000201, &t1, &t2); - - vvd(t1, 2453750.5, 1e-6, "eraTdbtt", "t1", status); - vvd(t2, 0.8928551393263888889, 1e-12, "eraTdbtt", "t2", status); - viv(j, 0, "eraTdbtt", "j", status); - -} - -static void t_tf2a(int *status) -/* -** - - - - - - - -** t _ t f 2 a -** - - - - - - - -** -** Test eraTf2a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTf2a, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double a; - int j; - - - j = eraTf2a('+', 4, 58, 20.2, &a); - - vvd(a, 1.301739278189537429, 1e-12, "eraTf2a", "a", status); - viv(j, 0, "eraTf2a", "j", status); - -} - -static void t_tf2d(int *status) -/* -** - - - - - - - -** t _ t f 2 d -** - - - - - - - -** -** Test eraTf2d function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTf2d, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double d; - int j; - - - j = eraTf2d(' ', 23, 55, 10.9, &d); - - vvd(d, 0.9966539351851851852, 1e-12, "eraTf2d", "d", status); - viv(j, 0, "eraTf2d", "j", status); - -} - -static void t_tr(int *status) -/* -** - - - - - -** t _ t r -** - - - - - -** -** Test eraTr function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTr, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r[3][3], rt[3][3]; - - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - eraTr(r, rt); - - vvd(rt[0][0], 2.0, 0.0, "eraTr", "11", status); - vvd(rt[0][1], 3.0, 0.0, "eraTr", "12", status); - vvd(rt[0][2], 3.0, 0.0, "eraTr", "13", status); - - vvd(rt[1][0], 3.0, 0.0, "eraTr", "21", status); - vvd(rt[1][1], 2.0, 0.0, "eraTr", "22", status); - vvd(rt[1][2], 4.0, 0.0, "eraTr", "23", status); - - vvd(rt[2][0], 2.0, 0.0, "eraTr", "31", status); - vvd(rt[2][1], 3.0, 0.0, "eraTr", "32", status); - vvd(rt[2][2], 5.0, 0.0, "eraTr", "33", status); - -} - -static void t_trxp(int *status) -/* -** - - - - - - - -** t _ t r x p -** - - - - - - - -** -** Test eraTrxp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTrxp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r[3][3], p[3], trp[3]; - - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - p[0] = 0.2; - p[1] = 1.5; - p[2] = 0.1; - - eraTrxp(r, p, trp); - - vvd(trp[0], 5.2, 1e-12, "eraTrxp", "1", status); - vvd(trp[1], 4.0, 1e-12, "eraTrxp", "2", status); - vvd(trp[2], 5.4, 1e-12, "eraTrxp", "3", status); - -} - -static void t_trxpv(int *status) -/* -** - - - - - - - - -** t _ t r x p v -** - - - - - - - - -** -** Test eraTrxpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTrxpv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r[3][3], pv[2][3], trpv[2][3]; - - - r[0][0] = 2.0; - r[0][1] = 3.0; - r[0][2] = 2.0; - - r[1][0] = 3.0; - r[1][1] = 2.0; - r[1][2] = 3.0; - - r[2][0] = 3.0; - r[2][1] = 4.0; - r[2][2] = 5.0; - - pv[0][0] = 0.2; - pv[0][1] = 1.5; - pv[0][2] = 0.1; - - pv[1][0] = 1.5; - pv[1][1] = 0.2; - pv[1][2] = 0.1; - - eraTrxpv(r, pv, trpv); - - vvd(trpv[0][0], 5.2, 1e-12, "eraTrxpv", "p1", status); - vvd(trpv[0][1], 4.0, 1e-12, "eraTrxpv", "p1", status); - vvd(trpv[0][2], 5.4, 1e-12, "eraTrxpv", "p1", status); - - vvd(trpv[1][0], 3.9, 1e-12, "eraTrxpv", "v1", status); - vvd(trpv[1][1], 5.3, 1e-12, "eraTrxpv", "v2", status); - vvd(trpv[1][2], 4.1, 1e-12, "eraTrxpv", "v3", status); - -} - -static void t_tttai(int *status) -/* -** - - - - - - - - -** t _ t t t a i -** - - - - - - - - -** -** Test eraTttai function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTttai, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double a1, a2; - int j; - - - j = eraTttai(2453750.5, 0.892482639, &a1, &a2); - - vvd(a1, 2453750.5, 1e-6, "eraTttai", "a1", status); - vvd(a2, 0.892110139, 1e-12, "eraTttai", "a2", status); - viv(j, 0, "eraTttai", "j", status); - -} - -static void t_tttcg(int *status) -/* -** - - - - - - - - -** t _ t t t c g -** - - - - - - - - -** -** Test eraTttcg function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTttcg, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double g1, g2; - int j; - - - j = eraTttcg(2453750.5, 0.892482639, &g1, &g2); - - vvd( g1, 2453750.5, 1e-6, "eraTttcg", "g1", status); - vvd( g2, 0.8924900312508587113, 1e-12, "eraTttcg", "g2", status); - viv(j, 0, "eraTttcg", "j", status); - -} - -static void t_tttdb(int *status) -/* -** - - - - - - - - -** t _ t t t d b -** - - - - - - - - -** -** Test eraTttdb function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTttdb, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double b1, b2; - int j; - - - j = eraTttdb(2453750.5, 0.892855139, -0.000201, &b1, &b2); - - vvd(b1, 2453750.5, 1e-6, "eraTttdb", "b1", status); - vvd(b2, 0.8928551366736111111, 1e-12, "eraTttdb", "b2", status); - viv(j, 0, "eraTttdb", "j", status); - -} - -static void t_ttut1(int *status) -/* -** - - - - - - - - -** t _ t t u t 1 -** - - - - - - - - -** -** Test eraTtut1 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraTtut1, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double u1, u2; - int j; - - - j = eraTtut1(2453750.5, 0.892855139, 64.8499, &u1, &u2); - - vvd(u1, 2453750.5, 1e-6, "eraTtut1", "u1", status); - vvd(u2, 0.8921045614537037037, 1e-12, "eraTtut1", "u2", status); - viv(j, 0, "eraTtut1", "j", status); - -} - -static void t_ut1tai(int *status) -/* -** - - - - - - - - - -** t _ u t 1 t a i -** - - - - - - - - - -** -** Test eraUt1tai function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraUt1tai, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double a1, a2; - int j; - - - j = eraUt1tai(2453750.5, 0.892104561, -32.6659, &a1, &a2); - - vvd(a1, 2453750.5, 1e-6, "eraUt1tai", "a1", status); - vvd(a2, 0.8924826385462962963, 1e-12, "eraUt1tai", "a2", status); - viv(j, 0, "eraUt1tai", "j", status); - -} - -static void t_ut1tt(int *status) -/* -** - - - - - - - - -** t _ u t 1 t t -** - - - - - - - - -** -** Test eraUt1tt function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraUt1tt, vvd, viv -** -** This revision: 2013 October 3 -*/ -{ - double t1, t2; - int j; - - - j = eraUt1tt(2453750.5, 0.892104561, 64.8499, &t1, &t2); - - vvd(t1, 2453750.5, 1e-6, "eraUt1tt", "t1", status); - vvd(t2, 0.8928551385462962963, 1e-12, "eraUt1tt", "t2", status); - viv(j, 0, "eraUt1tt", "j", status); - -} - -static void t_ut1utc(int *status) -/* -** - - - - - - - - - -** t _ u t 1 u t c -** - - - - - - - - - -** -** Test eraUt1utc function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraUt1utc, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double u1, u2; - int j; - - - j = eraUt1utc(2453750.5, 0.892104561, 0.3341, &u1, &u2); - - vvd(u1, 2453750.5, 1e-6, "eraUt1utc", "u1", status); - vvd(u2, 0.8921006941018518519, 1e-12, "eraUt1utc", "u2", status); - viv(j, 0, "eraUt1utc", "j", status); - -} - -static void t_utctai(int *status) -/* -** - - - - - - - - - -** t _ u t c t a i -** - - - - - - - - - -** -** Test eraUtctai function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraUtctai, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double u1, u2; - int j; - - - j = eraUtctai(2453750.5, 0.892100694, &u1, &u2); - - vvd(u1, 2453750.5, 1e-6, "eraUtctai", "u1", status); - vvd(u2, 0.8924826384444444444, 1e-12, "eraUtctai", "u2", status); - viv(j, 0, "eraUtctai", "j", status); - -} - -static void t_utcut1(int *status) -/* -** - - - - - - - - - -** t _ u t c u t 1 -** - - - - - - - - - -** -** Test eraUtcut1 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraUtcut1, vvd, viv -** -** This revision: 2013 August 7 -*/ -{ - double u1, u2; - int j; - - - j = eraUtcut1(2453750.5, 0.892100694, 0.3341, &u1, &u2); - - vvd(u1, 2453750.5, 1e-6, "eraUtcut1", "u1", status); - vvd(u2, 0.8921045608981481481, 1e-12, "eraUtcut1", "u2", status); - viv(j, 0, "eraUtcut1", "j", status); - -} - -static void t_xy06(int *status) -/* -** - - - - - - - -** t _ x y 0 6 -** - - - - - - - -** -** Test eraXy06 function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraXy06, vvd -** -** This revision: 2013 August 7 -*/ -{ - double x, y; - - - eraXy06(2400000.5, 53736.0, &x, &y); - - vvd(x, 0.5791308486706010975e-3, 1e-15, "eraXy06", "x", status); - vvd(y, 0.4020579816732958141e-4, 1e-16, "eraXy06", "y", status); - -} - -static void t_xys00a(int *status) -/* -** - - - - - - - - - -** t _ x y s 0 0 a -** - - - - - - - - - -** -** Test eraXys00a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraXys00a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double x, y, s; - - - eraXys00a(2400000.5, 53736.0, &x, &y, &s); - - vvd(x, 0.5791308472168152904e-3, 1e-14, "eraXys00a", "x", status); - vvd(y, 0.4020595661591500259e-4, 1e-15, "eraXys00a", "y", status); - vvd(s, -0.1220040848471549623e-7, 1e-18, "eraXys00a", "s", status); - -} - -static void t_xys00b(int *status) -/* -** - - - - - - - - - -** t _ x y s 0 0 b -** - - - - - - - - - -** -** Test eraXys00b function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraXys00b, vvd -** -** This revision: 2013 August 7 -*/ -{ - double x, y, s; - - - eraXys00b(2400000.5, 53736.0, &x, &y, &s); - - vvd(x, 0.5791301929950208873e-3, 1e-14, "eraXys00b", "x", status); - vvd(y, 0.4020553681373720832e-4, 1e-15, "eraXys00b", "y", status); - vvd(s, -0.1220027377285083189e-7, 1e-18, "eraXys00b", "s", status); - -} - -static void t_xys06a(int *status) -/* -** - - - - - - - - - -** t _ x y s 0 6 a -** - - - - - - - - - -** -** Test eraXys06a function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraXys06a, vvd -** -** This revision: 2013 August 7 -*/ -{ - double x, y, s; - - - eraXys06a(2400000.5, 53736.0, &x, &y, &s); - - vvd(x, 0.5791308482835292617e-3, 1e-14, "eraXys06a", "x", status); - vvd(y, 0.4020580099454020310e-4, 1e-15, "eraXys06a", "y", status); - vvd(s, -0.1220032294164579896e-7, 1e-18, "eraXys06a", "s", status); - -} - -static void t_zp(int *status) -/* -** - - - - - -** t _ z p -** - - - - - -** -** Test eraZp function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraZp, vvd -** -** This revision: 2013 August 7 -*/ -{ - double p[3]; - - - p[0] = 0.3; - p[1] = 1.2; - p[2] = -2.5; - - eraZp(p); - - vvd(p[0], 0.0, 0.0, "eraZp", "1", status); - vvd(p[1], 0.0, 0.0, "eraZp", "2", status); - vvd(p[2], 0.0, 0.0, "eraZp", "3", status); - -} - -static void t_zpv(int *status) -/* -** - - - - - - -** t _ z p v -** - - - - - - -** -** Test eraZpv function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraZpv, vvd -** -** This revision: 2013 August 7 -*/ -{ - double pv[2][3]; - - - pv[0][0] = 0.3; - pv[0][1] = 1.2; - pv[0][2] = -2.5; - - pv[1][0] = -0.5; - pv[1][1] = 3.1; - pv[1][2] = 0.9; - - eraZpv(pv); - - vvd(pv[0][0], 0.0, 0.0, "eraZpv", "p1", status); - vvd(pv[0][1], 0.0, 0.0, "eraZpv", "p2", status); - vvd(pv[0][2], 0.0, 0.0, "eraZpv", "p3", status); - - vvd(pv[1][0], 0.0, 0.0, "eraZpv", "v1", status); - vvd(pv[1][1], 0.0, 0.0, "eraZpv", "v2", status); - vvd(pv[1][2], 0.0, 0.0, "eraZpv", "v3", status); - -} - -static void t_zr(int *status) -/* -** - - - - - -** t _ z r -** - - - - - -** -** Test eraZr function. -** -** Returned: -** status int FALSE = success, TRUE = fail -** -** Called: eraZr, vvd -** -** This revision: 2013 August 7 -*/ -{ - double r[3][3]; - - - r[0][0] = 2.0; - r[1][0] = 3.0; - r[2][0] = 2.0; - - r[0][1] = 3.0; - r[1][1] = 2.0; - r[2][1] = 3.0; - - r[0][2] = 3.0; - r[1][2] = 4.0; - r[2][2] = 5.0; - - eraZr(r); - - vvd(r[0][0], 0.0, 0.0, "eraZr", "00", status); - vvd(r[1][0], 0.0, 0.0, "eraZr", "01", status); - vvd(r[2][0], 0.0, 0.0, "eraZr", "02", status); - - vvd(r[0][1], 0.0, 0.0, "eraZr", "10", status); - vvd(r[1][1], 0.0, 0.0, "eraZr", "11", status); - vvd(r[2][1], 0.0, 0.0, "eraZr", "12", status); - - vvd(r[0][2], 0.0, 0.0, "eraZr", "20", status); - vvd(r[1][2], 0.0, 0.0, "eraZr", "21", status); - vvd(r[2][2], 0.0, 0.0, "eraZr", "22", status); - -} - -int main(int argc, char *argv[]) -/* -** - - - - - -** m a i n -** - - - - - -** -** This revision: 2016 March 12 -*/ -{ - int status; - - -/* If any command-line argument, switch to verbose reporting. */ - if (argc > 1) { - verbose = 1; - argv[0][0] += 0; /* to avoid compiler warnings */ - } - -/* Preset the &status to FALSE = success. */ - status = 0; - -/* Test all of the ERFA functions. */ - t_a2af(&status); - t_a2tf(&status); - t_ab(&status); - t_af2a(&status); - t_anp(&status); - t_anpm(&status); - t_apcg(&status); - t_apcg13(&status); - t_apci(&status); - t_apci13(&status); - t_apco(&status); - t_apco13(&status); - t_apcs(&status); - t_apcs13(&status); - t_aper(&status); - t_aper13(&status); - t_apio(&status); - t_apio13(&status); - t_atci13(&status); - t_atciq(&status); - t_atciqn(&status); - t_atciqz(&status); - t_atco13(&status); - t_atic13(&status); - t_aticq(&status); - t_aticqn(&status); - t_atio13(&status); - t_atioq(&status); - t_atoc13(&status); - t_atoi13(&status); - t_atoiq(&status); - t_bi00(&status); - t_bp00(&status); - t_bp06(&status); - t_bpn2xy(&status); - t_c2i00a(&status); - t_c2i00b(&status); - t_c2i06a(&status); - t_c2ibpn(&status); - t_c2ixy(&status); - t_c2ixys(&status); - t_c2s(&status); - t_c2t00a(&status); - t_c2t00b(&status); - t_c2t06a(&status); - t_c2tcio(&status); - t_c2teqx(&status); - t_c2tpe(&status); - t_c2txy(&status); - t_cal2jd(&status); - t_cp(&status); - t_cpv(&status); - t_cr(&status); - t_d2dtf(&status); - t_d2tf(&status); - t_dat(&status); - t_dtdb(&status); - t_dtf2d(&status); - t_eceq06(&status); - t_ecm06(&status); - t_ee00(&status); - t_ee00a(&status); - t_ee00b(&status); - t_ee06a(&status); - t_eect00(&status); - t_eform(&status); - t_eo06a(&status); - t_eors(&status); - t_epb(&status); - t_epb2jd(&status); - t_epj(&status); - t_epj2jd(&status); - t_epv00(&status); - t_eqec06(&status); - t_eqeq94(&status); - t_era00(&status); - t_fad03(&status); - t_fae03(&status); - t_faf03(&status); - t_faju03(&status); - t_fal03(&status); - t_falp03(&status); - t_fama03(&status); - t_fame03(&status); - t_fane03(&status); - t_faom03(&status); - t_fapa03(&status); - t_fasa03(&status); - t_faur03(&status); - t_fave03(&status); - t_fk52h(&status); - t_fk5hip(&status); - t_fk5hz(&status); - t_fw2m(&status); - t_fw2xy(&status); - t_g2icrs(&status); - t_gc2gd(&status); - t_gc2gde(&status); - t_gd2gc(&status); - t_gd2gce(&status); - t_gmst00(&status); - t_gmst06(&status); - t_gmst82(&status); - t_gst00a(&status); - t_gst00b(&status); - t_gst06(&status); - t_gst06a(&status); - t_gst94(&status); - t_h2fk5(&status); - t_hfk5z(&status); - t_icrs2g(&status); - t_ir(&status); - t_jd2cal(&status); - t_jdcalf(&status); - t_ld(&status); - t_ldn(&status); - t_ldsun(&status); - t_lteceq(&status); - t_ltecm(&status); - t_lteqec(&status); - t_ltp(&status); - t_ltpb(&status); - t_ltpecl(&status); - t_ltpequ(&status); - t_num00a(&status); - t_num00b(&status); - t_num06a(&status); - t_numat(&status); - t_nut00a(&status); - t_nut00b(&status); - t_nut06a(&status); - t_nut80(&status); - t_nutm80(&status); - t_obl06(&status); - t_obl80(&status); - t_p06e(&status); - t_p2pv(&status); - t_p2s(&status); - t_pap(&status); - t_pas(&status); - t_pb06(&status); - t_pdp(&status); - t_pfw06(&status); - t_plan94(&status); - t_pmat00(&status); - t_pmat06(&status); - t_pmat76(&status); - t_pm(&status); - t_pmp(&status); - t_pmpx(&status); - t_pmsafe(&status); - t_pn(&status); - t_pn00(&status); - t_pn00a(&status); - t_pn00b(&status); - t_pn06a(&status); - t_pn06(&status); - t_pnm00a(&status); - t_pnm00b(&status); - t_pnm06a(&status); - t_pnm80(&status); - t_pom00(&status); - t_ppp(&status); - t_ppsp(&status); - t_pr00(&status); - t_prec76(&status); - t_pv2p(&status); - t_pv2s(&status); - t_pvdpv(&status); - t_pvm(&status); - t_pvmpv(&status); - t_pvppv(&status); - t_pvstar(&status); - t_pvtob(&status); - t_pvu(&status); - t_pvup(&status); - t_pvxpv(&status); - t_pxp(&status); - t_refco(&status); - t_rm2v(&status); - t_rv2m(&status); - t_rx(&status); - t_rxp(&status); - t_rxpv(&status); - t_rxr(&status); - t_ry(&status); - t_rz(&status); - t_s00a(&status); - t_s00b(&status); - t_s00(&status); - t_s06a(&status); - t_s06(&status); - t_s2c(&status); - t_s2p(&status); - t_s2pv(&status); - t_s2xpv(&status); - t_sepp(&status); - t_seps(&status); - t_sp00(&status); - t_starpm(&status); - t_starpv(&status); - t_sxp(&status); - t_sxpv(&status); - t_taitt(&status); - t_taiut1(&status); - t_taiutc(&status); - t_tcbtdb(&status); - t_tcgtt(&status); - t_tdbtcb(&status); - t_tdbtt(&status); - t_tf2a(&status); - t_tf2d(&status); - t_tr(&status); - t_trxp(&status); - t_trxpv(&status); - t_tttai(&status); - t_tttcg(&status); - t_tttdb(&status); - t_ttut1(&status); - t_ut1tai(&status); - t_ut1tt(&status) ; - t_ut1utc(&status); - t_utctai(&status); - t_utcut1(&status); - t_xy06(&status); - t_xys00a(&status); - t_xys00b(&status); - t_xys06a(&status); - t_zp(&status); - t_zpv(&status); - t_zr(&status); - -/* Report, set up an appropriate exit status, and finish. */ - if (status) { - printf("t_erfa_c validation failed!\n"); - } else { - printf("t_erfa_c validation successful\n"); - } - return status; -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/taitt.c b/ast/erfa/taitt.c deleted file mode 100644 index 087399e..0000000 --- a/ast/erfa/taitt.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "erfa.h" - -int eraTaitt(double tai1, double tai2, double *tt1, double *tt2) -/* -** - - - - - - - - - -** e r a T a i t t -** - - - - - - - - - -** -** Time scale transformation: International Atomic Time, TAI, to -** Terrestrial Time, TT. -** -** Given: -** tai1,tai2 double TAI as a 2-part Julian Date -** -** Returned: -** tt1,tt2 double TT as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Note: -** -** tai1+tai2 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where tai1 is the Julian -** Day Number and tai2 is the fraction of a day. The returned -** tt1,tt2 follow suit. -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* TT minus TAI (days). */ - static const double dtat = ERFA_TTMTAI/ERFA_DAYSEC; - - -/* Result, safeguarding precision. */ - if ( tai1 > tai2 ) { - *tt1 = tai1; - *tt2 = tai2 + dtat; - } else { - *tt1 = tai1 + dtat; - *tt2 = tai2; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/taiut1.c b/ast/erfa/taiut1.c deleted file mode 100644 index 4a9a485..0000000 --- a/ast/erfa/taiut1.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "erfa.h" - -int eraTaiut1(double tai1, double tai2, double dta, - double *ut11, double *ut12) -/* -** - - - - - - - - - - -** e r a T a i u t 1 -** - - - - - - - - - - -** -** Time scale transformation: International Atomic Time, TAI, to -** Universal Time, UT1. -** -** Given: -** tai1,tai2 double TAI as a 2-part Julian Date -** dta double UT1-TAI in seconds -** -** Returned: -** ut11,ut12 double UT1 as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Notes: -** -** 1) tai1+tai2 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where tai1 is the Julian -** Day Number and tai2 is the fraction of a day. The returned -** UT11,UT12 follow suit. -** -** 2) The argument dta, i.e. UT1-TAI, is an observed quantity, and is -** available from IERS tabulations. -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dtad; - - -/* Result, safeguarding precision. */ - dtad = dta / ERFA_DAYSEC; - if ( tai1 > tai2 ) { - *ut11 = tai1; - *ut12 = tai2 + dtad; - } else { - *ut11 = tai1 + dtad; - *ut12 = tai2; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/taiutc.c b/ast/erfa/taiutc.c deleted file mode 100644 index ce3a177..0000000 --- a/ast/erfa/taiutc.c +++ /dev/null @@ -1,168 +0,0 @@ -#include "erfa.h" - -int eraTaiutc(double tai1, double tai2, double *utc1, double *utc2) -/* -** - - - - - - - - - - -** e r a T a i u t c -** - - - - - - - - - - -** -** Time scale transformation: International Atomic Time, TAI, to -** Coordinated Universal Time, UTC. -** -** Given: -** tai1,tai2 double TAI as a 2-part Julian Date (Note 1) -** -** Returned: -** utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 1-3) -** -** Returned (function value): -** int status: +1 = dubious year (Note 4) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) tai1+tai2 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where tai1 is the Julian -** Day Number and tai2 is the fraction of a day. The returned utc1 -** and utc2 form an analogous pair, except that a special convention -** is used, to deal with the problem of leap seconds - see the next -** note. -** -** 2) JD cannot unambiguously represent UTC during a leap second unless -** special measures are taken. The convention in the present -** function is that the JD day represents UTC days whether the -** length is 86399, 86400 or 86401 SI seconds. In the 1960-1972 era -** there were smaller jumps (in either direction) each time the -** linear UTC(TAI) expression was changed, and these "mini-leaps" -** are also included in the ERFA convention. -** -** 3) The function eraD2dtf can be used to transform the UTC quasi-JD -** into calendar date and clock time, including UTC leap second -** handling. -** -** 4) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the future -** to be trusted. See eraDat for further details. -** -** Called: -** eraUtctai UTC to TAI -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int big1; - int i, j; - double a1, a2, u1, u2, g1, g2; - - -/* Put the two parts of the TAI into big-first order. */ - big1 = ( tai1 >= tai2 ); - if ( big1 ) { - a1 = tai1; - a2 = tai2; - } else { - a1 = tai2; - a2 = tai1; - } - -/* Initial guess for UTC. */ - u1 = a1; - u2 = a2; - -/* Iterate (though in most cases just once is enough). */ - for ( i = 0; i < 3; i++ ) { - - /* Guessed UTC to TAI. */ - j = eraUtctai(u1, u2, &g1, &g2); - if ( j < 0 ) return j; - - /* Adjust guessed UTC. */ - u2 += a1 - g1; - u2 += a2 - g2; - } - -/* Return the UTC result, preserving the TAI order. */ - if ( big1 ) { - *utc1 = u1; - *utc2 = u2; - } else { - *utc1 = u2; - *utc2 = u1; - } - -/* Status. */ - return j; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tcbtdb.c b/ast/erfa/tcbtdb.c deleted file mode 100644 index 007af2e..0000000 --- a/ast/erfa/tcbtdb.c +++ /dev/null @@ -1,141 +0,0 @@ -#include "erfa.h" - -int eraTcbtdb(double tcb1, double tcb2, double *tdb1, double *tdb2) -/* -** - - - - - - - - - - -** e r a T c b t d b -** - - - - - - - - - - -** -** Time scale transformation: Barycentric Coordinate Time, TCB, to -** Barycentric Dynamical Time, TDB. -** -** Given: -** tcb1,tcb2 double TCB as a 2-part Julian Date -** -** Returned: -** tdb1,tdb2 double TDB as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Notes: -** -** 1) tcb1+tcb2 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where tcb1 is the Julian -** Day Number and tcb2 is the fraction of a day. The returned -** tdb1,tdb2 follow suit. -** -** 2) The 2006 IAU General Assembly introduced a conventional linear -** transformation between TDB and TCB. This transformation -** compensates for the drift between TCB and terrestrial time TT, -** and keeps TDB approximately centered on TT. Because the -** relationship between TT and TCB depends on the adopted solar -** system ephemeris, the degree of alignment between TDB and TT over -** long intervals will vary according to which ephemeris is used. -** Former definitions of TDB attempted to avoid this problem by -** stipulating that TDB and TT should differ only by periodic -** effects. This is a good description of the nature of the -** relationship but eluded precise mathematical formulation. The -** conventional linear relationship adopted in 2006 sidestepped -** these difficulties whilst delivering a TDB that in practice was -** consistent with values before that date. -** -** 3) TDB is essentially the same as Teph, the time argument for the -** JPL solar system ephemerides. -** -** Reference: -** -** IAU 2006 Resolution B3 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* 1977 Jan 1 00:00:32.184 TT, as two-part JD */ - static const double t77td = ERFA_DJM0 + ERFA_DJM77; - static const double t77tf = ERFA_TTMTAI/ERFA_DAYSEC; - -/* TDB (days) at TAI 1977 Jan 1.0 */ - static const double tdb0 = ERFA_TDB0/ERFA_DAYSEC; - - double d; - - -/* Result, safeguarding precision. */ - if ( tcb1 > tcb2 ) { - d = tcb1 - t77td; - *tdb1 = tcb1; - *tdb2 = tcb2 + tdb0 - ( d + ( tcb2 - t77tf ) ) * ERFA_ELB; - } else { - d = tcb2 - t77td; - *tdb1 = tcb1 + tdb0 - ( d + ( tcb1 - t77tf ) ) * ERFA_ELB; - *tdb2 = tcb2; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tcgtt.c b/ast/erfa/tcgtt.c deleted file mode 100644 index 0e463b4..0000000 --- a/ast/erfa/tcgtt.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "erfa.h" - -int eraTcgtt(double tcg1, double tcg2, double *tt1, double *tt2) -/* -** - - - - - - - - - -** e r a T c g t t -** - - - - - - - - - -** -** Time scale transformation: Geocentric Coordinate Time, TCG, to -** Terrestrial Time, TT. -** -** Given: -** tcg1,tcg2 double TCG as a 2-part Julian Date -** -** Returned: -** tt1,tt2 double TT as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Note: -** -** tcg1+tcg2 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where tcg1 is the Julian -** Day Number and tcg22 is the fraction of a day. The returned -** tt1,tt2 follow suit. -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),. -** IERS Technical Note No. 32, BKG (2004) -** -** IAU 2000 Resolution B1.9 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* 1977 Jan 1 00:00:32.184 TT, as MJD */ - static const double t77t = ERFA_DJM77 + ERFA_TTMTAI/ERFA_DAYSEC; - - -/* Result, safeguarding precision. */ - if ( tcg1 > tcg2 ) { - *tt1 = tcg1; - *tt2 = tcg2 - ( ( tcg1 - ERFA_DJM0 ) + ( tcg2 - t77t ) ) * ERFA_ELG; - } else { - *tt1 = tcg1 - ( ( tcg2 - ERFA_DJM0 ) + ( tcg1 - t77t ) ) * ERFA_ELG; - *tt2 = tcg2; - } - -/* OK status. */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tdbtcb.c b/ast/erfa/tdbtcb.c deleted file mode 100644 index c12f807..0000000 --- a/ast/erfa/tdbtcb.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "erfa.h" - -int eraTdbtcb(double tdb1, double tdb2, double *tcb1, double *tcb2) -/* -** - - - - - - - - - - -** e r a T d b t c b -** - - - - - - - - - - -** -** Time scale transformation: Barycentric Dynamical Time, TDB, to -** Barycentric Coordinate Time, TCB. -** -** Given: -** tdb1,tdb2 double TDB as a 2-part Julian Date -** -** Returned: -** tcb1,tcb2 double TCB as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Notes: -** -** 1) tdb1+tdb2 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where tdb1 is the Julian -** Day Number and tdb2 is the fraction of a day. The returned -** tcb1,tcb2 follow suit. -** -** 2) The 2006 IAU General Assembly introduced a conventional linear -** transformation between TDB and TCB. This transformation -** compensates for the drift between TCB and terrestrial time TT, -** and keeps TDB approximately centered on TT. Because the -** relationship between TT and TCB depends on the adopted solar -** system ephemeris, the degree of alignment between TDB and TT over -** long intervals will vary according to which ephemeris is used. -** Former definitions of TDB attempted to avoid this problem by -** stipulating that TDB and TT should differ only by periodic -** effects. This is a good description of the nature of the -** relationship but eluded precise mathematical formulation. The -** conventional linear relationship adopted in 2006 sidestepped -** these difficulties whilst delivering a TDB that in practice was -** consistent with values before that date. -** -** 3) TDB is essentially the same as Teph, the time argument for the -** JPL solar system ephemerides. -** -** Reference: -** -** IAU 2006 Resolution B3 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* 1977 Jan 1 00:00:32.184 TT, as two-part JD */ - static const double t77td = ERFA_DJM0 + ERFA_DJM77; - static const double t77tf = ERFA_TTMTAI/ERFA_DAYSEC; - -/* TDB (days) at TAI 1977 Jan 1.0 */ - static const double tdb0 = ERFA_TDB0/ERFA_DAYSEC; - -/* TDB to TCB rate */ - static const double elbb = ERFA_ELB/(1.0-ERFA_ELB); - - double d, f; - - -/* Result, preserving date format but safeguarding precision. */ - if ( tdb1 > tdb2 ) { - d = t77td - tdb1; - f = tdb2 - tdb0; - *tcb1 = tdb1; - *tcb2 = f - ( d - ( f - t77tf ) ) * elbb; - } else { - d = t77td - tdb2; - f = tdb1 - tdb0; - *tcb1 = f + ( d - ( f - t77tf ) ) * elbb; - *tcb2 = tdb2; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tdbtt.c b/ast/erfa/tdbtt.c deleted file mode 100644 index 879ffe5..0000000 --- a/ast/erfa/tdbtt.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "erfa.h" - -int eraTdbtt(double tdb1, double tdb2, double dtr, - double *tt1, double *tt2 ) -/* -** - - - - - - - - - -** e r a T d b t t -** - - - - - - - - - -** -** Time scale transformation: Barycentric Dynamical Time, TDB, to -** Terrestrial Time, TT. -** -** Given: -** tdb1,tdb2 double TDB as a 2-part Julian Date -** dtr double TDB-TT in seconds -** -** Returned: -** tt1,tt2 double TT as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Notes: -** -** 1) tdb1+tdb2 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where tdb1 is the Julian -** Day Number and tdb2 is the fraction of a day. The returned -** tt1,tt2 follow suit. -** -** 2) The argument dtr represents the quasi-periodic component of the -** GR transformation between TT and TCB. It is dependent upon the -** adopted solar-system ephemeris, and can be obtained by numerical -** integration, by interrogating a precomputed time ephemeris or by -** evaluating a model such as that implemented in the ERFA function -** eraDtdb. The quantity is dominated by an annual term of 1.7 ms -** amplitude. -** -** 3) TDB is essentially the same as Teph, the time argument for the -** JPL solar system ephemerides. -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** IAU 2006 Resolution 3 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dtrd; - - -/* Result, safeguarding precision. */ - dtrd = dtr / ERFA_DAYSEC; - if ( tdb1 > tdb2 ) { - *tt1 = tdb1; - *tt2 = tdb2 - dtrd; - } else { - *tt1 = tdb1 - dtrd; - *tt2 = tdb2; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tf2a.c b/ast/erfa/tf2a.c deleted file mode 100644 index 678a33d..0000000 --- a/ast/erfa/tf2a.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "erfa.h" -#include - -int eraTf2a(char s, int ihour, int imin, double sec, double *rad) -/* -** - - - - - - - - -** e r a T f 2 a -** - - - - - - - - -** -** Convert hours, minutes, seconds to radians. -** -** Given: -** s char sign: '-' = negative, otherwise positive -** ihour int hours -** imin int minutes -** sec double seconds -** -** Returned: -** rad double angle in radians -** -** Returned (function value): -** int status: 0 = OK -** 1 = ihour outside range 0-23 -** 2 = imin outside range 0-59 -** 3 = sec outside range 0-59.999... -** -** Notes: -** -** 1) The result is computed even if any of the range checks fail. -** -** 2) Negative ihour, imin and/or sec produce a warning status, but -** the absolute value is used in the conversion. -** -** 3) If there are multiple errors, the status value reflects only the -** first, the smallest taking precedence. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* Compute the interval. */ - *rad = ( s == '-' ? -1.0 : 1.0 ) * - ( 60.0 * ( 60.0 * ( (double) abs(ihour) ) + - ( (double) abs(imin) ) ) + - fabs(sec) ) * ERFA_DS2R; - -/* Validate arguments and return status. */ - if ( ihour < 0 || ihour > 23 ) return 1; - if ( imin < 0 || imin > 59 ) return 2; - if ( sec < 0.0 || sec >= 60.0 ) return 3; - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tf2d.c b/ast/erfa/tf2d.c deleted file mode 100644 index 3936bfc..0000000 --- a/ast/erfa/tf2d.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "erfa.h" -#include - -int eraTf2d(char s, int ihour, int imin, double sec, double *days) -/* -** - - - - - - - - -** e r a T f 2 d -** - - - - - - - - -** -** Convert hours, minutes, seconds to days. -** -** Given: -** s char sign: '-' = negative, otherwise positive -** ihour int hours -** imin int minutes -** sec double seconds -** -** Returned: -** days double interval in days -** -** Returned (function value): -** int status: 0 = OK -** 1 = ihour outside range 0-23 -** 2 = imin outside range 0-59 -** 3 = sec outside range 0-59.999... -** -** Notes: -** -** 1) The result is computed even if any of the range checks fail. -** -** 2) Negative ihour, imin and/or sec produce a warning status, but -** the absolute value is used in the conversion. -** -** 3) If there are multiple errors, the status value reflects only the -** first, the smallest taking precedence. -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* Compute the interval. */ - *days = ( s == '-' ? -1.0 : 1.0 ) * - ( 60.0 * ( 60.0 * ( (double) abs(ihour) ) + - ( (double) abs(imin) ) ) + - fabs(sec) ) / ERFA_DAYSEC; - -/* Validate arguments and return status. */ - if ( ihour < 0 || ihour > 23 ) return 1; - if ( imin < 0 || imin > 59 ) return 2; - if ( sec < 0.0 || sec >= 60.0 ) return 3; - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tr.c b/ast/erfa/tr.c deleted file mode 100644 index d49dc27..0000000 --- a/ast/erfa/tr.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "erfa.h" - -void eraTr(double r[3][3], double rt[3][3]) -/* -** - - - - - - -** e r a T r -** - - - - - - -** -** Transpose an r-matrix. -** -** Given: -** r double[3][3] r-matrix -** -** Returned: -** rt double[3][3] transpose -** -** Note: -** It is permissible for r and rt to be the same array. -** -** Called: -** eraCr copy r-matrix -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double wm[3][3]; - int i, j; - - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - wm[i][j] = r[j][i]; - } - } - eraCr(wm, rt); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/trxp.c b/ast/erfa/trxp.c deleted file mode 100644 index eaba6f1..0000000 --- a/ast/erfa/trxp.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "erfa.h" - -void eraTrxp(double r[3][3], double p[3], double trp[3]) -/* -** - - - - - - - - -** e r a T r x p -** - - - - - - - - -** -** Multiply a p-vector by the transpose of an r-matrix. -** -** Given: -** r double[3][3] r-matrix -** p double[3] p-vector -** -** Returned: -** trp double[3] r * p -** -** Note: -** It is permissible for p and trp to be the same array. -** -** Called: -** eraTr transpose r-matrix -** eraRxp product of r-matrix and p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double tr[3][3]; - - -/* Transpose of matrix r. */ - eraTr(r, tr); - -/* Matrix tr * vector p -> vector trp. */ - eraRxp(tr, p, trp); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/trxpv.c b/ast/erfa/trxpv.c deleted file mode 100644 index ce6e5ae..0000000 --- a/ast/erfa/trxpv.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "erfa.h" - -void eraTrxpv(double r[3][3], double pv[2][3], double trpv[2][3]) -/* -** - - - - - - - - - -** e r a T r x p v -** - - - - - - - - - -** -** Multiply a pv-vector by the transpose of an r-matrix. -** -** Given: -** r double[3][3] r-matrix -** pv double[2][3] pv-vector -** -** Returned: -** trpv double[2][3] r * pv -** -** Note: -** It is permissible for pv and trpv to be the same array. -** -** Called: -** eraTr transpose r-matrix -** eraRxpv product of r-matrix and pv-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double tr[3][3]; - - -/* Transpose of matrix r. */ - eraTr(r, tr); - -/* Matrix tr * vector pv -> vector trpv. */ - eraRxpv(tr, pv, trpv); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tttai.c b/ast/erfa/tttai.c deleted file mode 100644 index 0392aee..0000000 --- a/ast/erfa/tttai.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "erfa.h" - -int eraTttai(double tt1, double tt2, double *tai1, double *tai2) -/* -** - - - - - - - - - -** e r a T t t a i -** - - - - - - - - - -** -** Time scale transformation: Terrestrial Time, TT, to International -** Atomic Time, TAI. -** -** Given: -** tt1,tt2 double TT as a 2-part Julian Date -** -** Returned: -** tai1,tai2 double TAI as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Note: -** -** tt1+tt2 is Julian Date, apportioned in any convenient way between -** the two arguments, for example where tt1 is the Julian Day Number -** and tt2 is the fraction of a day. The returned tai1,tai2 follow -** suit. -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* TT minus TAI (days). */ - static const double dtat = ERFA_TTMTAI/ERFA_DAYSEC; - - -/* Result, safeguarding precision. */ - if ( tt1 > tt2 ) { - *tai1 = tt1; - *tai2 = tt2 - dtat; - } else { - *tai1 = tt1 - dtat; - *tai2 = tt2; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tttcg.c b/ast/erfa/tttcg.c deleted file mode 100644 index a0367dc..0000000 --- a/ast/erfa/tttcg.c +++ /dev/null @@ -1,121 +0,0 @@ -#include "erfa.h" - -int eraTttcg(double tt1, double tt2, double *tcg1, double *tcg2) -/* -** - - - - - - - - - -** e r a T t t c g -** - - - - - - - - - -** -** Time scale transformation: Terrestrial Time, TT, to Geocentric -** Coordinate Time, TCG. -** -** Given: -** tt1,tt2 double TT as a 2-part Julian Date -** -** Returned: -** tcg1,tcg2 double TCG as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Note: -** -** tt1+tt2 is Julian Date, apportioned in any convenient way between -** the two arguments, for example where tt1 is the Julian Day Number -** and tt2 is the fraction of a day. The returned tcg1,tcg2 follow -** suit. -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** IAU 2000 Resolution B1.9 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* 1977 Jan 1 00:00:32.184 TT, as MJD */ - static const double t77t = ERFA_DJM77 + ERFA_TTMTAI/ERFA_DAYSEC; - -/* TT to TCG rate */ - static const double elgg = ERFA_ELG/(1.0-ERFA_ELG); - - -/* Result, safeguarding precision. */ - if ( tt1 > tt2 ) { - *tcg1 = tt1; - *tcg2 = tt2 + ( ( tt1 - ERFA_DJM0 ) + ( tt2 - t77t ) ) * elgg; - } else { - *tcg1 = tt1 + ( ( tt2 - ERFA_DJM0 ) + ( tt1 - t77t ) ) * elgg; - *tcg2 = tt2; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/tttdb.c b/ast/erfa/tttdb.c deleted file mode 100644 index 2d59625..0000000 --- a/ast/erfa/tttdb.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "erfa.h" - -int eraTttdb(double tt1, double tt2, double dtr, - double *tdb1, double *tdb2) -/* -** - - - - - - - - - -** e r a T t t d b -** - - - - - - - - - -** -** Time scale transformation: Terrestrial Time, TT, to Barycentric -** Dynamical Time, TDB. -** -** Given: -** tt1,tt2 double TT as a 2-part Julian Date -** dtr double TDB-TT in seconds -** -** Returned: -** tdb1,tdb2 double TDB as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Notes: -** -** 1) tt1+tt2 is Julian Date, apportioned in any convenient way between -** the two arguments, for example where tt1 is the Julian Day Number -** and tt2 is the fraction of a day. The returned tdb1,tdb2 follow -** suit. -** -** 2) The argument dtr represents the quasi-periodic component of the -** GR transformation between TT and TCB. It is dependent upon the -** adopted solar-system ephemeris, and can be obtained by numerical -** integration, by interrogating a precomputed time ephemeris or by -** evaluating a model such as that implemented in the ERFA function -** eraDtdb. The quantity is dominated by an annual term of 1.7 ms -** amplitude. -** -** 3) TDB is essentially the same as Teph, the time argument for the JPL -** solar system ephemerides. -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** IAU 2006 Resolution 3 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dtrd; - - -/* Result, safeguarding precision. */ - dtrd = dtr / ERFA_DAYSEC; - if ( tt1 > tt2 ) { - *tdb1 = tt1; - *tdb2 = tt2 + dtrd; - } else { - *tdb1 = tt1 + dtrd; - *tdb2 = tt2; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ttut1.c b/ast/erfa/ttut1.c deleted file mode 100644 index b225f3a..0000000 --- a/ast/erfa/ttut1.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "erfa.h" - -int eraTtut1(double tt1, double tt2, double dt, - double *ut11, double *ut12) -/* -** - - - - - - - - - -** e r a T t u t 1 -** - - - - - - - - - -** -** Time scale transformation: Terrestrial Time, TT, to Universal Time, -** UT1. -** -** Given: -** tt1,tt2 double TT as a 2-part Julian Date -** dt double TT-UT1 in seconds -** -** Returned: -** ut11,ut12 double UT1 as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Notes: -** -** 1) tt1+tt2 is Julian Date, apportioned in any convenient way between -** the two arguments, for example where tt1 is the Julian Day Number -** and tt2 is the fraction of a day. The returned ut11,ut12 follow -** suit. -** -** 2) The argument dt is classical Delta T. -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dtd; - - -/* Result, safeguarding precision. */ - dtd = dt / ERFA_DAYSEC; - if ( tt1 > tt2 ) { - *ut11 = tt1; - *ut12 = tt2 - dtd; - } else { - *ut11 = tt1 - dtd; - *ut12 = tt2; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ut1tai.c b/ast/erfa/ut1tai.c deleted file mode 100644 index 34a87c6..0000000 --- a/ast/erfa/ut1tai.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "erfa.h" - -int eraUt1tai(double ut11, double ut12, double dta, - double *tai1, double *tai2) -/* -** - - - - - - - - - - -** e r a U t 1 t a i -** - - - - - - - - - - -** -** Time scale transformation: Universal Time, UT1, to International -** Atomic Time, TAI. -** -** Given: -** ut11,ut12 double UT1 as a 2-part Julian Date -** dta double UT1-TAI in seconds -** -** Returned: -** tai1,tai2 double TAI as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Notes: -** -** 1) ut11+ut12 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where ut11 is the Julian -** Day Number and ut12 is the fraction of a day. The returned -** tai1,tai2 follow suit. -** -** 2) The argument dta, i.e. UT1-TAI, is an observed quantity, and is -** available from IERS tabulations. -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dtad; - - -/* Result, safeguarding precision. */ - dtad = dta / ERFA_DAYSEC; - if ( ut11 > ut12 ) { - *tai1 = ut11; - *tai2 = ut12 - dtad; - } else { - *tai1 = ut11 - dtad; - *tai2 = ut12; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ut1tt.c b/ast/erfa/ut1tt.c deleted file mode 100644 index 56964e0..0000000 --- a/ast/erfa/ut1tt.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "erfa.h" - -int eraUt1tt(double ut11, double ut12, double dt, - double *tt1, double *tt2) -/* -** - - - - - - - - - -** e r a U t 1 t t -** - - - - - - - - - -** -** Time scale transformation: Universal Time, UT1, to Terrestrial -** Time, TT. -** -** Given: -** ut11,ut12 double UT1 as a 2-part Julian Date -** dt double TT-UT1 in seconds -** -** Returned: -** tt1,tt2 double TT as a 2-part Julian Date -** -** Returned (function value): -** int status: 0 = OK -** -** Notes: -** -** 1) ut11+ut12 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where ut11 is the Julian -** Day Number and ut12 is the fraction of a day. The returned -** tt1,tt2 follow suit. -** -** 2) The argument dt is classical Delta T. -** -** Reference: -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double dtd; - - -/* Result, safeguarding precision. */ - dtd = dt / ERFA_DAYSEC; - if ( ut11 > ut12 ) { - *tt1 = ut11; - *tt2 = ut12 + dtd; - } else { - *tt1 = ut11 + dtd; - *tt2 = ut12; - } - -/* Status (always OK). */ - return 0; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/ut1utc.c b/ast/erfa/ut1utc.c deleted file mode 100644 index 6ec1b44..0000000 --- a/ast/erfa/ut1utc.c +++ /dev/null @@ -1,202 +0,0 @@ -#include "erfa.h" - -int eraUt1utc(double ut11, double ut12, double dut1, - double *utc1, double *utc2) -/* -** - - - - - - - - - - -** e r a U t 1 u t c -** - - - - - - - - - - -** -** Time scale transformation: Universal Time, UT1, to Coordinated -** Universal Time, UTC. -** -** Given: -** ut11,ut12 double UT1 as a 2-part Julian Date (Note 1) -** dut1 double Delta UT1: UT1-UTC in seconds (Note 2) -** -** Returned: -** utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 3,4) -** -** Returned (function value): -** int status: +1 = dubious year (Note 5) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) ut11+ut12 is Julian Date, apportioned in any convenient way -** between the two arguments, for example where ut11 is the Julian -** Day Number and ut12 is the fraction of a day. The returned utc1 -** and utc2 form an analogous pair, except that a special convention -** is used, to deal with the problem of leap seconds - see Note 3. -** -** 2) Delta UT1 can be obtained from tabulations provided by the -** International Earth Rotation and Reference Systems Service. The -** value changes abruptly by 1s at a leap second; however, close to -** a leap second the algorithm used here is tolerant of the "wrong" -** choice of value being made. -** -** 3) JD cannot unambiguously represent UTC during a leap second unless -** special measures are taken. The convention in the present -** function is that the returned quasi JD day UTC1+UTC2 represents -** UTC days whether the length is 86399, 86400 or 86401 SI seconds. -** -** 4) The function eraD2dtf can be used to transform the UTC quasi-JD -** into calendar date and clock time, including UTC leap second -** handling. -** -** 5) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the future -** to be trusted. See eraDat for further details. -** -** Called: -** eraJd2cal JD to Gregorian calendar -** eraDat delta(AT) = TAI-UTC -** eraCal2jd Gregorian calendar to JD -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int big1; - int i, iy, im, id, js; - double duts, u1, u2, d1, dats1, d2, fd, dats2, ddats, us1, us2, du; - - -/* UT1-UTC in seconds. */ - duts = dut1; - -/* Put the two parts of the UT1 into big-first order. */ - big1 = ( ut11 >= ut12 ); - if ( big1 ) { - u1 = ut11; - u2 = ut12; - } else { - u1 = ut12; - u2 = ut11; - } - -/* See if the UT1 can possibly be in a leap-second day. */ - d1 = u1; - dats1 = 0; - for ( i = -1; i <= 3; i++ ) { - d2 = u2 + (double) i; - if ( eraJd2cal(d1, d2, &iy, &im, &id, &fd) ) return -1; - js = eraDat(iy, im, id, 0.0, &dats2); - if ( js < 0 ) return -1; - if ( i == - 1 ) dats1 = dats2; - ddats = dats2 - dats1; - if ( fabs(ddats) >= 0.5 ) { - - /* Yes, leap second nearby: ensure UT1-UTC is "before" value. */ - if ( ddats * duts >= 0 ) duts -= ddats; - - /* UT1 for the start of the UTC day that ends in a leap. */ - if ( eraCal2jd(iy, im, id, &d1, &d2) ) return -1; - us1 = d1; - us2 = d2 - 1.0 + duts/ERFA_DAYSEC; - - /* Is the UT1 after this point? */ - du = u1 - us1; - du += u2 - us2; - if ( du > 0 ) { - - /* Yes: fraction of the current UTC day that has elapsed. */ - fd = du * ERFA_DAYSEC / ( ERFA_DAYSEC + ddats ); - - /* Ramp UT1-UTC to bring about ERFA's JD(UTC) convention. */ - duts += ddats * ( fd <= 1.0 ? fd : 1.0 ); - } - - /* Done. */ - break; - } - dats1 = dats2; - } - -/* Subtract the (possibly adjusted) UT1-UTC from UT1 to give UTC. */ - u2 -= duts / ERFA_DAYSEC; - -/* Result, safeguarding precision. */ - if ( big1 ) { - *utc1 = u1; - *utc2 = u2; - } else { - *utc1 = u2; - *utc2 = u1; - } - -/* Status. */ - return js; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/utctai.c b/ast/erfa/utctai.c deleted file mode 100644 index 2863867..0000000 --- a/ast/erfa/utctai.c +++ /dev/null @@ -1,186 +0,0 @@ -#include "erfa.h" - -int eraUtctai(double utc1, double utc2, double *tai1, double *tai2) -/* -** - - - - - - - - - - -** e r a U t c t a i -** - - - - - - - - - - -** -** Time scale transformation: Coordinated Universal Time, UTC, to -** International Atomic Time, TAI. -** -** Given: -** utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 1-4) -** -** Returned: -** tai1,tai2 double TAI as a 2-part Julian Date (Note 5) -** -** Returned (function value): -** int status: +1 = dubious year (Note 3) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any -** convenient way between the two arguments, for example where utc1 -** is the Julian Day Number and utc2 is the fraction of a day. -** -** 2) JD cannot unambiguously represent UTC during a leap second unless -** special measures are taken. The convention in the present -** function is that the JD day represents UTC days whether the -** length is 86399, 86400 or 86401 SI seconds. In the 1960-1972 era -** there were smaller jumps (in either direction) each time the -** linear UTC(TAI) expression was changed, and these "mini-leaps" -** are also included in the ERFA convention. -** -** 3) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the future -** to be trusted. See eraDat for further details. -** -** 4) The function eraDtf2d converts from calendar date and time of day -** into 2-part Julian Date, and in the case of UTC implements the -** leap-second-ambiguity convention described above. -** -** 5) The returned TAI1,TAI2 are such that their sum is the TAI Julian -** Date. -** -** Called: -** eraJd2cal JD to Gregorian calendar -** eraDat delta(AT) = TAI-UTC -** eraCal2jd Gregorian calendar to JD -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int big1; - int iy, im, id, j, iyt, imt, idt; - double u1, u2, fd, dat0, dat12, w, dat24, dlod, dleap, z1, z2, a2; - - -/* Put the two parts of the UTC into big-first order. */ - big1 = ( utc1 >= utc2 ); - if ( big1 ) { - u1 = utc1; - u2 = utc2; - } else { - u1 = utc2; - u2 = utc1; - } - -/* Get TAI-UTC at 0h today. */ - j = eraJd2cal(u1, u2, &iy, &im, &id, &fd); - if ( j ) return j; - j = eraDat(iy, im, id, 0.0, &dat0); - if ( j < 0 ) return j; - -/* Get TAI-UTC at 12h today (to detect drift). */ - j = eraDat(iy, im, id, 0.5, &dat12); - if ( j < 0 ) return j; - -/* Get TAI-UTC at 0h tomorrow (to detect jumps). */ - j = eraJd2cal(u1+1.5, u2-fd, &iyt, &imt, &idt, &w); - if ( j ) return j; - j = eraDat(iyt, imt, idt, 0.0, &dat24); - if ( j < 0 ) return j; - -/* Separate TAI-UTC change into per-day (DLOD) and any jump (DLEAP). */ - dlod = 2.0 * (dat12 - dat0); - dleap = dat24 - (dat0 + dlod); - -/* Remove any scaling applied to spread leap into preceding day. */ - fd *= (ERFA_DAYSEC+dleap)/ERFA_DAYSEC; - -/* Scale from (pre-1972) UTC seconds to SI seconds. */ - fd *= (ERFA_DAYSEC+dlod)/ERFA_DAYSEC; - -/* Today's calendar date to 2-part JD. */ - if ( eraCal2jd(iy, im, id, &z1, &z2) ) return -1; - -/* Assemble the TAI result, preserving the UTC split and order. */ - a2 = z1 - u1; - a2 += z2; - a2 += fd + dat0/ERFA_DAYSEC; - if ( big1 ) { - *tai1 = u1; - *tai2 = a2; - } else { - *tai1 = a2; - *tai2 = u1; - } - -/* Status. */ - return j; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/utcut1.c b/ast/erfa/utcut1.c deleted file mode 100644 index 1ab4e94..0000000 --- a/ast/erfa/utcut1.c +++ /dev/null @@ -1,156 +0,0 @@ -#include "erfa.h" - -int eraUtcut1(double utc1, double utc2, double dut1, - double *ut11, double *ut12) -/* -** - - - - - - - - - - -** e r a U t c u t 1 -** - - - - - - - - - - -** -** Time scale transformation: Coordinated Universal Time, UTC, to -** Universal Time, UT1. -** -** Given: -** utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 1-4) -** dut1 double Delta UT1 = UT1-UTC in seconds (Note 5) -** -** Returned: -** ut11,ut12 double UT1 as a 2-part Julian Date (Note 6) -** -** Returned (function value): -** int status: +1 = dubious year (Note 3) -** 0 = OK -** -1 = unacceptable date -** -** Notes: -** -** 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any -** convenient way between the two arguments, for example where utc1 -** is the Julian Day Number and utc2 is the fraction of a day. -** -** 2) JD cannot unambiguously represent UTC during a leap second unless -** special measures are taken. The convention in the present -** function is that the JD day represents UTC days whether the -** length is 86399, 86400 or 86401 SI seconds. -** -** 3) The warning status "dubious year" flags UTCs that predate the -** introduction of the time scale or that are too far in the future -** to be trusted. See eraDat for further details. -** -** 4) The function eraDtf2d converts from calendar date and time of -** day into 2-part Julian Date, and in the case of UTC implements -** the leap-second-ambiguity convention described above. -** -** 5) Delta UT1 can be obtained from tabulations provided by the -** International Earth Rotation and Reference Systems Service. -** It is the caller's responsibility to supply a dut1 argument -** containing the UT1-UTC value that matches the given UTC. -** -** 6) The returned ut11,ut12 are such that their sum is the UT1 Julian -** Date. -** -** References: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Explanatory Supplement to the Astronomical Almanac, -** P. Kenneth Seidelmann (ed), University Science Books (1992) -** -** Called: -** eraJd2cal JD to Gregorian calendar -** eraDat delta(AT) = TAI-UTC -** eraUtctai UTC to TAI -** eraTaiut1 TAI to UT1 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - int iy, im, id, js, jw; - double w, dat, dta, tai1, tai2; - - -/* Look up TAI-UTC. */ - if ( eraJd2cal(utc1, utc2, &iy, &im, &id, &w) ) return -1; - js = eraDat ( iy, im, id, 0.0, &dat); - if ( js < 0 ) return -1; - -/* Form UT1-TAI. */ - dta = dut1 - dat; - -/* UTC to TAI to UT1. */ - jw = eraUtctai(utc1, utc2, &tai1, &tai2); - if ( jw < 0 ) { - return -1; - } else if ( jw > 0 ) { - js = jw; - } - if ( eraTaiut1(tai1, tai2, dta, ut11, ut12) ) return -1; - -/* Status. */ - return js; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/xy06.c b/ast/erfa/xy06.c deleted file mode 100644 index 67079b4..0000000 --- a/ast/erfa/xy06.c +++ /dev/null @@ -1,2767 +0,0 @@ -#include "erfa.h" - -void eraXy06(double date1, double date2, double *x, double *y) -/* -** - - - - - - - - -** e r a X y 0 6 -** - - - - - - - - -** -** X,Y coordinates of celestial intermediate pole from series based -** on IAU 2006 precession and IAU 2000A nutation. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** x,y double CIP X,Y coordinates (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The X,Y coordinates are those of the unit vector towards the -** celestial intermediate pole. They represent the combined effects -** of frame bias, precession and nutation. -** -** 3) The fundamental arguments used are as adopted in IERS Conventions -** (2003) and are from Simon et al. (1994) and Souchay et al. -** (1999). -** -** 4) This is an alternative to the angles-based method, via the ERFA -** function eraFw2xy and as used in eraXys06a for example. The two -** methods agree at the 1 microarcsecond level (at present), a -** negligible amount compared with the intrinsic accuracy of the -** models. However, it would be unwise to mix the two methods -** (angles-based and series-based) in a single application. -** -** Called: -** eraFal03 mean anomaly of the Moon -** eraFalp03 mean anomaly of the Sun -** eraFaf03 mean argument of the latitude of the Moon -** eraFad03 mean elongation of the Moon from the Sun -** eraFaom03 mean longitude of the Moon's ascending node -** eraFame03 mean longitude of Mercury -** eraFave03 mean longitude of Venus -** eraFae03 mean longitude of Earth -** eraFama03 mean longitude of Mars -** eraFaju03 mean longitude of Jupiter -** eraFasa03 mean longitude of Saturn -** eraFaur03 mean longitude of Uranus -** eraFane03 mean longitude of Neptune -** eraFapa03 general accumulated precession in longitude -** -** References: -** -** Capitaine, N., Wallace, P.T. & Chapront, J., 2003, -** Astron.Astrophys., 412, 567 -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855 -** -** McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003), -** IERS Technical Note No. 32, BKG -** -** Simon, J.L., Bretagnon, P., Chapront, J., Chapront-Touze, M., -** Francou, G. & Laskar, J., Astron.Astrophys., 1994, 282, 663 -** -** Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M., 1999, -** Astron.Astrophys.Supp.Ser. 135, 111 -** -** Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - -/* Maximum power of T in the polynomials for X and Y */ - enum { MAXPT = 5 }; - -/* Polynomial coefficients (arcsec, X then Y). */ - static const double xyp[2][MAXPT+1] = { - - { -0.016617, - 2004.191898, - -0.4297829, - -0.19861834, - 0.000007578, - 0.0000059285 - }, - { -0.006951, - -0.025896, - -22.4072747, - 0.00190059, - 0.001112526, - 0.0000001358 - } - }; - -/* Fundamental-argument multipliers: luni-solar terms */ - static const int mfals[][5] = { - - /* 1-10 */ - { 0, 0, 0, 0, 1 }, - { 0, 0, 2, -2, 2 }, - { 0, 0, 2, 0, 2 }, - { 0, 0, 0, 0, 2 }, - { 0, 1, 0, 0, 0 }, - { 0, 1, 2, -2, 2 }, - { 1, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 1 }, - { 1, 0, 2, 0, 2 }, - { 0, 1, -2, 2, -2 }, - - /* 11-20 */ - { 0, 0, 2, -2, 1 }, - { 1, 0, -2, 0, -2 }, - { 1, 0, 0, -2, 0 }, - { 1, 0, 0, 0, 1 }, - { 1, 0, 0, 0, -1 }, - { 1, 0, -2, -2, -2 }, - { 1, 0, 2, 0, 1 }, - { 2, 0, -2, 0, -1 }, - { 0, 0, 0, 2, 0 }, - { 0, 0, 2, 2, 2 }, - - /* 21-30 */ - { 2, 0, 0, -2, 0 }, - { 0, 2, -2, 2, -2 }, - { 2, 0, 2, 0, 2 }, - { 1, 0, 2, -2, 2 }, - { 1, 0, -2, 0, -1 }, - { 2, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 0 }, - { 0, 1, 0, 0, 1 }, - { 1, 0, 0, -2, -1 }, - { 0, 2, 2, -2, 2 }, - - /* 31-40 */ - { 0, 0, 2, -2, 0 }, - { 1, 0, 0, -2, 1 }, - { 0, 1, 0, 0, -1 }, - { 0, 2, 0, 0, 0 }, - { 1, 0, -2, -2, -1 }, - { 1, 0, 2, 2, 2 }, - { 0, 1, 2, 0, 2 }, - { 2, 0, -2, 0, 0 }, - { 0, 0, 2, 2, 1 }, - { 0, 1, -2, 0, -2 }, - - /* 41-50 */ - { 0, 0, 0, 2, 1 }, - { 1, 0, 2, -2, 1 }, - { 2, 0, 0, -2, -1 }, - { 2, 0, 2, -2, 2 }, - { 2, 0, 2, 0, 1 }, - { 0, 0, 0, 2, -1 }, - { 0, 1, -2, 2, -1 }, - { 1, 1, 0, -2, 0 }, - { 2, 0, 0, -2, 1 }, - { 1, 0, 0, 2, 0 }, - - /* 51-60 */ - { 0, 1, 2, -2, 1 }, - { 1, -1, 0, 0, 0 }, - { 0, 1, -1, 1, -1 }, - { 2, 0, -2, 0, -2 }, - { 0, 1, 0, -2, 0 }, - { 1, 0, 0, -1, 0 }, - { 3, 0, 2, 0, 2 }, - { 0, 0, 0, 1, 0 }, - { 1, -1, 2, 0, 2 }, - { 1, 1, -2, -2, -2 }, - - /* 61-70 */ - { 1, 0, -2, 0, 0 }, - { 2, 0, 0, 0, -1 }, - { 0, 1, -2, -2, -2 }, - { 1, 1, 2, 0, 2 }, - { 2, 0, 0, 0, 1 }, - { 1, 1, 0, 0, 0 }, - { 1, 0, -2, 2, -1 }, - { 1, 0, 2, 0, 0 }, - { 1, -1, 0, -1, 0 }, - { 1, 0, 0, 0, 2 }, - - /* 71-80 */ - { 1, 0, -1, 0, -1 }, - { 0, 0, 2, 1, 2 }, - { 1, 0, -2, -4, -2 }, - { 1, -1, 0, -1, -1 }, - { 1, 0, 2, 2, 1 }, - { 0, 2, -2, 2, -1 }, - { 1, 0, 0, 0, -2 }, - { 2, 0, -2, -2, -2 }, - { 1, 1, 2, -2, 2 }, - { 2, 0, -2, -4, -2 }, - - /* 81-90 */ - { 1, 0, -4, 0, -2 }, - { 2, 0, 2, -2, 1 }, - { 1, 0, 0, -1, -1 }, - { 2, 0, 2, 2, 2 }, - { 3, 0, 0, 0, 0 }, - { 1, 0, 0, 2, 1 }, - { 0, 0, 2, -2, -1 }, - { 3, 0, 2, -2, 2 }, - { 0, 0, 4, -2, 2 }, - { 1, 0, 0, -4, 0 }, - - /* 91-100 */ - { 0, 1, 2, 0, 1 }, - { 2, 0, 0, -4, 0 }, - { 1, 1, 0, -2, -1 }, - { 2, 0, -2, 0, 1 }, - { 0, 0, 2, 0, -1 }, - { 0, 1, -2, 0, -1 }, - { 0, 1, 0, 0, 2 }, - { 0, 0, 2, -1, 2 }, - { 0, 0, 2, 4, 2 }, - { 2, 1, 0, -2, 0 }, - - /* 101-110 */ - { 1, 1, 0, -2, 1 }, - { 1, -1, 0, -2, 0 }, - { 1, -1, 0, -1, -2 }, - { 1, -1, 0, 0, 1 }, - { 0, 1, -2, 2, 0 }, - { 0, 1, 0, 0, -2 }, - { 1, -1, 2, 2, 2 }, - { 1, 0, 0, 2, -1 }, - { 1, -1, -2, -2, -2 }, - { 3, 0, 2, 0, 1 }, - - /* 111-120 */ - { 0, 1, 2, 2, 2 }, - { 1, 0, 2, -2, 0 }, - { 1, 1, -2, -2, -1 }, - { 1, 0, 2, -4, 1 }, - { 0, 1, -2, -2, -1 }, - { 2, -1, 2, 0, 2 }, - { 0, 0, 0, 2, 2 }, - { 1, -1, 2, 0, 1 }, - { 1, -1, -2, 0, -2 }, - { 0, 1, 0, 2, 0 }, - - /* 121-130 */ - { 0, 1, 2, -2, 0 }, - { 0, 0, 0, 1, 1 }, - { 1, 0, -2, -2, 0 }, - { 0, 3, 2, -2, 2 }, - { 2, 1, 2, 0, 2 }, - { 1, 1, 0, 0, 1 }, - { 2, 0, 0, 2, 0 }, - { 1, 1, 2, 0, 1 }, - { 1, 0, 0, -2, -2 }, - { 1, 0, -2, 2, 0 }, - - /* 131-140 */ - { 1, 0, -1, 0, -2 }, - { 0, 1, 0, -2, 1 }, - { 0, 1, 0, 1, 0 }, - { 0, 0, 0, 1, -1 }, - { 1, 0, -2, 2, -2 }, - { 1, -1, 0, 0, -1 }, - { 0, 0, 0, 4, 0 }, - { 1, -1, 0, 2, 0 }, - { 1, 0, 2, 1, 2 }, - { 1, 0, 2, -1, 2 }, - - /* 141-150 */ - { 0, 0, 2, 1, 1 }, - { 1, 0, 0, -2, 2 }, - { 1, 0, -2, 0, 1 }, - { 1, 0, -2, -4, -1 }, - { 0, 0, 2, 2, 0 }, - { 1, 1, 2, -2, 1 }, - { 1, 0, -2, 1, -1 }, - { 0, 0, 1, 0, 1 }, - { 2, 0, -2, -2, -1 }, - { 4, 0, 2, 0, 2 }, - - /* 151-160 */ - { 2, -1, 0, 0, 0 }, - { 2, 1, 2, -2, 2 }, - { 0, 1, 2, 1, 2 }, - { 1, 0, 4, -2, 2 }, - { 1, 1, 0, 0, -1 }, - { 2, 0, 2, 0, 0 }, - { 2, 0, -2, -4, -1 }, - { 1, 0, -1, 0, 0 }, - { 1, 0, 0, 1, 0 }, - { 0, 1, 0, 2, 1 }, - - /* 161-170 */ - { 1, 0, -4, 0, -1 }, - { 1, 0, 0, -4, -1 }, - { 2, 0, 2, 2, 1 }, - { 2, 1, 0, 0, 0 }, - { 0, 0, 2, -3, 2 }, - { 1, 2, 0, -2, 0 }, - { 0, 3, 0, 0, 0 }, - { 0, 0, 4, 0, 2 }, - { 0, 0, 2, -4, 1 }, - { 2, 0, 0, -2, -2 }, - - /* 171-180 */ - { 1, 1, -2, -4, -2 }, - { 0, 1, 0, -2, -1 }, - { 0, 0, 0, 4, 1 }, - { 3, 0, 2, -2, 1 }, - { 1, 0, 2, 4, 2 }, - { 1, 1, -2, 0, -2 }, - { 0, 0, 4, -2, 1 }, - { 2, -2, 0, -2, 0 }, - { 2, 1, 0, -2, -1 }, - { 0, 2, 0, -2, 0 }, - - /* 181-190 */ - { 1, 0, 0, -1, 1 }, - { 1, 1, 2, 2, 2 }, - { 3, 0, 0, 0, -1 }, - { 2, 0, 0, -4, -1 }, - { 3, 0, 2, 2, 2 }, - { 0, 0, 2, 4, 1 }, - { 0, 2, -2, -2, -2 }, - { 1, -1, 0, -2, -1 }, - { 0, 0, 2, -1, 1 }, - { 2, 0, 0, 2, 1 }, - - /* 191-200 */ - { 1, -1, -2, 2, -1 }, - { 0, 0, 0, 2, -2 }, - { 2, 0, 0, -4, 1 }, - { 1, 0, 0, -4, 1 }, - { 2, 0, 2, -4, 1 }, - { 4, 0, 2, -2, 2 }, - { 2, 1, -2, 0, -1 }, - { 2, 1, -2, -4, -2 }, - { 3, 0, 0, -4, 0 }, - { 1, -1, 2, 2, 1 }, - - /* 201-210 */ - { 1, -1, -2, 0, -1 }, - { 0, 2, 0, 0, 1 }, - { 1, 2, -2, -2, -2 }, - { 1, 1, 0, -4, 0 }, - { 2, 0, 0, -2, 2 }, - { 0, 2, 2, -2, 1 }, - { 1, 0, 2, 0, -1 }, - { 2, 1, 0, -2, 1 }, - { 2, -1, -2, 0, -1 }, - { 1, -1, -2, -2, -1 }, - - /* 211-220 */ - { 0, 1, -2, 1, -2 }, - { 1, 0, -4, 2, -2 }, - { 0, 1, 2, 2, 1 }, - { 3, 0, 0, 0, 1 }, - { 2, -1, 2, 2, 2 }, - { 0, 1, -2, -4, -2 }, - { 1, 0, -2, -3, -2 }, - { 2, 0, 0, 0, 2 }, - { 1, -1, 0, -2, -2 }, - { 2, 0, -2, 2, -1 }, - - /* 221-230 */ - { 0, 2, -2, 0, -2 }, - { 3, 0, -2, 0, -1 }, - { 2, -1, 2, 0, 1 }, - { 1, 0, -2, -1, -2 }, - { 0, 0, 2, 0, 3 }, - { 2, 0, -4, 0, -2 }, - { 2, 1, 0, -4, 0 }, - { 1, 1, -2, 1, -1 }, - { 0, 2, 2, 0, 2 }, - { 1, -1, 2, -2, 2 }, - - /* 231-240 */ - { 1, -1, 0, -2, 1 }, - { 2, 1, 2, 0, 1 }, - { 1, 0, 2, -4, 2 }, - { 1, 1, -2, 0, -1 }, - { 1, 1, 0, 2, 0 }, - { 1, 0, 0, -3, 0 }, - { 2, 0, 2, -1, 2 }, - { 0, 2, 0, 0, -1 }, - { 2, -1, 0, -2, 0 }, - { 4, 0, 0, 0, 0 }, - - /* 241-250 */ - { 2, 1, -2, -2, -2 }, - { 0, 2, -2, 2, 0 }, - { 1, 0, 2, 1, 1 }, - { 1, 0, -1, 0, -3 }, - { 3, -1, 2, 0, 2 }, - { 2, 0, 2, -2, 0 }, - { 1, -2, 0, 0, 0 }, - { 2, 0, 0, 0, -2 }, - { 1, 0, 0, 4, 0 }, - { 0, 1, 0, 1, 1 }, - - /* 251-260 */ - { 1, 0, 2, 2, 0 }, - { 0, 1, 0, 2, -1 }, - { 0, 1, 0, 1, -1 }, - { 0, 0, 2, -2, 3 }, - { 3, 1, 2, 0, 2 }, - { 1, 1, 2, 1, 2 }, - { 1, 1, -2, 2, -1 }, - { 2, -1, 2, -2, 2 }, - { 1, -2, 2, 0, 2 }, - { 1, 0, 2, -4, 0 }, - - /* 261-270 */ - { 0, 0, 1, 0, 0 }, - { 1, 0, 2, -3, 1 }, - { 1, -2, 0, -2, 0 }, - { 2, 0, 0, 2, -1 }, - { 1, 1, 2, -4, 1 }, - { 4, 0, 2, 0, 1 }, - { 0, 1, 2, 1, 1 }, - { 1, 2, 2, -2, 2 }, - { 2, 0, 2, 1, 2 }, - { 2, 1, 2, -2, 1 }, - - /* 271-280 */ - { 1, 0, 2, -1, 1 }, - { 1, 0, 4, -2, 1 }, - { 1, -1, 2, -2, 1 }, - { 0, 1, 0, -4, 0 }, - { 3, 0, -2, -2, -2 }, - { 0, 0, 4, -4, 2 }, - { 2, 0, -4, -2, -2 }, - { 2, -2, 0, -2, -1 }, - { 1, 0, 2, -2, -1 }, - { 2, 0, -2, -6, -2 }, - - /* 281-290 */ - { 1, 0, -2, 1, -2 }, - { 1, 0, -2, 2, 1 }, - { 1, -1, 0, 2, -1 }, - { 1, 0, -2, 1, 0 }, - { 2, -1, 0, -2, 1 }, - { 1, -1, 0, 2, 1 }, - { 2, 0, -2, -2, 0 }, - { 1, 0, 2, -3, 2 }, - { 0, 0, 0, 4, -1 }, - { 2, -1, 0, 0, 1 }, - - /* 291-300 */ - { 2, 0, 4, -2, 2 }, - { 0, 0, 2, 3, 2 }, - { 0, 1, 4, -2, 2 }, - { 0, 1, -2, 2, 1 }, - { 1, 1, 0, 2, 1 }, - { 1, 0, 0, 4, 1 }, - { 0, 0, 4, 0, 1 }, - { 2, 0, 0, -3, 0 }, - { 1, 0, 0, -1, -2 }, - { 1, -2, -2, -2, -2 }, - - /* 301-310 */ - { 3, 0, 0, 2, 0 }, - { 2, 0, 2, -4, 2 }, - { 1, 1, -2, -4, -1 }, - { 1, 0, -2, -6, -2 }, - { 2, -1, 0, 0, -1 }, - { 2, -1, 0, 2, 0 }, - { 0, 1, 2, -2, -1 }, - { 1, 1, 0, 1, 0 }, - { 1, 2, 0, -2, -1 }, - { 1, 0, 0, 1, -1 }, - - /* 311-320 */ - { 0, 0, 1, 0, 2 }, - { 3, 1, 2, -2, 2 }, - { 1, 0, -4, -2, -2 }, - { 1, 0, 2, 4, 1 }, - { 1, -2, 2, 2, 2 }, - { 1, -1, -2, -4, -2 }, - { 0, 0, 2, -4, 2 }, - { 0, 0, 2, -3, 1 }, - { 2, 1, -2, 0, 0 }, - { 3, 0, -2, -2, -1 }, - - /* 321-330 */ - { 2, 0, 2, 4, 2 }, - { 0, 0, 0, 0, 3 }, - { 2, -1, -2, -2, -2 }, - { 2, 0, 0, -1, 0 }, - { 3, 0, 2, -4, 2 }, - { 2, 1, 2, 2, 2 }, - { 0, 0, 3, 0, 3 }, - { 1, 1, 2, 2, 1 }, - { 2, 1, 0, 0, -1 }, - { 1, 2, 0, -2, 1 }, - - /* 331-340 */ - { 3, 0, 2, 2, 1 }, - { 1, -1, -2, 2, -2 }, - { 1, 1, 0, -1, 0 }, - { 1, 2, 0, 0, 0 }, - { 1, 0, 4, 0, 2 }, - { 1, -1, 2, 4, 2 }, - { 2, 1, 0, 0, 1 }, - { 1, 0, 0, 2, 2 }, - { 1, -1, -2, 2, 0 }, - { 0, 2, -2, -2, -1 }, - - /* 341-350 */ - { 2, 0, -2, 0, 2 }, - { 5, 0, 2, 0, 2 }, - { 3, 0, -2, -6, -2 }, - { 1, -1, 2, -1, 2 }, - { 3, 0, 0, -4, -1 }, - { 1, 0, 0, 1, 1 }, - { 1, 0, -4, 2, -1 }, - { 0, 1, 2, -4, 1 }, - { 1, 2, 2, 0, 2 }, - { 0, 1, 0, -2, -2 }, - - /* 351-360 */ - { 0, 0, 2, -1, 0 }, - { 1, 0, 1, 0, 1 }, - { 0, 2, 0, -2, 1 }, - { 3, 0, 2, 0, 0 }, - { 1, 1, -2, 1, 0 }, - { 2, 1, -2, -4, -1 }, - { 3, -1, 0, 0, 0 }, - { 2, -1, -2, 0, 0 }, - { 4, 0, 2, -2, 1 }, - { 2, 0, -2, 2, 0 }, - - /* 361-370 */ - { 1, 1, 2, -2, 0 }, - { 1, 0, -2, 4, -1 }, - { 1, 0, -2, -2, 1 }, - { 2, 0, 2, -4, 0 }, - { 1, 1, 0, -2, -2 }, - { 1, 1, -2, -2, 0 }, - { 1, 0, 1, -2, 1 }, - { 2, -1, -2, -4, -2 }, - { 3, 0, -2, 0, -2 }, - { 0, 1, -2, -2, 0 }, - - /* 371-380 */ - { 3, 0, 0, -2, -1 }, - { 1, 0, -2, -3, -1 }, - { 0, 1, 0, -4, -1 }, - { 1, -2, 2, -2, 1 }, - { 0, 1, -2, 1, -1 }, - { 1, -1, 0, 0, 2 }, - { 2, 0, 0, 1, 0 }, - { 1, -2, 0, 2, 0 }, - { 1, 2, -2, -2, -1 }, - { 0, 0, 4, -4, 1 }, - - /* 381-390 */ - { 0, 1, 2, 4, 2 }, - { 0, 1, -4, 2, -2 }, - { 3, 0, -2, 0, 0 }, - { 2, -1, 2, 2, 1 }, - { 0, 1, -2, -4, -1 }, - { 4, 0, 2, 2, 2 }, - { 2, 0, -2, -3, -2 }, - { 2, 0, 0, -6, 0 }, - { 1, 0, 2, 0, 3 }, - { 3, 1, 0, 0, 0 }, - - /* 391-400 */ - { 3, 0, 0, -4, 1 }, - { 1, -1, 2, 0, 0 }, - { 1, -1, 0, -4, 0 }, - { 2, 0, -2, 2, -2 }, - { 1, 1, 0, -2, 2 }, - { 4, 0, 0, -2, 0 }, - { 2, 2, 0, -2, 0 }, - { 0, 1, 2, 0, 0 }, - { 1, 1, 0, -4, 1 }, - { 1, 0, 0, -4, -2 }, - - /* 401-410 */ - { 0, 0, 0, 1, 2 }, - { 3, 0, 0, 2, 1 }, - { 1, 1, 0, -4, -1 }, - { 0, 0, 2, 2, -1 }, - { 1, 1, 2, 0, 0 }, - { 1, -1, 2, -4, 1 }, - { 1, 1, 0, 0, 2 }, - { 0, 0, 2, 6, 2 }, - { 4, 0, -2, -2, -1 }, - { 2, 1, 0, -4, -1 }, - - /* 411-420 */ - { 0, 0, 0, 3, 1 }, - { 1, -1, -2, 0, 0 }, - { 0, 0, 2, 1, 0 }, - { 1, 0, 0, 2, -2 }, - { 3, -1, 2, 2, 2 }, - { 3, -1, 2, -2, 2 }, - { 1, 0, 0, -1, 2 }, - { 1, -2, 2, -2, 2 }, - { 0, 1, 0, 2, 2 }, - { 0, 1, -2, -1, -2 }, - - /* 421-430 */ - { 1, 1, -2, 0, 0 }, - { 0, 2, 2, -2, 0 }, - { 3, -1, -2, -1, -2 }, - { 1, 0, 0, -6, 0 }, - { 1, 0, -2, -4, 0 }, - { 2, 1, 0, -4, 1 }, - { 2, 0, 2, 0, -1 }, - { 2, 0, -4, 0, -1 }, - { 0, 0, 3, 0, 2 }, - { 2, 1, -2, -2, -1 }, - - /* 431-440 */ - { 1, -2, 0, 0, 1 }, - { 2, -1, 0, -4, 0 }, - { 0, 0, 0, 3, 0 }, - { 5, 0, 2, -2, 2 }, - { 1, 2, -2, -4, -2 }, - { 1, 0, 4, -4, 2 }, - { 0, 0, 4, -1, 2 }, - { 3, 1, 0, -4, 0 }, - { 3, 0, 0, -6, 0 }, - { 2, 0, 0, 2, 2 }, - - /* 441-450 */ - { 2, -2, 2, 0, 2 }, - { 1, 0, 0, -3, 1 }, - { 1, -2, -2, 0, -2 }, - { 1, -1, -2, -3, -2 }, - { 0, 0, 2, -2, -2 }, - { 2, 0, -2, -4, 0 }, - { 1, 0, -4, 0, 0 }, - { 0, 1, 0, -1, 0 }, - { 4, 0, 0, 0, -1 }, - { 3, 0, 2, -1, 2 }, - - /* 451-460 */ - { 3, -1, 2, 0, 1 }, - { 2, 0, 2, -1, 1 }, - { 1, 2, 2, -2, 1 }, - { 1, 1, 0, 2, -1 }, - { 0, 2, 2, 0, 1 }, - { 3, 1, 2, 0, 1 }, - { 1, 1, 2, 1, 1 }, - { 1, 1, 0, -1, 1 }, - { 1, -2, 0, -2, -1 }, - { 4, 0, 0, -4, 0 }, - - /* 461-470 */ - { 2, 1, 0, 2, 0 }, - { 1, -1, 0, 4, 0 }, - { 0, 1, 0, -2, 2 }, - { 0, 0, 2, 0, -2 }, - { 1, 0, -1, 0, 1 }, - { 3, 0, 2, -2, 0 }, - { 2, 0, 2, 2, 0 }, - { 1, 2, 0, -4, 0 }, - { 1, -1, 0, -3, 0 }, - { 0, 1, 0, 4, 0 }, - - /* 471 - 480 */ - { 0, 1, -2, 0, 0 }, - { 2, 2, 2, -2, 2 }, - { 0, 0, 0, 1, -2 }, - { 0, 2, -2, 0, -1 }, - { 4, 0, 2, -4, 2 }, - { 2, 0, -4, 2, -2 }, - { 2, -1, -2, 0, -2 }, - { 1, 1, 4, -2, 2 }, - { 1, 1, 2, -4, 2 }, - { 1, 0, 2, 3, 2 }, - - /* 481-490 */ - { 1, 0, 0, 4, -1 }, - { 0, 0, 0, 4, 2 }, - { 2, 0, 0, 4, 0 }, - { 1, 1, -2, 2, 0 }, - { 2, 1, 2, 1, 2 }, - { 2, 1, 2, -4, 1 }, - { 2, 0, 2, 1, 1 }, - { 2, 0, -4, -2, -1 }, - { 2, 0, -2, -6, -1 }, - { 2, -1, 2, -1, 2 }, - - /* 491-500 */ - { 1, -2, 2, 0, 1 }, - { 1, -2, 0, -2, 1 }, - { 1, -1, 0, -4, -1 }, - { 0, 2, 2, 2, 2 }, - { 0, 2, -2, -4, -2 }, - { 0, 1, 2, 3, 2 }, - { 0, 1, 0, -4, 1 }, - { 3, 0, 0, -2, 1 }, - { 2, 1, -2, 0, 1 }, - { 2, 0, 4, -2, 1 }, - - /* 501-510 */ - { 2, 0, 0, -3, -1 }, - { 2, -2, 0, -2, 1 }, - { 2, -1, 2, -2, 1 }, - { 1, 0, 0, -6, -1 }, - { 1, -2, 0, 0, -1 }, - { 1, -2, -2, -2, -1 }, - { 0, 1, 4, -2, 1 }, - { 0, 0, 2, 3, 1 }, - { 2, -1, 0, -1, 0 }, - { 1, 3, 0, -2, 0 }, - - /* 511-520 */ - { 0, 3, 0, -2, 0 }, - { 2, -2, 2, -2, 2 }, - { 0, 0, 4, -2, 0 }, - { 4, -1, 2, 0, 2 }, - { 2, 2, -2, -4, -2 }, - { 4, 1, 2, 0, 2 }, - { 4, -1, -2, -2, -2 }, - { 2, 1, 0, -2, -2 }, - { 2, 1, -2, -6, -2 }, - { 2, 0, 0, -1, 1 }, - - /* 521-530 */ - { 2, -1, -2, 2, -1 }, - { 1, 1, -2, 2, -2 }, - { 1, 1, -2, -3, -2 }, - { 1, 0, 3, 0, 3 }, - { 1, 0, -2, 1, 1 }, - { 1, 0, -2, 0, 2 }, - { 1, -1, 2, 1, 2 }, - { 1, -1, 0, 0, -2 }, - { 1, -1, -4, 2, -2 }, - { 0, 3, -2, -2, -2 }, - - /* 531-540 */ - { 0, 1, 0, 4, 1 }, - { 0, 0, 4, 2, 2 }, - { 3, 0, -2, -2, 0 }, - { 2, -2, 0, 0, 0 }, - { 1, 1, 2, -4, 0 }, - { 1, 1, 0, -3, 0 }, - { 1, 0, 2, -3, 0 }, - { 1, -1, 2, -2, 0 }, - { 0, 2, 0, 2, 0 }, - { 0, 0, 2, 4, 0 }, - - /* 541-550 */ - { 1, 0, 1, 0, 0 }, - { 3, 1, 2, -2, 1 }, - { 3, 0, 4, -2, 2 }, - { 3, 0, 2, 1, 2 }, - { 3, 0, 0, 2, -1 }, - { 3, 0, 0, 0, 2 }, - { 3, 0, -2, 2, -1 }, - { 2, 0, 4, -4, 2 }, - { 2, 0, 2, -3, 2 }, - { 2, 0, 0, 4, 1 }, - - /* 551-560 */ - { 2, 0, 0, -3, 1 }, - { 2, 0, -4, 2, -1 }, - { 2, 0, -2, -2, 1 }, - { 2, -2, 2, 2, 2 }, - { 2, -2, 0, -2, -2 }, - { 2, -1, 0, 2, 1 }, - { 2, -1, 0, 2, -1 }, - { 1, 1, 2, 4, 2 }, - { 1, 1, 0, 1, 1 }, - { 1, 1, 0, 1, -1 }, - - /* 561-570 */ - { 1, 1, -2, -6, -2 }, - { 1, 0, 0, -3, -1 }, - { 1, 0, -4, -2, -1 }, - { 1, 0, -2, -6, -1 }, - { 1, -2, 2, 2, 1 }, - { 1, -2, -2, 2, -1 }, - { 1, -1, -2, -4, -1 }, - { 0, 2, 0, 0, 2 }, - { 0, 1, 2, -4, 2 }, - { 0, 1, -2, 4, -1 }, - - /* 571-580 */ - { 5, 0, 0, 0, 0 }, - { 3, 0, 0, -3, 0 }, - { 2, 2, 0, -4, 0 }, - { 1, -1, 2, 2, 0 }, - { 0, 1, 0, 3, 0 }, - { 4, 0, -2, 0, -1 }, - { 3, 0, -2, -6, -1 }, - { 3, 0, -2, -1, -1 }, - { 2, 1, 2, 2, 1 }, - { 2, 1, 0, 2, 1 }, - - /* 581-590 */ - { 2, 0, 2, 4, 1 }, - { 2, 0, 2, -6, 1 }, - { 2, 0, 2, -2, -1 }, - { 2, 0, 0, -6, -1 }, - { 2, -1, -2, -2, -1 }, - { 1, 2, 2, 0, 1 }, - { 1, 2, 0, 0, 1 }, - { 1, 0, 4, 0, 1 }, - { 1, 0, 2, -6, 1 }, - { 1, 0, 2, -4, -1 }, - - /* 591-600 */ - { 1, 0, -1, -2, -1 }, - { 1, -1, 2, 4, 1 }, - { 1, -1, 2, -3, 1 }, - { 1, -1, 0, 4, 1 }, - { 1, -1, -2, 1, -1 }, - { 0, 1, 2, -2, 3 }, - { 3, 0, 0, -2, 0 }, - { 1, 0, 1, -2, 0 }, - { 0, 2, 0, -4, 0 }, - { 0, 0, 2, -4, 0 }, - - /* 601-610 */ - { 0, 0, 1, -1, 0 }, - { 0, 0, 0, 6, 0 }, - { 0, 2, 0, 0, -2 }, - { 0, 1, -2, 2, -3 }, - { 4, 0, 0, 2, 0 }, - { 3, 0, 0, -1, 0 }, - { 3, -1, 0, 2, 0 }, - { 2, 1, 0, 1, 0 }, - { 2, 1, 0, -6, 0 }, - { 2, -1, 2, 0, 0 }, - - /* 611-620 */ - { 1, 0, 2, -1, 0 }, - { 1, -1, 0, 1, 0 }, - { 1, -1, -2, -2, 0 }, - { 0, 1, 2, 2, 0 }, - { 0, 0, 2, -3, 0 }, - { 2, 2, 0, -2, -1 }, - { 2, -1, -2, 0, 1 }, - { 1, 2, 2, -4, 1 }, - { 0, 1, 4, -4, 2 }, - { 0, 0, 0, 3, 2 }, - - /* 621-630 */ - { 5, 0, 2, 0, 1 }, - { 4, 1, 2, -2, 2 }, - { 4, 0, -2, -2, 0 }, - { 3, 1, 2, 2, 2 }, - { 3, 1, 0, -2, 0 }, - { 3, 1, -2, -6, -2 }, - { 3, 0, 0, 0, -2 }, - { 3, 0, -2, -4, -2 }, - { 3, -1, 0, -3, 0 }, - { 3, -1, 0, -2, 0 }, - - /* 631-640 */ - { 2, 1, 2, 0, 0 }, - { 2, 1, 2, -4, 2 }, - { 2, 1, 2, -2, 0 }, - { 2, 1, 0, -3, 0 }, - { 2, 1, -2, 0, -2 }, - { 2, 0, 0, -4, 2 }, - { 2, 0, 0, -4, -2 }, - { 2, 0, -2, -5, -2 }, - { 2, -1, 2, 4, 2 }, - { 2, -1, 0, -2, 2 }, - - /* 641-650 */ - { 1, 3, -2, -2, -2 }, - { 1, 1, 0, 0, -2 }, - { 1, 1, 0, -6, 0 }, - { 1, 1, -2, 1, -2 }, - { 1, 1, -2, -1, -2 }, - { 1, 0, 2, 1, 0 }, - { 1, 0, 0, 3, 0 }, - { 1, 0, 0, -4, 2 }, - { 1, 0, -2, 4, -2 }, - { 1, -2, 0, -1, 0 }, - - /* 651-NFLS */ - { 0, 1, -4, 2, -1 }, - { 1, 0, -2, 0, -3 }, - { 0, 0, 4, -4, 4 } - }; - -/* Number of frequencies: luni-solar */ - static const int NFLS = (int) (sizeof mfals / sizeof (int) / 5); - -/* Fundamental-argument multipliers: planetary terms */ - static const int mfapl[][14] = { - - /* 1-10 */ - { 0, 0, 1, -1, 1, 0, 0, -1, 0, -2, 5, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -5, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 1, -1, 1, 0, -8, 12, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -8, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 8,-16, 4, 5, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, -1, 2, 0, 0, 0, 0, 0 }, - - /* 11-20 */ - { 0, 0, 0, 0, 0, 0, 8,-13, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 2, -5, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, -5, 6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 4, -6, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, -1, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -8, 3, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 6, -8, 3, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 2, -3, 0, 0, 0, 0, 0, 0 }, - - /* 21-30 */ - { 0, 0, 0, 0, 0, 0, 2, -2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 1, 0, 0, -4, 8, -3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 4, -8, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -5, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 1, -1, 1, 0, 0, 0, -2, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, -1, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1 }, - { 2, 0, 0, -2, 0, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - - /* 31-40 */ - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 8,-13, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 5, -8, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -5, 0, 0, 1 }, - { 2, 0, 0, -2, 0, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, -1, 0, 0, 0 }, - - /* 41-50 */ - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 5, -7, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 1, -1, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 4, 0, -2, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 8,-13, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 2, -1, 0, 0, 0, 0, 0, 2 }, - { 1, 0, 0, 0, 0, 0,-18, 16, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 2 }, - - /* 51-60 */ - { 0, 0, 1, -1, 1, 0, -5, 7, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0,-10, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 0, 0, -5, 6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -1, 0, 0, 0, 2 }, - { 1, 0, 2, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -2, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1 }, - { 1, 0, -2, 0, -2, 0, 0, 4, -8, 3, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, 2, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - - /* 61-70 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 8,-16, 4, 5, 0, 0, -2 }, - { 0, 0, 1, -1, 1, 0, 0, 3, -8, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 8,-11, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 8,-16, 4, 5, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 4, -6, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -3, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, 0 }, - - /* 71-80 */ - { 0, 0, 0, 0, 0, 0, 6, -8, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 3, -2, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 8,-15, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 2, -5, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 1, -3, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, -2, 0, 0, 0, 2 }, - { 0, 0, 1, -1, 1, 0, 0, -5, 8, -3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -2, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, 0, 0 }, - - /* 81-90 */ - { 2, 0, 0, -2, 1, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 5, -8, 0, 0, 0, 0, 0, -1 }, - { 2, 0, 0, -2, 0, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 8,-13, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 0, 0, -2, 5, 0, 0, 0 }, - { 1, 0, 0, -1, 0, 0, -3, 4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2 }, - { 1, 0, 0, 0, -1, 0,-18, 16, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, -5, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - - /* 91-100 */ - { 1, 0, 0, -2, 0, 0, 19,-21, 3, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, -8, 13, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 7, -9, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2 }, - { 1, 0, 0, 0, 1, 0,-18, 16, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 6,-16, 4, 5, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 4, -7, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 3, -7, 0, 0, 0, 0, 0, -2 }, - - /* 101-110 */ - { 0, 0, 0, 0, 0, 0, 2, -2, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 }, - { 2, 0, 0, -2, 1, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -4, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, -1, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 2 }, - - /* 111-120 */ - { 0, 0, 0, 0, 1, 0, 0, 1, -2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2 }, - { 0, 0, 2, -2, 1, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0 }, - { 2, 0, 0, -2, 0, 0, -6, 8, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -2, 2, 0, 0, 0, 0, 0 }, - - /* 121-130 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -3, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 8,-10, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 1, -1, 1, 0, -3, 4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 6, -9, 0, 0, 0, 0, 0, -2 }, - { 1, 0, 0, -1, 1, 0, 0, -1, 0, 2, 0, 0, 0, 0 }, - - /* 131-140 */ - { 0, 0, 0, 0, 0, 0, 5, -7, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 5, -5, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, 0, -3, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 1, 0, 2, -3, 0, 0, 0, 0, 0, 0 }, - - /* 141-150 */ - { 1, 0, 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, -3, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -4, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 9,-11, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 2, -3, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 8,-15, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, -4, 5, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 4, -6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 4, 0, -1, 0, 0, 0, 2 }, - - /* 151-160 */ - { 1, 0, 0, -1, 1, 0, -3, 4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, -4, 10, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -1, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -4, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -5, 0, 0, -2 }, - { 0, 0, 2, -2, 1, 0, -4, 4, 0, 0, 0, 0, 0, 0 }, - - /* 161-170 */ - { 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -1, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -3, 0, 0, 0, 0, 2 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, 0, 0, 2, 0 }, - { 0, 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 5, -8, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -9, 13, 0, 0, 0, 0, 0 }, - { 2, 0, 2, 0, 2, 0, 0, 2, 0, -3, 0, 0, 0, 0 }, - - /* 171-180 */ - { 0, 0, 0, 0, 0, 0, 3, -6, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 1, -1, 2, 0, 0, -1, 0, 0, 2, 0, 0, 0 }, - { 1, 0, 0, -1, -1, 0, -3, 4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -6, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 6, -6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1 }, - { 1, 0, 2, 0, 1, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 1, 0, -2, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, -2, 4, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, 0 }, - - /* 181-190 */ - { 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 2, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, -8, 3, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 6,-10, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 7, -8, 3, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 1, 0, -3, 5, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, -5, 7, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -2, 0, 0, 0, 1 }, - - /* 191-200 */ - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 7,-10, 0, 0, 0, 0, 0, -2 }, - { 1, 0, 0, -2, 0, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, -5, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 6, -8, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 1, -1, 1, 0, 0, -9, 15, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, -2, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, -1, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -6, 0, 0, 0, 0, 0 }, - - /* 201-210 */ - { 0, 0, 0, 0, 0, 0, 0, 1, -4, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -1, 0, 0, 2 }, - { 2, 0, 0, -2, 1, 0, -6, 8, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 5, -5, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 1, -1, 1, 0, 3, -6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, -2, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 8,-14, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - - /* 211-220 */ - { 0, 0, 0, 0, 1, 0, 0, 8,-15, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -6, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 7, -7, 0, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, 1, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -1, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 2 }, - { 2, 0, -1, -1, 0, 0, 0, 3, -7, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -7, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -3, 4, 0, 0, 0, 0, 0 }, - - /* 221-230 */ - { 2, 0, 0, -2, 0, 0, 0, -6, 8, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, 0, 0, 0, -5, 6, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 1, 0, 0, 1, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -9, 4, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, -2 }, - - /* 231-240 */ - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -4, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1 }, - { 0, 0, 0, 0, 0, 0, 7,-11, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 3, -5, 4, 0, 0, 0, 0, 2 }, - { 0, 0, 1, -1, 0, 0, 0, -1, 0, -1, 1, 0, 0, 0 }, - { 2, 0, 0, 0, 0, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 8,-15, 0, 0, 0, 0, -2 }, - { 0, 0, 1, -1, 2, 0, 0, -2, 2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 6, -6, 0, 0, 0, 0, 0, -1 }, - - /* 241-250 */ - { 0, 0, 1, -1, 1, 0, 0, -1, 0, -1, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 2, -2, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -7, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -8, 3, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 2, -4, 0, -3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 3, -5, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, -3, 0, 0, 0, 2 }, - { 0, 0, 2, -2, 2, 0, -8, 11, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -8, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -2, 0, 0, 0 }, - - /* 251-260 */ - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -9, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -5, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 7, -9, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 4, -7, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, -2, -2, -2, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -2, 5, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 1 }, - - /* 261-270 */ - { 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, -5, 0, 0, 2 }, - { 2, 0, 0, -2, -1, 0, 0, -2, 0, 0, 5, 0, 0, 0 }, - { 2, 0, 0, -2, -1, 0, -6, 8, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, -2, 0, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 8, -8, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, -5, 0, 0, 2 }, - { 0, 0, 0, 0, 1, 0, 3, -7, 4, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, -2, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - - /* 271-280 */ - { 0, 0, 1, -1, 0, 0, 0, -1, 0, -2, 5, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, -3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -1, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 2, -3, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 6,-15, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 2 }, - { 1, 0, 0, -1, 0, 0, 0, -3, 4, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, -3, 7, -4, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5, 0, -2, 0, 0, 0, 2 }, - - /* 281-290 */ - { 0, 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 2, -2, 2, 0, -5, 6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 2, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -8, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -5, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 5, -7, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 6,-11, 0, 0, 0, 0, -2 }, - - /* 291-300 */ - { 0, 0, 0, 0, 0, 0, 0, 1, -3, 0, 0, 0, 0, -2 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 3, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, 0, -1, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 9,-12, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 1, -1, 0, 0, -8, 12, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, -2, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 7, -7, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -6, 0, 0, 0, 0, -1 }, - - /* 301-310 */ - { 0, 0, 0, 0, 0, 0, 0, 6, -6, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 1, 0, -4, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 1, -1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 6, -9, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 1, -1, -1, 0, 0, 0, -2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, -5, 0, 0, 0, 0, -2 }, - { 2, 0, 0, -2, 0, 0, 0, -2, 0, 3, -1, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -2, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -9, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 0, 2 }, - - /* 311-320 */ - { 0, 0, 0, 0, 0, 0, 9, -9, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, 3, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 2, -4, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 5, -3, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1 }, - { 0, 0, 1, -1, 2, 0, 0, -1, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 5, -9, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -3, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2 }, - { 0, 0, 2, 0, 2, 0, 0, 4, -8, 3, 0, 0, 0, 0 }, - - /* 321-330 */ - { 0, 0, 2, 0, 2, 0, 0, -4, 8, -3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5, 0, -3, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0 }, - { 2, 0, -1, -1, -1, 0, 0, -1, 0, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 4, -3, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 4, -2, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 5,-10, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 8,-13, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 2, -2, 1, -1, 0, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, 0, 2, 0, 0 }, - - /* 331-340 */ - { 0, 0, 0, 0, 1, 0, 3, -5, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, -2, 0, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 0, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 9, -9, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 2, 0, 1, -1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -8, 11, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -2, 0, 0, 2, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, -1, 2, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 5, -5, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 2, -6, 0, 0, 0, 0, 0, -2 }, - - /* 341-350 */ - { 0, 0, 0, 0, 0, 0, 0, 8,-15, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -2, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 7,-13, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, -2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 2 }, - { 0, 0, 2, -2, 1, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 8, -8, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 8,-10, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 4, -2, 0, 0, 0, 0, 0, 1 }, - - /* 351-360 */ - { 0, 0, 0, 0, 0, 0, 3, -6, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 3, -4, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -5, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -4, 0, 0, 0, 0 }, - { 2, 0, 0, -2, -1, 0, 0, -5, 6, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -5, 0, 0, 0, 0, -2 }, - { 2, 0, -1, -1, -1, 0, 0, 3, -7, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -8, 0, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 2, 0, -1, 1, 0, 0, 0, 0, 0, 0 }, - - /* 361-370 */ - { 2, 0, 0, -2, 0, 0, 0, -2, 0, 4, -3, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 6,-11, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, 1, 0, 0, -6, 8, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -8, 1, 5, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 6, -5, 0, 0, 0, 0, 2 }, - { 1, 0, -2, -2, -2, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 2, 0, 0, 0, -2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 2, 0, 0, 4, -8, 3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 2, 0, 0, -4, 8, -3, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1 }, - - /* 371-380 */ - { 0, 0, 0, 0, 0, 0, 0, 6, -7, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, -2, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -2, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 1, -6, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, -5, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 3, -5, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 7,-13, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -2, 0, 0, 0, 2 }, - - /* 381-390 */ - { 0, 0, 1, -1, 0, 0, 0, -1, 0, 0, 2, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, -8, 15, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, -2, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 2, 0, -1, -1, -1, 0, 0, -1, 0, 2, 0, 0, 0, 0 }, - { 1, 0, 2, -2, 2, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 1, 0, -1, 1, -1, 0,-18, 17, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 2, 0, 0, 1, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 2, -2, -1, 0, -5, 6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - - /* 391-400 */ - { 0, 0, 0, 0, 1, 0, 2, -2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 8,-16, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 }, - { 0, 0, 0, 0, 2, 0, 0, -1, 2, 0, 0, 0, 0, 0 }, - { 2, 0, -1, -1, -2, 0, 0, -1, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 6,-10, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, -2, 4, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2 }, - { 2, 0, 0, -2, -1, 0, 0, -2, 0, 4, -5, 0, 0, 0 }, - - /* 401-410 */ - { 2, 0, 0, -2, -1, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 2, 0, -1, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 1, -1, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, -1, -1, 0, 0, -2, 2, 0, 0, 0, 0, 0 }, - { 1, 0, -1, -1, -1, 0, 20,-20, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 1, -2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, -2, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 5, -8, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0 }, - - /* 411-420 */ - { 0, 0, 0, 0, 0, 0, 9,-11, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 5, -3, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -3, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 6, -7, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, -2, 0, 0, 0 }, - { 0, 0, 1, -1, 2, 0, 0, -1, 0, -2, 5, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -7, 0, 0, 0, 0, 0 }, - - /* 421-430 */ - { 0, 0, 0, 0, 0, 0, 1, -3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -8, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -6, 0, 0, 0, 0, -2 }, - { 1, 0, 0, -2, 0, 0, 20,-21, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 8,-12, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -4, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 2, 0, 0, -1, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 8,-12, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 9,-17, 0, 0, 0, 0, 0 }, - - /* 431-440 */ - { 0, 0, 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -8, 1, 5, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -6, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -7, 0, 0, 0, 0, -2 }, - { 1, 0, 0, -1, 1, 0, 0, -3, 4, 0, 0, 0, 0, 0 }, - { 1, 0, -2, 0, -2, 0,-10, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, -9, 17, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, -4, 0, 0, 0, 0, 0, -2 }, - { 1, 0, -2, -2, -2, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 1, 0, -1, 1, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - - /* 441-450 */ - { 0, 0, 2, -2, 2, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 2, 0, 0, -1, 0, 0, 1, 0, 0, 0 }, - { 0, 0, 1, -1, 2, 0, -5, 7, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 2, -2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 4, -5, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 3, -4, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5,-10, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, 0, -4, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, -5, 0, 0, 0, -2 }, - - /* 451-460 */ - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -5, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -2, 5, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -2, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 2, -3, 0, 0, 0, 0, 0, 1 }, - { 1, 0, 0, -2, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -7, 4, 0, 0, 0, 0, 0 }, - { 2, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, -1, 0, 0, -1, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 1, 0, -2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 6,-10, 0, 0, 0, 0, -2 }, - - /* 461-470 */ - { 1, 0, 0, -1, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, 4, -8, 3, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, 1, 0, -1, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -4, 8, -3, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -3, 0, 3, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, -5, 5, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 1, -3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -4, 6, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, 0, -1, 0, 0 }, - { 0, 0, 1, -1, 1, 0, -5, 6, 0, 0, 0, 0, 0, 0 }, - - /* 471-480 */ - { 0, 0, 0, 0, 1, 0, 3, -4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, -2, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 7,-10, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 5, -5, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 4, -5, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 3, -8, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 2, -5, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 7, -9, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 7, -8, 0, 0, 0, 0, 2 }, - - /* 481-490 */ - { 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -8, 3, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -2, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -4, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1 }, - { 2, 0, 0, -2, -1, 0, 0, -6, 8, 0, 0, 0, 0, 0 }, - { 2, 0, -1, -1, 1, 0, 0, 3, -7, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -7, 9, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -5, 0, 0, 0, 0, -1 }, - - /* 491-500 */ - { 0, 0, 1, -1, 2, 0, -8, 12, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 1, 0, 0, -2, 0, 0, 2, -2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 7, -8, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, 1, 0, 0, -5, 6, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, -1, 0, 0, -2, 0, 3, -1, 0, 0, 0 }, - { 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, -2, 1, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 1, 0, 0, -2, -1, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - - /* 501-510 */ - { 1, 0, 0, -1, -1, 0, 0, -3, 4, 0, 0, 0, 0, 0 }, - { 1, 0, -1, 0, -1, 0, -3, 5, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -4, 4, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, -8, 11, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 0, 0, 0, -9, 13, 0, 0, 0, 0, 0 }, - { 0, 0, 1, 1, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, 1, -4, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, 0, -1, 0, 1, -3, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 7,-13, 0, 0, 0, 0, 0 }, - - /* 511-520 */ - { 0, 0, 0, 0, 1, 0, 0, 2, 0, -2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, -2, 2, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, -3, 4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 1, 0, -4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 7,-11, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 6, -6, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 6, -4, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 4, -2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -4, 0, 0, 0, 0, 0, 1 }, - - /* 521-530 */ - { 0, 0, 0, 0, 0, 0, 1, -4, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 9,-17, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 7, -7, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -8, 3, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -8, 3, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -8, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 4, -7, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -4, 0, 0, 0, 0 }, - { 2, 0, 0, -2, 0, 0, 0, -4, 8, -3, 0, 0, 0, 0 }, - - /* 531-540 */ - { 2, 0, 0, -2, 0, 0, -2, 2, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 0, 4, -8, 3, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 0, -4, 8, -3, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, -2, 0, 0, 17,-16, 0, -2, 0, 0, 0, 0 }, - { 1, 0, 0, -1, 0, 0, 0, -2, 2, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 0, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 6, -9, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 3, 0, -4, 0, 0, 0, 0 }, - - /* 541-550 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -2, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 2 }, - { 2, 0, 0, -2, 0, 0, 0, -4, 4, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, 0, 0, 0, -2, 0, 2, 2, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, -2, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, -2, 0, 0, 0, 4, -8, 3, 0, 0, 0, 0 }, - { 1, 0, 0, -2, 0, 0, 0, -4, 8, -3, 0, 0, 0, 0 }, - - /* 551-560 */ - { 1, 0, 0, -2, 0, 0, -2, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 0, 0, -4, 4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, 3, -6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, 0, -2, 2, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, -4, 5, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, -3, 4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 2, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0 }, - - /* 561-570 */ - { 0, 0, 0, 0, 0, 0, 8, -9, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -5, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -2, 0, 0, 0 }, - { 2, 0, -2, -2, -2, 0, 0, -2, 0, 2, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 1, 0,-10, 3, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, -1, 0,-10, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 2, 0, 2, -3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 2, 0, 2, -2, 0, 0, 0, 0, 0, 0 }, - - /* 571-580 */ - { 0, 0, 2, 0, 2, 0, -2, 3, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, 0, 2, 0, -2, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, -1, 0, 2, 0, 0, 0, 0 }, - { 2, 0, 2, -2, 2, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 2, 0, 1, -3, 1, 0, -6, 7, 0, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, 0, 0, 2, -5, 0, 0, 0, 0, 0, 0 }, - { 2, 0, 0, -2, 0, 0, 0, -2, 0, 5, -5, 0, 0, 0 }, - { 2, 0, 0, -2, 0, 0, 0, -2, 0, 1, 5, 0, 0, 0 }, - { 2, 0, 0, -2, 0, 0, 0, -2, 0, 0, 5, 0, 0, 0 }, - - /* 581-590 */ - { 2, 0, 0, -2, 0, 0, 0, -2, 0, 0, 2, 0, 0, 0 }, - { 2, 0, 0, -2, 0, 0, -4, 4, 0, 0, 0, 0, 0, 0 }, - { 2, 0, -2, 0, -2, 0, 0, 5, -9, 0, 0, 0, 0, 0 }, - { 2, 0, -1, -1, 0, 0, 0, -1, 0, 3, 0, 0, 0, 0 }, - { 1, 0, 2, 0, 2, 0, 1, -1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 2, 0, 2, 0, 0, 4, -8, 3, 0, 0, 0, 0 }, - { 1, 0, 2, 0, 2, 0, 0, -4, 8, -3, 0, 0, 0, 0 }, - { 1, 0, 2, 0, 2, 0, -1, 1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 2, -2, 2, 0, -3, 3, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0 }, - - /* 591-600 */ - { 1, 0, 0, 0, 0, 0, 0, -2, 0, 3, 0, 0, 0, 0 }, - { 1, 0, 0, -2, 0, 0, 0, 2, 0, -2, 0, 0, 0, 0 }, - { 1, 0, -2, -2, -2, 0, 0, 1, 0, -1, 0, 0, 0, 0 }, - { 1, 0, -1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 1, 0, -1, -1, 0, 0, 0, 8,-15, 0, 0, 0, 0, 0 }, - { 0, 0, 2, 2, 2, 0, 0, 2, 0, -2, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0, -2, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 1, 0, 0,-10, 15, 0, 0, 0, 0, 0 }, - { 0, 0, 2, -2, 0, -1, 0, 2, 0, 0, 0, 0, 0, 0 }, - - /* 601-610 */ - { 0, 0, 1, -1, 2, 0, 0, -1, 0, 0, -1, 0, 0, 0 }, - { 0, 0, 1, -1, 2, 0, -3, 4, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, -4, 6, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 1, 0, -1, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, 0, -1, 0, 0, -2, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, -2, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 1, -1, -1, 0, -5, 7, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 2, 0, 0, 0, 2, 0, -2, 0, 0, 0, 0 }, - - /* 611-620 */ - { 0, 0, 0, 2, 0, 0, -2, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 2, 0, -3, 5, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, -1, 2, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 9,-13, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 8,-14, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 8,-11, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 6, -9, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 6, -8, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 6, -7, 0, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 0, -2 }, - - /* 621-630 */ - { 0, 0, 0, 0, 0, 0, 5, -6, -4, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 5, -4, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 4, -8, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 4, -5, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 3, -3, 0, 2, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 3, -1, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 7,-12, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 6, -9, 0, 0, 0, 0, -2 }, - - /* 631-640 */ - { 0, 0, 0, 0, 0, 0, 0, 6, -8, 1, 5, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 6, -4, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 6,-10, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5, 0, -4, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -9, 0, 0, 0, 0, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -8, 3, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -7, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 5, -6, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 5,-16, 4, 5, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 5,-13, 0, 0, 0, 0, -2 }, - - /* 641-650 */ - { 0, 0, 0, 0, 0, 0, 0, 3, 0, -5, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -9, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 3, -7, 0, 0, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -3, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 2, -8, 1, 5, 0, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, -5, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -3, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 0, -3, 5, 0, 0, 0 }, - - /* 651-NFPL */ - { 0, 0, 0, 0, 0, 0, 0, 1, -3, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -6, 3, 0, -2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -2, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } - }; - -/* Number of frequencies: planetary */ - static const int NFPL = (int) (sizeof mfapl / sizeof (int) / 14); - -/* Pointers into amplitudes array, one pointer per frequency */ - static const int nc[] = { - - /* 1-100 */ - 1, 21, 37, 51, 65, 79, 91, 103, 115, 127, - 139, 151, 163, 172, 184, 196, 207, 219, 231, 240, - 252, 261, 273, 285, 297, 309, 318, 327, 339, 351, - 363, 372, 384, 396, 405, 415, 423, 435, 444, 452, - 460, 467, 474, 482, 490, 498, 506, 513, 521, 528, - 536, 543, 551, 559, 566, 574, 582, 590, 597, 605, - 613, 620, 628, 636, 644, 651, 658, 666, 674, 680, - 687, 695, 702, 710, 717, 725, 732, 739, 746, 753, - 760, 767, 774, 782, 790, 798, 805, 812, 819, 826, - 833, 840, 846, 853, 860, 867, 874, 881, 888, 895, - - /* 101-200 */ - 901, 908, 914, 921, 928, 934, 941, 948, 955, 962, - 969, 976, 982, 989, 996, 1003, 1010, 1017, 1024, 1031, - 1037, 1043, 1050, 1057, 1064, 1071, 1078, 1084, 1091, 1098, - 1104, 1112, 1118, 1124, 1131, 1138, 1145, 1151, 1157, 1164, - 1171, 1178, 1185, 1192, 1199, 1205, 1212, 1218, 1226, 1232, - 1239, 1245, 1252, 1259, 1266, 1272, 1278, 1284, 1292, 1298, - 1304, 1310, 1316, 1323, 1329, 1335, 1341, 1347, 1353, 1359, - 1365, 1371, 1377, 1383, 1389, 1396, 1402, 1408, 1414, 1420, - 1426, 1434, 1440, 1446, 1452, 1459, 1465, 1471, 1477, 1482, - 1488, 1493, 1499, 1504, 1509, 1514, 1520, 1527, 1532, 1538, - - /* 201-300 */ - 1543, 1548, 1553, 1558, 1564, 1569, 1574, 1579, 1584, 1589, - 1594, 1596, 1598, 1600, 1602, 1605, 1608, 1610, 1612, 1617, - 1619, 1623, 1625, 1627, 1629, 1632, 1634, 1640, 1642, 1644, - 1646, 1648, 1650, 1652, 1654, 1658, 1660, 1662, 1664, 1668, - 1670, 1672, 1673, 1675, 1679, 1681, 1683, 1684, 1686, 1688, - 1690, 1693, 1695, 1697, 1701, 1703, 1705, 1707, 1709, 1711, - 1712, 1715, 1717, 1721, 1723, 1725, 1727, 1729, 1731, 1733, - 1735, 1737, 1739, 1741, 1743, 1745, 1747, 1749, 1751, 1753, - 1755, 1757, 1759, 1761, 1762, 1764, 1766, 1768, 1769, 1771, - 1773, 1775, 1777, 1779, 1781, 1783, 1785, 1787, 1788, 1790, - - /* 301-400 */ - 1792, 1794, 1796, 1798, 1800, 1802, 1804, 1806, 1807, 1809, - 1811, 1815, 1817, 1819, 1821, 1823, 1825, 1827, 1829, 1831, - 1833, 1835, 1837, 1839, 1840, 1842, 1844, 1848, 1850, 1852, - 1854, 1856, 1858, 1859, 1860, 1862, 1864, 1866, 1868, 1869, - 1871, 1873, 1875, 1877, 1879, 1881, 1883, 1885, 1887, 1889, - 1891, 1892, 1896, 1898, 1900, 1901, 1903, 1905, 1907, 1909, - 1910, 1911, 1913, 1915, 1919, 1921, 1923, 1927, 1929, 1931, - 1933, 1935, 1937, 1939, 1943, 1945, 1947, 1948, 1949, 1951, - 1953, 1955, 1957, 1958, 1960, 1962, 1964, 1966, 1968, 1970, - 1971, 1973, 1974, 1975, 1977, 1979, 1980, 1981, 1982, 1984, - - /* 401-500 */ - 1986, 1988, 1990, 1992, 1994, 1995, 1997, 1999, 2001, 2003, - 2005, 2007, 2008, 2009, 2011, 2013, 2015, 2017, 2019, 2021, - 2023, 2024, 2025, 2027, 2029, 2031, 2033, 2035, 2037, 2041, - 2043, 2045, 2046, 2047, 2049, 2051, 2053, 2055, 2056, 2057, - 2059, 2061, 2063, 2065, 2067, 2069, 2070, 2071, 2072, 2074, - 2076, 2078, 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, - 2095, 2096, 2097, 2099, 2101, 2105, 2106, 2107, 2108, 2109, - 2110, 2111, 2113, 2115, 2119, 2121, 2123, 2125, 2127, 2129, - 2131, 2133, 2135, 2136, 2137, 2139, 2141, 2143, 2145, 2147, - 2149, 2151, 2153, 2155, 2157, 2159, 2161, 2163, 2165, 2167, - - /* 501-600 */ - 2169, 2171, 2173, 2175, 2177, 2179, 2181, 2183, 2185, 2186, - 2187, 2188, 2192, 2193, 2195, 2197, 2199, 2201, 2203, 2205, - 2207, 2209, 2211, 2213, 2217, 2219, 2221, 2223, 2225, 2227, - 2229, 2231, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, - 2241, 2244, 2246, 2248, 2250, 2252, 2254, 2256, 2258, 2260, - 2262, 2264, 2266, 2268, 2270, 2272, 2274, 2276, 2278, 2280, - 2282, 2284, 2286, 2288, 2290, 2292, 2294, 2296, 2298, 2300, - 2302, 2303, 2304, 2305, 2306, 2307, 2309, 2311, 2313, 2315, - 2317, 2319, 2321, 2323, 2325, 2327, 2329, 2331, 2333, 2335, - 2337, 2341, 2343, 2345, 2347, 2349, 2351, 2352, 2355, 2356, - - /* 601-700 */ - 2357, 2358, 2359, 2361, 2363, 2364, 2365, 2366, 2367, 2368, - 2369, 2370, 2371, 2372, 2373, 2374, 2376, 2378, 2380, 2382, - 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, - 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, - 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, - 2414, 2415, 2417, 2418, 2430, 2438, 2445, 2453, 2460, 2468, - 2474, 2480, 2488, 2496, 2504, 2512, 2520, 2527, 2535, 2543, - 2550, 2558, 2566, 2574, 2580, 2588, 2596, 2604, 2612, 2619, - 2627, 2634, 2642, 2648, 2656, 2664, 2671, 2679, 2685, 2693, - 2701, 2709, 2717, 2725, 2733, 2739, 2747, 2753, 2761, 2769, - - /* 701-800 */ - 2777, 2785, 2793, 2801, 2809, 2817, 2825, 2833, 2841, 2848, - 2856, 2864, 2872, 2878, 2884, 2892, 2898, 2906, 2914, 2922, - 2930, 2938, 2944, 2952, 2958, 2966, 2974, 2982, 2988, 2996, - 3001, 3009, 3017, 3025, 3032, 3039, 3045, 3052, 3059, 3067, - 3069, 3076, 3083, 3090, 3098, 3105, 3109, 3111, 3113, 3120, - 3124, 3128, 3132, 3136, 3140, 3144, 3146, 3150, 3158, 3161, - 3165, 3166, 3168, 3172, 3176, 3180, 3182, 3185, 3189, 3193, - 3194, 3197, 3200, 3204, 3208, 3212, 3216, 3219, 3221, 3222, - 3226, 3230, 3234, 3238, 3242, 3243, 3247, 3251, 3254, 3258, - 3262, 3266, 3270, 3274, 3275, 3279, 3283, 3287, 3289, 3293, - - /* 801-900 */ - 3296, 3300, 3303, 3307, 3311, 3315, 3319, 3321, 3324, 3327, - 3330, 3334, 3338, 3340, 3342, 3346, 3350, 3354, 3358, 3361, - 3365, 3369, 3373, 3377, 3381, 3385, 3389, 3393, 3394, 3398, - 3402, 3406, 3410, 3413, 3417, 3421, 3425, 3429, 3433, 3435, - 3439, 3443, 3446, 3450, 3453, 3457, 3458, 3461, 3464, 3468, - 3472, 3476, 3478, 3481, 3485, 3489, 3493, 3497, 3501, 3505, - 3507, 3511, 3514, 3517, 3521, 3524, 3525, 3527, 3529, 3533, - 3536, 3540, 3541, 3545, 3548, 3551, 3555, 3559, 3563, 3567, - 3569, 3570, 3574, 3576, 3578, 3582, 3586, 3590, 3593, 3596, - 3600, 3604, 3608, 3612, 3616, 3620, 3623, 3626, 3630, 3632, - - /* 901-1000 */ - 3636, 3640, 3643, 3646, 3648, 3652, 3656, 3660, 3664, 3667, - 3669, 3671, 3675, 3679, 3683, 3687, 3689, 3693, 3694, 3695, - 3699, 3703, 3705, 3707, 3710, 3713, 3717, 3721, 3725, 3729, - 3733, 3736, 3740, 3744, 3748, 3752, 3754, 3757, 3759, 3763, - 3767, 3770, 3773, 3777, 3779, 3783, 3786, 3790, 3794, 3798, - 3801, 3805, 3809, 3813, 3817, 3821, 3825, 3827, 3831, 3835, - 3836, 3837, 3840, 3844, 3848, 3852, 3856, 3859, 3863, 3867, - 3869, 3871, 3875, 3879, 3883, 3887, 3890, 3894, 3898, 3901, - 3905, 3909, 3913, 3917, 3921, 3922, 3923, 3924, 3926, 3930, - 3932, 3936, 3938, 3940, 3944, 3948, 3952, 3956, 3959, 3963, - - /* 1001-1100 */ - 3965, 3969, 3973, 3977, 3979, 3981, 3982, 3986, 3989, 3993, - 3997, 4001, 4004, 4006, 4009, 4012, 4016, 4020, 4024, 4026, - 4028, 4032, 4036, 4040, 4044, 4046, 4050, 4054, 4058, 4060, - 4062, 4063, 4064, 4068, 4071, 4075, 4077, 4081, 4083, 4087, - 4089, 4091, 4095, 4099, 4101, 4103, 4105, 4107, 4111, 4115, - 4119, 4123, 4127, 4129, 4131, 4135, 4139, 4141, 4143, 4145, - 4149, 4153, 4157, 4161, 4165, 4169, 4173, 4177, 4180, 4183, - 4187, 4191, 4195, 4198, 4201, 4205, 4209, 4212, 4213, 4216, - 4217, 4221, 4223, 4226, 4230, 4234, 4236, 4240, 4244, 4248, - 4252, 4256, 4258, 4262, 4264, 4266, 4268, 4270, 4272, 4276, - - /* 1101-1200 */ - 4279, 4283, 4285, 4287, 4289, 4293, 4295, 4299, 4300, 4301, - 4305, 4309, 4313, 4317, 4319, 4323, 4325, 4329, 4331, 4333, - 4335, 4337, 4341, 4345, 4349, 4351, 4353, 4357, 4361, 4365, - 4367, 4369, 4373, 4377, 4381, 4383, 4387, 4389, 4391, 4395, - 4399, 4403, 4407, 4411, 4413, 4414, 4415, 4418, 4419, 4421, - 4423, 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4443, 4446, - 4450, 4452, 4456, 4458, 4460, 4462, 4466, 4469, 4473, 4477, - 4481, 4483, 4487, 4489, 4491, 4493, 4497, 4499, 4501, 4504, - 4506, 4510, 4513, 4514, 4515, 4518, 4521, 4522, 4525, 4526, - 4527, 4530, 4533, 4534, 4537, 4541, 4542, 4543, 4544, 4545, - - /* 1201-1300 */ - 4546, 4547, 4550, 4553, 4554, 4555, 4558, 4561, 4564, 4567, - 4568, 4571, 4574, 4575, 4578, 4581, 4582, 4585, 4586, 4588, - 4590, 4592, 4596, 4598, 4602, 4604, 4608, 4612, 4613, 4616, - 4619, 4622, 4623, 4624, 4625, 4626, 4629, 4632, 4633, 4636, - 4639, 4640, 4641, 4642, 4643, 4644, 4645, 4648, 4649, 4650, - 4651, 4652, 4653, 4656, 4657, 4660, 4661, 4664, 4667, 4670, - 4671, 4674, 4675, 4676, 4677, 4678, 4681, 4682, 4683, 4684, - 4687, 4688, 4689, 4692, 4693, 4696, 4697, 4700, 4701, 4702, - 4703, 4704, 4707, 4708, 4711, 4712, 4715, 4716, 4717, 4718, - 4719, 4720, 4721, 4722, 4723, 4726, 4729, 4730, 4733, 4736, - - /* 1301-(NFLS+NFPL) */ - 4737, 4740, 4741, 4742, 4745, 4746, 4749, 4752, 4753 - }; - -/* Amplitude coefficients (microarcsec); indexed using the nc array. */ - static const double a[] = { - - /* 1-105 */ - -6844318.44, 9205236.26,1328.67,1538.18, 205833.11, - 153041.79, -3309.73, 853.32,2037.98, -2301.27, - 81.46, 120.56, -20.39, -15.22, 1.73, -1.61, -0.10, 0.11, - -0.02, -0.02, -523908.04, 573033.42,-544.75,-458.66, - 12814.01, 11714.49, 198.97,-290.91, 155.74,-143.27, - -2.75, -1.03, -1.27, -1.16, 0.00, -0.01, -90552.22, - 97846.69, 111.23, 137.41,2187.91,2024.68, 41.44, -51.26, - 26.92, -24.46, -0.46, -0.28, -0.22, -0.20, 82168.76, - -89618.24, -27.64, -29.05, -2004.36, -1837.32, - -36.07, 48.00, -24.43, 22.41, 0.47, 0.24, 0.20, 0.18, - 58707.02,7387.02, 470.05,-192.40, 164.33, -1312.21, - -179.73, -28.93, -17.36, -1.83, -0.50, 3.57, 0.00, 0.13, - -20557.78, 22438.42, -20.84, -17.40, 501.82, 459.68, - 59.20, -67.30, 6.08, -5.61, -1.36, -1.19, 28288.28, - -674.99, -34.69, 35.80, -15.07,-632.54, -11.19, 0.78, -8.41, - 0.17, 0.01, 0.07, -15406.85, 20069.50, 15.12, - - /* 106-219 */ - 31.80, 448.76, 344.50, -5.77, 1.41, 4.59, -5.02, 0.17, - 0.24, -11991.74, 12902.66, 32.46, 36.70, 288.49, - 268.14, 5.70, -7.06, 3.57, -3.23, -0.06, -0.04, - -8584.95, -9592.72, 4.42, -13.20,-214.50, 192.06, - 23.87, 29.83, 2.54, 2.40, 0.60, -0.48,5095.50, - -6918.22, 7.19, 3.92,-154.91,-113.94, 2.86, -1.04, - -1.52, 1.73, -0.07, -0.10, -4910.93, -5331.13, - 0.76, 0.40,-119.21, 109.81, 2.16, 3.20, 1.46, 1.33, - 0.04, -0.02, -6245.02,-123.48, -6.68, -8.20, -2.76, - 139.64, 2.71, 0.15, 1.86,2511.85, -3323.89, 1.07, - -0.90, -74.33, -56.17, 1.16, -0.01, -0.75, 0.83, -0.02, - -0.04,2307.58,3143.98, -7.52, 7.50, 70.31, -51.60, 1.46, - 0.16, -0.69, -0.79, 0.02, -0.05,2372.58,2554.51, 5.93, - -6.60, 57.12, -53.05, -0.96, -1.24, -0.71, -0.64, -0.01, - -2053.16,2636.13, 5.13, 7.80, 58.94, 45.91, -0.42, - -0.12, 0.61, -0.66, 0.02, 0.03, -1825.49, - - /* 220-339 */ - -2423.59, 1.23, -2.00, -54.19, 40.82, -1.07, -1.02, - 0.54, 0.61, -0.04, 0.04,2521.07,-122.28, -5.97, 2.90, - -2.73, -56.37, -0.82, 0.13, -0.75, -1534.09,1645.01, - 6.29, 6.80, 36.78, 34.30, 0.92, -1.25, 0.46, -0.41, - -0.02, -0.01,1898.27, 47.70, -0.72, 2.50, 1.07, -42.45, - -0.94, 0.02, -0.56, -1292.02, -1387.00, 0.00, - 0.00, -31.01, 28.89, 0.68, 0.00, 0.38, 0.35, -0.01, - -0.01, -1234.96,1323.81, 5.21, 5.90, 29.60, 27.61, - 0.74, -1.22, 0.37, -0.33, -0.02, -0.01,1137.48, - -1233.89, -0.04, -0.30, -27.59, -25.43, -0.61, 1.00, - -0.34, 0.31, 0.01, 0.01,-813.13, -1075.60, 0.40, - 0.30, -24.05, 18.18, -0.40, -0.01, 0.24, 0.27, -0.01, - 0.01,1163.22, -60.90, -2.94, 1.30, -1.36, -26.01, -0.58, - 0.07, -0.35,1029.70, -55.55, -2.63, 1.10, -1.25, -23.02, - -0.52, 0.06, -0.31,-556.26, 852.85, 3.16, -4.48, 19.06, - 12.44, -0.81, -0.27, 0.17, -0.21, 0.00, 0.02,-603.52, - - /* 340-467 */ - -800.34, 0.44, 0.10, -17.90, 13.49, -0.08, -0.01, 0.18, - 0.20, -0.01, 0.01,-628.24, 684.99, -0.64, -0.50, 15.32, - 14.05, 3.18, -4.19, 0.19, -0.17, -0.09, -0.07,-866.48, - -16.26, 0.52, -1.30, -0.36, 19.37, 0.43, -0.01, 0.26, - -512.37, 695.54, -1.47, -1.40, 15.55, 11.46, -0.16, 0.03, - 0.15, -0.17, 0.01, 0.01, 506.65, 643.75, 2.54, -2.62, - 14.40, -11.33, -0.77, -0.06, -0.15, -0.16, 0.00, 0.01, - 664.57, 16.81, -0.40, 1.00, 0.38, -14.86, -3.71, -0.09, - -0.20, 405.91, 522.11, 0.99, -1.50, 11.67, -9.08, -0.25, - -0.02, -0.12, -0.13,-305.78, 326.60, 1.75, 1.90, 7.30, - 6.84, 0.20, -0.04, 300.99,-325.03, -0.44, -0.50, -7.27, - -6.73, -1.01, 0.01, 0.00, 0.08, 0.00, 0.02, 438.51, - 10.47, -0.56, -0.20, 0.24, -9.81, -0.24, 0.01, -0.13, - -264.02, 335.24, 0.99, 1.40, 7.49, 5.90, -0.27, -0.02, - 284.09, 307.03, 0.32, -0.40, 6.87, -6.35, -0.99, -0.01, - -250.54, 327.11, 0.08, 0.40, 7.31, 5.60, -0.30, 230.72, - - /* 468-595 */ - -304.46, 0.08, -0.10, -6.81, -5.16, 0.27, 229.78, 304.17, - -0.60, 0.50, 6.80, -5.14, 0.33, 0.01, 256.30,-276.81, - -0.28, -0.40, -6.19, -5.73, -0.14, 0.01,-212.82, 269.45, - 0.84, 1.20, 6.02, 4.76, 0.14, -0.02, 196.64, 272.05, - -0.84, 0.90, 6.08, -4.40, 0.35, 0.02, 188.95, 272.22, - -0.12, 0.30, 6.09, -4.22, 0.34,-292.37, -5.10, -0.32, - -0.40, -0.11, 6.54, 0.14, 0.01, 161.79,-220.67, 0.24, - 0.10, -4.93, -3.62, -0.08, 261.54, -19.94, -0.95, 0.20, - -0.45, -5.85, -0.13, 0.02, 142.16,-190.79, 0.20, 0.10, - -4.27, -3.18, -0.07, 187.95, -4.11, -0.24, 0.30, -0.09, - -4.20, -0.09, 0.01, 0.00, 0.00, -79.08, 167.90, 0.04, - 0.00, 3.75, 1.77, 121.98, 131.04, -0.08, 0.10, 2.93, - -2.73, -0.06,-172.95, -8.11, -0.40, -0.20, -0.18, 3.87, - 0.09, 0.01,-160.15, -55.30, -14.04, 13.90, -1.23, 3.58, - 0.40, 0.31,-115.40, 123.20, 0.60, 0.70, 2.75, 2.58, - 0.08, -0.01,-168.26, -2.00, 0.20, -0.20, -0.04, 3.76, - - /* 596-723 */ - 0.08,-114.49, 123.20, 0.32, 0.40, 2.75, 2.56, 0.07, - -0.01, 112.14, 120.70, 0.28, -0.30, 2.70, -2.51, -0.07, - -0.01, 161.34, 4.03, 0.20, 0.20, 0.09, -3.61, -0.08, - 91.31, 126.64, -0.40, 0.40, 2.83, -2.04, -0.04, 0.01, - 105.29, 112.90, 0.44, -0.50, 2.52, -2.35, -0.07, -0.01, - 98.69,-106.20, -0.28, -0.30, -2.37, -2.21, -0.06, 0.01, - 86.74,-112.94, -0.08, -0.20, -2.53, -1.94, -0.05,-134.81, - 3.51, 0.20, -0.20, 0.08, 3.01, 0.07, 79.03, 107.31, - -0.24, 0.20, 2.40, -1.77, -0.04, 0.01, 132.81, -10.77, - -0.52, 0.10, -0.24, -2.97, -0.07, 0.01,-130.31, -0.90, - 0.04, 0.00, 0.00, 2.91, -78.56, 85.32, 0.00, 0.00, - 1.91, 1.76, 0.04, 0.00, 0.00, -41.53, 89.10, 0.02, - 0.00, 1.99, 0.93, 66.03, -71.00, -0.20, -0.20, -1.59, - -1.48, -0.04, 60.50, 64.70, 0.36, -0.40, 1.45, -1.35, - -0.04, -0.01, -52.27, -70.01, 0.00, 0.00, -1.57, 1.17, - 0.03, -52.95, 66.29, 0.32, 0.40, 1.48, 1.18, 0.04, - - /* 724-851 */ - -0.01, 51.02, 67.25, 0.00, 0.00, 1.50, -1.14, -0.03, - -55.66, -60.92, 0.16, -0.20, -1.36, 1.24, 0.03, -54.81, - -59.20, -0.08, 0.20, -1.32, 1.23, 0.03, 51.32, -55.60, - 0.00, 0.00, -1.24, -1.15, -0.03, 48.29, 51.80, 0.20, - -0.20, 1.16, -1.08, -0.03, -45.59, -49.00, -0.12, 0.10, - -1.10, 1.02, 0.03, 40.54, -52.69, -0.04, -0.10, -1.18, - -0.91, -0.02, -40.58, -49.51, -1.00, 1.00, -1.11, 0.91, - 0.04, 0.02, -43.76, 46.50, 0.36, 0.40, 1.04, 0.98, - 0.03, -0.01, 62.65, -5.00, -0.24, 0.00, -0.11, -1.40, - -0.03, 0.01, -38.57, 49.59, 0.08, 0.10, 1.11, 0.86, - 0.02, -33.22, -44.04, 0.08, -0.10, -0.98, 0.74, 0.02, - 37.15, -39.90, -0.12, -0.10, -0.89, -0.83, -0.02, 36.68, - -39.50, -0.04, -0.10, -0.88, -0.82, -0.02, -53.22, -3.91, - -0.20, 0.00, -0.09, 1.19, 0.03, 32.43, -42.19, -0.04, - -0.10, -0.94, -0.73, -0.02, -51.00, -2.30, -0.12, -0.10, - 0.00, 1.14, -29.53, -39.11, 0.04, 0.00, -0.87, 0.66, - - /* 852-979 */ - 0.02, 28.50, -38.92, -0.08, -0.10, -0.87, -0.64, -0.02, - 26.54, 36.95, -0.12, 0.10, 0.83, -0.59, -0.01, 26.54, - 34.59, 0.04, -0.10, 0.77, -0.59, -0.02, 28.35, -32.55, - -0.16, 0.20, -0.73, -0.63, -0.01, -28.00, 30.40, 0.00, - 0.00, 0.68, 0.63, 0.01, -27.61, 29.40, 0.20, 0.20, - 0.66, 0.62, 0.02, 40.33, 0.40, -0.04, 0.10, 0.00, - -0.90, -23.28, 31.61, -0.08, -0.10, 0.71, 0.52, 0.01, - 37.75, 0.80, 0.04, 0.10, 0.00, -0.84, 23.66, 25.80, - 0.00, 0.00, 0.58, -0.53, -0.01, 21.01, -27.91, 0.00, - 0.00, -0.62, -0.47, -0.01, -34.81, 2.89, 0.04, 0.00, - 0.00, 0.78, -23.49, -25.31, 0.00, 0.00, -0.57, 0.53, - 0.01, -23.47, 25.20, 0.16, 0.20, 0.56, 0.52, 0.02, - 19.58, 27.50, -0.12, 0.10, 0.62, -0.44, -0.01, -22.67, - -24.40, -0.08, 0.10, -0.55, 0.51, 0.01, -19.97, 25.00, - 0.12, 0.20, 0.56, 0.45, 0.01, 21.28, -22.80, -0.08, - -0.10, -0.51, -0.48, -0.01, -30.47, 0.91, 0.04, 0.00, - - /* 980-1107 */ - 0.00, 0.68, 18.58, 24.00, 0.04, -0.10, 0.54, -0.42, - -0.01, -18.02, 24.40, -0.04, -0.10, 0.55, 0.40, 0.01, - 17.74, 22.50, 0.08, -0.10, 0.50, -0.40, -0.01, -19.41, - 20.70, 0.08, 0.10, 0.46, 0.43, 0.01, -18.64, 20.11, - 0.00, 0.00, 0.45, 0.42, 0.01, -16.75, 21.60, 0.04, - 0.10, 0.48, 0.37, 0.01, -18.42, -20.00, 0.00, 0.00, - -0.45, 0.41, 0.01, -26.77, 1.41, 0.08, 0.00, 0.00, - 0.60, -26.17, -0.19, 0.00, 0.00, 0.00, 0.59, -15.52, - 20.51, 0.00, 0.00, 0.46, 0.35, 0.01, -25.42, -1.91, - -0.08, 0.00, -0.04, 0.57, 0.45, -17.42, 18.10, 0.00, - 0.00, 0.40, 0.39, 0.01, 16.39, -17.60, -0.08, -0.10, - -0.39, -0.37, -0.01, -14.37, 18.91, 0.00, 0.00, 0.42, - 0.32, 0.01, 23.39, -2.40, -0.12, 0.00, 0.00, -0.52, - 14.32, -18.50, -0.04, -0.10, -0.41, -0.32, -0.01, 15.69, - 17.08, 0.00, 0.00, 0.38, -0.35, -0.01, -22.99, 0.50, - 0.04, 0.00, 0.00, 0.51, 0.00, 0.00, 14.47, -17.60, - - /* 1108-1235 */ - -0.01, 0.00, -0.39, -0.32, -13.33, 18.40, -0.04, -0.10, - 0.41, 0.30, 22.47, -0.60, -0.04, 0.00, 0.00, -0.50, - -12.78, -17.41, 0.04, 0.00, -0.39, 0.29, 0.01, -14.10, - -15.31, 0.04, 0.00, -0.34, 0.32, 0.01, 11.98, 16.21, - -0.04, 0.00, 0.36, -0.27, -0.01, 19.65, -1.90, -0.08, - 0.00, 0.00, -0.44, 19.61, -1.50, -0.08, 0.00, 0.00, - -0.44, 13.41, -14.30, -0.04, -0.10, -0.32, -0.30, -0.01, - -13.29, 14.40, 0.00, 0.00, 0.32, 0.30, 0.01, 11.14, - -14.40, -0.04, 0.00, -0.32, -0.25, -0.01, 12.24, -13.38, - 0.04, 0.00, -0.30, -0.27, -0.01, 10.07, -13.81, 0.04, - 0.00, -0.31, -0.23, -0.01, 10.46, 13.10, 0.08, -0.10, - 0.29, -0.23, -0.01, 16.55, -1.71, -0.08, 0.00, 0.00, - -0.37, 9.75, -12.80, 0.00, 0.00, -0.29, -0.22, -0.01, - 9.11, 12.80, 0.00, 0.00, 0.29, -0.20, 0.00, 0.00, - -6.44, -13.80, 0.00, 0.00, -0.31, 0.14, -9.19, -12.00, - 0.00, 0.00, -0.27, 0.21, -10.30, 10.90, 0.08, 0.10, - - /* 1236-1363 */ - 0.24, 0.23, 0.01, 14.92, -0.80, -0.04, 0.00, 0.00, - -0.33, 10.02, -10.80, 0.00, 0.00, -0.24, -0.22, -0.01, - -9.75, 10.40, 0.04, 0.00, 0.23, 0.22, 0.01, 9.67, - -10.40, -0.04, 0.00, -0.23, -0.22, -0.01, -8.28, -11.20, - 0.04, 0.00, -0.25, 0.19, 13.32, -1.41, -0.08, 0.00, - 0.00, -0.30, 8.27, 10.50, 0.04, 0.00, 0.23, -0.19, - 0.00, 0.00, 13.13, 0.00, 0.00, 0.00, 0.00, -0.29, - -12.93, 0.70, 0.04, 0.00, 0.00, 0.29, 7.91, -10.20, - 0.00, 0.00, -0.23, -0.18, -7.84, -10.00, -0.04, 0.00, - -0.22, 0.18, 7.44, 9.60, 0.00, 0.00, 0.21, -0.17, - -7.64, 9.40, 0.08, 0.10, 0.21, 0.17, 0.01, -11.38, - 0.60, 0.04, 0.00, 0.00, 0.25, -7.48, 8.30, 0.00, - 0.00, 0.19, 0.17, -10.98, -0.20, 0.00, 0.00, 0.00, - 0.25, 10.98, 0.20, 0.00, 0.00, 0.00, -0.25, 7.40, - -7.90, -0.04, 0.00, -0.18, -0.17, -6.09, 8.40, -0.04, - 0.00, 0.19, 0.14, -6.94, -7.49, 0.00, 0.00, -0.17, - - /* 1364-1491 */ - 0.16, 6.92, 7.50, 0.04, 0.00, 0.17, -0.15, 6.20, - 8.09, 0.00, 0.00, 0.18, -0.14, -6.12, 7.80, 0.04, - 0.00, 0.17, 0.14, 5.85, -7.50, 0.00, 0.00, -0.17, - -0.13, -6.48, 6.90, 0.08, 0.10, 0.15, 0.14, 0.01, - 6.32, 6.90, 0.00, 0.00, 0.15, -0.14, 5.61, -7.20, - 0.00, 0.00, -0.16, -0.13, 9.07, 0.00, 0.00, 0.00, - 0.00, -0.20, 5.25, 6.90, 0.00, 0.00, 0.15, -0.12, - -8.47, -0.40, 0.00, 0.00, 0.00, 0.19, 6.32, -5.39, - -1.11, 1.10, -0.12, -0.14, 0.02, 0.02, 5.73, -6.10, - -0.04, 0.00, -0.14, -0.13, 4.70, 6.60, -0.04, 0.00, - 0.15, -0.11, -4.90, -6.40, 0.00, 0.00, -0.14, 0.11, - -5.33, 5.60, 0.04, 0.10, 0.13, 0.12, 0.01, -4.81, - 6.00, 0.04, 0.00, 0.13, 0.11, 5.13, 5.50, 0.04, - 0.00, 0.12, -0.11, 4.50, 5.90, 0.00, 0.00, 0.13, - -0.10, -4.22, 6.10, 0.00, 0.00, 0.14, -4.53, 5.70, - 0.00, 0.00, 0.13, 0.10, 4.18, 5.70, 0.00, 0.00, - - /* 1492-1619 */ - 0.13, -4.75, -5.19, 0.00, 0.00, -0.12, 0.11, -4.06, - 5.60, 0.00, 0.00, 0.13, -3.98, 5.60, -0.04, 0.00, - 0.13, 4.02, -5.40, 0.00, 0.00, -0.12, 4.49, -4.90, - -0.04, 0.00, -0.11, -0.10, -3.62, -5.40, -0.16, 0.20, - -0.12, 0.00, 0.01, 4.38, 4.80, 0.00, 0.00, 0.11, - -6.40, -0.10, 0.00, 0.00, 0.00, 0.14, -3.98, 5.00, - 0.04, 0.00, 0.11, -3.82, -5.00, 0.00, 0.00, -0.11, - -3.71, 5.07, 0.00, 0.00, 0.11, 4.14, 4.40, 0.00, - 0.00, 0.10, -6.01, -0.50, -0.04, 0.00, 0.00, 0.13, - -4.04, 4.39, 0.00, 0.00, 0.10, 3.45, -4.72, 0.00, - 0.00, -0.11, 3.31, 4.71, 0.00, 0.00, 0.11, 3.26, - -4.50, 0.00, 0.00, -0.10, -3.26, -4.50, 0.00, 0.00, - -0.10, -3.34, -4.40, 0.00, 0.00, -0.10, -3.74, -4.00, - 3.70, 4.00, 3.34, -4.30, 3.30, -4.30, -3.66, 3.90, - 0.04, 3.66, 3.90, 0.04, -3.62, -3.90, -3.61, 3.90, - -0.20, 5.30, 0.00, 0.00, 0.12, 3.06, 4.30, 3.30, - - /* 1620-1747 */ - 4.00, 0.40, 0.20, 3.10, 4.10, -3.06, 3.90, -3.30, - -3.60, -3.30, 3.36, 0.01, 3.14, 3.40, -4.57, -0.20, - 0.00, 0.00, 0.00, 0.10, -2.70, -3.60, 2.94, -3.20, - -2.90, 3.20, 2.47, -3.40, 2.55, -3.30, 2.80, -3.08, - 2.51, 3.30, -4.10, 0.30, -0.12, -0.10, 4.10, 0.20, - -2.74, 3.00, 2.46, 3.23, -3.66, 1.20, -0.20, 0.20, - 3.74, -0.40, -2.51, -2.80, -3.74, 2.27, -2.90, 0.00, - 0.00, -2.50, 2.70, -2.51, 2.60, -3.50, 0.20, 3.38, - -2.22, -2.50, 3.26, -0.40, 1.95, -2.60, 3.22, -0.40, - -0.04, -1.79, -2.60, 1.91, 2.50, 0.74, 3.05, -0.04, - 0.08, 2.11, -2.30, -2.11, 2.20, -1.87, -2.40, 2.03, - -2.20, -2.03, 2.20, 2.98, 0.00, 0.00, 2.98, -1.71, - 2.40, 2.94, -0.10, -0.12, 0.10, 1.67, 2.40, -1.79, - 2.30, -1.79, 2.20, -1.67, 2.20, 1.79, -2.00, 1.87, - -1.90, 1.63, -2.10, -1.59, 2.10, 1.55, -2.10, -1.55, - 2.10, -2.59, -0.20, -1.75, -1.90, -1.75, 1.90, -1.83, - - /* 1748-1875 */ - -1.80, 1.51, 2.00, -1.51, -2.00, 1.71, 1.80, 1.31, - 2.10, -1.43, 2.00, 1.43, 2.00, -2.43, -1.51, 1.90, - -1.47, 1.90, 2.39, 0.20, -2.39, 1.39, 1.90, 1.39, - -1.80, 1.47, -1.60, 1.47, -1.60, 1.43, -1.50, -1.31, - 1.60, 1.27, -1.60, -1.27, 1.60, 1.27, -1.60, 2.03, - 1.35, 1.50, -1.39, -1.40, 1.95, -0.20, -1.27, 1.49, - 1.19, 1.50, 1.27, 1.40, 1.15, 1.50, 1.87, -0.10, - -1.12, -1.50, 1.87, -1.11, -1.50, -1.11, -1.50, 0.00, - 0.00, 1.19, 1.40, 1.27, -1.30, -1.27, -1.30, -1.15, - 1.40, -1.23, 1.30, -1.23, -1.30, 1.22, -1.29, 1.07, - -1.40, 1.75, -0.20, -1.03, -1.40, -1.07, 1.20, -1.03, - 1.15, 1.07, 1.10, 1.51, -1.03, 1.10, 1.03, -1.10, - 0.00, 0.00, -1.03, -1.10, 0.91, -1.20, -0.88, -1.20, - -0.88, 1.20, -0.95, 1.10, -0.95, -1.10, 1.43, -1.39, - 0.95, -1.00, -0.95, 1.00, -0.80, 1.10, 0.91, -1.00, - -1.35, 0.88, 1.00, -0.83, 1.00, -0.91, 0.90, 0.91, - - /* 1876-2003 */ - 0.90, 0.88, -0.90, -0.76, -1.00, -0.76, 1.00, 0.76, - 1.00, -0.72, 1.00, 0.84, -0.90, 0.84, 0.90, 1.23, - 0.00, 0.00, -0.52, -1.10, -0.68, 1.00, 1.19, -0.20, - 1.19, 0.76, 0.90, 1.15, -0.10, 1.15, -0.10, 0.72, - -0.90, -1.15, -1.15, 0.68, 0.90, -0.68, 0.90, -1.11, - 0.00, 0.00, 0.20, 0.79, 0.80, -1.11, -0.10, 0.00, - 0.00, -0.48, -1.00, -0.76, -0.80, -0.72, -0.80, -1.07, - -0.10, 0.64, 0.80, -0.64, -0.80, 0.64, 0.80, 0.40, - 0.60, 0.52, -0.50, -0.60, -0.80, -0.71, 0.70, -0.99, - 0.99, 0.56, 0.80, -0.56, 0.80, 0.68, -0.70, 0.68, - 0.70, -0.95, -0.64, 0.70, 0.64, 0.70, -0.60, 0.70, - -0.60, -0.70, -0.91, -0.10, -0.51, 0.76, -0.91, -0.56, - 0.70, 0.88, 0.88, -0.63, -0.60, 0.55, -0.60, -0.80, - 0.80, -0.80, -0.52, 0.60, 0.52, 0.60, 0.52, -0.60, - -0.48, 0.60, 0.48, 0.60, 0.48, 0.60, -0.76, 0.44, - -0.60, 0.52, -0.50, -0.52, 0.50, 0.40, 0.60, -0.40, - - /* 2004-2131 */ - -0.60, 0.40, -0.60, 0.72, -0.72, -0.51, -0.50, -0.48, - 0.50, 0.48, -0.50, -0.48, 0.50, -0.48, 0.50, 0.48, - -0.50, -0.48, -0.50, -0.68, -0.68, 0.44, 0.50, -0.64, - -0.10, -0.64, -0.10, -0.40, 0.50, 0.40, 0.50, 0.40, - 0.50, 0.00, 0.00, -0.40, -0.50, -0.36, -0.50, 0.36, - -0.50, 0.60, -0.60, 0.40, -0.40, 0.40, 0.40, -0.40, - 0.40, -0.40, 0.40, -0.56, -0.56, 0.36, -0.40, -0.36, - 0.40, 0.36, -0.40, -0.36, -0.40, 0.36, 0.40, 0.36, - 0.40, -0.52, 0.52, 0.52, 0.32, 0.40, -0.32, 0.40, - -0.32, 0.40, -0.32, 0.40, 0.32, -0.40, -0.32, -0.40, - 0.32, -0.40, 0.28, -0.40, -0.28, 0.40, 0.28, -0.40, - 0.28, 0.40, 0.48, -0.48, 0.48, 0.36, -0.30, -0.36, - -0.30, 0.00, 0.00, 0.20, 0.40, -0.44, 0.44, -0.44, - -0.44, -0.44, -0.44, 0.32, -0.30, 0.32, 0.30, 0.24, - 0.30, -0.12, -0.10, -0.28, 0.30, 0.28, 0.30, 0.28, - 0.30, 0.28, -0.30, 0.28, -0.30, 0.28, -0.30, 0.28, - - /* 2132-2259 */ - 0.30, -0.28, 0.30, 0.40, 0.40, -0.24, 0.30, 0.24, - -0.30, 0.24, -0.30, -0.24, -0.30, 0.24, 0.30, 0.24, - -0.30, -0.24, 0.30, 0.24, -0.30, -0.24, -0.30, 0.24, - -0.30, 0.24, 0.30, -0.24, 0.30, -0.24, 0.30, 0.20, - -0.30, 0.20, -0.30, 0.20, -0.30, 0.20, 0.30, 0.20, - -0.30, 0.20, -0.30, 0.20, 0.30, 0.20, 0.30, -0.20, - -0.30, 0.20, -0.30, 0.20, -0.30, -0.36, -0.36, -0.36, - -0.04, 0.30, 0.12, -0.10, -0.32, -0.24, 0.20, 0.24, - 0.20, 0.20, -0.20, -0.20, -0.20, -0.20, -0.20, 0.20, - 0.20, 0.20, -0.20, 0.20, 0.20, 0.20, 0.20, -0.20, - -0.20, 0.00, 0.00, -0.20, -0.20, -0.20, 0.20, -0.20, - 0.20, 0.20, -0.20, -0.20, -0.20, 0.20, 0.20, 0.20, - 0.20, 0.20, -0.20, 0.20, -0.20, 0.28, 0.28, 0.28, - 0.28, 0.28, 0.28, -0.28, 0.28, 0.12, 0.00, 0.24, - 0.16, -0.20, 0.16, -0.20, 0.16, -0.20, 0.16, 0.20, - -0.16, 0.20, 0.16, 0.20, -0.16, 0.20, -0.16, 0.20, - - /* 2260-2387 */ - -0.16, 0.20, 0.16, -0.20, 0.16, 0.20, 0.16, -0.20, - -0.16, 0.20, -0.16, -0.20, -0.16, 0.20, 0.16, 0.20, - 0.16, -0.20, 0.16, -0.20, 0.16, 0.20, 0.16, 0.20, - 0.16, 0.20, -0.16, -0.20, 0.16, 0.20, -0.16, 0.20, - 0.16, 0.20, -0.16, -0.20, 0.16, -0.20, 0.16, -0.20, - -0.16, -0.20, 0.24, -0.24, -0.24, 0.24, 0.24, 0.12, - 0.20, 0.12, 0.20, -0.12, -0.20, 0.12, -0.20, 0.12, - -0.20, -0.12, 0.20, -0.12, 0.20, -0.12, -0.20, 0.12, - 0.20, 0.12, 0.20, 0.12, -0.20, -0.12, 0.20, 0.12, - -0.20, -0.12, 0.20, 0.12, 0.20, 0.00, 0.00, -0.12, - 0.20, -0.12, 0.20, 0.12, -0.20, -0.12, 0.20, 0.12, - 0.20, 0.00, -0.21, -0.20, 0.00, 0.00, 0.20, -0.20, - -0.20, -0.20, 0.20, -0.16, -0.10, 0.00, 0.17, 0.16, - 0.16, 0.16, 0.16, -0.16, 0.16, 0.16, -0.16, 0.16, - -0.16, 0.16, 0.12, 0.10, 0.12, -0.10, -0.12, 0.10, - -0.12, 0.10, 0.12, -0.10, -0.12, 0.12, -0.12, 0.12, - - /* 2388-2515 */ - -0.12, 0.12, -0.12, -0.12, -0.12, -0.12, -0.12, -0.12, - -0.12, 0.12, 0.12, 0.12, 0.12, -0.12, -0.12, 0.12, - 0.12, 0.12, -0.12, 0.12, -0.12, -0.12, -0.12, 0.12, - -0.12, -0.12, 0.12, 0.00, 0.11, 0.11,-122.67, 164.70, - 203.78, 273.50, 3.58, 2.74, 6.18, -4.56, 0.00, -0.04, - 0.00, -0.07, 57.44, -77.10, 95.82, 128.60, -1.77, -1.28, - 2.85, -2.14, 82.14, 89.50, 0.00, 0.00, 2.00, -1.84, - -0.04, 47.73, -64.10, 23.79, 31.90, -1.45, -1.07, 0.69, - -0.53, -46.38, 50.50, 0.00, 0.00, 1.13, 1.04, 0.02, - -18.38, 0.00, 63.80, 0.00, 0.00, 0.41, 0.00, -1.43, - 59.07, 0.00, 0.00, 0.00, 0.00, -1.32, 57.28, 0.00, - 0.00, 0.00, 0.00, -1.28, -48.65, 0.00, -1.15, 0.00, - 0.00, 1.09, 0.00, 0.03, -18.30, 24.60, -17.30, -23.20, - 0.56, 0.41, -0.51, 0.39, -16.91, 26.90, 8.43, 13.30, - 0.60, 0.38, 0.31, -0.19, 1.23, -1.70, -19.13, -25.70, - -0.03, -0.03, -0.58, 0.43, -0.72, 0.90, -17.34, -23.30, - - /* 2516-2643 */ - 0.03, 0.02, -0.52, 0.39, -19.49, -21.30, 0.00, 0.00, - -0.48, 0.44, 0.01, 20.57, -20.10, 0.64, 0.70, -0.45, - -0.46, 0.00, -0.01, 4.89, 5.90, -16.55, 19.90, 0.14, - -0.11, 0.44, 0.37, 18.22, 19.80, 0.00, 0.00, 0.44, - -0.41, -0.01, 4.89, -5.30, -16.51, -18.00, -0.11, -0.11, - -0.41, 0.37, -17.86, 0.00, 17.10, 0.00, 0.00, 0.40, - 0.00, -0.38, 0.32, 0.00, 24.42, 0.00, 0.00, -0.01, - 0.00, -0.55, -23.79, 0.00, 0.00, 0.00, 0.00, 0.53, - 14.72, -16.00, -0.32, 0.00, -0.36, -0.33, -0.01, 0.01, - 3.34, -4.50, 11.86, 15.90, -0.11, -0.07, 0.35, -0.27, - -3.26, 4.40, 11.62, 15.60, 0.09, 0.07, 0.35, -0.26, - -19.53, 0.00, 5.09, 0.00, 0.00, 0.44, 0.00, -0.11, - -13.48, 14.70, 0.00, 0.00, 0.33, 0.30, 0.01, 10.86, - -14.60, 3.18, 4.30, -0.33, -0.24, 0.09, -0.07, -11.30, - -15.10, 0.00, 0.00, -0.34, 0.25, 0.01, 2.03, -2.70, - 10.82, 14.50, -0.07, -0.05, 0.32, -0.24, 17.46, 0.00, - - /* 2644-2771 */ - 0.00, 0.00, 0.00, -0.39, 16.43, 0.00, 0.52, 0.00, - 0.00, -0.37, 0.00, -0.01, 9.35, 0.00, 13.29, 0.00, - 0.00, -0.21, 0.00, -0.30, -10.42, 11.40, 0.00, 0.00, - 0.25, 0.23, 0.01, 0.44, 0.50, -10.38, 11.30, 0.02, - -0.01, 0.25, 0.23, -14.64, 0.00, 0.00, 0.00, 0.00, - 0.33, 0.56, 0.80, -8.67, 11.70, 0.02, -0.01, 0.26, - 0.19, 13.88, 0.00, -2.47, 0.00, 0.00, -0.31, 0.00, - 0.06, -1.99, 2.70, 7.72, 10.30, 0.06, 0.04, 0.23, - -0.17, -0.20, 0.00, 13.05, 0.00, 0.00, 0.00, 0.00, - -0.29, 6.92, -9.30, 3.34, 4.50, -0.21, -0.15, 0.10, - -0.07, -6.60, 0.00, 10.70, 0.00, 0.00, 0.15, 0.00, - -0.24, -8.04, -8.70, 0.00, 0.00, -0.19, 0.18, -10.58, - 0.00, -3.10, 0.00, 0.00, 0.24, 0.00, 0.07, -7.32, - 8.00, -0.12, -0.10, 0.18, 0.16, 1.63, 1.70, 6.96, - -7.60, 0.03, -0.04, -0.17, -0.16, -3.62, 0.00, 9.86, - 0.00, 0.00, 0.08, 0.00, -0.22, 0.20, -0.20, -6.88, - - /* 2772-2899 */ - -7.50, 0.00, 0.00, -0.17, 0.15, -8.99, 0.00, 4.02, - 0.00, 0.00, 0.20, 0.00, -0.09, -1.07, 1.40, -5.69, - -7.70, 0.03, 0.02, -0.17, 0.13, 6.48, -7.20, -0.48, - -0.50, -0.16, -0.14, -0.01, 0.01, 5.57, -7.50, 1.07, - 1.40, -0.17, -0.12, 0.03, -0.02, 8.71, 0.00, 3.54, - 0.00, 0.00, -0.19, 0.00, -0.08, 0.40, 0.00, 9.27, - 0.00, 0.00, -0.01, 0.00, -0.21, -6.13, 6.70, -1.19, - -1.30, 0.15, 0.14, -0.03, 0.03, 5.21, -5.70, -2.51, - -2.60, -0.13, -0.12, -0.06, 0.06, 5.69, -6.20, -0.12, - -0.10, -0.14, -0.13, -0.01, 2.03, -2.70, 4.53, 6.10, - -0.06, -0.05, 0.14, -0.10, 5.01, 5.50, -2.51, 2.70, - 0.12, -0.11, 0.06, 0.06, -1.91, 2.60, -4.38, -5.90, - 0.06, 0.04, -0.13, 0.10, 4.65, -6.30, 0.00, 0.00, - -0.14, -0.10, -5.29, 5.70, 0.00, 0.00, 0.13, 0.12, - -2.23, -4.00, -4.65, 4.20, -0.09, 0.05, 0.10, 0.10, - -4.53, 6.10, 0.00, 0.00, 0.14, 0.10, 2.47, 2.70, - - /* 2900-3027 */ - -4.46, 4.90, 0.06, -0.06, 0.11, 0.10, -5.05, 5.50, - 0.84, 0.90, 0.12, 0.11, 0.02, -0.02, 4.97, -5.40, - -1.71, 0.00, -0.12, -0.11, 0.00, 0.04, -0.99, -1.30, - 4.22, -5.70, -0.03, 0.02, -0.13, -0.09, 0.99, 1.40, - 4.22, -5.60, 0.03, -0.02, -0.13, -0.09, -4.69, -5.20, - 0.00, 0.00, -0.12, 0.10, -3.42, 0.00, 6.09, 0.00, - 0.00, 0.08, 0.00, -0.14, -4.65, -5.10, 0.00, 0.00, - -0.11, 0.10, 0.00, 0.00, -4.53, -5.00, 0.00, 0.00, - -0.11, 0.10, -2.43, -2.70, -3.82, 4.20, -0.06, 0.05, - 0.10, 0.09, 0.00, 0.00, -4.53, 4.90, 0.00, 0.00, - 0.11, 0.10, -4.49, -4.90, 0.00, 0.00, -0.11, 0.10, - 2.67, -2.90, -3.62, -3.90, -0.06, -0.06, -0.09, 0.08, - 3.94, -5.30, 0.00, 0.00, -0.12, -3.38, 3.70, -2.78, - -3.10, 0.08, 0.08, -0.07, 0.06, 3.18, -3.50, -2.82, - -3.10, -0.08, -0.07, -0.07, 0.06, -5.77, 0.00, 1.87, - 0.00, 0.00, 0.13, 0.00, -0.04, 3.54, -4.80, -0.64, - - /* 3028-3155 */ - -0.90, -0.11, 0.00, -0.02, -3.50, -4.70, 0.68, -0.90, - -0.11, 0.00, -0.02, 5.49, 0.00, 0.00, 0.00, 0.00, - -0.12, 1.83, -2.50, 2.63, 3.50, -0.06, 0.00, 0.08, - 3.02, -4.10, 0.68, 0.90, -0.09, 0.00, 0.02, 0.00, - 0.00, 5.21, 0.00, 0.00, 0.00, 0.00, -0.12, -3.54, - 3.80, 2.70, 3.60, -1.35, 1.80, 0.08, 0.00, 0.04, - -2.90, 3.90, 0.68, 0.90, 0.09, 0.00, 0.02, 0.80, - -1.10, -2.78, -3.70, -0.02, 0.00, -0.08, 4.10, 0.00, - -2.39, 0.00, 0.00, -0.09, 0.00, 0.05, -1.59, 2.10, - 2.27, 3.00, 0.05, 0.00, 0.07, -2.63, 3.50, -0.48, - -0.60, -2.94, -3.20, -2.94, 3.20, 2.27, -3.00, -1.11, - -1.50, -0.07, 0.00, -0.03, -0.56, -0.80, -2.35, 3.10, - 0.00, -0.60, -3.42, 1.90, -0.12, -0.10, 2.63, -2.90, - 2.51, 2.80, -0.64, 0.70, -0.48, -0.60, 2.19, -2.90, - 0.24, -0.30, 2.15, 2.90, 2.15, -2.90, 0.52, 0.70, - 2.07, -2.80, -3.10, 0.00, 1.79, 0.00, 0.00, 0.07, - - /* 3156-3283 */ - 0.00, -0.04, 0.88, 0.00, -3.46, 2.11, 2.80, -0.36, - 0.50, 3.54, -0.20, -3.50, -1.39, 1.50, -1.91, -2.10, - -1.47, 2.00, 1.39, 1.90, 2.07, -2.30, 0.91, 1.00, - 1.99, -2.70, 3.30, 0.00, 0.60, -0.44, -0.70, -1.95, - 2.60, 2.15, -2.40, -0.60, -0.70, 3.30, 0.84, 0.00, - -3.10, -3.10, 0.00, -0.72, -0.32, 0.40, -1.87, -2.50, - 1.87, -2.50, 0.32, 0.40, -0.24, 0.30, -1.87, -2.50, - -0.24, -0.30, 1.87, -2.50, -2.70, 0.00, 1.55, 2.03, - 2.20, -2.98, -1.99, -2.20, 0.12, -0.10, -0.40, 0.50, - 1.59, 2.10, 0.00, 0.00, -1.79, 2.00, -1.03, 1.40, - -1.15, -1.60, 0.32, 0.50, 1.39, -1.90, 2.35, -1.27, - 1.70, 0.60, 0.80, -0.32, -0.40, 1.35, -1.80, 0.44, - 0.00, 2.23, -0.84, 0.90, -1.27, -1.40, -1.47, 1.60, - -0.28, -0.30, -0.28, 0.40, -1.27, -1.70, 0.28, -0.40, - -1.43, -1.50, 0.00, 0.00, -1.27, -1.70, 2.11, -0.32, - -0.40, -1.23, 1.60, 1.19, -1.30, -0.72, -0.80, 0.72, - - /* 3284-3411 */ - -0.80, -1.15, -1.30, -1.35, -1.50, -1.19, -1.60, -0.12, - 0.20, 1.79, 0.00, -0.88, -0.28, 0.40, 1.11, 1.50, - -1.83, 0.00, 0.56, -0.12, 0.10, -1.27, -1.40, 0.00, - 0.00, 1.15, 1.50, -0.12, 0.20, 1.11, 1.50, 0.36, - -0.50, -1.07, -1.40, -1.11, 1.50, 1.67, 0.00, 0.80, - -1.11, 0.00, 1.43, 1.23, -1.30, -0.24, -1.19, -1.30, - -0.24, 0.20, -0.44, -0.90, -0.95, 1.10, 1.07, -1.40, - 1.15, -1.30, 1.03, -1.10, -0.56, -0.60, -0.68, 0.90, - -0.76, -1.00, -0.24, -0.30, 0.95, -1.30, 0.56, 0.70, - 0.84, -1.10, -0.56, 0.00, -1.55, 0.91, -1.30, 0.28, - 0.30, 0.16, -0.20, 0.95, 1.30, 0.40, -0.50, -0.88, - -1.20, 0.95, -1.10, -0.48, -0.50, 0.00, 0.00, -1.07, - 1.20, 0.44, -0.50, 0.95, 1.10, 0.00, 0.00, 0.92, - -1.30, 0.95, 1.00, -0.52, 0.60, 1.59, 0.24, -0.40, - 0.91, 1.20, 0.84, -1.10, -0.44, -0.60, 0.84, 1.10, - -0.44, 0.60, -0.44, 0.60, -0.84, -1.10, -0.80, 0.00, - - /* 3412-3539 */ - 1.35, 0.76, 0.20, -0.91, -1.00, 0.20, -0.30, -0.91, - -1.20, -0.95, 1.00, -0.48, -0.50, 0.88, 1.00, 0.48, - -0.50, -0.95, -1.10, 0.20, -0.20, -0.99, 1.10, -0.84, - 1.10, -0.24, -0.30, 0.20, -0.30, 0.84, 1.10, -1.39, - 0.00, -0.28, -0.16, 0.20, 0.84, 1.10, 0.00, 0.00, - 1.39, 0.00, 0.00, -0.95, 1.00, 1.35, -0.99, 0.00, - 0.88, -0.52, 0.00, -1.19, 0.20, 0.20, 0.76, -1.00, - 0.00, 0.00, 0.76, 1.00, 0.00, 0.00, 0.76, 1.00, - -0.76, 1.00, 0.00, 0.00, 1.23, 0.76, 0.80, -0.32, - 0.40, -0.72, 0.80, -0.40, -0.40, 0.00, 0.00, -0.80, - -0.90, -0.68, 0.90, -0.16, -0.20, -0.16, -0.20, 0.68, - -0.90, -0.36, 0.50, -0.56, -0.80, 0.72, -0.90, 0.44, - -0.60, -0.48, -0.70, -0.16, 0.00, -1.11, 0.32, 0.00, - -1.07, 0.60, -0.80, -0.28, -0.40, -0.64, 0.00, 0.91, - 1.11, 0.64, -0.90, 0.76, -0.80, 0.00, 0.00, -0.76, - -0.80, 1.03, 0.00, -0.36, -0.64, -0.70, 0.36, -0.40, - - /* 3540-3667 */ - 1.07, 0.36, -0.50, -0.52, -0.70, 0.60, 0.00, 0.88, - 0.95, 0.00, 0.48, 0.16, -0.20, 0.60, 0.80, 0.16, - -0.20, -0.60, -0.80, 0.00, -1.00, 0.12, 0.20, 0.16, - -0.20, 0.68, 0.70, 0.59, -0.80, -0.99, -0.56, -0.60, - 0.36, -0.40, -0.68, -0.70, -0.68, -0.70, -0.36, -0.50, - -0.44, 0.60, 0.64, 0.70, -0.12, 0.10, -0.52, 0.60, - 0.36, 0.40, 0.00, 0.00, 0.95, -0.84, 0.00, 0.44, - 0.56, 0.60, 0.32, -0.30, 0.00, 0.00, 0.60, 0.70, - 0.00, 0.00, 0.60, 0.70, -0.12, -0.20, 0.52, -0.70, - 0.00, 0.00, 0.56, 0.70, -0.12, 0.10, -0.52, -0.70, - 0.00, 0.00, 0.88, -0.76, 0.00, -0.44, 0.00, 0.00, - -0.52, -0.70, 0.52, -0.70, 0.36, -0.40, -0.44, -0.50, - 0.00, 0.00, 0.60, 0.60, 0.84, 0.00, 0.12, -0.24, - 0.00, 0.80, -0.56, 0.60, -0.32, -0.30, 0.48, -0.50, - 0.28, -0.30, -0.48, -0.50, 0.12, 0.20, 0.48, -0.60, - 0.48, 0.60, -0.12, 0.20, 0.24, 0.00, 0.76, -0.52, - - /* 3668-3795 */ - -0.60, -0.52, 0.60, 0.48, -0.50, -0.24, -0.30, 0.12, - -0.10, 0.48, 0.60, 0.52, -0.20, 0.36, 0.40, -0.44, - 0.50, -0.24, -0.30, -0.48, -0.60, -0.44, -0.60, -0.12, - 0.10, 0.76, 0.76, 0.20, -0.20, 0.48, 0.50, 0.40, - -0.50, -0.24, -0.30, 0.44, -0.60, 0.44, -0.60, 0.36, - 0.00, -0.64, 0.72, 0.00, -0.12, 0.00, -0.10, -0.40, - -0.60, -0.20, -0.20, -0.44, 0.50, -0.44, 0.50, 0.20, - 0.20, -0.44, -0.50, 0.20, -0.20, -0.20, 0.20, -0.44, - -0.50, 0.64, 0.00, 0.32, -0.36, 0.50, -0.20, -0.30, - 0.12, -0.10, 0.48, 0.50, -0.12, 0.30, -0.36, -0.50, - 0.00, 0.00, 0.48, 0.50, -0.48, 0.50, 0.68, 0.00, - -0.12, 0.56, -0.40, 0.44, -0.50, -0.12, -0.10, 0.24, - 0.30, -0.40, 0.40, 0.64, 0.00, -0.24, 0.64, 0.00, - -0.20, 0.00, 0.00, 0.44, -0.50, 0.44, 0.50, -0.12, - 0.20, -0.36, -0.50, 0.12, 0.00, 0.64, -0.40, 0.50, - 0.00, 0.10, 0.00, 0.00, -0.40, 0.50, 0.00, 0.00, - - /* 3796-3923 */ - -0.40, -0.50, 0.56, 0.00, 0.28, 0.00, 0.10, 0.36, - 0.50, 0.00, -0.10, 0.36, -0.50, 0.36, 0.50, 0.00, - -0.10, 0.24, -0.20, -0.36, -0.40, 0.16, 0.20, 0.40, - -0.40, 0.00, 0.00, -0.36, -0.50, -0.36, -0.50, -0.32, - -0.50, -0.12, 0.10, 0.20, 0.20, -0.36, 0.40, -0.60, - 0.60, 0.28, 0.00, 0.52, 0.12, -0.10, 0.40, 0.40, - 0.00, -0.50, 0.20, -0.20, -0.32, 0.40, 0.16, 0.20, - -0.16, 0.20, 0.32, 0.40, 0.56, 0.00, -0.12, 0.32, - -0.40, -0.16, -0.20, 0.00, 0.00, 0.40, 0.40, -0.40, - -0.40, -0.40, 0.40, -0.36, 0.40, 0.12, 0.10, 0.00, - 0.10, 0.36, 0.40, 0.00, -0.10, 0.36, 0.40, -0.36, - 0.40, 0.00, 0.10, 0.32, 0.00, 0.44, 0.12, 0.20, - 0.28, -0.40, 0.00, 0.00, 0.36, 0.40, 0.32, -0.40, - -0.16, 0.12, 0.10, 0.32, -0.40, 0.20, 0.30, -0.24, - 0.30, 0.00, 0.10, 0.32, 0.40, 0.00, -0.10, -0.32, - -0.40, -0.32, 0.40, 0.00, 0.10, -0.52, -0.52, 0.52, - - /* 3924-4051 */ - 0.32, -0.40, 0.00, 0.00, 0.32, 0.40, 0.32, -0.40, - 0.00, 0.00, -0.32, -0.40, -0.32, 0.40, 0.32, 0.40, - 0.00, 0.00, 0.32, 0.40, 0.00, 0.00, -0.32, -0.40, - 0.00, 0.00, 0.32, 0.40, 0.16, 0.20, 0.32, -0.30, - -0.16, 0.00, -0.48, -0.20, 0.20, -0.28, -0.30, 0.28, - -0.40, 0.00, 0.00, 0.28, -0.40, 0.00, 0.00, 0.28, - -0.40, 0.00, 0.00, -0.28, -0.40, 0.28, 0.40, -0.28, - -0.40, -0.48, -0.20, 0.20, 0.24, 0.30, 0.44, 0.00, - 0.16, 0.24, 0.30, 0.16, -0.20, 0.24, 0.30, -0.12, - 0.20, 0.20, 0.30, -0.16, 0.20, 0.00, 0.00, 0.44, - -0.32, 0.30, 0.24, 0.00, -0.36, 0.36, 0.00, 0.24, - 0.12, -0.20, 0.20, 0.30, -0.12, 0.00, -0.28, 0.30, - -0.24, 0.30, 0.12, 0.10, -0.28, -0.30, -0.28, 0.30, - 0.00, 0.00, -0.28, -0.30, 0.00, 0.00, -0.28, -0.30, - 0.00, 0.00, 0.28, 0.30, 0.00, 0.00, -0.28, -0.30, - -0.28, 0.30, 0.00, 0.00, -0.28, -0.30, 0.00, 0.00, - - /* 4052-4179 */ - 0.28, 0.30, 0.00, 0.00, -0.28, 0.30, 0.28, -0.30, - -0.28, 0.30, 0.40, 0.40, -0.24, 0.30, 0.00, -0.10, - 0.16, 0.00, 0.36, -0.20, 0.30, -0.12, -0.10, -0.24, - -0.30, 0.00, 0.00, -0.24, 0.30, -0.24, 0.30, 0.00, - 0.00, -0.24, 0.30, -0.24, 0.30, 0.24, -0.30, 0.00, - 0.00, 0.24, -0.30, 0.00, 0.00, 0.24, 0.30, 0.24, - -0.30, 0.24, 0.30, -0.24, 0.30, -0.24, 0.30, -0.20, - 0.20, -0.16, -0.20, 0.00, 0.00, -0.32, 0.20, 0.00, - 0.10, 0.20, -0.30, 0.20, -0.20, 0.12, 0.20, -0.16, - 0.20, 0.16, 0.20, 0.20, 0.30, 0.20, 0.30, 0.00, - 0.00, -0.20, 0.30, 0.00, 0.00, 0.20, 0.30, -0.20, - -0.30, -0.20, -0.30, 0.20, -0.30, 0.00, 0.00, 0.20, - 0.30, 0.00, 0.00, 0.20, 0.30, 0.00, 0.00, 0.20, - 0.30, 0.00, 0.00, 0.20, 0.30, 0.00, 0.00, 0.20, - -0.30, 0.00, 0.00, -0.20, -0.30, 0.00, 0.00, -0.20, - 0.30, 0.00, 0.00, -0.20, 0.30, 0.00, 0.00, 0.36, - - /* 4180-4307 */ - 0.00, 0.00, 0.36, 0.12, 0.10, -0.24, 0.20, 0.12, - -0.20, -0.16, -0.20, -0.13, 0.10, 0.22, 0.21, 0.20, - 0.00, -0.28, 0.32, 0.00, -0.12, -0.20, -0.20, 0.12, - -0.10, 0.12, 0.10, -0.20, 0.20, 0.00, 0.00, -0.32, - 0.32, 0.00, 0.00, 0.32, 0.32, 0.00, 0.00, -0.24, - -0.20, 0.24, 0.20, 0.20, 0.00, -0.24, 0.00, 0.00, - -0.24, -0.20, 0.00, 0.00, 0.24, 0.20, -0.24, -0.20, - 0.00, 0.00, -0.24, 0.20, 0.16, -0.20, 0.12, 0.10, - 0.20, 0.20, 0.00, -0.10, -0.12, 0.10, -0.16, -0.20, - -0.12, -0.10, -0.16, 0.20, 0.20, 0.20, 0.00, 0.00, - -0.20, 0.20, -0.20, 0.20, -0.20, 0.20, -0.20, 0.20, - 0.20, -0.20, -0.20, -0.20, 0.00, 0.00, -0.20, 0.20, - 0.20, 0.00, -0.20, 0.00, 0.00, -0.20, 0.20, -0.20, - 0.20, -0.20, -0.20, -0.20, -0.20, 0.00, 0.00, 0.20, - 0.20, 0.20, 0.20, 0.12, -0.20, -0.12, -0.10, 0.28, - -0.28, 0.16, -0.20, 0.00, -0.10, 0.00, 0.10, -0.16, - - /* 4308-4435 */ - 0.20, 0.00, -0.10, -0.16, -0.20, 0.00, -0.10, 0.16, - -0.20, 0.16, -0.20, 0.00, 0.00, 0.16, 0.20, -0.16, - 0.20, 0.00, 0.00, 0.16, 0.20, 0.16, -0.20, 0.16, - -0.20, -0.16, 0.20, 0.16, -0.20, 0.00, 0.00, 0.16, - 0.20, 0.00, 0.00, 0.16, 0.20, 0.00, 0.00, -0.16, - -0.20, 0.16, -0.20, -0.16, -0.20, 0.00, 0.00, -0.16, - -0.20, 0.00, 0.00, -0.16, 0.20, 0.00, 0.00, 0.16, - -0.20, 0.16, 0.20, 0.16, 0.20, 0.00, 0.00, -0.16, - -0.20, 0.00, 0.00, -0.16, -0.20, 0.00, 0.00, 0.16, - 0.20, 0.16, 0.20, 0.00, 0.00, 0.16, 0.20, 0.16, - -0.20, 0.16, 0.20, 0.00, 0.00, -0.16, 0.20, 0.00, - 0.10, 0.12, -0.20, 0.12, -0.20, 0.00, -0.10, 0.00, - -0.10, 0.12, 0.20, 0.00, -0.10, -0.12, 0.20, -0.15, - 0.20, -0.24, 0.24, 0.00, 0.00, 0.24, 0.24, 0.12, - -0.20, -0.12, -0.20, 0.00, 0.00, 0.12, 0.20, 0.12, - -0.20, 0.12, 0.20, 0.12, 0.20, 0.12, 0.20, 0.12, - - /* 4436-4563 */ - -0.20, -0.12, 0.20, 0.00, 0.00, 0.12, 0.20, 0.12, - 0.00, -0.20, 0.00, 0.00, -0.12, -0.20, 0.12, -0.20, - 0.00, 0.00, 0.12, 0.20, -0.12, 0.20, -0.12, 0.20, - 0.12, -0.20, 0.00, 0.00, 0.12, 0.20, 0.20, 0.00, - 0.12, 0.00, 0.00, -0.12, 0.20, 0.00, 0.00, -0.12, - -0.20, 0.00, 0.00, -0.12, -0.20, -0.12, -0.20, 0.00, - 0.00, 0.12, -0.20, 0.12, -0.20, 0.12, 0.20, -0.12, - -0.20, 0.00, 0.00, 0.12, -0.20, 0.12, -0.20, 0.12, - 0.20, 0.12, 0.00, 0.20, -0.12, -0.20, 0.00, 0.00, - 0.12, 0.20, -0.16, 0.00, 0.16, -0.20, 0.20, 0.00, - 0.00, -0.20, 0.00, 0.00, -0.20, 0.20, 0.00, 0.00, - 0.20, 0.20, -0.20, 0.00, 0.00, -0.20, 0.12, 0.00, - -0.16, 0.20, 0.00, 0.00, 0.20, 0.12, -0.10, 0.00, - 0.10, 0.16, -0.16, -0.16, -0.16, -0.16, -0.16, 0.00, - 0.00, -0.16, 0.00, 0.00, -0.16, -0.16, -0.16, 0.00, - 0.00, -0.16, 0.00, 0.00, 0.16, 0.00, 0.00, 0.16, - - /* 4564-4691 */ - 0.00, 0.00, 0.16, 0.16, 0.00, 0.00, -0.16, 0.00, - 0.00, -0.16, -0.16, 0.00, 0.00, 0.16, 0.00, 0.00, - -0.16, -0.16, 0.00, 0.00, -0.16, -0.16, 0.12, 0.10, - 0.12, -0.10, 0.12, 0.10, 0.00, 0.00, 0.12, 0.10, - -0.12, 0.10, 0.00, 0.00, 0.12, 0.10, 0.12, -0.10, - 0.00, 0.00, -0.12, -0.10, 0.00, 0.00, 0.12, 0.10, - 0.12, 0.00, 0.00, 0.12, 0.00, 0.00, -0.12, 0.00, - 0.00, 0.12, 0.12, 0.12, 0.12, 0.12, 0.00, 0.00, - 0.12, 0.00, 0.00, 0.12, 0.12, 0.00, 0.00, 0.12, - 0.00, 0.00, 0.12, -0.12, -0.12, 0.12, 0.12, -0.12, - -0.12, 0.00, 0.00, 0.12, -0.12, 0.12, 0.12, -0.12, - -0.12, 0.00, 0.00, -0.12, -0.12, 0.00, 0.00, -0.12, - 0.12, 0.00, 0.00, 0.12, 0.00, 0.00, 0.12, 0.00, - 0.00, 0.12, -0.12, 0.00, 0.00, -0.12, 0.12, -0.12, - -0.12, 0.12, 0.00, 0.00, 0.12, 0.12, 0.12, -0.12, - 0.00, 0.00, -0.12, -0.12, -0.12, 0.00, 0.00, -0.12, - - /* 4692-NA */ - -0.12, 0.00, 0.00, 0.12, 0.12, 0.00, 0.00, -0.12, - -0.12, -0.12, -0.12, 0.12, 0.00, 0.00, 0.12, -0.12, - 0.00, 0.00, -0.12, -0.12, 0.00, 0.00, 0.12, -0.12, - -0.12, -0.12, -0.12, 0.12, 0.12, -0.12, -0.12, 0.00, - 0.00, -0.12, 0.00, 0.00, -0.12, 0.12, 0.00, 0.00, - 0.12, 0.00, 0.00, -0.12, -0.12, 0.00, 0.00, -0.12, - -0.12, 0.12, 0.00, 0.00, 0.12, 0.12, 0.00, 0.00, - 0.12, 0.00, 0.00, 0.12, 0.12, 0.08, 0.00, 0.04 - }; - -/* Number of amplitude coefficients */ - static const int NA = (int) (sizeof a / sizeof (double)); - -/* Amplitude usage: X or Y, sin or cos, power of T. */ - static const int jaxy[] = {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1}; - static const int jasc[] = {0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0}; - static const int japt[] = {0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4}; - -/* Miscellaneous */ - double t, w, pt[MAXPT+1], fa[14], xypr[2], xypl[2], xyls[2], arg, - sc[2]; - int jpt, i, j, jxy, ialast, ifreq, m, ia, jsc; - -/*--------------------------------------------------------------------*/ - -/* Interval between fundamental date J2000.0 and given date (JC). */ - t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; - -/* Powers of T. */ - w = 1.0; - for (jpt = 0; jpt <= MAXPT; jpt++) { - pt[jpt] = w; - w *= t; - } - -/* Initialize totals in X and Y: polynomial, luni-solar, planetary. */ - for (jxy = 0; jxy < 2; jxy++) { - xypr[jxy] = 0.0; - xyls[jxy] = 0.0; - xypl[jxy] = 0.0; - } - -/* --------------------------------- */ -/* Fundamental arguments (IERS 2003) */ -/* --------------------------------- */ - -/* Mean anomaly of the Moon. */ - fa[0] = eraFal03(t); - -/* Mean anomaly of the Sun. */ - fa[1] = eraFalp03(t); - -/* Mean argument of the latitude of the Moon. */ - fa[2] = eraFaf03(t); - -/* Mean elongation of the Moon from the Sun. */ - fa[3] = eraFad03(t); - -/* Mean longitude of the ascending node of the Moon. */ - fa[4] = eraFaom03(t); - -/* Planetary longitudes, Mercury through Neptune. */ - fa[5] = eraFame03(t); - fa[6] = eraFave03(t); - fa[7] = eraFae03(t); - fa[8] = eraFama03(t); - fa[9] = eraFaju03(t); - fa[10] = eraFasa03(t); - fa[11] = eraFaur03(t); - fa[12] = eraFane03(t); - -/* General accumulated precession in longitude. */ - fa[13] = eraFapa03(t); - -/* -------------------------------------- */ -/* Polynomial part of precession-nutation */ -/* -------------------------------------- */ - - for (jxy = 0; jxy < 2; jxy++) { - for (j = MAXPT; j >= 0; j--) { - xypr[jxy] += xyp[jxy][j] * pt[j]; - } - } - -/* ---------------------------------- */ -/* Nutation periodic terms, planetary */ -/* ---------------------------------- */ - -/* Work backwards through the coefficients per frequency list. */ - ialast = NA; - for (ifreq = NFPL-1; ifreq >= 0; ifreq--) { - - /* Obtain the argument functions. */ - arg = 0.0; - for (i = 0; i < 14; i++) { - m = mfapl[ifreq][i]; - if (m != 0) arg += (double)m * fa[i]; - } - sc[0] = sin(arg); - sc[1] = cos(arg); - - /* Work backwards through the amplitudes at this frequency. */ - ia = nc[ifreq+NFLS]; - for (i = ialast; i >= ia; i--) { - - /* Coefficient number (0 = 1st). */ - j = i-ia; - - /* X or Y. */ - jxy = jaxy[j]; - - /* Sin or cos. */ - jsc = jasc[j]; - - /* Power of T. */ - jpt = japt[j]; - - /* Accumulate the component. */ - xypl[jxy] += a[i-1] * sc[jsc] * pt[jpt]; - } - ialast = ia-1; - } - -/* ----------------------------------- */ -/* Nutation periodic terms, luni-solar */ -/* ----------------------------------- */ - -/* Continue working backwards through the number of coefficients list. */ - for (ifreq = NFLS-1; ifreq >= 0; ifreq--) { - - /* Obtain the argument functions. */ - arg = 0.0; - for (i = 0; i < 5; i++) { - m = mfals[ifreq][i]; - if (m != 0) arg += (double)m * fa[i]; - } - sc[0] = sin(arg); - sc[1] = cos(arg); - - /* Work backwards through the amplitudes at this frequency. */ - ia = nc[ifreq]; - for (i = ialast; i >= ia; i--) { - - /* Coefficient number (0 = 1st). */ - j = i-ia; - - /* X or Y. */ - jxy = jaxy[j]; - - /* Sin or cos. */ - jsc = jasc[j]; - - /* Power of T. */ - jpt = japt[j]; - - /* Accumulate the component. */ - xyls[jxy] += a[i-1] * sc[jsc] * pt[jpt]; - } - ialast = ia-1; - } - -/* ------------------------------------ */ -/* Results: CIP unit vector components */ -/* ------------------------------------ */ - - *x = ERFA_DAS2R * (xypr[0] + (xyls[0] + xypl[0]) / 1e6); - *y = ERFA_DAS2R * (xypr[1] + (xyls[1] + xypl[1]) / 1e6); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/xys00a.c b/ast/erfa/xys00a.c deleted file mode 100644 index 41a0723..0000000 --- a/ast/erfa/xys00a.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "erfa.h" - -void eraXys00a(double date1, double date2, - double *x, double *y, double *s) -/* -** - - - - - - - - - - -** e r a X y s 0 0 a -** - - - - - - - - - - -** -** For a given TT date, compute the X,Y coordinates of the Celestial -** Intermediate Pole and the CIO locator s, using the IAU 2000A -** precession-nutation model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** x,y double Celestial Intermediate Pole (Note 2) -** s double the CIO locator s (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The Celestial Intermediate Pole coordinates are the x,y -** components of the unit vector in the Geocentric Celestial -** Reference System. -** -** 3) The CIO locator s (in radians) positions the Celestial -** Intermediate Origin on the equator of the CIP. -** -** 4) A faster, but slightly less accurate result (about 1 mas for -** X,Y), can be obtained by using instead the eraXys00b function. -** -** Called: -** eraPnm00a classical NPB matrix, IAU 2000A -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraS00 the CIO locator s, given X,Y, IAU 2000A -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rbpn[3][3]; - - -/* Form the bias-precession-nutation matrix, IAU 2000A. */ - eraPnm00a(date1, date2, rbpn); - -/* Extract X,Y. */ - eraBpn2xy(rbpn, x, y); - -/* Obtain s. */ - *s = eraS00(date1, date2, *x, *y); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/xys00b.c b/ast/erfa/xys00b.c deleted file mode 100644 index d2ebda7..0000000 --- a/ast/erfa/xys00b.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "erfa.h" - -void eraXys00b(double date1, double date2, - double *x, double *y, double *s) -/* -** - - - - - - - - - - -** e r a X y s 0 0 b -** - - - - - - - - - - -** -** For a given TT date, compute the X,Y coordinates of the Celestial -** Intermediate Pole and the CIO locator s, using the IAU 2000B -** precession-nutation model. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** x,y double Celestial Intermediate Pole (Note 2) -** s double the CIO locator s (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The Celestial Intermediate Pole coordinates are the x,y -** components of the unit vector in the Geocentric Celestial -** Reference System. -** -** 3) The CIO locator s (in radians) positions the Celestial -** Intermediate Origin on the equator of the CIP. -** -** 4) The present function is faster, but slightly less accurate (about -** 1 mas in X,Y), than the eraXys00a function. -** -** Called: -** eraPnm00b classical NPB matrix, IAU 2000B -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraS00 the CIO locator s, given X,Y, IAU 2000A -** -** Reference: -** -** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), -** IERS Technical Note No. 32, BKG (2004) -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rbpn[3][3]; - - -/* Form the bias-precession-nutation matrix, IAU 2000A. */ - eraPnm00b(date1, date2, rbpn); - -/* Extract X,Y. */ - eraBpn2xy(rbpn, x, y); - -/* Obtain s. */ - *s = eraS00(date1, date2, *x, *y); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/xys06a.c b/ast/erfa/xys06a.c deleted file mode 100644 index e116e15..0000000 --- a/ast/erfa/xys06a.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "erfa.h" - -void eraXys06a(double date1, double date2, - double *x, double *y, double *s) -/* -** - - - - - - - - - - -** e r a X y s 0 6 a -** - - - - - - - - - - -** -** For a given TT date, compute the X,Y coordinates of the Celestial -** Intermediate Pole and the CIO locator s, using the IAU 2006 -** precession and IAU 2000A nutation models. -** -** Given: -** date1,date2 double TT as a 2-part Julian Date (Note 1) -** -** Returned: -** x,y double Celestial Intermediate Pole (Note 2) -** s double the CIO locator s (Note 2) -** -** Notes: -** -** 1) The TT date date1+date2 is a Julian Date, apportioned in any -** convenient way between the two arguments. For example, -** JD(TT)=2450123.7 could be expressed in any of these ways, -** among others: -** -** date1 date2 -** -** 2450123.7 0.0 (JD method) -** 2451545.0 -1421.3 (J2000 method) -** 2400000.5 50123.2 (MJD method) -** 2450123.5 0.2 (date & time method) -** -** The JD method is the most natural and convenient to use in -** cases where the loss of several decimal digits of resolution -** is acceptable. The J2000 method is best matched to the way -** the argument is handled internally and will deliver the -** optimum resolution. The MJD method and the date & time methods -** are both good compromises between resolution and convenience. -** -** 2) The Celestial Intermediate Pole coordinates are the x,y components -** of the unit vector in the Geocentric Celestial Reference System. -** -** 3) The CIO locator s (in radians) positions the Celestial -** Intermediate Origin on the equator of the CIP. -** -** 4) Series-based solutions for generating X and Y are also available: -** see Capitaine & Wallace (2006) and eraXy06. -** -** Called: -** eraPnm06a classical NPB matrix, IAU 2006/2000A -** eraBpn2xy extract CIP X,Y coordinates from NPB matrix -** eraS06 the CIO locator s, given X,Y, IAU 2006 -** -** References: -** -** Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855 -** -** Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981 -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - double rbpn[3][3]; - - -/* Form the bias-precession-nutation matrix, IAU 2006/2000A. */ - eraPnm06a(date1, date2, rbpn); - -/* Extract X,Y. */ - eraBpn2xy(rbpn, x, y); - -/* Obtain s. */ - *s = eraS06(date1, date2, *x, *y); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/zp.c b/ast/erfa/zp.c deleted file mode 100644 index 77a8e59..0000000 --- a/ast/erfa/zp.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "erfa.h" - -void eraZp(double p[3]) -/* -** - - - - - - -** e r a Z p -** - - - - - - -** -** Zero a p-vector. -** -** Returned: -** p double[3] p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - p[0] = 0.0; - p[1] = 0.0; - p[2] = 0.0; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/zpv.c b/ast/erfa/zpv.c deleted file mode 100644 index ca176be..0000000 --- a/ast/erfa/zpv.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "erfa.h" - -void eraZpv(double pv[2][3]) -/* -** - - - - - - - -** e r a Z p v -** - - - - - - - -** -** Zero a pv-vector. -** -** Returned: -** pv double[2][3] pv-vector -** -** Called: -** eraZp zero p-vector -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - eraZp(pv[0]); - eraZp(pv[1]); - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa/zr.c b/ast/erfa/zr.c deleted file mode 100644 index 3a07ff8..0000000 --- a/ast/erfa/zr.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "erfa.h" - -void eraZr(double r[3][3]) -/* -** - - - - - - -** e r a Z r -** - - - - - - -** -** Initialize an r-matrix to the null matrix. -** -** Returned: -** r double[3][3] r-matrix -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** Derived, with permission, from the SOFA library. See notes at end of file. -*/ -{ - r[0][0] = 0.0; - r[0][1] = 0.0; - r[0][2] = 0.0; - r[1][0] = 0.0; - r[1][1] = 0.0; - r[1][2] = 0.0; - r[2][0] = 0.0; - r[2][1] = 0.0; - r[2][2] = 0.0; - - return; - -} -/*---------------------------------------------------------------------- -** -** -** Copyright (C) 2013-2016, NumFOCUS Foundation. -** All rights reserved. -** -** This library is derived, with permission, from the International -** Astronomical Union's "Standards of Fundamental Astronomy" library, -** available from http://www.iausofa.org. -** -** The ERFA version is intended to retain identical functionality to -** the SOFA library, but made distinct through different function and -** file names, as set out in the SOFA license conditions. The SOFA -** original has a role as a reference standard for the IAU and IERS, -** and consequently redistribution is permitted only in its unaltered -** state. The ERFA version is not subject to this restriction and -** therefore can be included in distributions which do not support the -** concept of "read only" software. -** -** Although the intent is to replicate the SOFA API (other than -** replacement of prefix names) and results (with the exception of -** bugs; any that are discovered will be fixed), SOFA is not -** responsible for any errors found in this version of the library. -** -** If you wish to acknowledge the SOFA heritage, please acknowledge -** that you are using a library derived from SOFA, rather than SOFA -** itself. -** -** -** TERMS AND CONDITIONS -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1 Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** -** 2 Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** -** 3 Neither the name of the Standards Of Fundamental Astronomy Board, -** the International Astronomical Union nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -** POSSIBILITY OF SUCH DAMAGE. -** -*/ diff --git a/ast/erfa2ast.h b/ast/erfa2ast.h deleted file mode 100644 index b19e0fc..0000000 --- a/ast/erfa2ast.h +++ /dev/null @@ -1,248 +0,0 @@ -#if !defined( ERFA2AST_INCLUDED ) /* Include this file only once */ -#define ERFA2AST_INCLUDED -/* -* Name: -* erfa2ast.h - -* Type: -* C include file. - -* Purpose: -* Defines new names for symbols exported by the ERFA library. - -* Invocation: -* #include "erfa2ast.h" - -* Description: -* This include file defines a new name for each public function -* defined by the ERFA library. The names defined by ERFA itself are -* of the form "eraXxx" (e.g. eraPmp) - this include file defines -* a macro that translates each such name to the form "astEraXxx" -* (e.g. astEraPmp). This is done so that the names do not clash -* with any external ERFA library with which the application is linked. -* -* It should be included at the start of any AST source file that refers -* to ERFA functions using the standard names (e.g. eraPmp). - -* Copyright: -* Copyright (C) 2012 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 16-FEB-2012 (DSB): -* Original version. -*/ - -/* Rename all ERFA functions called directlty from PAL. */ -#define eraAf2a astEraAf2a -#define eraAnp astEraAnp -#define eraAnpm astEraAnpm -#define eraC2s astEraC2s -#define eraCal2jd astEraCal2jd -#define eraD2tf astEraD2tf -#define eraDat astEraDat -#define eraEe06a astEraEe06a -#define eraEpb astEraEpb -#define eraEpb2jd astEraEpb2jd -#define eraEpj astEraEpj -#define eraEpj2jd astEraEpj2jd -#define eraEpv00 astEraEpv00 -#define eraFk5hz astEraFk5hz -#define eraGd2gc astEraGd2gc -#define eraGmst06 astEraGmst06 -#define eraHfk5z astEraHfk5z -#define eraIr astEraIr -#define eraJd2cal astEraJd2cal -#define eraObl06 astEraObl06 -#define eraP06e astEraP06e -#define eraPap astEraPap -#define eraPas astEraPas -#define eraPdp astEraPdp -#define eraPmat06 astEraPmat06 -#define eraPn astEraPn -#define eraPnm06a astEraPnm06a -#define eraPxp astEraPxp -#define eraRm2v astEraRm2v -#define eraRv2m astEraRv2m -#define eraRx astEraRx -#define eraRxp astEraRxp -#define eraRxpv astEraRxpv -#define eraRxr astEraRxr -#define eraRy astEraRy -#define eraRz astEraRz -#define eraS2c astEraS2c -#define eraSepp astEraSepp -#define eraSeps astEraSeps -#define eraTf2a astEraTf2a -#define eraTf2d astEraTf2d -#define eraTr astEraTr -#define eraTrxp astEraTrxp - - -/* Rename all ERFA functions called internally within the above ERFA - functions. */ -#define eraA2af astEraA2af -#define eraA2tf astEraA2tf -#define eraBi00 astEraBi00 -#define eraBp00 astEraBp00 -#define eraBp06 astEraBp06 -#define eraBpn2xy astEraBpn2xy -#define eraC2i00a astEraC2i00a -#define eraC2i00b astEraC2i00b -#define eraC2i06a astEraC2i06a -#define eraC2ibpn astEraC2ibpn -#define eraC2ixy astEraC2ixy -#define eraC2ixys astEraC2ixys -#define eraC2t00a astEraC2t00a -#define eraC2t00b astEraC2t00b -#define eraC2t06a astEraC2t06a -#define eraC2tcio astEraC2tcio -#define eraC2teqx astEraC2teqx -#define eraC2tpe astEraC2tpe -#define eraC2txy astEraC2txy -#define eraCp astEraCp -#define eraCpv astEraCpv -#define eraCr astEraCr -#define eraD2dtf astEraD2dtf -#define eraDtdb astEraDtdb -#define eraDtf2d astEraDtf2d -#define eraEe00 astEraEe00 -#define eraEe00a astEraEe00a -#define eraEe00b astEraEe00b -#define eraEect00 astEraEect00 -#define eraEform astEraEform -#define eraEo06a astEraEo06a -#define eraEors astEraEors -#define eraEqeq94 astEraEqeq94 -#define eraEra00 astEraEra00 -#define eraFad03 astEraFad03 -#define eraFae03 astEraFae03 -#define eraFaf03 astEraFaf03 -#define eraFaju03 astEraFaju03 -#define eraFal03 astEraFal03 -#define eraFalp03 astEraFalp03 -#define eraFama03 astEraFama03 -#define eraFame03 astEraFame03 -#define eraFane03 astEraFane03 -#define eraFaom03 astEraFaom03 -#define eraFapa03 astEraFapa03 -#define eraFasa03 astEraFasa03 -#define eraFaur03 astEraFaur03 -#define eraFave03 astEraFave03 -#define eraFk52h astEraFk52h -#define eraFk5hip astEraFk5hip -#define eraFw2m astEraFw2m -#define eraFw2xy astEraFw2xy -#define eraGc2gd astEraGc2gd -#define eraGc2gde astEraGc2gde -#define eraGd2gce astEraGd2gce -#define eraGmst00 astEraGmst00 -#define eraGmst82 astEraGmst82 -#define eraGst00a astEraGst00a -#define eraGst00b astEraGst00b -#define eraGst06 astEraGst06 -#define eraGst06a astEraGst06a -#define eraGst94 astEraGst94 -#define eraH2fk5 astEraH2fk5 -#define eraJdcalf astEraJdcalf -#define eraNum00a astEraNum00a -#define eraNum00b astEraNum00b -#define eraNum06a astEraNum06a -#define eraNumat astEraNumat -#define eraNut00a astEraNut00a -#define eraNut00b astEraNut00b -#define eraNut06a astEraNut06a -#define eraNut80 astEraNut80 -#define eraNutm80 astEraNutm80 -#define eraObl80 astEraObl80 -#define eraP2pv astEraP2pv -#define eraP2s astEraP2s -#define eraPb06 astEraPb06 -#define eraPfw06 astEraPfw06 -#define eraPlan94 astEraPlan94 -#define eraPm astEraPm -#define eraPmat00 astEraPmat00 -#define eraPmat76 astEraPmat76 -#define eraPmp astEraPmp -#define eraPn00 astEraPn00 -#define eraPn00a astEraPn00a -#define eraPn00b astEraPn00b -#define eraPn06 astEraPn06 -#define eraPn06a astEraPn06a -#define eraPnm00a astEraPnm00a -#define eraPnm00b astEraPnm00b -#define eraPnm80 astEraPnm80 -#define eraPom00 astEraPom00 -#define eraPpp astEraPpp -#define eraPpsp astEraPpsp -#define eraPr00 astEraPr00 -#define eraPrec76 astEraPrec76 -#define eraPv2p astEraPv2p -#define eraPv2s astEraPv2s -#define eraPvdpv astEraPvdpv -#define eraPvm astEraPvm -#define eraPvmpv astEraPvmpv -#define eraPvppv astEraPvppv -#define eraPvstar astEraPvstar -#define eraPvu astEraPvu -#define eraPvup astEraPvup -#define eraPvxpv astEraPvxpv -#define eraRefco astEraRefco -#define eraS00 astEraS00 -#define eraS00a astEraS00a -#define eraS00b astEraS00b -#define eraS06 astEraS06 -#define eraS06a astEraS06a -#define eraS2p astEraS2p -#define eraS2pv astEraS2pv -#define eraS2xpv astEraS2xpv -#define eraSp00 astEraSp00 -#define eraStarpm astEraStarpm -#define eraStarpv astEraStarpv -#define eraSxp astEraSxp -#define eraSxpv astEraSxpv -#define eraTaitt astEraTaitt -#define eraTaiut1 astEraTaiut1 -#define eraTaiutc astEraTaiutc -#define eraTcbtdb astEraTcbtdb -#define eraTcgtt astEraTcgtt -#define eraTdbtcb astEraTdbtcb -#define eraTdbtt astEraTdbtt -#define eraTrxpv astEraTrxpv -#define eraTttai astEraTttai -#define eraTttcg astEraTttcg -#define eraTttdb astEraTttdb -#define eraTtut1 astEraTtut1 -#define eraUt1tai astEraUt1tai -#define eraUt1tt astEraUt1tt -#define eraUt1utc astEraUt1utc -#define eraUtctai astEraUtctai -#define eraUtcut1 astEraUtcut1 -#define eraXy06 astEraXy06 -#define eraXys00a astEraXys00a -#define eraXys00b astEraXys00b -#define eraXys06a astEraXys06a -#define eraZp astEraZp -#define eraZpv astEraZpv -#define eraZr astEranZr - -#endif diff --git a/ast/erfam.h b/ast/erfam.h deleted file mode 100644 index 5190b3e..0000000 --- a/ast/erfam.h +++ /dev/null @@ -1,61 +0,0 @@ -#if !defined( ERFAM_INCLUDED ) /* Include this file only once */ -#define ERFAM_INCLUDED -/* -*+ -* Name: -* erfam.h - -* Purpose: -* Macros defined by the ERFA library. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Include file - -* Description: -* Macros defined by the ERFA library. This is needed by the pal.c -* file, which includes source files that include "erfam.h" from the -* current directory (i.e. the main AST source directory), not the -* erfa subdirectory. - -* Authors: -* DSBJ: David S Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 23-FEB-2012 (DSB): -* Initial version. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 3 of -* the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be -* useful, but WITHOUT ANY WARRANTY; without even the implied -* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 -* USA. - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -/* Include the macros defined in the corresponding header file in the - erfa subdirectory. */ -#include "erfa/erfam.h" - -#endif diff --git a/ast/err.h b/ast/err.h deleted file mode 100644 index 9448d86..0000000 --- a/ast/err.h +++ /dev/null @@ -1,66 +0,0 @@ -#if !defined( ERR_INCLUDED ) /* Include this file only once */ -#define ERR_INCLUDED -/* -*+ -* Name: -* err.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the err module. - -* Invocation: -* #include "err.h" - -* Description: -* This include file defines the interface to the err module and -* provides the type definitions, function prototypes and macros, etc. -* needed to use this module. - -* Inheritance: -* The err module is not a class and does not inherit. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (STARLINK) -* {enter_new_authors_here} - -* History: -* 6-NOV-1996 (DSB): -* Original version. -* {enter_changes_here} -*- -*/ - -/* Function prototypes. */ -/* ==================== */ -#if defined(astCLASS) /* Protected */ -void astPutErr_( int, const char * ); - -/* Function interfaces. */ -/* ==================== */ -#define astPutErr(status,message) astPutErr_(status,message) -#endif - -#endif diff --git a/ast/err_drama.c b/ast/err_drama.c deleted file mode 100644 index 643afda..0000000 --- a/ast/err_drama.c +++ /dev/null @@ -1,122 +0,0 @@ -/* -* Name: -* err_ems.c - -* Purpose: -* Implement the "err" module for the DRAMA ERS error system. - -* Description: -* This file implements an alternative "err" module for the AST -* library. It is used to deliver error messages through the -* DRAMA ERS error message system rather than by the default mechanism. - -* Copyright: -* Copyright (C) 2008 Science and Technology Facilities Council. -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (UCLan) -* TIMJ: Tim Jenness (JAC, Hawaii) -* RFWS: R.F. Warren-Smith (STARLINK) -* {enter_new_authors_here} - -* History: -* 6-NOV-1996 (DSB): -* Original version. -* 16-SEP-2008 (TIMJ): -* Use modern EMS interface -* 13-NOV-2008 (TIMJ): -* Modify for DRAMA -* {enter_changes_here} -*/ - -#if HAVE_CONFIG_H -#include -#endif - -/* Module Macros. */ -/* ============== */ -/* Define the astCLASS macro (even although this is not a class - implementation). This indicates to header files that they should - make "protected" symbols available. */ -#define astCLASS - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "err.h" /* Interface to this module */ - -/* Need to define these for DRAMA. Otherwise we have to include drama.h - in the distribution as well */ -#if HAVE_STDARG_H -# define DSTDARG_OK -#endif -#define ERS_STANDALONE -#include "Ers.h" /* Interface to the Ers system */ - -/* Function implementations. */ -/* ========================= */ -void astPutErr_( int status, const char *message ) { -/* -*+ -* Name: -* astPutErr - -* Purpose: -* Deliver an error message. - -* Type: -* Protected function. - -* Synopsis: -* #include "err.h" -* void astPutErr( int status, const char *message ) - -* Description: -* This function delivers an error message and (optionally) an -* accompanying status value to the user. It may be re-implemented -* in order to deliver error messages in different ways, according -* to the environment in which the AST library is being used. - -* Parameters: -* status -* The error status value. -* message -* A pointer to a null-terminated character string containing -* the error message to be delivered. This should not contain -* newline characters. - -* Notes: -* - This function is documented as "protected" but, in fact, is -* publicly accessible so that it may be re-implemented as -* required. -*- -*/ - -/* Local Variables: */ - StatusType local_status; /* Local status value */ - -/* Make a copy of the status value supplied. Then invoke ems_rep_c to - report the error message through EMS and to associate the error - status with it. Ignore any returned status value. */ - local_status = status; - ErsRep( 0, &local_status, "%s", message ); -} diff --git a/ast/err_ems.c b/ast/err_ems.c deleted file mode 100644 index 63bcab6..0000000 --- a/ast/err_ems.c +++ /dev/null @@ -1,108 +0,0 @@ -/* -* Name: -* err_ems.c - -* Purpose: -* Implement the "err" module for the EMS error system. - -* Description: -* This file implements an alternative "err" module for the AST -* library. It is used to deliver error messages through the -* Starlink EMS error message system (Starlink System Note 4) -* rather than by the default mechanism. - -* Copyright: -* Copyright (C) 2008 Science and Technology Facilities Council. -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (STARLINK) -* {enter_new_authors_here} - -* History: -* 6-NOV-1996 (DSB): -* Original version. -* 16-SEP-2008 (TIMJ): -* Use modern EMS interface -* {enter_changes_here} -*/ - -/* Module Macros. */ -/* ============== */ -/* Define the astCLASS macro (even although this is not a class - implementation). This indicates to header files that they should - make "protected" symbols available. */ -#define astCLASS - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "err.h" /* Interface to this module */ -#include "ems.h" /* Interface to the EMS system */ - -/* Function implementations. */ -/* ========================= */ -void astPutErr_( int status, const char *message ) { -/* -*+ -* Name: -* astPutErr - -* Purpose: -* Deliver an error message. - -* Type: -* Protected function. - -* Synopsis: -* #include "err.h" -* void astPutErr( int status, const char *message ) - -* Description: -* This function delivers an error message and (optionally) an -* accompanying status value to the user. It may be re-implemented -* in order to deliver error messages in different ways, according -* to the environment in which the AST library is being used. - -* Parameters: -* status -* The error status value. -* message -* A pointer to a null-terminated character string containing -* the error message to be delivered. This should not contain -* newline characters. - -* Notes: -* - This function is documented as "protected" but, in fact, is -* publicly accessible so that it may be re-implemented as -* required. -*- -*/ - -/* Local Variables: */ - int local_status; /* Local status value */ - -/* Make a copy of the status value supplied. Then invoke ems_rep_c to - report the error message through EMS and to associate the error - status with it. Ignore any returned status value. */ - local_status = status; - emsRep( "AST_ERROR", message, &local_status ); -} diff --git a/ast/err_null.c b/ast/err_null.c deleted file mode 100644 index 72ca9ef..0000000 --- a/ast/err_null.c +++ /dev/null @@ -1,111 +0,0 @@ -/* -* Name: -* err_null.c - -* Purpose: -* Implement the default "err" module. - -* Description: -* This file implements the default "err" module for the AST -* library. It is used to deliver error messages if no alternative -* error delivery mechanism is provided. -* -* To provide an alternative mechanism, re-implement the astPutErr -* function defined within this module. You can then either link -* your program against the resulting library, or you can register -* the re-implemented astPutErr function at run-time using the -* astSetPutErr function defined in file error.c. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (STARLINK) -* {enter_new_authors_here} - -* History: -* 6-NOV-1996 (DSB): -* Original version. -* {enter_changes_here} -*/ - -/* Module Macros. */ -/* ============== */ -/* Define the astCLASS macro (even although this is not a class - implementation). This indicates to header files that they should - make "protected" symbols available. */ -#define astCLASS - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "err.h" /* Interface to this module */ -#include "error.h" /* Interface to the error module */ - -/* C header files. */ -/* --------------- */ -#include - -/* Function implementations. */ -/* ========================= */ -void astPutErr_( int status_value, const char *message ) { -/* -*+ -* Name: -* astPutErr - -* Purpose: -* Deliver an error message. - -* Type: -* Protected function. - -* Synopsis: -* #include "err.h" -* void astPutErr( int status_value, const char *message ) - -* Description: -* This function delivers an error message and (optionally) an -* accompanying status value to the user. It may be re-implemented -* in order to deliver error messages in different ways, according -* to the environment in which the AST library is being used. - -* Parameters: -* status_value -* The error status value. -* message -* A pointer to a null-terminated character string containing -* the error message to be delivered. This should not contain -* newline characters. - -* Notes: -* - This function is documented as "protected" but, in fact, is -* publicly accessible so that it may be re-implemented as -* required. -*- -*/ - - -/* This is the default implementation. Simply write the message to - standard error with a newline appended. Ignore the status value. */ - int *status = astGetStatusPtr; - (void) fprintf( stderr, "%s%s\n", astOK ? "!! " : "! ", message ); -} diff --git a/ast/error.c b/ast/error.c deleted file mode 100644 index a28bfff..0000000 --- a/ast/error.c +++ /dev/null @@ -1,1359 +0,0 @@ -/* -* Name: -* error.c - -* Purpose: -* Implement error handling functions. - -* Description: -* This file implements the Error module which provides functions -* for handling error conditions in the AST library. Internally, AST -* indicates an error has occurred by calling function astError. This -* in turn delivers an apprioriate error message to the user by -* calling a function, astPutErr. The default version of astPutErr -* that comes with AST simply writes the message to standard output, -* but astPutErr can be re-implemented if required to deliver the -* message to some external underlying error system. The -* re-implemented function can either be linked into your application -* in place of the default version at build-time (see the options in -* the ast_link script), or registered at run-time using function -* astSetPutErr (defined within this module). See the file err_null.c -* included in the AST source distribution for details of how to -* re-implement astPutErr. -* -* Since its initial release, AST has used a global status variable -* rather than adding an explicit status parameter to the argument -* list of each AST function. This caused problems for the thread-safe -* version of AST since each thread needs its own status value. Whilst -* it would have been possible for each function to access a global -* status value via the pthreads "thread speific data key" mechanism, -* the huge number of status checks performed within AST caused this -* option to be slow. Instead AST has been modified so that every -* function has an explicit status pointer parameter. This though -* causes problems in that we cannot change the public interface to -* AST because doing so would break large amounts of external software. -* To get round this, the macros that define the public interface to -* AST have been modified so that they provide a status pointer -* automatically to the function that is being invoked. This is how -* the system works... -* -* All AST functions have an integer inherited status pointer parameter -* called "status". This parameter is "hidden" in AST functions that -* are invoked via macros (typically public and protected functions). -* This means that whilst "int *status" appears explicitly at the end -* of the function argument list (in both prototype and definition), it -* is not included in the prologue documentation, and is not included -* explicitly in the argument list when invoking the function. Instead, -* the macro that is used to invoke the function adds in the required -* status parameter to the function invocation. -* -* Macros which are invoked within AST (the protected interface) expand -* to include ", status" at the end of the function parameter list. For -* backward compatability with previous versions of AST, macros which -* are invoked from outside AST (the public interface) expand to include -* ", astGetStatusPtr" at the end of the function parameter list. The -* astGetStatusPtr function returns a pointer to the interbal AST -* status variable or to the external variable specified via astWatch. -* -* Parameter lists for functions that have variable argument lists -* (such as astError) cannot be handled in this way, since macros cannot -* have variable numbers of arguments. Instead, separate public and -* protected implementations of such functions are provided within AST. -* Protected implementations include an explicit, documented status -* pointer parameter that must be given explicitly when invoking the -* function. Public implementations do not have a status pointer -* parameter. Instead they obtain the status pointer internally using -* astGetStatusPtr. -* -* Private functions are called directly rather than via macros, and so -* they have a documented status pointer parameter that should be -* included explicitly in the parameter list when invoking the -* function. - -* Copyright: -* Copyright (C) 2017 East Asian Observatory. -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2008-2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 2-JAN-1996 (RFWS): -* Original version. -* 8-JAN-1996 (RFWS): -* Tidied up. -* 26-JAN-1996 (RFWS): -* Incorporated changes to prologue style. -* 14-JUN-1996 (RFWS): -* Added astAt. -* 20-JUN-1996 (RFWS): -* Added astSetStatus. -* 15-JUL-1996 (RFWS): -* Sorted out the public interface. -* 16-JUL-1996 (RFWS): -* Added astWatch. -* 18-MAR-1998 (RFWS): -* Added notes about functions being available for writing -* foreign language and graphics interfaces, etc. -* 27-NOV-2002 (DSB): -* Added suppression of error reporting using astReporting. -* 11-MAR-2004 (DSB): -* Add facility to astAt to allow astAt to be called from public -* interface without private interface settings over-riding the -* public interface settings. -* 30-MAR-2005 (DSB): -* Added facility to report deferred messages when reporting is -* switched back on. -* 16-FEB-2006 (DSB): -* Improve efficiency by replacing the astOK_ function with a macro -* which tests the value of status variable. The pointer which points -* to the AST status variable are now global rather than static. -* 19-SEP-2008 (DSB): -* Big changes for the thread-safe version of AST. -* 3-FEB-2009 (DSB): -* Added astBacktrace. -* 28-FEB-2017 (DSB): -* Added facility for specifying the error handling function, -* astPutErr, at run-time via new function astSetPutErr, rather -* than at link-time. -* 17-OCT-2017 (DSB): -* Added astGetAt. -*/ - -/* Define the astCLASS macro (even although this is not a class - implementation) to obtain access to protected interfaces. */ -#define astCLASS - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "err.h" /* Interface to the err module */ -#include "error.h" /* Interface to this module */ -#include "globals.h" /* Thread-safe global data access */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Configuration results. */ -/* ---------------------- */ -#if HAVE_CONFIG_H -#include -#endif - -/* Select the appropriate memory management functions. These will be the - system's malloc, free and realloc unless AST was configured with the - "--with-starmem" option, in which case they will be the starmem - malloc, free and realloc. */ -#ifdef HAVE_STAR_MEM_H -# include -# define MALLOC starMalloc -# define FREE starFree -# define REALLOC starRealloc -#else -# define MALLOC malloc -# define FREE free -# define REALLOC realloc -#endif - -/* Include execinfo.h if the backtrace function is available */ -#if HAVE_EXECINFO_H -#include -#endif - - - -/* Module Variables. */ -/* ================= */ - -/* Define macros for accessing all items of thread-safe global data - used by this module. */ -#ifdef THREAD_SAFE - -#define reporting astGLOBAL(Error,Reporting) -#define current_file astGLOBAL(Error,Current_File) -#define puterr astGLOBAL(Error,PutErr) -#define puterr_wrapper astGLOBAL(Error,PutErr_Wrapper) -#define current_routine astGLOBAL(Error,Current_Routine) -#define current_line astGLOBAL(Error,Current_Line) -#define foreign_set astGLOBAL(Error,Foreign_Set) -#define message_stack astGLOBAL(Error,Message_Stack) -#define mstack_size astGLOBAL(Error,Mstack_Size) - -/* Since the external astPutErr function may not be thread safe, we need - to ensure that it cannot be invoked simultaneously from two different - threads. So we lock a mutex before each call to astPutErr. */ -static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX1 pthread_mutex_lock( &mutex1 ) -#define UNLOCK_MUTEX1 pthread_mutex_unlock( &mutex1 ) - -/* Define the initial values for the global data for this module. */ -#define GLOBAL_inits \ - globals->Reporting = 1; \ - globals->PutErr = NULL; \ - globals->PutErr_Wrapper = NULL; \ - globals->Current_File = NULL; \ - globals->Current_Routine = NULL; \ - globals->Current_Line = 0; \ - globals->Foreign_Set = 0; \ - globals->Mstack_Size = 0; \ - -/* Create the global initialisation function. */ -astMAKE_INITGLOBALS(Error) - - -/* If thread safety is not needed, declare globals at static variables. */ -/* -------------------------------------------------------------------- */ -#else - -/* Status variable. */ -static int internal_status = 0; /* Internal error status */ -int *starlink_ast_status_ptr = &internal_status; /* Pointer to status variable */ - -/* Reporting flag: delivery of message is supressed if zero. */ -static int reporting = 1; - -/* Error context. */ -static const char *current_file = NULL; /* Current file name pointer */ -static const char *current_routine = NULL; /* Current routine name pointer */ -static int current_line = 0; /* Current line number */ -static int foreign_set = 0; /* Have foreign values been set? */ - -/* Function pointers */ -static AstPutErrFun puterr = NULL; /* Pointer to registered error handler */ -static AstPutErrFunWrapper puterr_wrapper = NULL; /* Pointer to - PutError wrapper */ - -/* Un-reported message stack */ -static char *message_stack[ AST__ERROR_MSTACK_SIZE ]; -static int mstack_size = 0; - -#define LOCK_MUTEX1 -#define UNLOCK_MUTEX1 - -#endif - - -/* Function prototypes. */ -/* ==================== */ -static void PutErr( int, const char * ); -static void CPutErrWrapper( AstPutErrFun, int, const char * ); -static void EmptyStack( int, int * ); - -/* Function implementations. */ -/* ========================= */ -void astAt_( const char *routine, const char *file, int line, int forn, - int *status) { -/* -*+ -* Name: -* astAt - -* Purpose: -* Store a routine, file and line number context in case of error. - -* Type: -* Protected function. - -* Synopsis: -* #include "error.h" -* void astAt( const char *routine, const char *file, int line, int forn) - -* Description: -* This function stores a pointer to two strings containing the -* names of a routine and a file, together with an integer line -* number. These values are retained for subsequent use in -* reporting the context of any error that may arise. - -* Parameters: -* routine -* Pointer to a null terminated C string containing a routine -* name (which should reside in static memory). -* file -* Pointer to a null terminated C string containing a file name -* (which should reside in static memory). -* line -* The line number in the file. -* for -* Is this call being made from a foreign language interface? -* If so any values supplied will take precedence of the values -* set by the C interface. - -* Notes: -* - This function returns without action (i.e. without changing -* the stored values) if the global error status is set. It -* performs no other error checking. -* - Any (or all) of the arguments may be omitted by supplying a -* NULL or zero value (as appropriate) and will then not be included -* in any error report. -* - This function is documented as protected because it should not -* be invoked by external code. However, it is available via the -* external C interface so that it may be used when writing (e.g.) -* foreign language or graphics interfaces. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* If the values refer to a foreign interface, or if no foreign values - have yet been set, store the supplied values. */ - if( forn|| !foreign_set ) { - current_routine = routine; - current_file = file; - current_line = line; - } - -/* If the values relate to a foreign interface, set a flag which prevents - local values set later replacing them. */ - foreign_set = forn; -} - -void astBacktrace_( int *status ) { -/* -c+ -* Name: -* astBacktrace - -* Purpose: -* Display a backtrace on standard output. - -* Type: -* Protected macro. - -* Synopsis: -* #include "error.h" -* astBacktrace; - -* Description: -* This macro displays a set of messages on standard output that -* give a backtrace of the caller. It can be useful for debugging AST -* code in situations when it is not easy or possible to use a -* debugger (for instance, when debugging JNIAST). - -* Notes: -* - Only non-static function names are included in the backtrace. -* - This function requires the GNU C library. When called, it will -* just issue a warning if the GNU 'backtrace' function was not -* available when AST was configured. -c- -*/ -#if HAVE_BACKTRACE - -#define MAX_ADDR 100 - -/* Local Variables: */ - char **strings; /* Pointer to array of formated strings */ - char buf[ 120 ]; /* Output line buffer */ - int j; /* String index */ - int np; /* Number of used return addresses */ - void *buffer[ MAX_ADDR ]; /* Array of return addresses */ - -/* Get the array of return addresses. */ - np = backtrace( buffer, MAX_ADDR ); - -/* Convert them into strings. */ - strings = backtrace_symbols( buffer, np ); - -/* If succesful, display them and then free the array. Note we skip the - first one since that will refer to this function. */ - if( strings ) { - PutErr( astStatus, " " ); - for( j = 1; j < np; j++ ) { - sprintf( buf, "%d: %s", j, strings[j] ); - PutErr( astStatus, buf ); - } - free( strings ); - PutErr( astStatus, " " ); - -/* If not succesful, issue a warning. */ - } else { - PutErr( astStatus, "Cannot convert backtrace addresses into formatted strings" ); - } - -#else - PutErr( astStatus, "Backtrace functionality is not available " - "on the current operating system." ); -#endif -} - -void astClearStatus_( int *status ) { -/* -c++ -* Name: -* astClearStatus - -* Purpose: -* Clear the AST error status. - -* Type: -* Public macro. - -* Synopsis: -* #include "error.h" -* void astClearStatus - -* Description: -* This macro resets the AST error status to an OK value, -* indicating that an error condition (if any) has been cleared. - -* Notes: -* - If the AST error status is set to an error value (after an -* error), most AST functions will not execute and will simply -* return without action. Using astClearStatus will restore normal -* behaviour. -c-- -*/ - -/* Empty the deferred error stack without displaying the messages on the - stack. */ - EmptyStack( 0, status ); - -/* Reset the error status value. */ - *status = 0; -} - -static void EmptyStack( int display, int *status ) { -/* -* Name: -* EmptyStack - -* Purpose: -* Empty the stack of deferred error messages, optionally displaying -* them. - -* Type: -* Private function. - -* Synopsis: -* #include "error.h" -* void EmptyStack( int display, int *status ) - -* Description: -* This function removes all messages from the stack of deferred error -* messages. If "display" is non-zero it reports them using astPutErr -* before deleting them. - -* Parameters: -* display -* Report messages before deleting them? -* status -* Pointer to the integer holding the inherited status value. - -*/ - -/* Local variables; */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int i; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Loop round all messages on the stack. */ - for( i = 0; i < mstack_size; i++ ) { - -/* Display the message if required. */ - if( display ) PutErr( astStatus, message_stack[ i ] ); - -/* Free the memory used to hold the message. */ - FREE( message_stack[ i ] ); - message_stack[ i ] = NULL; - } - -/* Reset the stack size to zero. */ - mstack_size = 0; - -} - -void astErrorPublic_( int status_value, const char *fmt, ... ) { -/* -*+ -* Name: -* astError - -* Purpose: -* Set the AST error status and report an error message. - -* Type: -* Protected function. - -* Synopsis: -* #include "error.h" -* void astError( int status_value, const char *fmt, ... ) - -* Description: -* This function sets the AST error status to a specified value and -* reports an associated error message. - -* Parameters: -* status_value -* The new error status value to be set. -* fmt -* Pointer to a null-terminated character string containing the -* format specification for the error message, in the same way -* as for a call to the C "printf" family of functions. -* ... -* Additional optional arguments (as used by e.g. "printf") -* which specify values which are to appear in the error -* message. - -* Notes: -* This function operates just like "printf", except that: -* - The first argument is an error status. -* - The return value is void. -* - A newline is automatically appended to the error message -* (there is no need to add one). -* - This function is documented as protected because it should not -* be invoked by external code. However, it is available via the -* external C interface so that it may be used when writing (e.g.) -* foreign language or graphics interfaces. -*- - -* This is the public implementation of astError. It does not have an - status pointer parameter, but instead obtains the status pointer - explicitly using the astGetStatusPtr function. This is different to - other public functions, which typically have a status pointer parameter - that is supplied via a call to astGetStatusPtr within the associated - interface macro. The benefit of doing it the usual way is that the - public and protected implementations are the same, with the - differences between public and protecte dinterfaces wrapped up in the - associated interface macro. We cannot do this with this function - because of the variale argument list. The prologue for the astError_ - function defines the interface for use internally within AST. - -*/ - -/* Local Constants: */ -#define BUFF_LEN 1023 /* Max. length of an error message */ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char buff[ BUFF_LEN + 1 ]; /* Message buffer */ - int *status; /* Pointer to inherited status value */ - int imess; /* Index into deferred message stack */ - int nc; /* Number of characters written */ - va_list args; /* Variable argument list pointer */ - -/* Initialise the variable argument list pointer. */ - va_start( args, fmt ); - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the integer holding the inherited status value. */ - status = astGetStatusPtr; - -/* If this is the first report of an error (the global status has not - previously been set) and error context information is available, - then construct an error context message. */ - if ( astOK && - ( current_routine || current_file || current_line ) ) { - nc = sprintf( buff, "AST: Error" ); - if ( current_routine ) { - nc += sprintf( buff + nc, " in routine %s", current_routine ); - } - if ( current_line ) { - nc += sprintf( buff + nc, " at line %d", current_line ); - } - if ( current_file ) { - nc += sprintf( buff + nc, " in file %s", current_file ); - } - nc += sprintf( buff + nc, "." ); - -/* Deliver the error message unless reporting has been switched off using - astReporting. In which case store them in a static array. */ - if( reporting ) { - PutErr( status_value, buff ); - } else if( mstack_size < AST__ERROR_MSTACK_SIZE ){ - imess = mstack_size++; - message_stack[ imess ] = MALLOC( strlen( buff ) + 1 ); - if( message_stack[ imess ] ) { - strcpy( message_stack[ imess ], buff ); - } - } - -/* Set the global status. */ - astSetStatus( status_value ); - } - -/* Write the error message supplied to the formatting buffer. */ - nc = vsprintf( buff, fmt, args ); - -/* Tidy up the argument pointer. */ - va_end( args ); - -/* Deliver the error message unless reporting has been switched off using - astReporting. */ - if( reporting ) { - PutErr( status_value, buff ); - } else if( mstack_size < AST__ERROR_MSTACK_SIZE ){ - imess = mstack_size++; - message_stack[ imess ] = MALLOC( strlen( buff ) + 1 ); - if( message_stack[ imess ] ) { - strcpy( message_stack[ imess ], buff ); - } - } - -/* Set the error status value. */ - astSetStatus( status_value ); - -/* Undefine macros local to this function. */ -#undef BUFF_LEN -} - -void astError_( int status_value, const char *fmt, int *status, ... ) { -/* -*+ -* Name: -* astError - -* Purpose: -* Set the AST error status and report an error message. - -* Type: -* Protected function. - -* Synopsis: -* #include "error.h" -* void astError( int status_value, const char *fmt, int *status, ... ) - -* Description: -* This function sets the AST error status to a specified value and -* reports an associated error message. - -* Parameters: -* status_value -* The error status value to be set. -* fmt -* Pointer to a null-terminated character string containing the -* format specification for the error message, in the same way -* as for a call to the C "printf" family of functions. -* status -* Pointer to the integer holding the inherited status value. -* ... -* Additional optional arguments (as used by e.g. "printf") -* which specify values which are to appear in the error -* message. - -* Notes: -* This function operates just like "printf", except that: -* - The first argument is an error status. -* - The return value is void. -* - A newline is automatically appended to the error message -* (there is no need to add one). -* - This function is documented as protected because it should not -* be invoked by external code. However, it is available via the -* external C interface so that it may be used when writing (e.g.) -* foreign language or graphics interfaces. -*- - -* This is the protected implementation of astError. It has a status - pointer parameter that is not present in the public form. Different - implementations for protected and public interfaces are required - because of the variable argument list. - -*/ - -/* Local Constants: */ -#define BUFF_LEN 1023 /* Max. length of an error message */ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char buff[ BUFF_LEN + 1 ]; /* Message buffer */ - int imess; /* Index into deferred message stack */ - int nc; /* Number of characters written */ - va_list args; /* Variable argument list pointer */ - -/* Initialise the variable argument list pointer. */ - va_start( args, status ); - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* If this is the first report of an error (the global status has not - previously been set) and error context information is available, - then construct an error context message. */ - if ( astOK && - ( current_routine || current_file || current_line ) ) { - nc = sprintf( buff, "AST: Error" ); - if ( current_routine ) { - nc += sprintf( buff + nc, " in routine %s", current_routine ); - } - if ( current_line ) { - nc += sprintf( buff + nc, " at line %d", current_line ); - } - if ( current_file ) { - nc += sprintf( buff + nc, " in file %s", current_file ); - } - nc += sprintf( buff + nc, "." ); - -/* Deliver the error message unless reporting has been switched off using - astReporting. In which case store them in a static array. */ - if( reporting ) { - PutErr( status_value, buff ); - } else if( mstack_size < AST__ERROR_MSTACK_SIZE ){ - imess = mstack_size++; - message_stack[ imess ] = MALLOC( strlen( buff ) + 1 ); - if( message_stack[ imess ] ) { - strcpy( message_stack[ imess ], buff ); - } - } - -/* Set the global status. */ - astSetStatus( status_value ); - } - -/* Write the error message supplied to the formatting buffer. */ - nc = vsprintf( buff, fmt, args ); - -/* Tidy up the argument pointer. */ - va_end( args ); - -/* Deliver the error message unless reporting has been switched off using - astReporting. */ - if( reporting ) { - PutErr( status_value, buff ); - } else if( mstack_size < AST__ERROR_MSTACK_SIZE ){ - imess = mstack_size++; - message_stack[ imess ] = MALLOC( strlen( buff ) + 1 ); - if( message_stack[ imess ] ) { - strcpy( message_stack[ imess ], buff ); - } - } - -/* Set the error status value. */ - astSetStatus( status_value ); - -/* Undefine macros local to this function. */ -#undef BUFF_LEN -} - -void astGetAt_( const char **routine, const char **file, int *line ){ -/* -*+ -* Name: -* astGetAt - -* Purpose: -* Return the current routine, file and line number context. - -* Type: -* Protected function. - -* Synopsis: -* #include "error.h" -* void astGetAt( const char **routine, const char **file, int *line ) - -* Description: -* This function returns pointers to two strings containing the -* names of a routine and a file, together with an integer line -* number. These values will have been stored previously by calling -* function astAt. Null values are returned if astAt has not been -* called. - -* Parameters: -* routine -* Address of a pointer to a null terminated C string containing -* a routine name (the string will reside in static memory). The -* pointer will be set to NULL on exit if no routine name has been -* specified usiung astAt. -* file -* Address of a pointer to a null terminated C string containing -* a file name (the string will reside in static memory). The -* pointer will be set to NULL on exit if no file name has been -* specified usiung astAt. -* line -* Address of an int in which to stopre the line number in the file. -* A line number of zero is returned if no line number has been -* stored using astAt. - -* Notes: -* - This function attempts to execute even if the global error status -* is set. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Return the stored values */ - *routine = current_routine; - *file = current_file; - *line = current_line; -} - -int *astGetStatusPtr_(){ -/* -*+ -* Name: -* astGetStatusPtr - -* Purpose: -* Return a pointer to the integer holding the inherited status value. - -* Type: -* Protected function. - -* Synopsis: -* #include "error.h" -* int *astGetStatusPtr; - -* Description: -* This macro returns a pointer to the integer holding the inherited -* status pointer. This will either be an internal global integer -* (possibly stored as thread specific data), or an ineger specified -* via the astWatch function. - -* Returned Value: -* A pointer to the integer holding the inherited status value. - -*- -*/ - -/* The thread-safe version of AST stores the status pointer in thread - specific data, using the key stored in the global variable - "starlink_ast_status_key". */ -#if defined(THREAD_SAFE) - astDECLARE_GLOBALS - AstStatusBlock *sb; - - astGET_GLOBALS(NULL); - sb = (AstStatusBlock *) pthread_getspecific(starlink_ast_status_key); - return sb->status_ptr; - -/* The non thread-safe version of AST stores the status pointer in the - global variable "starlink_ast_status_ptr". */ -#else - return starlink_ast_status_ptr; -#endif -} - -static void CPutErrWrapper( AstPutErrFun fun, int status_value, - const char *message ) { -/* -* -* Name: -* CPutErrWrapper - -* Purpose: -* A wrapper to call a astPutErr error handling function written in C. - -* Type: -* Private function. - -* Synopsis: -* #include "error.h" -* void CPutErrWrapper( AstPutErrFun fun, int status_value, -* const char *message ) - -* Description: -* This function calls the supplied astPutErr function to deliver -* an error message, assuming the supplied function is written in C. - -* Parameters: -* fun -* Pointer to the user-supplied astPutErr function. It is called -* using C calling conventions -* status_value -* The error status value. -* message -* A pointer to a null-terminated character string containing -* the error message to be delivered. This should not contain -* newline characters. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX1; - -/* Invoke the astPutErr function registered using astSetPutErr. */ - if( fun ) ( *fun )( status_value, message ); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX1; -} - -static void PutErr( int status_value, const char *message ) { -/* -* -* Name: -* PutErr - -* Purpose: -* Call the astPutErr error handling function. - -* Type: -* Private function. - -* Synopsis: -* #include "error.h" -* void PutErr( int status_value, const char *message ) - -* Description: -* This function calls the astPutErr function to deliver an error -* message, either calling the version registered using astSetPutErr, -* or the version in the linked error module. The linked version -* is used if no function has been registered for PutErr using -* astSetPutErr. - -* Parameters: -* status_value -* The error status value. -* message -* A pointer to a null-terminated character string containing -* the error message to be delivered. This should not contain -* newline characters. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int old_status; /* Old status value */ - int *status; /* Pointer to status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Use the astPutErr function registered using astSetPutErr (so long as a - function has been supplied). This is called via a wrapper which adapts - the interface to suit the language in which the function is written. */ - if( puterr && puterr_wrapper ) { - -/* We need to ensure the AST status is cleared before invoking the - external error handler, as it may use AST memory management functions, - will return without action if the AST status is non-zero. Remember the - current status value so that it can be re-instated afterwards. */ - status = astGetStatusPtr; - old_status = *status; - *status = 0; - - ( *puterr_wrapper )( puterr, status_value, message ); - - *status = old_status; - -/* Otherwise, use the function in the external error module, selected at - link-time using ast_link options.*/ - } else { - astPutErr( status_value, message ); - } -} - - -/* -c++ -* Name: -* astOK - -* Purpose: -* Test whether AST functions have been successful. - -* Type: -* Public macro. - -* Synopsis: -* #include "error.h" -* int astOK - -* Description: -* This macro returns a boolean value (0 or 1) to indicate if -* preceding AST functions have completed successfully -* (i.e. without setting the AST error status). If the error status -* is set to an error value, a value of zero is returned, otherwise -* the result is one. - -* Returned Value: -* astOK -* One if the AST error status is OK, otherwise zero. - -* Notes: -* - If the AST error status is set to an error value (after an -* error), most AST functions will not execute and will simply -* return without action. To clear the error status and restore -* normal behaviour, use astClearStatus. -c-- -*/ - - -int astReporting_( int report, int *status ) { -/* -c+ -* Name: -* astReporting - -* Purpose: -* Controls the reporting of error messages. - -* Type: -* Protected function. - -* Synopsis: -* #include "error.h" -* int astReporting( int report ) - -* Description: -* Error messages supplied to astError will only be delivered to the -* underlying error system if the "Reporting" flag is set to a -* non-zero value. Setting this flag to zero suppresses the reporting -* of error messages (the value of the AST error status however is -* unaffected). Instead, the reports are saved in an internal message -* stack. When reporting is switched back on again, any messages on this -* stack of deferred messages will be reported (and the stack emptied) -* if the AST error status is not astOK. Also the stack is emptied each -* time astClearStatus is called (the stacked messages are not displayed -* in this case). - -* Parameters: -* report -* The new value for the Reporting flag. - -* Returned Value: -* The original value of the Reporting flag. - -* Notes: -* - The Reporting flag is initially set to 1. -c- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int oldval; /* Original "reporting" value */ - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Save the original reporting value, and then store the new value. */ - oldval = reporting; - reporting = report; - -/* If we are now reporting errors, flush any messages on the error stack. - This causes the messages to be displayed and the stack emptied. */ - if( reporting ) EmptyStack( 1, status ); - -/* Return the original reporting value. */ - return oldval; -} - -void astSetPutErr_( AstPutErrFun fun, int *status ){ -/* -*++ -* Name: -c astSetPutErr -f AST_SETPUTERR - -* Purpose: -c Register an error handling function for use by the AST error model -f Register an error handling routine for use by the AST error model - -* Type: -* Public function. - -* Synopsis: -c #include "error.h" -c void astSetPutErr( void (*fun)(int,const char*) ) -f CALL AST_GRFSET( FUN, STATUS ) - -* Description: -* This function can be used to register an external function to be -* used to deliver an error message and (optionally) an accompanying -* status value to the user. -* -* If this function is not called prior to the first error occuring -* within AST, then the external error handling function selected at -* link-time (using the ast_link command) will be used. To use an -* alternative error handler, call this function before using any other -* AST functions, specifying the external error handling function to be -* used. This will register the function for future use. - -* Parameters: -c fun -f FUN = INTEGER FUNCTION (Given) -c A Pointer to the function to be used to handle errors. The interface -c for this function is described below. -f The name of the routine to be used to handle errors (the name -f should also appear in a Fortran EXTERNAL statement in the -f routine which invokes AST_SETPUTERR). -c Once a function has been provided, a NULL pointer can be supplied -c in a subsequent call to astSetPutErr to reset the function to the -c corresponding function selected at link-time. -f Once a routine has been provided, the "null" routine AST_NULL can -f be supplied in a subsequent call to astSetPutErr to reset the routine -f to the corresponding routine selected at link-time. AST_NULL is -f defined in the AST_PAR include file. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Function Interface: -* The supplied external function should deliver the supplied error message -* and (optionally) the supplied status value to the user or to some -* underlying error system. It requires the following interface: -* -c void PutErr( int status_value, const char *message ) -f SUBROUTINE PUTERR( STATUS_VALUE, MESSAGE ) -* -c - status_value - -f - STATUS_VALUE = INTEGER (Given) - -* The error status value. -c - message - Pointer to a null-terminated character string containing -c the error message to be delivered. -f - MESSAGE = CHARACTER * ( * ) (Given) - The error message to be delivered. - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Ensure that the thread-specific status block has been created and - initialised. */ - astGET_GLOBALS(NULL); - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the pointer. */ - puterr = fun; - -/* In general, the interface to the PutErr function will differ for - different languages. So we need a wrapper function with a known fixed - interface which can be used to invoke the actual function with - an interface suited to the language in use. Call astPutErrWrapper to - store a wrapper to a suitable function which can invoke the supplied - function. Here, we assume that the supplied function has a C interface, - so we set up a C wrapper. If this function is being called from another - language, then the interface for this function within that language - should set up an appropriate wrapper after calling this function, thus - over-riding the C wrapper set up here. */ - astSetPutErrWrapper( CPutErrWrapper ); -} - -void astSetPutErrWrapper_( AstPutErrFunWrapper wrapper, int *status ){ -/* -*+ -* Name: -* astSetPutErrWrapper - -* Purpose: -* Register a wrapper for the error handling function. - -* Type: -* Public function. - -* Synopsis: -* #include "error.h" -* void astSetPutErrWrapper( AstPutErrFunWrapper wrapper ) - -* Description: -* This function must be used to register a wrapper for the external -* function to be used to deliver an error message and (optionally) -* an accompanying status value to the user. - -* Parameters: -* wrapper -* A pointer to the wrapper function to be used to handle errors. - -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Ensure that the thread-specific status block has been created and - initialised. */ - astGET_GLOBALS(NULL); - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the pointer. */ - puterr_wrapper = wrapper; -} - -/* -c++ -* Name: -* astSetStatus - -* Purpose: -* Set the AST error status to an explicit value. - -* Type: -* Public function. - -* Synopsis: -* #include "error.h" -* void astSetStatus( int status_value ) - -* Description: -* This function sets the AST error status to the value supplied. -* It does not cause any error message to be produced and should -* not be used as part of normal error reporting. Its purpose is -* simply to communicate to AST that an error has occurred in some -* other item of software. -* -* For example, a source or sink function supplied as an argument -* to astChannel or astFitsChan might use this to signal that an -* input/output error has occurred. AST could then respond by -* terminating the current read or write operation. - -* Parameters: -* status_value -* The new error status value to be set. - -* Notes: -* - If the AST error status is set to an error value, most AST -* functions will not execute and will simply return without -* action. To clear the error status and restore normal behaviour, -* use astClearStatus. -c-- -*/ - -/* -c++ -* Name: -* astStatus - -* Purpose: -* Obtain the current AST error status value. - -* Type: -* Public function. - -* Synopsis: -* #include "error.h" -* int astStatus - -* Description: -* This function returns the current value of the AST error status. - -* Returned Value: -* astStatus -* The AST error status value. - -* Notes: -* - If the AST error status is set to an error value (after an -* error), most AST functions will not execute and will simply -* return without action. To clear the error status and restore -* normal behaviour, use astClearStatus. -c-- -*/ - -int *astWatch_( int *status_ptr ) { -/* -c++ -* Name: -* astWatch - -* Purpose: -* Identify a new error status variable for the AST library. - -* Type: -* Public function. - -* Synopsis: -* #include "error.h" -* int *astWatch( int *status_ptr ) - -* Description: -* This function allows a new error status variable to be accessed -* by the AST library when checking for and reporting error -* conditions. -* -* By default, the library uses an internal integer error status -* which is set to an error value if an error occurs. Use of -* astWatch allows the internal error status to be replaced by an -* integer variable of your choosing, so that the AST library can -* share its error status directly with other code which uses the -* same error detection convention. -* -* If an alternative error status variable is supplied, it is used -* by all related AST functions and macros (e.g. astOK, astStatus -* and astClearStatus). - -* Parameters: -* status_ptr -* Pointer to an int whose value is to be used subsequently as -* the AST inherited status value. If a NULL pointer is supplied, -* the AST library will revert to using its own internal error status. - -* Returned Value: -* astWatch() -* Address of the previous error status variable. This may later -* be passed back to astWatch to restore the previous behaviour -* of the library. (Note that on the first invocation of -* astWatch the returned value will be the address of the -* internal error status variable.) - -* Notes: -* - This function is not available in the FORTRAN 77 interface to -* the AST library. -c-- -*/ - -/* Local Variables: */ - int *result; /* Value to be returned */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -#if defined(THREAD_SAFE) - AstStatusBlock *sb = NULL; -#endif - -/* Ensure that the thread-specific status block has been created and - ininitialised. */ - astGET_GLOBALS(NULL); - -#if defined(THREAD_SAFE) - sb = (AstStatusBlock *) pthread_getspecific( starlink_ast_status_key ); - result = sb->status_ptr; - sb->status_ptr = status_ptr ? status_ptr : &(sb->internal_status); -#else - result = starlink_ast_status_ptr; - starlink_ast_status_ptr = status_ptr ? status_ptr : &internal_status; -#endif - -/* Return the old address. */ - return result; -} - - - diff --git a/ast/error.h b/ast/error.h deleted file mode 100644 index af0e2ae..0000000 --- a/ast/error.h +++ /dev/null @@ -1,362 +0,0 @@ -#if !defined( ERROR_INCLUDED ) /* Include this file only once */ -#define ERROR_INCLUDED 1 -/* -*+ -* Name: -* error.h - -* Purpose: -* Define the interface to the Error module. - -* Description: -* This module defines functions which implement error handling and -* reporting of error messages from within the AST library. A -* simple public interface is included to allow the AST error -* status to be tested and cleared after an error. -* -* Note that this module is not a class implementation, although it -* resembles one. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2008 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S Berry (Starlink) -* NG: Norman Gray (Starlink) - -* History: -* 2-JAN-1996 (RFWS): -* Original version. -* 26-JAN-1996 (RFWS): -* Added function interfaces. -* 14-JUN-1996 (RFWS): -* Added AST__FAC and astAt. -* 20-JUN-1996 (RFWS): -* Added astSetStatus. -* 16-JUL-1996 (RFWS): -* Added astWatch. -* 18-MAR-1998 (RFWS): -* Make interface available for writing foreign language and -* graphics interfaces, etc. -* 27-NOV-2002 (DSB): -* Added astReporting. -* 14-MAR-2005 (NG): -* Added astAssert -* 20-MAY-2005 (DSB): -* Modified astAssert so that it does nothing if the AST error -* status is already set, and also so that does nothing unless -* the DEBUG macro is defined. -* 16-FEB-2006 (DSB): -* Improve efficiency by replacing the astOK_ function with a macro -* which tests the value of status variable. The pointer which points -* to the status variable are now global rather than static. -* 1-MAR-2006 (DSB): -* Remove astAssert. -* 19-SEP-2008 (DSB) -* Big changes for thread-safe version of AST. -*- -*/ - -/* Suppress "operands are evaluated in unspecified order" warnings from - the Intel icc compiler. These are caused by the astGetStatusPtr_ - function being called several times within each of the macros that - form the public interface for AST. */ -#ifdef __INTEL_COMPILER -#pragma warning(disable:981) -#endif - - -/* Include files. */ -/* ============== */ -#if defined(THREAD_SAFE) -#include -#endif - -#if HAVE_CONFIG_H -#include -#endif - -/* Macros. */ -/* ======= */ -#if defined(astCLASS) || defined(astFORTRAN77) /* Protected */ - -/* Define a facility number that is unique to this library. The number here - * is the facility code assigned to the AST library, but it doesn't have to - * be this number -- it only has to be probably unique. If that code were - * ever to change, then you can update this number if you feel it's tidier - * that way. */ -#define AST__FAC (1521) - -/* Max number of messages which can be deferred when reporting is - switched off. */ -#define AST__ERROR_MSTACK_SIZE 100 - -#endif - - -/* This macro expands to an invocation of a specified function, together - with a call to astAt to record the routine, file and line number at which - the invocation occurs. These are included in public error reports and are - stored with public Object identifiers (from which they can be recoivered - using function astCreatedAt). This is only done for invocations from - outside of AST (i.e. public invocations). */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define astERROR_INVOKE(function) (function) -#elif defined FUNCTION_NAME -#define astERROR_INVOKE(function) (astAt_(FUNCTION_NAME,__FILE__,__LINE__,0,astGetStatusPtr),(function)) -#else -#define astERROR_INVOKE(function) (astAt_(NULL,__FILE__,__LINE__,0,astGetStatusPtr),(function)) -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type definitions */ -/* ================ */ - -/* The interface for the PutErr functions to be passed as an argument - to astSetPutErr. */ -typedef void (* AstPutErrFun)( int, const char * ); - -/* The interface for the PutErr wrapper functions to be passed as an argument - to astSetPutErrWrapper. */ -typedef void (* AstPutErrFunWrapper)( AstPutErrFun, int, const char * ); - -/* Define a structure to hold information about an error context. */ -typedef struct AstErrorContext { - int reporting; /* Value of error reporting flag at start of context */ - int ok; /* Was the status value OK at start of context? */ - int status; /* The status value at the start of the context */ -} AstErrorContext; - -#if defined(THREAD_SAFE) && ( defined(astCLASS) || defined(astFORTRAN77) ) - -/* Define a structure holding all data items that are global within the - error.c file. */ -typedef struct AstErrorGlobals { - -/* Reporting flag: delivery of message is supressed if zero. */ - int Reporting; - -/* Error context. */ - const char *Current_File; /* Current file name pointer */ - const char *Current_Routine; /* Current routine name pointer */ - int Current_Line; /* Current line number */ - int Foreign_Set; /* Have foreign values been set? */ - -/* Foreign functions */ - AstPutErrFun PutErr; /* Pointer to registered error handler */ - AstPutErrFunWrapper PutErr_Wrapper; /* Pointer to wrapper for error handler */ - -/* Un-reported message stack */ - char *Message_Stack[ AST__ERROR_MSTACK_SIZE ]; - int Mstack_Size; - -} AstErrorGlobals; - -/* Structure to hold the internal status variable, and the status - pointer for a single thread. */ -typedef struct AstStatusBlock { - int internal_status; - int *status_ptr; -} AstStatusBlock; - -#endif - - -/* Function Macros. */ -/* ================ */ - -#if defined(astCLASS) - -/* -*+ -* Name: -* astErrorBegin - -* Purpose: -* Begin a new error reporting context. - -* Type: -* Protected macro. - -* Synopsis: -* #include "error.h" -* astErrorBegin( AstErrorContext *context ); - -* Description: -* This macro starts a new error reporting context. It saves any -* existing error status in the supplied ontext structure, and then -* clears the status value. It also defers further error reporting. -* -* Each invocation of this macro should be followed (eventually) by a -* matching invocation of astErrorEnd. - -* Parameters: -* context -* Pointer to a structure in which to to storeinformation about the -* current error reporting context. This structure should be passed -* unchanged to the corresponding invocation of astErrorEnd. - -*- -*/ -#define astErrorBegin(context) {\ -\ -/* Save the original error status value. */ \ - (context)->status = astStatus; \ -\ -/* Save a flag indicating if the original error status was good. */ \ - (context)->ok = astOK; \ -\ -/* Switch off the immediate delivery of error messages, recording the \ - original value of the reporting flag. */ \ - (context)->reporting = astReporting( 0 ); \ -\ -/* Clear any existing error condition. */ \ - astClearStatus; \ -} - - -/* -*+ -* Name: -* astErrorEnd - -* Purpose: -* End an error reporting context. - -* Type: -* Protected macro. - -* Synopsis: -* #include "error.h" -* astErrorEnd( AstErrorContext *context ); - -* Description: -* This macro ends an error reporting context started using -* astErrorBegin. -* -* Each invocation of this macro should correspond to an earlier -* invocation of astErrorBegin. - -* Parameters: -* context -* Pointer to a structure holding information returned by the -* matching invocation of astErrorBegin. - -*- -*/ -#define astErrorEnd(context) { \ -\ -/* If an error condition existed when astErrorBegin was called, and \ - another error has since occurred, clear the deferred messages \ - reported during the error context without displaying them. */ \ - if( !(context)->ok && !astOK ) astClearStatus; \ -\ -/* Put the error reporting flag back to its original value. This will \ - have the effect of displaying any remaining errors reported within \ - the error context (they will already have been cleared if an error \ - condition existed at the start of the context). */ \ - astReporting( (context)->reporting ); \ -\ -/* If an error condition existed at the start of the context, re-instate \ - the original status value. */ \ - if( !(context)->ok ) astSetStatus( (context)->status ); \ -} -#endif - -/* Function prototypes. */ -/* ==================== */ - -int *astWatch_( int * ); -void astClearStatus_( int * ); -int *astGetStatusPtr_( void )__attribute__((pure)); -void astAt_( const char *, const char *, int, int, int * ); -void astSetPutErr_( AstPutErrFun, int * ); - -#if defined(astCLASS) || defined(astFORTRAN77) /* Protected only */ -void astSetPutErrWrapper_( AstPutErrFunWrapper, int * ); -int astReporting_( int, int * ); -void astError_( int, const char *, int *, ... )__attribute__((format(printf,2,4))); -void astBacktrace_( int * ); -void astGetAt_( const char **, const char **, int * ); - -#if defined(THREAD_SAFE) -void astInitErrorGlobals_( AstErrorGlobals * ); -#endif -#endif - -void astErrorPublic_( int, const char *, ... )__attribute__((format(printf,2,3))); - - - -/* Function interfaces. */ -/* ==================== */ -/* These wrap up the functions defined by this module to make them - easier to use. */ - -#define astWatch(status_ptr) astWatch_(status_ptr) -#define astGetStatusPtr astGetStatusPtr_() -#define astOK (astStatus==0) -#define astSetStatus(status_value) (astStatus=(status_value)) - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -#define astSetPutErr(fun) astSetPutErr_(fun,STATUS_PTR) - -#if defined(astCLASS) /* Protected */ - -#define astAt(routine,file,line) astAt_(routine,file,line,0,status) -#define astClearStatus astClearStatus_(status) -#define astStatus (*status) -#define astError astError_ -#define astReporting(report) astReporting_(report,status) -#define astBacktrace astBacktrace_(status) -#define astSetPutErrWrapper(fun) astSetPutErrWrapper_(fun,status) -#define astGetAt astGetAt_ - -#elif defined(astFORTRAN77) - -#define astAt(routine,file,line) astAt_(routine,file,line,1,STATUS) -#define astClearStatus astClearStatus_(status) -#define astStatus (*status) -#define astError astError_ -#define astReporting(report) astReporting_(report,status) -#define astSetPutErrWrapper(fun) astSetPutErrWrapper_(fun,status) - -#else - -#define astAt(routine,file,line) astAt_(routine,file,line,1,astGetStatusPtr) -#define astClearStatus astClearStatus_(astGetStatusPtr) -#define astStatus (*astGetStatusPtr) -#define astError astErrorPublic_ - -#endif - -#endif diff --git a/ast/f77.h.in b/ast/f77.h.in deleted file mode 100644 index 3a886fc..0000000 --- a/ast/f77.h.in +++ /dev/null @@ -1,1096 +0,0 @@ -/* -*+ -* Name: -* f77.h and cnf.h - -* Purpose: -* C - FORTRAN interace macros and prototypes - -* Language: -* C (part ANSI, part not) - -* Type of Module: -* C include file - -* Description: -* For historical reasons two files, F77.h and cnf.h are required -* but the have now been combined and for new code, only one is -* necessary. -* -* This file defines the macros needed to write C functions that are -* designed to be called from FORTRAN programs, and to do so in a -* portable way. Arguments are normally passed by reference from a -* FORTRAN program, and so the F77 macros arrange for a pointer to -* all arguments to be available. This requires no work on most -* machines, but will actually generate the pointers on a machine -* that passes FORTRAN arguments by value. - -* Notes: -* - Macros are provided to handle the conversion of logical data -* values between the way that FORTRAN represents a value and the -* way that C represents it. -* - Macros are provided to convert variables between the FORTRAN and -* C method of representing them. In most cases there is no -* conversion required, the macros just arrange for a pointer to -* the FORTRAN variable to be set appropriately. The possibility that -* FORTRAN and C might use different ways of representing integer -* and floating point values is considered remote, the macros are -* really only there for completeness and to assist in the automatic -* generation of C interfaces. -* - For character variables the macros convert between -* the FORTRAN method of representing them (fixed length, blank -* filled strings) and the C method (variable length, null -* terminated strings) using calls to the CNF functions. - -* Implementation Deficiencies: -* - The macros support the K&R style of function definition, but -* this file may not work with all K&R compilers as it contains -* "#if defined" statements. These could be replaced with #ifdef's -* if necessary. This has not been done as is would make the code -* less clear and the need for support for K&R sytle definitions -* should disappear as ANSI compilers become the default. - -* Copyright: -* Copyright (C) 1991, 1993 Science & Engineering Research Council. -* Copyright (C) 2006 Particle Physics and Astronomy Research Council. -* Copyright (C) 2007,2008 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 of -* the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be -* useful,but WITHOUT ANY WARRANTY; without even the implied -* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street,Fifth Floor, Boston, MA -* 02110-1301, USA - -* Authors: -* PMA: Peter Allan (Starlink, RAL) -* AJC: Alan Chipperfield (Starlink, RAL) -* TIMJ: Tim Jenness (JAC) -* PWD: Peter W. Draper (JAC, Durham University) -* {enter_new_authors_here} - -* History: -* 23-MAY-1991 (PMA): -* Original version. -* 19-JUN-1991 (PMA): -* Removed VMS versions of IM(EX)PORT_LOGICAL macros that tried -* to convert data representations. -* 24-JUN-1991 (PMA): -* Changed the names of IMPORT macros to GENPTR. -* Removed the EXPORT macros. -* 27-JUN-1991 (PMA): -* Modified DECstation specific stuff to allow use of the c89 -* compiler. -* 8-JUL-1991 (PMA): -* Added macros to call FORTRAN from C. -* 16-OCT-1991 (PMA): -* Remove type_ARRAY2 definitions. -* Remove the length argument from CHARACTER_ARRAY and the -* dimension specifier from GENPTR_type_ARRAY. -* Add extra brackets to F77_ISFALSE and F77_ISTRUE. -* 25-OCT-1991 (PMA): -* Changed "if defined(sun4)" to "if defined(sun)" -* 2-JUN-1992 (PMA): -* Changed "if defined(mips)" to "if defined(ultrix)" to prevent -* those definitions being used on a Silicon Graphics machine. -* 11-JUN-1992 (PMA): -* Changed "if defined(ultrix)" back to "if defined(mips)" so that -* it still works on OSF/1 on a DECstation. -* Add support for general non-ANSI compilers, but not basic K&R -* ones. -* 12-JUN-1992 (PMA): -* Change declaration of dummy scalar arguments to be const -* pointers. Change declaration of dummy array arguments to be -* const pointers. -* 5-JAN-1993 (PMA): -* Changed "if defined(mips)" so that it will recognise a -* DECstation running Ultrix or OSF/1, but not a Silicon Graphics -* workstation. -* Change the definition of F77_BYTE_TYPE to add "signed". -* Redefine this on VMS where signed is invalid syntax. -* Add new types of UBYTE and UWORD. -* 8-JAN-1993 (PMA): -* Fix bug in the definition of CHARACTER_RETURN_VALUE. There was -* an extraneous space. -* Add a macro F77_POINTER_TYPE and use it to define POINTER. -* 13-JAN-1993 (PMA): -* Start to add support for K&R function definitions. These are -* done on a per machine basis. -* 16-APR-1993 (PMA): -* Change the definition of F77_POINTER_TYPE from int to unsigned -* int. -* 7-MAY-1993 (PMA): -* Change from using a null comment as a token concatenation -* operator to using the internal macro _f77_x on non-ANSI -* systems. -* 10-MAY-1993 (PMA): -* Finish adding K&R support. This will form version 2.0 of F77. -* 10-MAY-1993 (PMA): -* Add support for Alpha OSF/1. -* 9-JUL-1993 (PMA): -* Add further POINTER macros: POINTER_ARRAY, -* GENPTR_POINTER_ARRAY, DECLARE_POINTER, DECLARE_POINTER_ARRAY, -* POINTER_ARG, POINTER_ARRAY_ARG, F77_POINTER_FUNCTION, -* KR_POINTER_ARRAY. -* 24-AUG-1993 (PMA): -* Add const to the VMS definitions of CHARACTER and CHARACTER_ARRAY. -* 3-NOV-1993 (PMA): -* Remove K&R stuff to a separate file. -* Released on Unix as version 2.0 of CNF. -* 11-NOV-1993 (PMA): -* Return to using the null comment to concatenate text on non-ANSI -* systems as _f77_x caused problems with the c89 -common flag on -* DECstations. -* 23-JAN-1996 (AJC): -* Add SUBROUTINE, type_FUNCTION, SUBROUTINE_ARG, -* type_FUNCTION_ARG, GENPTR_SUBROUTINE and GENPTR_type_FUNCTION -* required for passed subroutine and function name. -* 29-JAN-1996 (AJC): -* Add the dynamic CHARACTER_ macros -* and CHARACTER_ARG_TYPE -* 22-FEB-1996 (AJC): -* Add CHARACTER_RETURN_ARG -* 23-MAY-1996 (AJC): -* Add DECLARE_CHARACTER_ARRAY_DYN -* F77_CREATE_CHARACTER_ARRAY -* F77_CHARACTER_ARG_TYPE -* 14-JUN-1996 (AJC): -* Add DECLARE_LOGICAL_ARRAY_DYN -* F77_CREATE_LOGICAL_ARRAY -* 21-JUN-1996 (AJC): -* Add cast to _ARRAY_ARGs to allow multidimensional arrays -* 17-MAR-1998 (AJC): -* Add DECLARE, CREATE and FREE dynamic array macros for all types -* Changed CREATE_CHARACTER_ARRAY and CREATE_LOGICAL_ARRAY to use -* number of elements rather than dimensions. -* Add IMPORT, EXPORT and ASSOC macros -* 22-JUL-1998 (AJC): -* Combined F77.h and cnf.h -* 23-SEP-1998 (AJC): -* Input strings for cnf -> const char * -* Input int arrays for cnf -> const int * -* 4-NOV-1998 (AJC): -* Bring cnf prototypes in line with .c routines -* 8-FEB-1999 (AJC): -* Added cnf_mem stuff -* 9-FEB-1999 (AJC): -* Use cnf_cptr/fptr for IMPORT/EXPORT_POINTER -* 16-FEB-1999 (AJC): -* Added missing cnf_fptr prototype -* 23-JUN-1999 (AJC): -* Change cnf_name to cnfName -* and add macros for cnf_name -* 1-DEC-1999 (AJC): -* Add define cnf_free -* 7-JAN-2000 (AJC): -* Correct omission of F77_ASSOC_UBYTE_ARRAY -* Correct F77_EXPORT_UWORD_ARRAY -* 25-AUG-2005 (TIMJ): -* Add cnfInitRTL -* 23-FEB-2006 (TIMJ): -* Add cnfRealloc -* Use starMalloc rather than malloc in F77_CREATE_POINTER_ARRAY -* (since it needs to match what goes on in cnfFree) -* 21-JUN-2006 (PWD): -* Changed to use a different return type for REAL functions. This -* effects g77 under 64-bit, when the f2c bindings expect the return -* value of a REAL function to be a double, not a float. -* 25-SEP-2006 (PWD): -* Introduced F77_CREATE_IMPORT_CHARACTER. Match length of -* F77_CREATE_CHARACTER to result from cnfCref. -* 13-JUL-2007 (PWD): -* Parameterise the type of Fortran character string lengths. Can -* be long. -* 7-OCT-2008 (TIMJ): -* Initialise pointers. -* 11-MAY-2011 (DSB): -* Added F77_LOCK -* {enter_further_changes_here} -* - -* Bugs: -* {note_any_bugs_here} - -*- ------------------------------------------------------------------------------- -*/ -#if !defined(CNF_MACROS) -#define CNF_MACROS - -#include -#include -/* This initial sections defines values for all macros. These are the */ -/* values that are generally appropriate to an ANSI C compiler on Unix. */ -/* For macros that have different values on other systems, the macros */ -/* should be undefined and then redefined in the system specific sections. */ -/* At the end of this section, some macros are redefined if the compiler */ -/* is non-ANSI. */ - -#if defined(__STDC__) || defined(VMS) -#define CNF_CONST const -#else -#define CNF_CONST -#endif - -/* ----- Macros common to calling C from FORTRAN and FORTRAN from C ---- */ - - -/* --- External Names --- */ - -/* Macro to define the name of a Fortran routine or common block. This */ -/* ends in an underscore on many Unix systems. */ - -#define F77_EXTERNAL_NAME(X) X ## _ - - -/* --- Logical Values --- */ - -/* Define the values that are used to represent the logical values TRUE */ -/* and FALSE in Fortran. */ - -#define F77_TRUE 1 -#define F77_FALSE 0 - -/* Define macros that evaluate to C logical values, given a FORTRAN */ -/* logical value. */ - -#define F77_ISTRUE(X) ( X ) -#define F77_ISFALSE(X) ( !( X ) ) - - -/* --- Common Blocks --- */ - -/* Macros used in referring to FORTRAN common blocks. */ - -#define F77_BLANK_COMMON @BLANK_COMMON_SYMBOL@ -#define F77_NAMED_COMMON(B) F77_EXTERNAL_NAME(B) - - - -/* ------------------ Calling C from FORTRAN --------------------------- */ - - -/* --- Data Types --- */ - -/* Define macros for all the Fortran data types (except COMPLEX, which is */ -/* not handled by this package). */ - -#define F77_INTEGER_TYPE int -#define F77_REAL_TYPE float -#define F77_REAL_FUNCTION_TYPE @REAL_FUNCTION_TYPE@ -#define F77_DOUBLE_TYPE double -#define F77_LOGICAL_TYPE int -#define F77_CHARACTER_TYPE char -#define F77_BYTE_TYPE signed char -#define F77_WORD_TYPE short int -#define F77_UBYTE_TYPE unsigned char -#define F77_UWORD_TYPE unsigned short int - -/* Define macros for the type of a CHARACTER and CHARACTER_ARRAY argument */ -#define F77_CHARACTER_ARG_TYPE char -#define F77_CHARACTER_ARRAY_ARG_TYPE char - -/* Define a macro to use when passing arguments that STARLINK FORTRAN */ -/* treats as a pointer. From the point of view of C, this type should be */ -/* (void *), but it is declared as type unsigned int as we actually pass */ -/* an INTEGER from the FORTRAN routine. The distinction is important for */ -/* architectures where the size of an INTEGER is not the same as the size */ -/* of a pointer. */ - -#define F77_POINTER_TYPE unsigned int - - -/* --- Subroutine Names --- */ - -/* This declares that the C function returns a value of void. */ - -#define F77_SUBROUTINE(X) void F77_EXTERNAL_NAME(X) - - -/* --- Function Names --- */ - -/* Macros to define the types and names of functions that return values. */ -/* Due the the different ways that function return values could be */ -/* implemented, it is better not to use functions, but to stick to using */ -/* subroutines. */ - -/* Character functions are implemented, but in a way that cannot be */ -/* guaranteed to be portable although it will work on VMS, SunOS, Ultrix */ -/* and DEC OSF/1. It would be better to return the character value as a */ -/* subroutine argument where possible, rather than use a character */ -/* function. */ - -#define F77_INTEGER_FUNCTION(X) F77_INTEGER_TYPE F77_EXTERNAL_NAME(X) -#define F77_REAL_FUNCTION(X) F77_REAL_FUNCTION_TYPE F77_EXTERNAL_NAME(X) -#define F77_DOUBLE_FUNCTION(X) F77_DOUBLE_TYPE F77_EXTERNAL_NAME(X) -#define F77_LOGICAL_FUNCTION(X) F77_LOGICAL_TYPE F77_EXTERNAL_NAME(X) -#define F77_CHARACTER_FUNCTION(X) void F77_EXTERNAL_NAME(X) -#define F77_BYTE_FUNCTION(X) F77_BYTE_TYPE F77_EXTERNAL_NAME(X) -#define F77_WORD_FUNCTION(X) F77_WORD_TYPE F77_EXTERNAL_NAME(X) -#define F77_UBYTE_FUNCTION(X) F77_UBYTE_TYPE F77_EXTERNAL_NAME(X) -#define F77_UWORD_FUNCTION(X) F77_UWORD_TYPE F77_EXTERNAL_NAME(X) -#define F77_POINTER_FUNCTION(X) F77_POINTER_TYPE F77_EXTERNAL_NAME(X) - - -/* --- Character return value for a function --- */ - -#define CHARACTER_RETURN_VALUE(X) CHARACTER(X) TRAIL(X) -#define CHARACTER_RETURN_ARG(X) CHARACTER_ARG(X) TRAIL_ARG(X) - -/* --- Dummy Arguments --- */ - -/* Macros for defining subroutine arguments. All these macros take a */ -/* single argument; the name of the parameter. On most systems, a numeric */ -/* argument is passed as a pointer. */ - -#define INTEGER(X) F77_INTEGER_TYPE *CNF_CONST X -#define REAL(X) F77_REAL_TYPE *CNF_CONST X -#define DOUBLE(X) F77_DOUBLE_TYPE *CNF_CONST X -#define LOGICAL(X) F77_LOGICAL_TYPE *CNF_CONST X -#define BYTE(X) F77_BYTE_TYPE *CNF_CONST X -#define WORD(X) F77_WORD_TYPE *CNF_CONST X -#define UBYTE(X) F77_UBYTE_TYPE *CNF_CONST X -#define UWORD(X) F77_UWORD_TYPE *CNF_CONST X - -/* Pointer arguments. Define a pointer type for passing pointer values */ -/* between subroutines. */ - -#define POINTER(X) F77_POINTER_TYPE *CNF_CONST X - -/* EXTERNAL arguments. Define a passed subroutine or function name */ -#define SUBROUTINE(X) void (*X)() -#define INTEGER_FUNCTION(X) F77_INTEGER_TYPE (*X)() -#define REAL_FUNCTION(X) F77_REAL_TYPE (*X)() -#define DOUBLE_FUNCTION(X) F77_DOUBLE_TYPE (*X)() -#define LOGICAL_FUNCTION(X) F77_LOGICAL_TYPE (*X)() -#define CHARACTER_FUNCTION(X) F77_CHARACTER_TYPE (*X)() -#define BYTE_FUNCTION(X) F77_BYTE_TYPE (*X)() -#define WORD_FUNCTION(X) F77_WORD_TYPE (*X)() -#define UBYTE_FUNCTION(X) F77_UBYTE_TYPE (*X)() -#define UWORD_FUNCTION(X) F77_UWORD_TYPE (*X)() -#define POINTER_FUNCTION(X) F77_POINTER_TYPE (*X)() - -/* Array arguments. */ - -#define INTEGER_ARRAY(X) F77_INTEGER_TYPE *CNF_CONST X -#define REAL_ARRAY(X) F77_REAL_TYPE *CNF_CONST X -#define DOUBLE_ARRAY(X) F77_DOUBLE_TYPE *CNF_CONST X -#define LOGICAL_ARRAY(X) F77_LOGICAL_TYPE *CNF_CONST X -#define BYTE_ARRAY(X) F77_BYTE_TYPE *CNF_CONST X -#define WORD_ARRAY(X) F77_WORD_TYPE *CNF_CONST X -#define UBYTE_ARRAY(X) F77_UBYTE_TYPE *CNF_CONST X -#define UWORD_ARRAY(X) F77_UWORD_TYPE *CNF_CONST X - -#define POINTER_ARRAY(X) F77_POINTER_TYPE *CNF_CONST X - -/* Macros to handle character arguments. */ - -/* Character arguments can be passed in many ways. The purpose of these */ -/* macros and the GENPTR_CHARACTER macro (defined in the next section) is */ -/* to generate a pointer to a character variable called ARG and an integer */ -/* ARG_length containing the length of ARG. If these two variables are */ -/* available directly from the argument list of the routine, then the */ -/* GENPTR_CHARACTER macro is null, otherwise it works on intermediate */ -/* variables. */ - -#define CHARACTER(X) F77_CHARACTER_TYPE *CNF_CONST X -#define TRAIL(X) ,@TRAIL_TYPE@ X ## _length -#define CHARACTER_ARRAY(X) F77_CHARACTER_TYPE *CNF_CONST X - - -/* --- Getting Pointers to Arguments --- */ - -/* Macros that ensure that a pointer to each argument is available for the */ -/* programmer to use. Usually this means that these macros are null. On */ -/* VMS, a pointer to a character variable has to be generated. If a */ -/* particular machine were to pass arguments by reference, rather than by */ -/* value, then these macros would construct the appropriate pointers. */ - -#define GENPTR_INTEGER(X) -#define GENPTR_REAL(X) -#define GENPTR_DOUBLE(X) -#define GENPTR_CHARACTER(X) -#define GENPTR_LOGICAL(X) -#define GENPTR_BYTE(X) -#define GENPTR_WORD(X) -#define GENPTR_UBYTE(X) -#define GENPTR_UWORD(X) -#define GENPTR_POINTER(X) - -#define GENPTR_INTEGER_ARRAY(X) -#define GENPTR_REAL_ARRAY(X) -#define GENPTR_DOUBLE_ARRAY(X) -#define GENPTR_CHARACTER_ARRAY(X) -#define GENPTR_LOGICAL_ARRAY(X) -#define GENPTR_BYTE_ARRAY(X) -#define GENPTR_WORD_ARRAY(X) -#define GENPTR_UBYTE_ARRAY(X) -#define GENPTR_UWORD_ARRAY(X) -#define GENPTR_POINTER_ARRAY(X) - -#define GENPTR_SUBROUTINE(X) -#define GENPTR_INTEGER_FUNCTION(X) -#define GENPTR_REAL_FUNCTION(X) -#define GENPTR_DOUBLE_FUNCTION(X) -#define GENPTR_CHARACTER_FUNCTION(X) -#define GENPTR_LOGICAL_FUNCTION(X) -#define GENPTR_BYTE_FUNCTION(X) -#define GENPTR_WORD_FUNCTION(X) -#define GENPTR_UBYTE_FUNCTION(X) -#define GENPTR_UWORD_FUNCTION(X) -#define GENPTR_POINTER_FUNCTION(X) - - - -/* ------------------ Calling FORTRAN from C --------------------------- */ - - -/* --- Declare variables --- */ - -#define DECLARE_INTEGER(X) F77_INTEGER_TYPE X -#define DECLARE_REAL(X) F77_REAL_TYPE X -#define DECLARE_DOUBLE(X) F77_DOUBLE_TYPE X -#define DECLARE_LOGICAL(X) F77_LOGICAL_TYPE X -#define DECLARE_BYTE(X) F77_BYTE_TYPE X -#define DECLARE_WORD(X) F77_WORD_TYPE X -#define DECLARE_UBYTE(X) F77_UBYTE_TYPE X -#define DECLARE_UWORD(X) F77_UWORD_TYPE X - -#define DECLARE_POINTER(X) F77_POINTER_TYPE X - -#define DECLARE_CHARACTER(X,L) F77_CHARACTER_TYPE X[L]; \ - const int X##_length = L - - -/* --- Declare arrays --- */ - -#define DECLARE_INTEGER_ARRAY(X,D) F77_INTEGER_TYPE X[D] -#define DECLARE_REAL_ARRAY(X,D) F77_REAL_TYPE X[D] -#define DECLARE_DOUBLE_ARRAY(X,D) F77_DOUBLE_TYPE X[D] -#define DECLARE_LOGICAL_ARRAY(X,D) F77_LOGICAL_TYPE X[D] -#define DECLARE_BYTE_ARRAY(X,D) F77_BYTE_TYPE X[D] -#define DECLARE_WORD_ARRAY(X,D) F77_WORD_TYPE X[D] -#define DECLARE_UBYTE_ARRAY(X,D) F77_UBYTE_TYPE X[D] -#define DECLARE_UWORD_ARRAY(X,D) F77_UWORD_TYPE X[D] -#define DECLARE_POINTER_ARRAY(X,D) F77_POINTER_TYPE X[D] -#define DECLARE_CHARACTER_ARRAY(X,L,D) F77_CHARACTER_TYPE X[D][L]; \ - const int X##_length = L - -/* --- Declare and construct dynamic CHARACTER arguments --- */ -#define DECLARE_CHARACTER_DYN(X) F77_CHARACTER_TYPE *X = NULL;\ - int X##_length = 0 -#define F77_CREATE_CHARACTER(X,L) X=cnfCref(L);\ - X##_length = (L>0?L:1) - -/* Declare Dynamic Fortran arrays */ -#define DECLARE_INTEGER_ARRAY_DYN(X) F77_INTEGER_TYPE *X = NULL -#define DECLARE_REAL_ARRAY_DYN(X) F77_REAL_TYPE *X = NULL -#define DECLARE_DOUBLE_ARRAY_DYN(X) F77_DOUBLE_TYPE *X = NULL -#define DECLARE_LOGICAL_ARRAY_DYN(X) F77_LOGICAL_TYPE *X = NULL -#define DECLARE_BYTE_ARRAY_DYN(X) F77_BYTE_TYPE *X = NULL -#define DECLARE_WORD_ARRAY_DYN(X) F77_WORD_TYPE *X = NULL -#define DECLARE_UBYTE_ARRAY_DYN(X) F77_UBYTE_TYPE *X = NULL -#define DECLARE_UWORD_ARRAY_DYN(X) F77_UWORD_TYPE *X = NULL -#define DECLARE_POINTER_ARRAY_DYN(X) F77_POINTER_TYPE *X = NULL -#define DECLARE_CHARACTER_ARRAY_DYN(X) F77_CHARACTER_TYPE *X = NULL;\ - int X##_length = 0 - -/* Create arrays dynamic Fortran arrays for those types which require */ -/* Separate space for Fortran and C arrays */ -/* Character and logical are already defined */ -/* For most types there is nothing to do */ -#define F77_CREATE_CHARACTER_ARRAY(X,L,N) \ - {int f77dims[1];f77dims[0]=N;X=cnfCrefa(L,1,f77dims);X##_length=L;} -#define F77_CREATE_CHARACTER_ARRAY_M(X,L,N,D) X=cnfCrefa(L,N,D);\ - X##_length = L -#define F77_CREATE_LOGICAL_ARRAY(X,N) \ - {int f77dims[1];f77dims[0]=N;X=cnfCrela(1,f77dims);} -#define F77_CREATE_LOGICAL_ARRAY_M(X,N,D) X=cnfCrela(N,D) -#define F77_CREATE_INTEGER_ARRAY(X,N) -#define F77_CREATE_REAL_ARRAY(X,N) -#define F77_CREATE_DOUBLE_ARRAY(X,N) -#define F77_CREATE_BYTE_ARRAY(X,N) -#define F77_CREATE_UBYTE_ARRAY(X,N) -#define F77_CREATE_WORD_ARRAY(X,N) -#define F77_CREATE_UWORD_ARRAY(X,N) -#define F77_CREATE_POINTER_ARRAY(X,N)\ - X=(F77_POINTER_TYPE *) malloc(N*sizeof(F77_POINTER_TYPE)) - -/* Associate Fortran arrays with C arrays */ -/* These macros ensure that there is space somewhere for the Fortran */ -/* array. They are complemetary to the CREATE_type_ARRAY macros */ -#define F77_ASSOC_CHARACTER_ARRAY(F,C) -#define F77_ASSOC_LOGICAL_ARRAY(F,C) -#define F77_ASSOC_INTEGER_ARRAY(F,C) F=C -#define F77_ASSOC_REAL_ARRAY(F,C) F=C -#define F77_ASSOC_DOUBLE_ARRAY(F,C) F=C -#define F77_ASSOC_BYTE_ARRAY(F,C) F=C -#define F77_ASSOC_UBYTE_ARRAY(F,C) F=C -#define F77_ASSOC_WORD_ARRAY(F,C) F=C -#define F77_ASSOC_UWORD_ARRAY(F,C) F=C -#define F77_ASSOC_POINTER_ARRAY(F,C) - -/* Free created dynamic arrays */ -/* Character and logical are already defined */ -/* For most types there is nothing to do */ -#define F77_FREE_INTEGER(X) -#define F77_FREE_REAL(X) -#define F77_FREE_DOUBLE(X) -#define F77_FREE_BYTE(X) -#define F77_FREE_UBYTE(X) -#define F77_FREE_WORD(X) -#define F77_FREE_UWORD(X) -#define F77_FREE_POINTER(X) cnfFree((void *)X); -#define F77_FREE_CHARACTER(X) cnfFreef( X ) -#define F77_FREE_LOGICAL(X) cnfFree( (char *)X ) - -/* --- IMPORT and EXPORT of values --- */ -/* Export C variables to Fortran variables */ -#define F77_EXPORT_CHARACTER(C,F,L) cnfExprt(C,F,L) -#define F77_EXPORT_DOUBLE(C,F) F=C -#define F77_EXPORT_INTEGER(C,F) F=C -#define F77_EXPORT_LOGICAL(C,F) F=C?F77_TRUE:F77_FALSE -#define F77_EXPORT_REAL(C,F) F=C -#define F77_EXPORT_BYTE(C,F) F=C -#define F77_EXPORT_WORD(C,F) F=C -#define F77_EXPORT_UBYTE(C,F) F=C -#define F77_EXPORT_UWORD(C,F) F=C -#define F77_EXPORT_POINTER(C,F) F=cnfFptr(C) -#define F77_EXPORT_LOCATOR(C,F) cnfExpch(C,F,DAT__SZLOC) - -/* Allow for character strings to be NULL, protects strlen. Note this - * does not allow lengths to differ. */ -#define F77_CREATE_EXPORT_CHARACTER(C,F) \ - if (C) { \ - F77_CREATE_CHARACTER(F,strlen(C)); \ - F77_EXPORT_CHARACTER(C,F,F##_length); \ - } else { \ - F77_CREATE_CHARACTER(F,1); \ - F77_EXPORT_CHARACTER(" ",F,F##_length); \ - } - -/* Export C arrays to Fortran */ -/* Arrays are assumed to be 1-d so just the number of elements is given */ -/* This may be OK for n-d arrays also */ -/* CHARACTER arrays may be represented in C as arrays of arrays of char or */ -/* as arrays of pointers to char (the _P variant) */ -#define F77_EXPORT_CHARACTER_ARRAY(C,LC,F,LF,N) \ - {int f77dims[1];f77dims[0]=N;cnfExprta(C,LC,F,LF,1,f77dims);} -#define F77_EXPORT_CHARACTER_ARRAY_P(C,F,LF,N) \ - {int f77dims[1];f77dims[0]=N;cnfExprtap(C,F,LF,1,f77dims);} -#define F77_EXPORT_DOUBLE_ARRAY(C,F,N) F=(F77_DOUBLE_TYPE *)C -#define F77_EXPORT_INTEGER_ARRAY(C,F,N) F=(F77_INTEGER_TYPE *)C -#define F77_EXPORT_LOGICAL_ARRAY(C,F,N) \ - {int f77dims[1];f77dims[0]=N;cnfExpla(C,F,1,f77dims);} -#define F77_EXPORT_REAL_ARRAY(C,F,N) F=(F77_REAL_TYPE *)C -#define F77_EXPORT_BYTE_ARRAY(C,F,N) F=(F77_BYTE_TYPE *)C -#define F77_EXPORT_WORD_ARRAY(C,F,N) F=(F77_WORD_TYPE *)C -#define F77_EXPORT_UBYTE_ARRAY(C,F,N) F=(F77_UBYTE_TYPE *)C -#define F77_EXPORT_UWORD_ARRAY(C,F,N) F=(F77_UWORD_TYPE * )C -#define F77_EXPORT_POINTER_ARRAY(C,F,N) \ - {int f77i;for (f77i=0;f77i -#endif - - -#undef F77_CHARACTER_ARG_TYPE -#define F77_CHARACTER_ARG_TYPE struct dsc$descriptor_s -#undef F77_CHARACTER_ARRAY_ARG_TYPE -#define F77_CHARACTER_ARRAY_ARG_TYPE struct dsc$descriptor_a -#undef CHARACTER -#define CHARACTER(X) F77_CHARACTER_ARG_TYPE *CNF_CONST X/**/_arg -#undef TRAIL -#define TRAIL(X) -#undef CHARACTER_ARRAY -#define CHARACTER_ARRAY(X) F77_CHARACTER_ARRAY_ARG_TYPE *CNF_CONST X/**/_arg -#undef GENPTR_CHARACTER -#define GENPTR_CHARACTER(X) \ - F77_CHARACTER_TYPE *X = X/**/_arg->dsc$a_pointer; \ - int X/**/_length = X/**/_arg->dsc$w_length; -#undef GENPTR_CHARACTER_ARRAY -#define GENPTR_CHARACTER_ARRAY(X) GENPTR_CHARACTER(X) - - -/* --- Logical Values --- */ - -#undef F77_TRUE -#define F77_TRUE -1 -#undef F77_ISTRUE -#define F77_ISTRUE(X) ( (X)&1 ) -#undef F77_ISFALSE -#define F77_ISFALSE(X) ( ! ( (X)&1 ) ) - - -/* --- Common Blocks --- */ - -#undef F77_BLANK_COMMON -#define F77_BLANK_COMMON $BLANK - - -/* --- Declare Variables --- */ - -#undef DECLARE_CHARACTER -#define DECLARE_CHARACTER(X,L) \ - F77_CHARACTER_TYPE X[L]; const int X/**/_length = L; \ - F77_CHARACTER_ARG_TYPE X/**/_descr = \ - { L, DSC$K_DTYPE_T, DSC$K_CLASS_S, X }; \ - F77_CHARACTER_ARG_TYPE *X/**/_arg = &X/**/_descr -#undef DECLARE_CHARACTER_ARRAY -#define DECLARE_CHARACTER_ARRAY(X,L,D) \ - F77_CHARACTER_TYPE X[D][L]; const int X/**/_length = L; \ - F77_CHARACTER_ARRAY_ARG_TYPE X/**/_descr = \ - { L, DSC$K_DTYPE_T, DSC$K_CLASS_S, X }; \ - F77_CHARACTER_ARRAY_ARG_TYPE *X/**/_arg = &X/**/_descr - - -/* --- The dynamic allocation of character arguments --- */ -#undef DECLARE_CHARACTER_DYN -#define DECLARE_CHARACTER_DYN(X) int X/**/_length;\ - F77_CHARACTER_ARG_TYPE *X/**/_arg;\ - F77_CHARACTER_TYPE *X -#undef DECLARE_CHARACTER_ARRAY_DYN -#define DECLARE_CHARACTER_ARRAY_DYN(X) int X/**/_length;\ - F77_CHARACTER_ARRAY_ARG_TYPE *X/**/_arg;\ - F77_CHARACTER_TYPE *X -#undef F77_CREATE_CHARACTER -#define F77_CREATE_CHARACTER(X,L) X/**/_arg = cnfCref(L);\ - X = X/**/_arg->dsc$a_pointer; \ - X/**/_length = X/**/_arg->dsc$w_length -#undef F77_CREATE_CHARACTER_ARRAY -#define F77_CREATE_CHARACTER_ARRAY(X,L,N) \ - {int f77dims[1];f77dims[0]=N;X/**/_arg=cnfCrefa(L,1,f77dims);X/**/_length=L;} -#define F77_CREATE_CHARACTER_ARRAY_M(X,L,N,D) X/**/_arg = cnfCrefa(L,N,D);\ - X = X/**/_arg->dsc$a_pointer; \ - X/**/_length = X/**/_arg->dsc$w_length -#undef F77_FREE_CHARACTER -#define F77_FREE_CHARACTER(X) cnfFreef( X/**/_arg ) - -/* --- Pass arguments to a FORTRAN routine --- */ - -#undef CHARACTER_ARG -#define CHARACTER_ARG(X) X/**/_arg -#undef CHARACTER_ARRAY_ARG -#define CHARACTER_ARRAY_ARG(X) X/**/_arg -#undef TRAIL_ARG -#define TRAIL_ARG(X) - -#endif /* VMS */ - -/* ----------------------------------------------------------------------- */ - -/*-------------------------- -| DECstation Ultrix (cc) | -| DECstation Ultrix (c89) | -| DECstation OSF/1 | -| Alpha OSF/1 | - --------------------------*/ - -/* Do this complicated set of definitions as a single #if cannot be */ -/* continued across multiple lines. */ - -#if defined(mips) && defined(ultrix) -#define _dec_unix 1 -#endif -#if defined(__mips) && defined(__ultrix) -#define _dec_unix 1 -#endif -#if defined(__mips__) && defined(__osf__) -#define _dec_unix 1 -#endif -#if defined(__alpha) && defined(__osf__) -#define _dec_unix 1 -#endif - -#if _dec_unix - -/* The macros for Ultrix are the same as the standard ones except for ones */ -/* dealing with logical values. The ANSI definitions work with the c89 */ -/* compiler, and the non ANSI definitions work with the cc compiler. */ -/* The same applies to DEC OSF/1, except that its cc compiler is ANSI */ -/* compliant. */ - - -/* --- Logical Values --- */ - -/* Redefine macros that evaluate to a C logical value, given a FORTRAN */ -/* logical value. These definitions are only valid when used with the DEC */ -/* FORTRAN for RISC compiler. If you are using the earlier FORTRAN for */ -/* RISC compiler from MIPS, then these macros should be deleted. */ - -#undef F77_TRUE -#define F77_TRUE -1 -#undef F77_ISTRUE -#define F77_ISTRUE(X) ( (X)&1 ) -#undef F77_ISFALSE -#define F77_ISFALSE(X) ( ! ( (X)&1 ) ) - - -#endif /* DEC Unix */ - -/* -*+ -* Name: -* cnf.h - -* Purpose: -* Function prototypes for cnf routines - -* Language: -* ANSI C - -* Type of Module: -* C include file - -* Description: -* These are the prototype definitions for the functions in the CNF -* library. They are used used in mixing C and FORTRAN programs. - -* Copyright: -* Copyright (C) 1991 Science & Engineering Research Council - -* Authors: -* PMA: Peter Allan (Starlink, RAL) -* AJC: Alan Chipperfield (Starlink, RAL) -* {enter_new_authors_here} - -* History: -* 23-MAY-1991 (PMA): -* Original version. -* 12-JAN-1996 (AJC): -* Add cnf_cref and cnf_freef -* 14-JUN-1996 (AJC): -* Add cnf_crefa, imprta, exprta -* crela, impla, expla -* 18-JUL-1996 (AJC): -* Add impch and expch -* 17-MAR-1998 (AJC): -* Add imprtap and exprtap -* {enter_changes_here} - -* Bugs: -* {note_any_bugs_here} - -*- ------------------------------------------------------------------------------- -*/ -void cnfInitRTL( int, char** ); -void *cnfCalloc( size_t, size_t ); -void cnfCopyf( const char *source_f, int source_len, char *dest_f, - int dest_len ); -void *cnfCptr( F77_POINTER_TYPE ); -char *cnfCreat( int length ); -F77_CHARACTER_ARG_TYPE *cnfCref( int length ); -F77_CHARACTER_ARG_TYPE *cnfCrefa( int length, int ndims, const int *dims ); -char *cnfCreib( const char *source_f, int source_len ); -char *cnfCreim( const char *source_f, int source_len ); -F77_LOGICAL_TYPE *cnfCrela( int ndims, const int *dims ); -void cnfExpch( const char *source_c, char *dest_f, int nchars ); -void cnfExpla( const int *source_c, F77_LOGICAL_TYPE *dest_f, int ndims, - const int *dims ); -void cnfExpn( const char *source_c, int max, char *dest_f, int dest_len ); -void cnfExprt( const char *source_c, char *dest_f, int dest_len ); -void cnfExprta( const char *source_c, int source_len, char *dest_f, - int dest_len, int ndims, const int *dims ); -void cnfExprtap( char *const *source_c, char *dest_f, int dest_len, - int ndims, const int *dims ); -F77_POINTER_TYPE cnfFptr( void *cpointer ); -void cnfFree( void * ); -void cnfFreef( F77_CHARACTER_ARG_TYPE *temp ); -void cnfImpb( const char *source_f, int source_len, char *dest_c ); -void cnfImpbn( const char *source_f, int source_len, int max, char *dest_c ); -void cnfImpch( const char *source_f, int nchars, char *dest_c ); -void cnfImpla( const F77_LOGICAL_TYPE *source_f, int *dest_c, - int ndims, const int *dims ); -void cnfImpn( const char *source_f, int source_len, int max, char *dest_c ); -void cnfImprt( const char *source_f, int source_len, char *dest_c ); -void cnfImprta( const char *source_f, int source_len, char *dest_c, - int dest_len, int ndims, const int *dims ); -void cnfImprtap( const char *source_f, int source_len, char *const *dest_c, - int dest_len, int ndims, const int *dims ); -int cnfLenc( const char *source_c ); -int cnfLenf( const char *source_f, int source_len ); -void *cnfMalloc( size_t ); -void *cnfRealloc( void *, size_t ); -int cnfRegp( void * ); -void cnfUregp( void * ); -void cnfLock( void ); -void cnfUnlock( void ); -#endif - -#ifndef CNF_OLD_DEFINED -#define CNF_OLD_DEFINED -/* Define old names to be new names */ -#define cnf_calloc cnfCalloc -#define cnf_copyf cnfCopyf -#define cnf_cptr cnfCptr -#define cnf_creat cnfCreat -#define cnf_cref cnfCref -#define cnf_crefa cnfCrefa -#define cnf_creib cnfCreib -#define cnf_creim cnfCreim -#define cnf_crela cnfCrela -#define cnf_expch cnfExpch -#define cnf_expla cnfExpla -#define cnf_expn cnfExpn -#define cnf_exprt cnfExprt -#define cnf_exprta cnfExprta -#define cnf_exprtap cnfExprtap -#define cnf_fptr cnfFptr -#define cnf_free cnfFree -#define cnf_freef cnfFreef -#define cnf_impb cnfImpb -#define cnf_impbn cnfImpbn -#define cnf_impch cnfImpch -#define cnf_impla cnfImpla -#define cnf_impn cnfImpn -#define cnf_imprt cnfImprt -#define cnf_imprta cnfImprta -#define cnf_imprtap cnfImprtap -#define cnf_lenc cnfLenc -#define cnf_lenf cnfLenf -#define cnf_malloc cnfMalloc -#define cnf_regp cnfRegp -#define cnf_uregp cnfUregp - -#endif /* CNF_MACROS */ diff --git a/ast/fbox.c b/ast/fbox.c deleted file mode 100644 index 8dff34f..0000000 --- a/ast/fbox.c +++ /dev/null @@ -1,110 +0,0 @@ -/* -*+ -* Name: -* fbox.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Box class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Box class. - -* Routines Defined: -* AST_ISABOX -* AST_BOX - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-MAR-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "box.h" /* C interface to the Box class */ - -F77_LOGICAL_FUNCTION(ast_isabox)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISABOX", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsABox( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_box)( INTEGER(FRAME), - INTEGER(FORM), - DOUBLE_ARRAY(POINT1), - DOUBLE_ARRAY(POINT2), - INTEGER(UNC), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_INTEGER(FORM) - GENPTR_DOUBLE_ARRAY(POINT1) - GENPTR_DOUBLE_ARRAY(POINT2) - GENPTR_INTEGER(UNC) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_BOX", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - - RESULT = astP2I( astBox( astI2P( *FRAME ), *FORM, POINT1, POINT2, - astI2P( *UNC ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fchannel.c b/ast/fchannel.c deleted file mode 100644 index 9f70315..0000000 --- a/ast/fchannel.c +++ /dev/null @@ -1,473 +0,0 @@ -/* -*+ -* Name: -* fchannel.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Channel class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Channel class. - -* Routines Defined: -* AST_CHANNEL -* AST_ISACHANNEL -* AST_READ -* AST_WRITE - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 6-SEP-1996 (RFWS): -* Original version. -* 12-DEC-1996 (RFWS): -* Added SOURCE and SINK arguments to AST_CHANNEL. -* 13-NOV-2003 (DSB): -* Made SourceWrap and SinkWrap into protected functions rather -* than private functions, so that they can be used in fxmlchan.c -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "channel.h" /* C interface to the Channel class */ - -#include - -/* Module Variables. */ -/* ================= */ -static char *line_in = NULL; /* Pointer to incoming line of text */ -static const char *line_out = NULL; /* Pointer to outgoing line of text */ - -/* Prototypes for external functions. */ -/* ================================== */ -/* This is the null function defined by the FORTRAN interface in fobject.c. */ -F77_SUBROUTINE(ast_null)( void ); - -/* Source and sink function interfaces. */ -/* ==================================== */ -/* These functions are concerned with allowing FORTRAN implementations - of Channel source and sink functions to be passed to the Channel - class and invoked when necessary by C code in the main class - implementation. All FORTRAN-specific aspects of this interface are - encapsulated here. */ -F77_SUBROUTINE(ast_getline)( CHARACTER(LINE), - INTEGER(L), - INTEGER(STATUS) - TRAIL(LINE) ) { -/* -f++ -* Name: -* AST_GETLINE - -* Purpose: -* Obtain text to be written by a Channel sink routine. - -* Type: -* Public function. - -* Synopsis: -* CALL AST_GETLINE( LINE, L, STATUS ) - -* Description: -* This routine should only be used when implementing a routine -* which will be passed as the SINK argument to AST_CHANNEL. It -* should be used to obtain (from the AST library) each line of -* text which is to be written to the external data sink. One such -* line should be obtained in this way for each invocation of the -* sink routine. - -* Parameters: -* LINE = CHARACTER * ( * ) (Returned) -* The line of text to be written. Depending on the length of -* character variable supplied, the returned text may be -* truncated if necessary. Note, however, that it will not be -* padded with blanks in order to fill this variable. -* L = INTEGER (Returned) -* The number of characters returned, which may be zero. Note -* that characters beyond the L'th character in the LINE -* variable are not modified and may therefore contain junk. -* STATUS = INTEGER (Given and Returned) -* The global status. - -* Notes: -* - This routine is only available in the Fortran interface to the -* AST library. -f-- -*/ - -/* Argument Pointers: */ - GENPTR_CHARACTER(LINE) - GENPTR_INTEGER(L) - -/* Local Variables: */ - int i; /* Loop counter for characters */ - -/* Set the error context and watch the STATUS value. */ - astAt( "AST_GETLINE", NULL, 0 ); - astWatchSTATUS( - -/* Initialise the returned string length. */ - *L = 0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If there is no outgoing line ready (e.g. if this routine has been - called at an inappropriate point), we simply return - nothing. Otherwise, loop to copy the text into the character - argument supplied, ensuring that its length is not exceeded. */ - if ( line_out ) { - for ( i = 0; line_out[ i ] && ( i < LINE_length ); i++ ) { - LINE[ i ] = line_out[ i ]; - } - -/* Return the number of characters copied. */ - *L = i; - } - ) -} - -F77_SUBROUTINE(ast_putline)( CHARACTER(LINE), - INTEGER(L), - INTEGER(STATUS) - TRAIL(LINE) ) { -/* -f++ -* Name: -* AST_PUTLINE - -* Purpose: -* Store a text line read by a Channel source routine. - -* Type: -* Public function. - -* Synopsis: -* CALL AST_PUTLINE( LINE, L, STATUS ) - -* Description: -* This routine should only be used when implementing a routine -* which will be passed as the SOURCE argument to AST_CHANNEL. It -* should be used to pass back (to the AST library) each line of -* text read from the external data source. One such line should be -* passed back in this way for each invocation of the source -* routine. - -* Parameters: -* LINE = CHARACTER * ( * ) (Given) -* A character string containing the line of input text which -* has been read. -* L = INTEGER (Given) -* The number of characters in the input line, which may be -* zero. If there is no more input available (e.g. an end of -* file has been reached), this value should be set negative and -* this will terminate the read operation on the Channel. -* STATUS = INTEGER (Given and Returned) -* The global status. - -* Notes: -* - This routine is only available in the Fortran interface to the -* AST library. -f-- -*/ - -/* Argument Pointers: */ - GENPTR_CHARACTER(LINE) - GENPTR_INTEGER(L) - -/* Local Variables: */ - int l; /* Number of characters in line */ - -/* Set the error context and watch the STATUS value. */ - astAt( "AST_PUTLINE", NULL, 0 ); - astWatchSTATUS( - -/* Initialise the incoming line pointer. */ - line_in = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the number of characters in the line. */ - l = *L; - -/* Negative values (or STATUS set) indicate end of input. If the value - is not negative, limit the number of characters to the length of - the character variable supplied. */ - if ( l >= 0 ) { - if ( l > LINE_length ) l = LINE_length; - -/* Create a dynamic string and fill it with the incoming data. Store - the resulting pointer, which will be picked up by the SourceWrap - function. */ - line_in = astString( LINE, l ); - } - ) -} - -void astSinkWrap_( void (* sink)( const char * ), const char *line, int *status ) { -/* -*+ -* Name: -* astSinkWrap - -* Purpose: -* Wrapper function to invoke a FORTRAN Channel sink function. - -* Type: -* Protected function. - -* Synopsis: -* void astSinkWrap( void (* sink)( const char * ), const char *line ) - -* Description: -* This function invokes the sink function whose pointer is -* supplied in order to write an output line to an external data -* store. - -* Parameters: -* sink -* Pointer to a sink function. This should result from a cast -* applied to a pointer to a function, with a single FORTRAN -* INTEGER error status argument, that returns void. This is -* the form of Channel sink function employed by the FORTRAN -* language interface to the AST library. -* line -* Pointer to a constant null-terminated string containing the -* line of output text. -*- -*/ - -/* Local Variables; */ - DECLARE_INTEGER(STATUS); /* FORTRAN error status variable */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the pointer to the output text line in the (static) - "line_out" variable, where it will be accessed by the sink function - invoking AST_GETLINE. */ - line_out = line; - -/* Cast the sink function pointer to a pointer to the FORTRAN - subroutine and then invoke it. Transfer the AST error status to and - from the subroutine's error status argument. */ - STATUS = astStatus; - ( *(void (*)()) sink )( INTEGER_ARG(&STATUS) ); - astSetStatus( STATUS ); - -/* Clear the outgoing line pointer. */ - line_out = NULL; -} - -char *astSourceWrap_( const char *(* source)( void ), int *status ) { -/* -*+ -* Name: -* astSourceWrap - -* Purpose: -* Wrapper function to invoke a FORTRAN Channel source function. - -* Type: -* Protected function. - -* Synopsis: -* char *astSourceWrap( const char *(* source)( void ) ) - -* Description: -* This function invokes the source function whose pointer is -* supplied in order to read the next input line from an external -* data store. It then returns a pointer to a dynamic string -* containing a copy of the text that was read. - -* Parameters: -* source -* Pointer to a source function. This should result from a cast -* applied to a pointer to a function, with a single FORTRAN -* INTEGER error status argument, that returns void. This is -* the form of Channel source function employed by the FORTRAN -* language interface to the AST library. - -* Returned Value: -* A pointer to a dynamically allocated, null terminated string -* containing a copy of the text that was read. This string must be -* freed by the caller (using astFree) when no longer required. -* -* A NULL pointer will be returned if there is no more input text -* to read. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*- -*/ - -/* Local Variables: */ - DECLARE_INTEGER(STATUS); /* FORTRAN error status variable */ - char *result; /* Result pointer to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise the incoming line pointer. */ - line_in = NULL; - -/* Cast the source function pointer to a pointer to the FORTRAN - subroutine and then invoke it. Transfer the AST error status to and - from the subroutine's error status argument. */ - STATUS = astStatus; - ( *(void (*)()) source )( INTEGER_ARG(&STATUS) ); - astSetStatus( STATUS ); - -/* This should result in a pointer to a dynamic string containing the - input text being stored in the (static) "line_in" variable as a - result of the source function invoking AST_PUTLINE. Save this - string pointer and clear the original. */ - result = line_in; - line_in = NULL; - -/* If an error occurred, free the returned string. */ - if ( ! astOK ) result = astFree( result ); - -/* Return the result. */ - return result; -} - -/* FORTRAN interface functions. */ -/* ============================ */ -/* These functions implement the remainder of the FORTRAN interface. */ -F77_INTEGER_FUNCTION(ast_channel)( void (* SOURCE)(), - void (* SINK)(), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - const char *(* source)( void ); - int i; - void (* sink)( const char * ); - - astAt( "AST_CHANNEL", NULL, 0 ); - astWatchSTATUS( - -/* Set the source and sink function pointers to NULL if a pointer to - the null routine AST_NULL has been supplied. */ - source = (const char *(*)( void )) SOURCE; - if ( source == (const char *(*)( void )) F77_EXTERNAL_NAME(ast_null) ) { - source = NULL; - } - sink = (void (*)( const char * )) SINK; - if ( sink == (void (*)( const char * )) F77_EXTERNAL_NAME(ast_null) ) { - sink = NULL; - } - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astChannelFor( source, astSourceWrap, sink, astSinkWrap, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_isachannel)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISACHANNEL", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAChannel( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_read)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_READ", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astRead( astI2P( *THIS ) ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_write)( INTEGER(THIS), - INTEGER(OBJECT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(OBJECT) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_WRITE", NULL, 0 ); - astWatchSTATUS( - RESULT = astWrite( astI2P( *THIS ), astI2P( *OBJECT ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_warnings)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_WARNINGS", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astWarnings( astI2P( *THIS ) ) ); - ) - return RESULT; -} - - - diff --git a/ast/fchebymap.c b/ast/fchebymap.c deleted file mode 100644 index 2b006ae..0000000 --- a/ast/fchebymap.c +++ /dev/null @@ -1,137 +0,0 @@ -/* -*+ -* Name: -* fchebymap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST ChebyMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the ChebyMap class. - -* Routines Defined: -* AST_ISACHEBYMAP -* AST_CHEBYMAP - -* Copyright: -* Copyright (C) 201y East Asian Observatory. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 2-MAR-2017 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "chebymap.h" /* C interface to the ChebyMap class */ - -F77_LOGICAL_FUNCTION(ast_isachebymap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISACHEBYMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAChebyMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_chebymap)( INTEGER(NIN), - INTEGER(NOUT), - INTEGER(NCOEFF_F), - DOUBLE_ARRAY(COEFF_F), - INTEGER(NCOEFF_I), - DOUBLE_ARRAY(COEFF_I), - DOUBLE_ARRAY(LBND_F), - DOUBLE_ARRAY(UBND_F), - DOUBLE_ARRAY(LBND_I), - DOUBLE_ARRAY(UBND_I), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NIN) - GENPTR_INTEGER(NOUT) - GENPTR_INTEGER(NCOEFF_F) - GENPTR_DOUBLE_ARRAY(COEFF_F) - GENPTR_INTEGER(NCOEFF_I) - GENPTR_DOUBLE_ARRAY(COEFF_I) - GENPTR_DOUBLE_ARRAY(LBND_F) - GENPTR_DOUBLE_ARRAY(UBND_F) - GENPTR_DOUBLE_ARRAY(LBND_I) - GENPTR_DOUBLE_ARRAY(UBND_I) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_CHEBYMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astChebyMap( *NIN, *NOUT, *NCOEFF_F, COEFF_F, *NCOEFF_I, - COEFF_I, LBND_F, UBND_F, LBND_I, UBND_I, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - - -F77_SUBROUTINE(ast_chebydomain)( INTEGER(THIS), - INTEGER(FWD), - DOUBLE(LBND), - DOUBLE(UBND), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(FWD) - GENPTR_DOUBLE(XOUT) - GENPTR_DOUBLE(YOUT) - - astAt( "AST_CHEBYDOMAIN", NULL, 0 ); - astWatchSTATUS( - astChebyDomain( astI2P( *THIS ), *FWD, LBND, UBND ); - ) -} - diff --git a/ast/fcircle.c b/ast/fcircle.c deleted file mode 100644 index b217a4f..0000000 --- a/ast/fcircle.c +++ /dev/null @@ -1,128 +0,0 @@ -/* -*+ -* Name: -* fcircle.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Circle class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Circle class. - -* Routines Defined: -* AST_ISACIRCLE -* AST_CIRCLE - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 31-AUG-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "circle.h" /* C interface to the Circle class */ - - -F77_LOGICAL_FUNCTION(ast_isacircle)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISACIRCLE", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsACircle( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_circle)( INTEGER(FRAME), - INTEGER(FORM), - DOUBLE_ARRAY(POINT1), - DOUBLE_ARRAY(POINT2), - INTEGER(UNC), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_INTEGER(FORM) - GENPTR_DOUBLE_ARRAY(POINT1) - GENPTR_DOUBLE_ARRAY(POINT2) - GENPTR_INTEGER(UNC) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_CIRCLE", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - - RESULT = astP2I( astCircle( astI2P( *FRAME ), *FORM, POINT1, POINT2, - astI2P( *UNC ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_circlepars)( INTEGER(THIS), - DOUBLE_ARRAY(CENTRE), - DOUBLE(RADIUS), - DOUBLE_ARRAY(P1), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(CENTRE) - GENPTR_DOUBLE(RADIUS) - GENPTR_DOUBLE_ARRAY(P1) - - astAt( "AST_CIRCLEPARS", NULL, 0 ); - astWatchSTATUS( - astCirclePars( astI2P( *THIS ), CENTRE, RADIUS, P1 ); - ) -} - diff --git a/ast/fcmpframe.c b/ast/fcmpframe.c deleted file mode 100644 index 8d99d3b..0000000 --- a/ast/fcmpframe.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -*+ -* Name: -* fcmpframe.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST CmpFrame class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the CmpFrame class. - -* Routines Defined: -* AST_CMPFRAME -* AST_ISACMPFRAME - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 30-SEP-1996 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "cmpframe.h" /* C interface to the CmpFrame class */ - -F77_LOGICAL_FUNCTION(ast_isacmpframe)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISACMPFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsACmpFrame( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_cmpframe)( INTEGER(FRAME1), - INTEGER(FRAME2), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME1) - GENPTR_INTEGER(FRAME2) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_CMPFRAME", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astCmpFrame( astI2P( *FRAME1 ), astI2P( *FRAME2 ), - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fcmpmap.c b/ast/fcmpmap.c deleted file mode 100644 index 2888519..0000000 --- a/ast/fcmpmap.c +++ /dev/null @@ -1,106 +0,0 @@ -/* -*+ -* Name: -* fcmpmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST CmpMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the CmpMap class. - -* Routines Defined: -* AST_ISACMPMAP -* AST_CMPMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 25-SEP-1996 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "cmpmap.h" /* C interface to the CmpMap class */ - -F77_LOGICAL_FUNCTION(ast_isacmpmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astWatchSTATUS( - astAt( "AST_ISACMPMAP", NULL, 0 ); - RESULT = astIsACmpMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_cmpmap)( INTEGER(MAP1), - INTEGER(MAP2), - LOGICAL(SERIES), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(MAP1) - GENPTR_INTEGER(MAP2) - GENPTR_LOGICAL(SERIES) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_CMPMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astCmpMap( astI2P( *MAP1 ), astI2P( *MAP2 ), - F77_ISTRUE( *SERIES ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fcmpregion.c b/ast/fcmpregion.c deleted file mode 100644 index f494d28..0000000 --- a/ast/fcmpregion.c +++ /dev/null @@ -1,107 +0,0 @@ -/* -*+ -* Name: -* fcmpregion.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST CmpRegion class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the CmpRegion class. - -* Routines Defined: -* AST_ISACMPREGION -* AST_CMPREGION - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 12-OCT-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "cmpregion.h" /* C interface to the CmpRegion class */ - - -F77_LOGICAL_FUNCTION(ast_isacmpregion)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISACMPREGION", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsACmpRegion( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_cmpregion)( INTEGER(REG1), - INTEGER(REG2), - INTEGER(OPER), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(REG1) - GENPTR_INTEGER(REG2) - GENPTR_INTEGER(OPER) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_CMPREGION", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - - RESULT = astP2I( astCmpRegion( astI2P( *REG1 ), astI2P( *REG2 ), - *OPER, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fdsbspecframe.c b/ast/fdsbspecframe.c deleted file mode 100644 index f0ec5db..0000000 --- a/ast/fdsbspecframe.c +++ /dev/null @@ -1,100 +0,0 @@ -/* -*+ -* Name: -* fdsbspecframe.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST DSBSpecFrame class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the DSBSpecFrame class. - -* Routines Defined: -* AST_ISADSBSPECFRAME -* AST_DSBSPECFRAME - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 5-AUG-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "dsbspecframe.h" /* C interface to the DSBSpecFrame class */ - -F77_LOGICAL_FUNCTION(ast_isadsbspecframe)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISADSBSPECFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsADSBSpecFrame( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_dsbspecframe)( CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_DSBSPECFRAME", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astDSBSpecFrame( "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - diff --git a/ast/fdssmap.c b/ast/fdssmap.c deleted file mode 100644 index 8e570de..0000000 --- a/ast/fdssmap.c +++ /dev/null @@ -1,75 +0,0 @@ -/* -*+ -* Name: -* fdssmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST DssMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the DssMap class. - -* Routines Defined: -* AST_ISADSSMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 19-FEB-1997 (DSB): -* Original version. -* 5-SEP-1997 (RFWS) -* Removed the AST_DSSMAP function (now protected, so not -* required in the Fortran interface). -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "dssmap.h" /* C interface to the DssMap class */ - -F77_LOGICAL_FUNCTION(ast_isadssmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISADSSMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsADssMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} diff --git a/ast/fellipse.c b/ast/fellipse.c deleted file mode 100644 index 2570a2c..0000000 --- a/ast/fellipse.c +++ /dev/null @@ -1,136 +0,0 @@ -/* -*+ -* Name: -* fellipse.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Ellipse class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Ellipse class. - -* Routines Defined: -* AST_ISAELLIPSE -* AST_ELLIPSE - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 31-AUG-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "ellipse.h" /* C interface to the Ellipse class */ - - -F77_LOGICAL_FUNCTION(ast_isaellipse)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAELLIPSE", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAEllipse( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_ellipse)( INTEGER(FRAME), - INTEGER(FORM), - DOUBLE_ARRAY(POINT1), - DOUBLE_ARRAY(POINT2), - DOUBLE_ARRAY(POINT3), - INTEGER(UNC), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_INTEGER(FORM) - GENPTR_DOUBLE_ARRAY(POINT1) - GENPTR_DOUBLE_ARRAY(POINT2) - GENPTR_DOUBLE_ARRAY(POINT3) - GENPTR_INTEGER(UNC) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_ELLIPSE", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - - RESULT = astP2I( astEllipse( astI2P( *FRAME ), *FORM, POINT1, POINT2, - POINT3, astI2P( *UNC ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_ellipsepars)( INTEGER(THIS), - DOUBLE_ARRAY(CENTRE), - DOUBLE(A), - DOUBLE(B), - DOUBLE(ANGLE), - DOUBLE_ARRAY(P1), - DOUBLE_ARRAY(P2), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(CENTRE) - GENPTR_DOUBLE(A) - GENPTR_DOUBLE(B) - GENPTR_DOUBLE(ANGLE) - GENPTR_DOUBLE_ARRAY(P1) - GENPTR_DOUBLE_ARRAY(P2) - - astAt( "AST_ELLIPSEPARS", NULL, 0 ); - astWatchSTATUS( - astEllipsePars( astI2P( *THIS ), CENTRE, A, B, ANGLE, P1, P2 ); - ) -} - diff --git a/ast/ferror.c b/ast/ferror.c deleted file mode 100644 index 7407b0f..0000000 --- a/ast/ferror.c +++ /dev/null @@ -1,120 +0,0 @@ -/* -*+ -* Name: -* ferror.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Error module. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Error module. - -* Routines Defined: -* None. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 15-JUL-1996 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -#define MXSTRLEN 80 /* String length at which truncation starts - within astPutErr */ -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "error.h" /* C interface to the Error module */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ - - -/* Prototypes for external functions. */ -/* ================================== */ -/* This is the null function defined by the FORTRAN interface in -fobject.c. */ -F77_SUBROUTINE(ast_null)( void ); - -static void FPutErrWrapper( AstPutErrFun, int, const char * ); - - -/* Wrapper functions */ -/* ================= */ -F77_SUBROUTINE(ast_setputerr)( AstPutErrFun FUN, INTEGER(STATUS) ) { - AstPutErrFun fun; - const char *class; /* Object class */ - const char *method; /* Current method */ - - method = "AST_GRFSET"; - class = "Plot"; - - astAt( method, NULL, 0 ); - astWatchSTATUS( - -/* Set the function pointer to NULL if a pointer to - the null routine AST_NULL has been supplied. */ - fun = FUN; - if ( fun == (AstPutErrFun) F77_EXTERNAL_NAME(ast_null) ) { - fun = NULL; - } - -/* Store the function pointer in the error module. */ - astSetPutErr( fun ); - -/* The above call assumes that "fun" uses C calling conventions. Since in - fact "fun" uses Fortran calling conventions, we need to tell the error - module to call "fun" via a wrapper that converts strings etc from C to - Fortran. */ - astSetPutErrWrapper( FPutErrWrapper ); - ) -} - - -static void FPutErrWrapper( AstPutErrFun fun, int status_value, const char *message ){ - - DECLARE_CHARACTER(LMESSAGE,MXSTRLEN); - int fmessage_length; - - fmessage_length = strlen( message ); - if( fmessage_length > LMESSAGE_length ) fmessage_length = LMESSAGE_length; - astStringExport( message, LMESSAGE, fmessage_length ); - - ( *(void (*)( INTEGER(status_value), CHARACTER(LMESSAGE) - TRAIL(fmessage) ) ) fun)(INTEGER_ARG(&status_value), - CHARACTER_ARG(LMESSAGE) - TRAIL_ARG(fmessage)); - - -} - - diff --git a/ast/fetch b/ast/fetch deleted file mode 100755 index 1ca0578..0000000 --- a/ast/fetch +++ /dev/null @@ -1,5 +0,0 @@ - -here=${PWD} -cd ${AST_REF} -cp $@ ${here} -cd ${here} diff --git a/ast/ffitschan.c b/ast/ffitschan.c deleted file mode 100644 index ef1b83e..0000000 --- a/ast/ffitschan.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* -*+ -* Name: -* ffitschan.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST FitsChan class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the FitsChan class. - -* Routines Defined: -* AST_DELFITS -* AST_PURGEWCS -* AST_FINDFITS -* AST_FITSCHAN -* AST_ISAFITSCHAN -* AST_PUTCARDS -* AST_PUTFITS -* AST_RETAINFITS -* AST_SETFITS -* AST_GETFITS - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 11-DEC-1996 (DSB): -* Original version. -* 21-FEB-1997 (DSB): -* Added source and sink functions to AST_FITSCHAN. -* 20-MAR-1997 (DSB): -* Functions for accessing named keywords removed. Others renamed. -* 28-APR-1997 (DSB): -* FindFits and GetFits merged. -* 10-SEP-2004 (TIMJ): -* Only copy the fits header to fortran string if it was found -* by astFindFits. -* 17-NOV-2004 (DSB): -* Added AST_SETFITS -* 7-OCT-2005 (DSB): -* Added AST_GETFITS -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "ast_err.h" /* AST error codes */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "object.h" /* C interface to the base Object class */ -#include "fitschan.h" /* C interface to the FitsChan class */ - -#include -#include - -/* Prototypes for private functions. */ -/* ================================= */ -static char *SourceWrap( const char *(*)( void ), int * ); -static void SinkWrap( void (*)( const char * ), const char *, int * ); -static void TabSourceWrap( void (*)( void ), - AstFitsChan *, const char *, int, int, int * ); - -/* Prototypes for external functions. */ -/* ================================== */ -/* This is the null function defined by the FORTRAN interface in fobject.c. */ -F77_SUBROUTINE(ast_null)( void ); - -/* Source and sink function interfaces. */ -/* ==================================== */ -/* These functions are concerned with allowing FORTRAN implementations - of FitsChan source and sink functions to be passed to the FitsChan - class and invoked when necessary by C code in the main class - implementation. All FORTRAN-specific aspects of this interface are - encapsulated here. */ -static void SinkWrap( void (* sink)( const char * ), const char *line, - int *status ) { -/* -* Name: -* SinkWrap - -* Purpose: -* Wrapper function to invoke a FORTRAN FitsChan sink function. - -* Type: -* Private function. - -* Synopsis: -* static void SinkWrap( void (* sink)( const char * ), const char *line, -* int *status ) - -* Description: -* This function invokes the sink function whose pointer is -* supplied in order to write an output line to an external data -* store. - -* Parameters: -* sink -* Pointer to a sink function. This should result from a cast -* applied to a pointer to a function (with two FORTRAN -* arguments: a character string of length 80 to receive a FITS -* card and an integer error status), that returns void. This -* is the form of FitsChan sink function employed by the FORTRAN -* language interface to the AST library. -* status -* Pointer to inherited status value. -*/ - -/* Local Variables: */ - DECLARE_CHARACTER(CARD,80); - DECLARE_INTEGER(STATUS); - char *d; - const char *c; - int i,lim; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Copy the supplied null terminated string to a fixed length, blank - padded string which can be passed to the Fortran routine. */ - c = line; - d = CARD; - - lim = (int) strlen( line ); - if( lim > 80 ) lim = 80; - - for( i = 0; i < lim; i++ ){ - *(d++) = (*c++); - } - - for( ; i < 80; i++ ){ - *(d++) = ' '; - } - -/* Cast the sink function pointer to a pointer to the FORTRAN - subroutine and then invoke it. Transfer the AST error status to and - from the subroutine's error status argument. */ - STATUS = astStatus; - ( ( void (*)() ) sink )( CHARACTER_ARG(CARD), INTEGER_ARG(&STATUS) - TRAIL_ARG(CARD) ); - astSetStatus( STATUS ); -} - -static char *SourceWrap( const char *(* source)( void ), int *status ) { -/* -* Name: -* SourceWrap - -* Purpose: -* Wrapper function to invoke a FORTRAN FitsChan source function. - -* Type: -* Private function. - -* Synopsis: -* static char *SourceWrap( const char *(* source)( void ), int *status ) - -* Description: -* This function invokes the source function whose pointer is -* supplied in order to read the next input line from an external -* data store. It then returns a pointer to a dynamic string -* containing a copy of the text that was read. - -* Parameters: -* source -* Pointer to a source function. This should result from a cast -* applied to a pointer to a function (with two FORTRAN -* arguments: a character string of length 80 to return a FITS -* card and an integer error status), that returns a Fortran -* integer. This is the form of FitsChan source function -* employed by the FORTRAN language interface to the AST -* library. -* status -* Pointer to inherited status. - -* Returned Value: -* A pointer to a dynamically allocated, null terminated string -* containing a copy of the text that was read. This string must be -* freed by the caller (using astFree) when no longer required. -* -* A NULL pointer will be returned if there is no more input text -* to read. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - DECLARE_CHARACTER(CARD,81); /* Fixed length Fortran string */ - DECLARE_INTEGER(STATUS); /* Fortran error status value */ - char *result; /* Result pointer to return */ - int retval; /* Value returned by source subroutine */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Cast the source function pointer to a pointer to the FORTRAN - function and then invoke it. Transfer the AST error status to and - from the subroutine's error status argument. */ - STATUS = astStatus; - retval = ( *(F77_INTEGER_TYPE (*)()) source )( CHARACTER_ARG(CARD), - INTEGER_ARG(&STATUS) - TRAIL_ARG(CARD) ); - astSetStatus( STATUS ); - -/* If a card was returned, make a dynamic copy of it. */ - if ( astOK && retval ) result = astString( CARD, 80 ); - -/* Return the result. */ - return result; -} - -static void TabSourceWrap( void (*tabsource)( void ), - AstFitsChan *this, const char *extname, - int extver, int extlevel, int *status ){ -/* -* Name: -* TabSourceWrap - -* Purpose: -* Wrapper function to invoke the F77 table source function. - -* Type: -* Private function. - -* Synopsis: -* void TabSourceWrap( void (*tabsource)( void ), -* AstFitsChan *this, const char *extname, -* int extver, int extlevel, int *status ){ - -* Class Membership: -* Channel member function. - -* Description: -* This function invokes the table source function whose pointer is -* supplied in order to read a named FITS binary table from an external -* FITS file. - -* Parameters: -* tabsource -* Pointer to the C tab source function. -* this -* Pointer to the FitsChan. It's reference count will be decremented -* by this function. -* extname -* Pointer to the string holding the name of the FITS extension -* from which a table is to be read. -* extver -* FITS "EXTVER" value for required extension. -* extlevel -* FITS "EXTLEVEL" value for required extension. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - DECLARE_CHARACTER(EXTNAME,80); - DECLARE_INTEGER(THIS_ID); - DECLARE_INTEGER(LSTAT); - DECLARE_INTEGER(EXTVER); - DECLARE_INTEGER(EXTLEVEL); - AstObject *this_id; - char *d; - const char *c; - int i; - int lim; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get an external identifier for the FitsChan. Note, this does not - increment the Object's reference count. Cannot use astClone as we - are in a "public" environment and so astClone would require an object - identifier, not a true C pointer. So the calling function should clone - the pointer before calling this function to avoid the reference count - dropping to zero when the associated identifier is annulled at the end of - this function. */ - this_id = astMakeId( this ); - THIS_ID = astP2I( this_id ); - -/* Export the extver and extlevel values */ - EXTVER = extver; - EXTLEVEL = extlevel; - -/* Copy the supplied null terminated string to a fixed length, blank - padded string which can be passed to the Fortran routine. */ - c = extname; - d = EXTNAME; - - lim = (int) strlen( extname ); - if( lim > 80 ) lim = 80; - - for( i = 0; i < lim; i++ ){ - *(d++) = (*c++); - } - - for( ; i < 80; i++ ){ - *(d++) = ' '; - } - -/* Invoke the table source function (casting it to the F77 API first) to - read the table, and store it in the FitsChan. */ - if( astOK ) { - LSTAT = 0; - ( ( void (*)() ) tabsource )( - INTEGER_ARG(&THIS_ID), CHARACTER_ARG(EXTNAME), INTEGER_ARG(&EXTVER), - INTEGER_ARG(&EXTLEVEL), INTEGER_ARG(&LSTAT) TRAIL_ARG(EXTNAME) ); - } - -/* Report an error if the source function failed. */ - if( LSTAT ) { - if( astOK ) { - astError( AST__NOTAB, "astRead(%s): The table source function failed to read " - "a binary table from extension %s in an external FITS file.", - status, astGetC( this_id, "Class" ), extname ); - } else { - astError( astStatus, "astRead(%s): The table source function failed to read " - "a binary table from extension %s in an external FITS file.", - status, astGetC( this_id, "Class" ), extname ); - } - } - - -/* Free the external identifier for the FitsChan. Note, this decrements - the Object reference count. See comments above. */ - (void) astAnnulId( this_id ); - -} - -/* FORTRAN interface functions. */ -/* ============================ */ -/* These functions implement the remainder of the FORTRAN interface. */ -F77_INTEGER_FUNCTION(ast_fitschan)( F77_INTEGER_TYPE (* SOURCE)(), - void (* SINK)(), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - const char *(* source)( void ); - int i; - void (* sink)( const char * ); - - astAt( "AST_FITSCHAN", NULL, 0 ); - astWatchSTATUS( - -/* Set the source and sink function pointers to NULL if a pointer to - the null routine AST_NULL has been supplied. */ - source = (const char *(*)( void )) SOURCE; - if ( source == (const char *(*)( void )) F77_EXTERNAL_NAME(ast_null) ) { - source = NULL; - } - sink = (void (*)( const char * )) SINK; - if ( sink == (void (*)( const char * )) F77_EXTERNAL_NAME(ast_null) ) { - sink = NULL; - } - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astFitsChanFor( source, SourceWrap, sink, SinkWrap, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_isafitschan)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAFITSCHAN", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAFitsChan( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_SUBROUTINE(ast_putcards)( INTEGER(THIS), - CHARACTER(CARDS), - INTEGER(STATUS) - TRAIL(CARDS) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(CARDS) - char *cards; - - astAt( "AST_PUTCARDS", NULL, 0 ); - astWatchSTATUS( - cards = astString( CARDS, CARDS_length ); - astPutCards( astI2P( *THIS ), cards ); - (void) astFree( (void *) cards ); - ) -} - -F77_SUBROUTINE(ast_putfits)( INTEGER(THIS), - CHARACTER(CARD), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(CARD) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(CARD) - GENPTR_LOGICAL(OVERWRITE) - int overwrite; - char *card; - - astAt( "AST_PUTFITS", NULL, 0 ); - astWatchSTATUS( - card = astString( CARD, CARD_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - astPutFits( astI2P( *THIS ), card, overwrite ); - (void) astFree( (void *) card ); - ) -} - -F77_SUBROUTINE(ast_delfits)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_DELFITS", NULL, 0 ); - astWatchSTATUS( - astDelFits( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_purgewcs)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_PURGEWCS", NULL, 0 ); - astWatchSTATUS( - astPurgeWCS( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_retainfits)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_RETAINFITS", NULL, 0 ); - astWatchSTATUS( - astRetainFits( astI2P( *THIS ) ); - ) -} - -F77_LOGICAL_FUNCTION(ast_findfits)( INTEGER(THIS), - CHARACTER(NAME), - CHARACTER(CARD), - LOGICAL(INC), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(CARD) ){ - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_CHARACTER(CARD) - GENPTR_LOGICAL(INC) - F77_LOGICAL_TYPE(RESULT); - int i, len; - char *name; - char card[ 81 ]; - int inc; - - astAt( "AST_FINDFITS", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - inc = F77_ISTRUE( *INC ); - RESULT = astFindFits( astI2P( *THIS ), name, card, inc ) ? - F77_TRUE : F77_FALSE; - i = 0; - if ( astOK && F77_ISTRUE(RESULT) ) { - len = (int) strlen( card ); - for( i = 0; i < CARD_length && i < len; i++ ) CARD[i] = card[i]; - } - for( ; i < CARD_length; i++ ) CARD[i] = ' '; - (void) astFree( (void *) name ); - ) - return RESULT; -} - - -F77_SUBROUTINE(ast_setfitsf)( INTEGER(THIS), - CHARACTER(NAME), - DOUBLE(VALUE), - CHARACTER(COMMENT), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_DOUBLE(VALUE) - GENPTR_CHARACTER(COMMENT) - GENPTR_LOGICAL(OVERWRITE) - int overwrite; - char *name, *comment; - - astAt( "AST_SETFITSF", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - comment = astString( COMMENT, COMMENT_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - astSetFitsF( astI2P( *THIS ), name, *VALUE, comment, overwrite ); - (void) astFree( (void *) name ); - (void) astFree( (void *) comment ); - ) -} - -F77_SUBROUTINE(ast_setfitsu)( INTEGER(THIS), - CHARACTER(NAME), - CHARACTER(COMMENT), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_CHARACTER(COMMENT) - GENPTR_LOGICAL(OVERWRITE) - int overwrite; - char *name, *comment; - - astAt( "AST_SETFITSU", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - comment = astString( COMMENT, COMMENT_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - astSetFitsU( astI2P( *THIS ), name, comment, overwrite ); - (void) astFree( (void *) name ); - (void) astFree( (void *) comment ); - ) -} - -F77_SUBROUTINE(ast_setfitscm)( INTEGER(THIS), - CHARACTER(COMMENT), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(COMMENT) - GENPTR_LOGICAL(OVERWRITE) - int overwrite; - char *comment; - - astAt( "AST_SETFITSCM", NULL, 0 ); - astWatchSTATUS( - comment = astString( COMMENT, COMMENT_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - astSetFitsCM( astI2P( *THIS ), comment, overwrite ); - (void) astFree( (void *) comment ); - ) -} - - -F77_SUBROUTINE(ast_setfitsi)( INTEGER(THIS), - CHARACTER(NAME), - INTEGER(VALUE), - CHARACTER(COMMENT), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_INTEGER(VALUE) - GENPTR_CHARACTER(COMMENT) - GENPTR_LOGICAL(OVERWRITE) - int overwrite; - char *name, *comment; - - astAt( "AST_SETFITSI", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - comment = astString( COMMENT, COMMENT_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - astSetFitsI( astI2P( *THIS ), name, *VALUE, comment, overwrite ); - (void) astFree( (void *) name ); - (void) astFree( (void *) comment ); - ) -} - - -F77_SUBROUTINE(ast_setfitscf)( INTEGER(THIS), - CHARACTER(NAME), - DOUBLE_ARRAY(VALUE), - CHARACTER(COMMENT), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_DOUBLE_ARRAY(VALUE) - GENPTR_CHARACTER(COMMENT) - GENPTR_LOGICAL(OVERWRITE) - int overwrite; - char *name, *comment; - - astAt( "AST_SETFITSCF", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - comment = astString( COMMENT, COMMENT_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - astSetFitsCF( astI2P( *THIS ), name, VALUE, comment, overwrite ); - (void) astFree( (void *) name ); - (void) astFree( (void *) comment ); - ) -} - - -F77_SUBROUTINE(ast_setfitsci)( INTEGER(THIS), - CHARACTER(NAME), - INTEGER_ARRAY(VALUE), - CHARACTER(COMMENT), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_INTEGER_ARRAY(VALUE) - GENPTR_CHARACTER(COMMENT) - GENPTR_LOGICAL(OVERWRITE) - int overwrite; - char *name, *comment; - - astAt( "AST_SETFITSCI", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - comment = astString( COMMENT, COMMENT_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - astSetFitsCI( astI2P( *THIS ), name, VALUE, comment, overwrite ); - (void) astFree( (void *) name ); - (void) astFree( (void *) comment ); - ) -} - - -F77_SUBROUTINE(ast_setfitsl)( INTEGER(THIS), - CHARACTER(NAME), - LOGICAL(VALUE), - CHARACTER(COMMENT), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_LOGICAL(VALUE) - GENPTR_CHARACTER(COMMENT) - GENPTR_LOGICAL(OVERWRITE) - int overwrite, value; - char *name, *comment; - - astAt( "AST_SETFITSL", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - comment = astString( COMMENT, COMMENT_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - value = F77_ISTRUE( *VALUE ); - astSetFitsL( astI2P( *THIS ), name, value, comment, overwrite ); - (void) astFree( (void *) name ); - (void) astFree( (void *) comment ); - ) -} - - -F77_SUBROUTINE(ast_setfitss)( INTEGER(THIS), - CHARACTER(NAME), - CHARACTER(VALUE), - CHARACTER(COMMENT), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(VALUE) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_CHARACTER(VALUE) - GENPTR_CHARACTER(COMMENT) - GENPTR_LOGICAL(OVERWRITE) - int overwrite; - char *name, *comment, *value; - - astAt( "AST_SETFITSS", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - value = astString( VALUE, VALUE_length ); - comment = astString( COMMENT, COMMENT_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - astSetFitsS( astI2P( *THIS ), name, value, comment, overwrite ); - (void) astFree( (void *) name ); - (void) astFree( (void *) value ); - (void) astFree( (void *) comment ); - ) -} - -F77_SUBROUTINE(ast_setfitscn)( INTEGER(THIS), - CHARACTER(NAME), - CHARACTER(VALUE), - CHARACTER(COMMENT), - LOGICAL(OVERWRITE), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(VALUE) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_CHARACTER(VALUE) - GENPTR_CHARACTER(COMMENT) - GENPTR_LOGICAL(OVERWRITE) - int overwrite; - char *name, *comment, *value; - - astAt( "AST_SETFITSS", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - value = astString( VALUE, VALUE_length ); - comment = astString( COMMENT, COMMENT_length ); - overwrite = F77_ISTRUE( *OVERWRITE ); - astSetFitsCN( astI2P( *THIS ), name, value, comment, overwrite ); - (void) astFree( (void *) name ); - (void) astFree( (void *) value ); - (void) astFree( (void *) comment ); - ) -} - -#define MAKE_AST_GETFITS(f,F,Ftype,X,Xtype) \ -F77_LOGICAL_FUNCTION(ast_getfits##f)( INTEGER(THIS), \ - CHARACTER(NAME), \ - Ftype(VALUE), \ - INTEGER(STATUS) \ - TRAIL(NAME) ){ \ - GENPTR_INTEGER(THIS) \ - GENPTR_CHARACTER(NAME) \ - GENPTR_##Ftype(VALUE) \ - GENPTR_INTEGER(STATUS) \ - F77_LOGICAL_TYPE(RESULT); \ -\ - char *name; \ - Xtype *value; \ -\ - value = (Xtype *) VALUE; \ -\ - astAt( "AST_GETFITS"#F, NULL, 0 ); \ - astWatchSTATUS( \ - name = astString( NAME, NAME_length ); \ - if( name && !strcmp( name, "." ) ) name = astFree( name ); \ - RESULT = astGetFits##X( astI2P( *THIS ), name, value ) ? \ - F77_TRUE : F77_FALSE; \ - (void) astFree( (void *) name ); \ - ) \ - return RESULT; \ -} - -MAKE_AST_GETFITS(f,F,DOUBLE,F,double) -MAKE_AST_GETFITS(i,I,INTEGER,I,int) -MAKE_AST_GETFITS(l,L,LOGICAL,L,int) -#undef MAKE_AST_GETFITS - - -F77_LOGICAL_FUNCTION(ast_testfits)( INTEGER(THIS), - CHARACTER(NAME), - LOGICAL(THERE), - INTEGER(STATUS) - TRAIL(NAME) ){ - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_LOGICAL(THERE) - GENPTR_INTEGER(STATUS) - F77_LOGICAL_TYPE(RESULT); - - char *name; - int there; - - astAt( "AST_TESTFITS", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - if( name && !strcmp( name, "." ) ) name = astFree( name ); \ - RESULT = astTestFits( astI2P( *THIS ), name, &there ) ? - F77_TRUE : F77_FALSE; - (void) astFree( (void *) name ); - ) - *THERE = there ? F77_TRUE : F77_FALSE; - return RESULT; -} - - -#define MAKE_AST_GETFITS(f,F,Ftype,X,Xtype) \ -F77_LOGICAL_FUNCTION(ast_getfits##f)( INTEGER(THIS), \ - CHARACTER(NAME), \ - Ftype##_ARRAY(VALUE), \ - INTEGER(STATUS) \ - TRAIL(NAME) ){ \ - GENPTR_INTEGER(THIS) \ - GENPTR_CHARACTER(NAME) \ - GENPTR_##Ftype##_ARRAY(VALUE) \ - GENPTR_INTEGER(STATUS) \ - F77_LOGICAL_TYPE(RESULT); \ -\ - char *name; \ - Xtype value[2]; \ -\ - astAt( "AST_GETFITS"#F, NULL, 0 ); \ - astWatchSTATUS( \ - name = astString( NAME, NAME_length ); \ - if( name && !strcmp( name, "." ) ) name = astFree( name ); \ - RESULT = astGetFits##X( astI2P( *THIS ), name, value ) ? \ - F77_TRUE : F77_FALSE; \ - VALUE[ 0 ] = (F77_DOUBLE_TYPE) value[ 0 ]; \ - VALUE[ 1 ] = (F77_DOUBLE_TYPE) value[ 1 ]; \ - (void) astFree( (void *) name ); \ - ) \ - return RESULT; \ -} - - -MAKE_AST_GETFITS(cf,CF,DOUBLE,CF,double) -MAKE_AST_GETFITS(ci,CI,INTEGER,CI,int) - -#undef MAKE_AST_GETFITS - -#define MAKE_AST_GETFITS(f,F,X) \ -F77_LOGICAL_FUNCTION(ast_getfits##f)( INTEGER(THIS), \ - CHARACTER(NAME), \ - CHARACTER(VALUE), \ - INTEGER(STATUS) \ - TRAIL(NAME) \ - TRAIL(VALUE) ){ \ - GENPTR_INTEGER(THIS) \ - GENPTR_CHARACTER(NAME) \ - GENPTR_CHARACTER(VALUE) \ - GENPTR_INTEGER(STATUS) \ - F77_LOGICAL_TYPE(RESULT); \ -\ - char *name; \ - int i, len; \ - char *value; \ -\ - astAt( "AST_GETFITS"#F, NULL, 0 ); \ - astWatchSTATUS( \ - name = astString( NAME, NAME_length ); \ - if( name && !strcmp( name, "." ) ) name = astFree( name ); \ - RESULT = astGetFits##X( astI2P( *THIS ), name, &value ) ? \ - F77_TRUE : F77_FALSE; \ - if ( astOK && F77_ISTRUE(RESULT) ) { \ - len = (int) strlen( value ); \ - for( i = 0; i < VALUE_length && i < len; i++ ) VALUE[i] = value[i]; \ - } else { \ - i = 0; \ - } \ - for( ; i < VALUE_length; i++ ) VALUE[i] = ' '; \ - (void) astFree( (void *) name ); \ - ) \ - return RESULT; \ -} - -MAKE_AST_GETFITS(s,S,S) -MAKE_AST_GETFITS(cn,CN,CN) - -#undef MAKE_AST_GETFITS - -F77_SUBROUTINE(ast_readfits)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_READFITS", NULL, 0 ); - astWatchSTATUS( - astReadFits( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_writefits)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_WRITEFITS", NULL, 0 ); - astWatchSTATUS( - astWriteFits( astI2P( *THIS ) ); - ) -} - - -F77_SUBROUTINE(ast_emptyfits)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_EMPTYFITS", NULL, 0 ); - astWatchSTATUS( - astEmptyFits( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_showfits)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_SHOWFITS", NULL, 0 ); - astWatchSTATUS( - astShowFits( astI2P( *THIS ) ); - ) -} - - -F77_INTEGER_FUNCTION(ast_gettables)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETTABLES", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetTables( astI2P( *THIS ) ) ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_removetables)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - char *key; - - astAt( "AST_REMOVETABLES", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - astRemoveTables( astI2P( *THIS ), key ); - (void) astFree( (void *) key ); - ) -} - -F77_SUBROUTINE(ast_puttable)( INTEGER(THIS), - INTEGER(TABLE), - CHARACTER(EXTNAM), - INTEGER(STATUS) - TRAIL(EXTNAM) ){ - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(TABLES) - GENPTR_CHARACTER(EXTNAM) - char *extnam; - - astAt( "AST_PUTTABLE", NULL, 0 ); - astWatchSTATUS( - extnam = astString( EXTNAM, EXTNAM_length ); - astPutTable( astI2P( *THIS ), astI2P( *TABLE ), extnam ); - extnam = astFree( extnam ); - ) -} - -F77_SUBROUTINE(ast_puttables)( INTEGER(THIS), - INTEGER(TABLES), - INTEGER(STATUS) ){ - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(TABLES) - - astAt( "AST_PUTTABLES", NULL, 0 ); - astWatchSTATUS( - astPutTables( astI2P( *THIS ), astI2P( *TABLES ) ); - ) -} - -F77_SUBROUTINE(ast_tablesource)( INTEGER(THIS), - void (* SOURCE)(), - INTEGER(STATUS) ){ - GENPTR_INTEGER(THIS) - void (* source)( void ); - - astAt( "AST_TABLESOURCE", NULL, 0 ); - astWatchSTATUS( - source = (void (*)( void )) SOURCE; - if ( source == (void (*)( void )) F77_EXTERNAL_NAME(ast_null) ) { - source = NULL; - } - astSetTableSource( astI2P( *THIS ), source, TabSourceWrap ); - ) -} - - diff --git a/ast/ffitstable.c b/ast/ffitstable.c deleted file mode 100644 index 9f2db37..0000000 --- a/ast/ffitstable.c +++ /dev/null @@ -1,234 +0,0 @@ -/* -*+ -* Name: -* ffitstable.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST FitsTable class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the FitsTable class. - -* Routines Defined: -* AST_ISAFITSTABLE -* AST_FITSTABLE - -* Copyright: -* Copyright (C) 2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S.Berry (Starlink) - -* History: -* 25-NOV-2010 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "ast_err.h" /* AST error codes */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "fitstable.h" /* C interface to the FitsTable class */ - -F77_LOGICAL_FUNCTION(ast_isafitstable)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astWatchSTATUS( - astAt( "AST_ISAFITSTABLE", NULL, 0 ); - RESULT = astIsAFitsTable( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_fitstable)( INTEGER(HEADER), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(HEADER) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_FITSTABLE", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astFitsTable( astI2P( *HEADER ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_gettableheader)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETTABLEHEADER", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetTableHeader( astI2P( *THIS ) ) ); - ) - return RESULT; -} - - -F77_SUBROUTINE(ast_puttableheader)( INTEGER(THIS), - INTEGER(HEADER), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(HEADER) - - astAt( "AST_PUTTABLEHEADER", NULL, 0 ); - astWatchSTATUS( - astPutTableHeader( astI2P( *THIS ), astI2P( *HEADER ) ); - ) -} - -F77_INTEGER_FUNCTION(ast_columnnull)( INTEGER(THIS), - CHARACTER(COLUMN), - LOGICAL(SET), - INTEGER(NEWVAL), - LOGICAL(WASSET), - LOGICAL(HASNULL), - INTEGER(STATUS) - TRAIL(COLUMN) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(COLUMN) - GENPTR_LOGICAL(SET) - GENPTR_INTEGER(NEWVAL) - GENPTR_LOGICAL(WASSET) - GENPTR_LOGICAL(HASNULL) - F77_INTEGER_TYPE(RESULT); - int wasset, hasnull; - char *column; - - astAt( "AST_COLUMNNULL", NULL, 0 ); - astWatchSTATUS( - column = astString( COLUMN, COLUMN_length ); - RESULT = astColumnNull( astI2P( *THIS ), column, - F77_ISTRUE( *SET ) ? 1 : 0, *NEWVAL, - &wasset, &hasnull ); - *WASSET = wasset ? F77_TRUE : F77_FALSE; - *HASNULL = hasnull ? F77_TRUE : F77_FALSE; - astFree( column ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_columnsize)( INTEGER(THIS), - CHARACTER(COLUMN), - INTEGER(STATUS) - TRAIL(COLUMN) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(COLUMN) - F77_INTEGER_TYPE(RESULT); - char *column; - size_t result; - - astAt( "AST_COLUMNSIZE", NULL, 0 ); - astWatchSTATUS( - column = astString( COLUMN, COLUMN_length ); - result = astColumnSize( astI2P( *THIS ), column ); - astFree( column ); - - RESULT = result; - if( (size_t) RESULT != result && astOK ) { - astError( AST__BIGTAB, "AST_COLUMNSIZE(FitsTable): The number of bytes in the " - "column is too large to fit in a Fortran INTEGER.", status ); - } - - ) - return RESULT; -} - -F77_SUBROUTINE(ast_getcolumndata)( INTEGER(THIS), - CHARACTER(COLUMN), - REAL(RNULL), - DOUBLE(DNULL), - INTEGER(MXSIZE), - BYTE_ARRAY(COLDATA), - INTEGER(NELEM), - INTEGER(STATUS) - TRAIL(COLUMN) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(COLUMN) - GENPTR_REAL(RNULL) - GENPTR_DOUBLE(DNULL) - GENPTR_INTEGER(MXSIZE) - GENPTR_BYTE_ARRAY(COLDATA) - GENPTR_INTEGER(NELEM) - char *column; - - astAt( "AST_GETCOLUMNDATA", NULL, 0 ); - astWatchSTATUS( - column = astString( COLUMN, COLUMN_length ); - astGetColumnData( astI2P( *THIS ), column, *RNULL, *DNULL, *MXSIZE, - (void *) COLDATA, NELEM ); - astFree( column ); - ) -} - -F77_SUBROUTINE(ast_putcolumndata)( INTEGER(THIS), - CHARACTER(COLUMN), - INTEGER(CLEN), - INTEGER(SIZE), - BYTE_ARRAY(COLDATA), - INTEGER(STATUS) - TRAIL(COLUMN) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(COLUMN) - GENPTR_INTEGER(CLEN) - GENPTR_INTEGER(SIZE) - GENPTR_BYTE_ARRAY(COLDATA) - char *column; - - astAt( "AST_PUTCOLUMNDATA", NULL, 0 ); - astWatchSTATUS( - column = astString( COLUMN, COLUMN_length ); - astPutColumnData( astI2P( *THIS ), column, *CLEN, *SIZE, (void *) COLDATA ); - astFree( column ); - ) -} - diff --git a/ast/ffluxframe.c b/ast/ffluxframe.c deleted file mode 100644 index ab55e80..0000000 --- a/ast/ffluxframe.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -*+ -* Name: -* ffluxframe.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST FluxFrame class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the FluxFrame class. - -* Routines Defined: -* AST_ISAFLUXFRAME -* AST_FLUXFRAME - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 1-DEC-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "fluxframe.h" /* C interface to the FluxFrame class */ - -F77_LOGICAL_FUNCTION(ast_isafluxframe)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAFLUXFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAFluxFrame( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_fluxframe)( DOUBLE(SPECVAL), - INTEGER(SPECFRM), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_DOUBLE(SPECVAL) - GENPTR_INTEGER(SPECFRM) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_FLUXFRAME", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astFluxFrame( *SPECVAL, astI2P( *SPECFRM ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - diff --git a/ast/fframe.c b/ast/fframe.c deleted file mode 100644 index 6a71cc1..0000000 --- a/ast/fframe.c +++ /dev/null @@ -1,514 +0,0 @@ -/* -*+ -* Name: -* fframe.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Frame class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Frame class. - -* Routines Defined: -* AST_ANGLE -* AST_AXANGLE -* AST_AXDISTANCE -* AST_AXOFFSET -* AST_CONVERT -* AST_DISTANCE -* AST_FORMAT -* AST_FRAME -* AST_GETACTIVEUNIT -* AST_INTERSECT -* AST_ISAFRAME -* AST_NORM -* AST_OFFSET -* AST_OFFSET2 -* AST_PERMAXES -* AST_PICKAXES -* AST_RESOLVE -* AST_SETACTIVEUNIT -* AST_UNFORMAT - -* Copyright: -* Copyright (C) 1997-2009 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 23-JUL-1996 (RFWS): -* Original version. -* 16-SEP-1996 (RFWS): -* Added AST_DISTANCE and AST_OFFSET. -* 25-FEB-1998 (RFWS): -* Added AST_UNFORMAT. -* 21-JUN-2001 (DSB): -* Added AST_ANGLE and AST_OFFSET2. -* 29-AUG-2001 (DSB): -* Added AST_AXDISTANCE and AST_AXOFFSET. -* 9-SEP-2001 (DSB): -* Added AST_RESOLVE and AST_BEAR. -* 21-SEP-2001 (DSB): -* Replaced AST_BEAR by AST_AXANGLE. -* 17-DEC-2002 (DSB): -* Added AST_GETACTIVEUNIT and AST_SETACTIVEUNIT. -* 14-JAN-2009 (DSB): -* Added AST_INTERSECT. -* 26-OCT-2016 (DSB): -* Added method AST_AXNORM. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "mapping.h" /* C interface to the Mapping class */ -#include "frame.h" /* C interface to the Frame class */ - - -F77_INTEGER_FUNCTION(ast_convert)( INTEGER(FROM), - INTEGER(TO), - CHARACTER(NAMELIST), - INTEGER(STATUS) - TRAIL(NAMELIST) ) { - GENPTR_INTEGER(FROM) - GENPTR_INTEGER(TO) - GENPTR_INTEGER(NAMELIST) - F77_INTEGER_TYPE(RESULT); - char *namelist; - - astAt( "AST_CONVERT", NULL, 0 ); - astWatchSTATUS( - namelist = astString( NAMELIST, NAMELIST_length ); - RESULT = astP2I( astConvert( astI2P( *FROM ), astI2P( *TO ), - namelist ) ); - namelist = astFree( namelist ); - ) - return RESULT; -} - -F77_DOUBLE_FUNCTION(ast_angle)( INTEGER(THIS), - DOUBLE_ARRAY(A), - DOUBLE_ARRAY(B), - DOUBLE_ARRAY(C), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(A) - GENPTR_DOUBLE_ARRAY(B) - GENPTR_DOUBLE_ARRAY(C) - F77_DOUBLE_TYPE(RESULT); - - astAt( "AST_ANGLE", NULL, 0 ); - astWatchSTATUS( - RESULT = astAngle( astI2P( *THIS ), A, B, C ); - ) - return RESULT; -} - -F77_DOUBLE_FUNCTION(ast_axangle)( INTEGER(THIS), - DOUBLE_ARRAY(A), - DOUBLE_ARRAY(B), - INTEGER(AXIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(A) - GENPTR_DOUBLE_ARRAY(B) - GENPTR_INTEGER(AXIS) - F77_DOUBLE_TYPE(RESULT); - - astAt( "AST_AXANGLE", NULL, 0 ); - astWatchSTATUS( - RESULT = astAxAngle( astI2P( *THIS ), A, B, *AXIS ); - ) - return RESULT; -} - -F77_DOUBLE_FUNCTION(ast_distance)( INTEGER(THIS), - DOUBLE_ARRAY(POINT1), - DOUBLE_ARRAY(POINT2), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(POINT1) - GENPTR_DOUBLE_ARRAY(POINT2) - F77_DOUBLE_TYPE(RESULT); - - astAt( "AST_DISTANCE", NULL, 0 ); - astWatchSTATUS( - RESULT = astDistance( astI2P( *THIS ), POINT1, POINT2 ); - ) - return RESULT; -} - -F77_DOUBLE_FUNCTION(ast_axdistance)( INTEGER(THIS), - INTEGER(AXIS), - DOUBLE(V1), - DOUBLE(V2), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(AXIS) - GENPTR_DOUBLE(V1) - GENPTR_DOUBLE(V2) - F77_DOUBLE_TYPE(RESULT); - - astAt( "AST_AXDISTANCE", NULL, 0 ); - astWatchSTATUS( - RESULT = astAxDistance( astI2P( *THIS ), *AXIS, *V1, *V2 ); - ) - return RESULT; -} - -F77_DOUBLE_FUNCTION(ast_axoffset)( INTEGER(THIS), - INTEGER(AXIS), - DOUBLE(V1), - DOUBLE(DIST), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(AXIS) - GENPTR_DOUBLE(V1) - GENPTR_DOUBLE(DIST) - F77_DOUBLE_TYPE(RESULT); - - astAt( "AST_AXOFFSET", NULL, 0 ); - astWatchSTATUS( - RESULT = astAxOffset( astI2P( *THIS ), *AXIS, *V1, *DIST ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_findframe)( INTEGER(TARGET), - INTEGER(TEMPLATE), - CHARACTER(NAMELIST), - INTEGER(STATUS) - TRAIL(NAMELIST) ) { - GENPTR_INTEGER(TARGET) - GENPTR_INTEGER(TEMPLATE) - GENPTR_INTEGER(NAMELIST) - F77_INTEGER_TYPE(RESULT); - char *namelist; - - astAt( "AST_FINDFRAME", NULL, 0 ); - astWatchSTATUS( - namelist = astString( NAMELIST, NAMELIST_length ); - RESULT = astP2I( astFindFrame( astI2P( *TARGET ), astI2P( *TEMPLATE ), - namelist ) ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_matchaxes)( INTEGER(FRM1), - INTEGER(FRM2), - INTEGER_ARRAY(AXES), - INTEGER(STATUS) ) { - GENPTR_INTEGER(FRM1) - GENPTR_INTEGER(FRM2) - GENPTR_INTEGER_ARRAY(AXES) - - astAt( "AST_MATCHAXES", NULL, 0 ); - astWatchSTATUS( - astMatchAxes( astI2P( *FRM1 ), astI2P( *FRM2 ), AXES ); - ) -} - -/* NO_CHAR_FUNCTION indicates that the f77.h method of returning a - character result doesn't work, so add an extra argument instead and - wrap this function up in a normal FORTRAN 77 function (in the file - frame.f). */ -#if NO_CHAR_FUNCTION -F77_SUBROUTINE(ast_format_a)( CHARACTER(RESULT), -#else -F77_SUBROUTINE(ast_format)( CHARACTER_RETURN_VALUE(RESULT), -#endif - INTEGER(THIS), - INTEGER(AXIS), - DOUBLE(VALUE), - INTEGER(STATUS) -#if NO_CHAR_FUNCTION - TRAIL(RESULT) -#endif - ) { - GENPTR_CHARACTER(RESULT) - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(AXIS) - GENPTR_DOUBLE(VALUE) - const char *result; - int i; - - astAt( "AST_FORMAT", NULL, 0 ); - astWatchSTATUS( - result = astFormat( astI2P( *THIS ), *AXIS, *VALUE ); - i = 0; - if ( astOK ) { /* Copy result */ - for ( ; result[ i ] && i < RESULT_length; i++ ) { - RESULT[ i ] = result[ i ]; - } - } - while ( i < RESULT_length ) RESULT[ i++ ] = ' '; /* Pad with blanks */ - ) -} - -F77_INTEGER_FUNCTION(ast_frame)( INTEGER(NAXES), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NAXES) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_FRAME", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exclude any trailing spaces. */ - astChrTrunc( options ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astFrame( *NAXES, "%s", options ) ); - (void) astFree( options ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_isaframe)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAFrame( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_getactiveunit)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_GETACTIVEUNIT", NULL, 0 ); - astWatchSTATUS( - RESULT = astGetActiveUnit( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_SUBROUTINE(ast_setactiveunit)( INTEGER(THIS), - LOGICAL(VALUE), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_LOGICAL(VALUE) - - astAt( "AST_SETACTIVEUNIT", NULL, 0 ); - astWatchSTATUS( - astSetActiveUnit( astI2P( *THIS ), F77_ISTRUE( *VALUE ) ? 1 : 0 ); - ) -} - -F77_SUBROUTINE(ast_norm)( INTEGER(THIS), - DOUBLE_ARRAY(VALUE), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(VALUE) - - astAt( "AST_NORM", NULL, 0 ); - astWatchSTATUS( - astNorm( astI2P( *THIS ), VALUE ); - ) -} - -F77_SUBROUTINE(ast_offset)( INTEGER(THIS), - DOUBLE_ARRAY(POINT1), - DOUBLE_ARRAY(POINT2), - DOUBLE(OFFSET), - DOUBLE_ARRAY(POINT3), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(POINT1) - GENPTR_DOUBLE_ARRAY(POINT2) - GENPTR_DOUBLE(OFFSET) - GENPTR_DOUBLE_ARRAY(POINT3) - - astAt( "AST_OFFSET", NULL, 0 ); - astWatchSTATUS( - astOffset( astI2P( *THIS ), POINT1, POINT2, *OFFSET, POINT3 ); - ) -} - -F77_DOUBLE_FUNCTION(ast_offset2)( INTEGER(THIS), - DOUBLE_ARRAY(POINT1), - DOUBLE(ANGLE), - DOUBLE(OFFSET), - DOUBLE_ARRAY(POINT2), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(POINT1) - GENPTR_DOUBLE(ANGLE) - GENPTR_DOUBLE(OFFSET) - GENPTR_DOUBLE_ARRAY(POINT2) - F77_DOUBLE_TYPE(RESULT); - - astAt( "AST_OFFSET2", NULL, 0 ); - astWatchSTATUS( - RESULT = astOffset2( astI2P( *THIS ), POINT1, *ANGLE, *OFFSET, POINT2 ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_resolve)( INTEGER(THIS), - DOUBLE_ARRAY(POINT1), - DOUBLE_ARRAY(POINT2), - DOUBLE_ARRAY(POINT3), - DOUBLE_ARRAY(POINT4), - DOUBLE(D1), - DOUBLE(D2), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(POINT1) - GENPTR_DOUBLE_ARRAY(POINT2) - GENPTR_DOUBLE_ARRAY(POINT3) - GENPTR_DOUBLE_ARRAY(POINT4) - GENPTR_DOUBLE(D1) - GENPTR_DOUBLE(D2) - - astAt( "AST_RESOLVE", NULL, 0 ); - astWatchSTATUS( - astResolve( astI2P( *THIS ), POINT1, POINT2, POINT3, POINT4, D1, D2 ); - ) -} - -F77_SUBROUTINE(ast_intersect)( INTEGER(THIS), - DOUBLE_ARRAY(A1), - DOUBLE_ARRAY(A2), - DOUBLE_ARRAY(B1), - DOUBLE_ARRAY(B2), - DOUBLE_ARRAY(CROSS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(A1) - GENPTR_DOUBLE_ARRAY(A2) - GENPTR_DOUBLE_ARRAY(B1) - GENPTR_DOUBLE_ARRAY(B2) - GENPTR_DOUBLE_ARRAY(CROSS) - - astAt( "AST_INTERSECT", NULL, 0 ); - astWatchSTATUS( - astIntersect( astI2P( *THIS ), A1, A2, B1, B2, CROSS ); - ) -} - -F77_SUBROUTINE(ast_permaxes)( INTEGER(THIS), - INTEGER_ARRAY(PERM), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER_ARRAY(PERM) - - astAt( "AST_PERMAXES", NULL, 0 ); - astWatchSTATUS( - astPermAxes( astI2P( *THIS ), PERM ); - ) -} - -F77_INTEGER_FUNCTION(ast_pickaxes)( INTEGER(THIS), - INTEGER(NAXES), - INTEGER_ARRAY(AXES), - INTEGER(MAP), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(NAXES) - GENPTR_INTEGER_ARRAY(AXES) - GENPTR_INTEGER(MAP) - F77_INTEGER_TYPE(RESULT); - AstMapping *map; - - astAt( "AST_PICKAXES", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astPickAxes( astI2P( *THIS ), *NAXES, AXES, &map ) ); - *MAP = astP2I( map ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_unformat)( INTEGER(THIS), - INTEGER(AXIS), - CHARACTER(STRING), - DOUBLE(VALUE), - INTEGER(STATUS) - TRAIL(STRING) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(AXIS) - GENPTR_CHARACTER(STRING) - GENPTR_DOUBLE(VALUE) - GENPTR_INTEGER(STATUS) - F77_INTEGER_TYPE(RESULT); - char *string; - double value; - - astAt( "AST_UNFORMAT", NULL, 0 ); - astWatchSTATUS( - string = astString( STRING, STRING_length ); - - RESULT = astUnformat( astI2P( *THIS ), *AXIS, string, &value ); - *VALUE = value; - (void) astFree( string ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_axnorm)( INTEGER(THIS), - INTEGER(AXIS), - INTEGER(OPER), - INTEGER(NVAL), - DOUBLE(VALUES), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(AXIS) - GENPTR_INTEGER(OPER) - GENPTR_INTEGER(NVAL) - GENPTR_DOUBLE(VALUES) - - astAt( "AST_AXNORM", NULL, 0 ); - astWatchSTATUS( - astAxNorm( astI2P( *THIS ), *AXIS, *OPER, *NVAL, VALUES ); - ) -} diff --git a/ast/fframeset.c b/ast/fframeset.c deleted file mode 100644 index 1698847..0000000 --- a/ast/fframeset.c +++ /dev/null @@ -1,214 +0,0 @@ -/* -*+ -* Name: -* fframeset.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST FrameSet class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the FrameSet class. - -* Routines Defined: -* AST_ADDFRAME -* AST_ADDVARIANT -* AST_MIRRORVARIANTS -* AST_FRAMESET -* AST_GETFRAME -* AST_GETMAPPING -* AST_ISAFRAMESET -* AST_REMAPFRAME -* AST_REMOVEFRAME - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 1-AUG-1996 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "mapping.h" /* C interface to the Mapping class */ -#include "frame.h" /* C interface to the Frame class */ -#include "frameset.h" /* C interface to the FrameSet class */ - -F77_SUBROUTINE(ast_addframe)( INTEGER(THIS), - INTEGER(IFRAME), - INTEGER(MAP), - INTEGER(FRAME), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(IFRAME) - GENPTR_INTEGER(MAP) - GENPTR_INTEGER(FRAME) - - astAt( "AST_ADDFRAME", NULL, 0 ); - astWatchSTATUS( - astAddFrame( astI2P( *THIS ), *IFRAME, astI2P( *MAP ), - astI2P( *FRAME ) ); - ) -} - -F77_INTEGER_FUNCTION(ast_frameset)( INTEGER(FRAME), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_FRAMESET", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astFrameSet( astI2P( *FRAME ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_getframe)( INTEGER(THIS), - INTEGER(IFRAME), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(IFRAME) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetFrame( astI2P( *THIS ), *IFRAME ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_getmapping)( INTEGER(THIS), - INTEGER(IFRAME1), - INTEGER(IFRAME2), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(IFRAME1) - GENPTR_INTEGER(IFRAME2) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETMAPPING", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetMapping( astI2P( *THIS ), *IFRAME1, *IFRAME2 ) ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_isaframeset)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAFRAMESET", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAFrameSet( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_SUBROUTINE(ast_remapframe)( INTEGER(THIS), - INTEGER(IFRAME), - INTEGER(MAP), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(IFRAME) - GENPTR_INTEGER(MAP) - - astAt( "AST_REMAPFRAME", NULL, 0 ); - astWatchSTATUS( - astRemapFrame( astI2P( *THIS ), *IFRAME, astI2P( *MAP ) ); - ) -} - -F77_SUBROUTINE(ast_removeframe)( INTEGER(THIS), - INTEGER(IFRAME), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(IFRAME) - - astAt( "AST_REMOVEFRAME", NULL, 0 ); - astWatchSTATUS( - astRemoveFrame( astI2P( *THIS ), *IFRAME ); - ) -} - -F77_SUBROUTINE(ast_addvariant)( INTEGER(THIS), - INTEGER(MAP), - CHARACTER(NAME), - INTEGER(STATUS) - TRAIL(NAME) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(MAP) - GENPTR_CHARACTER(NAME) - char *name; - - astAt( "AST_ADDVARIANT", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - astAddVariant( astI2P( *THIS ), astI2P( *MAP ), name ); - name = astFree( name ); - ) -} - -F77_SUBROUTINE(ast_mirrorvariants)( INTEGER(THIS), - INTEGER(IFRAME), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(IFRAME) - - astAt( "AST_MIRRORVARIANTS", NULL, 0 ); - astWatchSTATUS( - astMirrorVariants( astI2P( *THIS ), *IFRAME ); - ) -} - diff --git a/ast/fgrismmap.c b/ast/fgrismmap.c deleted file mode 100644 index f26159c..0000000 --- a/ast/fgrismmap.c +++ /dev/null @@ -1,99 +0,0 @@ -/* -*+ -* Name: -* fgrismmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST GrismMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the GrismMap class. - -* Routines Defined: -* AST_ISAGRISMMAP -* AST_GRISMMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 10-JUL-2003 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "grismmap.h" /* C interface to the GrismMap class */ - -F77_LOGICAL_FUNCTION(ast_isagrismmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAGRISMMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAGrismMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_grismmap)( CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_GRISMMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astGrismMap( "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/finterval.c b/ast/finterval.c deleted file mode 100644 index 7023868..0000000 --- a/ast/finterval.c +++ /dev/null @@ -1,109 +0,0 @@ -/* -*+ -* Name: -* finterval.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Interval class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Interval class. - -* Routines Defined: -* AST_ISAINTERVAL -* AST_INTERVAL - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 31-AUG-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "interval.h" /* C interface to the Interval class */ - - -F77_LOGICAL_FUNCTION(ast_isainterval)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAINTERVAL", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAInterval( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_interval)( INTEGER(FRAME), - DOUBLE_ARRAY(LBND), - DOUBLE_ARRAY(UBND), - INTEGER(UNC), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_DOUBLE_ARRAY(LBND) - GENPTR_DOUBLE_ARRAY(UBND) - GENPTR_INTEGER(UNC) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_INTERVAL", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - - RESULT = astP2I( astInterval( astI2P( *FRAME ), LBND, UBND, - astI2P( *UNC ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fintramap.c b/ast/fintramap.c deleted file mode 100644 index cdf3e4e..0000000 --- a/ast/fintramap.c +++ /dev/null @@ -1,332 +0,0 @@ -/* -*+ -* Name: -* fintramap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST IntraMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the IntraMap class. - -* Routines Defined: -* AST_INTRAMAP -* AST_INTRAREG -* AST_ISAINTRAMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 18-MAR-1998 (RFWS): -* Original version. -* 15-SEP-1999 (RFWS): -* Added a THIS pointer to the external transformation function -* used by an IntraMap. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "intramap.h" /* C interface to the IntraMap class */ - -#include -#include - -/* Prototypes for private functions. */ -/* ================================= */ -static void TranWrap( void (*)( AstMapping *, int, int, const double *[], int, int, double *[] ), AstMapping *, int, int, const double *[], int, int, double *[], int * ); - -/* Transformation function interface. */ -/* ================================== */ -/* This is concerned with allowing FORTRAN implementations of - transformation functions to be passed to the IntraMap class and - invoked when necessary by C code in the main class - implementation. All FORTRAN-specific aspects of this interface are - encapsulated here. */ -static void TranWrap( void (* tran)( AstMapping *, int, int, const double *[], - int, int, double *[] ), - AstMapping *this, int npoint, int ncoord_in, - const double *ptr_in[], int forward, int ncoord_out, - double *ptr_out[], int *status ) { -/* -* Name: -* TranWrap - -* Purpose: -* Wrapper function to invoke a FORTRAN transformation function. - -* Type: -* Private function. - -* Synopsis: -* void TranWrap( void (* tran)( AstMapping *, int, int, const double *[], -* int, int, double *[] ), -* AstMapping *this, int npoint, int ncoord_in, -* const double *ptr_in[], int forward, int ncoord_out, -* double *ptr_out[], int *status ) - -* Description: -* This function invokes a FORTRAN implementation of a -* transformation function (which resembles AST_TRANN from the -* Mapping class FORTRAN interface) in order to make it callable by -* C code which would prefer to call a C function that resembles -* astTranP (from the Mapping class C interface). - -* Parameters: -* tran -* Pointer to the FORTRAN transformation function to be invoked. -* This should result from a cast applied to a pointer to a -* function that resembles AST_TRANN (but with the first -* argument omitted). -* this -* An external Mapping ID associated with the internal (true C) pointer -* for the IntraMap whose transformation is being evaluated. -* npoint -* The number of points to be transformed. -* ncoord_in -* The number of coordinates being supplied for each input point -* (i.e. the number of dimensions of the space in which the -* input points reside). -* ptr_in -* An array of pointers to double, with "ncoord_in" -* elements. Element "ptr_in[coord]" should point at the first -* element of an array of double (with "npoint" elements) which -* contain the values of coordinate number "coord" for each -* input (untransformed) point. The value of coordinate number -* "coord" for input point number "point" is therefore given by -* "ptr_in[coord][point]". -* forward -* A non-zero value indicates that the forward coordinate -* transformation is to be applied, while a zero value indicates -* that the inverse transformation should be used. -* ncoord_out -* The number of coordinates being generated for each output -* point (i.e. the number of dimensions of the space in which -* the output points reside). This need not be the same as -* "ncoord_in". -* ptr_out -* An array of pointers to double, with "ncoord_out" -* elements. Element "ptr_out[coord]" should point at the first -* element of an array of double (with "npoint" elements) into -* which the values of coordinate number "coord" for each output -* (transformed) point will be written. The value of coordinate -* number "coord" for output point number "point" will therefore -* be found in "ptr_out[coord][point]". -* status -* Pointer to the inherited status value. -*/ - -/* Local Variables; */ - DECLARE_INTEGER(INDIM); /* First dimension size of input array */ - DECLARE_INTEGER(NCOORD_IN); /* Number of input coordinates */ - DECLARE_INTEGER(NCOORD_OUT); /* Number of output coordinates */ - DECLARE_INTEGER(NPOINT); /* Number of points */ - DECLARE_INTEGER(OUTDIM); /* First dimension size of output array */ - DECLARE_INTEGER(STATUS); /* FORTRAN error status variable */ - DECLARE_INTEGER(THIS); /* External ID for the IntraMap */ - DECLARE_LOGICAL(FORWARD); /* Use forward transformation? */ - F77_DOUBLE_TYPE *IN; /* Input coordinate array for FORTRAN */ - F77_DOUBLE_TYPE *OUT; /* Output coordinate array for FORTRAN */ - int coord; /* Loop counter for coordinates */ - int i; /* Index into FORTRAN arrays */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Assign input values to the arguments for the FORTRAN transformation - function. */ - THIS = astP2I( this ); - NPOINT = npoint; - NCOORD_IN = ncoord_in; - INDIM = npoint; - FORWARD = forward ? F77_TRUE : F77_FALSE; - NCOORD_OUT = ncoord_out; - OUTDIM = npoint; - -/* Since the input/output coordinate values may be stored in separate - arrays, we must move them temporarily into new 2-dimensional - arrays, as required by the FORTRAN transformation function - interface. Allocate memory for these arrays. */ - IN = astMalloc( (size_t) ( npoint * ncoord_in ) * - sizeof( F77_DOUBLE_TYPE ) ); - OUT = astMalloc( (size_t) ( npoint * ncoord_out ) * - sizeof( F77_DOUBLE_TYPE ) ); - -/* If OK, fill the input array with coordinate values. Use "memcpy" to - avoid numerical errors if the data contain junk - this allows the - transformation function to produce the appropriate error instead of - it happening here. */ - if ( astOK ) { - i = 0; - for ( coord = 0; coord < ncoord_in; coord++ ) { - (void) memcpy( IN + i, ptr_in[ coord ], - (size_t) npoint * sizeof( F77_DOUBLE_TYPE ) ); - i += npoint; - } - } - -/* Cast the transformation function pointer to a pointer to the - FORTRAN subroutine and then invoke it. Transfer the AST error - status to and from the subroutine's error status argument. */ - if ( astOK ) { - STATUS = astStatus; - ( *(void (*)()) tran )( INTEGER_ARG(&THIS), - INTEGER_ARG(&NPOINT), - INTEGER_ARG(&NCOORD_IN), - INTEGER_ARG(&INDIM), - DOUBLE_ARRAY_ARG(IN), - LOGICAL_ARG(&FORWARD), - INTEGER_ARG(&NCOORD_OUT), - INTEGER_ARG(&OUTDIM), - DOUBLE_ARRAY_ARG(OUT), - INTEGER_ARG(&STATUS) ); - astSetStatus( STATUS ); - } - - -/* If OK, transfer the transformed coordinate values to the output - arrays. */ - if ( astOK ) { - i = 0; - for ( coord = 0; coord < ncoord_out; coord++ ) { - (void) memcpy( ptr_out[ coord ], OUT + i, - (size_t) npoint * sizeof( F77_DOUBLE_TYPE ) ); - i += npoint; - } - } - -/* Free the temporary arrays. */ - astFree( IN ); - astFree( OUT ); -} - -/* FORTRAN interface functions. */ -/* ============================ */ -/* These functions implement the remainder of the FORTRAN interface. */ -F77_SUBROUTINE(ast_intrareg)( CHARACTER(NAME), - INTEGER(NIN), - INTEGER(NOUT), - void (* TRAN)(), - INTEGER(FLAGS), - CHARACTER(PURPOSE), - CHARACTER(AUTHOR), - CHARACTER(CONTACT), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(PURPOSE) - TRAIL(AUTHOR) - TRAIL(CONTACT) ) { - GENPTR_CHARACTER(NAME) - GENPTR_INTEGER(NIN) - GENPTR_INTEGER(NOUT) - GENPTR_INTEGER(FLAGS) - GENPTR_CHARACTER(PURPOSE) - GENPTR_CHARACTER(AUTHOR) - GENPTR_CHARACTER(CONTACT) - char *name; - void (* tran)( AstMapping *, int, int, const double *[], int, int, - double *[] ); - char *purpose; - char *author; - char *contact; - - astAt( "AST_INTRAREG", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - tran = - (void (*)( AstMapping *, int, int, const double *[], int, int, - double *[] )) TRAN; - purpose = astString( PURPOSE, PURPOSE_length ); - author = astString( AUTHOR, AUTHOR_length ); - contact = astString( CONTACT, CONTACT_length ); - astIntraRegFor( name, *NIN, *NOUT, tran, TranWrap, *FLAGS, purpose, - author, contact ); - astFree( name ); - astFree( purpose ); - astFree( author ); - astFree( contact ); - ) -} - -F77_INTEGER_FUNCTION(ast_intramap)( CHARACTER(NAME), - INTEGER(NIN), - INTEGER(NOUT), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(NAME) - GENPTR_INTEGER(NIN) - GENPTR_INTEGER(NOUT) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *name; - char *options; - int i; - - astAt( "AST_INTRAMAP", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astIntraMap( name, *NIN, *NOUT, "%s", options ) ); - astFree( name ); - astFree( options ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_isaintramap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAINTRAMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAIntraMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} diff --git a/ast/fitschan.c b/ast/fitschan.c deleted file mode 100644 index ae7c36e..0000000 --- a/ast/fitschan.c +++ /dev/null @@ -1,43747 +0,0 @@ -/* -*class++ -* Name: -* FitsChan - -* Purpose: -* I/O Channel using FITS header cards to represent Objects. - -* Constructor Function: -c astFitsChan -f AST_FITSCHAN - -* Description: -* A FitsChan is a specialised form of Channel which supports I/O -* operations involving the use of FITS (Flexible Image Transport -* System) header cards. Writing an Object to a FitsChan (using -c astWrite) will, if the Object is suitable, generate a -f AST_WRITE) will, if the Object is suitable, generate a -* description of that Object composed of FITS header cards, and -* reading from a FitsChan will create a new Object from its FITS -* header card description. -* -* While a FitsChan is active, it represents a buffer which may -* contain zero or more 80-character "header cards" conforming to -* FITS conventions. Any sequence of FITS-conforming header cards -* may be stored, apart from the "END" card whose existence is -* merely implied. The cards may be accessed in any order by using -* the FitsChan's integer Card attribute, which identifies a "current" -* card, to which subsequent operations apply. Searches -c based on keyword may be performed (using astFindFits), new -c cards may be inserted (astPutFits, astPutCards, astSetFits) and -c existing ones may be deleted (astDelFits), extracted (astGetFits), -c or changed (astSetFits). -f based on keyword may be performed (using AST_FINDFITS), new -f cards may be inserted (AST_PUTFITS, AST_PUTCARDS, AST_SETFITS) and -f existing ones may be deleted (AST_DELFITS), extracted -f (AST_GETFITS) or changed (AST_SETFITS). -* -* When you create a FitsChan, you have the option of specifying -* "source" and "sink" functions which connect it to external data -* stores by reading and writing FITS header cards. If you provide -* a source function, it is used to fill the FitsChan with header cards -* when it is accessed for the first time. If you do not provide a -* source function, the FitsChan remains empty until you explicitly enter -c data into it (e.g. using astPutFits, astPutCards, astWrite -f data into it (e.g. using AST_PUTFITS, AST_PUTCARDS, AST_WRITE -* or by using the SourceFile attribute to specifying a text file from -* which headers should be read). When the FitsChan is deleted, any -* remaining header cards in the FitsChan can be saved in either of -* two ways: 1) by specifying a value for the SinkFile attribute (the -* name of a text file to which header cards should be written), or 2) -* by providing a sink function (used to to deliver header cards to an -* external data store). If you do not provide a sink function or a -* value for SinkFile, any header cards remaining when the FitsChan -* is deleted will be lost, so you should arrange to extract them -* first if necessary -c (e.g. using astFindFits or astRead). -f (e.g. using AST_FINDFITS or AST_READ). -* -* Coordinate system information may be described using FITS header -* cards using several different conventions, termed -* "encodings". When an AST Object is written to (or read from) a -* FitsChan, the value of the FitsChan's Encoding attribute -* determines how the Object is converted to (or from) a -* description involving FITS header cards. In general, different -* encodings will result in different sets of header cards to -* describe the same Object. Examples of encodings include the DSS -* encoding (based on conventions used by the STScI Digitised Sky -* Survey data), the FITS-WCS encoding (based on a proposed FITS -* standard) and the NATIVE encoding (a near loss-less way of -* storing AST Objects in FITS headers). -* -* The available encodings differ in the range of Objects they can -* represent, in the number of Object descriptions that can coexist -* in the same FitsChan, and in their accessibility to other -* (external) astronomy applications (see the Encoding attribute -* for details). Encodings are not necessarily mutually exclusive -* and it may sometimes be possible to describe the same Object in -* several ways within a particular set of FITS header cards by -* using several different encodings. -* -c The detailed behaviour of astRead and astWrite, when used with -f The detailed behaviour of AST_READ and AST_WRITE, when used with -* a FitsChan, depends on the encoding in use. In general, however, -c all successful use of astRead is destructive, so that FITS header cards -f all successful use of AST_READ is destructive, so that FITS header cards -* are consumed in the process of reading an Object, and are -* removed from the FitsChan (this deletion can be prevented for -* specific cards by calling the -c astRetainFits function). -f AST_RETAINFITS routine). -* An unsuccessful call of -c astRead -f AST_READ -* (for instance, caused by the FitsChan not containing the necessary -* FITS headers cards needed to create an Object) results in the -* contents of the FitsChan being left unchanged. -* -* If the encoding in use allows only a single Object description -* to be stored in a FitsChan (e.g. the DSS, FITS-WCS and FITS-IRAF -c encodings), then write operations using astWrite will -f encodings), then write operations using AST_WRITE will -* over-write any existing Object description using that -* encoding. Otherwise (e.g. the NATIVE encoding), multiple Object -* descriptions are written sequentially and may later be read -* back in the same sequence. - -* Inheritance: -* The FitsChan class inherits from the Channel class. - -* Attributes: -* In addition to those attributes common to all Channels, every - -* FitsChan also has the following attributes: -* -* - AllWarnings: A list of the available conditions -* - Card: Index of current FITS card in a FitsChan -* - CardComm: The comment of the current FITS card in a FitsChan -* - CardName: The keyword name of the current FITS card in a FitsChan -* - CardType: The data type of the current FITS card in a FitsChan -* - CarLin: Ignore spherical rotations on CAR projections? -* - CDMatrix: Use a CD matrix instead of a PC matrix? -* - Clean: Remove cards used whilst reading even if an error occurs? -* - DefB1950: Use FK4 B1950 as default equatorial coordinates? -* - Encoding: System for encoding Objects as FITS headers -* - FitsAxisOrder: Sets the order of WCS axes within new FITS-WCS headers -* - FitsDigits: Digits of precision for floating-point FITS values -* - Iwc: Add a Frame describing Intermediate World Coords? -* - Ncard: Number of FITS header cards in a FitsChan -* - Nkey: Number of unique keywords in a FitsChan -* - PolyTan: Use PVi_m keywords to define distorted TAN projection? -* - SipReplace: Replace SIP inverse transformation? -* - SipOK: Use Spitzer Space Telescope keywords to define distortion? -* - SipReplace: Replace SIP inverse transformation? -* - TabOK: Should the FITS "-TAB" algorithm be recognised? -* - Warnings: Produces warnings about selected conditions - -* Functions: -c In addition to those functions applicable to all Channels, the -c following functions may also be applied to all FitsChans: -f In addition to those routines applicable to all Channels, the -f following routines may also be applied to all FitsChans: -* -c - astDelFits: Delete the current FITS card in a FitsChan -c - astEmptyFits: Delete all cards in a FitsChan -c - astFindFits: Find a FITS card in a FitsChan by keyword -c - astGetFits: Get a keyword value from a FitsChan -c - astGetTables: Retrieve any FitsTables from a FitsChan -c - astPurgeWCS: Delete all WCS-related cards in a FitsChan -c - astPutCards: Stores a set of FITS header card in a FitsChan -c - astPutFits: Store a FITS header card in a FitsChan -c - astPutTable: Store a single FitsTable in a FitsChan -c - astPutTables: Store multiple FitsTables in a FitsChan -c - astReadFits: Read cards in through the source function -c - astRemoveTables: Remove one or more FitsTables from a FitsChan -c - astRetainFits: Ensure current card is retained in a FitsChan -c - astSetFits: Store a new keyword value in a FitsChan -c - astShowFits: Display the contents of a FitsChan on standard output -c - astTableSource: Register a source function for FITS table access -c - astTestFits: Test if a keyword has a defined value in a FitsChan -c - astWriteFits: Write all cards out to the sink function -f - AST_DELFITS: Delete the current FITS card in a FitsChan -f - AST_EMPTYFITS: Delete all cards in a FitsChan -f - AST_FINDFITS: Find a FITS card in a FitsChan by keyword -f - AST_GETFITS: Get a keyword value from a FitsChan -f - AST_GETTABLES: Retrieve any FitsTables from a FitsChan -f - AST_PURGEWCS: Delete all WCS-related cards in a FitsChan -f - AST_PUTCARDS: Stores a set of FITS header card in a FitsChan -f - AST_PUTFITS: Store a FITS header card in a FitsChan -f - AST_PUTTABLE: Store a single FitsTables in a FitsChan -f - AST_PUTTABLES: Store multiple FitsTables in a FitsChan -f - AST_READFITS: Read cards in through the source function -f - AST_REMOVETABLES: Remove one or more FitsTables from a FitsChan -f - AST_RETAINFITS: Ensure current card is retained in a FitsChan -f - AST_SETFITS: Store a new keyword value in a FitsChan -c - AST_SHOWFITS: Display the contents of a FitsChan on standard output -f - AST_TABLESOURCE: Register a source function for FITS table access -f - AST_TESTFITS: Test if a keyword has a defined value in a FitsChan -f - AST_WRITEFITS: Write all cards out to the sink function - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2008-2011 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink, RAL) -* TIMJ: Tim Jenness (JAC, Hawaii) - -* History: -* 11-DEC-1996 (DSB): -* Original version. -* 20-MAR-1997 (DSB): -* Made keyword setting and getting functions protected instead of -* public. Renamed public methods. Added Ncard attribute. -* 20-MAY-1997 (RFWS): -* Tidied public prologues. -* 30-JUN-1997 (DSB): -* Added support for reading post-2000 DATE-OBS strings. Reading DSS -* or FITS-WCS objects now returns NULL unless the FitsChan is -* positioned at the start-of-file prior to the read. Bug fixed -* which caused Ncard to be returned too large by one. Removed -* dependancy on hard-wired header and footer text in Native -* FitsChans. -* 18-AUG-1997 (DSB): -* Bug fixed in WcsNative which caused incorrect CRVAL values -* to be used if the axes needed permuting. Values assigned to the -* Projection attribute fo the SkyFrames created by astRead. -* 2-SEP-1997 (DSB): -* Added the IRAF convention that EPOCH=0.0 really means EPOCH=1950.0 -* (the EPOCH keyword is deprecated in the new FITS-WCS conventions -* and is taken always as a Besselian epoch). -* 19-SEP-1997 (DSB): -* Corrected interpretation of the FITS CD matrix. -* 25-SEP-1997 (DSB): -* o Fix bug in LinearMap which caused it always to detect a linear -* mapping. For instance, this allowed DssMaps to be erroneously -* written out using FITS-WCS encoding with a CAR projection. -* o Assign a full textual description to SkyFrame's Projection -* attribute instead of a 3 letter acronym. -* o If DATE-OBS >= 1999.0 then DATE-OBS is now written in new -* Y2000 format. For DATE-OBS < 1999.0, the old format is written. -* o Add new attribute CDMatrix to determine whether PC or CD -* matrices should be used when writing objects using FITS-WCS -* encoding. -* o Modified the way floating point values are formatted to omit -* unnecessary leading zeros from the exponent (i.e. E-5 instead of -* E-05). -* o New-line characters at the end of supplied header cards are now -* ignored. -* o Cater for EQUINOX specified as a string prefixed by B or J -* rather than as a floating point value (some HST data does this). -* o Corrected SetValue so that it always inserts comment cards -* rather than over-write existing comment cards. Previously, -* writing a FrameSet to a DSS encoded FitsChan resulted in all -* comments cards being stripped except for the last one. -* o Reading a FrameSet from a DSS-encoded FrameSet now only -* removes the keywords actually required to construct the FrameSet. -* Previously, all keywords were removed. -* o The EPOCH and EQUINOX keywords created when a FrameSet is -* written to a DSS-encoded FitsChan are now determined from the -* epoch and equinox of the current Frame, instead of from a copy -* of the original FitsChan stored within the DssMap. -* o The Encoding and CDMatrix attributes, and keyword types are -* now stored as strings externally instead of integers. -* 11-NOV-1997 (DSB): -* o Assume default of j2000 for DSS EQUINOX value. -* o Check for null object pointers in the interfaces for -* virtual functions which execute even if an error has previously -* occurred. Otherwise, a segmentation violation can occur when -* trying to find the member function pointer. -* o Trailing spaces ignored in Encoding attribute. -* o Bugs fixed in FindWcs and SetValue which resulted in WCS cards -* being written at the wrong place if the supplied FitsChan does not -* contain any WCS keywords. -* o Default for CDMatrix (if no axis rotation keywords can be found) -* changed to 2 (i.e. use "CDi_j" form keywords). -* o Write now leaves the current card unchanged if nothing is -* written to the FitsChan. -* 17-NOV-1997 (RFWS): -* Disabled use of CDmatrix. Fixed initialisation problems in -* astLoadFitsChan. -* 24-NOV-1997 (DSB): -* Replace references to error code AST__OPT with AST__RDERR. -* 28-NOV-1997 (DSB): -* o Function WcsValues modified to prevent it from changing the -* current card. Previously, this could cause new cards to be -* written to the wrong place in a FITS-WCS encoded FitsChan. -* o Description of argument "value" corrected in prologue of -* function SetFits. -* o Argument "lastkey" removed from function SetValue since it -* was never used (it was a relic from a previous method of -* determining where to store new cards). Corresponding changes -* have been made to all the functions which create "lastkey" values -* or pass them on to SetValue (i.e DescWcs, WcsPrimary, WcsSecondary, -* WriteWcs and WriteDss). -* 10-DEC-1997 (DSB): -* Bug fixed which caused the initial character designating the system -* within CTYPE value (eg E in ELON, G in GLON, etc) to be omitted. -* 1-JUN-1998 (DSB): -* CDELT values of zero are now replaced by a small non-zero value -* when creating the "pixel-to-relative physical" transformation -* matrix. Previously, zero CDELT values could cause the matrix to -* be non-invertable. -* 4-SEP-1998 (DSB): -* - Indicate that SphMaps created by this class when using FITS-WCS -* encoding all operate on the unit sphere. This aids simplification. -* - Fix a bug in StoreFits which caused CD matrices to be indexed -* incorrectly (sometimes causing floating exceptions) if they do not -* describe a celestial longitude/latitude system. -* - Changed astFindFits to ignore trailing spaces in the keyword -* template. -* - astSplit changed so that an error is not reported if a textual -* keyword value ends before column 20. -* 7-OCT-1998 (DSB): -* - Corrected test for linearity in LinearMap to include a factor -* of the test vector length. Also LinearMap now uses a simplified -* Mapping. -* 5-NOV-1998 (DSB): -* Added FITS-IRAF encoding. -* 9-NOV-1998 (DSB): -* - Corrected values of macros DSS_ENCODING and MAX_ENCODING. -* - Corrected erroneous success indication in IrafStore. -* - Included checks for bad values in function LinearMap. -* 17-NOV-1998 (DSB): -* The Domain name GRID is now given to the Base Frame in any FrameSets -* created by astRead when using FitsChans with DSS, FITS-WCS or -* FITS-IRAF encodings. -* 18-DEC-1998 (DSB): -* Check for "D" exponents in floating point keyword strings. -* 12-FEB-1998 (DSB): -* Modified EncodeFloat to avoid exceeding the 20 character FITS -* limit wherever possible if FitsDigits is positive. -* 10-MAY-1998 (DSB): -* Bug fixed in astSplit which caused comments associated with string -* keywords to be lost when storing the card in a FitsChan. -* 15-JUN-1999 (DSB): -* Report an error if an unrecognised projection name is supplied. -* 9-DEC-1999 (DSB): -* - Fixed bug in WcsNatPole which could result in longitude values -* being out by 180 degrees for cylindrical projections such as CAR. -* - Only report an "unrecognised projection" error for CTYPE values -* which look like celestial longitude or latitude axes (i.e. if the -* first 4 characters are "RA--", "DEC-", "xLON" or "xLAT", and the -* fifth character is "-"). -* - Added function SpecTrans to translated keywords related to the -* IRAF ZPX projection into keyword for the standard ZPN projection. -* - Add ICRS as a valid value for the RADECSYS keyword. Since the -* SkyFrame class does not yet support ICRS, an FK5 SkyFrame is -* created if RADECSYS=ICRS. -* 16-DEC-1999 (DSB): -* - Modified SpecTrans so that all keywords used to created a -* standard WCS representation from a non-standard one are consumed -* by the astRead operation. -* - Changed the text of ASTWARN cards added to the FitsChan if an -* IRAF ZPX projection is found to require unsupported corrections. -* - Simplified the documentation describing the handling of the IRAF -* ZPX projection. -* - Fixed code which assumed that the 10 FITS-WCS projection -* parameters were PROJP1 -> PROJP10. In fact they are PROJP0 - -* PROJP9. This could cause projection parameter values to be -* incorrectly numbered when they are written out upon deletion of -* the FitsChan. -* 1-FEB-2000 (DSB): -* Check that FITS_IRAF encoding is not being used before using a -* PC matrix when reading WCS information from a header. This is -* important if the header contains both PC and CD matrices. -* 8-FEB-2000 (DSB): -* - Header cards are now only consumed by an astRead operation if the -* operation succeeds (i.e. returns a non-null Object). -* - The original FITS-WCS encoding has been renamed as FITS-PC (to -* indicate the use of a PCiiijjj matrix), and a new FITS-WCS -* encoding has been added. -* - The disabled CDMatrix attribute has been removed. -* - Bug in LinearMap corrected which prevented genuinely linear -* Mappings from being judged to be linear. This bug was previously -* fudged (so it now appears) by the introduction of the test vector -* length factor (see History entry for 7-OCT-1998). This test -* vector length scale factor has consequently now been removed. -* - Added FITS-AIPS encoding. -* - The critical keywords used to select default encoding have been -* changed. -* - Support for common flavours of IRAF TNX projections added. -* - The algorithm used to find a WcsMap in the supplied FrameSet -* has been improved so that compound Mappings which contain complex -* mixtures of parallel and serial Mappings can be translated into -* FITS-WCS encoding. -* - Trailing white space in string keyword values is now retained -* when using foreign encodings to enable correct concatenation where -* a string has been split over several keywords. E.g. if 2 string -* keywords contain a list of formatted numerical values (e.g. IRAF -* WAT... keywords), and the 1st one ends "0.123 " and the next one -* begins "1234.5 ", the trailing space at the end of the first keyword -* is needed to prevent the two numbers being merged into "0.1231234.5". -* Trailing spaces in native encodings is still protected by enclosing -* the whole string in double quotes. -* - The Channel methods WriteString and GetNextData can now save -* and restore strings of arbitary length. This is done by storing -* as much of the string as possible in the usual way, and then -* storing any remaining characters in subsequent CONTINUE cards, -* using the FITSIO conventions. This storage and retrieval of long -* strings is only available for native encodings. -* 19-MAY-2000 (DSB): -* Added attribute Warnings. Lowered DSS in the priority list -* of encodings implemented by GetEncoding. -* 6-OCT-2000 (DSB): -* Increased size of buffers used to store CTYPE values to take -* account of the possiblity of lots of trailing spaces. -* 5-DEC-2000 (DSB): -* Add support for the WCSNAME FITS keyword. -* 12-DEC-2000 (DSB): -* Add a title to each physical, non-celestial coord Frame based on -* its Domain name (if any). -* 3-APR-2001 (DSB): -* - Use an "unknown" celestial coordinate system, instead of a -* Cartesian coordinate system, if the CTYPE keywords specify an -* unknown celestial coordinate system. -* - Do not report an error if there are no CTYPE keywords in the -* header (assume a unit mapping, like in La Palma FITS files). -* - Add a NoCTYPE warning condition. -* - Added AllWarnings attribute. -* - Ensure multiple copies of identical warnings are not produced. -* - Use the Object Ident attribute to store the identifier letter -* associated with each Frame read from a secondary axis description, -* so that they can be given the same letter when they are written -* out to a new FITS file. -* 10-AUG-2001 (DSB): -* - Corrected function value returned by SkySys to be 1 unless an -* error occurs. This error resulted in CAR headers being produced -* by astWrite with CRVAL and CD values till in radians rather than -* degrees. -* - Introduced SplitMap2 in order to guard against producing -* celestial FITS headers for a Mapping which includes more than -* one WcsMap. -* 13-AUG-2001 (DSB): -* - Modified FixNew so that it retains the current card index if possible. -* This fixed a bug which could cause headers written out using Native -* encodings to be non-contiguous. -* - Corrected ComBlock to correctly remove AST comment blocks in -* native encoded fitschans. -* 14-AUG-2001 (DSB): -* - Modified FixUsed so that it it does not set the current card -* back to the start of file if the last card in the FitsChan is -* deleted. -* 16-AUG-2001 (DSB): -* Modified WcsNative to limit reference point latitude to range -* +/-90 degs (previously values outside this range were wrapped -* round onto the opposite meridian). Also added new warning -* condition "badlat". -* 23-AUG-2001 (DSB): -* - Re-write LinearMap to use a least squares fit. -* - Check that CDj_i is not AST__BAD within WcsWithWcs when -* forming the increments along each physical axis. -* 28-SEP-2001 (DSB): -* GoodWarns changed so that no error is reported if a blank list -* of conditions is supplied. -* 12-OCT-2001 (DSB): -* - Added DefB1950 attribute. -* - Corrected equations which calculate CROTA when writing -* FITS-AIPS encodings. -* - Corrected equations which turn a CROTA value into a CD matrix. -* 29-NOV-2001 (DSB): -* Corrected use of "_" and "-" characters when referring to FK4-NO-E -* system in function SkySys. -* 20-FEB-2002 (DSB) -* Added CarLin attribute. -* 8-MAY-2002 (DSB): -* Correct DSSToStore to ignore trailing blanks in the PLTDECSN -* keyword value. -* 9-MAY-2002 (DSB): -* Correct GetCard to avoid infinite loop if the current card has -* been marked as deleted. -* 25-SEP-2002 (DSB): -* AIPSFromStore: use larger of coscro and sincro when determining -* CDELT values. Previously a non-zero coscro was always used, even -* if it was a s small as 1.0E-17. -* 3-OCT-2002 (DSB): -* - SkySys: Corrected calculation of longitude axis index for unknown -* celestial systems. -* - SpecTrans: Corrected check for latcor terms for ZPX projections. -* - WcsFrame: Only store an explicit equinox value in a skyframe if -* it needs one (i.e. if the system is ecliptic or equatorial). -* - WcsWithWcs: For Zenithal projections, always use the default -* LONPOLE value, and absorb any excess rotation caused by this -* into the CD matrix. -* - WcsWithWcs: Improve the check that the native->celestial mapping -* is a pure rotation, allowing for rotations which change the -* handed-ness of the system (if possible). -* - WcsWithWcs: Avoid using LONPOLE keywords when creating headers -* for a zenithal projection. Instead, add the corresponding rotation -* into the CD matrix. -* 22-OCT-2002 (DSB): -* - Retain leading and trailing white space within COMMENT cards. -* - Only use CTYPE comments as axis labels if all non-celestial -* axes have a unique non-blank comment (otherwise use CTYPE -* values as labels). -* - Updated to use latest FITS-WCS projections. This means that the -* "TAN with projection terms" is no longer a standard FITS -* projection. It is now represented using the AST-specific TPN -* projection (until such time as FITS-WCS paper IV is finished). -* - Remove trailing "Z" from DATE-OBS values created by astWrite. -* 14-NOV-2002 (DSB): -* - WcsWithWcs: Corrected to ignore longitude axis returned by -* astPrimaryFrame since it does not take into account any axis -* permutation. -* 26-NOV-2002 (DSB): -* - SpecTrans: Corrected no. of characters copied from CTYPE to PRJ, -* (from 5 to 4), and terminate PRJ correctly. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitFitsChanVtab -* method. -* 22-JAN-2003 (DSB): -* Restructured the functions used for reading FITS_WCS headers to -* make the distinction between the generic parts (pixel->intermediate -* world coordinates) and the specialised parts (e.g. celestial, -* spectral, etc) clearer. -* 31-JAN-2003 (DSB) -* - Added Clean attribute. -* - Corrected initialisation and defaulting of CarLin and DefB1950 -* attributes. -* - Extensive changes to allow foreign encodings to be produced in -* cases where the Base Frame has fewer axes than the Current Frame. -* 12-FEB-2003 (DSB) -* - Modified SetFits so that the existing card comment is retained -* if the new data value equals the existing data value. -* 30-APR-2003 (DSB): -* - Revert to standard "TAN" code for distorted tan projections, -* rather than using the "TPN" code. Also recognise QVi_m (produced -* by AUTOASTROM) as an alternative to PVi_m when reading distorted -* TAN headers. -* 22-MAY-2003 (DSB): -* Modified GetEncoding so that the presence of RADECSYS and/or -* PROJPm is only considered significant if the modern equivalent -* keyword (REDESYS or PVi_m) is *NOT* present. -* 2-JUN-2003 (DSB): -* - Added support for PCi_j kewwords within FITS-WCS encoding -* - Added CDMatrix attribute -* - Changed internal FitsStore usage to use PC/CDELT instead of CD -* (as preparation for FITS-WCS paper IV). -* - Added warning "BadMat". -* 11-JUN-2003 (DSB): -* - Modified WcsNative to use the new SphMap PolarLong attribute -* in order to ensure correct propagation of the longitude CRVAL -* value in cases where the fiducial point is coincident with a pole. -* - Use PVi_3 and PVi_4 for longitude axis "i" (if present) in -* preference to LONPOLE and LATPOLE when reading a FITS-WCS header. -* Note, these projection values are never written out (LONPOLE and -* LATPOLE are written instead). -* - Associate "RADESYS=ICRS" with SkyFrame( "System=ICRS" ), rather -* than SkyFrame( "System=FK5" ). -* - If DefB1950 is zero, use ICRS instead of FK5 as the default RADESYS -* if no EQUINOX is present. -* 1-SEP-2003 (DSB): -* - Modify Dump so that it dumps all cards including those flagged as -* having been read. -* - Added "reset" parameter to FixUsed. -* - WcsMapFrm: store an Ident of ' ' for the primary coordinate -* description (previously Ident was left unset) -* - Default value for DefB1950 attribute now depends on the value -* of the Encoding attribute. -* 15-SEP-2003 (DSB): -* - Added Warnings "BadVal", "Distortion". -* - Ignore FITS-WCS paper IV CTYPE distortion codes (except for -* "-SIP" which is interpreted correctly on reading). -* 22-OCT-2003 (DSB): -* - GetEncoding: If the header contains CDi_j but does not contain -* any of the old IRAF keywords (RADECSYS, etc) then assume FITS-WCS -* encoding. This allows a FITS-WCS header to have both CDi_j *and* -* CROTA keywords. -* 5-JAN-2004 (DSB): -* - SpecTrans: Use 1.0 (instead of the CDELT value) as the -* diagonal PCi_j term for non-celestial axes with associated CROTA -* values. -* 12-JAN-2004 (DSB): -* - CelestialAxes: Initialise "tmap1" pointer to NULL in case of error -* (avoids a segvio happening in the case of an error). -* - AddVersion: Do not attempt to add a Frame into the FITS header -* if the mapping from grid to frame is not invertable. -* - WorldAxes: Initialise the returned "perm" values to safe values, -* and return these values if no basis vectors cen be created. -* 19-JAN-2004 (DSB): -* - When reading a FITS-WCS header, allow all keywords to be defaulted -* as decribed in paper I. -* 27-JAN-2004 (DSB): -* - Modify FitLine to use correlation between actual and estimated -* axis value as the test for linearity. -* - Modify RoundFString to avoid writing beyond the end of the -* supplied buffer if the supplied string contains a long list of 9's. -* 11-MAR-2004 (DSB): -* - Modified SpecTrans to check all axis descriptions for keywords -* to be translated. -* 19-MAR-2004 (DSB): -* - Added astPutCards to support new fits_hdr2str function in -* CFITSIO. -* 25-MAR-2004 (DSB): -* - Corrected bug in astSplit which causes legal cards to be -* rejected because characters beyond the 80 char limit are being -* considered significant. -* - Corrected bug in SpecTrans which caused QV keywords to be -* ignored. -* 15-APR-2004 (DSB): -* - SpecTrans modified to include translation of old "-WAV", "-FRQ" -* and "-VEL" spectral algorithm codes to modern "-X2P" form. -* - WcsFromStore modified to supress creation of WCSAXES keywords -* for un-used axis versions. -* - IsMapLinear modified to improve fit by doing a second least -* squares fit to the residualleft by the first least squares fit. -* 16-APR-2004 (DSB): -* - NonLinSpecWcs: Issue a warning if an illegal non-linear -* spectral code is encountered. -* - Add a BadCTYPE warning condition. -* - Corrected default value for Clean so that it is zero (as -* documented). -* 21-APR-2004 (DSB): -* - FindWcs: Corrected to use correct OBSGEO template. This bug -* caused OBSGEO keywords to be misplaced in written headers. -* 23-APR-2004 (DSB): -* - SplitMap: Modified so that a Mapping which has celestial axes -* with constant values (such as produced by a PermMap) are treated -* as a valid sky coordinate Mapping. -* - AddFrame modified so that WCS Frames with a different number -* of axes to the pixel Frame can be added into the FrameSet. -* - IRAFFromStore and AIPSFromStore modified so that they do not -* create any output keywords if the number of WCS axes is different -* to the number of pixel axes. -* - Handling of OBSGEO-X/Y/Z corrected again. -* - WCSFromStore modified to avouid writing partial axis descriptions. -* 26-APR-2004 (DSB): -* - Corrected text of output SPECSYS keyword values. -* 17-MAY-2004 (DSB): -* - Added IWC attribute. -* 15-JUN-2004 (DSB): -* - Ensure out-of-bounds longitude CRPIX values for CAR -* projections are wrapped back into bounds. -* 21-JUN-2004 (DSB): -* - Ensure primary MJD-OBS value is used when reading foreign FITS -* headers. -* 7-JUL-2004 (DSB): -* - Issue errors if an un-invertable PC/CD matrix is supplied in a -* FITS-WCS Header. -* 11-JUL-2004 (DSB): -* - Re-factor code for checking spectral axis CTYPE values into -* new function IsSpectral. -* - Modify AIPSFromSTore to create spectral axis keywords if -* possible. -* - Modify SpecTrans to recognize AIPS spectral axis keywords, and -* to convert "HZ" to "Hz". -* - Added FITS-AIPS++ encoding. -* 12-AUG-2004 (DSB): -* - Convert GLS projection codes to equivalent SFL in SpecTrans. -* - Added FITS-CLASS encoding. -* 16-AUG-2004 (DSB): -* - Removed support for paper III keyword VSOURCE, and added -* support for SSYSSRC keyword. -* - Added initial support for CLASS encoding. -* - In FitOK: Changed tolerance for detecting constant values -* from 1.0E-10 to 1.0E-8. -* 17-AUG-2004 (DSB): -* Correct GetFiducialNSC so that the stored values for longitude -* parameters 1 and 2 are ignored unless the value of parameter 0 is -* not zero. -* 19-AUG-2004 (DSB): -* Modify SpecTrans to ignore any CDELT values if the header -* includes some CDi_j values. -* 26-AUG-2004 (DSB): -* Modify astSplit_ to allow floating point keyword values which -* include an exponent to be specified with no decimal point -* (e.g. "2E-4"). -* 27-AUG-2004 (DSB): -* Completed initial attempt at a FITS-CLASS encoding. -* 9-SEP-2004 (DSB): -* Fixed usage of uninitialised values within ReadCrval. -* 13-SEP-2004 (DSB): -* Check the "text" pointer can be used safely before using it in -* DSSToStore. -* 27-SEP-2004 (DSB): -* In SpecTrans, before creating new PCi_j values, check that no -* PCi_j values have been created via an earlier translation. -* 28-SEP-2004 (DSB): -* In AIPSPPFromStore only get projection parameters values if there -* are some celestialaxes. Also allow CROTA to describe rotation of -* non-celestial axes (same for AIPSFromSTore). -* 4-OCT-2004 (DSB): -* Correct rounding of CRPIX in AddVersion to avoid integer overflow. -* 11-NOV-2004 (DSB): -* - WcsFcRead: Avoid issuing warnings about bad keywords which -* have already been translated into equivalent good forms. -* - SpecTrans: If both PROJP and PV keywords are present, use PV -* in favour of PROJP only if the PV values look correct. -* 17-NOV-2004 (DSB): -* - Make astSetFits public. -* 16-MAR-2005 (DSB): -* - Primary OBSGEO-X/Y/Z, MJD-AVG and MJDOBS keywords are associated -* with all axis descriptions and should not have a trailing single -* character indicating an alternate axis set. -* 9-AUG-2005 (DSB): -* In WcsMapFrm, check reffrm is used before annulling it. -* 8-SEP-2005 (DSB): -* - Change "if( a < b < c )" constructs to "if( a < b && b < c )" -* - DSBSetup: correct test on FrameSet pointer state -* - Ensure CLASS keywords written to a FitsChan do not come before -* the final fixed position keyword. -* 9-SEP-2005 (DSB): -* - Added "AZ--" and "EL--" as allowed axis types in FITS-WCS -* ctype values. -* 12-SEP-2005 (DSB): -* - Cast difference between two pointers to (int) -* - CLASSFromStore:Check source velocity is defined before -* storing it in the output header. -* 13-SEP-2005 (DSB): -* - Corrected B1940 to B1950 in AddEncodingFrame. This bug -* prevented some FrameSets being written out using FITS-CLASS. -* - Rationalise the use of the "mapping" pointer in AddVersion. -* - WcsCelestial: Modified so that the FITS reference point is -* stored as the SkyFrame SkyRef attribute value. -* 7-OCT-2005 (DSB): -* Make astGetFits public. -* 30-NOV-2005 (DSB): -* Add support for undefined FITS keyword values. -* 5-DEC-2005 (DSB): -* - Include an IMAGFREQ keyword in the output when writing a -* DSBSpecFrame out using FITS-WCS encoding. -* - Correct test for constant values in FitOK. -* 7-DEC-2005 (DSB): -* Free memory allocated by calls to astReadString. -* 30-JAN-2006 (DSB): -* Modify astSplit so that it does no read the supplied card beyond -* column 80. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 28-FEB-2006 (DSB): -* Correct documentation typo ("NCards" -> "Ncard"). -* 5-APR-2006 (DSB): -* Modify SpecTrans to convert CTYPE="LAMBDA" to CTYPE="WAVE". -* 26-MAY-2006 (DSB): -* Guard against NULL comment pointer when converting RESTFREQ to -* RESTFRQ in SpecTrans. -* 29-JUN-2006 (DSB): -* - Added astRetainFits. -* - Consume VELOSYS FITS-WCS keywords when reading an object. -* - Write out VELOSYS FITS-WCS keywords when writing an object. -* 7-AUG-2006 (DSB): -* Remove trailing spaces from the string returned by astGetFitsS -* if the original string contains 8 or fewer characters. -* 16-AUG-2006 (DSB): -* Document non-destructive nature of unsuccessful astRead calls. -* 17-AUG-2006 (DSB): -* Fix bugs so that the value of the Clean attribute is honoured -* even if an error has occurred. -* 4-SEP-2006 (DSB): -* Modify GetClean so that it ignores the inherited status. -* 20-SEP-2006 (DSB): -* Fix memory leak in WcsSpectral. -* 6-OCT-2006 (DSB): -* Modify IsSpectral and IsAIPSSpectral to allow for CTYPE values that -* are shorter than eight characters. -* 13-OCT-2006 (DSB): -* - Ensure SpecFrames and SkyFrames created from a foreign FITS header -* are consistent in their choice of Epoch. -* - Convert MJD-OBS and MJD-AVG values from TIMESYS timescale to -* TDB before using as the Epoch value in an AstFrame. Use UTC if -* TIMESYS is absent. -* - Convert Epoch values from TDB to UTC before storing as the -* value of an MJD-OBS or MJD-AVG keyword (no TIMESYS keyword is -* written). -* 23-OCT-2006 (DSB): -* Prefer MJD-AVG over MJD-OBS. -* 30-OCT-2006 (DSB): -* In FitOK: Changed lower limit on acceptbale correlation from -* 0.999999 to 0.99999. -* 1-NOV-2006 (DSB): -* - When reading a foreign header that contains a DUT1 keyword, -* use it to set the Dut1 attribute in the SkyFrame. Note, JACH -* store DUT1 in units of days. This may clash with the FITS-WCS -* standard (when its produced). Also note that DUT1 is not written -* out as yet when writing a FrameSet to a foreign FITS header. -* - Correct bug that prevented ZSOURCE keyword being added to the -* output header if the source velocity was negative. -* 9-NOV-2006 (DSB): -* Add STATUS argument to docs for F77 AST_SETx. -* 20-DEC-2006 (DSB): -* Correct FK5 to ICRS in error message issued if no RADESYS or -* EQUINOX is found. -* 16-JAN-2007 (DSB): -* Cast ignored function return values to (void) to avoid compiler -* warnings. -* 31-JAN-2007 (DSB): -* Change SpecTrans to ignore blank unit strings (previously -* converted them to "Hz"). -* 16-APR-2007 (DSB): -* In SplitMat, increase the allowed level of rounding erros from -* 1.0E-10 to 1.0E-7 (to avoid spurious low CDi_j values being -* created that should be zero). -* 30-APR-2007 (DSB): -* - Change DSBSetup so that the central DSBSpecFrame frequency is -* CRVAL and the IF is the difference between CRVAL and LO. -* - Change tolerance in FitOK from 0.99999 to 0.995 to handle data from Nicolas -* Peretto. -* 1-MAY-2007 (DSB): -* - In astSplit, if a keyword value looks like an int but is too long to -* fit in an int, then treat it as a float instead. -* 18-MAY-2007 (DSB): -* In CnvType, use input type rather than output type when checking -* for a COMMENT card. Also, return a null data value buffer for a -* COMMENT card. -* 4-JUN-2007 (DSB): -* In CLASSFromStore, create a DELTAV header even if it is equal to -* the spectral CDELT value. Also, convert spatial reference point -* to (az,el) and write out as headers AZIMUTH and ELEVATIO. -* 9-JUL-2007 (DSB): -* Fixed bug in DSBSetUp - previously, this function assumed that -* the supplied DSBSpecFrame represented frequency, and so gave -* incorrect values for IF and DSBCentre if the header described -* velocity. -* 9-AUG-2007 (DSB): -* Changed GetEncoding so that critcal keywords are ignored if -* there are no CTYPE, CRPIX or CRVAL keywords in the header. -* 10-AUG-2007 (DSB): -* - Changed GetEncoding so that FITS_PC is not returned if there are -* any CDi_j or PCi_j keywords in the header. -* - Added astPurgeWCS method. -* 13-AUG-2007 (DSB): -* - Include the DSS keywords AMDX%d and AMDY%d in FindWCS. -* 16-AUG-2007 (DSB): -* - Force all FITS-CLASS headers to contain frequency axes -* (velocity axes seem not to be recognised properly by CLASS). -* - Change the CLASS "VELO-LSR" header to be the velocity at the -* reference channel, not the source velocity. -* 22-AUG-2007 (DSB): -* - Remove debugging printf statements. -* 20-SEP-2007 (DSB): -* Changed FitOK to check that the RMS residual is not more than -* a fixed small fraction of the pixel size. -* 4-DEC-2007 (DSB): -* Changed CreateKeyword so that it uses a KeyMap to search for -* existing keywords. This is much faster than checking every -* FitsCard in the FitsChan explicitly. -* 18-DEC-2007 (DSB): -* Add keyword VLSR to the CLASS encoding. It holds the same value -* as VELO-LSR, but different versions of class use different names. -* Also write out the DELTAV keyword in the LSR rest frame rather -* than the source rest frame. -* 31-JAN-2008 (DSB): -* Correct calculation of redshift from radio velocity in ClassTrans. -* 25-FEB-2008 (DSB): -* Ensure a SkyFrame represents absolute (rather than offset) -* coords before writing it out in any non-native encoding. -* 28-FEB-2008 (DSB): -* Test for existing of SkyRefIs attribute before accessing it. -* 2-APR-2008 (DSB): -* In CLASSFromStore, adjust the spatial CRVAL and CRPIX values to be -* the centre of the first pixel if the spatial axes are degenerate. -* 17-APR-2008 (DSB): -* Ignore latitude axis PV terms supplied in a TAN header -* (previously, such PV terms were used as polynomial correction -* terms in a TPN projection). -* 30-APR-2008 (DSB): -* SetValue changed so that new keywords are inserted before the -* current card. -* 1-MAY-2008 (DSB): -* Added UndefRead warning. -* 7-MAY-2008 (DSB): -* Correct conversion of CDi_j to PCi_j/CDELT in SpecTrans. -* 8-MAY-2008 (DSB): -* When writing out a FITS-WCS header, allow linear grid->WCS -* mapping to be represented by a CAR projection. -* 9-MAY-2008 (DSB): -* Make class variables IgnoreUsed and MarkNew static. -* 30-JUN-2008 (DSB): -* Improve efficiency of FindWcs. -* 2-JUL-2008 (DSB): -* FitsSof now returns non-zero if the FitsChan is empty. -* 16-JUL-2008 (DSB): -* Plug memory leak caused by failure to free the Warnings -* attribute string when a FitsChan is deleted. -* 24-JUL-2008 (TIMJ): -* Fix buffer overrun in astGetFits when writing the keyword -* to the buffer (occurred if the input string was 80 characters). -* 1-OCT-2008 (DSB): -* When reading a FITS-WCS header, spurious PVi_j keywords no -* longer generate an error. Instead they generate warnings via the -* new "BadPV" warning type. -* 21-NOV-2008 (DSB): -* Do not remove keywords from read headers if they may be of -* relevance to things other than WCS (e.g. MJD-OBS, OBSGEO, etc). -* 2-DEC-2008 (DSB): -* - astGetFits now reports an error if the keyword value is undefined. -* - Add new functions astTestFits and astSetFitsU. -* - Remove use of AST__UNDEF constants. -* - Remove "undefread" warning. -* 16-JAN-2009 (DSB): -* Use astAddWarning to store each warning in the parent Channel -* structure. -* 4-MAR-2009 (DSB): -* DATE-OBS and MJD-OBS cannot have an axis description character. -* 13-MAR-2009 (DSB): -* The VELOSYS value read from the header is never used, so do not -* report an error if VELOSYS has an undefined value. -* 11-JUN-2009 (DSB): -* Delay reading cards from the source until they are actually -* needed. Previously, the source function was called in the -* FitsChan initialiser, but this means it is not possible for -* application code to call astPutChannelData before the source -* function is called. The ReadFromSource function is now called -* at the start of each (nearly) public or protected function to -* ensure the source function has been called (the source function -* pointer in the FitsChan is then nullified to ensure it is not -* called again). -* 18-JUN-2009 (DSB): -* Include the effect of observer height (in the ObsAlt attribute) -* when creating OBSGEO-X/Y/Z headers, and store a value for -* ObsAlt when reading a set of OBSGEO-X/Y/Z headers. -* 2-JUL-2009 (DSB): -* Check FitsChan is not empty at start of FindWcs. -* 7-JUL-2009 (DSB): -* Add new function astSetFitsCM. -* 30-JUL-2009 (DSB): -* Fix axis numbering in SkyPole. -* 12-FEB-2010 (DSB): -* Use "" to represent AST__BAD externally. -* 25-JUN-2010 (DSB): -* Fix problem rounding lots of 9's in RoundFString. The problem -* only affected negative values, and could lead to an extra zero -* being included in the integer part. -* 28-JUN-2010 (DSB): -* Another problem in RoundFString! If the value has a series of -* 9's followed by a series of zeros, with no decimal point (e.g. -* "260579999000"), then the trailing zeros were being lost. -* 16-JUL-2010 (DSB): -* In SpecTrans, avoid over-writing the spatial projection code -* with the spectral projection code. -* 20-JUL-2010 (DSB): -* Correct interpretation of NCP projection code. -* 14-OCT-2010 (DSB): -* - Correct loading of FitsChans that contain UNDEF keywords. -* - Correct translation of spectral units with non-standard -* capitalisation in SpecTrans. -* 10-JAN-2011 (DSB): -* Fix memory leak in MakeIntWorld. -* 13-JAN-2011 (DSB): -* Rename astEmpty ast astEmptyFits and make public. -* 20-JAN-2011 (DSB): -* - Extensive changes to support -TAB algorithm -* - Recovery from a major unrequested reformatting of whitespace by -* my editor! -* 7-FEB-2011 (DSB): -* Put a space between keyword value and slash that starts a comment -* when formatting a FITS header card. -* 11-FEB-2011 (DSB): -* Change meaning of TabOK attribute. It is no longer a simple -* boolean indicating if the -TAB algorithm is supported. Instead -* it gives the value to be used for the EXTVER header - i.e. the -* version number to store with any binary table created as a -* result of calling astWrite. If TabOK is zero or begative, then -* the -TAB algorithm is not supported. This is so that there is -* some way of having multiple binary table extensions with the same -* name (but different EXTVER values). -* 14-FEB-2011 (DSB): -* - Spectral reference point CRVAL records the obs. centre. So for -TAB -* (when CRVAL is set to zero) we need to record the obs centre some -* other way (use the AST-specific AXREF keywords, as for spatial axes). -* - Whether to scale spatial axes from degs to rads depends on -* whether the spatial axes are descirbed by -TAB or not. -* - Relax the linearity requirement in IsMapLinear by a factor of -* 10 to prevent a change in rest frame resulting in a non-linear -* mapping. -* 17-FEB-2011 (DSB): -* Fix bug in axis linearity check (IsMapLinear). -* 22-FEB-2011 (DSB): -* The translations of AIPS non-standard CTYPE values were always -* stored as primary axis description keywords, even if the original -* non-standard CTYPE values were read from an alternative axis -* descriptions. -* 5-APR-2011 (DSB): -* In SpecTrans, correct the MSX CAR projection translation. The -* first pixel starts at GRID=0.5, not GRID=0.0. So the CRPIX value -* needs to be reduced by 0.5 prior to normalisation, and then -* increased by 0.5 after normalisation. -* 23-MAY-2011 (DSB): -* Add support for TNX projections that use Chebyshev polynomials. -* 24-MAY-2011 (DSB): -* - Add support for ZPX projections that include IRAF polynomial -* corrections. -* - Add PolyTan attribute. -* - Fix interpretation of -SIP headers that have no inverse. -* 1-JUN-2011 (DSB): -* In astInitFitsChanVtab, only create the two TimeFrames if they -* have not already been created (fixes scuba2 trac ticket #666). -* 9-JUN-2011 (DSB): -* In WCSFcRead, ignore trailing spaces when reading string values -* for WCS keywords. -* 23-JUN-2011 (DSB): -* - Override the parent astSetSourceFile method so that it reads -* headers from the SourceFile and appends them to the end of the -* FitsChan. -* - On deletion, write out the FitsChan contents to the file -* specified by the SinkFile attribute. If no file is specified, -* use the sink function specified when the FitsChan was created. -* 30-AUG-2011 (DSB): -* - Added astWriteFits and astReadFits. -* - Move the deletion of tables and warnings from Delete to -* EmptyFits. -* 21-SEP-2011 (DSB): -* - In RoundFString, remember to update the pointer to the exponent. -* This bug caused parts of the exponent to dissappear when -* formatting a value that included some trailing zeros and a -* series of adjacent 9's. -* - Added Nkey attribute. -* 22-SEP-2011 (DSB): -* - Added CardType attribute -* - Allow GetFits to be used to get/set the value of the current -* card. -* 4-OCT-2011 (DSB): -* When reading a FITS-WCFS header, if the projection is TPV (as produced -* by SCAMP), change to TPN (the internal AST code for a distorted -* TAN projection). -* 22-NOV-2011 (DSB): -* Allow the "-SIP" code to be used with non-celestial axes. -* 1-FEB-2012 (DSB): -* Write out MJD-OBS in the timescale specified by any TIMESYS -* keyword in the FitsChan, and ensure the TIMESYS value is included -* in the output header. -* 23-FEB-2012 (DSB): -* Use iauGd2gc in place of palGeoc where is saves some calculations. -* 24-FEB-2012 (DSB): -* Move invocation of AddEncodingFrame from Write to end of -* MakeFitsFrameSet. This is so that AddEncodingFrame can take -* advantage of any standardisations (such as adding celestial axes) -* performed by MakeFItsFrameSet. Without this, a FRameSet contain -* a 1D SpecFrame (no celestial axes) would fail to be exported using -* FITS-CLASS encoding. -* 29-FEB-2012 (DSB): -* Fix bug in CLASSFromStore that caused spatial axes added by -* MakeFitsFrameSet to be ignored. -* 2-MAR-2012 (DSB): -* - In CLASSFromSTore, ensure NAXIS2/3 values are stored in teh FitsChan, -* and cater for FrameSets that have only a apectral axis and no celestial -* axes (this prevented the VELO_LSR keyword being created).. -* 7-MAR-2012 (DSB): -* Use iauGc2gd in place of Geod. -* 22-JUN-2012 (DSB): -* - Check for distorted TAN projections that have zero for all PVi_m -* coefficients. Issue a warning and ignore the distortion in such -* cases. -* - Remove all set but unused variables. -* - Convert SAO distorted TAN projections (which use COi_j keywords -* for polynomial coeffs) to TPN. -* 26-JUN-2012 (DSB): -* Correct call to astKeyFields in SAOTrans (thanks to Bill Joye -* for pointing out this error). -* 8-AUG-2012 (DSB): -* Correct assignment to lonpole within CLASSFromStore. -* 10-AUG-2012 (DSB): -* Default DSS keywords CNPIX1 and CNPIX2 to zero if they are -* absent, rather than reporting an error. -* 7-DEC-2012 (DSB): -* - When writing out a FrameSet that uses an SkyFrame to describe a -* generalised spherical coordinate system ("system=unknown"), ensure -* that the generated FITS CTYPE values use FITS-compliant codes -* for the axis type ( "xxLN/xxLT" or "xLON/xLAT" ). -* - Add support for reading and writing offset SkyFrames to -* FITS-WCS. -* 30-JAN-2013 (DSB): -* When reading a FITS-CLASS header, use "VLSR" keyword if -* "VELO-..." is not available. -* 15-APR-2013 (DSB): -* Correct initialisation of missing coefficients When reading a -* SAO plate solution header. -* 16-APR-2013 (DSB): -* When determining default Encoding value, use "VLSR" keyword if -* "VELO-..." is not available. -* 30-MAY-2013 (DSB): -* Prevent seg fault caused by overrunning the coeffs array in -* WATCoeffs in cases where the TNX/ZPX projection is found to be -* of a form that cannot be implemented as a TPN projection. -* 11-JUN-2013 (DSB): -* Fix support for reading GLS projections, and add support for -* rotated GLS projections. -* 28-AUG-2013 (DSB): -* In WcsCelestial, if celestial axes are found with no projection -* code in CTYPE, assume an old-fashioned CAR projection (i.e. no -* rotation from native to WCS coords). Before this change, -* CTYPE = "RA" | "DEC" axes got treated as radians, not degrees. -* 16-SEP-2013 (DSB): -* When exporting alternate offset SkyFrames to FITS-WCS headers, -* correctly test the alternate Frame in the supplied FrameSet, rather -* than the current Frame. -* 24-SEP-2013 (DSB): -* Fix bug in choosing default value for PolyTan attribute. -* 19-OCT-2013 (DSB): -* - In SIPMapping, always ignore any inverse polynomial supplied in -* a SIP header as they seem often to be inaccurate. A new inverse is -* created to replace it. -* - In SIPMapping, only use a fit to the inverted SIP transformation -* if an accuracy of 0.01 pixel can be achieved over an area three -* times the dimensions of the image. Otherwise use an iterative -* inverse for each point. People were seeing bad round-trip errors -* when transforming points outside the image because the fit was -* being used when it was not very accurate. -* 12-NOV-2013 (DSB): -* Added CardName and CardComm attributes. -* 13-NOV-2013 (DSB): -* Use a zero-length string for the CardComm attribute if the card -* has no comment. -* 15-NOV-2013 (DSB): -* - Added method astShowFits. -* - Ensure PurgeWcs removes WCS cards even if an error occurs when -* reading FrameSets from the FitsChan. -* - Change IsMapTab1D to improve chances of a -TAB mapping being found. -* 6-JAN-2014 (DSB): -* - Allow default options for newly created FitsChans to be -* specified by the FITSCHAN_OPTIONS environment variable. -* - Ensure the used CarLin value is not changed by a trailing frequency axis. -* 9-JUL-2014 (DSB): -* Added attribute FitsAxisOrder, which allows an order to be -* specified for WCS axis within FITS headers generated using astWrite. -* 9-SEP-2014 (DSB): -* Modify Split so that any non-printing characters such as -* newlines at the end of the string are ignored. -* 30-SEP-2014 (DSB): -* Modify CnvType to indicate that comment cards cannot be -* converted to any other data type. For instance, this causes -* a warning to be issued if an equals sign is misplaced in a -* WCS-related card (causing it to be treated as a comment card). -* 24-MAR-2015 (DSB): -* Modify SpecTrans to avoid modifying the CRPIC value for CAR -* projections when they do not need to be modified. The princiuple -* is that the bulk of the array should be witin the native longitude -* range [-180,+180]. Prompted by bug report from Bill Joye "yet -* another CAR issue" on 24-MAR-2015 (file CHIPASS_Equ.head in -* ast_tester). -* 27-APR-2015 (DSB): -* Modify MakeFitsFrameSet so that isolated SkyAxes (e.g. -* individual axes that have been oicked from a SkyFrame) are -* re-mapped into degrees before being used. -* 20-APR-2015 (DSB): -* In MakeIntWorld, relax tolerance for checking that each FITS-WCS IWC -* axis is linear, from 0.01 of a pixel to 0.1 of a pixel. -* 6-JUL-2015 (DSB): -* When checking a sub-string, ensure the whole string is at least as -* long as the offset to the start of the sub-string. Without this, you -* can get erroneous sub-string matches by chance, depending on what -* characters happen to be present in memory after the end of the string. -* 11-AUG-2015 (DSB): -* - Fix bug in CheckFitsName that prevented an error from being reported -* if the FITS keyword name contained any illegal printable characters. -* - Add new Warning "badkeyname", and issue such a warning instead -* of an error if illegal characters are found in a keyword name. -* 31-AUG-2015 (DSB): -* In FitLine, use the whole axis rather than 0.1 of the axis (if "dim" -* is supplied). This is because non-linearity can become greater at -* further distances along the axis. In practice, it meant that SIP -* distortion were being treated as linear because the test did not -* explore a large enough region of pixel space. -* 12-OCT-2015 (DSB): -* Only add sky axes to a SpecFrame if the WCS Frame contains no -* other axes other than the SpecFrame (MakeFitsFrameSet). -* 17-OCT-2015 (DSB): -* - Add new Warning "badkeyvalue", and issue such a warning instead -* of an error if the Split function cannot determine the keyword value. -* - Move the check for PLTRAH (i.e. DSS encoding) higher up in GetEncoding. -* This is because some DSS file slaos have CD and/or PC keywords. -* 5-NOV-2015 (DSB): -* Fix bug in MakeFitsFrameSet that could cause an inappropriate -* RefRA and RefDec values to be used when writing out a SpecFrame -* using FITS-WCS. This bug was caused by the assumption that -* changing the current Frame of a FRameSet also changes the Frame -* that was added into the FRameSet. This used to be the case as -* astAddFrame took a clone of the supplied Frame pointer, but it -* now takes a deep copy, so the original Frame and the FrameSet's -* current Frame are now independent of each other. -* 28-JUN-2016 ((DSB): -* IsAipsSpectral: Trailing spaces in CTYPE values are insignificant. -* 17-MAR-2017 (DSB): -* Fix memory leak in MakeFitsFrameSet. -* 25-APR-2017 (DSB): -* When reading foreign WCS, retain the TIMESYS keyword by default. -* 28-APR-2017 (DSB): -* When reading a JCMT or UKIRT foreign header that contains a -* DTAI keyword, use it to set the Dtai attribute in the WCS Frame. -* 11-SEP-2017 (DSB): -* Allow a NULL keyword name to be supplied to astTestFits to -* indicate that the current card should be used (as is also done in -* astGetFits). -* 25-OCT-2017 (DSB): -* Added attribute FitsTol. -* 27-OCT-2017 (DSB): -* In RoundFString, only right justift the final string if a -* minimum field width is given. Otherwise, leave the unchanged -* characters in their original positions. Right justifying ccould -* cause very long strings to be returned. -* 6-NOV-2017 (DSB): -* In CelestialAxes, simplify the base->current mapping before -* attempting to split it. This can cause multiple WcsMaps to cancel out, -* which could otherwise prevent SplitMap from splitting the Mapping -* successfully. -* 7-NOV-2017 (DSB): -* If an IWC Frame is included in the FrameSet returned by astRead, -* ensure it comes between the pixel and sky frames in the mapping chain. -* Previously the order was PIXEL->SKY->IWC, Now it is PIXEL->IWC->SKY. -* The inter-Frame Mappings required by the new arrangment are simpler -* than for the old arrangement. -* 20-NOV-2017 (DSB) -* Added SipReplace attribute. -* 20-NOV-2017 (DSB) -* Added SipReplace attribute. -* 30-DEC-2017 (DSB): -* Add the SipOK attribute, and support for writing SIP headers. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ - -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS FitsChan - -/* A macro which tests a character to see if it can be used within a FITS - keyword. We include lower case letters here, but they are considered - as equivalent to upper case letter. */ -#define isFits(a) ( islower(a) || isupper(a) || isdigit(a) || (a)=='-' || (a)=='_' ) - -/* A amacro to test if a Frame is a SkyFrame, and is used to describe the - sky (skyframes could be used for other purposes - eg a POLANAL Frame). */ -#define IsASkyFrame(frame) (astIsASkyFrame(frame)&&!strcmp("SKY",astGetDomain(frame))) - -/* Macro which takes a pointer to a FitsCard and returns non-zero if the - card has been used and so should be ignored. */ -#define CARDUSED(card) ( \ - ( ignore_used == 2 && \ - ( (FitsCard *) (card) )->flags & PROVISIONALLY_USED ) || \ - ( ignore_used >= 1 && \ - ( (FitsCard *) (card) )->flags & USED ) ) - -/* Set of characters used to encode a "sequence number" at the end of - FITS keywords in an attempt to make them unique.. */ -#define SEQ_CHARS "_ABCDEFGHIJKLMNOPQRSTUVWXYZ" - -/* A general tolerance for equality between floating point values. */ -#define TOL1 10.0*DBL_EPSILON - -/* A tolerance for equality between angular values in radians. */ -#define TOL2 1.0E-10 - -/* Macro to check for equality of floating point angular values. We cannot - compare bad values directory because of the danger of floating point - exceptions, so bad values are dealt with explicitly. The smallest - significant angle is assumed to be 1E-9 radians (0.0002 arc-seconds).*/ -#define EQUALANG(aa,bb) (((aa)==AST__BAD)?(((bb)==AST__BAD)?1:0):(((bb)==AST__BAD)?0:(fabs((aa)-(bb))<=astMAX(1.0E5*(fabs(aa)+fabs(bb))*DBL_EPSILON,1.0E-9)))) - -/* Macro to compare an angle in radians with zero, allowing some tolerance. */ -#define ZEROANG(aa) (fabs(aa)<1.0E-9) - -/* Constants: */ -#define UNKNOWN_ENCODING -1 -#define NATIVE_ENCODING 0 -#define FITSPC_ENCODING 1 -#define DSS_ENCODING 2 -#define FITSWCS_ENCODING 3 -#define FITSIRAF_ENCODING 4 -#define FITSAIPS_ENCODING 5 -#define FITSAIPSPP_ENCODING 6 -#define FITSCLASS_ENCODING 7 -#define MAX_ENCODING 7 -#define UNKNOWN_STRING "UNKNOWN" -#define NATIVE_STRING "NATIVE" -#define FITSPC_STRING "FITS-PC" -#define FITSPC_STRING2 "FITS_PC" -#define DSS_STRING "DSS" -#define FITSWCS_STRING "FITS-WCS" -#define FITSWCS_STRING2 "FITS_WCS" -#define FITSIRAF_STRING "FITS-IRAF" -#define FITSIRAF_STRING2 "FITS_IRAF" -#define FITSAIPS_STRING "FITS-AIPS" -#define FITSAIPS_STRING2 "FITS_AIPS" -#define FITSAIPSPP_STRING "FITS-AIPS++" -#define FITSAIPSPP_STRING2 "FITS_AIPS++" -#define FITSCLASS_STRING "FITS-CLASS" -#define FITSCLASS_STRING2 "FITS_CLASS" -#define INDENT_INC 3 -#define PREVIOUS 0 -#define NEXT 1 -#define HEADER_TEXT "Beginning of AST data for " -#define FOOTER_TEXT "End of AST data for " -#define FITSNAMLEN 8 -#define FITSSTCOL 20 -#define FITSRLCOL 30 -#define FITSIMCOL 50 -#define FITSCOMCOL 32 -#define NORADEC 0 -#define FK4 1 -#define FK4NOE 2 -#define FK5 3 -#define GAPPT 4 -#define ICRS 5 -#define NOCEL 0 -#define RADEC 1 -#define ECLIP 2 -#define GALAC 3 -#define SUPER 4 -#define HECLIP 5 -#define AZEL 6 -#define LONAX -1 -#define NONAX 0 -#define LATAX 1 -#define NDESC 9 -#define MXCTYPELEN 81 -#define ALLWARNINGS " distortion noequinox noradesys nomjd-obs nolonpole nolatpole tnx zpx badcel noctype badlat badmat badval badctype badpv badkeyname badkeyvalue " -#define NPFIT 10 -#define SPD 86400.0 -#define FL 1.0/298.257 /* Reference spheroid flattening factor */ -#define A0 6378140.0 /* Earth equatorial radius (metres) */ - -/* String used to represent AST__BAD externally. */ -#define BAD_STRING "" - -/* Each card in the fitschan has a set of flags associated with it, - stored in different bits of the "flags" item within each FitsCard - structure (note, in AST V1.4 these flags were stored in the "del" - item... Dump and LoadFitsChan will need to be changed to use a - correspondingly changed name for the external representation of this - item). The following flags are currently defined: */ - -/* "USED" - This flag indicates that the the card has been used in the - construction of an AST Object returned by astRead. Such cards should - usually be treated as if they do not exist, i.e. they should not be - used again by subsequent calls to astRead, they should not be recognised - by public FitsChan methods which search the FitsChan for specified - cards, and they should not be written out when the FitsChan is deleted. - This flag was the only flag available in AST V1.4, and was called - "Del" (for "deleted"). Used cards are retained in order to give an - indication of where abouts within the header new cards should be placed - when astWrite is called (i.e. new cards should usually be placed at - the same point within the header as the cards which they replace). */ -#define USED 1 - -/* "PROVISIONALLY_USED" - This flag indicates that the the card is being - considered as a candidate for inclusion in the construction of an AST - Object. If the Object is constructed succesfully, cards flagged as - "provisionally used" will be changed to be flagged as "definitely used" - (using the USED flag). If the Object fails to be constructed - succesfully (if some required cards are missing from the FitsChan - for instance), then "provisionally used" cards will be returned to the - former state which they had prior to the attempt to construct the - object. */ -#define PROVISIONALLY_USED 2 - -/* "NEW" - This flag indicates that the the card has just been added to - the FitsChan and may yet proove to be unrequired. For instance if the - supplied Object is not of an appropriate flavour to be stored using - the requested encoding, all "new" cards which were added before the - inappropriateness was discovered will be removed from the FitsChan. - Two different levels of "newness" are available. */ -#define NEW1 4 -#define NEW2 8 - -/* "PROTECTED" - This flag indicates that the the card should not be - removed form the FitsChan when an Object is read using astRead. If - this flag is not set, then the card will dehave as if it has been - deleted if it was used in the construction of the returned AST Object. */ -#define PROTECTED 16 - -/* Include files. */ -/* ============== */ - -/* Interface definitions. */ -/* ---------------------- */ -#include "channel.h" -#include "cmpframe.h" -#include "cmpmap.h" -#include "dssmap.h" -#include "error.h" -#include "fitschan.h" -#include "frame.h" -#include "frameset.h" -#include "grismmap.h" -#include "lutmap.h" -#include "mathmap.h" -#include "matrixmap.h" -#include "memory.h" -#include "object.h" -#include "permmap.h" -#include "pointset.h" -#include "shiftmap.h" -#include "skyframe.h" -#include "timeframe.h" -#include "keymap.h" -#include "pal.h" -#include "erfa.h" -#include "slamap.h" -#include "specframe.h" -#include "dsbspecframe.h" -#include "specmap.h" -#include "sphmap.h" -#include "unit.h" -#include "unitmap.h" -#include "polymap.h" -#include "wcsmap.h" -#include "winmap.h" -#include "zoommap.h" -#include "globals.h" -#include "fitstable.h" - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Type Definitions */ -/* ================ */ - -/* This structure contains information describing a single FITS header card - in a circular list of such structures. */ -typedef struct FitsCard { - char name[ FITSNAMLEN + 1 ];/* Keyword name (plus terminating null). */ - int type; /* Data type. */ - void *data; /* Pointer to the keyword's data value. */ - char *comment; /* Pointer to a comment for the keyword. */ - int flags; /* Flags for each card */ - size_t size; /* Size of data value */ - struct FitsCard *next; /* Pointer to next structure in list. */ - struct FitsCard *prev; /* Pointer to previous structure in list. */ -} FitsCard; - -/* Structure used to store information derived from the FITS WCS keyword - values in a form more convenient to further processing. Conventions - for units, etc, for values in a FitsStore follow FITS-WCS (e.g. angular - values are stored in degrees, equinox is B or J depending on RADECSYS, - etc). */ -typedef struct FitsStore { - char ****cname; - char ****ctype; - char ****ctype_com; - char ****cunit; - char ****radesys; - char ****wcsname; - char ****specsys; - char ****ssyssrc; - char ****ps; - char ****timesys; - double ***pc; - double ***cdelt; - double ***crpix; - double ***crval; - double ***equinox; - double ***latpole; - double ***lonpole; - double ***mjdobs; - double ***dtai; - double ***dut1; - double ***mjdavg; - double ***pv; - double ***wcsaxes; - double ***obsgeox; - double ***obsgeoy; - double ***obsgeoz; - double ***restfrq; - double ***restwav; - double ***zsource; - double ***velosys; - double ***asip; - double ***bsip; - double ***apsip; - double ***bpsip; - double ***imagfreq; - double ***axref; - int naxis; - AstKeyMap *tables; - double ***skyref; - double ***skyrefp; - char ****skyrefis; -} FitsStore; - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static void (* parent_setsourcefile)( AstChannel *, const char *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_getfull)( AstChannel *, int * ); -static int (* parent_getskip)( AstChannel *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static int (* parent_write)( AstChannel *, AstObject *, int * ); -static AstObject *(* parent_read)( AstChannel *, int * ); -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Strings to describe each data type. These should be in the order implied - by the corresponding macros (eg AST__FLOAT, etc). */ -static const char *type_names[9] = {"comment", "integer", "floating point", - "string", "complex floating point", - "complex integer", "logical", - "continuation string", "undef" }; - -/* Text values used to represent Encoding values externally. */ - -static const char *xencod[8] = { NATIVE_STRING, FITSPC_STRING, - DSS_STRING, FITSWCS_STRING, - FITSIRAF_STRING, FITSAIPS_STRING, - FITSAIPSPP_STRING, FITSCLASS_STRING }; -/* Define two variables to hold TimeFrames which will be used for converting - MJD values between time scales. */ -static AstTimeFrame *tdbframe = NULL; -static AstTimeFrame *timeframe = NULL; - -/* Max number of characters in a formatted int */ -static int int_dig; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->Items_Written = 0; \ - globals->Write_Nest = -1; \ - globals->Current_Indent = 0; \ - globals->Ignore_Used = 1; \ - globals->Mark_New = 0; \ - globals->CnvType_Text[ 0 ] = 0; \ - globals->CnvType_Text0[ 0 ] = 0; \ - globals->CnvType_Text1[ 0 ] = 0; \ - globals->CreateKeyword_Seq_Nchars = -1; \ - globals->FormatKey_Buff[ 0 ] = 0; \ - globals->FitsGetCom_Sval[ 0 ] = 0; \ - globals->IsSpectral_Ret = NULL; \ - globals->Match_Fmt[ 0 ] = 0; \ - globals->Match_Template = NULL; \ - globals->Match_PA = 0; \ - globals->Match_PB = 0; \ - globals->Match_NA = 0; \ - globals->Match_NB = 0; \ - globals->Match_Nentry = 0; \ - globals->WcsCelestial_Type[ 0 ] = 0; \ - globals->Ignore_Used = 1; \ - globals->Mark_New = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(FitsChan) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(FitsChan,Class_Init) -#define class_vtab astGLOBAL(FitsChan,Class_Vtab) -#define getattrib_buff astGLOBAL(FitsChan,GetAttrib_Buff) -#define items_written astGLOBAL(FitsChan,Items_Written) -#define write_nest astGLOBAL(FitsChan,Write_Nest) -#define current_indent astGLOBAL(FitsChan,Current_Indent) -#define ignore_used astGLOBAL(FitsChan,Ignore_Used) -#define mark_new astGLOBAL(FitsChan,Mark_New) -#define cnvtype_text astGLOBAL(FitsChan,CnvType_Text) -#define cnvtype_text0 astGLOBAL(FitsChan,CnvType_Text0) -#define cnvtype_text1 astGLOBAL(FitsChan,CnvType_Text1) -#define createkeyword_seq_nchars astGLOBAL(FitsChan,CreateKeyword_Seq_Nchars) -#define formatkey_buff astGLOBAL(FitsChan,FormatKey_Buff) -#define fitsgetcom_sval astGLOBAL(FitsChan,FitsGetCom_Sval) -#define isspectral_ret astGLOBAL(FitsChan,IsSpectral_Ret) -#define match_fmt astGLOBAL(FitsChan,Match_Fmt) -#define match_template astGLOBAL(FitsChan,Match_Template) -#define match_pa astGLOBAL(FitsChan,Match_PA) -#define match_pb astGLOBAL(FitsChan,Match_PB) -#define match_na astGLOBAL(FitsChan,Match_NA) -#define match_nb astGLOBAL(FitsChan,Match_NB) -#define match_nentry astGLOBAL(FitsChan,Match_Nentry) -#define wcscelestial_type astGLOBAL(FitsChan,WcsCelestial_Type) -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); -static pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX3 pthread_mutex_lock( &mutex3 ); -#define UNLOCK_MUTEX3 pthread_mutex_unlock( &mutex3 ); -static pthread_mutex_t mutex4 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX4 pthread_mutex_lock( &mutex4 ); -#define UNLOCK_MUTEX4 pthread_mutex_unlock( &mutex4 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ AST__FITSCHAN_GETATTRIB_BUFF_LEN + 1 ]; - -/* Buffer for returned text string in CnvType */ -static char cnvtype_text[ AST__FITSCHAN_FITSCARDLEN + 1 ]; - -/* Buffer for real value in CnvType */ -static char cnvtype_text0[ AST__FITSCHAN_FITSCARDLEN + 1 ]; - -/* Buffer for imaginary value in CnvType */ -static char cnvtype_text1[ AST__FITSCHAN_FITSCARDLEN + 1 ]; - -/* Number of output items written since the last "Begin" or "IsA" - output item, and level of Object nesting during recursive - invocation of the astWrite method. */ -static int items_written = 0; -static int write_nest = -1; - -/* Indentation level for indented comments when writing Objects to a - FitsChan. */ -static int current_indent = 0; - -/* Ignore_Used: If 2, then cards which have been marked as either "definitely - used" or "provisionally used" (see the USED flag above) will be ignored - when searching the FitsChan, etc (i.e. they will be treated as if they - have been removed from the FitsChan). If 1, then cards which have been - "definitely used" will be skipped over. If zero then no cards will be - skipped over. */ -static int ignore_used = 1; - -/* Mark_New: If non-zero, then all cards added to the FitsChan will be - marked with both the NEW1 and NEW2 flags (see above). If zero then - new cards will not be marked with either NEW1 or NEW2. */ -static int mark_new = 0; - -/* Number of characters used for encoding */ -static int createkeyword_seq_nchars = -1; - -/* Buffer for value returned by FormatKey */ -static char formatkey_buff[ 10 ]; - -/* Buffer for value returned by FitsGetCom */ -static char fitsgetcom_sval[ AST__FITSCHAN_FITSCARDLEN + 1 ]; - -/* Pointer returned by IsSpectral */ -static const char *isspectral_ret = NULL; - -/* Format specifier for reading an integer field in Match */ -static char match_fmt[ 10 ]; - -/* Pointer to start of template in Match */ -static const char *match_template = NULL; - -/* Pointer to first returned field value in Match */ -static int *match_pa = 0; - -/* Pointer to last returned field value in Match */ -static int *match_pb = 0; - -/* No. of characters read from the test string in Match */ -static int match_na = 0; - -/* No. of characters read from the template string in Match */ -static int match_nb = 0; - -/* Number of recursive entries into Match */ -static int match_nentry = 0; - -/* Buffer for celestial system in WcsCelestial */ -static char wcscelestial_type[ 4 ]; - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstFitsChanVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 -#define LOCK_MUTEX3 -#define UNLOCK_MUTEX3 -#define LOCK_MUTEX4 -#define UNLOCK_MUTEX4 -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ - -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstFitsChan *astFitsChanForId_( const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), const char *, int * ), - const char *, ... ); -AstFitsChan *astFitsChanId_( const char *(* source)( void ), - void (* sink)( const char * ), - const char *options, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static int GetObjSize( AstObject *, int * ); -static void ClearCard( AstFitsChan *, int * ); -static int GetCard( AstFitsChan *, int * ); -static int TestCard( AstFitsChan *, int * ); -static void SetCard( AstFitsChan *, int, int * ); -static void ClearEncoding( AstFitsChan *, int * ); -static int GetEncoding( AstFitsChan *, int * ); -static int TestEncoding( AstFitsChan *, int * ); -static void SetEncoding( AstFitsChan *, int, int * ); -static void ClearCDMatrix( AstFitsChan *, int * ); -static int GetCDMatrix( AstFitsChan *, int * ); -static int TestCDMatrix( AstFitsChan *, int * ); -static void SetCDMatrix( AstFitsChan *, int, int * ); -static void ClearFitsDigits( AstFitsChan *, int * ); -static int GetFitsDigits( AstFitsChan *, int * ); -static int TestFitsDigits( AstFitsChan *, int * ); -static void SetFitsDigits( AstFitsChan *, int, int * ); -static void ClearFitsAxisOrder( AstFitsChan *, int * ); -static const char *GetFitsAxisOrder( AstFitsChan *, int * ); -static int TestFitsAxisOrder( AstFitsChan *, int * ); -static void SetFitsAxisOrder( AstFitsChan *, const char *, int * ); -static void ClearDefB1950( AstFitsChan *, int * ); -static int GetDefB1950( AstFitsChan *, int * ); -static int TestDefB1950( AstFitsChan *, int * ); -static void SetDefB1950( AstFitsChan *, int, int * ); -static void ClearTabOK( AstFitsChan *, int * ); -static int GetTabOK( AstFitsChan *, int * ); -static int TestTabOK( AstFitsChan *, int * ); -static void SetTabOK( AstFitsChan *, int, int * ); -static void ClearCarLin( AstFitsChan *, int * ); -static int GetCarLin( AstFitsChan *, int * ); -static int TestCarLin( AstFitsChan *, int * ); -static void SetCarLin( AstFitsChan *, int, int * ); -static void ClearSipReplace( AstFitsChan *, int * ); -static int GetSipReplace( AstFitsChan *, int * ); -static int TestSipReplace( AstFitsChan *, int * ); -static void SetSipReplace( AstFitsChan *, int, int * ); -static void ClearPolyTan( AstFitsChan *, int * ); -static int GetPolyTan( AstFitsChan *, int * ); -static int TestPolyTan( AstFitsChan *, int * ); -static void SetPolyTan( AstFitsChan *, int, int * ); -static void ClearSipOK( AstFitsChan *, int * ); -static int GetSipOK( AstFitsChan *, int * ); -static int TestSipOK( AstFitsChan *, int * ); -static void SetSipOK( AstFitsChan *, int, int * ); -static void ClearIwc( AstFitsChan *, int * ); -static int GetIwc( AstFitsChan *, int * ); -static int TestIwc( AstFitsChan *, int * ); -static void SetIwc( AstFitsChan *, int, int * ); -static void ClearClean( AstFitsChan *, int * ); -static int GetClean( AstFitsChan *, int * ); -static int TestClean( AstFitsChan *, int * ); -static void SetClean( AstFitsChan *, int, int * ); -static void ClearWarnings( AstFitsChan *, int * ); -static const char *GetWarnings( AstFitsChan *, int * ); -static int TestWarnings( AstFitsChan *, int * ); -static void SetWarnings( AstFitsChan *, const char *, int * ); -static double GetFitsTol( AstFitsChan *, int * ); -static int TestFitsTol( AstFitsChan *, int * ); -static void ClearFitsTol( AstFitsChan *, int * ); -static void SetFitsTol( AstFitsChan *, double, int * ); - - -static AstFitsChan *SpecTrans( AstFitsChan *, int, const char *, const char *, int * ); -static AstFitsTable *GetNamedTable( AstFitsChan *, const char *, int, int, int, const char *, int * ); -static AstFrameSet *MakeFitsFrameSet( AstFitsChan *, AstFrameSet *, int, int, int, const char *, const char *, int * ); -static AstGrismMap *ExtractGrismMap( AstMapping *, int, AstMapping **, int * ); -static AstKeyMap *GetTables( AstFitsChan *, int * ); -static AstMapping *AddUnitMaps( AstMapping *, int, int, int * ); -static AstMapping *CelestialAxes( AstFitsChan *this, AstFrameSet *, double *, int *, char, FitsStore *, int *, int, const char *, const char *, int * ); -static AstMapping *GrismSpecWcs( char *, FitsStore *, int, char, AstSpecFrame *, const char *, const char *, int * ); -static AstMapping *IsMapTab1D( AstMapping *, double, const char *, AstFrame *, double *, int, int, AstFitsTable **, int *, int *, int *, int * ); -static AstMapping *IsMapTab2D( AstMapping *, double, const char *, AstFrame *, double *, int, int, int, int, AstFitsTable **, int *, int *, int *, int *, int *, int *, int *, int *, int * ); -static AstMapping *LinearWcs( FitsStore *, int, char, const char *, const char *, int * ); -static AstMapping *LogAxis( AstMapping *, int, int, double *, double *, double, int * ); -static AstMapping *LogWcs( FitsStore *, int, char, const char *, const char *, int * ); -static AstMapping *MakeColumnMap( AstFitsTable *, const char *, int, int, const char *, const char *, int * ); -static AstMapping *NonLinSpecWcs( AstFitsChan *, char *, FitsStore *, int, char, AstSpecFrame *, const char *, const char *, int * ); -static AstMapping *OtherAxes( AstFitsChan *, AstFrameSet *, double *, int *, char, FitsStore *, double *, int *, const char *, const char *, int * ); -static AstMapping *SIPIntWorld( AstMapping *, int, int, char, FitsStore *, double *, int[2], double[2], double[4], const char *, const char *, int * ); -static AstMapping *SIPMapping( AstFitsChan *, double *, FitsStore *, char, int, const char *, const char *, int * ); -static AstMapping *SpectralAxes( AstFitsChan *, AstFrameSet *, double *, int *, char, FitsStore *, double *, int *, const char *, const char *, int * ); -static AstMapping *TabMapping( AstFitsChan *, FitsStore *, char, int **, const char *, const char *, int *); -static AstMapping *WcsCelestial( AstFitsChan *, FitsStore *, char, AstFrame **, AstFrame *, double *, double *, AstSkyFrame **, AstMapping **, int *, const char *, const char *, int * ); -static AstMapping *WcsIntWorld( AstFitsChan *, FitsStore *, char, int, const char *, const char *, int * ); -static AstMapping *WcsMapFrm( AstFitsChan *, FitsStore *, char, AstFrame **, const char *, const char *, int * ); -static AstMapping *WcsNative( AstFitsChan *, FitsStore *, char, AstWcsMap *, int, int, const char *, const char *, int * ); -static AstMapping *WcsOthers( AstFitsChan *, FitsStore *, char, AstFrame **, AstFrame *, const char *, const char *, int * ); -static AstMapping *WcsSpectral( AstFitsChan *, FitsStore *, char, AstFrame **, AstFrame *, double, double, AstSkyFrame *, const char *, const char *, int * ); -static AstMapping *ZPXMapping( AstFitsChan *, FitsStore *, char, int, int[2], const char *, const char *, int * ); -static AstMatrixMap *WcsCDeltMatrix( FitsStore *, char, int, const char *, const char *, int * ); -static AstMatrixMap *WcsPCMatrix( FitsStore *, char, int, const char *, const char *, int * ); -static AstObject *FsetFromStore( AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static AstObject *Read( AstChannel *, int * ); -static AstSkyFrame *WcsSkyFrame( AstFitsChan *, FitsStore *, char, int, char *, int, int, const char *, const char *, int * ); -static AstTimeScaleType TimeSysToAst( AstFitsChan *, const char *, const char *, const char *, int * ); -static AstWinMap *WcsShift( FitsStore *, char, int, const char *, const char *, int * ); -static FitsCard *GetLink( FitsCard *, int, const char *, const char *, int * ); -static FitsStore *FitsToStore( AstFitsChan *, int, const char *, const char *, int * ); -static FitsStore *FreeStore( FitsStore *, int * ); -static FitsStore *FsetToStore( AstFitsChan *, AstFrameSet *, int, double *, int, const char *, const char *, int * ); -static char *CardComm( AstFitsChan *, int * ); -static char *CardName( AstFitsChan *, int * ); -static char *ConcatWAT( AstFitsChan *, int, const char *, const char *, int * ); -static char *FormatKey( const char *, int, int, char, int * ); -static char *GetItemC( char *****, int, int, char, char *, const char *method, const char *class, int * ); -static char *SourceWrap( const char *(*)( void ), int * ); -static char *UnPreQuote( const char *, int * ); -static char GetMaxS( double ****item, int * ); -static const char *GetAllWarnings( AstFitsChan *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetCardComm( AstFitsChan *, int * ); -static const char *GetCardName( AstFitsChan *, int * ); -static const char *GetFitsSor( const char *, int * ); -static const char *IsSpectral( const char *, char[5], char[5], int * ); -static double **OrthVectorSet( int, int, double **, int * ); -static double *Cheb2Poly( double *, int, int, double, double, double, double, int * ); -static double *FitLine( AstMapping *, double *, double *, double *, double, double *, int * ); -static double *OrthVector( int, int, double **, int * ); -static double *ReadCrval( AstFitsChan *, AstFrame *, char, const char *, const char *, int * ); -static double ChooseEpoch( AstFitsChan *, FitsStore *, char, const char *, const char *, int * ); -static double DateObs( const char *, int * ); -static double GetItem( double ****, int, int, char, char *, const char *method, const char *class, int * ); -static double NearestPix( AstMapping *, double, int, int * ); -static double TDBConv( double, int, int, const char *, const char *, int * ); -static int *CardFlags( AstFitsChan *, int * ); -static int AIPSFromStore( AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static int AIPSPPFromStore( AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static int AddEncodingFrame( AstFitsChan *, AstFrameSet *, int, const char *, const char *, int * ); -static int AddVersion( AstFitsChan *, AstFrameSet *, int, int, FitsStore *, double *, char, int, int, const char *, const char *, int * ); -static int CLASSFromStore( AstFitsChan *, FitsStore *, AstFrameSet *, double *, const char *, const char *, int * ); -static int CardType( AstFitsChan *, int * ); -static int CheckFitsName( AstFitsChan *, const char *, const char *, const char *, int * ); -static int ChrLen( const char *, int * ); -static int CnvType( int, void *, size_t, int, int, void *, const char *, const char *, const char *, int * ); -static int CnvValue( AstFitsChan *, int , int, void *, const char *, int * ); -static int ComBlock( AstFitsChan *, int, const char *, const char *, int * ); -static int CountFields( const char *, char, const char *, const char *, int * ); -static int DSSFromStore( AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static int EncodeFloat( char *, int, int, int, double, int * ); -static int EncodeValue( AstFitsChan *, char *, int, int, const char *, int * ); -static int FindBasisVectors( AstMapping *, int, int, double *, AstPointSet *, AstPointSet *, int * ); -static int FindFits( AstFitsChan *, const char *, char[ AST__FITSCHAN_FITSCARDLEN + 1 ], int, int * ); -static int FindKeyCard( AstFitsChan *, const char *, const char *, const char *, int * ); -static int FindLonLatSpecAxes( FitsStore *, char, int *, int *, int *, const char *, const char *, int * ); -static int FindString( int, const char *[], const char *, const char *, const char *, const char *, int * ); -static int FitOK( int, double *, double *, double, int * ); -static int FitsAxisOrder( AstFitsChan *this, int nwcs, AstFrame *wcsfrm, int *perm, int *status ); -static int FitsEof( AstFitsChan *, int * ); -static int FitsFromStore( AstFitsChan *, FitsStore *, int, double *, AstFrameSet *, const char *, const char *, int * ); -static int FitsGetCom( AstFitsChan *, const char *, char **, int * ); -static int FitsSof( AstFitsChan *, int * ); -static int FullForm( const char *, const char *, int, int * ); -static int GetCardType( AstFitsChan *, int * ); -static int GetFiducialWCS( AstWcsMap *, AstMapping *, int, int, double *, double *, int * ); -static int GetFitsCF( AstFitsChan *, const char *, double *, int * ); -static int GetFitsCI( AstFitsChan *, const char *, int *, int * ); -static int GetFitsCN( AstFitsChan *, const char *, char **, int * ); -static int GetFitsF( AstFitsChan *, const char *, double *, int * ); -static int GetFitsI( AstFitsChan *, const char *, int *, int * ); -static int GetFitsL( AstFitsChan *, const char *, int *, int * ); -static int GetFitsS( AstFitsChan *, const char *, char **, int * ); -static int GetFull( AstChannel *, int * ); -static int GetMaxI( double ****item, char, int * ); -static int GetMaxJM( double ****item, char, int * ); -static int GetMaxJMC( char *****item, char, int * ); -static int GetNcard( AstFitsChan *, int * ); -static int GetNkey( AstFitsChan *, int * ); -static int GetSkip( AstChannel *, int * ); -static int GetUsedPolyTan( AstFitsChan *, AstFitsChan *, int, int, char, const char *, const char *, int * ); -static int GetValue( AstFitsChan *, const char *, int, void *, int, int, const char *, const char *, int * ); -static int GetValue2( AstFitsChan *, AstFitsChan *, const char *, int, void *, int, const char *, const char *, int * ); -static int GoodWarns( const char *, int * ); -static int HasAIPSSpecAxis( AstFitsChan *, const char *, const char *, int * ); -static int HasCard( AstFitsChan *, const char *, const char *, const char *, int * ); -static int IRAFFromStore( AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static int IsAIPSSpectral( const char *, char **, char **, int * ); -static int IsMapLinear( AstMapping *, const double [], const double [], int, int * ); -static int IsSkyOff( AstFrameSet *, int, int * ); -static int KeyFields( AstFitsChan *, const char *, int, int *, int *, int * ); -static int LooksLikeClass( AstFitsChan *, const char *, const char *, int * ); -static int MakeBasisVectors( AstMapping *, int, int, double *, AstPointSet *, AstPointSet *, int * ); -static int MakeIntWorld( AstMapping *, AstFrame *, int *, char, FitsStore *, double *, double, int, const char *, const char *, int * ); -static int Match( const char *, const char *, int, int *, int *, const char *, const char *, int * ); -static int MatchChar( char, char, const char *, const char *, const char *, int * ); -static int MatchFront( const char *, const char *, char *, int *, int *, int *, const char *, const char *, const char *, int * ); -static int MoveCard( AstFitsChan *, int, const char *, const char *, int * ); -static int PCFromStore( AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static int SAOTrans( AstFitsChan *, AstFitsChan *, const char *, const char *, int * ); -static int SearchCard( AstFitsChan *, const char *, const char *, const char *, int * ); -static int SetFits( AstFitsChan *, const char *, void *, int, const char *, int, int * ); -static int Similar( const char *, const char *, int * ); -static int SkySys( AstFitsChan *, AstSkyFrame *, int, int, FitsStore *, int, int, char c, int, const char *, const char *, int * ); -static int Split( AstFitsChan *, const char *, char **, char **, char **, const char *, const char *, int * ); -static int SplitMap( AstMapping *, int, int, int, AstMapping **, AstWcsMap **, AstMapping **, int * ); -static int SplitMap2( AstMapping *, int, AstMapping **, AstWcsMap **, AstMapping **, int * ); -static int SplitMat( int , double *, double *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestFits( AstFitsChan *, const char *, int *, int * ); -static int Use( AstFitsChan *, int, int, int * ); -static int Ustrcmp( const char *, const char *, int * ); -static int Ustrncmp( const char *, const char *, size_t, int * ); -static int WATCoeffs( const char *, int, double **, int **, int *, int * ); -static int WcsFromStore( AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static int WcsNatPole( AstFitsChan *, AstWcsMap *, double, double, double, double *, double *, double *, int * ); -static int WorldAxes( AstFitsChan *this, AstMapping *, double *, int *, int * ); -static int Write( AstChannel *, AstObject *, int * ); -static void *CardData( AstFitsChan *, size_t *, int * ); -static void AdaptLut( AstMapping *, int, double, double, double, double, double, double **, double **, int *, int * ); -static void AddFrame( AstFitsChan *, AstFrameSet *, int, int, FitsStore *, char, const char *, const char *, int * ); -static void ChangePermSplit( AstMapping *, int * ); -static void CheckZero( char *, double, int, int * ); -static void Chpc1( double *, double *, int, int *, int *, int * ); -static void ClassTrans( AstFitsChan *, AstFitsChan *, int, int, const char *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void CreateKeyword( AstFitsChan *, const char *, char [ FITSNAMLEN + 1 ], int * ); -static void DSBSetUp( AstFitsChan *, FitsStore *, AstDSBSpecFrame *, char, double, const char *, const char *, int * ); -static void DSSToStore( AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static void DelFits( AstFitsChan *, int * ); -static void Delete( AstObject *, int * ); -static void DeleteCard( AstFitsChan *, const char *, const char *, int * ); -static void DistortMaps( AstFitsChan *, FitsStore *, char, int , AstMapping **, AstMapping **, AstMapping **, AstMapping **, const char *, const char *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void EmptyFits( AstFitsChan *, int * ); -static void FindWcs( AstFitsChan *, int, int, int, const char *, const char *, int * ); -static void FixNew( AstFitsChan *, int, int, const char *, const char *, int * ); -static void FixUsed( AstFitsChan *, int, int, int, const char *, const char *, int * ); -static void FormatCard( AstFitsChan *, char *, const char *, int * ); -static void FreeItem( double ****, int * ); -static void FreeItemC( char *****, int * ); -static void GetFiducialNSC( AstWcsMap *, double *, double *, int * ); -static void GetFiducialPPC( AstWcsMap *, double *, double *, int * ); -static void GetNextData( AstChannel *, int, char **, char **, int * ); -static void InsCard( AstFitsChan *, int, const char *, int, void *, const char *, const char *, const char *, int * ); -static void MakeBanner( const char *, const char *, const char *, char [ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN + 1 ], int * ); -static void MakeIndentedComment( int, char, const char *, const char *, char [ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN + 1], int * ); -static void MakeIntoComment( AstFitsChan *, const char *, const char *, int * ); -static void MakeInvertable( double **, int, double *, int * ); -static void MarkCard( AstFitsChan *, int * ); -static void NewCard( AstFitsChan *, const char *, int, const void *, const char *, int, int * ); -static void PreQuote( const char *, char [ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN - 3 ], int * ); -static void PurgeWCS( AstFitsChan *, int * ); -static void PutCards( AstFitsChan *, const char *, int * ); -static void PutFits( AstFitsChan *, const char [ AST__FITSCHAN_FITSCARDLEN + 1 ], int, int * ); -static void PutTable( AstFitsChan *, AstFitsTable *, const char *, int * ); -static void PutTables( AstFitsChan *, AstKeyMap *, int * ); -static void ReadFits( AstFitsChan *, int * ); -static void ReadFromSource( AstFitsChan *, int * ); -static void RemoveTables( AstFitsChan *, const char *, int * ); -static void RetainFits( AstFitsChan *, int * ); -static void RoundFString( char *, int, int * ); -static void SetAlgCode( char *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetFitsCF( AstFitsChan *, const char *, double *, const char *, int, int * ); -static void SetFitsCI( AstFitsChan *, const char *, int *, const char *, int, int * ); -static void SetFitsCM( AstFitsChan *, const char *, int, int * ); -static void SetFitsCN( AstFitsChan *, const char *, const char *, const char *, int, int * ); -static void SetFitsCom( AstFitsChan *, const char *, const char *, int, int * ); -static void SetFitsF( AstFitsChan *, const char *, double, const char *, int, int * ); -static void SetFitsI( AstFitsChan *, const char *, int, const char *, int, int * ); -static void SetFitsL( AstFitsChan *, const char *, int, const char *, int, int * ); -static void SetFitsS( AstFitsChan *, const char *, const char *, const char *, int, int * ); -static void SetFitsU( AstFitsChan *, const char *, const char *, int, int * ); -static void SetItem( double ****, int, int, char, double, int * ); -static void SetItemC( char *****, int, int, char, const char *, int * ); -static void SetSourceFile( AstChannel *, const char *, int * ); -static void SetValue( AstFitsChan *, const char *, void *, int, const char *, int * ); -static void ShowFits( AstFitsChan *, int * ); -static void Shpc1( double, double, int, double *, double *, int * ); -static void SinkWrap( void (*)( const char * ), const char *, int * ); -static void SkyPole( AstWcsMap *, AstMapping *, int, int, int *, char, FitsStore *, const char *, const char *, int * ); -static void TableSource( AstFitsChan *, void (*)( AstFitsChan *, const char *, int, int, int * ), int * ); -static void TidyOffsets( AstFrameSet *, int * ); -static void Warn( AstFitsChan *, const char *, const char *, const char *, const char *, int * ); -static void WcsFcRead( AstFitsChan *, AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static void WcsToStore( AstFitsChan *, AstFitsChan *, FitsStore *, const char *, const char *, int * ); -static void WriteBegin( AstChannel *, const char *, const char *, int * ); -static void WriteDouble( AstChannel *, const char *, int, int, double, const char *, int * ); -static void WriteEnd( AstChannel *, const char *, int * ); -static void WriteFits( AstFitsChan *, int * ); -static void WriteInt( AstChannel *, const char *, int, int, int, const char *, int * ); -static void WriteIsA( AstChannel *, const char *, const char *, int * ); -static void WriteObject( AstChannel *, const char *, int, int, AstObject *, const char *, int * ); -static void WriteString( AstChannel *, const char *, int, int, const char *, const char *, int * ); -static void WriteToSink( AstFitsChan *, int * ); -static void SetTableSource( AstFitsChan *, - void (*)( void ), - void (*)( void (*)( void ), - AstFitsChan *, const char *, int, int, int * ), int * ); -static void TabSourceWrap( void (*)( void ), - AstFitsChan *, const char *, int, int, int * ); -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ - -static void AdaptLut( AstMapping *map, int npos, double eps, double x0, - double x1, double v0, double v1, double **xtab, - double **vtab, int *nsamp, int *status ){ -/* -* Name: -* AdaptLut - -* Purpose: -* Create a table of optimally sampled values for a Mapping. - -* Type: -* Private function. - -* Synopsis: -* void AdaptLut( AstMapping *map, int npos, double eps, double x0, -* double x1, double v0, double v1, double **xtab, -* double **vtab, int *nsamp, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function returns a look-up table holding samples of the supplied -* 1D mapping. The input values at which the samples are taken are -* returned in the "xtab" array, and the Mapping output values at -* these input values are returned in the "vtab" array. The sample -* spacing is smaller at positions where the output gradient is -* changing more rapidly (i.e. where the output is more non-linear). - -* Parameters: -* map -* Pointer to the Mapping. Should have 1 input and 1 output. -* npos -* The minimum number of samples to place within the interval to be -* sampled, excluding the two end points (which are always sampeld -* anyway). These samples are placed evenly through the [x0,x1] - interval. The interval between adjacent samples will be further -* subdivided if necessary by calling this function recursively. -* eps -* The maximum error in X (i.e. the Mapping input) allowed before -* the supplied interval is subdivided further by a recursive call -* to this function. -* x0 -* The Mapping input value at the start of the interval to be sampled. -* It is assumed that this value is already stored in (*xtab)[0] on -* entry. -* x1 -* The Mapping input value at the end of the interval to be sampled. -* v0 -* The Mapping output value at the start of the interval to be sampled. -* It is assumed that this value is already stored in (*vtab)[0] on -* entry. -* v1 -* The Mapping output value at the end of the interval to be sampled. -* xtab -* Address of a pointer to the array in which to store the Mapping -* input values at which samples were taken. The supplied pointer -* may be changed on exit to point to a larger array. New values -* are added to the end of this array. The initial size of the array -* is given by the supplied value for "*nsamp" -* vtab -* Address of a pointer to the array in which to store the Mapping -* output value at each sample. The supplied pointer may be changed -* on exit to point to a larger array. New values are added to the -* end of this array. The initial size of the array is given by the -* supplied value for "*nsamp". -* nsamp -* Address of an int holding the number of values in the "*xtab" -* and "*ytab" arrays. Updated on exit to include the new values -* added to the arrays by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The size of the returned xtab and vtab arrays. -*/ - -/* Local Variables: */ - double *vv; /* Pointer to Mapping output values */ - double *xx; /* Pointer to Mapping input values */ - double dx; /* Step between sample positions */ - double rg; /* Reciprocal of gradient of (x0,v0)->(x1,v1) line */ - double xx0; /* X at first new sample position */ - int ipos; /* Interior sample index */ - int isamp; /* Index into extended xtab and vtab arrays. */ - int subdivide; /* Subdivide each subinterval? */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Allocate work space. */ - xx = astMalloc( sizeof( double )*npos ); - vv = astMalloc( sizeof( double )*npos ); - if( astOK ) { - -/* Set up the evenly spaced interior sample positions. */ - dx = ( x1 - x0 )/( npos + 1 ); - xx0 = x0 + dx; - for( ipos = 0; ipos < npos; ipos++ ) { - xx[ ipos ] = xx0 + ipos*dx; - } - -/* Find the Mapping output values at these input values. */ - astTran1( map, npos, xx, 1, vv ); - -/* See if any of these samples deviate significantly from the straight line - defined by (x0,v0) and (x1,v1). If any such sample is found, we call - this function recursively to sample the subdivided intervals. First - handle cases where the straight line has zero gradient. */ - subdivide = 0; - if( v0 == v1 ) { - -/* Subdivide if any of the interior sample values are different to the - end values. */ - for( ipos = 0; ipos < npos; ipos++ ) { - if( vv[ ipos ] != v0 ) { - subdivide = 1; - break; - } - } - -/* Now handle cases where the line has non-zero gradient. Subdivide if any - of the interior sample input positions are further than "eps" from the - input position that would give the same output value if the mapping was - linear. */ - } else { - rg = ( x1 - x0 )/( v1 - v0 ); - for( ipos = 0; ipos < npos; ipos++ ) { - if( vv[ ipos ] == AST__BAD || - fabs( rg*( vv[ ipos ] - v0 ) - ( xx[ ipos ] - x0 ) ) > eps ) { - subdivide = 1; - break; - } - } - } - -/* If required, call this function recursively to subdivide each section - of the supplied input interval, and append samples to the returned - arrays. */ - if( subdivide ) { - -/* Do each sub-interval, except the last one. The number of subintervals - is one more than the number of interior samples. */ - for( ipos = 0; ipos < npos; ipos++ ) { - -/* Append samples covering the current subinterval to the ends of the - arrays. */ - AdaptLut( map, npos, eps, x0, xx[ ipos ], v0, vv[ ipos ], - xtab, vtab, nsamp, status ); - -/* Store the starting position for the next sub-interval. */ - x0 = xx[ ipos ]; - v0 = vv[ ipos ]; - } - -/* Now do the final sub-interval. */ - AdaptLut( map, npos, eps, x0, x1, v0, v1, xtab, vtab, nsamp, status ); - -/* If we do not need to subdivide, store the samples in the returned - array, together with the supplied final point. */ - } else { - -/* Extend the arrays. */ - isamp = *nsamp; - *nsamp += npos + 1; - *xtab = astGrow( *xtab, *nsamp, sizeof( double ) ); - *vtab = astGrow( *vtab, *nsamp, sizeof( double ) ); - if( astOK ) { - -/* Store the sample positions and values at the end of the extended - arrays. */ - for( ipos = 0; ipos < npos; ipos++, isamp++ ) { - (*xtab)[ isamp ] = xx[ ipos ]; - (*vtab)[ isamp ] = vv[ ipos ]; - } - (*xtab)[ isamp ] = x1; - (*vtab)[ isamp ] = v1; - } - } - } - -/* Free resources. */ - xx = astFree( xx ); - vv= astFree( vv ); -} - -static int AddEncodingFrame( AstFitsChan *this, AstFrameSet *fs, int encoding, - const char *method, const char *class, int *status ){ - -/* -* Name: -* AddEncodingFrame - -* Purpose: -* Add a Frame which conforms to the requirements of the specified encoding. - -* Type: -* Private function. - -* Synopsis: -* int AddEncodingFrame( AstFitsChan *this, AstFrameSet *fs, int encoding, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function attempts to create a Frame based on the current Frame -* of the supplied FrameSet, which conforms to the requirements of the -* specified Encoding. If created, this Frame is added into the -* FrameSet as the new current Frame, and the index of the original current -* Frame is returned. - -* Parameters: -* this -* Pointer to the FitsChan. -* fs -* Pointer to the FrameSet. -* encoding -* The encoding in use. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The index of the original current Frame in the FrameSet. A value of -* AST__NOFRAME is returned if no new Frame is added to the FrameSet, -* or if an error occurs. -*/ - -/* Local Variables: */ - AstCmpFrame *cmpfrm; /* Pointer to spectral cube frame */ - AstFrame *cfrm; /* Pointer to original current Frame */ - AstFrame *newfrm; /* Frame describing coord system to be used */ - AstFrame *pfrm; /* Pointer to primary Frame containing axis */ - AstFrameSet *fsconv; /* FrameSet converting what we have to what we want */ - AstMapping *map; /* Mapping from what we have to what we want */ - AstSkyFrame *skyfrm; /* Pointer to SkyFrame */ - AstSpecFrame *specfrm; /* Pointer to SpecFrame */ - AstSystemType sys; /* Frame coordinate system */ - int i; /* Axis index */ - int naxc; /* No. of axes in original current Frame */ - int paxis; /* Axis index in primary frame */ - int result; /* Returned value */ - -/* Initialise */ - result = AST__NOFRAME; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the current Frame and note how many axes it has. */ - cfrm = astGetFrame( fs, AST__CURRENT ); - naxc = astGetNaxes( cfrm ); - -/* FITS-CLASS */ -/* ========== */ - if( encoding == FITSCLASS_ENCODING ) { - -/* Try to locate a SpecFrame and a SkyFrame in the current Frame. */ - specfrm = NULL; - skyfrm = NULL; - for( i = 0; i < naxc; i++ ) { - astPrimaryFrame( cfrm, i, &pfrm, &paxis ); - if( astIsASpecFrame( pfrm ) ) { - if( !specfrm ) specfrm = astCopy( pfrm ); - } else if( IsASkyFrame( pfrm ) ) { - if( !skyfrm ) skyfrm = astCopy( pfrm ); - } - pfrm = astAnnul( pfrm ); - } - -/* Cannot do anything if either is missing. */ - if( specfrm && skyfrm ) { - -/* If the spectral axis is not frequency, set it to frequency. Also set - spectral units of "Hz". */ - sys = astGetSystem( specfrm ); - if( sys != AST__FREQ ) { - astSetSystem( specfrm, AST__FREQ ); - sys = AST__FREQ; - } - -/* Ensure the standard of rest is Source and units are "Hz". */ - astSetUnit( specfrm, 0, "Hz" ); - astSetStdOfRest( specfrm, AST__SCSOR ); - -/* The celestial axes must be either FK4, FK5 or galactic. */ - sys = astGetSystem( skyfrm ); - if( sys != AST__FK4 && sys != AST__FK5 && sys != AST__GALACTIC ) { - astSetSystem( skyfrm, AST__FK5 ); - sys = AST__FK5; - } - -/* FK5 systems must be J2000, and FK4 must be B1950. */ - if( sys == AST__FK5 ) { - astSetC( skyfrm, "Equinox", "J2000.0" ); - } else if( sys == AST__FK4 ) { - astSetC( skyfrm, "Equinox", "B1950.0" ); - } - -/* Combine the spectral and celestial Frames into a single CmpFrame with - the spectral axis being the first axis. */ - cmpfrm = astCmpFrame( specfrm, skyfrm, "", status ); - -/* Attempt to obtain the current Frame of the supplied FrameSet to this - new Frame. */ - fsconv = astConvert( cfrm, cmpfrm, "" ); - if( fsconv ) { - -/* Get the Mapping and current Frame from the rconversion FrameSet. */ - newfrm = astGetFrame( fsconv, AST__CURRENT ); - map = astGetMapping( fsconv, AST__BASE, AST__CURRENT ); - -/* Save the original current Frame index. */ - result = astGetCurrent( fs ); - -/* Add the new Frame into the supplied FrameSet using the above Mapping - to connect it to the original current Frame. The new Frame becomes the - current Frame. */ - astAddFrame( fs, AST__CURRENT, map, newfrm ); - -/* Free resources */ - map = astAnnul( map ); - newfrm = astAnnul( newfrm ); - fsconv = astAnnul( fsconv ); - } - -/* Free resources */ - cmpfrm = astAnnul( cmpfrm ); - } - -/* Release resources. */ - if( specfrm ) specfrm = astAnnul( specfrm ); - if( skyfrm ) skyfrm = astAnnul( skyfrm ); - } - -/* Free reources. */ - cfrm = astAnnul( cfrm ); - -/* Return the result */ - return result; -} - -static void AddFrame( AstFitsChan *this, AstFrameSet *fset, int pixel, - int npix, FitsStore *store, char s, const char *method, - const char *class, int *status ){ -/* -* Name: -* AddFrame - -* Purpose: -* Create a Frame describing a set of axes with a given co-ordinate -* version, and add it to the supplied FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void AddFrame( AstFitsChan *this, AstFrameSet *fset, int pixel, -* int npix, FitsStore *store, char s, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A Frame is created describing axis with a specific co-ordinate -* version character, reading information from the supplied FitsStore. -* A suitable Mapping is created to connect the new Frame to the pixel -* (GRID) Frame in the supplied FrameSet, and the Frame is added into -* the FrameSet using this Mapping. - -* Parameters: -* this -* The FitsChan from which the keywords were read. Warning messages -* are added to this FitsChan if the celestial co-ordinate system is -* not recognized. -* fset -* Pointer to the FrameSet to be extended. -* pixel -* The index of the pixel (GRID) Frame within fset. -* npix -* The number of pixel axes. -* store -* The FitsStore containing the required information extracted from -* the FitsChan. -* s -* The co-ordinate version character. A space means the primary -* axis descriptions. Otherwise the supplied character should be -* an upper case alphabetical character ('A' to 'Z'). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *frame; /* Requested Frame */ - AstMapping *mapping; /* Mapping from pixel to requested Frame */ - AstMapping *tmap; /* Temporary Mapping pointer */ - AstPermMap *pmap; /* PermMap pointer to add or remove axes */ - double con; /* Value to be assigned to missing axes */ - int *inperm; /* Pointer to input axis permutation array */ - int *outperm; /* Pointer to output axis permutation array */ - int i; /* Axis index */ - int nf; /* Number of Frames originally in fset */ - int nwcs; /* Number of wcs axes */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Get a Mapping between pixel coordinates and physical coordinates, using - the requested axis descriptions. Also returns a Frame describing the - physical coordinate system. */ - mapping = WcsMapFrm( this, store, s, &frame, method, class, status ); - -/* Add the Frame into the FrameSet, and annul the mapping and frame. If - the new Frame has more axes than the pixel Frame, use a PermMap which - assigns constant value 1.0 to the extra axes. If the new Frame has less - axes than the pixel Frame, use a PermMap which throws away the extra - axes. */ - if( mapping != NULL ) { - nwcs = astGetNin( mapping ); - if( nwcs != npix ) { - inperm = astMalloc( sizeof(int)*(size_t)npix ); - outperm = astMalloc( sizeof(int)*(size_t)nwcs ); - if( astOK ) { - for( i = 0; i < npix; i++ ) { - inperm[ i ] = ( i < nwcs ) ? i : -1; - } - for( i = 0; i < nwcs; i++ ) { - outperm[ i ] = ( i < npix ) ? i : -1; - } - con = 1.0; - pmap = astPermMap( npix, inperm, nwcs, outperm, &con, "", status ); - tmap = (AstMapping *) astCmpMap( pmap, mapping, 1, "", status ); - pmap = astAnnul( pmap ); - (void) astAnnul( mapping ); - mapping = tmap; - } - inperm = astFree( inperm ); - outperm = astFree( outperm ); - } - -/* Record the original number of Frames in the FrameSet. */ - nf = astGetNframe( fset ); - -/* Add in the Frame (which may be a FrameSet). */ - astAddFrame( fset, pixel, mapping, frame ); - -/* Ensure the WCS Frame is the current Frame within fset (it may not be if - the frame returned by WcsMapFrm is actually a FrameSet containing a IWC - Frame as well as a WCS Frame). The WCS Frame is always the first frame - in the frame/frameset returned by WcsMapFrm. */ - astSetCurrent( fset, nf + 1 ); - -/* Annul temporary resources. */ - mapping = astAnnul( mapping ); - } - frame = astAnnul( frame ); -} - -static int AddVersion( AstFitsChan *this, AstFrameSet *fs, int ipix, int iwcs, - FitsStore *store, double *dim, char s, int encoding, - int isoff, const char *method, const char *class, - int *status ){ -/* -* Name: -* AddVersion - -* Purpose: -* Add values to a FitsStore describing a specified Frame in a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int AddVersion( AstFitsChan *this, AstFrameSet *fs, int ipix, int iwcs, -* FitsStore *store, double *dim, char s, int encoding, -* int isoff, const char *method, const char *class, -* int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Values are added to the supplied FitsStore describing the specified -* WCS Frame, and its relationship to the specified pixel Frame. These -* values are based on the standard FITS-WCS conventions. - -* Parameters: -* this -* Pointer to the FitsChan. -* fs -* Pointer to the FrameSet. -* ipix -* The index of the pixel (GRID) Frame within fset. -* iwcs -* The index of the Frame within fset to use as the WCS co-ordinate -* Frame. -* store -* The FitsStore in which to store the information extracted from -* the FrameSet. -* dim -* Pointer to an array of pixel axis dimensions. Individual elements -* will be AST__BAD if dimensions are not known. The number of -* elements should equal the number of axes in the base Frame of the -* supplied FrameSet. -* s -* The co-ordinate version character. A space means the primary -* axis descriptions. Otherwise the supplied character should be -* an upper case alphabetical character ('A' to 'Z'). -* encoding -* The encoding being used. -* isoff -* If greater than zero, the Frame is an offset SkyFrame and the -* description added to the FitsStore should describe offset coordinates. -* If less than than zero, the Frame is an offset SkyFrame and the -* description added to the FitsStore should describe absolute coordinates. -* If zero, the Frame is an absolute SkyFrame and the description added -* to the FitsSTore should (by necessity) describe absolute coordinates. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Retuned Value: -* A value of 1 is returned if the WCS Frame was succesfully added to -* the FitsStore. A value of zero is returned otherwise. -*/ - -/* Local Variables: */ - AstFrame *wcsfrm; /* WCS Frame */ - AstFrameSet *fset; /* Temporary FrameSet */ - AstMapping *iwcmap; /* Mapping from WCS to IWC Frame */ - AstMapping *mapping; /* Mapping from pixel to WCS Frame */ - AstMapping *pixiwcmap; /* Mapping from pixel to IWC Frame */ - AstMapping *tmap2; /* Temporary Mapping */ - AstMapping *tmap; /* Temporary Mapping */ - const char *old_skyrefis;/* Old value of SkyRefIs attribute */ - double *crvals; /* Pointer to array holding default CRVAL values */ - double cdelt2; /* Sum of squared PC values */ - double cdelt; /* CDELT value for axis */ - double crpix; /* CRPIX value for axis */ - double crval; /* CRVAL value for axis */ - double fitstol; /* Max departure from linearity, in pixels */ - double pc; /* Element of the PC array */ - int *axis_done; /* Flags indicating which axes have been done */ - int *wperm; /* FITS axis for each Mapping output (Frame axis) */ - int fits_i; /* FITS WCS axis index */ - int fits_j; /* FITS pixel axis index */ - int iax; /* Frame axis index */ - int icurr; /* Index of current Frame */ - int nwcs; /* No. of axes in WCS frame */ - int ret; /* Returned value */ - int sipok; /* Should SIP headers be produced? */ - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* If the frame is a SkyFrame describing offset coordinates, but the - description added to the FitsStore should be for absolute coordinates, - temporarily clear the SkyFrame SkyRefIs attribute. We need to make it - the current Frame first so that we can use the FrameSet to clear the - attribte, so that the SkyFrame will be re-mapped within the FrameSet - to take account of the clearing. For negative isoff values, set the - specific negative value to indicate the original SkyRefIs value. */ - if( isoff < 0 ) { - icurr = astGetCurrent( fs ); - astSetCurrent( fs, iwcs ); - old_skyrefis = astGetC( fs, "SkyRefIs" ); - if( astOK ) { - if( !Ustrcmp( old_skyrefis, "POLE", status ) ) { - isoff = -1; - } else if( !Ustrcmp( old_skyrefis, "ORIGIN", status ) ) { - isoff = -2; - } else { - isoff = -3; - } - } - astClear( fs, "SkyRefIs" ); - astSetCurrent( fs, icurr ); - } else { - old_skyrefis = AST__BAD_REF; - } - -/* Construct a new FrameSet holding the pixel and WCS Frames from the - supplied FrameSet, but in which the current Frame is a copy of the - supplied WCS Frame, but optionally extended to include any extra axes - needed to conform to the FITS model. For instance, if the WCS Frame - consists of a single 1D SpecFrame with a defined celestial reference - position (SpecFrame attributes RefRA and RefDec), then FITS-WCS paper - III requires there to be a pair of celestial axes in the WCS Frame in - which the celestial reference point for the spectral axis is defined. */ - fset = MakeFitsFrameSet( this, fs, ipix, iwcs, encoding, method, class, status ); - -/* If required, re-instate the original value of the SkyRefIs attribute - in the supplied FrameSet. */ - if( old_skyrefis != AST__BAD_REF ) { - astSetCurrent( fs, iwcs ); - astSetC( fs, "SkyRefIs", old_skyrefis ); - astSetCurrent( fs, icurr ); - } - -/* Abort if the FrameSet could not be produced. */ - if( !fset ) return ret; - -/* Get the Mapping from base to current Frame and check its inverse is - defined. Return if not. Note, we can handle non-invertable Mappings if - we are allowed to use the -TAB algorithm. */ - mapping = astGetMapping( fset, AST__BASE, AST__CURRENT ); - wcsfrm = astGetFrame( fset, AST__CURRENT ); - if( !astGetTranInverse( mapping ) && astGetTabOK( this ) <= 0 ) { - mapping = astAnnul( mapping ); - wcsfrm = astAnnul( wcsfrm ); - fset = astAnnul( fset ); - return ret; - } - -/* We now need to choose the "FITS WCS axis" (i.e. the number that is included - in FITS keywords such as CRVAL2) for each axis of the output Frame. - Allocate memory to store these indices. */ - nwcs = astGetNout( mapping ); - wperm = astMalloc( sizeof(int)*(size_t) nwcs ); - -/* Attempt to use the FitsAxisOrder attribute to determine the order. If - this is set to "", then for each WCS axis, we use the index of - the pixel axis which is most closely aligned with it. */ - if( !FitsAxisOrder( this, nwcs, wcsfrm, wperm, status ) && - !WorldAxes( this, mapping, dim, wperm, status ) ) { - wperm = astFree( wperm ); - mapping = astAnnul( mapping ); - wcsfrm = astAnnul( wcsfrm ); - fset = astAnnul( fset ); - return ret; - } - -/* Allocate an array of flags, one for each axis, which indicate if a - description of the corresponding axis has yet been stored in the - FitsStore. Initialise them to indicate that no axes have yet been - described. */ - axis_done = astMalloc( sizeof(int)*(size_t) nwcs ); - if( astOK ) for( iax = 0; iax < nwcs; iax++ ) axis_done[ iax ] = 0; - -/* Get the original reference point from the FitsChan and convert it into - the require WCS Frame. This is used as the default reference point (some - algorithms may choose to ignore this default reference point ). */ - crvals = ReadCrval( this, wcsfrm, s, method, class, status ); - -/* For each class of FITS conventions (celestial, spectral, others), - identify any corresponding axes within the WCS Frame and add - descriptions of them to the FitsStore. These descriptions are in terms - of the FITS keywords defined in the corresponding FITS-WCS paper. Note, - the keywords which describe the pixel->IWC mapping (CRPIX, CD, PC, - CDELT) are not stored by these functions, instead each function - returns a Mapping from WCS to IWC coords (these Mappings pass on axes - of the wrong class without change). These Mappings are combined in - series to get the final WCS->IWC Mapping. First do celestial axes. */ - iwcmap = CelestialAxes( this, fset, dim, wperm, s, store, axis_done, - isoff, method, class, status ); - -/* Now look for spectral axes, and update the iwcmap. */ - tmap = SpectralAxes( this, fset, dim, wperm, s, store, crvals, axis_done, - method, class, status ); - tmap2 = (AstMapping *) astCmpMap( iwcmap, tmap, 1, "", status ); - tmap = astAnnul( tmap ); - (void) astAnnul( iwcmap ); - iwcmap = tmap2; - -/* Finally add descriptions of any axes not yet described (they are - assumed to be linear), and update the iwcmap. */ - tmap = OtherAxes( this, fset, dim, wperm, s, store, crvals, axis_done, - method, class, status ); - tmap2 = (AstMapping *) astCmpMap( iwcmap, tmap, 1, "", status ); - tmap = astAnnul( tmap ); - (void) astAnnul( iwcmap ); - iwcmap = tmap2; - -/* The "iwcmap" Mapping found above converts from the WCS Frame to the IWC - Frame. Combine the pixel->WCS Mapping with this WCS->IWC Mapping to - get the pixel->IWC Mapping. */ - pixiwcmap = (AstMapping *) astCmpMap( mapping, iwcmap, 1, "", status ); - mapping = astAnnul( mapping ); - iwcmap = astAnnul( iwcmap ); - -/* Get the maximum departure from linearity, in pixels, for the pixiwcmap - mapping to be considered linear. */ - fitstol = astGetFitsTol( this ); - -/* See if SIP headers are to be produced. */ - sipok = astGetSipOK( this ); - -/* Now attempt to store values for the keywords describing the pixel->IWC - Mapping (CRPIX, CD, PC, CDELT). This tests that the iwcmap is linear. - It can also include keywords describing distortion in the form of SIP - headers, if appropriate. Zero is returned if the test fails. */ - ret = MakeIntWorld( pixiwcmap, wcsfrm, wperm, s, store, dim, fitstol, - sipok, method, class, status ); - -/* If succesfull... */ - if( ret ) { - -/* Store the Domain name as the WCSNAME keyword (if set). */ - if( astTestDomain( wcsfrm ) ) { - SetItemC( &(store->wcsname), 0, 0, s, (char *) astGetDomain( wcsfrm ), - status ); - } - -/* Store the UT1-UTC correction, if set, converting from seconds to days - (as used by JACH). */ - if( astTestDut1( wcsfrm ) && s == ' ' ) { - SetItem( &(store->dut1), 0, 0, ' ', astGetDut1( wcsfrm )/SPD, status ); - } - -/* Store the TAI-UTC correction, if set. */ - if( astTestDtai( wcsfrm ) && s == ' ' ) { - SetItem( &(store->dtai), 0, 0, ' ', astGetDtai( wcsfrm ), status ); - } - -/* Set CRVAL values which are very small compared to the pixel size to - zero. */ - for( iax = 0; iax < nwcs; iax++ ) { - fits_i = wperm[ iax ]; - crval = GetItem( &(store->crval), fits_i, 0, s, NULL, method, class, - status ); - if( crval != AST__BAD ) { - cdelt2 = 0.0; - for( fits_j = 0; fits_j < nwcs; fits_j++ ){ - pc = GetItem( &(store->pc), fits_i, fits_j, s, NULL, method, class, status ); - if( pc == AST__BAD ) pc = ( fits_i == fits_j ) ? 1.0 : 0.0; - cdelt2 += pc*pc; - } - cdelt = GetItem( &(store->cdelt), fits_i, 0, s, NULL, method, class, status ); - if( cdelt == AST__BAD ) cdelt = 1.0; - cdelt2 *= ( cdelt*cdelt ); - if( fabs( crval ) < sqrt( DBL_EPSILON*cdelt2 ) ) { - SetItem( &(store->crval), fits_i, 0, s, 0.0, status ); - } - } - } - -/* Round CRPIX values to the nearest millionth of a pixel. */ - for( iax = 0; iax < nwcs; iax++ ) { - crpix = GetItem( &(store->crpix), 0, iax, s, NULL, method, class, status ); - if( crpix != AST__BAD ) { - SetItem( &(store->crpix), 0, iax, s, - floor( crpix*1.0E6 + 0.5 )*1.0E-6, status ); - } - } - } - -/* Free remaining resources. */ - if( crvals ) crvals = astFree( crvals ); - wcsfrm = astAnnul( wcsfrm ); - pixiwcmap = astAnnul( pixiwcmap ); - axis_done = astFree( axis_done ); - wperm = astFree( wperm ); - fset = astAnnul( fset ); - -/* If an error has occurred, return zero */ - return astOK ? ret : 0; -} - -static AstMapping *AddUnitMaps( AstMapping *map, int iax, int nax, int *status ) { -/* -* Name: -* AddUnitMaps - -* Purpose: -* Embed a Mapping within a pair of parallel UnitMaps. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *AddUnitMaps( AstMapping *map, int iax, int nax, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns a Mapping which consists of the supplied Mapping -* in parallel with a pair of UnitMaps so that the first axis of the -* supplied Mapping is at a specified axis number in the returned Mapping. - -* Parameters: -* map -* Pointer to the Mapping. The Mapping must have equal numbers of -* input and output coordinates. -* iax -* The index for the first input of "map" within the returned -* Mapping. -* nax -* The number of axes for the returned Mapping. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A Mapping which has "nax" axes, and in which the "iax" axis -* corresponds to the first axis of "map". Axes lower than "iax" are -* transformed using a UnitMap, and axes higher than the last axis of -* "map" are transformed using a UnitMap. -*/ - -/* Local Variables: */ - AstMapping *ret; /* Returned Mapping */ - AstMapping *tmap0; /* Temporary Mapping */ - AstMapping *tmap1; /* Temporary Mapping */ - AstMapping *tmap2; /* Temporary Mapping */ - int nmap; /* Number of supplied Mapping inputs */ - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Initialise the returned Mapping to be a clone of the supplied Mapping. */ - ret = astClone( map ); - -/* Note the number of inputs of the supplied Mapping (assumed to be equal - to the number of outputs). */ - nmap = astGetNin( map ); - -/* If necessary produce a parallel CmpMap which combines the Mapping with a - UnitMap representing the axes lower than "iax". */ - if( iax > 0 ) { - tmap0 = (AstMapping *) astUnitMap( iax, "", status ); - tmap1 = (AstMapping *) astCmpMap( tmap0, ret, 0, "", status ); - ret = astAnnul( ret ); - tmap0 = astAnnul( tmap0 ); - ret = tmap1; - } - -/* If necessary produce a parallel CmpMap which combines the Mapping with a - UnitMap representing the axes higher than "iax+nmap". */ - if( iax + nmap < nax ) { - tmap1 = (AstMapping *) astUnitMap( nax - iax - nmap, "", status ); - tmap2 = (AstMapping *) astCmpMap( ret, tmap1, 0, "", status ); - ret = astAnnul( ret ); - tmap1 = astAnnul( tmap1 ); - ret = tmap2; - } - -/* Return the result. */ - return ret; -} - -static int AIPSFromStore( AstFitsChan *this, FitsStore *store, - const char *method, const char *class, int *status ){ - -/* -* Name: -* AIPSFromStore - -* Purpose: -* Store WCS keywords in a FitsChan using FITS-AIPS encoding. - -* Type: -* Private function. - -* Synopsis: - -* int AIPSFromStore( AstFitsChan *this, FitsStore *store, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function copies the WCS information stored in the supplied -* FitsStore into the supplied FitsChan, using FITS-AIPS encoding. -* -* AIPS encoding is like FITS-WCS encoding but with the following -* restrictions: -* -* 1) The celestial projection must not have any projection parameters -* which are not set to their default values. The one exception to this -* is that SIN projections are acceptable if the associated projection -* parameter PV_1 is zero and PV_2 = cot( reference point -* latitude). This is encoded using the string "-NCP". The SFL projection -* is encoded using the string "-GLS". Note, the original AIPS WCS -* system only recognised a small subset of the currently available -* projections, but some more recent AIPS-like software recognizes some -* of the new projections included in the FITS-WCS encoding. The AIT, -* GLS and MER can only be written if the CRVAL keywords are zero for -* both longitude and latitude axes. -* -* 2) The celestial axes must be RA/DEC, galactic or ecliptic. -* -* 3) LONPOLE and LATPOLE must take their default values. -* -* 4) Only primary axis descriptions are written out. -* -* 5) EPOCH is written instead of EQUINOX & RADECSYS, and uses the -* IAU 1984 rule ( EPOCH < 1984.0 is treated as a Besselian epoch -* and implies RADECSYS=FK4, EPOCH >= 1984.0 is treated as a -* Julian epoch and implies RADECSYS=FK5). The RADECSYS & EQUINOX -* values in the FitsStore must be consistent with this rule. -* -* 6) Any rotation produced by the PC matrix must be restricted to -* the celestial plane, and must involve no shear. A CROTA keyword -* with associated CDELT values are produced instead of the PC -* matrix. -* -* 7) ICRS is not supported. -* -* 8) Spectral axes can be created only for FITS-WCS CTYPE values of "FREQ" -* "VRAD" and "VOPT-F2W" and with standards of rest of LSRK, LSRD, -* BARYCENT and GEOCENTR. - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if succesfull, and zero is returned -* otherwise. -*/ - -/* Local Variables: */ - char *comm; /* Pointer to comment string */ - const char *cval; /* Pointer to string keyword value */ - const char *specunit;/* Pointer to corrected spectral units string */ - char combuf[80]; /* Buffer for FITS card comment */ - char lattype[MXCTYPELEN];/* Latitude axis CTYPE */ - char lontype[MXCTYPELEN];/* Longitude axis CTYPE */ - char s; /* Co-ordinate version character */ - char sign[2]; /* Fraction's sign character */ - char spectype[MXCTYPELEN];/* Spectral axis CTYPE */ - double *cdelt; /* Pointer to CDELT array */ - double cdl; /* CDELT term */ - double cdlat_lon; /* Off-diagonal CD element */ - double cdlon_lat; /* Off-diagonal CD element */ - double coscro; /* Cos( CROTA ) */ - double crota; /* CROTA value to use */ - double epoch; /* Epoch of reference equinox */ - double fd; /* Fraction of a day */ - double latval; /* CRVAL for latitude axis */ - double lonval; /* CRVAL for longitude axis */ - double mjd99; /* MJD at start of 1999 */ - double p1, p2; /* Projection parameters */ - double rho_a; /* First estimate of CROTA */ - double rho_b; /* Second estimate of CROTA */ - double sincro; /* Sin( CROTA ) */ - double specfactor; /* Factor for converting internal spectral units */ - double val; /* General purpose value */ - int axlat; /* Index of latitude FITS WCS axis */ - int axlon; /* Index of longitude FITS WCS axis */ - int axrot1; /* Index of first CROTA rotation axis */ - int axrot2; /* Index of second CROTA rotation axis */ - int axspec; /* Index of spectral FITS WCS axis */ - int i; /* Axis index */ - int ihmsf[ 4 ]; /* Hour, minute, second, fractional second */ - int iymdf[ 4 ]; /* Year, month, date, fractional day */ - int j; /* Axis index */ - int jj; /* SlaLib status */ - int naxis; /* No. of axes */ - int ok; /* Is FitsSTore OK for IRAF encoding? */ - int prj; /* Projection type */ - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Initialise */ - specunit = ""; - specfactor = 1.0; - -/* First check that the values in the FitsStore conform to the - requirements of the AIPS encoding. Assume they do to begin with. */ - ok = 1; - -/* Just do primary axes. */ - s = ' '; - -/* Look for the primary celestial axes. */ - FindLonLatSpecAxes( store, s, &axlon, &axlat, &axspec, method, class, status ); - -/* If both longitude and latitude axes are present ...*/ - if( axlon >= 0 && axlat >= 0 ) { - -/* Get the CRVAL values for both axes. */ - latval = GetItem( &( store->crval ), axlat, 0, s, NULL, method, class, status ); - if( latval == AST__BAD ) ok = 0; - lonval = GetItem( &( store->crval ), axlon, 0, s, NULL, method, class, status ); - if( lonval == AST__BAD ) ok = 0; - -/* Get the CTYPE values for both axes. Extract the projection type as - specified by the last 4 characters in the latitude CTYPE keyword value. */ - cval = GetItemC( &(store->ctype), axlon, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else { - strcpy( lontype, cval ); - } - cval = GetItemC( &(store->ctype), axlat, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - prj = AST__WCSBAD; - } else { - strcpy( lattype, cval ); - prj = astWcsPrjType( cval + 4 ); - } - -/* Check the projection type is OK. */ - if( prj == AST__WCSBAD ){ - ok = 0; - } else if( prj != AST__SIN ){ - -/* There must be no projection parameters. */ - if( GetMaxJM( &(store->pv), ' ', status ) >= 0 ) { - ok = 0; - -/* FITS-AIPS cannot handle the AST-specific TPN projection. */ - } else if( prj == AST__TPN ) { - ok = 0; - -/* For AIT, MER and GLS, check that the reference point is the origin of - the celestial co-ordinate system. */ - } else if( prj == AST__MER || - prj == AST__AIT || - prj == AST__SFL ) { - if( latval != 0.0 || lonval != 0.0 ){ - ok = 0; - -/* Change the new SFL projection code to to the older equivalent GLS */ - } else if( prj == AST__SFL ){ - (void) strcpy( lontype + 4, "-GLS" ); - (void) strcpy( lattype + 4, "-GLS" ); - } - } - -/* SIN projections are only acceptable if the associated projection - parameters are both zero, or if the first is zero and the second - = cot( reference point latitude ) (the latter case is equivalent to - the old NCP projection). */ - } else { - p1 = GetItem( &( store->pv ), axlat, 1, s, NULL, method, class, status ); - p2 = GetItem( &( store->pv ), axlat, 2, s, NULL, method, class, status ); - if( p1 == AST__BAD ) p1 = 0.0; - if( p2 == AST__BAD ) p2 = 0.0; - ok = 0; - if( p1 == 0.0 ) { - if( p2 == 0.0 ) { - ok = 1; - } else if( fabs( p2 ) >= 1.0E14 && latval == 0.0 ){ - ok = 1; - (void) strcpy( lontype + 4, "-NCP" ); - (void) strcpy( lattype + 4, "-NCP" ); - } else if( fabs( p2*tan( AST__DD2R*latval ) - 1.0 ) - < 0.01 ){ - ok = 1; - (void) strcpy( lontype + 4, "-NCP" ); - (void) strcpy( lattype + 4, "-NCP" ); - } - } - } - -/* Identify the celestial coordinate system from the first 4 characters of the - longitude CTYPE value. Only RA, galactic longitude, and ecliptic - longitude can be stored using FITS-AIPS. */ - if( ok && strncmp( lontype, "RA--", 4 ) && - strncmp( lontype, "GLON", 4 ) && - strncmp( lontype, "ELON", 4 ) ) ok = 0; - -/* If the physical Frame requires a LONPOLE or LATPOLE keyword, it cannot - be encoded using FITS-IRAF. */ - if( GetItem( &(store->latpole), 0, 0, s, NULL, method, class, status ) - != AST__BAD || - GetItem( &(store->lonpole), 0, 0, s, NULL, method, class, status ) - != AST__BAD ) ok = 0; - } - -/* If a spectral axis is present ...*/ - if( ok && axspec >= 0 ) { - -/* Get the CTYPE values for the axis, and find the AIPS equivalent, if - possible. */ - cval = GetItemC( &(store->ctype), axspec, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else { - if( !strncmp( cval, "FREQ", astChrLen( cval ) ) ) { - strcpy( spectype, "FREQ" ); - } else if( !strncmp( cval, "VRAD", astChrLen( cval ) ) ) { - strcpy( spectype, "VELO" ); - } else if( !strncmp( cval, "VOPT-F2W", astChrLen( cval ) ) ) { - strcpy( spectype, "FELO" ); - } else { - ok = 0; - } - } - -/* If OK, check the SPECSYS value and add the AIPS equivalent onto the - end of the CTYPE value.*/ - cval = GetItemC( &(store->specsys), 0, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else if( ok ) { - if( !strncmp( cval, "LSRK", astChrLen( cval ) ) ) { - strcpy( spectype+4, "-LSR" ); - } else if( !strncmp( cval, "LSRD", astChrLen( cval ) ) ) { - strcpy( spectype+4, "-LSD" ); - } else if( !strncmp( cval, "BARYCENT", astChrLen( cval ) ) ) { - strcpy( spectype+4, "-HEL" ); - } else if( !strncmp( cval, "GEOCENTR", astChrLen( cval ) ) ) { - strcpy( spectype+4, "-GEO" ); - } else { - ok = 0; - } - } - -/* If still OK, ensure the spectral axis units are Hz or m/s. */ - cval = GetItemC( &(store->cunit), axspec, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else if( ok ) { - if( !strcmp( cval, "Hz" ) ) { - specunit = "HZ"; - specfactor = 1.0; - } else if( !strcmp( cval, "kHz" ) ) { - specunit = "HZ"; - specfactor = 1.0E3; - } else if( !strcmp( cval, "MHz" ) ) { - specunit = "HZ"; - specfactor = 1.0E6; - } else if( !strcmp( cval, "GHz" ) ) { - specunit = "HZ"; - specfactor = 1.0E9; - } else if( !strcmp( cval, "m/s" ) ) { - specunit = "m/s"; - specfactor = 1.0; - } else if( !strcmp( cval, "km/s" ) ) { - specunit = "m/s"; - specfactor = 1.0E3; - } else { - ok = 0; - } - } - } - -/* Save the number of axes */ - naxis = GetMaxJM( &(store->crpix), ' ', status ) + 1; - -/* If this is different to the value of NAXIS abort since this encoding - does not support WCSAXES keyword. */ - if( naxis != store->naxis ) ok = 0; - -/* Allocate memory to store the CDELT values */ - if( ok ) { - cdelt = (double *) astMalloc( sizeof(double)*naxis ); - if( !cdelt ) ok = 0; - } else { - cdelt = NULL; - } - -/* Check that rotation is restricted to the celestial plane, and extract - the CDELT (diagonal) terms, etc. If there are no celestial - axes, restrict rotation to the first two non-spectral axes. */ - if( axlat < 0 && axlon < 0 ) { - if( axspec >= 0 && naxis > 2 ) { - axrot2 = ( axspec == 0 ) ? 1 : 0; - axrot1 = axrot2 + 1; - if( axrot1 == axspec ) axrot1++; - } else if( naxis > 1 ){ - axrot2 = 0; - axrot1 = 1; - } else { - axrot2 = -1; - axrot1 = -1; - } - } else { - axrot1 = axlon; - axrot2 = axlat; - } - cdlat_lon = 0.0; - cdlon_lat = 0.0; - for( i = 0; i < naxis && ok; i++ ){ - cdl = GetItem( &(store->cdelt), i, 0, s, NULL, method, class, status ); - if( cdl == AST__BAD ) cdl = 1.0; - for( j = 0; j < naxis && ok; j++ ){ - val = GetItem( &(store->pc), i, j, s, NULL, method, class, status ); - if( val == AST__BAD ) val = ( i == j ) ? 1.0 : 0.0; - val *= cdl; - if( i == j ){ - cdelt[ i ] = val; - } else if( i == axrot2 && j == axrot1 ){ - cdlat_lon = val; - } else if( i == axrot1 && j == axrot2 ){ - cdlon_lat = val; - } else if( val != 0.0 ){ - ok = 0; - } - } - } - -/* Find the CROTA and CDELT values for the celestial axes. */ - if( ok && axrot1 >= 0 && axrot2 >= 0 ) { - if( cdlat_lon > 0.0 ) { - rho_a = atan2( cdlat_lon, cdelt[ axrot1 ] ); - } else if( cdlat_lon == 0.0 ) { - rho_a = 0.0; - } else { - rho_a = atan2( -cdlat_lon, -cdelt[ axrot1 ] ); - } - if( cdlon_lat > 0.0 ) { - rho_b = atan2( cdlon_lat, -cdelt[ axrot2 ] ); - } else if( cdlon_lat == 0.0 ) { - rho_b = 0.0; - } else { - rho_b = atan2( -cdlon_lat, cdelt[ axrot2 ] ); - } - if( fabs( palDrange( rho_a - rho_b ) ) < 1.0E-2 ){ - crota = 0.5*( palDranrm( rho_a ) + palDranrm( rho_b ) ); - coscro = cos( crota ); - sincro = sin( crota ); - if( fabs( coscro ) > fabs( sincro ) ){ - cdelt[ axrot2 ] /= coscro; - cdelt[ axrot1 ] /= coscro; - } else { - cdelt[ axrot2 ] = -cdlon_lat/sincro; - cdelt[ axrot1 ] = cdlat_lon/sincro; - } - crota *= AST__DR2D; - } else { - ok = 0; - } - } else { - crota = 0.0; - } - -/* Get RADECSYS and the reference equinox (called EPOCH in FITS-AIPS). */ - cval = GetItemC( &(store->radesys), 0, 0, s, NULL, method, class, status ); - epoch = GetItem( &(store->equinox), 0, 0, s, NULL, method, class, status ); - -/* If RADECSYS was available... */ - if( cval ){ - -/* ICRS is not supported in this encoding. */ - if( !strcmp( "ICRS", cval ) ) ok = 0; - -/* If epoch was not available, set a default epoch. */ - if( epoch == AST__BAD ){ - if( !strcmp( "FK4", cval ) ){ - epoch = 1950.0; - } else if( !strcmp( "FK5", cval ) ){ - epoch = 2000.0; - } else { - ok = 0; - } - -/* If an epoch was supplied, check it is consistent with the IAU 1984 - rule. */ - } else { - if( !strcmp( "FK4", cval ) ){ - if( epoch >= 1984.0 ) ok = 0; - } else if( !strcmp( "FK5", cval ) ){ - if( epoch < 1984.0 ) ok = 0; - } else { - ok = 0; - } - } - } - -/* Only create the keywords if the FitsStore conforms to the requirements - of the FITS-AIPS encoding. */ - if( ok ) { - -/* Get and save CRPIX for all pixel axes. These are required, so break - if they are not available. */ - for( j = 0; j < naxis && ok; j++ ){ - val = GetItem( &(store->crpix), 0, j, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - } else { - sprintf( combuf, "Reference pixel on axis %d", j + 1 ); - SetValue( this, FormatKey( "CRPIX", j + 1, -1, s, status ), &val, - AST__FLOAT, combuf, status ); - } - } - -/* Get and save CRVAL for all intermediate axes. These are required, so - break if they are not available. */ - for( i = 0; i < naxis && ok; i++ ){ - val = GetItem( &(store->crval), i, 0, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - } else { - if( i == axspec ) val *= specfactor; - sprintf( combuf, "Value at ref. pixel on axis %d", i + 1 ); - SetValue( this, FormatKey( "CRVAL", i + 1, -1, s, status ), &val, - AST__FLOAT, combuf, status ); - } - } - -/* Get and save CTYPE for all intermediate axes. These are required, so - break if they are not available. Use the potentially modified versions - saved above for the celestial axes. */ - for( i = 0; i < naxis && ok; i++ ){ - if( i == axlat ) { - cval = lattype; - } else if( i == axlon ) { - cval = lontype; - } else if( i == axspec ) { - cval = spectype; - } else { - cval = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - } - if( cval && ( strlen(cval) < 5 || strcmp( cval + 4, "-TAB" ) ) ) { - comm = GetItemC( &(store->ctype_com), i, 0, s, NULL, method, class, status ); - if( !comm ) { - sprintf( combuf, "Type of co-ordinate on axis %d", i + 1 ); - comm = combuf; - } - SetValue( this, FormatKey( "CTYPE", i + 1, -1, s, status ), &cval, - AST__STRING, comm, status ); - } else { - ok = 0; - } - } - -/* CDELT values */ - if( axspec != -1 ) cdelt[ axspec ] *= specfactor; - for( i = 0; i < naxis; i++ ){ - SetValue( this, FormatKey( "CDELT", i + 1, -1, s, status ), cdelt + i, - AST__FLOAT, "Pixel size", status ); - } - -/* CUNIT values. */ - for( i = 0; i < naxis; i++ ) { - cval = GetItemC( &(store->cunit), i, 0, s, NULL, method, class, status ); - if( cval ) { - if( i == axspec ) cval = specunit; - sprintf( combuf, "Units for axis %d", i + 1 ); - SetValue( this, FormatKey( "CUNIT", i + 1, -1, s, status ), &cval, AST__STRING, - combuf, status ); - } - } - -/* CROTA */ - if( axrot2 != -1 ){ - SetValue( this, FormatKey( "CROTA", axrot2 + 1, -1, s, status ), &crota, - AST__FLOAT, "Axis rotation", status ); - } else if( ( axspec == -1 && naxis > 1 ) || - ( axspec != -1 && naxis > 2 ) ) { - SetValue( this, "CROTA1", &crota, AST__FLOAT, "Axis rotation", status ); - } - -/* Reference equinox */ - if( epoch != AST__BAD ) SetValue( this, "EPOCH", &epoch, AST__FLOAT, - "Epoch of reference equinox", status ); - -/* Date of observation. */ - val = GetItem( &(store->mjdobs), 0, 0, ' ', NULL, method, class, status ); - if( val != AST__BAD ) { - -/* The format used for the DATE-OBS keyword depends on the value of the - keyword. For DATE-OBS < 1999.0, use the old "dd/mm/yy" format. - Otherwise, use the new "ccyy-mm-ddThh:mm:ss[.ssss]" format. */ - palCaldj( 99, 1, 1, &mjd99, &jj ); - if( val < mjd99 ) { - palDjcal( 0, val, iymdf, &jj ); - sprintf( combuf, "%2.2d/%2.2d/%2.2d", iymdf[ 2 ], iymdf[ 1 ], - iymdf[ 0 ] - ( ( iymdf[ 0 ] > 1999 ) ? 2000 : 1900 ) ); - } else { - palDjcl( val, iymdf, iymdf+1, iymdf+2, &fd, &jj ); - palDd2tf( 3, fd, sign, ihmsf ); - sprintf( combuf, "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d.%3.3d", - iymdf[0], iymdf[1], iymdf[2], ihmsf[0], ihmsf[1], - ihmsf[2], ihmsf[3] ); - } - -/* Now store the formatted string in the FitsChan. */ - cval = combuf; - SetValue( this, "DATE-OBS", (void *) &cval, AST__STRING, - "Date of observation", status ); - } - -/* Spectral stuff.. */ - if( axspec >= 0 ) { - -/* Rest frequency */ - val = GetItem( &(store->restfrq), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "RESTFREQ", -1, -1, s, status ), - &val, AST__FLOAT, "[Hz] Rest frequency", status ); - } - } - -/* Release CDELT workspace */ - if( cdelt ) cdelt = (double *) astFree( (void *) cdelt ); - -/* Return zero or ret depending on whether an error has occurred. */ - return astOK ? ok : 0; -} - -static int AIPSPPFromStore( AstFitsChan *this, FitsStore *store, - const char *method, const char *class, int *status ){ - -/* -* Name: -* AIPSPPFromStore - -* Purpose: -* Store WCS keywords in a FitsChan using FITS-AIPS++ encoding. - -* Type: -* Private function. - -* Synopsis: - -* int AIPSPPFromStore( AstFitsChan *this, FitsStore *store, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function copies the WCS information stored in the supplied -* FitsStore into the supplied FitsChan, using FITS-AIPS++ encoding. -* -* AIPS++ encoding is like FITS-WCS encoding but with the following -* restrictions: -* -* 1) The celestial axes must be RA/DEC, galactic or ecliptic. -* -* 2) Only primary axis descriptions are written out. -* -* 3) RADESYS is not written and so the RADECSYS & EQUINOX values in the -* FitsStore must be consistent with the "1984" rule. -* -* 4) Any rotation produced by the PC matrix must be restricted to -* the celestial plane, and must involve no shear. A CROTA keyword -* with associated CDELT values are produced instead of the PC -* matrix. -* -* 5) ICRS is not supported. -* -* 6) Spectral axes can be created only for FITS-WCS CTYPE values of "FREQ" -* "VRAD" and "VOPT-F2W" and with standards of rest of LSRK, LSRD, -* BARYCENT and GEOCENTR. - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if succesfull, and zero is returned -* otherwise. -*/ - -/* Local Variables: */ - char *comm; /* Pointer to comment string */ - const char *cval; /* Pointer to string keyword value */ - const char *specunit;/* Pointer to corrected spectral units string */ - char combuf[80]; /* Buffer for FITS card comment */ - char lattype[MXCTYPELEN];/* Latitude axis CTYPE */ - char lontype[MXCTYPELEN];/* Longitude axis CTYPE */ - char s; /* Co-ordinate version character */ - char sign[2]; /* Fraction's sign character */ - char spectype[MXCTYPELEN];/* Spectral axis CTYPE */ - double *cdelt; /* Pointer to CDELT array */ - double cdl; /* CDELT term */ - double cdlat_lon; /* Off-diagonal CD element */ - double cdlon_lat; /* Off-diagonal CD element */ - double coscro; /* Cos( CROTA ) */ - double crota; /* CROTA value to use */ - double epoch; /* Epoch of reference equinox */ - double fd; /* Fraction of a day */ - double mjd99; /* MJD at start of 1999 */ - double rho_a; /* First estimate of CROTA */ - double rho_b; /* Second estimate of CROTA */ - double sincro; /* Sin( CROTA ) */ - double specfactor; /* Factor for converting internal spectral units */ - double val; /* General purpose value */ - int axlat; /* Index of latitude FITS WCS axis */ - int axlon; /* Index of longitude FITS WCS axis */ - int axrot1; /* Index of first CROTA rotation axis */ - int axrot2; /* Index of second CROTA rotation axis */ - int axspec; /* Index of spectral FITS WCS axis */ - int i; /* Axis index */ - int ihmsf[ 4 ]; /* Hour, minute, second, fractional second */ - int iymdf[ 4 ]; /* Year, month, date, fractional day */ - int j; /* Axis index */ - int jj; /* SlaLib status */ - int m; /* Projection parameter index */ - int maxm; /* Max projection parameter index */ - int naxis; /* No. of axes */ - int ok; /* Is FitsSTore OK for IRAF encoding? */ - int prj; /* Projection type */ - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Initialise */ - specunit = ""; - specfactor = 1.0; - maxm = 0; - -/* First check that the values in the FitsStore conform to the - requirements of the AIPS++ encoding. Assume they do to begin with. */ - ok = 1; - -/* Just do primary axes. */ - s = ' '; - -/* Save the number of axes */ - naxis = GetMaxJM( &(store->crpix), ' ', status ) + 1; - -/* Look for the primary celestial and spectral axes. */ - FindLonLatSpecAxes( store, s, &axlon, &axlat, &axspec, method, class, status ); - -/* If both longitude and latitude axes are present ...*/ - if( axlon >= 0 && axlat >= 0 ) { - -/* Get the CTYPE values for both axes. Extract the projection type as - specified by the last 4 characters in the latitude CTYPE keyword value. */ - cval = GetItemC( &(store->ctype), axlon, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else { - strcpy( lontype, cval ); - } - cval = GetItemC( &(store->ctype), axlat, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - prj = AST__WCSBAD; - } else { - strcpy( lattype, cval ); - prj = astWcsPrjType( cval + 4 ); - } - -/* FITS-AIPS++ cannot handle the AST-specific TPN projection. */ - if( prj == AST__TPN || prj == AST__WCSBAD ) ok = 0; - -/* Projection parameters. FITS-AIPS++ encoding ignores projection parameters - associated with the longitude axis. The number of parameters is limited to - 10. */ - maxm = GetMaxJM( &(store->pv), ' ', status ); - for( i = 0; i < naxis && ok; i++ ){ - if( i != axlon ) { - for( m = 0; m <= maxm; m++ ){ - val = GetItem( &(store->pv), i, m, s, NULL, method, class, status ); - if( val != AST__BAD ) { - if( i != axlat || m >= 10 ){ - ok = 0; - break; - } - } - } - } - } - -/* Identify the celestial coordinate system from the first 4 characters of the - longitude CTYPE value. Only RA, galactic longitude, and ecliptic - longitude can be stored using FITS-AIPS++. */ - if( ok && strncmp( lontype, "RA--", 4 ) && - strncmp( lontype, "GLON", 4 ) && - strncmp( lontype, "ELON", 4 ) ) ok = 0; - } - -/* If a spectral axis is present ...*/ - if( axspec >= 0 ) { - -/* Get the CTYPE values for the axis, and find the AIPS equivalent, if - possible. */ - cval = GetItemC( &(store->ctype), axspec, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else { - if( !strncmp( cval, "FREQ", astChrLen( cval ) ) ) { - strcpy( spectype, "FREQ" ); - } else if( !strncmp( cval, "VRAD", astChrLen( cval ) ) ) { - strcpy( spectype, "VELO" ); - } else if( !strncmp( cval, "VOPT-F2W", astChrLen( cval ) ) ) { - strcpy( spectype, "FELO" ); - } else { - ok = 0; - } - } - -/* If OK, check the SPECSYS value and add the AIPS equivalent onto the - end of the CTYPE value.*/ - cval = GetItemC( &(store->specsys), 0, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else { - if( !strncmp( cval, "LSRK", astChrLen( cval ) ) ) { - strcpy( spectype+4, "-LSR" ); - } else if( !strncmp( cval, "LSRD", astChrLen( cval ) ) ) { - strcpy( spectype+4, "-LSD" ); - } else if( !strncmp( cval, "BARYCENT", astChrLen( cval ) ) ) { - strcpy( spectype+4, "-HEL" ); - } else if( !strncmp( cval, "GEOCENTR", astChrLen( cval ) ) ) { - strcpy( spectype+4, "-GEO" ); - } else { - ok = 0; - } - } - -/* If still OK, ensure the spectral axis units are Hz or m/s. */ - cval = GetItemC( &(store->cunit), axspec, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else if( ok ) { - if( !strcmp( cval, "Hz" ) ) { - specunit = "HZ"; - specfactor = 1.0; - } else if( !strcmp( cval, "kHz" ) ) { - specunit = "HZ"; - specfactor = 1.0E3; - } else if( !strcmp( cval, "MHz" ) ) { - specunit = "HZ"; - specfactor = 1.0E6; - } else if( !strcmp( cval, "GHz" ) ) { - specunit = "HZ"; - specfactor = 1.0E9; - } else if( !strcmp( cval, "m/s" ) ) { - specunit = "m/s"; - specfactor = 1.0; - } else if( !strcmp( cval, "km/s" ) ) { - specunit = "m/s"; - specfactor = 1.0E3; - } else { - ok = 0; - } - } - } - -/* If this is different to the value of NAXIS abort since this encoding - does not support WCSAXES keyword. */ - if( naxis != store->naxis ) ok = 0; - -/* Allocate memory to store the CDELT values */ - if( ok ) { - cdelt = (double *) astMalloc( sizeof(double)*naxis ); - if( !cdelt ) ok = 0; - } else { - cdelt = NULL; - } - -/* Check that rotation is restricted to the celestial plane, and extract - the CDELT (diagonal) terms, etc. If there are no celestial - axes, restrict rotation to the first two non-spectral axes. */ - if( axlat < 0 && axlon < 0 ) { - if( axspec >= 0 && naxis > 2 ) { - axrot2 = ( axspec == 0 ) ? 1 : 0; - axrot1 = axrot2 + 1; - if( axrot1 == axspec ) axrot1++; - } else if( naxis > 1 ){ - axrot2 = 0; - axrot1 = 1; - } else { - axrot2 = -1; - axrot1 = -1; - } - } else { - axrot1 = axlon; - axrot2 = axlat; - } - cdlat_lon = 0.0; - cdlon_lat = 0.0; - for( i = 0; i < naxis && ok; i++ ){ - cdl = GetItem( &(store->cdelt), i, 0, s, NULL, method, class, status ); - if( cdl == AST__BAD ) cdl = 1.0; - for( j = 0; j < naxis && ok; j++ ){ - val = GetItem( &(store->pc), i, j, s, NULL, method, class, status ); - if( val == AST__BAD ) val = ( i == j ) ? 1.0 : 0.0; - val *= cdl; - if( i == j ){ - cdelt[ i ] = val; - } else if( i == axrot2 && j == axrot1 ){ - cdlat_lon = val; - } else if( i == axrot1 && j == axrot2 ){ - cdlon_lat = val; - } else if( val != 0.0 ){ - ok = 0; - } - } - } - -/* Find the CROTA and CDELT values for the celestial axes. */ - if( ok && axrot1 >= 0 && axrot2 >= 0 ) { - if( cdlat_lon > 0.0 ) { - rho_a = atan2( cdlat_lon, cdelt[ axrot1 ] ); - } else if( cdlat_lon == 0.0 ) { - rho_a = 0.0; - } else { - rho_a = atan2( -cdlat_lon, -cdelt[ axrot1 ] ); - } - if( cdlon_lat > 0.0 ) { - rho_b = atan2( cdlon_lat, -cdelt[ axrot2 ] ); - } else if( cdlon_lat == 0.0 ) { - rho_b = 0.0; - } else { - rho_b = atan2( -cdlon_lat, cdelt[ axrot2 ] ); - } - if( fabs( palDrange( rho_a - rho_b ) ) < 1.0E-2 ){ - crota = 0.5*( palDranrm( rho_a ) + palDranrm( rho_b ) ); - coscro = cos( crota ); - sincro = sin( crota ); - if( fabs( coscro ) > fabs( sincro ) ){ - cdelt[ axrot2 ] /= coscro; - cdelt[ axrot1 ] /= coscro; - } else { - cdelt[ axrot2 ] = -cdlon_lat/sincro; - cdelt[ axrot1 ] = cdlat_lon/sincro; - } - crota *= AST__DR2D; - -/* Use AST__BAD to indicate that CDi_j values should be produced - instead of CROTA/CDELT. (I am told AIPS++ can understand CD matrices) */ - } else { - crota = AST__BAD; - } - } else { - crota = 0.0; - } - -/* Get RADECSYS and the reference equinox. */ - cval = GetItemC( &(store->radesys), 0, 0, s, NULL, method, class, status ); - epoch = GetItem( &(store->equinox), 0, 0, s, NULL, method, class, status ); - -/* If RADECSYS was available... */ - if( cval ){ - -/* ICRS is not supported in this encoding. */ - if( !strcmp( "ICRS", cval ) ) ok = 0; - -/* If epoch was not available, set a default epoch. */ - if( epoch == AST__BAD ){ - if( !strcmp( "FK4", cval ) ){ - epoch = 1950.0; - } else if( !strcmp( "FK5", cval ) ){ - epoch = 2000.0; - } else { - ok = 0; - } - -/* If an equinox was supplied, check it is consistent with the IAU 1984 - rule. */ - } else { - if( !strcmp( "FK4", cval ) ){ - if( epoch >= 1984.0 ) ok = 0; - } else if( !strcmp( "FK5", cval ) ){ - if( epoch < 1984.0 ) ok = 0; - } else { - ok = 0; - } - } - } - -/* Only create the keywords if the FitsStore conforms to the requirements - of the FITS-AIPS++ encoding. */ - if( ok ) { - -/* Get and save CRPIX for all pixel axes. These are required, so break - if they are not available. */ - for( j = 0; j < naxis && ok; j++ ){ - val = GetItem( &(store->crpix), 0, j, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - } else { - sprintf( combuf, "Reference pixel on axis %d", j + 1 ); - SetValue( this, FormatKey( "CRPIX", j + 1, -1, s, status ), &val, - AST__FLOAT, combuf, status ); - } - } - -/* Get and save CRVAL for all intermediate axes. These are required, so - break if they are not available. */ - for( i = 0; i < naxis && ok; i++ ){ - val = GetItem( &(store->crval), i, 0, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - } else { - if( i == axspec ) val *= specfactor; - sprintf( combuf, "Value at ref. pixel on axis %d", i + 1 ); - SetValue( this, FormatKey( "CRVAL", i + 1, -1, s, status ), &val, - AST__FLOAT, combuf, status ); - } - } - -/* Get and save CTYPE for all intermediate axes. These are required, so - break if they are not available. Use the potentially modified versions - saved above for the celestial axes. */ - for( i = 0; i < naxis && ok; i++ ){ - if( i == axlat ) { - cval = lattype; - } else if( i == axlon ) { - cval = lontype; - } else if( i == axspec ) { - cval = spectype; - } else { - cval = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - } - if( cval && ( strlen(cval) < 5 || strcmp( cval + 4, "-TAB" ) ) ) { - comm = GetItemC( &(store->ctype_com), i, 0, s, NULL, method, class, status ); - if( !comm ) { - sprintf( combuf, "Type of co-ordinate on axis %d", i + 1 ); - comm = combuf; - } - SetValue( this, FormatKey( "CTYPE", i + 1, -1, s, status ), &cval, - AST__STRING, comm, status ); - } else { - ok = 0; - } - } - -/* CDELT values */ - if( axspec != -1 ) cdelt[ axspec ] *= specfactor; - for( i = 0; i < naxis; i++ ){ - SetValue( this, FormatKey( "CDELT", i + 1, -1, s, status ), cdelt + i, - AST__FLOAT, "Pixel size", status ); - } - -/* CUNIT values. [Spectral axis units should be upper-case] */ - for( i = 0; i < naxis; i++ ) { - cval = GetItemC( &(store->cunit), i, 0, s, NULL, method, class, status ); - if( cval ) { - if( i == axspec ) cval = specunit; - sprintf( combuf, "Units for axis %d", i + 1 ); - SetValue( this, FormatKey( "CUNIT", i + 1, -1, s, status ), &cval, AST__STRING, - combuf, status ); - } - } - -/* CD matrix. Multiply the row of the PC matrix by the CDELT value. */ - if( crota == AST__BAD ) { - for( i = 0; i < naxis; i++ ) { - cdl = GetItem( &(store->cdelt), i, 0, s, NULL, method, class, status ); - if( cdl == AST__BAD ) cdl = 1.0; - for( j = 0; j < naxis; j++ ){ - val = GetItem( &(store->pc), i, j, s, NULL, method, class, status ); - if( val == AST__BAD ) val = ( i == j ) ? 1.0 : 0.0; - val *= cdl; - if( val != 0.0 ) { - SetValue( this, FormatKey( "CD", i + 1, j + 1, s, status ), &val, - AST__FLOAT, "Transformation matrix element", status ); - } - } - } - -/* CROTA */ - } else if( crota != 0.0 ) { - if( axrot2 != -1 ){ - SetValue( this, FormatKey( "CROTA", axrot2 + 1, -1, s, status ), &crota, - AST__FLOAT, "Axis rotation", status ); - } else if( ( axspec == -1 && naxis > 1 ) || - ( axspec != -1 && naxis > 2 ) ) { - SetValue( this, "CROTA1", &crota, AST__FLOAT, "Axis rotation", status ); - } - } - -/* Reference equinox */ - if( epoch != AST__BAD ) SetValue( this, "EPOCH", &epoch, AST__FLOAT, - "Epoch of reference equinox", status ); - -/* Latitude of native north pole. */ - val = GetItem( &(store->latpole), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, "LATPOLE", &val, AST__FLOAT, - "Latitude of native north pole", status ); - -/* Longitude of native north pole. */ - val = GetItem( &(store->lonpole), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, "LONPOLE", &val, AST__FLOAT, - "Longitude of native north pole", status ); - -/* Date of observation. */ - val = GetItem( &(store->mjdobs), 0, 0, ' ', NULL, method, class, status ); - if( val != AST__BAD ) { - -/* The format used for the DATE-OBS keyword depends on the value of the - keyword. For DATE-OBS < 1999.0, use the old "dd/mm/yy" format. - Otherwise, use the new "ccyy-mm-ddThh:mm:ss[.ssss]" format. */ - palCaldj( 99, 1, 1, &mjd99, &jj ); - if( val < mjd99 ) { - palDjcal( 0, val, iymdf, &jj ); - sprintf( combuf, "%2.2d/%2.2d/%2.2d", iymdf[ 2 ], iymdf[ 1 ], - iymdf[ 0 ] - ( ( iymdf[ 0 ] > 1999 ) ? 2000 : 1900 ) ); - } else { - palDjcl( val, iymdf, iymdf+1, iymdf+2, &fd, &jj ); - palDd2tf( 3, fd, sign, ihmsf ); - sprintf( combuf, "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d.%3.3d", - iymdf[0], iymdf[1], iymdf[2], ihmsf[0], ihmsf[1], - ihmsf[2], ihmsf[3] ); - } - -/* Now store the formatted string in the FitsChan. */ - cval = combuf; - SetValue( this, "DATE-OBS", (void *) &cval, AST__STRING, - "Date of observation", status ); - } - -/* Projection parameters. */ - if( axlat >= 0 && axlon >= 0 ) { - for( m = 0; m <= maxm; m++ ){ - val = GetItem( &(store->pv), axlat, m, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "PROJP", m, -1, ' ', status ), - &val, AST__FLOAT, "Projection parameter", status ); - } - } - -/* Spectral stuff.. */ - if( axspec >= 0 ) { - -/* Rest frequency */ - val = GetItem( &(store->restfrq), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "RESTFREQ", -1, -1, s, status ), - &val, AST__FLOAT, "[Hz] Rest frequency", status ); - } - } - -/* Release CDELT workspace */ - if( cdelt ) cdelt = (double *) astFree( (void *) cdelt ); - -/* Return zero or ret depending on whether an error has occurred. */ - return astOK ? ok : 0; -} - -static char *CardComm( AstFitsChan *this, int *status ){ - -/* -* Name: -* CardComm - -* Purpose: -* Return the keyword comment from the current card. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* char *CardComm( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns a pointer to a string holding the keyword comment from the -* current card. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the keyword comment, or NULL if the FitsChan is at -* end-of-file, or does not have a comment. - -* Notes: -* - The current card is not changed by this function. -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - char *ret; - -/* Check the supplied object. */ - if( !this ) return NULL; - -/* If the current card is defined, store a pointer to its keyword comment. */ - if( this->card ){ - ret = ( (FitsCard *) this->card )->comment; - -/* Otherwise store a NULL pointer. */ - } else { - ret = NULL; - } - -/* Return the answer. */ - return ret; -} - -static void *CardData( AstFitsChan *this, size_t *size, int *status ){ - -/* -* Name: -* CardData - -* Purpose: -* Return a pointer to the keyword data value for the current card. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void *CardData( AstFitsChan *this, size_t *size, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns a pointer to keyword data value from the current card. - -* Parameters: -* this -* Pointer to the FitsChan. -* size -* A pointer to a location at which to return the number of bytes -* occupied by the data value. NULL can be supplied if this -* information is not required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the keyword data, or NULL if the FitsChan is at -* end-of-file, or if the keyword does not have any data. - -* Notes: -* - For text data, the returned value for "size" includes the -* terminating null character. -* - The current card is not changed by this function. -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - void *ret; - -/* Check the supplied object. */ - if( !this ) return NULL; - -/* If the current card is defined, store a pointer to its keyword data. */ - if( this->card ){ - ret = ( (FitsCard *) this->card )->data; - if( size ) *size = ( (FitsCard *) this->card )->size; - -/* Otherwise store a NULL pointer. */ - } else { - ret = NULL; - if( size ) *size = 0; - } - -/* Return the answer. */ - return ret; -} - -static int *CardFlags( AstFitsChan *this, int *status ){ - -/* -* Name: -* CardFlags - -* Purpose: -* Return a pointer to the flags mask for the current card. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int *CardFlags( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns a pointer to the flags mask for the current card. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The pointer to the flags mask. - -* Notes: -* - The current card is not changed by this function. -* - NULL is returned if the current card is not defined. -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - int *ret; - -/* Check the supplied object. */ - if( !this ) return NULL; - -/* If the current card is defined, store its deletion flag. */ - if( this->card ){ - ret = &( ( (FitsCard *) this->card )->flags ); - -/* Otherwise store zero. */ - } else { - ret = NULL; - } - -/* Return the answer. */ - return ret; -} - -static char *CardName( AstFitsChan *this, int *status ){ -/* -* Name: -* CardName - -* Purpose: -* Return the keyword name from the current card. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* char *CardName( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns a pointer to a string holding the keyword name from the -* current card. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the keyword name, or NULL if the FitsChan is at -* end-of-file. - -* Notes: -* - The current card is not changed by this function. -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - char *ret; - -/* Check the supplied object. */ - if( !this ) return NULL; - -/* If the current card is defined, store a pointer to its keyword name. */ - if( this->card ){ - ret = ( (FitsCard *) this->card )->name; - -/* Otherwise store a NULL pointer. */ - } else { - ret = NULL; - } - -/* Return the answer. */ - return ret; -} - -static int CardType( AstFitsChan *this, int *status ){ -/* -* Name: -* CardType - -* Purpose: -* Return the keyword type from the current card. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int CardType( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns the keyword type from the current card. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The keyword type. - -* Notes: -* - The current card is not changed by this function. -* - AST__NOTYPE is returned if the current card is not defined. -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - int ret; - -/* Check the supplied object. */ - if( !this ) return AST__NOTYPE; - -/* If the current card is defined, store the keyword type. */ - if( this->card ){ - ret = ( (FitsCard *) this->card )->type; - -/* Otherwise store AST__NOTYPE. */ - } else { - ret = AST__NOTYPE; - } - -/* Return the answer. */ - return ret; -} - -static AstMapping *CelestialAxes( AstFitsChan *this, AstFrameSet *fs, double *dim, - int *wperm, char s, FitsStore *store, int *axis_done, - int isoff, const char *method, const char *class, int *status ){ - -/* -* Name: -* CelestialAxes - -* Purpose: -* Add values to a FitsStore describing celestial axes in a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *CelestialAxes( AstFitsChan *this, AstFrameSet *fs, double *dim, -* int *wperm, char s, FitsStore *store, int *axis_done, -* int isoff, const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The current Frame of the supplied FrameSet is searched for celestial -* axes. If any are found, FITS WCS keyword values describing the axis -* are added to the supplied FitsStore, if possible (the conventions -* of FITS-WCS paper II are used). Note, this function does not store -* values for keywords which define the transformation from pixel -* coords to Intermediate World Coords (CRPIX, PC and CDELT), but a -* Mapping is returned which embodies these values. This Mapping is -* from the current Frame in the FrameSet (WCS coords) to a Frame -* representing IWC. The IWC Frame has the same number of axes as the -* WCS Frame which may be greater than the number of base Frame (i.e. -* pixel) axes. - -* Parameters: -* this -* Pointer to the FitsChan. -* fs -* Pointer to the FrameSet. The base Frame should represent FITS pixel -* coordinates, and the current Frame should represent FITS WCS -* coordinates. The number of base Frame axes should not exceed the -* number of current Frame axes. -* dim -* An array holding the image dimensions in pixels. AST__BAD can be -* supplied for any unknown dimensions. -* wperm -* Pointer to an array of integers with one element for each axis of -* the current Frame. Each element holds the zero-based -* index of the FITS-WCS axis (i.e. the value of "i" in the keyword -* names "CTYPEi", "CRVALi", etc) which describes the Frame axis. -* s -* The co-ordinate version character. A space means the primary -* axis descriptions. Otherwise the supplied character should be -* an upper case alphabetical character ('A' to 'Z'). -* store -* The FitsStore in which to store the FITS WCS keyword values. -* axis_done -* An array of flags, one for each Frame axis, which indicate if a -* description of the corresponding axis has yet been stored in the -* FitsStore. -* isoff -* If greater than zero, the description to add to the FitsStore -* should describe offset coordinates. If less than zero, the -* description to add to the FitsStore should describe absolute -* coordinates but should include the SkyRefIs, SkyRef and SkyRefP -* attributes. If zero, ignore all offset coordinate info. The -* absolute value indicates the nature of the reference point: -* 1 == "pole", 2 == "origin", otherwise "ignored". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If celestial axes were found which can be described using the -* conventions of FITS-WCS paper II, then a Mapping from the current Frame -* of the supplied FrameSet, to the IWC Frame is returned. Otherwise, -* a UnitMap is returned. Note, the Mapping only defines the IWC -* transformation for celestial axes. Any non-celestial axes are passed -* unchanged by the returned Mapping. -*/ - -/* Local Variables: */ - AstFitsTable *table; /* Pointer to structure holding -TAB table info */ - AstFrame *pframe; /* Primary Frame containing current WCS axis*/ - AstFrame *wcsfrm; /* WCS Frame within FrameSet */ - AstMapping *map0; /* Unsimplified Pixel -> WCS mapping */ - AstMapping *map1; /* Pointer to pre-WcsMap Mapping */ - AstMapping *map3; /* Pointer to post-WcsMap Mapping */ - AstMapping *map; /* Simplified Pixel -> WCS mapping */ - AstMapping *ret; /* Returned Mapping */ - AstMapping *tmap0; /* A temporary Mapping */ - AstMapping *tmap1; /* A temporary Mapping */ - AstMapping *tmap2; /* A temporary Mapping */ - AstMapping *tmap3; /* A temporary Mapping */ - AstMapping *tmap4; /* A temporary Mapping */ - AstSkyFrame *skyfrm; /* The SkyFrame defining current WCS axis */ - AstWcsMap *map2; /* Pointer to WcsMap */ - AstWcsMap *map2b; /* Pointer to WcsMap with cleared lat/lonpole */ - char *cval; /* Pointer to keyword value */ - char *temp; /* Pointer to temporary string */ - double *mat; /* Pointer to matrix diagonal elements */ - double *ppcfid; /* Pointer to array holding PPC at fiducial point */ - double con; /* Constant value for unassigned axes */ - double crval[ 2 ]; /* Psi coords of reference point */ - double pv; /* Projection parameter value */ - double skyfid[ 2 ]; /* Sky coords of fiducial point */ - double val; /* Keyword value */ - int *inperm; /* Input axis permutation array */ - int *outperm; /* Output axis permutation array */ - int *tperm; /* Pointer to new FITS axis numbering array */ - int axlat; /* Index of latitude output from WcsMap */ - int axlon; /* Index of longitude output from WcsMap */ - int extver; /* Table version number for -TAB headers */ - int fits_ilat; /* FITS WCS axis index for latitude axis */ - int fits_ilon; /* FITS WCS axis index for longitude axis */ - int i; /* Loop index */ - int iax; /* Axis index */ - int icolindexlat; /* Index of table column holding lat index vector */ - int icolindexlon; /* Index of table column holding lon index vector */ - int icolmainlat; /* Index of table column holding main lat coord array */ - int icolmainlon; /* Index of table column holding main lon coord array */ - int interplat; /* INterpolation method for latitude look-up tables */ - int interplon; /* INterpolation method for longitude look-up tables */ - int ilat; /* Index of latitude axis within total WCS Frame */ - int ilon; /* Index of longitude axis within total WCS Frame */ - int j; /* Loop index */ - int m; /* Projection parameter index */ - int maxm; /* Largest used "m" value */ - int mlat; /* Index of latitude axis in main lat coord array */ - int mlon; /* Index of longitude axis in main lon coord array */ - int nwcs; /* Number of WCS axes */ - int nwcsmap; /* Number of inputs/outputs for the WcsMap */ - int paxis; /* Axis index within primary Frame */ - int skylataxis; /* Index of latitude axis within SkyFrame */ - int skylonaxis; /* Index of longitude axis within SkyFrame */ - int tpn; /* Is the WCS projectiona TPN projection? */ - -/* Initialise */ - ret = NULL; - -/* Other initialisation to avoid compiler warnings. */ - mlon = 0; - mlat = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Get a pointer to the WCS Frame. */ - wcsfrm = astGetFrame( fs, AST__CURRENT ); - -/* Store the number of WCS axes. */ - nwcs = astGetNout( fs ); - -/* Check each axis in the WCS Frame to see if it is a celestial axis. */ - skyfrm = NULL; - map = NULL; - ilon = -1; - ilat = -1; - for( iax = 0; iax < nwcs; iax++ ) { - -/* Obtain a pointer to the primary Frame containing the current WCS axis. */ - astPrimaryFrame( wcsfrm, iax, &pframe, &paxis ); - -/* If the current axis belongs to a SkyFrame, we have found a celestial - axis. Keep a pointer to it, and note the indices of the celestial axes - within the complete WCS Frame. The MakeFitsFrameSet function will have - ensured that the WCS Frame only contains at most a single SkyFrame. */ - if( IsASkyFrame( pframe ) ) { - if( !skyfrm ) skyfrm = astClone( pframe ); - if( paxis == 0 ) { - ilon = iax; - } else { - ilat = iax; - } - -/* Indicate that this axis has been classified. */ - axis_done[ iax ] = 1; - } - -/* Release resources. */ - pframe = astAnnul( pframe ); - } - -/* Only proceed if we found celestial axes. */ - if( ilon != -1 && ilat != -1 ) { - -/* Note the FITS WCS axis indices for the longitude and latitude axes */ - fits_ilon = wperm[ ilon ]; - fits_ilat = wperm[ ilat ]; - -/* Create an array to hold the Projection Plane Coords corresponding to the - CRVALi keywords. */ - ppcfid = (double *) astMalloc( sizeof( double )*nwcs ); - -/* Get the pixel->wcs Mapping. */ - map0 = astGetMapping( fs, AST__BASE, AST__CURRENT ); - map = astSimplify( map0 ); - map0 = astAnnul( map0 ); - -/* Get the table version number to use if we end up using the -TAB - algorithm. This is the set value of the TabOK attribute (if positive). */ - extver = astGetTabOK( this ); - -/* Some of the required FITS Keyword values are defined by the WcsMap - contained within the Mapping. Split the mapping up into a list of serial - component mappings, and locate the first WcsMap in this list. The first - Mapping returned by this call is the result of compounding all the - Mappings up to (but not including) the WcsMap, the second returned Mapping - is the (inverted) WcsMap, and the third returned Mapping is anything - following the WcsMap. Only proceed if one and only one WcsMap is found. */ - if( SplitMap( map, astGetInvert( map ), ilon, ilat, &map1, &map2, &map3, - status ) ){ - -/* Get the indices of the latitude and longitude axes within the SkyFrame - (not necessarily (1,0) because they may have been permuted). */ - skylataxis = astGetLatAxis( skyfrm ); - skylonaxis = astGetLonAxis( skyfrm ); - -/* The reference point in the celestial coordinate system is found by - transforming the fiducial point in native spherical co-ordinates - into WCS coordinates using map3. */ - if( GetFiducialWCS( map2, map3, ilon, ilat, skyfid + skylonaxis, - skyfid + skylataxis, status ) ){ - -/* We also need to find the indices of the longitude and latitude outputs - from the WcsMap. These may not be the same as ilat and ilon because of - axis permutations in "map3". */ - axlon = astGetWcsAxis( map2, 0 ); - axlat = astGetWcsAxis( map2, 1 ); - -/* Normalise the latitude and longitude values at the fiducial point. The - longitude and latitude values found above will be in radians, but after - normalization we convert them to degrees, as expected by other functions - which handle FitsStores. */ - if( skyfid[ skylonaxis ] == AST__BAD ) skyfid[ skylonaxis ] = 0.0; - if( skyfid[ skylataxis ] == AST__BAD ) skyfid[ skylataxis ] = 0.0; - if( ZEROANG( skyfid[ 0 ] ) ) skyfid[ 0 ] = 0.0; - if( ZEROANG( skyfid[ 1 ] ) ) skyfid[ 1 ] = 0.0; - astNorm( skyfrm, skyfid ); - SetItem( &(store->crval), fits_ilon, 0, s, AST__DR2D*skyfid[ skylonaxis ], status ); - SetItem( &(store->crval), fits_ilat, 0, s, AST__DR2D*skyfid[ skylataxis ], status ); - -/* Set a flag if we have a TPN projection. This is an AST-specific - projection which mimicks the old "TAN with correction terms" projection - which was removed from the final version of the FITS-WCS paper II. */ - tpn = ( astGetWcsType( map2 ) == AST__TPN ); - -/* Store the WCS projection parameters. Except for TPN projections, always - exclude parameters 3 and 4 on the longitude axis since these are - reserved to hold copies of LONPOLE and LATPOLE. */ - for( m = 0; m < WCSLIB_MXPAR; m++ ){ - if( astTestPV( map2, axlon, m ) ) { - if( m < 3 || m > 4 || tpn ) { - pv = astGetPV( map2, axlon, m ); - if( pv != AST__BAD ) SetItem( &(store->pv), fits_ilon, m, - s, pv, status ); - } - } - if( astTestPV( map2, axlat, m ) ) { - pv = astGetPV( map2, axlat, m ); - if( pv != AST__BAD ) SetItem( &(store->pv), fits_ilat, m, - s, pv, status ); - } - } - -/* If PVi_0 (for the longitude axis) is non-zero, the Cartesian coordinates - used by the WcsMap (Projection Plane Coordinates, PPC) need to be shifted - to produce Intermediate World Coordinates (IWC). This shift results in - the pixel reference position specified by the CRPIXi values (and which - corresponds to the origin of IWC) mapping on to the fiducial position - specified by the CRVALi values. The required shifts are just the PPC - coordinates of the fiducial point. The AST-specific "TPN" projection uses - longitude projection parameters to define correction terms, and so cannot - use the above convention (which is part of FITS-WCS paper II). Therefore - TPN projections always use zero shift between PPC and IWC. */ - for( iax = 0; iax < nwcs; iax++ ) ppcfid[ iax ] = 0.0; - if( !tpn && astGetPV( map2, axlon, 0 ) != 0.0 ) { - GetFiducialPPC( (AstWcsMap *) map2, ppcfid + ilon, ppcfid + ilat, status ); - if( ppcfid[ ilon ] == AST__BAD ) ppcfid[ ilon ] = 0.0; - if( ppcfid[ ilat ] == AST__BAD ) ppcfid[ ilat ] = 0.0; - ppcfid[ ilon ] *= AST__DR2D; - ppcfid[ ilat ] *= AST__DR2D; - } - -/* Store the CTYPE, CNAME, EQUINOX, MJDOBS, and RADESYS values. */ - SkySys( this, skyfrm, 1, astGetWcsType( map2 ), store, fits_ilon, - fits_ilat, s, isoff, method, class, status ); - -/* Store the LONPOLE and LATPOLE values in the FitsStore. */ - SkyPole( map2, map3, ilon, ilat, wperm, s, store, method, class, status ); - -/* The values of LONPOLE and LATPOLE stored above (in the FitsStore) will be - ignored by WcsNative if the WcsMap contains set values for projection - parameters PVi_3a and/or PVi_4a (these will be used in preference to - the values in the FitsStore). To avoid this happening we take a copy - of the WcsMap and clear the relevant parameters (but not if the WcsMap is - for a TPN projection because TPN uses PVi_3a and PVi_4a for other - purposes). */ - if( astGetWcsType( map2 ) != AST__TPN ) { - map2b = astCopy( map2 ); - astClearPV( map2b, axlon, 3 ); - astClearPV( map2b, axlon, 4 ); - } else { - map2b = astClone( map2 ); - } - -/* We will now create the Mapping from WCS coords to IWC coords. In fact, - we produce the Mapping from IWC to WCS and then invert it. Create the - first component of this Mapping which implements any shift of origin - from IWC to PPC. */ - tmap0 = (AstMapping *) astShiftMap( nwcs, ppcfid, "", status ); - -/* The next component of this Mapping scales the PPC coords from degrees - to radians on the celestial axes. */ - mat = astMalloc( sizeof( double )*(size_t) nwcs ); - if( astOK ) { - for( iax = 0; iax < nwcs; iax++ ) mat[ iax ] = 1.0; - mat[ ilon ] = AST__DD2R; - mat[ ilat ] = AST__DD2R; - tmap1 = (AstMapping *) astMatrixMap( nwcs, nwcs, 1, mat, "", status ); - mat = astFree( mat ); - } else { - tmap1 = NULL; - } - -/* Now create the Mapping from Native Spherical Coords to WCS. */ - tmap2 = WcsNative( NULL, store, s, map2b, fits_ilon, fits_ilat, - method, class, status ); - -/* Combine the WcsMap with the above Mapping, to get the Mapping from PPC - to WCS. */ - tmap3 = (AstMapping *) astCmpMap( map2b, tmap2, 1, "", status ); - tmap2 = astAnnul( tmap2 ); - -/* If there are more WCS axes than IWC axes, create a UnitMap for the extra - WCS axes and add it in parallel with tmap3. */ - nwcsmap = astGetNin( map3 ); - if( nwcsmap < nwcs ) { - tmap2 = (AstMapping *) astUnitMap( nwcs - nwcsmap, "", status ); - tmap4 = (AstMapping *) astCmpMap( tmap3, tmap2, 0, "", status ); - tmap3 = astAnnul( tmap3 ); - tmap2 = astAnnul( tmap2 ); - tmap3 = tmap4; - nwcsmap = nwcs; - } - -/* The pixel->wcs mapping may include a PermMap which selects some sub-set - or super-set of the orignal WCS axes. In this case the number of inputs - and outputs for "tmap3" created above may not equal "nwcs". To avoid this, - we embed "tmap3" between 2 PermMaps which select the required axes. */ - if( nwcsmap != nwcs || ilon != axlon || ilat != axlat ) { - inperm = astMalloc( sizeof( int )*(size_t) nwcs ); - outperm = astMalloc( sizeof( int )*(size_t) nwcsmap ); - if( astOK ) { - -/* Indicate that no inputs of the PermMap have yet been assigned to any - outputs */ - for( i = 0; i < nwcs; i++ ) inperm[ i ] = -1; - -/* Assign the WcsMap long/lat axes to the WCS Frame long/lat axes */ - inperm[ ilon ] = axlon; - inperm[ ilat ] = axlat; - -/* Assign the remaining inputs arbitrarily (doesn't matter how we do this - since the WcsMap is effectively a UnitMap on all non-celestial axes). */ - iax = 0; - for( i = 0; i < nwcs; i++ ) { - while( iax == axlon || iax == axlat ) iax++; - if( inperm[ i ] == -1 ) inperm[ i ] = iax++; - } - -/* Do the same for the outputs. */ - for( i = 0; i < nwcsmap; i++ ) outperm[ i ] = -1; - outperm[ axlon ] = ilon; - outperm[ axlat ] = ilat; - iax = 0; - for( i = 0; i < nwcsmap; i++ ) { - while( iax == ilon || iax == ilat ) iax++; - if( outperm[ i ] == -1 ) outperm[ i ] = iax++; - } - -/* Create the PermMap. */ - con = AST__BAD; - tmap2 = (AstMapping *) astPermMap( nwcs, inperm, nwcsmap, - outperm, &con, "", status ); - -/* Sandwich the WcsMap between the PermMap and its inverse. */ - tmap4 = (AstMapping *) astCmpMap( tmap2, tmap3, 1, "", status ); - tmap3 = astAnnul( tmap3 ); - astInvert( tmap2 ); - tmap3 = (AstMapping *) astCmpMap( tmap4, tmap2, 1, "", status ); - tmap2 = astAnnul( tmap2 ); - tmap4 = astAnnul( tmap4 ); - } - inperm = astFree( inperm ); - outperm = astFree( outperm ); - } - -/* Combine these Mappings together. */ - tmap4 = (AstMapping *) astCmpMap( tmap0, tmap1, 1, "", status ); - tmap0 = astAnnul( tmap0 ); - tmap1 = astAnnul( tmap1 ); - ret = (AstMapping *) astCmpMap( tmap4, tmap3, 1, "", status ); - tmap3 = astAnnul( tmap3 ); - tmap4 = astAnnul( tmap4 ); - -/* Invert this Mapping to get the Mapping from WCS to IWC. */ - astInvert( ret ); - -/* The spherical rotation involved in converting WCS to IWC can result in - inappropriate numbering of the FITS axes. For instance, a LONPOLE - value of 90 degrees causes the IWC axes to be transposed. For this - reason we re-asses the FITS axis numbers assigned to the celestial - axes in order to make the IWC axes as close as possible to the pixel - axes with the same number (but only if the axis order is being - determined automatically). To do this, we need the Mapping from - pixel to IWC, which is formed by concatenating the pixel->WCS - Mapping with the WCS->IWC Mapping. */ - if( astChrMatch( astGetFitsAxisOrder( this ), "" ) ) { - tmap0 = (AstMapping *) astCmpMap( map, ret, 1, "", status ); - -/* Find the outputs of this Mapping which should be associated with each - input. */ - tperm = astMalloc( sizeof(int)*(size_t) nwcs ); - if( ! WorldAxes( this, tmap0, dim, tperm, status ) ) { - ret = astAnnul( ret ); - } - -/* If the index associated with the celestial axes appear to have been - swapped... */ - if( ret && astOK && fits_ilon == tperm[ ilat ] && - fits_ilat == tperm[ ilon ] ) { - -/* Swap the fits axis indices associated with each WCS axis to match. */ - wperm[ ilon ] = fits_ilat; - wperm[ ilat ] = fits_ilon; - -/* Swap the stored CRVAL value for the longitude and latitude axis. */ - val = GetItem( &(store->crval), fits_ilat, 0, s, NULL, method, class, status ); - SetItem( &(store->crval), fits_ilat, 0, s, - GetItem( &(store->crval), fits_ilon, 0, s, NULL, - method, class, status ), status ); - SetItem( &(store->crval), fits_ilon, 0, s, val, status ); - -/* Swap the stored CTYPE value for the longitude and latitude axis. */ - cval = GetItemC( &(store->ctype), fits_ilat, 0, s, NULL, method, class, status ); - if( cval ) { - temp = astStore( NULL, (void *) cval, strlen( cval ) + 1 ); - cval = GetItemC( &(store->ctype), fits_ilon, 0, s, NULL, method, class, status ); - if( cval ) { - SetItemC( &(store->ctype), fits_ilat, 0, s, cval, status ); - SetItemC( &(store->ctype), fits_ilon, 0, s, temp, status ); - } - temp = astFree( temp ); - } - -/* Swap the stored CNAME value for the longitude and latitude axis. */ - cval = GetItemC( &(store->cname), fits_ilat, 0, s, NULL, method, class, status ); - if( cval ) { - temp = astStore( NULL, (void *) cval, strlen( cval ) + 1 ); - cval = GetItemC( &(store->cname), fits_ilon, 0, s, NULL, method, class, status ); - if( cval ) { - SetItemC( &(store->cname), fits_ilat, 0, s, cval, status ); - SetItemC( &(store->cname), fits_ilon, 0, s, temp, status ); - } - temp = astFree( temp ); - } - -/* Swap the projection parameters asociated with the longitude and latitude - axes. */ - maxm = GetMaxJM( &(store->pv), s, status ); - for( m = 0; m <= maxm; m++ ){ - val = GetItem( &(store->pv), fits_ilat, m, s, NULL, method, class, status ); - SetItem( &(store->pv), fits_ilat, m, s, - GetItem( &(store->pv), fits_ilon, m, s, NULL, - method, class, status ), status ); - SetItem( &(store->pv), fits_ilon, m, s, val, status ); - } - } - -/* Release resources. */ - tperm = astFree( tperm ); - tmap0 = astAnnul( tmap0 ); - } - map2b = astAnnul( map2b ); - } - -/* Release resources. */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - map3 = astAnnul( map3 ); - -/* If no WcsMap was found in the pixel->WCS Mapping, it may be possible - to describe the celestial axes using a tabular look-up table (i.e. the - FITS-WCS "_TAB" algorithm). Only do this if the -TAB algorithm is to - be supported. */ - } else if( extver > 0 ) { - -/* Get any pre-existing FitsTable from the FitsStore. This is the table - in which the tabular data will be stored (if the Mapping can be expressed - in -TAB form). */ - if( !astMapGet0A( store->tables, AST_TABEXTNAME, &table ) ) table = NULL; - -/* See if the transformations for the celestial axes can be expressed in -TAB - form. The returned Mapping (if any) is the Mapping from (lon,lat) - (rads) to (psi_lon,psi_lat) (pixels). See FITS-WCS paper III section 6.1.2 - for definition of psi. Scale the values stored in the table from radians - to degrees. */ - tmap0 = IsMapTab2D( map, AST__DR2D, "deg", wcsfrm, dim, ilon, ilat, - fits_ilon, fits_ilat, &table, &icolmainlon, - &icolmainlat, &icolindexlon, &icolindexlat, - &mlon, &mlat, &interplon, &interplat, status ); - if( tmap0 ) { - -/* Store the CTYPE, CNAME, EQUINOX, MJDOBS, and RADESYS values. */ - SkySys( this, skyfrm, 0, 0, store, fits_ilon, fits_ilat, s, isoff, - method, class, status ); - -/* If possible, choose the two CRVAL values (which are values on the psi - axes) so that transforming them using the Mapping returned by - IsMapTab2D gives the sky reference position stored in the SkyFrame. - Check the SkyFrame has a defined reference position. */ - if( astTestSkyRef( skyfrm, 0 ) && astTestSkyRef( skyfrm, 1 ) ){ - -/* Get the longitude and latitude at the reference point in radians. */ - skyfid[ 0 ] = astGetSkyRef( skyfrm, astGetLonAxis( skyfrm )); - skyfid[ 1 ] = astGetSkyRef( skyfrm, astGetLatAxis( skyfrm )); - -/* We use the WCS->psi Mapping to convert the reference point WCS coords - (rads) into psi coords (pixels). We can only do this if the WCS->psi - Mapping has a defined forward transformation. */ - if( astGetTranForward( tmap0 ) ) { - astTran2( tmap0, 1, skyfid, skyfid + 1, 1, crval, - crval + 1 ); - -/* If the WCS->psi mapping has an undefined forward transformation, then - just store the sky reference point coords (in degs) in keywords - AXREFn, and use 1.0 for the CRVAL values, so that IWC becomes equal - to (psi-1) i.e. (grid coords - 1). This means the reference point is - at grid coords (1.0,1.0). Note this choice of 1.0 for CRVAL is not - arbitrary since it is required by the trick used to create invertable CD - matrix in function MakeInvertable. */ - } else { - SetItem( &(store->axref), fits_ilon, 0, s, - AST__DR2D*skyfid[ 0 ], status ); - SetItem( &(store->axref), fits_ilat, 0, s, - AST__DR2D*skyfid[ 1 ], status ); - crval[ 0 ] = 1.0; - crval[ 1 ] = 1.0; - } - -/* If the SkyFrame has no reference position, use 1.0 for the CRVAL values. */ - } else { - crval[ 0 ] = 1.0; - crval[ 1 ] = 1.0; - } - -/* Create a Mapping that describes the transformation from the lon and lat - psi axes to the lon and lat IWC axes (i.e. a ShiftMap that just subtracts - the CRVAL values from each axis). */ - crval[ 0 ] = -crval[ 0 ]; - crval[ 1 ] = -crval[ 1 ]; - tmap1 = (AstMapping *) astShiftMap( 2, crval, " ", status ); - crval[ 0 ] = -crval[ 0 ]; - crval[ 1 ] = -crval[ 1 ]; - -/* Create a series compound Mapping that applies the Mapping returned - by IsMapTab2D first (the Mapping from WCS to psi), followed by the - Mapping from psi to IWC created above. There-after, use this compound - Mapping in place of the Mapping returned by IsMapTab2D. It maps WCS to - IWC. */ - tmap2 = (AstMapping *) astCmpMap( tmap0, tmap1, 1, " ", status ); - (void) astAnnul( tmap0 ); - tmap1 = astAnnul( tmap1 ); - tmap0 = tmap2; - -/* Store the CRVAL values */ - SetItem( &(store->crval), fits_ilon, 0, s, crval[ 0 ], status ); - SetItem( &(store->crval), fits_ilat, 0, s, crval[ 1 ], status ); - -/* Store TAB-specific values in the FitsStore. First the name of the - FITS binary table extension holding the coordinate info. */ - SetItemC( &(store->ps), fits_ilon, 0, s, AST_TABEXTNAME, status ); - SetItemC( &(store->ps), fits_ilat, 0, s, AST_TABEXTNAME, status ); - -/* Next the table version number. This is the set (positive) value for the - TabOK attribute. */ - SetItem( &(store->pv), fits_ilon, 1, s, extver, status ); - SetItem( &(store->pv), fits_ilat, 1, s, extver, status ); - -/* Also store the table version in the binary table header. */ - astSetFitsI( table->header, "EXTVER", extver, "Table version number", - 0 ); - -/* Next the name of the table column containing the main coords array. */ - SetItemC( &(store->ps), fits_ilon, 1, s, - astColumnName( table, icolmainlon ), status ); - SetItemC( &(store->ps), fits_ilat, 1, s, - astColumnName( table, icolmainlat ), status ); - -/* Next the name of the column containing the index array. */ - if( icolindexlon >= 0 ) SetItemC( &(store->ps), fits_ilon, 2, s, - astColumnName( table, icolindexlon ), status ); - if( icolindexlat >= 0 ) SetItemC( &(store->ps), fits_ilat, 2, s, - astColumnName( table, icolindexlat ), status ); - -/* The one-based index of the axes within the coordinate array that - describes FITS WCS axes "fits_ilon" and "fits_ilat". */ - SetItem( &(store->pv), fits_ilon, 3, s, mlon, status ); - SetItem( &(store->pv), fits_ilat, 3, s, mlat, status ); - -/* The interpolation method (an AST extension to the published -TAB - algorithm, communicated through the QVi_4a keyword). */ - SetItem( &(store->pv), fits_ilon, 4, s, interplon, status ); - SetItem( &(store->pv), fits_ilat, 4, s, interplat, status ); - -/* Also store the FitsTable itself in the FitsStore. */ - astMapPut0A( store->tables, AST_TABEXTNAME, table, NULL ); - -/* Allocate space for the arrays that define the permutations required - for the inputs and outputs of a PermMap. */ - inperm = astMalloc( sizeof( double )*nwcs ); - outperm = astMalloc( sizeof( double )*nwcs ); - if( astOK ) { - -/* Create the WCS -> IWC Mapping. First create a parallel CmpMap that - combines the Mapping returned by IsMapTab2D (which transforms the celestial - axes), with a UnitMap which transforms the non-celestial axes. */ - if( nwcs > 2 ) { - tmap1 = (AstMapping *) astUnitMap( nwcs - 2, " ", status ); - tmap2 = (AstMapping *) astCmpMap( tmap0, tmap1, 0, " ", status ); - tmap1 = astAnnul( tmap1 ); - } else { - tmap2 = astClone( tmap0 ); - } - -/* Now create a PermMap that permutes the inputs of this CmpMap into the - order of the axes in the WCS Frame. */ - outperm[ 0 ] = ilon; - outperm[ 1 ] = ilat; - j = 0; - for( i = 2; i < nwcs; i++ ) { - while( j == ilon || j == ilat ) j++; - outperm[ i ] = j++; - } - for( i = 0; i < nwcs; i++ ) inperm[ outperm[ i ] ] = i; - tmap1 = (AstMapping *) astPermMap( nwcs, inperm, nwcs, outperm, - NULL, " ", status ); - -/* Use this PermMap (and its inverse) to permute the inputs (and outputs) - of the parallel CmpMap created above. */ - tmap3 = (AstMapping *) astCmpMap( tmap1, tmap2, 1, " ", status ); - tmap2 = astAnnul( tmap2 ); - astInvert( tmap1 ); - tmap2 = (AstMapping *) astCmpMap( tmap3, tmap1, 1, " ", status ); - tmap1 = astAnnul( tmap1 ); - tmap3 = astAnnul( tmap3 ); - -/* Now create a PermMap that permutes the WCS axes into the FITS axis order. */ - for( i = 0; i < nwcs; i++ ) { - inperm[ i ] = wperm[ i ]; - outperm[ wperm[ i ] ] = i; - } - tmap1 = (AstMapping *) astPermMap( nwcs, inperm, nwcs, outperm, - NULL, "", status ); - -/* Use this PermMap to permute the outputs of the "tmap2" Mapping. The - resulting Mapping is the Mapping from the current Frame to IWC and is - the Mapping to be returned as the function value. */ - ret = (AstMapping *) astCmpMap( tmap2, tmap1, 1, " ", status ); - tmap1 = astAnnul( tmap1 ); - tmap2 = astAnnul( tmap2 ); - } - -/* Free remaining resources. */ - inperm = astFree( inperm ); - outperm = astFree( outperm ); - tmap0 = astAnnul( tmap0 ); - } - if( table ) table = astAnnul( table ); - } - -/* Release resources. */ - ppcfid = astFree( ppcfid ); - } - -/* Release resources. */ - wcsfrm = astAnnul( wcsfrm ); - if( skyfrm ) skyfrm = astAnnul( skyfrm ); - if( map ) map = astAnnul( map ); - -/* If we have a Mapping to return, simplify it. Otherwise, create - a UnitMap to return. */ - if( ret ) { - tmap0 = ret; - ret = astSimplify( tmap0 ); - tmap0 = astAnnul( tmap0 ); - } else { - ret = (AstMapping *) astUnitMap( nwcs, "", status ); - } - -/* Return the result. */ - return ret; -} - -static void ChangePermSplit( AstMapping *map, int *status ){ -/* -* Name: -* ChangePermSplit - -* Purpose: -* Change all PermMaps in a Mapping to use the alternate -* implementation of the astMapSplit method. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void ChangePermSplit( AstMapping *map, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The PemMap class provides two implementations of the astMapSplit -* method. The implementation used by each PermMap is determined by -* the value of the PermMap's "PermSplit" attribute. This function -* searches the supplied Mapping for any PermMaps, and set their -* PermSplit attribute to 1, indicating that the alternate -* implementation of astMapSplit should be used. - -* Parameters: -* map -* Pointer to the Mapping. Modified on exit by setting all -* PermSplit attributes to 1. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstMapping *map1; - AstMapping *map2; - int series; - int invert1; - int invert2; - -/* Check inherited status */ - if( !astOK ) return; - -/* If the supplied Mapping is a PermMap, set its PermSplit attribute - non-zero. */ - if( astIsAPermMap( map ) ) { - astSetPermSplit( map, 1 ); - -/* If the supplied Mapping is not a PermMap, attempt to decompose the - Mapping into two component Mappings. */ - } else { - astDecompose( map, &map1, &map2, &series, &invert1, &invert2 ); - -/* If the Mapping could be decomposed, use this function recursively to - set the PermSplit attributes in each component Mapping. */ - if( map1 && map2 ) { - ChangePermSplit( map1, status ); - ChangePermSplit( map2, status ); - -/* Annul the component Mappings. */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - } else if( map1 ) { - map1 = astAnnul( map1 ); - } else if( map2 ) { - map2 = astAnnul( map2 ); - } - } -} - -static double *Cheb2Poly( double *c, int nx, int ny, double xmin, double xmax, - double ymin, double ymax, int *status ){ -/* -* Name: -* Cheb2Poly - -* Purpose: -* Converts a two-dimensional Chebyshev polynomial to standard form and -* scale the arguments. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* double *Cheb2Poly( double *c, int nx, int ny, double xmin, double xmax, -* double ymin, double ymax, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* Given the coefficients of a two-dimensional Chebychev polynomial P(u,v), -* find the coefficients of the equivalent standard two-dimensional -* polynomial Q(x,y). The allowed range of u and v is assumed to be the -* unit square, and this maps on to the rectangle in (x,y) given by -* (xmin:xmax,ymin:ymax). - -* Parameters: -* c -* An array of (nx,ny) elements supplied holding the coefficients of -* P, such that the coefficient of (Ti(u)*Tj(v)) is held in element -* (i + j*nx), where "Ti(u)" is the Chebychev polynomial (of the -* first kind) of order "i" evaluated at "u", and "Tj(v)" is the -* Chebychev polynomial of order "j" evaluated at "v". -* nx -* One more than the maximum power of u within P. -* ny -* One more than the maximum power of v within P. -* xmin -* X value corresponding to u = -1 -* xmax -* X value corresponding to u = +1 -* ymin -* Y value corresponding to v = -1 -* ymax -* Y value corresponding to v = +1 -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a dynamically allocated array of (nx,ny) elements holding -* the coefficients of Q, such that the coefficient of (x^i*y^j) is held -* in element (i + j*nx). Free it using astFree when no longer needed. -*/ - -/* Local Variables: */ - double *d; - double *pa; - double *pw; - double *work1; - double *work2; - double *work3; - int *iw1; - int *iw2; - int i; - int j; - -/* Check the status and supplied value pointer. */ - if( !astOK ) return NULL; - -/* Allocate returned array. */ - d = astMalloc( sizeof( *d )*nx*ny ); - -/* Allocate workspace. */ - work1 = astMalloc( sizeof( *work1 )*ny ); - work2 = astMalloc( sizeof( *work2 )*ny ); - work3 = astMalloc( sizeof( *work2 )*nx ); - iw1 = astMalloc( sizeof(int)*( nx > ny ? nx : ny ) ); - iw2 = astMalloc( sizeof(int)*( nx > ny ? nx : ny ) ); - if( astOK ) { - -/* Thinking of P as a 1D polynomial in v, each coefficient would itself then - be a 1D polynomial in u: - - P = ( c[0] + c[1]*T1(u) + c[2]*T2(u) + ... ) + - ( c[nx] + c[nx+1]*T1(u) + c[nx+2]*T2(u) + ... )*T1(v) + - (c[2*nx] + c[2*nx+1]*T1(u) + c[2*nx+2]*T2(u) + ... )*T2(v) + - ... - (c[(ny-1)*nx] + c[(ny-1)*nx+1]*T1(u) + c[(ny-1)*nx+2]*T2(u) + ... )T{ny-1}(v) - - Use Chpc1 to convert these "polynomial coefficients" to standard - form, storing the result in the corresponding row of "d" . Also, - convert them from u to x. */ - - for( j = 0; j < ny; j++ ) { - Chpc1( c + j*nx, work3, nx, iw1, iw2, status ); - Shpc1( xmin, xmax, nx, work3, d + j*nx, status ); - } - -/* The polynomial value is now: - - ( d[0] + d[1]*x + d[2]*x*x + ... ) + - ( d[nx] + d[nx+1]*x + d[nx+2]*x*x + ... )*T1(v) + - (d[2*nx] + d[2*nx+1]*x + d[2*nx+2]*x*x + ... )*T2(v) + - ... - (d[(ny-1)*nx] + d[(ny-1)*nx+1]*x + d[(ny-1)*nx+2]*x*x + ... )*T{ny-1}(v) - - If we rearrange this expression to view it as a 1D polynomial in x, - rather than v, each coefficient of the new 1D polynomial is then - itself a polynomial in v: - - ( d[0] + d[nx]*T1(v) + d[2*nx]*T2(v) + ... d[(ny-1)*nx]*T{ny-1}(v) ) + - ( d[1] + d[nx+1]*T1(v) + d[2*nx+1]*T2(v) + ... d[(ny-1)*nx+1]T{ny-1}(v)... )*x + - ( d[2] + d[nx+2]*T1(v) + d[2*nx+2]*T2(v) + ... d[(ny-1)*nx+2]T{ny-1}(v)... )*x*x + - ... - ( d[nx-1] + d[2*nx-1]*T1(v) + d[3*nx-1]*T2(v) + ... d[ny*nx-1]*T{ny-1}(v) )*x*x*... - - - Now use Chpc1 to convert each of these "polynomial coefficients" - to standard form. We copy each column of the d array into a 1D work array, - use Shpc1 to modify the values in the work array, and then write - the modified values back into the current column of d. Also convert - from v to y. */ - - for( i = 0; i < nx; i++ ) { - pa = d + i; - pw = work1; - for( j = 0; j < ny; j++ ) { - *(pw++) = *pa; - pa += nx; - } - - Chpc1( work1, work2, ny, iw1, iw2, status ); - Shpc1( ymin, ymax, ny, work2, work1, status ); - - pa = d + i; - pw = work1; - for( j = 0; j < ny; j++ ) { - *pa = *(pw++); - pa += nx; - } - } - -/* So the polynomial is now: - - ( d[0] + d[nx]*y + d[2*nx]*y*y + ... d[(ny-1)*nx]*y*y*... ) + - ( d[1] + d[nx+1]*y + d[2*nx+1]*y*y + ... d[(ny-1)*nx+1]*y*y*... )*x + - ( d[2] + d[nx+2]*y + d[2*nx+2]*y*y + ... d[(ny-1)*nx+2]*y*y*... )*x*x + - ... - ( d[nx-1] + d[2*nx-1]*y + d[3*nx-1]*y*y + ... d[ny*nx-1]*y*y*... )*x*x*... - - Re-arranging, this is: - - ( d[0] + d[1]*x + d[2]*x*x + ... ) + - ( d[nx] + d[nx+1]*x + d[nx+2]*x*x + ... )*y + - (d[2*nx] + d[2*nx+1]*x + d[2*nx+2]*x*x + ... )*y*y + - ... - (d[(ny-1)*nx] + d[(ny-1)*nx+1]*x + d[(ny-1)*nx+2]*x*x + ... )*y*y*... - - as required. */ - - } - -/* Free the workspace. */ - work1 = astFree( work1 ); - work2 = astFree( work2 ); - work3 = astFree( work3 ); - iw1 = astFree( iw1 ); - iw2 = astFree( iw2 ); - -/* Return the result. */ - return d; -} - -static int CheckFitsName( AstFitsChan *this, const char *name, - const char *method, const char *class, int *status ){ -/* -* Name: -* CheckFitsName - -* Purpose: -* Check a keyword name conforms to FITS standards. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int CheckFitsName( AstFitsChan *this, const char *name, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* FITS keywords must contain between 1 and 8 characters, and each -* character must be an upper-case Latin alphabetic character, a digit, -* an underscore, or a hyphen. Leading, trailing or embedded white space -* is not allowed, with the exception of totally blank or null keyword -* names. -* -* If the supplied keyword name is invalid, either a warning is issued -* (for violations that can be handled - such as illegal characters in -* keywords), or an error is reported (for more major violations such -* as the keyname containing an equals sign). - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* Pointer to a string holding the name to check. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 0 is returned if the supplied name was blank. A value of 1 -* is returned otherwise. - -* Notes: -* - An error is reported if the supplied keyword name does not -* conform to FITS requirements, and zero is returned. -*/ - -/* Local Variables: */ - char buf[100]; /* Buffer for warning text */ - const char *c; /* Pointer to next character in name */ - size_t n; /* No. of characters in supplied name */ - int ret; /* Returned value */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise the returned value to indicate that the supplied name was - blank. */ - ret = 0; - -/* Check that the supplied pointer is not NULL. */ - if( name ){ - -/* Get the number of characters in the name. */ - n = strlen( name ); - -/* Report an error if the name has too many characters in it. */ - if( n > FITSNAMLEN ){ - astError( AST__BDFTS, "%s(%s): The supplied FITS keyword name ('%s') " - "has %d characters. FITS only allows up to %d.", status, method, - class, name, (int) n, FITSNAMLEN ); - -/* If the name has no characters in it, then assume it is a legal blank - keyword name. Otherwise, check that no illegal characters occur in the - name. */ - } else if( n != 0 ) { - -/* Whitespace is only allowed in the special case of a name consisting - entirely of whitespace. Such keywords are used to indicate that the rest - of the card is a comment. Find the first non-whitespace character in the - name. */ - c = name; - while( isspace( ( int ) *(c++) ) ); - -/* If the name is filled entirely with whitespace, then the name is acceptable - as the special case. Otherwise, we need to do more checks. */ - if( c - name - 1 < n ){ - -/* Indicate that the supplied name is not blank. */ - ret = 1; - -/* Loop round every character checking that it is one of the legal characters. - Report an error if any illegal characters are found. */ - c = name; - while( *c ){ - if( !isFits( (int) *c ) ){ - if( *c == '=' ){ - astError( AST__BDFTS, "%s(%s): An equals sign ('=') was found " - "before column %d within a FITS keyword name or header " - "card.", status, method, class, FITSNAMLEN + 1 ); - - } else if( *c < ' ' ) { - sprintf( buf, "The FITS keyword name ('%s') contains an " - "illegal non-printing character (ascii value " - "%d).", name, *c ); - Warn( this, "badkeyname", buf, method, class, status ); - - - } else if( *c > ' ' ) { - sprintf( buf, "The FITS keyword name ('%s') contains an " - "illegal character ('%c').", name, *c ); - Warn( this, "badkeyname", buf, method, class, status ); - } - break; - } - c++; - } - } - } - -/* Report an error if no pointer was supplied. */ - } else if( astOK ){ - astError( AST__INTER, "CheckFitsName(%s): AST internal error; a NULL " - "pointer was supplied for the keyword name. ", status, - astGetClass( this ) ); - } - -/* If an error has occurred, return 0. */ - if( !astOK ) ret = 0; - -/* Return the answer. */ - return ret; -} - -static void CheckZero( char *text, double value, int width, int *status ){ -/* -* Name: -* CheckZero - -* Purpose: -* Ensure that the formatted value zero has no minus sign. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void CheckZero( char *text, double value, int width, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* There is sometimes a problem (perhaps only on DEC UNIX) when formatting -* the floating-point value 0.0 using C. Sometimes it gives the string -* "-0". This function fixed this by checking the first character of -* the supplied string (if the supplied value is zero), and shunting the -* remaining text one character to the right if it is a minus sign. It -* returns without action if the supplied value is not zero. -* -* In addition, this function also rounds out long sequences of -* adjacent zeros or nines in the number. - -* Parameters: -* text -* The formatted value. -* value -* The floating value which was formatted. -* width -* The minimum field width to use. The value is right justified in -* this field width. Ignored if zero. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - char *c; - -/* Return if no text was supplied. */ - if( !text ) return; - -/* If the numerical value is zero, check for the leading minus sign. */ - if( value == 0.0 ) { - -/* Find the first non-space character. */ - c = text; - while( *c && isspace( (int) *c ) ) c++; - -/* If the first non-space character is a minus sign, replace it with a - space. */ - if( *c == '-' ) *c = ' '; - -/* Otherwise, round out sequences of zeros or nines. */ - } else { - RoundFString( text, width, status ); - } -} - -static double ChooseEpoch( AstFitsChan *this, FitsStore *store, char s, - const char *method, const char *class, int *status ){ -/* -* Name: -* ChooseEpoch - -* Purpose: -* Choose a FITS keyword value to use for the AST Epoch attribute. - -* Type: -* Private function. - -* Synopsis: -* double ChooseEpoch( AstFitsChan *this, FitsStore *store, char s, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function returns an MJD value in the TDB timescale, which can -* be used as the Epoch value in an AST Frame. It uses the following -* preference order: secondary MJD-AVG, primary MJD-AVG, secondary MJD-OBS, -* primary MJD-OBS. Note, DATE-OBS keywords are converted into MJD-OBS -* keywords by the SpecTrans function before this function is called. - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* A structure containing values for FITS keywords relating to -* the World Coordinate System. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* method -* The calling method. Used only in error messages. -* class -* The object class. Used only in error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The MJD value. - -* Notes: -* - A value of AST__BAD is returned if an error occurs, or if none -* of the required keywords can be found in the FitsChan. -*/ - -/* Local Variables: */ - const char *timesys; /* The TIMESYS value in the FitsStore */ - double mjd; /* The returned MJD */ - -/* Initialise the returned value. */ - mjd = AST__BAD; - -/* Check the global status. */ - if( !astOK ) return mjd; - -/* Otherwise, try to get the secondary MJD-AVG value. */ - mjd = GetItem( &(store->mjdavg), 0, 0, s, NULL, method, class, status ); - -/* Otherwise, try to get the primary MJD-AVG value. */ - if( mjd == AST__BAD ) mjd = GetItem( &(store->mjdavg), 0, 0, ' ', NULL, - method, class, status ); - -/* If the secondary MJD-OBS keyword is present in the FitsChan, gets its - value. */ - if( mjd == AST__BAD ) mjd = GetItem( &(store->mjdobs), 0, 0, s, NULL, - method, class, status ); - -/* Otherwise, try to get the primary MJD-OBS value. */ - if( mjd == AST__BAD ) mjd = GetItem( &(store->mjdobs), 0, 0, ' ', NULL, - method, class, status ); - -/* Now convert the MJD value to the TDB timescale. */ - timesys = GetItemC( &(store->timesys), 0, 0, ' ', NULL, method, class, status ); - mjd = TDBConv( mjd, TimeSysToAst( this, timesys, method, class, status ), - 0, method, class, status ); - -/* Return the answer. */ - return mjd; -} - -static void Chpc1( double *c, double *d, int n, int *w0, int *w1, int *status ){ -/* -* Name: -* Chpc1 - -* Purpose: -* Converts a one-dimensional Chebyshev polynomial to standard form. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void Chpc1( double *c, double *d, int n, int *w0, int *w1, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* Given the coefficients of a one-dimensional Chebychev polynomial P(u), -* find the coefficients of the equivalent standard 1D polynomial Q(u). -* The allowed range of u is assumed to be the unit interval. - -* Parameters: -* c -* An array of n elements supplied holding the coefficients of -* P, such that the coefficient of (Ti(u)) is held in element -* (i), where "Ti(u)" is the Chebychev polynomial (of the -* first kind) of order "i" evaluated at "u". -* d -* An array of n elements returned holding the coefficients of -* Q, such that the coefficient of (u^i) is held in element (i). -* n -* One more than the highest power of u in P. -* w0 -* Pointer to a work array of n elements. -* w1 -* Pointer to a work array of n elements. -* status -* Inherited status value - -* Notes: -* - Vaguely inspired by the Numerical Recipes routine "chebpc". But the -* original had bugs, so I wrote this new version from first principles. - -*/ - -/* Local Variables: */ - int sv; - int j; - int k; - -/* Check inherited status */ - if( !astOK ) return; - -/* Initialise the returned coefficients array. */ - for( j = 0; j < n; j++ ) d[ j ] = 0.0; - -/* Use the recurrence relation - - T{k+1}(x) = 2.x.T{k}(x) - T{k-1}(x). - - w0[i] holds the coefficient of x^i in T{k-1}. w1[i] holds the - coefficient of x^i in T{k}. Initialise them for T0 (="1") and - T1 (="x"). */ - for( j = 0; j < n; j++ ) w0[ j ] = w1[ j ] = 0; - w0[ 0 ] = 1; - w1[ 1 ] = 1; - -/* Update the returned coefficients array to include the T0 and T1 terms. */ - d[ 0 ] = c[ 0 ]; - d[ 1 ] = c[ 1 ]; - -/* Loop round using the above recurrence relation until we have found - T{n-1}. */ - for( k = 1; k < n - 1; k++ ){ - -/* To get the coefficients of T{k+1} shift the contents of w1 up one - element, introducing a zero at the low end, and then double all the - values in w1. Finally subtract off the values in w0. This implements - the above recurrence relationship. Starting at the top end and working - down to the bottom, store a new value for each element of w1. */ - for( j = n - 1; j > 0; j-- ) { - -/* First save the original element of w1 in w0 for use next time. But we - also need the original w0 element later on so save it first. */ - sv = w0[ j ]; - w0[ j ] = w1[ j ]; - -/* Double the lower neighbouring w1 element and subtract off the w0 - element saved above. This forms the new value for w1. */ - w1[ j ] = 2*w1[ j - 1 ] - sv; - } - -/* Introduce a zero into the lowest element of w1, saving the original - value first in w0. Then subtract off the original value of w0. */ - sv = w0[ 0 ]; - w0[ 0 ] = w1[ 0 ]; - w1[ 0 ] = -sv; - -/* W1 now contains the coefficients of T{k+1} in w1, and the coefficients - of T{k} in w0. Multiply these by the supplied coefficient for T{k+1}, - and add them into the returned array. */ - for( j = 0; j <= k + 1; j++ ){ - d[ j ] += c[ k + 1 ]*w1[ j ]; - } - } -} - -static int ChrLen( const char *string, int *status ){ -/* -* Name: -* ChrLen - -* Purpose: -* Return the length of a string excluding any trailing white space. - -* Type: -* Private function. - -* Synopsis: -* int ChrLen( const char *string, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function returns the length of a string excluding any trailing -* white space, or non-printable characters. - -* Parameters: -* string -* Pointer to the string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The length of a string excluding any trailing white space and -* non-printable characters. - -* Notes: -* - A value of zero is returned if a NULL pointer is supplied, or if an -* error has already occurred. -*/ - -/* Local Variables: */ - const char *c; /* Pointer to the next character to check */ - int ret; /* The returned string length */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise the returned string length. */ - ret = 0; - -/* Check a string has been supplied. */ - if( string ){ - -/* Check each character in turn, starting with the last one. */ - ret = strlen( string ); - c = string + ret - 1; - while( ret ){ - if( isprint( (int) *c ) && !isspace( (int) *c ) ) break; - c--; - ret--; - } - } - -/* Return the answer. */ - return ret; -} - -static int CLASSFromStore( AstFitsChan *this, FitsStore *store, - AstFrameSet *fs, double *dim, const char *method, - const char *class, int *status ){ - -/* -* Name: -* CLASSFromStore - -* Purpose: -* Store WCS keywords in a FitsChan using FITS-CLASS encoding. - -* Type: -* Private function. - -* Synopsis: - -* int CLASSFromStore( AstFitsChan *this, FitsStore *store, -* AstFrameSet *fs, double *dim, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function copies the WCS information stored in the supplied -* FitsStore into the supplied FitsChan, using FITS-CLASS encoding. - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore. -* fs -* Pointer to the FrameSet from which the values in the FitsStore -* were derived. -* dim -* Pointer to an array holding the main array dimensions (AST__BAD -* if a dimension is not known). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if succesfull, and zero is returned -* otherwise. -*/ - -/* Local Variables: */ - AstFrame *azelfrm; /* (az,el) frame */ - AstFrame *curfrm; /* Current Frame in supplied FrameSet */ - AstFrame *freqfrm; /* Frame for reference frequency value */ - AstFrame *radecfrm; /* Spatial frame for CRVAL values */ - AstFrame *velofrm; /* Frame for reference velocity value */ - AstFrameSet *fsconv1;/* FrameSet connecting "curfrm" & "radecfrm" */ - AstFrameSet *fsconv2;/* FrameSet connecting "curfrm" & "azelfrm" */ - AstMapping *map1; /* Axis permutation to get (lonaxis,lataxis) = (0,1) */ - AstMapping *map2; /* Mapping from FITS CTYPE to (az,el) */ - AstMapping *map3; /* Mapping from (lon,lat) to (az,el) */ - char *comm; /* Pointer to comment string */ - char *cval; /* Pointer to string keyword value */ - char attbuf[20]; /* Buffer for AST attribute name */ - char combuf[80]; /* Buffer for FITS card comment */ - char lattype[MXCTYPELEN];/* Latitude axis CTYPE */ - char lontype[MXCTYPELEN];/* Longitude axis CTYPE */ - char s; /* Co-ordinate version character */ - char sign[2]; /* Fraction's sign character */ - char spectype[MXCTYPELEN];/* Spectral axis CTYPE */ - double *cdelt; /* Pointer to CDELT array */ - double aval[ 2 ]; /* General purpose array */ - double azel[ 2 ]; /* Reference (az,el) values */ - double cdl; /* CDELT term */ - double crval[ 3 ]; /* CRVAL values converted to rads, etc */ - double delta; /* Spectral axis increment */ - double equ; /* Epoch of reference equinox */ - double fd; /* Fraction of a day */ - double latval; /* CRVAL for latitude axis */ - double lonpole; /* LONPOLE value */ - double lonval; /* CRVAL for longitude axis */ - double mjd99; /* MJD at start of 1999 */ - double p1, p2; /* Projection parameters */ - double radec[ 2 ]; /* Reference (lon,lat) values */ - double rf; /* Rest freq (Hz) */ - double specfactor; /* Factor for converting internal spectral units */ - double val; /* General purpose value */ - double xin[ 3 ]; /* Grid coords at centre of first pixel */ - double xout[ 3 ]; /* WCS coords at centre of first pixel */ - int axlat; /* Index of latitude FITS WCS axis */ - int axlon; /* Index of longitude FITS WCS axis */ - int axspec; /* Index of spectral FITS WCS axis */ - int i; /* Axis index */ - int ihmsf[ 4 ]; /* Hour, minute, second, fractional second */ - int iymdf[ 4 ]; /* Year, month, date, fractional day */ - int j; /* Axis index */ - int jj; /* SlaLib status */ - int naxis2; /* Length of pixel axis 2 */ - int naxis3; /* Length of pixel axis 3 */ - int naxis; /* No. of axes */ - int ok; /* Is FitsSTore OK for IRAF encoding? */ - int prj; /* Projection type */ - -/* Other initialisation to avoid compiler warnings. */ - lonval = 0.0; - latval = 0.0; - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Initialise */ - specfactor = 1.0; - -/* First check that the values in the FitsStore conform to the - requirements of the CLASS encoding. Assume they do not to begin with. */ - ok = 0; - -/* Just do primary axes. */ - s = ' '; - -/* Look for the primary celestial axes. */ - FindLonLatSpecAxes( store, s, &axlon, &axlat, &axspec, method, class, status ); - -/* Get the current Frame from the supplied FrameSet. */ - curfrm = astGetFrame( fs, AST__CURRENT ); - -/* Spectral and celestial axes must be present in axes 1,2 and 3. */ - if( axspec >= 0 && axspec < 3 && - axlon >= 0 && axlon < 3 && - axlat >= 0 && axlat < 3 ) { - ok = 1; - -/* If the spatial pixel axes are degenerate (i.e. span only a single - pixel), modify the CRPIX and CRVAL values in the FitsStore to put - the reference point at the centre of the one and only spatial pixel. */ - if( store->naxis >= 3 && dim[ axlon ] == 1.0 && dim[ axlat ] == 1.0 ){ - xin[ 0 ] = 1.0; - xin[ 1 ] = 1.0; - xin[ 2 ] = 1.0; - astTranN( fs, 1, 3, 1, xin, 1, 3, 1, xout ); - if( xout[ axlon ] != AST__BAD && xout[ axlat ] != AST__BAD ) { - -/* The indices of the spatial axes in the FITS header may not be the same - as the indices of the spatial axes in the WCS Frame of the supplied - FrameSet. So search the current Frame for longitude and latitude axes, - and store the corresponding elements of the "xout" array for later use. */ - for( i = 0; i < 3; i++ ) { - sprintf( attbuf, "IsLonAxis(%d)", i + 1 ); - if( astHasAttribute( curfrm, attbuf ) ) { - if( astGetI( curfrm, attbuf ) ) { - lonval = xout[ i ]; - } else { - latval = xout[ i ]; - } - } - } - -/* Store them in the FitsStore. */ - SetItem( &(store->crval), axlon, 0, ' ', lonval*AST__DR2D, status ); - SetItem( &(store->crval), axlat, 0, ' ', latval*AST__DR2D, status ); - SetItem( &(store->crpix), 0, axlon, ' ', 1.0, status ); - SetItem( &(store->crpix), 0, axlat, ' ', 1.0, status ); - } - } - -/* Get the CRVAL values for both spatial axes. */ - latval = GetItem( &( store->crval ), axlat, 0, s, NULL, method, class, status ); - if( latval == AST__BAD ) ok = 0; - lonval = GetItem( &( store->crval ), axlon, 0, s, NULL, method, class, status ); - if( lonval == AST__BAD ) ok = 0; - -/* Get the CTYPE values for both axes. Extract the projection type as - specified by the last 4 characters in the latitude CTYPE keyword value. */ - cval = GetItemC( &(store->ctype), axlon, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else { - strcpy( lontype, cval ); - } - cval = GetItemC( &(store->ctype), axlat, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - prj = AST__WCSBAD; - } else { - strcpy( lattype, cval ); - prj = astWcsPrjType( cval + 4 ); - } - -/* Check the projection type is OK. */ - if( prj == AST__WCSBAD ){ - ok = 0; - } else if( prj != AST__SIN ){ - -/* Check the projection code is OK. */ - ok = 0; - if( prj == AST__TAN || - prj == AST__ARC || - prj == AST__STG || - prj == AST__AIT || - prj == AST__SFL ) { - ok = 1; - -/* For AIT, and SFL, check that the reference point is the origin of - the celestial co-ordinate system. */ - if( prj == AST__AIT || - prj == AST__SFL ) { - if( latval != 0.0 || lonval != 0.0 ){ - ok = 0; - -/* Change the new SFL projection code to to the older equivalent GLS */ - } else if( prj == AST__SFL ){ - (void) strcpy( lontype + 4, "-GLS" ); - (void) strcpy( lattype + 4, "-GLS" ); - -/* Change the new AIT projection code to to the older equivalent ATF */ - } else if( prj == AST__AIT ){ - (void) strcpy( lontype + 4, "-ATF" ); - (void) strcpy( lattype + 4, "-ATF" ); - } - } - } - -/* SIN projections are only acceptable if the associated projection - parameters are both zero. */ - } else { - p1 = GetItem( &( store->pv ), axlat, 1, s, NULL, method, class, status ); - p2 = GetItem( &( store->pv ), axlat, 2, s, NULL, method, class, status ); - if( p1 == AST__BAD ) p1 = 0.0; - if( p2 == AST__BAD ) p2 = 0.0; - ok = ( p1 == 0.0 && p2 == 0.0 ); - } - -/* Identify the celestial coordinate system from the first 4 characters of the - longitude CTYPE value. Only RA and galactic longitude can be stored using - FITS-CLASS. */ - if( ok && strncmp( lontype, "RA--", 4 ) && - strncmp( lontype, "GLON", 4 ) ) ok = 0; - -/* Get the CTYPE values for the spectral axis, and find the CLASS equivalent, - if possible. */ - cval = GetItemC( &(store->ctype), axspec, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else { - if( !strncmp( cval, "FREQ", astChrLen( cval ) ) ) { - strcpy( spectype, "FREQ" ); - } else { - ok = 0; - } - } - -/* If OK, check the SPECSYS value is SOURCE. */ - cval = GetItemC( &(store->specsys), 0, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else if( ok ) { - if( strncmp( cval, "SOURCE", astChrLen( cval ) ) ) ok = 0; - } - -/* If still OK, ensure the spectral axis units are Hz. */ - cval = GetItemC( &(store->cunit), axspec, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - } else if( ok ) { - if( !strcmp( cval, "Hz" ) ) { - specfactor = 1.0; - } else if( !strcmp( cval, "kHz" ) ) { - specfactor = 1.0E3; - } else if( !strcmp( cval, "MHz" ) ) { - specfactor = 1.0E6; - } else if( !strcmp( cval, "GHz" ) ) { - specfactor = 1.0E9; - } else { - ok = 0; - } - } - } - -/* Save the number of WCS axes */ - naxis = GetMaxJM( &(store->crpix), ' ', status ) + 1; - -/* If this is larger than 3, ignore the surplus WCS axes. Note, the - above code has checked that the spatial and spectral axes are - WCS axes 0, 1 and 2. */ - if( naxis > 3 ) naxis = 3; - -/* Allocate memory to store the CDELT values */ - if( ok ) { - cdelt = (double *) astMalloc( sizeof(double)*naxis ); - if( !cdelt ) ok = 0; - } else { - cdelt = NULL; - } - -/* Check that there is no rotation, and extract the CDELT (diagonal) terms, - etc. If the spatial axes are degenerate (i.e. cover only a single pixel) - then ignore any rotation. */ - if( !GetValue( this, FormatKey( "NAXIS", axlon + 1, -1, s, status ), AST__INT, - &naxis2, 0, 0, method, class, status ) ) { - naxis2 = 0; - } - if( !GetValue( this, FormatKey( "NAXIS", axlat + 1, -1, s, status ), AST__INT, - &naxis3, 0, 0, method, class, status ) ) { - naxis3 = 0; - } - for( i = 0; i < naxis && ok; i++ ){ - cdl = GetItem( &(store->cdelt), i, 0, s, NULL, method, class, status ); - if( cdl == AST__BAD ) cdl = 1.0; - for( j = 0; j < naxis && ok; j++ ){ - val = GetItem( &(store->pc), i, j, s, NULL, method, class, status ); - if( val == AST__BAD ) val = ( i == j ) ? 1.0 : 0.0; - val *= cdl; - if( i == j ){ - cdelt[ i ] = val; - } else if( val != 0.0 ){ - if( naxis2 != 1 || naxis3 != 1 ) ok = 0; - } - } - } - -/* Get RADECSYS and the reference equinox. */ - cval = GetItemC( &(store->radesys), 0, 0, s, NULL, method, class, status ); - equ = GetItem( &(store->equinox), 0, 0, s, NULL, method, class, status ); - -/* If RADECSYS was available... */ - if( cval ){ - -/* Only FK4 and FK5 are supported in this encoding. */ - if( strcmp( "FK4", cval ) && strcmp( "FK5", cval ) ) ok = 0; - -/* If epoch was not available, set a default epoch. */ - if( equ == AST__BAD ){ - if( !strcmp( "FK4", cval ) ){ - equ = 1950.0; - } else if( !strcmp( "FK5", cval ) ){ - equ = 2000.0; - } else { - ok = 0; - } - -/* If an epoch was supplied, check it is consistent with the IAU 1984 - rule. */ - } else { - if( !strcmp( "FK4", cval ) ){ - if( equ >= 1984.0 ) ok = 0; - } else if( !strcmp( "FK5", cval ) ){ - if( equ < 1984.0 ) ok = 0; - } else { - ok = 0; - } - } - -/* Check we have a rest frequency */ - rf = GetItem( &(store->restfrq), 0, 0, s, NULL, method, class, status ); - if( rf == AST__BAD ) ok = 0; - } - -/* If the spatial Frame covers more than a single Frame and requires a LONPOLE - or LATPOLE keyword, it cannot be encoded using FITS-CLASS. However since - FITS-CLASS imposes a no rotation restriction, it can tolerate lonpole - values of +/- 180 degrees. */ - if( ok && ( naxis2 != 1 || naxis3 != 1 ) ) { - lonpole = GetItem( &(store->lonpole), 0, 0, s, NULL, method, class, status ); - if( lonpole != AST__BAD && lonpole != -180.0 && lonpole == 180 ) ok = 0; - if( GetItem( &(store->latpole), 0, 0, s, NULL, method, class, status ) - != AST__BAD ) ok = 0; - } - -/* Only create the keywords if the FitsStore conforms to the requirements - of the FITS-CLASS encoding. */ - if( ok ) { - -/* If celestial axes were added by MakeFitsFrameSet, we need to ensure - the header contains 3 main array axes. This is because the CLASS - encoding does not support the WCSAXES keyword. */ - if( store->naxis == 1 ) { - -/* Update the "NAXIS" value to 3 or put a new card in at the start. */ - astClearCard( this ); - i = 3; - SetValue( this, "NAXIS", &i, AST__INT, NULL, status ); - -/* Put NAXIS2/3 after NAXIS1, or after NAXIS if the FitsChan does not contain - NAXIS1. These are set to 1 since the spatial axes are degenerate. */ - if( FindKeyCard( this, "NAXIS1", method, class, status ) ) { - MoveCard( this, 1, method, class, status ); - } - i = 1; - SetValue( this, "NAXIS2", &i, AST__INT, NULL, status ); - SetValue( this, "NAXIS3", &i, AST__INT, NULL, status ); - } - -/* Find the last WCS related card. */ - FindWcs( this, 1, 1, 0, method, class, status ); - -/* Get and save CRPIX for all pixel axes. These are required, so break - if they are not available. */ - for( j = 0; j < naxis && ok; j++ ){ - val = GetItem( &(store->crpix), 0, j, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - } else { - sprintf( combuf, "Reference pixel on axis %d", j + 1 ); - SetValue( this, FormatKey( "CRPIX", j + 1, -1, s, status ), &val, - AST__FLOAT, combuf, status ); - } - } - -/* Get and save CRVAL for all intermediate axes. These are required, so - break if they are not available. Note, the frequency axis CRVAL is - redefined by FITS-CLASS by reducing it by the RESTFREQ value. */ - for( i = 0; i < naxis && ok; i++ ){ - val = GetItem( &(store->crval), i, 0, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - } else { - crval[ i ] = val; - if( i == axspec ) { - val *= specfactor; - val -= rf; - } - sprintf( combuf, "Value at ref. pixel on axis %d", i + 1 ); - SetValue( this, FormatKey( "CRVAL", i + 1, -1, s, status ), &val, - AST__FLOAT, combuf, status ); - } - } - -/* Get and save CTYPE for all intermediate axes. These are required, so - break if they are not available. Use the potentially modified versions - saved above for the celestial axes. */ - for( i = 0; i < naxis && ok; i++ ){ - if( i == axlat ) { - cval = lattype; - } else if( i == axlon ) { - cval = lontype; - } else if( i == axspec ) { - cval = spectype; - } else { - cval = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - } - if( cval && ( strlen(cval) < 5 || strcmp( cval + 4, "-TAB" ) ) ) { - comm = GetItemC( &(store->ctype_com), i, 0, s, NULL, method, class, status ); - if( !comm ) { - sprintf( combuf, "Type of co-ordinate on axis %d", i + 1 ); - comm = combuf; - } - SetValue( this, FormatKey( "CTYPE", i + 1, -1, s, status ), &cval, - AST__STRING, comm, status ); - } else { - ok = 0; - } - } - -/* CDELT values */ - if( axspec != -1 ) cdelt[ axspec ] *= specfactor; - for( i = 0; i < naxis; i++ ){ - SetValue( this, FormatKey( "CDELT", i + 1, -1, s, status ), cdelt + i, - AST__FLOAT, "Pixel size", status ); - } - -/* Reference equinox */ - if( equ != AST__BAD ) SetValue( this, "EQUINOX", &equ, AST__FLOAT, - "Epoch of reference equinox", status ); - -/* Date of observation. */ - val = GetItem( &(store->mjdobs), 0, 0, ' ', NULL, method, class, status ); - if( val != AST__BAD ) { - -/* The format used for the DATE-OBS keyword depends on the value of the - keyword. For DATE-OBS < 1999.0, use the old "dd/mm/yy" format. - Otherwise, use the new "ccyy-mm-ddThh:mm:ss[.ssss]" format. */ - palCaldj( 99, 1, 1, &mjd99, &jj ); - if( val < mjd99 ) { - palDjcal( 0, val, iymdf, &jj ); - sprintf( combuf, "%2.2d/%2.2d/%2.2d", iymdf[ 2 ], iymdf[ 1 ], - iymdf[ 0 ] - ( ( iymdf[ 0 ] > 1999 ) ? 2000 : 1900 ) ); - } else { - palDjcl( val, iymdf, iymdf+1, iymdf+2, &fd, &jj ); - palDd2tf( 3, fd, sign, ihmsf ); - sprintf( combuf, "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d.%3.3d", - iymdf[0], iymdf[1], iymdf[2], ihmsf[0], ihmsf[1], - ihmsf[2], ihmsf[3] ); - } - -/* Now store the formatted string in the FitsChan. */ - cval = combuf; - SetValue( this, "DATE-OBS", (void *) &cval, AST__STRING, - "Date of observation", status ); - } - -/* Rest frequency */ - SetValue( this, "RESTFREQ", &rf, AST__FLOAT, "[Hz] Rest frequency", status ); - -/* The image frequency corresponding to the rest frequency (only used for - double sideband data). */ - val = GetItem( &(store->imagfreq), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) { - SetValue( this, "IMAGFREQ", &val, AST__FLOAT, "[Hz] Image frequency", status ); - } - -/* Ensure the FitsChan contains OBJECT and LINE headers */ - if( !HasCard( this, "OBJECT", method, class, status ) ) { - cval = " "; - SetValue( this, "OBJECT", &cval, AST__STRING, NULL, status ); - } - if( !HasCard( this, "LINE", method, class, status ) ) { - cval = " "; - SetValue( this, "LINE", &cval, AST__STRING, NULL, status ); - } - -/* CLASS expects the VELO-LSR keyword to hold the radio velocity of the - reference channel (NOT of the source as I was told!!) with respect to - the LSRK rest frame. The "crval" array holds the frequency of the - reference channel in the source rest frame, so we need to convert this - to get the value for VELO-LSR. Create a SpecFrame describing the - required frame (other attributes such as Epoch etc are left unset and - so will be picked up from the supplied FrameSet). We set MinAxes - and MaxAxes so that the Frame can be used as a template to match the - 1D or 3D current Frame in the supplied FrameSet. */ - velofrm = (AstFrame *) astSpecFrame( "System=vrad,StdOfRest=lsrk," - "Unit=m/s,MinAxes=1,MaxAxes=3", status ); - -/* Find the spectral axis within the current Frame of the supplied - FrameSet, using the above "velofrm" as a template. */ - fsconv1 = astFindFrame( curfrm, velofrm, "" ); - -/* If OK, extract the SpecFrame from the returned FraneSet (this will - have the attribute values that were assigned explicitly to "velofrm" - and will have inherited all unset attributes from the supplied - FrameSet). */ - if( fsconv1 ) { - velofrm = astAnnul( velofrm ); - velofrm = astGetFrame( fsconv1, AST__CURRENT ); - fsconv1 = astAnnul( fsconv1 ); - -/* Take a copy of the velofrm and modify its attributes so that it - describes frequency in the sources rest frame in units of Hz. This is - the system that CLASS expects for the CRVAL3 keyword. */ - freqfrm = astCopy( velofrm ); - astSet( freqfrm, "System=freq,StdOfRest=Source,Unit=Hz", status ); - -/* Get a Mapping from frequency to velocity. */ - fsconv1 = astConvert( freqfrm, velofrm, "" ); - if( fsconv1 ) { - -/* Use this Mapping to convert the spectral crval value from frequency to - velocity. Also convert the value for the neighbouring channel. */ - aval[ 0 ] = crval[ axspec ]*specfactor; - aval[ 1 ] = aval[ 0 ] + cdelt[ axspec ]*specfactor; - astTran1( fsconv1, 2, aval, 1, aval ); - -/* Store the value. Also store it as VLSR since this keyword seems to be - used for the same thing. */ - SetValue( this, "VELO-LSR", aval, AST__FLOAT, "[m/s] Reference velocity", status ); - SetValue( this, "VLSR", aval, AST__FLOAT, "[m/s] Reference velocity", status ); - -/* The DELTAV keyword holds the radio velocity channel spacing in the - LSR. */ - delta = aval[ 1 ] - aval[ 0 ]; - SetValue( this, "DELTAV", &delta, AST__FLOAT, "[m/s] Velocity resolution", status ); - -/* Free remaining resources. */ - fsconv1 = astAnnul( fsconv1 ); - } - } - velofrm = astAnnul( velofrm ); - -/* AZIMUTH and ELEVATIO - the (az,el) equivalent of CRVAL. We need a - Mapping from the CTYPE spatial system to (az,el). This depends on all - the extra info like telescope position, epoch, etc. This info is in - the current Frame in the supplied FrameSet. First get a conversion - from a sky frame with default axis ordering to the supplied Frame. All - the extra info is picked up from the supplied Frame since it is not set - in the template. */ - radecfrm = (AstFrame *) astSkyFrame( "Permute=0,MinAxes=3,MaxAxes=3", status ); - fsconv1 = astFindFrame( curfrm, radecfrm, "" ); - -/* Now get conversion from the an (az,el) Frame to the supplied Frame. */ - azelfrm = (AstFrame *) astSkyFrame( "System=AZEL,Permute=0,MinAxes=3,MaxAxes=3", status ); - fsconv2 = astFindFrame( curfrm, azelfrm, "" ); - -/* If both conversions werew possible, concatenate their Mappings to get - a Mapping from (lon,lat) in the CTYPE system, to (az,el). */ - if( fsconv1 && fsconv2 ) { - map1 = astGetMapping( fsconv1, AST__CURRENT, AST__BASE ); - map2 = astGetMapping( fsconv2, AST__BASE, AST__CURRENT ); - map3 = (AstMapping *) astCmpMap( map1, map2, 1, "", status ); - -/* Store the CRVAL (ra,dec) values in the default order. */ - radec[ 0 ] = crval[ axlon ]*AST__DD2R; - radec[ 1 ] = crval[ axlat ]*AST__DD2R; - -/* Transform to (az,el), normalise, convert to degrees and store. */ - astTranN( map3, 1, 2, 1, radec, 1, 2, 1, azel ); - if( azel[ 0 ] != AST__BAD && azel[ 1 ] != AST__BAD ) { - astNorm( azelfrm, azel ); - azel[ 0 ] *= AST__DR2D; - azel[ 1 ] *= AST__DR2D; - SetValue( this, "AZIMUTH", azel, AST__FLOAT, "[Deg] Telescope azimuth", status ); - SetValue( this, "ELEVATIO", azel + 1, AST__FLOAT, "[Deg] Telescope elevation", status ); - } - -/* Free resources */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - map3 = astAnnul( map3 ); - fsconv1 = astAnnul( fsconv1 ); - fsconv2 = astAnnul( fsconv2 ); - } - radecfrm = astAnnul( radecfrm ); - azelfrm = astAnnul( azelfrm ); - } - curfrm = astAnnul( curfrm ); - -/* Release CDELT workspace */ - if( cdelt ) cdelt = (double *) astFree( (void *) cdelt ); - -/* Return zero or ret depending on whether an error has occurred. */ - return astOK ? ok : 0; -} - -static void ClassTrans( AstFitsChan *this, AstFitsChan *ret, int axlat, - int axlon, const char *method, const char *class, int *status ){ - -/* -* Name: -* ClassTrans - -* Purpose: -* Translated non-standard FITS-CLASS headers into equivalent standard -* ones. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void ClassTrans( AstFitsChan *this, AstFitsChan *ret, int axlat, -* int axlon, const char *method, const char *class ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function extends the functionality of the SpecTrans function, -* by converting non-standard WCS keywords into standard FITS-WCS -* keywords, using the conventions of the FITS-CLASS encoding. - -* Parameters: -* this -* Pointer to the FitsChan containing the original header cards. -* ret -* Pointer to a FitsChan in which to return the standardised header -* cards. -* axlat -* Zero-based index of the celestial latitude axis. -* axlon -* Zero-based index of the celestial longitude axis. -* method -* Pointer to string holding name of calling method. -* class -* Pointer to a string holding the name of the supplied object class. -*/ - -/* Local Variables: */ - char *cval; /* Pointer to character string */ - char newtype[ 10 ]; /* New CTYPE value */ - const char *keyname; /* Pointer to keyword name */ - const char *ssyssrc; /* Pointer to SSYSSRC keyword value string */ - double crval; /* CRVAL value */ - double restfreq; /* Rest frequency (Hz) */ - double v0; /* Ref channel velocity in source frame */ - double vref; /* Ref channel velocity in LSR or whatever */ - double vsource; /* Source velocity */ - double zsource; /* Source redshift */ - int axspec; /* Index of spectral axis */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the rest frequency. */ - restfreq = AST__BAD; - if( !GetValue2( ret, this, "RESTFRQ", AST__FLOAT, (void *) &restfreq, 0, - method, class, status ) ){ - GetValue2( ret, this, "RESTFREQ", AST__FLOAT, (void *) &restfreq, 0, - method, class, status ); - } - if( restfreq == AST__BAD ) { - astError( AST__BDFTS, "%s(%s): Keyword RESTFREQ not found in CLASS " - "FITS header.", status, method, class ); - } - -/* Get the index of the spectral axis. */ - if( axlat + axlon == 1 ) { - axspec = 2; - } else if( axlat + axlon == 3 ) { - axspec = 0; - } else { - axspec = 1; - } - -/* Get the spectral CTYPE value */ - if( GetValue2( ret, this, FormatKey( "CTYPE", axspec + 1, -1, ' ', status ), - AST__STRING, (void *) &cval, 0, method, class, status ) ){ - -/* We can only handle frequency axes at the moment. */ - if( !astChrMatch( "FREQ", cval ) ) { - astError( AST__BDFTS, "%s(%s): FITS-CLASS keyword %s has value " - "\"%s\" - CLASS support in AST only includes \"FREQ\" axes.", status, - method, class, FormatKey( "CTYPE", axspec + 1, -1, ' ', status ), - cval ); - -/* CRVAL for the spectral axis needs to be incremented by RESTFREQ if the - axis represents frequency. */ - } else { - keyname = FormatKey( "CRVAL", axspec + 1, -1, ' ', status ); - if( GetValue2( ret, this, keyname, AST__FLOAT, (void *) &crval, 1, - method, class, status ) ) { - crval += restfreq; - SetValue( ret, keyname, (void *) &crval, AST__FLOAT, NULL, status ); - } - } - -/* CLASS frequency axes describe source frame frequencies. */ - cval = "SOURCE"; - SetValue( ret, "SPECSYS", (void *) &cval, AST__STRING, NULL, status ); - } - -/* If no projection code is supplied for the longitude and latitude axes, - use "-GLS". This will be translated to "-SFL" by SpecTrans. */ - keyname = FormatKey( "CTYPE", axlon + 1, -1, ' ', status ); - if( GetValue2( ret, this, keyname, AST__STRING, (void *) &cval, 0, method, - class, status ) ){ - if( strlen(cval) > 4 && !strncmp( " ", cval + 4, 4 ) ) { - strncpy( newtype, cval, 4 ); - strcpy( newtype + 4, "-GLS" ); - cval = newtype; - SetValue( ret, keyname, (void *) &cval, AST__STRING, NULL, status ); - } - } - keyname = FormatKey( "CTYPE", axlat + 1, -1, ' ', status ); - if( GetValue2( ret, this, keyname, AST__STRING, (void *) &cval, 0, method, - class, status ) ){ - if( strlen(cval) > 4 && !strncmp( " ", cval + 4, 4 ) ) { - strncpy( newtype, cval, 4 ); - strcpy( newtype + 4, "-GLS" ); - cval = newtype; - SetValue( ret, keyname, (void *) &cval, AST__STRING, NULL, status ); - } - } - -/* Look for a keyword with name "VELO-...". This specifies the radio velocity - at the reference channel, in a standard of rest specified by the "..." - in the keyword name. If "VELO-..." is not found, look for "VLSR", - which is the same as "VELO-LSR". */ - if( GetValue2( ret, this, "VELO-%3c", AST__FLOAT, (void *) &vref, 0, - method, class, status ) || - GetValue2( ret, this, "VLSR", AST__FLOAT, (void *) &vref, 0, - method, class, status ) ){ - -/* Calculate the radio velocity (in the rest frame of the source) corresponding - to the frequency at the reference channel. */ - v0 = AST__C*( restfreq - crval )/restfreq; - -/* Assume that the source velocity is the difference between this velocity - and the reference channel velocity given by "VELO-..." */ - vsource = vref - v0; - -/* Get the keyword name and find the corresponding SSYSSRC keyword value. */ - keyname = CardName( this, status ); - if( !strcmp( keyname, "VELO-HEL" ) ) { - ssyssrc = "BARYCENT"; - } else if( !strcmp( keyname, "VELO-OBS" ) || !strcmp( keyname, "VELO-TOP" ) ) { - ssyssrc = "TOPOCENT"; - } else if( !strcmp( keyname, "VELO-EAR" ) || !strcmp( keyname, "VELO-GEO" ) ) { - ssyssrc = "GEOCENTR"; - } else { - ssyssrc = "LSRK"; - } - SetValue( ret, "SSYSSRC", (void *) &ssyssrc, AST__STRING, NULL, status ); - -/* Convert from radio velocity to redshift and store as ZSOURCE */ - zsource = ( AST__C / (AST__C - vsource) ) - 1.0; - SetValue( ret, "ZSOURCE", (void *) &zsource, AST__FLOAT, NULL, status ); - } -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* FitsChan member function (over-rides the astClearAttrib protected -* method inherited from the Channel class). - -* Description: -* This function clears the value of a specified attribute for a -* FitsChan, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the FitsChan. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Card. */ -/* ----- */ - if ( !strcmp( attrib, "card" ) ) { - astClearCard( this ); - -/* Encoding. */ -/* --------- */ - } else if ( !strcmp( attrib, "encoding" ) ) { - astClearEncoding( this ); - -/* CDMatrix */ -/* -------- */ - } else if ( !strcmp( attrib, "cdmatrix" ) ) { - astClearCDMatrix( this ); - -/* FitsAxisOrder. */ -/* ----------- */ - } else if ( !strcmp( attrib, "fitsaxisorder" ) ) { - astClearFitsAxisOrder( this ); - -/* FitsDigits. */ -/* ----------- */ - } else if ( !strcmp( attrib, "fitsdigits" ) ) { - astClearFitsDigits( this ); - -/* DefB1950 */ -/* -------- */ - } else if ( !strcmp( attrib, "defb1950" ) ) { - astClearDefB1950( this ); - -/* TabOK */ -/* ----- */ - } else if ( !strcmp( attrib, "tabok" ) ) { - astClearTabOK( this ); - -/* CarLin */ -/* ------ */ - } else if ( !strcmp( attrib, "carlin" ) ) { - astClearCarLin( this ); - -/* SipReplace */ -/* ---------- */ - } else if ( !strcmp( attrib, "sipreplace" ) ) { - astClearSipReplace( this ); - -/* FitsTol */ -/* ------- */ - } else if ( !strcmp( attrib, "fitstol" ) ) { - astClearFitsTol( this ); - -/* PolyTan */ -/* ------- */ - } else if ( !strcmp( attrib, "polytan" ) ) { - astClearPolyTan( this ); - -/* SipOK */ -/* ------- */ - } else if ( !strcmp( attrib, "sipok" ) ) { - astClearSipOK( this ); - -/* Iwc */ -/* --- */ - } else if ( !strcmp( attrib, "iwc" ) ) { - astClearIwc( this ); - -/* Clean */ -/* ----- */ - } else if ( !strcmp( attrib, "clean" ) ) { - astClearClean( this ); - -/* Warnings. */ -/* -------- */ - } else if ( !strcmp( attrib, "warnings" ) ) { - astClearWarnings( this ); - -/* If the name was not recognised, test if it matches any of the - read-only attributes of this class. If it does, then report an - error. */ - } else if ( astOK && ( !strcmp( attrib, "ncard" ) || - !strcmp( attrib, "allwarnings" ) ) ){ - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearCard( AstFitsChan *this, int *status ){ - -/* -*+ -* Name: -* astClearCard - -* Purpose: -* Clear the Card attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* void astClearCard( AstFitsChan *this ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function clears the Card attribute for the supplied FitsChan by -* setting it to the index of the first un-used card in the FitsChan. -* This causes the next read operation performed on the FitsChan to -* read the first card. Thus, it is equivalent to "rewinding" the FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Notes: -* - This function attempts to execute even if an error has occurred. -*- -*/ - -/* Local Variables; */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Check the supplied FitsChan. If its is empty, return. */ - if ( !this || !(this->head) ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Set the pointer to the current card so that it points to the card at - the head of the list. */ - this->card = this->head; - -/* If the current card has been read into an AST object, move on to the - first card which has not, unless we are not skipping such cards. */ - if( CARDUSED(this->card) ){ - MoveCard( this, 1, "astClearCard", astGetClass( this ), status ); - } -} - -static int CnvValue( AstFitsChan *this, int type, int undef, void *buff, - const char *method, int *status ){ - -/* -* -* Name: -* CnvValue - -* Purpose: -* Convert a data value into a given FITS data type. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int CnvValue( AstFitsChan *this, int type, int undef, void *buff, -* const char *method, int *status ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function produces a copy of the data value for the current card -* converted from its stored data type to the supplied data type. - -* Parameters: -* this -* Pointer to the FitsChan. -* type -* The FITS data type in which to return the data value of the -* current card. -* undef -* Determines what happens if the current card has an undefined -* value. If "undef" is zero, an error will be reported identifying -* the undefined keyword value. If "undef" is non-zero, no error is -* reported and the contents of the output buffer are left unchanged. -* buf -* A pointer to a buffer to recieve the converted value. It is the -* responsibility of the caller to ensure that a suitable buffer is -* supplied. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the conversion was not possible (in which case NO error is -* reported), one otherwise. - -* Notes: -* - When converting from floating point to integer, the floating -* point value is truncated using a C cast. -* - Non-zero numerical values are considered TRUE, and zero -* numerical values are considered FALSE. Any string starting with a -* 'T' or a 'Y' (upper or lower case) is considered TRUE, and anything -* starting with an 'F' or an 'N' (upper or lower case) is considered -* FALSE. In addition, a dot ('.') may be placed in front of a 'T' or an -* 'F'. -* - A logical TRUE value is represented as a real numerical value of -* one and the character string "Y". A logical FALSE value is represented -* by a real numerical value of zero and the character string "N". -* - When converting from a string to any numerical value, zero is -* returned if the string is not a formatted value which can be converted -* into the corresponding type using astSscanf. -* - Real and imaginary parts of a complex value should be separated by -* spaces within strings. If a string does contains only a single numerical -* value, it is assumed to be the real part, and the imaginary part is -* assumed to be zero. -* - When converting a complex numerical type to a non-complex numerical -* type, the returned value is derived from the real part only, the -* imaginary part is ignored. -* - Zero is returned if an error has occurred, or if this function -* should fail for any reason. -* - If the supplied value is undefined an error will be reported. -*/ - -/* Local Variables: */ - int otype; /* Stored data type */ - size_t osize; /* Size of stored data */ - void *odata; /* Pointer to stored data */ - -/* Check the global error status, and the supplied buffer. */ - if ( !astOK || !buff ) return 0; - -/* Get the type in which the data value is stored. */ - otype = CardType( this, status ); - -/* Get a pointer to the stored data value, and its size. */ - osize = 0; - odata = CardData( this, &osize, status ); - -/* Do the conversion. */ - return CnvType( otype, odata, osize, type, undef, buff, - CardName( this, status ), method, astGetClass( this ), - status ); -} - -static int CnvType( int otype, void *odata, size_t osize, int type, int undef, - void *buff, const char *name, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* CnvType - -* Purpose: -* Convert a data value into a given FITS data type. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int CnvType( int otype, void *odata, size_t osize, int type, int undef, -* void *buff, const char *name, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function produces a copy of the data value for the current card -* converted from its stored data type to the supplied data type. - -* Parameters: -* otype -* The type of the supplied data value. -* odata -* Pointer to a buffer holding the supplied data value. -* osize -* The size of the data value (in bytes - strings include the -* terminating null). -* type -* The FITS data type in which to return the data value of the -* current card. -* undef -* Determines what happens if the supplied data value type is -* undefined If "undef" is zero, an error will be reported identifying -* the undefined keyword value. If "undef" is non-zero, no error is -* reported and the contents of the output buffer are left unchanged. -* buff -* A pointer to a buffer to recieve the converted value. It is the -* responsibility of the caller to ensure that a suitable buffer is -* supplied. -* name -* A pointer to a string holding a keyword name to include in error -* messages. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the conversion was not possible (in which case NO error is -* reported), one otherwise. - -* Notes: -* - When converting from floating point to integer, the floating -* point value is truncated using a C cast. -* - Non-zero numerical values are considered TRUE, and zero -* numerical values are considered FALSE. Any string starting with a -* 'T' or a 'Y' (upper or lower case) is considered TRUE, and anything -* starting with an 'F' or an 'N' (upper or lower case) is considered -* FALSE. In addition, a dot ('.') may be placed in front of a 'T' or an -* 'F'. -* - A logical TRUE value is represented as a real numerical value of -* one and the character string "Y". A logical FALSE value is represented -* by a real numerical value of zero and the character string "N". -* - When converting from a string to any numerical value, zero is -* returned if the string isn not a formatted value which can be converted -* into the corresponding type using astSscanf. -* - Real and imaginary parts of a complex value should be separated by -* spaces within strings. If a string does contains only a single numerical -* value, it is assumed to be the real part, and the imaginary part is -* assumed to be zero. -* - When converting a complex numerical type to a non-complex numerical -* type, the returned value is derived from the real part only, the -* imaginary part is ignored. -* - Zero is returned if an error has occurred, or if this function -* should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *c; /* Pointer to next character */ - const char *ostring; /* String data value */ - double odouble; /* Double data value */ - int oint; /* Integer data value */ - int ival; /* Integer value read from string */ - int len; /* Length of character string */ - int nc; /* No. of characetsr used */ - int ret; /* Returned success flag */ - -/* Check the global error status, and the supplied buffer. */ - if ( !astOK || !buff ) return 0; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Assume success. */ - ret = 1; - -/* If the supplied data type is undefined, report an error unless the - returned data type is also undefined or an undefined value is - acceptable for the keyword. */ - if( otype == AST__UNDEF ) { - if( type != AST__UNDEF && !undef ) { - ret = 0; - astError( AST__FUNDEF, "The FITS keyword '%s' has an undefined " - "value.", status, name ); - } - -/* If the returned data type is undefined, the returned value is - immaterial, so leave the buffer contents unchanged. */ - } else if( type == AST__UNDEF ) { - -/* If there is no data value and this is not a COMMENT keyword, or if - there is a data value and this is a COMMENT card, conversion is not - possible. */ - } else if( ( odata && otype == AST__COMMENT ) || - ( !odata && otype != AST__COMMENT ) ) { - ret = 0; - -/* If there is no data value (and therefore this is a comment card), - conversion is only possible if the output type is also a comment. */ - } else if( !odata ) { - if( type != AST__COMMENT ) ret = 0; - -/* Otherwise we have a data value, so do each possible combination of - supplied and stored data types... */ - } else { - -/* Convert a AST__FLOAT data value to ... */ - if( otype == AST__FLOAT ){ - odouble = *( (double *) odata ); - if( type == AST__FLOAT ){ - (void) memcpy( buff, odata, osize ); - } else if( type == AST__STRING || type == AST__CONTINUE ){ - if( odouble != AST__BAD ) { - (void) sprintf( cnvtype_text, "%.*g", AST__DBL_DIG, odouble ); - CheckZero( cnvtype_text, odouble, 0, status ); - } else { - strcpy( cnvtype_text, BAD_STRING ); - } - *( (char **) buff ) = cnvtype_text; - } else if( type == AST__INT ){ - *( (int *) buff ) = (int) odouble; - } else if( type == AST__LOGICAL ){ - *( (int *) buff ) = ( odouble == 0.0 ) ? 0 : 1; - } else if( type == AST__COMPLEXF ){ - ( (double *) buff )[ 0 ] = odouble; - ( (double *) buff )[ 1 ] = 0.0; - } else if( type == AST__COMPLEXI ){ - ( (int *) buff )[ 0 ] = (int) odouble; - ( (int *) buff )[ 1 ] = 0; - } else if( astOK ){ - ret = 0; - astError( AST__INTER, "CnvType: AST internal programming error - " - "FITS data-type no. %d not yet supported.", status, type ); - } - -/* Convert a AST__STRING data value to ... */ - } else if( otype == AST__STRING || type == AST__CONTINUE ){ - ostring = (char *) odata; - len = (int) strlen( ostring ); - if( type == AST__FLOAT ){ - if( nc = 0, - ( 0 == astSscanf( ostring, BAD_STRING " %n", &nc ) ) - && (nc >= len ) ){ - *( (double *) buff ) = AST__BAD; - } else if( nc = 0, - ( 1 != astSscanf( ostring, "%lf %n", (double *) buff, &nc ) ) - || (nc < len ) ){ - ret = 0; - } - } else if( type == AST__STRING || type == AST__CONTINUE ){ - strncpy( cnvtype_text, (char *) odata, AST__FITSCHAN_FITSCARDLEN ); - *( (char **) buff ) = cnvtype_text; - } else if( type == AST__INT ){ - if( nc = 0, - ( 1 != astSscanf( ostring, "%d %n", (int *) buff, &nc ) ) - || (nc < len ) ){ - ret = 0; - } - } else if( type == AST__LOGICAL ){ - if( nc = 0, - ( 1 == astSscanf( ostring, "%d %n", &ival, &nc ) ) - && (nc >= len ) ){ - *( (int *) buff ) = ival ? 1 : 0; - } else { - c = ostring; - while( *c && isspace( (int) *c ) ) c++; - if( *c == 'y' || *c == 'Y' || *c == 't' || *c == 'T' || - ( *c == '.' && ( c[1] == 't' || c[1] == 'T' ) ) ){ - *( (int *) buff ) = 1; - } else if( *c == 'n' || *c == 'N' || *c == 'f' || *c == 'F' || - ( *c == '.' && ( c[1] == 'f' || c[1] == 'F' ) ) ){ - *( (int *) buff ) = 0; - } else { - ret = 0; - } - } - } else if( type == AST__COMPLEXF ){ - if( nc = 0, - ( 1 != astSscanf( ostring, "%lf %lf %n", (double *) buff, - (double *) buff + 1, &nc ) ) - || (nc < len ) ){ - if( nc = 0, - ( 1 != astSscanf( ostring, "%lf %n", (double *) buff, - &nc ) ) - || (nc < len ) ){ - ret = 0; - } else { - ( (double *) buff )[ 1 ] = 0.0; - } - } - } else if( type == AST__COMPLEXI ){ - if( nc = 0, - ( 1 != astSscanf( ostring, "%d %d %n", (int *) buff, - (int *) buff + 1, &nc ) ) - || (nc < len ) ){ - if( nc = 0, - ( 1 != astSscanf( ostring, "%d %n", (int *) buff, &nc ) ) - || (nc < len ) ){ - ret = 0; - } else { - ( (int *) buff )[ 1 ] = 0; - } - } - } else if( astOK ){ - ret = 0; - astError( AST__INTER, "CnvType: AST internal programming error - " - "FITS data-type no. %d not yet supported.", status, type ); - } - -/* Convert an AST__INT data value to ... */ - } else if( otype == AST__INT ){ - oint = *( (int *) odata ); - if( type == AST__FLOAT ){ - *( (double *) buff ) = (double) oint; - } else if( type == AST__STRING || type == AST__CONTINUE ){ - (void) sprintf( cnvtype_text, "%d", oint ); - *( (char **) buff ) = cnvtype_text; - } else if( type == AST__INT ){ - (void) memcpy( buff, odata, osize ); - } else if( type == AST__LOGICAL ){ - *( (int *) buff ) = oint ? 1 : 0; - } else if( type == AST__COMPLEXF ){ - ( (double *) buff )[ 0 ] = (double) oint; - ( (double *) buff )[ 1 ] = 0.0; - } else if( type == AST__COMPLEXI ){ - ( (int *) buff )[ 0 ] = oint; - ( (int *) buff )[ 1 ] = 0; - } else if( astOK ){ - ret = 0; - astError( AST__INTER, "CnvType: AST internal programming error - " - "FITS data-type no. %d not yet supported.", status, type ); - } - -/* Convert a LOGICAL data value to ... */ - } else if( otype == AST__LOGICAL ){ - oint = *( (int *) odata ); - if( type == AST__FLOAT ){ - *( (double *) buff ) = oint ? 1.0 : 0.0; - } else if( type == AST__STRING || type == AST__CONTINUE ){ - if( oint ){ - strcpy( cnvtype_text, "Y" ); - } else { - strcpy( cnvtype_text, "N" ); - } - *( (char **) buff ) = cnvtype_text; - } else if( type == AST__INT ){ - *( (int *) buff ) = oint; - } else if( type == AST__LOGICAL ){ - (void) memcpy( buff, odata, osize ); - } else if( type == AST__COMPLEXF ){ - ( (double *) buff )[ 0 ] = oint ? 1.0 : 0.0; - ( (double *) buff )[ 1 ] = 0.0; - } else if( type == AST__COMPLEXI ){ - ( (int *) buff )[ 0 ] = oint ? 1 : 0; - ( (int *) buff )[ 1 ] = 0; - } else if( astOK ){ - ret = 0; - astError( AST__INTER, "CnvType: AST internal programming error - " - "FITS data-type no. %d not yet supported.", status, type ); - } - -/* Convert a AST__COMPLEXF data value to ... */ - } else if( otype == AST__COMPLEXF ){ - odouble = ( (double *) odata )[ 0 ]; - if( type == AST__FLOAT ){ - *( (double *) buff ) = odouble; - } else if( type == AST__STRING || type == AST__CONTINUE ){ - (void) sprintf( cnvtype_text0, "%.*g", AST__DBL_DIG, ( (double *) odata )[ 0 ] ); - CheckZero( cnvtype_text0, ( (double *) odata )[ 0 ], 0, status ); - (void) sprintf( cnvtype_text1, "%.*g", AST__DBL_DIG, ( (double *) odata )[ 1 ] ); - CheckZero( cnvtype_text1, ( (double *) odata )[ 1 ], 0, status ); - (void) sprintf( cnvtype_text, "%s %s", cnvtype_text0, cnvtype_text1 ); - *( (char **) buff ) = cnvtype_text; - } else if( type == AST__INT ){ - *( (int *) buff ) = (int) odouble; - } else if( type == AST__LOGICAL ){ - *( (int *) buff ) = ( odouble == 0.0 ) ? 0 : 1; - } else if( type == AST__COMPLEXF ){ - (void) memcpy( buff, odata, osize ); - } else if( type == AST__COMPLEXI ){ - ( (int *) buff )[ 0 ] = (int) odouble; - ( (int *) buff )[ 1 ] = (int) ( (double *) odata )[ 1 ]; - } else if( astOK ){ - ret = 0; - astError( AST__INTER, "CnvType: AST internal programming error - " - "FITS data-type no. %d not yet supported.", status, type ); - } - -/* Convert a AST__COMPLEXI data value to ... */ - } else if( otype == AST__COMPLEXI ){ - oint = ( (int *) odata )[ 0 ]; - if( type == AST__FLOAT ){ - *( (double *) buff ) = (double) oint; - } else if( type == AST__STRING || type == AST__CONTINUE ){ - (void) sprintf( cnvtype_text, "%d %d", ( (int *) odata )[ 0 ], - ( (int *) odata )[ 1 ] ); - *( (char **) buff ) = cnvtype_text; - } else if( type == AST__INT ){ - *( (int *) buff ) = oint; - } else if( type == AST__LOGICAL ){ - *( (int *) buff ) = oint ? 1 : 0; - } else if( type == AST__COMPLEXF ){ - ( (double *) buff )[ 0 ] = (double) oint; - ( (double *) buff )[ 1 ] = (double) ( (int *) odata )[ 1 ]; - } else if( type == AST__COMPLEXI ){ - (void) memcpy( buff, odata, osize ); - } else if( astOK ){ - ret = 0; - astError( AST__INTER, "CnvType: AST internal programming error - " - "FITS data-type no. %d not yet supported.", status, type ); - } - } else if( astOK ){ - ret = 0; - astError( AST__INTER, "CnvType: AST internal programming error - " - "FITS data-type no. %d not yet supported.", status, type ); - } - } - return ret; -} - -static int ComBlock( AstFitsChan *this, int incr, const char *method, - const char *class, int *status ){ - -/* -* Name: -* ComBlock - -* Purpose: -* Delete a AST comment block in a Native-encoded FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int ComBlock( AstFitsChan *this, int incr, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function looks for a block of comment cards as defined below, -* and deletes all the cards in the block, if a suitable block is found. -* -* Comment blocks consist of a contiguous sequence of COMMENT cards. The -* text of each card should start and end with the 3 characters "AST". -* The block is delimited above by a card containing all +'s (except -* for the two "AST" strings), and below by a card containing all -'s. -* -* The block is assumed to start on the card which is adjacent to the -* current card on entry. - -* Parameters: -* this -* Pointer to the FitsChan. -* incr -* This should be either +1 or -1, and is the increment between -* adjacent cards in the comment block. A value of +1 means -* that the card following the current card is taken as the first in -* the block, and subsequent cards are checked. The block must then -* end with a line of -'s. If -1 is supplied, then the card -* preceding the current card is taken as the first in the block, -* and preceding cards are checked. The block must then end with -* a row of +'s. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* 1 if a block was found and deleted, 0 otherwise. - -* Notes: -* - The pointer to the current card is returned unchanged. -*/ - -/* Local Variables: */ - FitsCard *card0; /* Pointer to current FitsCard on entry */ - char del; /* Delimiter character */ - char *text; /* Pointer to the comment text */ - int i; /* Card index within the block */ - int ncard; /* No. of cards in the block */ - int ret; /* The returned flag */ - size_t len; /* Length of the comment text */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Save the pointer to the current card. */ - card0 = this->card; - -/* Initialise the returned flag to indicate that we have not found a - comment block. */ - ret = 0; - -/* Move on to the first card in the block. If this is not possible (due to - us already being at the start or end of the FitsChan), then return. */ - if( MoveCard( this, incr, method, class, status ) == 1 ) { - -/* Store the character which is used in the delimiter line for the - comment block. */ - del = ( incr == 1 ) ? '-' : '+'; - -/* Initialise the number of cards in the comment block to zero. */ - ncard = 0; - -/* Loop round until the end (or start) of the comment block is found. - Leave the loop if an error occurs. */ - while( astOK ) { - -/* Is this card a comment card? If not, then we have failed to find a - complete comment block. Break out of the loop. */ - if( CardType( this, status ) != AST__COMMENT ) break; - -/* Increment the number of cards in the comment block. */ - ncard++; - -/* Get the text of the comment, and its length. */ - text = CardComm( this, status ); - if( text ){ - len = strlen( text ); - -/* Check the first 3 characters. Break out of the loop if they are not - "AST". */ - if( strncmp( "AST", text, 3 ) ) break; - -/* Check the last 3 characters. Break out of the loop if they are not - "AST". */ - if( strcmp( "AST", text + len - 3 ) ) break; - -/* If the comment is the appropriate block delimiter (a line of +'s or - -'s depending on the direction), then set the flag to indicate that we - have a complete comment block and leave the loop. Allow spaces to be - included. Exclude the "AST" strings at begining and end from the check. */ - ret = 1; - for( i = 3; i < len - 3; i++ ) { - if( text[ i ] != del && text[ i ] != ' ' ) { - ret = 0; - break; - } - } - } - if( ret ) break; - -/* Move on to the next card. If this is not possible (due to us already - being at the start or end of the FitsChan), then break out of the loop. */ - if( MoveCard( this, incr, method, class, status ) == 0 ) break; - } - -/* Re-instate the original current card. */ - this->card = card0; - -/* If we found a complete comment block, mark it (which is equivalent to - deleting it except that memory of the cards location within the - FitsChan is preserved for future use), and then re-instate the original - current card. */ - if( ret && astOK ) { - for( i = 0; i < ncard; i++ ) { - MoveCard( this, incr, method, class, status ); - MarkCard( this, status ); - } - this->card = card0; - } - } - -/* If an error occurred, indicate that coment block has been deleted. */ - if( !astOK ) ret = 0; - return ret; -} - -static char *ConcatWAT( AstFitsChan *this, int iaxis, const char *method, - const char *class, int *status ){ -/* -* Name: -* ConcatWAT - -* Purpose: -* Concatenate all the IRAF "WAT" keywords for an axis. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* char *ConcatWAT( AstFitsChan *this, int iaxis, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function searches the supplied FitsChan for any keywords of -* the form "WATi_j", where i and j are integers and i is equal to the -* supplied "iaxis" value plus one, and concatenates their string -* values into a single string. Such keywords are created by IRAF to -* describe their non-standard ZPX and TNX projections. - -* Parameters: -* this -* The FistChan. -* iaxis -* The zero-based index of the axis to be retrieved. -* method -* The name of the calling method to include in error messages. -* class -* The object type to include in error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated, null terminated string -* containing a copy of the concatentated WAT values. This string must -* be freed by the caller (using astFree) when no longer required. -* -* A NULL pointer will be returned if there are no WAT kewyords for -* the requested axis in the FitsChan. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - char keyname[ FITSNAMLEN + 5 ];/* Keyword name */ - char *wat; /* Pointer to a single WAT string */ - char *result; /* Returned string */ - int watlen; /* Length of total WAT string (inc. term null)*/ - int j; /* WAT index */ - size_t size; /* Length of string value */ - -/* Initialise returned value. */ - result = NULL; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Rewind the FitsChan. */ - astClearCard( this ); - -/* Concatenate all the IRAF "WAT" keywords together for this axis. These - keywords are marked as having been used, so that they are not written - out when the FitsChan is deleted. */ - watlen = 1; - j = 1; - size = 0; - sprintf( keyname, "WAT%d_%.3d", iaxis + 1, j ); - while( astOK ) { - -/* Search forward from the current card for the next WAT card. If no - found, try searching again from the start of the FitsChan. If not found - evenm then, break. */ - if( ! FindKeyCard( this, keyname, method, class, status ) ) { - astClearCard( this ); - if( ! FindKeyCard( this, keyname, method, class, status ) ) break; - } - - wat = (char *) CardData( this, &size, status ); - result = (char *) astRealloc( (void *) result, - watlen - 1 + size ); - if( result ) { - strcpy( result + watlen - 1, wat ); - watlen += size - 1; - MarkCard( this, status ); - MoveCard( this, 1, method, class, status ); - j++; - sprintf( keyname, "WAT%d_%.3d", iaxis + 1, j ); - } else { - break; - } - } - -/* Return the result. */ - return result; -} - -static int CountFields( const char *temp, char type, const char *method, - const char *class, int *status ){ -/* -* Name: -* CountFields - -* Purpose: -* Count the number of field specifiers in a template string. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int CountFields( const char *temp, char type, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns the number of fields which include the -* specified character type in the supplied string. - -* Parameters: -* temp -* Pointer to a null terminated string holding the template. -* type -* A single character giving the field type to be counted (e.g. -* 'd', 'c' or 'f'). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of fields. - -* Notes: -* - No error is reported if the parameter "type" is not a valid -* field type specifier, but zero will be returned. -* - An error is reported if the template has any invalid field -* specifiers in it. -* - A value of zero is returned if an error has already occurred, -* or if this function should fail for any reason. -*/ - -/* Local Variables: */ - const char *b; /* Pointer to next template character */ - int nf; /* No. of fields found so far */ - -/* Check global status. */ - if( !astOK ) return 0; - -/* Initialise a pointer to the start of the template string. */ - b = temp; - -/* Initialise the number of fields found so far. */ - nf = 0; - -/* Go through the string. */ - while( *b && astOK ){ - -/* If the current character is a '%', a field is starting. */ - if( *b == '%' ){ - -/* Skip over the field width (if supplied). */ - if( isdigit( (int) *(++b) ) ) b++; - -/* Report an error if the end of the string occurs within the field. */ - if( !*b ) { - astError( AST__BDFMT, "%s(%s): Incomplete field specifier found " - "at end of filter template '%s'.", status, method, class, - temp ); - break; - -/* Report an error if the field type is illegal. */ - } else if( *b != 'd' && *b != 'c' && *b != 'f' ) { - astError( AST__BDFMT, "%s(%s): Illegal field type or width " - "specifier '%c' found in filter template '%s'.", status, - method, class, *b, temp ); - break; - } - -/* Compare the field type with the supplied type, and increment the - number of fields found if it is the correct type. */ - if( *b == type ) nf++; - } - -/* Move on to the next character. */ - b++; - } - -/* If an error has occurred, return 0. */ - if( !astOK ) nf = 0; - -/* Return the answer. */ - return nf; -} - -static void CreateKeyword( AstFitsChan *this, const char *name, - char keyword[ FITSNAMLEN + 1 ], int *status ){ - -/* -* Name: -* CreateKeyword - -* Purpose: -* Create a unique un-used keyword for a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void CreateKeyword( AstFitsChan *this, const char *name, -* char keyword[ FITSNAMLEN + 1 ], int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function takes a name which forms the basis of a FITS -* keyword and appends a sequence number (encoded as a pair of -* legal FITS keyword characters) so as to generate a unique FITS -* keyword which has not previously been used in the FitsChan -* supplied. -* -* It is intended for use when several keywords with the same name -* must be stored in a FitsChan, since to comply strictly with the -* FITS standard keywords should normally be unique (otherwise -* external software which processes the keywords might omit one or -* other of the values). -* -* An attempt is also made to generate keywords in a form that is -* unlikely to clash with those from other sources (in as far as -* this is possible with FITS). In any event, a keyword that -* already appears in the FitsChan will not be re-used. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* Pointer to a constant null-terminated string containing the -* name on which the new keyword should be based. This should be -* a legal FITS keyword in itself, except that it should be at -* least two characters shorter than the maximum length, in -* order to accommodate the sequence number characters. -* -* If this string is too long, it will be silently -* truncated. Mixed case is permitted, as all characters -* supplied are converted to upper case before use. -* keyword -* A character array in which the generated unique keyword will -* be returned, null terminated. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *seq_chars = SEQ_CHARS;/* Pointer to characters used for encoding */ - char seq_char; /* The first sequence character */ - const char *class; /* Object clas */ - int found; /* Keyword entry found in list? */ - int limit; /* Sequence number has reached limit? */ - int nc; /* Number of basic keyword characters */ - int seq; /* The sequence number */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Store the object class. */ - class = astGetClass( this ); - -/* On the first invocation only, determine the number of characters - being used to encode sequence number information and save this - value. */ - if( createkeyword_seq_nchars < 0 ) createkeyword_seq_nchars = (int) strlen( seq_chars ); - -/* Copy the name supplied into the output array, converting to upper - case. Leave space for two characters to encode a sequence - number. Terminate the resulting string. */ - for( nc = 0; ( nc < ( FITSNAMLEN - 2 ) ) && name[ nc ]; nc++ ) { - keyword[ nc ] = toupper( name[ nc ] ); - } - keyword[ nc ] = '\0'; - -/* We now search the list of sequence numbers already allocated to - find the next one to use for this keyword. */ - if( this->keyseq ) { - found = astMapGet0I( this->keyseq, keyword, &seq ); - } else { - found = 0; - this->keyseq = astKeyMap( " ", status ); - } - -/* If the keyword was not found in the list, create a new list entry - to describe it. */ - if( !found ) seq = 0; - -/* If OK, loop to find a new sequence number which results in a FITS - keyword that hasn't already been used to store data in the - FitsChan. */ - if( astOK ) { - while( 1 ) { - -/* Determine if the sequence number just obtained has reached the - upper limit. This is unlikely to happen in practice, but if it - does, we simply re-use this maximum value. Otherwise, we increment - the sequence number last used for this keyword to obtain a new - one. */ - limit = ( seq >= ( createkeyword_seq_nchars * createkeyword_seq_nchars - 1 ) ); - if( !limit ) seq++; - -/* Encode the sequence number into two characters and append them to - the original keyword (with a terminating null). */ - seq_char = seq_chars[ seq / createkeyword_seq_nchars ]; - keyword[ nc ] = seq_char; - keyword[ nc + 1 ] = seq_chars[ seq % createkeyword_seq_nchars ]; - keyword[ nc + 2 ] = '\0'; - -/* If the upper sequence number limit has not been reached, try to - look up the resulting keyword in the FitsChan to see if it has - already been used. Quit searching when a suitable keyword is - found. */ - if ( limit || !HasCard( this, keyword, "astWrite", class, status ) ) break; - } - -/* Store the update sequence number in the keymap. The keys into this - keymap are the base keyword name without the appended sequence string, so - temporaily terminate the returned keyword name to exclude the sequence - string. */ - keyword[ nc ] = '\0'; - astMapPut0I( this->keyseq, keyword, seq, NULL ); - keyword[ nc ] = seq_char; - } -} - -static double DateObs( const char *dateobs, int *status ) { -/* -* Name: -* DateObs - -* Purpose: -* Convert a FITS DATE-OBS keyword value to a MJD. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* double DateObs( const char *dateobs, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Extracts the date and time fields from the supplied string and converts -* them into a modified Julian Date. Supports both old "dd/mm/yy" -* format, and the new "ccyy-mm-ddThh:mm:ss[.sss...]" format. - -* Parameters: -* dateobs -* Pointer to the DATE-OBS string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Modified Julian Date corresponding to the supplied DATE-OBS -* string. - -* Notes: -* - The value AST__BAD is returned (without error) if the supplied -* string does not conform to the requirements of a FITS DATE-OBS value, -* or if an error has already occurred. -*/ - -/* Local Variables: */ - double days; /* The hours, mins and secs as a fraction of a day */ - double ret; /* The returned MJD value */ - double secs; /* The total value of the two seconds fields */ - int dd; /* The day field from the supplied string */ - int fsc; /* The fractional seconds field from the supplied string */ - int hr; /* The hour field from the supplied string */ - int j; /* SLALIB status */ - int len; /* The length of the supplied string */ - int mm; /* The month field from the supplied string */ - int mn; /* The minute field from the supplied string */ - int nc; /* Number of characters used */ - int ok; /* Was the string of a legal format? */ - int rem; /* The least significant digit in fsc */ - int sc; /* The whole seconds field from the supplied string */ - int yy; /* The year field from the supplied string */ - -/* Check the global status. */ - if( !astOK ) return AST__BAD; - -/* Initialise the returned value. */ - ret = AST__BAD; - -/* Save the length of the supplied string. */ - len = (int) strlen( dateobs ); - -/* Extract the year, month, day, hour, minute, second and fractional - seconds fields from the supplied string. Assume initially that the - string does not match any format. */ - ok = 0; - -/* First check for the old "dd/mm/yy" format. */ - if( nc = 0, - ( astSscanf( dateobs, " %2d/%2d/%d %n", &dd, &mm, &yy, &nc ) == 3 ) && - ( nc >= len ) ){ - ok = 1; - hr = 0; - mn = 0; - sc = 0; - fsc = 0; - -/* Otherwise, check for the new short format "ccyy-mm-dd". */ - } else if( nc = 0, - ( astSscanf( dateobs, " %4d-%2d-%2d %n", &yy, &mm, &dd, &nc ) == 3 ) && - ( nc >= len ) ){ - ok = 1; - hr = 0; - mn = 0; - sc = 0; - fsc = 0; - -/* Otherwise, check for the new format "ccyy-mm-ddThh:mm:ss" without a - fractional seconds field or the trailing Z. */ - } else if( nc = 0, - ( astSscanf( dateobs, " %4d-%2d-%2dT%2d:%2d:%2d %n", &yy, &mm, &dd, - &hr, &mn, &sc, &nc ) == 6 ) && ( nc >= len ) ){ - ok = 1; - fsc = 0; - -/* Otherwise, check for the new format "ccyy-mm-ddThh:mm:ss.sss" with a - fractional seconds field but without the trailing Z. */ - } else if( nc = 0, - ( astSscanf( dateobs, " %4d-%2d-%2dT%2d:%2d:%2d.%d %n", &yy, &mm, &dd, - &hr, &mn, &sc, &fsc, &nc ) == 7 ) && ( nc >= len ) ){ - ok = 1; - -/* Otherwise, check for the new format "ccyy-mm-ddThh:mm:ssZ" without a - fractional seconds field but with the trailing Z. */ - } else if( nc = 0, - ( astSscanf( dateobs, " %4d-%2d-%2dT%2d:%2d:%2dZ %n", &yy, &mm, &dd, - &hr, &mn, &sc, &nc ) == 6 ) && ( nc >= len ) ){ - ok = 1; - fsc = 0; - -/* Otherwise, check for the new format "ccyy-mm-ddThh:mm:ss.sssZ" with a - fractional seconds field and the trailing Z. */ - } else if( nc = 0, - ( astSscanf( dateobs, " %4d-%2d-%2dT%2d:%2d:%2d.%dZ %n", &yy, &mm, &dd, - &hr, &mn, &sc, &fsc, &nc ) == 7 ) && ( nc >= len ) ){ - ok = 1; - } - -/* If the supplied string was legal, create a MJD from the separate fields. */ - if( ok ) { - -/* Get the MJD at the start of the day. */ - palCaldj( yy, mm, dd, &ret, &j ); - -/* If succesful, convert the hours, minutes and seconds to a fraction of - a day, and add it onto the MJD found above. */ - if( j == 0 ) { - -/* Obtain a floating point representation of the fractional seconds - field. */ - secs = 0.0; - while ( fsc > 0 ) { - rem = ( fsc % 10 ); - fsc /= 10; - secs = 0.1 * ( secs + (double) rem ); - } - -/* Add on the whole seconds field. */ - secs += (double) sc; - -/*Convert the hours, minutes and seconds to a fractional day. */ - palDtf2d( hr, mn, secs, &days, &j ); - -/* If succesful, add this onto the returned MJD. */ - if( j == 0 ) { - ret = ret + days; - -/* If the conversion to MJD failed, return AST__BAD. */ - } else { - ret = AST__BAD; - } - } else { - ret = AST__BAD; - } - } - -/* Return the result. */ - return ret; -} - -static void DeleteCard( AstFitsChan *this, const char *method, - const char *class, int *status ){ -/* -* Name: -* DeleteCard - -* Purpose: -* Delete the current card from a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void DeleteCard( AstFitsChan *this, const char *method, -* const char *class ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The current card is removed from the circular linked list of structures -* stored in the supplied FitsChan, and the memory used to store the -* structure is then freed. - -* Parameters: -* this -* Pointer to the FitsChan containing the list. -* method -* Name of calling method. -* class -* Object class. - -* Notes: -* - This function returns without action if the FitsChan is -* currently at "end-of-file". -* - The next card becomes the current card. -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - FitsCard *card; /* Pointer to the current card */ - FitsCard *next; /* Pointer to next card in list */ - FitsCard *prev; /* Pointer to previous card in list */ - -/* Return if the supplied object or current card is NULL. */ - if( !this || !this->card ) return; - -/* Get a pointer to the card to be deleted (the current card). */ - card = (FitsCard *) this->card; - -/* Remove it from the KeyMap holding all keywords. */ - astMapRemove( this->keywords, card->name ); - -/* Move the current card on to the next card. */ - MoveCard( this, 1, method, class, status ); - -/* Save pointers to the previous and next cards in the list. */ - prev = GetLink( card, PREVIOUS, method, class, status ); - next = GetLink( card, NEXT, method, class, status ); - -/* If the backwards link points back to the supplied card, then it must - be the only one left on the list. */ - if( prev == card ) prev = NULL; - if( next == card ) next = NULL; - -/* If the list head is to be deleted, store a value for the new list - head. */ - if( this->head == (void *) card ) this->head = (void *) next; - -/* Free the memory used to hold the data value. */ - (void) astFree( card->data ); - -/* Free the memory used to hold any comment. */ - if( card->comment ) (void) astFree( (void *) card->comment ); - -/* Free the memory used to hold the whole structure. */ - (void) astFree( (void *) card ); - -/* Fix up the links between the two adjacent cards in the list, unless the - supplied card was the last one in the list. */ - if( prev && next ){ - next->prev = prev; - prev->next = next; - } else { - this->head = NULL; - this->card = NULL; - } - -/* Return. */ - return; -} - -static void DelFits( AstFitsChan *this, int *status ){ - -/* -*++ -* Name: -c astDelFits -f AST_DELFITS - -* Purpose: -* Delete the current FITS card in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" -c void astDelFits( AstFitsChan *this ) -f CALL AST_DELFITS( THIS, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function deletes the current FITS card from a FitsChan. The -f This routine deletes the current FITS card from a FitsChan. The -* current card may be selected using the Card attribute (if its index -c is known) or by using astFindFits (if only the FITS keyword is -f is known) or by using AST_FINDFITS (if only the FITS keyword is -* known). -* -* After deletion, the following card becomes the current card. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - This function returns without action if the FitsChan is -* initially positioned at the "end-of-file" (i.e. if the Card -* attribute exceeds the number of cards in the FitsChan). -* - If there are no subsequent cards in the FitsChan, then the -* Card attribute is left pointing at the "end-of-file" after -* deletion (i.e. is set to one more than the number of cards in -* the FitsChan). -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Delete the current card. The next card will be made the current card. */ - DeleteCard( this, "astDelFits", astGetClass( this ), status ); -} - -static void DistortMaps( AstFitsChan *this, FitsStore *store, char s, - int naxes, AstMapping **map1, AstMapping **map2, - AstMapping **map3, AstMapping **map4, - const char *method, const char *class, int *status ){ -/* -* Name: -* DistortMap - -* Purpose: -* Create a Mapping representing a FITS-WCS Paper IV distortion code. - -* Type: -* Private function. - -* Synopsis: -* void DistortMaps( AstFitsChan *this, FitsStore *store, char s, -* int naxes, AstMapping **map1, AstMapping **map2, -* AstMapping **map3, AstMapping **map4, -* const char *method, const char *class ) - -* Class Membership: -* FitsChan - -* Description: -* This function checks the CTYPE keywords in the supplied FitsStore to see -* if they contain a known distortion code (following the syntax described -* in FITS-WCS paper IV). If so, Mappings are returned which represent the -* distortions to be applied at each stage in the pixel->IWC chain. If -* any distortion codes are found in the FitsStore CTYPE values, whether -* recognised or not, the CTYPE values in the FitsStore are modified to -* remove the distortion code. Warnings about any unknown or inappropriate -* distortion codes are added to the FitsChan. - -* Parameters: -* this -* The FitsChan. ASTWARN cards may be added to this FitsChan if any -* anomalies are found in the keyword values in the FitsStore. -* store -* A structure containing information about the requested axis -* descriptions derived from a FITS header. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* naxes -* The number of intermediate world coordinate axes (WCSAXES). -* map1 -* Address of a location at which to store a pointer to a Mapping -* which describes any distortion to be applied to pixel -* coordinates, prior to performing the translation specified by the -* CRPIXj keywords. NULL is returned if no distortion is necessary. -* map2 -* Address of a location at which to store a pointer to a Mapping -* which describes any distortion to be applied to translated pixel -* coordinates, prior to performing the PC matrix multiplication. -* NULL is returned if no distortion is necessary. -* map3 -* Address of a location at which to store a pointer to a Mapping -* which describes any distortion to be applied to unscaled IWC -* coordinates, prior to performing the CDELT matrix multiplication. -* NULL is returned if no distortion is necessary. -* map4 -* Address of a location at which to store a pointer to a Mapping -* which describes any distortion to be applied to scaled IWC -* coordinates, after performing the CDELT matrix multiplication. -* NULL is returned if no distortion is necessary. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -*/ - -/* Local Variables: */ - AstMapping *tmap1; /* Mapping pointer */ - AstMapping *tmap2; /* Mapping pointer */ - char *ctype; /* Pointer to CTYPE value */ - char code[ 4 ]; /* Projection code extracted from CTYPE */ - char dist[ 4 ]; /* Distortion code extracted from CTYPE */ - char msgbuf[ 250 ]; /* Buffer for warning message */ - char type[ 5 ]; /* Axis type extracted from CTYPE */ - double *dim; /* Array holding array dimensions */ - int found_axes[ 2 ]; /* Index of axes with the distortion code */ - int i; /* FITS axis index */ - int nc; /* No. of characters in CTYPE without "-SIP" */ - int nfound; /* No. of axes with the distortion code */ - int warned; /* Have any ASTWARN cards been issued? */ - -/* Initialise pointers to the returned Mappings. */ - *map1 = NULL; - *map2 = NULL; - *map3 = NULL; - *map4 = NULL; - -/* Check the global status. */ - if ( !astOK ) return; - -/* Allocate memory to hold the image dimensions. */ - dim = (double *) astMalloc( sizeof(double)*naxes ); - if( dim ){ - -/* Note the image dimensions, if known. If not, store AST__BAD values. */ - for( i = 0; i < naxes; i++ ){ - if( !astGetFitsF( this, FormatKey( "NAXIS", i + 1, -1, ' ', status ), - dim + i ) ) dim[ i ] = AST__BAD; - } - -/* First check each known distortion type... */ - -/* "-SIP": Spitzer (http://irsa.ipac.caltech.edu/data/SPITZER/docs/files/spitzer/shupeADASS.pdf) - ============= */ - -/* Spitzer distortion is limited to 2D. Check the first two axes to see if - they have "-SIP" codes at the end of their CTYPE values. If they do, - terminate the ctype string in order to exclude the distortion code (this - is so that later functions do not need to allow for the possibility of a - distortion code being present in the CTYPE value). */ - ctype = GetItemC( &(store->ctype), 0, 0, s, NULL, method, class, status ); - if( ctype ){ - nc = astChrLen( ctype ) - 4; - if( nc >= 0 && !strcmp( ctype + nc, "-SIP" ) ) { - ctype[ nc ] = 0; - ctype = GetItemC( &(store->ctype), 1, 0, s, NULL, method, class, status ); - if( ctype ) { - nc = astChrLen( ctype ) - 4; - if( nc >= 0 && !strcmp( ctype + nc, "-SIP" ) ) { - ctype[ nc ] = 0; - -/* Create a Mapping describing the distortion (other axes are passed - unchanged by this Mapping), and add it in series with the returned map2 - (Spitzer distortion is applied to the translated pixel coordinates). */ - tmap1 = SIPMapping( this, dim, store, s, naxes, method, class, status ); - if( ! *map2 ) { - *map2 = tmap1; - } else { - tmap2 = (AstMapping *) astCmpMap( *map2, tmap1, 1, "", status ); - *map2 = astAnnul( *map2 ); - tmap1 = astAnnul( tmap1 ); - *map2 = tmap2; - } - } - } - } - } - -/* Check that the "-SIP" code is not included in any axes other than axes - 0 and 1. Issue a warning if it is, and remove it. */ - warned = 0; - for( i = 2; i < naxes; i++ ){ - ctype = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - if( ctype ){ - nc = astChrLen( ctype ) - 4; - if( nc >= 0 && !strcmp( ctype + nc, "-SIP" ) ) { - if( !warned ){ - warned = 1; - sprintf( msgbuf, "The \"-SIP\" distortion code can only be " - "used on axes 1 and 2, but was found in keyword " - "%s (='%s'). The distortion will be ignored.", - FormatKey( "CTYPE", i + 1, -1, ' ', status ), ctype ); - Warn( this, "distortion", msgbuf, method, class, status ); - } - ctype[ nc ] = 0; - } - } - } - -/* "-ZPX": IRAF (http://iraf.noao.edu/projects/ccdmosaic/zpx.html) - ============= */ - -/* An IRAF ZPX header uses a ZPX projection within each CTYPE value in place - of the basic ZPN projection. The SpecTrans function converts -ZPX" to - "-ZPN-ZPX" (i.e. a basic projection of ZPN with a distortion code of - "-ZPX"). This function then traps and processes the "-ZPX" distortion - code. */ - -/* Look for axes that have the "-ZPX" code in their CTYPE values. If any - are found, check that there are exactly two such axes, and terminate the - ctype strings in order to exclude the distortion code (this is so that - later functions do not need to allow for the possibility of a distortion - code being present in the CTYPE value)*/ - nfound = 0; - for( i = 0; i < naxes; i++ ){ - ctype = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - if( ctype && 3 == astSscanf( ctype, "%4s-%3s-%3s", type, code, dist ) ){ - if( !strcmp( "ZPX", dist ) ){ - if( nfound < 2 ) found_axes[ nfound ] = i; - nfound++; - ctype[ 8 ] = 0; - } - } - } - -/* Issue a warning if more than two ZPX axes were found. */ - if( nfound > 2 ) { - Warn( this, "distortion", "More than two axes were found " - "with the \"-ZPX\" projection code. A ZPN projection " - "will be used instead.", method, class, status ); - -/* Otherwise, create a Mapping describing the distortion (other axes are passed - unchanged by this Mapping), and add it in series with the returned map4 - (ZPX distortion is applied to the translated, rotated, scaled IWC - coordinates). */ - } else if( nfound == 2 ){ - tmap1 = ZPXMapping( this, store, s, naxes, found_axes, method, - class, status ); - if( ! *map4 ) { - *map4 = tmap1; - } else { - tmap2 = (AstMapping *) astCmpMap( *map4, tmap1, 1, "", status ); - *map4 = astAnnul( *map4 ); - tmap1 = astAnnul( tmap1 ); - *map4 = tmap2; - } - } - -/* (There are currently no other supported distortion codes.) */ - -/* Finally, check all axes looking for any remaining (and therefore - unsupported) distortion codes. Issue a warning about them and remove - them. - =================================================================== */ - -/* Indicate that we have not yet issued a warning. */ - warned = 0; - -/* Do each IWC axis. */ - for( i = 0; i < naxes; i++ ){ - -/* Get the CTYPE value for this axis. */ - ctype = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - if( ctype ) { - -/* See if has the "4-3-3" form described in FITS-WCS paper IV. */ - if( 3 == astSscanf( ctype, "%4s-%3s-%3s", type, code, dist ) ){ - -/* Add an ASTWARN card to the FitsChan. Only issue one warning (this avoids - multiple warnings about the same distortion code in multiple CTYPE values). */ - if( !warned ){ - warned = 1; - sprintf( msgbuf, "The header contains CTYPE values (e.g. " - "%s = '%s') which " - "include a distortion code \"-%s\". AST " - "currently ignores this distortion. The code " - "has been removed from the CTYPE values.", - FormatKey( "CTYPE", i + 1, -1, ' ', status ), ctype, dist ); - Warn( this, "distortion", msgbuf, method, class, status ); - } - -/* Terminate the CTYPE value in the FitsStore in order to exclude the distortion - code. This means that later functions will not need to take account of - distortion codes. */ - ctype[ 8 ] = 0; - } - } - } - } - -/* Free resources. */ - dim = astFree( dim ); -} - -static void DSBSetUp( AstFitsChan *this, FitsStore *store, - AstDSBSpecFrame *dsb, char s, double crval, - const char *method, const char *class, int *status ){ - -/* -* Name: -* DSBSetUp - -* Purpose: -* Modify an AstDSBSpecFrame object to reflect the contents of a FitsStore. - -* Type: -* Private function. - -* Synopsis: - -* void DSBSetUp( AstFitsChan *this, FitsStore *store, -* AstDSBSpecFrame *dsb, char s, double crval, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function sets the attributes of the supplied DSBSpecFrame to -* reflect the values in the supplied FitsStore. - -* Parameters: -* this -* The FitsChan. -* store -* A structure containing information about the requested axis -* descriptions derived from a FITS header. -* dsb -* Pointer to the DSBSpecFrame. -* s -* Alternate axis code. -* crval -* The spectral CRVAL value, in the spectral system represented by -* the supplied DSBSPecFrame. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This implementation follows the conventions of the FITS-CLASS encoding. -*/ - -/* Local Variables: */ - AstDSBSpecFrame *dsb_src; /* New DSBSpecFrame in which StdOfRest is source */ - AstDSBSpecFrame *dsb_topo;/* New DSBSpecFrame in which StdOfRest is topo */ - AstFrameSet *fs; /* FrameSet connecting two standards of rest */ - double dsbcentre; /* Topocentric reference (CRVAL) frequency */ - double in[2]; /* Source rest and image frequencies */ - double lo; /* Topocentric Local Oscillator frequency */ - double out[2]; /* Topocentric rest and image frequencies */ - -/* Check the global status. */ - if ( !astOK ) return; - -/* In order to determine the topocentric IF, we need the topocentric - frequencies corresponding to the RESTFREQ and IMAGFREQ values in the - FITS header. The values stored in the FITS header are measured in Hz, - in the source's rest frame, so we need a mapping from frequency in the - source rest frame to topocentric frequency. Take a copy of the supplied - DSBSpecFrame and then set its attributes to represent frequency in the - sources rest frame. */ - dsb_src = astCopy( dsb ); - astSetStdOfRest( dsb_src, AST__SCSOR ); - astSetSystem( dsb_src, AST__FREQ ); - astSetUnit( dsb_src, 0, "Hz" ); - -/* Take a copy of this DSBSpecFrame and set its standard of rest to - topocentric. */ - dsb_topo = astCopy( dsb_src ); - astSetStdOfRest( dsb_topo, AST__TPSOR ); - -/* Now get the Mapping between these. */ - fs = astConvert( dsb_src, dsb_topo, "" ); - dsb_src = astAnnul( dsb_src ); - dsb_topo = astAnnul( dsb_topo ); - -/* Check a conversion was found. */ - if( fs != NULL ) { - -/* Use this Mapping to transform the rest frequency and the image - frequency from the standard of rest of the source to that of the - observer. */ - in[ 0 ] = astGetRestFreq( dsb ); - in[ 1 ] = GetItem( &(store->imagfreq), 0, 0, s, NULL, method, class, status ); - astTran1( fs, 2, in, 1, out ); - -/* The intermediate frequency is half the distance between these two - frequencies. Note, the IF value is signed so as to put the rest - frequency in the observed sideband. */ - if( out[ 0 ] != AST__BAD && out[ 1 ] != AST__BAD ) { - -/* Store the spectral CRVAL value as the centre frequency of the - DSBSpecFrame. The public astSetD method interprets the supplied value - as a value in the spectral system described by the other SpecFrame - attributes. */ - astSetD( dsb, "DSBCentre", crval ); - -/* To calculate the topocentric IF we need the topocentric frequency - equivalent of CRVAL. So take a copy of the DSBSpecFrame, then set it to - represent topocentric frequency, and read back the DSBCentre value. */ - dsb_topo = astCopy( dsb ); - astSetStdOfRest( dsb_topo, AST__TPSOR ); - astSetSystem( dsb_topo, AST__FREQ ); - astSetUnit( dsb_topo, 0, "Hz" ); - dsbcentre = astGetD( dsb_topo, "DSBCentre" ); - dsb_topo = astAnnul( dsb_topo ); - -/* We also need the topocentric Local Oscillator frequency. This is - assumed to be half way between the topocentric IMAGFREQ and RESTFREQ - values. */ - lo = 0.5*( out[ 1 ] + out[ 0 ] ); - -/* Set the IF to be the difference between the Local Oscillator frequency - and the CRVAL frequency. */ - astSetIF( dsb, lo - dsbcentre ); - -/* Set the DSBSpecFrame to represent the observed sideband */ - astSetC( dsb, "SideBand", "observed" ); - } - -/* Free resources. */ - fs = astAnnul( fs ); - } -} - -static int DSSFromStore( AstFitsChan *this, FitsStore *store, - const char *method, const char *class, int *status ){ - -/* -* Name: -* DSSFromStore - -* Purpose: -* Store WCS keywords in a FitsChan using DSS encoding. - -* Type: -* Private function. - -* Synopsis: - -* int DSSFromStore( AstFitsChan *this, FitsStore *store, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function copies the WCS information stored in the supplied -* FitsStore into the supplied FitsChan, using DSS encoding. - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if succesfull, and zero is returned -* otherwise. -*/ - -/* Local Variables: */ - const char *comm; /* Pointer to comment string */ - char *cval; /* Pointer to string keyword value */ - const char *pltdecsn;/* PLTDECSN keyword value */ - double amdx[20]; /* AMDXi keyword value */ - double amdy[20]; /* AMDYi keyword value */ - double cdelt; /* CDELT element */ - double cnpix1; /* CNPIX1 keyword value */ - double cnpix2; /* CNPIX2 keyword value */ - double pc; /* PC element */ - double pltdecd; /* PLTDECD keyword value */ - double pltdecm; /* PLTDECM keyword value */ - double pltdecs; /* PLTDECS keyword value */ - double pltrah; /* PLTRAH keyword value */ - double pltram; /* PLTRAM keyword value */ - double pltras; /* PLTRAS keyword value */ - double pltscl; /* PLTSCL keyword value */ - double ppo1; /* PPO1 keyword value */ - double ppo2; /* PPO2 keyword value */ - double ppo3; /* PPO3 keyword value */ - double ppo4; /* PPO4 keyword value */ - double ppo5; /* PPO5 keyword value */ - double ppo6; /* PPO6 keyword value */ - double pvx[22]; /* X projection parameter values */ - double pvy[22]; /* Y projection parameter values */ - double val; /* General purpose value */ - double xpixelsz; /* XPIXELSZ keyword value */ - double ypixelsz; /* YPIXELSZ keyword value */ - int i; /* Loop count */ - int gottpn; /* Is the projection a "TPN" projection? */ - int m; /* Parameter index */ - int ret; /* Returned value. */ - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Check the image is 2 dimensional. */ - if( GetMaxJM( &(store->crpix), ' ', status ) != 1 ) return ret; - -/* Check the first axis is RA with a TAN or TPN projection. */ - cval = GetItemC( &(store->ctype), 0, 0, ' ', NULL, method, class, status ); - if( !cval ) return ret; - gottpn = !strcmp( "RA---TPN", cval ); - if( strcmp( "RA---TAN", cval ) && !gottpn ) return ret; - -/* Check the second axis is DEC with a TAN or TPN projection. */ - cval = GetItemC( &(store->ctype), 1, 0, ' ', NULL, method, class, status ); - if( !cval ) return ret; - if( gottpn ) { - if( strcmp( "DEC--TPN", cval ) ) return ret; - } else { - if( strcmp( "DEC--TAN", cval ) ) return ret; - } - -/* Check that LONPOLE is undefined or is 180 degrees. */ - val = GetItem( &(store->lonpole), 0, 0, ' ', NULL, method, class, status ); - if( val != AST__BAD && val != 180.0 ) return ret; - -/* Check that the RA/DEC system is FK5. */ - cval = GetItemC( &(store->radesys), 0, 0, ' ', NULL, method, class, status ); - if( !cval || strcmp( "FK5", cval ) ) return ret; - -/* Check that equinox is not defined or is 2000.0 */ - val = GetItem( &(store->equinox), 0, 0, ' ', NULL, method, class, status ); - if( val != AST__BAD && val != 2000.0 ) return ret; - -/* Get the pixel sizes from the PC/CDELT keywords. They must be defined and - not be zero. */ - cdelt = GetItem( &(store->cdelt), 0, 0, ' ', NULL, method, class, status ); - if( cdelt == AST__BAD ) return ret; - pc = GetItem( &(store->pc), 0, 0, ' ', NULL, method, class, status ); - if( pc == AST__BAD ) pc = 1.0; - xpixelsz = cdelt*pc; - cdelt = GetItem( &(store->cdelt), 1, 0, ' ', NULL, method, class, status ); - if( cdelt == AST__BAD ) return ret; - pc = GetItem( &(store->pc), 1, 1, ' ', NULL, method, class, status ); - if( pc == AST__BAD ) pc = 1.0; - ypixelsz = cdelt*pc; - if( xpixelsz == 0.0 || ypixelsz == 0.0 ) return ret; - xpixelsz *= -1000.0; - ypixelsz *= 1000.0; - -/* Check the off-diagonal PC terms are zero. DSS does not allow any rotation. */ - val = GetItem( &(store->pc), 0, 1, ' ', NULL, method, class, status ); - if( val != AST__BAD && val != 0.0 ) return ret; - val = GetItem( &(store->pc), 1, 0, ' ', NULL, method, class, status ); - if( val != AST__BAD && val != 0.0 ) return ret; - -/* Get the required projection parameter values from the store, supplying - appropriate values if a simple TAN projection is being used. */ - for( m = 0; m < 22; m++ ){ - pvx[ m ] = GetItem( &(store->pv), 0, m, ' ', NULL, method, class, status ); - if( pvx[ m ] == AST__BAD || !gottpn ) pvx[ m ] = ( m == 1 ) ? 1.0 : 0.0; - pvy[ m ] = GetItem( &(store->pv), 1, m, ' ', NULL, method, class, status ); - if( pvy[ m ] == AST__BAD || !gottpn ) pvy[ m ] = ( m == 1 ) ? 1.0 : 0.0; - } - -/* Check that no other projection parameters have been set. */ - if( GetMaxJM( &(store->pv), ' ', status ) > 21 ) return ret; - -/* Check that specific parameters take their required zero value. */ - if( pvx[ 3 ] != 0.0 || pvy[ 3 ] != 0.0 ) return ret; - for( m = 11; m < 17; m++ ){ - if( pvx[ m ] != 0.0 || pvy[ m ] != 0.0 ) return ret; - } - if( pvx[ 18 ] != 0.0 || pvy[ 18 ] != 0.0 ) return ret; - if( pvx[ 20 ] != 0.0 || pvy[ 20 ] != 0.0 ) return ret; - -/* Check that other projection parameters are related correctly. */ - if( !astEQUAL( 2*pvx[ 17 ], pvx[ 19 ] ) ) return ret; - if( !astEQUAL( pvx[ 17 ], pvx[ 21 ] ) ) return ret; - if( !astEQUAL( 2*pvy[ 17 ], pvy[ 19 ] ) ) return ret; - if( !astEQUAL( pvy[ 17 ], pvy[ 21 ] ) ) return ret; - -/* Initialise all polynomial co-efficients to zero. */ - for( m = 0; m < 20; m++ ){ - amdx[ m ] = 0.0; - amdy[ m ] = 0.0; - } - -/* Polynomial co-efficients. There is redundancy here too, so we - arbitrarily choose to leave AMDX/Y7 and AMDX/Y12 set to zero. */ - amdx[ 0 ] = 3600.0*pvx[ 1 ]; - amdx[ 1 ] = 3600.0*pvx[ 2 ]; - amdx[ 2 ] = 3600.0*pvx[ 0 ]; - amdx[ 3 ] = 3600.0*pvx[ 4 ]; - amdx[ 4 ] = 3600.0*pvx[ 5 ]; - amdx[ 5 ] = 3600.0*pvx[ 6 ]; - amdx[ 7 ] = 3600.0*pvx[ 7 ]; - amdx[ 8 ] = 3600.0*pvx[ 8 ]; - amdx[ 9 ] = 3600.0*pvx[ 9 ]; - amdx[ 10 ] = 3600.0*pvx[ 10 ]; - amdx[ 12 ] = 3600.0*pvx[ 17 ]; - amdy[ 0 ] = 3600.0*pvy[ 1 ]; - amdy[ 1 ] = 3600.0*pvy[ 2 ]; - amdy[ 2 ] = 3600.0*pvy[ 0 ]; - amdy[ 3 ] = 3600.0*pvy[ 4 ]; - amdy[ 4 ] = 3600.0*pvy[ 5 ]; - amdy[ 5 ] = 3600.0*pvy[ 6 ]; - amdy[ 7 ] = 3600.0*pvy[ 7 ]; - amdy[ 8 ] = 3600.0*pvy[ 8 ]; - amdy[ 9 ] = 3600.0*pvy[ 9 ]; - amdy[ 10 ] = 3600.0*pvy[ 10 ]; - amdy[ 12 ] = 3600.0*pvy[ 17 ]; - -/* The plate scale is the mean of the first X and Y co-efficients. */ - pltscl = 0.5*( amdx[ 0 ] + amdy[ 0 ] ); - -/* There is redundancy in the DSS encoding. We can choose an arbitrary - pixel corner (CNPIX1, CNPIX2) so long as we use the corresponding origin - for the cartesian co-ordinate system in which the plate centre is - specified (PPO3, PPO6). Arbitrarily set CNPIX1 and CNPIX2 to one. */ - cnpix1 = 1.0; - cnpix2 = 1.0; - -/* Find the corresponding plate centre PPO3 and PPO6 (other co-efficients - are set to zero). */ - ppo1 = 0.0; - ppo2 = 0.0; - val = GetItem( &(store->crpix), 0, 0, ' ', NULL, method, class, status ); - if( val == AST__BAD ) return ret; - ppo3 = xpixelsz*( val + cnpix1 - 0.5 ); - ppo4 = 0.0; - ppo5 = 0.0; - val = GetItem( &(store->crpix), 0, 1, ' ', NULL, method, class, status ); - if( val == AST__BAD ) return ret; - ppo6 = ypixelsz*( val + cnpix2 - 0.5 ); - -/* The reference RA. Get it in degrees. */ - val = GetItem( &(store->crval), 0, 0, ' ', NULL, method, class, status ); - if( val == AST__BAD ) return ret; - -/* Convert to hours and ensure it is in the range 0 to 24 */ - val /= 15.0; - while( val < 0 ) val += 24.0; - while( val >= 24.0 ) val -= 24.0; - -/* Split into hours, mins and seconds. */ - pltrah = (int) val; - val = 60.0*( val - pltrah ); - pltram = (int) val; - pltras = 60.0*( val - pltram ); - -/* The reference DEC. Get it in degrees. */ - val = GetItem( &(store->crval), 1, 0, ' ', NULL, method, class, status ); - if( val == AST__BAD ) return ret; - -/* Ensure it is in the range -180 to +180 */ - while( val < -180.0 ) val += 360.0; - while( val >= 180.0 ) val -= 360.0; - -/* Save the sign. */ - if( val > 0.0 ){ - pltdecsn = "+"; - } else { - pltdecsn = "-"; - val = -val; - } - -/* Split into degrees, mins and seconds. */ - pltdecd = (int) val; - val = 60.0*( val - pltdecd ); - pltdecm = (int) val; - pltdecs = 60.0*( val - pltdecm ); - -/* Store the DSS keywords in the FitsChan. */ - SetValue( this, "CNPIX1", &cnpix1, AST__FLOAT, "X corner (pixels)", status ); - SetValue( this, "CNPIX2", &cnpix2, AST__FLOAT, "Y corner (pixels)", status ); - SetValue( this, "PPO1", &ppo1, AST__FLOAT, "Orientation co-efficients", status ); - SetValue( this, "PPO2", &ppo2, AST__FLOAT, "", status ); - SetValue( this, "PPO3", &ppo3, AST__FLOAT, "", status ); - SetValue( this, "PPO4", &ppo4, AST__FLOAT, "", status ); - SetValue( this, "PPO5", &ppo5, AST__FLOAT, "", status ); - SetValue( this, "PPO6", &ppo6, AST__FLOAT, "", status ); - SetValue( this, "XPIXELSZ", &xpixelsz, AST__FLOAT, "X pixel size (microns)", status ); - SetValue( this, "YPIXELSZ", &ypixelsz, AST__FLOAT, "Y pixel size (microns)", status ); - SetValue( this, "PLTRAH", &pltrah, AST__FLOAT, "RA at plate centre", status ); - SetValue( this, "PLTRAM", &pltram, AST__FLOAT, "", status ); - SetValue( this, "PLTRAS", &pltras, AST__FLOAT, "", status ); - SetValue( this, "PLTDECD", &pltdecd, AST__FLOAT, "DEC at plate centre", status ); - SetValue( this, "PLTDECM", &pltdecm, AST__FLOAT, "", status ); - SetValue( this, "PLTDECS", &pltdecs, AST__FLOAT, "", status ); - SetValue( this, "PLTDECSN", &pltdecsn, AST__STRING, "", status ); - SetValue( this, "PLTSCALE", &pltscl, AST__FLOAT, "Plate scale (arcsec/mm)", status ); - comm = "Plate solution x co-efficients"; - for( i = 0; i < 20; i++ ){ - SetValue( this, FormatKey( "AMDX", i + 1, -1, ' ', status ), amdx + i, - AST__FLOAT, comm, status ); - comm = NULL; - } - comm = "Plate solution y co-efficients"; - for( i = 0; i < 20; i++ ){ - SetValue( this, FormatKey( "AMDY", i + 1, -1, ' ', status ), amdy + i, - AST__FLOAT, comm, status ); - comm = NULL; - } - -/* If no error has occurred, return one. */ - if( astOK ) ret = 1; - -/* Return the answer. */ - return ret; -} - -static void DSSToStore( AstFitsChan *this, FitsStore *store, - const char *method, const char *class, int *status ){ - -/* -* Name: -* DSSToStore - -* Purpose: -* Extract WCS information from the supplied FitsChan using a DSS -* encoding, and store it in the supplied FitsStore. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void DSSToStore( AstFitsChan *this, FitsStore *store, - const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function extracts DSS keywords from the supplied FitsChan, and -* stores the corresponding WCS information in the supplied FitsStore. -* The conversion from DSS encoding to standard WCS encoding is -* described in an ear;y draft of the Calabretta & Greisen paper -* "Representations of celestial coordinates in FITS" (A&A, in prep.), -* and uses the now deprecated "TAN with polynomial corrections", -* which is still supported by the WcsMap class as type AST__TPN. -* Here we use "lambda=1" (i.e. plate co-ordinate are measured in mm, -* not degrees). -* -* It is assumed that DSS images are 2 dimensional. - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore structure. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - char *text; /* Pointer to textual keyword value */ - char pltdecsn[11]; /* First 10 non-blank characters from PLTDECSN keyword */ - char keyname[10]; /* Buffer for keyword name */ - double amdx[20]; /* AMDXi keyword value */ - double amdy[20]; /* AMDYi keyword value */ - double cnpix1; /* CNPIX1 keyword value */ - double cnpix2; /* CNPIX2 keyword value */ - double crval2; /* Equivalent CRVAL2 keyword value */ - double dummy; /* Unused keyword value */ - double pltdecd; /* PLTDECD keyword value */ - double pltdecm; /* PLTDECM keyword value */ - double pltdecs; /* PLTDECS keyword value */ - double pltrah; /* PLTRAH keyword value */ - double pltram; /* PLTRAM keyword value */ - double pltras; /* PLTRAS keyword value */ - double ppo3; /* PPO3 keyword value */ - double ppo6; /* PPO6 keyword value */ - double pv; /* Projection parameter value */ - double xpixelsz; /* XPIXELSZ keyword value */ - double ypixelsz; /* YPIXELSZ keyword value */ - int i; /* Loop count */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Get the optional DSS keywords, supplying defaults for any missing keywords. */ - cnpix1 = 0.0; - cnpix2 = 0.0; - GetValue( this, "CNPIX1", AST__FLOAT, &cnpix1, 0, 1, method, class, status ); - GetValue( this, "CNPIX2", AST__FLOAT, &cnpix2, 0, 1, method, class, status ); - -/* Get the required DSS keywords. Report an error if any are missing. */ - GetValue( this, "PPO3", AST__FLOAT, &ppo3, 1, 1, method, class, status ); - GetValue( this, "PPO6", AST__FLOAT, &ppo6, 1, 1, method, class, status ); - GetValue( this, "XPIXELSZ", AST__FLOAT, &xpixelsz, 1, 1, method, class, status ); - GetValue( this, "YPIXELSZ", AST__FLOAT, &ypixelsz, 1, 1, method, class, status ); - GetValue( this, "PLTRAH", AST__FLOAT, &pltrah, 1, 1, method, class, status ); - GetValue( this, "PLTRAM", AST__FLOAT, &pltram, 1, 1, method, class, status ); - GetValue( this, "PLTRAS", AST__FLOAT, &pltras, 1, 1, method, class, status ); - GetValue( this, "PLTDECD", AST__FLOAT, &pltdecd, 1, 1, method, class, status ); - GetValue( this, "PLTDECM", AST__FLOAT, &pltdecm, 1, 1, method, class, status ); - GetValue( this, "PLTDECS", AST__FLOAT, &pltdecs, 1, 1, method, class, status ); - -/* Copy the first 10 non-blank characters from the PLTDECSN keyword. */ - GetValue( this, "PLTDECSN", AST__STRING, &text, 1, 1, method, class, status ); - if( astOK ) { - text += strspn( text, " " ); - text[ strcspn( text, " " ) ] = 0; - strncpy( pltdecsn, text, 10 ); - } - -/* Read other related keywords. We do not need these, but we read them - so that they are not propagated to any output FITS file. */ - GetValue( this, "PLTSCALE", AST__FLOAT, &dummy, 0, 1, method, class, status ); - GetValue( this, "PPO1", AST__FLOAT, &dummy, 0, 1, method, class, status ); - GetValue( this, "PPO2", AST__FLOAT, &dummy, 0, 1, method, class, status ); - GetValue( this, "PPO4", AST__FLOAT, &dummy, 0, 1, method, class, status ); - GetValue( this, "PPO5", AST__FLOAT, &dummy, 0, 1, method, class, status ); - -/* Get the polynomial co-efficients. These can be defaulted if they are - missing, so do not report an error. */ - for( i = 0; i < 20; i++ ){ - (void) sprintf( keyname, "AMDX%d", i + 1 ); - amdx[i] = AST__BAD; - GetValue( this, keyname, AST__FLOAT, amdx + i, 0, 1, method, class, status ); - (void) sprintf( keyname, "AMDY%d", i + 1 ); - amdy[i] = AST__BAD; - GetValue( this, keyname, AST__FLOAT, amdy + i, 0, 1, method, class, status ); - } - -/* Check the above went OK. */ - if( astOK ) { - -/* Calculate and store the equivalent PV projection parameters. */ - if( amdx[2] != AST__BAD ) { - pv = amdx[2]/3600.0; - SetItem( &(store->pv), 0, 0, ' ', pv, status ); - } - if( amdx[0] != AST__BAD ) { - pv = amdx[0]/3600.0; - SetItem( &(store->pv), 0, 1, ' ', pv, status ); - } - if( amdx[1] != AST__BAD ) { - pv = amdx[1]/3600.0; - SetItem( &(store->pv), 0, 2, ' ', pv, status ); - } - if( amdx[3] != AST__BAD && amdx[6] != AST__BAD ) { - pv = ( amdx[3] + amdx[6] )/3600.0; - SetItem( &(store->pv), 0, 4, ' ', pv, status ); - } - if( amdx[4] != AST__BAD ) { - pv = amdx[4]/3600.0; - SetItem( &(store->pv), 0, 5, ' ', pv, status ); - } - if( amdx[5] != AST__BAD && amdx[6] != AST__BAD ) { - pv = ( amdx[5] + amdx[6] )/3600.0; - SetItem( &(store->pv), 0, 6, ' ', pv, status ); - } - if( amdx[7] != AST__BAD && amdx[11] != AST__BAD ) { - pv = ( amdx[7] + amdx[11] )/3600.0; - SetItem( &(store->pv), 0, 7, ' ', pv, status ); - } - if( amdx[8] != AST__BAD ) { - pv = amdx[8]/3600.0; - SetItem( &(store->pv), 0, 8, ' ', pv, status ); - } - if( amdx[9] != AST__BAD && amdx[11] != AST__BAD ) { - pv = ( amdx[9] + amdx[11] )/3600.0; - SetItem( &(store->pv), 0, 9, ' ', pv, status ); - } - if( amdx[10] != AST__BAD ) { - pv = amdx[10]/3600.0; - SetItem( &(store->pv), 0, 10, ' ', pv, status ); - } - if( amdx[12] != AST__BAD ) { - pv = amdx[12]/3600.0; - SetItem( &(store->pv), 0, 17, ' ', pv, status ); - SetItem( &(store->pv), 0, 19, ' ', 2*pv, status ); - SetItem( &(store->pv), 0, 21, ' ', pv, status ); - } - if( amdy[2] != AST__BAD ) { - pv = amdy[2]/3600.0; - SetItem( &(store->pv), 1, 0, ' ', pv, status ); - } - if( amdy[0] != AST__BAD ) { - pv = amdy[0]/3600.0; - SetItem( &(store->pv), 1, 1, ' ', pv, status ); - } - if( amdy[1] != AST__BAD ) { - pv = amdy[1]/3600.0; - SetItem( &(store->pv), 1, 2, ' ', pv, status ); - } - if( amdy[3] != AST__BAD && amdy[6] != AST__BAD ) { - pv = ( amdy[3] + amdy[6] )/3600.0; - SetItem( &(store->pv), 1, 4, ' ', pv, status ); - } - if( amdy[4] != AST__BAD ) { - pv = amdy[4]/3600.0; - SetItem( &(store->pv), 1, 5, ' ', pv, status ); - } - if( amdy[5] != AST__BAD && amdy[6] != AST__BAD ) { - pv = ( amdy[5] + amdy[6] )/3600.0; - SetItem( &(store->pv), 1, 6, ' ', pv, status ); - } - if( amdy[7] != AST__BAD && amdy[11] != AST__BAD ) { - pv = ( amdy[7] + amdy[11] )/3600.0; - SetItem( &(store->pv), 1, 7, ' ', pv, status ); - } - if( amdy[8] != AST__BAD ) { - pv = amdy[8]/3600.0; - SetItem( &(store->pv), 1, 8, ' ', pv, status ); - } - if( amdy[9] != AST__BAD && amdy[11] != AST__BAD ) { - pv = ( amdy[9] + amdy[11] )/3600.0; - SetItem( &(store->pv), 1, 9, ' ', pv, status ); - } - if( amdy[10] != AST__BAD ) { - pv = amdy[10]/3600.0; - SetItem( &(store->pv), 1, 10, ' ', pv, status ); - } - if( amdy[12] != AST__BAD ) { - pv = amdy[12]/3600.0; - SetItem( &(store->pv), 1, 17, ' ', pv, status ); - SetItem( &(store->pv), 1, 19, ' ', 2*pv, status ); - SetItem( &(store->pv), 1, 21, ' ', pv, status ); - } - -/* Calculate and store the equivalent CRPIX values. */ - if( xpixelsz != 0.0 ) { - SetItem( &(store->crpix), 0, 0, ' ', - ( ppo3/xpixelsz ) - cnpix1 + 0.5, status ); - } else if( astOK ){ - astError( AST__BDFTS, "%s(%s): FITS keyword XPIXELSZ has illegal " - "value 0.0", status, method, class ); - } - if( ypixelsz != 0.0 ) { - SetItem( &(store->crpix), 0, 1, ' ', - ( ppo6/ypixelsz ) - cnpix2 + 0.5, status ); - } else if( astOK ){ - astError( AST__BDFTS, "%s(%s): FITS keyword YPIXELSZ has illegal " - "value 0.0", status, method, class ); - } - -/* Calculate and store the equivalent CRVAL values. */ - SetItem( &(store->crval), 0, 0, ' ', - 15.0*( pltrah + pltram/60.0 + pltras/3600.0 ), status ); - crval2 = pltdecd + pltdecm/60.0 + pltdecs/3600.0; - if( !strcmp( pltdecsn, "-") ) crval2 = -crval2; - SetItem( &(store->crval), 1, 0, ' ', crval2, status ); - -/* Calculate and store the equivalent PC matrix. */ - SetItem( &(store->pc), 0, 0, ' ', -0.001*xpixelsz, status ); - SetItem( &(store->pc), 1, 1, ' ', 0.001*ypixelsz, status ); - -/* Set values of 1.0 for the CDELT values. */ - SetItem( &(store->cdelt), 0, 0, ' ', 1.0, status ); - SetItem( &(store->cdelt), 1, 0, ' ', 1.0, status ); - -/* Store remaining constant items */ - SetItem( &(store->lonpole), 0, 0, ' ', 180.0, status ); - SetItem( &(store->equinox), 0, 0, ' ', 2000.0, status ); - SetItemC( &(store->radesys), 0, 0, ' ', "FK5", status ); - SetItem( &(store->wcsaxes), 0, 0, ' ', 2.0, status ); - store->naxis = 2; - SetItemC( &(store->ctype), 0, 0, ' ', "RA---TPN", status ); - SetItemC( &(store->ctype), 1, 0, ' ', "DEC--TPN", status ); - } -} - -static void EmptyFits( AstFitsChan *this, int *status ){ - -/* -*++ -* Name: -c astEmptyFits -f AST_EMPTYFITS - -* Purpose: -* Delete all cards in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" -c void astEmptyFits( AstFitsChan *this ) -f CALL AST_EMPTYFITS( THIS, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* deletes all cards and associated information from a FitsChan. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - This method simply deletes the cards currently in the FitsChan. -c Unlike astWriteFits, -f Unlike AST_WRITEFITS, -* they are not first written out to the sink function or sink file. -* - Any Tables or warnings stored in the FitsChan are also deleted. -* - This method attempt to execute even if an error has occurred -* previously. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *class; /* Pointer to string holding object class */ - const char *method; /* Pointer to string holding calling method */ - int old_ignore_used; /* Original setting of ignore_used variable */ - -/* Check a FitsChan was supplied. */ - if( !this ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Store the method and class strings. */ - method = "astEmpty"; - class = astGetClass( this ); - -/* Delete all cards from the circular linked list stored in the FitsChan, - starting with the card at the head of the list. */ - old_ignore_used = ignore_used; - ignore_used = 0; - astClearCard( this ); - while( !astFitsEof( this ) ) DeleteCard( this, method, class, status ); - ignore_used = old_ignore_used; - -/* Delete the KeyMap which holds keywords and the latest sequence number - used by each of them. */ - if( this->keyseq ) this->keyseq = astAnnul( this->keyseq ); - -/* Delete the KeyMap holding the keyword names. */ - if( this->keywords ) this->keywords = astAnnul( this->keywords ); - -/* Free any memory used to hold the Warnings attribute value. */ - this->warnings = astFree( this->warnings ); - -/* Other objects in the FitsChan structure. */ - if( this->tables ) this->tables = astAnnul( this->tables ); -} - -static int EncodeFloat( char *buf, int digits, int width, int maxwidth, - double value, int *status ){ -/* -* -* Name: -* EncodeFloat - -* Purpose: -* Formats a floating point value. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int EncodeFloat( char *buf, int digits, int width, int maxwidth, -* double value, int *status ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function formats the value using a G format specified in order -* to use the minimum field width (trailing zeros are not printed). -* However, the G specifier does not include a decimal point unless it -* is necessary. FITS requires that floating point values always include -* a decimal point, so this function inserts one, if necessary. - -* Parameters: -* buf -* A character string into which the value is written. -* digits -* The number of digits after the decimal point. If the supplied value -* is negative, the number of digits actually used may be reduced if -* the string would otherwise extend beyond the number of columns -* allowed by the FITS standard. If the value is positive, the -* specified number of digits are always produced, even if it means -* breaking the FITS standard. -* width -* The minimum field width to use. The value is right justified in -* this field width. -* maxwidth -* The maximum field width to use. A value of zero is returned if -* the maximum field width is exceeded. -* value -* The value to format. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The field width actually used, or zero if the value could not be -* formatted. This does not include the trailing null character. - -* Notes: -* - If there is room, a trailing zero is also added following the -* inserted decimal point. -*/ - -/* Local Variables: */ - char *c; - char *w, *r; - int i; - int ldigits; - int n; - int ret; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* The supplied value of "digits" may be negative. Obtain the positive - value giving the initial number of decimal digits to use. */ - ldigits = ( digits > 0 ) ? digits : -digits; - -/* Loop until a suitably encoded value has been obtained. */ - while( 1 ){ - -/* Write the value into the buffer. Most are formatted with a G specifier. - This will result in values between -0.001 and -0.0001 being formatted - without an exponent, and thus occupying (ldigits+6) characters. With - an exponent, these values would be formatted in (ldigits+5) characters - thus saving one character. This is important because the default value - of ldigits is 15, resulting in 21 characters being used by the G - specifier. This is one more than the maximum allowed by the FITS - standard. Using an exponent instead would result in 20 characters - being used without any loss of precision, thus staying within the FITS - limit. Note, the precision used with the E specifier is one less than - with the G specifier because the digit to the left of the decimal place - is significant with the E specifier, and so we only need (ldigits-1) - significant digits to the right of the decimal point. */ - if( value > -0.001 && value < -0.0001 ) { - (void) sprintf( buf, "%*.*E", width, ldigits - 1, value ); - } else { - (void) sprintf( buf, "%*.*G", width, ldigits, value ); - } - -/* Check that the value zero is not encoded with a minus sign (e.g. "-0."). - This also rounds out long sequences of zeros or nines. */ - CheckZero( buf, value, width, status ); - -/* If the formatted value includes an exponent, it will have 2 digits. - If the exponent includes a leading zero, remove it. */ - if( ( w = strstr( buf, "E-0" ) ) ) { - w += 2; - } else if( ( w = strstr( buf, "E+0" ) ) ){ - w += 2; - } else if( ( w = strstr( buf, "E0" ) ) ){ - w += 1; - } - -/* If a leading zero was found, shuffle everything down from the start of - the string by one character, over-writing the redundant zero, and insert - a space at the start of the string. */ - if( w ) { - r = w - 1 ; - while( w != buf ) *(w--) = *(r--); - *w = ' '; - } - -/* If the used field width was too large, reduce it and try again, so - long as we are allowed to change the number of digits being used. */ - ret = strlen( buf ); - if( ret > width && digits < 0 ){ - ldigits -= ( ret - width ); - -/* Otherwise leave the loop. Return zero field width if the maximum field - width was exceeded. */ - } else { - if( ret > maxwidth ) ret = 0; - break; - } - } - -/* If a formatted value was obtained, we need to ensure that the it includes - a decimal point. */ - if( ret ){ - -/* Get a pointer to the first digit in the buffer. */ - c = strpbrk( buf, "0123456789" ); - -/* Something funny is going on if there are no digits in the buffer, - so return a zero field width. */ - if( !c ){ - ret = 0; - -/* Otherwise... */ - } else { - -/* Find the number of digits following and including the first digit. */ - n = strspn( c, "0123456789" ); - -/* If the first non-digit character is a decimal point, do nothing. */ - if( c[ n ] != '.' ){ - -/* If there are two or more leading spaces, move the start of the string - two character to the left, and insert ".0" in the gap created. This - keeps the field right justified within the desired field width. */ - if( buf[ 0 ] == ' ' && buf[ 1 ] == ' ' ){ - for( i = 2; i < c - buf + n; i++ ) buf[ i - 2 ] = buf[ i ]; - c[ n - 2 ] = '.'; - c[ n - 1 ] = '0'; - -/* If there is just one leading space, move the start of the string - one character to the left, and insert "." in the gap created. This - keeps the field right justified within the desired field width. */ - } else if( buf[ 0 ] == ' ' ){ - for( i = 0; i < n; i++ ) c[ i - 1 ] = c[ i ]; - c[ n - 1 ] = '.'; - -/* If there are no leading spaces we need to move the end of the string - to the right. This will result in the string no longer being right - justified in the required field width. Return zero if there is - insufficient room for an extra character. */ - } else { - ret++; - if( ret > maxwidth ){ - ret = 0; - -/* Otherwise, more the end of the string one place to the right and insert - the decimal point. */ - } else { - for( i = strlen( c ); i >= n; i-- ) c[ i + 1 ] = c[ i ]; - c[ n ] = '.'; - } - } - } - } - } - -/* Return the field width. */ - return ret; -} - -static int EncodeValue( AstFitsChan *this, char *buf, int col, int digits, - const char *method, int *status ){ - -/* -* Name: -* EncodeValue - -* Purpose: -* Encode the current card's keyword value into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int EncodeValue( AstFitsChan *this, char *buf, int col, int digits, -* const char *method, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function encodes the keyword value defined in the current card -* of the supplied FitsChan and stores it at the start of the supplied -* buffer. The number of characters placed in the buffer is returned -* (not including a terminating null). - -* Parameters: -* this -* Pointer to the FitsChan. -* buf -* The buffer to receive the formatted value. This should be at least -* 70 characters long. -* col -* The column number within the FITS header card corresponding to the -* start of "buf". -* digits -* The number of digits to use when formatting floating point -* values. If the supplied value is negative, the number of digits -* actually used may be reduced if the string would otherwise extend -* beyond the number of columns allowed by the FITS standard. If the -* value is positive, the specified number of digits are always -* produced, even if it means breaking the FITS standard. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of columns used by the encoded value. - -* Notes: -* - The function returns 0 if an error has already occurred -* or if an error occurs for any reason within this function. -*/ - -/* Local Variables: */ - char *c; /* Pointer to next character */ - char *name; /* Pointer to the keyword name */ - double dval; /* Keyword value */ - void *data; /* Pointer to keyword value */ - int i; /* Loop count */ - int ilen; /* Length of imaginary part */ - int len; /* Returned length */ - int quote; /* Quote character found? */ - int rlen; /* Length of real part */ - int type; /* Data type for keyword in current card */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise returned length. */ - len = 0; - -/* Get the data type of the keyword. */ - type = CardType( this, status ); - -/* Get a pointer to the data value in the current card. */ - data = CardData( this, NULL, status ); - -/* Return if there is no defined value associated with the keyword in the - current card. */ - if( type != AST__UNDEF ) { - -/* Get the name of the keyword. */ - name = CardName( this, status ); - -/* Go through each supported data type (roughly in the order of - decreasing usage)... */ - -/* AST__FLOAT - stored internally in a variable of type "double". Right - justified to column 30 in the header card. */ - if( type == AST__FLOAT ){ - dval = *( (double *) data ); - len = EncodeFloat( buf, digits, FITSRLCOL - FITSNAMLEN - 2, - AST__FITSCHAN_FITSCARDLEN - col + 1, dval, status ); - if( len <= 0 && astOK ) { - astError( AST__BDFTS, "%s(%s): Cannot encode floating point value " - "%g into a FITS header card for keyword '%s'.", status, method, - astGetClass( this ), dval, name ); - } - -/* AST__STRING & AST__CONTINUE - stored internally in a null terminated array of - type "char". The encoded string is enclosed in single quotes, starting - at FITS column 11 and ending in at least column 20. Single quotes - in the string are replaced by two adjacent single quotes. */ - } else if( type == AST__STRING || type == AST__CONTINUE ){ - c = (char *) data; - -/* Enter the opening quote. */ - len = 0; - buf[ len++ ] = '\''; - -/* Inspect each character, looking for quotes. */ - for ( i = 0; c[ i ]; ) { - quote = ( c[ i ] == '\'' ); - -/* If it will not fit into the header card (allowing for doubled - quotes), give up here. */ - if ( len + ( quote ? 2 : 1 ) > AST__FITSCHAN_FITSCARDLEN - col ) break; - -/* Otherwise, copy it into the output buffer and double any quotes. */ - buf[ len++ ] = c[ i ]; - if ( quote ) buf[ len++ ] = '\''; - -/* Look at the next character. */ - i++; - } - -/* Pad the string out to the required minimum length with blanks and - add the final quote. */ - while( len < FITSSTCOL - col ) buf[ len++ ] = ' '; - buf[ len++ ] = '\''; - -/* Inspect any characters that weren't used. If any are non-blank, - report an error. */ - for ( ; c[ i ]; i++ ) { - if ( !isspace( c[ i ] ) ) { - astError( AST__BDFTS, - "%s(%s): Cannot encode string '%s' into a FITS " - "header card for keyword '%s'.", status, method, astGetClass( this ), - (char *) data, name ); - break; - } - } - -/* INTEGER - stored internally in a variable of type "int". Right justified - to column 30 in the header card. */ - } else if( type == AST__INT ){ - len = sprintf( buf, "%*d", FITSRLCOL - col + 1, - *( (int *) data ) ); - if( len < 0 || len > AST__FITSCHAN_FITSCARDLEN - col ) { - astError( AST__BDFTS, "%s(%s): Cannot encode integer value %d into a " - "FITS header card for keyword '%s'.", status, method, astGetClass( this ), - *( (int *) data ), name ); - } - -/* LOGICAL - stored internally in a variable of type "int". Represented by - a "T" or "F" in column 30 of the FITS header card. */ - } else if( type == AST__LOGICAL ){ - for( i = 0; i < FITSRLCOL - col; i++ ) buf[ i ] = ' '; - if( *( (int *) data ) ){ - buf[ FITSRLCOL - col ] = 'T'; - } else { - buf[ FITSRLCOL - col ] = 'F'; - } - len = FITSRLCOL - col + 1; - -/* AST__COMPLEXF - stored internally in an array of two "doubles". The real - part is right justified to FITS column 30. The imaginary part is right - justified to FITS column 50. */ - } else if( type == AST__COMPLEXF ){ - dval = ( (double *) data )[ 0 ]; - rlen = EncodeFloat( buf, digits, FITSRLCOL - FITSNAMLEN - 2, - AST__FITSCHAN_FITSCARDLEN - col + 1, dval, status ); - if( rlen <= 0 || rlen > AST__FITSCHAN_FITSCARDLEN - col ) { - astError( AST__BDFTS, "%s(%s): Cannot encode real part of a complex " - "floating point value [%g,%g] into a FITS header card " - "for keyword '%s'.", status, method, astGetClass( this ), dval, - ( (double *) data )[ 1 ], name ); - } else { - dval = ( (double *) data )[ 1 ]; - ilen = EncodeFloat( buf + rlen, digits, - FITSIMCOL - FITSRLCOL, - AST__FITSCHAN_FITSCARDLEN - col - rlen, dval, status ); - if( ilen <= 0 ) { - astError( AST__BDFTS, "%s(%s): Cannot encode imaginary part of a " - "complex floating point value [%g,%g] into a FITS header " - "card for keyword '%s'.", status, method, astGetClass( this ), - ( (double *) data )[ 0 ], dval, name ); - } else { - len = ilen + rlen; - } - } - -/* AST__COMPLEXI - stored internally in a an array of two "ints". */ - } else if( type == AST__COMPLEXI ){ - rlen = sprintf( buf, "%*d", FITSRLCOL - col + 1, - ( (int *) data )[ 0 ] ); - if( rlen < 0 || rlen > AST__FITSCHAN_FITSCARDLEN - col ) { - astError( AST__BDFTS, "%s(%s): Cannot encode real part of a complex " - "integer value [%d,%d] into a FITS header card " - "for keyword '%s'.", status, method, astGetClass( this ), - ( (int *) data )[ 0 ], - ( (int *) data )[ 1 ], name ); - } else { - ilen = sprintf( buf + rlen, "%*d", FITSIMCOL - FITSRLCOL + 1, - ( (int *) data )[ 1 ] ); - if( ilen < 0 || ilen > AST__FITSCHAN_FITSCARDLEN - col - rlen ) { - astError( AST__BDFTS, "%s(%s): Cannot encode imaginary part of a " - "complex integer value [%d,%d] into a FITS header card " - "for keyword '%s'.", status, method, astGetClass( this ), - ( (int *) data )[ 0 ], - ( (int *) data )[ 1 ], name ); - } else { - len = ilen + rlen; - } - } - -/* Report an internal (ast) programming error if the keyword is of none of the - above types. */ - } else if( astOK ){ - astError( AST__INTER, "EncodeValue: AST internal programming error - " - "FITS %s data-type not yet supported.", status, - type_names[ type ] ); - } - } - -/* If an error has occurred, return zero length. */ - if( !astOK ) len = 0; - -/* Return the answer. */ - return len; -} - -static AstGrismMap *ExtractGrismMap( AstMapping *map, int iax, - AstMapping **new_map, int *status ){ -/* -* Name: -* ExtractGrismMap - -* Purpose: -* Extract a GrismMap from the end of the supplied Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstGrismMap *ExtractGrismMap( AstMapping *map, int iax, -* AstMapping **new_map, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function examines the supplied Mapping; if the specified output -* coordinate of the Mapping is created directly by an un-inverted GrismMap, -* then a pointer to the GrismMap is returned as the function value. A new -* Mapping is also returned via parameter "new_map" which is a copy of -* the supplied Mapping, except that the GrismMap is replaced with a -* UnitMap. If no GrismMap is found, NULL is returned for both Mappings. -* The condition that "the specified output coordinate of the Mapping is -* created directly by an un-inverted GrismMap" means that the output -* of the GrismMap is no subsequently modified by any further Mappings -* before being returned as the "iax"th output of the supplied Mapping. -* This means the GrismMap must be "at the end of" a CmpMap, not in -* the middle of the CmpMap. - -* Parameters: -* map -* Pointer to the Mapping to check. -* iax -* The index for the output coordinate to be checked. -* new_map -* Pointer to a location at which to return a pointer to a new -* Mapping which is a copy of "map" except that the GrismMap is -* replaced by a UnitMap. NULL is returned if the specified output -* was not created by a GrismMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The extracted GrismMap, or NULL if the specified output was not -* created by a GrismMap. -*/ - -/* Local Variables: */ - AstMapping *mapa; /* First component Mapping */ - AstMapping *mapb; /* Second component Mapping */ - AstMapping *new_mapa; /* Replacement for first component Mapping */ - AstMapping *new_mapb; /* Replacement for second component Mapping */ - AstGrismMap *ret; /* Returned GrismMap */ - int inva; /* Invert attribute for mapa within the CmpMap */ - int invb; /* Invert attribute for mapb within the CmpMap */ - int na; /* Number of outputs for mapa */ - int old_inva; /* Current Invert attribute for mapa */ - int old_invb; /* Current Invert attribute for mapb */ - int series; /* Are component Mappings applied in series? */ - -/* Initialise */ - ret = NULL; - *new_map = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* If the supplied Mapping is a GrismMap which has not been inverted, - return it as the function value and return a UnitMap as the new - Mapping. */ - if( astIsAGrismMap( map ) ) { - if( !astGetInvert( map ) ) { - ret = astClone( map ); - *new_map = (AstMapping *) astUnitMap( 1, "", status ); - } - -/* If the supplied Mapping is a CmpMap, get its two component Mappings, - see if they are applied in parallel or series, and get the Invert - attribute values which the component Mappings had at the time the - CmpMap was created. */ - } else if( astIsACmpMap( map ) ) { - astDecompose( map, &mapa, &mapb, &series, &inva, &invb ); - -/* Temporaily reset the Invert attributes of the component Mappings back to - the values they had when the CmpMap was created. */ - old_inva = astGetInvert( mapa ); - old_invb = astGetInvert( mapb ); - astSetInvert( mapa, inva ); - astSetInvert( mapb, invb ); - -/* If the supplied Mapping is a series CmpMap, attempt to extract a - GrismMap from the second component Mapping ("mapb"). The first - component Mapping ("mapa") is unchanged. We do not need to consdier - the first component since we are only interested in GrismMaps which are - at the end of the CmpMap. */ - if( series ) { - ret = ExtractGrismMap( mapb, iax, &new_mapb, status ); - if( ret ) new_mapa = astClone( mapa ); - -/* If the supplied Mapping is a parallel CmpMap, attempt to extract a - GrismMap from the component Mapping which produces output "iax". The - other component Mapping is unchanged. */ - } else { - na = astGetNout( mapa ); - if( iax < na ) { - ret = ExtractGrismMap( mapa, iax, &new_mapa, status ); - if( ret ) new_mapb = astClone( mapb ); - } else { - ret = ExtractGrismMap( mapb, iax - na, &new_mapb, status ); - if( ret ) new_mapa = astClone( mapa ); - } - } - -/* If succesful, create a new CmpMap to return. */ - if( ret ) { - *new_map = (AstMapping *) astCmpMap( new_mapa, new_mapb, series, "", status ); - new_mapa = astAnnul( new_mapa ); - new_mapb = astAnnul( new_mapb ); - } - -/* Re-instate the original Invert attributes of the component Mappings. */ - astSetInvert( mapa, old_inva ); - astSetInvert( mapb, old_invb ); - -/* Annul the component Mapping pointers. */ - mapa = astAnnul( mapa ); - mapb = astAnnul( mapb ); - } - -/* Return the result. */ - return ret; -} - -static int MakeBasisVectors( AstMapping *map, int nin, int nout, - double *g0, AstPointSet *psetg, - AstPointSet *psetw, int *status ){ -/* -* Name: -* MakeBasisVectors - -* Purpose: -* Create a set of basis vectors in grid coordinates - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int MakeBasisVectors( AstMapping *map, int nin, int nout, -* double *g0, AstPointSet *psetg, -* AstPointSet *psetw, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns a set of unit vectors in grid coordinates, -* one for each grid axis. Each unit vector is parallel to the -* corresponding grid axis, and rooted at a specified grid position -* ("g0"). The IWC coordinates corresponding to "g0" and to the end of -* each of the unit vectors are also returned, together with a flag -* indicating if all the IWC coordinate values are good. - -* Parameters: -* map -* A pointer to a Mapping which transforms grid coordinates into -* intermediate world coordinates (IWC). The number of outputs must -* be greater than or equal to the number of inputs. -* nin -* The number of inputs for "map" (i.e. the number of grid axes). -* nout -* The number of outputs for "map" (i.e. the number of IWC axes). -* g0 -* Pointer to an array of holding the grid coordinates at the -* "root" position. -* psetg -* A pointer to a PointSet which can be used to hold the required -* grid positions. This should have room for nin+1 positions. On -* return, the first position holds "g0", and the subsequent "nin" -* positions hold are offset from "g0" by unit vectors along the -* corresponding grid axis. -* psetw -* A pointer to a PointSet which can be used to hold the required -* IWC position. This should also have room for nin+1 positions. On -* return, the values are the IWC coordinates corresponding to the -* grid positions returned in "psetg". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if all the axis values in "psetw" are good. -* Zero is returned otherwise. - -* Notes: -* - Zero is returned if an error occurs. -*/ - -/* Local Variables: */ - double **ptrg; - double **ptrw; - double *c; - int i; - int ii; - int j; - int ret; - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Get pointers to the data in the two supplied PointSets. */ - ptrg = astGetPoints( psetg ); - ptrw = astGetPoints( psetw ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Assume success. */ - ret = 1; - -/* Store the required grid positions in PointSet "pset1". The first - position is the supplied root grid position, g0. The next "nin" - positions are offset from the root position by a unit vector along - each grid axis in turn. Store values for each grid axis in turn. */ - for( i = 0; i < nin; i++ ) { - -/* Get a pointer to the first axis value for this grid axis. */ - c = ptrg[ i ]; - -/* Initially set all values for this axis to the supplied root grid value. */ - for( ii = 0; ii < nin + 1; ii++ ) c[ ii ] = g0[ i ]; - -/* Modify the value corresponding to the vector along this grid axis. */ - c[ i + 1 ] += 1.0; - } - -/* Transform these grid positions in IWC positions using the supplied - Mapping. */ - (void) astTransform( map, psetg, 1, psetw ); - -/* Check that all the transformed positions are good. */ - for( j = 0; j < nout; j++ ) { - c = ptrw[ j ]; - for( ii = 0; ii < nin + 1; ii++, c++ ) { - if( *c == AST__BAD ) { - ret = 0; - break; - } - } - } - } - -/* Return the result. */ - return ret; -} - -static int FindBasisVectors( AstMapping *map, int nin, int nout, - double *dim, AstPointSet *psetg, - AstPointSet *psetw, int *status ){ -/* -* Name: -* FindBasisVectors - -* Purpose: -* Find the a set of basis vectors in grid coordinates - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int FindBasisVectors( AstMapping *map, int nin, int nout, -* double *dim, AstPointSet *psetg, -* AstPointSet *psetw, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns a set of unit vectors in grid coordinates, -* one for each grid axis. Each unit vector is parallel to the -* corresponding grid axis, and rooted at a specified grid position -* ("g0"). The IWC coordinates corresponding to "g0" and to the end of -* each of the unit vectors are also returned, together with a flag -* indicating if all the IWC coordinate values are good. - -* Parameters: -* map -* A pointer to a Mapping which transforms grid coordinates into -* intermediate world coordinates (IWC). The number of outputs must -* be greater than or equal to the number of inputs. -* nin -* The number of inputs for "map" (i.e. the number of grid axes). -* nout -* The number of outputs for "map" (i.e. the number of IWC axes). -* dim -* Array dimensions, in pixels, if known (otherwise supplied a NULL -* pointer to values of AST__BAD). -* psetg -* A pointer to a PointSet which can be used to hold the required -* grid position. This should have room for nin+1 positions. On -* return, the first position holds the "root" position and the -* subsequent "nin" positions hold are offset from root position -* by unit vectors along the corresponding grid axis. -* psetw -* A pointer to a PointSet which can be used to hold the required -* IWC position. This should also have room for nin+1 positions. On -* return, the values are the IWC coordinates corresponding to the -* grid positions returned in "psetg". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if a set of basis vectors was found -* succesfully. Zero is returned otherwise. - -* Notes: -* - Zero is returned if an error occurs. -*/ - -/* Local Variables: */ - double *g0; - double dd; - double ddlim; - int i; - int ii; - int ret; - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Allocate an array to store the candidate root position. */ - g0 = astMalloc( sizeof( double )*(size_t) nin ); - if( astOK ) { - -/* First try the grid centre, if known. */ - ddlim = 0; - ret = 0; - if( dim ) { - ret = 1; - for( i = 0; i < nin; i++ ) { - if( dim[ i ] != AST__BAD ) { - g0[ i ] = 0.5*( 1 + dim[ i ] ); - if( dim[ i ] > ddlim ) ddlim = dim[ i ]; - } else { - ret = 0; - break; - } - } - } - if( ret ) ret = MakeBasisVectors( map, nin, nout, g0, psetg, psetw, status ); - -/* If this did not produce a set of good IWC positions, try grid position - (1,1,1...). */ - if( !ret ) { - for( i = 0; i < nin; i++ ) g0[ i ] = 1.0; - ret = MakeBasisVectors( map, nin, nout, g0, psetg, psetw, status ); - } - -/* If this did not produce a set of good IWC positions, try a sequence of - grid positions which move an increasing distance along each grid axis - from (1,1,1,...). Stop when we get further than "ddlim" from the - origin. */ - dd = 10.0; - if( ddlim == 0.0 ) ddlim = 10240.0; - while( !ret && dd <= ddlim ) { - -/* First try positions which extend across the middle of the data set. - If the image dimensions are known, make the line go from the "bottom - left corner" towards the "top right corner", taking the aspect ratio - of the image into account. Otherise, just use a vector of (1,1,1,..) */ - for( i = 0; i < nin; i++ ) { - if( dim && dim[ i ] != AST__BAD ) { - g0[ i ] = dd*dim[ i ]/ddlim; - } else { - g0[ i ] = dd; - } - } - ret = MakeBasisVectors( map, nin, nout, g0, psetg, psetw, status ); - -/* If the above didn't produce good positions, try moving out along each - grid axis in turn. */ - for( ii = 0; !ret && ii < nin; ii++ ) { - for( i = 0; i < nin; i++ ) g0[ i ] = 1.0; - g0[ ii ] = dd; - ret = MakeBasisVectors( map, nin, nout, g0, psetg, psetw, status ); - } - -/* Go further out from the origin for the next set of tests (if any). */ - dd *= 2.0; - } - } - -/* Free resources. */ - g0 = astFree( g0 ); - -/* Return the result. */ - return ret; -} - -static int FindLonLatSpecAxes( FitsStore *store, char s, int *axlon, int *axlat, - int *axspec, const char *method, const char *class, int *status ) { -/* -* Name: -* FindLonLatSpecAxes - -* Purpose: -* Search the CTYPE values in a FitsStore for celestial and spectral axes. - -* Type: -* Private function. - -* Synopsis: -* int FindLonLatSpecAxes( FitsStore *store, char s, int *axlon, int *axlat, -* int *axspec, const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* The supplied FitsStore is searched for axes with a specified axis -* description character which describe celestial longitude or latitude -* or spectral position. - -* Parameters: -* store -* A structure containing values for FITS keywords relating to -* the World Coordinate System. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* axlon -* Address of a location at which to return the index of the -* longitude axis (if found). This is the value of "i" within the -* keyword name "CTYPEi". A value of -1 is returned if no longitude -* axis is found. -* axlat -* Address of a location at which to return the index of the -* latitude axis (if found). This is the value of "i" within the -* keyword name "CTYPEi". A value of -1 is returned if no latitude -* axis is found. -* axspec -* Address of a location at which to return the index of the -* spectral axis (if found). This is the value of "i" within the -* keyword name "CTYPEi". A value of -1 is returned if no spectral -* axis is found. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One is returned if both celestial axes were found. Zero is returned if -* either axis was not found. The presence of a spectral axis does not -* affect the returned value. - -* Notes: -* - If an error occurs, zero is returned. -*/ - -/* Local Variables: */ - char *assys; - char *astype; - char algcode[5]; - char stype[5]; - const char *ctype; - double dval; - int i; - int wcsaxes; - -/* Initialise */ - *axlon = -1; - *axlat = -1; - *axspec = -1; - -/* Check the global status. */ - if ( !astOK ) return 0; - -/* Obtain the number of FITS WCS axes in the header. If the WCSAXES header - was specified, use it. Otherwise assume it is the same as the number - of pixel axes. */ - dval = GetItem( &(store->wcsaxes), 0, 0, s, NULL, method, class, status ); - if( dval != AST__BAD ) { - wcsaxes = (int) dval + 0.5; - } else { - wcsaxes = store->naxis; - } - -/* Loop round the FITS WCS axes, getting each CTYPE value. */ - for( i = 0; i < wcsaxes && astOK; i++ ){ - ctype = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - -/* Check a value was found. */ - if( ctype ) { - -/* First check for spectral axes, either FITS-WCS or AIPS-like. */ - if( IsSpectral( ctype, stype, algcode, status ) || - IsAIPSSpectral( ctype, &astype, &assys, status ) ) { - *axspec = i; - -/* Otherwise look for celestial axes. Celestial axes must have a "-" as the - fifth character in CTYPE. */ - } else if( ctype[4] == '-' ) { - -/* See if this is a longitude axis (e.g. if the first 4 characters of CTYPE - are "RA--" or "xLON" or "yzLN" ). */ - if( !strncmp( ctype, "RA--", 4 ) || - !strncmp( ctype, "AZ--", 4 ) || - !strncmp( ctype + 1, "LON", 3 ) || - !strncmp( ctype + 2, "LN", 2 ) ){ - *axlon = i; - -/* Otherwise see if it is a latitude axis. */ - } else if( !strncmp( ctype, "DEC-", 4 ) || - !strncmp( ctype, "EL--", 4 ) || - !strncmp( ctype + 1, "LAT", 3 ) || - !strncmp( ctype + 2, "LT", 2 ) ){ - *axlat = i; - } - } - } - } - -/* Indicate failure if an error occurred. */ - if( !astOK ) { - *axlon = -1; - *axlat = -1; - *axspec = -1; - } - -/* Return the result. */ - return ( *axlat != -1 && *axlon != -1 ); -} - -static void FindWcs( AstFitsChan *this, int last, int all, int rewind, - const char *method, const char *class, int *status ){ - -/* -* Name: -* FindWcs - -* Purpose: -* Find the first or last FITS WCS related keyword in a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void FindWcs( AstFitsChan *this, int last, int all, int rewind, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A search is made through the FitsChan for the first or last card -* which relates to a FITS WCS keyword (any encoding). If "last" is -* non-zero, the next card becomes the current card. If "last" is -* zero, the WCS card is left as the current card. Cards marked as -* having been read are included or not, as specified by "all". - -* Parameters: -* this -* Pointer to the FitsChan. -* last -* If non-zero, the last WCS card is searched for. Otherwise, the -* first WCS card is searched for. -* all -* If non-zero, then cards marked as having been read are included -* in the search. Otherwise such cards are ignored. -* rewind -* Only used if "last" is zero (i.e. the first card is being -* searched for). If "rewind" is non-zero, then the search starts -* from the first card in the FitsChan. If zero, the search starts -* from the current card. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The FitsChan is left at end-of-file if no FITS-WCS keyword cards -* are found in the FitsChan. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *keyname; /* Keyword name from current card */ - int nfld; /* Number of fields in keyword template */ - int old_ignore_used; /* Original value of variable ignore_used */ - -/* Check the global status. Also check the FitsChan is not empty. */ - if( !astOK || !this->head ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Indicate that we should, or should not, skip over cards marked as having - been read. */ - old_ignore_used = ignore_used; - ignore_used = all ? 0 : 1; - -/* If required, set the FitsChan to start or end of file. */ - if( last ) { - astSetCard( this, INT_MAX ); - } else if( rewind ) { - astClearCard( this ); - } - -/* If the current card is marked as used, and we are skipping used cards, - move on to the next unused card */ - if( CARDUSED( this->card ) ) MoveCard( this, last?-1:1, method, class, status ); - -/* Check each card moving backwards from the end to the start, or - forwards from the start to the end, until a WCS keyword is found, - or the other end of the FitsChan is reached. */ - while( astOK ){ - -/* Get the keyword name from the current card. */ - keyname = CardName( this, status ); - -/* Save a pointer to the keyword if it is the first non-null, non-comment - card. */ - if( keyname ) { - -/* If it matches any of the WCS keywords, move on one card - and break out of the loop. */ - if( Match( keyname, "CRVAL%d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "CRPIX%d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "CDELT%d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "CROTA%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "CTYPE%d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "CUNIT%d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PC%3d%3d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "CD%3d%3d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "CD%1d_%1d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PC%1d_%1d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "LONGPOLE", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "LONPOLE%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "LATPOLE%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PROJP%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PV%d_%d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PS%d_%d%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "EPOCH", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "EQUINOX%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "MJD-OBS", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "DATE-OBS", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "TIMESYS", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "RADECSYS", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "RADESYS%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "C%1dVAL%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "C%1dPIX%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "C%1dELT%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "C%1dYPE%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "C%1dNIT%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "CNPIX1", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "CNPIX2", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PPO%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "AMDX%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "AMDY%d", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "XPIXELSZ", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "YPIXELSZ", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PLTRAH", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PLTRAM", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PLTRAS", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PLTDECD", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PLTDECM", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PLTDECS", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PLTDECSN", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PLTSCALE", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PPO1", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PPO2", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PPO4", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "PPO5", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "WCSNAME%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "SPECSYS%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "SSYSSRC%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "ZSOURCE%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "VELOSYS%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "RESTFRQ%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "MJD_AVG%0c", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "OBSGEO-X", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "OBSGEO-Y", 0, NULL, &nfld, method, class, status ) || - Match( keyname, "OBSGEO-Z", 0, NULL, &nfld, method, class, status ) ) { - if( last ) MoveCard( this, 1, method, class, status ); - break; - } - } - -/* Leave the FitsChan at end-of-file if no WCS cards were found. */ - if( (last && FitsSof( this, status ) ) || - (!last && astFitsEof( this ) ) ) { - astSetCard( this, INT_MAX ); - break; - } else { - MoveCard( this, last?-1:1, method, class, status ); - } - } - -/* Re-instate the original flag indicating if cards marked as having been - read should be skipped over. */ - ignore_used = old_ignore_used; - -/* Return. */ - return; -} - -static int FindString( int n, const char *list[], const char *test, - const char *text, const char *method, - const char *class, int *status ){ -/* -* Name: -* FindString - -* Purpose: -* Find a given string within an array of character strings. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int FindString( int n, const char *list[], const char *test, -* const char *text, const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function identifies a supplied string within a supplied -* array of valid strings, and returns the index of the string within -* the array. The test option may not be abbreviated, but case is -* insignificant. - -* Parameters: -* n -* The number of strings in the array pointed to be "list". -* list -* A pointer to an array of legal character strings. -* test -* A candidate string. -* text -* A string giving a description of the object, parameter, -* attribute, etc, to which the test value refers. -* This is only for use in constructing error messages. It should -* start with a lower case letter. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The index of the identified string within the supplied array, starting -* at zero. - -* Notes: -* - A value of -1 is returned if an error has already occurred, or -* if this function should fail for any reason (for instance if the -* supplied option is not specified in the supplied list). -*/ - -/* Local Variables: */ - int ret; /* The returned index */ - -/* Check global status. */ - if( !astOK ) return -1; - -/* Compare the test string with each element of the supplied list. Leave - the loop when a match is found. */ - for( ret = 0; ret < n; ret++ ) { - if( !Ustrcmp( test, list[ ret ], status ) ) break; - } - -/* Report an error if the supplied test string does not match any element - in the supplied list. */ - if( ret >= n && astOK ) { - astError( AST__RDERR, "%s(%s): Illegal value '%s' supplied for %s.", status, - method, class, test, text ); - ret = -1; - } - -/* Return the answer. */ - return ret; -} - -static int FitOK( int n, double *act, double *est, double tol, int *status ) { -/* -* Name: -* FitOK - -* Purpose: -* See if a fit is usable. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int FitOK( int n, double *act, double *est, double tol, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function is supplied with a set of actual data values, and the -* corresponding values estimated by some fitting process. It tests -* that the RMS residual between them is no more than "tol". - -* Parameters: -* n -* Number of data points. -* act -* Pointer to the start of the actual data values. -* est -* Pointer to the start of the estimated data values. -* tol -* The largest acceptable RMS error between "act" and "est". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if the two sets of values agree. Zero is -* returned otherwise. - -* Notes: -* - Zero is returned if an error occurs. -*/ - -/* Local Variables: */ - int ret, i; - double s1, s2; - double *px, *py, diff, mserr; - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Initialise the sum of the squared residuals, and the number summed. */ - s1 = 0.0; - s2 = 0.0; - -/* Initialise pointers to the next actual and estimated values to use. */ - px = act; - py = est; - -/* Loop round all pairs of good actual and estimate value. */ - for( i = 0; i < n; i++, px++, py++ ){ - if( *px != AST__BAD && *py != AST__BAD ) { - -/* Increment the sums need to find the RMS residual between the actual - and estimated values. */ - diff = *px - *py; - s1 += diff*diff; - s2 += 1.0; - } - } - -/* If the sums are usable... */ - if( s2 > 0.0 ) { - -/* Form the mean squared residual, and check if it is less than the - squared error limit. */ - mserr = s1/s2; - if( mserr < tol*tol ) ret = 1; - } - -/* Return the result. */ - return ret; -} - -static int FitsAxisOrder( AstFitsChan *this, int nwcs, AstFrame *wcsfrm, - int *perm, int *status ){ -/* -* Name: -* FitsAxisOrder - -* Purpose: -* Return the order of WCS axes specified by attribute FitsAxisOrder. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int FitsAxisOrder( AstFitsChan *this, int nwcs, AstFrame *wcsfrm, -* int *perm, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns an array indicating the order of the WCS axes -* within the output FITS header, as specified by the FitsAxisOrder -* attribute. - -* Parameters: -* this -* Pointer to the FitsChan. -* nwcs -* The number of axes in "wcsfrm". -* wcsfrm -* The Frame containing the output WCS axes. -* perm -* Pointer to an array of "nwcs" integers. On exit, element "k" -* of this array holds the zero-based index of the FITS-WCS axis -* (i.e. one less than the value of "i" in the keyword names -* "CTYPEi", "CRVALi", etc) that describes the k'th axis in "wcsfrm". -* In other words, "perm[ast_index] = fits_index". The order is -* determined by the FitsAxisOrder attribute. If this attribute is -* "" or "", then "perm[k]=k" for all k on exit (i.e. -* a unit mapping between axes in "wcsfrm" and the FITS header). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Returns zero if the FitsAxisOrder attribute is ", and -* non-zero otherwise. This is a flag indicating if the returned -* values in "perm" can be used s they are. - -*/ - -/* Local Variables: */ - AstKeyMap *km; /* KeyMap holding axis indices keyed by axis symbols */ - char **words; /* Pointer to array of words from FitsAxisOrder */ - char attr_name[15];/* Attribute name */ - const char *attr; /* Pointer to a string holding the FitsAxisOrder value */ - int i; /* Loop count */ - int j; /* Zero-based axis index */ - int k; /* Zero-based axis index */ - int nword; /* Number of words in FitsAxisOrder */ - int result; /* Retrned value */ - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Initialise the returned array to a unit mapping from Frame axis to - FITS axis. */ - for( i = 0; i < nwcs; i++ ) perm[ i ] = i; - -/* Get the FitsAxisOrder attribute value, and set the returned value to - indicate if it is "". */ - attr = astGetFitsAxisOrder( this ); - result = !astChrMatch( attr, "" ); - -/* Return immediately if it is "" or "". */ - if( result && !astChrMatch( attr, "" ) ) { - -/* Create a KeyMap in which each key is the Symbol for an axis and the - associated value is the zero based index of the axis within "wcsfrm". */ - km = astKeyMap( "KeyCase=0", status ); - for( i = 0; i < nwcs; i++ ){ - sprintf( attr_name, "Symbol(%d)", i + 1 ); - astMapPut0I( km, astGetC( wcsfrm, attr_name ), i, NULL ); - } - -/* Split the FitsAxisOrder value into a collection of space-separated words. */ - words = astChrSplit( attr, &nword ); - -/* Loop round them all. */ - k = 0; - for( i = 0; i < nword; i++ ) { - -/* Get the zero based index within "wcsfrm" of the axis that has a Symbol - equal to the current word from FitsAxisOrder. */ - if( astMapGet0I( km, words[ i ], &j ) ) { - -/* If this "wcsfrm" axis has already been used, report an error. */ - if( j < 0 ) { - if( astOK ) astError( AST__ATTIN, "astWrite(fitschan): " - "attribute FitsAxisOrder (%s) refers to axis " - "%s more than once.", status, attr, words[ i ] ); - -/* Otherwise, set the corresponding element of the returned array, and - ensure this axis cannot be used again by assigning it an index of -1 - in the KeyMap. */ - } else { - perm[ j ] = k++; - astMapPut0I( km, words[ i ], -1, NULL ); - } - } - -/* Free the memory holding the copy of the word. */ - words[ i ] = astFree( words[ i ] ); - } - -/* Report an error if any wcsfrm axes were not included in FitsAxisOrder. */ - if( astOK ) { - for( i = 0; i < nwcs; i++ ){ - sprintf( attr_name, "Symbol(%d)", i + 1 ); - if( astMapGet0I( km, astGetC( wcsfrm, attr_name ), &j ) ) { - if( j >= 0 ) { - astError( AST__ATTIN, "astWrite(fitschan): attribute FitsAxisOrder " - "(%s) does not specify a position for WCS axis '%s'.", - status, attr, astGetC( wcsfrm, attr_name ) ); - break; - } - } - } - } - -/* Free resources. */ - words = astFree( words ); - km = astAnnul( km ); - } - - return result; -} - -static int FitsFromStore( AstFitsChan *this, FitsStore *store, int encoding, - double *dim, AstFrameSet *fs, const char *method, - const char *class, int *status ){ - -/* -* Name: -* FitsFromStore - -* Purpose: -* Store WCS keywords in a FitsChan. - -* Type: -* Private function. - -* Synopsis: - -* int FitsFromStore( AstFitsChan *this, FitsStore *store, int encoding, -* double *dim, AstFrameSet *fs, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function copies the WCS information stored in the supplied -* FitsStore into the supplied FitsChan, using a specified encoding. - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore. -* encoding -* The encoding to use. -* dim -* Pointer to an array holding the array dimensions (AST__BAD -* indicates that the dimenson is not known). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if succesfull, and zero is returned -* otherwise. -*/ - -/* Local Variables: */ - int ret; - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Set the current card so that it points to the last WCS-related keyword - in the FitsChan (whether previously read or not). Any new WCS related - keywords either over-write pre-existing cards for the same keyword, or - (if no pre-existing card exists) are inserted after the last WCS related - keyword. */ - FindWcs( this, 1, 1, 0, method, class, status ); - -/* Do each non-standard FITS encoding... */ - if( encoding == DSS_ENCODING ){ - ret = DSSFromStore( this, store, method, class, status ); - } else if( encoding == FITSPC_ENCODING ){ - ret = PCFromStore( this, store, method, class, status ); - } else if( encoding == FITSIRAF_ENCODING ){ - ret = IRAFFromStore( this, store, method, class, status ); - } else if( encoding == FITSAIPS_ENCODING ){ - ret = AIPSFromStore( this, store, method, class, status ); - } else if( encoding == FITSAIPSPP_ENCODING ){ - ret = AIPSPPFromStore( this, store, method, class, status ); - } else if( encoding == FITSCLASS_ENCODING ){ - ret = CLASSFromStore( this, store, fs, dim, method, class, status ); - -/* Standard FITS-WCS encoding */ - } else { - ret = WcsFromStore( this, store, method, class, status ); - } - -/* If there are any Tables in the FitsStore move the KeyMap that contains - them from the FitsStore to the FitsChan, from where they can be - retrieved using the public astGetTables method. */ - if( astMapSize( store->tables ) > 0 ) { - if( !this->tables ) this->tables = astKeyMap( " ", status ); - astMapCopy( this->tables, store->tables ); - (void) astAnnul( store->tables ); - store->tables = astKeyMap( " ", status ); - } - -/* If an error has occurred, return zero. */ - if( !astOK ) ret = 0; - -/* Return the answer. */ - return ret; -} - -static FitsStore *FitsToStore( AstFitsChan *this, int encoding, - const char *method, const char *class, int *status ){ - -/* -* Name: -* FitsToStore - -* Purpose: -* Return a pointer to a FitsStore structure containing WCS information -* read from the supplied FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* FitsStore *FitsToStore( AstFitsChan *this, int encoding, -* const char *method, const char *class ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function creates a new FitsStore containing WCS information -* read from the supplied FitsChan using the specified encoding. An -* error is reported and a null pointer returned if the FitsChan does -* not contain usable WCS information with the specified encoding. - -* Parameters: -* this -* Pointer to the FitsChan. -* encoding -* The encoding to use. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* Returned Value: -* A pointer to a new FitsStore, or NULL if an error has occurred. The -* FitsStore should be released using FreeStore function when it is no -* longer needed. -*/ - -/* Local Variables: */ - AstFitsChan *trans; - FitsStore *ret; - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Allocate memory for the new FitsStore, and store NULL pointers in it. */ - ret = (FitsStore *) astMalloc( sizeof(FitsStore) ); - if( ret ) { - ret->cname = NULL; - ret->ctype = NULL; - ret->ctype_com = NULL; - ret->cunit = NULL; - ret->ps = NULL; - ret->radesys = NULL; - ret->wcsname = NULL; - ret->wcsaxes = NULL; - ret->pc = NULL; - ret->cdelt = NULL; - ret->crpix = NULL; - ret->crval = NULL; - ret->equinox = NULL; - ret->latpole = NULL; - ret->lonpole = NULL; - ret->mjdobs = NULL; - ret->mjdavg = NULL; - ret->dut1 = NULL; - ret->dtai = NULL; - ret->pv = NULL; - ret->specsys = NULL; - ret->ssyssrc = NULL; - ret->obsgeox = NULL; - ret->obsgeoy = NULL; - ret->obsgeoz = NULL; - ret->restfrq = NULL; - ret->restwav = NULL; - ret->zsource = NULL; - ret->velosys = NULL; - ret->asip = NULL; - ret->bsip = NULL; - ret->apsip = NULL; - ret->bpsip = NULL; - ret->imagfreq = NULL; - ret->axref = NULL; - ret->naxis = 0; - ret->timesys = NULL; - ret->tables = astKeyMap( " ", status ); - ret->skyref = NULL; - ret->skyrefp = NULL; - ret->skyrefis = NULL; - } - -/* Call the routine apropriate to the encoding. */ - if( encoding == DSS_ENCODING ){ - DSSToStore( this, ret, method, class, status ); - -/* All other foreign encodings are treated as variants of FITS-WCS. */ - } else { - -/* Create a new FitsChan containing standard translations for any - non-standard keywords in the supplied FitsChan. The non-standard - keywords are marked as provisionally read in the supplied FitsChan. */ - trans = SpecTrans( this, encoding, method, class, status ); - -/* Copy the required values to the FitsStore, using keywords in "trans" - in preference to those in "this". */ - WcsToStore( this, trans, ret, method, class, status ); - -/* Delete the temporary FitsChan holding translations of non-standard - keywords. */ - if( trans ) trans = (AstFitsChan *) astDelete( trans ); - -/* Store the number of pixel axes. This is taken as the highest index used - in any primary CRPIX keyword. */ - ret->naxis = GetMaxJM( &(ret->crpix), ' ', status ) + 1; - } - -/* If an error has occurred, free the returned FitsStore, and return a null - pointer. */ - if( !astOK ) ret = FreeStore( ret, status ); - -/* Return the answer. */ - return ret; -} - -static void FreeItem( double ****item, int *status ){ -/* -* Name: -* FreeItem - -* Purpose: -* Frees all dynamically allocated memory associated with a specified -* item in a FitsStore. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void FreeItem( double ****item, int *status ); - -* Class Membership: -* FitsChan member function. - -* Description: -* Frees all dynamically allocated memory associated with the specified -* item in a FitsStore. A NULL pointer is stored in the FitsStore. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->crval) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (j), and the pointer locates an -* array of axis keyword values. These arrays of keyword values have -* one element for every pixel axis (i) or projection parameter (m). -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function attempt to execute even if an error has occurred. -*/ - -/* Local Variables: */ - int si; /* Integer co-ordinate version index */ - int j; /* Intermediate co-ordinate axis index */ - int oldstatus; /* Old error status value */ - int oldreport; /* Old error reporting value */ - -/* Other initialisation to avoid compiler warnings. */ - oldreport = 0; - -/* Check the supplied pointer */ - if( item && *item ){ - -/* Start a new error reporting context. */ - oldstatus = astStatus; - if( !astOK ) { - oldreport = astReporting( 0 ); - astClearStatus; - } - -/* Loop round each coordinate version. */ - for( si = 0; si < astSizeOf( (void *) *item )/sizeof(double **); - si++ ){ - -/* Check the pointer stored for this co-ordinate version is not null. */ - if( (*item)[si] ) { - -/* Loop round the intermediate axes. */ - for( j = 0; j < astSizeOf( (void *) (*item)[si] )/sizeof(double *); - j++ ){ - -/* Free the pixel axis/parameter index pointer. */ - (*item)[si][j] = (double *) astFree( (void *) (*item)[si][j] ); - } - -/* Free the intermediate axes pointer */ - (*item)[si] = (double **) astFree( (void *) (*item)[si] ); - } - } - -/* Free the co-ordinate versions pointer */ - *item = (double ***) astFree( (void *) *item ); - -/* If there was an error status on entry to this function, re-instate it. - Otherwise, allow any new error status to remain. */ - if( oldstatus ){ - if( !astOK ) astClearStatus; - astSetStatus( oldstatus ); - astReporting( oldreport ); - } - } -} - -static void FreeItemC( char *****item, int *status ){ -/* -* Name: -* FreeItemC - -* Purpose: -* Frees all dynamically allocated memory associated with a specified -* string item in a FitsStore. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void FreeItemC( char *****item, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Frees all dynamically allocated memory associated with the specified -* string item in a FitsStore. A NULL pointer is stored in the FitsStore. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->ctype) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (j), and the pointer locates an -* array of axis keyword values. These arrays of keyword values have -* one element (a char pointyer) for every pixel axis (i) or -* projection parameter (m). -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - int si; /* Integer co-ordinate version index */ - int i; /* Intermediate co-ordinate axis index */ - int jm; /* Pixel co-ordinate axis or parameter index */ - int oldstatus; /* Old error status value */ - int oldreport; /* Old error reporting value */ - -/* Other initialisation to avoid compiler warnings. */ - oldreport = 0; - -/* Check the supplied pointer */ - if( item && *item ){ - -/* Start a new error reporting context. */ - oldstatus = astStatus; - if( !astOK ) { - oldreport = astReporting( 0 ); - astClearStatus; - } - -/* Loop round each coordinate version. */ - for( si = 0; si < astSizeOf( (void *) *item )/sizeof(char ***); - si++ ){ - -/* Check the pointer stored for this co-ordinate version is not null. */ - if( (*item)[si] ) { - -/* Loop round the intermediate axes. */ - for( i = 0; i < astSizeOf( (void *) (*item)[si] )/sizeof(char **); - i++ ){ - -/* Check the pointer stored for this intermediate axis is not null. */ - if( (*item)[si][i] ) { - -/* Loop round the pixel axes or parameter values. */ - for( jm = 0; jm < astSizeOf( (void *) (*item)[si][i] )/sizeof(char *); - jm++ ){ - -/* Free the string. */ - (*item)[si][i][jm] = (char *) astFree( (void *) (*item)[si][i][jm] ); - } - -/* Free the pixel axes/parameter pointer */ - (*item)[si][i] = (char **) astFree( (void *) (*item)[si][i] ); - } - } - -/* Free the intermediate axes pointer */ - (*item)[si] = (char ***) astFree( (void *) (*item)[si] ); - } - } - -/* Free the co-ordinate versions pointer */ - *item = (char ****) astFree( (void *) *item ); - -/* If there was an error status on entry to this function, re-instate it. - Otherwise, allow any new error status to remain. */ - if( oldstatus ){ - if( !astOK ) astClearStatus; - astSetStatus( oldstatus ); - astReporting( oldreport ); - } - } -} - -static FitsStore *FreeStore( FitsStore *store, int *status ){ -/* -* Name: -* FreeStore - -* Purpose: -* Free dynamic arrays stored in a FitsStore structure. - -* Type: -* Private function. - -* Synopsis: -* FitsStore *FreeStore( FitsStore *store, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function frees all dynamically allocated arrays stored in the -* supplied FitsStore structure, and returns a NULL pointer. - -* Parameters: -* store -* Pointer to the structure to clean. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function attempts to execute even if an error exists on entry. -*/ - -/* Return if no FitsStore was supplied. */ - if( !store ) return NULL; - -/* Free each of the dynamic arrays stored in the FitsStore. */ - FreeItemC( &(store->cname), status ); - FreeItemC( &(store->ctype), status ); - FreeItemC( &(store->ctype_com), status ); - FreeItemC( &(store->cunit), status ); - FreeItemC( &(store->radesys), status ); - FreeItemC( &(store->wcsname), status ); - FreeItemC( &(store->specsys), status ); - FreeItemC( &(store->ssyssrc), status ); - FreeItemC( &(store->ps), status ); - FreeItemC( &(store->timesys), status ); - FreeItem( &(store->pc), status ); - FreeItem( &(store->cdelt), status ); - FreeItem( &(store->crpix), status ); - FreeItem( &(store->crval), status ); - FreeItem( &(store->equinox), status ); - FreeItem( &(store->latpole), status ); - FreeItem( &(store->lonpole), status ); - FreeItem( &(store->mjdobs), status ); - FreeItem( &(store->dut1), status ); - FreeItem( &(store->dtai), status ); - FreeItem( &(store->mjdavg), status ); - FreeItem( &(store->pv), status ); - FreeItem( &(store->wcsaxes), status ); - FreeItem( &(store->obsgeox), status ); - FreeItem( &(store->obsgeoy), status ); - FreeItem( &(store->obsgeoz), status ); - FreeItem( &(store->restfrq), status ); - FreeItem( &(store->restwav), status ); - FreeItem( &(store->zsource), status ); - FreeItem( &(store->velosys), status ); - FreeItem( &(store->asip), status ); - FreeItem( &(store->bsip), status ); - FreeItem( &(store->apsip), status ); - FreeItem( &(store->bpsip), status ); - FreeItem( &(store->imagfreq), status ); - FreeItem( &(store->axref), status ); - store->tables = astAnnul( store->tables ); - FreeItem( &(store->skyref), status ); - FreeItem( &(store->skyrefp), status ); - FreeItemC( &(store->skyrefis), status ); - return (FitsStore *) astFree( (void *) store ); -} - -static char *FormatKey( const char *key, int c1, int c2, char s, int *status ){ -/* -* Name: -* FormatKey - -* Purpose: -* Format a keyword name with indices and co-ordinate version character. - -* Type: -* Private function. - -* Synopsis: -* char *FormatKey( const char *key, int c1, int c2, char s, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function formats a keyword name by including the supplied -* axis/parameter indices and co-ordinate version character. - -* Parameters: -* key -* The base name of the keyword (e.g. "CD", "CRVAL", etc). -* c1 -* An integer value to append to the end of the keyword. Ignored if -* less than zero. -* c2 -* A second integer value to append to the end of the keyword. Ignored if -* less than zero. This second integer is preceded by an underscore. -* s -* The co-ordinate version character to append to the end of the -* final string. Ignored if blank. -* status -* Pointer to the inherited status variable. -* Returned Value; -* A pointer to a static character buffer containing the final string. -* NULL if an error occurs. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - char *ret; - int len; - int nc; - -/* Initialise */ - ret = NULL; - -/* Check inherited status */ - if( !astOK ) return ret; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* No characters stored yet. A value of -1 is used to indicate that an - error has occurred. */ - len = 0; - -/* Store the supplied keyword base name. */ - if( len >= 0 && ( nc = sprintf( formatkey_buff + len, "%s", key ) ) >= 0 ){ - len += nc; - } else { - len = -1; - } - -/* If index c1 has been supplied, append it to the end of the string. */ - if( c1 >= 0 ) { - if( len >= 0 && ( nc = sprintf( formatkey_buff + len, "%d", c1 ) ) >= 0 ){ - len += nc; - } else { - len = -1; - } - -/* If index c2 has been supplied, append it to the end of the string, - preceded by an underscore. */ - if( c2 >= 0 ) { - if( len >= 0 && ( nc = sprintf( formatkey_buff + len, "_%d", c2 ) ) >= 0 ){ - len += nc; - } else { - len = -1; - } - } - } - -/* If a co-ordinate version character has been supplied, append it to the end - of the string. */ - if( s != ' ' ) { - if( len >= 0 && ( nc = sprintf( formatkey_buff + len, "%c", s ) ) >= 0 ){ - len += nc; - } else { - len = -1; - } - } - -/* Report an error if necessary */ - if( len < 0 && astOK ) { - astError( AST__INTER, "FormatKey(fitschan): AST internal error; failed " - "to format the keyword %s with indices %d and %d, and " - "co-ordinate version %c.", status, key, c1, c2, s ); - ret = NULL; - } else { - ret = formatkey_buff; - } - return formatkey_buff; -} - -static AstObject *FsetFromStore( AstFitsChan *this, FitsStore *store, - const char *method, const char *class, int *status ){ -/* -* Name: -* FsetFromStore - -* Purpose: -* Create a FrameSet using the the information previously stored in -* the suppllied FitsStore structure. - -* Type: -* Private function. - -* Synopsis: -* AstObject *FsetFromStore( AstFitsChan *this, FitsStore *store, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function creates a new FrameSet containing WCS information -* stored in the supplied FitsStore. A null pointer is returned and no -* error is reported if this is not possible. - -* Parameters: -* this -* The FitsChan from which the keywords were read. Warning messages -* are added to this FitsChan if the celestial co-ordinate system is -* not recognized. -* store -* Pointer to the FitsStore. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new FrameSet, or a null pointer if no FrameSet -* could be constructed. - -* Notes: -* - The pixel Frame is given a title of "Pixel Coordinates", and -* each axis in the pixel Frame is given a label of the form "Pixel -* axis ", where is the axis index (starting at one). -* - The FITS CTYPE keyword values are used to set the labels for any -* non-celestial axes in the physical coordinate Frames, and the FITS -* CUNIT keywords are used to set the corresponding units strings. -* - On exit, the pixel Frame is the base Frame, and the physical -* Frame derived from the primary axis descriptions is the current Frame. -* - Extra Frames are added to hold any secondary axis descriptions. All -* axes within such a Frame refer to the same coordinate version ('A', -* 'B', etc). -*/ - -/* Local Variables: */ - AstFrame *frame; /* Pointer to pixel Frame */ - AstFrameSet *ret; /* Pointer to returned FrameSet */ - char buff[ 20 ]; /* Buffer for axis label */ - char s; /* Co-ordinate version character */ - int i; /* Pixel axis index */ - int physical; /* Index of primary physical co-ordinate Frame */ - int pixel; /* Index of pixel Frame in returned FrameSet */ - int use; /* Has this co-ordinate version been used? */ - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return (AstObject *) ret; - -/* Only proceed if there are some axes. */ - if( store->naxis ) { - -/* Create a Frame describing the pixel coordinate system. Give it the Domain - GRID. */ - frame = astFrame( store->naxis, "Title=Pixel Coordinates,Domain=GRID", status ); - -/* Store labels for each pixel axis. */ - if( astOK ){ - for( i = 0; i < store->naxis; i++ ){ - sprintf( buff, "Pixel axis %d", i + 1 ); - astSetLabel( frame, i, buff ); - } - } - -/* Create the FrameSet initially holding just the pixel coordinate frame - (this becomes the base Frame). */ - ret = astFrameSet( frame, "", status ); - -/* Annul the pointer to the pixel coordinate Frame. */ - frame = astAnnul( frame ); - -/* Get the index of the pixel Frame in the FrameSet. */ - pixel = astGetCurrent( ret ); - -/* Produce the Frame describing the primary axis descriptions, and add it - into the FrameSet. */ - AddFrame( this, ret, pixel, store->naxis, store, ' ', method, class, status ); - -/* Get the index of the primary physical co-ordinate Frame in the FrameSet. */ - physical = astGetCurrent( ret ); - -/* Loop, producing secondary axis Frames for each of the co-ordinate - versions stored in the FitsStore. */ - for( s = 'A'; s <= GetMaxS( &(store->crval), status ) && astOK; s++ ){ - -/* Only use this co-ordinate version character if any of the required - keywords (for any axis) are stored in the FitsStore. */ - use = 0; - for( i = 0; i < store->naxis; i++ ){ - if( GetItem( &(store->crval), i, 0, s, NULL, method, class, status ) != AST__BAD || - GetItem( &(store->crpix), 0, i, s, NULL, method, class, status ) != AST__BAD || - GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ) != NULL ){ - use = 1; - break; - } - } - -/* If this co-ordinate version has been used, add a Frame to the returned - FrameSet holding this co-ordinate version. */ - if( use ) AddFrame( this, ret, pixel, store->naxis, store, s, method, class, status ); - } - -/* Ensure the pixel Frame is the Base Frame and the primary physical - Frame is the Current Frame. */ - astSetBase( ret, pixel ); - astSetCurrent( ret, physical ); - -/* Remove any unneeded Frames that hold a FITS representation of offset - coordinates. */ - TidyOffsets( ret, status ); - -/* If an error has occurred, free the returned FrameSet and return a null - pointer. */ - if( !astOK ) ret = astAnnul( ret ); - } - -/* Return the answer. */ - return (AstObject *) ret; -} - -static FitsStore *FsetToStore( AstFitsChan *this, AstFrameSet *fset, int naxis, - double *dim, int encoding, const char *class, - const char *method, int *status ){ - -/* -* Name: -* FsetToStore - -* Purpose: -* Fill a FitsStore structure with a description of the supplied -* FrameSet. - -* Type: -* Private function. - -* Synopsis: - -* FitsStore *FsetToStore( AstFitsChan *this, AstFrameSet *fset, int naxis, -* double *dim, int encoding, const char *class, -* const char *method, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function creates a new FitsStore containing WCS information -* read from the supplied FitsChan using the specified encoding. An -* error is reported and a null pointer returned if the FitsChan does -* not contain usable WCS information with the specified encoding. - -* Parameters: -* this -* Pointer to the FitsChan. -* fset -* Pointer to the FrameSet. -* naxis -* The number of axes in the Base Frame of the supplied FrameSet. -* dim -* Pointer to an array of pixel axis dimensions. Individual elements -* will be AST__BAD if dimensions are not known. -* encoding -* The encoding being used. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a new FitsStore, or NULL if an error has occurred. The -* FitsStore should be released using FreeStore function when it is no -* longer needed. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the AST error status set, or if it should fail for any -* reason. -* - The Base Frame in the FrameSet is used as the pixel Frame, and -* the Current Frame is used to create the primary axis descriptions. -* Attempts are made to create secondary axis descriptions for any -* other Frames in the FrameSet (up to a total of 26). -*/ - -/* Local Variables: */ - AstFrame *frame; /* A Frame */ - const char *id; /* Frame Ident string */ - int nfrm; /* Number of Frames in FrameSet */ - char *sid; /* Pointer to array of version letters */ - int frms[ 'Z' + 1 ]; /* Array of Frame indices */ - FitsStore *ret; /* Returned FitsStore */ - char s; /* Next available co-ordinate version character */ - char s0; /* Co-ordinate version character */ - int ibase; /* Base Frame index */ - int icurr; /* Current Frame index */ - int ifrm; /* Next Frame index */ - int isoff; /* Is the Frame an offset SkyFrame? */ - int primok; /* Primary Frame stored succesfully? */ - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Allocate memory for the new FitsStore, and store NULL pointers in it. */ - ret = (FitsStore *) astMalloc( sizeof(FitsStore) ); - if( astOK ) { - ret->cname = NULL; - ret->ctype = NULL; - ret->ctype_com = NULL; - ret->cunit = NULL; - ret->ps = NULL; - ret->radesys = NULL; - ret->wcsname = NULL; - ret->wcsaxes = NULL; - ret->pc = NULL; - ret->cdelt = NULL; - ret->crpix = NULL; - ret->crval = NULL; - ret->equinox = NULL; - ret->latpole = NULL; - ret->lonpole = NULL; - ret->dut1 = NULL; - ret->dtai = NULL; - ret->mjdobs = NULL; - ret->mjdavg = NULL; - ret->pv = NULL; - ret->specsys = NULL; - ret->ssyssrc = NULL; - ret->obsgeox = NULL; - ret->obsgeoy = NULL; - ret->obsgeoz = NULL; - ret->restfrq = NULL; - ret->restwav = NULL; - ret->zsource = NULL; - ret->velosys = NULL; - ret->asip = NULL; - ret->bsip = NULL; - ret->apsip = NULL; - ret->bpsip = NULL; - ret->imagfreq = NULL; - ret->axref = NULL; - ret->naxis = naxis; - ret->timesys = NULL; - ret->tables = astKeyMap( " ", status ); - ret->skyref = NULL; - ret->skyrefp = NULL; - ret->skyrefis = NULL; - -/* Obtain the index of the Base Frame (i.e. the pixel frame ). */ - ibase = astGetBase( fset ); - -/* Obtain the index of the Current Frame (i.e. the Frame to use as the - primary physical coordinate frame). */ - icurr = astGetCurrent( fset ); - -/* Does the current Frame contain a SkyFrame that describes offset - coordinates? */ - isoff = IsSkyOff( fset, icurr, status ); - -/* Add a description of the primary axes to the FitsStore, based on the - Current Frame in the FrameSet. */ - primok = AddVersion( this, fset, ibase, icurr, ret, dim, ' ', - encoding, isoff, method, class, status ); - -/* Do not add any alternate axis descriptions if the primary axis - descriptions could not be produced. */ - if( primok && astOK ) { - -/* Get the number of Frames in the FrameSet. */ - nfrm = astGetNframe( fset ); - -/* We now need to allocate a version letter to each Frame. Allocate - memory to hold the version letter assigned to each Frame. */ - sid = (char *) astMalloc( ( nfrm + 1 )*sizeof( char ) ); - -/* The frms array has an entry for each of the 26 possible version - letters (starting at A and ending at Z). Each entry holds the index of - the Frame which has been assigned that version character. Initialise - this array to indicate that no version letters have yet been assigned. */ - for( s = 'A'; s <= 'Z'; s++ ) { - frms[ (int) s ] = 0; - } - -/* Loop round all frames (excluding the current and base and IWC Frames which - do not need version letters). If the Frame has an Ident attribute consisting - of a single upper case letter, use it as its version letter unless that - letter has already been given to an earlier frame. IWC Frames are not - written out - identify them by giving them a "sid" value of 1 (an - illegal FITS axis description character). */ - for( ifrm = 1; ifrm <= nfrm; ifrm++ ){ - sid[ ifrm ] = 0; - if( ifrm != icurr && ifrm != ibase ) { - frame = astGetFrame( fset, ifrm ); - if( astChrMatchN( astGetDomain( frame ), "IWC", 3 ) ) { - sid[ ifrm ] = 1; - } else { - id = astGetIdent( frame ); - if( strlen( id ) == 1 && isupper( id[ 0 ] ) ) { - if( frms[ (int) id[ 0 ] ] == 0 ) { - frms[ (int) id[ 0 ] ] = ifrm; - sid[ ifrm ] = id[ 0 ]; - } - } - } - (void) astAnnul( frame ); - } - } - -/* Now go round all the Frames again, looking for Frames which did not - get a version letter assigned to it on the previous loop. Assign them - letters now, selected them from the letters not already assigned - (lowest to highest). */ - s = 'A' - 1; - for( ifrm = 1; ifrm <= nfrm; ifrm++ ){ - if( ifrm != icurr && ifrm != ibase && sid[ ifrm ] != 1 ) { - if( sid[ ifrm ] == 0 ){ - while( frms[ (int) ++s ] != 0 ); - if( s <= 'Z' ) { - sid[ ifrm ] = s; - frms[ (int) s ] = ifrm; - } - } - } - } - -/* If the primary headers describe offset coordinates, create an alternate - axis description for the correspondsing absolute coordinate system. */ - if( isoff && ++s <= 'Z' ) { - (void) AddVersion( this, fset, ibase, icurr, ret, dim, - s, encoding, -1, method, class, status ); - } - -/* Now go through all the other Frames in the FrameSet, attempting to - create alternate axis descriptions for each one. */ - for( ifrm = 1; ifrm <= nfrm; ifrm++ ){ - s0 = sid[ ifrm ]; - if( s0 != 0 && s0 != 1 ) { - -/* Does it contain an offset sky frame? */ - isoff = IsSkyOff( fset, ifrm, status ); - -/* Write out the Frame - offset if it is offset, absolute otherwise. */ - (void) AddVersion( this, fset, ibase, ifrm, ret, dim, - s0, encoding, isoff, method, class, status ); - -/* If the Frame is offset, create an extra alternate axis description for - the correspondsing absolute coordinate system. */ - if( isoff && ++s <= 'Z' ) { - (void) AddVersion( this, fset, ibase, ifrm, ret, dim, - s, encoding, -1, method, class, status ); - } - } - } - -/* Free memory holding version letters */ - sid = (char *) astFree( (void *) sid ); - } - -/* If an error has occurred, or if the primary Frame could not be cerated, - free the returned FitsStore, and return a null pointer. */ - if( !astOK || !primok ) ret = FreeStore( ret, status ); - } - -/* Return the answer. */ - return ret; -} - -static int GetClean( AstFitsChan *this, int *status ) { - -/* -* Name: -* GetClean - -* Purpose: -* Return the value of the Clean attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int GetClean( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns the value of the Clean attribute. Since this -* attribute controls the behaviour of the FitsChan in the event of an -* error condition, it is is necessary to ignore any inherited error -* condition when getting the attribute value. This is why the -* astMAKE_GET macro is not used. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Clean value to use. -*/ - -/* Return if no FitsChan pointer was supplied. */ - if ( !this ) return 0; - -/* Return the attribute value, supplying a default value of 0 (false). */ - return ( this->clean == -1 ) ? 0 : (this->clean ? 1 : 0 ); -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* FitsChan member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied FitsChan, -* in bytes. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to FitsChan structure */ - FitsCard *card; /* Pointer to next FitsCard */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the FitsChan structure. */ - this = (AstFitsChan *) this_object; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astTSizeOf( this->warnings ); - result += astGetObjSize( this->keyseq ); - result += astGetObjSize( this->keywords ); - result += astGetObjSize( this->tables ); - card = (FitsCard *) ( this->head ); - while( card ) { - result += astTSizeOf( card ); - result += card->size; - result += astTSizeOf( card->comment ); - card = GetLink( card, NEXT, "astGetObjSize", "FitsChan", status ); - if( (void *) card == this->head ) break; - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetCDMatrix( AstFitsChan *this, int *status ){ - -/* -* Name: -* GetCDMatrix - -* Purpose: -* Get the value of the CDMatrix attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int GetCDMatrix( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* If the CDMatrix attribute has been set, then its value is returned. -* Otherwise, the supplied FitsChan is searched for keywords of the -* form CDi_j. If any are found a non-zero value is returned. Otherwise -* a zero value is returned. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The attribute value to use. - -* Notes: -* - A value of zero is returned if an error has already occurred -* or if an error occurs for any reason within this function. -*/ - -/* Local Variables... */ - int ret; /* Returned value */ - int icard; /* Index of current card on entry */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* If a value has been supplied for the CDMatrix attribute, use it. */ - if( astTestCDMatrix( this ) ) { - ret = this->cdmatrix; - -/* Otherwise, check for the existence of CDi_j keywords... */ - } else { - -/* Save the current card index, and rewind the FitsChan. */ - icard = astGetCard( this ); - astClearCard( this ); - -/* If the FitsChan contains any keywords with the format "CDi_j" then return - 1. Otherwise return zero. */ - ret = astKeyFields( this, "CD%1d_%1d", 0, NULL, NULL ) ? 1 : 0; - -/* Reinstate the original current card index. */ - astSetCard( this, icard ); - } - -/* Return the result. */ - return astOK ? ret : 0; -} - -static int GetEncoding( AstFitsChan *this, int *status ){ - -/* -* Name: -* GetEncoding - -* Purpose: -* Get the value of the Encoding attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GetEncoding( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* If the Encoding attribute has been set, then its value is returned. -* Otherwise, an attempt is made to determine the encoding scheme by -* looking for selected keywords within the FitsChan. Checks are made -* for the following keywords in the order specified, and the -* corresponding encoding is adopted when the first one is found ( where - -* i, j and m are integers and s is a single upper case character): -* -* 1) Any keywords starting with "BEGAST" = Native encoding -* 2) DELTAV and VELO-xxx (or VLSR) keywords = FITS-CLASS. -* 3) Any AIPS spectral CTYPE values: - -* Any of CDi_j, PROJP, LONPOLE, LATPOLE = FITS-AIPS++ encoding: -* None of the above = FITS-AIPS encoding. -* 4) Any keywords matching PCiiijjj = FITS-PC encoding -* 5) Any keywords matching CDiiijjj = FITS-IRAF encoding -* 6) Any keywords matching CDi_j, AND at least one of RADECSYS, PROJPi -* or CmVALi = FITS-IRAF encoding -* 7) Any keywords RADECSYS, PROJPi or CmVALi, and no CDi_j or PCi_j -* keywords, = FITS-PC encoding -* 8) Any keywords matching CROTAi = FITS-AIPS encoding -* 9) Keywords matching CRVALi = FITS-WCS encoding -* 10) The PLTRAH keyword = DSS encoding -* 11) If none of the above keywords are found, Native encoding is assumed. -* -* For cases 2) to 9), a check is also made that the header contains -* at least one of each keyword CTYPE, CRPIX and CRVAL. If not, then -* the checking process continues to the next case. This goes some way -* towards ensuring that the critical keywords used to determine the -* encoding are part of a genuine WCS description and have not just been -* left in the header by accident. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The encoding scheme identifier. - -* Notes: -* - The function returns UNKNOWN_ENCODING if an error has already occurred -* or if an error occurs for any reason within this function. -*/ - -/* Local Variables... */ - int hascd; /* Any CDi_j keywords found? */ - int haspc; /* Any PCi_j keywords found? */ - int haswcs; /* Any CRVAL, CTYPE and CRPIX found? */ - int icard; /* Index of current card on entry */ - int ret; /* Returned value */ - -/* Check the global status. */ - if( !astOK ) return UNKNOWN_ENCODING; - -/* If a value has been supplied for the Encoding attribute, use it. */ - if( astTestEncoding( this ) ) { - ret = this->encoding; - -/* Otherwise, check for the existence of certain critcal keywords... */ - } else { - -/* See if the header contains some CTYPE, CRPIX and CRVAL keywords. */ - haswcs = astKeyFields( this, "CTYPE%d", 0, NULL, NULL ) && - astKeyFields( this, "CRPIX%d", 0, NULL, NULL ) && - astKeyFields( this, "CRVAL%d", 0, NULL, NULL ); - -/* See if there are any CDi_j keywords. */ - hascd = astKeyFields( this, "CD%1d_%1d", 0, NULL, NULL ); - -/* See if there are any PCi_j keywords. */ - haspc = astKeyFields( this, "PC%1d_%1d", 0, NULL, NULL ); - -/* Save the current card index, and rewind the FitsChan. */ - icard = astGetCard( this ); - astClearCard( this ); - -/* If the FitsChan contains any keywords starting with "BEGAST", then return - "Native" encoding. */ - if( astKeyFields( this, "BEGAST%2f", 0, NULL, NULL ) ){ - ret = NATIVE_ENCODING; - -/* Otherwise, look for a FITS-CLASS signature... */ - } else if( haswcs && LooksLikeClass( this, "astGetEncoding", "AstFitsChan", status ) ){ - ret = FITSCLASS_ENCODING; - -/* Otherwise, if the FitsChan contains any CTYPE keywords which have the - peculiar form used by AIPS, then use "FITS-AIPS" or "FITS-AIPS++" encoding. */ - } else if( haswcs && HasAIPSSpecAxis( this, "astGetEncoding", "AstFitsChan", status ) ){ - if( hascd || - astKeyFields( this, "PROJP%d", 0, NULL, NULL ) || - astKeyFields( this, "LONPOLE", 0, NULL, NULL ) || - astKeyFields( this, "LATPOLE", 0, NULL, NULL ) ) { - ret = FITSAIPSPP_ENCODING; - } else { - ret = FITSAIPS_ENCODING; - } - -/* Otherwise, if the FitsChan contains the "PLTRAH" keywords, use "DSS" - encoding. */ - } else if( astKeyFields( this, "PLTRAH", 0, NULL, NULL ) ){ - ret = DSS_ENCODING; - -/* Otherwise, if the FitsChan contains any keywords with the format - "PCiiijjj" then return "FITS-PC" encoding. */ - } else if( haswcs && astKeyFields( this, "PC%3d%3d", 0, NULL, NULL ) ){ - ret = FITSPC_ENCODING; - -/* Otherwise, if the FitsChan contains any keywords with the format - "CDiiijjj" then return "FITS-IRAF" encoding. */ - } else if( haswcs && astKeyFields( this, "CD%3d%3d", 0, NULL, NULL ) ){ - ret = FITSIRAF_ENCODING; - -/* Otherwise, if the FitsChan contains any keywords with the format - "CDi_j" AND there is a RADECSYS. PROJPi or CmVALi keyword, then return - "FITS-IRAF" encoding. If "CDi_j" is present but none of the others - are, return "FITS-WCS" encoding. */ - } else if( haswcs && hascd ) { - if( ( astKeyFields( this, "RADECSYS", 0, NULL, NULL ) && - !astKeyFields( this, "RADESYS", 0, NULL, NULL ) ) || - ( astKeyFields( this, "PROJP%d", 0, NULL, NULL ) && - !astKeyFields( this, "PV%d_%d", 0, NULL, NULL ) ) || - ( astKeyFields( this, "C%1dVAL%d", 0, NULL, NULL )) ){ - ret = FITSIRAF_ENCODING; - } else { - ret = FITSWCS_ENCODING; - } - -/* Otherwise, if the FitsChan contains any keywords with the format - RADECSYS. PROJPi or CmVALi keyword, then return "FITS-PC" encoding, - so long as there are no FITS-WCS equivalent keywords. */ - } else if( haswcs && !haspc && !hascd && ( - ( astKeyFields( this, "RADECSYS", 0, NULL, NULL ) && - !astKeyFields( this, "RADESYS", 0, NULL, NULL ) ) || - ( astKeyFields( this, "PROJP%d", 0, NULL, NULL ) && - !astKeyFields( this, "PV%d_%d", 0, NULL, NULL ) ) || - astKeyFields( this, "C%1dVAL%d", 0, NULL, NULL ) ) ) { - ret = FITSPC_ENCODING; - -/* Otherwise, if the FitsChan contains any keywords with the format - "CROTAi" then return "FITS-AIPS" encoding. */ - } else if( haswcs && astKeyFields( this, "CROTA%d", 0, NULL, NULL ) ){ - ret = FITSAIPS_ENCODING; - -/* Otherwise, if the FitsChan contains any keywords with the format - "CRVALi" then return "FITS-WCS" encoding. */ - } else if( haswcs && astKeyFields( this, "CRVAL%d", 0, NULL, NULL ) ){ - ret = FITSWCS_ENCODING; - -/* If none of these conditions is met, assume Native encoding. */ - } else { - ret = NATIVE_ENCODING; - } - -/* Reinstate the original current card index. */ - astSetCard( this, icard ); - } - -/* Return the encoding scheme. */ - return astOK ? ret : UNKNOWN_ENCODING; -} - -static void GetFiducialNSC( AstWcsMap *map, double *phi, double *theta, int *status ){ -/* -* Name: -* GetFiducialNSC - -* Purpose: -* Return the Native Spherical Coordinates at the fiducial point of a -* WcsMap projection. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void GetFiducialNSC( AstWcsMap *map, double *phi, double *theta, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns the native spherical coords corresponding at -* the fiducial point of a WcsMap. -* -* The values of parameters 1 and 2 on the longitude axis of the WcsMap -* are usually used as the native spherical coordinates of the -* fiducial point. The default values for these parameters are equal -* to the native spherical coordinates of the projection reference point. -* The exception is that a TPN projection always uses the default -* values, since the projection parameters are used to store polynomial -* coefficients. - -* Parameters: -* map -* Pointer to the WcsMap. -* phi -* Address of a location at which to return the native spherical -* longitude at the fiducial point (radians). -* theta -* Address of a location at which to return the native spherical -* latitude at the fiducial point (radians). -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int axlon; /* Index of longitude axis */ - -/* Initialise */ - *phi = AST__BAD; - *theta = AST__BAD; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* If this is not a TPN projection get he value of the required - projection parameters (the default values for these are equal to the - fixed native shperical coordinates at the projection reference point). */ - if( astGetWcsType( map ) != AST__TPN ) { - axlon = astGetWcsAxis( map, 0 ); - if( astGetPV( map, axlon, 0 ) != 0.0 ) { - *phi = AST__DD2R*astGetPV( map, axlon, 1 ); - *theta = AST__DD2R*astGetPV( map, axlon, 2 ); - } else { - *phi = astGetNatLon( map ); - *theta = astGetNatLat( map ); - } - -/* If this is a TPN projection, the returned values are always the fixed - native shperical coordinates at the projection reference point). */ - } else { - *phi = astGetNatLon( map ); - *theta = astGetNatLat( map ); - } -} - -static void GetFiducialPPC( AstWcsMap *map, double *x0, double *y0, int *status ){ -/* -* Name: -* GetFiducialPPC - -* Purpose: -* Return the IWC at the fiducial point of a WcsMap projection. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void GetFiducialPPC( AstWcsMap *map, double *x0, double *y0, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns the projection plane coords corresponding to -* the native spherical coords of the fiducial point of a FITS-WCS -* header. Note, projection plane coordinates (PPC) are equal to -* Intermediate World Coordinates (IWC) except for cases where the -* fiducial point does not correspond to the projection reference point. -* In these cases, IWC and PPC will be connected by a translation -* which ensures that the fiducial point corresponds to the origin of -* IWC. -* -* The values of parameters 1 and 2 on the longitude axis of -* the WcsMap are used as the native spherical coordinates of the -* fiducial point. The default values for these parameters are equal -* to the native spherical coordinates of the projection reference point. - -* Parameters: -* map -* Pointer to the WcsMap. -* x0 -* Address of a location at which to return the PPC X axis value at -* the fiducial point (radians). -* y0 -* Address of a location at which to return the PPC Y axis value at -* the fiducial point (radians). -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* Pointer to the native spherical PointSet */ - AstPointSet *pset2; /* Pointer to the intermediate world PointSet */ - double **ptr1; /* Pointer to pset1 data */ - double **ptr2; /* Pointer to pset2 data */ - int axlat; /* Index of latitude axis */ - int axlon; /* Index of longitude axis */ - int i; /* Loop count */ - int naxes; /* Number of axes */ - -/* Initialise */ - *x0 = AST__BAD; - *y0 = AST__BAD; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Save number of axes in the WcsMap. */ - naxes = astGetNin( map ); - -/* Allocate resources. */ - pset1 = astPointSet( 1, naxes, "", status ); - ptr1 = astGetPoints( pset1 ); - pset2 = astPointSet( 1, naxes, "", status ); - ptr2 = astGetPoints( pset2 ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Get the indices of the longitude and latitude axes in WcsMap. */ - axlon = astGetWcsAxis( map, 0 ); - axlat = astGetWcsAxis( map, 1 ); - -/* Use zero on all non-celestial axes. */ - for( i = 0; i < naxes; i++ ) ptr1[ i ][ 0 ] = 0.0; - -/* Get the native spherical coords at the fiducial point. */ - GetFiducialNSC( map, ptr1[ axlon ], ptr1[ axlat ], status ); - -/* Use the inverse WcsMap to convert the native longitude and latitude of - the fiducial point into PPC (x,y). */ - (void) astTransform( map, pset1, 0, pset2 ); - -/* Return the calculated PPC coords. */ - *x0 = ptr2[ axlon ][ 0 ]; - *y0 = ptr2[ axlat ][ 0 ]; - } - -/* Free resources. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); -} - -static int GetFiducialWCS( AstWcsMap *wcsmap, AstMapping *map2, int colon, - int colat, double *fidlon, double *fidlat, int *status ){ -/* -* Name: -* GetFiducialWCS - -* Purpose: -* Decide on the celestial coordinates of the fiducial point. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GetFiducialWCS( AstWcsMap wcsmap, AstMapping map2, int colon, -* int colat, double *fidlon, double *fidlat, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns the celestial longitude and latitude values -* to use for the fiducial point. These are the values stored in FITS -* keywords CRVALi. - -* Parameters: -* wcsmap -* The WcsMap which converts Projection Plane Coordinates into -* native spherical coordinates. The number of outputs from this -* Mapping should match the number of inputs to "map2". -* map2 -* The Mapping which converts native spherical coordinates into WCS -* coordinates. -* colon -* The index of the celestial longitude output from "map2". -* colat -* The index of the celestial latitude output from "map2". -* fidlon -* Pointer to a location at which to return the celestial longitude -* value at the fiducial point. The value is returned in radians. -* fidlat -* Pointer to a location at which to return the celestial latitude -* value at the fiducial point. The value is returned in radians. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the fiducial point longitude or latitude could not be -* determined. One otherwise. -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* Pointer to the native spherical PointSet */ - AstPointSet *pset2; /* Pointer to the WCS PointSet */ - double **ptr1; /* Pointer to pset1 data */ - double **ptr2; /* Pointer to pset2 data */ - int axlat; /* Index of latitude axis */ - int axlon; /* Index of longitude axis */ - int iax; /* Axis index */ - int naxin; /* Number of IWC axes */ - int naxout; /* Number of WCS axes */ - int ret; /* The returned FrameSet */ - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Allocate resources. */ - naxin = astGetNin( map2 ); - naxout = astGetNout( map2 ); - pset1 = astPointSet( 1, naxin, "", status ); - ptr1 = astGetPoints( pset1 ); - pset2 = astPointSet( 1, naxout, "", status ); - ptr2 = astGetPoints( pset2 ); - if( astOK ) { - -/* Get the indices of the latitude and longitude outputs in the WcsMap. - These are not necessarily the same as "colat" and "colon" because "map2" - may contain a PermMap. */ - axlon = astGetWcsAxis( wcsmap, 0 ); - axlat = astGetWcsAxis( wcsmap, 1 ); - -/* Use zero on all non-celestial axes. */ - for( iax = 0; iax < naxin; iax++ ) ptr1[ iax ][ 0 ] = 0.0; - -/* Get the native spherical coords at the fiducial point. */ - GetFiducialNSC( wcsmap, ptr1[ axlon ], ptr1[ axlat ], status ); - -/* The fiducial point in the celestial coordinate system is found by - transforming the fiducial point in native spherical co-ordinates - into absolute physical coordinates using map2. */ - (void) astTransform( map2, pset1, 1, pset2 ); - -/* Store the returned WCS values. */ - *fidlon = ptr2[ colon ][ 0 ]; - *fidlat = ptr2[ colat ][ 0 ]; - -/* Indicate if we have been succesfull. */ - if( astOK && *fidlon != AST__BAD && *fidlat != AST__BAD ) ret = 1; - } - -/* Free resources. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Return the result. */ - return ret; -} - -static const char *GetFitsSor( const char *string, int *status ) { -/* -* Name: -* GetFitsSor - -* Purpose: -* Get the string used to represent an AST spectral standard of rest. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* const char *GetFitsSor( const char *string, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns a pointer to a static string which is the -* FITS equivalent to a given SpecFrame StdOfRest value. - -* Parameters: -* string -* Pointer to a constant null-terminated string containing the -* SpecFrame StdOfRest value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a static null-terminated string containing the FITS -* equivalent to the supplied string. NULL is returned if the supplied -* string has no FITS equivalent. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked wth the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Compare the supplied string with SpecFrame value for which there is a - known FITS equivalent. */ - if( !strcmp( string, "Topocentric" ) ){ - result = "TOPOCENT"; - } else if( !strcmp( string, "Geocentric" )){ - result = "GEOCENTR"; - } else if( !strcmp( string, "Barycentric" )){ - result = "BARYCENT"; - } else if( !strcmp( string, "Heliocentric" )){ - result = "HELIOCEN"; - } else if( !strcmp( string, "LSRK" )){ - result = "LSRK"; - } else if( !strcmp( string, "LSRD" )){ - result = "LSRD"; - } else if( !strcmp( string, "Galactic" )){ - result = "GALACTOC"; - } else if( !strcmp( string, "Local_group" )){ - result = "LOCALGRP"; - } else if( !strcmp( string, "Source" )){ - result = "SOURCE"; - } else { - result = NULL; - } - -/* Return the answer. */ - return result; -} - -static double GetItem( double ****item, int i, int jm, char s, char *name, - const char *method, const char *class, int *status ){ -/* -* Name: -* GetItem - -* Purpose: -* Retrieve a value for a axis keyword value from a FitStore structure. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* double GetItem( double ****item, int i, int jm, char s, char *name, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The requested keyword value is retrieved from the specified array, -* at a position indicated by the axis and co-ordinate version. -* AST__BAD is returned if the array does not contain the requested -* value. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->crval) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (i), and the pointer locates an -* array of axis keyword values. These arrays of keyword values have -* one element for every pixel axis (j) or projection parameter (m). -* i -* The zero based intermediate axis index in the range 0 to 98. Set -* this to zero for keywords (e.g. CRPIX) which are not indexed by -* intermediate axis number. -* jm -* The zero based pixel axis index (in the range 0 to 98) or parameter -* index (in the range 0 to WCSLIB_MXPAR-1). Set this to zero for -* keywords (e.g. CRVAL) which are not indexed by either pixel axis or -* parameter number. -* s -* The co-ordinate version character (A to Z, or space), case -* insensitive -* name -* A string holding a name for the item of information. A NULL -* pointer may be supplied, in which case it is ignored. If a -* non-NULL pointer is supplied, an error is reported if the item -* of information has not been stored, and the supplied name is -* used to identify the information within the error message. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The required keyword value, or AST__BAD if no value has previously -* been stored for the keyword (or if an error has occurred). -*/ - -/* Local Variables: */ - double ret; /* Returned keyword value */ - int si; /* Integer co-ordinate version index */ - -/* Initialise */ - ret = AST__BAD; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Convert the character co-ordinate version into an integer index, and - check it is within range. The primary axis description (s=' ') is - given index zero. 'A' is 1, 'B' is 2, etc. */ - if( s == ' ' ) { - si = 0; - } else if( islower(s) ){ - si = (int) ( s - 'a' ) + 1; - } else { - si = (int) ( s - 'A' ) + 1; - } - if( si < 0 || si > 26 ) { - astError( AST__INTER, "GetItem(fitschan): AST internal error; " - "co-ordinate version '%c' ( char(%d) ) is invalid.", status, s, s ); - -/* Check the intermediate axis index is within range. */ - } else if( i < 0 || i > 98 ) { - astError( AST__INTER, "GetItem(fitschan): AST internal error; " - "intermediate axis index %d is invalid.", status, i ); - -/* Check the pixel axis or parameter index is within range. */ - } else if( jm < 0 || jm > 99 ) { - astError( AST__INTER, "GetItem(fitschan): AST internal error; " - "pixel axis or parameter index %d is invalid.", status, jm ); - -/* Otherwise, if the array holding the required keyword is not null, - proceed... */ - } else if( *item ){ - -/* Find the number of coordinate versions in the supplied array. - Only proceed if it encompasses the requested co-ordinate - version. */ - if( astSizeOf( (void *) *item )/sizeof(double **) > si ){ - -/* Find the number of intermediate axes in the supplied array. - Only proceed if it encompasses the requested intermediate axis. */ - if( astSizeOf( (void *) (*item)[si] )/sizeof(double *) > i ){ - -/* Find the number of pixel axes or parameters in the supplied array. - Only proceed if it encompasses the requested index. */ - if( astSizeOf( (void *) (*item)[si][i] )/sizeof(double) > jm ){ - -/* Return the required keyword value. */ - ret = (*item)[si][i][jm]; - } - } - } - } - -/* If required, report an error if the requested item of information has - not been stored. */ - if( ret == AST__BAD && name && astOK ){ - astError( AST__NOFTS, "%s(%s): No value can be found for %s.", status, - method, class, name ); - } - return ret; -} - -static int GetMaxJM( double ****item, char s, int *status ){ -/* -* Name: -* GetMaxJM - -* Purpose: -* Return the largest pixel axis or parameter index stored for an -* numerical axis keyword value in a FitStore structure. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GetMaxJM( double ****item, char s, int *status) - -* Class Membership: -* FitsChan member function. - -* Description: -* The number of pixel axis numbers or projection parameters stored for -* a specified axis keyword is found and returned. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->crpix) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (i), and the pointer locates an -* array of axis keyword values. These arrays of keyword values have -* one element for every pixel axis (j) or projection parameter (m). -* s -* The co-ordinate version character (A to Z, or space), case -* insensitive -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The maximum pixel axis number or projection parameter index (zero -* based). -*/ - -/* Local Variables: */ - int jm; /* Number of parameters/pixel axes */ - int i; /* Intermediate axis index */ - int ret; /* Returned axis index */ - int si; /* Integer co-ordinate version index */ - -/* Initialise */ - ret = -1; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* If the array holding the required keyword is not null, proceed... */ - if( *item ){ - -/* Convert the character co-ordinate version into an integer index, and - check it is within range. The primary axis description (s=' ') is - given index zero. 'A' is 1, 'B' is 2, etc. */ - if( s == ' ' ) { - si = 0; - } else if( islower(s) ){ - si = (int) ( s - 'a' ) + 1; - } else { - si = (int) ( s - 'A' ) + 1; - } - if( si < 0 || si > 26 ) { - astError( AST__INTER, "GetMaxJM(fitschan): AST internal error; " - "co-ordinate version '%c' ( char(%d) ) is invalid.", status, s, s ); - return ret; - } - -/* Find the number of coordinate versions in the supplied array. - Only proceed if it encompasses the requested co-ordinate - version. */ - if( astSizeOf( (void *) *item )/sizeof(double **) > si ){ - -/* Check that the pointer to the array of intermediate axis values is not null. */ - if( (*item)[si] ){ - -/* Loop round each used element in this array. */ - for( i = 0; i < astSizeOf( (void *) (*item)[si] )/sizeof(double *); - i++ ){ - if( (*item)[si][i] ){ - -/* Get the size of the pixel axis/projection parameter array for the - current intermediate axis, and subtract 1 to get the largest index. */ - jm = astSizeOf( (void *) (*item)[si][i] )/sizeof(double) - 1; - -/* Ignore any trailing unused (AST__BAD) values. */ - while( jm >= 0 && (*item)[si][i][jm] == AST__BAD ) jm--; - -/* Update the returned value if the current value is larger. */ - if( jm > ret ) ret = jm; - } - } - } - } - } - return ret; -} - -static int GetMaxJMC( char *****item, char s, int *status ){ -/* -* Name: -* GetMaxJMC - -* Purpose: -* Return the largest pixel axis or parameter index stored for an -* character-valued axis keyword value in a FitStore structure. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GetMaxJMC( char *****item, char s, int *status) - -* Class Membership: -* FitsChan member function. - -* Description: -* The number of pixel axis numbers or projection parameters stored for -* a specified axis keyword is found and returned. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->ctype) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (i), and the pointer locates an -* array of axis keyword string pointers. These arrays of keyword -* string pointers have one element for every pixel axis (j) or -* projection parameter (m). -* s -* The co-ordinate version character (A to Z, or space), case -* insensitive -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The maximum pixel axis number or projection parameter index (zero -* based). -*/ - -/* Local Variables: */ - int jm; /* Number of parameters/pixel axes */ - int i; /* Intermediate axis index */ - int ret; /* Returned axis index */ - int si; /* Integer co-ordinate version index */ - -/* Initialise */ - ret = -1; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* If the array holding the required keyword is not null, proceed... */ - if( *item ){ - -/* Convert the character co-ordinate version into an integer index, and - check it is within range. The primary axis description (s=' ') is - given index zero. 'A' is 1, 'B' is 2, etc. */ - if( s == ' ' ) { - si = 0; - } else if( islower(s) ){ - si = (int) ( s - 'a' ) + 1; - } else { - si = (int) ( s - 'A' ) + 1; - } - if( si < 0 || si > 26 ) { - astError( AST__INTER, "GetMaxJMC(fitschan): AST internal error; " - "co-ordinate version '%c' ( char(%d) ) is invalid.", status, s, s ); - return ret; - } - -/* Find the number of coordinate versions in the supplied array. - Only proceed if it encompasses the requested co-ordinate - version. */ - if( astSizeOf( (void *) *item )/sizeof(char ***) > si ){ - -/* Check that the pointer to the array of intermediate axis values is not null. */ - if( (*item)[si] ){ - -/* Loop round each used element in this array. */ - for( i = 0; i < astSizeOf( (void *) (*item)[si] )/sizeof(char **); - i++ ){ - if( (*item)[si][i] ){ - -/* Get the size of the pixel axis/projection parameter array for the - current intermediate axis, and subtract 1 to get the largest index. */ - jm = astSizeOf( (void *) (*item)[si][i] )/sizeof(char *) - 1; - -/* Ignore any trailing unused (NULL) values. */ - while( jm >= 0 && (*item)[si][i][jm] == NULL ) jm--; - -/* Update the returned value if the current value is larger. */ - if( jm > ret ) ret = jm; - } - } - } - } - } - return ret; -} - -static int GetMaxI( double ****item, char s, int *status ){ -/* -* Name: -* GetMaxI - -* Purpose: -* Return the largest WCS axis index stored for an axis keyword value in -* a FitStore structure. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GetMaxJM( double ****item, char s) - -* Class Membership: -* FitsChan member function. - -* Description: -* The number of Wcs axis numbers stored for a specified axis keyword is -* found and returned. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->crval) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (i), and the pointer locates an -* array of axis keyword values. These arrays of keyword values have -* one element for every pixel axis (j) or projection parameter (m). -* s -* The co-ordinate version character (A to Z, or space), case -* insensitive - -* Returned Value: -* The maximum WCS axis index (zero based). -*/ - -/* Local Variables: */ - int ret; /* Returned axis index */ - int si; /* Integer co-ordinate version index */ - -/* Initialise */ - ret = -1; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* If the array holding the required keyword is not null, proceed... */ - if( *item ){ - -/* Convert the character co-ordinate version into an integer index, and - check it is within range. The primary axis description (s=' ') is - given index zero. 'A' is 1, 'B' is 2, etc. */ - if( s == ' ' ) { - si = 0; - } else if( islower(s) ){ - si = (int) ( s - 'a' ) + 1; - } else { - si = (int) ( s - 'A' ) + 1; - } - if( si < 0 || si > 26 ) { - astError( AST__INTER, "GetMaxI(fitschan): AST internal error; " - "co-ordinate version '%c' ( char(%d) ) is invalid.", status, s, s ); - return ret; - } - -/* Find the number of coordinate versions in the supplied array. - Only proceed if it encompasses the requested co-ordinate - version. */ - if( astSizeOf( (void *) *item )/sizeof(double **) > si ){ - -/* Check that the pointer to the array of intermediate axis values is not null. */ - if( (*item)[si] ){ - -/* Get the size of the intermediate axis array and subtract 1 to get the largest - index. */ - ret = astSizeOf( (void *) (*item)[si] )/sizeof(double *) - 1; - -/* Ignore any trailing unused (NULL) values. */ - while( ret >= 0 && (*item)[si][ret] == NULL ) ret--; - } - } - } - return ret; -} - -static char GetMaxS( double ****item, int *status ){ -/* -* Name: -* GetMaxS - -* Purpose: -* Return the largest (i.e. closest to Z) coordinate version character -* stored for a axis keyword value in a FitStore structure. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* char GetMaxS( double ****item, int *status) - -* Class Membership: -* FitsChan member function. - -* Description: -* The largest (i.e. closest to Z) coordinate version character -* stored for a axis keyword value in a FitStore structure is found -* and returned. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->crval) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (i), and the pointer locates an -* array of axis keyword values. These arrays of keyword values have -* one element for every pixel axis (j) or projection parameter (m). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The highest coordinate version character. -*/ - -/* Local Variables: */ - char ret; /* Returned axis index */ - int si; /* Integer index into alphabet */ - -/* Initialise */ - ret = ' '; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* If the array holding the required keyword is not null, proceed... */ - if( *item ){ - -/* Find the length of this array, and subtract 1 to get the largest index - in the array. */ - si = astSizeOf( (void *) *item )/sizeof(double **) - 1; - -/* Ignore any trailing null (i.e. unused) values. */ - while( si >= 0 && !(*item)[si] ) si--; - -/* Store the corresponding character */ - if( si == 0 ) { - ret = ' '; - } else { - ret = 'A' + si - 1; - } - } - return ret; -} - -static char *GetItemC( char *****item, int i, int jm, char s, char *name, - const char *method, const char *class, int *status ){ -/* -* Name: -* GetItemC - -* Purpose: -* Retrieve a string value for a axis keyword value from a FitStore -* structure. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* char *GetItemC( char *****item, int i, int jm, char s, char *name, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The requested keyword string value is retrieved from the specified -* array, at a position indicated by the axis and co-ordinate version. -* NULL is returned if the array does not contain the requested -* value. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->ctype) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (i), and the pointer locates an -* array of axis keyword string pointers. These arrays of keyword -* string pointers have one element for every pixel axis (j) or -* projection parameter (m). -* i -* The zero based intermediate axis index in the range 0 to 98. Set -* this to zero for keywords (e.g. CRPIX) which are not indexed by -* intermediate axis number. -* jm -* The zero based pixel axis index (in the range 0 to 98) or parameter -* index (in the range 0 to WCSLIB__MXPAR-1). Set this to zero for -* keywords (e.g. CTYPE) which are not indexed by either pixel axis or -* parameter number. -* s -* The co-ordinate version character (A to Z, or space), case -* insensitive -* name -* A string holding a name for the item of information. A NULL -* pointer may be supplied, in which case it is ignored. If a -* non-NULL pointer is supplied, an error is reported if the item -* of information has not been stored, and the supplied name is -* used to identify the information within the error message. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the required keyword string value, or NULL if no value -* has previously been stored for the keyword (or if an error has -* occurred). -*/ - -/* Local Variables: */ - char *ret; /* Returned keyword value */ - int si; /* Integer co-ordinate version index */ - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Convert the character co-ordinate version into an integer index, and - check it is within range. The primary axis description (s=' ') is - given index zero. 'A' is 1, 'B' is 2, etc. */ - if( s == ' ' ) { - si = 0; - } else if( islower(s) ){ - si = (int) ( s - 'a' ) + 1; - } else { - si = (int) ( s - 'A' ) + 1; - } - if( si < 0 || si > 26 ) { - astError( AST__INTER, "GetItemC(fitschan): AST internal error; " - "co-ordinate version '%c' ( char(%d) ) is invalid.", status, s, s ); - -/* Check the intermediate axis index is within range. */ - } else if( i < 0 || i > 98 ) { - astError( AST__INTER, "GetItemC(fitschan): AST internal error; " - "intermediate axis index %d is invalid.", status, i ); - -/* Check the pixel axis or parameter index is within range. */ - } else if( jm < 0 || jm > 99 ) { - astError( AST__INTER, "GetItem(fitschan): AST internal error; " - "pixel axis or parameter index %d is invalid.", status, jm ); - -/* Otherwise, if the array holding the required keyword is not null, - proceed... */ - } else if( *item ){ - -/* Find the number of coordinate versions in the supplied array. - Only proceed if it encompasses the requested co-ordinate - version. */ - if( astSizeOf( (void *) *item )/sizeof(char ***) > si ){ - -/* Find the number of intermediate axes in the supplied array. - Only proceed if it encompasses the requested intermediate axis. */ - if( astSizeOf( (void *) (*item)[si] )/sizeof(char **) > i ){ - -/* Find the number of pixel axes or parameters in the supplied array. - Only proceed if it encompasses the requested index. */ - if( astSizeOf( (void *) (*item)[si][i] )/sizeof(char *) > jm ){ - -/* Return the required keyword value. */ - ret = (*item)[si][i][jm]; - } - } - } - } - -/* If required, report an error if the requested item of information has - not been stored. */ - if( !ret && name && astOK ){ - astError( AST__NOFTS, "%s(%s): No value can be found for %s.", status, - method, class, name ); - } - return ret; -} - -static AstFitsTable *GetNamedTable( AstFitsChan *this, const char *extname, - int extver, int extlevel, int report, - const char *method, int *status ){ - -/* -* Name: -* GetNamedTable - -* Purpose: -* Return a FitsTable holding the contents of a named FITS binary table. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* AstFitsTable *GetNamedTable( AstFitsChan *this, const char *extname, -* int extver, int extlevel, int report, -* const char *method, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* If a table source function has been registered with FitsChan (using -* astTableSource), invoke it to read the required table from the external -* FITS file. If the extension is available in the FITS file, this will -* put a FitsTable into the "tables" KeyMap in the FitsChan structure, -* using the FITS extension name as the key - this will replace any -* FitsTable already present in the KeyMap with the same key. Finally, -* return a pointer to the FitsTable stored in the KeyMap - if any. -* -* This strategy allows the astPutTables or astPutTable method to be used -* as an alternative to registering a table source function with the -* FitsChan. Note, any table read using the source function is used -* in preference to any table stored in the FitsChan by an earlier call -* to astPutTables/astPutTable. - -* Parameters: -* this -* Pointer to the FitsChan. -* extname -* The key associated with the required table - should be the name -* of the FITS extension containing the binary table. -* extver -* The FITS "EXTVER" value for the required table. -* extlevel -* The FITS "EXTLEVEL" value for the required table. -* report -* If non-zero, report an error if the named table is not available. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the FitsTable, or NULL if the table is not avalable. -*/ - -/* Local Variables: */ - AstFitsTable *ret; - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Fitrst attempt to read the required table from the external FITS file. - Only proceed if table source function and wrapper have been supplied - using astTableSource. */ - if( this->tabsource && this->tabsource_wrap ){ - -/* Invoke the table source function asking it to place the required FITS - table in the FitsChan. This is an externally supplied function which may - not be thread-safe, so lock a mutex first. Note, a cloned FitsChan pointer - is sent to the table source function since the table source function will - annul the supplied FitsChan pointer. Also store the channel data - pointer in a global variable so that it can be accessed in the source - function using macro astChannelData. */ - astStoreChannelData( this ); - LOCK_MUTEX2; - ( *this->tabsource_wrap )( this->tabsource, astClone( this ), extname, - extver, extlevel, status ); - UNLOCK_MUTEX2; - } - -/* Now get a pointer to the required FitsTable, stored as an entry in the - "tables" KeyMap. Report an error if required. */ - if( ! (this->tables) || !astMapGet0A( this->tables, extname, &ret ) ){ - if( report && astOK ) { - astError( AST__NOTAB, "%s(%s): Failed to read FITS binary table " - "from extension '%s' (extver=%d, extlevel=%d).", status, - method, astGetClass( this ), extname, extver, extlevel ); - } - } - -/* Return the result. */ - return ret; -} - -static AstKeyMap *GetTables( AstFitsChan *this, int *status ) { - -/* -*++ -* Name: -c astGetTables -f AST_GETTABLES - -* Purpose: -* Retrieve any FitsTables currently in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" -c AstKeyMap *astGetTables( AstFitsChan *this ) -f RESULT = AST_GETTABLES( THIS, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -* If the supplied FitsChan currently contains any tables, then this -* function returns a pointer to a KeyMap. Each entry in the KeyMap -* is a pointer to a FitsTable holding the data for a FITS binary -* table. The key used to access each entry is the FITS extension -* name in which the table should be stored. -* -* Tables can be present in a FitsChan as a result either of using the -c astPutTable (or astPutTables) -f AST_PUTTABLE (or AST_PUTTABLES) -* method to store existing tables in the FitsChan, or of using the -c astWrite -f AST_WRITE -* method to write a FrameSet to the FitsChan. For the later case, if -* the FitsChan "TabOK" attribute is positive and the FrameSet requires -* a look-up table to describe one or more axes, then the "-TAB" -* algorithm code described in FITS-WCS paper III is used and the table -* values are stored in the FitsChan in the form of a FitsTable object -* (see the documentation for the "TabOK" attribute). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetTables() -f AST_GETTABLES = INTEGER -* A pointer to a deep copy of the KeyMap holding the tables currently -* in the FitsChan, or -c NULL -f AST__NULL -* if the FitsChan does not contain any tables. The returned -* pointer should be annulled using -c astAnnul -f AST_ANNUL -* when no longer needed. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstKeyMap *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the FitsChan contains any tables, return a pointer to a copy of - the KeyMap containing them. Otherwise, return a NULL pointer. */ - if( this->tables && astMapSize( this->tables ) > 0 ) { - result = astCopy( this->tables ); - } - -/* Return the result. */ - return result; -} - -static int GetUsedPolyTan( AstFitsChan *this, AstFitsChan *out, int latax, - int lonax, char s, const char *method, - const char *class, int *status ){ -/* -* Name: -* GetUsedPolyTan - -* Purpose: -* Get the value to use for the PolyTan attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GetUsedPolyTan( AstFitsChan *this, AstFitsChan *out, int latax, -* int lonax, char s, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* If the PolyTan attribute is zero or positive, then its value is -* returned. If it is negative, the supplied FitsChan is searched for -* keywords of the form PVi_m. If any are found on the latitude axis, -* or if any are found on the longitude axis with "m" > 4, +1 is -* returned (meaning "use the distorted TAN conventio"). Otherwise 0 -* is returned (meaning "use the standard TAN convention"). -* -* If all the PVi_m values for m > 0 on either axis are zero, a warning is -* issued and zero is returned. - -* Parameters: -* this -* Pointer to the FitsChan. -* out -* Pointer to a secondary FitsChan. If the PV values in "this" are -* found to be unusable, they will be marked as used in both "this" -* and "out". -* latax -* The one-based index of the latitude axis within the FITS header. -* lonax -* The one-based index of the longitude axis within the FITS header. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The attribute value to use. - -* Notes: -* - A value of zero is returned if an error has already occurred -* or if an error occurs for any reason within this function. -*/ - -/* Local Variables... */ - char template[ 20 ]; - double pval; - int lbnd_lat; - int lbnd_lon; - int m; - int nfound1; - int nfound2; - int ok; - int ret; - int ubnd_lat; - int ubnd_lon; - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Get the value of the PolyTan attribute. */ - ret = astGetPolyTan( this ); - -/* If it is negative, we examine the FitsChan to see which convention to - use. */ - if( ret < 0 ) { - ret = 0; - -/* Search the FitsChan for latitude PV cards. */ - if( s != ' ' ) { - sprintf( template, "PV%d_%%d%c", latax, s ); - } else { - sprintf( template, "PV%d_%%d", latax ); - } - nfound1 = astKeyFields( this, template, 1, &ubnd_lat, &lbnd_lat ); - -/* Search the FitsChan for longitude PV cards. */ - if( s != ' ' ) { - sprintf( template, "PV%d_%%d%c", lonax, s ); - } else { - sprintf( template, "PV%d_%%d", lonax ); - } - nfound2 = astKeyFields( this, template, 1, &ubnd_lon, &lbnd_lon ); - -/* If any were found with "m" value greater than 4, assume the distorted - TAN convention is in use. Otherwise assume the stdanrd TAN convention is - in use. */ - if( nfound1 || ( nfound2 && ubnd_lon > 4 ) ) ret = 1; - -/* If the distorted TAN convention is to be used, check that at least one - of the PVi_m values is non-zero on each axis. We ignore the PVi_0 - (constant) terms in this check. */ - if( ret > 0 ) { - -/* Do the latitude axis first, skipping the first (constant) term. Assume - that all latitude pV values are zero until we find one that is not. */ - ok = 0; - for( m = 1; m <= ubnd_lat && !ok; m++ ) { - -/* Form the PVi_m keyword name. */ - if( s != ' ' ) { - sprintf( template, "PV%d_%d%c", latax, m, s ); - } else { - sprintf( template, "PV%d_%d", latax, m ); - } - -/* Get it's value. */ - if( ! GetValue( this, template, AST__FLOAT, &pval, 0, 0, - method, class, status ) ) { - -/* If the PVi_m header is not present in the FitsChan, use a default value. */ - pval = ( m == 1 ) ? 1.0 : 0.0; - } - -/* If the PVi_m header has a non-zero value, we can leave the loop. */ - if( pval != 0.0 ) ok = 1; - } - -/* If all the latitude PVi_m values are zero, issue a warning and return - zero, indicating that a simple undistorted TAN projection should be used. */ - if( !ok ) { - Warn( this, "badpv", "This FITS header describes a distorted TAN " - "projection, but all the distortion coefficients (the " - "PVi_m headers) on the latitude axis are zero.", method, - class, status ); - ret = 0; - - -/* Also, delete the PV keywords so that no attempt is made to use them. */ - for( m = 1; m <= ubnd_lat; m++ ) { - if( s != ' ' ) { - sprintf( template, "PV%d_%d%c", latax, m, s ); - } else { - sprintf( template, "PV%d_%d", latax, m ); - } - astClearCard( this ); - if( FindKeyCard( this, template, method, class, status ) ) { - DeleteCard( this, method, class, status ); - } - } - -/* Otherwise, do the same check for the longitude axis. */ - } else { - ok = 0; - for( m = 1; m <= ubnd_lon && !ok; m++ ) { - - if( s != ' ' ) { - sprintf( template, "PV%d_%d%c", lonax, m, s ); - } else { - sprintf( template, "PV%d_%d", lonax, m ); - } - - if( ! GetValue( this, template, AST__FLOAT, &pval, 0, 0, - method, class, status ) ) { - - pval = ( m == 1 ) ? 1.0 : 0.0; - } - - if( pval != 0.0 ) ok = 1; - } - - if( !ok ) { - Warn( this, "badpv", "This FITS header describes a distorted TAN " - "projection, but all the distortion coefficients (the " - "PVi_m headers) on the longitude axis are zero.", method, - class, status ); - ret = 0; - - for( m = 1; m <= ubnd_lon; m++ ) { - if( s != ' ' ) { - sprintf( template, "PV%d_%d%c", lonax, m, s ); - } else { - sprintf( template, "PV%d_%d", lonax, m ); - } - astClearCard( this ); - if( FindKeyCard( this, template, method, class, status ) ) { - DeleteCard( this, method, class, status ); - } - } - } - } - } - } - -/* Return the result. */ - return astOK ? ret : 0; -} - -static int GoodWarns( const char *value, int *status ){ -/* -* Name: -* GoodWarns - -* Purpose: -* Checks a string to ensure it is a legal list of warning conditions. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GoodWarns( const char *value, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function checks the supplied string to ensure it contains a space -* separated list of zero or more recognised warning conditions. An -* error is reported if it does not. - -* Parameters: -* value -* The string to check. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the supplied string is not a legal list of -* conditions, or if an error has already occurred. One is returned -* otherwise. -*/ - -/* Local Variables: */ - char *b; /* Pointer to next buffer element */ - const char *c ; /* Pointer to next character */ - char buf[100]; /* Buffer for condition name */ - int inword; /* Are we in a word? */ - int n; /* Number of conditions supplied */ - int ret; /* Returned value */ - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Report an error and return if the pointer is null. */ - if( !value ){ - astError( AST__ATTIN, "astSetWarnings(fitschan): Null pointer " - "supplied for the Warnings attribute." , status); - return ret; - } - -/* Initialise things */ - inword = 0; - buf[ 0 ] = ' '; - b = buf + 1; - n = 0; - ret = 1; - -/* Loop round each character in the supplied string. */ - for( c = value ; c < value + strlen( value ) + 1; c++ ){ - -/* Have we found the first space or null following a word? */ - if( ( !(*c) || isspace( *c ) ) && inword ){ - -/* Add a space to the end of the buffer and terminate it. */ - *(b++) = ' '; - *b = 0; - -/* Check the word is legal by searching for it in the string of all - conditions, which should be lower case and have spaces at start and end. - The word in the buffer is delimited by spaces and so it will not match - a substring within a condition. If it is legal increment the number of - conditions found. */ - if( strstr( ALLWARNINGS, buf ) ){ - n++; - -/* Otherwise, report an error and break. */ - } else { - ret = 0; - *(--b) = 0; - astError( AST__ATTIN, "astSetWarnings(fitschan): Unknown " - "condition '%s' specified when setting the Warnings " - "attribute.", status, buf + 1 ); - break; - } - -/* Reset the pointer to the next character in the buffer, retaining the - initial space in the buffer. */ - b = buf + 1; - -/* Indicate we are no longer in a word. */ - inword = 0; - -/* Have we found the first non-space, non-null character following a space? */ - } else if( *c && !isspace( *c ) && !inword ){ - -/* Note we are now in a word. */ - inword = 1; - } - -/* If we are in a word, copy the lowercase character to the buffer. */ - if( inword ) *(b++) = tolower( *c ); - } - return ret; -} - -static AstMapping *GrismSpecWcs( char *algcode, FitsStore *store, int i, - char s, AstSpecFrame *specfrm, - const char *method, const char *class, int *status ) { -/* -* Name: -* GrismSpecWcs - -* Purpose: -* Create a Mapping describing a FITS-WCS grism-dispersion algorithm - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *GrismSpecWcs( char *algcode, FitsStore *store, int i, char s, -* AstSpecFrame *specfrm, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function uses the contents of the supplied FitsStore to create -* a Mapping which goes from Intermediate World Coordinate (known as "w" -* in the context of FITS-WCS paper III) to the spectral system -* described by the supplied SpecFrame. -* -* The returned Mapping implements the grism "GRA" and "GRI" algorithms -* described in FITS-WCS paper III. - -* Parameters: -* algcode -* Pointer to a string holding the code for the required algorithm -* ("-GRA" or "-GRI"). -* store -* Pointer to the FitsStore structure holding the values to use for -* the WCS keywords. -* i -* The zero-based index of the spectral axis within the FITS header -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* specfrm -* Pointer to the SpecFrame. This specifies the "S" system - the -* system in which the CRVAL kewyords (etc) are specified. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a Mapping, or NULL if an error occurs. -*/ - -/* Local Variables: */ - AstFrameSet *fs; - AstMapping *gmap; - AstMapping *map1; - AstMapping *map2; - AstMapping *map2a; - AstMapping *map2b; - AstMapping *ret; - AstMapping *smap; - AstSpecFrame *wfrm; - double crv; - double dg; - double gcrv; - double pv; - double wcrv; - -/* Check the global status. */ - ret = NULL; - if( !astOK ) return ret; - -/* The returned Mapping will be a CmpMap including a GrismMap. This - GrismMap will produced wavelength as output. We also need the Mapping - from wavelength to the system represented by the supplied SpecFrame. - To get this, we first create a copy of the supplied SpecFrame (in order - to inherit the standard of rest, epoch, etc), and set its System to - wavlength in vacuum (for "-GRI") or air (for "-GRA"), and then use - astConvert to get the Mapping from the SpecFrame system to relevant - form of wavelength. */ - wfrm = astCopy( specfrm ); - astSetSystem( wfrm, strcmp( algcode, "-GRI" )?AST__AIRWAVE:AST__WAVELEN ); - astSetUnit( wfrm, 0, "m" ); - fs = astConvert( specfrm, wfrm, "" ); - if( fs ) { - smap = astGetMapping( fs, AST__BASE, AST__CURRENT ); - fs = astAnnul( fs ); - -/* Get the CRVAL value for the spectral axis (this will be in the S system). */ - crv = GetItem( &(store->crval), i, 0, s, NULL, method, class, status ); - if( crv == AST__BAD ) crv = 0.0; - -/* Convert it to the wavelength system (vacuum or air) in metres. */ - astTran1( smap, 1, &crv, 1, &wcrv ); - -/* Create a GrismMap, and then use the projection parameters stored in - the FitsStore to set its attributes (convert degrees values to radians - and supply the defaults specified in FITS-WCS paper III). The FITS - paper specifies units in which these parameters should be stored in a - FITS header - distances are in metres and angles in degrees. */ - gmap = (AstMapping *) astGrismMap( "", status ); - pv = GetItem( &(store->pv), i, 0, s, NULL, method, class, status ); - astSetGrismG( gmap, ( pv != AST__BAD )?pv:0.0 ); - pv = GetItem( &(store->pv), i, 1, s, NULL, method, class, status ); - astSetGrismM( gmap, ( pv != AST__BAD )?(int) ( pv + 0.5 ):0); - pv = GetItem( &(store->pv), i, 2, s, NULL, method, class, status ); - astSetGrismAlpha( gmap, ( pv != AST__BAD )?pv*AST__DD2R:0.0 ); - pv = GetItem( &(store->pv), i, 3, s, NULL, method, class, status ); - astSetGrismNR( gmap, ( pv != AST__BAD )?pv:1.0 ); - pv = GetItem( &(store->pv), i, 4, s, NULL, method, class, status ); - astSetGrismNRP( gmap, ( pv != AST__BAD )?pv:0.0 ); - pv = GetItem( &(store->pv), i, 5, s, NULL, method, class, status ); - astSetGrismEps( gmap, ( pv != AST__BAD )?pv*AST__DD2R:0.0 ); - pv = GetItem( &(store->pv), i, 6, s, NULL, method, class, status ); - astSetGrismTheta( gmap, ( pv != AST__BAD )?pv*AST__DD2R:0.0 ); - -/* Store the reference wavelength found above as an attribute of the - GrismMap. */ - astSetGrismWaveR( gmap, wcrv ); - -/* Invert the GrismMap to get the (Wavelength -> grism parameter) Mapping, and - then combine it with the (S -> Wavelength) Mapping to get the (S -> grism - parameter) Mapping. */ - astInvert( gmap ); - map1 = (AstMapping *) astCmpMap( smap, gmap, 1, "", status ); - -/* Convert the reference point value from wavelength to grism parameter. */ - astTran1( gmap, 1, &wcrv, 1, &gcrv ); - -/* Find the rate of change of grism parameter with respect to the S - system at the reference point, dg/dS. */ - dg = astRate( map1, &crv, 0, 0 ); - if( dg != AST__BAD && dg != 0.0 ) { - -/* FITS-WCS paper II requires headers to be constructed so that dS/dw = 1.0 - at the reference point. Therefore dg/dw = dg/dS. Create a WinMap which - scales and shifts the "w" value to get the grism parameter value. */ - map2a = (AstMapping *) astZoomMap( 1, dg, "", status ); - map2b = (AstMapping *) astShiftMap( 1, &gcrv, "", status ); - map2 = (AstMapping *) astCmpMap( map2a, map2b, 1, "", status ); - map2a = astAnnul( map2a ); - map2b = astAnnul( map2b ); - -/* The Mapping to be returned is the concatenation of the above Mapping - (from w to g) with the Mapping from g to S. */ - astInvert( map1 ); - ret = (AstMapping *) astCmpMap( map2, map1, 1, "", status ); - map2 = astAnnul( map2 ); - } - map1 = astAnnul( map1 ); - smap = astAnnul( smap ); - gmap = astAnnul( gmap ); - } - wfrm = astAnnul( wfrm ); - -/* Return the result */ - return ret; -} - -static int KeyFields( AstFitsChan *this, const char *filter, int maxfld, - int *ubnd, int *lbnd, int *status ){ - -/* -*+ -* Name: -* astKeyFields - -* Purpose: -* Find the ranges taken by integer fields within the keyword names -* in a FitsChan. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* int astKeyFields( AstFitsChan *this, const char *filter, int maxfld, -* int *ubnd, int *lbnd ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function returns the number of cards within a FitsChan which -* refer to keywords which match the supplied filter template. If the -* filter contains any integer field specifiers (e.g. "%d", "%3d", etc), -* it also returns the upper and lower bounds found for the integer -* fields. - -* Parameters: -* this -* Pointer to the FitsChan. -* filter -* The filter string. -* maxfld -* The size of the "ubnd" and "lbnd" arrays. -* ubnd -* A pointer to an integer array in which to return the -* upper bound found for each integer field in the filter. -* They are stored in the order in which they occur in the filter. -* If the filter contains too many fields to fit in the supplied -* array, the excess trailing fields are ignored. -* lbnd -* A pointer to an integer array in which to return the -* lower bound found for each integer field in the filter. - -* Returned Value: -* astKeyFields() -* The total number of cards matching the supplied filter in the -* FitsChan. - -* Filter Syntax: -* - The criteria for a keyword name to match a filter template are -* as follows: -* - All characters in the template other than "%" (and the field width -* and type specifiers which follow a "%") must be matched by an -* identical character in the test string. - - If a "%" occurs in the template, then the next character in the -* template should be a single digit specifying a field width. If it is -* zero, then the test string may contain zero or more matching characters. -* Otherwise, the test string must contain exactly the specified number -* of matching characters (i.e. 1 to 9). The field width digit may be -* omitted, in which case the test string must contain one or more matching -* characters. The next character in the template specifies the type of -* matching characters and must be one of "d", "c" or "f". Decimal digits -* are matched by "d", all upper (but not lower) case alphabetical -* characters are matched by "c", and all characters which may legally be -* found within a FITS keyword name are matched by "f". - -* Examples: -* - The filter "CRVAL1" accepts the single keyword CRVAL1. -* - The filter "CRVAL%1d" accepts the single keyword CRVAL0, CRVAL1, -* CRVAL2, up to CRVAL9. -* - The filter "CRVAL%d" accepts any keyword consisting of the string -* "CRVAL" followed by any integer value. -* - The filter "CR%0s1" accepts any keyword starting with the string "CR" -* and ending with the character "1" (including CR1). - -* Notes: -* - The entire FitsChan is searched, irrespective of the setting of -* the Card attribute. -* - If "maxfld" is supplied as zero, "ubnd" and "lbnd" are ignored, -* but the number of matching cards is still returned as the function value. -* - If no matching cards are found in the FitsChan, or if there are no -* integer fields in the filter, then the lower and upper bounds are -* returned as zero and -1 (i.e. reversed). -* - If an error has already occured, or if this function should fail -* for any reason, a value of zero is returned for the function value, -* and the lower and upper bounds are set to zero and -1. -*- -*/ - -/* Local Variables: */ - const char *class; /* Object class */ - const char *method; /* Method name */ - int *fields; /* Pointer to array of field values */ - int i; /* Field index */ - int icard; /* Index of current card on entry */ - int nmatch; /* No. of matching cards */ - int nf; /* No. of integer fields in the filter */ - int nfld; /* No. of integer fields in current keyword name */ - -/* Initialise the returned values. */ - nmatch = 0; - for( i = 0; i < maxfld; i++ ){ - lbnd[ i ] = 0; - ubnd[ i ] = -1; - } - nf = 0; - -/* Check the global error status. */ - if ( !astOK || !filter ) return nf; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Store the method name and object class for use in error messages. */ - method = "astKeyFields"; - class = astGetClass( this ); - -/* Count the number of integer fields in the filter string. */ - nf = CountFields( filter, 'd', method, class, status ); - -/* If this is larger than the supplied arrays, use the size of the arrays - instead. */ - if( nf > maxfld ) nf = maxfld; - -/* Allocate memory to hold the integer field values extracted from - each matching keyword. */ - fields = (int *) astMalloc( sizeof( int )*(size_t) nf ); - -/* Save the current card index, and rewind the FitsChan. */ - icard = astGetCard( this ); - astClearCard( this ); - -/* Check that the FitsChan is not empty and the pointer can be used. */ - if( !astFitsEof( this ) && astOK ){ - -/* Initialise the returned bounds. Any excess elements in the array are left - at the previously initialised values. */ - for( i = 0; i < nf; i++ ){ - lbnd[ i ] = INT_MAX; - ubnd[ i ] = -INT_MAX; - } - -/* Initialise the number of matching keywords. */ - nmatch = 0; - -/* Loop round all the cards in the FitsChan. */ - while( !astFitsEof( this ) && astOK ){ - -/* If the current keyword name matches the filter, update the returned - bounds and increment the number of matches. */ - if( Match( CardName( this, status ), filter, nf, fields, &nfld, - method, class, status ) ){ - for( i = 0; i < nf; i++ ){ - if( fields[ i ] > ubnd[ i ] ) ubnd[ i ] = fields[ i ]; - if( fields[ i ] < lbnd[ i ] ) lbnd[ i ] = fields[ i ]; - } - nmatch++; - } - -/* Move on to the next card. */ - MoveCard( this, 1, method, class, status ); - } - -/* If bounds were not found, returned 0 and -1. */ - for( i = 0; i < nf; i++ ){ - if( lbnd[ i ] == INT_MAX ){ - lbnd[ i ] = 0; - ubnd[ i ] = -1; - } - } - } - -/* Reinstate the original current card index. */ - astSetCard( this, icard ); - -/* Free the memory used to hold the integer field values extracted from - each matching keyword. */ - fields = (int *) astFree( (void *) fields ); - -/* If an error has occurred, returned no matches and reversed bounds. */ - if( !astOK ){ - nmatch = 0; - for( i = 0; i < maxfld; i++ ){ - lbnd[ i ] = 0; - ubnd[ i ] = -1; - } - } - -/* Returned the answer. */ - return nmatch; -} - -static int FindFits( AstFitsChan *this, const char *name, - char card[ AST__FITSCHAN_FITSCARDLEN + 1 ], int inc, int *status ){ - -/* -*++ -* Name: -c astFindFits -f AST_FINDFITS - -* Purpose: -* Find a FITS card in a FitsChan by keyword. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c int astFindFits( AstFitsChan *this, const char *name, char card[ 81 ], -c int inc ) -f RESULT = AST_FINDFITS( THIS, NAME, CARD, INC, STATUS ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function searches for a card in a FitsChan by keyword. The -* search commences at the current card (identified by the Card -* attribute) and ends when a card is found whose FITS keyword -* matches the template supplied, or when the last card in the -* FitsChan has been searched. -* -* If the search is successful (i.e. a card is found which matches -c the template), the contents of the card are (optionally) -f the template), the contents of the card are -* returned and the Card attribute is adjusted to identify the card -* found or, if required, the one following it. If the search is -c not successful, the function returns zero and the Card attribute -f not successful, the function returns .FALSE. and the Card attribute -* is set to the "end-of-file". - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c name -f NAME = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing a -f A character string containing a -* template for the keyword to be found. In the simplest case, -* this should simply be the keyword name (the search is case -* insensitive and trailing spaces are ignored). However, this -* template may also contain "field specifiers" which are -* capable of matching a range of characters (see the "Keyword -* Templates" section for details). In this case, the first card -* with a keyword which matches the template will be found. To -* find the next FITS card regardless of its keyword, you should -* use the template "%f". -c card -f CARD = CHARACTER * ( 80 ) (Returned) -c An array of at least 81 characters (to allow room for a -c terminating null) -f A character variable with at least 80 characters -* in which the FITS card which is found will be returned. If -c the search is not successful (or a NULL pointer is given), a -f the search is not successful, a -* card will not be returned. -c inc -f INC = LOGICAL (Given) -c If this value is zero (and the search is successful), the -f If this value is .FALSE. (and the search is successful), the -* FitsChan's Card attribute will be set to the index of the card -c that was found. If it is non-zero, however, the Card -f that was found. If it is .TRUE., however, the Card -* attribute will be incremented to identify the card which -* follows the one found. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astFindFits() -f AST_FINDFITS = LOGICAL -c One if the search was successful, otherwise zero. -f .TRUE. if the search was successful, otherwise .FALSE.. - -* Notes: -* - The search always starts with the current card, as identified -* by the Card attribute. To ensure you search the entire contents -* of a FitsChan, you should first clear the Card attribute (using -c astClear). This effectively "rewinds" the FitsChan. -f AST_CLEAR). This effectively "rewinds" the FitsChan. -* - If a search is unsuccessful, the Card attribute is set to the -* "end-of-file" (i.e. to one more than the number of cards in the -* FitsChan). No error occurs. -c - A value of zero will be returned if this function is invoked -f - A value of .FALSE. will be returned if this function is invoked -* with the AST error status set, or if it should fail for any -* reason. - -* Examples: -c result = astFindFits( fitschan, "%f", card, 1 ); -f RESULT = AST_FINDFITS( FITSCHAN, '%f', CARD, .TRUE., STATUS ) -* Returns the current card in a FitsChan and advances the Card -* attribute to identify the card that follows (the "%f" -* template matches any keyword). -c result = astFindFits( fitschan, "BITPIX", card, 1 ); -f RESULT = AST_FINDFITS( FITSCHAN, 'BITPIX', CARD, .TRUE., STATUS ) -* Searches a FitsChan for a FITS card with the "BITPIX" keyword -* and returns that card. The Card attribute is then incremented -* to identify the card that follows it. -c result = astFindFits( fitschan, "COMMENT", NULL, 0 ); -f RESULT = AST_FINDFITS( FITSCHAN, 'COMMENT', CARD, .FALSE., STATUS ) -* Sets the Card attribute of a FitsChan to identify the next -c COMMENT card (if any). The card itself is not returned. -f COMMENT card (if any) and returns that card. -c result = astFindFits( fitschan, "CRVAL%1d", card, 1 ); -f RESULT = AST_FINDFITS( FITSCHAN, 'CRVAL%1d', CARD, .TRUE., STATUS ) -* Searches a FitsChan for the next card with a keyword of the -* form "CRVALi" (for example, any of the keywords "CRVAL1", -* "CRVAL2" or "CRVAL3" would be matched). The card found (if -* any) is returned, and the Card attribute is then incremented -* to identify the following card (ready to search for another -* keyword with the same form, perhaps). - -* Keyword Templates: -* The templates used to match FITS keywords are normally composed -* of literal characters, which must match the keyword exactly -* (apart from case). However, a template may also contain "field -* specifiers" which can match a range of possible characters. This -* allows you to search for keywords that contain (for example) -* numbers, where the digits comprising the number are not known in -* advance. -* -* A field specifier starts with a "%" character. This is followed -* by an optional single digit (0 to 9) specifying a field -* width. Finally, there is a single character which specifies the - -* type of character to be matched, as follows: -* -* - "c": matches all upper case letters, -* - "d": matches all decimal digits, -* - "f": matches all characters which are permitted within a FITS -* keyword (upper case letters, digits, underscores and hyphens). -* -* If the field width is omitted, the field specifier matches one -* or more characters. If the field width is zero, it matches zero -* or more characters. Otherwise, it matches exactly the number of - -* characters specified. In addition to this: -* -* - The template "%f" will match a blank FITS keyword consisting -* of 8 spaces (as well as matching all other keywords). -* - A template consisting of 8 spaces will match a blank keyword -* (only). -* - -* For example: -* -* - The template "BitPix" will match the keyword "BITPIX" only. -* - The template "crpix%1d" will match keywords consisting of -* "CRPIX" followed by one decimal digit. -* - The template "P%c" will match any keyword starting with "P" -* and followed by one or more letters. -* - The template "E%0f" will match any keyword beginning with "E". -* - The template "%f" will match any keyword at all (including a -* blank one). -*-- -*/ - -/* Local Variables: */ - char *c; /* Pointer to next character to check */ - char *lname; /* Pointer to copy of name without trailing spaces */ - const char *class; /* Object class */ - const char *method; /* Calling method */ - int ret; /* Was a card found? */ - -/* Check the global status, and supplied keyword name. */ - if( !astOK ) return 0; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Store the calling method and object class. */ - method = "astFindFits"; - class = astGetClass( this ); - -/* Get a local copy of the keyword template. */ - lname = (char *) astStore( NULL, (void *) name, strlen(name) + 1 ); - -/* Terminate it to exclude trailing spaces. */ - c = lname + strlen(lname) - 1; - while( *c == ' ' && c >= lname ) *(c--) = 0; - -/* Use the private FindKeyCard function to find the card and make it the - current card. Always use the supplied current card (if any) if the - template is "%f" or "%0f". */ - if ( !strcmp( lname, "%f" ) || !strcmp( lname, "%0f" ) ){ - ret = astFitsEof( this ) ? 0 : 1; - } else { - ret = FindKeyCard( this, lname, method, class, status ); - } - -/* Only proceed if the card was found. */ - if( ret && astOK ){ - -/* Format the current card if a destination string was supplied. */ - if( card ) FormatCard( this, card, method, status ); - -/* Increment the current card pointer if required. */ - if( inc ) MoveCard( this, 1, method, class, status ); - -/* Indicate that a card has been formatted. */ - ret = 1; - } - -/* Free the memory holding the local copy of the keyword template. */ - lname = (char *) astFree( (void *) lname ); - -/* If an errror has occurred, return zero. */ - if( !astOK ) ret = 0; - -/* Return the answer. */ - return ret; -} - -static int FindKeyCard( AstFitsChan *this, const char *name, - const char *method, const char *class, int *status ){ -/* -* Name: -* FindKeyCard - -* Purpose: -* Find the next card refering to given keyword. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int FindKeyCard( AstFitsChan *this, const char *name, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Finds the next card which refers to the supplied keyword and makes -* it the current card. The search starts with the current card and ends -* when it reaches the last card. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* Pointer to a string holding the keyword template (using the -* syntax expected by the Match function). -* method -* Pointer to string holding name of calling method. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if a card was found refering to the given -* keyword. Otherwise zero is returned. - -* Notes: -* - If a NULL pointer is supplied for "name" then the current card -* is left unchanged. -* - The current card is set to NULL (end-of-file) if no card can be -* found for the supplied keyword. -*/ - -/* Local Variables: */ - int nfld; /* Number of fields in keyword template */ - int ret; /* Was a card found? */ - -/* Check the global status, and supplied keyword name. */ - if( !astOK || !name ) return 0; - -/* Indicate that no card has been found yet. */ - ret = 0; - -/* Search forward through the list until all cards have been checked. */ - while( !astFitsEof( this ) && astOK ){ - -/* Break out of the loop if the keyword name from the current card matches - the supplied keyword name. */ - if( Match( CardName( this, status ), name, 0, NULL, &nfld, method, class, status ) ){ - ret = 1; - break; - -/* Otherwise, move the current card on to the next card. */ - } else { - MoveCard( this, 1, method, class, status ); - } - } - -/* Return. */ - return ret; -} - -static double *FitLine( AstMapping *map, double *g, double *g0, double *w0, - double dim, double *tol, int *status ){ -/* -* Name: -* FitLine - -* Purpose: -* Check a Mapping for linearity. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* double *FitLine( AstMapping *map, double *g, double *g0, double *w0, -* double dim, double *tol, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function applies the supplied Mapping to a set of points along -* a straight line in the input space. It checks to see if the transformed -* positions also lie on a straight line (in the output space). If so, -* it returns the vector along this line in the output space which -* corresponds to a unit vector along the line in the input space. If -* not, a NULL pointer is returned. -* -* The returned vector is found by doing a least squares fit. - -* Parameters: -* map -* A pointer to the Mapping to test. The number of outputs must be -* greater than or equal to the number of inputs. -* g -* A pointer to an array holding a unit vector within the input space -* defining the straight line to be checked. The number of elements -* within this array should equal the number of inputs for "map". -* g0 -* A pointer to an array holding a position within the input space -* giving the central position of the vector "g". The number of elements -* within this array should equal the number of inputs for "map". -* w0 -* A pointer to an array holding a vector within the output space -* which corresponds to "g0". The number of elements within this array -* should equal the number of outputs for "map". -* dim -* The length of the pixel axis, or AST__BAD if unknown. -* tol -* Pointer to an array holding the tolerance for equality on each -* output axis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to dynamically allocated memory holding the required vector -* in the output space. The number of elements in this vector will equal -* the number of outputs for "map". The memory should be freed using -* astFree when no longer needed. If the Mapping is not linear, NULL -* is returned. - -* Notes: -* - NULL is returned if an error occurs. -*/ - -/* Local Constants: */ -#define NPO2 50 -#define NP (2*NPO2+1) - -/* Local Variables: */ - AstPointSet *pset1; - AstPointSet *pset2; - double **ptr1; - double **ptr2; - double *offset; - double *pax; - double *ret; - double *voffset; - double dax; - double denom; - double gap; - double sd2; - double sd; - double sdw; - double sw; - double wmax; - double wmin; - int i; - int j; - int n; - int nin; - int nout; - int ok; - -/* Initialise */ - ret = NULL; - -/* Check the inherited status and supplied axis size. */ - if( !astOK || dim == 0.0 ) return ret; - -/* Get the number of inputs and outputs for the Mapping. Return if the - number of outputs is smaller than the number of inputs. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - if( nout < nin ) return ret; - -/* Check the supplied position is good on all axes. */ - for( j = 0; j < nout; j++ ) { - if( w0[ j ] == AST__BAD ) return ret; - } - -/* We use NP points in the fit. If a value for "dim" has been supplied, - we use points evenly distributed over the whole axis. If not, we use - a gap of 1.0 (corresponds to an axis length of 100 pixels). - Choose the gap. */ - gap = ( dim != AST__BAD ) ? dim/NP : 1.0; - -/* Create PointSets to hold the input and output positions. */ - pset1 = astPointSet( NP, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - pset2 = astPointSet( NP, nout, "", status ); - ptr2 = astGetPoints( pset2 ); - -/* Allocate the returned array. */ - ret = astMalloc( sizeof( double )*(size_t) nout ); - -/* Allocate workspace to hold the constant offsets of the fit. */ - offset = astMalloc( sizeof( double )*(size_t) nout ); - voffset = astMalloc( sizeof( double )*(size_t) nout ); - -/* Indicate we have not yet got a usable returned vector. */ - ok = 0; - -/* Check we can use the pointers safely. */ - if( astOK ) { - -/* Set up the input positions: NP evenly spaced points along a line with - unit direction vector given by "g", centred at position given by "g0". */ - for( j = 0; j < nin; j++ ) { - pax = ptr1[ j ]; - dax = g[ j ]*gap; - for( i = -NPO2; i <= NPO2; i++ ) *(pax++) = g0[ j ] + dax*i; - } - -/* Transform these positions into the output space. */ - (void) astTransform( map, pset1, 1, pset2 ); - -/* Loop over all output axes, finding the component of the returned vector. */ - ok = 1; - for( j = 0; j < nout; j++ ) { - pax = ptr2[ j ]; - -/* Now loop over all the transformed points to form the other required - sums. We also form the sums needed to estimate the variance in the - calculated offset. */ - sdw = 0.0; - sw = 0.0; - sd = 0.0; - sd2 = 0.0; - n = 0; - wmax = -DBL_MAX; - wmin = DBL_MAX; - for( i = -NPO2; i <= NPO2; i++, pax++ ) { - if( *pax != AST__BAD ) { - -/* Increment the required sums. */ - sdw += i*(*pax); - sw += (*pax); - sd += i; - sd2 += i*i; - n++; - if( *pax > wmax ) wmax = *pax; - if( *pax < wmin ) wmin = *pax; - } - } - -/* If a reasonable number of good points were found, find the component of - the returned vector (excluding a scale factor of 1/gap). */ - denom = sd2*n - sd*sd; - if( n > NP/4 && denom != 0.0 ) { - -/* Find the constant scale factor to return for this axis. If the axis - value is constant, return zero. */ - if( wmax > wmin ) { - ret[ j ] = (sdw*n - sw*sd)/denom; - } else { - ret[ j ] = 0.0; - } - -/* Now find the constant offset for this axis. */ - offset[ j ] = (sw*sd2 - sdw*sd)/denom; - } else { - ok = 0; - break; - } - } - -/* Now check that the fit is good enough. Each axis is checked separately. - All axes must be good. */ - if( ok ) { - for( j = 0; j < nout; j++ ) { - -/* Store the axis values implied by the linear fit in the now un-needed ptr1[0] - array. */ - pax = ptr1[ 0 ]; - for( i = -NPO2; i <= NPO2; i++, pax++ ) { - *pax = i*ret[ j ] + offset[ j ]; - } - -/* Test the fit to see if we beleive that the mapping is linear. If - it is, scale the returned value from units of "per gap" to units of - "per pixel". Otherwise,indicate that he returned vector is unusable. */ - if( FitOK( NP, ptr2[ j ], ptr1[ 0 ], tol[ j ], status ) ) { - ret[ j ] /= gap; - } else { - ok = 0; - break; - } - } - } - } - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Free memory. */ - offset = astFree( offset ); - voffset = astFree( voffset ); - -/* If an error has occurred, or if the returned vector is unusable, - free any returned memory */ - if( !astOK || !ok ) ret = astFree( ret ); - -/* Return the answer. */ - return ret; - -/* Undefine local constants: */ -#undef NP -#undef NPO2 -} - -static int FitsEof( AstFitsChan *this, int *status ){ - -/* -*+ -* Name: -* astFitsEof - -* Purpose: -* See if the FitsChan is at "end-of-file". - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* int astFitsEof( AstFitsChan *this ) - -* Class Membership: -* FitsChan method. - -* Description: -* A value of zero is returned if any more cards remain to be read from the -* FitsChan. Otherwise a value of 1 is returned. Thus, it is -* equivalent to testing the FitsChan for an "end-of-file" condition. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Returned Value: -* One if no more cards remain to be read, otherwise zero. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*- -*/ - -/* Check the supplied object. */ - if( !this ) return 1; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* If no more cards remain to be read, the current card pointer in the - FitsChan will be NULL. Return an appropriate integer value. */ - return this->card ? 0 : 1; -} - -static int FitsSof( AstFitsChan *this, int *status ){ - -/* -*+ -* Name: -* FitsSof - -* Purpose: -* See if the FitsChan is at "start-of-file". - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int FitsSof( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A value of 1 is returned if the current card is the first card in -* the FitsChan. Otherwise a value of zero is returned. This function -* is much more efficient than "astGetCard(this) <= 1" . - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the current card is the first card. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -* - A non-zero value is returned if the FitsChan is empty. -*- -*/ - -/* Return if no FitsChan was supplied, or if the FitsChan is empty. */ - if ( !this || !this->head ) return 1; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* If the current card is at the head of the linked list, it is the first - card. */ - return this->card == this->head; -} - -/* -*++ -* Name: -c astGetFits -f AST_GETFITS - -* Purpose: -* Get a named keyword value from a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c int astGetFits( AstFitsChan *this, const char *name, type *value ) -f RESULT = AST_GETFITS( THIS, NAME, VALUE, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -* This is a family of functions which gets a value for a named keyword, -* or the value of the current card, from a FitsChan using one of several -* different data types. The data type of the returned value is selected -* by replacing in the function name by one of the following strings -* representing the recognised FITS data types: -* -* - CF - Complex floating point values. -* - CI - Complex integer values. -* - F - Floating point values. -* - I - Integer values. -* - L - Logical (i.e. boolean) values. -* - S - String values. -* - CN - A "CONTINUE" value, these are treated like string values, but -* are encoded without an equals sign. -* -* The data type of the "value" -c parameter -f argument - -* depends on as follows: -* -c - CF - "double *" (a pointer to a 2 element array to hold the real and -c imaginary parts of the complex value). -c - CI - "int *" (a pointer to a 2 element array to hold the real and -c imaginary parts of the complex value). -c - F - "double *". -c - I - "int *". -c - L - "int *". -c - S - "char **" (a pointer to a static "char" array is returned at the -c location given by the "value" parameter, Note, the stored string -c may change on subsequent invocations of astGetFitsS so a -c permanent copy should be taken of the string if necessary). -c - CN - Like"S". -f - CF - DOUBLE PRECISION(2) (a 2 element array to hold the real and -f imaginary parts of the complex value). -f - CI - INTEGER(2) (a 2 element array to hold the real and imaginary -f parts of the complex value). -f - F - DOUBLE PRECISION. -f - I - INTEGER -f - L - LOGICAL -f - S - CHARACTER -f - CN - CHARACTER - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c name -f NAME = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string -f A character string -* containing the FITS keyword name. This may be a complete FITS -* header card, in which case the keyword to use is extracted from -* it. No more than 80 characters are read from this string. If -c NULL -f a single dot '.' -* is supplied, the value of the current card is returned. -c value -f VALUE = type (Returned) -c A pointer to a -f A -* buffer to receive the keyword value. The data type depends on -* as described above. The conents of the buffer on entry are left -* unchanged if the keyword is not found. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetFits() -f AST_GETFITS = LOGICAL -c A value of zero -f .FALSE. -* is returned if the keyword was not found in the FitsChan (no error -* is reported). Otherwise, a value of -c one -f .TRUE. -* is returned. - -* Notes: -* - If a name is supplied, the card following the current card is -* checked first. If this is not the required card, then the rest of the -* FitsChan is searched, starting with the first card added to the -* FitsChan. Therefore cards should be accessed in the order they are -* stored in the FitsChan (if possible) as this will minimise the time -* spent searching for cards. -* - If the requested card is found, it becomes the current card, -* otherwise the current card is left pointing at the "end-of-file". -* - If the stored keyword value is not of the requested type, it is -* converted into the requested type. -* - If the keyword is found in the FitsChan, but has no associated -* value, an error is reported. If necessary, the -c astTestFits -f AST_TESTFITS -* function can be used to determine if the keyword has a defined -* value in the FitsChan prior to calling this function. -* - An error will be reported if the keyword name does not conform -* to FITS requirements. -c - Zero -* - .FALSE. -* is returned as the function value if an error has already occurred, -* or if this function should fail for any reason. -* - The FITS standard says that string keyword values should be -* padded with trailing spaces if they are shorter than 8 characters. -* For this reason, trailing spaces are removed from the string -* returned by -c astGetFitsS -f AST_GETFITSS -* if the original string (including any trailing spaces) contains 8 -* or fewer characters. Trailing spaces are not removed from longer -* strings. -*-- -*/ - -/* Define a macro which expands to the implementation of the astGetFits - routine for a given data type. */ -#define MAKE_FGET(code,ctype,ftype) \ -static int GetFits##code( AstFitsChan *this, const char *name, ctype value, int *status ){ \ -\ -/* Local Variables: */ \ - const char *class; /* Object class */ \ - const char *method; /* Calling method */ \ - char *lcom; /* Supplied keyword comment */ \ - char *lname; /* Supplied keyword name */ \ - char *lvalue; /* Supplied keyword value */ \ - char *string; /* Pointer to returned string value */ \ - char *c; /* Pointer to next character */ \ - int cl; /* Length of string value */ \ - int ret; /* The returned value */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Ensure the source function has been called */ \ - ReadFromSource( this, status ); \ -\ -/* Store the calling method and object class. */ \ - method = "astGetFits"#code; \ - class = astGetClass( this ); \ -\ -/* Initialise the returned value. */ \ - ret = 0; \ -\ -/* Extract the keyword name from the supplied string. */ \ - if( name ) { \ - (void) Split( this, name, &lname, &lvalue, &lcom, method, class, status ); \ - } else { \ - lname = NULL; \ - lvalue = NULL; \ - lcom = NULL; \ - } \ -\ -/* Attempt to find a card in the FitsChan refering to this keyword, \ - and make it the current card. Only proceed if a card was found. No \ - need to do the search if the value of the current card is required. */ \ - if( !lname || SearchCard( this, lname, method, class, status ) ){ \ -\ -/* Convert the stored data value to the requested type, and store it in \ - the supplied buffer. */ \ - if( !CnvValue( this, ftype, 0, value, method, status ) && astOK ) { \ - astError( AST__FTCNV, "%s(%s): Cannot convert FITS keyword " \ - "'%s' to %s.", status, method, class, \ - CardName( this, status ), type_names[ ftype ] ); \ - } \ -\ -/* If the returned value is a string containing 8 or fewer characters, \ - replace trailing spaces with null characters. */ \ - if( astOK ) { \ - if( ftype == AST__STRING ) { \ - string = *( (char **) value ); \ - if( string ) { \ - cl =strlen( string ); \ - if( cl <= 8 ) { \ - c = string + cl - 1; \ - while( *c == ' ' && c > string ) { \ - *c = 0; \ - c--; \ - } \ - } \ - } \ - } \ -\ -/* Indicate that a value is available. */ \ - ret = 1; \ - } \ -\ - } \ -\ -/* Context error message. */ \ - if( !astOK && lname && *lname ) { \ - astError( astStatus, "%s(%s): Cannot get value for FITS keyword " \ - "'%s'.", status, method, class, lname ); \ - } \ -\ -/* Release the memory used to hold keyword name, value and comment strings. */ \ - lname = (char *) astFree( (void *) lname ); \ - lvalue = (char *) astFree( (void *) lvalue ); \ - lcom = (char *) astFree( (void *) lcom ); \ -\ -/* Return the answer. */ \ - return ret; \ -\ -} - -/* Use the above macro to give defintions for the astGetFits method - for each FITS data type. */ -MAKE_FGET(CF,double *,AST__COMPLEXF) -MAKE_FGET(CI,int *,AST__COMPLEXI) -MAKE_FGET(F,double *,AST__FLOAT) -MAKE_FGET(I,int *,AST__INT) -MAKE_FGET(L,int *,AST__LOGICAL) -MAKE_FGET(S,char **,AST__STRING) -MAKE_FGET(CN,char **,AST__CONTINUE) -#undef MAKE_FGET - -static int FitsGetCom( AstFitsChan *this, const char *name, - char **comment, int *status ){ - -/* -*+ -* Name: -* astFitsGetCom - -* Purpose: -* Get a keyword comment from a FitsChan. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" - -* int astFitsGetCom( AstFitsChan *this, const char *name, -* char **comment ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function gets the comment associated with the next occurrence of -* a named keyword in a FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* A pointer to a -* string holding the keyword name. This may be a complete FITS -* header card, in which case the keyword to use is extracted from -* it. No more than 80 characters are read from this string. -* comment -* A pointer to a location at which to return a pointer to a string -* holding the keyword comment. Note, the stored string will change on -* subsequent invocations of astFitsGetCom so a permanent copy -* should be taken of the string if necessary. - -* Returned Value: -* astFitsGetCom() -* A value of zero is returned if the keyword was not found before -* the end of the FitsChan was reached (no error is reported). -* Otherwise, a value of one is returned. - -* Notes: -* - If a NULL pointer is supplied for "name" then the comment from -* the current card is returned. -* - The returned value is obtained from the next card refering to -* the required keyword, starting the search with the current card. -* Any cards occuring before the current card are not seached. If -* the entire contents of the FitsChan must be searched, then ensure -* the current card is the first card in the FitsChan by clearing the Card -* attribute. This effectively "rewinds" the FitsChan. -* - The current card is updated to become the card following the one -* read by this function. If the card read by this function is the -* last one in the FitsChan, then the current card is left pointing at the -* "end-of-file". -* - An error will be reported if the keyword name does not conform -* to FITS requirements. -* - A NULL pointer is returned for the comment string if the keyword -* has no comment. -* - Zero is returned as the function value if an error has already -* occurred, or if this function should fail for any reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *method; /* Calling method */ - const char *class; /* Object class */ - char *lcom; /* Supplied keyword comment */ - char *lname; /* Supplied keyword name */ - char *lvalue; /* Supplied keyword value */ - int ret; /* The returned value */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Initialise the returned value. */ - ret = 0; - -/* Store the method name and object class. */ - method = "astFitsGetCom"; - class = astGetClass( this ); - -/* Extract the keyword name from the supplied string (if supplied). */ - if( name ){ - (void) Split( this, name, &lname, &lvalue, &lcom, method, class, status ); - } else { - lname = NULL; - lcom = NULL; - lvalue = NULL; - } - -/* Find the next card in the FitsChan refering to this keyword. This will - be the current card if no keyword name was supplied. The matching card - is made the current card. Only proceed if a card was found. */ - if( FindKeyCard( this, lname, method, class, status ) ){ - -/* Copy the comment into a static buffer, and return a pointer to it. */ - if( CardComm( this, status ) ){ - (void) strncpy( fitsgetcom_sval, CardComm( this, status ), AST__FITSCHAN_FITSCARDLEN ); - fitsgetcom_sval[ AST__FITSCHAN_FITSCARDLEN ] = 0; - if( comment ) *comment = fitsgetcom_sval; - } else { - if( comment ) *comment = NULL; - } - -/* Move on to the next card. */ - MoveCard( this, 1, method, class, status ); - -/* Indicate that a value is available. */ - if( astOK ) ret = 1; - } - -/* Release the memory used to hold keyword name, value and comment strings. */ - lname = (char *) astFree( (void *) lname ); - lvalue = (char *) astFree( (void *) lvalue ); - lcom = (char *) astFree( (void *) lcom ); - -/* Return the answer. */ - return ret; -} - -static int SetFits( AstFitsChan *this, const char *keyname, void *value, - int type, const char *comment, int overwrite, int *status ){ - -/* -* Name: -* SetFits - -* Purpose: -* Store a keyword value of any type in a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int SetFits( AstFitsChan *this, const char *keyname, void *value, -* int type, const char *comment, int overwrite, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function stores the supplied value for the supplied keyword -* in the supplied FitsChan, assuming it is of the supplied data type. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* A pointer to a string holding the keyword name. -* value -* A pointer to a buffer holding the keyword value. For strings, -* the buffer should hold the address of a pointer to the character -* string. -* type -* The keyword type. -* comment -* A pointer to a string holding a comment to associated with the -* keyword. If a NULL pointer or a blank string is supplied, then -* any comment included in the string supplied for the "name" parameter -* is used instead. If "name" contains no comment, then any existing -* comment in the card being over-written is retained, or a NULL -* pointer is stored if a new card is being inserted. If the data -* value being stored for the card is the same as the card being -* over-written, then any existing comment is retained. -* overwrite -* If non-zero, the new card formed from the supplied keyword name, -* value and comment string over-writes the current card, and the -* current card is incremented to refer to the next card. If zero, the -* new card is inserted in front of the current card and the current -* card is left unchanged. In either case, if the current card on -* entry points to the "end-of-file", the new card is appended to the -* end of the list. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 0 is returned if the value could not be stored for any -* reason. A value of 1 is returned otherwise. - -* Notes: -* - Nothing is stored in the FitsChan and a value of zero is returned -* (but no error is reported) if an AST__FLOAT value is supplied equal -* to AST__BAD. -*/ - -/* Local Variables: */ - const char *cval; - const char *ecval; - double dval; - double ecdval[ 2 ]; - double edval; - int ecival[ 2 ]; - int eival; - int ival; - int ret; - -/* Check the global status, and the supplied pointer. */ - if( !astOK || !value ) return 0; - -/* Initialise the returned value to indicate that the supplied name was - stored. */ - ret = 1; - -/* Check each data type in turn. */ - if( type == AST__FLOAT ){ - dval = *( (double *) value ); - if( dval != AST__BAD ) { - -/* If the data value has not changed, and the card has a coment, - set the comment pointer NULL so that the existing comment will be - retained. */ - if( overwrite && CnvValue( this, type, 0, &edval, "SetFits", - status ) && - CardComm( this, status ) ) { - if( astEQUAL( edval, dval ) ) comment = NULL; - } - astSetFitsF( this, keyname, dval, comment, overwrite ); - } else { - ret = 0; - } - } else if( type == AST__STRING ){ - cval = *( (char **) value); - if( cval ){ - -/* If the data value has not changed, retain the original comment. */ - if( overwrite && CnvValue( this, type, 0, &ecval, "SetFits", - status ) && - CardComm( this, status ) ) { - if( Similar( ecval, cval, status ) ) comment = NULL; - } - -/* Ignore comments if they are identical to the keyword value. */ - if( comment && !strcmp( cval, comment ) ) comment = NULL; - astSetFitsS( this, keyname, cval, comment, overwrite ); - } else { - ret = 0; - } - } else if( type == AST__CONTINUE ){ - cval = *( (char **) value); - if( cval ){ - astSetFitsCN( this, keyname, cval, comment, overwrite ); - } else { - ret = 0; - } - } else if( type == AST__COMMENT ){ - astSetFitsCom( this, keyname, comment, overwrite ); - } else if( type == AST__INT ){ - ival = *( (int *) value ); - -/* If the data value has not changed, retain the original comment. */ - if( overwrite && CnvValue( this, type, 0, &eival, "SetFits", - status ) && - CardComm( this, status ) ) { - if( eival == ival ) comment = NULL; - } - astSetFitsI( this, keyname, ival, comment, overwrite ); - } else if( type == AST__COMPLEXF ){ - if( ( (double *) value )[0] != AST__BAD && - ( (double *) value )[1] != AST__BAD ) { - -/* If the data value has not changed, retain the original comment. */ - if( overwrite && CnvValue( this, type, 0, ecdval, "SetFits", - status ) && - CardComm( this, status ) ) { - if( astEQUAL( ecdval[ 0 ], ( (double *) value )[ 0 ] ) && - astEQUAL( ecdval[ 1 ], ( (double *) value )[ 1 ] ) ) comment = NULL; - } - astSetFitsCF( this, keyname, (double *) value, comment, overwrite ); - } else { - ret = 0; - } - } else if( type == AST__COMPLEXI ){ - -/* If the data value has not changed, retain the original comment. */ - if( overwrite && CnvValue( this, type, 0, ecival, "SetFits", - status ) && - CardComm( this, status ) ) { - if( ecival[ 0 ] == ( (int *) value )[ 0 ] && - ecival[ 1 ] == ( (int *) value )[ 1 ] ) comment = NULL; - } - astSetFitsCI( this, keyname, (int *) value, comment, overwrite ); - } else if( type == AST__LOGICAL ){ - ival = ( *( (int *) value ) != 0 ); - -/* If the data value has not changed, retain the original comment. */ - if( overwrite && CnvValue( this, type, 0, &eival, "SetFits", - status ) && - CardComm( this, status ) ) { - if( eival == ival ) comment = NULL; - } - astSetFitsL( this, keyname, ival, comment, overwrite ); - } else if( type == AST__UNDEF ){ - if( overwrite && CardType( this, status ) == AST__UNDEF && CardComm( this, status ) ) { - comment = NULL; - } - astSetFitsU( this, keyname, comment, overwrite ); - } - return ret; -} - -/* -*++ -* Name: -c astSetFits -f AST_SETFITS - -* Purpose: -* Store a keyword value in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c void astSetFits( AstFitsChan *this, const char *name, type value, -c const char *comment, int overwrite ) -f CALL AST_SETFITS( THIS, NAME, VALUE, COMMENT, OVERWRITE, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This is a family of functions which store values for named keywords -f This is a family of routines which store values for named keywords -* within a FitsChan at the current card position. The supplied keyword -* value can either over-write an existing keyword value, or can be -* inserted as a new header card into the FitsChan. -* -c The keyword data type is selected by replacing in the function name -f The keyword data type is selected by replacing in the routine name -* by one of the following strings representing the recognised FITS data - -* types: -* -* - CF - Complex floating point values. -* - CI - Complex integer values. -* - F - Floating point values. -* - I - Integer values. -* - L - Logical (i.e. boolean) values. -* - S - String values. -* - CN - A "CONTINUE" value, these are treated like string values, but -* are encoded without an equals sign. -* - -* The data type of the "value" parameter depends on as follows: -* -c - CF - "double *" (a pointer to a 2 element array holding the real and -c imaginary parts of the complex value). -c - CI - "int *" (a pointer to a 2 element array holding the real and -c imaginary parts of the complex value). -c - F - "double". -c - I - "int". -c - L - "int". -c - S - "const char *". -c - CN - "const char *". -* -f - CF - DOUBLE PRECISION(2) (a 2 element array holding the real and -f imaginary parts of the complex value). -f - CI - INTEGER(2) (a 2 element array holding the real and imaginary -f parts of the complex value). -f - F - DOUBLE PRECISION. -f - I - INTEGER -f - L - LOGICAL -f - S - CHARACTER -f - CN - CHARACTER - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c name -f NAME = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string -f A character string -* containing the FITS keyword name. This may be a complete FITS -* header card, in which case the keyword to use is extracted from -* it. No more than 80 characters are read from this string. -c value -f VALUE = type (Given) -* The keyword value to store with the named keyword. The data type -* of this parameter depends on as described above. -c comment -f COMMENT = CHARACTER * ( * ) (Given) -c A pointer to a null terminated string -f A string -* holding a comment to associated with the keyword. -c If a NULL pointer or -f If -* a blank string is supplied, then any comment included in the string -* supplied for the -c "name" parameter is used instead. If "name" -f NAME parameter is used instead. If NAME -* contains no comment, then any existing comment in the card being -* over-written is retained. Otherwise, no comment is stored with -* the card. -c overwrite -f OVERWRITE = LOGICAL (Given) -c If non-zero, -f If .TRUE., -* the new card formed from the supplied keyword name, value and comment -* string over-writes the current card, and the current card is -* incremented to refer to the next card (see the "Card" attribute). If -c zero, -f .FALSE., -* the new card is inserted in front of the current card and the current -* card is left unchanged. In either case, if the current card on entry -* points to the "end-of-file", the new card is appended to the end of -* the list. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The -c function astSetFitsU -f routine AST_SETFITSU -* can be used to indicate that no value is associated with a keyword. -* - The -c function astSetFitsCM -f routine AST_SETFITSCM -* can be used to store a pure comment card (i.e. a card with a blank -* keyword). -* - To assign a new value for an existing keyword within a FitsChan, -c first find the card describing the keyword using astFindFits, and -c then use one of the astSetFits family to over-write the old value. -f first find the card describing the keyword using AST_FINDFITS, and -f then use one of the AST_SETFITS family to over-write the old value. -* - If, on exit, there are no cards following the card written by -c this function, then the current card is left pointing at the -f this routine, then the current card is left pointing at the -* "end-of-file". -* - An error will be reported if the keyword name does not conform -* to FITS requirements. -*-- -*/ - -/* Define a macro which expands to the implementation of the astSetFits - routine for a given data type. */ -#define MAKE_FSET(code,ctype,ftype,valexp) \ -static void SetFits##code( AstFitsChan *this, const char *name, ctype value, const char *comment, int overwrite, int *status ) { \ -\ -/* Local variables: */ \ - const char *class; /* Object class */ \ - const char *method; /* Calling method */ \ - const char *com; /* Comment to use */ \ - char *lcom; /* Supplied keyword comment */ \ - char *lname; /* Supplied keyword name */ \ - char *lvalue; /* Supplied keyword value */ \ - int free_com; /* Should com be freed before returned? */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Ensure the source function has been called */ \ - ReadFromSource( this, status ); \ -\ -/* Store the object clas and calling method. */ \ - class = astGetClass( this ); \ - method = "astSetFits"#code; \ -\ -/* Extract the keyword name from the supplied string. */ \ - (void) Split( this, name, &lname, &lvalue, &lcom, method, class, status ); \ -\ -/* Initialise a pointer to the comment to be stored. If the supplied \ - comment is blank, use the comment given with "name". */ \ - com = ChrLen( comment, status ) ? comment : lcom; \ -\ -/* If the comment is still blank, use the existing comment if we are \ - over-writing, or a NULL pointer otherwise. */ \ - free_com = 0; \ - if( !ChrLen( com, status ) ) { \ - com = NULL; \ - if( overwrite ) { \ - if( CardComm( this, status ) ){ \ - com = (const char *) astStore( NULL, (void *) CardComm( this, status ), \ - strlen( CardComm( this, status ) ) + 1 ); \ - free_com = 1; \ - } \ - } \ - } \ -\ -/* Insert the new card. */ \ - InsCard( this, overwrite, lname, ftype, valexp, com, method, class, status ); \ -\ -/* Release the memory used to hold keyword name, value and comment strings. */ \ - lname = (char *) astFree( (void *) lname ); \ - lvalue = (char *) astFree( (void *) lvalue ); \ - lcom = (char *) astFree( (void *) lcom ); \ -\ -/* Release the memory holding the stored comment string, so long as it was \ - allocated within this function. */ \ - if( free_com ) com = (const char *) astFree( (void *) com ); \ -\ -} - -/* Use the above macro to give defintions for the astSetFits method - for each FITS data type. */ -MAKE_FSET(I,int,AST__INT,(void *)&value) -MAKE_FSET(F,double,AST__FLOAT,(void *)&value) -MAKE_FSET(S,const char *,AST__STRING,(void *)value) -MAKE_FSET(CN,const char *,AST__CONTINUE,(void *)value) -MAKE_FSET(CF,double *,AST__COMPLEXF,(void *)value) -MAKE_FSET(CI,int *,AST__COMPLEXI,(void *)value) -MAKE_FSET(L,int,AST__LOGICAL,(void *)&value) -#undef MAKE_FSET - -static void SetFitsU( AstFitsChan *this, const char *name, const char *comment, - int overwrite, int *status ) { - -/* -*++ -* Name: -c astSetFitsU -f AST_SETFITSU - -* Purpose: -* Store an undefined keyword value in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c void astSetFitsU( AstFitsChan *this, const char *name, -c const char *comment, int overwrite ) -f CALL AST_SETFITSU( THIS, NAME, COMMENT, OVERWRITE, STATUS ) - -* Description: -* This -c function -f routine -* stores an undefined value for a named keyword within -* a FitsChan at the current card position. The new undefined value -* can either over-write an existing keyword value, or can be inserted -* as a new header card into the FitsChan. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c name -f NAME = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string -f A character string -* containing the FITS keyword name. This may be a complete FITS -* header card, in which case the keyword to use is extracted from -* it. No more than 80 characters are read from this string. -c comment -f COMMENT = CHARACTER * ( * ) (Given) -c A pointer to a null terminated string -f A string -* holding a comment to associated with the keyword. -c If a NULL pointer or -f If -* a blank string is supplied, then any comment included in the string -* supplied for the -c "name" parameter is used instead. If "name" -f NAME parameter is used instead. If NAME -* contains no comment, then any existing comment in the card being -* over-written is retained. Otherwise, no comment is stored with -* the card. -c overwrite -f OVERWRITE = LOGICAL (Given) -c If non-zero, -f If .TRUE., -* the new card formed from the supplied keyword name and comment -* string over-writes the current card, and the current card is -* incremented to refer to the next card (see the "Card" attribute). If -c zero, -f .FALSE., -* the new card is inserted in front of the current card and the current -* card is left unchanged. In either case, if the current card on entry -* points to the "end-of-file", the new card is appended to the end of -* the list. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If, on exit, there are no cards following the card written by -* this function, then the current card is left pointing at the -* "end-of-file". -* - An error will be reported if the keyword name does not conform -* to FITS requirements. -*-- -*/ - -/* Local variables: */ - const char *class; /* Object class */ - const char *method; /* Calling method */ - const char *com; /* Comment to use */ - char *lcom; /* Supplied keyword comment */ - char *lname; /* Supplied keyword name */ - char *lvalue; /* Supplied keyword value */ - int free_com; /* Should com be freed before returned? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Store the object clas and calling method. */ - class = astGetClass( this ); - method = "astSetFitsU"; - -/* Extract the keyword name from the supplied string. */ - (void) Split( this, name, &lname, &lvalue, &lcom, method, class, status ); - -/* Initialise a pointer to the comment to be stored. If the supplied - comment is blank, use the comment given with "name". */ - com = ChrLen( comment, status ) ? comment : lcom; - -/* If the comment is still blank, use the existing comment if we are - over-writing, or a NULL pointer otherwise. */ - free_com = 0; - if( !ChrLen( com, status ) ) { - com = NULL; - if( overwrite ) { - if( CardComm( this, status ) ){ - com = (const char *) astStore( NULL, (void *) CardComm( this, status ), - strlen( CardComm( this, status ) ) + 1 ); - free_com = 1; - } - } - } - -/* Insert the new card. */ - InsCard( this, overwrite, lname, AST__UNDEF, NULL, com, method, class, - status ); - -/* Release the memory used to hold keyword name, value and comment strings. */ - lname = (char *) astFree( (void *) lname ); - lvalue = (char *) astFree( (void *) lvalue ); - lcom = (char *) astFree( (void *) lcom ); - -/* Release the memory holding the stored comment string, so long as it was - allocated within this function. */ - if( free_com ) com = (const char *) astFree( (void *) com ); -} - -static void SetFitsCM( AstFitsChan *this, const char *comment, - int overwrite, int *status ) { - -/* -*++ -* Name: -c astSetFitsCM -f AST_SETFITSCM - -* Purpose: -* Store a comment card in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c void astSetFitsCM( AstFitsChan *this, const char *comment, -c int overwrite ) -f CALL AST_SETFITSCM( THIS, COMMENT, OVERWRITE, STATUS ) - -* Description: -* This -c function -f routine -* stores a comment card ( i.e. a card with no keyword name or equals -* sign) within a FitsChan at the current card position. The new card -* can either over-write an existing card, or can be inserted as a new -* card into the FitsChan. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c comment -f COMMENT = CHARACTER * ( * ) (Given) -c A pointer to a null terminated string -f A string -* holding the text of the comment card. -c If a NULL pointer or -f If -* a blank string is supplied, then a totally blank card is produced. -c overwrite -f OVERWRITE = LOGICAL (Given) -c If non-zero, -f If .TRUE., -* the new card over-writes the current card, and the current card is -* incremented to refer to the next card (see the "Card" attribute). If -c zero, -f .FALSE., -* the new card is inserted in front of the current card and the current -* card is left unchanged. In either case, if the current card on entry -* points to the "end-of-file", the new card is appended to the end of -* the list. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If, on exit, there are no cards following the card written by -* this function, then the current card is left pointing at the -* "end-of-file". -*-- -*/ - -/* Just call astSetFitsCom with a blank keyword name. */ - astSetFitsCom( this, "", comment, overwrite ); -} - -static void SetFitsCom( AstFitsChan *this, const char *name, - const char *comment, int overwrite, int *status ){ - -/* -*+ -* Name: -* astSetFitsCom - -* Purpose: -* Store a comment for a keyword in a FitsChan. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" - -* void astSetFitsCom( AstFitsChan *this, const char *name, -* const char *comment, int overwrite ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function replaces the comment within an existing card, or -* stores a new comment card within a FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* A pointer to a -* string holding the keyword name. This may be a complete FITS -* header card, in which case the keyword to use is extracted from -* it. No more than 80 characters are read from this string. -* comment -* A pointer to a -* string holding a comment to associated with the keyword. -* If a NULL or -* blank string is supplied, any existing comment associated with -* the keyword is removed. -* overwrite -* If non-zero, the new comment replaces the comment in the current -* card, and the current card is then incremented to refer to the next -* card. If zero, a new comment card is inserted in front of the current -* card and the current card is left unchanged. In either case, if the -* current card on entry points to the "end-of-file", the new card is -* appended to the end of the list. - -* Notes: -* - When replacing an existing comment, any existing keyword value is -* retained only if the supplied keyword name is the same as the keyword -* name in the current card. If the keyword names are different, then -* the new name replaces the old name, and any existing keyword data value -* is deleted. The card thus becomes a comment card with the supplied -* keyword name and comment, but no data value. -* - If, on exit, there are no cards following the card written by -* this function, then the current card is left pointing at the -* "end-of-file". -* - The current card can be set explicitly before calling this function -* either by assigning a value to the Card attribute (if the index of the -* required card is already known), or using astFindFits (if only the -* keyword name is known). -* - An error will be reported if the keyword name does not conform -* to FITS requirements. -*- -*/ - -/* Local variables: */ - const char *class; /* Pointer to object class string */ - const char *method; /* Pointer to calling method string */ - const char *cname; /* The existing keyword name */ - const char *com; /* The comment to use */ - char *lcom; /* Supplied keyword comment */ - char *lname; /* Supplied keyword name */ - char *lvalue; /* Supplied keyword value */ - void *old_data; /* Pointer to the old data value */ - void *data; /* Pointer to data value to be stored */ - size_t size; /* The size of the data value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialisation */ - size = 0; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Store the calling method and object class. */ - method = "astSetFitsCom"; - class = astGetClass( this ); - -/* Extract the keyword name, etc, from the supplied string. */ - (void) Split( this, name, &lname, &lvalue, &lcom, method, class, status ); - -/* If a blank comment has been supplied, use NULL instead. */ - com = ChrLen( comment, status )? comment : NULL; - -/* If we are inserting a new card, or over-writing an old card with a - different name, create and store a comment card with the given keyword - name and comment, but no data value. */ - cname = CardName( this, status ); - if( !overwrite || !cname || strcmp( lname, cname ) ){ - InsCard( this, overwrite, lname, AST__COMMENT, NULL, com, method, class, status ); - -/* If we are overwriting an existing keyword comment, use the data type - and value from the existing current card. Note, we have to take a copy - of the old data value because InsCard over-writes by deleting the old - card and then inserting a new one. */ - } else { - old_data = CardData( this, &size, status ); - data = astStore( NULL, old_data, size ); - InsCard( this, 1, lname, CardType( this, status ), data, com, method, class, status ); - data = astFree( data ); - } - -/* Release the memory used to hold keyword name, value and comment strings. */ - lname = (char *) astFree( (void *) lname ); - lvalue = (char *) astFree( (void *) lvalue ); - lcom = (char *) astFree( (void *) lcom ); -} - -static void FixNew( AstFitsChan *this, int flag, int remove, - const char *method, const char *class, int *status ){ - -/* -* -* Name: -* FixNew - -* Purpose: -* Remove "new" flags from the whole FitsChan, and optionally remove -* "new" cards. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void FixNew( AstFitsChan *this, int flag, int remove, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function searches the entire FitsChan for cards which are -* marked as new using the supplied flag (NEW1 or NEW2). If "remove" -* is non-zero, these cards are completely removed from the FitsChan -* (not just marked as used). If "remove" is zero, they are retained -* and the specified flag is cleared. - -* Parameters: -* this -* Pointer to the FitsChan. -* flag -* The flag to use; NEW1 or NEW2. -* remove -* Remove flagged cards from the FitsChan? -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function attempts to execute even if an error has occurred. -* - If any cards are removed, the current Card is left at "end-of-file" -* on exit. If no cards are removed, the original current card is -* retained. -*- -*/ - -/* Local Variables: */ - int *flags; /* Pointer to flags mask for the current card */ - int icard; /* Index of current card on entry */ - int ndeleted; /* Number of cards deleted by this call */ - -/* Return if no FitsChan was supplied, or if the FitsChan is empty. */ - if ( !this || !this->head ) return; - -/* Save the current card index, and rewind the FitsChan. */ - icard = astGetCard( this ); - astClearCard( this ); - -/* Indicate no cards have yet been deleted. */ - ndeleted = 0; - -/* Loop through the list of FitsCards in the FitsChan until the final - card is reached. */ - while( astOK && this->card ){ - -/* Get a pointer to the flags mask for this card. */ - flags = CardFlags( this, status ); - -/* See if the Card has been marked with the requeste new flag. */ - if( flags && ( (*flags) & flag ) ) { - -/* If requested, remove the card. This will automatically move the - current card on to the next card. */ - if( remove ){ - DeleteCard( this, method, class, status ); - ndeleted++; - -/* Otherwise, clear the flag. */ - } else { - *flags = (*flags) & ~flag; - -/* Increment the card count and move on to the next card. */ - MoveCard( this, 1, method, class, status ); - } - -/* Move on to the next card if this card is not marked with the requested - new flag. */ - } else { - MoveCard( this, 1, method, class, status ); - } - } - -/* If no cards were removed, we can safely re-instate the original - current card. Otherwise, the current card is left at "end-of-file". */ - if( ndeleted == 0 ) astSetCard( this, icard ); - -/* Return */ - return; -} - -static void FixUsed( AstFitsChan *this, int reset, int used, int remove, - const char *method, const char *class, int *status ){ - -/* -* -* Name: -* FixUsed - -* Purpose: -* Remove "provisionally used" flags from the whole FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void FixUsed( AstFitsChan *this, int reset, int used, int remove, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function searches the entire FitsChan for cards which are -* marked as "provisionally used". The "provisionally used" flag is -* cleared for each such card. In addition, if "used" is non-zero then -* each such card is flagged as having been "definitely used". If -* "remove" is non-zero, then all "provisionally used" cards are deleted -* from the FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. -* reset -* Set all cards so that they are neither provisionally used or -* definitely used. In this case neither the "used" nor the -* "remove" parameter are accssed. -* used -* Have the provisionally used cards definitely been used? -* remove -* Should provisionally used cards be deleted? -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function attempts to execute even if an error has occurred. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - FitsCard *card0; /* Pointer to current FitsCard */ - int *flags; /* Pointer to flags mask for the current card */ - int old_ignore_used; /* Original value of variable ignore_used */ - int old_status; /* Original inherited status value */ - int rep; /* Original error reporting flag */ - -/* Return if no FitsChan was supplied, or if the FitsChan is empty. */ - if ( !this || !this->head ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Temporarily clear any bad status value and supress error reporting in - this function. */ - old_status = astStatus; - astClearStatus; - rep = astReporting( 0 ); - -/* Indicate that we should not skip over cards marked as having been - read. */ - old_ignore_used = ignore_used; - ignore_used = 0; - -/* Save a pointer to the current card, and the reset the current card to - be the first card. */ - card0 = this->card; - astClearCard( this ); - -/* Loop through the list of FitsCards in the FitsChan until the final - card is reached. */ - while( this->card ){ - -/* Get a pointer to the flags mask for this card. */ - flags = CardFlags( this, status ); - -/* Reset both used flags if required. */ - if( reset ) { - *flags = (*flags) & ~PROVISIONALLY_USED; - *flags = (*flags) & ~USED; - MoveCard( this, 1, method, class, status ); - -/* Otherwise perform the actions indicated by parameters "used" and - "remove". */ - } else { - -/* See if the Card has been provisionally used. */ - if( flags && ( (*flags) & PROVISIONALLY_USED ) ) { - -/* Clear the provisionally used flag. */ - *flags = (*flags) & ~PROVISIONALLY_USED; - -/* If required, set the definitely used flag. */ - if( used ) *flags = (*flags) | USED; - -/* If required, delete the card. The next card is made current. If we are - about to delete the original current card, we need to update the - pointer to the card to be made current at the end of this function. - If we end up back at the head of the chain, indicate that we have - reached the end of file by setting card0 NULL. */ - if( remove ) { - if( card0 == this->card && card0 ) { - card0 = ( (FitsCard *) this->card )->next; - if( (void *) card0 == this->head ) card0 = NULL; - } - DeleteCard( this, method, class, status ); - -/* Otherwise, just move on to the next card. */ - } else { - MoveCard( this, 1, method, class, status ); - } - -/* If this card has not bee provisionally used, move on to the next card. */ - } else { - MoveCard( this, 1, method, class, status ); - } - } - } - -/* Re-instate the original current card. */ - this->card = card0; - -/* If this card is now flagged as definitely used, move forward to the - next un-used card. */ - flags = CardFlags( this, status ); - if( flags && (*flags & USED ) ) { - ignore_used = 1; - MoveCard( this, 1, method, class, status ); - } - -/* Re-instate the original flag indicating if cards marked as having been - read should be skipped over. */ - ignore_used = old_ignore_used; - -/* Re-instate the original status value and error reporting condition. */ - astReporting( rep ); - astSetStatus( old_status ); -} - -static void FormatCard( AstFitsChan *this, char *buf, const char *method, int *status ){ - -/* -* -* Name: -* FormatCard - -* Purpose: -* Formats the current card. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void FormatCard( AstFitsChan *this, char *buf, const char *method, int *status ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function write the current card into the supplied character -* buffer as a complete FITS header card. - -* Parameters: -* this -* Pointer to the FitsChan. -* buf -* A character string into which the header card is written. This -* should be at least 81 characters long. The returned string is -* padded with spaces upto column 80. A terminating null character -* is added. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - An error is reported if the requested header card does not conform to -* FITS standards. -* -*/ - -/* Local Variables: */ - const char *com; /* Pointer to comment string to use */ - int comlen; /* Length of comment string */ - int comstart; /* Column in which to start comment */ - int i; /* Loop counter for characters */ - int len; /* Output string length */ - int digits; /* No. of digits to use when formatting floating point values */ - int type; /* Card data type */ - -/* Check the global error status, and check the current card is defined. */ - if ( !astOK || astFitsEof( this ) ) return; - -/* Get a pointer to the comment to use and determine its length. */ - com = CardComm( this, status ); - comlen = ChrLen( com, status ); - -/* Copy the keyword name to the start of the output buffer, and store - its length. */ - len = (int) strlen( strcpy( buf, CardName( this, status ) ) ); - -/* Pad the name with spaces up to column 8. */ - while ( len < FITSNAMLEN ) buf[ len++ ] = ' '; - -/* If the card contains a keyword value... */ - type = CardType( this, status ); - if( type != AST__COMMENT ){ - -/* Get the number of digits to use when formatting floating point values. */ - digits = astGetFitsDigits( this ); - -/* Put an equals sign in column 9 (or a space if the keyword is a CONTINUE - card), followed by a space in column 10. */ - buf[ len++ ] = ( type == AST__CONTINUE ) ? ' ' : '='; - buf[ len++ ] = ' '; - -/* Format and store the keyword value, starting at column 11 and update the - output string length. */ - len += EncodeValue( this, buf + len, FITSNAMLEN + 3, digits, - method, status ); - -/* If there is a comment, determine which column it should start in so that - it ends in column 80. */ - if( com ){ - comstart = AST__FITSCHAN_FITSCARDLEN - ( comlen - 2 ) + 1; - -/* Adjust the starting column to 32 if possible, avoiding over-writing - the value, or running off the end of the card unless this is - unavoidable. */ - if ( comstart > FITSCOMCOL ) comstart = FITSCOMCOL; - if ( comstart < len + 2 ) comstart = len + 2; - -/* Pad the output buffer with spaces up to the start of the comment. */ - while ( len < comstart - 1 ) buf[ len++ ] = ' '; - -/* Then append "/ " to introduce the comment, truncating if the card - length forces this. */ - for ( i = 0; ( i < 2 ) && ( len < AST__FITSCHAN_FITSCARDLEN ); i++ ) { - buf[ len++ ] = "/ "[ i ]; - } - } - } - -/* Append any comment, truncating it if the card length forces - this. */ - if ( com ) { - for ( i = 0; com[ i ] && ( len < AST__FITSCHAN_FITSCARDLEN ); i++ ) { - buf[ len++ ] = com[ i ]; - } - } - -/* Pad with spaces up to the end of the card. */ - while ( len < AST__FITSCHAN_FITSCARDLEN ) buf[ len++ ] = ' '; - -/* Terminate it. */ - buf[ AST__FITSCHAN_FITSCARDLEN ] = 0; -} - -static int FullForm( const char *list, const char *test, int abbrev, int *status ){ -/* -* Name: -* FullForm - -* Purpose: -* Identify the full form of an option string. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int FullForm( const char *list, const char *test, int abbrev, int *status ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function identifies a supplied test option within a supplied -* list of valid options, and returns the index of the option within -* the list. The test option may be abbreviated, and case is -* insignificant. - -* Parameters: -* list -* A list of space separated option strings. -* test -* A candidate option string. -* abbrev -* 1 if abbreviations are to be accepted. Zero otherwise. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The index of the identified option within the supplied list, starting -* at zero. -1 is returned if the option is not recognised, and (if -* abbrev is 1 ) -2 if the option is ambiguous (no errors are reported -* in these cases). If abbrev is zero, the returned index will be the -* index of the first matching string. -* - -* Notes: -* - A value of -1 is returned if an error has already occurred, or -* if this function should fail for any reason. -*/ - -/* Local Variables: */ - char *context; /* Context used by strtok_r */ - char *llist; /* Pointer to a local copy of the options list */ - char *option; /* Pointer to the start of the next option */ - int i; /* Current option index */ - int len; /* Length of supplied option */ - int nmatch; /* Number of matching options */ - int ret; /* The returned index */ - -/* Initialise the answer to indicate that the option has not been - identified. */ - ret = -1; - -/* Avoid compiler warnings. */ - context = NULL; - -/* Check global status. */ - if( !astOK ) return ret; - -/* Take a local copy of the supplied options list. This is necessary since - "strtok" modified the string by inserting null characters. */ - llist = (char *) astStore( NULL, (void *) list, strlen(list) + 1 ); - if( astOK ){ - -/* Save the number of characters in the supplied test option (excluding - trailing spaces). */ - len = ChrLen( test, status ); - -/* Compare the supplied test option against each of the known options in - turn. Count the number of matches. */ - nmatch = 0; -#if HAVE_STRTOK_R - option = strtok_r( llist, " ", &context ); -#else - option = strtok( llist, " " ); -#endif - i = 0; - while( option ){ - -/* If every character in the supplied label matches the corresponding - character in the current test label we have a match. Increment the - number of matches and save the current item index. If abbreviation is - not allowed ensure that the lengths of the strings are equal. */ - if( !Ustrncmp( test, option, len, status ) && ( abbrev || - len == ChrLen( option, status ) ) ) { - nmatch++; - ret = i; - if( !abbrev ) break; - } - -/* Get a pointer to the next option. */ -#if HAVE_STRTOK_R - option = strtok_r( NULL, " ", &context ); -#else - option = strtok( NULL, " " ); -#endif - i++; - } - -/* Return -1 if no match was found. */ - if( !nmatch ){ - ret = -1; - -/* Return -2 if the option was ambiguous. */ - } else if( abbrev && nmatch > 1 ){ - ret = -2; - } - -/* Free the local copy of the options list. */ - llist = (char *) astFree( (void *) llist ); - } - -/* Return the answer. */ - return ret; -} - -static const char *GetAllWarnings( AstFitsChan *this, int *status ){ - -/* -*+ -* Name: -* astGetAllWarnings - -* Purpose: -* Return a list of all condition names. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* const char *GetAllWarnings( AstFitsChan *this ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function returns a space separated lits of the condition names -* currently recognized by the Warnings attribute. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Returned Value: -* A pointer to a static string holding the condition names. - -* Notes: -* - This routine does not check the inherited status. -*- -*/ - -/* Return the result. */ - return ALLWARNINGS; -} -const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { - -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* FitsChan member function (over-rides the protected astGetAttrib -* method inherited from the Channel class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a FitsChan, formatted as a character string. - -* Parameters: -* this -* Pointer to the FitsChan. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the FitsChan, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the FitsChan. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - const char *result; /* Pointer value to return */ - double dval; /* Double attribute value */ - int ival; /* Integer attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_object; - -/* Card. */ -/* ----- */ - if ( !strcmp( attrib, "card" ) ) { - ival = astGetCard( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* CardComm. */ -/* --------- */ - } else if ( !strcmp( attrib, "cardcomm" ) ) { - result = astGetCardComm( this ); - -/* CardName. */ -/* --------- */ - } else if ( !strcmp( attrib, "cardname" ) ) { - result = astGetCardName( this ); - -/* CardType. */ -/* --------- */ - } else if ( !strcmp( attrib, "cardtype" ) ) { - ival = astGetCardType( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Encoding. */ -/* --------- */ - } else if ( !strcmp( attrib, "encoding" ) ) { - ival = astGetEncoding( this ); - if ( astOK ) { - if( ival == NATIVE_ENCODING ){ - result = NATIVE_STRING; - } else if( ival == FITSPC_ENCODING ){ - result = FITSPC_STRING; - } else if( ival == FITSIRAF_ENCODING ){ - result = FITSIRAF_STRING; - } else if( ival == FITSAIPS_ENCODING ){ - result = FITSAIPS_STRING; - } else if( ival == FITSAIPSPP_ENCODING ){ - result = FITSAIPSPP_STRING; - } else if( ival == FITSCLASS_ENCODING ){ - result = FITSCLASS_STRING; - } else if( ival == FITSWCS_ENCODING ){ - result = FITSWCS_STRING; - } else if( ival == DSS_ENCODING ){ - result = DSS_STRING; - } else { - result = UNKNOWN_STRING; - } - } - -/* CDMatrix */ -/* -------- */ - } else if ( !strcmp( attrib, "cdmatrix" ) ) { - ival = astGetCDMatrix( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* DefB1950 */ -/* -------- */ - } else if ( !strcmp( attrib, "defb1950" ) ) { - ival = astGetDefB1950( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TabOK */ -/* ----- */ - } else if ( !strcmp( attrib, "tabok" ) ) { - ival = astGetTabOK( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* CarLin */ -/* ------ */ - } else if ( !strcmp( attrib, "carlin" ) ) { - ival = astGetCarLin( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* SipReplace */ -/* ---------- */ - } else if ( !strcmp( attrib, "sipreplace" ) ) { - ival = astGetSipReplace( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* FitsTol. */ -/* -------- */ - } else if ( !strcmp( attrib, "fitstol" ) ) { - dval = astGetFitsTol( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* PolyTan */ -/* ------- */ - } else if ( !strcmp( attrib, "polytan" ) ) { - ival = astGetPolyTan( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* SipOK */ -/* ------- */ - } else if ( !strcmp( attrib, "sipok" ) ) { - ival = astGetSipOK( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Iwc */ -/* --- */ - } else if ( !strcmp( attrib, "iwc" ) ) { - ival = astGetIwc( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Clean */ -/* ----- */ - } else if ( !strcmp( attrib, "clean" ) ) { - ival = astGetClean( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* FitsAxisOrder. */ -/* -------------- */ - } else if ( !strcmp( attrib, "fitsaxisorder" ) ) { - result = astGetFitsAxisOrder( this ); - -/* FitsDigits. */ -/* ----------- */ - } else if ( !strcmp( attrib, "fitsdigits" ) ) { - ival = astGetFitsDigits( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Ncard. */ -/* ------ */ - } else if ( !strcmp( attrib, "ncard" ) ) { - ival = astGetNcard( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Nkey. */ -/* ----- */ - } else if ( !strcmp( attrib, "nkey" ) ) { - ival = astGetNkey( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* AllWarnings */ -/* ----------- */ - } else if ( !strcmp( attrib, "allwarnings" ) ) { - result = astGetAllWarnings( this ); - -/* Warnings. */ -/* -------- */ - } else if ( !strcmp( attrib, "warnings" ) ) { - result = astGetWarnings( this ); - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static int GetCard( AstFitsChan *this, int *status ){ - -/* -*+ -* Name: -* astGetCard - -* Purpose: -* Get the value of the Card attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* int astGetCard( AstFitsChan *this ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function returns the value of the Card attribute for the supplied -* FitsChan. This is the index of the next card to be read from the -* FitsChan. The index of the first card is 1. If there are no more -* cards to be read, a value one greater than the number of cards in the -* FitsChan is returned. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Returned Value: -* The index of the next card to be read. - -* Notes: -* - A value of zero will be returned if the current card is not defined. -* - This function attempts to execute even if an error has occurred. -*- -*/ - -/* Local Variables: */ - const char *class; /* Pointer to class string */ - const char *method; /* Pointer to method string */ - FitsCard *card0; /* Pointer to current FitsCard */ - int index; /* Index of next FitsCard */ - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Return if no FitsChan was supplied, or if the FitsChan is empty. */ - if ( !this || !this->head ) return 0; - -/* Store the method and object class. */ - method = "astGetCard"; - class = astGetClass( this ); - -/* Save a pointer to the current card, and the reset the current card to - be the first card. */ - card0 = this->card; - astClearCard( this ); - -/* Count through the list of FitsCards in the FitsChan until the original - current card is reached. If the current card is not found (for instance - if it has been marked as deleted and we are currently skipping such cards), - this->card will be left null (end-of-file). */ - index = 1; - while( this->card != card0 && astOK && this->card ){ - -/* Increment the card count and move on to the next card. */ - index++; - MoveCard( this, 1, method, class, status ); - } - -/* Return the card index. */ - return index; -} - -static const char *GetCardComm( AstFitsChan *this, int *status ){ -/* -*+ -* Name: -* GetCardComm - -* Purpose: -* Get the value of the CardComm attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* const char *astGetCardComm( AstFitsChan *this) - -* Class Membership: -* FitsChan method. - -* Description: -* This function returns the value of the CardComm attribute for the -* supplied FitsChan. This is the comment for the current card. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Returned Value: -* A pointer to a static string holding the comment. A zero-length -* string is returned if the card has no comment. - -* Notes: -* - A value of NULL will be returned if an error has already -* occurred, or if this function should fail for any reason. -*- -*/ - -/* Local Variables */ - const char *result = NULL; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Get the comment for the current card. */ - result = CardComm( this, status ); - -/* Return a zero-length string if the card has no comment. */ - if( astOK && !result ) result = ""; - -/* Return the comment. */ - return result; -} - -static const char *GetCardName( AstFitsChan *this, int *status ){ -/* -*+ -* Name: -* GetCardName - -* Purpose: -* Get the value of the CardName attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* const char *astGetCardName( AstFitsChan *this) - -* Class Membership: -* FitsChan method. - -* Description: -* This function returns the value of the CardName attribute for the -* supplied FitsChan. This is the keyword name for the current card. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Returned Value: -* A pointer to a static string holding the keyword name. - -* Notes: -* - A value of NULL will be returned if an error has already -* occurred, or if this function should fail for any reason. -*- -*/ - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Return the keyword name of the current card. */ - return CardName( this, status ); -} - -static int GetCardType( AstFitsChan *this, int *status ){ -/* -*+ -* Name: -* GetCardType - -* Purpose: -* Get the value of the CardType attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* int astGetCardType( AstFitsChan *this ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function returns the value of teh CardType attribute for the supplied -* FitsChan. This is the data type of the keyword value for the current card. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Returned Value: -* An integer representing the data type of the current card. - -* Notes: -* - A value of AST__NOTYPE will be returned if an error has already -* occurred, or if this function should fail for any reason. -*- -*/ - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Return the data type of the current card. */ - return CardType( this, status ); -} - -static int GetFull( AstChannel *this_channel, int *status ) { -/* -* Name: -* GetFull - -* Purpose: -* Obtain the value of the Full attribute for a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GetFull( AstChannel *this, int *status ) - -* Class Membership: -* FitsChan member function (over-rides the protected astGetFull -* method inherited from the Channel class). - -* Description: -* This function return the integer value of the Full attribute for -* a FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Full attribute value. - -* Notes: -* - This function modifies the default Full value from 0 to -1 for -* the benefit of the FitsChan class. This prevents non-essential -* information being written by the astWrite method unless it is -* requested by explicitlt setting a Full value. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - int result; /* Result value to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* If the Full attribute us set, obtain its value using the parent class - method. */ - if ( astTestFull( this ) ) { - result = (* parent_getfull)( this_channel, status ); - -/* Otherwise, supply a default value of -1. */ - } else { - result = -1; - } - -/* Return the result. */ - return result; -} - -static FitsCard *GetLink( FitsCard *card, int next, const char *method, - const char *class, int *status ){ -/* -* Name: -* GetLink - -* Purpose: -* Get a pointer to the next or previous card in the list. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* FitsCard *GetLink( FitsCard *card, int next, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns the a pointer to either the next or previous FitsCard -* structure in the circular linked list of such structures stored in a -* FitsChan. A check is performed to ensure that the forward and -* backward links from the supplied card are consistent and an error -* is reported if they are not (so long as no previous error has been -* reported). Memory corruption can result in inconsistent links -* which can result in infinite loops if an attempt is made to scan the -* list. - -* Parameters: -* card -* The current card. -* next -* If non-zero, a pointer to the "next" card is returned. Otherwise -* a pointer to the "previous" card is returned. -* method -* Pointer to string holding the name of the calling method. -* class -* Pointer to string holding the object class. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the required card, or NULL if an error occurs. - -* Notes: -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - FitsCard *ret; /* Pointer to the returned card */ - -/* Check that the "next" link from the previous card points back to - the current card, and that the "prev" link from the next card points - back to the current card. */ - if( card && ( card->prev->next != card || - card->next->prev != card ) ){ - -/* Report an error so long as no previous error has been reported, and - return a NULL pointer. */ - if( astOK ){ - astError( AST__FCRPT, "%s(%s): A corrupted %s object has been " - "supplied.", status, method, class, class ); - } - ret = NULL; - -/* If the links are good, return a pointer to the required card. */ - } else { - ret = next ? card->next : card->prev; - } - -/* Return the result. */ - return ret; -} - -static int GetNcard( AstFitsChan *this, int *status ){ - -/* -*+ -* Name: -* astGetNcard - -* Purpose: -* Get the value of the Ncard attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* int astGetNcard( AstFitsChan *this ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function returns the value of the Ncard attribute for the supplied -* FitsChan. This is the number of cards currently in the FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Returned Value: -* The number of cards currently in the FitsChan. - -* Notes: -* - A value of zero will be returned if an error has already -* occurred, or if this function should fail for any reason. -*- -*/ - -/* Local Variables: */ - const char *class; /* Pointer to class string */ - const char *method; /* Pointer to method string */ - FitsCard *card0; /* Pointer to current card on entry */ - int ncard; /* Number of cards so far */ - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Return zero if an error has already occurred, or no FitsChan was supplied, - or the FitsChan is empty. */ - if ( !astOK || !this || !this->head ) return 0; - -/* Store the method and object class. */ - method = "astGetNcard"; - class = astGetClass( this ); - -/* Save a pointer to the current card, and then reset the current card to - be the first card. */ - card0 = this->card; - astClearCard( this ); - -/* Count through the cards in the FitsChan until the end of file is reached. */ - ncard = 0; - while( astOK && this->card ){ - -/* Increment the card count and move on to the next card. */ - ncard++; - MoveCard( this, 1, method, class, status ); - } - -/* Reset the current card to be the original current card. */ - this->card = card0; - -/* Return the result. */ - return astOK ? ncard : 0; -} - -static int GetNkey( AstFitsChan *this, int *status ){ - -/* -*+ -* Name: -* astGetNkey - -* Purpose: -* Get the value of the Nkey attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* int astGetNkey( AstFitsChan *this ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function returns the value of the Nkey attribute for the supplied -* FitsChan. This is the number of unique keywords currently in the -* FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Returned Value: -* The number of unique keywords currently in the FitsChan. - -* Notes: -* - A value of zero will be returned if an error has already -* occurred, or if this function should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstKeyMap *km; /* KeyMap holding unique keyword names */ - FitsCard *card0; /* Pointer to current card on entry */ - const char *class; /* Pointer to class string */ - const char *method; /* Pointer to method string */ - int nkey; /* Returned Nkey value */ - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Return zero if an error has already occurred, or no FitsChan was supplied, - or the FitsChan is empty. */ - if ( !astOK || !this || !this->head ) return 0; - -/* Store the method and object class. */ - method = "astGetNkey"; - class = astGetClass( this ); - -/* Create an empty KeyMap to hold the unused keyword names */ - km = astKeyMap( " ", status ); - -/* Save a pointer to the current card, and then reset the current card to - be the first card. */ - card0 = this->card; - astClearCard( this ); - -/* Loop through the cards in the FitsChan until the end of file is reached. */ - while( astOK && this->card ){ - -/* Get the keyword name for the current card and add it to the keymap. */ - astMapPut0I( km, CardName( this, status ), 0, NULL ); - -/* Move on to the next unused card. */ - MoveCard( this, 1, method, class, status ); - } - -/* Reset the current card to be the original current card. */ - this->card = card0; - -/* Get the number of keywords. */ - nkey = astMapSize( km ); - -/* Annull the KeyMap . */ - km = astAnnul( km ); - -/* Return the result. */ - return astOK ? nkey : 0; -} - -static void GetNextData( AstChannel *this_channel, int skip, char **name, - char **val, int *status ) { -/* -* Name: -* GetNextData - -* Purpose: -* Read the next item of data from a data source. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void GetNextData( AstChannel *this, int skip, char **name, char **val ) - -* Class Membership: -* FitsChan member function (over-rides the protected -* astGetNextData method inherited from the Channel class). - -* Description: -* This function reads the next item of input data from a data -* source associated with a FitsChan and returns the result. It -* decodes the data item and returns name/value pairs ready for -* use. - -* Parameters: -* this -* Pointer to the FitsChan. -* skip -* A non-zero value indicates that a new Object is to be read, -* and that all input data up to the next "Begin" item are to be -* skipped in order to locate it. This is useful if the data -* source contains AST objects interspersed with other data (but -* note that these other data cannot appear inside AST Objects, -* only between them). -* -* A zero value indicates that all input data are significant -* and the next item will therefore be read and an attempt made -* to interpret it whatever it contains. Any other data -* inter-mixed with AST Objects will then result in an error. -* name -* An address at which to store a pointer to a null-terminated -* dynamically allocated string containing the name of the next -* item in the input data stream. This name will be in lower -* case with no surrounding white space. It is the callers -* responsibilty to free the memory holding this string (using -* astFree) when it is no longer required. -* -* A NULL pointer value will be returned (without error) to -* indicate when there are no further input data items to be -* read. -* val -* An address at which to store a pointer to a null-terminated -* dynamically allocated string containing the value associated -* with the next item in the input data stream. No case -* conversion is performed on this string and all white space is -* potentially significant. It is the callers responsibilty to -* free the memory holding this string (using astFree) when it -* is no longer required. -* -* The returned pointer will be NULL if an Object data item is -* read (see the "Data Representation" section). - -* Data Representation: - -* The returned data items fall into the following categories: -* -* - Begin: Identified by the name string "begin", this indicates -* the start of an Object definition. The associated value string -* gives the class name of the Object being defined. -* -* - IsA: Identified by the name string "isa", this indicates the -* end of the data associated with a particular class structure -* within the definiton of a larger Object. The associated value -* string gives the name of the class whose data have just been -* read. -* -* - End: Identified by the name string "end", this indicates the -* end of the data associated with a complete Object -* definition. The associated value string gives the class name of -* the Object whose definition is being ended. -* -* - Non-Object: Identified by any other name string plus a -* non-NULL "val" pointer, this gives the value of a non-Object -* structure component (instance variable). The name identifies -* which instance variable it is (within the context of the class -* whose data are being read) and the value is encoded as a string. -* -* - Object: Identified by any other name string plus a NULL "val" -* pointer, this identifies the value of an Object structure -* component (instance variable). The name identifies which -* instance variable it is (within the context of the class whose -* data are being read) and the value is given by subsequent data -* items (so the next item should be a "Begin" item). - -* Notes: -* - NULL pointer values will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Constants: */ -#define BUFF_LEN 100 /* Length of formatting buffer */ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - char *keyword; /* Pointer to current keyword string */ - char *newdata; /* Pointer to stripped string value */ - char *upq; /* Pointer to unprequoted string */ - char buff[ BUFF_LEN + 1 ]; /* Buffer for formatting values */ - const char *class; /* Pointer to object class */ - const char *method; /* Pointer to method name */ - int cont; /* String ends with an ampersand? */ - int done; /* Data item found? */ - int freedata; /* Should the data pointer be freed? */ - int i; /* Loop counter for keyword characters */ - int len; /* Length of current keyword */ - int nc; /* Number of characters read by "astSscanf" */ - int nn; /* No. of characters after UnPreQuoting */ - int type; /* Data type code */ - void *data; /* Pointer to current data value */ - -/* Initialise the returned pointer values. */ - *name = NULL; - *val = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Store the method name and object class. */ - method = "astRead"; - class = astGetClass( this ); - -/* Loop to consider successive cards stored in the FitsChan (starting - at the "current" card) until a valid data item is read or "end of - file" is reached. Also quit the loop if an error occurs. */ - done = 0; - newdata = NULL; - while ( !done && !astFitsEof( this ) && astOK ){ - -/* Obtain the keyword string, data type code and data value pointer - from the current card. */ - keyword = CardName( this, status ); - type = CardType( this, status ); - data = CardData( this, NULL, status ); - -/* Mark all cards as having been used unless we are skipping over cards which - may not be related to AST. */ - if( !skip ) MarkCard( this, status ); - -/* Ignore comment cards. */ - if ( type != AST__COMMENT ) { - -/* Native encoding requires trailing white space to be removed from - string values (so that null strings can be distinguished from blank - strings). Do this now. */ - freedata = 0; - if ( ( type == AST__STRING || type == AST__CONTINUE ) && data ){ - newdata = (char *) astStore( NULL, data, strlen( (char *) data ) + 1 ); - if( newdata ){ - newdata[ ChrLen( data, status ) ] = 0; - data = (void *) newdata; - freedata = 1; - } - } - -/* Obtain the keyword length and test the card to identify the type of - AST data item (if any) that it represents. */ - len = (int) strlen( keyword ); - -/* "Begin" item. */ -/* ------------- */ - -/* This is identified by a string value and a keyword of the form - "BEGASTxx", where "xx" are characters encoding a sequence - number. */ - if ( ( type == AST__STRING ) && - ( nc = 0, - ( 0 == astSscanf( keyword, "BEGAST" - "%*1[" SEQ_CHARS "]" - "%*1[" SEQ_CHARS "]%n", &nc ) ) - && ( nc >= len ) ) ) { - -/* Note we have found a data item. */ - done = 1; - -/* Set the returned name to "begin" and extract the associated class - name from the string value. Store both of these in dynamically - allocated strings. */ - *name = astString( "begin", 5 ); - *val = UnPreQuote( (const char *) data, status ); - -/* Indicate that the current card has been used. */ - MarkCard( this, status ); - -/* The "begin" item will be preceded by a header of COMMENT cards. Mark - them as having been used. */ - ComBlock( this, -1, method, class, status ); - -/* "IsA" item. */ -/* ----------- */ - -/* This is identified by a string value and a keyword of the form - "ISAxx", where "xx" are characters encoding a sequence - number. Don't accept the item if we are skipping over cards looking - for a "Begin" item. */ - } else if ( !skip && - ( type == AST__STRING ) && - ( nc = 0, - ( 0 == astSscanf( keyword, - "ISA" - "%*1[" SEQ_CHARS "]" - "%*1[" SEQ_CHARS "]%n", &nc ) ) - && ( nc >= len ) ) ) { - -/* Note we have found a data item. */ - done = 1; - -/* Set the returned name to "isa" and extract the associated class - name from the string value. Store both of these in dynamically - allocated strings. */ - *name = astString( "isa", 3 ); - *val = UnPreQuote( (const char *) data, status ); - -/* "End" item. */ -/* ----------- */ - -/* This is identified by a string value and a keyword of the form - "ENDASTxx", where "xx" are characters encoding a sequence - number. Don't accept the item if we are skipping over cards looking - for a "Begin" item. */ - } else if ( !skip && - ( type == AST__STRING ) && - ( nc = 0, - ( 0 == astSscanf( keyword, - "ENDAST" - "%*1[" SEQ_CHARS "]" - "%*1[" SEQ_CHARS "]%n", &nc ) ) - && ( nc >= len ) ) ) { - -/* Note we have found a data item. */ - done = 1; - -/* Set the returned name to "end" and extract the associated class - name from the string value. Store both of these in dynamically - allocated strings. */ - *name = astString( "end", 3 ); - *val = UnPreQuote( (const char *) data, status ); - -/* The "end" item eill be followed by a footer of COMMENT cards. Mark - these cards as having been used. */ - ComBlock( this, 1, method, class, status ); - -/* Object or data item. */ -/* -------------------- */ - -/* These are identified by a string, int, or double value, and a - keyword ending in two characters encoding a sequence number. Don't - accept the item if we are skipping over cards looking for a "Begin" - item. */ - } else if ( !skip && - ( ( type == AST__STRING ) || - ( type == AST__INT ) || - ( type == AST__FLOAT ) ) && - ( len > 2 ) && - strchr( SEQ_CHARS, keyword[ len - 1 ] ) && - strchr( SEQ_CHARS, keyword[ len - 2 ] ) ) { - -/* Note we have found a data item. */ - done = 1; - -/* Set the returned name by removing the last two characters from the - keyword and converting to lower case. Store this in a dynamically - allocated string. */ - *name = astString( keyword, len - 2 ); - for ( i = 0; ( *name )[ i ]; i++ ) { - ( *name )[ i ] = tolower( ( *name )[ i ] ); - } - -/* Classify the data type. */ - switch ( type ) { - -/* If the value is a string, test if it is zero-length. If so, this - "null" value indicates an Object data item (whose definition - follows), so leave the returned value pointer as NULL. Otherwise, - we have a string data item, so extract its value and store it in a - dynamically allocated string. */ - case AST__STRING: - if ( *( (char *) data ) ) { - -/* A long string value may be continued on subsequent CONTINUE cards. See - if the current string may be continued. This is the case if the final - non-blank character (before UnPreQuoting) is an ampersand. */ - cont = ( ((char *) data)[ ChrLen( data, status ) - 1 ] == '&' ); - -/* If the string does not end with an ampersand, just UnPreQUote it and - return a copy. */ - if( !cont ) { - *val = UnPreQuote( (const char *) data, status ); - -/* Otherwise, initialise the returned string to hold a copy of the keyword - value. */ - } else { - nc = strlen( (const char *) data ); - *val = astStore( NULL, (const char *) data, nc + 1 ); - -/* Loop round reading any subsequent CONTINUE cards. Leave the loop when - the end-of-file is hit, or an error occurs. */ - while( cont && MoveCard( this, 1, method, class, status ) && - astOK ){ - -/* See if this is a CONTINUE card. If so, get its data pointer. */ - if( CardType( this, status ) == AST__CONTINUE ){ - data = CardData( this, NULL, status ); - -/* See if the CONTINUE card ends with an ampersand (i.e. if there is - a possibility of there being any remaining CONTINUE cards). */ - cont = ( ( (char *) data)[ ChrLen( data, status ) - 1 ] == '&' ); - -/* UnPreQUote it. */ - upq = UnPreQuote( (const char *) data, status ); - if( !astOK ) break; - -/* Expand the memory for the returned string to hold the new string. */ - nn = strlen( upq ); - *val = astRealloc( *val, nc + nn ); - if( !astOK ) break; - -/* Copy the new string into the expanded memory, so that the first - character of the new string over-writes the trailing ampersand - currently in the buffer. */ - strcpy( *val + nc - 1, upq ); - -/* Release the memory holding the UnPreQUoted string . */ - upq = astFree( upq ); - -/* Update the current length of the returned string. */ - nc += nn - 1; - -/* Mark the current card as having been read. */ - MarkCard( this, status ); - -/* Report an error if this is not a CONTINUE card. */ - } else { - astError( AST__BADIN, "%s(%s): One or more " - "FITS \"CONTINUE\" cards are missing " - "after the card for keyword \"%s\".", status, - method, class, keyword ); - } - } - } - } - break; - -/* If the value is an int, format it and store the result in a - dynamically allocated string. */ - case AST__INT: - (void) sprintf( buff, "%d", *( (int *) data ) ); - *val = astString( buff, (int) strlen( buff ) ); - break; - -/* If the value is a double, format it and store the result in a - dynamically allocated string. */ - case AST__FLOAT: - (void) sprintf( buff, "%.*g", AST__DBL_DIG, *( (double *) data ) ); - CheckZero( buff, *( (double *) data ), 0, status ); - *val = astString( buff, (int) strlen( buff ) ); - break; - } - -/* Anything else. */ -/* -------------- */ - -/* If the input line didn't match any of the above and the "skip" flag - is not set, then report an error.. */ - } else if ( !skip ) { - astError( AST__BADIN, - "%s(%s): Cannot interpret the input data given by " - "FITS keyword \"%s\".", status, method, class, keyword ); - } - -/* Free any memory used to hold stripped string data. */ - if( freedata ) newdata = (char *) astFree( (void *) newdata ); - } - -/* Increment the current card. */ - MoveCard( this, 1, method, class, status ); - } - -/* If an error occurred, ensure that any allocated memory is freed and - that NULL pointer values are returned. */ - if ( !astOK ) { - *name = astFree( *name ); - *val = astFree( *val ); - } - -/* Undefine macros local to this function. */ -#undef BUFF_LEN -} - -static int GetSkip( AstChannel *this_channel, int *status ) { -/* -* Name: -* GetSkip - -* Purpose: -* Obtain the value of the Skip attribute for a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int GetSkip( AstChannel *this, int *status ) - -* Class Membership: -* FitsChan member function (over-rides the protected astGetSkip -* method inherited from the Channel class). - -* Description: -* This function return the (boolean) integer value of the Skip -* attribute for a FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Skip attribute value. - -* Notes: -* - This function modifies the default Skip value from 0 to 1 for -* the benefit of the FitsChan class. This default value allows the -* astRead method to skip over unrelated FITS keywords when -* searching for the next Object to read. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - int result; /* Result value to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* If the Skip attribute us set, obtain its value using the parent class - method. */ - if ( astTestSkip( this ) ) { - result = (* parent_getskip)( this_channel, status ); - -/* Otherwise, supply a default value of 1. */ - } else { - result = 1; - } - -/* Return the result. */ - return result; -} - -static int GetValue( AstFitsChan *this, const char *keyname, int type, - void *value, int report, int mark, const char *method, - const char *class, int *status ){ -/* -* Name: -* GetValue - -* Purpose: -* Obtain a FITS keyword value. - -* Type: -* Private function. - -* Synopsis: -* int GetValue( AstFitsChan *this, const char *keyname, int type, void *value, -* int report, int mark, const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function gets a value for the specified keyword from the -* supplied FitsChan, and stores it in the supplied buffer. Optionally, -* the keyword is marked as having been read into an AST object so that -* it is not written out when the FitsChan is deleted. - -* Parameters: -* this -* A pointer to the FitsChan containing the keyword values to be -* read. -* keyname -* A pointer to a string holding the keyword name. -* type -* The FITS data type in which to return the keyword value. If the -* stored value is not of the requested type, it is converted if -* possible. -* value -* A pointer to a buffer of suitable size to receive the keyword -* value. The supplied value is left unchanged if the keyword is -* not found. -* report -* Should an error be reported if the keyword cannot be found, or -* cannot be converted to the requested type? -* mark -* Should the card be marked as having been used? -* method -* A string holding the name of the calling method. -* class -* A string holding the object class. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the keyword does not exist in "this", or cannot be -* converted to the requested type. One is returned otherwise. - -* Notes: -* - An error is reported if the keyword value is undefined. -* - A value of zero is returned if an error has already occurred, -* or if an error occurs within this function. -*/ - -/* Local Variables: */ - int icard; /* Current card index */ - int ret; /* Returned value */ - -/* Check the status */ - if( !astOK ) return 0; - -/* Save the current card index. */ - icard = astGetCard( this ); - -/* Attempt to find the supplied keyword. */ - ret = SearchCard( this, keyname, method, class, status ); - -/* If the keyword was found, convert the current card's data value and copy - it to the supplied buffer. */ - if( ret ){ - if( CnvValue( this, type, 0, value, method, status ) ) { - -/* If required, mark it as having been read into an AST object. */ - if( mark ) MarkCard( this, status ); - -/* If the value is undefined, report an error if "report" is non-zero. */ - if( type == AST__UNDEF && report && astOK ) { - ret = 0; - astError( AST__FUNDEF, "%s(%s): FITS keyword \"%s\" has no value.", - status, method, class, keyname ); - } - -/* If the value could not be converted to the requested data, type report - an error if reporting is enabled. */ - } else { - ret = 0; - if( report && astOK ){ - astError( AST__FTCNV, "%s(%s): Cannot convert FITS keyword '%s' to %s.", - status, method, class, keyname, type_names[ type ] ); - } - } - -/* If the keyword was not found, report an error if "report" is non-zero. */ - } else if( report && astOK ){ - astError( AST__BDFTS, "%s(%s): Unable to find a value for FITS " - "keyword \"%s\".", status, method, class, keyname ); - } - -/* Reinstate the original current card index. */ - astSetCard( this, icard ); - -/* If an error has occurred, return 0. */ - if( !astOK ) ret = 0; - -/* Return the result. */ - return ret; -} - -static int GetValue2( AstFitsChan *this1, AstFitsChan *this2, const char *keyname, - int type, void *value, int report, const char *method, - const char *class, int *status ){ -/* -* Name: -* GetValue2 - -* Purpose: -* Obtain a FITS keyword value from one of two FitsChans. - -* Type: -* Private function. - -* Synopsis: -* int GetValue2( AstFitsChan *this1, AstFitsChan *this2, const char *keyname, -* int type, void *value, int report, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function attempts to get a value for the specified keyword from -* the first supplied FitsChan. If this fails (due to the FitsChan not -* containing a value for the ketword) then an attempt is made to get -* a value for the keyword from the second supplied FitsChan. - -* Parameters: -* this1 -* A pointer to the first FitsChan to be used. -* this2 -* A pointer to the second FitsChan to be used. -* keyname -* A pointer to a string holding the keyword name. -* type -* The FITS data type in which to return the keyword value. If the -* stored value is not of the requested type, it is converted if -* possible. -* value -* A pointer to a buffer of suitable size to receive the keyword -* value. The supplied value is left unchanged if the keyword is -* not found. -* report -* Should an error be reported if the keyword cannot be found, or -* cannot be converted to the requested type? -* method -* A string holding the name of the calling method. -* class -* A string holding the object class. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the keyword does not exist in either FitsChan, or cannot be -* converted to the requested type. One is returned otherwise. - -* Notes: -* - A value of zero is returned if an error has already occurred, -* or if an error occurs within this function. -* - If the card is found in the first FitsChan, it is not marked as -* having been used. If the card is found in the second FitsChan, it is -* marked as having been used. -*/ - -/* Local Variables: */ - int ret; /* Returned value */ - -/* Check the status */ - if( !astOK ) return 0; - -/* Try the first FitsChan. If this fails try the second. Do not report - an error if the keyword is not found in the first FitsChan (this will - be done, if required, once the second FitsChan has been searched). */ - ret = GetValue( this1, keyname, type, value, 0, 0, method, class, status ); - if( ! ret ) { - ret = GetValue( this2, keyname, type, value, report, 1, method, class, status ); - } - -/* If an error has occurred, return 0. */ - if( !astOK ) ret = 0; - -/* Return the result. */ - return ret; -} - -static int HasAIPSSpecAxis( AstFitsChan *this, const char *method, - const char *class, int *status ){ - -/* -* Name: -* HasAIPSSpecAxis - -* Purpose: -* Does the FitsChan contain an AIPS spectral CTYPE keyword? - -* Type: -* Private function. - -* Synopsis: - -* int HasAIPSSpecAxis( AstFitsChan *this, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function returns a non-zero value if the FitsCHan contains a -* CTYPE value which conforms to the non-standard system used by AIPS. - -* Parameters: -* this -* A pointer to the FitsChan to be used. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if an AIPS spectral CTYPE keyword was found. -*/ - -/* Local Variables: */ - char *assys; /* AIPS standard of rest type */ - char *astype; /* AIPS spectral type */ - char *cval; /* Pointer to character string */ - int j; /* Current axis index */ - int jhi; /* Highest axis index with a CTYPE */ - int jlo; /* Lowest axis index with a CTYPE */ - int ret; /* Returned value */ - -/* Initialise */ - ret = 0; - -/* Check the status */ - if( !astOK ) return ret; - -/* If the FitsChan contains any CTYPE values, convert the bounds from - one-based to zero-based, and loop round them all. */ - if( astKeyFields( this, "CTYPE%1d", 1, &jhi, &jlo ) ) { - jlo--; - jhi--; - for( j = jlo; j <= jhi; j++ ) { - -/* Get the next CTYPE value. If found, see if it is an AIPS spectral - CTYPE value. */ - if( GetValue( this, FormatKey( "CTYPE", j + 1, -1, ' ', status ), - AST__STRING, (void *) &cval, 0, 0, method, - class, status ) ){ - if( IsAIPSSpectral( cval, &astype, &assys, status ) ) { - ret = 1; - break; - } - } - } - } - -/* If an error has occurred, return 0. */ - if( !astOK ) ret = 0; - -/* Return the result. */ - return ret; -} - -static int HasCard( AstFitsChan *this, const char *name, - const char *method, const char *class, int *status ){ - -/* -* Name: -* HasCard - -* Purpose: -* Check if the FitsChan contains a specified keyword. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int HasCard( AstFitsChan *this, const char *name, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns a non-zero value if the FitsChan contains the given keyword, -* and zero otherwise. The current card is unchanged. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* Pointer to a string holding the keyword name. -* method -* Pointer to string holding name of calling method. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if a card was found refering to the given -* keyword. Otherwise zero is returned. -*/ - -/* Check the supplied pointers (we can rely on astMapHasKey to check the - inherited status). */ - if( !name || !this || !this->keywords ) return 0; - -/* Search the KeyMap holding the keywords currently in the FitsChan, - returning non-zero if the keyword was found. A KeyMap is used because - it uses a hashing algorithm to find the entries and is therefore a lot - quicker than searching through the list of linked FitsCards. */ - return astMapHasKey( this->keywords, name ); -} -void astInitFitsChanVtab_( AstFitsChanVtab *vtab, const char *name, int *status ) { - -/* -*+ -* Name: -* astInitFitsChanVtab - -* Purpose: -* Initialise a virtual function table for a FitsChan. - -* Type: -* Protected function. - -* Synopsis: -* #include "fitschan.h" -* void astInitFitsChanVtab( AstFitsChanVtab *vtab, const char *name ) - -* Class Membership: -* FitsChan vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the FitsChan class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstChannelVtab *channel; /* Pointer to Channel component of Vtab */ - char buf[ 100 ]; /* Buffer large enough to store formatted INT_MAX */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitChannelVtab( (AstChannelVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAFitsChan) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstChannelVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ - -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->PutCards = PutCards; - vtab->PutFits = PutFits; - vtab->DelFits = DelFits; - vtab->GetTables = GetTables; - vtab->PutTables = PutTables; - vtab->PutTable = PutTable; - vtab->TableSource = TableSource; - vtab->SetTableSource = SetTableSource; - vtab->RemoveTables = RemoveTables; - vtab->PurgeWCS = PurgeWCS; - vtab->RetainFits = RetainFits; - vtab->FindFits = FindFits; - vtab->KeyFields = KeyFields; - vtab->ReadFits = ReadFits; - vtab->ShowFits = ShowFits; - vtab->WriteFits = WriteFits; - vtab->EmptyFits = EmptyFits; - vtab->FitsEof = FitsEof; - vtab->GetFitsCF = GetFitsCF; - vtab->GetFitsCI = GetFitsCI; - vtab->GetFitsF = GetFitsF; - vtab->GetFitsI = GetFitsI; - vtab->GetFitsL = GetFitsL; - vtab->TestFits = TestFits; - vtab->GetFitsS = GetFitsS; - vtab->GetFitsCN = GetFitsCN; - vtab->FitsGetCom = FitsGetCom; - vtab->SetFitsCom = SetFitsCom; - vtab->SetFitsCF = SetFitsCF; - vtab->SetFitsCI = SetFitsCI; - vtab->SetFitsF = SetFitsF; - vtab->SetFitsI = SetFitsI; - vtab->SetFitsL = SetFitsL; - vtab->SetFitsU = SetFitsU; - vtab->SetFitsS = SetFitsS; - vtab->SetFitsCN = SetFitsCN; - vtab->SetFitsCM = SetFitsCM; - vtab->ClearCard = ClearCard; - vtab->TestCard = TestCard; - vtab->SetCard = SetCard; - vtab->GetCard = GetCard; - vtab->ClearFitsDigits = ClearFitsDigits; - vtab->TestFitsDigits = TestFitsDigits; - vtab->SetFitsDigits = SetFitsDigits; - vtab->GetFitsDigits = GetFitsDigits; - vtab->ClearFitsAxisOrder = ClearFitsAxisOrder; - vtab->TestFitsAxisOrder = TestFitsAxisOrder; - vtab->SetFitsAxisOrder = SetFitsAxisOrder; - vtab->GetFitsAxisOrder = GetFitsAxisOrder; - vtab->ClearDefB1950 = ClearDefB1950; - vtab->TestDefB1950 = TestDefB1950; - vtab->SetDefB1950 = SetDefB1950; - vtab->GetDefB1950 = GetDefB1950; - vtab->ClearTabOK = ClearTabOK; - vtab->TestTabOK = TestTabOK; - vtab->SetTabOK = SetTabOK; - vtab->GetTabOK = GetTabOK; - vtab->ClearCarLin = ClearCarLin; - vtab->TestCarLin = TestCarLin; - vtab->SetCarLin = SetCarLin; - vtab->GetCarLin = GetCarLin; - vtab->ClearSipReplace = ClearSipReplace; - vtab->TestSipReplace = TestSipReplace; - vtab->SetSipReplace = SetSipReplace; - vtab->GetSipReplace = GetSipReplace; - vtab->ClearFitsTol = ClearFitsTol; - vtab->TestFitsTol = TestFitsTol; - vtab->SetFitsTol = SetFitsTol; - vtab->GetFitsTol = GetFitsTol; - vtab->ClearPolyTan = ClearPolyTan; - vtab->TestPolyTan = TestPolyTan; - vtab->SetPolyTan = SetPolyTan; - vtab->GetPolyTan = GetPolyTan; - vtab->ClearSipOK = ClearSipOK; - vtab->TestSipOK = TestSipOK; - vtab->SetSipOK = SetSipOK; - vtab->GetSipOK = GetSipOK; - vtab->ClearIwc = ClearIwc; - vtab->TestIwc = TestIwc; - vtab->SetIwc = SetIwc; - vtab->GetIwc = GetIwc; - vtab->ClearWarnings = ClearWarnings; - vtab->TestWarnings = TestWarnings; - vtab->SetWarnings = SetWarnings; - vtab->GetWarnings = GetWarnings; - vtab->GetCardType = GetCardType; - vtab->GetCardName = GetCardName; - vtab->GetCardComm = GetCardComm; - vtab->GetNcard = GetNcard; - vtab->GetNkey = GetNkey; - vtab->GetAllWarnings = GetAllWarnings; - vtab->ClearEncoding = ClearEncoding; - vtab->TestEncoding = TestEncoding; - vtab->SetEncoding = SetEncoding; - vtab->GetEncoding = GetEncoding; - vtab->ClearClean = ClearClean; - vtab->TestClean = TestClean; - vtab->SetClean = SetClean; - vtab->GetClean = GetClean; - vtab->ClearCDMatrix = ClearCDMatrix; - vtab->TestCDMatrix = TestCDMatrix; - vtab->SetCDMatrix = SetCDMatrix; - vtab->GetCDMatrix = GetCDMatrix; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - channel = (AstChannelVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - parent_write = channel->Write; - channel->Write = Write; - parent_read = channel->Read; - channel->Read = Read; - parent_getskip = channel->GetSkip; - channel->GetSkip = GetSkip; - parent_getfull = channel->GetFull; - channel->GetFull = GetFull; - channel->WriteBegin = WriteBegin; - channel->WriteIsA = WriteIsA; - channel->WriteEnd = WriteEnd; - channel->WriteInt = WriteInt; - channel->WriteDouble = WriteDouble; - channel->WriteString = WriteString; - channel->WriteObject = WriteObject; - channel->GetNextData = GetNextData; - parent_setsourcefile = channel->SetSourceFile; - channel->SetSourceFile = SetSourceFile; - -/* Declare the class dump, copy and delete functions.*/ - astSetDump( vtab, Dump, "FitsChan", "I/O channels to FITS files" ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - astSetDelete( (AstObjectVtab *) vtab, Delete ); - -/* Max number of characters needed to format an int. */ - LOCK_MUTEX4 - sprintf( buf, "%d", INT_MAX ); - int_dig = strlen( buf ); - -/* Create a pair of MJD TimeFrames which will be used for converting to and - from TDB. */ - astBeginPM; - if( !tdbframe ) tdbframe = astTimeFrame( "system=MJD,timescale=TDB", status ); - if( !timeframe ) timeframe = astTimeFrame( "system=MJD", status ); - astEndPM; - UNLOCK_MUTEX4 - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void InsCard( AstFitsChan *this, int overwrite, const char *name, - int type, void *data, const char *comment, - const char *method, const char *class, int *status ){ - -/* -* Name: -* InsCard - -* Purpose: -* Inserts a card into a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void InsCard( AstFitsChan *this, int overwrite, const char *name, -* int type, void *data, const char *comment, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Either appends a new card to a FitsChan, or over-writes an existing -* card, holding the supplied keyword name, value and comment. - -* Parameters: -* this -* Pointer to the FitsChan containing the filters to apply to the -* keyword name. If a NULL pointer is supplied, no filtering is applied. -* overwrite -* If non-zero, the new card over-writes the current card given by -* the "Card" attribute, and the current card is incremented so -* that it refers to the next card. Otherwise, the new card is -* inserted in front of the current card and the current card is -* left unchanged. -* name -* Pointer to a string holding the keyword name of the new card. -* type -* An integer value representing the data type of the keyword. -* data -* Pointer to the data associated with the keyword. -* comment -* Pointer to a null-terminated string holding a comment. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - An error is reported if an attempt is made to change the data type -* of an existing card. -* - If a type of AST__COMMENT is supplied, then any data value (of any -* type) associated with an existing card is left unchanged. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - int flags; /* Flags to assign to new card */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* If the current card is to be over-written, delete the current card (the - next card in the list, if any, will become the new current card). */ - if( overwrite ) DeleteCard( this, method, class, status ); - -/* If requested, set both NEW flags for the new card. */ - flags = ( mark_new ) ? ( NEW1 | NEW2 ): 0; - -/* Insert the new card into the list, just before the current card. */ - NewCard( this, name, type, data, comment, flags, status ); -} - -static int IRAFFromStore( AstFitsChan *this, FitsStore *store, - const char *method, const char *class, int *status ){ - -/* -* Name: -* IRAFFromStore - -* Purpose: -* Store WCS keywords in a FitsChan using FITS-IRAF encoding. - -* Type: -* Private function. - -* Synopsis: - -* int IRAFFromStore( AstFitsChan *this, FitsStore *store, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function copies the WCS information stored in the supplied -* FitsStore into the supplied FitsChan, using FITS-IRAF encoding. -* -* IRAF encoding is like FITS-WCS encoding but with the following -* restrictions: -* -* 1) The celestial projection must not have any projection parameters -* which are not set to their default values. The one exception to this -* is that SIN projections are acceptable if the associated projection -* parameter PV_1 is zero and PV_2 = cot( reference point -* latitude). This is encoded using the string "-NCP". The SFL projection -* is encoded using the string "-GLS". Note, the original IRAF WCS -* system only recognised a small subset of the currently available -* projections, but some more recent IRAF-like software recognizes some -* of the new projections included in the FITS-WCS encoding. -* -* 2) The celestial axes must be RA/DEC, galactic or ecliptic. -* -* 3) LONPOLE and LATPOLE cannot be used. -* -* 4) Only primary axis descriptions are written out. -* -* 5) RADECSYS is used in place of RADESYS. -* -* 6) PC/CDELT keywords are not allowed (CD must be used) - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if succesfull, and zero is returned -* otherwise. -*/ - -/* Local Variables: */ - char *comm; /* Pointer to comment string */ - char *cval; /* Pointer to string keyword value */ - char combuf[80]; /* Buffer for FITS card comment */ - char lattype[MXCTYPELEN];/* Latitude axis CTYPE */ - char lontype[MXCTYPELEN];/* Longitude axis CTYPE */ - char s; /* Co-ordinate version character */ - char sign[2]; /* Fraction's sign character */ - double cdelt; /* A CDELT value */ - double fd; /* Fraction of a day */ - double mjd99; /* MJD at start of 1999 */ - double p1, p2; /* Projection parameters */ - double val; /* General purpose value */ - int axlat; /* Index of latitude FITS WCS axis */ - int axlon; /* Index of longitude FITS WCS axis */ - int axspec; /* Index of spectral FITS WCS axis */ - int i; /* Axis index */ - int ihmsf[ 4 ]; /* Hour, minute, second, fractional second */ - int iymdf[ 4 ]; /* Year, month, date, fractional day */ - int j; /* Axis index */ - int jj; /* SlaLib status */ - int naxis; /* No. of axes */ - int ok; /* Is FitsSTore OK for IRAF encoding? */ - int prj; /* Projection type */ - int ret; /* Returned value. */ - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* First check that the values in the FitsStore conform to the - requirements of the IRAF encoding. Assume they do to begin with. */ - ok = 1; - -/* Just do primary axes. */ - s = ' '; - -/* Look for the primary celestial and spectral axes. */ - FindLonLatSpecAxes( store, s, &axlon, &axlat, &axspec, method, class, status ); - -/* If both longitude and latitude axes are present and thereis no - spectral axis...*/ - if( axlon >= 0 && axlat >= 0 ) { - -/* Get the CTYPE values for both axes. */ - cval = GetItemC( &(store->ctype), axlon, 0, s, NULL, method, class, status ); - if( !cval ) return ret; - strcpy( lontype, cval ); - cval = GetItemC( &(store->ctype), axlat, 0, s, NULL, method, class, status ); - if( !cval ) return ret; - strcpy( lattype, cval ); - -/* Extract the projection type as specified by the last 4 characters - in the CTYPE keyword value. */ - prj = astWcsPrjType( lattype + 4 ); - -/* Check the projection type is OK. Assume not initially. */ - ok = 0; - -/* FITS-IRAF cannot handle the AST-specific TPN projection. */ - if( prj == AST__TPN || prj == AST__WCSBAD ) { - ok = 0; - -/* SIN projections are handled later. */ - } else if( prj != AST__SIN ){ - -/* There must be no projection parameters. */ - if( GetMaxJM( &(store->pv), ' ', status ) == -1 ) ok = 1; - -/* Change the new SFL projection code to to the older equivalent GLS */ - if( prj == AST__SFL ){ - (void) strcpy( lontype + 4, "-GLS" ); - (void) strcpy( lattype + 4, "-GLS" ); - } - -/* SIN projections are only acceptable if the associated projection - parameters are both zero, or if the first is zero and the second - = cot( reference point latitude ) (the latter case is equivalent to - the old NCP projection). */ - } else { - p1 = GetItem( &( store->pv ), axlat, 1, s, NULL, method, class, status ); - p2 = GetItem( &( store->pv ), axlat, 2, s, NULL, method, class, status ); - if( p1 == AST__BAD ) p1 = 0.0; - if( p2 == AST__BAD ) p2 = 0.0; - val = GetItem( &( store->crval ), axlat, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) { - if( p1 == 0.0 ) { - if( p2 == 0.0 ) { - ok = 1; - } else if( fabs( p2 ) >= 1.0E14 && val == 0.0 ){ - ok = 1; - (void) strcpy( lontype + 4, "-NCP" ); - (void) strcpy( lattype + 4, "-NCP" ); - } else if( fabs( p2*tan( AST__DD2R*val ) - 1.0 ) - < 0.01 ){ - ok = 1; - (void) strcpy( lontype + 4, "-NCP" ); - (void) strcpy( lattype + 4, "-NCP" ); - } - } - } - } - -/* Identify the celestial coordinate system from the first 4 characters of the - longitude CTYPE value. Only RA, galactic longitude, and ecliptic - longitude can be stored using FITS-IRAF. */ - if( strncmp( lontype, "RA--", 4 ) && - strncmp( lontype, "GLON", 4 ) && - strncmp( lontype, "ELON", 4 ) ) ok = 0; - -/* If the physical Frame requires a LONPOLE or LATPOLE keyword, it cannot - be encoded using FITS-IRAF. */ - if( GetItem( &(store->latpole), 0, 0, s, NULL, method, class, status ) - != AST__BAD || - GetItem( &(store->lonpole), 0, 0, s, NULL, method, class, status ) - != AST__BAD ) ok = 0; - -/* If there are no celestial axes, the physical Frame can be written out - using FITS-IRAF. */ - } else { - ok = 1; - } - -/* Save the number of axes */ - naxis = GetMaxJM( &(store->crpix), ' ', status ) + 1; - -/* If this is different to the value of NAXIS abort since this encoding - does not support WCSAXES keyword. */ - if( naxis != store->naxis ) ok = 0; - -/* Return if the FitsStore does not conform to IRAF encoding. */ - if( !ok ) return ret; - -/* Get and save CRPIX for all pixel axes. These are required, so return - if they are not available. */ - for( i = 0; i < naxis; i++ ){ - val = GetItem( &(store->crpix), 0, i, s, NULL, method, class, status ); - if( val == AST__BAD ) return ret; - sprintf( combuf, "Reference pixel on axis %d", i + 1 ); - SetValue( this, FormatKey( "CRPIX", i + 1, -1, s, status ), &val, AST__FLOAT, - combuf, status ); - } - -/* Get and save CRVAL for all intermediate axes. These are required, so return - if they are not available. */ - for( j = 0; j < naxis; j++ ){ - val = GetItem( &(store->crval), j, 0, s, NULL, method, class, status ); - if( val == AST__BAD ) return ret; - sprintf( combuf, "Value at ref. pixel on axis %d", j + 1 ); - SetValue( this, FormatKey( "CRVAL", j + 1, -1, s, status ), &val, AST__FLOAT, - combuf, status ); - } - -/* Get and save CTYPE for all intermediate axes. These are required, so return - if they are not available. Use the potentially modified versions saved - above for the celestial axes. */ - for( i = 0; i < naxis; i++ ){ - if( i == axlat ) { - cval = lattype; - } else if( i == axlon ) { - cval = lontype; - } else { - cval = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - if( !cval ) return ret; - } - if( strlen(cval) > 4 && !strcmp( cval + 4, "-TAB" ) ) return ret; - comm = GetItemC( &(store->ctype_com), i, 0, s, NULL, method, class, status ); - if( !comm ) { - sprintf( combuf, "Type of co-ordinate on axis %d", i + 1 ); - comm = combuf; - } - SetValue( this, FormatKey( "CTYPE", i + 1, -1, s, status ), &cval, AST__STRING, - comm, status ); - } - -/* CD matrix (the product of the CDELT and PC matrices). */ - for( i = 0; i < naxis; i++ ){ - cdelt = GetItem( &(store->cdelt), i, 0, s, NULL, method, class, status ); - if( cdelt == AST__BAD ) cdelt = 1.0; - for( j = 0; j < naxis; j++ ){ - val = GetItem( &(store->pc), i, j, s, NULL, method, class, status ); - if( val == AST__BAD ) val = ( i == j ) ? 1.0 : 0.0; - val *= cdelt; - if( val != 0.0 ) { - SetValue( this, FormatKey( "CD", i + 1, j + 1, s, status ), &val, - AST__FLOAT, "Transformation matrix element", status ); - } - } - } - -/* Get and save CUNIT for all intermediate axes. These are NOT required, so - do not return if they are not available. */ - for( i = 0; i < naxis; i++ ){ - cval = GetItemC( &(store->cunit), i, 0, s, NULL, method, class, status ); - if( cval ) { - sprintf( combuf, "Units for axis %d", i + 1 ); - SetValue( this, FormatKey( "CUNIT", i + 1, -1, s, status ), &cval, AST__STRING, - combuf, status ); - } - } - -/* Get and save RADECSYS. This is NOT required, so do not return if it is - not available. */ - cval = GetItemC( &(store->radesys), 0, 0, s, NULL, method, class, status ); - if( cval ) SetValue( this, "RADECSYS", &cval, AST__STRING, - "Reference frame for RA/DEC values", status ); - -/* Reference equinox */ - val = GetItem( &(store->equinox), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, "EQUINOX", &val, AST__FLOAT, - "Epoch of reference equinox", status ); - -/* Date of observation */ - val = GetItem( &(store->mjdobs), 0, 0, ' ', NULL, method, class, status ); - if( val != AST__BAD ) { - -/* The format used for the DATE-OBS keyword depends on the value of the - keyword. For DATE-OBS < 1999.0, use the old "dd/mm/yy" format. - Otherwise, use the new "ccyy-mm-ddThh:mm:ss[.ssss]" format. */ - palCaldj( 99, 1, 1, &mjd99, &jj ); - if( val < mjd99 ) { - palDjcal( 0, val, iymdf, &jj ); - sprintf( combuf, "%2.2d/%2.2d/%2.2d", iymdf[ 2 ], iymdf[ 1 ], - iymdf[ 0 ] - ( ( iymdf[ 0 ] > 1999 ) ? 2000 : 1900 ) ); - } else { - palDjcl( val, iymdf, iymdf+1, iymdf+2, &fd, &jj ); - palDd2tf( 3, fd, sign, ihmsf ); - sprintf( combuf, "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d.%3.3d", - iymdf[0], iymdf[1], iymdf[2], ihmsf[0], ihmsf[1], - ihmsf[2], ihmsf[3] ); - } - -/* Now store the formatted string in the FitsChan. */ - cval = combuf; - SetValue( this, "DATE-OBS", (void *) &cval, AST__STRING, - "Date of observation", status ); - } - -/* If we get here we have succeeded. */ - ret = 1; - -/* Return zero or ret depending on whether an error has occurred. */ - return astOK ? ret : 0; -} - -static int IsMapLinear( AstMapping *smap, const double lbnd_in[], - const double ubnd_in[], int coord_out, int *status ) { -/* -* Name: -* IsMapLinear - -* Purpose: -* See if a specified Mapping output is linearly related to the -* Mapping inputs. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int IsMapLinear( AstMapping *smap, const double lbnd_in[], -* const double ubnd_in[], int coord_out, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns a flag indicating if the specified output of the supplied -* Mapping is a linear function of the Mapping inputs. A set of output -* positions are created which are evenly spaced along the specified -* output coordinate. The spacing is chosen so that the entire range -* of the output coordinate is covered in 20 steps. The other output -* coordinates are held fixed at arbitrary values (actually, values -* at which the specified output coordinate achieves its minimum value). -* This set of output positions is transformed into the corresponding -* set of input coordinates using the inverse of the supplied Mapping. -* A least squares linear fit is then made which models each input -* coordinate as a linear function of the specified output coordinate. -* The residual at every point in this fit must be less than some -* small fraction of the total range of the corresponding input -* coordinate for the Mapping to be considered linear. - -* Parameters: -* smap -* Pointer to the Mapping. -* lbnd_in -* Pointer to an array of double, with one element for each -* Mapping input coordinate. This should contain the lower bound -* of the input box in each input dimension. -* ubnd_in -* Pointer to an array of double, with one element for each -* Mapping input coordinate. This should contain the upper bound -* of the input box in each input dimension. -* coord_out -* The zero-based index of the Mapping output which is to be checked. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the specified Mapping output is linear. Zero otherwise. -*/ - -/* Local Constants: */ -#define NP 20 - -/* Local Variables: */ - AstMapping *map; - AstPointSet *pset1; - AstPointSet *pset2; - double **ptr1; - double **ptr2; - double *p; - double *s; - double *xl; - double c; - double d; - double delta; - double in_lbnd; - double in_ubnd; - double lbnd_out; - double m; - double p0; - double pv; - double sn; - double sp; - double sps; - double ss2; - double ss; - double sv; - double tol; - double ubnd_out; - int *ins; - int boxok; - int i; - int j; - int nin; - int nout; - int oldrep; - int ret; - -/* Initialise */ - ret = 0; - -/* Check inherited status */ - if( !astOK ) return ret; - -/* Attempt to split off the required output (in case any of the other - outputs are associated with Mappings that do not have an inverse). */ - astInvert( smap ); - ins = astMapSplit( smap, 1, &coord_out, &map ); - astInvert( smap ); - -/* If successful, check that the output is fed by only one input. */ - if( ins ) { - if( astGetNin( map ) == 1 ) { - -/* If so, invert the map so that it goes from pixel to wcs, and then - modify the supplied arguments so that they refer to the single required - axis. */ - astInvert( map ); - lbnd_in += coord_out; - ubnd_in += coord_out; - coord_out = 0; - -/* If the output was fed by more than one input, annul the split mapping - and use the supplied nmapping. */ - } else { - (void) astAnnul( map ); - map = astClone( smap ); - } - ins = astFree( ins ); - -/* If the supplied Mapping could not be split, use the supplied nmapping. */ - } else { - map = astClone( smap ); - } - -/* Check the Mapping is defined in both directions. */ - if( astGetTranForward( map ) && astGetTranInverse( map ) ) { - -/* Allocate resources. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - xl = astMalloc( sizeof( double )*(size_t) nin ); - pset1 = astPointSet( NP, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - pset2 = astPointSet( NP, nout, "", status ); - ptr2 = astGetPoints( pset2 ); - -/* Call astMapBox in a new error reporting context. */ - boxok = 0; - if( astOK ) { - -/* Temporarily switch off error reporting so that no report is made if - astMapBox cannot find a bounding box (which can legitimately happen with - some non-linear Mappings). */ - oldrep = astReporting( 0 ); - -/* Find the upper and lower bounds on the specified Mapping output. This also - returns the input coords of a point at which the required output has its - lowest value. */ - astMapBox( map, lbnd_in, ubnd_in, 1, coord_out, &lbnd_out, &ubnd_out, - xl, NULL ); - -/* If the box could not be found, clear the error status and pass on. */ - if( !astOK ) { - astClearStatus; - -/* If the box was found OK, flag this and check if the bounds are equal. - If so we cannot use them. In this case create new bounds. */ - } else { - boxok = 1; - if( astEQUAL( lbnd_out, ubnd_out ) ) { - m = 0.5*( lbnd_out + ubnd_out ); - if( fabs( m ) > 1.0E-15 ) { - lbnd_out = 0.9*m; - ubnd_out = 1.1*m; - } else { - lbnd_out = -1.0; - ubnd_out = 1.0; - } - } - } - -/* Re-instate error reporting. */ - astReporting( oldrep ); - } - -/* Check pointers can be used safely and a box was obtained. */ - if( astOK && boxok ) { - -/* Transform the input position returned by astMapBox using the supplied - Mapping to get the corresponding output position. Fill all unused - elements of the PointSet with AST__BAD. */ - for( i = 0; i < nin; i++ ){ - p = ptr1[ i ]; - *(p++) = xl[ i ]; - for( j = 1; j < NP; j++ ) *(p++) = AST__BAD; - } - (void) astTransform( map, pset1, 1, pset2 ); - -/* Now create a set of NP points evenly spaced in output coordinates. The - first point is at the output position found above. Each subsequent - point is incremented by a fixed amount along the specified output - coordinate (the values on all other output coordinates is held fixed). */ - delta = ( ubnd_out - lbnd_out )/ ( NP - 1 ); - for( i = 0; i < nout; i++ ){ - p = ptr2[ i ]; - if( i == coord_out ) { - for( j = 0; j < NP; j++ ) *(p++) = lbnd_out + j*delta; - } else { - p0 = p[ 0 ]; - for( j = 0; j < NP; j++ ) *(p++) = p0; - } - } - -/* Transform these output positions into input positions using the - inverse Mapping. */ - (void) astTransform( map, pset2, 0, pset1 ); - -/* Do a least squares fit to each input coordinate. Each fit gives the - corresponding input coordinate value as a linear function of the - specified output coordinate value. Note, linear function should never - produce bad values so abort if a bad value is found. */ - ret = 1; - s = ptr2[ coord_out ]; - for( i = 0; i < nin; i++ ) { - p = ptr1[ i ]; - -/* Form the required sums. Also find the largest and smallest input - coordinate value achieved. */ - sp = 0.0; - ss = 0.0; - sps = 0.0; - sn = 0.0; - ss2 = 0.0; - in_lbnd = DBL_MAX; - in_ubnd = DBL_MIN; - for( j = 0; j < NP; j++ ) { - sv = s[ j ]; - pv = p[ j ]; - if( pv != AST__BAD && sv != AST__BAD ) { - sp += pv; - ss += sv; - sps += pv*sv; - sn += 1.0; - ss2 += sv*sv; - if( pv < in_lbnd ) in_lbnd = pv; - if( pv > in_ubnd ) in_ubnd = pv; - } else { - sn = 0.0; - break; - } - } - -/* Ignore input axes which are independant of the output axis. */ - if( !astEQUAL( in_lbnd, in_ubnd ) ) { - -/* Calculate the constants "input coord = m*output coord + c" */ - d = ss*ss - sn*ss2; - if( sn > 0.0 && d != 0.0 ) { - m = ( sp*ss - sps*sn )/d; - c = ( sps*ss - sp*ss2 )/d; - -/* Subtract off the fit value form the "p" values to get the residuals of - the fit. */ - for( j = 0; j < NP; j++ ) p[ j ] -= m*s[ j ] + c; - -/* We now do a least squares fit to the residuals. This second fit is done - because the first least squares fit sometimes leaves the residuals with a - distinct non-zero gradient. We do not need to worry about bad values - here since we have checked above that there are no bad values. Also we - do not need to recalculate sums which only depend on the "s" values since - they have not changed. */ - sp = 0.0; - sps = 0.0; - for( j = 0; j < NP; j++ ) { - pv = p[ j ]; - sp += pv; - sps += pv*s[ j ]; - } - -/* Find the constants in "input residual = m*output coord + c" equation. */ - m = ( sp*ss - sps*sn )/d; - c = ( sps*ss - sp*ss2 )/d; - -/* Subtract off the fit value form the "p residuals" values to get the - residual redisuals of the fit. */ - for( j = 0; j < NP; j++ ) p[ j ] -= m*s[ j ] + c; - -/* The requirement for a linear relationship is that the absolute residual - between the input coord produced by the above linear fit and the input - coord produced by the actual Mapping should be less than some small - fraction of the total range of input coord value, at every point. Test - this. */ - tol = 1.0E-7*( in_ubnd - in_lbnd ); - for( j = 0; j < NP; j++ ) { - if( fabs( p[ j ] ) > tol ) { - ret = 0; - break; - } - } - } else { - ret = 0; - } - } - if( !ret ) break; - } - } - -/* Free resources. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - xl = astFree( xl ); - } - map = astAnnul( map ); - -/* Return the answer. */ - return ret; -} - -static AstMapping *IsMapTab1D( AstMapping *map, double scale, const char *unit, - AstFrame *wcsfrm, double *dim, int iax, - int iwcs, AstFitsTable **table, int *icolmain, - int *icolindex, int *interp, int *status ){ -/* -* Name: -* IsMapTab1D - -* Purpose: -* See if a specified Mapping output is related to a single Mapping input -* via a FITS -TAB algorithm. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *IsMapTab1D( AstMapping *map, double scale, const char *unit, -* AstFrame *wcsfrm, double *dim, int iax, -* int iwcs, AstFitsTable **table, int *icolmain, -* int *icolindex, int *interp, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A specified axis of the supplied Mapping is tested to see if it -* can be represented by the -TAB alogirithm described in FITS-WCS -* paper III. If the test is passed, a Mapping is returned from the -* specified WCS axis to the corresponding psi axis. A FitsTable is -* also created holding the information to be stored in the -* corresponding FITS binary table. -* -* Note, when creating a -TAB header, AST uses grid coords for the psi -* axis. See FITS-WCS paper III section 6.1.2 for a definition of the -* psi axes. - -* Parameters: -* map -* Pointer to the Mapping from pixel coords to WCS coords. -* scale -* A scale factor by which to multiply the axis values stored in the -* returned FitsTable. Note, the returned Mapping is unaffected by -* this scaling factor. -* unit -* Pointer to the unit string to store with the coords column. If -* NULL, the unit string is extracted form the supplied WCS Frame. -* wcsfrm -* Pointer to a Frame describing WCS coords. -* dim -* An array holding the array dimensions in pixels. AST__BAD should -* be supplied for any unknown dimensions. -* iax -* The zero-based index of the Mapping output which is to be checked. -* iwcs -* The zero-based index of the corresponding FITS WCS axis. -* table -* Pointer to a location holding a pointer to the FitsTable describing -* the -TAB look-up table. If "*table" is NULL on entry, a new -* FitsTable will be created and returned, otherwise the supplied -* FitsTable is used. -* icolmain -* The one-based index of the column within "*table" that holds the -* main data array. -* icolindex -* The one-based index of the column within "*table" that holds the -* index vector. Returned equal to -1 if no index is added to the -* table (i.e. if the index is a unt index). -* interp -* The interpolation method (0=linear, other=nearest neighbour). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If the specified "map" output can be described using the -TAB -* algorithm of FITS-WCS paper III, then a 1-input/1-output Mapping -* from the specified WCS axis to the corresponding psi axis (which is -* assumed to be equal to grid coords) is returned. NULL is returned -* otherwise, of if an error occurs. -*/ - -/* Local Variables: */ - AstCmpMap *cm; /* CmpMap pointer */ - AstMapping **map_list; /* Mapping array pointer */ - AstMapping *postmap; /* Total Mapping after LutMap */ - AstMapping *premap; /* Total Mapping before LutMap */ - AstMapping *ret; /* Returned WCS axis Mapping */ - AstMapping *tmap; /* Temporary Mapping */ - AstPermMap *pm; /* PermMap pointer */ - char cellname[ 20 ]; /* Buffer for cell name */ - char colname[ 20 ]; /* Buffer for column name */ - double *lut; /* Pointer to table of Y values */ - double *work1; /* Pointer to work array */ - double *work2; /* Pointer to work array */ - double inc; /* X increment between table entries */ - double start; /* X value at first table entry */ - double v[ 2 ]; /* Y values at start and end of interval */ - double x[ 2 ]; /* X values at start and end of interval */ - int *ins; /* Array of "map" input indices */ - int *invert_list; /* Invert array pointer */ - int *outs; /* Array of "map" output indices */ - int dims[ 2 ]; /* Dimensions of the tab coords array */ - int iin; /* Index of Mapping input */ - int ilut; /* Index of the LutMap within the mappings list */ - int imap; /* Index of current Mapping in list */ - int iout; /* Index of Mapping output */ - int jout; /* Index of Mapping output */ - int nin; /* Number of Mapping inputs */ - int nlut; /* Number of elements in "lut" array */ - int nmap; /* Number of Mappings in the list */ - int nout; /* Number of Mapping outputs */ - int ok; /* Were columns added to the table? */ - int old_invert; /* Original value for Mapping's Invert flag */ - int outperm; /* Index of input that feeds the single output */ - -/* Initialise */ - ret = NULL; - *icolmain = -1; - *icolindex = -1; - *interp = 0; - -/* Check inherited status */ - if( !astOK ) return ret; - -/* Ensure we have aunit string. */ - if( !unit ) unit = astGetUnit( wcsfrm, iax ); - -/* Check that the requested mapping output is fed by only one mapping - input, identify that input, and extract the input->output mapping from - the total mapping. Since astMapSplit splits off a specified input, we - need to invert the Mapping first so we can split off a specified output. */ - astInvert( map ); - ins = astMapSplit( map, 1, &iax, &ret ); - astInvert( map ); - -/* If the Mapping could not be split, try a different approach in which - each input is checked in turn to see if it feeds the specified output. */ - if( !ins ) { - -/* Loop round each input of "map". */ - nin = astGetNin( map ); - for( iin = 0; iin < nin && !ins; iin++ ) { - -/* Attempt to find a group of outputs (of "map") that are fed by just - this one input. */ - outs = astMapSplit( map, 1, &iin, &ret ); - -/* If successful, "ret" will be a Mapping with one input corresponding to - input "iin" of "map, and one or more outputs. We loop round these - outputs to see if any of them correspond to output "iax" of "map". */ - if( outs ) { - nout = astGetNout( ret ); - for( iout = 0; iout < nout; iout++ ) { - if( outs[ iout ] == iax ) break; - } - -/* Did input "iin" feed the output "iax" (and possibly other outputs)? */ - if( iout < nout ) { - -/* The "ret" Mapping is now a 1-input (pixel) N-output (WCS) Mapping in which - output "iout" corresponds to output "iax" of Mapping. To be compatible - with the previous approach, we want "ret" to be a 1-input (WCS) to - 1-output (pixel) Mapping in which the input corresponds to output - "iax" of Mapping. To get "ret" into this form, we first append a PermMap - to "ret" that selects a single output ("iout"), and then invert the - whole CmpMap. */ - for( jout = 0; jout < nout; jout++ ) { - outs[ jout ] = -1; - } - outs[ iout ] = 0; - outperm = iout; - - pm = astPermMap( nout, outs, 1, &outperm, NULL, "", status ); - cm = astCmpMap( ret, pm, 1, " ", status ); - (void) astAnnul( ret ); - pm = astAnnul( pm ); - ret = (AstMapping *) cm; - astInvert( ret ); - -/* The earlier approach leves ins[ 0 ] holding the index of the input to - "map" that feeds output iax. Ensure we have this too. */ - ins = outs; - ins[ 0 ] = iin; - -/* Free resources if the current input did not feed the required output. */ - } else { - outs = astFree( outs ); - ret = astAnnul( ret ); - } - } - } - } - -/* If the Mapping still could not be split, try again on a copy of the - Mapping in which all PermMaps provide an alternative implementation of - the astMapSplit method. */ - if( !ins ) { - astInvert( map ); - tmap = astCopy( map ); - ChangePermSplit( tmap, status ); - ins = astMapSplit( tmap, 1, &iax, &ret ); - tmap = astAnnul( tmap ); - astInvert( map ); - } - -/* Assume the Mapping cannot be represented by -TAB */ - ok = 0; - -/* Check a Mapping was returned by astMapSplit. If so, it will be the - mapping from the requested output of "map" (the WCS axis) to the - corresponding input(s) (grid axes). Check only one "map" input feeds the - requested output. */ - if( ins && ret && astGetNout( ret ) == 1 ) { - -/* Invert the Mapping so that the input is grid coord and the output is - WCS coord. */ - astInvert( ret ); - -/* We now search the "ret" mapping for a non-inverted LutMap, splitting ret - up into three serial components: 1) the mappings before the LutMap, 2) the - LutMap itself, and 3) the mappings following the LutMap. First, decompose - the mapping into a list of series mappings. */ - map_list = NULL; - invert_list = NULL; - nmap = 0; - astMapList( ret, 1, astGetInvert( ret ), &nmap, &map_list, - &invert_list ); - -/* Search the list for a non-inverted LutMap. */ - ilut = -1; - for( imap = 0; imap < nmap; imap++ ) { - if( astIsALutMap( map_list[ imap ] ) && !(invert_list[ imap ]) ) { - ilut = imap; - break; - } - } - -/* If a LutMap was found, combine all Mappings before the LutMap into a - single Mapping. Remember to set the Mapping Invert flags temporarily to - the values used within the CmpMap. */ - if( ilut >= 0 ) { - premap = (AstMapping *) astUnitMap( 1, " ", status ); - for( imap = 0; imap < ilut; imap++ ) { - old_invert = astGetInvert( map_list[ imap ] ); - astSetInvert( map_list[ imap ], invert_list[ imap ] ); - tmap = (AstMapping *) astCmpMap( premap, map_list[ imap ], 1, - " ", status ); - astSetInvert( map_list[ imap ], old_invert ); - (void) astAnnul( premap ); - premap = tmap; - } - -/* Also combine all Mappings after the LutMap into a single Mapping, setting - the Mapping Invert flags temporarily to the values used within the - CmpMap. */ - postmap = (AstMapping *) astUnitMap( 1, " ", status ); - for( imap = ilut + 1; imap < nmap; imap++ ) { - old_invert = astGetInvert( map_list[ imap ] ); - astSetInvert( map_list[ imap ], invert_list[ imap ] ); - tmap = (AstMapping *) astCmpMap( postmap, map_list[ imap ], 1, - " ", status ); - astSetInvert( map_list[ imap ], old_invert ); - (void) astAnnul( postmap ); - postmap = tmap; - } - -/* Get the table of values, and other attributes, from the LutMap. */ - lut = astGetLutMapInfo( map_list[ ilut ], &start, &inc, &nlut ); - *interp = astGetLutInterp( map_list[ ilut ] ); - -/* If required, create a FitsTable to hold the returned table info. */ - if( ! *table ) *table = astFitsTable( NULL, "", status ); - ok = 1; - -/* Define the properties of the column in the FitsTable that holds the main - coordinate array. Points on a WCS axis are described by a single value - (wavelength, frequency, or whatever), but the coords array has to be - 2-dimensional, with an initial degenerate axis, as required by FITS-WCS - paper III. */ - dims[ 0 ] = 1; - dims[ 1 ] = nlut; - sprintf( colname, "COORDS%d", iwcs + 1 ); - astAddColumn( *table, colname, AST__DOUBLETYPE, 2, dims, unit ); - -/* Get the one-based index of the column just added to the table. */ - *icolmain = astGetNcolumn( *table ); - -/* Get workspace. */ - work1 = astMalloc( nlut*sizeof( double ) ); - if( astOK ) { - -/* Transform the LutMap table values using the post-lutmap mapping to - get the list of WCS values in AST units. */ - astTran1( postmap, nlut, lut, 1, work1 ); - -/* Convert them to FITS units (e.g. celestial axis values should be - converted from radians to degrees). */ - for( ilut = 0; ilut < nlut; ilut++ ) work1[ ilut ] *= scale; - -/* Store them in row 1, column COORDS, in the FitsTable. */ - sprintf( cellname, "COORDS%d(1)", iwcs + 1 ); - astMapPut1D( *table, cellname, nlut, work1, NULL ); - -/* Create an array holding the LutMap input value at the centre of each - table entry. Re-use the "lut" array since we no longer need it. */ - for( ilut = 0; ilut < nlut; ilut++ ) { - lut[ ilut ] = start + ilut*inc; - } - -/* Transform this array using the inverted pre-lutmap mapping to get the - list of grid coord. */ - astTran1( premap, nlut, lut, 0, work1 ); - -/* Test this list to see if they form a unit index (i.e. index(i) == i+1 ). - (not the "+1" is due to the fact that "i" is zero based). */ - for( ilut = 0; ilut < nlut; ilut++ ) { - if( fabs( work1[ ilut ] - ilut - 1.0 ) > 1.0E-6 ) break; - } - -/* if it is not a unit index, we add the index to the table. */ - if( ilut < nlut ) { - -/* Define the properties of the column in the FitsTable that holds the - indexing vector. */ - sprintf( colname, "INDEX%d", iwcs + 1 ); - astAddColumn( *table, colname, AST__DOUBLETYPE, 1, &nlut, " " ); - -/* Get the one-based index of the column just added to the table. */ - *icolindex = astGetNcolumn( *table ); - -/* Store the values in the column. */ - sprintf( cellname, "INDEX%d(1)", iwcs + 1 ); - astMapPut1D( *table, cellname, nlut, work1, NULL ); - } - } - -/* Free resources. */ - work1 = astFree( work1 ); - lut = astFree( lut ); - premap = astAnnul( premap ); - postmap = astAnnul( postmap ); - -/* If no LutMap was found in the Mapping, then we can create a FitsTable - by sampling the full WCS Mapping at selected input (i.e. grid) - positions. But we can only do this if we know the number of pixels - along the WCS axis. */ - } else if( dim[ ins[ 0 ] ] != AST__BAD ) { - -/* Create two works array each holding a single value. The first holds - the grid coords at which the samples are taken. The second holds the - WCS coords at the sampled positions. These arrays are expanded as - required within function AdaptLut. */ - work1 = astMalloc( sizeof( double ) ); - work2 = astMalloc( sizeof( double ) ); - if( astOK ) { - -/* Get the WCS values at the centres of the first and last pixel on - the WCS axis. */ - x[ 0 ] = 1.0; - x[ 1 ] = dim[ ins[ 0 ] ]; - astTran1( ret, 2, x, 1, v ); - -/* Put the lower limit into the work arrays. */ - work1[ 0 ] = x[ 0 ]; - work2[ 0 ] = v[ 0 ]; - nlut = 1; - -/* Expand the arrays by sampling the WCS axis adaptively so that - more samples occur where the WCS value is changing most rapidly. - We require the maximum error introduced by the table to be 0.25 pixels. */ - AdaptLut( ret, 3, 0.25, x[ 0 ], x[ 1 ], v[ 0 ], v[ 1 ], - &work1, &work2, &nlut, status ); - -/* Create a FitsTable to hold the returned table info. */ - if( ! *table ) *table = astFitsTable( NULL, "", status ); - ok = 1; - -/* Define the properties of the column in the FitsTable that holds the main - coordinate array. */ - sprintf( colname, "COORDS%d", iwcs + 1 ); - dims[ 0 ] = 1; - dims[ 1 ] = nlut; - astAddColumn( *table, colname, AST__DOUBLETYPE, 2, dims, unit ); - *icolmain = astGetNcolumn( *table ); - -/* Convert the axis values to FITS units (e.g. celestial axis values should be - converted from radians to degrees). */ - for( ilut = 0; ilut < nlut; ilut++ ) work2[ ilut ] *= scale; - -/* Store the scaled axis values in row 1 of the column. */ - sprintf( cellname, "COORDS%d(1)", iwcs + 1 ); - astMapPut1D( *table, cellname, nlut, work2, NULL ); - -/* Test the index vector to see if they form a unit index (i.e. index(i) == - i+1 ). If not the "+1" is due to the fact that "i" is zero based). If not, store - them as the index vector in the FitsTable. */ - for( ilut = 0; ilut < nlut; ilut++ ) { - if( fabs( work1[ ilut ] - ilut - 1.0 ) > 1.0E-6 ) break; - } - -/* If the index vector is not a unit index, define the properties of the - column in the FitsTable that holds the indexing vector. Then store values - in row 1 of the column. */ - if( ilut < nlut ) { - sprintf( colname, "INDEX%d", iwcs + 1 ); - astAddColumn( *table, colname, AST__DOUBLETYPE, 1, &nlut, " " ); - *icolindex = astGetNcolumn( *table ); - sprintf( cellname, "INDEX%d(1)", iwcs + 1 ); - astMapPut1D( *table, cellname, nlut, work1, NULL ); - } - } - -/* Free resources */ - work1 = astFree( work1 ); - work2 = astFree( work2 ); - } - -/* If columns were added to the table, invert the returned Mapping again - so that the input is wcs coord and the output is grid coord. Otherwise, - annul the returned Mapping. */ - if( ok ) { - astInvert( ret ); - } else { - ret = astAnnul( ret ); - } - -/* Loop to annul all the Mapping pointers in the list. */ - for ( imap = 0; imap < nmap; imap++ ) map_list[ imap ] = astAnnul( map_list[ imap ] ); - -/* Free the dynamic arrays. */ - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - } - -/* Free resources. */ - ins = astFree( ins ); - -/* If an error occurred, free the returned Mapping. */ - if( !astOK ) ret = astAnnul( ret ); - -/* Return the result. */ - return ret; -} - -static AstMapping *IsMapTab2D( AstMapping *map, double scale, const char *unit, - AstFrame *wcsfrm, double *dim, int iax1, - int iax2, int iwcs1, int iwcs2, - AstFitsTable **table, int *icolmain1, - int *icolmain2, int *icolindex1, - int *icolindex2, int *max1, int *max2, - int *interp1, int *interp2, int *status ){ -/* -* Name: -* IsMapTab2D - -* Purpose: -* See if a specified pair of Mapping outputs are related to a pair of -* Mapping inputs via a FITS -TAB algorithm. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *IsMapTab2D( AstMapping *map, double scale, const char *unit, -* AstFrame *wcsfrm, double *dim, int iax1, -* int iax2, int iwcs1, int iwcs2, -* AstFitsTable **table, int *icolmain1, -* int *icolmain2, int *icolindex1, -* int *icolindex2, int *max1, int *max2, -* int *interp1, int *interp2, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A specified pair of outputs axes of the supplied Mapping are tested -* to see if they can be represented by the -TAB alogirithm described in -* FITS-WCS paper III. If the test is passed, a Mapping is returned from -* the specified WCS axes to the corresponding psi axes. A FitsTable is -* also created holding the information to be stored in the corresponding -* FITS binary table. Note, when creating a header, AST assumes a unit -* transformaton between psi axes and grid axes (psi axes are defined -* in FITS-WCS paper III section 6.1.2). - -* Parameters: -* map -* Pointer to the Mapping from pixel coords to WCS coords. -* scale -* A scale factor by which to multiply the axis values stored in the -* returned FitsTable. Note, the returned Mapping is unaffected by -* this scaling factor. -* unit -* A unit string for the axis values. If supplied, the same -* string is stored for both axes. If NULL, the unit strings are -* extracted from the relavent axes of the supplied WCS Frame. -* wcsfrm -* Pointer to a Frame describing WCS coords. -* dim -* An array holding the array dimensions in pixels. AST__BAD should -* be supplied for any unknown dimensions. -* iax1 -* The zero-based index of the first Mapping output which is to be -* checked. -* iax2 -* The zero-based index of the second Mapping output which is to be -* checked. -* iwcs1 -* The zero-based index of the FITS WCS axis corresponding to "iax1". -* iwcs2 -* The zero-based index of the FITS WCS axis corresponding to "iax2". -* table -* Pointer to a location holding a pointer to the FitsTable describing -* the -TAB look-up table. If "*table" is NULL on entry, a new -* FitsTable will be created and returned, otherwise the supplied -* FitsTable is used. -* icolmain1 -* The one-based index of the column within "*table" that holds the -* main coord array for the first Mapping output. -* icolmain2 -* The one-based index of the column within "*table" that holds the -* main coord array for the second Mapping output. -* icolindex1 -* The one-based index of the column within "*table" that holds the -* index vector for the first Mapping output. Returned equal to -1 -* if no index is added to the table (e.g. because the index is a -* unit index). -* icolindex2 -* The one-based index of the column within "*table" that holds the -* index vector for the second Mapping output. Returned equal to -1 -* if no index is added to the table (e.g. because the index is a -* unit index). -* max1 -* The one-based index of the dimension describing the first Mapping -* output within the main coord array specified by "icolmain1". -* max2 -* The one-based index of the dimension describing the second Mapping -* output within the main coord array specified by "icolmain1". -* interp1 -* The interpolation method (0=linear, other=nearest neighbour) for -* the first mapping output. -* interp2 -* The interpolation method (0=linear, other=nearest neighbour) for -* the second mapping output. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If the specified "map" outputs can be described using the -TAB -* algorithm of FITS-WCS paper III, then a 2-input/2-output Mapping -* from the specified WCS axes to the corresponding psi axes (i.e. -* grid axes) is returned. NULL is returned otherwise, of if an error -* occurs. -*/ - -/* Local Variables: */ - AstMapping *ret1; /* WCS->IWC Mapping for first output */ - AstMapping *ret2; /* WCS->IWC Mapping for second output */ - AstMapping *ret; /* Returned WCS axis Mapping */ - AstMapping *tmap; - AstPermMap *pm; - int *pix_axes; /* Zero-based indices of corresponding pixel axes */ - int wcs_axes[ 2 ]; /* Zero-based indices of selected WCS axes */ - int inperm[ 1 ]; - int outperm[ 2 ]; - -/* Initialise */ - ret = NULL; - -/* Check inherited status */ - if( !astOK ) return ret; - -/* First see if the two required Mapping outputs are separable, in which case - they can be described by two 1D tables. */ - ret1 = IsMapTab1D( map, scale, unit, wcsfrm, dim, iax1, iwcs1, table, icolmain1, - icolindex1, interp1, status ); - ret2 = IsMapTab1D( map, scale, unit, wcsfrm, dim, iax2, iwcs2, table, icolmain2, - icolindex2, interp2, status ); - -/* If both outputs are seperable... */ - if( ret1 && ret2 ) { - -/* Both axes are stored as the first dimension in the corresponding main - coords array. */ - *max1 = 1; - *max2 = 1; - -/* Get a Mapping from the required pair of WCS axes to the corresponding - pair of grid axes. First try to split the supplied grid->wcs mapping. */ - wcs_axes[ 0 ] = iax1; - wcs_axes[ 1 ] = iax2; - - astInvert( map ); - pix_axes = astMapSplit( map, 2, wcs_axes, &ret ); - astInvert( map ); - - if( pix_axes ) { - pix_axes = astFree( pix_axes ); - if( astGetNout( ret ) > 2 ) { - ret = astAnnul( ret ); - -/* If the two output WCS axes are fed by the same grid axis, we need to - add another pixel axis to form the pair. */ - } else if( astGetNout( ret ) == 1 ) { - inperm[ 0 ] = 0; - outperm[ 0 ] = 0; - outperm[ 1 ] = 0; - pm = astPermMap( 1, inperm, 2, outperm, NULL, " ", status ); - tmap = (AstMapping *) astCmpMap( ret, pm, 1, " ", status ); - ret = astAnnul( ret ); - pm = astAnnul( pm ); - ret = tmap; - } - } - -/* If this was unsuccessful, combine the Mappings returned by IsMapTab1D. - We only do this if the above astMapSplit call failed, since the IsMapTab1D - mappings may well not be independent of each other, and we may end up - sticking together in parallel two mappings that are basically the same - except for ending with PermMapa that select different axes. Is is hard - then to simplify such a parallel CmpMap back into the simpler form - that uses only one of the two identical mappings, without a PermMap. */ - if( !ret ) { - ret = (AstMapping *) astCmpMap( ret1, ret2, 0, " ", status ); - } - -/* Free resources. */ - ret1 = astAnnul( ret1 ); - ret2 = astAnnul( ret2 ); - -/* If only one output is separable, remove the corresponding columns from - the returned table. */ - } else if( ret1 ) { - ret1 = astAnnul( ret1 ); - astRemoveColumn( *table, astColumnName( *table, *icolmain1 ) ); - if( icolindex1 >= 0 ) astRemoveColumn( *table, astColumnName( *table, *icolindex1 ) ); - } else if( ret2 ) { - ret2 = astAnnul( ret2 ); - astRemoveColumn( *table, astColumnName( *table, *icolmain2 ) ); - if( icolindex1 >= 0 ) astRemoveColumn( *table, astColumnName( *table, *icolindex2 ) ); - } - -/* If the required Mapping outputs were not separable, create a single - 2D coords array describing both outputs. */ - if( !ret ) { - -/* TO BE DONE... Until then non-separable Mappings will result in a - failure to create a -TAB header. No point in doing this until AST has - an N-dimensional LutMap class (otherwise AST could never read the - resulting FITS header). */ - } - -/* If an error occurred, free the returned Mapping. */ - if( !astOK ) ret = astAnnul( ret ); - -/* Return the result. */ - return ret; -} - -static int IsAIPSSpectral( const char *ctype, char **wctype, char **wspecsys, int *status ){ -/* -* Name: -* IsAIPSSpectral - -* Purpose: -* See if a given CTYPE value describes a FITS-AIPS spectral axis. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int IsAIPSSpectral( const char *ctype, char **wctype, char **wspecsys, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The given CTYPE value is checked to see if it conforms to the -* requirements of a spectral axis CTYPE value as specified by -* FITS-AIPS encoding. If so, the equivalent FITS-WCS CTYPE and -* SPECSYS values are returned. - -* Parameters: -* ctype -* Pointer to a null terminated string holding the CTYPE value to -* check. -* wctype -* The address of a location at which to return a pointer to a -* static string holding the corresponding FITS-WCS CTYPE value. A -* NULL pointer is returned if the supplied CTYPE string is not an -* AIPS spectral CTYPE value. -* wspecsys -* The address of a location at which to return a pointer to a -* static string holding the corresponding FITS-WCS SPECSYS value. A -* NULL pointer is returned if the supplied CTYPE string is not an -* AIPS spectral CTYPE value. -* status -* Pointer to the inherited status variable. - -* Retuned Value: -* Non-zero fi the supplied CTYPE was an AIPS spectral CTYPE value. - -* Note: -* - These translations are also used by the FITS-CLASS encoding. -*/ - -/* Local Variables: */ - int ret; - -/* Initialise */ - ret = 0; - *wctype = NULL; - *wspecsys = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* If the used length of the string is not 8, then it is not an AIPS spectral axis. */ - if( astChrLen( ctype ) == 8 ) { - -/* Translate AIPS spectral CTYPE values to FITS-WCS paper III equivalents. - These are of the form AAAA-BBB, where "AAAA" can be "FREQ", "VELO" (=VRAD!) - or "FELO" (=VOPT-F2W), and BBB can be "LSR", "LSD", "HEL" (=*Bary*centric!) - or "GEO". */ - if( !strncmp( ctype, "FREQ", 4 ) ){ - *wctype = "FREQ "; - } else if( !strncmp( ctype, "VELO", 4 ) ){ - *wctype = "VRAD "; - } else if( !strncmp( ctype, "FELO", 4 ) ){ - *wctype = "VOPT-F2W"; - } else if( !strncmp( ctype, "WAVELENG", 8 ) ){ - *wctype = "WAVE "; - } - if( !strncmp( ctype + 4, "-LSR", 4 ) ){ - *wspecsys = "LSRK"; - } else if( !strncmp( ctype + 4, "LSRK", 4 ) ){ - *wspecsys = "LSRK"; - } else if( !strncmp( ctype + 4, "-LSD", 4 ) ){ - *wspecsys = "LSRD"; - } else if( !strncmp( ctype + 4, "-HEL", 4 ) ){ - *wspecsys = "BARYCENT"; - } else if( !strncmp( ctype + 4, "-EAR", 4 ) || !strncmp( ctype + 4, "-GEO", 4 ) ){ - *wspecsys = "GEOCENTR"; - } else if( !strncmp( ctype + 4, "-OBS", 4 ) || !strncmp( ctype + 4, "-TOP", 4 ) ){ - *wspecsys = "TOPOCENT"; - } - if( *wctype && *wspecsys ) { - ret = 1; - } else { - *wctype = NULL; - *wspecsys = NULL; - } - } - -/* Return the result. */ - return ret; -} - -static int IsSkyOff( AstFrameSet *fset, int iframe, int *status ){ -/* -* Name: -* IsSkyOff - -* Purpose: -* See if a given Frame contains an offset SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int IsSkyOff( AstFrameSet *fset, int iframe, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns a flag indicating if the specified Frame within the -* supplied FrameSet is, or contains, a SkyFrame that represents -* offset coordinates. This is the case if the Frame is a SkyFrame -* and its SkyRefIs attribute is "Pole" or "Origin", or is a CmpFrame -* containing such a SkyFrame. - -* Parameters: -* fset -* The FrameSet. -* iframe -* Index of the Frame to check within "fset" -* status -* Pointer to the inherited status variable. - -* Retuned Value: -* +1 if the Frame is an offset SkyFrame. Zero otherwise. - -* Notes: -* - Zero is returned if an error has already occurred. -*/ - -/* Local Variables: */ - AstFrame *frm; - const char *skyrefis; - int oldrep; - int result; - -/* Initialise. */ - result = 0; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the required Frame in the FrameSet */ - frm = astGetFrame( fset, iframe ); - -/* Since the current Frame may not contain a SkyFrame, we temporarily - switch off error reporting. */ - oldrep = astReporting( 0 ); - -/* Get the SkyRefIs attribute value. */ - skyrefis = astGetC( frm, "SkyRefIs" ); - -/* If it is "Pole" or "Origin", return 1. */ - if( skyrefis && ( !Ustrcmp( skyrefis, "POLE", status ) || - !Ustrcmp( skyrefis, "ORIGIN", status ) ) ) result = 1; - -/* Cancel any error and switch error reporting back on again. */ - astClearStatus; - astReporting( oldrep ); - -/* Annul the Frame pointer. */ - frm = astAnnul( frm ); - -/* Return the result. */ - return result; -} - -static const char *IsSpectral( const char *ctype, char stype[5], char algcode[5], int *status ) { -/* -* Name: -* IsSpectral - -* Purpose: -* See if a given FITS-WCS CTYPE value describes a spectral axis. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* char *IsSpectral( const char *ctype, char stype[5], char algcode[5], int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The given CTYPE value is checked to see if it conforms to the -* requirements of a spectral axis CTYPE value as specified by -* FITS-WCS paper 3. If so, the spectral system and algorithm codes -* are extracted from it and returned, together with the default units -* for the spectral system. - -* Parameters: -* ctype -* Pointer to a null terminated string holding the CTYPE value to -* check. -* stype -* An array in which to return the null-terminated spectral system type -* (e.g. "FREQ", "VELO", "WAVE", etc). A null string is returned if -* the CTYPE value does not describe a spectral axis. -* algcode -* An array in which to return the null-terminated algorithm code -* (e.g. "-LOG", "", "-F2W", etc). A null string is returned if the -* spectral axis is linear. A null string is returned if the CTYPE -* value does not describe a spectral axis. -* status -* Pointer to the inherited status variable. - -* Retuned Value: -* A point to a static string holding the default units associated -* with the spectral system specified by the supplied CTYPE value. -* NULL is returned if the CTYPE value does not describe a spectral -* axis. - -* Notes: -* - The axis is considered to be a spectral axis if the first 4 -* characters form one of the spectral system codes listed in FITS-WCS -* paper 3. The algorithm code is not checked, except to ensure that -* it begins with a minus sign, or is blank. -* - A NULL pointer is returned if an error has already occurred. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - int ctype_len; - -/* Initialise */ - stype[ 0 ] = 0; - algcode[ 0 ] = 0; - -/* Check the inherited status. */ - if( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Initialise more stuff */ - isspectral_ret = NULL; - -/* If the length of the string is less than 4, then it is not a spectral - axis. */ - ctype_len = strlen( ctype ); - if( ctype_len >= 4 ) { - -/* Copy the first 4 characters (the coordinate system described by the - axis) into a null-terminated buffer. */ - strncpy( stype, ctype, 4 ); - stype[ 4 ] = 0; - stype[ astChrLen( stype ) ] = 0; - -/* Copy any remaining characters (the algorithm code) into a null-terminated - buffer. Only copy a maximum of 4 characters. */ - if( ctype_len > 4 ) { - if( ctype_len <= 8 ) { - strcpy( algcode, ctype + 4 ); - } else { - strncpy( algcode, ctype + 4, 4 ); - algcode[ 4 ] = 0; - } - algcode[ astChrLen( algcode ) ] = 0; - } else { - algcode[ 0 ] = 0; - } - -/* See if the first 4 characters of the CTYPE value form one of the legal - spectral coordinate type codes listed in FITS-WCS Paper III. Also note - the default units associated with the system. */ - if( !strcmp( stype, "FREQ" ) ) { - isspectral_ret = "Hz"; - } else if( !strcmp( stype, "ENER" ) ) { - isspectral_ret = "J"; - } else if( !strcmp( stype, "WAVN" ) ) { - isspectral_ret = "/m"; - } else if( !strcmp( stype, "VRAD" ) ) { - isspectral_ret = "m/s"; - } else if( !strcmp( stype, "WAVE" ) ) { - isspectral_ret = "m"; - } else if( !strcmp( stype, "VOPT" ) ) { - isspectral_ret = "m/s"; - } else if( !strcmp( stype, "ZOPT" ) ) { - isspectral_ret = ""; - } else if( !strcmp( stype, "AWAV" ) ) { - isspectral_ret = "m"; - } else if( !strcmp( stype, "VELO" ) ) { - isspectral_ret = "m/s"; - } else if( !strcmp( stype, "BETA" ) ) { - isspectral_ret = ""; - } - -/* Also check that the remaining part of CTYPE (the algorithm code) begins - with a minus sign or is blank. */ - if( algcode[ 0 ] != '-' && strlen( algcode ) > 0 ) isspectral_ret = NULL; - } - -/* Return null strings if the axis is not a spectral axis. */ - if( ! isspectral_ret ) { - stype[ 0 ] = 0; - algcode[ 0 ] = 0; - } - -/* Return the result. */ - return isspectral_ret; -} - -static AstMapping *LinearWcs( FitsStore *store, int i, char s, - const char *method, const char *class, int *status ) { -/* -* Name: -* LinearWcs - -* Purpose: -* Create a Mapping describing a FITS-WCS linear algorithm - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *LinearWcs( FitsStore *store, int i, char s, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function uses the contents of the supplied FitsStore to create -* a Mapping which goes from Intermediate World Coordinate (known as "w" -* in the context of FITS-WCS paper III) to a linearly related axis. -* -* The returned Mapping is a ShiftMap which simply adds on the value of -* CRVALi. - -* Parameters: -* store -* Pointer to the FitsStore structure holding the values to use for -* the WCS keywords. -* i -* The zero-based index of the spectral axis within the FITS header -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a Mapping, or NULL if an error occurs. -*/ - -/* Local Variables: */ - AstMapping *ret; - double crv; - -/* Check the global status. */ - ret = NULL; - if( !astOK ) return ret; - -/* Get the CRVAL value for the specified axis. */ - crv = GetItem( &(store->crval), i, 0, s, NULL, method, class, status ); - if( crv == AST__BAD ) crv = 0.0; - -/* Create a 1D ShiftMap which adds this value onto the IWCS value. */ - if( crv != 0.0 ) { - ret = (AstMapping *) astShiftMap( 1, &crv, "", status ); - } else { - ret = (AstMapping *) astUnitMap( 1, "", status ); - } - return ret; -} - -static AstMapping *LogAxis( AstMapping *map, int iax, int nwcs, double *lbnd_p, - double *ubnd_p, double crval, int *status ){ -/* -* Name: -* LogAxes - -* Purpose: -* Test a Frame axis to see if it logarithmically spaced in pixel coords. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *LogAxis( AstMapping *map, int iax, int nwcs, double *lbnd_p, -* double *ubnd_p, double crval ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A specified axis of the supplied Mappinhg is tested to see if it -* corresponds to the form -* -* S = Sr.exp( w/Sr ) -* -* where "w" is one of the Mapping inputs, "S" is the specified -* Mapping output, and "Sr" is the supplied value of "crval". This -* is the form for a FITS log axis as defined in FITS-WCS paper III. -* -* If the above test is passed, a Mapping is returned from "S" to "w" -* (the inverseof the above expression). - -* Parameters: -* map -* Pointer to the Mapping. This will usually be a Mapping from -* pixel coords to WCS coords. -* iax -* The index of the output of "map" which correspoinds to "S". -* nwcs -* The number of outputs from "map". -* lbnd_p -* Pointer to an array of double, with one element for each -* Mapping input coordinate. This should contain the lower bound -* of the input pixel box in each input dimension. -* ubnd_p -* Pointer to an array of double, with one element for each -* Mapping input coordinate. This should contain the upper bound -* of the input pixel box in each input dimension. -* crval -* The reference value ("Sr") to use. Must not be zero. - -* Returned Value: -* If the specified axis is logarithmically spaced, a Mapping with -* "nwcs" inputs and "nwcs" outputs is returned. This Mapping transforms - -* its "iax"th input using the transformation: -* -* w = Sr.Log( S/Sr ) -* -* (where "S" is the Mapping is the "iax"th input and "w" is the -* "iax"th output). Other inputs are copied to the corresponding -* output without change. NULL is returned if the specified axis is -* not logarithmically spaced. -*/ - -/* Local Variables: */ - AstMapping *result; /* Returned Mapping */ - AstMapping *tmap0; /* A temporary Mapping */ - AstMapping *tmap1; /* A temporary Mapping */ - AstMapping *tmap2; /* A temporary Mapping */ - AstMapping *tmap3; /* A temporary Mapping */ - AstMapping *tmap4; /* A temporary Mapping */ - const char *fexps[ 1 ]; /* Forward MathMap expressions */ - const char *iexps[ 1 ]; /* Inverse MathMap expressions */ - -/* Initialise */ - result = NULL; - -/* Check the inherited status and crval value. */ - if( !astOK || crval == 0.0 ) return result; - -/* If the "log" algorithm is appropriate, the supplied axis (s) is related - to pixel coordinate (p) by s = Sr.EXP( a*p - b ). If this is the case, - then the log of s will be linearly related to pixel coordinates. To test - this, we create a CmpMap which produces log(s). */ - fexps[ 0 ] = "logs=log(s)"; - iexps[ 0 ] = "s=exp(logs)"; - tmap1 = (AstMapping *) astMathMap( 1, 1, 1, fexps, 1, iexps, - "simpfi=1,simpif=1", status ); - tmap2 = AddUnitMaps( tmap1, iax, nwcs, status ); - tmap0 = (AstMapping *) astCmpMap( map, tmap2, 1, "", status ); - tmap2 = astAnnul( tmap2 ); - -/* See if this Mapping is linear. */ - if( IsMapLinear( tmap0, lbnd_p, ubnd_p, iax, status ) ) { - -/* Create the Mapping which defines the IWC axis. This is the Mapping from - WCS to IWCS - "W = Sr.log( S/Sr )". Other axes are left unchanged by the - Mapping. The IWC axis has the same axis index as the WCS axis. */ - tmap2 = (AstMapping *) astZoomMap( 1, 1.0/crval, "", status ); - tmap3 = (AstMapping *) astCmpMap( tmap2, tmap1, 1, "", status ); - tmap2 = astAnnul( tmap2 ); - tmap2 = (AstMapping *) astZoomMap( 1, crval, "", status ); - tmap4 = (AstMapping *) astCmpMap( tmap3, tmap2, 1, "", status ); - tmap3 = astAnnul( tmap3 ); - tmap2 = astAnnul( tmap2 ); - result = AddUnitMaps( tmap4, iax, nwcs, status ); - tmap4 = astAnnul( tmap4 ); - } - -/* Free resources. */ - tmap0 = astAnnul( tmap0 ); - tmap1 = astAnnul( tmap1 ); - -/* Return the result. */ - return result; -} - -static AstMapping *LogWcs( FitsStore *store, int i, char s, - const char *method, const char *class, int *status ) { -/* -* Name: -* LogWcs - -* Purpose: -* Create a Mapping describing a FITS-WCS logarithmic algorithm - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *LogWcs( FitsStore *store, int i, char s, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function uses the contents of the supplied FitsStore to create -* a Mapping which goes from Intermediate World Coordinate (known as "w" -* in the context of FITS-WCS paper III) to a logarthmic version of w - -* called "S" given by: -* -* S = Sr.exp( w/Sr ) -* -* where Sr is the value of S corresponding to w=0. - -* Parameters: -* store -* Pointer to the FitsStore structure holding the values to use for -* the WCS keywords. -* i -* The zero-based index of the axis within the FITS header -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a Mapping, or NULL if an error occurs. -*/ - -/* Local Variables: */ - AstMapping *ret; - char forexp[ 12 + AST__DBL_DIG*2 ]; - char invexp[ 12 + AST__DBL_DIG*2 ]; - const char *fexps[ 1 ]; - const char *iexps[ 1 ]; - double crv; - -/* Check the global status. */ - ret = NULL; - if( !astOK ) return ret; - -/* Get the CRVAL value for the specified axis. Use a default of zero. */ - crv = GetItem( &(store->crval), i, 0, s, NULL, method, class, status ); - if( crv == AST__BAD ) crv = 0.0; - -/* Create the MathMap, if possible. */ - if( crv != 0.0 ) { - sprintf( forexp, "s=%.*g*exp(w/%.*g)", AST__DBL_DIG, crv, AST__DBL_DIG, crv ); - sprintf( invexp, "w=%.*g*log(s/%.*g)", AST__DBL_DIG, crv, AST__DBL_DIG, crv ); - fexps[ 0 ] = forexp; - iexps[ 0 ] = invexp; - ret = (AstMapping *) astMathMap( 1, 1, 1, fexps, 1, iexps, "simpfi=1,simpif=1", status ); - } - -/* Return the result */ - return ret; -} - -static int LooksLikeClass( AstFitsChan *this, const char *method, - const char *class, int *status ){ - -/* -* Name: -* LooksLikeClass - -* Purpose: -* Does the FitsChan seem to use FITS-CLASS encoding? - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int LooksLikeClass( AstFitsChan *this, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns non-zero if the supplied FitsChan probably uses FITS-CLASS -* encoding. This is the case if it contains a DELTAV keyword and a -* keyword of the form VELO-xxx", where xxx is one of the accepted -* standards of rest, or "VLSR". - -* Parameters: -* this -* Pointer to the FitsChan. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the encoding in use lookslike FITS-CLASS. -*/ - -/* Local Variables... */ - int ret; /* Returned value */ - -/* Initialise */ - ret = 0; - -/* Check the global status. */ - if( !astOK ) return ret; - -/* See if there is a "DELTAV" card, and a "VELO-xxx" or "VLSR" card. */ - if( astKeyFields( this, "DELTAV", 0, NULL, NULL ) && ( - astKeyFields( this, "VLSR", 0, NULL, NULL ) || - astKeyFields( this, "VELO-OBS", 0, NULL, NULL ) || - astKeyFields( this, "VELO-HEL", 0, NULL, NULL ) || - astKeyFields( this, "VELO-EAR", 0, NULL, NULL ) || - astKeyFields( this, "VELO-LSR", 0, NULL, NULL ) ) ) { - ret = 1; - } - -/* Return the result. */ - return ret; -} - -static void MakeBanner( const char *prefix, const char *middle, - const char *suffix, - char banner[ AST__FITSCHAN_FITSCARDLEN - - FITSNAMLEN + 1 ], int *status ) { -/* -* Name: -* MakeBanner - -* Purpose: -* Create a string containing a banner comment. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void MakeBanner( const char *prefix, const char *middle, -* const char *suffix, -* char banner[ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN + 1 ], int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function creates a string which can be written as a FITS -* comment card to produce a banner heading (or tail) for an AST -* Object when it is written to a FitsChan. The banner will occupy -* the maximum permitted width for text in a FITS comment card. - -* Parameters: -* prefix -* A pointer to a constant null-terminated string containing the -* first part of the text to appear in the banner. -* middle -* A pointer to a constant null-terminated string containing the -* second part of the text to appear in the banner. -* suffix -* A pointer to a constant null-terminated string containing the -* third part of the text to appear in the banner. -* banner -* A character array to receive the null-terminated result string. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The text to appear in the banner is constructed by -* concatenating the three input strings supplied. -*/ - -/* Local Variables: */ - char token[] = "AST"; /* Identifying token */ - int i; /* Loop counter for input characters */ - int len; /* Number of output characters */ - int ltok; /* Length of token string */ - int mxlen; /* Maximum permitted output characters */ - int start; /* Column number where text starts */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Calculate the maximum number of characters that the output banner - can hold and the length of the token string. */ - mxlen = AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN; - ltok = (int) strlen( token ); - -/* Calculate the column in which to start the text, so that it is - centred in the banner (with 4 non-text characters on each side). */ - start = ltok + 2 + ( mxlen - ltok - 1 - - (int) ( strlen( prefix ) + - strlen( middle ) + - strlen( suffix ) ) - 1 - ltok ) / 2; - if ( start < ltok + 2 ) start = ltok + 2; - -/* Start building the banner with the token string. */ - len = 0; - for ( i = 0; token[ i ] && ( len < mxlen ); i++ ) { - banner[ len++ ] = token[ i ]; - } - -/* Then pad with spaces up to the start of the text. */ - while ( len < start - 1 ) banner[ len++ ] = ' '; - -/* Insert the prefix data, truncating it if it is too long. */ - for ( i = 0; prefix[ i ] && ( len < mxlen - ltok - 1 ); i++ ) { - banner[ len++ ] = prefix[ i ]; - } - -/* Insert the middle data, truncating it if it is too long. */ - for ( i = 0; middle[ i ] && ( len < mxlen - ltok - 1 ); i++ ) { - banner[ len++ ] = middle[ i ]; - } - -/* Insert the suffix data, truncating it if it is too long. */ - for ( i = 0; suffix[ i ] && ( len < mxlen - ltok - 1 ); i++ ) { - banner[ len++ ] = suffix[ i ]; - } - -/* Pad the end of the text with spaces. */ - while ( len < mxlen - ltok ) banner[ len++ ] = ' '; - -/* Finish the banner with the token string. */ - for ( i = 0; token[ i ] && ( len < mxlen ); i++ ) { - banner[ len++ ] = token[ i ]; - } - -/* Terminate the output string. */ - banner[ len ] = '\0'; -} - -static AstMapping *MakeColumnMap( AstFitsTable *table, const char *col, - int isindex, int interp, const char *method, - const char *class, int *status ){ -/* -* Name: -* MakeColumnMap - -* Purpose: -* Create a Mapping describing a look-up table supplied in a cell of a -* FITS binary table. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *MakeColumnMap( AstFitsTable *table, const char *col, -* int isindex, int interp, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns a Mapping representing the array of values -* stored in row 1 of a named column of a supplied FitsTable. The -* array of values is treated as a look-up table following the prescription -* of FITS-WCS paper III (the "-TAB" algorithm). If the array has (N+1) -* dimensions (where N is one or more), the returned Mapping has N -* inputs and N outputs. The inputs correspond to FITS GRID coords -* within the array. FITS-WCS paper III requires that the first dimension -* in the array has a length of "N" and contains the N output values -* at each input values. - -* Parameters: -* table -* Pointer to the Fitstable. -* col -* A string holding the name of the column to use. -* isindex -* Non-zero if the column hold an index array, zero if it holds a -* coordinate array. -* interp -* The value to use for the Interp attribute of the LutMap. A value -* of zero tells the LutMap class to use linear interpolation. Other -* values tell the LutMap class to use nearest neighbour interpolation. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the Mapping, or NULL if an error occurs. -*/ - -/* Local Variables: */ - AstMapping *result; - char *key; - double *lut; - int *dims; - int ndim; - int nel; - -/* Initialise */ - result = NULL; - -/* Check the inherited status */ - if( !astOK ) return result; - -/* Get the number of dimensions spanned by the value in the named column. */ - ndim = astGetColumnNdim( table, col ); - -/* First deal with index vectors. */ - if( isindex ) { - -/* FITS-WCS paper II mandates that index arrays must be 1-dimensional. */ - if( ndim != 1 && astOK ) { - astError( AST__BADTAB, "%s(%s): Column '%s' has %d dimensions but it " - "holds an index vector and should therefore be 1-dimensional.", - status, method, class, col, ndim ); - } - -/* Get the length of the index vector. */ - nel = astGetColumnLength( table, col ); - -/* Allocate memory to hold the array values, and to hold the cell key. */ - lut = astMalloc( nel*sizeof( double ) ); - key = astMalloc( strlen( col ) + 5 ); - if( astOK ) { - -/* Create the key for the table cell holding the required array. FITS-WCS - paper III mandates that tables always occur in the first row of the - table (and that the table only has one row). Ignore trailing spaces in - the column name. */ - sprintf( key, "%.*s(1)", (int) astChrLen( col ), col ); - -/* Copy the array values into the above memory. */ - if( astMapGet1D( table, key, nel, &nel, lut ) ) { - -/* Create a 1D LutMap. FITS-WCS paper III (sec 6.1.2) mandates that the input - corresponds to FITS grid coord (i.e. 1.0 at the centre of the first entry). - Ensure the LutMap uses linear interpolation. */ - result = (AstMapping *) astLutMap( nel, lut, 1.0, 1.0, - "LutInterp=%d", status, interp ); - -/* Report an error if the table cell was empty. */ - } else if( astOK ) { - astError( AST__BADTAB, "%s(%s): Row 1 of the binary table " - "contains no value for column '%s'.", status, method, - class, col ); - } - } - -/* Free memory. */ - lut = astFree( lut ); - key = astFree( key ); - -/* Now deal with coordinate arrays. */ - } else { - -/* Get the shape of the array. */ - dims = astMalloc( sizeof( int )*ndim ); - astColumnShape( table, col, ndim, &ndim, dims ); - -/* For coordinate arrays, check the length of the first axis is "ndim-1", as - required by FITS-WCS paper III. */ - if( astOK && dims[ 0 ] != ndim - 1 && !isindex ) { - astError( AST__BADTAB, "%s(%s): The first dimension of the coordinate " - "array has length %d (should be %d since the array has %d " - "dimensions).", status, method, class, dims[ 0 ], ndim - 1, - ndim ); - } - -/* We can currently only handle 1D look-up tables. These are stored in - notionally two-dimensional arrays in which the first dimension is - degenarate (i.e. spans only a single element). */ - if( ndim > 2 ) { - if( astOK ) astError( AST__INTER, "%s(%s): AST can currently only " - "handle 1-dimensional coordinate look-up tables " - "(the supplied table has %d dimensions).", status, - method, class, ndim - 1 ); - -/* Handle 1-dimensional look-up tables. */ - } else if( astOK ){ - -/* Allocate memory to hold the array values, and to hold the cell key. */ - lut = astMalloc( dims[ 1 ]*sizeof( double ) ); - key = astMalloc( strlen( col ) + 5 ); - if( astOK ) { - -/* Create the key for the table cell holding the required array. FITS-WCS - paper III mandates that tables always occur in the first row of the - table (and that the table only has one row). Ignore trailing spaces in - the column name. */ - sprintf( key, "%.*s(1)", (int) astChrLen( col ), col ); - -/* Copy the array values into the above memory. */ - if( astMapGet1D( table, key, dims[ 1 ], dims, lut ) ) { - -/* Create a 1D LutMap. FITS-WCS paper III (sec 6.1.2) mandates that the input - corresponds to FITS grid coord (i.e. 1.0 at the centre of the first entry). - Ensure the LutMap uses linear interpolation. */ - result = (AstMapping *) astLutMap( dims[ 1 ], lut, 1.0, 1.0, - "LutInterp=%d", status, - interp ); - -/* Report an error if the table cell was empty. */ - } else if( astOK ) { - astError( AST__BADTAB, "%s(%s): Row 1 of the binary table " - "contains no value for column '%s'.", status, method, - class, col ); - } - } - -/* Free memory. */ - lut = astFree( lut ); - key = astFree( key ); - } - dims = astFree( dims ); - } - -/* Issue a context message and annul the returned Mapping if an error - has occurred. */ - if( !astOK ) { - astError( astStatus, "%s(%s): Cannot read a look-up table for a " - "tabular WCS axis from column '%s' of a FITS binary table.", - status, method, class, col ); - result = astAnnul( result ); - } - -/* Return the result. */ - return result; -} - -static AstFrameSet *MakeFitsFrameSet( AstFitsChan *this, AstFrameSet *fset, - int ipix, int iwcs, int encoding, - const char *method, const char *class, - int *status ) { -/* -* Name: -* MakeFitsFrameSet - -* Purpose: -* Create a FrameSet which conforms to the requirements of the FITS-WCS -* papers. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstFrameSet *MakeFitsFrameSet( AstFitsChan *this, AstFrameSet *fset, -* int ipix, int iwcs, int encoding, -* const char *method, const char *class, -* int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function constructs a new FrameSet holding the pixel and WCS -* Frames from the supplied FrameSet, but optionally extends the WCS -* Frame to include any extra axes needed to conform to the FITS model. - -* Currently, this function does the following: -* -* - if the WCS Frame contains a 1D spectral Frame with a defined celestial -* reference position (SpecFrame attributes RefRA and RefDec), then -* it ensures that the WCS Frame also contains a pair of celestial -* axes (such axes are added if they do not already exist within the -* supplied WCS Frame). The pixel->WCS Mapping is adjusted accordingly. -* -* - if the WCS Frame contains a spectral axis and a pair of celestial -* axes, then the SpecFrame attributes RefRA and RefDec are set to the -* reference position defined by the celestial axes. The pixel->WCS -* Mapping is adjusted accordingly. -* -* - NULL is returned if the WCS Frame contains more than one spectral -* axis. -* -* - NULL is returned if the WCS Frame contains more than one pair of -* celestial axes. -* -* - Any isolated sky axes (i.e. not contained within a SkyFrame) are -* re-mapped from radians into degrees. - -* Parameters: -* this -* The FitsChan. -* fset -* The FrameSet to check. -* ipix -* The index of the FITS pixel Frame within "fset". -* iwcs -* The index of the WCS Frame within "fset". -* encoding -* The encoding in use. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A new FrameSet which confoms to the requirements of the FITS-WCS -* papers. The base Frame in this FrameSet will be the FITS pixel -* Frame, and the current Frame will be the WCS Frame. NULL is -* returned if an error has already occurred, or if the FrameSet cannot -* be produced for any reason. -*/ - -/* Local Variables: */ - AstFitsChan *fc; /* Pointer to temporary FitsChan */ - AstFrame *pframe; /* Pointer to the primary Frame */ - AstFrame *pixfrm; /* Pointer to the FITS pixel Frame */ - AstFrame *tfrm0; /* Pointer to a temporary Frame */ - AstFrame *tfrm; /* Pointer to a temporary Frame */ - AstFrame *wcsfrm; /* Pointer to the FITS WCS Frame */ - AstFrameSet *ret; /* The returned FrameSet */ - AstFrameSet *tfs; /* Pointer to a temporary FrameSet */ - AstMapping *map1; /* Pointer to pre-WcsMap Mapping */ - AstMapping *map3; /* Pointer to post-WcsMap Mapping */ - AstMapping *map; /* Pointer to the pixel->wcs Mapping */ - AstMapping *remap; /* Total Mapping from internal to external units */ - AstMapping *smap; /* Simplified Mapping */ - AstMapping *tmap0; /* Pointer to a temporary Mapping */ - AstMapping *tmap1; /* Pointer to a temporary Mapping */ - AstMapping *tmap2; /* Pointer to a temporary Mapping */ - AstMapping *tmap; /* Pointer to a temporary Mapping */ - AstMapping *umap; /* 1D Mapping from internal to external units */ - AstSpecFrame *skyfrm; /* Pointer to the SkyFrame within WCS Frame */ - AstSpecFrame *specfrm; /* Pointer to the SpecFrame within WCS Frame */ - AstWcsMap *map2; /* Pointer to WcsMap */ - char card[ AST__FITSCHAN_FITSCARDLEN + 1 ]; /* A FITS header card */ - char equinox_attr[ 13 ];/* Name of Equinox attribute for sky axes */ - char system_attr[ 12 ]; /* Name of System attribute for sky axes */ - const char *eqn; /* Pointer to original sky Equinox value */ - const char *extunit; /* External units string */ - const char *intunit; /* Internal units string */ - const char *skysys; /* Pointer to original sky System value */ - double con; /* Constant axis value */ - double reflat; /* Celestial latitude at reference point */ - double reflon; /* Celestial longitude at reference point */ - int *perm; /* Pointer to axis permutation array */ - int iax; /* Axis inex */ - int icurr; /* Index of original current Frame in returned FrameSet */ - int ilat; /* Celestial latitude index within WCS Frame */ - int ilon; /* Celestial longitude index within WCS Frame */ - int npix; /* Number of pixel axes */ - int nwcs; /* Number of WCS axes */ - int ok; /* Is the supplied FrameSet usable? */ - int paxis; /* Axis index within the primary Frame */ - int rep; /* Was error reporting switched on? */ - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Get copies of the pixel Frame, the WCS Frame and the Mapping. */ - tfrm = astGetFrame( fset, ipix ); - pixfrm = astCopy( tfrm ); - tfrm = astAnnul( tfrm ); - tfrm = astGetFrame( fset, iwcs ); - wcsfrm = astCopy( tfrm ); - tfrm = astAnnul( tfrm ); - tmap = astGetMapping( fset, ipix, iwcs ); - map = astCopy( tmap ); - tmap = astAnnul( tmap ); - -/* Store the number of pixel and WCS axes. */ - npix = astGetNaxes( pixfrm ); - nwcs = astGetNaxes( wcsfrm ); - -/* Search the WCS Frame for SkyFrames and SpecFrames. */ - umap = NULL; - remap = NULL; - specfrm = NULL; - skyfrm = NULL; - ok = 1; - ilat = -1; - ilon = -1; - for( iax = 0; iax < nwcs; iax++ ) { - -/* Obtain a pointer to the primary Frame containing the current WCS axis. */ - astPrimaryFrame( wcsfrm, iax, &pframe, &paxis ); - -/* If the current axis is a SpecFrame, save a pointer to it. If we have already - found a SpecFrame, abort. */ - if( astIsASpecFrame( pframe ) ) { - if( specfrm ) { - ok = 0; - break; - } - specfrm = astClone( pframe ); - -/* If the current axis is a SkyFrame, save a pointer to it, and its WCS - index. If we have already found a different SkyFrame, abort. */ - } else if( IsASkyFrame( pframe ) ) { - if( skyfrm ) { - if( pframe != (AstFrame *) skyfrm ) { - ok = 0; - break; - } - } else { - skyfrm = astClone( pframe ); - } - if( paxis == 0 ) { - ilon = iax; - } else { - ilat = iax; - } - -/* If the internal and external units differ, attempt to remap the axis - into its external units. */ - } else { - -/* Get the string describing the external units (the "Unit" attribute). */ - extunit = astGetUnit( pframe, paxis ); - -/* Get the string describing the internal units (the "InternalUnit" - attribute). */ - intunit = astGetInternalUnit( pframe, paxis ); - -/* If they are the same, we do not need to modify this axis. */ - if( astOK && strcmp( extunit, intunit ) ){ - -/* Otherwise, get the mapping from the internal units to the external - units, if possible. Ignore any error reported by unitmapper. */ - rep = astReporting( 0 ); - umap = astUnitMapper( intunit, extunit, NULL, NULL ); - if( !astOK ) astClearStatus; - astReporting( rep ); - - if( !umap ) { - -/* If the above failed, ensure that the external units are the same as - the internal units (except that internal radians are converted to - external degrees). */ - if( !strcmp( intunit, "rad" ) ) { - umap = (AstMapping *) astZoomMap( 1, AST__DR2D, " ", status ); - extunit = "deg"; - } else { - extunit = intunit; - } - - astSetUnit( wcsfrm, iax, extunit ); - } - } - } - -/* If no change is needed for the mapping for this axis, use a UnitMap. */ - if( !umap ) umap = (AstMapping *) astUnitMap( 1, " ", status ); - -/* Extend the parallel CmpMap to encompass the current axis. */ - if( remap ) { - tmap = (AstMapping *) astCmpMap( remap, umap, 0, " ", status ); - (void) astAnnul( remap ); - remap = tmap; - } else { - remap = astClone( umap ); - } - -/* Free resources. */ - umap = astAnnul( umap ); - pframe = astAnnul( pframe ); - } - -/* See if the pixel->wcs mapping needs to be modified to take account of - any changes to axis units. */ - smap = astSimplify( remap ); - if( ! astIsAUnitMap( smap ) ) { - tmap = (AstMapping *) astCmpMap( map, remap, 1, " ", status ); - (void) astAnnul( map ); - map = tmap; - } - remap = astAnnul( remap ); - smap = astAnnul( smap ); - -/* If the supplied FrameSet is usable... */ - if( ok ) { - -/* If we did not find a SpecFrame, return a FrameSet made from the base - and current Frames in the supplied FrameSet. */ - if( !specfrm ) { - ret = astFrameSet( pixfrm, "", status ); - astAddFrame( ret, AST__BASE, map, wcsfrm ); - -/* If we have a SpecFrame, proceed. */ - } else { - -/* Check that both the RefRA and RefDec attributes of the SpecFrame are set. - If not, return a FrameSet made from the base and current Frames in the - supplied FrameSet. Also do this if the original WCS Frame contains 3 - or more axes (since it is almost always inappropriate to add extra sky - axes in such circumestances). But if the other axes form a skyfram, - then we need to make sure they use the right refrence point. */ - if( !astTestRefRA( specfrm ) || !astTestRefDec( specfrm ) || - ( nwcs > 2 && !skyfrm ) ) { - ret = astFrameSet( pixfrm, "", status ); - astAddFrame( ret, AST__BASE, map, wcsfrm ); - -/* If we have a celestial reference position for the spectral axis, ensure - it is described correctly by a pair of celestial axes. */ - } else { - -/* If the WCS Frame does not contain any celestial axes, we add some now. */ - if( !skyfrm ) { - -/* The easiest way to create the required mapping from pixel to celestial - to create a simple FITS header and read it in via a FitsChan to create a - FrameSet. */ - fc = astFitsChan( NULL, NULL, "", status ); - astPutFits( fc, "CRPIX1 = 0", 0 ); - astPutFits( fc, "CRPIX2 = 0", 0 ); - astPutFits( fc, "CDELT1 = 0.0003", 0 ); - astPutFits( fc, "CDELT2 = 0.0003", 0 ); - astPutFits( fc, "CTYPE1 = 'RA---TAN'", 0 ); - astPutFits( fc, "CTYPE2 = 'DEC--TAN'", 0 ); - astPutFits( fc, "RADESYS = 'FK5'", 0 ); - astPutFits( fc, "EQUINOX = 2000.0", 0 ); - sprintf( card, "CRVAL1 = %.*g", AST__DBL_DIG, - AST__DR2D*astGetRefRA( specfrm ) ); - astPutFits( fc, card, 0 ); - sprintf( card, "CRVAL2 = %.*g", AST__DBL_DIG, - AST__DR2D*astGetRefDec( specfrm ) ); - astPutFits( fc, card, 0 ); - sprintf( card, "MJD-OBS = %.*g", AST__DBL_DIG, - TDBConv( astGetEpoch( specfrm ), AST__UTC, 1, - "astWrite", "FitsChan", status ) ); - astPutFits( fc, card, 0 ); - astClearCard( fc ); - tfs = astRead( fc ); - if( tfs ) { - -/* Create the new pixel->wcs Mapping. First get the 2-input,2-output - Mapping between pixel and sky coords from the above FrameSet. Then add - this Mapping in parallel with the original pixel->wcs Mapping. */ - tmap0 = astGetMapping( tfs, AST__BASE, AST__CURRENT ); - tmap1 = (AstMapping *) astCmpMap( map, tmap0, 0, "", status ); - tmap0 = astAnnul( tmap0 ); - -/* We now have a (npix+2)-input,(nwcs+2)-output Mapping. We now add a - PermMap in series with this which feeds the constant value 0.0 (the - CRPIX value in the above set of FITS headers) into the 2 pixel axes - corresponding to RA and Dec. This PermMap has npix-inputs and (npix+2) - outputs. The total Mapping then has npix inputs and (nwcs+2) outputs. */ - perm = astMalloc( sizeof( int )*(size_t) ( npix + 2 ) ); - if( astOK ) { - for( iax = 0; iax < npix; iax++ ) perm[ iax ] = iax; - perm[ npix ] = -1; - perm[ npix + 1 ] = -1; - con = 0.0; - tmap0 = (AstMapping *) astPermMap( npix, perm, npix + 2, perm, &con, "", status ); - tmap2 = (AstMapping *) astCmpMap( tmap0, tmap1, 1, "", status ); - tmap0 = astAnnul( tmap0 ); - tmap1 = astAnnul( tmap1 ); - -/* We now create the new WCS Frame with the extra RA and Dec axes. This - is just a CmpFrame made up of the original WCS Frame and the new - SkyFrame. */ - tfrm = astGetFrame( tfs, AST__CURRENT ); - tfrm0 = (AstFrame *) astCmpFrame( wcsfrm, tfrm, "", status ); - tfrm = astAnnul( tfrm ); - -/* Construct the returned FrameSet. */ - ret = astFrameSet( pixfrm, "", status ); - astAddFrame( ret, AST__BASE, tmap2, tfrm0 ); - tmap2 = astAnnul( tmap2 ); - tfrm0 = astAnnul( tfrm0 ); - -/* Free remaining resources. */ - perm = astFree( perm ); - } - tfs = astAnnul( tfs ); - } - fc = astAnnul( fc ); - -/* If the WCS Frame does contain celestial axes we make sure that the - SpecFrame uses the same reference point. */ - } else { - -/* The returned FrameSet has no extra Frames (although some attributes - may be changed) so just create a new FrameSet equaivalent to the supplied - FrameSet. */ - tfs = astFrameSet( pixfrm, "", status ); - astAddFrame( tfs, AST__BASE, map, wcsfrm ); - -/* The RefRA and RefDec attributes of the SpecFrame must be set in FK5 - J2000. Therefore we need to know the celestial reference point in - FK5 J2000. Modify the SkyFrame within the FrameSet to represent FK5 - J2000, noting the original sky system and equinox first so that they - can be re-instated (if set) later on. */ - sprintf( system_attr, "System(%d)", ilon + 1 ); - if( astTest( tfs, system_attr ) ) { - skysys = astGetC( tfs, system_attr ); - } else { - skysys = NULL; - } - astSetC( tfs, system_attr, "FK5" ); - sprintf( equinox_attr, "Equinox(%d)", ilon + 1 ); - if( astTest( tfs, equinox_attr ) ) { - eqn = astGetC( tfs, equinox_attr ); - } else { - eqn = NULL; - } - astSetC( tfs, equinox_attr, "J2000" ); - -/* The reference point for the celestial axes is defined by the WcsMap - contained within the Mapping. Split the mapping up into a list of serial - component mappings, and locate the first WcsMap in this list. The first - Mapping returned by this call is the result of compounding all the - Mappings up to (but not including) the WcsMap, the second returned Mapping - is the (inverted) WcsMap, and the third returned Mapping is anything - following the WcsMap. Only proceed if one and only one WcsMap is found. */ - tmap0 = astGetMapping( tfs, AST__BASE, AST__CURRENT ); - if( SplitMap( tmap0, astGetInvert( tmap0 ), ilon, ilat, &map1, &map2, &map3, status ) ){ - -/* The reference point in the celestial coordinate system is found by - transforming the fiducial point in native spherical co-ordinates - into absolute physical coordinates using map3. */ - if( GetFiducialWCS( map2, map3, ilon, ilat, &reflon, &reflat, status ) ){ - -/* Use reflon and reflat (which represent FK5 J2000 RA and Dec) to set - the values of the SpecFrame RefRA and RefDec attributes. Format the - values first so that we can use the FrameSet astSetC method, and so - maintain the FrameSet integrity. Use "tfs" rather than "wcsfrm" when - calling astFormat, as "wcsfrm" is not affected by the above change - to the current frame of "tfs" (i.e. astAddFrame takes a deep copy of the - supplied Frame). */ - astSetC( tfs, "RefRA", astFormat( tfs, ilon, reflon ) ); - astSetC( tfs, "RefDec", astFormat( tfs, ilat, reflat ) ); - -/* If succesfull, return a pointer to the FrameSet. */ - if( astOK ) ret = astClone( tfs ); - } - -/* Release resources. */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - map3 = astAnnul( map3 ); - -/* If no WcsMap was found, the celestial axes have no reference point and - so we can retain the original spectral reference point, so just return - the temporary FrameSet. */ - } else if( astOK ) { - ret = astClone( tfs ); - } - tmap0 = astAnnul( tmap0 ); - -/* Re-instate the original sky system and equinox. */ - if( skysys ) astSetC( tfs, system_attr, skysys ); - if( eqn ) astSetC( tfs, equinox_attr, eqn ); - -/* Release resources. */ - tfs = astAnnul( tfs ); - } - } - } - } - -/* Add a new current Frame into the FrameSet which increases the chances of - the requested encoding being usable. The index of the original current - Frame is returned, or AST__NOFRAME if no new Frame was added. */ - icurr = AddEncodingFrame( this, ret, encoding, method, class, status ); - -/* If a new Frame was added, remove the original current Frame. */ - if( icurr != AST__NOFRAME ) astRemoveFrame( ret, icurr ); - -/* Free resources. */ - if( specfrm ) specfrm = astAnnul( specfrm ); - if( skyfrm ) skyfrm = astAnnul( skyfrm ); - pixfrm = astAnnul( pixfrm ); - wcsfrm = astAnnul( wcsfrm ); - map = astAnnul( map ); - -/* Return NULL if an error has occurred. */ - if( !astOK && ret ) ret = astAnnul( ret ); - -/* Return the result. */ - return ret; -} - -static void MakeIndentedComment( int indent, char token, - const char *comment, const char *data, - char string[ AST__FITSCHAN_FITSCARDLEN - - FITSNAMLEN + 1 ], int *status ) { -/* -* Name: -* MakeIndentedComment - -* Purpose: -* Create a comment string containing an indentation bar. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void MakeIndentedComment( int indent, char token, -* const char *comment, const char *data, -* char string[ AST__FITSCHAN_FITSCARDLEN - -* FITSNAMLEN + 1 ], int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function creates a string that may be used as text in a -* FITS comment card. The string contains a textual comment -* preceded by a bar (a line of characters) whose length can be -* used to indicate a level of indentation (in the absence of any -* way of indenting FITS keywords). - -* Parameters: -* indent -* The level of indentation, in characters. -* token -* The character used to form the indentation bar. -* comment -* A pointer to a constant null-terminated string containing the text -* of the comment to be included. -* data -* A pointer to a constant null-terminated string containing any -* textual data to be appended to the comment. -* string -* A character array to receive the output string. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The comment text that appears in the output string is formed by -* concatenating the "comment" and "data" strings. -*/ - -/* Local Variables: */ - int i; /* Loop counter for input characters */ - int len; /* Number of output characters */ - int mxlen; /* Maximum length of output string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Calculate the maximum number of characters that the output string - can accommodate. */ - mxlen = AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN; - -/* Start the string with "indent" copies of the token character, but - without exceeding the output string length. */ - len = 0; - while ( ( len < indent ) && ( len < mxlen ) ) string[ len++ ] = token; - -/* Pad with spaces up to the start of the comment, if necessary. */ - while ( len < ( FITSCOMCOL - FITSNAMLEN - 1 ) ) { - string[ len++ ] = ' '; - } - -/* Add "/ " to introduce the comment (strictly not necessary as the - whole card will be a comment, but it matches the other non-comment - cards). Truncate if necessary. */ - for ( i = 0; ( i < 2 ) && ( len < mxlen ); i++ ) { - string[ len++ ] = "/ "[ i ]; - } - -/* Append the comment string, truncating it if it is too long. */ - for ( i = 0; comment[ i ] && ( len < mxlen ); i++ ) { - string[ len++ ] = comment[ i ]; - } - -/* Append the data string, again truncating if too long. */ - for ( i = 0; data[ i ] && ( len < mxlen ); i++ ) { - string[ len++ ] = data[ i ]; - } - -/* Terminate the output string. */ - string[ len ] = '\0'; -} - -static void MakeIntoComment( AstFitsChan *this, const char *method, - const char *class, int *status ){ - -/* -* Name: -* MakeIntoComment - -* Purpose: -* Convert a card into a FITS COMMENT card. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void MakeIntoComment( AstFitsChan *this, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function formats the card stored just prior to the current card, -* and re-stores it as a COMMENT card. It is used (when writing an Object -* to a FitsChan) to output values that are not "set" and which are -* therefore provided for information only, and should not be read back. -* the COMMENT card has the effect of "commenting out" the value. - -* Parameters: -* this -* Pointer to the FitsChan. -* method -* Calling method. -* class -* Object class. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - char card[ AST__FITSCHAN_FITSCARDLEN + 1 ]; /* Character buffer for FITS card data */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Move the current card backwards by one card. */ - MoveCard( this, -1, method, class, status ); - -/* Format the new current card. */ - FormatCard( this, card, method, status ); - -/* Write the resulting string to the FitsChan as the contents of a COMMENT - card, overwriting the existing card. The current card is incremented - by this call so that it refers to the same card as on entry. */ - astSetFitsCom( this, "COMMENT", card, 1 ); -} - -static int MakeIntWorld( AstMapping *cmap, AstFrame *fr, int *wperm, char s, - FitsStore *store, double *dim, double fitstol, - int sipok, const char *method, const char *class, - int *status ){ -/* -* Name: -* MakeIntWorld - -* Purpose: -* Create FITS header values which map grid into intermediate world -* coords. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int MakeIntWorld( AstMapping *cmap, AstFrame *fr, int *wperm, char s, -* FitsStore *store, double *dim, double fitstol, -* int sipok, const char *method, const char *class, -* int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function adds values to the supplied FitsStore which describe -* the transformation from grid (pixel) coords to intermediate world -* coords. The values added to the FitsStore correspond to the CRPIXj, -* PCi_j, CDELTi and WCSAXES keywords, and are determined by examining the -* supplied Mapping, which must be linear with an optional shift of -* origin, otherwise a value of zero is returned. The exception to -* this rule is that if the Mapping contains a PolyMap, and the "sipok" -* argument is non-zero, an attempt is made to create a set of SIP -* headers to describe the non-linear transformation. -* -* Much of the complication in the algorithm arises from the need to -* support cases where the supplied Mapping has more outputs than -* inputs. In these case we add some "degenerate" axes to the grid -* coord system, choosing their unit vectors to be orthogonal to all -* the other grid axes. It is assumed that degenerate axes will never -* be used to find a position other than at the axis value of 1.0. -* -* NOTE, appropriate values for CRVAL keywords should have been stored -* in the FitsStore before calling this function (since this function may -* modify them). - -* Parameters: -* cmap -* A pointer to a Mapping which transforms grid coordinates into -* intermediate world coordinates. The number of outputs must be -* greater than or equal to the number of inputs. -* fr -* Pointer to the final WCS coordinate Frame. -* wperm -* Pointer to an array of integers with one element for each axis of -* the "fr" Frame. Each element holds the zero-based index of the -* FITS-WCS axis (i.e. the value of "i" in the keyword names "CTYPEi", -* "CDi_j", etc) which describes the Frame axis. -* s -* The co-ordinate version character. A space means the primary -* axis descriptions. Otherwise the supplied character should be -* an upper case alphabetical character ('A' to 'Z'). -* store -* A pointer to the FitsStore into which the calculated CRPIX and -* CDi_j values are to be put. -* dim -* An array holding the image dimensions in pixels. AST__BAD can be -* supplied for any unknwon dimensions. -* fitstol -* The maximum departure from linearity that can be introduced by -* "cmap" on any axis for it to be considered linear. Expressed as -* a fraction of a grid pixel. -* sipok -* Flag indicating if SIP headers should be produced if there is -* a suitable PolyMap in the Mapping chain. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if the CRPIX and CDi_j values are -* succesfully calculated. Zero is returned otherwise. - -* Notes: -* - Zero is returned if an error occurs. -*/ - -/* Local Variables: */ - AstFrame *pfrm; - AstFrame *sfrm; - AstMapping *map; - AstMapping *sipmap; - AstPointSet *psetg; - AstPointSet *psetw; - double **fullmat; - double **partmat; - double **ptrw; - double **ptrg; - double *c; - double *cdelt; - double *cdmat; - double *colvec; - double *d; - double *g0; - double *g; - double *m; - double *mat; - double *tol; - double *w0; - double *y; - double cd; - double cd_sip[4]; - double crp; - double crpix_sip[2]; - double crv; - double cv; - double det; - double err; - double k; - double mxcv; - double skydiag0; - double skydiag1; - double val; - int *iw; - int *lin; - int *pperm; - int *skycol; - int havesip; - int i; - int ii; - int j; - int jax; - int jj; - int lonax; - int latax; - int nin; - int nout; - int nwcs; - int paxis; - int ret; - int sipax[2]; - int sing; - int skycol0; - int skycol1; - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Get the number of inputs and outputs for the Mapping. Return if the - number of outputs is smaller than the number of inputs. */ - nin = astGetNin( cmap ); - nout = astGetNout( cmap ); - if( nout < nin ) return ret; - -/* Simplify the supplied Mapping to reduce rounding errors when - transforming points. */ - map = astSimplify( cmap ); - -/* See if the WCS Frame contains a SkyFrame, and if so get the indices of - the Mapping outputs that correspond to the longitude and latitude - axes. */ - lonax = -1; - latax = -1; - for( i = 0; i < nout; i++ ) { - astPrimaryFrame( fr, i, &pfrm, &paxis ); - if( astIsASkyFrame( pfrm ) ) { - if( paxis == 0 ) { - lonax = i; - } else { - latax = i; - } - } - } - -/* If there is a pair of celestial axes in the WCS Frame, and if the - celestial axes can be described using SIP distortion, then put the - headers describing the SIP distortion into the FitsStore. This also - returns the CRPIX and CD values to use with the celestial axes. */ - havesip = 0; - if( sipok && lonax != -1 ){ - sipmap = SIPIntWorld( map, lonax, latax, s, store, dim, sipax, - crpix_sip, cd_sip, method, class, status ); - -/* If SIP headers were stored successfully, use the modified mapping from - now on. This is the same as "map" but does not include the PolyMap - from which the SIP headers were determined. This is done so that he - PolyMap does not break the linearity test performed below in order to - determine CRPIX and CD values for any other non-celestial axes. */ - if( sipmap ) { - (void) astAnnul( map ); - map = sipmap; - havesip = 1; - } - } - -/* Note the number of final World Coordinate axes (not necessarily the - same as "nout", since some intermediate axes may be discarded by a - later PermMap. */ - nwcs = astGetNaxes( fr ); - -/* Allocate work space. */ - g = astMalloc( sizeof(double)*(size_t) nin ); - g0 = astMalloc( sizeof(double)*(size_t) nin ); - w0 = astMalloc( sizeof(double)*(size_t) nout ); - tol = astMalloc( sizeof(double)*(size_t) nout ); - partmat = astMalloc( sizeof(double *)*(size_t) nout ); - lin = astMalloc( sizeof(int)*(size_t) nout ); - pperm = astMalloc( sizeof(int)*(size_t) nout ); - skycol = astMalloc( sizeof(int)*(size_t) nout ); - cdmat = astMalloc( sizeof(double)*(size_t) (nout*nout) ); - cdelt = astMalloc( sizeof(double)*(size_t) nout ); - -/* For safety, initialise all other pointers. */ - if( partmat ) for( j = 0; j < nout; j++ ) partmat[ j ] = NULL; - fullmat = NULL; - -/* Create a PointSet to hold an input (grid) position for each axis, plus - an extra one. Create two other PointSets to hold corresponding - output (IWC) coordinates. */ - psetg = astPointSet( nin + 1, nin, "", status ); - ptrg = astGetPoints( psetg ); - psetw = astPointSet( nin + 1, nout, "", status ); - ptrw = astGetPoints( psetw ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Assume success. */ - ret = 1; - -/* The next section finds a 'root' grid position for which the - corresponding IWC coordinates are all good. It also finds these IWC - coordinates, together with the IWC coordinates of "nin" points which - are a unit distance away from the root grid position along each - grid axis. It also finds an estimate of the rounding error in each - Mapping output. - ================================================================= */ - ret = FindBasisVectors( map, nin, nout, dim, psetg, psetw, status ); - -/* Save the grid root position in "g0". */ - for( j = 0; j < nin; j++ ) g0[ j ] = ptrg[ j ][ 0 ]; - -/* Save the transformed root position in "w0". This is the grid root - position represented as a vector within the Intermediate World - Coordinate system. */ - for( j = 0; j < nout; j++ ) { - w0[ j ] = ptrw[ j ][ 0 ]; - -/* Find the tolerance for positions on the j'th IWC axis. This is a - fraction "fitstol" of the largest change in the j'th IWC axis value - caused by moving out 1 pixel along any grid axis. */ - tol[ j ] = 0.0; - for( i = 0; i < nin; i++ ) { - err = fabs( ptrw[ j ][ i + 1 ] - w0[ j ] ); - if( err > tol[ j ] ) tol[ j ] = err; - } - tol[ j ] *= fitstol; - -/* If the tolerance is zero (e.g. as is produced for degenerate axes), - then use a tolerance equal to a very small fraction of hte degenerate - axis value. If the axis value is zero use a fixed small value. */ - if( tol[ j ] == 0.0 ) tol[ j ] = w0[ j ]*DBL_EPSILON*1.0E5; - if( tol[ j ] == 0.0 ) tol[ j ] = sqrt( DBL_MIN ); - } - -/* The next section finds the CD matrix. - ===================================== */ - -/* Initialise the CD matrix elements to "all missing". */ - for( i = 0; i < nout*nout; i++ ) cdmat[ i ] = AST__BAD; - -/* The elements of column "j" of the CD matrix form a vector (in Intermediate - World Coords) which corresponds to a unit vector along grid axis "j". - We now find these vectors for all the grid axes represented by the - inputs to the supplied Mapping. */ - for( i = 0; i < nin && ret; i++ ) { - -/* Form a unit vector along the current input axis. */ - for( ii = 0; ii < nin; ii++ ) g[ ii ] = 0.0; - g[ i ] = 1.0; - -/* Fit a straight line (within IWC) to the current input axis of the Mapping. - The IWC vector corresponding to a unit vector along the current input axis - is returned if the Mapping is linear. A NULL pointer is returned if the - Mapping is not linear. */ - partmat[ i ] = FitLine( map, g, g0, w0, dim[ i ], tol, status ); - -/* If unsuccesful, indicate failure and break out of the loop. */ - if( !partmat[ i ] ) { - ret = 0; - break; - } - } - -/* If we are using SIP distortion, replace the values for the celestial - axes found above with the values found by SIPIntWorld. */ - if( havesip ) { - partmat[ sipax[0] ][ lonax ] = cd_sip[ 0 ]; - partmat[ sipax[1] ][ lonax ] = cd_sip[ 1 ]; - partmat[ sipax[0] ][ latax ] = cd_sip[ 2 ]; - partmat[ sipax[1] ][ latax ] = cd_sip[ 3 ]; - } - -/* If the number of outputs for "map" is larger than the number of inputs, - then we will still be missing some column vectors for the CDi_j matrix - (which has to be square). We invent these such that the they are - orthogonal to all the other column vectors. Only do this if the - Mapping is linear. */ - if( ret ) { - fullmat = OrthVectorSet( nout, nin, partmat, status ); - if( !fullmat ) ret = 0; - } - -/* Check everything is OK. */ - if( ret ) { - -/* Check that the full matrix is invertable, and if not, see if there is - any way to make it invertable. */ - MakeInvertable( fullmat, nout, dim, status ); - -/* Set up an array holding index of the Mapping output corresponding to - each IWC axis (the inverse of "wperm"). Also look for matching pairs of - celestial WCS axes. For the first such pair, note the corresponding - column indices and the diagonal element of the matrix which gives the - scaling for the axis (taking account of the permutation of WCS axes). - Also note if the Mapping from intermediate world coords to final world - coords is linear for each axis (this is assumed to be the case if the - axis is part of a simple Frame). */ - sfrm = NULL; - skydiag0 = AST__BAD; - skydiag1 = AST__BAD; - skycol0 = -1; - skycol1 = -1; - for( i = 0; i < nout; i++ ) { - pperm[ wperm[ i ] ] = i; - astPrimaryFrame( fr, i, &pfrm, &paxis ); - if( IsASkyFrame( pfrm ) ) { - skycol[ wperm[ i ] ] = paxis + 1; - lin[ i ] = 0; - if( !sfrm ) { - sfrm = astClone( pfrm ); - skycol0 = wperm[ i ]; - skydiag0 = fullmat[ skycol0 ][ i ]; - } else if( sfrm == pfrm ) { - skycol1 = wperm[ i ]; - skydiag1 = fullmat[ skycol1 ][ i ]; - } - } else { - skycol[ wperm[ i ] ] = 0; - lin[ i ] = !strcmp( astGetClass( pfrm ), "Frame" ); - } - pfrm = astAnnul( pfrm ); - } - if( sfrm ) sfrm = astAnnul( sfrm ); - -/* We now have the complete CDi_j matrix. Now to find the CRPIX values. - These are the grid coords of the reference point (which corresponds to - the origin of Intermediate World Coords). The "w0" array currently holds - the position of the root position, as a position within IWC, and the - "g0" array holds the corresponding position in grid coordinates. We - also have IWC vectors which correspond to unit vectors on each grid - axis. The CRPIX values are defined by the matrix equation - w0 = fullmat*( g0 - crpix ) - The "g0" array only contains "nin" values. If nout>nin, then the - missing g0 values will be assumed to be zero when we come to find the - CRPIX values below. - We use palDmat to solve this system of simultaneous equations to get - crpix. The "y" array initially holds "w0" but is over-written to hold - "g0 - crpix". */ - mat = astMalloc( sizeof( double )*(size_t)( nout*nout ) ); - y = astMalloc( sizeof( double )*(size_t) nout ); - iw = astMalloc( sizeof( int )*(size_t) nout ); - if( astOK ) { - m = mat; - for( i = 0; i < nout; i++ ) { - for( j = 0; j < nout; j++ ) *(m++) = fullmat[ j ][ i ]; - y[ i ] = w0[ i ]; - } - palDmat( nout, mat, y, &det, &sing, iw ); - } - mat = astFree( mat ); - iw = astFree( iw ); - -/* Loop round all axes, storing the column vector pointer. */ - for( j = 0; j < nout; j++ ) { - colvec = fullmat[ j ]; - -/* Get the CRPIX values from the "y" vector created above by palDmat. - First deal with axes for which there are Mapping inputs. If we are - using SIP distortion, replace the crpix values for the celestial - axes found above with the values found by SIPIntWorld. */ - if( j < nin ) { - crp = g0[ j ] - y[ j ]; - if( havesip ) { - if( j == sipax[0] ){ - crp = crpix_sip[0]; - } else if( j == sipax[1] ){ - crp = crpix_sip[1]; - } - } - -/* If this is a grid axis which has been created to represent a "missing" - input to the mapping, we need to add on 1.0 to the crpix value found - above. This is because the "w0" vector corresponds to a value of zero - on any missing axes, but the FITS grid value for any missing axes is - 1.0. */ - } else { - crp = 1.0 - y[ j ]; - } - -/* Store the CD and CRPIX values for axes which correspond to inputs - of "map". The CD matrix elements are stored in an array and are - converted later to the corresponding PC and CDELT values. */ - if( j < nin || crp == 0.0 ) { - for( i = 0; i < nout; i++ ) { - cdmat[ wperm[ i ]*nout+j ] = colvec[ i ]; - } - SetItem( &(store->crpix), 0, j, s, crp, status ); - -/* The length of the unit vector along any "degenerate" axes was fixed - arbitrarily at 1.0 by the call to OrthVectorSet. We can probably - choose a more appropriate vector length. The choice shouldn't make any - difference to the transformation, but an appropriate value will look - more natural to human readers. */ - } else { - -/* First, try to arrange for longitude/latitude axis pairs to have the same - scale. Do we have a matching pair of celestial axes? */ - k = AST__BAD; - if( skydiag0 != AST__BAD && skydiag1 != AST__BAD ) { - -/* Is the current column the one which corresponds to the first celestial - axis, and does the other sky column correspond to a Mapping input? */ - if( skycol0 == j && skycol1 < nin ) { - -/* If so, scale this column so that its diagonal element is the negative - of the diagonal element of the other axis. This is on the assumption that - the scales on the two axes should be equal, and that longitude increases - east whilst latitude increases north, and that the CD matrix does not - introduce an axis permutation. */ - if( skydiag0 != 0.0 ) k = -skydiag1/skydiag0; - -/* Now see if the current column the one which corresponds to the second - celestial axis. Do the same as above. */ - } else if( skycol1 == j && skycol0 < nin ) { - if( skydiag1 != 0.0 ) k = -skydiag0/skydiag1; - -/* If neither of the above conditions was met, assume a diagonal element - value of 1.0 degrees for latitude axes, and -1.0 degrees for longitude - axes. */ - } - } - -/* If this failed, the next choice is to arrange for diagonally opposite - elements to be equal and opposite in value. Look for the element of the - column which has the largest diagonally opposite element, and choose a - scaling factor which makes this column element equal to the negative value - of its diagonally opposite element. Be careful to take axis permutations - into account when finding the value of the diagonal element. */ - if( k == AST__BAD ) { - mxcv = 0.0; - ii = pperm[ j ]; - for( i = 0; i < nout; i++ ) { - jj = wperm[ i ]; - if( jj < nin ) { - cv = fullmat[ jj ][ ii ]; - if( !astEQUAL( colvec[ i ], 0.0 ) && fabs( cv ) > mxcv ) { - mxcv = fabs( cv ); - k = -cv/colvec[ i ]; - } - } - } - } - -/* If still no scaling factor is available, use a scaling factor which - produces a diagonal element of 1.0 degree if the corresponding row is a - sky latitude axis, -1.0 degree of sky longitude axes, and 1.0 for other - axes. */ - if( k == AST__BAD && colvec[ pperm[ j ] ] != 0.0 ) { - if( skycol[ j ] ) { - k = AST__DD2R/colvec[ pperm[ j ] ]; - if( skycol[ j ] == 1 ) k = -k; - } else { - k = 1.0/colvec[ pperm[ j ] ]; - } - } - -/* If we still do not have a scaling, use 1.0 (no scaling). */ - if( k == AST__BAD ) k = 1.0; - -/* Now scale and store the column elements. */ - for( i = 0; i < nout; i++ ) { - cdmat[ wperm[ i ]*nout+j ] = k*colvec[ i ]; - } - -/* Find the corresponding modified CRPIX value and store it. */ - crp = 1.0 + ( crp - 1.0 )/k; - SetItem( &(store->crpix), 0, j, s, crp, status ); - } - -/* Free resources */ - if( pfrm ) pfrm = astAnnul( pfrm ); - } - -/* Any "degenerate" axes added in the above process for which the - intermediate->world mapping is linear, and which depend only on one - pixel axis, can be adjusted so that the reference point is at grid - coord 1.0. */ - for( i = 0; i < nout; i++ ) { - if( lin[ i ] ) { - -/* Check only one pixel axis contributes to this intermediate world axis - and find which one it is. */ - jax = -1; - for( j = 0; j < nout; j++ ) { - if( !astEQUAL( fullmat[ j ][ i ], 0.0 ) ) { - if( jax == -1 ) { - jax = j; - } else { - jax = -1; - break; - } - } - } - -/* We only adjust values for "degenerate" axes. */ - if( jax >= nin ) { - -/* Check that this pixel axis only contributes to the single world axis - currently being considered. */ - for( ii = 0; ii < nout; ii++ ) { - if( ii != i ) { - if( !astEQUAL( fullmat[ jax ][ ii ], 0.0 ) ) { - jax = -1; - break; - } - } - } - if( jax != -1 ) { - -/* Get the original CRVAL, CRPIX and CD values. Check they are defined.*/ - crv = GetItem( &(store->crval), wperm[ i ], 0, s, NULL, - method, class, status ); - cd = cdmat[ wperm[ i ]*nout + jax ]; - crp = GetItem( &(store->crpix), 0, jax, s, NULL, method, class, status ); - if( crv != AST__BAD && crp != AST__BAD && - cd != AST__BAD ) { - -/* Modify the CRPIX to be 1.0 and modify the CRVAL value accordingly. */ - SetItem( &(store->crpix), 0, jax, s, 1.0, status ); - SetItem( &(store->crval), wperm[ i ], 0, s, - cd*( 1.0 - crp ) + crv, status ); - } - } - } - } - } - -/* Finally, if there are fewer input axes than output axes, put a value for - the WCSAXES keyword into the store. */ - if( nin < nwcs ) SetItem( &(store->wcsaxes), 0, 0, s, nwcs, status ); - -/* Release resources. */ - y = astFree( y ); - } - -/* Produce and store PC and CDELT values from the above CD matrix */ - SplitMat( nout, cdmat, cdelt, status ); - c = cdmat; - d = cdelt; - for( i = 0; i < nout; i++ ){ - for( j = 0; j < nout; j++ ){ - val = *(c++); - if( i == j ){ - if( astEQUAL( val, 1.0 ) ) val = AST__BAD; - } else { - if( astEQUAL( val, 0.0 ) ) val = AST__BAD; - } - if( val != AST__BAD ) SetItem( &(store->pc), i, j, s, val, status ); - } - SetItem( &(store->cdelt), i, 0, s, *(d++), status ); - } - } - -/* Annul pointsets. */ - psetg = astAnnul( psetg ); - psetw = astAnnul( psetw ); - -/* Free other resources*/ - map = astAnnul( map ); - if( fullmat ) for( j = 0; j < nout; j++ ) fullmat[ j ] = astFree( fullmat[ j ] ); - if( partmat ) for( j = 0; j < nout; j++ ) partmat[ j ] = astFree( partmat[ j ] ); - fullmat = astFree( fullmat ); - partmat = astFree( partmat ); - cdmat = astFree( cdmat ); - cdelt = astFree( cdelt ); - g = astFree( g ); - g0 = astFree( g0 ); - w0 = astFree( w0 ); - tol = astFree( tol ); - lin = astFree( lin ); - skycol = astFree( skycol ); - pperm = astFree( pperm ); - -/* If an error has occurred, return zero. */ - if( !astOK ) ret = 0; - -/* Return the answer. */ - return ret; -} - -static void MakeInvertable( double **fullmat, int n, double *dim, int *status ){ -/* -* Name: -* MakeInvertable - -* Purpose: -* Modify a supplied square CD matrix if possible to make it invertable. - -* Type: -* Private function. - -* Synopsis: -* void MakeInvertable( double **fullmat, int n, double *dim, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A search is made for matrix inputs that have no effect on any -* matrix outputs. if any such matrix inputs are associated with -* degenerate pixel axes (i.e. pixel axes that span only a single -* pixel), then the matrix input should always have the value zero and -* so the corresponding diagonal element of the matrix can be set to -* 1.0 without changing and of the outputs. - -* Parameters: -* fullmat -* A pointer to an array with "n" elements corresponding to the n -* inputs of the matrix, each element being a pointer to an array -* with "n" elements corresponding to the n outputs of the matrix. -* n -* The number of inputs and outputs for the square matrix. -* dim -* Pointer to an array of "n" input (i.e. pixel) axis dimensions. -* Individual elements will be AST__BAD if dimensions are not known. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int i; /* Input index */ - int j; /* Output index */ - int unused; /* Does the current input have no effect on any output? */ - -/* Check inherited status */ - if( !astOK ) return; - -/* Look for any inputs that have no effect on any of the outputs. If such - an input is associated with a degenerate grid axis (i.e. a grid axis - with a dimension of 1.0), then the input value will always be zero and - so the corresponding diagonal element of the matrix can eb set to 1.0 - without affecting the output value (which will always be zero since - zero times anything is zero). Loop over all inputs. */ - for( i = 0; i < n; i++ ) { - -/* Assume this input has no effect on any output. */ - unused = 1; - -/* Loop over all outputs. */ - for( j = 0; j < n; j++ ) { - -/* If the corresponding matrix term is non-zero, the the input will have - an effect on the output, so set the unused flag false and break out of - the output loop. */ - if( fullmat[ i ][ j ] != 0.0 ) { - unused = 0; - break; - } - } - -/* If the input is unused, and it is associated with a degenerate pixel - axis, we can set the corresponding diagonal element of the matrix to - 1.0. */ - if( unused && dim[ i ] == 1.0 ) fullmat[ i ][ i ] = 1.0; - } -} -#if defined(THREAD_SAFE) - -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* FitsChan member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode - -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: - -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to FitsChan structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NUL. */ - if( ! this_object ) return result; - -/* Obtain a pointers to the FitsChan structure. */ - this = (AstFitsChan *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->keyseq, mode, extra, fail ); - if( !result ) result = astManageLock( this->keywords, mode, extra, fail ); - return result; -} -#endif - -static int Match( const char *test, const char *temp, int maxfld, int *fields, - int *nfld, const char *method, const char *class, int *status ){ -/* -* Name: -* Match - -* Purpose: -* Sees if a test keyword name matches a template. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int Match( const char *test, const char *temp, int maxfld, int *fields, -* int *nfld, const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* All characters in the template other than "%" (and the field width -* and type specifiers which follow a "%") must be matched by an -* identical character (ignoring case) in the test string. If a "%" occurs -* in the template, then the next character in the template should be a -* single digit specifying a field width. If it is zero, then the test -* string may contain zero or more matching characters. Otherwise, -* the test string must contain exactly the specified number of matching -* characters (i.e. 1 to 9). The field width digit may be omitted, in -* which case the test string must contain one or more matching -* characters. The next character in the template specifies the type of -* matching characters and must be one of "d", "c" or "f". Decimal digits -* are matched by "d", all upper (but not lower) case alphabetical -* characters are matched by "c", and all characters which are legal within -* a FITS keyword (i.e. upper case letters, digits, underscores and -* hyphens) are matched by "f". - -* Parameters: -* test -* Pointer to a null terminated string holding the keyword name to -* be tested. -* temp -* Pointer to a null terminated string holding the template. -* maxfld -* The maximum number of integer field values which should be -* returned in "fields". -* fields -* A pointer to an array of at least "maxfld" integers. This is -* returned holding the values of any integer fields specified -* in the template. The values are extracted from the test string, -* and stored in the order they appear in the template string. -* nfld -* Pointer to a location at which is returned the total number of -* integer fields in the test string. This may be more than the -* number returned in "fields" if "maxfld" is smaller than "*nfld". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the test string does not match the template -* string, and one is returned if it does. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char type; /* Field type specifier */ - const char *a; /* Pointer to next test character */ - const char *b; /* Pointer to next template character */ - int extend; /* Can the width of the first field be extended? */ - int i; /* Field index */ - int match; /* Does "test" match "temp"? */ - int nfret; /* No. of fields returned */ - int tmp; /* Field value */ - -/* Check global status. */ - if( !astOK ) return 0; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* On the first entry to this function, indicate that no integer fields - have yet been returned, and save a pointer to the start of the template - string. */ - if( !match_nentry ) { - *nfld = 0; - match_template = temp; - } - -/* Increment the number of entries into this function. */ - match_nentry++; - -/* Initialise pointers to the start of each string. */ - a = test; - b = temp; - -/* Initialise the returned flag to indicate that the two strings do not - match. */ - match = 0; - -/* Check that the initial part of the test string can match the first - field in the template. */ - if( MatchFront( a, b, &type, &extend, &match_na, &match_nb, method, class, match_template, status ) ){ - -/* If it does, increment the pointers to skip over the characters - used up in the comparison. */ - a += match_na; - b += match_nb; - -/* If the ends of both strings have been reached, they match. */ - if( *a == 0 && *b == 0 ){ - match = 1; - -/* Otherwise, if the end of the template has been reached but there are - still characters to be read from the test string, we could still have - a match if all the remaining test characters match an extandable field. */ - } else if( *b == 0 && *a != 0 && extend ){ - -/* Loop until all the matching characters have been read from the end of - the test string. */ - while( *a != 0 && MatchChar( *a, type, method, class, match_template, status ) ) a++; - -/* If we reached the end of the test string, we have a match. */ - if( *a == 0 ) match = 1; - -/* Otherwise, we need to carry on checking the remaining fields. */ - } else { - -/* Call this function recursively to see if the remainder of the - strings match. */ - if( Match( a, b, maxfld, fields, nfld, method, class, status ) ){ - match = 1; - -/* If the remainder of the strings do not match, we may be able to make - them match by using up some extra test characters on the first field. - This can only be done if the first field has an unspecified field width, - and if the next test character if of a type which matches the first - field in the template. */ - } else if( extend ){ - -/* Loop until all the suitable characters have been read from the - test string. Break out of the loop early if we find a field width - which results in the whole string matching. */ - while( MatchChar( *a, type, method, class, match_template, status ) ){ - a++; - if( Match( a, b, maxfld, fields, nfld, method, class, status ) ){ - match = 1; - break; - } - } - } - } - } - -/* If the strings match and the leading field is an integer, decode - the field and store it in the supplied array (if there is room). */ - if( match && type == 'd' && a > test ){ - if( *nfld < maxfld ){ - sprintf( match_fmt, "%%%dd", (int) ( a - test ) ); - astSscanf( test, match_fmt, fields + *nfld ); - } - (*nfld)++; - } - -/* Decrement the number of entries into this function. */ - match_nentry--; - -/* If we are leaving this function for the last time, reverse the - order of the returned integer fields so that they are returned - in the same order that they occur in the template. */ - if( !match_nentry ){ - nfret = ( *nfld < maxfld ) ? (*nfld) : maxfld; - match_pa = fields; - match_pb = fields + nfret - 1; - for( i = 0; i < nfret/2; i++ ){ - tmp = *match_pa; - *(match_pa++) = *match_pb; - *(match_pb--) = tmp; - } - } - -/* Return the result. */ - return match; -} - -static int MatchChar( char test, char type, const char *method, - const char *class, const char *template, int *status ){ -/* -* Name: -* MatchChar - -* Purpose: -* See if a given character is of a specified type. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int MatchChar( char test, char type, const char *method, -* const char *class, const char *template, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function checks that the supplied test character belongs -* to the set of characters specified by the parameter "type". - -* Parameters: -* test -* The character to test. -* type -* The character specifying the set of acceptable characters. This -* should be one of the field type characters accepted by function -* Match (e.g. "d", "c" or "f"). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* template -* Pointer to the start of the whole template string, for use in error -* messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the test character does not belongs to the -* specified character set, and one is returned if it does. - -* Notes: -* - An error is reported if the type specifier is not legal. -* - Zero is returned if an error has already occurred, or if ths -* function fails for any reason. -*/ - -/* Local Variables: */ - int ret; /* Returned flag */ - -/* Check global status. */ - ret = 0; - if( !astOK ) return ret; - -/* Check for "d" specifiers (digits). */ - if( type == 'd' ){ - ret = isdigit( (int) test ); - -/* Check for "c" specifiers (upper case letters). */ - } else if( type == 'c' ){ - ret = isupper( (int) test ); - -/* Check for "s" specifiers (any legal FITS keyword character). */ - } else if( type == 'f' ){ - ret = isFits( (int) test ); - -/* Report an error for any other specifier. */ - } else if( astOK ){ - ret = 0; - astError( AST__BDFMT, "%s(%s): Illegal field type or width " - "specifier '%c' found in filter template '%s'.", status, - method, class, type, template ); - } - -/* Return the answer. */ - return ret; -} - -static int MatchFront( const char *test, const char *temp, char *type, - int *extend, int *ntest, int *ntemp, - const char *method, const char *class, - const char *template, int *status ){ -/* -* Name: -* MatchFront - -* Purpose: -* Sees if the start of a test string matches the start of a template. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int MatchFront( const char *test, const char *temp, char *type, -* int *extend, int *ntest, int *ntemp, -* const char *method, const char *class, -* const char *template ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function looks for a match between the first field in the -* template string and the string at the start of the test string, -* using the syntax described in function Match. - -* Parameters: -* test -* Pointer to a null terminated string holding the keyword name to -* be tested. -* temp -* Pointer to a null terminated string holding the template. -* type -* Pointer to a location at which to return a character specifying the -* sort of field that was matched. This will be one of the legal field -* types accepted by Match (e.g. "d", "c" or "f"), or null (zero) if -* the first field in the template string was a literal character (i.e. -* did not start with a "%"). -* extend -* Pointer to a location at which to return a flag which will be non-zero -* if the further test characters could be matched by the first field in -* the template. This will be the case if the template field only -* specifies a minimum number of matching characters (i.e. if the field -* width can be extended). For instance, "%d" can be extended, but "%1d" -* cannot. -* ntest -* Pointer to a location at which to return the number of characters -* matched in the test string. This will be the minimum number allowed -* by the template field. -* ntemp -* Pointer to a location at which to return the number of characters -* read from the template string (i.e. the number of characters in the -* field specification). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* template -* Pointer to the start of the whole template string, for use in error -* messages. - -* Returned Value: -* Zero is returned if the test string starts with fewer than the -* minimum number of characters matching the template string, and one -* is returned if it does. - -* Notes: -* - Zero is returned if an error has already occurred, or if this -* function fails for any reason. -*/ - -/* Local Variables: */ - const char *a; /* Pointer to next test character */ - const char *b; /* Pointer to next template character */ - int i; /* Character index */ - int match; /* Does "test" match "temp"? */ - -/* Check global status. */ - if( !astOK ) return 0; - -/* Initialise pointers to the start of each string. */ - a = test; - b = temp; - -/* Initialise the returned value to indicate that the strings match. */ - match = 1; - -/* If the current character in the template is not a % sign, it must - match the current character in the test string (except for case). */ - if( *b != '%' ){ - if( toupper( (int) *b ) != toupper( (int) *a ) ) { - match = 0; - -/* If the characters match, return all the required information. */ - } else { - *type = 0; - *extend = 0; - *ntest = 1; - *ntemp = 1; - } - -/* If the current character of the template is a %, we need to match - a field. */ - } else { - *ntemp = 3; - -/* The next character in the template string determines the field width. - Get the lowest number of characters which must match in the test string, - and set a flag indicating if this lowest limit can be extended. */ - b++; - if( *b == '0' ){ - *ntest = 0; - *extend = 1; - } else if( *b == '1' ){ - *ntest = 1; - *extend = 0; - } else if( *b == '2' ){ - *ntest = 2; - *extend = 0; - } else if( *b == '3' ){ - *ntest = 3; - *extend = 0; - } else if( *b == '4' ){ - *ntest = 4; - *extend = 0; - } else if( *b == '5' ){ - *ntest = 5; - *extend = 0; - } else if( *b == '6' ){ - *ntest = 6; - *extend = 0; - } else if( *b == '7' ){ - *ntest = 7; - *extend = 0; - } else if( *b == '8' ){ - *ntest = 8; - *extend = 0; - } else if( *b == '9' ){ - *ntest = 9; - *extend = 0; - -/* If no field width was given, one or more test characters are matched. - Step back a character so that the current character will be re-used as - the type specifier. */ - } else { - *ntest = 1; - *extend = 1; - b--; - (*ntemp)--; - } - -/* The next template character gives the type of character which should - be matched. */ - b++; - *type = *b; - -/* Report an error if the template string ended within the field - specifier. */ - if( !*b ){ - match = 0; - astError( AST__BDFMT, "%s(%s): Incomplete field specifier found " - "at end of filter template '%s'.", status, method, class, - template ); - -/* Otherwise, check that the test string starts with the minimum allowed - number of characters matching the specified type. */ - } else { - for( i = 0; i < *ntest; i++ ){ - if( !MatchChar( *a, *type, method, class, template, status ) ){ - match = 0; - break; - } - a++; - } - } - } - -/* Return the answer. */ - return match; -} - -static void MarkCard( AstFitsChan *this, int *status ){ - -/* -* Name: -* MarkCard - -* Purpose: -* Mark the current card as having been read into an AST object. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void MarkCard( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The current card is marked as having been "provisionally used" in -* the construction of an AST object. If the Object is constructed -* succesfully, such cards are marked as having been definitely used, -* and they are then considered to have been removed from the FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan containing the list of cards. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The card remains the current card even though it is now marked -* as having been read. -*/ - int flags; - -/* Return if the global error status has been set, or the current card - is not defined. */ - if( !astOK || !this->card ) return; - -/* Set the PROVISIONALLY_USED flag in the current card, but only if the - PROTECTED flag is not set. */ - flags = ( (FitsCard *) this->card )->flags; - if( !( flags & PROTECTED ) ) { - ( (FitsCard *) this->card )->flags = flags | PROVISIONALLY_USED; - } -} - -static int MoveCard( AstFitsChan *this, int move, const char *method, - const char *class, int *status ){ - -/* -* Name: -* MoveCard - -* Purpose: -* Move the current card a given number of cards forward or backwards. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int MoveCard( AstFitsChan *this, int move, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The current card is increment by the given number of cards, ignoring -* cards which have been read into an AST object if the ignore_used flag -* is set non-zero. - -* Parameters: -* this -* Pointer to the FitsChan containing the list of cards. -* move -* The number of cards by which to move the current card. Positive -* values move towards the end-of-file. Negative values move -* towards the start of the file (i.e. the list head). -* method -* Pointer to string holding name of calling method. -* class -* Pointer to string holding object class. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of cards actually moved. This may not always be equal to -* the requested number (for instance, if the end or start of the -* FitsChan is encountered first). - -* Notes: -* - If the end-of-file is reached before the required number of -* cards have been skipped, the current card is set NULL, to indicate -* an end-of-file condition. -* - If the start of the file is reached before the required number of -* cards have been skipped, the current card is left pointing to the -* first usable card. -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - FitsCard *card; /* The current card */ - FitsCard *card0; /* The previous non-deleted card */ - int moved; /* The number of cards moved by so far */ - -/* Return if the supplied object is NULL or the FitsChan is - empty, or zero movement is requested. */ - if( !this || !this->head || !move ) return 0; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Get a pointer to the current card. */ - card = (FitsCard *) this->card; - -/* Initialise the number of cards moved so far. */ - moved = 0; - -/* First deal with positive movements (towards the end-of-file). */ - if( move > 0 ){ - -/* Loop round moving on to the next card until the correct number of - moves have been made, or the end-of-file is reached. */ - while( moved < move && card ){ - -/* Get a pointer to the next card in the list, reporting an error if the - links are inconsistent. */ - card = GetLink( card, NEXT, method, class, status ); - -/* If we have moved past the last card and are now pointing back at the - list head, then indicate that we are at end-of-file by setting the - card pointer NULL. */ - if( (void *) card == this->head ){ - card = NULL; - -/* Otherwise, increment the number of cards moved. We ignore cards which - have been read into an AST object if the external "ignore_used" flag is - set. */ - } else if( card ){ - if( !CARDUSED(card) ) moved++; - } - } - -/* Now deal with negative movements (towards the list head), so long as - we are not currently at the list head. */ - } else if( (void *) card != this->head ){ - -/* If we are currently at end-of-file, replace the NULL pointer for the - current card with a pointer to the list head. The first step backwards - will make the last card the current card. */ - if( !card ) card = (FitsCard *) this->head; - -/* Loop round until the correct number of cards have been moved. */ - while( moved < -move && card ){ - -/* If cards which have been read into an AST object are to be included in the - count of moved cards, get a pointer to the previous card in the list, - reporting an error if the links are inconsistent. */ - if( !ignore_used ){ - card = GetLink( card, PREVIOUS, method, class, status ); - -/* If cards which have been read into an AST object are to be ignored... */ - } else { - -/* We need to find the previous card which has not been read into an AST - object. We do not search beyond the start of the list. */ - card0 = GetLink( card, PREVIOUS, method, class, status ); - while( card0 && CARDUSED(card0) && (void *) card0 != this->head ){ - card0 = GetLink( card0, PREVIOUS, method, class, status ); - } - -/* If no such card was found we leave the card where it is. */ - if( card0 && ( card0->flags & USED ) ) { - break; - -/* Otherwise, move back to card found above. */ - } else { - card = card0; - } - } - -/* Increment the number of cards moved. */ - moved++; - -/* If the current card is the list head, break out of the loop. */ - if( (void *) card == this->head ) break; - } - } - -/* Store the new current card. */ - this->card = (void *) card; - -/* Return the answer. */ - return moved; -} - -static double NearestPix( AstMapping *map, double val, int axis, int *status ){ -/* -* Name: -* NearestPix - -* Purpose: -* Find an axis value which corresponds to an integer pixel value. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* double NearestPix( AstMapping *map, double val, int axis, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The supplied axis value is transformed using the inverse of the -* supplied Mapping (other axes are given the value AST__BAD). The -* resulting axis values are rounded to the nearest whole number, and -* then transformed back using the supplied Mapping in the forward -* direction. If the nominated axis value is good, it is returned as -* the function value, otherwise the supplied value is returned unchanged. - -* Parameters: -* map -* A Mapping (usually the input coordinates will correspond to -* pixel coordinates). -* val -* A value for one of the outputs of the "map" Mapping. -* axis -* The index of the Mapping output to which "val" refers. -* status -* Pointer to the inherited status variable. - -* Retuned Value: -* The modified output axis value. -*/ - -/* Local Variables: */ - AstMapping *tmap; /* Mapping to be used */ - AstPointSet *pset1; /* Pixel coords PointSet */ - AstPointSet *pset2; /* WCS coords PointSet */ - double **ptr1; /* Pointer to data in pset1 */ - double **ptr2; /* Pointer to data in pset2 */ - double result; /* Returned value */ - int *ins; /* Array holding input axis indices */ - int i; /* Loop count */ - int nin; /* Number of Mapping inputs */ - int nout; /* Number of Mapping outputs */ - -/* Initialise. */ - result = val; - -/* Check inherited status, and that the supplied value is good. */ - if( !astOK || result == AST__BAD ) return result; - -/* If the supplied Mapping has no inverse, trying splitting off the - transformation for the required axis, which may have an inverse. - If succesful, use the 1-in,1-out Mapping returned by astMapSPlit - instead of the supplied Mapping, and adjust the axis index accordingly. */ - if( !astGetTranInverse( map ) ) { - astInvert( map ); - ins = astMapSplit( map, 1, &axis, &tmap ); - if( tmap ) { - astInvert( tmap ); - axis = 0; - } else { - tmap = astClone( map ); - } - ins = astFree( ins ); - astInvert( map ); - } else { - tmap = astClone( map ); - } - -/* If the Mapping still has no inverse, return the supplied value - unchanged. */ - if( astGetTranInverse( tmap ) ) { - -/* Get the number of input and output coordinates. */ - nin = astGetNin( tmap ); - nout = astGetNout( tmap ); - -/* Create PointSets to hold a single input position and the corresponding - output position. */ - pset1 = astPointSet( 1, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - pset2 = astPointSet( 1, nout, "", status ); - ptr2 = astGetPoints( pset2 ); - if( astOK ) { - -/* Assign AST__BAD values to all output axes, except for the specified - axis, which is given the supplied axis value. */ - for( i = 0; i < nout; i++ ) ptr2[ i ][ 0 ] = AST__BAD; - ptr2[ axis ][ 0 ] = val; - -/* Transform this output position into an input position. */ - (void) astTransform( tmap, pset2, 0, pset1 ); - -/* Round all good axis values in the resulting input position to the nearest - integer. */ - for( i = 0; i < nin; i++ ) { - if( ptr1[ i ][ 0 ] != AST__BAD ) { - ptr1[ i ][ 0 ] = (int) ( ptr1[ i ][ 0 ] + 0.5 ); - } - } - -/* Transform this input position back into output coords. */ - (void) astTransform( tmap, pset1, 1, pset2 ); - -/* If the resulting axis value is good, return it. */ - if( ptr2[ axis ] [ 0 ] != AST__BAD ) result = ptr2[ axis ] [ 0 ]; - } - -/* Free resources. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - } - tmap = astAnnul( tmap ); - -/* Return the result. */ - return result; -} - -static void NewCard( AstFitsChan *this, const char *name, int type, - const void *data, const char *comment, int flags, - int *status ){ - -/* -* Name: -* NewCard - -* Purpose: -* Insert a new card in front of the current card. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void NewCard( AstFitsChan *this, const char *name, int type, -* const void *data, const char *comment, int flags, -* int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The supplied keyword name, data type and value, and comment are -* stored in a new FitsCard structure, and this structure is -* inserted into the circular linked list stored in the supplied -* FitsChan. It is inserted in front of the current card. - -* Parameters: -* this -* Pointer to the FitsChan containing the list of cards. -* name -* Pointer to a string holding the keyword name of the new card. -* type -* An integer value representing the data type of the keyword. -* data -* Pointer to the data associated with the keyword. -* comment -* Pointer to a null-terminated string holding a comment. -* flags -* The flags to assign to the card. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The new card is inserted into the list in front of the current card, -* so that the "next" link from the new card points to the current card. -* If the FitsChan is currently at end-of-file (indicated by a NULL -* pointer being stored for the current card), then the card is appended -* to the end of the list. The pointer to the current card is left -* unchanged. -* - Keyword names are converted to upper case before being stored. -* - Any trailing white space in a string value is saved as supplied. -* - Logical values are converted to zero or one before being stored. -* - The "comment" and/or "data" pointers may be supplied as NULL. -*/ - -/* Local Variables: */ - FitsCard *new; /* Pointer to the new card */ - FitsCard *prev; /* Pointer to the previous card in the list */ - char *b; /* Pointer to next stored character */ - const char *a; /* Pointer to next supplied character */ - int lval; /* Logical data value restricted to 0 or 1 */ - int nc; /* No. of characters to store */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get memory to hold the new FitsCard structure. */ - new = (FitsCard *) astMalloc( sizeof( FitsCard ) ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Copy the keyword name, converting to upper case. */ - a = name; - b = new->name; - while( *a ) *(b++) = (char) toupper( (int) *(a++) ); - *b = 0; - -/* Ensure that a KeyMap exists to hold the keywords currently in the - FitsChan. */ - if( !this->keywords ) this->keywords = astKeyMap( " ", status ); - -/* Add the keyword name to the KeyMap. The value associated with the - KeyMap entry is not used and is set arbitrarily to zero. */ - astMapPut0I( this->keywords, new->name, 0, NULL ); - -/* Copy the data type. */ - new->type = type; - -/* Copy any data (ignore any data supplied for an UNDEF value). */ - if( data && type != AST__UNDEF ){ - -/* Logical values are converted to zero or one before being stored. */ - if( type == AST__LOGICAL ){ - lval = *( (int *) data ) ? 1 : 0; - new->size = sizeof( int ); - new->data = astStore( NULL, (void *) &lval, sizeof( int ) ); - -/* String values... */ - } else if( type == AST__STRING || type == AST__CONTINUE ){ - -/* Find the number of characters excluding the trailing null character. */ - nc = strlen( data ); - -/* Store the string, reserving room for a terminating null. */ - new->size = (size_t)( nc + 1 ); - new->data = astStore( NULL, (void *) data, (size_t)( nc + 1 ) ); - -/* Terminate it. */ - ( (char *) new->data)[ nc ] = 0; - -/* Other types are stored as supplied. */ - } else if( type == AST__INT ){ - new->size = sizeof( int ); - new->data = astStore( NULL, (void *) data, sizeof( int ) ); - } else if( type == AST__FLOAT ){ - new->size = sizeof( double ); - new->data = astStore( NULL, (void *) data, sizeof( double ) ); - } else if( type == AST__COMPLEXF ){ - if( *( (double *) data ) != AST__BAD ) { - new->size = 2*sizeof( double ); - new->data = astStore( NULL, (void *) data, 2*sizeof( double ) ); - } else { - nc = strlen( BAD_STRING ); - new->size = (size_t)( nc + 1 ); - new->data = astStore( NULL, BAD_STRING, (size_t)( nc + 1 ) ); - ( (char *) new->data)[ nc ] = 0; - } - } else if( type == AST__COMPLEXI ){ - new->size = 2*sizeof( int ); - new->data = astStore( NULL, (void *) data, 2*sizeof( int ) ); - } else { - new->size = 0; - new->data = NULL; - } - } else { - new->size = 0; - new->data = NULL; - } - -/* Find the first non-blank character in the comment, and find the used - length of the remaining string. We retain leading and trailing white - space if the card is a COMMENT card. */ - if( comment ){ - a = comment; - if( type != AST__COMMENT ) { - while( isspace( *a ) ) a++; - nc = ChrLen( a, status ); - } else { - nc = strlen( a ); - } - } else { - nc = 0; - } - -/* Copy any comment, excluding leading and trailing white space unless - this is a COMMENT card */ - if( nc > 0 ){ - new->comment = astStore( NULL, (void *) a, (size_t)( nc + 1 ) ); - ( (char *) new->comment)[ nc ] = 0; - } else { - new->comment = NULL; - } - -/* Set the supplied flag values. */ - new->flags = flags; - -/* Insert the copied card into the list, in front of the current card. If - the current card is the list head, make the new card the list head. */ - if( this->card ){ - prev = ( ( FitsCard *) this->card )->prev; - ( ( FitsCard *) this->card )->prev = new; - new->prev = prev; - prev->next = new; - new->next = (FitsCard *) this->card; - if( this->card == this->head ) this->head = (void *) new; - -/* If the FitsChan is at end-of-file, append the new card to the end of - the list (i.e. insert it just before the list head). */ - } else { - if( this->head ){ - prev = ( (FitsCard *) this->head )->prev; - ( (FitsCard *) this->head )->prev = new; - new->prev = prev; - prev->next = new; - new->next = (FitsCard *) this->head; - -/* If there are no cards in the list, start a new list. */ - } else { - new->prev = new; - new->next = new; - this->head = (void *) new; - this->card = NULL; - } - } - } - -/* Return. */ - return; -} - -static AstMapping *NonLinSpecWcs( AstFitsChan *this, char *algcode, - FitsStore *store, int i, char s, - AstSpecFrame *specfrm, const char *method, - const char *class, int *status ) { - -/* -* Name: -* NonLinSpecWcs - -* Purpose: -* Create a Mapping describing a FITS-WCS non-linear spectral algorithm - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* AstMapping *NonLinSpecWcs( AstFitsChan *this, char *algcode, -* FitsStore *store, int i, char s, -* AstSpecFrame *specfrm, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function uses the contents of the supplied FitsStore to create -* a Mapping which goes from Intermediate World Coordinate (known as "w" -* in the context of FITS-WCS paper III) to the spectral system -* described by the supplied SpecFrame. -* -* The returned Mapping implements the non-linear "X2P" algorithms -* described in FITS-WCS paper III. The axis is linearly sampled in -* system "X" but expressed in some other system (specified by the -* supplied SpecFrame). - -* Parameters: -* this -* Pointer to the FitsChan. -* algcode -* Pointer to a string holding the non-linear "-X2P" code for the -* required algorithm. This includes aleading "-" character. -* store -* Pointer to the FitsStore structure holding the values to use for -* the WCS keywords. -* i -* The zero-based index of the spectral axis within the FITS header -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* specfrm -* Pointer to the SpecFrame. This specified the "S" system - the -* system in which the CRVAL kewyords (etc) are specified. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a Mapping, or NULL if an error occurs. -*/ - -/* Local Variables: */ - AstFrameSet *fs; - AstMapping *map1; - AstMapping *ret; - AstSpecFrame *xfrm; - AstMapping *map2; - char buf[ 100 ]; - char pc; - double crv; - double ds; - double in_a; - double in_b; - double out_a; - double out_b; - int ok; - int s_sys; - -/* Check the global status. */ - ret = NULL; - if( !astOK ) return ret; - -/* Identify the spectral "X" system within the "X2P" algorithm code, and - create a SpecFrame describing the X system ("X" is the system in - which the axis is linearly sampled). This is done by copying the - supplied SpecFrame and then setting its System attribute. Copying - the supplied SpecFrame ensures that all the other attributes (RestFreq, - etc.) are set correctly. */ - ok = 1; - xfrm = astCopy( specfrm ); - if( algcode[ 1 ] == 'F' ) { - astSetSystem( xfrm, AST__FREQ ); - astSetUnit( xfrm, 0, "Hz" ); - } else if( algcode[ 1 ] == 'W' ) { - astSetSystem( xfrm, AST__WAVELEN ); - astSetUnit( xfrm, 0, "m" ); - } else if( algcode[ 1 ] == 'V' ) { - astSetSystem( xfrm, AST__VREL ); - astSetUnit( xfrm, 0, "m/s" ); - } else if( algcode[ 1 ] == 'A' ) { - astSetSystem( xfrm, AST__AIRWAVE ); - astSetUnit( xfrm, 0, "m" ); - } else { - ok = 0; - } - -/* If the X system was identified, find a Mapping from the "S" (specfrm) - system to the X system. */ - map1 = NULL; - if( ok ) { - ok = 0; - fs = astConvert( specfrm, xfrm, "" ); - if( fs ) { - map1 = astGetMapping( fs, AST__BASE, AST__CURRENT ); - fs = astAnnul( fs ); - ok = 1; - } - -/* Issue a warning if the "P" system is not the correct one for the given - "S" system. We can however continue, sine AST interprets illegal "P" - systems correctly. */ - pc = 0; - s_sys = astGetSystem( specfrm ); - if( s_sys == AST__FREQ || s_sys == AST__ENERGY || - s_sys == AST__WAVENUM || s_sys == AST__VRADIO ) { - pc = 'F'; - } else if( s_sys == AST__WAVELEN || s_sys == AST__VOPTICAL || - s_sys == AST__REDSHIFT ){ - pc = 'W'; - } else if( s_sys == AST__AIRWAVE ) { - pc = 'A'; - } else if( s_sys == AST__BETA || s_sys == AST__VREL ) { - pc = 'V'; - } else if( astOK ) { - pc = algcode[ 3 ]; - astError( AST__INTER, "%s: Function NonLinSpecWcs does not yet " - "support spectral axes of type %s (internal AST " - "programming error).", status, method, astGetC( specfrm, "System" ) ); - } - if( algcode[ 3 ] != pc ) { - sprintf( buf, "The spectral CTYPE value %s%s is not legal - " - "using %s%.3s%c instead.", astGetC( specfrm, "System" ), - algcode, astGetC( specfrm, "System" ), algcode, pc ); - Warn( this, "badctype", buf, method, class, status ); - } - } - -/* If succesfull, use this Mapping to find the reference value (CRVAL) - in the "X" system. */ - if( ok ) { - -/* Get the CRVAL value for the spectral axis (this will be in the S system). */ - crv = GetItem( &(store->crval), i, 0, s, NULL, method, class, status ); - if( crv == AST__BAD ) crv = 0.0; - -/* Convert it to the X system. */ - astTran1( map1, 1, &crv, 1, &crv ); - -/* Invert this Mapping so that it forward transformation goes from X to S. */ - astInvert( map1 ); - -/* Find the rate of change of S with respect to X (dS/dX) at the reference - point (x = crv). */ - ds = astRate( map1, &crv, 0, 0 ); - if( ds != AST__BAD && ds != 0.0 ) { - -/* FITS-WCS paper III says that dS/dw must be 1.0 at the reference point. - Therefore dX/dw = dX/dS at the reference point. Also, since the spectral - axis is linear in X, dX/dw must be constant. Therefore the Mapping from - IWC to X is a WinMap which scales the IWC axis ("w") by dX/dw and adds - on the X value at the reference point. */ - if( crv != 0.0 ) { - in_a = 0.0; - out_a = crv; - in_b = crv*ds; - out_b = 2.0*crv; - map2 = (AstMapping *) astWinMap( 1, &in_a, &in_b, &out_a, &out_b, "", status ); - } else { - map2 = (AstMapping *) astZoomMap( 1, 1.0/ds, "", status ); - } - -/* The Mapping to be returned is the concatenation of the above Mapping - (from w to X) with the Mapping from X to S. */ - ret = (AstMapping *) astCmpMap( map2, map1, 1, "", status ); - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - } - } - xfrm = astAnnul( xfrm ); - -/* Return the result */ - return ret; -} - -static double *OrthVector( int n, int m, double **in, int *status ){ -/* -* Name: -* OrthVector - -* Purpose: -* Find a unit vector which is orthogonal to a set of supplied vectors. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* double *OrthVector( int n, int m, double **in, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A set of M vectors is supplied, each vector being N-dimensional. -* It is assumed that M < N and that the supplied vectors span M -* axes within the N dimensional space. An N-dimensional unit vector is -* returned which is orthogonal to all the supplied vectors. -* -* The required vector is orthogonal to all the supplied vectors. -* Therefore the dot product of the required vector with each of the -* supplied vectors must be zero. This gives us M equations of the - -* form: -* -* a1*r1 + a2*r2 + a3*r3 + .... + aN*rN = 0.0 -* b1*r1 + b2*r2 + b3*r3 + .... + bN*rN = 0.0 -* ... -* -* where (a1,a2,..,aN), (b1,b2,..,bN), ... are the supplied vectors -* and (r1,r2,...,rN) is the required vector. Since M is less -* than N the system of linear simultaneous equations is under -* specified and we need to assign arbitrary values to some of the -* components of the required vector in order to allow the equations -* to be solved. We arbitrarily assume that 1 element of the required -* vector has value 1.0 and (N-M-1) have value zero. The selection of -* *which* elements to set constant is based on the magnitudes of the -* columns of coefficients (a1,b1...), (a2,b2,...), etc. The M components -* of the required vector which are *not* set constant are the ones which -* have coefficient columns with the *largest* magnitude. This choice is -* made in order to minimise the risk of the remaining matrix of -* coefficients being singular (for instance, if a component of the -* required vector has a coefficient of zero in every supplied vector -* then the column magnitude will be zero and that component will be -* set to 1.0). After choosing the M largest columns, the largest -* remaining column is assigned a value of 1.0 in the required vector, -* and all other columns are assigned the value zero in the required - -* vector. This means that the above equations becomes: -* -* a1*r1 + a2*r2 + a3*r3 + .... + aM*rM = -aM+1 -* b1*r1 + b2*r2 + b3*r3 + .... + bM*rM = -bM+1 -* ... -* -* Where the indices are now not direct indices into the supplied and -* returned vectors, but indices into an array of indices which have -* been sorted into column magnitude order. This is now a set of MxM - -* simultaneous linear equations which we can solve using palDmat: -* -* MAT.R = V -* -* where MAT is the the matrix of columns (coefficients) on the left -* hand side of the above set of simultaneous equations, R is the -* required vector (just the components which have *not* been set -* constant), and V is a constant vector equal to the column of values -* on the right hand side in the above set of simultaneous equations. -* The palDmat function solves this equation to obtain R. - -* Parameters: -* n -* The number of dimensions -* m -* The number of supplied vectors. -* in -* A pointer to an array with "m" elements, each element being a -* pointer to an array with "n" elements. Each of these "n" element -* array holds one of the supplied vectors. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The pointer to some newly allocated memory holding the returned N -* dimensional unit vector. The memory should be freed using astFree when -* no longer needed. - -* Notes: -* - NULL is returned if an error occurs. -* - NULL is returned (without error) if the required vector cannot -* be found (.e.g becuase the supplied M vectors span less than M axes). -*/ - -/* Local Variables: */ - double *colmag; - double *d; - double *e; - double *mat; - double *mel; - double *ret; - double *rhs; - double det; - double sl; - int *colperm; - int *iw; - int done; - int i; - int ih; - int ii; - int il; - int j; - int sing; - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Return if any of the M supplied vectors are NULL. */ - for( i = 0; i < m; i++ ) { - if( !in[ i ] ) return ret; - } - -/* Allocate rquired memory. */ - ret = astMalloc( sizeof( double )*(size_t) n ); - rhs = astMalloc( sizeof( double )*(size_t) m ); - mat = astMalloc( sizeof( double )*(size_t) m*m ); - iw = astMalloc( sizeof( int )*(size_t) m ); - colmag = astMalloc( sizeof( double )*(size_t) n ); - colperm = astMalloc( sizeof( int )*(size_t) n ); - -/* Check memory can be used safely. */ - if( astOK ) { - -/* Find the magnitude of each column of coefficients in the full set of - simultaneous linear equations (before setting any components of the - required vector constant). Also initialise the column permutation array - to indicate that the columns are in their original order. The outer - loop loops through the columns and the inner loop loops through rows - (i.e. equations). */ - for( i = 0; i < n; i++ ) { - colperm[ i ] = i; - colmag[ i ] = 0.0; - for( j = 0; j < m; j++ ) { - colmag[ i ] += in[ j ][ i ]*in[ j ][ i ]; - } - } - -/* Now re-arrange the column indices within the permutation array so that - they are in order of decreasing ciolumn magnitude (i.e. colperm[0] will - be left holding the index of the column with the largest magnitude). A - simple bubble sort is used. */ - ii = 1; - done = 0; - while( !done ) { - done = 1; - for( i = ii; i < n; i++ ) { - ih = colperm[ i ]; - il = colperm[ i - 1 ]; - if( colmag[ ih ] > colmag[ il ] ) { - colperm[ i ] = il; - colperm[ i - 1 ] = ih; - done = 0; - } - } - ii++; - } - -/* The first M elements in "colperm" now hold the indices of the - columns which are to be used within the MAT matrix, the next element - of "colperm" hold the index of the column which is to be included in the - V vector (other elements hold the indices of the columns which are - being ignored because they will be mutiplied by a value of zero - the - assumed value of the corresponding components of the returned vector). We - now copy the these values into arrays which can be passed to palDmat. - First, initialise a pointer used to step through the mat array. */ - mel = mat; - -/* Loop through all the supplied vectors. Get a pointer to the first - element of the vector. */ - for( i = 0; i < m; i++ ) { - d = in[ i ]; - -/* Copy the required M elements of this supplied vector into the work array - which will be passed to palDmat. */ - for( j = 0; j < m; j++ ) *(mel++) = d[ colperm[ j ] ]; - -/* Put the next right-hand side value into the "rhs" array. */ - rhs[ i ] = -d[ colperm[ m ] ]; - } - -/* Use palDmat to find the first M elements of the returned array. These - are stored in "rhs", over-writing the original right-hand side values. */ - palDmat( m, mat, rhs, &det, &sing, iw ); - -/* If the supplied vectors span fewer than M axes, the above call will fail. - In this case, annul the returned vector. */ - if( sing != 0 ) { - ret = astFree( ret ); - -/* If succesful, copy the M elements of the solution vector into the - required M elements of the returned vector. Also find the squared length - of the vector. */ - } else { - sl = 0.0; - e = rhs; - for( j = 0; j < m; j++ ) { - sl += (*e)*(*e); - ret[ colperm[ j ] ] = *(e++); - } - -/* Put 1.0 into the next element of the returned vector. */ - sl += 1.0; - ret[ colperm[ m ] ] = 1.0; - -/* Fill up the rest of the returned vector with zeros. */ - for( j = m + 1; j < n; j++ ) ret[ colperm[ j ] ] = 0.0; - -/* Normalise the returned vector so that it is a unit vector.Also ensure - that any zeros are "+0.0" insteasd of "-0.0". */ - e = ret; - sl = sqrt( sl ); - for( j = 0; j < n; e++,j++ ) { - *e /= sl; - if( *e == 0.0 ) *e = 0.0; - } - } - } - -/* Free workspace. */ - rhs = astFree( rhs ); - mat = astFree( mat ); - iw = astFree( iw ); - colmag = astFree( colmag ); - colperm = astFree( colperm ); - -/* Free the returned vector if an error has occurred. */ - if( !astOK ) ret = astFree( ret ); - -/* Return the answer. */ - return ret; -} - -static double **OrthVectorSet( int n, int m, double **in, int *status ){ -/* -* Name: -* OrthVectorSet - -* Purpose: -* Find a set of mutually orthogonal vectors. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* double **OrthVectorSet( int n, int m, double **in, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A set of M vectors is supplied, each vector being N-dimensional. -* It is assumed that the supplied vectors span M axes within the -* N dimensional space. A pointer to a set of N vectors is returned. -* The first M returned vectors are copies of the M supplied vectors. -* The remaining returned vectors are unit vectors chosen to be -* orthogonal to all other vectors in the returned set. - -* Parameters: -* n -* The number of dimensions -* m -* The number of supplied vectors. -* in -* A pointer to an array with "m" elements, each element being a -* pointer to an array with "n" elements. Each of these "n" element -* array holds one of the supplied vectors. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The pointer to some newly allocated memory holding the returned N -* vectors. The pointer locates an array of N elements, each of which -* is a pointer to an array holding the N elements of a single vector. -* The memory (including the inner pointers) should be freed using -* astFree when no longer needed. - -* Notes: -* - NULL is returned if an error occurs. -* - NULL is returned (without error) if the required vectors cannot -* be found (e.g. becuase the supplied M vectors span less than M axes). -*/ - -/* Local Variables: */ - double **ret; - int i; - int bad; - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Allocate required memory. */ - ret = astMalloc( sizeof( double * )*(size_t) n ); - -/* Check memory can be used safely. */ - bad = 0; - if( astOK ) { - -/* Copy the supplied vectors into the returned array. */ - for( i = 0; i < m; i++ ) { - ret[ i ] = astStore( NULL, in[ i ], sizeof( double )*n ); - } - -/* For the remaining vectors, find a vector which is orthogonal to all - the vectors currently in the returned set. */ - for( ; i < n; i++ ) { - ret[ i ] = OrthVector( n, i, ret, status ); - if( !ret[ i ] ) bad = 1; - } - } - -/* Free the returned vectors if an error has occurred. */ - if( bad || !astOK ) { - for( i = 0; ret && i < n; i++ ) ret[ i ] = astFree( ret[ i ] ); - ret = astFree( ret ); - } - -/* Return the answer. */ - return ret; -} - -static AstMapping *OtherAxes( AstFitsChan *this, AstFrameSet *fs, double *dim, - int *wperm, char s, FitsStore *store, - double *crvals, int *axis_done, - const char *method, const char *class, - int *status ){ - -/* -* Name: -* OtherAxes - -* Purpose: -* Add values to a FitsStore describing unknown axes in a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* AstMapping *OtherAxes( AstFitsChan *this, AstFrameSet *fs, double *dim, -* int *wperm, char s, FitsStore *store, -* double *crvals, int *axis_done, -* const char *method, const char *class, -* int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* FITS WCS keyword values are added to the supplied FitsStore which -* describe any as yet undescribed axes in the supplied FrameSet. These -* axes are assumed to be linear and to follow the conventions -* of FITS-WCS paper I (if in fact they are not linear, then the -* grid->iwc mapping determined by MakeIntWorld will not be linear and -* so the axes will be rejected). -* -* Note, this function does not store values for keywords which define -* the transformation from pixel coords to Intermediate World Coords -* (CRPIX, PC and CDELT), but a Mapping is returned which embodies these -* values. This Mapping is from the current Frame in the FrameSet (WCS -* coords) to a Frame representing IWC. The IWC Frame has the same number -* of axes as the WCS Frame which may be greater than the number of base -* Frame (i.e. pixel) axes. - -* Parameters: -* this -* Pointer to the FitsChan. -* fs -* Pointer to the FrameSet. The base Frame should represent FITS pixel -* coordinates, and the current Frame should represent FITS WCS -* coordinates. The number of base Frame axes should not exceed the -* number of current Frame axes. -* dim -* An array holding the image dimensions in pixels. AST__BAD can be -* supplied for any unknwon dimensions. -* wperm -* Pointer to an array of integers with one element for each axis of -* the current Frame. Each element holds the zero-based -* index of the FITS-WCS axis (i.e. the value of "i" in the keyword -* names "CTYPEi", "CRVALi", etc) which describes the Frame axis. -* s -* The co-ordinate version character. A space means the primary -* axis descriptions. Otherwise the supplied character should be -* an upper case alphabetical character ('A' to 'Z'). -* store -* The FitsStore in which to store the FITS WCS keyword values. -* crvals -* Pointer to an array holding the default CRVAL value for each -* axis in the WCS Frame. -* axis_done -* An array of flags, one for each Frame axis, which indicate if a -* description of the corresponding axis has yet been stored in the -* FitsStore. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If any axis descriptions were added to the FitsStore, a Mapping from -* the current Frame of the supplied FrameSet, to the IWC Frame is returned. -* Otherwise, a UnitMap is returned. Note, the Mapping only defines the IWC -* transformation for the described axes. Any other (previously -* described) axes are passed unchanged by the returned Mapping. -*/ - -/* Local Variables: */ - AstFitsTable *table; /* Pointer to structure holding -TAB table info */ - AstFrame *wcsfrm; /* WCS Frame within FrameSet */ - AstMapping *axmap; /* Mapping from WCS to IWC */ - AstMapping *map; /* FITS pixel->WCS Mapping */ - AstMapping *ret; /* Returned Mapping */ - AstMapping *tmap0; /* Pointer to a temporary Mapping */ - AstMapping *tmap1; /* Pointer to a temporary Mapping */ - AstPermMap *pm; /* PermMap pointer */ - AstPointSet *pset1; /* PointSet holding central pixel position */ - AstPointSet *pset2; /* PointSet holding reference WCS position */ - char buf[80]; /* Text buffer */ - const char *lab; /* Pointer to axis Label */ - const char *sym; /* Pointer to axis Symbol */ - double **ptr1; /* Pointer to data for pset1 */ - double **ptr2; /* Pointer to data for pset2 */ - double *lbnd_p; /* Pointer to array of lower pixel bounds */ - double *ubnd_p; /* Pointer to array of upper pixel bounds */ - double crval; /* The value for the FITS CRVAL keyword */ - int *inperm; /* Pointer to permutation array for input axes */ - int *outperm; /* Pointer to permutation array for output axes */ - int extver; /* Table version number for -TAB headers */ - int fits_i; /* FITS WCS axis index */ - int i; /* Loop count */ - int iax; /* WCS Frame axis index */ - int icolindex; /* Index of table column holding index vector */ - int icolmain; /* Index of table column holding main coord array */ - int interp; /* Interpolation method for look-up tables */ - int log_axis; /* Is the axis logarithmically spaced? */ - int nother; /* Number of axes still to be described */ - int npix; /* Number of pixel axes */ - int nwcs; /* Number of WCS axes */ - int tab_axis; /* Can the axis be described by the -TAB algorithm? */ - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Get the number of WCS axes. */ - nwcs = astGetNaxes( fs ); - -/* Count the number of WCS axes which have not yet been described. */ - nother = 0; - for( iax = 0; iax < nwcs; iax++ ) { - if( ! axis_done[ iax ] ) nother++; - } - -/* Only proceed if there are some axes to described. */ - if( nother ) { - -/* Get a pointer to the WCS Frame. */ - wcsfrm = astGetFrame( fs, AST__CURRENT ); - -/* Get a pointer to the pixel->wcs Mapping. */ - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - -/* Store the number of pixel and WCS axes. */ - npix = astGetNin( fs ); - nwcs = astGetNout( fs ); - -/* Store the upper and lower pixel bounds. */ - lbnd_p = astMalloc( sizeof( double )*(size_t) npix ); - ubnd_p = astMalloc( sizeof( double )*(size_t) npix ); - if( astOK ) { - for( iax = 0; iax < npix; iax++ ) { - lbnd_p[ iax ] = 1.0; - ubnd_p[ iax ] = ( dim[ iax ] != AST__BAD ) ? dim[ iax ] : 500; - } - } - -/* Transform the central pixel coords into WCS coords */ - pset1 = astPointSet( 1, npix, "", status ); - ptr1 = astGetPoints( pset1 ); - pset2 = astPointSet( 1, nwcs, "", status ); - ptr2 = astGetPoints( pset2 ); - if( astOK ) { - for( iax = 0; iax < npix; iax++ ) { - ptr1[ iax ][ 0 ] = ( dim[ iax ] != AST__BAD ) ? floor( 0.5*dim[ iax ] ) : 1.0; - } - (void) astTransform( map, pset1, 1, pset2 ); - } - -/* Loop round all WCS axes, producing descriptions of any axes which have not - yet been described. */ - for( iax = 0; iax < nwcs && astOK; iax++ ) { - if( ! axis_done[ iax ] ) { - -/* Get the (one-based) FITS WCS axis index to use for this Frame axis. */ - fits_i = wperm[ iax ]; - -/* Use the supplied default CRVAL value. If bad, use the WCS value - corresponding to the central pixel found above (if this value is bad, - abort). */ - crval = crvals ? crvals[ iax ] : AST__BAD; - if( crval == AST__BAD ) crval = ptr2[ iax ][ 0 ]; - if( crval == AST__BAD ) { - break; - } else { - SetItem( &(store->crval), fits_i, 0, s, crval, status ); - } - -/* Initialise flags indicating the type of the axis. */ - log_axis = 0; - tab_axis = 0; - -/* Get the table version number to use if we end up using the -TAB - algorithm. This is the set value of the TabOK attribute (if positive). */ - extver = astGetTabOK( this ); - -/* See if the axis is linear. If so, create a ShiftMap which subtracts off - the CRVAL value. */ - - if( IsMapLinear( map, lbnd_p, ubnd_p, iax, status ) ) { - crval = -crval; - tmap0 = (AstMapping *) astShiftMap( 1, &crval, "", status ); - axmap = AddUnitMaps( tmap0, iax, nwcs, status ); - tmap0 = astAnnul( tmap0 ); - crval = -crval; - -/* If it is not linear, see if it is logarithmic. If the "log" algorithm is - appropriate (as defined in FITS-WCS paper III), the supplied Frame (s) is - related to pixel coordinate (p) by - s = Sr.EXP( a*p - b ). If this - is the case, the log of s will be linearly related to pixel coordinates. - Test this. If the test is passed a Mapping is returned from WCS to IWC. */ - } else if( (axmap = LogAxis( map, iax, nwcs, lbnd_p, ubnd_p, - crval, status ) ) ) { - log_axis = 1; - -/* If it is not linear or logarithmic, and the TabOK attribute is - non-zero, describe it using the -TAB algorithm. */ - } else if( extver > 0 ){ - -/* Get any pre-existing FitsTable from the FitsStore. This is the table - in which the tabular data will be stored (if the Mapping can be expressed - in -TAB form). */ - if( !astMapGet0A( store->tables, AST_TABEXTNAME, &table ) ) table = NULL; - -/* See if the Mapping can be expressed in -TAB form. */ - tmap0 = IsMapTab1D( map, 1.0, NULL, wcsfrm, dim, iax, fits_i, - &table, &icolmain, &icolindex, &interp, - status ); - if( tmap0 ) { - tab_axis = 1; - -/* The values stored in the table index vector are GRID coords. So we - need to ensure that IWC are equivalent to GRID coords. So set CRVAL - to zero. */ - crval = 0.0; - -/* Store TAB-specific values in the FitsStore. First the name of the - FITS binary table extension holding the coordinate info. */ - SetItemC( &(store->ps), fits_i, 0, s, AST_TABEXTNAME, status ); - -/* Next the table version number. This is the set (positive) value for the - TabOK attribute. */ - SetItem( &(store->pv), fits_i, 1, s, extver, status ); - -/* Also store the table version in the binary table header. */ - astSetFitsI( table->header, "EXTVER", extver, - "Table version number", 0 ); - -/* Next the name of the table column containing the main coords array. */ - SetItemC( &(store->ps), fits_i, 1, s, - astColumnName( table, icolmain ), status ); - -/* Next the name of the column containing the index array */ - if( icolindex >= 0 ) SetItemC( &(store->ps), fits_i, 2, s, - astColumnName( table, icolindex ), status ); - -/* The interpolation method (an AST extension to the published -TAB - algorithm, communicated through the QVi_4a keyword). */ - SetItem( &(store->pv), fits_i, 4, s, interp, status ); - -/* Also store the FitsTable itself in the FitsStore. */ - astMapPut0A( store->tables, AST_TABEXTNAME, table, NULL ); - -/* Create the WCS -> IWC Mapping (AST uses grid coords as IWC coords for - the -TAB algorithm). First, get a Mapping that combines the TAB axis - Mapping( tmap0) in parallel with one or two UnitMaps in order to put - the TAB axis at the required index. */ - tmap1 = AddUnitMaps( tmap0, iax, nwcs, status ); - -/* Now get a PermMap that permutes the WCS axes into the FITS axis order. */ - inperm = astMalloc( sizeof( double )*nwcs ); - outperm = astMalloc( sizeof( double )*nwcs ); - if( astOK ) { - for( i = 0; i < nwcs; i++ ) { - inperm[ i ] = wperm[ i ]; - outperm[ wperm[ i ] ] = i; - } - } - pm = astPermMap( nwcs, inperm, nwcs, outperm, NULL, "", - status ); - -/* Combine these two Mappings in series, to get the Mapping from WCS to - IWC. */ - axmap = (AstMapping *) astCmpMap( pm, tmap1, 1, " ", - status ); - -/* Free resources. */ - inperm = astFree( inperm ); - outperm = astFree( outperm ); - pm = astAnnul( pm ); - tmap0 = astAnnul( tmap0 ); - tmap1 = astAnnul( tmap1 ); - } - if( table ) table = astAnnul( table ); - } - -/* If the axis cannot be described by any of the above methods, we - pretend it is linear. This will generate a non-linear PIXEL->IWC - mapping later (in MakeIntWorld) which will cause the write operation - to fail. */ - if( !axmap ) { - crval = -crval; - tmap0 = (AstMapping *) astShiftMap( 1, &crval, "", status ); - axmap = AddUnitMaps( tmap0, iax, nwcs, status ); - tmap0 = astAnnul( tmap0 ); - crval = -crval; - } - -/* Combine the Mapping for this axis in series with those of earlier axes. */ - if( ret ) { - tmap0 = (AstMapping *) astCmpMap( ret, axmap, 1, "", status ); - (void) astAnnul( ret ); - ret = tmap0; - } else { - ret = astClone( axmap ); - } - -/* Get axis label and symbol. */ - sym = astGetSymbol( wcsfrm, iax ); - lab = astGetLabel( wcsfrm, iax ); - -/* The axis symbols are taken as the CTYPE values. Append "-LOG" or "-TAB" if - the axis is logarithmic or tabular. */ - if( sym && strlen( sym ) ) { - (void) sprintf( buf, "%s", sym ); - } else { - (void) sprintf( buf, "AXIS%d", iax + 1 ); - } - if( log_axis ) { - SetAlgCode( buf, "-LOG", status ); - } else if( tab_axis ) { - SetAlgCode( buf, "-TAB", status ); - } - SetItemC( &(store->ctype), fits_i, 0, s, buf, status ); - -/* The axis labels are taken as the comment for the CTYPE keywords and as - the CNAME keyword (but only if a label has been set and is different to - the symbol). */ - if( lab && lab[ 0 ] && astTestLabel( wcsfrm, iax ) && strcmp( sym, lab ) ) { - SetItemC( &(store->ctype_com), fits_i, 0, s, (char *) lab, status ); - SetItemC( &(store->cname), fits_i, 0, s, (char *) lab, status ); - } else { - sprintf( buf, "Type of co-ordinate on axis %d", iax + 1 ); - SetItemC( &(store->ctype_com), fits_i, 0, s, buf, status ); - } - -/* If a value has been set for the axis units, use it as CUNIT. */ - if( astTestUnit( wcsfrm, iax ) ){ - SetItemC( &(store->cunit), fits_i, 0, s, (char *) astGetUnit( wcsfrm, iax ), status ); - } - -/* Indicate this axis has now been described. */ - axis_done[ iax ] = 1; - -/* Release Resources. */ - axmap = astAnnul( axmap ); - } - } - -/* Release Resources. */ - wcsfrm = astAnnul( wcsfrm ); - map = astAnnul( map ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - lbnd_p = astFree( lbnd_p ); - ubnd_p = astFree( ubnd_p ); - } - -/* If we have a Mapping to return, simplify it. Otherwise, create - a UnitMap to return. */ - if( ret ) { - tmap0 = ret; - ret = astSimplify( tmap0 ); - tmap0 = astAnnul( tmap0 ); - } else { - ret = (AstMapping *) astUnitMap( nwcs, "", status ); - } - -/* Return the result. */ - return ret; -} - -static int PCFromStore( AstFitsChan *this, FitsStore *store, - const char *method, const char *class, int *status ){ - -/* -* Name: -* PCFromStore - -* Purpose: -* Store WCS keywords in a FitsChan using FITS-PC encoding. - -* Type: -* Private function. - -* Synopsis: -* int PCFromStore( AstFitsChan *this, FitsStore *store, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function copies the WCS information stored in the supplied -* FitsStore into the supplied FitsChan, using FITS-PC encoding. -* -* Zero is returned if the primary axis descriptions cannot be produced. -* Whether or not secondary axis descriptions can be produced does not -* effect the returned value (i.e. failure to produce a specific set of -* secondary axes does not prevent other axis descriptions from being -* produced). - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if succesfull, and zero is returned -* otherwise. -*/ - -/* Local Variables: */ - char *comm; /* Pointer to comment string */ - char *cval; /* Pointer to string keyword value */ - char combuf[80]; /* Buffer for FITS card comment */ - char keyname[10]; /* Buffer for keyword name string */ - char primsys[20]; /* Buffer for primnary RADECSYS value */ - char type[MXCTYPELEN];/* Buffer for CTYPE value */ - char s; /* Co-ordinate version character */ - char sign[2]; /* Fraction's sign character */ - char sup; /* Upper limit on s */ - double *c; /* Pointer to next array element */ - double *d; /* Pointer to next array element */ - double *matrix; /* Pointer to Frame PC/CD matrix */ - double *primpc; /* Pointer to primary PC/CD matrix */ - double fd; /* Fraction of a day */ - double mjd99; /* MJD at start of 1999 */ - double primdt; /* Primary mjd-obs value */ - double primeq; /* Primary equinox value */ - double primln; /* Primary lonpole value */ - double primlt; /* Primary latpole value */ - double primpv[10]; /* Primary projection parameter values */ - double val; /* General purpose value */ - int axlat; /* Index of latitude FITS WCS axis */ - int axlon; /* Index of longitude FITS WCS axis */ - int axspec; /* Index of spectral FITS WCS axis */ - int i; /* Axis index */ - int ihmsf[ 4 ]; /* Hour, minute, second, fractional second */ - int is; /* Co-ordinate version index */ - int iymdf[ 4 ]; /* Year, month, date, fractional day */ - int j; /* Axis index */ - int jj; /* SlaLib status */ - int m; /* Parameter index */ - int maxm; /* Upper limit on m */ - int naxis; /* No. of axes */ - int nc; /* Length of string */ - int ok; /* Frame written out succesfully? */ - int prj; /* Projection type */ - int ret; /* Returned value. */ - -/* Initialise */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Find the number of co-ordinate versions in the FitsStore. FITS-PC - can only encode 10 axis descriptions (including primary). */ - sup = GetMaxS( &(store->crval), status ); - if( sup > 'I' ) return ret; - -/* Initialise */ - primdt = AST__BAD; - primeq = AST__BAD; - primln = AST__BAD; - primlt = AST__BAD; - -/* Loop round all co-ordinate versions (0-9) */ - primpc = NULL; - for( s = ' '; s <= sup && astOK; s++ ){ - is = s - 'A' + 1; - -/* Assume the Frame can be created succesfully. */ - ok = 1; - -/* Save the number of wcs axes */ - val = GetItem( &(store->wcsaxes), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) { - naxis = (int) ( val + 0.5 ); - SetValue( this, FormatKey( "WCSAXES", -1, -1, s, status ), - &naxis, AST__INT, "Number of WCS axes", status ); - } else { - naxis = GetMaxJM( &(store->crpix), s, status ) + 1; - } - -/* PC matrix: - --------- */ - -/* This encoding does not allow the PC matrix to be specified for each - version - instead they all share the primary PC matrix. Therefore we - need to check that all versions can use the primary PC matrix. Allocate - memory to hold the PC matrix for this version. */ - matrix = (double *) astMalloc( sizeof(double)*naxis*naxis ); - if( matrix ){ - -/* Fill these array with the values supplied in the FitsStore. */ - c = matrix; - for( i = 0; i < naxis; i++ ){ - for( j = 0; j < naxis; j++ ){ - *c = GetItem( &(store->pc), i, j, s, NULL, method, class, status ); - if( *c == AST__BAD ) *c = ( i == j ) ? 1.0 : 0.0; - c++; - } - } - -/* If we are currently processing the primary axis description, take - a copy of the PC matrix. */ - if( s == ' ' ) { - primpc = (double *) astStore( NULL, (void *) matrix, - sizeof(double)*naxis*naxis ); - -/* Store each matrix element in turn. */ - c = matrix; - for( i = 0; i < naxis; i++ ){ - for( j = 0; j < naxis; j++ ){ - -/* Set the element bad if it takes its default value. */ - val = *(c++); - if( i == j ){ - if( astEQUAL( val, 1.0 ) ) val = AST__BAD; - } else { - if( astEQUAL( val, 0.0 ) ) val = AST__BAD; - } - -/* Only store elements which do not take their default values. */ - if( val != AST__BAD ){ - sprintf( keyname, "PC%.3d%.3d", i + 1, j + 1 ); - SetValue( this, keyname, &val, AST__FLOAT, NULL, status ); - } - } - } - -/* For secondary axis descriptions, a check is made that the PC values are - the same as the primary PC values stored earlier. If not, the current - Frame cannot be stored as a secondary axis description so continue on - to the next Frame. */ - } else { - if( primpc ){ - c = matrix; - d = primpc; - for( i = 0; i < naxis; i++ ){ - for( j = 0; j < naxis; j++ ){ - if( !astEQUAL( *c, *d ) ){ - ok = 0; - } else { - c++; - d++; - } - } - } - -/* Continue with the next Frame if the PC matrix for this Frame is different - to the primary PC matrix. */ - if( !ok ) goto next; - } - } - matrix = (double *) astFree( (void *) matrix ); - } - -/* CDELT: - ------ */ - for( i = 0; i < naxis; i++ ){ - val = GetItem( &(store->cdelt), i, 0, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - goto next; - } - sprintf( combuf, "Pixel scale on axis %d", i + 1 ); - if( s == ' ' ) { - sprintf( keyname, "CDELT%d", i + 1 ); - } else { - sprintf( keyname, "C%dELT%d", is, i + 1 ); - } - SetValue( this, keyname, &val, AST__FLOAT, combuf, status ); - } - -/* CRPIX: - ------ */ - for( j = 0; j < naxis; j++ ){ - val = GetItem( &(store->crpix), 0, j, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - goto next; - } - sprintf( combuf, "Reference pixel on axis %d", j + 1 ); - if( s == ' ' ) { - sprintf( keyname, "CRPIX%d", j + 1 ); - } else { - sprintf( keyname, "C%dPIX%d", is, j + 1 ); - } - SetValue( this, keyname, &val, AST__FLOAT, combuf, status ); - } - -/* CRVAL: - ------ */ - for( i = 0; i < naxis; i++ ){ - val = GetItem( &(store->crval), i, 0, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - goto next; - } - sprintf( combuf, "Value at ref. pixel on axis %d", i + 1 ); - if( s == ' ' ) { - sprintf( keyname, "CRVAL%d", i + 1 ); - } else { - sprintf( keyname, "C%dVAL%d", is, i + 1 ); - } - SetValue( this, keyname, &val, AST__FLOAT, combuf, status ); - } - -/* CTYPE: - ------ */ - for( i = 0; i < naxis; i++ ){ - cval = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - nc = strlen( cval ); - if( !cval || ( nc > 4 && !strcmp( cval + 4, "-TAB" ) ) ) { - ok = 0; - goto next; - } - comm = GetItemC( &(store->ctype_com), i, 0, s, NULL, method, class, status ); - if( !comm ) { - sprintf( combuf, "Type of co-ordinate on axis %d", i + 1 ); - comm = combuf; - } - if( s == ' ' ) { - sprintf( keyname, "CTYPE%d", i + 1 ); - } else { - sprintf( keyname, "C%dYPE%d", is, i + 1 ); - } - -/* FITS-PC cannot handle celestial axes of type "xxLT" or "xxLN". - Neither can it handle the "-TAB". */ - if( ( nc > 2 && !strncmp( cval + 2, "LT-", 3 ) ) || - ( nc > 2 && !strncmp( cval + 2, "LN-", 3 ) ) || - ( nc > 4 && !strncmp( cval + 4, "-TAB", 4 ) ) ){ - ok = 0; - goto next; - } - -/* Extract the projection type as specified by the last 4 characters - in the CTYPE keyword value. This will be AST__WCSBAD for non-celestial - axes. */ - prj = astWcsPrjType( cval + 4 ); - -/* Change the new SFL projection code to to the older equivalent GLS */ - if( prj == AST__SFL ) { - strcpy( type, cval ); - (void) strcpy( type + 4, "-GLS" ); - cval = type; - } - -/* FITS-PC cannot handle the AST-specific TPN projection. */ - if( prj == AST__TPN ) { - ok = 0; - goto next; - } - -/* Store the CTYPE value */ - SetValue( this, keyname, &cval, AST__STRING, comm, status ); - } - -/* Get and save CUNIT for all intermediate axes. These are NOT required, so - do not pass on if they are not available. */ - for( i = 0; i < naxis; i++ ){ - cval = GetItemC( &(store->cunit), i, 0, s, NULL, method, class, status ); - if( cval ) { - sprintf( combuf, "Units for axis %d", i + 1 ); - if( s == ' ' ) { - sprintf( keyname, "CUNIT%d", i + 1 ); - } else { - sprintf( keyname, "C%dNIT%d", is, i + 1 ); - } - SetValue( this, keyname, &cval, AST__STRING, combuf, status ); - } - } - -/* Get and save RADESYS. This is NOT required, so do not pass on if it is - not available. If RADECSYS is provided for a secondary axis, it must - be the same as the primary axis RADECSYS value. If it is not, pass on to - the next Frame. */ - cval = GetItemC( &(store->radesys), 0, 0, s, NULL, method, class, status ); - if( cval ) { - if( s == ' ' ) { - strcpy( primsys, cval ); - SetValue( this, "RADECSYS", &cval, AST__STRING, - "Reference frame for RA/DEC values", status ); - } else if( strcmp( cval, primsys ) ) { - ok = 0; - goto next; - } - } - -/* Reference equinox. This is NOT required, so do not pass on if it is - not available. If equinox is provided for a secondary axis, it must - be the same as the primary axis equinox value. If it is not, pass on to - the next Frame. */ - val = GetItem( &(store->equinox), 0, 0, s, NULL, method, class, status ); - if( s == ' ' ) { - primeq = val; - if( val != AST__BAD ) SetValue( this, "EQUINOX", &val, AST__FLOAT, - "Epoch of reference equinox", status ); - } else if( !astEQUAL( val, primeq ) ){ - ok = 0; - goto next; - } - -/* Latitude of native north pole. This is NOT required, so do not pass on - if it is not available. If latpole is provided for a secondary axis, it - must be the same as the primary axis value. If it is not, pass on to - the next Frame. */ - val = GetItem( &(store->latpole), 0, 0, s, NULL, method, class, status ); - if( s == ' ' ) { - primlt = val; - if( val != AST__BAD ) SetValue( this, "LATPOLE", &val, AST__FLOAT, - "Latitude of native north pole", status ); - } else if( !EQUALANG( val, primlt ) ){ - ok = 0; - goto next; - } - -/* Longitude of native north pole. This is NOT required, so do not pass on - if it is not available. If lonpole is provided for a secondary axis, it - must be the same as the primary axis value. If it is not, pass on to - the next Frame. */ - val = GetItem( &(store->lonpole), 0, 0, s, NULL, method, class, status ); - if( s == ' ' ) { - primln = val; - if( val != AST__BAD ) SetValue( this, "LONGPOLE", &val, AST__FLOAT, - "Longitude of native north pole", status ); - } else if( !EQUALANG( val, primln ) ){ - ok = 0; - goto next; - } - -/* Date of observation. This is NOT required, so do not pass on if it is - not available. If mjd-obs is provided for a secondary axis, it must be - the same as the primary axis value. If it is not, pass on to the next - Frame. */ - val = GetItem( &(store->mjdobs), 0, 0, s, NULL, method, class, status ); - if( s == ' ' ) { - primdt = val; - if( val != AST__BAD ) { - SetValue( this, "MJD-OBS", &val, AST__FLOAT, - "Modified Julian Date of observation", status ); - -/* The format used for the DATE-OBS keyword depends on the value of the - keyword. For DATE-OBS < 1999.0, use the old "dd/mm/yy" format. - Otherwise, use the new "ccyy-mm-ddThh:mm:ss[.ssss]" format. */ - palCaldj( 99, 1, 1, &mjd99, &jj ); - if( val < mjd99 ) { - palDjcal( 0, val, iymdf, &jj ); - sprintf( combuf, "%2.2d/%2.2d/%2.2d", iymdf[ 2 ], iymdf[ 1 ], - iymdf[ 0 ] - ( ( iymdf[ 0 ] > 1999 ) ? 2000 : 1900 ) ); - } else { - palDjcl( val, iymdf, iymdf+1, iymdf+2, &fd, &jj ); - palDd2tf( 3, fd, sign, ihmsf ); - sprintf( combuf, "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d.%3.3d", - iymdf[0], iymdf[1], iymdf[2], ihmsf[0], ihmsf[1], - ihmsf[2], ihmsf[3] ); - } - -/* Now store the formatted string in the FitsChan. */ - cval = combuf; - SetValue( this, "DATE-OBS", &cval, AST__STRING, - "Date of observation", status ); - } - } else if( !astEQUAL( val, primdt ) ){ - ok = 0; - goto next; - } - -/* Look for the celestial and spectral axes. */ - FindLonLatSpecAxes( store, s, &axlon, &axlat, &axspec, method, class, status ); - -/* If both longitude and latitude axes are present ...*/ - if( axlon >= 0 && axlat >= 0 ) { - -/* Get the CTYPE values for the latitude axis. */ - cval = GetItemC( &(store->ctype), axlat, 0, s, NULL, method, class, status ); - -/* Extract the projection type as specified by the last 4 characters - in the CTYPE keyword value. */ - prj = ( cval ) ? astWcsPrjType( cval + 4 ) : AST__WCSBAD; - -/* Projection parameters. If provided for a secondary axis, they must be - the same as the primary axis value. If it is not, pass on to the next - Frame. PC encoding ignores parameters associated with the longitude - axis. The old PC TAN projection did not have any parameters. - Pass on if a TAN projection with parameters is found. The number of - parameters was limited to 10. Pass on if more than 10 are supplied. */ - maxm = GetMaxJM( &(store->pv), ' ', status ); - for( i = 0; i < naxis; i++ ){ - if( i != axlon ) { - for( m = 0; m <= maxm; m++ ){ - val = GetItem( &(store->pv), i, m, s, NULL, method, class, status ); - if( s == ' ' ){ - if( val != AST__BAD ) { - if( i != axlat || prj == AST__TAN || m >= 10 ){ - ok = 0; - goto next; - } else { - SetValue( this, FormatKey( "PROJP", m, -1, ' ', status ), &val, - AST__FLOAT, "Projection parameter", status ); - } - } - if( i == axlat && m < 10 ) primpv[m] = val; - } else { - if( ( ( i != axlat || m >= 10 ) && val != AST__BAD ) || - ( i == axlat && m < 10 && !astEQUAL( val, primpv[m] ) ) ){ - ok = 0; - goto next; - } - } - } - } - } - } - -/* See if a Frame was sucessfully written to the FitsChan. */ -next: - ok = ok && astOK; - -/* If so, indicate we have something to return. */ - if( ok ) ret = 1; - -/* Clear any error status so we can continue to produce the next Frame. - Retain the error if the primary axes could not be produced. After the - primary axes, do the A axes. */ - if( s != ' ' ) { - astClearStatus; - } else { - s = 'A' - 1; - } - -/* Remove the secondary "new" flags from the FitsChan. This flag is - associated with cards which have been added to the FitsChan during - this pass through the main loop in this function. If the Frame was - written out succesfully, just clear the flags. If anything went wrong - with this Frame, remove the flagged cards from the FitsChan. */ - FixNew( this, NEW2, !ok, method, class, status ); - -/* Set the current card so that it points to the last WCS-related keyword - in the FitsChan (whether previously read or not). */ - FindWcs( this, 1, 1, 0, method, class, status ); - } - -/* Annul the array holding the primary PC matrix. */ - primpc = (double *) astFree( (void *) primpc ); - -/* Return zero or ret depending on whether an error has occurred. */ - return astOK ? ret : 0; -} - -static void PreQuote( const char *value, - char string[ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN - 3 ], int *status ) { - -/* -* Name: -* PreQuote - -* Purpose: -* Pre-quote FITS character data. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void PreQuote( const char *value, -* char string[ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN - 3 ] ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function processes a string value in such a way that it can -* be stored as a FITS character value (associated with a keyword) -* and later retrieved unchanged, except for possible truncation. -* -* This pre-processing is necessary because FITS does not regard -* trailing white space as significant, so it is lost. This -* function adds double quote (") characters around the string if -* it is necessary in order to prevent this loss. These quotes are -* also added to zero-length strings and to strings that are -* already quoted (so that the original quotes are not lost when -* they are later un-quoted). -* -* This function will silently truncate any string that is too long -* to be stored as a FITS character value, but will ensure that the -* maximum number of characters are retained, taking account of any -* quoting required. - -* Parameters: -* value -* Pointer to a constant null-terminated string containing the -* input character data to be quoted. All white space is -* significant. -* string -* A character array into which the result string will be -* written, with a terminating null. The maximum number of -* characters from the input string that can be accommodated in -* this is (AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN - 4), but this -* will be reduced if quoting is necessary. - -* Notes: -* - The UnPreQuote function should be used to reverse the effect -* of this function on a string (apart from any truncation). -*/ - -/* Local Variables: */ - int dq; /* Number of double quotes needed */ - int dquotes; /* Final number of double quotes */ - int i; /* Loop counter for input characters */ - int j; /* Counter for output characters */ - int nc; /* Number of characters to be accommodated */ - int sq; /* Number of single quotes needed */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise, setting the default number of double quotes (which - applies to a zero-length string) to 2. */ - dquotes = 2; - nc = 0; - sq = 0; - -/* Loop to consider each input character to see if it will fit into - the result string. */ - for ( i = 0; value[ i ]; i++ ) { - -/* If a single quote character is to be included, count it. When the - string is encoded as FITS character data, these quotes will be - doubled, so will increase the overall string length by one. */ - if ( value[ i ] == '\'' ) sq++; - -/* See how many double quotes are needed around the string (0 or - 2). These are needed if there is trailing white space that needs - protecting (this is not significant in FITS and will be removed), - or if the string already has quotes at either end (in which case an - extra set is needed to prevent the original ones being removed when - it is later un-quoted). Note we do not need to double existing - double quote characters within the string, because the position of - the ends of the string are known (from the quoting supplied by - FITS) so only the first and last characters need be inspected when - un-quoting the string. - In assessing the number of double quotes, assume the string will be - truncated after the current character. */ - dq = ( isspace( value[ i ] ) || - ( ( value[ 0 ] == '"' ) && ( value[ i ] == '"' ) ) ) ? 2 : 0; - -/* See if the length of the resulting string, including the current - character and all necessary quotes, is too long. If so, give up - here. */ - if ( ( nc + 1 + dq + sq ) > - ( AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN - 4 ) ) break; - -/* If the string is not too long, accept the character and note the - number of double quotes needed. */ - nc = i + 1; - dquotes = dq; - } - -/* If double quotes are needed, insert the opening quote into the - output string. */ - j = 0; - if ( dquotes ) string[ j++ ] = '"'; - -/* Follow this with the maximum number of input string characters that - can be accommodated. */ - for ( i = 0; i < nc; i++ ) string[ j++ ] = value[ i ]; - -/* Append the closing quote if necessary and terminate the output - string. */ - if ( dquotes ) string[ j++ ] = '"'; - string[ j ] = '\0'; -} - -static void PurgeWCS( AstFitsChan *this, int *status ){ - -/* -*++ -* Name: -c astPurgeWCS -f AST_PURGEWCS - -* Purpose: -* Delete all cards in the FitsChan describing WCS information. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" -c void astPurgeWCS( AstFitsChan *this ) -f CALL AST_PURGEWCS( THIS, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* deletes all cards in a FitsChan that relate to any of the recognised -* WCS encodings. On exit, the current card is the first remaining card -* in the FitsChan. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -f STATUS = INTEGER (Given and Returned) -f The global status. -*-- -*/ - -/* Local Variables: */ - AstObject *obj; - int oldclean; - -/* Check the global status. */ - if( !astOK ) return; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Ensure the Clean attribute is set so that WCS keywords are removed - even if an error occurs. */ - if( astTestClean( this ) ) { - oldclean = astGetClean( this ); - astSetClean( this, 1 ); - } else { - astSetClean( this, 1 ); - oldclean = -1; - } - -/* Loop round attempting to read AST objects form the FitsChan. This will - flag cards as used that are involved in the creation of these object - (including NATIVE encodings). Ignore any error that ocurs whilst doing - this. */ - astClearCard( this ); - if( astOK ) { - int oldreporting = astReporting( 0 ); - obj = astRead( this ); - while( obj ) { - obj = astAnnul( obj ); - astClearCard( this ); - obj = astRead( this ); - } - if( !astOK ) astClearStatus; - astReporting( oldreporting ); - } - -/* We now loop round to remove any spurious WCS-related cards left in the - FitsChan that did not form part of a complete WCS encoding. Find the - first WCS-related card left in the FitsChan. */ - FindWcs( this, 0, 0, 1, "DeleteWcs", "FitsChan", status ); - -/* Loop round marking each WCS-related card as used until none are left */ - while( this->card && astOK ) { - -/* Mark the current card as having been read. */ - ( (FitsCard*) this->card )->flags = USED; - -/* Find the next WCS-related card. */ - FindWcs( this, 0, 0, 0, "DeleteWcs", "FitsChan", status ); - } - -/* Rewind the FitsChan. */ - astClearCard( this ); - -/* Reset the Clean attribute. */ - if( oldclean == -1 ) { - astClearClean( this ); - } else { - astSetClean( this, oldclean ); - } - -} - -static void PutCards( AstFitsChan *this, const char *cards, int *status ) { - -/* -*++ -* Name: -c astPutCards -f AST_PUTCARDS - -* Purpose: -* Store a set of FITS header cards in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c void astPutCards( AstFitsChan *this, const char *cards ) -f CALL AST_PUTCARDS( THIS, CARDS, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* stores a set of FITS header cards in a FitsChan. The cards are -* supplied concatenated together into a single character string. -* Any existing cards in the FitsChan are removed before the new cards -* are added. The FitsChan is "re-wound" on exit by clearing its Card -* attribute. This means that a subsequent invocation of -c astRead -f AST_READ -* can be made immediately without the need to re-wind the FitsChan -* first. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c cards -f CARDS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string -f A character string -* containing the FITS cards to be stored. Each individual card -* should occupy 80 characters in this string, and there should be -* no delimiters, new lines, etc, between adjacent cards. The final -* card may be less than 80 characters long. -c This is the format produced by the fits_hdr2str function in the -c CFITSIO library. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - An error will result if the supplied string contains any cards -* which cannot be interpreted. -*-- -*/ - -/* Local Variables: */ - const char *a; /* Pointer to start of next card */ - int clen; /* Length of supplied string */ - int i; /* Card index */ - int ncard; /* No. of cards supplied */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Empty the FitsChan. */ - astEmptyFits( this ); - -/* Loop round the supplied string in 80 character segments, inserting - each segment into the FitsChan as a header card. Allow the last card - to be less than 80 characters long. */ - clen = strlen( cards ); - ncard = clen/80; - if( ncard*80 < clen ) ncard++; - a = cards; - for( i = 0; i < ncard; i++, a += 80 ) astPutFits( this, a, 1 ); - -/* Rewind the FitsChan. */ - astClearCard( this ); -} - -static void PutFits( AstFitsChan *this, const char card[ AST__FITSCHAN_FITSCARDLEN + 1 ], - int overwrite, int *status ){ - -/* -*++ -* Name: -c astPutFits -f AST_PUTFITS - -* Purpose: -* Store a FITS header card in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c void astPutFits( AstFitsChan *this, const char card[ 80 ], -c int overwrite ) -f CALL AST_PUTFITS( THIS, CARD, OVERWRITE, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function stores a FITS header card in a FitsChan. The card -f This routine stores a FITS header card in a FitsChan. The card -* is either inserted before the current card (identified by the -* Card attribute), or over-writes the current card, as required. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c card -f CARD = CHARACTER * ( 80 ) (Given) -c Pointer to a possibly null-terminated character string -c containing the FITS card to be stored. No more than 80 -c characters will be used from this string (or fewer if a null -c occurs earlier). -f A character string string containing the FITS card to be -f stored. No more than 80 characters will be used from this -f string. -c overwrite -f OVERWRITE = LOGICAL (Given) -c If this value is zero, the new card is inserted in front of -f If this value is .FALSE., the new card is inserted in front of -* the current card in the FitsChan (as identified by the -c initial value of the Card attribute). If it is non-zero, the -f initial value of the Card attribute). If it is .TRUE., the -* new card replaces the current card. In either case, the Card -* attribute is then incremented by one so that it subsequently -* identifies the card following the one stored. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the Card attribute initially points at the "end-of-file" -* (i.e. exceeds the number of cards in the FitsChan), then the new -* card is appended as the last card in the FitsChan. -* - An error will result if the supplied string cannot be interpreted -* as a FITS header card. -*-- -*/ - -/* Local Variables: */ - char *comment; /* The keyword comment */ - char *name; /* The keyword name */ - char *value; /* The keyword value */ - const char *class; /* Object class */ - const char *method; /* Current method */ - double cfval[2]; /* Complex floating point keyword value */ - double fval; /* floating point keyword value */ - int cival[2]; /* Complex integer keyword value */ - int ival; /* Integer keyword value */ - int len; /* No. of characters to read from the value string */ - int nc; /* No. of characters read from value string */ - int type; /* Keyword data type */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astPutFits"; - class = astGetClass( this ); - -/* Split the supplied card up into name, value and commment strings, and - get pointers to local copies of them. The data type associated with the - keyword is returned. */ - type = Split( this, card, &name, &value, &comment, method, class, status ); - -/* Check that the pointers can be used. */ - if( astOK ){ - -/* Initialise the number of characters read from the value string. */ - nc = 0; - -/* Store the number of characters in the value string. */ - len = strlen( value ); - -/* Read and store floating point values from the value string. NB, this - list is roughly in the order of descreasing frequency of use (i.e. - most FITS keywords are simple floating point values, the next most - common are strings, etc). */ - if( type == AST__FLOAT ){ - if( 1 == astSscanf( value, " %lf %n", &fval, &nc ) && nc >= len ){ - astSetFitsF( this, name, fval, comment, overwrite ); - } else { - astError( AST__BDFTS, "%s(%s): Unable to read a floating point " - "FITS keyword value.", status, method, class ); - } - -/* Read and store string values from the value string. */ - } else if( type == AST__STRING ){ - astSetFitsS( this, name, value, comment, overwrite ); - -/* Read and store string values from the value string. */ - } else if( type == AST__CONTINUE ){ - astSetFitsCN( this, name, value, comment, overwrite ); - -/* Store comment card. */ - } else if( type == AST__COMMENT ){ - astSetFitsCom( this, name, comment, overwrite ); - -/* Read and store integer values from the value string. */ - } else if( type == AST__INT ){ - if( 1 == astSscanf( value, " %d %n", &ival, &nc ) && nc >= len ){ - astSetFitsI( this, name, ival, comment, overwrite ); - } else { - astError( AST__BDFTS, "%s(%s): Unable to read an integer FITS " - "keyword value.", status, method, class ); - } - -/* Read and store logical values from the value string. */ - } else if( type == AST__LOGICAL ){ - astSetFitsL( this, name, (*value == 'T'), comment, overwrite ); - -/* Read and store undefined values from the value string. */ - } else if( type == AST__UNDEF ){ - astSetFitsU( this, name, comment, overwrite ); - -/* Read and store complex floating point values from the value string. */ - } else if( type == AST__COMPLEXF ){ - if( 2 == astSscanf( value, " %lf %lf %n", cfval, cfval + 1, &nc ) && - nc >= len ){ - astSetFitsCF( this, name, cfval, comment, overwrite ); - } else { - astError( AST__BDFTS, "%s(%s): Unable to read a complex pair " - "of floating point FITS keyword values.", status, method, class ); - } - -/* Read and store complex integer values from the value string. */ - } else if( type == AST__COMPLEXI ){ - if( 2 == astSscanf( value, " %d %d %n", cival, cival + 1, &nc ) && - nc >= len ){ - astSetFitsCI( this, name, cival, comment, overwrite ); - } else { - astError( AST__BDFTS, "%s(%s): Unable to read a complex pair " - "of integer FITS keyword values.", status, method, class ); - } - -/* Report an error for any other type. */ - } else { - astError( AST__INTER, "%s: AST internal programming error - " - "FITS data-type '%d' not yet supported.", status, method, type ); - } - -/* Give a context message if an error occurred. */ - if( !astOK ){ - astError( astStatus, "%s(%s): Unable to store the following FITS " - "header card:\n%s\n", status, method, class, card ); - } - } - -/* Free the memory used to hold the keyword name, comment and value - strings. */ - (void) astFree( (void *) name ); - (void) astFree( (void *) comment ); - (void) astFree( (void *) value ); -} - -static void PutTable( AstFitsChan *this, AstFitsTable *table, - const char *extnam, int *status ) { - -/* -*++ -* Name: -c astPutTable -f AST_PUTTABLE - -* Purpose: -* Store a single FitsTable in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c void astPutTable( AstFitsChan *this, AstFitsTable *table, -c const char *extnam ) -f CALL AST_PUTTABLE( THIS, TABLE, EXTNAM, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* allows a representation of a single FITS binary table to be -* stored in a FitsChan. For instance, this may provide the coordinate -* look-up tables needed subequently when reading FITS-WCS headers -* for axes described using the "-TAB" algorithm. Since, in general, -* the calling application may not know which tables will be needed - -* if any - prior to calling -c astRead, the astTablesSource function -f AST_READ, the AST_TABLESOURCE routine -* provides an alternative mechanism in which a caller-supplied -* function is invoked to store a named table in the FitsChan. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c table -f TABLE = INTEGER (Given) -* Pointer to a FitsTable to be added to the FitsChan. If a FitsTable -* with the associated extension name already exists in the FitsChan, -* it is replaced with the new one. A deep copy of the FitsTable is -* stored in the FitsChan, so any subsequent changes made to the -* FitsTable will have no effect on the behaviour of the FitsChan. -c extnam -f EXTNAM = CHARACTER * ( * ) (Given) -* The name of the FITS extension associated with the table. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Tables stored in the FitsChan may be retrieved using -c astGetTables. -f AST_GETTABLES. -c - The astPutTables method can add multiple FitsTables in a single call. -f - The AST_PUTTABLES method can add multiple FitsTables in a single call. -*-- -*/ - -/* Local Variables: */ - AstObject *ft; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Create a KeyMap to hold the tables within the FitsChan, if this has not - already been done. */ - if( !this->tables ) this->tables = astKeyMap( " ", status ); - -/* Store a copy of the FitsTable in the FitsChan. */ - ft = astCopy( table ); - astMapPut0A( this->tables, extnam, ft, NULL ); - ft = astAnnul( ft ); -} - -static void PutTables( AstFitsChan *this, AstKeyMap *tables, int *status ) { - -/* -*++ -* Name: -c astPutTables -f AST_PUTTABLES - -* Purpose: -* Store one or more FitsTables in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c void astPutTables( AstFitsChan *this, AstKeyMap *tables ) -f CALL AST_PUTTABLES( THIS, TABLES, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* allows representations of one or more FITS binary tables to be -* stored in a FitsChan. For instance, these may provide the coordinate -* look-up tables needed subequently when reading FITS-WCS headers -* for axes described using the "-TAB" algorithm. Since, in general, -* the calling application may not know which tables will be needed - -* if any - prior to calling -c astRead, the astTablesSource function -f AST_READ, the AST_TABLESOURCE routine -* provides an alternative mechanism in which a caller-supplied -* function is invoked to store a named table in the FitsChan. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c tables -f TABLES = INTEGER (Given) -* Pointer to a KeyMap holding the tables that are to be added -* to the FitsChan. Each entry should hold a scalar value which is a -* pointer to a FitsTable to be added to the FitsChan. Any unusable -* entries are ignored. The key associated with each entry should be -* the name of the FITS binary extension from which the table was -* read. If a FitsTable with the associated key already exists in the -* FitsChan, it is replaced with the new one. A deep copy of each -* usable FitsTable is stored in the FitsChan, so any subsequent -* changes made to the FitsTables will have no effect on the -* behaviour of the FitsChan. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Tables stored in the FitsChan may be retrieved using -c astGetTables. -f AST_GETTABLES. -* - The tables in the supplied KeyMap are added to any tables already -* in the FitsChan. -c - The astPutTable -f - The AST_PUTTABLE -* method provides a simpler means of adding a single table to a FitsChan. -*-- -*/ - -/* Local Variables: */ - AstObject *obj; - const char *key; - int ientry; - int nentry; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Loop through all entries in the supplied KeyMap. */ - nentry = astMapSize( tables ); - for( ientry = 0; ientry < nentry; ientry++ ) { - key = astMapKey( tables, ientry ); - -/* Ignore entries that do not contain AST Object pointers, or are not - scalar. */ - if( astMapType( tables, key ) == AST__OBJECTTYPE && - astMapLength( tables, key ) == 1 ) { - -/* Get the pointer, amd ignore it if it is not a FitsTable. */ - astMapGet0A( tables, key, &obj ); - if( astIsAFitsTable( obj ) ) { - -/* Store it in the FitsChan. */ - astPutTable( this, (AstFitsTable *) obj, key ); - } - -/* Annul the Object pointer. */ - obj = astAnnul( obj ); - } - } -} - -static AstObject *Read( AstChannel *this_channel, int *status ) { -/* -* Name: -* Read - -* Purpose: -* Read an Object from a Channel. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstObject *Read( AstChannel *this_channel, int *status ) - -* Class Membership: -* FitsChan member function (over-rides the astRead method -* inherited from the Channel class). - -* Description: -* This function reads an Object from a FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new Object. This will always be a FrameSet. - -* Notes: -* - The pixel Frame is given a title of "Pixel Coordinates", and -* each axis in the pixel Frame is given a label of the form "Pixel -* axis ", where is the axis index (starting at one). -* - The FITS CTYPE keyword values are used to set the labels for any -* non-celestial axes in the physical coordinate Frames, and the FITS -* CUNIT keywords are used to set the corresponding units strings. -* - On exit, the pixel Frame is the base Frame, and the physical -* Frame derived from the primary axis descriptions is the current Frame. -* - Extra Frames are added to hold any secondary axis descriptions. All -* axes within such a Frame refer to the same coordinate version ('A', -* 'B', etc). -* - For foreign encodings, the first card in the FitsChan must be -* the current card on entry (otherwise a NULL pointer is returned), -* and the FitsChan is left at end-of-file on exit. -* - For the Native encoding, reading commences from the current card -* on entry (which need not be the first in the FitsChan), and the -* current Card on exit is the first card following the last one read -* (or end-of-file). -*/ - -/* Local Variables: */ - AstObject *new; /* Pointer to returned Object */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - FitsStore *store; /* Intermediate storage for WCS information */ - const char *method; /* Pointer to string holding calling method */ - const char *class; /* Pointer to string holding object class */ - int encoding; /* The encoding scheme */ - int remove; /* Remove used cards? */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Store the calling method, and object class. */ - method = "astRead"; - class = astGetClass( this ); - -/* Get the encoding scheme used by the FitsChan. */ - encoding = astGetEncoding( this ); - -/* If we are reading from a FitsChan in which AST objects are encoded using - native AST-specific keywords, use the Read method inherited from the - Channel class. */ - if( encoding == NATIVE_ENCODING ){ - new = (*parent_read)( this_channel, status ); - -/* Indicate that used cards should be removed from the FitsChan. */ - remove = 1; - -/* If we are reading from a FitsChan in which AST objects are encoded using - any of the other supported encodings, the header may only contain a - single FrameSet. */ - } else { - remove = 0; - -/* Only proceed if the FitsChan is at start-of-file. */ - if( !astTestCard( this ) && astOK ){ - -/* Extract the required information from the FITS header into a standard - intermediary structure called a FitsStore. */ - store = FitsToStore( this, encoding, method, class, status ); - -/* Now create a FrameSet from this FitsStore. */ - new = FsetFromStore( this, store, method, class, status ); - -/* Release the resources used by the FitsStore. */ - store = FreeStore( store, status ); - -/* Indicate that used cards should be retained in the FitsChan. */ - remove = 0; - -/* If no object is being returned, rewind the fitschan in order to - re-instate the original current Card. */ - if( !new ) { - astClearCard( this ); - -/* Otherwise, ensure the current card is at "end-of-file". */ - } else { - astSetCard( this, INT_MAX ); - } - } - } - -/* If an error occurred, clean up by deleting the new Object and - return a NULL pointer. */ - if ( !astOK ) new = astDelete( new ); - -/* If no object is being returned, clear the "provisionally used" flags - associated with cards which were read. We do not do this if the user - wants to clean WCS cards from the FitsChan even if an error occurs. */ - if( !new && !astGetClean( this ) ) { - FixUsed( this, 0, 0, 0, method, class, status ); - -/* Otherwise, indicate that all the "provisionally used" cards have been - "definitely used". If native encoding was used, these cards are - totally removed from the FitsChan. */ - } else { - FixUsed( this, 0, 1, remove, method, class, status ); - } - -/* Return the pointer to the new Object. */ - return new; -} - -static double *ReadCrval( AstFitsChan *this, AstFrame *wcsfrm, char s, - const char *method, const char *class, int *status ){ - -/* -* Name: -* ReadCrval - -* Purpose: -* Obtain the reference point from the supplied FitsChan in the -* supplied WCS Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* double *ReadCrval( AstFitsChan *this, AstFrame *wcsfrm, char s, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The original reference point in the "s" coordinate description is read -* from the CRVAL keywords in the supplied FitsChan, and the original -* FrameSet is re-read from the FitsChan. If possible, the reference -* position is then converted from the "s" coordinate description to the -* supplied WCS Frame, and a pointer to an array holding the axis -* values for the transformed reference point is returned. - -* Parameters: -* this -* The FitsChan. -* wcsfrm -* The WCS Frame in the FitsChan being written to. -* s -* The co-ordinate version character. A space means the primary -* axis descriptions. Otherwise the supplied character should be -* an upper case alphabetical character ('A' to 'Z'). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array holding the reference -* point in the supplied WCS Frame. NULL is returned if is is not -* possible to determine the reference point for any reason (for -* instance, if the FitsChan does not contain values for the CRVAL -* keywords). -*/ - -/* Local Variables: */ - AstFitsChan *fc; /* A copy of the supplied FitsChan */ - AstFrame *tfrm; /* Temporary Frame pointer */ - AstFrameSet *fs; /* The FITS FrameSet */ - AstFrameSet *tfs; /* FrameSet connecting FITS and supplied WCS Frame */ - const char *id; /* Pointer to Object "Id" string */ - char buf[ 11 ]; /* FITS keyword template buffer */ - double *crval; /* CRVAL keyword values in supplied FitsChan */ - double *ret; /* Returned array */ - int hii; /* Highest found FITS axis index */ - int iax; /* Axis index (zero based) */ - int ifr; /* Frames index */ - int loi; /* Lowest found FITS axis index */ - int nax; /* Axis count */ - int nfr; /* No. of Frames in FITS FrameSet */ - int ok; /* Were CRVAL values found? */ - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* We want to re-create the original FrameSet represented by the original - contents of the supplied FitsChan. Some of the contents of the - FitsChan will already have been marked as "having been read" and so - will be ignored if we attempt to read a FrameSet directly from the - supplied FitsChan. Therefore we take a deep copy of the supplied - FitsChan and clear all the "previusly read" flags in the copy. */ - fc = astCopy( this ); - astClearEncoding( fc ); - FixUsed( fc, 1, 0, 0, method, class, status ); - -/* Copy the CRVAL values for the "s" axis descriptions into a dynamically - allocated array ("crval"). */ - if( s == ' ' ) { - strcpy( buf, "CRVAL%d" ); - } else { - sprintf( buf, "CRVAL%%d%c", s ); - } - if( astKeyFields( fc, buf, 1, &hii, &loi ) > 0 ) { - crval = astMalloc( sizeof( double )*(size_t) hii ); - ok = 1; - for( iax = 0; iax < hii; iax++ ){ - ok = ok && GetValue( fc, FormatKey( "CRVAL", iax + 1, -1, s, status ), - AST__FLOAT, (void *) (crval + iax), 0, 0, method, - class, status ); - } - } else { - crval = NULL; - ok = 0; - } - -/* If the CRVAL values were obtained succesfully, attempt to read a FrameSet - from the FitsChan copy. Do it in a new error report context so that we - can annull any error when the FrameSet is read. */ - if( ok ) { - int oldreporting = astReporting( 0 ); - astClearCard( fc ); - fs = astRead( fc ); - if( fs ) { - -/* We want to find a conversion from the Frame in this FrameSet which - represents the FITS-WCS "s" coordinate descriptions and the supplied WCS - Frame. So first find the Frame which has its Ident attribute set to - "s" and make it the current Frame. */ - nfr = astGetNframe( fs ); - for( ifr = 1; ifr <= nfr; ifr++ ) { - astSetCurrent( fs, ifr ); - tfrm = astGetFrame( fs, ifr ); - id = astTestIdent( tfrm ) ? astGetIdent( tfrm ) : NULL; - tfrm = astAnnul( tfrm ); - if( id && strlen( id ) == 1 && id[ 0 ] == s ) break; - } - -/* Check a Frame was found, and that we have CRVAL values for all axes in - the Frame. */ - if( ifr <= nfr && astGetNaxes( fs ) == hii ) { - -/* Attempt to find a conversion route from the Frame found above to the - supplied WCS Frame. */ - tfs = astConvert( fs, wcsfrm, astGetDomain( wcsfrm ) ); - if( tfs ) { - -/* Allocate memory to hold the returned reference point. */ - nax = astGetNaxes( wcsfrm ); - ret = astMalloc( sizeof( double )*(size_t) nax ); - -/* Transform the original reference position from the "s" Frame to the - supplied WCS Frame using the Mapping returned by astConvert. */ - astTranN( tfs, 1, hii, 1, crval, 1, nax, 1, ret ); - -/* Free resources. */ - tfs = astAnnul( tfs ); - } - } - -/* Free resources. */ - fs = astAnnul( fs ); - -/* Annul any error that occurred reading the FitsChan. */ - } else if( !astOK ) { - astClearStatus; - } - -/* Re-instate error reporting. */ - astReporting( oldreporting ); - } - -/* Free resources. */ - if( crval ) crval = astFree( crval ); - fc = astAnnul( fc ); - -/* If an error occurred, free the returned array. */ - if( !astOK ) ret = astFree( ret ); - -/* Return the result. */ - return ret; -} - -static void ReadFits( AstFitsChan *this, int *status ){ - -/* -*++ -* Name: -c astReadFits -f AST_READFITS - -* Purpose: -* Read cards into a FitsChan from the source function. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" -c void astReadFits( AstFitsChan *this ) -f CALL AST_READFITS( THIS, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* reads cards from the source function that was specified when the -* FitsChan was created, and stores them in the FitsChan. This -* normally happens once-only, when the FitsChan is accessed for the -* first time. -c This function -f This routine -* provides a means of forcing a re-read of the external source, and -* may be useful if (say) new cards have been deposited into the -* external source. Any newcards read from the source are appended to -* the end of the current contents of the FitsChan. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - This function returns without action if no source function was -* specified when the FitsChan was created. -* - The SourceFile attribute is ignored by this -c function. -f routine. -* New cards are read from the source file whenever a new value is -* assigned to the SourceFile attribute. - -*-- -*/ - -/* Check the inherited status */ - if( !astOK ) return; - -/* If no source function is available, re-instate any saved source - function pointer. */ - if( !this->source ) { - this->source = this->saved_source; - this->saved_source = NULL; - } - -/* Call the source function. */ - ReadFromSource( this, status ); -} - -static void ReadFromSource( AstFitsChan *this, int *status ){ - -/* -* Name: -* ReadFromSource - -* Purpose: -* Fill the FitsChan by reading cards from the source function. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void ReadFromSource( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The source function specified when the FitsChan was created is -* called repeatedly until it returns a NULL pointer. The string -* returned by each such call is assumed to be a FITS header card, -* and is stored in the FitsChan using astPutFits. -* -* If no source function was provided, the FitsChan is left as supplied. -* This is different to a standard Channel, which tries to read data -* from standard input if no source function is provided. -* -* This function should be called at the start of most public or protected -* FitsChan functions, and most private functions that are used to override -* methods inherited form the Channel class. Previously, this function -* was called only once, from the FitsChan initialiser (astInitFitschan). -* However, calling it from astInitFitsChan means that application code -* cannot use the astPutChannelData function with a FitsChan, since the -* source function would already have been called by the time the -* FitsChan constructor returned (and thus before astPutChannelData -* could have been called). In order to ensure that the source -* function is called only once, this function now nullifies the source -* function pointer after its first use. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The new cards are appended to the end of the FitsChan. -* - The first of the new cards is made the current card on exit. If no -* source function is supplied, the current card is left unchanged. -*/ - -/* Local Variables: */ - const char *(* source)( void ); /* Pointer to source function */ - const char *card; /* Pointer to externally-read header card */ - int icard; /* Current card index on entry */ - -/* Check the global status. */ - if( !astOK || !this ) return; - -/* Only proceed if source function and wrapper were supplied when the FitsChan - was created and are still available. */ - if( this->source && this->source_wrap ){ - -/* Save the source function pointer and then nullify the pointer in the - FitsChan structure. This avoids infinte loops. */ - source = this->source; - this->source = NULL; - -/* Save the source fubnction pointer in the FitsChan so that it can be - re-instated if required (e.g. by astReadFits). */ - this->saved_source = source; - -/* Ensure the FitsChan is at end-of-file. This will result in the - new cards being appended to the end of the FitsChan. */ - astSetCard( this, INT_MAX ); - -/* Store the current card index. */ - icard = astGetCard( this ); - -/* Obtain the first header card from the source function. This is an - externally supplied function which may not be thread-safe, so lock a - mutex first. Also store the channel data pointer in a global variable - so that it can be accessed in the source function using macro - astChannelData. */ - astStoreChannelData( this ); - LOCK_MUTEX2; - card = ( *this->source_wrap )( source, status ); - UNLOCK_MUTEX2; - -/* Loop until a NULL pointer is returned by the source function, or an - error occurs. */ - while( card && astOK ){ - -/* Store the card in the FitsChan. */ - astPutFits( this, card, 0 ); - -/* Free the memory holding the header card. */ - card = (char *) astFree( (void *) card ); - -/* Obtain the next header card. Also store the channel data pointer in a - global variable so that it can be accessed in the source function using - macro astChannelData. */ - astStoreChannelData( this ); - LOCK_MUTEX2; - card = ( *this->source_wrap )( source, status ); - UNLOCK_MUTEX2; - } - -/* Set the current card index so that the first of the new cards will be the - next card to be read from the FitsChan. */ - astSetCard( this, icard ); - } -} - -static void RemoveTables( AstFitsChan *this, const char *key, int *status ){ - -/* -*++ -* Name: -c astRemoveTables -f AST_REMOVETABLES - -* Purpose: -* Remove one or more tables from a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c void astRemoveTables( AstFitsChan *this, const char *key ) -f CALL AST_REMOVETABLES( THIS, KEY, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* removes the named tables from the FitsChan, it they exist (no error -* is reported if any the tables do not exist). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c key -f KEY = CHARACTER * ( * ) (Given) -* The key indicating which tables to exist. A single key or a -* comma-separated list of keys can be supplied. If a blank string -* is supplied, all tables are removed. -f STATUS = INTEGER (Given and Returned) -f The global status. -*-- -*/ - -/* Local variables: */ - char **words; - int itable; - int ntable; - -/* Return if the global error status has been set, or the FitsChan - contains no tables KeyMap. */ - if( !astOK || !this->tables ) return; - -/* If the string is blank, remove all tables. */ - if( astChrLen( key ) == 0 ) { - ntable = astMapSize( this->tables ); - for( itable = 0; itable < ntable; itable++ ) { - astMapRemove( this->tables, astMapKey( this->tables, itable ) ); - } - -/* Otherwise, split the supplied comma-separated string up into individual - items. */ - } else { - words = astChrSplitC( key, ',', &ntable ); - -/* Attempt to remove each one, and then free the string. */ - if( astOK ) { - for( itable = 0; itable < ntable; itable++ ) { - astMapRemove( this->tables, words[ itable ] ); - words[ itable ] = astFree( words[ itable ] ); - } - } - -/* Free the list. */ - words = astFree( words ); - } -} - -static void RetainFits( AstFitsChan *this, int *status ){ - -/* -*++ -* Name: -c astRetainFits -f AST_RETAINFITS - -* Purpose: -* Indicate that the current card in a FitsChan should be retained. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" -c void astRetainFits( AstFitsChan *this ) -f CALL AST_RETAINFITS( THIS, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* stores a flag with the current card in the FitsChan indicating that -* the card should not be removed from the FitsChan when an Object is -* read from the FitsChan using -c astRead. -f AST_READ. -* -* Cards that have not been flagged in this way are removed when a -* read operation completes succesfully, but only if the card was used -* in the process of creating the returned AST Object. Any cards that -* are irrelevant to the creation of the AST Object are retained whether -* or not they are flagged. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - This function returns without action if the FitsChan is -* initially positioned at the "end-of-file" (i.e. if the Card -* attribute exceeds the number of cards in the FitsChan). -* - The current card is not changed by this function. -*-- -*/ - -/* Local variables: */ - int flags; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Return if the global error status has been set, or the current card - is not defined. */ - if( !astOK || !this->card ) return; - -/* Set the PROTECTED flag in the current card. */ - flags = ( (FitsCard *) this->card )->flags; - ( (FitsCard *) this->card )->flags = flags | PROTECTED; -} - -static void RoundFString( char *text, int width, int *status ){ -/* -* Name: -* RoundString - -* Purpose: -* Modify a formatted floating point number to round out long -* sequences of zeros or nines. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void RoundFString( char *text, int width ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The supplied string is assumed to be a valid decimal representation of -* a floating point number. It is searched for sub-strings consisting -* of NSEQ or more adjacent zeros, or NSEQ or more adjacent nines. If found -* the string is modified to represent the result of rounding the -* number to remove the sequence of zeros or nines. - -* Parameters: -* text -* The formatted number. Modified on exit to round out long -* sequences of zeros or nines. The returned string is right justified. -* width -* The minimum field width to use. The value is right justified in -* this field width. Ignored if zero. -*/ - -/* Local Constants: */ -#define NSEQ 4 /* No. of adjacent 0's or 9's to produce rounding */ - -/* Local Variables: */ - char *a; - char *c; - char *dot; - char *exp; - char *last; - char *start; - char *end; - int i; - int neg; - int nnine; - int nonzero; - int nzero; - int replace; - int started; - int len; - int bu; - int nls; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Save the original length of the text. */ - len = strlen( text ); - -/* Locate the start of any exponent string. */ - exp = strpbrk( text, "dDeE" ); - -/* First check for long strings of adjacent zeros. - =============================================== */ - -/* Indicate that we have not yet found a decimal point in the string. */ - dot = NULL; - -/* The "started" flag controls whether *leading* zeros should be removed - if there are more than NSEQ of them. They are only removed if there is an - exponent. */ - started = ( exp != NULL ); - -/* We are not currently replacing digits with zeros. */ - replace = 0; - -/* We have not yet found any adjacent zeros. */ - nzero = 0; - -/* We have no evidence yet that the number is non-zero. */ - nonzero = 0; - -/* Loop round the supplied text string. */ - c = text; - while( *c && c != exp ){ - -/* If this is a zero, increment the number of adjacent zeros found, so - long as we have previously found a non-zero digit (or there is an - exponent). If this is the NSEQ'th adjacent zero, indicate that - subsequent digits should be replaced by zeros. */ - if( *c == '0' ){ - if( started && ++nzero >= NSEQ ) replace = 1; - -/* Note if the number contains a decimal point. */ - } else if( *c == '.' ){ - dot = c; - -/* If this character is a non-zero digit, indicate that we have found a - non-zero digit. If we have previously found a long string of adjacent - zeros, replace the digit by '0'. Otherwise, reset the count of - adjacent zeros, and indicate the final number is non-zero. */ - } else if( *c != ' ' && *c != '+' && *c != '-' ){ - started = 1; - if( replace ) { - *c = '0'; - } else { - nzero = 0; - nonzero = 1; - } - } - -/* Move on to the next character. */ - c++; - } - -/* If the final number is zero, just return the most simple decimal zero - value. */ - if( !nonzero ) { - strcpy( text, "0.0" ); - -/* Otherwise, we remove any trailing zeros which occur to the right of a - decimal point. */ - } else if( dot ) { - -/* Find the last non-zero digit. */ - while( c-- > text && *c == '0' ); - -/* If any trailing zeros were found... */ - if( c > text ) { - -/* Retain one trailing zero after a decimal point. */ - if( *c == '.' ) c++; - -/* We put a terminator following the last non-zero character. The - terminator is the exponent, if there was one, or a null character. - Remember to update the pointer to the start of the exponent. */ - c++; - if( exp ) { - a = exp; - exp = c; - while( ( *(c++) = *(a++) ) ); - } else { - *c = 0; - } - } - } - -/* Next check for long strings of adjacent nines. - ============================================= */ - -/* We have not yet found any adjacent nines. */ - nnine = 0; - -/* We have not yet found a non-nine digit. */ - a = NULL; - -/* We have not yet found a non-blank character */ - start = NULL; - last = NULL; - -/* Number is assumed positive. */ - neg = 0; - -/* Indicate that we have not yet found a decimal point in the string. */ - dot = NULL; - -/* Loop round the supplied text string. */ - c = text; - while( *c && c != exp ){ - -/* Note the address of the first non-blank character. */ - if( !start && *c != ' ' ) start = c; - -/* If this is a nine, increment the number of adjacent nines found. */ - if( *c == '9' ){ - ++nnine; - -/* Note if the number contains a decimal point. */ - } else if( *c == '.' ){ - dot = c; - -/* Note if the number is negative. */ - } else if( *c == '-' ){ - neg = 1; - -/* If this character is a non-nine digit, and we have not had a long - sequence of 9's, reset the count of adjacent nines, and update a pointer - to "the last non-nine digit prior to a long string of nines". */ - } else if( *c != ' ' && *c != '+' ){ - if( nnine < NSEQ ) { - nnine = 0; - a = c; - } - } - -/* Note the address of the last non-blank character. */ - if( *c != ' ' ) last = c; - -/* Move on to the next character. */ - c++; - } - -/* If a long string of adjacent nines was found... */ - if( nnine >= NSEQ ) { - c = NULL; - -/* If we found at least one non-nine digit. */ - if( a ) { - -/* "a" points to the last non-nine digit before the first of the group of 9's. - Increment this digit by 1. Since we know the digit is not a nine, there - is no danger of a carry. */ - *a = *a + 1; - -/* Fill with zeros up to the decimal point, or to the end if there is no - decimal point. */ - c = a + 1; - if( dot ) { - while( c < dot ) *(c++) = '0'; - } else { - while( *c ) *(c++) = '0'; - } - -/* Now make "c" point to the first character for the terminator. This is - usually the character following the last non-nine digit. However, if - the last non-nine digit appears immediately before a decimal point, then - we append ".0" to the string before appending the terminator. */ - if( *c == '.' ) { - *(++c) = '0'; - c++; - } - -/* If all digits were nines, the rounded number will occupy one more - character than the supplied number. We can only do the rounding if there - is a spare character (i.e.a space) in the supplied string. */ - } else if( last - start + 1 < len ) { - -/* Put the modified text at the left of the available space. */ - c = text; - -/* Start with a minus sing if needed, followed by the leading "1" (caused - by the overflow from the long string of 9's). */ - if( neg ) *(c++) = '-'; - *(c++) = '1'; - -/* Now find the number of zeros to place after the leading "1". This is - the number of characters in front of the terminator marking the end of - the integer part of the number. */ - if( dot ) { - nzero = dot - start; - } else if( exp ) { - nzero = exp - start; - } else { - nzero = last - start; - } - -/* If the number is negative, the above count will include the leading - minus sign, which is not a digit. So reduce the count by one. */ - if( neg ) nzero--; - -/* Now put in the correct number of zeros. */ - for( i = 0; i < nzero; i++ ) *(c++) = '0'; - -/* If the original string containsed a decimal point, make sure the - returned string also contains one. */ - if( dot ) { - *(c++) = '.'; - if( *c ) *(c++) = '0'; - } - } - -/* We put a terminator following the last non-zero character. The - terminator is the exponent, if there was one, or a null character. */ - if( c ) { - if( exp ) { - while( ( *(c++) = *(exp++) ) ); - } else { - *c = 0; - } - } - } - -/* If a minimum field width has been given, right justify the returned - string in the original field width. */ - if( width ) { - end = text + len; - c = text + strlen( text ); - if( c != end ) { - while( c >= text ) *(end--) = *(c--); - while( end >= text ) *(end--) = ' '; - } - } - -/* If a minimum field width was given, shunt the text to the left in - order to reduce the used field width to the specified value. This - requires there to be some leading spaces (because we do not want to - loose any non-blank characters from the left hand end of the string). - If there are insufficient leading spaces to allow the field width to - be reduced to the specified value, then reduce the field width as far - as possible. First find the number of spaces we would like to remove - from the front of the string (in order to reduce the used width to the - specified value). */ - bu = len - width; - -/* If we need to remove any leading spaces... */ - if( width > 0 && bu > 0 ) { - -/* Find the number of leading spaces which are available to be removed. */ - c = text - 1; - while( *(++c) == ' ' ); - nls = c - text; - -/* If there are insufficient leading spaces, just use however many there - are. */ - if( bu > nls ) bu = nls; - -/* Shift the string. */ - c = text; - a = c + bu; - while( ( *(c++) = *(a++) ) ); - } - -/* Undefine local constants. */ -#undef NSEQ -} - -static int SAOTrans( AstFitsChan *this, AstFitsChan *out, const char *method, - const char *class, int *status ){ -/* -* Name: -* SAOTrans - -* Purpose: -* Translate an SAO encoded header into a TPN encoded header. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int SAOTrans( AstFitsChan *this, AstFitsChan *out, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Search "this" for keywords that give a description of a distorted -* TAN projection using the SAO representation and, if found, write -* keywords to "out" that describe an equivalent projection using TPN -* representation. The definition of the SAO polynomial is taken from -* the platepos.c file included in Doug Mink's WCSTools. - -* Parameters: -* this -* Pointer to the FitsChan to read. -* out -* Pointer to a FitsCHan in which to store translated keywords. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if "this" contained an SAO encoded header. Zero otherwise. - -*/ - -#define NC 13 - -/* Local Variables: */ - char keyname[10]; - double co[ 2 ][ NC ]; - double pv; - int i; - int is_sao; - int m; - int ok; - int result; - -/* Initialise */ - result = 0; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Check there are exactly two CTYPE keywords in the header. */ - if( 2 == astKeyFields( this, "CTYPE%d", 0, NULL, NULL ) ){ - -/* Initialise all cooefficients. */ - memset( co, 0, sizeof( co ) ); - -/* Get the required SAO keywords. */ - is_sao = 1; - ok = 1; - for( i = 0; i < 2 && ok && is_sao; i++ ) { - - ok = 0; - for( m = 0; m < NC; m++ ) { - -/* Get the value of the next "COi_j" keyword. If any of the first 3 values - are missing on either axis, we assume this is not an SAO header. */ - sprintf( keyname, "CO%d_%d", i + 1, m + 1 ); - if( !GetValue( this, keyname, AST__FLOAT, &co[ i ][ m ], 0, 1, method, - class, status ) ) { - if( m < 3 ) is_sao = 0; - break; - } - -/* Check that we have at least one non-zero coefficient (excluding the - first constant term ). */ - if( co[ i ][ m ] != 0.0 && m > 0 ) ok = 1; - } - } - -/* If this is an SAO header.. */ - if( is_sao ) { - -/* Issue a warning if all coefficients for this axis are zero. */ - if( !ok ) { - Warn( this, "badpv", "This FITS header describes an SAO encoded " - "distorted TAN projection, but all the distortion " - "coefficients for at least one axis are zero.", method, class, - status ); - -/* Otherwise, calculate and store the equivalent PV projection parameters. */ - } else { - pv = co[ 0 ][ 0 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_0", &pv, - AST__FLOAT, NULL, status ); - - pv = co[ 0 ][ 1 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_1", &pv, - AST__FLOAT, NULL, status ); - - pv = co[ 0 ][ 2 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_2", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 0 ][ 3 ] != AST__BAD ) pv += co[ 0 ][ 3 ]; - if( co[ 0 ][ 10 ] != AST__BAD ) pv += co[ 0 ][ 10 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_4", &pv, - AST__FLOAT, NULL, status ); - - pv = co[ 0 ][ 5 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_5", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 0 ][ 4 ] != AST__BAD ) pv += co[ 0 ][ 4 ]; - if( co[ 0 ][ 10 ] != AST__BAD ) pv += co[ 0 ][ 10 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_6", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 0 ][ 6 ] != AST__BAD ) pv += co[ 0 ][ 6 ]; - if( co[ 0 ][ 11 ] != AST__BAD ) pv += co[ 0 ][ 11 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_7", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 0 ][ 8 ] != AST__BAD ) pv += co[ 0 ][ 8 ]; - if( co[ 0 ][ 12 ] != AST__BAD ) pv += co[ 0 ][ 12 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_8", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 0 ][ 9 ] != AST__BAD ) pv += co[ 0 ][ 9 ]; - if( co[ 0 ][ 11 ] != AST__BAD ) pv += co[ 0 ][ 11 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_9", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 0 ][ 7 ] != AST__BAD ) pv += co[ 0 ][ 7 ]; - if( co[ 0 ][ 12 ] != AST__BAD ) pv += co[ 0 ][ 12 ]; - if( pv != AST__BAD ) SetValue( out, "PV1_10", &pv, - AST__FLOAT, NULL, status ); - - pv = co[ 1 ][ 0 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_0", &pv, - AST__FLOAT, NULL, status ); - - pv = co[ 1 ][ 2 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_1", &pv, - AST__FLOAT, NULL, status ); - - pv = co[ 1 ][ 1 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_2", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 1 ][ 4 ] != AST__BAD ) pv += co[ 1 ][ 4 ]; - if( co[ 1 ][ 10 ] != AST__BAD ) pv += co[ 1 ][ 10 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_4", &pv, - AST__FLOAT, NULL, status ); - - pv = co[ 1 ][ 5 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_5", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 1 ][ 3 ] != AST__BAD ) pv += co[ 1 ][ 3 ]; - if( co[ 1 ][ 10 ] != AST__BAD ) pv += co[ 1 ][ 10 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_6", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 1 ][ 7 ] != AST__BAD ) pv += co[ 1 ][ 7 ]; - if( co[ 1 ][ 12 ] != AST__BAD ) pv += co[ 1 ][ 12 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_7", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 1 ][ 9 ] != AST__BAD ) pv += co[ 1 ][ 9 ]; - if( co[ 1 ][ 11 ] != AST__BAD ) pv += co[ 1 ][ 11 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_8", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 1 ][ 8 ] != AST__BAD ) pv += co[ 1 ][ 8 ]; - if( co[ 1 ][ 12 ] != AST__BAD ) pv += co[ 1 ][ 12 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_9", &pv, - AST__FLOAT, NULL, status ); - - pv = 0.0; - if( co[ 1 ][ 6 ] != AST__BAD ) pv += co[ 1 ][ 6 ]; - if( co[ 1 ][ 11 ] != AST__BAD ) pv += co[ 1 ][ 11 ]; - if( pv != AST__BAD ) SetValue( out, "PV2_10", &pv, - AST__FLOAT, NULL, status ); - -/* From an example header provided by Bill Joye, it seems that the SAO - polynomial includes the rotation and scaling effects of the CD matrix. - Therefore we mark as read all CDi_j, CDELT and CROTA values. Without - this, the rotation and scaling would be applied twice. First, mark the - original values as having been used, no matter which FitsChan they are - in. */ - GetValue( this, "CD1_1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "CD1_2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "CD2_1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "CD2_2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "PC1_1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "PC1_2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "PC2_1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "PC2_2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "CDELT1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "CDELT2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "CROTA1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( this, "CROTA2", AST__FLOAT, &pv, 0, 1, method, class, status ); - - GetValue( out, "CD1_1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "CD1_2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "CD2_1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "CD2_2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "PC1_1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "PC1_2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "PC2_1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "PC2_2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "CDELT1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "CDELT2", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "CROTA1", AST__FLOAT, &pv, 0, 1, method, class, status ); - GetValue( out, "CROTA2", AST__FLOAT, &pv, 0, 1, method, class, status ); - -/* Now store new default values in the returned FitsChan. */ - pv = 1.0; - SetValue( out, "PC1_1", &pv, AST__FLOAT, NULL, - status ); - SetValue( out, "PC2_2", &pv, AST__FLOAT, NULL, - status ); - SetValue( out, "CDELT1", &pv, AST__FLOAT, NULL, - status ); - SetValue( out, "CDELT2", &pv, AST__FLOAT, NULL, - status ); - - pv = 0.0; - SetValue( out, "PC1_2", &pv, AST__FLOAT, NULL, - status ); - SetValue( out, "PC2_1", &pv, AST__FLOAT, NULL, - status ); - -/* Indicate we have converted an SAO header. */ - result = 1; - } - } - } - -/* Return a flag indicating if an SAO header was found. */ - return result; -} -#undef NC - -static int SearchCard( AstFitsChan *this, const char *name, - const char *method, const char *class, int *status ){ - -/* -* Name: -* SearchCard - -* Purpose: -* Search the whole FitsChan for a card refering to given keyword. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int SearchCard( AstFitsChan *this, const char *name, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Searches the whole FitsChan for a card refering to the supplied keyword, -* and makes it the current card. The card following the current card is -* checked first. If this is not the required card, then a search is -* performed starting with the first keyword in the FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* Pointer to a string holding the keyword name. -* method -* Pointer to string holding name of calling method. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if a card was found refering to the given -* keyword. Otherwise zero is returned. - -* Notes: -* - If a NULL pointer is supplied for "name" then the current card -* is left unchanged. -* - The current card is set to NULL (end-of-file) if no card can be -* found for the supplied keyword. -*/ - -/* Local Variables: */ - int ret; /* Was a card found? */ - -/* Check the global status, and supplied keyword name. */ - if( !astOK || !name ) return 0; - -/* Indicate that no card has been found yet. */ - ret = 0; - -/* The required card is very often the next card in the FitsChan, so check the - next card, and only search the entire FitsChan if the check fails. */ - MoveCard( this, 1, method, class, status ); - if( !astFitsEof( this ) && - !Ustrncmp( CardName( this, status ), name, FITSNAMLEN, status ) ){ - ret = 1; - -/* If the next card is not the required card, rewind the FitsChan back to - the first card. */ - } else { - astClearCard( this ); - -/* Attempt to find the supplied keyword, searching from the first card. */ - ret = FindKeyCard( this, name, method, class, status ); - } - -/* Return. */ - return ret; -} - -static void SetAlgCode( char *buf, const char *algcode, int *status ){ -/* -* Name: -* SetAlgCode - -* Purpose: -* Create a non-linear CTYPE string from a system code and an algorithm -* code. - -* Type: -* Private function. - -* Synopsis: -* void SetAlgCode( char *buf, const char *algcode, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* FITS-WCS paper 1 says that non-linear axes must have a CTYPE of the -* form "4-3" (e.g. "VRAD-TAB"). This function handles the truncation -* of long system codes, or the padding of short system codes. - -* Parameters: -* buf -* A buffer in which is stored the system code. Modified on exit to -* hold the combined CTYPE value. It should have a length long -* enough to hold the system code and the algorithm code. -* algcode -* Pointer to a string holding the algorithm code (with a leading -* "-", e.g. "-TAB"). -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int nc; - -/* Check inherited status */ - if( !astOK ) return; - -/* Pad the supplied string to at least 4 characters using "-" characters. */ - nc = strlen( buf ); - while( nc < 4 ) buf[ nc++ ] = '-'; - -/* Insert the null-terminated code at position 4. */ - strcpy( buf + 4, algcode ); -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* FitsChan member function (over-rides the astSetAttrib protected -* method inherited from the Channel class). - -* Description: -* This function assigns an attribute value for a FitsChan, the -* attribute and its value being specified by means of a string of - -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the FitsChan. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - const char *class; /* Object class */ - double dval; /* Double attribute value */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - int offset; /* Offset of attribute string */ - int warn; /* Offset of Warnings string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Obtain the object class. */ - class = astGetClass( this ); - -/* Card. */ -/* ----- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "card= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetCard( this, ival ); - -/* Encoding. */ -/* --------- */ - } else if( nc = 0, - ( 0 == astSscanf( setting, "encoding=%n%*[^\n]%n", &ival, &nc ) ) - && ( nc >= len ) ) { - nc = ChrLen( setting + ival, status ); - if( !Ustrncmp( setting + ival, NATIVE_STRING, nc, status ) ){ - astSetEncoding( this, NATIVE_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSPC_STRING, nc, status ) ){ - astSetEncoding( this, FITSPC_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSPC_STRING2, nc, status ) ){ - astSetEncoding( this, FITSPC_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSWCS_STRING, nc, status ) ){ - astSetEncoding( this, FITSWCS_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSWCS_STRING2, nc, status ) ){ - astSetEncoding( this, FITSWCS_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSIRAF_STRING, nc, status ) ){ - astSetEncoding( this, FITSIRAF_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSIRAF_STRING2, nc, status ) ){ - astSetEncoding( this, FITSIRAF_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSAIPS_STRING, nc, status ) ){ - astSetEncoding( this, FITSAIPS_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSAIPS_STRING2, nc, status ) ){ - astSetEncoding( this, FITSAIPS_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSAIPSPP_STRING, nc, status ) ){ - astSetEncoding( this, FITSAIPSPP_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSAIPSPP_STRING2, nc, status ) ){ - astSetEncoding( this, FITSAIPSPP_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSCLASS_STRING, nc, status ) ){ - astSetEncoding( this, FITSCLASS_ENCODING ); - } else if( !Ustrncmp( setting + ival, FITSCLASS_STRING2, nc, status ) ){ - astSetEncoding( this, FITSCLASS_ENCODING ); - } else if( !Ustrncmp( setting + ival, DSS_STRING, nc, status ) ){ - astSetEncoding( this, DSS_ENCODING ); - } else { - astError( AST__BADAT, "astSet(%s): Unknown encoding system '%s' " - "requested for a %s.", status, class, setting + ival, class ); - } - -/* FitsDigits. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "fitsdigits= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetFitsDigits( this, ival ); - -/* FitsAxisOrder. */ -/* -------------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "fitsaxisorder=%n%*[^\n]%n", - &offset, &nc ) ) - && ( nc >= len ) ) { - astSetFitsAxisOrder( this, setting + offset ); - -/* CDMatrix */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "cdmatrix= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetCDMatrix( this, ival ); - -/* DefB1950 */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "defb1950= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetDefB1950( this, ival ); - -/* TabOK */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "tabok= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetTabOK( this, ival ); - -/* CarLin */ -/* ------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "carlin= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetCarLin( this, ival ); - -/* SipReplace */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "sipreplace= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetSipReplace( this, ival ); - -/* FitsTol. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "fitstol= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetFitsTol( this, dval ); - -/* PolyTan */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "polytan= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetPolyTan( this, ival ); - -/* SipOK */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "sipok= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetSipOK( this, ival ); - -/* Iwc */ -/* --- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "iwc= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetIwc( this, ival ); - -/* Clean */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "clean= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetClean( this, ival ); - -/* Warnings. */ -/* -------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "warnings=%n%*[^\n]%n", &warn, &nc ) ) - && ( nc >= len ) ) { - astSetWarnings( this, setting + warn ); - -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* If the attribute was not recognised, use this macro to report an error - if a read-only attribute has been specified. */ - } else if ( MATCH( "ncard" ) || - MATCH( "cardtype" ) || - MATCH( "cardcomm" ) || - MATCH( "cardname" ) || - MATCH( "nkey" ) || - MATCH( "allwarnings" ) ){ - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetCard( AstFitsChan *this, int icard, int *status ){ - -/* -*+ -* Name: -* astSetCard - -* Purpose: -* Set the value of the Card attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" - -* void astSetCard( AstFitsChan *this, int icard ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function sets the value of the Card attribute for the supplied -* FitsChan. This is the index of the next card to be read from the -* FitsChan. If a value of 1 or less is supplied, the first card in -* the FitsChan will be read next. If a value greater than the number -* of cards in the FitsChan is supplied, the FitsChan will be left in an -* "end-of-file" condition, in which no further read operations can be -* performed. - -* Parameters: -* this -* Pointer to the FitsChan. -* icard -* The index of the next card to read. - -* Notes: -* - This function attempts to execute even if an error has occurred. -*- -*/ - -/* Check the supplied object. */ - if ( !this ) return; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Rewind the FitsChan. */ - astClearCard( this ); - -/* Move forward the requested number of cards. */ - MoveCard( this, icard - 1, "astSetCard", astGetClass( this ), status ); - -/* Return. */ - return; -} - -static void SetItem( double ****item, int i, int jm, char s, double val, int *status ){ -/* -* Name: -* SetItem - -* Purpose: -* Store a value for a axis keyword value in a FitStore structure. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void SetItem( double ****item, int i, int jm, char s, double val, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The supplied keyword value is stored in the specified array, -* at a position indicated by the axis and co-ordinate version. -* The array is created or extended as necessary to make room for -* the new value. Any old value is over-written. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->crval) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (i), and the pointer locates an -* array of axis keyword values. These arrays of keyword values have -* one element for every pixel axis (j) or projection parameter (m). -* i -* The zero based intermediate axis index in the range 0 to 98. Set -* this to zero for keywords (e.g. CRPIX) which are not indexed by -* intermediate axis number. -* jm -* The zero based pixel axis index (in the range 0 to 98) or parameter -* index (in the range 0 to WCSLIB__MXPAR-1). Set this to zero for -* keywords (e.g. CRVAL) which are not indexed by either pixel axis or -* parameter number. -* val -* The keyword value to store. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int el; /* Array index */ - int nel; /* Number of elements in array */ - int si; /* Integer co-ordinate version index */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Convert the character co-ordinate version into an integer index, and - check it is within range. The primary axis description (s=' ') is - given index zero. 'A' is 1, 'B' is 2, etc. */ - if( s == ' ' ) { - si = 0; - } else if( islower(s) ){ - si = (int) ( s - 'a' ) + 1; - } else { - si = (int) ( s - 'A' ) + 1; - } - if( si < 0 || si > 26 ) { - astError( AST__INTER, "SetItem(fitschan): AST internal error; " - "co-ordinate version '%c' ( char(%d) ) is invalid.", status, s, s ); - -/* Check the intermediate axis index is within range. */ - } else if( i < 0 || i > 98 ) { - astError( AST__INTER, "SetItem(fitschan): AST internal error; " - "intermediate axis index %d is invalid.", status, i ); - -/* Check the pixel axis or parameter index is within range. */ - } else if( jm < 0 || jm > 99 ) { - astError( AST__INTER, "SetItem(fitschan): AST internal error; " - "pixel axis or parameter index %d is invalid.", status, jm ); - -/* Otherwise proceed... */ - } else { - -/* Store the current number of coordinate versions in the supplied array */ - nel = astSizeOf( (void *) *item )/sizeof(double **); - -/* If required, extend the array located by the supplied pointer so that - it is long enough to hold the specified co-ordinate version. */ - if( nel < si + 1 ){ - *item = (double ***) astGrow( (void *) *item, si + 1, - sizeof(double **) ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Initialise the new elements to hold NULL. Note, astGrow may add more - elements to the array than is actually needed, so use the actual current - size of the array as implied by astSize rather than the index si. */ - for( el = nel; - el < astSizeOf( (void *) *item )/sizeof(double **); - el++ ) (*item)[el] = NULL; - } - } - -/* If the above went OK... */ - if( astOK ){ - -/* Store the currrent number of intermediate axes in the supplied array */ - nel = astSizeOf( (void *) (*item)[si] )/sizeof(double *); - -/* If required, extend the array so that it is long enough to hold the - specified intermediate axis. */ - if( nel < i + 1 ){ - (*item)[si] = (double **) astGrow( (void *) (*item)[si], i + 1, - sizeof(double *) ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Initialise the new elements to hold NULL. */ - for( el = nel; - el < astSizeOf( (void *) (*item)[si] )/sizeof(double *); - el++ ) (*item)[si][el] = NULL; - } - } - -/* If the above went OK... */ - if( astOK ){ - -/* Store the current number of pixel axis or parameter values in the array. */ - nel = astSizeOf( (void *) (*item)[si][i] )/sizeof(double); - -/* If required, extend the array so that it is long enough to hold the - specified axis. */ - if( nel < jm + 1 ){ - (*item)[si][i] = (double *) astGrow( (void *) (*item)[si][i], - jm + 1, sizeof(double) ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Initialise the new elements to hold AST__BAD. */ - for( el = nel; - el < astSizeOf( (void *) (*item)[si][i] )/sizeof(double); - el++ ) (*item)[si][i][el] = AST__BAD; - } - } - -/* If the above went OK, store the supplied keyword value. */ - if( astOK ) (*item)[si][i][jm] = val; - } - } - } -} - -static void SetItemC( char *****item, int i, int jm, char s, const char *val, - int *status ){ -/* -* Name: -* SetItemC - -* Purpose: -* Store a character string for an axis keyword value in a FitStore -* structure. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void SetItemC( char *****item, int i, int jm, char s, const char *val, -* int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The supplied keyword string value is stored in the specified array, -* at a position indicated by the axis and co-ordinate version. -* The array is created or extended as necessary to make room for -* the new value. Any old value is over-written. - -* Parameters: -* item -* The address of the pointer within the FitsStore which locates the -* arrays of values for the required keyword (eg &(store->ctype) ). -* The array located by the supplied pointer contains a vector of -* pointers. Each of these pointers is associated with a particular -* co-ordinate version (s), and locates an array of pointers for that -* co-ordinate version. Each such array of pointers has an element -* for each intermediate axis number (i), and the pointer locates an -* array of axis keyword string pointers. These arrays of keyword -* string pointers have one element for every pixel axis (j) or -* projection parameter (m). -* i -* The zero based intermediate axis index in the range 0 to 98. Set -* this to zero for keywords (e.g. RADESYS) which are not indexed by -* intermediate axis number. -* jm -* The zero based pixel axis index (in the range 0 to 98) or parameter -* index (in the range 0 to WCSLIB__MXPAR-1). Set this to zero for -* keywords (e.g. CTYPE) which are not indexed by either pixel axis or -* parameter number. -* val -* The keyword string value to store. A copy of the supplied string -* is taken. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int el; /* Array index */ - int nel; /* Number of elements in array */ - int si; /* Integer co-ordinate version index */ - -/* Check the inherited status and the supplied pointer. */ - if( !astOK || !val ) return; - -/* Convert the character co-ordinate version into an integer index, and - check it is within range. The primary axis description (s=' ') is - given index zero. 'A' is 1, 'B' is 2, etc. */ - if( s == ' ' ) { - si = 0; - } else if( islower(s) ){ - si = (int) ( s - 'a' ) + 1; - } else { - si = (int) ( s - 'A' ) + 1; - } - if( si < 0 || si > 26 ) { - astError( AST__INTER, "SetItemC(fitschan): AST internal error; " - "co-ordinate version '%c' ( char(%d) ) is invalid.", status, s, s ); - -/* Check the intermediate axis index is within range. */ - } else if( i < 0 || i > 98 ) { - astError( AST__INTER, "SetItemC(fitschan): AST internal error; " - "intermediate axis index %d is invalid.", status, i ); - -/* Check the pixel axis or parameter index is within range. */ - } else if( jm < 0 || jm > 99 ) { - astError( AST__INTER, "SetItemC(fitschan): AST internal error; " - "pixel axis or parameter index %d is invalid.", status, jm ); - -/* Otherwise proceed... */ - } else { - -/* Store the current number of coordinate versions in the supplied array */ - nel = astSizeOf( (void *) *item )/sizeof(char ***); - -/* If required, extend the array located by the supplied pointer so that - it is long enough to hold the specified co-ordinate version. */ - if( nel < si + 1 ){ - *item = (char ****) astGrow( (void *) *item, si + 1, - sizeof(char ***) ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Initialise the new elements to hold NULL. Note, astGrow may add more - elements to the array than is actually needed, so use the actual current - size of the array as implied by astSize rather than the index si. */ - for( el = nel; - el < astSizeOf( (void *) *item )/sizeof(char ***); - el++ ) (*item)[el] = NULL; - } - } - -/* If the above went OK... */ - if( astOK ){ - -/* Store the currrent number of intermediate axes in the supplied array */ - nel = astSizeOf( (void *) (*item)[si] )/sizeof(char **); - -/* If required, extend the array so that it is long enough to hold the - specified intermediate axis. */ - if( nel < i + 1 ){ - (*item)[si] = (char ***) astGrow( (void *) (*item)[si], i + 1, - sizeof(char **) ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Initialise the new elements to hold NULL. */ - for( el = nel; - el < astSizeOf( (void *) (*item)[si] )/sizeof(char **); - el++ ) (*item)[si][el] = NULL; - } - } - -/* If the above went OK... */ - if( astOK ){ - -/* Store the current number of pixel axis or parameter values in the array. */ - nel = astSizeOf( (void *) (*item)[si][i] )/sizeof(char *); - -/* If required, extend the array so that it is long enough to hold the - specified axis. */ - if( nel < jm + 1 ){ - (*item)[si][i] = (char **) astGrow( (void *) (*item)[si][i], - jm + 1, sizeof(char *) ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Initialise the new elements to hold NULL. */ - for( el = nel; - el < astSizeOf( (void *) (*item)[si][i] )/sizeof(char *); - el++ ) (*item)[si][i][el] = NULL; - } - } - -/* If the above went OK... */ - if( astOK ){ - -/* Store a copy of the supplied string, using any pre-allocated memory. */ - (*item)[si][i][jm] = (char *) astStore( (void *) (*item)[si][i][jm], - (void *) val, - strlen( val ) + 1 ); - } - } - } - } -} - -static void SetSourceFile( AstChannel *this_channel, const char *source_file, - int *status ) { -/* -* Name: -* SetSourceFile - -* Purpose: -* Set a new value for the SourceFile attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void SetSourceFile( AstChannel *this, const char *source_file, -* int *status ) - -* Class Membership: -* FitsChan member function (over-rides the astSetSourceFile -* method inherited from the Channel class). - -* Description: -* This function stores the supplied string as the new value for the -* SourceFile attribute. In addition, it also attempts to open the -* file, read FITS headers from it and append them to the end of the -* FitsChan. It then closes the SourceFile. - -* Parameters: -* this -* Pointer to the FitsChan. -* source_file -* The new attribute value. Should be the path to an existing text -* file, holding FITS headers (one per line) -* status -* Inherited status pointer. - -*/ - -/* Local Constants: */ -#define ERRBUF_LEN 80 - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - FILE *fd; /* Descriptor for source file */ - char *errstat; /* Pointer for system error message */ - char card[ AST__FITSCHAN_FITSCARDLEN + 2 ]; /* Buffer for source line */ - char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Invoke the parent astSetSourceFile method to store the supplied - string in the Channel structure. */ - (*parent_setsourcefile)( this_channel, source_file, status ); - -/* Attempt to open the file. */ - fd = NULL; - if( astOK ) { - fd = fopen( source_file, "r" ); - if( !fd ) { - if ( errno ) { -#if HAVE_STRERROR_R - strerror_r( errno, errbuf, ERRBUF_LEN ); - errstat = errbuf; -#else - errstat = strerror( errno ); -#endif - astError( AST__RDERR, "astSetSourceFile(%s): Failed to open input " - "SourceFile '%s' - %s.", status, astGetClass( this ), - source_file, errstat ); - } else { - astError( AST__RDERR, "astSetSourceFile(%s): Failed to open input " - "SourceFile '%s'.", status, astGetClass( this ), - source_file ); - } - } - } - -/* Move the FitsChan to EOF */ - astSetCard( this, INT_MAX ); - -/* Read each line from the file, remove trailing space, and append to the - FitsChan. */ - while( astOK && fgets( card, AST__FITSCHAN_FITSCARDLEN + 2, fd ) ) { - card[ astChrLen( card ) ] = 0; - astPutFits( this, card, 0 ); - } - -/* Close the source file. */ - if( fd ) fclose( fd ); - -} - -static void SetTableSource( AstFitsChan *this, - void (*tabsource)( void ), - void (*tabsource_wrap)( void (*)( void ), - AstFitsChan *, const char *, - int, int, int * ), - int *status ){ - -/* -*+ -* Name: -* astSetTableSource - -* Purpose: -* Register source and wrapper function for accessing tables in FITS files. - -* Type: -* Protected function. - -* Synopsis: -* #include "fitschan.h" -* void astSetTableSource( AstFitsChan *this, -* void (*tabsource)( void ), -* void (*tabsource_wrap)( void (*)( void ), -* AstFitsChan *, const char *, -* int, int, int * ), -* int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function registers a table source function and its wrapper. A -* wrapper function exists to adapt the API of the table source -* function to the needs of different languages. The wrapper is called -* from the FitsChan code. The wrapper then adjusts the arguments as -* required and then calls the actualy table source function. - -* Parameters: -* this -* Pointer to the FitsChan. -* tabsource -* Pointer to the table source function. The API for this function -* will depend on the language, and so is cast to void here. It -* should be cast to the required form within the wrapper function. -* tabsource_wrap -* The wrapper function. -*- -*/ - -/* Local Variables: */ - -/* Check the global error status. */ - if ( !astOK ) return; - this->tabsource = tabsource; - this->tabsource_wrap = tabsource_wrap; -} - -static void SetValue( AstFitsChan *this, const char *keyname, void *value, - int type, const char *comment, int *status ){ - -/* -* Name: -* SetValue - -* Purpose: -* Save a FITS keyword value, over-writing any existing keyword value. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void SetValue( AstFitsChan *this, char *keyname, void *value, -* int type, const char *comment, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function saves a keyword value as a card in the supplied -* FitsChan. Comment cards are always inserted in-front of the current -* card. If the keyword is not a comment card, any existing value -* for the keyword is over-written with the new value (even if it is -* marked as having been read). Otherwise, (i.e. if it is not a comment -* card, and no previous value exists) it is inserted in front -* of the current card. - -* Parameters: -* this -* A pointer to the FitsChan. -* keyname -* A pointer to a string holding the keyword name. -* value -* A pointer to a buffer holding the keyword value. For strings, -* the buffer should hold a pointer to the character string. -* type -* The FITS data type of the supplied keyword value. -* comment -* A comment to store with the keyword. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Nothing is stored if a NULL pointer is supplied for "value". -* - If the keyword has a value of AST__BAD then nothing is stored, -* and an error is reported. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - FitsCard *card; /* Pointer to original current card */ - const char *class; /* Class name to include in error messages */ - const char *method; /* Method name to include in error messages */ - int newcard; /* Has the original current card been deleted? */ - int old_ignore_used; /* Original setting of external ignore_used variable */ - int stored; /* Has the keyword been stored? */ - -/* Check the status and supplied value pointer. */ - if( !astOK || !value ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Set up the method and class names for inclusion in error mesages. */ - method = "astWrite"; - class = astGetClass( this ); - -/* Comment card are always inserted in-front of the current card. */ - if ( type == AST__COMMENT ) { - SetFits( this, keyname, value, type, comment, 0, status ); - -/* Otherwise... */ - } else { - -/* Report an error if a bad value is stored for a keyword. */ - if( type == AST__FLOAT ){ - if( *( (double *) value ) == AST__BAD && astOK ) { - astError( AST__BDFTS, "%s(%s): The required FITS keyword " - "\"%s\" is indeterminate.", status, method, class, keyname ); - } - } - -/* Save a pointer to the current card. */ - card = (FitsCard *) this->card; - -/* Indicate that we should not skip over cards marked as having been - read. */ - old_ignore_used = ignore_used; - ignore_used = 0; - -/* Indicate that we have not yet stored the keyword value. */ - stored = 0; - -/* Attempt to find a card refering to the supplied keyword. If one is - found, it becomes the current card. */ - if( SearchCard( this, keyname, "astWrite", astGetClass( this ), status ) ){ - -/* If the card which was current on entry to this function will be - over-written, we will need to take account of this when re-instating the - original current card. Make a note of this. */ - newcard = ( card == (FitsCard *) this->card ); - -/* Replace the current card with a card holding the supplied information. */ - SetFits( this, keyname, value, type, comment, 1, status ); - stored = 1; - -/* If we have just replaced the original current card, back up a card - so that the replacement card becomes the current card. */ - if( newcard ) { - MoveCard( this, -1, "astWrite", astGetClass( this ), status ); - -/* Otherwise, re-instate the original current card. */ - } else { - this->card = (void *) card; - } - } - -/* If the keyword has not yet been stored (i.e. if it did not exist in the - FitsChan), re-instate the original current card and insert the new card - before the original current card, leaving the current card unchanged. */ - if( !stored ) { - this->card = (void *) card; - SetFits( this, keyname, value, type, comment, 0, status ); - } - -/* Re-instate the original flag indicating if cards marked as having been - read should be skipped over. */ - ignore_used = old_ignore_used; - } -} - -static void Shpc1( double xmin, double xmax, int n, double *d, double *w, - int *status ){ -/* -* Name: -* Shpc1 - -* Purpose: -* Modifies a one-dimensional polynomial to scale the polynomial argument. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void Shpc1( double xmin, double xmax, int n, double *d, double *w, -* int *status ) - -* Description: -* Given the coefficients of a one-dimensional polynomial P(u) defined on a -* unit interval (i.e. -1 <= u <= +1 ), find the coefficients of another -* one-dimensional polynomial Q(x) where: -* -* Q(x) = P(u) -* u = ( 2*x - ( xmax + xmin ) ) / ( xmax - xmin ) -* -* That is, u is a scaled version of x, such that the unit interval in u -* maps onto (xmin:xmax) in x. - -* Parameters: -* xmin -* X value corresponding to u = -1 -* xmax -* X value corresponding to u = +1 -* n -* One more than the maximum power of u within P. -* d -* An array of n elements supplied holding the coefficients of P such -* that the coefficient of (u^i) is held in element (i). -* w -* An array of n elements returned holding the coefficients of Q such -* that the coefficient of (x^i) is held in element (i). -* status -* Pointer to the inherited status variable. - -* Notes: -* - Vaguely inspired by the Numerical Recipes routine "pcshft". But the -* original had bugs, so I wrote this new version from first principles. - -*/ - -/* Local Variables: */ - double b; - double a; - int j; - int i; - -/* Check inherited status */ - if( !astOK ) return; - -/* Get the scale and shift terms so that u = a*x + b */ - a = 2.0/( xmax - xmin ); - b = ( xmin + xmax )/( xmin - xmax ); - -/* Initialise the returned coeffs */ - for( i = 0; i < n; i++ ) w[ i ] = 0.0; - -/* The supplied Polynomial is - - P(u) = d0 + d1*u + d2*u^2 + ... - - = d0 + u*( d1 + u*( d2 + ... u*( d{n-1} ) ) ) . . . . . (1) - - = d0 + (a*x+b)*( d1 + (a*x+b)*( d2 + ... (a*x+b)*( d[n-1] ) ) ) - - The inner-most parenthesised expression is a polynomial of order zero - (a constant - d[n-1]). Store the coefficients of this zeroth order - polynomial in the returned array. The "w" array is used to hold the - coefficients of Q, i.e. coefficients of powers of "x", not "u", but - since the inner-most polynomial is a constant, it makes no difference - (x^0 == u^0 == 1). */ - w[ 0 ] = d[ n - 1 ]; - -/* Now loop through each remaining level of parenthetic nesting in (1). At - each level, the parenthesised expression represents a polynomial of order - "i". At the end of each pass though this loop, the returned array "w" - holds the coefficients of this "i"th order polynomial. So on the last - loop, i = n-1, "w" holds the required coefficients of Q. */ - for( i = 1; i < n; i++ ) { - -/* If "R" is the polynomial at the "i-1"th level of nesting (the - coefficiemts of which are currently held in "w"), and "S" is the - polynomial at the "i"th level of nesting, we can see from (1) that: - - S = d[ n - 1 - i ] + u*R - - Substituting for "u", this becomes - - S = d[ n - 1 - i ] + ( a*x + b )*R - = d[ n - 1 - i ] + a*R*x + b*R - - Looking at each of these three terms in reverse order: - - 1) The "b*R" term is implemented by simply scaling the current contents - of the "w" array by "b"; in the "a*R*x" term. - - 2) In "a*R*x", the effect of multiplying by "x" is to move the existing - coefficients in "w" up one element. We then multiply the shifted - coefficients by "a" and add them onto the coefficients produced at - step 1) above. - - We know that "w" still contains the initial zeros at indices higher than - "i" so we only need to scale the bottom "i" elements. We do not do the - zeroth term in this loop since there is no lower term to shift up into - it. */ - - for( j = i; j > 0; j-- ){ - w[ j ] = b*w[ j ] + a*w[ j - 1 ]; - } - -/* Now do the zeroth term. Scale the existing zeroth term by "b" as - required by step 1) and add on the first term, the constant - "d[ n - 1 - i ]". Step 2) is a no-op, since in effect the value of - "w[-1]" is zero. */ - w[ 0 ] = d[ n - i - 1 ] + b*w[ 0 ]; - } - -} - -static void ShowFits( AstFitsChan *this, int *status ){ - -/* -*++ -* Name: -c astShowFits -f AST_SHOWFITS - -* Purpose: -* Display the contents of a FitsChan on standard output. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" -c void astShowFits( AstFitsChan *this ) -f CALL AST_SHOWFITS( THIS, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* formats and displays all the cards in a FitsChan on standard output. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char card[ AST__FITSCHAN_FITSCARDLEN + 1]; /* Buffer for header card */ - int icard; /* Current card index on entry */ - int old_ignore_used; /* Original value of external variable ignore_used */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Store the current card index. */ - icard = astGetCard( this ); - -/* Indicate that cards which have been read into an AST object should skipped - over by the functions which navigate the linked list of cards. */ - old_ignore_used = ignore_used; - ignore_used = 1; - -/* Ensure that the first card in the FitsChan will be the next one to be - read. */ - astSetCard( this, 1 ); - -/* Loop round obtaining and writing out each card, until all cards have been - processed. */ - while( !astFitsEof( this ) && astOK ){ - -/* Get the current card, and display it. The call to astFindFits increments - the current card. */ - if( astFindFits( this, "%f", card, 1 ) ) printf( "%s\n", card ); - } - -/* Re-instate the original flag indicating if cards marked as having been - read should be skipped over. */ - ignore_used = old_ignore_used; - -/* Set the current card index back to what it was on entry. */ - astSetCard( this, icard ); - -} - -static int Similar( const char *str1, const char *str2, int *status ){ -/* -* Name: -* Similar - -* Purpose: -* Are two string effectively the same to human readers? - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void Similar( const char *str1, const char *str2, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function returns a non-zero value if the two supplied strings -* are equivalent to a human reader. This is assumed to be the case if -* the strings are equal apart from leading and trailing white space, -* multiple embedded space, and case. - -* Parameters: -* str1 -* The first string -* str2 -* The second string -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the two supplied strings are equivalent, and zero -* otherwise. -*/ - -/* Local Variables: */ - const char *ea; /* Pointer to end of string a */ - const char *eb; /* Pointer to end of string b */ - const char *a; /* Pointer to next character in string a */ - const char *b; /* Pointer to next character in string b */ - int result; /* Are the two strings equivalent? */ - int ss; /* Skip subsequent spaces? */ - -/* Initialise */ - result = 0; - -/* Check the status and supplied value pointer. */ - if( !astOK ) return result; - -/* Initialise pointers into the two strings. */ - a = str1; - b = str2; - -/* Get a pointer to the character following the last non-blank character in - each string. */ - ea = a + ChrLen( a, status ) - 1; - eb = b + ChrLen( b, status ) - 1; - -/* Set a flag indicating that spaces before the next non-blank character - should be ignored. */ - ss = 1; - -/* Compare the strings. */ - while( 1 ){ - -/* Move on to the next significant character in both strings. */ - while( a < ea && *a == ' ' && ss ) a++; - while( b < eb && *b == ' ' && ss ) b++; - -/* If one string has been exhausted but the other has not, the strings - are not equivalent. */ - if( ( a < ea && b == eb ) || ( a == ea && b < eb ) ) { - break; - -/* If both strings have been exhausted simultaneously, the strings - are equivalent. */ - } else if( b == eb && a == ea ) { - result = 1; - break; - -/* If neither string has been exhausted, compare the current character - for equality, ignoring case. Break if they are different. */ - } else if( tolower( *a ) != tolower( *b ) ){ - break; - -/* If the two characters are both spaces, indicate that subsequent spaces - should be skipped. */ - } else if( *a == ' ' ) { - ss = 1; - -/* If the two characters are not spaces, indicate that subsequent spaces - should not be skipped. */ - } else { - ss = 0; - } - -/* Move on to the next characters. */ - a++; - b++; - } - -/* Return the result. */ - return result; -} - -static void SinkWrap( void (* sink)( const char * ), const char *line, int *status ) { -/* -* Name: -* SinkWrap - -* Purpose: -* Wrapper function to invoke a C FitsChan sink function. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void SinkWrap( void (* sink)( const char * ), const char *line, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function invokes the sink function whose pointer is -* supplied in order to write an output line to an external data -* store. - -* Parameters: -* sink -* Pointer to a sink function, whose single parameter is a -* pointer to a const, null-terminated string containing the -* text to be written, and which returns void. This is the form -* of FitsChan sink function employed by the C language interface -* to the AST library. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the sink function. */ - ( *sink )( line ); -} - -static AstMapping *SIPIntWorld( AstMapping *map, int lonax, int latax, - char s, FitsStore *store, double *dim, - int inaxes[2], double crpix[2], double cd[4], - const char *method, const char *class, - int *status ){ -/* -* Name: -* SIPIntWorld - -* Purpose: -* Create FITS header values which map grid into intermediate world -* coords for celestial axes that include SIP distortion. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *SIPIntWorld( AstMapping *map, int lonax, int latax, -* char s, FitsStore *store, double *dim, -* int inaxes[2], double crpix[2], double cd[4], -* const char *method, const char *class, -* int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function finds and returns values for the CRPIX and CDi_j -* keywords for sky axes that can be described using the SIP -* distortion scheme. These values are determined by examining the -* supplied pixel->IWCS Mapping. Values for SIP headers are also stored -* in the supplied FitsSTore. -* -* The celestial axes are first identified and the supplied Mapping -* split to create a (2-in,2-out) Mapping that describes them. This -* Mapping is then searched for a PolyMap. If found, the Mapping prior -* to the PolyMap is checked to ensure it is a simple shift of origin. -* The Mapping following the PolyMap is checked to ensure it is a -* linear transformation with no shift of origin. The PolyMap itself -* is checked to see if it conforms to the requirements of the SIP -* conventions. If any of these conditions are not met, NULL is -* returned as the function value. Otherwise, CRPIX values are created -* from the Mapping prior to the PolyMap, and CDi_j values from the -* Mapping following the PolyMap. The keywords describing the SIP -* distortion itself (the PolyMap) are stored in the supplied FitsStore. -* A Mapping is retuned that is identical to the supplied Mapping but -* without the PolyMap. - -* Parameters: -* map -* A pointer to a Mapping which transforms grid coordinates into -* intermediate world coordinates. -* lonax -* The zero-based index of the output of "map" corresponding to -* celestial longitude. -* latax -* The zero-based index of the output of "map" corresponding to -* celestial latitude. -* s -* The co-ordinate version character. A space means the primary -* axis descriptions. Otherwise the supplied character should be -* an upper case alphabetical character ('A' to 'Z'). -* store -* A pointer to the FitsStore into which the calculated SIP headers -* are stored. -* dim -* An array holding the image dimensions in pixels. AST__BAD can be -* supplied for any unknwon dimensions. -* inaxes -* Returned holding the indices of the two Mapping inputs that generate -* the returned "crpix" and "cd" values. -* crpix -* If SIP headers are stored successfully in the FitsStore, then -* this array is returned holding the CRPIX values. The first -* element refers to the Mapping input given by the first element -* of "inaxes". The second element refers to the Mapping input given -* by the second element of "inaxes". -* cd -* If SIP headers are stored successfully in the FitsStore, then -* this array is returned holding the CD values in the order -* (CDlonax_j1,CDlonax_j2,CDlatax_j1,CDlatax_j2). Where "lonax" and -* "latax" are the indices of the lon and lat Mapping outputs -* (note, these may be different to the corresponding FITS "i" axis -* indices), and "j1" and "j2" are the indices of the Mapping inputs -* returned in "inaxes" (i.e. j1 = inaxes[0] and j2 = inaxes[1]). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A Mapping is returned if SIP headers have been stored in the -* FitsStore successfully. NULL is returned otherwise. The returned -* Mapping is a copy of the supplied mapping "map", but without the -* PolyMap. - -* Notes: -* - NULL is returned if an error occurs. -*/ - -/* Local Variables: */ - AstMapping **map_list; - AstMapping *map_upper; - AstMapping *map_lower; - AstMapping *result; - AstMapping *smap; - AstMapping *tmap; - AstMapping *tmap2; - AstMapping *tmap1; - AstPolyMap *polymap; - AstPermMap *pm; - const char *cval; - char buf[30]; - double ****item; - double *coeffs; - double *pc; - double *scales; - double *shifts; - double fit[ 6 ]; - double iwcxin; - double iwcyin; - double lbnd[ 2 ]; - double ubnd[ 2 ]; - double val; - int *inax1; - int *inax2; - int *inperm1; - int *inperm2; - int *invert_list; - int *outperm1; - int *outperm2; - int *outrem; - int fwd; - int i; - int icoeff; - int iin; - int imap; - int imap_pm; - int iout; - int ioutrem; - int jm; - int ncoeff; - int nin; - int nmap; - int nout; - int noutrem; - int ok; - int old_invert; - int outax[ 2 ]; - int aimax; - int ajmmax; - int bimax; - int bjmmax; - -/* Initialise */ - result = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get the number of inputs and outputs for the Mapping. */ - nin = astGetNin( map ); - nout = astGetNin( map ); - -/* Check both transformations are defined in the supplied Mapping. */ - if( astGetTranForward( map ) && astGetTranInverse( map ) ) { - -/* Attempt to split the supplied Mapping to generate a (2-input,2-output) - Mapping that goes from grid coords to celestial longitude and latitude. - Since we want to specify the retained output, we need to invert the - Mapping, because astMapSplit only allows us to specify the retained - inputs. */ - astInvert( map ); - outax[ 0 ] = lonax; - outax[ 1 ] = latax; - inax1 = astMapSplit( map, 2, outax, &tmap1 ); - astInvert( map ); - -/* Check the Mapping could be split, and that the mapping that generates - lonax/latax has exactly two inputs (use the NBout attribute since - "tmap1" is inverted). Then invert "tmap1" so that it is in the same - direction as the supplied mapping. */ - if( inax1 && tmap1 && astGetNout( tmap1 ) == 2 ) { - astInvert( tmap1 ); - inaxes[ 0 ] = inax1[ 0 ]; - inaxes[ 1 ] = inax1[ 1 ]; - -/* Search this list of Mappings for a PolyMap. First simplify it, then - expand it as a list of Mappings in series. Then look through the list - for a PolyMap. */ - polymap = NULL; - smap = astSimplify( tmap1 ); - nmap = 0; - map_list = NULL; - invert_list = NULL; - (void) astMapList( smap, 1, astGetInvert(smap), &nmap, &map_list, - &invert_list ); - for( imap = 0; imap < nmap; imap++ ) { - if( astIsAPolyMap( map_list[ imap ] ) ) { - imap_pm = imap; - polymap = astCopy( map_list[ imap ] ); - astSetInvert( polymap, invert_list[ imap ] ); - break; - } - } - -/* If a PolyMap is found, check it conforms to the requirements of the - SIP convention. */ - if( polymap ){ - if( astGetNin( polymap ) == 2 && astGetNout( polymap ) == 2 ){ - -/* Check that each Mapping before the PolyMap is a shift of origin, and - accumulate them into a single CmpMap. */ - map_lower = NULL; - ok = 1; - for( imap = 0; ok && imap < imap_pm; imap++ ) { - old_invert = astGetInvert( map_list[ imap ] ); - astSetInvert( map_list[ imap ], invert_list[ imap ] ); - - if( astGetNin( map_list[ imap ] ) != 2 ){ - ok = 0; - - } else if( astIsAWinMap( map_list[ imap ] ) ) { - astWinTerms( map_list[ imap ], &shifts, &scales ); - if( scales[ 0 ] != 1.0 || scales[ 1 ] != 1.0 ) ok = 0; - - } else if( !astIsAShiftMap( map_list[ imap ] ) && - !astIsAUnitMap( map_list[ imap ] ) ) { - ok = 0; - } - - if( map_lower ) { - tmap = (AstMapping *) astCmpMap( map_lower, map_list[ imap ], 1, " ", status ); - (void) astAnnul( map_lower ); - map_lower = tmap; - } else { - map_lower = astCopy( map_list[ imap ] ); - } - - astSetInvert( map_list[ imap ], old_invert ); - } - -/* Check that each Mapping after the PolyMap is a scaling or matrix, - and accumulate them into a single CmpMap. */ - map_upper = NULL; - for( imap = imap_pm + 1; ok && imap < nmap; imap++ ) { - old_invert = astGetInvert( map_list[ imap ] ); - astSetInvert( map_list[ imap ], invert_list[ imap ] ); - - if( astGetNin( map_list[ imap ] ) != 2 ){ - ok = 0; - - } else if( astIsAWinMap( map_list[ imap ] ) ) { - astWinTerms( map_list[ imap ], &shifts, &scales ); - if( shifts[ 0 ] != 0.0 || shifts[ 1 ] != 0.0 ) ok = 0; - - } else if( !astIsAMatrixMap( map_list[ imap ] ) && - !astIsAZoomMap( map_list[ imap ] ) && - !astIsAUnitMap( map_list[ imap ] ) ) { - ok = 0; - } - - if( map_upper ) { - tmap = (AstMapping *) astCmpMap( map_upper, map_list[ imap ], 1, " ", status ); - (void) astAnnul( map_upper ); - map_upper = tmap; - } else { - map_upper = astCopy( map_list[ imap ] ); - } - - astSetInvert( map_list[ imap ], old_invert ); - } - -/* Split the supplied Mapping to generate the Mapping that gives - any remaining non-celestial output axes. We only need to do this if - the supplied Mapping has any surplus inputs or outputs. */ - inax2 = NULL; - tmap2 = NULL; - outrem = NULL; - - if( nout > 2 ) { - noutrem = nout - 2; - outrem = astMalloc( noutrem*sizeof(int) ); - if( astOK ) { - ioutrem = 0; - for( iout = 0; iout < nout; iout++ ) { - if( iout != lonax && iout != latax ) outrem[ ioutrem++ ] = iout; - } - - astInvert( map ); - inax2 = astMapSplit( map, noutrem, outrem, &tmap2 ); - astInvert( map ); - if( tmap2 ) { - astInvert( tmap2 ); - } else { - ok = 0; - } - } - - } else if( nout != 2 || nin != 2 ) { - ok = 0; - } - -/* If the above tests were passed, transform the origin of IWC (the total map - output space) into grid coords. This gives CRPIX. */ - if( ok ) { - iwcxin = 0.0; - iwcyin = 0.0; - astTran2( smap, 1, &iwcxin, &iwcyin, 0, crpix, crpix + 1 ); - -/* Determine the CD matrix. We already know the upper Mapping is linear - because we have checked that it contains only linear atomic mappings. - So we can use fixed bounds for the fitting area safely. */ - lbnd[ 0 ] = -1.0; - lbnd[ 1 ] = -1.0; - ubnd[ 0 ] = 1.0; - ubnd[ 1 ] = 1.0; - if( !astLinearApprox( map_upper, lbnd, ubnd, 0.01, fit ) ) { - astError( AST__INTER, "%s(%s): SipIntWorld: Mapping " - "following PolyMap is not linear (internal " - "AST programming error).", status, method, - class ); - } - -/* Store the matrix elements in the required order. */ - cd[ 0 ] = fit[ 2 ]; - cd[ 1 ] = fit[ 3 ]; - cd[ 2 ] = fit[ 4 ]; - cd[ 3 ] = fit[ 5 ]; - -/* Store SIP headers describing first the forward then the inverse - transformation of the PolyMap in the FitsStore. Note, the axis indices - returned by astPolyCoeffs are 1-based. */ - for( fwd = 1; fwd >= 0; fwd-- ) { - if( ( fwd && astGetTranForward( polymap ) ) || - ( !fwd && astGetTranInverse( polymap ) ) ) { - astPolyCoeffs( polymap, fwd, 0, NULL, &ncoeff ); - coeffs = astMalloc( 4*ncoeff*sizeof(*coeffs) ); - if( astOK ) { - astPolyCoeffs( polymap, fwd, 4*ncoeff, coeffs, &ncoeff ); - -/* Find the maximum used power on each input axis. */ - aimax = 0; - ajmmax = 0; - bimax = 0; - bjmmax = 0; - pc = coeffs; - for( icoeff = 0; icoeff < ncoeff; icoeff++ ) { - if( inaxes[ 0 ] < inaxes [ 1 ] ) { - i = (int) ( pc[ 2 ] + 0.5 ); - jm = (int) ( pc[ 3 ] + 0.5 ); - if( pc[ 1 ] == 1 ) { - if( i > aimax ) aimax = i; - if( jm > ajmmax ) ajmmax = jm; - } else { - if( i > bimax ) bimax = i; - if( jm > bjmmax ) bjmmax = jm; - } - } else { - i = (int) ( pc[ 3 ] + 0.5 ); - jm = (int) ( pc[ 2 ] + 0.5 ); - if( pc[ 1 ] == 1 ) { - if( i > bimax ) bimax = i; - if( jm > bjmmax ) bjmmax = jm; - } else { - if( i > aimax ) aimax = i; - if( jm > ajmmax ) ajmmax = jm; - } - } - pc += 4; - } - -/* Initialise the arrays with bad values so that unused powers are not - included in the header. */ - - for( i = 0; i <= aimax; i++ ){ - for( jm = 0; jm <= ajmmax; jm++ ){ - SetItem( fwd? &(store->asip) : &(store->apsip), - i, jm, s, AST__BAD, status ); - } - } - - for( i = 0; i <= bimax; i++ ){ - for( jm = 0; jm <= bjmmax; jm++ ){ - SetItem( fwd? &(store->bsip) : &(store->bpsip), - i, jm, s, AST__BAD, status ); - } - } - -/* Over-write the bad values with real values for the powers that are - actually used. Reduce the coefficients of the linear terms by 1.0 - since the SIP distortion is an additive correction, rather than a direct - transformation. */ - pc = coeffs; - for( icoeff = 0; icoeff < ncoeff; icoeff++ ) { - if( inaxes[ 0 ] < inaxes [ 1 ] ) { - if( pc[ 1 ] == 1 ) { - item = fwd ? &(store->asip) : &(store->apsip); - } else { - item = fwd ? &(store->bsip) : &(store->bpsip); - } - i = (int) ( pc[ 2 ] + 0.5 ); - jm = (int) ( pc[ 3 ] + 0.5 ); - } else { - if( pc[ 1 ] == 1 ) { - item = fwd ? &(store->bsip) : &(store->bpsip); - } else { - item = fwd ? &(store->asip) : &(store->apsip); - } - i = (int) ( pc[ 3 ] + 0.5 ); - jm = (int) ( pc[ 2 ] + 0.5 ); - } - - val = pc[ 0 ]; - if( ( pc[ 1 ] == 1 && i == 1 && jm == 0 ) || - ( pc[ 1 ] == 2 && i == 0 && jm == 1 ) ){ - val -= 1.0; - } - if( val != 0.0 && val != AST__BAD ) { - SetItem( item, i, jm, s, val, status ); - } - pc += 4; - } - } - coeffs = astFree( coeffs ); - } - } - -/* Change the CTYPE value to indicate SIP distortion is in use. */ - cval = GetItemC( &(store->ctype), latax, 0, s, NULL, method, - class, status ); - if( cval ){ - strcpy( buf, cval ); - strcpy( buf + 8, "-SIP" ); - SetItemC( &(store->ctype), latax, 0, s, buf, status ); - } - - cval = GetItemC( &(store->ctype), lonax, 0, s, NULL, method, - class, status ); - if( cval ){ - strcpy( buf, cval ); - strcpy( buf + 8, "-SIP" ); - SetItemC( &(store->ctype), lonax, 0, s, buf, status ); - } - -/* Construct the returned Mapping. This is equivalent to the supplied - Mapping, but without the PolyMap. Use PermMaps at beginning and end to - take account of any axis permutations introduced by the operation of - astMapSplit. First put the 2D Mapping preceding the PolyMap in series - with the 2D Mapping following the PolyMap. */ - result = (AstMapping *) astCmpMap( map_lower, map_upper, 1, " ", status ); - -/* Now put the above Mapping in parallel with the mMapping that - transforms any additional axes. */ - if( tmap2 ) { - tmap = (AstMapping *) astCmpMap( result, tmap2, 0, " ", status ); - (void) astAnnul( result ); - result = tmap; - } - -/* Create a PermMap that permutes the outputs of the above Mapping back - into their original order. */ - inperm1 = astMalloc( nout*sizeof(int) ); - outperm1 = astMalloc( nout*sizeof(int) ); - inperm2 = astMalloc( nin*sizeof(int) ); - outperm2 = astMalloc( nin*sizeof(int) ); - if( astOK ) { - inperm1[ 0 ] = lonax; - inperm1[ 1 ] = latax; - outperm1[ lonax ] = 0; - outperm1[ latax ] = 1; - if( tmap2 ) { - for( iout = 0; iout < noutrem; iout++ ) { - inperm1[ iout + 2 ] = outrem[ iout ]; - outperm1[ outrem[ iout ] ] = iout + 2; - } - } - pm = astPermMap( nout, inperm1, nout, outperm1, - NULL, " ", status ); - -/* Put this PermMap in series with (following) the main Mapping created - above. */ - tmap = (AstMapping *) astCmpMap( result, pm, 1, " ", status ); - (void) astAnnul( result ); - pm = astAnnul( pm ); - result = tmap; - -/* Create a PermMap that permutes the inputs of the above Mapping back - into their original order. */ - outperm2[ 0 ] = inax1[ 0 ]; - outperm2[ 1 ] = inax1[ 1 ]; - inperm2[ inax1[ 0 ] ] = 0; - inperm2[ inax1[ 1 ] ] = 1; - - if( tmap2 ) { - for( iin = 0; iin < nin - 2; iin++ ) { - outperm2[ iin + 2 ] = inax2[ iin ]; - inperm2[ inax2[ iin ] ] = iin + 2; - } - } - - pm = astPermMap( nin, inperm2, nin, outperm2, - NULL, " ", status ); - -/* Put this PermMap in series with (preceding) the main Mapping created - above. */ - tmap = (AstMapping *) astCmpMap( pm, result, 1, " ", status ); - (void) astAnnul( result ); - pm = astAnnul( pm ); - result = tmap; - } - -/* Free resources. */ - inperm1 = astFree( inperm1 ); - inperm2 = astFree( inperm2 ); - outperm1 = astFree( outperm1 ); - outperm2 = astFree( outperm2 ); - } - - inax2 = astFree( inax2 ); - outrem = astFree( outrem ); - if( tmap2 ) tmap2 = astAnnul( tmap2 ); - if( map_lower ) map_lower = astAnnul( map_lower ); - if( map_upper ) map_upper = astAnnul( map_upper ); - } - - polymap = astAnnul( polymap ); - } - - for( imap = 0; imap < nmap; imap++ ) { - map_list[ imap ] = astAnnul( map_list[ imap ] ); - } - - invert_list = astFree( invert_list ); - map_list = astFree( map_list ); - inax1 = astFree( inax1 ); - smap = astAnnul( smap ); - } - if( tmap1 ) tmap1 = astAnnul( tmap1 ); - } - -/* Return the Mapping. */ - return result; -} - -static AstMapping *SIPMapping( AstFitsChan *this, double *dim, FitsStore *store, - char s, int naxes, const char *method, - const char *class, int *status ){ -/* -* Name: -* SIPMapping - -* Purpose: -* Create a Mapping descriping "-SIP" (Spitzer) distortion. - -* Type: -* Private function. - -* Synopsis: -* AstMapping *SIPMapping( AstFitsChan *this, double *dim, FitsStore *store, -* char s, int naxes, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function uses the values in the supplied FitsStore to create a -* Mapping which implements the "-SIP" distortion code. This is the - -* code used by the Spitzer project and is described in: -* -* http://irsa.ipac.caltech.edu/data/SPITZER/docs/files/spitzer/shupeADASS.pdf -* -* SIP distortion can only be applied to axes 0 and 1. Other axes are -* passed unchanged by the returned Mapping. - -* Parameters: -* this -* The FitsChan. -* dim -* The dimensions of the array in pixels. AST__BAD is stored for -* each value if dimensions are not known. -* store -* A structure containing information about the requested axis -* descriptions derived from a FITS header. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* naxes -* The number of intermediate world coordinate axes (WCSAXES). -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the Mapping. -*/ - -/* Local Variables: */ - AstMapping *ret; /* Pointer to the returned Mapping */ - AstPolyMap *pmap; /* PolyMap describing the distortion */ - AstPolyMap *pmap2; /* New PolyMap describing the distortion */ - double ****item; /* Address of FitsStore item to use */ - double *c; /* Pointer to start of coefficient description */ - double *coeff_f; /* Array of coeffs. for forward transformation */ - double *coeff_i; /* Array of coeffs. for inverse transformation */ - double cof; /* Coefficient value */ - double lbnd[ 2 ]; /* Lower bounds of fitted region */ - double ubnd[ 2 ]; /* Upper bounds of fitted region */ - int def; /* Is transformation defined? */ - int iin; /* Input (u or v) index */ - int iout; /* Output (U or V) index */ - int ncoeff_f; /* No. of coeffs. for forward transformation */ - int ncoeff_i; /* No. of coeffs. for inverse transformation */ - int p; /* Power of u or U */ - int pmax; /* Max power of u or U */ - int q; /* Power of v or V */ - int qmax; /* Max power of v or V */ - -/* Initialise the pointer to the returned Mapping. */ - ret = NULL; - -/* Check the global status. */ - if ( !astOK ) return ret; - -/* Store coefficients of the forward transformation: - ================================================ */ - -/* Indicate that we have as yet no coefficients for the forward polynomials. */ - ncoeff_f = 0; - -/* Indicate that we do not yet have any evidence that the forward - transformation is defined. */ - def = 0; - -/* Allocate workspace to hold descriptions of (initially) 20 coefficients used - within the forward polynomials. */ - coeff_f = astMalloc( sizeof( double )*20 ); - -/* Store the coefficients of the polynomial which produces each output - axis (U or V) in turn. */ - for( iout = 0; iout < 2; iout++ ){ - -/* Get a pointer to the FitsStore item holding the values defining this - output. */ - item = ( iout == 0 ) ? &(store->asip) : &(store->bsip); - -/* Get the largest powers used of u and v. */ - pmax = GetMaxI( item, s, status ); - qmax = GetMaxJM( item, s, status ); - -/* Loop round all combination of powers. */ - for( p = 0; p <= pmax; p++ ){ - for( q = 0; q <= qmax; q++ ){ - -/* Get the polynomial coefficient for this combination of powers. */ - cof = GetItem( item, p, q, s, NULL, method, class, status ); - -/* If there is no coefficient for this combination of powers, use a value - of zero. Otherwise indicate we have found at least one coefficient. */ - if( cof == AST__BAD ) { - cof = 0.0; - } else { - def = 1; - } - -/* The distortion polynomial gives a correction to be added on to the - input value. On the other hand, the returned Mapping is a direct - transformation from input to output. Therefore increment the coefficient - value by 1 for the term which corresponds to the current output axis. */ - if( p == ( 1 - iout ) && q == iout ) cof += 1.0; - -/* If the coefficient is not zero, store it in the array of coefficient - descriptions. */ - if( cof != 0.0 ) { - -/* Increment the number of coefficients for the forward polynomials. */ - ncoeff_f++; - -/* Ensure the "coeff_f" array is large enough to hold the new coefficient. */ - coeff_f = astGrow( coeff_f, sizeof( double )*4, ncoeff_f ); - if( astOK ) { - -/* Store it. Each coefficient is described by 4 values (since we have 2 - inputs to the Mapping). The first is the coefficient value, the second - is the (1-based) index of the output to which the coefficient relates. - The next is the power of input 0, and the last one is the power of input 1. */ - c = coeff_f + 4*( ncoeff_f - 1 ); - c[ 0 ] = cof; - c[ 1 ] = iout + 1; - c[ 2 ] = p; - c[ 3 ] = q; - } - } - } - } - } - -/* If no coefficients were supplied in the FitsStore, the forward - transformation is undefined. */ - if( !def ) ncoeff_f = 0; - -/* Store coefficients of the inverse transformation: - ================================================ */ - -/* Indicate that we have as yet no coefficients for the inverse polynomials. */ - ncoeff_i = 0; - -/* Indicate that we do not yet have any evidence that the forward - transformation is defined. */ - def = 0; - -/* Allocate workspace to hold descriptions of (initially) 20 coefficients used - within the inverse polynomials. */ - coeff_i = astMalloc( sizeof( double )*20 ); - -/* Store the coefficients of the polynomial which produces each input - axis (u or v) in turn. */ - for( iin = 0; iin < 2; iin++ ){ - -/* Get a pointer to the FitsStore item holding the values defining this - output. */ - item = ( iin == 0 ) ? &(store->apsip) : &(store->bpsip); - -/* Get the largest powers used of U and V. */ - pmax = GetMaxI( item, s, status ); - qmax = GetMaxJM( item, s, status ); - -/* Loop round all combination of powers. */ - for( p = 0; p <= pmax; p++ ){ - for( q = 0; q <= qmax; q++ ){ - -/* Get the polynomial coefficient for this combination of powers. */ - cof = GetItem( item, p, q, s, NULL, method, class, status ); - -/* If there is no coefficient for this combination of powers, use a value - of zero. Otherwise indicate we have found at least one coefficient. */ - if( cof == AST__BAD ) { - cof = 0.0; - } else { - def = 1; - } - -/* The distortion polynomial gives a correction to be added on to the - output value. On the other hand, the returned Mapping is a direct - transformation from output to input. Therefore increment the coefficient - value by 1 for the term which corresponds to the current input axis. */ - if( p == ( 1 - iin ) && q == iin ) cof += 1.0; - -/* If the coefficient is not zero, store it in the array of coefficient - descriptions. */ - if( cof != 0.0 ) { - -/* Increment the number of coefficients for the inverse polynomials. */ - ncoeff_i++; - -/* Ensure the "coeff_i" array is large enough to hold the new coefficient. */ - coeff_i = astGrow( coeff_i, sizeof( double )*4, ncoeff_i ); - if( astOK ) { - -/* Store it. Each coefficient is described by 4 values (since we have 2 - outputs to the Mapping). The first is the coefficient value, the second - is the (1-based) index of the input to which the coefficient relates. The - next is the power of output 0, and the last one is the power of output 1. */ - c = coeff_i + 4*( ncoeff_i - 1 ); - c[ 0 ] = cof; - c[ 1 ] = iin + 1; - c[ 2 ] = p; - c[ 3 ] = q; - } - } - } - } - } - -/* If no coefficients were supplied in the FitsStore, the forward - transformation is undefined. */ - if( !def ) ncoeff_i = 0; - -/* Create the returned Mapping: - ============================ */ - -/* If neither transformation is defined, create a UnitMap. */ - if( ncoeff_f == 0 && ncoeff_i == 0 ){ - ret = (AstMapping *) astUnitMap( naxes, "", status ); - -/* Otherwise, create a PolyMap to describe axes 0 and 1. */ - } else { - pmap = astPolyMap( 2, 2, ncoeff_f, coeff_f, ncoeff_i, coeff_i, "", status ); - -/* The inverse transformations supplied within SIP headers are often - inaccurate. So replace any existing inverse by sampling the supplied - transformation, and fitting a polynomial to the sampled positions. If - the fit fails to reach 0.01 pixel accuracy, forget it and rely on the - (slower) iterative inverse provided by the PolyMap class. Do the fit - over an area three times the size of the image to provide accurate - values outside the image. Only do this if it has not been disabled - using attribute SipReplace. */ - if( astGetSipReplace( this ) ) { - lbnd[ 0 ] = ( dim[ 0 ] != AST__BAD ) ? -dim[ 0 ] : -1000.0; - lbnd[ 1 ] = ( dim[ 1 ] != AST__BAD ) ? -dim[ 1 ] : -1000.0; - ubnd[ 0 ] = ( dim[ 0 ] != AST__BAD ) ? 2*dim[ 0 ] : 2000.0; - ubnd[ 1 ] = ( dim[ 1 ] != AST__BAD ) ? 2*dim[ 1 ] : 2000.0; - pmap2 = astPolyTran( pmap, (ncoeff_f == 0), 0.0001, 0.01, 7, lbnd, - ubnd ); - if( pmap2 ) { - (void) astAnnul( pmap ); - pmap = pmap2; - } else { - astSet( pmap, "IterInverse=1,NiterInverse=6,TolInverse=1.0E-8", - status ); - } - } - -/* Add the above Mapping in parallel with a UnitMap which passes any - other axes unchanged. */ - ret = AddUnitMaps( (AstMapping *) pmap, 0, naxes, status ); - pmap = astAnnul( pmap ); - } - -/* Free resources. */ - coeff_f = astFree( coeff_f ); - coeff_i = astFree( coeff_i ); - -/* Return the result. */ - return ret; -} - -static void SkyPole( AstWcsMap *map2, AstMapping *map3, int ilon, int ilat, - int *wperm, char s, FitsStore *store, const char *method, - const char *class, int *status ){ -/* -* Name: -* SkyPole - -* Purpose: -* Put values for FITS keywords LONPOLE and LATPOLE into a FitsStore. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void SkyPole( AstWcsMap *map2, AstMapping *map3, int ilon, int ilat, -* int *wperm, char s, FitsStore *store, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function calculates values for the LONPOLE and LATPOLE FITS -* keywords and stores them in the supplied FitsStore. LONPOLE and -* LATPOLE are the longitude and latitude of the celestial north pole -* in native spherical coordinates. - -* Parameters: -* map2 -* Pointer to the Mapping from Intermediate World Coordinates to Native -* Spherical Coordinates. -* map3 -* Pointer to the Mapping from Native Spherical Coordinates to celestial -* coordinates. -* ilon -* Zero-based index of longitude output from "map3". -* ilat -* Zero-based index of latitude output from "map3". -* wperm -* Pointer to an array of integers with one element for each axis of -* the current Frame. Each element holds the zero-based -* index of the FITS-WCS axis (i.e. the value of "i" in the keyword -* names "CTYPEi", "CRVALi", etc) which describes the Frame axis. -* s -* The co-ordinate version character. A space means the primary -* axis descriptions. Otherwise the supplied character should be -* an upper case alphabetical character ('A' to 'Z'). -* store -* The FitsStore in which to store the FITS WCS keyword values. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* PointSet holding intermediate wcs coords */ - AstPointSet *pset2; /* PointSet holding final WCS coords */ - double **ptr1; /* Pointer to coordinate data */ - double **ptr2; /* Pointer to coordinate data */ - double alpha0; /* Long. of fiducial point in standard system */ - double alphap; /* Celestial longitude of native north pole */ - double deflonpole; /* Default value for lonpole */ - double delta0; /* Lat. of fiducial point in standard system */ - double latpole; /* Native latitude of celestial north pole */ - double lonpole; /* Native longitude of celestial north pole */ - double phi0; /* Native longitude at fiducial point */ - double theta0; /* Native latitude at fiducial point */ - int axlat; /* Index of latitude output from "map2" */ - int axlon; /* Index of longitude output from "map2" */ - int fits_ilat; /* FITS WCS axis index for latitude axis */ - int fits_ilon; /* FITS WCS axis index for longitude axis */ - int iax; /* Axis index */ - int nax; /* Number of IWC axes */ - int nax2; /* Number of WCS axes */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Store the indices of the native longitude and latitude outputs of the - WcsMap. */ - axlon = astGetWcsAxis( map2, 0 ); - axlat = astGetWcsAxis( map2, 1 ); - -/* Store the indices of the FITS WCS axes for longitude and latitude */ - fits_ilon = wperm[ ilon ]; - fits_ilat = wperm[ ilat ]; - -/* To find the longitude and latitude of the celestial north pole in native - spherical coordinates, we will transform the coords of the celestial north - pole into spherical cords using the inverse of "map2", and if the resulting - native spherical coords differ from the default values of LONPOLE and - LATPOLE, we store them in the FitsStore. However, for zenithal projections, - any value can be used simply by introducing an extra rotation into the - (X,Y) projection plane. If values have been set in the WcsMap (as - projection parameters PVi_3 and PVi_4 for longitude axis "i") uses - them. Otherwise, set the values bad to indicate that the default values - should be used. Note, these projection parameters are used for other - purposes in a TPN projection. */ - lonpole = AST__BAD; - latpole = AST__BAD; - if( astIsZenithal( map2 ) ) { - if( astGetWcsType( map2 ) != AST__TPN ) { - lonpole = astTestPV( map2, axlon, 3 ) ? astGetPV( map2, axlon, 3 ) - : AST__BAD; - latpole = astTestPV( map2, axlon, 4 ) ? astGetPV( map2, axlon, 4 ) - : AST__BAD; - } - -/* For non-zenithal projections, do the full calculation. */ - } else { - -/* Allocate resources. */ - nax = astGetNin( map2 ); - pset1 = astPointSet( 1, nax, "", status ); - ptr1 = astGetPoints( pset1 ); - nax2 = astGetNout( map3 ); - pset2 = astPointSet( 1, nax2, "", status ); - ptr2 = astGetPoints( pset2 ); - if( astOK ) { - -/* Calculate the longitude and latitude of the celestial north pole - in native spherical coordinates (using the inverse of map3). These - values correspond to the LONPOLE and LATPOLE keywords. */ - for( iax = 0; iax < nax2; iax++ ) ptr2[ iax ][ 0 ] = 0.0; - ptr2[ ilat ][ 0 ] = AST__DPIBY2; - (void) astTransform( map3, pset2, 0, pset1 ); - -/* Retrieve the latitude and longitude (in the standard system) of the - fiducial point (i.e. CRVAL), in radians. */ - delta0 = GetItem( &(store->crval), fits_ilat, 0, s, NULL, method, class, status ); - if( delta0 == AST__BAD ) delta0 = 0.0; - delta0 *= AST__DD2R; - alpha0 = GetItem( &(store->crval), fits_ilon, 0, s, NULL, method, class, status ); - if( alpha0 == AST__BAD ) alpha0 = 0.0; - alpha0 *= AST__DD2R; - -/* The default value of the LATPOLE is defined by equation 8 of FITS-WCS - paper II (taking the +ve signs). Find this value. */ - if( WcsNatPole( NULL, map2, alpha0, delta0, 999.0, ptr1[ axlon ], - &alphap, &latpole, status ) ){ - -/* If the default value is defined, compare it to the latitude of the - north pole found above. If they are equal use a bad value instead to - prevent an explicit keyword from being added to the FitsChan. */ - if( EQUALANG( ptr1[ axlat ][ 0 ], latpole ) ) { - latpole = AST__BAD; - } else { - latpole = ptr1[ axlat ][ 0 ]; - } - -/* If the default value is not defined, always store an explicit LATPOLE - value. */ - } else { - latpole = ptr1[ axlat ][ 0 ]; - } - -/* The default LONPOLE value is zero if the celestial latitude at the - fiducial point is greater than or equal to the native latitude at the - fiducial point. Otherwise, the default is (+ or -) 180 degrees. If LONPOLE - takes the default value, replace it with AST__BAD to prevent an explicit - keyword being stored in the FitsChan. */ - GetFiducialNSC( map2, &phi0, &theta0, status ); - lonpole = palDranrm( ptr1[ axlon ][ 0 ] ); - if( delta0 >= theta0 ){ - deflonpole = 0.0; - } else { - deflonpole = AST__DPI; - } - if( EQUALANG( lonpole, deflonpole ) ) lonpole = AST__BAD; - } - -/* Convert from radians to degrees. */ - if( lonpole != AST__BAD ) lonpole *= AST__DR2D; - if( latpole != AST__BAD ) latpole *= AST__DR2D; - -/* Free resources. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - } - -/* Store these values. */ - SetItem( &(store->lonpole), 0, 0, s, lonpole, status ); - SetItem( &(store->latpole), 0, 0, s, latpole, status ); - -/* FITS-WCS paper 2 recommends putting a copy of LONPOLE and LATPOLE in - projection parameters 3 and 4 associated with the longitude axis. Only do - this if the projection is not TPN (since this projection uses these - parameters for other purposes). */ - if( astGetWcsType( map2 ) != AST__TPN ) { - SetItem( &(store->pv), fits_ilon, 3, s, lonpole, status ); - SetItem( &(store->pv), fits_ilon, 4, s, latpole, status ); - } -} - -static int SkySys( AstFitsChan *this, AstSkyFrame *skyfrm, int wcstype, - int wcsproj, FitsStore *store, int axlon, int axlat, char s, - int isoff, const char *method, const char *class, int *status ){ -/* -* Name: -* SkySys - -* Purpose: -* Return FITS-WCS values describing a sky coordinate system. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int SkySys( AstFitsChan *this, AstSkyFrame *skyfrm, int wcstype, -* int wcsproj, FitsStore *store, int axlon, int axlat, char s, -* int isoff, const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function sets values for the following FITS-WCS keywords -* within the supplied FitsStore structure: CTYPE, CNAME, RADESYS, EQUINOX, -* MJDOBS, CUNIT, OBSGEO-X/Y/Z. The values are derived from the supplied -* SkyFrame and WcsMap. - -* Parameters: -* this -* Pointer to the FitsChan. -* skyfrm -* A pointer to the SkyFrame to be described. -* wcstype -* The type of WCS: 0 = TAB, 1 = WcsMap projection. -* wcsproj -* An identifier for the type of WCS projection to use. Should be -* one of the values defined by the WcsMap class. Only used if "wcstype" -* is 1. -* store -* A pointer to the FitsStore structure in which to store the -* results. -* axlon -* The index of the FITS WCS longitude axis (i.e. the value of "i" -* in "CTYPEi"). -* axlat -* The index of the FITS WCS latitude axis (i.e. the value of "i" -* in "CTYPEi"). -* s -* Co-ordinate version character. -* isoff -* If greater than zero, the description to add to the FitsStore -* should describe offset coordinates. If less than zero, the -* description to add to the FitsStore should describe absolute -* coordinates but should include the SkyRefIs, SkyRef and SkyRefP -* attributes. If zero, ignore all offset coordinate info. The -* absolute value indicates the nature of the reference point: -* 1 == "pole", 2 == "origin", otherwise "ignored". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Are the keywords values in the FitsStore usable? -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *label; /* Pointer to axis label string */ - char attr[20]; /* Buffer for AST attribute name */ - char com[80]; /* Buffer for keyword comment */ - char lattype[MXCTYPELEN];/* Latitude axis CTYPE value */ - char lontype[MXCTYPELEN];/* Longitude axis CTYPE value */ - const char *latsym; /* SkyFrame latitude axis symbol */ - const char *lonsym; /* SkyFrame longitude axis symbol */ - const char *prj_name; /* Pointer to projection name string */ - const char *skyref; /* Formatted SkyRef position */ - const char *skyrefis; /* SkyRefIs value */ - const char *sys; /* Celestal coordinate system */ - const char *timesys; /* Timescale specified in FitsChan */ - double ep; /* Epoch of observation in required timescale (MJD) */ - double ep_tdb; /* Epoch of observation in TDB timescale (MJD) */ - double ep_utc; /* Epoch of observation in UTC timescale (MJD) */ - double eq; /* Epoch of reference equinox (MJD) */ - double geolat; /* Geodetic latitude of observer (radians) */ - double geolon; /* Geodetic longitude of observer (radians) */ - double h; /* Geodetic altitude of observer (metres) */ - double skyref_lat; /* SkyRef latitude value (rads) */ - double skyrefp_lat; /* SkyRefP latitude value (rads) */ - double skyref_lon; /* SkyRef longitude value (rads) */ - double skyrefp_lon; /* SkyRefP longitude value (rads) */ - double xyz[3]; /* Geocentric position vector (in m) */ - int defdate; /* Can the date keywords be defaulted? */ - int i; /* Character count */ - int isys; /* Celestial coordinate system */ - int latax; /* Index of latitude axis in SkyFrame */ - int lonax; /* Index of longitude axis in SkyFrame */ - int ok; /* Do axis symbols conform to FITS-WCS CTYPE form? */ - int old_ignore_used; /* Original setting of external ignore_used variable */ - int ret; /* Returned flag */ - -/* Check the status. */ - if( !astOK ) return 0; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Check we have a SkyFrame. */ - if( !IsASkyFrame( skyfrm ) ) return 0; - -/* Initialise */ - ret = 1; - -/* Get the equinox, epoch of observation, and system of the SkyFrame. The epoch - is in TDB. It is assumed the Equinox is in UTC. */ - eq = astGetEquinox( skyfrm ); - sys = astGetC( skyfrm, "system" ); - ep_tdb = astTestEpoch( skyfrm ) ? astGetEpoch( skyfrm ) : AST__BAD; - -/* Convert the epoch to UTC. */ - ep_utc = TDBConv( ep_tdb, AST__UTC, 1, method, class, status ); - -/* See if the FitsChan contains a value for the TIMESYS keyword (include - previously used cards in the search). If so, and if it is not UTC, convert - the epoch to the specified time scale, and store a TIMESYS value in the - FitsStore. */ - old_ignore_used = ignore_used; - ignore_used = 0; - if( GetValue( this, "TIMESYS", AST__STRING, (void *) ×ys, 0, 0, method, - class, status ) && strcmp( timesys, "UTC" ) ) { - ep = TDBConv( ep_tdb, TimeSysToAst( this, timesys, method, class, - status ), - 1, method, class, status ); - SetItemC( &(store->timesys), 0, 0, s, timesys, status ); - -/* If no TIMESYS keyword was found in the FitsChan, or the timesys was - UTC, we use the UTC epoch value found above. In this case no TIMESYS value - need be stored in the FitsSTore since UTC is the default for TIMESYS. */ - } else { - ep = ep_utc; - } - -/* Reinstate the original value for the flag that indicates whether keywords - in the FitsChan that have been used previously should be ignored. */ - ignore_used = old_ignore_used; - -/* The MJD-OBS and DATE-OBS keywords default to the epoch of the - reference equinox if not supplied. Therefore MJD-OBS and DATE-OBS do - not need to be stored in the FitsChan if the epoch of observation is - the same as the epoch of the reference equinox. This can avoid - producing FITS headers which say unlikely things like - DATE-OBS = "01/01/50". Set a flag indicating if MJD-OBS and DATE-OBS - can be defaulted. */ - defdate = astEQUAL( ep_utc, eq ); - -/* Convert the equinox to a Julian or Besselian epoch. Also get the - reference frame and standard system. */ - if( !Ustrcmp( sys, "FK4", status ) ){ - eq = palEpb( eq ); - isys = RADEC; - SetItemC( &(store->radesys), 0, 0, s, "FK4", status ); - } else if( !Ustrcmp( sys, "FK4_NO_E", status ) || !Ustrcmp( sys, "FK4-NO-E", status ) ){ - eq = palEpb( eq ); - isys = RADEC; - SetItemC( &(store->radesys), 0, 0, s, "FK4-NO-E", status ); - } else if( !Ustrcmp( sys, "FK5", status ) ){ - eq = palEpj( eq ); - isys = RADEC; - SetItemC( &(store->radesys), 0, 0, s, "FK5", status ); - } else if( !Ustrcmp( sys, "ICRS", status ) ){ - eq = AST__BAD; - isys = RADEC; - SetItemC( &(store->radesys), 0, 0, s, "ICRS", status ); - } else if( !Ustrcmp( sys, "GAPPT", status ) || - !Ustrcmp( sys, "Apparent", status ) || - !Ustrcmp( sys, "Geocentric", status ) ){ - eq = AST__BAD; - isys = RADEC; - SetItemC( &(store->radesys), 0, 0, s, "GAPPT", status ); - } else if( !Ustrcmp( sys, "Helioecliptic", status ) ){ - eq = AST__BAD; - isys = HECLIP; - } else if( !Ustrcmp( sys, "Galactic", status ) ){ - eq = AST__BAD; - isys = GALAC; - } else if( !Ustrcmp( sys, "Supergalactic", status ) ){ - eq = AST__BAD; - isys = SUPER; - } else if( !Ustrcmp( sys, "AzEl", status ) ){ - eq = AST__BAD; - isys = AZEL; - } else { - eq = AST__BAD; - isys = NOCEL; - } - -/* Store these values. Only store the date if it does not take its - default value. */ - SetItem( &(store->equinox), 0, 0, s, eq, status ); - if( !defdate ) SetItem( &(store->mjdobs), 0, 0, ' ', ep, status ); - -/* Only proceed if we have usable values */ - if( astOK ) { - -/* Get the indices of the latitude and longitude axes within the - SkyFrame. */ - latax = astGetLatAxis( skyfrm ); - lonax = 1 - latax; - -/* The first 4 characters in CTYPE are determined by the celestial coordinate - system and the second 4 by the projection type. If we are describing - offset coordinates, then use "OFLN" and "OFLT. Otherwise use the - standard FITS-WCS name of the system. */ - if( isoff > 0 ){ - strcpy( lontype, "OFLN" ); - strcpy( lattype, "OFLT" ); - } else if( isys == RADEC ){ - strcpy( lontype, "RA--" ); - strcpy( lattype, "DEC-" ); - } else if( isys == ECLIP ){ - strcpy( lontype, "ELON" ); - strcpy( lattype, "ELAT" ); - } else if( isys == HECLIP ){ - strcpy( lontype, "HLON" ); - strcpy( lattype, "HLAT" ); - } else if( isys == GALAC ){ - strcpy( lontype, "GLON" ); - strcpy( lattype, "GLAT" ); - } else if( isys == SUPER ){ - strcpy( lontype, "SLON" ); - strcpy( lattype, "SLAT" ); - } else if( isys == AZEL ){ - strcpy( lontype, "AZ--" ); - strcpy( lattype, "EL--" ); - -/* For unknown systems, use the axis symbols within CTYPE if they conform - to the requirement of FITS-WCS (i.e. "xxLN/xxLT" or "xLON/xLAT") or use - "UNLN/UNLT" otherwise. */ - } else { - latsym = astGetSymbol( skyfrm, latax ); - lonsym = astGetSymbol( skyfrm, lonax ); - if( astOK ) { - - ok = 0; - if( strlen( latsym ) == 4 && strlen( lonsym ) == 4 ) { - if( !strcmp( latsym + 2, "LT" ) && - !strcmp( lonsym + 2, "LN" ) && - !strncmp( latsym, lonsym, 2 ) ) { - ok = 1; - } else if( !strcmp( latsym + 1, "LAT" ) && - !strcmp( lonsym + 1, "LON" ) && - !strncmp( latsym, lonsym, 1 ) ) { - ok = 1; - } - } - - if( !ok ) { - latsym = "UNLT"; - lonsym = "UNLN"; - } - - strncpy( lontype, lonsym, 4 ); - for( i = strlen( lonsym ); i < 4; i++ ) { - lontype[ i ] = '-'; - } - strncpy( lattype, latsym, 4 ); - for( i = strlen( latsym ); i < 4; i++ ) { - lattype[ i ] = '-'; - } - } - } - -/* Store the projection strings. */ - prj_name = ( wcstype == 0 ) ? "-TAB" : astWcsPrjName( wcsproj ); - if( astOK ) { - strcpy( lontype + 4, prj_name ); - strcpy( lattype + 4, prj_name ); - } - -/* Store the total CTYPE strings */ - SetItemC( &(store->ctype), axlon, 0, s, lontype, status ); - SetItemC( &(store->ctype), axlat, 0, s, lattype, status ); - -/* Store offset coord information. */ - if( isoff ) { - -/* If the description is for offset coords store suitable comments for - the CTYPE keywords. */ - if( isoff > 0 ) { - skyref = astGetC( skyfrm, "SkyRef" ); - - sprintf( attr, "Symbol(%d)", axlon + 1 ); - sprintf( com, "%s offset from %s",astGetC( skyfrm, attr )+1, skyref ); - SetItemC( &(store->ctype_com), axlon, 0, s, com, status ); - - sprintf( attr, "Symbol(%d)", axlat + 1 ); - sprintf( com, "%s offset from %s",astGetC( skyfrm, attr )+1, skyref ); - SetItemC( &(store->ctype_com), axlat, 0, s, com, status ); - -/* If the description is for absolute coords store the SkyFrame attribute - values in AST-specific keywords. */ - } else { - sprintf( attr, "SkyRef(%d)", axlon + 1 ); - skyref_lon = astGetD( skyfrm, attr ); - sprintf( attr, "SkyRef(%d)", axlat + 1 ); - skyref_lat = astGetD( skyfrm, attr ); - - sprintf( attr, "SkyRefP(%d)", axlon + 1 ); - skyrefp_lon = astGetD( skyfrm, attr ); - sprintf( attr, "SkyRefP(%d)", axlat + 1 ); - skyrefp_lat = astGetD( skyfrm, attr ); - - skyrefis = (isoff < -2) ? "IGNORED" : - ( (isoff < -1) ? "ORIGIN" : "POLE" ); - - SetItemC( &(store->skyrefis), 0, 0, s, skyrefis, status ); - if( astTest( skyfrm, "SkyRef(1)" ) ) { - SetItem( &(store->skyref), axlon, 0, s, skyref_lon, status ); - SetItem( &(store->skyref), axlat, 0, s, skyref_lat, status ); - } - if( astTest( skyfrm, "SkyRefP(1)" ) ) { - SetItem( &(store->skyrefp), axlon, 0, s, skyrefp_lon, status ); - SetItem( &(store->skyrefp), axlat, 0, s, skyrefp_lat, status ); - } - } - } - -/* If the Label attribute has been set for an axis, use it as the CTYPE - comment and CNAME value. */ - if( astTestLabel( skyfrm, latax ) ) { - label = (char *) astGetLabel( skyfrm, latax ); - SetItemC( &(store->ctype_com), axlat, 0, s, label, status ); - SetItemC( &(store->cname), axlat, 0, s, label, status ); - } - if( astTestLabel( skyfrm, lonax ) ) { - label = (char *) astGetLabel( skyfrm, lonax ); - SetItemC( &(store->ctype_com), axlon, 0, s, label, status ); - SetItemC( &(store->cname), axlon, 0, s, label, status ); - } - -/* Nullify any CUNITS strings for the longitude and latitude axes (they - always take the default value of degrees). */ - SetItemC( &(store->cunit), axlat, 0, s, NULL, status ); - SetItemC( &(store->cunit), axlon, 0, s, NULL, status ); - } - -/* Store the Domain name as the WCSNAME keyword (if set). */ - if( astTestDomain( skyfrm ) ) { - SetItemC( &(store->wcsname), 0, 0, s, (char *) astGetDomain( skyfrm ), status ); - } - -/* Store the observer's position if set (needed for definition of AzEl - systems). */ - if( astTestObsLon( skyfrm ) && astTestObsLat( skyfrm ) && s == ' ' ) { - geolon = astGetObsLon( skyfrm ); - geolat = astGetObsLat( skyfrm ); - h = astGetObsAlt( skyfrm ); - if( geolat != AST__BAD && geolon != AST__BAD && h != AST__BAD ) { - eraGd2gc( 1, geolon, geolat, h, xyz ); - SetItem( &(store->obsgeox), 0, 0, ' ', xyz[0], status ); - SetItem( &(store->obsgeoy), 0, 0, ' ', xyz[1], status ); - SetItem( &(store->obsgeoz), 0, 0, ' ', xyz[2], status ); - } - } - if( !astOK ) ret = 0; - return ret; -} - -static char *SourceWrap( const char *(* source)( void ), int *status ) { -/* -* Name: -* SourceWrap - -* Purpose: -* Wrapper function to invoke a C FitsChan source function. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* char *SourceWrap( const char *, int *status(* source)( void ) ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function invokes the source function whose pointer is -* supplied in order to read the next input line from an external -* data store. It then returns a pointer to a dynamic string -* containing a copy of the text that was read. - -* Parameters: -* source -* Pointer to a source function, with no parameters, that -* returns a pointer to a const, null-terminated string -* containing the text that it read. This is the form of FitsChan -* source function employed by the C language interface to the -* AST library. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated, null terminated string -* containing a copy of the text that was read. This string must be -* freed by the caller (using astFree) when no longer required. -* -* A NULL pointer will be returned if there is no more input text -* to read. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - char *result; /* Pointer value to return */ - const char *line; /* Pointer to input line */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the source function to read the next input line and return a - pointer to the resulting string. */ - line = ( *source )(); - -/* If a string was obtained, make a dynamic copy of it and save the - resulting pointer. */ - if ( line ) result = astString( line, (int) strlen( line ) ); - -/* Return the result. */ - return result; -} - -static AstMapping *SpectralAxes( AstFitsChan *this, AstFrameSet *fs, - double *dim, int *wperm, - char s, FitsStore *store, double *crvals, - int *axis_done, const char *method, - const char *class, int *status ){ - -/* -* Name: -* SpectralAxes - -* Purpose: -* Add values to a FitsStore describing spectral axes in a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* AstMapping *SpectralAxes( AstFitsChan *this, AstFrameSet *fs, -* double *dim, int *wperm, -* char s, FitsStore *store, double *crvals, -* int *axis_done, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The current Frame of the supplied FrameSet is searched for spectral -* axes. If any are found, FITS WCS keyword values describing the axis -* are added to the supplied FitsStore, if possible (the conventions -* of FITS-WCS paper III are used). Note, this function does not store -* values for keywords which define the transformation from pixel -* coords to Intermediate World Coords (CRPIX, PC and CDELT), but a -* Mapping is returned which embodies these values. This Mapping is -* from the current Frame in the FrameSet (WCS coords) to a Frame -* representing IWC. The IWC Frame has the same number of axes as the -* WCS Frame which may be greater than the number of base Frame (i.e. -* pixel) axes. -* -* If a spectral axis is found, the RafRA and RefDec attributes of the -* SpecFrame describing the axis are ignored: it is assumed that the -* WCS Frame also contains a pair of celestial axes which will result -* in appropriate celestial reference values being stored in the -* FitsStore (this asumption should be enforced by calling function -* MakeFitsFrameSet prior to calling this function). - -* Parameters: -* this -* Pointer to the FitsChan. -* fs -* Pointer to the FrameSet. The base Frame should represent FITS pixel -* coordinates, and the current Frame should represent FITS WCS -* coordinates. The number of base Frame axes should not exceed the -* number of current Frame axes. The spectral Unit in the returned -* FrameSet will always be linearly related to the default Units for -* the spectral System in use by the axis. If this requires a -* change to the existing spectral Unit, the integrity of the -* FrameSet will be maintained by suitable adjustments to the Mappings -* within the FrameSet. -* dim -* An array holding the image dimensions in pixels. AST__BAD can be -* supplied for any unknwon dimensions. -* wperm -* Pointer to an array of integers with one element for each axis of -* the current Frame. Each element holds the zero-based -* index of the FITS-WCS axis (i.e. one les than the value of "i" in -* the keyword names "CTYPEi", "CRVALi", etc) which describes the -* Frame axis. -* s -* The co-ordinate version character. A space means the primary -* axis descriptions. Otherwise the supplied character should be -* an upper case alphabetical character ('A' to 'Z'). -* store -* The FitsStore in which to store the FITS WCS keyword values. -* crvals -* Pointer to an array holding the default CRVAL value for each -* axis in the WCS Frame. -* axis_done -* An array of flags, one for each Frame axis, which indicate if a -* description of the corresponding axis has yet been stored in the -* FitsStore. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If a spectral axis was found which can be described using the -* conventions of FITS-WCS paper III, then a Mapping from the current Frame -* of the supplied FrameSet, to the IWC Frame is returned. Otherwise, -* a UnitMap is returned. Note, the Mapping only defines the IWC -* transformation for spectral axes. Any non-spectral axes are passed -* unchanged by the returned Mapping. -*/ - -/* Local Variables: */ - AstFitsTable *table; /* Pointer to structure holding -TAB table info */ - AstFrame *pframe; /* Primary Frame containing current WCS axis*/ - AstFrame *tfrm1; /* A temporary Frame */ - AstFrame *tfrm; /* A temporary Frame */ - AstFrame *wcsfrm; /* WCS Frame within FrameSet */ - AstFrameSet *tfs; /* A temporary FrameSet */ - AstGrismMap *gmap; /* GrismMap defining the spectral axis */ - AstMapping *axmap; /* Mapping from WCS to IWC */ - AstMapping *map; /* Pixel -> WCS mapping */ - AstMapping *ret; /* Returned Mapping */ - AstMapping *tmap0; /* A temporary Mapping */ - AstMapping *tmap1; /* A temporary Mapping */ - AstMapping *tmap2; /* A temporary Mapping */ - AstMapping *tmap3; /* A temporary Mapping */ - AstMapping *tmap4; /* A temporary Mapping */ - AstMapping *tmap5; /* A temporary Mapping */ - AstMapping *tmap6; /* A temporary Mapping */ - AstPermMap *pm; /* PermMap pointer */ - AstSpecFrame *specfrm; /* The SpecFrame defining current WCS axis */ - char *cname; /* Pointer to CNAME value */ - char ctype[ MXCTYPELEN ]; /* The value for the FITS CTYPE keyword */ - char lin_unit[ 20 ]; /* Linear spectral Units being used */ - char orig_system[ 40 ]; /* Value of System attribute for current WCS axis */ - char system_attr[ 10 ]; /* Name of System attribute for current WCS axis */ - char unit_attr[ 10 ]; /* Name of Unit attribute for current WCS axis */ - const char *cval; /* Pointer to temporary character string */ - const char *x_sys[ 4 ]; /* Basic spectral systems */ - double *lbnd_p; /* Pointer to array of lower pixel bounds */ - double *ubnd_p; /* Pointer to array of upper pixel bounds */ - double crval; /* The value for the FITS CRVAL keyword */ - double dgbyds; /* Rate of change of grism parameter wrt "S" at ref. point */ - double dsbydx; /* Rate of change of "S" wrt "X" at ref. point */ - double geolat; /* Geodetic latitude of observer (radians) */ - double geolon; /* Geodetic longitude of observer (radians) */ - double gval; /* Value of grism parameter at reference point */ - double h; /* Geodetic altitude of observer (metres) */ - double imagfreq; /* Image sideband equivalent to the rest frequency (Hz) */ - double lbnd_s; /* Lower bound on spectral axis */ - double pv; /* Value of projection parameter */ - double restfreq; /* Rest frequency (Hz) */ - double ubnd_s; /* Upper bound on spectral axis */ - double vsource; /* Rel.vel. of source (m/s) */ - double xval; /* Value of "X" system at reference point */ - double xyz[3]; /* Geocentric position vector (in m) */ - double zsource; /* Redshift of source */ - int *inperm; /* Pointer to permutation array for input axes */ - int *outperm; /* Pointer to permutation array for output axes */ - int extver; /* Table version number for -TAB headers */ - int fits_i; /* FITS WCS axis index for current WCS axis */ - int iax; /* Axis index */ - int icolindex; /* Index of table column holding index vector */ - int icolmain; /* Index of table column holding main coord array */ - int interp; /* INterpolation method for look-up tables */ - int ix; /* System index */ - int j; /* Loop count */ - int npix; /* Number of pixel axes */ - int nwcs; /* Number of WCS axes */ - int paxis; /* Axis index within primary Frame */ - int sourcevrf; /* Rest Frame in which SourceVel is accesed */ - -/* Initialise */ - ret = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Every supported spectral system is linearly related to one of the - following four systems. */ - x_sys[ 0 ] = "FREQ"; - x_sys[ 1 ] = "WAVE"; - x_sys[ 2 ] = "AWAV"; - x_sys[ 3 ] = "VELO"; - -/* Get a pointer to the WCS Frame. */ - wcsfrm = astGetFrame( fs, AST__CURRENT ); - -/* Store the number of pixel and WCS axes. */ - npix = astGetNin( fs ); - nwcs = astGetNout( fs ); - -/* Store the upper and lower pixel bounds. */ - lbnd_p = astMalloc( sizeof( double )*(size_t) npix ); - ubnd_p = astMalloc( sizeof( double )*(size_t) npix ); - if( astOK ) { - for( iax = 0; iax < npix; iax++ ) { - lbnd_p[ iax ] = 1.0; - ubnd_p[ iax ] = ( dim[ iax ] != AST__BAD ) ? dim[ iax ] : 500; - } - } - -/* Check each axis in the WCS Frame to see if it is a spectral axis. */ - axmap = NULL; - for( iax = 0; iax < nwcs; iax++ ) { - -/* Obtain a pointer to the primary Frame containing the current WCS axis. */ - astPrimaryFrame( wcsfrm, iax, &pframe, &paxis ); - -/* If the current axis belongs to a SpecFrame, we have found a spectral - axis. */ - if( astIsASpecFrame( pframe ) ) { - specfrm = (AstSpecFrame *) pframe; - -/* Note the (zero-based) FITS WCS axis index to be used for the current - Frame axis. */ - fits_i = wperm[ iax ]; - -/* Note the name and original value of the System attribute for the spectral - axis within the FrameSet current Frame. */ - sprintf( system_attr, "System(%d)", iax + 1 ); - cval = astGetC( wcsfrm, system_attr ); - if( cval ) strcpy( orig_system, cval ); - -/* Note the name of the Unit attribute for the spectral axis within the - FrameSet current Frame. */ - sprintf( unit_attr, "Unit(%d)", iax + 1 ); - -/* Get a pointer to the Mapping from FITS pixel coordinates to SpecFrame. */ - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - -/* Find the bounds of the Spectral axis over the volume of the pixel grid. */ - astMapBox( map, lbnd_p, ubnd_p, 1, iax, &lbnd_s, &ubnd_s, - NULL, NULL ); - -/* The Unit attribute of a SpecFrame can be set to arbitrary non-linear - functions of standard linear spectral units. FITS-WCS paper III requires - CRVAL etc to be given in linear units. So first we ensure that we have a - SpecFrame with linear Units. Create a copy of the SpecFrame and clear - its Unit attribute (this ensures the copy has the default linear units). - Then find a Mapping from the original spectral units to the default - linear units. If the conversion is possible, see if the Mapping - between the units is linear. If it is, then the original Unit attribute - of the SpecFrame is OK (i.e. the units are linear). If not, clear - the Unit attribute of the spectral axis in the FrameSet so that it - uses the default linear units (retaining the original value so that it - can be re-instated later). Using the clear method on the FrameSet - pointer rather than the SpecFrame pointer causes the SpecFrame to be - re-mapped within the FrameSet to maintain its correct relationship with - the other Frames in the FrameSet. Also update the pixel->spectrum - Mapping to take account of the change in units and re-calculate the new - bounds on the spectral axis. Also update any supplied CRVAL value for - the spectral axis. */ - tfrm = astCopy( specfrm ); - astClearUnit( tfrm, 0 ); - tfs = astConvert( specfrm, tfrm, "" ); - tfrm = astAnnul( tfrm ); - if( tfs ) { - crval = crvals ? crvals[ iax ] : AST__BAD; - tmap1 = astGetMapping( tfs, AST__BASE, AST__CURRENT ); - tfs = astAnnul( tfs ); - if( !IsMapLinear( tmap1, &lbnd_s, &ubnd_s, 0, status ) ) { - astClear( fs, unit_attr ); - (void) astAnnul( map ); - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - astMapBox( map, lbnd_p, ubnd_p, 1, iax, &lbnd_s, &ubnd_s, - NULL, NULL ); - astTran1( tmap1, 1, &crval, 1, &crval ); - } - tmap1 = astAnnul( tmap1 ); - -/* Note the linear spectral Unit currently in use. */ - cval = astGetUnit( specfrm, 0 ); - if( cval ) strcpy( lin_unit, cval ); - -/* For some of the algorithms, the reference value CRVAL is arbitrary. - For these algorithms we choose to use the supplied default CRVAL value. - If no default CRVAL value was suppllied, we use the mid spectral value - if the size of the spectral axis was given, or the lower bound (i.e. - pixel 1) if the size of the spectral axis was not given. */ - if( crval == AST__BAD ) { - if( dim[ iax ] != AST__BAD ) { - crval = 0.5*( lbnd_s + ubnd_s ); - } else { - crval = lbnd_s; - } - } - -/* Modify this crval value so that it correpsonds to an integer pixel - coordinate. */ - crval = NearestPix( map, crval, iax, status ); - -/* We now check to see if the Mapping from pixel coords -> linear spectral - coords corresponds to one of the algorithms supported in FITS-WCS paper - III. First check for the "linear" algorithm in which the linear spectral - coordinate given by the SpecFrame is related linearly to the pixel - coords. */ - ctype[ 0 ] = 0; - if( IsMapLinear( map, lbnd_p, ubnd_p, iax, status ) ) { - -/* The CTYPE value is just the spectral system. */ - strcpy( ctype, orig_system ); - -/* Create the Mapping which defines the spectral IWC axis. This is - initially the Mapping from WCS to IWCS - it subtracts the CRVAL value - from the spectral WCS value to get the spectral IWC value (other - non-spectral axes are left unchanged by this Mapping). This results - in the spectral IWC axis having the same axis index as the spectral - WCS axis. */ - crval = -crval; - tmap0 = (AstMapping *) astShiftMap( 1, &crval, "", status ); - crval = -crval; - axmap = AddUnitMaps( tmap0, iax, nwcs, status ); - tmap0 = astAnnul( tmap0 ); - } - -/* If the "linear" algorithm above is inappropriate, see if the "non-linear" - algorithm defined in FITS-WCS paper III can be used, in which pixel - coords are linearly related to some spectral system (called "X") other - than the one represented by the supplied SpecFrame (called "S"). */ - if( !ctype[ 0 ] ) { - -/* Loop round each of the 4 allowed X systems. All other spectral systems - are linearly related to one of these 4 systems and so do not need to be - tested. */ - for( ix = 0; ix < 4 && !ctype[ 0 ]; ix++ ) { - -/* Set the system of the spectral WCS axis to the new trial X system. Clear - the Unit attribute to ensure we are using the default linear units. - Using the FrameSet pointer "fs" ensures that the Mappings within the - FrameSet are modified to maintain the correct inter-Frame relationships. */ - astSetC( fs, system_attr, x_sys[ ix ] ); - astClear( fs, unit_attr ); - -/* Now we check to see if the current X system is linearly related to - pixel coordinates. */ - tmap3 = astGetMapping( fs, AST__BASE, AST__CURRENT ); - if( IsMapLinear( tmap3, lbnd_p, ubnd_p, iax, status ) ) { - -/* CTYPE: First 4 characters specify the "S" system. */ - strcpy( ctype, orig_system ); - -/* The non-linear algorithm code to be appended to the "S" system is of the - form "-X2P" ("P" is the system which is linearly related to "S"). */ - if( !strcmp( x_sys[ ix ], "FREQ" ) ) { - strcpy( ctype + 4, "-F2" ); - } else if( !strcmp( x_sys[ ix ], "WAVE" ) ) { - strcpy( ctype + 4, "-W2" ); - } else if( !strcmp( x_sys[ ix ], "AWAV" ) ) { - strcpy( ctype + 4, "-A2" ); - } else { - strcpy( ctype + 4, "-V2" ); - } - if( !strcmp( orig_system, "FREQ" ) || - !strcmp( orig_system, "ENER" ) || - !strcmp( orig_system, "WAVN" ) || - !strcmp( orig_system, "VRAD" ) ) { - strcpy( ctype + 7, "F" ); - } else if( !strcmp( orig_system, "WAVE" ) || - !strcmp( orig_system, "VOPT" ) || - !strcmp( orig_system, "ZOPT" ) ) { - strcpy( ctype + 7, "W" ); - } else if( !strcmp( orig_system, "AWAV" ) ) { - strcpy( ctype + 7, "A" ); - } else { - strcpy( ctype + 7, "V" ); - } - -/* Create a Mapping which gives S as a function of X. */ - tfrm = astCopy( specfrm ); - astSetC( tfrm, "System(1)", orig_system ); - astSetC( tfrm, "Unit(1)", lin_unit ); - tfs = astConvert( specfrm, tfrm, "" ); - tmap5 = astGetMapping( tfs, AST__BASE, AST__CURRENT ); - tfs = astAnnul( tfs ); - tfrm = astAnnul( tfrm ); - -/* Use the inverse of this Mapping to get the X value at the reference S - value. */ - astTran1( tmap5, 1, &crval, 0, &xval ); - -/* Also use it to get the rate of change of S with respect to X at the - reference point. */ - dsbydx = astRate( tmap5, &xval, 0, 0 ); - -/* Create the Mapping which defines the spectral IWC axis. This is the - Mapping from WCS to IWC - it first converts from S to X, then subtracts - the X reference value value, and then scales the axis to ensure that - the rate of change of S with respect to IWC is unity (as required by - FITS-WCS paper III). Other non-spectral axes are left unchanged by - the Mapping. The spectral IWC axis has the same axis index as the - spectral WCS axis. */ - xval = -xval; - tmap2 = (AstMapping *) astShiftMap( 1, &xval, "", status ); - astInvert( tmap5 ); - tmap0 = (AstMapping *) astCmpMap( tmap5, tmap2, 1, "", status ); - tmap5 = astAnnul( tmap5 ); - tmap2 = astAnnul( tmap2 ); - tmap2 = (AstMapping *) astZoomMap( 1, dsbydx, "", status ); - tmap1 = (AstMapping *) astCmpMap( tmap0, tmap2, 1, "", status ); - tmap0 = astAnnul( tmap0 ); - tmap2 = astAnnul( tmap2 ); - axmap = AddUnitMaps( tmap1, iax, nwcs, status ); - tmap1 = astAnnul( tmap1 ); - } - tmap3 = astAnnul( tmap3 ); - -/* Re-instate the original system and unit attributes for the spectral axis. */ - astSetC( fs, system_attr, orig_system ); - astSetC( fs, unit_attr, lin_unit ); - } - } - -/* If the "non-linear" algorithm above is inappropriate, see if the - "log-linear" algorithm defined in FITS-WCS paper III can be used, in - which the spectral axis is logarithmically spaced in the spectral - system given by the SpecFrame. */ - if( !ctype[ 0 ] ) { - -/* If the "log-linear" algorithm is appropriate, the supplied SpecFrame (s) - is related to pixel coordinate (p) by s = Sr.EXP( a*p - b ). If this - is the case, then the log of s will be linearly related to pixel - coordinates. Test this. If the test is passed a Mapping is returned from - WCS to IWC. */ - axmap = LogAxis( map, iax, nwcs, lbnd_p, ubnd_p, crval, status ); - -/* If the axis is logarithmic... */ - if( axmap ) { - -/* CTYPE: First 4 characters specify the "S" system. */ - strcpy( ctype, orig_system ); - -/* The rest is "-LOG". */ - strcpy( ctype + 4, "-LOG" ); - } - } - -/* If the "log-linear" algorithm above is inappropriate, see if the "grism" - algorithm defined in FITS-WCS paper III can be used, in which pixel - coords are related to wavelength using a grism dispersion function, - implemented in AST by a GrismMap. GrismMaps produce either vacuum - wavelength or air wavelength as output. Temporarily set the SpecFrame - to these two systems in turn before we do the check for a GrismMap. */ - for( ix = 0; ix < 2 && !ctype[ 0 ]; ix++ ) { - astSetC( fs, system_attr, ( ix == 0 ) ? "WAVE" : "AWAV" ); - astSetC( fs, unit_attr, "m" ); - -/* Get the simplified Mapping from pixel to wavelength. If the Mapping is - a CmpMap containing a GrismMap, and if the output of the GrismMap is - scaled by a neighbouring ZoomMap (e.g. into different wavelength units), - then the GrismMap will be modified to incorporate the effect of the - ZoomMap, and the ZoomMap will be removed. */ - tmap2 = astGetMapping( fs, AST__BASE, AST__CURRENT ); - tmap1 = astSimplify( tmap2 ); - tmap2 = astAnnul( tmap2 ); - -/* Analyse this Mapping to see if the iax'th output is created diretcly by a - GrismMap (i.e. the output of theGrismMap must not subsequently be - modified by some other Mapping). If so, ExtractGrismMap returns a pointer - to the GrismMap as its function value, and also returns "tmap2" as a copy - of tmap1 in which the GrismMap has been replaced by a UnitMap. */ - gmap = ExtractGrismMap( tmap1, iax, &tmap2, status ); - if( gmap ) { - -/* The Mapping without the GrismMap must be linear on the spectral axis. */ - if( IsMapLinear( tmap2, lbnd_p, ubnd_p, iax, status ) ) { - -/* Get the reference wavelength (in "m") stored in the GrismMap. */ - crval = astGetGrismWaveR( gmap ); - -/* Save a copy of the current Wavelength (in "m") SpecFrame. */ - tfrm1 = astCopy( specfrm ); - -/* Re-instate the original System and Unit attributes for the SpecFrame. */ - astSetC( fs, system_attr, orig_system ); - astSetC( fs, unit_attr, lin_unit ); - -/* Find the Mapping from the original "S" system to wavelength (in "m"). */ - tfs = astConvert( specfrm, tfrm1, "" ); - tfrm1 = astAnnul( tfrm1 ); - if( tfs ) { - tmap3 = astGetMapping( tfs, AST__BASE, AST__CURRENT ); - tfs = astAnnul( tfs ); - -/* Use the inverse of this Mapping to convert the reference value from - wavelength to the "S" system. */ - astTran1( tmap3, 1, &crval, 0, &crval ); - -/* Concatenate the "S"->wavelength Mapping with the inverse GrismMap (from - wavelength to grism parameter), to get the "S" -> "grism parameter" - Mapping. */ - astInvert( gmap ); - tmap4 = (AstMapping *) astCmpMap( tmap3, gmap, 1, "", status ); - tmap3 = astAnnul( tmap3 ); - -/* Use this Mapping to find the grism parameter at the reference point. */ - astTran1( tmap4, 1, &crval, 1, &gval ); - -/* Also use it to find the rate of change of grism parameter with respect - to "S" at the reference point. */ - dgbyds = astRate( tmap4, &crval, 0, 0 ); - -/* FITS-WCS paper III required ds/dw to be unity at the reference point. - Therefore the rate of change of grism parameter with respect to IWC ("w") - is equal to the rate of change of grism parameter with respect to "S" - (at the reference point). The mapping from "w" to grism parameter is a - ZoomMap which scales "w" by "dgbyds" followed by a ShiftMap which adds - on "gval". */ - tmap5 = (AstMapping *) astZoomMap( 1, dgbyds, "", status ); - tmap6 = (AstMapping *) astShiftMap( 1, &gval, "", status ); - tmap3 = (AstMapping *) astCmpMap( tmap5, tmap6, 1, "", status ); - tmap5 = astAnnul( tmap5 ); - tmap6 = astAnnul( tmap6 ); - -/* Create the Mapping which defines the spectral IWC axis. This is the - Mapping from WCS "S" to IWCS "w", formed by combining the Mapping from - "S" to grism parameter (tmap4), with the Mapping from grism parameter to - "w" (inverse of tmap3). Other non-spectral axes are left unchanged by the - Mapping. The spectral IWC axis has the same axis index as the spectral - WCS axis. */ - astInvert( tmap3 ); - tmap5 = (AstMapping *) astCmpMap( tmap4, tmap3, 1, "", status ); - tmap3 = astAnnul( tmap3 ); - tmap4 = astAnnul( tmap4 ); - axmap = AddUnitMaps( tmap5, iax, nwcs, status ); - tmap5 = astAnnul( tmap5 ); - -/* CTYPE: First 4 characters specify the "S" system. */ - strcpy( ctype, orig_system ); - -/* Last 4 characters are "-GRA" or "-GRI". */ - strcpy( ctype + 4, ( ix == 0 ) ? "-GRI" : "-GRA" ); - -/* Store values for the projection parameters in the FitsStore. Ignore - parameters which are set to the default values defined in FITS-WCS - paper III. */ - pv = astGetGrismG( gmap ); - if( pv != 0 ) SetItem( &(store->pv), fits_i, 0, s, pv, status ); - pv = (double) astGetGrismM( gmap ); - if( pv != 0 ) SetItem( &(store->pv), fits_i, 1, s, pv, status ); - pv = astGetGrismAlpha( gmap ); - if( pv != 0 ) SetItem( &(store->pv), fits_i, 2, s, pv*AST__DR2D, status ); - pv = astGetGrismNR( gmap ); - if( pv != 1.0 ) SetItem( &(store->pv), fits_i, 3, s, pv, status ); - pv = astGetGrismNRP( gmap ); - if( pv != 0 ) SetItem( &(store->pv), fits_i, 4, s, pv, status ); - pv = astGetGrismEps( gmap ); - if( pv != 0 ) SetItem( &(store->pv), fits_i, 5, s, pv*AST__DR2D, status ); - pv = astGetGrismTheta( gmap ); - if( pv != 0 ) SetItem( &(store->pv), fits_i, 6, s, pv*AST__DR2D, status ); - } - } - -/* Release resources. */ - tmap2 = astAnnul( tmap2 ); - gmap = astAnnul( gmap ); - } - -/* Release resources. */ - tmap1 = astAnnul( tmap1 ); - -/* Re-instate the original System and Unit attributes for the SpecFrame. */ - astSetC( fs, system_attr, orig_system ); - astSetC( fs, unit_attr, lin_unit ); - } - -/* If none of the above algorithms are appropriate, we must resort to - using the -TAB algorithm, in which the Mapping is defined by a look-up - table. Check the TabOK attribute to see -TAB is to be supported. */ - extver = astGetTabOK( this ); - if( !ctype[ 0 ] && extver > 0 ) { - -/* Get any pre-existing FitsTable from the FitsStore. This is the table - in which the tabular data will be stored (if the Mapping can be expressed - in -TAB form). */ - if( !astMapGet0A( store->tables, AST_TABEXTNAME, &table ) ) table = NULL; - -/* See if the Mapping can be expressed in -TAB form. */ - tmap0 = IsMapTab1D( map, 1.0, NULL, wcsfrm, dim, iax, fits_i, &table, - &icolmain, &icolindex, &interp, status ); - if( tmap0 ) { - -/* CTYPE: First 4 characters specify the "S" system. Last 4 characters are - "-TAB". */ - strcpy( ctype, orig_system ); - strcpy( ctype + 4, "-TAB" ); - -/* The values stored in the table index vector are GRID coords. So we - need to ensure that IWC are equivalent to GRID coords. So set CRVAL - to zero. First store the original CRVAL value (which gives the - observation centre) in AXREF. */ - SetItem( &(store->axref), fits_i, 0, s, crval, status ); - crval = 0.0; - -/* Store TAB-specific values in the FitsStore. First the name of the - FITS binary table extension holding the coordinate info. */ - SetItemC( &(store->ps), fits_i, 0, s, AST_TABEXTNAME, status ); - -/* Next the table version number. This is the set (positive) value for the - TabOK attribute. */ - SetItem( &(store->pv), fits_i, 1, s, extver, status ); - -/* Also store the table version in the binary table header. */ - astSetFitsI( table->header, "EXTVER", extver, - "Table version number", 0 ); - -/* Next the name of the table column containing the main coords array. */ - SetItemC( &(store->ps), fits_i, 1, s, - astColumnName( table, icolmain ), status ); - -/* Next the name of the column containing the index array */ - if( icolindex >= 0 ) SetItemC( &(store->ps), fits_i, 2, s, - astColumnName( table, icolindex ), status ); - -/* The interpolation method (an AST extension to the published -TAB - algorithm, communicated through the QVi_4a keyword). */ - SetItem( &(store->pv), fits_i, 4, s, interp, status ); - -/* Also store the FitsTable itself in the FitsStore. */ - astMapPut0A( store->tables, AST_TABEXTNAME, table, NULL ); - -/* Create the WCS -> IWC Mapping (AST uses grid coords as IWC coords for - the -TAB algorithm). First, get a Mapping that combines the TAB axis - Mapping( tmap0) in parallel with one or two UnitMaps in order to put - the TAB axis at the required index. */ - tmap1 = AddUnitMaps( tmap0, iax, nwcs, status ); - -/* Now get a PermMap that permutes the WCS axes into the FITS axis order. */ - inperm = astMalloc( sizeof( double )*nwcs ); - outperm = astMalloc( sizeof( double )*nwcs ); - if( astOK ) { - for( j = 0; j < nwcs; j++ ) { - inperm[ j ] = wperm[ j ]; - outperm[ wperm[ j ] ] = j; - } - } - pm = astPermMap( nwcs, inperm, nwcs, outperm, NULL, "", - status ); - -/* Combine these two Mappings in series, to get the Mapping from WCS to - IWC. */ - axmap = (AstMapping *) astCmpMap( pm, tmap1, 1, " ", - status ); - -/* Free resources. */ - inperm = astFree( inperm ); - outperm = astFree( outperm ); - pm = astAnnul( pm ); - tmap0 = astAnnul( tmap0 ); - tmap1 = astAnnul( tmap1 ); - } - if( table ) table = astAnnul( table ); - } - -/* If this axis is a usable spectral axis... */ - if( ctype[ 0 ] ) { - -/* Add the Mapping for this axis in series with any existing result Mapping. */ - if( ret ) { - tmap0 = (AstMapping *) astCmpMap( ret, axmap, 1, "", status ); - (void) astAnnul( ret ); - ret = tmap0; - } else { - ret = astClone( axmap ); - } - axmap = astAnnul( axmap ); - -/* Store values for CTYPE, CRVAL and CUNIT in the FitsStore. */ - SetItemC( &(store->ctype), fits_i, 0, s, ctype, status ); - SetItem( &(store->crval), fits_i, 0, s, crval, status ); - SetItemC( &(store->cunit), fits_i, 0, s, lin_unit, status ); - -/* If the axis label has been set, use it as the CTYPE comment and CNAME - value. */ - if( astTestLabel( specfrm, 0 ) ) { - cname = (char *) astGetLabel( specfrm, 0 ); - SetItemC( &(store->ctype_com), fits_i, 0, s, cname, status ); - SetItemC( &(store->cname), fits_i, 0, s, cname, status ); - } - -/* Store values for the other FITS-WCS keywords which describe the - spectral system. Only store values which have been explicitly set in - the SpecFrame, which are different to the default values defined by - FITS-WCS paper III (if any), and which are not bad. */ - if( astTestObsLon( specfrm ) && astTestObsLat( specfrm ) && - s == ' ' ) { - geolon = astGetObsLon( specfrm ); - geolat = astGetObsLat( specfrm ); - h = astGetObsAlt( specfrm ); - if( geolat != AST__BAD && geolon != AST__BAD && h != AST__BAD ) { - eraGd2gc( 1, geolon, geolat, h, xyz ); - SetItem( &(store->obsgeox), 0, 0, ' ', xyz[0], status ); - SetItem( &(store->obsgeoy), 0, 0, ' ', xyz[1], status ); - SetItem( &(store->obsgeoz), 0, 0, ' ', xyz[2], status ); - } - } - if( astTestRestFreq( specfrm ) ) { - restfreq = astGetRestFreq( specfrm ); - if( restfreq != AST__BAD ) { - if( !strcmp( orig_system, "WAVE" ) || - !strcmp( orig_system, "VOPT" ) || - !strcmp( orig_system, "ZOPT" ) || - !strcmp( orig_system, "AWAV" ) ) { - SetItem( &(store->restwav), 0, 0, s, AST__C/restfreq, status ); - } else { - SetItem( &(store->restfrq), 0, 0, s, restfreq, status ); - } - } - if( astIsADSBSpecFrame( specfrm ) ) { - imagfreq = astGetImagFreq( (AstDSBSpecFrame *) specfrm ); - if( imagfreq != AST__BAD ) { - SetItem( &(store->imagfreq), 0, 0, s, imagfreq, status ); - } - } - } - cval = GetFitsSor( astGetC( specfrm, "StdOfRest" ), status ); - if( cval ) SetItemC( &(store->specsys), 0, 0, s, cval, status ); - if( astTestSourceVel( specfrm ) ) { - vsource = astGetSourceVel( specfrm ); - if( vsource != AST__BAD && fabs( vsource ) < AST__C ) { - zsource = sqrt( (AST__C + vsource)/ - (AST__C - vsource) ) - 1.0; - SetItem( &(store->zsource), 0, 0, s, zsource, status ); - cval = GetFitsSor( astGetC( specfrm, "SourceVRF" ), status ); - if( cval ) SetItemC( &(store->ssyssrc), 0, 0, s, cval, status ); - } - } else { - vsource = AST__BAD; - } - -/* Store the VELOSYS value (not strictly needed since it can be - determined from the other values, but FITS-WCS paper III says it can be - useful). We temporarily change the source velocity to be zero m/s - in the main rest frame (StdOfRest) (unless the main rest frame is - already the source rest frame). We then change the source rest - frame to topocentric and get the source velocity (i.e. the velocity of - the main rest Frame) in the topocentric system. We then re-instate the - original attribute values if they were set. */ - if( astGetStdOfRest( specfrm ) != AST__SCSOR ) { - sourcevrf = astGetSourceVRF( specfrm ); - astSetSourceVRF( specfrm, astGetStdOfRest( specfrm ) ); - astSetSourceVel( specfrm, 0.0 ); - } else { - vsource = AST__BAD; - sourcevrf = AST__NOSOR; - } - astSetSourceVRF( specfrm, AST__TPSOR ); - SetItem( &(store->velosys), 0, 0, s, - astGetSourceVel( specfrm ), status ); - if( vsource != AST__BAD ){ - astSetSourceVRF( specfrm, sourcevrf ); - astSetSourceVel( specfrm, vsource ); - } - -/* Indicate that this axis has been described. */ - axis_done[ iax ] = 1; - } - -/* Release resources. */ - map = astAnnul( map ); - } - } - pframe = astAnnul( pframe ); - } - -/* Release resources. */ - lbnd_p = astFree( lbnd_p ); - ubnd_p = astFree( ubnd_p ); - wcsfrm = astAnnul( wcsfrm ); - -/* If we have a Mapping to return, simplify it. Otherwise, create - a UnitMap to return. */ - if( ret ) { - tmap0 = ret; - ret = astSimplify( tmap0 ); - tmap0 = astAnnul( tmap0 ); - } else { - ret = (AstMapping *) astUnitMap( nwcs, "", status ); - } - -/* Return the result. */ - return ret; -} - -static AstFitsChan *SpecTrans( AstFitsChan *this, int encoding, - const char *method, const char *class, int *status ){ -/* -* Name: -* SpecTrans - -* Purpose: -* Translated non-standard WCS FITS headers into equivalent standard -* ones. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstFitsChan *SpecTrans( AstFitsChan *this, int encoding, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function checks the supplied FitsChan for selected -* non-standard WCS keywords and, if found, stores equivalent -* standard keywords in a newly created FitsChan which is returned as -* the function value. All the original keywords are marked -* as having been used, so that they are not written out when the -* FitsChan is deleted. -* - -* At the moment, the non-standard keywords checked for are: -* -* 1) RADECSYS is renamed as RADESYS -* -* 2) LONGPOLE is renamed as LONPOLE -* -* 3) CDjjjiii and CDj_i are converted to PCi_j (with unit CDELT) -* -* 4) CROTAj are converted to PCi_j -* -* 5) PROJPi are converted to PV_i -* -* 6) CmVALi are converted to CRVALis (s=A,B,,, for m=1,2...). This -* is also done for CmPIXi, CmYPEi, and CmNITi. CmELTi is converted -* to a CDj_is array. -* -* 7) EQUINOX keywords with string values equal to a date preceded -* by the letter B or J (eg "B1995.0"). These are converted to the -* corresponding Julian floating point value without any epoch -* specifier. -* -* 8) EPOCH values are converted into Julian EQUINOX values (but only -* if the FitsChan does not already contain an EQUINOX value). -* -* 9) DATE-OBS values are converted into MJD-OBS values (but only -* if the FitsChan does not already contain an MJD-OBS value). -* -* 10) EQUINOX or EPOCH keywords with value zero are converted to -* B1950. -* -* 11) The AIPS NCP and GLS projections are converted into equivalent SIN -* or SFL projections. -* -* 12) The IRAF "ZPX" projection. If the last 4 chacaters of CTYPEi - -* (i = 1, naxis) are "-ZPX", then: -* - "ZPX" is replaced by "ZPN" within the CTYPEi value -* - A distortion code of "-ZPX" is appended to the end of the CTYPEi -* value (this is used later by the DistortMaps function). -* - If the FitsChan contains no PROJP keywords, then projection -* parameter valus are read from any WATi_nnn keywords, and -* corresponding PV keywords are added to the FitsChan. -* -* 13) The IRAF "TNX" projection. If the last 4 chacaters of CTYPEi - -* (i = 1, naxis) are "-TNX", then: -* - "TNX" is replaced by "TAN" within the CTYPEi value (the distorted -* TAN projection included in a pre-final version of FITS-WCS is still -* supported by AST using the WcsMap AST__TPN projection). -* - If the FitsChan contains no PROJP keywords, then projection -* parameter valus are read from any WATi_nnn keywords, and -* corresponding PV keywords are added to the FitsChan. -* - If the TNX projection cannot be converted exactly into a TAN -* projection, ASTWARN keywords are added to the FitsChan -* containing a warning message. The calling application can (if it -* wants to) check for this keyword, and report its contents to the -* user. -* -* 14) Keywords relating to the IRAF "mini-WCS" system are removed. -* This is the IRAF equivalent of the AST native encoding. Mini-WCS -* keywords are removed in order to avoid confusion arising between -* potentially inconsistent encodings. -* -* 15) "QV" parameters for TAN projections (as produced by AUTOASTROM) -* or "-TAB" (as produced by FitsChan) are renamed to "PV". -* -* 16) RESTFREQ is converted to RESTFRQ. -* -* 17) the "-WAV", "-FRQ" and "-VEL" CTYPE algorithms included in an -* early draft of FITS-WCS paper III are translated to the -* corresponding modern "-X2P" form. -* -* 18) AIPS spectral CTYPE values are translated to FITS-WCS paper III -* equivalents. -* -* 19) AIPS spectral keywords OBSRA and OBSDEC are used to create a -* pair of celestial axes with reference point at the specified -* (OBSRA,OBSDEC) position. This is only done if the header does not -* already contain a pair of celestial axes. -* -* 20) Common case insensitive CUNIT values: "Hz", "Angstrom", "km/s", -* "M/S" -* -* 21) Various translations specific to the FITS-CLASS encoding. -* -* 22) SAO distorted TAN projections (uses COi_j keywords to store -* polynomial coefficients) are converted to TPN projections. - -* 23) CTYPE == "LAMBDA" changed to CTYPE = "WAVE" -* -* 24) if the projection is TAN and the PolyTan attribute is non-zero, -* or if the projection is TPV (produced by SCAMP), the projection is -* changed to TPN (the AST code for the draft FITS-WCS paper II -* conventions for a distorted TAN projection). - -* Parameters: -* this -* Pointer to the FitsChan. -* encoding -* The FitsChan encoding in use. -* method -* Pointer to string holding name of calling method. -* class -* Pointer to a string holding the name of the supplied object class. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new FitsChan containing the keywords which -* constitute the standard equivalents to any non-standard keywords in -* the supplied FitsChan. A NULL pointer is returned if there are no -* non-standard keywords in the supplied FitsChan. -*/ - -/* Local Variables: */ - AstFitsChan *ret; /* The returned FitsChan */ - char *assys; /* AIPS standad of rest type */ - char *astype; /* AIPS spectral type */ - char *comm; /* Pointer to comment string */ - char *cval; /* Pointer to character string */ - char *start; /* Pointer to start of projp term */ - char *watmem; /* Pointer to total WAT string */ - char bj; /* Besselian/Julian indicator */ - char format[ 50 ]; /* scanf format string */ - char keyname[ FITSNAMLEN + 5 ];/* General keyword name + formats */ - char lattype[MXCTYPELEN]; /* CTYPE value for latitude axis */ - char lontype[MXCTYPELEN]; /* CTYPE value for longitude axis */ - char prj[6]; /* Spatial projection string */ - char s; /* Co-ordinate version character */ - char spectype[MXCTYPELEN]; /* CTYPE value for spectral axis */ - char sprj[6]; /* Spectral projection string */ - char ss; /* Co-ordinate version character */ - char template[ FITSNAMLEN + 1 ];/* General keyword name template */ - double *cvals; /* PVi_m values for TPN projection */ - double cdelti; /* CDELT for longitude axis */ - double cdeltj; /* CDELT for latitude axis */ - double cosrota; /* Cos( CROTA ) */ - double crota; /* CROTA Value */ - double dval; /* General floating value */ - double lambda; /* Ratio of CDELTs */ - double projp; /* Projection parameter value */ - double rowsum2; /* Sum of squared CDi_j row elements */ - double sinrota; /* Sin( CROTA ) */ - double sinval; /* Sin( dec ref ) */ - int *mvals; /* "m" index of each PVi_m value */ - int axlat; /* Index of latitude axis */ - int axlon; /* Index of longitude axis */ - int diag; /* Sign of diagonal CDi_j element */ - int dim; /* Length of pixel axis */ - int gotpcij; /* Does FitsChan contain any PCi_j keywords? */ - int i,j; /* Indices */ - int iaxis; /* Axis index */ - int icoeff; /* Index of next PVi_m value */ - int iproj; /* Projection parameter index */ - int jhi; /* Highest axis index */ - int jlo; /* Lowest axis index */ - int lbnd[ 2 ]; /* Lower index bounds */ - int m; /* Co-ordinate version index */ - int naxis; /* Number of axes */ - int nc; /* Length of string */ - int ncoeff; /* Number of PVi_m values */ - int ok; /* Can projection be represented in FITS-WCS?*/ - int shifted; /* Non-zero if there is an origin shift */ - int tlbnd[ 2 ]; /* Lower index bounds */ - int tubnd[ 2 ]; /* Upper index bounds */ - int ubnd[ 2 ]; /* Upper index bounds */ - int use_projp; /* Use PROJP keywors in favour of PV keywords? */ - size_t size; /* Length of string value */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise to avoid compiler warnings. */ - size = 0; - prj[ 0 ] = 0; - -/* Create the returned FitsChan. */ - ret = astFitsChan( NULL, NULL, "", status ); - -/* Loop round all axis descriptions, starting with primary (' '). */ - for( s = 'A' - 1; s <= 'Z' && astOK; s++ ){ - if( s == 'A' - 1 ) s = ' '; - -/* Find the number of axes by finding the highest axis number in any - CRPIXi keyword name. Pass on if there are no axes for this axis - description. */ - if( s != ' ' ) { - sprintf( template, "CRPIX%%d%c", s ); - } else { - strcpy( template, "CRPIX%d" ); - } - if( !astKeyFields( this, template, 1, &naxis, lbnd ) ) { - if( s == ' ' ) s = 'A' - 1; - continue; - } - -/* Find the longitude and latitude axes by examining the CTYPE values. - They are marked as read. Such markings are only provisional, and they - can be read again any number of times until the current astRead - operation is completed. Also note the projection type. */ - j = 0; - axlon = -1; - axlat = -1; - while( j < naxis && astOK ){ - if( GetValue2( ret, this, FormatKey( "CTYPE", j + 1, -1, s, status ), - AST__STRING, (void *) &cval, 0, method, - class, status ) ){ - nc = strlen( cval ); - if( !strncmp( cval, "RA--", 4 ) || - !strncmp( cval, "AZ--", 4 ) || - ( nc > 1 && !strncmp( cval + 1, "LON", 3 ) ) || - ( nc > 2 && !strncmp( cval + 2, "LN", 2 ) ) ) { - axlon = j; - strncpy( prj, cval + 4, 4 ); - strncpy( lontype, cval, 10 ); - prj[ 4 ] = 0; - } else if( !strncmp( cval, "DEC-", 4 ) || - !strncmp( cval, "EL--", 4 ) || - ( nc > 1 && !strncmp( cval + 1, "LAT", 3 ) ) || - ( nc > 2 && !strncmp( cval + 2, "LT", 2 ) ) ) { - axlat = j; - strncpy( prj, cval + 4, 4 ); - strncpy( lattype, cval, 10 ); - prj[ 4 ] = 0; - -/* Check for spectral algorithms from early drafts of paper III */ - } else { - sprj[ 0 ] = '-'; - if( ( nc > 4 && !strncmp( cval + 4, "-WAV", 4 ) ) ) { - sprj[ 1 ] = 'W'; - } else if( ( nc > 4 && !strncmp( cval + 4, "-FRQ", 4 ) ) ) { - sprj[ 1 ] = 'F'; - } else if( ( nc > 4 && !strncmp( cval + 4, "-VEL", 4 ) ) ) { - sprj[ 1 ] = 'V'; - } else { - sprj[ 0 ] = 0; - } - if( *sprj ) { - sprj[ 2 ] = '2'; - if( !strncmp( cval, "WAVE", 4 ) ) { - sprj[ 3 ] = 'W'; - } else if( !strncmp( cval, "FREQ", 4 ) ) { - sprj[ 3 ] = 'F'; - } else if( !strncmp( cval, "VELO", 4 ) ) { - sprj[ 3 ] = 'V'; - } else if( !strncmp( cval, "VRAD", 4 ) ) { - sprj[ 3 ] = 'F'; - } else if( !strncmp( cval, "VOPT", 4 ) ) { - sprj[ 3 ] = 'W'; - } else if( !strncmp( cval, "ZOPT", 4 ) ) { - sprj[ 3 ] = 'W'; - } else if( !strncmp( cval, "ENER", 4 ) ) { - sprj[ 3 ] = 'F'; - } else if( !strncmp( cval, "WAVN", 4 ) ) { - sprj[ 3 ] = 'F'; - } else if( !strncmp( cval, "BETA", 4 ) ) { - sprj[ 3 ] = 'V'; - } else { - sprj[ 0 ] = 0; - } - } - if( *sprj ) { - strcpy( spectype, cval ); - if( sprj[ 1 ] == sprj[ 3 ] ) { - strcpy( sprj, strlen( cval ) > 8 ? "----" : " " ); - } else { - sprj[ 4 ] = 0; - } - strncpy( spectype + 4, sprj, 4 ); - cval = spectype; - SetValue( ret, FormatKey( "CTYPE", j + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - } - } - j++; - } else { - break; - } - } - -/* RADECSYS keywords - ----------------- */ - if( s == ' ' ) { - if( GetValue2( ret, this, "RADECSYS", AST__STRING, (void *) &cval, 0, method, - class, status ) ){ - if( encoding == FITSPC_ENCODING || encoding == FITSIRAF_ENCODING ){ - SetValue( ret, "RADESYS", (void *) &cval, AST__STRING, - CardComm( this, status ), status ); - } - } - -/* LONGPOLE keywords - ----------------- */ - if( GetValue2( ret, this, "LONGPOLE", AST__FLOAT, (void *) &dval, 0, method, - class, status ) ){ - if( encoding == FITSPC_ENCODING || encoding == FITSIRAF_ENCODING ){ - SetValue( ret, "LONPOLE", (void *) &dval, AST__FLOAT, - CardComm( this, status ), status ); - } - } - } - -/* Zero CDELT values. - ----------------- */ - -/* Check there are some CDELT keywords... */ - if( s != ' ' ) { - sprintf( template, "CDELT%%d%c", s ); - } else { - strcpy( template, "CDELT%d" ); - } - if( astKeyFields( this, template, 0, NULL, NULL ) ){ - -/* Do each row in the matrix. */ - for( j = 0; j < naxis; j++ ){ - -/* Get the CDELT value for this row. */ - GetValue2( ret, this, FormatKey( "CDELT", j + 1, -1, s, status ), AST__FLOAT, - (void *) &cdeltj, 0, method, class, status ); - -/* If CDELT is zero, use 1.0E-6 of the corresponding CRVAL value - instead, or 1.0 if CRVAL is zero. Otherwise, the zeros could cause the - matrix to be non-invertable. The Mapping could then not be simplified - or used by a Plot. CDELT values of zero are usually used to indicate - "redundant" axes. For instance, a 2D image may be stored as a 3D cube - with a single plane with the "redundant" 3rd axis used to specify the - wavelength of the filter. The actual value used for CDELT shouldn't - matter since the axis only spans a single pixel anyway. */ - if( cdeltj == 0.0 ){ - GetValue2( ret, this, FormatKey( "CDELT", j + 1, -1, s, status ), AST__FLOAT, - (void *) &dval, 1, method, class, status ); - cdeltj = 1.0E-6*dval; - if( cdeltj == 0.0 ) cdeltj = 1.0; - SetValue( ret, FormatKey( "CDELT", j + 1, -1, s, status ), (void *) &cdeltj, - AST__FLOAT, NULL, status ); - } - } - } - -/* Following conversions produce PCi_j keywords. Only do them if there - are currently no PCi_j keywords in the header. */ - if( s != ' ' ) { - sprintf( template, "PC%%d_%%d%c", s ); - } else { - strcpy( template, "PC%d_%d" ); - } - gotpcij = astKeyFields( this, template, 0, NULL, NULL ); - if( !gotpcij ){ - -/* CDjjjiii - -------- */ - if( s == ' ' && astKeyFields( this, "CD%3d%3d", 0, NULL, NULL ) ){ - -/* Do each row in the matrix. */ - for( j = 0; j < naxis; j++ ){ - -/* Do each column in the matrix. */ - for( i = 0; i < naxis; i++ ){ - -/* Get the CDjjjiii matrix element */ - sprintf( keyname, "CD%.3d%.3d", j + 1, i + 1 ); - if( GetValue2( ret, this, keyname, AST__FLOAT, (void *) &dval, 0, - method, class, status ) ){ - -/* If found, save it with name PCj_i, and ensure the default value of 1.0 - is used for CDELT. */ - if( encoding == FITSIRAF_ENCODING ){ - SetValue( ret, FormatKey( "PC", j + 1, i + 1, ' ', status ), - (void *) &dval, AST__FLOAT, NULL, status ); - dval = 1.0; - SetValue( ret, FormatKey( "CDELT", j + 1, -1, s, status ), - (void *) &dval, AST__FLOAT, NULL, status ); - gotpcij = 1; - } - } - } - } - } - -/* CDj_i - ---- */ - if( s != ' ' ) { - sprintf( template, "CD%%d_%%d%c", s ); - } else { - strcpy( template, "CD%d_%d" ); - } - if( !gotpcij && astKeyFields( this, template, 0, NULL, NULL ) ){ - -/* Do each row in the matrix. */ - for( j = 0; j < naxis; j++ ){ - -/* First find the sum of the squared elements in the row. and note the - sign of the diagonal element. */ - rowsum2 = 0.0; - diag = +1; - for( i = 0; i < naxis; i++ ){ - if( GetValue2( ret, this, FormatKey( "CD", j + 1, i + 1, s, status ), - AST__FLOAT, (void *) &dval, 0, method, class, status ) ){ - rowsum2 += dval*dval; - if( i == j ) diag = ( dval >= 0.0 ) ? +1 : -1; - } - } - -/* The CDELT value for this row will be the length of the row vector. This means that - each row will be a unit vector when converted to PCi_j form, and the CDELT will - give a real indication of the pixel size. Ensure that the diagonal - PCi+j element has a positive sign. */ - cdelti = sqrt( rowsum2 )*diag; - SetValue( ret, FormatKey( "CDELT", j + 1, -1, s, status ), - (void *) &cdelti, AST__FLOAT, NULL, status ); - -/* Do each column in the matrix. */ - for( i = 0; i < naxis; i++ ){ - -/* Get the CDj_i matrix element (note default value for all CD elements - is zero (even diagonal elements!). */ - if( !GetValue2( ret, this, FormatKey( "CD", j + 1, i + 1, s, status ), - AST__FLOAT, (void *) &dval, 0, method, class, status ) ){ - dval = 0.0; - } - -/* Divide by the rows cdelt value and save it with name PCj_i. */ - if( cdelti != 0.0 ) dval /= cdelti; - SetValue( ret, FormatKey( "PC", j + 1, i + 1, s, status ), - (void *) &dval, AST__FLOAT, NULL, status ); - gotpcij = 1; - } - } - } - -/* PCjjjiii and CROTAi keywords - ---------------------------- */ - -/* Check there are some CDELT keywords... */ - if( s != ' ' ) { - sprintf( template, "CDELT%%d%c", s ); - } else { - strcpy( template, "CDELT%d" ); - } - if( !gotpcij && astKeyFields( this, template, 0, NULL, NULL ) ){ - -/* See if there is a CROTA keyword. Try to read values for both axes - since they are sometimes both included. This ensures they will not be - included in the output when the FitsChan is deleted. Read the latitude - axis second in order to give it priority in cases where both are - present. */ - crota = AST__BAD; - GetValue2( ret, this, FormatKey( "CROTA", axlon + 1, -1, s, status ), - AST__FLOAT, (void *) &crota, 0, method, class, status ); - GetValue2( ret, this, FormatKey( "CROTA", axlat + 1, -1, s, status ), - AST__FLOAT, (void *) &crota, 0, method, class, status ); - -/* If there are any PCjjjiii keywords, rename them as PCj_i. */ - if( s == ' ' && astKeyFields( this, "PC%3d%3d", 0, NULL, NULL ) ){ - -/* Do each row in the matrix. */ - for( j = 0; j < naxis; j++ ){ - -/* Do each column in the matrix. */ - for( i = 0; i < naxis; i++ ){ - -/* Get the PCiiijjj matrix element */ - sprintf( keyname, "PC%.3d%.3d", j + 1, i + 1 ); - if( GetValue2( ret, this, keyname, AST__FLOAT, (void *) &dval, 0, - method, class, status ) ){ - } else if( i == j ) { - dval = 1.0; - } else { - dval = 0.0; - } - -/* Store it as PCi_j */ - SetValue( ret, FormatKey( "PC", j + 1, i + 1, ' ', status ), - (void *) &dval, AST__FLOAT, NULL, status ); - gotpcij = 1; - } - } - -/* If there is a CROTA value and no PCjjjii keywords, create a PCj_i - matrix from the CROTA values. We need to have latitude and longitude - axes for this. */ - } else if( s == ' ' && axlat != -1 && axlon != -1 && crota != AST__BAD ){ - -/* Get the sin and cos of CROTA */ - cosrota = cos( crota*AST__DD2R ); - sinrota = sin( crota*AST__DD2R ); - -/* Get the CDELT values for the longitude and latitude axes. */ - if( GetValue2( ret, this, FormatKey( "CDELT", axlat + 1, -1, ' ', status ), - AST__FLOAT, (void *) &cdeltj, 1, method, - class, status ) && - GetValue2( ret, this, FormatKey( "CDELT", axlon + 1, -1, ' ', status ), - AST__FLOAT, (void *) &cdelti, 1, method, - class, status ) ){ - -/* Save the ratio, needed below. */ - lambda = cdeltj/cdelti; - -/* Save a corresponding set of PCi_j keywords in the FitsChan. First do - the diagonal terms. */ - for( i = 0; i < naxis; i++ ){ - if( i == axlat ) { - dval = cosrota; - } else if( i == axlon ) { - dval = cosrota; - } else { - dval = 1.0; - } - SetValue( ret, FormatKey( "PC", i + 1, i + 1, ' ', status ), - (void *) &dval, AST__FLOAT, NULL, status ); - gotpcij = 1; - } - -/* Now do the non-zero off-diagonal terms. */ - dval = sinrota/lambda; - SetValue( ret, FormatKey( "PC", axlat + 1, axlon + 1, ' ', status ), - (void *) &dval, AST__FLOAT, NULL, status ); - dval = -sinrota*lambda; - SetValue( ret, FormatKey( "PC", axlon + 1, axlat + 1, ' ', status ), - (void *) &dval, AST__FLOAT, NULL, status ); - } - } - } - } - -/* Conversion of old PROJP, etc, is done once on the "primary" pass. */ - if( s == ' ' ) { - -/* PROJP keywords - -------------- */ - if( astKeyFields( this, "PROJP%d", 1, ubnd, lbnd ) && axlat != -1 ) { - -/* Some people produce headers with both PROJP and PV. Even worse, the - PROJP and PV values are sometimes inconsistent. In this case we trust - the PV values rather than the PROJP values, but only if the PV values - are not obviously incorrect for some reason. In particularly, we check - that, *if* either PVi_1 or PVi_2 (where i=longitude axis) is present, - then PVi_0 is also present. Conversely we check that if PVi_0 is - present then at least one of PVi_1 or PVi_2 is present. */ - use_projp = 1; - if( axlat != -1 && - astKeyFields( this, "PV%d_%d", 2, tubnd, tlbnd ) ){ - use_projp = 0; - -/* Are there any PV values for the longitude axis? */ - if( tlbnd[ 0 ] <= axlon + 1 && axlon + 1 <= tubnd[ 0 ] ) { - -/* Are either PVi_1 or PVi_2 available? */ - if( HasCard( this, FormatKey( "PV", axlon + 1, 1, ' ', status ), - method, class, status ) || - HasCard( this, FormatKey( "PV", axlon + 1, 2, ' ', status ), - method, class, status ) ) { - -/* If so use PROJP if PVi_0 is not also available. */ - if( !HasCard( this, FormatKey( "PV", axlon + 1, 0, ' ', status ), - method, class, status ) ) use_projp = 1; - -/* If neither PVi_1 or PVi_2 are available, use PROJP if PVi_0 is - available. */ - } else if( HasCard( this, FormatKey( "PV", axlon + 1, 0, ' ', status ), - method, class, status ) ) { - use_projp = 1; - } - } - } - -/* Translate PROJP to PV if required. */ - if( use_projp ) { - for( i = lbnd[ 0 ]; i <= ubnd[ 0 ]; i++ ){ - if( GetValue2( ret, this, FormatKey( "PROJP", i, -1, ' ', status ), - AST__FLOAT, (void *) &dval, 0, method, class, status ) && - ( encoding == FITSPC_ENCODING || - encoding == FITSIRAF_ENCODING ) ){ - SetValue( ret, FormatKey( "PV", axlat + 1, i, ' ', status ), - (void *) &dval, AST__FLOAT, CardComm( this, status ), status ); - } - } - } - } - -/* CmVALi keywords - --------------- */ - if( astKeyFields( this, "C%1dVAL%d", 2, ubnd, lbnd ) ){ - ss = 'A'; - for( m = lbnd[ 0 ]; m <= ubnd[ 0 ]; m++ ){ - for( i = lbnd[ 1 ]; i <= ubnd[ 1 ]; i++ ){ - sprintf( keyname, "C%dVAL%d", m, i ); - if( GetValue2( ret, this, keyname, AST__FLOAT, (void *) &dval, 0, - method, class, status ) && - ( encoding == FITSPC_ENCODING || - encoding == FITSIRAF_ENCODING ) ){ - sprintf( keyname, "CRVAL%d%c", i, ss ); - SetValue( ret, keyname, (void *) &dval, AST__FLOAT, - CardComm( this, status ), status ); - } - } - ss++; - } - } - -/* CmPIXi keywords - --------------- */ - if( astKeyFields( this, "C%1dPIX%d", 2, ubnd, lbnd ) ){ - ss = 'A'; - for( m = lbnd[ 0 ]; m <= ubnd[ 0 ]; m++ ){ - for( i = lbnd[ 1 ]; i <= ubnd[ 1 ]; i++ ){ - sprintf( keyname, "C%dPIX%d", m, i ); - if( GetValue2( ret, this, keyname, AST__FLOAT, (void *) &dval, 0, - method, class, status ) && - ( encoding == FITSPC_ENCODING || - encoding == FITSIRAF_ENCODING ) ){ - sprintf( keyname, "CRPIX%d%c", i, ss ); - SetValue( ret, keyname, (void *) &dval, AST__FLOAT, - CardComm( this, status ), status ); - } - } - ss++; - } - } - -/* CmYPEi keywords - --------------- */ - if( astKeyFields( this, "C%1dYPE%d", 2, ubnd, lbnd ) ){ - ss = 'A'; - for( m = lbnd[ 0 ]; m <= ubnd[ 0 ]; m++ ){ - for( i = lbnd[ 1 ]; i <= ubnd[ 1 ]; i++ ){ - sprintf( keyname, "C%dYPE%d", m, i ); - if( GetValue2( ret, this, keyname, AST__STRING, (void *) &cval, 0, - method, class, status ) && - ( encoding == FITSPC_ENCODING || - encoding == FITSIRAF_ENCODING ) ){ - sprintf( keyname, "CTYPE%d%c", i, ss ); - SetValue( ret, keyname, (void *) &cval, AST__STRING, - CardComm( this, status ), status ); - } - } - ss++; - } - } - -/* CmNITi keywords - --------------- */ - if( astKeyFields( this, "C%1dNIT%d", 2, ubnd, lbnd ) ){ - ss = 'A'; - for( m = lbnd[ 0 ]; m <= ubnd[ 0 ]; m++ ){ - for( i = lbnd[ 1 ]; i <= ubnd[ 1 ]; i++ ){ - sprintf( keyname, "C%dNIT%d", m, i ); - if( GetValue2( ret, this, keyname, AST__STRING, (void *) &cval, 0, - method, class, status ) && - ( encoding == FITSPC_ENCODING || - encoding == FITSIRAF_ENCODING ) ){ - sprintf( keyname, "CUNIT%d%c", i, ss ); - SetValue( ret, keyname, (void *) &cval, AST__STRING, - CardComm( this, status ), status ); - } - } - ss++; - } - } - -/* CmELTi keywords - --------------- */ - if( astKeyFields( this, "C%1dELT%d", 2, ubnd, lbnd ) ){ - ss = 'A'; - for( m = lbnd[ 0 ]; m <= ubnd[ 0 ]; m++ ){ - -/* Create a PCj_is matrix by copying the PCjjjiii values and rename CmELTi as - CDELTis. */ - -/* Do each row in the matrix. */ - for( j = 0; j < naxis; j++ ){ - -/* Get the CDELT value for this row. Report an error if not present. */ - sprintf( keyname, "C%dELT%d", m, j + 1 ); - GetValue2( ret, this, keyname, AST__FLOAT, (void *) &cdeltj, 1, - method, class, status ); - -/* If CDELT is zero, use one hundredth of the corresponding CRVAL value - instead, or 1.0 if CRVAL is zero. Otherwise, the zeros could cause the - matrix to be non-invertable. The Mapping could then not be simplified - or used by a Plot. CDELT values of zero are usually used to indicate - "redundant" axes. For instance, a 2D image may be stored as a 3D cube - with a single plane with the "redundant" 3rd axis used to specify the - wavelength of the filter. The actual value used for CDELT shouldn't - matter since the axis only spans a single pixel anyway. */ - if( cdeltj == 0.0 ){ - GetValue2( ret, this, FormatKey( "CRVAL", j + 1, -1, ss, status ), AST__FLOAT, - (void *) &dval, 1, method, class, status ); - cdeltj = 0.01*dval; - if( cdeltj == 0.0 ) cdeltj = 1.0; - } - -/* Save it as CDELTis */ - sprintf( keyname, "CDELT%d%c", j + 1, ss ); - SetValue( ret, keyname, (void *) &cdeltj, AST__FLOAT, - CardComm( this, status ), status ); - -/* Do each column in the matrix. */ - for( i = 0; i < naxis; i++ ){ - -/* Get the PCiiijjj matrix element */ - sprintf( keyname, "PC%.3d%.3d", j + 1, i + 1 ); - if( GetValue2( ret, this, keyname, AST__FLOAT, (void *) &dval, 0, - method, class, status ) ){ - } else if( i == j ) { - dval = 1.0; - } else { - dval = 0.0; - } - -/* Store it as PCi_js. */ - SetValue( ret, FormatKey( "PC", j + 1, i + 1, ss, status ), - (void *) &dval, AST__FLOAT, NULL, status ); - } - } - ss++; - } - } - -/* EPOCH keywords - ------------ */ - -/* Get any EPOCH card, marking it as read. */ - if( GetValue2( ret, this, "EPOCH", AST__FLOAT, (void *) &dval, 0, method, - class, status ) ){ - -/* Convert values of zero to B1950. */ - if( dval == 0.0 ) dval = 1950.0; - -/* Save a new EQUINOX card in the FitsChan, so long as there is not - already one there. */ - if( !GetValue2( ret, this, "EQUINOX", AST__STRING, (void *) &cval, 0, - method, class, status ) ){ - SetValue( ret, "EQUINOX", (void *) &dval, AST__FLOAT, - "Reference equinox", status ); - } - } - -/* String EQUINOX values - --------------------- - If found, EQUINOX will be used in favour of any EPOCH value found - above. */ - if( GetValue2( ret, this, "EQUINOX", AST__STRING, (void *) &cval, 0, method, - class, status ) ){ - -/* Note the first character. */ - bj = cval[ 0 ]; - -/* If it is "B" or "J", read a floating value from the rest */ - if( bj == 'B' || bj == 'J' ) { - if( 1 == astSscanf( cval + 1, " %lf ", &dval ) ){ - -/* If it is a Besselian epoch, convert to Julian. */ - if( bj == 'B' ) dval = palEpj( palEpb2d( dval ) ); - -/* Replace the original EQUINOX card. */ - SetValue( ret, "EQUINOX", (void *) &dval, AST__FLOAT, - CardComm( this, status ), status ); - } - } - } - -/* EQUINOX = 0.0 keywords - ---------------------- */ - if( GetValue2( ret, this, "EQUINOX", AST__FLOAT, (void *) &dval, 0, method, - class, status ) ){ - if( dval == 0.0 ){ - dval = 1950.0; - SetValue( ret, "EQUINOX", (void *) &dval, AST__FLOAT, - CardComm( this, status ), status ); - } - } - } - -/* DATE-OBS keywords - ---------------- */ - -/* Read any DATE-OBS card. This prevents it being written out when the - FitsChan is deleted. */ - if( s == ' ' ) { - strcpy( keyname, "DATE-OBS" ); - if( GetValue2( ret, this, keyname, AST__STRING, (void *) &cval, 0, method, - class, status ) ){ - -/* Ignore DATE-OBS values if the header contains an MJD-OBS value */ - strcpy( keyname, "MJD-OBS" ); - if( !GetValue2( ret, this, keyname, AST__FLOAT, (void *) &dval, 0, - method, class, status ) ){ - -/* Get the corresponding mjd-obs value, checking that DATE-OBS is valid. */ - dval = DateObs( cval, status ); - if( dval != AST__BAD ){ - SetValue( ret, keyname, (void *) &dval, AST__FLOAT, - "Date of observation", status ); - } - } - } - } - -/* Things specific to the CLASS encoding - ------------------------------------- */ - if( encoding == FITSCLASS_ENCODING ) ClassTrans( this, ret, axlat, - axlon, method, class, status ); - -/* Convert SAO distorted TAN headers to TPN distorted TAN headers. - -------------------------------------------------------------- */ - if( s == ' ' && !Ustrcmp( prj, "-TAN", status ) ){ - -/* Translate the COi_m keywords into PV i+m keywords. */ - if( SAOTrans( this, ret, method, class, status ) ) { - -/* Change the CTYPE projection form TAN to TPV. */ - strcpy( prj, "-TPN" ); - strcpy( lontype + 4, "-TPN" ); - cval = lontype; - SetValue( ret, FormatKey( "CTYPE", axlon + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - strcpy( lattype + 4, "-TPN" ); - cval = lattype; - SetValue( ret, FormatKey( "CTYPE", axlat + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - } - } - -/* AIPS "NCP" projections - --------------------- */ - -/* Compare the projection type with "-NCP" */ - if( !Ustrcmp( prj, "-NCP", status ) ) { - -/* Get the latitude reference value, and take is cot. */ - GetValue2( ret, this, FormatKey( "CRVAL", axlat + 1, -1, s, status ), - AST__FLOAT, (void *) &dval, 1, method, class, status ); - sinval = sin( dval*AST__DD2R ); - if( sinval != 0.0 ) { - dval = cos( dval*AST__DD2R )/sinval; - -/* Replace NCP with SIN in the CTYPE values. */ - strcpy( lontype + 4, "-SIN" ); - cval = lontype; - SetValue( ret, FormatKey( "CTYPE", axlon + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - strcpy( lattype + 4, "-SIN" ); - cval = lattype; - SetValue( ret, FormatKey( "CTYPE", axlat + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - -/* Store the new projection parameters using names suitable to FITS_WCS - encoding. */ - SetValue( ret, FormatKey( "PV", axlat + 1, 2, s, status ), - (void *) &dval, AST__FLOAT, NULL, status ); - dval = 0.0; - SetValue( ret, FormatKey( "PV", axlat + 1, 1, s, status ), - (void *) &dval, AST__FLOAT, NULL, status ); - } - } - -/* CLASS "ATF" projections - ---------------------- */ - -/* Replace ATF with AIT in the CTYPE values. */ - if( !Ustrcmp( prj, "-ATF", status ) ) { - strcpy( lontype + 4, "-AIT" ); - cval = lontype; - SetValue( ret, FormatKey( "CTYPE", axlon + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - strcpy( lattype + 4, "-AIT" ); - cval = lattype; - SetValue( ret, FormatKey( "CTYPE", axlat + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - } - -/* AIPS "GLS" projections - --------------------- */ - -/* Compare the projection type with "-GLS" */ - if( !Ustrcmp( prj, "-GLS", status ) ) { - -/* Convert to "-SFL" */ - strcpy( lontype + 4, "-SFL" ); - cval = lontype; - SetValue( ret, FormatKey( "CTYPE", axlon + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - strcpy( lattype + 4, "-SFL" ); - cval = lattype; - SetValue( ret, FormatKey( "CTYPE", axlat + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - -/* FITS-WCS paper 2 (sec. 6.1.4) describes how to handle AIPS GLS - projections, but requires that the axes are not rotated. Instead, we - modify the native latitude at the fiducial point, theta_0, as is done - in wcslib function celfix in file wcsfix.c (see also FITS-WCS paper - II sec. 2.5). We only need to change theta_0 if the CRVAL position is - not the celestial origin. */ - shifted = 0; - sprintf( keyname, "CRVAL%d", axlon + 1 ); - if( GetValue2( ret, this, keyname, AST__FLOAT, (void *) &dval, 0, - method, class, status ) ){ - if( dval != 0.0 ) shifted = 1; - } - sprintf( keyname, "CRVAL%d", axlat + 1 ); - if( GetValue2( ret, this, keyname, AST__FLOAT, (void *) &dval, 0, - method, class, status ) ){ - if( dval != 0.0 ) shifted = 1; - } - - if( 0 && shifted ) { - SetValue( ret, FormatKey( "PV", axlon + 1, 2, s, status ), - (void *) &dval, AST__FLOAT, NULL, status ); - dval = 0.0; - SetValue( ret, FormatKey( "PV", axlon + 1, 1, s, status ), - (void *) &dval, AST__FLOAT, NULL, status ); - dval = 1.0; - SetValue( ret, FormatKey( "PV", axlon + 1, 0, s, status ), - (void *) &dval, AST__FLOAT, NULL, status ); - } - } - -/* Rename any "QV" projection parameters to "PV" (such as used by - -TAB to indicate the interpolation method, or by the internal - -TPN projection to indicate distortion coefficients). - ------------------------------------------------------------ */ - -/* Rewind the FitsChan. */ - astClearCard( this ); - -/* Search the FitsChan for QV cards. */ - if( s != ' ' ) { - sprintf( template, "QV%%d_%%d%c", s ); - } else { - strcpy( template, "QV%d_%d" ); - } - while( FindKeyCard( this, template, method, class, status ) && astOK ) { - -/* If the projection name is "TAN", replace TAN with TPN in the CTYPE values. */ - if( !Ustrcmp( prj, "-TAN", status ) ){ - strcpy( prj, "-TPN" ); - strcpy( lontype + 4, "-TPN" ); - cval = lontype; - SetValue( ret, FormatKey( "CTYPE", axlon + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - strcpy( lattype + 4, "-TPN" ); - cval = lattype; - SetValue( ret, FormatKey( "CTYPE", axlat + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - } - -/* Indicate that the QV card has been consumed. */ - MarkCard( this, status ); - -/* Get the keyword name and change it from QV to PV. */ - strcpy( keyname, CardName( this, status ) ); - keyname[ 0 ] ='P'; - -/* Store the new PV card so long as there it is not already present in the - FitsChan. */ - if( !GetValue2( ret, this, keyname, AST__FLOAT, (void *) &cval, 0, - method, class, status ) ){ - SetValue( ret, keyname, CardData( this, &size, status ), AST__FLOAT, - CardComm( this, status ), status ); - } - -/* Move on to the next card. */ - MoveCard( this, 1, method, class, status ); - } - - - -/* Change any TAN projection to TPN projection if the PolyTan attribute - is non-zero. Also change any TPV projection to TPN projection. - --------------------------------------------------- */ - if( ( !Ustrcmp( prj, "-TAN", status ) && - GetUsedPolyTan( this, ret, axlat + 1, axlon + 1, s, method, class, status ) ) || - !Ustrcmp( prj, "-TPV", status ) ){ - strcpy( prj, "-TPN" ); - strcpy( lontype + 4, "-TPN" ); - cval = lontype; - SetValue( ret, FormatKey( "CTYPE", axlon + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - strcpy( lattype + 4, "-TPN" ); - cval = lattype; - SetValue( ret, FormatKey( "CTYPE", axlat + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - } - - - -/* IRAF "ZPX" projections - --------------------- */ - if( s == ' ' && !Ustrcmp( prj, "-ZPX", status ) ) { - -/* Replace "ZPX" with "ZPN-ZPX" (i.e. ZPN projection with ZPX distortion - code) in the CTYPE values. */ - strcpy( lontype + 4, "-ZPN-ZPX" ); - cval = lontype; - SetValue( ret, FormatKey( "CTYPE", axlon + 1, -1, ' ', status ), - (void *) &cval, AST__STRING, NULL, status ); - strcpy( lattype + 4, "-ZPN-ZPX" ); - cval = lattype; - SetValue( ret, FormatKey( "CTYPE", axlat + 1, -1, ' ', status ), - (void *) &cval, AST__STRING, NULL, status ); - -/* Check latitude then longitude axes */ - for( i = 0; i < 2; i++ ){ - iaxis = i ? axlat : axlon; - -/* Concatenate all the IRAF "WAT" keywords together for this axis. These - keywords are marked as having been used, so that they are not written - out when the FitsChan is deleted. */ - watmem = ConcatWAT( this, iaxis, method, class, status ); - -/* Search the total WAT string for any projp terms. */ - if( watmem ){ - for( iproj = 0; iproj < 10 && astOK; iproj++ ) { - sprintf( format, "projp%d=", iproj ); - start = strstr( watmem, format ); - if( start ) { - sprintf( format, "projp%d=%%lf", iproj ); - if( astSscanf( start, format, &projp ) ){ - SetValue( ret, FormatKey( "PV", axlat + 1, iproj, ' ', status ), - (void *) &projp, AST__FLOAT, - "ZPN projection parameter", status ); - } - } - } - -/* Release the memory used to hold the concatenated WAT keywords. */ - watmem = (char *) astFree( (void *) watmem ); - } - } - -/* IRAF "TNX" projections - --------------------- */ - } else if( s == ' ' && !Ustrcmp( prj, "-TNX", status ) ) { - -/* Replace TNX with TPN in the CTYPE values. */ - strcpy( lontype + 4, "-TPN" ); - cval = lontype; - SetValue( ret, FormatKey( "CTYPE", axlon + 1, -1, ' ', status ), - (void *) &cval, AST__STRING, NULL, status ); - strcpy( lattype + 4, "-TPN" ); - cval = lattype; - SetValue( ret, FormatKey( "CTYPE", axlat + 1, -1, ' ', status ), - (void *) &cval, AST__STRING, NULL, status ); - -/* Check latitude then longitude axes */ - for( i = 0; i < 2; i++ ){ - iaxis = i ? axlat : axlon; - -/* Concatenate all the IRAF "WAT" keywords together for this axis. These - keywords are marked as having been used, so that they are not written - out when the FitsChan is deleted. */ - watmem = ConcatWAT( this, iaxis, method, class, status ); - -/* Extract the polynomial coefficients from the concatenated WAT string. - These are returned in the form of a list of PVi_m values for a TPN - projection. */ - ncoeff = WATCoeffs( watmem, i, &cvals, &mvals, &ok, status ); - -/* If we can handle the TNX projection, store the PV values in the FitsChan. */ - if( ok ) { - for( icoeff = 0; icoeff < ncoeff; icoeff++ ) { - SetValue( ret, FormatKey( "PV", iaxis + 1, mvals[ icoeff ], - ' ', status ), - (void *) (cvals + icoeff), AST__FLOAT, - "TAN projection parameter", status ); - } - -/* If the TNX cannot be represented in FITS-WCS (within our restrictions), add - warning keywords to the FitsChan. */ - } else { - Warn( this, "tnx", "This FITS header includes, or was " - "derived from, a TNX projection which requires " - "unsupported IRAF-specific corrections. The WCS " - "information may therefore be incorrect.", method, class, status ); - } - -/* Release the memory used to hold the concatenated WAT keywords. */ - watmem = (char *) astFree( (void *) watmem ); - } - } - -/* MSX CAR projections. - ------------------- */ - if( !Ustrcmp( prj, "-CAR", status ) && !astGetCarLin( this ) ) { - -/* The CAR projection has valid projection plane points only for native - longitudes in the range [-180,+180]. The reference pixel (CRPIX) is at - native longitude zero. We need to check that the reference point is not - so far outside the image that the entire image lies outside the range - [-180,+180]. If it is, we modify the CRPIX value by the number of - pixels corresponding to 360 degres of longitude in order to bring the - array into the valid domain ([-180,+180]) of the projection. */ - if( GetValue2( ret, this, FormatKey( "CDELT", axlon + 1, -1, s, status ), - AST__FLOAT, (void *) &cdelti, 1, method, class, status ) && - GetValue2( ret, this, FormatKey( "CRPIX", axlon + 1, -1, s, status ), - AST__FLOAT, (void *) &dval, 0, method, class, status ) ) { - -/* We check if the mid point of the array is in the valiud longitude range. Use the - bottom left corner as a fallback if the image size is unknown. */ - if( !GetValue( this, FormatKey( "NAXIS", axlon + 1, -1, ' ', status ), - AST__INT, &dim, 0, 0, method, class, status ) ) { - dim = 0; - } - - if( cdelti != 0.0 ) { - double offset = 0.5*( dim + 1 ); - dval = offset + AST__DR2D*palDrange( AST__DD2R*( dval - offset )*cdelti )/cdelti; - SetValue( ret, FormatKey( "CRPIX", axlon + 1, -1, s, status ), - (void *) &dval, AST__FLOAT, CardComm( this, status ), status ); - } - } - } - -/* Replace RESTFREQ by RESTFRQ. - ---------------------------- */ - -/* Get any RESTFREQ card, marking it as read. */ - if( s != ' ' ) { - sprintf( keyname, "RESTFREQ%c", s ); - } else { - strcpy( keyname, "RESTFREQ" ); - } - if( GetValue2( ret, this, keyname, AST__FLOAT, (void *) &dval, 0, method, - class, status ) ){ - -/* Look for "MHz" and "GHz" within the comment. If found scale the value - into Hz. */ - comm = CardComm( this, status ); - if( comm ) { - if( strstr( comm, "GHz" ) ) { - dval *= 1.0E9; - comm = "[Hz] Rest Frequency"; - } else if( strstr( comm, "MHz" ) ) { - dval *= 1.0E6; - comm = "[Hz] Rest Frequency"; - } - } - -/* Save a new RESTFRQ card in the FitsChan, so long as there is not - already one there. */ - if( s != ' ' ) { - sprintf( keyname, "RESTFRQ%c", s ); - } else { - strcpy( keyname, "RESTFRQ" ); - } - if( !GetValue2( ret, this, keyname, AST__STRING, (void *) &cval, 0, - method, class, status ) ){ - SetValue( ret, keyname, (void *) &dval, AST__FLOAT, comm, status ); - } - } - -/* Translate AIPS spectral CTYPE values to FITS-WCS paper III equivalents. - These are of the form AAAA-BBB, where "AAAA" can be "FREQ", "VELO" (=VRAD!) - or "FELO" (=VOPT-F2W), and BBB can be "LSR", "LSD", "HEL" (=*Bary*centric!) - or "GEO". Also convert "LAMBDA" to "WAVE". */ - for( j = 0; j < naxis; j++ ) { - if( GetValue2( ret, this, FormatKey( "CTYPE", j + 1, -1, s, status ), - AST__STRING, (void *) &cval, 0, method, - class, status ) ){ - if( IsAIPSSpectral( cval, &astype, &assys, status ) ) { - SetValue( ret, FormatKey( "CTYPE", j + 1, -1, s, status ), - (void *) &astype, AST__STRING, NULL, status ); - SetValue( ret, "SPECSYS", (void *) &assys, AST__STRING, NULL, status ); - break; - } else if( !strcmp( cval, "LAMBDA " ) ) { - cval = "WAVE"; - SetValue( ret, FormatKey( "CTYPE", j + 1, -1, s, status ), - (void *) &cval, AST__STRING, NULL, status ); - break; - } - } - } - -/* Common case insensitive CUNIT values: "Hz", "Angstrom", "km/s", "M/S" */ - if( s != ' ' ) { - sprintf( template, "CUNIT%%d%c", s ); - } else { - strcpy( template, "CUNIT%d" ); - } - if( astKeyFields( this, template, 1, &jhi, &jlo ) ){ - -/* Convert keyword indices from 1-based to 0-base, and loop round them all. */ - jhi--; - jlo--; - for( j = jlo; j <= jhi; j++ ){ - char *keynam; - keynam = FormatKey( "CUNIT", j + 1, -1, s, status ); - if( GetValue2( ret, this, keynam, AST__STRING, (void *) &cval, 0, - method, class, status ) ){ - size_t nc = astChrLen( cval ); - if( nc == 0 ) { - cval = NULL; - } else if( !Ustrcmp( cval, "Hz", status ) ) { - cval = "Hz"; - } else if( !Ustrcmp( cval, "Angstrom", status ) ) { - cval = "Angstrom"; - } else if( !Ustrcmp( cval, "km/s", status ) ) { - cval = "km/s"; - } else if( !Ustrcmp( cval, "m/s", status ) ) { - cval = "m/s"; - } else { - cval = NULL; - } - if( cval ) SetValue( ret, keynam, (void *) &cval, AST__STRING, NULL, status ); - } - } - } - -/* After doing the primary axis descriptions, prepare to do the "A" - description. */ - if( s == ' ' ) s = 'A' - 1; - } - -/* IRAF mini-WCS keywords - ---------------------- */ - -/* Rewind the FitsChan to search from the first card. */ - astClearCard( this ); - -/* Search forward through until all cards have been checked. */ - while( !astFitsEof( this ) && astOK ){ - -/* Check to see if the keyword name from the current card matches - any of the known mini-WCS keywords. If so, mark the card as read. */ - if( Match( CardName( this, status ), "WAT%d_%d", 0, NULL, &m, method, class, status ) || - Match( CardName( this, status ), "LTM%d_%d", 0, NULL, &m, method, class, status ) || - Match( CardName( this, status ), "LTV%d", 0, NULL, &m, method, class, status ) || - Match( CardName( this, status ), "WSV%d_LEN", 0, NULL, &m, method, class, status ) || - Match( CardName( this, status ), "WSV%d_%d", 0, NULL, &m, method, class, status ) ){ - MarkCard( this, status ); - } - -/* Now move the current card on to the next card. */ - MoveCard( this, 1, method, class, status ); - } - -/* Delete the returned FitsChan if it is empty. */ - if( ret && !astGetNcard( ret ) ) ret = (AstFitsChan *) astDelete( ret ); - -/* Return. */ - return ret; -} - -int Split( AstFitsChan *this, const char *card, char **name, char **value, - char **comment, const char *method, const char *class, int *status ){ -/* -* Name: -* Split - -* Purpose: -* Extract the keyword name, value and comment from a FITS header card. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int Split( AstFitsChan *this, const char *card, char **name, char **value, -* char **comment, const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* The name, value and comment (if present) are extracted from the -* supplied card text and returned. - -* Parameters: -* this -* Pointer to the FitsCHan. -* card -* Pointer to a string holding the FITS header card. -* name -* Pointer to a location at which to return the pointer to a string -* holding the keyword name. -* value -* Pointer to a location at which to return the pointer to a string -* holding the keyword value. -* comment -* Pointer to a location at which to return the pointer to a string -* holding the keyword comment. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned value: -* - An integer identifying the data type of the keyword value. This -* will be one of the values AST__UNDEF, AST__COMMENT, AST__INT, -* AST__STRING, AST__CONTINUE, AST__FLOAT, AST__COMPLEXI or AST__COMPLEXF -* defined in fitschan.h. - -* Notes: -* - If the keyword value is a string, then the returned value does not -* include the delimiting quotes, and pairs of adjacent quotes within the -* string are replaced by single quotes. -* - A maximum of 80 characters are read from the supplied card, so the -* string does not need to be null terminated unless less than 80 -* characters are to be read. -* - The memory holding the three strings "name", "value" and "comment" -* should be released when no longer needed using astFree. -* - NULL pointers and a data type of AST__COMMENT are returned if an -* error has already occurred, or if this function fails for any reason. -*/ - -/* Local Variables: */ - char *c; /* Pointer to returned comment string */ - char *dd; /* Pointer to intermediate character */ - char *slash; /* Pointer to comment character */ - char *v; /* Pointer to returned value string */ - char buf[255]; /* Buffer for warning text */ - const char *d; /* Pointer to first comment character */ - const char *v0; /* Pointer to first non-blank value character */ - double fi, fr; /* Values read from value string */ - int badval; /* Is the keyword value illegal? */ - int blank_name; /* Is keyword name blank? */ - int cont; /* Is this a continuation card? */ - int i; /* Character index */ - int ii, ir; /* Values read from value string */ - int iopt; /* Index of option within list */ - int len; /* Used length of value string */ - int lq; /* Was previous character an escaping quote? */ - int nch; /* No. of characters used */ - int ndig; /* No. of digits in the formatted integer */ - int type; /* Keyword data type */ - size_t nc; /* Number of character in the supplied card */ - size_t ncc; /* No. of characters in the comment string */ - size_t ncv; /* No. of characters in the value string */ - -/* Initialise the returned pointers. */ - *name = NULL; - *value = NULL; - *comment = NULL; - type = AST__COMMENT; - -/* Check the global status. */ - if( !astOK ) return type; - -/* Assume initially that the keyword value is legal. */ - badval = 0; - -/* Store the number of characters to be read from the supplied card. This - is not allowed to be more than the length of a FITS header card. */ - nc = 0; - while( nc < AST__FITSCHAN_FITSCARDLEN && card[ nc ] ) nc++; - -/* Reduce the number of characters to read so that any non-printing - characters such as new-lines at the end of the string are ignored. */ - while( nc > 0 && !isprint( card[ nc - 1 ] ) ) nc--; - -/* Allocate memory for a copy of the keyword name plus a terminating - null character. */ - *name = (char *) astMalloc( ( 1 + FITSNAMLEN )*sizeof(char) ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Initialise the name string by filling it with spaces, and terminating it. */ - for( i = 0; i < FITSNAMLEN; i++ ) (*name)[ i ] = ' '; - (*name)[ FITSNAMLEN ] = 0; - -/* Copy the the keyword name, ensuring that no more than FITSNAMLEN (8) - characters are copied. */ - strncpy( *name, card, ( nc > FITSNAMLEN ) ? FITSNAMLEN : nc ); - -/* If there is no keyword name, flag that we have a blank name which will - be treated as a comment card. */ - if( strspn( *name, " " ) == strlen( *name ) ){ - blank_name = 1; - -/* If the card contains a keyword name, replace any white space with - nulls. */ - } else { - blank_name = 0; - dd = *name + strlen( *name ) - 1; - while( isspace( *dd ) ) *(dd--) = 0; - } - -/* Check the keyword name is legal. */ - CheckFitsName( this, *name, method, class, status ); - -/* Allocate memory to hold the keyword value and comment strings. */ - *value = (char *) astMalloc( sizeof(char)*( 2 + nc ) ); - *comment = (char *) astMalloc( sizeof(char)*( 1 + nc ) ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Check for CONTINUE cards. These have keyword CONTINUE but have a space - instead of an equals sign in column 9. They must also have a single quote - in column 11. */ - cont = ( !Ustrcmp( *name, "CONTINUE", status ) && - nc > FITSNAMLEN + 3 && - card[ FITSNAMLEN ] == ' ' && - card[ FITSNAMLEN + 2 ] == '\'' ); - -/* If column 9 does not contain an equals sign (but is not a CONTINUE card), or if - the keyword is "HISTORY", "COMMENT" or blank, then columns 9 to the end are - comment characters, and the value string is null. */ - if( ( nc <= FITSNAMLEN || card[ FITSNAMLEN ] != '=' - || !Ustrcmp( *name, "HISTORY", status ) - || !Ustrcmp( *name, "COMMENT", status ) - || blank_name ) && !cont ){ - (*value)[ 0 ] = 0; - if( nc > FITSNAMLEN ){ - (void) strncpy( *comment, card + FITSNAMLEN, - nc - FITSNAMLEN ); - (*comment)[ nc - FITSNAMLEN ] = 0; - } else { - (*comment)[ 0 ] = 0; - } - -/* Otherwise there is a value field. */ - } else { - -/* Find the first non-blank character in the value string. */ - v0 = card + FITSNAMLEN + 1; - while( (size_t)(v0 - card) < nc && - isspace( (int) *v0 ) ) v0++; - -/* Store pointers to the start of the returned value and comment strings. */ - v = *value; - c = *comment; - -/* If the first character in the value string is a single quote, the value is - a string. In this case the value ends at the first non-escaped single - quote. */ - if( *v0 == '\''){ - type = cont ? AST__CONTINUE : AST__STRING; - -/* We want to copy the string value, without the delimiting quotes, to the - returned value string. Single quotes within the string are represented - by two adjacent quotes, so we also need to check for these and replace - them by one quote in the returned string. First initialise a pointer - to the first character after the opening quote, and set a flag - indicating that (for the purposes of identifying pairs of adjacent - quotes within the string) the previous character was not a quote. */ - d = v0 + 1; - lq = 0; - -/* Loop round each remaining character in the supplied card. */ - while( (size_t)(d - card) < nc ){ - -/* If the current character is a single quote... */ - if( *d == '\'' ){ - -/* If the previous character was also a single quote then the quote does - not mark the end of the string, but is a quote to be included literally - in the value. Copy the quote to the returned string and clear the flag - to indicate that the pair of adjacent quotes is now complete. */ - if( lq ){ - *(v++) = '\''; - lq = 0; - -/* If the last character was not a quote, then set the flag for the next - pass through the loop, but do not copy the quote to the returned string - since it will either be a quote escaping a following adjacent quote, or - a quote to mark the end of the string. */ - } else { - lq = 1; - } - -/* If the current character is not a quote... */ - } else { - -/* If the previous character was a quote, then we have found a single - isolated quote which therefore marks the end of the string value. - The pointer "d" is left pointing to the first character - after the terminating quote. */ - if( lq ){ - break; - -/* If the last character was not a quote, copy it to the returned string. */ - } else { - *(v++) = *d; - } - } - d++; - } - -/* Terminate the returned value string. */ - *v = 0; - -/* Now deal with logical and numerical values. */ - } else { - -/* The end of the value field is marked by the first "/". Find the number - of characters in the value field. Pointer "d" is left pointing to the - first character in the comment (if any). Only use "/" characters which - occur within the first nc characters, and do not occur wiuthin the - keyword name (not strictly legal, but a warning will have been issued - by CheckFitsName in such cases). */ - d = strchr( card + FITSNAMLEN, '/' ); - if( !d || ( d - card ) >= nc ){ - ncv = nc - FITSNAMLEN - 1; - d = NULL; - } else { - ncv = (size_t)( d - card ) - FITSNAMLEN - 1; - } - -/* Copy the value string to the returned string. */ - if( ncv == 0 ){ - *v = 0; - } else { - strncpy( v, card + FITSNAMLEN + 1, ncv ); - v[ ncv ] = ' '; - v[ ncv + 1 ] = 0; - } - -/* Find the first non-blank character in the value string. */ - v0 = v; - while( *v0 && isspace( (int) *v0 ) ) v0++; - -/* See if the value string is one of the following strings (optionally - abbreviated and case insensitive): YES, NO, TRUE, FALSE. */ - iopt = FullForm( "YES NO TRUE FALSE", v0, 1, status ); - -/* Return the single character "T" or "F" at the start of the value string - if the value matches one of the above strings. */ - if( iopt == 0 || iopt == 2 ) { - type = AST__LOGICAL; - strcpy ( v, "T" ); - } else if( iopt == 1 || iopt == 3 ) { - type = AST__LOGICAL; - strcpy ( v, "F" ); - -/* If it does not match, see if the value is numerical. */ - } else { - -/* Save the length of the value string excluding trailing blanks. */ - len = ChrLen( v, status ); - -/* If the entire string is blank, the value type is UNDEF. */ - if( len == 0 ) { - type = AST__UNDEF; - -/* If there are no dots (decimal points) or exponents (D or E) in the value... */ - } else if( !strpbrk( v, ".EeDd" ) ){ - -/* First attempt to read two integers from the string (separated by white - space). */ - if( nch = 0, - ( 2 == astSscanf( v, " %d %d%n", &ir, &ii, &nch ) ) && - ( nch >= len ) ) { - type = AST__COMPLEXI; - -/* If that failed, attempt to read a single integer from the string. */ - } else if( nch = 0, - ( 1 == astSscanf( v, " %d%n", &ir, &nch ) ) && - ( nch >= len ) ) { - type = AST__INT; - } - -/* If there are dots (decimal points) in the value... */ - } else { - -/* First attempt to read two doubles from the string (separated by white - space). */ - if( nch = 0, - ( 2 == astSscanf( v, " %lf %lf%n", &fr, &fi, &nch ) ) && - ( nch >= len ) ) { - type = AST__COMPLEXF; - -/* If that failed, attempt to read a single double from the string. */ - } else if( nch = 0, - ( 1 == astSscanf( v, " %lf%n", &fr, &nch ) ) && - ( nch >= len ) ) { - type = AST__FLOAT; - } - -/* If both the above failed, it could be because the string contains a - "D" exponent (which is probably valid FITS) instead of an "E" exponent. - Replace any "D" in the string with "e" and try again. */ - if( type == AST__COMMENT && astOK ) { - -/* Replace "d" and "D" by "e" (if this doesn't produce a readable floating - point value then the value string will not be used, so it is safe to - do the replacement in situ). */ - for( i = 0; i < len; i++ ) { - if( v[ i ] == 'd' || v[ i ] == 'D' ) v[ i ] = 'e'; - } - -/* Attempt to read two doubles from the edited string (separated by white - space). */ - if( nch = 0, - ( 2 == astSscanf( v, " %lf %lf%n", &fr, &fi, &nch ) ) && - ( nch >= len ) ) { - type = AST__COMPLEXF; - -/* If that failed, attempt to read a single double from the edited string. */ - } else if( nch = 0, - ( 1 == astSscanf( v, " %lf%n", &fr, &nch ) ) && - ( nch >= len ) ) { - type = AST__FLOAT; - } - } - } - } - -/* If the value type could not be determined, indicate that a warning - should be issued. */ - if( type == AST__COMMENT && astOK ) { - badval = 1; - (*value)[ 0 ] = 0; - (*comment)[ 0 ] = 0; - d = NULL; - } - } - -/* Find the number of characters in the comment. Pointer "d" should point to - the first character following the value string. */ - if( d ){ - ncc = nc - (size_t)( d - card ); - } else { - ncc = 0; - } - -/* Copy the remainder of the card to the returned comment string. */ - if( astOK && ncc > 0 ){ - strncpy( c, d, ncc ); - c[ ncc ] = 0; - -/* Find the start of the comment (indicated by the first "/" after the - value string). */ - slash = strchr( c, '/' ); - -/* Temporarily terminate the string at the slash. */ - if( slash ) *slash = 0; - -/* Shuffle the characters following the slash down to the - start of the returned string. */ - if( slash ){ - ncc -= (size_t)( slash - c ) + 1; - d = slash + 1; - for( i = 0; i < 1 + (int) ncc; i++ ) *(c++) = *(d++); - } - -/* If there is no comment string, return a null string. */ - } else { - *c = 0; - } - } - } - } - -/* Truncate the returned string to avoid wasting space. */ - if( *name ) *name = (char *) astRealloc( (void *) *name, strlen( *name ) + 1 ); - if( *comment ) *comment = (char *) astRealloc( (void *) *comment, strlen( *comment ) + 1 ); - if( *value ) *value = (char *) astRealloc( (void *) *value, strlen( *value ) + 1 ); - -/* If the value is deemed to be integer, check that the number of digits - in the formatted value does not exceed the capacity of an int. This may - be the case if there are too many digits in the integer for an "int" to - hold. In this case, change the data type to float. */ - if( *value && type == AST__INT ) { - ndig = 0; - c = *value; - while( *c ) { - if( isdigit( *(c++) ) ) ndig++; - } - if( ndig >= int_dig ) type = AST__FLOAT; - } - -/* If an error occurred, free the returned strings and issue a context message. */ - if( !astOK ){ - *name = (char *) astFree( (void *) *name ); - *value = (char *) astFree( (void *) *value ); - *comment = (char *) astFree( (void *) *comment ); - type = AST__COMMENT; - astError( astStatus, "%s(%s): Unable to store the following FITS " - "header card:\n%.*s\n", status, method, class, - AST__FITSCHAN_FITSCARDLEN, card ); - -/* If a bad keyword value was encountered, issue a warning. Remember that - "card" may not be null terminated, so ensure that only one header is - included from "card". */ - } else if( badval ){ - snprintf( buf, sizeof(buf), "The keyword value is illegal in " - "'%.*s'", AST__FITSCHAN_FITSCARDLEN, card ); - Warn( this, "badkeyvalue", buf, method, class, status ); - } - -/* Return the data type. */ - return type; -} - -static int SplitMap( AstMapping *map, int invert, int ilon, int ilat, - AstMapping **map1, AstWcsMap **map2, AstMapping **map3, int *status ){ -/* -* Name: -* SplitMap - -* Purpose: -* Locate a WCS projection within a Mapping. - -* Type: -* Private function. - -* Synopsis: -* int SplitMap( AstMapping *map, int invert, int ilon, int ilat, -* AstMapping **map1, AstWcsMap **map2, AstMapping **map3, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* If possible, the supplied Mapping is decomposed into three component -* mappings to be compounded in series. To be acceptable, the second of -* these three Mappings must be an inverted WcsMap with a non-zero -* FITSProj attribute value, and there must not be such a WcsMap in -* either of the other two Mappings. If it is not possible to produce -* such a group of three Mappings, then a zero function value is returned, -* together with three NULL Mapping pointers. All the mappings before the -* WcsMap are compounded together and returned as "map1". The inverse of -* the WcsMap itself is returned as "map2", and any remaining Mappings -* are compounded together and returned as "map3". -* -* The search algorithm allows for an arbitrary combination of series and -* parallel CmpMaps. - -* Parameters: -* map -* A pointer to the Mapping from pixel to physical coordinates. -* invert -* The value of the Invert attribute to use with "map" (the value -* returned by astGetInvert is not used). -* ilon -* Index of mapping output which is connected to the longitude axis. -* ilat -* Index of mapping output which is connected to the latitude axis. -* map1 -* A location at which to return a pointer to the Mapping from pixel -* to intermediate world coordinates. -* map2 -* A location at which to return a pointer to the Mapping from -* intermediate world coordinates to native spherical coordinates. This -* will be an inverted WcsMap with non-zero FITSProj attribute value. -* map3 -* A location at which to return a pointer to the Mapping from -* native spherical coordinates to physical coordinates. -* dep -* The address of an integer holding the current depth of recursion -* into this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a suitable WcsMap was found, zero otherwise. - -* Notes: -* - The returned Mappings contain independant copies of the relevant -* components of the supplied Mapping and can be modified without -* changing the supplied Mapping. -* - NULL pointers will be returned for all Mappings if no WcsMap -* can be found in the supplied Mapping. -* - A pointer to a UnitMap will be returned for map1 if no mappings -* exist before the WcsMap. -* - A pointer to a UnitMap will be returned for map3 if no mappings -* exist after the WcsMap. -* - NULL pointers will be returned for all Mappings and a function -* value of zero will be returned if an error has occurred, or if this -* function should fail for any reason. -*/ - -/* Local Variables */ - AstFitsChan *fc; /* Pointer to temporary FitsChan */ - AstFrameSet *tfs; /* Temporary FrameSet */ - AstMapping *mapa; /* Pre-wcs Mapping */ - AstMapping *mapc; /* Post-wcs Mapping */ - AstMapping *tmap1; /* Temporary Mapping */ - AstMapping *tmap2; /* Temporary Mapping */ - AstPointSet *pset1; /* Pixel positions */ - AstPointSet *pset2; /* WCS positions */ - AstWcsMap *mapb; /* WcsMap */ - char card[ AST__FITSCHAN_FITSCARDLEN + 1 ]; /* Buffer for header card */ - double **ptr1; /* Pointer to pixel axis values */ - double **ptr2; /* Pointer to WCS axis values */ - double *iwc_origin; /* Array holding IWC at pixel origin */ - double *pix_origin; /* Array holding pixel coords at pixel origin */ - double *w1; /* Pointer to work space */ - int i; /* Loop index */ - int npix; /* Number of pixel axes */ - int nwcs; /* Number of WCS axes */ - int ret; /* Was a non-linear Mapping found? */ - -/* Initialise */ - *map1 = NULL; - *map2 = NULL; - *map3 = NULL; - ret = 0; - -/* Check the global status. */ - if( !astOK ) return ret; - -/* Call SplitMap2 to do the work. SplitMap2 does not check that the - WcsMap is an *inverted* WcsMap, neither does it check that there - are no WcsMaps in either map1 or map3. */ - if( SplitMap2( map, invert, map1, map2, map3, status ) ) { - -/* Check that the WcsMap is inverted. */ - if( astGetInvert( *map2 ) ) { - -/* Check that map 1 does not contain a WcsMap with non-zero FITSProj - attribute. */ - if( !SplitMap2( *map1, astGetInvert( *map1 ), &mapa, &mapb, &mapc, - status ) ) { - -/* Check that map 3 does not contain a WcsMap with non-zero FITSProj - attribute. */ - if( !SplitMap2( *map3, astGetInvert( *map3 ), &mapa, &mapb, &mapc, - status ) ) { - -/* If so, the three Mappings are OK. */ - ret = 1; - } else { - mapa = astAnnul( mapa ); - mapb = astAnnul( mapb ); - mapc = astAnnul( mapc ); - } - } else { - mapa = astAnnul( mapa ); - mapb = astAnnul( mapb ); - mapc = astAnnul( mapc ); - } - } - } - -/* If the above failed to find a suitable WcsMap, we now consider cases - where the pixel->WCS mapping is linear. We can invent a CAR projection - WcsMap for such cases. We use a ShiftMap to move the origin of the - longitude IWC axis to a sensible value (it is left at zero otherwise). - We cannot do this with the latitude axis since pre-FITS-WCS fits - readers could not handle the resulting rotation from native to celestial - coords. */ - if( !ret && astGetIsLinear( map ) ) { - nwcs = astGetNout( map ); - npix = astGetNin( map ); - iwc_origin = astMalloc( sizeof( double )*nwcs ); - pix_origin = astMalloc( sizeof( double )*npix ); - if( astOK ) { - for( i = 0; i < npix; i++ ) pix_origin[ i ] = 0.0; - astTranN( map, 1, npix, 1, pix_origin, 1, nwcs, 1, iwc_origin ); - for( i = 0; i < nwcs; i++ ) { - if( i != ilon ) { - iwc_origin[ i ] = 0.0; - } else { - iwc_origin[ i ] *= -1; - } - } - mapa = (AstMapping *) astShiftMap( nwcs, iwc_origin, "", status ); - *map1 = (AstMapping *) astCmpMap( map, mapa, 1, "", status ); - *map2 = astWcsMap( nwcs, AST__CAR, ilon + 1, ilat + 1, "Invert=1", status ); - astInvert( mapa ); - *map3 = astClone( mapa ); - mapa = astAnnul( mapa ); - ret = 1; - } - iwc_origin = astFree( iwc_origin ); - pix_origin = astFree( pix_origin ); - } - -/* If the above failed to find a suitable WcsMap, we now consider cases - where the output (long,lat) values are constants supplied by a - final PermMap. We can invent a WcsMap for such cases. */ - if( !ret ) { - -/* Transform two arbitrary pixel positions into the WCS Frame. */ - npix = astGetNin( map ); - nwcs = astGetNout( map ); - pset1 = astPointSet( 2, npix, "", status ); - pset2 = astPointSet( 2, nwcs, "", status ); - ptr1 = astGetPoints( pset1 ); - ptr2 = astGetPoints( pset2 ); - w1 = astMalloc( sizeof( double )*(size_t) nwcs ); - if( astOK ) { - for( i = 0; i < npix; i++ ) { - ptr1[ i ][ 0 ] = 1.0; - ptr1[ i ][ 1 ] = 1000.0; - } - (void) astTransform( map, pset1, 1, pset2 ); - -/* If the two wcs positions have equal longitude and latitude values, - assume that the output longitude and latitude axes are assigned - constant values by the Mapping. */ - if( ptr2[ ilon ][ 0 ] == ptr2[ ilon ][ 1 ] && - ptr2[ ilon ][ 0 ] != AST__BAD && - ptr2[ ilat ][ 0 ] == ptr2[ ilat ][ 1 ] && - ptr2[ ilat ][ 0 ] != AST__BAD ) { - -/* Create a set of Mappings to return, including a WcsMap, which result in - these constant latitude and longitude values. We do this by creating a - FITS-WCS header and reading the FrameSet from it. Keywords which are not - important to the final mappings are given arbitrary values. */ - fc = astFitsChan( NULL, NULL, "", status ); - for( i = 0; i < nwcs; i++ ) { - sprintf( card, "CRPIX%d = 0", i + 1 ); - astPutFits( fc, card, 0 ); - sprintf( card, "CDELT%d = 0.0003", i + 1 ); - astPutFits( fc, card, 0 ); - if( i == ilon ) { - sprintf( card, "CTYPE%d = 'RA---TAN'", i + 1 ); - } else if( i == ilat ) { - sprintf( card, "CTYPE%d = 'DEC--TAN'", i + 1 ); - } else { - sprintf( card, "CTYPE%d = 'DUMMY'", i + 1 ); - } - astPutFits( fc, card, 0 ); - if( i == ilon ) { - sprintf( card, "CRVAL%d = %.*g", i + 1, AST__DBL_DIG, AST__DR2D*ptr2[ ilon ][ 0 ] ); - } else if( i == ilat ) { - sprintf( card, "CRVAL%d = %.*g", i + 1, AST__DBL_DIG, AST__DR2D*ptr2[ ilat ][ 0 ] ); - } else { - sprintf( card, "CRVAL%d = 0.0", i + 1 ); - } - astPutFits( fc, card, 0 ); - } - astClearCard( fc ); - tfs = astRead( fc ); - if( tfs ) { - -/* Use SplitMap to get the required Mapings from the FrameSet. */ - tmap2 = astGetMapping( tfs, AST__BASE, AST__CURRENT ); - SplitMap( tmap2, astGetInvert( tmap2 ), 0, 1, &tmap1, map2, - map3, status ); - tmap1 = astAnnul( tmap1 ); - tmap2 = astAnnul( tmap2 ); - -/* Create a ShiftMap which subtract the constant longitude and latitude - values off the inputs. */ - for( i = 0; i < nwcs; i++ ) w1[ i ] = 0.0; - w1[ ilon ] = -ptr2[ ilon ][ 0 ]; - w1[ ilat ] = -ptr2[ ilat ][ 0 ]; - tmap1 = (AstMapping *) astShiftMap( nwcs, w1, "", status ); - -/* Compose this with the supplied Mapping. This results in the celestial - outputs being zero. This gives the required "map1". */ - *map1 = (AstMapping *) astCmpMap( map, tmap1, 1, "", status ); - -/* Indicate success.*/ - ret = 1; - -/* Free resources. */ - tmap1 = astAnnul( tmap1 ); - tfs = astAnnul( tfs ); - } - fc = astAnnul( fc ); - } - } - -/* Free resources */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - w1 = astFree( w1 ); - } - if( !ret ) { - if( *map1 ) *map1 = astAnnul( *map1 ); - if( *map2 ) *map2 = astAnnul( *map2 ); - if( *map3 ) *map3 = astAnnul( *map3 ); - } - return ret; -} - -static int SplitMap2( AstMapping *map, int invert, AstMapping **map1, - AstWcsMap **map2, AstMapping **map3, int *status ){ -/* -* Name: -* SplitMap2 - -* Purpose: -* Locate a WCS projection within a Mapping. - -* Type: -* Private function. - -* Synopsis: -* int SplitMap2( AstMapping *map, int invert, AstMapping **map1, -* AstWcsMap **map2, AstMapping **map3, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* If possible, the supplied Mapping is decomposed into three component -* mappings to be compounded in series. To be acceptable, the second of -* these three Mappings must be a WcsMap with a non-zero FITSProj value. -* If it is not possible to produce such a group of three Mappings, then a -* zero function value is returned, together with three NULL Mapping -* pointers. All the mappings before the WcsMap are compounded together -* and returned as "map1". The WcsMap itself is returned as "map2", and -* any remaining Mappings are compounded together and returned as "map3". -* -* The search algorithm allows for an arbitrary combination of series and -* parallel CmpMaps. - -* Parameters: -* map -* A pointer to the Mapping from pixel to physical coordinates. -* invert -* The value of the Invert attribute to use with "map" (the value -* returned by astGetInvert is not used). -* map1 -* A location at which to return a pointer to the Mapping from pixel -* to intermediate world coordinates. -* map2 -* A location at which to return a pointer to the Mapping from relative -* physical coordinates to native spherical coordinates. This will -* be a WcsMap, and it will have a non-zero FITSProj value. -* map3 -* A location at which to return a pointer to the Mapping from -* native spherical coordinates to physical coordinates. -* dep -* The address of an integer holding the current depth of recursion -* into this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a suitable WcsMap was found, zero otherwise. - -* Notes: -* - The returned Mappings contain independant copies of the relevant -* components of the supplied Mapping and can be modified without -* changing the supplied Mapping. -* - NULL pointers will be returned for all Mappings if no WcsMap -* with anon-zero FITSProj value can be found in the supplied Mapping. -* - A pointer to a UnitMap will be returned for map1 if no mappings -* exist before the WcsMap. -* - A pointer to a UnitMap will be returned for map3 if no mappings -* exist after the WcsMap. -* - NULL pointers will be returned for all Mappings and a function -* value of zero will be returned if an error has occurred, or if this -* function should fail for any reason. -* - "*map1" and "*map3" may contain WcsMaps, but they will have zero -* values for their FITSProj values. -*/ - -/* Local Variables */ - AstMapping **map_list; /* Mapping array pointer */ - AstMapping *mapa; /* Pre-wcs Mapping */ - AstWcsMap *mapb; /* WcsMap */ - AstMapping *mapc; /* Post-wcs Mapping */ - AstMapping *temp; /* Intermediate Mapping */ - const char *class; /* Pointer to class of supplied Mapping */ - double pv; /* Projection parameter value */ - int *invert_list; /* Invert array pointer */ - int axis; /* No. of axes in whole Mapping */ - int axlat; /* Index of latitude axis */ - int axlon; /* Index of longitude axis */ - int haswcs; /* Was a usable inverted WcsMap found? */ - int imap; /* Index of current Mapping in list */ - int i; /* axis index */ - int m; /* Parameter index */ - int nax; /* No. of axes in Mapping */ - int nmap; /* Number of Mappings in the list */ - int ret; /* Was a non-linear Mapping found? */ - int wcsaxis; /* Index of first WcsMap axis */ - -/* Initialise */ - *map1 = NULL; - *map2 = NULL; - *map3 = NULL; - ret = 0; - -/* Check the global status. */ - if( !astOK ) return ret; - -/* Get the class of the Mapping. */ - class = astGetClass( map ); - -/* If the supplied Mapping is a CmpMap... */ - wcsaxis = -1; - if( !strcmp( class, "CmpMap" ) ){ - -/* Decompose the Mapping into a sequence of Mappings to be applied in - series and an associated list of Invert flags. */ - map_list = NULL; - invert_list = NULL; - nmap = 0; - astMapList( map, 1, invert, &nmap, &map_list, &invert_list ); - -/* If there is more than one Mapping, this must be a series CmpMap. */ - if( nmap > 1 && astOK ){ - -/* Initialise the returned pre-wcs Mapping to be a UnitMap. */ - if( invert == astGetInvert( map ) ){ - *map1 = (AstMapping *) astUnitMap( astGetNin( map ), "", status ); - } else { - *map1 = (AstMapping *) astUnitMap( astGetNout( map ), "", status ); - } - -/* Indicate we have not yet found a WcsMap. */ - ret = 0; - -/* Process each series Mapping. */ - for( imap = 0; imap < nmap; imap++ ){ - -/* If we have not yet found a WcsMap... */ - if( !ret ){ - -/* Search this Mapping for a WcsMap. */ - ret = SplitMap2( map_list[ imap ], invert_list[ imap ], &mapa, - map2, map3, status ); - -/* If no WcsMap was found, use the whole mapping as part of the - pre-wcs Mapping. */ - if( !ret ){ - mapa = astCopy( map_list[ imap ] ); - astSetInvert( mapa, invert_list[ imap ] ); - } - -/* Add the pre-wcs mapping to the cumulative pre-wcs CmpMap. */ - temp = (AstMapping *) astCmpMap( *map1, mapa, 1, "", status ); - *map1 = astAnnul( *map1 ); - mapa = astAnnul( mapa ); - *map1 = temp; - -/* If we have previously found a WcsMap, use the whole mapping - as part of the post-wcs mapping. */ - } else { - mapc = astCopy( map_list[ imap ] ); - astSetInvert( mapc, invert_list[ imap ] ); - temp = (AstMapping *) astCmpMap( *map3, mapc, 1, "", status ); - *map3 = astAnnul( *map3 ); - mapc = astAnnul( mapc ); - *map3 = temp; - } - } - -/* If there is only one Mapping, this must be a parallel CmpMap. */ - } else { - -/* Annul the Mapping pointer in the series list created above, and free the - dynamic arrays. */ - map_list[ 0 ] = astAnnul( map_list[ 0 ] ); - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - nmap = 0; - -/* Decompose the Mapping into a sequence of Mappings to be applied in - parallel and an associated list of Invert flags. */ - astMapList( map, 0, invert, &nmap, &map_list, &invert_list ); - -/* Process each parallel Mapping. */ - axis = 0; - for( imap = 0; imap < nmap && astOK; imap++ ){ - -/* See if this Mapping contains a usable WcsMap. Only do the search - if no such WcsMap has already been found, since only the first is usable. */ - if( !ret ) { - -/* Search this Mapping for a WcsMap. */ - haswcs = SplitMap2( map_list[ imap ], invert_list[ imap ], &mapa, - &mapb, &mapc, status ); - -/* Note if we have found a usable WcsMap, and its first axis index. */ - if( haswcs ){ - ret = 1; - wcsaxis = axis; - } - -/* If a WcsMap has already been found, the mapping cannot contain a - usable WcsMap. */ - } else { - haswcs = 0; - } - -/* If the Mapping did not contain a usable WcsMap, use the whole mapping as - part of the pre-wcs Mapping, and create a UnitMap as part of the post-wcs - mapping. */ - if( !haswcs ){ - mapa = astCopy( map_list[ imap ] ); - astSetInvert( mapa, invert_list[ imap ] ); - nax = astGetNout( mapa ); - mapc = (AstMapping *) astUnitMap( nax, "", status ); - } - -/* Increment the index of the first axis in the next Mapping. */ - axis += astGetNout( mapa ); - -/* Add the pre-wcs mapping in parallel with the cumulative pre-wcs CmpMap. */ - if( *map1 ){ - temp = (AstMapping *) astCmpMap( *map1, mapa, 0, "", status ); - *map1 = astAnnul( *map1 ); - mapa = astAnnul( mapa ); - *map1 = temp; - } else { - *map1 = mapa; - } - -/* Add the post-wcs mapping in parallel with the cumulative post-wcs CmpMap. */ - if( *map3 ){ - temp = (AstMapping *) astCmpMap( *map3, mapc, 0, "", status ); - *map3 = astAnnul( *map3 ); - mapc = astAnnul( mapc ); - *map3 = temp; - } else { - *map3 = mapc; - } - } - -/* If a usable WcsMap was found, create a new one which has all the same - properties, but with enough axes to join the pre and post wcs Mappings - together. Ensure the correct axes are used for longitude and latitude, - and copy the projection parameters. */ - if( ret ){ - axlat = astGetWcsAxis( mapb, 1 ); - axlon = astGetWcsAxis( mapb, 0 ); - *map2 = astWcsMap( axis, astGetWcsType( mapb ), - axlon + wcsaxis + 1, - axlat + wcsaxis + 1, "", status ); - for( i = 0; i < astGetNin( mapb ); i++ ){ - for( m = 0; m < WCSLIB_MXPAR; m++ ){ - if( astTestPV( mapb, i, m ) ) { - pv = astGetPV( mapb, i, m ); - if( pv != AST__BAD ) astSetPV( *map2, i + wcsaxis, m, pv ); - } - } - } - astInvert( *map2 ); - mapb = astAnnul( mapb ); - } - } - -/* Loop to annul all the Mapping pointers in the list. */ - for ( imap = 0; imap < nmap; imap++ ) map_list[ imap ] = astAnnul( map_list[ imap ] ); - -/* Free the dynamic arrays. */ - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - -/* If the supplied Mapping is not a CmpMap, see if it is a WcsMap with a - non-zero FITSProj value. If so, take a copy and set its invert attribute - correctly. Also create UnitMaps for the pre and post wcs mappings. */ - } else if( astOK && !strcmp( class, "WcsMap" ) && astGetFITSProj( map ) ){ - ret = 1; - nax = astGetNin( map ); - *map1 = (AstMapping *) astUnitMap( nax, "", status ); - *map2 = astCopy( map ); - astSetInvert( *map2, invert ); - *map3 = (AstMapping *) astUnitMap( nax, "", status ); - } - -/* If an error has occurred, or if no suitable WcsMap was found, annul any - Mappings. */ - if( !astOK || !ret ){ - ret = 0; - if( *map1 ) *map1 = astAnnul( *map1 ); - if( *map2 ) *map2 = astAnnul( *map2 ); - if( *map3 ) *map3 = astAnnul( *map3 ); - } - -/* Return the answer. */ - return ret; -} - -static int SplitMat( int naxis, double *matrix, double *cdelt, int *status ){ -/* -* Name: -* SplitMat - -* Purpose: -* Factorises a single "CD"-style matrix into a diagonal CDELT matrix -* and a "PC"-style matrix. - -* Type: -* Private function. - -* Synopsis: -* int SplitMat( int naxis, double *matrix, double *cdelt, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function splits up the supplied CD matrix into separate PC and -* CDELT matrices. The product of the returned matrices (CDELT.PC) -* equals the supplied CD matrix. The CDELT values are chosen so that -* the corresponding row of the PC matrix represents a unit vector. -* The signs of the CDELT values are chosen so that the diagonal terms -* of the PC matrix are all positive. -* - -* Parameters: -* naxis -* The number of axes. -* matrix -* A pointer to an array of naxis*naxis elements. On entry this holds -* the "CD" matrix. On exit, it is modified to represent the "PC" -* matrix. -* cdelt -* A pointer to an array of naxis elements. On exit this holds the CDELT -* values for each axis (i.e. the diagonal terms of the CDELT matrix). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if any bad values are found in the supplied -* matrix, or if an error has already occurred. One is returned otherwise. -*/ - -/* Local Variables: */ - int i; - int j; - int ok; - double *a; - int dineg; - double s2; - double cdlt; - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Assume success. */ - ok = 1; - -/* Loop round every row in the matrix. Get a pointer to the first element - in the row. */ - for( i = 0; i < naxis; i++ ){ - a = matrix + i*naxis; - -/* Note the sign of the diagonal term (i.e. the i'th element) of this row. */ - dineg = ( a[ i ] < 0.0 ); - -/* Get the magnitude of the vector represented by this row. This is the - CDELT value for the row. BAD values cause the whole function to return. */ - s2 = 0.0; - for( j = 0; j < naxis; j++ ){ - if( *a == AST__BAD ) { - ok = 0; - break; - } - s2 += (*a)*(*a); - a++; - } - if( !ok ) break; - cdlt = sqrt( astMAX( 0.0, s2 ) ); - -/* If the diagonal term for this row of the matrix is negative, make - the CDELT value negative instead. This means that the diagonal term in - the final PC matrix will be positive. */ - if( dineg ) cdlt = -cdlt; - -/* Store the CDELT value. */ - cdelt[ i ] = cdlt; - -/* The row of the PC matrix is obtained by dividing the original row by - the CDELT value. Set to zero any PC values which are less than 1.0E-7 - (such values may be produced by rounding errors). */ - a = matrix + i*naxis; - for( j = 0; j < naxis; j++ ) { - if( cdlt != 0.0 ){ - *a /= cdlt; - if( fabs( *a ) < 1.E-7 ) *a = 0.0; - } else { - *a = 0.0; - } - a++; - } - } - return ok; -} -static void TableSource( AstFitsChan *this, - void (* tabsource)( AstFitsChan *, const char *, - int, int, int * ), - int *status ){ - -/* -*++ -* Name: -c astTableSource -f AST_TABLESOURCE - -* Purpose: -c Register a source function for accessing tables in FITS files. -f Register a source routine for accessing tables in FITS files. - -* Type: -* Public function. - -* Synopsis: -c #include "fitschan.h" -c void astTableSource( AstFitsChan *this, -c void (* tabsource)( AstFitsChan *, const char *, -c int, int, int * ) ) -f CALL AST_TABLESOURCE( THIS, TABSOURCE, STATUS ) - -* Class Membership: -* FitsChan member function. - -* Description: -c This function can be used to register a call-back function -f This routine can be used to register a call-back routine -* with a FitsChan. The registered -c function -f routine -* is called when-ever the FitsChan needs to read information from a -* binary table contained within a FITS file. This occurs if the -c astRead -f AST_READ -* function is invoked to read a FrameSet from a set of FITS headers -* that use the "-TAB" algorithm to describe one or more axes. Such -* axes use a FITS binary table to store a look-up table of axis values. -* The FitsChan will fail to read such axes unless the "TabOK" attribute -* is set to a non-zero positive integer value. The table containing the -* axis values must be made available to the FitsChan either by storing -* the table contents in the FitsChan (using -c astPutTables or astPutTable) prior to invoking astRead -f AST_PUTTABLES or AST_PUTTABLE) prior to invoking AST_READ -* or by registering a call-back -c function using astTableSource. -f routine using AST_TABLESOURCE. -* The first method is possibly simpler, but requires that the name of -* the extension containing the table be known in advance. Since the -* table name is embedded in the FITS headers, the name is often not -* known in advance. If a call-back is registered, the FitsChan will -* determine the name of the required table and invoke the call-back -c function -f routine -* to supply the table at the point where it is needed (i.e. within -c the astRead method). -f the AST_READ method). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c tabsource -f TABSOURCE = SUBROUTINE (Given) -c Pointer to the table source function to use. -f The table source routine to use. -* It takes five arguments - the first is a pointer to the -* FitsChan, the second is a string holding the name of the -* FITS extension containing the required binary table ("EXTNAME"), -* the third is the integer FITS "EXTVER" header value for the -* required extension, the fourth is the integer FITS "EXTLEVEL" -* header value for the required extension, and the fifth is -c a pointer to -* the inherited integer status value. -* -* The call-back should read the entire contents (header and data) -* of the binary table in the named extension of the external FITS -* file, storing the contents in a newly created FitsTable object. It -* should then store this FitsTable in the FitsChan using the -c astPutTables or astPutTable -f AST_PUTTABLES or AST_PUTTABLE -* method, and finally annull its local copy of the FitsTable pointer. -* If the table cannot be read for any reason, or if any other -* error occurs, it should return a non-zero integer for the final -* (third) argument. -* -c If "tabsource" is NULL, -f If TABSOURCE is AST_NULL, -* any registered call-back function will be removed. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - Application code can pass arbitrary data (such as file -c descriptors, etc) to the table source function using the -c astPutChannelData function. The source function should use -c the astChannelData macro to retrieve this data. -f - The name of the routine supplied for the TABSOURCE -f argument should appear in an EXTERNAL statement in the Fortran -f routine which invokes AST_TABLESOURCE. However, this is not generally -f necessary for the null routine AST_NULL (so long as the AST_PAR -f include file has been used). -f - Note that the null routine AST_NULL (one underscore) is -f different to AST__NULL (two underscores), which is the null Object -f pointer. -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Register the supplied source function, using the wrapper function - appropriate for calling C table source functions. */ - astSetTableSource( this, (void (*)( void )) tabsource, TabSourceWrap ); -} - -static AstMapping *TabMapping( AstFitsChan *this, FitsStore *store, char s, - int **tabaxis, const char *method, - const char *class, int *status ) { - -/* -* Name: -* TabMapping - -* Purpose: -* Create a Mapping that performs any -TAB look-ups for all WCS axes. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstMapping *TabMapping( AstFitsChan *this, FitsStore *store, char s, -* int **tabaxis, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function returns a Mapping that has "nwcs" inputs and outputs, -* where "nwcs" is the number of FITS WCS axes defined in the supplied -* FitsStore. The inputs and outputs are in the same order as the -* CTYPEi keywords in the FitsStore. The forward transformation of the -* Mapping converts positions from the axes defined by the CRVALi keywords -* to the WCS axes. This transformation will be a UnitMap except for -* any axes that are described using the "-TAB" algorithm. For "-TAB" -* axes, the transformation will implement the relevant coordinate -* look-up function. - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore structure holding the values to use for -* the WCS keywords. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* tabaxis -* Address of a location at which to store a pointer to an array of -* flags, one for each output of the returned Mapping. A flag will -* be non-zero if the corresponding output of the returned Mapping -* corresponds to a -TAB axis. A NULL pointer is returned if the -* returned Mapping is NULL. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a Mapping. A NULL pointer is returned if the FitsChan does -* not support the -TAB algorithm (i.e. if the value of the TabOK -* attribute is zero or negative), or if no axes use the "-TAB" algorithm. -*/ - -/* Local Variables: */ - AstFitsTable *table; - AstKeyMap *used_tables; - AstMapping *tmap1; - AstMapping *tmap2; - AstMapping *indexmap; - AstMapping *tmap0; - AstMapping *ret; - AstPermMap *pm; - char name[21]; - const char *indexcol; - const char *extname; - const char *cval; - const char *ctype; - const char *coordscol; - double dval; - int *marray; - int *permin; - int *permout; - int extlevel; - int extver; - int iaxis; - int iiaxis; - int ikey; - int interp; - int ival; - int maxis; - int mdim; - int nkey; - int nperm; - int unit; - int wcsaxes; - -/* Initialise */ - ret = NULL; - *tabaxis = NULL; - extname = NULL; - tmap0 = NULL; - tmap2 = NULL; - -/* Check the global status. */ - if( !astOK ) return ret; - -/* Obtain the number of physical axes in the header. If the WCSAXES header - was specified, use it. Otherwise assume it is the same as the number - of pixel axes. */ - dval = GetItem( &(store->wcsaxes), 0, 0, s, NULL, method, class, status ); - if( dval != AST__BAD ) { - wcsaxes = (int) dval + 0.5; - } else { - wcsaxes = store->naxis; - } - -/* If the FitsChan does not support the -TAB algorithm, return a NULL - pointer. */ - if( astGetTabOK( this ) > 0 ) { - -/* Create a KeyMap to hold a list of the used extension names. */ - used_tables = astKeyMap( " ", status ); - -/* Allocate memory to indicate if each WCS axis is described by a -TAB - algorithm or not. Initialiss it to zero. */ - *tabaxis = astCalloc( wcsaxes, sizeof( int ) ); - -/* Allocate memory to hold the FITS-WCS axis index corresponding to each - input of the "tmap0" Mapping. Indicate that as yet, not values are - stored in this array. Also allocate memory for the inverse of this - permutation array. */ - permout = astMalloc( wcsaxes*sizeof( int ) ); - permin = astMalloc( wcsaxes*sizeof( int ) ); - nperm = 0; - if( astOK ) { - -/* Initialise the permutation arrays. */ - for( iaxis = 0; iaxis < wcsaxes; iaxis++ ) { - permout[ iaxis ] = permin[ iaxis ] = -1; - } - -/* Otherwise, loop round all FITS WCS axis indices present in the FitsStore. */ - for( iaxis = 0; iaxis < wcsaxes; iaxis++ ) { - -/* If the current FITS WCS axis is already included in the returned - Mapping, skip it. This will be the case if the axis uses the same - coordinate array as an earlier axis since all FITS WCS axes associated - with a coordinate array are processed together. */ - if( permin[ iaxis ] == -1 ) { - -/* See if this WCS axis uses the -TAB algorithm. */ - ctype = GetItemC( &(store->ctype), iaxis, 0, s, NULL, method, - class, status ); - if( ctype && strlen(ctype) > 4 && !strncmp( ctype + 4, "-TAB", 4 ) ) { - -/* Get the name of the FITS binary table extension holding the coordinate - info. No default, so report an error if not present. */ - sprintf( name, "PS%d_0%c", iaxis + 1, s ); - extname = GetItemC( &(store->ps), iaxis, 0, s, name, method, - class, status ); - -/* Get the extension version and level. */ - dval = GetItem( &(store->pv), iaxis, 1, s, NULL, method, - class, status ); - extver = ( dval != AST__BAD ) ? (int) dval : 1; - dval = GetItem( &(store->pv), iaxis, 2, s, NULL, method, - class, status ); - extlevel = ( dval != AST__BAD ) ? (int) dval : 1; - -/* Get the FITS binary table. This will invoke any supplied table source - function, and put a copy of the table into the FitsChan structure. - Report an error if the table can not be obtained. */ - table = GetNamedTable( this, extname, extver, extlevel, 1, - method, status ); - -/* Add this extension name to a list of used extensions. */ - astMapPut0I( used_tables, extname, 1, NULL ); - -/* Get the name of the table column containing the main coords array. No - default so report error if not present. Report an error if the column - is not present in the table. */ - sprintf( name, "PS%d_1%c", iaxis + 1, s ); - coordscol = GetItemC( &(store->ps), iaxis, 1, s, name, method, - class, status ); - if( !astHasColumn( table, coordscol ) && astOK ) { - astError( AST__BADTAB, "%s(%s): Unable to find the " - "coordinate array for FITS-WCS axis %d (type %s): " - "column '%s' cannot be found in table '%s'.", status, - method, class, iaxis + 1, ctype, coordscol, extname ); - } - -/* Get the number of dimensions spanned by the coordinate array. Report - an error if the coordinate array has only one axis (FITS-WCS paper III - requires it to have at leats two axes). */ - mdim = astGetColumnNdim( table, coordscol ); - if( mdim == 1 && astOK ) { - astError( AST__BADTAB, "%s(%s): Unable to use the " - "coordinate array for FITS-WCS axis %d (type %s): " - "column '%s' in table '%s' has one axis but at " - "least two are required.", status, method, class, - iaxis + 1, ctype, coordscol, extname ); - } - -/* Allocate memory to hold the FITS-WCS axis corresponding to each dimension - of the coordinate array. Initialise it to hold -1 (i.e. "no matching - FITS-WCS axis yet found") at every element. */ - marray = astMalloc( mdim*sizeof( int ) ); - if( astOK ) { - for( maxis = 0; maxis < mdim; maxis++ ) { - marray[ maxis ] = -1; - } - -/* Loop round each dimension of the coordinate array, storing the index - of the corresponding FITS-WCS axis in "marray". We omit the first axis - (axis 0) since FITS-WCS Paper III defines it is a "conventional" axis - used to enumerate the planes of coordinate values. */ - for( maxis = 1; maxis < mdim && astOK ; maxis++ ) { - -/* Each axis of the coordinate array (except axis 0) must have one, and only - one, corresponding FITS-WCS axis. Check each FITS-WCS axis to find one - that uses the same table and column as the "iaxis" axis, and which - corresponds to axis "maxis" of the coordinate array. */ - for( iiaxis = 0; iiaxis < wcsaxes; iiaxis++ ) { - cval = GetItemC( &(store->ps), iiaxis, 0, s, NULL, - method, class, status ); - if( cval && !strcmp( cval, extname ) ) { - cval= GetItemC( &(store->ps), iiaxis, 1, s, NULL, - method, class, status ); - if( cval && !strcmp( cval, coordscol ) ) { - dval = GetItem( &(store->pv), iiaxis, 3, s, - NULL, method, class, status ); - if( dval != AST__BAD ) { - ival = (int)( dval + 0.5 ); - } else { - ival = 1; - } - if( ival == maxis ) { - -/* Arrive here if the "iiaxis" FITS-WCS axis uses the same table and column - as "iaxis", and corresponds to the "maxis" axis in the coordinate - array. If this is the first matching FITS-WCS axis, store its index. */ - if( marray[ maxis ] == -1 ) { - marray[ maxis ] = iiaxis; - -/* If a matching FITS-WCS axis has already been found, report an error. */ - } else if( astOK ) { - astError( AST__BADTAB, "%s(%s): Unable to use " - "the coordinate array for FITS-WCS " - "axis %d (type %s): more than one " - "intermediate WCS axis is mapped onto " - " dimension %d of the coordinate " - "array in column '%s' of table '%s'.", - status, method, class, iaxis + 1, - ctype, maxis, coordscol, extname ); - } - } - } - } - } - } - -/* Check that every dimension of the coordinate array (except the first) has - a corresponding FITS-WCS axis. */ - for( maxis = 1; maxis < mdim && astOK ; maxis++ ) { - if( marray[ maxis ] == -1 ) { - astError( AST__BADTAB, "%s(%s): Unable to use the " - "coordinate array for FITS-WCS axis %d (type " - "%s): no intermediate WCS axis is mapped onto " - " dimension %d of the coordinate array in column " - " '%s' of table '%s'.", status, method, class, - iaxis + 1, ctype, maxis, coordscol, extname ); - } - } - -/* Now we know which FITS-WCS axis corresponds to each dimension of the - coordinate array. We now need to form a parallel CmpMap (compound Mapping) - by gathering together the indexing vectors for each dimension of the - coordinates array. Each indexing vector is represented by an inverted - 1D LutMap - dimensions that do not have an indexing vector are - represented using a UnitMap. */ - indexmap = NULL; - unit = 1; - for( maxis = 1; maxis < mdim && astOK ; maxis++ ) { - -/* Get the name of the column containing the index array. Defaults is to - use a unit index, so do not report an error if not present. */ - indexcol = GetItemC( &(store->ps), marray[ maxis ], 2, - s, NULL, method, class, status ); - -/* If the table contains an index vector, create a LutMap from it, then - invert it. */ - if( indexcol ) { - tmap1 = MakeColumnMap( table, indexcol, 1, 0, - method, class, status ); - astInvert( tmap1 ); - unit = 0; - -/* If the table does not contain an index vector, use a UnitMap. */ - } else { - tmap1 = (AstMapping *) astUnitMap( 1, " ", status ); - } - -/* Combine the index Mapping for this dimension in parallel with the - Mapping for all earlier dimensions. */ - if( indexmap ) { - tmap2 = (AstMapping *) astCmpMap( indexmap, tmap1, - 0, " ", status ); - indexmap = astAnnul( indexmap ); - tmap1 = astAnnul( tmap1 ); - indexmap = tmap2; - } else { - indexmap = tmap1; - } - } - -/* Get the interpolation method to use for the main coordinate array. - This is an extension to the published -TAB algorithm in which the - QVi_4a keyword is assumed to hold zero for linear interpolation (the - default) and non-zero for nearest neighbour interpolation. The QVi_4a - keyword will be translated to PVi_4a by the SpecTrans function. */ - dval = GetItem( &(store->pv), iaxis, 4, s, - NULL, method, class, status ); - if( dval != AST__BAD ) { - interp = (int)( dval + 0.5 ); - } else { - interp = 0; - } - -/* Make a Mapping from the main coordinate array, and then if required - append it in series to the end of the index Mapping created above. */ - tmap1 = MakeColumnMap( table, coordscol, 0, interp, - method, class, status ); - if( ! unit ) { - tmap2 = (AstMapping *) astCmpMap( indexmap, tmap1, 1, - " ", status ); - } else { - tmap2 = astClone( tmap1 ); - } - indexmap = astAnnul( indexmap ); - tmap1 = astAnnul( tmap1 ); - -/* Extend the array that holds the zero-based FITS-WCS axis index - corresponding to each input of the extended "tmap0" mapping. Also create - the inverse permutation (i.e. zero-based "tmap0" input indexed by - zero-based FITS-WCS axis index). */ - for( maxis = 1; maxis < mdim; maxis++ ) { - permout[ nperm ] = marray[ maxis ]; - permin[ marray[ maxis ] ] = nperm++; - } - -/* Free resources. */ - marray = astFree( marray ); - } - -/* Annul the table pointer. */ - table = astAnnul( table ); - -/* Clear the CTYPE algorithm code to indicate that the axis should be - considered to be linear from now on. This means that the following - functions will create a Mapping from pixel to psi (the system in which - the CRVAL values are defined when using -TAB). The psi axes will then - be mapping into the CS axes using the Mappign returned by this function. */ - strncpy( name, ctype, 4 ); - strcpy( name + 4, ctype + 8 ); - SetItemC( &(store->ctype), iaxis, 0, s, name, status ); - -/* Set the returned flag for this axis. */ - (*tabaxis)[ iaxis ] = 1; - -/* If the FITS WCS axis "iaxis" does not use a -TAB algorithm, describe - it in the returned Mapping using a 1D UnitMap. */ - } else { - tmap2 = (AstMapping *) astUnitMap( 1, " ", status ); - -/* Extend the array that holds the zero-based FITS-WCS axis index - corresponding to each input of the extended "tmap0" mapping. Also create - the inverse permutation (i.e. zero-based "tmap0" input indexed by - zero-based FITS-WCS axis index). */ - permout[ nperm ] = iaxis; - permin[ iaxis ] = nperm++; - } - -/* Append the Mapping describing the FITS WCS axis "iaxis" in parallel to any - Mappings created for earlier "iaxis" axes. */ - if( tmap0 ) { - tmap1 = (AstMapping *) astCmpMap( tmap0, tmap2, 0, " ", status ); - tmap0 = astAnnul( tmap0 ); - tmap2 = astAnnul( tmap2 ); - tmap0 = tmap1; - } else { - tmap0 = tmap2; - } - } - } - -/* If no -TAB axes were found, just return a NULL pointer. */ - if( extname && astOK ) { - -/* Do a sanity check on the permutation arrays. */ - for( iaxis = 0; iaxis < wcsaxes; iaxis++ ) { - if( permin[ iaxis ] < 0 || permin[ iaxis ] >= wcsaxes || - permout[ permin[ iaxis ] ] != iaxis ) { - astError( AST__INTER, "%s(%s): Invalid permutation " - "arrays in function TabMapping (internal AST " - "progranmming error).", status, method, class ); - break; - } - } - -/* Sandwich the "tmap0" Mapping in series between two PermMaps to create a - Mapping in which the inputs and outputs correspond to FITS WCS axis - numbering. */ - pm = astPermMap( wcsaxes, permin, wcsaxes, permout, NULL, " ", - status ); - tmap1 = (AstMapping *) astCmpMap( pm, tmap0, 1, " ", status ); - astInvert( pm ); - tmap2 = (AstMapping *) astCmpMap( tmap1, pm, 1, " ", status ); - pm = astAnnul( pm ); - tmap1 = astAnnul( tmap1 ); - -/* Simplify the returned Mapping. */ - ret = astSimplify( tmap2 ); - tmap2 = astAnnul( tmap2 ); - } - -/* Free remaining resources */ - tmap0 = astAnnul( tmap0 ); - } - permout = astFree( permout ); - permin = astFree( permin ); - -/* Remove all used tables from the FitsChan now that they have been used. */ - nkey = astMapSize( used_tables ); - for( ikey = 0; ikey < nkey; ikey++ ) { - astRemoveTables( this, astMapKey( used_tables, ikey ) ); - } - -/* Delete the KeyMap holding the used table names. */ - used_tables = astAnnul( used_tables ); - -/* If we are not returning a Mapping, ensure we do not return any axis - flags either. */ - if( !ret ) *tabaxis = astFree( *tabaxis ); - } - -/* Return the result */ - return ret; -} -static void TabSourceWrap( void (*tabsource)( void ), - AstFitsChan *this, const char *extname, - int extver, int extlevel, int *status ){ - -/* -* Name: -* TabSourceWrap - -* Purpose: -* Wrapper function to invoke the C table source function. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void TabSourceWrap( void (*tabsource)( void ), -* AstFitsChan *this, const char *extname, -* int extver, int extlevel, int *status ) - -* Class Membership: -* Channel member function. - -* Description: -* This function invokes the table source function whose pointer is -* supplied in order to read a named FITS binary table from an external -* FITS file. - -* Parameters: -* tabsource -* Pointer to the C tab source function. -* this -* Pointer to the FitsChan. The reference count for the FitsChan is -* decremented by this function (this behaviour is imposed by -* restrictions in the equivalent Fortran wrapper function). -* extname -* Pointer to the string holding the name of the FITS extension -* from which a table is to be read. -* extver -* The integer "EXTVER" value for the required extension. -* extlevel -* The integer "EXTLEVEL" value for the required extension. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFitsChan *this_id; - int lstat; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get an external identifier for the FitsChan. Could use astClone here - to avoid this function anulling the supplied pointer, but the F77 wrapper - cannot use the protected version of astClone, so for consistency we do - not use it here either. */ - this_id = astMakeId( this ); - -/* Invoke the table source function (casting it to the C API first) to - read the table, and store it in the FitsChan. */ - ( *( void (*)( struct AstFitsChan *, const char *, int, int, int * ) )tabsource )( this_id, extname, extver, extlevel, &lstat ); - -/* Free the FitsChan identifier (this annuls the supplied "this" pointer). */ - this_id = astAnnulId( this_id ); - -/* Report an error if the source function failed. */ - if( !lstat ) { - astError( AST__NOTAB, "astRead(%s): The table source function failed to read " - "a binary table from extension %s in an external FITS file.", - status, astGetClass( this ), extname ); - } -} - -static double TDBConv( double mjd, int timescale, int fromTDB, - const char *method, const char *class, int *status ){ -/* -* Name: -* TDBConv - -* Purpose: -* Convert an MJD between the TDB time scale and another timescale. - -* Type: -* Private function. - -* Synopsis: -* double TDBConv( double mjd, int timescale, int fromTDB, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function converts the supplied mjd value to or from the TDB -* timescale. - -* Parameters: -* mjd -* The input MJD value. -* timescale -* The other timescale. -* fromTDB -* Indicates the direction of the required conversion. If non-zero, -* the supplied "mjd" value should be in the TDB timescale, and the -* returned value will be in the timescale specified by "timescale". -* If zero, the supplied "mjd" value should be in the timescale -* specified by "timescale", and the returned value will be in the -* TDB timescale. -* method -* The calling method. Used only in error messages. -* class -* The object class. Used only in error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The converted MJD value, or AST__BAD if an error occurs. -*/ - -/* Local Variables: */ - AstFrameSet *fs; /* Mapping from supplied timescale to TDB */ - double ret; /* The returned value */ - -/* Initialise */ - ret = AST__BAD; - -/* Check inherited status and supplied TDB value. */ - if( !astOK || mjd == AST__BAD ) return ret; - -/* Return the supplied value if no conversion is needed. */ - if( timescale == AST__TDB ) { - ret = mjd; - -/* Otherwise, do the conversion. */ - } else { - -/* Lock the timeframes for use by the current thread, waiting if they are - currently locked by another thread. */ - astManageLock( timeframe, AST__LOCK, 1, NULL ); - astManageLock( tdbframe, AST__LOCK, 1, NULL ); - -/* Set the required timescale. */ - astSetTimeScale( timeframe, timescale ); - -/* Get the Mapping between the two timescales, and use it to convert the - suipplied value. */ - fs = astConvert( tdbframe, timeframe, "" ); - astTran1( fs, 1, &mjd, fromTDB, &ret ); - fs = astAnnul( fs ); - -/* Unlock the timeframes. */ - astManageLock( timeframe, AST__UNLOCK, 1, NULL ); - astManageLock( tdbframe, AST__UNLOCK, 1, NULL ); - } - -/* Return the result */ - return ret; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* FitsChan member function (over-rides the astTestAttrib protected -* method inherited from the Channel class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a FitsChan's attributes. - -* Parameters: -* this -* Pointer to the FitsChan. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_object; - -/* Card. */ -/* ----- */ - if ( !strcmp( attrib, "card" ) ) { - result = astTestCard( this ); - -/* Encoding. */ -/* --------- */ - } else if ( !strcmp( attrib, "encoding" ) ) { - result = astTestEncoding( this ); - -/* FitsAxisOrder. */ -/* -------------- */ - } else if ( !strcmp( attrib, "fitsaxisorder" ) ) { - result = astTestFitsAxisOrder( this ); - -/* FitsDigits. */ -/* ----------- */ - } else if ( !strcmp( attrib, "fitsdigits" ) ) { - result = astTestFitsDigits( this ); - -/* DefB1950. */ -/* --------- */ - } else if ( !strcmp( attrib, "defb1950" ) ) { - result = astTestDefB1950( this ); - -/* TabOK. */ -/* ------ */ - } else if ( !strcmp( attrib, "tabok" ) ) { - result = astTestTabOK( this ); - -/* CDMatrix. */ -/* --------- */ - } else if ( !strcmp( attrib, "cdmatrix" ) ) { - result = astTestCDMatrix( this ); - -/* CarLin. */ -/* --------- */ - } else if ( !strcmp( attrib, "carlin" ) ) { - result = astTestCarLin( this ); - -/* SipReplace. */ -/* ----------- */ - } else if ( !strcmp( attrib, "sipreplace" ) ) { - result = astTestSipReplace( this ); - -/* FitsTol. */ -/* -------- */ - } else if ( !strcmp( attrib, "fitstol" ) ) { - result = astTestFitsTol( this ); - -/* PolyTan */ -/* ------- */ - } else if ( !strcmp( attrib, "polytan" ) ) { - result = astTestPolyTan( this ); - -/* SipOK */ -/* ----- */ - } else if ( !strcmp( attrib, "sipok" ) ) { - result = astTestSipOK( this ); - -/* Iwc. */ -/* ---- */ - } else if ( !strcmp( attrib, "iwc" ) ) { - result = astTestIwc( this ); - -/* Clean. */ -/* ------ */ - } else if ( !strcmp( attrib, "clean" ) ) { - result = astTestClean( this ); - -/* Warnings. */ -/* -------- */ - } else if ( !strcmp( attrib, "warnings" ) ) { - result = astTestWarnings( this ); - -/* If the name is not recognised, test if it matches any of the - read-only attributes of this class. If it does, then return - zero. */ - } else if ( !strcmp( attrib, "ncard" ) || - !strcmp( attrib, "nkey" ) || - !strcmp( attrib, "cardtype" ) || - !strcmp( attrib, "cardcomm" ) || - !strcmp( attrib, "cardname" ) || - !strcmp( attrib, "allwarnings" ) ){ - result = 0; - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static int TestCard( AstFitsChan *this, int *status ){ - -/* -*+ -* Name: -* astTestCard - -* Purpose: -* Test the Card attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fitschan.h" -* int astTestCard( AstFitsChan *this ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function tests the Card attribute for the supplied FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. - -* Returned Value: -* If the Card attribute has its "cleared" value (i.e. if the first card -* in the FitsChan will be the next one to be read), then zero is returned, -* otherwise 1 is returned. -*- -*/ - -/* Local Variables: */ - int card; /* The original value of Card */ - int ret; /* The returned flag */ - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Get the current value of Card. */ - card = astGetCard( this ); - -/* Temporarily clear Card. */ - astClearCard( this ); - -/* See if the original Card is equal to the cleared card, and set the - returned flag appropriately. Re-instate the original value of card is - required.*/ - if( astGetCard( this ) == card ) { - ret = 0; - } else { - astSetCard( this, card ); - ret = 1; - } - -/* Return the flag. */ - return ret; -} - -static int TestFits( AstFitsChan *this, const char *name, int *there, - int *status ){ - -/* -*++ -* Name: -c astTestFits -f AST_TESTFITS - -* Purpose: -* See if a named keyword has a defined value in a FitsChan. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" - -c int astTestFits( AstFitsChan *this, const char *name, int *there ) -f RESULT = AST_TESTFITS( THIS, NAME, THERE, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -* This function serches for a named keyword in a FitsChan. If found, -* and if the keyword has a value associated with it, a -c non-zero -f .TRUE. -* value is returned. If the keyword is not found, or if it does not -* have an associated value, a -c zero -f .FALSE. -* value is returned. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -c name -f NAME = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string -f A character string -* containing the FITS keyword name. This may be a complete FITS -* header card, in which case the keyword to use is extracted from -* it. No more than 80 characters are read from this string. If -c NULL -f a single dot '.' -* is supplied, the current card is tested. -c there -f THERE = LOGICAL (Returned) -c Pointer to an integer which will be returned holding a non-zero -c value if the keyword was found in the header, and zero otherwise. -f A value of .TRUE. will be returned if the keyword was found in the -f header, and .FALSE. otherwise. -* This parameter allows a distinction to be made between the case -* where a keyword is not present, and the case where a keyword is -* present but has no associated value. -c A NULL pointer may be supplied if this information is not -c required. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astTestFits() -f AST_TESTFITS = LOGICAL -* A value of zero -f .FALSE. -* is returned if the keyword was not found in the FitsChan or has -* no associated value. Otherwise, a value of -c one -f .TRUE. -* is returned. - -* Notes: -* - The current card is left unchanged by this function. -* - The card following the current card is checked first. If this is -* not the required card, then the rest of the FitsChan is searched, -* starting with the first card added to the FitsChan. Therefore cards -* should be accessed in the order they are stored in the FitsChan (if -* possible) as this will minimise the time spent searching for cards. -* - An error will be reported if the keyword name does not conform -* to FITS requirements. -c - Zero -f - .FALSE. -* is returned as the function value if an error has already occurred, -* or if this function should fail for any reason. -*-- -*/ - -/* Local Variables: */ - const char *class; /* Object class */ - const char *method; /* Calling method */ - char *lcom; /* Supplied keyword comment */ - char *lname; /* Supplied keyword name */ - char *lvalue; /* Supplied keyword value */ - int icard; /* Current card index on entry */ - int ret; /* The returned value */ - int type; /* The card's type */ - -/* Initialise */ - if( there ) *there = 0; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Store the calling method and object class. */ - method = "astTestFits"; - class = astGetClass( this ); - -/* Initialise the returned value. */ - ret = 0; - -/* Extract the keyword name from the supplied string. */ - if( name ) { - (void) Split( this, name, &lname, &lvalue, &lcom, method, class, status ); - } else { - lname = NULL; - lvalue = NULL; - lcom = NULL; - } - -/* Store the current card index. */ - icard = astGetCard( this ); - -/* Attempt to find a card in the FitsChan refering to this keyword, - and make it the current card. Only proceed if a card was found. No - need to do the search if the value of the current card is required. */ - if( !lname || SearchCard( this, lname, method, class, status ) ){ - -/* Get the card type. */ - type = CardType( this, status ); - -/* Check the card exists. */ - if( type != AST__NOTYPE ) { - -/* If the cards data type is not undefined, return 1. */ - if( CardType( this, status ) != AST__UNDEF ) ret = 1; - -/* Indicate the card has been found. */ - if( there ) *there = 1; - } - } - -/* Re-instate the original current card index. */ - astSetCard( this, icard ); - -/* Release the memory used to hold keyword name, value and comment strings. */ - lname = (char *) astFree( (void *) lname ); - lvalue = (char *) astFree( (void *) lvalue ); - lcom = (char *) astFree( (void *) lcom ); - -/* Return the answer. */ - return ret; -} - -static void TidyOffsets( AstFrameSet *fset, int *status ) { -/* -* Name: -* TidyOffsets - -* Purpose: -* Remove un-needed offset coordinate Frames. - -* Type: -* Private function. - -* Synopsis: -* void TidyOffsets( AstFrameSet *fset, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FITS header stores offset sky coordinates as two alternaive axis -* descriptions - one giving the offset axes and one giving the absolute -* axes. But AST can hold both forms in a single SkyFrame. This function -* removes the FITS Frames describing offset axes from the FrameSet. -* The remaining absolute Frame is then used to describe both absolute -* and offset. - -* Parameters: -* fset -* A FrameSet holding the Frames read from a FITS-WCS Header. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *frm; - AstFrame *pfrm; - const char *dom; - const char *skyrefis; - int hasabs; - int hasoff; - int iax; - int icurr; - int icurr_is_offset; - int ifrm; - int nax; - int nfrm; - int pax; - int remove; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Note the original current Frame index. */ - icurr = astGetCurrent( fset ); - -/* Assume the current Frame is not an offset frame until proven - otherwise. */ - icurr_is_offset = 0; - -/* Does the FrameSet contain any Frames holding sky offsets? Such Frames - should have been given a Domain of SKY_OFFSETS within function - WcsSkyFrame. Loop round all Frames, checking each one. Also note if - the FrameSet contains any (absolute) SKY frames. Also set the SkyRefIs - attribute for any absolute SkyFrames that were marked with domains - SKY_POLE or SKY_OFFSET in WcsSkyFrame. */ - hasabs = 0; - hasoff = 0; - nfrm = astGetNframe( fset ); - for( ifrm = 1; ifrm <= nfrm; ifrm++ ){ - skyrefis = NULL; - frm = astGetFrame( fset, ifrm ); - nax = astGetNaxes( frm ); - for( iax = 0; iax < nax; iax++ ) { - astPrimaryFrame( frm, iax, &pfrm, &pax ); - if( IsASkyFrame( pfrm ) ) { - dom = astGetDomain( pfrm ); - if( dom ) { - if( !strcmp( dom, "SKY_OFFSETS" ) ){ - hasoff = 1; - if( ifrm == icurr ) icurr_is_offset = 1; - iax = nax; - } else if( !strcmp( dom, "SKY" ) ){ - hasabs = 1; - iax = nax; - } else if( !strcmp( dom, "SKY_POLE" ) ){ - hasabs = 1; - skyrefis = "POLE"; - iax = nax; - } else if( !strcmp( dom, "SKY_ORIGIN" ) ){ - hasabs = 1; - skyrefis = "ORIGIN"; - iax = nax; - } - } - } - pfrm = astAnnul( pfrm ); - } - frm = astAnnul( frm ); - - if( skyrefis ) { - astSetI( fset, "Current", ifrm); - astSetC( fset, "SkyRefIs", skyrefis ); - astSetI( fset, "Current", icurr ); - } - } - -/* If one or more absolute sky frames were found, then remove any offset - sky frames. Clear the Ident attribute (that holds the FITS-WCS alternate - axis description character) for any absoute Frames. */ - if( hasabs && hasoff ) { - - for( ifrm = nfrm; ifrm > 0; ifrm-- ) { - remove = 0; - frm = astGetFrame( fset, ifrm ); - nax = astGetNaxes( frm ); - for( iax = 0; iax < nax; iax++ ) { - astPrimaryFrame( frm, iax, &pfrm, &pax ); - if( IsASkyFrame( pfrm ) ) { - dom = astGetDomain( pfrm ); - if( dom ) { - if( !strcmp( dom, "SKY_OFFSETS" ) ){ - remove = 1; - iax = nax; - - } else if( !strcmp( dom, "SKY_POLE" ) || - !strcmp( dom, "SKY_ORIGIN" ) ){ - astClearIdent( frm ); - astClearDomain( pfrm ); - -/* If we will be deleting the original current Frame (because it is an - offset Frame), then mark the first absolute Frame as the new current - Frame. */ - if( icurr_is_offset ) { - astSetCurrent( fset, ifrm ); - icurr_is_offset = 0; - } - iax = nax; - } - } - } - pfrm = astAnnul( pfrm ); - } - frm = astAnnul( frm ); - - if( remove ) astRemoveFrame( fset, ifrm ); - } - } -} - -static AstTimeScaleType TimeSysToAst( AstFitsChan *this, const char *timesys, - const char *method, const char *class, int *status ){ -/* -* Name: -* TimeSysToAst - -* Purpose: -* Convert a FITS TIMESYS value to an AST TimeFrame timescale value. - -* Type: -* Private function. - -* Synopsis: -* AstTimeScaleType TimeSysToAst( AstFitsChan *this, const char *timesys, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function returns the value used by the AST TimeFrame class to -* represent the timescale specified by the "timesys" parameter, which -* should hold the value of a FITS TIMESYS keyword. The TIMESYS -* convention was introduced as part of the Y2K DATE-OBS changes, and -* is not currently part of the published FITS-WCS conventions. -* -* If the requested timescale is not supported by AST, then a warning is -* added to the FitsChan and a value of AST__UTC is returned (but no -* error is reported). - -* Parameters: -* this -* Pointer to the FitsChan. -* timesys -* Pointer to the string holding the TIMESYS value. A NULL pointer -* returns the default timescale of UTC. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The equivalent AstTimeScaleType value. -*/ - -/* Local Variables: */ - AstTimeScaleType result; /* The returned timescale */ - char buf[ 200 ]; /* Buffer for warning message */ - -/* Initialise */ - result = AST__UTC; - -/* Check the inherited status. */ - if( !astOK ) return result; - if( !timesys ) { - result = AST__UTC; - } else if( !strcmp( timesys, "UTC" ) ) { - result = AST__UTC; - } else if( !strcmp( timesys, "UT" ) ) { - result = AST__UTC; - Warn( this, "badval", "The original FITS header contained a value of UT " - "for keyword TIMESYS which is being interpreted as UTC.", method, - class, status ); - } else if( !strcmp( timesys, "TAI" ) ) { - result = AST__TAI; - } else if( !strcmp( timesys, "IAT" ) ) { - result = AST__TAI; - } else if( !strcmp( timesys, "ET" ) ) { - result = AST__TT; - Warn( this, "badval", "The original FITS header contained a value of ET " - "for keyword TIMESYS. TT will be used instead.", method, class, status ); - } else if( !strcmp( timesys, "TT" ) ) { - result = AST__TT; - } else if( !strcmp( timesys, "TDT" ) ) { - result = AST__TT; - } else if( !strcmp( timesys, "TDB" ) ) { - result = AST__TDB; - } else if( !strcmp( timesys, "TCG" ) ) { - result = AST__TCG; - } else if( !strcmp( timesys, "TCB" ) ) { - result = AST__TCB; - } else { - result = AST__UTC; - sprintf( buf, "The original FITS header contained a value of %s for " - "keyword TIMESYS. AST does not support this timescale so " - "UTC will be used instead.", timesys ); - Warn( this, "badval", buf, method, class, status ); - } - -/* Return the result */ - return result; -} - -static char *UnPreQuote( const char *string, int *status ) { -/* -* Name: -* UnPreQuote - -* Purpose: -* Reverse the pre-quoting of FITS character data. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* char *UnPreQuote( const char *string, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function reverses the effect of the PreQuote function on a -* string (apart from any loss of data due to truncation). It -* should be used to recover the original character data from the -* pre-quoted version of a string retrieved from a FITS character -* value associated with a keyword. - -* Parameters: -* string -* Pointer to a constant null-terminated string containing the -* pre-quoted character data. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a dynamically allocated null-terminated string -* containing the un-quoted character data. The memory holding this -* string should be freed by the caller (using astFree) when no -* longer required. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked wth the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - char *result; /* Pointer value to return */ - int i1; /* Offset of first useful character */ - int i2; /* Offest of last useful character */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise to use the first and last characters in the input - string. */ - i1 = 0; - i2 = strlen( string ) - 1; - -/* If the string contains at least 2 characters, check if the first - and last characters are double quotes ("). If so, adjust the - offsets to exclude them. */ - if ( ( i2 > i1 ) && - ( string[ i1 ] == '"' ) && ( string[ i2 ] == '"' ) ) { - i1++; - i2--; - } - -/* Make a dynamically allocated copy of the useful part of the - string. */ - result = astString( string + i1, i2 - i1 + 1 ); - -/* Return the answer. */ - return result; -} - -static int Use( AstFitsChan *this, int set, int helpful, int *status ) { - -/* -* Name: -* Use - -* Purpose: -* Decide whether to write a value to a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int Use( AstFitsChan *this, int set, int helpful, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* This function decides whether a value supplied by a class "Dump" -* function, via a call to one of the astWrite... protected -* methods, should actually be written to a FitsChan. -* -* This decision is based on the settings of the "set" and -* "helpful" flags supplied to the astWrite... method, plus the -* attribute settings of the FitsChan. - -* Parameters: -* this -* A pointer to the FitsChan. -* set -* The "set" flag supplied. -* helpful -* The "helpful" value supplied. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the value should be written out, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - int full; /* Full attribute value */ - int result; /* Result value to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* If "set" is non-zero, then so is the result ("set" values must - always be written out). */ - result = ( set != 0 ); - -/* Otherwise, obtain the value of the FitsChan's Full attribute. */ - if ( !set ) { - full = astGetFull( this ); - -/* If Full is positive, display all values, if zero, display only - "helpful" values, if negative, display no (un-"set") values. */ - if ( astOK ) result = ( ( helpful && ( full > -1 ) ) || ( full > 0 ) ); - } - -/* Return the result. */ - return result; -} - -static int Ustrcmp( const char *a, const char *b, int *status ){ -/* -* Name: -* Ustrcmp - -* Purpose: -* A case blind version of strcmp. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int Ustrcmp( const char *a, const char *b, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns 0 if there are no differences between the two strings, and 1 -* otherwise. Comparisons are case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference between -* the two strings, whereas "strcmp" does. -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int ret; /* Returned value */ - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Loop round each character. */ - while( 1 ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - } - } - -/* Return the result. */ - return ret; -} - -static int Ustrncmp( const char *a, const char *b, size_t n, int *status ){ -/* -* Name: -* Ustrncmp - -* Purpose: -* A case blind version of strncmp. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int Ustrncmp( const char *a, const char *b, size_t n, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* Returns 0 if there are no differences between the first "n" -* characters of the two strings, and 1 otherwise. Comparisons are -* case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. -* n -* The maximum number of characters to compare. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference between -* the two strings, whereas "strncmp" does. -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int i; /* Character index */ - int ret; /* Returned value */ - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Compare up to "n" characters. */ - for( i = 0; i < (int) n; i++ ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - } - } - -/* Return the result. */ - return ret; -} - -static void Warn( AstFitsChan *this, const char *condition, const char *text, - const char*method, const char *class, int *status ){ -/* -* Name: -* Warn - -* Purpose: -* Store warning cards in a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int Warn( AstFitsChan *this, const char *condition, const char *text, -* const char*method, const char *class, int *status ); - -* Class Membership: -* FitsChan member function. - -* Description: -* If the Warnings attribute indicates that occurences of the specified -* condition should be reported, the supplied text is split into lines -* and stored in the FitsChan as a series of ASTWARN cards, in front -* of the current card. If the specified condition is not being reported, -* this function returns without action. - -* Parameters: -* this -* The FitsChan. If NULL, this function returns without action. -* condition -* Pointer to a string holding a lower case condition name. -* text -* Pointer to a string holding the text of the warning. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - char buff[ AST__FITSCHAN_FITSCARDLEN + 1 ]; /* Buffer for new card text */ - const char *a; /* Pointer to 1st character in next card */ - const char *b; /* Pointer to terminating null character */ - const char *c; /* Pointer to last character in next card */ - int exists; /* Has the supplied warning already been issued? */ - int icard; /* Index of original card */ - int nc; /* No. of characters in next card */ - -/* Check the inherited status, warning text, FitsChan and Clean attribute. */ - if( !astOK || !text || !text[0] || !this || astGetClean( this ) ) return; - -/* Ignore the warning if the supplied condition is not contained within - the list of conditions to be reported in this way (given by the - Warnings attribute). */ - if( FullForm( astGetWarnings( this ), condition, 0, status ) >= 0 ){ - -/* If found, store the warning in the parent Channel structure. */ - astAddWarning( this, 1, "%s", method, status, text ); - -/* For historical reasons, warnings are also stored in the FitsChan as a - set of FITS cards... First save the current card index, and rewind the - FitsChan. */ - icard = astGetCard( this ); - astClearCard( this ); - -/* Break the supplied text into lines and check the FitsChan to see if - a block of adjacent ASTWARN cards with these lines already exist - within the FitsChan. Assume they do until proven otherwise. */ - exists = 1; - a = text; - b = a + strlen( text ); - while( a < b ){ - -/* Each card contains about 60 characters of the text. Get a pointer to - the nominal last character in the next card. */ - c = a + 60; - -/* If this puts the last character beyond the end of the text, use the - last character before the null as the last character in the card. */ - if( c >= b ) { - c = b - 1; - -/* Otherwise, if the last character is not a space, move the last - character backwards to the first space. This avoids breaking words - across cards. */ - } else { - while( !isspace( *c ) && c > a ) c--; - } - -/* Copy the text into a null terminated buffer. */ - nc = c - a + 1; - strncpy( buff, a, nc ); - buff[ nc ] = 0; - -/* If this is the first line, search the entire FitsChan for an ASTWARN card - with this text. If not, indiate that the supplied text needs to be - stored in the FitsChan, and break out of the loop. */ - if( a == text ) { - exists = 0; - while( !exists && - FindKeyCard( this, "ASTWARN", method, class, status ) ) { - if( !strcmp( (const char *) CardData( this, NULL, status ), buff ) ) { - exists = 1; - } - MoveCard( this, 1, method, class, status ); - } - if( !exists ) break; - -/* If this is not the first line, see if the next card in the FitsChan is - an ASTWARN card with this text. If not, indiate that the supplied text - needs to be stored in the FitsChan, and break out of the loop. */ - } else { - if( !strcmp( CardName( this, status ), "ASTWARN" ) && - !strcmp( (const char *) CardData( this, NULL, status ), buff ) ) { - MoveCard( this, 1, method, class, status ); - } else { - exists = 0; - break; - } - } - -/* Set the start of the next bit of the text. */ - a = c + 1; - } - -/* Reinstate the original current card index. */ - astSetCard( this, icard ); - -/* We only add new cards to the FitsChan if they do not already exist. */ - if( !exists ) { - -/* Break the text into lines using the same algorithm as above, and store - each line as a new ASTWARN card. Start with a blank ASTWARN card. */ - astSetFitsS( this, "ASTWARN", " ", NULL, 0 ); - -/* Loop until the entire text has been written out. */ - a = text; - b = a + strlen( text ); - while( a < b ){ - -/* Each card contains about 60 characters of the text. Get a pointer to - the nominal last character in the next card. */ - c = a + 60; - -/* If this puts the last character beyond the end of the text, use the - last character before the null as the last character in the card. */ - if( c >= b ) { - c = b - 1; - -/* Otherwise, if the last character is not a space, move the last - character backwards to the first space. This avoids breaking words - across cards. */ - } else { - while( !isspace( *c ) && c > a ) c--; - } - -/* Copy the text into a null terminated buffer. */ - nc = c - a + 1; - strncpy( buff, a, nc ); - buff[ nc ] = 0; - -/* Store the buffer as the next card. */ - astSetFitsS( this, "ASTWARN", buff, NULL, 0 ); - -/* Set the start of the next bit of the text. */ - a = c + 1; - } - -/* Include a final blank card. */ - astSetFitsS( this, "ASTWARN", " ", NULL, 0 ); - } - } -} - -static int WATCoeffs( const char *watstr, int iaxis, double **cvals, - int **mvals, int *ok, int *status ){ -/* -* Name: -* WATCoeffs - -* Purpose: -* Get the polynomial coefficients from the lngcor or latcor component -* of an IRAF WAT string. - -* Type: -* Private function. - -* Synopsis: -* int WATCoeffs( const char *watstr, int iaxis, double **cvals, -* int **mvals, int *ok, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function extracts the polynomial coefficients from a supplied -* string containing the concatenated values of a set of IRAF "WAT" -* keywords, such as used for the IRAF-specific TNX and ZPX projections. -* The coefficients are returned in the form of a set of PVi_m values -* for a TPN projection. - -* Parameters: -* watstr -* The concatentated WAT keyword values. -* iaxis -* Zero based index of the axis to which the WAT keywords refer (0 -* or 1). -* cvals -* Location at which to return a pointer to a dynamically allocated -* list of coefficient values, or NULL if no lngcor/latcor values -* were found in the WAT string. Free using astFree. -* mvals -* Location at which to return a pointer to a dynamically allocated -* list of coefficient indices, or NULL if no lngcor/latcor values -* were found in the WAT string. Free using astFree. -* ok -* Pointer to an in which is returned set to zero if the polynomial -* in the supplied WAT string cannot be represented using TPN form. -* Non-zero otherwise. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The size of the returned cvals and mvals arrays. - -*/ - -/* Local Variables: */ - char **w1; - char **w2; - double *coeff; - double *pc; - int result; - double dval; - double etamax; - double etamin; - double ximax; - double ximin; - int cheb; - int etaorder; - int iword; - int m; - int mn; - int nword; - int order; - int porder; - int xiorder; - int ires; - -/* The number of lngcor/latcor values needed for each order. */ - static const int nab[] = {1,3,6,10,15,21,28,36}; - -/* Initialise the pointer to the returned Mapping. */ - result = 0; - *mvals = NULL; - *cvals = NULL; - *ok = 1; - -/* Other initialisation to avoid compiler warnings. */ - etamin = 0.0; - etamax = 0.0; - ximax = 0.0; - ximin = 0.0; - order = 0; - -/* Check the global status. */ - if ( !astOK || !watstr ) return result; - -/* Look for cor = "..." and extract the "..." string. */ - w1 = astChrSplitRE( watstr, "cor *= *\"(.*)\"", &nword, NULL ); - if( w1 ) { - -/* Split the "..." string into words. */ - w2 = astChrSplit( w1[ 0 ], &nword ); - if( w2 ) { - -/* Initialise flags. */ - cheb = 0; - xiorder = 0; - etaorder = 0; - coeff = NULL; - porder = -1; - -/* Loop round each word. Break early if we find that the projection - cannot be represented as a TPN projection. */ - for( iword = 0; iword < nword && *ok; iword++ ) { - -/* Convert the word to double. */ - dval = astChr2Double( w2[ iword ] ); - if( dval == AST__BAD ) { - astError( AST__BDFTS, "astRead(FitsChan): Failed to read a " - "numerical value from sub-string \"%s\" found in " - "an IRAF \"WAT...\" keyword.", status, w2[ iword ] ); - break; - } - -/* The first value gives the correction surface type. We can only handle type - 1 (chebyshev) or 3 (simple polynomial). */ - if( iword == 0 ){ - if( dval == 1.0 ) { - cheb = 1; - } else if( dval == 2.0 ) { - *ok = 0; - } - -/* The second and third numbers gives the orders of the polynomial in X - and Y. We can only handle cases in which the orders are the same on - both axes, and greater than 0 and less than 8. Store a pointer to the - first TAN projection parameter index to use. */ - } else if( iword == 1 ){ - order = dval; - porder = order - 1; - - } else if( iword == 2 ){ - if( dval - 1 != porder || dval < 0 || dval > 7 ) *ok = 0; - -/* The fourth number defines the type of cross-terms. We can only handle - type 2 (half-cross terms). */ - } else if( iword == 3 ){ - if( dval != 2.0 ) *ok = 0; - -/* We now know the maximum number of co-efficients that may be needed. - Allocate memory to hold them, and fill it with zeros. They are - stored in this array as if full cross-terms have been supplied (the - unspecified coefficients retain their initialised value of zero). */ - coeff = astCalloc( order*order, sizeof( double ) ); - if( !astOK ) break; - -/* The next 4 numbers describe the region of validity of the fits in IRAF's - xi and eta space, e.g. ximin, ximax, etamin, etamax. We only uses - these if we have a chebyshev polynomial. */ - } else if( iword == 4 ) { - ximin = dval; - - } else if( iword == 5 ) { - ximax = dval; - - } else if( iword == 6 ) { - etamin = dval; - - } else if( iword == 7 ) { - etamax = dval; - -/* The remaining terms are the coefficients of the polynomial terms. */ - } else if( iword > 7 ){ - -/* Store the coefficient in the array. They are stored so that power of - xi increases fastest. */ - coeff[ xiorder + order*etaorder ] = dval; - -/* Increment the powers of the next coefficient. We know we only have half - cross-terms, so the maximum power of xi decreases from order to zero - as we move through the list of coefficients. */ - if( ++xiorder == order - etaorder ) { - xiorder = 0; - etaorder++; - } - } - } - -/* Check that all the required co-efficients were found */ - if( porder == -1 || nword != 8 + nab[ porder ] ) *ok = 0; - -/* If we can handle the projection, proceed. */ - if( *ok && astOK ) { - -/* If the coefficients were supplied in chebyshev form, convert to simple - form. */ - if( cheb ) { - double *tcoeff = coeff; - coeff = Cheb2Poly( tcoeff, order, order, ximin, - ximax, etamin, etamax, status ); - tcoeff = astFree( tcoeff ); - } - -/* The polynomials provide a "correction* to be added to the supplied X and - Y values. Therefore increase the linear co-efficients by 1 on the axis - that is being calculated. */ - coeff[ iaxis ? order : 1 ] += 1.0; - -/* Loop round all coefficients, keeping track of the power of xi and eta - for the current coefficient. */ - pc = coeff; - for( etaorder = 0; etaorder < order; etaorder++ ) { - for( xiorder = 0; xiorder < order; xiorder++,pc++ ) { - -/* Skip coefficients that have their default values (zero, except for the - linear coefficients which default to 1.0). */ - mn = xiorder + etaorder; - if( *pc != ( mn == 1 ? 1.0 : 0.0 ) ) { - -/* Find the "m" index of the PVi_m FITS keyword for the current - coefficient. */ - m = mn*( 1 + mn )/2 + mn/2; - m += iaxis ? xiorder : etaorder; - -/* Append the PV and m values to the ends of the returned arrays. */ - ires = result++; - *cvals = astGrow( *cvals, sizeof( double ), result ); - *mvals = astGrow( *mvals, sizeof( int ), result ); - if( astOK ) { - (*cvals)[ ires ] = *pc; - (*mvals)[ ires ] = m; - } - } - } - } - -/* Free coefficients arrays */ - coeff = astFree( coeff ); - } - -/* Free resources */ - w2 = astFree( w2 ); - } - w1 = astFree( w1 ); - } - -/* Return the result. */ - return result; -} - -static AstMatrixMap *WcsCDeltMatrix( FitsStore *store, char s, int naxes, - const char *method, const char *class, int *status ){ -/* -* Name: -* WcsCDeltMatrix - -* Purpose: -* Create a MatrixMap representing the CDELT scaling. - -* Type: -* Private function. - -* Synopsis: -* AstMatrixMap *WcsCDeltMatrix( FitsStore *store, char s, int naxes, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A diagonal MatrixMap representing the FITS "CDELT" keywords is -* returned. - -* Parameters: -* store -* A structure containing values for FITS keywords relating to -* the World Coordinate System. -* s -* A character s identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* naxes -* The number of intermediate world coordinate axes (WCSAXES). -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the created MatrixMap or a NULL pointer if an -* error occurred. -*/ - -/* Local Variables: */ - AstMatrixMap *new; /* The created MatrixMap */ - double *el; /* Pointer to next matrix element */ - double *mat; /* Pointer to matrix array */ - int i; /* Pixel axis index */ - -/* Initialise/ */ - new = NULL; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Allocate memory for the diagonal matrix elements. */ - mat = (double *) astMalloc( sizeof(double)*naxes ); - if( astOK ){ - -/* Fill the matrix diagonal with values from the FitsStore. */ - el = mat; - for( i = 0; i < naxes; i++ ){ - -/* Get the CDELTi value for this axis. Missing terms can be defaulted so - do not report an error if the required value is not present in the - FitsStore. */ - *el = GetItem( &(store->cdelt), i, 0, s, NULL, method, class, status ); - -/* Missing terms default to to 1.0. */ - if( *el == AST__BAD ) *el = 1.0; - -/* Move on to the next matrix element. */ - el++; - } - -/* Create the diagional matrix. */ - new = astMatrixMap( naxes, naxes, 1, mat, "", status ); - -/* Report an error if the inverse transformation is undefined. */ - if( !astGetTranInverse( new ) && astOK ) { - astError( AST__BDFTS, "%s(%s): Unusable CDELT values found " - "in the FITS-WCS header - one or more values are zero.", status, method, class ); - } - -/* Release the memory used to hold the matrix. */ - mat = (double *) astFree( (void *) mat ); - } - -/* If an error has occurred, attempt to annul the returned MatrixMap. */ - if( !astOK ) new = astAnnul( new ); - -/* Return the MatrixMap. */ - return new; -} - -static AstMapping *WcsCelestial( AstFitsChan *this, FitsStore *store, char s, - AstFrame **frm, AstFrame *iwcfrm, double *reflon, double *reflat, - AstSkyFrame **reffrm, AstMapping **tabmap, - int *tabaxis, const char *method, - const char *class, int *status ){ -/* -* Name: -* WcsCelestial - -* Purpose: -* Create a Mapping from intermediate world coords to celestial coords -* as described in a FITS header. - -* Type: -* Private function. - -* Synopsis: -* AstMapping *WcsCelestial( AstFitsChan *this, FitsStore *store, char s, -* AstFrame **frm, AstFrame *iwcfrm, double *reflon, double *reflat, -* AstSkyFrame **reffrm, , AstMapping **tabmap, -* int *tabaxis, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function interprets the contents of the supplied FitsStore -* structure, looking for world coordinate axes which describe positions -* on the sky. If a pair of such longitude/latitude axes is found, a -* Mapping is returned which transforms the corresponding intermediate -* world coordinates to celestial world coordinates (this mapping leaves -* any other axes unchanged). It also, modifies the supplied Frame to -* describe the axes (again, other axes are left unchanged). If no -* pair of celestial axes is found, a UnitMap is returned, and the -* supplied Frame is left unchanged. - -* Parameters: -* this -* The FitsChan. -* store -* A structure containing information about the requested axis -* descriptions derived from a FITS header. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* frm -* The address of a location at which to store a pointer to the -* Frame describing the world coordinate axes. -* iwcfrm -* A pointer to the Frame describing the intermediate world coordinate -* axes. The properties of this Frame may be changed on exit. -* reflon -* Address of a location at which to return the celestial longitude -* at the reference point. It is returned as AST__BAD if no -* celestial coordinate frame is found. -* reflat -* Address of a location at which to return the celestial latitude -* at the reference point. It is returned as AST__BAD if no -* celestial coordinate frame is found. -* reffrm -* Address of a location at which to return a pointer to a SkyFrame -* which define the reference values returned in reflon and reflat. -* It is returned as NULL if no celestial coordinate frame is found. -* tabmap -* Address of a pointer to a Mapping describing any -TAB -* transformations to be applied to the results of the Mapping returned -* by this function. If any celestial axes are found, the supplied -* Mapping is modified so that the celestial axes produce values in -* radians rather than degrees. NULL if no axes are described by -TAB. -* tabaxis -* Pointer to an array of flags, one for each WCS axis, indicating -* if the corresponding WCS axis is described by the -TAB algorithm. -* NULL if no axes are described by -TAB. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the Mapping. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFrame *ofrm; /* Pointer to a Frame */ - AstMapping *map1; /* Pointer to a Mapping */ - AstMapping *map2; /* Pointer to a Mapping */ - AstMapping *map3; /* Pointer to a Mapping */ - AstMapping *map4; /* Pointer to a Mapping */ - AstMapping *ret; /* Pointer to the returned Mapping */ - AstMapping *newmap; /* Modified PIXEL->IWC Mapping */ - AstMapping *shiftmap; /* ShiftMap from IWC to PPC */ - AstSkyFrame *sfrm; /* Pointer to a SkyFrame */ - char *ctype; /* Pointer to CTYPE string */ - char *keyname; /* Pointer to keyword name string */ - char buf[300]; /* Text buffer */ - char latctype[MXCTYPELEN];/* Latitude CTYPE keyword value */ - char latkey[10]; /* Latitude CTYPE keyword name */ - char lattype[4]; /* Buffer for celestial system */ - char lonctype[MXCTYPELEN];/* Longitude CTYPE keyword value */ - char lonkey[10]; /* Longitude CTYPE keyword name */ - char lontype[4]; /* Buffer for celestial system */ - double *shifts; /* Array holding axis shifts */ - double *ina; /* Pointer to memory holding input position A */ - double *inb; /* Pointer to memory holding input position B */ - double *mat; /* Pointer to data for deg->rad scaling matrix */ - double *outa; /* Pointer to memory holding output position A */ - double *outb; /* Pointer to memory holding output position B */ - double latval; /* CRVAL for latitude axis */ - double lonval; /* CRVAL for longitude axis */ - double pv; /* Projection parameter value */ - double x0; /* IWC X at the projection fiducial point */ - double y0; /* IWC Y at the projection fiducial point */ - int *axes; /* Point to a list of axis indices */ - int axlat; /* Index of latitude physical axis */ - int axlon; /* Index of longitude physical axis */ - int carlin; /* Assume native and WCS axes are the same? */ - int ctlen; /* Length of CTYPE string */ - int gotax; /* Celestial axis found? */ - int i; /* Loop count */ - int j; /* Axis index */ - int latprj; /* Latitude projection type identifier */ - int lonprj; /* Longitude projection type identifier */ - int m; /* Parameter index */ - int mxpar_lat; /* Max. projection parameter index on lat axis */ - int mxpar_lon; /* Max. projection parameter index on lon axis */ - int naxes; /* Number of axes */ - int nc; /* String length */ - int np; /* Max parameter index */ - int prj; /* Projection type identifier */ - -/* Initialise the returned values. */ - ret = NULL; - *reflon = AST__BAD; - *reflat = AST__BAD; - *reffrm = NULL; - -/* Other initialisation to avoid compiler warnings. */ - map1 = NULL; - -/* Check the global status. */ - if ( !astOK ) return ret; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Get the number of physical axes. */ - naxes = astGetNaxes( *frm ); - -/* See if CAR projections should be interpreted in the old fashioned way - (i.e native coords are always the same as WCS coords, so no need for - any rotation). */ - carlin = astGetCarLin( this ); - -/* The first major section sees if the physical axes include a pair of - longitude/latitude celestial axes. - ================================================================= */ - -/* We have not yet found any celestial axes. */ - axlon = -1; - axlat = -1; - latprj = AST__WCSBAD; - lonprj = AST__WCSBAD; - prj = AST__WCSBAD; - -/* First, we examine the CTYPE values in the FitsStore to determine - which axes are the longitude and latitude axes, and what the celestial - co-ordinate system and projection are. Loop round the physical axes, - getting each CTYPE value. */ - for( i = 0; i < naxes && astOK; i++ ){ - keyname = FormatKey( "CTYPE", i + 1, -1, s, status ); - ctype = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - -/* Issue a warning if no CTYPE value was found. */ - if( !ctype ) { - sprintf( buf, "Axis type keywords (CTYPE, etc) were not found " - "for one or more axes in the original FITS header. These " - "axes will be assumed to be linear." ); - Warn( this, "noctype", buf, method, class, status ); - } else { - -/* See if this is a longitude axis (e.g. if the first 4 characters of CTYPE - are "RA--" or "xLON" or "yzLN" ). If so, store the value of "x" or "yz" - (or "EQU" for equatorial coordinates) in variable "type" to indicate which - coordinate system is being used. */ - nc = strlen( ctype ); - gotax = 0; - if( !strcmp( ctype, "RA" ) || !strncmp( ctype, "RA--", 4 ) ){ - strcpy( wcscelestial_type, "EQU" ); - gotax = 1; - } else if( !strcmp( ctype, "AZ" ) || !strncmp( ctype, "AZ--", 4 ) ){ - strcpy( wcscelestial_type, "AZL" ); - gotax = 1; - } else if( nc > 1 && ( !strcmp( ctype + 1, "LON" ) || - !strncmp( ctype + 1, "LON-", 4 ) ) ){ - wcscelestial_type[ 0 ] = ctype[ 0 ]; - wcscelestial_type[ 1 ] = 0; - gotax = 1; - } else if( nc > 2 && ( !strcmp( ctype + 2, "LN" ) || - !strncmp( ctype + 2, "LN-", 3 ) ) ){ - wcscelestial_type[ 0 ] = ctype[ 0 ]; - wcscelestial_type[ 1 ] = ctype[ 1 ]; - wcscelestial_type[ 2 ] = 0; - gotax = 1; - } - -/* If this is a longitude axis... */ - if( gotax ){ - -/* Check that this is the first longitude axis to be found. */ - if( axlon == -1 ){ - -/* Find the projection type as specified by the last 4 characters - in the CTYPE keyword value. AST__WCSBAD is stored in "prj" if the - last 4 characters do not specify a known WCS projection, but no error - is reported. Assume simple linear axes if no projection code is - supplied. Note, AST__WCSBAD is used to indicate a TAB header. */ - ctlen = strlen( ctype ); - if( ctlen > 4 ) { - prj = astWcsPrjType( ctype + ctlen - 4 ); - } else if( tabmap && *tabmap ) { - prj = AST__WCSBAD; - } else { - prj = AST__CAR; - carlin = 1; - } - -/* Report an error if the projection is unknown. */ - if( prj == AST__WCSBAD && ctlen > 4 ){ - astError( AST__BDFTS, "%s(%s): FITS keyword '%s' refers to " - "an unknown projection type '%s'.", status, method, class, - keyname, ctype + ctlen - 4 ); - break; - } - -/* Store the index of the longitude axis, type of longitude, etc. */ - axlon = i; - strcpy( lontype, wcscelestial_type ); - strcpy( lonkey, keyname ); - strcpy( lonctype, ctype ); - lonprj = prj; - -/* If another longitude axis has already been found, report an error. */ - } else { - astError( AST__BDFTS, "%s(%s): FITS keywords '%s' (='%s') " - "and '%s' (='%s') both describe celestial longitude axes.", status, - method, class, keyname, ctype, lonkey, lonctype ); - break; - } - } - -/* Do the same for the latitude axis, checking for "DEC-" and "xLAT" and - "yzLT". */ - gotax = 0; - if( !strcmp( ctype, "DEC" ) || !strncmp( ctype, "DEC-", 4 ) ){ - strcpy( wcscelestial_type, "EQU" ); - gotax = 1; - } else if( !strcmp( ctype, "EL" ) || !strncmp( ctype, "EL--", 4 ) ){ - strcpy( wcscelestial_type, "AZL" ); - gotax = 1; - } else if( !strcmp( ctype + 1, "LAT" ) || !strncmp( ctype + 1, "LAT-", 4 ) ){ - wcscelestial_type[ 0 ] = ctype[ 0 ]; - wcscelestial_type[ 1 ] = 0; - gotax = 1; - } else if( !strcmp( ctype + 2, "LT" ) || !strncmp( ctype + 2, "LT-", 3 ) ){ - wcscelestial_type[ 0 ] = ctype[ 0 ]; - wcscelestial_type[ 1 ] = ctype[ 1 ]; - wcscelestial_type[ 2 ] = 0; - gotax = 1; - } - if( gotax ){ - if( axlat == -1 ){ - ctlen = strlen( ctype ); - if( ctlen > 4 ) { - prj = astWcsPrjType( ctype + ctlen - 4 ); - } else if( tabmap && *tabmap ) { - prj = AST__WCSBAD; - } else { - prj = AST__CAR; - carlin = 1; - } - - if( prj == AST__WCSBAD && ctlen > 4 ){ - astError( AST__BDFTS, "%s(%s): FITS keyword '%s' refers to " - "an unknown projection type '%s'.", status, method, class, - keyname, ctype + ctlen - 4 ); - break; - } - axlat = i; - strcpy( lattype, wcscelestial_type ); - strcpy( latkey, keyname ); - strcpy( latctype, ctype ); - latprj = prj; - } else { - astError( AST__BDFTS, "%s(%s): FITS keywords '%s' (='%s') " - "and '%s' (='%s') both describe celestial latitude axes.", status, - method, class, keyname, ctype, latkey, latctype ); - break; - } - } - } - } - -/* Check the above went OK */ - if( astOK ){ - -/* If both longitude and latitude axes were found... */ - if( axlat != -1 && axlon != -1 ){ - -/* Report an error if they refer to different celestial coordinate systems. */ - if( strcmp( lattype, lontype ) ){ - astError( AST__BDFTS, "%s(%s): FITS keywords '%s' and '%s' " - "indicate different celestial coordinate systems " - "('%s' and '%s').", status, method, class, latkey, lonkey, - latctype, lonctype ); - -/* Otherwise report an error if longitude and latitude axes use different - projections. */ - } else if( lonprj != latprj ){ - astError( AST__BDFTS, "%s(%s): FITS keywords '%s' and '%s' " - "indicate different projections ('%s' and '%s').", status, - method, class, latkey, lonkey, latctype, lonctype ); - } - -/* If only one axis has been provided without the other (e.g. longitude but no - latitude), report an error. */ - } else if( axlat != -1 && prj != AST__WCSBAD ){ - astError( AST__BDFTS, "%s(%s): A latitude axis ('%s') was found " - "without a corresponding longitude axis.", status, method, class, - latctype ); - } else if( axlon != -1 && prj != AST__WCSBAD ){ - astError( AST__BDFTS, "%s(%s): A longitude axis ('%s') was found " - "without a corresponding latitude axis.", status, method, class, - lonctype ); - } - } - -/* If a pair of matching celestial axes was not found, return a UnitMap - and leave the Frame unchanged. - ===================================================================== */ - if( axlat == -1 || axlon == -1 ) { - ret = (AstMapping *) astUnitMap( naxes, "", status ); - -/* The rest of this function deals with creating a Mapping from - intermediate world coords to celestial coords, and modifying the - Frame appropriately. - ===================================================================== */ - } else if( astOK ) { - -/* Create a MatrixMap which scales the intermediate world coordinate axes - corresponding to the longitude and latitude axes from degrees to radians. - Only do this if a projection was supplied. */ - if( latprj != AST__WCSBAD ) { - mat = (double *) astMalloc( sizeof(double)*naxes ); - if( mat ){ - for( i = 0; i < naxes; i++ ){ - if( i == axlat || i == axlon ){ - mat[ i ] = AST__DD2R; - } else { - mat[ i ] = 1.0; - } - } - map1 = (AstMapping *) astMatrixMap( naxes, naxes, 1, mat, "", status ); - mat = (double *) astFree( (void *) mat ); - } - } else { - map1 = (AstMapping *) astUnitMap( naxes, " ", status ); - } - -/* If the projection is a CAR projection, but the CarLin attribute is - set, then we consider the CAR projection to be a simple linear mapping - of pixel coords to celestial coords. Do this by using a WcsMap with no - projection. All axes will then be treated as linear and non-celestial. - If no projection was specified (i.e. if prj == AST__WCSBAD, as is the - case when using -TAB for instance) then do the same but use a UnitMap - instead of a WcsMap. */ - map3 = NULL; - if( ( latprj == AST__CAR && carlin ) || latprj == AST__WCSBAD ) { - if( latprj == AST__CAR ) { - map2 = (AstMapping *) astWcsMap( naxes, AST__WCSBAD, axlon + 1, - axlat + 1, "", status ); - } else { - map2 = (AstMapping *) astUnitMap( naxes, "", status ); - } - -/* Now create a WinMap which adds on the CRVAL values to each axis. */ - ina = astMalloc( sizeof(double)*naxes ); - inb = astMalloc( sizeof(double)*naxes ); - outa = astMalloc( sizeof(double)*naxes ); - outb = astMalloc( sizeof(double)*naxes ); - if( astOK ) { - for( i = 0; i < naxes; i++ ) { - ina[ i ] = 0.0; - inb[ i ] = 1.0; - outa[ i ] = 0.0; - outb[ i ] = 1.0; - } - lonval = GetItem( &(store->crval), axlon, 0, s, NULL, method, class, status ); - if( lonval != AST__BAD ) { - -/* For recognised projections the CRVAL value is required to be degrees, - so convert to radians. For other algorithms (e.g. -TAB) the CRVAL - values are in unknown units so retain their original scaling. */ - *reflon = ( latprj == AST__CAR ) ? lonval*AST__DD2R : lonval; - - outa[ axlon ] += *reflon; - outb[ axlon ] += *reflon; - } else { - outa[ axlon ] = AST__BAD; - outb[ axlon ] = AST__BAD; - } - - latval = GetItem( &(store->crval), axlat, 0, s, NULL, method, class, status ); - if( latval != AST__BAD ) { - *reflat = ( latprj == AST__CAR ) ? latval*AST__DD2R : latval; - outa[ axlat ] += *reflat; - outb[ axlat ] += *reflat; - } else { - outa[ axlat ] = AST__BAD; - outb[ axlat ] = AST__BAD; - } - - map3 = (AstMapping *) astWinMap( naxes, ina, inb, outa, outb, "", status ); - - } - ina = astFree( ina ); - inb = astFree( inb ); - outa = astFree( outa ); - outb = astFree( outb ); - -/* Otherwise, create a WcsMap with the specified projection. The WcsMap - is equivalent to a unit mapping for all axes other than "axlat" and - "axlon". */ - } else { - -/* Get the highest index ("m" value) of any supplied PVi_m projection - parameters (on any axes). */ - np = GetMaxJM( &(store->pv), s, status ); - -/* Create the WcsMap */ - map2 = (AstMapping *) astWcsMap( naxes, latprj, axlon + 1, - axlat + 1, "", status ); - -/* If the FITS header contains any projection parameters, store them in - the WcsMap. */ - mxpar_lat = astGetPVMax( map2, axlat ); - mxpar_lon = astGetPVMax( map2, axlon ); - for( m = 0; m <= np; m++ ){ - pv = GetItem( &(store->pv), axlat, m, s, NULL, method, class, status ); - if( pv != AST__BAD ) { - if( m <= mxpar_lat ) { - astSetPV( map2, axlat, m, pv ); - } else { - sprintf( buf, "Projection parameter PV%d_%d found, " - "but is not used by %s projections.", axlat + 1, - m, astWcsPrjName( astGetWcsType( map2 ) ) ); - Warn( this, "badpv", buf, method, class, status ); - } - } - pv = GetItem( &(store->pv), axlon, m, s, NULL, method, class, status ); - if( pv != AST__BAD ) { - if( m <= mxpar_lon ) { - astSetPV( map2, axlon, m, pv ); - } else { - sprintf( buf, "Projection parameter PV%d_%d found, " - "but is not used by %s projections.", axlon + 1, - m, astWcsPrjName( astGetWcsType( map2 ) ) ); - Warn( this, "badpv", buf, method, class, status ); - } - } - } - -/* Invert the WcsMap to get a DEprojection. */ - astInvert( map2 ); - -/* Now produce a Mapping which converts the axes holding "Native Spherical - Coords" into "Celestial Coords", leaving all other axes unchanged. */ - map3 = WcsNative( this, store, s, (AstWcsMap *) map2, -1, -1, - method, class, status ); - -/* Retrieve and store the reference longitude and latitude. */ - *reflon = GetItem( &(store->crval), axlon, 0, s, NULL, method, class, status ); - if( *reflon != AST__BAD ) *reflon *= AST__DD2R; - *reflat = GetItem( &(store->crval), axlat, 0, s, NULL, method, class, status ); - if( *reflat != AST__BAD ) *reflat *= AST__DD2R; - } - -/* If projection parameter PVi_0a for the longitude axis "i" is non-zero, - then there is a shift of origin between Intermediate World Coords, IWC, - (the CRPIXi values correspond to the origin of IWC), and Projection Plane - Coords, PPC (these are the cartesian coordinates used by the WcsMap). - This shift of origin results in the fiducial point specified by the - CRVALi values mapping onto the pixel reference point specified by the - CRPIXj values. In this case we need to add a Mapping which implements - the shift of origin. Note, the AST-specific "TPN" projection cannot use - this convention since it uses PVi_0 to hold a polynomial correction term. */ - if( latprj != AST__WCSBAD && astGetWcsType( map2 ) != AST__TPN && - astGetPV( map2, axlon, 0 ) != 0.0 ) { - -/* Find the projection plane coords corresponding to the fiducial point - of the projection. This is done by using the inverse WcsMap to convert - the native spherical coords at the fiducial point into PPC (x,y), which - are returned in units of radians (not degrees). */ - GetFiducialPPC( (AstWcsMap *) map2, &x0, &y0, status ); - if( x0 != AST__BAD && y0 != AST__BAD ) { - -/* Allocate resources. */ - shifts = astMalloc( sizeof( double )*(size_t) naxes ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Create a Mapping (a ShiftMap) from IWC to PPC. */ - for( i = 0; i < naxes; i++ ) shifts[ i ] = 0.0; - shifts[ axlon ] = x0; - shifts[ axlat ] = y0; - shiftmap = (AstMapping *) astShiftMap( naxes, shifts, "", status ); - -/* Produce a CmpMap which combines "map1" (which converts degrees to - radians on the celestial axes) with the above ShiftMap. */ - newmap = (AstMapping *) astCmpMap( map1, shiftmap, 1, "", status ); - -/* Annul the component Mappings and use the new one in place of map1. */ - shiftmap = astAnnul( shiftmap ); - map1 = astAnnul( map1 ); - map1 = newmap; - } - -/* Free resources. */ - shifts = astFree( shifts ); - } - } - -/* Now concatenate the Mappings to produce the returned Mapping. */ - map4 = (AstMapping *) astCmpMap( map1, map2, 1, "", status ); - ret = (AstMapping *) astCmpMap( map4, map3, 1, "", status ); - -/* Annul the component Mappings. */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - map3 = astAnnul( map3 ); - map4 = astAnnul( map4 ); - -/* We now make changes to the supplied Frame so that the longitude and - latitude axes are described by a SkyFrame. First create an appropriate - SkyFrame. */ - sfrm = WcsSkyFrame( this, store, s, prj, wcscelestial_type, axlon, - axlat, method, class, status ); - -/* The values currently stored in *reflat and *reflon are the CRVAL - values. In some circumstances, these may not be the original values in - the supplied header but may have been translated within the SpecTrans - function as part of the process of translating an old unsupported - projection into a new supported projection. Since the returned RefLat - and RefLon values may be used to set the reference position for a - SpecFrame, we should return the original values rather than the - translated values. The original values will have been stored (within - SpecTrans) in the FitsChan as keywords RFVALi. If such keywords can - be found, use their values in preference to the currently stored CRVAL - values.*/ - if( GetValue( this, FormatKey( "RFVAL", axlon + 1, -1, s, status ), - AST__FLOAT, (void *) &lonval, 0, 0, method, class, status ) && - GetValue( this, FormatKey( "RFVAL", axlat + 1, -1, s, status ), - AST__FLOAT, (void *) &latval, 0, 0, method, class, status ) ) { - *reflon = lonval*AST__DD2R; - *reflat = latval*AST__DD2R; - } - -/* Store the reflon and reflat values as the SkyRef position in the - SkyFrame, and set SkyRefIs to "ignore" so that the SkyFrame continues - to represent absolute celestial coords. Do not change the SkyFrame if - it already had a set reference posiiton. */ - if( ! astTestSkyRef( sfrm, 0 ) ) { - if( *reflon != AST__BAD && *reflat != AST__BAD ) { - astSetSkyRef( sfrm, 0, *reflon ); - astSetSkyRef( sfrm, 1, *reflat ); - astSet( sfrm, "SkyRefIs=Ignored", status ); - } - } - -/* Return a clone of this SkyFrame as the reference Frame. */ - *reffrm = astClone( sfrm ); - -/* Create a Frame by picking all the other (non-celestial) axes from the - supplied Frame. */ - axes = astMalloc( naxes*sizeof( int ) ); - if( axes ) { - j = 0; - for( i = 0; i < naxes; i++ ) { - if( i != axlat && i != axlon ) axes[ j++ ] = i; - } - -/* If there were no other axes, replace the supplied Frame with the skyframe. */ - if( j == 0 ) { - (void) astAnnul( *frm ); - *frm = (AstFrame *) astClone( sfrm ); - -/* Otherwise pick the other axes from the supplied Frame */ - } else { - ofrm = astPickAxes( *frm, j, axes, NULL ); - -/* Replace the supplied Frame with a CmpFrame made up of this Frame and - the SkyFrame. */ - (void) astAnnul( *frm ); - *frm = (AstFrame *) astCmpFrame( ofrm, sfrm, "", status ); - ofrm = astAnnul( ofrm ); - } - -/* Permute the axis order to put the longitude and latitude axes back in - their original position. The SkyFrame will have the default axis - ordering (lon=axis 0, lat = axis 1). */ - j = 0; - for( i = 0; i < naxes; i++ ) { - if( i == axlat ) { - axes[ i ] = naxes - 1; - } else if( i == axlon ) { - axes[ i ] = naxes - 2; - } else { - axes[ i ] = j++; - } - } - astPermAxes( *frm, axes ); - -/* Free the axes array. */ - axes= astFree( axes ); - } - -/* Set the units in the supplied IWC Frame for the longitude and latitude - axes. Unless using -TAB, these are degrees (the conversion from degs to - rads is part of the Mapping from IWC to WCS). If using -TAB the units - are unknown. */ - if( !tabaxis || !tabaxis[ axlon ] ) astSetUnit( iwcfrm, axlon, "deg" ); - if( !tabaxis || !tabaxis[ axlat ] ) astSetUnit( iwcfrm, axlat, "deg" ); - -/* Modify any supplied tabmap so that the celestial outputs create - radians rather than degrees (but only if the celestial axes are - generated by the -TAB algorithm). */ - if( tabaxis && tabaxis[ axlon ] && tabaxis[ axlat ] ) { - mat = (double *) astMalloc( sizeof(double)*naxes ); - if( mat ){ - for( i = 0; i < naxes; i++ ){ - if( i == axlat || i == axlon ){ - mat[ i ] = AST__DD2R; - } else { - mat[ i ] = 1.0; - } - } - map1 = (AstMapping *) astMatrixMap( naxes, naxes, 1, mat, "", status ); - mat = (double *) astFree( (void *) mat ); - map2 = (AstMapping *) astCmpMap( *tabmap, map1, 1, " ", status ); - map1 = astAnnul( map1 ); - (void) astAnnul( *tabmap ); - *tabmap = map2; - } - -/* Also modify the returned reflon and reflat values to transform them - using the tabmap. Also transform the reference position in the SkyFrame. */ - if( *reflon != AST__BAD && *reflat != AST__BAD ) { - ina = astMalloc( sizeof(double)*naxes ); - outa = astMalloc( sizeof(double)*naxes ); - if( astOK ) { - for( i = 0; i < naxes; i++ ) ina[ i ] = 0.0; - ina[ axlat ] = *reflat; - ina[ axlon ] = *reflon; - astTranN( *tabmap, 1, naxes, 1, ina, 1, naxes, 1, outa ); - *reflon = outa[ axlon ]; - *reflat = outa[ axlat ]; - } - ina = astFree( ina ); - outa = astFree( outa ); - -/* Store this transformed reference position in the SkyFrame. */ - astSetSkyRef( sfrm, 0, *reflon ); - astSetSkyRef( sfrm, 1, *reflat ); - astSet( sfrm, "SkyRefIs=Ignored", status ); - } - } - -/* If the header contains AXREF values for both lon and lat axes, use - them as the sky reference position in preferences to the values - derived form the CRVAL values. AXREF keywords are created by the - astWrite method for axes described by -TAB algorithm that have no inverse - transformation. */ - if( GetValue( this, FormatKey( "AXREF", axlon + 1, -1, s, status ), - AST__FLOAT, (void *) &lonval, 0, 0, method, class, status ) && - GetValue( this, FormatKey( "AXREF", axlat + 1, -1, s, status ), - AST__FLOAT, (void *) &latval, 0, 0, method, class, status ) ) { - *reflon = lonval*AST__DD2R; - *reflat = latval*AST__DD2R; - astSetSkyRef( sfrm, 0, *reflon ); - astSetSkyRef( sfrm, 1, *reflat ); - astSet( sfrm, "SkyRefIs=Ignored", status ); - } - -/* Free resources. */ - sfrm = astAnnul( sfrm ); - } - -/* Return the result. */ - return ret; -} - -static void WcsFcRead( AstFitsChan *fc, AstFitsChan *fc2, FitsStore *store, - const char *method, const char *class, int *status ){ -/* -* Name: -* WcsFcRead - -* Purpose: -* Extract WCS information from a supplied FitsChan using a FITSWCS -* encoding, and store it in the supplied FitsStore. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void WcsFcRead( AstFitsChan *fc, AstFitsChan *fc2, FitsStore *store, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function extracts FITSWCS keywords from the supplied FitsChan, -* and stores the corresponding WCS information in the supplied FitsStore. - -* Parameters: -* fc -* Pointer to the FitsChan containing the cards read from the -* original FITS header. This should not include any un-used -* non-standard keywords. -* fc2 -* Pointer to a second FitsChan. If a card read from "fc" fails to -* be converted to its correct data type, a warning is only issued -* if there is no card for this keyword in "fc2". "fc2" may be NULL -* in which case a warning is always issued. -* store -* Pointer to the FitsStore structure. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - char buf[200]; /* Buffer for warning message */ - char *cval; /* String keyword value */ - char *keynam; /* Pointer to current keyword name */ - char s; /* Co-ordinate version character */ - char *telescop; /* Pointer to TELESCOP keyword value */ - double dval; /* Floating point keyword value */ - int fld[2]; /* Integer field values from keyword name */ - int jm; /* Pixel axis or projection parameter index */ - int i; /* Intermediate axis index */ - int mark; /* Non-zero if card should be removed once used */ - int nfld; /* Number of integer fields in test string */ - int ok; /* Was value converted succesfully? */ - int type; /* Keyword data type */ - int undef; /* Is an undefined keyword value acceptable? */ - void *item; /* Pointer to item to get/put */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Ensure the FitsChan is re-wound. */ - astClearCard( fc ); - -/* Loop round all the cards in the FitsChan obtaining the keyword name for - each card. Note, the single "=" is correct in the following "while" - statement. */ - s = 0; - jm = -1; - i = -1; - type = AST__NOTYPE; - while( (keynam = CardName( fc, status )) ){ - item = NULL; - -/* Assume the card is to be consumed by the reading process. This means - the card will be marked as used and effectively excluded from the header. - Keywords which supply observation details that do not depend on the - mapping from pixel to WCS axes, or on the nature of the WCS axes, - are not removed as they may be needed for other, non-WCS related, - purposes. */ - mark = 1; - -/* For most keywords, if the keyword is present in the header it must - have a definded value. However, some keywords are read from the header - but not actually used for anything. This is done to ensure that the - keyword is stripped from the header. It is acceptable for such - keywords to have an undefined value. Initialise a flag indicating that - the next keyword read is not allowed to have an undefined value. */ - undef = 0; - -/* Is this a primary CRVAL keyword? */ - if( Match( keynam, "CRVAL%d", 1, fld, &nfld, method, class, status ) ){ - item = &(store->crval); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = ' '; - -/* Is this a secondary CRVAL keyword? */ - } else if( Match( keynam, "CRVAL%d%1c", 1, fld, &nfld, method, class, status ) ){ - item = &(store->crval); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary CRPIX keyword? */ - } else if( Match( keynam, "CRPIX%d", 1, fld, &nfld, method, class, status ) ){ - item = &(store->crpix); - type = AST__FLOAT; - i = 0; - jm = fld[ 0 ] - 1; - s = ' '; - -/* Is this a secondary CRPIX keyword? */ - } else if( Match( keynam, "CRPIX%d%1c", 1, fld, &nfld, method, class, status ) ){ - item = &(store->crpix); - type = AST__FLOAT; - i = 0; - jm = fld[ 0 ] - 1; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary CDELT keyword? */ - } else if( Match( keynam, "CDELT%d", 1, fld, &nfld, method, class, status ) ){ - item = &(store->cdelt); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = ' '; - -/* Is this a secondary CDELT keyword? */ - } else if( Match( keynam, "CDELT%d%1c", 1, fld, &nfld, method, class, status ) ){ - item = &(store->cdelt); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary CTYPE keyword? If so, store the associated comment. */ - } else if( Match( keynam, "CTYPE%d", 1, fld, &nfld, method, class, status ) ){ - item = &(store->ctype); - type = AST__STRING; - i = fld[ 0 ] - 1; - jm = 0; - s = ' '; - SetItemC( &(store->ctype_com), i, 0, ' ', CardComm( fc, status ), status ); - -/* Is this a secondary CTYPE keyword? If so, store the associated comment. */ - } else if( Match( keynam, "CTYPE%d%1c", 1, fld, &nfld, method, class, status ) ){ - item = &(store->ctype); - type = AST__STRING; - i = fld[ 0 ] - 1; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - SetItemC( &(store->ctype_com), i, 0, s, CardComm( fc, status ), status ); - -/* Is this a primary CNAME keyword? */ - } else if( Match( keynam, "CNAME%d", 1, fld, &nfld, method, class, status ) ){ - item = &(store->cname); - type = AST__STRING; - i = fld[ 0 ] - 1; - jm = 0; - s = ' '; - -/* Is this a secondary CNAME keyword? */ - } else if( Match( keynam, "CNAME%d%1c", 1, fld, &nfld, method, class, status ) ){ - item = &(store->cname); - type = AST__STRING; - i = fld[ 0 ] - 1; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary CUNIT keyword? */ - } else if( Match( keynam, "CUNIT%d", 1, fld, &nfld, method, class, status ) ){ - item = &(store->cunit); - type = AST__STRING; - i = fld[ 0 ] - 1; - jm = 0; - s = ' '; - -/* Is this a secondary CUNIT keyword? */ - } else if( Match( keynam, "CUNIT%d%1c", 1, fld, &nfld, method, class, status ) ){ - item = &(store->cunit); - type = AST__STRING; - i = fld[ 0 ] - 1; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary PC keyword? */ - } else if( Match( keynam, "PC%d_%d", 2, fld, &nfld, method, class, status ) ){ - item = &(store->pc); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = fld[ 1 ] - 1; - s = ' '; - -/* Is this a secondary PC keyword? */ - } else if( Match( keynam, "PC%d_%d%1c", 2, fld, &nfld, method, class, status ) ){ - item = &(store->pc); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = fld[ 1 ] - 1; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary PV keyword? */ - } else if( Match( keynam, "PV%d_%d", 2, fld, &nfld, method, class, status ) ){ - item = &(store->pv); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = fld[ 1 ]; - s = ' '; - -/* Is this a secondary PV keyword? */ - } else if( Match( keynam, "PV%d_%d%1c", 2, fld, &nfld, method, class, status ) ){ - item = &(store->pv); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = fld[ 1 ]; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary PS keyword? */ - } else if( Match( keynam, "PS%d_%d", 2, fld, &nfld, method, class, status ) ){ - item = &(store->ps); - type = AST__STRING; - i = fld[ 0 ] - 1; - jm = fld[ 1 ]; - s = ' '; - -/* Is this a secondary PS keyword? */ - } else if( Match( keynam, "PS%d_%d%1c", 2, fld, &nfld, method, class, status ) ){ - item = &(store->ps); - type = AST__STRING; - i = fld[ 0 ] - 1; - jm = fld[ 1 ]; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary RADESYS keyword? */ - } else if( Match( keynam, "RADESYS", 0, fld, &nfld, method, class, status ) ){ - item = &(store->radesys); - type = AST__STRING; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary RADESYS keyword? */ - } else if( Match( keynam, "RADESYS%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->radesys); - type = AST__STRING; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary EQUINOX keyword? */ - } else if( Match( keynam, "EQUINOX", 0, fld, &nfld, method, class, status ) ){ - item = &(store->equinox); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary EQUINOX keyword? */ - } else if( Match( keynam, "EQUINOX%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->equinox); - type = AST__FLOAT; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary LATPOLE keyword? */ - } else if( Match( keynam, "LATPOLE", 0, fld, &nfld, method, class, status ) ){ - item = &(store->latpole); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary LATPOLE keyword? */ - } else if( Match( keynam, "LATPOLE%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->latpole); - type = AST__FLOAT; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary LONPOLE keyword? */ - } else if( Match( keynam, "LONPOLE", 0, fld, &nfld, method, class, status ) ){ - item = &(store->lonpole); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary LONPOLE keyword? */ - } else if( Match( keynam, "LONPOLE%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->lonpole); - type = AST__FLOAT; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary WXSAXES keyword? */ - } else if( Match( keynam, "WCSAXES", 0, fld, &nfld, method, class, status ) ){ - item = &(store->wcsaxes); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary WCSAXES keyword? */ - } else if( Match( keynam, "WCSAXES%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->wcsaxes); - type = AST__FLOAT; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary DUT1 keyword? */ - } else if( Match( keynam, "DUT1", 0, fld, &nfld, method, class, status ) ){ - mark = 0; - item = &(store->dut1); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a primary DTAI keyword? Only handle if the telescope is JCMT - or UKIRT, since other telescopes may use DTAI for different purposes. */ - } else if( Match( keynam, "DTAI", 0, fld, &nfld, method, class, status ) ){ - if( GetValue( fc, "TELESCOP", AST__STRING, &telescop, 0, 0, method, - class, status ) && ( !strncmp( telescop, "JCMT", 4) - || !strncmp( telescop, "UKIRT", 5 ) ) ){ - mark = 0; - item = &(store->dtai); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - } - -/* Is this a primary MJD-OBS keyword? */ - } else if( Match( keynam, "MJD-OBS", 0, fld, &nfld, method, class, status ) ){ - mark = 0; - item = &(store->mjdobs); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a primary WCSNAME keyword? */ - } else if( Match( keynam, "WCSNAME", 0, fld, &nfld, method, class, status ) ){ - item = &(store->wcsname); - type = AST__STRING; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary WCSNAME keyword? */ - } else if( Match( keynam, "WCSNAME%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->wcsname); - type = AST__STRING; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary SPECSYS keyword? */ - } else if( Match( keynam, "SPECSYS", 0, fld, &nfld, method, class, status ) ){ - item = &(store->specsys); - type = AST__STRING; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary SPECSYS keyword? */ - } else if( Match( keynam, "SPECSYS%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->specsys); - type = AST__STRING; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary SSYSSRC keyword? */ - } else if( Match( keynam, "SSYSSRC", 0, fld, &nfld, method, class, status ) ){ - item = &(store->ssyssrc); - type = AST__STRING; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary SSYSSRC keyword? */ - } else if( Match( keynam, "SSYSSRC%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->ssyssrc); - type = AST__STRING; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary ZSOURCE keyword? */ - } else if( Match( keynam, "ZSOURCE", 0, fld, &nfld, method, class, status ) ){ - item = &(store->zsource); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary ZSOURCE keyword? */ - } else if( Match( keynam, "ZSOURCE%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->zsource); - type = AST__FLOAT; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary VELOSYS keyword? */ - } else if( Match( keynam, "VELOSYS", 0, fld, &nfld, method, class, status ) ){ - item = &(store->velosys); - type = AST__FLOAT; - undef = 1; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary VELOSYS keyword? */ - } else if( Match( keynam, "VELOSYS%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->velosys); - type = AST__FLOAT; - undef = 1; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary RESTFRQ keyword? */ - } else if( Match( keynam, "RESTFRQ", 0, fld, &nfld, method, class, status ) ){ - item = &(store->restfrq); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary RESTFRQ keyword? */ - } else if( Match( keynam, "RESTFRQ%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->restfrq); - type = AST__FLOAT; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary RESTWAV keyword? */ - } else if( Match( keynam, "RESTWAV", 0, fld, &nfld, method, class, status ) ){ - item = &(store->restwav); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary RESTWAV keyword? */ - } else if( Match( keynam, "RESTWAV%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->restwav); - type = AST__FLOAT; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary IMAGFREQ keyword? */ - } else if( Match( keynam, "IMAGFREQ", 0, fld, &nfld, method, class, status ) ){ - item = &(store->imagfreq); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a primary SKYREF keyword? */ - } else if( Match( keynam, "SREF%d", 1, fld, &nfld, method, class, status ) ){ - item = &(store->skyref); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = ' '; - -/* Is this a secondary SKYREF keyword? */ - } else if( Match( keynam, "SREF%d%1c", 1, fld, &nfld, method, class, status ) ){ - item = &(store->skyref); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary SKYREFP keyword? */ - } else if( Match( keynam, "SREFP%d", 1, fld, &nfld, method, class, status ) ){ - item = &(store->skyrefp); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = ' '; - -/* Is this a secondary SKYREFP keyword? */ - } else if( Match( keynam, "SREFP%d%1c", 1, fld, &nfld, method, class, status ) ){ - item = &(store->skyrefp); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary SKYREFIS keyword? */ - } else if( Match( keynam, "SREFIS", 0, fld, &nfld, method, class, status ) ){ - item = &(store->skyrefis); - type = AST__STRING; - i = 0; - jm = 0; - s = ' '; - -/* Is this a secondary SKYREFIS keyword? */ - } else if( Match( keynam, "SREFIS%1c", 0, fld, &nfld, method, class, status ) ){ - item = &(store->skyrefis); - type = AST__STRING; - i = 0; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary AXREF keyword? */ - } else if( Match( keynam, "AXREF%d", 1, fld, &nfld, method, class, status ) ){ - item = &(store->axref); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = ' '; - -/* Is this a secondary AXREF keyword? */ - } else if( Match( keynam, "AXREF%d%1c", 1, fld, &nfld, method, class, status ) ){ - item = &(store->axref); - type = AST__FLOAT; - i = fld[ 0 ] - 1; - jm = 0; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a MJD-AVG keyword? */ - } else if( Match( keynam, "MJD-AVG", 0, fld, &nfld, method, class, status ) ){ - mark = 0; - item = &(store->mjdavg); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a OBSGEO-X keyword? */ - } else if( Match( keynam, "OBSGEO-X", 0, fld, &nfld, method, class, status ) ){ - mark = 0; - item = &(store->obsgeox); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a OBSGEO-Y keyword? */ - } else if( Match( keynam, "OBSGEO-Y", 0, fld, &nfld, method, class, status ) ){ - mark = 0; - item = &(store->obsgeoy); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a OBSGEO-Z keyword? */ - } else if( Match( keynam, "OBSGEO-Z", 0, fld, &nfld, method, class, status ) ){ - mark = 0; - item = &(store->obsgeoz); - type = AST__FLOAT; - i = 0; - jm = 0; - s = ' '; - -/* Is this a TIMESYS keyword? */ - } else if( Match( keynam, "TIMESYS", 0, fld, &nfld, method, class, status ) ){ - mark = 0; - item = &(store->timesys); - type = AST__STRING; - i = 0; - jm = 0; - s = ' '; - -/* Following keywords are used to describe "-SIP" distortion as used by - the Spitzer project... */ - -/* Is this a primary A keyword? */ - } else if( Match( keynam, "A_%d_%d", 2, fld, &nfld, method, class, status ) ){ - item = &(store->asip); - type = AST__FLOAT; - i = fld[ 0 ]; - jm = fld[ 1 ]; - s = ' '; - -/* Is this a secondary A keyword? */ - } else if( Match( keynam, "A_%d_%d%1c", 2, fld, &nfld, method, class, status ) ){ - item = &(store->asip); - type = AST__FLOAT; - i = fld[ 0 ]; - jm = fld[ 1 ]; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary B keyword? */ - } else if( Match( keynam, "B_%d_%d", 2, fld, &nfld, method, class, status ) ){ - item = &(store->bsip); - type = AST__FLOAT; - i = fld[ 0 ]; - jm = fld[ 1 ]; - s = ' '; - -/* Is this a secondary B keyword? */ - } else if( Match( keynam, "B_%d_%d%1c", 2, fld, &nfld, method, class, status ) ){ - item = &(store->bsip); - type = AST__FLOAT; - i = fld[ 0 ]; - jm = fld[ 1 ]; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary AP keyword? */ - } else if( Match( keynam, "AP_%d_%d", 2, fld, &nfld, method, class, status ) ){ - item = &(store->apsip); - type = AST__FLOAT; - i = fld[ 0 ]; - jm = fld[ 1 ]; - s = ' '; - -/* Is this a secondary AP keyword? */ - } else if( Match( keynam, "AP_%d_%d%1c", 2, fld, &nfld, method, class, status ) ){ - item = &(store->apsip); - type = AST__FLOAT; - i = fld[ 0 ]; - jm = fld[ 1 ]; - s = keynam[ strlen( keynam ) - 1 ]; - -/* Is this a primary BP keyword? */ - } else if( Match( keynam, "BP_%d_%d", 2, fld, &nfld, method, class, status ) ){ - item = &(store->bpsip); - type = AST__FLOAT; - i = fld[ 0 ]; - jm = fld[ 1 ]; - s = ' '; - -/* Is this a secondary BP keyword? */ - } else if( Match( keynam, "BP_%d_%d%1c", 2, fld, &nfld, method, class, status ) ){ - item = &(store->bpsip); - type = AST__FLOAT; - i = fld[ 0 ]; - jm = fld[ 1 ]; - s = keynam[ strlen( keynam ) - 1 ]; - } - -/* If this keyword was recognized, store it in the FitsStore, and mark it - as having been read. */ - if( item ){ - ok = 1; - if( type == AST__FLOAT ){ - if( CnvValue( fc, AST__FLOAT, undef, &dval, method, status ) ) { - SetItem( (double ****) item, i, jm, s, dval, status ); - if( mark ) MarkCard( fc, status ); - } else { - ok = 0; - } - } else { - if( CnvValue( fc, AST__STRING, undef, &cval, method, status ) ) { - cval[ astChrLen( cval ) ] = 0; /* Exclude trailing spaces */ - SetItemC( (char *****) item, i, jm, s, cval, status ); - if( mark ) MarkCard( fc, status ); - } else { - ok = 0; - } - } - -/* Issue a warning if the value could not be converted to the expected - type. */ - if( !ok ) { - -/* First check that the keyword is not included in "fc2". */ - if( !HasCard( fc2, keynam, method, class, status ) ) { - sprintf( buf, "The original FITS header contained a value for " - "keyword %s which could not be converted to a %s.", - keynam, ( type==AST__FLOAT ? "floating point number": - "character string" ) ); - Warn( fc, "badval", buf, "astRead", "FitsChan", status ); - } - } - } - -/* Move on to the next card. */ - MoveCard( fc, 1, method, class, status ); - } -} - -static int WcsFromStore( AstFitsChan *this, FitsStore *store, - const char *method, const char *class, int *status ){ - -/* -* Name: -* WcsFromStore - -* Purpose: -* Store WCS keywords in a FitsChan using FITS-WCS encoding. - -* Type: -* Private function. - -* Synopsis: -* int WcsFromStore( AstFitsChan *this, FitsStore *store, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function copies the WCS information stored in the supplied -* FitsStore into the supplied FitsChan, using FITS-WCS encoding. - -* Parameters: -* this -* Pointer to the FitsChan. -* store -* Pointer to the FitsStore. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A value of 1 is returned if succesfull, and zero is returned -* otherwise. -*/ - -/* Local Variables: */ - char *comm; /* Pointer to comment string */ - char *cval; /* Pointer to string keyword value */ - char combuf[80]; /* Buffer for FITS card comment */ - char parprefix[4]; /* Prefix for projection parameter keywords */ - char s; /* Co-ordinate version character */ - char sign[2]; /* Fraction's sign character */ - char sup; /* Upper limit on s */ - char type[MXCTYPELEN];/* Buffer for CTYPE value */ - const char *order_kwd; /* Name for SIP max order keyword */ - double ****item; /* Address of FitsStore item to use */ - double cdl; /* CDELT value */ - double fd; /* Fraction of a day */ - double mjd99; /* MJD at start of 1999 */ - double val; /* General purpose value */ - int *tabaxis; /* Flags WCS axes that use -TAB algorithm */ - int i; /* Axis index */ - int ihmsf[ 4 ]; /* Hour, minute, second, fractional second */ - int iymdf[ 4 ]; /* Year, month, date, fractional day */ - int j; /* Axis index */ - int jj; /* SlaLib status */ - int m; /* Parameter index */ - int maxm; /* Upper limit on m */ - int naxis; /* Value of NAXIS keyword */ - int nc; /* Length of STYPE string */ - int nwcs; /* No. of WCS axes */ - int ok; /* Frame created succesfully? */ - int order; /* Max SIP polynomial order */ - int p; /* Power of u or U */ - int pmax; /* Max power of u or U */ - int prj; /* Projection type */ - int q; /* Power of v or V */ - int qmax; /* Max power of v or V */ - int ret; /* Returned value */ - -/* Initialise */ - ret = 0; - -/* Other initialisation to avoid compiler warnings. */ - tabaxis = NULL; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* If the FitsChan contains a value for the NAXIS keyword, note it. - Otherwise store -1. */ - if( !astGetFitsI( this, "NAXIS", &naxis ) ) naxis = -1; - -/* Find the last WCS related card. */ - FindWcs( this, 1, 1, 0, method, class, status ); - -/* Loop round all co-ordinate versions */ - sup = GetMaxS( &(store->crval), status ); - for( s = ' '; s <= sup && astOK; s++ ){ - -/* For alternate axes, skip this axis description if there is no CRPIX1 or - CRVAL1 value. This avoids partial axis descriptions being written out. */ - if( s != ' ' ) { - if( GetItem( &(store->crpix), 0, 0, s, NULL, method, class, status ) == - AST__BAD || - GetItem( &(store->crval), 0, 0, s, NULL, method, class, status ) == - AST__BAD ) { - ok = 0; - goto next; - } - } - -/* Assume the Frame can be created succesfully. */ - ok = 1; - -/* Save the number of wcs axes. If a value for WCSAXES has been set, or - if the number of axes is not the same as specified in the NAXIS keyword, - store a WCSAXES keyword. */ - val = GetItem( &(store->wcsaxes), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) { - nwcs = (int) ( val + 0.5 ); - } else { - nwcs = GetMaxJM( &(store->crpix), s, status ) + 1; - if( nwcs != 0 && nwcs != naxis ) val = (double) nwcs; - } - if( val != AST__BAD ) { - SetValue( this, FormatKey( "WCSAXES", -1, -1, s, status ), - &nwcs, AST__INT, "Number of WCS axes", status ); - } - -/* Get and save WCSNAME. This is NOT required, so do not return if it is - not available. If the WCS is 1-d, only store WCSNAME if its value is - different to the CTYPE1 value. */ - cval = GetItemC( &(store->wcsname), 0, 0, s, NULL, method, class, status ); - if( cval && nwcs == 1 ) { - comm = GetItemC( &(store->ctype), 0, 0, s, NULL, method, class, status ); - if( comm && Similar( comm, cval, status ) ) cval = NULL; - } - if( cval ) SetValue( this, FormatKey( "WCSNAME", -1, -1, s, status ), &cval, - AST__STRING, "Reference name for the coord. frame", status ); - -/* The prefix for numerical projection parameters is usually "PV". */ - strcpy( parprefix, "PV" ); - -/* Keywords common to all axis types... */ - -/* Get and save CRPIX for all pixel axes. These are required, so pass on - if they are not available. */ - for( i = 0; i < nwcs; i++ ) { - val = GetItem( &(store->crpix), 0, i, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - goto next; - } - sprintf( combuf, "Reference pixel on axis %d", i + 1 ); - SetValue( this, FormatKey( "CRPIX", i + 1, -1, s, status ), &val, AST__FLOAT, - combuf, status ); - } - -/* Get and save CRVAL for all WCS axes. These are required, so - pass on if they are not available. */ - for( i = 0; i < nwcs; i++ ) { - val = GetItem( &(store->crval), i, 0, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - goto next; - } - sprintf( combuf, "Value at ref. pixel on axis %d", i + 1 ); - SetValue( this, FormatKey( "CRVAL", i + 1, -1, s, status ), &val, AST__FLOAT, - combuf, status ); - } - -/* Allocate memory to indicate if each WCS axis is described by a -TAB - algorithm or not. Initialiss it to zero. */ - tabaxis = astCalloc( nwcs, sizeof( int ) ); - -/* Get and save CTYPE for all WCS axes. These are required, so - pass on if they are not available. */ - for( i = 0; i < nwcs; i++ ) { - cval = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - if( !cval ) { - ok = 0; - goto next; - } - comm = GetItemC( &(store->ctype_com), i, 0, s, NULL, method, class, status ); - if( !comm ) { - sprintf( combuf, "Type of co-ordinate on axis %d", i + 1 ); - comm = combuf; - } - -/* Extract the projection type as specified by the last 4 characters - in the CTYPE keyword value. This will be AST__WCSBAD for non-celestial - axes. Note, CTYPE can be more than 8 characters long. */ - nc = strlen( cval ); - prj = ( nc > 4 ) ? astWcsPrjType( cval + nc - 4 ) : AST__WCSBAD; - -/* If the projection type is "TPN" (an AST-specific code) convert it to - standard FITS-WCS code "TAN" and change the prefix for projection - parameters from "PV" to "QV". AST will do the inverse conversions when - reading such a header. Non-AST software will simply ignore the QV - terms and interpret the header as a simple TAN projection. */ - if( prj == AST__TPN ) { - strcpy( parprefix, "QV" ); - strcpy( type, cval ); - (void) strcpy( type + nc - 4, "-TAN" ); - cval = type; - } - -/* Note if the axis is described by the -TAB algorithm. */ - tabaxis[ i ] = ( prj == AST__WCSBAD && strlen( cval ) >= 8 && - !strncmp( cval + 4, "-TAB", 4 ) ); - -/* Store the (potentially modified) CTYPE value. */ - SetValue( this, FormatKey( "CTYPE", i + 1, -1, s, status ), &cval, AST__STRING, - comm, status ); - } - -/* Get and save CNAME for all WCS axes. These are NOT required, so - do not pass on if they are not available. Do not include a CNAME - keyword if its value equals the commen or value of the corresponding - CTYPE keyword. */ - for( i = 0; i < nwcs; i++ ) { - cval = GetItemC( &(store->cname), i, 0, s, NULL, method, class, status ); - if( cval ) { - comm = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - if( !comm || strcmp( comm, cval ) ) { - comm = GetItemC( &(store->ctype_com), i, 0, s, NULL, method, class, status ); - if( !comm || strcmp( comm, cval ) ) { - sprintf( combuf, "Description of axis %d", i + 1 ); - SetValue( this, FormatKey( "CNAME", i + 1, -1, s, status ), &cval, - AST__STRING, combuf, status ); - } - } - } - } - -/* Now choose whether to produce CDi_j or CDELT/PCi_j keywords. */ - if( astGetCDMatrix( this ) ) { - -/* CD matrix. Multiply the row of the PC matrix by the CDELT value. */ - for( i = 0; i < nwcs; i++ ) { - cdl = GetItem( &(store->cdelt), i, 0, s, NULL, method, class, status ); - if( cdl == AST__BAD ) cdl = 1.0; - for( j = 0; j < nwcs; j++ ){ - val = GetItem( &(store->pc), i, j, s, NULL, method, class, status ); - if( val == AST__BAD ) val = ( i == j ) ? 1.0 : 0.0; - val *= cdl; - if( val != 0.0 ) { - SetValue( this, FormatKey( "CD", i + 1, j + 1, s, status ), &val, - AST__FLOAT, "Transformation matrix element", status ); - } - } - } - -/* If producing PC/CDELT keywords... */ - } else { - -/* CDELT keywords. */ - for( i = 0; i < nwcs; i++ ) { - val = GetItem( &(store->cdelt), i, 0, s, NULL, method, class, status ); - if( val == AST__BAD ) { - ok = 0; - goto next; - } - sprintf( combuf, "Pixel size on axis %d", i + 1 ); - SetValue( this, FormatKey( "CDELT", i + 1, -1, s, status ), &val, AST__FLOAT, - combuf, status ); - } - -/* PC matrix. */ - for( i = 0; i < nwcs; i++ ) { - for( j = 0; j < nwcs; j++ ){ - val = GetItem( &(store->pc), i, j, s, NULL, method, class, status ); - if( val != AST__BAD ) { - if( i == j ) { - if( astEQUAL( val, 1.0 ) ) val = AST__BAD; - } else { - if( astEQUAL( val, 0.0 ) ) val = AST__BAD; - } - } - if( val != AST__BAD ) { - SetValue( this, FormatKey( "PC", i + 1, j + 1, s, status ), &val, - AST__FLOAT, "Transformation matrix element", status ); - } - } - } - } - -/* Get and save CUNIT for all WCS axes. These are NOT required, so - do not pass on if they are not available. */ - for( i = 0; i < nwcs; i++ ) { - cval = GetItemC( &(store->cunit), i, 0, s, NULL, method, class, status ); - if( cval ) { - sprintf( combuf, "Units for axis %d", i + 1 ); - SetValue( this, FormatKey( "CUNIT", i + 1, -1, s, status ), &cval, AST__STRING, - combuf, status ); - } - } - -/* Get and save AXREF for all WCS axes. These are NOT required, so do not - pass on if they are not available. Note, AXREF is a non-standard keyword - used by AST to communicate the reference position on any axes described - by the -TAB algorithm and which has no inverse transformation. For all - other cases, the reference position corresponds to the values of CRVAL. */ - for( i = 0; i < nwcs; i++ ) { - val = GetItem( &(store->axref), i, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) { - sprintf( combuf, "Reference WCS value on axis %d", i + 1 ); - SetValue( this, FormatKey( "AXREF", i + 1, -1, s, status ), &val, AST__FLOAT, - combuf, status ); - } - } - -/* Get and save SREFIS. This is NOT required, so do not return if it is - not available. Note, SREFIS is a non-standard keyword used by AST to - communicate the SkyRefIs attribute in the original SkyFrame. */ - cval = GetItemC( &(store->skyrefis), 0, 0, s, NULL, method, class, status ); - if( cval ) SetValue( this, FormatKey( "SREFIS", -1, -1, s, status ), &cval, - AST__STRING, "Is SkyRef used as pole or origin?", status ); - -/* Get and save SREF for all WCS axes. These are NOT required, so do not - pass on if they are not available. Note, SREF is a non-standard keyword - used by AST to communicate the SkyRef position on any axes described - by a offset SkyFrame. */ - for( i = 0; i < nwcs; i++ ) { - val = GetItem( &(store->skyref), i, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) { - sprintf( combuf, "Sky reference position on axis %d", i + 1 ); - SetValue( this, FormatKey( "SREF", i + 1, -1, s, status ), &val, AST__FLOAT, - combuf, status ); - } - } - -/* Get and save SREFP for all WCS axes. These are NOT required, so do not - pass on if they are not available. Note, SREFP is a non-standard keyword - used by AST to communicate the SkyRefP position on any axes described - by a offset SkyFrame. */ - for( i = 0; i < nwcs; i++ ) { - val = GetItem( &(store->skyrefp), i, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) { - sprintf( combuf, "Sky primary meridian position on axis %d", i + 1 ); - SetValue( this, FormatKey( "SREFP", i + 1, -1, s, status ), &val, AST__FLOAT, - combuf, status ); - } - } - -/* Date of observation (only allowed for primary axis descriptions). */ - if( s == ' ' ) { - val = GetItem( &(store->mjdobs), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) { - SetValue( this, FormatKey( "MJD-OBS", -1, -1, s, status ), - &val, AST__FLOAT, "Modified Julian Date of observation", status ); - -/* The format used for the DATE-OBS keyword depends on the value of the - keyword. For DATE-OBS < 1999.0, use the old "dd/mm/yy" format. - Otherwise, use the new "ccyy-mm-ddThh:mm:ss[.ssss]" format. */ - palCaldj( 99, 1, 1, &mjd99, &jj ); - if( val < mjd99 ) { - palDjcal( 0, val, iymdf, &jj ); - sprintf( combuf, "%2.2d/%2.2d/%2.2d", iymdf[ 2 ], iymdf[ 1 ], - iymdf[ 0 ] - ( ( iymdf[ 0 ] > 1999 ) ? 2000 : 1900 ) ); - } else { - palDjcl( val, iymdf, iymdf+1, iymdf+2, &fd, &jj ); - palDd2tf( 3, fd, sign, ihmsf ); - sprintf( combuf, "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d.%3.3d", - iymdf[0], iymdf[1], iymdf[2], ihmsf[0], ihmsf[1], - ihmsf[2], ihmsf[3] ); - } - -/* Now store the formatted string in the FitsChan. */ - cval = combuf; - SetValue( this, "DATE-OBS", (void *) &cval, AST__STRING, - "Date of observation", status ); - } - val = GetItem( &(store->mjdavg), 0, 0, ' ', NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, "MJD-AVG", &val, AST__FLOAT, - "Average Modified Julian Date of observation", status ); - -/* Store the timescale in TIMESYS. */ - cval = GetItemC( &(store->timesys), 0, 0, s, NULL, method, class, status ); - if( cval ) SetValue( this, "TIMESYS", &cval, AST__STRING, - "Timescale for MJD-OBS/MJD-AVG values", status ); - } - -/* Numerical projection parameters */ - maxm = GetMaxJM( &(store->pv), s, status ); - for( i = 0; i < nwcs; i++ ){ - for( m = 0; m <= maxm; m++ ){ - val = GetItem( &(store->pv), i, m, s, NULL, method, class, status ); - if( val != AST__BAD ) { - -/* If the axis uses the "TAB" algorithm, there may be a PVi_4a parameter - in the FitsStore. This is an AST extension to the published -TAB - algorithm, and is used to hold the interpolation method. To avoid - clashing with any standard use of PV1_4a, rename it to QVi_4a. The - default is zero (linear interpolation) so do not write the QV value - if it zero. */ - if( m == 4 && tabaxis[ i ] ) { - if( val != 0.0 ) { - SetValue( this, FormatKey( "QV", i + 1, m, s, status ), - &val, AST__FLOAT, "Use nearest neighbour " - "interpolation", status ); - } - -/* Just store the parameters for other type of axes. */ - } else { - SetValue( this, FormatKey( parprefix, i + 1, m, s, status ), &val, - AST__FLOAT, "Projection parameter", status ); - } - } - } - } - -/* String projection parameters */ - maxm = GetMaxJMC( &(store->ps), s, status ); - for( i = 0; i < nwcs; i++ ){ - for( m = 0; m <= maxm; m++ ){ - cval = GetItemC( &(store->ps), i, m, s, NULL, method, class, status ); - if( cval ) { - SetValue( this, FormatKey( "PS", i + 1, m, s, status ), &cval, - AST__STRING, "Projection parameter", status ); - } - } - } - -/* Keywords specific to celestial axes... */ - -/* Get and save RADESYS. This is NOT required, so do not return if it is - not available. */ - cval = GetItemC( &(store->radesys), 0, 0, s, NULL, method, class, status ); - if( cval ) SetValue( this, FormatKey( "RADESYS", -1, -1, s, status ), &cval, - AST__STRING, "Reference frame for RA/DEC values", status ); - -/* Reference equinox */ - val = GetItem( &(store->equinox), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "EQUINOX", -1, -1, s, status ), - &val, AST__FLOAT, - "[yr] Epoch of reference equinox", status ); - -/* Latitude of native north pole */ - val = GetItem( &(store->latpole), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "LATPOLE", -1, -1, s, status ), - &val, AST__FLOAT, - "[deg] Latitude of native north pole", status ); - -/* Longitude of native north pole */ - val = GetItem( &(store->lonpole), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "LONPOLE", -1, -1, s, status ), - &val, AST__FLOAT, - "[deg] Longitude of native north pole", status ); - -/* Keywords specific to spectral axes... */ - -/* SPECSYS - the standard of rest for the spectral axis */ - cval = GetItemC( &(store->specsys), 0, 0, s, NULL, method, class, status ); - if( cval ) SetValue( this, FormatKey( "SPECSYS", -1, -1, s, status ), &cval, - AST__STRING, "Standard of rest for spectral axis", status ); - -/* SSYSSRC - the standard of rest in which ZSOURCE is stored. */ - cval = GetItemC( &(store->ssyssrc), 0, 0, s, NULL, method, class, status ); - if( cval ) SetValue( this, FormatKey( "SSYSSRC", -1, -1, s, status ), &cval, - AST__STRING, "Standard of rest for source redshift", status ); - -/* ZSOURCE - topocentric optical velocity of source */ - val = GetItem( &(store->zsource), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "ZSOURCE", -1, -1, s, status ), - &val, AST__FLOAT, "[] Redshift of source", status ); - -/* VELOSYS - topocentric apparent radial velocity of the standard of rest. */ - val = GetItem( &(store->velosys), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "VELOSYS", -1, -1, s, status ), - &val, AST__FLOAT, "[m/s] Topo. apparent velocity of rest frame", status ); - -/* RESTFRQ - rest frequency */ - val = GetItem( &(store->restfrq), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "RESTFRQ", -1, -1, s, status ), - &val, AST__FLOAT, "[Hz] Rest frequency", status ); - -/* RESTWAV - rest wavelength */ - val = GetItem( &(store->restwav), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, FormatKey( "RESTWAV", -1, -1, s, status ), - &val, AST__FLOAT, "[m] Rest wavelength", status ); - -/* The image frequency corresponding to the rest frequency (only used for - double sideband data). This is not part of the FITS-WCS standard but - is added for the benefit of JACH. */ - val = GetItem( &(store->imagfreq), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) { - SetValue( this, "IMAGFREQ", &val, AST__FLOAT, "[Hz] Image frequency", status ); - } - -/* OBSGEO-X/Y/Z - observer's geocentric coords. Note, these always refer - to the primary axes. */ - if( s == ' ' ) { - val = GetItem( &(store->obsgeox), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, "OBSGEO-X", &val, AST__FLOAT, "[m] Observatory geocentric X", status ); - val = GetItem( &(store->obsgeoy), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, "OBSGEO-Y", &val, AST__FLOAT, "[m] Observatory geocentric Y", status ); - val = GetItem( &(store->obsgeoz), 0, 0, s, NULL, method, class, status ); - if( val != AST__BAD ) SetValue( this, "OBSGEO-Z", &val, AST__FLOAT, "[m] Observatory geocentric Z", status ); - } - - -/* Forward SIP distortion keywords. Loop over the two spatial axes. My reading - of the SIP paper is that the SIP distortion *must* be attached to the first - two pixel axes defined by the FITS header. */ - for( i = 0; i < 2; i++ ) { - -/* Get a pointer to the FitsStore item holding the values defining this - output. */ - if( i == 0 ) { - item = &(store->asip); - strcpy( parprefix, "A_" ); - order_kwd = "A_ORDER"; - } else { - item = &(store->bsip); - strcpy( parprefix, "B_" ); - order_kwd = "B_ORDER"; - } - -/* Get the largest powers used of u and v. */ - pmax = GetMaxI( item, s, status ); - qmax = GetMaxJM( item, s, status ); - -/* Loop round all combination of powers. */ - order = 0; - for( p = 0; p <= pmax; p++ ){ - for( q = 0; q <= qmax; q++ ){ - -/* Get the polynomial coefficient for this combination of powers. If it - is good, format the keyword name and store it in the header. */ - val = GetItem( item, p, q, s, NULL, method, class, status ); - if( val != AST__BAD ) { - SetValue( this, FormatKey( parprefix, p, q, s, status ), &val, - AST__FLOAT, "SIP forward distortion coeff", status ); - if( p + q > order ) order = p + q; - } - } - } - if( order > 0 ) SetValue( this, order_kwd, &order, AST__INT, - "SIP max order", status ); - } - -/* Inverse SIP distortion keywords. Loop over the two spatial axes. */ - for( i = 0; i < 2; i++ ) { - -/* Get a pointer to the FitsStore item holding the values defining this - output. */ - if( i == 0 ) { - item = &(store->apsip); - strcpy( parprefix, "AP_" ); - order_kwd = "AP_ORDER"; - } else { - item = &(store->bpsip); - strcpy( parprefix, "BP_" ); - order_kwd = "BP_ORDER"; - } - -/* Get the largest powers used of u and v. */ - pmax = GetMaxI( item, s, status ); - qmax = GetMaxJM( item, s, status ); - -/* Loop round all combination of powers. */ - order = 0; - for( p = 0; p <= pmax; p++ ){ - for( q = 0; q <= qmax; q++ ){ - -/* Get the polynomial coefficient for this combination of powers. If it - is good, format the keyword name and store it in the header. */ - val = GetItem( item, p, q, s, NULL, method, class, status ); - if( val != AST__BAD ) { - SetValue( this, FormatKey( parprefix, p, q, s, status ), &val, - AST__FLOAT, "SIP inverse distortion coeff", status ); - if( p + q > order ) order = p + q; - } - } - } - if( order > 0 ) SetValue( this, order_kwd, &order, AST__INT, - "SIP inverse max order", status ); - } - -/* See if a Frame was sucessfully written to the FitsChan. */ -next: - ok = ok && astOK; - -/* If so, indicate we have something to return. */ - if( ok ) ret = 1; - -/* If we are producing secondary axes, clear any error status so we can - continue to produce the next Frame. Retain the error if the primary axes - could not be produced. After the primary axes, do the A axes. */ - if( s != ' ' ) { - astClearStatus; - } else { - s = 'A' - 1; - } - -/* Remove the secondary "new" flags from the FitsChan. This flag is - associated with cards which have been added to the FitsChan during - this pass through the main loop in this function. If the Frame was - written out succesfully, just clear the flags. If anything went wrong - with this Frame, remove the flagged cards from the FitsChan. */ - FixNew( this, NEW2, !ok, method, class, status ); - -/* Set the current card so that it points to the last WCS-related keyword - in the FitsChan (whether previously read or not). */ - FindWcs( this, 1, 1, 0, method, class, status ); - -/* Free resources. */ - tabaxis = astFree( tabaxis ); - } - -/* Return zero or ret depending on whether an error has occurred. */ - return astOK ? ret : 0; -} - -static AstMapping *WcsIntWorld( AstFitsChan *this, FitsStore *store, char s, - int naxes, const char *method, const char *class, int *status ){ -/* -* Name: -* WcsIntWorld - -* Purpose: -* Create a Mapping from pixel coords to intermediate world coords. - -* Type: -* Private function. - -* Synopsis: -* AstMapping *WcsIntWorld( AstFitsChan *this, FitsStore *store, char s, -* int naxes, const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function interprets the contents of the supplied FitsStore -* structure, and creates a Mapping which describes the transformation -* from pixel coordinates to intermediate world coordinates, using the -* FITS World Coordinate System conventions. This is a general linear -* transformation described by the CRPIXj, PCi_j and CDELTi keywords. - -* Parameters: -* this -* The FitsChan. ASTWARN cards may be added to this FitsChan if any -* anomalies are found in the keyword values in the FitsStore. -* store -* A structure containing information about the requested axis -* descriptions derived from a FITS header. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* naxes -* The number of intermediate world coordinate axes (WCSAXES). -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the Mapping. -*/ - -/* Local Variables: */ - AstMapping *mapd1; /* Pointer to first distortion Mapping */ - AstMapping *mapd2; /* Pointer to second distortion Mapping */ - AstMapping *mapd3; /* Pointer to third distortion Mapping */ - AstMapping *mapd4; /* Pointer to fourth distortion Mapping */ - AstMapping *map0; /* Pointer to a Mapping */ - AstMapping *map1; /* Pointer to a Mapping */ - AstMapping *ret; /* Pointer to the returned Mapping */ - -/* Initialise the pointer to the returned Mapping. */ - ret = NULL; - -/* Check the global status. */ - if ( !astOK ) return ret; - -/* First of all, check the CTYPE keywords to see if they contain any known - distortion codes (following the syntax described in FITS-WCS paper IV). - If so, Mappings are returned which represents the distortions to be - applied at each point in the chain of Mappings produced by this function. - Any distortion codes are removed from the CTYPE values in the FitsStore. */ - DistortMaps( this, store, s, naxes, &mapd1, &mapd2, &mapd3, &mapd4, method, - class, status ); - -/* If distortion is to be applied now, initialise the returned Mapping to - be the distortion. */ - if( mapd1 ) ret = mapd1; - -/* Try to create a WinMap which translates the pixel coordinates so - that they are refered to an origin at the reference pixel. This - subtracts the value of CRPIXi from axis i. */ - map1 = (AstMapping *) WcsShift( store, s, naxes, method, class, status ); - -/* Combine this with any previous Mapping. */ - if( ret ) { - map0 = (AstMapping *) astCmpMap( ret, map1, 1, "", status ); - ret = astAnnul( ret ); - map1 = astAnnul( map1 ); - ret = map0; - } else { - ret = map1; - } - -/* If distortion is to be applied now, combine the two Mappings. */ - if( mapd2 ) { - map0 = (AstMapping *) astCmpMap( ret, mapd2, 1, "", status ); - ret = astAnnul( ret ); - mapd2 = astAnnul( mapd2 ); - ret = map0; - } - -/* Now try to create a MatrixMap to implement the PC matrix. Combine it - with the above Mapping. Add a Warning if this mapping cannot be inverted. */ - map1 = (AstMapping *) WcsPCMatrix( store, s, naxes, method, class, status ); - if( !astGetTranInverse( map1 ) ) { - Warn( this, "badmat", "The pixel rotation matrix in the original FITS " - "header (specified by CD or PC keywords) could not be inverted. " - "This may be because the matrix contains rows or columns which " - "are entirely zero.", method, class, status ); - } - map0 = (AstMapping *) astCmpMap( ret, map1, 1, "", status ); - ret = astAnnul( ret ); - map1 = astAnnul( map1 ); - ret = map0; - -/* If distortion is to be applied now, combine the two Mappings. */ - if( mapd3 ) { - map0 = (AstMapping *) astCmpMap( ret, mapd3, 1, "", status ); - ret = astAnnul( ret ); - mapd3 = astAnnul( mapd3 ); - ret = map0; - } - -/* Now try to create a diagonal MatrixMap to implement the CDELT scaling. - Combine it with the above Mapping. */ - map1 = (AstMapping *) WcsCDeltMatrix( store, s, naxes, method, class, status ); - map0 = (AstMapping *) astCmpMap( ret, map1, 1, "", status ); - ret = astAnnul( ret ); - map1 = astAnnul( map1 ); - ret = map0; - -/* If distortion is to be applied now, combine the two Mappings. */ - if( mapd4 ) { - map0 = (AstMapping *) astCmpMap( ret, mapd4, 1, "", status ); - ret = astAnnul( ret ); - mapd4 = astAnnul( mapd4 ); - ret = map0; - } - -/* Return the result. */ - return ret; -} - -static AstMapping *WcsMapFrm( AstFitsChan *this, FitsStore *store, char s, - AstFrame **frm, const char *method, - const char *class, int *status ){ -/* -* Name: -* WcsMapFrm - -* Purpose: -* Create a Mapping and Frame for the WCS transformations described in a -* FITS header. - -* Type: -* Private function. - -* Synopsis: -* AstMapping *WcsMapFrm( AstFitsChan *this, FitsStore *store, char s, -* AstFrame **frm, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function interprets the contents of the supplied FitsStore -* structure, and creates a Mapping which describes the transformation -* from pixel coordinates to world coordinates, using the FITS World -* Coordinate System conventions. It also creates a Frame describing -* the world coordinate axes. - -* Parameters: -* this -* The FitsChan. -* store -* A structure containing information about the requested axis -* descriptions derived from a FITS header. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* frm -* The address of a location at which to store a pointer to the -* Frame describing the world coordinate axes. If the Iwc attribute -* is non-zero, then this is actually a FrameSet in which Frame 1 -* is the base Frame and describes the required WCS system. Frame -* 2 is the current Frame and describes the FITS IWC system. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the Mapping. If the Iwc attribute is non-zero, this -* will be the Mapping from pixel to IWC coordinates. Otherwise it -* will be the mapping from pixel to WCS coordinates. -*/ - -/* Local Variables: */ - AstFrame *iwcfrm; /* Frame defining IWC system */ - AstFrameSet *fs; /* Pointer to returned FrameSet */ - AstMapping *map10; /* Pointer to a Mapping */ - AstMapping *map1; /* Pointer to a Mapping */ - AstMapping *map2; /* Pointer to a Mapping */ - AstMapping *map3; /* Pointer to a Mapping */ - AstMapping *map4; /* Pointer to a Mapping */ - AstMapping *map5; /* Pointer to a Mapping */ - AstMapping *map6; /* Pointer to a Mapping */ - AstMapping *map7; /* Pointer to a Mapping */ - AstMapping *map8; /* Pointer to a Mapping */ - AstMapping *map9; /* Pointer to a Mapping */ - AstMapping *ret; /* Pointer to the returned Mapping */ - AstMapping *tabmap; /* Mapping from psi to WCS (paper III - 6.1.2) */ - AstSkyFrame *reffrm; /* SkyFrame defining reflon and reflat */ - char id[2]; /* ID string for returned Frame */ - char iwc[5]; /* Domain name for IWC Frame */ - const char *cc; /* Pointer to Domain */ - double dtai; /* TAI-UTC correction in seconds */ - double dut1; /* UT1-UTC correction in days */ - double dval; /* Temporary double value */ - double reflat; /* Reference celestial latitude */ - double reflon; /* Reference celestial longitude */ - int *tabaxis; /* Flags indicating -TAB axes */ - int wcsaxes; /* Number of physical axes */ - -/* Initialise the pointer to the returned Mapping. */ - ret = NULL; - -/* Check the global status. */ - if ( !astOK ) return ret; - -/* Identify any axes that use the -TAB algoritm code described in FITS-WCS - paper III, and convert their CTYPE values to describe linear axes - (i.e. just remove "-TAB" from the CTYPE value). This also returns a - Mapping (which includes one or more LutMaps) that should be applied to - the resulting linear axis values in order to generate the final WCS - axis values. A NULL pointer is returned if no axes use -TAB. */ - tabmap = TabMapping( this, store, s, &tabaxis, method, class, status ); - -/* Obtain the number of physical axes in the header. If the WCSAXES header - was specified, use it. Otherwise assume it is the same as the number - of pixel axes. */ - dval = GetItem( &(store->wcsaxes), 0, 0, s, NULL, method, class, status ); - if( dval != AST__BAD ) { - wcsaxes = (int) dval + 0.5; - } else { - wcsaxes = store->naxis; - } - -/* Create a simple Frame to represent IWC coords. */ - iwcfrm = astFrame( wcsaxes, "Title=FITS Intermediate World Coordinates", status ); - strcpy( iwc, "IWC" ); - iwc[ 3 ]= s; - iwc[ 4 ]= 0; - astSetDomain( iwcfrm, iwc ); - -/* Create a simple Frame which will be used as the initial representation - for the physical axes. This Frame will be changed later (or possibly - replaced by a Frame of another class) when we know what type of - physical axes we are dealing with. Set its Domain to "AST_FITSCHAN" - This value is used to identify axes which have not been changed, - and will be replaced before returning the final FrameSet. */ - *frm = astFrame( wcsaxes, "Domain=AST_FITSCHAN", status ); - -/* Store the coordinate version character as the Ident attribute for the - returned Frame. */ - id[ 0 ] = s; - id[ 1 ] = 0; - astSetIdent( *frm, id ); - -/* Create a Mapping which goes from pixel coordinates to what FITS-WCS - paper I calls "intermediate world coordinates". This stage is the same - for all axes. It uses the CRPIXj, PCi_j and CDELTi headers (and - distortion codes from the CTYPE keywords). */ - map1 = WcsIntWorld( this, store, s, wcsaxes, method, class, status ); - -/* The conversion from intermediate world coordinates to the final world - coordinates depends on the type of axis being converted (as specified - by its CTYPE keyword). Check for each type of axis for which known - conventions exist... */ - -/* Celestial coordinate axes. The following call returns a Mapping which - transforms any celestial coordinate axes from intermediate world - coordinates to the final celestial coordinates. Other axes are left - unchanged by the Mapping. It also modifies the Frame so that a - SkyFrame is used to describe the celestial axes. */ - map2 = WcsCelestial( this, store, s, frm, iwcfrm, &reflon, &reflat, - &reffrm, &tabmap, tabaxis, method, class, status ); - -/* Spectral coordinate axes. The following call returns a Mapping which - transforms any spectral coordinate axes from intermediate world - coordinates to the final spectral coordinates. Other axes are left - unchanged by the Mapping. It also modifies the Frame so that a - SpecFrame is used to describe the spectral axes. */ - map3 = WcsSpectral( this, store, s, frm, iwcfrm, reflon, reflat, reffrm, - method, class, status ); - -/* Any axes which were not recognized by the above calls are assumed to - be linear. Create a Mapping which adds on the reference value for such - axes, and modify the Frame to desribe the axes. */ - map4 = WcsOthers( this, store, s, frm, iwcfrm, method, class, status ); - -/* If the Frame still has the Domain "AST_FITSCHAN", clear it. */ - cc = astGetDomain( *frm ); - if( cc && !strcmp( cc, "AST_FITSCHAN" ) ) astClearDomain( *frm ); - -/* Concatenate the Mappings and simplify the result. */ - map5 = (AstMapping *) astCmpMap( map1, map2, 1, "", status ); - map6 = (AstMapping *) astCmpMap( map5, map3, 1, "", status ); - map7 = (AstMapping *) astCmpMap( map6, map4, 1, "", status ); - if( tabmap ) { - map8 = (AstMapping *) astCmpMap( map7, tabmap, 1, "", status ); - } else { - map8 = astClone( map7 ); - } - - ret = astSimplify( map8 ); - -/* Ensure that the coordinate version character is stored as the Ident - attribute for the returned Frame (the above calls may have changed it). */ - astSetIdent( *frm, id ); - -/* Set the DUT1 value. Note, the JACH store DUT1 in units of days in their - FITS headers, so convert from days to seconds. May need to do somthing - about this if the forthcoming FITS-WCS paper 5 (time axes) defines DUT1 - to be in seconds. */ - dut1 = GetItem( &(store->dut1), 0, 0, s, NULL, method, class, status ); - if( dut1 != AST__BAD ) astSetDut1( *frm, dut1*SPD ); - -/* Set the DTAI value. */ - dtai = GetItem( &(store->dtai), 0, 0, s, NULL, method, class, status ); - if( dtai != AST__BAD ) astSetDtai( *frm, dtai ); - -/* The returned Frame is actually a FrameSet in which the base (first) Frame - is the required WCS Frame. The FrameSet contains one other Frame, - which is the Frame representing IWC and is always frame 2, the current - Frame. Create a FrameSet containing these two Frames. */ - if( astGetIwc( this ) ) { - fs = astFrameSet( *frm, "", status ); - astInvert( ret ); - map9 = (AstMapping *) astCmpMap( ret, map1, 1, "", status ); - astInvert( ret ); - map10 = astSimplify( map9 ); - astAddFrame( fs, AST__BASE, map10, iwcfrm ); - -/* Return this FrameSet instead of the Frame. */ - *frm = astAnnul( *frm ); - *frm = (AstFrame *) fs; - -/* Free resources */ - map9 = astAnnul( map9 ); - map10 = astAnnul( map10 ); - -/* Also modify the returned mapping so that it goes from pixel to iwc - instead of to wcs. */ - ret = astAnnul( ret ); - ret = astClone( map1 ); - } - -/* Annull temporary resources. */ - if( reffrm ) reffrm = astAnnul( reffrm ); - if( tabmap ) tabmap = astAnnul( tabmap ); - tabaxis = astFree( tabaxis ); - iwcfrm = astAnnul( iwcfrm ); - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - map3 = astAnnul( map3 ); - map4 = astAnnul( map4 ); - map5 = astAnnul( map5 ); - map6 = astAnnul( map6 ); - map7 = astAnnul( map7 ); - map8 = astAnnul( map8 ); - -/* Annul thre returned objects if an error has occurred. */ - if( !astOK ) { - ret = astAnnul( ret ); - *frm = astAnnul( *frm ); - } - -/* Return the result. */ - return ret; -} - -static AstMatrixMap *WcsPCMatrix( FitsStore *store, char s, int naxes, - const char *method, const char *class, int *status ){ -/* -* Name: -* WcsPCMatrix - -* Purpose: -* Create a MatrixMap representing the PC matrix. - -* Type: -* Private function. - -* Synopsis: -* AstMatrixMap *WcsPCMatrix( FitsStore *store, char s, int naxes, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A MatrixMap representing the FITS "PC" matrix is returned. - -* Parameters: -* store -* A structure containing values for FITS keywords relating to -* the World Coordinate System. -* s -* A character s identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* naxes -* The number of intermediate world coordinate axes (WCSAXES). -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the created MatrixMap or a NULL pointer if an -* error occurred. -*/ - -/* Local Variables: */ - AstMatrixMap *new; /* The created MatrixMap */ - double *el; /* Pointer to next matrix element */ - double *mat; /* Pointer to matrix array */ - int i; /* Pixel axis index */ - int j; /* Intermediate axis index. */ - -/* Initialise/ */ - new = NULL; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Allocate memory for the matrix. */ - mat = (double *) astMalloc( sizeof(double)*naxes*naxes ); - if( astOK ){ - -/* Fill the matrix with values from the FitsStore. */ - el = mat; - for( i = 0; i < naxes; i++ ){ - for( j = 0; j < naxes; j++ ){ - -/* Get the PCj_i value for this axis. Missing terms can be defaulted so - do not report an error if the required value is not present in the - FitsStore. */ - *el = GetItem( &(store->pc), i, j, s, NULL, method, class, status ); - -/* Diagonal terms default to to 1.0, off-diagonal to zero. */ - if( *el == AST__BAD ) *el = ( i == j ) ? 1.0: 0.0; - -/* Move on to the next matrix element. */ - el++; - } - } - -/* Create the matrix. */ - new = astMatrixMap( naxes, naxes, 0, mat, "", status ); - -/* Report an error if the inverse transformation is undefined. */ - if( !astGetTranInverse( new ) && astOK ) { - astError( AST__BDFTS, "%s(%s): Unusable rotation matrix (PC or CD) found " - "in the FITS-WCS header - the matrix cannot be inverted.", status, method, class ); - } - -/* Release the memory used to hold the matrix. */ - mat = (double *) astFree( (void *) mat ); - } - -/* If an error has occurred, attempt to annul the returned MatrixMap. */ - if( !astOK ) new = astAnnul( new ); - -/* Return the MatrixMap. */ - return new; -} - -static AstMapping *WcsNative( AstFitsChan *this, FitsStore *store, char s, - AstWcsMap *wcsmap, int fits_ilon, int fits_ilat, - const char *method, const char *class, int *status ){ -/* -* Name: -* WcsNative - -* Purpose: -* Create a CmpMap which transforms Native Spherical Coords to -* Celestial Coords. - -* Type: -* Private function. - -* Synopsis: -* AstMapping *WcsNative( AstFitsChan *this, FitsStore *store, char s, -* AstWcsMap *wcsmap, int fits_ilon, int fits_ilat, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A CmpMap is created which rotates the supplied Native Spherical Coords -* into Celestial Coords in the standard system specified by the CTYPE -* keywords. Any non-celestial axes are left unchanged. -* -* At the highest level, the returned CmpMap is made up of the following - -* Mappings in series (if celestial long/lat axes are present): -* 1 - A PermMap which rearranges the axes so that the longitude axis is -* axis 0, the latitude axis is axis 1, and all other axes are -* stored at higher indices, starting at axis 2. -* 2 - A CmpMap which converts the values on axes 0 and 1 from Native -* Spherical to Celestial coordinates, leaving all other axes -* unchanged. -* 3 - A PermMap which rearranges the axes to put the longitude and -* latitude axes back in their original places. This is just the -* inverse of the PermMap used at stage 1 above. -* -* The CmpMap used at stage 2 above, is made up of two Mappings in - -* parallel: -* 4 - A CmpMap which maps axes 0 and 1 from Native Spherical to -* Celestial coordinates. -* 5 - A UnitMap which passes on the values to axes 2, 3, etc, -* without change. -* -* The CmpMap used at stage 4 above, is made up of the following Mappings - -* in series: -* 6 - A SphMap which converts the supplied spherical coordinates into -* Cartesian Coordinates. -* 7 - A MatrixMap which rotates the Cartesian coordinates from the -* Native to the Celestial system. -* 8 - A SphMap which converts the resulting Cartesian coordinates back -* to spherical coordinates. - -* Parameters: -* this -* The FitsChan in which to store any warning cards. If NULL, no -* warnings are stored. -* store -* A structure containing values for FITS keywords relating to -* the World Coordinate System. -* s -* Co-ordinate version character to use (space means primary axes). -* wcsmap -* A mapping describing the deprojection which is being used. This is -* needed in order to be able to locate the fiducial point within the -* Native Speherical Coordinate system, since it varies from projection -* to projection. -* fits_ilon -* The zero-based FITS WCS axis index corresponding to celestial -* longitude (i.e. one less than the value of "i" in the keyword -* names "CTYPEi", "CRVALi", etc). If -1 is supplied, the index of -* the longitude axis in the supplied WcsMap is used. -* fits_ilat -* The zero-based FITS WCS axis index corresponding to celestial -* latitude (i.e. one less than the value of "i" in the keyword -* names "CTYPEi", "CRVALi", etc). If -1 is supplied, the index of -* the latitude axis in the supplied WcsMap is used. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the created CmpMap or a NULL pointer if an error occurred. - -* Notes: -* - The local variable names correspond to the notation in the papers -* by Greisen & Calabretta describing the FITS WCS system. -*/ - -/* Local Variables: */ - AstCmpMap *cmpmap; /* A CmpMap */ - AstMapping *new; /* The returned CmpMap */ - AstMatrixMap *matmap2; /* Another MatrixMap */ - AstMatrixMap *matmap; /* A MatrixMap */ - AstPermMap *permmap; /* A PermMap */ - AstSphMap *sphmap; /* A SphMap */ - AstUnitMap *unitmap; /* A UnitMap */ - char buf[150]; /* Message buffer */ - double alpha0; /* Long. of fiduaicl point in standard system */ - double alphap; /* Long. of native nth pole in standard system */ - double axis[3]; /* Vector giving the axis of rotation */ - double delta0; /* Lat. of fiducial point in standard system */ - double deltap; /* Lat. of native nth pole in standard system */ - double latpole; /* Lat. of native nth pole in standard system if deltap undefined */ - double phip; /* Long. of standard nth pole in native system */ - double phi0; /* Native longitude at fiducial point */ - double theta0; /* Native latitude at fiducial point */ - int *inperm; /* Pointer to array of output axis indices */ - int *outperm; /* Pointer to array of input axis indices */ - int axlat; /* Index of latitude physical axis */ - int axlon; /* Index of longitude physical axis */ - int i; /* Loop count */ - int nax_rem; /* No. of non-astrometric axes */ - int naxis; /* No. of axes. */ - int new_axlat; /* Index of lat. physical axis after perming */ - int tpn; /* Is this a TPN projection? */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the returned CmpMap pointer. */ - new = NULL; - -/* Store the number of axes in a local variable. */ - naxis = astGetNin( wcsmap ); - -/* Get the indices of the celestial axes. */ - axlon = astGetWcsAxis( wcsmap, 0 ); - axlat = astGetWcsAxis( wcsmap, 1 ); - -/* If the corresponding FITS axis indices were not supplied, use the - WcsMap axes found above. */ - if( fits_ilon == -1 ) fits_ilon = axlon; - if( fits_ilat == -1 ) fits_ilat = axlat; - -/* If there is no longitude or latitude axis, or if we have a - non-celestial projection, just return a UnitMap. */ - if( axlon == axlat || astGetWcsType( wcsmap ) == AST__WCSBAD ){ - new = (AstMapping *) astUnitMap( naxis, "", status ); - -/* If there is a lon/lat axis pair, create the inperm and outperm arrays - which will be needed later to create the PermMap which reorganises - the axes so that axis zero is the longitude axis and axis 1 is the - latitude axis. */ - } else { - -/* Get storage for the two arrays. */ - inperm = (int *) astMalloc( sizeof( int )*(size_t)naxis ); - outperm = (int *) astMalloc( sizeof( int )*(size_t)naxis ); - if( astOK ){ - -/* Initialise an array holding the indices of the input axes which are copied - to each output axis. Initially assume that there is no re-arranging of - the axes. */ - for( i = 0; i < naxis; i++ ) outperm[ i ] = i; - -/* Swap the longitude axis and axis 0. */ - i = outperm[ axlon ]; - outperm[ axlon ] = outperm[ 0 ]; - outperm[ 0 ] = i; - -/* If axis 0 was originally the latitude axis, the latitude axis will now - be where the longitude axis was originally (because of the above axis - swap). */ - if( axlat == 0 ) { - new_axlat = axlon; - } else { - new_axlat = axlat; - } - -/* Swap the latitude axis and axis 1. */ - i = outperm[ new_axlat ]; - outperm[ new_axlat ] = outperm[ 1 ]; - outperm[ 1 ] = i; - -/* Create the array holding the output axis index corresponding to - each input axis. */ - for( i = 0; i < naxis; i++ ) inperm[ outperm[ i ] ] = i; - } - -/* Store the latitude and longitude (in the standard system) of the fiducial - point, in radians. */ - delta0 = GetItem( &(store->crval), fits_ilat, 0, s, NULL, method, class, status ); - if( delta0 == AST__BAD ) delta0 = 0.0; - delta0 *= AST__DD2R; - alpha0 = GetItem( &(store->crval), fits_ilon, 0, s, NULL, method, class, status ); - if( alpha0 == AST__BAD ) alpha0 = 0.0; - alpha0 *= AST__DD2R; - -/* Limit the latitude to the range +/- PI/2, issuing a warning if the - supplied CRVAL value is outside this range. The "alphap" variable is used - as workspace here. */ - alphap = palDrange( delta0 ); - delta0 = alphap; - if ( delta0 > AST__DPIBY2 ){ - delta0 = AST__DPIBY2; - } else if ( delta0 < -AST__DPIBY2 ){ - delta0 = -AST__DPIBY2; - } - if( alphap != delta0 ) { - sprintf( buf, "The original FITS header specified a fiducial " - "point with latitude %.*g. A value of %.*g is being used " - "instead. ", AST__DBL_DIG, alphap*AST__DR2D, AST__DBL_DIG, - delta0*AST__DR2D ); - Warn( this, "badlat", buf, method, class, status ); - } - -/* Set a flag indicating if we have a TPN projection. The handling or - projection parameters is different for TPN projections. */ - tpn = ( astGetWcsType( wcsmap ) == AST__TPN ); - -/* Store the radian values of the FITS keywords LONPOLE and LATPOLE. Defaults - will be used if either of these items was not supplied. These keyword - values may be stored in projection parameters PVi_3a and PVi_4a for - longitude axis "i" - in which case the "PV" values take precedence over - the "LONPOLE" and "LATPOLE" values. Do not do this for TPN projections - since they use these projection parameters to specify correcton terms. */ - if( astTestPV( wcsmap, axlon, 3 ) && !tpn ) { - phip = astGetPV( wcsmap, axlon, 3 ); - } else { - phip = GetItem( &(store->lonpole), 0, 0, s, NULL, method, class, status ); - if( phip != AST__BAD && !tpn ) astSetPV( wcsmap, axlon, 3, phip ); - } - if( phip != AST__BAD ) phip *= AST__DD2R; - if( astTestPV( wcsmap, axlon, 4 ) && !tpn ) { - latpole = astGetPV( wcsmap, axlon, 4 ); - } else { - latpole = GetItem( &(store->latpole), 0, 0, s, NULL, method, class, status ); - if( latpole != AST__BAD && !tpn ) astSetPV( wcsmap, axlon, 4, latpole ); - } - if( latpole != AST__BAD ) latpole *= AST__DD2R; - -/* Find the standard Celestial Coordinates of the north pole of the Native - Spherical Coordinate system. Report an error if the position was not - defined. */ - if( !WcsNatPole( this, wcsmap, alpha0, delta0, latpole, &phip, &alphap, - &deltap, status ) && astOK ){ - astError( AST__BDFTS, "%s(%s): Conversion from FITS WCS native " - "coordinates to celestial coordinates is ill-conditioned.", status, - method, class ); - } - -/* Create the SphMap which converts spherical coordinates to Cartesian - coordinates (stage 6 in the prologue). This asumes that axis 0 is the - longitude axis, and axis 1 is the latitude axis. This will be ensured - by a PermMap created later. Indicate that the SphMap will only be used - to transform points on a unit sphere. This enables a forward SphMap - to be combined with an inverse SphMap into a UnitMap, and thus aids - simplification. */ - sphmap = astSphMap( "UnitRadius=1", status ); - astInvert( sphmap ); - -/* Set the PolarLong attribute of the SphMap so that a longitude of phi0 (the - native longitude of the fiducial point) is returned by the inverse - transformation (cartesian->spherical) at either pole. */ - GetFiducialNSC( wcsmap, &phi0, &theta0, status ); - astSetPolarLong( sphmap, phi0 ); - -/* Create a unit MatrixMap to be the basis of the MatrixMap which rotates - Native Spherical Coords to Celestial Coords (stage 7 in the prologue). */ - matmap = astMatrixMap( 3, 3, 2, NULL, "", status ); - -/* Modify the above MatrixMap so that it rotates the Cartesian position vectors - by -phip (i.e. LONPOLE) about the Z axis. This puts the north pole of the - standard system at zero longitude in the rotated system. Then annul the - original MatrixMap and use the new one instead. */ - axis[ 0 ] = 0; - axis[ 1 ] = 0; - axis[ 2 ] = 1; - matmap2 = astMtrRot( matmap, -phip, axis ); - matmap = astAnnul( matmap ); - matmap = matmap2; - -/* Now modify the above MatrixMap so that it rotates the Cartesian position - vectors by -(PI/2-deltap) about the Y axis. This puts the north pole of - the standard system as 90 degrees latitude in the rotated system. Then annul - the original MatrixMap and use the new one instead. */ - axis[ 0 ] = 0; - axis[ 1 ] = 1; - axis[ 2 ] = 0; - matmap2 = astMtrRot( matmap, deltap - AST__DPIBY2, axis ); - matmap = astAnnul( matmap ); - matmap = matmap2; - -/* Finally modify the above MatrixMap so that it rotates the Cartesian position - vectors (PI+alphap) about the Z axis. This puts the primary meridian of the - standard system at zero longitude in the rotated system. This results in the - rotated system being coincident with the standard system. */ - axis[ 0 ] = 0; - axis[ 1 ] = 0; - axis[ 2 ] = 1; - matmap2 = astMtrRot( matmap, AST__DPI + alphap, axis ); - matmap = astAnnul( matmap ); - matmap = matmap2; - -/* Combine the SphMap (stage 6) and MatrixMap (stage 7) in series. */ - cmpmap = astCmpMap( sphmap, matmap, 1, "", status ); - sphmap = astAnnul( sphmap ); - matmap = astAnnul( matmap ); - -/* Create a new SphMap which converts Cartesian coordinates to spherical - coordinates (stage 8 in the prologue). Indicate that the SphMap will - only be used to transform points on a unit sphere. */ - sphmap = astSphMap( "UnitRadius=1", status ); - -/* Set the PolarLong attribute of the SphMap so that a longitude of alpha0 - (the celestial longitude of the fiducial point) is returned by the - forward transformation (cartesian->spherical) at either pole. */ - astSetPolarLong( sphmap, alpha0 ); - -/* Add it to the compound mapping. The CmpMap then corresponds to stage 4 - in the prologue. Annul the constituent mappings. */ - new = (AstMapping *) astCmpMap( cmpmap, sphmap, 1, "", status ); - cmpmap = astAnnul( cmpmap ); - sphmap = astAnnul( sphmap ); - -/* If there are any remaining axes (i.e. axes which do not describe a - Celestial coordinate system), create a UnitMap which passes on their - values unchanged (stage 5 in the prologue), and add it the CmpMap, - putting it in parallel with the earlier mappings. The resulting CmpMap - then corresponds to stage 2 in the prologue. Note, the axis numbering - used by this UnitMap needs to take account of the fact that it is only - applied to the non-celestial axes. The axes are re-ordered by the - PermMap described at stage 1 in the prologue. */ - nax_rem = naxis - 2; - if( nax_rem > 0 ){ - unitmap = astUnitMap( nax_rem, "", status ); - cmpmap = astCmpMap( new, unitmap, 0, "", status ); - new = astAnnul( new ); - unitmap = astAnnul( unitmap ); - new = (AstMapping *) cmpmap; - } - -/* Now we need to ensure that axes 0 and 1 correspond to longitude and - latitude. If this is already the case, then the CmpMap can be returned - as it is. Otherwise, a PermMap needs to be created to rearrange the - axes. */ - if( axlon != 0 || axlat != 1 ){ - -/* Create the PermMap using the inperm and outperm arrays created earlier. - This is the mapping described as stage 1 in the prologue. */ - permmap = astPermMap( naxis, inperm, naxis, outperm, NULL, "", status ); - -/* Compound this PermMap and the CmpMap corresponding to stage 2 (created - earlier) in series. */ - cmpmap = astCmpMap( permmap, new, 1, "", status ); - new = astAnnul( new ); - new = (AstMapping *) cmpmap; - -/* Now invert the PermMap, so that it re-arranges the axes back into - their original order. This is the mapping described as stage 3 in - the prologue. */ - astInvert( permmap ); - -/* And finally.... add this inverted PermMap onto the end of the CmpMap. */ - cmpmap = astCmpMap( new, permmap, 1, "", status ); - permmap = astAnnul( permmap ); - new = astAnnul( new ); - new = (AstMapping *) cmpmap; - } - -/* Free the temporary arrays. */ - inperm = (int *) astFree( (void *) inperm ); - outperm = (int *) astFree( (void *) outperm ); - } - -/* If an error has occurred, attempt to annul the new CmpMap. */ - if( !astOK ) new = astAnnul( new ); - -/* Return the CmpMap. */ - return new; -} - -static int WcsNatPole( AstFitsChan *this, AstWcsMap *wcsmap, double alpha0, - double delta0, double latpole, double *phip, - double *alphap, double *deltap, int *status ){ - -/* -* Name: -* WcsNatPole - -* Purpose: -* Find the celestial coordinates of the north pole of the Native Spherical -* Coordinate system. - -* Type: -* Private function. - -* Synopsis: - -* int WcsNatPole( AstFitsChan *this, AstWcsMap *wcsmap, double alpha0, -* double delta0, double latpole, double *phip, -* double *alphap, double *deltap, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* The supplied WcsMap converts projected positions given in -* "Projection Plane Coords" to positions in the "Native Spherical -* Coordinate" system. This function finds the pole of this spherical -* coordinate system in terms of the standard celestial coordinate -* system to which the CRVALi, LONPOLE and LATPOLE keywords refer (this -* system should be identified by characters 5-8 of the CTYPEi -* keywords). It also supplies a default value for LONPOLE if no value -* has been supplied explicitly in the FITS header. -* -* This function implements equations 8, 9 and 10 from the FITS-WCS paper -* II by Calabretta & Greisen (plus the associated treatment of special -* cases). The paper provides more detailed documentation for the -* mathematics implemented by this function. - -* Parameters: -* this -* The FitsChan in which to store any warning cards. If NULL, no -* warnings are stored. -* wcsmap -* A mapping describing the deprojection being used (i.e. the -* mapping from Projection Plane Coords to Native Spherical Coords). -* alpha0 -* The longitude of the fiducial point in the standard celestial -* coordinate frame (in radians). Note, this fiducial point does -* not necessarily correspond to the point given by keywords CRPIXj. -* delta0 -* The celestial latitude (radians) of the fiducial point. -* latpole -* The value of FITS keyword LATPOLE, converted to radians, or the -* symbolic constant AST__BAD if the keyword was not supplied. -* phip -* Pointer to a location at which is stored the longitude of the north -* pole of the standard Celestial coordinate system, as measured in -* the Native Spherical Coordinate system, in radians. This should be -* supplied holding the radian equivalent of the value of the FITS -* keyword LONPOLE, or the symbolic constant AST__BAD if the keyword was -* not supplied (in which case a default value will be returned at the -* given location). -* alphap -* Pointer to a location at which to store the calculated longitude -* of the Native North Pole, in radians. -* deltap -* Pointer to a location at which to store the calculated latitude -* of the Native North Pole, in radians. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A status: non-zero for success, zero if the position of the native -* north pole is undefined. - -* Notes: -* - Certain combinations of keyword values result in the latitude of -* the Native North Pole being undefined. In these cases, a value of -* 0 is returned for the function value, but no error is reported. -* - All angular values used by this function are in radians. -* - A value of 0 is returned if an error has already occurred. -*/ - -/* Local Variables: */ - char buf[150]; /* Buffer for warning message */ - double cos_theta0; /* Cosine of theta0 */ - double cos_phip; /* Cosine of (phip - phi0) */ - double cos_delta0; /* Cosine of delta0 */ - double cos_deltap; /* Cosine of deltap */ - double deltap_1; /* First possible value for deltap */ - double deltap_2; /* Second possible value for deltap */ - double sin_theta0; /* Sine of theta0 */ - double sin_phip; /* Sine of (phip - phi0) */ - double sin_delta0; /* Sine of delta0 */ - double sin_deltap; /* Sine of deltap */ - double t0, t1, t2, t3, t4; /* Intermediate values */ - double phi0, theta0; /* Native coords of fiducial point */ - -/* Check the global status. */ - if ( !astOK ) return 0; - -/* Get the longitude and latitude of the fiducial point in the native - spherical coordinate frame (in radians). */ - GetFiducialNSC( wcsmap, &phi0, &theta0, status ); - -/* If no value was supplied for the FITS keyword LONPOLE, set up a default - value such that the celestial latitude increases in the same direction - as the native latitude at the fiducial; point. */ - if( *phip == AST__BAD ){ - if( delta0 >= theta0 ){ - *phip = 0.0; - } else { - *phip = AST__DPI; - } - -/* Issue a warning that a default lonpole value has been adopted. */ - sprintf( buf, "The original FITS header did not specify the " - "longitude of the native north pole. A default value " - "of %.8g degrees was assumed.", (*phip)*AST__DR2D ); - Warn( this, "nolonpole", buf, "astRead", "FitsChan", status ); - } - -/* If the fiducial point is coincident with the Native North Pole, then the - Native North Pole must have the same coordinates as the fiducial - point. Tests for equality include some tolerance to allow for rounding - errors. */ - sin_theta0 = sin( theta0 ); - if( astEQUAL( sin_theta0, 1.0 ) ){ - *alphap = alpha0; - *deltap = delta0; - -/* If the fiducial point is concident with the Native South Pole, then the - Native North Pole must have the coordinates of the point diametrically - opposite the fiducial point. */ - } else if( astEQUAL( sin_theta0, -1.0 ) ){ - *alphap = alpha0 + AST__DPI; - *deltap = -delta0; - -/* For all other cases, go through the procedure described in the WCS paper - by Greisen & Calabretta, to find the position of the Native North Pole. - First store some useful values. */ - } else { - cos_theta0 = cos( theta0 ); - cos_delta0 = cos( delta0 ); - cos_phip = cos( *phip - phi0 ); - sin_delta0 = sin( delta0 ); - sin_phip = sin( *phip - phi0 ); - -/* Next, find the two possible values for the latitude of the Native - North Pole (deltap). If any stage of this transformation is - indeterminate, return zero (except for the single special case noted - in item 6 para. 2 of the WCS paper, for which LATPOLE specifies the - values to be used). */ - t0 = cos_theta0*cos_phip; - if( fabs( t0 ) < TOL2 && fabs( sin_theta0 ) < TOL2 ){ - if( latpole != AST__BAD ) { - *deltap = latpole; - } else { - return 0; - } - } else { - t1 = atan2( sin_theta0, t0 ); - t2 = cos_theta0*cos_phip; - t2 *= t2; - t2 += sin_theta0*sin_theta0; - if( t2 <= DBL_MIN ){ - return 0; - } else { - t3 = sin_delta0/sqrt( t2 ); - if( fabs( t3 ) > 1.0 + TOL1 ){ - return 0; - } else { - if( t3 < -1.0 ){ - t4 = AST__DPI; - } else if( t3 > 1.0 ){ - t4 = 0.0; - } else { - t4 = acos( t3 ); - } - deltap_1 = palDrange( t1 + t4 ); - deltap_2 = palDrange( t1 - t4 ); - -/* Select which of these two values of deltap to use. Values outside the - range +/- PI/2 cannot be used. If both values are within this range - use the value which is closest to the supplied value of latpole (or - use the northern most value if the LATPOLE keyword was not supplied. */ - if( fabs( deltap_1 ) > AST__DPIBY2 + TOL2 ){ - *deltap = deltap_2; - } else if( fabs( deltap_2 ) > AST__DPIBY2 + TOL2 ){ - *deltap = deltap_1; - } else { - if( latpole != AST__BAD ){ - if( fabs( deltap_1 - latpole ) < - fabs( deltap_2 - latpole ) ){ - *deltap = deltap_1; - } else { - *deltap = deltap_2; - } - } else { - if( deltap_1 > deltap_2 ){ - *deltap = deltap_1; - } else { - *deltap = deltap_2; - } - -/* Issue a warning that a default latpole value has been adopted. */ - sprintf( buf, "The original FITS header did not specify " - "the latitude of the native north pole. A " - "default value of %.8g degrees was assumed.", - (*deltap)*AST__DR2D ); - Warn( this, "nolatpole", buf, "astRead", "FitsChan", status ); - } - } - if( fabs( *deltap ) > AST__DPIBY2 + TOL2 ) { - return 0; - } else if( *deltap < -AST__DPIBY2 ){ - *deltap = -AST__DPIBY2; - } else if( *deltap > AST__DPIBY2 ){ - *deltap = AST__DPIBY2; - } - } - } - } - -/* If a valid value for the latitude (deltap) has been found, find the - longitude of the Native North Pole. */ - if( *deltap != AST__BAD ) { - if( fabs( cos_delta0) > TOL2 ){ - cos_deltap = cos( *deltap ); - sin_deltap = sin( *deltap ); - if( fabs( cos_deltap ) > TOL2 ){ - t1 = sin_phip*cos_theta0/cos_delta0; - t2 = ( sin_theta0 - sin_deltap*sin_delta0 ) - /( cos_delta0*cos_deltap ); - if( ( fabs( t1 ) > TOL2 ) || ( fabs( t2 ) > TOL2 ) ){ - *alphap = alpha0 - atan2( t1, t2 ); - } else { - *alphap = alpha0; - } - } else if( sin_deltap > 0.0 ){ - *alphap = alpha0 + (*phip - phi0) - AST__DPI; - } else { - *alphap = alpha0 - (*phip - phi0); - } - } else { - *alphap = alpha0; - } - } else { - *alphap = AST__BAD; - } - } - -/* Return a success status if valid latitude and longitude values were - found. */ - return (*deltap) != AST__BAD && (*alphap) != AST__BAD ; -} - -static AstMapping *WcsOthers( AstFitsChan *this, FitsStore *store, char s, - AstFrame **frm, AstFrame *iwcfrm, const char *method, - const char *class, int *status ){ - -/* -* Name: -* WcsOthers - -* Purpose: -* Create a Mapping from intermediate world coords to any axes -* which are not covered by specialised conventions. - -* Type: -* Private function. - -* Synopsis: - -* AstMapping *WcsOthers( AstFitsChan *this, FitsStore *store, char s, -* AstFrame **frm, AstFrame *iwcfrm, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function interprets the contents of the supplied FitsStore -* structure, looking for world coordinate axes for which no -* description has yet been added to the supplied Frame . It is -* assumed that any such axes are simple linear axes. It returns a -* Mapping which simply adds on the CRVAL values to such axes. -* It also modifies the supplied Frame to describe the axes. - -* Parameters: -* this -* The FitsChan. -* store -* A structure containing information about the requested axis -* descriptions derived from a FITS header. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* frm -* The address of a location at which to store a pointer to the -* Frame describing the world coordinate axes. -* iwcfrm -* A pointer to the Frame describing the intermediate world coordinate -* axes. The properties of this Frame may be changed on exit. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the Mapping. -*/ - -/* Local Variables: */ - AstFrame *pfrm; /* Pointer to primary Frame */ - AstFrame *pfrm2; /* Pointer to primary Frame */ - AstMapping *map1; /* Pointer to a Mapping */ - AstMapping *map2; /* Pointer to a Mapping */ - AstMapping *ret; /* The returned Mapping */ - char **comms; /* Pointer to array of CTYPE commments */ - char buf[ 100 ]; /* Buffer for textual attribute value */ - char buf2[ 100 ]; /* Buffer for textual attribute value */ - char buf3[ 20 ]; /* Buffer for default CTYPE value */ - char *newdom; /* Pointer to new Domain value */ - const char *ckeyval; /* Pointer to character keyword value */ - int i; /* Axis index */ - int j; /* Axis index */ - int len; /* Used length of string */ - int naxes; /* no. of axes in Frame */ - int nother; /* The number of "other" axes */ - int paxis; /* Primary axis index */ - int usecom; /* Use CTYPE comments as axis Labels? */ - -/* Initialise the pointer to the returned Mapping. */ - ret = NULL; - -/* Check the global status. */ - if ( !astOK ) return ret; - -/* Get the number of physical axes. */ - naxes = astGetNaxes( *frm ); - -/* Assume we will use CTYPE comments as the axis labels. */ - usecom = 1; - -/* Initialise the count of "other" axes. */ - nother = 0; - -/* Get the comments associated with the CTYPE keywords for all "other" - axes. */ - comms = astMalloc( naxes*sizeof( char * ) ); - if( comms ) { - -/* Loop round all axes in the Frame, and initialise the pointer to its - comment. */ - for( i = 0; i < naxes; i++ ){ - comms[ i ] = NULL; - -/* Get the Domain for the primary frame containing the axis. This will be - "AST_FITSCHAN" if the axis has not yet been recognised (this Domain is - set up by WcsMapFrm). Only consider the axis further if the Domain has - not been changed. */ - astPrimaryFrame( *frm, i, &pfrm, &paxis ); - if( !strcmp( astGetDomain( pfrm ), "AST_FITSCHAN" ) ) { - -/* Increment the count of "other" axes. */ - nother++; - -/* Get the comment associated with the CTYPE header. */ - ckeyval = GetItemC( &(store->ctype_com), i, 0, s, NULL, method, class, status ); - -/* If this axis has no CTYPE comment, we will use CTYPE values as axis - labels (if given, the CNAME keyword take precedence). */ - if( !ckeyval || astChrLen( ckeyval ) == 0 ) { - usecom = 0; - -/* If the CTYPE comment for this axis is the same as any other comment, we - will use CTYPE values as axis labels. */ - } else { - for( j = 0; j < nother - 1; j++ ) { - if( comms[ j ] && !strcmp( ckeyval, comms[ j ] ) ) { - usecom = 0; - break; - } - } - } - -/* If we are still using comments as axis labels, store a copy of it in the - workspace. */ - if( usecom ) comms[ i ] = astStore( NULL, ckeyval, - strlen( ckeyval ) + 1 ); - } - pfrm = astAnnul( pfrm ); - } - -/* Free the workspace holding comments. */ - for( i = 0; i < naxes; i++ ) comms[ i ] = astFree( comms[ i ] ); - comms = astFree( comms ); - } - -/* If there are no "other" axes, just return a UnitMap. */ - if( nother == 0 ) { - ret = (AstMapping *) astUnitMap( naxes, "", status ); - -/* Otherwise... */ - } else { - -/* If we have only a single other axis, use CTYPE value instead of - comment. */ - if( nother == 1 ) usecom = 0; - -/* Not yet started a new Domain value to replace "AST_FITSCHAN". */ - newdom = NULL; - pfrm2 = NULL; - -/* Check each axis of the Frame looking for axes which have not yet been - recognised. */ - for( i = 0; i < naxes; i++ ) { - -/* Get the Domain for the primary frame containing the axis. This will be - "AST_FITSCHAN" if the axis has not yet been recognised (this Domain is - set up by WcsMapFrm). Only consider the axis further if the Domain has - not been changed. */ - astPrimaryFrame( *frm, i, &pfrm, &paxis ); - if( !strcmp( astGetDomain( pfrm ), "AST_FITSCHAN" ) ) { - -/* Save a pointer to the primary Frame which we will use to set the - Domain of the primary Frame. */ - if( !pfrm2 ) pfrm2 = astClone( pfrm ); - -/* Get the CTYPE value. Use a default of "AXISn". */ - ckeyval = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - if( !ckeyval ) { - sprintf( buf3, "AXIS%d", i + 1 ); - ckeyval = buf3; - } - -/* If the CTYPE value ends with "-LOG", assume it is a logarithmically spaced - axis. Get the Mapping from IWC to WCS. Reduce the used length of the - CTYPE string to exlude any trailing "-LOG" string. */ - len = strlen( ckeyval ); - if( len > 3 && !strcmp( ckeyval + len - 4, "-LOG" ) ){ - map1 = LogWcs( store, i, s, method, class, status ); - sprintf( buf2, "%.*s", len - 4, ckeyval ); - -/* Otherwise, assume the axis is linearly spaced. */ - } else { - map1 = LinearWcs( store, i, s, method, class, status ); - sprintf( buf2, "%.*s", len, ckeyval ); - } - -/* Append the CTYPE value to the final Domain value for the primary Frame. */ - if( ckeyval && astChrLen( ckeyval ) > 0 ) { - if( newdom ) { - sprintf( buf, "%s-%s", newdom, buf2 ); - } else { - sprintf( buf, "%s", buf2 ); - newdom = buf; - } - } - -/* Now modify the axis in the Frame to have appropriate values for the - Unit, Label and Symbol attributes. Also set the Unit attribute for - the corresponding axis in the IWC Frame. */ - if( ckeyval ) astSetSymbol( *frm, i, buf2 ); - ckeyval = GetItemC( &(store->cname), i, 0, s, NULL, method, class, status ); - if( !ckeyval && usecom ) ckeyval = GetItemC( &(store->ctype_com), - i, 0, s, NULL, method, class, status ); - if( !ckeyval ) ckeyval = buf2; - if( ckeyval ) astSetLabel( *frm, i, ckeyval ); - ckeyval = GetItemC( &(store->cunit), i, 0, s, NULL, method, class, status ); - if( ckeyval ) { - astSetUnit( *frm, i, ckeyval ); - astSetUnit( iwcfrm, i, ckeyval ); - } - -/* If this axis has been described by an earlier function (because it - uses specialised conventions such as those described in FITS-WCS papers - II or III), then create a UnitMap for this axis. */ - } else { - map1 = (AstMapping *) astUnitMap( 1, "", status ); - } - -/* Annul the pointer to the primary Frame containing the current axis. */ - pfrm = astAnnul( pfrm ); - -/* Add the Mapping for this axis in parallel with the current "running sum" - Mapping (if any). */ - if( ret ) { - map2 = (AstMapping *) astCmpMap( ret, map1, 0, "", status ); - ret = astAnnul( ret ); - map1 = astAnnul( map1 ); - ret = map2; - } else { - ret = map1; - } - } - -/* Set the Domain name for the primary Frame. It is currently set to - AST_FITSCHAN. We replace it with a value formed by concatenating the - CTYPE values of its axes. */ - if( pfrm2 ) { - if( newdom && astChrLen( newdom ) > 0 ) { - astSetDomain( pfrm2, newdom ); - } else { - astClearDomain( pfrm2 ); - } - pfrm2 = astAnnul( pfrm2 ); - } - -/* If the header contained a WCSNAME keyword, use it as the Domain name for - the Frame. Also use it to create a title. */ - ckeyval = GetItemC( &(store->wcsname), 0, 0, s, NULL, method, class, status ); - if( ckeyval ){ - astSetDomain( *frm, ckeyval ); - sprintf( buf, "%s coordinates", ckeyval ); - astSetTitle( *frm, buf ); - } - } - -/* Return the result. */ - return ret; -} - -static AstWinMap *WcsShift( FitsStore *store, char s, int naxes, - const char *method, const char *class, int *status ){ -/* -* Name: -* WcsShift - -* Purpose: -* Create a WinMap which shifts pixels coordinates so that their origin -* is at the reference pixel. - -* Type: -* Private function. - -* Synopsis: -* AstWinMap *WcsShift( FitsStore *store, char s, int naxes, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* A WinMap is created which implements a shift of origin by subtracting -* the reference pixel coordinates (CRPIXi) from the input pixel -* coordinates. - -* Parameters: -* store -* A structure containing values for FITS keywords relating to -* the World Coordinate System. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* naxes -* The number of intermediate world coordinate axes (WCSAXES). -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the created WinMap or a NULL pointer if an -* error occurred. - -* Notes: -* - If an error occurs, a NULL pointer is returned. -*/ - -/* Local Variables: */ - AstWinMap *new; /* The created WinMap */ - int j; /* Pixel axis index */ - double crpix; /* CRPIX keyword value */ - double *c1_in; /* Input corner 1 */ - double *c2_in; /* Input corner 2 */ - double *c1_out; /* Output corner 1 */ - double *c2_out; /* Output corner 2 */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the returned WinMap pointer. */ - new = NULL; - -/* Allocate memory to hold the two corners, in both input and output - coordinates. */ - c1_in = (double *) astMalloc( sizeof( double )*(size_t) naxes ); - c1_out = (double *) astMalloc( sizeof( double )*(size_t) naxes ); - c2_in = (double *) astMalloc( sizeof( double )*(size_t) naxes ); - c2_out = (double *) astMalloc( sizeof( double )*(size_t) naxes ); - -/* Check these pointers can be used. */ - if( astOK ){ - -/* Set up two arbitrary corners in the input coordinate system, and the - corresponding values with the CRPIX values subtracted off. */ - for( j = 0; j < naxes; j++ ){ - -/* Get the CRPIX value for this axis. */ - crpix = GetItem( &(store->crpix), 0, j, s, NULL, method, class, status ); - if( crpix == AST__BAD ) crpix = 0.0; - -/* Store the corner co-ordinates. */ - c1_in[ j ] = 0.0; - c2_in[ j ] = 1.0; - c1_out[ j ] = -crpix; - c2_out[ j ] = 1.0 - crpix; - } - -/* Create the WinMap. */ - new = astWinMap( naxes, c1_in, c2_in, c1_out, c2_out, "", status ); - -/* If an error has occurred, attempt to annul the new WinMap. */ - if( !astOK ) new = astAnnul( new ); - } - -/* Free the memory holding the corners. */ - c1_in = (double *) astFree( (void *) c1_in ); - c1_out = (double *) astFree( (void *) c1_out ); - c2_in = (double *) astFree( (void *) c2_in ); - c2_out = (double *) astFree( (void *) c2_out ); - -/* Return the WinMap. */ - return new; -} - -static AstSkyFrame *WcsSkyFrame( AstFitsChan *this, FitsStore *store, char s, - int prj, char *sys, int axlon, int axlat, - const char *method, const char *class, int *status ){ - -/* -* Name: -* WcsSkyFrame - -* Purpose: -* Create a SkyFrame to describe a WCS celestial coordinate system. - -* Type: -* Private function. - -* Synopsis: -* AstSkyFrame *WcsSkyFrame( AstFitsChan this, FitsStore *store, char s, int prj, -* char *sys, int axlon, int axlat, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A SkyFrame is returned describing the celestial coordinate system -* described by a FITS header. The axes are *not* permuted in the -* returned Frame (that is, axis 0 is longitude and axis 1 is latitude -* in the returned SkyFrame, no matter what values are supplied for -* "axlat" and "axlon"). - -* Parameters: -* this -* The FitsChan from which the keywords were read. Warning messages -* may be added to this FitsChan. -* store -* A structure containing values for FITS keywords relating to -* the World Coordinate System. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* prj -* An integer code for the WCS projection being used. -* sys -* A pointer to a string identifying the celestial co-ordinate system -* implied by the CTYPE values in the FitsStore. This will be "EQU" (for -* equatorial), or a one or two character code extracted from the -* CTYPE values. -* axlon -* Zero based index of the longitude axis in the FITS header. -* axlat -* Zero based index of the latitude axis in the FITS header. -* method -* The calling method. Used only in error messages. -* class -* The object class. Used only in error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the SkyFrame. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or -* if this function should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *ret; /* Returned Frame */ - char *ckeyval; /* Pointer to string item value */ - char *lattype; /* Pointer to latitude CTYPE value */ - char *lontype; /* Pointer to longitude CTYPE value */ - char bj; /* Besselian/Julian selector */ - char buf[300]; /* Text buffer */ - char sym[10]; /* Axis symbol */ - double dval; /* Floating point attribute value */ - double eqmjd; /* MJD equivalent of equinox */ - double equinox; /* EQUINOX value */ - double geolat; /* Observer's geodetic latitude */ - double geolon; /* Observer's geodetic longitude */ - double h; /* Observer's geodetic height */ - double mjdobs; /* MJD-OBS value */ - double obsgeo[ 3 ]; /* Observer's Cartesian position */ - int radesys; /* RADESYS value */ - int report; /* Report unknown lon/lat system? */ - -/* Initialise. */ - ret = NULL; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Get the RADESYS keyword from the header, and identify the value. - Store a integer value identifying the system. Report an error if an - unrecognised system is supplied. Store NORADEC if the keyword was - not supplied. */ - ckeyval = GetItemC( &(store->radesys), 0, 0, s, NULL, method, class, status ); - radesys = NORADEC; - if( ckeyval ){ - if( !strncmp( ckeyval, "FK4 ", 4 ) || - !strcmp( ckeyval, "FK4" ) ){ - radesys = FK4; - } else if( !strncmp( ckeyval, "FK4-NO-E", 8 ) ){ - radesys = FK4NOE; - } else if( !strncmp( ckeyval, "FK5 ", 4 ) || - !strcmp( ckeyval, "FK5" ) ){ - radesys = FK5; - } else if( !strncmp( ckeyval, "ICRS ", 5 ) || - !strcmp( ckeyval, "ICRS" ) ){ - radesys = ICRS; - } else if( !strncmp( ckeyval, "GAPPT ", 6 ) || - !strcmp( ckeyval, "GAPPT" ) ){ - radesys = GAPPT; - } else if( astOK ){ - astError( AST__BDFTS, "%s(%s): FITS keyword '%s' has the " - "unrecognised value '%s'.", status, method, class, - FormatKey( "RADESYS", -1, -1, s, status ), ckeyval ); - } - } else { - radesys = NORADEC; - } - -/* Get the value of the EQUINOX keyword. */ - equinox = GetItem( &(store->equinox), 0, 0, s, NULL, method, class, status ); - -/* For FK4 and FK4-NO-E any supplied equinox value is Besselian. For all - other systems, the equinox value is Julian. */ - bj = 0; - if( equinox != AST__BAD ){ - if( radesys == FK4 || radesys == FK4NOE ){ - bj = 'B'; - } else if( radesys != NORADEC ) { - bj = 'J'; - -/* If no RADESYS was suppied, but an equinox was, use the IAU 1984 rule - to determine the default RADESYS and equinox type. */ - } else { - if( equinox < 1984.0 ){ - radesys = FK4; - bj = 'B'; - } else { - radesys = FK5; - bj = 'J'; - } - -/* If an equatorial system is being used, give a warning that a default RADESYS - value is being used. */ - if( !strcmp( sys, "EQU" ) ){ - sprintf( buf, "The original FITS header did not specify the " - "RA/DEC reference frame. A default value of %s was " - "assumed.", ( radesys == FK4 ) ? "FK4" : "FK5" ); - Warn( this, "noradesys", buf, method, class, status ); - } - } - -/* If no equinox was supplied, use a default equinox value depending - on the frame of reference. For FK4-based systems, use B1950. */ - } else { - if( radesys == FK4 || radesys == FK4NOE ){ - equinox = 1950.0; - bj = 'B'; - -/* For FK5-based systems, use J2000. */ - } else if( radesys == FK5 ){ - equinox = 2000.0; - bj = 'J'; - -/* If no RADESYS or EQUINOX was supplied, assume either FK4 B1950 or ICRS - - as decided by attribute DefB1950 (GAPPT and ICRS do not use EQUINOX). */ - } else if( radesys == NORADEC ) { - if( astGetDefB1950( this ) ) { - equinox = 1950.0; - bj = 'B'; - radesys = FK4; - } else { - radesys = ICRS; - } - if( !strcmp( sys, "EQU" ) ){ - sprintf( buf, "The original FITS header did not specify the " - "RA/DEC reference frame. A default value of %s was " - "assumed.", ( radesys == FK4 ) ? "FK4" : "ICRS" ); - Warn( this, "noradesys", buf, method, class, status ); - } - } - -/* If we have an equatorial or ecliptic system, issue a warning that a default - equinox has been adopted. */ - if( ( !strcmp( sys, "EQU" ) && radesys != ICRS && radesys != GAPPT ) || - !strcmp( sys, "ECL" ) ){ - sprintf( buf, "The original FITS header did not specify the " - "reference equinox. A default value of %c%.8g was " - "assumed.", bj, equinox ); - Warn( this, "noequinox", buf, method, class, status ); - } - } - -/* Convert the equinox to a Modified Julian Date. */ - if( equinox != AST__BAD ) { - if( bj == 'B' ) { - eqmjd = palEpb2d( equinox ); - } else { - eqmjd = palEpj2d( equinox ); - } - } else { - eqmjd = AST__BAD; - } - -/* Get a value for the Epoch attribute. If no value is available, use - EQUINOX and issue a warning. */ - mjdobs = ChooseEpoch( this, store, s, method, class, status ); - if( mjdobs == AST__BAD ) { - mjdobs = eqmjd; - if( mjdobs != AST__BAD ) { - sprintf( buf, "The original FITS header did not specify the " - "date of observation. A default value of %c%.8g was " - "assumed.", bj, equinox ); - Warn( this, "nomjd-obs", buf, method, class, status ); - } - } - -/* Create a SkyFrame for the specified system. */ - if( !strcmp( sys, "E" ) ){ - ret = astSkyFrame( "System=Ecliptic", status ); - } else if( !strcmp( sys, "H" ) ){ - ret = astSkyFrame( "System=Helioecliptic", status ); - } else if( !(strcmp( sys, "G" ) ) ){ - ret = astSkyFrame( "System=Galactic", status ); - } else if( !(strcmp( sys, "S" ) ) ){ - ret = astSkyFrame( "System=Supergalactic", status ); - } else if( !(strcmp( sys, "AZL" ) ) ){ - ret = astSkyFrame( "System=AzEl", status ); - } else if( !(strcmp( sys, "EQU" ) ) ){ - -/* For equatorial systems, the specific system is given by the RADESYS - value. */ - if( radesys == FK4 ){ - ret = astSkyFrame( "System=FK4", status ); - } else if( radesys == FK4NOE ){ - ret = astSkyFrame( "System=FK4-NO-E", status ); - } else if( radesys == FK5 ){ - ret = astSkyFrame( "System=FK5", status ); - } else if( radesys == ICRS ){ - ret = astSkyFrame( "System=ICRS", status ); - } else if( radesys == GAPPT ){ - ret = astSkyFrame( "System=GAPPT", status ); - } else if( astOK ){ - astError( AST__INTER, "%s(%s): Internal AST programming " - "error - FITS equatorial coordinate system type %d " - "not yet supported in WcsSkyFrame.", status, method, class, radesys ); - } - -/* If an unknown celestial co-ordinate system was specified by the CTYPE - keywords, add warning messages to the FitsChan and treat the axes as - a general spherical coordinate system. */ - } else if( astOK ){ - report = 1; - ret = astSkyFrame( "System=UNKNOWN", status ); - strcpy( sym, sys ); - if( strlen( sys ) == 1 ) { - strcpy( sym + 1, "LON" ); - astSetSymbol( ret, 0, sym ); - strcpy( sym + 1, "LAT" ); - astSetSymbol( ret, 1, sym ); - } else { - strcpy( sym + 2, "LN" ); - astSetSymbol( ret, 0, sym ); - strcpy( sym + 2, "LT" ); - astSetSymbol( ret, 1, sym ); - -/* The code "OF" is used by AST to describe offset sky coordinates. Set - the Domain to SKY_OFFSETS in these cases, so that we can identify - these Frames later. */ - if( !strcmp( sys, "OF" ) ) { - astSetDomain( ret, "SKY_OFFSETS" ); - report = 0; - } - } - - if( report ) { - lontype = GetItemC( &(store->ctype), axlon, 0, s, NULL, method, class, status ); - lattype = GetItemC( &(store->ctype), axlat, 0, s, NULL, method, class, status ); - if( lontype && lattype ){ - sprintf( buf, "This FITS header contains references to an unknown " - "spherical co-ordinate system specified in the values " - "%s and %s. It may not be possible to convert to " - "other standard co-ordinate systems.", lontype, lattype ); - Warn( this, "badcel", buf, method, class, status ); - } - } - } - -/* If a skyFrame was created... */ - if( ret ){ - -/* Store the projection description. */ - if( prj != AST__WCSBAD ) astSetProjection( ret, astWcsPrjDesc( prj ) ); - -/* Store the epoch of the observation in the SkyFrame. */ - if( mjdobs != AST__BAD ) astSetEpoch( ret, mjdobs ); - -/* For equatorial and ecliptic systems, store the epoch of the reference - equinox in the SkyFrame. */ - if( ( !strcmp( sys, "EQU" ) || !strcmp( sys, "ECL" ) ) && - equinox != AST__BAD ) astSetEquinox( ret, eqmjd ); - -/* If either of the CNAME keywords is set, use it as the axis label. */ - ckeyval = GetItemC( &(store->cname), axlon, 0, s, NULL, method, class, status ); - if( ckeyval ) astSetLabel( ret, 0, ckeyval ); - ckeyval = GetItemC( &(store->cname), axlat, 0, s, NULL, method, class, status ); - if( ckeyval ) astSetLabel( ret, 1, ckeyval ); - -/* Observer's position (from primary axis descriptions). Get the OBSGEO-X/Y/Z - keywords, convert to geodetic longitude and latitude and store as the - SpecFrame's ObsLat, ObsLon and ObsAlt attributes. */ - obsgeo[ 0 ] = GetItem( &(store->obsgeox), 0, 0, ' ', NULL, method, class, status ); - obsgeo[ 1 ] = GetItem( &(store->obsgeoy), 0, 0, ' ', NULL, method, class, status ); - obsgeo[ 2 ] = GetItem( &(store->obsgeoz), 0, 0, ' ', NULL, method, class, status ); - if( obsgeo[ 0 ] != AST__BAD && - obsgeo[ 1 ] != AST__BAD && - obsgeo[ 2 ] != AST__BAD ) { - eraGc2gd( 1, obsgeo, &geolon, &geolat, &h ); - astSetObsLat( ret, geolat ); - astSetObsLon( ret, geolon ); - astSetObsAlt( ret, h ); - } - -/* Store values for the reference point in the SkyFrame. */ - dval = GetItem( &(store->skyref), axlon, 0, s, NULL, method, class, status ); - if( dval != AST__BAD ) astSetSkyRef( ret, 0, dval ); - dval = GetItem( &(store->skyref), axlat, 0, s, NULL, method, class, status ); - if( dval != AST__BAD ) astSetSkyRef( ret, 1, dval ); - - dval = GetItem( &(store->skyrefp), axlon, 0, s, NULL, method, class, status ); - if( dval != AST__BAD ) astSetSkyRefP( ret, 0, dval ); - dval = GetItem( &(store->skyrefp), axlat, 0, s, NULL, method, class, status ); - if( dval != AST__BAD ) astSetSkyRefP( ret, 1, dval ); - -/* We cannot store the SkyRefIs value yet since this needs to be done - after the SkyFrame has been added into the FrameSet, so that the Frame - will be remapped to represent the intended offsets. SO instance, mark - the Frame by setting the domain to "SKY_POLE" or "SKY_ORIGIN". This - odd Domain value will be cleared later in TidyOffsets. */ - ckeyval = GetItemC( &(store->skyrefis), 0, 0, s, NULL, method, class, status ); - if( ckeyval ) { - if( !Ustrcmp( "POLE", ckeyval, status ) ) { - astSetDomain( ret, "SKY_POLE" ); - } else if( !Ustrcmp( "ORIGIN", ckeyval, status ) ) { - astSetDomain( ret, "SKY_ORIGIN" ); - } - } - } - -/* If an error has occurred, annul the Frame. */ - if( !astOK ) ret = astAnnul( ret ); - -/* Return the Frame. */ - return ret; -} - -static AstMapping *WcsSpectral( AstFitsChan *this, FitsStore *store, char s, - AstFrame **frm, AstFrame *iwcfrm, double reflon, double reflat, - AstSkyFrame *reffrm, const char *method, - const char *class, int *status ){ - -/* -* Name: -* WcsSpectral - -* Purpose: -* Create a Mapping from intermediate world coords to spectral coords -* as described in a FITS header. - -* Type: -* Private function. - -* Synopsis: - -* AstMapping *WcsSpectral( AstFitsChan *this, FitsStore *store, char s, -* AstFrame **frm, AstFrame *iwcfrm, double reflon, -* double reflat, AstSkyFrame *reffrm, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function interprets the contents of the supplied FitsStore -* structure, looking for world coordinate axes which describe positions -* in a spectrum. If such an axis is found, a Mapping is returned which -* transforms the corresponding intermediate world coordinates to -* spectral world coordinates (this mapping leaves any other axes -* unchanged). It also, modifies the supplied Frame to describe the -* axis (again, other axes are left unchanged). If no spectral axis -* is found, a UnitMap is returned, and the supplied Frame is left -* unchanged. - -* Parameters: -* this -* The FitsChan. -* store -* A structure containing information about the requested axis -* descriptions derived from a FITS header. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* frm -* The address of a location at which to store a pointer to the -* Frame describing the world coordinate axes. -* iwcfrm -* A pointer to the Frame describing the intermediate world coordinate -* axes. The properties of this Frame may be changed on exit. -* reflon -* The reference celestial longitude, in the frame given by reffrm. -* reflat -* The reference celestial latitude, in the frame given by reffrm. -* reffrm -* The SkyFrame defining reflon and reflat. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the Mapping. -*/ - -/* Local Variables: */ - AstFrame *ofrm; /* Pointer to a Frame */ - AstMapping *map1; /* Pointer to Mapping */ - AstMapping *map2; /* Pointer to Mapping */ - AstMapping *ret; /* Pointer to the returned Mapping */ - AstSpecFrame *specfrm; /* Pointer to a SpecFrame */ - char algcode[ 5 ]; /* Displayed spectral type string */ - char stype[ 5 ]; /* Displayed spectral type string */ - const char *cname; /* Pointer to CNAME value */ - const char *ctype; /* Pointer to CTYPE value */ - const char *cunit; /* Pointer to CUNIT value */ - const char *defunit; /* Default unit string */ - const char *specsys; /* Pointer to SPECSYS value */ - const char *ssyssrc; /* Pointer to SSYSSRC value */ - double geolat; /* Observer's geodetic latitude */ - double geolon; /* Observer's geodetic longitude */ - double h; /* Observer's geodetic height */ - double mjd; /* Modified Julian Date */ - double obscentre; /* Spectral value at observation centre */ - double obsgeo[ 3 ]; /* Observer's Cartesian position */ - double restfrq; /* RESTFRQ keyword value */ - double vsource; /* Source velocity */ - int *axes; /* Pointer to axis permutation array */ - int i; /* Axis index */ - int j; /* Loop count */ - int k; /* Loop count */ - int kk; /* Loop count */ - int naxes; /* No. of axes in Frame */ - -/* Initialise the pointer to the returned Mapping. */ - ret = NULL; - -/* Check the global status. */ - if ( !astOK ) return ret; - -/* Get the number of physical axes. */ - naxes = astGetNaxes( *frm ); - -/* An array to hold a list of axis selections. */ - axes = astMalloc( naxes*sizeof( int ) ); - -/* Loop round checking each axis. */ - defunit = NULL; - map1 = NULL; - for( i = 0; i < naxes && astOK; i++ ) { - -/* Get the CTYPE value. Pass on to the next axis if no CTYPE is available. */ - ctype = GetItemC( &(store->ctype), i, 0, s, NULL, method, class, status ); - if( ctype ) { - -/* See if this CTYPE describes a spectral axis, and if so, extract the - system code, the algorithm code and get the default units. */ - defunit = IsSpectral( ctype, stype, algcode, status ); - -/* Skip to the next axis if the system type was not a spectral system - type. */ - if( defunit ) { - -/* Create a SpecFrame or DSBSpecFrame with this system (the FITS type codes - are also legal SpecFrame System values). We use astSetC rather than - astSetSystem because astSetC translates string values into the - corresponding integer system identifiers. */ - if( GetItem( &(store->imagfreq), 0, 0, s, NULL, method, - class, status ) == AST__BAD ) { - specfrm = astSpecFrame( "", status ); - } else { - specfrm = (AstSpecFrame *) astDSBSpecFrame( "", status ); - } - astSetC( specfrm, "System", stype ); - -/* Set the reference position (attributes RefRA and RefDec), if known. */ - if( reffrm ) astSetRefPos( specfrm, reffrm, reflon, reflat ); - -/* Set the SpecFrame units. Use the value of the CUNIT FITS keyword for this - axis if available, otherwise use the default units for the system, noted - above. */ - cunit = GetItemC( &(store->cunit), i, 0, s, NULL, method, class, status ); - if( !cunit ) cunit = defunit; - astSetUnit( specfrm, 0, cunit ); - -/* Set the axis unit in the IWC Frame. */ - astSetUnit( iwcfrm, i, cunit ); - -/* Get a value for the Epoch attribute (the date of observation). */ - mjd = ChooseEpoch( this, store, s, method, class, status ); - if( mjd != AST__BAD ) astSetEpoch( specfrm, mjd ); - -/* Set the rest frequency. Use the RESTFRQ keyword (assumed to be in Hz), - or (if RESTFRQ is not available), RESTWAV (assumes to be in m). */ - restfrq = GetItem( &(store->restfrq), 0, 0, s, NULL, method, class, status ); - if( restfrq == AST__BAD ) { - restfrq = GetItem( &(store->restwav), 0, 0, s, NULL, method, class, status ); - if( restfrq != AST__BAD ) restfrq = AST__C/restfrq; - } - astSetRestFreq( specfrm, restfrq ); - -/* Observer's position (from primary axis descriptions). Get the OBSGEO-X/Y/Z - keywords, convert to geodetic longitude and latitude and store as the - SpecFrame's ObsLat, ObsLon and ObsAlt attributes. */ - obsgeo[ 0 ] = GetItem( &(store->obsgeox), 0, 0, ' ', NULL, method, class, status ); - obsgeo[ 1 ] = GetItem( &(store->obsgeoy), 0, 0, ' ', NULL, method, class, status ); - obsgeo[ 2 ] = GetItem( &(store->obsgeoz), 0, 0, ' ', NULL, method, class, status ); - if( obsgeo[ 0 ] != AST__BAD && - obsgeo[ 1 ] != AST__BAD && - obsgeo[ 2 ] != AST__BAD ) { - eraGc2gd( 1, obsgeo, &geolon, &geolat, &h ); - astSetObsLat( specfrm, geolat ); - astSetObsLon( specfrm, geolon ); - astSetObsAlt( specfrm, h ); - } - -/* Source velocity rest frame */ - ssyssrc = GetItemC( &(store->ssyssrc), 0, 0, s, NULL, method, class, status ); - if( ssyssrc ) astSetC( specfrm, "SourceVRF", ssyssrc ); - -/* Source velocity. Use the ZSOURCE keyword and convert from redshift to - velocity. */ - vsource = GetItem( &(store->zsource), 0, 0, s, NULL, method, class, status ); - if( vsource != AST__BAD ) { - vsource += 1.0; - vsource *= vsource; - vsource = AST__C*( vsource - 1.0 )/( vsource + 1.0 ); - astSetSourceVel( specfrm, vsource ); - } - -/* Reference frame. If the SPECSYS keyword is set, use it (the FITS codes - are also legal SpecFrame StdOfRest values). We use astSetC rather than - astSetSystem because astSetC translates string values into the - corresponding integer system identifiers. */ - specsys = GetItemC( &(store->specsys), 0, 0, s, NULL, method, class, status ); - if( specsys ) astSetC( specfrm, "StdOfRest", specsys ); - -/* Axis label. If the CNAME keyword is set, use it as the axis label. */ - cname = GetItemC( &(store->cname), i, 0, s, NULL, method, class, status ); - if( cname ) astSetLabel( specfrm, 0, cname ); - -/* If the header contains an AXREF value for the spectral axis, use it as the - observation centre in preferences to the CRVAL value. AXREF keywords are - created by the astWrite method for axes described by -TAB algorithm that - have no inverse transformation. */ - obscentre = GetItem( &(store->axref), i, 0, s, NULL, method, - class, status ); - if( obscentre == AST__BAD ) { - obscentre = GetItem( &(store->crval), i, 0, s, NULL, method, - class, status ); - } - -/* Now do the extra stuff needed if we are creating a dual sideband - SpecFrame. */ - if( astIsADSBSpecFrame( specfrm ) ) { - DSBSetUp( this, store, (AstDSBSpecFrame *) specfrm, s, - obscentre, method, class, status ); - } - -/* Now branch for each type of algorithm code. Each case returns a 1D - Mapping which converts IWC value into the specified Spectral system. */ - -/* Linear */ - if( strlen( algcode ) == 0 ) { - map1 = LinearWcs( store, i, s, method, class, status ); - -/* Log-Linear */ - } else if( !strcmp( "-LOG", algcode ) ) { - map1 = LogWcs( store, i, s, method, class, status ); - -/* Non-Linear */ - } else if( algcode[ 0 ] == '-' && algcode[ 2 ] == '2' ) { - map1 = NonLinSpecWcs( this, algcode, store, i, s, specfrm, method, class, status ); - -/* Grism */ - } else if( !strcmp( "-GRI", algcode ) || - !strcmp( "-GRA", algcode ) ) { - map1 = GrismSpecWcs( algcode, store, i, s, specfrm, method, class, status ); - } else { - map1 = NULL; - } - if( map1 == NULL && astOK ) { - specfrm = astAnnul( specfrm ); - astError( AST__BDFTS, "%s(%s): Cannot implement spectral " - "algorithm code '%s' specified in FITS keyword '%s'.", status, - method, class, ctype + 4, FormatKey( "CTYPE", i + 1, -1, s, status ) ); - astError( AST__BDFTS, "%s(%s): Unknown algorithm code or " - "unusable parameter values.", status, method, class ); - break; - } - -/* Create a Frame by picking all the other (non-spectral) axes from the - supplied Frame. */ - j = 0; - for( k = 0; k < naxes; k++ ) { - if( k != i ) axes[ j++ ] = k; - } - -/* If there were no other axes, replace the supplied Frame with the - specframe. */ - if( j == 0 ) { - (void) astAnnul( *frm ); - *frm = (AstFrame *) specfrm; - -/* Otherwise pick the other axes from the supplied Frame */ - } else { - ofrm = astPickAxes( *frm, j, axes, NULL ); - -/* Replace the supplied Frame with a CmpFrame made up of this Frame and - the SpecFrame. */ - (void) astAnnul( *frm ); - *frm = (AstFrame *) astCmpFrame( ofrm, specfrm, "", status ); - ofrm = astAnnul( ofrm ); - specfrm = astAnnul( specfrm ); - } - -/* Permute the axis order to put the spectral axis back in its original - position. */ - j = 0; - for( kk = 0; kk < naxes; kk++ ) { - if( kk == i ) { - axes[ kk ] = naxes - 1; - } else { - axes[ kk ] = j++; - } - } - astPermAxes( *frm, axes ); - } - } - -/* If this axis is not a spectral axis, create a UnitMap (the Frame is left - unchanged). */ - if( !map1 && astOK ) map1 = (AstMapping *) astUnitMap( 1, "", status ); - -/* Add the Mapping for this axis in parallel with the Mappings for - previous axes. */ - if( ret ) { - map2 = (AstMapping *) astCmpMap( ret, map1, 0, "", status ); - ret = astAnnul( ret ); - map1 = astAnnul( map1 ); - ret = map2; - } else { - ret = map1; - map1 = NULL; - } - } - -/* Free the axes array. */ - axes= astFree( axes ); - -/* Return the result. */ - return ret; -} - -static void WcsToStore( AstFitsChan *this, AstFitsChan *trans, - FitsStore *store, const char *method, - const char *class, int *status ){ - -/* -* Name: -* WcsToStore - -* Purpose: -* Extract WCS information from the supplied FitsChan using a FITSWCS -* encoding, and store it in the supplied FitsStore. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* void WcsToStore( AstFitsChan *this, AstFitsChan *trans, -* FitsStore *store, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* A FitsStore is a structure containing a generalised represention of -* a FITS WCS FrameSet. Functions exist to convert a FitsStore to and -* from a set of FITS header cards (using a specified encoding), or -* an AST FrameSet. In other words, a FitsStore is an encoding- -* independant intermediary staging post between a FITS header and -* an AST FrameSet. -* -* This function extracts FITSWCS keywords from the supplied FitsChan(s), -* and stores the corresponding WCS information in the supplied FitsStore. -* Keywords will be searched for first in "trans", and then, if they -* are not found in "trans", they will be searched for in "this". - -* Parameters: -* this -* Pointer to the FitsChan containing the cards read from the -* original FITS header. This may include non-standard keywords. -* trans -* Pointer to a FitsChan containing cards representing standard -* translations of any non-standard keywords in "this". A NULL -* pointer indicates that "this" contains no non-standard keywords. -* store -* Pointer to the FitsStore structure. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Read all usable cards out of the main FitsChan, into the FitsStore. */ - WcsFcRead( this, trans, store, method, class, status ); - -/* If a FitsChan containing standard translations was supplied, read all - cards out of it, into the FitsStore, potentially over-writing the - non-standard values stored in the previous call to WcsFcRead. */ - if( trans ) WcsFcRead( trans, NULL, store, method, class, status ); -} - -static int WorldAxes( AstFitsChan *this, AstMapping *cmap, double *dim, int *perm, - int *status ){ - -/* -* Name: -* WorldAxes - -* Purpose: -* Associate final world axes with pixel axes. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" - -* int WorldAxes( AstFitsChan *this, AstMapping *cmap, double *dim, int *perm, -* int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function finds the association between the axes of the final -* world coordinate system, and those of the pixel coordinate -* system. This may not simply be a 1-to-1 association because the -* Mapping may include a PermMap. Each output axis is associated with -* the input axis which is most nearly aligned with it. - -* Parameters: -* this -* Pointer to the FitsChan. -* cmap -* Pointer to the Mapping from pixel coordinates to final world -* coordinates. -* dim -* Pointer to an array with one element for each input of "map", -* supplied holding the no. of pixels in the data cube along the axis, or -* AST__BAD If unknown. -* perm -* Pointer to an array with one element for each output of "map". -* On exit, each element of this array holds the zero-based index of the -* "corresponding" (i.e. most nearly parallel) pixel axis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero for success - zero for failure. -*/ - -/* Local Variables: */ - AstMapping *smap; - AstMapping *map; - AstPointSet *pset1; - AstPointSet *pset2; - double **ptr2; - double **ptr1; - double *dw; - double *g0; - double *nwt; - double *ntn; - double *tn; - double *wt; - double *w0; - double dg; - double s; - double sj; - double tnmin; - double wtmax; - int *outs; - int i2; - int i; - int imin; - int j2; - int j; - int jmin; - int nin; - int nout; - int nouts; - int nused; - int ret; - int retain; - int used; - -/* Initialise returned value */ - ret = 0; - -/* Other initialisation to avoid compiler warnings. */ - retain = 0; - -/* Check the status */ - if( !astOK ) return ret; - -/* Simplfy the Mapping. */ - map = astSimplify( cmap ); - -/* Get the number of inputs and outputs for the Mapping. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - -/* Initialise "perm". */ - for( i = 0; i < nout; i++ ) perm[ i ] = i; - -/* First deal with Mappings that are defined in both directions. */ - if( astGetTranForward( map ) && astGetTranInverse( map ) ) { - -/* Use FindBasisVectors to find an input position which coresponds to a - good output position. Store it in a dynamic array pointed to by "g0". */ - pset1 = astPointSet( nin+1, nin, "", status ); - pset2 = astPointSet( nin+1, nout, "", status ); - if( FindBasisVectors( map, nin, nout, dim, pset1, pset2, status ) ) { - g0 = astMalloc( sizeof(double)*nin ); - ptr1 = astGetPoints( pset1 ); - if( astOK ) { - for( j = 0; j < nin; j++ ) g0[ j ] = ptr1[ j ][ 0 ]; - } - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* If no basis vectors found, return. */ - } else { - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - return ret; - } - -/* Create Pointset to hold two input (pixel) points. */ - pset1 = astPointSet( 2, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - -/* Create a Pointset to hold the same number of output (world) points. */ - pset2 = astPointSet( 2, nout, "", status ); - ptr2 = astGetPoints( pset2 ); - -/* Allocate memory to use as work space */ - w0 = astMalloc( sizeof(double)*nout ); - dw = astMalloc( sizeof(double)*nout ); - tn = astMalloc( sizeof(double)*nout*nin ); - wt = astMalloc( sizeof(double)*nout*nin ); - -/* Check that the pointers can be used. */ - if( astOK ) { - -/* Transform the grid position found above, plus a position 1 pixel away - along all pixel axes, into world coords. Also set up "dw" to hold - "a small increment" along each world axis. */ - for( j = 0; j < nin; j++ ) { - ptr1[ j ] [ 0 ] = g0[ j ]; - ptr1[ j ] [ 1 ] = g0[ j ] + 1.0; - } - (void) astTransform( map, pset1, 1, pset2 ); - for( i = 0; i < nout; i++ ) { - w0[ i ] = ptr2[ i ] [ 0 ]; - if( w0[ i ] != AST__BAD && ptr2[ i ] [ 1 ] != AST__BAD ) { - dw[ i ] = fabs( 0.1*( ptr2[ i ] [ 1 ] - w0[ i ] ) ); - if( dw[ i ] <= fabs( 0.001*w0[ i ] ) ) { - if( w0[ i ] != 0.0 ) { - dw[ i ] = fabs( 0.001*w0[ i ] ); - } else { - dw[ i ] = 1.0; - } - } - } else { - dw[ i ] = AST__BAD; - } - } - -/* Any PermMap in the mapping may result in the the "inverse transformation" - not being a true inverse of the forward transformation (for instance, - constant values fed in for degenerate axis would have this effect). To - ensure that "g0" and "w0" are corresponding positions, transform the - "w0" position back into grid coords and use the resulting grid position - as "g0". */ - (void) astTransform( map, pset2, 0, pset1 ); - for( j = 0; j < nin; j++ ) { - g0[ j ] = ptr1[ j ] [ 0 ]; - } - -/* In the next loop we find the tan of the angle between each WCS axis and - each of the pixel axes. Loop round each WCS axis. */ - for( i = 0; i < nout; i++ ) { - -/* Initialise the tan values for this WCS axis to AST__BAD. */ - ntn = tn + i*nin; - nwt = wt + i*nin; - for( j = 0; j < nin; j++ ) ntn[ j ] = AST__BAD; - -/* As a side issue, initialise the pixel axis assigned to each WCS axis - to -1, to indicate that no grid axis has yet been associated with this - WCS axis. */ - perm[ i ] = -1; - -/* Skip over this axis if the increment is bad. */ - if( dw[ i ] != AST__BAD ) { - -/* Store a WCS position which is offset from the "w0" position by a small - amount along the current WCS axis. The first position in "ptr2" is - currently "w0". */ - ptr2[ i ][ 0 ] += dw[ i ]; - -/* Transform this position into grid coords. */ - (void) astTransform( map, pset2, 0, pset1 ); - -/* Re-instate the original "w0" values within "ptr2", ready for the next - WCS axis. */ - ptr2[ i ][ 0 ] = w0[ i ]; - -/* Consider each pixel axis in turn as a candidate for being assigned to - the current WCS axis. */ - for( j = 0; j < nin; j++ ) { - -/* Find the tan of the angle between the current ("i"th) WCS axis and the - current ("j"th) pixel axis. This gets stored in tn[j+nin*i]. A - corresponding weight for each angle is stored in nwt[j+nin*i]. This - is the length of the projection of the vector onto the "j"th pixel - axis. */ - s = 0.0; - sj = 0.0; - for( j2 = 0; j2 < nin; j2++ ) { - if( ptr1[ j2 ][ 0 ] != AST__BAD ) { - dg = ptr1[ j2 ][ 0 ] - g0[ j2 ]; - if( j2 != j ) { - s += dg*dg; - } else { - sj = fabs( dg ); - } - } else { - s = AST__BAD; - break; - } - } - if( s != AST__BAD && sj != 0.0 ) { - ntn[ j ] = sqrt( s )/sj; - nwt[ j ] = sj; - } - } - } - } - -/* Loop until every grid axes has been assigned to a WCS axis. */ - while( 1 ) { - -/* Pass through the array of tan values, finding the smallest. Note the - pixel and WCS axis for which the smallest tan value occurs. If the tan - values are equal, favour the one with highest weight. */ - ntn = tn; - nwt = wt; - tnmin = AST__BAD; - wtmax = AST__BAD; - imin = 0; - jmin = 0; - for( i = 0; i < nout; i++ ) { - for( j = 0; j < nin; j++ ) { - if( *ntn != AST__BAD ) { - if( tnmin == AST__BAD || *ntn < tnmin ) { - tnmin = *ntn; - wtmax = *nwt; - imin = i; - jmin = j; - } else if( astEQUAL( *ntn, tnmin ) && *nwt > wtmax ) { - wtmax = *nwt; - imin = i; - jmin = j; - } - } - ntn++; - nwt++; - } - } - -/* Check we found a usable minimum tan value */ - if( tnmin != AST__BAD ) { - -/* Assign the pixel axis to the WCS axis. */ - perm[ imin ] = jmin; - -/* Set bad all the tan values for this pixel and WCS axis pair. This ensures - that the pixel axis will not be assigned to another WCS axis, and that - the WCS will not have another pixel axis assigned to it. */ - ntn = tn; - for( i = 0; i < nout; i++ ) { - for( j = 0; j < nin; j++ ) { - if( i == imin || j == jmin ) *ntn = AST__BAD; - ntn++; - } - } - -/* Leave the loop if no more good tan values were found. */ - } else { - break; - } - } - -/* The above process may have left some WCS axes with out any assigned - pixel axis. We assign the remaining pixel arbitrarily to such axes, - starting with the first remaining pixel axis. Find the lowest unused - pixel axis. */ - for( j = 0; j < nin; j++ ) { - used = 0; - for( i = 0; i < nout; i++ ) { - if( perm[ i ] == j ) { - used = 1; - break; - } - } - if( !used ) break; - } - -/* Now check each WCS axis looking for outputs which were not assigned a - pixel axis in the above process. */ - for( i = 0; i < nout; i++ ) { - if( perm[ i ] == -1 ) { - -/* Use the next unused axis value. */ - perm[ i ] = j++; - -/* Find the next unused axis value. */ - for( ; j < nin; j++ ) { - used = 0; - for( i2 = 0; i2 < nout; i2++ ) { - if( perm[ i2 ] == j ) { - used = 1; - break; - } - } - if( !used ) break; - } - } - } - -/* Indicate success. */ - if( astOK ) ret = 1; - } - -/* Free resources. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - g0 = astFree( g0 ); - w0 = astFree( w0 ); - tn = astFree( tn ); - wt = astFree( wt ); - dw = astFree( dw ); - -/* Now, if we can use the TAB algorithm, deal with Mappings that are defined only in the forward direction. */ - } else if( astGetTranForward( map ) && astGetTabOK( this ) > 0 ) { - -/* Assume success. */ - ret = 1; - -/* Initialise to indicate no outputs have yet been assigned. */ - for( i = 0; i < nout; i++ ) perm[ i ] = -1; - -/* Find the output associated with each input. */ - for( j = 0; j < nin; j++ ) { - -/* Attempt to split off the current input. */ - outs = astMapSplit( map, 1, &j, &smap ); - -/* If successfull, store the index of the corresponding input for each - output. */ - if( outs && smap ) { - nouts = astGetNout( smap ); - for( i = 0; i < nouts; i++ ) { - if( perm[ outs[ i ] ] == -1 ) { - perm[ outs[ i ] ] = j; - } else { - ret = 0; - } - } - } - -/* Free resources. */ - outs = astFree( outs ); - if( smap ) smap = astAnnul( smap ); - } - -/* Check all outputs were assigned . */ - for( i = 0; i < nout && ret; i++ ) { - if( perm[ i ] == -1 ) ret = 0; - } - -/* If succesful, attempt to remove any duplicates from the "perm" array - (i.e. inputs that supply more than one output). First get a list of - the inputs that are currently unused (i.e. do not appear in "perm"). */ - if( ret ) { - -/* Check each input. */ - for( j = 0; j < nin; j++ ) { - -/* See how many outputs are fed by this input. */ - nused = 0; - for( i = 0; i < nout; i++ ) { - if( perm[ i ] == j ) nused++; - } - -/* If it used more than once, we need to remove all but one of the - occurrences. */ - if( nused > 1 ) { - -/* Choose the occurrence to retain. If the output with the same index as - the input is one of them, use it. Otherwise, use the first occurrence. */ - if( perm[ j ] == j ) { - retain = j; - } else { - for( i = 0; i < nout; i++ ) { - if( perm[ i ] == j ) { - retain = i; - break; - } - } - } - -/* Loop round all occurrences of this input again. */ - for( i = 0; i < nout && ret; i++ ) { - if( perm[ i ] == j ) { - -/* Replace all occurrences, except for the one being retained. */ - if( i != retain ) { - -/* Replace it with the next unused input. */ - for( j2 = 0; j2 < nin; j2++ ) { - used = 0; - for( i2 = 0; i2 < nout; i2++ ) { - if( perm[ i2 ] == j2 ) { - used = 1; - break; - } - } - if( ! used ) { - perm[ i ] = j2; - break; - } - } - -/* If there were no unused inputs, we cannot do it. */ - if( used ) ret = 0; - } - } - } - } - } - } - } - -/* Free resources. */ - map = astAnnul( map ); - -/* Return the result. */ - return ret; -} - -static int Write( AstChannel *this_channel, AstObject *object, int *status ) { -/* -* Name: -* Write - -* Purpose: -* Write an Object to a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* int Write( AstChannel *this, AstObject *object, int *status ) - -* Class Membership: -* FitsChan member function (over-rides the astWrite method -* inherited from the Channel class). - -* Description: -* This function writes an Object to a FitsChan. - -* Parameters: -* this -* Pointer to the FitsChan. -* object -* Pointer to the Object which is to be written. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of Objects written to the FitsChan by this invocation of -* astWrite. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the AST error status set, or if it should fail for any -* reason. -* - The Base Frame in the FrameSet is used as the pixel Frame, and -* the Current Frame is used to create the primary axis descriptions. -* Attempts are made to create secondary axis descriptions for any -* other Frames in the FrameSet (up to a total of 26). -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - FitsStore *store; /* Intermediate storage for WCS information */ - char banner[ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN + 1 ]; /* Buffer for begin/end banner */ - const char *class; /* Pointer to string holding object class */ - const char *method; /* Pointer to string holding calling method */ - double *dim; /* Pointer to array of axis dimensions */ - int card0; /* Index of original current card */ - int comm; /* Value of Comm attribute */ - int encoding; /* FITS encoding scheme to use */ - int i; /* Axis index */ - int naxis; /* No. of pixel axes */ - int ret; /* Number of objects read */ - -/* Initialise. */ - ret = 0; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_channel); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* Store the calling method, and object class. */ - method = "astWrite"; - class = astGetClass( this ); - -/* The original current card is re-instated at the end if no object - is written. Save its index. */ - card0 = astGetCard( this ); - -/* Indicate that all cards added to the FitsCHan by this call should be - marked as "new". */ - mark_new = 1; - -/* Get the encoding scheme used by the FitsChan. */ - encoding = astGetEncoding( this ); - -/* First deal with cases where we are writing to a FitsChan in which AST - objects are encoded using native AST-specific keywords... */ - if( encoding == NATIVE_ENCODING ){ - -/* Increment the nesting level which keeps track of recursive - invocations of this function. */ - write_nest++; - -/* Initialise the current indentation level for top-level objects. */ - if ( !write_nest ) current_indent = 0; - -/* Obtain the value of the Comm attribute. */ - comm = astGetComment( this ); - -/* If this is the top-level invocation (i.e. we are about to write out - a new top-level Object), then prefix it with a blank FITS line and - an appropriate banner of FITS comments, unless comments have been - suppressed. */ - if ( !write_nest && comm ) { - astSetFitsCom( this, " ", "", 0 ); - MakeBanner( -"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", - "", "", banner, status ); - astSetFitsCom( this, "COMMENT", banner, 0 ); - if( astIsAFrameSet( object ) ) { - MakeBanner( "WCS information in AST format", "", "", banner, status ); - astSetFitsCom( this, "COMMENT", banner, 0 ); - MakeBanner( "See http://www.starlink.ac.uk/ast/", "", "", banner, status ); - astSetFitsCom( this, "COMMENT", banner, 0 ); - } - MakeBanner( HEADER_TEXT, astGetClass( object ), " object", banner, status ); - astSetFitsCom( this, "COMMENT", banner, 0 ); - MakeBanner( -"................................................................", - "", "", banner, status ); - astSetFitsCom( this, "COMMENT", banner, 0 ); - } - -/* Invoke the parent astWrite method to write out the Object data. */ - (*parent_write)( this_channel, object, status ); - -/* Append a banner of FITS comments to the object data, as above, if - necessary. */ - if ( !write_nest && comm ) { - MakeBanner( -"................................................................", - "", "", banner, status ); - astSetFitsCom( this, "COMMENT", banner, 0 ); - MakeBanner( FOOTER_TEXT, astGetClass( object ), " object", banner, status ); - astSetFitsCom( this, "COMMENT", banner, 0 ); - MakeBanner( -"----------------------------------------------------------------", - "", "", banner, status ); - astSetFitsCom( this, "COMMENT", banner, 0 ); - } - -/* Return the nesting level to its previous value. */ - write_nest--; - -/* Indicate that an object has been written. */ - ret = 1; - -/* Now deal with cases where we are writing to a FitsChan in which AST - objects are encoded using any of the supported foreign encodings... */ - } else { - -/* Only proceed if the supplied object is a FrameSet. */ - if( astIsAFrameSet( object ) ){ - -/* Note the number of pixel (i.e. Base Frame) axes, and allocate memory to - hold the image dimensions. */ - naxis = astGetNin( (AstFrameSet *) object ); - dim = (double *) astMalloc( sizeof(double)*naxis ); - if( dim ){ - -/* Note the image dimensions, if known. If not, store AST__BAD values. */ - for( i = 0; i < naxis; i++ ){ - if( !astGetFitsF( this, FormatKey( "NAXIS", i + 1, -1, ' ', status ), - dim + i ) ) dim[ i ] = AST__BAD; - } - -/* Extract the required information from the FrameSet into a standard - intermediary structure called a FitsStore. The indices of any - celestial axes are returned. */ - store = FsetToStore( this, (AstFrameSet *) object, naxis, dim, - encoding, method, class, status ); - -/* If the FrameSet cannot be described in terms of any of the supported - FITS encodings, a null pointer will have been returned. */ - if( store ){ - -/* Now put header cards describing the contents of the FitsStore into the - supplied FitsChan, using the requested encoding. Zero or one is - returned depending on whether the information could be encoded. */ - ret = FitsFromStore( this, store, encoding, dim, - (AstFrameSet *) object, method, class, status ); - -/* Release the resources used by the FitsStore. */ - store = FreeStore( store, status ); - -/* If the Object was written to the FitsChan, set the current card to - end-of-file. */ - if( ret ) astSetCard( this, INT_MAX ); - } - -/* Free workspace holding image dimensions */ - dim = (double *) astFree( (void *) dim ); - } - } - } - -/* If an error has occurred, return zero and remove any new cards added - to the FitsCHan by this call. */ - if( !astOK ) ret = 0; - -/* Clear the new flag associated with cards which have been added to the - FitsChan as a result of this function. If the object was not added - succesfully to the FitsChan, remove any cards which were added before - the error was discovered. */ - FixNew( this, NEW1, !ret, method, class, status ); - FixNew( this, NEW2, !ret, method, class, status ); - -/* Indicate that all cards added to the FitsChan from now on should not be - marked as "new". */ - mark_new = 0; - -/* If no object was written, re-instate the original current card. */ - if( !ret ) astSetCard( this, card0 ); - -/* Return the answer. */ - return ret; -} - -static void WriteBegin( AstChannel *this_channel, const char *class, - const char *comment, int *status ) { -/* -* Name: -* WriteBegin - -* Purpose: -* Write a "Begin" data item to a data sink. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void WriteBegin( AstChannel *this, const char *class, -* const char *comment ) - -* Class Membership: -* FitsChan member function (over-rides the protected astWriteBegin -* method inherited from the Channel class). - -* Description: -* This function writes a "Begin" data item to the data sink -* associated with a FitsChan, so as to begin the output of a new -* Object definition. - -* Parameters: -* this -* Pointer to the FitsChan. -* class -* Pointer to a constant null-terminated string containing the -* name of the class to which the Object belongs. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the "Begin" -* item. Normally, this will describe the purpose of the Object. - -* Notes: -* - The comment supplied may not actually be used, depending on -* the nature of the FitsChan supplied. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFitsChan *this; /* Pointer to the FitsChan structure. */ - char buff[ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN + 1 ]; - /* Character buffer */ - char keyword[ FITSNAMLEN + 1 ]; /* Buffer for FITS keyword */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_channel); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Increment the indentation level for comments. */ - current_indent += INDENT_INC; - -/* If we are not beginning a top-level Object definition, and helpful - information has not been suppressed, generate an indented comment - to mark the "Begin" item and write it to the FitsChan as a comment - card with a blank keyword. */ - if ( write_nest && ( astGetFull( this ) >= 0 ) ) { - MakeIndentedComment( current_indent, '+', "Beginning of ", class, buff, status ); - astSetFitsCom( this, " ", buff, 0 ); - } - -/* Create a unique FITS keyword for this "Begin" item, basing it on - "BEGAST". */ - CreateKeyword( this, "BEGAST", keyword, status ); - -/* Generate a pre-quoted version of the class name. */ - PreQuote( class, buff, status ); - -/* Write the "Begin" item to the FitsChan as a keyword and string - value. */ - astSetFitsS( this, keyword, buff, - astGetComment( this ) ? comment : NULL, 0 ); - -/* Clear the count of items written. */ - items_written = 0; -} - -static void WriteDouble( AstChannel *this_channel, const char *name, - int set, int helpful, - double value, const char *comment, int *status ) { -/* -* Name: -* WriteDouble - -* Purpose: -* Write a double value to a data sink. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void WriteDouble( AstChannel *this, const char *name, -* int set, int helpful, -* double value, const char *comment ) - -* Class Membership: -* FitsChan member function (over-rides the protected -* astWriteDouble method inherited from the Channel class). - -* Description: -* This function writes a named double value, representing the -* value of a class instance variable, to the data sink associated -* with a FitsChan. It is intended for use by class "Dump" -* functions when writing out class information which will -* subsequently be re-read. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* Pointer to a constant null-terminated string containing the -* name to be used to identify the value in the external -* representation. This will form the key for identifying it -* again when it is re-read. The name supplied should be unique -* within its class. -* -* Mixed case may be used and will be preserved in the external -* representation (where possible) for cosmetic effect. However, -* case is not significant when re-reading values. -* -* It is recommended that a maximum of 6 alphanumeric characters -* (starting with an alphabetic character) be used. This permits -* maximum flexibility in adapting to standard external data -* representations (e.g. FITS). -* set -* If this is zero, it indicates that the value being written is -* a default value (or can be re-generated from other values) so -* need not necessarily be written out. Such values will -* typically be included in the external representation with -* (e.g.) a comment character so that they are available to -* human readers but will be ignored when re-read. They may also -* be completely omitted in some circumstances. -* -* If "set" is non-zero, the value will always be explicitly -* included in the external representation so that it can be -* re-read. -* helpful -* This flag provides a hint about whether a value whose "set" -* flag is zero (above) should actually appear at all in the -* external representaton. -* -* If the external representation allows values to be "commented -* out" then, by default, values will be included in this form -* only if their "helpful" flag is non-zero. Otherwise, they -* will be omitted entirely. When possible, omitting the more -* obscure values associated with a class is recommended in -* order to improve readability. -* -* This default behaviour may be further modified if the -* FitsChan's Full attribute is set - either to permit all -* values to be shown, or to suppress non-essential information -* entirely. -* value -* The value to be written. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the value. -* -* Note that this comment may not actually be used, depending on -* the nature of the FitsChan supplied and the setting of its -* Comm attribute. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFitsChan *this; /* Pointer to the FitsChan structure. */ - char keyword[ FITSNAMLEN + 1 ]; /* Buffer for FITS keyword */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_channel); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Use the "set" and "helpful" flags, along with the FitsChan's - attributes to decide whether this value should actually be - written. */ - if ( Use( this, set, helpful, status ) ) { - -/* Create a unique FITS keyword from the name supplied. */ - CreateKeyword( this, name, keyword, status ); - -/* Write the value to the FitsChan as a keyword and value */ - astSetFitsF( this, keyword, value, - astGetComment( this ) ? comment : NULL, 0 ); - -/* If the value is not "set", replace the card just written by a COMMENT - card containing the text of the card as the comment. */ - if( !set ) MakeIntoComment( this, "astWrite", astGetClass( this ), status ); - -/* Increment the count of items written. */ - items_written++; - } -} - -static void WriteEnd( AstChannel *this_channel, const char *class, int *status ) { -/* -* Name: -* WriteEnd - -* Purpose: -* Write an "End" data item to a data sink. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void WriteEnd( AstChannel *this, const char *class ) - -* Class Membership: -* FitsChan member function (over-rides the protected astWriteEnd -* method inherited from the Channel class). - -* Description: -* This function writes an "End" data item to the data sink -* associated with a FitsChan. This item delimits the end of an -* Object definition. - -* Parameters: -* this -* Pointer to the FitsChan. -* class -* Pointer to a constant null-terminated string containing the -* class name of the Object whose definition is being terminated -* by the "End" item. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFitsChan *this; /* Pointer to the FitsChan structure. */ - char buff[ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN + 1 ]; - /* Character buffer */ - char keyword[ FITSNAMLEN + 1 ]; /* Buffer for FITS keyword */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_channel); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Create a unique FITS keyword for this "End" item, basing it on - "ENDAST". */ - CreateKeyword( this, "ENDAST", keyword, status ); - -/* Generate a pre-quoted version of the class name. */ - PreQuote( class, buff, status ); - -/* Write the "End" item to the FitsChan as a keyword and string - value. */ - astSetFitsS( this, keyword, buff, - astGetComment( this ) ? "End of object definition" : NULL, - 0 ); - -/* If we are not ending a top-level Object definition, and helpful - information has not been suppressed, generate an indented comment - to mark the "End" item and write it to the FitsChan as a comment - card with a blank keyword. */ - if ( write_nest && ( astGetFull( this ) >= 0 ) ) { - MakeIndentedComment( current_indent, '-', "End of ", class, buff, status ); - astSetFitsCom( this, " ", buff, 0 ); - } - -/* Decrement the indentation level for comments. */ - current_indent -= INDENT_INC; -} - -static void WriteFits( AstFitsChan *this, int *status ){ - -/* -*++ -* Name: -c astWriteFits -f AST_WRITEFITS - -* Purpose: -* Write out all cards in a FitsChan to the sink function. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "fitschan.h" -c void astWriteFits( AstFitsChan *this ) -f CALL AST_WRITEFITS( THIS, STATUS ) - -* Class Membership: -* FitsChan method. - -* Description: -c This function -f This routine -* writes out all cards currently in the FitsChan. If the SinkFile -* attribute is set, they will be written out to the specified sink file. -* Otherwise, they will be written out using the sink function specified -* when the FitsChan was created. All cards are then deleted from the -* FitsChan. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsChan. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the SinkFile is unset, and no sink function is available, this -* method simply empties the FitsChan, and is then equivalent to -c astEmptyFits. -f AST_EMPTYFITS. -* - This method attempt to execute even if an error has occurred -* previously. -*-- -*/ - -/* Ensure a FitsChan was supplied. */ - if( this ) { - -/* Ensure the source function has been called */ - ReadFromSource( this, status ); - -/* We can usefully use the local destructor function to do the work, - since it only frees resources used within teh FitsChan, rather than - freeing the FitsChan itself. */ - Delete( (AstObject *) this, status ); - } -} - -static void WriteInt( AstChannel *this_channel, const char *name, - int set, int helpful, - int value, const char *comment, int *status ) { -/* -* Name: -* WriteInt - -* Purpose: -* Write an int value to a data sink. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void WriteInt( AstChannel *this, const char *name, -* int set, int helpful, -* int value, const char *comment ) - -* Class Membership: -* FitsChan member function (over-rides the protected -* astWriteInt method inherited from the Channel class). - -* Description: -* This function writes a named int value, representing the -* value of a class instance variable, to the data sink associated -* with a FitsChan. It is intended for use by class "Dump" -* functions when writing out class information which will -* subsequently be re-read. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* Pointer to a constant null-terminated string containing the -* name to be used to identify the value in the external -* representation. This will form the key for identifying it -* again when it is re-read. The name supplied should be unique -* within its class. -* -* Mixed case may be used and will be preserved in the external -* representation (where possible) for cosmetic effect. However, -* case is not significant when re-reading values. -* -* It is recommended that a maximum of 6 alphanumeric characters -* (starting with an alphabetic character) be used. This permits -* maximum flexibility in adapting to standard external data -* representations (e.g. FITS). -* set -* If this is zero, it indicates that the value being written is -* a default value (or can be re-generated from other values) so -* need not necessarily be written out. Such values will -* typically be included in the external representation with -* (e.g.) a comment character so that they are available to -* human readers but will be ignored when re-read. They may also -* be completely omitted in some circumstances. -* -* If "set" is non-zero, the value will always be explicitly -* included in the external representation so that it can be -* re-read. -* helpful -* This flag provides a hint about whether a value whose "set" -* flag is zero (above) should actually appear at all in the -* external representaton. -* -* If the external representation allows values to be "commented -* out" then, by default, values will be included in this form -* only if their "helpful" flag is non-zero. Otherwise, they -* will be omitted entirely. When possible, omitting the more -* obscure values associated with a class is recommended in -* order to improve readability. -* -* This default behaviour may be further modified if the -* FitsChan's Full attribute is set - either to permit all -* values to be shown, or to suppress non-essential information -* entirely. -* value -* The value to be written. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the value. -* -* Note that this comment may not actually be used, depending on -* the nature of the FitsChan supplied and the setting of its -* Comm attribute. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFitsChan *this; /* Pointer to the FitsChan structure. */ - char keyword[ FITSNAMLEN + 1 ]; /* Buffer for FITS keyword */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_channel); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Use the "set" and "helpful" flags, along with the FitsChan's - attributes to decide whether this value should actually be - written. */ - if ( Use( this, set, helpful, status ) ) { - -/* Create a unique FITS keyword from the name supplied. */ - CreateKeyword( this, name, keyword, status ); - -/* Write the value to the FitsChan as a keyword and value */ - astSetFitsI( this, keyword, value, - astGetComment( this ) ? comment : NULL, 0 ); - -/* If the value is not "set", replace the card just written by a COMMENT - card containing the text of the card as the comment. */ - if( !set ) MakeIntoComment( this, "astWrite", astGetClass( this ), status ); - -/* Increment the count of items written. */ - items_written++; - } -} - -static void WriteIsA( AstChannel *this_channel, const char *class, - const char *comment, int *status ) { -/* -* Name: -* WriteIsA - -* Purpose: -* Write an "IsA" data item to a data sink. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void WriteIsA( AstChannel *this, const char *class, -* const char *comment ) - -* Class Membership: -* FitsChan member function (over-rides the protected astWriteIsA -* method inherited from the Channel class). - -* Description: -* This function writes an "IsA" data item to the data sink -* associated with a FitsChan. This item delimits the end of the -* data associated with the instance variables of a class, as part -* of an overall Object definition. - -* Parameters: -* this -* Pointer to the FitsChan. -* class -* Pointer to a constant null-terminated string containing the -* name of the class whose data are terminated by the "IsA" -* item. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the "IsA" -* item. Normally, this will describe the purpose of the class -* whose data are being terminated. - -* Notes: -* - The comment supplied may not actually be used, depending on -* the nature of the FitsChan supplied. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFitsChan *this; /* Pointer to the FitsChan structure. */ - char buff[ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN + 1 ]; - /* Character buffer */ - char keyword[ FITSNAMLEN + 1 ]; /* Buffer for FITS keyword */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_channel); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Output an "IsA" item only if there has been at least one item - written since the last "Begin" or "IsA" item, or if the Full - attribute for the Channel is greater than zero (requesting maximum - information). */ - if ( items_written || astGetFull( this ) > 0 ) { - -/* Create a unique FITS keyword for this "IsA" item, basing it on - "ISA". */ - CreateKeyword( this, "ISA", keyword, status ); - -/* Generate a pre-quoted version of the class name. */ - PreQuote( class, buff, status ); - -/* Write the "IsA" item to the FitsChan as a keyword and string - value. */ - astSetFitsS( this, keyword, buff, - astGetComment( this ) ? comment : NULL, 0 ); - -/* If helpful information has not been suppressed, generate an - indented comment to mark the "IsA" item and write it to the - FitsChan as a comment card with a blank keyword. */ - if ( astGetFull( this ) >= 0 ) { - MakeIndentedComment( current_indent, '.', "Class boundary", "", - buff, status ); - astSetFitsCom( this, " ", buff, 0 ); - } - } - -/* Clear the count of items written. */ - items_written = 0; -} - -static void WriteObject( AstChannel *this_channel, const char *name, - int set, int helpful, - AstObject *value, const char *comment, int *status ) { -/* -* Name: -* WriteObject - -* Purpose: -* Write an Object value to a data sink. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void WriteObject( AstChannel *this, const char *name, -* int set, int helpful, -* AstObject *value, const char *comment ) - -* Class Membership: -* FitsChan member function (over-rides the protected -* astWriteObject method inherited from the Channel class). - -* Description: -* This function writes a named Object value, representing the -* value of a class instance variable, to the data sink associated -* with a FitsChan. It is intended for use by class "Dump" -* functions when writing out class information which will -* subsequently be re-read. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* Pointer to a constant null-terminated string containing the -* name to be used to identify the value in the external -* representation. This will form the key for identifying it -* again when it is re-read. The name supplied should be unique -* within its class. -* -* Mixed case may be used and will be preserved in the external -* representation (where possible) for cosmetic effect. However, -* case is not significant when re-reading values. -* -* It is recommended that a maximum of 6 alphanumeric characters -* (starting with an alphabetic character) be used. This permits -* maximum flexibility in adapting to standard external data -* representations (e.g. FITS). -* set -* If this is zero, it indicates that the value being written is -* a default value (or can be re-generated from other values) so -* need not necessarily be written out. Such values will -* typically be included in the external representation with -* (e.g.) a comment character so that they are available to -* human readers but will be ignored when re-read. They may also -* be completely omitted in some circumstances. -* -* If "set" is non-zero, the value will always be explicitly -* included in the external representation so that it can be -* re-read. -* helpful -* This flag provides a hint about whether a value whose "set" -* flag is zero (above) should actually appear at all in the -* external representaton. -* -* If the external representation allows values to be "commented -* out" then, by default, values will be included in this form -* only if their "helpful" flag is non-zero. Otherwise, they -* will be omitted entirely. When possible, omitting the more -* obscure values associated with a class is recommended in -* order to improve readability. -* -* This default behaviour may be further modified if the -* FitsChan's Full attribute is set - either to permit all -* values to be shown, or to suppress non-essential information -* entirely. -* value -* A pointer to the Object to be written. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the value. -* -* Note that this comment may not actually be used, depending on -* the nature of the FitsChan supplied and the setting of its -* Comm attribute. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFitsChan *this; /* Pointer to the FitsChan structure. */ - char keyword[ FITSNAMLEN + 1 ]; /* Buffer for FITS keyword */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_channel); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Use the "set" and "helpful" flags, along with the FitsChan's - attributes to decide whether this value should actually be - written. */ - if ( Use( this, set, helpful, status ) ) { - -/* Create a unique FITS keyword from the name supplied. */ - CreateKeyword( this, name, keyword, status ); - -/* Write the value to the FitsChan as a keyword and a blank string value, - not pre-quoted (this "null" value indicates that an Object description - follows). */ - astSetFitsS( this, keyword, "", - astGetComment( this ) ? comment : NULL, 0 ); - -/* If the value is "set", write out the Object description. */ - if ( set ) { - astWrite( this, value ); - -/* If the value is not set, replace the card just written to the FitsChan - by COMENT card containing the keyword and blank string value (do not - write out the Object description). */ - } else { - MakeIntoComment( this, "astWrite", astGetClass( this ), status ); - } - -/* Increment the count of items written. */ - items_written++; - } -} - -static void WriteToSink( AstFitsChan *this, int *status ){ -/* -* Name: -* WriteToSink - -* Purpose: -* Write the contents of the FitsChan out to the sink file or function. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void WriteToSink( AstFitsChan *this, int *status ) - -* Class Membership: -* FitsChan member function. - -* Description: -* If the SinkFile attribute is set, each card in the FitsChan is -* written out to the sink file. Otherwise, the cards are passed in -* turn to the sink function specified when the FitsChan was created. -* If no sink function was provided, the cards are not written out. -* Cards marked as having been read into an AST object are not written -* out. - -* Parameters: -* this -* Pointer to the FitsChan. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The current card is left unchanged. -*/ - -/* Local Constants: */ -#define ERRBUF_LEN 80 - -/* Local Variables: */ - FILE *fd; /* File descriptor for sink file */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *errstat; /* Pointer for system error message */ - char card[ AST__FITSCHAN_FITSCARDLEN + 1]; /* Buffer for header card */ - char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */ - const char *sink_file; /* Path to output sink file */ - int icard; /* Current card index on entry */ - int old_ignore_used; /* Original value of external variable ignore_used */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* If the SinkFile attribute is set, open the file. */ - fd = NULL; - if( astTestSinkFile( this ) ) { - sink_file = astGetSinkFile( this ); - fd = fopen( sink_file, "w" ); - if( !fd ) { - if ( errno ) { -#if HAVE_STRERROR_R - strerror_r( errno, errbuf, ERRBUF_LEN ); - errstat = errbuf; -#else - errstat = strerror( errno ); -#endif - astError( AST__WRERR, "astDelete(%s): Failed to open output " - "SinkFile '%s' - %s.", status, astGetClass( this ), - sink_file, errstat ); - } else { - astError( AST__WRERR, "astDelete(%s): Failed to open output " - "SinkFile '%s'.", status, astGetClass( this ), - sink_file ); - } - } - } - -/* Only proceed if a file was opened, or sink function and wrapper were supplied. */ - if( fd || ( this->sink && this->sink_wrap ) ){ - -/* Store the current card index. */ - icard = astGetCard( this ); - -/* Indicate that cards which have been read into an AST object should skipped - over by the functions which navigate the linked list of cards. */ - old_ignore_used = ignore_used; - ignore_used = 1; - -/* Ensure that the first card in the FitsChan will be the next one to be - read. */ - astSetCard( this, 1 ); - -/* Loop round obtaining and writing out each card, until all cards have been - processed. */ - while( !astFitsEof( this ) && astOK ){ - -/* Get the current card, and write it out through the sink function. - The call to astFindFits increments the current card. */ - if( astFindFits( this, "%f", card, 1 ) ) { - -/* If s sink file was opened, write the card out to it. */ - if( fd ) { - fprintf( fd, "%s\n", card ); - -/* Otherwise, use the isnk function. The sink function is an externally - supplied function which may not be thread-safe, so lock a mutex first. - Also store the channel data pointer in a global variable so that it can - be accessed in the sink function using macro astChannelData. */ - } else { - astStoreChannelData( this ); - LOCK_MUTEX3; - ( *this->sink_wrap )( *this->sink, card, status ); - UNLOCK_MUTEX3; - } - } - } - -/* Re-instate the original flag indicating if cards marked as having been - read should be skipped over. */ - ignore_used = old_ignore_used; - -/* Set the current card index back to what it was on entry. */ - astSetCard( this, icard ); - } - -/* Close the sink file. */ - if( fd ) fclose( fd ); -} - -static void WriteString( AstChannel *this_channel, const char *name, - int set, int helpful, - const char *value, const char *comment, int *status ) { -/* -* Name: -* WriteString - -* Purpose: -* Write a string value to a data sink. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* void WriteString( AstChannel *this, const char *name, -* int set, int helpful, -* const char *value, const char *comment ) - -* Class Membership: -* FitsChan member function (over-rides the protected -* astWriteString method inherited from the Channel class). - -* Description: -* This function writes a named string value, representing the -* value of a class instance variable, to the data sink associated -* with a FitsChan. It is intended for use by class "Dump" -* functions when writing out class information which will -* subsequently be re-read. - -* Parameters: -* this -* Pointer to the FitsChan. -* name -* Pointer to a constant null-terminated string containing the -* name to be used to identify the value in the external -* representation. This will form the key for identifying it -* again when it is re-read. The name supplied should be unique -* within its class. -* -* Mixed case may be used and will be preserved in the external -* representation (where possible) for cosmetic effect. However, -* case is not significant when re-reading values. -* -* It is recommended that a maximum of 6 alphanumeric characters -* (starting with an alphabetic character) be used. This permits -* maximum flexibility in adapting to standard external data -* representations (e.g. FITS). -* set -* If this is zero, it indicates that the value being written is -* a default value (or can be re-generated from other values) so -* need not necessarily be written out. Such values will -* typically be included in the external representation with -* (e.g.) a comment character so that they are available to -* human readers but will be ignored when re-read. They may also -* be completely omitted in some circumstances. -* -* If "set" is non-zero, the value will always be explicitly -* included in the external representation so that it can be -* re-read. -* helpful -* This flag provides a hint about whether a value whose "set" -* flag is zero (above) should actually appear at all in the -* external representaton. -* -* If the external representation allows values to be "commented -* out" then, by default, values will be included in this form -* only if their "helpful" flag is non-zero. Otherwise, they -* will be omitted entirely. When possible, omitting the more -* obscure values associated with a class is recommended in -* order to improve readability. -* -* This default behaviour may be further modified if the -* FitsChan's Full attribute is set - either to permit all -* values to be shown, or to suppress non-essential information -* entirely. -* value -* Pointer to a constant null-terminated string containing the -* value to be written. -* comment -* Pointer to a constant null-terminated string containing a -* textual comment to be associated with the value. -* -* Note that this comment may not actually be used, depending on -* the nature of the FitsChan supplied and the setting of its -* Comm attribute. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFitsChan *this; /* Pointer to the FitsChan structure. */ - char *c; /* Pointer to next buffer character */ - char buff1[ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN - 3 ]; /* Buffer for a single substring */ - char buff2[ AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN - 3 ]; /* Buffer for pre-quoted string */ - char cc; /* Next character */ - char keyword[ FITSNAMLEN + 1 ]; /* Buffer for FITS keyword */ - const char *start; /* Pointer to start of substring */ - int first; /* Is this the first sub-string? */ - int nc; /* No. of available columns remaining */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_channel); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_channel; - -/* Use the "set" and "helpful" flags, along with the FitsChan's - attributes to decide whether this value should actually be - written. */ - if ( Use( this, set, helpful, status ) ) { - -/* Create a unique FITS keyword from the name supplied. */ - CreateKeyword( this, name, keyword, status ); - -/* Store a pointer to the start of the next sub-string (i.e. the - beggining of the string), and then loop round until the end of the - string is reached. */ - start = value; - first = 1; - while( *start && astOK ){ - -/* Store the number of characters available in the 80 column header card - for the next substring, leaving room for the "= " string at the start, - and the delimiting quotes. Also reserve 2 characters to allow for the - possibility of double quotes being needed to protect trailing white space - (see function PreQuote). */ - nc = AST__FITSCHAN_FITSCARDLEN - FITSNAMLEN - 6; - -/* If this is the first sub-string reserve room for any comment. */ - if( first ){ - if( comment && comment[0] ) nc -= ChrLen( comment, status ) + 3; - -/* If the first card will be turned into a comment card, we need to leave room - for the keyword name and equals sign, etc, within the 80 columns. */ - if( !set ) nc -= FITSNAMLEN + 5; - } - -/* We need to check the sub-string for single quotes since these will - take up 2 characters each instead of 1 when encoded since single quotes - within a string are doubled. Search through from the starting - character, copying the sub-string into a buffer, and reducing the number - of available characters remaining in the card for each character. */ - c = buff1; - while( *start && nc > 0 ){ - cc = *(start++); - *(c++) = cc; - if( cc == '\'' ) { - nc -= 2; - } else { - nc -= 1; - } - } - -/* If the last character in the substring was a single quote, there may - not have been room for the extra quote which is added when the - sub-string is encoded. In this case we need to back up a character in - order to remove the single quote frin this substring and move it into - the next sub-string. */ - if( nc < 0 ){ - start--; - c--; - } - -/* If the supplied value has not been exhausted, append an ampersand to - the string. In this case we need to move the last character in the - substring into the next substring to make room for the ampersand. */ - if( *start ) { - start--; - c--; - *(c++) = '&'; - } - -/* Terminate the buffer. */ - *c = 0; - -/* The FITS standard considers trailing white space is be insignificant, - and so we need to guard against external applications throwing away - significant trailing white space. This is done by encosing the string, - including trailing white space, in double quotes. */ - PreQuote( buff1, buff2, status ); - -/* On the first pass through this loop, write the value to the FitsChan as - a keyword and value */ - if( first ){ - astSetFitsS( this, keyword, buff2, - astGetComment( this ) ? comment : NULL, 0 ); - -/* If the value is not "set", replace the card just written by a COMMENT - card containing the text of the card as the comment. */ - if( !set ) MakeIntoComment( this, "astWrite", astGetClass( this ), status ); - -/* On subsequent passes through the loop, store the string using a CONTINUE - keyword, with type AST__CONTINUE (this type is like AST__STRING but is - formatted without an equals sign). */ - } else { - astSetFitsCN( this, "CONTINUE", buff2, NULL, 0 ); - } - first = 0; - } - -/* Increment the count of items written. */ - items_written++; - } -} - -static AstMapping *ZPXMapping( AstFitsChan *this, FitsStore *store, char s, - int naxes, int zpxaxes[2], const char *method, - const char *class, int *status ){ -/* -* Name: -* ZPXMapping - -* Purpose: -* Create a Mapping descriping "-ZPX" (IRAF) distortion. - -* Type: -* Private function. - -* Synopsis: -* AstMapping *ZPXMapping( AstFitsChan *this, FitsStore *store, char s, -* int naxes, int zpxaxes[2], const char *method, -* const char *class, int *status ) - -* Class Membership: -* FitsChan - -* Description: -* This function uses the values in the supplied FitsStore to create a -* Mapping which implements the "-ZPX" distortion code, produced by -* the IRAF project. See: -* -* http://iraf.noao.edu/projects/ccdmosaic/zpx.html -* -* Note, the Mapping created by this function implements the "lngcor" -* and "latcor" corrections described in the WAT... keywords. The -* basic ZPN projection code is handled in the normal way, as any -* other projection is handled. - -* Parameters: -* store -* A structure containing information about the requested axis -* descriptions derived from a FITS header. -* s -* A character identifying the co-ordinate version to use. A space -* means use primary axis descriptions. Otherwise, it must be an -* upper-case alphabetical characters ('A' to 'Z'). -* naxes -* The number of intermediate world coordinate axes (WCSAXES). -* zpxaxes -* The zero-based indices of the two IWC axes that use the ZPX projection. -* method -* A pointer to a string holding the name of the calling method. -* This is used only in the construction of error messages. -* class -* A pointer to a string holding the class of the object being -* read. This is used only in the construction of error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the Mapping. -*/ - -/* Local Variables: */ - AstMapping *ret; - char *watstr; - double *cvals[ 2 ]; - int *mvals[ 2 ]; - int ncoeff[ 2 ]; - int i; - int icoeff; - int ok; - -/* Initialise the pointer to the returned Mapping. */ - ret = NULL; - -/* Check the global status. */ - if ( !astOK ) return ret; - -/* Check both axes */ - for( i = 0; i < 2; i++ ){ - mvals[ i ] = NULL; - cvals[ i ] = NULL; - ncoeff[ i ] = 0; - -/* Concatenate all the IRAF "WAT" keywords together for this axis. These - keywords are marked as having been used, so that they are not written - out when the FitsChan is deleted. */ - watstr = ConcatWAT( this, zpxaxes[ i ], method, class, status ); - -/* Extract the polynomial coefficients from the concatenated WAT string. - These are returned in the form of a list of PVi_m values for a TPN - projection. */ - ncoeff[ i ] = WATCoeffs( watstr, i, cvals + i, mvals + i, &ok, status ); - -/* If the current axis of the ZPX projection uses features not supported - by AST, do not do any more axes. */ - if( !ok ) break; - -/* Free the WAT string. */ - watstr = astFree( watstr ); - } - -/* If we can handle the ZPX projection, store the polynomial coefficients in - a new inverted TPN WcsMap. This WcsMap is used as a correction to the ZPN - WcsMap to be created later, therefore set its FITSProj value to zero so - that it is not used as the FITS projection when written out via - astWrite. Also set TPNTan to zero to indicate that the TAN part of the - TPN projection should not be used (i.e. just use the polynomial part). */ - if( ok && astOK ) { - - if( ncoeff[ 0 ] || ncoeff[ 1 ] ) { - ret = (AstMapping *) astWcsMap( naxes, AST__TPN, zpxaxes[ 0 ] + 1, - zpxaxes[ 1 ] + 1, "Invert=1", - status ); - astSetFITSProj( ret, 0 ); - astSetTPNTan( ret, 0 ); - for( i = 0; i < 2; i++ ){ - for( icoeff = 0; icoeff < ncoeff[ i ]; icoeff++ ) { - astSetPV( ret, zpxaxes[ i ], (mvals[ i ])[ icoeff ], - (cvals[ i ])[ icoeff ] ); - } - } - - } else { - ret = (AstMapping *) astUnitMap( naxes, " ", status ); - } - -/* If the TNX cannot be represented in FITS-WCS (within our restrictions), add - warning keywords to the FitsChan. */ - } else { - Warn( this, "zpx", "This FITS header includes, or was " - "derived from, a ZPX projection which requires " - "unsupported IRAF-specific corrections. The WCS " - "information may therefore be incorrect.", method, class, - status ); - } - -/* Return the result. */ - return ret; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ - -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* FitsTol - -* Purpose: -* Maximum non-linearity allowed when exporting to FITS-WCS. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute is used when attempting to write a FrameSet to a -* FitsChan using a foreign encoding. It specifies the maximum -* departure from linearity allowed on any axis within the mapping -* from pixel coordinates to Intermediate World Coordinates. It is -* expressed in units of pixels. If an axis of the Mapping is found -* to deviate from linearity by more than this amount, the write -* operation fails. If the linearity test succeeds, a linear -* approximation to the mapping is used to determine the FITS keyword -* values to be placed in the FitsChan. -* -* The default value is one tenth of a pixel. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,FitsTol,fitstol,-1.0) -astMAKE_GET(FitsChan,FitsTol,double,1,(this->fitstol==-1.0?0.1:this->fitstol)) -astMAKE_SET(FitsChan,FitsTol,double,fitstol,(astMAX(value,0.0))) -astMAKE_TEST(FitsChan,FitsTol,(this->fitstol!=-1.0)) - -/* -*att++ -* Name: -* Card - -* Purpose: -* Index of current FITS card in a FitsChan. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute gives the index of the "current" FITS header card -* within a FitsChan, the first card having an index of 1. The -c choice of current card affects the behaviour of functions that -f choice of current card affects the behaviour of routines that -c access the contents of the FitsChan, such as astDelFits, -c astFindFits and astPutFits. -f access the contents of the FitsChan, such as AST_DELFITS, -f AST_FINDFITS and AST_PUTFITS. -* -* A value assigned to Card will position the FitsChan at any -* desired point, so that a particular card within it can be -* accessed. Alternatively, the value of Card may be enquired in -* order to determine the current position of a FitsChan. -* -* The default value of Card is 1. This means that clearing -c this attribute (using astClear) effectively "rewinds" the -f this attribute (using AST_CLEAR) effectively "rewinds" the -* FitsChan, so that the first card is accessed next. If Card is -* set to a value which exceeds the total number of cards in the -* FitsChan (as given by its Ncard attribute), it is regarded as -* pointing at the "end-of-file". In this case, the value returned -* in response to an enquiry is always one more than the number of -* cards in the FitsChan. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ - -/* Encoding. */ -/* ========= */ - -/* -*att++ -* Name: -* Encoding - -* Purpose: -* System for encoding Objects as FITS headers. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies the encoding system to use when AST -* Objects are stored as FITS header cards in a FitsChan. It -c affects the behaviour of the astWrite and astRead functions when -f affects the behaviour of the AST_WRITE and AST_READ routines when -* they are used to transfer any AST Object to or from an external -* representation consisting of FITS header cards (i.e. whenever a -* write or read operation is performed using a FitsChan as the I/O -* Channel). -* -* There are several ways (conventions) by which coordinate system -* information may be represented in the form of FITS headers and -* the Encoding attribute is used to specify which of these should -* be used. The encoding options available are outlined in the -* "Encodings Available" section below, and in more detail in the -* sections which follow. -* -* Encoding systems differ in the range of possible Objects -* (e.g. classes) they can represent, in the restrictions they -* place on these Objects (e.g. compatibility with some -* externally-defined coordinate system model) and in the number of -* Objects that can be stored together in any particular set of -* FITS header cards (e.g. multiple Objects, or only a single -* Object). The choice of encoding also affects the range of -* external applications which can potentially read and interpret -* the FITS header cards produced. -* -* The encoding options available are not necessarily mutually -* exclusive, and it may sometimes be possible to store multiple -* Objects (or the same Object several times) using different -* encodings within the same set of FITS header cards. This -* possibility increases the likelihood of other applications being -* able to read and interpret the information. -* -* By default, a FitsChan will attempt to determine which encoding -* system is already in use, and will set the default Encoding -* value accordingly (so that subsequent I/O operations adopt the -* same conventions). It does this by looking for certain critical -* FITS keywords which only occur in particular encodings. For -* details of how this works, see the "Choice of Default Encoding" -* section below. If you wish to ensure that a particular encoding -* system is used, independently of any FITS cards already present, -* you should set an explicit Encoding value yourself. - -* Encodings Available: -* The Encoding attribute can take any of the following (case -* insensitive) string values to select the corresponding encoding - -* system: -* -* - "DSS": Encodes coordinate system information in FITS header -* cards using the convention developed at the Space Telescope -* Science Institute (STScI) for the Digitised Sky Survey (DSS) -* astrometric plate calibrations. The main advantages of this -* encoding are that FITS images which use it are widely available -* and it is understood by a number of important and -* well-established astronomy applications. For further details, -* see the section "The DSS Encoding" below. -* -* - "FITS-WCS": Encodes coordinate system information in FITS -* header cards using the conventions described in the FITS -* world coordinate system (FITS-WCS) papers by E.W. Greisen, -* M. Calabretta, et al. The main advantages of this encoding are that -* it should be understood by any FITS-WCS compliant application and -* is likely to be adopted widely for FITS data in future. For further -* details, see the section "The FITS-WCS Encoding" below. -* -* - "FITS-PC": Encodes coordinate system information in FITS -* header cards using the conventions described in an earlier draft -* of the FITS world coordinate system papers by E.W. Greisen and -* M. Calabretta. This encoding uses a combination of CDELTi and -* PCiiijjj keywords to describe the scale and rotation of the pixel -* axes. This encoding is included to support existing data and -* software which uses these now superceded conventions. In general, -* the "FITS-WCS" encoding (which uses CDi_j or PCi_j keywords to -* describe the scale and rotation) should be used in preference to -* "FITS-PC". -* -* - "FITS-IRAF": Encodes coordinate system information in FITS -* header cards using the conventions described in the document -* "World Coordinate Systems Representations Within the FITS -* Format" by R.J. Hanisch and D.G. Wells, 1988. This encoding is -* currently employed by the IRAF data analysis facility, so its -* use will facilitate data exchange with IRAF. Its main advantages -* are that it is a stable convention which approximates to a -* subset of the propsed FITS-WCS encoding (above). This makes it -* suitable as an interim method for storing coordinate system -* information in FITS headers until the FITS-WCS encoding becomes -* stable. Since many datasets currently use the FITS-IRAF -* encoding, conversion of data from FITS-IRAF to the final form of -* FITS-WCS is likely to be well supported. -* -* - "FITS-AIPS": Encodes coordinate system information in FITS -* header cards using the conventions originally introduced by the -* AIPS data analysis facility. This is base on the use of CDELTi and -* CROTAi keuwords to desribe the scale and rotation of each axis. -* These conventions have been superceded but are still widely used. -* -* - "FITS-AIPS++": Encodes coordinate system information in FITS -* header cards using the conventions used by the AIPS++ project. -* This is an extension of FITS-AIPS which includes some of the -* features of FITS-IRAF and FITS-PC. -* -* - "FITS-CLASS": Encodes coordinate system information in FITS -* header cards using the conventions used by the CLASS project. -* CLASS is a software package for reducing single-dish radio and -* sub-mm spectroscopic data. See the section "CLASS FITS format" at -* http://www.iram.fr/IRAMFR/GILDAS/doc/html/class-html/. -* -* - "NATIVE": Encodes AST Objects in FITS header cards using a -* convention which is private to the AST library (but adheres to -* the general FITS standard) and which uses FITS keywords that -* will not clash with other encoding systems. The main advantages -* of this are that any class of AST Object may be encoded, and any -* (reasonable) number of Objects may be stored sequentially in the -* same FITS header. This makes FITS headers an almost loss-less -* communication path for passing AST Objects between applications -* (although all such applications must, of course, make use of the -* AST library to interpret the information). For further details, -* see the section "The NATIVE Encoding" below. - -* Choice of Default Encoding: -* If the Encoding attribute of a FitsChan is not set, the default -* value it takes is determined by the presence of certain critical -* FITS keywords within the FitsChan. The sequence of decisions - -* used to arrive at the default value is as follows: -* -* - If the FitsChan contains any keywords beginning with the -* string "BEGAST", then NATIVE encoding is used, -* - Otherwise, FITS-CLASS is used if the FitsChan contains a DELTAV -* keyword and a keyword of the form VELO-xxx, where xxx indicates one -* of the rest frames used by class (e.g. "VELO-LSR"), or "VLSR". -* - Otherwise, if the FitsChan contains a CTYPE keyword which -* represents a spectral axis using the conventions of the AIPS and -* AIPS++ projects (e.g. "FELO-LSR", etc), then one of FITS-AIPS or -* FITS-AIPS++ encoding is used. FITS-AIPS++ is used if any of the -* keywords CDi_j, PROJP, LONPOLE or LATPOLE are -* found in the FitsChan. Otherwise FITS-AIPS is used. -* - Otherwise, if the FitsChan contains a keyword of the form -* "PCiiijjj", where "i" and "j" are single digits, then -* FITS-PC encoding is used, -* - Otherwise, if the FitsChan contains a keyword of the form -* "CDiiijjj", where "i" and "j" are single digits, then -* FITS-IRAF encoding is used, -* - Otherwise, if the FitsChan contains a keyword of the form -* "CDi_j", and at least one of RADECSYS, PROJPi, or CjVALi -* where "i" and "j" are single digits, then FITS-IRAF encoding is -* used. -* - Otherwise, if the FitsChan contains any keywords of the form -* PROJPi, CjVALi or RADECSYS, where "i" and "j" are single digits, -* then FITS-PC encoding is used. -* - Otherwise, if the FitsChan contains a keyword of the form -* CROTAi, where "i" is a single digit, then FITS-AIPS encoding is -* used. -* - Otherwise, if the FitsChan contains a keyword of the form -* CRVALi, where "i" is a single digit, then FITS-WCS encoding is -* used. -* - Otherwise, if the FitsChan contains the "PLTRAH" keyword, then -* DSS encoding is used, -* - Otherwise, if none of these conditions is met (as would be the -* case when using an empty FitsChan), then NATIVE encoding is -* used. -* -* Except for the NATIVE and DSS encodings, all the above checks -* also require that the header contains at least one CTYPE, CRPIX and -* CRVAL keyword (otherwise the checking process continues to the next -* case). -* -* Setting an explicit value for the Encoding attribute always -* over-rides this default behaviour. -* -* Note that when writing information to a FitsChan, the choice of -* encoding will depend greatly on the type of application you -* expect to be reading the information in future. If you do not -* know this, there may sometimes be an advantage in writing the -* information several times, using a different encoding on each -* occasion. - -* The DSS Encoding: -* The DSS encoding uses FITS header cards to store a multi-term -* polynomial which relates pixel positions on a digitised -* photographic plate to celestial coordinates (right ascension and -* declination). This encoding may only be used to store a single -* AST Object in any set of FITS header cards, and that Object must -* be a FrameSet which conforms to the STScI/DSS coordinate system -* model (this means the Mapping which relates its base and current -* Frames must include either a DssMap or a WcsMap with type -* AST__TAN or AST__TPN). -* -c When reading a DSS encoded Object (using astRead), the FitsChan -f When reading a DSS encoded Object (using AST_READ), the FitsChan -* concerned must initially be positioned at the first card (its -* Card attribute must equal 1) and the result of the read, if -* successful, will always be a pointer to a FrameSet. The base -* Frame of this FrameSet represents DSS pixel coordinates, and the -* current Frame represents DSS celestial coordinates. Such a read -* is always destructive and causes the FITS header cards required -* for the construction of the FrameSet to be removed from the -* FitsChan, which is then left positioned at the "end-of-file". A -* subsequent read using the same encoding will therefore not -* return another FrameSet, even if the FitsChan is rewound. -* -c When astWrite is used to store a FrameSet using DSS encoding, -f When AST_WRITE is used to store a FrameSet using DSS encoding, -* an attempt is first made to simplify the FrameSet to see if it -* conforms to the DSS model. Specifically, the current Frame must -* be a FK5 SkyFrame; the projection must be a tangent plane -* (gnomonic) projection with polynomial corrections conforming to -* DSS requirements, and north must be parallel to the second base -* Frame axis. -* -* If the simplification process succeeds, a description of the -* FrameSet is written to the FitsChan using appropriate DSS FITS -* header cards. The base Frame of the FrameSet is used to form the -* DSS pixel coordinate system and the current Frame gives the DSS -* celestial coordinate system. A successful write operation will -* over-write any existing DSS encoded data in the FitsChan, but -* will not affect other (non-DSS) header cards. If a destructive -* read of a DSS encoded Object has previously occurred, then an -* attempt will be made to store the FITS header cards back in -* their original locations. -* -* If an attempt to simplify a FrameSet to conform to the DSS model -* fails (or if the Object supplied is not a FrameSet), then no -c data will be written to the FitsChan and astWrite will return -f data will be written to the FitsChan and AST_WRITE will return -* zero. No error will result. - -* The FITS-WCS Encoding: -* The FITS-WCS convention uses FITS header cards to describe the -* relationship between pixels in an image (not necessarily -* 2-dimensional) and one or more related "world coordinate systems". -* The FITS-WCS encoding may only be used to store a single AST Object -* in any set of FITS header cards, and that Object must be a FrameSet -* which conforms to the FITS-WCS model (the FrameSet may, however, -* contain multiple Frames which will be result in multiple FITS -* "alternate axis descriptions"). Details of the use made by this -* Encoding of the conventions described in the FITS-WCS papers are -* given in the appendix "FITS-WCS Coverage" of this document. A few -* main points are described below. -* -* The rotation and scaling of the intermediate world coordinate system -* can be specified using either "CDi_j" keywords, or "PCi_j" together -* with "CDELTi" keywords. When writing a FrameSet to a FitsChan, the -* the value of the CDMatrix attribute of the FitsChan determines -* which system is used. -* -* In addition, this encoding supports the "TAN with polynomial correction -* terms" projection which was included in a draft of the FITS-WCS paper, -* but was not present in the final version. A "TAN with polynomial -* correction terms" projection is represented using a WcsMap with type -* AST__TPN (rather than AST__TAN which is used to represent simple -* TAN projections). When reading a FITS header, a CTYPE keyword value -* including a "-TAN" code results in an AST__TPN projection if there are -* any projection parameters (given by the PVi_m keywords) associated with -* the latitude axis, or if there are projection parameters associated -* with the longitude axis for m greater than 4. When writing a -* FrameSet to a FITS header, an AST__TPN projection gives rise to a -* CTYPE value including the normal "-TAN" code, but the projection -* parameters are stored in keywords with names "QVi_m", instead of the -* usual "PVi_m". Since these QV parameters are not part of the -* FITS-WCS standard they will be ignored by other non-AST software, -* resulting in the WCS being interpreted as a simple TAN projection -* without any corrections. This should be seen as an interim solution -* until such time as an agreed method for describing projection -* distortions within FITS-WCS has been published. -* -* AST extends the range of celestial coordinate systems which may be -* described using this encoding by allowing the inclusion of -* "AZ--" and "EL--" as the coordinate specification within CTYPE -* values. These form a longitude/latitude pair of axes which describe -* azimuth and elevation. The geographic position of the observer -* should be supplied using the OBSGEO-X/Y/Z keywords described in FITS-WCS -* paper III. Currently, a simple model is used which includes diurnal -* aberration, but ignores atmospheric refraction, polar motion, etc. -* These may be added in a later release. -* -* If an AST SkyFrame that represents offset rather than absolute -* coordinates (see attribute SkyRefIs) is written to a FitsChan using -* FITS-WCS encoding, two alternate axis descriptions will be created. -* One will describe the offset coordinates, and will use "OFLN" and -* "OFLT" as the axis codes in the CTYPE keywords. The other will -* describe absolute coordinates as specified by the System attribute -* of the SkyFrame, using the usual CTYPE codes ("RA--"/"DEC-", etc). -* In addition, the absolute coordinates description will contain -* AST-specific keywords (SREF1/2, SREFP1/2 and SREFIS) that allow the -* header to be read back into AST in order to reconstruct the original -* SkyFrame. -* -c When reading a FITS-WCS encoded Object (using astRead), the FitsChan -f When reading a FITS-WCS encoded Object (using AST_READ), the FitsChan -* concerned must initially be positioned at the first card (its -* Card attribute must equal 1) and the result of the read, if -* successful, will always be a pointer to a FrameSet. The base -* Frame of this FrameSet represents FITS-WCS pixel coordinates, -* and the current Frame represents the physical coordinate system -* described by the FITS-WCS primary axis descriptions. If -* secondary axis descriptions are also present, then the FrameSet -* may contain additional (non-current) Frames which represent -* these. Such a read is always destructive and causes the FITS -* header cards required for the construction of the FrameSet to be -* removed from the FitsChan, which is then left positioned at the -* "end-of-file". A subsequent read using the same encoding will -* therefore not return another FrameSet, even if the FitsChan is -* rewound. -* -c When astWrite is used to store a FrameSet using FITS-WCS -f When AST_WRITE is used to store a FrameSet using FITS-WCS -* encoding, an attempt is first made to simplify the FrameSet to -* see if it conforms to the FITS-WCS model. If this simplification -* process succeeds (as it often should, as the model is reasonably -* flexible), a description of the FrameSet is written to the -* FitsChan using appropriate FITS header cards. The base Frame of -* the FrameSet is used to form the FITS-WCS pixel coordinate -* system and the current Frame gives the physical coordinate -* system to be described by the FITS-WCS primary axis -* descriptions. Any additional Frames in the FrameSet may be used -* to construct secondary axis descriptions, where appropriate. -* -* A successful write operation will over-write any existing -* FITS-WCS encoded data in the FitsChan, but will not affect other -* (non-FITS-WCS) header cards. If a destructive read of a FITS-WCS -* encoded Object has previously occurred, then an attempt will be -* made to store the FITS header cards back in their original -* locations. Otherwise, the new cards will be inserted following -* any other FITS-WCS related header cards present or, failing -* that, in front of the current card (as given by the Card -* attribute). -* -* If an attempt to simplify a FrameSet to conform to the FITS-WCS -* model fails (or if the Object supplied is not a FrameSet), then -c no data will be written to the FitsChan and astWrite will -f no data will be written to the FitsChan and AST_WRITE will -* return zero. No error will result. - -* The FITS-IRAF Encoding: -* The FITS-IRAF encoding can, for most purposes, be considered as -* a subset of the FITS-WCS encoding (above), although it differs -* in the details of the FITS keywords used. It is used in exactly -* the same way and has the same restrictions, but with the - -* addition of the following: -* -* - The only celestial coordinate systems that may be represented -* are equatorial, galactic and ecliptic, -* - Sky projections can be represented only if any associated -* projection parameters are set to their default values. -* - Secondary axis descriptions are not supported, so when writing -* a FrameSet to a FitsChan, only information from the base and -* current Frames will be stored. -* -* Note that this encoding is provided mainly as an interim measure to -* provide a more stable alternative to the FITS-WCS encoding until the -* FITS standard for encoding WCS information is finalised. The name -* "FITS-IRAF" indicates the general keyword conventions used and does -* not imply that this encoding will necessarily support all features of -* the WCS scheme used by IRAF software. Nevertheless, an attempt has -* been made to support a few such features where they are known to be -* used by important sources of data. -* -* When writing a FrameSet using the FITS-IRAF encoding, axis rotations -* are specified by a matrix of FITS keywords of the form "CDi_j", where -* "i" and "j" are single digits. The alternative form "CDiiijjj", which -* is also in use, is recognised when reading an Object, but is never -* written. -* -* In addition, the experimental IRAF "ZPX" and "TNX" sky projections will -* be accepted when reading, but will never be written (the corresponding -* FITS "ZPN" or "distorted TAN" projection being used instead). However, -* there are restrictions on the use of these experimental projections. -* For "ZPX", longitude and latitude correction surfaces (appearing as -* "lngcor" or "latcor" terms in the IRAF-specific "WAT" keywords) are -* not supported. For "TNX" projections, only cubic surfaces encoded as -* simple polynomials with "half cross-terms" are supported. If an -* un-usable "TNX" or "ZPX" projection is encountered while reading -* from a FitsChan, a simpler form of TAN or ZPN projection is used -* which ignores the unsupported features and may therefore be -* inaccurate. If this happens, a warning message is added to the -* contents of the FitsChan as a set of cards using the keyword "ASTWARN". -* -* You should not normally attempt to mix the foreign FITS encodings within -* the same FitsChan, since there is a risk that keyword clashes may occur. - -* The FITS-PC Encoding: -* The FITS-PC encoding can, for most purposes, be considered as -* equivalent to the FITS-WCS encoding (above), although it differs -* in the details of the FITS keywords used. It is used in exactly -* the same way and has the same restrictions. - -* The FITS-AIPS Encoding: -* The FITS-AIPS encoding can, for most purposes, be considered as -* equivalent to the FITS-WCS encoding (above), although it differs -* in the details of the FITS keywords used. It is used in exactly -* the same way and has the same restrictions, but with the - -* addition of the following: -* -* - The only celestial coordinate systems that may be represented -* are equatorial, galactic and ecliptic, -* - Spectral axes can only be represented if they represent -* frequency, radio velocity or optical velocity, and are linearly -* sampled in frequency. In addition, the standard of rest -* must be LSRK, LSRD, barycentric or geocentric. -* - Sky projections can be represented only if any associated -* projection parameters are set to their default values. -* - The AIT, SFL and MER projections can only be written if the CRVAL -* keywords are zero for both longitude and latitude axes. -* - Secondary axis descriptions are not supported, so when writing -* a FrameSet to a FitsChan, only information from the base and -* current Frames will be stored. -* - If there are more than 2 axes in the base and current Frames, any -* rotation must be restricted to the celestial plane, and must involve -* no shear. - -* The FITS-AIPS++ Encoding: -* The FITS-AIPS++ encoding is based on the FITS-AIPS encoding, but -* includes some features of the FITS-IRAF and FITS-PC encodings. -* Specifically, any celestial projections supported by FITS-PC may be -* used, including those which require parameterisation, and the axis -* rotation and scaling may be specified using CDi_j keywords. When -* writing a FITS header, rotation will be specified using CROTA/CDELT -* keywords if possible, otherwise CDi_j keywords will be used instead. - -* The FITS-CLASS Encoding: -* The FITS-CLASS encoding uses the conventions of the CLASS project. -* These are described in the section "Developer Manual"/"CLASS FITS - -* Format" contained in the CLASS documentation at: -* -* http://www.iram.fr/IRAMFR/GILDAS/doc/html/class-html/class.html. -* - -* This encoding is similar to FITS-AIPS with the following restrictions: -* -* - When a SpecFrame is created by reading a FITS-CLASS header, the -* attributes describing the observer's position (ObsLat, ObsLon and -* ObsAlt) are left unset because the CLASS encoding does not specify -* these values. Conversions to or from the topocentric standard of rest -* will therefore be inaccurate (typically by up to about 0.5 km/s) -* unless suitable values are assigned to these attributes after the -* FrameSet has been created. -* - When writing a FrameSet to a FITS-CLASS header, the current Frame -* in the FrameSet must have at least 3 WCS axes, of which one must be -* a linear spectral axis. The spectral axis in the created header will -* always describe frequency. If the spectral axis in the supplied -* FrameSet refers to some other system (e.g. radio velocity, etc), -* then it will be converted to frequency. -* - There must be a pair of celestial axes - either (RA,Dec) or -* (GLON,GLAT). RA and Dec must be either FK4/B1950 or FK5/J2000. -* - A limited range of projection codes (TAN, ARC, STG, AIT, SFL, SIN) -* can be used. For AIT and SFL, the reference point must be at the -* origin of longitude and latitude. For SIN, the associated projection -* parameters must both be zero. -* - No rotation of the celestial axes is allowed, unless the spatial -* axes are degenerate (i.e. cover only a single pixel). -* - The frequency axis in the created header will always describe -* frequency in the source rest frame. If the supplied FrameSet uses -* some other standard of rest then suitable conversion will be applied. -* - The source velocity must be defined. In other words, the SpecFrame -* attributes SourceVel and SourceVRF must have been assigned values. -* - The frequency axis in a FITS-CLASS header does not represent -* absolute frequency, but instead represents offsets from the rest -* frequency in the standard of rest of the source. -* -* When writing a FrameSet out using FITS-CLASS encoding, the current -* Frame may be temporarily modified if this will allow the header -* to be produced. If this is done, the associated pixel->WCS Mapping -* will also be modified to take account of the changes to the Frame. -* The modifications performed include re-ordering axes (WCS axes, not -* pixel axes), changing spectral coordinate system and standard of -* rest, changing the celestial coordinate system and reference equinox, -* and changing axis units. - -* The NATIVE Encoding: -* The NATIVE encoding may be used to store a description of any -* class of AST Object in the form of FITS header cards, and (for -* most practical purposes) any number of these Object descriptions -* may be stored within a single set of FITS cards. If multiple -* Object descriptions are stored, they are written and read -* sequentially. The NATIVE encoding makes use of unique FITS -* keywords which are designed not to clash with keywords that have -* already been used for other purposes (if a potential clash is -* detected, an alternative keyword is constructed to avoid the -* clash). -* -* When reading a NATIVE encoded object from a FitsChan (using -c astRead), FITS header cards are read, starting at the current -f AST_READ), FITS header cards are read, starting at the current -* card (as determined by the Card attribute), until the start of -* the next Object description is found. This description is then -* read and converted into an AST Object, for which a pointer is -* returned. Such a read is always destructive and causes all the -* FITS header cards involved in the Object description to be -* removed from the FitsChan, which is left positioned at the -* following card. -* -* The Object returned may be of any class, depending on the -* description that was read, and other AST routines may be used to -* validate it (for example, by examining its Class or ID attribute -c using astGetC). If further NATIVE encoded Object descriptions -f using AST_GETC). If further NATIVE encoded Object descriptions -c exist in the FitsChan, subsequent calls to astRead will return -f exist in the FitsChan, subsequent calls to AST_READ will return -* the Objects they describe in sequence (and destroy their -* descriptions) until no more remain between the current card and -* the "end-of-file". -* -c When astWrite is used to write an Object using NATIVE encoding, -f When AST_WRITE is used to write an Object using NATIVE encoding, -* a description of the Object is inserted immediately before the -* current card (as determined by the Card attribute). Multiple -* Object descriptions may be written in this way and are stored -* separately (and sequentially if the Card attribute is not -* modified between the writes). A write operation using the NATIVE -* encoding does not over-write previously written Object -* descriptions. Note, however, that subsequent behaviour is -* undefined if an Object description is written inside a -* previously-written description, so this should be avoided. -* -* When an Object is written to a FitsChan using NATIVE encoding, -c astWrite should (barring errors) always transfer data and -f AST_WRITE should (barring errors) always transfer data and -* return a value of 1. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,Encoding,encoding,UNKNOWN_ENCODING) -astMAKE_SET(FitsChan,Encoding,int,encoding,( - value == NATIVE_ENCODING || - value == FITSPC_ENCODING || - value == FITSWCS_ENCODING || - value == FITSIRAF_ENCODING || - value == FITSAIPS_ENCODING || - value == FITSAIPSPP_ENCODING || - value == FITSCLASS_ENCODING || - value == DSS_ENCODING ? value : - (astError( AST__BADAT, "astSetEncoding: Unknown encoding system %d " - "supplied.", status, value ), UNKNOWN_ENCODING ))) -astMAKE_TEST(FitsChan,Encoding,( this->encoding != UNKNOWN_ENCODING )) - -/* DefB1950 */ -/* ======== */ - -/* -*att++ -* Name: -* DefB1950 - -* Purpose: -* Use FK4 B1950 as defaults? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which specifies a default equinox -* and reference frame to use when reading a FrameSet from a FitsChan -* with a foreign (i.e. non-native) encoding. It is only used if the FITS -* header contains RA and DEC axes but contains no information about the -* reference frame or equinox. If this is the case, then values of FK4 and -* B1950 are assumed if the DefB1950 attribute has a non-zero value and -* ICRS is assumed if DefB1950 is zero. The default value for DefB1950 -* depends on the value of the Encoding attribute: for FITS-WCS encoding -* the default is zero, and for all other encodings it is one. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,DefB1950,defb1950,-1) -astMAKE_GET(FitsChan,DefB1950,int,1,(this->defb1950 == -1 ? (astGetEncoding(this)== FITSWCS_ENCODING?0:1): this->defb1950)) -astMAKE_SET(FitsChan,DefB1950,int,defb1950,( value ? 1 : 0 )) -astMAKE_TEST(FitsChan,DefB1950,( this->defb1950 != -1 )) - -/* TabOK */ -/* ===== */ - -/* -*att++ -* Name: -* TabOK - -* Purpose: -* Should the FITS-WCS -TAB algorithm be recognised? - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute is an integer value which indicates if the "-TAB" -* algorithm, defined in FITS-WCS paper III, should be supported by -* the FitsChan. The default value is zero. A zero or negative value -* results in no support for -TAB axes (i.e. axes that have "-TAB" -* in their CTYPE keyword value). In this case, the -c astWrite -f AST_WRITE -* method will return zero if the write operation would required the -* use of the -TAB algorithm, and the -c astRead -f AST_READ -* method will return -c a NULL pointer -f AST__NULL -* if any axis in the supplied header uses the -TAB algorithm. - -* If TabOK is set to a non-zero positive integer, these methods will -* recognise and convert axes described by the -TAB algorithm, as -* follows: -* -c The astWrite -f The AST_WRITE -* method will generate headers that use the -TAB algorithm (if -* possible) if no other known FITS-WCS algorithm can be used to -* describe the supplied FrameSet. This will result in a table of -* coordinate values and index vectors being stored in the FitsChan. -* After the write operation, the calling application should check to -* see if such a table has been stored in the FitsChan. If so, the -* table should be retrived from the FitsChan using the -c astGetTables -f AST_GETTABLES -* method, and the data (and headers) within it copied into a new -* FITS binary table extension. See -c astGetTables -f AST_GETTABLES -* for more information. The FitsChan uses a FitsTable object to store -* the table data and headers. This FitsTable will contain the required -* columns and headers as described by FITS-WCS paper III - the -* coordinates array will be in a column named "COORDS", and the index -* vector(s) will be in columns named "INDEX" (where is the index -* of the corresponding FITS WCS axis). Note, index vectors are only -* created if required. The EXTNAME value will be set to the value of the -* AST__TABEXTNAME constant (currently "WCS-TAB"). The EXTVER header -* will be set to the positive integer value assigned to the TabOK -* attribute. No value will be stored for the EXTLEVEL header, and should -* therefore be considered to default to 1. -* -c The astRead -f The AST_READ -* method will generate a FrameSet from headers that use the -TAB -* algorithm so long as the necessary FITS binary tables are made -* available. There are two ways to do this: firstly, if the application -* knows which FITS binary tables will be needed, then it can create a -* Fitstable describing each such table and store it in the FitsChan -* (using method -c astPutTables or astPutTable) before invoking the astRead method. -f AST_PUTTABLES or AST_PUTTABLE) before invoking the AST_READ method. -* Secondly, if the application does not know which FITS binary tables -* will be needed by -c astRead, -f AST_READ, -* then it can register a call-back function with the FitsChan using -* method -c astTableSource. -f AST_TABLESOURCE. -* This call-back function will be called from within -c astRead -f AST_READ -* if and when a -TAB header is encountered. When called, its arguments -* will give the name, version and level of the FITS extension containing -* a required table. The call-back function should read this table from -* an external FITS file, and create a corresponding FitsTable which -* it should then return to -c astRead. Note, currently astRead -f AST_READ. Note, currently AST_READ -* can only handle -TAB headers that describe 1-dimensional (i.e. -* separable) axes. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,TabOK,tabok,-INT_MAX) -astMAKE_GET(FitsChan,TabOK,int,0,(this->tabok == -INT_MAX ? 0 : this->tabok)) -astMAKE_SET(FitsChan,TabOK,int,tabok,value) -astMAKE_TEST(FitsChan,TabOK,( this->tabok != -INT_MAX )) - -/* CarLin */ -/* ====== */ - -/* -*att++ -* Name: -* CarLin - -* Purpose: -* Ignore spherical rotations on CAR projections? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which specifies how FITS "CAR" -* (plate carree, or "Cartesian") projections should be treated when -* reading a FrameSet from a foreign encoded FITS header. If zero (the -* default), it is assumed that the CAR projection conforms to the -* conventions described in the FITS world coordinate system (FITS-WCS) -* paper II "Representation of Celestial Coordinates in FITS" by -* M. Calabretta & E.W. Greisen. If CarLin is non-zero, then these -* conventions are ignored, and it is assumed that the mapping from pixel -* coordinates to celestial coordinates is a simple linear transformation -* (hence the attribute name "CarLin"). This is appropriate for some older -* FITS data which claims to have a "CAR" projection, but which in fact do -* not conform to the conventions of the FITS-WCS paper. -* -* The FITS-WCS paper specifies that headers which include a CAR projection -* represent a linear mapping from pixel coordinates to "native spherical -* coordinates", NOT celestial coordinates. An extra mapping is then -* required from native spherical to celestial. This mapping is a 3D -* rotation and so the overall Mapping from pixel to celestial coordinates -* is NOT linear. See the FITS-WCS papers for further details. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,CarLin,carlin,-1) -astMAKE_GET(FitsChan,CarLin,int,1,(this->carlin == -1 ? 0 : this->carlin)) -astMAKE_SET(FitsChan,CarLin,int,carlin,( value ? 1 : 0 )) -astMAKE_TEST(FitsChan,CarLin,( this->carlin != -1 )) - -/* SipReplace */ -/* ========== */ - -/* -*att++ -* Name: -* SipReplace - -* Purpose: -* Replace SIP inverse transformation? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which specifies how SIP keywords -* should be handled when reading a FITS-WCS encoded header using the -c astRead -f AST_READ -* function. See -* http://irsa.ipac.caltech.edu/data/SPITZER/docs/files/spitzer/shupeADASS.pdf -* for more information about SIP headers. If SipReplace is non-zero, -* then any SIP keywords describing the inverse transformation (i.e. from -* WCS to pixel coordinates) are ignored. Instead a new inverse -* transformation is found by performing a fit to the forward -* transformation. The SipReplace attribute can be set to zero to prevent -* this happening. If SipReplace is zero, any SIP keywords describing the -* inverse transformation are used as supplied, rather than being -* replaced using a new fit. The default value is 1. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,SipReplace,sipreplace,-1) -astMAKE_GET(FitsChan,SipReplace,int,1,(this->sipreplace == -1 ? 1 : this->sipreplace)) -astMAKE_SET(FitsChan,SipReplace,int,sipreplace,( value ? 1 : 0 )) -astMAKE_TEST(FitsChan,SipReplace,( this->sipreplace != -1 )) - -/* PolyTan */ -/* ======= */ - -/* -*att++ -* Name: -* PolyTan - -* Purpose: -* Use PVi_m keywords to define distorted TAN projection? - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute is a boolean value which specifies how FITS "TAN" -* projections should be treated when reading a FrameSet from a foreign -* encoded FITS header. If zero, the projection is assumed to conform -* to the published FITS-WCS standard. If positive, the convention -* for a distorted TAN projection included in an early draft version -* of FITS-WCS paper II are assumed. In this convention the -* coefficients of a polynomial distortion to be applied to -* intermediate world coordinates are specified by the PVi_m keywords. -* This convention was removed from the paper before publication and so -* does not form part of the standard. Indeed, it is incompatible with -* the published standard because it re-defines the meaning of the -* first five PVi_m keywords on the longitude axis, which are reserved -* by the published standard for other purposes. However, this -* scheme has now been added to the registry of FITS conventions -* (http://fits.gsfc.nasa.gov/registry/tpvwcs.html) and headers -* that use this convention are created by the SCAMP utility -* (http://www.astromatic.net/software/scamp) and the Dark Energy -* Camera at NOAO. -* -* The default value for the PolyTan attribute is -1. A negative -* values causes the used convention to depend on the contents -* of the FitsChan. If the FitsChan contains any PVi_m keywords for -* the latitude axis, or if it contains PVi_m keywords for the -* longitude axis with "m" greater than 4, then the distorted TAN -* convention is used. Otherwise, the standard convention is used. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,PolyTan,polytan,-INT_MAX) -astMAKE_SET(FitsChan,PolyTan,int,polytan,value) -astMAKE_TEST(FitsChan,PolyTan,( this->polytan != -INT_MAX )) -astMAKE_GET(FitsChan,PolyTan,int,-1,(this->polytan == -INT_MAX ? -1 : this->polytan)) - -/* SipOK */ -/* ===== */ - -/* -*att++ -* Name: -* SipOK - -* Purpose: -* Use Spitzer Space Telescope keywords to define distortion? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which specifies whether to include -* support for the "SIP" scheme, which can be used to add distortion to -* basic FITS-WCS projections. This scheme was first defined by the -* Spitzer Space Telescope and is described in the following document: -* http://irsa.ipac.caltech.edu/data/SPITZER/docs/files/spitzer/shupeADASS.pdf -* The default for SipOK is 1. -* -* When using -c astRead -f AST_READ -* to read a FITS-WCS encoded header, a suitable PolyMap will always be -* included in the returned FrameSet if the header contains SIP -* keywords, regardless of the value of the SipOK attribute. The PolyMap -* will be immediately before the MatrixMap that corresponds to the FITS-WCS -* PC or CD matrix. -* -* When using -c astWrite -f AST_WRITE -* to write a FrameSet to a FITS-WCS encoded header, suitable SIP -* keywords will be included in the header if the FrameSet contains a -* PolyMap immediately before the MatrixMap that corresponds to the -* FITS-WCS PC or CD matrix, but only if the SipOK attribute is non-zero. -* If the FrameSet contains a PolyMap but SipOK is zero, then an attempt -* will be made to write out the FrameSet without SIP keywords using a -* linear approximation to the pixel-to-IWC mapping. If this fails -* because the Mapping exceeds the linearity requirement specified by -* attribute FitsTol, -c astWrite -f AST_WRITE -* will return zero, indicating that the FrameSet could not be written -* out. Note, SIP headers can only be produced for axes that form part -* of a SkyFrame. -* -* Note, the SIP distortion scheme is independent of the TPV/TPN -* distortion schemes (see attribute PolyTan). A FITS-WCS header could -* in principle, contain keywords for both schemes although this is unlikely. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,SipOK,sipok,-INT_MAX) -astMAKE_SET(FitsChan,SipOK,int,sipok,value) -astMAKE_TEST(FitsChan,SipOK,( this->sipok != -INT_MAX )) -astMAKE_GET(FitsChan,SipOK,int,1,(this->sipok == -INT_MAX ? 1 : this->sipok)) - -/* Iwc */ -/* === */ - -/* -*att++ -* Name: -* Iwc - -* Purpose: -* Include a Frame representing FITS-WCS intermediate world coordinates? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which is used when a FrameSet is -* read from a FitsChan with a foreign FITS encoding (e.g. FITS-WCS) using -c astRead. -f AST_READ. -* If it has a non-zero value then the returned FrameSet will include -* Frames representing "intermediate world coordinates" (IWC). These -* Frames will have Domain name "IWC" for primary axis descriptions, and -* "IWCa" for secondary axis descriptions, where "a" is replaced by -* the single alternate axis description character, as used in the -* FITS-WCS header. The default value for "Iwc" is zero. -* -* FITS-WCS paper 1 defines IWC as a Cartesian coordinate system with one -* axis for each WCS axis, and is the coordinate system produced by the -* rotation matrix (represented by FITS keyword PCi_j, CDi_j, etc). -* For instance, for a 2-D FITS-WCS header describing projected -* celestial longitude and latitude, the intermediate world -* coordinates represent offsets in degrees from the reference point -* within the plane of projection. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,Iwc,iwc,-1) -astMAKE_GET(FitsChan,Iwc,int,1,(this->iwc == -1 ? 0 : this->iwc)) -astMAKE_SET(FitsChan,Iwc,int,iwc,( value ? 1 : 0 )) -astMAKE_TEST(FitsChan,Iwc,( this->iwc != -1 )) - -/* -*att++ -* Name: -* CDMatrix - -* Purpose: -* Use CDi_j keywords to represent pixel scaling, rotation, etc? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which specifies how the linear -* transformation from pixel coordinates to intermediate world -* coordinates should be represented within a FitsChan when using -* FITS-WCS encoding. This transformation describes the scaling, -* rotation, shear, etc., of the pixel axes. -* -* If the attribute has a non-zero value then the transformation is -* represented by a set of CDi_j keywords representing a square matrix -* (where "i" is the index of an intermediate world coordinate axis -* and "j" is the index of a pixel axis). If the attribute has a zero -* value the transformation is represented by a set of PCi_j keywords -* (which also represent a square matrix) together with a corresponding -* set of CDELTi keywords representing the axis scalings. See FITS-WCS -* paper II "Representation of Celestial Coordinates in FITS" by -* M. Calabretta & E.W. Greisen, for a complete description of these two -* schemes. -* -* The default value of the CDMatrix attribute is determined by the -* contents of the FitsChan at the time the attribute is accessed. If -* the FitsChan contains any CDi_j keywords then the default value is -* non-zero. Otherwise it is zero. Note, reading a FrameSet from a -* FitsChan will in general consume any CDi_j keywords present in the -* FitsChan. Thus the default value for CDMatrix following a read will -* usually be zero, even if the FitsChan originally contained some -* CDi_j keywords. This behaviour is similar to that of the Encoding -* attribute, the default value for which is determined by the contents -* of the FitsChan at the time the attribute is accessed. If you wish -* to retain the original value of the CDMatrix attribute (that is, -* the value before reading the FrameSet) then you should enquire the -* default value before doing the read, and then set that value -* explicitly. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,CDMatrix,cdmatrix,-1) -astMAKE_SET(FitsChan,CDMatrix,int,cdmatrix,( value ? 1 : 0 )) -astMAKE_TEST(FitsChan,CDMatrix,( this->cdmatrix != -1 )) - -/* Clean */ -/* ===== */ - -/* -*att++ -* Name: -* Clean - -* Purpose: -* Remove cards used whilst reading even if an error occurs? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute indicates whether or not cards should be removed from -* the FitsChan if an error occurs within -c astRead. -f AST_READ. -* A succesful read on a FitsChan always results in the removal of -* the cards which were involved in the description of the returned -* Object. However, in the event of an error during the read (for instance -* if the cards in the FitsChan have illegal values, or if some required -* cards are missing) no cards will be removed from the FitsChan if -* the Clean attribute is zero (the default). If Clean is non-zero then -* any cards which were used in the aborted attempt to read an object -* will be removed. -* -* This provides a means of "cleaning" a FitsChan of WCS related cards -* which works even in the event of the cards not forming a legal WCS -* description. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,Clean,clean,-1) -astMAKE_SET(FitsChan,Clean,int,clean,( value ? 1 : 0 )) -astMAKE_TEST(FitsChan,Clean,( this->clean != -1 )) - -/* -*att++ -* Name: -* FitsAxisOrder - -* Purpose: -* Frame title. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies the order for the WCS axes in any new -* FITS-WCS headers created using the -c astWrite -f AST_WRITE -* method. -* -* The value of the FitsAxisOrder attribute can be either "" -* (the default value), "" or a space-separated list of axis -* symbols: -* -* "": causes the WCS axis order to be chosen automatically so that -* the i'th WCS axis in the new FITS header is the WCS axis which is -* more nearly parallel to the i'th pixel axis. -* -* "": causes the WCS axis order to be set so that the i'th WCS -* axis in the new FITS header is the i'th WCS axis in the current -* Frame of the FrameSet being written out to the header. -* -* "Sym1 Sym2...": the space-separated list is seached in turn for -* the Symbol attribute of each axis in the current Frame of the -* FrameSet. The order in which these Symbols occur within the -* space-separated list defines the order of the WCS axes in the -* new FITS header. An error is reported if Symbol for a current -* Frame axis is not present in the supplied list. However, no error -* is reported if the list contains extra words that do not correspond -* to the Symbol of any current Frame axis. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,FitsAxisOrder,fitsaxisorder,astFree( this->fitsaxisorder )) -astMAKE_GET(FitsChan,FitsAxisOrder,const char *,NULL,(this->fitsaxisorder ? this->fitsaxisorder : "" )) -astMAKE_SET(FitsChan,FitsAxisOrder,const char *,fitsaxisorder,astStore( this->fitsaxisorder, value, strlen( value ) + (size_t) 1 )) -astMAKE_TEST(FitsChan,FitsAxisOrder,( this->fitsaxisorder != NULL )) - -/* FitsDigits. */ -/* =========== */ - -/* -*att++ -* Name: -* FitsDigits - -* Purpose: -* Digits of precision for floating point FITS values. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute gives the number of significant decimal digits to -* use when formatting floating point values for inclusion in the -* FITS header cards within a FitsChan. -* -* By default, a positive value is used which results in no loss of -c information, assuming that the value's precision is double. -f information, assuming that the value is double precision. -* Usually, this causes no problems. -* -* However, to adhere strictly to the recommendations of the FITS -* standard, the width of the formatted value (including sign, -* decimal point and exponent) ought not to be more than 20 -* characters. If you are concerned about this, you should set -* FitsDigits to a negative value, such as -15. In this case, the -* absolute value (+15) indicates the maximum number of significant -* digits to use, but the actual number used may be fewer than this -* to ensure that the FITS recommendations are satisfied. When -* using this approach, the resulting number of significant digits -* may depend on the value being formatted and on the presence of -* any sign, decimal point or exponent. -* -* The value of this attribute is effective when FITS header cards -* are output, either using -c astFindFits or by the action of the FitsChan's sink function -f AST_FINDFITS or by the action of the FitsChan's sink routine -* when it is finally deleted. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(FitsChan,FitsDigits,fitsdigits,AST__DBL_DIG) -astMAKE_GET(FitsChan,FitsDigits,int,AST__DBL_DIG,this->fitsdigits) -astMAKE_SET(FitsChan,FitsDigits,int,fitsdigits,value) -astMAKE_TEST(FitsChan,FitsDigits,( this->fitsdigits != AST__DBL_DIG )) - -/* CardComm */ -/* ======== */ - -/* -*att++ -* Name: -* CardComm - -* Purpose: -* The comment for the current card in a FitsChan. - -* Type: -* Public attribute. - -* Synopsis: -* String, read-only. - -* Description: -* This attribute gives the comment for the current card of the -* FitsChan. A zero-length string is returned if the card has no comment. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ - -/* CardName */ -/* ======== */ - -/* -*att++ -* Name: -* CardName - -* Purpose: -* The keyword name of the current card in a FitsChan. - -* Type: -* Public attribute. - -* Synopsis: -* String, read-only. - -* Description: -* This attribute gives the name of the keyword for the -* current card of the FitsChan. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ - -/* CardType */ -/* ======== */ - -/* -*att++ -* Name: -* CardType - -* Purpose: -* The data type of the current card in a FitsChan. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the data type of the keyword value for the -* current card of the FitsChan. It will be one of the following -* integer constants: AST__NOTYPE, AST__COMMENT, AST__INT, AST__FLOAT, -* AST__STRING, AST__COMPLEXF, AST__COMPLEXI, AST__LOGICAL, -* AST__CONTINUE, AST__UNDEF. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ - -/* Ncard */ -/* ===== */ - -/* -*att++ -* Name: -* Ncard - -* Purpose: -* Number of FITS header cards in a FitsChan. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the total number of FITS header cards -* stored in a FitsChan. It is updated as cards are added or -* deleted. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ - -/* Nkey */ -/* ==== */ - -/* -*att++ -* Name: -* Nkey - -* Purpose: -* Number of unique FITS keywords in a FitsChan. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the total number of unique FITS keywords -* stored in a FitsChan. It is updated as cards are added or -* deleted. If no keyword occurrs more than once in the FitsChan, the -* Ncard and Nkey attributes will be equal. If any keyword occurrs -* more than once, the Nkey attribute value will be smaller than -* the Ncard attribute value. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ - -/* Warnings. */ -/* ======== */ - -/* -*att++ -* Name: -* Warnings - -* Purpose: -* Controls the issuing of warnings about various conditions. - -* Type: -* Public attribute. - -* Synopsis: -* String - -* Description: -* This attribute controls the issuing of warnings about selected -* conditions when an Object or keyword is read from or written to a -* FitsChan. The value supplied for the Warnings attribute should -* consist of a space separated list of condition names (see the -* AllWarnings attribute for a list of the currently defined names). -* Each name indicates a condition which should be reported. The default -* value for Warnings is the string "BadKeyName BadKeyValue Tnx Zpx -* BadCel BadMat BadPV BadCTYPE". -* -* The text of any warning will be stored within the FitsChan in the -* form of one or more new header cards with keyword ASTWARN. If -* required, applications can check the FitsChan for ASTWARN cards -c (using astFindFits) after the call to astRead or astWrite has been -f (using AST_FINDFITS) after the call to AST_READ or AST_WRITE has been -* performed, and report the text of any such cards to the user. ASTWARN -* cards will be propagated to any output header unless they are -c deleted from the FitsChan using astDelFits. -f deleted from the FitsChan using astDelFits. - -* Notes: -* This attribute only controls the warnings that are to be stored as -* a set of header cards in the FitsChan as described above. It has no -* effect on the storage of warnings in the parent Channel structure. -* All warnings are stored in the parent Channel structure, from where -* they can be retrieved using the -c astWarnings -f AST_WARNINGS -* function. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ - -/* Clear the Warnings value by freeing the allocated memory and assigning - a NULL pointer. */ -astMAKE_CLEAR(FitsChan,Warnings,warnings,astFree( this->warnings )) - -/* If the Warnings value is not set, supply a default in the form of a - pointer to the constant string "BadKeyName BadKeyValue Tnx Zpx BadCel BadMat BadCTYPE". */ -astMAKE_GET(FitsChan,Warnings,const char *,NULL,( this->warnings ? this->warnings : - "BadKeyName BadKeyValue Tnx Zpx BadPV BadCel BadMat BadCTYPE" )) - -/* Set a Warnings value by freeing any previously allocated memory, allocating - new memory, storing the string and saving the pointer to the copy. - First check that the list does not contain any unknown conditions. If - it does, an error is reported by GoodWarns and the current attribute value - is retained. */ -astMAKE_SET(FitsChan,Warnings,const char *,warnings,( GoodWarns( value, status ) ? - astStore( this->warnings, value, strlen( value ) + (size_t) 1 ) : - this->warnings)) - -/* The Warnings value is set if the pointer to it is not NULL. */ -astMAKE_TEST(FitsChan,Warnings,( this->warnings != NULL )) - -/* AllWarnings. */ -/* ============ */ - -/* -*att++ -* Name: -* AllWarnings - -* Purpose: -* A list of all currently available condition names. - -* Type: -* Public attribute. - -* Synopsis: -* String, read-only - -* Description: -* This read-only attribute is a space separated list of all the conditions -* names recognized by the Warnings attribute. The names are listed -* below. - -* Conditions: -* The following conditions are currently recognised (all are -* case-insensitive): -* -* - "BadCel": This condition arises when reading a FrameSet from a -* non-Native encoded FitsChan if an unknown celestial co-ordinate -* system is specified by the CTYPE keywords. -* -* - "BadCTYPE": This condition arises when reading a FrameSet from a -* non-Native encoded FitsChan if an illegal algorithm code is specified -* by a CTYPE keyword, and the illegal code can be converted to an -* equivalent legal code. -* -* - "BadKeyName": This condition arises if a FITS keyword name is -* encountered that contains an illegal character (i.e. one not allowed -* by the FITS standard). -* -* - "BadKeyValue": This condition arises if the value of a FITS keyword -* cannot be determined from the content of the header card. -* -* - "BadLat": This condition arises when reading a FrameSet from a -* non-Native encoded FitsChan if the latitude of the reference point -* has an absolute value greater than 90 degrees. The actual absolute -* value used is set to exactly 90 degrees in these cases. -* -* - "BadMat": This condition arises if the matrix describing the -* transformation from pixel offsets to intermediate world coordinates -* cannot be inverted. This matrix describes the scaling, rotation, shear, -* etc., applied to the pixel axes, and is specified by keywords such as -* PCi_j, CDi_j, CROTA, etc. For example, the matrix will not be invertable -* if any rows or columns consist entirely of zeros. The FITS-WCS Paper I -* "Representation of World Coordinates in FITS" by Greisen & Calabretta -* requires that this matrix be invertable. Many operations (such as -* grid plotting) will not be possible if the matrix cannot be inverted. -* -* - "BadPV": This condition arises when reading a FrameSet from a -* non-Native encoded FitsChan. It is issued if a PVi_m header is found -* that refers to a projection parameter that is not used by the -* projection type specified by CTYPE, or the PV values are otherwise -* inappropriate for the projection type. -* -* - "BadVal": This condition arises when reading a FrameSet from a -* non-Native encoded FitsChan if it is not possible to convert the -* value of a FITS keywords to the expected type. For instance, this -* can occur if the FITS header contains a string value for a keyword -* which should have a floating point value, or if the keyword has no -* value at all (i.e. is a comment card). -* -* - "Distortion": This condition arises when reading a FrameSet from a -* non-Native encoded FitsChan if any of the CTYPE keywords specify an -* unsupported distortion code using the "4-3-3" format specified in -* FITS-WCS paper IV. Such distortion codes are ignored. -* -* - "NoCTYPE": This condition arises if a default CTYPE value is used -c within astRead, due to no value being present in the supplied FitsChan. -f within AST_READ, due to no value being present in the supplied FitsChan. -* This condition is only tested for when using non-Native encodings. -* -* - "NoEquinox": This condition arises if a default equinox value is used -c within astRead, due to no value being present in the supplied FitsChan. -f within AST_READ, due to no value being present in the supplied FitsChan. -* This condition is only tested for when using non-Native encodings. -* -* - "NoRadesys": This condition arises if a default reference frame is -c used for an equatorial co-ordinate system within astRead, due to no -f used for an equatorial co-ordinate system within AST_READ, due to no -* value being present in the supplied FitsChan. This condition is only -* tested for when using non-Native encodings. -* -* - "NoLonpole": This condition arises if a default value is used for -c the LONPOLE keyword within astRead, due to no value being present -f the LONPOLE keyword within AST_READ, due to no value being present -* in the supplied FitsChan. This condition is only tested for when -* using non-Native encodings. -* -* - "NoLatpole": This condition arises if a default value is used for -c the LATPOLE keyword within astRead, due to no value being present -f the LATPOLE keyword within AST_READ, due to no value being present -* in the supplied FitsChan. This condition is only tested for when -* using non-Native encodings. -* -* - "NoMjd-obs": This condition arises if a default value is used for -c the date of observation within astRead, due to no value being present -f the date of observation within AST_READ, due to no value being present -* in the supplied FitsChan. This condition is only tested for when using -* non-Native encodings. -* -* - "Tnx": This condition arises if a FrameSet is read from a FITS -* header containing an IRAF "TNX" projection which includes terms -* not supproted by AST. Such terms are ignored and so the resulting -* FrameSet may be inaccurate. -* -* - "Zpx": This condition arises if a FrameSet is read from a FITS -* header containing an IRAF "ZPX" projection which includes "lngcor" -* or "latcor" correction terms. These terms are not supported by AST -* and are ignored. The resulting FrameSet may therefore be inaccurate. - -* Applicability: -* FitsChan -* All FitsChans have this attribute. -*att-- -*/ - -/* Copy constructor. */ -/* ----------------- */ - -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for FitsChan objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for FitsChan objects. - -* Parameters: -* objin -* Pointer to the FitsChan to be copied. -* objout -* Pointer to the FitsChan being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The source and sink functions are not propagated (i.e. the -* pointers are set NULL in the output FitsChan). -* - This constructor makes a deep copy, including a copy of the -* keyword values. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *class; /* Pointer to object class */ - AstFitsChan *in; /* Pointer to input FitsChan */ - AstFitsChan *out; /* Pointer to output FitsChan */ - int *flags; - int icard; - int old_ignore_used; /* Original value of external variable ignore_used */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(objin); - -/* Obtain pointers to the input and output FitsChans. */ - in = (AstFitsChan *) objin; - out = (AstFitsChan *) objout; - -/* Nullify all pointers in the output FitsChan so that the input - data will not be deleted in the event of an error occurring. */ - out->card = NULL; - out->head = NULL; - out->keyseq = NULL; - out->keywords = NULL; - out->source = NULL; - out->saved_source = NULL; - out->source_wrap = NULL; - out->sink = NULL; - out->sink_wrap = NULL; - out->warnings = NULL; - out->tabsource = NULL; - out->tabsource_wrap = NULL; - -/* Store the object class. */ - class = astGetClass( in ); - -/* Ensure all cards are copied, including those already read by astRead. */ - old_ignore_used = ignore_used; - ignore_used = 0; - -/* Save the current card index in the input FitsChan. */ - icard = astGetCard( in ); - -/* Rewind the input FitsChan. */ - astClearCard( in ); - -/* Copy all the FitsCard structures from input to output. */ - while( !astFitsEof( in ) && astOK ){ - -/* Get a pointer to the flags mask for this card. */ - flags = CardFlags( in, status ); - -/* Store a new card in the output, holding the same information as the - input card. */ - NewCard( out, CardName( in, status ), CardType( in, status ), CardData( in, NULL, status ), - CardComm( in, status ), (flags?(*flags):0), status ); - -/* Move on to the next input card. */ - MoveCard( in, 1, "astCopy", class, status ); - } - -/* Set the current card in both input and output to the current input - card on entry. */ - astSetCard( in, icard ); - astSetCard( out, icard ); - -/* Copy the list of keyword sequence numbers used. */ - if( in->keyseq ) out->keyseq = astCopy( in->keyseq ); - -/* Copy the Warnings attribute value */ - if( in->warnings ) out->warnings = astStore( NULL, in->warnings, - strlen( in->warnings ) + 1 ); - -/* Copy any tables currently in the FitsChan structure. */ - if( in->tables ) out->tables = astCopy( in->tables ); - -/* Reinstate the original setting of the external ignore_used variable. */ - ignore_used = old_ignore_used; - -/* If an error occurred, delete the contents of the output Object. */ - if( !astOK ) Delete( objout, status ); -} - -/* Destructor. */ -/* ----------- */ - -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for FitsChan objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for FitsChan objects. - -* Parameters: -* obj -* Pointer to the FitsChan to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to FitsChan */ - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) obj; - -/* Write out the contents of the FitsChan using the sink function - provided when it was created. */ - WriteToSink( this, status ); - -/* Remove all cards from the FitsChan. */ - EmptyFits( this, status ); -} - -/* Dump function. */ -/* -------------- */ - -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for FitsChan objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the FitsChan class to an output Channel. - -* Parameters: -* this -* Pointer to the FitsChan whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstFitsChan *this; /* Pointer to the FitsChan structure */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - const char *class; /* Object class */ - const char *sval; /* Pointer to string value */ - double dval; /* Double value */ - int cardtype; /* Keyword data type */ - int flags; /* Keyword flags */ - int icard; /* Index of current card */ - int ival; /* Integer value */ - int ncard; /* No. of cards dumped so far */ - int old_ignore_used; /* Original value of external variable ignore_used */ - int set; /* Attribute value set? */ - void *data; /* Pointer to keyword data value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the FitsChan structure. */ - this = (AstFitsChan *) this_object; - -/* Store the object class. */ - class = astGetClass( this ); - -/* Save the index of ht ecurrent card. */ - icard = astGetCard( this ); - -/* Write out values representing the instance variables for the - FitsChan class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* Card. */ -/* ----- */ - astWriteInt( channel, "Card", 1, 1, icard, "Index of current card" ); - -/* Encoding. */ -/* --------- */ - set = TestEncoding( this, status ); - ival = set ? GetEncoding( this, status ) : astGetEncoding( this ); - if( ival > UNKNOWN_ENCODING && ival <= MAX_ENCODING ) { - astWriteString( channel, "Encod", set, 1, xencod[ival], "Encoding system" ); - } else { - astWriteString( channel, "Encod", set, 1, UNKNOWN_STRING, "Encoding system" ); - } - -/* FitsAxisOrder. */ -/* -------------- */ - set = TestFitsAxisOrder( this, status ); - sval = set ? GetFitsAxisOrder( this, status ) : astGetFitsAxisOrder( this ); - astWriteString( channel, "FAxOrd", set, 1, sval, - "Order of WCS axes in new FITS headers" ); - -/* FitsDigits. */ -/* ----------- */ - set = TestFitsDigits( this, status ); - ival = set ? GetFitsDigits( this, status ) : astGetFitsDigits( this ); - astWriteInt( channel, "FitsDg", set, 1, ival, "No. of digits for floating point values" ); - -/* DefB1950 */ -/* -------- */ - set = TestDefB1950( this, status ); - ival = set ? GetDefB1950( this, status ) : astGetDefB1950( this ); - astWriteInt( channel, "DfB1950", set, 1, ival, (ival ? "Default to FK4 B1950": "Default to ICRS") ); - -/* TabOK */ -/* ----- */ - set = TestTabOK( this, status ); - ival = set ? GetTabOK( this, status ) : astGetTabOK( this ); - astWriteInt( channel, "TabOK", set, 1, ival, ( ival > 0 ? "EXTVER value for -TAB headers": "Do not support -TAB CTYPE codes") ); - -/* CDMatrix */ -/* -------- */ - set = TestCDMatrix( this, status ); - ival = set ? GetCDMatrix( this, status ) : astGetCDMatrix( this ); - astWriteInt( channel, "CdMat", set, 1, ival, (ival ? "Use CD Matrix":"Use PC matrix") ); - -/* CarLin */ -/* ------ */ - set = TestCarLin( this, status ); - ival = set ? GetCarLin( this, status ) : astGetCarLin( this ); - astWriteInt( channel, "CarLin", set, 1, ival, (ival ? "Use simple linear CAR projections": "Use full FITS-WCS CAR projections") ); - -/* SipReplace */ -/* ------ */ - set = TestSipReplace( this, status ); - ival = set ? GetSipReplace( this, status ) : astGetSipReplace( this ); - astWriteInt( channel, "SipReplace", set, 1, ival, "Replace SIP inverse coefficients?" ); - -/* FitsTol */ -/* ------- */ - set = TestFitsTol( this, status ); - dval = set ? GetFitsTol( this, status ) : astGetFitsTol( this ); - astWriteDouble( channel, "FitsTol", set, 1, dval, "[pixel] Max allowed " - "departure from linearity"); - -/* PolyTan */ -/* ------- */ - set = TestPolyTan( this, status ); - ival = set ? GetPolyTan( this, status ) : astGetPolyTan( this ); - astWriteInt( channel, "PolyTan", set, 0, ival, (ival ? "Use distorted TAN convention": "Use standard TAN convention") ); - -/* SipOK */ -/* ----- */ - set = TestSipOK( this, status ); - ival = set ? GetSipOK( this, status ) : astGetSipOK( this ); - astWriteInt( channel, "SipOK", set, 0, ival, (ival ? "Use SIP distortion convention": "Ignore SIP keywords") ); - -/* Iwc */ -/* --- */ - set = TestIwc( this, status ); - ival = set ? GetIwc( this, status ) : astGetIwc( this ); - astWriteInt( channel, "Iwc", set, 1, ival, (ival ? "Include an IWC Frame": "Do not include an IWC Frame") ); - -/* Clean */ -/* ----- */ - set = TestClean( this, status ); - ival = set ? GetClean( this, status ) : astGetClean( this ); - astWriteInt( channel, "Clean", set, 0, ival, "Always remove used cards?" ); - -/* Warnings. */ -/* --------- */ - set = TestWarnings( this, status ); - sval = set ? GetWarnings( this, status ) : astGetWarnings( this ); - astWriteString( channel, "Warn", set, 1, sval, "Warnings to be reported" ); - -/* Now do instance variables which are not attributes. */ -/* =================================================== */ - -/* Ensure all cards are copied, including those already read by astRead. */ - old_ignore_used = ignore_used; - ignore_used = 0; - -/* Rewind the FitsChan. */ - astClearCard( this ); - -/* Dump each card. */ - ncard = 1; - while( !astFitsEof( this ) && astOK ){ - -/* Write out the keyword name. */ - if( CardName( this, status ) ){ - (void) sprintf( buff, "Nm%d", ncard ); - astWriteString( channel, buff, 1, 1, CardName( this, status ), - "FITS keyword name" ); - } - -/* Write out the keyword type. */ - cardtype = CardType( this, status ); - (void) sprintf( buff, "Ty%d", ncard ); - astWriteString( channel, buff, 1, 1, type_names[ cardtype ], - "FITS keyword data type" ); - -/* Write out the flag values if any are non-zero. */ - flags = *CardFlags( this, status ); - if( flags ){ - (void) sprintf( buff, "Fl%d", ncard ); - astWriteInt( channel, buff, 1, 1, flags, "FITS keyword flags" ); - } - -/* Write out the data value, if defined, using the appropriate data type. */ - data = CardData( this, NULL, status ); - if( data && cardtype != AST__UNDEF ){ - if( cardtype == AST__FLOAT ){ - (void) sprintf( buff, "Dt%d", ncard ); - astWriteDouble( channel, buff, 1, 1, *( (double *) data ), - "FITS keyword value" ); - } else if( cardtype == AST__STRING || cardtype == AST__CONTINUE ){ - (void) sprintf( buff, "Dt%d", ncard ); - astWriteString( channel, buff, 1, 1, (char *) data, - "FITS keyword value" ); - } else if( cardtype == AST__INT ){ - (void) sprintf( buff, "Dt%d", ncard ); - astWriteInt( channel, buff, 1, 1, *( (int *) data ), - "FITS keyword value" ); - } else if( cardtype == AST__LOGICAL ){ - (void) sprintf( buff, "Dt%d", ncard ); - astWriteInt( channel, buff, 1, 1, *( (int *) data ), - "FITS keyword value" ); - } else if( cardtype == AST__COMPLEXF ){ - (void) sprintf( buff, "Dr%d", ncard ); - astWriteDouble( channel, buff, 1, 1, *( (double *) data ), - "FITS keyword real value" ); - (void) sprintf( buff, "Di%d", ncard ); - astWriteDouble( channel, buff, 1, 1, *( ( (double *) data ) + 1 ), - "FITS keyword imaginary value" ); - } else if( cardtype == AST__COMPLEXI ){ - (void) sprintf( buff, "Dr%d", ncard ); - astWriteInt( channel, buff, 1, 1, *( (int *) data ), - "FITS keyword real value" ); - (void) sprintf( buff, "Di%d", ncard ); - astWriteInt( channel, buff, 1, 1, *( ( (int *) data ) + 1 ), - "FITS keyword imaginary value" ); - } - } - -/* Write out the keyword comment. */ - if( CardComm( this, status ) ){ - (void) sprintf( buff, "Cm%d", ncard ); - astWriteString( channel, buff, 1, 1, CardComm( this, status ), - "FITS keyword comment" ); - } - -/* Move on to the next card. */ - ncard++; - MoveCard( this, 1, "astDump", class, status ); - } - -/* Dump any FitTables. */ - if( this->tables ) { - astWriteObject( channel, "Tables", 1, 1, this->tables, - "A KeyMap holding associated binary tables" ); - } - -/* Reinstate the original setting of the external ignore_used variable. */ - ignore_used = old_ignore_used; - -/* Reinstate the original current card. */ - astSetCard( this, icard ); -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ - -/* Implement the astIsAFitsChan and astCheckFitsChan functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(FitsChan,Channel) -astMAKE_CHECK(FitsChan) -AstFitsChan *astFitsChan_( const char *(* source)( void ), - void (* sink)( const char * ), - const char *options, int *status, ...) { - -/* -*++ -* Name: -c astFitsChan -f AST_FITSCHAN - -* Purpose: -* Create a FitsChan. - -* Type: -* Public function. - -* Synopsis: -c #include "fitschan.h" -c AstFitsChan *astFitsChan( const char *(* source)( void ), -c void (* sink)( const char * ), -c const char *options, ... ) -f RESULT = AST_FITSCHAN( SOURCE, SINK, OPTIONS, STATUS ) - -* Class Membership: -* FitsChan constructor. - -* Description: -* This function creates a new FitsChan and optionally initialises -* its attributes. -* -* A FitsChan is a specialised form of Channel which supports I/O -* operations involving the use of FITS (Flexible Image Transport -* System) header cards. Writing an Object to a FitsChan (using -c astWrite) will, if the Object is suitable, generate a -f AST_WRITE) will, if the Object is suitable, generate a -* description of that Object composed of FITS header cards, and -* reading from a FitsChan will create a new Object from its FITS -* header card description. -* -* While a FitsChan is active, it represents a buffer which may -* contain zero or more 80-character "header cards" conforming to -* FITS conventions. Any sequence of FITS-conforming header cards -* may be stored, apart from the "END" card whose existence is -* merely implied. The cards may be accessed in any order by using -* the FitsChan's integer Card attribute, which identifies a "current" -* card, to which subsequent operations apply. Searches -c based on keyword may be performed (using astFindFits), new -c cards may be inserted (astPutFits, astPutCards, astSetFits) and -c existing ones may be deleted (astDelFits) or changed (astSetFits). -f based on keyword may be performed (using AST_FINDFITS), new -f cards may be inserted (AST_PUTFITS, AST_PUTCARDS, AST_SETFITS) and -f existing ones may be deleted (AST_DELFITS) or changed (AST_SETFITS). -* -* When you create a FitsChan, you have the option of specifying -* "source" and "sink" functions which connect it to external data -* stores by reading and writing FITS header cards. If you provide -* a source function, it is used to fill the FitsChan with header cards -* when it is accessed for the first time. If you do not provide a -* source function, the FitsChan remains empty until you explicitly enter -c data into it (e.g. using astPutFits, astPutCards, astWrite -f data into it (e.g. using AST_PUTFITS, AST_PUTCARDS, AST_WRITE -* or by using the SourceFile attribute to specifying a text file from -* which headers should be read). When the FitsChan is deleted, any -* remaining header cards in the FitsChan can be saved in either of -* two ways: 1) by specifying a value for the SinkFile attribute (the -* name of a text file to which header cards should be written), or 2) -* by providing a sink function (used to to deliver header cards to an -* external data store). If you do not provide a sink function or a -* value for SinkFile, any header cards remaining when the FitsChan -* is deleted will be lost, so you should arrange to extract them -* first if necessary -c (e.g. using astFindFits or astRead). -f (e.g. using AST_FINDFITS or AST_READ). -* -* Coordinate system information may be described using FITS header -* cards using several different conventions, termed -* "encodings". When an AST Object is written to (or read from) a -* FitsChan, the value of the FitsChan's Encoding attribute -* determines how the Object is converted to (or from) a -* description involving FITS header cards. In general, different -* encodings will result in different sets of header cards to -* describe the same Object. Examples of encodings include the DSS -* encoding (based on conventions used by the STScI Digitised Sky -* Survey data), the FITS-WCS encoding (based on a proposed FITS -* standard) and the NATIVE encoding (a near loss-less way of -* storing AST Objects in FITS headers). -* -* The available encodings differ in the range of Objects they can -* represent, in the number of Object descriptions that can coexist -* in the same FitsChan, and in their accessibility to other -* (external) astronomy applications (see the Encoding attribute -* for details). Encodings are not necessarily mutually exclusive -* and it may sometimes be possible to describe the same Object in -* several ways within a particular set of FITS header cards by -* using several different encodings. -* -c The detailed behaviour of astRead and astWrite, when used with -f The detailed behaviour of AST_READ and AST_WRITE, when used with -* a FitsChan, depends on the encoding in use. In general, however, -c all use of astRead is destructive, so that FITS header cards -f all use of AST_READ is destructive, so that FITS header cards -* are consumed in the process of reading an Object, and are -* removed from the FitsChan (this deletion can be prevented for -* specific cards by calling the -c astRetainFits function). -f AST_RETAINFITS routine). -* -* If the encoding in use allows only a single Object description -* to be stored in a FitsChan (e.g. the DSS, FITS-WCS and FITS-IRAF -c encodings), then write operations using astWrite will -f encodings), then write operations using AST_WRITE will -* over-write any existing Object description using that -* encoding. Otherwise (e.g. the NATIVE encoding), multiple Object -* descriptions are written sequentially and may later be read -* back in the same sequence. - -* Parameters: -c source -f SOURCE = FUNCTION (Given) -c Pointer to a source function which takes no arguments and -c returns a pointer to a null-terminated string. This function -c will be used by the FitsChan to obtain input FITS header -c cards. On each invocation, it should read the next input card -c from some external source (such as a FITS file), and return a -c pointer to the (null-terminated) contents of the card. It -c should return a NULL pointer when there are no more cards to -c be read. -c -c If "source" is NULL, the FitsChan will remain empty until -c cards are explicitly stored in it (e.g. using astPutCards, -c astPutFits or via the SourceFile attribute). -f A source routine, which is a function taking two arguments: a -f character argument of length 80 to contain a FITS card, and an -f integer error status argument. It should return an integer value. -f This function will be used by the FitsChan to obtain input -f FITS header cards. On each invocation, it should read the -f next input card from some external source (such as a FITS -f file), and return the contents of the card via its character -f argument. It should return a function result of one unless -f there are no more cards to be read, in which case it should -f return zero. If an error occurs, it should set its error -f status argument to an error value before returning. -f -f If the null routine AST_NULL is supplied as the SOURCE value, -f the FitsChan will remain empty until cards are explicitly -f stored in it (e.g. using AST_PUTCARDS, AST_PUTFITS or via the -f SourceFile attribute). -c sink -f SINK = SUBROUTINE (Given) -c Pointer to a sink function that takes a pointer to a -c null-terminated string as an argument and returns void. If -c no value has been set for the SinkFile attribute, this -c function will be used by the FitsChan to deliver any FITS -c header cards it contains when it is finally deleted. On -c each invocation, it should deliver the contents of the character -c string passed to it as a FITS header card to some external -c data store (such as a FITS file). -f A sink routine, which is a subroutine which takes two -f arguments: a character argument of length 80 to contain a -f FITS card, and an integer error status argument. If no -f value has been set for the SinkFile attribute, this routine -f will be used by the FitsChan to deliver any FITS header cards -f it contains when it is finally deleted. On each invocation, -f it should deliver the contents of the character string passed -f to it as a FITS header card to some external data store (such -f as a FITS file). If an error occurs, it should set its error -f status argument to an error value before returning. -* -c If "sink" is NULL, -f If the null routine AST_NULL is supplied as the SINK value, -* and no value has been set for the SinkFile attribute, the -* contents of the FitsChan will be lost when it is deleted. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new FitsChan. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new FitsChan. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -* -* Note, the FITSCHAN_OPTIONS environment variable may be used -* to specify default options for all newly created FitsChans. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astFitsChan() -f AST_FITSCHAN = INTEGER -* A pointer to the new FitsChan. - -* Notes: -f - The names of the routines supplied for the SOURCE and SINK -f arguments should appear in EXTERNAL statements in the Fortran -f routine which invokes AST_FITSCHAN. However, this is not generally -f necessary for the null routine AST_NULL (so long as the AST_PAR -f include file has been used). -c - No FITS "END" card will be written via the sink function. You -f - No FITS "END" card will be written via the sink routine. You -* should add this card yourself after the FitsChan has been -* deleted. -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -f - Note that the null routine AST_NULL (one underscore) is -f different to AST__NULL (two underscores), which is the null Object -f pointer. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFitsChan *new; /* Pointer to new FitsChan */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the FitsChan, allocating memory and initialising the - virtual function table as well if necessary. This interface is for - use by other C functions within AST, and uses the standard "wrapper" - functions included in this class. */ - new = astInitFitsChan( NULL, sizeof( AstFitsChan ), !class_init, - &class_vtab, "FitsChan", source, SourceWrap, - sink, SinkWrap ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Apply any default options specified by "_OPTIONS" environment - variable. */ - astEnvSet( new ); - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - FitsChan's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new FitsChan. */ - return new; -} - -AstFitsChan *astFitsChanId_( const char *(* source)( void ), - void (* sink)( const char * ), - const char *options, ... ) { - -/* -* Name: -* astFitsChanId_ - -* Purpose: -* Create a FitsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "fitschan.h" -* AstFitsChan *astFitsChanId_( const char *(* source)( void ), -* void (* sink)( const char * ), -* const char *options, ... ) - -* Class Membership: -* FitsChan constructor. - -* Description: -* This function implements the external (public) C interface to the -* astFitsChan constructor function. Another function (astFitsChanForId) -* should be called to create a FitsChan for use within other languages. -* Both functions return an ID value (instead of a true C pointer) to -* external users, and must be provided because astFitsChan_ has a variable -* argument list which cannot be encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astFitsChan_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astFitsChan_. - -* Returned Value: -* The ID value associated with the new FitsChan. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFitsChan *new; /* Pointer to new FitsChan */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the FitsChan, allocating memory and initialising the - virtual function table as well if necessary. This interface is for - use by external C functions and uses the standard "wrapper" - functions included in this class. */ - new = astInitFitsChan( NULL, sizeof( AstFitsChan ), !class_init, - &class_vtab, "FitsChan", source, SourceWrap, - sink, SinkWrap ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Apply any default options specified by "_OPTIONS" environment - variable. */ - astEnvSet( new ); - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - FitsChan's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new FitsChan. */ - return astMakeId( new ); -} - -AstFitsChan *astFitsChanForId_( const char *(* source)( void ), - char *(* source_wrap)( const char *(*)( void ), int * ), - void (* sink)( const char * ), - void (* sink_wrap)( void (*)( const char * ), - const char *, int * ), - const char *options, ... ) { - -/* -*+ -* Name: -* astFitsChanFor - -* Purpose: -* Initialise a FitsChan from a foreign language interface. - -* Type: -* Public function. - -* Synopsis: -* #include "fitschan.h" -* AstFitsChan *astFitsChanFor( const char *(* source)( void ), -* char *(* source_wrap)( const char *(*) -* ( void ), int * ), -* void (* sink)( const char * ), -* void (* sink_wrap)( void (*)( const char * ), -* const char *, int * ), -* const char *options, ... ) - -* Class Membership: -* FitsChan constructor. - -* Description: -* This function creates a new FitsChan from a foreign language -* interface and optionally initialises its attributes. -* -* A FitsChan implements FITS input/output for the AST library. -* Writing an Object to a FitsChan (using astWrite) will generate a -* textual representation of that Object in terms of FITS header cards, -* and reading from a FitsChan (using astRead) will create a new Object -* from its FITS representation. -* -* Normally, when you use a FitsChan, you should provide "source" -* and "sink" functions which connect it to an external data store -* by reading and writing the resulting text. This function also -* requires you to provide "wrapper" functions which will invoke -* the source and sink functions. - -* Parameters: -* source -* Pointer to a "source" function which will be used to obtain -* FITS header cards. Generally, this will be obtained by -* casting a pointer to a source function which is compatible -* with the "source_wrap" wrapper function (below). The pointer -* should later be cast back to its original type by the -* "source_wrap" function before the function is invoked. -* -* If "source" is NULL, the FitsChan will remain empty until -* cards are added explicitly (e.g. using astPutCards or astPutFits). -* source_wrap -* Pointer to a function which can be used to invoke the -* "source" function supplied (above). This wrapper function is -* necessary in order to hide variations in the nature of the -* source function, such as may arise when it is supplied by a -* foreign (non-C) language interface. -* -* The single parameter of the "source_wrap" function is a -* pointer to the "source" function, and it should cast this -* function pointer (as necessary) and invoke the function with -* appropriate arguments to obtain the next FITS header card. -* The "source_wrap" function should then return a pointer -* to a dynamically allocated, null terminated string containing -* the text that was read. The string will be freed (using -* astFree) when no longer required and the "source_wrap" -* function need not concern itself with this. A NULL pointer -* should be returned if there is no more input to read. -* -* If "source" is NULL, the FitsChan will remain empty until -* cards are added explicitly (e.g. using astPutCards or astPutFits). -* sink -* Pointer to a "sink" function which will be used to deliver -* FITS header cards. Generally, this will be obtained by -* casting a pointer to a sink function which is compatible with -* the "sink_wrap" wrapper function (below). The pointer should -* later be cast back to its original type by the "sink_wrap" -* function before the function is invoked. -* -* If "sink" is NULL, the contents of the FitsChan will not be -* written out before being deleted. -* sink_wrap -* Pointer to a function which can be used to invoke the "sink" -* function supplied (above). This wrapper function is necessary -* in order to hide variations in the nature of the sink -* function, such as may arise when it is supplied by a foreign -* (non-C) language interface. -* -* The first parameter of the "sink_wrap" function is a pointer -* to the "sink" function, and the second parameter is a pointer -* to a const, null-terminated character string containing the -* text to be written. The "sink_wrap" function should cast the -* "sink" function pointer (as necessary) and invoke the -* function with appropriate arguments to deliver the line of -* output text. The "sink_wrap" function then returns void. -* -* If "sink_wrap" is NULL, the contents of the FitsChan will not be -* written out before being deleted. -* options -* Pointer to a null-terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new FitsChan. The syntax used is identical to -* that for the astSet function and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of additional arguments may follow it in -* order to supply values to be substituted for these -* specifiers. The rules for supplying these are identical to -* those for the astSet function (and for the C "printf" -* function). - -* Returned Value: -* astFitsChanFor() -* A pointer to the new FitsChan. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -* - This function is only available through the public interface -* to the FitsChan class (not the protected interface) and is -* intended solely for use in implementing foreign language -* interfaces to this class. -*- - -* Implememtation Notes: -* - This function behaves exactly like astFitsChanId_, in that it -* returns ID values and not true C pointers, but it has two -* additional arguments. These are pointers to the "wrapper -* functions" which are needed to accommodate foreign language -* interfaces. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFitsChan *new; /* Pointer to new FitsChan */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise the FitsChan, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitFitsChan( NULL, sizeof( AstFitsChan ), !class_init, - &class_vtab, "FitsChan", source, source_wrap, - sink, sink_wrap ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Apply any default options specified by "_OPTIONS" environment - variable. */ - astEnvSet( new ); - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - FitsChan's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new FitsChan. */ - return astMakeId( new ); -} - -AstFitsChan *astInitFitsChan_( void *mem, size_t size, int init, - AstFitsChanVtab *vtab, const char *name, - const char *(* source)( void ), - char *(* source_wrap)( const char *(*)( void ), int * ), - void (* sink)( const char * ), - void (* sink_wrap)( void (*)( const char * ), - const char *, int * ), int *status ) { - -/* -*+ -* Name: -* astInitFitsChan - -* Purpose: -* Initialise a FitsChan. - -* Type: -* Protected function. - -* Synopsis: -* #include "fitschan.h" -* AstFitsChan *astInitFitsChan_( void *mem, size_t size, int init, -* AstFitsChanVtab *vtab, const char *name, -* const char *(* source)( void ), -* char *(* source_wrap)( const char *(*)( void ), int * ), -* void (* sink)( const char * ), -* void (* sink_wrap)( void (*)( const char * ), -* const char *, int * ) ) - -* Class Membership: -* FitsChan initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new FitsChan object. It allocates memory (if -* necessary) to accommodate the FitsChan plus any additional data -* associated with the derived class. It then initialises a -* FitsChan structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual -* function table for a FitsChan at the start of the memory passed -* via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the FitsChan is to be -* initialised. This must be of sufficient size to accommodate -* the FitsChan data (sizeof(FitsChan)) plus any data used by the -* derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the FitsChan (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the FitsChan structure, so a valid value must be -* supplied even if not required for allocating memory. -* init -* A boolean flag indicating if the FitsChan's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new FitsChan. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* source -* Pointer to a "source" function which will be used to obtain -* FITS header cards. Generally, this will be obtained by -* casting a pointer to a source function which is compatible -* with the "source_wrap" wrapper function (below). The pointer -* should later be cast back to its original type by the -* "source_wrap" function before the function is invoked. -* -* If "source" is NULL, the FitsChan will remain empty until -* cards are added explicitly (e.g. using astPutCards or astPutFits). -* source_wrap -* Pointer to a function which can be used to invoke the -* "source" function supplied (above). This wrapper function is -* necessary in order to hide variations in the nature of the -* source function, such as may arise when it is supplied by a -* foreign (non-C) language interface. -* -* The single parameter of the "source_wrap" function is a -* pointer to the "source" function, and it should cast this -* function pointer (as necessary) and invoke the function with -* appropriate arguments to obtain the next FITS header card. -* The "source_wrap" function should then return a pointer -* to a dynamically allocated, null terminated string containing -* the text that was read. The string will be freed (using -* astFree) when no longer required and the "source_wrap" -* function need not concern itself with this. A NULL pointer -* should be returned if there is no more input to read. -* -* If "source" is NULL, the FitsChan will remain empty until -* cards are added explicitly (e.g. using astPutCards or astPutFits). -* sink -* Pointer to a "sink" function which will be used to deliver -* FITS header cards. Generally, this will be obtained by -* casting a pointer to a sink function which is compatible with -* the "sink_wrap" wrapper function (below). The pointer should -* later be cast back to its original type by the "sink_wrap" -* function before the function is invoked. -* -* If "sink" is NULL, the contents of the FitsChan will not be -* written out before being deleted. -* sink_wrap -* Pointer to a function which can be used to invoke the "sink" -* function supplied (above). This wrapper function is necessary -* in order to hide variations in the nature of the sink -* function, such as may arise when it is supplied by a foreign -* (non-C) language interface. -* -* The first parameter of the "sink_wrap" function is a pointer -* to the "sink" function, and the second parameter is a pointer -* to a const, null-terminated character string containing the -* text to be written. The "sink_wrap" function should cast the -* "sink" function pointer (as necessary) and invoke the -* function with appropriate arguments to deliver the line of -* output text. The "sink_wrap" function then returns void. -* -* If "sink_wrap" is NULL, the contents of the FitsChan will not be -* written out before being deleted. - -* Returned Value: -* A pointer to the new FitsChan. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstFitsChan *new; /* Pointer to new FitsChan */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitFitsChanVtab( vtab, name ); - -/* Initialise a Channel structure (the parent class) as the first - component within the FitsChan structure, allocating memory if - necessary. I am not sure why FitsChan has its own source_wrap and - sink_wrap items, rather than just using those inherited from Channel. - It may be possible to do away with the fitschan wrappers and just use - the channel wrapper, but I have not yet tried this. Old mail from RFWS - suggests that it may be because the F77 FitsChan source and sink - interfaces handle fixed length strings (80 characters), whereas - Channel sournce and sink handle variable length strings. This needs - investigating. */ - new = (AstFitsChan *) astInitChannel( mem, size, 0, - (AstChannelVtab *) vtab, name, - NULL, NULL, NULL, NULL ); - if ( astOK ) { - -/* Initialise the FitsChan data. */ -/* ---------------------------- */ - new->head = NULL; - new->card = NULL; - new->keyseq = NULL; - new->keywords = NULL; - new->defb1950 = -1; - new->tabok = -INT_MAX; - new->cdmatrix = -1; - new->carlin = -1; - new->sipreplace = -1; - new->fitstol = -1.0; - new->polytan = -INT_MAX; - new->sipok = -INT_MAX; - new->iwc = -1; - new->clean = -1; - new->fitsdigits = AST__DBL_DIG; - new->fitsaxisorder = NULL; - new->encoding = UNKNOWN_ENCODING; - new->warnings = NULL; - new->tables = NULL; - -/* Save the pointers to the source and sink functions and the wrapper - functions that invoke them. */ - new->source = source; - new->saved_source = NULL; - new->source_wrap = source_wrap; - new->sink = sink; - new->sink_wrap = sink_wrap; - new->tabsource = NULL; - new->tabsource_wrap = NULL; - -/* Rewind the FitsChan so that the next read operation will return the - first card. */ - new->card = new->head; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} -AstFitsChan *astLoadFitsChan_( void *mem, size_t size, - AstFitsChanVtab *vtab, const char *name, - AstChannel *channel, int *status ) { - -/* -*+ -* Name: -* astLoadFitsChan - -* Purpose: -* Load a FitsChan. - -* Type: -* Protected function. - -* Synopsis: -* #include "fitschan.h" -* AstFitsChan *astLoadFitsChan( void *mem, size_t size, -* AstFitsChanVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* FitsChan loader. - -* Description: -* This function is provided to load a new FitsChan using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* FitsChan structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a FitsChan at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the FitsChan is to be -* loaded. This must be of sufficient size to accommodate the -* FitsChan data (sizeof(FitsChan)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the FitsChan (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the FitsChan structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstFitsChan) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new FitsChan. If this is NULL, a pointer -* to the (static) virtual function table for the FitsChan class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "FitsChan" is used instead. - -* Returned Value: -* A pointer to the new FitsChan. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFitsChan *new; /* Pointer to the new FitsChan */ - char *comment; /* Pointer to keyword comment */ - char *keynm; /* Keyword name */ - char *text; /* Textual version of integer value */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - double dval[2]; /* Double precision data values */ - int flags; /* Keyword flags */ - int free_data; /* Should data memory be freed? */ - int ival[2]; /* Integer data values */ - int ncard; /* No. of FitsCards read so far */ - int type; /* Keyword type */ - void *data; /* Pointer to keyword data value */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this FitsChan. In this case the - FitsChan belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstFitsChan ); - vtab = &class_vtab; - name = "FitsChan"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitFitsChanVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built FitsChan. */ - new = astLoadChannel( mem, size, (AstChannelVtab *) vtab, name, - channel ); - if ( astOK ) { - -/* Read input data. */ -/* ================ */ - -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "FitsChan" ); - -/* Initialise the KeyMap holding the keywords in the FitsChan. */ - new->keywords = NULL; - -/* Initialise the list of keyword sequence numbers. */ - new->keyseq = NULL; - -/* Set the pointers to the source and sink functions, and their - wrapper functions, to NULL (we cannot restore these since they - refer to process-specific addresses). */ - new->source = NULL; - new->saved_source = NULL; - new->source_wrap = NULL; - new->sink = NULL; - new->sink_wrap = NULL; - new->tabsource = NULL; - new->tabsource_wrap = NULL; - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* Encoding. */ -/* --------- */ - text = astReadString( channel, "encod", UNKNOWN_STRING ); - if( text && strcmp( text, UNKNOWN_STRING ) ) { - new->encoding = FindString( MAX_ENCODING + 1, xencod, text, - "the FitsChan component 'Encod'", - "astRead", astGetClass( channel ), status ); - } else { - new->encoding = UNKNOWN_ENCODING; - } - if ( TestEncoding( new, status ) ) SetEncoding( new, new->encoding, status ); - text = astFree( text ); - -/* FitsAxisOrder. */ -/* -------------- */ - new->fitsaxisorder = astReadString( channel, "faxord", NULL ); - -/* FitsDigits. */ -/* ----------- */ - new->fitsdigits = astReadInt( channel, "fitsdg", AST__DBL_DIG ); - if ( TestFitsDigits( new, status ) ) SetFitsDigits( new, new->fitsdigits, status ); - -/* DefB1950 */ -/* -------- */ - new->defb1950 = astReadInt( channel, "dfb1950", -1 ); - if ( TestDefB1950( new, status ) ) SetDefB1950( new, new->defb1950, status ); - -/* TabOK */ -/* ----- */ - new->tabok = astReadInt( channel, "tabok", -INT_MAX ); - if ( TestTabOK( new, status ) ) SetTabOK( new, new->tabok, status ); - -/* CDMatrix */ -/* -------- */ - new->cdmatrix = astReadInt( channel, "cdmat", -1 ); - if ( TestCDMatrix( new, status ) ) SetCDMatrix( new, new->cdmatrix, status ); - -/* CarLin */ -/* ------ */ - new->carlin = astReadInt( channel, "carlin", -1 ); - if ( TestCarLin( new, status ) ) SetCarLin( new, new->carlin, status ); - -/* SipReplace */ -/* ---------- */ - new->sipreplace = astReadInt( channel, "sipreplace", -1 ); - if ( TestSipReplace( new, status ) ) SetSipReplace( new, new->sipreplace, status ); - -/* FitsTol */ -/* ------- */ - new->fitstol = astReadDouble( channel, "fitstol", -1.0 ); - if ( TestFitsTol( new, status ) ) SetFitsTol( new, new->fitstol, status ); - -/* PolyTan */ -/* ------- */ - new->polytan = astReadInt( channel, "polytan", -1 ); - if ( TestPolyTan( new, status ) ) SetPolyTan( new, new->polytan, status ); - -/* SipOK */ -/* ----- */ - new->sipok = astReadInt( channel, "sipok", -1 ); - if ( TestSipOK( new, status ) ) SetSipOK( new, new->sipok, status ); - -/* Iwc */ -/* --- */ - new->iwc = astReadInt( channel, "iwc", -1 ); - if ( TestIwc( new, status ) ) SetIwc( new, new->iwc, status ); - -/* Clean */ -/* ----- */ - new->clean = astReadInt( channel, "clean", -1 ); - if ( TestClean( new, status ) ) SetClean( new, new->clean, status ); - -/* Warnings. */ -/* --------- */ - new->warnings = astReadString( channel, "warn", NULL ); - -/* Card. */ -/* ----- */ - -/* Initialise the index of the card to be read next. */ - ncard = 1; - new->card = NULL; - new->head = NULL; - -/* Load each card. */ - type = AST__NOTYPE + 1; - while( type != AST__NOTYPE && astOK ){ - -/* Get the keyword type. */ - (void) sprintf( buff, "ty%d", ncard ); - text = astReadString( channel, buff, " " ); - if( strcmp( text, " " ) ) { - type = FindString( 9, type_names, text, - "a FitsChan keyword data type", - "astRead", astGetClass( channel ), status ); - } else { - type = AST__NOTYPE; - } - text = astFree( text ); - -/* Only proceed if the keyword type was found. */ - if( type != AST__NOTYPE ){ - -/* Get the keyword name. Use a default blank name. */ - (void) sprintf( buff, "nm%d", ncard ); - keynm = astReadString( channel, buff, " " ); - -/* Get the data value, using the appropriate data type, unless the - keyword is a comment keyword or is undefined. */ - free_data = 0; - if( type == AST__FLOAT ){ - (void) sprintf( buff, "dt%d", ncard ); - dval[ 0 ] = astReadDouble( channel, buff, AST__BAD ); - data = (void *) dval; - } else if( type == AST__STRING || type == AST__CONTINUE ){ - (void) sprintf( buff, "dt%d", ncard ); - data = (void *) astReadString( channel, buff, "" ); - free_data = 1; - } else if( type == AST__INT ){ - (void) sprintf( buff, "dt%d", ncard ); - ival[ 0 ] = astReadInt( channel, buff, 0 ); - data = (void *) ival; - } else if( type == AST__LOGICAL ){ - (void) sprintf( buff, "dt%d", ncard ); - ival[ 0 ] = astReadInt( channel, buff, 0 ); - data = (void *) ival; - } else if( type == AST__COMPLEXF ){ - (void) sprintf( buff, "dr%d", ncard ); - dval[ 0 ] = astReadDouble( channel, buff, AST__BAD ); - (void) sprintf( buff, "di%d", ncard ); - dval[ 1 ] = astReadDouble( channel, buff, AST__BAD ); - data = (void *) dval; - } else if( type == AST__COMPLEXI ){ - (void) sprintf( buff, "dr%d", ncard ); - ival[ 0 ] = astReadInt( channel, buff, 0 ); - (void) sprintf( buff, "di%d", ncard ); - ival[ 1 ] = astReadInt( channel, buff, 0 ); - data = (void *) ival; - } else { - data = NULL; - } - -/* Get the keyword flags (only written by versions of AST later than - V1.4). These are packed into an int. */ - (void) sprintf( buff, "fl%d", ncard ); - flags = astReadInt( channel, buff, 0 ); - -/* If the flags were not found, use the keyword deletion flag written by - AST V1.4 and earlier. */ - if( !flags ) { - (void) sprintf( buff, "dl%d", ncard ); - flags = astReadInt( channel, buff, 0 ); - } - -/* Get the keyword comment. */ - (void) sprintf( buff, "cm%d", ncard ); - comment = astReadString( channel, buff, NULL ); - -/* Append a new card to the output FitsChan. */ - NewCard( new, keynm, type, data, comment, flags, status ); - -/* Free the character strings, and data (if required). */ - comment = (char *) astFree( (void *) comment ); - keynm = (char *) astFree( (void *) keynm ); - if( free_data ) data = astFree( data ); - } - -/* Move on to the next card. */ - ncard++; - } - -/* Set up the current card index. */ - astSetCard( new, astReadInt( channel, "card", 0 ) ); - -/* Load any FitTables. */ - new->tables = astReadObject( channel, "tables", NULL ); - } - -/* If an error occurred, clean up by deleting the new FitsChan. */ - if ( !astOK ) new = astDelete( new ); - -/* Return the new FitsChan pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ - -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astWriteFits_( AstFitsChan *this, int *status ){ - if( !this ) return; - (**astMEMBER(this,FitsChan,WriteFits))(this, status ); -} - -void astReadFits_( AstFitsChan *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,ReadFits))(this, status ); -} - -void astEmptyFits_( AstFitsChan *this, int *status ){ - if( !this ) return; - (**astMEMBER(this,FitsChan,EmptyFits))(this, status ); -} - -void astShowFits_( AstFitsChan *this, int *status ){ - if( !this ) return; - (**astMEMBER(this,FitsChan,ShowFits))(this, status ); -} - -void astPutCards_( AstFitsChan *this, const char *cards, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,PutCards))(this,cards, status ); -} - -void astPutFits_( AstFitsChan *this, const char *card, int overwrite, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,PutFits))(this,card,overwrite, status ); -} - -void astDelFits_( AstFitsChan *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,DelFits))(this, status ); -} - -void astPurgeWCS_( AstFitsChan *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,PurgeWCS))(this, status ); -} - -AstKeyMap *astGetTables_( AstFitsChan *this, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,FitsChan,GetTables))(this, status ); -} - -void astPutTables_( AstFitsChan *this, AstKeyMap *tables, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,PutTables))(this, tables, status ); -} - -void astPutTable_( AstFitsChan *this, AstFitsTable *table, const char *extnam, - int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,PutTable))(this, table, extnam, status ); -} - -void astRemoveTables_( AstFitsChan *this, const char *key, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,RemoveTables))(this, key, status ); -} - -void astRetainFits_( AstFitsChan *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,RetainFits))(this, status ); -} - -int astFitsEof_( AstFitsChan *this, int *status ){ - if( !this ) return 1; - return (**astMEMBER(this,FitsChan,FitsEof))( this, status ); -} - -void astSetFitsCom_( AstFitsChan *this, const char *name, - const char *comment, int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsCom))( this, name, comment, overwrite, status ); -} - -void astSetFitsI_( AstFitsChan *this, const char *name, int value, - const char *comment, int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsI))( this, name, value, comment, overwrite, status ); -} - -void astSetFitsF_( AstFitsChan *this, const char *name, double value, - const char *comment, int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsF))( this, name, value, comment, overwrite, status ); -} - -void astSetFitsS_( AstFitsChan *this, const char *name, const char *value, - const char *comment, int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsS))( this, name, value, comment, overwrite, status ); -} - -void astSetFitsCN_( AstFitsChan *this, const char *name, const char *value, - const char *comment, int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsCN))( this, name, value, comment, overwrite, status ); -} - -void astSetFitsCF_( AstFitsChan *this, const char *name, double *value, - const char *comment, int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsCF))( this, name, value, comment, overwrite, status ); -} - -void astSetFitsCI_( AstFitsChan *this, const char *name, int *value, - const char *comment, int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsCI))( this, name, value, comment, overwrite, status ); -} - -void astSetFitsL_( AstFitsChan *this, const char *name, int value, - const char *comment, int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsL))( this, name, value, comment, overwrite, status ); -} - -void astSetFitsU_( AstFitsChan *this, const char *name, const char *comment, - int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsU))( this, name, comment, overwrite, status ); -} - -void astSetFitsCM_( AstFitsChan *this, const char *comment, int overwrite, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsChan,SetFitsCM))( this, comment, overwrite, status ); -} - -void astClearCard_( AstFitsChan *this, int *status ){ - if( !this ) return; - (**astMEMBER(this,FitsChan,ClearCard))( this, status ); -} - -void astSetCard_( AstFitsChan *this, int card, int *status ){ - if( !this ) return; - (**astMEMBER(this,FitsChan,SetCard))( this, card, status ); -} - -int astTestCard_( AstFitsChan *this, int *status ){ - if( !this ) return 0; - return (**astMEMBER(this,FitsChan,TestCard))( this, status ); -} - -int astGetCard_( AstFitsChan *this, int *status ){ - if( !this ) return 0; - return (**astMEMBER(this,FitsChan,GetCard))( this, status ); -} - -int astGetNcard_( AstFitsChan *this, int *status ){ - if( !this ) return 0; - return (**astMEMBER(this,FitsChan,GetNcard))( this, status ); -} - -int astGetCardType_( AstFitsChan *this, int *status ){ - if( !this ) return AST__NOTYPE; - return (**astMEMBER(this,FitsChan,GetCardType))( this, status ); -} - -const char *astGetCardComm_( AstFitsChan *this, int *status ){ - if( !this ) return NULL; - return (**astMEMBER(this,FitsChan,GetCardComm))( this, status ); -} - -const char *astGetCardName_( AstFitsChan *this, int *status ){ - if( !this ) return NULL; - return (**astMEMBER(this,FitsChan,GetCardName))( this, status ); -} - -int astGetNkey_( AstFitsChan *this, int *status ){ - if( !this ) return 0; - return (**astMEMBER(this,FitsChan,GetNkey))( this, status ); -} - -int astGetClean_( AstFitsChan *this, int *status ){ - if( !this ) return 0; - return (**astMEMBER(this,FitsChan,GetClean))( this, status ); -} - -const char *astGetAllWarnings_( AstFitsChan *this, int *status ){ - if( !this ) return NULL; - return (**astMEMBER(this,FitsChan,GetAllWarnings))( this, status ); -} - -int astGetFitsCF_( AstFitsChan *this, const char *name, double *value, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,GetFitsCF))( this, name, value, status ); -} - -int astGetFitsCI_( AstFitsChan *this, const char *name, int *value, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,GetFitsCI))( this, name, value, status ); -} - -int astGetFitsF_( AstFitsChan *this, const char *name, double *value, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,GetFitsF))( this, name, value, status ); -} - -int astGetFitsI_( AstFitsChan *this, const char *name, int *value, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,GetFitsI))( this, name, value, status ); -} - -int astGetFitsL_( AstFitsChan *this, const char *name, int *value, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,GetFitsL))( this, name, value, status ); -} - -int astTestFits_( AstFitsChan *this, const char *name, int *there, int *status ){ - if( there ) *there = 0; - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,TestFits))( this, name, there, status ); -} - -int astGetFitsS_( AstFitsChan *this, const char *name, char **value, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,GetFitsS))( this, name, value, status ); -} - -int astGetFitsCN_( AstFitsChan *this, const char *name, char **value, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,GetFitsCN))( this, name, value, status ); -} - -int astFitsGetCom_( AstFitsChan *this, const char *name, char **comment, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,FitsGetCom))( this, name, comment, status ); -} - -int astKeyFields_( AstFitsChan *this, const char *filter, int maxfld, - int *ubnd, int *lbnd, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,KeyFields))( this, filter, maxfld, - ubnd, lbnd, status ); -} - -int astFindFits_( AstFitsChan *this, const char *name, char *card, int inc, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,FindFits))( this, name, card, inc, status ); -} - -int astGetEncoding_( AstFitsChan *this, int *status ){ - if( !astOK ) return UNKNOWN_ENCODING; - return (**astMEMBER(this,FitsChan,GetEncoding))( this, status ); -} - -int astGetCDMatrix_( AstFitsChan *this, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,FitsChan,GetCDMatrix))( this, status ); -} -void astSetTableSource_( AstFitsChan *this, - void (*tabsource)( void ), - void (*tabsource_wrap)( void (*)( void ), - AstFitsChan *, const char *, - int, int, int * ), - int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,SetTableSource))( this, tabsource, - tabsource_wrap, status ); -} -void astTableSource_( AstFitsChan *this, - void (* tabsource)( AstFitsChan *, const char *, - int, int, int * ), - int *status ){ - if( !astOK ) return; - (**astMEMBER(this,FitsChan,TableSource))( this, tabsource, status ); -} - -/* - * A diagnostic function which lists the contents of a FitsChan to - * standard output. - */ - -/* -static void ListFC( AstFitsChan *, const char * ); - -static void ListFC( AstFitsChan *this, const char *ttl ) { - FitsCard *cardo; - char card[ 81 ]; - printf("%s\n----------------------------------------\n", ttl ); - cardo = (FitsCard *) this->card; - astClearCard( this ); - while( !astFitsEof( this ) && astOK ){ - FormatCard( this, card, "List" ); - if( this->card == cardo ) { - printf( "%s <<<<< currrent card <<<<< \n", card ); - } else { - printf( "%s\n", card ); - } - MoveCard( this, 1, "List", "FitsChan" ); - } - this->card = cardo; -} -*/ - - - - - - - - - - - - - - - diff --git a/ast/fitschan.h b/ast/fitschan.h deleted file mode 100644 index c3e9329..0000000 --- a/ast/fitschan.h +++ /dev/null @@ -1,933 +0,0 @@ -#if !defined( FITSCHAN_INCLUDED ) /* Include this file only once */ -#define FITSCHAN_INCLUDED -/* -*+ -* Name: -* fitschan.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the FitsChan class. - -* Invocation: -* #include "fitschan.h" - -* Description: -* This include file defines the interface to the FitsChan class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The FitsChan class provides facilities for reading and writing AST -* Objects in the form of FITS header cards. - -* Inheritance: -* The FitsChan class inherits from the Channel class. - -* Macros: - -* Protected: -* AST__NOTYPE -* Integer dentifier for an illegal FITS data type. -* AST__COMMENT -* Integer dentifier for a FITS comment keyword. -* AST__INT -* Integer dentifier for the integer FITS data type. -* AST__FLOAT -* Integer dentifier for the floating point FITS data type. -* AST__STRING -* Integer dentifier for the string FITS data type. -* AST__CONTINUE -* Integer dentifier for the continuation string FITS data type. -* AST__COMPLEXF -* Integer dentifier for the complex floating point FITS data type. -* AST__COMPLEXI -* Integer dentifier for the complex integer FITS data type. -* AST__LOGICAL -* Integer dentifier for the logical FITS data type. -* AST__UNDEF -* Integer dentifier for undefined FITS data type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 11-DEC-1996 (DSB): -* Original version. -* 30-Jun-1997 (DSB): -* Changed character pointer argument to character array in PutFits. -* 26-SEP-1997 (DSB): -* Added CDMatrix attribute. -* 21-OCT-1997 (DSB): -* o Renamed astFields as astKeyFields. -* 1-APR-2000 (DSB): -* Changes for CDi_j based FITS-WCS standard. -* 18-MAY-2000 (DSB): -* Added Warnings attribute. -* 4-APR-2001 (DSB): -* Added AllWarnings attribute. -* 20-FEB-2002 (DSB): -* Added CarLin attribute. -* 8-JAN-2003 (DSB): -* Added protected astInitFitsChanVtab method. -* 13-FEB-2003 (DSB): -* Added Clean attribute. -* 19-MAR-2004 (DSB): -* Added astPutCards function. -* 20-NOV-2017 (DSB): -* Added SipReplace attribute. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "channel.h" /* I/O channels (parent class) */ -#include "pointset.h" /* Defines AST__BAD */ -#include "keymap.h" /* Defines the AstKeyMap type */ - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros. */ -/* ------- */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -#define AST__NOTYPE -1 -#define AST__COMMENT 0 -#define AST__INT 1 -#define AST__FLOAT 2 -#define AST__STRING 3 -#define AST__COMPLEXF 4 -#define AST__COMPLEXI 5 -#define AST__LOGICAL 6 -#define AST__CONTINUE 7 -#define AST__UNDEF 8 - -#if defined(astCLASS) /* Protected */ - -/* Define constants used to size global arrays in this module. */ -#define AST__FITSCHAN_FITSCARDLEN 80 -#define AST__FITSCHAN_GETATTRIB_BUFF_LEN 50 - -#endif - -/* The EXTNAME value for FITS binary tables used to store coordinate arrays for - the -TAB algorithm. */ -#define AST_TABEXTNAME "WCS-TAB" - -/* Type Definitions. */ -/* ================= */ - -/* FitsChan structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -struct AstFitsChan; -typedef struct AstFitsChan { - -/* Attributes inherited from the parent class. */ - AstChannel channel; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int encoding; /* System for encoding AST objects ito FITS headers */ - int defb1950; /* Use FK4 B1950 as defaults? */ - int tabok; /* Support -TAB algorithm? */ - int cdmatrix; /* Use a CD matrix in FITS-WCS Encoding? */ - int polytan; /* Use distorted TAN convention? */ - int sipok; /* Use SIP distortion convention? */ - int carlin; /* Use linear CAR mappings? */ - int sipreplace; /* Replace SIP inverse coefficients? */ - double fitstol; /* Max departure from linearity, in pixels */ - int iwc; /* Include an IWC Frame? */ - int clean; /* Remove used cards even if an error occurs? */ - int fitsdigits; /* No. of decmial places in formatted floating point keyword values */ - char *fitsaxisorder; /* Pointer to a string defining WCS axis order */ - char *warnings; /* Pointer to a string containing warning conditions */ - void *card; /* Pointer to next FitsCard to be read */ - void *head; /* Pointer to first FitsCard in the circular linked list */ - AstKeyMap *keyseq; /* List of keyword sequence numbers used */ - AstKeyMap *keywords; /* A KeyMap holding the keywords in the FitsChan */ - AstKeyMap *tables; /* A KeyMap holding the binary tables in the FitsChan */ - - const char *(* source)( void ); /* Pointer to source function */ - const char *(* saved_source)( void ); /* Pointer to saved source function */ - char *(* source_wrap)( const char *(*)( void ), int * ); - /* Source wrapper function pointer */ - - void (* sink)( const char * ); /* Pointer to sink function */ - void (* sink_wrap)( void (*)( const char * ), const char *, int * ); - /* Sink wrapper function pointer */ - - void (* tabsource)( void ); /* Pointer to table source function */ - void (* tabsource_wrap)( void (*)( void ), struct AstFitsChan *, const char *, int, int, int * ); - /* Table source wrapper function pointer */ - -} AstFitsChan; - -/* Virtual function table. */ -/* ----------------------- */ -/* The virtual function table makes a forward reference to the - AstFitsTable structure which is not defined until "fitstable.h" is - included (below). Hence make a preliminary definition available - now. */ -struct AstFitsTable; - -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstFitsChanVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstChannelVtab channel_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstKeyMap *(* GetTables)( AstFitsChan *, int * ); - int (* FindFits)( AstFitsChan *, const char *, char [81], int, int * ); - int (* FitsEof)( AstFitsChan *, int * ); - int (* FitsGetCom)( AstFitsChan *, const char *, char **, int * ); - int (* GetFitsCF)( AstFitsChan *, const char *, double *, int * ); - int (* GetFitsCI)( AstFitsChan *, const char *, int *, int * ); - int (* GetFitsCN)( AstFitsChan *, const char *, char **, int * ); - int (* GetFitsF)( AstFitsChan *, const char *, double *, int * ); - int (* GetFitsI)( AstFitsChan *, const char *, int *, int * ); - int (* GetFitsL)( AstFitsChan *, const char *, int *, int * ); - int (* GetFitsS)( AstFitsChan *, const char *, char **, int * ); - int (* KeyFields)( AstFitsChan *, const char *, int, int *, int *, int * ); - int (* TestFits)( AstFitsChan *, const char *, int *, int * ); - void (* DelFits)( AstFitsChan *, int * ); - void (* Empty)( AstFitsChan *, int * ); - void (* ReadFits)( AstFitsChan *, int * ); - void (* WriteFits)( AstFitsChan *, int * ); - void (* EmptyFits)( AstFitsChan *, int * ); - void (* ShowFits)( AstFitsChan *, int * ); - void (* PurgeWCS)( AstFitsChan *, int * ); - void (* PutCards)( AstFitsChan *, const char *, int * ); - void (* PutFits)( AstFitsChan *, const char [81], int, int * ); - void (* PutTable)( AstFitsChan *, struct AstFitsTable *, const char *, int * ); - void (* PutTables)( AstFitsChan *, AstKeyMap *, int * ); - void (* RemoveTables)( AstFitsChan *, const char *, int * ); - void (* RetainFits)( AstFitsChan *, int * ); - void (* SetFitsCF)( AstFitsChan *, const char *, double *, const char *, int, int * ); - void (* SetFitsCI)( AstFitsChan *, const char *, int *, const char *, int, int * ); - void (* SetFitsCM)( AstFitsChan *, const char *, int, int * ); - void (* SetFitsCN)( AstFitsChan *, const char *, const char *, const char *, int, int * ); - void (* SetFitsCom)( AstFitsChan *, const char *, const char *, int, int * ); - void (* SetFitsF)( AstFitsChan *, const char *, double, const char *, int, int * ); - void (* SetFitsI)( AstFitsChan *, const char *, int, const char *, int, int * ); - void (* SetFitsL)( AstFitsChan *, const char *, int, const char *, int, int * ); - void (* SetFitsS)( AstFitsChan *, const char *, const char *, const char *, int, int * ); - void (* SetFitsU)( AstFitsChan *, const char *, const char *, int, int * ); - - int (* GetCard)( AstFitsChan *, int * ); - int (* TestCard)( AstFitsChan *, int * ); - void (* SetCard)( AstFitsChan *, int, int * ); - void (* ClearCard)( AstFitsChan *, int * ); - - int (* GetFitsDigits)( AstFitsChan *, int * ); - int (* TestFitsDigits)( AstFitsChan *, int * ); - void (* SetFitsDigits)( AstFitsChan *, int, int * ); - void (* ClearFitsDigits)( AstFitsChan *, int * ); - - const char *(* GetFitsAxisOrder)( AstFitsChan *, int * ); - int (* TestFitsAxisOrder)( AstFitsChan *, int * ); - void (* SetFitsAxisOrder)( AstFitsChan *, const char *, int * ); - void (* ClearFitsAxisOrder)( AstFitsChan *, int * ); - - int (* GetDefB1950)( AstFitsChan *, int * ); - int (* TestDefB1950)( AstFitsChan *, int * ); - void (* SetDefB1950)( AstFitsChan *, int, int * ); - void (* ClearDefB1950)( AstFitsChan *, int * ); - - int (* GetTabOK)( AstFitsChan *, int * ); - int (* TestTabOK)( AstFitsChan *, int * ); - void (* SetTabOK)( AstFitsChan *, int, int * ); - void (* ClearTabOK)( AstFitsChan *, int * ); - - int (* GetCarLin)( AstFitsChan *, int * ); - int (* TestCarLin)( AstFitsChan *, int * ); - void (* SetCarLin)( AstFitsChan *, int, int * ); - void (* ClearCarLin)( AstFitsChan *, int * ); - - int (* GetSipReplace)( AstFitsChan *, int * ); - int (* TestSipReplace)( AstFitsChan *, int * ); - void (* SetSipReplace)( AstFitsChan *, int, int * ); - void (* ClearSipReplace)( AstFitsChan *, int * ); - - double (* GetFitsTol)( AstFitsChan *, int * ); - int (* TestFitsTol)( AstFitsChan *, int * ); - void (* SetFitsTol)( AstFitsChan *, double, int * ); - void (* ClearFitsTol)( AstFitsChan *, int * ); - - int (* GetNcard)( AstFitsChan *, int * ); - - int (* GetCardType)( AstFitsChan *, int * ); - const char *(* GetCardName)( AstFitsChan *, int * ); - const char *(* GetCardComm)( AstFitsChan *, int * ); - - int (* GetNkey)( AstFitsChan *, int * ); - - int (* GetEncoding)( AstFitsChan *, int * ); - int (* TestEncoding)( AstFitsChan *, int * ); - void (* SetEncoding)( AstFitsChan *, int, int * ); - void (* ClearEncoding)( AstFitsChan *, int * ); - - const char *(* GetAllWarnings)( AstFitsChan *, int * ); - - const char *(* GetWarnings)( AstFitsChan *, int * ); - int (* TestWarnings)( AstFitsChan *, int * ); - void (* ClearWarnings)( AstFitsChan *, int * ); - void (* SetWarnings)( AstFitsChan *, const char *, int * ); - - int (* GetClean)( AstFitsChan *, int * ); - int (* TestClean)( AstFitsChan *, int * ); - void (* SetClean)( AstFitsChan *, int, int * ); - void (* ClearClean)( AstFitsChan *, int * ); - - int (* GetCDMatrix)( AstFitsChan *, int * ); - int (* TestCDMatrix)( AstFitsChan *, int * ); - void (* SetCDMatrix)( AstFitsChan *, int, int * ); - void (* ClearCDMatrix)( AstFitsChan *, int * ); - - int (* GetPolyTan)( AstFitsChan *, int * ); - int (* TestPolyTan)( AstFitsChan *, int * ); - void (* SetPolyTan)( AstFitsChan *, int, int * ); - void (* ClearPolyTan)( AstFitsChan *, int * ); - - int (* GetSipOK)( AstFitsChan *, int * ); - int (* TestSipOK)( AstFitsChan *, int * ); - void (* SetSipOK)( AstFitsChan *, int, int * ); - void (* ClearSipOK)( AstFitsChan *, int * ); - - int (* GetIwc)( AstFitsChan *, int * ); - int (* TestIwc)( AstFitsChan *, int * ); - void (* SetIwc)( AstFitsChan *, int, int * ); - void (* ClearIwc)( AstFitsChan *, int * ); - - void (* SetTableSource)( AstFitsChan *, - void (*)( void ), - void (*)( void (*)( void ), - AstFitsChan *, const char *, int, - int, int * ), - int * ); - - void (* TableSource)( AstFitsChan *, - void (*)( AstFitsChan *, const char *, int, int, - int * ), - int * ); - -} AstFitsChanVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstFitsChanGlobals { - AstFitsChanVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ AST__FITSCHAN_GETATTRIB_BUFF_LEN + 1 ]; - char CnvType_Text[ AST__FITSCHAN_FITSCARDLEN + 1 ]; - char CnvType_Text0[ AST__FITSCHAN_FITSCARDLEN + 1 ]; - char CnvType_Text1[ AST__FITSCHAN_FITSCARDLEN + 1 ]; - int Items_Written; - int Write_Nest; - int Current_Indent; - int Ignore_Used; - int Mark_New; - int CreateKeyword_Seq_Nchars; - char FormatKey_Buff[ 10 ]; - char FitsGetCom_Sval[ AST__FITSCHAN_FITSCARDLEN + 1 ]; - const char *IsSpectral_Ret; - char Match_Fmt[ 10 ]; - const char *Match_Template; - int *Match_PA; - int *Match_PB; - int Match_NA; - int Match_NB; - int Match_Nentry; - char WcsCelestial_Type[ 4 ]; -} AstFitsChanGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(FitsChan) /* Check class membership */ -astPROTO_ISA(FitsChan) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstFitsChan *astFitsChan_( const char *(*)( void ), void (*)( const char * ), - const char *, int *, ...); -#else -AstFitsChan *astFitsChanId_( const char *(*)( void ), void (*)( const char * ), - const char *, ... )__attribute__((format(printf,3,4))); -AstFitsChan *astFitsChanForId_( const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), - const char *, int * ), - const char *, ... ); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstFitsChan *astInitFitsChan_( void *, size_t, int, AstFitsChanVtab *, - const char *, - const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), const char *, int * ), int * ); - -/* Vtab initialiser. */ -void astInitFitsChanVtab_( AstFitsChanVtab *, const char *, int * ); - - - -/* Loader. */ -AstFitsChan *astLoadFitsChan_( void *, size_t, AstFitsChanVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitFitsChanGlobals_( AstFitsChanGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - AstKeyMap *astGetTables_( AstFitsChan *, int * ); - int astFindFits_( AstFitsChan *, const char *, char [81], int, int * ); - int astGetFitsCF_( AstFitsChan *, const char *, double *, int * ); - int astGetFitsCI_( AstFitsChan *, const char *, int *, int * ); - int astGetFitsCN_( AstFitsChan *, const char *, char **, int * ); - int astGetFitsF_( AstFitsChan *, const char *, double *, int * ); - int astGetFitsI_( AstFitsChan *, const char *, int *, int * ); - int astGetFitsL_( AstFitsChan *, const char *, int *, int * ); - int astGetFitsS_( AstFitsChan *, const char *, char **, int * ); - int astTestFits_( AstFitsChan *, const char *, int *, int * ); - void astDelFits_( AstFitsChan *, int * ); - void astReadFits_( AstFitsChan *, int * ); - void astWriteFits_( AstFitsChan *, int * ); - void astEmptyFits_( AstFitsChan *, int * ); - void astShowFits_( AstFitsChan *, int * ); - void astPurgeWCS_( AstFitsChan *, int * ); - void astPutCards_( AstFitsChan *, const char *, int * ); - void astPutFits_( AstFitsChan *, const char [81], int, int * ); - void astPutTable_( AstFitsChan *, struct AstFitsTable *, const char *, int * ); - void astPutTables_( AstFitsChan *, AstKeyMap *, int * ); - void astRemoveTables_( AstFitsChan *, const char *, int * ); - void astRetainFits_( AstFitsChan *, int * ); - void astSetFitsCF_( AstFitsChan *, const char *, double *, const char *, int, int * ); - void astSetFitsCI_( AstFitsChan *, const char *, int *, const char *, int, int * ); - void astSetFitsCM_( AstFitsChan *, const char *, int, int * ); - void astSetFitsCN_( AstFitsChan *, const char *, const char *, const char *, int, int * ); - void astSetFitsF_( AstFitsChan *, const char *, double, const char *, int, int * ); - void astSetFitsI_( AstFitsChan *, const char *, int, const char *, int, int * ); - void astSetFitsL_( AstFitsChan *, const char *, int, const char *, int, int * ); - void astSetFitsS_( AstFitsChan *, const char *, const char *, const char *, int, int * ); - void astSetFitsU_( AstFitsChan *, const char *, const char *, int, int * ); - - void astTableSource_( AstFitsChan *, - void (*)( AstFitsChan *, const char *, int, int, int * ), - int * ); - - - -# if defined(astCLASS) || defined(astFORTRAN77) /* Protected or F77 interface */ - void astSetTableSource_( AstFitsChan *, - void (*)( void ), - void (*)( void (*)( void ), - AstFitsChan *, const char *, int, - int, int * ), - int * ); - -#endif - -# if defined(astCLASS) /* Protected */ - - int astFitsEof_( AstFitsChan *, int * ); - int astFitsGetCom_( AstFitsChan *, const char *, char **, int * ); - void astSetFitsCom_( AstFitsChan *, const char *, const char *, int, int * ); - - int astKeyFields_( AstFitsChan *, const char *, int, int *, int *, int * ); - - int astGetCard_( AstFitsChan *, int * ); - int astTestCard_( AstFitsChan *, int * ); - void astSetCard_( AstFitsChan *, int, int * ); - void astClearCard_( AstFitsChan *, int * ); - - int astGetDefB1950_( AstFitsChan *, int * ); - int astTestDefB1950_( AstFitsChan *, int * ); - void astSetDefB1950_( AstFitsChan *, int, int * ); - void astClearDefB1950_( AstFitsChan *, int * ); - - int astGetTabOK_( AstFitsChan *, int * ); - int astTestTabOK_( AstFitsChan *, int * ); - void astSetTabOK_( AstFitsChan *, int, int * ); - void astClearTabOK_( AstFitsChan *, int * ); - - int astGetCDMatrix_( AstFitsChan *, int * ); - int astTestCDMatrix_( AstFitsChan *, int * ); - void astSetCDMatrix_( AstFitsChan *, int, int * ); - void astClearCDMatrix_( AstFitsChan *, int * ); - - int astGetPolyTan_( AstFitsChan *, int * ); - int astTestPolyTan_( AstFitsChan *, int * ); - void astSetPolyTan_( AstFitsChan *, int, int * ); - void astClearPolyTan_( AstFitsChan *, int * ); - - int astGetSipReplace_( AstFitsChan *, int * ); - int astTestSipReplace_( AstFitsChan *, int * ); - void astSetSipReplace_( AstFitsChan *, int, int * ); - void astClearSipReplace_( AstFitsChan *, int * ); - - int astGetSipOK_( AstFitsChan *, int * ); - int astTestSipOK_( AstFitsChan *, int * ); - void astSetSipOK_( AstFitsChan *, int, int * ); - void astClearSipOK_( AstFitsChan *, int * ); - - int astGetCarLin_( AstFitsChan *, int * ); - int astTestCarLin_( AstFitsChan *, int * ); - void astSetCarLin_( AstFitsChan *, int, int * ); - void astClearCarLin_( AstFitsChan *, int * ); - - double astGetFitsTol_( AstFitsChan *, int * ); - int astTestFitsTol_( AstFitsChan *, int * ); - void astSetFitsTol_( AstFitsChan *, double, int * ); - void astClearFitsTol_( AstFitsChan *, int * ); - - int astGetIwc_( AstFitsChan *, int * ); - int astTestIwc_( AstFitsChan *, int * ); - void astSetIwc_( AstFitsChan *, int, int * ); - void astClearIwc_( AstFitsChan *, int * ); - - int astGetClean_( AstFitsChan *, int * ); - int astTestClean_( AstFitsChan *, int * ); - void astSetClean_( AstFitsChan *, int, int * ); - void astClearClean_( AstFitsChan *, int * ); - - int astGetFitsDigits_( AstFitsChan *, int * ); - int astTestFitsDigits_( AstFitsChan *, int * ); - void astSetFitsDigits_( AstFitsChan *, int, int * ); - void astClearFitsDigits_( AstFitsChan *, int * ); - - const char *astGetFitsAxisOrder_( AstFitsChan *, int * ); - int astTestFitsAxisOrder_( AstFitsChan *, int * ); - void astSetFitsAxisOrder_( AstFitsChan *, const char *, int * ); - void astClearFitsAxisOrder_( AstFitsChan *, int * ); - - const char *astGetAllWarnings_( AstFitsChan *, int * ); - - const char *astGetWarnings_( AstFitsChan *, int * ); - int astTestWarnings_( AstFitsChan *, int * ); - void astClearWarnings_( AstFitsChan *, int * ); - void astSetWarnings_( AstFitsChan *, const char *, int * ); - - int astGetNcard_( AstFitsChan *, int * ); - - int astGetCardType_( AstFitsChan *, int * ); - const char *astGetCardName_( AstFitsChan *, int * ); - const char *astGetCardComm_( AstFitsChan *, int * ); - - int astGetNkey_( AstFitsChan *, int * ); - - int astGetEncoding_( AstFitsChan *, int * ); - int astTestEncoding_( AstFitsChan *, int * ); - void astSetEncoding_( AstFitsChan *, int, int * ); - void astClearEncoding_( AstFitsChan *, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckFitsChan(this) astINVOKE_CHECK(FitsChan,this,0) -#define astVerifyFitsChan(this) astINVOKE_CHECK(FitsChan,this,1) - -/* Test class membership. */ -#define astIsAFitsChan(this) astINVOKE_ISA(FitsChan,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astFitsChan astINVOKE(F,astFitsChan_) -#else -#define astFitsChan astINVOKE(F,astFitsChanId_) -#define astFitsChanFor astINVOKE(F,astFitsChanForId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitFitsChan(mem,size,init,vtab,name,source,sourcewrap,sink,sinkwrap) \ -astINVOKE(O,astInitFitsChan_(mem,size,init,vtab,name,source,sourcewrap,sink,sinkwrap,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitFitsChanVtab(vtab,name) astINVOKE(V,astInitFitsChanVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadFitsChan(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadFitsChan_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - - -/* More include files. */ -/* =================== */ -/* The interface to the FitsTable class must be included here (after the - type definitions for the FitsChan class) because "fitstable.h" itself - includes this file ("fitschan.h"), although "fitschan.h" refers to the - AstFitsTable structure above. This seems a little strange at first, - but is simply analogous to making a forward reference to a - structure type when recursively defining a normal C structure - (except that here the definitions happen to be in separate include - files). */ -#include "fitstable.h" - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckFitsChan to validate FitsChan pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astPutFits(this,card,overwrite) \ -astINVOKE(V,astPutFits_(astCheckFitsChan(this),card,overwrite,STATUS_PTR)) - -#define astPutCards(this,cards) \ -astINVOKE(V,astPutCards_(astCheckFitsChan(this),cards,STATUS_PTR)) - -#define astDelFits(this) \ -astINVOKE(V,astDelFits_(astCheckFitsChan(this),STATUS_PTR)) - -#define astPurgeWCS(this) \ -astINVOKE(V,astPurgeWCS_(astCheckFitsChan(this),STATUS_PTR)) - -#define astGetTables(this) \ -astINVOKE(O,astGetTables_(astCheckFitsChan(this),STATUS_PTR)) - -#define astPutTable(this,table,extnam) \ -astINVOKE(V,astPutTable_(astCheckFitsChan(this),astCheckFitsTable(table),extnam,STATUS_PTR)) - -#define astPutTables(this,tables) \ -astINVOKE(V,astPutTables_(astCheckFitsChan(this),astCheckKeyMap(tables),STATUS_PTR)) - -#define astRemoveTables(this,key) \ -astINVOKE(V,astRemoveTables_(astCheckFitsChan(this),key,STATUS_PTR)) - -#define astRetainFits(this) \ -astINVOKE(V,astRetainFits_(astCheckFitsChan(this),STATUS_PTR)) - -#define astFindFits( this, name, card, inc ) \ -astINVOKE(V,astFindFits_(astCheckFitsChan(this),name,card,inc,STATUS_PTR)) - -#define astSetFitsI(this,name,value,comment,overwrite) \ -astINVOKE(V,astSetFitsI_(astCheckFitsChan(this),name,value,comment,overwrite,STATUS_PTR)) - -#define astSetFitsF(this,name,value,comment,overwrite) \ -astINVOKE(V,astSetFitsF_(astCheckFitsChan(this),name,value,comment,overwrite,STATUS_PTR)) - -#define astSetFitsS(this,name,value,comment,overwrite) \ -astINVOKE(V,astSetFitsS_(astCheckFitsChan(this),name,value,comment,overwrite,STATUS_PTR)) - -#define astSetFitsCN(this,name,value,comment,overwrite) \ -astINVOKE(V,astSetFitsCN_(astCheckFitsChan(this),name,value,comment,overwrite,STATUS_PTR)) - -#define astSetFitsCI(this,name,value,comment,overwrite) \ -astINVOKE(V,astSetFitsCI_(astCheckFitsChan(this),name,value,comment,overwrite,STATUS_PTR)) - -#define astSetFitsCF(this,name,value,comment,overwrite) \ -astINVOKE(V,astSetFitsCF_(astCheckFitsChan(this),name,value,comment,overwrite,STATUS_PTR)) - -#define astSetFitsL(this,name,value,comment,overwrite) \ -astINVOKE(V,astSetFitsL_(astCheckFitsChan(this),name,value,comment,overwrite,STATUS_PTR)) - -#define astSetFitsU(this,name,comment,overwrite) \ -astINVOKE(V,astSetFitsU_(astCheckFitsChan(this),name,comment,overwrite,STATUS_PTR)) - -#define astSetFitsCM(this,comment,overwrite) \ -astINVOKE(V,astSetFitsCM_(astCheckFitsChan(this),comment,overwrite,STATUS_PTR)) - -#define astGetFitsCF(this,name,value) \ -astINVOKE(V,astGetFitsCF_(astCheckFitsChan(this),name,value,STATUS_PTR)) - -#define astGetFitsCI(this,name,value) \ -astINVOKE(V,astGetFitsCI_(astCheckFitsChan(this),name,value,STATUS_PTR)) - -#define astGetFitsF(this,name,value) \ -astINVOKE(V,astGetFitsF_(astCheckFitsChan(this),name,value,STATUS_PTR)) - -#define astGetFitsI(this,name,value) \ -astINVOKE(V,astGetFitsI_(astCheckFitsChan(this),name,value,STATUS_PTR)) - -#define astGetFitsL(this,name,value) \ -astINVOKE(V,astGetFitsL_(astCheckFitsChan(this),name,value,STATUS_PTR)) - -#define astTestFits(this,name,there) \ -astINVOKE(V,astTestFits_(astCheckFitsChan(this),name,there,STATUS_PTR)) - -#define astGetFitsS(this,name,value) \ -astINVOKE(V,astGetFitsS_(astCheckFitsChan(this),name,value,STATUS_PTR)) - -#define astGetFitsCN(this,name,value) \ -astINVOKE(V,astGetFitsCN_(astCheckFitsChan(this),name,value,STATUS_PTR)) - -#define astReadFits(this) \ -astINVOKE(V,astReadFits_(astCheckFitsChan(this),STATUS_PTR)) - -#define astWriteFits(this) \ -astINVOKE(V,astWriteFits_(astCheckFitsChan(this),STATUS_PTR)) - -#define astEmptyFits(this) \ -astINVOKE(V,astEmptyFits_(astCheckFitsChan(this),STATUS_PTR)) - -#define astShowFits(this) \ -astINVOKE(V,astShowFits_(astCheckFitsChan(this),STATUS_PTR)) - -#define astTableSource(this,tabsource) \ -astINVOKE(V,astTableSource_(astCheckFitsChan(this),tabsource,STATUS_PTR)) - - -#if defined(astCLASS) || defined(astFORTRAN77) /* Protected or F77 interface */ - -#define astSetTableSource(this,tabsource,tabsource_wrap) \ -astINVOKE(V,astSetTableSource_(astCheckFitsChan(this),tabsource,tabsource_wrap,STATUS_PTR)) - -#endif - - -#if defined(astCLASS) /* Protected */ - -#define astFitsEof(this) \ -astINVOKE(V,astFitsEof_(astCheckFitsChan(this),STATUS_PTR)) - -#define astFitsGetCom(this,name,comment) \ -astINVOKE(V,astFitsGetCom_(astCheckFitsChan(this),name,comment,STATUS_PTR)) - -#define astSetFitsCom(this,name,comment,overwrite) \ -astINVOKE(V,astSetFitsCom_(astCheckFitsChan(this),name,comment,overwrite,STATUS_PTR)) - -#define astKeyFields(this,filter,maxfld,ubnd,lbnd) \ -astINVOKE(V,astKeyFields_(astCheckFitsChan(this),filter,maxfld,ubnd,lbnd,STATUS_PTR)) - -#define astClearCard(this) \ -astINVOKE(V,astClearCard_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetCard(this) \ -astINVOKE(V,astGetCard_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetCard(this,card) \ -astINVOKE(V,astSetCard_(astCheckFitsChan(this),card,STATUS_PTR)) -#define astTestCard(this) \ -astINVOKE(V,astTestCard_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearDefB1950(this) \ -astINVOKE(V,astClearDefB1950_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetDefB1950(this) \ -astINVOKE(V,astGetDefB1950_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetDefB1950(this,defb950) \ -astINVOKE(V,astSetDefB1950_(astCheckFitsChan(this),defb950,STATUS_PTR)) -#define astTestDefB1950(this) \ -astINVOKE(V,astTestDefB1950_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearTabOK(this) \ -astINVOKE(V,astClearTabOK_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetTabOK(this) \ -astINVOKE(V,astGetTabOK_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetTabOK(this,tabok) \ -astINVOKE(V,astSetTabOK_(astCheckFitsChan(this),tabok,STATUS_PTR)) -#define astTestTabOK(this) \ -astINVOKE(V,astTestTabOK_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearCDMatrix(this) \ -astINVOKE(V,astClearCDMatrix_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetCDMatrix(this) \ -astINVOKE(V,astGetCDMatrix_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetCDMatrix(this,cdmatrix) \ -astINVOKE(V,astSetCDMatrix_(astCheckFitsChan(this),cdmatrix,STATUS_PTR)) -#define astTestCDMatrix(this) \ -astINVOKE(V,astTestCDMatrix_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearPolyTan(this) \ -astINVOKE(V,astClearPolyTan_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetPolyTan(this) \ -astINVOKE(V,astGetPolyTan_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetPolyTan(this,value) \ -astINVOKE(V,astSetPolyTan_(astCheckFitsChan(this),value,STATUS_PTR)) -#define astTestPolyTan(this) \ -astINVOKE(V,astTestPolyTan_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearSipOK(this) \ -astINVOKE(V,astClearSipOK_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetSipOK(this) \ -astINVOKE(V,astGetSipOK_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetSipOK(this,value) \ -astINVOKE(V,astSetSipOK_(astCheckFitsChan(this),value,STATUS_PTR)) -#define astTestSipOK(this) \ -astINVOKE(V,astTestSipOK_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearCarLin(this) \ -astINVOKE(V,astClearCarLin_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetCarLin(this) \ -astINVOKE(V,astGetCarLin_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetCarLin(this,carln) \ -astINVOKE(V,astSetCarLin_(astCheckFitsChan(this),carln,STATUS_PTR)) -#define astTestCarLin(this) \ -astINVOKE(V,astTestCarLin_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearSipReplace(this) \ -astINVOKE(V,astClearSipReplace_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetSipReplace(this) \ -astINVOKE(V,astGetSipReplace_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetSipReplace(this,siprep) \ -astINVOKE(V,astSetSipReplace_(astCheckFitsChan(this),siprep,STATUS_PTR)) -#define astTestSipReplace(this) \ -astINVOKE(V,astTestSipReplace_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearFitsTol(this) \ -astINVOKE(V,astClearFitsTol_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetFitsTol(this) \ -astINVOKE(V,astGetFitsTol_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetFitsTol(this,fitstl) \ -astINVOKE(V,astSetFitsTol_(astCheckFitsChan(this),fitstl,STATUS_PTR)) -#define astTestFitsTol(this) \ -astINVOKE(V,astTestFitsTol_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearClean(this) \ -astINVOKE(V,astClearClean_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetClean(this) \ -astINVOKE(V,astGetClean_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetClean(this,value) \ -astINVOKE(V,astSetClean_(astCheckFitsChan(this),value,STATUS_PTR)) -#define astTestClean(this) \ -astINVOKE(V,astTestClean_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearFitsDigits(this) \ -astINVOKE(V,astClearFitsDigits_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetFitsDigits(this) \ -astINVOKE(V,astGetFitsDigits_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetFitsDigits(this,fitsdigits) \ -astINVOKE(V,astSetFitsDigits_(astCheckFitsChan(this),fitsdigits,STATUS_PTR)) -#define astTestFitsDigits(this) \ -astINVOKE(V,astTestFitsDigits_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearFitsAxisOrder(this) \ -astINVOKE(V,astClearFitsAxisOrder_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetFitsAxisOrder(this) \ -astINVOKE(V,astGetFitsAxisOrder_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetFitsAxisOrder(this,fitsaxisorder) \ -astINVOKE(V,astSetFitsAxisOrder_(astCheckFitsChan(this),fitsaxisorder,STATUS_PTR)) -#define astTestFitsAxisOrder(this) \ -astINVOKE(V,astTestFitsAxisOrder_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearWarnings(this) \ -astINVOKE(V,astClearWarnings_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetWarnings(this) \ -astINVOKE(V,astGetWarnings_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetWarnings(this,warnings) \ -astINVOKE(V,astSetWarnings_(astCheckFitsChan(this),warnings,STATUS_PTR)) -#define astTestWarnings(this) \ -astINVOKE(V,astTestWarnings_(astCheckFitsChan(this),STATUS_PTR)) - -#define astGetAllWarnings(this) \ -astINVOKE(V,astGetAllWarnings_(astCheckFitsChan(this),STATUS_PTR)) - -#define astGetCardType(this) \ -astINVOKE(V,astGetCardType_(astCheckFitsChan(this),STATUS_PTR)) - -#define astGetCardName(this) \ -astINVOKE(V,astGetCardName_(astCheckFitsChan(this),STATUS_PTR)) - -#define astGetCardComm(this) \ -astINVOKE(V,astGetCardComm_(astCheckFitsChan(this),STATUS_PTR)) - -#define astGetNcard(this) \ -astINVOKE(V,astGetNcard_(astCheckFitsChan(this),STATUS_PTR)) - -#define astGetNkey(this) \ -astINVOKE(V,astGetNkey_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearEncoding(this) \ -astINVOKE(V,astClearEncoding_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetEncoding(this) \ -astINVOKE(V,astGetEncoding_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetEncoding(this,encoding) \ -astINVOKE(V,astSetEncoding_(astCheckFitsChan(this),encoding,STATUS_PTR)) -#define astTestEncoding(this) \ -astINVOKE(V,astTestEncoding_(astCheckFitsChan(this),STATUS_PTR)) - -#define astClearIwc(this) \ -astINVOKE(V,astClearIwc_(astCheckFitsChan(this),STATUS_PTR)) -#define astGetIwc(this) \ -astINVOKE(V,astGetIwc_(astCheckFitsChan(this),STATUS_PTR)) -#define astSetIwc(this,iwc) \ -astINVOKE(V,astSetIwc_(astCheckFitsChan(this),iwc,STATUS_PTR)) -#define astTestIwc(this) \ -astINVOKE(V,astTestIwc_(astCheckFitsChan(this),STATUS_PTR)) - -#endif - -#endif - - - - - diff --git a/ast/fitstable.c b/ast/fitstable.c deleted file mode 100644 index 148431c..0000000 --- a/ast/fitstable.c +++ /dev/null @@ -1,3006 +0,0 @@ -/* -*class++ -* Name: -* FitsTable - -* Purpose: -* A representation of a FITS binary table. - -* Constructor Function: -c astFitsTable -f AST_FITSTABLE - -* Description: -* The FitsTable class is a representation of a FITS binary table. It -* inherits from the Table class. The parent Table is used to hold the -* binary data of the main table, and a FitsChan (encapsulated within -* the FitsTable) is used to hold the FITS header. -* -* Note - it is not recommended to use the FitsTable class to store -* very large tables. -* -* FitsTables are primarily geared towards the needs of the "-TAB" -* algorithm defined in FITS-WCS paper 2, and so do not support all -* features of FITS binary tables. In particularly, they do not -* provide any equivalent to the following features of FITS binary -* tables: "heap" data (i.e. binary data following the main table), -* columns holding complex values, columns holding variable length -* arrays, scaled columns, column formats, columns holding bit values, -* 8-byte integer values or logical values. - -* Inheritance: -* The FitsTable class inherits from the Table class. - -* Attributes: -* The FitsTable class does not define any new attributes beyond -* those which are applicable to all Tables. - -* Functions: -c In addition to those functions applicable to all Tables, the -c following functions may also be applied to all FitsTables: -f In addition to those routines applicable to all Tables, the -f following routines may also be applied to all FitsTables: -* -c - astColumnNull: Get/set the null value for a column of a FitsTable -c - astColumnSize: Get number of bytes needed to hold a full column of data -c - astGetColumnData: Retrieve all the data values stored in a column -c - astGetTableHeader: Get the FITS headers from a FitsTable -c - astPutColumnData: Store data values in a column -c - astPutTableHeader: Store FITS headers within a FitsTable -f - AST_COLUMNNULL: Get/set the null value for a column of a FitsTable -f - AST_COLUMNSIZE: Get number of bytes needed to hold a full column of data -f - AST_GETCOLUMNDATA: Retrieve all the data values stored in a column -f - AST_GETTABLEHEADER: Get the FITS headers from a FitsTable -f - AST_PUTCOLUMNDATA: Store data values in a column -f - AST_PUTTABLEHEADER: Store FITS headers within a FitsTable - -* Copyright: -* Copyright (C) 2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 25-NOV-2010 (DSB): -* Original version. -* 2-OCT-2012 (DSB): -* Check for Infs as well as NaNs. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS FitsTable - -/* The KeyMap key use to store the null value for a column. */ -#define NULLKEY "Null" - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "table.h" /* Tables (parent class) */ -#include "channel.h" /* I/O channels */ -#include "pointset.h" /* For astCheckNaN(F) functions */ -#include "fitstable.h" /* Interface definition for this class */ - - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include - - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_equal)( AstObject *, AstObject *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); -static void (* parent_addcolumn)( AstTable *, const char *, int, int, int *, const char *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(FitsTable) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(FitsTable,Class_Init) -#define class_vtab astGLOBAL(FitsTable,Class_Vtab) - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstFitsTableVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstFitsTable *astFitsTableId_( void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstFitsChan *GetTableHeader( AstFitsTable *, int * ); -static char *MakeKey( const char *, int, char *, int, int * ); -static int ColumnNull( AstFitsTable *, const char *, int, int, int *, int *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetObjSize( AstObject *, int * ); -static size_t ColumnSize( AstFitsTable *, const char *, int * ); -static void AddColumn( AstTable *, const char *, int, int, int *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void CopyStrings( int, size_t, const char *, char *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void GenerateColumns( AstFitsTable *, AstFitsChan *, int * ); -static void GetColumnData( AstFitsTable *, const char *, float, double, size_t, void *, int *, int * ); -static void PurgeHeader( AstFitsTable *, int * ); -static void PutColumnData( AstFitsTable *, const char *, int, size_t, void *, int * ); -static void PutTableHeader( AstFitsTable *, AstFitsChan *, int * ); -static void UpdateHeader( AstFitsTable *, const char *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ - -static void AddColumn( AstTable *this, const char *name, int type, - int ndim, int *dims, const char *unit, int *status ) { -/* -* Name: -* AddColumn - -* Purpose: -* Add a new column definition to a FitsTable. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* void AddColumn( AstTable *this, const char *name, int type, int ndim, -* int *dims, const char *unit, int *status ) - -* Class Membership: -* FitsTable member function (over-rides the astAddColumn method -* inherited from the Table class). - -* Description: -* Adds the definition of a new column to the supplied table. Initially, -* the column contains a null value for every row. Values may be added -* subsequently using the methods of the KeyMap class. -* -* The FitsTable class extend the method inherited from the parent -* Table class in order to prevent the addition of columns with properties -* not supported by FITS binary tables. - -* Parameters: -* this -* Pointer to the Table. -* name -* The column name. Trailing spaces are ignored (all other spaces -* are significant). The supplied string is converted to upper case. -* type -* The data type associated with the column. One of AST__INTTYPE -* (for integer), AST__SINTTYPE (for short int), AST__BYTETYPE (for -* unsigned bytes - i.e. unsigned chars), AST__DOUBLETYPE (for double -* precision floating point), AST__FLOATTYPE (for single precision -* floating point), AST__STRINGTYPE (for character string). Note, -* pointers and undefined values cannot be stored in a FitsTable -* column. -* ndim -* The number of dimensions spanned by the values stored in a single -* cell of the column. Zero if the column holds scalar values. -* dims -* An array holding the the lengths of each of the axes spanned by -* the values stored in a single cell of the column. Ignored if the -* column holds scalara values. -* unit -* A string specifying the units of the column. Supply a blank -* string if the column is unitless. -* status -* Pointer to the inherited status. - -* Notes: -* - This function returns without action if a column already exists in -* the Table with the supplied name and properties. However an error is -* reported if any of the properties differ. -*/ - -/* Local Variables: */ - const char *text; /* Data type string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Report an error if the supplied data type is supported by the Table - class but not by the FitsTable class. */ - if( type == AST__OBJECTTYPE ) { - text = "Object pointer"; - - } else if( type == AST__POINTERTYPE ) { - text = "generic pointer"; - - } else if( type == AST__UNDEFTYPE ) { - text = "undefined type"; - - } else { - text = NULL; - } - - if( text ) { - astError( AST__NAXIN, "astAddColumn(%s): Bad data type (%s) supplied " - "for new column %s. The %s class does not support %s " - "columns.", status, astGetClass( this ), text, name, - astGetClass( this ), text ); - -/* Otherwise, invoke the parent method to add the column. */ - } else { - (*parent_addcolumn)( this, name, type, ndim, dims, unit, status ); - } -} - -static int ColumnNull( AstFitsTable *this, const char *column, int set, - int newval, int *wasset, int *hasnull, int *status ){ -/* -*++ -* Name: -c astColumnNull -f AST_COLUMNNULL - -* Purpose: -* Get or set the null value for an integer column of a FITS table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c int astColumnNull( AstFitsTable *this, const char *column, int set, -c int newval, int *wasset, int *hasnull ) -f RESULT = AST_COLUMNNULL( THIS, COLUMN, SET, NEWVAL, WASSET, HASNULL, -f STATUS ) - -* Class Membership: -* FitsTable method. - -* Description: -* This function allows a null value to be stored with a named -* integer-valued column in a FitsTable. The supplied null value is -* assigned to the TNULLn keyword in the FITS header associated with -* the FitsTable. A value in the named column is then considered to be -* null if 1) it equals the null value supplied to this function, or -* 2) no value has yet been stored in the cell. -* -* As well as setting a new null value, this function also returns the -* previous null value. If no null value has been set previously, a -* default value will be returned. This default will be an integer -* value that does not currently occur anywhere within the named column. -* If no such value can be found, what happens depends on whether the -* column contains any cells in which no values have yet been stored. -* If so, an error will be reported. Otherwise (i.e. if there are no -* null values in the column), an arbitrary value of zero will be -* returned as the function value, and no TNULLn keyword will be -* stored in the FITS header. -* -* A flag is returned indicating if the returned null value was set -* explicitly by a previous call to this function, or is a default -* value. -* -* A second flag is returned indicating if the named column contains -* any null values (i.e. values equal to the supplied null value, or -* cells to which no value has yet been assigned). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c column -f COLUMN = CHARACTER * ( * ) (Given) -* The character string holding the name of the column. Trailing -* spaces are ignored. -c set -f SET = LOGICAL (Given) -c If non-zero, the value supplied for parameter "newval" -f If .TRUE., the value supplied for argument NEWVAL -* will be stored as the current null value, replacing any value -* set by a previous call to this function. -c If zero, the value supplied for parameter "newval" -f If .FALSE., the value supplied for argument NEWVAL -* is ignored and the current null value is left unchanged. -c newval -f NEWVAL = INTEGER (Given) -* The new null value to use. Ignored if -c "set" is zero. -f SET is .FALSE. -* An error will be reported if the supplied value is outside the -* range of values that can be stored in the integer data type -* associated with the column. -c wasset -f WASSET = LOGICAL (Returned) -c Pointer to an int that will be returned non-zero -f .TRUE. will be returned -* if the returned null value was set previously via an -* earlier invocation of this function. -c Zero -f .FALSE. -* is returned otherwise. If the named column does not exist, or an -* error occurs, a value of -c zero is returned. -f .FALSE. is returned. -c hasnull -f HASNULL = LOGICAL (Returned) -c Pointer to an int that will be returned non-zero -f .TRUE. will be returned -* if and only if the named column currently contains any values -* equal to the null value on exit (i.e. -c "newval" if "set" is non-zero, -f NEWVAL if SET is .TRUE. -* or the returned function value otherwise), or contains any empty -* cells. If the named column does not exist, or an error occurs, a -* value of -c zero is returned. -f .FALSE. is returned. -c If a NULL pointer is supplied for "hasnull", no check on the -c presence of null values will be performed. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astColumnNull() -f AST_COLUMNNULL = INTEGER -* The null value that was in use on entry to this function. If a -* null value has been set by a previous invocation of this -* function, it will be returned. Otherwise, if -c "set" is non-zero, the supplied "newval" -f SET is .TRUE., the supplied NEWVAL -* value is returned. Otherwise, a default value is chosen (if -* possible) that does not currently occur in the named column. If -* all available values are in use in the column, an error is -* reported if and only if the column contains any empty cells. -* Otherwise, a value of zero is returned. A value of zero is also -* returned if the named column does not exist, or an error occurs. - -* Notes: -* - The FITS binary table definition allows only integer-valued -* columns to have an associated null value. This routine will return -* without action if the column is not integer-valued. - -*-- -*/ - -/* Local Variables: */ - AstKeyMap *col_km; /* KeyMap holding named column definition */ - AstKeyMap *cols; /* KeyMap holding all column definitions */ - char key[ AST__MXCOLKEYLEN + 1 ]; /* Current cell key string */ - int *cell; /* Pointer to array of cell values */ - int foundhi; /* Has an occurrence of "nullhi" been found yet? */ - int foundlo; /* Has an occurrence of "nulllo" been found yet? */ - int gotresult; /* Has a usable value been put into "result"? */ - int idim; /* Index of current axis in each column's value */ - int iel; /* Index of current element within cell value */ - int imax; /* Maximum storable value */ - int imin; /* Minimum storable value */ - int irow; /* Index of current row in table */ - int ndim; /* Number of axes in each column's value */ - int nel; /* Total number of values in each cell */ - int nrow; /* Number of rows in table */ - int null; /* The null value on exit */ - int nullfound; /* Has a null value been found in the column yet? */ - int nullhi; /* Higher candidate default null value */ - int nulllo; /* Lower candidate default null value */ - int result; /* Returned value */ - int type; /* Column data type */ - -/* Initialise */ - result = 0; - *wasset = 0; - if( hasnull ) *hasnull = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Store the max and min integer values that can be store din the column - data type. */ - type = astGetColumnType( this, column ); - if( type == AST__BYTETYPE ) { - imin = 0; - imax = UCHAR_MAX; - - } else if( type == AST__SINTTYPE ) { - imin = SHRT_MIN; - imax = SHRT_MAX; - - } else if( type == AST__INTTYPE ) { - imin = INT_MIN; - imax = INT_MAX; - - } else { - imax = 0; - imin = 0; - } - -/* Check the named column contains integer values of any length. */ - if( imax > imin ) { - -/* Get the KeyMap holding information about all columns. */ - cols = astColumnProps( this ); - -/* Get the KeyMap holding information about the named column. */ - if( astMapGet0A( cols, column, &col_km ) ) { - -/* If the column definition already includes a null value, put it into - "result". Also store the "*wasset" flag that indicates if the returned - null value is a default value or not. */ - *wasset = astMapGet0I( col_km, NULLKEY, &result ); - -/* If a new null value is to be established... */ - if( set ) { - -/* If there was no previously set null value, return the new null value - as the function value. */ - if( ! *wasset ) result = newval; - -/* Indicate we now know what the returned function value is. */ - gotresult = 1; - -/* Save the null value that will be in use when this function exits. */ - null = newval; - -/* Check the supplied value is in range. If so store it in the column - keymap. Otherwise report an error. */ - if( null >= imin && null <= imax ) { - astMapPut0I( col_km, NULLKEY, null, NULL ); - - } else if( astOK ) { - astError( AST__BADNULL, "astColumnNull(%s): Supplied null " - "value (%d) is outside the range of integers " - "that can be stored in column '%s'.", status, - astGetClass( this ), newval, column ); - } - -/* If no new null value was supplied, the null value on exit will be the - previously set value, if any. */ - } else { - null = result; - gotresult = *wasset; - } - -/* The rest is only needed if we need to find a default result value, or if - we need to check if there are any null values in the table. */ - if( !gotresult || hasnull ) { - -/* Get the total number of values in each cell of the column. */ - nel = astGetColumnLength( this, column ); - -/* Allocate memory to hold the values in a single cell of the column, - stored as ints. */ - cell = astMalloc( nel*sizeof( int ) ); - -/* No null values found yet. */ - nullfound = 0; - -/* On the first pass round the following loop, we search for occurrences - of the highest and lowest integer values allowed in the column. If no - such occurrences are found we use one or the other as the default null - value. If occurrences of both of these values are found, we change the - values and start the search again. */ - nullhi = imax; - nulllo = imin; - foundlo = 0; - foundhi = 0; - -/* Loop round all rows in the Table. */ - nrow = astGetNrow( this ); - for( irow = 1; irow <= nrow && astOK; irow++ ) { - -/* Format the cell name. */ - (void) MakeKey( column, irow, key, AST__MXCOLKEYLEN + 1, - status ); - -/* Attempt to get the values in the cell */ - if( astMapGet1I( this, key, nel, &nel, cell ) ) { - -/* Get the number of dimensions. */ - ndim = astGetColumnNdim( this, column ); - -/* If we know what the null value is on exit, check the cell for such null - values (but only if the caller want s to know). Skip this check after the - first null is found. */ - if( gotresult ) { - if( ! nullfound ) { - for( idim = 0; idim < ndim; idim++ ) { - if( cell[ idim ] == null ) { - nullfound = 1; - break; - } - } - } - -/* If we do not yet know what the returned value is, we try to find an - integer value within the allowed data range that is not currently used in - the column. For the moment, this is a no-brain algorithm that will - become untenable for large tables. Need to fix it when it is apparent - that it is causing a problem. */ - } else if( nulllo <= nullhi ) { - -/* See if the current cell contains any occurrences of either of the - two currently nominated null values. Is so, increment the matched - nominated null value, and start again at row 1. */ - for( iel = 0; iel < nel; iel++ ) { - - if( cell[ iel ] == nulllo ) { - foundlo = 1; - } else if( cell[ iel ] == nullhi ) { - foundhi = 1; - } - - if( foundlo && foundhi ) { - nullhi--; - nulllo++; - irow = 0; - foundlo = 0; - foundhi = 0; - continue; - } - - } - } - -/* If the column does not contain anything in the current cell, we know - there is at least one null value in the column, so store a non-zero value - in the returned flag. */ - } else { - nullfound = 1; - } - -/* If we now have a value for the result and know that there are nulls in - the column, we can leave the loop. */ - if( gotresult && nullfound ) break; - } - -/* Return the "null found" flag if required. */ - if( hasnull ) *hasnull = nullfound; - -/* If we have not yet stored the default null value to be returned as the - function value, do so now. If no unused value could be found, and - there are missing cells in the table, report an error. */ - if( !gotresult ) { - if( !foundhi ) { - result = nullhi; - - } else if( !foundlo ) { - result = nulllo; - - } else if( nullfound && astOK ) { - astError( AST__BADNULL, "astColumnNull(%s): Cannot find " - "an unused value to use as the null value in " - "column '%s'.", status, astGetClass( this ), - column ); - } - } - -/* Free resources */ - cell = astFree( cell ); - } - col_km = astAnnul( col_km ); - } - cols = astAnnul( cols ); - } - -/* Return null values if an error occurred. */ - if( !astOK ) { - result = 0; - *wasset = 0; - if( hasnull ) *hasnull = 0; - } - -/* Return the result. */ - return result; -} - -static size_t ColumnSize( AstFitsTable *this, const char *column, int *status ){ -/* -*++ -* Name: -c astColumnSize -f AST_COLUMNSIZE - -* Purpose: -* Get the number of bytes needed to hold a full column of data. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c size_t astColumnSize( AstFitsTable *this, const char *column, -c int *hasnull ) -f RESULT = AST_COLUMNSIZE( THIS, COLUMN, STATUS ) - -* Class Membership: -* FitsTable method. - -* Description: -* This function returns the number of bytes of memory that must be -* allocated prior to retrieving the data from a column using -c astGetColumnData. -f AST_GETCOLUMNDATA. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c column -f COLUMN = CHARACTER * ( * ) (Given) -* The character string holding the name of the column. Trailing -* spaces are ignored. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astColumnNull() -f AST_COLUMNNULL = INTEGER -* The number of bytes required to store the column data. - -* Notes: -* - An error will be reported if the named column does not exist in -* the FitsTable. -* - Zero will be returned as the function value in an error occurs. - -*-- -*/ - -/* Local Variables: */ - size_t result; /* Returned value */ - int type; /* Column data type */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Find the number of bytes needed to hold a single element of the value - in a column cell. */ - type = astGetColumnType( this, column ); - if( type == AST__INTTYPE ) { - result = sizeof( int ); - - } else if( type == AST__DOUBLETYPE ){ - result = sizeof( double ); - - } else if( type == AST__STRINGTYPE ){ - result = astGetColumnLenC( this, column )*sizeof( char ); - - } else if( type == AST__FLOATTYPE ){ - result = sizeof( float ); - - } else if( type == AST__SINTTYPE ){ - result = sizeof( short int ); - - } else if( type == AST__BYTETYPE ){ - result = sizeof( char ); - - } else if( astOK ) { - astError( AST__INTER, "astColumnSize(%s): Unsupported column type " - "%d (internal AST programming error).", status, - astGetClass( this ), type ); - } - -/* Multiply it by the number of elements per value. */ - result *= astGetColumnLength( this, column ); - -/* Multiply it by the number of values per column (i.e. the number of rows). */ - result *= astGetNrow( this ); - -/* Return zero if an error occurred. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static void CopyStrings( int nval, size_t nb, const char *cbuf, char *pout, - int *status ){ -/* -* Name: -* CopyStrings - -* Purpose: -* Remove terminating nulls from an array of fixed-length strings. - -* Type: -* Private function. - -* Synopsis: -* void CopyStrings( int nval, size_t nb, const char *cbuf, char *pout, -* int *status ) - -* Description: -* This function copies null terminated strings from "cbuf" to "pout", -* removing the terminating nulls in the process. Thus each output string -* is one character shorter than the corresponding input string. - -* Parameters: -* nval -* The number of strings to copy. -* nb -* The maximum length of each string, excluding trailing null. -* cbuf -* The input array holding "nval" adjacent strings, each occupying -* ( nb + 1 ) characters (the last one is the trailing null). -* pout -* The output array to which "nval" adjacent strings are written, -* each occupying ( nb ) characters (i.e. no trailing null). -* status -* Pointer to inherited status. - -*/ - -/* Local Variables: */ - int i; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Copy the first "nb" characters of each string. */ - for( i = 0; i < nval; i++ ) { - memcpy( pout, cbuf, nb ); - -/* Increment the pointer to the start of the next output string. */ - pout += nb; - -/* Increment the pointer to the start of the next input string. */ - cbuf += nb + 1; - } - -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two FitsTables are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "fitstable.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* FitsTable member function (over-rides the astEqual protected -* method inherited from the astTable class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two FitsTables are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a FitsTable). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the FitsTables are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFitsTable *that; - AstFitsTable *this; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two FitsTable structures. */ - this = (AstFitsTable *) this_object; - that = (AstFitsTable *) that_object; - -/* Check the second object is a FitsTable. We know the first is a - FitsTable since we have arrived at this implementation of the virtual - function. */ - if( astIsAFitsTable( that ) ) { - -/* Check the FitsTables are equal when compared as Tables. */ - if( (*parent_equal)( this_object, that_object, status ) ) { - -/* Check the headers are equal. */ - result = astEqual( this->header, that->header ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void GenerateColumns( AstFitsTable *this, AstFitsChan *header, - int *status ) { -/* -* Name: -* GenerateColumns - -* Purpose: -* Add new column definitions to a FitsTable as defined by a FITS -* header. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* void GenerateColumns( AstFitsTable *this, AstFitsChan *header, -* int *status ) - -* Class Membership: -* FitsTable member function - -* Description: -* For each binary table column defined in the supplied FITS header, -* this function adds an equivalent column to the FitsTable. - -* Parameters: -* this -* Pointer to the FitsTable. -* header -* Pointer to a FitsChan holding the column definitions. -* status -* Pointer to the inherited status. - -*/ - -/* Local Variables: */ - char *cval; - char *name; - char *p; - char *unit; - char buff[ 50 ]; - char code; - char keyword[ 20 ]; - double dval; - int *dims; - int icol; - int idim; - int ival; - int nc; - int ncol; - int ndim; - int nel; - int repeat; - int type; - int wasset; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise */ - type = AST__BADTYPE; - -/* Get the number of columns defined in the header. */ - if( !astGetFitsI( header, "TFIELDS", &ncol ) ) ncol = 0; - -/* Add a column definition to the FitsTable for each column in the header. */ - for( icol = 0; icol < ncol; icol++ ) { - -/* Get the TFORMi keyword that defines the column data type and shape from - the header. Report an error if it is missing. */ - sprintf( keyword, "TFORM%d", icol + 1 ); - if( !astGetFitsS( header, keyword, &cval ) && astOK ) { - astError( AST__NOFTS, "astFitsTable: Supplied FITS binary table " - "header does not contain the required keyword '%s'.", - status, keyword ); - } - -/* Extract the repeat count and data type code from the TFORM string. */ - if( sscanf( cval, "%d%n", &repeat, &nc ) == 0 ) { - repeat = 1; - nc = 0; - } else if( repeat < 0 && astOK ) { - astError( AST__BDFTS, "astFitsTable: Keyword '%s' in supplied FITS " - "binary table header has unsupported value '%s'.", status, - keyword, cval ); - } - code = cval[ nc ]; - -/* Get the corresponding KeyMap data type. Report an error if the FITS - data type is not supported by the KeyMap class. */ - if( code == 'B' ) { - type = AST__BYTETYPE; - - } else if( code == 'I' ) { - type = AST__SINTTYPE; - - } else if( code == 'J' ) { - type = AST__INTTYPE; - - } else if( code == 'D' ) { - type = AST__DOUBLETYPE; - - } else if( code == 'E' ) { - type = AST__FLOATTYPE; - - } else if( code == 'A' ) { - type = AST__STRINGTYPE; - - } else if( astOK ){ - astError( AST__BDFTS, "astFitsTable: Keyword '%s' in supplied FITS " - "binary table header has unsupported value '%s'.", status, - keyword, cval ); - } - -/* The TTYPEi keyword gives the column name. Create a column name based - on the index of the column. */ - sprintf( keyword, "TTYPE%d", icol + 1 ); - if( !astGetFitsS( header, keyword, &cval ) ) { - sprintf( buff, "FCOLUMN%d", icol + 1 ); - cval = buff; - } - name = astStore( NULL, cval, strlen( cval ) + 1 ); - -/* Column units. */ - sprintf( keyword, "TUNIT%d", icol + 1 ); - if( !astGetFitsS( header, keyword, &cval ) ) { - buff[ 0 ] = 0; - cval = buff; - } - unit = astStore( NULL, cval, strlen( cval ) + 1 ); - -/* Column shape is defined by the TDIMi keyword - in the form - "(i,j,k,...)". where i, j, k ... are the dimensions. If it is missing - then the field is assumed to be a 1D vector with the length specified by - the repeat count in the TFORMn keyword, or a scalar (if repeat cound - is one). */ - sprintf( keyword, "TDIM%d", icol + 1 ); - if( astGetFitsS( header, keyword, &cval ) ) { - -/* Count the commas in the keyword value. This equals one less than the - number of dimensions. */ - ndim = 1; - p = cval; - while( *p ) { - if( *(p++) == ',' ) ndim++; - } - -/* Allocate memory for the dimensions. */ - dims = astMalloc( ndim*sizeof( int ) ); - -/* Find each dimension and copy it into the above memory. Also find the - total number of elements (nel). */ - nel = 1; - idim = 0; - p = cval; - if( *p == '(' ) p++; - while( sscanf( p, "%d%n", dims + idim, &nc ) ) { - nel *= dims[ idim ]; - idim++; - p += nc; - if( *p == ',' ) p++; - } - -/* For strings, the first TDIM value gives the length of the string, so - reduce the number of dimensions by one. */ - if( type == AST__STRINGTYPE ) { - ndim--; - dims++; - } - - } else { - nel = repeat; - if( nel == 1 ) { - ndim = 0; - dims = NULL; - } else { - ndim = 1; - dims = astMalloc( sizeof( int ) ); - if( dims ) *dims = nel; - } - } - -/* Check the total number of elements equal the repeat count from the - TFORM keyword. */ - if( repeat != nel && astOK ) { - - sprintf( keyword, "TFORM%d", icol + 1 ); - astGetFitsS( header, keyword, &cval ); - strcpy( buff, cval ); - - sprintf( keyword, "TDIM%d", icol + 1 ); - if( !astGetFitsS( header, keyword, &cval ) ) cval = " "; - - astError( AST__BDFTS, "astFitsTable: Supplied FITS binary table " - "header contains inconsistent TFORM (%s) and TDIM (%s) " - "keywords for field %d.", status, buff, cval, icol + 1 ); - } - -/* Check any TSCALi value is 1.0 */ - sprintf( keyword, "TSCAL%d", icol + 1 ); - if( astGetFitsF( header, keyword, &dval ) && dval != 1.0 && astOK ) { - astError( AST__BDFTS, "astFitsTable: Supplied FITS binary table " - "header contains scaled columns which are not " - "supported by AST.", status ); - } - -/* Check any TZEROi value is 0.0 */ - sprintf( keyword, "TSCAL%d", icol + 1 ); - if( astGetFitsF( header, keyword, &dval ) && dval != 0.0 && astOK ) { - astError( AST__BDFTS, "astFitsTable: Supplied FITS binary table " - "header contains scaled columns which are not " - "supported by AST.", status ); - } - -/* Add the column to the table. */ - astAddColumn( this, name, type, ndim, dims, unit ); - -/* Set the null value, if present. */ - sprintf( keyword, "TNULL%d", icol + 1 ); - if( astGetFitsI( header, keyword, &ival ) ) { - (void) astColumnNull( this, name, 1, ival, &wasset, NULL ); - } - -/* Free resources. */ - dims = astFree( dims - ( ( type == AST__STRINGTYPE ) ? 1 : 0 ) ); - name = astFree( name ); - unit = astFree( unit ); - - } -} - -static void GetColumnData( AstFitsTable *this, const char *column, - float fnull, double dnull, size_t mxsize, - void *coldata, int *nelem, int *status ){ -/* -*++ -* Name: -c astGetColumnData -f AST_GETCOLUMNDATA - -* Purpose: -* Retrieve all the data values stored in a column. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c void astGetColumnData( AstFitsTable *this, const char *column, -c float fnull, double dnull, size_t mxsize, -c void *coldata, int *nelem ) -f CALL AST_GETCOLUMNDATA( THIS, COLUMN, RNULL, DNULL, MXSIZE, -f COLDATA, NELEM, STATUS ) - -* Class Membership: -* FitsTable method. - -* Description: -c This function -f This routine -* copies all data values from a named column into a supplied buffer - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsTable. -c column -f COLUMN = CHARACTER * ( * ) (Given) -* The character string holding the name of the column. Trailing -* spaces are ignored. -c fnull -f RNULL = REAL (Given) -* The value to return in -c "coldata" -f COLDATA -* for any cells for which no value has been stored in the -* FitsTable. Ignored if the column's data type is not -* AST__FLOATTYPE. Supplying -c AST__NANF -f AST__NANR -* will cause a single precision IEEE NaN value to be used. -c dnull -f DNULL = REAL (Given) -* The value to return in -c "coldata" -f COLDATA -* for any cells for which no value has been stored in the -* FitsTable. Ignored if the column's data type is not -* AST__DOUBLETYPE. Supplying AST__NAN will cause a double precision -* IEEE NaN value to be used. -c mxsize -f MXSIZE = INTEGER (Given) -* The size of the -c "coldata" -f COLDATA -* array, in bytes. The amount of memory needed to hold the data -* from a column may be determined using -c astColumnSize. -f AST_COLUMNSIZE. -* If the supplied array is too small to hold all the column data, -* trailing column values will be omitted from the returned array, -* but no error will be reported. -c coldata -f COLDATA( * ) = BYTE (Given) -c A pointer to an -f An -* area of memory in which to return the data -* values currently stored in the column. The values are stored in -* row order. If the column holds non-scalar values, the elements -* of each value are stored in "Fortran" order. No data type -* conversion is performed - the data type of each returned value -* is the data type associated with the column when the column was -* added to the table. If the column holds strings, the returned -* strings will be null terminated. Any excess room at the end of -* the array will be left unchanged. -c nelem -f NELEM = INTEGER (Return) -* The number of elements returned in the -c "coldata" -f COLDATA -* array. This is the product of the number of rows returned and -* the number of elements in each column value. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -f - The RNULL and DNULL arguments -c - The "fnull" and "dnull" parameters -* specify the value to be returned for any empty cells within columns -* holding floating point values. For columns holding integer values, -* the value returned for empty cells is the value returned by the -c astColumNull function. -f AST_COLUMNNULL functiom. -* For columns holding string values, the ASCII NULL character is returned -* for empty cells. -*-- -*/ - -/* Local Variables: */ - char *cbuf; /* Array of strings returned by astMapGet1C */ - char key[ AST__MXCOLKEYLEN + 1 ]; /* Current cell key string */ - int iel; /* Index of current element */ - int irow; /* Index of value being copied */ - int nel; /* No. of elements per value */ - int nrow; /* No. of values to copy */ - int nval; /* Number of values read from KeyMap entry */ - int ok; /* Was the value found in the KeyMap? */ - int type; /* Data type */ - int wasset; /* Was the integer null value set explicitly? */ - size_t nb; /* No. of bytes for a single element of a value */ - size_t nbv; /* No. of bytes per value */ - void *pnull; /* Pointer to a buffer holding a null value */ - void *pout; /* Pointer to next output element */ - -/* Initialise */ - *nelem = 0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise */ - nb = 0; - -/* Find the number of bytes needed to hold a single element of the value - in a column cell. */ - type = astGetColumnType( this, column ); - if( type == AST__INTTYPE ) { - nb = sizeof( int ); - - } else if( type == AST__DOUBLETYPE ){ - nb = sizeof( double ); - - } else if( type == AST__STRINGTYPE ){ - nb = astGetColumnLenC( this, column )*sizeof( char ); - - } else if( type == AST__FLOATTYPE ){ - nb = sizeof( float ); - - } else if( type == AST__SINTTYPE ){ - nb = sizeof( short int ); - - } else if( type == AST__BYTETYPE ){ - nb = sizeof( char ); - - } else if( astOK ) { - astError( AST__INTER, "astGetColumnData(%s): Unsupported column type " - "%d (internal AST programming error).", status, - astGetClass( this ), type ); - } - -/* Get the number of elements per value, and the number of bytes per value. */ - nel = astGetColumnLength( this, column ); - nbv = nb*nel; - -/* Initialise a pointer to the next element of the output array to write to. */ - pout = coldata; - -/* Get the number of rows in the table. */ - nrow = astGetNrow( this ); - -/* For string columns, the buffer returned by astMapGet1C will include a - null character at the end of each string. This is not required for the - fixed-length string format used by FITS binary tables, so for each row we - produce a copy of the string returned by astMapGet1C excluding the - trailing nulls. Allocate a buffer to receive the string returned by - astMapGet1C. */ - if( type == AST__STRINGTYPE ) { - cbuf = astMalloc( ( nb + 1 )*nel ); - } else { - cbuf = NULL; - } - -/* If required, substitute NaN values for the supplied null values. */ - fnull = astCheckNaNF( fnull ); - dnull = astCheckNaN( dnull ); - -/* Indicate we have not yet determined a null value for the column */ - pnull = NULL; - -/* Reduce the number of rows to be returned if the returned array is too - small to hold all rows. */ - if( mxsize < nbv*nrow ) nrow = mxsize/nbv; - -/* Loop round the returned rows rows. */ - for( irow = 1; irow <= nrow; irow++ ) { - -/* Format the cell name. */ - (void) MakeKey( column, irow, key, AST__MXCOLKEYLEN + 1, - status ); - -/* Get the values in the current cell of the column, using its native - data type. For floating point, convert any NaNs into the appropriate - null value (do not need to do this if the null value is itself NaN). */ - if( type == AST__INTTYPE ) { - ok = astMapGet1I( this, key, nel, &nval, pout ); - - } else if( type == AST__DOUBLETYPE ){ - ok = astMapGet1D( this, key, nel, &nval, pout ); - - if( ok && astISFINITE(dnull) ) { - for( iel = 0; iel < nel; iel++ ) { - if( !astISFINITE( ((double *)pout)[ iel ] ) ) { - ((double *)pout)[ iel ] = dnull; - } - } - } - - } else if( type == AST__FLOATTYPE ){ - ok = astMapGet1F( this, key, nel, &nval, pout ); - - if( ok && astISFINITE(fnull) ) { - for( iel = 0; iel < nel; iel++ ) { - if( !astISFINITE( ((float *)pout)[ iel ] ) ) { - ((float *)pout)[ iel ] = fnull; - } - } - } - - } else if( type == AST__SINTTYPE ){ - ok = astMapGet1S( this, key, nel, &nval, pout ); - - } else if( type == AST__BYTETYPE ){ - ok = astMapGet1B( this, key, nel, &nval, pout ); - - } else if( type == AST__STRINGTYPE ){ - ok = astMapGet1C( this, key, nb + 1, nel, &nval, cbuf ); - -/* Copy the strings returned by astMapGet1C into the returned array, - omitting the trailing null at the end of each string. */ - CopyStrings( nval, nb, cbuf, pout, status ); - - } else { - ok = 0; - } - -/* If the cell could not be found, return a suitable number of column null - values. */ - if( !ok ) { - -/* Determine the null value to use, if this has not already been done. */ - if( !pnull ) { - -/* Allocate a buffer to hold a single null value */ - pnull = astMalloc( nb ); - if( astOK ) { - -/* Copy the appropriate null value into the buffer allocated above. */ - if( type == AST__INTTYPE ) { - *( (int *) pnull ) = astColumnNull( this, column, 0, 0, - &wasset, NULL ); - } else if( type == AST__DOUBLETYPE ){ - *( (double *) pnull ) = dnull; - - } else if( type == AST__FLOATTYPE ){ - *( (float *) pnull ) = fnull; - - } else if( type == AST__STRINGTYPE ){ - memset( pnull, 0, nb ); - - } else if( type == AST__SINTTYPE ){ - *( (short int *) pnull ) = astColumnNull( this, column, 0, 0, - &wasset, NULL ); - } else if( type == AST__BYTETYPE ){ - *( (unsigned char *) pnull ) = astColumnNull( this, column, 0, 0, - &wasset, NULL ); - } - } - } - -/* Append the right number of nulls to the returned array. */ - for( iel = 0; iel < nel; iel++ ) { - memcpy( pout, pnull, nb ); - pout += nb; - } - -/* If the cell was found in the table, just increment the pointer to the next - returned value. */ - } else { - pout += nbv; - } - } - -/* Free resources. */ - cbuf = astFree( cbuf ); - pnull = astFree( pnull ); - -/* Return the number of returned elements. */ - *nelem = nel*nrow; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "fitstable.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* FitsTable member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied FitsTables, -* in bytes. - -* Parameters: -* this -* Pointer to the FitsTable. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The FitsTable size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFitsTable *this; /* Pointer to FitsTable structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the FitsTable structure. */ - this = (AstFitsTable *) this_object; - -/* Invoke the GetObjSize method inherited from the parent Table class, and - then add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astGetObjSize( this->header ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static AstFitsChan *GetTableHeader( AstFitsTable *this, int *status ) { -/* -*++ -* Name: -c astGetTableHeader -f AST_GetTableHeader - -* Purpose: -* Get the FITS headers from a FitsTable. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c AstFitsChan *astGetTableHeader( AstFitsTable *this ) -f RESULT = AST_GETTABLEHEADER( THIS, STATUS ) - -* Class Membership: -* FitsTable method. - -* Description: -* This function returns a pointer to a FitsChan holding copies of -* the FITS headers associated with a FitsTable. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsTable. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetTableHeader() -f AST_GetTableHeader = INTEGER -* A pointer to a deep copy of the FitsChan stored within the -* FitsTable. - -* Notes: -* - The returned pointer should be annulled using -c astAnnul -f AST_ANNUL -* when it is no longer needed. -* - Changing the contents of the returned FitsChan will have no effect -* on the FitsTable. To modify the FitsTable, the modified FitsChan must -* be stored in the FitsTable using -c astPutTableHeader. -f AST_PUTTABLEHEADER. - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Ensure the fixed value headers are up-to-date in the FitsChan stored - in the FitsTable. */ - UpdateHeader( this, "astGetTableHeader", status ); - -/* Reset the current card to the first card. */ - astClearCard( this->header ); - -/* Return a deep copy of the FitsChan. */ - return astCopy( this->header ); -} - -void astInitFitsTableVtab_( AstFitsTableVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitFitsTableVtab - -* Purpose: -* Initialise a virtual function table for a FitsTable. - -* Type: -* Protected function. - -* Synopsis: -* #include "fitstable.h" -* void astInitFitsTableVtab( AstFitsTableVtab *vtab, const char *name ) - -* Class Membership: -* FitsTable vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the FitsTable class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstTableVtab *table; /* Pointer to Table component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitTableVtab( (AstTableVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAFitsTable) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstTableVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->GetTableHeader = GetTableHeader; - vtab->PutTableHeader = PutTableHeader; - vtab->ColumnNull = ColumnNull; - vtab->ColumnSize = ColumnSize; - vtab->GetColumnData = GetColumnData; - vtab->PutColumnData = PutColumnData; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - table = (AstTableVtab *) vtab; - - parent_equal = object->Equal; - object->Equal = Equal; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_addcolumn = table->AddColumn; - table->AddColumn = AddColumn; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "FitsTable", "FITS binary table" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static char *MakeKey( const char *column, int irow, char *buf, int len, - int *status ){ -/* -* Name: -* MakeKey - -* Purpose: -* Construct a key for a column cell from a column name and row number. - -* Type: -* Private function. - -* Synopsis: -* #include "fitstable.h" -* char *MakeKey( const char *column, int irow, char *buf, int len, -* int *status ) - -* Class Membership: -* FitsTable member function - -* Description: -* This function constructs a key for a column cell from a column name -* and row number. An error is reported if the buffer is too short. - -* Parameters: -* column -* Pointer to the column name. Trailing white space is ignored. -* irow -* One-based index of the row. -* buf -* Pointer to a buffer in which to store the returned key. -* len -* The length of the buffer. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A copy of "buf". - -*/ - -/* Local Variables: */ - char *result; - char rbuf[ 40 ]; - int collen; - int nc; - -/* Initialise. */ - result = buf; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Format the column number. */ - nc = sprintf( rbuf, "%d", irow ); - -/* Get the used length of the column name (i.e. excluding trailing white - space). */ - collen = astChrLen( column ); - -/* For the total length of the returned string. */ - nc += collen + 3; - -/* If the buffer is large enough, store the returned string. */ - if( len >= nc ) { - sprintf( buf, "%.*s(%s)", collen, column, rbuf ); - } else { - astError( AST__INTER, "MakeKey(FitsTable): Internal buffer is too " - "short to hold Table cell name '%.*s(%s)' (internal AST " - "programming error).", status, collen, column, rbuf ); - } - -/* Return the result, */ - return result; -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* FitsTable member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstFitsTable *this; /* Pointer to FitsTable structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the FitsTable structure. */ - this = (AstFitsTable *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->header, mode, extra, fail ); - - return result; - -} -#endif - -static void PurgeHeader( AstFitsTable *this, int *status ) { -/* -* Name: -* PurgeHeader - -* Purpose: -* Remove fixed-value keywords from the table header. - -* Type: -* Private function. - -* Synopsis: -* void PurgeHeader( AstFitsTable *this, int *status ) - -* Description: -* This function ensures that the headers that are determined by the -* table contents or by the FITS standard do not exist in the header -* of the supplied FitsTable. - -* Parameters: -* this -* Pointer to the FitsTable. -* status -* Pointer to inherited status. - -*/ - -/* Local Constants: */ -#define nfixed 14 /* Number of fixed-value keywords to check for */ - -/* Local Variables: */ - int ifixed; - -/* A list of FITS keywords that have values that are fixed by the FITS - standard or by the contents of the Table. */ - const char *fixed[] = { "XTENSION", "BITPIX", "NAXIS", "NAXIS1", - "NAXIS2", "PCOUNT", "GCOUNT", "TFIELDS", - "TFORM%d", "TTYPE%d", "TNULL%d", "THEAP", - "TDIM%d", "TUNIT%d" }; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Remove headers that have fixed values. */ - for( ifixed = 0; ifixed < nfixed; ifixed++ ) { - astClearCard( this->header ); - while( astFindFits( this->header, fixed[ ifixed ], NULL, 0 ) ) { - astDelFits( this->header ); - } - } - -/* Undefine local constants */ -#undef nfixed -} - -static void PutColumnData( AstFitsTable *this, const char *column, - int clen, size_t size, void *coldata, int *status ){ -/* -*++ -* Name: -c astPutColumnData -f AST_PUTCOLUMNDATA - -* Purpose: -* Store new data values for all rows of a column. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c void astPutColumnData( AstFitsTable *this, const char *column, -c int clen, size_t size, void *coldata ) -f CALL AST_PUTCOLUMNDATA( THIS, COLUMN, CLEN, SIZE, COLDATA, STATUS ) - -* Class Membership: -* FitsTable method. - -* Description: -c This function -f This routine -* copies data values from a supplied buffer into a named column. The -* first element in the buffer becomes the first element in the first -* row of the column. If the buffer does not completely fill the -* column, then any trailing rows are filled with null values. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsTable. -c column -f COLUMN = CHARACTER * ( * ) (Given) -* The character string holding the name of the column. Trailing -* spaces are ignored. -c clen -f CLEN = INTEGER (Given) -* If the column holds character strings, then this must be set to -* the length of each fixed length string in the supplied array. -* This is often determined by the appropriate TFORMn keyword in -* the binary table header. The supplied value is ignored if the -* column does not hold character data. -c size -f SIZE = INTEGER (Given) -* The size of the -c "coldata" -f COLDATA -* array, in bytes. This should be an integer multiple of the -* number of bytes needed to hold the full vector value stored in a -* single cell of the column. An error is reported if this is not -* the case. -c coldata -f COLDATA( * ) = BYTE (Given) -c A pointer to an -f An -* area of memory holding the data to copy into the column. The values -* should be stored in row order. If the column holds non-scalar values, -* the elements of each value should be stored in "Fortran" order. No -* data type conversion is performed. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - char key[ AST__MXCOLKEYLEN + 1 ]; /* Current cell key string */ - char **carray; /* Pointer to array of null terminated string pointers */ - int irow; /* Index of value being copied */ - int iel; /* Index of current element */ - int nel; /* No. of elements per value */ - int nrow; /* No. of values to copy */ - int type; /* Data type */ - size_t nb; /* No. of bytes for a single element of a value */ - size_t nbv; /* No. of bytes per value */ - void *pin; /* Pointer to next input array element */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise */ - nb = 0; - -/* Find the number of bytes in the supplied array holding a single element - of the value in a column cell. */ - type = astGetColumnType( this, column ); - if( type == AST__INTTYPE ) { - nb = sizeof( int ); - - } else if( type == AST__DOUBLETYPE ){ - nb = sizeof( double ); - - } else if( type == AST__STRINGTYPE ){ - nb = clen*sizeof( char ); - - } else if( type == AST__FLOATTYPE ){ - nb = sizeof( float ); - - } else if( type == AST__SINTTYPE ){ - nb = sizeof( short int ); - - } else if( type == AST__BYTETYPE ){ - nb = sizeof( char ); - - } else if( astOK ) { - astError( AST__INTER, "astPutColumnData(%s): Unsupported column type " - "%d (internal AST programming error).", status, - astGetClass( this ), type ); - } - -/* Get the number of elements per value, and the number of bytes (in the - supplied array) per value. */ - nel = astGetColumnLength( this, column ); - nbv = nb*nel; - -/* Initialise a pointer to the next element of the supplied array to read. */ - pin = coldata; - -/* Get the number of rows to copy from the supplied array. */ - nrow = nbv ? size / nbv : 0; - -/* As yet we have no array of null terminated character pointers. */ - carray = NULL; - -/* Report an error if the supplied array does not hold an exact number of - column cells. */ - if( nrow*nbv != size && astOK ) { - astError( AST__BADSIZ, "astPutColumnData(%s): The supplied array size " - "(%d bytes) is not an exact multiple of the size of one " - "column value (%d bytes).", status, astGetClass( this ), - (int) size, (int) nbv ); - } - -/* Loop round the rows to be copied. */ - for( irow = 1; irow <= nrow; irow++ ) { - -/* Format the cell name. */ - (void) MakeKey( column, irow, key, AST__MXCOLKEYLEN + 1, - status ); - -/* Put the next value into the current cell of the column, using its native - data type. Skip floating point values that are entirely NaN. */ - if( type == AST__INTTYPE ) { - astMapPut1I( this, key, nel, pin, NULL ); - - } else if( type == AST__DOUBLETYPE ){ - for( iel = 0; iel < nel; iel++ ) { - if( astISFINITE( ((double *)pin)[ iel ] ) ) { - astMapPut1D( this, key, nel, pin, NULL ); - break; - } - } - - } else if( type == AST__FLOATTYPE ){ - for( iel = 0; iel < nel; iel++ ) { - if( astISFINITE( ((double *)pin)[ iel ] ) ) { - astMapPut1F( this, key, nel, pin, NULL ); - break; - } - } - - } else if( type == AST__SINTTYPE ){ - astMapPut1S( this, key, nel, pin, NULL ); - - } else if( type == AST__BYTETYPE ){ - astMapPut1B( this, key, nel, pin, NULL ); - -/* If each cell in the column holds an array of strings, we need to - convert the fixed length strings in the supplied array into an array - of pointers to null terminated strings. */ - } else if( type == AST__STRINGTYPE ){ - carray = astStringArray( pin, nel, clen ); - astMapPut1C( this, key, nel, (const char ** ) carray, NULL ); - carray = astFree( carray ); - } - -/* Increment the pointer to the next input value. */ - pin += nbv; - } - -/* Remove any remaining cells already present in this column. */ - nrow = astGetNrow( this ); - for( ; irow <= nrow; irow++ ) { - (void) MakeKey( column, irow, key, AST__MXCOLKEYLEN + 1, - status ); - astMapRemove( this, key ); - } -} - -static void PutTableHeader( AstFitsTable *this, AstFitsChan *header, - int *status ) { -/* -*++ -* Name: -c astPutTableHeader -f AST_PUTTABLEHEADER - -* Purpose: -* Store new FITS headers in a FitsTable. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c void astPutTableHeader( AstFitsTable *this, AstFitsChan *header ) -f CALL AST_PUTTABLEHEADER( THIS, HEADER, STATUS ) - -* Class Membership: -* FitsTable method. - -* Description: -c This function -f This routine -* stores new FITS headers in the supplied FitsTable. Any existing -* headers are first deleted. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FitsTable. -c header -f HEADER = INTEGER (Given) -* Pointer to a FitsChan holding the headers for the FitsTable. -* A deep copy of the supplied FitsChan is stored in the FitsTable, -* replacing the current FitsChan in the Fitstable. Keywords that -* are fixed either by the properties of the Table, or by the FITS -* standard, are removed from the copy (see "Notes:" below). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The attributes of the supplied FitsChan, together with any source -* and sink functions associated with the FitsChan, are copied to the -* FitsTable. -* - Values for the following keywords are generated automatically by -* the FitsTable (any values for these keywords in the supplied -* FitsChan will be ignored): "XTENSION", "BITPIX", "NAXIS", "NAXIS1", -* "NAXIS2", "PCOUNT", "GCOUNT", "TFIELDS", "TFORM%d", "TTYPE%d", -* "TNULL%d", "THEAP", "TDIM%d". - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Annul the existing FitsChan. */ - (void) astAnnul( this->header ); - -/* Store a deep copy of the supplied FitsChan in the FitsTable. */ - this->header = astCopy( header ); - -/* Remove headers that have fixed values. */ - PurgeHeader( this, status ); -} - -static void UpdateHeader( AstFitsTable *this, const char *method, - int *status ) { -/* -* Name: -* UpdateHeader - -* Purpose: -* Ensure FITS headers accurately describe the current table contents. - -* Type: -* Private function. - -* Synopsis: -* void UpdateHeader( AstFitsTable *this, const char *method, -* int *status ) - -* Description: -* This function ensures that the FITS headers that are determined by -* the table contents or by the FITS standard are up to date. - -* Parameters: -* this -* Pointer to the FitsTable. -* method -* Pointer to a string holding the name of the method to include in -* error messages. -* status -* Pointer to inherited status. - -*/ - -/* Local Variables: */ - char *dimbuf; - char buf[ 20 ]; - char code; - char keyword[ 14 ]; - const char *unit; - const char *name; - int *dims; - int hasNull; - int icol; - int idim; - int nc; - int ncol; - int ndim; - int nel; - int null; - int rowsize; - int set; - int slen; - int type; - -/* Check inherited status */ - if( !astOK ) return; - -/* Remove any existing headers that will have values stored for them by - this function. */ - PurgeHeader( this, status ); - -/* Store headers that have fixed values regardless of the contents of the - table. Rewind the FitsChan first so they go at the start of the header. */ - astClearCard( this->header ); - astSetFitsS( this->header, "XTENSION", "BINTABLE", NULL, 0 ); - astSetFitsI( this->header, "BITPIX", 8, NULL, 0 ); - astSetFitsI( this->header, "NAXIS", 2, NULL, 0 ); - astSetFitsI( this->header, "PCOUNT", 0, NULL, 0 ); - astSetFitsI( this->header, "GCOUNT", 1, NULL, 0 ); - -/* The number of columns. */ - ncol = astGetNcolumn( this ); - astSetFitsI( this->header, "TFIELDS", ncol, NULL, 0 ); - -/* Add column-specific keywords, one for each column in the Table. */ - dims = NULL; - dimbuf = NULL; - rowsize = 0; - for( icol = 1; icol <= ncol && astOK; icol++ ){ - -/* Get the name, type and shape of the current column. */ - name = astColumnName( this, icol ); - nel = astGetColumnLength( this, name ); - type = astGetColumnType( this, name ); - unit = astGetColumnUnit( this, name ); - ndim = astGetColumnNdim( this, name ); - dims = astGrow( dims, ndim, sizeof( int ) ); - if( astOK ) { - astColumnShape( this, name, ndim, &ndim, dims ); - -/* Get the FITS code that describes the column data type. Also increment - the number of bytes (rowsize) used to describe a whole row. */ - slen = 0; - code = ' '; - if( type == AST__BYTETYPE ) { - code = 'B'; - rowsize += nel; - - } else if( type == AST__SINTTYPE ) { - code = 'I'; - rowsize += 2*nel; - - } else if( type == AST__INTTYPE ) { - code = 'J'; - rowsize += 4*nel; - - } else if( type == AST__DOUBLETYPE ) { - code = 'D'; - rowsize += 8*nel; - - } else if( type == AST__FLOATTYPE ) { - code = 'E'; - rowsize += 4*nel; - - } else if( type == AST__STRINGTYPE ) { - code = 'A'; - -/* Use the maximum length of the strings in the current column (excluding - null) to scale the FITS repeat count. */ - slen = astGetColumnLenC( this, name ); - nel *= slen; - rowsize += nel; - -/* Report an error if the data type is not supported by FITS. */ - } else if( astOK ) { - astError( AST__INTER, "%s(%s): Illegal type %d for column '%s' " - "in a %s (internal AST programming error).", status, - method, astGetClass( this ), type, name, - astGetClass( this ) ); - } - -/* Start the TFORMn keyword value. This is the number of values in each - cell, and is not needed if the cell contains only one value. */ - nc = sprintf( buf, "%d", nel ); - -/* Add the data type code to complete the TFORMn value, and store it in - the FitsChan. */ - sprintf( buf + nc, "%c", code ); - sprintf( keyword, "TFORM%d", icol ); - astSetFitsS( this->header, keyword, buf, NULL, 0 ); - -/* Column name. */ - sprintf( keyword, "TTYPE%d", icol ); - astSetFitsS( this->header, keyword, name, NULL, 0 ); - -/* Column units. */ - if( astChrLen( unit ) ) { - sprintf( keyword, "TUNIT%d", icol ); - astSetFitsS( this->header, keyword, unit, NULL, 0 ); - } - -/* Column null value (integer columns only). Only store a TNULLn keyword - if the NULL attribute has been set for the column, or if the column - contains missing (i.e. null) values. */ - if( type == AST__BYTETYPE || type == AST__SINTTYPE || - type == AST__INTTYPE ) { - null = astColumnNull( this, name, 0, 0, &set, &hasNull ); - if( set || hasNull ) { - sprintf( keyword, "TNULL%d", icol ); - astSetFitsI( this->header, keyword, null, NULL, 0 ); - } - } - -/* Array dimensions (only needed for non-scalars). */ - if( ndim > 0 ) { - dimbuf = astGrow( dimbuf, ndim, 15 ); - if( astOK ) { - -/* For strings, the first dimension is the length of the fixed-length - strings that make up the array. */ - if( type != AST__STRINGTYPE ) { - nc = sprintf( dimbuf, "(%d", dims[ 0 ] ); - } else { - nc = sprintf( dimbuf, "(%d,%d", slen, dims[ 0 ] ); - } - -/* Append the second and subsequent dimensions to the buffer. */ - for( idim = 1; idim < ndim; idim++ ) { - nc += sprintf( dimbuf + nc, ",%d", dims[ idim ] ); - } - sprintf( dimbuf + nc, ")" ); - -/* Store the buffered string as the value for keyword TDIMn in the - FitsChan. */ - sprintf( keyword, "TDIM%d", icol ); - astSetFitsS( this->header, keyword, dimbuf, NULL, 0 ); - } - } - } - } - -/* Insert the NAXISi keywords into the header, following the NAXIS value - (i.e. starting at card 4). */ - astSetCard( this->header, 4 ); - astSetFitsI( this->header, "NAXIS1", rowsize, NULL, 0 ); - astSetFitsI( this->header, "NAXIS2", astGetNrow( this ), NULL, 0 ); - -/* Free resources. */ - dims = astFree( dims ); - dimbuf = astFree( dimbuf ); -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for FitsTable objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for FitsTable objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Mappings within the FitsTable. -*/ - -/* Local Variables: */ - AstFitsTable *in; /* Pointer to input FitsTable */ - AstFitsTable *out; /* Pointer to output FitsTable */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output FitsTables. */ - in = (AstFitsTable *) objin; - out = (AstFitsTable *) objout; - -/* Make copies of the component Tables and store pointers to them in the - output FitsTable structure. */ - out->header = astCopy( in->header ); -} - - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for FitsTable objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for FitsTable objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstFitsTable *this; /* Pointer to FitsTable */ - -/* Obtain a pointer to the FitsTable structure. */ - this = (AstFitsTable *) obj; - -/* Annul the pointers to the component Tables. */ - this->header = astAnnul( this->header ); - -} - - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for FitsTable objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the FitsTable class to an output Channel. - -* Parameters: -* this -* Pointer to the FitsTable whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFitsTable *this; /* Pointer to the FitsTable structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FitsTable structure. */ - this = (AstFitsTable *) this_object; - -/* Write out values representing the instance variables for the FitsTable - class. Note, the primitive data in the FitsTable will be written out - by the parent Table Dump function. This function deals just with the - extra information held in the FitsTable structure. */ - -/* Write out the FITS header. */ - astWriteObject( channel, "Header", 1, 0, this->header, "FITS headers" ); -} - - - - - - - - - - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAFitsTable and astCheckFitsTable functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(FitsTable,Table) -astMAKE_CHECK(FitsTable) - -AstFitsTable *astFitsTable_( void *header_void, const char *options, int *status, ...) { -/* -*++ -* Name: -c astFitsTable -f AST_FITSTABLE - -* Purpose: -* Create a FitsTable. - -* Type: -* Public function. - -* Synopsis: -c #include "fitstable.h" -c AstFitsTable *astFitsTable( AstFitsChan *header, const char *options, ... ) -f RESULT = AST_FITSTABLE( HEADER, OPTIONS, STATUS ) - -* Class Membership: -* FitsTable constructor. - -* Description: -* This function creates a new FitsTable and optionally initialises -* its attributes. -* -* The FitsTable class is a representation of a FITS binary table. It -* inherits from the Table class. The parent Table is used to hold the -* binary data of the main table, and a FitsChan is used to hold the FITS -* header. Note, there is no provision for binary data following the main -* table (such data is referred to as a "heap" in the FITS standard). -* -* Note - it is not recommended to use the FitsTable class to store -* very large tables. - -* Parameters: -c header -f HEADER = INTEGER (Given) -* Pointer to an optional FitsChan containing headers to be stored -* in the FitsTable. -c NULL -f AST__NULL -* may be supplied if the new FitsTable is to be left empty. If -* supplied, and if the headers describe columns of a FITS binary -* table, then equivalent (empty) columns are added to the FitsTable. -* Each column has the same index in the FitsTable that it has in -* the supplied header. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new FitsTable. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new FitsTable. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astFitsTable() -f AST_FITSTABLE = INTEGER -* A pointer to the new FitsTable. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list described above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFitsTable *new; /* Pointer to new FitsTable */ - AstFitsChan *header; /* Pointer to header FitsChan */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate pointers to the header FitsChan provided. */ - header = header_void ? astCheckFitsChan( header_void ) : NULL; - -/* Initialise the FitsTable, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitFitsTable( NULL, sizeof( AstFitsTable ), !class_init, - &class_vtab, "FitsTable", header ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new FitsTable's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new FitsTable. */ - return new; -} - -AstFitsTable *astFitsTableId_( void *header_void, const char *options, ... ) { -/* -* Name: -* astFitsTableId_ - -* Purpose: -* Create a FitsTable. - -* Type: -* Private function. - -* Synopsis: -* #include "fitstable.h" -* AstFitsTable *astFitsTableId_( AstFitsChan *header, const char *options, ... ) - -* Class Membership: -* FitsTable constructor. - -* Description: -* This function implements the external (public) interface to the -* astFitsTable constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astFitsTable_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astFitsTable_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astFitsTable_. - -* Returned Value: -* The ID value associated with the new FitsTable. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFitsChan *header; /* Genuine C poitner to header FitsChan */ - AstFitsTable *new; /* Pointer to new FitsTable */ - int *status; /* Pointer to inherited status value */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a FitsChan pointer from any ID supplied and validate the - pointer to ensure it identifies a valid FitsChan. */ - header = header_void ? astCheckFitsChan( astMakePointer( header_void ) ) : NULL; - -/* Initialise the FitsTable, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitFitsTable( NULL, sizeof( AstFitsTable ), !class_init, - &class_vtab, "FitsTable", header ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new FitsTable's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new FitsTable. */ - return astMakeId( new ); -} - -AstFitsTable *astInitFitsTable_( void *mem, size_t size, int init, - AstFitsTableVtab *vtab, const char *name, - AstFitsChan *header, int *status ) { -/* -*+ -* Name: -* astInitFitsTable - -* Purpose: -* Initialise a FitsTable. - -* Type: -* Protected function. - -* Synopsis: -* #include "fitstable.h" -* AstFitsTable *astInitFitsTable( void *mem, size_t size, int init, -* AstFitsTableVtab *vtab, const char *name, -* AstFitsChan *header ) - -* Class Membership: -* FitsTable initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new FitsTable object. It allocates memory (if necessary) to accommodate -* the FitsTable plus any additional data associated with the derived class. -* It then initialises a FitsTable structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a FitsTable at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the FitsTable is to be initialised. -* This must be of sufficient size to accommodate the FitsTable data -* (sizeof(FitsTable)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the FitsTable (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the FitsTable -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the FitsTable's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new FitsTable. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* header -* If not NULL, a FitsChan that is used to populate the FitsTable -* with headers and columns. - -* Returned Value: -* A pointer to the new FitsTable. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstFitsTable *new; /* Pointer to new FitsTable */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitFitsTableVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a Table structure (the parent class) as the first component - within the FitsTable structure, allocating memory if necessary. Specify that - the Table should be defined in both the forward and inverse directions. */ - new = (AstFitsTable *) astInitTable( mem, size, 0, (AstTableVtab *) vtab, - name ); - if ( astOK ) { - -/* Initialise the FitsTable data. */ -/* ---------------------------- */ - new->header = astFitsChan( NULL, NULL, " ", status ); - -/* If a header was supplied, add equivalent columns to the FitsTable, and - store the header. */ - if( header ) { - GenerateColumns( new, header, status ); - PutTableHeader( new, header, status ); - } - -/* If an error occurred, clean up by deleting the new FitsTable. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new FitsTable. */ - return new; -} - -AstFitsTable *astLoadFitsTable_( void *mem, size_t size, AstFitsTableVtab *vtab, - const char *name, AstChannel *channel, - int *status ) { -/* -*+ -* Name: -* astLoadFitsTable - -* Purpose: -* Load a FitsTable. - -* Type: -* Protected function. - -* Synopsis: -* #include "fitstable.h" -* AstFitsTable *astLoadFitsTable( void *mem, size_t size, AstFitsTableVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* FitsTable loader. - -* Description: -* This function is provided to load a new FitsTable using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* FitsTable structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a FitsTable at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the FitsTable is to be -* loaded. This must be of sufficient size to accommodate the -* FitsTable data (sizeof(FitsTable)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the FitsTable (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the FitsTable structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstFitsTable) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new FitsTable. If this is NULL, a pointer -* to the (static) virtual function table for the FitsTable class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "FitsTable" is used instead. - -* Returned Value: -* A pointer to the new FitsTable. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFitsTable *new; /* Pointer to the new FitsTable */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this FitsTable. In this case the - FitsTable belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstFitsTable ); - vtab = &class_vtab; - name = "FitsTable"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitFitsTableVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built FitsTable. */ - new = astLoadTable( mem, size, (AstTableVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "FitsTable" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* FitsChan holding table headers. */ - new->header = astReadObject( channel, "header", NULL ); - -/* If an error occurred, clean up by deleting the new FitsTable. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new FitsTable pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -AstFitsChan *astGetTableHeader_( AstFitsTable *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,FitsTable,GetTableHeader))(this,status); -} - -void astPutTableHeader_( AstFitsTable *this, AstFitsChan *header, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FitsTable,PutTableHeader))(this,header,status); -} - -int astColumnNull_( AstFitsTable *this, const char *column, int set, - int newval, int *wasset, int *hasnull, int *status ){ - *wasset = 0; - if( hasnull ) *hasnull = 0; - if ( !astOK ) return 0; - return (**astMEMBER(this,FitsTable,ColumnNull))(this,column,set,newval,wasset,hasnull,status); -} - -size_t astColumnSize_( AstFitsTable *this, const char *column, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,FitsTable,ColumnSize))(this,column,status); -} - -void astGetColumnData_( AstFitsTable *this, const char *column, float fnull, - double dnull, size_t mxsize, void *coldata, int *nelem, - int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,FitsTable,GetColumnData))(this,column,fnull,dnull,mxsize, - coldata,nelem,status); -} - -void astPutColumnData_( AstFitsTable *this, const char *column, int clen, - size_t size, void *coldata, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,FitsTable,PutColumnData))(this,column,clen,size,coldata,status); -} - - - - - - - - diff --git a/ast/fitstable.h b/ast/fitstable.h deleted file mode 100644 index a2633b6..0000000 --- a/ast/fitstable.h +++ /dev/null @@ -1,235 +0,0 @@ -#if !defined( FITSTABLE_INCLUDED ) /* Include this file only once */ -#define FITSTABLE_INCLUDED -/* -*+ -* Name: -* fitstable.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the FitsTable class. - -* Invocation: -* #include "fitstable.h" - -* Description: -* This include file defines the interface to the FitsTable class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. - -* Inheritance: -* The FitsTable class inherits from the Table class. - -* Copyright: -* Copyright (C) 2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 25-NOV-2010 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "table.h" /* Parent class */ -#include "fitschan.h" - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* FitsTable structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstFitsTable { - -/* Attributes inherited from the parent class. */ - AstTable table; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstFitsChan *header; /* FitsChan containing table headers */ -} AstFitsTable; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstFitsTableVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstTableVtab table_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstFitsChan *(* GetTableHeader)( AstFitsTable *, int * ); - void (* PutTableHeader)( AstFitsTable *, AstFitsChan *, int * ); - int (* ColumnNull)( AstFitsTable *, const char *, int, int, int *, int *, int * ); - size_t (* ColumnSize)( AstFitsTable *, const char *, int * ); - void (* GetColumnData)( AstFitsTable *, const char *, float, double, size_t, void *, int *, int * ); - void (* PutColumnData)( AstFitsTable *, const char *, int, size_t, void *, int * ); - -} AstFitsTableVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstFitsTableGlobals { - AstFitsTableVtab Class_Vtab; - int Class_Init; -} AstFitsTableGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitFitsTableGlobals_( AstFitsTableGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(FitsTable) /* Check class membership */ -astPROTO_ISA(FitsTable) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstFitsTable *astFitsTable_( void *, const char *, int *, ...); -#else -AstFitsTable *astFitsTableId_( void *, const char *, ... )__attribute__((format(printf,2,3))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstFitsTable *astInitFitsTable_( void *, size_t, int, AstFitsTableVtab *, - const char *, AstFitsChan *, int * ); - -/* Vtab initialiser. */ -void astInitFitsTableVtab_( AstFitsTableVtab *, const char *, int * ); - -/* Loader. */ -AstFitsTable *astLoadFitsTable_( void *, size_t, AstFitsTableVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -AstFitsChan *astGetTableHeader_( AstFitsTable *, int * ); -void astPutTableHeader_( AstFitsTable *, AstFitsChan *, int * ); -int astColumnNull_( AstFitsTable *, const char *, int, int, int *, int *, int * ); -size_t astColumnSize_( AstFitsTable *, const char *, int * ); -void astGetColumnData_( AstFitsTable *, const char *, float, double, size_t, void *, int *, int * ); -void astPutColumnData_( AstFitsTable *, const char *, int, size_t, void *, int * ); - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckFitsTable(this) astINVOKE_CHECK(FitsTable,this,0) -#define astVerifyFitsTable(this) astINVOKE_CHECK(FitsTable,this,1) - -/* Test class membership. */ -#define astIsAFitsTable(this) astINVOKE_ISA(FitsTable,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astFitsTable astINVOKE(F,astFitsTable_) -#else -#define astFitsTable astINVOKE(F,astFitsTableId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitFitsTable(mem,size,init,vtab,name,header) \ -astINVOKE(O,astInitFitsTable_(mem,size,init,vtab,name,header,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitFitsTableVtab(vtab,name) astINVOKE(V,astInitFitsTableVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadFitsTable(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadFitsTable_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckFitsTable to validate FitsTable pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astGetTableHeader(this) \ -astINVOKE(O,astGetTableHeader_(astCheckFitsTable(this),STATUS_PTR)) -#define astPutTableHeader(this,header) \ -astINVOKE(V,astPutTableHeader_(astCheckFitsTable(this),astCheckFitsChan(header),STATUS_PTR)) -#define astColumnNull(this,column,set,newval,wasset,hasnull) \ -astINVOKE(V,astColumnNull_(astCheckFitsTable(this),column,set,newval,wasset,hasnull,STATUS_PTR)) -#define astColumnSize(this,column) \ -astINVOKE(V,astColumnSize_(astCheckFitsTable(this),column,STATUS_PTR)) -#define astGetColumnData(this,column,fnull,dnull,mxsize,coldata,nelem) \ -astINVOKE(V,astGetColumnData_(astCheckFitsTable(this),column,fnull,dnull,mxsize,coldata,nelem,STATUS_PTR)) -#define astPutColumnData(this,column,clen,size,coldata) \ -astINVOKE(V,astPutColumnData_(astCheckFitsTable(this),column,clen,size,coldata,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#endif - -#endif diff --git a/ast/fkeymap.c b/ast/fkeymap.c deleted file mode 100644 index 2eea900..0000000 --- a/ast/fkeymap.c +++ /dev/null @@ -1,1441 +0,0 @@ -/* -*+ -* Name: -* fkeymap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST KeyMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the KeyMap class. - -* Routines Defined: -* AST_ISAKEYMAP -* AST_KEYMAP -* AST_MAPCOPY -* AST_MAPPUT0 -* AST_MAPPUT1 -* AST_MAPPUTU -* AST_MAPGET0 -* AST_MAPGET1 -* AST_MAPGETELEM -* AST_MAPPUTELEM -* AST_MAPREMOVE -* AST_MAPRENAME -* AST_MAPSIZE -* AST_MAPLENGTH -* AST_MAPLENC -* AST_MAPTYPE -* AST_MAPKEY - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 13-NOV-2004 (DSB): -* Original version. -* 5-JUN-2006 (DSB): -* Added support for single precision entries. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "keymap.h" /* C interface to the KeyMap class */ - -F77_LOGICAL_FUNCTION(ast_isakeymap)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAKEYMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAKeyMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_keymap)( CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_KEYMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astKeyMap( "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_mapput0a)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT0A", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut0A( astI2P( *THIS ), key, astI2P( *VALUE ), comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput0c)( INTEGER(THIS), - CHARACTER(KEY), - CHARACTER(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(VALUE) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_CHARACTER(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *value, *key; - - astAt( "AST_MAPPUT0C", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - value = astString( VALUE, VALUE_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut0C( astI2P( *THIS ), key, value, comment ); - astFree( key ); - astFree( value ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput0i)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT0I", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut0I( astI2P( *THIS ), key, *VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput0s)( INTEGER(THIS), - CHARACTER(KEY), - WORD(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_WORD(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT0W", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut0S( astI2P( *THIS ), key, *VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput0b)( INTEGER(THIS), - CHARACTER(KEY), - UBYTE(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_UBYTE(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT0B", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut0B( astI2P( *THIS ), key, *VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput0d)( INTEGER(THIS), - CHARACTER(KEY), - DOUBLE(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_DOUBLE(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT0D", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut0D( astI2P( *THIS ), key, *VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput0r)( INTEGER(THIS), - CHARACTER(KEY), - REAL(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_REAL(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT0R", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut0F( astI2P( *THIS ), key, *VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput1a)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(SIZE), - INTEGER_ARRAY(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(SIZE) - GENPTR_INTEGER_ARRAY(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - AstObject **values; - int i; - - astAt( "AST_MAPPUT1A", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - - values = astMalloc( sizeof( AstObject * )*(size_t)( *SIZE )); - if( astOK ) { - for( i = 0; i < *SIZE; i++ ) { - values[ i ] = astI2P( VALUE[ i ] ); - } - } - - astMapPut1A( astI2P( *THIS ), key, *SIZE, values, comment ); - astFree( values ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput1c)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(SIZE), - CHARACTER_ARRAY(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(VALUE) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(SIZE) - GENPTR_CHARACTER_ARRAY(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - const char **values; - int i; - - astAt( "AST_MAPPUT1C", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - - values = astMalloc( sizeof( const char * )*(size_t)( *SIZE )); - if( astOK ) { - for( i = 0; i < *SIZE; i++ ) { - values[ i ] = astString( VALUE + i*VALUE_length, VALUE_length ); - } - } - - astMapPut1C( astI2P( *THIS ), key, *SIZE, values, comment ); - - if( astOK ) { - for( i = 0; i < *SIZE; i++ ) astFree( (void *) values[ i ] ); - } - astFree( (void *) values ); - astFree( key ); - astFree( comment ); - ) -} - - - -F77_SUBROUTINE(ast_mapput1i)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(SIZE), - INTEGER_ARRAY(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(SIZE) - GENPTR_INTEGER_ARRAY(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT1I", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut1I( astI2P( *THIS ), key, *SIZE, VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - - -F77_SUBROUTINE(ast_mapput1s)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(SIZE), - WORD_ARRAY(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(SIZE) - GENPTR_WORD_ARRAY(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT1W", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut1S( astI2P( *THIS ), key, *SIZE, VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput1b)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(SIZE), - UBYTE_ARRAY(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(SIZE) - GENPTR_UBYTE_ARRAY(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT1B", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut1B( astI2P( *THIS ), key, *SIZE, VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - - -F77_SUBROUTINE(ast_mapput1d)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(SIZE), - DOUBLE_ARRAY(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(SIZE) - GENPTR_DOUBLE_ARRAY(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT1D", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut1D( astI2P( *THIS ), key, *SIZE, VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapput1r)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(SIZE), - REAL_ARRAY(VALUE), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(SIZE) - GENPTR_REAL_ARRAY(VALUE) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUT1R", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPut1F( astI2P( *THIS ), key, *SIZE, VALUE, comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_SUBROUTINE(ast_mapputu)( INTEGER(THIS), - CHARACTER(KEY), - CHARACTER(COMMENT), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(COMMENT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_CHARACTER(COMMENT) - char *comment, *key; - - astAt( "AST_MAPPUTU", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - comment = astString( COMMENT, COMMENT_length ); - astMapPutU( astI2P( *THIS ), key, comment ); - astFree( key ); - astFree( comment ); - ) -} - -F77_LOGICAL_FUNCTION(ast_mapget0i)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET0I", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet0I( astI2P( *THIS ), key, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget0s)( INTEGER(THIS), - CHARACTER(KEY), - WORD(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_WORD(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET0W", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet0S( astI2P( *THIS ), key, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget0b)( INTEGER(THIS), - CHARACTER(KEY), - UBYTE(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_UBYTE(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET0W", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet0B( astI2P( *THIS ), key, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget0d)( INTEGER(THIS), - CHARACTER(KEY), - DOUBLE(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_DOUBLE(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET0D", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet0D( astI2P( *THIS ), key, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget0r)( INTEGER(THIS), - CHARACTER(KEY), - REAL(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_REAL(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET0R", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet0F( astI2P( *THIS ), key, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget0c)( INTEGER(THIS), - CHARACTER(KEY), - CHARACTER(VALUE), - INTEGER(L), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(VALUE) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_CHARACTER(VALUE) - GENPTR_INTEGER(L) - F77_LOGICAL_TYPE(RESULT); - char *key; - const char *value; - int i; - - astAt( "AST_MAPGET0C", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - value = NULL; - RESULT = astMapGet0C( astI2P( *THIS ), key, &value ) ? F77_TRUE : F77_FALSE; - astFree( key ); - i = 0; - if( value ) { - for( ; value[ i ] && ( i < VALUE_length ); i++ ) { - VALUE[ i ] = value[ i ]; - } - *L = i; - } else { - *L = 0; - } - - if( VALUE ) { - for( ; i < VALUE_length; i++ ) { - VALUE[ i ] = ' '; - } - } - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget0a)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - AstObject *value; - - astAt( "AST_MAPGET0A", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet0A( astI2P( *THIS ), key, &value ) ? F77_TRUE : F77_FALSE; - astFree( key ); - *VALUE = astP2I( value ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget1i)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(MXVAL), - INTEGER(NVAL), - INTEGER_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(MXVAL) - GENPTR_INTEGER(NVAL) - GENPTR_INTEGER_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET1I", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet1I( astI2P( *THIS ), key, *MXVAL, NVAL, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - - -F77_LOGICAL_FUNCTION(ast_mapget1d)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(MXVAL), - INTEGER(NVAL), - DOUBLE_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(MXVAL) - GENPTR_INTEGER(NVAL) - GENPTR_DOUBLE_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET1D", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet1D( astI2P( *THIS ), key, *MXVAL, NVAL, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget1s)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(MXVAL), - INTEGER(NVAL), - WORD_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(MXVAL) - GENPTR_INTEGER(NVAL) - GENPTR_WORD_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET1W", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet1S( astI2P( *THIS ), key, *MXVAL, NVAL, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget1b)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(MXVAL), - INTEGER(NVAL), - UBYTE_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(MXVAL) - GENPTR_INTEGER(NVAL) - GENPTR_UBYTE_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET1B", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet1B( astI2P( *THIS ), key, *MXVAL, NVAL, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapget1r)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(MXVAL), - INTEGER(NVAL), - REAL_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(MXVAL) - GENPTR_INTEGER(NVAL) - GENPTR_REAL_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGET1R", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGet1F( astI2P( *THIS ), key, *MXVAL, NVAL, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - - -F77_LOGICAL_FUNCTION(ast_mapget1a)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(MXVAL), - INTEGER(NVAL), - INTEGER_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(MXVAL) - GENPTR_INTEGER(NVAL) - GENPTR_INTEGER_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - AstObject **values; - int i; - - astAt( "AST_MAPGET1A", NULL, 0 ); - astWatchSTATUS( - values = astMalloc( sizeof( AstObject *)*(size_t) *MXVAL ); - key = astString( KEY, KEY_length ); - RESULT = astMapGet1A( astI2P( *THIS ), key, *MXVAL, NVAL, values ) ? F77_TRUE : F77_FALSE; - astFree( key ); - if( astOK ) { - for( i = 0; i < *NVAL; i++ ) VALUE[ i ] = astP2I( values[ i ] ); - } - astFree( values ); - - ) - return RESULT; -} - - -F77_LOGICAL_FUNCTION(ast_mapget1c)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(MXVAL), - INTEGER(NVAL), - CHARACTER_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(VALUE) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(MXVAL) - GENPTR_INTEGER(NVAL) - GENPTR_CHARACTER_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - char *values, *c, *d; - int i, j, term; - - astAt( "AST_MAPGET1C", NULL, 0 ); - astWatchSTATUS( - values = astMalloc( sizeof( char )*(size_t) (*MXVAL)*( VALUE_length + 1 ) ); - key = astString( KEY, KEY_length ); - RESULT = astMapGet1C( astI2P( *THIS ), key, VALUE_length + 1, *MXVAL, - NVAL, values ) ? F77_TRUE : F77_FALSE; - astFree( key ); - -/* Loop round each string value returned in the array */ - if( astOK ) { - c = values; - d = VALUE; - for( i = 0; i < *NVAL; i++ ) { - -/* Loop round each of character in the "i"th element of the returned - array. Copy characters from the work array until a terminating null is - found. Replace this null by a space and replace all subsequent - characters by spaces up to the end of the returned array element. */ - term = 0; - for( j = 0; j < VALUE_length; j++, d++, c++ ) { - if( term ) { - *d = ' '; - } else if( (*d = *c) == 0 ) { - *d = ' '; - term = 1; - } - } - -/* Skip over the extra character at the end of each element in the work - array. */ - c++; - } - } - astFree( values ); - ) - return RESULT; -} - - -F77_SUBROUTINE(ast_mapremove)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - char *key; - - astAt( "AST_MAPREMOVE", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - astMapRemove( astI2P( *THIS ), key ); - astFree( key ); - ) -} - -F77_SUBROUTINE(ast_maprename)( INTEGER(THIS), - CHARACTER(OLDKEY), - CHARACTER(NEWKEY), - INTEGER(STATUS) - TRAIL(OLDKEY) - TRAIL(NEWKEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(OLDKEY) - GENPTR_CHARACTER(NEWKEY) - char *oldkey, *newkey; - - astAt( "AST_MAPRENAME", NULL, 0 ); - astWatchSTATUS( - oldkey = astString( OLDKEY, OLDKEY_length ); - newkey = astString( NEWKEY, NEWKEY_length ); - astMapRename( astI2P( *THIS ), oldkey, newkey ); - astFree( oldkey ); - astFree( newkey ); - ) -} - -F77_SUBROUTINE(ast_mapcopy)( INTEGER(THIS), - INTEGER(THAT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(THAT) - - astAt( "AST_MAPCOPY", NULL, 0 ); - astWatchSTATUS( - astMapCopy( astI2P( *THIS ), astI2P( *THAT ) ); - ) -} - -F77_INTEGER_FUNCTION(ast_mapsize)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_MAPSIZE", NULL, 0 ); - astWatchSTATUS( - RESULT = astMapSize( astI2P( *THIS ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_maplength)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - F77_INTEGER_TYPE(RESULT); - char *key; - - astAt( "AST_MAPLENGTH", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapLength( astI2P( *THIS ), key ); - astFree( key ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_maplenc)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - F77_INTEGER_TYPE(RESULT); - char *key; - - astAt( "AST_MAPLENGTH", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapLenC( astI2P( *THIS ), key ); - astFree( key ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_maptype)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - F77_INTEGER_TYPE(RESULT); - char *key; - - astAt( "AST_MAPTYPE", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapType( astI2P( *THIS ), key ); - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_maphaskey)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPHASKEY", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapHasKey( astI2P( *THIS ), key ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapdefined)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPDEFINED", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapDefined( astI2P( *THIS ), key ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -/* NO_CHAR_FUNCTION indicates that the f77.h method of returning a - character result doesn't work, so add an extra argument instead and - wrap this function up in a normal FORTRAN 77 function (in the file - keymap.f). */ -#if NO_CHAR_FUNCTION -F77_SUBROUTINE(ast_mapkey_a)( CHARACTER(RESULT), -#else -F77_SUBROUTINE(ast_mapkey)( CHARACTER_RETURN_VALUE(RESULT), -#endif - INTEGER(THIS), - INTEGER(INDEX), -#if NO_CHAR_FUNCTION - INTEGER(STATUS) - TRAIL(RESULT) ) { -#else - INTEGER(STATUS) ) { -#endif - GENPTR_CHARACTER(RESULT) - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(INDEX) - const char *result; - int i; - - astAt( "AST_MAPKEY", NULL, 0 ); - astWatchSTATUS( - result = astMapKey( astI2P( *THIS ), *INDEX - 1 ); - i = 0; - if ( astOK ) { /* Copy result */ - for ( ; result[ i ] && i < RESULT_length; i++ ) { - RESULT[ i ] = result[ i ]; - } - } - while ( i < RESULT_length ) RESULT[ i++ ] = ' '; /* Pad with blanks */ - ) -} - - -F77_LOGICAL_FUNCTION(ast_mapgetelemi)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - INTEGER_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_INTEGER_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGETELEMI", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGetElemI( astI2P( *THIS ), key, *ELEM - 1, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - - -F77_LOGICAL_FUNCTION(ast_mapgetelemd)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - DOUBLE_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_DOUBLE_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGETELEMD", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGetElemD( astI2P( *THIS ), key, *ELEM - 1, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapgetelems)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - WORD_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_WORD_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGETELEMW", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGetElemS( astI2P( *THIS ), key, *ELEM - 1, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapgetelemb)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - UBYTE_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_UBYTE_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGETELEMB", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGetElemB( astI2P( *THIS ), key, *ELEM - 1, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_mapgetelemr)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - REAL_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_REAL_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - - astAt( "AST_MAPGETELEMR", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGetElemF( astI2P( *THIS ), key, *ELEM - 1, VALUE ) ? F77_TRUE : F77_FALSE; - astFree( key ); - ) - return RESULT; -} - - -F77_LOGICAL_FUNCTION(ast_mapgetelema)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - INTEGER_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_INTEGER_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - AstObject *ptr; - - astAt( "AST_MAPGETELEMA", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - RESULT = astMapGetElemA( astI2P( *THIS ), key, *ELEM - 1, &ptr ) ? F77_TRUE : F77_FALSE; - astFree( key ); - if( astOK ) *VALUE = astP2I( ptr ); - ) - return RESULT; -} - - -F77_LOGICAL_FUNCTION(ast_mapgetelemc)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - CHARACTER_ARRAY(VALUE), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(VALUE) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_CHARACTER_ARRAY(VALUE) - F77_LOGICAL_TYPE(RESULT); - char *key; - char *values, *c, *d; - int j; - - astAt( "AST_MAPGETELEMC", NULL, 0 ); - astWatchSTATUS( - values = astMalloc( sizeof( char )*(size_t) ( VALUE_length + 1 ) ); - key = astString( KEY, KEY_length ); - RESULT = astMapGetElemC( astI2P( *THIS ), key, VALUE_length + 1, *ELEM - 1, - values ) ? F77_TRUE : F77_FALSE; - astFree( key ); - -/* Copy characters from the work array until a terminating null is - found. Replace this null by a space and replace all subsequent - characters by spaces up to the end of the returned array element. */ - if( astOK ) { - c = values; - d = VALUE; - - for( j = 0; j < VALUE_length; j++, d++, c++ ) { - if( (*d = *c) == 0 ) { - *d = ' '; - break; - } - } - - for( ; j < VALUE_length; j++, d++ ) *d = ' '; - - } - astFree( values ); - ) - return RESULT; -} - - -F77_SUBROUTINE(ast_mapputelemi)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - INTEGER(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_INTEGER(VALUE) - char *key; - - astAt( "AST_MAPPUTELEMI", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - astMapPutElemI( astI2P( *THIS ), key, *ELEM - 1, *VALUE ); - astFree( key ); - ) -} - - -F77_SUBROUTINE(ast_mapputelems)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - WORD(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_WORD(VALUE) - char *key; - - astAt( "AST_MAPPUTELEMW", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - astMapPutElemS( astI2P( *THIS ), key, *ELEM - 1, *VALUE ); - astFree( key ); - ) -} - -F77_SUBROUTINE(ast_mapputelemb)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - UBYTE(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_UBYTE(VALUE) - char *key; - - astAt( "AST_MAPPUTELEMB", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - astMapPutElemB( astI2P( *THIS ), key, *ELEM - 1, *VALUE ); - astFree( key ); - ) -} - -F77_SUBROUTINE(ast_mapputelemd)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - DOUBLE(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_DOUBLE(VALUE) - char *key; - - astAt( "AST_MAPPUTELEMD", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - astMapPutElemD( astI2P( *THIS ), key, *ELEM - 1, *VALUE ); - astFree( key ); - ) -} - -F77_SUBROUTINE(ast_mapputelemr)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - REAL(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_REAL(VALUE) - char *key; - - astAt( "AST_MAPPUTELEMR", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - astMapPutElemF( astI2P( *THIS ), key, *ELEM - 1, *VALUE ); - astFree( key ); - ) -} - - -F77_SUBROUTINE(ast_mapputelema)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - INTEGER(VALUE), - INTEGER(STATUS) - TRAIL(KEY) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_INTEGER(VALUE) - char *key; - - astAt( "AST_MAPPUTELEMA", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - astMapPutElemA( astI2P( *THIS ), key, *ELEM - 1, astI2P( *VALUE ) ); - astFree( key ); - ) -} - - -F77_SUBROUTINE(ast_mapputelemc)( INTEGER(THIS), - CHARACTER(KEY), - INTEGER(ELEM), - CHARACTER(VALUE), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(VALUE) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_INTEGER(ELEM) - GENPTR_CHARACTER(VALUE) - char *key; - char *value; - - astAt( "AST_MAPPUTELEMC", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - value = astString( VALUE, VALUE_length ); - astMapPutElemC( astI2P( *THIS ), key, *ELEM - 1, value ); - astFree( key ); - astFree( value ); - ) -} - -F77_LOGICAL_FUNCTION(ast_mapgetc)( INTEGER(THIS), - CHARACTER(KEY), - CHARACTER(VALUE), - INTEGER(L), - INTEGER(STATUS) - TRAIL(KEY) - TRAIL(VALUE) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(KEY) - GENPTR_CHARACTER(VALUE) - GENPTR_INTEGER(L) - F77_LOGICAL_TYPE(RESULT); - char *key; - const char *value; - int i; - - astAt( "AST_MAPGETC", NULL, 0 ); - astWatchSTATUS( - key = astString( KEY, KEY_length ); - value = NULL; - RESULT = astMapGetC( astI2P( *THIS ), key, &value ) ? F77_TRUE : F77_FALSE; - astFree( key ); - i = 0; - if( value ) { - for( ; value[ i ] && ( i < VALUE_length ); i++ ) { - VALUE[ i ] = value[ i ]; - } - *L = i; - } else { - *L = 0; - } - - if( VALUE ) { - for( ; i < VALUE_length; i++ ) { - VALUE[ i ] = ' '; - } - } - ) - return RESULT; -} - diff --git a/ast/flutmap.c b/ast/flutmap.c deleted file mode 100644 index 4ff5f0a..0000000 --- a/ast/flutmap.c +++ /dev/null @@ -1,107 +0,0 @@ -/* -*+ -* Name: -* flutmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST LutMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the LutMap class. - -* Routines Defined: -* AST_ISALUTMAP -* AST_LUTMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 8-JUL-1997 (RFWS): -* Original version. -*- -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "lutmap.h" /* C interface to the LutMap class */ - -F77_LOGICAL_FUNCTION(ast_isalutmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISALUTMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsALutMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_lutmap)( INTEGER(NLUT), - DOUBLE_ARRAY(LUT), - DOUBLE(START), - DOUBLE(INC), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NLUT) - GENPTR_DOUBLE_ARRAY(LUT) - GENPTR_DOUBLE(START) - GENPTR_DOUBLE(INC) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - - astAt( "AST_LUTMAP", NULL, 0 ); - astWatchSTATUS( - char *options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astLutMap( *NLUT, LUT, *START, *INC, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fluxframe.c b/ast/fluxframe.c deleted file mode 100644 index ee62fa3..0000000 --- a/ast/fluxframe.c +++ /dev/null @@ -1,4490 +0,0 @@ -/* -*class++ -* Name: -* FluxFrame - -* Purpose: -* Measured flux description. - -* Constructor Function: -c astFluxFrame -f AST_FLUXFRAME - -* Description: -* A FluxFrame is a specialised form of one-dimensional Frame which -* represents various systems used to represent the signal level in an -* observation. The particular coordinate system to be used is specified -* by setting the FluxFrame's System attribute qualified, as necessary, by -* other attributes such as the units, etc (see the description of the -* System attribute for details). -* -* All flux values are assumed to be measured at the same frequency or -* wavelength (as given by the SpecVal attribute). Thus this class is -* more appropriate for use with images rather than spectra. - -* Inheritance: -* The FluxFrame class inherits from the Frame class. - -* Attributes: -* In addition to those attributes common to all Frames, every -* FluxFrame also has the following attributes: -* -* - SpecVal: The spectral position at which the flux values are measured. - -* Functions: -c The FluxFrame class does not define any new functions beyond those -f The FluxFrame class does not define any new routines beyond those -* which are applicable to all Frames. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 6-DEC-2004 (DSB): -* Original version. -* 14-DEC-2004 (DSB): -* Added AST__SBRIGHT and AST__SBRIGHTW systems. -* 7-DEC-2005 (DSB): -* Free memory allocated by calls to astReadString. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 31-JAN-2007 (DSB): -* Modified so that a FluxFrame can be used as a template to find a -* FluxFrame contained within a CmpFrame. This involves changes in -* Match and the removal of the local versions of SetMaxAxes and -* SetMinAxes. -* 3-SEP-2007 (DSB): -* In SubFrame, since AlignSystem is extended by the FluxFrame class -* it needs to be cleared before invoking the parent SubFrame -* method in cases where the result Frame is not a FluxFrame. -* 2-OCT-2007 (DSB): -* In Overlay, clear AlignSystem as well as System before calling -* the parent overlay method. -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS FluxFrame - -/* Define the first and last acceptable System values. */ -#define FIRST_SYSTEM AST__FLUXDEN -#define LAST_SYSTEM AST__SBRIGHTW - -/* Define other numerical constants for use in this module. */ -#define GETATTRIB_BUFF_LEN 50 -#define GETLABEL_BUFF_LEN 200 -#define GETSYMBOL_BUFF_LEN 20 -#define GETTITLE_BUFF_LEN 200 - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "unit.h" /* Units management facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "frame.h" /* Parent Frame class */ -#include "fluxframe.h" /* Interface definition for this class */ -#include "mapping.h" /* Coordinate Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "zoommap.h" /* Scaling Mappings */ -#include "specframe.h" /* Spectral Frames */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are used or extended by this - class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstSystemType (* parent_getalignsystem)( AstFrame *, int * ); -static AstSystemType (* parent_getsystem)( AstFrame *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static const char *(* parent_getdomain)( AstFrame *, int * ); -static const char *(* parent_getlabel)( AstFrame *, int, int * ); -static const char *(* parent_getsymbol)( AstFrame *, int, int * ); -static const char *(* parent_gettitle)( AstFrame *, int * ); -static const char *(* parent_getunit)( AstFrame *, int, int * ); -static int (* parent_match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int (* parent_subframe)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_setunit)( AstFrame *, int, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_setsystem)( AstFrame *, AstSystemType, int * ); -static void (* parent_clearsystem)( AstFrame *, int * ); -static void (* parent_clearunit)( AstFrame *, int, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->GetLabel_Buff[ 0 ] = 0; \ - globals->GetSymbol_Buff[ 0 ] = 0; \ - globals->GetTitle_Buff[ 0 ] = 0; \ - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(FluxFrame) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(FluxFrame,Class_Init) -#define class_vtab astGLOBAL(FluxFrame,Class_Vtab) -#define getattrib_buff astGLOBAL(FluxFrame,GetAttrib_Buff) -#define getlabel_buff astGLOBAL(FluxFrame,GetLabel_Buff) -#define getsymbol_buff astGLOBAL(FluxFrame,GetSymbol_Buff) -#define gettitle_buff astGLOBAL(FluxFrame,GetTitle_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffers for strings returned by various functions. */ -static char getattrib_buff[ AST__FLUXFRAME_GETATTRIB_BUFF_LEN + 1 ]; -static char getlabel_buff[ AST__FLUXFRAME_GETLABEL_BUFF_LEN + 1 ]; -static char getsymbol_buff[ AST__FLUXFRAME_GETSYMBOL_BUFF_LEN + 1 ]; -static char gettitle_buff[ AST__FLUXFRAME_GETTITLE_BUFF_LEN + 1 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstFluxFrameVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static int GetObjSize( AstObject *, int * ); -static AstSpecFrame *GetSpecFrame( AstFluxFrame *, int * ); -static AstSystemType DensitySystem( AstSystemType, int * ); -static AstSystemType GetAlignSystem( AstFrame *, int * ); -static AstSystemType GetDensitySystem( AstFluxFrame *, int * ); -static AstSystemType SystemCode( AstFrame *, const char *, int * ); -static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * ); -static const char *DefUnit( AstSystemType, const char *, const char *, int * ); -static const char *DensityUnit( AstSystemType, int * ); -static const char *FluxSystemString( AstSystemType, int * ); -static const char *GetDensityUnit( AstFluxFrame *, int * ); -static const char *GetDomain( AstFrame *, int * ); -static const char *GetLabel( AstFrame *, int, int * ); -static const char *GetSymbol( AstFrame *, int, int * ); -static const char *GetTitle( AstFrame *, int * ); -static const char *GetUnit( AstFrame *, int, int * ); -static const char *SystemLabel( AstSystemType, int * ); -static const char *SystemString( AstFrame *, AstSystemType, int * ); -static int GetActiveUnit( AstFrame *, int * ); -static int MakeFluxMapping( AstFluxFrame *, AstFluxFrame *, AstSystemType, AstMapping **, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int TestActiveUnit( AstFrame *, int * ); -static int UnitsOK( AstSystemType, const char *, int, const char *, const char *, int * ); -static void ClearUnit( AstFrame *, int, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void SetUnit( AstFrame *, int, const char *, int * ); - -static AstSystemType GetSystem( AstFrame *, int * ); -static void SetSystem( AstFrame *, AstSystemType, int * ); -static void ClearSystem( AstFrame *, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static double GetSpecVal( AstFluxFrame *, int * ); -static int TestSpecVal( AstFluxFrame *, int * ); -static void ClearSpecVal( AstFluxFrame *, int * ); -static void SetSpecVal( AstFluxFrame *, double, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astClearAttrib protected -* method inherited from the Frame class). - -* Description: -* This function clears the value of a specified attribute for a -* FluxFrame, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the FluxFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to the FluxFrame structure */ - int len; /* Length of attrib string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* SpecVal. */ -/* -------- */ - if ( !strcmp( attrib, "specval" ) ) { - astClearSpecVal( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearSystem - -* Purpose: -* Clear the System attribute for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* void ClearSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astClearSystem protected -* method inherited from the Frame class). - -* Description: -* This function clears the System attribute for a FluxFrame. - -* Parameters: -* this -* Pointer to the FluxFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to FluxFrame structure */ - AstSystemType newsys; /* System after clearing */ - AstSystemType oldsys; /* System before clearing */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_frame; - -/* Save the original system */ - oldsys = astGetSystem( this_frame ); - -/* Use the parent ClearSystem method to clear the System value. */ - (*parent_clearsystem)( this_frame, status ); - -/* Get the default System. */ - newsys = astGetSystem( this_frame ); - -/* If the system has actually changed. */ - if( newsys != oldsys ) { - -/* Changing the System value will in general require the Units to change - as well. If the used has previously specified the units to be used with - the new system, then re-instate them (they are stored in the "usedunits" - array in the FluxFrame structure). Otherwise, clear the units so that - the default units will eb used with the new System. */ - if( (int) newsys < this->nuunits && this->usedunits && - this->usedunits[ (int) newsys ] ) { - (*parent_setunit)( this_frame, 0, this->usedunits[ (int) newsys ], status ); - } else { - (*parent_clearunit)( this_frame, 0, status ); - } - -/* Also, clear all attributes which have system-specific defaults. */ - astClearLabel( this_frame, 0 ); - astClearSymbol( this_frame, 0 ); - astClearTitle( this_frame ); - } - -} - -static void ClearUnit( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* ClearUnit - -* Purpose: -* Clear the value of the Unit string for a FluxFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* void ClearUnit( AstFrame *this_frame, int axis ) - -* Class Membership: -* FluxFrame member function (over-rides the astClearUnit method inherited -* from the Frame class). - -* Description: -* This function clears the Unit string for a specified axis of a -* FluxFrame. It also clears the UsedUnit item in the FluxFrame -* structure corresponding to the current System. - -* Parameters: -* this -* Pointer to the FluxFrame. -* axis -* The number of the axis (zero-based). -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to the FluxFrame structure */ - int system; /* The FluxFrame's System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astClearUnit" ); - -/* Clear the UsedUnit item for the current System, if current set. */ - system = (int) astGetSystem( this ); - if( system < this->nuunits && this->usedunits ) { - this->usedunits[ system ] = astFree( this->usedunits[ system ] ); - } - -/* Use the parent method to clear the Unit attribute of the axis. */ - (*parent_clearunit)( this_frame, axis, status ); -} - -static const char *DefUnit( AstSystemType system, const char *method, - const char *class, int *status ){ -/* -* Name: -* DefUnit - -* Purpose: -* Return the default units for a flux coordinate system type. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *DefUnit( AstSystemType system, const char *method, -* const char *class, int *status ) - -* Class Membership: -* FluxFrame member function. - -* Description: -* This function returns a textual representation of the default -* units associated with the specified flux coordinate system. - -* Parameters: -* system -* The flux coordinate system. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* As tring describing the default units. This string follows the -* units syntax described in FITS WCS paper I "Representations of world -* coordinates in FITS" (Greisen & Calabretta). - -* Notes: -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Value to return */ - -/* Initialize */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get an identifier for the default units. */ - if( system == AST__FLUXDEN ) { - result = "W/m^2/Hz"; - - } else if( system == AST__FLUXDENW ) { - result = "W/m^2/Angstrom"; - - } else if( system == AST__SBRIGHT ) { - result = "W/m^2/Hz/arcmin**2"; - - } else if( system == AST__SBRIGHTW ) { - result = "W/m^2/Angstrom/arcmin**2"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "%s(%s): Corrupt %s contains illegal System " - "identification code (%d).", status, method, class, class, - (int) system ); - } - -/* Return the result. */ - return result; -} - -static AstSystemType DensitySystem( AstSystemType sys, int *status ) { -/* -* Name: -* DensitySystem - -* Purpose: -* Obtain the System describing the spectral density for a FluxFrame -* system. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* AstSystemType DensitySystem( AstSystemType sys, int *status ) - -* Class Membership: -* FluxFrame member function. - -* Description: -* This function returns AST__FREQ if the FluxFrame system describes -* a quantity measured per unit frequency, and returns AST__WAVELEN if -* the FluxFrame system describes a quantity measured per unit wavelength. - -* Parameters: -* sys -* A System value appropriate to a FluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The density System value. - -* Notes: -* - AST__BADSYSTEM is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Categorise the supplied system. */ - if( sys == AST__FLUXDEN || sys == AST__SBRIGHT ) { - result = AST__FREQ; - - } else if( sys == AST__FLUXDENW || sys == AST__SBRIGHTW ) { - result = AST__WAVELEN; - - } else if( astOK ) { - astError( AST__INTER, "DensitySystem(FluxFrame): The " - "DensitySystem method does not yet support " - "FluxFrame system %d (AST internal programming error).", status, - sys ); - } - -/* Return the result. */ - return result; -} - -static const char *DensityUnit( AstSystemType sys, int *status ) { -/* -* Name: -* DensityUnit - -* Purpose: -* Obtain the default units for the spectral density of a FluxFrame -* system. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *DensityUnit( AstSystemType sys, int *status ) - -* Class Membership: -* FluxFrame member function. - -* Description: -* This function returns "Hz" if the FluxFrame system describes -* a quantity measured per unit frequency, and returns "Angstrom" if -* the FluxFrame system describes a quantity measured per unit wavelength. - -* Parameters: -* sys -* A FluxFrame system value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a null-terminated string containing the Unit value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Categorise the supplied FluxFrame system. */ - if( sys == AST__FLUXDEN || sys == AST__SBRIGHT ) { - result = "Hz"; - - } else if( sys == AST__FLUXDENW || sys == AST__SBRIGHTW ) { - result = "Angstrom"; - - } else if( astOK ) { - astError( AST__INTER, "DensityUnit(FluxFrame): The DensityUnit " - "method does not yet support FluxFrame system %d (AST " - "internal programming error).", status, sys ); - } - -/* Return the result. */ - return result; -} - -static const char *FluxSystemString( AstSystemType system, int *status ) { -/* -* Name: -* FluxSystemString - -* Purpose: -* Convert a FluxFrame coordinate system type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *FluxSystemString( AstSystemType system, int *status ) - -* Class Membership: -* FluxFrame member function - -* Description: -* This function converts a FluxFrame coordinate system type code -* (System attribute value) into a string suitable for use as an -* external representation of the coordinate system type. - -* Parameters: -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. */ - switch ( system ) { - - case AST__FLUXDEN: - result = "FLXDN"; - break; - - case AST__FLUXDENW: - result = "FLXDNW"; - break; - - case AST__SBRIGHT: - result = "SFCBR"; - break; - - case AST__SBRIGHTW: - result = "SFCBRW"; - break; - - } - -/* Return the result pointer. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied FluxFrame, -* in bytes. - -* Parameters: -* this -* Pointer to the FluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to FluxFrame structure */ - int result; /* Result value to return */ - int i; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the FluxFrame structure. */ - this = (AstFluxFrame *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - if( this && this->usedunits ) { - for( i = 0; i < this->nuunits; i++ ) { - result += astTSizeOf( this->usedunits[ i ] ); - } - result += astTSizeOf( this->usedunits ); - } - - result += astGetObjSize( this->specframe ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetActiveUnit - -* Purpose: -* Obtain the value of the ActiveUnit flag for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* int GetActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astGetActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function returns the value of the ActiveUnit flag for a -* FluxFrame, which is always 1. - -* Parameters: -* this -* Pointer to the FluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to use for the ActiveUnit flag (1). - -*/ - return 1; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the protected astGetAttrib -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a FluxFrame, formatted as a character string. - -* Parameters: -* this -* Pointer to the FluxFrame. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - The returned string pointer may point at memory allocated -* within the FluxFrame, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the FluxFrame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFluxFrame *this; /* Pointer to the FluxFrame structure */ - const char *result; /* Pointer value to return */ - double dval; /* Attribute value */ - int len; /* Length of attrib string */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* SpecVal */ -/* ------- */ - if ( !strcmp( attrib, "specval" ) ) { - dval = astGetSpecVal( this ); - if ( astOK ) { - if( dval != AST__BAD ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } else { - result = ""; - } - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetDensitySystem( AstFluxFrame *this, int *status ) { -/* -*+ -* Name: -* astGetDensitySystem - -* Purpose: -* Obtain the System describing the spectral density of a FluxFrame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fluxframe.h" -* AstSystemType astGetDensitySystem( AstFluxFrame *this ) - -* Class Membership: -* FluxFrame method. - -* Description: -* This function returns AST__FREQ if the FluxFrame system describes -* a quantity measured per unit frequency, and returns AST__WAVELEN if -* the FluxFrame system describes a quantity measured per unit wavelength. - -* Parameters: -* this -* Pointer to the FluxFrame. - -* Returned Value: -* The System value. - -* Notes: -* - AST__BADSYSTEM is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return AST__BADSYSTEM; - -/* Get the FluxFrame system and categorise it. */ - return DensitySystem( astGetSystem( this ), status ); -} - -static const char *GetDensityUnit( AstFluxFrame *this, int *status ) { -/* -*+ -* Name: -* astGetDensityUnit - -* Purpose: -* Obtain the default units for the spectral density of a FluxFrame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fluxframe.h" -* const char *astGetDensityUnit( AstFluxFrame *this ) - -* Class Membership: -* FluxFrame method. - -* Description: -* This function returns "Hz" if the FluxFrame system describes -* a quantity measured per unit frequency, and returns "Angstrom" if -* the FluxFrame system describes a quantity measured per unit wavelength. - -* Parameters: -* this -* Pointer to the FluxFrame. - -* Returned Value: -* A pointer to a null-terminated string containing the Unit value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get the FluxFrame system and categorise it. */ - return DensityUnit( astGetSystem( this ), status ); -} - -static const char *GetDomain( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetDomain - -* Purpose: -* Obtain a pointer to the Domain attribute string for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *GetDomain( AstFrame *this, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astGetDomain protected -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the Domain attribute string -* for a FluxFrame. - -* Parameters: -* this -* Pointer to the FluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a constant null-terminated string containing the -* Domain value. - -* Notes: -* - The returned pointer or the string it refers to may become -* invalid following further invocation of this function or -* modification of the FluxFrame. -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to FluxFrame structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_frame; - -/* If a Domain attribute string has been set, invoke the parent method - to obtain a pointer to it. */ - if ( astTestDomain( this ) ) { - result = (*parent_getdomain)( this_frame, status ); - -/* Otherwise, provide a pointer to a suitable default string. */ - } else { - result = "FLUX"; - } - -/* Return the result. */ - return result; -} - -static const char *GetLabel( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetLabel - -* Purpose: -* Access the Label string for a FluxFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *GetLabel( AstFrame *this, int axis, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astGetLabel method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Label string for a specified axis -* of a FluxFrame. - -* Parameters: -* this -* Pointer to the FluxFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstMapping *map; /* Mapping between units */ - AstSystemType system; /* Code identifying type of flux coordinates */ - char *new_lab; /* Modified label string */ - const char *result; /* Pointer to label string */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetLabel" ); - -/* Check if a value has been set for the required axis label string. If so, - invoke the parent astGetLabel method to obtain a pointer to it. */ - if ( astTestLabel( this, axis ) ) { - result = (*parent_getlabel)( this, axis, status ); - -/* Otherwise, identify the flux coordinate system described by the - FluxFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default label string. */ - if ( astOK ) { - result = strcpy( getlabel_buff, SystemLabel( system, status ) ); - getlabel_buff[ 0 ] = toupper( getlabel_buff[ 0 ] ); - -/* Modify this default to take account of the current value of the Unit - attribute, if set. */ - if( astTestUnit( this, axis ) ) { - -/* Find a Mapping from the default Units for the current System, to the - units indicated by the Unit attribute. This Mapping is used to modify - the existing default label appropriately. For instance, if the default - units is "Jy" and the actual units is "log(Jy)", then the default label - of "Flux density" is changed to "log( Flux density )". */ - map = astUnitMapper( DefUnit( system, "astGetLabel", - astGetClass( this ), status ), - astGetUnit( this, axis ), result, - &new_lab ); - if( new_lab ) { - result = strcpy( getlabel_buff, new_lab ); - new_lab = astFree( new_lab ); - } - -/* Annul the unused Mapping. */ - if( map ) map = astAnnul( map ); - - } - } - } - -/* Return the result. */ - return result; -} - -static AstSpecFrame *GetSpecFrame( AstFluxFrame *this, int *status ) { -/* -* Name: -* GetSpecFrame - -* Purpose: -* Get a pointer to a SpecFrame associated with a FluxFrame - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* AstSpecFrame *GetSpecFrame( AstFluxFrame *this, int *status ) - -* Class Membership: -* FluxFrame member function - -* Description: -* This function returns a SpecFrame describing the spectral system in -* which the FluxFrame's SpecVal attribute is stored. A default -* SpecFrame is created and returned if the no SpecFrame was supplied -* when the FluxFrame was created. - -* Parameters: -* this -* The FluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the SpecFrame. It should be freed using astAnnul when no -* longer needed. - -* Notes: -* - A NULL pointer value is returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstSpecFrame *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the FluxFrame contains a SpecFrame, return a clone of its pointer. */ - if( this->specframe ) { - result = astClone( this->specframe ); - -/* Otherwise, create a SpecFrame appropriate to the FluxFrames System. */ - } else { - result = astSpecFrame( "", status ); - astSetSystem( result, astGetDensitySystem( this ) ); - astSetUnit( result, 0, astGetDensityUnit( this ) ); - } - -/* Annul the result if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result pointer. */ - return result; -} - -static const char *GetSymbol( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetSymbol - -* Purpose: -* Obtain a pointer to the Symbol string for a FluxFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *GetSymbol( AstFrame *this, int axis, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astGetSymbol method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Symbol string for a specified axis -* of a FluxFrame. - -* Parameters: -* this -* Pointer to the FluxFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstMapping *map; /* Mapping between units */ - AstSystemType system; /* Code identifying type of sky coordinates */ - char *new_sym; /* Modified symbol string */ - const char *result; /* Pointer to symbol string */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetSymbol" ); - -/* Check if a value has been set for the required axis symbol string. If so, - invoke the parent astGetSymbol method to obtain a pointer to it. */ - if ( astTestSymbol( this, axis ) ) { - result = (*parent_getsymbol)( this, axis, status ); - -/* Otherwise, identify the flux coordinate system described by the FluxFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default Symbol string. */ - if ( astOK ) { - - if( system == AST__FLUXDEN ) { - result = "S_nu"; - - } else if( system == AST__FLUXDENW ) { - result = "S_lambda"; - - } else if( system == AST__SBRIGHT ) { - result = "mu_nu"; - - } else if( system == AST__SBRIGHTW ) { - result = "mu_lambda"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "astGetSymbol(%s): Corrupt %s contains " - "invalid System identification code (%d).", status, - astGetClass( this ), astGetClass( this ), (int) system ); - } - -/* Modify this default to take account of the current value of the Unit - attribute, if set. */ - if( astTestUnit( this, axis ) ) { - -/* Find a Mapping from the default Units for the current System, to the - units indicated by the Unit attribute. This Mapping is used to modify - the existing default symbol appropriately. For instance, if the default - units is "Jy" and the actual units is "log(Jy)", then the default symbol - of "S_nu" is changed to "log( S_nu )". */ - map = astUnitMapper( DefUnit( system, "astGetSymbol", - astGetClass( this ), status ), - astGetUnit( this, axis ), result, - &new_sym ); - if( new_sym ) { - result = strcpy( getsymbol_buff, new_sym ); - new_sym = astFree( new_sym ); - } - -/* Annul the unused Mapping. */ - if( map ) map = astAnnul( map ); - - } - } - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetAlignSystem - -* Purpose: -* Obtain the AlignSystem attribute for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astGetAlignSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the AlignSystem attribute for a FluxFrame. - -* Parameters: -* this -* Pointer to the FluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The AlignSystem value. - -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to FluxFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_frame; - -/* If a AlignSystem attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestAlignSystem( this ) ) { - result = (*parent_getalignsystem)( this_frame, status ); - -/* Otherwise, provide a suitable default. */ - } else { - result = AST__FLUXDEN; - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetSystem - -* Purpose: -* Obtain the System attribute for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* AstSystemType GetSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astGetSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the System attribute for a FluxFrame. - -* Parameters: -* this -* Pointer to the FluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System value. - -* Notes: -* - AST__BADSYSTEM is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to FluxFrame structure */ - AstMapping *map; /* Pointer to unit Mapping */ - AstSystemType i; /* System to check */ - AstSystemType result; /* Value to return */ - const char *units; /* FluxFrame units */ - int unitSet; /* Has a value been supplied for Unit? */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_frame; - -/* See if a value has been assigned to the Unit attribute. */ - unitSet = astTestUnit( this_frame, 0 ); - -/* If a System attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestSystem( this ) ) { - result = (*parent_getsystem)( this_frame, status ); - -/* Otherwise, if the Unit attribute has been set, provide a suitable default - system based on the units. */ - } else if( unitSet ){ - -/* Loop round each known system value. If a Mapping can be found from the - current units to the default units for the system, then use the system as - the default system. */ - units = astGetUnit( this_frame, 0 ); - for( i = FIRST_SYSTEM; i <= LAST_SYSTEM; i++ ) { - map = astUnitMapper( units, DefUnit( i, "astGetSystem", - astGetClass( this ), status ), NULL, NULL ); - if( map ) { - map = astAnnul( map ); - result = i; - break; - } - } - -/* Otherwise, report an error. */ - if( result == AST__BADSYSTEM && astOK ) { - astError( AST__BADUN, "astGetSystem(%s): The current units (%s) " - "cannot be used with any of the supported flux systems.", status, - astGetClass( this ), astGetUnit( this_frame, 0 ) ); - } - -/* Otherwise, provide a suitable default based on the units. */ - } else { - result = AST__FLUXDEN; - } - -/* Return the result. */ - return result; -} - -static const char *GetTitle( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetTitle - -* Purpose: -* Obtain a pointer to the Title string for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *GetTitle( AstFrame *this_frame, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astGetTitle method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Title string for a FluxFrame. -* A pointer to a suitable default string is returned if no Title value has -* previously been set. - -* Parameters: -* this -* Pointer to the FluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null-terminated character string containing the requested -* information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFluxFrame *this; /* Pointer to FluxFrame structure */ - AstSpecFrame *sf; /* Pointer to SpecFrame structure */ - const char *result; /* Pointer to result string */ - const char *sv; /* Formatted SpecVal string */ - const char *su; /* Units string */ - double specval; /* SpecVal value */ - int pos; /* Buffer position to enter text */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_frame); - -/* Initialise. */ - result = NULL; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_frame; - -/* See if a Title string has been set. If so, use the parent astGetTitle - method to obtain a pointer to it. */ - if ( astTestTitle( this ) ) { - result = (*parent_gettitle)( this_frame, status ); - -/* Otherwise, we will generate a default Title string. */ - } else { - -/* Classify the coordinate system type and create an appropriate Title - string. */ - if ( astOK ) { - result = gettitle_buff; - -/* Begin with the system's default label. */ - pos = sprintf( gettitle_buff, "%s", SystemLabel( astGetSystem( this ), status ) ); - gettitle_buff[ 0 ] = toupper( gettitle_buff[ 0 ] ); - -/* Append the spectral position, if known. */ - specval = astGetSpecVal( this ); - sf = GetSpecFrame( this, status ); - if( specval != AST__BAD && sf ) { - sv = astFormat( sf, 0, specval ); - su = astGetUnit( sf, 0 ); - pos += sprintf( gettitle_buff + pos, " at = %s %s", sv, su ); - } - sf = astAnnul( sf ); - } - } - -/* If an error occurred, clear the returned pointer value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static const char *GetUnit( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetUnit - -* Purpose: -* Obtain a pointer to the Unit string for a FluxFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *GetUnit( AstFrame *this_frame, int axis ) - -* Class Membership: -* FluxFrame member function (over-rides the astGetUnit method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Unit string for a specified axis -* of a FluxFrame. If the Unit attribute has not been set for the axis, a -* pointer to a suitable default string is returned instead. - -* Parameters: -* this -* Pointer to the FluxFrame. -* axis -* The number of the axis (zero-based) for which information is required. - -* Returned Value: -* A pointer to a null-terminated string containing the Unit value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to the FluxFrame structure */ - AstSystemType system; /* The FluxFrame's System value */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetUnit" ); - -/* If a value has been set for the Unit attribute, use the parent - GetUnit method to return a pointer to the required Unit string. */ - if( astTestUnit( this, axis ) ){ - result = (*parent_getunit)( this_frame, axis, status ); - -/* Otherwise, identify the flux coordinate system described by the - FluxFrame. */ - } else { - system = astGetSystem( this ); - -/* Return a string describing the default units. */ - result = DefUnit( system, "astGetUnit", astGetClass( this ), status ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -void astInitFluxFrameVtab_( AstFluxFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitFluxFrameVtab - -* Purpose: -* Initialise a virtual function table for a FluxFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "fluxframe.h" -* void astInitFluxFrameVtab( AstFluxFrameVtab *vtab, const char *name ) - -* Class Membership: -* FluxFrame vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the FluxFrame class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameVtab( (AstFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAFluxFrame) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->GetDensitySystem = GetDensitySystem; - vtab->GetDensityUnit = GetDensityUnit; - - vtab->ClearSpecVal = ClearSpecVal; - vtab->TestSpecVal = TestSpecVal; - vtab->GetSpecVal = GetSpecVal; - vtab->SetSpecVal = SetSpecVal; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - frame = (AstFrameVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_getdomain = frame->GetDomain; - frame->GetDomain = GetDomain; - - parent_getsystem = frame->GetSystem; - frame->GetSystem = GetSystem; - parent_setsystem = frame->SetSystem; - frame->SetSystem = SetSystem; - parent_clearsystem = frame->ClearSystem; - frame->ClearSystem = ClearSystem; - - parent_getalignsystem = frame->GetAlignSystem; - frame->GetAlignSystem = GetAlignSystem; - - parent_getlabel = frame->GetLabel; - frame->GetLabel = GetLabel; - - parent_getsymbol = frame->GetSymbol; - frame->GetSymbol = GetSymbol; - - parent_gettitle = frame->GetTitle; - frame->GetTitle = GetTitle; - - parent_clearunit = frame->ClearUnit; - frame->ClearUnit = ClearUnit; - - parent_getunit = frame->GetUnit; - frame->GetUnit = GetUnit; - - parent_setunit = frame->SetUnit; - frame->SetUnit = SetUnit; - - parent_match = frame->Match; - frame->Match = Match; - - parent_overlay = frame->Overlay; - frame->Overlay = Overlay; - - parent_subframe = frame->SubFrame; - frame->SubFrame = SubFrame; - -/* Store replacement pointers for methods which will be over-ridden by new - member functions implemented here. */ - frame->GetActiveUnit = GetActiveUnit; - frame->TestActiveUnit = TestActiveUnit; - frame->ValidateSystem = ValidateSystem; - frame->SystemString = SystemString; - frame->SystemCode = SystemCode; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "FluxFrame", "Description of flux values" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to FluxFrame structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the FluxFrame structure. */ - this = (AstFluxFrame *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->specframe, mode, extra, fail ); - - return result; - -} -#endif - -static int MakeFluxMapping( AstFluxFrame *target, AstFluxFrame *result, - AstSystemType align_sys, AstMapping **map, int *status ) { -/* -* Name: -* MakeFluxMapping - -* Purpose: -* Generate a Mapping between two FluxFrames. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* int MakeFluxMapping( AstFluxFrame *target, AstFluxFrame *result, -* AstSystemType align_sys, MakeFluAstMapping **map, int *status ) - -* Class Membership: -* FluxFrame member function. - -* Description: -* This function takes two FluxFrames and generates a Mapping that -* converts between them, taking account of differences in their -* coordinate systems, reference frequency, etc. -* -* In order to cut down the number of transformations to be considered, -* the scheme works by first converting from the target frame to an -* "alignment" Frame, using the attributes of the target to define the -* transformation. A transformation is then found from the alignment -* frame to the required result Frame, using the attributes of the -* result to define the transformation. The alignment Frame is -* described by the supplied parameter "align_sys". - -* Parameters: -* target -* Pointer to the first FluxFrame. -* result -* Pointer to the second FluxFrame. -* align_sys -* The flux system in which to align the two FluxFrames. -* map -* Pointer to a location which is to receive a pointer to the -* returned Mapping. The forward transformation of this Mapping -* will convert from "target" coordinates to "result" -* coordinates, and the inverse transformation will convert in -* the opposite direction (all coordinate values in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Mapping could be generated, or zero if the two -* FluxFrames are sufficiently un-related that no meaningful Mapping -* can be produced (in which case a NULL Mapping pointer will be -* returned). - -* Notes: -* A value of zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrameSet *fs; - AstMapping *map1; - AstMapping *map2; - AstMapping *map3; - AstMapping *map4; - AstMapping *map5; - AstMapping *smap; - AstMapping *smap_in; - AstMapping *smap_out; - AstMapping *tmap; - AstSpecFrame *sfin1; - AstSpecFrame *sfin2; - AstSpecFrame *sfout1; - AstSpecFrame *sfout2; - AstSystemType rsys_in; - AstSystemType rsys_out; - AstSystemType sys_in; - AstSystemType sys_out; - double specval2; - double specval; - double specval_in; - double specval_out; - double zoom; - int match; - int sb_in; - int sb_out; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise the returned values. */ - match = 0; - *map = NULL; - -/* Initialise to avoid compiler warnings. */ - map1 = NULL; - map2 = NULL; - map3 = NULL; - -/* Note the target and result System */ - rsys_in = astGetSystem( target ); - rsys_out = astGetSystem( result ); - -/* First get a Mapping which converts from the units used in the target - to the default units associated with the target's system. - ---------------------------------------------------------------------- */ - map1 = astUnitMapper( astGetUnit( target, 0 ), - DefUnit( rsys_in, "MakeFluxMapping", "FluxFrame", status ), - NULL, NULL ); - -/* If the target system is surface brightness, change it to the - corresponding flux density system. We are effectively converting from - surface brightness to the flux density normalised to unit area. Also - set flags indicating if the systems are surface brightness systems. */ - if( rsys_in == AST__SBRIGHT ) { - sys_in = AST__FLUXDEN; - sb_in = 1; - - } else if( rsys_in == AST__SBRIGHTW ) { - sys_in = AST__FLUXDENW; - sb_in = 1; - - } else { - sys_in = rsys_in; - sb_in = 0; - } - -/* Likewise if the result system is surface brightness, change it to the - corresponding flux density system. */ - if( rsys_out == AST__SBRIGHT ) { - sys_out = AST__FLUXDEN; - sb_out = 1; - - } else if( rsys_out == AST__SBRIGHTW ) { - sys_out = AST__FLUXDENW; - sb_out = 1; - - } else { - sys_out = rsys_out; - sb_out = 0; - } - -/* Assume at this point in the chain of coversions that we have target values - in some form of flux density system (either frequency or wavelength). The - precise units do not matter at this point (so long as they are - dimensionally correct for describing the relevant form of flux density). - When other systems are added (e.g. antenna temperature), some code - will have to come before this point which produces a Mapping from (e.g.) - antenna temperature to flux density. */ - - -/* Get a Mapping from the default units for the input flux density system - to the default units for the output flux density system. - ---------------------------------------------------------------------- */ - -/* If one but not both of the systems represent surface brightness, then - we cannot form a Mapping. */ - if( sb_in != sb_out ) { - zoom = AST__BAD; - -/* If the input and output flux density systems are the same, then the - required Mapping is a UnitMap. */ - } else if( sys_in == sys_out ) { - zoom = 1.0; - -/* Otherwise, the required Mapping is a zoom map in which the scale factor is - the rate of change of the input spectral system with respect to the output - spectral system, at the position given by the SpecVal attribute (we - cannot do the conversion if the SpecVal values in the target and result - differ). Each spectral system is either wavelength (in Angstrom) or - frequency (in Hz), depending on whether the associated flux density - system is "per Angstrom" or "per Hertz". The SpecVal value may be - stored in some other system, so the first job is to create SpecFrames - with the required system and units from the SpecFrames encapsulated - within the target and result FluxFrames. Take deep copies of the two - SpecFrames, and set their systems and units. */ - } else { - sfin1 = GetSpecFrame( target, status ); - sfin2 = astCopy( sfin1 ); - astSetSystem( sfin2, DensitySystem( sys_in, status ) ); - astSetUnit( sfin2, 0, DensityUnit( sys_in, status ) ); - - sfout1 = GetSpecFrame( result, status ); - sfout2 = astCopy( sfout1 ); - astSetSystem( sfout2, DensitySystem( sys_out, status ) ); - astSetUnit( sfout2, 0, DensityUnit( sys_out, status ) ); - -/* Indicate we do not yet have a zoom factor */ - zoom = AST__BAD; - -/* Get the Mapping from output to input spectral coordinate system */ - fs = astConvert( sfout2, sfin2, "" ); - if( fs ) { - tmap = astGetMapping( fs, AST__BASE, AST__CURRENT ); - fs = astAnnul( fs ); - -/* Simplify the Mapping. */ - smap = astSimplify( tmap ); - tmap = astAnnul( tmap ); - -/* We first need to transform the two SpecVal attributes into the input - coordinate system of the "smap" Mapping (i.e. the standardised result - FluxFrame), and check they are the same. For this we need the Mappings - from the SpecFrames stored in the FluxFrames to the modified copies - created above. */ - fs = astConvert( sfin1, sfin2, "" ); - if( fs ) { - smap_in = astGetMapping( fs, AST__BASE, AST__CURRENT ); - fs = astAnnul( fs ); - } else { - smap_in = NULL; - } - - fs = astConvert( sfout1, sfout2, "" ); - if( fs ) { - smap_out = astGetMapping( fs, AST__BASE, AST__CURRENT ); - fs = astAnnul( fs ); - } else { - smap_out = NULL; - } - -/* Convert the target's SpecVal into the standardised target system */ - specval = astGetSpecVal( target ); - astTran1( smap_in, 1, &specval, 1, &specval2 ); - -/* Now convert it into the standardised result system. Note, we need to - use "smap" in the inverse direction for this. */ - astTran1( smap, 1, &specval2, 0, &specval_in ); - -/* Convert the results's SpecVal into the standardised result system */ - specval = astGetSpecVal( result ); - astTran1( smap_out, 1, &specval, 1, &specval_out ); - -/* Check they are equal and good. */ - if( astEQUALS( specval_in, specval_out, 1.0E8 ) && specval_in != AST__BAD ) { - -/* If the siSimplified Mapping is a UnitMap the required rate of change - factor is 1.0. If it resuts in a ZoomMap, the required factor is - the zoom factor in the ZoomMap. */ - if( astIsAUnitMap( smap ) ) { - zoom = 1.0; - - } else if( astIsAZoomMap( smap ) ) { - zoom = astGetZoom( smap ); - -/* For any other type of Mapping, we must determine the rate of change factor - by differentiating the Mapping at the SpecVal position. */ - } else { - specval = 0.5*( specval_in + specval_out ); - zoom = astRate( smap, &specval, 0, 0 ); - } - } - -/* Free resources */ - if( smap_in ) smap_in = astAnnul( smap_in ); - if( smap_out ) smap_out = astAnnul( smap_out ); - smap = astAnnul( smap ); - } - - sfout1 = astAnnul( sfout1 ); - sfin1 = astAnnul( sfin1 ); - sfout2 = astAnnul( sfout2 ); - sfin2 = astAnnul( sfin2 ); - } - -/* Create the required zoom map if a scaling factor was found. */ - if( zoom != AST__BAD ) { - map2 = (AstMapping *) astZoomMap( 1, fabs( zoom ), "", status ); - } else { - map2 = NULL; - } - -/* Now get a Mapping which converts from the default units associated with - the results's system, to the units used in the result. - ----------------------------------------------------------------------- */ - map3 = astUnitMapper( DefUnit( rsys_out, "MakeFluxMapping", "FluxFrame", status ), - astGetUnit( result, 0 ), NULL, NULL ); - -/* Indicate a match was found and combine all Mapings in series. */ - if( map1 && map2 && map3 ) { - match = 1; - map4 = (AstMapping *) astCmpMap( map1, map2, 1, "", status ); - map5 = (AstMapping *) astCmpMap( map4, map3, 1, "", status ); - -/* Return the simplified Mapping. */ - *map = astSimplify( map5 ); - -/* Free resources. */ - map4 = astAnnul( map4 ); - map5 = astAnnul( map5 ); - } - -/* Free resources. */ - if( map1 ) map1 = astAnnul( map1 ); - if( map2 ) map2 = astAnnul( map2 ); - if( map3 ) map3 = astAnnul( map3 ); - -/* If an error occurred, annul the returned Mapping and clear the returned - values. */ - if ( !astOK ) { - *map = astAnnul( *map ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static int Match( AstFrame *template_frame, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* Match - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the protected astMatch method -* inherited from the Frame class). - -* Description: -* This function matches a "template" FluxFrame to a "target" Frame and -* determines whether it is possible to convert coordinates between them. -* If it is, a mapping that performs the transformation is returned along -* with a new Frame that describes the coordinate system that results when -* this mapping is applied to the "target" coordinate system. In addition, -* information is returned to allow the axes in this "result" Frame to be -* associated with the corresponding axes in the "target" and "template" -* Frames from which they are derived. - -* Parameters: -* template -* Pointer to the template FluxFrame. This describes the coordinate -* system (or set of possible coordinate systems) into which we wish to -* convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate system in -* which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case. -* template_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the template FluxFrame axis from -* which it is derived. If it is not derived from any template -* FluxFrame axis, a value of -1 will be returned instead. -* target_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the target Frame axis from which it -* is derived. If it is not derived from any target Frame axis, a value -* of -1 will be returned instead. -* map -* Address of a location where a pointer to a new Mapping will be -* returned if the requested coordinate conversion is possible. If -* returned, the forward transformation of this Mapping may be used to -* convert coordinates between the "target" Frame and the "result" -* Frame (see below) and the inverse transformation will convert in the -* opposite direction. -* result -* Address of a location where a pointer to a new Frame will be returned -* if the requested coordinate conversion is possible. If returned, this -* Frame describes the coordinate system that results from applying the -* returned Mapping (above) to the "target" coordinate system. In -* general, this Frame will combine attributes from (and will therefore -* be more specific than) both the target and the template Frames. In -* particular, when the template allows the possibility of transformaing -* to any one of a set of alternative coordinate systems, the "result" -* Frame will indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate conversion is -* possible. Otherwise zero is returned (this will not in itself result in -* an error condition). - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* This implementation addresses the matching of a FluxFrame class -* object to any other class of Frame. A FluxFrame will match any class -* of FluxFrame (i.e. possibly from a derived class) but will not match -* a less specialised class of Frame. -*/ - -/* Local Variables: */ - AstFrame *frame0; /* Pointer to Frame underlying axis 0 */ - AstFluxFrame *template; /* Pointer to template FluxFrame structure */ - int iaxis0; /* Axis index underlying axis 0 */ - int iaxis; /* Axis index */ - int match; /* Coordinate conversion possible? */ - int target_axis0; /* Index of FluxFrame axis in the target */ - int target_naxes; /* Number of target axes */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the template FluxFrame structure. */ - template = (AstFluxFrame *) template_frame; - -/* Obtain the number of axes in the target Frame. */ - target_naxes = astGetNaxes( target ); - -/* The first criterion for a match is that the template matches as a - Frame class object. This ensures that the number of axes (1) and - domain, etc. of the target Frame are suitable. Invoke the parent - "astMatch" method to verify this. */ - match = (*parent_match)( template_frame, target, matchsub, - template_axes, target_axes, map, result, status ); - -/* If a match was found, annul the returned objects, which are not - needed, but keep the memory allocated for the axis association - arrays, which we will re-use. */ - if ( astOK && match ) { - *map = astAnnul( *map ); - *result = astAnnul( *result ); - } - -/* If OK so far, obtain pointers to the primary Frames which underlie - all target axes. Stop when a FluxFrame axis is found. */ - if ( match && astOK ) { - match = 0; - for( iaxis = 0; iaxis < target_naxes; iaxis++ ) { - astPrimaryFrame( target, iaxis, &frame0, &iaxis0 ); - if( astIsAFluxFrame( frame0 ) ) { - frame0 = astAnnul( frame0 ); - target_axis0 = iaxis; - match = 1; - break; - } else { - frame0 = astAnnul( frame0 ); - } - } - } - -/* Check at least one FluxFrame axis was found it the target. Store the - axis associataions. */ - if( match && astOK ) { - (*template_axes)[ 0 ] = 0; - (*target_axes)[ 0 ] = target_axis0; - -/* Use the target's "astSubFrame" method to create a new Frame (the - result Frame) with copies of the target axes in the required - order. This process also overlays the template attributes on to the - target Frame and returns a Mapping between the target and result - Frames which effects the required coordinate conversion. */ - match = astSubFrame( target, template, 1, *target_axes, *template_axes, - map, result ); - } - -/* If an error occurred, or conversion to the result Frame's - coordinate system was not possible, then free all memory, annul the - returned objects, and reset the returned value. */ - if ( !astOK || !match ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static void Overlay( AstFrame *template, const int *template_axes, - AstFrame *result, int *status ) { -/* -* Name: -* Overlay - -* Purpose: -* Overlay the attributes of a template FluxFrame on to another Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* void Overlay( AstFrame *template, const int *template_axes, -* AstFrame *result, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the protected astOverlay method -* inherited from the Frame class). - -* Description: -* This function overlays attributes of a FluxFrame (the "template") on to -* another Frame, so as to over-ride selected attributes of that second -* Frame. Normally only those attributes which have been specifically set -* in the template will be transferred. This implements a form of -* defaulting, in which a Frame acquires attributes from the template, but -* retains its original attributes (as the default) if new values have not -* previously been explicitly set in the template. -* -* Note that if the result Frame is a FluxFrame and a change of flux -* coordinate system occurs as a result of overlaying its System -* attribute, then some of its original attribute values may no -* longer be appropriate (e.g. the Title, or attributes describing -* its axes). In this case, these will be cleared before overlaying -* any new values. - -* Parameters: -* template -* Pointer to the template FluxFrame, for which values should have been -* explicitly set for any attribute which is to be transferred. -* template_axes -* Pointer to an array of int, with one element for each axis of the -* "result" Frame (see below). For each axis in the result frame, the -* corresponding element of this array should contain the (zero-based) -* index of the template axis to which it corresponds. This array is used -* to establish from which template axis any axis-dependent attributes -* should be obtained. -* -* If any axis in the result Frame is not associated with a template -* axis, the corresponding element of this array should be set to -1. -* -* If a NULL pointer is supplied, the template and result axis -* indices are assumed to be identical. -* result -* Pointer to the Frame which is to receive the new attribute values. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - In general, if the result Frame is not from the same class as the -* template FluxFrame, or from a class derived from it, then attributes may -* exist in the template FluxFrame which do not exist in the result Frame. -* In this case, these attributes will not be transferred. -*/ - - -/* Local Variables: */ - AstFluxFrame *resff; /* Result FluxFrame */ - AstFluxFrame *tmpff; /* Template FluxFrame */ - AstSystemType new_alignsystem;/* Code identifying alignment coords */ - AstSystemType new_system; /* Code identifying new cordinates */ - AstSystemType old_system; /* Code identifying old coordinates */ - const char *method; /* Pointer to method string */ - const char *new_class; /* Pointer to template class string */ - const char *old_class; /* Pointer to result class string */ - int fluxframe; /* Result Frame is a FluxFrame? */ - int resetSystem; /* Was the template System value cleared? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise strings used in error messages. */ - new_class = astGetClass( template ); - old_class = astGetClass( result ); - method = "astOverlay"; - -/* Get the old and new systems. */ - old_system = astGetSystem( result ); - new_system = astGetSystem( template ); - -/* If the result Frame is a FluxFrame, we must test to see if overlaying its - System attribute will change the type of coordinate system it describes. - Determine the value of this attribute for the result and template - FluxFrames. */ - resetSystem = 0; - fluxframe = astIsAFluxFrame( result ); - if( fluxframe ) { - -/* If the coordinate system will change, any value already set for the result - FluxFrame's Title will no longer be appropriate, so clear it. */ - if ( new_system != old_system ) { - astClearTitle( result ); - -/* If the systems have the same default units, we can retain the current - Unit value. */ - if( strcmp( DefUnit( new_system, method, new_class, status ), - DefUnit( old_system, method, old_class, status ) ) ) { - astClearUnit( result, 0 ); - } - -/* If necessary, clear inappropriate values for all those axis attributes - whose access functions are over-ridden by this class (these access functions - will then provide suitable defaults appropriate to the new coordinate system - instead). */ - astClearLabel( result, 0 ); - astClearSymbol( result, 0 ); - } - -/* Transfer the default SpecVal value and the SpecFrame. */ - resff = (AstFluxFrame *) result; - tmpff = (AstFluxFrame *) template; - resff->defspecval = tmpff->defspecval; - if( resff->specframe ) (void) astAnnul( resff->specframe ); - resff->specframe = tmpff->specframe ? astCopy( tmpff->specframe ) : NULL; - -/* If the result Frame is not a FluxFrame, we must temporarily clear the - System and AlignSystem values since the values used by this class are only - appropriate to this class. */ - } else { - if( astTestSystem( template ) ) { - astClearSystem( template ); - - new_alignsystem = astGetAlignSystem( template ); - astClearAlignSystem( template ); - - resetSystem = 1; - } - } - -/* Invoke the parent class astOverlay method to transfer attributes inherited - from the parent class. */ - (*parent_overlay)( template, template_axes, result, status ); - -/* Reset the System and AlignSystem values if necessary */ - if( resetSystem ) { - astSetSystem( template, new_system ); - astSetAlignSystem( template, new_alignsystem ); - } - -/* Check if the result Frame is a FluxFrame or from a class derived from - FluxFrame. If not, we cannot transfer FluxFrame attributes to it as it is - insufficiently specialised. In this case simply omit these attributes. */ - if ( fluxframe && astOK ) { - -/* Define macros that test whether an attribute is set in the template and, - if so, transfers its value to the result. */ -#define OVERLAY(attribute) \ - if ( astTest##attribute( template ) ) { \ - astSet##attribute( result, astGet##attribute( template ) ); \ - } - -/* Use the macro to transfer each FluxFrame attribute in turn. */ - OVERLAY(SpecVal) - - - } - -/* Undefine macros local to this function. */ -#undef OVERLAY -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* FluxFrame member function (extends the astSetAttrib method inherited from -* the Mapping class). - -* Description: -* This function assigns an attribute value for a FluxFrame, the attribute -* and its value being specified by means of a string of the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in lower -* case with no white space present. The value to the right of the "=" -* should be a suitable textual representation of the value to be assigned -* and this will be interpreted according to the attribute's data type. -* White space surrounding the value is only significant for string -* attributes. - -* Parameters: -* this -* Pointer to the FluxFrame. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This protected method is intended to be invoked by the Object astSet -* method and makes additional attributes accessible to it. -*/ - -/* Local Vaiables: */ - AstFluxFrame *this; /* Pointer to the FluxFrame structure */ - double dval; /* Floating point attribute value */ - int len; /* Length of setting string */ - int nc; /* No. of characters read */ - int ulen; /* Used length of setting string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Obtain the used length of the setting string. */ - ulen = astChrLen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* SpecVal. */ -/* -------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "specval= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetSpecVal( this, dval ); - -/* Pass any unrecognised setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status ) { -/* -* Name: -* SetSystem - -* Purpose: -* Set the System attribute for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astSetSystem protected -* method inherited from the Frame class). - -* Description: -* This function sets the System attribute for a FluxFrame. - -* Parameters: -* this -* Pointer to the FluxFrame. -* newsys -* The new System value to be stored. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to FluxFrame structure */ - AstSystemType oldsys; /* Original System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_frame; - -/* Save the original System value */ - oldsys = astGetSystem( this_frame ); - -/* Use the parent SetSystem method to store the new System value. */ - (*parent_setsystem)( this_frame, newsys, status ); - -/* If the system has changed... */ - if( oldsys != newsys ) { - -/* Changing the System value will in general require the Units to change - as well. If the user has previously specified the units to be used with - the new system, then re-instate them (they are stored in the "usedunits" - array in the FluxFrame structure). Otherwise, clear the units so that - the default units will eb used with the new System. */ - if( (int) newsys < this->nuunits && this->usedunits && - this->usedunits[ (int) newsys ] ) { - (*parent_setunit)( this_frame, 0, this->usedunits[ (int) newsys ], status ); - } else { - (*parent_clearunit)( this_frame, 0, status ); - } - -/* Also, clear all attributes which have system-specific defaults. */ - astClearLabel( this_frame, 0 ); - astClearSymbol( this_frame, 0 ); - astClearTitle( this_frame ); - } -} - -static void SetUnit( AstFrame *this_frame, int axis, const char *value, int *status ) { -/* -* Name: -* SetUnit - -* Purpose: -* Set a pointer to the Unit string for a FluxFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* void SetUnit( AstFrame *this_frame, int axis, const char *value ) - -* Class Membership: -* FluxFrame member function (over-rides the astSetUnit method inherited -* from the Frame class). - -* Description: -* This function stores a pointer to the Unit string for a specified axis -* of a FluxFrame. It also stores the string in the "usedunits" array -* in the FluxFrame structure, in the element associated with the -* current System. - -* Parameters: -* this -* Pointer to the FluxFrame. -* axis -* The number of the axis (zero-based) for which information is required. -* unit -* The new string to store. -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to the FluxFrame structure */ - AstSystemType system; /* The FluxFrame's System value */ - int i; /* Loop counter */ - int isystem; /* The FluxFrame's System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Use the parent SetUnit method to store the value in the Axis - structure */ - (*parent_setunit)( this_frame, axis, value, status ); - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astSetUnit" ); - -/* If the new units are appropriate for the current System, store the - supplied value as the UsedUnit for the current System. First ensure the - array is big enough. Free any previous value stored for the current - system. */ - system = astGetSystem( this ); - if( UnitsOK( system, value, 0, "astSetUnit", astGetClass( this ), status ) ) { - isystem = (int) astGetSystem( this ); - if( isystem >= this->nuunits ) { - this->usedunits = astGrow( this->usedunits, isystem + 1, - sizeof(char *) ); - if( astOK ) { - for( i = this->nuunits; i < isystem + 1; i++ ) this->usedunits[ i ] = NULL; - this->nuunits = isystem + 1; - } - } - -/* Now store a copy of the value, if it is different to the stored string. */ - if( astOK && ( !this->usedunits[ isystem ] || - strcmp( this->usedunits[ isystem ], value ) ) ) { - this->usedunits[ isystem ] = astStore( this->usedunits[ isystem ], - value, strlen( value ) + 1 ); - } - -/* If the new units are not appropriate for the current System, clear the - System value. Use the parent ClearSystem function since the - astClearSystem implemented by this class will clear the units. */ - } else { - (*parent_clearsystem)( this_frame, status ); - } - -} - -static int SubFrame( AstFrame *target_frame, AstFrame *template, - int result_naxes, const int *target_axes, - const int *template_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* SubFrame - -* Purpose: -* Select axes from a FluxFrame and convert to the new coordinate -* system. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* int SubFrame( AstFrame *target, AstFrame *template, -* int result_naxes, const int *target_axes, -* const int *template_axes, AstMapping **map, -* AstFrame **result, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the protected astSubFrame -* method inherited from the Frame class). - -* Description: -* This function selects a requested sub-set (or super-set) of the axes -* from a "target" FluxFrame and creates a new Frame with copies of -* the selected axes assembled in the requested order. It then -* optionally overlays the attributes of a "template" Frame on to the -* result. It returns both the resulting Frame and a Mapping that -* describes how to convert between the coordinate systems described by -* the target and result Frames. If necessary, this Mapping takes -* account of any differences in the Frames' attributes due to the -* influence of the template. - -* Parameters: -* target -* Pointer to the target FluxFrame, from which axes are to be -* selected. -* template -* Pointer to the template Frame, from which new attributes for the -* result Frame are to be obtained. Optionally, this may be NULL, in -* which case no overlaying of template attributes will be performed. -* result_naxes -* Number of axes to be selected from the target Frame. This number may -* be greater than or less than the number of axes in this Frame (or -* equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving a list -* of the (zero-based) axis indices of the axes to be selected from the -* target FluxFrame. The order in which these are given determines -* the order in which the axes appear in the result Frame. If any of the -* values in this array is set to -1, the corresponding result axis will -* not be derived from the target Frame, but will be assigned default -* attributes instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This should -* contain a list of the template axes (given as zero-based axis indices) -* with which the axes of the result Frame are to be associated. This -* array determines which axes are used when overlaying axis-dependent -* attributes of the template on to the result. If any element of this -* array is set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not used and -* a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned Mapping. -* The forward transformation of this Mapping will describe how to -* convert coordinates from the coordinate system described by the target -* FluxFrame to that described by the result Frame. The inverse -* transformation will convert in the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is possible -* between the target and the result Frame. Otherwise zero is returned and -* *map and *result are returned as NULL (but this will not in itself -* result in an error condition). In general, coordinate conversion should -* always be possible if no template Frame is supplied but may not always -* be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* - This implementation addresses the selection of axes from a -* FluxFrame object. This results in another object of the same class -* only if the single FluxFrame axis is selected exactly once. -* Otherwise, the result is a Frame class object which inherits the -* FluxFrame's axis information (if appropriate) but none of the other -* properties of a FluxFrame. -* - In the event that a FluxFrame results, the returned Mapping will -* take proper account of the relationship between the target and result -* coordinate systems. -* - In the event that a Frame class object results, the returned Mapping -* will only represent a selection/permutation of axes. - -* Implementation Deficiencies: -* - Any axis selection is currently permitted. Probably this should be -* restricted so that each axis can only be selected once. The -* astValidateAxisSelection method will do this but currently there are bugs -* in the CmpFrame class that cause axis selections which will not pass this -* test. Install the validation when these are fixed. -*/ - -/* Local Variables: */ - AstFluxFrame *target; /* Pointer to the FluxFrame structure */ - AstFluxFrame *temp; /* Pointer to copy of target FluxFrame */ - AstSystemType align_sys; /* System in which to align the FluxFrames */ - int match; /* Coordinate conversion is possible? */ - int report; /* Report errors if FluxFrames cannot be aligned? */ - -/* Initialise the returned values. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the target FluxFrame structure. */ - target = (AstFluxFrame *) target_frame; - -/* Result is a FluxFrame. */ -/* -------------------------- */ -/* Check if the result Frame is to have one axis obtained by selecting - the single target FluxFrame axis. If so, the result will also be - a FluxFrame. */ - if ( ( result_naxes == 1 ) && ( target_axes[ 0 ] == 0 ) ) { - -/* Form the result from a copy of the target. */ - *result = astCopy( target ); - -/* Initialise a flag to indicate that MakeFluxMapping should not report - errors if no Mapping can be created. */ - report = 0; - -/* If required, overlay the template attributes on to the result FluxFrame. - Also get the system in which to align the two FluxFrames. These are the - values from the template (if there is a template). */ - if ( template ) { - astOverlay( template, template_axes, *result ); - if( astIsAFluxFrame( template ) ) { - align_sys = astGetAlignSystem( template ); - -/* Since we now know that both the template and target are FluxFrames, it - should usually be possible to convert betwen them. If conversion is - *not* possible then the user will probably be interested in knowing the - reason why conversion is not possible. Therefore, indicate that - MakeFluxMapping should report errors if no Mapping can be created. */ - report = 1; - - } else { - align_sys = astGetAlignSystem( target ); - } - -/* If no template was supplied, align in the System of the target. */ - } else { - align_sys = astGetSystem( target ); - } - -/* Generate a Mapping that takes account of changes in the coordinate system - between the target FluxFrame and the result FluxFrame. If this Mapping can - be generated, set "match" to indicate that coordinate conversion is - possible. If the template is a fluxframe, report errors if a match is not - possible. */ - match = ( MakeFluxMapping( target, (AstFluxFrame *) *result, - align_sys, map, status ) != 0 ); - -/* Result is not a FluxFrame. */ -/* ------------------------------ */ -/* In this case, we select axes as if the target were from the Frame - class. However, since the resulting data will then be separated - from their enclosing FluxFrame, default attribute values may differ - if the methods for obtaining them were over-ridden by the FluxFrame - class. To overcome this, we ensure that these values are explicitly - set for the result Frame (rather than relying on their defaults). */ - } else { - -/* Make a temporary copy of the target FluxFrame. We will explicitly - set the attribute values in this copy so as not to modify the original. */ - temp = astCopy( target ); - -/* Define a macro to test if an attribute is set. If not, set it - explicitly to its default value. */ -#define SET(attribute) \ - if ( !astTest##attribute( temp ) ) { \ - astSet##attribute( temp, astGet##attribute( temp ) ); \ - } - -/* Set attribute values which apply to the Frame as a whole and which - we want to retain, but whose defaults are over-ridden by the - FluxFrame class. */ - SET(Domain) - SET(Title) - -/* Define a macro to test if an attribute is set for axis zero (the only - axis of a FluxFrame). If not, set it explicitly to its default value. */ -#define SET_AXIS(attribute) \ - if ( !astTest##attribute( temp, 0 ) ) { \ - astSet##attribute( temp, 0, \ - astGet##attribute( temp, 0 ) ); \ - } - -/* Use this macro to set explicit values for all the axis attributes - for which the FluxFrame class over-rides the default value. */ - SET_AXIS(Label) - SET_AXIS(Symbol) - SET_AXIS(Unit) - -/* Clear attributes which have an extended range of values allowed by - this class. */ - astClearSystem( temp ); - astClearAlignSystem( temp ); - -/* Invoke the astSubFrame method inherited from the Frame class to - produce the result Frame by selecting the required set of axes and - overlaying the template Frame's attributes. */ - match = (*parent_subframe)( (AstFrame *) temp, template, - result_naxes, target_axes, template_axes, - map, result, status ); - -/* Delete the temporary copy of the target FluxFrame. */ - temp = astDelete( temp ); - } - -/* If an error occurred or no match was found, annul the returned - objects and reset the returned result. */ - if ( !astOK || !match ) { - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; - -/* Undefine macros local to this function. */ -#undef SET -#undef SET_AXIS -} - -static AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) { -/* -* Name: -* SystemCode - -* Purpose: -* Convert a string into a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astSystemCode method -* inherited from the Frame class). - -* Description: -* This function converts a string used for the external -* description of a coordinate system into a FluxFrame -* coordinate system type code (System attribute value). It is the -* inverse of the astSystemString function. - -* Parameters: -* this -* The Frame. -* system -* Pointer to a constant null-terminated string containing the -* external description of the sky coordinate system. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System type code. - -* Notes: -* - A value of AST__BADSYSTEM is returned if the sky coordinate -* system description was not recognised. This does not produce an -* error. -* - A value of AST__BADSYSTEM is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" string against each possibility and assign the - result. */ - if ( astChrMatch( "FLXDN", system ) ) { - result = AST__FLUXDEN; - - } else if ( astChrMatch( "FLXDNW", system ) ) { - result = AST__FLUXDENW; - - }else if ( astChrMatch( "SFCBR", system ) ) { - result = AST__SBRIGHT; - - } else if ( astChrMatch( "SRCBR", system ) ) { - result = AST__SBRIGHTW; - - } - -/* Return the result. */ - return result; -} - -static const char *SystemLabel( AstSystemType system, int *status ) { -/* -* Name: -* SystemLabel - -* Purpose: -* Return a label for a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *SystemLabel( AstSystemType system, int *status ) - -* Class Membership: -* FluxFrame member function. - -* Description: -* This function converts a FluxFrame coordinate system type code -* (System attribute value) into a descriptive string for human readers. - -* Parameters: -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the sky coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. */ - switch ( system ) { - - case AST__FLUXDEN: - result = "flux density"; - break; - - case AST__FLUXDENW: - result = "flux wavelength density"; - break; - - case AST__SBRIGHT: - result = "surface brightness"; - break; - - case AST__SBRIGHTW: - result = "surface brightness (per wavelength)"; - break; - - } - -/* Return the result pointer. */ - return result; -} - -static const char *SystemString( AstFrame *this, AstSystemType system, int *status ) { -/* -* Name: -* SystemString - -* Purpose: -* Convert a coordinate system type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* const char *SystemString( AstFrame *this, AstSystemType system, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astSystemString method -* inherited from the Frame class). - -* Description: -* This function converts a FluxFrame coordinate system type code -* (System attribute value) into a string suitable for use as an -* external representation of the coordinate system type. - -* Parameters: -* this -* The Frame. -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - - return FluxSystemString( system, status ); -} - -static int TestActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* TestActiveUnit - -* Purpose: -* Test the ActiveUnit flag for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* int TestActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astTestActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function test the value of the ActiveUnit flag for a FluxFrame, -* which is always "unset". - -* Parameters: -* this -* Pointer to the FluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The result of the test (0). - -*/ - return 0; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a FluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astTestAttrib protected -* method inherited from the Frame class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a FluxFrame's attributes. - -* Parameters: -* this -* Pointer to the FluxFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to the FluxFrame structure */ - int len; /* Length of attrib string */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* SpecVal. */ -/* -------- */ - if ( !strcmp( attrib, "specval" ) ) { - result = astTestSpecVal( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static int UnitsOK( AstSystemType system, const char *units, int report, - const char *method, const char *class, int *status ) { -/* -* Name: -* UnitsOK - -* Purpose: -* Check if a units string is appropriate for the current System. - -* Type: -* Private function. - -* Synopsis: -* #include "fluxframe.h" -* int UnitsOK( AstSystemType system, const char *units, int report, -* const char *method, const char *class, int *status ) - -* Class Membership: -* FluxFrame member function - -* Description: -* This function returns a non-zero value if the supplied units string -* can be mapped to the defaultunits for the current System in the -* supplied FluxFrame. - -* Parameters: -* system -* The system type to check. -* unit -* The units string to check. -* report -* Should an error be reported if the units and system are -* inconsistent? -* method -* String holding a method name to be used in error messages. -* class -* String holding a class name to be used in error messages. -* status -* Pointer to the inherited status variable. - -* Returns Value: -* Non-zero if the units string can be used to describe the current -* flux System. Zero otherwise. - -*/ - -/* Local Variables: */ - AstMapping *map; - int result; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get the Mapping from the default units for the supplied system to the - supplied Units. */ - map = astUnitMapper( DefUnit( system, method, class, status ), units, NULL, NULL ); - -/* If a Mapping was found succesfully, annul it and return non-zero. - Otherwise return zero. */ - if( map ) { - result = 1; - map = astAnnul( map ); - - } else { - result = 0; - -/* Report an error if required. */ - if( report && astOK ) { - astError( AST__BADUN, "%s(%s): The units (%s) and system (%s) " - "within the supplied %s are inconsistent.", status, method, - class, units, FluxSystemString( system, status ), class ); - } - } - -/* Return the result. */ - return result; -} - -static int ValidateSystem( AstFrame *this, AstSystemType system, const char *method, int *status ) { -/* -* -* Name: -* ValidateSystem - -* Purpose: -* Validate a value for a Frame's System attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "fluxframe.h" -* int ValidateSystem( AstFrame *this, AstSystemType system, -* const char *method, int *status ) - -* Class Membership: -* FluxFrame member function (over-rides the astValidateSystem method -* inherited from the Frame class). - -* Description: -* This function checks the validity of the supplied system value. -* If the value is valid, it is returned unchanged. Otherwise, an -* error is reported and a value of AST__BADSYSTEM is returned. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The system value to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The validated system value. - -* Notes: -* - A value of AST__BADSYSTEM will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Validated system value */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the value is out of bounds, report an error. */ - if ( system < FIRST_SYSTEM || system > LAST_SYSTEM ) { - astError( AST__AXIIN, "%s(%s): Bad value (%d) given for the System " - "or AlignSystem attribute of a %s.", status, method, - astGetClass( this ), (int) system, astGetClass( this ) ); - -/* Otherwise, return the supplied value. */ - } else { - result = system; - } - -/* Return the result. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* -*att++ -* Name: -* SpecVal - -* Purpose: -* The spectral position at which flux values are measured. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the spectral position (frequency, wavelength, -* etc.), at which the values described by the FluxFrame are measured. -* It is used when determining the Mapping between between FluxFrames. -* -* The default value and spectral system used for this attribute are -* both specified when the FluxFrame is created. - -* Applicability: -* FluxFrame -* All FluxFrames have this attribute. - -*att-- -*/ -astMAKE_CLEAR(FluxFrame,SpecVal,specval,AST__BAD) -astMAKE_GET(FluxFrame,SpecVal,double,AST__BAD,((this->specval!=AST__BAD)?this->specval:this->defspecval)) -astMAKE_SET(FluxFrame,SpecVal,double,specval,value) -astMAKE_TEST(FluxFrame,SpecVal,( this->specval != AST__BAD )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for FluxFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for FluxFrame objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstFluxFrame *in; /* Pointer to input FluxFrame */ - AstFluxFrame *out; /* Pointer to output FluxFrame */ - char *usedunit; /* Pointer to an element of usedunits array */ - int i; /* Loop count */ - int nused; /* Size of "usedunits" array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output FluxFrames. */ - in = (AstFluxFrame *) objin; - out = (AstFluxFrame *) objout; - -/* Nullify the pointers stored in the output object since these will - currently be pointing at the input data (since the output is a simple - byte-for-byte copy of the input). Otherwise, the input data could be - freed by accidient if the output object is deleted due to an error - occuring in this function. */ - out->usedunits = NULL; - out->specframe = NULL; - -/* Store the last used units in the output SpecMap. */ - if( in && in->usedunits ) { - nused = in->nuunits; - out->usedunits = astMalloc( nused*sizeof( char * ) ); - if( out->usedunits ) { - for( i = 0; i < nused; i++ ) { - usedunit = in->usedunits[ i ]; - if( usedunit ) { - out->usedunits[ i ] = astStore( NULL, usedunit, - strlen( usedunit ) + 1 ); - } else { - out->usedunits[ i ] = NULL; - } - } - } - } - -/* Copy the SpecFrame */ - if( in->specframe ) out->specframe = astCopy( in->specframe ); - -/* If an error has occurred, free the output resources. */ - if( !astOK ) Delete( (AstObject *) out, status ); - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for FluxFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for FluxFrame objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstFluxFrame *this; - int i; - -/* Release the memory referred to in the FluxFrame structure. */ - this = (AstFluxFrame *) obj; - if( this && this->usedunits ) { - for( i = 0; i < this->nuunits; i++ ) { - this->usedunits[ i ] = astFree( this->usedunits[ i ] ); - } - this->usedunits = astFree( this->usedunits ); - } - -/* Annulthe SpecFrame. */ - if( this->specframe ) this->specframe = astAnnul( this->specframe ); - -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for FluxFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the FluxFrame class to an output Channel. - -* Parameters: -* this -* Pointer to the FluxFrame whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFluxFrame *this; /* Pointer to the FluxFrame structure */ - char buff[ 20 ]; /* Buffer for item name */ - char comm[ 50 ]; /* Buffer for comment */ - double dval; /* Double value */ - int i; /* Loop count */ - int j; /* Loop count */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FluxFrame structure. */ - this = (AstFluxFrame *) this_object; - -/* Write out values representing the instance variables for the - FluxFrame class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* SpecVal. */ -/* -------- */ - set = TestSpecVal( this, status ); - dval = set ? GetSpecVal( this, status ) : astGetSpecVal( this ); - if( dval != AST__BAD ) { - astWriteDouble( channel, "SpcVl", set, 0, dval, "Spectral position" ); - } - -/* The SpecFrame */ -/* ------------- */ - if( this->specframe ) { - astWriteObject( channel, "SpcFr", 1, 0, this->specframe, "SpcVl coord system" ); - } - -/* Default SpecVal. */ -/* ---------------- */ - if( this->defspecval != AST__BAD ) { - astWriteDouble( channel, "DfSpc", 1, 0, this->defspecval, "Default spectral position" ); - } - -/* UsedUnits */ -/* --------- */ - if( this->usedunits ) { - for( i = 0; i < this->nuunits; i++ ) { - if( this->usedunits[ i ] ) { - sprintf( buff, "U%s", astSystemString( this, (AstSystemType) i )); - for( j = 2; j < strlen( buff ); j++ ) buff[ j ] = tolower( buff[ j ] ); - sprintf( comm, "Preferred units for %s", SystemLabel( (AstSystemType) i, status ) ); - astWriteString( channel, buff, 1, 0, this->usedunits[ i ], comm ); - } - } - } -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAFluxFrame and astCheckFluxFrame functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(FluxFrame,Frame) -astMAKE_CHECK(FluxFrame) - -AstFluxFrame *astFluxFrame_( double specval, void *specfrm_void, - const char *options, int *status, ...) { -/* -*+ -* Name: -* astFluxFrame - -* Purpose: -* Create a FluxFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "fluxframe.h" -* AstFluxFrame *astFluxFrame( double specval, AstSpecFrame *specfrm, -* const char *options, ..., int *status ) - -* Class Membership: -* FluxFrame constructor. - -* Description: -* This function creates a new FluxFrame and optionally initialises its -* attributes. - -* Parameters: -* specval -* The spectral value to which the flux values refer, given in the -* spectral coordinate system specified by "specfrm". The value -* supplied for the "specval" parameter becomes the default value for -* the SpecVal attribute. -* specfrm -* A pointer to a SpecFrame describing the spectral coordinate system -* in which the "specval" parameter is given. A deep copy of this object -* is taken, so any subsequent changes to the SpecFrame using the -* supplied pointer will have no effect on the new FluxFrame. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new FluxFrame. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new FluxFrame. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic FluxFrame constructor which -* is available via the protected interface to the FluxFrame class. -* A public interface is provided by the astFluxFrameId_ function. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *um; /* Mapping from default to actual units */ - AstFluxFrame *new; /* Pointer to new FluxFrame */ - AstSpecFrame *sfrm; /* Pointer to SpecFrame */ - AstSystemType s; /* System */ - const char *u; /* Units string */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the SpecFrame structures provided. */ - sfrm = specfrm_void ? astCheckSpecFrame( specfrm_void ) : NULL; - -/* Initialise the FluxFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitFluxFrame( NULL, sizeof( AstFluxFrame ), !class_init, - &class_vtab, "FluxFrame", specval, sfrm ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new FluxFrame's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* Check the Units are appropriate for the System. */ - u = astGetUnit( new, 0 ); - s = astGetSystem( new ); - um = astUnitMapper( DefUnit( s, "astFluxFrame", "FluxFrame", status ), - u, NULL, NULL ); - if( um ) { - um = astAnnul( um ); - } else { - astError( AST__BADUN, "astFluxFrame: Inappropriate units (%s) " - "specified for a %s axis.", status, u, SystemLabel( s, status ) ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new FluxFrame. */ - return new; -} - -AstFluxFrame *astInitFluxFrame_( void *mem, size_t size, int init, - AstFluxFrameVtab *vtab, const char *name, - double specval, AstSpecFrame *specfrm, int *status ) { -/* -*+ -* Name: -* astInitFluxFrame - -* Purpose: -* Initialise a FluxFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "fluxframe.h" -* AstFluxFrame *astInitFluxFrame( void *mem, size_t size, int init, -* AstFrameVtab *vtab, const char *name, -* double specval, AstSpecFrame *specfrm) - -* Class Membership: -* FluxFrame initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new FluxFrame object. It allocates memory (if -* necessary) to accommodate the FluxFrame plus any additional data -* associated with the derived class. It then initialises a -* FluxFrame structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual function -* table for a FluxFrame at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the FluxFrame is to be -* created. This must be of sufficient size to accommodate the -* FluxFrame data (sizeof(FluxFrame)) plus any data used by -* the derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the FluxFrame (plus derived -* class data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also stored -* in the FluxFrame structure, so a valid value must be supplied -* even if not required for allocating memory. -* init -* A logical flag indicating if the FluxFrame's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new FluxFrame. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object belongs -* (it is this pointer value that will subsequently be returned by -* the astGetClass method). -* specval -* The spectral value to which the flux values refer, given in the -* spectral coordinate system specified by "specfrm". The value -* supplied for the "specval" parameter becomes the default value for -* the SpecVal attribute. May be AST__BAD. -* specfrm -* A pointer to a SpecFrame describing the spectral coordinate system -* in which the "specval" parameter is given. A deep copy of this object -* is taken, so any subsequent changes to the SpecFrame using the -* supplied pointer will have no effect on the new FluxFrame. Should -* be NULL if "specval" is AST__BAD. - -* Returned Value: -* A pointer to the new FluxFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstFluxFrame *new; /* Pointer to the new FluxFrame */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitFluxFrameVtab( vtab, name ); - -/* Initialise a 1D Frame structure (the parent class) as the first component - within the FluxFrame structure, allocating memory if necessary. */ - new = (AstFluxFrame *) astInitFrame( mem, size, 0, - (AstFrameVtab *) vtab, name, 1 ); - - if ( astOK ) { - -/* Initialise the FluxFrame data. */ -/* ----------------------------- */ -/* Initialise all attributes to their "undefined" values. */ - new->specval = AST__BAD; - new->defspecval = specval; - new->specframe = specfrm ? astCopy( specfrm ) : NULL; - new->nuunits = 0; - new->usedunits = NULL; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - - } - -/* Return a pointer to the new object. */ - return new; -} - -AstFluxFrame *astLoadFluxFrame_( void *mem, size_t size, AstFluxFrameVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadFluxFrame - -* Purpose: -* Load a FluxFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "fluxframe.h" -* AstFluxFrame *astLoadFluxFrame( void *mem, size_t size, AstFluxFrameVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* FluxFrame loader. - -* Description: -* This function is provided to load a new FluxFrame using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* FluxFrame structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the FluxFrame is to be -* loaded. This must be of sufficient size to accommodate the -* FluxFrame data (sizeof(FluxFrame)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the FluxFrame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the FluxFrame structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstFluxFrame) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new FluxFrame. If this is NULL, a pointer -* to the (static) virtual function table for the FluxFrame class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "FluxFrame" is used instead. - -* Returned Value: -* A pointer to the new FluxFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFluxFrame *new; /* Pointer to the new FluxFrame */ - char buff[ 20 ]; /* Buffer for item name */ - char *sval; /* Pointer to string value */ - int i; /* Loop count */ - int j; /* Get a pointer to the thread specific global data structure. */ - -/* Loop count */ - int sys; /* System value */ - - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this FluxFrame. In this case the - FluxFrame belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstFluxFrame ); - vtab = &class_vtab; - name = "FluxFrame"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitFluxFrameVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built FluxFrame. */ - new = astLoadFrame( mem, size, (AstFrameVtab *) vtab, name, - channel ); - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "FluxFrame" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Default SpecVal */ -/* --------------- */ - new->defspecval = astReadDouble( channel, "dfspc", AST__BAD ); - -/* SpecFrame */ -/* ---------- */ - new->specframe = astReadObject( channel, "spcfr", NULL ); - -/* SpecVal */ -/* ------- */ - new->specval = astReadDouble( channel, "spcvl", AST__BAD ); - if ( TestSpecVal( new, status ) ) SetSpecVal( new, new->specval, status ); - -/* UsedUnits */ -/* --------- */ - new->nuunits = 0; - new->usedunits = NULL; - for( sys = FIRST_SYSTEM; sys <= LAST_SYSTEM; sys++ ) { - sprintf( buff, "u%s", astSystemString( new, (AstSystemType) sys )); - for( j = 0; j < strlen( buff ); j++ ) buff[ j ] = tolower( buff[ j ] ); - sval = astReadString( channel, buff, NULL ); - if( sval ) { - if( (int) sys >= new->nuunits ) { - new->usedunits = astGrow( new->usedunits, sys + 1, - sizeof(char *) ); - if( astOK ) { - for( i = new->nuunits; i < sys + 1; i++ ) new->usedunits[ i ] = NULL; - new->nuunits = sys + 1; - } - } else { - new->usedunits[ sys ] = astFree( new->usedunits[ sys ] ); - } - if( astOK ) { - new->usedunits[ sys ] = astStore( new->usedunits[ sys ], - sval, strlen( sval ) + 1 ); - } - sval = astFree( sval ); - } - } - -/* If an error occurred, clean up by deleting the new FluxFrame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new FluxFrame pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -AstSystemType astGetDensitySystem_( AstFluxFrame *this, int *status ){ - if ( !astOK ) return AST__BADSYSTEM; - return (**astMEMBER(this,FluxFrame,GetDensitySystem))(this, status ); -} - -const char *astGetDensityUnit_( AstFluxFrame *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,FluxFrame,GetDensityUnit))(this, status ); -} - - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstFluxFrame *astFluxFrameId_( double, void *, const char *, ... ); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstFluxFrame *astFluxFrameId_( double specval, void *specfrm_void, - const char *options, ... ) { -/* -*++ -* Name: -c astFluxFrame -f AST_FLUXFRAME - -* Purpose: -* Create a FluxFrame. - -* Type: -* Public function. - -* Synopsis: -c #include "fluxframe.h" -c AstFluxFrame *astFluxFrame( double specval, AstSpecFrame *specfrm, -c const char *options, ... ) -f RESULT = AST_FLUXFRAME( SPECVAL, SPECFRM, OPTIONS, STATUS ) - -* Class Membership: -* FluxFrame constructor. - -* Description: -* This function creates a new FluxFrame and optionally initialises -* its attributes. -* -* A FluxFrame is a specialised form of one-dimensional Frame which -* represents various systems used to represent the signal level in an -* observation. The particular coordinate system to be used is specified -* by setting the FluxFrame's System attribute qualified, as necessary, by -* other attributes such as the units, etc (see the description of the -* System attribute for details). -* -* All flux values are assumed to be measured at the same frequency or -* wavelength (as given by the SpecVal attribute). Thus this class is -* more appropriate for use with images rather than spectra. - -* Parameters: -c specval -f SPECVAL = DOUBLE PRECISION (Given) -* The spectral value to which the flux values refer, given in the -* spectral coordinate system specified by -c "specfrm". The value supplied for the "specval" -f SPECFRM. The value supplied for the SPECVAL -* parameter becomes the default value for the SpecVal attribute. -* A value of AST__BAD may be supplied if the spectral position is -* unknown, but this may result in it not being possible for the -c astConvert -f AST_CONVERT -* function to determine a Mapping between the new FluxFrame and -* some other FluxFrame. -c specfrm -f SPECFRM = INTEGER (Given) -* A pointer to a SpecFrame describing the spectral coordinate system -* in which the -c "specval" -f SPECVAL -* parameter is given. A deep copy of this object is taken, so any -* subsequent changes to the SpecFrame using the supplied pointer will -* have no effect on the new FluxFrame. -c A NULL pointer can be supplied if AST__BAD is supplied for "specval". -f AST__NULL can be supplied if AST__BAD is supplied for SPECVAL. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new FluxFrame. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new FluxFrame. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astFluxFrame() -f AST_FLUXFRAME = INTEGER -* A pointer to the new FluxFrame. - -* Notes: -* - When conversion between two FluxFrames is requested (as when -c supplying FluxFrames to astConvert), -f supplying FluxFrames AST_CONVERT), -* account will be taken of the nature of the flux coordinate systems -* they represent, together with any qualifying attribute values, including -* the AlignSystem attribute. The results will therefore fully reflect the -* relationship between positions measured in the two systems. In addition, -* any difference in the Unit attributes of the two systems will also be -* taken into account. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astFluxFrame constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astFluxFrame_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - The variable argument list also prevents this function from -* invoking astFluxFrame_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *um; /* Mapping from default to actual units */ - AstFluxFrame *new; /* Pointer to new FluxFrame */ - AstSpecFrame *sfrm; /* Pointer to SpecFrame */ - AstSystemType s; /* System */ - const char *u; /* Units string */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the SpecFrame structures provided. */ - sfrm = specfrm_void ? astCheckSpecFrame( astMakePointer( specfrm_void ) ) : NULL; - -/* Initialise the FluxFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitFluxFrame( NULL, sizeof( AstFluxFrame ), !class_init, - &class_vtab, "FluxFrame", specval, sfrm ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new FluxFrame's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* Check the Units are appropriate for the System. */ - u = astGetUnit( new, 0 ); - s = astGetSystem( new ); - um = astUnitMapper( DefUnit( s, "astFluxFrame", "FluxFrame", status ), - u, NULL, NULL ); - if( um ) { - um = astAnnul( um ); - } else { - astError( AST__BADUN, "astFluxFrame: Inappropriate units (%s) " - "specified for a %s axis.", status, u, SystemLabel( s, status ) ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new FluxFrame. */ - return astMakeId( new ); -} - - - - - - - - - diff --git a/ast/fluxframe.h b/ast/fluxframe.h deleted file mode 100644 index c030142..0000000 --- a/ast/fluxframe.h +++ /dev/null @@ -1,267 +0,0 @@ -#if !defined( FLUXFRAME_INCLUDED ) /* Include this file only once */ -#define FLUXFRAME_INCLUDED -/* -*+ -* Name: -* fluxframe.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the FluxFrame class. - -* Invocation: -* #include "fluxframe.h" - -* Description: -* This include file defines the interface to the FluxFrame class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 1-DEC-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "frame.h" /* Parent Frame class */ -#include "specframe.h" /* Spectral coordinate systems */ - -/* Macros. */ -/* ======= */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -#if defined(astCLASS) /* Protected */ - -/* Values used to represent different System attribute values. */ -#define AST__FLUXDEN 1 -#define AST__FLUXDENW 2 -#define AST__SBRIGHT 3 -#define AST__SBRIGHTW 4 - -/* Define constants used to size global arrays in this module. */ -#define AST__FLUXFRAME_GETATTRIB_BUFF_LEN 50 -#define AST__FLUXFRAME_GETLABEL_BUFF_LEN 200 -#define AST__FLUXFRAME_GETSYMBOL_BUFF_LEN 20 -#define AST__FLUXFRAME_GETTITLE_BUFF_LEN 200 - -#endif - -/* Type Definitions. */ -/* ================= */ - -/* FluxFrame structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstFluxFrame { - -/* Attributes inherited from the parent class. */ - AstFrame frame; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double specval; /* Spectral position */ - double defspecval; /* Default spectral position */ - AstSpecFrame *specframe; /* SpecFrame describing specval & defspecval */ - int nuunits; /* Size of usedunits array */ - char **usedunits; /* Last used units for each system */ -} AstFluxFrame; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all objects in the - class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstFluxFrameVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstFrameVtab frame_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - - AstSystemType (* GetDensitySystem)( AstFluxFrame *, int * ); - const char *(* GetDensityUnit)( AstFluxFrame *, int * ); - - double (* GetSpecVal)( AstFluxFrame *, int * ); - int (* TestSpecVal)( AstFluxFrame *, int * ); - void (* ClearSpecVal)( AstFluxFrame *, int * ); - void (* SetSpecVal)( AstFluxFrame *, double, int * ); - -} AstFluxFrameVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstFluxFrameGlobals { - AstFluxFrameVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ AST__FLUXFRAME_GETATTRIB_BUFF_LEN + 1 ]; - char GetLabel_Buff[ AST__FLUXFRAME_GETLABEL_BUFF_LEN + 1 ]; - char GetSymbol_Buff[ AST__FLUXFRAME_GETSYMBOL_BUFF_LEN + 1 ]; - char GetTitle_Buff[ AST__FLUXFRAME_GETTITLE_BUFF_LEN + 1 ]; -} AstFluxFrameGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(FluxFrame) /* Check class membership */ -astPROTO_ISA(FluxFrame) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -AstFluxFrame *astFluxFrame_( double, void *, const char *, int *, ...); -#else -AstFluxFrame *astFluxFrameId_( double, void *, const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstFluxFrame *astInitFluxFrame_( void *, size_t, int, - AstFluxFrameVtab *, - const char *, double, AstSpecFrame *, int * ); - -/* Vtab initialiser. */ -void astInitFluxFrameVtab_( AstFluxFrameVtab *, const char *, int * ); - -/* Loader. */ -AstFluxFrame *astLoadFluxFrame_( void *, size_t, - AstFluxFrameVtab *, - const char *, AstChannel *channel, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitFluxFrameGlobals_( AstFluxFrameGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -#if defined(astCLASS) /* Protected */ - -AstSystemType astGetDensitySystem_( AstFluxFrame *, int * ); -const char *astGetDensityUnit_( AstFluxFrame *, int * ); - -double astGetSpecVal_( AstFluxFrame *, int * ); -int astTestSpecVal_( AstFluxFrame *, int * ); -void astClearSpecVal_( AstFluxFrame *, int * ); -void astSetSpecVal_( AstFluxFrame *, double, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckFluxFrame(this) astINVOKE_CHECK(FluxFrame,this,0) -#define astVerifyFluxFrame(this) astINVOKE_CHECK(FluxFrame,this,1) - -/* Test class membership. */ -#define astIsAFluxFrame(this) astINVOKE_ISA(FluxFrame,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -#define astFluxFrame astINVOKE(F,astFluxFrame_) -#else -#define astFluxFrame astINVOKE(F,astFluxFrameId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitFluxFrame(mem,size,init,vtab,name,specval,specfrm) \ -astINVOKE(O,astInitFluxFrame_(mem,size,init,vtab,name,specval,astCheckSpecFrame(specfrm),STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitFluxFrameVtab(vtab,name) astINVOKE(V,astInitFluxFrameVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadFluxFrame(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadFluxFrame_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) - -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ - -/* None. */ - -/* Interfaces to protected member functions. */ -/* ----------------------------------------- */ -/* Here we make use of astCheckFluxFrame to validate FluxFrame pointers - before use. This provides a contextual error report if a pointer to - the wrong sort of object is supplied. */ - -#if defined(astCLASS) /* Protected */ - -#define astGetDensitySystem(this) astINVOKE(V,astGetDensitySystem_(astCheckFluxFrame(this),STATUS_PTR)) -#define astGetDensityUnit(this) astINVOKE(V,astGetDensityUnit_(astCheckFluxFrame(this),STATUS_PTR)) - -#define astGetSpecVal(this) astINVOKE(V,astGetSpecVal_(astCheckFluxFrame(this),STATUS_PTR)) -#define astTestSpecVal(this) astINVOKE(V,astTestSpecVal_(astCheckFluxFrame(this),STATUS_PTR)) -#define astClearSpecVal(this) astINVOKE(V,astClearSpecVal_(astCheckFluxFrame(this),STATUS_PTR)) -#define astSetSpecVal(this,value) astINVOKE(V,astSetSpecVal_(astCheckFluxFrame(this),value,STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/fmapping.c b/ast/fmapping.c deleted file mode 100644 index 16f2b75..0000000 --- a/ast/fmapping.c +++ /dev/null @@ -1,771 +0,0 @@ -/* -*+ -* Name: -* fmapping.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Mapping class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Mapping class. - -* Routines Defined: -* AST_DECOMPOSE -* AST_INVERT -* AST_ISAMAPPING -* AST_LINEARMAPPING -* AST_REBIN -* AST_REBINSEQ -* AST_MAPBOX -* AST_MAPSPLIT -* AST_RATE -* AST_REMOVEREGIONS -* AST_RESAMPLE -* AST_SIMPLIFY -* AST_TRAN1 -* AST_TRAN2 -* AST_TRANGRID -* AST_TRANN -* AST_RATE - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 11-JUL-1996 (RFWS): -* Original version. -* 13-DEC-1996 (RFWS) -* Added AST_SIMPLIFY. -* 28-MAY-1998 (RFWS): -* Added AST_MAPBOX. -* 12-NOV-1998 (RFWS): -* Added AST_RESAMPLE. -* 22-NOV-2000 (DSB): -* Pass the "flags" argument by reference instead of by value in the -* MAKE_AST_RESAMPLE_UINTERP macro. -* 9-JAN-2001 (DSB): -* Changed in and out arguments for TranN from type "double (*)[]" -* to "double *". -* 26-SEP-2001 (DSB): -* Added AST_DECOMPOSE. -* 16-JUL-2003 (DSB): -* Added AST_RATE. -* 30-JUN-2005 (DSB): -* Added AST_REBIN. -* 1-SEP-2005 (DSB): -* Added AST_REBINSEQ. -* 8-MAR-2006 (DSB): -* Added AST_TRANGRID. -* 5-MAY-2009 (DSB): -* Added AST_REMOVEREGIONS. -* 4-MAY-2010 (DSB): -* Add support for AST__VARWGT flag to AST_REBINSEQ. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "mapping.h" /* C interface to the Mapping class */ - -#include - -/* Module Variables. */ -/* ================= */ -/* Pointer to user-supplied (FORTRAN 77) interpolation function for - use by AST_RESAMPLE. */ -static void (* ast_resample_FINTERP)(); - -/* Interpolation function interface. */ -/* ================================= */ -/* These functions are associated with allowing FORTRAN 77 - implementations of interpolation functions to be passed to - AST_RESAMPLE via the FORTRAN 77 interface and then to be invoked - when necessary by the C code in the main implementation of - astResample. */ - -/* Define a macro which defines an interface function called - ast_resample_uinterp for a specific data type. - - The resulting function has a suitable interface to allow it to be - passed as an interpolation function to the C interface of - astResample in the case where the "interp" parameter is set to - AST__UINTERP. In turn, it invokes the equivalent user-supplied - FORTRAN 77 interpolation function, a pointer to which should - previously have been stored in the static variable - "ast_resample_FINTERP". */ -#define MAKE_AST_RESAMPLE_UINTERP(X,Xtype,Ftype) \ -static void ast_resample_uinterp##X( int ndim, \ - const int lbnd[], const int ubnd[], \ - const Xtype in[], const Xtype in_var[], \ - int npoint, const int offset[], \ - const double *const coords[], \ - const double params[], int flags, \ - Xtype badval, \ - Xtype *out, Xtype *out_var, \ - int *nbad ) { \ - DECLARE_INTEGER(STATUS); \ - int *status; \ -\ -/* Get a pointer to the inherited staus value. */ \ - status = astGetStatusPtr; \ -\ -/* Obtain the C status and then invoke the FORTRAN 77 interpolation \ - function via the stored pointer. Note that the "coords" array we \ - pass to FORTRAN has to be a contiguous 2-d array, so we must \ - de-reference one level of pointer compared to the C case. */ \ - STATUS = astStatus; \ - ( *ast_resample_FINTERP )( INTEGER_ARG(&ndim), \ - INTEGER_ARRAY_ARG(lbnd), \ - INTEGER_ARRAY_ARG(ubnd), \ - Ftype##_ARRAY_ARG(in), \ - Ftype##_ARRAY_ARG(in_var), \ - INTEGER_ARG(&npoint), \ - INTEGER_ARRAY_ARG(offset), \ - DOUBLE_ARRAY_ARG(coords[ 0 ]), \ - DOUBLE_ARRAY_ARG(params), \ - INTEGER_ARG(&flags), \ - Ftype##_ARG(&badval), \ - Ftype##_ARRAY_ARG(out), \ - Ftype##_ARRAY_ARG(out_var), \ - INTEGER_ARG(nbad), \ - INTEGER_ARG(&STATUS) ); \ -\ -/* Set the C status to the returned FORTRAN 77 status. */ \ - astSetStatus( STATUS ); \ -} - -/* Invoke the above macro to define an interface function for each - required data type. */ -MAKE_AST_RESAMPLE_UINTERP(D,double,DOUBLE) -MAKE_AST_RESAMPLE_UINTERP(F,float,REAL) -MAKE_AST_RESAMPLE_UINTERP(I,int,INTEGER) -MAKE_AST_RESAMPLE_UINTERP(UI,unsigned int,INTEGER) -MAKE_AST_RESAMPLE_UINTERP(K,INT_BIG,INTEGER8) -MAKE_AST_RESAMPLE_UINTERP(UK,UINT_BIG,INTEGER8) -MAKE_AST_RESAMPLE_UINTERP(S,short int,WORD) -MAKE_AST_RESAMPLE_UINTERP(US,unsigned short int,UWORD) -MAKE_AST_RESAMPLE_UINTERP(B,signed char,BYTE) -MAKE_AST_RESAMPLE_UINTERP(UB,unsigned char,UBYTE) - -/* Undefine the macro. */ -#undef MAKE_AST_RESAMPLE_UINTERP - -/* Define a function called ast_resample_ukern1 which has a suitable - interface to allow it to be passed as an interpolation function to - the C interface of astResample in the case where the "interp" - parameter is set to AST__UKERN1. In turn, it invokes the equivalent - user-supplied FORTRAN 77 interpolation function, a pointer to which - should previously have been stored in the static variable - "ast_resample_FINTERP". */ -static void ast_resample_ukern1( double offset, const double params[], - int flags, double *value ) { - DECLARE_INTEGER(STATUS); - int *status; - -/* Obtain the C status and then invoke the FORTRAN 77 interpolation - function via the stored pointer. */ - status = astGetStatusPtr; - STATUS = astStatus; - ( *ast_resample_FINTERP )( DOUBLE_ARG(&offset), - DOUBLE_ARRAY_ARG(params), - INTEGER_ARG(&flags), - DOUBLE_ARG(value), - INTEGER_ARG(&STATUS) ); - -/* Set the C status to the returned FORTRAN 77 status. */ - astSetStatus( STATUS ); -} - -/* FORTRAN interface functions. */ -/* ============================ */ -/* These functions implement the remainder of the FORTRAN interface. */ - -F77_SUBROUTINE(ast_decompose)( INTEGER(THIS), - INTEGER(MAP1), - INTEGER(MAP2), - LOGICAL(SERIES), - INTEGER(INVERT1), - INTEGER(INVERT2), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(MAP1) - GENPTR_INTEGER(MAP2) - GENPTR_LOGICAL(SERIES) - GENPTR_INTEGER(INVERT1) - GENPTR_INTEGER(INVERT2) - AstMapping *map1; - AstMapping *map2; - int series; - - astAt( "AST_DECOMPOSE", NULL, 0 ); - astWatchSTATUS( - astDecompose( astI2P( *THIS ), &map1, &map2, &series, INVERT1, INVERT2 ); - *MAP1 = astP2I( map1 ); - *MAP2 = astP2I( map2 ); - *SERIES = ( series )?F77_TRUE:F77_FALSE; - ) -} - -F77_SUBROUTINE(ast_invert)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_INVERT", NULL, 0 ); - astWatchSTATUS( - astInvert( astI2P( *THIS ) ); - ) -} - -F77_LOGICAL_FUNCTION(ast_isamapping)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAMAPPING", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAMapping( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_linearapprox)( INTEGER(THIS), - DOUBLE_ARRAY(LBND), - DOUBLE_ARRAY(UBND), - DOUBLE(TOL), - DOUBLE_ARRAY(FIT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(LBND) - GENPTR_DOUBLE_ARRAY(UBND) - GENPTR_DOUBLE(TOL) - GENPTR_DOUBLE_ARRAY(FIT) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_LINEARAPPROX", NULL, 0 ); - astWatchSTATUS( - RESULT = astLinearApprox( astI2P( *THIS ), LBND, UBND, *TOL, FIT ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_quadapprox)( INTEGER(THIS), - DOUBLE_ARRAY(LBND), - DOUBLE_ARRAY(UBND), - INTEGER(NX), - INTEGER(NY), - DOUBLE_ARRAY(FIT), - DOUBLE(RMS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(LBND) - GENPTR_DOUBLE_ARRAY(UBND) - GENPTR_INTEGER(NX) - GENPTR_INTEGER(NY) - GENPTR_DOUBLE_ARRAY(FIT) - GENPTR_DOUBLE(RMS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_QUADAPPROX", NULL, 0 ); - astWatchSTATUS( - RESULT = astQuadApprox( astI2P( *THIS ), LBND, UBND, *NX, *NY, FIT, RMS ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_mapbox)( INTEGER(THIS), - DOUBLE_ARRAY(LBND_IN), - DOUBLE_ARRAY(UBND_IN), - LOGICAL(FORWARD), - INTEGER(COORD_OUT), - DOUBLE(LBND_OUT), - DOUBLE(UBND_OUT), - DOUBLE_ARRAY(XL), - DOUBLE_ARRAY(XU), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(LBND_IN) - GENPTR_DOUBLE_ARRAY(UBND_IN) - GENPTR_LOGICAL(FORWARD) - GENPTR_INTEGER(COORD_OUT) - GENPTR_DOUBLE(LBND_OUT) - GENPTR_DOUBLE(UBND_OUT) - GENPTR_DOUBLE_ARRAY(XL) - GENPTR_DOUBLE_ARRAY(XU) - double lbnd_out; - double ubnd_out; - - astAt( "AST_MAPBOX", NULL, 0 ); - astWatchSTATUS( - astMapBox( astI2P( *THIS ), LBND_IN, UBND_IN, F77_ISTRUE( *FORWARD ), - *COORD_OUT, &lbnd_out, &ubnd_out, XL, XU ); - *LBND_OUT = lbnd_out; - *UBND_OUT = ubnd_out; - ) -} - -/* AST_RESAMPLE requires a function for each possible data type, so - define it via a macro. */ -#define MAKE_AST_RESAMPLE(f,F,Ftype,X,Xtype) \ -F77_INTEGER_FUNCTION(ast_resample##f)( INTEGER(THIS), \ - INTEGER(NDIM_IN), \ - INTEGER_ARRAY(LBND_IN), \ - INTEGER_ARRAY(UBND_IN), \ - Ftype##_ARRAY(IN), \ - Ftype##_ARRAY(IN_VAR), \ - INTEGER(INTERP), \ - void (* FINTERP)(), \ - DOUBLE_ARRAY(PARAMS), \ - INTEGER(FLAGS), \ - DOUBLE(TOL), \ - INTEGER(MAXPIX), \ - Ftype(BADVAL), \ - INTEGER(NDIM_OUT), \ - INTEGER_ARRAY(LBND_OUT), \ - INTEGER_ARRAY(UBND_OUT), \ - INTEGER_ARRAY(LBND), \ - INTEGER_ARRAY(UBND), \ - Ftype##_ARRAY(OUT), \ - Ftype##_ARRAY(OUT_VAR), \ - INTEGER(STATUS) ) { \ - GENPTR_INTEGER(THIS) \ - GENPTR_INTEGER(NDIM_IN) \ - GENPTR_INTEGER_ARRAY(LBND_IN) \ - GENPTR_INTEGER_ARRAY(UBND_IN) \ - GENPTR_##Ftype##_ARRAY(IN) \ - GENPTR_##Ftype##_ARRAY(IN_VAR) \ - GENPTR_INTEGER(INTERP) \ - GENPTR_DOUBLE_ARRAY(PARAMS) \ - GENPTR_INTEGER(FLAGS) \ - GENPTR_DOUBLE(TOL) \ - GENPTR_INTEGER(MAXPIX) \ - GENPTR_##Ftype(BADVAL) \ - GENPTR_INTEGER(NDIM_OUT) \ - GENPTR_INTEGER_ARRAY(LBND_OUT) \ - GENPTR_INTEGER_ARRAY(UBND_OUT) \ - GENPTR_INTEGER_ARRAY(LBND) \ - GENPTR_INTEGER_ARRAY(UBND) \ - GENPTR_##Ftype##_ARRAY(OUT) \ - GENPTR_##Ftype##_ARRAY(OUT_VAR) \ - GENPTR_INTEGER(STATUS) \ -\ - void (* finterp)(); \ - Xtype *out_var; \ - const Xtype *in_var; \ - F77_INTEGER_TYPE RESULT; \ -\ - astAt( "AST_RESAMPLE"#F, NULL, 0 ); \ - astWatchSTATUS( \ -\ -/* If *INTERP is set to a value that requires a user-supplied \ - interpolation function, then store a pointer to the supplied \ - FORTRAN 77 version of this function and use the appropriate C \ - wrapper function (defined above) to invoke it. */ \ - if ( *INTERP == AST__UINTERP ) { \ - ast_resample_FINTERP = FINTERP; \ - finterp = (void (*)()) ast_resample_uinterp##X; \ - } else if ( *INTERP == AST__UKERN1 ) { \ - ast_resample_FINTERP = FINTERP; \ - finterp = (void (*)()) ast_resample_ukern1; \ - } else { \ - ast_resample_FINTERP = NULL; \ - finterp = NULL; \ - } \ -\ -/* If the AST__USEVAR flag is set, use the input and output variance \ - arrays, otherwise pass NULL pointers. */ \ - in_var = out_var = NULL; \ - if ( AST__USEVAR & *FLAGS ) { \ - in_var = (const Xtype *) IN_VAR; \ - out_var = (Xtype *) OUT_VAR; \ - } \ - RESULT = astResample##X( astI2P( *THIS ), *NDIM_IN, \ - LBND_IN, UBND_IN, (const Xtype *) IN, in_var, \ - *INTERP, finterp, PARAMS, *FLAGS, \ - *TOL, *MAXPIX, *BADVAL, \ - *NDIM_OUT, LBND_OUT, UBND_OUT, \ - LBND, UBND, (Xtype *) OUT, out_var ); \ - ) \ - return RESULT; \ -} - -/* Invoke the above macro to define a function for each data - type. Include synonyms for some functions. */ -MAKE_AST_RESAMPLE(d,D,DOUBLE,D,double) -MAKE_AST_RESAMPLE(r,R,REAL,F,float) -MAKE_AST_RESAMPLE(i,I,INTEGER,I,int) -MAKE_AST_RESAMPLE(ui,UI,INTEGER,UI,unsigned int) -MAKE_AST_RESAMPLE(k,K,INTEGER8,K,INT_BIG) -MAKE_AST_RESAMPLE(uk,UK,INTEGER8,UK,UINT_BIG) -MAKE_AST_RESAMPLE(s,S,WORD,S,short int) -MAKE_AST_RESAMPLE(us,US,UWORD,US,unsigned short int) -MAKE_AST_RESAMPLE(w,W,WORD,S,short int) -MAKE_AST_RESAMPLE(uw,UW,UWORD,US,unsigned short int) -MAKE_AST_RESAMPLE(b,B,BYTE,B,signed char) -MAKE_AST_RESAMPLE(ub,UB,UBYTE,UB,unsigned char) -#undef MAKE_AST_RESAMPLE - -/* AST_REBIN requires a function for each possible data type, so - define it via a macro. */ -#define MAKE_AST_REBIN(f,F,Ftype,X,Xtype) \ -F77_SUBROUTINE(ast_rebin##f)( INTEGER(THIS), \ - DOUBLE(WLIM), \ - INTEGER(NDIM_IN), \ - INTEGER_ARRAY(LBND_IN), \ - INTEGER_ARRAY(UBND_IN), \ - Ftype##_ARRAY(IN), \ - Ftype##_ARRAY(IN_VAR), \ - INTEGER(INTERP), \ - DOUBLE_ARRAY(PARAMS), \ - INTEGER(FLAGS), \ - DOUBLE(TOL), \ - INTEGER(MAXPIX), \ - Ftype(BADVAL), \ - INTEGER(NDIM_OUT), \ - INTEGER_ARRAY(LBND_OUT), \ - INTEGER_ARRAY(UBND_OUT), \ - INTEGER_ARRAY(LBND), \ - INTEGER_ARRAY(UBND), \ - Ftype##_ARRAY(OUT), \ - Ftype##_ARRAY(OUT_VAR), \ - INTEGER(STATUS) ) { \ - GENPTR_INTEGER(THIS) \ - GENPTR_DOUBLE(WLIM) \ - GENPTR_INTEGER(NDIM_IN) \ - GENPTR_INTEGER_ARRAY(LBND_IN) \ - GENPTR_INTEGER_ARRAY(UBND_IN) \ - GENPTR_##Ftype##_ARRAY(IN) \ - GENPTR_##Ftype##_ARRAY(IN_VAR) \ - GENPTR_INTEGER(INTERP) \ - GENPTR_DOUBLE_ARRAY(PARAMS) \ - GENPTR_INTEGER(FLAGS) \ - GENPTR_DOUBLE(TOL) \ - GENPTR_INTEGER(MAXPIX) \ - GENPTR_##Ftype(BADVAL) \ - GENPTR_INTEGER(NDIM_OUT) \ - GENPTR_INTEGER_ARRAY(LBND_OUT) \ - GENPTR_INTEGER_ARRAY(UBND_OUT) \ - GENPTR_INTEGER_ARRAY(LBND) \ - GENPTR_INTEGER_ARRAY(UBND) \ - GENPTR_##Ftype##_ARRAY(OUT) \ - GENPTR_##Ftype##_ARRAY(OUT_VAR) \ - GENPTR_INTEGER(STATUS) \ -\ - Xtype *out_var; \ - const Xtype *in_var; \ -\ - astAt( "AST_REBIN"#F, NULL, 0 ); \ - astWatchSTATUS( \ -\ -/* If the AST__USEVAR flag is set, use the input and output variance \ - arrays, otherwise pass NULL pointers. */ \ - in_var = out_var = NULL; \ - if ( AST__USEVAR & *FLAGS ) { \ - in_var = (const Xtype *) IN_VAR; \ - out_var = (Xtype *) OUT_VAR; \ - } \ - astRebin##X( astI2P( *THIS ), *WLIM, *NDIM_IN, \ - LBND_IN, UBND_IN, (const Xtype *) IN, in_var, \ - *INTERP, PARAMS, *FLAGS, \ - *TOL, *MAXPIX, *BADVAL, \ - *NDIM_OUT, LBND_OUT, UBND_OUT, \ - LBND, UBND, (Xtype *) OUT, out_var ); \ - ) \ -} - -/* Invoke the above macro to define a function for each data - type. Include synonyms for some functions. */ -MAKE_AST_REBIN(d,D,DOUBLE,D,double) -MAKE_AST_REBIN(r,R,REAL,F,float) -MAKE_AST_REBIN(i,I,INTEGER,I,int) -MAKE_AST_REBIN(b,B,BYTE,B,signed char) -MAKE_AST_REBIN(ub,UB,UBYTE,UB,unsigned char) -#undef MAKE_AST_REBIN - -/* AST_REBINSEQ requires a function for each possible data type, so - define it via a macro. */ -#define MAKE_AST_REBINSEQ(f,F,Ftype,X,Xtype) \ -F77_SUBROUTINE(ast_rebinseq##f)( INTEGER(THIS), \ - DOUBLE(WLIM), \ - INTEGER(NDIM_IN), \ - INTEGER_ARRAY(LBND_IN), \ - INTEGER_ARRAY(UBND_IN), \ - Ftype##_ARRAY(IN), \ - Ftype##_ARRAY(IN_VAR), \ - INTEGER(INTERP), \ - DOUBLE_ARRAY(PARAMS), \ - INTEGER(FLAGS), \ - DOUBLE(TOL), \ - INTEGER(MAXPIX), \ - Ftype(BADVAL), \ - INTEGER(NDIM_OUT), \ - INTEGER_ARRAY(LBND_OUT), \ - INTEGER_ARRAY(UBND_OUT), \ - INTEGER_ARRAY(LBND), \ - INTEGER_ARRAY(UBND), \ - Ftype##_ARRAY(OUT), \ - Ftype##_ARRAY(OUT_VAR), \ - DOUBLE_ARRAY(WEIGHTS), \ - INTEGER8(NUSED), \ - INTEGER(STATUS) ) { \ - GENPTR_INTEGER(THIS) \ - GENPTR_DOUBLE(WLIM) \ - GENPTR_INTEGER(NDIM_IN) \ - GENPTR_INTEGER_ARRAY(LBND_IN) \ - GENPTR_INTEGER_ARRAY(UBND_IN) \ - GENPTR_##Ftype##_ARRAY(IN) \ - GENPTR_##Ftype##_ARRAY(IN_VAR) \ - GENPTR_INTEGER(INTERP) \ - GENPTR_DOUBLE_ARRAY(PARAMS) \ - GENPTR_INTEGER(FLAGS) \ - GENPTR_DOUBLE(TOL) \ - GENPTR_INTEGER(MAXPIX) \ - GENPTR_##Ftype(BADVAL) \ - GENPTR_INTEGER(NDIM_OUT) \ - GENPTR_INTEGER_ARRAY(LBND_OUT) \ - GENPTR_INTEGER_ARRAY(UBND_OUT) \ - GENPTR_INTEGER_ARRAY(LBND) \ - GENPTR_INTEGER_ARRAY(UBND) \ - GENPTR_##Ftype##_ARRAY(OUT) \ - GENPTR_##Ftype##_ARRAY(OUT_VAR) \ - GENPTR_DOUBLE_ARRAY(WEIGHTS) \ - GENPTR_INTEGER8(NUSED) \ - GENPTR_INTEGER(STATUS) \ -\ - Xtype *out_var; \ - const Xtype *in_var; \ - int64_t nused; \ -\ - astAt( "AST_REBINSEQ"#F, NULL, 0 ); \ - astWatchSTATUS( \ -\ -/* We need the input variances if the AST__USEVAR or AST__VARWGT flag is \ - set. Otherwise use a NULL pointer for the input variances. */ \ - if ( AST__USEVAR & *FLAGS || AST__VARWGT & *FLAGS ) { \ - in_var = (const Xtype *) IN_VAR; \ - } else { \ - in_var = NULL; \ - } \ -\ -/* We need the output variances if the AST__USEVAR or AST__GENVAR flag is \ - set. Otherwise use a NULL pointer for the output variances. */ \ - if ( AST__USEVAR & *FLAGS || AST__GENVAR & *FLAGS ) { \ - out_var = (Xtype *) OUT_VAR; \ - } else { \ - out_var = NULL; \ - } \ -\ - nused = *NUSED; \ - astRebinSeq##X( astI2P( *THIS ), *WLIM, *NDIM_IN, \ - LBND_IN, UBND_IN, (const Xtype *) IN, in_var, \ - *INTERP, PARAMS, *FLAGS, \ - *TOL, *MAXPIX, *BADVAL, \ - *NDIM_OUT, LBND_OUT, UBND_OUT, \ - LBND, UBND, (Xtype *) OUT, out_var, WEIGHTS, \ - &nused ); \ - *NUSED = nused; \ - ) \ -} \ - -/* Invoke the above macro to define a function for each data - type. Include synonyms for some functions. */ -MAKE_AST_REBINSEQ(d,D,DOUBLE,D,double) -MAKE_AST_REBINSEQ(r,R,REAL,F,float) -MAKE_AST_REBINSEQ(i,I,INTEGER,I,int) -MAKE_AST_REBINSEQ(b,B,BYTE,B,signed char) -MAKE_AST_REBINSEQ(ub,UB,UBYTE,UB,unsigned char) -#undef MAKE_AST_REBINSEQ - -F77_INTEGER_FUNCTION(ast_removeregions)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_REMOVEREGIONS", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astRemoveRegions( astI2P( *THIS ) ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_simplify)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_SIMPLIFY", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astSimplify( astI2P( *THIS ) ) ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_tran1)( INTEGER(THIS), - INTEGER(NPOINT), - DOUBLE(XIN), - LOGICAL(FORWARD), - DOUBLE(XOUT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(NPOINT) - GENPTR_DOUBLE(XIN) - GENPTR_LOGICAL(FORWARD) - GENPTR_DOUBLE(XOUT) - - astAt( "AST_TRAN1", NULL, 0 ); - astWatchSTATUS( - astTran1( astI2P( *THIS ), *NPOINT, XIN, F77_ISTRUE( *FORWARD ), XOUT ); - ) -} - -F77_SUBROUTINE(ast_tran2)( INTEGER(THIS), - INTEGER(NPOINT), - DOUBLE(XIN), - DOUBLE(YIN), - LOGICAL(FORWARD), - DOUBLE(XOUT), - DOUBLE(YOUT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(NPOINT) - GENPTR_DOUBLE(XIN) - GENPTR_DOUBLE(YIN) - GENPTR_LOGICAL(FORWARD) - GENPTR_DOUBLE(XOUT) - GENPTR_DOUBLE(YOUT) - - astAt( "AST_TRAN2", NULL, 0 ); - astWatchSTATUS( - astTran2( astI2P( *THIS ), *NPOINT, XIN, YIN, - F77_ISTRUE( *FORWARD ), XOUT, YOUT ); - ) -} - -F77_SUBROUTINE(ast_trangrid)( INTEGER(THIS), - INTEGER(NCOORD_IN), - INTEGER_ARRAY(LBND), - INTEGER_ARRAY(UBND), - DOUBLE(TOL), - INTEGER(MAXPIX), - LOGICAL(FORWARD), - INTEGER(NCOORD_OUT), - INTEGER(OUTDIM), - DOUBLE_ARRAY(OUT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(NCOORD_IN) - GENPTR_INTEGER_ARRAY(LBND) - GENPTR_INTEGER_ARRAY(UBND) - GENPTR_DOUBLE(TOL) - GENPTR_INTEGER(MAXPIX) - GENPTR_LOGICAL(FORWARD) - GENPTR_INTEGER(NCOORD_OUT) - GENPTR_INTEGER(OUTDIM) - GENPTR_DOUBLE_ARRAY(OUT) - - astAt( "AST_TRANGRID", NULL, 0 ); - astWatchSTATUS( - astTranGrid( astI2P( *THIS ), *NCOORD_IN, LBND, UBND, *TOL, *MAXPIX, - F77_ISTRUE( *FORWARD ), *NCOORD_OUT, *OUTDIM, OUT ); - ) -} - -F77_SUBROUTINE(ast_trann)( INTEGER(THIS), - INTEGER(NPOINT), - INTEGER(NCOORD_IN), - INTEGER(INDIM), - DOUBLE_ARRAY(IN), - LOGICAL(FORWARD), - INTEGER(NCOORD_OUT), - INTEGER(OUTDIM), - DOUBLE_ARRAY(OUT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(NPOINT) - GENPTR_INTEGER(NCOORD_IN) - GENPTR_INTEGER(INDIM) - GENPTR_DOUBLE_ARRAY(IN) - GENPTR_LOGICAL(FORWARD) - GENPTR_INTEGER(NCOORD_OUT) - GENPTR_INTEGER(OUTDIM) - GENPTR_DOUBLE_ARRAY(OUT) - - astAt( "AST_TRANN", NULL, 0 ); - astWatchSTATUS( - astTranN( astI2P( *THIS ), *NPOINT, *NCOORD_IN, *INDIM, - (const double *)IN, F77_ISTRUE( *FORWARD ), - *NCOORD_OUT, *OUTDIM, OUT ); - ) -} - -F77_DOUBLE_FUNCTION(ast_rate)( INTEGER(THIS), - DOUBLE_ARRAY(AT), - INTEGER(AX1), - INTEGER(AX2), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(AX1) - GENPTR_INTEGER(AX2) - GENPTR_DOUBLE_ARRAY(AT) - F77_DOUBLE_TYPE(RESULT); - - astAt( "AST_RATE", NULL, 0 ); - astWatchSTATUS( - RESULT = astRate( astI2P( *THIS ), AT, *AX1, *AX2 ); - ) - return RESULT; -} - - -F77_SUBROUTINE(ast_mapsplit)( INTEGER(THIS), - INTEGER(NIN), - INTEGER_ARRAY(IN), - INTEGER_ARRAY(OUT), - INTEGER(MAP), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(NIN) - GENPTR_INTEGER_ARRAY(IN) - GENPTR_INTEGER_ARRAY(OUT) - GENPTR_INTEGER(MAP) - AstMapping *map; - - astAt( "AST_MAPSPLIT", NULL, 0 ); - astWatchSTATUS( - astMapSplit( astI2P( *THIS ), *NIN, IN, OUT, &map ); - *MAP = astP2I( map ); - ) -} - diff --git a/ast/fmathmap.c b/ast/fmathmap.c deleted file mode 100644 index 88ac236..0000000 --- a/ast/fmathmap.c +++ /dev/null @@ -1,122 +0,0 @@ -/* -*+ -* Name: -* fmathmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST MathMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the MathMap class. - -* Routines Defined: -* AST_ISAMATHMAP -* AST_MATHMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 3-SEP-1999 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "mathmap.h" /* C interface to the MathMap class */ - -F77_LOGICAL_FUNCTION(ast_isamathmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAMATHMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAMathMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_mathmap)( INTEGER(NIN), - INTEGER(NOUT), - INTEGER(NFWD), - CHARACTER_ARRAY(FWD), - INTEGER(NINV), - CHARACTER_ARRAY(INV), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(FWD) - TRAIL(INV) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NIN) - GENPTR_INTEGER(NOUT) - GENPTR_INTEGER(NFWD) - GENPTR_CHARACTER_ARRAY(FWD) - GENPTR_INTEGER(NINV) - GENPTR_CHARACTER_ARRAY(INV) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char **fwd; - char **inv; - char *options; - int i; - - astAt( "AST_MATHMAP", NULL, 0 ); - astWatchSTATUS( - fwd = astStringArray( FWD, *NFWD, FWD_length ); - inv = astStringArray( INV, *NINV, INV_length ); - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astMathMap( *NIN, *NOUT, - *NFWD, (const char **) fwd, - *NINV, (const char **) inv, - "%s", options ) ); - astFree( options ); - astFree( inv ); - astFree( fwd ); - ) - return RESULT; -} diff --git a/ast/fmatrixmap.c b/ast/fmatrixmap.c deleted file mode 100644 index 8fff328..0000000 --- a/ast/fmatrixmap.c +++ /dev/null @@ -1,110 +0,0 @@ -/* -*+ -* Name: -* fmatrixmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST MatrixMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the MatrixMap class. - -* Routines Defined: -* AST_ISAMATRIXMAP -* AST_MATRIXMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 14-NOV-1996 (DSB): -* Original version. -* 3-JUN-1997 (DSB): -* AST_MTRROT and AST_MTRMULT removed. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "matrixmap.h" /* C interface to the MatrixMap class */ - -F77_LOGICAL_FUNCTION(ast_isamatrixmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAMATRIXMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAMatrixMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_matrixmap)( INTEGER(NIN), - INTEGER(NOUT), - INTEGER(FORM), - DOUBLE_ARRAY(MATRIX), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NIN) - GENPTR_INTEGER(NOUT) - GENPTR_INTEGER(FORM) - GENPTR_DOUBLE_ARRAY(MATRIX) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_MATRIXMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astMatrixMap( *NIN, *NOUT, *FORM, MATRIX, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fnormmap.c b/ast/fnormmap.c deleted file mode 100644 index f7fa127..0000000 --- a/ast/fnormmap.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -*+ -* Name: -* fnormmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST NormMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the NormMap class. - -* Routines Defined: -* AST_ISANORMMAP -* AST_NORMMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S.Berry (Starlink) - -* History: -* 11-JUL-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "normmap.h" /* C interface to the NormMap class */ - -F77_LOGICAL_FUNCTION(ast_isanormmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astWatchSTATUS( - astAt( "AST_ISANORMMAP", NULL, 0 ); - RESULT = astIsANormMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_normmap)( INTEGER(FRAME), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_NORMMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astNormMap( astI2P( *FRAME ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fnullregion.c b/ast/fnullregion.c deleted file mode 100644 index 6e7d61f..0000000 --- a/ast/fnullregion.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -*+ -* Name: -* fnullregion.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST NullRegion class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the NullRegion class. - -* Routines Defined: -* AST_ISANULLREGION -* AST_NULLREGION - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 12-OCT-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "nullregion.h" /* C interface to the NullRegion class */ - - -F77_LOGICAL_FUNCTION(ast_isanullregion)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISANULLREGION", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsANullRegion( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_nullregion)( INTEGER(FRAME), - INTEGER(UNC), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_INTEGER(UNC) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_NULLREGION", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - - RESULT = astP2I( astNullRegion( astI2P( *FRAME ), astI2P( *UNC ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fobject.c b/ast/fobject.c deleted file mode 100644 index c718986..0000000 --- a/ast/fobject.c +++ /dev/null @@ -1,674 +0,0 @@ -/* -*+ -* Name: -* fobject.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Object class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Object class. - -* Routines Defined: -* AST_ANNUL -* AST_BEGIN -* AST_CLEAR -* AST_CLONE -* AST_COPY -* AST_DELETE -* AST_END -* AST_ESCAPES -* AST_EXEMPT -* AST_EXPORT -* AST_GET(C,D,I,L,R) -* AST_ISAOBJECT -* AST_NULL -* AST_SET -* AST_SET(C,D,I,L,R) -* AST_SHOW -* AST_VERSION -* AST_LISTISSUED (only if macro DEBUG is defined) -* AST_SETWATCHID (only if macro DEBUG is defined) -* AST_TUNE -* AST_TUNEC - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 20-JUN-1996 (RFWS): -* Original version. -* 9-SEP-1996 (RFWS): -* Added AST_SHOW. -* 11-DEC-1996 (RFWS): -* Added AST_NULL. -* 14-JUL-1997 (RFWS): -* Add AST_EXEMPT function. -* 30-APR-2003 (DSB): -* Add AST_VERSION function. -* 7-FEB-2004 (DSB): -* Add AST_ESCAPES function. -* 27-JAN-2005 (DSB): -* Added AST_LISTISSUED and AST_SETWATCHID so that DEBUG facilities -* can be used from fortran. -* 7-FEB-2006 (DSB): -* Added AST_TUNE. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 13-OCT-2011 (DSB): -* Added AST_TUNEC. -*- -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include - -/* Configuration results. */ -/* ---------------------- */ -#if HAVE_CONFIG_H -#include -#endif - -/* AST headers */ -/* ----------- */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "object.h" /* C interface to the Object class */ - -F77_SUBROUTINE(ast_annul)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_ANNUL", NULL, 0 ); - astWatchSTATUS( - *THIS = astP2I( astAnnul( astI2P( *THIS ) ) ); - ) -} - -F77_SUBROUTINE(ast_begin)( INTEGER(STATUS) ) { - - astAt( "AST_BEGIN", NULL, 0 ); - astWatchSTATUS( - int dummy = *status; /* Avoid "unused variable 'status'" messages */ - *status = dummy; - astBegin; - ) -} - -F77_SUBROUTINE(ast_clear)( INTEGER(THIS), - CHARACTER(ATTRIB), - INTEGER(STATUS) - TRAIL(ATTRIB) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(ATTRIB) - char *attrib; - - astAt( "AST_CLEAR", NULL, 0 ); - astWatchSTATUS( - attrib = astString( ATTRIB, ATTRIB_length ); - astClear( astI2P( *THIS ), attrib ); - astFree( attrib ); - ) -} - -F77_INTEGER_FUNCTION(ast_clone)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_CLONE", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astClone( astI2P( *THIS ) ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_version)( ) { - int status_value = 0; - int *STATUS = &status_value; - int *status = &status_value; - astAt( "AST_VERSION", NULL, 0 ); - return astVersion; -} - -F77_INTEGER_FUNCTION(ast_escapes)( INTEGER(NEWVAL), - INTEGER(STATUS) ) { - GENPTR_INTEGER(NEWVAL) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_ESCAPES", NULL, 0 ); - astWatchSTATUS( - RESULT = astEscapes( *NEWVAL ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_copy)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_COPY", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astCopy( astI2P( *THIS ) ) ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_delete)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_DELETE", NULL, 0 ); - astWatchSTATUS( - *THIS = astP2I( astDelete( astI2P( *THIS ) ) ); - ) -} - -F77_SUBROUTINE(ast_end)( INTEGER(STATUS) ) { - - astAt( "AST_END", NULL, 0 ); - astWatchSTATUS( - astEnd; - ) -} - -F77_SUBROUTINE(ast_exempt)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_EXEMPT", NULL, 0 ); - astWatchSTATUS( - astExempt( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_export)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_EXPORT", NULL, 0 ); - astWatchSTATUS( - astExport( astI2P( *THIS ) ); - ) -} - -#define MAKE_GETX(name,code,TYPE,CODE,type) \ -F77_##TYPE##_FUNCTION(ast_get##code)( INTEGER(THIS), \ - CHARACTER(ATTRIB), \ - INTEGER(STATUS) \ - TRAIL(ATTRIB) ) { \ - GENPTR_INTEGER(THIS) \ - GENPTR_CHARACTER(ATTRIB) \ - F77_##TYPE##_TYPE(RESULT); \ - char *attrib; \ -\ - astAt( name, NULL, 0 ); \ - astWatchSTATUS( \ - attrib = astString( ATTRIB, ATTRIB_length ); \ - RESULT = astGet##CODE( astI2P( *THIS ), attrib ); \ - astFree( attrib ); \ - ) \ - return RESULT; \ -} - -MAKE_GETX("AST_GETD",d,DOUBLE,D,double) -MAKE_GETX("AST_GETI",i,INTEGER,L,long) -MAKE_GETX("AST_GETR",r,REAL,D,double) - -/* NO_CHAR_FUNCTION indicates that the f77.h method of returning a - character result doesn't work, so add an extra argument instead and - wrap this function up in a normal FORTRAN 77 function (in the file - object.f). */ -#if NO_CHAR_FUNCTION -F77_SUBROUTINE(ast_getc_a)( CHARACTER(RESULT), -#else -F77_SUBROUTINE(ast_getc)( CHARACTER_RETURN_VALUE(RESULT), -#endif - INTEGER(THIS), - CHARACTER(ATTRIB), - INTEGER(STATUS) -#if NO_CHAR_FUNCTION - TRAIL(RESULT) -#endif - TRAIL(ATTRIB) ) { - GENPTR_CHARACTER(RESULT) - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(ATTRIB) - char *attrib; - const char *result; - int i; - - astAt( "AST_GETC", NULL, 0 ); - astWatchSTATUS( - attrib = astString( ATTRIB, ATTRIB_length ); - result = astGetC( astI2P( *THIS ), attrib ); - i = 0; - if ( astOK ) { /* Copy result */ - for ( ; result[ i ] && i < RESULT_length; i++ ) { - RESULT[ i ] = result[ i ]; - } - } - while ( i < RESULT_length ) RESULT[ i++ ] = ' '; /* Pad with blanks */ - astFree( attrib ); - ) -} - -F77_LOGICAL_FUNCTION(ast_getl)( INTEGER(THIS), - CHARACTER(ATTRIB), - INTEGER(STATUS) - TRAIL(ATTRIB) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(ATTRIB) - F77_LOGICAL_TYPE(RESULT); - char *attrib; - - astAt( "AST_GETL", NULL, 0 ); - astWatchSTATUS( - attrib = astString( ATTRIB, ATTRIB_length ); - RESULT = astGetL( astI2P( *THIS ), attrib ) ? F77_TRUE : F77_FALSE; - astFree( attrib ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_isaobject)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAOBJECT", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAObject( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_SUBROUTINE(ast_null)( void ) {} - -/* Omit the C variable length argument list here. */ -F77_SUBROUTINE(ast_set)( INTEGER(THIS), - CHARACTER(SETTING), - INTEGER(STATUS) - TRAIL(SETTING) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(SETTING) - char *setting; - int i; - int quoted; - - astAt( "AST_SET", NULL, 0 ); - astWatchSTATUS( - setting = astString( SETTING, SETTING_length ); - -/* Truncate the string to exclude any trailing spaces. */ - astChrTrunc( setting ); - -/* Change ',' to '\n' (which is what astSet normally does to its second - argument internally to separate the fields). This then allows "setting" - to be provided as an additional string value to be formatted using "%s". - This avoids interpretation of its contents (e.g. '%') as C format - specifiers. */ - if ( astOK ) { - quoted = 0; - for ( i = 0; setting[ i ]; i++ ) { - if( !quoted ) { - if ( setting[ i ] == ',' ) { - setting[ i ] = '\n'; - } else if( setting[ i ] == '"' ) { - quoted = 1; - } - } else if( setting[ i ] == '"' ){ - quoted = 0; - } - } - } - astSet( astI2P( *THIS ), "%s", setting ); - astFree( setting ); - ) -} - -#define MAKE_SETX(name,code,TYPE,CODE,type) \ -F77_SUBROUTINE(ast_set##code)( INTEGER(THIS), \ - CHARACTER(ATTRIB), \ - TYPE(VALUE), \ - INTEGER(STATUS) \ - TRAIL(ATTRIB) ) { \ - GENPTR_INTEGER(THIS) \ - GENPTR_CHARACTER(ATTRIB) \ - GENPTR_##TYPE(VALUE) \ - char *attrib; \ -\ - astAt( name, NULL, 0 ); \ - astWatchSTATUS( \ - attrib = astString( ATTRIB, ATTRIB_length ); \ - astSet##CODE( astI2P( *THIS ), attrib, *VALUE ); \ - astFree( attrib ); \ - ) \ -} - -MAKE_SETX("AST_SETD",d,DOUBLE,D,double) -MAKE_SETX("AST_SETR",r,REAL,D,double) -MAKE_SETX("AST_SETI",i,INTEGER,L,long) - -F77_SUBROUTINE(ast_setc)( INTEGER(THIS), - CHARACTER(ATTRIB), - CHARACTER(VALUE), - INTEGER(STATUS) - TRAIL(ATTRIB) - TRAIL(VALUE) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(ATTRIB) - GENPTR_CHARACTER(VALUE) - char *attrib, *value; - - astAt( "AST_SETC", NULL, 0 ); - astWatchSTATUS( - attrib = astString( ATTRIB, ATTRIB_length ); - value = astString( VALUE, VALUE_length ); - -/* Truncate the strings to exclude any trailing spaces. */ - astChrTrunc( attrib ); - astChrTrunc( value ); - - astSetC( astI2P( *THIS ), attrib, value ); - astFree( attrib ); - astFree( value ); - ) -} - -F77_SUBROUTINE(ast_setl)( INTEGER(THIS), - CHARACTER(ATTRIB), - LOGICAL(VALUE), - INTEGER(STATUS) - TRAIL(ATTRIB) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(ATTRIB) - GENPTR_LOGICAL(VALUE) - char *attrib; - - astAt( "AST_SETL", NULL, 0 ); - astWatchSTATUS( - attrib = astString( ATTRIB, ATTRIB_length ); - astSetI( astI2P( *THIS ), attrib, F77_ISTRUE( *VALUE ) ? 1 : 0 ); - astFree( attrib ); - ) -} - -F77_SUBROUTINE(ast_show)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_SHOW", NULL, 0 ); - astWatchSTATUS( - astShow( astI2P( *THIS ) ); - ) -} - -F77_LOGICAL_FUNCTION(ast_test)( INTEGER(THIS), - CHARACTER(ATTRIB), - INTEGER(STATUS) - TRAIL(ATTRIB) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(ATTRIB) - F77_LOGICAL_TYPE(RESULT); - char *attrib; - - astAt( "AST_TEST", NULL, 0 ); - astWatchSTATUS( - attrib = astString( ATTRIB, ATTRIB_length ); - RESULT = astTest( astI2P( *THIS ), attrib ) ? F77_TRUE : F77_FALSE; - astFree( attrib ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_hasattribute)( INTEGER(THIS), - CHARACTER(ATTRIB), - INTEGER(STATUS) - TRAIL(ATTRIB) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(ATTRIB) - F77_LOGICAL_TYPE(RESULT); - char *attrib; - - astAt( "AST_HASATTRIBUTE", NULL, 0 ); - astWatchSTATUS( - attrib = astString( ATTRIB, ATTRIB_length ); - RESULT = astHasAttribute( astI2P( *THIS ), attrib ) ? F77_TRUE : F77_FALSE; - astFree( attrib ); - ) - return RESULT; -} - - -F77_LOGICAL_FUNCTION(ast_same)( INTEGER(THIS), - INTEGER(THAT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(THAT) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_SAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astSame( astI2P( *THIS ), astI2P( *THAT ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - - -#ifdef MEM_DEBUG - -F77_SUBROUTINE(ast_beginpm)( void ) { - int status = 0; - astBeginPM_( &status ); -} - -F77_SUBROUTINE(ast_endpm)( void ) { - int status = 0; - astEndPM_( &status ); -} - -F77_SUBROUTINE(ast_activememory)( CHARACTER(TEXT) - TRAIL(TEXT) ) { - GENPTR_CHARACTER(TEXT) - char *text; - int status_value; - int *status = &status_value; - *status = 0; - astBeginPM; - text = astString( TEXT, TEXT_length ); - astEndPM; - astActiveMemory( text ); - astFree( text ); -} - -F77_SUBROUTINE(ast_watchmemory)( INTEGER(ID) ) { - GENPTR_INTEGER(ID) - astWatchMemory( *ID ); -} - -F77_SUBROUTINE(ast_flushmemory)( INTEGER(LEAK) ) { - GENPTR_INTEGER(LEAK) - int status = 0; - astFlushMemory_( *LEAK, &status ); -} - -#else - -F77_SUBROUTINE(ast_activememory)( CHARACTER(TEXT) - TRAIL(TEXT) ) { - GENPTR_CHARACTER(TEXT) -} - -F77_SUBROUTINE(ast_watchmemory)( INTEGER(ID) ) { - GENPTR_INTEGER(ID) -} - -F77_SUBROUTINE(ast_flushmemory)( INTEGER(LEAK) ) { - GENPTR_INTEGER(LEAK) -} - -F77_SUBROUTINE(ast_beginpm)( void ) { -} - -F77_SUBROUTINE(ast_endpm)( void ) { -} - - - - -#endif - - -F77_INTEGER_FUNCTION(ast_tune)( CHARACTER(NAME), - INTEGER(VALUE), - INTEGER(STATUS) - TRAIL(NAME) ) { - GENPTR_INTEGER(VALUE) - GENPTR_CHARACTER(NAME) - F77_INTEGER_TYPE(RESULT); - char *name; - - astAt( "AST_TUNE", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - RESULT = astTune( name, *VALUE ); - name = astFree( name ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_tunec)( CHARACTER(NAME), - CHARACTER(VALUE), - CHARACTER(BUFF), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(VALUE) - TRAIL(BUFF) ) { - GENPTR_CHARACTER(NAME) - GENPTR_CHARACTER(VALUE) - GENPTR_CHARACTER(BUFF) - char *name; - char *value; - char *buff; - - astAt( "AST_TUNEC", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - value = astString( VALUE, VALUE_length ); - if( value && !strcmp( value, AST__TUNULLC ) ) value = astFree( value ); - buff = astMalloc( BUFF_length + 1 ); - - astTuneC( name, value, buff, BUFF_length + 1 ); - - int i = 0; - if( astOK ) { - for ( ; buff[ i ] && i < BUFF_length; i++ ) { - BUFF[ i ] = buff[ i ]; - } - } - while ( i < BUFF_length ) BUFF[ i++ ] = ' '; /* Pad with blanks */ - - buff = astFree( buff ); - name = astFree( name ); - value = astFree( value ); - ) -} - -F77_LOGICAL_FUNCTION(ast_chrsub)( CHARACTER(TEST), - CHARACTER(PATTERN), - CHARACTER(RESULT), - INTEGER(STATUS) - TRAIL(TEST) - TRAIL(PATTERN) - TRAIL(RESULT) ) { - GENPTR_CHARACTER(TEST) - GENPTR_CHARACTER(PATTERN) - GENPTR_CHARACTER(RESULT) - F77_LOGICAL_TYPE(MATCH); - - char *test, *pattern, *result; - int i; - - astAt( "AST_CHRSUB", NULL, 0 ); - astWatchSTATUS( - test = astString( TEST, TEST_length ); - pattern = astString( PATTERN, PATTERN_length ); - - if( pattern ) { - test[ astChrLen( test ) ] = 0; - pattern[ astChrLen( pattern ) ] = 0; - } - - result = astChrSub( test, pattern, NULL, 0 ); - - i = 0; - if( result ) { - MATCH = F77_TRUE; - for ( ; result[ i ] && i < RESULT_length; i++ ) { - RESULT[ i ] = result[ i ]; - } - result = astFree( result ); - } else { - MATCH = F77_FALSE; - } - while ( i < RESULT_length ) RESULT[ i++ ] = ' '; /* Pad with blanks */ - - test = astFree( test ); - pattern = astFree( pattern ); - ) - return MATCH; -} - - -F77_LOGICAL_FUNCTION(ast_equal)( INTEGER(THIS), - INTEGER(THAT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(THAT) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_EQUAL", NULL, 0 ); - astWatchSTATUS( - RESULT = astEqual( astI2P( *THIS ), astI2P( *THAT ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - - - diff --git a/ast/fpcdmap.c b/ast/fpcdmap.c deleted file mode 100644 index bd5a335..0000000 --- a/ast/fpcdmap.c +++ /dev/null @@ -1,103 +0,0 @@ -/* -*+ -* Name: -* fpcdmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST PcdMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the PcdMap class. - -* Routines Defined: -* AST_ISAPCDMAP -* AST_PCDMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 19-MAY-1999 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "pcdmap.h" /* C interface to the PcdMap class */ - -F77_LOGICAL_FUNCTION(ast_isapcdmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAPCDMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAPcdMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_pcdmap)( DOUBLE(DISCO), - DOUBLE_ARRAY(PCDCEN), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_DOUBLE(DISCO) - GENPTR_DOUBLE_ARRAY(PCDCEN) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_PCDMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astPcdMap( *DISCO, PCDCEN, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fpermmap.c b/ast/fpermmap.c deleted file mode 100644 index d280958..0000000 --- a/ast/fpermmap.c +++ /dev/null @@ -1,110 +0,0 @@ -/* -*+ -* Name: -* fpermmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST PermMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the PermMap class. - -* Routines Defined: -* AST_ISAPERMMAP -* AST_PERMMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 26-SEP-1996 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "permmap.h" /* C interface to the PermMap class */ - -F77_LOGICAL_FUNCTION(ast_isapermmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAPERMMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAPermMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_permmap)( INTEGER(NIN), - INTEGER_ARRAY(INPERM), - INTEGER(NOUT), - INTEGER_ARRAY(OUTPERM), - DOUBLE_ARRAY(CONSTANT), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NIN) - GENPTR_INTEGER_ARRAY(INPERM) - GENPTR_INTEGER(NOUT) - GENPTR_INTEGER_ARRAY(OUTPERM) - GENPTR_DOUBLE_ARRAY(CONSTANT) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_PERMMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astPermMap( *NIN, INPERM, *NOUT, OUTPERM, CONSTANT, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fplot.c b/ast/fplot.c deleted file mode 100644 index a5e0b47..0000000 --- a/ast/fplot.c +++ /dev/null @@ -1,683 +0,0 @@ -/* -*+ -* Name: -* fplot.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Plot class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Plot class. - -* Routines Defined: -* AST_BORDER -* AST_BOUNDINGBOX -* AST_CLIP -* AST_CURVE -* AST_GENCURVE -* AST_GRID -* AST_GRIDLINE -* AST_ISAPLOT -* AST_MARK -* AST_PLOT -* AST_POLYCURVE -* AST_REGIONOUTLINE -* AST_TEXT -* AST_GRFSET -* AST_GRFPUSH -* AST_GRFPOP -* AST_STRIPESCAPES -* AST_GETGRFCONTEXT - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 23-OCT-1996 (DSB): -* Original version. -* 14-NOV-1996 (DSB): -* Method names shortened. CrvBreak removed. -* 21-NOV-1996 (DSB): -* Method names changed, CLIP argument NBND removed. -* 18-DEC-1996 (DSB): -* Argument UP changed to single precision and NCOORD removed -* in AST_TEXT. -* 11-AUG-1998 (DSB): -* Added AST_POLYCURVE. -* 9-JAN-2001 (DSB): -* Change argument "in" for astMark and astPolyCurve from type -* "const double (*)[]" to "const double *". -* 13-JUN-2001 (DSB): -* Modified to add support for astGenCurve, astGrfSet, astGrfPop, -* astGrfPush and EXTERNAL grf functions. -* 14-AUG-2002 (DSB): -* Added AST_BOUNDINGBOX. -* 8-JAN-2003 (DSB): -* Include "string.h". -* 10-JUL-2006 (DSB): -* Add AST_STRIPESCAPES -* 21-JUN-2007 (DSB): -* - Avoid use of protected astGetGrfContext function. -* - Change data type of GrfContext from integer to AST Object pointer. -* 29-JUN-2007 (DSB): -* Added astGetGrfCOntext and removed astSetGrfContext. -* 30-AUG-2007 (DSB): -* Use astGrfConID to get the identifier for the graphics context -* KeyMap. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -#define MXSTRLEN 80 /* String length at which truncation starts - within pgqtxt and pgptxt. */ -/* Header files. */ -/* ============= */ -#include "string.h" -#include "ast_err.h" /* AST error codes */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "plot.h" /* C interface to the Plot class */ -#include "grf.h" /* Low-level graphics interface */ - -/* Prototypes for external functions. */ -/* ================================== */ -/* This is the null function defined by the FORTRAN interface in -fobject.c. */ -F77_SUBROUTINE(ast_null)( void ); - -static int FGAttrWrapper( AstPlot *, int, double, double *, int ); -static int FGBBufWrapper( AstPlot * ); -static int FGEBufWrapper( AstPlot * ); -static int FGFlushWrapper( AstPlot * ); -static int FGLineWrapper( AstPlot *, int, const float *, const float * ); -static int FGMarkWrapper( AstPlot *, int, const float *, const float *, int ); -static int FGTextWrapper( AstPlot *, const char *, float, float, const char *, float, float ); -static int FGTxExtWrapper( AstPlot *, const char *, float, float, const char *, float, float, float *, float * ); -static int FGCapWrapper( AstPlot *, int, int ); -static int FGQchWrapper( AstPlot *, float *, float * ); -static int FGScalesWrapper( AstPlot *, float *, float * ); - -F77_LOGICAL_FUNCTION(ast_isaplot)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAPLOT", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAPlot( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_plot)( INTEGER(FRAME), - REAL_ARRAY(GRAPHBOX), - DOUBLE_ARRAY(BASEBOX), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_REAL_ARRAY(GRAPHBOX) - GENPTR_DOUBLE_ARRAY(BASEBOX) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_PLOT", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astPlot( astI2P( *FRAME ), GRAPHBOX, BASEBOX, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_border)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_BORDER", NULL, 0 ); - astWatchSTATUS( - RESULT = astBorder( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_SUBROUTINE(ast_boundingbox)( INTEGER(THIS), - REAL_ARRAY(LBND), - REAL_ARRAY(UBND), - INTEGER(STATUS) ){ - GENPTR_INTEGER(THIS) - GENPTR_REAL_ARRAY(LBND) - GENPTR_REAL_ARRAY(UBND) - - astAt( "AST_BOUNDINGBOX", NULL, 0 ); - astWatchSTATUS( - astBoundingBox( astI2P( *THIS ), LBND, UBND ); - ) -} - -F77_SUBROUTINE(ast_clip)( INTEGER(THIS), - INTEGER(IFRAME), - DOUBLE_ARRAY(LBND), - DOUBLE_ARRAY(UBND), - INTEGER(STATUS) ){ - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(IFRAME) - GENPTR_DOUBLE_ARRAY(LBND) - GENPTR_DOUBLE_ARRAY(UBND) - - astAt( "AST_CLIP", NULL, 0 ); - astWatchSTATUS( - astClip( astI2P( *THIS ), *IFRAME, LBND, UBND ); - ) -} - -F77_SUBROUTINE(ast_gridline)( INTEGER(THIS), - INTEGER(AXIS), - DOUBLE_ARRAY(START), - DOUBLE(LENGTH), - INTEGER(STATUS) ){ - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(AXIS) - GENPTR_DOUBLE_ARRAY(START) - GENPTR_DOUBLE(LENGTH) - - astAt( "AST_GRIDLINE", NULL, 0 ); - astWatchSTATUS( - astGridLine( astI2P( *THIS ), *AXIS, START, *LENGTH ); - ) -} - -F77_SUBROUTINE(ast_curve)( INTEGER(THIS), - DOUBLE_ARRAY(START), - DOUBLE_ARRAY(FINISH), - INTEGER(STATUS) ){ - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE_ARRAY(START) - GENPTR_DOUBLE_ARRAY(FINISH) - - astAt( "AST_CURVE", NULL, 0 ); - astWatchSTATUS( - astCurve( astI2P( *THIS ), START, FINISH ); - ) -} - -F77_SUBROUTINE(ast_grid)( INTEGER(THIS), - INTEGER(STATUS) ){ - GENPTR_INTEGER(THIS) - - astAt( "AST_GRID", NULL, 0 ); - astWatchSTATUS( - astGrid( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_mark)( INTEGER(THIS), - INTEGER(NMARK), - INTEGER(NCOORD), - INTEGER(INDIM), - DOUBLE_ARRAY(IN), - INTEGER(TYPE), - INTEGER(STATUS) ){ - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(NMARK) - GENPTR_INTEGER(NCOORD) - GENPTR_INTEGER(INDIM) - GENPTR_DOUBLE_ARRAY(IN) - GENPTR_INTEGER(TYPE) - - astAt( "AST_MARK", NULL, 0 ); - astWatchSTATUS( - astMark( astI2P( *THIS ), *NMARK, *NCOORD, *INDIM, - (const double *)IN, *TYPE ); - ) -} - -F77_SUBROUTINE(ast_polycurve)( INTEGER(THIS), - INTEGER(NPOINT), - INTEGER(NCOORD), - INTEGER(INDIM), - DOUBLE_ARRAY(IN), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(NPOINT) - GENPTR_INTEGER(NCOORD) - GENPTR_INTEGER(INDIM) - GENPTR_DOUBLE_ARRAY(IN) - - astAt( "AST_POLYCURVE", NULL, 0 ); - astWatchSTATUS( - astPolyCurve( astI2P( *THIS ), *NPOINT, *NCOORD, *INDIM, - (const double *)IN ); - ) -} - -F77_SUBROUTINE(ast_regionoutline)( INTEGER(THIS), - INTEGER(REGION), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(REGION) - - astAt( "AST_REGIONOUTLINE", NULL, 0 ); - astWatchSTATUS( - astRegionOutline( astI2P( *THIS ), astI2P( *REGION ) ); - ) -} - -F77_SUBROUTINE(ast_gencurve)( INTEGER(THIS), - INTEGER(MAP), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(MAP) - - astAt( "AST_GENCURVE", NULL, 0 ); - astWatchSTATUS( - astGenCurve( astI2P( *THIS ), astI2P( *MAP ) ); - ) -} - -F77_SUBROUTINE(ast_text)( INTEGER(THIS), - CHARACTER(TEXT), - DOUBLE_ARRAY(POS), - REAL_ARRAY(UP), - CHARACTER(JUST), - INTEGER(STATUS) - TRAIL(TEXT) - TRAIL(JUST) ){ - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(TEXT) - GENPTR_DOUBLE_ARRAY(POS) - GENPTR_REAL_ARRAY(UP) - GENPTR_CHARACTER(JUST) - char *text, *just; - - astAt( "AST_TEXT", NULL, 0 ); - astWatchSTATUS( - text = astString( TEXT, TEXT_length ); - just = astString( JUST, JUST_length ); - astText( astI2P( *THIS ), text, POS, UP, just ); - (void) astFree( (void *) text ); - (void) astFree( (void *) just ); - ) -} - -F77_SUBROUTINE(ast_grfpush)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - astAt( "AST_GRFPUSH", NULL, 0 ); - astWatchSTATUS( - astGrfPush( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_grfpop)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - astAt( "AST_GRFPOP", NULL, 0 ); - astWatchSTATUS( - astGrfPop( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_bbuf)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - astAt( "AST_BBUF", NULL, 0 ); - astWatchSTATUS( - astBBuf( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_ebuf)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - astAt( "AST_EBUF", NULL, 0 ); - astWatchSTATUS( - astEBuf( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_grfset)( INTEGER(THIS), CHARACTER(NAME), - AstGrfFun FUN, INTEGER(STATUS) - TRAIL(NAME) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - char *name; - AstGrfFun fun; - const char *class; /* Object class */ - const char *method; /* Current method */ - int ifun; /* Index into grf function list */ - AstGrfWrap wrapper; /* Wrapper function for C Grf routine*/ - - method = "AST_GRFSET"; - class = "Plot"; - - astAt( method, NULL, 0 ); - astWatchSTATUS( - -/* Set the function pointer to NULL if a pointer to - the null routine AST_NULL has been supplied. */ - fun = FUN; - if ( fun == (AstGrfFun) F77_EXTERNAL_NAME(ast_null) ) { - fun = NULL; - } - - name = astString( NAME, NAME_length ); - astGrfSet( astI2P( *THIS ), name, fun ); - - ifun = astGrfFunID( name, method, class ); - - if( ifun == AST__GATTR ) { - wrapper = (AstGrfWrap) FGAttrWrapper; - - } else if( ifun == AST__GBBUF ) { - wrapper = (AstGrfWrap) FGBBufWrapper; - - } else if( ifun == AST__GEBUF ) { - wrapper = (AstGrfWrap) FGEBufWrapper; - - } else if( ifun == AST__GFLUSH ) { - wrapper = (AstGrfWrap) FGFlushWrapper; - - } else if( ifun == AST__GLINE ) { - wrapper = (AstGrfWrap) FGLineWrapper; - - } else if( ifun == AST__GMARK ) { - wrapper = (AstGrfWrap) FGMarkWrapper; - - } else if( ifun == AST__GTEXT ) { - wrapper = (AstGrfWrap) FGTextWrapper; - - } else if( ifun == AST__GCAP ) { - wrapper = (AstGrfWrap) FGCapWrapper; - - } else if( ifun == AST__GTXEXT ) { - wrapper = (AstGrfWrap) FGTxExtWrapper; - - } else if( ifun == AST__GQCH ) { - wrapper = (AstGrfWrap) FGQchWrapper; - - } else if( ifun == AST__GSCALES ) { - wrapper = (AstGrfWrap) FGScalesWrapper; - - } else { - wrapper = (AstGrfWrap) FGFlushWrapper; - if( astOK ) astError( AST__INTER, "%s(%s): AST internal programming " - "error - Grf function id %d not yet supported.", status, - method, class, ifun ); - } - astGrfWrapper( astI2P( *THIS ), name, wrapper ); - ) -} - -static int FGAttrWrapper( AstPlot *this, int attr, double value, - double *old_value, int prim ) { - DECLARE_DOUBLE(OLDVAL); - int ret; - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - - if ( !astOK ) return 0; - - GRFCON = astP2I( astGrfConID( this ) ); - ret = ( *(int (*)( INTEGER(grfcon), INTEGER(attr), DOUBLE(value), - DOUBLE(old_value), INTEGER(prim) )) - this->grffun[ AST__GATTR ])( INTEGER_ARG(&GRFCON), - INTEGER_ARG(&attr), - DOUBLE_ARG(&value), - DOUBLE_ARG(&OLDVAL), - INTEGER_ARG(&prim) ); - if( old_value ) *old_value = OLDVAL; - return ret; -} - -static int FGBBufWrapper( AstPlot *this ) { - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - return ( *(int (*)(INTEGER(grfcon))) this->grffun[ AST__GBBUF ])(INTEGER_ARG(&GRFCON)); -} - -static int FGEBufWrapper( AstPlot *this ) { - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - return ( *(int (*)(INTEGER(grfcon))) this->grffun[ AST__GEBUF ])(INTEGER_ARG(&GRFCON)); -} - -static int FGFlushWrapper( AstPlot *this ) { - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - return ( *(int (*)(INTEGER(grfcon))) this->grffun[ AST__GFLUSH ])(INTEGER_ARG(&GRFCON)); -} - -static int FGLineWrapper( AstPlot *this, int n, const float *x, - const float *y ) { - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - return ( *(int (*)( INTEGER(grfcon), INTEGER(n), REAL_ARRAY(x), REAL_ARRAY(y) )) - this->grffun[ AST__GLINE ])( INTEGER_ARG(&GRFCON), - INTEGER_ARG(&n), - REAL_ARRAY_ARG(x), - REAL_ARRAY_ARG(y) ); -} - -static int FGMarkWrapper( AstPlot *this, int n, const float *x, - const float *y, int type ) { - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - return ( *(int (*)( INTEGER(grfcon), INTEGER(n), REAL_ARRAY(x), REAL_ARRAY(y), - INTEGER(type) )) - this->grffun[ AST__GMARK ])( INTEGER_ARG(&GRFCON), - INTEGER_ARG(&n), - REAL_ARRAY_ARG(x), - REAL_ARRAY_ARG(y), - INTEGER_ARG(&type) ); -} - -static int FGTextWrapper( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy ) { - - DECLARE_CHARACTER(LTEXT,MXSTRLEN); - DECLARE_CHARACTER(LJUST,MXSTRLEN); - int ftext_length; - int fjust_length; - - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - - ftext_length = strlen( text ); - if( ftext_length > LTEXT_length ) ftext_length = LTEXT_length; - astStringExport( text, LTEXT, ftext_length ); - - fjust_length = strlen( just ); - if( fjust_length > LJUST_length ) fjust_length = LJUST_length; - astStringExport( just, LJUST, fjust_length ); - - return ( *(int (*)( INTEGER(grfcon), CHARACTER(LTEXT), REAL(x), REAL(y), - CHARACTER(LJUST), REAL(upx), REAL(upy) - TRAIL(ftext) TRAIL(fjust) ) ) - this->grffun[ AST__GTEXT ])( - INTEGER_ARG(&GRFCON), - CHARACTER_ARG(LTEXT), - REAL_ARG(&x), - REAL_ARG(&y), - CHARACTER_ARG(LJUST), - REAL_ARG(&upx), - REAL_ARG(&upy) - TRAIL_ARG(ftext) - TRAIL_ARG(fjust) ); -} - -static int FGCapWrapper( AstPlot *this, int cap, int value ) { - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - return ( *(int (*)( INTEGER(grfcon), INTEGER(cap), INTEGER(value) ) ) - this->grffun[ AST__GCAP ])( - INTEGER_ARG(&GRFCON), - INTEGER_ARG(&cap), - INTEGER_ARG(&value) ); -} - -static int FGTxExtWrapper( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy, float *xb, - float *yb ) { - DECLARE_CHARACTER(LTEXT,MXSTRLEN); - DECLARE_CHARACTER(LJUST,MXSTRLEN); - int ftext_length; - int fjust_length; - - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - - ftext_length = strlen( text ); - if( ftext_length > LTEXT_length ) ftext_length = LTEXT_length; - astStringExport( text, LTEXT, ftext_length ); - - fjust_length = strlen( just ); - if( fjust_length > LJUST_length ) fjust_length = LJUST_length; - astStringExport( just, LJUST, fjust_length ); - - return ( *(int (*)( INTEGER(grfcon), CHARACTER(LTEXT), REAL(x), REAL(y), - CHARACTER(LJUST), REAL(upx), REAL(upy), - REAL_ARRAY(xb), REAL_ARRAY(yb) TRAIL(ftext) - TRAIL(fjust) ) ) - this->grffun[ AST__GTXEXT ])( - INTEGER_ARG(&GRFCON), - CHARACTER_ARG(LTEXT), - REAL_ARG(&x), - REAL_ARG(&y), - CHARACTER_ARG(LJUST), - REAL_ARG(&upx), - REAL_ARG(&upy), - REAL_ARRAY_ARG(xb), - REAL_ARRAY_ARG(yb) - TRAIL_ARG(ftext) - TRAIL_ARG(fjust) ); -} - -static int FGQchWrapper( AstPlot *this, float *chv, float *chh ) { - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - return ( *(int (*)( INTEGER(grfcon), REAL(chv), REAL(chh) ) ) - this->grffun[ AST__GQCH ])( INTEGER_ARG(&GRFCON), REAL_ARG(chv), REAL_ARG(chh) ); -} - -static int FGScalesWrapper( AstPlot *this, float *alpha, float *beta ) { - F77_INTEGER_TYPE(GRFCON); - int *status = astGetStatusPtr; - if ( !astOK ) return 0; - GRFCON = astP2I( astGrfConID( this ) ); - return ( *(int (*)( INTEGER(grfcon), REAL(alpha), REAL(beta) ) ) - this->grffun[ AST__GSCALES ])( INTEGER_ARG(&GRFCON), REAL_ARG(alpha), REAL_ARG(beta) ); -} - - -/* NO_CHAR_FUNCTION indicates that the f77.h method of returning a - character result doesn't work, so add an extra argument instead and - wrap this function up in a normal FORTRAN 77 function (in the file - plot.f). */ -#if NO_CHAR_FUNCTION -F77_SUBROUTINE(ast_stripescapes_a)( CHARACTER(RESULT), -#else -F77_SUBROUTINE(ast_stripescapes)( CHARACTER_RETURN_VALUE(RESULT), -#endif - CHARACTER(TEXT), - INTEGER(STATUS) -#if NO_CHAR_FUNCTION - TRAIL(RESULT) -#endif - TRAIL(TEXT) ) { - GENPTR_CHARACTER(RESULT) - GENPTR_CHARACTER(TEXT) - char *text; - const char *result; - int i; - - astAt( "AST_STRIPESCAPES", NULL, 0 ); - astWatchSTATUS( - text = astString( TEXT, TEXT_length ); - result = astStripEscapes( text ); - i = 0; - if ( astOK ) { /* Copy result */ - for ( ; result[ i ] && i < RESULT_length; i++ ) { - RESULT[ i ] = result[ i ]; - } - } - while ( i < RESULT_length ) RESULT[ i++ ] = ' '; /* Pad with blanks */ - astFree( text ); - ) -} - -F77_LOGICAL_FUNCTION(ast_getgrfcontext)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETGRFCONTEXT", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetGrfContext( astI2P( *THIS ) ) ); - ) - return RESULT; -} - - - - diff --git a/ast/fplot3d.c b/ast/fplot3d.c deleted file mode 100644 index 4246f50..0000000 --- a/ast/fplot3d.c +++ /dev/null @@ -1,107 +0,0 @@ -/* -*+ -* Name: -* fplot3d.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Plot3D class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Plot3D class. - -* Routines Defined: -* AST_ISAPLOT3D -* AST_PLOT3D - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 6-JUN-2007 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "plot3d.h" /* C interface to the Plot3D class */ - -F77_LOGICAL_FUNCTION(ast_isaplot3d)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAPLOT3D", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAPlot3D( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_plot3d)( INTEGER(FRAME), - REAL_ARRAY(GRAPHBOX), - DOUBLE_ARRAY(BASEBOX), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_REAL_ARRAY(GRAPHBOX) - GENPTR_DOUBLE_ARRAY(BASEBOX) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_PLOT3D", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astPlot3D( astI2P( *FRAME ), GRAPHBOX, BASEBOX, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - diff --git a/ast/fpointlist.c b/ast/fpointlist.c deleted file mode 100644 index 9644fdc..0000000 --- a/ast/fpointlist.c +++ /dev/null @@ -1,117 +0,0 @@ -/* -*+ -* Name: -* fpointlist.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST PointList class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the PointList class. - -* Routines Defined: -* AST_ISAPOINTLIST -* AST_POINTLIST - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 23-AUG-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "pointlist.h" /* C interface to the PointList class */ - -F77_LOGICAL_FUNCTION(ast_isapointlist)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAPOINTLIST", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAPointList( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_pointlist)( INTEGER(FRAME), - INTEGER(NPNT), - INTEGER(COORD), - INTEGER(INDIM), - DOUBLE_ARRAY(POINTS), - INTEGER(UNC), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_INTEGER(NPNT) - GENPTR_INTEGER(COORD) - GENPTR_INTEGER(INDIM) - GENPTR_DOUBLE_ARRAY(POINTS) - GENPTR_INTEGER(UNC) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_POINTLIST", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - - RESULT = astP2I( astPointList( astI2P( *FRAME ), *NPNT, *COORD, - *INDIM, POINTS, astI2P( *UNC ), "%s", - options ) ); - astFree( options ); - ) - return RESULT; -} - - - - diff --git a/ast/fpolygon.c b/ast/fpolygon.c deleted file mode 100644 index 12247d7..0000000 --- a/ast/fpolygon.c +++ /dev/null @@ -1,226 +0,0 @@ -/* -*+ -* Name: -* fpolygon.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Polygon class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Polygon class. - -* Routines Defined: -* AST_ISAPOLYGON -* AST_POLYGON -* AST_DOWNSIZE - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 27-OCT-2004 (DSB): -* Original version. -* 28-MAY-2009 (DSB): -* Added AST_DOWNSIZE. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "polygon.h" /* C interface to the Polygon class */ - -F77_LOGICAL_FUNCTION(ast_isapolygon)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAPOLYGON", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAPolygon( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_polygon)( INTEGER(FRAME), - INTEGER(NPNT), - INTEGER(INDIM), - DOUBLE_ARRAY(POINTS), - INTEGER(UNC), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME) - GENPTR_INTEGER(NPNT) - GENPTR_INTEGER(INDIM) - GENPTR_DOUBLE_ARRAY(POINTS) - GENPTR_INTEGER(UNC) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_POLYGON", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - - RESULT = astP2I( astPolygon( astI2P( *FRAME ), *NPNT, *INDIM, POINTS, - astI2P( *UNC ), "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_downsize)( INTEGER(THIS), - DOUBLE(MAXERR), - INTEGER(MAXVERT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE(MAXERR) - GENPTR_INTEGER(MAXVERT) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_DOWNSIZE", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astDownsize( astI2P( *THIS ), *MAXERR, *MAXVERT ) ); - ) - return RESULT; -} - - -/* AST_OUTLINE requires a function for each possible data type, so - define it via a macro. */ -#define MAKE_AST_OUTLINE(f,F,Ftype,X,Xtype) \ -F77_INTEGER_FUNCTION(ast_outline##f)( Ftype(VALUE), \ - INTEGER(OPER), \ - Ftype##_ARRAY(ARRAY), \ - INTEGER_ARRAY(LBND), \ - INTEGER_ARRAY(UBND), \ - DOUBLE(MAXERR), \ - INTEGER(MAXVERT), \ - INTEGER_ARRAY(INSIDE), \ - LOGICAL(STARPIX), \ - INTEGER(STATUS) ) { \ - GENPTR_##Ftype(VALUE) \ - GENPTR_INTEGER(OPER) \ - GENPTR_##Ftype##_ARRAY(ARRAY) \ - GENPTR_INTEGER_ARRAY(LBND) \ - GENPTR_INTEGER_ARRAY(UBND) \ - GENPTR_DOUBLE(MAXERR) \ - GENPTR_INTEGER(MAXVERT) \ - GENPTR_INTEGER_ARRAY(INSIDE) \ - GENPTR_LOGICAL(STARPIX) \ - GENPTR_INTEGER(STATUS) \ -\ - F77_INTEGER_TYPE RESULT; \ -\ - astAt( "AST_OUTLINE"#F, NULL, 0 ); \ - astWatchSTATUS( \ - RESULT = astP2I( astOutline##X( *VALUE, *OPER, (Xtype *) ARRAY, LBND, \ - UBND, *MAXERR, *MAXVERT, INSIDE, \ - F77_ISTRUE( *STARPIX ) ? 1 : 0 ) ); \ - ) \ - return RESULT; \ -} - -/* Invoke the above macro to define a function for each data - type. Include synonyms for some functions. */ -MAKE_AST_OUTLINE(d,D,DOUBLE,D,double) -MAKE_AST_OUTLINE(r,R,REAL,F,float) -MAKE_AST_OUTLINE(i,I,INTEGER,I,int) -MAKE_AST_OUTLINE(ui,UI,INTEGER,UI,unsigned int) -MAKE_AST_OUTLINE(s,S,WORD,S,short int) -MAKE_AST_OUTLINE(us,US,UWORD,US,unsigned short int) -MAKE_AST_OUTLINE(w,W,WORD,S,short int) -MAKE_AST_OUTLINE(uw,UW,UWORD,US,unsigned short int) -MAKE_AST_OUTLINE(b,B,BYTE,B,signed char) -MAKE_AST_OUTLINE(ub,UB,UBYTE,UB,unsigned char) -#undef MAKE_AST_OUTLINE - - -/* AST_CONVEX requires a function for each possible data type, so - define it via a macro. */ -#define MAKE_AST_CONVEX(f,F,Ftype,X,Xtype) \ -F77_INTEGER_FUNCTION(ast_convex##f)( Ftype(VALUE), \ - INTEGER(OPER), \ - Ftype##_ARRAY(ARRAY), \ - INTEGER_ARRAY(LBND), \ - INTEGER_ARRAY(UBND), \ - LOGICAL(STARPIX), \ - INTEGER(STATUS) ) { \ - GENPTR_##Ftype(VALUE) \ - GENPTR_INTEGER(OPER) \ - GENPTR_##Ftype##_ARRAY(ARRAY) \ - GENPTR_INTEGER_ARRAY(LBND) \ - GENPTR_INTEGER_ARRAY(UBND) \ - GENPTR_LOGICAL(STARPIX) \ - GENPTR_INTEGER(STATUS) \ -\ - F77_INTEGER_TYPE RESULT; \ -\ - astAt( "AST_CONVEX"#F, NULL, 0 ); \ - astWatchSTATUS( \ - RESULT = astP2I( astConvex##X( *VALUE, *OPER, (Xtype *) ARRAY, LBND, \ - UBND, F77_ISTRUE( *STARPIX ) ? 1 : 0 ) ); \ - ) \ - return RESULT; \ -} - -/* Invoke the above macro to define a function for each data - type. Include synonyms for some functions. */ -MAKE_AST_CONVEX(d,D,DOUBLE,D,double) -MAKE_AST_CONVEX(r,R,REAL,F,float) -MAKE_AST_CONVEX(i,I,INTEGER,I,int) -MAKE_AST_CONVEX(ui,UI,INTEGER,UI,unsigned int) -MAKE_AST_CONVEX(s,S,WORD,S,short int) -MAKE_AST_CONVEX(us,US,UWORD,US,unsigned short int) -MAKE_AST_CONVEX(w,W,WORD,S,short int) -MAKE_AST_CONVEX(uw,UW,UWORD,US,unsigned short int) -MAKE_AST_CONVEX(b,B,BYTE,B,signed char) -MAKE_AST_CONVEX(ub,UB,UBYTE,UB,unsigned char) -#undef MAKE_AST_CONVEX - - diff --git a/ast/fpolymap.c b/ast/fpolymap.c deleted file mode 100644 index 687e9f6..0000000 --- a/ast/fpolymap.c +++ /dev/null @@ -1,159 +0,0 @@ -/* -*+ -* Name: -* fpolymap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST PolyMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the PolyMap class. - -* Routines Defined: -* AST_ISAPOLYMAP -* AST_POLYMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 27-SEP-2003 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "polymap.h" /* C interface to the PolyMap class */ - -F77_LOGICAL_FUNCTION(ast_isapolymap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAPOLYMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAPolyMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_polymap)( INTEGER(NIN), - INTEGER(NOUT), - INTEGER(NCOEFF_F), - DOUBLE_ARRAY(COEFF_F), - INTEGER(NCOEFF_I), - DOUBLE_ARRAY(COEFF_I), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NIN) - GENPTR_INTEGER(NOUT) - GENPTR_INTEGER(NCOEFF_F) - GENPTR_DOUBLE_ARRAY(COEFF_F) - GENPTR_INTEGER(NCOEFF_I) - GENPTR_DOUBLE_ARRAY(COEFF_I) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_POLYMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astPolyMap( *NIN, *NOUT, *NCOEFF_F, COEFF_F, *NCOEFF_I, - COEFF_I, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - - -F77_INTEGER_FUNCTION(ast_polytran)( INTEGER(THIS), - LOGICAL(FORWARD), - DOUBLE(ACC), - DOUBLE(MAXACC), - INTEGER(MAXORDER), - DOUBLE_ARRAY(LBND), - DOUBLE_ARRAY(UBND), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_LOGICAL(FORWARD) - GENPTR_DOUBLE(ACC) - GENPTR_DOUBLE(MAXACC) - GENPTR_INTEGER(MAXORDER) - GENPTR_DOUBLE_ARRAY(LBND) - GENPTR_DOUBLE_ARRAY(UBND) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_POLYTRAN", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astPolyTran( astI2P( *THIS ), F77_ISTRUE( *FORWARD ), - *ACC, *MAXACC, *MAXORDER, LBND, UBND ) ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_polycoeffs)( INTEGER(THIS), - LOGICAL(FORWARD), - INTEGER(NEL), - DOUBLE_ARRAY(COEFFS), - INTEGER(NCOEFF), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_LOGICAL(FORWARD) - GENPTR_INTEGER(NEL) - GENPTR_DOUBLE_ARRAY(COEFFS) - GENPTR_INTEGER(NCOEFF) - - astAt( "AST_POLYCOEFFS", NULL, 0 ); - astWatchSTATUS( - astPolyCoeffs( astI2P( *THIS ), F77_ISTRUE( *FORWARD ), *NEL, COEFFS, NCOEFF ); - ) -} - - - diff --git a/ast/fprism.c b/ast/fprism.c deleted file mode 100644 index 7dc70b7..0000000 --- a/ast/fprism.c +++ /dev/null @@ -1,105 +0,0 @@ -/* -*+ -* Name: -* fprism.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Prism class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Prism class. - -* Routines Defined: -* AST_ISAPRISM -* AST_PRISM - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 10-JAN-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "prism.h" /* C interface to the Prism class */ - - -F77_LOGICAL_FUNCTION(ast_isaprism)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAPRISM", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAPrism( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_prism)( INTEGER(REG1), - INTEGER(REG2), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(REG1) - GENPTR_INTEGER(REG2) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_PRISM", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - - RESULT = astP2I( astPrism( astI2P( *REG1 ), astI2P( *REG2 ), - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/frame.c b/ast/frame.c deleted file mode 100644 index bd70cdd..0000000 --- a/ast/frame.c +++ /dev/null @@ -1,16067 +0,0 @@ -/* -*class++ -* Name: -* Frame - -* Purpose: -* Coordinate system description. - -* Constructor Function: -c astFrame -f AST_FRAME - -* Description: -* This class is used to represent coordinate systems. It does this -* in rather the same way that a frame around a graph describes the -* coordinate space in which data are plotted. Consequently, a -* Frame has a Title (string) attribute, which describes the -* coordinate space, and contains axes which in turn hold -* information such as Label and Units strings which are used for -* labelling (e.g.) graphical output. In general, however, the -* number of axes is not restricted to two. -* -* Functions are available for converting Frame coordinate values -* into a form suitable for display, and also for calculating -* distances and offsets between positions within the Frame. -* -* Frames may also contain knowledge of how to transform to and -* from related coordinate systems. - -* Inheritance: -* The Frame class inherits from the Mapping class. - -* Attributes: -* In addition to those attributes common to all Mappings, every -* Frame also has the following attributes (if the Frame has only one -* axis, the axis specifier can be omited from the following attribute -* names): -* -* - AlignSystem: Coordinate system used to align Frames -* - Bottom(axis): Lowest axis value to display -* - Digits/Digits(axis): Number of digits of precision -* - Direction(axis): Display axis in conventional direction? -* - Domain: Coordinate system domain -* - Dtai: Difference between the TAI and UTC timescale -* - Dut1: Difference between the UT1 and UTC timescale -* - Epoch: Epoch of observation -* - Format(axis): Format specification for axis values -* - InternalUnit(axis): Physical units for unformated axis values -* - Label(axis): Axis label -* - MatchEnd: Match trailing axes? -* - MaxAxes: Maximum number of Frame axes to match -* - MinAxes: Minimum number of Frame axes to match -* - Naxes: Number of Frame axes -* - NormUnit(axis): Normalised physical units for formatted axis values -* - ObsAlt: Geodetic altitude of observer -* - ObsLat: Geodetic latitude of observer -* - ObsLon: Geodetic longitude of observer -* - Permute: Permute axis order? -* - PreserveAxes: Preserve axes? -* - Symbol(axis): Axis symbol -* - System: Coordinate system used to describe the domain -* - Title: Frame title -* - Top(axis): Highest axis value to display -* - Unit(axis): Physical units for formatted axis values - -* Functions: -c In addition to those functions applicable to all Mappings, the -c following functions may also be applied to all Frames: -f In addition to those routines applicable to all Mappings, the -f following routines may also be applied to all Frames: -* -c - astAngle: Calculate the angle subtended by two points at a third point -c - astAxAngle: Find the angle from an axis, to a line through two points -c - astAxDistance: Calculate the distance between two axis values -c - astAxNorm: Normalises an array of axis values -c - astAxOffset: Calculate an offset along an axis -c - astConvert: Determine how to convert between two coordinate systems -c - astDistance: Calculate the distance between two points in a Frame -c - astFindFrame: Find a coordinate system with specified characteristics -c - astFormat: Format a coordinate value for a Frame axis -c - astGetActiveUnit: Determines how the Unit attribute will be used -c - astIntersect: Find the intersection between two geodesic curves -c - astMatchAxes: Find any corresponding axes in two Frames -c - astNorm: Normalise a set of Frame coordinates -c - astOffset: Calculate an offset along a geodesic curve -c - astOffset2: Calculate an offset along a geodesic curve in a 2D Frame -c - astPermAxes: Permute the order of a Frame's axes -c - astPickAxes: Create a new Frame by picking axes from an existing one -c - astResolve: Resolve a vector into two orthogonal components -c - astSetActiveUnit: Specify how the Unit attribute should be used -c - astUnformat: Read a formatted coordinate value for a Frame axis -f - AST_ANGLE: Find the angle subtended by two points at a third point -f - AST_AXANGLE: Find the angle from an axis, to a line through two points -f - AST_AXDISTANCE: Calculate the distance between two axis values -f - AST_AXNORM: Normalises an array of axis values -f - AST_AXOFFSET: Calculate an offset along an axis -f - AST_CONVERT: Determine how to convert between two coordinate systems -f - AST_DISTANCE: Calculate the distance between two points in a Frame -f - AST_FINDFRAME: Find a coordinate system with specified characteristics -f - AST_FORMAT: Format a coordinate value for a Frame axis -f - AST_GETACTIVEUNIT: Determines how the Unit attribute will be used -f - AST_INTERSECT: Find the intersection between two geodesic curves -f - AST_MATCHAXES: Find any corresponding axes in two Frames -f - AST_NORM: Normalise a set of Frame coordinates -f - AST_OFFSET: Calculate an offset along a geodesic curve -f - AST_OFFSET2: Calculate an offset along a geodesic curve in a 2D Frame -f - AST_PERMAXES: Permute the order of a Frame's axes -f - AST_PICKAXES: Create a new Frame by picking axes from an existing one -f - AST_RESOLVE: Resolve a vector into two orthogonal components -f - AST_SETACTIVEUNIT: Specify how the Unit attribute should be used -f - AST_UNFORMAT: Read a formatted coordinate value for a Frame axis - -* Notes: -* - When used as a Mapping, a Frame implements a unit (null) -* transformation in both the forward and inverse directions -* (equivalent to a UnitMap). The Nin and Nout attribute values are -* both equal to the number of Frame axes. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: B.S. Berry (Starlink) - -* History: -* 1-MAR-1996 (RFWS): -* Original version. -* 4-JUN-1996 (RFWS): -* Added the CleanDomain function to fold all Domain strings to -* upper case and remove white space. -* 12-JUL-1996 (RFWS): -* Over-ride the astReportPoints method to provide -* Frame-specific formatting. -* 11-SEP-1996 (RFWS): -* Added astGap (written by DSB). -* 10-JUN-1997 (RFWS): -* Re-implemented astConvert and astFindFrame. -* 1-SEP-1997 (RFWS): -* Added missing return statement in astAbbrev_. -* 14-NOV-1997 (RFWS): -* Fixed wrong amount of memory allocated in ValidateAxisSelection. -* 20-NOV-1997 (RFWS): -* Updated astConvert prologue. -* 22-DEC-1997 (RFWS): -* Updated astConvert prologue again. -* 15-FEB-1998 (RFWS): -* Added astUnformat. -* 2-MAR-1999 (RFWS); -* Fixed missing STATUS arguments in examples for AST_FINDFRAME -* prologue. -* 18-JUL-1999 (RFWS): -* Fixed memory leak in ConvertX. -* 21-JUN-2001 (DSB): -* Added methods astAngle and astOffset2. -* 29-AUG-2001 (DSB): -* Added methods astAxDistance and astAxOffset. -* 4-SEP-2001 (DSB): -* Added method astResolve. -* 9-SEP-2001 (DSB): -* Added method astBear. -* 21-SEP-2001 (DSB): -* Replaced astBear with astAxAngle. -* 10-OCT-2002 (DSB): -* Added Top and Bottom. -* 15-NOV-2002 (DSB): -* Moved the System and Epoch attributes from the SkyFrame class to -* this class. Added virtual method astValidateSystem, astSystemString, -* astSystemCode. Added attribute AlignSystem. -* 17-DEC-2002 (DSB): -* Added the GetActiveUnit, TestActiveUnit and SetActiveUnit functions. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitFrameVtab -* method. -* 15-SEP-2003 (DSB): -* Allow Frame attribute names to include an axis specifier within -* GetAttrib, SetAttrib, TestAttrib and ClearAttrib (eg "Domain(1)" -* is now accepted as equivalent to "Domain"). -* 24-JAN-2004 (DSB): -* o Added astFields. -* o Added argument "fmt" to Abbrev. -* 24-MAR-2004 (DSB): -* Add protected function astIsUnitFrame. -* 7-SEP-2004 (DSB): -* Modified SetUnit to exclude any trailing spaces -* 8-SEP-2004 (DSB): -* - Added astResolvePoints. -* - Override astEqual. -* 29-NOV-2004 (DSB): -* - Set/Get/Test/ClearAttrib: Allow axis specifier to be omitted from -* axis attribute names if the Frame only has one axis. -* 2-FEB-2005 (DSB): -* - Avoid using astStore to allocate more storage than is supplied -* in the "data" pointer. This can cause access violations since -* astStore will then read beyond the end of the "data" area. -* 17-FEB-2005 (DSB): -* - Change use of ActiveUnit flag so that both target and template -* Frames must have active units in order for the Mapping to take -* account of differences in units. Previously, the test was based -* on the template Frame alone. -* 23-MAR-2005 (DSB): -* - GetActiveUnit: Always return zero if the Frame contains any -* SkyAxes. -* 5-APR-2005 (DSB): -* Correct error checking in Clear/Get/Set/TestAttrib. -* 12-MAY-2005 (DSB): -* Added astNormBox method. -* 16-JUN-2005 (DSB): -* Added documentation for the TimeFrame class. -* 12-AUG-2005 (DSB): -* Added ObsLat and ObsLon attributes. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 15-MAY-2006 (DSB): -* Remove unused global variable parent_equal. -* 26-JUN-2006 (DSB): -* Document the use of the Direction attribute by the Plot class. -* 30-JUN-2006 (DSB): -* Allow astAbbrev to have a null "str1" value. -* 16-AUG-2006 (DSB): -* Correct "Class Applicability" to "Applicability". -* 5-OCT-2006 (DSB): -* Increase the number of digits used when formating a ObsLon or -* ObsLat value in GetAttrib. -* 14-OCT-2006 (DSB): -* - Add Dut1 attribute -* 26-JAN-2007 (DSB): -* Fix bug in NewUnit that causes segvio when changing axis symbols -* to accomodate changes in units. -* 17-MAY-2007 (DSB): -* Added read-only attribute NormUnit. -* 21-MAY-2007 (DSB): -* Use rather than ignore the value returned by astTestAxisDigits in -* TestAttrib. -* 25-JUN-2007 (DSB): -* Documentation typos. -* 26-NOV-2007 (DSB): -* In Clear/Get/Set/TestAttrib, include any appropriate axis index in -* the attribute name when attempting to get the attribute value from -* the primary frame -* 17-NOV-2008 (DSB): -* Correct parent class in invocation of astMAKE_ISA. -* 14-JAN-2009 (DSB): -* Added astIntersect. -* 18-MAR-2009 (DSB): -* Fixed bug in LineCrossing. -* 18-JUN-2000 (DSB): -* Added ObsAlt attribute. -* 28-SEP-2009 (DSB): -* Added astMatchAxes method. -* 22-MAR-2011 (DSB): -* Add astFrameGrid method. -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -* 11-APR-2012 (DSB): -* Change astValidateAxis so that it can permute in either direction. -* 29-APR-2013 (DSB): -* Added protected methods astSetFrameVariants and astGetFrameVariants. -* 1-MAY-2013 (DSB): -* Override the astDoNotSimplify method to indicate that Frames should -* always be simplified. This is mainly because the STC class uses the -* Ident attribute with Frames, and preventing such frames from -* simplifying (which is what the parent astDoNotSimplify method does) -* causes the STC tester in the ast_tester directory to fail. -* 10-FEB-2015 (DSB): -* When checking attribute settings for attribute names that end with -* an axis index, stop looking for the axis index when the first equals -* sign is encountered. -* 17-APR-2015 (DSB): -* Added astCentre. -* 27-APR-2015 (DSB): -* Added read-only attribute InternalUnit. -* 26-OCT-2016 (DSB): -* Added method astAxNorm. -* 11-JAN-2017 (GSB): -* Add Dtai attribute. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Frame - -/* Define numerical constants for use in this module. */ -#define LABEL_BUFF_LEN 100 /* Max length of default axis Label string */ -#define SYMBOL_BUFF_LEN 50 /* Max length of default axis Symbol string */ -#define TITLE_BUFF_LEN 100 /* Max length of default title string */ -#define GETATTRIB_BUFF_LEN 50 /* Max length of string returned by GetAttrib */ -#define ASTFMTDECIMALYR_BUFF_LEN 50 /* Max length of string returned by GetAttrib */ -#define ASTFORMATID_MAX_STRINGS 50 /* Number of string values buffer by astFormatID*/ - - -/* Define the first and last acceptable System values. */ -#define FIRST_SYSTEM AST__CART -#define LAST_SYSTEM AST__CART - -/* Define macros to implement methods for accessing axis attributes. */ -/* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a method to clear an attribute value for a Frame axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "frame.h" -* MAKE_CLEAR(attribute) - -* Class Membership: -* Defined by the Frame class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstFrame *this, int axis ) -* -* and an external interface function of the form: -* -* void astClear_( AstFrame *this, int axis ) -* -* which implement a method for clearing an attribute value for a specified -* axis of a Frame. - -* Parameters: -* attribute -* The name of the attribute to be cleared, as it appears in the -* function name (e.g. Label in "astClearLabel"). - -* Notes: -* - This macro assumes the existence of a method of the form: -* -* void astClearAxis( AstAxis *this ) -* -* which clears the required attribute for an Axis object. -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attribute) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attribute( AstFrame *this, int axis, int *status ) { \ - AstAxis *ax; /* Pointer to Axis object */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index and obtain a pointer to the required Axis. */ \ - (void) astValidateAxis( this, axis, 1, "astClear" #attribute ); \ - ax = astGetAxis( this, axis ); \ -\ -/* Clear the Axis attribute. */ \ - astClearAxis##attribute( ax ); \ -\ -/* Annul the Axis pointer. */ \ - ax = astAnnul( ax ); \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attribute##_( AstFrame *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,Frame,Clear##attribute))( this, axis, status ); \ -} - -/* -* Name: -* MAKE_GET - -* Purpose: -* Implement a method to get an attribute value for a Frame axis. - -* Type: -* Private macro. - -* Synopsis: -# #include "frame.h" -* MAKE_GET(attribute,type,bad_value,default,assign_default) - -* Class Membership: -* Defined by the Frame class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( AstFrame *this, int axis ) -* -* and an external interface function of the form: -* -* Type astGet_( AstFrame *this, int axis ) -* -* which implement a method for getting an attribute value for a specified -* axis of a Frame. - -* Parameters: -* attribute -* The name of the attribute whose value is to be obtained, as -* it appears in the function name (e.g. Label in -* "astGetLabel"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* default -* A boolean (int) constant that indicates whether a new default value -* should be returned by the method if the requested attribute has not -* been set for the axis. If this value is zero, the axis default will -* be used instead. -* assign_default -* An expression that evaluates to the new default value to be assigned. -* This value is ignored if "default" is zero, but a valid (e.g. -* constant) value should nevertheless be supplied. - -* Notes: -* - This macro assumes the existence of a method of the form: -* -* astGetAxis( AstAxis *this ) -* -* which gets the required attribute for an Axis object. -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_GET(attribute,type,bad_value,default,assign_default) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attribute( AstFrame *this, int axis, int *status ) { \ - AstAxis *ax; /* Pointer to Axis object */ \ - int digits_set; /* Axis Digits attribute set? */ \ - int old_axis; /* Original (un-permuted) axis index */ \ - type result; /* Result to be returned */ \ -\ -/* Initialise. */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate and permute the axis index and obtain a pointer to the required \ - Axis. */ \ - old_axis = axis; \ - axis = astValidateAxis( this, axis, 1, "astGet" #attribute ); \ - ax = astGetAxis( this, old_axis ); \ -\ -/* Since the Axis is "managed" by the enclosing Frame, we next test if any \ - Axis attributes which may affect the result are undefined (i.e. have not \ - been explicitly set). If so, we over-ride them, giving them temporary \ - values dictated by the Frame. Only the Digits attribute is relevant \ - here. */ \ - digits_set = astTestAxisDigits( ax ); \ - if ( !digits_set ) astSetAxisDigits( ax, astGetDigits( this ) ); \ -\ -/* If the default value is to be over-ridden, test if the Axis attribute has \ - been set. Then, if required, obtain the attribute value from the Axis. */ \ - if ( !(default) || astTestAxis##attribute( ax ) ) { \ - result = astGetAxis##attribute( ax ); \ -\ -/* If required, assign the new default value. */ \ - } else { \ - result = (assign_default); \ - } \ -\ -/* Clear Axis attributes which were temporarily over-ridden above and annul \ - the Axis pointer. */ \ - if ( !digits_set ) astClearAxisDigits( ax ); \ - ax = astAnnul( ax ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -type astGet##attribute##_( AstFrame *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,Frame,Get##attribute))( this, axis, status ); \ -} - -/* -* Name: -* MAKE_SET - -* Purpose: -* Implement a method to set an attribute value for a Frame axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "frame.h" -* MAKE_SET(attribute,type) - -* Class Membership: -* Defined by the Frame class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstFrame *this, int axis, value ) -* -* and an external interface function of the form: -* -* void astSet_( AstFrame *this, int axis, value ) -* -* which implement a method for setting an attribute value for a specified -* axis of a Frame. - -* Parameters: -* attribute -* The name of the attribute to be set, as it appears in the -* function name (e.g. Label in "astSetLabel"). -* type -* The C type of the attribute. - -* Notes: -* - This macro assumes the existence of a method of the form: -* -* void astSetAxis( AstAxis *this, value ) -* -* which sets the required attribute for an Axis object. -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_SET(attribute,type) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attribute( AstFrame *this, int axis, type value, int *status ) { \ - AstAxis *ax; /* Pointer to Axis object */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index and obtain a pointer to the required Axis. */ \ - (void) astValidateAxis( this, axis, 1, "astSet" #attribute ); \ - ax = astGetAxis( this, axis ); \ -\ -/* Set the Axis attribute value. */ \ - astSetAxis##attribute( ax, value ); \ -\ -/* Annul the Axis pointer. */ \ - ax = astAnnul( ax ); \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attribute##_( AstFrame *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,Frame,Set##attribute))( this, axis, value, status ); \ -} - -/* -* Name: -* MAKE_TEST - -* Purpose: -* Implement a method to test if an attribute has been set for a Frame axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "frame.h" -* MAKE_TEST(attribute) - -* Class Membership: -* Defined by the Frame class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static int Test( AstFrame *this, int axis ) -* -* and an external interface function of the form: -* -* int astTest_( AstFrame *this, int axis ) -* -* which implement a method for testing if an attribute has been set for a -* specified axis of a Frame. - -* Parameters: -* attribute -* The name of the attribute to be tested, as it appears in the -* function name (e.g. Label in "astTestLabel"). - -* Notes: -* - This macro assumes the existence of a method of the form: -* -* void astTestAxis( AstAxis *this ) -* -* which tests the required attribute for an Axis object. -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_TEST(attribute) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static int Test##attribute( AstFrame *this, int axis, int *status ) { \ - AstAxis *ax; /* Pointer to Axis object */ \ - int result; /* Value to be returned */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Validate the axis index and obtain a pointer to the required Axis. */ \ - (void) astValidateAxis( this, axis, 1, "astTest" #attribute ); \ - ax = astGetAxis( this, axis ); \ -\ -/* Test if the attribute has been set. */ \ - result = astTestAxis##attribute( ax ); \ -\ -/* Annul the Axis pointer. */ \ - ax = astAnnul( ax ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -int astTest##attribute##_( AstFrame *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,Frame,Test##attribute))( this, axis, status ); \ -} - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "pointset.h" /* Sets of points */ -#include "unitmap.h" /* Unit Mapping */ -#include "permmap.h" /* Coordinate permutation Mapping */ -#include "cmpmap.h" /* Compound Mappings */ -#include "axis.h" /* Coordinate Axis */ -#include "skyaxis.h" /* Sky coordinate axes */ -#include "skyframe.h" /* Celestial coordinate frames */ -#include "channel.h" /* I/O channels */ -#include "frame.h" /* Interface definition for this class */ -#include "frameset.h" /* Collections of Frames */ -#include "cmpframe.h" /* Compound Frames */ -#include "pal.h" /* SLALIB library interface */ -#include "unit.h" /* Units identification and mapping */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_cleanattribs)( AstObject *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Define a variable to hold a SkyFrame which will be used for formatting - and unformatting ObsLat and ObsLon values. */ -static AstSkyFrame *skyframe; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->AstFormatID_Init = 0; \ - globals->AstFormatID_Istr = 0; \ - globals->Label_Buff[ 0 ] = 0; \ - globals->Symbol_Buff[ 0 ] = 0; \ - globals->Title_Buff[ 0 ] = 0; \ - globals->AstFmtDecimalYr_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Frame) - -#define class_init astGLOBAL(Frame,Class_Init) -#define class_vtab astGLOBAL(Frame,Class_Vtab) -#define getattrib_buff astGLOBAL(Frame,GetAttrib_Buff) -#define astformatid_strings astGLOBAL(Frame,AstFormatID_Strings) -#define astformatid_istr astGLOBAL(Frame,AstFormatID_Istr) -#define astformatid_init astGLOBAL(Frame,AstFormatID_Init) -#define label_buff astGLOBAL(Frame,Label_Buff) -#define symbol_buff astGLOBAL(Frame,Symbol_Buff) -#define title_buff astGLOBAL(Frame,Title_Buff) -#define astfmtdecimalyr_buff astGLOBAL(Frame,AstFmtDecimalYr_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ GETATTRIB_BUFF_LEN + 1 ]; - -/* Strings returned by astFormatID */ -static char *astformatid_strings[ ASTFORMATID_MAX_STRINGS ]; - -/* Offset of next string in "AstFormatID_Strings" */ -static int astformatid_istr; - -/* "AstFormatID_Strings" array initialised? */ -static int astformatid_init; - -/* Default Label string buffer */ -static char label_buff[ LABEL_BUFF_LEN + 1 ]; - -/* Default Symbol buffer */ -static char symbol_buff[ SYMBOL_BUFF_LEN + 1 ]; - -/* Default Title string buffer */ -static char title_buff[ TITLE_BUFF_LEN + 1 ]; - -/* Buffer for result string */ -static char astfmtdecimalyr_buff[ ASTFMTDECIMALYR_BUFF_LEN + 1 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstFrameVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstAxis *GetAxis( AstFrame *, int, int * ); -static AstFrame *PickAxes( AstFrame *, int, const int[], AstMapping **, int * ); -static AstFrameSet *Convert( AstFrame *, AstFrame *, const char *, int * ); -static AstFrameSet *ConvertX( AstFrame *, AstFrame *, const char *, int * ); -static AstFrameSet *FindFrame( AstFrame *, AstFrame *, const char *, int * ); -static void MatchAxes( AstFrame *, AstFrame *, int *, int * ); -static void MatchAxesX( AstFrame *, AstFrame *, int *, int * ); -static AstLineDef *LineDef( AstFrame *, const double[2], const double[2], int * ); -static AstPointSet *FrameGrid( AstFrame *, int, const double *, const double *, int * ); -static AstPointSet *ResolvePoints( AstFrame *, const double [], const double [], AstPointSet *, AstPointSet *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static char *CleanDomain( char *, int * ); -static const char *Abbrev( AstFrame *, int, const char *, const char *, const char *, int * ); -static const char *Format( AstFrame *, int, double, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetDefaultLabel( int, int * ); -static const char *GetDefaultSymbol( AstFrame *, int, int * ); -static const char *GetDefaultTitle( AstFrame *, int * ); -static const char *GetDomain( AstFrame *, int * ); -static const char *GetFormat( AstFrame *, int, int * ); -static const char *GetInternalUnit( AstFrame *, int, int * ); -static const char *GetLabel( AstFrame *, int, int * ); -static const char *GetNormUnit( AstFrame *, int, int * ); -static const char *GetSymbol( AstFrame *, int, int * ); -static const char *GetTitle( AstFrame *, int * ); -static const char *GetUnit( AstFrame *, int, int * ); -static const int *GetPerm( AstFrame *, int * ); -static double Angle( AstFrame *, const double[], const double[], const double[], int * ); -static double AxAngle( AstFrame *, const double[], const double[], int, int * ); -static double AxDistance( AstFrame *, int, double, double, int * ); -static double AxOffset( AstFrame *, int, double, double, int * ); -static double Distance( AstFrame *, const double[], const double[], int * ); -static double Centre( AstFrame *, int, double, double, int * ); -static double Gap( AstFrame *, int, double, int *, int * ); -static double Offset2( AstFrame *, const double[2], double, double, double[2], int * ); -static int AxIn( AstFrame *, int, double, double, double, int, int * ); -static int ConsistentMaxAxes( AstFrame *, int, int * ); -static int ConsistentMinAxes( AstFrame *, int, int * ); -static int DefaultMaxAxes( AstFrame *, int * ); -static int DefaultMinAxes( AstFrame *, int * ); -static int DoNotSimplify( AstMapping *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int Fields( AstFrame *, int, const char *, const char *, int, char **, int *, double *, int * ); -static int GetDigits( AstFrame *, int * ); -static int GetDirection( AstFrame *, int, int * ); -static int GetIsLinear( AstMapping *, int * ); -static int GetIsSimple( AstMapping *, int * ); -static int LineContains( AstFrame *, AstLineDef *, int, double *, int * ); -static int LineCrossing( AstFrame *, AstLineDef *, AstLineDef *, double **, int * ); -static int GetObjSize( AstObject *, int * ); -static void AxNorm( AstFrame *, int, int, int, double *, int * ); -static void CleanAttribs( AstObject *, int * ); -static void LineOffset( AstFrame *, AstLineDef *, double, double, double[2], int * ); - -static double GetTop( AstFrame *, int, int * ); -static int TestTop( AstFrame *, int, int * ); -static void ClearTop( AstFrame *, int, int * ); -static void SetTop( AstFrame *, int, double, int * ); - -static double GetBottom( AstFrame *, int, int * ); -static int TestBottom( AstFrame *, int, int * ); -static void ClearBottom( AstFrame *, int, int * ); -static void SetBottom( AstFrame *, int, double, int * ); - -static AstSystemType GetSystem( AstFrame *, int * ); -static int TestSystem( AstFrame *, int * ); -static void ClearSystem( AstFrame *, int * ); -static void SetSystem( AstFrame *, AstSystemType, int * ); - -static AstSystemType GetAlignSystem( AstFrame *, int * ); -static int TestAlignSystem( AstFrame *, int * ); -static void ClearAlignSystem( AstFrame *, int * ); -static void SetAlignSystem( AstFrame *, AstSystemType, int * ); - -static double GetEpoch( AstFrame *, int * ); -static int TestEpoch( AstFrame *, int * ); -static void ClearEpoch( AstFrame *, int * ); -static void SetEpoch( AstFrame *, double, int * ); - -static double GetObsLat( AstFrame *, int * ); -static int TestObsLat( AstFrame *, int * ); -static void ClearObsLat( AstFrame *, int * ); -static void SetObsLat( AstFrame *, double, int * ); - -static double GetObsLon( AstFrame *, int * ); -static int TestObsLon( AstFrame *, int * ); -static void ClearObsLon( AstFrame *, int * ); -static void SetObsLon( AstFrame *, double, int * ); - -static double GetObsAlt( AstFrame *, int * ); -static int TestObsAlt( AstFrame *, int * ); -static void ClearObsAlt( AstFrame *, int * ); -static void SetObsAlt( AstFrame *, double, int * ); - -static double GetDtai( AstFrame *, int * ); -static int TestDtai( AstFrame *, int * ); -static void ClearDtai( AstFrame *, int * ); -static void SetDtai( AstFrame *, double, int * ); - -static double GetDut1( AstFrame *, int * ); -static int TestDut1( AstFrame *, int * ); -static void ClearDut1( AstFrame *, int * ); -static void SetDut1( AstFrame *, double, int * ); - -static int GetActiveUnit( AstFrame *, int * ); -static int TestActiveUnit( AstFrame *, int * ); -static void SetActiveUnit( AstFrame *, int, int * ); - -static AstFrameSet *GetFrameVariants( AstFrame *, int * ); -static void SetFrameVariants( AstFrame *, AstFrameSet *, int * ); - -static int GetFrameFlags( AstFrame *, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); -static int GetMatchEnd( AstFrame *, int * ); -static int GetMaxAxes( AstFrame *, int * ); -static int GetMinAxes( AstFrame *, int * ); -static int GetNaxes( AstFrame *, int * ); -static int GetNin( AstMapping *, int * ); -static int GetNout( AstMapping *, int * ); -static int GetPermute( AstFrame *, int * ); -static int GetPreserveAxes( AstFrame *, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestDigits( AstFrame *, int * ); -static int TestDirection( AstFrame *, int, int * ); -static int TestDomain( AstFrame *, int * ); -static int TestFormat( AstFrame *, int, int * ); -static int TestLabel( AstFrame *, int, int * ); -static int TestMatchEnd( AstFrame *, int * ); -static int TestMaxAxes( AstFrame *, int * ); -static int TestMinAxes( AstFrame *, int * ); -static int TestPermute( AstFrame *, int * ); -static int TestPreserveAxes( AstFrame *, int * ); -static int TestSymbol( AstFrame *, int, int * ); -static int TestTitle( AstFrame *, int * ); -static int TestUnit( AstFrame *, int, int * ); -static int IsUnitFrame( AstFrame *, int * ); -static int Unformat( AstFrame *, int, const char *, double *, int * ); -static int ValidateAxis( AstFrame *, int, int, const char *, int * ); -static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * ); -static AstSystemType SystemCode( AstFrame *, const char *, int * ); -static const char *SystemString( AstFrame *, AstSystemType, int * ); -static void AddUnderscores( char *, int * ); -static void CheckPerm( AstFrame *, const int *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearDigits( AstFrame *, int * ); -static void ClearDirection( AstFrame *, int, int * ); -static void ClearDomain( AstFrame *, int * ); -static void ClearFormat( AstFrame *, int, int * ); -static void ClearLabel( AstFrame *, int, int * ); -static void ClearMatchEnd( AstFrame *, int * ); -static void ClearMaxAxes( AstFrame *, int * ); -static void ClearMinAxes( AstFrame *, int * ); -static void ClearPermute( AstFrame *, int * ); -static void ClearPreserveAxes( AstFrame *, int * ); -static void ClearSymbol( AstFrame *, int, int * ); -static void ClearTitle( AstFrame *, int * ); -static void ClearUnit( AstFrame *, int, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void Intersect( AstFrame *, const double[2], const double[2], const double[2], const double[2], double[2], int * ); -static void Norm( AstFrame *, double[], int * ); -static void NormBox( AstFrame *, double[], double[], AstMapping *, int * ); -static void Offset( AstFrame *, const double[], const double[], double, double[], int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void PermAxes( AstFrame *, const int[], int * ); -static void PrimaryFrame( AstFrame *, int, AstFrame **, int *, int * ); -static void ReportPoints( AstMapping *, int, AstPointSet *, AstPointSet *, int * ); -static void Resolve( AstFrame *, const double [], const double [], const double [], double [], double *, double *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetAxis( AstFrame *, int, AstAxis *, int * ); -static void SetDigits( AstFrame *, int, int * ); -static void SetDirection( AstFrame *, int, int, int * ); -static void SetDomain( AstFrame *, const char *, int * ); -static void SetFormat( AstFrame *, int, const char *, int * ); -static void SetFrameFlags( AstFrame *, int, int * ); -static void SetLabel( AstFrame *, int, const char *, int * ); -static void SetMatchEnd( AstFrame *, int, int * ); -static void SetMaxAxes( AstFrame *, int, int * ); -static void SetMinAxes( AstFrame *, int, int * ); -static void SetPermute( AstFrame *, int, int * ); -static void SetPreserveAxes( AstFrame *, int, int * ); -static void SetSymbol( AstFrame *, int, const char *, int * ); -static void SetTitle( AstFrame *, const char *, int * ); -static void SetUnit( AstFrame *, int, const char *, int * ); -static void NewUnit( AstAxis *, const char *, const char *, const char *, const char *, int * ); -static void ValidateAxisSelection( AstFrame *, int, const int *, const char *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ -static const char *Abbrev( AstFrame *this, int axis, const char *fmt, - const char *str1, const char *str2, int *status ) { -/* -*+ -* Name: -* astAbbrev - -* Purpose: -* Abbreviate a formatted Frame axis value by skipping leading fields. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* const char *astAbbrev( AstFrame *this, int axis, const char *fmt, -* const char *str1, const char *str2 ) - -* Class Membership: -* Frame method. - -* Description: -* This function compares two Frame axis values that have been -* formatted (using astFormat) and determines if they have any -* redundant leading fields (i.e. leading fields in common which -* can be suppressed when tabulating the values or plotting them on -* the axis of a graph). - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the Frame axis for which the values have been -* formatted (axis numbering starts at zero for the first axis). -* fmt -* Pointer to a constant null-terminated string containing the -* format specification used to format the two values. -* str1 -* Pointer to a constant null-terminated string containing the -* first formatted value. If this is null, the returned pointer -* points to the start of the final field in str2. -* str2 -* Pointer to a constant null-terminated string containing the -* second formatted value. - -* Returned Value: -* A pointer into the "str2" string which locates the first -* character in the first field that differs between the two -* formatted values. -* -* If the two values have no leading fields in common, the returned -* value will point at the start of string "str2". If the two -* values are equal, it will point at the terminating null at the -* end of this string. - -* Notes: -* - This function assumes that the format specification used was -* the same when both values were formatted and that they both -* apply to the same Frame axis. -* - A pointer to the start of "str2" will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - const char *result; /* Result pointer to return */ - -/* Initialise. */ - result = str2; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate the axis index and obtain a pointer to the required - Axis. */ - (void) astValidateAxis( this, axis, 1, "astAbbrev" ); - ax = astGetAxis( this, axis ); - -/* Invoke the Axis astAxisAbbrev method to perform the processing. */ - result = astAxisAbbrev( ax, fmt, str1, str2 ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = str2; - -/* Return the result. */ - return result; -} - -static void AddUnderscores( char *string, int *status ) { -/* -* Name: -* AddUnderscores - -* Purpose: -* Add underscores to a string in place of white space. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* void AddUnderscores( char *string, int *status ) - -* Class Membership: -* Frame member function. - -* Description: -* This function changes all white space characters in a string into -* the underscore character '_'. - -* Parameters: -* this -* Pointer to the Frame. -* string -* Pointer to the null terminated string to be processed. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables. */ - int i; /* Loop counter for characters */ - -/* Inspect each character in the string. */ - for ( i = 0; string[ i ]; i++ ) { - -/* If it is a white space character, replace it with an underscore. */ - if ( isspace( string[ i ] ) ) string[ i ] = '_'; - } -} - -static double Angle( AstFrame *this, const double a[], - const double b[], const double c[], int *status ) { -/* -*++ -* Name: -c astAngle -f AST_ANGLE - -* Purpose: -* Calculate the angle subtended by two points at a third point. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c double astAngle( AstFrame *this, const double a[], const double b[], -c const double c[] ) -f RESULT = AST_ANGLE( THIS, A, B, C, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* finds the angle at point B between the line joining points A and B, -* and the line joining points C and B. These lines will in fact be -* geodesic curves appropriate to the Frame in use. For instance, in -* SkyFrame, they will be great circles. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c a -f A( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the first point. -c b -f B( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the second point. -c c -f C( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the third point. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astAngle -f AST_ANGLE = DOUBLE PRECISION -* The angle in radians, from the line AB to the line CB. If the -* Frame is 2-dimensional, it will be in the range $\pm \pi$, -* and positive rotation is in the same sense as rotation from -* the positive direction of axis 2 to the positive direction of -* axis 1. If the Frame has more than 2 axes, a positive value will -* always be returned in the range zero to $\pi$. - -* Notes: -* - A value of AST__BAD will also be returned if points A and B are -* co-incident, or if points B and C are co-incident. -* - A value of AST__BAD will also be returned if this function is -c invoked with the AST error status set, or if it should fail for -f invoked with STATUS set to an error value, or if it should fail for -* any reason. -*-- -*/ - -/* Local Variables: */ - double *ab; /* Pointer to vector AB */ - double *cb; /* Pointer to vector CB */ - double cos; /* cosine of required angle */ - double anga; /* Angle from +ve Y to the line BA */ - double angc; /* Angle from +ve Y to the line BC */ - double result; /* Result value to return */ - double sla; /* Squared length of vector AB */ - double slc; /* Squared length of vector CB */ - double sp; /* Scalar product of AB and CB */ - int axis; /* Axis index */ - int naxes; /* Number of Frame axes */ - int ok; /* Supplied points OK? */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Assume everything is ok */ - ok = 1; - -/* Obtain the number of Frame axes. */ - naxes = astGetNaxes( this ); - -/* Obtain workspace. */ - ab = (double *) astMalloc( sizeof(double)*naxes ); - cb = (double *) astMalloc( sizeof(double)*naxes ); - -/* Check all positions are good, and form the vectors from b to a, and - from b to c. Also find the squared length of each vector. */ - if( astOK ) { - sla = 0.0; - slc = 0.0; - for( axis = 0; axis < naxes; axis++ ) { - if( a[ axis ] == AST__BAD || b[ axis ] == AST__BAD || - c[ axis ] == AST__BAD ) { - ok = 0; - break; - } else { - ab[ axis ] = a[ axis ] - b[ axis ]; - cb[ axis ] = c[ axis ] - b[ axis ]; - sla += ( ab[ axis ] )*( ab[ axis ] ); - slc += ( cb[ axis ] )*( cb[ axis ] ); - } - } - -/* Check that neither of the vectors have zero length. */ - if( sla == 0 || slc == 0 ) ok = 0; - -/* Only proceed if these checks were passed. */ - if ( ok ) { - -/* Deal first with 2-dimensional Frames. */ - if( naxes == 2 ) { - -/* Find the angle from +ve Y to the line BA. */ - anga = atan2( ab[ 0 ], ab[ 1 ] ); - -/* Find the angle from +ve Y to the line BC. */ - angc = atan2( cb[ 0 ], cb[ 1 ] ); - -/* Find the difference, folded into the range +/- PI. */ - result = palDrange( angc - anga ); - -/* Now deal with Frames with more than 2 axes. */ - } else { - -/* Form the scalar product of the two vectors. */ - sp = 0.0; - for( axis = 0; axis < naxes; axis++ ) { - sp += ab[ axis ]*cb[ axis ]; - } - -/* Derive the required angle from the normalized scalar product. */ - cos = sp/sqrt( sla*slc ); - if( cos > 1.0 ) { - cos = 1.0; - } else if( cos < -1.0 ) { - cos = -1.0; - } - result =acos( cos ); - } - } - } - -/* Free the work space. */ - ab = (double *) astFree( (void *) ab ); - cb = (double *) astFree( (void *) cb ); - -/* Return the result. */ - return result; -} - -static double AxAngle( AstFrame *this, const double a[], const double b[], int axis, int *status ) { -/* -*++ -* Name: -c astAxAngle -f AST_AXANGLE - -* Purpose: -* Returns the angle from an axis, to a line through two points. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c double astAxAngle( AstFrame *this, const double a[], const double b[], int axis ) -f RESULT = AST_AXANGLE( THIS, A, B, AXIS, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* finds the angle, as seen from point A, between the positive -* direction of a specified axis, and the geodesic curve joining point -* A to point B. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c a -f A( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the first point. -c b -f B( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the second point. -c axis -f AXIS = INTEGER (Given) -* The number of the Frame axis from which the angle is to be -* measured (axis numbering starts at 1 for the first axis). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astAxAngle -f AST_AXANGLE = DOUBLE PRECISION -* The angle in radians, from the positive direction of the -* specified axis, to the line AB. If the Frame is 2-dimensional, -* it will be in the range [-PI/2,+PI/2], and positive rotation is in -* the same sense as rotation from the positive direction of axis 2 -* to the positive direction of axis 1. If the Frame has more than 2 -* axes, a positive value will always be returned in the range zero -* to PI. - -* Notes: -c - The geodesic curve used by this function is the path of -f - The geodesic curve used by this routine is the path of -* shortest distance between two points, as defined by the -c astDistance function. -f AST_DISTANCE function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value, or if the require -* position angle is undefined. -*-- -*/ - -/* Local Variables: */ - double *aa; /* Pointer to third point */ - double ab; /* Absolute value of component */ - double mxab; /* Largest absolute value of component */ - double result; /* The returned value */ - int iaxis; /* Axis index */ - int naxes; /* Number of Frame axes */ - int ok; /* Are values ok to use? */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxAngle" ); - -/* Obtain the number of Frame axes. */ - naxes = astGetNaxes( this ); - -/* Obtain workspace. */ - aa = (double *) astMalloc( sizeof(double)*naxes ); - -/* Create a position which is offset slightly from point A in the - positive direction of the specified axis. Also get the largest absolute - value of any component of the vector AB. */ - if( astOK ) { - ok = 1; - mxab = 0.0; - - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - if( a[ iaxis ] != AST__BAD && b[ iaxis ] != AST__BAD ) { - aa[ iaxis ] = a[ iaxis ]; - ab = fabs( a[ iaxis ] - b[ iaxis ] ); - if( ab > mxab ) mxab = ab; - } else { - ok = 0; - break; - } - } - - if( ok ) { - - if( a[ axis - 1 ] != 0.0 ) { - aa[ axis - 1 ] += 10000.0*DBL_EPSILON*fabs( a[ axis - 1 ] ); - - } else if( b[ axis - 1 ] != 0.0 ) { - aa[ axis - 1 ] = 10000.0*DBL_EPSILON*fabs( b[ iaxis - 1 ] ); - - } else if( mxab != 0.0 ) { - aa[ axis - 1 ] = 10000.0*DBL_EPSILON*mxab; - - } else { - aa[ axis - 1 ] = 1.0; - } - -/* Use astAngle to get the required angle. */ - result = astAngle( this, aa, a, b ); - } - } - -/* Free the workspace. */ - aa = (double *) astFree( (void *) aa ); - -/* Return the result. */ - return result; - -} - -static double AxDistance( AstFrame *this, int axis, double v1, double v2, int *status ) { -/* -*++ -* Name: -c astAxDistance -f AST_AXDISTANCE - -* Purpose: -* Find the distance between two axis values. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c double astAxDistance( AstFrame *this, int axis, double v1, double v2 ) -f RESULT = AST_AXDISTANCE( THIS, AXIS, V1, V2, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function returns a signed value representing the axis increment -f This routine returns a signed value representing the axis increment -* from axis value v1 to axis value v2. -* -* For a simple Frame, this is a trivial operation returning the -* difference between the two axis values. But for other derived classes -* of Frame (such as a SkyFrame) this is not the case. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c axis -f AXIS = INTEGER (Given) -* The index of the axis to which the supplied values refer. The -* first axis has index 1. -c v1 -f V1 = DOUBLE PRECISION (Given) -* The first axis value. -c v2 -f V2 = DOUBLE PRECISION (Given) -* The second axis value. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astAxDistance -f AST_AXDISTANCE = DOUBLE PRECISION -* The distance from the first to the second axis value. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input values has this value. -* - A "bad" value will also be returned if this function is -c invoked with the AST error status set, or if it should fail for -f invoked with STATUS set to an error value, or if it should fail for -* any reason. -*-- - -* Implementation Deficiencies; -* - The protected interface for this function uses 1-based axis -* numbering (like the public interface), rather than the more usual -* zero-based system used by all other protected interfaces. There is -* no real reason for this, and it should be changed at some time. - -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - double result; /* The returned answer */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate the axis index and obtain a pointer to the required Axis. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxDistance" ); - ax = astGetAxis( this, axis - 1 ); - -/* Use the AxisDistance method associated with the Axis. */ - if( astOK ) result = astAxisDistance( ax, v1, v2 ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* Return the result. */ - return result; - -} - -static void AxNorm( AstFrame *this, int axis, int oper, int nval, - double *values, int *status ){ -/* -*++ -* Name: -c astAxNorm -f AST_AXNORM - -* Purpose: -* Normalise an array of axis values. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c void astAxNorm( AstFrame *this, int axis, int oper, int nval, -c double *values, int *status ) -f CALL AST_AXNORM( THIS, AXIS, OPER, NVAL, VALUES, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* modifies a supplied array of axis values so that they are normalised -* in the manner indicated by -c parameter "oper". -f argument OPER. -* -* No normalisation is possible for a simple Frame and so the supplied -* values are returned unchanged. However, this may not be the case for -* specialised sub-classes of Frame. For instance, a SkyFrame has a -* discontinuity at zero longitude and so a longitude value can be -* expressed in the range [-Pi,+PI] or the range [0,2*PI]. See the -* "Applicability:" section below for details. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c axis -f AXIS = INTEGER (Given) -* The index of the axis to which the supplied values refer. The -* first axis has index 1. -c oper -f OPER = INTEGER (Given) -* Indicates the type of normalisation to be applied. If zero is -* supplied, the normalisation will be the same as that performed by -c function astNorm. -f routine AST_NORM. -* If 1 is supplied, the normalisation will be chosen automatically -* so that the resulting list has the smallest range. -c nval -f NVAL = INTEGER (Given) -* The number of points in the values array. -c values -f VALUES( NVAL ) = DOUBLE PRECISION (Given and Returned) -* On entry, the axis values to be normalised. Modified on exit to -* hold the normalised values. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* SkyFrame -c If "oper" -f If OPER -* is 0, longitude values are returned in the range [0,2*PI]. -c If "oper" -f If OPER -* is 1, longitude values are returned in either the range -* [0,2*PI] or [-PI,PI]. The choice is made so that that the -* resulting list has the smallest range. Latitude values are -* always returned in the range [-PI,PI]. -* All other classes of Frame -* The supplied axis values are returned unchanged. - -*-- - -* Implementation Deficiencies; -* - The protected interface for this function uses 1-based axis -* numbering (like the public interface), rather than the more usual -* zero-based system used by all other protected interfaces. There is -* no real reason for this, and it should be changed at some time. - -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the axis index and obtain a pointer to the required Axis. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxNorm" ); - ax = astGetAxis( this, axis - 1 ); - -/* Validate ther "oper" value. */ - if( ( oper < 0 || oper > 1 ) && astOK ) { - astError( AST__OPRIN, "astAxNorm(%s): Invalid operation %d.", status, - astGetClass( this ), oper ); - } - -/* Use the AxisNormValues method associated with the Axis. */ - if( astOK ) astAxisNormValues( ax, oper, nval, values ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); -} - -static int AxIn( AstFrame *this, int axis, double lo, double hi, double val, - int closed, int *status ){ -/* -*+ -* Name: -* astAxIn - -* Purpose: -* Test if an axis value lies within a given interval. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astAxIn( AstFrame *this, int axis, double lo, double hi, double val, -* int closed ) - -* Class Membership: -* Frame member function. - -* Description: -* This function returns non-zero if a given axis values lies within a -* given axis interval. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The index of the axis. The first axis has index 0. -* lo -* The lower axis limit of the interval. -* hi -* The upper axis limit of the interval. -* val -* The axis value to be tested. -* closed -* If non-zero, then the lo and hi axis values are themselves -* considered to be within the interval. Otherwise they are outside. - -* Returned Value: -* Non-zero if the test value is inside the interval. - -* Applicability: -* Frame -* Uses simple Euclidean test -* SkyFrame -* All angles which are numerically between "lo" and "hi" are within -* the interval. Angle outside this range are also within the interval -* if they can be brought into the range by addition or subtraction -* of a multiple of 2.PI. -*- -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - int result; /* Returned value */ - -/* For speed, omit the astOK check and axis validation (since this is - protected code, AST should get it right). Obtain a pointer to the - required Axis. */ - ax = astGetAxis( this, axis ); - -/* Use the AxisIn method associated with the Axis. */ - result = ax ? astAxisIn( ax, lo, hi, val, closed ) : 0; - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* Return the result. */ - return result; -} - -static double AxOffset( AstFrame *this, int axis, double v1, double dist, int *status ) { -/* -*++ -* Name: -c astAxOffset -f AST_AXOFFSET - -* Purpose: -* Add an increment onto a supplied axis value. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c double astAxOffset( AstFrame *this, int axis, double v1, double dist ) -f RESULT = AST_AXOFFSET( THIS, AXIS, V1, DIST, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function returns an axis value formed by adding a signed axis -f This routine returns an axis value formed by adding a signed axis -* increment onto a supplied axis value. -* -* For a simple Frame, this is a trivial operation returning the -* sum of the two supplied values. But for other derived classes -* of Frame (such as a SkyFrame) this is not the case. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c axis -f AXIS = INTEGER (Given) -* The index of the axis to which the supplied values refer. The -* first axis has index 1. -c v1 -f V1 = DOUBLE PRECISION (Given) -* The original axis value. -c dist -f DIST = DOUBLE PRECISION (Given) -* The axis increment to add to the original axis value. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astAxOffset -f AST_AXOFFSET = DOUBLE PRECISION -* The incremented axis value. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input values has this value. -* - A "bad" value will also be returned if this function is -c invoked with the AST error status set, or if it should fail for -f invoked with STATUS set to an error value, or if it should fail for -* any reason. -*-- -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - double result; /* The returned answer */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate the axis index and obtain a pointer to the required Axis. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxOffset" ); - ax = astGetAxis( this, axis - 1 ); - -/* Use the AxisOffset method associated with the Axis. */ - if( astOK ) result = astAxisOffset( ax, v1, dist ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* Return the result. */ - return result; - -} - -static double Centre( AstFrame *this, int axis, double value, double gap, int *status ) { -/* -*+ -* Name: -* astCentre - -* Purpose: -* Find a "nice" central value for tabulating Axis values. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* double astCentre( AstFrame *this, int axis, double value, double gap ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns an axis value which produces a nice formatted -* value suitable for a major tick mark on a plot axis, close to the -* supplied axis value. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which a gap is to be found. -* value -* An arbitrary axis value in the section that is being plotted. -* gap -* The gap size. - -* Returned Value: -* The nice central axis value. - -* Notes: -* - A value of zero is returned if the supplied gap size is zero. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - double result; /* The nice central value */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Validate the axis index and obtain a pointer to the required - Axis. */ - (void) astValidateAxis( this, axis, 1, "astCentre" ); - ax = astGetAxis( this, axis ); - -/* Find the nice central value. */ - result = astAxisCentre( ax, value, gap ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static void CheckPerm( AstFrame *this, const int *perm, const char *method, int *status ) { -/* -*+ -* Name: -* astCheckPerm - -* Purpose: -* Check that an array contains a valid permutation. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void astCheckPerm( AstFrame *this, const int *perm, const char *method ) - -* Class Membership: -* Frame method. - -* Description: -* This function checks the validity of a permutation array that -* will be used to permute the order of a Frame's axes. If the -* permutation specified by the array is not valid, an error is -* reported and the global error status is set. Otherwise, the -* function returns without further action. - -* Parameters: -* this -* Pointer to the Frame. -* perm -* Pointer to an array of integers with the same number of -* elements as there are axes in the Frame. For each axis, the -* corresponding integer gives the (zero based) axis index to be -* used to identify the information for that axis (using the -* un-permuted axis numbering). To be valid, the integers in -* this array should therefore all lie in the range zero to -* (naxes-1) inclusive, where "naxes" is the number of Frame -* axes, and each value should occur exactly once. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate a permutation array. This method name is used -* solely for constructing error messages. - -* Notes: -* - Error messages issued by this function refer to the external -* (public) numbering system used for axes (which is one-based), -* whereas zero-based axis indices are used internally. -*- -*/ - -/* Local Variables: */ - int *there; /* Pointer to temporary array */ - int axis; /* Loop counter for axes */ - int naxes; /* Number of Frame axes */ - int valid; /* Permutation array is valid? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise. */ - valid = 1; - -/* Obtain the number of Frame axes and allocate a temporary array of integers - with the same number of elements. */ - naxes = astGetNaxes( this ); - there = astMalloc( sizeof( int ) * (size_t) naxes ); - if ( astOK ) { - -/* Initialise the temporary array to zero. */ - for ( axis = 0; axis < naxes; axis++ ) there[ axis ] = 0; - -/* Scan the permutation array, checking that each permuted axis index it - contains is within the correct range. Note an error and quit checking - if an invalid value is found. */ - for ( axis = 0; axis < naxes; axis++ ) { - if ( ( perm[ axis ] < 0 ) || ( perm[ axis ] >= naxes ) ) { - valid = 0; - break; - -/* Use the temporary array to count how many times each valid axis index - occurs. */ - } else { - there[ perm[ axis ] ]++; - } - } - -/* If all the axis indices were within range, check to ensure that each value - occurred only once. */ - if ( valid ) { - for ( axis = 0; axis < naxes; axis++ ) { - -/* Note an error and quit checking if any value did not occur exactly once. */ - if ( there[ axis ] != 1 ) { - valid = 0; - break; - } - } - } - } - -/* Free the temporary array. */ - there = astFree( there ); - -/* If an invalid permutation was detected and no other error has - occurred, then report an error (note we convert to one-based axis - numbering in the error message). */ - if ( !valid && astOK ) { - astError( AST__PRMIN, "%s(%s): Invalid axis permutation array.", status, - method, astGetClass( this ) ); - astError( AST__PRMIN, "Each axis index should lie in the range 1 to %d " - "and should occur only once.", status, naxes ); - } -} - -static void CleanAttribs( AstObject *this_object, int *status ) { -/* -* Name: -* CleanAttribs - -* Purpose: -* Clear any invalid set attribute values. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* void CleanAttribs( AstObject *this_object, int *status ) - -* Class Membership: -* Frame member function (over-rides the protected astCleanAttribs -* method inherited from the Object class). - -* Description: -* This function clears any attributes that are currently set to -* invalid values in thr supplied object. - -* Parameters: -* this -* Pointer to the Object to be cleaned. - -*/ - -/* Local Variables; */ - AstAxis *ax; - AstFrame *this; - int i; - int nax; - int reporting; - -/* Check inherited status */ - if( !astOK ) return; - -/* Get a pointer to the Frame structure. */ - this = (AstFrame *) this_object; - -/* Defer error reporting, as required by the astCLEAN_ATTRIB macro. */ - reporting = astReporting( 0 ); - -/* Clean attributes in any Objects contained within "this". */ - nax = astGetNaxes( this ); - for( i = 0; i < nax; i++ ) { - ax = astGetAxis( this, i ); - astCleanAttribs( ax ); - ax = astAnnul( ax ); - } - -/* Clean attributes of this class. */ - astCLEAN_ATTRIB(System) - astCLEAN_ATTRIB(AlignSystem) - -/* Re-establish error reporting. */ - astReporting( reporting ); - -/* Invoke the method inherited form the parent to clean attributes - defined by the parent class. */ - (*parent_cleanattribs)( this_object, status ); -} - -static char *CleanDomain( char *domain, int *status ) { -/* -* Name: -* CleanDomain - -* Purpose: -* Clean a Domain string and convert to upper case. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* char *CleanDomain( char *domain, int *status ) - -* Class Membership: -* Frame member function. - -* Description: -* This function removes all white space from a string and converts -* other characters to upper case. It is intended for cleaning up -* values supplied for the Domain attribute of a Frame. - -* Parameters: -* domain -* Pointer to the null terminated Domain string to be modified. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The pointer value "domain" is always returned (even under error -* conditions). -*/ - -/* Local Variables: */ - int i; /* Loop counter for characters */ - int j; /* Good character count */ - -/* Check the global error status. */ - if ( !astOK ) return domain; - -/* Eliminate white space characters and convert the rest to upper - case. */ - for ( i = j = 0; domain[ i ]; i++ ) { - if ( !isspace( domain[ i ] ) ) domain[ j++ ] = toupper( domain[ i ] ); - } - domain[ j ] = '\0'; - -/* Return the string pointer. */ - return domain; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Frame member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* Frame, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Frame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis */ - AstFrame *pfrm; /* Pointer to primary Frame containing axis */ - AstFrame *this; /* Pointer to the Frame structure */ - char pfrm_attrib[ 100 ]; /* Primary Frame attribute */ - char *axis_attrib; /* Pointer to axis attribute name */ - const char *old_attrib; /* Pointer to supplied attribute name string */ - int axis; /* Frame axis number */ - int axis_nc; /* No. characters in axis attribute name */ - int free_axis_attrib; /* Should axis_attrib be freed? */ - int has_axis; /* Does attrib name include axis specifier? */ - int len; /* Length of attrib string */ - int nc; /* No. characters read by astSscanf */ - int oldrep; /* Original error reporting state */ - int paxis; /* Axis index within primary frame */ - int used; /* Could the setting string be used? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) this_object; - -/* Set a flag indicating if the attribute name includes an axis - specifier. */ - has_axis = ( strchr( attrib, '(' ) != NULL ); - -/* A flag indicating that we do not need to free the axis_attrib memory. */ - free_axis_attrib = 0; - -/* Initialise things to avoid compiler warnings. */ - axis_attrib = NULL; - old_attrib = NULL; - -/* Jump back to here if we are trying the same attribute but with an explicit - axis "(1)" added to the end of the name. */ -L1: - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Digits. */ -/* ------- */ - if ( !strcmp( attrib, "digits" ) ) { - astClearDigits( this ); - -/* Digits(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "digits(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - -/* There is no function to clear the Digits attribute for an axis - directly, so obtain a pointer to the Axis and use this to clear the - attribute. */ - (void) astValidateAxis( this, axis - 1, 1, "astClearDigits(axis)" ); - ax = astGetAxis( this, axis - 1 ); - astClearAxisDigits( ax ); - ax = astAnnul( ax ); - -/* Direction(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "direction(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearDirection( this, axis - 1 ); - -/* Epoch. */ -/* ------ */ - } else if ( !strcmp( attrib, "epoch" ) ) { - astClearEpoch( this ); - -/* Top(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "top(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearTop( this, axis - 1 ); - -/* Bottom(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "bottom(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearBottom( this, axis - 1 ); - -/* Domain. */ -/* ------- */ - } else if ( !strcmp( attrib, "domain" ) ) { - astClearDomain( this ); - -/* Format(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "format(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearFormat( this, axis - 1 ); - -/* Label(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "label(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLabel( this, axis - 1 ); - -/* MatchEnd. */ -/* --------- */ - } else if ( !strcmp( attrib, "matchend" ) ) { - astClearMatchEnd( this ); - -/* MaxAxes. */ -/* -------- */ - } else if ( !strcmp( attrib, "maxaxes" ) ) { - astClearMaxAxes( this ); - -/* MinAxes. */ -/* -------- */ - } else if ( !strcmp( attrib, "minaxes" ) ) { - astClearMinAxes( this ); - -/* Permute. */ -/* -------- */ - } else if ( !strcmp( attrib, "permute" ) ) { - astClearPermute( this ); - -/* PreserveAxes. */ -/* ------------- */ - } else if ( !strcmp( attrib, "preserveaxes" ) ) { - astClearPreserveAxes( this ); - -/* Symbol(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "symbol(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearSymbol( this, axis - 1 ); - -/* System. */ -/* ------- */ - } else if ( !strcmp( attrib, "system" ) ) { - astClearSystem( this ); - -/* AlignSystem. */ -/* ------------ */ - } else if ( !strcmp( attrib, "alignsystem" ) ) { - astClearAlignSystem( this ); - -/* Title. */ -/* ------ */ - } else if ( !strcmp( attrib, "title" ) ) { - astClearTitle( this ); - -/* Unit(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "unit(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearUnit( this, axis - 1 ); - -/* ObsLat. */ -/* ------- */ - } else if ( !strcmp( attrib, "obslat" ) ) { - astClearObsLat( this ); - -/* ObsLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "obslon" ) ) { - astClearObsLon( this ); - -/* ObsAlt. */ -/* ------- */ - } else if ( !strcmp( attrib, "obsalt" ) ) { - astClearObsAlt( this ); - -/* Dtai */ -/* --- */ - } else if ( !strcmp( attrib, "dtai" ) ) { - astClearDtai( this ); - -/* Dut1 */ -/* --- */ - } else if ( !strcmp( attrib, "dut1" ) ) { - astClearDut1( this ); - -/* Read-only attributes. */ -/* --------------------- */ -/* Test if the attribute name matches any of the read-only attributes - of this class. If it does, then report an error. */ - } else if ( !strcmp( attrib, "naxes" ) || - !strncmp( attrib, "normunit", 8 ) || - !strncmp( attrib, "internalunit", 12 ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Other axis attributes. */ -/* ---------------------- */ -/* If the attribute was not identified above, but appears to refer to - a Frame axis, then it may refer to an Axis object of a derived type - (which has additional attributes not recognised here). */ - } else if( !free_axis_attrib && ( nc = 0, - ( 1 == astSscanf( attrib, "%*[^()]%n(%d)%n", - &axis_nc, &axis, &nc ) ) - && ( nc >= len ) ) ) { - -/* Validate the axis index and extract the attribute name. */ - (void) astValidateAxis( this, axis - 1, 1, "astClear" ); - axis_attrib = astString( attrib, axis_nc ); - -/* Obtain a pointer to the Axis object. */ - ax = astGetAxis( this, axis - 1 ); - if( astOK ) { - -/* Assume that we will be able to use the attribute name. */ - used = 1; - -/* Temporarily switch off error reporting so that if the following attempt - to access the axis attribute fails, we can try to interpret the - attribute name as an attribute of the primary Frame containing the - specified axis. Any errors reported in this context will simply be - ignored, in particularly they are not deferred for later delivery. */ - oldrep = astReporting( 0 ); - -/* Use the Axis astClearAttrib method to clear the attribute value. */ - astClearAttrib( ax, axis_attrib ); - -/* If the above call failed with a status of AST__BADAT, indicating that - the attribute name was not recognised, clear the status so that we can - try to interpret the attribute name as an attribute of the primary Frame - containing the specified axis. */ - if( astStatus == AST__BADAT ) { - astClearStatus; - -/* Find the primary Frame containing the specified axis. */ - astPrimaryFrame( this, axis - 1, &pfrm, &paxis ); - -/* Only attempt to use the primary Frame if it is not the same as "this" - - otherwise we could end up in an infinite loop. */ - if( pfrm != this ) { - -/* astPrimaryFrame returns the original - unpermuted - axis index within - the primary Frame. So we need to take into account any axis permutation - which has been applied to the primary Frame when forming the attribute name - to use below. Find the permuted (external) axis index which corresponds to - the internal (unpermuted) axis index "paxis". */ - paxis = astValidateAxis( pfrm, paxis, 0, "astClear" ); - -/* Modify the attribute name to refer to the axis numbering of the - primary frame. */ - sprintf( pfrm_attrib, "%s(%d)", axis_attrib, paxis + 1 ); - -/* Attempt to clear the attribute as an attribute of the primary Frame. */ - astClearAttrib( pfrm, pfrm_attrib ); - -/* If this failed, clear the status and indicate that we have not managed to - use the attribute name. */ - if( !astOK ) { - astClearStatus; - used = 0; - } - - } else { - used = 0; - } - -/* If not found attempt to clear the attribute value in the Axis, omitting - the axis index. */ - if( ! used ) { - astClearAttrib( pfrm, axis_attrib ); - if( !astOK ) { - astClearStatus; - } else { - used = 1; - } - } - -/* Annul the primary Frame pointer. */ - pfrm = astAnnul( pfrm ); - } - -/* Re-instate the original error reporting state. */ - astReporting( oldrep ); - -/* If we could not use the attribute name, attempt to clear the axis - attribute again, this time retaining the error report. This is done - to ensure the user gets an appropriate error message. */ - if( !used ) astClearAttrib( ax, axis_attrib ); - } - -/* Annul the Axis pointer and free the memory holding the attribute - name. */ - ax = astAnnul( ax ); - axis_attrib = astFree( axis_attrib ); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is still not recognised, and the Frame has only 1 axis, - and the attribute name does not already include an axis specifier, try - again after appending "(1)" to the end of the attribute name. */ - } else if( !has_axis && astGetNaxes( this ) == 1 ) { - -/* Take a copy of the supplied name, allowing 3 extra characters for the - axis specifier "(1)". */ - axis_attrib = astMalloc( len + 4 ); - if( axis_attrib ) memcpy( axis_attrib, attrib, len ); - -/* Indicate we should free the axis_attrib memory. */ - free_axis_attrib = 1; - -/* Add in the axis specifier. */ - strcpy( axis_attrib + len, "(1)" ); - -/* Use the new attribute name instead of the supplied name. */ - old_attrib = attrib; - attrib = axis_attrib; - -/* Indicate the attribute name now has an axis specifier. */ - has_axis = 1; - -/* Jump back to try interpreting the new attribute name. */ - goto L1; - -/* Not recognised. */ -/* --------------- */ -/* If the attribute name is still not recognised, pass it on to the parent - method for further interpretation. First re-instate the original attrib - name string if it was changed above. */ - } else { - if( free_axis_attrib ) { - attrib = old_attrib; - axis_attrib = astFree( axis_attrib ); - } - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearUnit( AstFrame *this, int axis, int *status ) { -/* -* Name: -* ClearUnit - -* Purpose: -* Clear the Unit attribute of a Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void ClearUnit( AstFrame *this, int axis, int *status ) - -* Class Membership: -* Frame method. - -* Description: -* This function clears the Unit value for an axis of a Frame. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which the Unit value is to -* be cleared. -* unit -* The new value to be set. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - const char *units; /* Pointer to units string */ - char *old_units; /* Pointer to copy of original units */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astSetUnit" ); - -/* Do nothing more if the attribute is already cleared. */ - if( astTestUnit( this, axis ) ) { - -/* Obtain a pointer to the required Axis. */ - ax = astGetAxis( this, axis ); - -/* Save a copy of the old units. */ - units = astGetAxisUnit( ax ); - old_units = astStore( NULL, units, strlen( units ) + 1 ); - -/* Clear the Axis Unit attribute value, and then get a pointer to the - new default Units string. */ - astClearAxisUnit( ax ); - units = astGetUnit( this, axis ); - -/* The new unit may require the Label and/or Symbol to be changed, but - only if the Frames ActiveUnit flag is set. */ - if( astGetActiveUnit( this ) ) NewUnit( ax, old_units, units, - "astSetUnit", astGetClass( this ), status ); - -/* Free resources. */ - old_units = astFree( old_units ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - } -} - -static int ConsistentMaxAxes( AstFrame *this, int value, int *status ) { -/* -* Name: -* ConsistentMaxAxes - -* Purpose: -* Ensure a consistent value when setting the MaxAxes attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int ConsistentMaxAxes( AstFrame *this, int value, int *status ) - -* Class Membership: -* Frame member function. - -* Description: -* This function accepts a value which is to be set for a Frame's MaxAxes -* attribute and returns an appropriately adjusted value to be assigned -* to the Frame structure's max_axes component. If necessary, the Frame's -* MinAxes attribute is adjusted to remain consistent with the new MaxAxes -* value (but note that the MaxAxes value itself is not assigned by this -* function). - -* Parameters: -* this -* Pointer to the Frame. -* value -* The new value being set for the MaxAxes attribute. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to be assigned to the max_axes component. - -* Notes: -* - A value of -INT_MAX will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return -INT_MAX; - -/* Ensure that the result value isn't negative. */ - result = ( value >= 0 ) ? value : 0; - -/* Check if the MinAxes attribute is set. If not, its default value will be - consistent with the MaxAxes value (the DefaultMinAxes function ensures - this). Otherwise, obtain its value to check for consistency. */ - if ( astTestMinAxes( this ) ) { - -/* If necessary, set a new MinAxes value to prevent it exceeding the MaxAxes - value about to be returned. */ - if ( astGetMinAxes( this ) > result ) astSetMinAxes( this, result ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -INT_MAX; - -/* Return the result. */ - return result; -} - -static int ConsistentMinAxes( AstFrame *this, int value, int *status ) { -/* -* Name: -* ConsistentMinAxes - -* Purpose: -* Ensure a consistent value when setting the MinAxes attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int ConsistentMinAxes( AstFrame *this, int value, int *status ) - -* Class Membership: -* Frame member function. - -* Description: -* This function accepts a value which is to be set for a Frame's MinAxes -* attribute and returns an appropriately adjusted value to be assigned -* to the Frame structure's min_axes component. If necessary, the Frame's -* MaxAxes attribute is adjusted to remain consistent with the new MinAxes -* value (but note that the MinAxes value itself is not assigned by this -* function). - -* Parameters: -* this -* Pointer to the Frame. -* value -* The new value being set for the MinAxes attribute. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to be assigned to the min_axes component. - -* Notes: -* - A value of -INT_MAX will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return -INT_MAX; - -/* Ensure that the result value isn't negative. */ - result = ( value >= 0 ) ? value : 0; - -/* Check if the MaxAxes attribute is set. If not, its default value will be - consistent with the MinAxes value (the DefaultMaxAxes function ensures - this). Otherwise, obtain its value to check for consistency. */ - if ( astTestMaxAxes( this ) ) { - -/* If necessary, set a new MaxAxes value to prevent it being less than the - MinAxes value about to be returned. */ - if ( astGetMaxAxes( this ) < result ) astSetMaxAxes( this, result ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -INT_MAX; - -/* Return the result. */ - return result; -} - -static AstFrameSet *Convert( AstFrame *from, AstFrame *to, - const char *domainlist, int *status ) { -/* -*++ -* Name: -c astConvert -f AST_CONVERT - -* Purpose: -* Determine how to convert between two coordinate systems. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c AstFrameSet *astConvert( AstFrame *from, AstFrame *to, -c const char *domainlist ) -f RESULT = AST_CONVERT( FROM, TO, DOMAINLIST, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -* This function compares two Frames and determines whether it is -* possible to convert between the coordinate systems which they -* represent. If conversion is possible, it returns a FrameSet -* which describes the conversion and which may be used (as a -* Mapping) to transform coordinate values in either direction. -* -* The same function may also be used to determine how to convert -* between two FrameSets (or between a Frame and a FrameSet, or -* vice versa). This mode is intended for use when (for example) -* two images have been calibrated by attaching a FrameSet to each. -c astConvert might then be used to search for a -f AST_CONVERT might then be used to search for a -* celestial coordinate system that both images have in common, and -* the result could then be used to convert between the pixel -* coordinates of both images -- having effectively used their -* celestial coordinate systems to align them. -* -* When using FrameSets, there may be more than one possible -* intermediate coordinate system in which to perform the -* conversion (for instance, two FrameSets might both have -* celestial coordinates, detector coordinates, pixel coordinates, -* etc.). A comma-separated list of coordinate system domains may -* therefore be given which defines a priority order to use when -* selecting the intermediate coordinate system. The path used for -* conversion must go via an intermediate coordinate system whose -* Domain attribute matches one of the domains given. If conversion -* cannot be achieved using the first domain, the next one is -* considered, and so on, until success is achieved. - -* Parameters: -c from -f FROM = INTEGER (Given) -* Pointer to a Frame which represents the "source" coordinate -* system. This is the coordinate system in which you already -* have coordinates available. -* -* If a FrameSet is given, its current Frame (as determined by -* its Current attribute) is taken to describe the source -* coordinate system. Note that the Base attribute of this -* FrameSet may be modified by this function to indicate which -* intermediate coordinate system was used (see under -* "FrameSets" in the "Applicability" section for details). -c to -f TO = INTEGER (Given) -* Pointer to a Frame which represents the "destination" -* coordinate system. This is the coordinate system into which -* you wish to convert your coordinates. -* -* If a FrameSet is given, its current Frame (as determined by -* its Current attribute) is taken to describe the destination -* coordinate system. Note that the Base attribute of this -* FrameSet may be modified by this function to indicate which -* intermediate coordinate system was used (see under -* "FrameSets" in the "Applicability" section for details). -c domainlist -f DOMAINLIST = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing a -f A character string containing a -* comma-separated list of Frame domains. This may be used to -* define a priority order for the different intermediate -* coordinate systems that might be used to perform the -* conversion. -* -* The function will first try to obtain a conversion by making -* use only of an intermediate coordinate system whose Domain -* attribute matches the first domain in this list. If this -* fails, the second domain in the list will be used, and so on, -* until conversion is achieved. A blank domain (e.g. two -* consecutive commas) indicates that all coordinate systems -* should be considered, regardless of their domains. -* -* This list is case-insensitive and all white space is ignored. -* If you do not wish to restrict the domain in this way, -c you should supply an empty string. This is normally -f you should supply a blank string. This is normally -* appropriate if either of the source or destination coordinate -* systems are described by Frames (rather than FrameSets), -* since there is then usually only one possible choice of -* intermediate coordinate system. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astConvert() -f AST_CONVERT = INTEGER -* If the requested coordinate conversion is possible, the -* function returns a pointer to a FrameSet which describes the -* conversion. Otherwise, a null Object pointer (AST__NULL) is -* returned without error. -* -* If a FrameSet is returned, it will contain two Frames. Frame -* number 1 (its base Frame) will describe the source coordinate -c system, corresponding to the "from" parameter. Frame number 2 -f system, corresponding to the FROM argument. Frame number 2 -* (its current Frame) will describe the destination coordinate -c system, corresponding to the "to" parameter. The Mapping -f system, corresponding to the TO argument. The Mapping -* which inter-relates these two Frames will perform the -* required conversion between their respective coordinate -* systems. -* -* Note that a FrameSet may be used both as a Mapping and as a -* Frame. If the result is used as a Mapping (e.g. with -c astTran2), then it provides a means of converting coordinates -f AST_TRAN2), then it provides a means of converting coordinates -* from the source to the destination coordinate system (or -* vice versa if its inverse transformation is selected). If it -* is used as a Frame, its attributes will describe the -* destination coordinate system. - -* Applicability: -* DSBSpecFrame -* If the AlignSideBand attribute is non-zero, alignment occurs in the -* upper sideband expressed within the spectral system and standard of -* rest given by attributes AlignSystem and AlignStdOfRest. If -* AlignSideBand is zero, the two DSBSpecFrames are aligned as if -* they were simple SpecFrames (i.e. the SideBand is ignored). -* Frame -* This function applies to all Frames. Alignment occurs within the -* coordinate system given by attribute AlignSystem. -* FrameSet -c If either of the "from" or "to" parameters is a pointer to a -f If either of the FROM or TO arguments is a pointer to a -c FrameSet, then astConvert will attempt to convert from the -f FrameSet, then AST_CONVERT will attempt to convert from the -c coordinate system described by the current Frame of the "from" -f coordinate system described by the current Frame of the FROM -c FrameSet to that described by the current Frame of the "to" -f FrameSet to that described by the current Frame of the TO -* FrameSet. -* -* To achieve this, it will consider all of the Frames within -* each FrameSet as a possible way of reaching an intermediate -* coordinate system that can be used for the conversion. There -* is then the possibility that more than one conversion path -* may exist and, unless the choice is sufficiently restricted -c by the "domainlist" string, the sequence in which the Frames -f by the DOMAINLIST string, the sequence in which the Frames -* are considered can be important. In this case, the search -* for a conversion path proceeds as follows: -c - Each field in the "domainlist" string is considered in turn. -f - Each field in the DOMAINLIST string is considered in turn. -* - The Frames within each FrameSet are considered in a -* specific order: (1) the base Frame is always considered -* first, (2) after this come all the other Frames in -* Frame-index order (but omitting the base and current Frames), -* (3) the current Frame is always considered last. However, if -* either FrameSet's Invert attribute is set to a non-zero value -* (so that the FrameSet is inverted), then its Frames are -* considered in reverse order. (Note that this still means that -* the base Frame is considered first and the current Frame -* last, because the Invert value will also cause these Frames -* to swap places.) -* - All source Frames are first considered (in the appropriate -* order) for conversion to the first destination Frame. If no -* suitable intermediate coordinate system emerges, they are -* then considered again for conversion to the second -* destination Frame (in the appropriate order), and so on. -* - Generally, the first suitable intermediate coordinate -* system found is used. However, the overall Mapping between -* the source and destination coordinate systems is also -* examined. Preference is given to cases where both the -* forward and inverse transformations are defined (as indicated -* by the TranForward and TranInverse attributes). If only one -* transformation is defined, the forward one is preferred. -* - If the domain of the intermediate coordinate system matches -c the current "domainlist" field, the conversion path is -f the current DOMAINLIST field, the conversion path is -c accepted. Otherwise, the next "domainlist" field is considered -f accepted. Otherwise, the next DOMAINLIST field is considered -* and the process repeated. -* -* If conversion is possible, the Base attributes of the two -* FrameSets will be modified on exit to identify the Frames -* used to access the intermediate coordinate system which was -* finally accepted. -* -* Note that it is possible to force a particular Frame within a -* FrameSet to be used as the basis for the intermediate -* coordinate system, if it is suitable, by (a) focussing -* attention on -c it by specifying its domain in the "domainlist" string, or (b) -f it by specifying its domain in the DOMAINLIST string, or (b) -* making it the base Frame, since this is always considered -* first. -* SpecFrame -* Alignment occurs within the spectral system and standard of rest -* given by attributes AlignSystem and AlignStdOfRest. -* TimeFrame -* Alignment occurs within the time system and time scale given by -* attributes AlignSystem and AlignTimeScale. - -* Examples: -c cvt = astConvert( a, b, "" ); -f CVT = AST_CONVERT( A, B, ' ', STATUS ) -* Attempts to convert between the coordinate systems represented -c by "a" and "b" (assumed to be Frames). If successful, a FrameSet -f by A and B (assumed to be Frames). If successful, a FrameSet -c is returned via the "cvt" pointer which may be used to apply the -f is returned via the CVT pointer which may be used to apply the -c conversion to sets of coordinates (e.g. using astTran2). -f conversion to sets of coordinates (e.g. using AST_TRAN2). -c cvt = astConvert( astSkyFrame(""), astSkyFrame("Equinox=2005"), "" ); -f CVT = AST_CONVERT( AST_SKYFRAME( ' ', STATUS ), AST_SKYFRAME( 'Equinox=2005', STATUS ), ' ', STATUS ) -* Creates a FrameSet which describes precession in the default -* FK5 celestial coordinate system between equinoxes J2000 (also -c the default) and J2005. The returned "cvt" pointer may then -f the default) and J2005. The returned CVT pointer may then -c be passed to astTran2 to apply this precession correction to -f be passed to AST_TRAN2 to apply this precession correction to -* any number of coordinate values given in radians. -* -* Note that the returned FrameSet also contains information -* about how to format coordinate values. This means that -* setting its Report attribute to 1 is a simple way to obtain -* printed output (formatted in sexagesimal notation) to show -* the coordinate values before and after conversion. -c cvt = astConvert( a, b, "sky,detector," ); -f CVT = AST_CONVERT( A, B, 'SKY,DETECTOR,', STATUS ) -* Attempts to convert between the coordinate systems -c represented by the current Frames of "a" and "b" -f represented by the current Frames of A and B -* (now assumed to be FrameSets), via the intermediate "SKY" -* coordinate system. This, by default, is the Domain -* associated with a celestial coordinate system represented by -* a SkyFrame. -* -* If this fails (for example, because either FrameSet lacks -* celestial coordinate information), then the user-defined -* "DETECTOR" coordinate system is used instead. If this also -* fails, then all other possible ways of achieving conversion -* are considered before giving up. -* -c The returned pointer "cvt" indicates whether conversion was -f The returned pointer CVT indicates whether conversion was -* possible and will have the value AST__NULL if it was not. If -c conversion was possible, "cvt" will point at a new FrameSet -f conversion was possible, CVT will point at a new FrameSet -* describing the conversion. -* -* The Base attributes of the two FrameSets -c will be set by astConvert to indicate which of their Frames was -f will be set by AST_CONVERT to indicate which of their Frames was -* used for the intermediate coordinate system. This means that -* you can subsequently determine which coordinate system was -* used by enquiring the Domain attribute of either base Frame. - -* Notes: -* - The Mapping represented by the returned FrameSet results in -* alignment taking place in the coordinate system specified by the -c AlignSystem attribute of the "to" Frame. See the description of the -f AlignSystem attribute of the TO Frame. See the description of the -* AlignSystem attribute for further details. -* - When aligning (say) two images, which have been calibrated by -* attaching FrameSets to them, it is usually necessary to convert -* between the base Frames (representing "native" pixel -* coordinates) of both FrameSets. This may be achieved by -* inverting the FrameSets (e.g. using astInvert) so as to -* interchange their base and current Frames before using -* astConvert. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* This function is simply a wrap-up for the protected astConvertX -* method which performs the required processing but swaps the order -* of the first two arguments. This is a trick to allow the -* astConvert method to be over-ridden by derived classes on the -* basis of the class of either of the first two arguments. -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Invoke the "astConvertX" method with the first two arguments - swapped. */ - return astConvertX( to, from, domainlist ); -} - -static AstFrameSet *ConvertX( AstFrame *to, AstFrame *from, - const char *domainlist, int *status ) { -/* -*+ -* Name: -* astConvertX - -* Purpose: -* Determine how to convert between two coordinate systems. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* AstFrameSet *astConvertX( AstFrame *to, AstFrame *from, -* const char *domainlist ) - -* Class Membership: -* Frame method. - -* Description: -* This function performs the processing for the public astConvert -* method and has exactly the same interface except that the order -* of the first two arguments is swapped. This is a trick to allow -* the astConvert method to be over-ridden by derived classes on -* the basis of the class of either of its first two arguments. -* -* See the astConvert method for details of the interface. -*- - -* Implementation Deficiencies: -* - This function's job is basically to negotiate with two Frames -* to try and find a mutually agreeable coordinate system for -* conversion. Ideally, it should be able to juggle the number of -* axes, etc. to do this. At present, however, the implementation -* is much simpler. This is adequate for the Frame classes which -* exist at the time of writing, but the implementation may need -* beefing up in future. -* - One likely problem is with attributes which default in both -* the source and destination Frames. This means they also default -* in the common coordinate system. If these default values were to -* differ when matching different target Frames, however, we would -* be in trouble, because the common coordinate system would not -* then be remaining constant. The longer-term solution to this is -* probably to provide some mechanism to "fix" all attribute values -* for a Frame, by taking any attributes that are un-set and -* explicitly setting a firm value (equal to the default) so they -* cannot then change. -*/ - -/* Local Variables: */ - AstFrameSet *result; /* Pointer to Mapping to be returned */ - AstFrame *ftmp; /* Pointer to returned Frame */ - AstMapping **map1_address; /* Location of first Mapping pointer */ - AstMapping **map2_address; /* Location of second Mapping pointer */ - AstMapping *common0; /* Initial common coordinate system */ - AstMapping *common1; /* Improved common coordinate system */ - AstMapping *common2; /* Final common coordinate system */ - AstMapping *frame1; /* Pointer to Frame for first match */ - AstMapping *frame2; /* Pointer to Frame for second match */ - AstMapping *from_map; /* Pointer to "from" Mapping */ - AstMapping *map; /* Pointer to conversion Mapping */ - AstMapping *result_map; /* Pointer to result Mapping */ - AstMapping *tmp; /* Temporary Mapping pointer */ - AstMapping *to_map; /* Pointer to "to" Mapping */ - char *domain; /* Pointer to result domain */ - char *domain_end; /* Pointer to null at end of domain */ - char *domainlist_copy; /* Pointer to copy of domainlist */ - int *axes1; /* Pointer to axis assignments */ - int *axes2; /* Pointer to axis assignments */ - int best_score; /* Score assigned to best match */ - int icom; /* Common coordinate system loop counter */ - int match1; /* First match succeeded? */ - int match2; /* Second match succeeded? */ - int match; /* Overall match found? */ - int perfect; /* Perfect match found? */ - int score; /* Score assigned to match */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialisation. */ - result_map = NULL; - -/* Make a temporary copy of the domains list. */ - domainlist_copy = astStore( NULL, domainlist, - strlen( domainlist ) + (size_t) 1 ); - if ( astOK ) { - -/* Loop to inspect each comma-separated field in the domains list - until an error occurs, all the domains are used up, or a match is - found. */ - domain = domainlist_copy; - match = 0; - while ( astOK && domain && !match ) { - -/* Change the comma at the end of each field to a null to terminate - the domain. Then convert the domain to upper case and eliminate - white space. */ - if ( ( domain_end = strchr( domain, ',' ) ) ) *domain_end = '\0'; - CleanDomain( domain, status ); - -/* For any given domain, we will ignore imperfect matches in favour of - better ones by assigning a score to each match. Initialise the best - score value for the current domain. */ - best_score = -1; - -/* Loop to consider both the "to" and "from" Frames in turn as the - basis of a possible common coordinate system. Quit looping early if - an error occurs or a perfect match is found. */ - perfect = 0; - for ( icom = 0; astOK && !perfect && ( icom <= 1 ); icom++ ) { - -/* Make a copy of the Frame representing the initial guess at a common - coordinate system. We will use this to probe the other - Frame. Ensure that axes are not preserved (so that we convert to - the common axis number/order). */ - common0 = astCopy( icom ? from : to ); - astSetPreserveAxes( common0, 0 ); - -/* Also, if the current domain is not blank, set the Domain attribute (so - we will only find coordinate systems which match the current - "domainlist" field). */ - if ( *domain ) astSetDomain( common0, domain ); - -/* Obtain a pointer to the other Frame. */ - frame1 = astClone( icom ? to : from ); - -/* Set the address at which to store the resulting Mapping pointer. */ - map1_address = icom ? &to_map : &from_map; - -/* See if conversion from "frame1" to the common coordinate system is - possible. If successful, this results in a new approximation - ("common1") to the possible common coordinate system. */ - match1 = astMatch( common0, frame1, 1, &axes1, &axes2, - map1_address, &ftmp ); - common1 = (AstMapping *) ftmp; - -/* If successful, free memory allocated for the axis association - arrays, which are not needed. */ - if ( astOK && match1 ) { - axes1 = astFree( axes1 ); - axes2 = astFree( axes2 ); - -/* Using the improved approximation to the common coordinate system, - now test if conversion from the alternative Frame "frame2" is - possible. */ - frame2 = astClone( icom ? from : to ); - map2_address = icom ? &from_map : &to_map; - astSetPreserveAxes( common1, 0 ); - match2 = astMatch( common1, frame2, 1, &axes1, &axes2, - map2_address, &ftmp ); - common2 = (AstMapping *) ftmp; - -/* If successful, free memory allocated for the axis association - arrays, which are not needed. */ - if ( astOK && match2 ) { - axes1 = astFree( axes1 ); - axes2 = astFree( axes2 ); - -/* Invert the "to" Mapping and concatenate the two Mappings to - describe the conversion between the "from" and "to" Frames. Then - simplify the result. */ - astInvert( to_map ); - tmp = (AstMapping *) astCmpMap( from_map, to_map, 1, "", status ); - map = astSimplify( tmp ); - tmp = astAnnul( tmp ); - -/* Assign a score that favours Mappings with both transformations - available over those with only one, and Mappings with only a - forward transformation over those with only an inverse - transformation. */ - score = ( astGetTranForward( map ) ? 2 : 0 ) + - ( astGetTranInverse( map ) ? 1 : 0 ); - -/* If the new score is better than the previous one (or is the first - one), note that we have a possible match. */ - if ( astOK && ( score > best_score ) ) { - match = 1; - -/* Update the best score and note if it indicates a perfect match (in - which case we can stop searching at this point). */ - best_score = score; - perfect = ( best_score >= 3 ); - -/* Annul any previous result Mapping pointer and replace it with this - better one. */ - if ( result_map ) result_map = astAnnul( result_map ); - result_map = astClone( map ); - } - -/* Annul pointers to all the intermediate Objects. */ - map = astAnnul( map ); - common2 = astAnnul( common2 ); - *map2_address = astAnnul( *map2_address ); - } - frame2 = astAnnul( frame2 ); - common1 = astAnnul( common1 ); - *map1_address = astAnnul( *map1_address ); - } - frame1 = astAnnul( frame1 ); - common0 = astAnnul( common0 ); - } - -/* Go on to consider the next field in the domains list. */ - domain = domain_end ? domain_end + 1 : NULL; - } - } - -/* Free the domain list copy. */ - domainlist_copy = astFree( domainlist_copy ); - -/* If returning a result, build the result FrameSet. Then annul the - result Mapping pointer. */ - if ( result_map ) { - result = astFrameSet( from, "", status ); - astAddFrame( result, AST__BASE, result_map, to ); - result_map = astAnnul( result_map ); - } - -/* If an error occurred, annul the result FrameSet pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int DefaultMaxAxes( AstFrame *this, int *status ) { -/* -* Name: -* DefaultMaxAxes - -* Purpose: -* Obtain the MaxAxes attribute from a Frame structure, with defaulting. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int DefaultMaxAxes( AstFrame *this, int *status ) - -* Class Membership: -* Frame member function. - -* Description: -* This function inspects the max_axes component of a Frame structure and -* derives a value for the MaxAxes attribute. If the component's value -* indicates that the attribute has not been set, a suitable default is -* returned which is consistent with the state of the Frames's MinAxes -* attribute. - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to be used for the MaxAxes attribute. -*/ - -/* Local Variables. */ - int result; /* Result to be returned */ - int min_axes; /* Value of MinAxes attribute */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* If the Frame's max_axes component is set, return its value. */ - if ( this->max_axes != -INT_MAX ) { - result = this->max_axes; - -/* Otherwise, the preferred default value is the number of Frame axes. */ - } else { - result = astGetNaxes( this ); - -/* Before returning this value, check if the MinAxes attribute is set. If it - is, obtain its value. */ - if ( astTestMinAxes( this ) ) { - min_axes = astGetMinAxes( this ); - -/* If necessary, increase the MaxAxes default value so that it is not less than - MinAxes. */ - if ( result < min_axes ) result = min_axes; - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int DefaultMinAxes( AstFrame *this, int *status ) { -/* -* Name: -* DefaultMinAxes - -* Purpose: -* Obtain the MinAxes attribute from a Frame structure, with defaulting. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int DefaultMinAxes( AstFrame *this, int *status ) - -* Class Membership: -* Frame member function. - -* Description: -* This function inspects the min_axes component of a Frame structure and -* derives a value for the MinAxes attribute. If the component's value -* indicates that the attribute has not been set, a suitable default is -* returned which is consistent with the state of the Frames's MaxAxes -* attribute. - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to be used for the MinAxes attribute. -*/ - -/* Local Variables: */ - int result; /* Result to be returned */ - int max_axes; /* Value of MaxAxes attribute */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* If the Frame's min_axes component is set, return its value. */ - if ( this->min_axes != -INT_MAX ) { - result = this->min_axes; - -/* Otherwise, the preferred default value is the number of Frame axes. */ - } else { - result = astGetNaxes( this ); - -/* Before returning this value, check if the MaxAxes attribute is set. If it - is, obtain its value. */ - if ( astTestMaxAxes( this ) ) { - max_axes = astGetMaxAxes( this ); - -/* If necessary, reduce the MinAxes default value so that it does not exceed - MaxAxes. */ - if ( result > max_axes ) result = max_axes; - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static double Distance( AstFrame *this, - const double point1[], const double point2[], int *status ) { -/* -*++ -* Name: -c astDistance -f AST_DISTANCE - -* Purpose: -* Calculate the distance between two points in a Frame. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c double astDistance( AstFrame *this, -c const double point1[], const double point2[] ) -f RESULT = AST_DISTANCE( THIS, POINT1, POINT2, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -* This function finds the distance between two points whose Frame -* coordinates are given. The distance calculated is that along -* the geodesic curve that joins the two points. -* -* For example, in a basic Frame, the distance calculated will be -* the Cartesian distance along the straight line joining the two -* points. For a more specialised Frame describing a sky coordinate -* system, however, it would be the distance along the great circle -* passing through two sky positions. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c point1 -f POINT1( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the first point. -c point2 -f POINT2( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* containing the coordinates of the second point. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astDistance -f AST_DISTANCE = DOUBLE PRECISION -* The distance between the two points. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input coordinates has this value. -* - A "bad" value will also be returned if this function is -c invoked with the AST error status set, or if it should fail for -f invoked with STATUS set to an error value, or if it should fail for -* any reason. -*-- -*/ - -/* Local Variables: */ - double delta; /* Separation along an axis */ - double result; /* Result value to return */ - int axis; /* Loop counter for axes */ - int naxes; /* Number of Frame axes */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain the number of Frame axes. */ - naxes = astGetNaxes( this ); - if ( astOK ) { - -/* Loop to determine the Cartesian distance between the points. */ - result = 0.0; - for ( axis = 0; axis < naxes; axis++ ) { - -/* If any of the coordinates supplied is bad, set the distance to be - bad and quit looping. */ - if ( ( point1[ axis ] == AST__BAD ) || - ( point2[ axis ] == AST__BAD ) ) { - result = AST__BAD; - break; - -/* Otherwise, accumulate the sum of squared separations along each - axis. */ - } else { - delta = point1[ axis ] - point2[ axis ]; - result += ( delta * delta ); - } - } - -/* Take the square root to find the distance (if valid). */ - if ( result != AST__BAD ) result = sqrt( result ); - } - -/* Return the result. */ - return result; -} - -static int DoNotSimplify( AstMapping *this, int *status ) { -/* -* Name: -* DoNotSimplify - -* Purpose: -* Check if a Mapping is appropriate for simplification. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* int DoNotSImplify( AstMapping *this ); - -* Class Membership: -* CmpMap member function (over-rides the astDoNotSimplify protected -* method inherited from the parent class). - -* Description: -* This function returns a flag indivating if the supplied Mapping is -* appropriate for simplification. - -* Parameters: -* this -* Pointer to the Mapping. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the supplied Mapping is not appropriate for -* simplification, and zero otherwise. - -* Notes: -* - A value of 0 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. - -*/ - -/* Unlike basic Mappings, Frames that have a set value for the Ident - can be simplified. So always return zero. */ - return 0; -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two Frames are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* Frame member function (over-rides the astEqual protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two Frames are equivalent. - -* Parameters: -* this -* Pointer to the first Frame. -* that -* Pointer to the second Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the Frames are equivalent, zero otherwise. - -* Notes: -* - The two Frames are considered equivalent if the Mapping between -* them is a UnitMap. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *that; /* Pointer to the second Frame structure */ - AstFrame *this; /* Pointer to the first Frame structure */ - AstFrameSet *fs; /* FrameSet connecting the two Frames */ - AstMapping *map1; /* Mapping connecting the two Frames */ - AstMapping *map2; /* Simplified mapping connecting two Frames */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Checks that the second object is of the same class as the first . */ - if( !strcmp( astGetClass( this_object ), astGetClass( that_object ) ) ){ - -/* Obtain pointers to the two Frame structures. */ - this = (AstFrame *) this_object; - that = (AstFrame *) that_object; - -/* Get the Mapping between them, and see if it is a UnitMap. */ - fs = astConvert( that, this, "" ); - if( fs ) { - map1 = astGetMapping( fs, AST__BASE, AST__CURRENT ); - map2 = astSimplify( map1 ); - result = astIsAUnitMap( map2 ); - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - fs = astAnnul( fs ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int Fields( AstFrame *this, int axis, const char *fmt, - const char *str, int maxfld, char **fields, - int *nc, double *val, int *status ) { -/* -*+ -* Name: -* astFields - -* Purpose: -* Identify numerical fields within a formatted Axis value. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astFields( AstFrame *this, int axis, const char *fmt, -* const char *str, int maxfld, char **fields, -* int *nc, double *val ) - -* Class Membership: -* Frame method. - -* Description: -* This function identifies the numerical fields within a Frame axis -* value that has been formatted using astAxisFormat. It assumes that -* the value was formatted using the supplied format string. It also -* returns the equivalent floating point value. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the Frame axis for which the values have been -* formatted (axis numbering starts at zero for the first axis). -* fmt -* Pointer to a constant null-terminated string containing the -* format used when creating "str". -* str -* Pointer to a constant null-terminated string containing the -* formatted value. -* maxfld -* The maximum number of fields to identify within "str". -* fields -* A pointer to an array of at least "maxfld" character pointers. -* Each element is returned holding a pointer to the start of the -* corresponding field in "str" (in the order in which they occur -* within "str"), or NULL if no corresponding field can be found. -* nc -* A pointer to an array of at least "maxfld" integers. Each -* element is returned holding the number of characters in the -* corresponding field, or zero if no corresponding field can be -* found. -* val -* Pointer to a location at which to store the value -* equivalent to the returned field values. If this is NULL, -* it is ignored. - -* Returned Value: -* The number of fields succesfully identified and returned. - -* Notes: -* - Leading and trailing spaces are ignored. -* - If the formatted value is not consistent with the supplied format -* string, then a value of zero will be returned, "fields" will be -* returned holding NULLs, "nc" will be returned holding zeros, and -* "val" is returned holding VAL__BAD. -* - Fields are counted from the start of the formatted string. If the -* string contains more than "maxfld" fields, then trailing fields are -* ignored. -* - If this function is invoked with the global error status set, or -* if it should fail for any reason, then a value of zero will be returned -* as the function value, and "fields", "nc" and "val" will be returned -* holding their supplied values -*- -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - int result; /* Result field count to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate the axis index and obtain a pointer to the required - Axis. */ - (void) astValidateAxis( this, axis, 1, "astFields" ); - ax = astGetAxis( this, axis ); - -/* Invoke the Axis astAxisFields method to perform the processing. */ - result = astAxisFields( ax, fmt, str, maxfld, fields, nc, val ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static AstFrameSet *FindFrame( AstFrame *target, AstFrame *template, - const char *domainlist, int *status ) { -/* -*++ -* Name: -c astFindFrame -f AST_FINDFRAME - -* Purpose: -* Find a coordinate system with specified characteristics. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c AstFrameSet *astFindFrame( AstFrame *target, AstFrame *template, -c const char *domainlist ) -f RESULT = AST_FINDFRAME( TARGET, TEMPLATE, DOMAINLIST, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -* This function uses a "template" Frame to search another Frame -* (or FrameSet) to identify a coordinate system which has a -* specified set of characteristics. If a suitable coordinate -* system can be found, the function returns a pointer to a -* FrameSet which describes the required coordinate system and how -* to convert coordinates to and from it. -* -* This function is provided to help answer general questions about -* coordinate systems, such as typically arise when coordinate -* information is imported into a program as part of an initially -* unknown dataset. For example: -* - Is there a wavelength scale? -* - Is there a 2-dimensional coordinate system? -* - Is there a celestial coordinate system? -* - Can I plot the data in ecliptic coordinates? -* -* You can also use this function as a means of reconciling a -* user's preference for a particular coordinate system (for -* example, what type of axes to draw) with what is actually -* possible given the coordinate information available. -* -* To perform a search, you supply a "target" Frame (or FrameSet) -* which represents the set of coordinate systems to be searched. -* If a basic Frame is given as the target, this set of coordinate -* systems consists of the one described by this Frame, plus all -* other "virtual" coordinate systems which can potentially be -* reached from it by applying built-in conversions (for example, -* any of the celestial coordinate conversions known to the AST -* library would constitute a "built-in" conversion). If a FrameSet -* is given as the target, the set of coordinate systems to be -* searched consists of the union of those represented by all the -* individual Frames within it. -* -* To select from this large set of possible coordinate systems, -* you supply a "template" Frame which is an instance of the type -* of Frame you are looking for. Effectively, you then ask the -* function to "find a coordinate system that looks like this". -* -* You can make your request more or less specific by setting -* attribute values for the template Frame. If a particular -* attribute is set in the template, then the function will only -* find coordinate systems which have exactly the same value for -* that attribute. If you leave a template attribute un-set, -* however, then the function has discretion about the value the -* attribute should have in any coordinate system it finds. The -* attribute will then take its value from one of the actual -* (rather than virtual) coordinate systems in the target. If the -* target is a FrameSet, its Current attribute will be modified to -* indicate which of its Frames was used for this purpose. -* -* The result of this process is a coordinate system represented by -* a hybrid Frame which acquires some attributes from the template -* (but only if they were set) and the remainder from the -* target. This represents the "best compromise" between what you -* asked for and what was available. A Mapping is then generated -* which converts from the target coordinate system to this hybrid -* one, and the returned FrameSet encapsulates all of this -* information. - -* Parameters: -c target -f TARGET = INTEGER (Given) -* Pointer to the target Frame (or FrameSet). -* -* Note that if a FrameSet is supplied (and a suitable -* coordinate system is found), then its Current attribute will -* be modified to indicate which Frame was used to obtain -* attribute values which were not specified by the template. -* This Frame will, in some sense, represent the "closest" -* non-virtual coordinate system to the one you requested. -c template -f TEMPLATE = INTEGER (Given) -* Pointer to the template Frame, which should be an instance of -* the type of Frame you wish to find. If you wanted to find a -* Frame describing a celestial coordinate system, for example, -* then you might use a SkyFrame here. See the "Examples" -* section for more ideas. -c domainlist -f DOMAINLIST = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing a -f A character string containing a -* comma-separated list of Frame domains. This may be used to -* establish a priority order for the different types of -* coordinate system that might be found. -* -* The function will first try to find a suitable coordinate -* system whose Domain attribute equals the first domain in this -* list. If this fails, the second domain in the list will be -* used, and so on, until a result is obtained. A blank domain -* (e.g. two consecutive commas) indicates that any coordinate -* system is acceptable (subject to the template) regardless of -* its domain. -* -* This list is case-insensitive and all white space is ignored. -* If you do not wish to restrict the domain in this way, -c you should supply an empty string. -f you should supply a blank string. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astFindFrame() -f AST_FINDFRAME = INTEGER -* If the search is successful, the function returns a pointer -* to a FrameSet which contains the Frame found and a -* description of how to convert to (and from) the coordinate -* system it represents. Otherwise, a null Object pointer -* (AST__NULL) is returned without error. -* -* If a FrameSet is returned, it will contain two Frames. Frame -* number 1 (its base Frame) represents the target coordinate -* system and will be the same as the (base Frame of the) -* target. Frame number 2 (its current Frame) will be a Frame -* representing the coordinate system which the function -* found. The Mapping which inter-relates these two Frames will -* describe how to convert between their respective coordinate -* systems. -* -* Note that a FrameSet may be used both as a Mapping and as a -* Frame. If the result is used as a Mapping (e.g. with -* astTran2), then it provides a means of converting coordinates -* from the target coordinate system into the new coordinate -* system that was found (and vice versa if its inverse -* transformation is selected). If it is used as a Frame, its -* attributes will describe the new coordinate system. - -* Applicability: -* Frame -* This function applies to all Frames. -* FrameSet -* If the target is a FrameSet, the possibility exists that -* several of the Frames within it might be matched by the -* template. Unless the choice is sufficiently restricted by -c the "domainlist" string, the sequence in which Frames are -f the DOMAINLIST string, the sequence in which Frames are -* searched can then become important. In this case, the search -* proceeds as follows: -c - Each field in the "domainlist" string is considered in turn. -f - Each field in the DOMAINLIST string is considered in turn. -* - An attempt is made to match the template to each of the -* target's Frames in the order: (1) the current Frame, (2) the -* base Frame, (3) each remaining Frame in the order of being -* added to the target FrameSet. -* - Generally, the first match found is used. However, the -* Mapping between the target coordinate system and the -* resulting Frame is also examined. Preference is given to -* cases where both the forward and inverse transformations are -* defined (as indicated by the TranForward and TranInverse -* attributes). If only one transformation is defined, the -* forward one is preferred. -* - If a match is found and the domain of the resulting Frame also -c matches the current "domainlist" field, it is -f matches the current DOMAINLIST field, it is -c accepted. Otherwise, the next "domainlist" field is considered -f accepted. Otherwise, the next DOMAINLIST field is considered -* and the process repeated. -* -* If a suitable coordinate system is found, the Current -* attribute of the target FrameSet will be modified on exit to -* identify the Frame whose match with the target was eventually -* accepted. - -* Examples: -c result = astFindFrame( target, astFrame( 3, "" ), "" ); -f RESULT = AST_FINDFRAME( TARGET, AST_FRAME( 3, ' ', STATUS ), ' ', STATUS ) -* Searches for a 3-dimensional coordinate system in the target -* Frame (or FrameSet). No attributes have been set in the -c template Frame (created by astFrame), so no restriction has -f template Frame (created by AST_FRAME), so no restriction has -* been placed on the required coordinate system, other than -* that it should have 3 dimensions. The first suitable Frame -c found will be returned as part of the "result" FrameSet. -f found will be returned as part of the RESULT FrameSet. -c result = astFindFrame( target, astSkyFrame( "" ), "" ); -f RESULT = AST_FINDFRAME( TARGET, AST_SKYFRAME( ' ', STATUS ), ' ', STATUS ) -* Searches for a celestial coordinate system in the target -* Frame (or FrameSet). The type of celestial coordinate system -c is unspecified, so astFindFrame will return the first one -f is unspecified, so AST_FINDFRAME will return the first one -c found as part of the "result" FrameSet. If the target is -f found as part of the RESULT FrameSet. If the target is -* a FrameSet, then its Current attribute will be updated to -* identify the Frame that was used. -* -* If no celestial coordinate system can be found, a value of -* AST__NULL will be returned without error. -c result = astFindFrame( target, astSkyFrame( "MaxAxes=100" ), "" ); -f RESULT = AST_FINDFRAME( TARGET, AST_SKYFRAME( 'MaxAxes=100', STATUS ), ' ', STATUS ) -* This is like the last example, except that in the event of the -* target being a CmpFrame, the component Frames encapsulated by the -* CmpFrame will be searched for a SkyFrame. If found, the returned -* Mapping will included a PermMap which selects the required axes -* from the target CmpFrame. -* -* This is acomplished by setting the MaxAxes attribute of the -* template SkyFrame to a large number (larger than or equal to the -* number of axes in the target CmpFrame). This allows the SkyFrame -* to be used as a match for Frames containing from 2 to 100 axes. -c result = astFindFrame( target, astSkyFrame( "System=FK5" ), "" ); -f RESULT = AST_FINDFRAME( TARGET, AST_SKYFRAME( 'System=FK5', STATUS ), ' ', STATUS ) -* Searches for an equatorial (FK5) coordinate system in the -* target. The Equinox value for the coordinate system has not -* been specified, so will be obtained from the target. If the -* target is a FrameSet, its Current attribute will be updated -* to indicate which SkyFrame was used to obtain this value. -c result = astFindFrame( target, astFrame( 2, "" ), "sky,pixel," ); -f RESULT = AST_FINDFRAME( TARGET, AST_FRAME( 2, ' ', STATUS ), 'SKY,PIXEL,', STATUS ) -* Searches for a 2-dimensional coordinate system in the -* target. Initially, a search is made for a suitable coordinate -* system whose Domain attribute has the value "SKY". If this -* search fails, a search is then made for one with the domain -* "PIXEL". If this also fails, then any 2-dimensional -c coordinate system is returned as part of the "result" -f coordinate system is returned as part of the RESULT -* FrameSet. -* -* Only if no 2-dimensional coordinate systems can be reached by -* applying built-in conversions to any of the Frames in the -* target will a value of AST__NULL be returned. -c result = astFindFrame( target, astFrame( 1, "Domain=WAVELENGTH" ), "" ); -f RESULT = AST_FINDFRAME( TARGET, AST_FRAME( 1, 'Domain=WAVELENGTH', STATUS ), ' ', STATUS ) -* Searches for any 1-dimensional coordinate system in the -* target which has the domain "WAVELENGTH". -c result = astFindFrame( target, astFrame( 1, "" ), "wavelength" ); -f RESULT = AST_FINDFRAME( TARGET, AST_FRAME( 1, ' ', STATUS ), 'WAVELENGTH', STATUS ) -* This example has exactly the same effect as that above. It -* illustrates the equivalence of the template's Domain attribute -c and the fields in the "domainlist" string. -f and the fields in the DOMAINLIST string. -c result = astFindFrame( target, astFrame( 1, "MaxAxes=3" ), "" ); -f RESULT = AST_FINDFRAME( TARGET, AST_FRAME( 1, 'MaxAxes=3', STATUS ), ' ', STATUS ) -* This is a more advanced example which will search for any -* coordinate system in the target having 1, 2 or 3 -c dimensions. The Frame returned (as part of the "result" -f dimensions. The Frame returned (as part of the RESULT -* FrameSet) will always be 1-dimensional, but will be related -* to the coordinate system that was found by a suitable Mapping -* (e.g. a PermMap) which simply extracts the first axis. -* -* If we had wanted a Frame representing the actual (1, 2 or -* 3-dimensional) coordinate system found, we could set the -* PreserveAxes attribute to a non-zero value in the template. -c result = astFindFrame( target, astSkyFrame( "Permute=0" ), "" ); -f RESULT = AST_FINDFRAME( TARGET, AST_SKYFRAME( 'Permute=0', STATUS ), ' ', STATUS ) -* Searches for any celestial coordinate system in the target, -* but only finds one if its axes are in the conventional -* (longitude,latitude) order and have not been permuted -c (e.g. with astPermAxes). -f (e.g. with AST_PERMAXES). - -* Notes: -* - The Mapping represented by the returned FrameSet results in -* alignment taking place in the coordinate system specified by the -c AlignSystem attribute of the "template" Frame. See the description -f AlignSystem attribute of the TEMPLATE Frame. See the description -* of the AlignSystem attribute for further details. -* - Beware of setting the Domain attribute of the template and then -c using a "domainlist" string which does not include the template's domain -f using a DOMAINLIST string which does not include the template's domain -* (or a blank field). If you do so, no coordinate system will be -* found. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* More on Using Templates: -* A Frame (describing a coordinate system) will be found by this -* function if (a) it is "matched" by the template you supply, and -c (b) the value of its Domain attribute appears in the "domainlist" -f (b) the value of its Domain attribute appears in the DOMAINLIST -* string (except that a blank field in this string permits any -* domain). A successful match by the template depends on a number -* of criteria, as outlined below: -* - In general, a template will only match another Frame which -* belongs to the same class as the template, or to a derived (more -* specialised) class. For example, a SkyFrame template will match -* any other SkyFrame, but will not match a basic -* Frame. Conversely, a basic Frame template will match any class -* of Frame. -* - The exception to this is that a Frame of any class can be used to -* match a CmpFrame, if that CmpFrame contains a Frame of the same -* class as the template. Note however, the MaxAxes and MinAxes -* attributes of the template must be set to suitable values to allow -* it to match the CmpFrame. That is, the MinAxes attribute must be -* less than or equal to the number of axes in the target, and the MaxAxes -* attribute must be greater than or equal to the number of axes in -* the target. -* - If using a CmpFrame as a template frame, the MinAxes and MaxAxes -* for the template are determined by the MinAxes and MaxAxes values of -* the component Frames within the template. So if you want a template -* CmpFrame to be able to match Frames with different numbers of axes, -* then you must set the MaxAxes and/or MinAxes attributes in the component -* template Frames, before combining them together into the template -* CmpFrame. -* - If a template has a value set for any of its main attributes, then -* it will only match Frames which have an identical value for that -* attribute (or which can be transformed, using a built-in -* conversion, so that they have the required value for that -* attribute). If any attribute in the template is un-set, however, -* then Frames are matched regardless of the value they may have -* for that attribute. You may therefore make a template more or -* less specific by choosing the attributes for which you set -* values. This requirement does not apply to 'descriptive' attributes -* such as titles, labels, symbols, etc. -* - An important application of this principle involves the Domain -* attribute. Setting the Domain attribute of the template has the -* effect of restricting the search to a particular type of Frame -* (with the domain you specify). Conversely, if the Domain -* attribute is not set in the template, then the domain of the -* Frame found is not relevant, so all Frames are searched. Note -* that the -c "domainlist" string provides an alternative way of restricting the -f DOMAINLIST string provides an alternative way of restricting the -* search in the same manner, but is a more convenient interface if -* you wish to search automatically for another domain if the first -* search fails. -* - Normally, a template will only match a Frame which has the -* same number of axes as itself. However, for some classes of -* template, this default behaviour may be changed by means of the -* MinAxes, MaxAxes and MatchEnd attributes. In addition, the -* behaviour of a template may be influenced by its Permute and -* PreserveAxes attributes, which control whether it matches Frames -* whose axes have been permuted, and whether this permutation is -* retained in the Frame which is returned (as opposed to returning -* the axes in the order specified in the template, which is the -* default behaviour). You should consult the descriptions of these -* attributes for details of this more advanced use of templates. -*-- -*/ - -/* Local Variables: */ - AstFrame *frame; /* Pointer to result Frame */ - AstFrameSet *result; /* Pointer to result FrameSet */ - AstMapping *map; /* Pointer to result Mapping */ - AstMapping *tmp; /* Temporary Mapping pointer */ - char *domain_copy; /* Pointer to copy of result domain */ - char *domainlist_copy; /* Pointer to copy of domains list */ - const char *domain; /* Pointer to result Domain value */ - int *target_axes; /* Pointer to target axis assignments */ - int *template_axes; /* Pointer to template axis assignments */ - int i; /* Loop counter for characters */ - int j; /* Character index */ - int match; /* Template matched target? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Allocate space to store a copy of the domains list, with added - commas. */ - domainlist_copy = astMalloc( strlen( domainlist ) + (size_t) 3 ); - if ( astOK ) { - -/* Make a copy of the domains list, with an extra comma added at each - end. Also remove all white space and convert to upper case. */ - domainlist_copy[ 0 ] = ','; - for ( i = 0, j = 1; domainlist[ i ]; i++ ) { - if ( !isspace( domainlist[ i ] ) ) { - domainlist_copy[ j++ ] = toupper( domainlist[ i ] ); - } - } - domainlist_copy[ j++ ] = ','; - domainlist_copy[ j ] = '\0'; - -/* Invoke the protected astMatch method associated with the template - Frame. This matches the template to the target and returns - information about how to convert between the target and the Frame - it found (if any). */ - match = astMatch( template, target, 0, - &template_axes, &target_axes, &map, &frame ); - -/* If successful, obtain a pointer to the Domain string of the result - Frame. Allocate space for a copy of this string, with added - commas. */ - if ( match && astOK ) { - domain = astGetDomain( frame ); - if ( astOK ) { - domain_copy = astMalloc( strlen( domain ) + (size_t) 3 ); - if ( astOK ) { - -/* Make a copy of the domain, adding an extra comma at each end. */ - domain_copy[ 0 ] = ','; - for ( i = 0, j = 1; domain[ i ]; i++ ) { - domain_copy[ j++ ] = domain[ i ]; - } - domain_copy[ j++ ] = ','; - domain_copy[ j ] = '\0'; - -/* Test if the domain appears in the domains list (with added - commas). If not, test if a blank domain (which permits the result - Frame to have any Domain) appears instead. */ - if ( strstr( domainlist_copy, domain_copy ) || - strstr( domainlist_copy, ",," ) ) { - -/* If the result Frame is acceptable, simplify the result Mapping. */ - tmp = astSimplify( map ); - map = astAnnul( map ); - map = tmp; - -/* Build the result FrameSet. */ - result = astFrameSet( target, "", status ); - astAddFrame( result, AST__BASE, map, frame ); - } - } - -/* Free the copy of the result domain. */ - domain_copy = astFree( domain_copy ); - } - -/* Free space and annul pointers allocated by astMatch. */ - template_axes = astFree( template_axes ); - target_axes = astFree( target_axes ); - map = astAnnul( map ); - frame = astAnnul( frame ); - } - } - -/* Free the copy of the domains list. */ - domainlist_copy = astFree( domainlist_copy ); - -/* If an error occurred, annul any result pointer. */ - if ( !astOK && result ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -const char *astFmtDecimalYr_( double year, int digits, int *status ) { -/* -*+ -* Name: -* astFmtDecimalYr - -* Purpose: -* Format an epoch expressed in years as a decimal string. - -* Type: -* Protected function. - -* Synopsis: -* #include "frame.h" -* const char *astFmtDecimalYr( double year, int digits ) - -* Class Membership: -* Frame member function. - -* Description: -* This function formats an epoch expressed in years as a decimal string -* and returns a pointer to the result. It is intended for formatting -* Frame Epoch values, etc, for display. - -* Parameters: -* year -* The epoch to be formatted. -* digits -* The number of digits of precision required. - -* Returned Value: -* Pointer to a null terminated string containing the formatted value. - -* Notes: -* - The result string is stored in static memory and may be -* over-written by a subsequent invocation of this function. -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - int nc; /* Number of characters in buffer */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Limit the precision to what is meaningful. */ - digits = ( digits > AST__DBL_DIG ) ? AST__DBL_DIG : digits; - -/* Format the year value. Use "g" format to avoid buffer overflow and - to get useful diagnostic output if a silly value is given. */ - nc = sprintf( astfmtdecimalyr_buff, "%#.*g", digits, year ); - -/* Loop to remove redundant zeros from the end of the result. */ - while ( astfmtdecimalyr_buff[ --nc ] == '0' ) astfmtdecimalyr_buff[ nc ] = '\0'; - -/* If the last character is now a decimal point, put back one zero. */ - if ( astfmtdecimalyr_buff[ nc ] == '.' ) { - astfmtdecimalyr_buff[ ++nc ] = '0'; - astfmtdecimalyr_buff[ ++nc ] = '\0'; - } - -/* Return the result. */ - return astfmtdecimalyr_buff; -} - -static const char *Format( AstFrame *this, int axis, double value, int *status ) { -/* -*+ -* Name: -* astFormat - -* Purpose: -* Format a coordinate value for a Frame axis. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* const char *astFormat( AstFrame *this, int axis, double value ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns a pointer to a string containing the -* formatted (character) version of a coordinate value for a Frame -* axis. The formatting applied is determined by the Frame's -* attributes and, in particular, by any Format attribute string -* that has been set for the axis. A suitable default format will -* be applied if necessary. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the Frame axis for which formatting is to be -* performed (axis numbering starts at zero for the first axis). -* value -* The coordinate value to be formatted. - -* Returned Value: -* A pointer to a null-terminated string containing the formatted -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Frame, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Frame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic astFormat method available -* via the protected interface to the Frame class. The public -* interface to this method is provided by the astFormatId_ -* function. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - const char *result; /* Pointer value to return */ - int digits_set; /* Axis Digits attribute set? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Validate the axis index and obtain a pointer to the required Axis. */ - (void) astValidateAxis( this, axis, 1, "astFormat" ); - ax = astGetAxis( this, axis ); - -/* Test if any Axis attributes which may affect the result are undefined (i.e. - have not been explicitly set). If so, we over-ride them, giving them - temporary values dictated by the Frame. Only the Digits attribute is - relevant here. */ - digits_set = astTestAxisDigits( ax ); - if ( !digits_set ) astSetAxisDigits( ax, astGetDigits( this ) ); - -/* Format the value. */ - result = astAxisFormat( ax, value ); - -/* Clear any Axis attributes that were temporarily over-ridden. */ - if ( !digits_set ) astClearAxisDigits( ax ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static AstPointSet *FrameGrid( AstFrame *this, int size, const double *lbnd, - const double *ubnd, int *status ){ -/* -*+ -* Name: -* astFrameGrid - -* Purpose: -* Return a grid of points covering a rectangular area of a Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* AstPointSet *astFrameGrid( AstFrame *this_frame, int size, -* const double *lbnd, const double *ubnd ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns a PointSet containing positions spread -* approximately evenly throughtout a specified rectangular area of -* the Frame. - -* Parameters: -* this -* Pointer to the Frame. -* size -* The preferred number of points in the returned PointSet. The -* actual number of points in the returned PointSet may be -* different, but an attempt is made to stick reasonably closely to -* the supplied value. -* lbnd -* Pointer to an array holding the lower bound of the rectangular -* area on each Frame axis. The array should have one element for -* each Frame axis. -* ubnd -* Pointer to an array holding the upper bound of the rectangular -* area on each Frame axis. The array should have one element for -* each Frame axis. - -* Returned Value: -* A pointer to a new PointSet holding the grid of points. - -* Notes: -* - A NULL pointer is returned if an error occurs. -*- -*/ - -/* Local Variables: */ - AstPointSet *result; - const char *unit; - double **ptr; - double *gmean; - double *step; - int *maxi; - int *nsame; - int *ntick; - int *pi; - int bad; - int iax; - int ipp; - int jax; - int naxes; - int np; - int ntick0; - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the number of axes in the Frame. */ - naxes = astGetNaxes( this ); - -/* Allocate an array to hold the number of ticks along each axis. */ - ntick = astMalloc( sizeof(int)*naxes ); - -/* Allocate an array to hold the geometric mean of the lengths of the - axes that have the same units as the current axis. */ - gmean = astMalloc( naxes*sizeof(double) ); - -/* Allocate an array to hold the number of axes that share the same unit. */ - nsame = astMalloc( naxes*sizeof(int) ); - if( astOK ) { - -/* For each axis, find the total number of axes in the Frame that have - the same unit string. Also, find the product of the lengths of these - axes. */ - bad = 0; - for( iax = 0; iax < naxes; iax++ ) { - nsame[ iax ] = 1; - - if( ubnd[ iax ] == AST__BAD && - lbnd[ iax ] == AST__BAD ) { - bad = 1; - break; - } - - gmean[ iax ] = ubnd[ iax ] - lbnd[ iax ]; - unit = astGetUnit( this, iax ); - for( jax = 0; jax < naxes; jax++ ) { - if( jax != iax ) { - if( astOK && !strcmp( unit, astGetUnit( this, jax ) ) ) { - nsame[ iax ]++; - gmean[ iax ] *= ubnd[ jax ] - lbnd[ jax ]; - } - } - } - } - -/* Do nothing if any bad bounds were supplied, or if the size is less - than 1. */ - if( !bad && size >= 1 ) { - -/* Get the nominal number of ticks per axis. */ - ntick0 = pow( size, 1.0/(double)naxes ); - if( ntick0 < 2 ) ntick0 = 2; - -/* Convert the dimension products into geometric means. */ - for( iax = 0; iax < naxes; iax++ ) { - gmean[ iax ] = pow( fabs(gmean[ iax ]), 1.0/(double)nsame[ iax ] ); - } - -/* The number of ticks to use on each axis is equal to the nominal number - multiplied by the ratio of the axis length to the geometric mean of the - axis lengths that sahare the same unit string. This gives more ticks - on the longer axes within any group of common-unit axes, whilst - retaining the overall number of ticks (roughly). Also find the total - number of points. */ - np = 1; - for( iax = 0; iax < naxes; iax++ ) { - ntick[ iax ] = ntick0*( ubnd[ iax ] - lbnd[ iax ] )/gmean[ iax ]; - if( ntick[ iax ] < 2 ) ntick[ iax ] = 2; - np *= ntick[ iax ]; - } - -/* Create a PointSet large enough to hold this many points. */ - result = astPointSet( np, naxes, " ", status ); - ptr = astGetPoints( result ); - -/* Allocate memory to hold the max indices on each axis. */ - maxi = astMalloc( sizeof( int )*(size_t) naxes ); - -/* Allocate memory to hold the indices of the current position.*/ - pi = astMalloc( sizeof( int )*(size_t) naxes ); - -/* Allocate memory to hold the step size for each axis. */ - step = astMalloc( sizeof( double )*(size_t) naxes ); - if( astOK ) { - -/* For every axis, set up the step size, initialise the current position to - the lower bound, and store a modified upper limit which includes some - safety marging to allow for rounding errors. */ - for( iax = 0; iax < naxes; iax++ ) { - step[ iax ] = ( ubnd[ iax ] - lbnd[ iax ] )/( ntick[ iax ] - 1 ); - pi[ iax ] = 0; - maxi[ iax ] = ntick[ iax ] - 1; - } - -/* Initialise the index of the next position to store. */ - ipp = 0; - -/* Loop round adding points to the array until the whole volume has been - done. */ - iax = 0; - while( iax < naxes ) { - -/* Add the current point to the supplied array, and increment the index of - the next point to add. */ - for( iax = 0; iax < naxes; iax++ ) { - ptr[ iax ][ ipp ] = lbnd[ iax ] + pi[ iax ]*step[ iax ]; - } - ipp++; - -/* We now move the current position on to the next sample */ - iax = 0; - while( iax < naxes ) { - pi[ iax ]++; - if( pi[ iax ] > maxi[ iax ] ) { - pi[ iax ] = 0; - iax++; - } else { - break; - } - } - } - } - -/* Free resources. */ - maxi = astFree( maxi ); - pi = astFree( pi ); - step = astFree( step ); - -/* Report error if supplied values were bad. */ - } else if( astOK ) { - if( bad ) { - astError( AST__ATTIN, "astFrameGrid(%s): One of more of the " - "supplied bounds is AST__BAD (programming error).", - status, astGetClass( this ) ); - } else if( size < 1 ) { - astError( AST__ATTIN, "astFrameGrid(%s): The supplied grid " - "size (%d) is invalid (programming error).", - status, astGetClass( this ), size ); - } - } - } - -/* Free resources. */ - ntick = astFree( ntick ); - nsame = astFree( nsame ); - gmean = astFree( gmean ); - -/* Annul the returned PointSet if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the PointSet holding the grid. */ - return result; -} - -static double Gap( AstFrame *this, int axis, double gap, int *ntick, int *status ) { -/* -*+ -* Name: -* astGap - -* Purpose: -* Find a "nice" gap for tabulating Frame axis values. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* double astGap( AstFrame *this, int axis, double gap, int *ntick ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns a gap size which produces a nicely spaced -* series of formatted values for a Frame axis, the returned gap -* size being as close as possible to the supplied target gap -* size. It also returns a convenient number of divisions into -* which the gap can be divided. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which a gap is to be found. -* gap -* The target gap size. -* ntick -* Address of an int in which to return a convenient number of -* divisions into which the gap can be divided. - -* Returned Value: -* The nice gap size. - -* Notes: -* - A value of zero is returned if the target gap size is zero. -* - A negative gap size is returned if the supplied gap size is negative. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - double result; /* The nice gap value */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Validate the axis index and obtain a pointer to the required - Axis. */ - (void) astValidateAxis( this, axis, 1, "astGap" ); - ax = astGetAxis( this, axis ); - -/* Find the gap. */ - result = astAxisGap( ax, gap, ntick ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static int GetActiveUnit( AstFrame *this, int *status ){ -/* -*++ -* Name: -c astGetActiveUnit -f AST_GETACTIVEUNIT - -* Purpose: -* Determines how the Unit attribute will be used. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c int astGetActiveUnit( AstFrame *this ) -f RESULT = AST_GETACTIVEUNIT( THIS, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* returns the current value of the ActiveUnit flag for a Frame. See -c the description of the astSetActiveUnit function -f the description of the AST_SETACTIVEUNIT routine -* for a description of the ActiveUnit flag. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetActiveUnit -f AST_GETACTIVEUNIT = LOGICAL -* The current value of the ActiveUnit flag. - -* Notes: -c - A zero value will be returned if this function is -c invoked with the AST error status set, or if it should fail for -f - A value of .FALSE. will be returned if this function is -f invoked with STATUS set to an error value, or if it should fail for -* any reason. -*-- -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to axis structure */ - int i; /* Index of axis in Frame */ - int has_skyaxis; /* Does Frame contain any SkyAxes? */ - int nax; /* Number of axes in Frame */ - int result; /* The returned value */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* See if the Frame contains a SkyAxis. */ - has_skyaxis = 0; - nax = astGetNaxes( this ); - for( i = 0; i < nax; i++ ) { - ax = astGetAxis( this, i ); - if( astIsASkyAxis( ax ) ) has_skyaxis = 1; - ax = astAnnul( ax ); - } - -/* If the Frame contains a SkyAxis the ActiveUnit flag is always zero. */ - if( !has_skyaxis ) { - -/* Otherwise, get the value from the Frame. If it has not yet been assigned a - value return the value zero. */ - result = this->active_unit; - if( result == -INT_MAX ) result = 0; - } - -/* Return the result. */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Frame member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Frame, formatted as a character string. - -* Parameters: -* this -* Pointer to the Frame. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - The returned string pointer may point at memory allocated -* within the Frame, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Frame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstAxis *ax; /* Pointer to Axis */ - AstFrame *pfrm; /* Pointer to primary Frame containing axis */ - AstFrame *this; /* Pointer to the Frame structure */ - AstSystemType system; /* System code */ - char pfrm_attrib[ 100 ]; /* Primary Frame attribute */ - char *axis_attrib; /* Pointer to axis attribute name */ - const char *old_attrib; /* Pointer to supplied attribute name string */ - const char *result; /* Pointer value to return */ - double dval; /* Double attibute value */ - double epoch; /* Epoch attribute value (as MJD) */ - int axis; /* Frame axis number */ - int axis_nc; /* No. characters in axis attribute name */ - int digits; /* Digits attribute value */ - int direction; /* Direction attribute value */ - int free_axis_attrib; /* Should axis_attrib be freed? */ - int has_axis; /* Does attrib name include axis specifier? */ - int len; /* Length of attrib string */ - int match_end; /* MatchEnd attribute value */ - int max_axes; /* MaxAxes attribute value */ - int min_axes; /* MinAxes attribute value */ - int naxes; /* Naxes attribute value */ - int nc; /* No. characters read by astSscanf */ - int oldrep; /* Original error reporting state */ - int paxis; /* Axis index within primary frame */ - int permute; /* Permute attribute value */ - int preserve_axes; /* PreserveAxes attribute value */ - int used; /* Could the setting string be used? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) this_object; - -/* Set a flag indicating if the attribute name includes an axis - specifier. */ - has_axis = ( strchr( attrib, '(' ) != NULL ); - -/* A flag indicating that we do not need to free the axis_attrib memory. */ - free_axis_attrib = 0; - -/* Initialise things to avoid compiler warnings. */ - axis_attrib = NULL; - old_attrib = NULL; - -/* Jump back to here if we are trying the same attribute but with an explicit - axis "(1)" added to the end of the name. */ -L1: - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Save the number of axes in the Frame for later use. */ - naxes = astGetNaxes( this ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* Digits. */ -/* ------- */ - if ( !strcmp( attrib, "digits" ) ) { - digits = astGetDigits( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", digits ); - result = getattrib_buff; - } - -/* Digits(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "digits(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - -/* There is no function to obtain the Digits attribute value for an - axis directly, so obtain a pointer to the Axis and use this to - obtain the value. Use the Frame's Digits attribute instead if the - Axis attribute value is not set. */ - (void) astValidateAxis( this, axis - 1, 1, "astGetDigits(axis)" ); - ax = astGetAxis( this, axis - 1 ); - if ( astTestAxisDigits( ax ) ) { - digits = astGetAxisDigits( ax ); - } else { - digits = astGetDigits( this ); - } - ax = astAnnul( ax ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", digits ); - result = getattrib_buff; - } - - -/* Direction(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "direction(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - direction = astGetDirection( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", direction ); - result = getattrib_buff; - } - -/* Epoch. */ -/* ------ */ - } else if ( !strcmp( attrib, "epoch" ) ) { - epoch = astGetEpoch( this ); - if ( astOK ) { - -/* Format the Epoch as decimal years. Use a Besselian epoch if it will - be less than 1984.0, otherwise use a Julian epoch. */ - result = astFmtDecimalYr( ( epoch < palEpj2d( 1984.0 ) ) ? - palEpb( epoch ) : palEpj( epoch ), AST__DBL_DIG ); - } - -/* Top(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "top(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetTop( this, axis -1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Bottom(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "bottom(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetBottom( this, axis -1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Domain. */ -/* ------- */ - } else if ( !strcmp( attrib, "domain" ) ) { - result = astGetDomain( this ); - -/* Format(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "format(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astGetFormat( this, axis - 1 ); - -/* Label(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "label(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astGetLabel( this, axis - 1 ); - -/* MatchEnd. */ -/* --------- */ - } else if ( !strcmp( attrib, "matchend" ) ) { - match_end = astGetMatchEnd( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", match_end ); - result = getattrib_buff; - } - -/* MaxAxes. */ -/* -------- */ - } else if ( !strcmp( attrib, "maxaxes" ) ) { - max_axes = astGetMaxAxes( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", max_axes ); - result = getattrib_buff; - } - -/* MinAxes. */ -/* -------- */ - } else if ( !strcmp( attrib, "minaxes" ) ) { - min_axes = astGetMinAxes( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", min_axes ); - result = getattrib_buff; - } - -/* Naxes. */ -/* -----_ */ - } else if ( !strcmp( attrib, "naxes" ) ) { - (void) sprintf( getattrib_buff, "%d", naxes ); - result = getattrib_buff; - -/* Permute. */ -/* -------- */ - } else if ( !strcmp( attrib, "permute" ) ) { - permute = astGetPermute( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", permute ); - result = getattrib_buff; - } - -/* PreserveAxes. */ -/* ------------- */ - } else if ( !strcmp( attrib, "preserveaxes" ) ) { - preserve_axes = astGetPreserveAxes( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", preserve_axes ); - result = getattrib_buff; - } - -/* Symbol(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "symbol(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astGetSymbol( this, axis - 1 ); - -/* AlignSystem. */ -/* ------------ */ -/* Obtain the AlignSystem code and convert to a string. */ - } else if ( !strcmp( attrib, "alignsystem" ) ) { - system = astGetAlignSystem( this ); - if ( astOK ) { - result = astSystemString( this, system ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid " - "AlignSystem identification code (%d).", status, - astGetClass( this ), astGetClass( this ), (int) system ); - } - } - -/* System. */ -/* ------- */ -/* Obtain the System code and convert to a string. */ - } else if ( !strcmp( attrib, "system" ) ) { - system = astGetSystem( this ); - if ( astOK ) { - result = astSystemString( this, system ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid " - "System identification code (%d).", status, - astGetClass( this ), astGetClass( this ), (int) system ); - } - } - -/* Title. */ -/* ------ */ - } else if ( !strcmp( attrib, "title" ) ) { - result = astGetTitle( this ); - -/* Unit(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "unit(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astGetUnit( this, axis - 1 ); - -/* NormUnit(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "normunit(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astGetNormUnit( this, axis - 1 ); - -/* InternalUnit(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "internalunit(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astGetInternalUnit( this, axis - 1 ); - -/* ObsLat. */ -/* ------- */ - } else if ( !strcmp( attrib, "obslat" ) ) { - dval = astGetObsLat( this ); - if ( astOK ) { - -/* If not already created, create an FK5 J2000 SkyFrame which will be used - for formatting and unformatting ObsLon and ObsLat values. */ - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame("system=FK5,equinox=J2000,format(2)=dms.2", status ); - astEndPM; - } - -/* Display absolute value preceded by "N" or "S" as appropriate. */ - if( dval < 0 ) { - (void) sprintf( getattrib_buff, "S%s", astFormat( skyframe, 1, -dval ) ); - } else { - (void) sprintf( getattrib_buff, "N%s", astFormat( skyframe, 1, dval ) ); - } - result = getattrib_buff; - } - -/* ObsLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "obslon" ) ) { - dval = astGetObsLon( this ); - if ( astOK ) { - -/* Put into range +/- PI. */ - dval = palDrange( dval ); - -/* If not already created, create an FK5 J2000 SkyFrame which will be used - for formatting and unformatting ObsLon and ObsLat values. */ - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000,format(2)=dms.2", status ); - astEndPM; - } - -/* Display absolute value preceded by "E" or "W" as appropriate. */ - if( dval < 0 ) { - (void) sprintf( getattrib_buff, "W%s", astFormat( skyframe, 1, -dval ) ); - } else { - (void) sprintf( getattrib_buff, "E%s", astFormat( skyframe, 1, dval ) ); - } - result = getattrib_buff; - - } - -/* ObsAlt. */ -/* ------- */ - } else if ( !strcmp( attrib, "obsalt" ) ) { - dval = astGetObsAlt( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Dtai. */ -/* ---- */ - } else if ( !strcmp( attrib, "dtai" ) ) { - dval = astGetDtai( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Dut1. */ -/* ---- */ - } else if ( !strcmp( attrib, "dut1" ) ) { - dval = astGetDut1( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Other axis attributes. */ -/* ---------------------- */ -/* If the attribute was not identified above, but appears to refer to - a Frame axis, then it may refer to an Axis object of a derived type - (which has additional attributes not recognised here). */ - } else if ( !free_axis_attrib && ( nc = 0, - ( 1 == astSscanf( attrib, "%*[^()]%n(%d)%n", - &axis_nc, &axis, &nc ) ) - && ( nc >= len ) ) ) { - -/* Validate the axis index and extract the attribute name. */ - (void) astValidateAxis( this, axis - 1, 1, "astGet" ); - axis_attrib = astString( attrib, axis_nc ); - -/* Obtain a pointer to the Axis object. */ - ax = astGetAxis( this, axis - 1 ); - if( astOK ) { - -/* Assume that we will be able to use the attribute name. */ - used = 1; - -/* Temporarily switch off error reporting so that if the following attempt - to access the axis attribute fails, we can try to interpret the - attribute name as an attribute of the primary Frame containing the - specified axis. Any errors reported in this context will simply be - ignored, in particularly they are not deferred for later delivery. */ - oldrep = astReporting( 0 ); - -/* Use the Axis astGetAttrib method to obtain the result. */ - result = astGetAttrib( ax, axis_attrib ); - -/* If the above call failed with a status of AST__BADAT, indicating that - the attribute name was not recognised, clear the status so that we can - try to interpret the attribute name as an attribute of the primary Frame - containing the specified axis. */ - if( astStatus == AST__BADAT ) { - astClearStatus; - -/* Find the primary Frame containing the specified axis. */ - astPrimaryFrame( this, axis - 1, &pfrm, &paxis ); - -/* Only attempt to use the primary Frame if it is not the same as "this" - - otherwise we could end up in an infinite loop. */ - if( pfrm != this ) { - -/* astPrimaryFrame returns the original - unpermuted - axis index within - the primary Frame. So we need to take into account any axis permutation - which has been applied to the primary Frame when forming the attribute name - to use below. Find the permuted (external) axis index which corresponds to - the internal (unpermuted) axis index "paxis". */ - paxis = astValidateAxis( pfrm, paxis, 0, "astGet" ); - -/* Modify the attribute name to refer to the axis numbering of the - primary frame. */ - sprintf( pfrm_attrib, "%s(%d)", axis_attrib, paxis + 1 ); - -/* Attempt to use the Axis astGetAttrib method to obtain the result. */ - result = astGetAttrib( pfrm, pfrm_attrib ); - -/* If this failed, clear the status and indicate that we have not managed to - use the attribute name. */ - if( !astOK ) { - astClearStatus; - used = 0; - } - - } else { - used = 0; - } - -/* If not found attempt to get the attribute value from the Axis, omitting - the axis index. */ - if( ! used ) { - result = astGetAttrib( pfrm, axis_attrib ); - if( !astOK ) { - astClearStatus; - } else { - used = 1; - } - } - -/* Annul the primary Frame pointer. */ - pfrm = astAnnul( pfrm ); - } - -/* Re-instate the original error reporting state. */ - astReporting( oldrep ); - -/* If we could not use the attribute name, attempt to get the axis - attribute again, this time retaining the error report. This is done - to ensure the user gets an appropriate error message. */ - if( !used ) result = astGetAttrib( ax, axis_attrib ); - } - -/* Annul the Axis pointer and free the memory holding the attribute - name. */ - ax = astAnnul( ax ); - axis_attrib = astFree( axis_attrib ); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is still not recognised, and the Frame has only 1 axis, - and the attribute name does not already include an axis specifier, try - again after appending "(1)" to the end of the attribute name. */ - } else if( !has_axis && naxes == 1 ) { - -/* Take a copy of the supplied name, allowing 3 extra characters for the - axis specifier "(1)". */ - axis_attrib = astMalloc( len + 4 ); - if( axis_attrib ) memcpy( axis_attrib, attrib, len ); - -/* Indicate we should free the axis_attrib memory. */ - free_axis_attrib = 1; - -/* Add in the axis specifier. */ - strcpy( axis_attrib + len, "(1)" ); - -/* Use the new attribute name instead of the supplied name. */ - old_attrib = attrib; - attrib = axis_attrib; - -/* Indicate the attribute name now has an axis specifier. */ - has_axis = 1; - -/* Jump back to try interpreting the new attribute name. */ - goto L1; - -/* Not recognised. */ -/* --------------- */ -/* If the attribute name is still not recognised, pass it on to the parent - method for further interpretation. First re-instate the original attrib - name string if it was changed above. */ - } else { - if( free_axis_attrib ) { - attrib = old_attrib; - axis_attrib = astFree( axis_attrib ); - } - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static AstAxis *GetAxis( AstFrame *this, int axis, int *status ) { -/* -*+ -* Name: -* astGetAxis - -* Purpose: -* Obtain a pointer to a specified Axis from a Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* AstAxis *astGetAxis( AstFrame *this, int axis ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns a pointer to the Axis object associated -* with one of the axes of a Frame. This object describes the -* quantity which is represented along that axis. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which an Axis pointer is -* required. - -* Returned Value: -* A pointer to the requested Axis object. - -* Notes: -* - The reference count of the requested Axis object will be -* incremented by one to reflect the additional pointer returned by -* this function. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstAxis *result; /* Pointer to Axis */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise. */ - result = NULL; - -/* Validate and permute the axis index. */ - axis = astValidateAxis( this, axis, 1, "astGetAxis" ); - -/* If OK, clone the required Axis pointer. */ - if ( astOK ) result = astClone( this->axis[ axis ] ); - -/* Return the result. */ - return result; -} - -static const char *GetDefaultLabel( int axis, int *status ) { -/* -* Name: -* GetDefaultLabel - -* Purpose: -* Return a pointer to a default axis Label string. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* const char *GetDefaultLabel( int axis, int *status ) - -* Class Membership: -* Frame member function - -* Description: -* This function returns a pointer to a string holding a default axis -* Label value. - -* Parameters: -* axis -* Zero based axis index. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a static null-terminated string containing the attribute -* value. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Format the axis index, putting the string in a global buffer. */ - (void) sprintf( label_buff, "Axis %d", axis + 1 ); - -/* Return a pointer to the global buffer. */ - return label_buff; -} - -static const char *GetDefaultSymbol( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetDefaultSymbol - -* Purpose: -* Return a pointer to a default axis Symbol string. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* const char *GetDefaultSymbol( AstFrame *this, int axis, int *status ) - -* Class Membership: -* Frame member function - -* Description: -* This function returns a pointer to a string holding a default axis -* Symbol value. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* Zero based axis index. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a static null-terminated string containing the attribute -* value. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Note we use "sprintf" once to determine how many characters are - produced by the "%d" format string and then limit the number of - characters used from the Domain string in the second invocation of - "sprintf" so that the total length of the default Symbol string - does not exceed SYMBOL_BUFF_LEN characters. */ - (void) sprintf( symbol_buff, "%.*s%d", - SYMBOL_BUFF_LEN - sprintf( symbol_buff, "%d", axis + 1 ), - astTestDomain( this ) ? astGetDomain( this ) : "x", - axis + 1 ); - -/* Use the AddUnderscores function to replace any white space in the Symbol - string with underscore characters. */ - AddUnderscores( symbol_buff, status ); - -/* Return a pointer to the global buffer. */ - return symbol_buff; -} - -static const char *GetDefaultTitle( AstFrame *this, int *status ) { -/* -* Name: -* GetDefaultTitle - -* Purpose: -* Return a pointer to a default Title string. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* const char *GetDefaultTitle( AstFrame *this, int *status ) - -* Class Membership: -* Frame member function - -* Description: -* This function returns a pointer to a string holding a default Title value. - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a static null-terminated string containing the attribute -* value. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Create the Title value and put it in the global buffer. */ - (void) sprintf( title_buff, "%d-d coordinate system", astGetNaxes( this ) ); - -/* Return a pointer to the global buffer. */ - return title_buff; -} - -static int GetFrameFlags( AstFrame *this, int *status ){ -/* -*+ -* Name: -* astGetFrameFlags - -* Purpose: -* Return the bit mask of flags associated with a Frame. - -* Type: -* Protected function. - -* Synopsis: -* #include "frame.h" -* int *astGetFrameFlags( astFrame *this ) - -* Class Membership: -* Frame virtual function. - -* Description: -* This function returns a bit mask holding the current set of flags -* associated with a Frame. See astSetFrameFlags for details of these -* flags. - -* Parameters: -* this -* The Frame. - -* Returned Value: -* The bit mask. - -* Notes: -* - Zero is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the result. */ - return this->flags; -} - -static int GetIsLinear( AstMapping *this_mapping, int *status ){ -/* -* Name: -* GetIsLinear - -* Purpose: -* Return the value of the IsLinear attribute for a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GetIsLinear( AstMapping *this, int *status ) - -* Class Membership: -* Frame member function (over-rides the protected astGetIsLinear -* method inherited from the Mapping class). - -* Description: -* This function returns the value of the IsLinear attribute for a -* Frame, which is always one because a Frame is treated like a UnitMap. - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. -*/ - return 1; -} - -static int GetIsSimple( AstMapping *this_mapping, int *status ){ -/* -* Name: -* GetIsSimple - -* Purpose: -* Return the value of the IsSimple attribute for a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GetIsSimple( AstMapping *this, int *status ) - -* Class Membership: -* Frame member function (over-rides the protected astGetIsSimple -* method inherited from the Mapping class). - -* Description: -* This function returns the value of the IsSimple attribute for a -* Frame, which is always zero because Frames are not immutable (unlike -* non-Frame Mappings). - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. -*/ - return 0; -} - -static int GetNaxes( AstFrame *this, int *status ) { -/* -*+ -* Name: -* astGetNaxes - -* Purpose: -* Determine how many axes a Frame has. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astGetNaxes( AstFrame *this ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns the number of axes for a Frame. - -* Parameters: -* this -* Pointer to the Frame. - -* Returned Value: -* The number of Frame axes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the number of Frame axes. */ - return this->naxes; -} - -static int GetNin( AstMapping *this_mapping, int *status ) { -/* -* Name: -* GetNin - -* Purpose: -* Get the number of input coordinates for a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int GetNin( AstMapping *this, int *status ) - -* Class Membership: -* Frame member function (over-rides the astGetNin method inherited -* from the Mapping class). - -* Description: -* This function returns the number of input coordinate values -* required per point by a Frame, when used as a Mapping (i.e. the -* number of dimensions of the space in which input points reside). - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Number of coordinate values required. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *this; /* Pointer to Frame structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) this_mapping; - -/* Return the number of Frame axes. */ - result = astGetNaxes( this ); - -/* Return the result. */ - return result; -} - -static int GetNout( AstMapping *this_mapping, int *status ) { -/* -* Name: -* GetNout - -* Purpose: -* Get the number of output coordinates for a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int GetNout( AstMapping *this, int *status ) - -* Class Membership: -* Frame member function (over-rides the astGetNout method -* inherited from the Mapping class). - -* Description: -* This function returns the number of output coordinate values -* generated per point by a Frame, when used as a Mapping (i.e. the -* number of dimensions of the space in which output points -* reside). - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Number of coordinate values generated. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *this; /* Pointer to Frame structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) this_mapping; - -/* Return the number of Frame axes. */ - result = astGetNaxes( this ); - -/* Return the result. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* Frame member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied Frame, -* in bytes. - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *this; /* Pointer to Frame structure */ - int axis; /* Axis index */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the FrameSet structure. */ - this = (AstFrame *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astGetObjSize( this->variants ); - result += astTSizeOf( this->domain ); - result += astTSizeOf( this->title ); - result += astTSizeOf( this->axis ); - result += astTSizeOf( this->perm ); - - for ( axis = 0; axis < this->naxes; axis++ ) { - result += astGetObjSize( this->axis[ axis ] ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const int *GetPerm( AstFrame *this, int *status ) { -/* -*+ -* Name: -* astGetPerm - -* Purpose: -* Access the axis permutation array for a Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* const int *astGetPerm( AstFrame *this ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns a pointer to the axis permutation array -* for a Frame. This array constitutes a lookup-table that converts -* between an axis number supplied externally and the corresponding -* index in the Frame's internal axis arrays. - -* Parameters: -* this -* Pointer to the Frame. - -* Returned Value: -* Pointer to the Frame's axis permutation array (a constant array -* of int). Each element of this contains the (zero-based) -* internal axis index to be used in place of the external index -* which is used to address the permutation array. If the Frame has -* zero axes, this pointer will be NULL. - -* Notes: -* - This protected method is provided to assist class -* implementations which need to implement axis-dependent -* extensions to Frame methods, and which therefore need to know -* how a Frames's external axis index is converted for internal -* use. -* - The pointer returned by this function gives direct access to -* data internal to the Frame object. It remains valid only so long -* as the Frame exists. The permutation array contents may be -* modified by other functions which operate on the Frame and this -* may render the returned pointer invalid. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Return a pointer to the axis permutation array. */ - return this->perm; -} - -static AstFrameSet *GetFrameVariants( AstFrame *this, int *status ){ -/* -*+ -* Name: -* astGetFrameVariants - -* Purpose: -* Returns the FrameSet holding the available Frame variants. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* AstFrameSet *astGetFrameVariants( AstFrame *this ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns a pointer to any FrameSet previously stored -* in the Frame using method astSetVariants. - -* Parameters: -* this -* Pointer to the Frame. - -* Returned Value: -* astGetFrameVariants -* A pointer to the FrameSet. It should be annulled using astAnnul -* when no longer needed. NULL will be returned if no FrameSet is -* stored in the Frame. - -* Notes: -* - A NULL value will be returned if this function is invoked with the -* AST error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstFrameSet *result; - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a clone of any FrameSet pointer. */ - if( this->variants ) result = astClone( this->variants ); - -/* Return the result. */ - return result; -} - -void astInitFrameVtab_( AstFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitFrameVtab - -* Purpose: -* Initialise a virtual function table for a Frame. - -* Type: -* Protected function. - -* Synopsis: -* #include "frame.h" -* void astInitFrameVtab( AstFrameVtab *vtab, const char *name ) - -* Class Membership: -* Frame vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Frame class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAFrame ) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->Abbrev = Abbrev; - vtab->CheckPerm = CheckPerm; - vtab->ClearDigits = ClearDigits; - vtab->ClearDirection = ClearDirection; - vtab->ClearDomain = ClearDomain; - vtab->ClearFormat = ClearFormat; - vtab->ClearLabel = ClearLabel; - vtab->ClearMatchEnd = ClearMatchEnd; - vtab->ClearMaxAxes = ClearMaxAxes; - vtab->ClearMinAxes = ClearMinAxes; - vtab->ClearPermute = ClearPermute; - vtab->ClearPreserveAxes = ClearPreserveAxes; - vtab->ClearSymbol = ClearSymbol; - vtab->ClearTitle = ClearTitle; - vtab->ClearUnit = ClearUnit; - vtab->Convert = Convert; - vtab->ConvertX = ConvertX; - vtab->Angle = Angle; - vtab->Distance = Distance; - vtab->Fields = Fields; - vtab->FindFrame = FindFrame; - vtab->MatchAxes = MatchAxes; - vtab->MatchAxesX = MatchAxesX; - vtab->Format = Format; - vtab->Centre = Centre; - vtab->Gap = Gap; - vtab->GetAxis = GetAxis; - vtab->GetDigits = GetDigits; - vtab->GetDirection = GetDirection; - vtab->GetDomain = GetDomain; - vtab->GetFormat = GetFormat; - vtab->GetLabel = GetLabel; - vtab->GetMatchEnd = GetMatchEnd; - vtab->GetMaxAxes = GetMaxAxes; - vtab->GetMinAxes = GetMinAxes; - vtab->GetNaxes = GetNaxes; - vtab->GetPerm = GetPerm; - vtab->GetPermute = GetPermute; - vtab->GetPreserveAxes = GetPreserveAxes; - vtab->GetSymbol = GetSymbol; - vtab->GetTitle = GetTitle; - vtab->GetUnit = GetUnit; - vtab->GetInternalUnit = GetInternalUnit; - vtab->GetNormUnit = GetNormUnit; - vtab->Intersect = Intersect; - vtab->IsUnitFrame = IsUnitFrame; - vtab->Match = Match; - vtab->Norm = Norm; - vtab->NormBox = NormBox; - vtab->AxDistance = AxDistance; - vtab->AxNorm = AxNorm; - vtab->AxOffset = AxOffset; - vtab->AxIn = AxIn; - vtab->AxAngle = AxAngle; - vtab->FrameGrid = FrameGrid; - vtab->Offset = Offset; - vtab->Offset2 = Offset2; - vtab->Resolve = Resolve; - vtab->ResolvePoints = ResolvePoints; - vtab->LineDef = LineDef; - vtab->LineContains = LineContains; - vtab->LineCrossing = LineCrossing; - vtab->LineOffset = LineOffset; - vtab->Overlay = Overlay; - vtab->PermAxes = PermAxes; - vtab->PickAxes = PickAxes; - vtab->PrimaryFrame = PrimaryFrame; - vtab->SetAxis = SetAxis; - vtab->SetDigits = SetDigits; - vtab->SetDirection = SetDirection; - vtab->SetDomain = SetDomain; - vtab->SetFormat = SetFormat; - vtab->SetLabel = SetLabel; - vtab->SetMatchEnd = SetMatchEnd; - vtab->SetMaxAxes = SetMaxAxes; - vtab->SetMinAxes = SetMinAxes; - vtab->SetPermute = SetPermute; - vtab->SetPreserveAxes = SetPreserveAxes; - vtab->SetSymbol = SetSymbol; - vtab->SetTitle = SetTitle; - vtab->SetUnit = SetUnit; - vtab->SubFrame = SubFrame; - vtab->TestDigits = TestDigits; - vtab->TestDirection = TestDirection; - vtab->TestDomain = TestDomain; - vtab->TestFormat = TestFormat; - vtab->TestLabel = TestLabel; - vtab->TestMatchEnd = TestMatchEnd; - vtab->TestMaxAxes = TestMaxAxes; - vtab->TestMinAxes = TestMinAxes; - vtab->TestPermute = TestPermute; - vtab->TestPreserveAxes = TestPreserveAxes; - vtab->TestSymbol = TestSymbol; - vtab->TestTitle = TestTitle; - vtab->TestUnit = TestUnit; - vtab->Unformat = Unformat; - vtab->ValidateAxis = ValidateAxis; - vtab->ValidateAxisSelection = ValidateAxisSelection; - vtab->ValidateSystem = ValidateSystem; - vtab->SystemString = SystemString; - vtab->SystemCode = SystemCode; - - vtab->GetFrameFlags = GetFrameFlags; - vtab->SetFrameFlags = SetFrameFlags; - - vtab->TestActiveUnit = TestActiveUnit; - vtab->GetActiveUnit = GetActiveUnit; - vtab->SetActiveUnit = SetActiveUnit; - - vtab->GetFrameVariants = GetFrameVariants; - vtab->SetFrameVariants = SetFrameVariants; - - vtab->ClearSystem = ClearSystem; - vtab->GetSystem = GetSystem; - vtab->SetSystem = SetSystem; - vtab->TestSystem = TestSystem; - - vtab->ClearAlignSystem = ClearAlignSystem; - vtab->GetAlignSystem = GetAlignSystem; - vtab->SetAlignSystem = SetAlignSystem; - vtab->TestAlignSystem = TestAlignSystem; - - vtab->ClearTop = ClearTop; - vtab->GetTop = GetTop; - vtab->SetTop = SetTop; - vtab->TestTop = TestTop; - - vtab->ClearBottom = ClearBottom; - vtab->GetBottom = GetBottom; - vtab->SetBottom = SetBottom; - vtab->TestBottom = TestBottom; - - vtab->ClearEpoch = ClearEpoch; - vtab->GetEpoch = GetEpoch; - vtab->SetEpoch = SetEpoch; - vtab->TestEpoch = TestEpoch; - - vtab->ClearObsLat = ClearObsLat; - vtab->TestObsLat = TestObsLat; - vtab->GetObsLat = GetObsLat; - vtab->SetObsLat = SetObsLat; - - vtab->ClearObsLon = ClearObsLon; - vtab->TestObsLon = TestObsLon; - vtab->GetObsLon = GetObsLon; - vtab->SetObsLon = SetObsLon; - - vtab->ClearObsAlt = ClearObsAlt; - vtab->TestObsAlt = TestObsAlt; - vtab->GetObsAlt = GetObsAlt; - vtab->SetObsAlt = SetObsAlt; - - vtab->ClearDtai = ClearDtai; - vtab->GetDtai = GetDtai; - vtab->SetDtai = SetDtai; - vtab->TestDtai = TestDtai; - - vtab->ClearDut1 = ClearDut1; - vtab->GetDut1 = GetDut1; - vtab->SetDut1 = SetDut1; - vtab->TestDut1 = TestDut1; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_cleanattribs = object->CleanAttribs; - object->CleanAttribs = CleanAttribs; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - mapping = (AstMappingVtab *) vtab; - - object->Equal = Equal; - mapping->GetIsLinear = GetIsLinear; - mapping->GetIsSimple = GetIsSimple; - mapping->GetNin = GetNin; - mapping->GetNout = GetNout; - mapping->ReportPoints = ReportPoints; - mapping->Transform = Transform; - mapping->MapSplit = MapSplit; - mapping->DoNotSimplify = DoNotSimplify; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "Frame", "Coordinate system description" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void Intersect( AstFrame *this, const double a1[2], - const double a2[2], const double b1[2], - const double b2[2], double cross[2], - int *status ) { -/* -*++ -* Name: -c astIntersect -f AST_INTERSECT - -* Purpose: -* Find the point of intersection between two geodesic curves. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c void astIntersect( AstFrame *this, const double a1[2], -c const double a2[2], const double b1[2], -c const double b2[2], double cross[2] ) -f CALL AST_INTERSECT( THIS, A1, A2, B1, B2, CROSS, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* finds the coordinate values at the point of intersection between -* two geodesic curves. Each curve is specified by two points on -* the curve. It can only be used with 2-dimensional Frames. -* -* For example, in a basic Frame, it will find the point of -* intersection between two straight lines. But for a SkyFrame it -* will find an intersection of two great circles. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c a1 -f A1( 2 ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). This should contain the coordinates of the -* first point on the first geodesic curve. -c a2 -f A2( 2 ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). This should contain the coordinates of a -* second point on the first geodesic curve. It should not be -* co-incident with the first point. -c b1 -f B1( 2 ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). This should contain the coordinates of the -* first point on the second geodesic curve. -c b2 -f B2( 2 ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). This should contain the coordinates of a -* second point on the second geodesic curve. It should not be -* co-incident with the first point. -c cross -f CROSS( 2 ) = DOUBLE PRECISION (Returned) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* in which the coordinates of the required intersection will -* be returned. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - For SkyFrames each curve will be a great circle, and in general -* each pair of curves will intersect at two diametrically opposite -* points on the sky. The returned position is the one which is -* closest to point -c "a1". -f A1. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value, or if the two -* points defining either geodesic are co-incident, or if the two -* curves do not intersect. -c - The geodesic curve used by this function is the path of -f - The geodesic curve used by this routine is the path of -* shortest distance between two points, as defined by the -c astDistance function. -f AST_DISTANCE function. -* - An error will be reported if the Frame is not 2-dimensional. -*-- -*/ - -/* Local Variables: */ - double ca; /* Y axis intercept of line a */ - double cb; /* Y axis intercept of line b */ - double dxa; /* X range spanned by line a */ - double dxb; /* X range spanned by line b */ - double ma; /* Gradient of line a */ - double mb; /* Gradient of line b */ - int naxes; /* Number of Frame axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialize bad values. */ - cross[ 0 ] = AST__BAD; - cross[ 1 ] = AST__BAD; - -/* Determine the number of Frame axes. */ - naxes = astGetNaxes( this ); - -/* Report an error if the Frame is not 2 dimensional. */ - if( naxes != 2 && astOK ) { - astError( AST__NAXIN, "astIntersect(%s): Invalid number of Frame axes (%d)." - " astIntersect can only be used with 2 dimensonal Frames.", status, - astGetClass( this ), naxes ); - } - -/* Check that all supplied values are OK. */ - if ( ( a1[ 0 ] != AST__BAD ) && ( a1[ 1 ] != AST__BAD ) && - ( a2[ 0 ] != AST__BAD ) && ( a2[ 1 ] != AST__BAD ) && - ( b1[ 0 ] != AST__BAD ) && ( b1[ 1 ] != AST__BAD ) && - ( b2[ 0 ] != AST__BAD ) && ( b2[ 1 ] != AST__BAD ) ) { - -/* Find the x increments spanned by the two lines. */ - -/* Check the first line is not vertical. */ - dxa = a2[ 0 ] - a1[ 0 ]; - dxb = b2[ 0 ] - b1[ 0 ]; - if( dxa != 0.0 ) { - -/* Find the gradient and Y axis intercept of the first line. */ - ma = ( a2[ 1 ] - a1[ 1 ] )/dxa; - ca = a1[ 1 ] - a1[ 0 ]*ma; - -/* Check the second line is not vertical. */ - if( dxb != 0.0 ) { - -/* Find the gradient and Y axis intercept of the second line. */ - mb = ( b2[ 1 ] - b1[ 1 ] )/dxb; - cb = b1[ 1 ] - b1[ 0 ]*mb; - -/* Check the lines are not parallel. */ - if( ma != mb ) { - -/* Find the intersection of the two lines. */ - cross[ 0 ] = ( cb -ca )/( ma - mb ); - cross[ 1 ] = ( ( ma + mb )*cross[ 0 ] + ca + cb )/2; - } - -/* If the second line is vertical but the first is not. */ - } else if( b1[ 1 ] != b2[ 1 ] ){ - cross[ 0 ] = b1[ 0 ]; - cross[ 1 ] = ma*b1[ 0 ] + ca; - } - -/* First line is vertical but second is not. */ - } else if( dxb != 0.0 && a1[ 1 ] != a2[ 1 ] ){ - -/* Find the gradient and Y axis intercept of the second line. */ - mb = ( b2[ 1 ] - b1[ 1 ] )/dxb; - cb = b1[ 1 ] - b1[ 0 ]*mb; - -/* Find the intercection. */ - cross[ 0 ] = a1[ 0 ]; - cross[ 1 ] = mb*a1[ 0 ] + cb; - } - } -} - -static int IsUnitFrame( AstFrame *this, int *status ){ -/* -*+ -* Name: -* astIsUnitFrame - -* Purpose: -* Is this Frame equivalent to a UnitMap? - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astIsUnitFrame( AstFrame *this ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns a flag indicating if the supplied Frame is -* equivalent to a UnitMap when treated as a Mapping (note, the Frame -* class inherits from Mapping and therefore every Frame is also a Mapping). - -* Parameters: -* this -* Pointer to the Frame. - -* Returned Value: -* A non-zero value is returned if the supplied Frame is equivalent to -* a UnitMap when treated as a Mapping. - -*- -*/ - -/* Check the local error status. */ - if( !astOK ) return 0; - -/* The base Frame class is always equivalent to a UnitMap. */ - return 1; -} - -static int LineContains( AstFrame *this, AstLineDef *l, int def, double *point, int *status ) { -/* -*+ -* Name: -* astLineContains - -* Purpose: -* Determine if a line contains a point. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astLineContains( AstFrame *this, AstLineDef *l, int def, double *point ) - -* Class Membership: -* Frame method. - -* Description: -* This function determines if the supplied point is on the supplied -* line within the supplied Frame. The start point of the line is -* considered to be within the line, but the end point is not. The tests -* are that the point of closest approach of the line to the point should -* be between the start and end, and that the distance from the point to -* the point of closest aproach should be less than 1.0E-7 of the length -* of the line. - -* Parameters: -* this -* Pointer to the Frame. -* l -* Pointer to the structure defining the line. -* def -* Should be set non-zero if the "point" array was created by a -* call to astLineCrossing (in which case it may contain extra -* information following the axis values),and zero otherwise. -* point -* Point to an array containing the axis values of the point to be -* tested, possibly followed by extra cached information (see "def"). - -* Returned Value: -* A non-zero value is returned if the line contains the point. - -* Notes: -* - The pointer supplied for "l" should have been created using the -* astLineDef method. These structures contained cached information about -* the lines which improve the efficiency of this method when many -* repeated calls are made. An error will be reported if the structure -* does not refer to the Frame specified by "this". -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - int result; - double dx, dy, p; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check that the line refers to the supplied Frame. */ - if( l->frame != this ) { - astError( AST__INTER, "astLineContains(%s): The supplied line does " - "not relate to the supplied %s (AST internal programming " - "error).", status, astGetClass( this ), astGetClass( this ) ); - -/* If the point is good, find the offsets from the start of the line. */ - } else if( point[ 0 ] != AST__BAD && point[ 1 ] != AST__BAD ) { - dx = point[ 0 ] - l->start[ 0 ]; - dy = point[ 1 ] - l->start[ 1 ]; - -/* Check the nearest point on the line is between the start and end. - Exclude the end point. */ - p = dx*l->dir[ 0 ] + dy*l->dir[ 1 ]; - if( p >= 0.0 && p < l->length ) { - -/* Check the distance from the point to the nearest point on the line is not - further than 1.0E-7 of the length of the line. */ - if( fabs( dx*l->q[ 0 ] + dy*l->q[ 1 ] ) <= 1.0E-7*l->length ) { - result = 1; - } - } - } - -/* Return zero if an error occurred. */ - if( !astOK ) result = 0; - -/* Return a pointer to the output structure. */ - return result; -} - -static int LineCrossing( AstFrame *this, AstLineDef *l1, AstLineDef *l2, - double **cross, int *status ) { -/* -*+ -* Name: -* astLineCrossing - -* Purpose: -* Determine if two lines cross. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astLineCrossing( AstFrame *this, AstLineDef *l1, AstLineDef *l2, -* double **cross ) - -* Class Membership: -* Frame method. - -* Description: -* This function determines if the two suplied line segments cross, -* and if so returns the axis values at the point where they cross. -* A flag is also returned indicating if the crossing point occurs -* within the length of both line segments, or outside one or both of -* the line segments. - -* Parameters: -* this -* Pointer to the Frame. -* l1 -* Pointer to the structure defining the first line. -* l2 -* Pointer to the structure defining the second line. -* cross -* Pointer to a location at which to put a pointer to a dynamically -* alocated array containing the axis values at the crossing. If -* NULL is supplied no such array is returned. Otherwise, the returned -* array should be freed using astFree when no longer needed. If the -* lines are parallel (i.e. do not cross) then AST__BAD is returned for -* all axis values. Note usable axis values are returned even if the -* lines cross outside the segment defined by the start and end points -* of the lines. The order of axes in the returned array will take -* account of the current axis permutation array if appropriate. Note, -* sub-classes such as SkyFrame may append extra values to the end -* of the basic frame axis values. A NULL pointer is returned if an -* error occurs. - -* Returned Value: -* A non-zero value is returned if the lines cross at a point which is -* within the [start,end) segment of the lines that are flagged as -* finite (if a line is marked as infinite any crossing is assumed to -* be within the bounds of the line). If the crossing point is outside -* this segment on either (inifinte) line, or if the lines are parallel, -* zero is returned. Note, the start point is considered to be inside -* the length of the segment, but the end point is outside. - -* Notes: -* - The pointers supplied for "l1" and "l2" should have been created -* using the astLineDef method. These structures contained cached -* information about the lines which improve the efficiency of this method -* when many repeated calls are made. An error will be reported if -* either structure does not refer to the Frame specified by "this". -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - double *crossing; /* Returned array */ - double den; /* Denominator */ - double dx; /* Offset in start X values */ - double dy; /* Offset in start Y values */ - double t1; /* Distance from start of line 1 to crossing */ - double t2; /* Distance from start of line 2 to crossing */ - int result; /* Returned value */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise. */ - result = 0; - crossing = astMalloc( sizeof(double)*2 ); - -/* Check that both lines refer to the supplied Frame. */ - if( l1->frame != this ) { - astError( AST__INTER, "astLineCrossing(%s): First supplied line does " - "not relate to the supplied %s (AST internal programming " - "error).", status, astGetClass( this ), astGetClass( this ) ); - - } else if( l2->frame != this ) { - astError( AST__INTER, "astLineCrossing(%s): Second supplied line does " - "not relate to the supplied %s (AST internal programming " - "error).", status, astGetClass( this ), astGetClass( this ) ); - - } else if( crossing ){ - -/* Each of the lines can be represented as "p = start + t.v" where start is - the start position, v is the unit vector pointing from start to end, - and t is the scalar distance from the start position. So to find the - intersection put "start1 + t1.v1 = start2 + t2.v2" and solve for t1 - and t2. */ - den = (l1->dir[ 0 ])*(l2->dir[ 1 ]) - (l2->dir[ 0 ])*(l1->dir[ 1 ]); - if( den != 0.0 ) { - dx = l2->start[ 0 ] - l1->start[ 0 ]; - dy = l2->start[ 1 ] - l1->start[ 1 ]; - t1 = ( l2->dir[ 1 ]*dx - l2->dir[ 0 ]*dy )/den; - t2 = ( l1->dir[ 1 ]*dx - l1->dir[ 0 ]*dy )/den; - -/* Store the crossing point, using the smaller t value to redue error. */ - if( fabs( t1 ) < fabs( t2 ) ) { - crossing[ 0 ] = l1->start[ 0 ] + t1*l1->dir[ 0 ]; - crossing[ 1 ] = l1->start[ 1 ] + t1*l1->dir[ 1 ]; - } else { - crossing[ 0 ] = l2->start[ 0 ] + t2*l2->dir[ 0 ]; - crossing[ 1 ] = l2->start[ 1 ] + t2*l2->dir[ 1 ]; - } - -/* See if the intersection is within the length of both lines (excluding - the end points). If a line is flagged as infinite, set the "t" parameter - to zero to make it look like the crossing is within the line. */ - if( l1->infinite ) t1 = 0.0; - if( l2->infinite ) t2 = 0.0; - - if( t1 >= 0.0 && t1 < l1->length && - t2 >= 0.0 && t2 < l2->length ) result = 1; - - } else { - crossing[ 0 ] = AST__BAD; - crossing[ 1 ] = AST__BAD; - } - } - -/* Return zero if an error occurred. */ - if( !astOK ) { - crossing = astFree( crossing ); - result = 0; - } - -/* Return the crossing pointer. */ - if( cross ) { - *cross = crossing; - } else if( crossing ){ - crossing = astFree( crossing ); - } - -/* Return a pointer to the output structure. */ - return result; -} - -static AstLineDef *LineDef( AstFrame *this, const double start[2], - const double end[2], int *status ) { -/* -*+ -* Name: -* astLineDef - -* Purpose: -* Creates a structure describing a line segment in a 2D Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* AstLineDef *astLineDef( AstFrame *this, const double start[2], -* const double end[2] ) - -* Class Membership: -* Frame method. - -* Description: -* This function creates a structure containing information describing a -* given line segment within the supplied 2D Frame. This may include -* information which allows other methods such as astLineCrossing to -* function more efficiently. Thus the returned structure acts as a -* cache to store intermediate values used by these other methods. - -* Parameters: -* this -* Pointer to the Frame. Must have 2 axes. -* start -* An array of 2 doubles marking the start of the line segment. -* end -* An array of 2 doubles marking the end of the line segment. - -* Returned Value: -* Pointer to the memory structure containing the description of the -* line. This structure should be freed using astFree when no longer -* needed. A NULL pointer is returned (without error) if any of the -* supplied axis values are AST__BAD. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstLineDef *result; /* Pointer to output structure */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check the Frame has 2 axes. */ - if( astGetNaxes( this ) != 2 ) { - astError( AST__INTER, "astLineDef(%s): The supplied %s is not 2 " - "dimensional (internal AST proramming error).", status, - astGetClass( this ), astGetClass( this ) ); - } - -/* Check the axis values are good */ - if( start[ 0 ] != AST__BAD && start[ 1 ] != AST__BAD && - end[ 0 ] != AST__BAD && end[ 1 ] != AST__BAD ) { - -/* Allocate memory for the returned structure. */ - result = astMalloc( sizeof( AstLineDef ) ); - if( result ) { - -/* Store the supplied axis values in the returned structure. */ - result->start[ 0 ] = start[ 0 ]; - result->start[ 1 ] = start[ 1 ]; - result->end[ 0 ] = end[ 0 ]; - result->end[ 1 ] = end[ 1 ]; - -/* Store the length of the line segment. */ - result->length = astDistance( this, start, end ); - -/* Store a unit vector pointing from the start to the end. */ - if( result->length > 0.0 ) { - result->dir[ 0 ] = ( end[ 0 ] - start[ 0 ] )/result->length; - result->dir[ 1 ] = ( end[ 1 ] - start[ 1 ] )/result->length; - } else { - result->dir[ 0 ] = 1.0; - result->dir[ 1 ] = 0.0; - } - -/* Store a unit vector perpendicular to the line, such that the vector - points to the left, as vewied from the observer, when moving from the - start to the end of the line. */ - result->q[ 0 ] = -result->dir[ 1 ]; - result->q[ 1 ] = result->dir[ 0 ]; - -/* Store a pointer to the defining Frame. */ - result->frame = this; - -/* Indicate that the line is considered to be terminated at the start and - end points. */ - result->infinite = 0; - } - } - -/* Free the returned pointer if an error occurred. */ - if( !astOK ) result = astFree( result ); - -/* Return a pointer to the output structure. */ - return result; -} - -static void LineOffset( AstFrame *this, AstLineDef *line, double par, - double prp, double point[2], int *status ){ -/* -*+ -* Name: -* astLineOffset - -* Purpose: -* Find a position close to a line. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void LineOffset( AstFrame *this, AstLineDef *line, double par, -* double prp, double point[2] ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns a position formed by moving a given distance along -* the supplied line, and then a given distance away from the supplied line. - -* Parameters: -* this -* Pointer to the Frame. -* line -* Pointer to the structure defining the line. -* par -* The distance to move along the line from the start towards the end. -* prp -* The distance to move at right angles to the line. Positive -* values result in movement to the left of the line, as seen from -* the observer, when moving from start towards the end. - -* Notes: -* - The pointer supplied for "line" should have been created using the -* astLineDef method. This structure contains cached information about the -* line which improves the efficiency of this method when many repeated -* calls are made. An error will be reported if the structure does not -* refer to the Frame specified by "this". -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check that the line refers to the supplied Frame. */ - if( line->frame != this ) { - astError( AST__INTER, "astLineOffset(%s): The supplied line does " - "not relate to the supplied %s (AST internal programming " - "error).", status, astGetClass( this ), astGetClass( this ) ); - -/* This implementation uses simple flat geometry. */ - } else { - point[ 0 ] = line->start[ 0 ] + par*line->dir[ 0 ] + prp*line->q[ 0 ]; - point[ 1 ] = line->start[ 1 ] + par*line->dir[ 1 ] + prp*line->q[ 1 ]; - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* CmpMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstFrame *this; /* Pointer to Frame structure */ - int i; /* Loop count */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the Frame structure. */ - this = (AstFrame *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - for( i = 0; i < this->naxes; i++ ) { - if( !result ) result = astManageLock( this->axis[ i ], mode, extra, - fail ); - } - if( this->variants && !result ) result = astManageLock( this->variants, mode, - extra, fail ); - - return result; - -} -#endif - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* Frame method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing Frame. This is only possible if the specified inputs -* correspond to some subset of the Frame outputs. That is, there -* must exist a subset of the Frame outputs for which each output -* depends only on the selected Frame inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied Frame, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the Frame to be split (the Frame is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied Frame, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied Frame has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied Frame. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - int *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Pick the selected axes from the Frame. */ - *map = (AstMapping *) astPickAxes( (AstFrame *) this_map, nin, in, NULL ); - -/* Return a copy of the supplied axis array.*/ - result = astStore( NULL, in, sizeof( int )*(size_t) nin ); - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static int Match( AstFrame *template, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, - AstMapping **map, AstFrame **result, int *status ) { -/* -*+ -* Name: -* astMatch - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astMatch( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result ) - -* Class Membership: -* Frame method. - -* Description: -* This function matches a "template" frame to a "target" frame and -* determines whether it is possible to convert coordinates between -* them. If it is, a mapping that performs the transformation is -* returned along with a new Frame that describes the coordinate -* system that results when this mapping is applied to the "target" -* coordinate system. In addition, information is returned to allow -* the axes in this "result" Frame to be associated with the -* corresponding axes in the "target" and "template" Frames from -* which they are derived. - -* Parameters: -* template -* Pointer to the template Frame. This describes the coordinate -* system (or set of possible coordinate systems) into which we -* wish to convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate -* system in which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case (i.e. if the -* target is of a more specialised class than the template). In -* this latter case, the target is cast down to the class of the -* template. NOTE, this argument is handled by the global method -* wrapper function "astMatch_", rather than by the class-specific -* implementations of this method. -* template_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* template Frame axis from which it is derived. If it is not -* derived from any template frame axis, a value of -1 will be -* returned instead. -* target_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* target Frame axis from which it is derived. If it is not -* derived from any target Frame axis, a value of -1 will be -* returned instead. -* map -* Address of a location where a pointer to a new Mapping will -* be returned if the requested coordinate conversion is -* possible. If returned, the forward transformation of this -* Mapping may be used to convert coordinates between the -* "target" Frame and the "result" Frame (see below) and the -* inverse transformation will convert in the opposite -* direction. -* result -* Address of a location where a pointer to a new Frame will be -* returned if the requested coordinate conversion is -* possible. If returned, this Frame describes the coordinate -* system that results from applying the returned Mapping -* (above) to the "target" coordinate system. In general, this -* Frame will combine attributes from (and will therefore be -* more specific than) both the target and the template -* Frames. In particular, when the template allows the -* possibility of transformaing to any one of a set of -* alternative coordinate systems, the "result" Frame will -* indicate which of the alternatives was used. - -* Returned Value: -* A non-zero value is returned if the requested coordinate -* conversion is possible. Otherwise zero is returned (this will -* not in itself result in an error condition). - -* Notes: -* - By default, the "result" frame will have its number of axes -* and axis order determined by the "template" Frame. However, if -* the PreserveAxes attribute of the template frame is non-zero, -* then the axis count and axis order of the "target" frame will be -* used instead. -* - The template_axes and target_axes arrays are provided so that -* if the caller needs to permute the target and/or template axes -* before invoking this function, it is possible to deduce how the -* result axes should be permuted so as to correspond with the -* original template/target axis order. -* - For result axes that do not correspond with a template and/or -* target axis (where a value of -1 is returned in the -* template_axes and/or target_axes arrays), the caller has no -* clear way of knowing where these axes should appear in any -* permuted order. In this case, the relative position of these -* axes within the result Frame (with respect to axes that do have -* template/target axis associations) will be used to convey this -* information. Such axes should be taken to be associated either -* with the next preceding or following axis (depending on the -* AST__MATCHEND flag of the template frame) which does have an -* association. -* - If the result Frame has zero axes, then NULL pointer values -* will be returned for *template_axes and *target_axes. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* This implementation addresses the matching of a Frame class -* object to other types of Frames (i.e. the target may be from a -* derived class). A Frame will match any other type of Frame with -* an acceptable number of axes but will not distinguish axis order -* (i.e. it will match the axes in whatever order they are -* given). If the template Frame has a value set for its Domain -* attribute, then it will only match another Frame with the same -* Domain. -*/ - -/* Local Variables: */ - char *template_domain; /* Pointer to copy of template domain */ - const char *ptr; /* Pointer to domain string */ - const char *target_domain; /* Pointer to target domain string */ - int match; /* Template matches target? */ - int match_end; /* Match final axes of target? */ - int max_axes; /* Maximum acceptable number of axes */ - int min_axes; /* Minimum acceptable nu,ber of axes */ - int preserve_axes; /* Preserve target axes? */ - int result_axis; /* Loop counter for result axes */ - int result_naxes; /* Number of result axes */ - int target_naxes; /* Number of target axes */ - int template_naxes; /* Number of template axes */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* The first requirement for a match is that the target object is a Frame. This - is already known to be true, as it forms part of the argument validation - for this function. */ - -/* The second requirement is that the number of target axes is acceptable. - Obtain the number of target axes and the minimum and maximum number of axes - that the template will match. */ - target_naxes = astGetNaxes( target ); - min_axes = astGetMinAxes( template ); - max_axes = astGetMaxAxes( template ); - -/* Test if the number of target axes is acceptable. */ - if ( astOK ) { - match = ( ( target_naxes >= min_axes ) && ( target_naxes <= max_axes ) ); - } - -/* The third requirement is that if the template has its Domain - attribute defined, then the target must also have the same Domain - (although it need not be set - the default will do). First check if - the template has a domain. */ - if ( astOK && match ) { - if ( astTestDomain( template ) ) { - -/* Obtain a pointer to the template domain. Then allocate memory and - make a copy of it (this is necessary as we will next inquire the - domain of the target and may over-write the buffer holding the - template's domain). */ - ptr = astGetDomain( template ); - if ( astOK ) { - template_domain = astStore( NULL, ptr, - strlen( ptr ) + (size_t) 1 ); - -/* Obtain a pointer to the target domain. */ - target_domain = astGetDomain( target ); - -/* Compare the domain strings for equality. Then free the memory - allocated above. */ - match = astOK && !strcmp( template_domain, target_domain ); - template_domain = astFree( template_domain ); - } - } - } - -/* If the template matches, obtain the values of the template's PreserveAxes - and MatchEnd attributes and determine the number of template axes. */ - if ( astOK && match ) { - preserve_axes = astGetPreserveAxes( template ); - match_end = astGetMatchEnd( template ); - template_naxes = astGetNaxes( template ); - -/* If the PreserveAxes attribute is non-zero, the target axes should be - preserved, so the number of result axes equals the number of target axes. - Otherwise the number of template axes is used. */ - result_naxes = preserve_axes ? target_naxes : template_naxes; - -/* Allocate memory for the arrays of axis associations to be returned. */ - *template_axes = astMalloc( sizeof( int ) * (size_t) result_naxes ); - *target_axes = astMalloc( sizeof( int ) * (size_t) result_naxes ); - if ( astOK ) { - -/* Loop through each of the result axes. */ - for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) { - -/* Set up the axis associations. By default, associate the first result axis - with the first template/target axis. */ - (*template_axes)[ result_axis ] = result_axis; - (*target_axes)[ result_axis ] = result_axis; - -/* However, if the MatchEnd attribute is non-zero, associate the last result - axis with the last template/target axis (this only makes a difference if - there is a difference in the number of axes). */ - if ( match_end ) { - (*template_axes)[ result_axis ] += - template_naxes - result_naxes; - (*target_axes)[ result_axis ] += target_naxes - result_naxes; - } - -/* If any of the associations would be with a template/target axis that doesn't - exist, then use an axis index of -1 for the association instead. */ - if ( ( (*template_axes)[ result_axis ] < 0 ) || - ( (*template_axes)[ result_axis ] >= template_naxes ) ) { - (*template_axes)[ result_axis ] = -1; - } - if ( ( (*target_axes)[ result_axis ] < 0 ) || - ( (*target_axes)[ result_axis ] >= target_naxes ) ) { - (*target_axes)[ result_axis ] = -1; - } - } - -/* Use the target's astSubFrame method to select the required axes from it, - overlaying the template's attributes on to the resulting Frame. This process - also generates the required Mapping between the target and result Frames. */ - match = astSubFrame( target, template, - result_naxes, *target_axes, *template_axes, - map, result ); - } - } - -/* If an error occurred, free any allocated memory and reset the result. */ - if ( !astOK || !match ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static void MatchAxes( AstFrame *frm1, AstFrame *frm2, int *axes, - int *status ) { -/* -*++ -* Name: -c astMatchAxes -f AST_MATCHAXES - -* Purpose: -* Find any corresponding axes in two Frames. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c void astMatchAxes( AstFrame *frm1, AstFrame *frm2, int *axes ) -f CALL AST_MATCHAXES( FRM1, FRM2, AXES, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -* This function looks for corresponding axes within two supplied -* Frames. An array of integers is returned that contains an element -* for each axis in the second supplied Frame. An element in this array -* will be set to zero if the associated axis within the second Frame -* has no corresponding axis within the first Frame. Otherwise, it -* will be set to the index (a non-zero positive integer) of the -* corresponding axis within the first supplied Frame. - -* Parameters: -c frm1 -f FRM1 = INTEGER (Given) -* Pointer to the first Frame. -c frm2 -f FRM2 = INTEGER (Given) -* Pointer to the second Frame. -c axes -f AXES = INTEGER( * ) (Returned) -c Pointer to an -f An -* integer array in which to return the indices of the axes (within -* the first Frame) that correspond to each axis within the second -* Frame. Axis indices start at 1. A value of zero will be stored -* in the returned array for each axis in the second Frame that has -* no corresponding axis in the first Frame. -* -* The number of elements in this array must be greater than or -* equal to the number of axes in the second Frame. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Frame -* This function applies to all Frames. - -* Notes: -* - Corresponding axes are identified by the fact that a Mapping can -* be found between them using -c astFindFrame or astConvert. -f AST_FINDFRAME or AST_CONVERT. -* Thus, "corresponding axes" are not necessarily identical. For -* instance, SkyFrame axes in two Frames will match even if they -* describe different celestial coordinate systems -*-- - -* Implementation Notes: -* This function is simply a wrap-up for the protected astMatchAxesX -* method which performs the required processing but swaps the order -* of the first two arguments. This is a trick to allow the -* astMatchAxes method to be over-ridden by derived classes on the -* basis of the class of either of the first two arguments. -* -* In practice, each class that represents an encapsulated Frame (e.g. -* FrameSet, Region, etc) should over-ride this method, extracting a -* Frame from the supplied "frm1" pointer, and then invoking -* astMatchAxesX. - -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the "astMatchAxesX" method with the first two arguments - swapped. */ - astMatchAxesX( frm2, frm1, axes ); -} - -static void MatchAxesX( AstFrame *frm2, AstFrame *frm1, int *axes, - int *status ) { -/* -*+ -* Name: -* astMatchAxesX - -* Purpose: -* Find any corresponding axes in two Frames. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void astMatchAxesX( AstFrame *frm2, AstFrame *frm1, int *axes ) - -* Class Membership: -* Frame method. - -* Description: -* This function performs the processing for the public astMatchAxes -* method and has exactly the same interface except that the order -* of the first two arguments is swapped. This is a trick to allow -* the astMatchAxes method to be over-ridden by derived classes on -* the basis of the class of either of its first two arguments. -* -* See the astMatchAxes method for details of the interface. -*- -*/ - -/* Local Variables: */ - AstFrame *pfrm; - AstFrame *resfrm; - AstMapping *resmap; - int *frm1_axes; - int *pfrm_axes; - int ifirst; - int max_axes; - int min_axes; - int nax2; - int pax; - int preserve_axes; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Temporarily ensure that the PreserveAxes attribute is non-zero in - the second supplied Frame. This means thte result Frame returned by - astMatch below will have the axis count and order of the target Frame - (i.e. "pfrm"). */ - if( astTestPreserveAxes( frm1 ) ) { - preserve_axes = astGetPreserveAxes( frm1 ) ? 1 : 0; - } else { - preserve_axes = -1; - } - astSetPreserveAxes( frm1, 1 ); - -/* Temporarily ensure that the MaxAxes and MinAxes attributes in the - second supplied Frame are set so the Frame can be used as a template - in astMatch for matching any number of axes. */ - if( astTestMaxAxes( frm1 ) ) { - max_axes = astGetMaxAxes( frm1 ); - } else { - max_axes = -1; - } - astSetMaxAxes( frm1, 10000 ); - - if( astTestMinAxes( frm1 ) ) { - min_axes = astGetMinAxes( frm1 ); - } else { - min_axes = -1; - } - astSetMinAxes( frm1, 1 ); - -/* Get the number of axes in the frm2 Frame. */ - nax2 = astGetNaxes( frm2 ); - -/* Loop round the axes in the frm2 Frame. */ - for( ifirst = 0; ifirst < nax2; ifirst++ ) { - -/* Identify the primary Frame defining the current axis in the frm2 - Frame. */ - astPrimaryFrame( frm2, ifirst, &pfrm, &pax ); - -/* Attempt to find a sub-frame within the frm1 Frame that corresponds to - this primary Frame. */ - if( astMatch( frm1, pfrm, 1, &frm1_axes, &pfrm_axes, &resmap, &resfrm ) ) { - -/* Store the one-based index within "frm1" of the corresponding axis. */ - axes[ ifirst ] = frm1_axes[ pax ] + 1; - -/* Free resources */ - frm1_axes = astFree( frm1_axes ); - pfrm_axes = astFree( pfrm_axes ); - resmap = astAnnul( resmap ); - resfrm = astAnnul( resfrm ); - -/* If no corresponding axis was found store zero in the returned array. */ - } else { - axes[ ifirst ] = 0; - } - -/* Free resouces. */ - pfrm = astAnnul( pfrm ); - } - -/* Re-instate the original attribute values in the frm1 Frame. */ - if( preserve_axes == -1 ) { - astClearPreserveAxes( frm1 ); - } else { - astSetPreserveAxes( frm1, preserve_axes ); - } - - if( max_axes == -1 ) { - astClearMaxAxes( frm1 ); - } else { - astSetMaxAxes( frm1, max_axes ); - } - - if( min_axes == -1 ) { - astClearMinAxes( frm1 ); - } else { - astSetMinAxes( frm1, min_axes ); - } -} - -static void NewUnit( AstAxis *ax, const char *old_units, const char *new_units, - const char *method, const char *class, int *status ) { -/* -* Name: -* NewUnit - -* Purpose: -* Modify an Axis Label and Symbol to reflect a new Unit value. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* void NewUnit( AstAxis *ax, const char *old_units, const char *new_units, -* const char *method, const char *class ) - -* Class Membership: -* Frame method. - -* Description: -* This function modifies the Label and Symbol attributes of an Axis -* to reflect a new Unit value. This function should only be called if -* the ActiveUnit flag of the parent Frame is non-zero (this is not -* checked within this function). -* -* If the axis has a set label, then we may be able to modify it to -* correctly describe the axis in the supplied new units. For instance, -* if the original units were "Hz", the original label was "frequency", -* and the new units are "log(Hz)", then the label is modified to become -* "log( frequency )". -* -* The Axis Format attribute is cleared if the supplied units are -* different to the old units (because any set format is probably not -* going to be appropriate for a new system of units. - -* Parameters: -* ax -* Pointer to the Axis. -* old_units -* The original units value. -* new_units -* The new units value. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis selection. This method name is used -* solely for constructing error messages. -* class -* Pointer to a constant null-terminated character string -* containing the name of the class upon which this function -* was invoked. This is used solely for constructing error messages. - -* Returned Value: -* void. -*/ - -/* Local Variables: */ - AstMapping *map; /* Pointer to units Mapping */ - char *new_lab; /* Pointer to new axis label */ - char *new_sym; /* Pointer to new axis symbol */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check that the axis label is set. We relay on sub-classes to return - appropriate default labels if the label is not set. */ - if( astTestAxisLabel( ax ) ) { - -/* See if it is possible to map the old units into the new units. - If it is, then a Mapping is returned together with an appropriately - modified label. */ - map = astUnitMapper( old_units, new_units, astGetAxisLabel( ax ), - &new_lab ); - -/* If succesfull, annul the Mapping (which we do not need), and store the - modified label in the Axis, finally freeing the memory used to hold - the modified label. */ - if( map ) { - map = astAnnul( map ); - if( new_lab ) { - astSetAxisLabel( ax, new_lab ); - new_lab = astFree( new_lab ); - } - } - } - -/* Do the same for the axis symbol. */ - if( astTestAxisSymbol( ax ) ) { - map = astUnitMapper( old_units, new_units, astGetAxisSymbol( ax ), - &new_sym ); - if( map ) { - map = astAnnul( map ); - if( new_sym ) { - astSetAxisSymbol( ax, new_sym ); - new_sym = astFree( new_sym ); - } - } - } - -/* If succesful, clear the axis format if the new and old units are - different. */ - if( astOK ) { - if( strcmp( old_units, new_units ) ) astClearAxisFormat( ax ); - } - -} - -static void Norm( AstFrame *this, double value[], int *status ) { -/* -*++ -* Name: -c astNorm -f AST_NORM - -* Purpose: -* Normalise a set of Frame coordinates. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c void astNorm( AstFrame *this, double value[] ) -f CALL AST_NORM( THIS, VALUE, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function normalises a set of Frame coordinate values which -f This routine normalises a set of Frame coordinate values which -* might be unsuitable for display (e.g. may lie outside the -* expected range) into a set of acceptable values suitable for -* display. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c value -f VALUE( * ) = DOUBLE PRECISION (Given and Returned) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* coordinate values representing a point in the space which the -* Frame describes. If these values lie outside the expected -* range for the Frame, they will be replaced with more -* acceptable (normalised) values. Otherwise, they will be -* returned unchanged. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - For some classes of Frame, whose coordinate values are not -* constrained, this function will never modify the values -* supplied. However, for Frames whose axes represent cyclic -* quantities (such as angles or positions on the sky), coordinates -* will typically be wrapped into an appropriate standard range, -* such as zero to 2*pi. -* - The NormMap class is a Mapping which can be used to normalise a -* set of points using the -c astNorm function -f AST_NORM routine -* of a specified Frame. -* - It is intended to be possible to put any set of coordinates -* into a form suitable for display by using this function to -* normalise them, followed by appropriate formatting -c (using astFormat). -f (using AST_FORMAT). -*-- -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - int axis; /* Loop counter for axes */ - int naxes; /* Number of Frame axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the number of Frame axes. */ - naxes = astGetNaxes( this ); - -/* Loop to process the coordinate for each axis in turn. */ - for ( axis = 0; axis < naxes; axis++ ) { - -/* Obtain a pointer to the relevant Frame Axis. */ - ax = astGetAxis( this, axis ); - -/* Normalise the coordinate for this axis. */ - astAxisNorm( ax, value + axis ); - -/* Annul the pointer to the Axis. */ - ax = astAnnul( ax ); - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } -} - -static void NormBox( AstFrame *this, double lbnd[], double ubnd[], - AstMapping *reg, int *status ) { -/* -*+ -* Name: -* astNormBox - -* Purpose: -* Extend a box to include effect of any singularities in the Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void astNormBox( AstFrame *this, double lbnd[], double ubnd[], -* AstMapping *reg ) - -* Class Membership: -* Frame method. - -* Description: -* This function modifies a supplied box to include the effect of any -* singularities in the co-ordinate system represented by the Frame. -* For a normal Cartesian coordinate system, the box will be returned -* unchanged. Other classes of Frame may do other things. For instance, -* a SkyFrame will check to see if the box contains either the north -* or south pole and extend the box appropriately. - -* Parameters: -* this -* Pointer to the Frame. -* lbnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* lower axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* ubnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* upper axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* reg -* A Mapping which should be used to test if any singular points are -* inside or outside the box. The Mapping should leave an input -* position unchanged if the point is inside the box, and should -* set all bad if the point is outside the box. -*- -*/ - -/* This base class returns the box limits unchanged. */ -} - -static double Offset2( AstFrame *this, const double point1[2], double angle, - double offset, double point2[2], int *status ){ -/* -*++ -* Name: -c astOffset2 -f AST_OFFSET2 - -* Purpose: -* Calculate an offset along a geodesic curve in a 2D Frame. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c double astOffset2( AstFrame *this, const double point1[2], double angle, -c double offset, double point2[2] ); -f RESULT = AST_OFFSET2( THIS, POINT1, ANGLE, OFFSET, POINT2, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function finds the Frame coordinate values of a point which -f This routine finds the Frame coordinate values of a point which -* is offset a specified distance along the geodesic curve at a -* given angle from a specified starting point. It can only be -* used with 2-dimensional Frames. -* -* For example, in a basic Frame, this offset will be along the -* straight line joining two points. For a more specialised Frame -* describing a sky coordinate system, however, it would be along -* the great circle passing through two sky positions. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c point1 -f POINT1( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). This should contain the coordinates of the -* point marking the start of the geodesic curve. -c angle -f ANGLE = DOUBLE PRECISION (Given) -* The angle (in radians) from the positive direction of the second -* axis, to the direction of the required position, as seen from -* the starting position. Positive rotation is in the sense of -* rotation from the positive direction of axis 2 to the positive -* direction of axis 1. -c offset -f OFFSET = DOUBLE PRECISION -* The required offset from the first point along the geodesic -* curve. If this is positive, it will be in the direction of the -* given angle. If it is negative, it will be in the opposite -* direction. -c point2 -f POINT2( * ) = DOUBLE PRECISION (Returned) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* in which the coordinates of the required point will be returned. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astOffset2 -f AST_OFFSET2 = DOUBLE PRECISION -* The direction of the geodesic curve at the end point. That is, the -* angle (in radians) between the positive direction of the second -* axis and the continuation of the geodesic curve at the requested -* end point. Positive rotation is in the sense of rotation from -* the positive direction of axis 2 to the positive direction of axis -* 1. - -* Notes: -c - The geodesic curve used by this function is the path of -f - The geodesic curve used by this routine is the path of -* shortest distance between two points, as defined by the -c astDistance function. -f AST_DISTANCE function. -* - An error will be reported if the Frame is not 2-dimensional. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -*-- -*/ - -/* Local Variables: */ - int naxes; /* Number of Frame axes */ - double result; /* Returned value */ - -/* Check the global error status. */ - result = AST__BAD; - if ( !astOK ) return result; - -/* Initialize bad values. */ - point2[ 0 ] = AST__BAD; - point2[ 1 ] = AST__BAD; - -/* Determine the number of Frame axes. */ - naxes = astGetNaxes( this ); - -/* Report an error if the Frame is not 2 dimensional. */ - if( naxes != 2 && astOK ) { - astError( AST__NAXIN, "astOffset2(%s): Invalid number of Frame axes (%d)." - " astOffset2 can only be used with 2 dimensonal Frames.", status, - astGetClass( this ), naxes ); - } - -/* Check the supplied values. */ - if ( astOK && point1[ 0 ] != AST__BAD && point1[ 1 ] != AST__BAD && - angle != AST__BAD && offset != AST__BAD ) { - -/* Store the results. */ - point2[ 0 ] = point1[ 0 ] + sin( angle )*offset; - point2[ 1 ] = point1[ 1 ] + cos( angle )*offset; - -/* The position angle of the curve does not vary in cartesian coordinates */ - result = angle; - - } - -/* Return the result. */ - return result; - -} - -static void Offset( AstFrame *this, const double point1[], - const double point2[], double offset, double point3[], int *status ) { -/* -*++ -* Name: -c astOffset -f AST_OFFSET - -* Purpose: -* Calculate an offset along a geodesic curve. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c void astOffset( AstFrame *this, -c const double point1[], const double point2[], -c double offset, double point3[] ) -f CALL AST_OFFSET( THIS, POINT1, POINT2, OFFSET, POINT3, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function finds the Frame coordinate values of a point which -f This routine finds the Frame coordinate values of a point which -* is offset a specified distance along the geodesic curve between -* two other points. -* -* For example, in a basic Frame, this offset will be along the -* straight line joining two points. For a more specialised Frame -* describing a sky coordinate system, however, it would be along -* the great circle passing through two sky positions. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c point1 -f POINT1( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). This should contain the coordinates of the -* point marking the start of the geodesic curve. -c point2 -f POINT2( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis. -* This should contain the coordinates of the point marking the -* end of the geodesic curve. -c offset -f OFFSET = DOUBLE PRECISION -* The required offset from the first point along the geodesic -* curve. If this is positive, it will be towards the second -* point. If it is negative, it will be in the opposite -* direction. This offset need not imply a position lying -* between the two points given, as the curve will be -* extrapolated if necessary. -c point3 -f POINT3( * ) = DOUBLE PRECISION (Returned) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* in which the coordinates of the required point will be returned. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - The geodesic curve used by this function is the path of -f - The geodesic curve used by this routine is the path of -* shortest distance between two points, as defined by the -c astDistance function. -f AST_DISTANCE function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -* - "Bad" coordinate values will also be returned if the two -* points supplied are coincident (or otherwise fail to uniquely -* specify a geodesic curve) but the requested offset is non-zero. -*-- -*/ - -/* Local Variables: */ - double delta; /* Displacement along axis */ - double dist; /* Distance between points */ - double fract; /* Fraction of distance required */ - int axis; /* Loop counter for axes */ - int naxes; /* Number of Frame axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Determine the number of Frame axes. */ - naxes = astGetNaxes( this ); - if ( astOK ) { - -/* Loop to determine the Cartesian distance between points 1 and 2. */ - dist = 0.0; - for ( axis = 0; axis < naxes; axis++ ) { - -/* If any of the coordinates supplied is bad, set the distance to be - bad and quit looping. */ - if ( ( point1[ axis ] == AST__BAD ) || - ( point2[ axis ] == AST__BAD ) ) { - dist = AST__BAD; - break; - -/* Otherwise, accumulate the sum of squared displacements along each - axis. */ - } else { - delta = point1[ axis ] - point2[ axis ]; - dist += ( delta * delta ); - } - } - -/* Take the square root to find the distance (if valid). */ - if ( dist != AST__BAD ) dist = sqrt( dist ); - -/* If the distance between the points cannot be found, or the distance - is zero but the required offset is non-zero, then set the result - coordinates to be bad. */ - if ( ( dist == AST__BAD ) || - ( ( dist == 0.0 ) && ( offset != 0.0 ) ) ) { - for ( axis = 0; axis < naxes; axis++ ) { - point3[ axis ] = AST__BAD; - } - -/* Otherwise, calculate what fraction of the distance between the - points we need to move, and apply this fraction of the displacement - along each axis. */ - } else { - fract = ( dist == 0.0 ) ? 0.0 : offset / dist; - for ( axis = 0; axis < naxes; axis++ ) { - point3[ axis ] = point1[ axis ] + - fract * ( point2[ axis ] - point1[ axis ] ); - } - } - } -} - -static void Overlay( AstFrame *template, const int *template_axes, - AstFrame *result, int *status ) { -/* -*+ -* Name: -* astOverlay - -* Purpose: -* Overlay the attributes of a template Frame on to another Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void astOverlay( AstFrame *template, const int *template_axes, -* AstFrame *result ) - -* Class Membership: -* Frame method. - -* Description: -* This function overlays attributes of one Frame (the "template") on to -* another Frame, so as to over-ride selected attributes of that second -* Frame. Normally only those attributes which have been specifically set -* in the template will be transferred. This implements a form of -* defaulting, in which a Frame acquires attributes from the template, but -* retains its original attributes (as the default) if new values have not -* previously been explicitly set in the template. - -* Parameters: -* template -* Pointer to the template Frame, for which values should have been -* explicitly set for any attribute which is to be transferred. -* template_axes -* Pointer to an array of int, with one element for each axis of the -* "result" Frame (see below). For each axis in the result frame, the -* corresponding element of this array should contain the (zero-based) -* index of the template axis to which it corresponds. This array is used -* to establish from which template axis any axis-dependent attributes -* should be obtained. -* -* If any axis in the result Frame is not associated with a template -* axis, the corresponding element of this array should be set to -1. -* -* If a NULL pointer is supplied, the template and result axis -* indices are assumed to be identical. -* result -* Pointer to the Frame which is to receive the new attribute values. -*- -*/ - -/* Local Variables: */ - AstAxis *result_ax; /* Pointer to result Axis object */ - AstAxis *template_ax; /* Pointer to template Axis object */ - AstSystemType sys; /* System value */ - int result_axis; /* Loop counter for result Frame axes */ - int result_naxes; /* Number of result Frame axes */ - int template_axis; /* Index of template Frame axis */ - int template_naxes; /* Number of template Frame axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Define a macro that tests whether an attribute is set in the template and, - if so, transfers its value to the target. */ -#define OVERLAY(attribute) \ - if ( astTest##attribute( template ) ) { \ - astSet##attribute( result, astGet##attribute( template ) ); \ - } - -/* Use the macro to transfer each Frame attribute in turn. */ - OVERLAY(Dtai); - OVERLAY(Dut1); - OVERLAY(Digits); - OVERLAY(Domain); - OVERLAY(Epoch); - OVERLAY(Title); - OVERLAY(ObsLat) - OVERLAY(ObsLon) - OVERLAY(ObsAlt) - -/* Transfer the ActiveUnit flag. */ - astSetActiveUnit( result, astGetActiveUnit( template ) ); - -/* Only overlay the System and AlignSystem attribute if the values are - valid for the result class. */ - if( astTestSystem( template ) ) { - sys = astGetSystem( template ); - if( astValidateSystem( result, sys, "astOverlay" ) ) { - astSetSystem( result, sys ); - } - } - - if( astTestAlignSystem( template ) ) { - sys = astGetAlignSystem( template ); - if( astValidateSystem( result, sys, "astOverlay" ) ) { - astSetAlignSystem( result, sys ); - } - } - -/* Now transfer attributes associated with individual axes. Obtain the number - of axes in the template and result Frames. */ - template_naxes = astGetNaxes( template ); - result_naxes = astGetNaxes( result ); - if ( astOK ) { - -/* Loop through all the axes in the result Frame and determine to which - template axis each one corresponds. Check that the resulting axis index is - valid. If not, then the axis will not receive new attributes. */ - for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) { - template_axis = template_axes ? template_axes[ result_axis ] : result_axis; - if ( ( template_axis >= 0 ) && ( template_axis < template_naxes ) ) { - -/* Obtain pointers to the relevant Axis objects of each Frame and use the - astAxisOverlay method of the template Axis to overlay attributes on to - the result Axis. Annul the Axis pointers afterwards. */ - template_ax = astGetAxis( template, template_axis ); - result_ax = astGetAxis( result, result_axis ); - astAxisOverlay( template_ax, result_ax ); - template_ax = astAnnul( template_ax ); - result_ax = astAnnul( result_ax ); - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - } - } - -/* Undefine macros local to this function. */ -#undef OVERLAY -} - -static void PermAxes( AstFrame *this, const int perm[], int *status ) { -/* -*+ -* Name: -* astPermAxes - -* Purpose: -* Permute the order of a Frame's axes. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void astPermAxes( AstFrame *this, const int perm[] ) - -* Class Membership: -* Frame method. - -* Description: -* This function permutes the order in which a Frame's axes occur. - -* Parameters: -* this -* Pointer to the Frame. -* perm -* An array of int (with one element for each axis of the Frame) -* which lists the axes in their new order. Each element of this -* array should be a (zero-based) axis index identifying the -* axes according to their old (un-permuted) order. - -* Notes: -* - Only genuine permutations of the axis order are permitted, so -* each axis must be referenced exactly once in the "perm" array. -* - If more than one axis permutation is applied to a Frame, the -* effects are cumulative. -*- - -* Implementation Notes: -* - This function implements the basic astPermAxes method which is -* available via the protected interface to the Frame class. A -* public interface to this method is provided by the -* astPermAxesId_ function. -*/ - -/* Local Variables: */ - int *old; /* Pointer to copy of old permutation array */ - int axis; /* Loop counter for Frame axes */ - int naxes; /* Number of Frame axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the permutation array, to check that it describes a genuine - permutation. */ - astCheckPerm( this, perm, "astPermAxes" ); - -/* Obtain the number of Frame axes. */ - naxes = astGetNaxes( this ); - -/* Allocate memory and use it to store a copy of the old permutation array for - the Frame. */ - old = astStore( NULL, this->perm, sizeof( int ) * (size_t) naxes ); - -/* Apply the new axis permutation cumulatively to the old one and store the - result in the Frame. */ - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) { - this->perm[ axis ] = old[ perm[ axis ] ]; - } - } - -/* Free the temporary copy of the old array. */ - old = astFree( old ); -} - -static AstFrame *PickAxes( AstFrame *this, int naxes, const int axes[], - AstMapping **map, int *status ) { -/* -*+ -* Name: -* astPickAxes - -* Purpose: -* Create a new Frame by picking axes from an existing one. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* AstFrame *PickAxes( AstFrame *this, int naxes, const int axes[], -* AstMapping **map ) - -* Class Membership: -* Frame method. - -* Description: -* This function creates a new Frame whose axes are copies of axes -* picked from an existing Frame. Other Frame attributes are also -* copied to the new Frame. Zero or more of the original axes may -* be picked in any order, but each can be used only -* once. Additional axes (with default characteristics) may be -* included in the new Frame if required. -* -* Optionally, a Mapping that converts between the original Frame's -* axes and those of the new Frame may also be returned. - -* Parameters: -* this -* Pointer to the original Frame. -* naxes -* The number of axes required in the new Frame. -* axes -* Pointer to an array of int with naxes elements. This should -* contain (zero based) axis indices specifying the axes which -* are to be included in the new Frame, in the order -* required. Each axis index may occur only once. -* -* If additional (default) axes are also to be included, the -* corresponding elements of this array should be set to -1. -* map -* Address of a location to receive a pointer to a new -* Mapping. This will be a PermMap (or a UnitMap as a special -* case) that describes the axis permutation that has taken -* place between the original and new Frames. The forward -* transformation will convert from the original Frame's axes to -* the new one's, and vice versa. -* -* If this Mapping is not required, a NULL value may be supplied -* for this parameter. - -* Returned Value: -* Pointer to the new Frame. - -* Notes: -* - The class of object returned may differ from that of the -* original Frame, depending on which axes are selected. For -* example, if a single axis is picked from a SkyFrame (which -* always has two axes), the resulting Frame cannot be a valid -* SkyFrame, so will revert to the parent class (Frame) instead. -* - The new Frame contains a deep copy of all the data selected -* from the original Frame. Modifying the new Frame will therefore -* not affect the original one. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic astPickAxes method -* available via the protected interface to the Frame class. The -* public interface to this method is provided by the -* astPickAxesId_ function. -*/ - -/* Local Variables: */ - AstFrame *frame; /* Pointer to Frame to be returned */ - AstMapping *mapping; /* Pointer to Mapping to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the returned pointers. */ - frame = NULL; - if ( map ) *map = NULL; - -/* Check that a valid set of axes is being selected . */ - astValidateAxisSelection( this, naxes, axes, "astPickAxes" ); - -/* Create the required new Frame by selecting the axes. This also returns a - Mapping which transforms between the original Frame and the new one. */ - astSubFrame( this, NULL, naxes, axes, NULL, &mapping, &frame ); - if ( astOK ) { - -/* Return the Mapping pointer if required. */ - if ( map ) { - *map = mapping; - -/* Otherwise annul the Mapping. If an error occurs, also annul the Frame. */ - } else { - mapping = astAnnul( mapping ); - if ( !astOK ) frame = astAnnul( frame ); - } - } - -/* Return the pointer to the new Frame. */ - return frame; -} - -static void PrimaryFrame( AstFrame *this, int axis1, - AstFrame **frame, int *axis2, int *status ) { -/* -*+ -* Name: -* astPrimaryFrame - -* Purpose: -* Uniquely identify a primary Frame and one of its axes. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void astPrimaryFrame( AstFrame *this, int axis1, AstFrame **frame, -* int *axis2 ) - -* Class Membership: -* Frame method. - -* Description: -* This function returns information about the underlying (primary) Frame -* corresponding to a specified axis, when given what may be a compound -* Frame composed of more than one simpler one. - -* Parameters: -* this -* Pointer to the Frame. -* axis1 -* An axis index (zero-based) identifying the Frame axis for which -* information is required. -* frame -* Address of a location to receive a pointer to the underlying (primary) -* frame to which the requested axis belongs (i.e. this will not be a -* compound Frame). -* axis2 -* Pointer to an int which is to receive the (zero-based) axis -* index within "frame" which identifies the axis being referred -* to, using the axis order that applied when the primary Frame -* was originally constructed (i.e. this function undoes all -* subsequent axis pemutations and the effects of combining -* Frames, in order to reveal the original underlying axis -* order). - -* Notes: -* - This protected method is provided so that class implementations can -* distinguish the axes of frames from one another (e.g. can distinguish -* a longitude axis as being different from a latitide axis) even after -* their order has been permuted and they have been combined with axes from -* other Frames. -* - The reference count of the primary Frame will be incremented by one to -* reflect the new pointer returned. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise the returned values. */ - *frame = NULL; - *axis2 = 0; - -/* Validate and permute the axis index supplied. */ - axis1 = astValidateAxis( this, axis1, 1, "astPrimaryFrame" ); - -/* Since "this" is a primary Frame (i.e. is not compound), simply clone a - pointer to it. */ - if ( astOK ) *frame = astClone( this ); - -/* Return the permuted axis index, which refers to the original axis order. */ - if ( astOK ) *axis2 = axis1; -} - -double astReadDateTime_( const char *value, int *status ) { -/* -*+ -* Name: -* astReadDateTime - -* Purpose: -* Read a date/time string. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* double astReadDateTime( const char *value ) - -* Class Membership: -* Frame member function. - -* Description: -* This function reads a date/time string in a variety of formats and -* returns the resulting time as a Modified Julian Date. If the string -* cannot be interpreted as a date/time or contains invalid values, an -* error is reported. - -* Parameters: -* value -* Pointer to a null terminated string containing the value to be read. - -* Returned Value: -* The time as a Modified Julian date. - -* Date/Time Formats: -* The date/time formats supported by this function are listed below. These -* are interpreted in a case-insensitive manner and the function is -* generally flexible about the presence of additional white space and the -* use of alternative field delimiters. -* -* Besselian Epoch -* Expressed in decimal years, with or without decimal places -* ("B1950" or "B1976.13", for example). -* Julian Epoch -* Expressed in decimal years, with or without decimal places -* ("J2000" or "J2100.9", for example). -* Year -* Decimal years, with or without decimal places ("1996.8" for example). -* Such values are interpreted as a Besselian epoch (see above) if less -* than 1984.0 and as a Julian epoch otherwise. -* Julian Date -* With or without decimal places ("JD 2454321.9" for example). -* Modified Julian Date -* With or without decimal places ("MJD 54321.4" for example). -* Gregorian Calendar Date -* With the month expressed as an integer or 3-character -* abbreviation, and with optional decimal places to represent a -* fraction of a day ("1996-10-2" or "1996-Oct-2.6" for -* example). If no fractional part of a day is given, the time -* refers to the start of the day (zero hours). -* Gregorian Date and Time -* Any calendar date (as above) but with a fraction of a day expressed -* as hours, minutes and seconds ("1996-Oct-2 12:13:56.985" for example). -* The date and time can be separated by a space or by a "T" (as used -* by ISO8601). - -* Notes: -* - The date/time value is interpreted as a calendar date and time, not -* linked to any particular time system. Thus, interpretation of hours, -* minutes and seconds is done in the obvious manner assuming 86400 seconds -* in a day. No allowance for is made, for instance, for leap seconds or for -* the varying length of a second in some time systems. -* - A value of AST__BAD is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*- -*/ - -/* Local Vaiables: */ - char cmonth[ 4 ]; /* Buffer for name of month */ - char sep1[ 2 ]; /* Year/month separator string */ - char sep2[ 2 ]; /* Month/day separator string */ - char sep3[ 2 ]; /* Hour/minute separator string */ - char sep4[ 2 ]; /* Minute/second separator string */ - char *cc; /* Pointer to copy of remaining text */ - const char *v; /* Pointer into value string */ - const char *p; /* Pointer to date/time separator */ - double day; /* Day number plus fraction of whole day */ - double epoch; /* Epoch stored as decimal years */ - double hms; /* Hours, min & sec as fraction of a day */ - double jd; /* Julian Date */ - double mjd; /* Modified Julian Date */ - double result; /* Result to be returned */ - double sec; /* Seconds and fractions of a second */ - int hour; /* Number of hours */ - int iday; /* Number of whole days */ - int l; /* Length of string remaining */ - int len; /* Length of string */ - int match; /* Date/time string has correct form? */ - int minute; /* Number of minutes */ - int month; /* Number of months */ - int nc; /* Number of characters read from string */ - int stat; /* Status return from SLALIB functions */ - int year; /* Number of years */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Initialise. */ - result = AST__BAD; - -/* Obtain the length of the input string. */ - len = (int) strlen( value ); - -/* Attempt to read the string using each recognised format in turn. */ - -/* Besselian epoch in decimal years (e.g. "B1950.0"). */ -/* ================================================== */ - if ( nc = 0, - ( 1 == astSscanf( value, " %*1[Bb] %lf %n", &epoch, &nc ) ) - && ( nc >= len ) ) { - -/* Convert to Modified Julian Date. */ - result = palEpb2d( epoch ); - -/* Julian epoch in decimal years (e.g. "J2000.0"). */ -/* =============================================== */ - } else if ( nc = 0, - ( 1 == astSscanf( value, " %*1[Jj] %lf %n", &epoch, &nc ) ) - && ( nc >= len ) ) { - -/* Convert to Modified Julian Date. */ - result = palEpj2d( epoch ); - -/* Decimal years (e.g. "1976.2"). */ -/* ============================== */ - } else if ( nc = 0, - ( 1 == astSscanf( value, " %lf %n", &epoch, &nc ) ) - && ( nc >= len ) ) { - -/* Convert to Modified Julian Date, treating the epoch as Julian or Besselian - depending on whether it is 1984.0 or later. */ - result = ( epoch < 1984.0 ) ? palEpb2d( epoch ) : palEpj2d( epoch ); - -/* Modified Julian Date (e.g. "MJD 54321.0"). */ -/* ============================================ */ - } else if ( nc = 0, - ( 1 == astSscanf( value, " %*1[Mm] %*1[Jj] %*1[Dd] %lf %n", - &mjd, &nc ) ) && ( nc >= len ) ) { - -/* Use the result directly. */ - result = mjd; - -/* Julian Date (e.g. "JD 2454321.5"). */ -/* ==================================== */ - } else if ( nc = 0, - ( 1 == astSscanf( value, " %*1[Jj] %*1[Dd] %lf %n", - &jd, &nc ) ) && ( nc >= len ) ) { - -/* Convert to Modified Julian Date. */ - result = jd - 2400000.5; - -/* Gregorian calendar date (e.g. "1996-10-2" or "1996-Oct-2"). */ -/* =========================================================== */ -/* This format also allows day fractions expressed as decimal days, e.g: - - "1996-Oct-2.5001" - - or as hours, minutes and seconds, e.g: - - "1996-Oct-2 12:14:30.52" - - Various alternative field delimiters are also allowed. */ - } else { - -/* Note that the method used to parse this format relies heavily on - conditional execution controlled by "&&" and "||" operators. Initialise - the variables used. */ - v = value; - l = len; - *cmonth = '\0'; - year = month = iday = hour = minute = 0; - day = sec = 0.0; - -/* Identify the year and month. */ -/* ---------------------------- */ -/* Try to match an initial " 1996 - 10 -" or " 1996 10 " or similar. */ - match = - ( nc = 0, ( 4 == astSscanf( v, " %d %1[:/-] %2d %1[:/-]%n", - &year, sep1, &month, sep2, &nc ) ) ); - match = match || - ( nc = 0, ( 4 == astSscanf( v, " %d%1[ ] %2d%1[ ]%n", - &year, sep1, &month, sep2, &nc ) ) ); - -/* If that failed, allow " 1996 - Oct -" or " 1996 Oct " or similar. */ - match = match || - ( nc = 0, ( 4 == astSscanf( v, - " %d %1[:/-] %3[ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz] %1[:/-]%n", - &year, sep1, cmonth, sep2, &nc ) ) ); - match = match || - ( nc = 0, ( 4 == astSscanf( v, - " %d%1[ ] %3[ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz]%1[ ]%n", - &year, sep1, cmonth, sep2, &nc ) ) ); - -/* Alternative field separators are permitted above, but ensure that - they are both the same. */ - match = match && ( *sep1 == *sep2 ); - -/* Identify the day and fraction of day. */ -/*-------------------------------------- */ -/* If the above matched correctly, modify the string pointer "v" to - the next character to be interpreted and decrement the remaining - string length. */ - if ( match ) { - v += nc; - l -= nc; - -/* ISO8601 format uses the litter T as a delimiter between the date and time. - If there is a T in the remaining string, take a copy and change the T to - a space. */ - p = strchr( v, 'T' ); - if( p ) { - cc = astStore( NULL, v, l + 1 ); - cc[ p - v ] = ' '; - v = cc; - } else { - cc = NULL; - } - -/* We now try to match the following characters but without reading - any values. This is done to ensure the string has the correct form - (e.g. exclude "-" signs and exponents in numbers, which are - otherwise hard to detect). */ - -/* Try to match " 12.3456 " or similar. */ - match = - ( nc = 0, ( 0 == astSscanf( v, " %*2[0123456789].%*[0123456789] %n", - &nc ) ) - && ( nc == l ) ); - -/* If that failed, then try to match " 12. " or similar. */ - match = match || - ( nc = 0, ( 0 == astSscanf( v, " %*2[0123456789]. %n", &nc ) ) - && ( nc == l ) ); - -/* If that also failed, then try to match just " 12 " or similar. */ - match = match || - ( nc = 0, ( 0 == astSscanf( v, " %*2[0123456789] %n", &nc ) ) - && ( nc == l ) ); - -/* If any of the above patterns matched, now read the data (the day number) - as a double value. */ - if ( match ) { - match = ( nc = 0, ( 1 == astSscanf( v, " %lf %n", &day, &nc ) ) - && ( nc == l ) ); - -/* If none of the above matched, then look to see if the day fraction has been - given in hours, minutes and seconds by trying to match " 12 03 : 45 :" or - " 12 13 45 " or similar. */ - } else { - match = - ( nc = 0, ( 5 == astSscanf( v, - " %2d%*1[ ] %2d %1[:/-] %2d %1[:/-]%n", - &iday, &hour, sep3, &minute, sep4, - &nc ) ) ); - match = match || - ( nc = 0, ( 5 == astSscanf( v, " %2d%*1[ ] %2d%1[ ] %2d%1[ ]%n", - &iday, &hour, sep3, &minute, sep4, - &nc ) ) ); - -/* Alternative field separators are permitted above, but ensure that - they are both the same. */ - match = match && ( *sep3 == *sep4 ); - -/* If the day number was read as an integer, convert it to double. */ - if ( match ) day = (double) iday; - -/* If no match, see if we can get a match without a trailing seconds field. */ - if( !match ) { - match = - ( nc = 0, ( 4 == astSscanf( v, - " %2d%*1[ ] %2d %1[:/-] %2d %n", - &iday, &hour, sep3, &minute, &nc ) && - ( nc == l ) ) ); - match = match || - ( nc = 0, ( 4 == astSscanf( v, " %2d%*1[ ] %2d%1[ ] %2d %n", - &iday, &hour, sep3, &minute, &nc ) && - ( nc == l ) ) ); - -/* If the day number was read as an integer, convert it to double. */ - if ( match ) day = (double) iday; - -/* Otherwise, identify the seconds field. */ -/* -------------------------------------- */ -/* If hours and minutes fields have been matched, now look for the - final seconds (and fractions of seconds) field. This is similar to - the day/fraction field (see earlier) in that we first check that it - has the correct form before reading its value. */ - -/* Adjust the string pointer and remaining string length. */ - } else { - v += nc; - l -= nc; - -/* Try to match " 12.3456 " or similar. */ - match = - ( nc = 0, ( 0 == astSscanf( v, - " %*2[0123456789].%*[0123456789] %n", - &nc ) ) - && ( nc == l ) ); - -/* If that failed, then try to match " 12. " or similar. */ - match = match || - ( nc = 0, ( 0 == astSscanf( v, " %*2[0123456789]. %n", &nc ) ) - && ( nc == l ) ); - -/* If that also failed, then try to match just " 12 " or similar. */ - match = match || - ( nc = 0, ( 0 == astSscanf( v, " %*2[0123456789] %n", &nc ) ) - && ( nc == l ) ); - -/* If any of the above patterns matched, now read the data (the number of - seconds) as a double value. */ - if ( match ) { - match = ( nc = 0, ( 1 == astSscanf( v, " %lf %n", &sec, &nc ) ) - && ( nc == l ) ); - } - } - } - -/* Free resources */ - if( cc ) cc = astFree( cc ); - - } - -/* Interpret the values that were read. */ -/* ------------------------------------ */ -/* We execute this if all of the above text matching was successful, - transferred the required number of data values, and consumed the - entire input string. */ - if ( match ) { - -/* See if the month was given as a character string (e.g. "Oct") instead of - a number. If so, define local variables for use in converting it. */ - if ( *cmonth ) { - char lcmonth[ 4 ]; /* Lower case copy of month string */ - const char *ptr; /* Pointer result from look up */ - const char *table = /* Month look up table */ - "jan feb mar apr may jun jul aug sep oct nov dec"; - int i; /* Loop counter for characters */ - -/* Convert the month string to lower case. */ - for ( i = 0; cmonth[ i ]; i++ ) { - lcmonth[ i ] = tolower( cmonth[ i ] ); - } - lcmonth[ i ] = '\0'; - -/* Look the month up in the table of months and generate the required month - number. */ - if ( ( ptr = strstr( table, lcmonth ) ) ) { - month = 1 + ( ptr - table ) / 4; - -/* If the lookup failed, report an error. */ - } else { - astError( AST__DTERR, "Month value \"%s\" is invalid.", status, - cmonth ); - } - } - -/* If OK, extract the integral day number and convert years, months and days - to a Modified Julian Date. */ - if ( astOK ) { - iday = (int) day; - palCaldj( year, month, iday, &mjd, &stat ); - -/* Examine the return status from the conversion and report an appropriate - error if necessary. */ - switch ( stat ) { - case 1: - astError( AST__DTERR, "Year value (%d) is invalid.", status, year ); - break; - case 2: - astError( AST__DTERR, "Month value (%d) is invalid.", status, month ); - break; - case 3: - astError( AST__DTERR, "Day value (%.*g) is invalid.", status, AST__DBL_DIG, - day ); - break; - -/* If conversion to MJD was successful, add any fractional part of a day to the - result. */ - default: - mjd += ( day - (double) iday ); - -/* Convert hours, minutes and seconds to a fraction of a day (this will give - zero if none of these quantities was supplied). */ - palDtf2d( hour, minute, sec, &hms, &stat ); - -/* Examine the return status from the conversion and report an appropriate - error if necessary. */ - switch ( stat ) { - case 1: - astError( AST__DTERR, "Hour value (%d) is invalid.", status, hour ); - break; - case 2: - astError( AST__DTERR, "Minute value (%d) is invalid.", status, - minute ); - break; - case 3: - astError( AST__DTERR, "Seconds value (%.*g) is invalid.", status, - AST__DBL_DIG, sec ); - break; - -/* Add the fraction of a day derived from hours, minutes and seconds fields to - the result. */ - default: - mjd += hms; - break; - } - break; - } - -/* Return the result, if no error occurred. */ - if ( astOK ) result = mjd; - } - -/* If none of the supported date/time formats matched, then report an error. */ - } else { - astError( AST__DTERR, "Date/time does not have the correct form." , status); - } - } - -/* Return the result. */ - return result; -} - -static void ReportPoints( AstMapping *this_mapping, int forward, - AstPointSet *in_points, AstPointSet *out_points, int *status ) { -/* -* Name: -* ReportPoints - -* Purpose: -* Report the effect of transforming a set of points using a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void ReportPoints( AstMapping *this, int forward, -* AstPointSet *in_points, AstPointSet *out_points, int *status ) - -* Class Membership: -* Frame member function (over-rides the protected astReportPoints -* method inherited from the Mapping class). - -* Description: -* This function reports the coordinates of a set of points before -* and after being transformed by a Frame, by writing them to -* standard output. - -* Parameters: -* this -* Pointer to the Frame. -* forward -* A non-zero value indicates that the Frame's forward -* coordinate transformation has been applied, while a zero -* value indicates the inverse transformation. -* in_points -* Pointer to a PointSet which is associated with the -* coordinates of a set of points before the Frame was applied. -* out_points -* Pointer to a PointSet which is associated with the -* coordinates of the same set of points after the Frame has -* been applied. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *this; /* Pointer to the Frame structure */ - double **ptr_in; /* Pointer to array of input data pointers */ - double **ptr_out; /* Pointer to array of output data pointers */ - int coord; /* Loop counter for coordinates */ - int ncoord_in; /* Number of input coordinates per point */ - int ncoord_out; /* Number of output coordinates per point */ - int npoint; /* Number of points to report */ - int npoint_in; /* Number of input points */ - int npoint_out; /* Number of output points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) this_mapping; - -/* Obtain the numbers of points and coordinates associated with each - PointSet. */ - npoint_in = astGetNpoint( in_points ); - npoint_out = astGetNpoint( out_points ); - ncoord_in = astGetNcoord( in_points ); - ncoord_out = astGetNcoord( out_points ); - -/* Obtain the pointers that give access to the coordinate data - associated with each PointSet. */ - ptr_in = astGetPoints( in_points ); - ptr_out = astGetPoints( out_points ); - -/* In the event that both PointSets don't contain equal numbers of - points (this shouldn't actually happen), simply use the minimum - number. */ - npoint = ( npoint_in < npoint_out ) ? npoint_in : npoint_out; - -/* Loop to report the effect of the transformation on each point in - turn. */ - for ( point = 0; point < npoint; point++ ) { - -/* Report the input coordinates (in parentheses and separated by - commas). Format each value for display using the Frame's astFormat - method. */ - printf( "(" ); - for ( coord = 0; coord < ncoord_in; coord++ ) { - printf( "%s%s", coord ? ", " : "", - astFormat( this, coord, ptr_in[ coord ][ point ] ) ); - } - -/* Similarly report the output coordinates. */ - printf( ") --> (" ); - for ( coord = 0; coord < ncoord_out; coord++ ) { - printf( "%s%s", coord ? ", " : "", - astFormat( this, coord, ptr_out[ coord ][ point ] ) ); - } - printf( ")\n" ); - } -} - -static void Resolve( AstFrame *this, const double point1[], - const double point2[], const double point3[], - double point4[], double *d1, double *d2, int *status ){ -/* -*++ -* Name: -c astResolve -f AST_RESOLVE - -* Purpose: -* Resolve a vector into two orthogonal components - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c void astResolve( AstFrame *this, const double point1[], -c const double point2[], const double point3[], -c double point4[], double *d1, double *d2 ); -f CALL AST_RESOLVE( THIS, POINT1, POINT2, POINT3, POINT4, D1, D2, -f STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function resolves a vector into two perpendicular components. -f This routine resolves a vector into two perpendicular components. -* The vector from point 1 to point 2 is used as the basis vector. -* The vector from point 1 to point 3 is resolved into components -* parallel and perpendicular to this basis vector. The lengths of the -* two components are returned, together with the position of closest -* aproach of the basis vector to point 3. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c point1 -f POINT1( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vector to be resolved. -c point2 -f POINT2( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -c point3 -f POINT3( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute). This marks the end of the vector to be -* resolved. -c point4 -f POINT4( * ) = DOUBLE PRECISION (Returned) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* in which the coordinates of the point of closest approach of the -* basis vector to point 3 will be returned. -c d1 -f D1 = DOUBLE PRECISION (Returned) -c The address of a location at which to return the distance from -f The distance from -* point 1 to point 4 (that is, the length of the component parallel -* to the basis vector). Positive values are in the same sense as -* movement from point 1 to point 2. -c d2 -f D2 = DOUBLE PRECISION (Returned) -c The address of a location at which to return the distance from -f The distance from -* point 4 to point 3 (that is, the length of the component -* perpendicular to the basis vector). The value is always positive. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - Each vector used in this function is the path of -f - Each vector used in this routine is the path of -* shortest distance between two points, as defined by the -c astDistance function. -f AST_DISTANCE function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value, or if the required -* output values are undefined. -*-- -*/ - -/* Local Variables: */ - double bv; /* Length of basis vector */ - double c; /* Component length */ - double dp; /* Dot product */ - int axis; /* Loop counter for axes */ - int naxes; /* Number of Frame axes */ - int ok; /* OK to proceed? */ - -/* Check the global error status. */ - *d1 = AST__BAD; - *d2 = AST__BAD; - if ( !astOK ) return; - -/* Determine the number of Frame axes. */ - naxes = astGetNaxes( this ); - -/* Initialize bad values, and check if the supplied vectors are good. */ - ok = 1; - for( axis = 0; axis < naxes; axis++ ){ - point4[ axis ] = AST__BAD; - if( point1[ axis ] == AST__BAD || - point2[ axis ] == AST__BAD || - point3[ axis ] == AST__BAD ) ok = 0; - } - -/* Check the supplied values. */ - if ( ok ) { - -/* Find the dot product of the basis vector with the vector joining point 1 - and point 3. At the same time form the squared length of the basis - vector. */ - dp = 0.0; - bv = 0.0; - for( axis = 0; axis < naxes; axis++ ){ - c = point2[ axis ] - point1[ axis ]; - dp += c * ( point3[ axis ] - point1[ axis ] ); - bv += c * c; - } - -/* Check the basis vector does not have zero length, and convert the - squared length into a length. */ - if( bv > 0.0 ) { - bv = sqrt( bv ); - -/* The dot product is the required distance d1 multiplied by the length - of the basis vector. Form the distance d1. */ - *d1 = dp/bv; - -/* Offset away from point 1 towards point 2 by a distance of d1. */ - for( axis = 0; axis < naxes; axis++ ){ - point4[ axis ] = point1[ axis ] + - (*d1/bv)*( point2[ axis ] - point1[ axis ] ); - } - -/* Finally, form the required length d2. */ - *d2 = 0.0; - for( axis = 0; axis < naxes; axis++ ){ - c = ( point3[ axis ] - point4[ axis ] ); - *d2 += c*c; - } - *d2 = sqrt( *d2 ); - - } - } - - return; - -} - -static AstPointSet *ResolvePoints( AstFrame *this, const double point1[], - const double point2[], AstPointSet *in, - AstPointSet *out, int *status ) { -/* -*+ -* Name: -* astResolvePoints - -* Purpose: -* Resolve a set of vectors into orthogonal components - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* AstPointSet *astResolvePoints( AstFrame *this, const double point1[], -* const double point2[], AstPointSet *in, -* AstPointSet *out ) - -* Class Membership: -* Frame method. - -* Description: -* This function takes a Frame and a set of vectors encapsulated -* in a PointSet, and resolves each one into two orthogonal components, -* returning these two components in another PointSet. -* -* This is exactly the same as the public astResolve method, except -* that this method allows many vectors to be processed in a single call, -* thus reducing the computational cost of overheads of many -* individual calls to astResolve. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vectors to be resolved. -* point2 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -* in -* Pointer to the PointSet holding the ends of the vectors to be -* resolved. -* out -* Pointer to a PointSet which will hold the length of the two -* resolved components. A NULL value may also be given, in which -* case a new PointSet will be created by this function. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. The first axis will -* hold the lengths of the vector components parallel to the basis vector. -* These values will be signed (positive values are in the same sense as -* movement from point 1 to point 2. The second axis will hold the lengths -* of the vector components perpendicular to the basis vector. These -* values will be signed only if the Frame is 2-dimensional, in which -* case a positive value indicates that rotation from the basis vector -* to the tested vector is in the same sense as rotation from the first -* to the second axis of the Frame. - -* Notes: -* - The number of coordinate values per point in the input -* PointSet must match the number of axes in the supplied Frame. -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and 2 coordinate values per point. -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -* - We assume flat geometry throughout this function. Other classes, -* (e.g. SkyFrame) will override this method using more appropriate -* geometry. -*- -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - double **ptr_in; /* Pointers to input axis values */ - double **ptr_out; /* Pointers to returned axis values */ - double *basisv; /* Pointer to array holding basis vector */ - double *d1; /* Pointer to next parallel component value */ - double *d2; /* Pointer to next perpendicular component value */ - double *ip; /* Pointer to next input axis value */ - double bv; /* Length of basis vector */ - double c; /* Constant value */ - double d; /* Component length */ - double dp; /* Dot product */ - double x1; /* First axis of basis vector */ - double x2; /* First axis of test vector */ - double y1; /* Second axis of basis vector */ - double y2; /* Second axis of test vector */ - int axis; /* Loop counter for axes */ - int ipoint; /* Index of next point */ - int nax; /* Number of Frame axes */ - int ncoord_in; /* Number of input PointSet coordinates */ - int ncoord_out; /* Number of coordinates in output PointSet */ - int npoint; /* Number of points to transform */ - int npoint_out; /* Number of points in output PointSet */ - int ok; /* OK to proceed? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain the number of axes in the Frame. */ - nax = astGetNaxes( this ); - -/* Obtain the number of input vectors to resolve and the number of coordinate - values per vector. */ - npoint = astGetNpoint( in ); - ncoord_in = astGetNcoord( in ); - -/* If OK, check that the number of input coordinates matches the number - required by the Frame. Report an error if these numbers do not match. */ - if ( astOK && ( ncoord_in != nax ) ) { - astError( AST__NCPIN, "astResolvePoints(%s): Bad number of coordinate " - "values (%d) in input %s.", status, astGetClass( this ), ncoord_in, - astGetClass( in ) ); - astError( AST__NCPIN, "The %s given requires %d coordinate value(s) for " - "each input point.", status, astGetClass( this ), nax ); - } - -/* If still OK, and a non-NULL pointer has been given for the output PointSet, - then obtain the number of points and number of coordinates per point for - this PointSet. */ - if ( astOK && out ) { - npoint_out = astGetNpoint( out ); - ncoord_out = astGetNcoord( out ); - -/* Check that the dimensions of this PointSet are adequate to accommodate the - output coordinate values and report an error if they are not. */ - if ( astOK ) { - if ( npoint_out < npoint ) { - astError( AST__NOPTS, "astResolvePoints(%s): Too few points (%d) in " - "output %s.", status, astGetClass( this ), npoint_out, - astGetClass( out ) ); - astError( AST__NOPTS, "The %s needs space to hold %d transformed " - "point(s).", status, astGetClass( this ), npoint ); - } else if ( ncoord_out < 2 ) { - astError( AST__NOCTS, "astResolvePoints(%s): Too few coordinate " - "values per point (%d) in output %s.", status, - astGetClass( this ), ncoord_out, astGetClass( out ) ); - astError( AST__NOCTS, "The %s supplied needs space to store 2 " - "coordinate value(s) per transformed point.", status, - astGetClass( this ) ); - } - } - } - -/* If all the validation stages are passed successfully, and a NULL output - pointer was given, then create a new PointSet to encapsulate the output - coordinate data. */ - if ( astOK ) { - if ( !out ) { - result = astPointSet( npoint, 2, "", status ); - -/* Otherwise, use the PointSet supplied. */ - } else { - result = out; - } - } - -/* Get pointers to the input and output axis values */ - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Store points to the first two axis arrays in the returned PointSet. */ - d1 = ptr_out[ 0 ]; - d2 = ptr_out[ 1 ]; - -/* Allocate work space. */ - basisv = astMalloc( sizeof( double )*(size_t) nax ); - -/* If the Frame has only one axis, then the supplied basic vector is - irrelevant - the returned perpendicular distances are always zero and - the returned parallel distances are just the distances from point1 - to each input point. */ - if( nax < 2 && basisv ) { - ip = ptr_in[ 0 ]; - for( ipoint = 0; ipoint < npoint; ipoint++, d1++, d2++, ip++ ) { - *d1 = astAxDistance( this, 1, point1[0], *ip ); - *d2 = 0.0; - } - -/* Now deal with Frames which have 2 or more axes */ - } else if( basisv ){ - -/* Check if the supplied positions defining the basis vector are good. - Store the basis vector, and get its squared length. */ - ok = 1; - bv = 0.0; - for( axis = 0; axis < nax; axis++ ){ - if( point1[ axis ] == AST__BAD || - point2[ axis ] == AST__BAD ) { - ok = 0; - break; - } else { - basisv[ axis ] = point2[ axis ] - point1[ axis ]; - bv += basisv[ axis ]*basisv[ axis ]; - } - } - -/* Check the basis vector does not have zero length, and convert the - squared length into a length. */ - if( ok && bv > 0.0 ) { - bv = sqrt( bv ); - } else { - ok = 0; - } - -/* Store points to the first two axis arrays in the returned PointSet. */ - d1 = ptr_out[ 0 ]; - d2 = ptr_out[ 1 ]; - -/* Check supplied values can be used */ - if( ok ) { - -/* Loop round each supplied vector. */ - for( ipoint = 0; ipoint < npoint; ipoint++, d1++, d2++ ) { - -/* Find the dot product of the basis vector with the vector joining point 1 - and the end of the current vector. */ - ok = 1; - dp = 0.0; - for( axis = 0; axis < nax; axis++ ){ - d = ptr_in[ axis ][ ipoint ] - point1[ axis ]; - if( d != AST__BAD ) { - dp += basisv[ axis ] * d; - } else { - ok = 0; - break; - } - } - -/* If this input position is good... */ - if( ok ) { - -/* The dot product is the required parallel component length multiplied by the - length of the basis vector. Form the distance d1. */ - *d1 = dp/bv; - -/* Offset away from point 1 towards point 2 by a distance of d1, and form the - required length d2. */ - c = *d1/bv; - if( nax > 2 ) { - *d2 = 0.0; - for( axis = 0; axis < nax; axis++ ){ - d = ptr_in[ axis ][ ipoint ] - - ( point1[ axis ] + c*basisv[ axis ] ); - *d2 += d*d; - } - *d2 = sqrt( *d2 ); - -/* If the Frame is 2 dimensional, we can give a sign the the perpendicular - component. */ - } else { - x1 = c*basisv[ 0 ]; - y1 = c*basisv[ 1 ]; - x2 = ptr_in[ 0 ][ ipoint ] - ( point1[ 0 ] + x1 ); - y2 = ptr_in[ 1 ][ ipoint ] - ( point1[ 1 ] + y1 ); - *d2 = sqrt( x2*x2 + y2*y2 ); - if( x1*y2 - x2*y1 < 0.0 ) *d2 = -(*d2); - } - -/* If this input vector is bad, put bad values in the output */ - } else { - *d1 = AST__BAD; - *d2 = AST__BAD; - } - } - -/* If supplied values cannot be used, fill the returned PointSet with bad - values */ - } else { - for( ipoint = 0; ipoint < npoint; ipoint++, d1++, d2++ ) { - *d1 = AST__BAD; - *d2 = AST__BAD; - } - } - } - -/* Free resources */ - basisv = astFree( basisv ); - -/* Annul the returned PointSet if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static void SetActiveUnit( AstFrame *this, int value, int *status ){ -/* -*++ -* Name: -c astSetActiveUnit -f AST_SETACTIVEUNIT - -* Purpose: -* Specify how the Unit attribute should be used. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c void astSetActiveUnit( AstFrame *this, int value ) -f CALL AST_SETACTIVEUNIT( THIS, VALUE, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* sets the current value of the ActiveUnit flag for a Frame, which -* controls how the Frame behaves when it is used (by -c astFindFrame or astConvert) -f AST_FINDFRAME or AST_CONVERT) -* to match another Frame. If the ActiveUnit flag is set in both -* template and target Frames then the returned Mapping takes into account -* any differences in axis units. The default value for simple Frames is -* zero, which preserves the behaviour of versions of AST prior to -* version 2.0. -* -* If the ActiveUnit flag of either Frame is -c zero, -f .FALSE., -* then the Mapping will ignore any difference in the Unit attributes of -* corresponding template and target axes. In this mode, the Unit -* attributes are purely descriptive commentary for the benefit of -* human readers and do not influence the Mappings between Frames. -* This is the behaviour which all Frames had in older version of AST, -* prior to the introduction of this attribute. -* -* If the ActiveUnit flag of both Frames is -c non-zero, -f .TRUE., -* then the Mapping from template to target will take account of any -* difference in the axis Unit attributes, where-ever possible. For -* instance, if corresponding target and template axes have Unit strings of -* "km" and "m", then the FrameSet class will use a ZoomMap to connect -* them which introduces a scaling of 1000. If no Mapping can be found -* between the corresponding units string, then an error is reported. -* In this mode, it is assumed that values of the Unit attribute conform -* to the syntax for units strings described in the FITS WCS Paper I -* "Representations of world coordinates in FITS" (Greisen & Calabretta). -* Particularly, any of the named unit symbols, functions, operators or -* standard multiplier prefixes listed within that paper can be used within -* a units string. A units string may contain symbols for unit which are -* not listed in the FITS paper, but transformation to any other units -* will then not be possible (except to units which depend only on the -* same unknown units - thus "flops" can be transformed to "Mflops" -* even though "flops" is not a standard FITS unit symbol). -* -* A range of common non-standard variations of unit names and multiplier -* prefixes are also allowed, such as adding an "s" to the end of Angstrom, -* using a lower case "a" at the start of "angstrom", "micron" instead of -* "um", "sec" instead of "s", etc. -* -c If the ActiveUnit flag is non-zero, setting a new Unit value for an -f If the ActiveUnit flag is .TRUE., setting a new Unit value for an -* axis may also change its Label and Symbol attributes. For instance, if -* an axis has Unit "Hz" and Label "frequency", then changing its Unit to -* "log(Hz)" will change its Label to "log( frequency )". In addition, -* the Axis Format attribute will be cleared when-ever a new value -* is assigned to the Unit attribute. -* -c Note, if a non-zero value is set for the ActiveUnit flag, then changing a -f Note, if a .TRUE. value is set for the ActiveUnit flag, then changing a -* Unit value for the current Frame within a FrameSet will result in the -* Frame being re-mapped (that is, the Mappings which define the -* relationships between Frames within the FrameSet will be modified to -* take into account the change in Units). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c value -f VALUE = LOGICAL (Given) -* The new value to use. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* SkyFrame -c The ActiveUnit flag for a SkyFrame is always 0 (any value -c supplied using this function is ignored). -f The ActiveUnit flag for a SkyFrame is always .FALSE. (any value -f supplied using this routine is ignored). -* SpecFrame -c The ActiveUnit flag for a SpecFrame is always 1 (any value -c supplied using this function is ignored). -f The ActiveUnit flag for a SpecFrame is always .TRUE. (any value -f supplied using this routine is ignored). -* FluxFrame -c The ActiveUnit flag for a FluxFrame is always 1 (any value -c supplied using this function is ignored). -f The ActiveUnit flag for a FluxFrame is always .TRUE. (any value -f supplied using this routine is ignored). -* CmpFrame -c The default ActiveUnit flag for a CmpFrame is 1 if both of the -c component Frames are using active units, and zero otherwise. When -f The default ActiveUnit flag for a CmpFrame is .TRUE. if both of the -f component Frames are using active units, and .FALSE. otherwise. When -* a new value is set for the ActiveUnit flag, the flag value -* is propagated to the component Frames. This change will be -* reflected through all references to the component Frames, not -* just those encapsulated within the CmpFrame. -* Region: -* Regions always use active units if possible. - -* Notes: -* - The ActiveUnit flag resembles a Frame attribute, except that it -* cannot be tested or cleared, and it cannot be accessed using the -c generic astGet and astSet functions. -f generic AST_GET and AST_SET routines. -c - The astGetActiveUnit function can be used to retrieve the current -f - The AST_GETACTIVEUNIT routine can be used to retrieve the current -* value of the ActiveUnit flag. - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store a value of 1 for the Frame component if the supplied value is - non-zero. */ - this->active_unit = ( value ) ? 1 : 0; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* Frame member function (over-rides the astSetAttrib method inherited -* from the Mapping class). - -* Description: -* This function assigns an attribute value for a Frame, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Frame. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -*/ - -/* Local Vaiables: */ - AstAxis *ax; /* Pointer to Axis */ - AstFrame *pfrm; /* Pointer to primary Frame containing axis */ - AstFrame *this; /* Pointer to the Frame structure */ - AstSystemType system_code; /* System code */ - char pfrm_attrib[ 100 ]; /* Primary Frame attribute */ - char *pfrm_setting; /* Primary Frame attribute */ - char *axis_setting; /* Pointer to axis attribute setting string */ - const char *equals; /* Pointer to equals sign */ - const char *old_setting; /* Pointer to supplied setting string */ - const char *op; /* Pointer to opening parenthesis */ - double dval; /* Double attibute value */ - double mjd; /* Epoch as a Modified Julian Date */ - int axis; /* Index for the Frame axis */ - int axis_nc; /* No. characters in axis attribute name */ - int axis_value; /* Offset of value to be assigned to axis */ - int digits; /* Number of digits of precision */ - int direction; /* Axis direction flag */ - int domain; /* Offset of Domain string */ - int epoch; /* Offset of Epoch string */ - int format; /* Offset of axis Format string */ - int free_axis_setting; /* Should axis_setting be freed? */ - int has_axis; /* Does setting include an axis specifier? */ - int ival; /* Integer attribute value */ - int label; /* Offset of axis Label string */ - int len; /* Length of setting string */ - int match_end; /* Match final axes of target? */ - int max_axes; /* Maximum number of axes matched */ - int min_axes; /* Minimum number of axes matched */ - int nc; /* Number of characters read by astSscanf */ - int off2; /* Modified offset of attribute value */ - int off; /* Offset of attribute value */ - int oldrep; /* Original error reporting state */ - int paxis; /* Axis index within primary frame */ - int permute; /* Permute axes in order to match? */ - int preserve_axes; /* Preserve matched target axes? */ - int sign; /* Sign of longitude value */ - int symbol; /* Offset of axis Symbol string */ - int system; /* Offset of System string */ - int title; /* Offset of Title string */ - int unit; /* Offset of axis Unit string */ - int used; /* Could the setting string be used? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) this_object; - -/* Find the offset to the first equal sign in the setting string. */ - equals = strchr( setting, '=' ); - -/* Set a flag indicating if the attribute name includes an axis - specifier. */ - op = strchr( setting, '(' ); - has_axis = ( !op || op > equals ) ? 0 : 1; - -/* A flag indicating that we do not need to free the axis_setting memory. */ - free_axis_setting = 0; - -/* Initialise things to avoid compiler warnings. */ - axis_setting = NULL; - old_setting = NULL; - -/* Jump back to here if we are trying the same attribute setting but with - an explicit axis "(1)" added to the attribute name. */ -L1: - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* Digits. */ -/* ------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "digits= %d %n", &digits, &nc ) ) - && ( nc >= len ) ) { - astSetDigits( this, digits ); - -/* Digits(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "digits(%d)= %d %n", - &axis, &digits, &nc ) ) - && ( nc >= len ) ) { - -/* There is no function to set the Digits attribute value for an axis - directly, so obtain a pointer to the Axis and use this to set the - attribute. */ - (void) astValidateAxis( this, axis - 1, 1, "astSetDigits(axis)" ); - ax = astGetAxis( this, axis - 1 ); - astSetAxisDigits( ax, digits ); - ax = astAnnul( ax ); - -/* Direction(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "direction(%d)= %d %n", - &axis, &direction, &nc ) ) - && ( nc >= len ) ) { - astSetDirection( this, axis - 1, direction ); - -/* Epoch. */ -/* ------ */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "epoch=%n%*[^\n]%n", &epoch, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the Epoch value to a Modified Julian Date before use. */ - mjd = astReadDateTime( setting + epoch ); - if ( astOK ) { - astSetEpoch( this, mjd ); - -/* Report contextual information if the conversion failed. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid epoch value " - "\"%s\" given for coordinate system.", status, - astGetClass( this ), setting + epoch ); - } - -/* Top(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "top(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetTop( this, axis - 1, dval ); - -/* Bottom(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "bottom(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetBottom( this, axis - 1, dval ); - -/* Domain. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "domain=%n%*[^\n]%n", &domain, &nc ) ) - && ( nc >= len ) ) { - astSetDomain( this, setting + domain ); - -/* Format(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "format(%d)=%n%*[^\n]%n", - &axis, &format, &nc ) ) - && ( nc >= len ) ) { - astSetFormat( this, axis - 1, setting + format ); - -/* Label(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "label(%d)=%n%*[^\n]%n", - &axis, &label, &nc ) ) - && ( nc >= len ) ) { - astSetLabel( this, axis - 1, setting + label ); - -/* MatchEnd. */ -/* --------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "matchend= %d %n", &match_end, &nc ) ) - && ( nc >= len ) ) { - astSetMatchEnd( this, match_end ); - -/* MaxAxes. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "maxaxes= %d %n", &max_axes, &nc ) ) - && ( nc >= len ) ) { - astSetMaxAxes( this, max_axes ); - -/* MinAxes. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "minaxes= %d %n", &min_axes, &nc ) ) - && ( nc >= len ) ) { - astSetMinAxes( this, min_axes ); - -/* Permute. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "permute= %d %n", &permute, &nc ) ) - && ( nc >= len ) ) { - astSetPermute( this, permute ); - -/* PreserveAxes. */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "preserveaxes= %d %n", - &preserve_axes, &nc ) ) - && ( nc >= len ) ) { - astSetPreserveAxes( this, preserve_axes ); - -/* Symbol(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "symbol(%d)=%n%*[^\n]%n", - &axis, &symbol, &nc ) ) - && ( nc >= len ) ) { - astSetSymbol( this, axis - 1, setting + symbol ); - -/* AlignSystem. */ -/* ------------ */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "alignsystem= %n%*s %n", &system, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a System code before use. */ - system_code = astSystemCode( this, system + setting ); - if ( system_code != AST__BADSYSTEM ) { - astSetAlignSystem( this, system_code ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, - "astSetAttrib(%s): Invalid AlignSystem description \"%s\".", status, - astGetClass( this ), system + setting ); - } - -/* System. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "system= %n%*s %n", &system, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a System code before use. */ - system_code = astSystemCode( this, system + setting ); - if ( system_code != AST__BADSYSTEM ) { - astSetSystem( this, system_code ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, - "astSetAttrib(%s): Invalid System description \"%s\".", status, - astGetClass( this ), system + setting ); - } - -/* Title. */ -/* ------ */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "title=%n%*[^\n]%n", &title, &nc ) ) - && ( nc >= len ) ) { - astSetTitle( this, setting + title ); - -/* Unit(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "unit(%d)=%n%*[^\n]%n", - &axis, &unit, &nc ) ) - & ( nc >= len ) ) { - astSetUnit( this, axis - 1, setting + unit ); - -/* ObsLat. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "obslat=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - -/* If the first character in the value string is "N" or "S", remember the - sign of the value and skip over the sign character. Default is north - (+ve). */ - off2 = off; - if( setting[ off ] == 'N' || setting[ off ] == 'n' ) { - off2++; - sign = +1; - } else if( setting[ off ] == 'S' || setting[ off ] == 's' ) { - off2++; - sign = -1; - } else { - sign = +1; - } - -/* If not already created, create an FK5 J2000 SkyFrame which will be used - for formatting and unformatting ObsLon and ObsLat values. */ - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000,format(2)=dms.2", status ); - astEndPM; - } - -/* Convert the string to a radians value before use. */ - ival = astUnformat( skyframe, 1, setting + off2, &dval ); - if ( ival == astChrLen( setting ) - off2 ) { - astSetObsLat( this, dval*sign ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid value for " - "ObsLat (observers latitude) \"%s\".", status, astGetClass( this ), - setting + off ); - } - -/* ObsLon. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "obslon=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - -/* If the first character in the value string is "E" or "W", remember the - sign of the value and skip over the sign character. Default is east - (+ve). */ - off2 = off; - if( setting[ off ] == 'E' || setting[ off ] == 'e' ) { - off2++; - sign = +1; - } else if( setting[ off ] == 'W' || setting[ off ] == 'w' ) { - off2++; - sign = -1; - } else { - sign = +1; - } - -/* If not already created, create an FK5 J2000 SkyFrame which will be used - for formatting and unformatting ObsLon and ObsLat values. */ - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000,format(2)=dms.2", status ); - astEndPM; - } - -/* Convert the string to a radians value before use. */ - ival = astUnformat( skyframe, 1, setting + off2, &dval ); - if ( ival == astChrLen( setting ) - off2 ) { - astSetObsLon( this, dval*sign ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid value for " - "ObsLon (observers longitude) \"%s\".", status, astGetClass( this ), - setting + off ); - } - -/* ObsAlt. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "obsalt= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetObsAlt( this, dval ); - -/* Dtai. */ -/* ---- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "dtai= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetDtai( this, dval ); - -/* Dut1. */ -/* ---- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "dut1= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetDut1( this, dval ); - - -/* Read-only attributes. */ -/* --------------------- */ -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* Use this macro to report an error if a read-only attribute has been - specified. */ - } else if ( MATCH( "naxes" ) || - !strncmp( setting, "normunit", 8 ) || - !strncmp( setting, "internalunit", 12 ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Other axis attributes. */ -/* ---------------------- */ -/* If the attribute was not identified above, but appears to refer to - a Frame axis, then it may refer to an Axis object of a derived type - (which has additional attributes not recognised here). */ - } else if ( !free_axis_setting && ( nc = 0, - ( 1 == astSscanf( setting, "%*[^()=]%n(%d)%n=%*[^\n]%n", - &axis_nc, &axis, &axis_value, &nc ) ) - && ( nc >= len ) ) ) { - -/* Validate the axis index and copy the attribute setting string. */ - (void) astValidateAxis( this, axis - 1, 1, "astSet" ); - axis_setting = astString( setting, len ); - if ( astOK ) { - -/* Over-write the axis index in the copy with the value to be - assigned. */ - (void) strcpy( axis_setting + axis_nc, setting + axis_value ); - -/* Obtain a pointer to the Axis object. */ - ax = astGetAxis( this, axis - 1 ); - if( astOK ) { - -/* Assume that we will be able to use the setting. */ - used = 1; - -/* Temporarily switch off error reporting so that if the following attempt - to access the axis attribute fails, we can try to interpret the - attribute name as an attribute of the primary Frame containing the - specified axis. Any errors reported in this context will simply be - ignored, in particularly they are not deferred for later delivery. */ - oldrep = astReporting( 0 ); - -/* Use the Axis astSetAttrib method - to set the value. */ - astSetAttrib( ax, axis_setting ); - -/* If the above call failed with a status of AST__BADAT, indicating that - the attribute name was not recognised, clear the status so that we can - try to interpret the attribute name as an attribute of the primary Frame - containing the specified axis. */ - if( astStatus == AST__BADAT ) { - astClearStatus; - -/* Find the primary Frame containing the specified axis. */ - astPrimaryFrame( this, axis - 1, &pfrm, &paxis ); - -/* Only attempt to use the primary Frame if it is not the same as "this" - - otherwise we could end up in an infinite loop. */ - if( pfrm != this ) { - -/* astPrimaryFrame returns the original - unpermuted - axis index within - the primary Frame. So we need to take into account any axis permutation - which has been applied to the primary Frame when forming the attribute name - to use below. Find the permuted (external) axis index which corresponds to - the internal (unpermuted) axis index "paxis". */ - paxis = astValidateAxis( pfrm, paxis, 0, "astSet" ); - -/* Modify the attribute name to refer to the axis numbering of the - primary frame. */ - sprintf( pfrm_attrib, "%.*s(%d)", axis_nc, setting, paxis + 1 ); - -/* Create a setting string in which the attribute name refers to the axis - numbering of the primary frame. */ - pfrm_setting = NULL; - nc = 0; - pfrm_setting = astAppendString( pfrm_setting, &nc, pfrm_attrib ); - pfrm_setting = astAppendString( pfrm_setting, &nc, setting + axis_value ); - -/* Attempt to set the attribute within the primary Frame. */ - astSetAttrib( pfrm, pfrm_setting ); - -/* Free the memory. */ - pfrm_setting = astFree( pfrm_setting ); - -/* If this failed, clear the status and indicate that we have not managed to - use the attribute setting. */ - if( !astOK ) { - astClearStatus; - used = 0; - } - - } else { - used = 0; - } - -/* If not found attempt to set the attribute value in the Axis, omitting - the axis index. */ - if( ! used ) { - astSetAttrib( pfrm, axis_setting ); - if( !astOK ) { - astClearStatus; - } else { - used = 1; - } - } - -/* Free the setting string, and annul the primary Frame pointer. */ - pfrm = astAnnul( pfrm ); - } - -/* Re-instate the original error reporting state. */ - astReporting( oldrep ); - -/* If we could not use the setting, attempt to set the axis attribute again, - this time retaining the error report. This is done to ensure the user - gets an appropriate error message. */ - if( !used ) astSetAttrib( ax, axis_setting ); - } - -/* Annul the Axis pointer and free the memory holding the attribute - setting. */ - ax = astAnnul( ax ); - } - axis_setting = astFree( axis_setting ); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is still not recognised, and the Frame has only 1 axis, - and the attribute name does not already include an axis specifier, try - again after appending "(1)" to the end of the attribute name. */ - } else if( !has_axis && astGetNaxes( this ) == 1 && equals ) { - -/* Take a copy of the supplied setting, allowing 3 extra characters for the - axis specifier "(1)". */ - axis_setting = astMalloc( len + 4 ); - if( axis_setting ) memcpy( axis_setting, setting, len ); - -/* Indicate we should free the axis_setting memory. */ - free_axis_setting = 1; - -/* Add in the axis specifier. */ - strcpy( axis_setting + ( equals - setting ), "(1)" ); - -/* Add in the equals sign and attribute value. */ - strcpy( axis_setting + ( equals - setting ) + 3, equals ); - -/* Use the new setting instead of the supplied setting. */ - old_setting = setting; - setting = axis_setting; - -/* Indicate the setting now has an axis specifier. */ - has_axis = 1; - -/* Jump back to try interpreting the new setting string. */ - goto L1; - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. First re-instate the original setting - string if it was changed above. */ - } else { - if( free_axis_setting ) { - setting = old_setting; - axis_setting = astFree( axis_setting ); - free_axis_setting = 0; - } - (*parent_setattrib)( this_object, setting, status ); - } - - if( free_axis_setting ) axis_setting = astFree( axis_setting ); - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static void SetAxis( AstFrame *this, int axis, AstAxis *newaxis, int *status ) { -/* -*+ -* Name: -* astSetAxis - -* Purpose: -* Set a new Axis for a Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void astSetAxis( AstFrame *this, int axis, AstAxis *newaxis ) - -* Class Membership: -* Frame method. - -* Description: -* This function allows a new Axis object to be associated with one -* of the axes of a Frame, replacing the previous one. Each Axis -* object contains a description of the quantity represented along -* one of the Frame's axes, so this function allows this -* description to be exchanged for another one. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The index (zero-based) of the axis whose associated Axis object is to -* be replaced. -* newaxis -* Pointer to the new Axis object. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate and permute the axis index supplied. */ - axis = astValidateAxis( this, axis, 1, "astSetAxis" ); - -/* If OK, annul the Frame's pointer to the old Axis object and clone a pointer - to the new one to replace it. */ - if ( astOK ) { - this->axis[ axis ] = astAnnul( this->axis[ axis ] ); - this->axis[ axis ] = astClone( newaxis ); - } -} - -static void SetFrameFlags( AstFrame *this, int flags, int *status ){ -/* -*+ -* Name: -* astSetFrameFlags - -* Purpose: -* Store a new bit mask of flags in a Frame. - -* Type: -* Protected function. - -* Synopsis: -* #include "frame.h" -* void astSetFrameFlags( astFrame *this, int flags ) - -* Class Membership: -* Frame member function. - -* Description: -* This function stores a new set of flags in a Frame. The flags can -* be retrieved using astGetFrameFlags. - -* Parameters: -* this -* The Frame. -* flags -* A bit mask holding the flags. Currently, the following bits are -* used: -* -* 0 - Used to indicate if the Frame is currently involved in an -* attempt to restore the integrity of a FrameSet following -* changes to the attribute values of the Frame. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Assign the new bit mask. */ - this->flags = flags; -} - -static void SetFrameVariants( AstFrame *this, AstFrameSet *variants, int *status ){ -/* -*+ -* Name: -* astSetFrameVariants - -* Purpose: -* Store a FrameSet holding alternative Frame properties. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void astSetVariants( AstFrame *this, AstFrameSet *variants ) - -* Class Membership: -* Frame method. - -* Description: -* This function adds sets of alternative Frame properties to a Frame. - -* Parameters: -* this -* Pointer to the Frame. -* variants -* Pointer to a FrameSet in which each Frame is of the same class -* and dimensionality as "this" and all Frames have unique Domain -* names. - -* Notes: -* - A clone of the supplied FrameSet pointer is stored in the Frame. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Annul any variants FrameSet already stored in the Frame. */ - if( this->variants ) this->variants = astAnnul( this->variants ); - -/* Store a clone of ht esupplied FrameSet pointer. */ - if( variants ) this->variants = astClone( variants ); - -} - -static void SetUnit( AstFrame *this, int axis, const char *unit, int *status ) { -/* -* Name: -* SetUnit - -* Purpose: -* Set a value for the Unit attribute of a Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void SetUnit( AstFrame *this, int axis, const char *unit, int *status ) - -* Class Membership: -* Frame method. - -* Description: -* This function sets the Unit value for a Frame. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which the Unit value is to -* be set. -* unit -* The new value to be set. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - char *c; /* Copy of supplied string */ - const char *oldunit; /* Pointer to old units string */ - int l; /* Used length of supplied string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a copy of the supplied string which excludes trailing spaces. */ - l = astChrLen( unit ); - c = astStore( NULL, unit, (size_t) (l + 1) ); - if( astOK ) { - c[ l ] = 0; - -/* Validate the axis index and obtain a pointer to the required Axis. */ - (void) astValidateAxis( this, axis, 1, "astSetUnit" ); - ax = astGetAxis( this, axis ); - -/* The new unit may require the Label and/or Symbol to be changed, but - only if the Frames ActiveUnit flag is set. */ - if( astGetActiveUnit( this ) ) { - -/* Get the existing Axis unit, using the astGetUnit method (rather than - astGetAxisUnit) in order to get any default value in the case where - the Unit attribute is not set. */ - oldunit = astGetUnit( this, axis ); - -/* Assign the new Unit value. This modifies labels and/or Symbols if - necessary. */ - NewUnit( ax, oldunit, c, "astSetUnit", astGetClass( this ), status ); - } - -/* Set the Axis Unit attribute value. */ - astSetAxisUnit( ax, c ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - } - -/* Free the string copy */ - c = astFree( c ); - -} - -static int SubFrame( AstFrame *target, AstFrame *template, - int result_naxes, const int *target_axes, - const int *template_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -*+ -* Name: -* astSubFrame - -* Purpose: -* Select axes from a Frame and convert to the new coordinate system. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astSubFrame( AstFrame *target, AstFrame *template, -* int result_naxes, const int *target_axes, -* const int *template_axes, AstMapping **map, -* AstFrame **result ) - -* Class Membership: -* Frame method. - -* Description: -* This function selects a requested sub-set (or super-set) of the axes from -* a "target" Frame and creates a new Frame with copies of the selected -* axes assembled in the requested order. It then optionally overlays the -* attributes of a "template" Frame on to the result. It returns both the -* resulting Frame and a Mapping that describes how to convert between the -* coordinate systems described by the target and result Frames. If -* necessary, this Mapping takes account of any differences in the Frames' -* attributes due to the influence of the template. - -* Parameters: -* target -* Pointer to the target Frame, from which axes are to be selected. -* template -* Pointer to the template Frame, from which new attributes for the -* result Frame are to be obtained. Optionally, this may be NULL, in -* which case no overlaying of template attributes will be performed. -* result_naxes -* Number of axes to be selected from the target Frame. This number may -* be greater than or less than the number of axes in this Frame (or -* equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving a list -* of the (zero-based) axis indices of the axes to be selected from the -* target Frame. The order in which these are given determines the order -* in which the axes appear in the result Frame. If any of the values in -* this array is set to -1, the corresponding result axis will not be -* derived from the target Frame, but will be assigned default attributes -* instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This should -* contain a list of the template axes (given as zero-based axis indices) -* with which the axes of the result Frame are to be associated. This -* array determines which axes are used when overlaying axis-dependent -* attributes of the template on to the result. If any element of this -* array is set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not used and -* a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned Mapping. -* The forward transformation of this Mapping will describe how to -* convert coordinates from the coordinate system described by the target -* Frame to that described by the result Frame. The inverse -* transformation will convert in the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is -* possible between the target and the result Frame. Otherwise zero -* is returned and *map and *result are returned as NULL (but this -* will not in itself result in an error condition). In general, -* coordinate conversion should always be possible if no template -* Frame is supplied but may not always be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. - -* Implementation Deficiencies: -* - Any axis selection is currently permitted. Probably this -* should be restricted so that each axis can only be selected -* once. The astValidateAxisSelection method will do this but -* currently there are bugs in the CmpFrame class that cause axis -* selections which will not pass this test. Install the validation -* when these are fixed. -*- - -* Implementation Notes: -* - This implementation addresses the selection of axes from a -* Frame class object. This simply results in another object of the -* same class and a Mapping which describes an axis permutation (or -* a unit Mapping as a special case). Changes of Frame attributes -* have no significance for coordinate values in this class, so do -* not affect the Mapping returned. -*/ - -/* Local Variables: */ - AstAxis *newaxis; /* Pointer to new Axis object */ - AstFrame *tempframe; /* Pointer to temporary Frame */ - AstMapping *aumap; /* A units Mapping for a single axis */ - AstMapping *numap; /* The new total units Mapping */ - AstMapping *umap; /* The total units Mapping */ - int *inperm; /* Pointer to permutation array */ - int *outperm; /* Pointer to permutation array */ - int match; /* Coordinate conversion possible? */ - int result_axis; /* Result Frame axis index */ - int target_axis; /* Target Frame axis index */ - int target_naxes; /* Number of target Frame axes */ - int unit; /* Unit Mapping appropriate? */ - int uunit; /* Is the "umap" Mapping a UnitMap? */ - -/* Initialise the returned values. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain the number of target Frame axes. */ - target_naxes = astGetNaxes( target ); - -/* Ensure we do not attempt to use a negative number of result axes. */ - if ( result_naxes < 0 ) result_naxes = 0; - -/* Create a temporary new Frame with the required number of axes. This will - have a default Axis object associated with each of its axes. We will - replace these where necessary with copies of the actual Axis objects we - require. */ - tempframe = astFrame( result_naxes, "", status ); - -/* Allocate memory to store two permutation arrays. These will be used to - construct the Mapping that relates the target and result Frames. */ - inperm = astMalloc( sizeof( int ) * (size_t) target_naxes ); - outperm = astMalloc( sizeof( int ) * (size_t) result_naxes ); - if ( astOK ) { - -/* Initialise the array that associates each target axis with the corresponding - result axis (filling it with the value -1 initially signifies no - associations). */ - for ( target_axis = 0; target_axis < target_naxes; target_axis++ ) { - inperm[ target_axis ] = -1; - } - -/* Loop through each axis in the result Frame and obtain the index of the axis - in the target Frame from which it is to be derived. */ - for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) { - target_axis = target_axes[ result_axis ]; - -/* Check if the resulting axis index is valid. If not, this result axis is not - to be derived from any target axis, and it will therefore be left with its - default attributes. Make an entry in the appropriate permutation array to - indicate that this result axis is unassociated. */ - if ( ( target_axis < 0 ) || ( target_axis >= target_naxes ) ) { - outperm[ result_axis ] = -1; - -/* Otherwise, obtain a pointer to the target Axis object and modify the - temporary Frame so that its axis is associated with the same Axis object. - Annul the Axis pointer afterwards. */ - } else { - newaxis = astGetAxis( target, target_axis ); - astSetAxis( tempframe, result_axis, newaxis ); - newaxis = astAnnul( newaxis ); - -/* Update both permutation arrays to record the association between the target - and result axes. */ - outperm[ result_axis ] = target_axis; - inperm[ target_axis ] = result_axis; - } - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - -/* So far, we have only modified pointers in the temporary Frame to refer to - the target Frame's Axis objects. Since we will next modify these objects' - attributes, we must make a deep copy of the entire temporary Frame so that - we do not modify the target's axes. This copy now becomes our result Frame. - Annul the temporary one. */ - if ( astOK ) { - *result = astCopy( tempframe ); - tempframe = astAnnul( tempframe ); - -/* Invoke the target "astOverlay" method to overlay any remaining - attributes from the target Frame which are not associated with - individual axes (e.g. the Frame's Title and Domain). */ - astOverlay( target, target_axes, *result ); - -/* If a template Frame was supplied, also invoke its astOverlay method to - overlay its attributes on the result Frame. (Note that in this particular - case this has no effect other than transferring attributes. In general, - however, i.e. in derived classes, this process is vital to determining the - mapping below, whose main purpose is to convert between the target and - result Frames. These will have different attributes as a result of the - influence that the template has here.) */ - if ( template ) astOverlay( template, template_axes, *result ); - -/* We will next generate the Mapping that relates the target and result - Frames. If appropriate this should be a unit Mapping (UnitMap), so test if - the number of axes in both Frames is equal. */ - unit = ( target_naxes == result_naxes ); - -/* If so, check the contents of one of the permutation arrays to see if all - result axes are associated with the corresponding target axis (the converse - then also follows). If not, note this fact and quit checking. */ - if ( unit ) { - for ( result_axis = 0; result_axis < result_naxes; - result_axis++ ) { - if ( outperm[ result_axis ] != result_axis ) { - unit = 0; - break; - } - } - } - -/* If a unit Mapping is appropriate, then construct it. */ - if ( unit ) { - *map = (AstMapping *) astUnitMap( result_naxes, "", status ); - -/* Otherwise, construct a Mapping describing the axis permutation we have - produced. */ - } else { - *map = (AstMapping *) astPermMap( target_naxes, inperm, - result_naxes, outperm, NULL, - "", status ); - } - -/* Note that coordinate conversion is possible. */ - match = 1; - -/* If the ActiveUnit flag in both template and result Frame is non-zero, we - now modify the Mapping to take account of any differences in the Units - attributes of the target and results Frames. */ - if( template && astGetActiveUnit( template ) && - astGetActiveUnit( *result ) ) { - -/* Loop round the axes of the results Frame, accumulating a parallel CmpMap - ("umap") in which each Mapping is the 1-D Mapping which transforms the - Units of the corresponding target axis into the Units of the results - axis. */ - umap = NULL; - uunit = 1; - for( result_axis = 0; result_axis < result_naxes; result_axis++ ) { - -/* Find the index of the corresponding target axis. */ - if( unit ) { - target_axis = result_axis; - } else { - target_axis = outperm[ result_axis ]; - } - -/* Get the Unit string for both axes, and attempt to find a Mapping which - transforms values in the target units into the corresponding value in the - results units. If this results axis does not have a corresponding - target axis, then indicate that no units mapping can be found. */ - if( target_axis > -1 ) { - aumap = astUnitMapper( astGetUnit( target, target_axis ), - astGetUnit( *result, result_axis ), - NULL, NULL ); - } else { - aumap = NULL; - } - -/* If no Mapping could be found, annull the Mapping and leave the loop. - Otherwise, see if the Mapping is a UnitMap. If not, set a flag to indicate - that we have at least one non-unit map. */ - if( !aumap ) { - if( umap ) umap = astAnnul( umap ); - match = 0; - break; - } else { - if( !astIsAUnitMap( aumap ) ) uunit = 0; - } - -/* Add this Mapping into the parallel CmpMap. */ - if( umap ) { - numap = (AstMapping *) astCmpMap( umap, aumap, 0, "", status ); - umap = astAnnul( umap ); - aumap = astAnnul( aumap ); - umap = numap; - } else { - umap = aumap; - } - } - -/* If the resulting CmpMap is not just a UnitMap, add it in series with - the current results mapping, and then simplify it. */ - if( !uunit && umap ) { - numap = (AstMapping *) astCmpMap( *map, umap, 1, "", status ); - (void) astAnnul( *map ); - *map = numap; - } - -/* Annul the CmpMap containing the units Mappings. */ - if( umap ) umap = astAnnul( umap ); - -/* If the units could not bve matched annul the returned mapping. */ - if( !match && *map ) *map = astAnnul( *map ); - } - } - } - -/* Free the memory used for the permutation arrays. */ - inperm = astFree( inperm ); - outperm = astFree( outperm ); - -/* If an error occurred, annul the returned objects and reset the returned - value. */ - if ( !astOK ) { - *map = astAnnul( *map ); - *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) { -/* -*+ -* Name: -* astSystemCode - -* Purpose: -* Convert a string into a coordinate system type code. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* AstSystemType SystemCode( AstFrame *this, const char *system ) - -* Class Membership: -* Frame method. - -* Description: -* This function converts a string used for the external description of -* a coordinate system into a Frame coordinate system type code (System -* attribute value). It is the inverse of the astSystemString function. - -* Parameters: -* this -* Pointer to the Frame. -* system -* Pointer to a constant null-terminated string containing the -* external description of the coordinate system. - -* Returned Value: -* The System type code. - -* Notes: -* - A value of AST__BADSYSTEM is returned if the coordinate system -* description was not recognised. This does not produce an error. -* - A value of AST__BADSYSTEM is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*- -*/ - -/* Local Variables: */ - AstSystemType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" string against each possibility and assign the - result. The basic Frame class only supports a single system - "Cartesian". */ - if ( astChrMatch( "Cartesian", system ) ) { - result = AST__CART; - } - -/* Return the result. */ - return result; -} - -static const char *SystemString( AstFrame *this, AstSystemType system, int *status ) { -/* -*+ -* Name: -* astSystemString - -* Purpose: -* Convert a coordinate system type code into a string. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* const char *astSystemString( AstFrame *this, AstSystemType system ) - -* Class Membership: -* Frame method. - -* Description: -* This function converts a Frame coordinate system type code -* (System attribute value) into a string suitable for use as an -* external representation of the coordinate system type. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The coordinate system type code. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*- -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. (Where possible, return the same string as would be - used in the FITS WCS representation of the coordinate system). A basic - Frame only allows a single System value, "Cartesian". */ - switch ( system ) { - case AST__CART: - result = "Cartesian"; - break; - } - -/* Return the result pointer. */ - return result; - -} - -static int TestActiveUnit( AstFrame *this, int *status ){ -/* -*+ -* Name: -* astTestActiveUnit - -* Purpose: -* Determines if the ActiveUnit flag is set. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astTestActiveUnit( AstFrame *this ) - -* Class Membership: -* Frame method. - -* Description: -* This function tests the current value of the ActiveUnit flag for a -* Frame. See the description of the astSetActiveUnit function for a -* description of the ActiveUnit flag. - -* Parameters: -* this -* Pointer to the Frame. - -* Returned Value: -* Non-zero if the flag has been set. Zero otherwise. - -* Notes: -* - A zero value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*-- -*/ - -/* Local Variables: */ - int result; /* The returned value */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Return the result. */ - return ( this->active_unit != -INT_MAX ); -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Frame member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Frame's attributes. - -* Parameters: -* this -* Pointer to the Frame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis */ - AstFrame *pfrm; /* Pointer to primary Frame containing axis */ - AstFrame *this; /* Pointer to the Frame structure */ - char pfrm_attrib[ 100 ]; /* Primary Frame attribute */ - char *axis_attrib; /* Pointer to axis attribute name */ - const char *old_attrib; /* Pointer to supplied attribute name string */ - int axis; /* Frame axis number */ - int axis_nc; /* No. characters in axis attribute name */ - int free_axis_attrib; /* Should axis_attrib be freed? */ - int has_axis; /* Does attrib name include axis specifier? */ - int len; /* Length of attrib string */ - int nc; /* No. characters read by astSscanf */ - int oldrep; /* Original error reporting state */ - int paxis; /* Axis index within primary frame */ - int result; /* Result value to return */ - int used; /* Could the setting string be used? */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) this_object; - -/* Set a flag indicating if the attribute name includes an axis - specifier. */ - has_axis = ( strchr( attrib, '(' ) != NULL ); - -/* A flag indicating that we do not need to free the axis_attrib memory. */ - free_axis_attrib = 0; - -/* Initialise things to avoid compiler warnings. */ - axis_attrib = NULL; - old_attrib = NULL; - -/* Jump back to here if we are trying the same attribute but with an explicit - axis "(1)" added to the end of the name. */ -L1: - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* Digits. */ -/* ------- */ - if ( !strcmp( attrib, "digits" ) ) { - result = astTestDigits( this ); - -/* Digits(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "digits(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - -/* There is no function to test the Digits attribute for an axis - directly, so obtain a pointer to the Axis and use this to test the - attribute. */ - (void) astValidateAxis( this, axis - 1, 1, "astTestDigits(axis)" ); - ax = astGetAxis( this, axis - 1 ); - result = astTestAxisDigits( ax ); - ax = astAnnul( ax ); - -/* Direction(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "direction(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestDirection( this, axis - 1 ); - -/* Epoch. */ -/* ------ */ - } else if ( !strcmp( attrib, "epoch" ) ) { - result = astTestEpoch( this ); - -/* Bottom(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "bottom(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestBottom( this, axis - 1 ); - -/* Top(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "top(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestTop( this, axis - 1 ); - -/* Domain. */ -/* ------- */ - } else if ( !strcmp( attrib, "domain" ) ) { - result = astTestDomain( this ); - -/* Format(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "format(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestFormat( this, axis - 1 ); - -/* Label(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "label(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLabel( this, axis - 1 ); - -/* MatchEnd. */ -/* --------- */ - } else if ( !strcmp( attrib, "matchend" ) ) { - result = astTestMatchEnd( this ); - -/* MaxAxes. */ -/* -------- */ - } else if ( !strcmp( attrib, "maxaxes" ) ) { - result = astTestMaxAxes( this ); - -/* MinAxes. */ -/* -------- */ - } else if ( !strcmp( attrib, "minaxes" ) ) { - result = astTestMinAxes( this ); - -/* Permute. */ -/* -------- */ - } else if ( !strcmp( attrib, "permute" ) ) { - result = astTestPermute( this ); - -/* PreserveAxes. */ -/* ------------- */ - } else if ( !strcmp( attrib, "preserveaxes" ) ) { - result = astTestPreserveAxes( this ); - -/* Symbol(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "symbol(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestSymbol( this, axis - 1 ); - -/* AlignSystem. */ -/* ------------ */ - } else if ( !strcmp( attrib, "alignsystem" ) ) { - result = astTestAlignSystem( this ); - -/* System. */ -/* ------- */ - } else if ( !strcmp( attrib, "system" ) ) { - result = astTestSystem( this ); - -/* Title. */ -/* ------ */ - } else if ( !strcmp( attrib, "title" ) ) { - result = astTestTitle( this ); - -/* Unit(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "unit(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestUnit( this, axis - 1 ); - -/* ObsLat. */ -/* ------- */ - } else if ( !strcmp( attrib, "obslat" ) ) { - result = astTestObsLat( this ); - -/* ObsLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "obslon" ) ) { - result = astTestObsLon( this ); - -/* ObsAlt. */ -/* ------- */ - } else if ( !strcmp( attrib, "obsalt" ) ) { - result = astTestObsAlt( this ); - -/* Dtai. */ -/* ---- */ - } else if ( !strcmp( attrib, "dtai" ) ) { - result = astTestDtai( this ); - -/* Dut1. */ -/* ---- */ - } else if ( !strcmp( attrib, "dut1" ) ) { - result = astTestDut1( this ); - -/* Read-only attributes. */ -/* --------------------- */ -/* Test if the attribute name matches any of the read-only attributes - of this class. If it does, then return zero. */ - } else if ( !strcmp( attrib, "naxes" ) || - !strncmp( attrib, "normunit", 8 ) || - !strncmp( attrib, "internalunit", 12 ) ) { - result = 0; - -/* Other axis attributes. */ -/* ---------------------- */ -/* If the attribute was not identified above, but appears to refer to - a Frame axis, then it may refer to an Axis object of a derived type - (which has additional attributes not recognised here). */ - } else if ( !free_axis_attrib && ( nc = 0, - ( 1 == astSscanf( attrib, "%*[^()]%n(%d)%n", - &axis_nc, &axis, &nc ) ) - && ( nc >= len ) ) ) { - -/* Validate the axis index and extract the attribute name. */ - (void) astValidateAxis( this, axis - 1, 1, "astTest" ); - axis_attrib = astString( attrib, axis_nc ); - -/* Obtain a pointer to the Axis object. */ - ax = astGetAxis( this, axis - 1 ); - if( astOK ) { - -/* Assume that we will be able to use the attribute name. */ - used = 1; - -/* Temporarily switch off error reporting so that if the following attempt - to access the axis attribute fails, we can try to interpret the - attribute name as an attribute of the primary Frame containing the - specified axis. Any errors reported in this context will simply be - ignored, in particularly they are not deferred for later delivery. */ - oldrep = astReporting( 0 ); - -/* Use the Axis astTestAttrib method to test the attribute value. */ - result = astTestAttrib( ax, axis_attrib ); - -/* If the above call failed with a status of AST__BADAT, indicating that - the attribute name was not recognised, clear the status so that we can - try to interpret the attribute name as an attribute of the primary Frame - containing the specified axis. */ - if( astStatus == AST__BADAT ) { - astClearStatus; - -/* Find the primary Frame containing the specified axis. */ - astPrimaryFrame( this, axis - 1, &pfrm, &paxis ); - -/* Only attempt to use the primary Frame if it is not the same as "this" - - otherwise we could end up in an infinite loop. */ - if( pfrm != this ) { - -/* astPrimaryFrame returns the original - unpermuted - axis index within - the primary Frame. So we need to take into account any axis permutation - which has been applied to the primary Frame when forming the attribute name - to use below. Find the permuted (external) axis index which corresponds to - the internal (unpermuted) axis index "paxis". */ - paxis = astValidateAxis( pfrm, paxis, 0, "astTest" ); - -/* Modify the attribute name to refer to the axis numbering of the - primary frame. */ - sprintf( pfrm_attrib, "%s(%d)", axis_attrib, paxis + 1 ); - -/* Attempt to test the attribute as an attribute of the primary Frame. */ - result = astTestAttrib( pfrm, pfrm_attrib ); - -/* If this failed, clear the status and indicate that we have not managed to - use the attribute name. */ - if( !astOK ) { - astClearStatus; - used = 0; - } - - } else { - used = 0; - } - -/* If not found attempt to test the attribute value in the Axis, omitting - the axis index. */ - if( ! used ) { - result = astTestAttrib( pfrm, axis_attrib ); - if( !astOK ) { - astClearStatus; - } else { - used = 1; - } - } - -/* Annul the primary Frame pointer. */ - pfrm = astAnnul( pfrm ); - } - -/* Re-instate the original error reporting state. */ - astReporting( oldrep ); - -/* If we could not use the attribute name, attempt to test the axis - attribute again, this time retaining the error report. This is done - to ensure the user gets an appropriate error message. */ - if( !used ) result = astTestAttrib( ax, axis_attrib ); - } - -/* Annul the Axis pointer and free the memory holding the attribute - name. */ - ax = astAnnul( ax ); - axis_attrib = astFree( axis_attrib ); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is still not recognised, and the Frame has only 1 axis, - and the attribute name does not already include an axis specifier, try - again after appending "(1)" to the end of the attribute name. */ - } else if( !has_axis && astGetNaxes( this ) == 1 ) { - -/* Take a copy of the supplied name, allowing 3 extra characters for the - axis specifier "(1)". */ - axis_attrib = astMalloc( len + 4 ); - if( axis_attrib ) memcpy( axis_attrib, attrib, len ); - -/* Indicate we should free the axis_attrib memory. */ - free_axis_attrib = 1; - -/* Add in the axis specifier. */ - strcpy( axis_attrib + len, "(1)" ); - -/* Use the new attribute name instead of the supplied name. */ - old_attrib = attrib; - attrib = axis_attrib; - -/* Indicate the attribute name now has an axis specifier. */ - has_axis = 1; - -/* Jump back to try interpreting the new attribute name. */ - goto L1; - -/* Not recognised. */ -/* --------------- */ -/* If the attribute name is still not recognised, pass it on to the parent - method for further interpretation. First re-instate the original attrib - name string if it was changed above. */ - } else { - if( free_axis_attrib ) { - attrib = old_attrib; - axis_attrib = astFree( axis_attrib ); - } - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Use a Frame to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* Frame member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a Frame and a set of points encapsulated in a -* PointSet and transforms the points so as to perform the identity -* transformation (i.e. simply copies the coordinate values). - -* Parameters: -* this -* Pointer to the Frame. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. In this case, both transformations are equivalent. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the Frame being applied. This number -* will be equal to the number of Frame axes. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstFrame *this; /* Pointer to the Frame structure */ - AstPointSet *result; /* Pointer value to be returned */ - AstUnitMap *unitmap; /* Pointer to temporary UnitMap */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) this_mapping; - -/* Create a unit Mapping with one coordinate for each Frame axis. */ - unitmap = astUnitMap( astGetNaxes( this ), "", status ); - -/* Use the Mapping to transform (i.e. copy) the coordinate values. */ - result = astTransform( unitmap, in, forward, out ); - -/* Annul the Mapping. */ - unitmap = astAnnul( unitmap ); - -/* If an error occurred and a new PointSet may have been created, then annul - the result. In any case, ensure that a NULL pointer is returned. */ - if ( !astOK ) { - if ( !out ) result = astAnnul( result ); - result = NULL; - } - -/* Return the result pointer. */ - return result; -} - -static int Unformat( AstFrame *this, int axis, const char *string, - double *value, int *status ) { -/* -*+ -* Name: -* astUnformat - -* Purpose: -* Read a formatted coordinate value for a Frame axis. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astUnformat( AstFrame *this, int axis, const char *string, -* double *value ) - -* Class Membership: -* Frame method. - -* Description: -* This function reads a formatted coordinate value for a Frame -* axis (supplied as a string) and returns the equivalent numerical -* value as a double. It also returns the number of characters read -* from the string. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the Frame axis for which the coordinate value -* is to be read (axis numbering starts at zero for the first -* axis). -* string -* Pointer to a constant null-terminated string containing the -* formatted coordinate value. -* value -* Pointer to a double in which the coordinate value read will be -* returned. - -* Returned Value: -* The number of characters read from the string to obtain the -* coordinate value. - -* Notes: -* - Any white space at the beginning of the string will be -* skipped, as also will any trailing white space following the -* coordinate value read. The function's return value will reflect -* this. -* - A function value of zero (and no coordinate value) will be -* returned, without error, if the string supplied does not contain -* a suitably formatted value. -* - The string "" is recognised as a special case and will -* generate the value AST__BAD, without error. The test for this -* string is case-insensitive and permits embedded white space. -* - A function result of zero will be returned and no coordinate -* value will be returned via the "value" pointer if this function -* is invoked with the global error status set, or if it should -* fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic astUnformat method -* available via the protected interface to the Frame class. The -* public interface to this method is provided by the -* astUnformatId_ function. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - const char *label; /* Pointer to axis label string */ - double coord; /* Coordinate value read */ - int digits_set; /* Axis Digits attribute set? */ - int nc; /* Number of characters read */ - int status_value; /* AST error status */ - -/* Initialise. */ - nc = 0; - -/* Check the global error status. */ - if ( !astOK ) return nc; - -/* Validate the axis index and obtain a pointer to the required Axis. */ - (void) astValidateAxis( this, axis, 1, "astUnformat" ); - ax = astGetAxis( this, axis ); - -/* Test if any Axis attributes which may affect the result are - undefined (i.e. have not been explicitly set). If so, we over-ride - them, giving them temporary values dictated by the Frame. Only the - Digits attribute is potentially relevant here. */ - digits_set = astTestAxisDigits( ax ); - if ( !digits_set ) astSetAxisDigits( ax, astGetDigits( this ) ); - -/* Read the coordinate value. */ - if ( astOK ) { - nc = astAxisUnformat( ax, string, &coord ); - -/* If an error occurred, save and temporarily clear the global error - status while the axis Label string is obtained. Then restore the - original error status value afterwards. */ - if ( !astOK ) { - status_value = astStatus; - astClearStatus; - label = astGetLabel( this, axis ); - astSetStatus( status_value ); - -/* Report a contextual error message containing the axis label. */ - astError( status_value, "%s(%s): Unable to read \"%s\" value.", status, - "astUnformat", astGetClass( this ), label ); - } - } - -/* Clear any Axis attributes that were temporarily over-ridden. */ - if ( !digits_set ) astClearAxisDigits( ax ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* If an error occurred, clear the count of characters read. */ - if ( !astOK ) { - nc = 0; - -/* Otherwise, if characters were read, return the coordinate value. */ - } else if ( nc ) { - *value = coord; - } - -/* Return the number of characters read. */ - return nc; -} - -static int ValidateAxis( AstFrame *this, int axis, int fwd, const char *method, - int *status ) { -/* -*+ -* Name: -* astValidateAxis - -* Purpose: -* Validate and permute a Frame's axis index. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astValidateAxis( AstFrame *this, int axis, int fwd, -* const char *method ) - -* Class Membership: -* Frame method. - -* Description: -* This function checks the validity of an index (zero-based) which -* is to be used to address one of the coordinate axes of a -* Frame. If the index is valid, it is permuted using the axis -* permutation array associated with the Frame and the (zero-based) -* permuted axis index is returned. This gives the location of the -* required axis information within the Frame's internal arrays. If -* the axis index supplied is not valid, an error is reported and -* the global error status is set. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The axis index (zero-based) to be checked. To be valid, it -* must lie between zero and (naxes-1) inclusive, where "naxes" -* is the number of coordinate axes associated with the Frame. -* fwd -* If non-zero, the suppplied axis index is assumed to be an -* "external" axis index, and the corresponding "internal" axis index -* is returned as the function value. Otherwise, the suppplied axis -* index is assumed to be an "internal" axis index, and the -* corresponding "external" axis index is returned as the function -* value. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. - -* Returned Value: -* The permuted axis index - either "internal" or "external" as -* specified by "fwd". - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -* - Error messages issued by this function refer to the public -* numbering system used for axes which is one-based (zero-based axis -* indices are used internally). -*- -*/ - -/* Local Variables: */ - const int *perm; /* Pointer to axis permutation array */ - int naxes; /* Number of Frame axes */ - int result; /* Permuted axis index */ - -/* Initialise. */ - result = 0; - -/* Determine the number of Frame axes. */ - naxes = astGetNaxes( this ); - if ( astOK ) { - -/* If the Frame has no axes, report an error (note we convert to - one-based axis numbering in the error message). */ - if ( naxes == 0 ) { - astError( AST__AXIIN, "%s(%s): Invalid attempt to use an axis index " - "(%d) for a %s which has no axes.", status, method, - astGetClass( this ), axis + 1, astGetClass( this ) ); - -/* Otherwise, check the axis index for validity and report an error if - it is not valid (again, use one-based axis numbering). */ - } else if ( ( axis < 0 ) || ( axis >= naxes ) ) { - astError( AST__AXIIN, "%s(%s): Axis index (%d) invalid - it should " - "be in the range 1 to %d.", status, method, astGetClass( this ), - axis + 1, naxes ); - -/* If the axis index was valid, obtain the axis permutation array and - use this to generate the permuted axis value. */ - } else { - perm = astGetPerm( this ); - if( perm ) { - -/* External to internal is a simple look-up. */ - if( fwd ) { - result = perm[ axis ]; - -/* Internal to external requires a search through the permutation array. */ - } else { - for( result = 0; result < naxes; result++ ) { - if( perm[ result ] == axis ) break; - } - } - } - } - } - -/* Return the result. */ - return result; -} - -static void ValidateAxisSelection( AstFrame *this, int naxes, const int *axes, - const char *method, int *status ) { -/* -*+ -* Name: -* astValidateAxisSelection - -* Purpose: -* Check that a set of axes selected from a Frame is valid. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* void astValidateAxisSelection( AstFrame *this, int naxes, -* const int *axes, const char *method ) - -* Class Membership: -* Frame method. - -* Description: -* This function checks the validity of an array of (zero-based) -* axis indices that specify a set of axes to be selected from a -* Frame. To be valid, no axis should be selected more than -* once. In assessing this, any axis indices that do not refer to -* valid Frame axes (e.g. are set to -1) are ignored. -* -* If the axis selection is valid, this function returns without further -* action. Otherwise, an error is reported and the global error status is -* set. - -* Parameters: -* this -* Pointer to the Frame. -* naxes -* The number of axes to be selected (may be zero). -* axes -* Pointer to an array of int with naxes elements that contains the -* (zero based) axis indices to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis selection. This method name is used -* solely for constructing error messages. -*- -*/ - -/* Local Variables: */ - int *count; /* Pointer to temporary array of counts */ - int axis; /* Loop counter for selected axes */ - int frame_axis; /* Loop counter for Frame axes */ - int frame_naxes; /* Number of Frame axes */ - int valid; /* Axis selection valid? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check to see if no axes have been selected. If so, there is nothing to - do. */ - if ( naxes ) { - -/* Initialise. */ - valid = 1; - -/* Obtain the number of Frame axes and allocate an array of int with - one element for each Frame axis. This will store a count of the - number of times each axis is selected. */ - frame_naxes = astGetNaxes( this ); - count = astMalloc( sizeof( int ) * (size_t) frame_naxes ); - if ( astOK ) { - -/* Initialise the array of counts to zero. */ - for ( frame_axis = 0; frame_axis < frame_naxes; frame_axis++ ) { - count[ frame_axis ] = 0; - } - -/* Loop through each selected axis. */ - for ( axis = 0; axis < naxes; axis++ ) { - frame_axis = axes[ axis ]; - -/* Check if the selected axis index is valid for the Frame. If so, increment - the selection count for that Frame axis. */ - if ( ( frame_axis >= 0 ) && ( frame_axis < frame_naxes ) ) { - count[ frame_axis ]++; - } - } - -/* Loop through the count array and check that no Frame axis was selected - more than once. If it was, clear the "valid" flag and quit checking. */ - for ( frame_axis = 0; frame_axis < frame_naxes; frame_axis++ ) { - if ( count[ frame_axis ] > 1 ) { - valid = 0; - break; - } - } - } - -/* Free the temporary count array. */ - count = astFree( count ); - -/* If no error has occurred, but the axis selection is not valid, then report - an error. */ - if ( astOK && !valid ) { - astError( AST__SELIN, "%s(%s): Invalid axis selection - each axis " - "may be selected only once.", status, method, astGetClass( this ) ); - } - } -} - -static int ValidateSystem( AstFrame *this, AstSystemType system, const char *method, int *status ) { -/* -*+ -* Name: -* astValidateSystem - -* Purpose: -* Validate a value for a Frame's System attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int astValidateSystem( AstFrame *this, AstSystemType system, -* const char *method ) - -* Class Membership: -* Frame method. - -* Description: -* This function checks the validity of the supplied system value. -* If the value is valid, it is returned unchanged. Otherwise, an -* error is reported and a value of AST__BADSYSTEM is returned. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The system value to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. - -* Returned Value: -* The validated system value. - -* Notes: -* - A value of AST_BADSYSTEM will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstSystemType result; /* Validated system value */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the value is out of bounds, report an error. */ - if ( system < FIRST_SYSTEM || system > LAST_SYSTEM ) { - astError( AST__AXIIN, "%s(%s): Bad value (%d) given for the System " - "or AlignSystem attribute of a %s.", status, method, - astGetClass( this ), (int) system, astGetClass( this ) ); - -/* Otherwise, return the supplied value. */ - } else { - result = system; - } - -/* Return the result. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - the axes of a Frame using the private macros defined for this - purpose at the start of this file. */ - -/* -*att++ -* Name: -* Naxes - -* Purpose: -* Number of Frame axes. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This is a read-only attribute giving the number of axes in a -* Frame (i.e. the number of dimensions of the coordinate space -* which the Frame describes). This value is determined when the -* Frame is created. - -* Applicability: -* Frame -* All Frames have this attribute. -* FrameSet -* The Naxes attribute of a FrameSet is the same as that of its -* current Frame (as specified by the Current attribute). -* CmpFrame -* The Naxes attribute of a CmpFrame is equal to the sum of the -* Naxes values of its two component Frames. -*att-- -*/ - - -/* -*att++ -* Name: -* Direction(axis) - -* Purpose: -* Display axis in conventional direction? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which suggests how the axes of -* a Frame should be displayed (e.g.) in graphical output. By -* default, it has the value one, indicating that they should be -* shown in the conventional sense (increasing left to right for an -* abscissa, and bottom to top for an ordinate). If set to zero, -* this attribute indicates that the direction should be reversed, -* as would often be done for an astronomical magnitude or a right -* ascension axis. - -* Applicability: -* Frame -* The default Direction value supplied by the Frame class is 1, -* indicating that all axes should be displayed in the -* conventional direction. -* SkyFrame -* The SkyFrame class re-defines the default Direction value to -* suggest that certain axes (e.g. right ascension) should be -* plotted in reverse when appropriate. -* FrameSet -* The Direction attribute of a FrameSet axis is the same as -* that of its current Frame (as specified by the Current -* attribute). -* Plot -* The Direction attribute of the base Frame in a Plot is set to -* indicate the sense of the two graphics axes, as implied by the -* graphics bounding box supplied when the Plot was created. - -* Notes: -* - When specifying this attribute by name, it should be -* subscripted with the number of the Frame axis to which it -* applies. -* - The Direction attribute does not directly affect the behaviour -* of the AST library. Instead, it serves as a hint to applications -* programs about the orientation in which they may wish to display -* any data associated with the Frame. Applications are free to -* ignore this hint if they wish. -*att-- -*/ -/* This simply provides an interface to the Axis methods for accessing - the Direction flag. */ -MAKE_CLEAR(Direction) -MAKE_GET(Direction,int,0,0,0) -MAKE_SET(Direction,int) -MAKE_TEST(Direction) - -/* -*att++ -* Name: -* Dtai - -* Purpose: -* The TAI-UTC correction. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the difference between TAI and UTC (i.e. -* the number of leap seconds) at the moment corresponding to the -* Frame's Epoch value. The default value of AST__BAD causes the -* number of leap seconds to be determined from an internal look-up -* table, which is kept up-to-date manually by the AST development team. -* Therefore it is only necessary to assign a value to this attribute -* if the version of AST in use is so old that it does not include all -* leap seconds that occurred prior to the time represented by the -* Frame's Epoch value. - -* Applicability: -* Frame -* All Frames have this attribute. - -*att-- -*/ -/* The TAI-UTC correction, in seconds. Has a value of AST__BAD when not set. */ -astMAKE_CLEAR(Frame,Dtai,dtai,AST__BAD) -astMAKE_GET(Frame,Dtai,double,AST__BAD,(this->dtai)) -astMAKE_SET(Frame,Dtai,double,dtai,value) -astMAKE_TEST(Frame,Dtai,( this->dtai != AST__BAD )) - -/* -*att++ -* Name: -* Dut1 - -* Purpose: -* The UT1-UTC correction. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute is used when calculating the Local Apparent Sidereal -* Time corresponding to SkyFrame's Epoch value (used when converting -* positions to or from the "AzEl" system). It should be set to the -* difference, in seconds, between the UT1 and UTC timescales at the -* moment in time represented by the SkyFrame's Epoch attribute. The -* value to use is unpredictable and depends on changes in the earth's -* rotation speed. Values for UT1-UTC can be obtained from the -* International Earth Rotation and Reference Systems Service -* (IERS) at http://www.iers.org/. -* -* Currently, the correction is always less than 1 second. This is -* ensured by the occasional introduction of leap seconds into the UTC -* timescale. Therefore no great error will usually result if no value -* is assigned to this attribute (in which case a default value of -* zero is used). However, it is possible that a decision may be taken -* at some time in the future to abandon the introduction of leap -* seconds, in which case the DUT correction could grow to significant -* sizes. - -* Applicability: -* Frame -* All Frames have this attribute. - -*att-- -*/ -/* The UT1-UTC correction, in seconds. Has a value of AST__BAD when not set - yielding a default value of 0.0. */ -astMAKE_CLEAR(Frame,Dut1,dut1,AST__BAD) -astMAKE_GET(Frame,Dut1,double,0.0,(this->dut1 == AST__BAD ? 0.0 : this->dut1)) -astMAKE_SET(Frame,Dut1,double,dut1,value) -astMAKE_TEST(Frame,Dut1,( this->dut1 != AST__BAD )) - - - -/* -*att++ -* Name: -* Epoch - -* Purpose: -* Epoch of observation. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute is used to qualify the coordinate systems described by -* a Frame, by giving the moment in time when the coordinates are known -* to be correct. Often, this will be the date of observation, and is -* important in cases where coordinates systems move with respect to each -* other over the course of time. -* -* The Epoch attribute is stored as a Modified Julian Date, but -* when setting its value it may be given in a variety of -* formats. See the "Input Formats" section (below) for details. -* Strictly, the Epoch value should be supplied in the TDB timescale, -* but for some purposes (for instance, for converting sky positions -* between different types of equatorial system) the timescale is not -* significant, and UTC may be used. - -* Input Formats: -* The formats accepted when setting an Epoch value are listed -* below. They are all case-insensitive and are generally tolerant -* of extra white space and alternative field delimiters: -* -* - Besselian Epoch: Expressed in decimal years, with or without -* decimal places ("B1950" or "B1976.13" for example). -* -* - Julian Epoch: Expressed in decimal years, with or without -* decimal places ("J2000" or "J2100.9" for example). -* -* - Year: Decimal years, with or without decimal places ("1996.8" -* for example). Such values are interpreted as a Besselian epoch -* (see above) if less than 1984.0 and as a Julian epoch otherwise. -* -* - Julian Date: With or without decimal places ("JD 2454321.9" for -* example). -* -* - Modified Julian Date: With or without decimal places -* ("MJD 54321.4" for example). -* -* - Gregorian Calendar Date: With the month expressed either as an -* integer or a 3-character abbreviation, and with optional decimal -* places to represent a fraction of a day ("1996-10-2" or -* "1996-Oct-2.6" for example). If no fractional part of a day is -* given, the time refers to the start of the day (zero hours). -* -* - Gregorian Date and Time: Any calendar date (as above) but with -* a fraction of a day expressed as hours, minutes and seconds -* ("1996-Oct-2 12:13:56.985" for example). The date and time can be -* separated by a space or by a "T" (as used by ISO8601 format). - -* Output Format: -* When enquiring Epoch values, the format used is the "Year" -* format described under "Input Formats". This is a value in -* decimal years which will be a Besselian epoch if less than -* 1984.0 and a Julian epoch otherwise. By omitting any character -* prefix, this format allows the Epoch value to be obtained as -* either a character string or a floating point value. - -* Applicability: -* Frame -* All Frames have this attribute. The basic Frame class provides -* a default of J2000.0 (Julian) but makes no use of the Epoch value. -* This is because the Frame class does not distinguish between -* different Cartesian coordinate systems (see the System attribute). -* CmpFrame -* The default Epoch value for a CmpFrame is selected as follows; -* if the Epoch attribute has been set in the first component Frame -* then the Epoch value from the first component Frame is used as -* the default for the CmpFrame. Otherwise, if the Epoch attribute has -* been set in the second component Frame then the Epoch value from the -* second component Frame is used as the default for the CmpFrame. -* Otherwise, the default Epoch value from the first component -* Frame is used as the default for the CmpFrame. When the Epoch -* attribute of a CmpFrame is set or cleared, it is also set or -* cleared in the two component Frames. -* FrameSet -* The Epoch attribute of a FrameSet is the same as that of its current -* Frame (as specified by the Current attribute). -* SkyFrame -* The coordinates of sources within a SkyFrame can change with time -* for various reasons, including: (i) changing aberration of light -* caused by the observer's velocity (e.g. due to the Earth's motion -* around the Sun), (ii) changing gravitational deflection by the Sun -* due to changes in the observer's position with time, (iii) fictitious -* motion due to rotation of non-inertial coordinate systems (e.g. the -* old FK4 system), and (iv) proper motion of the source itself (although -* this last effect is not handled by the SkyFrame class because it -* affects individual sources rather than the coordinate system as -* a whole). -* -* The default Epoch value in a SkyFrame is B1950.0 (Besselian) for the -* old FK4-based coordinate systems (see the System attribute) and -* J2000.0 (Julian) for all others. -* -* Care must be taken to distinguish the Epoch value, which relates to -* motion (or apparent motion) of the source, from the superficially -* similar Equinox value. The latter is used to qualify a coordinate -* system which is itself in motion in a (notionally) predictable way -* as a result of being referred to a slowly moving reference plane -* (e.g. the equator). -* -* See the description of the System attribute for details of which -* qualifying attributes apply to each celestial coordinate system. -* TimeFrame -* A TimeFrame describes a general time axis and so cannot be completely -* characterised by a single Epoch value. For this reason the TimeFrame -* class makes no use of the Epoch attribute. However, user code can -* still make use of the attribute if necessary to represent a "typical" -* time spanned by the TimeFrame. The default Epoch value for a TimeFrame -* will be the TDB equivalent of the current value of the TimeFrame's -* TimeOrigin attribute. If no value has been set for TimeOrigin, -* then the default Epoch value is J2000.0. -*att-- -*/ -/* Clear the Epoch value by setting it to AST__BAD. */ -astMAKE_CLEAR(Frame,Epoch,epoch,AST__BAD) - -/* Provide a default value of J2000.0 setting. */ -astMAKE_GET(Frame,Epoch,double,AST__BAD,( - ( this->epoch != AST__BAD ) ? this->epoch : palEpj2d( 2000.0 ))) - -/* Allow any Epoch value to be set. */ -astMAKE_SET(Frame,Epoch,double,epoch,value) - -/* An Epoch value is set if it is not equal to AST__BAD. */ -astMAKE_TEST(Frame,Epoch,( this->epoch != AST__BAD )) - -/* -*att++ -* Name: -* Top(axis) - -* Purpose: -* Highest axis value to display - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute gives the highest axis value to be displayed (for -c instance, by the astGrid method). -f instance, by the AST_GRID method). - -* Applicability: -* Frame -* The default supplied by the Frame class is to display all axis -* values, without any limit. -* SkyFrame -* The SkyFrame class re-defines the default Top value to +90 degrees -* for latitude axes, and 180 degrees for co-latitude axes. The -* default for longitude axes is to display all axis values. - -* Notes: -* - When specifying this attribute by name, it should be -* subscripted with the number of the Frame axis to which it -* applies. -*att-- -*/ -/* This simply provides an interface to the Axis methods for accessing - the Top value. */ -MAKE_CLEAR(Top) -MAKE_GET(Top,double,DBL_MAX,0,DBL_MAX) -MAKE_SET(Top,double) -MAKE_TEST(Top) - -/* -*att++ -* Name: -* Bottom(axis) - -* Purpose: -* Lowest axis value to display - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute gives the lowest axis value to be displayed (for -c instance, by the astGrid method). -f instance, by the AST_GRID method). - -* Applicability: -* Frame -* The default supplied by the Frame class is to display all axis -* values, without any limit. -* SkyFrame -* The SkyFrame class re-defines the default Bottom value to -90 degrees -* for latitude axes, and 0 degrees for co-latitude axes. The -* default for longitude axes is to display all axis values. - -* Notes: -* - When specifying this attribute by name, it should be -* subscripted with the number of the Frame axis to which it -* applies. -*att-- -*/ -/* This simply provides an interface to the Axis methods for accessing - the Bottom value. */ -MAKE_CLEAR(Bottom) -MAKE_GET(Bottom,double,-DBL_MAX,0,-DBL_MAX) -MAKE_SET(Bottom,double) -MAKE_TEST(Bottom) - -/* -*att++ -* Name: -* Format(axis) - -* Purpose: -* Format specification for axis values. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies the format to be used when displaying -* coordinate values associated with a particular Frame axis -* (i.e. to convert values from binary to character form). It is -c interpreted by the astFormat function and determines the -f interpreted by the AST_FORMAT function and determines the -* formatting which it applies. -* -* If no Format value is set for a Frame axis, a default value is -* supplied instead. This is based on the value of the Digits, or -* Digits(axis), attribute and is chosen so that it displays the -* requested number of digits of precision. - -* Applicability: -* Frame -* The Frame class interprets this attribute as a format -* specification string to be passed to the C "printf" function -* (e.g. "%1.7G") in order to format a single coordinate value -* (supplied as a double precision number). -c -c When supplying a value for this attribute, beware that the -c "%" character may be interpreted directly as a format -c specification by some printf-like functions (such as -c astSet). You may need to double it (i.e. use "%%") to avoid -c this. -* SkyFrame -* The SkyFrame class re-defines the syntax and default value of -* the Format string to allow the formatting of sexagesimal -* values as appropriate for the particular celestial coordinate -* system being represented. The syntax of SkyFrame Format -* strings is described (below) in the "SkyFrame Formats" -* section. -* FrameSet -* The Format attribute of a FrameSet axis is the same as that -* of its current Frame (as specified by the Current -* attribute). Note that the syntax of the Format string is also -* determined by the current Frame. -* TimeFrame -* The TimeFrame class extends the syntax of the Format string to -* allow the formatting of TimeFrame axis values as Gregorian calendar -* dates and times. The syntax of TimeFrame Format strings is described -* (below) in the "TimeFrame Formats" section. - -* SkyFrame Formats: -* The Format string supplied for a SkyFrame should contain zero or -* more of the following characters. These may occur in any order, -* but the following is recommended for clarity: -* -* - "+": Indicates that a plus sign should be prefixed to positive -* values. By default, no plus sign is used. -* -* - "z": Indicates that leading zeros should be prefixed to the -* value so that the first field is of constant width, as would be -* required in a fixed-width table (leading zeros are always -* prefixed to any fields that follow). By default, no leading -* zeros are added. -* -* - "i": Use the standard ISO field separator (a colon) between -* fields. This is the default behaviour. -* -* - "b": Use a blank to separate fields. -* -* - "l": Use a letter ("h"/"d", "m" or "s" as appropriate) to -* separate fields. -* -* - "g": Use a letter and symbols to separate fields ("h"/"d", "m" or "s", -* etc, as appropriate), but include escape sequences in the formatted -* value so that the Plot class will draw the separators as small -* super-scripts. -c The default escape sequences are optimised for the pgplot graphics -c package, but new escape sequences may be specified using function -c astSetSkyDelim. -* -* - "d": Include a degrees field. Expressing the angle purely in -* degrees is also the default if none of "h", "m", "s" or "t" are -* given. -* -* - "h": Express the angle as a time and include an hours field -* (where 24 hours correspond to 360 degrees). Expressing the angle -* purely in hours is also the default if "t" is given without -* either "m" or "s". -* -* - "m": Include a minutes field. By default this is not included. -* -* - "s": Include a seconds field. By default this is not included. -* This request is ignored if "d" or "h" is given, unless a minutes -* field is also included. -* -* - "t": Express the angle as a time (where 24 hours correspond to -* 360 degrees). This option is ignored if either "d" or "h" is -* given and is intended for use where the value is to be expressed -* purely in minutes and/or seconds of time (with no hours -* field). If "t" is given without "d", "h", "m" or "s" being -* present, then it is equivalent to "h". -* -* - ".": Indicates that decimal places are to be given for the -* final field in the formatted string (whichever field this -* is). The "." should be followed immediately by an unsigned -* integer which gives the number of decimal places required, or by an -* asterisk. If an asterisk is supplied, a default number of decimal -* places is used which is based on the value of the Digits -* attribute. -* -* All of the above format specifiers are case-insensitive. If -* several characters make conflicting requests (e.g. if both "i" -* and "b" appear), then the character occurring last takes -* precedence, except that "d" and "h" always override "t". -* -* If the format string starts with a percentage sign (%), then the -* whole format string is assumed to conform to the syntax defined by -* the Frame class, and the axis values is formated as a decimal -* radians value. - -* TimeFrame Formats: -* The Format string supplied for a TimeFrame should either use the -* syntax defined by the base Frame class (i.e. a C "printf" format -* string), or the extended "iso" syntax described below (the default -* value is inherited from the Frame class): -* -* - C "printf" syntax: If the Format string is a C "printf" format -* description such as "%1.7G", the TimeFrame axis value will be -* formatted without change as a floating point value using this format. -* The formatted string will thus represent an offset from the zero point -* specified by the TimeFrame's TimeOrigin attribute, measured in -* units given by the TimeFrame's Unit attribute. -* -* - "iso" syntax: This is used to format a TimeFrame axis value as a -* Gregorian date followed by an optional time of day. If the Format -* value commences with the string "iso" then the TimeFrame axis value -* will be converted to an absolute MJD, including the addition of the -* current TimeOrigin value, and then formatted as a Gregorian date -* using the format "yyyy-mm-dd". Optionally, the Format value may -* include an integer precision following the "iso" specification (e.g. -* "iso.2"), in which case the time of day will be appended to the -* formatted date (if no time of day is included, the date field is -* rounded to the nearest day). The integer value in the Format string -* indicates the number of decimal places to use in the seconds field. For -* instance, a Format value of "iso.0" produces a time of day of the form -* "hh:mm:ss", and a Format value of "iso.2" produces a time of day of the -* form "hh:mm:ss.ss". The date and time fields will be separated by a -* space unless 'T' is appended to the end of string, in which case -* the letter T (upper case) will be used as the separator. The value of -* the Digits attribute is ignored when using this "iso" format. - -* Notes: -* - When specifying this attribute by name, it should be -* subscripted with the number of the Frame axis to which it -* applies. -*att-- -*/ -/* This simply provides an interface to the Axis methods for accessing - the Format string. */ -MAKE_CLEAR(Format) -MAKE_GET(Format,const char *,NULL,0,0) -MAKE_SET(Format,const char *) -MAKE_TEST(Format) - -/* -*att++ -* Name: -* Label(axis) - -* Purpose: -* Axis label. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies a label to be attached to each axis of -* a Frame when it is represented (e.g.) in graphical output. -* -* If a Label value has not been set for a Frame axis, then a -* suitable default is supplied. - -* Applicability: -* Frame -* The default supplied by the Frame class is the string "Axis -* ", where is 1, 2, etc. for each successive axis. -* SkyFrame -* The SkyFrame class re-defines the default Label value -* (e.g. to "Right ascension" or "Galactic latitude") as -* appropriate for the particular celestial coordinate system -* being represented. -* TimeFrame -* The TimeFrame class re-defines the default Label value as -* appropriate for the particular time system being represented. -* FrameSet -* The Label attribute of a FrameSet axis is the same as that of -* its current Frame (as specified by the Current attribute). - -* Notes: -* - Axis labels are intended purely for interpretation by human -* readers and not by software. -* - When specifying this attribute by name, it should be -* subscripted with the number of the Frame axis to which it -* applies. -*att-- -*/ -/* This provides an interface to the Axis methods for accessing the - Label string, but provides an alternative default Label based on - the axis number. This default string is written to the static - "label_buff" buffer and a pointer to this is returned if - required. */ -MAKE_CLEAR(Label) -MAKE_GET(Label,const char *,NULL,1,GetDefaultLabel( axis, status )) -MAKE_SET(Label,const char *) -MAKE_TEST(Label) - -/* -*att++ -* Name: -* Symbol(axis) - -* Purpose: -* Axis symbol. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies a short-form symbol to be used to -* represent coordinate values for a particular axis of a -* Frame. This might be used (e.g.) in algebraic expressions where -* a full description of the axis would be inappropriate. Examples -* include "RA" and "Dec" (for Right Ascension and Declination). -* -* If a Symbol value has not been set for a Frame axis, then a -* suitable default is supplied. - -* Applicability: -* Frame -* The default Symbol value supplied by the Frame class is the -* string "", where is 1, 2, etc. for successive -* axes, and is the value of the Frame's Domain -* attribute (truncated if necessary so that the final string -* does not exceed 15 characters). If no Domain value has been -* set, "x" is used as the value in constructing this -* default string. -* SkyFrame -* The SkyFrame class re-defines the default Symbol value -* (e.g. to "RA" or "Dec") as appropriate for the particular -* celestial coordinate system being represented. -* TimeFrame -* The TimeFrame class re-defines the default Symbol value as -* appropriate for the particular time system being represented. -* FrameSet -* The Symbol attribute of a FrameSet axis is the same as that -* of its current Frame (as specified by the Current attribute). - -* Notes: -* - When specifying this attribute by name, it should be -* subscripted with the number of the Frame axis to which it -* applies. -*att-- -*/ -/* This provides an interface to the Axis methods for accessing the - Symbol string, but provides an alternative default Symbol based on - the axis number and the Frame's Domain (if defined, otherwise "x" - is used). This default string is written to the static - "symbol_buff" buffer and a pointer to this is returned if - required. */ -MAKE_CLEAR(Symbol) -MAKE_GET(Symbol,const char *,NULL,1,GetDefaultSymbol( this, axis, status ) ) -MAKE_SET(Symbol,const char *) -MAKE_TEST(Symbol) - -/* -*att++ -* Name: -* Unit(axis) - -* Purpose: -* Physical units for formatted axis values - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute contains a textual representation of the physical -* units used to represent formatted coordinate values on a particular -* axis of a Frame. -c The astSetActiveUnit function controls how the Unit values -f The AST_SETACTIVEUNIT routine controls how the Unit values -* are used. - -* Applicability: -* Frame -* The default supplied by the Frame class is an empty string. -* SkyFrame -* The SkyFrame class re-defines the default Unit value (e.g. to -* "hh:mm:ss.sss") to describe the character string returned by -c the astFormat function when formatting coordinate values. -f the AST_FORMAT function when formatting coordinate values. -* SpecFrame -* The SpecFrame class re-defines the default Unit value so that it -* is appropriate for the current System value. See the System -* attribute for details. An error will be reported if an attempt -* is made to use an inappropriate Unit. -* TimeFrame -* The TimeFrame class re-defines the default Unit value so that it -* is appropriate for the current System value. See the System -* attribute for details. An error will be reported if an attempt -* is made to use an inappropriate Unit (e.g. "km"). -* FrameSet -* The Unit attribute of a FrameSet axis is the same as that of -* its current Frame (as specified by the Current attribute). - -* Notes: -* - This attribute described the units used when an axis value is -* formatted into a string using -c astFormat. -f AST_FORMAT. -* In some cases these units may be different to those used to represent -* floating point axis values within application code (for instance a -* SkyFrame always uses radians to represent floating point axis values). -* The InternalUnit attribute described the units used for floating -* point values. -* - When specifying this attribute by name, it should be -* subscripted with the number of the Frame axis to which it -* applies. -*att-- -*/ -/* This simply provides an interface to the Axis methods for accessing - the Unit string. */ -MAKE_GET(Unit,const char *,NULL,0,0) -MAKE_TEST(Unit) - -/* -*att++ -* Name: -* NormUnit(axis) - -* Purpose: -* Normalised physical units for formatted axis values - -* Type: -* Public attribute. - -* Synopsis: -* String, read-only. - -* Description: -* The value of this read-only attribute is derived from the current -* value of the Unit attribute. It will represent an equivalent system -* of units to the Unit attribute, but will potentially be simplified. -* For instance, if Unit is set to "s*(m/s)", the NormUnit value will -* be "m". If no simplification can be performed, the value of the -* NormUnit attribute will equal that of the Unit attribute. - -* Applicability: -* Frame -* All Frames have this attribute. - -* Notes: -* - When specifying this attribute by name, it should be -* subscripted with the number of the Frame axis to which it -* applies. -*att-- -*/ -/* This simply provides an interface to the Axis methods for accessing - the NormUnit string. */ -MAKE_GET(NormUnit,const char *,NULL,0,0) - -/* -*att++ -* Name: -* InternalUnit(axis) - -* Purpose: -* Physical units for unformated axis values - -* Type: -* Public attribute. - -* Synopsis: -* String, read-only. - -* Description: -* This read-only attribute contains a textual representation of the -* physical units used to represent unformatted (i.e. floating point) -* values on a particular axis of a Frame, typically handled internally -* within application code. In most cases, the value of the InternalUnit -* attribute will be the same as Unit attribute (i.e. formatted and -* unformatted axis values will normally use the same system of units). -* The main exception to this is the SkyFrame class, which represents -* unformatted axis values in radians, regardless of the current -* setting of the Unit attribute. - -* Applicability: -* Frame -* All Frames have this attribute. - -* Notes: -* - When specifying this attribute by name, it should be -* subscripted with the number of the Frame axis to which it -* applies. -*att-- -*/ -/* If the Axis structure provides a value for InternalUnit, then use - that value. Otherwise, use a default equal to the value of the Unit - attribute for the axis. */ -MAKE_GET(InternalUnit,const char *,NULL,1,astGetUnit(this,axis)) - -/* Implement member functions to access the attributes associated with - the Frame as a whole using the macros defined for this purpose in - the "object.h" file. */ - -/* -*att++ -* Name: -* Digits/Digits(axis) - -* Purpose: -* Number of digits of precision. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute specifies how many digits of precision are -* required by default when a coordinate value is formatted for a -c Frame axis (e.g. using astFormat). Its value may be set either -f Frame axis (e.g. using AST_FORMAT). Its value may be set either -* for a Frame as a whole, or (by subscripting the attribute name -* with the number of an axis) for each axis individually. Any -* value set for an individual axis will over-ride the value for -* the Frame as a whole. -* -* Note that the Digits value acts only as a means of determining a -* default Format string. Its effects are over-ridden if a Format -* string is set explicitly for an axis. However, if the Format -* attribute specifies the precision using the string ".*", then -* the Digits attribute is used to determine the number of decimal -* places to produce. - -* Applicability: -* Frame -* The default Digits value supplied by the Frame class is 7. If -* a value less than 1 is supplied, then 1 is used instead. -* FrameSet -* The Digits attribute of a FrameSet (or one of its axes) is -* the same as that of its current Frame (as specified by the -* Current attribute). -* Plot -* The default Digits value used by the Plot class when drawing -* annotated axis labels is the smallest value which results in all -* adjacent labels being distinct. -* TimeFrame -* The Digits attribute is ignored when a TimeFrame formats a value -* as a date and time string (see the Format attribute). -*att-- -*/ -/* Clear the Digits value by setting it to -INT_MAX. */ -astMAKE_CLEAR(Frame,Digits,digits,-INT_MAX) - -/* Supply a default of 7 digits if no value has been set. */ -astMAKE_GET(Frame,Digits,int,0,( ( this->digits != -INT_MAX ) ? this->digits : - 7 )) - -/* Constrain the Digits value being set to be at least 1. */ -astMAKE_SET(Frame,Digits,int,digits,( value > 1 ? value : 1 )) - -/* The Digits value is set if it is not -INT_MAX. */ -astMAKE_TEST(Frame,Digits,( this->digits != -INT_MAX )) - -/* -*att++ -* Name: -* MatchEnd - -* Purpose: -* Match trailing axes? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which controls how a Frame -c behaves when it is used (by astFindFrame) as a template to match -f behaves when it is used (by AST_FINDFRAME) as a template to match -* another (target) Frame. It applies only in the case where a -* match occurs between template and target Frames with different -* numbers of axes. -* -* If the MatchEnd value of the template Frame is zero, then the -* axes which occur first in the target Frame will be matched and -* any trailing axes (in either the target or template) will be -* disregarded. If it is non-zero, the final axes in each Frame -* will be matched and any un-matched leading axes will be -* disregarded instead. - -* Applicability: -* Frame -* The default MatchEnd value for a Frame is zero, so that -* trailing axes are disregarded. -* FrameSet -* The MatchEnd attribute of a FrameSet is the same as that of -* its current Frame (as specified by the Current attribute). -*att-- -*/ -/* Clear the MatchEnd value by setting it to -INT_MAX. */ -astMAKE_CLEAR(Frame,MatchEnd,match_end,-INT_MAX) - -/* Supply a default of 0 if no MatchEnd value has been set. */ -astMAKE_GET(Frame,MatchEnd,int,0,( ( this->match_end != -INT_MAX ) ? - this->match_end : 0 )) - -/* Set a MatchEnd value of 1 if any non-zero value is supplied. */ -astMAKE_SET(Frame,MatchEnd,int,match_end,( value != 0 )) - -/* The MatchEnd value is set if it is not -INT_MAX. */ -astMAKE_TEST(Frame,MatchEnd,( this->match_end != -INT_MAX )) - -/* -*att++ -* Name: -* MaxAxes - -* Purpose: -* Maximum number of Frame axes to match. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute controls how a Frame behaves when it is used (by -c astFindFrame) as a template to match another (target) Frame. It -f AST_FINDFRAME) as a template to match another (target) Frame. It -* specifies the maximum number of axes that the target Frame may -* have in order to match the template. -* -* Normally, this value will equal the number of Frame axes, so -* that a template Frame will only match another Frame with the -* same number of axes as itself. By setting a different value, -* however, the matching process may be used to identify Frames -* with specified numbers of axes. - -* Applicability: -* Frame -* The default MaxAxes value for a Frame is equal to the number -* of Frame axes (Naxes attribute). -* CmpFrame -* The MaxAxes attribute of a CmpFrame defaults to a large number -* (1000000) which is much larger than any likely number of axes in -* a Frame. Combined with the MinAxes default of zero (for a -* CmpFrame), this means that the default behaviour for a CmpFrame -* is to match any target Frame that consists of a subset of the -* axes in the template CmpFrame. To change this so that a CmpFrame -* will only match Frames that have the same number of axes, you -* should set the CmpFrame MaxAxes and MinAxes attributes to the -* number of axes in the CmpFrame. -* FrameSet -* The MaxAxes attribute of a FrameSet is the same as that of -* its current Frame (as specified by the Current attribute). - -* Notes: -* - When setting a MaxAxes value, the value of the MinAxes -* attribute may also be silently changed so that it remains -* consistent with (i.e. does not exceed) the new value. The -* default MaxAxes value may also be reduced to remain consistent -* with the MinAxes value. -* - If a template Frame is used to match a target with a different -* number of axes, the MatchEnd attribute of the template is used -* to determine how the individual axes of each Frame should match. -*att-- -*/ -/* Clear the MaxAxes value by setting it to -INT_MAX. */ -astMAKE_CLEAR(Frame,MaxAxes,max_axes,-INT_MAX) - -/* Use the DefaultMaxAxes and ConsistentMaxAxes functions (defined earlier) for - the Get and Set operations to ensure that MinAxes and MaxAxes values remain - consistent. */ -astMAKE_GET(Frame,MaxAxes,int,0,DefaultMaxAxes( this, status )) -astMAKE_SET(Frame,MaxAxes,int,max_axes,ConsistentMaxAxes( this, value, status )) - -/* The MaxAxes value is set if it is not -INT_MAX. */ -astMAKE_TEST(Frame,MaxAxes,( this->max_axes != -INT_MAX )) - -/* -*att++ -* Name: -* MinAxes - -* Purpose: -* Minimum number of Frame axes to match. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute controls how a Frame behaves when it is used (by -c astFindFrame) as a template to match another (target) Frame. It -f AST_FINDFRAME) as a template to match another (target) Frame. It -* specifies the minimum number of axes that the target Frame may -* have in order to match the template. -* -* Normally, this value will equal the number of Frame axes, so -* that a template Frame will only match another Frame with the -* same number of axes as itself. By setting a different value, -* however, the matching process may be used to identify Frames -* with specified numbers of axes. - -* Applicability: -* Frame -* The default MinAxes value for a Frame is equal to the number -* of Frame axes (Naxes attribute). -* CmpFrame -* The MinAxes attribute of a CmpFrame defaults to zero. Combined -* with the MaxAxes default of 1000000 (for a CmpFrame), this means -* that the default behaviour for a CmpFrame is to match any target -* Frame that consists of a subset of the axes in the template -* CmpFrame. To change this so that a CmpFrame will only match Frames -* that have the same number of axes, you should set the CmpFrame -* MinAxes and MaxAxes attributes to the number of axes in the CmpFrame. -* FrameSet -* The MinAxes attribute of a FrameSet is the same as that of -* its current Frame (as specified by the Current attribute). - -* Notes: -* - When setting a MinAxes value, the value of the MaxAxes -* attribute may also be silently changed so that it remains -* consistent with (i.e. is not less than) the new value. The -* default MinAxes value may also be reduced to remain consistent -* with the MaxAxes value. -* - If a template Frame is used to match a target with a different -* number of axes, the MatchEnd attribute of the template is used -* to determine how the individual axes of each Frame should match. -*att-- -*/ -/* Clear the MinAxes value by setting it to -INT_MAX. */ -astMAKE_CLEAR(Frame,MinAxes,min_axes,-INT_MAX) - -/* Use the DefaultMinAxes and ConsistentMinAxes functions (defined earlier) for - the Get and Set operations to ensure that MinAxes and MaxAxes values remain - consistent. */ -astMAKE_GET(Frame,MinAxes,int,0,DefaultMinAxes( this, status )) -astMAKE_SET(Frame,MinAxes,int,min_axes,ConsistentMinAxes( this, value, status )) - -/* The MinAxes value is set if it is not -INT_MAX. */ -astMAKE_TEST(Frame,MinAxes,( this->min_axes != -INT_MAX )) - -/* -*att++ -* Name: -* Domain - -* Purpose: -* Coordinate system domain. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute contains a string which identifies the physical -* domain of the coordinate system that a Frame describes. -* -* The Domain attribute also controls how a Frame behaves when it is -c used (by astFindFrame) as a template to match another (target) -f used (by AST_FINDFRAME) as a template to match another (target) -* Frame. It does this by specifying the Domain that the target -* Frame should have in order to match the template. If the Domain -* value in the template Frame is set, then only targets with the -* same Domain value will be matched. If the template's Domain -* value is not set, however, then the target's Domain will be -* ignored. - -* Applicability: -* Frame -* The default Domain value supplied by the Frame class is an -* empty string. -* SkyFrame -* The SkyFrame class re-defines the default Domain value to be -* "SKY". -* CmpFrame -* The CmpFrame class re-defines the default Domain value to be -* of the form "-", where and are the -* Domains of the two component Frames. If both these Domains are -* blank, then the string "CMP" is used as the default Domain name. -* FrameSet -* The Domain attribute of a FrameSet is the same as that of its -* current Frame (as specified by the Current attribute). -* SpecFrame -* The SpecFrame class re-defines the default Domain value to be -* "SPECTRUM". -* DSBSpecFrame -* The DSBSpecFrame class re-defines the default Domain value to be -* "DSBSPECTRUM". -* FluxFrame -* The FluxFrame class re-defines the default Domain value to be -* "FLUX". -* SpecFluxFrame -* The FluxFrame class re-defines the default Domain value to be -* "SPECTRUM-FLUX". -* TimeFrame -* The TimeFrame class re-defines the default Domain value to be -* "TIME". - -* Notes: -* - All Domain values are converted to upper case and white space -* is removed before use. -*att-- -*/ -/* Clear the Domain value by freeing the allocated memory and - assigning a NULL pointer. */ -astMAKE_CLEAR(Frame,Domain,domain,astFree( this->domain )) - -/* If the Domain value is not set, supply a default in the form of a - pointer to the constant string "". */ -astMAKE_GET(Frame,Domain,const char *,NULL,( this->domain ? this->domain : - "" )) - -/* Set a Domain value by freeing any previously allocated memory, - allocating new memory, storing the string, removing white space, - converting to upper case and saving the pointer to the cleaned - copy. */ -astMAKE_SET(Frame,Domain,const char *,domain,CleanDomain( - astStore( this->domain, - value, strlen( value ) + (size_t) 1 ), status )) - -/* The Domain value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Frame,Domain,( this->domain != NULL )) - -/* -*att++ -* Name: -* Permute - -* Purpose: -* Permute axis order? - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute is a boolean value which controls how a Frame -c behaves when it is used (by astFindFrame) as a template to match -f behaves when it is used (by AST_FINDFRAME) as a template to match -* another (target) Frame. It specifies whether the axis order of -* the target Frame may be permuted in order to obtain a match. -* -* If the template's Permute value is zero, it will match a target -* only if it can do so without changing the order of its -* axes. Otherwise, it will attempt to permute the target's axes as -* necessary. -* -* The default value is 1, so that axis permutation will be attempted. - -* Applicability: -* Frame -* All Frames have this attribute. However, the Frame class -* effectively ignores this attribute and behaves as if it has -* the value 1. This is because the axes of a basic Frame are -* not distinguishable and will always match any other Frame -* whatever their order. -* SkyFrame -* Unlike a basic Frame, the SkyFrame class makes use of this -* attribute. -* FrameSet -* The Permute attribute of a FrameSet is the same as that of -* its current Frame (as specified by the Current attribute). -*att-- -*/ -/* Clear the Permute value by setting it to -INT_MAX. */ -astMAKE_CLEAR(Frame,Permute,permute,-INT_MAX) - -/* Supply a default of 1 if no Permute value has been set. */ -astMAKE_GET(Frame,Permute,int,0,( ( this->permute != -INT_MAX ) ? - this->permute : 1 )) - -/* Set a Permute value of 1 if any non-zero value is supplied. */ -astMAKE_SET(Frame,Permute,int,permute,( value != 0 )) - -/* The Permute value is set if it is not -INT_MAX. */ -astMAKE_TEST(Frame,Permute,( this->permute != -INT_MAX )) - -/* -*att++ -* Name: -* PreserveAxes - -* Purpose: -* Preserve axes? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls how a Frame behaves when it is used (by -c astFindFrame) as a template to match another (target) Frame. It -f AST_FINDFRAME) as a template to match another (target) Frame. It -* determines which axes appear (and in what order) in the "result" -* Frame produced. -* -* If PreserveAxes is zero in the template Frame, then the result -* Frame will have the same number (and order) of axes as the -* template. If it is non-zero, however, the axes of the target -* Frame will be preserved, so that the result Frame will have the -* same number (and order) of axes as the target. -* -* The default value is zero, so that target axes are not preserved -* and the result Frame resembles the template. - -* Applicability: -* Frame -* All Frames have this attribute. -* FrameSet -* The PreserveAxes attribute of a FrameSet is the same as that -* of its current Frame (as specified by the Current attribute). -*att-- -*/ -/* Clear the PreserveAxes value by setting it to -INT_MAX. */ -astMAKE_CLEAR(Frame,PreserveAxes,preserve_axes,-INT_MAX) - -/* Supply a default of 0 if no PreserveAxes value has been set. */ -astMAKE_GET(Frame,PreserveAxes,int,0,( ( this->preserve_axes != -INT_MAX ) ? - this->preserve_axes : 0 )) - -/* Set a PreserveAxes value of 1 if any non-zero value is supplied. */ -astMAKE_SET(Frame,PreserveAxes,int,preserve_axes,( value != 0 )) - -/* The PreserveAxes value is set if it is not -INT_MAX. */ -astMAKE_TEST(Frame,PreserveAxes,( this->preserve_axes != -INT_MAX )) - -/* -*att++ -* Name: -* AlignSystem - -* Purpose: -* Coordinate system in which to align the Frame. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls how a Frame behaves when it is used (by -c astFindFrame or astConvert) as a template to match another (target) -f AST_FINDFRAME or AST_CONVERT) as a template to match another (target) -* Frame. It identifies the coordinate system in which the two Frames -* will be aligned by the match. -* -* The values which may be assigned to this attribute, and its default -* value, depend on the class of Frame and are described in the -* "Applicability" section below. In general, the AlignSystem attribute -* will accept any of the values which may be assigned to the System -* attribute. -* -c The Mapping returned by AST_FINDFRAME or AST_CONVERT will use the -f The Mapping returned by astFindFrame or astConvert will use the -* coordinate system specified by the AlignSystem attribute as an -* intermediate coordinate system. The total returned Mapping will first -* map positions from the first Frame into this intermediate coordinate -* system, using the attributes of the first Frame. It will then map -* these positions from the intermediate coordinate system into the -* second Frame, using the attributes of the second Frame. - -* Applicability: -* Frame -* The AlignSystem attribute for a basic Frame always equals "Cartesian", -* and may not be altered. -* CmpFrame -* The AlignSystem attribute for a CmpFrame always equals "Compound", -* and may not be altered. -* FrameSet -* The AlignSystem attribute of a FrameSet is the same as that of its -* current Frame (as specified by the Current attribute). -* SkyFrame -* The default AlignSystem attribute for a SkyFrame is "ICRS". -* SpecFrame -* The default AlignSystem attribute for a SpecFrame is "Wave" -* (wavelength). -* TimeFrame -* The default AlignSystem attribute for a TimeFrame is "MJD". -*att-- -*/ -/* Clear the AlignSystem value by setting it to AST__BADSYSTEM. */ -astMAKE_CLEAR(Frame,AlignSystem,alignsystem,AST__BADSYSTEM) - -/* Provide a default AlignSystem of AST__CART. */ -astMAKE_GET(Frame,AlignSystem,AstSystemType,AST__BADSYSTEM,( - ( this->alignsystem == AST__BADSYSTEM ) ? AST__CART : this->alignsystem ) ) - -/* Validate the AlignSystem value being set and retain the original if the - supplied value is not recognized. */ -astMAKE_SET(Frame,AlignSystem,AstSystemType,alignsystem,( - (astValidateSystem( this, value, "astSetAlignSystem" ) != AST__BADSYSTEM) ? - value : this->alignsystem )) - -/* The AlignSystem value is set if it is not AST__BADSYSTEM. */ -astMAKE_TEST(Frame,AlignSystem,( this->alignsystem != AST__BADSYSTEM )) - -/* -*att++ -* Name: -* System - -* Purpose: -* Coordinate system used to describe positions within the domain - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* In general it is possible for positions within a given physical -* domain to be described using one of several different coordinate -* systems. For instance, the SkyFrame class can use galactic -* coordinates, equatorial coordinates, etc, to describe positions on -* the sky. As another example, the SpecFrame class can use frequency, -* wavelength, velocity, etc, to describe a position within an -* electromagnetic spectrum. The System attribute identifies the particular -* coordinate system represented by a Frame. Each class of Frame -* defines a set of acceptable values for this attribute, as listed -* below (all are case insensitive). Where more than one alternative -* System value is shown, the first of will be returned when an -* enquiry is made. - -* Applicability: -* Frame -* The System attribute for a basic Frame always equals "Cartesian", -* and may not be altered. -* CmpFrame -* The System attribute for a CmpFrame always equals "Compound", -* and may not be altered. In addition, the CmpFrame class allows -* the System attribute to be referenced for a component Frame by -* including the index of an axis within the required component -* Frame. For instance, "System(3)" refers to the System attribute -* of the component Frame which includes axis 3 of the CmpFrame. -* FrameSet -* The System attribute of a FrameSet is the same as that of its -* current Frame (as specified by the Current attribute). -* SkyFrame -* The SkyFrame class supports the following System values and -* associated celestial coordinate systems: -* -* - "AZEL": Horizon coordinates. The longitude axis is azimuth -* such that geographic north has an azimuth of zero and geographic -* east has an azimuth of +PI/2 radians. The zenith has elevation -* +PI/2. When converting to and from other celestial coordinate -* systems, no corrections are applied for atmospheric refraction -* or polar motion (however, a correction for diurnal aberattion is -* applied). Note, unlike most other -* celestial coordinate systems, this system is right handed. Also, -* unlike other SkyFrame systems, the AzEl system is sensitive to -* the timescale in which the Epoch value is supplied. This is -* because of the gross diurnal rotation which this system undergoes, -* causing a small change in time to translate to a large rotation. -* When converting to or from an AzEl system, the Epoch value for -* both source and destination SkyFrames should be supplied in the -* TDB timescale. The difference between TDB and TT is between 1 -* and 2 milliseconds, and so a TT value can usually be supplied in -* place of a TDB value. The TT timescale is related to TAI via -* TT = TAI + 32.184 seconds. -* -* - "ECLIPTIC": Ecliptic coordinates (IAU 1980), referred to the -* ecliptic and mean equinox specified by the qualifying Equinox -* value. -* -* - "FK4": The old FK4 (barycentric) equatorial coordinate system, -* which should be qualified by an Equinox value. The underlying -* model on which this is based is non-inertial and rotates slowly -* with time, so for accurate work FK4 coordinate systems should -* also be qualified by an Epoch value. -* -* - "FK4-NO-E" or "FK4_NO_E": The old FK4 (barycentric) equatorial -* system but without the "E-terms of aberration" (e.g. some radio -* catalogues). This coordinate system should also be qualified by -* both an Equinox and an Epoch value. -* -* - "FK5" or "EQUATORIAL": The modern FK5 (barycentric) equatorial -* coordinate system. This should be qualified by an Equinox value. -* -* - "GALACTIC": Galactic coordinates (IAU 1958). -* -* - "GAPPT", "GEOCENTRIC" or "APPARENT": The geocentric apparent -* equatorial coordinate system, which gives the apparent positions -* of sources relative to the true plane of the Earth's equator and -* the equinox (the coordinate origin) at a time specified by the -* qualifying Epoch value. (Note that no Equinox is needed to -* qualify this coordinate system because no model "mean equinox" -* is involved.) These coordinates give the apparent right -* ascension and declination of a source for a specified date of -* observation, and therefore form an approximate basis for -* pointing a telescope. Note, however, that they are applicable to -* a fictitious observer at the Earth's centre, and therefore -* ignore such effects as atmospheric refraction and the (normally -* much smaller) aberration of light due to the rotational velocity -* of the Earth's surface. Geocentric apparent coordinates are -* derived from the standard FK5 (J2000.0) barycentric coordinates -* by taking account of the gravitational deflection of light by -* the Sun (usually small), the aberration of light caused by the -* motion of the Earth's centre with respect to the barycentre -* (larger), and the precession and nutation of the Earth's spin -* axis (normally larger still). -* -* - "HELIOECLIPTIC": Ecliptic coordinates (IAU 1980), referred to the -* ecliptic and mean equinox of J2000.0, in which an offset is added to -* the longitude value which results in the centre of the sun being at -* zero longitude at the date given by the Epoch attribute. Attempts to -* set a value for the Equinox attribute will be ignored, since this -* system is always referred to J2000.0. -* -* - "ICRS": The Internation Celestial Reference System, realised -* through the Hipparcos catalogue. Whilst not an equatorial system -* by definition, the ICRS is very close to the FK5 (J2000) system -* and is usually treated as an equatorial system. The distinction -* between ICRS and FK5 (J2000) only becomes important when accuracies -* of 50 milli-arcseconds or better are required. ICRS need not be -* qualified by an Equinox value. -* -* - "J2000": An equatorial coordinate system based on the mean -* dynamical equator and equinox of the J2000 epoch. The dynamical -* equator and equinox differ slightly from those used by the FK5 -* model, and so a "J2000" SkyFrame will differ slightly from an -* "FK5(Equinox=J2000)" SkyFrame. The J2000 System need not be -* qualified by an Equinox value -* -* - "SUPERGALACTIC": De Vaucouleurs Supergalactic coordinates. -* -* - "UNKNOWN": Any other general spherical coordinate system. No -* Mapping can be created between a pair of SkyFrames if either of the -* SkyFrames has System set to "Unknown". -* -* Currently, the default System value is "ICRS". However, this -* default may change in future as new astrometric standards -* evolve. The intention is to track the most modern appropriate -* standard. For this reason, you should use the default only if -* this is what you intend (and can tolerate any associated slight -* change in future). If you intend to use the ICRS system -* indefinitely, then you should specify it explicitly. -* SpecFrame -* The SpecFrame class supports the following System values and -* associated spectral coordinate systems (the default is "WAVE" - -* wavelength). They are all defined in FITS-WCS paper III: -* -* - "FREQ": Frequency (GHz) -* - "ENER" or "ENERGY": Energy (J) -* - "WAVN" or "WAVENUM": Wave-number (1/m) -* - "WAVE" or "WAVELEN": Vacuum wave-length (Angstrom) -* - "AWAV" or "AIRWAVE": Wave-length in air (Angstrom) -* - "VRAD" or "VRADIO": Radio velocity (km/s) -* - "VOPT" or "VOPTICAL": Optical velocity (km/s) -* - "ZOPT" or "REDSHIFT": Redshift (dimensionless) -* - "BETA": Beta factor (dimensionless) -* - "VELO" or "VREL": Apparent radial ("relativistic") velocity (km/s) -* -* The default value for the Unit attribute for each system is shown -* in parentheses. Note that the default value for the ActiveUnit flag -c is non-zero -f is .TRUE. -* for a SpecFrame, meaning that changes to the Unit attribute for -* a SpecFrame will result in the SpecFrame being re-mapped within -* its enclosing FrameSet in order to reflect the change in units -c (see astSetActiveUnit function for further information). -f (see AST_SETACTIVEUNIT routine for further information). -* TimeFrame -* The TimeFrame class supports the following System values and -* associated coordinate systems (the default is "MJD"): -* -* - "MJD": Modified Julian Date (d) -* - "JD": Julian Date (d) -* - "JEPOCH": Julian epoch (yr) -* - "BEPOCH": Besselian (yr) -* -* The default value for the Unit attribute for each system is shown -* in parentheses. Strictly, these systems should not allow changes -* to be made to the units. For instance, the usual definition of -* "MJD" and "JD" include the statement that the values will be in -* units of days. However, AST does allow the use of other units -* with all the above supported systems (except BEPOCH), on the -* understanding that conversion to the "correct" units involves -* nothing more than a simple scaling (1 yr = 365.25 d, 1 d = 24 h, -* 1 h = 60 min, 1 min = 60 s). Besselian epoch values are defined -* in terms of tropical years of 365.2422 days, rather than the -* usual Julian year of 365.25 days. Therefore, to avoid any -* confusion, the Unit attribute is automatically cleared to "yr" when -* a System value of BEPOCH System is selected, and an error is -* reported if any attempt is subsequently made to change the Unit -* attribute. -* -* Note that the default value for the ActiveUnit flag -c is non-zero -f is .TRUE. -* for a TimeFrame, meaning that changes to the Unit attribute for -* a TimeFrame will result in the TimeFrame being re-mapped within -* its enclosing FrameSet in order to reflect the change in units -c (see astSetActiveUnit function for further information). -f (see AST_SETACTIVEUNIT routine for further information). -* FluxFrame -* The FluxFrame class supports the following System values and -* associated systems for measuring observed value: -* -* - "FLXDN": Flux per unit frequency (W/m^2/Hz) -* - "FLXDNW": Flux per unit wavelength (W/m^2/Angstrom) -* - "SFCBR": Surface brightness in frequency units (W/m^2/Hz/arcmin**2) -* - "SFCBRW": Surface brightness in wavelength units (W/m^2/Angstrom/arcmin**2) -* -* The above lists specified the default units for each System. If an -* explicit value is set for the Unit attribute but no value is set -* for System, then the default System value is determined by the Unit -* string (if the units are not appropriate for describing any of the -* supported Systems then an error will be reported when an attempt is -* made to access the System value). If no value has been specified for -* either Unit or System, then System=FLXDN and Unit=W/m^2/Hz are -* used. -*att-- -*/ -/* Clear the System value by setting it to AST__BADSYSTEM. */ -astMAKE_CLEAR(Frame,System,system,AST__BADSYSTEM) - -/* Provide a default coordinate system of AST__CART. */ -astMAKE_GET(Frame,System,AstSystemType,AST__BADSYSTEM,( - ( this->system == AST__BADSYSTEM ) ? AST__CART : this->system ) ) - -/* Validate the System value being set and retain the original if the - supplied value is not recognized. */ -astMAKE_SET(Frame,System,AstSystemType,system,( - (astValidateSystem( this, value, "astSetSystem" ) != AST__BADSYSTEM) ? - value : this->system )) - -/* The System value is set if it is not AST__BADSYSTEM. */ -astMAKE_TEST(Frame,System,( this->system != AST__BADSYSTEM )) - -/* -*att++ -* Name: -* Title - -* Purpose: -* Frame title. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute holds a string which is used as a title in (e.g.) -* graphical output to describe the coordinate system which a Frame -* represents. Examples might be "Detector Coordinates" or -* "Galactic Coordinates". -* -* If a Title value has not been set for a Frame, then a suitable -* default is supplied, depending on the class of the Frame. - -* Applicability: -* Frame -* The default supplied by the Frame class is "-d coordinate -* system", where is the number of Frame axes (Naxes -* attribute). -* CmpFrame -* The CmpFrame class re-defines the default Title value to be -* "-d compound coordinate system", where is the number -* of CmpFrame axes (Naxes attribute). -* FrameSet -* The Title attribute of a FrameSet is the same as that of its -* current Frame (as specified by the Current attribute). - -* Notes: -* - A Frame's Title is intended purely for interpretation by human -* readers and not by software. -*att-- -*/ -/* Clear the Title value by freeing the allocated memory and assigning - a NULL pointer. */ -astMAKE_CLEAR(Frame,Title,title,astFree( this->title )) - -/* If the Title value is not set, write a default based on the number of Frame - axes into the static "title_buff" buffer, and return a pointer to this - buffer. */ -astMAKE_GET(Frame,Title,const char *,NULL,( this->title ? - this->title : GetDefaultTitle( this, status ) )) - -/* Set a Title value by freeing any previously allocated memory, allocating - new memory, storing the string and saving the pointer to the copy. */ -astMAKE_SET(Frame,Title,const char *,title,astStore( this->title, value, - strlen( value ) + (size_t) 1 )) - -/* The Title value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Frame,Title,( this->title != NULL )) - -/* -*att++ -* Name: -* ObsLat - -* Purpose: -* The geodetic latitude of the observer - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies the geodetic latitude of the observer, in -* degrees, relative to the IAU 1976 reference ellipsoid. The basic Frame -* class makes no use of this attribute, but specialised subclasses of -* Frame may use it. For instance, the SpecFrame, SkyFrame and TimeFrame -* classes use it. The default value is zero. -* -* The value is stored internally in radians, but is converted to and -* from a degrees string for access. Some example input formats are: -* "22:19:23.2", "22 19 23.2", "22:19.387", "22.32311", "N22.32311", -* "-45.6", "S45.6". As indicated, the sign of the latitude can -* optionally be indicated using characters "N" and "S" in place of the -* usual "+" and "-". When converting the stored value to a string, the -* format "[s]dd:mm:ss.ss" is used, when "[s]" is "N" or "S". - -* Applicability: -* Frame -* All Frames have this attribute. -* SpecFrame -* Together with the ObsLon, Epoch, RefRA and RefDec attributes, -* it defines the Doppler shift introduced by the observers diurnal -* motion around the earths axis, which is needed when converting to -* or from the topocentric standard of rest. The maximum velocity -* error which can be caused by an incorrect value is 0.5 km/s. The -* default value for the attribute is zero. -* TimeFrame -* Together with the ObsLon attribute, it is used when converting -* between certain time scales (TDB, TCB, LMST, LAST) - -*att-- -*/ -/* The geodetic latitude of the observer (radians). Clear the ObsLat value by - setting it to AST__BAD, returning zero as the default value. Any value is - acceptable. */ -astMAKE_CLEAR(Frame,ObsLat,obslat,AST__BAD) -astMAKE_GET(Frame,ObsLat,double,0.0,((this->obslat!=AST__BAD)?this->obslat:0.0)) -astMAKE_SET(Frame,ObsLat,double,obslat,value) -astMAKE_TEST(Frame,ObsLat,(this->obslat!=AST__BAD)) - - -/* -*att++ -* Name: -* ObsAlt - -* Purpose: -* The geodetic altitude of the observer - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the geodetic altitude of the observer, in -* metres, relative to the IAU 1976 reference ellipsoid. The basic Frame -* class makes no use of this attribute, but specialised subclasses of -* Frame may use it. For instance, the SpecFrame, SkyFrame and TimeFrame -* classes use it. The default value is zero. - -* Applicability: -* Frame -* All Frames have this attribute. -* SpecFrame -* Together with the ObsLon, Epoch, RefRA and RefDec attributes, -* it defines the Doppler shift introduced by the observers diurnal -* motion around the earths axis, which is needed when converting to -* or from the topocentric standard of rest. The maximum velocity -* error which can be caused by an incorrect value is 0.5 km/s. The -* default value for the attribute is zero. -* TimeFrame -* Together with the ObsLon attribute, it is used when converting -* between certain time scales (TDB, TCB, LMST, LAST) - -*att-- -*/ -/* The geodetic altitude of the observer (metres). Clear the ObsAlt value by - setting it to AST__BAD, returning zero as the default value. Any value is - acceptable. */ -astMAKE_CLEAR(Frame,ObsAlt,obsalt,AST__BAD) -astMAKE_GET(Frame,ObsAlt,double,0.0,((this->obsalt!=AST__BAD)?this->obsalt:0.0)) -astMAKE_SET(Frame,ObsAlt,double,obsalt,value) -astMAKE_TEST(Frame,ObsAlt,(this->obsalt!=AST__BAD)) - - -/* -*att++ -* Name: -* ObsLon - -* Purpose: -* The geodetic longitude of the observer - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies the geodetic (or equivalently, geocentric) -* longitude of the observer, in degrees, measured positive eastwards. -* See also attribute ObsLat. The basic Frame class makes no use of this -* attribute, but specialised subclasses of Frame may use it. For instance, -* the SpecFrame, SkyFrame and TimeFrame classes use it. The default value -* is zero. -* -* The value is stored internally in radians, but is converted to and -* from a degrees string for access. Some example input formats are: -* "155:19:23.2", "155 19 23.2", "155:19.387", "155.32311", "E155.32311", -* "-204.67689", "W204.67689". As indicated, the sign of the longitude can -* optionally be indicated using characters "E" and "W" in place of the -* usual "+" and "-". When converting the stored value to a string, the -* format "[s]ddd:mm:ss.ss" is used, when "[s]" is "E" or "W" and the -* numerical value is chosen to be less than 180 degrees. - -* Applicability: -* Frame -* All Frames have this attribute. -* SpecFrame -* Together with the ObsLon, Epoch, RefRA and RefDec attributes, -* it defines the Doppler shift introduced by the observers diurnal -* motion around the earths axis, which is needed when converting to -* or from the topocentric standard of rest. The maximum velocity -* error which can be caused by an incorrect value is 0.5 km/s. The -* default value for the attribute is zero. -* TimeFrame -* Together with the ObsLon attribute, it is used when converting -* between certain time scales (TDB, TCB, LMST, LAST) - -*att-- -*/ -/* The geodetic longitude of the observer (radians). Clear the ObsLon value by - setting it to AST__BAD, returning zero as the default value. Any value is - acceptable. */ -astMAKE_CLEAR(Frame,ObsLon,obslon,AST__BAD) -astMAKE_GET(Frame,ObsLon,double,0.0,((this->obslon!=AST__BAD)?this->obslon:0.0)) -astMAKE_SET(Frame,ObsLon,double,obslon,value) -astMAKE_TEST(Frame,ObsLon,(this->obslon!=AST__BAD)) - - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Frame objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Frame objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstFrame *in; /* Pointer to input Frame */ - AstFrame *out; /* Pointer to output Frame */ - int axis; /* Loop counter for axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Frames. */ - in = (AstFrame *) objin; - out = (AstFrame *) objout; - -/* For safety, first clear any references to the input memory from - the output Frame. */ - out->axis = NULL; - out->domain = NULL; - out->perm = NULL; - out->title = NULL; - out->variants = NULL; - -/* If necessary, allocate memory in the output Frame and store a copy of the - input Title and Domain strings. */ - if ( in->title ) out->title = astStore( NULL, in->title, - strlen( in->title ) + (size_t) 1 ); - if ( in->domain ) out->domain = astStore( NULL, in->domain, - strlen( in->domain ) + - (size_t) 1 ); - -/* Allocate memory to hold the output Frame's Axis object pointers and its axis - permutation array. */ - out->axis = astMalloc( sizeof( AstAxis * ) * (size_t) in->naxes ); - out->perm = astMalloc( sizeof( int ) * (size_t) in->naxes ); - -/* Make a copy of each of the input Frame's Axis objects, storing the pointer - to each new Axis in the memory just allocated. Also copy the axis - permutation array. */ - if ( astOK ) { - for ( axis = 0; axis < in->naxes; axis++ ) { - out->axis[ axis ] = astCopy( in->axis[ axis ] ); - out->perm[ axis ] = in->perm[ axis ]; - } - -/* If an error occurred while copying the Axis objects, then loop through the - resulting array of pointers and make sure that all of them are properly - annulled. */ - if ( !astOK ) { - for ( axis = 0; axis < in->naxes; axis++ ) { - out->axis[ axis ] = astAnnul( out->axis[ axis ] ); - } - } - } - -/* Other remaining objects */ - if( in->variants ) out->variants = astCopy( in->variants ); - -/* If an error occurred, free any allocated memory. */ - if ( !astOK ) { - out->axis = astFree( out->axis ); - out->domain = astFree( out->domain ); - out->perm = astFree( out->perm ); - out->title = astFree( out->title ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Frame objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Frame objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstFrame *this; /* Pointer to Frame */ - int axis; /* Loop counter for Frame axes */ - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) obj; - -/* Free the memory used for the Title and Domain strings if necessary. */ - this->title = astFree( this->title ); - this->domain = astFree( this->domain ); - -/* If memory has been allocated to store pointers to the Frame's Axis objects, - annul each of these pointers and then free the memory. */ - if ( this->axis ) { - for ( axis = 0; axis < this->naxes; axis++ ) { - this->axis[ axis ] = astAnnul( this->axis[ axis ] ); - } - this->axis = astFree( this->axis ); - } - -/* Free memory used for the axis permutation array if necessary. */ - this->perm = astFree( this->perm ); - -/* Other objects. */ - if( this->variants ) this->variants = astAnnul( this->variants ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Frame objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Frame class to an output Channel. - -* Parameters: -* this -* Pointer to the Frame whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define COMMENT_LEN 150 /* Maximum length of a comment string */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis */ - AstFrame *cfrm; /* Pointer to FrameSet's current Frame */ - AstFrame *this; /* Pointer to the Frame structure */ - AstSystemType system; /* System code */ - char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment strings */ - char key[ KEY_LEN + 1 ]; /* Buffer for keywords */ - const char *sval; /* Pointer to string value */ - const char *lab; /* Pointer to unit label */ - const int *perm; /* Pointer to axis permutation array */ - double dval; /* Double attibute value */ - int *invperm; /* Pointer to inverse permutation array */ - int axis; /* Loop counter for Frame axes */ - int bessyr; /* Format as Besselian years (else Julian) */ - int digits_set; /* Digits set explicitly for any axis? */ - int full; /* Full attribute value */ - int full_set; /* Full attribute set? */ - int helpful; /* Helpful to show value even if not set? */ - int isFrame; /* Is this a simple Frame? */ - int ival; /* Integer value */ - int naxes; /* Number of Frame axes */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Frame structure. */ - this = (AstFrame *) this_object; - -/* Determine the number of Frame axes and a pointer to the Frame's - axis permutation array (using methods, to allow for any over-ride - by a derived class). */ - naxes = astGetNaxes( this ); - perm = astGetPerm( this ); - -/* Some default attribute values are not helpful for a simple Frame. Note - if this is a simple Frame, or if it is a FrameSet with a simple Frame - as its current Frame., or if it is a CmpFrame. */ - if( !strcmp( astGetClass( this ), "Frame" ) ) { - isFrame = 1; - } else if( astIsAFrameSet( this ) ) { - cfrm = astGetFrame( (AstFrameSet *) this, AST__CURRENT ); - isFrame = !strcmp( astGetClass( cfrm ), "Frame" ); - cfrm = astAnnul( cfrm ); - } else if( astIsACmpFrame( this ) ) { - isFrame = 1; - } else { - isFrame = 0; - } - -/* Allocate memory to hold an inverse axis permutation array and - generate this array from the forward permutation values. This will - be used to determine which axis should be enquired about (using - possibly over-ridden methods) to obtain data to correspond with a - particular internal value (i.e. instance variable) relating to an - axis. This step is needed so that the effect of any axis - permutation can be un-done before values are written out, as output - values are written by this function in un-permuted order. */ - invperm = astMalloc( sizeof( int ) * (size_t) naxes ); - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) invperm[ perm[ axis ] ] = axis; - -/* Write out values representing the instance variables for the Frame - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Title. */ -/* ------ */ - set = TestTitle( this, status ); - sval = set ? GetTitle( this, status ) : astGetTitle( this ); - astWriteString( channel, "Title", set, 1, sval, - "Title of coordinate system" ); - -/* Naxes. */ -/* ------ */ - set = ( this->naxes != 0 ); - ival = set ? this->naxes : naxes; - astWriteInt( channel, "Naxes", set, 1, ival, - "Number of coordinate axes" ); - -/* Domain. */ -/* ------- */ - set = TestDomain( this, status ); - sval = set ? GetDomain( this, status ) : astGetDomain( this ); - -/* Don't show an un-set Domain value if it is blank. */ - helpful = ( sval && *sval ); - astWriteString( channel, "Domain", set, helpful, sval, - "Coordinate system domain" ); - -/* Epoch. */ -/* ------ */ - set = TestEpoch( this, status ); - dval = set ? GetEpoch( this, status ) : astGetEpoch( this ); - -/* Convert MJD to Besselian or Julian years, depending on the value. */ - bessyr = ( dval < palEpj2d( 1984.0 ) ); - dval = bessyr ? palEpb( dval ) : palEpj( dval ); - astWriteDouble( channel, "Epoch", set, !isFrame, dval, - bessyr ? "Besselian epoch of observation" : - "Julian epoch of observation" ); - -/* Label. */ -/* ------ */ -/* This, and some other, attributes are stored internally by the - Frame's Axis objects, but are "re-packaged" by the Frame class to - appear as Frame attributes. We treat them here like Frame - attributes that are "un-set". There is a Label value for each Frame - axis. */ - for ( axis = 0; axis < naxes; axis++ ) { - -/* The inverse axis permutation array is used to obtain the axis index - for astGetLabel. This reverses the effect of the Frame's axis - permutation array and yields a default value appropriate to the - axis with internal index "axis". */ - sval = astGetLabel( this, invperm[ axis ] ); - -/* Create keyword and comment strings appropriate to each axis - (converting to 1-based axis numbering) and write out the Label - values. */ - (void) sprintf( key, "Lbl%d", axis + 1 ); - (void) sprintf( comment, "Label for axis %d", axis + 1 ); - astWriteString( channel, key, 0, 1, sval, comment ); - } - -/* Symbol. */ -/* ------- */ -/* There is a Symbol value for each Frame axis. These are handled in - the same way as the Label values. */ - for ( axis = 0; axis < naxes; axis++ ) { - sval = astGetSymbol( this, invperm[ axis ] ); - (void) sprintf( key, "Sym%d", axis + 1 ); - (void) sprintf( comment, "Symbol for axis %d", axis + 1 ); - astWriteString( channel, key, 0, 0, sval, comment ); - } - -/* System. */ -/* ------- */ - set = TestSystem( this, status ); - system = set ? GetSystem( this, status ) : astGetSystem( this ); - -/* If set, convert explicitly to a string for the external representation. */ - if ( set ) { - if ( astOK ) { - sval = astSystemString( this, system ); - -/* Report an error if the System value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "astWrite(%s): Corrupt %s contains invalid " - "System identification code (%d).", status, - astGetClass( channel ), astGetClass( this ), - (int) system ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "system" ); - } - -/* Write out the value. */ - astWriteString( channel, "System", set, !isFrame, sval, - "Coordinate system type" ); - -/* AlignSystem. */ -/* ------------ */ - set = TestAlignSystem( this, status ); - system = set ? GetAlignSystem( this, status ) : astGetAlignSystem( this ); - -/* If set, convert explicitly to a string for the external representation. */ - if ( set ) { - if ( astOK ) { - sval = astSystemString( this, system ); - -/* Report an error if the AlignSystem value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "astWrite(%s): Corrupt %s contains invalid " - "AlignSystem identification code (%d).", status, - astGetClass( channel ), astGetClass( this ), - (int) system ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "alignsystem" ); - } - -/* Write out the value. */ - astWriteString( channel, "AlSys", set, 0, sval, - "Alignment coordinate system" ); - -/* Unit. */ -/* ----- */ -/* There is a Unit value for each axis. */ - for ( axis = 0; axis < naxes; axis++ ) { - sval = astGetUnit( this, invperm[ axis ] ); - -/* Get any label associated with the unit string. */ - lab = astUnitLabel( sval ); - -/* Construct a comment including the above label (but only if it is not - the same as the unit string) . */ - if( lab && strcmp( lab, sval ) ) { - (void) sprintf( comment, "Units for axis %d (%s)", axis + 1, lab ); - } else { - (void) sprintf( comment, "Units for axis %d", axis + 1 ); - } - -/* Show the Unit value if it is not blank. */ - helpful = ( sval && *sval ); - (void) sprintf( key, "Uni%d", axis + 1 ); - astWriteString( channel, key, 0, helpful, sval, comment ); - } - -/* Digits. */ -/* ------- */ -/* There is a Digits value for each axis... */ - digits_set = 0; - for ( axis = 0; axis < naxes; axis++ ) { - -/* Obtain the axis Digits value, using the Frame's Digits value as a - default. */ - ax = astGetAxis( this, invperm[ axis ] ); - set = astTestAxisDigits( ax ); - ival = set ? astGetAxisDigits( ax ) : astGetDigits( this ); - ax = astAnnul( ax ); - -/* Show the value if it is set for the axis (i.e. if it differs from - the default for the whole Frame) and note if any such value is - set. */ - helpful = set; - if ( set ) digits_set = 1; - (void) sprintf( key, "Dig%d", axis + 1 ); - (void) sprintf( comment, "Individual precision for axis %d", - axis + 1 ); - astWriteInt( channel, key, 0, helpful, ival, comment ); - } - -/* There is also a Digits value for the Frame as a whole... */ - set = TestDigits( this, status ); - -/* Show the value (even if not set) if an explicit Digits value has - been set for any axis (above). */ - helpful = digits_set; - ival = set ? GetDigits( this, status ) : astGetDigits( this ); - astWriteInt( channel, "Digits", set, helpful, ival, - "Default formatting precision" ); - -/* Format. */ -/* ------- */ -/* There is a Format value for each axis. */ - for ( axis = 0; axis < naxes; axis++ ) { - sval = astGetFormat( this, invperm[ axis ] ); - -/* Show the Format value if the Digits value is set for an individual - axis. */ - ax = astGetAxis( this, invperm[ axis ] ); - helpful = astTestAxisDigits( ax ); - ax = astAnnul( ax ); - (void) sprintf( key, "Fmt%d", axis + 1 ); - (void) sprintf( comment, "Format specifier for axis %d", axis + 1 ); - astWriteString( channel, key, 0, helpful, sval, comment ); - } - -/* Direction. */ -/* ---------- */ -/* There is a Direction value for each axis. */ - for ( axis = 0; axis < naxes; axis++ ) { - ival = astGetDirection( this, invperm[ axis ] ); - -/* Show the value if it is zero. */ - helpful = ( ival == 0 ); - (void) sprintf( key, "Dir%d", axis + 1 ); - (void) sprintf( comment, - ival ? "Plot axis %d in conventional direction" : - "Plot axis %d in reverse direction", - axis + 1 ); - astWriteInt( channel, key, 0, helpful, ival, comment ); - } - -/* Bottom. */ -/* ------- */ -/* There is a Bottom value for each axis. */ - for ( axis = 0; axis < naxes; axis++ ) { - dval = astGetBottom( this, invperm[ axis ] ); - -/* Show the value if it is zero. */ - helpful = ( dval != -DBL_MAX ); - (void) sprintf( key, "Bot%d", axis + 1 ); - astWriteDouble( channel, key, 0, helpful, dval, "Lowest legal axis value"); - } - -/* Top. */ -/* ------- */ -/* There is a Top value for each axis. */ - for ( axis = 0; axis < naxes; axis++ ) { - dval = astGetTop( this, invperm[ axis ] ); - -/* Show the value if it is zero. */ - helpful = ( dval != DBL_MAX ); - (void) sprintf( key, "Top%d", axis + 1 ); - astWriteDouble( channel, key, 0, helpful, dval, "Highest legal axis value"); - } - -/* PreserveAxes. */ -/* ------------- */ - set = TestPreserveAxes( this, status ); - ival = set ? GetPreserveAxes( this, status ) : astGetPreserveAxes( this ); - astWriteInt( channel, "Presrv", set, 0, ival, - ival ? "Preserve target axes" : - "Don't preserve target axes" ); - -/* Permute. */ -/* -------- */ - set = TestPermute( this, status ); - ival = set ? GetPermute( this, status ) : astGetPermute( this ); - astWriteInt( channel, "Permut", set, 0, ival, - ival ? "Axes may be permuted to match" : - "Axes may not be permuted match" ); - -/* MinAxes. */ -/* -------- */ - set = TestMinAxes( this, status ); - ival = set ? GetMinAxes( this, status ) : astGetMinAxes( this ); - astWriteInt( channel, "MinAx", set, 0, ival, - "Minimum number of axes to match" ); - -/* MaxAxes. */ -/* -------- */ - set = TestMaxAxes( this, status ); - ival = set ? GetMaxAxes( this, status ) : astGetMaxAxes( this ); - astWriteInt( channel, "MaxAx", set, 0, ival, - "Maximum number of axes to match" ); - -/* MatchEnd. */ -/* --------- */ - set = TestMatchEnd( this, status ); - ival = set ? GetMatchEnd( this, status ) : astGetMatchEnd( this ); - astWriteInt( channel, "MchEnd", set, 0, ival, - ival ? "Match final target axes" : - "Match initial target axes" ); - -/* ObsLat. */ -/* ------- */ - set = TestObsLat( this, status ); - dval = set ? GetObsLat( this, status ) : astGetObsLat( this ); - astWriteDouble( channel, "ObsLat", set, 0, dval, "Observers geodetic latitude (rads)" ); - -/* ObsLon. */ -/* ------- */ - set = TestObsLon( this, status ); - dval = set ? GetObsLon( this, status ) : astGetObsLon( this ); - astWriteDouble( channel, "ObsLon", set, 0, dval, "Observers geodetic longitude (rads)" ); - -/* ObsAlt. */ -/* ------- */ - set = TestObsAlt( this, status ); - dval = set ? GetObsAlt( this, status ) : astGetObsAlt( this ); - astWriteDouble( channel, "ObsAlt", set, 0, dval, "Observers geodetic altitude (metres)" ); - -/* Dtai*/ -/* ---- */ - set = TestDtai( this, status ); - dval = set ? GetDtai( this, status ) : astGetDtai( this ); - astWriteDouble( channel, "Dtai", set, 0, dval, "TAI-UTC in seconds" ); - -/* Dut1*/ -/* ---- */ - set = TestDut1( this, status ); - dval = set ? GetDut1( this, status ) : astGetDut1( this ); - astWriteDouble( channel, "Dut1", set, 0, dval, "UT1-UTC in seconds" ); - - -/* ActiveUnit. */ -/* ----------- */ - if( astTestActiveUnit( this ) ) { - ival = astGetActiveUnit( this ); - astWriteInt( channel, "ActUnt", 1, 0, ival, - ival ? "Unit strings affects alignment" : - "Unit strings do not affect alignment" ); - } - -/* Axis permutation array. */ -/* ----------------------- */ -/* Write out the axis permutation array value for each axis, - converting to 1-based axis numbering. */ - for ( axis = 0; axis < this->naxes; axis++ ) { - set = ( this->perm[ axis ] != axis ); - ival = this->perm[ axis ] + 1; - -/* Create a keyword and comment appropriate to the axis. */ - (void) sprintf( key, "Prm%d", axis + 1 ); - if ( set ) { - (void) sprintf( comment, - "Axis %d permuted to use internal axis %d", - axis + 1, ival ); - } else { - (void) sprintf( comment, "Axis %d not permuted", axis + 1 ); - } - astWriteInt( channel, key, set, 0, ival, comment ); - } - -/* Axis Objects. */ -/* ------------- */ -/* Temporarily set the Channel's Full attribute to -1 (unless it is +1 - to start with), remembering the original setting. This prevents any - unnecessary "un-set" Axis values being output that would otherwise - simply duplicate the Frame's attributes which have already been - written. "Set" Axis values are still written, however (and all - values are written if Full is set to 1). */ - full_set = astTestFull( channel ); - full = astGetFull( channel ); - if ( full <= 0 ) astSetFull( channel, -1 ); - -/* Handle each axis in turn. */ - for ( axis = 0; axis < this->naxes; axis++ ) { - -/* Create a keyword and comment appropriate to the axis (converting to - 1-based axis numbering). */ - (void) sprintf( key, "Ax%d", axis + 1 ); - (void) sprintf( comment, "Axis number %d", axis + 1 ); - -/* Write out the axis Object description. */ - astWriteObject( channel, key, 1, 0, this->axis[ axis ], comment ); - } - -/* Restore the Channel's original Full attribute setting. */ - if ( full_set ) { - astSetFull( channel, full ); - } else { - astClearFull( channel ); - } - -/* Free the inverse axis permutation array. */ - invperm = astFree( invperm ); - -/* Variants */ -/* ------- */ - if( this->variants ) astWriteObject( channel, "Vrnts", 1, 0, - this->variants, "Variant Frames" ); - } - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAFrame and astCheckFrame functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Frame,Mapping) -astMAKE_CHECK(Frame) - -AstFrame *astFrame_( int naxes, const char *options, int *status, ...) { -/* -*+ -* Name: -* astFrame - -* Purpose: -* Create a Frame. - -* Type: -* Protected function. - -* Synopsis: -* #include "frame.h" -* AstFrame *astFrame( int naxes, const char *options, int *status, ... ) - -* Class Membership: -* Frame constructor. - -* Description: -* This function creates a new Frame and optionally initialises its -* attributes. - -* Parameters: -* naxes -* The number of Frame axes. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new Frame. The syntax used is the same as -* for the astSet method and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of arguments may follow it in order to -* supply values to be substituted for these specifiers. The -* rules for supplying these are identical to those for the -* astSet method (and for the C "printf" function). - -* Returned Value: -* A pointer to the new Frame. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic Frame constructor which is -* available via the protected interface to the Frame class. A -* public interface is provided by the astFrameId_ function. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *new; /* Pointer to new Frame */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the Frame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitFrame( NULL, sizeof( AstFrame ), !class_init, &class_vtab, - "Frame", naxes ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Frame's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Frame. */ - return new; -} - -AstFrame *astInitFrame_( void *mem, size_t size, int init, - AstFrameVtab *vtab, const char *name, - int naxes, int *status ) { -/* -*+ -* Name: -* astInitFrame - -* Purpose: -* Initialise a Frame. - -* Type: -* Protected function. - -* Synopsis: -* #include "frame.h" -* AstFrame *astInitFrame( void *mem, size_t size, int init, -* AstFrameVtab *vtab, const char *name, -* int naxes ) - -* Class Membership: -* Frame initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Frame object. It allocates memory (if necessary) to accommodate -* the Frame plus any additional data associated with the derived class. -* It then initialises a Frame structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Frame at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Frame is to be created. This -* must be of sufficient size to accommodate the Frame data -* (sizeof(Frame)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Frame (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Frame -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Frame's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Frame. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* naxes -* The number of Frame axes. - -* Returned Value: -* A pointer to the new Frame. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstFrame *new; /* Pointer to new Frame */ - int axis; /* Loop counter for Frame axes */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitFrameVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check the number of axes for validity, reporting an error if necessary. */ - if ( naxes < 0 ) { - astError( AST__NAXIN, "astInitFrame(%s): Number of axes (%d) is " - "invalid - this number should not be negative.", status, name, naxes ); - -/* Initialise a Mapping structure (the parent class) as the first - component within the Frame structure, allocating memory if - necessary. Set the number of input/output coordinates to zero (the - astGetNin and astGetNout methods are over-ridden by the Frame class - to provide values for these that are equal to the number of Frame - axes). */ - } else { - new = (AstFrame *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - 0, 0, 1, 1 ); - - if ( astOK ) { - -/* Initialise the Frame data. */ -/* ----------------------------- */ -/* Set the number of Frame axes. */ - new->naxes = naxes; - -/* Initialise all attributes to their "undefined" values. */ - new->digits = -INT_MAX; - new->domain = NULL; - new->epoch = AST__BAD; - new->match_end = -INT_MAX; - new->max_axes = -INT_MAX; - new->min_axes = -INT_MAX; - new->permute = -INT_MAX; - new->preserve_axes = -INT_MAX; - new->title = NULL; - new->system = AST__BADSYSTEM; - new->alignsystem = AST__BADSYSTEM; - new->active_unit = -INT_MAX; - new->obsalt = AST__BAD; - new->obslat = AST__BAD; - new->obslon = AST__BAD; - new->dtai = AST__BAD; - new->dut1 = AST__BAD; - new->flags = 0; - new->variants = NULL; - -/* Allocate memory to store pointers to the Frame's Axis objects and to store - its axis permutation array. */ - new->axis = astMalloc( sizeof( AstAxis * ) * (size_t) naxes ); - new->perm = astMalloc( sizeof( int ) * (size_t) naxes ); - -/* Create a new Axis object to describe each axis of the Frame and store the - resulting pointers in the memory allocated above. Also initialise the - axis permutation array so that the axes appear in their natural order. */ - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) { - new->axis[ axis ] = astAxis( "", status ); - new->perm[ axis ] = axis; - } - -/* If an error occurred while creating the Axis objects, scan through the array - of pointers to them again to ensure that they are all correctly annulled. */ - if ( !astOK ) { - for ( axis = 0; axis < naxes; axis++ ) { - new->axis[ axis ] = astAnnul( new->axis[ axis ] ); - } - } - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new object. */ - return new; -} - -AstFrame *astLoadFrame_( void *mem, size_t size, - AstFrameVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadFrame - -* Purpose: -* Load a Frame. - -* Type: -* Protected function. - -* Synopsis: -* #include "frame.h" -* AstFrame *astLoadFrame( void *mem, size_t size, -* AstFrameVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* Frame loader. - -* Description: -* This function is provided to load a new Frame using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Frame structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Frame at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the Frame is to be loaded. -* This must be of sufficient size to accommodate the Frame data -* (sizeof(Frame)) plus any data used by derived classes. If a -* value of NULL is given, this function will allocate the -* memory itself using the "size" parameter to determine its -* size. -* size -* The amount of memory used by the Frame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Frame structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstFrame) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Frame. If this is NULL, a pointer to -* the (static) virtual function table for the Frame class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Frame" is used instead. - -* Returned Value: -* A pointer to the new Frame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstFrame *new; /* Pointer to the new Frame */ - char *sval; /* Pointer to string value */ - char key[ KEY_LEN + 1 ]; /* Buffer for keywords */ - double dval; /* DOuble attribute value */ - int axis; /* Loop counter for axes */ - int ival; /* Integer value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Frame. In this case the - Frame belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstFrame ); - vtab = &class_vtab; - name = "Frame"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitFrameVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Frame. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Assign values for transient components that are not included in the - Frame dump */ - new->flags = 0; - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Frame" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Naxes. */ -/* ------ */ -/* Obtain the number of Frame axes and allocate memory for the arrays - which hold axis information. */ - new->naxes = astReadInt( channel, "naxes", 0 ); - if ( new->naxes < 0 ) new->naxes = 0; - new->perm = astMalloc( sizeof( int ) * (size_t) new->naxes ); - new->axis = astMalloc( sizeof( AstAxis * ) * (size_t) new->naxes ); - -/* If an error occurred, ensure that any allocated memory is freed. */ - if ( !astOK ) { - new->perm = astFree( new->perm ); - new->axis = astFree( new->axis ); - -/* Otherwise, initialise the array of Axis pointers. */ - } else { - for ( axis = 0; axis < new->naxes; axis++ ) new->axis[ axis ] = NULL; - -/* Now obtain those input values which are required for each axis... */ - for ( axis = 0; axis < new->naxes; axis++ ) { - -/* Axis object. */ -/* ------------ */ -/* This must be read first, so that it can hold the other axis values - obtained below. */ - -/* Create a keyword appropriate to this axis. */ - (void) sprintf( key, "ax%d", axis + 1 ); - -/* Read the Axis object. If none was read, provide a default Axis - instead. */ - new->axis[ axis ] = astReadObject( channel, key, NULL ); - if ( !new->axis[ axis ] ) new->axis[ axis ] = astAxis( "", status ); - -/* Label. */ -/* ------ */ -/* Read the Label string for each axis. If a value is obtained, use - it to set the Label attribute for the axis. Free the memory holding - the string when no longer needed. */ - (void) sprintf( key, "lbl%d", axis + 1 ); - sval = astReadString( channel, key, NULL ); - if ( sval ) { - astSetAxisLabel( new->axis[ axis ], sval ); - sval = astFree( sval ); - } - -/* Symbol. */ -/* ------- */ - (void) sprintf( key, "sym%d", axis + 1 ); - sval = astReadString( channel, key, NULL ); - if ( sval ) { - astSetAxisSymbol( new->axis[ axis ], sval ); - sval = astFree( sval ); - } - -/* Format. */ -/* ------- */ - (void) sprintf( key, "fmt%d", axis + 1 ); - sval = astReadString( channel, key, NULL ); - if ( sval ) { - astSetAxisFormat( new->axis[ axis ], sval ); - sval = astFree( sval ); - } - -/* Unit. */ -/* ----- */ - (void) sprintf( key, "uni%d", axis + 1 ); - sval = astReadString( channel, key, NULL ); - if ( sval ) { - astSetAxisUnit( new->axis[ axis ], sval ); - sval = astFree( sval ); - } - -/* Direction. */ -/* ---------- */ - (void) sprintf( key, "dir%d", axis + 1 ); - ival = astReadInt( channel, key, -INT_MAX ); - if ( ival != -INT_MAX ) { - astSetAxisDirection( new->axis[ axis ], ival ); - } - -/* Top. */ -/*----- */ - (void) sprintf( key, "top%d", axis + 1 ); - dval = astReadDouble( channel, key, AST__BAD ); - if ( dval != AST__BAD ) { - astSetAxisTop( new->axis[ axis ], dval ); - } - -/* Bottom. */ -/*----- -- */ - (void) sprintf( key, "bot%d", axis + 1 ); - dval = astReadDouble( channel, key, AST__BAD ); - if ( dval != AST__BAD ) { - astSetAxisBottom( new->axis[ axis ], dval ); - } - -/* Digits. */ -/* ------- */ - (void) sprintf( key, "dig%d", axis + 1 ); - ival = astReadInt( channel, key, -INT_MAX ); - if ( ival != -INT_MAX ) { - astSetAxisDigits( new->axis[ axis ], ival ); - } - -/* Axis permutation array. */ -/* ----------------------- */ -/* Convert from 1-based to zero-based axis numbering at this - point. The default is the "un-permuted" value. */ - sprintf( key, "prm%d", axis + 1 ); - new->perm[ axis ] = astReadInt( channel, key, axis + 1 ) - 1; - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - -/* The remaining values are not associated with particular axes... */ - -/* Title. */ -/* ------ */ - new->title = astReadString( channel, "title", NULL ); - -/* Domain. */ -/* ------- */ - new->domain = astReadString( channel, "domain", NULL ); - -/* Epoch. */ -/* ------ */ -/* Interpret this as Besselian or Julian depending on its value. */ - new->epoch = astReadDouble( channel, "epoch", AST__BAD ); - if ( TestEpoch( new, status ) ) { - SetEpoch( new, ( new->epoch < 1984.0 ) ? palEpb2d( new->epoch ) : - palEpj2d( new->epoch ), status ); - } - -/* Digits. */ -/* ------- */ -/* This is the value that applies to the Frame as a whole. */ - new->digits = astReadInt( channel, "digits", -INT_MAX ); - if ( TestDigits( new, status ) ) SetDigits( new, new->digits, status ); - -/* PreserveAxes. */ -/* ------------- */ - new->preserve_axes = astReadInt( channel, "presrv", -INT_MAX ); - if ( TestPreserveAxes( new, status ) ) { - SetPreserveAxes( new, new->preserve_axes, status ); - } - -/* Permute. */ -/* -------- */ - new->permute = astReadInt( channel, "permut", -INT_MAX ); - if ( TestPermute( new, status ) ) SetPermute( new, new->permute, status ); - -/* MinAxes. */ -/* -------- */ - new->min_axes = astReadInt( channel, "minax", -INT_MAX ); - if ( TestMinAxes( new, status ) ) SetMinAxes( new, new->min_axes, status ); - -/* MaxAxes. */ -/* -------- */ - new->max_axes = astReadInt( channel, "maxax", -INT_MAX ); - if ( TestMaxAxes( new, status ) ) SetMaxAxes( new, new->max_axes, status ); - -/* MatchEnd. */ -/* --------- */ - new->match_end = astReadInt( channel, "mchend", -INT_MAX ); - if ( TestMatchEnd( new, status ) ) SetMatchEnd( new, new->match_end, status ); - -/* ObsLat. */ -/* ------- */ - new->obslat = astReadDouble( channel, "obslat", AST__BAD ); - if ( TestObsLat( new, status ) ) SetObsLat( new, new->obslat, status ); - -/* ObsLon. */ -/* ------- */ - new->obslon = astReadDouble( channel, "obslon", AST__BAD ); - if ( TestObsLon( new, status ) ) SetObsLon( new, new->obslon, status ); - -/* ObsAlt. */ -/* ------- */ - new->obsalt = astReadDouble( channel, "obsalt", AST__BAD ); - if ( TestObsAlt( new, status ) ) SetObsAlt( new, new->obsalt, status ); - -/* Dtai. */ -/* ---- */ - new->dtai = astReadDouble( channel, "dtai", AST__BAD ); - if ( TestDtai( new, status ) ) SetDtai( new, new->dtai, status ); - -/* Dut1. */ -/* ---- */ - new->dut1 = astReadDouble( channel, "dut1", AST__BAD ); - if ( TestDut1( new, status ) ) SetDut1( new, new->dut1, status ); - -/* ActiveUnit. */ -/* ----------- */ - new->active_unit = astReadInt( channel, "actunt", -INT_MAX ); - if ( TestActiveUnit( new, status ) ) SetActiveUnit( new, new->active_unit, status ); - -/* System. */ -/* ------- */ -/* Set the default and read the external representation as a string. */ - new->system = AST__BADSYSTEM; - sval = astReadString( channel, "system", NULL ); - -/* If a value was read, convert from a string to a System code. */ - if ( sval ) { - if ( astOK ) { - new->system = astSystemCode( new, sval ); - -/* Report an error if the value wasn't recognised. */ - if ( new->system == AST__BADSYSTEM ) { - astError( AST__ATTIN, - "astRead(%s): Invalid System description " - "\"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* AlignSystem. */ -/* ------------ */ -/* Set the default and read the external representation as a string. */ - new->alignsystem = AST__BADSYSTEM; - sval = astReadString( channel, "alsys", NULL ); - -/* If a value was read, convert from a string to a System code. */ - if ( sval ) { - if ( astOK ) { - new->alignsystem = astSystemCode( new, sval ); - -/* Report an error if the value wasn't recognised. */ - if ( new->alignsystem == AST__BADSYSTEM ) { - astError( AST__ATTIN, - "astRead(%s): Invalid AlignSystem description " - "\"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* Variants. */ -/* -------- */ - new->variants = astReadObject( channel, "vrnts", NULL ); - } - -/* If an error occurred, clean up by deleting the new Frame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Frame pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -const char *astAbbrev_( AstFrame *this, int axis, const char *fmt, - const char *str1, const char *str2, int *status ) { - if ( !astOK ) return str2; - return (**astMEMBER(this,Frame,Abbrev))( this, axis, fmt, str1, str2, status ); -} -int astFields_( AstFrame *this, int axis, const char *fmt, - const char *str, int maxfld, char **fields, - int *nc, double *val, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,Fields))( this, axis, fmt, str, maxfld, fields, nc, val, status ); -} -void astCheckPerm_( AstFrame *this, const int *perm, const char *method, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,CheckPerm))( this, perm, method, status ); -} - -AstPointSet *astResolvePoints_( AstFrame *this, const double point1[], - const double point2[], AstPointSet *in, - AstPointSet *out, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Frame,ResolvePoints))( this, point1, point2, in, out, status ); -} -AstLineDef *astLineDef_( AstFrame *this, const double start[2], - const double end[2], int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Frame,LineDef))( this, start, end, status ); -} -int astLineCrossing_( AstFrame *this, AstLineDef *l1, AstLineDef *l2, - double **cross, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,LineCrossing))( this, l1, l2, cross, status ); -} -void astLineOffset_( AstFrame *this, AstLineDef *line, double par, double prp, - double point[2], int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Frame,LineOffset))( this, line, par, prp, point, status ); -} -int astLineContains_( AstFrame *this, AstLineDef *l, int def, double *point, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,LineContains))( this, l, def, point, status ); -} -AstFrameSet *astConvert_( AstFrame *from, AstFrame *to, - const char *domainlist, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(from,Frame,Convert))( from, to, domainlist, status ); -} -AstFrameSet *astConvertX_( AstFrame *to, AstFrame *from, - const char *domainlist, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(to,Frame,ConvertX))( to, from, domainlist, status ); -} -double astAngle_( AstFrame *this, const double a[], const double b[], - const double c[], int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,Frame,Angle))( this, a, b, c, status ); -} -int astGetActiveUnit_( AstFrame *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,GetActiveUnit))( this, status ); -} -int astTestActiveUnit_( AstFrame *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,TestActiveUnit))( this, status ); -} -void astSetActiveUnit_( AstFrame *this, int value, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,SetActiveUnit))( this, value, status ); -} -double astDistance_( AstFrame *this, - const double point1[], const double point2[], int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,Frame,Distance))( this, point1, point2, status ); -} -AstFrameSet *astFindFrame_( AstFrame *target, AstFrame *template, - const char *domainlist, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(target,Frame,FindFrame))( target, template, domainlist, status ); -} -void astMatchAxes_( AstFrame *frm1, AstFrame *frm2, int *axes, int *status ) { - if ( !astOK ) return; - (**astMEMBER(frm1,Frame,MatchAxes))( frm1, frm2, axes, status ); -} -void astMatchAxesX_( AstFrame *frm2, AstFrame *frm1, int *axes, int *status ) { - if ( !astOK ) return; - (**astMEMBER(frm2,Frame,MatchAxesX))( frm2, frm1, axes, status ); -} -const char *astFormat_( AstFrame *this, int axis, double value, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Frame,Format))( this, axis, value, status ); -} -double astCentre_( AstFrame *this, int axis, double value, double gap, int *status ) { - if ( !astOK ) return 0.0; - return (**astMEMBER(this,Frame,Centre))( this, axis, value, gap, status ); -} -double astGap_( AstFrame *this, int axis, double gap, int *ntick, int *status ) { - if ( !astOK ) return 0.0; - return (**astMEMBER(this,Frame,Gap))( this, axis, gap, ntick, status ); -} -AstAxis *astGetAxis_( AstFrame *this, int axis, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Frame,GetAxis))( this, axis, status ); -} -int astGetNaxes_( AstFrame *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,GetNaxes))( this, status ); -} -const int *astGetPerm_( AstFrame *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Frame,GetPerm))( this, status ); -} -AstFrameSet *astGetFrameVariants_( AstFrame *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Frame,GetFrameVariants))( this, status ); -} -void astSetFrameVariants_( AstFrame *this, AstFrameSet *variants, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,SetFrameVariants))( this, variants, status ); -} - - -int astMatch_( AstFrame *this, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, - AstMapping **map, AstFrame **result, int *status ) { - - AstFrame *super_this; - const char *dom; - int match; - - if ( !astOK ) return 0; - - match = (**astMEMBER(this,Frame,Match))( this, target, matchsub, - template_axes, target_axes, - map, result, status ); - -/* If the template ("this") could not be used to probe the target, it may - be because the template class is a more specialised form of the target - class. E.g. a SkyFrame cannot directly be used to probe a Frame, but a - Frame *can* be used to probe a SkyFrame. This means (for instance), - that a basic Frame with Domain FRED cannot be aligned (using astConvert) - with a CmpFrame with Domain FRED. This sort of alignment is often - useful, so we try now to use the supplied template to probe a modified - form of the target that has been cast into the same class as the - template. This is only possible if the template class is a sub-class of - the target class. Attempt to do the cast. */ - if( ! match && matchsub ) { - super_this = (AstFrame *) astCast( this, target ); - -/* If the cast was possible, fix the template Domain since the parent - class may provide a different default Domain, and then invoke the Match - method appropriate to the new template class (i.e. the target class). */ - if( super_this ) { - if( astTestDomain( target ) ) { - dom = astGetDomain( this ); - if( astChrLen( dom ) > 0 ) astSetDomain( super_this, dom ); - } - match = (**astMEMBER(super_this,Frame,Match))( super_this, target, - matchsub, template_axes, - target_axes, map, - result, status ); - super_this = astAnnul( super_this ); - } - } - - return match; -} - - -int astIsUnitFrame_( AstFrame *this, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,IsUnitFrame))( this, status ); -} -void astNorm_( AstFrame *this, double value[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,Norm))( this, value, status ); -} -void astNormBox_( AstFrame *this, double lbnd[], double ubnd[], AstMapping *reg, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,NormBox))( this, lbnd, ubnd, reg, status ); -} -double astAxDistance_( AstFrame *this, int axis, double v1, double v2, int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,Frame,AxDistance))( this, axis, v1, v2, status ); -} -void astAxNorm_( AstFrame *this, int axis, int oper, int nval, double *values, - int *status ){ - if ( !astOK ) return; - return (**astMEMBER(this,Frame,AxNorm))( this, axis, oper, nval, values, status ); -} -double astAxOffset_( AstFrame *this, int axis, double v1, double dist, int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,Frame,AxOffset))( this, axis, v1, dist, status ); -} - - -AstPointSet *astFrameGrid_( AstFrame *this, int size, const double *lbnd, - const double *ubnd, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Frame,FrameGrid))( this, size, lbnd, ubnd, status ); -} - - -void astOffset_( AstFrame *this, const double point1[], const double point2[], - double offset, double point3[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,Offset))( this, point1, point2, offset, point3, status ); -} -double astAxAngle_( AstFrame *this, const double a[2], const double b[2], - int axis, int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,Frame,AxAngle))( this, a, b, axis, status ); -} -double astOffset2_( AstFrame *this, const double point1[2], double angle, - double offset, double point2[2], int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,Frame,Offset2))( this, point1, angle, offset, point2, status ); -} -void astIntersect_( AstFrame *this, const double a1[2], - const double a2[2], const double b1[2], - const double b2[2], double cross[2], - int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,Intersect))( this, a1, a2, b1, b2, cross, status ); -} -void astOverlay_( AstFrame *template, const int *template_axes, - AstFrame *result, int *status ) { - if ( !astOK ) return; - (**astMEMBER(template,Frame,Overlay))( template, template_axes, result, status ); -} -void astPermAxes_( AstFrame *this, const int perm[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,PermAxes))( this, perm, status ); -} -AstFrame *astPickAxes_( AstFrame *this, int naxes, const int axes[], - AstMapping **map, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Frame,PickAxes))( this, naxes, axes, map, status ); -} -void astPrimaryFrame_( AstFrame *this, int axis1, - AstFrame **frame, int *axis2, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,PrimaryFrame))( this, axis1, frame, axis2, status ); -} -void astResolve_( AstFrame *this, const double point1[], const double point2[], - const double point3[], double point4[], double *d1, - double *d2, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,Resolve))( this, point1, point2, point3, point4, d1, d2, status ); -} -void astSetAxis_( AstFrame *this, int axis, AstAxis *newaxis, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,SetAxis))( this, axis, newaxis, status ); -} -void astSetUnit_( AstFrame *this, int axis, const char *value, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,SetUnit))( this, axis, value, status ); -} -void astClearUnit_( AstFrame *this, int axis, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,ClearUnit))( this, axis, status ); -} -int astSubFrame_( AstFrame *target, AstFrame *template, int result_naxes, - const int *target_axes, const int *template_axes, - AstMapping **map, AstFrame **result, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(target,Frame,SubFrame))( target, template, result_naxes, - target_axes, template_axes, - map, result, status ); -} -int astUnformat_( AstFrame *this, int axis, const char *string, - double *value, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,Unformat))( this, axis, string, value, status ); -} -int astValidateAxis_( AstFrame *this, int axis, int fwd, const char *method, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,ValidateAxis))( this, axis, fwd, method, status ); -} -void astValidateAxisSelection_( AstFrame *this, int naxes, const int *axes, - const char *method, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,ValidateAxisSelection))( this, naxes, axes, - method, status ); -} -AstSystemType astValidateSystem_( AstFrame *this, AstSystemType system, const char *method, int *status ) { - if ( !astOK ) return AST__BADSYSTEM; - return (**astMEMBER(this,Frame,ValidateSystem))( this, system, method, status ); -} -AstSystemType astSystemCode_( AstFrame *this, const char *system, int *status ) { - if ( !astOK ) return AST__BADSYSTEM; - return (**astMEMBER(this,Frame,SystemCode))( this, system, status ); -} -const char *astSystemString_( AstFrame *this, AstSystemType system, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Frame,SystemString))( this, system, status ); -} -int astAxIn_( AstFrame *this, int axis, double lo, double hi, double val, - int closed, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,AxIn))( this, axis, lo, hi, val, closed, status ); -} -int astGetFrameFlags_( AstFrame *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Frame,GetFrameFlags))( this, status ); -} -void astSetFrameFlags_( AstFrame *this, int value, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Frame,SetFrameFlags))( this, value, status ); -} - - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstFrame *PickAxesId_( AstFrame *, int, const int[], AstMapping **, int * ); -AstFrame *astFrameId_( int, const char *, ... ); -const char *astFormatId_( AstFrame *, int, double, int * ); -int astUnformatId_( AstFrame *, int, const char *, double *, int * ); -void astPermAxesId_( AstFrame *, const int[], int * ); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -const char *astFormatId_( AstFrame *this, int axis, double value, int *status ) { -/* -*++ -* Name: -c astFormat -f AST_FORMAT - -* Purpose: -* Format a coordinate value for a Frame axis. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c const char *astFormat( AstFrame *this, int axis, double value ) -f RESULT = AST_FORMAT( THIS, AXIS, VALUE, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function returns a pointer to a string containing the -f This function returns a character string containing the -* formatted (character) version of a coordinate value for a Frame -* axis. The formatting applied is determined by the Frame's -* attributes and, in particular, by any Format attribute string -* that has been set for the axis. A suitable default format (based -* on the Digits attribute value) will be applied if necessary. - -* Parameters: -c this -f THIS = INTEGER (given) -* Pointer to the Frame. -c axis -f AXIS = INTEGER (Given) -* The number of the Frame axis for which formatting is to be -* performed (axis numbering starts at 1 for the first axis). -c value -f VALUE = DOUBLE PRECISION (Given) -* The coordinate value to be formatted. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astFormat() -c A pointer to a null-terminated string containing the formatted -c value. -f AST_FORMAT = CHARACTER * ( AST__SZCHR ) -f The formatted value. - -* Notes: -c - The returned pointer is guaranteed to remain valid and the -c string to which it points will not be over-written for a total -c of 50 successive invocations of this function. After this, the -c memory containing the string may be re-used, so a copy of the -c string should be made if it is needed for longer than this. -c - A formatted value may be converted back into a numerical (double) -c value using astUnformat. -f - A formatted value may be converted back into a numerical -f (double precision) value using AST_UNFORMAT. -c - A NULL pointer will be returned if this function is invoked -c with the AST error status set, or if it should fail for any -c reason. -f - A blank string will be returned if this function is invoked -f with STATUS set to an error value, or if it should fail for any -f reason. -*-- - -* Implementation Notes: -* This function implements the public interface for the astFormat -* method. It is identical to astFormat_ except that: -* -* - The axis index is decremented by 1 before use. This allows the -* public interface to use 1-based axis numbers (whereas internally -* axis numbers are zero-based). -* -* - The returned string value is buffered in dynamically allocated -* memory so that it will remain valid for a guaranteed number of -* function invocations. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - const char *fvalue; /* Pointer to formatted value */ - const char *result; /* Pointer value to return */ - int i; /* Loop counter for initialisation */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(this); - -/* If the "astformatid_strings" array has not been initialised, fill it with NULL - pointers. */ - if ( !astformatid_init ) { - astformatid_init = 1; - for ( i = 0; i < ASTFORMATID_MAX_STRINGS; i++ ) astformatid_strings[ i ] = NULL; - } - -/* Invoke the normal astFormat_ function to obtain a pointer to the - required formatted value, adjusting the axis index to become - zero-based. */ - fvalue = astFormat( this, axis - 1, value ); - -/* If OK, store a copy of the resulting string in dynamically allocated memory, - putting a pointer to the copy into the next element of the "astformatid_strings" - array. (This process also de-allocates any previously allocated memory pointed - at by this "astformatid_strings" element, so the earlier string is effectively - replaced by the new one.) */ - if ( astOK ) { - astBeginPM; - astformatid_strings[ astformatid_istr ] = astStore( astformatid_strings[ astformatid_istr ], fvalue, - strlen( fvalue ) + (size_t) 1 ); - astEndPM; - -/* If OK, return a pointer to the copy and increment "astformatid_istr" to use - the next element of "astformatid_strings" on the next invocation. Recycle - "astformatid_istr" to zero when all elements have been used. */ - if ( astOK ) { - result = astformatid_strings[ astformatid_istr++ ]; - if ( astformatid_istr == ( ASTFORMATID_MAX_STRINGS - 1 ) ) astformatid_istr = 0; - } - } - -/* Return the result. */ - return result; - -} - -AstFrame *astFrameId_( int naxes, const char *options, ... ) { -/* -*++ -* Name: -c astFrame -f AST_FRAME - -* Purpose: -* Create a Frame. - -* Type: -* Public function. - -* Synopsis: -c #include "frame.h" -c AstFrame *astFrame( int naxes, const char *options, ... ) -f RESULT = AST_FRAME( NAXES, OPTIONS, STATUS ) - -* Class Membership: -* Frame constructor. - -* Description: -* This function creates a new Frame and optionally initialises its -* attributes. -* -* A Frame is used to represent a coordinate system. It does this -* in rather the same way that a frame around a graph describes the -* coordinate space in which data are plotted. Consequently, a -* Frame has a Title (string) attribute, which describes the -* coordinate space, and contains axes which in turn hold -* information such as Label and Units strings which are used for -* labelling (e.g.) graphical output. In general, however, the -* number of axes is not restricted to two. -* -* Functions are available for converting Frame coordinate values -* into a form suitable for display, and also for calculating -* distances and offsets between positions within the Frame. -* -* Frames may also contain knowledge of how to transform to and -* from related coordinate systems. - -* Parameters: -c naxes -f NAXES = INTEGER (Given) -* The number of Frame axes (i.e. the number of dimensions of -* the coordinate space which the Frame describes). -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Frame. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Frame. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astFrame() -f AST_FRAME = INTEGER -* A pointer to the new Frame. - -* Examples: -c frame = astFrame( 2, "Title=Energy Spectrum: Plot %d", n ); -c Creates a new 2-dimensional Frame and initialises its Title -c attribute to the string "Energy Spectrum: Plot ", where -c takes the value of the int variable "n". -c frame = astFrame( 2, "Label(1)=Energy, Label(2)=Response" ); -c Creates a new 2-dimensional Frame and initialises its axis -c Label attributes to suitable string values. -f FRAME = AST_FRAME( 2, 'Title=Energy Spectrum', STATUS ); -f Creates a new 2-dimensional Frame and initialises its Title -f attribute to the string "Energy Spectrum". -f FRAME = AST_FRAME( 2, 'Label(1)=Energy, Label(2)=Response', STATUS ); -f Creates a new 2-dimensional Frame and initialises its axis -f Label attributes to suitable string values. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astFrame constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astFrame_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - The variable argument list also prevents this function from -* invoking astFrame_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *new; /* Pointer to new Frame */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the Frame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitFrame( NULL, sizeof( AstFrame ), !class_init, &class_vtab, - "Frame", naxes ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Frame's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Frame. */ - return astMakeId( new ); -} - -void astPermAxesId_( AstFrame *this, const int perm[], int *status ) { -/* -*++ -* Name: -c astPermAxes -f AST_PERMAXES - -* Purpose: -* Permute the axis order in a Frame. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c void astPermAxes( AstFrame *this, const int perm[] ) -f CALL AST_PERMAXES( THIS, PERM, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function permutes the order in which a Frame's axes occur. -f This routine permutes the order in which a Frame's axes occur. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c perm -f PERM( * ) = INTEGER (Given) -* An array with one element for each axis of the Frame (Naxes -* attribute). This should list the axes in their new order, -* using the original axis numbering (which starts at 1 for the -* first axis). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Only genuine permutations of the axis order are permitted, so -c each axis must be referenced exactly once in the "perm" array. -f each axis must be referenced exactly once in the PERM array. -* - If successive axis permutations are applied to a Frame, then -* the effects are cumulative. -*-- - -* Implementation Notes: -* This function implements the public interface for the -* astPermAxes method. It is identical to astPermAxes_ except that -* the axis numbers in the "perm" array are decremented by 1 before -* use. This is to allow the public interface to use one-based axis -* numbering (internally, zero-based axis numbering is used). -*/ - -/* Local Variables: */ - int *perm1; /* Pointer to modified perm array */ - int axis; /* Loop counter for Frame axes */ - int naxes; /* Number of Frame axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the number of Frame axes. */ - naxes = astGetNaxes( this ); - -/* Allocate an array to hold a modified version of the "perm" - array. */ - perm1 = astMalloc( sizeof( int ) * (size_t) naxes ); - if ( astOK ) { - -/* Make a modified copy of the "perm" array by subtracting one from - each element. This allows the public interface to use one-based - axis numbering, whereas all internal code is zero-based. */ - for ( axis = 0; axis < naxes; axis++ ) perm1[ axis ] = perm[ axis ] - 1; - -/* Invoke the normal astPermAxes_ function to permute the Frame's axes. */ - astPermAxes( this, perm1 ); - } - -/* Free the temporary array. */ - perm1 = astFree( perm1 ); -} - -AstFrame *astPickAxesId_( AstFrame *this, int naxes, const int axes[], - AstMapping **map, int *status ) { -/* -*++ -* Name: -c astPickAxes -f AST_PICKAXES - -* Purpose: -* Create a new Frame by picking axes from an existing one. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c AstFrame *astPickAxes( AstFrame *this, int naxes, const int axes[], -c AstMapping **map ) -f RESULT = AST_PICKAXES( THIS, NAXES, AXES, MAP, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -* This function creates a new Frame whose axes are copied from an -* existing Frame along with other Frame attributes, such as its -* Title. Any number (zero or more) of the original Frame's axes -* may be copied, in any order, and additional axes with default -* attributes may also be included in the new Frame. -* -c Optionally, a Mapping that converts between the coordinate -f A Mapping that converts between the coordinate -* systems described by the two Frames will also be returned. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the original Frame. -c naxes -f NAXES = INTEGER (Given) -* The number of axes required in the new Frame. -c axes -f AXES( NAXES ) = INTEGER (Given) -c An array, with "naxes" elements, which lists the axes to be -f An array which lists the axes to be -* copied. These should be given in the order required in the -* new Frame, using the axis numbering in the original Frame -* (which starts at 1 for the first axis). Axes may be selected -* in any order, but each may only be used once. If additional -* (default) axes are also to be included, the corresponding -* elements of this array should be set to zero. -c map -f MAP = INTEGER (Returned) -c Address of a location in which to return a pointer to a new -f A pointer to a new -* Mapping. This will be a PermMap (or a UnitMap as a special -* case) that describes the axis permutation that has taken -* place between the original and new Frames. The Mapping's -* forward transformation will convert coordinates from the -* original Frame into the new one, and vice versa. -c -c If this Mapping is not required, a NULL value may be supplied -c for this parameter. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPickAxes() -f AST_PICKAXES = INTEGER -* A pointer to the new Frame. - -* Applicability: -* Frame -* This function applies to all Frames. The class of Frame returned -* may differ from that of the original Frame, depending on which -* axes are selected. For example, if a single axis is picked from a -* SkyFrame (which must always have two axes) then the resulting -* Frame cannot be a valid SkyFrame, so will revert to the parent -* class (Frame) instead. -* FrameSet -* Using this function on a FrameSet is identical to using it on -* the current Frame in the FrameSet. The returned Frame will not -* be a FrameSet. -* Region -* If this function is used on a Region, an attempt is made to -* retain the bounds information on the selected axes. If -* succesful, the returned Frame will be a Region of some class. -* Otherwise, the returned Frame is obtained by calling this -* function on the Frame represented by the supplied Region (the -* returned Frame will then not be a Region). In order to be -* succesful, the selected axes in the Region must be independent -* of the others. For instance, a Box can be split in this way but -* a Circle cannot. Another requirement for success is that no -* default axes are added (that is, the -c "axes" -f AXES -* array must not contain any zero values. - -* Notes: -c - The new Frame will contain a "deep" copy (c.f. astCopy) of all -f - The new Frame will contain a "deep" copy (c.f. AST_COPY) of all -* the data selected from the original Frame. Modifying any aspect -* of the new Frame will therefore not affect the original one. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* This function implements the public interface for the -* astPickAxes method. It is identical to astPickAxes_ except for -* the following: -* -* - The axis numbers in the "axes" array are decremented by 1 before -* use. This is to allow the public interface to use one-based axis -* numbering (internally, zero-based axis numbering is used). -* -* - An ID value is returned via the "map" parameter (if used) -* instead of a true C pointer. This is required because this -* conversion cannot be performed by the macro that invokes the -* function. -*/ - -/* Local Variables: */ - AstFrame *result; /* Pointer to result Frame */ - int *axes1; /* Pointer to modified axes array */ - int axis; /* Loop counter for axes */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Allocate an array to hold a modified version of the "axes" array - (check that "naxes" is valid first - if not, this error will be - reported by astPickAxes_ below). */ - axes1 = ( naxes >= 0 ) ? astMalloc( sizeof( int ) * (size_t) naxes ) : - NULL; - if ( astOK ) { - -/* Make a modified copy of the "axes" array by subtracting one from - each element. This allows the public interface to use one-based - axis numbering, whereas all internal code is zero-based. */ - for ( axis = 0; axis < naxes; axis++ ) axes1[ axis ] = axes[ axis ] - 1; - -/* Invoke the normal astPickAxes_ function to select the required axes. */ - result = astPickAxes( this, naxes, axes1, map ); - } - -/* Free the temporary array. */ - axes1 = astFree( axes1 ); - -/* If required, return an ID value for the Mapping. */ - if ( map ) *map = astMakeId( *map ); - -/* Return the result. */ - return result; -} - -int astUnformatId_( AstFrame *this, int axis, const char *string, - double *value, int *status ) { -/* -*++ -* Name: -c astUnformat -f AST_UNFORMAT - -* Purpose: -* Read a formatted coordinate value for a Frame axis. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frame.h" -c int astUnformat( AstFrame *this, int axis, const char *string, -c double *value ) -f RESULT = AST_UNFORMAT( THIS, AXIS, STRING, VALUE, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function reads a formatted coordinate value (given as a -c character string) for a Frame axis and returns the equivalent -c numerical (double) value. It also returns the number of -c characters read from the string. -f This function reads a formatted coordinate value (given as a -f character string) for a Frame axis and returns the equivalent -f numerical (double precision) value. It also returns the number -f of characters read from the string. -* -c The principle use of this function is in decoding user-supplied -c input which contains formatted coordinate values. Free-format -c input is supported as far as possible. If input is ambiguous, it -c is interpreted with reference to the Frame's attributes (in -c particular, the Format string associated with the Frame's -c axis). This function is, in essence, the inverse of astFormat. -f The principle use of this function is in decoding user-supplied -f input which contains formatted coordinate values. Free-format -f input is supported as far as possible. If input is ambiguous, it -f is interpreted with reference to the Frame's attributes (in -f particular, the Format string associated with the Frame's -f axis). This function is, in essence, the inverse of AST_FORMAT. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Frame. -c axis -f AXIS = INTEGER (Given) -* The number of the Frame axis for which a coordinate value is to -* be read (axis numbering starts at 1 for the first axis). -c string -f STRING = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing the -c formatted coordinate value. -f A character string containing the formatted coordinate value. -* This string may contain additional information following the -* value to be read, in which case reading stops at the first -* character which cannot be interpreted as part of the value. -* Any white space before or after the value is discarded. -c value -f VALUE = DOUBLE PRECISION (Returned) -c Pointer to a double in which the coordinate value read will be -c returned. -f The coordinate value read. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astUnformat() -f AST_UNFORMAT = INTEGER -* The number of characters read from the string in order to -* obtain the coordinate value. This will include any white -* space which occurs before or after the value. - -* Applicability: -* Frame -* This function applies to all Frames. See the "Frame Input -* Format" section below for details of the input formats -* accepted by a basic Frame. -* SkyFrame -* The SkyFrame class re-defines the input format to be suitable -* for representing angles and times, with the resulting -* coordinate value returned in radians. See the "SkyFrame -* Input Format" section below for details of the formats -* accepted. -* FrameSet -* The input formats accepted by a FrameSet are determined by -* its current Frame (as specified by the Current attribute). - -* Frame Input Format -* The input format accepted for a basic Frame axis is as follows: -* - An optional sign, followed by: -* - A sequence of one or more digits possibly containing a decimal point, -* followed by: -* - An optional exponent field. -* - The exponent field, if present, consists of "E" or "e" -* followed by a possibly signed integer. -* -* Examples of acceptable Frame input formats include: -* - 99 -* - 1.25 -* - -1.6 -* - 1E8 -* - -.99e-17 -* - - -* SkyFrame Input Format -* The input format accepted for a SkyFrame axis is as follows: -* - An optional sign, followed by between one and three fields -* representing either degrees, arc-minutes, arc-seconds or hours, -* minutes, seconds (e.g. "-12 42 03"). -* - Each field should consist of a sequence of one or more digits, -* which may include leading zeros. At most one field may contain a -* decimal point, in which case it is taken to be the final field -* (e.g. decimal degrees might be given as "124.707", while degrees -* and decimal arc-minutes might be given as "-13 33.8"). -* - The first field given may take any value, allowing angles and -* times outside the conventional ranges to be -* represented. However, subsequent fields must have values of less -* than 60 (e.g. "720 45 31" is valid, whereas "11 45 61" is not). -* - Fields may be separated by white space or by ":" (colon), but -* the choice of separator must be used consistently throughout the -* value. Additional white space may be present around fields and -* separators (e.g. "- 2: 04 : 7.1"). -* - The following field identification characters may be used as -* separators to replace either of those above (or may be appended -* to the final field), in order to identify the field to which -* they are appended: "d"---degrees; "h"---hours; "m"---minutes of -* arc or time; "s"---seconds of arc or time; "'" (single -* quote)---minutes of arc; """ (double quote)---seconds of arc. -* Either lower or upper case may be used. Fields must be given in -* order of decreasing significance (e.g. "-11D 3' 14.4"" or -* "22h14m11.2s"). -* - The presence of any of the field identification characters -* "d", "'" (single quote) or """ (double quote) indicates that the -* value is to be interpreted as an angle. Conversely, the presence -* of "h" indicates that it is to be interpreted as a time (with 24 -* hours corresponding to 360 degrees). Incompatible angle/time -* identification characters may not be mixed (e.g. "10h14'3"" is -* not valid). The remaining field identification characters and -* separators do not specify a preference for an angle or a time -* and may be used with either. -c - If no preference for an angle or a time is expressed anywhere -c within the value, it is interpreted as an angle if the Format -c attribute string associated with the SkyFrame axis generates an -c angle and as a time otherwise. This ensures that values produced -c by astFormat are correctly interpreted by astUnformat. -f - If no preference for an angle or a time is expressed anywhere -f within the value, it is interpreted as an angle if the Format -f attribute string associated with the SkyFrame axis generates an -f angle and as a time otherwise. This ensures that values produced -f by AST_FORMAT are correctly interpreted by AST_UNFORMAT. -* - Fields may be omitted, in which case they default to zero. The -* remaining fields may be identified by using appropriate field -* identification characters (see above) and/or by adding extra -* colon separators (e.g. "-05m13s" is equivalent to "-:05:13"). If -* a field is not identified explicitly, it is assumed that -* adjacent fields have been given, after taking account of any -* extra separator characters (e.g. "14:25.4s" specifies minutes -* and seconds, while "14::25.4s" specifies degrees and seconds). -c - If fields are omitted in such a way that the remaining ones -c cannot be identified uniquely (e.g. "01:02"), then the first -c field (either given explicitly or implied by an extra leading -c colon separator) is taken to be the most significant field that -c astFormat would produce when formatting a value (using the -c Format attribute associated with the SkyFrame axis). By -c default, this means that the first field will normally be -c interpreted as degrees or hours. However, if this does not -c result in consistent field identification, then the last field -c (either given explicitly or implied by an extra trailing colon -c separator) is taken to to be the least significant field that -c astFormat would produce. -f - If fields are omitted in such a way that the remaining ones -f cannot be identified uniquely (e.g. "01:02"), then the first -f field (either given explicitly or implied by an extra leading -f colon separator) is taken to be the most significant field that -f AST_FORMAT would produce when formatting a value (using the -f Format attribute associated with the SkyFrame axis). By -f default, this means that the first field will normally be -f interpreted as degrees or hours. However, if this does not -f result in consistent field identification, then the last field -f (either given explicitly or implied by an extra trailing colon -f separator) is taken to to be the least significant field that -f AST_FORMAT would produce. -* -c This final convention is intended to ensure that values formatted -c by astFormat which contain less than three fields will be -c correctly interpreted if read back using astUnformat, even if -c they do not contain field identification characters. -f This final convention is intended to ensure that values formatted -f by AST_FORMAT which contain less than three fields will be -f correctly interpreted if read back using AST_UNFORMAT, even if -f they do not contain field identification characters. -* -* Examples of acceptable SkyFrame input formats (with -* interpretation in parentheses) include: -* - -14d 13m 22.2s (-14d 13' 22.2") -* - + 12:34:56.7 (12d 34' 56.7" or 12h 34m 56.7s) -* - 001 : 02 : 03.4 (1d 02' 03.4" or 1h 02m 03.4s) -* - 22h 30 (22h 30m 00s) -* - 136::10" (136d 00' 10" or 136h 00m 10s) -* - -14M 27S (-0d 14' 27" or -0h 14m 27s) -* - -:14: (-0d 14' 00" or -0h 14m 00s) -* - -::4.1 (-0d 00' 04.1" or -0h 00m 04.1s) -* - .9" (0d 00' 00.9") -* - d12m (0d 12' 00") -* - H 12:22.3s (0h 12m 22.3s) -* - (AST__BAD) -* -* Where alternative interpretations are shown, the choice of angle or -* time depends on the associated Format(axis) attribute. - -* Notes: -* - A function value of zero (and no coordinate value) will be -* returned, without error, if the string supplied does not contain -* a suitably formatted value. -c - Beware that it is possible for a formatting error part-way -c through an input string to terminate input before it has been -c completely read, but to yield a coordinate value that appears -c valid. For example, if a user types "1.5r6" instead of "1.5e6", -c the "r" will terminate input, giving an incorrect coordinate -c value of 1.5. It is therefore most important to check the return -c value of this function to ensure that the correct number of -c characters have been read. -f - Beware that it is possible for a formatting error part-way -f through an input string to terminate input before it has been -f completely read, but to yield a coordinate value that appears -f valid. For example, if a user types "1.5R6" instead of "1.5E6", -f the "R" will terminate input, giving an incorrect coordinate -f value of 1.5. It is therefore most important to check the return -f value of this function to ensure that the correct number of -f characters have been read. -* - An error will result if a value is read which appears to have -* the correct format, but which cannot be converted into a valid -* coordinate value (for instance, because the value of one or more -* of its fields is invalid). -* - The string "" is recognised as a special case and will -* yield the coordinate value AST__BAD without error. The test for -* this string is case-insensitive and also permits embedded white -* space. -c - A function result of zero will be returned and no coordinate -c value will be returned via the "value" pointer if this function -c is invoked with the AST error status set, or if it should fail -c for any reason. -f - A function result of zero will be returned and no coordinate -f value will be returned via the VALUE argument if this function -f is invoked with the AST error status set, or if it should fail -f for any reason. -*-- - -* Implementation Notes: -* This function implements the public interface for the -* astUnformat method. It is identical to astUnformat_ except that: -* -* - The axis index is decremented by 1 before use. This allows the -* public interface to use 1-based axis numbers (whereas internally -* axis numbers are zero-based). -*/ - -/* Invoke the normal astUnformat_ function, adjusting the axis index - to become zero-based. */ - return astUnformat( this, axis - 1, string, value ); -} - - - - - - - - - - - - - diff --git a/ast/frame.f b/ast/frame.f deleted file mode 100644 index d88402d..0000000 --- a/ast/frame.f +++ /dev/null @@ -1,71 +0,0 @@ - CHARACTER * ( * ) FUNCTION AST_FORMAT( THIS, AXIS, VALUE ) -*+ -* Name: -* AST_FORMAT - -* Purpose: -* Wrap up the C ast_format_a function. - -* Language: -* Fortran 77 - -* Invocation: -* RESULT = AST_FORMAT( THIS, AXIS, VALUE ) - -* Description: -* This function is a wrap-up of the C ast_format_a function. It -* will rarely need to be used, but is provided for use on platforms -* where the normal mechanism for returning character strings as -* function results from C to Fortran (as defined in the f77.h -* include file) doesn't work. -* -* If this problem is encountered, the C macro NO_CHAR_FUNCTION -* should be defined (in CFLAGS) during C compilation. This will -* cause the function ast_format_a to be built (instead of -* ast_format) and this returns its result via an additional initial -* argument. This Fortran function is then used simply to transfer -* the argument value to the function result. - -* Arguments: -* As for the C version of the Fortran-callable function ast_format. - -* Returned Value: -* AST_FORMAT = CHARACTER * ( * ) -* The character return value required. - -* Notes: -* - The length of the returned result is limited to 100 characters -* by a local buffer. This length can be increased if necessary. - -* Authors: -* RFWS: R.F. Warren-Smith (STARLINK, RAL) -* {enter_new_authors_here} - -* History: -* 23-JUL-1996 (RFWS): -* Original version. -* {enter_changes_here} - -* Bugs: -* {note_any_bugs_here} - -*- - -* Type Definitions: - IMPLICIT NONE ! No implicit typing - -* Arguments Given: - INTEGER THIS - INTEGER AXIS - DOUBLE PRECISION VALUE - -* Local Variables: - CHARACTER * ( 100 ) BUFF ! Local buffer for result -*. - -* Invoke the C function (with the additional argument). - CALL AST_FORMAT_A( BUFF, THIS, AXIS, VALUE ) - -* Return the argument value as the function result. - AST_FORMAT = BUFF - END diff --git a/ast/frame.h b/ast/frame.h deleted file mode 100644 index 91a628e..0000000 --- a/ast/frame.h +++ /dev/null @@ -1,1459 +0,0 @@ -#if !defined( FRAME_INCLUDED ) /* Include this file only once */ -#define FRAME_INCLUDED -/* -*+ -* Name: -* frame.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Frame class. - -* Invocation: -* #include "frame.h" - -* Description: -* This include file defines the interface to the Frame class and -* provides the type definitions, function prototypes and macros, etc. -* needed to use this class. -* -* A Frame object encapsulates information about a coordinate -* system, including its axes. It may also act as a "template" to -* be matched against another Frame object. This process determines -* whether it is possible to perform a coordinate transformation -* between the two coordinates systems they describe. - -* Inheritance: -* The Frame class inherits from the Mapping class. - -* Attributes Over-Ridden: -* Nin (integer, readonly) -* The Frame class sets this value to be equal to the number of -* Frame axes. -* Nout (integer, readonly) -* The Frame class sets this value to be equal to the number of -* Frame axes. - -* New Attributes Defined: -* AlignSystem (string) -* This attribute takes a value to identify the coordinate system -* in which the Frame should be aligned with other Frames. -* Digits [or Digits(axis)] (integer) -* Specifies how many digits of precision are required by -* default when a coordinate value for a Frame is formatted -* (e.g. using the astFormat method). The Digits value acts as a -* default only and is over-ridden if a Format string is -* specified for an axis explicitly. -* -* The default Digits value for a Frame is 7. This attribute -* normally applies to all the Frame's axes, but reference may -* be made to a particular axis by adding an axis subscript -* (e.g. Digits(1)). If a value is set for an individual axis, -* it will over-ride the Digits value for the Frame as a whole -* when formatting values for that axis. -* Direction(axis) (integer) -* A boolean value which specifies how coordinate values for -* each Frame axis should be displayed (e.g. in graphs). By -* default, it has the value one, indicating that they should be -* shown in the conventional sense (i.e. increasing left to -* right for an abscissa and bottom to top for an ordinate). If -* set to zero, this attribute indicates that the direction -* should be reversed (as would often be done for an -* astronomical magnitude or a right ascension axis, for -* example). -* Epoch (double) -* This value is used to qualify coordinate systems by -* giving the moment in time when the coordinates are known to -* be correct. Often, this will be the date of observation. -* Format(axis) (string) -* Specifies the format to be used to display coordinate values -* for each Frame axis (i.e. to convert them from binary to -* character form). The interpretation of this string (e.g. by -* derived classes) is left to the astFormat method which, in -* turn will invoke the astAxisFormat for the Axis object that -* describes each axis. By default, the Frame class supplies an -* Axis class object for each axis and this will interpret this -* parameter as a C "printf" format string which should be -* capable of formatting a single coordinate value stored as a -* double (e.g. "%1.7G"). If no Format string is set, the -* default format is based on the value of the Digits attribute. -* Label(axis) (string) -* Specifies the label to be attached to each Frame axis when it -* is represented in (e.g.) a graph. It is intended purely for -* interpretation by human readers and not by software. The -* default supplied by the Frame class is the string "Axis ", -* where is 1, 2, etc. for each successive axis. -* MatchEnd (integer) -* A boolean value that controls how a Frame behaves when used -* as a template to match another Frame. If it is zero and a -* template Frame matches a target frame which has a different -* number of axes, then the axes wich occur first in the target -* frame will be matched and any trailing axes in either the -* target or template will be discarded (if necessary). If it is -* non-zero, however, the last axes in each frame will be -* matched and any un-matched leading axes will be discarded -* instead. The default value supplied by the Frame class is -* zero. -* MaxAxes (integer) -* Specifies the maximum number of axes in a target Frame that -* can be matched when using the Frame as a template. Normally, -* by default, this value is equal to the number of Frame axes, -* so that a Frame will only match another Frame with the same -* number of axes as itself. By setting a different value, -* however, Frames with different numbers of axes may be matched -* (the MatchEnd attribute then determines which of the -* individual axes are matched). -* -* When setting this value, the value of the MinAxes attribute -* may be silently changed so that it remains consistent with -* (i.e. does not exceed) the new value. The default value may -* also be reduced if necessary to remain consistent with the -* MinAxes value. -* MinAxes (integer) -* Specifies the minimum number of axes in a target Frame that -* can be matched when using the Frame as a template. Normally, -* by default, this value is equal to the number of Frame axes, -* so that a Frame will only match another Frame with the same -* number of axes as itself. By setting a different value, -* however, Frames with different numbers of axes may be matched -* (the MatchEnd attribute then determines which of the -* individual axes are matched). -* -* When setting this value, the value of the MaxAxes attribute -* may be silently changed so that it remains consistent with -* (i.e. is not less than) the new value. The default value may -* also be reduced if necessary to remain consistent with the -* MaxAxes value. -* Domain (string) -* A string which may be used to identify the physical domain to -* which a Frame applies and used as an additional key when -* matching a target Frame with a template. If the Domain -* attribute in the template Frame is set, then only target -* frames with the same Domain value will be matched. If a -* Domain is not set in the template Frame, the target Frame's -* Domain value will be ignored and has no effect on -* matching. The default value supplied by the Frame class is an -* empty string. Domain values are automatically converted to -* upper case and all white space is removed before use. -* Naxes (integer) -* A read-only attribute that gives the number of axes in a -* Frame (i.e. the number of dimensions of the space which the -* Frame describes). This value is determined when the Frame is -* created. -* Permute (integer) -* A boolean value which specifies whether the axis order of a -* target Frame may be permuted in order to obtain a match with -* a template. If this value is set to zero in the template -* Frame, it will only match a target if it can do so without -* changing the order of its axes. The default value supplied by -* the Frame class is 1 (i.e. allow axis permutations). -* PreserveAxes (integer) -* A boolean value which determines how the "result" Frame is -* produced whan a target frame is matched by a template. If -* this value is zero in the template Frame, then the result -* Frame will have the same number of axes as the template. If -* it is non-zero, however, the axes of the target Frame will be -* preserved, so that the result Frame will have the same number -* of axes as the target. The default supplied by the Frame -* class is zero (i.e. target axes are not preserved). -* -* The main use for this attribute is when the MaxAxes and/or -* MinAxes attributes have been set to search for a Frame which -* may have a different number of axes from the template. For -* example, if a 2-dimensional template Frame matches a -* 3-dimensional target Frame, then by default the result is -* 2-dimensional and the last axis (normally) will be -* discarded. However, if the template's PreserveAxes value is -* non-zero, the result will instead be 3-dimensional to -* correspond with the target Frame. -* Symbol(axis) (string) -* Specifies the symbol to be used to represent coordinate -* values for each Frame axis in "short form", such as in -* algebraic expressions where a full description of the axis -* would be inappropriate. Examples include "RA" and "Dec" (for -* Right Ascension and Declination). -* -* The default supplied by the Frame class is the string -* "", where is 1, 2, etc. for successive axes, -* and is the value of the Frame's Domain attribute -* (with any white space replaced by underscores and truncated -* if necessary so that the final string does not exceed 15 -* characters). If no Domain value has been set, "x" is used as -* the value in constructing this default string. -* System (string) -* This attribute takes a value to identify the coordinate system -* used to describe positions within the domain of the Frame. -* Title (string) -* Specifies a string to be used as a title on (e.g.) graphs to -* describe the coordinate system which the Frame -* represents. Examples would be "Detector Coordinates" or -* "Galactic Coordinates". This string is intended solely for -* interpretation by human readers and not by software. The -* default supplied by the Frame class is "-D Coordinate -* System", where is the number of Frame axes. -* Unit(axis) (string) -* Describes the units used to represent coordinate values on -* each Frame axis. The default supplied by the Frame class is -* an empty string. - -* Methods Over-Ridden: -* Public: -* astGetNin -* Get the number of input coordinates for a Frame. -* astGetNout -* Get the number of output coordinates for a Frame. -* astTransform -* Use a Frame to transform a set of points. - -* Protected: -* astClearAttrib -* Clear an attribute value for a Frame. -* astGetAttrib -* Get an attribute value for a Frame. -* astReportPoints -* Report the effect of transforming a set of points using a Frame. -* astSetAttrib -* Set an attribute value for a Frame. -* astTestAttrib -* Test if an attribute value has been set for a Frame. - -* New Methods Defined: -* Public: -* astAngle -* Calculate the angle between three points. -* astAxAngle -* Find the angle from an axis to a line through two points. -* astAxDistance -* Calculate the distance between two axis values -* astAxOffset -* Calculate an offset along an axis -* astConvert -* Determine how to convert between two coordinate systems. -* astDistance -* Calculate the distance between two points. -* astFindFrame -* Find a coordinate system with specified characteristics -* astFormat -* Format a coordinate value for a Frame axis. -* astNorm -* Normalise a set of Frame coordinates. -* astOffset -* Calculate an offset along a geodesic curve. -* astOffset2 -* Calculate an offset along a geodesic curve for a 2D Frame. -* astPermAxes -* Permute the order of a Frame's axes. -* astPickAxes -* Create a new Frame by picking axes from an existing one. -* astResolve -* Resolve a vector into two orthogonal components. -* astUnformat -* Read a formatted coordinate value for a Frame axis. - -* Protected: -* astAbbrev -* Abbreviate a formatted Frame axis value by skipping -* leading fields. -* astCheckPerm -* Check that an array contains a valid permutation. -* astClearDigits -* Clear the Digits attribute for a Frame. -* astClearDirection -* Clear the Direction attribute for a Frame axis. -* astClearDomain -* Clear the Domain attribute for a Frame. -* astClearFormat -* Clear the Format attribute for a Frame axis. -* astClearLabel -* Clear the Label attribute for a Frame axis. -* astClearMatchEnd -* Clear the MatchEnd attribute for a Frame. -* astClearMaxAxes -* Clear the MaxAxes attribute for a Frame. -* astClearMinAxes -* Clear the MinAxes attribute for a Frame. -* astClearPermute -* Clear the Permute attribute for a Frame. -* astClearPreserveAxes -* Clear the PreserveAxes attribute for a Frame. -* astClearSymbol -* Clear the Symbol attribute for a Frame axis. -* astClearSystem -* Clear the value of the System attribute for a Frame. -* astClearTitle -* Clear the Title attribute for a Frame. -* astClearUnit -* Clear the Unit attribute for a Frame axis. -* astConvertX -* Determine how to convert between two coordinate systems. -* astFields -* Identify the fields within a formatted Frame axis value. -* astCentre -* Find a "nice" central value for tabulating Frame axis values. -* astGap -* Find a "nice" gap for tabulating Frame axis values. -* astGetAxis -* Obtain a pointer to a specified Axis from a Frame. -* astGetDigits -* Get the value of the Digits attribute for a Frame. -* astGetDirection -* Get the value of the Direction attribute for a Frame axis. -* astGetDomain -* Get a pointer to the Domain attribute for a Frame. -* astGetFormat -* Get a pointer to the Format attribute for a Frame axis. -* astGetLabel -* Get a pointer to the Label attribute for a Frame axis. -* astGetMatchEnd -* Get the value of the MatchEnd attribute for a Frame. -* astGetMaxAxes -* Get the value of the MaxAxes attribute for a Frame. -* astGetMinAxes -* Get the value of the MinAxes attribute for a Frame. -* astGetNaxes -* Determine how many axes a Frame has. -* astGetPerm -* Access the axis permutation array for a Frame. -* astGetPermute -* Get the value of the Permute attribute for a Frame. -* astGetPreserveAxes -* Get the value of the PreserveAxes attribute for a Frame. -* astGetSymbol -* Get a pointer to the Symbol attribute for a Frame axis. -* astGetSystem -* Get the value of the System attribute for a Frame. -* astGetTitle -* Get a pointer to the Title attribute for a Frame. -* astGetUnit -* Get a pointer to the Unit attribute for a Frame axis. -* astIsUnitFrame -* Returns a flag indicating if a Frame is equivalent to a UnitMap. -* astMatch -* Determine if conversion is possible between two coordinate systems. -* astOverlay -* Overlay the attributes of a template Frame on to another Frame. -* astPrimaryFrame -* Uniquely identify a primary Frame and one of its axes. -* astResolvePoints -* Resolve many vectors into two orthogonal components. -* astSetAxis -* Set a new Axis for a Frame. -* astSetDigits -* Set the value of the Digits attribute for a Frame. -* astSetDirection -* Set the value of the Direction attribute for a Frame axis. -* astSetDomain -* Set the value of the Domain attribute for a Frame. -* astSetFormat -* Set the value of the Format attribute for a Frame axis. -* astSetLabel -* Set the value of the Label attribute for a Frame axis. -* astSetMatchEnd -* Set the value of the MatchEnd attribute for a Frame. -* astSetMaxAxes -* Set the value of the MaxAxes attribute for a Frame. -* astSetMinAxes -* Set the value of the MinAxes attribute for a Frame. -* astSetPermute -* Set the value of the Permute attribute for a Frame. -* astSetPreserveAxes -* Set the value of the PreserveAxes attribute for a Frame. -* astSetSymbol -* Set the value of the Symbol attribute for a Frame axis. -* astSetSystem -* Set the value of the System attribute for a Frame. -* astSetTitle -* Set the value of the Title attribute for a Frame. -* astSetUnit -* Set the value of the Unit attribute for a Frame axis. -* astSubFrame -* Select axes from a Frame and convert to the new coordinate system. -* astTestDigits -* Test whether a value has been set for the Digits attribute of a -* Frame. -* astTestDirection -* Test whether a value has been set for the Direction attribute of a -* Frame axis. -* astTestDomain -* Test whether a value has been set for the Domain attribute of a -* Frame. -* astTestFormat -* Test whether a value has been set for the Format attribute of a -* Frame axis. -* astTestLabel -* Test whether a value has been set for the Label attribute of a -* Frame axis. -* astTestMatchEnd -* Test whether a value has been set for the MatchEnd attribute of a -* Frame. -* astTestMaxAxes -* Test whether a value has been set for the MaxAxes attribute of a -* Frame. -* astTestMinAxes -* Test whether a value has been set for the MinAxes attribute of a -* Frame. -* astTestPermute -* Test whether a value has been set for the Permute attribute of a -* Frame. -* astTestPreserveAxes -* Test whether a value has been set for the PreserveAxes attribute of -* a Frame. -* astTestSymbol -* Test whether a value has been set for the Symbol attribute of a -* Frame axis. -* astTestSystem -* Test whether a value has been set for the System attribute of a -* Frame. -* astTestTitle -* Test whether a value has been set for the Title attribute of a -* Frame. -* astTestUnit -* Test whether a value has been set for the Unit attribute of a Frame -* axis. -* astValidateAxis -* Validate and permute a Frame's axis index. -* astValidateAxisSelection -* Check that a set of axes selected from a Frame is valid. -* astValidateSystem -* Validate a Frame's System attribute. -* astSystemString -* Return a string representation of a System code. -* astSystemCode -* Return a code for a string representation of a System value - -* Other Class Functions: -* Public: -* astFrame -* Create a Frame. -* astIsAFrame -* Test class membership. - -* Protected: -* astCheckFrame -* Validate class membership. -* astInitFrame -* Initialise a Frame. -* astInitFrameVtab -* Initialise the virtual function table for the Frame class. -* astLoadFrame -* Load a Frame. - -* Macros: -* Public: -* None. - -* Protected: -* AST__BADSYSTEM -* A "bad" (undefined) value for the System attribute. - -* Type Definitions: -* Public: -* AstFrame -* Frame object type. - -* Protected: -* AstFrameVtab -* Frame virtual function table type. -* AstSystemType -* Enumerated type used for the System attribute. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: B.S. Berry (Starlink) - -* History: -* 1-MAR-1996 (RFWS): -* Original version. -* 25-APR-1996 (RFWS): -* Tidied up, etc. -* 11-SEP-1996 (RFWS): -* Added astGap (written by DSB). -* 10-JUN-1997 (RFWS): -* Revised astConvert and added astFindFrame. -* 15-FEB-1998 (RFWS): -* Added astUnformat. -* 21-JUN-2001 (DSB): -* Added astAngle and astOffset2. -* 29-AUG-2001 (DSB): -* Added astAxDistance and astAxOffset. -* 4-SEP-2001 (DSB): -* Added astResolve. -* 9-SEP-2001 (DSB): -* Added astBear. -* 21-SEP-2001 (DSB): -* Replace astBear with astAxAngle. -* 15-NOV-2002 (DSB): -* Moved System and Epoch attributes from SkyFrame into this class. -* Added AlignSystem attribute. -* 8-JAN-2003 (DSB): -* Added protected astInitFrameVtab method. -* 24-JAN-2004 (DSB): -* o Added astFields. -* o Added argument "fmt" to astAbbrev. -* 24-JUN-2004 (DSB): -* Remove unused entry "void (* SetMatchRange)( AstFrame *, int, int );" -* from AstFrameVtab structure. -* 9-NOV-2004 (DSB): -* Added protected astIsAUnitFrame method. -* 12-AUG-2005 (DSB): -* Added ObsLat and ObsLon attributes. -* 14-OCT-2006 (DSB): -* Added dut1 to the Frame structure. -* Added Dut1 accessor methods. -* 17-MAY-2007 (DSB): -* Added NormUnit attribute. -* 14-JAN-2009 (DSB): -* Added astIntersect method. -* 18-JUN-2009 (DSB): -* Added ObsAlt attribute. -* 17-APR-2015 (DSB): -* Added astCentre. -* 27-APR-2015 (DSB): -* Added InternalUnit attribute. -* 26-OCT-2016 (DSB): -* Added method astAxNorm. -* 11-JAN-2017 (GSB): -* Add Dtai attribute. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "axis.h" /* Coordinate Axis class */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#include - -/* Macros. */ -/* ------- */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -#if defined(astCLASS) /* Protected */ - -/* A bad value for the System attribute. */ -#define AST__BADSYSTEM -1 - -/* The legal System values recognized by this class of Frame. */ -#define AST__CART 0 - -/* Flag bitmasks for use with astSetFrameFlags. */ -# define AST__INTFLAG 1 /* FrameSet integrity is currently being restored */ - -/* Define constants used to size global arrays in this module. */ -#define AST__FRAME_LABEL_BUFF_LEN 100 /* Max length of default axis Label string */ -#define AST__FRAME_SYMBOL_BUFF_LEN 50 /* Max length of default axis Symbol string */ -#define AST__FRAME_TITLE_BUFF_LEN 100 /* Max length of default title string */ -#define AST__FRAME_GETATTRIB_BUFF_LEN 50 /* Max length of string returned by GetAttrib */ -#define AST__FRAME_ASTFMTDECIMALYR_BUFF_LEN 50 /* Max length of string returned by GetAttrib */ -#define AST__FRAME_ASTFORMATID_MAX_STRINGS 50 /* Number of string values buffer by astFormatID*/ - -#endif - -/* Type Definitions. */ -/* ================= */ -/* Integer type used to store the System attribute values. */ -typedef int AstSystemType; - -/* Frame structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstFrame { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstAxis **axis; /* Pointer to array of Axis objects */ - char *domain; /* Pointer to Domain string */ - char *title; /* Pointer to Title string */ - double epoch; /* Epoch as Modified Julian Date */ - double obslat; /* Geodetic latitude of observer */ - double obslon; /* Geodetic longitude of observer */ - double obsalt; /* Height above reference spheroid (geodetic, metres) */ - double dtai; /* TAI-UTC in seconds */ - double dut1; /* UT1-UTC in seconds */ - int *perm; /* Pointer to axis permutation array */ - int digits; /* Default digits of precision */ - int match_end; /* Match final axes of target? */ - int active_unit; /* Use Unit when aligning Frames? */ - int max_axes; /* Minimum no. axes matched */ - int min_axes; /* Max. no. axes matched */ - int naxes; /* Number of axes */ - int permute; /* Permute axes in order to match? */ - int preserve_axes; /* Preserve target axes? */ - AstSystemType system; /* Code identifying coordinate system */ - AstSystemType alignsystem; /* Code for Alignment coordinate system */ - int flags; /* Bit mask containing various protected flags */ - struct AstFrameSet *variants; /* FrameSet defining alternative properties for the Frame */ -} AstFrame; - -/* Cached Line structure. */ -/* ---------------------- */ -/* This structure contains information describing a line segment within a - 2D Frame. It is used by other classes to store intermediate cached values - relating to the line in order to speed up repeated operations on the - line. */ - -typedef struct AstLineDef { - AstFrame *frame; /* Pointer to Frame in which the line is defined */ - double length; /* Line length */ - int infinite; /* Disregard the start and end of the line? */ - double start[2]; /* Frame axis values at line start */ - double end[2]; /* Frame axis values at line end */ - double dir[2]; /* Unit vector defining line direction */ - double q[2]; /* Unit vector perpendicular to line */ -} AstLineDef; - -/* Virtual function table. */ -/* ----------------------- */ -/* The virtual function table makes a forward reference to the - AstFrameSet structure which is not defined until "frameset.h" is - included (below). Hence make a preliminary definition available - now. */ -struct AstFrameSet; - -/* This table contains all information that is the same for all objects in the - class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstFrameVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstAxis *(* GetAxis)( AstFrame *, int, int * ); - AstFrame *(* PickAxes)( AstFrame *, int, const int[], AstMapping **, int * ); - AstLineDef *(* LineDef)( AstFrame *, const double[2], const double[2], int * ); - AstPointSet *(* ResolvePoints)( AstFrame *, const double [], const double [], AstPointSet *, AstPointSet *, int * ); - const char *(* Abbrev)( AstFrame *, int, const char *, const char *, const char *, int * ); - const char *(* Format)( AstFrame *, int, double, int * ); - const char *(* GetDomain)( AstFrame *, int * ); - const char *(* GetFormat)( AstFrame *, int, int * ); - const char *(* GetLabel)( AstFrame *, int, int * ); - const char *(* GetSymbol)( AstFrame *, int, int * ); - const char *(* GetTitle)( AstFrame *, int * ); - const char *(* GetInternalUnit)( AstFrame *, int, int * ); - const char *(* GetNormUnit)( AstFrame *, int, int * ); - const char *(* GetUnit)( AstFrame *, int, int * ); - const int *(* GetPerm)( AstFrame *, int * ); - double (* Angle)( AstFrame *, const double[], const double[], const double[], int * ); - double (* Distance)( AstFrame *, const double[], const double[], int * ); - double (* Centre)( AstFrame *, int, double, double, int * ); - double (* Gap)( AstFrame *, int, double, int *, int * ); - int (* Fields)( AstFrame *, int, const char *, const char *, int, char **, int *, double *, int * ); - double (* AxDistance)( AstFrame *, int, double, double, int * ); - void (* AxNorm)( AstFrame *, int, int, int, double *, int * ); - double (* AxOffset)( AstFrame *, int, double, double, int * ); - int (* AxIn)( AstFrame *, int, double, double, double, int, int * ); - int (* GetDigits)( AstFrame *, int * ); - int (* GetDirection)( AstFrame *, int, int * ); - int (* GetMatchEnd)( AstFrame *, int * ); - int (* GetMaxAxes)( AstFrame *, int * ); - int (* GetMinAxes)( AstFrame *, int * ); - int (* GetNaxes)( AstFrame *, int * ); - int (* GetPermute)( AstFrame *, int * ); - int (* GetPreserveAxes)( AstFrame *, int * ); - int (* IsUnitFrame)( AstFrame *, int * ); - int (* LineCrossing)( AstFrame *, AstLineDef *, AstLineDef *, double **, int * ); - int (* LineContains)( AstFrame *, AstLineDef *, int, double *, int * ); - int (* Match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); - int (* SubFrame)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); - int (* TestDigits)( AstFrame *, int * ); - int (* TestDirection)( AstFrame *, int, int * ); - int (* TestDomain)( AstFrame *, int * ); - int (* TestFormat)( AstFrame *, int, int * ); - int (* TestLabel)( AstFrame *, int, int * ); - int (* TestMatchEnd)( AstFrame *, int * ); - int (* TestMaxAxes)( AstFrame *, int * ); - int (* TestMinAxes)( AstFrame *, int * ); - int (* TestPermute)( AstFrame *, int * ); - int (* TestPreserveAxes)( AstFrame *, int * ); - int (* TestSymbol)( AstFrame *, int, int * ); - int (* TestTitle)( AstFrame *, int * ); - int (* TestUnit)( AstFrame *, int, int * ); - int (* Unformat)( AstFrame *, int, const char *, double *, int * ); - int (* ValidateAxis)( AstFrame *, int, int, const char *, int * ); - AstSystemType (* ValidateSystem)( AstFrame *, AstSystemType, const char *, int * ); - AstSystemType (* SystemCode)( AstFrame *, const char *, int * ); - const char *(* SystemString)( AstFrame *, AstSystemType, int * ); - struct AstFrameSet *(* Convert)( AstFrame *, AstFrame *, const char *, int * ); - struct AstFrameSet *(* ConvertX)( AstFrame *, AstFrame *, const char *, int * ); - struct AstFrameSet *(* FindFrame)( AstFrame *, AstFrame *, const char *, int * ); - void (* MatchAxes)( AstFrame *, AstFrame *, int[], int * ); - void (* MatchAxesX)( AstFrame *, AstFrame *, int[], int * ); - void (* CheckPerm)( AstFrame *, const int *, const char *, int * ); - void (* ClearDigits)( AstFrame *, int * ); - void (* ClearDirection)( AstFrame *, int, int * ); - void (* ClearDomain)( AstFrame *, int * ); - void (* ClearFormat)( AstFrame *, int, int * ); - void (* ClearLabel)( AstFrame *, int, int * ); - void (* ClearMatchEnd)( AstFrame *, int * ); - void (* ClearMaxAxes)( AstFrame *, int * ); - void (* ClearMinAxes)( AstFrame *, int * ); - void (* ClearPermute)( AstFrame *, int * ); - void (* ClearPreserveAxes)( AstFrame *, int * ); - void (* ClearSymbol)( AstFrame *, int, int * ); - void (* ClearTitle)( AstFrame *, int * ); - void (* ClearUnit)( AstFrame *, int, int * ); - void (* Intersect)( AstFrame *, const double[2], const double[2], const double[2], const double[2], double[2], int * ); - void (* Norm)( AstFrame *, double[], int * ); - void (* NormBox)( AstFrame *, double *, double *, AstMapping *, int * ); - void (* Offset)( AstFrame *, const double[], const double[], double, double[], int * ); - double (* AxAngle)( AstFrame *, const double[2], const double[2], int, int * ); - double (* Offset2)( AstFrame *, const double[2], double, double, double[2], int * ); - void (* Overlay)( AstFrame *, const int *, AstFrame *, int * ); - void (* PermAxes)( AstFrame *, const int[], int * ); - void (* PrimaryFrame)( AstFrame *, int, AstFrame **, int *, int * ); - void (* Resolve)( AstFrame *, const double [], const double [], const double [], double [], double *, double *, int * ); - void (* SetAxis)( AstFrame *, int, AstAxis *, int * ); - void (* SetDigits)( AstFrame *, int, int * ); - void (* SetDirection)( AstFrame *, int, int, int * ); - void (* SetDomain)( AstFrame *, const char *, int * ); - void (* SetFormat)( AstFrame *, int, const char *, int * ); - void (* SetLabel)( AstFrame *, int, const char *, int * ); - void (* SetMatchEnd)( AstFrame *, int, int * ); - void (* SetMaxAxes)( AstFrame *, int, int * ); - void (* SetMinAxes)( AstFrame *, int, int * ); - void (* SetPermute)( AstFrame *, int, int * ); - void (* SetPreserveAxes)( AstFrame *, int, int * ); - void (* SetSymbol)( AstFrame *, int, const char *, int * ); - void (* SetTitle)( AstFrame *, const char *, int * ); - void (* SetUnit)( AstFrame *, int, const char *, int * ); - void (* ValidateAxisSelection)( AstFrame *, int, const int *, const char *, int * ); - void (* LineOffset)( AstFrame *, AstLineDef *, double, double, double[2], int * ); - AstPointSet *(* FrameGrid)( AstFrame *, int, const double *, const double *, int * ); - struct AstFrameSet *(* GetFrameVariants)( AstFrame *, int * ); - void (* SetFrameVariants)( AstFrame *, struct AstFrameSet *, int * ); - - double (* GetTop)( AstFrame *, int, int * ); - int (* TestTop)( AstFrame *, int, int * ); - void (* ClearTop)( AstFrame *, int, int * ); - void (* SetTop)( AstFrame *, int, double, int * ); - - double (* GetBottom)( AstFrame *, int, int * ); - int (* TestBottom)( AstFrame *, int, int * ); - void (* ClearBottom)( AstFrame *, int, int * ); - void (* SetBottom)( AstFrame *, int, double, int * ); - - AstSystemType (* GetSystem)( AstFrame *, int * ); - int (* TestSystem)( AstFrame *, int * ); - void (* ClearSystem)( AstFrame *, int * ); - void (* SetSystem)( AstFrame *, AstSystemType, int * ); - - AstSystemType (* GetAlignSystem)( AstFrame *, int * ); - int (* TestAlignSystem)( AstFrame *, int * ); - void (* ClearAlignSystem)( AstFrame *, int * ); - void (* SetAlignSystem)( AstFrame *, AstSystemType, int * ); - - double (* GetEpoch)( AstFrame *, int * ); - int (* TestEpoch)( AstFrame *, int * ); - void (* ClearEpoch)( AstFrame *, int * ); - void (* SetEpoch)( AstFrame *, double, int * ); - - int (* TestActiveUnit)( AstFrame *, int * ); - int (* GetActiveUnit)( AstFrame *, int * ); - void (* SetActiveUnit)( AstFrame *, int, int * ); - - double (* GetObsLon)( AstFrame *, int * ); - int (* TestObsLon)( AstFrame *, int * ); - void (* ClearObsLon)( AstFrame *, int * ); - void (* SetObsLon)( AstFrame *, double, int * ); - - double (* GetObsLat)( AstFrame *, int * ); - int (* TestObsLat)( AstFrame *, int * ); - void (* ClearObsLat)( AstFrame *, int * ); - void (* SetObsLat)( AstFrame *, double, int * ); - - double (* GetObsAlt)( AstFrame *, int * ); - int (* TestObsAlt)( AstFrame *, int * ); - void (* ClearObsAlt)( AstFrame *, int * ); - void (* SetObsAlt)( AstFrame *, double, int * ); - - double (* GetDtai)( AstFrame *, int * ); - int (* TestDtai)( AstFrame *, int * ); - void (* ClearDtai)( AstFrame *, int * ); - void (* SetDtai)( AstFrame *, double, int * ); - - double (* GetDut1)( AstFrame *, int * ); - int (* TestDut1)( AstFrame *, int * ); - void (* ClearDut1)( AstFrame *, int * ); - void (* SetDut1)( AstFrame *, double, int * ); - - void (* SetFrameFlags)( AstFrame *, int, int * ); - int (* GetFrameFlags)( AstFrame *, int * ); - -} AstFrameVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstFrameGlobals { - AstFrameVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ AST__FRAME_GETATTRIB_BUFF_LEN + 1 ]; - char *AstFormatID_Strings[ AST__FRAME_ASTFORMATID_MAX_STRINGS ]; - int AstFormatID_Istr; - int AstFormatID_Init; - char Label_Buff[ AST__FRAME_LABEL_BUFF_LEN + 1 ]; - char Symbol_Buff[ AST__FRAME_SYMBOL_BUFF_LEN + 1 ]; - char Title_Buff[ AST__FRAME_TITLE_BUFF_LEN + 1 ]; - char AstFmtDecimalYr_Buff[ AST__FRAME_ASTFMTDECIMALYR_BUFF_LEN + 1 ]; -} AstFrameGlobals; - -#endif -#endif - -/* More include files. */ -/* =================== */ -/* The interface to the FrameSet class must be included here (after - the type definitions for the Frame class) because "frameset.h" - itself includes this file ("frame.h"), although "frameset.h" refers - to the AstFrameSet structure above. This seems a little strange at - first, but is simply analogous to making a forward reference to a - structure type when recursively defining a normal C structure - (except that here the definitions happen to be in separate include - files). */ -#include "frameset.h" - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Frame) /* Check class membership */ -astPROTO_ISA(Frame) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -AstFrame *astFrame_( int, const char *, int *, ...); -#else -AstFrame *astFrameId_( int, const char *, ... )__attribute__((format(printf,2,3))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstFrame *astInitFrame_( void *, size_t, int, AstFrameVtab *, const char *, - int, int * ); - -/* Vtab initialiser. */ -void astInitFrameVtab_( AstFrameVtab *, const char *, int * ); - -/* Loader. */ -AstFrame *astLoadFrame_( void *, size_t, AstFrameVtab *, - const char *, AstChannel *channel, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitFrameGlobals_( AstFrameGlobals * ); -#endif -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -AstFrameSet *astConvert_( AstFrame *, AstFrame *, const char *, int * ); -AstFrameSet *astFindFrame_( AstFrame *, AstFrame *, const char *, int * ); -double astAngle_( AstFrame *, const double[], const double[], const double[], int * ); -double astAxAngle_( AstFrame *, const double[2], const double[2], int, int * ); -double astAxDistance_( AstFrame *, int, double, double, int * ); -double astAxOffset_( AstFrame *, int, double, double, int * ); -double astDistance_( AstFrame *, const double[], const double[], int * ); -double astOffset2_( AstFrame *, const double[2], double, double, double[2], int * ); -int astGetActiveUnit_( AstFrame *, int * ); -void astAxNorm_( AstFrame *, int, int, int, double *, int * ); -void astIntersect_( AstFrame *, const double[2], const double[2], const double[2], const double[2], double[2], int * ); -void astMatchAxes_( AstFrame *, AstFrame *, int[], int * ); -void astNorm_( AstFrame *, double[], int * ); -void astOffset_( AstFrame *, const double[], const double[], double, double[], int * ); -void astResolve_( AstFrame *, const double [], const double [], const double [], double [], double *, double *, int * ); -void astSetActiveUnit_( AstFrame *, int, int * ); -AstFrameSet *astGetFrameVariants_( AstFrame *, int * ); -void astSetFrameVariants_( AstFrame *, AstFrameSet *, int * ); - -#if defined(astCLASS) /* Protected */ -void astNormBox_( AstFrame *, double *, double *, AstMapping *, int * ); -AstFrame *astPickAxes_( AstFrame *, int, const int[], AstMapping **, int * ); -const char *astFormat_( AstFrame *, int, double, int * ); -int astUnformat_( AstFrame *, int, const char *, double *, int * ); -void astPermAxes_( AstFrame *, const int[], int * ); -#else -AstFrame *astPickAxesId_( AstFrame *, int, const int[], AstMapping **, int * ); -const char *astFormatId_( AstFrame *, int, double, int * ); -int astUnformatId_( AstFrame *, int, const char *, double *, int * ); -void astPermAxesId_( AstFrame *, const int[], int * ); -#endif - -#if defined(astCLASS) /* Protected */ -int astAxIn_( AstFrame *, int, double, double, double, int, int * ); -AstAxis * astGetAxis_( AstFrame *, int, int * ); -AstFrameSet *astConvertX_( AstFrame *, AstFrame *, const char *, int * ); -void astMatchAxesX_( AstFrame *, AstFrame *, int[], int * ); -AstLineDef *astLineDef_( AstFrame *, const double[2], const double[2], int * ); -AstPointSet *astResolvePoints_( AstFrame *, const double [], const double [], AstPointSet *, AstPointSet *, int * ); -const char *astAbbrev_( AstFrame *, int, const char *, const char *, const char *, int * ); -const char *astGetDomain_( AstFrame *, int * ); -const char *astGetFormat_( AstFrame *, int, int * ); -const char *astGetLabel_( AstFrame *, int, int * ); -const char *astGetSymbol_( AstFrame *, int, int * ); -const char *astGetTitle_( AstFrame *, int * ); -const char *astGetUnit_( AstFrame *, int, int * ); -const char *astGetInternalUnit_( AstFrame *, int, int * ); -const char *astGetNormUnit_( AstFrame *, int, int * ); -const int *astGetPerm_( AstFrame *, int * ); -double astCentre_( AstFrame *, int, double, double, int * ); -double astGap_( AstFrame *, int, double, int *, int * ); -int astFields_( AstFrame *, int, const char *, const char *, int, char **, int *, double *, int * ); -int astGetDigits_( AstFrame *, int * ); -int astGetDirection_( AstFrame *, int, int * ); -int astGetMatchEnd_( AstFrame *, int * ); -int astGetMaxAxes_( AstFrame *, int * ); -int astGetMinAxes_( AstFrame *, int * ); -int astGetNaxes_( AstFrame *, int * ); -int astGetPermute_( AstFrame *, int * ); -int astGetPreserveAxes_( AstFrame *, int * ); -int astIsUnitFrame_( AstFrame *, int * ); -int astLineCrossing_( AstFrame *, AstLineDef *, AstLineDef *, double **, int * ); -int astLineContains_( AstFrame *, AstLineDef *, int, double *, int * ); -int astMatch_( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -int astSubFrame_( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -int astTestDigits_( AstFrame *, int * ); -int astTestDirection_( AstFrame *, int, int * ); -int astTestDomain_( AstFrame *, int * ); -int astTestFormat_( AstFrame *, int, int * ); -int astTestLabel_( AstFrame *, int, int * ); -int astTestMatchEnd_( AstFrame *, int * ); -int astTestMaxAxes_( AstFrame *, int * ); -int astTestMinAxes_( AstFrame *, int * ); -int astTestPermute_( AstFrame *, int * ); -int astTestPreserveAxes_( AstFrame *, int * ); -int astTestSymbol_( AstFrame *, int, int * ); -int astTestTitle_( AstFrame *, int * ); -int astTestUnit_( AstFrame *, int, int * ); -int astValidateAxis_( AstFrame *, int, int, const char *, int * ); -AstSystemType astValidateSystem_( AstFrame *, AstSystemType, const char *, int * ); -AstSystemType astSystemCode_( AstFrame *, const char *, int * ); -const char *astSystemString_( AstFrame *, AstSystemType, int * ); -void astCheckPerm_( AstFrame *, const int *, const char *, int * ); -void astClearDigits_( AstFrame *, int * ); -void astClearDirection_( AstFrame *, int, int * ); -void astClearDomain_( AstFrame *, int * ); -void astClearFormat_( AstFrame *, int, int * ); -void astClearLabel_( AstFrame *, int, int * ); -void astClearMatchEnd_( AstFrame *, int * ); -void astClearMaxAxes_( AstFrame *, int * ); -void astClearMinAxes_( AstFrame *, int * ); -void astClearPermute_( AstFrame *, int * ); -void astClearPreserveAxes_( AstFrame *, int * ); -void astClearSymbol_( AstFrame *, int, int * ); -void astClearTitle_( AstFrame *, int * ); -void astClearUnit_( AstFrame *, int, int * ); -void astOverlay_( AstFrame *, const int *, AstFrame *, int * ); -void astPrimaryFrame_( AstFrame *, int, AstFrame **, int *, int * ); -void astSetAxis_( AstFrame *, int, AstAxis *, int * ); -void astSetDigits_( AstFrame *, int, int * ); -void astSetDirection_( AstFrame *, int, int, int * ); -void astSetDomain_( AstFrame *, const char *, int * ); -void astSetFormat_( AstFrame *, int, const char *, int * ); -void astSetLabel_( AstFrame *, int, const char *, int * ); -void astSetMatchEnd_( AstFrame *, int, int * ); -void astSetMaxAxes_( AstFrame *, int, int * ); -void astSetMinAxes_( AstFrame *, int, int * ); -void astSetPermute_( AstFrame *, int, int * ); -void astSetPreserveAxes_( AstFrame *, int, int * ); -void astSetSymbol_( AstFrame *, int, const char *, int * ); -void astSetTitle_( AstFrame *, const char *, int * ); -void astSetUnit_( AstFrame *, int, const char *, int * ); -void astValidateAxisSelection_( AstFrame *, int, const int *, const char *, int * ); -double astReadDateTime_( const char *, int * ); -const char *astFmtDecimalYr_( double, int, int * ); -void astLineOffset_( AstFrame *, AstLineDef *, double, double, double[2], int * ); -AstPointSet *astFrameGrid_( AstFrame *, int, const double *, const double *, int * ); - -double astGetTop_( AstFrame *, int, int * ); -int astTestTop_( AstFrame *, int, int * ); -void astClearTop_( AstFrame *, int, int * ); -void astSetTop_( AstFrame *, int, double, int * ); - -double astGetBottom_( AstFrame *, int, int * ); -int astTestBottom_( AstFrame *, int, int * ); -void astClearBottom_( AstFrame *, int, int * ); -void astSetBottom_( AstFrame *, int, double, int * ); - -AstSystemType astGetSystem_( AstFrame *, int * ); -int astTestSystem_( AstFrame *, int * ); -void astClearSystem_( AstFrame *, int * ); -void astSetSystem_( AstFrame *, AstSystemType, int * ); - -AstSystemType astGetAlignSystem_( AstFrame *, int * ); -int astTestAlignSystem_( AstFrame *, int * ); -void astClearAlignSystem_( AstFrame *, int * ); -void astSetAlignSystem_( AstFrame *, AstSystemType, int * ); - -double astGetEpoch_( AstFrame *, int * ); -int astTestEpoch_( AstFrame *, int * ); -void astClearEpoch_( AstFrame *, int * ); -void astSetEpoch_( AstFrame *, double, int * ); - -double astGetObsLon_( AstFrame *, int * ); -int astTestObsLon_( AstFrame *, int * ); -void astClearObsLon_( AstFrame *, int * ); -void astSetObsLon_( AstFrame *, double, int * ); - -double astGetObsLat_( AstFrame *, int * ); -int astTestObsLat_( AstFrame *, int * ); -void astClearObsLat_( AstFrame *, int * ); -void astSetObsLat_( AstFrame *, double, int * ); - -double astGetObsAlt_( AstFrame *, int * ); -int astTestObsAlt_( AstFrame *, int * ); -void astClearObsAlt_( AstFrame *, int * ); -void astSetObsAlt_( AstFrame *, double, int * ); - -double astGetDtai_( AstFrame *, int * ); -int astTestDtai_( AstFrame *, int * ); -void astClearDtai_( AstFrame *, int * ); -void astSetDtai_( AstFrame *, double, int * ); - -double astGetDut1_( AstFrame *, int * ); -int astTestDut1_( AstFrame *, int * ); -void astClearDut1_( AstFrame *, int * ); -void astSetDut1_( AstFrame *, double, int * ); - -int astTestActiveUnit_( AstFrame *, int * ); - -void astSetFrameFlags_( AstFrame *, int, int * ); -int astGetFrameFlags_( AstFrame *, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class to make - them easier to invoke (e.g. to avoid type mis-matches when passing pointers - to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them to - validate their own arguments. We must use a cast when passing object - pointers (so that they can accept objects from derived classes). */ - -/* Check class membership. */ -#define astCheckFrame(this) astINVOKE_CHECK(Frame,this,0) -#define astVerifyFrame(this) astINVOKE_CHECK(Frame,this,1) - -/* Test class membership. */ -#define astIsAFrame(this) astINVOKE_ISA(Frame,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -#define astFrame astINVOKE(F,astFrame_) -#else -#define astFrame astINVOKE(F,astFrameId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitFrame(mem,size,init,vtab,name,naxes) \ -astINVOKE(O,astInitFrame_(mem,size,init,vtab,name,naxes,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitFrameVtab(vtab,name) astINVOKE(V,astInitFrameVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadFrame(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadFrame_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckFrame to validate Frame pointers before - use. This provides a contextual error report if a pointer to the - wrong sort of Object is supplied. */ -#define astConvert(from,to,domainlist) \ -astINVOKE(O,astConvert_(astCheckFrame(from),astCheckFrame(to),domainlist,STATUS_PTR)) -#define astAngle(this,a,b,c) \ -astINVOKE(V,astAngle_(astCheckFrame(this),a,b,c,STATUS_PTR)) -#define astDistance(this,point1,point2) \ -astINVOKE(V,astDistance_(astCheckFrame(this),point1,point2,STATUS_PTR)) -#define astFindFrame(target,template,domainlist) \ -astINVOKE(O,astFindFrame_(astCheckFrame(target),astCheckFrame(template),domainlist,STATUS_PTR)) -#define astMatchAxes(frm1,frm2,axes) \ -astINVOKE(V,astMatchAxes_(astCheckFrame(frm1),astCheckFrame(frm2),axes,STATUS_PTR)) -#define astNorm(this,value) \ -astINVOKE(V,astNorm_(astCheckFrame(this),value,STATUS_PTR)) -#define astAxDistance(this,axis,v1,v2) \ -astINVOKE(V,astAxDistance_(astCheckFrame(this),axis,v1,v2,STATUS_PTR)) -#define astAxNorm(this,axis,oper,nval,values) \ -astINVOKE(V,astAxNorm_(astCheckFrame(this),axis,oper,nval,values,STATUS_PTR)) -#define astAxOffset(this,axis,v1,dist) \ -astINVOKE(V,astAxOffset_(astCheckFrame(this),axis,v1,dist,STATUS_PTR)) -#define astOffset(this,point1,point2,offset,point3) \ -astINVOKE(V,astOffset_(astCheckFrame(this),point1,point2,offset,point3,STATUS_PTR)) -#define astAxAngle(this,a,b,axis) \ -astINVOKE(V,astAxAngle_(astCheckFrame(this),a,b,axis,STATUS_PTR)) -#define astIntersect(this,a1,a2,b1,b2,cross) \ -astINVOKE(V,astIntersect_(astCheckFrame(this),a1,a2,b1,b2,cross,STATUS_PTR)) -#define astOffset2(this,point1,angle,offset,point2) \ -astINVOKE(V,astOffset2_(astCheckFrame(this),point1,angle,offset,point2,STATUS_PTR)) -#define astResolve(this,point1,point2,point3,point4,d1,d2) \ -astINVOKE(V,astResolve_(astCheckFrame(this),point1,point2,point3,point4,d1,d2,STATUS_PTR)) -#define astGetActiveUnit(this) \ -astINVOKE(V,astGetActiveUnit_(astCheckFrame(this),STATUS_PTR)) -#define astSetActiveUnit(this,value) \ -astINVOKE(V,astSetActiveUnit_(astCheckFrame(this),value,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astGetFrameVariants(this) \ -astINVOKE(O,astGetFrameVariants_(astCheckFrame(this),STATUS_PTR)) -#define astSetFrameVariants(this,variants) \ -astINVOKE(V,astSetFrameVariants_(astCheckFrame(this),astCheckFrameSet(variants),STATUS_PTR)) -#define astNormBox(this,lbnd,ubnd,reg) \ -astINVOKE(V,astNormBox_(astCheckFrame(this),lbnd,ubnd,astCheckMapping(reg),STATUS_PTR)) -#define astFormat(this,axis,value) \ -astINVOKE(V,astFormat_(astCheckFrame(this),axis,value,STATUS_PTR)) -#define astPermAxes(this,perm) \ -astINVOKE(V,astPermAxes_(astCheckFrame(this),perm,STATUS_PTR)) -#define astPickAxes(this,naxes,axes,map) \ -astINVOKE(O,astPickAxes_(astCheckFrame(this),naxes,axes,(AstMapping **)(map),STATUS_PTR)) -#define astUnformat(this,axis,string,value) \ -astINVOKE(V,astUnformat_(astCheckFrame(this),axis,string,value,STATUS_PTR)) -#else -#define astFormat(this,axis,value) \ -astINVOKE(V,astFormatId_(astCheckFrame(this),axis,value,STATUS_PTR)) -#define astPermAxes(this,perm) \ -astINVOKE(V,astPermAxesId_(astCheckFrame(this),perm,STATUS_PTR)) -#define astPickAxes(this,naxes,axes,map) \ -astINVOKE(O,astPickAxesId_(astCheckFrame(this),naxes,axes,(AstMapping **)(map),STATUS_PTR)) -#define astUnformat(this,axis,string,value) \ -astINVOKE(V,astUnformatId_(astCheckFrame(this),axis,string,value,STATUS_PTR)) -#endif - -#if defined(astCLASS) /* Protected */ -#define astAxIn(this,axis,lo,hi,val,closed) \ -astINVOKE(V,astAxIn_(astCheckFrame(this),axis,lo,hi,val,closed,STATUS_PTR)) -#define astAbbrev(this,axis,fmt,str1,str2) \ -astINVOKE(V,astAbbrev_(astCheckFrame(this),axis,fmt,str1,str2,STATUS_PTR)) -#define astFields(this,axis,fmt,str,maxfld,fields,nc,val) \ -astINVOKE(V,astFields_(astCheckFrame(this),axis,fmt,str,maxfld,fields,nc,val,STATUS_PTR)) -#define astCheckPerm(this,perm,method) \ -astINVOKE(V,astCheckPerm_(astCheckFrame(this),perm,method,STATUS_PTR)) -#define astResolvePoints(this,p1,p2,in,out) \ -astINVOKE(O,astResolvePoints_(astCheckFrame(this),p1,p2,astCheckPointSet(in),((out)?astCheckPointSet(out):NULL),STATUS_PTR)) -#define astLineDef(this,p1,p2) \ -astINVOKE(V,astLineDef_(astCheckFrame(this),p1,p2,STATUS_PTR)) -#define astLineOffset(this,line,par,prp,point) \ -astINVOKE(V,astLineOffset_(astCheckFrame(this),line,par,prp,point,STATUS_PTR)) -#define astFrameGrid(this,size,lbnd,ubnd) \ -astINVOKE(O,astFrameGrid_(astCheckFrame(this),size,lbnd,ubnd,STATUS_PTR)) -#define astLineCrossing(this,l1,l2,cross) \ -astINVOKE(V,astLineCrossing_(astCheckFrame(this),l1,l2,cross,STATUS_PTR)) -#define astLineContains(this,l,def,point) \ -astINVOKE(V,astLineContains_(astCheckFrame(this),l,def,point,STATUS_PTR)) -#define astClearDigits(this) \ -astINVOKE(V,astClearDigits_(astCheckFrame(this),STATUS_PTR)) -#define astClearDirection(this,axis) \ -astINVOKE(V,astClearDirection_(astCheckFrame(this),axis,STATUS_PTR)) -#define astClearDomain(this) \ -astINVOKE(V,astClearDomain_(astCheckFrame(this),STATUS_PTR)) -#define astClearFormat(this,axis) \ -astINVOKE(V,astClearFormat_(astCheckFrame(this),axis,STATUS_PTR)) -#define astClearLabel(this,axis) \ -astINVOKE(V,astClearLabel_(astCheckFrame(this),axis,STATUS_PTR)) -#define astClearMatchEnd(this) \ -astINVOKE(V,astClearMatchEnd_(astCheckFrame(this),STATUS_PTR)) -#define astClearMaxAxes(this) \ -astINVOKE(V,astClearMaxAxes_(astCheckFrame(this),STATUS_PTR)) -#define astClearMinAxes(this) \ -astINVOKE(V,astClearMinAxes_(astCheckFrame(this),STATUS_PTR)) -#define astClearPermute(this) \ -astINVOKE(V,astClearPermute_(astCheckFrame(this),STATUS_PTR)) -#define astClearPreserveAxes(this) \ -astINVOKE(V,astClearPreserveAxes_(astCheckFrame(this),STATUS_PTR)) -#define astClearSymbol(this,axis) \ -astINVOKE(V,astClearSymbol_(astCheckFrame(this),axis,STATUS_PTR)) -#define astClearTitle(this) \ -astINVOKE(V,astClearTitle_(astCheckFrame(this),STATUS_PTR)) -#define astClearUnit(this,axis) \ -astINVOKE(V,astClearUnit_(astCheckFrame(this),axis,STATUS_PTR)) -#define astConvertX(to,from,domainlist) \ -astINVOKE(O,astConvertX_(astCheckFrame(to),astCheckFrame(from),domainlist,STATUS_PTR)) -#define astCentre(this,axis,value,gap) \ -astINVOKE(V,astCentre_(astCheckFrame(this),axis,value,gap,STATUS_PTR)) -#define astGap(this,axis,gap,ntick) \ -astINVOKE(V,astGap_(astCheckFrame(this),axis,gap,ntick,STATUS_PTR)) -#define astGetAxis(this,axis) \ -astINVOKE(O,astGetAxis_(astCheckFrame(this),axis,STATUS_PTR)) -#define astGetDigits(this) \ -astINVOKE(V,astGetDigits_(astCheckFrame(this),STATUS_PTR)) -#define astGetDirection(this,axis) \ -astINVOKE(V,astGetDirection_(astCheckFrame(this),axis,STATUS_PTR)) -#define astGetDomain(this) \ -astINVOKE(V,astGetDomain_(astCheckFrame(this),STATUS_PTR)) -#define astGetFormat(this,axis) \ -astINVOKE(V,astGetFormat_(astCheckFrame(this),axis,STATUS_PTR)) -#define astGetLabel(this,axis) \ -astINVOKE(V,astGetLabel_(astCheckFrame(this),axis,STATUS_PTR)) -#define astGetMatchEnd(this) \ -astINVOKE(V,astGetMatchEnd_(astCheckFrame(this),STATUS_PTR)) -#define astGetMaxAxes(this) \ -astINVOKE(V,astGetMaxAxes_(astCheckFrame(this),STATUS_PTR)) -#define astGetMinAxes(this) \ -astINVOKE(V,astGetMinAxes_(astCheckFrame(this),STATUS_PTR)) -#define astGetNaxes(this) \ -astINVOKE(V,astGetNaxes_(astCheckFrame(this),STATUS_PTR)) -#define astGetPerm(this) \ -astINVOKE(V,astGetPerm_(astCheckFrame(this),STATUS_PTR)) -#define astGetPermute(this) \ -astINVOKE(V,astGetPermute_(astCheckFrame(this),STATUS_PTR)) -#define astGetPreserveAxes(this) \ -astINVOKE(V,astGetPreserveAxes_(astCheckFrame(this),STATUS_PTR)) -#define astGetSymbol(this,axis) \ -astINVOKE(V,astGetSymbol_(astCheckFrame(this),axis,STATUS_PTR)) -#define astGetTitle(this) \ -astINVOKE(V,astGetTitle_(astCheckFrame(this),STATUS_PTR)) -#define astGetUnit(this,axis) \ -astINVOKE(V,astGetUnit_(astCheckFrame(this),axis,STATUS_PTR)) -#define astGetNormUnit(this,axis) \ -astINVOKE(V,astGetNormUnit_(astCheckFrame(this),axis,STATUS_PTR)) -#define astGetInternalUnit(this,axis) \ -astINVOKE(V,astGetInternalUnit_(astCheckFrame(this),axis,STATUS_PTR)) -#define astMatch(template,target,matchsub,template_axes,target_axes,map,result) \ -astINVOKE(V,astMatch_(astCheckFrame(template),astCheckFrame(target),matchsub,template_axes,target_axes,(AstMapping **)(map),(AstFrame **)(result),STATUS_PTR)) -#define astIsUnitFrame(this) \ -astINVOKE(V,astIsUnitFrame_(astCheckFrame(this),STATUS_PTR)) -#define astOverlay(template,template_axes,result) \ -astINVOKE(V,astOverlay_(astCheckFrame(template),template_axes,astCheckFrame(result),STATUS_PTR)) -#define astPrimaryFrame(this,axis1,frame,axis2) \ -astINVOKE(V,astPrimaryFrame_(astCheckFrame(this),axis1,(AstFrame **)(frame),axis2,STATUS_PTR)) -#define astSetAxis(this,axis,newaxis) \ -astINVOKE(V,astSetAxis_(astCheckFrame(this),axis,astCheckAxis(newaxis),STATUS_PTR)) -#define astSetDigits(this,digits) \ -astINVOKE(V,astSetDigits_(astCheckFrame(this),digits,STATUS_PTR)) -#define astSetDirection(this,axis,direction) \ -astINVOKE(V,astSetDirection_(astCheckFrame(this),axis,direction,STATUS_PTR)) -#define astSetDomain(this,domain) \ -astINVOKE(V,astSetDomain_(astCheckFrame(this),domain,STATUS_PTR)) -#define astSetFormat(this,axis,format) \ -astINVOKE(V,astSetFormat_(astCheckFrame(this),axis,format,STATUS_PTR)) -#define astSetLabel(this,axis,label) \ -astINVOKE(V,astSetLabel_(astCheckFrame(this),axis,label,STATUS_PTR)) -#define astSetMatchEnd(this,value) \ -astINVOKE(V,astSetMatchEnd_(astCheckFrame(this),value,STATUS_PTR)) -#define astSetMaxAxes(this,value) \ -astINVOKE(V,astSetMaxAxes_(astCheckFrame(this),value,STATUS_PTR)) -#define astSetMinAxes(this,value) \ -astINVOKE(V,astSetMinAxes_(astCheckFrame(this),value,STATUS_PTR)) -#define astSetPermute(this,value) \ -astINVOKE(V,astSetPermute_(astCheckFrame(this),value,STATUS_PTR)) -#define astSetPreserveAxes(this,value) \ -astINVOKE(V,astSetPreserveAxes_(astCheckFrame(this),value,STATUS_PTR)) -#define astSetSymbol(this,axis,symbol) \ -astINVOKE(V,astSetSymbol_(astCheckFrame(this),axis,symbol,STATUS_PTR)) -#define astSetTitle(this,title) \ -astINVOKE(V,astSetTitle_(astCheckFrame(this),title,STATUS_PTR)) -#define astSetUnit(this,axis,unit) \ -astINVOKE(V,astSetUnit_(astCheckFrame(this),axis,unit,STATUS_PTR)) -#define astSubFrame(target,template,result_naxes,target_axes,template_axes,map,result) \ -astINVOKE(V,astSubFrame_(astCheckFrame(target),template?astCheckFrame(template):NULL,result_naxes,target_axes,template_axes,(AstMapping **)(map),(AstFrame **)(result),STATUS_PTR)) -#define astTestDigits(this) \ -astINVOKE(V,astTestDigits_(astCheckFrame(this),STATUS_PTR)) -#define astTestDirection(this,axis) \ -astINVOKE(V,astTestDirection_(astCheckFrame(this),axis,STATUS_PTR)) -#define astTestDomain(this) \ -astINVOKE(V,astTestDomain_(astCheckFrame(this),STATUS_PTR)) -#define astTestFormat(this,axis) \ -astINVOKE(V,astTestFormat_(astCheckFrame(this),axis,STATUS_PTR)) -#define astTestLabel(this,axis) \ -astINVOKE(V,astTestLabel_(astCheckFrame(this),axis,STATUS_PTR)) -#define astTestMatchEnd(this) \ -astINVOKE(V,astTestMatchEnd_(astCheckFrame(this),STATUS_PTR)) -#define astTestMaxAxes(this) \ -astINVOKE(V,astTestMaxAxes_(astCheckFrame(this),STATUS_PTR)) -#define astTestMinAxes(this) \ -astINVOKE(V,astTestMinAxes_(astCheckFrame(this),STATUS_PTR)) -#define astTestPermute(this) \ -astINVOKE(V,astTestPermute_(astCheckFrame(this),STATUS_PTR)) -#define astTestPreserveAxes(this) \ -astINVOKE(V,astTestPreserveAxes_(astCheckFrame(this),STATUS_PTR)) -#define astTestSymbol(this,axis) \ -astINVOKE(V,astTestSymbol_(astCheckFrame(this),axis,STATUS_PTR)) -#define astTestTitle(this) \ -astINVOKE(V,astTestTitle_(astCheckFrame(this),STATUS_PTR)) -#define astTestUnit(this,axis) \ -astINVOKE(V,astTestUnit_(astCheckFrame(this),axis,STATUS_PTR)) -#define astValidateAxis(this,axis,fwd,method) \ -astINVOKE(V,astValidateAxis_(astCheckFrame(this),axis,fwd,method,STATUS_PTR)) -#define astValidateAxisSelection(this,naxes,axes,method) \ -astINVOKE(V,astValidateAxisSelection_(astCheckFrame(this),naxes,axes,method,STATUS_PTR)) - -#define astMatchAxesX(frm2,frm1,axes) \ -astINVOKE(V,astMatchAxesX_(astCheckFrame(frm2),astCheckFrame(frm1),axes,STATUS_PTR)) - -#define astFmtDecimalYr(year,digits) astFmtDecimalYr_(year,digits,STATUS_PTR) -#define astReadDateTime(value) astReadDateTime_(value,STATUS_PTR) - -#define astValidateSystem(this,system,method) \ -astINVOKE(V,astValidateSystem_(astCheckFrame(this),system,method,STATUS_PTR)) -#define astSystemString(this,system) \ -astINVOKE(V,astSystemString_(astCheckFrame(this),system,STATUS_PTR)) -#define astSystemCode(this,system) \ -astINVOKE(V,astSystemCode_(astCheckFrame(this),system,STATUS_PTR)) - -#define astClearTop(this,axis) \ -astINVOKE(V,astClearTop_(astCheckFrame(this),axis,STATUS_PTR)) -#define astGetTop(this,axis) \ -astINVOKE(V,astGetTop_(astCheckFrame(this),axis,STATUS_PTR)) -#define astSetTop(this,axis,value) \ -astINVOKE(V,astSetTop_(astCheckFrame(this),axis,value,STATUS_PTR)) -#define astTestTop(this,axis) \ -astINVOKE(V,astTestTop_(astCheckFrame(this),axis,STATUS_PTR)) - -#define astClearBottom(this,axis) \ -astINVOKE(V,astClearBottom_(astCheckFrame(this),axis,STATUS_PTR)) -#define astGetBottom(this,axis) \ -astINVOKE(V,astGetBottom_(astCheckFrame(this),axis,STATUS_PTR)) -#define astSetBottom(this,axis,value) \ -astINVOKE(V,astSetBottom_(astCheckFrame(this),axis,value,STATUS_PTR)) -#define astTestBottom(this,axis) \ -astINVOKE(V,astTestBottom_(astCheckFrame(this),axis,STATUS_PTR)) - -#define astClearSystem(this) \ -astINVOKE(V,astClearSystem_(astCheckFrame(this),STATUS_PTR)) -#define astGetSystem(this) \ -astINVOKE(V,astGetSystem_(astCheckFrame(this),STATUS_PTR)) -#define astSetSystem(this,value) \ -astINVOKE(V,astSetSystem_(astCheckFrame(this),value,STATUS_PTR)) -#define astTestSystem(this) \ -astINVOKE(V,astTestSystem_(astCheckFrame(this),STATUS_PTR)) - -#define astClearAlignSystem(this) \ -astINVOKE(V,astClearAlignSystem_(astCheckFrame(this),STATUS_PTR)) -#define astGetAlignSystem(this) \ -astINVOKE(V,astGetAlignSystem_(astCheckFrame(this),STATUS_PTR)) -#define astSetAlignSystem(this,value) \ -astINVOKE(V,astSetAlignSystem_(astCheckFrame(this),value,STATUS_PTR)) -#define astTestAlignSystem(this) \ -astINVOKE(V,astTestAlignSystem_(astCheckFrame(this),STATUS_PTR)) - -#define astClearEpoch(this) \ -astINVOKE(V,astClearEpoch_(astCheckFrame(this),STATUS_PTR)) -#define astGetEpoch(this) \ -astINVOKE(V,astGetEpoch_(astCheckFrame(this),STATUS_PTR)) -#define astSetEpoch(this,value) \ -astINVOKE(V,astSetEpoch_(astCheckFrame(this),value,STATUS_PTR)) -#define astTestEpoch(this) \ -astINVOKE(V,astTestEpoch_(astCheckFrame(this),STATUS_PTR)) - -#define astGetObsLon(this) \ -astINVOKE(V,astGetObsLon_(astCheckFrame(this),STATUS_PTR)) -#define astTestObsLon(this) \ -astINVOKE(V,astTestObsLon_(astCheckFrame(this),STATUS_PTR)) -#define astClearObsLon(this) \ -astINVOKE(V,astClearObsLon_(astCheckFrame(this),STATUS_PTR)) -#define astSetObsLon(this,value) \ -astINVOKE(V,astSetObsLon_(astCheckFrame(this),value,STATUS_PTR)) - -#define astGetObsLat(this) \ -astINVOKE(V,astGetObsLat_(astCheckFrame(this),STATUS_PTR)) -#define astTestObsLat(this) \ -astINVOKE(V,astTestObsLat_(astCheckFrame(this),STATUS_PTR)) -#define astClearObsLat(this) \ -astINVOKE(V,astClearObsLat_(astCheckFrame(this),STATUS_PTR)) -#define astSetObsLat(this,value) \ -astINVOKE(V,astSetObsLat_(astCheckFrame(this),value,STATUS_PTR)) - -#define astGetObsAlt(this) \ -astINVOKE(V,astGetObsAlt_(astCheckFrame(this),STATUS_PTR)) -#define astTestObsAlt(this) \ -astINVOKE(V,astTestObsAlt_(astCheckFrame(this),STATUS_PTR)) -#define astClearObsAlt(this) \ -astINVOKE(V,astClearObsAlt_(astCheckFrame(this),STATUS_PTR)) -#define astSetObsAlt(this,value) \ -astINVOKE(V,astSetObsAlt_(astCheckFrame(this),value,STATUS_PTR)) - -#define astClearDtai(this) \ -astINVOKE(V,astClearDtai_(astCheckFrame(this),STATUS_PTR)) -#define astGetDtai(this) \ -astINVOKE(V,astGetDtai_(astCheckFrame(this),STATUS_PTR)) -#define astSetDtai(this,value) \ -astINVOKE(V,astSetDtai_(astCheckFrame(this),value,STATUS_PTR)) -#define astTestDtai(this) \ -astINVOKE(V,astTestDtai_(astCheckFrame(this),STATUS_PTR)) - -#define astClearDut1(this) \ -astINVOKE(V,astClearDut1_(astCheckFrame(this),STATUS_PTR)) -#define astGetDut1(this) \ -astINVOKE(V,astGetDut1_(astCheckFrame(this),STATUS_PTR)) -#define astSetDut1(this,value) \ -astINVOKE(V,astSetDut1_(astCheckFrame(this),value,STATUS_PTR)) -#define astTestDut1(this) \ -astINVOKE(V,astTestDut1_(astCheckFrame(this),STATUS_PTR)) - -#define astTestActiveUnit(this) \ -astINVOKE(V,astTestActiveUnit_(astCheckFrame(this),STATUS_PTR)) - -#define astSetFrameFlags(this,flags) \ -astINVOKE(V,astSetFrameFlags_(astCheckFrame(this),flags,STATUS_PTR)) -#define astGetFrameFlags(this) \ -astINVOKE(V,astGetFrameFlags_(astCheckFrame(this),STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/frames.pdf b/ast/frames.pdf deleted file mode 100644 index 6ac10e5..0000000 Binary files a/ast/frames.pdf and /dev/null differ diff --git a/ast/frameset.c b/ast/frameset.c deleted file mode 100644 index d3bcc06..0000000 --- a/ast/frameset.c +++ /dev/null @@ -1,13337 +0,0 @@ -/* -*class++ -* Name: -* FrameSet - -* Purpose: -* Set of inter-related coordinate systems. - -* Constructor Function: -c astFrameSet -f AST_FRAMESET - -* Description: -* A FrameSet consists of a set of one or more Frames (which -* describe coordinate systems), connected together by Mappings -* (which describe how the coordinate systems are inter-related). A -* FrameSet makes it possible to obtain a Mapping between any pair -* of these Frames (i.e. to convert between any of the coordinate -* systems which it describes). The individual Frames are -* identified within the FrameSet by an integer index, with Frames -* being numbered consecutively from one as they are added to the -* FrameSet. -* -* Every FrameSet has a "base" Frame and a "current" Frame (which -* are allowed to be the same). Any of the Frames may be nominated -* to hold these positions, and the choice is determined by the -* values of the FrameSet's Base and Current attributes, which hold -* the indices of the relevant Frames. By default, the first Frame -* added to a FrameSet is its base Frame, and the last one added is -* its current Frame. -* -* The base Frame describes the "native" coordinate system of -* whatever the FrameSet is used to calibrate (e.g. the pixel -* coordinates of an image) and the current Frame describes the -* "apparent" coordinate system in which it should be viewed -* (e.g. displayed, etc.). Any further Frames represent a library -* of alternative coordinate systems, which may be selected by -* making them current. -* -* When a FrameSet is used in a context that requires a Frame, -* (e.g. obtaining its Title value, or number of axes), the current -* Frame is used. A FrameSet may therefore be used in place of its -* current Frame in most situations. -* -* When a FrameSet is used in a context that requires a Mapping, -* the Mapping used is the one between its base Frame and its -* current Frame. Thus, a FrameSet may be used to convert "native" -* coordinates into "apparent" ones, and vice versa. Like any -c Mapping, a FrameSet may also be inverted (see astInvert), which -f Mapping, a FrameSet may also be inverted (see AST_INVERT), which -* has the effect of interchanging its base and current Frames and -* hence of reversing the Mapping between them. -* -* Regions may be added into a FrameSet (since a Region is a type of -* Frame), either explicitly or as components within CmpFrames. In this -* case the Mapping between a pair of Frames within a FrameSet will -* include the effects of the clipping produced by any Regions included -* in the path between the Frames. - -* Inheritance: -* The FrameSet class inherits from the Frame class. - -* Attributes: -* In addition to those attributes common to all Frames, every -* FrameSet also has the following attributes: -* -* - AllVariants: List of all variant mappings stored with current Frame -* - Base: FrameSet base Frame index -* - Current: FrameSet current Frame index -* - Nframe: Number of Frames in a FrameSet -* - Variant: Name of variant mapping in use by current Frame - -* Every FrameSet also inherits any further attributes that belong -* to its current Frame, regardless of that Frame's class. (For -* example, the Equinox attribute, defined by the SkyFrame class, is -* inherited by any FrameSet which has a SkyFrame as its current -* Frame.) The set of attributes belonging to a FrameSet may therefore -* change when a new current Frame is selected. - -* Functions: -c In addition to those functions applicable to all Frames, the -c following functions may also be applied to all FrameSets: -f In addition to those routines applicable to all Frames, the -f following routines may also be applied to all FrameSets: -* -c - astAddFrame: Add a Frame to a FrameSet to define a new coordinate -c system -c - astAddVariant: Add a variant Mapping to the current Frame -c - astGetFrame: Obtain a pointer to a specified Frame in a FrameSet -c - astGetMapping: Obtain a Mapping between two Frames in a FrameSet -c - astMirrorVariants: Make the current Frame mirror variant Mappings in another Frame -c - astRemapFrame: Modify a Frame's relationship to the other Frames in a -c FrameSet -c - astRemoveFrame: Remove a Frame from a FrameSet -f - AST_ADDFRAME: Add a Frame to a FrameSet to define a new coordinate -f system -f - AST_ADDVARIANT: Add a variant Mapping to the current Frame -f - AST_GETFRAME: Obtain a pointer to a specified Frame in a FrameSet -f - AST_GETMAPPING: Obtain a Mapping between two Frames in a FrameSet -f - AST_MIRRORVARIANTS: Make the current Frame mirror variant Mappings in another Frame -f - AST_REMAPFRAME: Modify a Frame's relationship to the other Frames in a -f FrameSet -f - AST_REMOVEFRAME: Remove a Frame from a FrameSet - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 16-FEB-1996 (RFWS): -* Original version. -* 5-JUN-1996 (RFWS): -* Tidied up, etc. -* 2-JUL-1996 (RFWS): -* Fixed bug in astRemoveFrame which caused the base/current -* Frame index to be wrong. -* 12-JUL-1996 (RFWS): -* Over-ride the astReportPoints method to provide -* Frame-specific formatting. -* 12-AUG-1996 (RFWS): -* Upgraded to provide a public interface, plus improvements to -* astAlign and the handling of nodes as Frames are -* added/removed. -* 11-SEP-1996 (RFWS): -* Added Gap. -* 25-SEP-1996 (RFWS): -* Added I/O facilities. -* 30-MAY-1997 (RFWS): -* Add special treatment for the ID attribute (which is not -* derived from the current Frame). -* 10-JUN-1997 (RFWS): -* Rationalised the astConvert implementation. -* 11-JUN-1997 (RFWS): -* Added the FindFrame implementation. -* 27-JUN-1997 (RFWS): -* Fixed bug which caused certain Mapping attributes to be -* handled by the current Frame instead of by the member -* functions defined by this class. -* 3-JUL-1997 (RFWS): -* Fixed bug: failing to extend the invert array in -* astRemapFrame. -* 10-JUL-1997 (RFWS): -* Over-ride the astSimplify method. -* 14-NOV-1997 (RFWS): -* Fixed error in loop implementing search over domains in -* FindFrame. -* 20-NOV-1997 (RFWS): -* Fixed bug in default Base and Current attribute values when a -* FrameSet has been inverted. -* 20-NOV-1997 (RFWS): -* Modified astConvert to use the current Frame of the "to" -* FrameSet as the destination coordinate system (instead of the -* base Frame) and to modify its Base attribute instead of its -* Current attribute. -* 22-DEC-1997 (RFWS): -* Further modified astConvert to convert from the Current Frame -* of the "from" FrameSet and to modify its Base -* attribute. Frame search order also reversed if the Invert -* attribute is non-zero for either FrameSet. -* 19-JAN-1998 (RFWS): -* Installed the TidyNodes function. -* 20-JAN-1998 (RFWS): -* Implemented preservation of FrameSet integrity when attribute -* values associated with the current Frame are modified. -* 24-FEB-1998 (RFWS): -* Added the ForceCopy function to allow integrity to be preserved -* when there are multiple references to the same Frame. -* 25-FEB-1998 (RFWS): -* Over-ride the astUnformat method. -* 24-MAR-1998 (RFWS): -* Fixed unterminated comment causing problems in CombineMaps. -* 6-APR-1998 (RFWS): -* Fixed another unterminated comment in CombineMaps. -* 27-MAY-1998 (RFWS): -* Fixed bug: failure to record new invert flag value after -* simplifying a CmpMap in TidyNodes. -* 17-DEC-2002 (DSB): -* Override accessors for Frame attributes Top, Bottom, Epoch, -* System, AlignSystem and ActiveUnit. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitFrameSetVtab -* method. -* 24-JAN-2004 (DSB): -* o Override the astFields method. -* o Add argument "fmt" to Abbrev. -* 23-MAR-2004 (DSB): -* Modified astGetMapping and Span to include the clipping effect of -* any Regions in the path between the two supplied Frames. -* 24-AUG-2004 (DSB): -* - Override various methods inherited from Frame (astAngle, -* astAxAngle, astAxDistance, astAxOffset, astCheckPerm, astOffset2, -* astResolve, astSystemCode, astSystemString, astValidateSystem, -* astValidateAxisSelection). These should have been overridden a -* long time ago! -* 8-SEP-2004 (DSB): -* Override astResolvePoints. -* 12-MAY-2005 (DSB): -* Override astNormBox method. -* 12-AUG-2005 (DSB): -* Override ObsLat and ObsLon accessor methods. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 15-MAY-2006 (DSB): -* Override astEqual. -* 30-JUN-2006 (DSB): -* Allow astAbbrev to have a null "str1" value. -* 22-JUN-2007 (DSB): -* Modify VSet to avoid using the args va_list twice since the -* first use (by the parent VSet function) invalidates the va_list -* causing a segvio to be generated by the second use (when -* formatting an error message). -* 11-JAN-2008 (DSB): -* Override the astRate method. -* 17-NOV-2008 (DSB): -* Correct parent class in invocation of astMAKE_ISA. -* 14-JAN-2009 (DSB): -* Override the astIntersect method. -* 18-JUN-2009 (DSB): -* Override ObsAlt accessor methods. -* 30-OCT-2009 (DSB): -* Make the Ident attribute relate to the FrameSet, not the current -* Frame. -* 22-MAR-2011 (DSB): -* Override astFrameGrid method. -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -* 2-SEP-2011 (DSB): -* Fix FrameSet implememntation of astEqual (mapping comparison -* tests were logically inverted). -* 3-OCT-2012 (DSB): -* Fix bug in AppendAxes that could cause internal Mappings to -* be inverted unintentionally when astAddFrame is called with -* iframe=AST__ALLFRAMES. -* 29-APR-2013 (DSB): -* Added attributes AllVariants and Variant. Also added methods -* astAddVariant and astMirrorVariants. -* 25-SEP-2014 (DSB): -* Allow Base and Current attributes to be specified by giving a -* Domain name. -* 17-APR-2015 (DSB): -* Added Centre. -* 28-APR-2015 (DSB): -* astAdFrame now takes deep copies of the supplied mapping and -* frame, rather than just cloning their pointers. So the modified -* FrameSet is now independent of the supplied Mapping and Frame -* objects. -* 26-OCT-2016 (DSB): -* Override the AxNorm method. -* 07-APR-2017 (GSB): -* Override Dtai and Dut1 accessor methods. -* 07-NOV-2017 (GSB): -* In AddFrame, check to see if a FrameSet is supplied in place of -* a Mapping and if so, use the FrameSet's base -> current Mapping -* instead. -* 11-DEC-2017 (DSB): -* Added method astGetNode. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS FrameSet - -#define GETALLVARIANTS_BUFF_LEN 200 - -/* -* Name: -* MAKE_CLEAR - -* Purpose: -* Define a function to clear an attribute value for a FrameSet. - -* Type: -* Private macro. - -* Synopsis: -* #include "frameset.h" -* MAKE_CLEAR(attribute) - -* Class Membership: -* Defined by the FrameSet class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Clear( AstFrame *this ) -* -* that clears the value of a specified attribute for the current Frame -* of a FrameSet (this). This function is intended to over-ride the -* astClear method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attribute) \ -static void Clear##attribute( AstFrame *this_frame, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *fr; /* Pointer to current Frame */ \ - AstFrameSet *this; /* Pointer to the FrameSet structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the FrameSet structure. */ \ - this = (AstFrameSet *) this_frame; \ -\ -/* Obtain a pointer to the current Frame and invoke its astClear \ - method. Annul the Frame pointer afterwards. */ \ - fr = astGetFrame( this, AST__CURRENT ); \ - astClear##attribute( fr ); \ - fr = astAnnul( fr ); \ -} - -/* -* Name: -* MAKE_CLEAR_AXIS - -* Purpose: -* Define a function to clear an attribute value for a FrameSet axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "frameset.h" -* MAKE_CLEAR_AXIS(attribute) - -* Class Membership: -* Defined by the FrameSet class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Clear( AstFrame *this, int axis ) -* -* that clears the value of a specified attribute for an axis of -* the current Frame of a FrameSet (this). This function is -* intended to over-ride the astClear method inherited -* from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR_AXIS(attribute) \ -static void Clear##attribute( AstFrame *this_frame, int axis, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *fr; /* Pointer to current Frame */ \ - AstFrameSet *this; /* Pointer to the FrameSet structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the FrameSet structure. */ \ - this = (AstFrameSet *) this_frame; \ -\ -/* Validate the axis index supplied. */ \ - (void) astValidateAxis( this, axis, 1, "astClear" #attribute ); \ -\ -/* Obtain a pointer to the FrameSet's current Frame and invoke its \ - astClear method. Annul the Frame pointer afterwards. */ \ - fr = astGetFrame( this, AST__CURRENT ); \ - astClear##attribute( fr, axis ); \ - fr = astAnnul( fr ); \ -} - -/* -* Name: -* MAKE_GET - -* Purpose: -* Define a function to get an attribute value for a FrameSet. - -* Type: -* Private macro. - -* Synopsis: -* #include "frameset.h" -* MAKE_GET(attribute,type) - -* Class Membership: -* Defined by the FrameSet class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static Get( AstFrame *this ) -* -* that gets the value of a specified attribute for the current Frame -* of a FrameSet (this). This function is intended to over-ride the -* astGet method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_GET(attribute,type) \ -static type Get##attribute( AstFrame *this_frame, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *fr; /* Pointer to current Frame */ \ - AstFrameSet *this; /* Pointer to the FrameSet structure */ \ - type result; /* Value to return */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (type) 0; \ -\ -/* Obtain a pointer to the FrameSet structure. */ \ - this = (AstFrameSet *) this_frame; \ -\ -/* Obtain a pointer to the current Frame and invoke its \ - astGet method. Annul the Frame pointer afterwards. */ \ - fr = astGetFrame( this, AST__CURRENT ); \ - result = astGet##attribute( fr ); \ - fr = astAnnul( fr ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = (type) 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* Name: -* MAKE_GET_AXIS - -* Purpose: -* Define a function to get an attribute value for a FrameSet axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "frameset.h" -* MAKE_GET_AXIS(attribute,type) - -* Class Membership: -* Defined by the FrameSet class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static Get( AstFrame *this, int axis ) -* -* that gets the value of a specified attribute for an axis of the -* current Frame of a FrameSet (this). This function is intended to -* over-ride the astGet method inherited from the Frame -* class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_GET_AXIS(attribute,type) \ -static type Get##attribute( AstFrame *this_frame, int axis, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *fr; /* Pointer to current Frame */ \ - AstFrameSet *this; /* Pointer to the FrameSet structure */ \ - type result; /* Value to return */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (type) 0; \ -\ -/* Obtain a pointer to the FrameSet structure. */ \ - this = (AstFrameSet *) this_frame; \ -\ -/* Validate the axis index supplied. */ \ - (void) astValidateAxis( this, axis, 1, "astGet" #attribute ); \ -\ -/* Obtain a pointer to the FrameSet's current Frame and invoke its \ - astGet method. Annul the Frame pointer afterwards. */ \ - fr = astGetFrame( this, AST__CURRENT ); \ - result = astGet##attribute( fr, axis ); \ - fr = astAnnul( fr ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = (type) 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* Name: -* MAKE_SET - -* Purpose: -* Define a function to set an attribute value for a FrameSet. - -* Type: -* Private macro. - -* Synopsis: -* #include "frameset.h" -* MAKE_SET(attribute,type) - -* Class Membership: -* Defined by the FrameSet class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Set( AstFrame *this, value ) -* -* that sets the value of a specified attribute for the current Frame -* of a FrameSet (this). This function is intended to over-ride the -* astSet method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_SET(attribute,type) \ -static void Set##attribute( AstFrame *this_frame, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *fr; /* Pointer to current Frame */ \ - AstFrameSet *this; /* Pointer to the FrameSet structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the FrameSet structure. */ \ - this = (AstFrameSet *) this_frame; \ -\ -/* Obtain a pointer to the FrameSet's current Frame and invoke its \ - astSet method. Annul the Frame pointer afterwards. */ \ - fr = astGetFrame( this, AST__CURRENT ); \ - astSet##attribute( fr, value ); \ - fr = astAnnul( fr ); \ -} - -/* -* Name: -* MAKE_SET_AXIS - -* Purpose: -* Define a function to set an attribute value for a FrameSet axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "frameset.h" -* MAKE_SET_AXIS(attribute,type) - -* Class Membership: -* Defined by the FrameSet class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Set( AstFrame *this, int axis, value ) -* -* that sets the value of a specified attribute for an axis of the -* current Frame of a FrameSet (this). This function is intended to -* over-ride the astSet method inherited from the Frame -* class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_SET_AXIS(attribute,type) \ -static void Set##attribute( AstFrame *this_frame, int axis, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *fr; /* Pointer to current Frame */ \ - AstFrameSet *this; /* Pointer to the FrameSet structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the FrameSet structure. */ \ - this = (AstFrameSet *) this_frame; \ -\ -/* Validate the axis index supplied. */ \ - (void) astValidateAxis( this, axis, 1, "astSet" #attribute ); \ -\ -/* Obtain a pointer to the FrameSet's current Frame and invoke its \ - astSet method. Annul the Frame pointer afterwards. */ \ - fr = astGetFrame( this, AST__CURRENT ); \ - astSet##attribute( fr, axis, value ); \ - fr = astAnnul( fr ); \ -} - -/* -* Name: -* MAKE_TEST - -* Purpose: -* Define a function to test if an attribute value is set for a FrameSet. - -* Type: -* Private macro. - -* Synopsis: -* #include "frameset.h" -* MAKE_TEST(attribute) - -* Class Membership: -* Defined by the FrameSet class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static int Test( AstFrame *this ) -* -* that returns a boolean result (0 or 1) to indicate if the value -* of a specified attribute for the current Frame of a FrameSet -* (this) is set. This function is intended to over-ride the -* astTest method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -*/ - -/* Define the macro. */ -#define MAKE_TEST(attribute) \ -static int Test##attribute( AstFrame *this_frame, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *fr; /* Pointer to current Frame */ \ - AstFrameSet *this; /* Pointer to FrameSet structure */ \ - int result; /* Result to return */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Obtain a pointer to the FrameSet structure. */ \ - this = (AstFrameSet *) this_frame; \ -\ -/* Obtain a pointer to the FrameSet's current Frame and invoke its \ - astTest method. Annul the Frame pointer afterwards. */ \ - fr = astGetFrame( this, AST__CURRENT ); \ - result = astTest##attribute( fr ); \ - fr = astAnnul( fr ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* Name: -* MAKE_TEST_AXIS - -* Purpose: -* Define a function to test if an attribute value is set for a FrameSet -* axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "frameset.h" -* MAKE_TEST_AXIS(attribute) - -* Class Membership: -* Defined by the FrameSet class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static int Test( AstFrame *this, int axis ) -* -* that returns a boolean result (0 or 1) to indicate if the value -* of a specified attribute for an axis of the current Frame of a -* FrameSet (this) is set. This function is intended to over-ride -* the astTest method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -*/ - -/* Define the macro. */ -#define MAKE_TEST_AXIS(attribute) \ -static int Test##attribute( AstFrame *this_frame, int axis, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *fr; /* Pointer to current Frame */ \ - AstFrameSet *this; /* Pointer to the FrameSet structure */ \ - int result; /* Value to return */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Obtain a pointer to the FrameSet structure. */ \ - this = (AstFrameSet *) this_frame; \ -\ -/* Validate the axis index supplied. */ \ - (void) astValidateAxis( this, axis, 1, "astTest" #attribute ); \ -\ -/* Obtain a pointer to the FrameSet's current Frame and invoke its \ - astTest method. Annul the Frame pointer afterwards. */ \ - fr = astGetFrame( this, AST__CURRENT ); \ - result = astTest##attribute( fr, axis ); \ - fr = astAnnul( fr ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "mapping.h" /* Coordinate Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "permmap.h" /* Coordinate permutation Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "frame.h" /* Parent Frame class */ -#include "frameset.h" /* Interface definition for this class */ -#include "cmpframe.h" /* Compound coordinate frames */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static void (* parent_clear)( AstObject *, const char *, int * ); -static int (* parent_getusedefs)( AstObject *, int * ); -static void (* parent_vset)( AstObject *, const char *, char **, va_list, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->Integrity_Frame = NULL; \ - globals->Integrity_Method = ""; \ - globals->Integrity_Lost = 0; \ - globals->GetAllVariants_Buff[ 0 ] = 0; \ - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(FrameSet) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(FrameSet,Class_Init) -#define class_vtab astGLOBAL(FrameSet,Class_Vtab) -#define getattrib_buff astGLOBAL(FrameSet,GetAttrib_Buff) -#define integrity_frame astGLOBAL(FrameSet,Integrity_Frame) -#define integrity_method astGLOBAL(FrameSet,Integrity_Method) -#define integrity_lost astGLOBAL(FrameSet,Integrity_Lost) -#define getallvariants_buff astGLOBAL(FrameSet,GetAllVariants_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ AST__FRAMESET_GETATTRIB_BUFF_LEN + 1 ]; - -/* Variables associated with preserving FrameSet integrity. */ -static AstFrame *integrity_frame = NULL; /* Pointer to copy of current Frame */ -static const char *integrity_method = ""; /* Name of method being used */ -static int integrity_lost = 0; /* Current Frame modified? */ - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstFrameSetVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -/* String buffers. */ -static char getallvariants_buff[ AST__FRAMESET_GETALLVARIANTS_BUFF_LEN + 1 ]; - -#endif - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstAxis *GetAxis( AstFrame *, int, int * ); -static AstFrame *GetFrame( AstFrameSet *, int, int * ); -static AstFrame *PickAxes( AstFrame *, int, const int[], AstMapping **, int * ); -static AstFrameSet *Convert( AstFrame *, AstFrame *, const char *, int * ); -static AstFrameSet *ConvertX( AstFrame *, AstFrame *, const char *, int * ); -static AstFrameSet *FindFrame( AstFrame *, AstFrame *, const char *, int * ); -static AstLineDef *LineDef( AstFrame *, const double[2], const double[2], int * ); -static AstMapping *CombineMaps( AstMapping *, int, AstMapping *, int, int, int * ); -static AstMapping *GetMapping( AstFrameSet *, int, int, int * ); -static AstMapping *RemoveRegions( AstMapping *, int * ); -static AstMapping *Simplify( AstMapping *, int * ); -static AstObject *Cast( AstObject *, AstObject *, int * ); -static AstPointSet *FrameGrid( AstFrame *, int, const double *, const double *, int * ); -static AstPointSet *ResolvePoints( AstFrame *, const double [], const double [], AstPointSet *, AstPointSet *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstSystemType SystemCode( AstFrame *, const char *, int * ); -static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * ); -static const char *Abbrev( AstFrame *, int, const char *, const char *, const char *, int * ); -static const char *Format( AstFrame *, int, double, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetDomain( AstFrame *, int * ); -static const char *GetFormat( AstFrame *, int, int * ); -static const char *GetLabel( AstFrame *, int, int * ); -static const char *GetSymbol( AstFrame *, int, int * ); -static const char *GetTitle( AstFrame *, int * ); -static const char *GetUnit( AstFrame *, int, int * ); -static const char *GetAllVariants( AstFrameSet *, int * ); -static const char *SystemString( AstFrame *, AstSystemType, int * ); -static const int *GetPerm( AstFrame *, int * ); -static double Angle( AstFrame *, const double[], const double[], const double[], int * ); -static double AxAngle( AstFrame *, const double[], const double[], int, int * ); -static double AxDistance( AstFrame *, int, double, double, int * ); -static double AxOffset( AstFrame *, int, double, double, int * ); -static double Distance( AstFrame *, const double[], const double[], int * ); -static double Centre( AstFrame *, int, double, double, int * ); -static double Gap( AstFrame *, int, double, int *, int * ); -static double Offset2( AstFrame *, const double[2], double, double, double[2], int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int Fields( AstFrame *, int, const char *, const char *, int, char **, int *, double *, int * ); -static int ForceCopy( AstFrameSet *, int, int * ); -static int GetActiveUnit( AstFrame *, int * ); -static int GetBase( AstFrameSet *, int * ); -static int GetCurrent( AstFrameSet *, int * ); -static int GetDigits( AstFrame *, int * ); -static int GetDirection( AstFrame *, int, int * ); -static int GetIsLinear( AstMapping *, int * ); -static int GetMatchEnd( AstFrame *, int * ); -static int GetMaxAxes( AstFrame *, int * ); -static int GetMinAxes( AstFrame *, int * ); -static int GetNaxes( AstFrame *, int * ); -static int GetNframe( AstFrameSet *, int * ); -static int GetNin( AstMapping *, int * ); -static int GetNode( AstFrameSet *, int, int *, int *, AstMapping **, int *, int * ); -static int GetNout( AstMapping *, int * ); -static int GetObjSize( AstObject *, int * ); -static int GetPermute( AstFrame *, int * ); -static int GetPreserveAxes( AstFrame *, int * ); -static int GetTranForward( AstMapping *, int * ); -static int GetTranInverse( AstMapping *, int * ); -static int GetVarFrm( AstFrameSet *, int, int * ); -static int IsUnitFrame( AstFrame *, int * ); -static int LineContains( AstFrame *, AstLineDef *, int, double *, int * ); -static int LineCrossing( AstFrame *, AstLineDef *, AstLineDef *, double **, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int Span( AstFrameSet *, AstFrame **, int, int, int, AstMapping **, int *, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int TestActiveUnit( AstFrame *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestBase( AstFrameSet *, int * ); -static int TestCurrent( AstFrameSet *, int * ); -static int TestDigits( AstFrame *, int * ); -static int TestDirection( AstFrame *, int, int * ); -static int TestDomain( AstFrame *, int * ); -static int TestFormat( AstFrame *, int, int * ); -static int TestLabel( AstFrame *, int, int * ); -static int TestMatchEnd( AstFrame *, int * ); -static int TestMaxAxes( AstFrame *, int * ); -static int TestMinAxes( AstFrame *, int * ); -static int TestPermute( AstFrame *, int * ); -static int TestPreserveAxes( AstFrame *, int * ); -static int TestSymbol( AstFrame *, int, int * ); -static int TestTitle( AstFrame *, int * ); -static int TestUnit( AstFrame *, int, int * ); -static int Unformat( AstFrame *, int, const char *, double *, int * ); -static int ValidateAxis( AstFrame *, int, int, const char *, int * ); -static int ValidateFrameIndex( AstFrameSet *, int, const char *, int * ); -static void AddFrame( AstFrameSet *, int, AstMapping *, AstFrame *, int * ); -static void AppendAxes( AstFrameSet *, AstFrame *, int * ); -static void AxNorm( AstFrame *, int, int, int, double *, int * ); -static void CheckPerm( AstFrame *, const int *, const char *, int * ); -static void Clear( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearBase( AstFrameSet *, int * ); -static void ClearCurrent( AstFrameSet *, int * ); -static void ClearDigits( AstFrame *, int * ); -static void ClearDirection( AstFrame *, int, int * ); -static void ClearDomain( AstFrame *, int * ); -static void ClearFormat( AstFrame *, int, int * ); -static void ClearLabel( AstFrame *, int, int * ); -static void ClearMatchEnd( AstFrame *, int * ); -static void ClearMaxAxes( AstFrame *, int * ); -static void ClearMinAxes( AstFrame *, int * ); -static void ClearPermute( AstFrame *, int * ); -static void ClearPreserveAxes( AstFrame *, int * ); -static void ClearSymbol( AstFrame *, int, int * ); -static void ClearTitle( AstFrame *, int * ); -static void ClearUnit( AstFrame *, int, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void Intersect( AstFrame *, const double[2], const double[2], const double[2], const double[2], double[2], int * ); -static void LineOffset( AstFrame *, AstLineDef *, double, double, double[2], int * ); -static void MatchAxes( AstFrame *, AstFrame *, int *, int * ); -static void MatchAxesX( AstFrame *, AstFrame *, int *, int * ); -static void Norm( AstFrame *, double[], int * ); -static void NormBox( AstFrame *, double[], double[], AstMapping *, int * ); -static void Offset( AstFrame *, const double[], const double[], double, double[], int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void PermAxes( AstFrame *, const int[], int * ); -static void PrimaryFrame( AstFrame *, int, AstFrame **, int *, int * ); -static void RecordIntegrity( AstFrameSet *, int * ); -static void AddVariant( AstFrameSet *, AstMapping *, const char *, int * ); -static void MirrorVariants( AstFrameSet *, int, int * ); -static void RemapFrame( AstFrameSet *, int, AstMapping *, int * ); -static void RemoveFrame( AstFrameSet *, int, int * ); -static void RemoveMirrors( AstFrameSet *, int, int * ); -static void ReportPoints( AstMapping *, int, AstPointSet *, AstPointSet *, int * ); -static void Resolve( AstFrame *, const double [], const double [], const double [], double [], double *, double *, int * ); -static void RestoreIntegrity( AstFrameSet *, int * ); -static void SetActiveUnit( AstFrame *, int, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetAxis( AstFrame *, int, AstAxis *, int * ); -static void SetBase( AstFrameSet *, int, int * ); -static void SetCurrent( AstFrameSet *, int, int * ); -static void SetDigits( AstFrame *, int, int * ); -static void SetDirection( AstFrame *, int, int, int * ); -static void SetDomain( AstFrame *, const char *, int * ); -static void SetFormat( AstFrame *, int, const char *, int * ); -static void SetLabel( AstFrame *, int, const char *, int * ); -static void SetMatchEnd( AstFrame *, int, int * ); -static void SetMaxAxes( AstFrame *, int, int * ); -static void SetMinAxes( AstFrame *, int, int * ); -static void SetPermute( AstFrame *, int, int * ); -static void SetPreserveAxes( AstFrame *, int, int * ); -static void SetSymbol( AstFrame *, int, const char *, int * ); -static void SetTitle( AstFrame *, const char *, int * ); -static void SetUnit( AstFrame *, int, const char *, int * ); -static void TidyNodes( AstFrameSet *, int * ); -static void VSet( AstObject *, const char *, char **, va_list, int * ); -static void ValidateAxisSelection( AstFrame *, int, const int *, const char *, int * ); - -static double GetBottom( AstFrame *, int, int * ); -static int TestBottom( AstFrame *, int, int * ); -static void ClearBottom( AstFrame *, int, int * ); -static void SetBottom( AstFrame *, int, double, int * ); - -static double GetTop( AstFrame *, int, int * ); -static int TestTop( AstFrame *, int, int * ); -static void ClearTop( AstFrame *, int, int * ); -static void SetTop( AstFrame *, int, double, int * ); - -static double GetEpoch( AstFrame *, int * ); -static int TestEpoch( AstFrame *, int * ); -static void ClearEpoch( AstFrame *, int * ); -static void SetEpoch( AstFrame *, double, int * ); - -static double GetDtai( AstFrame *, int * ); -static int TestDtai( AstFrame *, int * ); -static void ClearDtai( AstFrame *, int * ); -static void SetDtai( AstFrame *, double, int * ); - -static double GetDut1( AstFrame *, int * ); -static int TestDut1( AstFrame *, int * ); -static void ClearDut1( AstFrame *, int * ); -static void SetDut1( AstFrame *, double, int * ); - -static double GetObsAlt( AstFrame *, int * ); -static int TestObsAlt( AstFrame *, int * ); -static void ClearObsAlt( AstFrame *, int * ); -static void SetObsAlt( AstFrame *, double, int * ); - -static double GetObsLat( AstFrame *, int * ); -static int TestObsLat( AstFrame *, int * ); -static void ClearObsLat( AstFrame *, int * ); -static void SetObsLat( AstFrame *, double, int * ); - -static double GetObsLon( AstFrame *, int * ); -static int TestObsLon( AstFrame *, int * ); -static void ClearObsLon( AstFrame *, int * ); -static void SetObsLon( AstFrame *, double, int * ); - -static int GetUseDefs( AstObject *, int * ); - -static AstSystemType GetSystem( AstFrame *, int * ); -static int TestSystem( AstFrame *, int * ); -static void ClearSystem( AstFrame *, int * ); -static void SetSystem( AstFrame *, AstSystemType, int * ); - -static AstSystemType GetAlignSystem( AstFrame *, int * ); -static int TestAlignSystem( AstFrame *, int * ); -static void ClearAlignSystem( AstFrame *, int * ); -static void SetAlignSystem( AstFrame *, AstSystemType, int * ); - -static const char *GetVariant( AstFrameSet *, int * ); -static int TestVariant( AstFrameSet *, int * ); -static void ClearVariant( AstFrameSet *, int * ); -static void SetVariant( AstFrameSet *, const char *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ -static const char *Abbrev( AstFrame *this_frame, int axis, const char *fmt, - const char *str1, const char *str2, int *status ) { -/* -* Name: -* Abbrev - -* Purpose: -* Abbreviate a formatted FrameSet axis value by skipping leading fields. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* const char *Abbrev( AstFrame *this, int axis, const char *fmt, -* const char *str1, const char *str2, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astAbbrev -* method inherited from the Frame class). - -* Description: -* This function compares two FrameSet axis values that have been -* formatted (using astFormat) and determines if they have any -* redundant leading fields (i.e. leading fields in common which -* can be suppressed when tabulating the values or plotting them on -* the axis of a graph). - -* Parameters: -* this -* Pointer to the FrameSet. -* axis -* The number of the FrameSet axis for which the values have -* been formatted (axis numbering starts at zero for the first -* axis). -* fmt -* Pointer to a constant null-terminated string containing the -* format specification used to format the two values. -* str1 -* Pointer to a constant null-terminated string containing the -* first formatted value. If this is null, the returned pointer -* points to the start of the final field in str2. -* str2 -* Pointer to a constant null-terminated string containing the -* second formatted value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer into the "str2" string which locates the first -* character in the first field that differs between the two -* formatted values. -* -* If the two values have no leading fields in common, the returned -* value will point at the start of string "str2". If the two -* values are equal, it will point at the terminating null at the -* end of this string. - -* Notes: -* - This function assumes that the format specification used was -* the same when both values were formatted and that they both -* apply to the same FrameSet axis. -* - A pointer to the start of "str2" will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return str2; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astAbbrev" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astAbbrev method to perform the processing. Annul the Frame - pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astAbbrev( fr, axis, fmt, str1, str2 ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = str2; - -/* Return the result. */ - return result; -} - -static void AddFrame( AstFrameSet *this, int iframe, AstMapping *map0, - AstFrame *frame, int *status ) { -/* -*++ -* Name: -c astAddFrame -f AST_ADDFRAME - -* Purpose: -* Add a Frame to a FrameSet to define a new coordinate system. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c void astAddFrame( AstFrameSet *this, int iframe, AstMapping *map, -c AstFrame *frame ) -f CALL AST_ADDFRAME( THIS, IFRAME, MAP, FRAME, STATUS ) - -* Class Membership: -* FrameSet method. - -* Description: -c This function adds a new Frame and an associated Mapping to a -f This routine adds a new Frame and an associated Mapping to a -* FrameSet so as to define a new coordinate system, derived from -* one which already exists within the FrameSet. The new Frame then -* becomes the FrameSet's current Frame. -* -c This function -f This routine -* may also be used to merge two FrameSets, or to append extra axes -* to every Frame in a FrameSet. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FrameSet. -c iframe -f IFRAME = INTEGER (Given) -* The index of the Frame within the FrameSet which describes -* the coordinate system upon which the new one is to be based. -* This value should lie in the range from 1 to the number of -* Frames already in the FrameSet (as given by its Nframe -* attribute). As a special case, AST__ALLFRAMES may be supplied, -* in which case the axes defined by the supplied Frame are appended -* to every Frame in the FrameSet (see the Notes section for details). -c map -f MAP = INTEGER (Given) -* Pointer to a Mapping which describes how to convert -* coordinates from the old coordinate system (described by the -c Frame with index "iframe") into coordinates in the new -f Frame with index IFRAME) into coordinates in the new -* system. The Mapping's forward transformation should perform -* this conversion, and its inverse transformation should -* convert in the opposite direction. The supplied Mapping is ignored -c if parameter "iframe"is equal to AST__ALLFRAMES. -f if parameter IFRAME is equal to AST__ALLFRAMES. -c frame -f FRAME = INTEGER (Given) -* Pointer to a Frame that describes the new coordinate system. -* Any class of Frame may be supplied (including Regions and -* FrameSets). -* -c This function may also be used to merge two FrameSets by -c supplying a pointer to a second FrameSet for this parameter -f This routine may also be used to merge two FrameSets by -f supplying a pointer to a second FrameSet for this argument -* (see the Notes section for details). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Deep copies of the supplied -c "mapping" and "frame" -f MAPPING and FRAME -* objects are stored within the modified FrameSet. So any changes made -* to the FrameSet after calling this method will have no effect on the -* supplied Mapping and Frame objects. -* - A value of AST__BASE or AST__CURRENT may be given for the -c "iframe" parameter to specify the base Frame or the current -f IFRAME argument to specify the base Frame or the current -* Frame respectively. -c - This function sets the value of the Current attribute for the -f - This routine sets the value of the Current attribute for the -* FrameSet so that the new Frame subsequently becomes the current -* Frame. -* - The number of input coordinate values accepted by the supplied -* Mapping (its Nin attribute) must match the number of axes in the -c Frame identified by the "iframe" parameter. Similarly, the -f Frame identified by the IFRAME argument. Similarly, the -* number of output coordinate values generated by this Mapping -* (its Nout attribute) must match the number of axes in the new -* Frame. -* - As a special case, if a pointer to a FrameSet is given for the -c "frame" parameter, this is treated as a request to merge a pair of -f FRAME argument, this is treated as a request to merge a pair of -* FrameSets. This is done by appending all the new Frames (in the -c "frame" FrameSet) to the original FrameSet, while preserving -f FRAME FrameSet) to the original FrameSet, while preserving -* their order and retaining all the inter-relationships -* (i.e. Mappings) between them. The two sets of Frames are -* inter-related within the merged FrameSet by using the Mapping -* supplied. This should convert between the Frame identified by -c the "iframe" parameter (in the original FrameSet) and the current -c Frame of the "frame" FrameSet. This latter Frame becomes the -f the IFRAME argument (in the original FrameSet) and the current -f Frame of the FRAME FrameSet. This latter Frame becomes the -* current Frame in the merged FrameSet. -* - As another special case, if a value of AST__ALLFRAMES is supplied -* for parameter -c "iframe", -f IFRAME, -* then the supplied Mapping is ignored, and the axes defined by the -* supplied Frame are appended to each Frame in the FrameSet. In detail, -* each Frame in the FrameSet is replaced by a CmpFrame containing the -* original Frame and the Frame specified by parameter -c "frame". -f FRAME. -* In addition, each Mapping in the FrameSet is replaced by a CmpMap -* containing the original Mapping and a UnitMap in parallel. The Nin and -* Nout attributes of the UnitMap are set equal to the number of axes -* in the supplied Frame. Each new CmpMap is simplified using -c astSimplify -f AST_SIMPLIFY -* before being stored in the FrameSet. - -*-- -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to Frame identified by "iframe" */ - AstFrameSet *frameset; /* Pointer to new FrameSet (if given) */ - AstMapping *inode_map; /* Temporarily saved Mapping pointer */ - AstMapping *map; /* The supplied Mapping */ - AstMapping *next_map; /* Temporarily saved Mapping pointer */ - int current; /* Current Frame index in merged FrameSet */ - int current_node; /* Node number for current Frame */ - int ifr; /* Loop counter for Frames */ - int inode; /* Loop counter for nodes */ - int inode_invert; /* Temporarily saved invert flag value */ - int inode_link; /* Temporarily saved link value */ - int naxes; /* Number of Frame axes */ - int ncoord; /* Number of Mapping coordinates per point */ - int next; /* Number of next node in path */ - int next_invert; /* Temporarily saved invert flag value */ - int next_link; /* Temporarily saved link value */ - int nframe; /* Number of Frames in merged FrameSet */ - int nnode; /* Number of nodes in merged FrameSet */ - int node_zero; /* Location of "node zero" after merging */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* First handle cases where we are appending axes to the existing - Frames in a FrameSet. */ - if( iframe == AST__ALLFRAMES ) { - AppendAxes( this, frame, status ); - return; - } - -/* Now handle cases where we are adding a new Frame into the FrameSet. - Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - inode_map = NULL; - next_map = NULL; - inode_invert = 0; - next = 0; - next_invert = 0; - next_link = 0; - -/* If a FrameSet was supplied instead of a Mapping, use the Mapping from - its base Frame to its current Frame. */ - if( astIsAFrameSet( map0 ) ) { - map = astGetMapping( map0, AST__BASE, AST__CURRENT ); - } else { - map = astClone( map0 ); - } - -/* Validate and translate the Frame index supplied. */ - iframe = astValidateFrameIndex( this, iframe, "astAddFrame" ); - -/* Obtain a pointer to the Frame from which the new coordinate system - will be derived and determine how many axes it has. Annul the Frame - pointer afterwards. */ - if ( astOK ) { - fr = astGetFrame( this, iframe ); - naxes = astGetNaxes( fr ); - fr = astAnnul( fr ); - -/* Obtain the number of input coordinate values per point for the - Mapping supplied and check that this matches the number of axes - obtained above. Report an error if it does not. */ - ncoord = astGetNin( map ); - if ( astOK && ( naxes != ncoord ) ) { - astError( AST__NCPIN, "astAddFrame(%s): Bad number of %s input " - "coordinate values (%d).", status, astGetClass( this ), - astGetClass( map ), ncoord ); - astError( AST__NCPIN, "The %s given should accept %d coordinate " - "value%s for each input point.", status, astGetClass( map ), naxes, - ( naxes == 1 ) ? "" : "s" ); - } - } - -/* Similarly, obtain the number of output coordinate values per point - for the Mapping and check that this equals the number of axes for - the Frame supplied. Report an error if necessary. */ - if ( astOK ) { - ncoord = astGetNout( map ); - naxes = astGetNaxes( frame ); - if ( astOK && ( ncoord != naxes ) ) { - astError( AST__NCPIN, "astAddFrame(%s): Bad number of %s output " - "coordinate values (%d).", status, astGetClass( this ), - astGetClass( map ), ncoord ); - astError( AST__NCPIN, "The %s given should generate %d " - "coordinate value%s for each output point.", status, - astGetClass( map ), naxes, ( naxes == 1 ) ? "" : "s" ); - } - } - -/* Normal Frame supplied. */ -/* ====================== */ -/* Check that the Frame supplied is not a FrameSet (handling a - FrameSet is a special case which is addressed later). */ - if ( !astIsAFrameSet( frame ) && astOK ) { - -/* Increase the size of the FrameSet's arrays to accommodate one new - Frame. */ - this->frame = astGrow( this->frame, this->nframe + 1, - sizeof( AstFrame * ) ); - this->varfrm = astGrow( this->varfrm, this->nframe + 1, - sizeof( int ) ); - this->node = astGrow( this->node, this->nframe + 1, sizeof( int ) ); - this->map = astGrow( this->map, this->nnode, sizeof( AstMapping * ) ); - this->link = astGrow( this->link, this->nnode, sizeof( int ) ); - this->invert = astGrow( this->invert, this->nnode, sizeof( int ) ); - if ( astOK ) { - -/* Copy pointers to the Frame and Mapping supplied and store these pointers - in the FrameSet arrays. */ - this->frame[ this->nframe ] = astCopy( frame ); - this->map[ this->nnode - 1 ] = astCopy( map ); - -/* Indicate the Frame does not reflect the variant Mappings of any other - Frame. */ - this->varfrm[ this->nframe ] = 0; - -/* Associate the Frame with the Mapping via the "node" array. */ - this->node[ this->nframe ] = this->nnode; - -/* Add a "link" value which identifies the node from which the new - node is derived and store the current value of the Invert attribute - for the Mapping. */ - this->link[ this->nnode - 1 ] = this->node[ iframe - 1 ]; - this->invert[ this->nnode - 1 ] = astGetInvert( map ); - -/* If successful, increment the FrameSet's Frame and node counts and - set the Current attribute so that the new Frame becomes the current - Frame. */ - if ( astOK ) { - this->nframe++; - this->nnode++; - astSetCurrent( this, this->nframe ); - -/* If an error occurred while filling the FrameSet's arrays, clear any values - that may have been added, annulling any copied pointers. */ - } else { - this->frame[ this->nframe ] = - astAnnul( this->frame[ this->nframe ] ); - this->node[ this->nframe ] = -1; - this->map[ this->nnode - 1 ] = - astAnnul( this->map[ this->nnode - 1 ] ); - this->link[ this->nnode - 1 ] = -1; - } - } - -/* FrameSet supplied. */ -/* ================== */ -/* If the Frame supplied is a FrameSet, we handle this as a special - case by merging the two FrameSets (so that the final result - contains references to all the Frames from both FrameSets). */ - } else if ( astOK ) { - -/* Obtain a pointer to the FrameSet structure containing the new Frame - references and calculate how many Frames and nodes the combined - FrameSet will contain. */ - frameset = (AstFrameSet *) frame; - nframe = this->nframe + frameset->nframe; - nnode = this->nnode + frameset->nnode; - -/* Extend the original FrameSet's arrays to accommodate the new Frames - and nodes. */ - this->frame = astGrow( this->frame, nframe, sizeof( AstFrame * ) ); - this->varfrm = astGrow( this->varfrm, nframe, sizeof( int ) ); - this->node = astGrow( this->node, nframe, sizeof( int ) ); - this->map = astGrow( this->map, nnode - 1, sizeof( AstMapping * ) ); - this->link = astGrow( this->link, nnode - 1, sizeof( int ) ); - this->invert = astGrow( this->invert, nnode - 1, sizeof( int ) ); - -/* If OK, loop to transfer the new Frame data into the new array - elements, cloning each Frame pointer. Increment each "node" value - to allow for the new node numbering which will apply when the new - node data is appended to the new arrays. */ - if ( astOK ) { - for ( ifr = 1; ifr <= frameset->nframe; ifr++ ) { - this->frame[ this->nframe + ifr - 1 ] = - astCopy( frameset->frame[ ifr - 1 ] ); - this->node[ this->nframe + ifr - 1 ] = - frameset->node[ ifr - 1 ] + this->nnode; - if( frameset->varfrm[ ifr - 1 ] > 0 ) { - this->varfrm[ this->nframe + ifr - 1 ] = - frameset->varfrm[ ifr - 1 ] + this->nframe; - } else { - this->varfrm[ this->nframe + ifr - 1 ] = 0; - } - } - -/* Similarly, transfer the new node data, cloning each Mapping - pointer. Increment each "link" value to allow for the new node - numbering. */ - for ( inode = 1; inode < frameset->nnode; inode++ ) { - this->map[ this->nnode + inode - 1 ] = - astCopy( frameset->map[ inode - 1 ] ); - this->link[ this->nnode + inode - 1 ] = - frameset->link[ inode - 1 ] + this->nnode; - this->invert[ this->nnode + inode - 1 ] = - frameset->invert[ inode - 1 ]; - } - -/* In transferring the node data (above), we left an empty array - element which will later be filled with data corresponding to node - zero in the new FrameSet (there are no data to be copied for this - node). Initialise the data for this element to null values. */ - this->map[ this->nnode - 1 ] = NULL; - this->link[ this->nnode - 1 ] = -1; - this->invert[ this->nnode - 1 ] = -1; - -/* Determine which is the current Frame in the new FrameSet and - convert this into the corresponding Frame number in the combined - one. */ - current = astGetCurrent( frameset ) + this->nframe; - -/* We must now form a new link between this Frame and Frame "iframe" - (using the Mapping supplied) in order to inter-relate the Frames - from the two FrameSets. However, this cannot be done immediately - because in general the node corresponding to Frame "current" will - already have a link pointing to another node. Moreover, the node - which was originally node zero (in the new FrameSet) still has - no data in our merged FrameSet. - - To overcome this, we must re-structure the links within the - transferred data. We do this by starting at the node corresponding - to Frame "current" and working back through each link until the - original node zero is reached. At each step along this path, we - reverse the direction of the link. This involves shifting the - associated data by one step along the path, so that it becomes - associated with the next node. This results in the final - (initialised-to-null) node acquiring some data, and the starting - node being left free to receive our new link. - - We compensate for reversing the links by reversing the sense of the - "invert" flag associated with each Mapping along the path, so that - the overall structure of the FrameSet is unchanged. */ - -/* Identify the starting node (the one corresponding to Frame - "current"). */ - if ( astOK ) { - current_node = this->node[ current - 1 ]; - -/* Obtain the value which a "link" element will now have if it - originally identified node zero in the new FrameSet. We will use - this value to detect the end of the path. */ - node_zero = this->nnode; - -/* If we are not already at "node zero", save the data for the current - node. */ - if ( current_node != node_zero ) { - inode_map = this->map[ current_node - 1 ]; - inode_link = this->link[ current_node - 1 ]; - inode_invert = this->invert[ current_node - 1 ]; - -/* Reset the node's data to null values (pending setting up the new - link using the Mapping supplied). */ - this->map[ current_node - 1 ] = NULL; - this->link[ current_node - 1 ] = -1; - this->invert[ current_node - 1 ] = -1; - -/* Identify the next node in the path. */ - next = inode_link; - } - -/* Follow the path until "node zero" is reached. */ - inode = current_node; - while( inode != node_zero ) { - -/* If the next node on the path is not "node zero", save its data - (because we are about to write over it). */ - if ( next != node_zero ) { - next_map = this->map[ next - 1 ]; - next_link = this->link[ next - 1 ]; - next_invert = this->invert[ next - 1 ]; - } - -/* Reverse the link from the current node to the "next" node. This - involves transferring the "map" and "invert" values to the "next" - node and inverting the sense of the latter to compensate. Make the - "next" node point back to the current one. */ - this->map[ next - 1 ] = inode_map; - this->link[ next - 1 ] = inode; - this->invert[ next - 1 ] = !inode_invert; - -/* Move on to consider the next node. */ - inode = next; - -/* If we have not reached "node zero" yet, transfer the node data we - saved above into the variables from which it will be transferred to - the following node on the next pass through this loop. */ - if ( inode != node_zero ) { - inode_map = next_map; - inode_link = next_link; - inode_invert = next_invert; - -/* Identify the node that follows the next one. */ - next = inode_link; - } - } - -/* Once the necessary links have been re-structured, establish the new - link that inter-relates the Frames from the two FrameSets. */ - this->map[ current_node - 1 ] = astCopy( map ); - this->link[ current_node - 1 ] = this->node[ iframe - 1 ]; - this->invert[ current_node - 1 ] = astGetInvert( map ); - } - -/* If successful, update the Frame and node counts and make the - appropriate Frame current. */ - if ( astOK ) { - this->nframe = nframe; - this->nnode = nnode; - astSetCurrent( this, current ); - -/* If an error occurred, loop through all the new Frame and node array - elements and clear them, ensuring that any remaining Object - pointers are annulled. */ - } else { - for ( ifr = 1; ifr <= frameset->nframe; ifr++ ) { - this->frame[ this->nframe + ifr - 1 ] = - astAnnul( this->frame[ this->nframe + ifr - 1 ] ); - this->node[ this->nframe + ifr - 1 ] = -1; - this->varfrm[ this->nframe + ifr - 1 ] = 0; - } - for ( inode = 0; inode < frameset->nnode; inode++ ) { - this->map[ this->nnode + inode - 1 ] = - astAnnul( this->map[ this->nnode + inode - 1 ] ); - this->link[ this->nnode + inode - 1 ] = -1; - this->invert[ this->nnode + inode - 1 ] = -1; - } - } - } - } - -/* Annul the local pointer to the supplied Mapping. */ - map = astAnnul( map ); -} - -static void AddVariant( AstFrameSet *this, AstMapping *map, - const char *name, int *status ) { -/* -*++ -* Name: -c astAddVariant -f AST_ADDVARIANT - -* Purpose: -* Store a new variant Mapping for the current Frame in a FrameSet. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c void astAddVariant( AstFrameSet *this, AstMapping *map, -c const char *name ) -f CALL AST_ADDVARIANT( THIS, MAP, NAME, STATUS ) - -* Class Membership: -* FrameSet method. - -* Description: -c This function -f This routine -* allows a new variant Mapping to be stored with the current Frame -* in a FrameSet. See the "Variant" attribute for more details. It can -* also be used to rename the currently selected variant Mapping. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FrameSet. -c map -f MAP = INTEGER (Given) -* Pointer to a Mapping which describes how to convert -* coordinates from the current Frame to the new variant of the -* current Frame. If -c NULL -f AST__NULL -* is supplied, then the name associated with the currently selected -* variant of the current Frame is set to the value supplied for -c "name", but no new variant is added. -f NAME, but no new variant is added. -c name -f NAME = CHARACTER * ( * ) (Given) -* The name to associate with the new variant Mapping (or the currently -* selected variant Mapping if -c "map" is NULL). -f MAP is AST__NULL). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The newly added Variant becomes the current variant on exit (this is -* equivalent to setting the Variant attribute to the value supplied for -c "name). -f NAME). -* - An error is reported if a variant with the supplied name already -* exists in the current Frame. -* - An error is reported if the current Frame is a mirror for the -* variant Mappings in another Frame. This is only the case if the -c astMirrorVariants function -f AST_MIRRORVARIANTS routine -* has been called to make the current Frame act as a mirror. - -*-- -*/ - -/* Local Variables: */ - AstCmpMap *map2; - AstFrame *frm; - AstFrame *tfrm; - AstFrame *vfrm; - AstFrameSet *tfs; - AstFrameSet *vfs; - AstMapping *map1; - AstMapping *map3; - char *myname; - const char *dom; - int icur; - int ifrm; - int new; - int nfrm; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the one-based index of the current Frame. */ - icur = astGetCurrent( this ); - -/* Report an error if the current Frame is just a mirror. */ - if( this->varfrm[ icur - 1 ] > 0 && astOK ) { - astError( AST__MIRRO, "astAddVariant(%s): Illegal attempt to " - "add a variant Mapping to a mirror Frame (programming " - "error).", status, astGetClass( this ) ); - } - -/* Get a copy of the supplied string and clean it. */ - myname = astStore( NULL, name, strlen( name ) + 1 ); - astRemoveLeadingBlanks( myname ); - astChrCase( NULL, myname, 1, 0 ); - if( astOK ) { - myname[ astChrLen( myname ) ] = 0; - -/* Get the Variants FrameSet for the current Frame in "this". */ - frm = astGetFrame( this, icur ); - vfs = astGetFrameVariants( frm ); - -/* If current Frame of this has no Variant FrameSet, create a Variants - FrameSet containing a copy of the current Frame (retain its Domain - as the default variant name). */ - if( !vfs ) { - tfrm = astCopy( frm ); - vfs = astFrameSet( tfrm, " ", status ); - tfrm = astAnnul( tfrm ); - new = 1; - } else { - new = 0; - } - -/* Check the Variants FrameSet does not already contain a Frame with - a Domain equal to the supplied name. */ - nfrm = astGetNframe( vfs ); - for( ifrm = 0; ifrm < nfrm && astOK; ifrm++ ) { - vfrm = astGetFrame( vfs, ifrm + 1 ); - dom = astGetDomain( vfrm ); - if( astOK && !strcmp( dom, myname ) ) { - astError( AST__BDVNM, "astAddVariant(%s): Cannot add a " - "variant %s Frame with name '%s' because one " - "already exists in the %s (programming " - "error).", status, astGetClass( this ), - astGetDomain( frm ), myname, astGetClass( this ) ); - } - vfrm = astAnnul( vfrm ); - } - -/* If no Mapping was supplied, just set the name of the currently - selected variant. The names are stored in the Domain attribute of - the Frames in the variants FrameSet, so set teh DOmain for the current - Frame. */ - if( !map ){ - vfrm = astGetFrame( vfs, AST__CURRENT ); - astSetDomain( vfrm, name ); - vfrm = astAnnul( vfrm ); - -/* If a Mapping was supplied.... */ - } else { - -/* Get the Mapping from the current Frame in the variants FrameSet to the - current Frame in "this". Temporarily match the Domains so that - astConvert can work. */ - vfrm = astGetFrame( vfs, AST__CURRENT ); - dom = astGetDomain( frm ); - if( dom ) dom = astStore( NULL, dom, strlen( dom ) + 1 ); - astSetDomain( frm, astGetDomain( vfrm ) ); - tfs = astConvert( vfrm, frm, "" ); - astSetDomain( frm, dom ); - if( tfs ) { - map1 = astGetMapping( tfs, AST__BASE, AST__CURRENT ); - tfs = astAnnul( tfs ); - -/* Concatenate it with the supplied Mapping to get the mapping from the - current Frame in the Variants FrameSet to the new variant Frame. */ - map2 = astCmpMap( map1, map, 1, " ", status ); - map3 = astSimplify( map2 ); - -/* Add a copy of parent Frame into Variants FrameSet, using the above - mapping to connect it to the original current Variants Frame. Set - its Domain to the supplied name. Re-instate the original current Frame - afterwards. Remove the variant frame info before adding it. */ - (void) astAnnul( vfrm ); - vfrm = astCopy( frm ); - astSetFrameVariants( vfrm, NULL ); - astSetDomain( vfrm, name ); - icur = astGetCurrent( vfs ); - astAddFrame( vfs, AST__CURRENT, map3, vfrm ); - astSetCurrent( vfs, icur ); - -/* Free resources. */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - map3 = astAnnul( map3 ); - -/* Report an error if a Mapping cannot be found from the new variant Frame - to the current Frame in "this". */ - } else if( astOK ) { - astError( AST__INTER, "astAddVariant(%s): Cannot convert " - "from a %s with Domain '%s' to a %s with Domain " - "'%s' (internal programming error).", status, - astGetClass( this ), astGetClass( vfrm ), - astGetDomain( vfrm ), astGetClass( frm ), - astGetDomain( frm ) ); - } - -/* Free resources. */ - dom = astFree( (void *) dom ); - vfrm = astAnnul( vfrm ); - } - -/* If all is well, and the Variants FrameSet is new, store a pointer to - it in the current Frame of "this". */ - if( new ) astSetFrameVariants( frm, vfs ); - -/* Make the new Variant the current variant. */ - if( map ) astSetVariant( this, name ); - -/* Free remaining resources. */ - frm = astAnnul( frm ); - vfs = astAnnul( vfs ); - } - myname = astFree( myname ); -} - -static double Angle( AstFrame *this_frame, const double a[], - const double b[], const double c[], int *status ) { -/* -* Name: -* Angle - -* Purpose: -* Calculate the angle subtended by two points at a third point. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* double Angle( AstFrame *this, const double a[], const double b[], -* const double c[], int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astAngle -* method inherited from the Frame class). - -* Description: -* This function finds the angle at point B between the line joining points -* A and B, and the line joining points C and B. These lines will in fact be -* geodesic curves appropriate to the Frame in use. For instance, in -* SkyFrame, they will be great circles. - -* Parameters: -* this -* Pointer to the Frame. -* a -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the first point. -* b -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the second point. -* c -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the third point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* astAngle -* The angle in radians, from the line AB to the line CB. If the -* Frame is 2-dimensional, it will be in the range $\pm \pi$, -* and positive rotation is in the same sense as rotation from -* the positive direction of axis 2 to the positive direction of -* axis 1. If the Frame has more than 2 axes, a positive value will -* always be returned in the range zero to $\pi$. - -* Notes: -* - A value of AST__BAD will also be returned if points A and B are -* co-incident, or if points B and C are co-incident. -* - A value of AST__BAD will also be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astAngle method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astAngle( fr, a, b, c ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static void AppendAxes( AstFrameSet *this, AstFrame *frame, int *status ) { -/* -* Name: -* AppendAxes - -* Purpose: -* Append axes to every Frame in a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void AppendAxes( AstFrameSet *this, AstFrame *frame, int *status ) - -* Class Membership: -* FrameSet member function - -* Description: -* This function replaces every Frame in the FrameSet with a CmpFrame -* holding the original Frame and the supplied Frame. It also replaces -* every Mapping in the FrameSet with a parallel CmpMap holding the -* original Mapping and a UnitMap. The Nin and Nout attributes of every -* UnitMap are equal to the number of axes in the supplied Frame. Each -* CmpMap is simplified before being stored in the FrameSet. - - -* Parameters: -* this -* Pointer to the Frame. -* frame -* Pointer to a Frame holding the new axes to add to every Frame in -* the FrameSet. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstCmpFrame *frm; /* Pointer to new Frame */ - AstCmpMap *map; /* UnitMap to new Mapping */ - AstUnitMap *umap; /* UnitMap to feed the new axes */ - int iframe; /* Frame index */ - int imap; /* Mapping index */ - int inv_orig; /* Original value of Invert attribute */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Loop round every Frame in the FrameSet. */ - for ( iframe = 0; iframe < this->nframe; iframe++ ) { - -/* Create a CmpFrame holding the original Frame and the new Frame. */ - frm = astCmpFrame( this->frame[ iframe ], frame, " ", status ); - -/* Annul the original Frame pointer and store the new CmpFrame pointer. */ - (void) astAnnul( this->frame[ iframe ] ); - this->frame[ iframe ] = (AstFrame *) frm; - } - -/* Create a UnitMap with the number of inputs and outputs equal to the - number of axes in the supplied Frame. */ - umap = astUnitMap( astGetNaxes( frame ), " ", status ); - -/* Loop round every Mapping in the FrameSet. */ - for ( imap = 0; imap < this->nnode - 1; imap++ ) { - -/* The Invert attribute of the Mapping may have been changed via a - different pointer since it was first added into the FrameSet. To - ensure that the FrameSet continues to behave as was originally - intended, we set the Invert attribute back to the value it had when - the Mapping was first added into the FrameSet. First, note the - current value of the Invert flag so that it can be re-instated later. */ - inv_orig = astGetInvert( this->map[ imap ] ); - astSetInvert( this->map[ imap ], this->invert[ imap ] ); - -/* Create a parallel CmpMap holding the original Mapping and the UnitMap. */ - map = astCmpMap( this->map[ imap ], umap, 0, " ", status ); - -/* Re-instate the original value for the Invert flag, and then annul the - original Mapping pointer. */ - astSetInvert( this->map[ imap ], inv_orig ); - (void) astAnnul( this->map[ imap ] ); - -/* Simplify the new Mapping, and store it in the FrameSet. */ - this->map[ imap ] = astSimplify( map ); - -/* Store a copy of the Invert attribute that should be used with this - Mapping within the FrameSet (just in case it is modified via some - excternal reference). */ - this->invert[ imap ] = astGetInvert( this->map[ imap ] ); - -/* Annul the un-simplified Mapping pointer. */ - map = astAnnul( map ); - } - -/* Annul the UnitMap pointer. */ - umap = astAnnul( umap ); -} - -static double AxAngle( AstFrame *this_frame, const double a[], const double b[], int axis, int *status ) { -/* -* Name: -* AxAngle - -* Purpose: -* Returns the angle from an axis, to a line through two points. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* double AxAngle( AstFrame *this, const double a[], const double b[], int axis, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astAxAngle -* method inherited from the Frame class). - -* Description: -* This function finds the angle, as seen from point A, between the positive -* direction of a specified axis, and the geodesic curve joining point -* A to point B. - -* Parameters: -* this -* Pointer to the Frame. -* a -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the first point. -* b -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the second point. -* axis -* The number of the Frame axis from which the angle is to be -* measured (one-based). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The angle in radians, from the positive direction of the -* specified axis, to the line AB. If the Frame is 2-dimensional, -* it will be in the range $\pm \pi$, and positive rotation is in -* the same sense as rotation from the positive direction of axis 2 -* to the positive direction of axis 1. If the Frame has more than 2 -* axes, a positive value will always be returned in the range zero -* to $\pi$. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value, or if the require -* position angle is undefined. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxAngle" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astAxAngle method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astAxAngle( fr, a, b, axis ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static double AxDistance( AstFrame *this_frame, int axis, double v1, double v2, int *status ) { -/* -* Name: -* AxDistance - -* Purpose: -* Find the distance between two axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* double AxDistance( AstFrame *this, int axis, double v1, double v2, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astAxDistance -* method inherited from the Frame class). - -* Description: -* This function returns a signed value representing the axis increment -* from axis value v1 to axis value v2. -* -* For a simple Frame, this is a trivial operation returning the -* difference between the two axis values. But for other derived classes -* of Frame (such as a SkyFrame) this is not the case. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The index of the axis to which the supplied values refer. The -* first axis has index 1. -* v1 -* The first axis value. -* v2 -* The second axis value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The distance between the two axis values. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input vaues has this value. -* - A "bad" value will also be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxDistance" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astAxDistance method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astAxDistance( fr, axis, v1, v2 ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static void AxNorm( AstFrame *this_frame, int axis, int oper, int nval, - double *values, int *status ){ -/* -* Name: -* AxNorm - -* Purpose: -* Normalise an array of axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void AxNorm( AstFrame *this, int axis, int oper, int nval, -* double *values, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astAxNorm -* method inherited from the Frame class). - -* Description: -* This function modifies a supplied array of axis values so that -* they are normalised in the manner indicated by parameter "oper". -* -* No normalisation is possible for a simple Frame and so the supplied -* values are returned unchanged. However, this may not be the case for -* specialised sub-classes of Frame. For instance, a SkyFrame has a -* discontinuity at zero longitude and so a longitude value can be -* expressed in the range [-Pi,+PI] or the range [0,2*PI]. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The index of the axis to which the supplied values refer. The -* first axis has index 1. -* oper -* Indicates the type of normalisation to be applied. If zero is -* supplied, the normalisation will be the same as that performed by -* function astNorm. If 1 is supplied, the normalisation will be -* chosen automatically so that the resulting list has the smallest -* range. -* nval -* The number of points in the values array. -* values -* On entry, the axis values to be normalised. Modified on exit to -* hold the normalised values. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxNorm" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astAxNorm method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astAxNorm( fr, axis, oper, nval, values ); - fr = astAnnul( fr ); -} - -static double AxOffset( AstFrame *this_frame, int axis, double v1, double dist, int *status ) { -/* -* Name: -* AxOffset - -* Purpose: -* Add an increment onto a supplied axis value. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* double AxOffset( AstFrame *this, int axis, double v1, double dist, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astAxOffset -* method inherited from the Frame class). - -* Description: -* This function returns an axis value formed by adding a signed axis -* increment onto a supplied axis value. -* -* For a simple Frame, this is a trivial operation returning the -* sum of the two supplied values. But for other derived classes -* of Frame (such as a SkyFrame) this is not the case. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The index of the axis to which the supplied values refer. The -* first axis has index 1. -* v1 -* The original axis value. -* dist -* The axis increment to add to the original axis value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The incremented axis value. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input vaues has this value. -* - A "bad" value will also be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxOffset" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astAxOffset method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astAxOffset( fr, axis, v1, dist ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static AstObject *Cast( AstObject *this_object, AstObject *obj, int *status ) { -/* -* Name: -* Cast - -* Purpose: -* Cast an Object into an instance of a sub-class. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstObject *Cast( AstObject *this, AstObject *obj, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astCast -* method inherited from the Frame class). - -* Description: -* This function returns a deep copy of an ancestral component of the -* supplied object. The required class of the ancestral component is -* specified by another object. Specifically, if "this" and "new" are -* of the same class, a copy of "this" is returned. If "this" is an -* instance of a subclass of "obj", then a copy of the component -* of "this" that matches the class of "obj" is returned. Otherwise, -* a NULL pointer is returned without error. - -* Parameters: -* this -* Pointer to the Object to be cast. -* obj -* Pointer to an Object that defines the class of the returned Object. -* The returned Object will be of the same class as "obj". - -* Returned Value: -* A pointer to the new Object. NULL if "this" is not a sub-class of -* "obj", or if an error occurs. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables; */ - AstFrame *cfrm; - AstObject *new; - astDECLARE_GLOBALS - int generation_gap; - -/* Initialise */ - new = NULL; - -/* Check inherited status */ - if( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* See how many steps up the class inheritance ladder it is from "obj" - to this class (FrameSet). A positive value is returned if FrameSet - is a sub-class of "obj". A negative value is returned if "obj" is - a sub-class of FrameSet. Zero is returned if "obj" is a FrameSet. - AST__COUSIN is returned if "obj" is not on the same line of descent - as FrameSet. */ - generation_gap = astClassCompare( (AstObjectVtab *) &class_vtab, - astVTAB( obj ) ); - -/* If "obj" is a FrameSet or a sub-class of FrameSet, we can cast by - truncating the vtab for "this" so that it matches the vtab of "obJ", - and then taking a deep copy of "this". */ - if( generation_gap <= 0 && generation_gap != AST__COUSIN ) { - new = astCastCopy( this_object, obj ); - -/* If "obj" is not a FrameSet or a sub-class of FrameSet (e.g. a Frame or - some sub-class of Frame), we attempt to cast the current Frame into - the class indicated by "obj". */ - } else { - cfrm = astGetFrame( (AstFrameSet *) this_object, AST__CURRENT ); - new = astCast( cfrm, obj ); - cfrm = astAnnul( cfrm ); - } - -/* Return the new pointer. */ - return new; -} - -static double Centre( AstFrame *this_frame, int axis, double value, double gap, int *status ) { -/* -* Name: -* Centre - -* Purpose: -* Find a "nice" central value for tabulating Frame axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* double Centre( AstFrame *this_frame, int axis, double value, -* double gap, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astCentre method -* inherited from the Frame class). - -* Description: -* This function returns an axis value which produces a nice formatted -* value suitable for a major tick mark on a plot axis, close to the -* supplied axis value. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which a central value -* is to be found. -* value -* An arbitrary axis value in the section that is being plotted. -* gap -* The gap size. - -* Returned Value: -* The nice central axis value. - -* Notes: -* - A value of zero is returned if the supplied gap size is zero. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astCentre" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astCentre method to obtain the required value. Annul the - Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astCentre( fr, axis, value, gap ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static void CheckPerm( AstFrame *this_frame, const int *perm, const char *method, int *status ) { -/* -* Name: -* CheckPerm - -* Purpose: -* Check that an array contains a valid permutation. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void CheckPerm( AstFrame *this, const int *perm, const char *method, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astCheckPerm -* method inherited from the Frame class). - -* Description: -* This function checks the validity of a permutation array that -* will be used to permute the order of a Frame's axes. If the -* permutation specified by the array is not valid, an error is -* reported and the global error status is set. Otherwise, the -* function returns without further action. - -* Parameters: -* this -* Pointer to the Frame. -* perm -* Pointer to an array of integers with the same number of -* elements as there are axes in the Frame. For each axis, the -* corresponding integer gives the (zero based) axis index to be -* used to identify the information for that axis (using the -* un-permuted axis numbering). To be valid, the integers in -* this array should therefore all lie in the range zero to -* (naxes-1) inclusive, where "naxes" is the number of Frame -* axes, and each value should occur exactly once. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate a permutation array. This method name is used -* solely for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Error messages issued by this function refer to the external -* (public) numbering system used for axes (which is one-based), -* whereas zero-based axis indices are used internally. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astCheckPerm method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astCheckPerm( fr, perm, method ); - fr = astAnnul( fr ); - -} - -static void Clear( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* Clear - -* Purpose: -* Clear attribute values for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void Clear( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the public astClear method -* inherited from the Object class). - -* Description: -* This function clears the values of a specified set of attributes -* for a FrameSet. Clearing an attribute cancels any value that has -* previously been explicitly set for it, so that the standard -* default attribute value will subsequently be used instead. This -* also causes the astTest function to return the value zero for -* the attribute, indicating that no value has been set. - -* Parameters: -* this -* Pointer to the FrameSet. -* attrib -* Pointer to a null-terminated character string containing a -* comma-separated list of the names of the attributes to be -* cleared. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function preserves the integrity of the FrameSet (if -* possible) by appropriately remapping its current Frame to take -* account of its changed attribute values. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFrame *save_frame; /* Saved pointer to integrity Frame */ - AstFrameSet *this; /* Pointer to FrameSet structure */ - const char *save_method; /* Saved pointer to method name */ - int ok; /* Status OK? */ - int save_lost; /* Saved integrity modified flag */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* To allow this function to be invoked recursively, we first save any - existing FrameSet integrity information in local variables. */ - save_frame = integrity_frame; - save_lost= integrity_lost; - save_method = integrity_method; - -/* Set the name of the method being used (for use in error - messages). */ - integrity_method = "astClear"; - -/* Record the initial integrity state of the FrameSet. */ - RecordIntegrity( this, status ); - -/* Invoke the parent astClear method to clear the FrameSet's attribute - values and note if this succeeds. */ - (*parent_clear)( this_object, attrib, status ); - ok = astOK; - -/* Restore the FrameSet's integrity. */ - RestoreIntegrity( this, status ); - -/* If integrity could not be restored, then add contextual error - information. */ - if ( !astOK && ok ) { - astError( astStatus, "Unable to accommodate clearing the \"%s\" " - "attribute(s).", status, attrib ); - } - -/* Restore any saved FrameSet integrity information. */ - integrity_frame = save_frame; - integrity_lost = save_lost; - integrity_method = save_method; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void ClearAttrib( AstObject *this, const char *attrib ) - -* Class Membership: -* FrameSet member function (over-rides the astClearAttrib protected -* method inherited from the Frame class). - -* Description: -* This function clears the value of a specified attribute for a -* FrameSet, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the FrameSet. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* We first handle attributes that apply to the FrameSet as a whole - (rather than to the current Frame). */ - -/* Base. */ -/* ----- */ - if ( !strcmp( attrib, "base" ) ) { - astClearBase( this ); - -/* Current. */ -/* -------- */ -/* Since this determines the choice of current Frame, we must restore - the integrity state of the FrameSet before changing this attribute - and record the new integrity state afterwards. */ - } else if ( !strcmp( attrib, "current" ) ) { - RestoreIntegrity( this, status ); - astClearCurrent( this ); - RecordIntegrity( this, status ); - -/* ID. */ -/* --- */ - } else if ( !strcmp( attrib, "id" ) ) { - astClearID( this ); - -/* Ident. */ -/* ------ */ - } else if ( !strcmp( attrib, "ident" ) ) { - astClearIdent( this ); - -/* Invert. */ -/* ------- */ -/* Since this affects the choice of current Frame, we must restore the - integrity state of the FrameSet before changing this attribute and - record the new integrity state afterwards. */ - } else if ( !strcmp( attrib, "invert" ) ) { - RestoreIntegrity( this, status ); - astClearInvert( this ); - RecordIntegrity( this, status ); - -/* Report. */ -/* ------- */ - } else if ( !strcmp( attrib, "report" ) ) { - astClearReport( this ); - -/* Variant. */ -/* -------- */ - } else if ( !strcmp( attrib, "variant" ) ) { - astClearVariant( this ); - -/* If the name was not recognised, test if it matches any of the - read-only attributes of this class. If it does, then report an - error. */ - } else if ( !strcmp( attrib, "allvariants" ) || - !strcmp( attrib, "class" ) || - !strcmp( attrib, "nframe" ) || - !strcmp( attrib, "nin" ) || - !strcmp( attrib, "nobject" ) || - !strcmp( attrib, "nout" ) || - !strcmp( attrib, "refcount" ) || - !strcmp( attrib, "tranforward" ) || - !strcmp( attrib, "traninverse" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Pass unrecognised attributes on to the FrameSet's current Frame for - further interpretation. */ - } else { - -/* Force a copy to be made of the current Frame, if needed, to make it - independent of other Frames within the FrameSet. */ - (void) ForceCopy( this, AST__CURRENT, status ); - -/* Obtain a pointer to the current Frame and invoke its astClearAttrib - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astClearAttrib( fr, attrib ); - fr = astAnnul( fr ); - -/* Note that the current Frame has been modified. */ - integrity_lost = 1; - } -} - -static void ClearBase( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astClearBase - -* Purpose: -* Clear the value of the Base attribute of a FrameSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* void astClearBase( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function clears the value of the Base attribute of a -* FrameSet. This value is an index that identifies the base Frame -* for the FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. -*- -*/ - -/* Local Variables: */ - int invert; /* FrameSet is inverted? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Determine if the FrameSet has been inverted. */ - invert = astGetInvert( this ); - -/* If it has not been inverted, clear the base Frame index, otherwise - clear the current Frame index instead. */ - if ( astOK ) *( invert ? &this->current : &this->base ) = -INT_MAX; -} - -static void ClearCurrent( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astClearCurrent - -* Purpose: -* Clear the value of the Current attribute for a FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "frameset.h" -* int astClearCurrent( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function clears the value of the Current attribute for a -* FrameSet. This attribute is an index that identifies the current -* Frame for the FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. -*- -*/ - -/* Local Variables: */ - int invert; /* FrameSet is inverted? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Determine if the FrameSet has been inverted. */ - invert = astGetInvert( this ); - -/* If it has not been inverted, clear the current frame index, - otherwise clear the base Frame index instead. */ - if ( astOK ) *( invert ? &this->base : &this->current ) = -INT_MAX; -} - -static void ClearVariant( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astClearVariant - -* Purpose: -* Clear the value of the Variant attribute of a FrameSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* void astClearVariant( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function clears the value of the Variant attribute of a -* FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. -*- -*/ - -/* Local Variables: */ - AstFrame *frm; - int icur; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the one-based index of the Frame to use. */ - icur = GetVarFrm( this, astGetCurrent( this ), status ); - -/* Get a pointer to the current Frame in the FrameSet. */ - frm = astGetFrame( this, icur ); - -/* Replace any Variants FrameSet in the Frame with a NULL pointer. */ - astSetFrameVariants( frm, NULL ); - -/* Annul the current Frame pointer. */ - frm = astAnnul( frm ); - -} - -static AstMapping *CombineMaps( AstMapping *mapping1, int invert1, - AstMapping *mapping2, int invert2, - int series, int *status ) { -/* -* Name: -* CombineMaps - -* Purpose: -* Combine two Mappings with specified Invert flags into a CmpMap. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstMapping *CombineMaps( AstMapping *mapping1, int invert1, -* AstMapping *mapping2, int invert2, -* int series ) - -* Class Membership: -* FrameSet member function. - -* Description: -* This function combines two Mappings into a CmpMap (compound -* Mapping) as if their Invert flags were set to specified values -* when the CmpMap is created. However, the individual Mappings are -* returned with their Invert flag values unchanged from their -* original state. - -* Parameters: -* mapping1 -* Pointer to the first Mapping. -* invert1 -* The (boolean) Invert flag value required for the first Mapping. -* mapping2 -* Pointer to the second Mapping. -* invert2 -* The (boolean) Invert flag value required for the second Mapping. -* series -* Whether the Mappings are to be combined in series (as opposed to -* in parallel). - -* Returned Value: -* A pointer to the resulting compound Mapping (a CmpMap). - -* Notes: -* - This function is a wrap-up for the astCmpMap constructor and -* temporarily assigns the required Invert flag values while -* creating the required CmpMap. However, it also takes account of -* the possibility that the two Mapping pointers supplied may point -* at the same Mapping. -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *map1; /* First temporary Mapping pointer */ - AstMapping *map2; /* Second temporary Mapping pointer */ - AstMapping *result; /* Pointer to result Mapping */ - int copy; /* Copy needed? */ - int inv1; /* First original Invert flag value */ - int inv2; /* Second original Invert flag value */ - int set1; /* First Invert flag originally set? */ - int set2; /* Second Invert flag originally set? */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Limit incoming values to 0 or 1. */ - invert1 = ( invert1 != 0 ); - invert2 = ( invert2 != 0 ); - -/* Obtain the Invert flag values for each Mapping. */ - inv1 = astGetInvert( mapping1 ); - inv2 = astGetInvert( mapping2 ); - -/* Also determine if these values are explicitly set. */ - set1 = astTestInvert( mapping1 ); - set2 = astTestInvert( mapping2 ); - -/* If both Mappings are actually the same but we need different Invert - flag values to be set, then this can only be achieved by making a - copy. Note if this is necessary. */ - copy = ( ( mapping1 == mapping2 ) && ( invert1 != invert2 ) ); - -/* Clone the first Mapping pointer. Do likewise for the second but - make a copy instead if necessary. */ - map1 = astClone( mapping1 ); - map2 = copy ? astCopy( mapping2 ) : astClone( mapping2 ); - -/* If the Invert value for the first Mapping needs changing, make the - change. */ - if ( invert1 != inv1 ) { - if ( invert1 ) { - astSetInvert( map1, 1 ); - } else { - astClearInvert( map1 ); - } - } - -/* Similarly, change the Invert flag for the second Mapping if - necessary. */ - if ( invert2 != inv2 ) { - if ( invert2 ) { - astSetInvert( map2, 1 ); - } else { - astClearInvert( map2 ); - } - } - -/* Combine the two Mappings into a CmpMap. */ - result = (AstMapping *) astCmpMap( map1, map2, series, "", status ); - -/* If the first Mapping's Invert value was changed, restore it to its - original state. */ - if ( invert1 != inv1 ) { - if ( set1 ) { - astSetInvert( map1, inv1 ); - } else { - astClearInvert( map1 ); - } - } - -/* Similarly, restore the second Mapping's Invert value if - necessary. This step is not needed, however, if a copy was made. */ - if ( ( invert2 != inv2 ) && !copy ) { - if ( set2 ) { - astSetInvert( map2, inv2 ); - } else { - astClearInvert( map2 ); - } - } - -/* Annul the temporary Mapping pointers. */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - -/* If an error occurred, then annul the result pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstFrameSet *Convert( AstFrame *from, AstFrame *to, - const char *domainlist, int *status ) { -/* -* Name: -* Convert - -* Purpose: -* Determine how to convert between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstFrameSet *Convert( AstFrame *from, AstFrame *to, -* const char *domainlist, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the public astConvert -* method inherited fromm the Frame class). - -* Description: -* This function compares two FrameSets and determines whether it -* is possible to convert between the coordinate systems which -* their current Frames represent. If conversion is possible, it -* returns a FrameSet which describes the conversion and which may -* be used (as a Mapping) to transform coordinate values in either -* direction. -* -* If conversion is possible, the Base attributes of both FrameSets -* will be modified on exit to identify the Frames which were used -* as the intermediate coordinate system. - -* Parameters: -* from -* Pointer to a FrameSet whose current Frame represents the -* "source" coordinate system. Note that the Base attribute of -* the FrameSet may be modified by this function. -* to -* Pointer to a FrameSet whose current Frame represents the -* "destination" coordinate system. Note that the Base -* attribute of the FrameSet may be modified by this function. -* domainlist -* Pointer to a null-terminated character string containing a -* comma-separated list of Frame domains. This may be used to -* define a priority order for the different intermediate -* coordinate systems that might be used to perform the -* conversion. -* -* The function will first try to obtain a conversion by making -* use only of intermediate Frames whose Domain attribute -* matches the first domain in this list. If this fails, the -* second domain in the list will be used, and so on, until -* conversion is achieved. A blank domain (e.g. two consecutive -* commas) indicates that all Frames should be considered, -* regardless of their Domain attributes. The list is -* case-insensitive and all white space is ignored. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If the requested coordinate conversion is possible, the -* function returns a pointer to a FrameSet which describes the -* conversion. Otherwise, a null Object pointer (AST__NULL) is -* returned without error. -* -* If a FrameSet is returned, it will contain two Frames. Frame -* number 1 (its base Frame) will describe the source coordinate -* system, corresponding to the "from" parameter. Frame number 2 -* (its current Frame) will describe the destination coordinate -* system, corresponding to the "to" parameter. The Mapping -* which inter-relates these Frames will perform the required -* conversion between the two coordinate systems. - -* Notes: -* - Either of the "from" and "to" pointers may identify a basic -* Frame instead of a FrameSet, in which case the function behaves -* as if it were a FrameSet containing only a single Frame. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. - -* Implementation Notes: -* - This function is simply a wrap-up for the ConvertX function -* which performs the required processing but swaps the order of the -* first two arguments. This is a trick to allow the astConvert -* method to be over-ridden by derived classes on the basis of the -* class of either of the first two arguments. -*/ - -/* Check the inherited status. */ - if ( !astOK ) return NULL; - -/* Invoke the private "ConvertX" member function with the first two - arguments swapped. */ - return ConvertX( to, from, domainlist, status ); -} - -static AstFrameSet *ConvertX( AstFrame *to, AstFrame *from, - const char *domainlist, int *status ) { -/* -* Name: -* ConvertX - -* Purpose: -* Determine how to convert between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstFrameSet *ConvertX( AstFrame *to, AstFrame *from, -* const char *domainlist ) - -* Class Membership: -* FrameSet member function (over-rides the protected "astConvertX" -* method inherited from the Frame class). - -* Description: -* This function performs the processing for the public astConvert -* method (as inherited from the Frame class and over-ridden by the -* FrameSet class) and has exactly the same interface except that -* the order of the first two arguments is swapped. This is a trick -* to allow the astConvert method to be over-ridden by derived -* classes on the basis of the class of either of its first two -* arguments. -* -* See the astConvert method for details of the interface. -*/ - -/* Local Variables: */ - AstFrame *from_frame; /* Pointer to "from" Frame */ - AstFrame *to_frame; /* Pointer to "to" Frame */ - AstFrameSet *cvt; /* Pointer to conversion FrameSet */ - AstFrameSet *result; /* Pointer to FrameSet to be returned */ - AstMapping *from_map; /* Pointer to "from" Mapping */ - AstMapping *map; /* Pointer to conversion Mapping */ - AstMapping *result_map; /* Pointer to result Mapping */ - AstMapping *tmp; /* Temporary Mapping pointer */ - AstMapping *to_map; /* Pointer to "to" Mapping */ - char *domain; /* Pointer to individual domain string */ - char *domain_end; /* Pointer to final null of domain string */ - char *domainlist_copy; /* Pointer to copy of domains list */ - int *from_order; /* List of Frame indices in search order */ - int *to_order; /* List of Frame indices in search order */ - int best_score; /* Score from best match */ - int from_base; /* Index of "from" base Frame */ - int from_current; /* Index of "from" current Frame */ - int from_index; /* Index of "from" Frame */ - int from_isframe; /* "from" is a Frame (not a FrameSet)? */ - int from_nframe; /* Number of "from" Frames */ - int from_number; /* Loop counter for "from" Frames */ - int iframe_from; /* Index of best "from" Frame */ - int iframe_to; /* Index of best "to" Frame */ - int match; /* Possible match found? */ - int n; /* Count of Frames */ - int perfect; /* Perfect match found? */ - int score; /* Score from latest match */ - int to_base; /* Index of "to" base Frame */ - int to_current; /* Index of "to" current Frame */ - int to_index; /* Index of "to" Frame */ - int to_isframe; /* "to" is a Frame (not a FrameSet)? */ - int to_nframe; /* Number of "to" Frames */ - int to_number; /* Loop counter for "to" Frames */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - result_map = NULL; - iframe_from = 0; - iframe_to = 0; - -/* Determine the number of Frames in "from" and the indices of its - base and current Frames. Use values of 1 if "from" is a Frame and - not a FrameSet. */ - from_isframe = !astIsAFrameSet( from ); - from_nframe = from_isframe ? 1 : astGetNframe( from ); - from_base = from_isframe ? 1 : astGetBase( from ); - from_current = from_isframe ? 1 : astGetCurrent( from ); - -/* Obtain similar values for "to". */ - to_isframe = !astIsAFrameSet( to ); - to_nframe = to_isframe ? 1 : astGetNframe( to ); - to_base = to_isframe ? 1 : astGetBase( to ); - to_current = to_isframe ? 1 : astGetCurrent( to ); - -/* Allocate memory for arrays which will hold the indices of "from" - and "to" Frames. */ - from_order = astMalloc( sizeof( int ) * (size_t) from_nframe ); - to_order = astMalloc( sizeof( int ) * (size_t) to_nframe ); - -/* Make a temporary copy of the domains list. */ - domainlist_copy = astStore( NULL, domainlist, - strlen( domainlist ) + (size_t) 1 ); - if ( astOK ) { - -/* Fill the "from_order" array with the indices of all the Frames in - "from", in the order in which they will be used for searching. Use - the base Frame first. */ - n = 0; - from_order[ n++ ] = from_base; - -/* Then add all the "from" Frames in the appropriate order, omitting - the base and current Frames. */ - if ( !astGetInvert( from ) ) { - for ( from_index = 1; from_index <= from_nframe; from_index++ ) { - if ( ( from_index != from_base ) && - ( from_index != from_current ) ) { - from_order[ n++ ] = from_index; - } - } - } else { - for ( from_index = from_nframe; from_index >= 1; from_index-- ) { - if ( ( from_index != from_base ) && - ( from_index != from_current ) ) { - from_order[ n++ ] = from_index; - } - } - } - -/* Finish with the current Frame, if different from the base Frame. */ - if ( from_current != from_base ) from_order[ n++ ] = from_current; - -/* Repeat this process for the "to" Frame. */ - n = 0; - to_order[ n++ ] = to_base; - if ( !astGetInvert( to ) ) { - for ( to_index = 1; to_index <= to_nframe; to_index++ ) { - if ( ( to_index != to_base ) && ( to_index != to_current ) ) { - to_order[ n++ ] = to_index; - } - } - } else { - for ( to_index = to_nframe; to_index >= 1; to_index-- ) { - if ( ( to_index != to_base ) && ( to_index != to_current ) ) { - to_order[ n++ ] = to_index; - } - } - } - if ( to_current != to_base ) to_order[ n++ ] = to_current; - -/* Loop to inspect each comma-separated field in the domains list - until an error occurs, all the domains are used up, or a match is - found. */ - domain = domainlist_copy; - match = 0; - while ( astOK && domain && !match ) { - -/* Change the comma at the end of each field to a null to terminate - the domain. */ - if ( ( domain_end = strchr( domain, ',' ) ) ) *domain_end = '\0'; - -/* For any given domain, we will ignore imperfect matches in favour of - better ones by assigning a score to each match. Initialise the best - score value for the current domain. */ - best_score = -1; - -/* Loop through each Frame in "to". Quit looping early if an error - occurs or a perfect match is found. */ - perfect = 0; - for ( to_number = 0; - astOK && !perfect && ( to_number < to_nframe ); - to_number++ ) { - -/* Permute the "to" Frame number into a Frame index to implement the - required search order, and obtain a pointer to the required "to" - Frame. */ - to_index = to_order[ to_number ]; - to_frame = to_isframe ? astClone( to ) : - astGetFrame( to, to_index ); - -/* Loop through each Frame in "from". Quit looping early if an error - occurs or a perfect match is found. */ - for ( from_number = 0; - astOK && !perfect && ( from_number < from_nframe ); - from_number++ ) { - -/* Permute the "from" Frame number into a Frame index to implement the - required search order, and obtain a pointer to the required "from" - Frame. */ - from_index = from_order[ from_number ]; - from_frame = from_isframe ? astClone( from ) : - astGetFrame( from, from_index ); - -/* Attempt to obtain a FrameSet which describes the conversion between - the selected "from" and "to" Frames and test if successful. If so, - we have a potential route to construct the overall Mapping we - want. */ - cvt = astConvert( from_frame, to_frame, domain ); - if ( astOK && cvt ) { - -/* Extract the required Mapping from the returned FrameSet. */ - map = astGetMapping( cvt, AST__BASE, AST__CURRENT ); - -/* If necessary, prefix the Mapping between the "from" current Frame - and the individual "from" Frame we have selected. */ - if ( from_index != from_current ) { - from_map = astGetMapping( from, AST__CURRENT, - from_index ); - tmp = (AstMapping *) astCmpMap( from_map, map, 1, "", status ); - from_map = astAnnul( from_map ); - map = astAnnul( map ); - map = tmp; - } - -/* Similarly, if necessary, append the Mapping between the selected - "to" Frame and the "to" current Frame. */ - if ( to_index != to_current ) { - to_map = astGetMapping( to, to_index, AST__CURRENT ); - tmp = (AstMapping *) astCmpMap( map, to_map, 1, "", status ); - to_map = astAnnul( to_map ); - map = astAnnul( map ); - map = tmp; - } - -/* Simplify the resulting overall Mapping (this is done here because - it may sometimes affect the attribute values used to assign a score - below). */ - tmp = astSimplify( map ); - map = astAnnul( map ); - map = tmp; - -/* Assign a score that favours Mappings with both transformations - available over those with only one, and Mappings with only a - forward transformation over those with only an inverse - transformation. */ - score = ( astGetTranForward( map ) ? 2 : 0 ) + - ( astGetTranInverse( map ) ? 1 : 0 ); - -/* If the new score is better than the previous one (or is the first - one), note that we have a possible match. */ - if ( astOK && ( score > best_score ) ) { - match = 1; - -/* Update the best score and note if it indicates a perfect match (in - which case we can stop searching at this point). */ - best_score = score; - perfect = ( best_score >= 3 ); - -/* Annul any previous result Mapping pointer and replace it with this - better one. */ - if ( result_map ) result_map = astAnnul( result_map ); - result_map = astClone( map ); - -/* Note which "from" and "to" Frames were used. */ - iframe_from = from_index; - iframe_to = to_index; - } - -/* Annul pointers to the intermediate Objects. */ - map = astAnnul( map ); - cvt = astAnnul( cvt ); - } - from_frame = astAnnul( from_frame ); - } - to_frame = astAnnul( to_frame ); - } - -/* Go on to consider the next field in the domains list. */ - domain = domain_end ? domain_end + 1 : NULL; - } - } - -/* Free the memory allocated for temporary arrays. */ - domainlist_copy = astFree( domainlist_copy ); - from_order = astFree( from_order ); - to_order = astFree( to_order ); - -/* If a result is being returned, then obtain a pointer to the current - "from" Frame and use it to start constructing the result - FrameSet. */ - if ( result_map ) { - from_frame = from_isframe ? astClone( from ) : - astGetFrame( from, AST__CURRENT ); - result = astFrameSet( from_frame, "", status ); - from_frame = astAnnul( from_frame ); - -/* Similarly. obtain a pointer to the current "to" frame and add it to - the result FrameSet (related to the base Frame by the result - Mapping). */ - to_frame = to_isframe ? astClone( to ) : - astGetFrame( to, AST__CURRENT ); - astAddFrame( result, AST__BASE, result_map, to_frame ); - to_frame = astAnnul( to_frame ); - -/* Annul the result Mapping pointer. */ - result_map = astAnnul( result_map ); - } - -/* If successful, and a FrameSet is being returned, then set the base - Frames of "from" and "to" (if they are FrameSets) to indicate the - route used to generate the result Mapping. */ - if ( astOK && result ) { - if ( !from_isframe ) astSetBase( from, iframe_from ); - if ( !to_isframe ) astSetBase( to, iframe_to ); - } - -/* If an error occurred, annul the returned FrameSet pointer. */ - if ( !astOK && result ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static double Distance( AstFrame *this_frame, - const double point1[], const double point2[], int *status ) { -/* -* Name: -* Distance - -* Purpose: -* Calculate the distance between two points. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* double Distance( AstFrame *this, -* const double point1[], const double point2[], int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astDistance -* method inherited from the Frame class). - -* Description: -* This function finds the distance between two points whose -* FrameSet coordinates are given. The distance calculated is that -* along the geodesic curve that joins the two points. - -* Parameters: -* this -* Pointer to the FrameSet. -* point1 -* An array of double, with one element for each FrameSet axis -* containing the coordinates of the first point. -* point2 -* An array of double, with one element for each FrameSet axis -* containing the coordinates of the second point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The distance between the two points. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input coordinates has this value. -* - A "bad" value will also be returned if this function is -* invoked with the AST error status set or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astDistance method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astDistance( fr, point1, point2 ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two FrameSets are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astEqual protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two FrameSets are equivalent. - -* Parameters: -* this -* Pointer to the first FrameSet. -* that -* Pointer to the second FrameSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the FrameSets are equivalent, zero otherwise. - -* Notes: -* - The two FrameSets are considered equivalent if all the encapsulated -* Frames are equal and all the encapsulated Mappings are equal. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrameSet *that; /* Pointer to the second FrameSet structure */ - AstFrameSet *this; /* Pointer to the first FrameSet structure */ - int i; /* Loop index */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Checks that the second object is of the same class as the first . */ - if( !strcmp( astGetClass( this_object ), astGetClass( that_object ) ) ){ - -/* Obtain pointers to the two FrameSet structures. */ - this = (AstFrameSet *) this_object; - that = (AstFrameSet *) that_object; - -/* Check the number of nodes and frames are equal. Also check the indices - of the base and current Frames are equal */ - if( this->nframe == that->nframe && - this->nnode == that->nnode && - this->base == that->base && - this->current == that->current ) { - -/* Check the Frames and nodes are equal. */ - result = 1; - for ( i = 0; i < this->nframe; i++ ) { - if( !astEqual( this->frame[ i ], that->frame[ i ] ) || - this->node[ i ] != that->node[ i ] ){ - result = 0; - break; - } - } - -/* Check the Mappings, links and invert flags are equal. */ - if( result ) { - for ( i = 0; i < this->nnode - 1; i++ ) { - if( !astEqual( this->map[ i ], that->map[ i ] ) || - this->link[ i ] != that->link[ i ] || - this->invert[ i ] != that->invert[ i ] ) { - result = 0; - break; - } - } - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int Fields( AstFrame *this_frame, int axis, const char *fmt, - const char *str, int maxfld, char **fields, - int *nc, double *val, int *status ) { -/* -*+ -* Name: -* astFields - -* Purpose: -* Identify numerical fields within a formatted FrameSet axis value. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* int astFields( AstFrame *this, int axis, const char *fmt, -* const char *str, int maxfld, char **fields, -* int *nc, double *val ) - -* Class Membership: -* FrameSet member function (over-rides the protected astFields -* method inherited from the Frame class). - -* Description: -* This function identifies the numerical fields within a FrameSet axis -* value that has been formatted using astAxisFormat. It assumes that -* the value was formatted using the supplied format string. It also -* returns the equivalent floating point value. - -* Parameters: -* this -* Pointer to the FrameSet. -* axis -* The number of the FrameSet axis for which the values have been -* formatted (axis numbering starts at zero for the first axis). -* fmt -* Pointer to a constant null-terminated string containing the -* format used when creating "str". -* str -* Pointer to a constant null-terminated string containing the -* formatted value. -* maxfld -* The maximum number of fields to identify within "str". -* fields -* A pointer to an array of at least "maxfld" character pointers. -* Each element is returned holding a pointer to the start of the -* corresponding field in "str" (in the order in which they occur -* within "str"), or NULL if no corresponding field can be found. -* nc -* A pointer to an array of at least "maxfld" integers. Each -* element is returned holding the number of characters in the -* corresponding field, or zero if no corresponding field can be -* found. -* val -* Pointer to a location at which to store the value -* equivalent to the returned field values. If this is NULL, -* it is ignored. - -* Returned Value: -* The number of fields succesfully identified and returned. - -* Notes: -* - Leading and trailing spaces are ignored. -* - If the formatted value is not consistent with the supplied format -* string, then a value of zero will be returned, "fields" will be -* returned holding NULLs, "nc" will be returned holding zeros, and -* "val" is returned holding VAL__BAD. -* - Fields are counted from the start of the formatted string. If the -* string contains more than "maxfld" fields, then trailing fields are -* ignored. -* - If this function is invoked with the global error status set, or -* if it should fail for any reason, then a value of zero will be returned -* as the function value, and "fields", "nc" and "val" will be returned -* holding their supplied values -*- -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - int result; /* Result field count to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astFields" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astFields method to perform the processing. Annul the Frame - pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astFields( fr, axis, fmt, str, maxfld, fields, nc, val ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static AstFrameSet *FindFrame( AstFrame *target_frame, AstFrame *template, - const char *domainlist, int *status ) { -/* -* Name: -* FindFrame - -* Purpose: -* Find a coordinate system with specified characteristics. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstFrameSet *FindFrame( AstFrame *target, AstFrame *template, -* const char *domainlist, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astFindFrame method -* inherited from the Frame class). - -* Description: -* This function uses a "template" Frame to search a FrameSet to -* identify a coordinate system which has a specified set of -* characteristics. If a suitable coordinate system can be found, -* the function returns a pointer to a FrameSet which describes the -* required coordinate system and how to convert coordinates to and -* from it. - -* Parameters: -* target -* Pointer to the target FrameSet. Note that if a suitable -* coordinate system is found, then the FrameSet's Current -* attribute will be modified to indicate which Frame was used -* to obtain attribute values which were not specified by the -* template. -* template -* Pointer to the template Frame, which should be an instance of -* the type of Frame you wish to find. -* domainlist -* Pointer to a null-terminated character string containing a -* comma-separated list of Frame domains. This may be used to -* establish a priority order for the different types of -* coordinate system that might be found. -* -* The function will first try to find a suitable coordinate -* system whose Domain attribute equals the first domain in this -* list. If this fails, the second domain in the list will be -* used, and so on, until a result is obtained. A blank domain -* (e.g. two consecutive commas) indicates that any coordinate -* system is acceptable (subject to the template) regardless of -* its domain. -* -* This list is case-insensitive and all white space is ignored. -* If you do not wish to restrict the domain in this way, you -* should supply an empty string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If the search is successful, the function returns a pointer to a -* FrameSet which contains the Frame found and a description of how -* to convert to (and from) the coordinate system it -* represents. Otherwise, a null Object pointer (AST__NULL) is -* returned without error. -* -* If a FrameSet is returned, it will contain two Frames. Frame -* number 1 (its base Frame) represents the target coordinate -* system and will be the same as the (base Frame of the) -* target. Frame number 2 (its current Frame) will be a Frame -* representing the coordinate system which the function found. The -* Mapping which inter-relates these two Frames will describe how -* to convert between their respective coordinate systems. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *base_frame; /* Pointer to target base Frame */ - AstFrame *frame; /* Pointer to result Frame */ - AstFrame *selected_frame; /* Pointer to selected target Frame */ - AstFrameSet *found; /* FrameSet pointer (result of search) */ - AstFrameSet *result; /* Pointer to result FrameSet */ - AstFrameSet *target; /* Pointer to target FrameSet structure */ - AstMapping *map; /* Pointer to result Mapping */ - AstMapping *prefix; /* Pointer to prefix Mapping */ - AstMapping *tmp; /* Temporary Mapping pointer */ - char *domain; /* Pointer to individual domain field */ - char *domain_end; /* Pointer to null at end of domain */ - char *domainlist_copy; /* Pointer to copy of domains list */ - int *target_order; /* Array of indices defining search order */ - int match; /* Match obtained? */ - int n; /* Count of target_order elements */ - int target_base; /* Index of target base Frame */ - int target_current; /* Index of target current Frame */ - int target_index; /* Index of selected target Frame */ - int target_nframe; /* Number of Frames in target FrameSet */ - int target_number; /* Loop index for search */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - target_index = 0; - -/* Obtain a pointer to the target FrameSet structure. */ - target = (AstFrameSet *) target_frame; - -/* Determine the number of Frames in the target FrameSet and the - indices of the current and base Frames. */ - target_nframe = astGetNframe( target ); - target_current = astGetCurrent( target ); - target_base = astGetBase( target ); - -/* Allocate an array to hold a list of all the target Frame indices. */ - target_order = astMalloc( sizeof( int ) * (size_t) target_nframe ); - -/* Make a temporary copy of the domains list. */ - domainlist_copy = astStore( NULL, domainlist, - strlen( domainlist ) + (size_t) 1 ); - if ( astOK ) { - -/* Form a list of the indices of all the Frames in the target in the - order they will be searched for a match. Add the current Frame - index first. */ - n = 0; - target_order[ n++ ] = target_current; - -/* Follow this by the base Frame index, if different. */ - if ( target_base != target_current ) target_order[ n++ ] = target_base; - -/* Then add all the remaining target Frame indices. */ - for ( target_index = 1; target_index <= target_nframe; target_index++ ) { - if ( ( target_index != target_current ) && - ( target_index != target_base ) ) { - target_order[ n++ ] = target_index; - } - } - -/* Loop to inspect each comma-separated field in the domains list - until an error occurs, all the domains are used up, or a match is - found. */ - domain = domainlist_copy; - match = 0; - while ( astOK && domain && !match ) { - -/* Change the comma at the end of each field to a null to terminate - the domain. */ - if ( ( domain_end = strchr( domain, ',' ) ) ) *domain_end = '\0'; - -/* Loop to try and match each target Frame in turn, in the order - identified above. Quit the loop early if an error occurs or a match - is found. */ - for ( target_number = 0; - astOK && !match && ( target_number < target_nframe ); - target_number++ ) { - -/* Permute the target Frame number into a Frame index to implement the - required search order. Then obtain a pointer to the selected target - Frame. */ - target_index = target_order[ target_number ]; - selected_frame = astGetFrame( target, target_index ); - -/* Search the target Frame using the template supplied, together with - the current domain. */ - found = astFindFrame( selected_frame, template, domain ); - -/* Note if a match is found, and extract pointers to the conversion - Mapping and the result Frame from the FrameSet produced. */ - if ( astOK && found ) { - match = 1; - map = astGetMapping( found, AST__BASE, AST__CURRENT ); - frame = astGetFrame( found, AST__CURRENT ); - -/* Obtain a pointer to the Mapping between the target base Frame and - the selected target Frame, and prefix this Mapping to the one - obtained above. */ - prefix = astGetMapping( target, AST__BASE, target_index ); - tmp = (AstMapping *) astCmpMap( prefix, map, 1, "", status ); - prefix = astAnnul( prefix ); - map = astAnnul( map ); - map = tmp; - -/* Simplify the resulting Mapping. */ - tmp = astSimplify( map ); - map = astAnnul( map ); - map = tmp; - -/* Obtain a pointer to the target base Frame, and use this to start - building the result FrameSet. */ - base_frame = astGetFrame( target, AST__BASE ); - result = astFrameSet( base_frame, "", status ); - base_frame = astAnnul( base_frame ); - -/* Add the result Frame, which is related to the base Frame by the - result Mapping. */ - astAddFrame( result, AST__BASE, map, frame ); - -/* Annul pointers to all intermediate Objects. */ - map = astAnnul( map ); - frame = astAnnul( frame ); - found = astAnnul( found ); - } - selected_frame = astAnnul( selected_frame ); - } - -/* Go on to consider the next field in the domains list. */ - domain = domain_end ? domain_end + 1 : NULL; - } - } - -/* Free the temporary arrays. */ - target_order = astFree( target_order ); - domainlist_copy = astFree( domainlist_copy ); - -/* If a result is being returned, set the current Frame of the target - to indicate where the result Frame was found. */ - if ( astOK && result ) astSetCurrent( target, target_index ); - -/* If an error occurred, annul any result FrameSet pointer. */ - if ( !astOK && result ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *FrameGrid( AstFrame *this_frame, int size, const double *lbnd, - const double *ubnd, int *status ){ -/* -* Name: -* FrameGrid - -* Purpose: -* Return a grid of points covering a rectangular area of a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstPointSet *FrameGrid( AstFrame *this_frame, int size, -* const double *lbnd, const double *ubnd, -* int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astFrameGrid -* method inherited from the Frame class). - -* Description: -* This function returns a PointSet containing positions spread -* approximately evenly throughtout a specified rectangular area of -* the Frame. - -* Parameters: -* this -* Pointer to the Frame. -* size -* The preferred number of points in the returned PointSet. The -* actual number of points in the returned PointSet may be -* different, but an attempt is made to stick reasonably closely to -* the supplied value. -* lbnd -* Pointer to an array holding the lower bound of the rectangular -* area on each Frame axis. The array should have one element for -* each Frame axis. -* ubnd -* Pointer to an array holding the upper bound of the rectangular -* area on each Frame axis. The array should have one element for -* each Frame axis. - -* Returned Value: -* A pointer to a new PointSet holding the grid of points. - -* Notes: -* - A NULL pointer is returned if an error occurs. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - AstPointSet *result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astFrameGrid method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astFrameGrid( fr, size, lbnd, ubnd ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int ForceCopy( AstFrameSet *this, int iframe, int *status ) { -/* -* Name: -* ForceCopy - -* Purpose: -* Force a copy to be made of a Frame, if necessary. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int ForceCopy( AstFrameSet *this, int iframe, int *status ) - -* Class Membership: -* FrameSet member function. - -* Description: -* This function examines a Frame within a FrameSet, identified by its -* Frame index. If the same Frame is found to be referenced a second time -* within the FrameSet, then the original reference is replaced with an -* independent copy of the Frame. -* -* This process supports the preservation of FrameSet integrity in cases -* where the same Frame is referenced more than once. After using this -* function, the nominated Frame's attributes may be modified without -* danger of affecting other parts of the FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. -* iframe -* The index of the Frame to be examined. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a copy of the nominated Frame was made, otherwise zero. - -* Notes: -* - Using this function a second time on the same Frame will have no -* effect, since the first usage will make the Frame independent of any -* other Frames within the FrameSet. -* - A value of zero will be returned if this function is invoked with -* the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFrame *frame; /* Pointer to Frame */ - AstFrame *tmp; /* Temporary Frame pointer */ - int ifr; /* Loop counter for Frames */ - int result; /* Value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Validate and translate the Frame index supplied. */ - iframe = astValidateFrameIndex( this, iframe, integrity_method ); - -/* If OK, obtain the corresponding Frame pointer (don't clone it). */ - if ( astOK ) { - frame = this->frame[ iframe - 1 ]; - -/* Loop to inspect each Frame in the FrameSet. */ - for ( ifr = 1; ifr <= this->nframe; ifr++ ) { - -/* If the same Frame is referenced anywhere else, then make a copy of it. */ - if ( ( ifr != iframe ) && ( this->frame[ ifr - 1 ] == frame ) ) { - tmp = astCopy( frame ); - -/* If successful, replace the original reference to the Frame with a pointer - to this copy and annul the original pointer. */ - if ( astOK ) { - this->frame[ iframe - 1 ] = tmp; - frame = astAnnul( frame ); - -/* Set the returned result. */ - if ( astOK ) result = 1; - } - -/* Quit looping once a copy has been made. */ - break; - } - } - } - -/* Return the result. */ - return result; -} - -static const char *Format( AstFrame *this_frame, int axis, double value, int *status ) { -/* -* Name: -* Format - -* Purpose: -* Format a coordinate value for a FrameSet axis. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* const char *Format( AstFrame *this, int axis, double value, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astFormat method -* inherited from the Frame class). - -* Description: -* This function returns a pointer to a string containing the -* formatted (character) version of a coordinate value for a -* FrameSet axis. The formatting applied is that specified by a -* previous invocation of the astSetFormat method. A suitable -* default format is applied if necessary. - -* Parameters: -* this -* Pointer to the FrameSet. -* axis -* The number of the axis (zero-based) for which formatting is -* to be performed. -* value -* The coordinate value to be formatted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a null-terminated string containing the formatted -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the FrameSet object, or at static memory. The contents of -* the string may be over-written or the pointer may become invalid -* following a further invocation of the same function or deletion -* of the FrameSet. A copy of the string should therefore be made -* if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astFormat" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astFormat method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astFormat( fr, axis, value ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static double Gap( AstFrame *this_frame, int axis, double gap, int *ntick, int *status ) { -/* -* Name: -* Gap - -* Purpose: -* Find a "nice" gap for tabulating FrameSet axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* double Gap( AstFrame *this, int axis, double gap, int *ntick, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astGap method -* inherited from the Frame class). - -* Description: -* This function returns a gap size which produces a nicely spaced -* series of formatted values for a FrameSet axis, the returned gap -* size being as close as possible to the supplied target gap -* size. It also returns a convenient number of divisions into -* which the gap can be divided. - -* Parameters: -* this -* Pointer to the FrameSet. -* axis -* The number of the axis (zero-based) for which a gap is to be found. -* gap -* The target gap size. -* ntick -* Address of an int in which to return a convenient number of -* divisions into which the gap can be divided. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The nice gap size. - -* Notes: -* - A value of zero is returned if the target gap size is zero. -* - A negative gap size is returned if the supplied gap size is negative. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double result; /* Gap value to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astGap" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astGap method to obtain the required gap value. Annul the - Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astGap( fr, axis, gap, ntick ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static int GetNode( AstFrameSet *this, int inode, int *nnodes, - int *iframe, AstMapping **map, int *parent, - int *status ) { -/* -*+ -* Name: -* astGetNode - -* Purpose: -* Get information about a single node in a FrameSet tree. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* int astGetNode( AstFrameSet *this, int inode, int *nnodes, -* int *iframe, AstMapping **map, int *parent ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns information about a specified node in a -* FrameSet. It is documented as protected, because it should not -* be used in general purpose software since it depends on the internal -* details of the FrameSet class. However, it is in fact public so that -* it can be used in external software that needs to know about the -* internal structure of a FrameSet (for instance, a graphical FrameSet -* visualisation system). - -* Parameters: -* this -* Pointer to the FrameSet. -* inode -* The zero-based index of the required node. -* nnodes -* Address of an int returned holding the number of nodes defined -* in the FrameSet. -* iframe -* Address of an int returned holding the one-based index of the -* Frame associated with the node. AST__NOFRAME is returned if the -* node has no Frame. -* map -* Address of a Mapping pointer returned holding a pointer to a -* deep copy of the Mapping, if any, from the parent node to the -* requested node. NULL is returned if the node has no parent. -* parent -* Address of an int returned holding the zero-based index of the -* node from which the requested node is derived. -1 is returned if -* the requested node has no parent (i.e. is the root of the tree). - -* Returned Value: -* A non-zero value is returned if the "inode" value is within bounds. -* Otherwise, zero is returned. - -*- -*/ - -/* Local Variables: */ - int jframe; - int result; - -/* Initialise returned values. */ - *nnodes = 0; - *iframe = AST__NOFRAME; - *map = NULL; - *parent = -1; - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Return the number of nodes. */ - *nnodes = this->nnode; - -/* Check the index of the requested node. */ - if( inode >= 0 && inode < this->nnode ) { - -/* Get the index of the Frame - if any - associated with the node. */ - for( jframe = 0; jframe < this->nframe; jframe++ ) { - if( this->node[ jframe ] == inode ) { - *iframe = jframe + 1; - break; - } - } - -/* Get the Mapping - if any - associated with the node. The root node - - node zero - has no mapping or parent node. */ - if( inode > 0 ) { - *map = astCopy( this->map[ inode - 1 ] ); - if( astGetInvert( *map ) != this->invert[ inode - 1 ] ) { - astSetInvert( *map, this->invert[ inode - 1 ] ); - } - -/* The index of the parent node. */ - *parent = this->link[ inode - 1 ]; - } - -/* Indicate success. */ - result = 1; - } - - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied FrameSet, -* in bytes. - -* Parameters: -* this -* Pointer to the FrameSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrameSet *this; /* Pointer to FrameSet structure */ - int result; /* Result value to return */ - int iframe; /* Loop counter for Frames */ - int inode; /* Loop counter for nodes */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - for ( iframe = 0; iframe < this->nframe; iframe++ ) { - result += astGetObjSize( this->frame[ iframe ] ); - } - - for ( inode = 0; inode < this->nnode - 1; inode++ ) { - result += astGetObjSize( this->map[ inode ] ); - } - - result += astTSizeOf( this->frame ); - result += astTSizeOf( this->varfrm ); - result += astTSizeOf( this->node ); - result += astTSizeOf( this->map ); - result += astTSizeOf( this->link ); - result += astTSizeOf( this->invert ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astGetAttrib -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a FrameSet, formatted as a character string. - -* Parameters: -* this -* Pointer to the FrameSet. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the FrameSet, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the FrameSet. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - const char *result; /* Pointer value to return */ - int base; /* Base attribute value */ - int current; /* Current attribute value */ - int invert; /* Invert attribute value */ - int nframe; /* Nframe attribute value */ - int nin; /* Nin attribute value */ - int nobject; /* Nobject attribute value */ - int nout; /* Nout attribute value */ - int ref_count; /* RefCount attribute value */ - int report; /* Report attribute value */ - int tranforward; /* TranForward attribute value */ - int traninverse; /* TranInverse attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* We first handle attributes that apply to the FrameSet as a whole - (rather than to the current Frame). */ - -/* AllVariants. */ -/* ------------ */ - if ( !strcmp( attrib, "allvariants" ) ) { - result = astGetAllVariants( this ); - -/* Base. */ -/* ----- */ - } else if ( !strcmp( attrib, "base" ) ) { - base = astGetBase( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", base ); - result = getattrib_buff; - } - -/* Class. */ -/* ------ */ - } else if ( !strcmp( attrib, "class" ) ) { - result = astGetClass( this ); - -/* Current. */ -/* -------- */ - } else if ( !strcmp( attrib, "current" ) ) { - current = astGetCurrent( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", current ); - result = getattrib_buff; - } - -/* ID. */ -/* --- */ - } else if ( !strcmp( attrib, "id" ) ) { - result = astGetID( this ); - -/* Ident. */ -/* ------ */ - } else if ( !strcmp( attrib, "ident" ) ) { - result = astGetIdent( this ); - -/* Invert. */ -/* ------- */ - } else if ( !strcmp( attrib, "invert" ) ) { - invert = astGetInvert( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", invert ); - result = getattrib_buff; - } - -/* Nframe. */ -/* ------- */ - } else if ( !strcmp( attrib, "nframe" ) ) { - nframe = astGetNframe( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", nframe ); - result = getattrib_buff; - } - -/* Nin. */ -/* ---- */ - } else if ( !strcmp( attrib, "nin" ) ) { - nin = astGetNin( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", nin ); - result = getattrib_buff; - } - -/* Nobject. */ -/* -------- */ - } else if ( !strcmp( attrib, "nobject" ) ) { - nobject = astGetNobject( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", nobject ); - result = getattrib_buff; - } - -/* Nout. */ -/* ----- */ - } else if ( !strcmp( attrib, "nout" ) ) { - nout = astGetNout( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", nout ); - result = getattrib_buff; - } - -/* RefCount. */ -/* --------- */ - } else if ( !strcmp( attrib, "refcount" ) ) { - ref_count = astGetRefCount( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ref_count ); - result = getattrib_buff; - } - -/* Report. */ -/* ------- */ - } else if ( !strcmp( attrib, "report" ) ) { - report = astGetReport( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", report ); - result = getattrib_buff; - } - -/* TranForward. */ -/* ------------ */ - } else if ( !strcmp( attrib, "tranforward" ) ) { - tranforward = astGetTranForward( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", tranforward ); - result = getattrib_buff; - } - -/* TranInverse. */ -/* ------------ */ - } else if ( !strcmp( attrib, "traninverse" ) ) { - traninverse = astGetTranInverse( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", traninverse ); - result = getattrib_buff; - } - -/* Variant. */ -/* -------- */ - } else if ( !strcmp( attrib, "variant" ) ) { - result = astGetVariant( this ); - -/* Pass unrecognised attributes on to the FrameSet's current Frame for - further interpretation. */ - } else { - -/* Obtain a pointer to the current Frame and invoke its astGetAttrib - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astGetAttrib( fr, attrib ); - fr = astAnnul( fr ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static AstAxis *GetAxis( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetAxis - -* Purpose: -* Obtain a pointer to a specified Axis from a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstAxis *GetAxis( AstFrame *this, int axis, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astGetAxis method -* inherited from the Frame class). - -* Description: -* This function returns a pointer to the Axis object associated -* with one of the axes of the current Frame of a FrameSet. This -* object describes the quantity which is represented along that -* axis. - -* Parameters: -* this -* Pointer to the FrameSet. -* axis -* The number of the axis (zero-based) for which an Axis pointer -* is required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the requested Axis object. - -* Notes: -* - The reference count of the requested Axis object will be -* incremented by one to reflect the additional pointer returned by -* this function. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstAxis *result; /* Pointer to Axis */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astGetAxis" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astGetAxis method to obtain the required Axis - pointer. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astGetAxis( fr, axis ); - fr = astAnnul( fr ); - -/* If an error occurred, annul the result. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int GetBase( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astGetBase - -* Purpose: -* Obtain the value of the Base attribute for a FrameSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* int astGetBase( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns the value of the Base attribute for a -* FrameSet. This value is an index that identifies the base Frame -* in the FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Returned Value: -* The Base attribute value. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - int invert; /* FrameSet is inverted? */ - int result; /* Value to return */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Determine if the FrameSet has been inverted. */ - invert = astGetInvert( this ); - -/* If it has not been inverted, return the base Frame index, otherwise - return the index of the current Frame instead. Provide defaults if - necessary. */ - if ( astOK ) { - if ( !invert ) { - result = ( this->base != -INT_MAX ) ? this->base : 1; - } else { - result = ( this->current != -INT_MAX ) ? this->current : - astGetNframe( this ); - } - } - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int GetCurrent( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astGetCurrent - -* Purpose: -* Obtain the value of the Current attribute for a FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "frameset.h" -* int astGetCurrent( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns the value of the Current attribute for a -* FrameSet. This attribute is an index that identifies the -* current Frame in a FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Returned Value: -* Value of the Current attribute. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - int invert; /* FrameSet is inverted? */ - int result; /* Value to return */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Determine if the FrameSet has been inverted. */ - invert = astGetInvert( this ); - -/* If it has not been inverted, return the current Frame index, - otherwise return the index of the base Frame instead. Provide - defaults if necessary. */ - if ( astOK ) { - if ( !invert ) { - result = ( this->current != -INT_MAX ) ? this->current : - astGetNframe( this ); - } else { - result = ( this->base != -INT_MAX ) ? this->base : 1; - } - } - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static AstFrame *GetFrame( AstFrameSet *this, int iframe, int *status ) { -/* -*++ -* Name: -c astGetFrame -f AST_GETFRAME - -* Purpose: -* Obtain a pointer to a specified Frame in a FrameSet. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c AstFrame *astGetFrame( AstFrameSet *this, int iframe ) -f RESULT = AST_GETFRAME( THIS, IFRAME, STATUS ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns a pointer to a specified Frame in a -* FrameSet. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FrameSet. -c iframe -f IFRAME = INTEGER (Given) -* The index of the required Frame within the FrameSet. This -* value should lie in the range from 1 to the number of Frames -* in the FrameSet (as given by its Nframe attribute). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetFrame() -f AST_GETFRAME = INTEGER -* A pointer to the requested Frame. - -* Notes: -* - A value of AST__BASE or AST__CURRENT may be given for the -c "iframe" parameter to specify the base Frame or the current -f IFRAME argument to specify the base Frame or the current -* Frame respectively. -* - This function increments the RefCount attribute of the -* selected Frame by one. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstFrame *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate and translate the Frame index supplied. */ - iframe = astValidateFrameIndex( this, iframe, "astGetFrame" ); - -/* If OK, clone a pointer to the requested Frame. */ - if ( astOK ) result = astClone( this->frame[ iframe - 1 ] ); - -/* Return the result. */ - return result; -} - -static int GetIsLinear( AstMapping *this_mapping, int *status ){ -/* -* Name: -* GetIsLinear - -* Purpose: -* Return the value of the IsLinear attribute for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GetIsLinear( AstMapping *this, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astGetIsLinear -* method inherited from the Mapping class). - -* Description: -* This function returns the value of the IsLinear attribute for a -* FrameSet, which is the IsLinear value of he base->current Mapping. - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. -*/ -/* Local Variables: */ - AstMapping *map; - int result; - -/* Check global status */ - if( !astOK ) return 0; - -/* Get the Mapping. */ - map = astGetMapping( (AstFrameSet *) this_mapping, AST__BASE, - AST__CURRENT ); - -/* Get its IsLinear attribute value. */ - result = astGetIsLinear( map ); - -/* Free the Mapping. */ - map = astAnnul( map ); - -/* Return the result. */ - return result; -} - -static AstMapping *GetMapping( AstFrameSet *this, int iframe1, int iframe2, int *status ) { -/* -*++ -* Name: -c astGetMapping -f AST_GETMAPPING - -* Purpose: -* Obtain a Mapping that converts between two Frames in a FrameSet. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c AstMapping *astGetMapping( AstFrameSet *this, int iframe1, int iframe2 ) -f RESULT = AST_GETMAPPING( THIS, IFRAME1, IFRAME2, STATUS ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns a pointer to a Mapping that will convert -* coordinates between the coordinate systems represented by two -* Frames in a FrameSet. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FrameSet. -c iframe1 -f IFRAME1 = INTEGER (Given) -* The index of the first Frame in the FrameSet. This Frame describes -* the coordinate system for the "input" end of the Mapping. -c iframe2 -f IFRAME2 = INTEGER (Given) -* The index of the second Frame in the FrameSet. This Frame -* describes the coordinate system for the "output" end of the -* Mapping. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetMapping() -f AST_GETMAPPING = INTEGER -* Pointer to a Mapping whose forward transformation converts -* coordinates from the first coordinate system to the second -* one, and whose inverse transformation converts coordinates in -* the opposite direction. - -* Notes: -* - The returned Mapping will include the clipping effect of any -* Regions which occur on the path between the two supplied Frames -* (this includes the two supplied Frames themselves). -c - The values given for the "iframe1" and "iframe2" parameters -f - The values given for the IFRAME1 and IFRAME2 arguments -* should lie in the range from 1 to the number of Frames in the -* FrameSet (as given by its Nframe attribute). A value of -* AST__BASE or AST__CURRENT may also be given to identify the -* FrameSet's base Frame or current Frame respectively. It is -c permissible for both these parameters to have the same value, in -f permissible for both these arguments to have the same value, in -* which case a unit Mapping (UnitMap) is returned. -* - It should always be possible to generate the Mapping -* requested, but this does necessarily guarantee that it will be -* able to perform the required coordinate conversion. If -* necessary, the TranForward and TranInverse attributes of the -* returned Mapping should be inspected to determine if the -* required transformation is available. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstFrame *fr; /* Temporary pointer to Frame */ - AstFrame **frames; /* Pointer to array of Frames */ - AstMapping **path; /* Pointer to array of conversion Mappings */ - AstMapping *copy; /* Pointer to copy of Mapping */ - AstMapping *result; /* Result pointer to be returned */ - AstMapping *tmp; /* Temporary pointer for joining Mappings */ - int *forward; /* Pointer to array of Mapping directions */ - int ipath; /* Loop counter for conversion path steps */ - int iframe; /* Frame index */ - int inode; /* Node index */ - int npath; /* Number of steps in conversion path */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate and translate the Frame indices supplied. */ - iframe1 = astValidateFrameIndex( this, iframe1, "astGetMapping" ); - iframe2 = astValidateFrameIndex( this, iframe2, "astGetMapping" ); - -/* Allocate memory to hold an array of Mapping pointers and associated - direction flags - a maximum of one element for each Mapping and one - for each Frame in the FrameSet. */ - path = astMalloc( sizeof( AstMapping * ) * (size_t) ( this->nnode - 1 + - this->nframe ) ); - forward = astMalloc( sizeof( int ) * (size_t) ( this->nnode - 1 + - this->nframe ) ); - -/* Allocate memory to hold a list of the Frame pointers (if any) associated - with each node. */ - frames = astMalloc( sizeof( AstFrame * ) * (size_t) ( this->nnode ) ); - -/* If OK, set up an array of Frame pointers indexed by node index. If a - node has no associated Frame store a NULL pointer. This is needed so - that we can find Frame pointers quickly within the Span function. Note, - we simply copy the pointers rather than cloning them, so they do not - need to be annulled when finished with. */ - if ( astOK ) { - for( inode = 0; inode < this->nnode; inode++ ) frames[ inode ] = NULL; - for( iframe = 0; iframe < this->nframe; iframe++ ) { - frames[ this->node[ iframe ] ] = this->frame[ iframe ]; - } - -/* Obtain the Mapping pointers and direction flags needed to convert - coordinates between the nodes associated with the two specified - Frames. */ - npath = Span( this, frames, this->node[ iframe1 - 1 ], - this->node[ iframe2 - 1 ], -1, path, forward, status ) - 1; - -/* If this failed, it indicates a corrupt FrameSet object, so report - an error. */ - if ( npath < 0 ) { - astError( AST__FRSIN, "astGetMapping(%s): Invalid or corrupt " - "%s - could not find conversion path between Frames " - "%d and %d.", status, astGetClass( this ), astGetClass( this ), - iframe1, iframe2 ); - -/* If the conversion path is of zero length (i.e. the two Frames are - the same) then we will return a Mapping which is equivalent to the - Frame. Most classes of Frame are equivalent to a UnitMap. However, we do - not hard-wire this equivalence since some classes of Frame (e.g. Regions - or CmpFrames containing Regions) do not correspond to a UnitMap. Instead - we use the astIsUnitFrame method on the Frame to determine if the - Frame is equivalent to a UnitMap.Is os, create a suitable UnitMap. If - not, return the Frame itself (a form of Mapping). */ - } else if ( npath == 0 ) { - fr = astGetFrame( this, iframe1 ); - if( astIsUnitFrame( fr ) ){ - result = (AstMapping *) astUnitMap( astGetNaxes( fr ), "", status ); - } else { - result = (AstMapping *) astClone( fr ); - } - fr = astAnnul( fr ); - -/* If the conversion path involves at least one non-trivial Mapping, - make a copy of the first Mapping, inverting the copy if - necessary. */ - } else { - result = astCopy( path[ 0 ] ); - if ( !forward[ 0 ] ) astInvert( result ); - -/* Now loop to concatenate any further Mappings. First make a copy of - each additional Mapping and invert the copy if necessary. */ - for ( ipath = 1; ipath < npath; ipath++ ) { - copy = astCopy( path[ ipath ] ); - if ( !forward[ ipath ] ) astInvert( copy ); - -/* Concatenate the copy with the result so far, then annul the pointer - to the copy and save the pointer to the new result. */ - tmp = (AstMapping *) astCmpMap( result, copy, 1, "", status ); - result = astAnnul( result ); - copy = astAnnul( copy ); - result = tmp; - } - } - } - -/* Free the memory allocated for the conversion path information. */ - path = astFree( path ); - forward = astFree( forward ); - frames = astFree( frames ); - -/* If an error occurred, annul the returned Mapping. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int GetNaxes( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetNaxes - -* Purpose: -* Determine how many axes a FrameSet has. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int GetNaxes( AstFrame *this, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astGetNaxes method -* inherited from the Frame class). - -* Description: -* This function returns the number of axes for a FrameSet. This is equal -* to the number of axes in its current Frame. - -* Parameters: -* this -* Pointer to the FrameSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of FrameSet axes (zero or more). - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame. */ - fr = astGetFrame( this, AST__CURRENT ); - -/* Obtain the number of axes in this Frame. */ - result = astGetNaxes( fr ); - -/* Annul the current Frame pointer. */ - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int GetNframe( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astGetNframe - -* Purpose: -* Determine the number of Frames in a FrameSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* int astGetNframe( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns the number of Frames in a FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Returned Value: -* The number of Frames in the FrameSet (always 1 or more). - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the Frame count. */ - return this->nframe; -} - -static int GetNin( AstMapping *this_mapping, int *status ) { -/* -* Name: -* GetNin - -* Purpose: -* Get the number of input coordinates for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int GetNin( AstMapping *this, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astGetNin method -* inherited from the Frame class). - -* Description: -* This function returns the number of input coordinate values -* required per point by a FrameSet when used to transform a set of -* points (i.e. the number of dimensions of the space in which the -* input points reside). -* -* The value returned is equal to the number of axes in the -* FrameSet's base Frame. - -* Parameters: -* this -* Pointer to the FrameSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Number of coordinate values required. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to base Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_mapping; - -/* Obtain a pointer to the FrameSet's base Frame. */ - fr = astGetFrame( this, AST__BASE ); - -/* Obtain the number of axes in this Frame. */ - result = astGetNaxes( fr ); - -/* Annul the base Frame pointer. */ - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int GetNout( AstMapping *this_mapping, int *status ) { -/* -* Name: -* GetNout - -* Purpose: -* Get the number of output coordinates for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int GetNout( AstMapping *this, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astGetNout method -* inherited from the Frame class). - -* Description: -* This function returns the number of output coordinate values -* generated per point by a FrameSet when used to transform a set -* of points (i.e. the number of dimensions of the space in which -* the output points reside). -* -* The value returned is equal to the number of axes in the -* FrameSet's current Frame. - -* Parameters: -* this -* Pointer to the FrameSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Number of coordinate values generated. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the number of axes in the FrameSet's current Frame. */ - return GetNaxes( (AstFrame *) this_mapping, status ); -} - -static const int *GetPerm( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetPerm - -* Purpose: -* Access the axis permutation array for the current Frame of a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* const int *GetPerm( AstFrame *this, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astGetPerm protected -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the axis permutation array -* for the current Frame of a FrameSet. This array constitutes a -* lookup-table that converts between an axis number supplied -* externally and the corresponding index in the Frame's internal -* axis arrays. - -* Parameters: -* this -* Pointer to the FrameSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the current Frame's axis permutation array (a -* constant array of int). Each element of this contains the -* (zero-based) internal axis index to be used in place of the -* external index which is used to address the permutation -* array. If the current Frame has zero axes, this pointer will be -* NULL. - -* Notes: -* - The pointer returned by this function gives direct access to -* data internal to the Frame object. It remains valid only so long -* as the Frame exists. The permutation array contents may be -* modified by other functions which operate on the Frame and this -* may render the returned pointer invalid. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to FrameSet structure */ - const int *result; /* Result pointer value */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and then obtain a - pointer to its axis permutation array. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astGetPerm( fr ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static int GetTranForward( AstMapping *this_mapping, int *status ) { -/* -* Name: -* GetTranForward - -* Purpose: -* Determine if a FrameSet defines a forward coordinate transformation. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int GetTranForward( AstMapping *this ) - -* Class Membership: -* Frameset member function (over-rides the astGetTranForward -* protected method inherited from the Frame class). - -* Description: -* This function returns a value indicating whether a FrameSet is -* able to perform a coordinate transformation in the "forward" -* direction. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Returned Value: -* Zero if the forward coordinate transformation is not defined, or -* 1 if it is. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - AstMapping *map; /* Pointer to base->current Mapping */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_mapping; - -/* Obtain the Mapping between the base and current Frames in the - FrameSet (note this takes account of whether the FrameSet has been - inverted). */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Determine whether the required transformation is defined. */ - result = astGetTranForward( map ); - -/* Annul the Mapping pointer. */ - map = astAnnul( map ); - -/* If an error occurred, clear the returned result. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int GetTranInverse( AstMapping *this_mapping, int *status ) { -/* -* Name: -* GetTranInverse - -* Purpose: -* Determine if a FrameSet defines an inverse coordinate transformation. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int GetTranInverse( AstMapping *this ) - -* Class Membership: -* Frameset member function (over-rides the astGetTranInverse -* protected method inherited from the Frame class). - -* Description: -* This function returns a value indicating whether a FrameSet is -* able to perform a coordinate transformation in the "inverse" -* direction. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Returned Value: -* Zero if the inverse coordinate transformation is not defined, or -* 1 if it is. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - AstMapping *map; /* Pointer to base->current Mapping */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_mapping; - -/* Obtain the Mapping between the base and current Frames in the - FrameSet (note this takes account of whether the FrameSet has been - inverted). */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Determine whether the required transformation is defined. */ - result = astGetTranInverse( map ); - -/* Annul the Mapping pointer. */ - map = astAnnul( map ); - -/* If an error occurred, clear the returned result. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int GetUseDefs( AstObject *this_object, int *status ) { -/* -* Name: -* GetUseDefs - -* Purpose: -* Get the value of the UseDefs attribute for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int GetUseDefs( AstObject *this_object, int *status ) { - -* Class Membership: -* FrameSet member function (over-rides the protected astGetUseDefs -* method inherited from the Frame class). - -* Description: -* This function returns the value of the UseDefs attribute for a FrameSet, -* supplying a suitable default. - -* Parameters: -* this -* Pointer to the FrameSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - The USeDefs value. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - int result; /* Value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* If the UseDefs value for the FrameSet has been set explicitly, use the - Get method inherited from the parent Frame class to get its value> */ - if( astTestUseDefs( this ) ) { - result = (*parent_getusedefs)( this_object, status ); - -/* Otherwise, supply a default value equal to the UseDefs value of the - current Frame. */ - } else { - fr = astGetFrame( this, AST__CURRENT ); - result = astGetUseDefs( fr ); - fr = astAnnul( fr ); - } - -/* Return the result. */ - return result; -} - -static int GetVarFrm( AstFrameSet *this, int iframe, int *status ) { -/* -* Name: -* GetVarFrm - -* Purpose: -* Get the index of the variants Frame for a nominated Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int GetVarFrm( AstFrameSet *this, int iframe, int *status ) { - -* Class Membership: -* Private function. - -* Description: -* This function returns the index of the variants Frame associated -* with a nominated mirror Frame. See astMirrorVariants. - -* Parameters: -* this -* Pointer to the FrameSet. -* iframe -* The one-based index of the nominated Frame that may potentially be -* a mirror for the variant Mappings in another Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The one-based Frame index of the Frame that defines the variant -* Mappings associated with Frame "iframe". This will be the same as -* "iframe" unless the nominated Frame is a mirror for another Frame. -*/ - -/* Local Variables: */ - int result; /* Value to return */ - -/* Initialise. */ - result = AST__NOFRAME; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise the returned value. */ - result = iframe; - -/* If the nominated Frame is mirroring another Frame, return the index of - the mirrored Frame. Walk up the chain until we reach a Frame which is - not a mirror for another Frame. */ - while( this->varfrm[ result - 1 ] > 0 ) { - if( this->varfrm[ result - 1 ] == result ) { - astError( AST__INTER, "GetVarFrm(FrameSet): FrameSet is corrupt " - "(internal programming error).", status ); - break; - } else { - result = this->varfrm[ result - 1 ]; - } - } - -/* Return the result. */ - return result; -} - -static const char *GetVariant( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astGetVariant - -* Purpose: -* Obtain the value of the Variant attribute for a FrameSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* const char *astGetVariant( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns the value of the Variant attribute for a -* FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Returned Value: -* The Variant attribute value. - -* Notes: -* - A NULL value will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstFrame *frm; - AstFrame *vfs; - const char *result; - int icur; - int iuse; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the one-based index of the current Frame. */ - icur = astGetCurrent( this ); - -/* The current Frame may mirror the variant Mappings in another Frame, - rather than defining any variant Mappings itself. Get the one-based - index of the Frame that defines the variant Mappings to use. */ - iuse = GetVarFrm( this, icur, status ); - -/* Get a pointer to the Variants FrameSet in the used Frame. */ - frm = astGetFrame( this, iuse ); - vfs = astGetFrameVariants( frm ); - -/* If the current Frame has no Variants FrameSet, return the Domain name - of the current Frame. */ - if( !vfs ) { - result = astGetDomain( this ); - -/* Otherwise, return the Domain name of the current Frame in the Variants - FrameSet. Then annul the Variants FrameSet pointer. */ - } else { - result = astGetDomain( vfs ); - vfs = astAnnul( vfs ); - } - -/* Annul the current Frame pointer. */ - frm = astAnnul( frm ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -void astInitFrameSetVtab_( AstFrameSetVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitFrameSetVtab - -* Purpose: -* Initialise a virtual function table for a FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "frameset.h" -* void astInitFrameSetVtab( AstFrameSetVtab *vtab, const char *name ) - -* Class Membership: -* FrameSet vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the FrameSet class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameVtab( (AstFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAFrameSet) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->AddFrame = AddFrame; - vtab->AddVariant = AddVariant; - vtab->ClearBase = ClearBase; - vtab->ClearCurrent = ClearCurrent; - vtab->GetBase = GetBase; - vtab->GetCurrent = GetCurrent; - vtab->GetFrame = GetFrame; - vtab->GetMapping = GetMapping; - vtab->GetNframe = GetNframe; - vtab->GetNode = GetNode; - vtab->GetAllVariants = GetAllVariants; - vtab->MirrorVariants = MirrorVariants; - vtab->RemapFrame = RemapFrame; - vtab->RemoveFrame = RemoveFrame; - vtab->SetBase = SetBase; - vtab->SetCurrent = SetCurrent; - vtab->TestBase = TestBase; - vtab->TestCurrent = TestCurrent; - vtab->ValidateFrameIndex = ValidateFrameIndex; - - vtab->ClearVariant = ClearVariant; - vtab->GetVariant = GetVariant; - vtab->SetVariant = SetVariant; - vtab->TestVariant = TestVariant; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - - parent_clear = object->Clear; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - object->Clear = Clear; - - parent_vset = object->VSet; - object->VSet = VSet; - - parent_getusedefs = object->GetUseDefs; - object->GetUseDefs = GetUseDefs; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - mapping = (AstMappingVtab *) vtab; - frame = (AstFrameVtab *) vtab; - - object->ClearAttrib = ClearAttrib; - object->GetAttrib = GetAttrib; - object->SetAttrib = SetAttrib; - object->TestAttrib = TestAttrib; - - object->GetUseDefs = GetUseDefs; - object->Equal = Equal; - object->Cast = Cast; - - mapping->GetIsLinear = GetIsLinear; - mapping->GetNin = GetNin; - mapping->GetNout = GetNout; - mapping->GetTranForward = GetTranForward; - mapping->GetTranInverse = GetTranInverse; - mapping->Rate = Rate; - mapping->ReportPoints = ReportPoints; - mapping->RemoveRegions = RemoveRegions; - mapping->Simplify = Simplify; - mapping->Transform = Transform; - mapping->MapSplit = MapSplit; - - frame->Abbrev = Abbrev; - frame->Angle = Angle; - frame->AxAngle = AxAngle; - frame->AxDistance = AxDistance; - frame->AxNorm = AxNorm; - frame->AxOffset = AxOffset; - frame->CheckPerm = CheckPerm; - frame->ClearDigits = ClearDigits; - frame->ClearDirection = ClearDirection; - frame->ClearDomain = ClearDomain; - frame->ClearFormat = ClearFormat; - frame->ClearLabel = ClearLabel; - frame->ClearMatchEnd = ClearMatchEnd; - frame->ClearMaxAxes = ClearMaxAxes; - frame->ClearMinAxes = ClearMinAxes; - frame->ClearPermute = ClearPermute; - frame->ClearPreserveAxes = ClearPreserveAxes; - frame->ClearSymbol = ClearSymbol; - frame->ClearTitle = ClearTitle; - frame->ClearUnit = ClearUnit; - frame->Convert = Convert; - frame->ConvertX = ConvertX; - frame->Distance = Distance; - frame->Fields = Fields; - frame->FindFrame = FindFrame; - frame->Format = Format; - frame->FrameGrid = FrameGrid; - frame->Centre = Centre; - frame->Gap = Gap; - frame->GetAxis = GetAxis; - frame->GetDigits = GetDigits; - frame->GetDirection = GetDirection; - frame->GetDomain = GetDomain; - frame->GetFormat = GetFormat; - frame->GetLabel = GetLabel; - frame->GetMatchEnd = GetMatchEnd; - frame->GetMaxAxes = GetMaxAxes; - frame->GetMinAxes = GetMinAxes; - frame->GetNaxes = GetNaxes; - frame->GetPerm = GetPerm; - frame->GetPermute = GetPermute; - frame->GetPreserveAxes = GetPreserveAxes; - frame->GetSymbol = GetSymbol; - frame->GetTitle = GetTitle; - frame->GetUnit = GetUnit; - frame->Intersect = Intersect; - frame->IsUnitFrame = IsUnitFrame; - frame->LineContains = LineContains; - frame->LineCrossing = LineCrossing; - frame->LineDef = LineDef; - frame->LineOffset = LineOffset; - frame->Match = Match; - frame->MatchAxes = MatchAxes; - frame->MatchAxesX = MatchAxesX; - frame->Norm = Norm; - frame->NormBox = NormBox; - frame->Offset = Offset; - frame->Offset2 = Offset2; - frame->Overlay = Overlay; - frame->PermAxes = PermAxes; - frame->PickAxes = PickAxes; - frame->PrimaryFrame = PrimaryFrame; - frame->Resolve = Resolve; - frame->ResolvePoints = ResolvePoints; - frame->SetAxis = SetAxis; - frame->SetDigits = SetDigits; - frame->SetDirection = SetDirection; - frame->SetDomain = SetDomain; - frame->SetFormat = SetFormat; - frame->SetLabel = SetLabel; - frame->SetMatchEnd = SetMatchEnd; - frame->SetMaxAxes = SetMaxAxes; - frame->SetMinAxes = SetMinAxes; - frame->SetPermute = SetPermute; - frame->SetPreserveAxes = SetPreserveAxes; - frame->SetSymbol = SetSymbol; - frame->SetTitle = SetTitle; - frame->SetUnit = SetUnit; - frame->SubFrame = SubFrame; - frame->SystemCode = SystemCode; - frame->SystemString = SystemString; - frame->TestDigits = TestDigits; - frame->TestDirection = TestDirection; - frame->TestDomain = TestDomain; - frame->TestFormat = TestFormat; - frame->TestLabel = TestLabel; - frame->TestMatchEnd = TestMatchEnd; - frame->TestMaxAxes = TestMaxAxes; - frame->TestMinAxes = TestMinAxes; - frame->TestPermute = TestPermute; - frame->TestPreserveAxes = TestPreserveAxes; - frame->TestSymbol = TestSymbol; - frame->TestTitle = TestTitle; - frame->TestUnit = TestUnit; - frame->Unformat = Unformat; - frame->ValidateAxis = ValidateAxis; - frame->ValidateAxisSelection = ValidateAxisSelection; - frame->ValidateSystem = ValidateSystem; - - frame->GetActiveUnit = GetActiveUnit; - frame->SetActiveUnit = SetActiveUnit; - frame->TestActiveUnit = TestActiveUnit; - - frame->GetTop = GetTop; - frame->SetTop = SetTop; - frame->TestTop = TestTop; - frame->ClearTop = ClearTop; - - frame->GetBottom = GetBottom; - frame->SetBottom = SetBottom; - frame->TestBottom = TestBottom; - frame->ClearBottom = ClearBottom; - - frame->GetEpoch = GetEpoch; - frame->SetEpoch = SetEpoch; - frame->TestEpoch = TestEpoch; - frame->ClearEpoch = ClearEpoch; - - frame->GetDtai = GetDtai; - frame->SetDtai = SetDtai; - frame->TestDtai = TestDtai; - frame->ClearDtai = ClearDtai; - - frame->GetDut1 = GetDut1; - frame->SetDut1 = SetDut1; - frame->TestDut1 = TestDut1; - frame->ClearDut1 = ClearDut1; - - frame->GetSystem = GetSystem; - frame->SetSystem = SetSystem; - frame->TestSystem = TestSystem; - frame->ClearSystem = ClearSystem; - - frame->GetAlignSystem = GetAlignSystem; - frame->SetAlignSystem = SetAlignSystem; - frame->TestAlignSystem = TestAlignSystem; - frame->ClearAlignSystem = ClearAlignSystem; - - frame->ClearObsLat = ClearObsLat; - frame->TestObsLat = TestObsLat; - frame->GetObsLat = GetObsLat; - frame->SetObsLat = SetObsLat; - - frame->ClearObsAlt = ClearObsAlt; - frame->TestObsAlt = TestObsAlt; - frame->GetObsAlt = GetObsAlt; - frame->SetObsAlt = SetObsAlt; - - frame->ClearObsLon = ClearObsLon; - frame->TestObsLon = TestObsLon; - frame->GetObsLon = GetObsLon; - frame->SetObsLon = SetObsLon; - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "FrameSet", - "Set of inter-related coordinate systems" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void Intersect( AstFrame *this_frame, const double a1[2], - const double a2[2], const double b1[2], - const double b2[2], double cross[2], - int *status ) { -/* -* Name: -* Intersect - -* Purpose: -* Find the point of intersection between two geodesic curves. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void Intersect( AstFrame *this_frame, const double a1[2], -* const double a2[2], const double b1[2], -* const double b2[2], double cross[2], -* int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astIntersect method -* inherited from the Frame class). - -* Description: -* This function finds the coordinate values at the point of -* intersection between two geodesic curves. Each curve is specified -* by two points on the curve. - -* Parameters: -* this -* Pointer to the SkyFrame. -* a1 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a point on the first -* geodesic curve. -* a2 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a second point on the -* first geodesic curve. -* b1 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a point on the second -* geodesic curve. -* b2 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a second point on -* the second geodesic curve. -* cross -* An array of double, with one element for each Frame axis -* in which the coordinates of the required intersection -* point will be returned. These will be AST__BAD if the curves do -* not intersect. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -* - For SkyFrames each curve will be a great circle, and in general -* each pair of curves will intersect at two diametrically opposite -* points on the sky. The returned position is the one which is -* closest to point "a1". -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astIntersect method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astIntersect( fr, a1, a2, b1, b2, cross ); - fr = astAnnul( fr ); - -} - -static int IsUnitFrame( AstFrame *this_frame, int *status ){ -/* -* Name: -* IsUnitFrame - -* Purpose: -* Is this Frame equivalent to a UnitMap? - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int IsUnitFrame( AstFrame *this, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astIsUnitFrame -* method inherited from the Frame class). - -* Description: -* This function returns a flag indicating if the supplied Frame is -* equivalent to a UnitMap when treated as a Mapping (note, the Frame -* class inherits from Mapping and therefore every Frame is also a Mapping). - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the supplied Frame is equivalent to -* a UnitMap when treated as a Mapping. - -*- -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to FrameSet's current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - int result; /* Result to be returned */ - -/* Initialise the returned value. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame. */ - fr = astGetFrame( this, AST__CURRENT ); - -/* Invoke the astIsUnitFrame method for this Frame. */ - result = astIsUnitFrame( fr ); - -/* Annul the Frame pointer. */ - fr = astAnnul( fr ); - -/* If an error occurred, clean up by clearing the returned result. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int LineContains( AstFrame *this_frame, AstLineDef *l, int def, double *point, int *status ) { -/* -* Name: -* LineContains - -* Purpose: -* Determine if a line contains a point. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int LineContains( AstFrame *this, AstLineDef *l, int def, double *point, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astLineContains -* method inherited from the Frame class). - -* Description: -* This function determines if the supplied point is on the supplied -* line within the supplied Frame. - -* Parameters: -* this -* Pointer to the Frame. -* l -* Pointer to the structure defining the line. -* def -* Should be set non-zero if the "point" array was created by a -* call to astLineCrossing (in which case it may contain extra -* information following the axis values),and zero otherwise. -* point -* Point to an array containing the axis values of the point to be -* tested, possibly followed by extra cached information (see "def"). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the line contains the point. - -* Notes: -* - The pointer supplied for "l" should have been created using the -* astLineDef method. These structures contained cached information about -* the lines which improve the efficiency of this method when many -* repeated calls are made. An error will be reported if the structure -* does not refer to the Frame specified by "this". -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - int result; /* Returned value */ - -/* Initialise */ - result =0; - -/* Obtain a pointer to the FrameSet's current Frame and then invoke the - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( (AstFrameSet *) this_frame, AST__CURRENT ); - result = astLineContains( fr, l, def, point ); - fr = astAnnul( fr ); - -/* Return the result. */ - return result; -} - -static int LineCrossing( AstFrame *this_frame, AstLineDef *l1, AstLineDef *l2, - double **cross, int *status ) { -/* -* Name: -* LineCrossing - -* Purpose: -* Determine if two lines cross. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int LineCrossing( AstFrame *this, AstLineDef *l1, AstLineDef *l2, -* double **cross, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astLineCrossing -* method inherited from the Frame class). - -* Description: -* This function determines if the two suplied line segments cross, -* and if so returns the axis values at the point where they cross. -* A flag is also returned indicating if the crossing point occurs -* within the length of both line segments, or outside one or both of -* the line segments. - -* Parameters: -* this -* Pointer to the Frame. -* l1 -* Pointer to the structure defining the first line. -* l2 -* Pointer to the structure defining the second line. -* cross -* Pointer to a location at which to put a pointer to a dynamically -* alocated array containing the axis values at the crossing. If -* NULL is supplied no such array is returned. Otherwise, the returned -* array should be freed using astFree when no longer needed. If the -* lines are parallel (i.e. do not cross) then AST__BAD is returned for -* all axis values. Note usable axis values are returned even if the -* lines cross outside the segment defined by the start and end points -* of the lines. The order of axes in the returned array will take -* account of the current axis permutation array if appropriate. Note, -* sub-classes such as SkyFrame may append extra values to the end -* of the basic frame axis values. A NULL pointer is returned if an -* error occurs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the lines cross at a point which is -* within the [start,end) segment of both lines. If the crossing point -* is outside this segment on either line, or if the lines are parallel, -* zero is returned. Note, the start point is considered to be inside -* the length of the segment, but the end point is outside. - -* Notes: -* - The pointers supplied for "l1" and "l2" should have been created -* using the astLineDef method. These structures contained cached -* information about the lines which improve the efficiency of this method -* when many repeated calls are made. An error will be reported if -* either structure does not refer to the Frame specified by "this". -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - int result; /* Returned value */ - -/* Initialise */ - result =0; - -/* Obtain a pointer to the FrameSet's current Frame and then invoke the - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( (AstFrameSet *) this_frame, AST__CURRENT ); - result = astLineCrossing( fr, l1, l2, cross ); - fr = astAnnul( fr ); - -/* Return the result. */ - return result; -} - -static AstLineDef *LineDef( AstFrame *this_frame, const double start[2], - const double end[2], int *status ) { -/* -* Name: -* LineDef - -* Purpose: -* Creates a structure describing a line segment in a 2D Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstLineDef *LineDef( AstFrame *this, const double start[2], -* const double end[2], int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astLineDef -* method inherited from the Frame class). - -* Description: -* This function creates a structure containing information describing a -* given line segment within the supplied 2D Frame. This may include -* information which allows other methods such as astLineCrossing to -* function more efficiently. Thus the returned structure acts as a -* cache to store intermediate values used by these other methods. - -* Parameters: -* this -* Pointer to the Frame. Must have 2 axes. -* start -* An array of 2 doubles marking the start of the line segment. -* end -* An array of 2 doubles marking the end of the line segment. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the memory structure containing the description of the -* line. This structure should be freed using astFree when no longer -* needed. A NULL pointer is returned (without error) if any of the -* supplied axis values are AST__BAD. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstLineDef *result; /* Returned value */ - -/* Initialise */ - result = NULL; - -/* Obtain a pointer to the FrameSet's current Frame and then invoke the - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( (AstFrameSet *) this_frame, AST__CURRENT ); - result = astLineDef( fr, start, end ); - fr = astAnnul( fr ); - -/* Return the result. */ - return result; -} - -static void LineOffset( AstFrame *this_frame, AstLineDef *line, double par, - double prp, double point[2], int *status ){ -/* -* Name: -* LineOffset - -* Purpose: -* Find a position close to a line. - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* void LineOffset( AstFrame *this, AstLineDef *line, double par, -* double prp, double point[2], int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astLineOffset -* method inherited from the Frame class). - -* Description: -* This function returns a position formed by moving a given distance along -* the supplied line, and then a given distance away from the supplied line. - -* Parameters: -* this -* Pointer to the Frame. -* line -* Pointer to the structure defining the line. -* par -* The distance to move along the line from the start towards the end. -* prp -* The distance to move at right angles to the line. Positive -* values result in movement to the left of the line, as seen from -* the observer, when moving from start towards the end. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The pointer supplied for "line" should have been created using the -* astLineDef method. This structure contains cached information about the -* line which improves the efficiency of this method when many repeated -* calls are made. An error will be reported if the structure does not -* refer to the Frame specified by "this". -*/ - - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - -/* Obtain a pointer to the FrameSet's current Frame and then invoke the - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( (AstFrameSet *) this_frame, AST__CURRENT ); - astLineOffset( fr, line, par, prp, point ); - fr = astAnnul( fr ); -} - -static const char *GetAllVariants( AstFrameSet *this, int *status ) { -/* -* Name: -* GetAllVariants - -* Purpose: -* Get a pointer to a list of the variant Mappings for the current Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* const char *getAllVariants( AstFrameSet *this ) - -* Class Membership: -* FrameSet member function. - -* Description: -* This function returns a space separated list of names for all the -* variant Mappings associated with the current Frame. See attribute -* "Variant". If the current Frame has no variant Mappings, the return -* value contains just the Domain name of the current Frame in the -* supplied FrameSet. - -* Parameters: -* this -* Pointer to the Frame. - -* Returned Value: -* A pointer to a null-terminated string containing the list. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the FrameSet, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Frame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - AstFrame *frm; - AstFrame *vfrm; - AstFrameSet *vfs; - const char *dom; - const char *result; - int ifrm; - int nc; - int icur; - int nfrm; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS( this ); - -/* Get the one-based index of the Frame that defines the available - variant Mappings. */ - icur = GetVarFrm( this, astGetCurrent( this ), status ); - -/* Get the variants FrameSet from the Frame selected above. */ - frm = astGetFrame( this, icur ); - vfs = astGetFrameVariants( frm ); - -/* If the Frame does not have a variants FrameSet, just return the DOmain - name from the current Frame. */ - if( !vfs ) { - result = astGetDomain( this ); - -/* If a variants FrameSet was found, form a space sperated list of the - Domain names in the FrameSet, stored in the static "getallvariants_buff" - string. */ - } else if( astOK ){ - nc = 0; - - nfrm = astGetNframe( vfs ); - for( ifrm = 0; ifrm < nfrm; ifrm++ ) { - vfrm = astGetFrame( vfs, ifrm + 1 ); - dom = astGetDomain( vfrm ); - if( astOK ){ - if( ( nc + strlen(dom) + 1 ) < GETALLVARIANTS_BUFF_LEN ) { - nc += sprintf( getallvariants_buff + nc, "%s ", dom ); - } else { - astError( AST__INTER, "astGetAllVariants(%s): Buffer " - "overflow - too many variants.", status, - astGetClass(this) ); - } - } - vfrm = astAnnul( vfrm ); - } - -/* Remove the final space. */ - getallvariants_buff[ nc - 1 ] = 0; - -/* Return a pointer to the buffer. */ - result = getallvariants_buff; - -/* Annul the pointer to the variants FrameSet. */ - vfs = astAnnul( vfs ); - } - -/* Free the pointer to the current Frame. */ - frm = astAnnul( frm ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstFrameSet *this; /* Pointer to FrameSet structure */ - int i; /* Loop count */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - for( i = 0; i < this->nframe; i++ ) { - if( !result ) result = astManageLock( this->frame[ i ], mode, - extra, fail ); - } - - for ( i = 0; i < this->nnode - 1; i++ ) { - if( !result ) result = astManageLock( this->map[ i ], mode, extra, - fail ); - } - - return result; - -} -#endif - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* FrameSet method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing FrameSet. This is only possible if the specified inputs -* correspond to some subset of the FrameSet outputs. That is, there -* must exist a subset of the FrameSet outputs for which each output -* depends only on the selected FrameSet inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied FrameSet, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the FrameSet to be split (the FrameSet is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied FrameSet, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied FrameSet has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied FrameSet. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstMapping *bcmap; /* Base->current Mapping */ - int *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the Mapping from base to current Frame and try to split it. */ - bcmap = astGetMapping( (AstFrameSet *) this_map, AST__BASE, AST__CURRENT ); - result = astMapSplit( bcmap, nin, in, map ); - bcmap = astAnnul( bcmap ); - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static int Match( AstFrame *this_frame, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, - AstMapping **map, AstFrame **result, int *status ) { -/* -* Name: -* Match - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astMatch -* method inherited from the Frame class). - -* Description: -* This function matches the current Frame of a "template" FrameSet -* to a "target" frame and determines whether it is possible to -* convert coordinates between them. If it is, a Mapping that -* performs the transformation is returned along with a new Frame -* that describes the coordinate system that results when this -* Mapping is applied to the current Frame of the target -* FrameSet. In addition, information is returned to allow the axes -* in this "result" Frame to be associated with the corresponding -* axes in the target and template Frames from which they are -* derived. - -* Parameters: -* template -* Pointer to the template FrameSet, whose current Frame -* describes the coordinate system (or set of possible -* coordinate systems) into which we wish to convert our -* coordinates. -* target -* Pointer to the target Frame. This describes the coordinate -* system in which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case (i.e. if the -* target is of a more specialised class than the template). In -* this latter case, the target is cast down to the class of the -* template. NOTE, this argument is handled by the global method -* wrapper function "astMatch_", rather than by the class-specific -* implementations of this method. -* template_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the index of the axis in the -* template FrameSet's current Frame from which it is -* derived. If it is not derived from any template FrameSet -* axis, a value of -1 will be returned instead. -* target_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the index of the target Frame axis -* from which it is derived. If it is not derived from any -* target Frame axis, a value of -1 will be returned instead. -* map -* Address of a location where a pointer to a new Mapping will -* be returned if the requested coordinate conversion is -* possible. If returned, the forward transformation of this -* Mapping may be used to convert coordinates between the target -* Frame and the result Frame (see below) and the inverse -* transformation will convert in the opposite direction. -* result -* Address of a location where a pointer to a new Frame will be -* returned if the requested coordinate conversion is -* possible. If returned, this Frame describes the coordinate -* system that results from applying the returned Mapping -* (above) to the "target" coordinate system. In general, this -* Frame will combine attributes from (and will therefore be -* more specific than) both the target Frame and the current -* Frame of the template FrameSet. In particular, when the -* template allows the possibility of transformaing to any one -* of a set of alternative coordinate systems, the "result" -* Frame will indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate -* conversion is possible. Otherwise zero is returned (this will -* not in itself result in an error condition). - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to FrameSet's current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - int match; /* Result to be returned */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame. */ - fr = astGetFrame( this, AST__CURRENT ); - -/* Invoke the astMatch method for this Frame. */ - match =astMatch( fr, target, matchsub, template_axes, target_axes, - map, result ); - -/* Annul the Frame pointer. */ - fr = astAnnul( fr ); - -/* If an error occurred, clean up by freeing any allocated memory, - annulling returned objects and clearing the returned result. */ - if ( !astOK ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - *map = astAnnul( *map ); - *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static void MatchAxes( AstFrame *frm1_frame, AstFrame *frm2, int *axes, - int *status ) { -/* -* Name: -* MatchAxes - -* Purpose: -* Find any corresponding axes in two Frames. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void MatchAxes( AstFrame *frm1, AstFrame *frm2, int *axes ) -* int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astMatchAxes -* method inherited from the Frame class). - -* Description: -* This function looks for corresponding axes within two supplied -* Frames. An array of integers is returned that contains an element -* for each axis in the second supplied Frame. An element in this array -* will be set to zero if the associated axis within the second Frame -* has no corresponding axis within the first Frame. Otherwise, it -* will be set to the index (a non-zero positive integer) of the -* corresponding axis within the first supplied Frame. - -* Parameters: -* frm1 -* Pointer to the first Frame. -* frm2 -* Pointer to the second Frame. -* axes -* Pointer to an -* integer array in which to return the indices of the axes (within -* the second Frame) that correspond to each axis within the first -* Frame. Axis indices start at 1. A value of zero will be stored -* in the returned array for each axis in the first Frame that has -* no corresponding axis in the second Frame. -* -* The number of elements in this array must be greater than or -* equal to the number of axes in the first Frame. -* status -* Pointer to inherited status value. - -* Notes: -* - Corresponding axes are identified by the fact that a Mapping -* can be found between them using astFindFrame or astConvert. Thus, -* "corresponding axes" are not necessarily identical. For instance, -* SkyFrame axes in two Frames will match even if they describe -* different celestial coordinate systems -*/ - -/* Local Variables: */ - AstFrame *frm1; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the current Frame in the FrameSet. */ - frm1 = astGetFrame( (AstFrameSet *) frm1_frame, AST__CURRENT ); - -/* Invoke the astMatchAxesX on the second Frame. */ - astMatchAxesX( frm2, frm1, axes ); - -/* Free resources */ - frm1 = astAnnul( frm1 ); -} - -static void MatchAxesX( AstFrame *frm2_frame, AstFrame *frm1, int *axes, - int *status ) { -/* -* Name: -* MatchAxesX - -* Purpose: -* Find any corresponding axes in two Frames. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void MatchAxesX( AstFrame *frm2, AstFrame *frm1, int *axes ) -* int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astMatchAxesX -* method inherited from the Frame class). - -* This function looks for corresponding axes within two supplied -* Frames. An array of integers is returned that contains an element -* for each axis in the second supplied Frame. An element in this array -* will be set to zero if the associated axis within the second Frame -* has no corresponding axis within the first Frame. Otherwise, it -* will be set to the index (a non-zero positive integer) of the -* corresponding axis within the first supplied Frame. - -* Parameters: -* frm2 -* Pointer to the second Frame. -* frm1 -* Pointer to the first Frame. -* axes -* Pointer to an integer array in which to return the indices of -* the axes (within the first Frame) that correspond to each axis -* within the second Frame. Axis indices start at 1. A value of zero -* will be stored in the returned array for each axis in the second -* Frame that has no corresponding axis in the first Frame. -* -* The number of elements in this array must be greater than or -* equal to the number of axes in the second Frame. -* status -* Pointer to inherited status value. - -* Notes: -* - Corresponding axes are identified by the fact that a Mapping -* can be found between them using astFindFrame or astConvert. Thus, -* "corresponding axes" are not necessarily identical. For instance, -* SkyFrame axes in two Frames will match even if they describe -* different celestial coordinate systems -*/ - -/* Local Variables: */ - AstFrame *frm2; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the current Frame in the FrameSet. */ - frm2 = astGetFrame( (AstFrameSet *) frm2_frame, AST__CURRENT ); - -/* Invoke the astMatchAxesX on the current Frame. */ - astMatchAxesX( frm2, frm1, axes ); - -/* Free resources */ - frm2 = astAnnul( frm2 ); -} - -static void MirrorVariants( AstFrameSet *this, int iframe, int *status ) { -/* -*++ -* Name: -c astMirrorVariants -f AST_MIRRORVARIANTS - -* Purpose: -* Make the current Frame mirror the variant Mappings in another Frame. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c void astMirrorVariants( AstFrameSet *this, int iframe ) -f CALL AST_MIRRORVARIANTS( THIS, IFRAME, STATUS ) - -* Class Membership: -* FrameSet method. - -* Description: -c This function -f This routine -* indicates that all access to the Variant attribute of the current -* Frame should should be forwarded to some other nominated Frame in -* the FrameSet. For instance, if a value is set subsequently for the -* Variant attribute of the current Frame, the current Frame will be left -* unchanged and the setting is instead applied to the nominated Frame. -* Likewise, if the value of the Variant attribute is requested, the -* value returned is the value stored for the nominated Frame rather -* than the current Frame itself. -* -* This provides a mechanism for propagating the effects of variant -* Mappings around a FrameSet. If a new Frame is added to a FrameSet -* by connecting it to an pre-existing Frame that has two or more variant -* Mappings, then it may be appropriate to set the new Frame so that it -* mirrors the variants Mappings of the pre-existing Frame. If this is -* done, then it will be possible to select a specific variant Mapping -* using either the pre-existing Frame or the new Frame. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FrameSet. -c iframe -f IFRAME = INTEGER (Given) -* The index of the Frame within the FrameSet which is to be -* mirrored by the current Frame. This value should lie in the range -* from 1 to the number of Frames in the FrameSet (as given by its -* Nframe attribute). If AST__NOFRAME is supplied (or the current -* Frame is specified), then any mirroring established by a previous -* call to this -c function -f routine -* is disabled. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Mirrors can be chained. That is, if Frame B is set to be a mirror -* of Frame A, and Frame C is set to be a mirror of Frame B, then -* Frame C will act as a mirror of Frame A. -* - Variant Mappings cannot be added to the current Frame if it is -* mirroring another Frame. So calls to the -c astAddVariant function -f AST_ADDVARIANT routine -* will cause an error to be reported if the current Frame is -* mirroring another Frame. -* - A value of AST__BASE may be given for the -c "iframe" parameter -f IFRAME argument -* to specify the base Frame. -* - Any variant Mappings explicitly added to the current Frame using -c astAddVariant -f AST_ADDVARIANT -* will be ignored if the current Frame is mirroring another Frame. - -*-- -*/ - -/* Local Variables: */ - int icur; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the current Frame index. */ - icur = astGetCurrent( this ); - -/* If AST__NOFRAME, disable any mirroring. */ - if( iframe == AST__NOFRAME ) { - this->varfrm[ icur - 1 ] = 0; - -/* Otherwise, validate and translate the Frame index supplied. */ - } else { - iframe = astValidateFrameIndex( this, iframe, "astMirrorVariants" ); - -/* If the current Frame has been specified, disable any mirroring. */ - if( iframe == icur ) { - this->varfrm[ icur - 1 ] = 0; - -/* Otherwise, store the one-based variants frame index. */ - } else { - this->varfrm[ icur - 1 ] = iframe; - } - } -} - -static void Norm( AstFrame *this_frame, double value[], int *status ) { -/* -* Name: -* Norm - -* Purpose: -* Normalise a set of FrameSet coordinates. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void Norm( AstAxis *this, double value[], int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astNorm method -* inherited from the Frame class). - -* Description: -* This function converts a set of coordinate values for the -* current Frame of a FrameSet, which might potentially be -* unsuitable for display to a user (for instance, may lie outside -* the expected range of values) into a set of acceptable -* alternative values suitable for display. -* -* Typically, for Frames whose axes represent cyclic values (such -* as angles or positions on the sky), this function wraps an -* arbitrary set of coordinates, so that they lie within the first -* cycle (say zero to 2*pi or -pi/2 to +pi/2). For Frames with -* ordinary linear axes, without constraints, this function will -* typically return the original coordinate values unchanged. - -* Parameters: -* this -* Pointer to the FrameSet. -* value -* An array of double, with one element for each FrameSet axis. -* This should contain the initial set of coordinate values, -* which will be modified in place. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to the current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astNorm method to obtain the new values. Annul the Frame - pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astNorm( fr, value ); - fr = astAnnul( fr ); -} - -static void NormBox( AstFrame *this_frame, double lbnd[], double ubnd[], - AstMapping *reg, int *status ) { -/* -* Name: -* NormBox - -* Purpose: -* Extend a box to include effect of any singularities in the Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void astNormBox( AstFrame *this, double lbnd[], double ubnd[], -* AstMapping *reg, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astNormBox method inherited -* from the Frame class). - -* Description: -* This function modifies a supplied box to include the effect of any -* singularities in the co-ordinate system represented by the Frame. -* For a normal Cartesian coordinate system, the box will be returned -* unchanged. Other classes of Frame may do other things. For instance, -* a SkyFrame will check to see if the box contains either the north -* or south pole and extend the box appropriately. - -* Parameters: -* this -* Pointer to the Frame. -* lbnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* lower axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* ubnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* upper axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* reg -* A Mapping which should be used to test if any singular points are -* inside or outside the box. The Mapping should leave an input -* position unchanged if the point is inside the box, and should -* set all bad if the point is outside the box. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to the current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astNormBox method to obtain the new values. Annul the Frame - pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astNormBox( fr, lbnd, ubnd, reg ); - fr = astAnnul( fr ); -} - -static void Offset( AstFrame *this_frame, const double point1[], - const double point2[], double offset, double point3[], int *status ) { -/* -* Name: -* Offset - -* Purpose: -* Calculate an offset along a geodesic curve. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "frameset.h" -* void Offset( AstFrame *this, -* const double point1[], const double point2[], -* double offset, double point3[], int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astOffset -* method inherited from the Frame class). - -* Description: -* This function finds the FrameSet coordinate values of a point -* which is offset a specified distance along the geodesic curve -* between two other points. - -* Parameters: -* this -* Pointer to the FrameSet. -* point1 -* An array of double, with one element for each FrameSet axis. -* This should contain the coordinates of the point marking the -* start of the geodesic curve. -* point2 -* An array of double, with one element for each FrameSet axis -* This should contain the coordinates of the point marking the -* end of the geodesic curve. -* offset -* The required offset from the first point along the geodesic -* curve. If this is positive, it will be towards the second -* point. If it is negative, it will be in the opposite -* direction. This offset need not imply a position lying -* between the two points given, as the curve will be -* extrapolated if necessary. -* point3 -* An array of double, with one element for each FrameSet axis -* in which the coordinates of the required point will be -* returned. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -* - "Bad" coordinate values will also be returned if the two -* points supplied are coincident (or otherwise fail to uniquely -* specify a geodesic curve) but the requested offset is non-zero. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astOffset method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astOffset( fr, point1, point2, offset, point3 ); - fr = astAnnul( fr ); -} - -static double Offset2( AstFrame *this_frame, const double point1[2], - double angle, double offset, double point2[2], int *status ){ -/* -* Name: -* Offset2 - -* Purpose: -* Calculate an offset along a geodesic curve in a 2D Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* double Offset2( AstFrame *this, const double point1[2], double angle, -* double offset, double point2[2], int *status ); - -* Class Membership: -* FrameSet member function (over-rides the protected astOffset2 -* method inherited from the Frame class). - -* Description: -* This function finds the Frame coordinate values of a point which -* is offset a specified distance along the geodesic curve at a -* given angle from a specified starting point. It can only be -* used with 2-dimensional Frames. -* -* For example, in a basic Frame, this offset will be along the -* straight line joining two points. For a more specialised Frame -* describing a sky coordinate system, however, it would be along -* the great circle passing through two sky positions. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This should contain the coordinates of the -* point marking the start of the geodesic curve. -* angle -* The angle (in radians) from the positive direction of the second -* axis, to the direction of the required position, as seen from -* the starting position. Positive rotation is in the sense of -* rotation from the positive direction of axis 2 to the positive -* direction of axis 1. -* offset -* The required offset from the first point along the geodesic -* curve. If this is positive, it will be in the direction of the -* given angle. If it is negative, it will be in the opposite -* direction. -* point2 -* An array of double, with one element for each Frame axis -* in which the coordinates of the required point will be returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The direction of the geodesic curve at the end point. That is, the -* angle (in radians) between the positive direction of the second -* axis and the continuation of the geodesic curve at the requested -* end point. Positive rotation is in the sense of rotation from -* the positive direction of axis 2 to the positive direction of axis 1. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - An error will be reported if the Frame is not 2-dimensional. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astOffset2 method for this Frame. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astOffset2( fr, point1, angle, offset, point2 ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static void Overlay( AstFrame *template_frame, const int *template_axes, - AstFrame *result, int *status ) { -/* -* Name: -* Overlay - -* Purpose: -* Overlay the attributes of a template FrameSet on to another Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void Overlay( AstFrame *template, const int *template_axes, -* AstFrame *result, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astOverlay -* method inherited from the Frame class). - -* Description: -* This function overlays attributes from the current Frame of a -* FrameSet on to another Frame, so as to over-ride selected -* attributes of that second Frame. Normally only those attributes -* which have been specifically set in the template will be -* transferred. This implements a form of defaulting, in which a -* Frame acquires attributes from the template, but retains its -* original attributes (as the default) if new values have not -* previously been explicitly set in the template. - -* Parameters: -* template -* Pointer to the template FrameSet, for whose current Frame -* values should have been explicitly set for any attribute -* which is to be transferred. -* template_axes -* Pointer to an array of int, with one element for each axis of -* the "result" Frame (see below). For each axis in the result -* frame, the corresponding element of this array should contain -* the (zero-based) index of the axis in the current Frame of -* the template FrameSet to which it corresponds. This array is -* used to establish from which template Frame axis any -* axis-dependent attributes should be obtained. -* -* If any axis in the result Frame is not associated with a -* template Frame axis, the corresponding element of this array -* should be set to -1. -* -* If a NULL pointer is supplied, the template and result axis -* indices are assumed to be identical. -* result -* Pointer to the Frame which is to receive the new attribute values. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *template; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - template = (AstFrameSet *) template_frame; - -/* Obtain a pointer to the current Frame and invoke its astOverlay - method to overlay its attributes. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( template, AST__CURRENT ); - astOverlay( fr, template_axes, result ); - fr = astAnnul( fr ); -} - -static void PermAxes( AstFrame *this_frame, const int perm[], int *status ) { -/* -* Name: -* PermAxes - -* Purpose: -* Permute the order of a FrameSet's axes. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void PermAxes( AstFrame *this, const int perm[], int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astPermAxes method -* inherited from the Frame class). - -* Description: -* This function permutes the order in which the axes in the -* current Frame of a FrameSet occur. - -* Parameters: -* this -* Pointer to the FrameSet. -* perm -* An array of int (with one element for each axis of the -* FrameSet's current Frame) which lists the axes in their new -* order. Each element of this array should be a (zero-based) -* axis index identifying the axes according to their old -* (un-permuted) order. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Only genuine permutations of the axis order are permitted, so -* each axis must be referenced exactly once in the "perm" array. -* - If more than one axis permutation is applied to the same Frame -* in a FrameSet, the effects are cumulative. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - AstPermMap *map; /* Pointer to axis permutation Mapping */ - int *invperm; /* Pointer to inverse permutation array */ - int axis; /* Loop counter for axes */ - int naxes; /* Number of FrameSet axes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the permutation array, to check that it describes a - genuine permutation. */ - astCheckPerm( this, perm, "astPermAxes" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astPermAxes method to permute its axes. Annul the Frame - pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astPermAxes( fr, perm ); - fr = astAnnul( fr ); - -/* Obtain the number of axes in the FrameSet's current Frame and allocate - memory to hold an inverse permutation array. */ - naxes = astGetNaxes( this ); - invperm = astMalloc( sizeof( int ) * (size_t) naxes ); - -/* Fill the inverse permutation array with values that will invert the - axis permutation supplied. */ - if ( astOK ) { - for ( axis = 0; axis < naxes; axis++ ) invperm[ perm[ axis ] ] = axis; - -/* Create a PermMap that will permute coordinate values in the same way as - the current Frame's axes have been permuted. */ - map = astPermMap( naxes, invperm, naxes, perm, NULL, "", status ); - -/* Modify the Frame's relationship to the rest of the Frames in the - FrameSet so that the correct coordinate values remain associated - with the permuted axes. */ - astRemapFrame( this, AST__CURRENT, map ); - -/* Annul the PermMap and free the inverse permutation array. */ - map = astAnnul( map ); - } - invperm = astFree( invperm ); -} - -static AstFrame *PickAxes( AstFrame *this_frame, int naxes, const int axes[], - AstMapping **map, int *status ) { -/* -* Name: -* PickAxes - -* Purpose: -* Create a new Frame by picking axes from a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstFrame *PickAxes( AstFrame *this, int naxes, const int axes[], -* AstMapping **map, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astPickAxes protected -* method inherited from the Frame class). - -* Description: -* This function creates a new Frame whose axes are copies of axes -* picked from the current Frame of an existing FrameSet. Other -* Frame attributes are also copied from this current Frame to the -* new Frame. Zero or more of the original axes may be picked in -* any order, but each can be used only once. Additional axes (with -* default characteristics) may be included in the new Frame if -* required. -* -* Optionally, a Mapping that converts between the original Frame's -* axes and those of the new Frame may also be returned. - -* Parameters: -* this -* Pointer to the FrameSet. -* naxes -* The number of axes required in the new Frame. -* axes -* Pointer to an array of int with naxes elements. This should -* contain (zero based) axis indices specifying the axes which -* are to be included in the new Frame, in the order -* required. Each axis index may occur only once. -* -* If additional (default) axes are also to be included, the -* corresponding elements of this array should be set to -1. -* map -* Address of a location to receive a pointer to a new -* Mapping. This will be a PermMap (or a UnitMap as a special -* case) that describes the axis permutation that has taken -* place between the current Frame of the FrameSet and the new -* Frame. The forward transformation will convert from the -* original FrameSet's axes to the new one's, and vice versa. -* -* If this Mapping is not required, a NULL value may be supplied -* for this parameter. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new Frame. - -* Notes: -* - The class of object returned may differ from that of the -* original current Frame, depending on which axes are -* selected. For example, if a single axis is picked from a -* SkyFrame (which always has two axes), the resulting Frame cannot -* be a valid SkyFrame, so will revert to the parent class (Frame) -* instead. -* - The new Frame contains a deep copy of all the data selected -* from the original current Frame. Modifying the new Frame will -* therefore not affect the FrameSet or the Frames it contains. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrame *frame; /* Pointer to Frame to be returned */ - AstFrameSet *this; /* Pointer to FrameSet structure */ - -/* Initialise the returned pointers. */ - if ( map ) *map = NULL; - frame = NULL; - -/* Check the global error status. */ - if ( !astOK ) return frame; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Check that a valid set of axes is being selected . */ - astValidateAxisSelection( this, naxes, axes, "astPickAxes" ); - -/* Obtain a pointer to the FrameSet's current Frame and use its - astPickAxes method to obtain the required new Frame and - Mapping. Annul the current Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - frame = astPickAxes( fr, naxes, axes, map ); - fr = astAnnul( fr ); - -/* If an error occurred, annul the Mapping pointer (if requested) and - the new Frame pointer. */ - if ( !astOK ) { - if ( map ) *map = astAnnul( *map ); - frame = astAnnul( frame ); - } - -/* Return the pointer to the new Frame. */ - return frame; -} - -static void PrimaryFrame( AstFrame *this_frame, int axis1, - AstFrame **frame, int *axis2, int *status ) { -/* -* Name: -* PrimaryFrame - -* Purpose: -* Uniquely identify a primary Frame and one of its axes. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void PrimaryFrame( AstFrame *this, int axis1, AstFrame **frame, -* int *axis2, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected -* astPrimaryFrame method inherited from the Frame class). - -* Description: -* This function returns information about the underlying (primary) -* Frame corresponding to a specified axis of the current Frame of -* a FrameSet, when this current Frame may be a compound Frame -* composed of more than one simpler one. - -* Parameters: -* this -* Pointer to the FrameSet. -* axis1 -* An axis index (zero-based) identifying the axis of the -* FrameSet's current Frame for which information is required. -* frame -* Address of a location to receive a pointer to the underlying -* (primary) frame to which the requested axis belongs -* (i.e. this will not be a compound Frame). -* axis2 -* Pointer to an int which is to receive the axis index within -* "frame" which identifies the axis being referred to, using -* the axis order that applied when the primary Frame was -* originally constructed (i.e. this function undoes all -* subsequent axis pemutations and the effects of combining -* Frames, in order to reveal the original underlying axis -* order). -* status -* Pointer to the inherited status variable. - -* Notes: -* - This protected method is provided so that class -* implementations can distinguish the axes of Frames from one -* another (e.g. can distinguish a longitude axis as being -* different from a latitide axis) even after their order has been -* permuted and they have been combined with axes from other -* Frames. -* - The reference count of the primary Frame will be incremented -* by one to reflect the new pointer returned. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Initialise the returned values. */ - *frame = NULL; - *axis2 = 0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index supplied. */ - (void) astValidateAxis( this, axis1, 1, "astPrimaryFrame" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke its - astPrimaryFrame method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astPrimaryFrame( fr, axis1, frame, axis2 ); - fr = astAnnul( fr ); - -/* If an error occurred, annul the returned object and clear the - returned axis value. */ - if ( !astOK ) { - *frame = astAnnul( *frame ); - *axis2 = 0; - } -} - -static double Rate( AstMapping *this_mapping, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astRate method -* inherited from the Frame class). - -* This function evaluates the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. -* -* The result is estimated by interpolating the function using a -* fourth order polynomial in the neighbourhood of the specified -* position. The size of the neighbourhood used is chosen to minimise -* the RMS residual per unit length between the interpolating -* polynomial and the supplied Mapping function. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* astRate() -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - AstMapping *map; /* Pointer to the base->current Mapping */ - double result; /* Returned rate of change */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_mapping; - -/* Obtain the Mapping between the base and current Frames in the - FrameSet (note this takes account of whether the FrameSet has been - inverted). */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Invoke the astRate method on the Mapping. */ - result = astRate( map, at, ax1, ax2 ); - -/* Annul the Mapping pointer. */ - map = astAnnul( map ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static void RecordIntegrity( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* RecordIntegrity - -* Purpose: -* Record the current integrity state of a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void RecordIntegrity( AstFrameSet *this, int *status ) - -* Class Membership: -* FrameSet member function. - -* Description: -* This function makes a record of the current integrity state of a -* FrameSet by taking a copy of its current Frame (it stores a -* pointer to this copy in a static variable). If the current Frame -* is subsequently modified, the RestoreIntegrity function can then -* attempt to restore the FrameSet's integrity to this recorded -* state by appropriately remapping its current Frame. - -* Parameters: -* this -* Pointer to the FrameSet. -*- -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFrame *current; /* Pointer to current Frame */ - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise the record of the FrameSet's integrity. */ - integrity_frame = NULL; - integrity_lost = 0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet's current Frame. */ - current = astGetFrame( this, AST__CURRENT ); - -/* Make a copy of this Frame, storing its pointer. */ - integrity_frame = astCopy( current ); - -/* Annul the current Frame pointer. */ - current = astAnnul( current ); -} - -static void RemapFrame( AstFrameSet *this, int iframe, AstMapping *map, int *status ) { -/* -*++ -* Name: -c astRemapFrame -f AST_REMAPFRAME - -* Purpose: -* Modify a Frame's relationship to other Frames in a FrameSet. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c void astRemapFrame( AstFrameSet *this, int iframe, AstMapping *map ) -f CALL AST_REMAPFRAME( THIS, IFRAME, MAP, STATUS ) - -* Class Membership: -* FrameSet method. - -* Description: -c This function modifies the relationship (i.e. Mapping) between a -f This routine modifies the relationship (i.e. Mapping) between a -* specified Frame in a FrameSet and the other Frames in that -* FrameSet. -* -* Typically, this might be required if the FrameSet has been used -* to calibrate (say) an image, and that image is re-binned. The -* Frame describing the image will then have undergone a coordinate -* transformation, and this should be communicated to the associated -c FrameSet using this function. -f FrameSet using this routine. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FrameSet. -c iframe -f IFRAME = INTEGER (Given) -* The index within the FrameSet of the Frame to be modified. -* This value should lie in the range from 1 to the number of -* Frames in the FrameSet (as given by its Nframe attribute). -c map -f MAP = INTEGER (Given) -* Pointer to a Mapping whose forward transformation converts -* coordinate values from the original coordinate system -* described by the Frame to the new one, and whose inverse -* transformation converts in the opposite direction. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - A value of AST__BASE or AST__CURRENT may be given for the -c "iframe" parameter to specify the base Frame or the current -f IFRAME argument to specify the base Frame or the current -* Frame respectively. -* - The relationship between the selected Frame and any other -c Frame within the FrameSet will be modified by this function, -f Frame within the FrameSet will be modified by this routine, -* but the relationship between all other Frames in the FrameSet -* remains unchanged. -* - The number of input coordinate values accepted by the Mapping -* (its Nin attribute) and the number of output coordinate values -* generated (its Nout attribute) must be equal and must match the -* number of axes in the Frame being modified. -* - If a simple change of axis order is required, then the -c astPermAxes function may provide a more straightforward method -f AST_PERMAXES routine may provide a more straightforward method -* of making the required changes to the FrameSet. -c - This function cannot be used to change the number of Frame -f - This routine cannot be used to change the number of Frame -* axes. To achieve this, a new Frame must be added to the FrameSet -c (astAddFrame) and the original one removed if necessary -c (astRemoveFrame). -f (AST_ADDFRAME) and the original one removed if necessary -f (AST_REMOVEFRAME). -* - Any variant Mappings associated with the remapped Frame (except -* for the current variant) will be lost as a consequence of calling this -* method (see attribute "Variant"). -*-- -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to Frame */ - int icur; /* Index of original current Frame */ - int naxes; /* Number of Frame axes */ - int nin; /* Number of Mapping input coordinates */ - int nout; /* Number of Mapping output coordinates */ - int varfrm; /* The index of the variants frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate and translate the Frame index supplied. */ - iframe = astValidateFrameIndex( this, iframe, "astRemapFrame" ); - -/* Variant Mappings from a source node to a destination node are stored - within the Frame object associated with the destination node. But - remapping a Frame causes the Frame to be dissociated from its original - node, and associated with a new node, leaving the original node - without any Frame in which to store its variant mappings. So we are - forced to remove the variant Mappings if the Frame is remapped. We do - this by clearing the Variant attribute before the Frame is remapped. - This will leave the current variant as the sole Mapping between the - original source and destination nodes. However, if the Frame being - remapped is just a mirror for another Frame, then we do not need to - do this since the Frame being mirrored is not itself being remapped - and so can retain its variant mappings. So we temporarily prevent the - remapped Frame from acting as a mirror before we clear the Variant - attribute. */ - icur = astGetCurrent( this ); - astSetCurrent( this, iframe ); - - varfrm = this->varfrm[ iframe - 1 ]; - this->varfrm[ iframe - 1 ] = 0; - - astClearVariant( this ); - - this->varfrm[ iframe - 1 ] = varfrm; - astSetCurrent( this, icur ); - -/* Obtain the number of input and output coordinates per point for the - Mapping supplied. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - -/* Obtain a pointer to the specified Frame and determine how many axes - it has. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, iframe ); - naxes = astGetNaxes( fr ); - fr = astAnnul( fr ); - -/* Check that the number of input coordinates matches the number of - Frame axes and report an error if necessary. */ - if ( astOK ) { - if ( nin != naxes ) { - astError( AST__NCPIN, "astRemapFrame(%s): Bad number of %s input " - "coordinate values (%d).", status, astGetClass( this ), - astGetClass( map ), nin ); - astError( AST__NCPIN, "The %s given should accept %d coordinate " - "value%s for each input point.", status, astGetClass( map ), naxes, - ( naxes == 1 ) ? "" : "s" ); - -/* Similarly, check that the number of output coordinates matches the - number of Frame axes. */ - } else if ( nout != naxes ) { - astError( AST__NCPIN, "astRemapFrame(%s): Bad number of %s output " - "coordinate values (%d).", status, astGetClass( this ), - astGetClass( map ), nout ); - astError( AST__NCPIN, "The %s given should generate %d " - "coordinate value%s for each output point.", status, - astGetClass( map ), naxes, ( naxes == 1 ) ? "" : "s" ); - } - } - -/* If there is more than one Frame present in the FrameSet, extend the - FrameSet arrays to hold a new node. */ - if ( astOK && ( this->nframe > 1 ) ) { - this->map = astGrow( this->map, this->nnode, sizeof( AstMapping * ) ); - this->link = astGrow( this->link, this->nnode, sizeof( int ) ); - this->invert = astGrow( this->invert, this->nnode, sizeof( int ) ); - -/* Clone and store a pointer to the Mapping. */ - if ( astOK ) { - this->map[ this->nnode - 1 ] = astClone( map ); - -/* Add a new "link" element showing that the new node is derived from - that of the old Frame and store the current value of the Invert - attribute for the Mapping. */ - this->link[ this->nnode - 1 ] = this->node[ iframe - 1 ]; - this->invert[ this->nnode - 1 ] = astGetInvert( map ); - -/* Increment the node count and associate the modified Frame with the - new node. */ - if ( astOK ) { - this->nnode++; - this->node[ iframe - 1 ] = this->nnode - 1; - -/* Tidy the resulting set of nodes, because the node originally - referenced by the Frame may no longer be needed. This also - simplifies any compound Mapping which may result if this node is - removed. */ - TidyNodes( this, status ); - } - } - } -} - -static void RemoveFrame( AstFrameSet *this, int iframe, int *status ) { -/* -*++ -* Name: -c astRemoveFrame -f AST_REMOVEFRAME - -* Purpose: -* Remove a Frame from a FrameSet. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "frameset.h" -c void astRemoveFrame( AstFrameSet *this, int iframe ) -f CALL AST_REMOVEFRAME( THIS, IFRAME, STATUS ) - -* Class Membership: -* FrameSet method. - -* Description: -c This function removes a Frame from a FrameSet. All other Frames -f This routine removes a Frame from a FrameSet. All other Frames -* in the FrameSet have their indices re-numbered from one (if -* necessary), but are otherwise unchanged. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the FrameSet. -c iframe -f IFRAME = INTEGER (Given) -* The index within the FrameSet of the Frame to be removed. -* This value should lie in the range from 1 to the number of -* Frames in the FrameSet (as given by its Nframe attribute). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Removing a Frame from a FrameSet does not affect the -* relationship between other Frames in the FrameSet, even if they -* originally depended on the Frame being removed. -* - The number of Frames in a FrameSet cannot be reduced to zero. -* An error will result if an attempt is made to remove the only -* remaining Frame. -* - A value of AST__BASE or AST__CURRENT may be given for the -c "iframe" parameter to specify the base Frame or the current -f IFRAME argument to specify the base Frame or the current -* Frame respectively. -* - If a FrameSet's base or current Frame is removed, the Base or -* Current attribute (respectively) of the FrameSet will have its -* value cleared, so that another Frame will then assume its role -* by default. -* - If any other Frame is removed, the base and current Frames -* will remain the same. To ensure this, the Base and/or Current -* attributes of the FrameSet will be changed, if necessary, to -* reflect any change in the indices of these Frames. -*-- -*/ - -/* Local Variables: */ - int ifr; /* Loop counter for Frames */ - int ii; /* Base/current Frame index */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate and translate the Frame index supplied. */ - iframe = astValidateFrameIndex( this, iframe, "astRemoveFrame" ); - if ( astOK ) { - -/* Reject any attempt to remove the final Frame from the FrameSet. */ - if ( this->nframe == 1 ) { - astError( AST__REMIN, "astRemoveFrame(%s): Invalid attempt to " - "remove the only Frame in a %s.", status, astGetClass( this ), - astGetClass( this ) ); - -/* If OK, annul the pointer to the selected Frame. */ - } else { - this->frame[ iframe - 1 ] = astAnnul( this->frame[ iframe - 1 ] ); - -/* Ensure that the variant Mappings in the Frame being removed are not - mirrored by any other Frames in the FrameSet. */ - RemoveMirrors( this, iframe, status ); - -/* Any Frames that are mirroring variants in Frames higher than the - removed Frame need to have their mirror frame indices decremented. */ - for ( ifr = 1; ifr <= this->nframe; ifr++ ) { - if( this->varfrm[ ifr - 1 ] > iframe ) this->varfrm[ ifr - 1 ]--; - } - -/* Loop to move all subsequent Frame pointers down in the FrameSet's - "frame" array to close the resulting gap. Also move the associated - "node" and "varfrm" array contents in the same way. */ - for ( ifr = iframe; ifr < this->nframe; ifr++ ) { - this->frame[ ifr - 1 ] = this->frame[ ifr ]; - this->node[ ifr - 1 ] = this->node[ ifr ]; - this->varfrm[ ifr - 1 ] = this->varfrm[ ifr ]; - } - this->frame[ this->nframe - 1 ] = NULL; - this->node[ this->nframe - 1 ] = -1; - this->varfrm[ this->nframe - 1 ] = 0; - -/* Decrement the Frame count. */ - this->nframe--; - -/* Tidy the nodes in the FrameSet. */ - TidyNodes( this, status ); - -/* If the Base attribute is set and the removed Frame was the base - Frame, then clear the attribute value so that a new base Frame will - be selected by default. */ - if ( astTestBase( this ) ) { - ii = astGetBase( this ); - if ( iframe == ii ) { - astClearBase( this ); - -/* If the index of the removed Frame is smaller than the base Frame - index, then decrement the Base attribute so that the same base - Frame will be used in future. */ - } else if ( iframe < ii ) { - astSetBase( this, ii - 1 ); - } - } - -/* Repeat the above procedure for the current Frame. */ - if ( astTestCurrent( this ) ) { - ii = astGetCurrent( this ); - if ( iframe == ii ) { - astClearCurrent( this ); - } else if ( iframe < ii ) { - astSetCurrent( this, ii - 1 ); - } - } - } - } -} - -static void RemoveMirrors( AstFrameSet *this, int iframe, int *status ) { -/* -* Name: -* RemoveMirrors - -* Purpose: -* Ensure no other Frames act as mirrors for a specified Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void RemoveMirrors( AstFrameSet *this, int iframe, int *status ) - -* Class Membership: -* Private function. - -* Description: -* This function searchs the FrameSet for Frames that are currently -* acting as mirrors for the variant Mappings in the Frame with index -* "iframe", and disables mirroring in any found Frames. It should be -* used when "iframe" has its variant Mappings removed. - -* Parameters: -* this -* Pointer to the FrameSet. -* iframe -* One-based index of a Frame that has had its variant Mappings -* removed. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int *frmlist; - int ifr; - int nfrm; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Iniitalise a list to hold the indices of the FRames that mirror - "iframe". */ - nfrm = 0; - frmlist = NULL; - -/* Check each Frame in the FrameSet. */ - for( ifr = 1; ifr <= this->nframe; ifr++ ) { - -/* Get the index of the Frame that defines the variant Mappings to use - with Frame "ifr". If this is "iframe", then add "ifr" to the list of - Frames that need to be "de-mirrored". We cannot "de-mirror" the Frame - immediately as doing so may break a chain of mirrors, resulting in the - Frames higher up the chain no longer being associated with "iframe". */ - if( GetVarFrm( this, ifr, status ) == iframe ) { - frmlist = astGrow( frmlist, nfrm + 1, sizeof( *frmlist ) ); - if( astOK ) frmlist[ nfrm++ ] = ifr; - } - } - -/* Loop round all the Frames found above that mirror "iframe". */ - for( ifr = 0; ifr < nfrm; ifr++ ) { - -/* Indicate that the Frame no longer mirrors any other Frame. */ - this->varfrm[ frmlist[ ifr ] - 1 ] = 0; - } - -/* Free the list. */ - frmlist = astFree( frmlist ); -} - -static AstMapping *RemoveRegions( AstMapping *this_mapping, int *status ) { -/* -* Name: -* RemoveRegions - -* Purpose: -* Remove any Regions from a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstMapping *RemoveRegions( AstMapping *this, int *status ) - -* Class Membership: -* FrameSet method (over-rides the astRemoveRegions method inherited -* from the Mapping class). - -* Description: -* This function searches the supplied Mapping (which may be a -* compound Mapping such as a FrameSet) for any component Mappings -* that are instances of the AST Region class. It then creates a new -* Mapping from which all Regions have been removed. If a Region -* cannot simply be removed (for instance, if it is a component of a -* parallel FrameSet), then it is replaced with an equivalent UnitMap -* in the returned Mapping. -* -* The implementation provided by the FrameSet class invokes the -* astRemoveRegions method on all the component Frames and Mappings, -* and joins the results together into a new FrameSet. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the modified mapping. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame **newfrms; /* Array of new Frames */ - AstFrameSet *new; /* Pointer to new FrameSet */ - AstFrameSet *this; /* Pointer to FrameSet structure */ - AstMapping **newmaps; /* Array of new Mappings */ - AstMapping *result; /* Result pointer to return */ - int changed; /* Has any mapping been changed? */ - int i; /* Loop count */ - int nax; /* Number of Frame axes */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the FrameSet. */ - this = (AstFrameSet *) this_mapping; - -/* Allocate arrays to hold the modified Mapping and Frame pointers. */ - newmaps = astMalloc( sizeof( AstMapping *)*( this->nnode - 1 ) ); - newfrms = astMalloc( sizeof( AstFrame *)*( this->nframe ) ); - if( astOK ) { - -/* Invoke the astRemoveRegions method on all the component Mappings. */ - changed = 0; - for( i = 0; i < this->nnode - 1; i++ ) { - newmaps[ i ] = astRemoveRegions( this->map[ i ] ); - -/* Note if any Mapping was changed. */ - if( newmaps[ i ] != this->map[ i ] ) { - changed = 1; - -/* The implementation of the astRemoveRegions method provided by the - Region class returns a Frame rather than a UnitMap. But we need - Mappings here, not Frames. So if the new Mapping is a Frame, replace - it with an equivalent UnitMap. */ - if( astIsAFrame( newmaps[ i ] ) ) { - nax = astGetNin( newmaps[ i ] ); - (void) astAnnul( newmaps[ i ] ); - newmaps[ i ] = (AstMapping *) astUnitMap( nax, " ", status ); - } - } - } - -/* Invoke the astRemoveRegions method on all the component Frames. */ - for( i = 0; i < this->nframe; i++ ) { - newfrms[ i ] = astRemoveRegions( this->frame[ i ] ); - -/* Note if any Frame was changed. */ - if( newfrms[ i ] != this->frame[ i ] ) changed = 1; - } - -/* If no component was modified, just return a clone of the supplied - pointer. */ - if( ! changed ) { - result = astClone( this ); - -/* Otherwise, we need to create a new FrameSet to return. We take a deep - copy of the supplied FrameSet and then modify the Mappings and Frames - so that we retain any extra information in the supplied FrameSet. */ - } else { - new = astCopy( this ); - - for( i = 0; i < this->nnode - 1; i++ ) { - (void) astAnnul( new->map[ i ] ); - new->map[ i ] = astClone( newmaps[ i ] ); - } - - for( i = 0; i < this->nframe; i++ ) { - (void) astAnnul( new->frame[ i ] ); - new->frame[ i ] = astClone( newfrms[ i ] ); - } - - result = (AstMapping *) new; - } - -/* Free resources. */ - for( i = 0; i < this->nnode - 1; i++ ) { - newmaps[ i ] = astAnnul( newmaps[ i ] ); - } - - for( i = 0; i < this->nframe; i++ ) { - newfrms[ i ] = astAnnul( newfrms[ i ] ); - } - - } - - newfrms = astFree( newfrms ); - newmaps = astFree( newmaps ); - -/* Annul the returned Mapping if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void ReportPoints( AstMapping *this_mapping, int forward, - AstPointSet *in_points, AstPointSet *out_points, int *status ) { -/* -* Name: -* ReportPoints - -* Purpose: -* Report the effect of transforming a set of points using a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void ReportPoints( AstMapping *this, int forward, -* AstPointSet *in_points, AstPointSet *out_points, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astReportPoints -* method inherited from the Frame class). - -* Description: -* This function reports the coordinates of a set of points before -* and after being transformed by a FrameSet, by writing them to -* standard output. - -* Parameters: -* this -* Pointer to the FrameSet. -* forward -* A non-zero value indicates that the FrameSet's forward -* coordinate transformation has been applied, while a zero -* value indicates the inverse transformation. -* in_points -* Pointer to a PointSet which is associated with the -* coordinates of a set of points before the FrameSet was -* applied. -* out_points -* Pointer to a PointSet which is associated with the -* coordinates of the same set of points after the FrameSet has -* been applied. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *base_frame; /* Pointer to current Frame */ - AstFrame *current_frame; /* Pointer to base Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double **ptr_in; /* Pointer to array of input data pointers */ - double **ptr_out; /* Pointer to array of output data pointers */ - int coord; /* Loop counter for coordinates */ - int ncoord_in; /* Number of input coordinates per point */ - int ncoord_out; /* Number of output coordinates per point */ - int npoint; /* Number of points to report */ - int npoint_in; /* Number of input points */ - int npoint_out; /* Number of output points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_mapping; - -/* Obtain the numbers of points and coordinates associated with each - PointSet. */ - npoint_in = astGetNpoint( in_points ); - npoint_out = astGetNpoint( out_points ); - ncoord_in = astGetNcoord( in_points ); - ncoord_out = astGetNcoord( out_points ); - -/* Obtain the pointers that give access to the coordinate data - associated with each PointSet. */ - ptr_in = astGetPoints( in_points ); - ptr_out = astGetPoints( out_points ); - -/* In the event that both PointSets don't contain equal numbers of - points (this shouldn't actually happen), simply use the minimum - number. */ - npoint = ( npoint_in < npoint_out ) ? npoint_in : npoint_out; - -/* Obtain pointers to the FrameSet's base and current Frames. */ - base_frame = astGetFrame( this, AST__BASE ); - current_frame = astGetFrame( this, AST__CURRENT ); - -/* Loop to report the effect of the transformation on each point in - turn. */ - if ( astOK ) { - for ( point = 0; point < npoint; point++ ) { - -/* Report the input coordinates (in parentheses and separated by - commas). Format each value for display using the appropriate - Frame's astFormat method. */ - printf( "(" ); - for ( coord = 0; coord < ncoord_in; coord++ ) { - printf( "%s%s", coord ? ", " : "", - astFormat( forward ? base_frame : current_frame, - coord, ptr_in[ coord ][ point ] ) ); - } - -/* Similarly report the output coordinates, this time formatting - values using the other Frame's astFormat method. */ - printf( ") --> (" ); - for ( coord = 0; coord < ncoord_out; coord++ ) { - printf( "%s%s", coord ? ", " : "", - astFormat( forward ? current_frame : base_frame, - coord, ptr_out[ coord ][ point ] ) ); - } - printf( ")\n" ); - } - } - -/* Annul the Frame pointers. */ - base_frame = astAnnul( base_frame ); - current_frame = astAnnul( current_frame ); -} - -static void Resolve( AstFrame *this_frame, const double point1[], - const double point2[], const double point3[], - double point4[], double *d1, double *d2, int *status ){ -/* -* Name: -* Resolve - -* Purpose: -* Resolve a vector into two orthogonal components - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void Resolve( AstFrame *this, const double point1[], -* const double point2[], const double point3[], -* double point4[], double *d1, double *d2, int *status ); - -* Class Membership: -* FrameSet member function (over-rides the protected astResolve -* method inherited from the Frame class). - -* Description: -* This function resolves a vector into two perpendicular components. -* The vector from point 1 to point 2 is used as the basis vector. -* The vector from point 1 to point 3 is resolved into components -* parallel and perpendicular to this basis vector. The lengths of the -* two components are returned, together with the position of closest -* aproach of the basis vector to point 3. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vector to be resolved. -* point2 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -* point3 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the vector to be -* resolved. -* point4 -* An array of double, with one element for each Frame axis -* in which the coordinates of the point of closest approach of the -* basis vector to point 3 will be returned. -* d1 -* The address of a location at which to return the distance from -* point 1 to point 4 (that is, the length of the component parallel -* to the basis vector). Positive values are in the same sense as -* movement from point 1 to point 2. -* d2 -* The address of a location at which to return the distance from -* point 4 to point 3 (that is, the length of the component -* perpendicular to the basis vector). The value is always positive. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Each vector used in this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value, or if the required -* output values are undefined. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astResolve method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astResolve( fr, point1, point2, point3, point4, d1, d2 ); - fr = astAnnul( fr ); - -} - -static AstPointSet *ResolvePoints( AstFrame *this_frame, const double point1[], - const double point2[], AstPointSet *in, - AstPointSet *out, int *status ) { -/* -* Name: -* ResolvePoints - -* Purpose: -* Resolve a set of vectors into orthogonal components - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstPointSet *astResolvePoints( AstFrame *this, const double point1[], -* const double point2[], AstPointSet *in, -* AstPointSet *out ) - -* Class Membership: -* FrameSet member function (over-rides the astResolvePoints method -* inherited from the Frame class). - -* Description: -* This function takes a Frame and a set of vectors encapsulated -* in a PointSet, and resolves each one into two orthogonal components, -* returning these two components in another PointSet. -* -* This is exactly the same as the public astResolve method, except -* that this method allows many vectors to be processed in a single call, -* thus reducing the computational cost of overheads of many -* individual calls to astResolve. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vectors to be resolved. -* point2 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -* in -* Pointer to the PointSet holding the ends of the vectors to be -* resolved. -* out -* Pointer to a PointSet which will hold the length of the two -* resolved components. A NULL value may also be given, in which -* case a new PointSet will be created by this function. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. The first axis will -* hold the lengths of the vector components parallel to the basis vector. -* These values will be signed (positive values are in the same sense as -* movement from point 1 to point 2. The second axis will hold the lengths -* of the vector components perpendicular to the basis vector. These -* values will always be positive. - -* Notes: -* - The number of coordinate values per point in the input -* PointSet must match the number of axes in the supplied Frame. -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and 2 coordinate values per point. -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstFrameSet *this; /* Pointer to FrameSet structure */ - AstFrame *fr; /* Pointer to current Frame */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astResolvePoints method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astResolvePoints( this, point1, point2, in, out ); - fr = astAnnul( fr ); - -/* Return a pointer to the output PointSet. */ - return result; - -} - -static void RestoreIntegrity( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* RestoreIntegrity - -* Purpose: -* Restore a previous integrity state for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void RestoreIntegrity( AstFrameSet *this ) - -* Class Membership: -* FrameSet member function. - -* Description: -* This function restores a FrameSet to a previous integrity state, -* as recorded (in static variables) by a previous invocation of -* the RecordIntegrity function. It does this by appropriately -* remapping the FrameSet's current Frame, if this appears -* necessary. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Notes: -* - The previous record of the FrameSet's integrity state (as -* recorded by RecordIntegrity) is deleted by this function, even -* if it is invoked with the global error status set. -* - An error will result if the previous integrity state cannot be -* restored. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFrame *current; /* Pointer to current Frame */ - AstFrameSet *cvt; /* Pointer to conversion FrameSet */ - AstMapping *map; /* Pointer to conversion Mapping */ - int flags; /* Flags associated with current frame */ - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Check that a previous record of the FrameSet's integrity state has - been made. Do not modify the FrameSet if it appears that the - previous integrity state has not been lost (i.e. that the current - Frame has not been modified), nor if there is only one Frame - present. Check the global error status. */ - if ( integrity_frame && integrity_lost && ( astGetNframe( this ) > 1 ) && - astOK ) { - -/* Obtain a pointer to the current Frame. */ - current = astGetFrame( this, AST__CURRENT ); - -/* Since we need to obtain a conversion between the recorded copy of - this Frame and the current one, we must match their Domain - attributes (otherwise conversion cannot be performed). Do this by - changing the recorded copy as necessary. */ - if ( astTestDomain( current ) ) { - astSetDomain( integrity_frame, astGetDomain( current ) ); - } else { - astClearDomain( integrity_frame ); - } - -/* Temporarily set both Frames AST__INTFLAG flag to indicate that the - following call to astConvert is part of the process of restoring a - FrameSet's integrity. Some classes of Frame (e.g. DSBSpecFrames) may - choose to return a different Mapping in this case. */ - astSetFrameFlags( integrity_frame, astGetFrameFlags( integrity_frame ) - | AST__INTFLAG ); - flags = astGetFrameFlags( current ); - astSetFrameFlags( current, flags | AST__INTFLAG ); - -/* Obtain the required conversion FrameSet, restore the original frame - flags and annul the current Frame pointer. */ - cvt = astConvert( integrity_frame, current, "" ); - astSetFrameFlags( current, flags ); - current = astAnnul( current ); - -/* If no conversion could be found, then the FrameSet's integrity - state cannot be restored, so report an error. */ - if ( !cvt ) { - if( astOK ) { - astError( AST__ILOST, "%s(%s): Cannot maintain %s integrity.", status, - integrity_method, astGetClass( this ), - astGetClass( this ) ); - } - -/* Otherwise, obtain a pointer to the conversion Mapping. */ - } else { - map = astGetMapping( cvt, AST__BASE, AST__CURRENT ); - -/* If the Mapping is not a UnitMap (i.e. a null Mapping), then use it - to remap the FrameSet's current Frame. */ - if ( strcmp( astGetClass( map ), "UnitMap" ) ) { - astRemapFrame( this, AST__CURRENT, map ); - } - -/* Annul the conversion Mapping and Frameset pointers. */ - map = astAnnul( map ); - cvt = astAnnul( cvt ); - } - } - -/* Delete the recorded integrity information by annulling the original - copy of the current Frame (thus deleting it) and resetting the - associated modification flag. */ - if ( integrity_frame ) integrity_frame = astAnnul( integrity_frame ); - integrity_lost = 0; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* FrameSet member function (extends the astSetAttrib method -* inherited from the Frame class). - -* Description: -* This function assigns an attribute value for a FrameSet, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the FrameSet. -* setting -* Pointer to a null terminated string specifying the new -* attribute value. -* status -* Pointer to the inherited status variable. - -* Attributes: -* The set of attribute values is not fixed and is determined by -* the current Frame. In addition, the FrameSet class defines the -* following attributes: -* -* Base (integer) -* Current (integer) - -* Notes: -* - This protected method is intended to be invoked by the Object -* astSet method and makes additional attributes accessible to it. -* - All attribute settings passed to this function are simply -* passed on to the corresponding method for the FrameSet's current -* Frame. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to a Frame within the FrameSet */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *dom; /* Pointer to Domain string */ - int base; /* Base attribute value */ - int base_off; /* Offset of Base value string */ - int current; /* Current attribute value */ - int current_off; /* Offset of Current value string */ - int id; /* Offset of ID string */ - int invert; /* Invert attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - int nfrm; /* Number of Frames in FrameSet */ - int report; /* Report attribute value */ - int variant; /* Offset of Variant string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* We first handle attributes that apply to the FrameSet as a whole - (rather than to the current Frame). */ - -/* Base. */ -/* ----- */ -/* Read as an integer. */ - if ( nc = 0, - ( 1 == astSscanf( setting, "base= %d %n", &base, &nc ) ) - && ( nc >= len ) ) { - astSetBase( this, base ); - -/* Also allow a string. */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "base= %n%*s %n", &base_off, &nc ) ) - && ( nc >= len ) ) { - -/* Check for "AST__CURRENT" or "Current". */ - if ( astChrMatch( "AST__CURRENT", setting + base_off ) || - astChrMatch( "Current", setting + base_off ) ) { - astSetBase( this, AST__CURRENT ); - -/* Check for "AST__BASE" or "Base" (possible, although not very - useful). */ - } else if ( astChrMatch( "AST__BASE", setting + base_off ) || - astChrMatch( "Base", setting + base_off ) ) { - -/* If the FrameSet contains a Frame with the given Domain name, make it - the base Frame. */ - } else { - nfrm = astGetNframe( this ); - for( base = 1; base <= nfrm; base++ ) { - fr = astGetFrame( this, base ); - dom = astGetDomain( fr ); - fr = astAnnul( fr ); - if( astChrMatch( dom, setting + base_off ) ) break; - } - - if( base <= nfrm ) { - astSetBase( this, base ); - -/* Report an error if the value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid index value for " - "Base Frame \"%s\".", status, - astGetClass( this ), setting + base_off ); - } - } - -/* Current. */ -/* -------- */ -/* Since this determines the choice of current Frame, we must restore - the integrity state of the FrameSet before changing this attribute - and record the new integrity state afterwards. */ - -/* Read as an integer. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "current= %d %n", ¤t, &nc ) ) - && ( nc >= len ) ) { - RestoreIntegrity( this, status ); - astSetCurrent( this, current ); - RecordIntegrity( this, status ); - -/* Also allow a string. */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "current= %n%*s %n", - ¤t_off, &nc ) ) - && ( nc >= len ) ) { - -/* Check for "AST__BASE" or "Base". */ - if ( astChrMatch( "AST__BASE", setting + current_off ) || - astChrMatch( "Base", setting + current_off ) ) { - RestoreIntegrity( this, status ); - astSetCurrent( this, AST__BASE ); - RecordIntegrity( this, status ); - -/* Check for "AST__CURRENT" or "Current" (possible, although not very - useful). */ - } else if ( astChrMatch( "AST__CURRENT", setting + current_off ) || - astChrMatch( "Current", setting + current_off ) ) { - -/* If the FrameSet contains a Frame with the given Domain name, make it - the current Frame. */ - } else { - nfrm = astGetNframe( this ); - for( current = 1; current <= nfrm; current++ ) { - fr = astGetFrame( this, current ); - dom = astGetDomain( fr ); - fr = astAnnul( fr ); - if( astChrMatch( dom, setting + current_off ) ) break; - } - - if( current <= nfrm ) { - RestoreIntegrity( this, status ); - astSetCurrent( this, current ); - RecordIntegrity( this, status ); - -/* Report an error if the value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid index value for " - "Current Frame \"%s\".", status, - astGetClass( this ), setting + current_off ); - } - } - -/* ID. */ -/* --- */ - } else if ( nc = 0, ( 0 == astSscanf( setting, "id=%n%*[^\n]%n", &id, &nc ) ) - && ( nc >= len ) ) { - astSetID( this, setting + id ); - -/* Ident. */ -/* ------ */ - } else if ( nc = 0, ( 0 == astSscanf( setting, "ident=%n%*[^\n]%n", &id, &nc ) ) - && ( nc >= len ) ) { - astSetIdent( this, setting + id ); - -/* Invert. */ -/* ------- */ -/* Since this affects the choice of current Frame, we must restore the - integrity state of the FrameSet before changing this attribute and - record the new integrity state afterwards. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "invert= %d %n", &invert, &nc ) ) - && ( nc >= len ) ) { - RestoreIntegrity( this, status ); - astSetInvert( this, invert ); - RecordIntegrity( this, status ); - -/* Report. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "report= %d %n", &report, &nc ) ) - && ( nc >= len ) ) { - astSetReport( this, report ); - -/* Variant. */ -/* -------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "variant=%n%*[^\n]%n", &variant, &nc ) ) - && ( nc >= len ) ) { - astSetVariant( this, setting + variant ); - -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* If the attribute was not recognised, use this macro to report an error - if a read-only attribute has been specified. */ - } else if ( MATCH( "allvariants" ) || - MATCH( "class" ) || - MATCH( "nframe" ) || - MATCH( "nin" ) || - MATCH( "nobject" ) || - MATCH( "nout" ) || - MATCH( "refcount" ) || - MATCH( "tranforward" ) || - MATCH( "traninverse" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Pass unrecognised settings on to the FrameSet's current Frame for - further interpretation. */ - } else { - -/* Force a copy to be made of the current Frame, if needed, to make it - independent of other Frames within the FrameSet. */ - (void) ForceCopy( this, AST__CURRENT, status ); - -/* Obtain a pointer to the current Frame and invoke its astSetAttrib - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astSetAttrib( fr, setting ); - fr = astAnnul( fr ); - -/* Note that the current Frame has been modified. */ - integrity_lost = 1; - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static void SetAxis( AstFrame *this_frame, int axis, AstAxis *newaxis, int *status ) { -/* -* Name: -* SetAxis - -* Purpose: -* Set a new Axis for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void SetAxis( AstFrame *this, int axis, AstAxis *newaxis, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astSetAxis method -* inherited from the Frame class). - -* Description: -* This function allows a new Axis object to be associated with one -* of the axes of the current Frame in a FrameSet, replacing the -* previous one. Each Axis object contains a description of the -* quantity represented along one of the Frame's axes, so this -* function allows this description to be exchanged for another -* one. - -* Parameters: -* this -* Pointer to the FrameSet. -* axis -* The index (zero-based) of the axis whose associated Axis -* object is to be replaced. -* newaxis -* Pointer to the new Axis object. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index supplied. */ - (void) astValidateAxis( this, axis, 1, "astSetAxis" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astSetAxis method to assign the new Axis object. Annul the - Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astSetAxis( fr, axis, newaxis ); - fr = astAnnul( fr ); -} - -static void SetBase( AstFrameSet *this, int iframe, int *status ) { -/* -*+ -* Name: -* astSetBase - -* Purpose: -* Set a value for the Base attribute of a FrameSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* void astSetBase( AstFrameSet *this, int iframe ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function sets a value for the Base attribute of a FrameSet. This -* value is an index that identifies the base Frame for the FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. -* iframe -* Value to be set for the Base attribute. - -* Notes: -* - A value of AST__BASE or AST__CURRENT may be given for the -* "iframe" parameter to identify the base Frame or the current -* Frame respectively. -*- -*/ - -/* Local Variables: */ - int invert; /* FrameSet is inverted? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate and translate the Frame index supplied. */ - iframe = astValidateFrameIndex( this, iframe, "astSetBase" ); - -/* Determine if the FrameSet has been inverted. */ - invert = astGetInvert( this ); - -/* If it has not been inverted, set the base Frame index, otherwise - set the current Frame index instead. */ - if ( astOK ) *( invert ? &this->current : &this->base ) = iframe; -} - -static void SetCurrent( AstFrameSet *this, int iframe, int *status ) { -/* -*+ -* Name: -* astSetCurrent - -* Purpose: -* Set a value for the Current attribute of a FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "frameset.h" -* int astSetCurrent( AstFrameSet *this, int iframe ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function sets a value for the Current attribute of a -* FrameSet. This attribute is an index that identifies the current -* Frame for the FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. -* iframe -* Value to be set for the Current attribute. - -* Notes: -* - A value of AST__BASE or AST__CURRENT may be given for the -* "iframe" parameter to identify the base Frame or the current -* Frame respectively. -*- -*/ - -/* Local Variables: */ - int invert; /* FrameSet is inverted? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate and translate the Frame index supplied. */ - iframe = astValidateFrameIndex( this, iframe, "astSetCurrent" ); - -/* Determine if the FrameSet has been inverted. */ - invert = astGetInvert( this ); - -/* If it has not been inverted, set the current frame index, otherwise - set the base Frame index instead. */ - if ( astOK ) *( invert ? &this->base : &this->current ) = iframe; -} - -static void SetVariant( AstFrameSet *this, const char *variant, int *status ) { -/* -*+ -* Name: -* astSetVariant - -* Purpose: -* Set a value for the Variant attribute of a FrameSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* void astSetVariant( AstFrameSet *this, const char *variant ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function sets a value for the Variant attribute of a FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. -* variant -* Value to be set for the Variant attribute. - -* Notes: -* - An error will be reported if the supplied variant name cannot be -* found in the Variants FrameSet associated with the current Frame. - -*- -*/ - -/* Local Variables: */ - AstCmpMap *map6; - AstCmpMap *map5; - AstCmpMap *map4; - AstFrame *frm; - AstFrame *vfrm; - AstFrameSet *tfs; - AstFrameSet *vfs; - AstMapping *map0; - AstMapping *map2; - AstMapping *map3; - AstMapping *map1; - char *myvar; - const char *dom; - int icur; - int ifrm; - int inode; - int inv0; - int inv; - int nfrm; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a copy of the supplied string and clean it. */ - myvar = astStore( NULL, variant, strlen( variant ) + 1 ); - astRemoveLeadingBlanks( myvar ); - astChrCase( NULL, myvar, 1, 0 ); - if( astOK ) { - myvar[ astChrLen( myvar ) ] = 0; - -/* Get the one-based index of the Frame that defines the available - variant Mappings. */ - icur = GetVarFrm( this, astGetCurrent( this ), status ); - -/* Get the variants FrameSet from the Frame selected above. */ - frm = astGetFrame( this, icur ); - vfs = astGetFrameVariants( frm ); - -/* If there is no variants FrameSet in the Frame, the only allowed value - for "Variant" is the Domain name of the current Frame. */ - if( ! vfs ) { - dom = astGetDomain( this ); - if( astOK && strcmp( myvar, dom ) ) { - astError( AST__ATTIN, "astSetVariant(%s): Unknown Frame " - "variant '%s' requested.", status, astGetClass( this ), - myvar ); - } - -/* If there is a variants FrameSet in the Frame... */ - } else { - -/* Find the index of the Frame in the Variants FrameSet that has a Domain - equal to myvar. */ - nfrm = astGetNframe( vfs ); - for( ifrm = 0; ifrm < nfrm; ifrm++ ) { - vfrm = astGetFrame( vfs, ifrm + 1 ); - dom = astGetDomain( vfrm ); - vfrm = astAnnul( vfrm ); - if( !astOK || !strcmp( myvar, dom ) ) break; - } - -/* Report an error if no such Frame found. */ - if( ifrm == nfrm && astOK ) { - astError( AST__ATTIN, "astSetVariant(%s): Unknown Frame " - "variant '%s' requested - available variants are " - "'%s'.", status, astGetClass(this), myvar, - astGetAllVariants(this) ); - -/* Otherwise, get a Mapping from the current Frame in "this" to the - currently selected Variant Frame. We cannot assume that they are the - same as attributes of the current Frame (e.g. System) may have been - changed since the variant was added. If the required Frame is already - the current Frame, there is nothing more to do since the required - variant is already selected. */ - } else if( ifrm + 1 != astGetCurrent( vfs ) ){ - vfrm = astGetFrame( vfs, AST__CURRENT ); - dom = astGetDomain( frm ); - if( dom ) dom = astStore( NULL, dom, strlen( dom ) + 1 ); - astSetDomain( frm, astGetDomain( vfrm ) ); - tfs = astConvert( frm, vfrm, "" ); - astSetDomain( frm, dom ); - if( tfs ) { - map1 = astGetMapping( tfs, AST__BASE, AST__CURRENT ); - tfs = astAnnul( tfs ); - vfrm = astAnnul( vfrm ); - -/* Get the Mapping from the original Variant Frame to the requested variant - Frame. */ - map2 = astGetMapping( vfs, AST__CURRENT, ifrm + 1 ); - -/* Get a Mapping from the new variant Frame to the current Frame in "this". */ - vfrm = astGetFrame( vfs, ifrm + 1 ); - astSetDomain( frm, astGetDomain( vfrm ) ); - tfs = astConvert( vfrm, frm, "" ); - astSetDomain( frm, dom ); - if( tfs ) { - map3 = astGetMapping( tfs, AST__BASE, AST__CURRENT ); - tfs = astAnnul( tfs ); - -/* Concatentate the three Mappings, to get the Mapping from the old - variant Frame to the new variant Frame. */ - map4 = astCmpMap( map1, map2, 1, " ", status ); - map5 = astCmpMap( map4, map3, 1, " ", status ); - -/* Now we modify the Mapping in the FrameSet. First get the index of the node - with which the Frame is associated. */ - inode = this->node[ icur - 1 ]; - -/* Get the Mapping that generates the node values, and its Invert flag. */ - map0 = this->map[ inode - 1 ]; - inv0 = this->invert[ inode - 1 ]; - -/* Temporarily reset the invert flag in the Mapping to account for any - changes made to the Mapping via other pointers. */ - inv = astGetInvert( map0 ); - astSetInvert( map0, inv0 ); - -/* Concatentate with "map5" to get the Mapping form the the parent node - to the new variant of the current node. */ - map6 = astCmpMap( map0, map5, 1, " ", status ); - -/* Simplify it and use it to replace the Mapping in the FrameSet structure. */ - this->map[ inode - 1 ] = astSimplify( map6 ); - this->invert[ inode - 1 ] = astGetInvert( this->map[ inode - 1 ] ); - -/* Re-instate the original Invert flag and free the old Mapping pointer. */ - astSetInvert( map0, inv ); - map0 = astAnnul( map0 ); - -/* Make the variant Frame the current Frame within the Variants FrameSet. */ - astSetCurrent( vfs, ifrm + 1 ); - -/* Free resources. */ - map6 = astAnnul( map6 ); - map5 = astAnnul( map5 ); - map4 = astAnnul( map4 ); - map3 = astAnnul( map3 ); - -/* Report an error if a Mapping cannot be found from the new variant Frame - to the current Frame in "this". */ - } else if( astOK ) { - astError( AST__INTER, "astSetVariant(%s): Cannot convert " - "from a %s with Domain '%s' to a %s with Domain " - "'%s' (internal programming error).", status, - astGetClass( this ), astGetClass( vfrm ), - astGetDomain( vfrm ), astGetClass( frm ), - astGetDomain( frm ) ); - } - -/* Free resources. */ - map2 = astAnnul( map2 ); - map1 = astAnnul( map1 ); - -/* Report an error if a Mapping cannot be found from the current Frame in - "this" to the current Variant Frame. */ - } else if( astOK ) { - astError( AST__INTER, "astSetVariant(%s): Cannot convert " - "from a %s with Domain '%s' to a %s with Domain " - "'%s' (internal programming error).", status, - astGetClass( this ), astGetClass( frm ), - astGetDomain( frm ), astGetClass( vfrm ), - astGetDomain( vfrm ) ); - } - -/* Free resources. */ - vfrm = astAnnul( vfrm ); - dom = astFree( (void *) dom ); - } - -/* Annul the pointer to the Variants FrameSet. */ - vfs = astAnnul( vfs ); - } - -/* Annul the pointer to the current Frame in "this". */ - frm = astAnnul( frm ); - } - -/* Free the memory holding the cleaned variant name. */ - myvar = astFree( myvar ); -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mappings in a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* FrameSet method (over-rides the astSimplify method inherited -* from the Frame class). - -* Description: -* This function simplifies the Mappings in a FrameSet to eliminate -* redundant computational steps, or to merge separate steps which -* can be performed more efficiently in a single operation. - -* Parameters: -* this -* Pointer to the original FrameSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A new pointer to the (possibly simplified) FrameSet. If -* simplification was not possible, this will be a cloned pointer -* to the original FrameSet. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrameSet *new; /* Pointer to new (simpler?) FrameSet */ - AstFrameSet *this; /* Pointer to original FrameSet structure */ - AstMapping *map; /* Pointer to Mapping */ - AstMapping *result; /* Result pointer to return */ - AstMapping *tmp; /* Temporary Mapping pointer */ - int inode; /* Loop counter for FrameSet nodes */ - int inv; /* Mapping Invert attribute value */ - int invert; /* Invert flag value */ - int set; /* Invert attribute set? */ - int simpler; /* Simplification achieved? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_mapping; - -/* Make a copy of the FrameSet, since we may alter it (this is a deep - copy, which is a minor limitation of the current implementation). */ - new = astCopy( this ); - -/* Loop to examine each of the Mappings between the Frames in the - copy. */ - simpler = 0; - for ( inode = 1; astOK && ( inode < new->nnode ); inode++ ) { - -/* Obtain the Mapping pointer and associated invert flag. */ - map = new->map[ inode - 1 ]; - invert = new->invert[ inode - 1 ]; - -/* Determine if the Mapping's Invert attribute is set, and obtain its - value. */ - set = astTestInvert( map ); - inv = astGetInvert( map ); - -/* If necessary, set the required value for the Invert attribute. */ - if ( inv != invert ) astSetInvert( map, invert ); - -/* Simplify the Mapping. */ - tmp = astSimplify( map ); - -/* If necessary, restore the original state of the Mapping's Invert - attribute. */ - if ( inv != invert ) { - if ( set ) { - astSetInvert( map, inv ); - } else { - astClearInvert( map ); - } - } - -/* Test if simplification was performed. */ - if ( astOK ) { - if ( tmp != map ) { - -/* If so, annul the original Mapping pointer and substitute the new - one. Also set a new invert flag to accompany it. */ - (void) astAnnul( new->map[ inode - 1 ] ); - new->map[ inode - 1 ] = astClone( tmp ); - new->invert[ inode - 1 ] = astGetInvert( tmp ); - -/* Note if any Mapping within the FrameSet is simplified. */ - simpler = 1; - } - } - -/* Annul the pointer to the simplified Mapping. */ - tmp = astAnnul( tmp ); - } - -/* If simplification was possible, clone a pointer to the new - FrameSet. Otherwise clone a pointer to the original one. */ - if ( astOK ) result = astClone( simpler ? new : this ); - -/* Annul the new FrameSet pointer. */ - new = astAnnul( new ); - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int Span( AstFrameSet *this, AstFrame **frames, int inode1, int inode2, - int avoid, AstMapping **map, int *forward, int *status ) { -/* -* Name: -* Span - -* Purpose: -* Find a path between two nodes in a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int Span( AstFrameSet *this, AstFrame **frames, int inode1, int inode2, -* int avoid, AstMapping **map, int *forward, int *status ) - -* Class Membership: -* FrameSet member function. - -* Description: -* This function searches a FrameSet to identify a path between two -* specified nodes. It returns an array of pointers to each Mapping -* in the path, along with direction information, so that an -* overall Mapping between the two nodes can be constructed. - -* Parameters: -* this -* Pointer to the FrameSet. -* frames -* Pointer to an array of Frame pointers, indexed by node index. -* Nodes which have no associated Frame will have a NULL pointer -* stored in this array. -* inode1 -* Zero based index of the starting node. -* inode2 -* Zero based index of the ending node. -* avoid -* Zero based index which identifies a node which is to be -* avoided (i.e. the initial step in the path should not be via -* this node). This value is required because the function -* invokes itself recursively; it provides a mechanism to -* prevent searches proceeding back down paths that have already -* been searched. External callers should provide a value of -1, -* which indicates that all possible paths should initially be -* explored. -* map -* Pointer to the start of an array that will be filled with a -* series of pointers to Mappings which must be applied in turn -* in order to transform between the two Frames. External -* callers should ensure that this array contains at least as many -* elements as there are Mappings and Frames in the FrameSet (one less -* than the number of nodes plus the number of Frames). -* -* Note that the pointers are simply copies of addresses from -* the FrameSet's "map" array. They are not cloned, so should -* not be annulled by the caller. -* forward -* Pointer to the start of an array of int that will be filled -* with boolean flags (0 or 1) to indicate whether the forward -* (as opposed to the inverse) transformation should be used for -* each Mapping returned in order to effect the transformation -* between the starting and ending nodes. This array should be the -* same size as the "map" array. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The function returns one more than the number of Mappings -* required to perform the transformation, or zero if it was not -* possible to find a path between the two nodes. - -* Notes: -* - If a node has an associated Frame, the Frame usually represents a -* UnitMap and so can be ignored. The exception is if the Frame is -* actually a Region (or a CmpFrame containing a Region), in which case -* it represents a Mapping which returns bad values if the input position -* is outside the region. This form of Mapping should not be ignored, and -* so the returned list of Mappings includes the effect of any Frames -* along the path which are not equivalent to a UnitMap. This -* equivalence is determined by invoking the astSimplify method on the -* Frame. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -* - On the assumption that the FrameSet has been consistently -* constructed, there should be exactly one path between any pair -* of its nodes. It should not, therefore, ever fail to find a -* path except when invoked recursively to explore a subset of the -* FrameSet's nodes (this should not be visible to an external -* caller). Failure to find a path does not in itself result in an -* error condition. -*/ - -/* Local Variables: */ - AstFrame *frame; /* Pointer to Frame associated with inode1 */ - int fwd; /* Forward Mapping identified? */ - int inode; /* Loop counter for nodes */ - int inv; /* Inverse Mapping identified? */ - int invert; /* Original Mapping Invert value */ - int nextra; /* No. of extra Mappings to add to path */ - int result; /* Count of mappings (to be returned) */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the two nodes are the same. */ - result = ( inode1 == inode2 ); - -/* If so, we need to consider the Mapping represented by any Frame - associated with the node. Most classes of Frames are equivalent to a - UnitMap and so can be ignored. But some (e.g. the Region class) are not - equivalent to a UnitMap and so needs to be included in the returned - Mapping list. */ - if( result ) { - result = 1; - -/* If inode1 is associated with a Frame, which is not equivalent to a - UnitMap, add the Frame as the first Mapping into the returned list. The - "forward" value is irrelevant since the forward and inverse transformations - of Frames are the same. */ - frame = frames[ inode1 ]; - if( frame ) { - if( !astIsUnitFrame( frame ) ) { - result++; - *map = (AstMapping *) frame; - *forward = 1; - } - } - -/* If the nodes are different, we now attempt to find the next step in - the path between them. Loop through all available nodes looking for - the next one to transform to (i.e. one that is directly related by - a Mapping to our starting node). */ - } else { - for ( inode = 0; inode < this->nnode; inode++ ) { - -/* Do not consider node "avoid". This prevents us re-tracing our steps - backwards when this function is invoked recursively. */ - if ( inode != avoid ) { - -/* Test if inode is derived from inode1 (if so, the Mapping associated - with inode will convert from inode1 to inode when applied in the - forward direction). */ - fwd = ( inode > 0 ) && ( this->link[ inode - 1 ] == inode1 ); - -/* Test if inode1 is derived from inode (if so, the Mapping associated - with inode1 will convert from inode1 to inode when applied in the - inverse direction). */ - inv = ( inode1 > 0 ) && ( this->link[ inode1 - 1 ] == inode ); - -/* If the nodes are directly related, we try to find a path from inode to - inode2 without going back through inode1. */ - if ( fwd || inv ) { - -/* If node1 is associated with a Frame, we need to include the Frame - as a Mapping in the returned list unless the Frame is equivalent to a - UnitMap. Note the number of slots to be reserved for node1 when we call - Span recursively below. */ - nextra = 1; - frame = frames[ inode1 ]; - if( frame && !astIsUnitFrame( frame ) ) nextra = 2; - -/* Invoke this function recursively to try and find a path from inode - to inode2 without going back through inode1. If this is possible, a - non-zero result will be returned. Store the returned Mappings and - direction information in the arrays supplied, but leave extra space to - insert information about the Mapping between nodes inode1 and inode. */ - result = Span( this, frames, inode, inode2, inode1, - map + nextra, forward + nextra, status ); - -/* If a path was found, increment the Mapping count to account for the - one that transforms between nodes inode1 and inode and insert - information for this Mapping into the output arrays. */ - if ( result ) { - result++; - nextra--; - map[ nextra ] = this->map[ ( fwd ? inode : inode1 ) - 1 ]; - forward[ nextra ] = fwd; - -/* Obtain the original value of the Invert attribute for the Mapping - between nodes inode1 and inode (recorded when the Mapping was first - added to the FrameSet). Test if this value has now changed. If so, - some external code has inverted the Mapping via another pointer, so - invert the returned direction information to compensate for - this. */ - invert = this->invert[ ( fwd ? inode : inode1 ) - 1 ]; - if ( invert != astGetInvert( map[ nextra ] ) ) { - forward[ nextra ] = !forward[ nextra ]; - } - -/* If inode1 is associated with a non-unit Frame Mapping, add the Frame - Mapping in as the first Mapping in the returned list. The "forward" value - is irrelevant since the forward and inverse transformations of Frames - are the same. */ - if( nextra ) { - result++; - *map = (AstMapping *) frame; - *forward = 1; - } - -/* Quit searching once a path has been found. */ - break; - } - } - } - } - } - -/* Return the result, which is one more than the number of mappings - found (i.e. steps in the path), or zero if no path was found (this - should only occur when invoked recursively to explore an - unsuccessful sub-path). */ - return result; -} - -static int SubFrame( AstFrame *this_frame, AstFrame *template, - int result_naxes, - const int *target_axes, const int *template_axes, - AstMapping **map, AstFrame **result, int *status ) { -/* -* Name: -* SubFrame - -* Purpose: -* Select axes from a FrameSet and convert to the new coordinate system. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int SubFrame( AstFrame *target, AstFrame *template, int result_naxes, -* const int *target_axes, const int *template_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astSubFrame -* method inherited from the Frame class). - -* Description: -* This function selects a requested sub-set (or super-set) of the -* axes from the current Frame of a "target" FrameSet and creates a -* new Frame with copies of the selected axes assembled in the -* requested order. It then optionally overlays the attributes of a -* "template" Frame on to the result. It returns both the resulting -* Frame and a Mapping that describes how to convert between the -* coordinate systems described by the current Frame of the target -* FrameSet and the result Frame. If necessary, this Mapping takes -* account of any differences in the Frames' attributes due to the -* influence of the template. - -* Parameters: -* target -* Pointer to the target FrameSet, from whose current Frame the -* axes are to be selected. -* template -* Pointer to the template Frame, from which new attributes for -* the result Frame are to be obtained. Optionally, this may be -* NULL, in which case no overlaying of template attributes will -* be performed. -* result_naxes -* Number of axes to be selected from the target FrameSet. This -* number may be greater than or less than the number of axes in -* the FrameSet's current Frame (or equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving -* a list of the (zero-based) axis indices of the axes to be -* selected from the current Frame of the target FrameSet. The -* order in which these are given determines the order in which -* the axes appear in the result Frame. If any of the values in -* this array is set to -1, the corresponding result axis will -* not be derived from the target FrameSet, but will be assigned -* default attributes instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This -* should contain a list of the template axes (given as -* zero-based axis indices) with which the axes of the result -* Frame are to be associated. This array determines which axes -* are used when overlaying axis-dependent attributes of the -* template on to the result. If any element of this array is -* set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not -* used and a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned -* Mapping. The forward transformation of this Mapping will -* describe how to convert coordinates from the coordinate -* system described by the current Frame of the target FrameSet -* to that described by the result Frame. The inverse -* transformation will convert in the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is -* possible between the current Frame of the target FrameSet and -* the result Frame. Otherwise zero is returned and *map and -* *result are returned as NULL (but this will not in itself result -* in an error condition). In general, coordinate conversion should -* always be possible if no template Frame is supplied but may not -* always be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to FrameSet's current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - int match; /* Result to be returned */ - -/* Initialise. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame. */ - fr = astGetFrame( this, AST__CURRENT ); - -/* Invoke the astSubFrame method for this Frame. */ - match = astSubFrame( fr, template, result_naxes, target_axes, template_axes, - map, result ); - -/* Annul the Frame pointer. */ - fr = astAnnul( fr ); - -/* If an error occurred, clean up by annulling any returned objects and clear - the returned result. */ - if ( !astOK ) { - *map = astAnnul( *map ); - *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static AstSystemType SystemCode( AstFrame *this_frame, const char *system, int *status ) { -/* -* Name: -* SystemCode - -* Purpose: -* Convert a string into a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astSystemCode -* method inherited from the Frame class). - -* Description: -* This function converts a string used for the external description of -* a coordinate system into a Frame coordinate system type code (System -* attribute value). It is the inverse of the astSystemString function. - -* Parameters: -* this -* Pointer to the Frame. -* system -* Pointer to a constant null-terminated string containing the -* external description of the coordinate system. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System type code. - -* Notes: -* - A value of AST__BADSYSTEM is returned if the coordinate system -* description was not recognised. This does not produce an error. -* - A value of AST__BADSYSTEM is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Result value to return */ - AstFrame *fr; /* Pointer to FrameSet's current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astSystemCode method for this Frame. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astSystemCode( fr, system ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BADSYSTEM; - -/* Return the result. */ - return result; -} - -static const char *SystemString( AstFrame *this_frame, AstSystemType system, int *status ) { -/* -* Name: -* SystemString - -* Purpose: -* Convert a coordinate system type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* const char *SystemString( AstFrame *this, AstSystemType system, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astSystemString -* method inherited from the Frame class). - -* Description: -* This function converts a Frame coordinate system type code -* (System attribute value) into a string suitable for use as an -* external representation of the coordinate system type. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to FrameSet's current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astSystemString method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astSystemString( fr, system ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result pointer. */ - return result; - -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astTestAttrib protected -* method inherited from the Frame class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a FrameSet's attributes. - -* Parameters: -* this -* Pointer to the FrameSet. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* We first handle attributes that apply to the FrameSet as a whole - (rather than to the current Frame). */ - -/* Base. */ -/* ----- */ - if ( !strcmp( attrib, "base" ) ) { - result = astTestBase( this ); - -/* Current. */ -/* -------- */ - } else if ( !strcmp( attrib, "current" ) ) { - result = astTestCurrent( this ); - -/* ID. */ -/* --- */ - } else if ( !strcmp( attrib, "id" ) ) { - result = astTestID( this ); - -/* Ident. */ -/* ------ */ - } else if ( !strcmp( attrib, "ident" ) ) { - result = astTestIdent( this ); - -/* Invert. */ -/* ------- */ - } else if ( !strcmp( attrib, "invert" ) ) { - result = astTestInvert( this ); - -/* Report. */ -/* ------- */ - } else if ( !strcmp( attrib, "report" ) ) { - result = astTestReport( this ); - -/* Variant. */ -/* -------- */ - } else if ( !strcmp( attrib, "variant" ) ) { - result = astTestVariant( this ); - -/* If the name is not recognised, test if it matches any of the - read-only attributes of this class. If it does, then return - zero. */ - } else if ( !strcmp( attrib, "allvariants" ) || - !strcmp( attrib, "class" ) || - !strcmp( attrib, "nframe" ) || - !strcmp( attrib, "nin" ) || - !strcmp( attrib, "nobject" ) || - !strcmp( attrib, "nout" ) || - !strcmp( attrib, "refcount" ) || - !strcmp( attrib, "tranforward" ) || - !strcmp( attrib, "traninverse" ) ) { - result = 0; - -/* Pass unrecognised attributes on to the FrameSet's current Frame for - further interpretation. */ - } else { - -/* Obtain a pointer to the current Frame and invoke its astTestAttrib - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astTestAttrib( fr, attrib ); - fr = astAnnul( fr ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int TestBase( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astTestBase - -* Purpose: -* Determine if a value has been set for the Base attribute of a FrameSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* int astTestBase( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns a boolean result to indicate if a value -* has been set for the Base attribute of a FrameSet. This -* attribute is an index that identifies the base Frame in the -* FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Returned Value: -* Zero or 1, depending on whether a value has been set. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - int invert; /* FrameSet is inverted? */ - int result; /* Value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Determine if the FrameSet has been inverted. */ - invert = astGetInvert( this ); - -/* If it has not been inverted, test the base Frame index, otherwise - test the index of the current Frame instead. */ - if ( astOK ) { - if ( !invert ) { - result = ( this->base != -INT_MAX ); - } else { - result = ( this->current != -INT_MAX ); - } - } - -/* Return the result. */ - return result; -} - -static int TestCurrent( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astTestCurrent - -* Purpose: -* Test if a value has been set for the Current attribute of a FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "frameset.h" -* int astTestCurrent( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns a boolean result to indicate whether a -* value has been set for the Current attribute of a FrameSet. -* This attribute is an index that identifies the current Frame in -* a FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Returned Value: -* Zero or 1, depending on whether a value has been set. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - int invert; /* FrameSet is inverted? */ - int result; /* Value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Determine if the FrameSet has been inverted. */ - invert = astGetInvert( this ); - -/* If it has not been inverted, test the current Frame index, - otherwise test the index of the base Frame instead. */ - if ( astOK ) { - if ( !invert ) { - result = ( this->current != -INT_MAX ); - } else { - result = ( this->base != -INT_MAX ); - } - } - -/* Return the result. */ - return result; -} - -static int TestVariant( AstFrameSet *this, int *status ) { -/* -*+ -* Name: -* astTestVariant - -* Purpose: -* Determine if a value has been set for the Variant attribute of a FrameSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* int astTestVariant( AstFrameSet *this ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns a boolean result to indicate if a value -* has been set for the Variant attribute of a FrameSet. - -* Parameters: -* this -* Pointer to the FrameSet. - -* Returned Value: -* Zero or 1, depending on whether a value has been set. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstFrame *frm; - AstFrameSet *vfs; - int result; - int icur; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the one-based index of the Frame to use. */ - icur = GetVarFrm( this, astGetCurrent( this ), status ); - -/* Get a pointer to the Variants FrameSet in the current Frame. */ - frm = astGetFrame( this, icur ); - vfs = astGetFrameVariants( frm ); - -/* If it is null, return zero, otherwise 1. */ - result = vfs ? 1 : 0; - -/* Annul pointers. */ - if( vfs ) vfs = astAnnul( vfs ); - frm = astAnnul( frm ); - -/* Return the result. */ - return result; -} - -static void TidyNodes( AstFrameSet *this, int *status ) { -/* -* Name: -* TidyNodes - -* Purpose: -* Tidy the nodes in a FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void TidyNodes( AstFrameSet *this, int *status ) - -* Class Membership: -* FrameSet member function. - -* Description: -* This function tidies the nodes in a FrameSet, removing any that -* are unnecessary or represent dead-ends. It should be used after -* any changes have been made to a FrameSet that may have reduced -* the number of references to any of its nodes (either by Frames -* or by other nodes). - -* Parameters: -* this -* Pointer to the FrameSet. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstMapping *newmap; /* Pointer to simplified Mapping */ - AstMapping *tmpmap; /* Pointer to new compound Mapping */ - int ifr; /* Loop counter for Frames */ - int inode; /* Loop counter for nodes */ - int last_link[ 2 ]; /* Last nodes to reference via "link" array */ - int link_ref; /* Number of "link" array references */ - int needed; /* Node still required? */ - int next; /* Node which references the removed one */ - int remove; /* Node to be removed */ - int suspect; /* Loop counter for testing nodes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Loop to search for unnecessary nodes until no more are found. */ - needed = 0; - while ( !needed ) { - -/* Inspect each node (including node zero, which does not actually - have a Mapping associated with it) to see how many times it is - referenced. */ - for ( suspect = 0; suspect < this->nnode; suspect++ ) { - link_ref = 0; - -/* Test for at least one reference from within the "node" array which - associates Frames with particular nodes. */ - for ( ifr = 1; ifr <= this->nframe; ifr++ ) { - if ( ( needed = ( this->node[ ifr - 1 ] == suspect ) ) ) break; - } - -/* If no references were found above, look for references in the - "link" array that inter-connects all the nodes. */ - if ( !needed ) { - for ( inode = 1; inode < this->nnode; inode ++ ) { - if ( this->link[ inode - 1 ] == suspect ) { - -/* Node zero must be retained if it has more than two links - referencing it, while other nodes only require more than one. */ - if ( ( needed = ( link_ref >= ( suspect ? 1 : 2 ) ) ) ) break; - -/* Remember (up to) the first two nodes which reference the current one. */ - last_link[ link_ref++ ] = inode; - } - } - } - -/* If there were insufficient references to retain this node, we must - now decide why it should be removed. */ - if ( !needed ) { - -/* If there is no Frame associated with a node and there are less than - two links to it (for node zero), or less then one link (for other - nodes), then the there is no route to anything else via this node. - It is a dead-end. */ - if ( link_ref < ( suspect ? 1 : 2 ) ) { - -/* To tidy up, we remove the affected node or, for node zero, the - remaining one that references it. Annul the Mapping associated with - the node being removed. */ - remove = suspect ? suspect : last_link[ 0 ]; - this->map[ remove - 1 ] = astAnnul( this->map[ remove - 1 ] ); - -/* If an unnecessary node is not a dead-end, then it is a redundant - node which simply joins two Mappings. */ - } else { - -/* To tidy up, we remove the affected node or, for node zero, the - first one that references it. */ - remove = suspect ? suspect : last_link[ 0 ]; - -/* We then produce a compound Mapping which spans the gap by - concatenating the Mappings associated with the node being removed - and the remaining one which references it. For node zero, the first - of these Mappings must be inverted because there are no out-going - Mappings from node zero. */ - next = suspect ? last_link[ 0 ] : last_link[ 1 ]; - tmpmap = CombineMaps( this->map[ remove - 1 ], - this->invert[ remove - 1 ] != !suspect, - this->map[ next - 1 ], - this->invert[ next - 1 ], 1, status ); - -/* Simplify this compound Mapping. */ - newmap = astSimplify( tmpmap ); - tmpmap = astAnnul( tmpmap ); - -/* Annul the individual Mapping pointers. */ - this->map[ remove - 1 ] = astAnnul( this->map[ remove - 1 ] ); - this->map[ next - 1 ] = astAnnul( this->map[ next - 1 ] ); - -/* Install the new compound Mapping and its Invert flag. */ - this->map[ next - 1 ] = newmap; - this->invert[ next - 1 ] = astGetInvert( newmap ); - -/* Transfer the "link" value from the removed node to the one which - takes its place. */ - this->link[ next - 1 ] = this->link[ remove - 1 ]; - } - -/* Loop to move all subsequent node data down in the "map", "invert" - and "link" arrays to close the gap where a node has been - removed. */ - for ( inode = remove; inode < this->nnode - 1; inode ++ ) { - this->map [ inode - 1 ] = this->map[ inode ]; - this->link [ inode - 1 ] = this->link[ inode ]; - this->invert[ inode - 1 ] = this->invert[ inode ]; - } - this->map[ this->nnode - 2 ] = NULL; - this->link[ this->nnode - 2 ] = -1; - this->invert[ this->nnode - 2 ] = -1; - -/* Decrement the node count. */ - this->nnode--; - -/* Loop to adjust each entry in the "node" array for the change in - node numbering, re-directing references to the removed node towards - the new node zero. */ - for ( ifr = 1; ifr <= this->nframe; ifr++ ) { - if ( this->node[ ifr - 1 ] > remove ) { - this->node[ ifr - 1 ]--; - } else if ( this->node[ ifr - 1 ] == remove ) { - this->node[ ifr - 1 ] = 0; - } - } - -/* Similarly adjust each entry in the "link" array. */ - for ( inode = 1; inode < this->nnode; inode++ ) { - if ( this->link[ inode - 1 ] > remove ) { - this->link[ inode - 1 ]--; - } else if ( this->link[ inode - 1 ] == remove ) { - this->link[ inode - 1 ] = 0; - } - } - -/* Once a node has been removed, other nodes (perhaps already tested) - may no longer be needed, so quit the testing loop and start testing - again with node zero. The process terminates when no more - unnecessary nodes can be found. */ - break; - } - } - } -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the astTransform method -* inherited from the Frame class). - -* Description: -* This function takes a FrameSet and a set of points encapsulated -* in a PointSet, and applies either the forward or inverse -* coordinate transformation (if defined by the FrameSet) to the -* points. The forward transformation converts between the -* FrameSet's base Frame and its current Frame, while the inverse -* transformation converts in the opposite direction. - -* Parameters: -* this -* Pointer to the FrameSet. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - An error will result if the FrameSet supplied does not define -* the requested coordinate transformation (either forward or -* inverse). -* - The number of coordinate values per point in the input -* PointSet must match the number of input coordinates for the -* FrameSet being applied (or number of output coordinates if the -* inverse transformation is requested). This will be equal to the -* number of axes in the FrameSet's base Frame (or the current -* Frame for the inverse transformation). -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and coordinate values per point to -* accommodate the result (e.g. the number of FrameSet output -* coordinates, or number of input coordinates if the inverse -* transformation is requested). Any excess space will be ignored. -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - AstMapping *map; /* Pointer to the base->current Mapping */ - AstPointSet *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_mapping; - -/* Obtain the Mapping between the base and current Frames in the - FrameSet (note this takes account of whether the FrameSet has been - inverted). */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Apply the Mapping to the input PointSet. */ - result = astTransform( map, in, forward, out ); - -/* Annul the Mapping pointer. */ - map = astAnnul( map ); - -/* If an error has occurred and a new PointSet may have been created, then - clean up by annulling it. In any case, ensure that a NULL result is - returned.*/ - if ( !astOK ) { - if ( !out ) result = astAnnul( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -static int Unformat( AstFrame *this_frame, int axis, const char *string, - double *value, int *status ) { -/* -* Name: -* Unformat - -* Purpose: -* Read a formatted coordinate value for a FrameSet axis. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int Unformat( AstFrame *this, int axis, const char *string, -* double *value, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the public astUnformat -* method inherited from the Frame class). - -* Description: -* This function reads a formatted coordinate value for a FrameSet -* axis (supplied as a string) and returns the equivalent numerical -* value as a double. It also returns the number of characters read -* from the string. - -* Parameters: -* this -* Pointer to the FrameSet. -* axis -* The number of the FrameSet axis for which the coordinate -* value is to be read (axis numbering starts at zero for the -* first axis). -* string -* Pointer to a constant null-terminated string containing the -* formatted coordinate value. -* value -* Pointer to a double in which the coordinate value read will be -* returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of characters read from the string to obtain the -* coordinate value. - -* Notes: -* - Any white space at the beginning of the string will be -* skipped, as also will any trailing white space following the -* coordinate value read. The function's return value will reflect -* this. -* - A function value of zero (and no coordinate value) will be -* returned, without error, if the string supplied does not contain -* a suitably formatted value. -* - The string "" is recognised as a special case and will -* generate the value AST__BAD, without error. The test for this -* string is case-insensitive and permits embedded white space. -* - A function result of zero will be returned and no coordinate -* value will be returned via the "value" pointer if this function -* is invoked with the global error status set, or if it should -* fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - double coord; /* Coordinate value read */ - int nc; /* Number of characters read */ - -/* Initialise. */ - nc = 0; - -/* Check the global error status. */ - if ( !astOK ) return nc; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astUnformat" ); - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astUnformat method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - nc = astUnformat( fr, axis, string, &coord ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the number of characters read. */ - if ( !astOK ) { - nc = 0; - -/* Otherwise, if characters were read, return the coordinate value. */ - } else if ( nc ) { - *value = coord; - } - -/* Return the number of characters read. */ - return nc; -} - -static int ValidateAxis( AstFrame *this_frame, int axis, int fwd, - const char *method, int *status ) { -/* -* Name: -* ValidateAxis - -* Purpose: -* Validate and permute a FrameSet's axis index. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int ValidateAxis( AstFrame *this, int axis, int fwd, const char *method, -* int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected -* astValidateAxis method inherited from the Frame class). - -* Description: -* This function checks the validity of an index (zero-based) which -* is to be used to address one of the coordinate axes of the -* current Frame in a FrameSet. If the index is valid, it is -* permuted using the axis permutation array associated with the -* FrameSet's current Frame and the (zero-based) permuted axis -* index is returned. This gives the index the axis had when the -* Frame was first created. If the axis index supplied is not -* valid, an error is reported and the global error status is set. - -* Parameters: -* this -* Pointer to the FrameSet. -* axis -* The axis index (zero-based) to be checked. To be valid, it -* must lie between zero and (naxes-1) inclusive, where "naxes" -* is the number of coordinate axes associated with the -* FrameSet's current Frame. -* fwd -* If non-zero, the suppplied axis index is assumed to be an -* "external" axis index, and the corresponding "internal" axis index -* is returned as the function value. Otherwise, the suppplied axis -* index is assumed to be an "internal" axis index, and the -* corresponding "external" axis index is returned as the function -* value. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The permuted axis index - either "internal" or "external" as -* specified by "fwd". - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - int naxes; /* Number of FrameSet axes */ - int result; /* Permuted axis index */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Determine the number of FrameSet axes. */ - naxes = astGetNaxes( this ); - if ( astOK ) { - -/* If the FrameSet has no axes, report an error (convert to 1-based - axis numbering for the benefit of the public interface). */ - if ( naxes == 0 ) { - astError( AST__AXIIN, "%s(%s): Invalid attempt to use an axis index " - "(%d) for a %s which has no axes.", status, method, - astGetClass( this ), axis + 1, astGetClass( this ) ); - -/* Otherwise, check the axis index for validity and report an error if - it is not valid (again, convert to 1-based axis numbering). */ - } else if ( ( axis < 0 ) || ( axis >= naxes ) ) { - astError( AST__AXIIN, "%s(%s): Axis index (%d) invalid - it should " - "be in the range 1 to %d.", status, method, astGetClass( this ), - axis + 1, naxes ); - -/* If the axis index was valid, obtain a pointer to the FrameSet's - current Frame and invoke this Frame's astValidateAxis method to - obtain the permuted axis index. Annul the Frame pointer - afterwards. */ - } else { - fr = astGetFrame( this, AST__CURRENT ); - result = astValidateAxis( fr, axis, fwd, "astValidateAxis" ); - fr = astAnnul( fr ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static void ValidateAxisSelection( AstFrame *this_frame, int naxes, - const int *axes, const char *method, int *status ) { -/* -* Name: -* ValidateAxisSelection - -* Purpose: -* Check that a set of axes selected from a Frame is valid. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void ValidateAxisSelection( AstFrame *this, int naxes, -* const int *axes, const char *method, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astValidateAxisSelection -* method inherited from the Frame class). - -* Description: -* This function checks the validity of an array of (zero-based) -* axis indices that specify a set of axes to be selected from a -* Frame. To be valid, no axis should be selected more than -* once. In assessing this, any axis indices that do not refer to -* valid Frame axes (e.g. are set to -1) are ignored. -* -* If the axis selection is valid, this function returns without further -* action. Otherwise, an error is reported and the global error status is -* set. - -* Parameters: -* this -* Pointer to the Frame. -* naxes -* The number of axes to be selected (may be zero). -* axes -* Pointer to an array of int with naxes elements that contains the -* (zero based) axis indices to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis selection. This method name is used -* solely for constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke this - Frame's astValidateAxisSelection method. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - astValidateAxisSelection( fr, naxes, axes, method ); - fr = astAnnul( fr ); - -} - -static int ValidateFrameIndex( AstFrameSet *this, int iframe, - const char *method, int *status ) { -/* -*+ -* Name: -* astValidateFrameIndex - -* Purpose: -* Validate a FrameSet Frame index number. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* int astValidateFrameIndex( AstFrameSet *this, int iframe, -* const char *method ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function checks a (one-based) FrameSet Frame index for -* validity. If it is not valid, an error is reported. Otherwise, -* the function returns the Frame index value, having translated -* the special values AST__CURRENT and AST__BASE into valid Frame -* indices if necessary. - -* Parameters: -* this -* Pointer to the FrameSet. -* iframe -* The Frame index. To be valid this should lie in the range 1 -* to the number of Frames in the FrameSet. In addition, the -* values AST__CURRENT and AST__BASE may be given to indicate -* the "current" and "base" Frames. These values will be -* translated into the acceptable range. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate a Frame index. This method name is used solely -* for constructing error messages. - -* Returned Value: -* The validated (one-based) Frame index. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason -* (e.g. if the Frame index is invalid). -*- -*/ - -/* Local Variables: */ - int nframe; /* Number of Frames */ - int result; /* Returned index value */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check if the base or current Frame was specified and retrieve the - required Frame index from the FrameSet. */ - if ( iframe == AST__BASE ) { - result = astGetBase( this ); - } else if ( iframe == AST__CURRENT ) { - result = astGetCurrent( this ); - -/* Otherwise, determine how many Frames there are in the FrameSet. */ - } else { - nframe = astGetNframe( this ); - if ( astOK ) { - -/* Check that the supplied index is within range and report an error - if it is not. */ - if ( ( iframe < 1 ) || ( iframe > nframe ) ) { - astError( AST__FRMIN, "%s(%s): Invalid Frame index (%d) given.", status, - method, astGetClass( this ), iframe ); - astError( AST__FRMIN, "This value should be in the range 1 to " - "%d (or AST__CURRENT or AST__BASE).", status, nframe ); - -/* If OK, return the validated index value. */ - } else { - result = iframe; - } - } - } - -/* Return the result. */ - return result; -} - -static int ValidateSystem( AstFrame *this_frame, AstSystemType system, const char *method, int *status ) { -/* -* Name: -* ValidateSystem - -* Purpose: -* Validate a value for a Frame's System attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* int ValidateSystem( AstFrame *this, AstSystemType system, -* const char *method, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astValidateSystem -* method inherited from the Frame class). - -* Description: -* This function checks the validity of the supplied system value. -* If the value is valid, it is returned unchanged. Otherwise, an -* error is reported and a value of AST__BADSYSTEM is returned. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The system value to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The validated system value. - -* Notes: -* - A value of AST_BADSYSTEM will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstSystemType result; /* Validated system value */ - AstFrame *fr; /* Pointer to FrameSet's current Frame */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_frame; - -/* Obtain a pointer to the FrameSet's current Frame and invoke the - astValidateSystem method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this, AST__CURRENT ); - result = astValidateSystem( this, system, method ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BADSYSTEM; - -/* Return the result. */ - return result; -} - -static void VSet( AstObject *this_object, const char *settings, - char **text, va_list args, int *status ) { -/* -* Name: -* VSet - -* Purpose: -* Set values for a FrameSet's attributes. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void VSet( AstObject *this, const char *settings, char **text, -* va_list args, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astVSet -* method inherited from the Object class). - -* Description: -* This function assigns a set of attribute values for a FrameSet, -* the attributes and their values being specified by means of a -* string containing a comma-separated list of the form: -* -* "attribute1 = value1, attribute2 = value2, ... " -* -* Here, "attribute" specifies an attribute name and the value to -* the right of each "=" sign should be a suitable textual -* representation of the value to be assigned to that -* attribute. This will be interpreted according to the attribute's -* data type. -* -* The string supplied may also contain "printf"-style format -* specifiers identified by a "%" sign in the usual way. If -* present, these will be substituted by values supplied as -* optional arguments (as a va_list variable argument list), using -* the normal "printf" rules, before the string is used. - -* Parameters: -* this -* Pointer to the FrameSet. -* settings -* Pointer to a null-terminated string containing a -* comma-separated list of attribute settings. -* text -* Pointer to a location at which to return a pointer to dynamic -* memory holding a copy of the expanded setting string. This memory -* should be freed using astFree when no longer needed. If a NULL -* pointer is supplied, no string is created. -* args -* The variable argument list which contains values to be -* substituted for any "printf"-style format specifiers that -* appear in the "settings" string. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function preserves the integrity of the FrameSet (if -* possible) by appropriately remapping its current Frame to take -* account of its changed attribute values. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFrame *save_frame; /* Saved pointer to integrity Frame */ - AstFrameSet *this; /* Pointer to FrameSet structure */ - char *fulltext; /* Pointer to expanded text string */ - const char *save_method; /* Saved pointer to method name */ - int len; /* Length of settings string */ - int ok; /* Status OK? */ - int save_lost; /* Saved integrity modified flag */ - -/* Initialise */ - if( text ) *text = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain the length of the "settings" string and test it is not - zero. If it is, there is nothing more to do. */ - len = (int) strlen( settings ); - if ( len != 0 ) { - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* This function may be invoked recursively (because astConvert, - below, constructs a FrameSet and may require that its attributes be - set). To allow this, we first save any existing FrameSet integrity - information in local variables. */ - save_frame = integrity_frame; - save_lost = integrity_lost; - save_method = integrity_method; - -/* Set the name of the method being used (for use in error - messages). */ - integrity_method = "astSet"; - -/* Record the initial integrity state of the FrameSet. */ - RecordIntegrity( this, status ); - -/* Invoke the parent astVSet method to set the FrameSet's attribute - values and note if this succeeds. */ - (*parent_vset)( this_object, settings, &fulltext, args, status ); - ok = astOK; - -/* Restore the FrameSet's integrity. */ - RestoreIntegrity( this, status ); - -/* If integrity could not be restored, then add contextual error - information. */ - if ( !astOK && ok ) { - -/* Display the message. */ - astError( astStatus, "Unable to accommodate the attribute setting " - "\"%s\".", status, fulltext ); - } - -/* Restore any saved FrameSet integrity information. */ - integrity_frame = save_frame; - integrity_lost = save_lost; - integrity_method = save_method; - -/* If the full text of the setting string is not needed, free it. - Otherwise return it. */ - if( text ) { - *text = fulltext; - } else { - fulltext = astFree( fulltext ); - } - } -} - -/* FrameSet Attributes. */ -/* -------------------- */ -/* -*att++ -* Name: -* AllVariants - -* Purpose: -* A list of the variant Mappings associated with the current Frame. - -* Type: -* Public attribute. - -* Synopsis: -* String, read-only. - -* Description: -* This attribute gives a space separated list of the names of all the -* variant Mappings associated with the current Frame (see attribute -* "Variant"). If the current Frame has no variant Mappings, then the -* list will hold a single entry equal to the Domain name of the -* current Frame. - -* Applicability: -* FrameSet -* All FrameSets have this attribute. -*att-- -*/ - -/* -*att++ -* Name: -* Base - -* Purpose: -* FrameSet base Frame index. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute gives the index of the Frame which is to be -* regarded as the "base" Frame within a FrameSet. The default is -* the first Frame added to the FrameSet when it is created (this -* Frame always has an index of 1). -* -* When setting a new value for this attribute, a string may be -* supplied instead of an integer index. In this case a search -* is made within the FrameSet for a Frame that has its Domain -* attribute value equal to the supplied string (the comparison is -* case-insensitive). If found, the Frame is made the base Frame. -* Otherwise an error is reported. - -* Applicability: -* FrameSet -* All FrameSets have this attribute. - -* Notes: -* - Inverting a FrameSet (inverting the boolean sense of its -c Invert attribute, with the astInvert function for example) will -f Invert attribute, with the AST_INVERT routine for example) will -* interchange the values of its Base and Current attributes. -*att-- -*/ - -/* -*att++ -* Name: -* Current - -* Purpose: -* FrameSet current Frame index. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute gives the index of the Frame which is to be -* regarded as the "current" Frame within a FrameSet. The default -* is the most recent Frame added to the FrameSet (this Frame -* always has an index equal to the FrameSet's Nframe attribute). -* -* When setting a new value for this attribute, a string may be -* supplied instead of an integer index. In this case a search -* is made within the FrameSet for a Frame that has its Domain -* attribute value equal to the supplied string (the comparison is -* case-insensitive). If found, the Frame is made the current Frame. -* Otherwise an error is reported. - -* Applicability: -* FrameSet -* All FrameSets have this attribute. - -* Notes: -* - Inverting a FrameSet (inverting the boolean sense of its -c Invert attribute, with the astInvert function for example) will -f Invert attribute, with the AST_INVERT routine for example) will -* interchange the values of its Base and Current attributes. -*att-- -*/ - -/* -*att++ -* Name: -* Nframe - -* Purpose: -* Number of Frames in a FrameSet. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the number of Frames in a FrameSet. This -* value will change as Frames are added or removed, but will -* always be at least one. - -* Applicability: -* FrameSet -* All FrameSets have this attribute. -*att-- -*/ - -/* -*att++ -* Name: -* Variant - -* Purpose: -* Indicates which variant of the current Frame is to be used. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute can be used to change the Mapping that connects the -* current Frame to the other Frames in the FrameSet. By default, each -* Frame in a FrameSet is connected to the other Frames by a single -* Mapping that can only be changed by using the -c astRemapFrame -f AST_REMAPFRAME -* method. However, it is also possible to associate multiple Mappings -* with a Frame, each Mapping having an identifying name. If this is -* done, the "Variant" attribute can be set to indicate the name of -* the Mapping that is to be used with the current Frame. -* -* A possible (if unlikely) use-case is to create a FrameSet that can -* be used to describe the WCS of an image formed by co-adding images -* of two different parts of the sky. In such an image, each pixel contains -* flux from two points on the sky.and so the WCS for the image should -* ideally contain one pixel Frame and two SkyFrames - one describing -* each of the two co-added images. There is nothing to prevent a -* FrameSet containing two explicit SkyFrames, but the problem then arises -* of how to distinguish between them. The two primary characteristics of -* a Frame that distinguishes it from other Frames are its class and its -* Domain attribute value. The class of a Frame cannot be changed, but we -* could in principle use two different Domain values to distinguish the -* two SkyFrames. However, in practice it is not uncommon for application -* software to assume that SkyFrames will have the default Domain value -* of "SKY". That is, instead of searching for Frames that have a class -* of "SkyFrame", such software searches for Frames that have a Domain -* of "SKY". To alleviate this problem, it is possible to add a single -* SkyFrame to the FrameSet, but specifying two alternate Mappings to -* use with the SkyFrame. Setting the "Variant" attribute to the name -* of one or the other of these alternate Mappings will cause the -* SkyFrame to be remapped within the FrameSet so that it uses the -* specified Mapping. The same facility can be used with any class of -* Frame, not just SkyFrames. -* -* To use this facility, the Frame should first be added to the -* FrameSet in the usual manner using the -c astAddFrame method. By default, the Mapping supplied to astAddFrame -f AST_ADDFRAME method. By default, the Mapping supplied to AST_ADDVARIANT -* is assigned a name equal to the Domain name of the Frame. To assign a -* different name to it, the -c astAddVariant -f AST_ADDVARIANT -* method should then be called specifying the required name and a NULL -* Mapping. The -c astAddVariant -f AST_ADDVARIANT -* method should then be called repeatedly to add each required extra -* Mapping to the current Frame, supplying a unique name for each one. -* -* Each Frame in a FrameSet can have its own set of variant Mappings. -* To control the Mappings in use with a specific Frame, you need first -* to make it the current Frame in the FrameSet. -* -* The -c astMirrorVariants function -f AST_MIRRORVARIANTS routine -* allows the effects of variant Mappings associated with a nominated -* Frame to be propagated to other Frames in the FrameSet. -* -* Once this has been done, setting a new value for the "Variant" -* attribute of a FrameSet will cause the current Frame in the -* FrameSet to be remapped to use the specified variant Mapping. An -* error will be reported if the current Frame has no variant Mapping -* with the supplied name. -* -* Getting the value of the "Variant" attribute will return the name -* of the variant Mapping currently in use with the current Frame. If -* the Frame has no variant Mappings, the value will default to the -* Domain name of the current Frame. -* -* Clearing the "Variant" attribute will have the effect of removing -* all variant Mappings (except for the currently selected Mapping) from -* the current Frame. -* -* Testing the "Variant" attribute will return -c a non-zero value -f .TRUE. -* if the current Frame contains any variant Mappings, and -c zero -f .FALSE. -* otherwise. -* -* A complete list of the names associated with all the available -* variant Mappings in the current Frame can be obtained from the -* AllVariants attribute. -* -* If a Frame with variant Mappings is remapped using the -c astRemapFrame -f AST_REMAPFRAME -* method, the currently selected variant Mapping is used by -c astRemapFrame -f AST_REMAPFRAME -* and the other variant Mappings are removed from the Frame. - -* Applicability: -* FrameSet -* All FrameSets have this attribute. -*att-- -*/ - -/* Access to attributes of the current Frame. */ -/* ------------------------------------------ */ -/* Use the macros defined at the start of this file to implement - private member functions that give access to the attributes of the - current Frame of a FrameSet and its axes. These functions over-ride - the attribute access methods inherited from the Frame class. */ - -/* Clear, Get, Set and Test axis-independent Frame attributes. */ -MAKE_CLEAR(Digits) -MAKE_CLEAR(Domain) -MAKE_CLEAR(MatchEnd) -MAKE_CLEAR(MaxAxes) -MAKE_CLEAR(MinAxes) -MAKE_CLEAR(Permute) -MAKE_CLEAR(PreserveAxes) -MAKE_CLEAR(Title) - -MAKE_GET(Digits,int) -MAKE_GET(Domain,const char *) -MAKE_GET(MatchEnd,int) -MAKE_GET(MaxAxes,int) -MAKE_GET(MinAxes,int) -MAKE_GET(Permute,int) -MAKE_GET(PreserveAxes,int) -MAKE_GET(Title,const char *) -MAKE_SET(Digits,int) -MAKE_SET(Domain,const char *) -MAKE_SET(MatchEnd,int) -MAKE_SET(MaxAxes,int) -MAKE_SET(MinAxes,int) -MAKE_SET(Permute,int) -MAKE_SET(PreserveAxes,int) -MAKE_SET(Title,const char *) -MAKE_TEST(Digits) -MAKE_TEST(Domain) -MAKE_TEST(MatchEnd) -MAKE_TEST(MaxAxes) -MAKE_TEST(MinAxes) -MAKE_TEST(Permute) -MAKE_TEST(PreserveAxes) -MAKE_TEST(Title) - -MAKE_GET(ActiveUnit,int) -MAKE_SET(ActiveUnit,int) -MAKE_TEST(ActiveUnit) - -MAKE_GET(System,AstSystemType) -MAKE_SET(System,AstSystemType) -MAKE_TEST(System) -MAKE_CLEAR(System) - -MAKE_GET(AlignSystem,AstSystemType) -MAKE_SET(AlignSystem,AstSystemType) -MAKE_TEST(AlignSystem) -MAKE_CLEAR(AlignSystem) - -MAKE_GET(Epoch,double) -MAKE_SET(Epoch,double) -MAKE_TEST(Epoch) -MAKE_CLEAR(Epoch) - -MAKE_GET(Dtai,double) -MAKE_SET(Dtai,double) -MAKE_TEST(Dtai) -MAKE_CLEAR(Dtai) - -MAKE_GET(Dut1,double) -MAKE_SET(Dut1,double) -MAKE_TEST(Dut1) -MAKE_CLEAR(Dut1) - -MAKE_GET(ObsLon,double) -MAKE_SET(ObsLon,double) -MAKE_TEST(ObsLon) -MAKE_CLEAR(ObsLon) - -MAKE_GET(ObsLat,double) -MAKE_SET(ObsLat,double) -MAKE_TEST(ObsLat) -MAKE_CLEAR(ObsLat) - -MAKE_GET(ObsAlt,double) -MAKE_SET(ObsAlt,double) -MAKE_TEST(ObsAlt) -MAKE_CLEAR(ObsAlt) - -/* Clear, Get, Set and Test axis-dependent Frame attributes. */ -MAKE_CLEAR_AXIS(Direction) -MAKE_CLEAR_AXIS(Format) -MAKE_CLEAR_AXIS(Label) -MAKE_CLEAR_AXIS(Symbol) -MAKE_CLEAR_AXIS(Unit) -MAKE_GET_AXIS(Direction,int) -MAKE_GET_AXIS(Format,const char *) -MAKE_GET_AXIS(Label,const char *) -MAKE_GET_AXIS(Symbol,const char *) -MAKE_GET_AXIS(Unit,const char *) -MAKE_SET_AXIS(Direction,int) -MAKE_SET_AXIS(Format,const char *) -MAKE_SET_AXIS(Label,const char *) -MAKE_SET_AXIS(Symbol,const char *) -MAKE_SET_AXIS(Unit,const char *) -MAKE_TEST_AXIS(Direction) -MAKE_TEST_AXIS(Format) -MAKE_TEST_AXIS(Label) -MAKE_TEST_AXIS(Symbol) -MAKE_TEST_AXIS(Unit) - -MAKE_GET_AXIS(Bottom,double) -MAKE_SET_AXIS(Bottom,double) -MAKE_TEST_AXIS(Bottom) -MAKE_CLEAR_AXIS(Bottom) - -MAKE_GET_AXIS(Top,double) -MAKE_SET_AXIS(Top,double) -MAKE_TEST_AXIS(Top) -MAKE_CLEAR_AXIS(Top) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for FrameSet objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for FrameSet objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstFrameSet *in; /* Pointer to input FrameSet */ - AstFrameSet *out; /* Pointer to output FrameSet */ - int iframe; /* Loop counter for Frames */ - int inode; /* Loop counter for nodes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output FrameSets. */ - in = (AstFrameSet *) objin; - out = (AstFrameSet *) objout; - -/* For safety, first clear any references to the input memory from - the output FrameSet. */ - out->frame = NULL; - out->varfrm = NULL; - out->node = NULL; - out->map = NULL; - out->link = NULL; - out->invert = NULL; - -/* Allocate memory in the output FrameSet to store the Frame and node - information and copy scalar information across. */ - out->frame = astMalloc( sizeof( AstFrame * ) * (size_t) in->nframe ); - out->varfrm = astStore( NULL, in->varfrm, sizeof( int ) * - (size_t) in->nframe ); - out->node = astStore( NULL, in->node, sizeof( int ) * - (size_t) in->nframe ); - out->map = astMalloc( sizeof( AstMapping * ) * (size_t) ( in->nnode - 1 ) ); - out->link = astStore( NULL, in->link, sizeof( int ) * - (size_t) ( in->nnode - 1 ) ); - out->invert = astStore( NULL, in->invert, sizeof( int ) * - (size_t) ( in->nnode - 1 ) ); - -/* If OK, make copies of each input Frame and Mapping and store the - resulting pointers in the output FrameSet. */ - if ( astOK ) { - for ( iframe = 0; iframe < in->nframe; iframe++ ) { - out->frame[ iframe ] = astCopy( in->frame[ iframe ] ); - } - for ( inode = 0; inode < in->nnode - 1; inode++ ) { - out->map[ inode ] = astCopy( in->map[ inode ] ); - } - -/* If an error occurred while copying any of these objects, clean up - by looping through the arrays of pointers again and annulling them - all. */ - if ( !astOK ) { - for ( iframe = 0; iframe < in->nframe; iframe++ ) { - out->frame[ iframe ] = astAnnul( out->frame[ iframe ] ); - } - for ( inode = 0; inode < in->nnode - 1; inode++ ) { - out->map[ inode ] = astAnnul( out->map[ inode ] ); - } - } - } - -/* If an error occurred, clean up by freeing all memory allocated above. */ - if ( !astOK ) { - out->frame = astFree( out->frame ); - out->varfrm = astFree( out->varfrm ); - out->node = astFree( out->node ); - out->map = astFree( out->map ); - out->link = astFree( out->link ); - out->invert = astFree( out->invert ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for FrameSet objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for FrameSet objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstFrameSet *this; /* Pointer to FrameSet */ - int iframe; /* Loop counter for Frames */ - int inode; /* Loop counter for nodes */ - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) obj; - -/* Annul all Frame pointers and clear the node numbers associated with - them. */ - for ( iframe = 0; iframe < this->nframe; iframe++ ) { - this->frame[ iframe ] = astAnnul( this->frame[ iframe ] ); - this->node[ iframe ] = 0; - } - -/* Annul all Mapping pointers and clear the links between pairs of - nodes and the associated Mapping Invert information. */ - for ( inode = 0; inode < this->nnode - 1; inode++ ) { - this->map[ inode ] = astAnnul( this->map[ inode ] ); - this->link[ inode ] = 0; - this->invert[ inode ] = 0; - } - -/* Free all allocated memory. */ - this->frame = astFree( this->frame ); - this->varfrm = astFree( this->varfrm ); - this->node = astFree( this->node ); - this->map = astFree( this->map ); - this->link = astFree( this->link ); - this->invert = astFree( this->invert ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for FrameSet objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the FrameSet class to an output Channel. - -* Parameters: -* this -* Pointer to the FrameSet whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define COMMENT_LEN 150 /* Maximum length of a comment string */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstFrameSet *this; /* Pointer to the FrameSet structure */ - char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment string */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int ifr; /* Loop counter for Frames */ - int inode; /* Loop counter for nodes */ - int invert; /* Invert attribute value */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstFrameSet *) this_object; - -/* Determine if the FrameSet is inverted. This is required so that the - effects of inversion can be un-done to obtain information about the - "true" Base and Current Frames. (The values written are "internal" - values that are not affected by the Invert setting.) */ - invert = astGetInvert( this ); - -/* Write out values representing the instance variables for the - FrameSet class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Nframe. */ -/* ------- */ - set = ( this->nframe != 0 ); - ival = set ? this->nframe : astGetNframe( this ); - astWriteInt( channel, "Nframe", set, 1, ival, - "Number of Frames in FrameSet" ); - -/* Base. */ -/* ----- */ - set = ( this->base != -INT_MAX ); - ival = set ? this->base : ( !invert ? astGetBase( this ) : - astGetCurrent( this ) ); - astWriteInt( channel, "Base", set, 1, ival, "Index of base Frame" ); - -/* Current. */ -/* -------- */ - set = ( this->current != -INT_MAX ); - ival = set ? this->current : ( !invert ? astGetCurrent( this ) : - astGetBase( this ) ); - astWriteInt( channel, "Currnt", set, 1, ival, "Index of current Frame" ); - -/* Number of nodes. */ -/* ---------------- */ - ival = this->nnode; - set = ( ival != this->nframe ); - astWriteInt( channel, "Nnode", set, 0, ival, - "Number of nodes in FrameSet" ); - -/* Node index for each Frame. */ -/* -------------------------- */ -/* There is a node value for each Frame in the FrameSet. */ - for ( ifr = 1; ifr <= this->nframe; ifr++ ) { - -/* Convert node numbering to start at 1 for the external - representation. Regard a node number as "set" if it differs from - the Frame number. */ - ival = this->node[ ifr - 1 ] + 1; - set = ( ival != ifr ); - -/* Create a suitable keyword and comment. */ - (void) sprintf( key, "Nod%d", ifr ); - (void) sprintf( comment, - "Frame %d is associated with node %d", ifr, ival ); - -/* Write out the value. */ - astWriteInt( channel, key, set, 0, ival, comment ); - } - -/* Index of variants Frame for each Frame. */ -/* --------------------------------------- */ - for ( ifr = 1; ifr <= this->nframe; ifr++ ) { - -/* Retain the one-based Frame index values in varfrm. Regard a number as - "set" if it is greater than zero. */ - ival = this->varfrm[ ifr - 1 ]; - set = ( ival > 0 ); - -/* Create a suitable keyword and comment. */ - (void) sprintf( key, "VFr%d", ifr ); - (void) sprintf( comment, - "Frame %d inherits variants from Frame %d", ifr, ival ); - -/* Write out the value. */ - astWriteInt( channel, key, set, 0, ival, comment ); - } - -/* Links between nodes. */ -/* -------------------- */ -/* Each node in the FrameSet (except the first) has a link to another - node from which it is derived. */ - for ( inode = 1; inode < this->nnode; inode++ ) { - -/* Convert node numbering to start at 1 (as above). */ - ival = this->link[ inode - 1 ] + 1; - (void) sprintf( key, "Lnk%d", inode + 1 ); - (void) sprintf( comment, - "Node %d is derived from node %d", inode + 1, ival ); - astWriteInt( channel, key, 1, 0, ival, comment ); - -/* Inversion flags. */ -/* ---------------- */ -/* Each node with a link has a value which the Invert attribute of the - associated Mapping should have when the transformation from the - parent node to the node in question is required. */ - ival = this->invert[ inode - 1 ]; - -/* Regard the value as set only if the Mapping's inverse - transformation is required. */ - set = ( ival != 0 ); - (void) sprintf( key, "Inv%d", inode + 1 ); - astWriteInt( channel, key, set, 0, ival, - ival ? "The inverse mapping is used" : - "The forward mapping is used" ); - } - -/* Frame objects. */ -/* -------------- */ -/* Output an Object description for each Frame in the FrameSet. */ - for ( ifr = 1; ifr <= this->nframe; ifr++ ) { - (void) sprintf( key, "Frm%d", ifr ); - (void) sprintf( comment, "Frame number %d", ifr ); - astWriteObject( channel, key, 1, 1, this->frame[ ifr - 1 ], - comment ); - } - -/* Mapping objects. */ -/* ---------------- */ -/* Output an Object description for each Mapping in the FrameSet. */ - for ( inode = 1; inode < this->nnode; inode++ ) { - (void) sprintf( key, "Map%d", inode + 1 ); - (void) sprintf( comment, "Mapping between nodes %d and %d", - this->link[ inode - 1 ] + 1, inode + 1 ); - astWriteObject( channel, key, 1, 1, this->map[ inode - 1 ], comment ); - } - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAFrameSet and astCheckFrameSet functions using - the macros defined for this purpose in the "object.h" header - file. */ -astMAKE_ISA(FrameSet,Frame) -astMAKE_CHECK(FrameSet) - -AstFrameSet *astFrameSet_( void *frame_void, const char *options, int *status, ...) { -/* -*+ -* Name: -* astFrameSet - -* Purpose: -* Create a FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "frameset.h" -* AstFrameSet *astFrameSet( AstFrame *frame, const char *options, int *status, ... ) - -* Class Membership: -* FrameSet constructor. - -* Description: -* This function creates a new FrameSet and optionally initialises -* its attributes. - -* Parameters: -* frame -* Pointer to the initial Frame. If this is not a FrameSet, the -* new FrameSet will be initialised to contain this Frame alone. -* -* If it is a FrameSet, the new FrameSet will be initialised to -* contain the same Frames (and Mappings) and to have the same -* attribute values as the one supplied. This is similar to -* making a copy, except that the Frames (and Mappings) -* contained in the original FrameSet are not themselves copied, -* but are shared by both FrameSets. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new FrameSet. The syntax used is the same as -* for the astSet method and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of arguments may follow it in order to -* supply values to be substituted for these specifiers. The -* rules for supplying these are identical to those for the -* astSet method (and for the C "printf" function). - -* Returned Value: -* A pointer to the new FrameSet. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic FrameSet constructor which -* is available via the protected interface to the FrameSet class. -* A public interface is provided by the astFrameSetId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "frame" parameter is of type (void *) and is converted and -* validated within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstFrameSet *new; /* Pointer to new FrameSet */ - va_list args; /* Variable argument list */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain and validate a pointer to the Frame structure provided. */ - frame = astCheckFrame( frame_void ); - if ( astOK ) { - -/* Initialise the FrameSet, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitFrameSet( NULL, sizeof( AstFrameSet ), !class_init, - &class_vtab, "FrameSet", frame ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - FrameSet's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new FrameSet. */ - return new; -} - -AstFrameSet *astInitFrameSet_( void *mem, size_t size, int init, - AstFrameSetVtab *vtab, const char *name, - AstFrame *frame, int *status ) { -/* -*+ -* Name: -* astInitFrameSet - -* Purpose: -* Initialise a FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "frameset.h" -* AstFrameSet *astInitFrameSet( void *mem, size_t size, int init, -* AstFrameSetVtab *vtab, const char *name, -* AstFrame *frame ) - -* Class Membership: -* FrameSet initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new FrameSet object. It allocates memory (if -* necessary) to accommodate the FrameSet plus any additional data -* associated with the derived class. It then initialises a -* FrameSet structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual -* function table for a FrameSet at the start of the memory passed -* via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the FrameSet is to be -* created. This must be of sufficient size to accommodate the -* FrameSet data (sizeof(FrameSet)) plus any data used by the -* derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the FrameSet (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the FrameSet structure, so a valid value must be -* supplied even if not required for allocating memory. -* init -* A logical flag indicating if the FrameSet's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new FrameSet. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* frame -* Pointer to the initial Frame (or FrameSet). - -* Returned Value: -* A pointer to the new FrameSet. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstFrameSet *new; /* Pointer to new FrameSet */ - AstFrameSet *old; /* Pointer to original FrameSet */ - int iframe; /* Loop counter for Frames */ - int inode; /* Loop counter for nodes */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitFrameSetVtab( vtab, name ); - -/* Initialise a Frame structure (the parent class) as the first - component within the FrameSet structure, allocating memory if - necessary. Give this Frame zero axes, as all axis information for - the FrameSet will be derived from the Frames it contains. */ - new = (AstFrameSet *) astInitFrame( mem, size, 0, - (AstFrameVtab *) vtab, name, 0 ); - - if ( astOK ) { - -/* Initialise the FrameSet data. */ -/* ----------------------------- */ - -/* Normal Frame supplied. */ -/* ---------------------- */ -/* Check that the Frame supplied is not a FrameSet (initialising using - a FrameSet is a special case which is handled below). If not, we - initialise the new FrameSet to refer to a single Frame. */ - if ( !astIsAFrameSet( frame ) && astOK ) { - -/* Allocate memory for the arrays of Frame information. */ - new->frame = astMalloc( sizeof( AstFrame * ) ); - new->node = astMalloc( sizeof( int ) ); - new->varfrm = astMalloc( sizeof( int ) ); - -/* The node arrays are not required until at least two Frames are - present. */ - new->map = NULL; - new->link = NULL; - new->invert = NULL; - -/* If OK, initialise these arrays, thus adding the Frame to the - FrameSet. */ - if ( astOK ) { - new->frame[ 0 ] = astClone( frame ); - new->node[ 0 ] = 0; - new->varfrm[ 0 ] = 0; - new->nframe = 1; - new->nnode = 1; - -/* Initialise the FrameSet attributes to their undefined states. */ - new->base = -INT_MAX; - new->current = -INT_MAX; - } - -/* FrameSet supplied. */ -/* ------------------ */ -/* If a FrameSet was supplied, we will initialise the new FrameSet to - refer to the same Frame and Mapping information (this is similar to - making a copy, except that we clone all the pointers, instead of - copying the Objects they refer to). */ - } else if ( astOK ) { - -/* Obtain a pointer to the original FrameSet structure. */ - old = (AstFrameSet *) frame; - -/* Allocate memory in the new FrameSet to store the Frame and node - information and copy any scalar information across. */ - new->frame = astMalloc( sizeof( AstFrame * ) * (size_t) old->nframe ); - new->node = astStore( NULL, old->node, - sizeof( int ) * (size_t) old->nframe ); - new->varfrm = astStore( NULL, old->varfrm, - sizeof( int ) * (size_t) old->nframe ); - new->map = astMalloc( sizeof( AstMapping * ) * - (size_t) ( old->nnode - 1 ) ); - new->link = astStore( NULL, old->link, - sizeof( int ) * (size_t) ( old->nnode - 1 ) ); - new->invert = astStore( NULL, old->invert, - sizeof( int ) * (size_t) ( old->nnode - 1 ) ); - -/* If OK, clone the pointer to each Frame and Mapping referenced by - the original FrameSet and store the resulting pointers in the new - FrameSet. */ - if ( astOK ) { - for ( iframe = 0; iframe < old->nframe; iframe++ ) { - new->frame[ iframe ] = astClone( old->frame[ iframe ] ); - } - for ( inode = 0; inode < old->nnode - 1; inode++ ) { - new->map[ inode ] = astClone( old->map[ inode ] ); - } - -/* If an error occurred while cloning any of these pointers, clean up - by looping through the arrays of cloned pointers again and - annulling them all. */ - if ( !astOK ) { - for ( iframe = 0; iframe < old->nframe; iframe++ ) { - new->frame[ iframe ] = astAnnul( new->frame[ iframe ] ); - } - for ( inode = 0; inode < old->nnode - 1; inode++ ) { - new->map[ inode ] = astAnnul( new->map[ inode ] ); - } - } - } - -/* If an error occurred, clean up by freeing all memory allocated - above. */ - if ( !astOK ) { - new->frame = astFree( new->frame ); - new->node = astFree( new->node ); - new->varfrm = astFree( new->varfrm ); - new->map = astFree( new->map ); - new->link = astFree( new->link ); - new->invert = astFree( new->invert ); - } - -/* Copy the Frame and node counts across. */ - new->nframe = old->nframe; - new->nnode = old->nnode; - -/* Copy the other FrameSet attributes across. */ - new->base = old->base; - new->current = old->current; - -/* Transfer any other inherited attribute values that relate to the - FrameSet itself (rather than the enclosed Frames). */ - if ( astTestInvert( old ) ) astSetInvert( new, astGetInvert( old ) ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; - -/* Undefine macros local to this function. */ -#undef TRANSFER -} - -AstFrameSet *astLoadFrameSet_( void *mem, size_t size, - AstFrameSetVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadFrameSet - -* Purpose: -* Load a FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "frameset.h" -* AstFrameSet *astLoadFrameSet( void *mem, size_t size, -* AstFrameSetVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* FrameSet loader. - -* Description: -* This function is provided to load a new FrameSet using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* FrameSet structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the FrameSet is to be -* loaded. This must be of sufficient size to accommodate the -* FrameSet data (sizeof(FrameSet)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the FrameSet (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the FrameSet structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstFrameSet) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new FrameSet. If this is NULL, a pointer -* to the (static) virtual function table for the FrameSet class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "FrameSet" is used instead. - -* Returned Value: -* A pointer to the new FrameSet. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstFrameSet *new; /* Pointer to the new FrameSet */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int ifr; /* Get a pointer to the thread specific global data structure. */ - -/* Loop counter for Frames */ - int inode; /* Loop counter for nodes */ - - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this FrameSet. In this case the - FrameSet belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstFrameSet ); - vtab = &class_vtab; - name = "FrameSet"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitFrameSetVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built FrameSet. */ - new = astLoadFrame( mem, size, (AstFrameVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "FrameSet" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Nframe. */ -/* ------- */ - new->nframe = astReadInt( channel, "nframe", 1 ); - if ( new->nframe < 0 ) new->nframe = 1; - -/* Number of nodes. */ -/* ---------------- */ - new->nnode = astReadInt( channel, "nnode", new->nframe ); - if ( new->nnode < 1 ) new->nnode = 1; - -/* Allocate memory to hold Frame and node information. */ - new->frame = astMalloc( sizeof( AstFrame *) * (size_t) new->nframe ); - new->node = astMalloc( sizeof( int ) * (size_t) new->nframe ); - new->varfrm = astMalloc( sizeof( int ) * (size_t) new->nframe ); - new->link = astMalloc( sizeof( int ) * (size_t) ( new->nnode - 1 ) ); - new->invert = astMalloc( sizeof( int ) * (size_t) ( new->nnode - 1 ) ); - new->map = astMalloc( sizeof( AstMapping * ) * - (size_t) ( new->nnode - 1 ) ); - -/* If an error occurs, ensure that all allocated memory is freed. */ - if ( !astOK ) { - new->frame = astFree( new->frame ); - new->node = astFree( new->node ); - new->varfrm = astFree( new->varfrm ); - new->link = astFree( new->link ); - new->invert = astFree( new->invert ); - new->map = astFree( new->map ); - -/* Otherwise, initialise the arrays which will hold Object pointers. */ - } else { - for ( ifr = 1; ifr <= new->nframe; ifr++ ) { - new->frame[ ifr - 1 ] = NULL; - } - for ( inode = 1; inode < new->nnode; inode++ ) { - new->map[ inode - 1 ] = NULL; - } - -/* Read Frame data... */ - for ( ifr = 1; ifr <= new->nframe; ifr++ ) { - -/* Frame objects. */ -/* -------------- */ -/* Create the required keyword and then read the Frame. */ - (void) sprintf( key, "frm%d", ifr ); - new->frame[ ifr - 1 ] = astReadObject( channel, key, NULL ); - -/* Node index for each Frame. */ -/* -------------------------- */ - (void) sprintf( key, "nod%d", ifr ); - new->node[ ifr - 1 ] = astReadInt( channel, key, ifr ) - 1; - -/* Index of variants Frame. */ -/* ------------------------ */ - (void) sprintf( key, "vfr%d", ifr ); - new->varfrm[ ifr - 1 ] = astReadInt( channel, key, 0 ); - } - -/* Read node data... */ - for ( inode = 1; inode < new->nnode; inode++ ) { - -/* Links between nodes. */ -/* -------------------- */ - (void) sprintf( key, "lnk%d", inode + 1 ); - new->link[ inode - 1 ] = astReadInt( channel, key, 0 ) - 1; - -/* Inversion flags. */ -/* ---------------- */ - (void) sprintf( key, "inv%d", inode + 1 ); - new->invert[ inode - 1 ] = astReadInt( channel, key, 0 ); - -/* Mapping objects. */ -/* ---------------- */ - (void) sprintf( key, "map%d", inode + 1 ); - new->map[ inode - 1 ] = astReadObject( channel, key, NULL ); - } - -/* Read remaining data... */ - -/* Base. */ -/* ----- */ - new->base = astReadInt( channel, "base", -INT_MAX ); - if ( new->base < 1 ) new->base = -INT_MAX; - -/* Current. */ -/* -------- */ - new->current = astReadInt( channel, "currnt", -INT_MAX ); - if ( new->base < 1 ) new->base = -INT_MAX; - } - -/* If an error occurred, clean up by deleting the new FrameSet. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new FrameSet pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -void astAddFrame_( AstFrameSet *this, int iframe, AstMapping *map, - AstFrame *frame, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,AddFrame))( this, iframe, map, frame, status ); -} -void astClearBase_( AstFrameSet *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,ClearBase))( this, status ); -} -void astClearCurrent_( AstFrameSet *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,ClearCurrent))( this, status ); -} -void astClearVariant_( AstFrameSet *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,ClearVariant))( this, status ); -} -int astGetBase_( AstFrameSet *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,FrameSet,GetBase))( this, status ); -} -int astGetCurrent_( AstFrameSet *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,FrameSet,GetCurrent))( this, status ); -} -const char *astGetVariant_( AstFrameSet *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,FrameSet,GetVariant))( this, status ); -} -AstFrame *astGetFrame_( AstFrameSet *this, int iframe, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,FrameSet,GetFrame))( this, iframe, status ); -} -AstMapping *astGetMapping_( AstFrameSet *this, int iframe1, int iframe2, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,FrameSet,GetMapping))( this, iframe1, iframe2, status ); -} -int astGetNframe_( AstFrameSet *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,FrameSet,GetNframe))( this, status ); -} -void astRemapFrame_( AstFrameSet *this, int iframe, AstMapping *map, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,RemapFrame))( this, iframe, map, status ); -} -void astAddVariant_( AstFrameSet *this, AstMapping *map, const char *name, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,AddVariant))( this, map, name, status ); -} -void astMirrorVariants_( AstFrameSet *this, int iframe, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,MirrorVariants))( this, iframe, status ); -} -void astRemoveFrame_( AstFrameSet *this, int iframe, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,RemoveFrame))( this, iframe, status ); -} -void astSetBase_( AstFrameSet *this, int ibase, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,SetBase))( this, ibase, status ); -} -void astSetCurrent_( AstFrameSet *this, int icurrent, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,SetCurrent))( this, icurrent, status ); -} -void astSetVariant_( AstFrameSet *this, const char *variant, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,FrameSet,SetVariant))( this, variant, status ); -} -int astTestBase_( AstFrameSet *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,FrameSet,TestBase))( this, status ); -} -int astTestCurrent_( AstFrameSet *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,FrameSet,TestCurrent))( this, status ); -} -int astTestVariant_( AstFrameSet *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,FrameSet,TestVariant))( this, status ); -} -int astValidateFrameIndex_( AstFrameSet *this, int iframe, - const char *method, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,FrameSet,ValidateFrameIndex))( this, iframe, - method, status ); -} -const char *astGetAllVariants_( AstFrameSet *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,FrameSet,GetAllVariants))( this, status ); -} -int astGetNode_( AstFrameSet *this, int inode, int *nnodes, - int *iframe, AstMapping **map, int *parent, - int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,FrameSet,GetNode))( this, inode, nnodes, - iframe, map, parent, status ); -} - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstFrameSet *astFrameSetId_( void *, const char *, ... ); -int astGetNodeId_( AstFrameSet *, int, int *, int *, AstMapping **, int *, int *); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstFrameSet *astFrameSetId_( void *frame_void, const char *options, ... ) { -/* -*++ -* Name: -c astFrameSet -f AST_FRAMESET - -* Purpose: -* Create a FrameSet. - -* Type: -* Public function. - -* Synopsis: -c #include "frameset.h" -c AstFrameSet *astFrameSet( AstFrame *frame, const char *options, ... ) -f RESULT = AST_FRAMESET( FRAME, OPTIONS, STATUS ) - -* Class Membership: -* FrameSet constructor. - -* Description: -* This function creates a new FrameSet and optionally initialises -* its attributes. -* -* A FrameSet consists of a set of one or more Frames (which -* describe coordinate systems), connected together by Mappings -* (which describe how the coordinate systems are inter-related). A -* FrameSet makes it possible to obtain a Mapping between any pair -* of these Frames (i.e. to convert between any of the coordinate -* systems which it describes). The individual Frames are -* identified within the FrameSet by an integer index, with Frames -* being numbered consecutively from one as they are added to the -* FrameSet. -* -* Every FrameSet has a "base" Frame and a "current" Frame (which -* are allowed to be the same). Any of the Frames may be nominated -* to hold these positions, and the choice is determined by the -* values of the FrameSet's Base and Current attributes, which hold -* the indices of the relevant Frames. By default, the first Frame -* added to a FrameSet is its base Frame, and the last one added is -* its current Frame. -* -* The base Frame describes the "native" coordinate system of -* whatever the FrameSet is used to calibrate (e.g. the pixel -* coordinates of an image) and the current Frame describes the -* "apparent" coordinate system in which it should be viewed -* (e.g. displayed, etc.). Any further Frames represent a library -* of alternative coordinate systems, which may be selected by -* making them current. -* -* When a FrameSet is used in a context that requires a Frame, -* (e.g. obtaining its Title value, or number of axes), the current -* Frame is used. A FrameSet may therefore be used in place of its -* current Frame in most situations. -* -* When a FrameSet is used in a context that requires a Mapping, -* the Mapping used is the one between its base Frame and its -* current Frame. Thus, a FrameSet may be used to convert "native" -* coordinates into "apparent" ones, and vice versa. Like any -c Mapping, a FrameSet may also be inverted (see astInvert), which -f Mapping, a FrameSet may also be inverted (see AST_INVERT), which -* has the effect of interchanging its base and current Frames and -* hence of reversing the Mapping between them. -* -* Regions may be added into a FrameSet (since a Region is a type of -* Frame), either explicitly or as components within CmpFrames. In this -* case the Mapping between a pair of Frames within a FrameSet will -* include the effects of the clipping produced by any Regions included -* in the path between the Frames. - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* Pointer to the first Frame to be inserted into the -* FrameSet. This initially becomes both the base and the -* current Frame. (Further Frames may be added using the -c astAddFrame function.) -f AST_ADDFRAME routine.) -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new FrameSet. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new FrameSet. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astFrameSet() -f AST_FRAMESET -* A pointer to the new FrameSet. - -* Notes: -c - If a pointer to an existing FrameSet is given for the "frame" -c parameter, then the new FrameSet will (as a special case) be -f - If a pointer to an existing FrameSet is given for the FRAME -f argument, then the new FrameSet will (as a special case) be -* initialised to contain the same Frames and Mappings, and to have -* the same attribute values, as the one supplied. This process is -c similar to making a copy of a FrameSet (see astCopy), except -f similar to making a copy of a FrameSet (see AST_COPY), except -* that the Frames and Mappings contained in the original are not -* themselves copied, but are shared by both FrameSets. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astFrameSet constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astFrameSet_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "frame" parameter is of type -* (void *) and is converted from an ID value to a pointer and -* validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astFrameSet_ directly, so it must be a -* re-implementation of it in all respects, except for the -* conversions between IDs and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstFrameSet *new; /* Pointer to new FrameSet */ - va_list args; /* Variable argument list */ - - int *status; - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain the Frame pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Frame. */ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - if ( astOK ) { - -/* Initialise the FrameSet, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitFrameSet( NULL, sizeof( AstFrameSet ), !class_init, - &class_vtab, "FrameSet", frame ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - FrameSet's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new FrameSet. */ - return astMakeId( new ); -} - -int astGetNodeId_( AstFrameSet *this, int inode, int *nnodes, - int *iframe, AstMapping **map, int *parent, - int *status ) { -/* -*+ -* Name: -* astGetNode - -* Purpose: -* Get information about a single node in a FrameSet tree. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frameset.h" -* int astGetNode( AstFrameSet *this, int inode, int *nnodes, -* int *iframe, AstMapping **map, int *parent ) - -* Class Membership: -* FrameSet method. - -* Description: -* This function returns information about a specified node in a -* FrameSet. It is documented as protected, because it should not -* be used in general purpose software since it depends on the internal -* details of the FrameSet class. However, it is in fact public so that -* it can be used in external software that needs to know about the -* internal structure of a FrameSet (for instance, a graphical FrameSet -* visualisation system). - -* Parameters: -* this -* Pointer to the FrameSet. -* inode -* The zero-based index of the required node. -* nnodes -* Address of an int returned holding the number of nodes defined -* in the FrameSet. -* frame -* Address of a Frame pointer returned holding a pointer to a deep -* copy of the Frame, if any, associated with the node. NULL -* is returned if the node has no Frame. -* map -* Address of a Mapping pointer returned holding a pointer to a -* deep copy of the Mapping, if any, from the parent node to the -* requested node. NULL is returned if the node has no parent. -* parent -* Address of an int returned holding the zero-based index of the -* node from which the requested node is derived. -1 is returned if -* the requested node has no parent (i.e. is the root of the tree). - -* Returned Value: -* A non-zero value is returned if the "inode" value is within bounds. -* Otherwise, zero is returned. - -*- -*/ - -/* Local Variables: */ - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the normal astGetNode_ function. */ - result = astGetNode_( this, inode, nnodes, iframe, map, parent, status ); - -/* Return an ID value for the Mapping. */ - *map = astMakeId( *map ); - -/* Return the result. */ - return result; -} - - diff --git a/ast/frameset.h b/ast/frameset.h deleted file mode 100644 index 6629cfb..0000000 --- a/ast/frameset.h +++ /dev/null @@ -1,714 +0,0 @@ -/* -*+ -* Name: -* frameset.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the FrameSet class. - -* Invocation: -* #include "frameset.h" - -* Description: -* This include file defines the interface to the FrameSet class and -* provides the type definitions, function prototypes and macros, etc. -* needed to use this class. -* -* A FrameSet consists of a set of one or more Frames, which are -* inter-related by Mappings in such a way that it is possible to -* obtain a Mapping between any pair of the Frames. The Frames are -* identified by an integer index, with Frames being numbered -* consecutively from one as they are added to the FrameSet. -* -* At any time, there is a "base" Frame and a "current" Frame -* (which are allowed to be the same). Any of the Frames may be -* nominated to hold these positions, and the choice is determined -* by the values of the FrameSet's Base and Current attributes -* which hold the indices of the relevant Frames. By default, the -* first Frame added to a FrameSet is its base Frame, and the last -* one added is its current Frame. -* -* The base Frame describes the "native" coordinate system of -* whatever the FrameSet is used to calibrate (e.g. the pixel -* coordinates of an image) and the current Frame describes the -* "apparent" coordinate system in which it should be viewed -* (e.g. displayed, etc.). The other Frames represent alternative -* coordinate systems which may be selected by making them current. -* -* When Frame methods are invoked on a FrameSet (e.g. to obtain a -* Title value or to determine the number of axes), they are -* applied to the current Frame. Thus, a FrameSet may be used in -* place of its current Frame in most situations. -* -* When Mapping methods are invoked on a FrameSet, the Mapping used -* is the one between its base Frame and its current Frame. Thus, a -* FrameSet may be used to convert "native" coordinates into -* "apparent" ones, and vice versa. A FrameSet may also be -* inverted, which has the effect of interchanging its base and -* current Frames (and hence of reversing the Mapping between -* them). -* -* The FrameSet class also defines methods of its own, which are -* used to manage the Frames and Mappings that it contains and to -* convert between coordinate systems described by different -* FrameSets. - -* Inheritance: -* The FrameSet class inherits from the Frame class. - -* Attributes Over-Ridden: -* Digits (integer) -* Direction(axis) (integer) -* Domain (string) -* Format(axis) (string) -* Label(axis) (string) -* MatchEnd (integer) -* MaxAxes (integer) -* MinAxes (integer) -* Naxes (integer) -* Permute (integer) -* PreserveAxes (integer) -* Symbol(axis) (string) -* Title (string) -* Unit(axis) (string) -* The FrameSet acquires all of these attributes from its -* current Frame, so their meanings, values and defaults are -* determined by this Frame and may change if a different -* current Frame is selected. -* Nin (integer) -* Nout (integer) -* TranForward (integer) -* TranInverse (integer) -* The FrameSet interprets all of these as applying to the -* Mapping that converts coordinates between its base Frame and -* its current Frame, so their values may change if a different -* base or current Frame is selected. -* Invert (integer) -* Report (integer) -* The FrameSet interprets these as applying to the Mapping that -* converts coordinates between its base Frame and its current -* Frame, but their values are not affected by selecing a -* different base or current Frame. - -* New Attributes Defined: -* Base (integer) -* The (one-based) index of the Frame which is to be regarded as -* the base Frame in the FrameSet. By default, this is the first -* Frame added to the FrameSet (i.e. when it was created), -* unless the Frameset has been inverted, in which case it is -* the last Frame added. Inverting a FrameSet interchanges the -* values of its Base and Current attributes. -* Current (integer) -* The (one-based) index of the Frame which is to be regarded as -* the current Frame in the FrameSet. By default, this is the -* last Frame added to the FrameSet, unless the Frameset has -* been inverted, in which case it is the first Frame added -* (i.e. when the FrameSet was created). Inverting a FrameSet -* interchanges the values of its Base and Current attributes. -* Nframe (integer) -* A read-only value giving the number of Frames in a -* FrameSet. This value will change as Frames are added or -* removed. - -* Methods Over-Ridden: -* Public: -* astClear -* Clear attribute values for a FrameSet. -* astConvert -* Determine how to convert between two coordinate systems. -* astDistance -* Calculate the distance between two points. -* astFindFrame -* Find a coordinate system with specified characteristics -* astFormat -* Format a coordinate value for a FrameSet axis. -* astGetAxis -* Obtain a pointer to a specified Axis from a FrameSet. -* astGetNaxes -* Determine how many axes a FrameSet has. -* astGetNin -* Get the number of input coordinates for a FrameSet. -* astGetNout -* Get the number of output coordinates for a FrameSet. -* astNorm -* Normalise a set of FrameSet coordinates. -* astOffset -* Calculate an offset along a geodesic curve. -* astPermAxes -* Permute the order of a FrameSet's axes. -* astPickAxes -* Create a new Frame by picking axes from a FrameSet. -* astSetAxis -* Set a new Axis for a FrameSet. -* astSimplify -* Simplify the Mappings in a FrameSet. -* astTransform -* Transform a set of points. -* astUnformat -* Read a formatted coordinate value for a FrameSet axis. -* -* Protected: -* astAbbrev -* Abbreviate a formatted FrameSet axis value by skipping leading -* fields. -* astClearDigits -* Clear the value of the Digits attribute for a FrameSet. -* astClearDirection -* Clear the value of the Direction attribute for a FrameSet axis. -* astClearDomain -* Clear the value of the Domain attribute for a FrameSet. -* astClearFormat -* Clear the value of the Format attribute for a FrameSet axis. -* astClearLabel -* Clear the value of the Label attribute for a FrameSet axis. -* astClearMatchEnd -* Clear the value of the MatchEnd attribute for a FrameSet. -* astClearMaxAxes -* Clear the value of the MaxAxes attribute for a FrameSet. -* astClearMinAxes -* Clear the value of the MinAxes attribute for a FrameSet. -* astClearPermute -* Clear the value of the Permute attribute for a FrameSet. -* astClearPreserveAxes -* Clear the value of the PreserveAxes attribute for a FrameSet. -* astClearSymbol -* Clear the value of the Symbol attribute for a FrameSet axis. -* astClearTitle -* Clear the value of the Title attribute for a FrameSet. -* astClearUnit -* Clear the value of the Unit attribute for a FrameSet axis. -* astConvertX -* Determine how to convert between two coordinate systems. -* astGap -* Find a "nice" gap for tabulating FrameSet axis values. -* astGetDigits -* Get the value of the Digits attribute for a FrameSet. -* astGetDirection -* Get the value of the Direction attribute for a FrameSet axis. -* astGetDomain -* Get the value of the Domain attribute for a FrameSet. -* astGetFormat -* Get the value of the Format attribute for a FrameSet axis. -* astGetLabel -* Get the value of the Label attribute for a FrameSet axis. -* astGetMatchEnd -* Get the value of the MatchEnd attribute for a FrameSet. -* astGetMaxAxes -* Get the value of the MaxAxes attribute for a FrameSet. -* astGetMinAxes -* Get the value of the MinAxes attribute for a FrameSet. -* astGetPerm -* Access the axis permutation array for the current Frame of -* a FrameSet. -* astGetPermute -* Get the value of the Permute attribute for a FrameSet. -* astGetPreserveAxes -* Get the value of the PreserveAxes attribute for a FrameSet. -* astGetSymbol -* Get the value of the Symbol attribute for a FrameSet axis. -* astGetTitle -* Get the value of the Title attribute for a FrameSet. -* astGetTranForward -* Determine if a Mapping can perform a "forward" coordinate -* transformation. -* astGetTranInverse -* Determine if a Mapping can perform an "inverse" coordinate -* transformation. -* astGetUnit -* Get the value of the Unit attribute for a FrameSet axis. -* astMatch -* Determine if conversion is possible between two coordinate systems. -* astOverlay -* Overlay the attributes of a template FrameSet on to another Frame. -* astPrimaryFrame -* Uniquely identify a primary Frame and one of its axes. -* astReportPoints -* Report the effect of transforming a set of points using a FrameSet. -* astSetAttrib -* Set an attribute value for a FrameSet. -* astSetDigits -* Set the value of the Digits attribute for a FrameSet. -* astSetDirection -* Set the value of the Direction attribute for a FrameSet axis. -* astSetDomain -* Set the value of the Domain attribute for a FrameSet. -* astSetFormat -* Set the value of the Format attribute for a FrameSet axis. -* astSetLabel -* Set the value of the Label attribute for a FrameSet axis. -* astSetMatchEnd -* Set the value of the MatchEnd attribute for a FrameSet. -* astSetMaxAxes -* Set the value of the MaxAxes attribute for a FrameSet. -* astSetMinAxes -* Set the value of the MinAxes attribute for a FrameSet. -* astSetPermute -* Set the value of the Permute attribute for a FrameSet. -* astSetPreserveAxes -* Set the value of the PreserveAxes attribute for a FrameSet. -* astSetSymbol -* Set the value of the Symbol attribute for a FrameSet axis. -* astSetTitle -* Set the value of the Title attribute for a FrameSet. -* astSetUnit -* Set the value of the Unit attribute for a FrameSet axis. -* astSubFrame -* Select axes from a FrameSet and convert to the new coordinate -* system. -* astTestDigits -* Test if a value has been set for the Digits attribute of a -* FrameSet. -* astTestDirection -* Test if a value has been set for the Direction attribute of a -* FrameSet axis. -* astTestDomain -* Test if a value has been set for the Domain attribute of a -* FrameSet. -* astTestFormat -* Test if a value has been set for the Format attribute of a -* FrameSet axis. -* astTestLabel -* Test if a value has been set for the Label attribute of a -* FrameSet axis. -* astTestMatchEnd -* Test if a value has been set for the MatchEnd attribute of a -* FrameSet. -* astTestMaxAxes -* Test if a value has been set for the MaxAxes attribute of a -* FrameSet. -* astTestMinAxes -* Test if a value has been set for the MinAxes attribute of a -* FrameSet. -* astTestPermute -* Test if a value has been set for the Permute attribute of a -* FrameSet. -* astTestPreserveAxes -* Test if a value has been set for the PreserveAxes attribute of a -* FrameSet. -* astTestSymbol -* Test if a value has been set for the Symbol attribute of a -* FrameSet axis. -* astTestTitle -* Test if a value has been set for the Title attribute of a FrameSet. -* astTestUnit -* Test if a value has been set for the Unit attribute of a FrameSet -* axis. -* astValidateAxis -* Validate and permute a FrameSet's axis index. -* astVSet -* Set values for a FrameSet's attributes. - -* New Methods Defined: -* Public: -* astAddFrame -* Add a Frame to a FrameSet to define a new coordinate system. -* astGetFrame -* Obtain a pointer to a specified Frame in a FrameSet. -* astGetMapping -* Obtain a Mapping between two Frames in a FrameSet. -* astRemapFrame -* Modify a Frame's relationshp to the other Frames in a FrameSet. -* astRemoveFrame -* Remove a Frame from a FrameSet. -* -* Protected: -* astClearBase -* Clear the value of the Base attribute for a FrameSet. -* astClearCurrent -* Clear the value of the Current attribute for a FrameSet. -* astGetBase -* Obtain the value of the Base attribute for a FrameSet. -* astGetCurrent -* Obtain the value of the Current attribute for a FrameSet. -* astGetNframe -* Determine the number of Frames in a FrameSet. -* astSetBase -* Set the value of the Base attribute for a FrameSet. -* astSetCurrent -* Set the value of the Current attribute for a FrameSet. -* astTestBase -* Test if a value has been set for the Base attribute of a FrameSet. -* astTestCurrent -* Test if a value has been set for the Current attribute of a -* FrameSet. -* astValidateFrameIndex -* Validate a FrameSet Frame index number. - -* Other Class Functions: -* Public: -* astFrameSet -* Create a FrameSet. -* astIsAFrameSet -* Test class membership. -* -* Protected: -* astCheckFrameSet -* Validate class membership. -* astInitFrameSet -* Initialise a FrameSet. -* astInitFrameSetVtab -* Initialise the virtual function table for the FrameSet class. -* astLoadFrameSet -* Load a FrameSet. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstFrameSet -* FrameSet object type. - -* Protected: -* AstFrameSetVtab -* FrameSet virtual function table type. - -* Macros: -* Public: -* AST__BASE -* Expands to a constant int that may be used as a Frame index to -* refer to a FrameSet's base Frame. -* AST__CURRENT -* Expands to a constant int that may be used as a Frame index to -* refer to a FrameSet's current Frame. -* AST__NOFRAME -* Expands to a constant int that is guaranteed not to be valid when -* used as a Frame index for a FrameSet. -* -* Protected: -* None. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 16-FEB-1996 (RFWS): -* Original version. -* 5-JUN-1996 (RFWS): -* Tidied up, etc. -* 12-AUG-1996 (RFWS): -* Added support for the public interface. -* 25-SEP-1996 (RFWS): -* Added I/O facilities. -* 20-JAN-1998 (RFWS): -* Implemented preservation of FrameSet integrity when attribute -* values associated with the current Frame are modified. -* 25-FEB-1998 (RFWS): -* Over-ride the astUnformat method. -* 8-JAN-2003 (DSB): -* Added protected astInitFrameSetVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "frame.h" /* Parent Frame class */ - -/* Note that the usual setting of the FRAMESET_INCLUDED flag, which - prevents this file being included more than once, must be deferred - until after including the "frame.h" file. This is because "frame.h" - needs to include the present interface definition (as a form of - "forward reference") in order to have access to FrameSets - itself. */ -#if !defined( FRAMESET_INCLUDED ) -#define FRAMESET_INCLUDED - -/* Macros. */ -/* ======= */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif -#define AST__BASE (0) /* Identify base Frame */ -#define AST__CURRENT (-1) /* Identify current Frame */ -#define AST__NOFRAME (-99) /* An invalid Frame index */ -#define AST__ALLFRAMES (-199) /* A value representing all Frames */ -#define AST__FRAMESET_GETALLVARIANTS_BUFF_LEN 200 /* Length for AllVariants buffer */ -#define AST__FRAMESET_GETATTRIB_BUFF_LEN 200 /* Length for GetAtribb buffer */ - -/* Type Definitions. */ -/* ================= */ -/* FrameSet structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstFrameSet { - -/* Attributes inherited from the parent class. */ - AstFrame parent; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstFrame **frame; /* Array of Frame pointers */ - AstMapping **map; /* Array of Mapping pointers */ - int *varfrm; /* Array of variants Frames indices */ - int *invert; /* Array of Mapping Invert values */ - int *link; /* Parent node index for each node */ - int *node; /* Index of node associated with Frame */ - int base; /* Index of base Frame */ - int current; /* Index of current Frame */ - int nframe; /* Number of Frames */ - int nnode; /* Number of nodes */ -} AstFrameSet; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all objects in the - class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstFrameSetVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstFrameVtab frame_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstFrame *(* GetFrame)( AstFrameSet *, int, int * ); - AstMapping *(* GetMapping)( AstFrameSet *, int, int, int * ); - int (* GetBase)( AstFrameSet *, int * ); - int (* GetCurrent)( AstFrameSet *, int * ); - int (* GetNframe)( AstFrameSet *, int * ); - int (* TestBase)( AstFrameSet *, int * ); - int (* TestCurrent)( AstFrameSet *, int * ); - int (* ValidateFrameIndex)( AstFrameSet *, int, const char *, int * ); - void (* AddFrame)( AstFrameSet *, int, AstMapping *, AstFrame *, int * ); - void (* AddVariant)( AstFrameSet *, AstMapping *, const char *, int * ); - void (* MirrorVariants)( AstFrameSet *, int, int * ); - void (* ClearBase)( AstFrameSet *, int * ); - void (* ClearCurrent)( AstFrameSet *, int * ); - void (* RemapFrame)( AstFrameSet *, int, AstMapping *, int * ); - void (* RemoveFrame)( AstFrameSet *, int, int * ); - void (* SetBase)( AstFrameSet *, int, int * ); - void (* SetCurrent)( AstFrameSet *, int, int * ); - void (* ClearVariant)( AstFrameSet *, int * ); - const char *(* GetVariant)( AstFrameSet *, int * ); - void (* SetVariant)( AstFrameSet *, const char *, int * ); - int (* TestVariant)( AstFrameSet *, int * ); - const char *(* GetAllVariants)( AstFrameSet *, int * ); - int (* GetNode)( AstFrameSet *, int, int *, int *, AstMapping **, int *, int * ); -} AstFrameSetVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstFrameSetGlobals { - AstFrameSetVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ AST__FRAMESET_GETATTRIB_BUFF_LEN + 1 ]; - char GetAllVariants_Buff[ AST__FRAMESET_GETALLVARIANTS_BUFF_LEN + 1 ]; - AstFrame *Integrity_Frame; - const char *Integrity_Method; - int Integrity_Lost; -} AstFrameSetGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(FrameSet) /* Check class membership */ -astPROTO_ISA(FrameSet) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -AstFrameSet *astFrameSet_( void *, const char *, int *, ...); -#else -AstFrameSet *astFrameSetId_( void *, const char *, ... )__attribute__((format(printf,2,3))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstFrameSet *astInitFrameSet_( void *, size_t, int, AstFrameSetVtab *, - const char *, AstFrame *, int * ); - -/* Vtab initialiser. */ -void astInitFrameSetVtab_( AstFrameSetVtab *, const char *, int * ); - -/* Loader. */ -AstFrameSet *astLoadFrameSet_( void *, size_t, AstFrameSetVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitFrameSetGlobals_( AstFrameSetGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -AstFrame *astGetFrame_( AstFrameSet *, int, int * ); -AstMapping *astGetMapping_( AstFrameSet *, int, int, int * ); -void astAddFrame_( AstFrameSet *, int , AstMapping *, AstFrame *, int * ); -void astAddVariant_( AstFrameSet *, AstMapping *, const char *, int * ); -void astMirrorVariants_( AstFrameSet *, int, int * ); -void astRemapFrame_( AstFrameSet *, int, AstMapping *, int * ); -void astRemoveFrame_( AstFrameSet *, int, int * ); -int astGetNodeId_( AstFrameSet *, int, int *, int *, AstMapping **, int *, int * ); - -#if defined(astCLASS) /* Protected */ -const char *astGetAllVariants_( AstFrameSet *, int * ); -int astGetBase_( AstFrameSet *, int * ); -int astGetCurrent_( AstFrameSet *, int * ); -int astGetNframe_( AstFrameSet *, int * ); -int astTestBase_( AstFrameSet *, int * ); -int astTestCurrent_( AstFrameSet *, int * ); -int astValidateFrameIndex_( AstFrameSet *, int, const char *, int * ); -void astClearBase_( AstFrameSet *, int * ); -void astClearCurrent_( AstFrameSet *, int * ); -void astSetBase_( AstFrameSet *, int, int * ); -void astSetCurrent_( AstFrameSet *, int, int * ); -void astClearVariant_( AstFrameSet *, int * ); -const char *astGetVariant_( AstFrameSet *, int * ); -void astSetVariant_( AstFrameSet *, const char *, int * ); -int astTestVariant_( AstFrameSet *, int * ); -int astGetNode_( AstFrameSet *, int, int *, int *, AstMapping **, int *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class to make - them easier to invoke (e.g. to avoid type mis-matches when passing pointers - to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them to - validate their own arguments. We must use a cast when passing object - pointers (so that they can accept objects from derived classes). */ - -/* Check class membership. */ -#define astCheckFrameSet(this) astINVOKE_CHECK(FrameSet,this,0) -#define astVerifyFrameSet(this) astINVOKE_CHECK(FrameSet,this,1) - -/* Test class membership. */ -#define astIsAFrameSet(this) astINVOKE_ISA(FrameSet,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -#define astFrameSet astINVOKE(F,astFrameSet_) -#else -#define astFrameSet astINVOKE(F,astFrameSetId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitFrameSet(mem,size,init,vtab,name,frame) \ -astINVOKE(O,astInitFrameSet_(mem,size,init,vtab,name,astCheckFrame(frame),STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitFrameSetVtab(vtab,name) astINVOKE(V,astInitFrameSetVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadFrameSet(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadFrameSet_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckFrameSet to validate FrameSet pointers before - use. This provides a contextual error report if a pointer to the wrong sort - of object is supplied. */ -#define astAddFrame(this,iframe,map,frame) \ -astINVOKE(V,astAddFrame_(astCheckFrameSet(this),iframe,(((iframe)!=AST__ALLFRAMES)?astCheckMapping(map):NULL),astCheckFrame(frame),STATUS_PTR)) -#define astAddVariant(this,map,name) \ -astINVOKE(V,astAddVariant_(astCheckFrameSet(this),map?astCheckMapping(map):NULL,name,STATUS_PTR)) -#define astMirrorVariants(this,iframe) \ -astINVOKE(V,astMirrorVariants_(astCheckFrameSet(this),iframe,STATUS_PTR)) -#define astGetFrame(this,iframe) \ -astINVOKE(O,astGetFrame_(astCheckFrameSet(this),iframe,STATUS_PTR)) -#define astGetMapping(this,iframe1,iframe2) \ -astINVOKE(O,astGetMapping_(astCheckFrameSet(this),iframe1,iframe2,STATUS_PTR)) -#define astRemapFrame(this,iframe,map) \ -astINVOKE(V,astRemapFrame_(astCheckFrameSet(this),iframe,astCheckMapping(map),STATUS_PTR)) -#define astRemoveFrame(this,iframe) \ -astINVOKE(V,astRemoveFrame_(astCheckFrameSet(this),iframe,STATUS_PTR)) -#define astGetNode(this,inode,nnodes,iframe,map,parent) \ -astINVOKE(V,astGetNodeId_(astCheckFrameSet(this),inode,nnodes,iframe,map,parent,STATUS_PTR)) - -/* Interfaces to protected member functions. */ -/* ----------------------------------------- */ -#if defined(astCLASS) /* Protected */ -#define astClearBase(this) \ -astINVOKE(V,astClearBase_(astCheckFrameSet(this),STATUS_PTR)) -#define astClearCurrent(this) \ -astINVOKE(V,astClearCurrent_(astCheckFrameSet(this),STATUS_PTR)) -#define astGetBase(this) \ -astINVOKE(V,astGetBase_(astCheckFrameSet(this),STATUS_PTR)) -#define astGetCurrent(this) \ -astINVOKE(V,astGetCurrent_(astCheckFrameSet(this),STATUS_PTR)) -#define astGetNframe(this) \ -astINVOKE(V,astGetNframe_(astCheckFrameSet(this),STATUS_PTR)) -#define astSetBase(this,ibase) \ -astINVOKE(V,astSetBase_(astCheckFrameSet(this),ibase,STATUS_PTR)) -#define astSetCurrent(this,icurrent) \ -astINVOKE(V,astSetCurrent_(astCheckFrameSet(this),icurrent,STATUS_PTR)) -#define astTestBase(this) \ -astINVOKE(V,astTestBase_(astCheckFrameSet(this),STATUS_PTR)) -#define astTestCurrent(this) \ -astINVOKE(V,astTestCurrent_(astCheckFrameSet(this),STATUS_PTR)) -#define astValidateFrameIndex(this,iframe,method) \ -astINVOKE(V,astValidateFrameIndex_(astCheckFrameSet(this),iframe,method,STATUS_PTR)) -#define astClearVariant(this) \ -astINVOKE(V,astClearVariant_(astCheckFrameSet(this),STATUS_PTR)) -#define astGetVariant(this) \ -astINVOKE(V,astGetVariant_(astCheckFrameSet(this),STATUS_PTR)) -#define astSetVariant(this,variant) \ -astINVOKE(V,astSetVariant_(astCheckFrameSet(this),variant,STATUS_PTR)) -#define astTestVariant(this) \ -astINVOKE(V,astTestVariant_(astCheckFrameSet(this),STATUS_PTR)) -#define astGetAllVariants(this) \ -astINVOKE(V,astGetAllVariants_(astCheckFrameSet(this),STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/frameset.pdf b/ast/frameset.pdf deleted file mode 100644 index 7730800..0000000 Binary files a/ast/frameset.pdf and /dev/null differ diff --git a/ast/fratemap.c b/ast/fratemap.c deleted file mode 100644 index 62588ab..0000000 --- a/ast/fratemap.c +++ /dev/null @@ -1,106 +0,0 @@ -/* -*+ -* Name: -* fratemap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST RateMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the RateMap class. - -* Routines Defined: -* AST_ISARATEMAP -* AST_RATEMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S.Berry (Starlink) - -* History: -* 10-FEB-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "ratemap.h" /* C interface to the RateMap class */ - -F77_LOGICAL_FUNCTION(ast_isaratemap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astWatchSTATUS( - astAt( "AST_ISARATEMAP", NULL, 0 ); - RESULT = astIsARateMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_ratemap)( INTEGER(MAP), - INTEGER(AX1), - INTEGER(AX2), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(MAP) - GENPTR_INTEGER(AX1) - GENPTR_INTEGER(AX2) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_RATEMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astRateMap( astI2P( *MAP ), *AX1, *AX2, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fregion.c b/ast/fregion.c deleted file mode 100644 index 2c3b4ef..0000000 --- a/ast/fregion.c +++ /dev/null @@ -1,297 +0,0 @@ -/* -*+ -* Name: -* fregion.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Region class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Region class. - -* Routines Defined: -* AST_NEGATE -* AST_ISAREGION -* AST_MAPREGION -* AST_GETREGIONBOUNDS -* AST_GETREGIONFRAME -* AST_GETREGIONFRAMESET -* AST_OVERLAP -* AST_SETUNC -* AST_GETUNC -* AST_SHOWMESH - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-MAR-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "region.h" /* C interface to the Region class */ - -/* FORTRAN interface functions. */ -/* ============================ */ -/* These functions implement the remainder of the FORTRAN interface. */ - -F77_SUBROUTINE(ast_negate)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_NEGATE", NULL, 0 ); - astWatchSTATUS( - astNegate( astI2P( *THIS ) ); - ) -} - -F77_SUBROUTINE(ast_setunc)( INTEGER(THIS), - INTEGER(UNC), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(UNC) - - astAt( "AST_SETUNC", NULL, 0 ); - astWatchSTATUS( - astSetUnc( astI2P( *THIS ), astI2P( *UNC ) ); - ) -} - -F77_LOGICAL_FUNCTION(ast_isaregion)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAREGION", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsARegion( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_getregionframe)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETREGIONFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetRegionFrame( astI2P( *THIS ) ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_getregionframeset)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETREGIONFRAMESET", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetRegionFrameSet( astI2P( *THIS ) ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_getunc)( INTEGER(THIS), - LOGICAL(DEF), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_LOGICAL(DEF) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETUNC", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetUnc( astI2P( *THIS ), F77_ISTRUE( *DEF ) ? 1 : 0 ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_mapregion)( INTEGER(REG), - INTEGER(MAP), - INTEGER(FRM), - INTEGER(STATUS) ) { - GENPTR_INTEGER(REG) - GENPTR_INTEGER(MAP) - GENPTR_INTEGER(FRM) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_MAPREGION", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astMapRegion( astI2P( *REG ), astI2P( *MAP ), - astI2P( *FRM ) ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_overlap)( INTEGER(THIS), - INTEGER(THAT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(THAT) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_OVERLAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astOverlap( astI2P( *THIS ), astI2P( *THAT ) ); - ) - return RESULT; -} - -/* AST_MASK requires a function for each possible data type, so - define it via a macro. */ -#define MAKE_AST_MASK(f,F,Ftype,X,Xtype) \ -F77_INTEGER_FUNCTION(ast_mask##f)( INTEGER(THIS), \ - INTEGER(MAP), \ - LOGICAL(INSIDE), \ - INTEGER(NDIM), \ - INTEGER_ARRAY(LBND), \ - INTEGER_ARRAY(UBND), \ - Ftype##_ARRAY(IN), \ - Ftype(VAL), \ - INTEGER(STATUS) ) { \ - GENPTR_INTEGER(THIS) \ - GENPTR_INTEGER(MAP) \ - GENPTR_LOGICAL(INSIDE) \ - GENPTR_INTEGER(NDIM) \ - GENPTR_INTEGER_ARRAY(LBND) \ - GENPTR_INTEGER_ARRAY(UBND) \ - GENPTR_##Ftype##_ARRAY(IN) \ - GENPTR_##Ftype(VAL) \ - GENPTR_INTEGER(STATUS) \ -\ - F77_INTEGER_TYPE RESULT; \ -\ - astAt( "AST_MASK"#F, NULL, 0 ); \ - astWatchSTATUS( \ -\ - RESULT = astMask##X( astI2P( *THIS ), astI2P( *MAP ), \ - F77_ISTRUE( *INSIDE ) ? 1 : 0, *NDIM, \ - LBND, UBND, (Xtype *) IN, *VAL ); \ - ) \ - return RESULT; \ -} - -/* Invoke the above macro to define a function for each data - type. Include synonyms for some functions. */ -MAKE_AST_MASK(d,D,DOUBLE,D,double) -MAKE_AST_MASK(r,R,REAL,F,float) -MAKE_AST_MASK(i,I,INTEGER,I,int) -MAKE_AST_MASK(ui,UI,INTEGER,UI,unsigned int) -MAKE_AST_MASK(s,S,WORD,S,short int) -MAKE_AST_MASK(us,US,UWORD,US,unsigned short int) -MAKE_AST_MASK(w,W,WORD,S,short int) -MAKE_AST_MASK(uw,UW,UWORD,US,unsigned short int) -MAKE_AST_MASK(b,B,BYTE,B,signed char) -MAKE_AST_MASK(ub,UB,UBYTE,UB,unsigned char) -#undef MAKE_AST_MASK - -F77_SUBROUTINE(ast_getregionbounds)( INTEGER(THIS), - DOUBLE(LBND), - DOUBLE(UBND), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_DOUBLE(XOUT) - GENPTR_DOUBLE(YOUT) - - astAt( "AST_GETREGIONBOUNDS", NULL, 0 ); - astWatchSTATUS( - astGetRegionBounds( astI2P( *THIS ), LBND, UBND ); - ) -} - -F77_SUBROUTINE(ast_showmesh)( INTEGER(THIS), - LOGICAL(FORMAT), - CHARACTER(TTL), - INTEGER(STATUS) - TRAIL(TTL) ) { - GENPTR_INTEGER(THIS) - GENPTR_LOGICAL(FORMAT) - GENPTR_CHARACTER(TTL) - char *ttl; - - astAt( "AST_SHOWMESH", NULL, 0 ); - astWatchSTATUS( - ttl = astString( TTL, TTL_length ); - astShowMesh( astI2P( *THIS ), F77_ISTRUE( *FORMAT ) ? 1 : 0, ttl ); - ttl = astFree( ttl ); - ) -} - -F77_SUBROUTINE(ast_getregionpoints)( INTEGER(THIS), - INTEGER(MAXPOINT), - INTEGER(MAXCOORD), - INTEGER(NPOINT), - DOUBLE_ARRAY(POINTS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(MAXPOINT) - GENPTR_INTEGER(MAXCOORD) - GENPTR_INTEGER(NPOINT) - GENPTR_DOUBLE_ARRAY(POINTS) - - astAt( "AST_GETREGIONPOINT", NULL, 0 ); - astWatchSTATUS( - astGetRegionPoints( astI2P( *THIS ), *MAXPOINT, *MAXCOORD, NPOINT, - POINTS ); - ) -} - -F77_SUBROUTINE(ast_getregionmesh)( INTEGER(THIS), - LOGICAL(SURFACE), - INTEGER(MAXPOINT), - INTEGER(MAXCOORD), - INTEGER(NPOINT), - DOUBLE_ARRAY(POINTS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_LOGICAL(SURFACE) - GENPTR_INTEGER(MAXPOINT) - GENPTR_INTEGER(MAXCOORD) - GENPTR_INTEGER(NPOINT) - GENPTR_DOUBLE_ARRAY(POINTS) - - astAt( "AST_GETREGIONMESH", NULL, 0 ); - astWatchSTATUS( - astGetRegionMesh( astI2P( *THIS ), F77_ISTRUE( *SURFACE ), *MAXPOINT, - *MAXCOORD, NPOINT, POINTS ); - ) -} - - diff --git a/ast/fronta.pdf b/ast/fronta.pdf deleted file mode 100644 index fc0cd6e..0000000 Binary files a/ast/fronta.pdf and /dev/null differ diff --git a/ast/fronta_bw.pdf b/ast/fronta_bw.pdf deleted file mode 100644 index 099405e..0000000 Binary files a/ast/fronta_bw.pdf and /dev/null differ diff --git a/ast/frontb.pdf b/ast/frontb.pdf deleted file mode 100644 index e01d2cf..0000000 Binary files a/ast/frontb.pdf and /dev/null differ diff --git a/ast/frontb_bw.pdf b/ast/frontb_bw.pdf deleted file mode 100644 index d5a0e67..0000000 Binary files a/ast/frontb_bw.pdf and /dev/null differ diff --git a/ast/frontc.pdf b/ast/frontc.pdf deleted file mode 100644 index ec9228c..0000000 Binary files a/ast/frontc.pdf and /dev/null differ diff --git a/ast/frontc_bw.pdf b/ast/frontc_bw.pdf deleted file mode 100644 index d6dd1c8..0000000 Binary files a/ast/frontc_bw.pdf and /dev/null differ diff --git a/ast/fsalign.pdf b/ast/fsalign.pdf deleted file mode 100644 index e1c0c97..0000000 Binary files a/ast/fsalign.pdf and /dev/null differ diff --git a/ast/fsconvert.pdf b/ast/fsconvert.pdf deleted file mode 100644 index 1665762..0000000 Binary files a/ast/fsconvert.pdf and /dev/null differ diff --git a/ast/fselectormap.c b/ast/fselectormap.c deleted file mode 100644 index 4ecc4a7..0000000 --- a/ast/fselectormap.c +++ /dev/null @@ -1,115 +0,0 @@ -/* -*+ -* Name: -* fselectormap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST SelectorMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the SelectorMap class. - -* Routines Defined: -* AST_ISASELECTORMAP -* AST_SELECTORMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S.Berry (Starlink) - -* History: -* 14-MAR-2006 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "selectormap.h" /* C interface to the SelectorMap class */ - -F77_LOGICAL_FUNCTION(ast_isaselectormap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astWatchSTATUS( - astAt( "AST_ISASELECTORMAP", NULL, 0 ); - RESULT = astIsASelectorMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_selectormap)( INTEGER(NREG), - INTEGER_ARRAY(REGS), - DOUBLE(BADVAL), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NREG) - GENPTR_INTEGER_ARRAY(REGS) - GENPTR_DOUBLE(BADVAL) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - AstObject **regs; - - astAt( "AST_SELECTORMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - regs = astMalloc( sizeof(AstObject *) * (*NREG) ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - - for ( i = 0; i < *NREG; i++ ) { - regs[ i ] = astI2P( REGS[ i ] ); - } - } - - - RESULT = astP2I( astSelectorMap( *NREG, (void **) regs, *BADVAL, "%s", - options ) ); - astFree( regs ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fsexample.pdf b/ast/fsexample.pdf deleted file mode 100644 index 4b7d1df..0000000 Binary files a/ast/fsexample.pdf and /dev/null differ diff --git a/ast/fshiftmap.c b/ast/fshiftmap.c deleted file mode 100644 index d876071..0000000 --- a/ast/fshiftmap.c +++ /dev/null @@ -1,103 +0,0 @@ -/* -*+ -* Name: -* fshiftmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST ShiftMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the ShiftMap class. - -* Routines Defined: -* AST_ISASHIFTMAP -* AST_SHIFTMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 18-AUG-2003 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "shiftmap.h" /* C interface to the ShiftMap class */ - -F77_LOGICAL_FUNCTION(ast_isashiftmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASHIFTMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAShiftMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_shiftmap)( INTEGER(NAXES), - DOUBLE(SHIFT), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NAXES) - GENPTR_DOUBLE(SHIFT) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_SHIFTMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astShiftMap( *NAXES, SHIFT, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fskyframe.c b/ast/fskyframe.c deleted file mode 100644 index ebdbaaa..0000000 --- a/ast/fskyframe.c +++ /dev/null @@ -1,112 +0,0 @@ -/* -*+ -* Name: -* fskyframe.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST SkyFrame class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the SkyFrame class. - -* Routines Defined: -* AST_ISASKYFRAME -* AST_SKYFRAME - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 23-JUL-1996 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "skyframe.h" /* C interface to the SkyFrame class */ - -F77_LOGICAL_FUNCTION(ast_isaskyframe)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASKYFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsASkyFrame( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_skyframe)( CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_SKYFRAME", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astSkyFrame( "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_skyoffsetmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_SKYOFFSETMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astSkyOffsetMap( astI2P( *THIS ) ) ); - ) - return RESULT; -} - diff --git a/ast/fslamap.c b/ast/fslamap.c deleted file mode 100644 index 0fa631b..0000000 --- a/ast/fslamap.c +++ /dev/null @@ -1,122 +0,0 @@ -/* -*+ -* Name: -* fslamap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST SlaMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the SlaMap class. - -* Routines Defined: -* AST_ISASLAMAP -* AST_SLAADD -* AST_SLAMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 28-MAY-1997 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "slamap.h" /* C interface to the SlaMap class */ - -F77_LOGICAL_FUNCTION(ast_isaslamap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASLAMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsASlaMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_SUBROUTINE(ast_slaadd)( INTEGER(THIS), - CHARACTER(CVT), - INTEGER(NARG), - DOUBLE_ARRAY(ARGS), - INTEGER(STATUS) - TRAIL(CVT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(CVT) - GENPTR_INTEGER(NARG) - GENPTR_DOUBLE_ARRAY(ARGS) - char *cvt; - - astAt( "AST_SLAADD", NULL, 0 ); - astWatchSTATUS( - cvt = astString( CVT, CVT_length ); - astSlaAdd( astI2P( *THIS ), cvt, *NARG, ARGS ); - astFree( cvt ); - ) -} - -F77_INTEGER_FUNCTION(ast_slamap)( INTEGER(FLAGS), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FLAGS) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_SLAMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astSlaMap( *FLAGS, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fsmerge.pdf b/ast/fsmerge.pdf deleted file mode 100644 index 33fe7dc..0000000 Binary files a/ast/fsmerge.pdf and /dev/null differ diff --git a/ast/fspecfluxframe.c b/ast/fspecfluxframe.c deleted file mode 100644 index fb1c218..0000000 --- a/ast/fspecfluxframe.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -*+ -* Name: -* fspecfluxframe.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST SpecFluxFrame class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the SpecFluxFrame class. - -* Routines Defined: -* AST_SPECFLUXFRAME -* AST_ISASPECFLUXFRAME - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 8-DEC-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "specfluxframe.h" /* C interface to the SpecFluxFrame class */ - -F77_LOGICAL_FUNCTION(ast_isaspecfluxframe)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASPECFLUXFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsASpecFluxFrame( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_specfluxframe)( INTEGER(FRAME1), - INTEGER(FRAME2), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FRAME1) - GENPTR_INTEGER(FRAME2) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_SPECFLUXFRAME", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astSpecFluxFrame( astI2P( *FRAME1 ), astI2P( *FRAME2 ), - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fspecframe.c b/ast/fspecframe.c deleted file mode 100644 index c45c7e3..0000000 --- a/ast/fspecframe.c +++ /dev/null @@ -1,134 +0,0 @@ -/* -*+ -* Name: -* fspecframe.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST SpecFrame class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the SpecFrame class. - -* Routines Defined: -* AST_ISASPECFRAME -* AST_SPECFRAME -* AST_SETREFPOS -* AST_GETREFPOS - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 20-NOV-2002 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "specframe.h" /* C interface to the SpecFrame class */ - -F77_LOGICAL_FUNCTION(ast_isaspecframe)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASPECFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsASpecFrame( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_specframe)( CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_SPECFRAME", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astSpecFrame( "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_getrefpos)( INTEGER(THIS), - INTEGER(FRM), - DOUBLE(LON), - DOUBLE(LAT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(FRM) - GENPTR_DOUBLE(LON) - GENPTR_DOUBLE(LAT) - - astAt( "AST_GETREFPOS", NULL, 0 ); - astWatchSTATUS( - astGetRefPos( astI2P( *THIS ), astI2P( *FRM ), LON, LAT ); - ) -} - -F77_SUBROUTINE(ast_setrefpos)( INTEGER(THIS), - INTEGER(FRM), - DOUBLE(LON), - DOUBLE(LAT), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(FRM) - GENPTR_DOUBLE(LON) - GENPTR_DOUBLE(LAT) - - astAt( "AST_SETREFPOS", NULL, 0 ); - astWatchSTATUS( - astSetRefPos( astI2P( *THIS ), astI2P( *FRM ), *LON, *LAT ); - ) -} - diff --git a/ast/fspecmap.c b/ast/fspecmap.c deleted file mode 100644 index f96db73..0000000 --- a/ast/fspecmap.c +++ /dev/null @@ -1,124 +0,0 @@ -/* -*+ -* Name: -* fspecmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST SpecMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the SpecMap class. - -* Routines Defined: -* AST_ISASPECMAP -* AST_SPECADD -* AST_SPECMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 11-NOV-2002 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "specmap.h" /* C interface to the SpecMap class */ - -F77_LOGICAL_FUNCTION(ast_isaspecmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASPECMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsASpecMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_SUBROUTINE(ast_specadd)( INTEGER(THIS), - CHARACTER(CVT), - INTEGER(NARG), - DOUBLE_ARRAY(ARGS), - INTEGER(STATUS) - TRAIL(CVT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(CVT) - GENPTR_INTEGER(NARG) - GENPTR_DOUBLE_ARRAY(ARGS) - char *cvt; - - astAt( "AST_SPECADD", NULL, 0 ); - astWatchSTATUS( - cvt = astString( CVT, CVT_length ); - astSpecAdd( astI2P( *THIS ), cvt, *NARG, ARGS ); - astFree( cvt ); - ) -} - -F77_INTEGER_FUNCTION(ast_specmap)( INTEGER(NIN), - INTEGER(FLAGS), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NIN) - GENPTR_INTEGER(FLAGS) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_SPECMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astSpecMap( *NIN, *FLAGS, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fsphmap.c b/ast/fsphmap.c deleted file mode 100644 index 439fec9..0000000 --- a/ast/fsphmap.c +++ /dev/null @@ -1,99 +0,0 @@ -/* -*+ -* Name: -* fsphmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST SphMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the SphMap class. - -* Routines Defined: -* AST_ISASPHMAP -* AST_SPHMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 25-OCT-1996 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "sphmap.h" /* C interface to the SphMap class */ - -F77_LOGICAL_FUNCTION(ast_isasphmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASPHMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsASphMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_sphmap)( CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_SPHMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astSphMap( "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fsremap.pdf b/ast/fsremap.pdf deleted file mode 100644 index 3554420..0000000 Binary files a/ast/fsremap.pdf and /dev/null differ diff --git a/ast/fstc.c b/ast/fstc.c deleted file mode 100644 index 50c53bb..0000000 --- a/ast/fstc.c +++ /dev/null @@ -1,114 +0,0 @@ -/* -*+ -* Name: -* fstc.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Stc class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Stc class. - -* Routines Defined: -* AST_ISASTC -* AST_GETSTCREGION -* AST_GETSTCCOORD -* AST_GETSTCNCOORD - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-NOV-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "stc.h" /* C interface to the Stc class */ - - -F77_INTEGER_FUNCTION(ast_getstcncoord)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETSTCNCOORD", NULL, 0 ); - astWatchSTATUS( - RESULT = astGetStcNCoord( astI2P( *THIS ) ); - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_getstccoord)( INTEGER(THIS), - INTEGER(ICOORD), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(ICOORD) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETSTCCOORD", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetStcCoord( astI2P( *THIS ), *ICOORD ) ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_isastc)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASTC", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAStc( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_getstcregion)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_INTEGER_TYPE(RESULT); - - astAt( "AST_GETSTCREGION", NULL, 0 ); - astWatchSTATUS( - RESULT = astP2I( astGetStcRegion( astI2P( *THIS ) ) ); - ) - return RESULT; -} - - diff --git a/ast/fstccatalogentrylocation.c b/ast/fstccatalogentrylocation.c deleted file mode 100644 index 5c88aa0..0000000 --- a/ast/fstccatalogentrylocation.c +++ /dev/null @@ -1,117 +0,0 @@ -/* -*+ -* Name: -* fstccatalogentrylocation.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST StcCatalogEntryLocation class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the StcCatalogEntryLocation class. - -* Routines Defined: -* AST_ISASTCCATALOGENTRYLOCATION -* AST_STCCATALOGENTRYLOCATION - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-NOV-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "stccatalogentrylocation.h" /* C interface to the StcCatalogEntryLocation class */ - - -F77_LOGICAL_FUNCTION(ast_isastccatalogentrylocation)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASTCCATALOGENTRYLOCATION", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAStcCatalogEntryLocation( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_stccatalogentrylocation)( INTEGER(REG), - INTEGER(NCOORDS), - INTEGER_ARRAY(COORDS), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(REG) - GENPTR_INTEGER(NCOORDS) - GENPTR_CHARACTER(OPTIONS) - GENPTR_INTEGER_ARRAY(COORDS) - AstKeyMap **coords; - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_STCCATALOGENTRYLOCATION", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - -/* Convert supplied integers to pointers. */ - coords = astMalloc( sizeof( AstKeyMap * )*(size_t)( *NCOORDS )); - if( astOK ) { - for( i = 0; i < *NCOORDS; i++ ) { - coords[ i ] = (AstKeyMap *) astMakePointer( astI2P( COORDS[ i ] )); - } - } - - RESULT = astP2I( astStcCatalogEntryLocation( astI2P( *REG ), *NCOORDS, - coords, "%s", options ) ); - astFree( coords ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fstcobsdatalocation.c b/ast/fstcobsdatalocation.c deleted file mode 100644 index 767ebb4..0000000 --- a/ast/fstcobsdatalocation.c +++ /dev/null @@ -1,117 +0,0 @@ -/* -*+ -* Name: -* fstcobsdatalocation.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST StcObsDataLocation class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the StcObsDataLocation class. - -* Routines Defined: -* AST_ISASTCOBSDATALOCATION -* AST_STCOBSDATALOCATION - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-NOV-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "stcobsdatalocation.h" /* C interface to the StcObsDataLocation class */ - - -F77_LOGICAL_FUNCTION(ast_isastcobsdatalocation)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASTCOBSDATALOCATION", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAStcObsDataLocation( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_stcobsdatalocation)( INTEGER(REG), - INTEGER(NCOORDS), - INTEGER_ARRAY(COORDS), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(REG) - GENPTR_INTEGER(NCOORDS) - GENPTR_CHARACTER(OPTIONS) - GENPTR_INTEGER_ARRAY(COORDS) - AstKeyMap **coords; - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_STCOBSDATALOCATION", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - -/* Convert supplied integers to pointers. */ - coords = astMalloc( sizeof( AstKeyMap * )*(size_t)( *NCOORDS )); - if( astOK ) { - for( i = 0; i < *NCOORDS; i++ ) { - coords[ i ] = (AstKeyMap *) astMakePointer( astI2P( COORDS[ i ] )); - } - } - - RESULT = astP2I( astStcObsDataLocation( astI2P( *REG ), *NCOORDS, - coords, "%s", options ) ); - astFree( coords ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fstcresourceprofile.c b/ast/fstcresourceprofile.c deleted file mode 100644 index 04484f3..0000000 --- a/ast/fstcresourceprofile.c +++ /dev/null @@ -1,118 +0,0 @@ -/* -*+ -* Name: -* fstcresourceprofile.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST StcResourceProfile class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the StcResourceProfile class. - -* Routines Defined: -* AST_ISASTCRESOURCEPROFILE -* AST_STCRESOURCEPROFILE - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-NOV-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "object.h" /* Basic AST Object management functions */ -#include "stcresourceprofile.h" /* C interface to the StcResourceProfile class */ - - -F77_LOGICAL_FUNCTION(ast_isastcresourceprofile)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASTCRESOURCEPROFILE", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAStcResourceProfile( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_stcresourceprofile)( INTEGER(REG), - INTEGER(NCOORDS), - INTEGER_ARRAY(COORDS), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(REG) - GENPTR_INTEGER(NCOORDS) - GENPTR_CHARACTER(OPTIONS) - GENPTR_INTEGER_ARRAY(COORDS) - AstKeyMap **coords; - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_STCRESOURCEPROFILE", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - -/* Convert supplied integers to pointers. */ - coords = astMalloc( sizeof( AstKeyMap * )*(size_t)( *NCOORDS )); - if( astOK ) { - for( i = 0; i < *NCOORDS; i++ ) { - coords[ i ] = (AstKeyMap *) astMakePointer( astI2P( COORDS[ i ] )); - } - } - - RESULT = astP2I( astStcResourceProfile( astI2P( *REG ), *NCOORDS, - coords, "%s", options ) ); - astFree( coords ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fstcschan.c b/ast/fstcschan.c deleted file mode 100644 index 9f47469..0000000 --- a/ast/fstcschan.c +++ /dev/null @@ -1,131 +0,0 @@ -/* -*+ -* Name: -* fstcschan.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST StcsChan class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the StcsChan class. - -* Routines Defined: -* AST_STCSCHAN -* AST_ISASTCSCHAN - -* Copyright: -* Copyright (C) 2008 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (JAC,UCLan) - -* History: -* 18-DEC-2008 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "channel.h" /* Provides wrapper functions */ -#include "stcschan.h" /* C interface to the StcsChan class */ - -#include - -/* Prototypes for external functions. */ -/* ================================== */ -/* This is the null function defined by the FORTRAN interface in fobject.c. */ -F77_SUBROUTINE(ast_null)( void ); - -/* FORTRAN interface functions. */ -/* ============================ */ -/* These functions implement the remainder of the FORTRAN interface. */ -F77_INTEGER_FUNCTION(ast_stcschan)( void (* SOURCE)(), - void (* SINK)(), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - const char *(* source)( void ); - int i; - void (* sink)( const char * ); - - astAt( "AST_STCSCHAN", NULL, 0 ); - astWatchSTATUS( - -/* Set the source and sink function pointers to NULL if a pointer to - the null routine AST_NULL has been supplied. */ - source = (const char *(*)( void )) SOURCE; - if ( source == (const char *(*)( void )) F77_EXTERNAL_NAME(ast_null) ) { - source = NULL; - } - sink = (void (*)( const char * )) SINK; - if ( sink == (void (*)( const char * )) F77_EXTERNAL_NAME(ast_null) ) { - sink = NULL; - } - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astStcsChanFor( source, astSourceWrap, sink, astSinkWrap, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_isastcschan)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASTCSCHAN", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAStcsChan( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - - - - - diff --git a/ast/fstcsearchlocation.c b/ast/fstcsearchlocation.c deleted file mode 100644 index aa74baf..0000000 --- a/ast/fstcsearchlocation.c +++ /dev/null @@ -1,117 +0,0 @@ -/* -*+ -* Name: -* fstcsearchlocation.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST StcSearchLocation class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the StcSearchLocation class. - -* Routines Defined: -* AST_ISASTCSEARCHLOCATION -* AST_STCSEARCHLOCATION - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-NOV-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "stcsearchlocation.h" /* C interface to the StcSearchLocation class */ - - -F77_LOGICAL_FUNCTION(ast_isastcsearchlocation)( INTEGER(THIS), INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISASTCSEARCHLOCATION", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAStcSearchLocation( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_stcsearchlocation)( INTEGER(REG), - INTEGER(NCOORDS), - INTEGER_ARRAY(COORDS), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(REG) - GENPTR_INTEGER(NCOORDS) - GENPTR_CHARACTER(OPTIONS) - GENPTR_INTEGER_ARRAY(COORDS) - AstKeyMap **coords; - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_STCSEARCHLOCATION", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - -/* Convert supplied integers to pointers. */ - coords = astMalloc( sizeof( AstKeyMap * )*(size_t)( *NCOORDS )); - if( astOK ) { - for( i = 0; i < *NCOORDS; i++ ) { - coords[ i ] = (AstKeyMap *) astMakePointer( astI2P( COORDS[ i ] )); - } - } - - RESULT = astP2I( astStcSearchLocation( astI2P( *REG ), *NCOORDS, - coords, "%s", options ) ); - astFree( coords ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fswitchmap.c b/ast/fswitchmap.c deleted file mode 100644 index 0159420..0000000 --- a/ast/fswitchmap.c +++ /dev/null @@ -1,118 +0,0 @@ -/* -*+ -* Name: -* fswitchmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST SwitchMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the SwitchMap class. - -* Routines Defined: -* AST_ISASWITCHMAP -* AST_SWITCHMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S.Berry (Starlink) - -* History: -* 13-MAR-2006 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "switchmap.h" /* C interface to the SwitchMap class */ - -F77_LOGICAL_FUNCTION(ast_isaswitchmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astWatchSTATUS( - astAt( "AST_ISASWITCHMAP", NULL, 0 ); - RESULT = astIsASwitchMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_switchmap)( INTEGER(FSMAP), - INTEGER(ISMAP), - INTEGER(NROUTE), - INTEGER_ARRAY(ROUTEMAPS), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FSMAP) - GENPTR_INTEGER(ISMAP) - GENPTR_INTEGER(NROUTE) - GENPTR_INTEGER_ARRAY(ROUTEMAPS) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - AstObject **routemaps; - - astAt( "AST_SWITCHMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - routemaps = astMalloc( sizeof(AstObject *) * (*NROUTE) ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - - for ( i = 0; i < *NROUTE; i++ ) { - routemaps[ i ] = astI2P( ROUTEMAPS[ i ] ); - } - } - - - RESULT = astP2I( astSwitchMap( astI2P( *FSMAP ), astI2P( *ISMAP ), - *NROUTE, (void **) routemaps, "%s", - options ) ); - astFree( routemaps ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/ftable.c b/ast/ftable.c deleted file mode 100644 index 5656531..0000000 --- a/ast/ftable.c +++ /dev/null @@ -1,330 +0,0 @@ -/* -*+ -* Name: -* ftable.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST Table class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the Table class. - -* Routines Defined: -* AST_ISATABLE -* AST_TABLE - -* Copyright: -* Copyright (C) 2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S.Berry (Starlink) - -* History: -* 22-NOV-2010 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "table.h" /* C interface to the Table class */ - -F77_LOGICAL_FUNCTION(ast_isatable)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astWatchSTATUS( - astAt( "AST_ISATABLE", NULL, 0 ); - RESULT = astIsATable( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_table)( CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_TABLE", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astTable( "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_SUBROUTINE(ast_addcolumn)( INTEGER(THIS), - CHARACTER(NAME), - INTEGER(TYPE), - INTEGER(NDIM), - INTEGER_ARRAY(DIMS), - CHARACTER(UNIT), - INTEGER(STATUS) - TRAIL(NAME) - TRAIL(UNIT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - GENPTR_INTEGER(TYPE) - GENPTR_INTEGER(NDIM) - GENPTR_INTEGER_ARRAY(DIMS) - GENPTR_CHARACTER(UNIT) - char *name, *unit; - - astAt( "AST_ADDCOLUMN", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - unit = astString( UNIT, UNIT_length ); - astAddColumn( astI2P( *THIS ), name, *TYPE, *NDIM, DIMS, unit ); - astFree( name ); - astFree( unit ); - ) -} - -F77_SUBROUTINE(ast_addparameter)( INTEGER(THIS), - CHARACTER(NAME), - INTEGER(STATUS) - TRAIL(NAME) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - char *name; - - astAt( "AST_ADDPARAMETER", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - astAddParameter( astI2P( *THIS ), name ); - astFree( name ); - ) -} - -F77_SUBROUTINE(ast_removecolumn)( INTEGER(THIS), - CHARACTER(NAME), - INTEGER(STATUS) - TRAIL(NAME) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - char *name; - - astAt( "AST_REMOVECOLUMN", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - astRemoveColumn( astI2P( *THIS ), name ); - astFree( name ); - ) -} - -F77_SUBROUTINE(ast_removeparameter)( INTEGER(THIS), - CHARACTER(NAME), - INTEGER(STATUS) - TRAIL(NAME) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(NAME) - char *name; - - astAt( "AST_REMOVEPARAMETER", NULL, 0 ); - astWatchSTATUS( - name = astString( NAME, NAME_length ); - astRemoveParameter( astI2P( *THIS ), name ); - astFree( name ); - ) -} - -F77_SUBROUTINE(ast_removerow)( INTEGER(THIS), - INTEGER(INDEX), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(INDEX) - - astAt( "AST_REMOVEROW", NULL, 0 ); - astWatchSTATUS( - astRemoveRow( astI2P( *THIS ), *INDEX ); - ) -} - -F77_SUBROUTINE(ast_purgerows)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - - astAt( "AST_PURGEROWS", NULL, 0 ); - astWatchSTATUS( - astPurgeRows( astI2P( *THIS ) ); - ) -} - - -/* NO_CHAR_FUNCTION indicates that the f77.h method of returning a - character result doesn't work, so add an extra argument instead and - wrap this function up in a normal FORTRAN 77 function (in the file - keymap.f). */ -#if NO_CHAR_FUNCTION -F77_SUBROUTINE(ast_columnname_a)( CHARACTER(RESULT), -#else -F77_SUBROUTINE(ast_columnname)( CHARACTER_RETURN_VALUE(RESULT), -#endif - INTEGER(THIS), - INTEGER(INDEX), -#if NO_CHAR_FUNCTION - INTEGER(STATUS) - TRAIL(RESULT) ) { -#else - INTEGER(STATUS) ) { -#endif - GENPTR_CHARACTER(RESULT) - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(INDEX) - const char *result; - int i; - - astAt( "AST_COLUMNNAME", NULL, 0 ); - astWatchSTATUS( - result = astColumnName( astI2P( *THIS ), *INDEX ); - i = 0; - if ( astOK ) { /* Copy result */ - for ( ; result[ i ] && i < RESULT_length; i++ ) { - RESULT[ i ] = result[ i ]; - } - } - while ( i < RESULT_length ) RESULT[ i++ ] = ' '; /* Pad with blanks */ - ) -} - -/* NO_CHAR_FUNCTION indicates that the f77.h method of returning a - character result doesn't work, so add an extra argument instead and - wrap this function up in a normal FORTRAN 77 function (in the file - keymap.f). */ -#if NO_CHAR_FUNCTION -F77_SUBROUTINE(ast_parametername_a)( CHARACTER(RESULT), -#else -F77_SUBROUTINE(ast_parametername)( CHARACTER_RETURN_VALUE(RESULT), -#endif - INTEGER(THIS), - INTEGER(INDEX), -#if NO_CHAR_FUNCTION - INTEGER(STATUS) - TRAIL(RESULT) ) { -#else - INTEGER(STATUS) ) { -#endif - GENPTR_CHARACTER(RESULT) - GENPTR_INTEGER(THIS) - GENPTR_INTEGER(INDEX) - const char *result; - int i; - - astAt( "AST_PARAMETERNAME", NULL, 0 ); - astWatchSTATUS( - result = astParameterName( astI2P( *THIS ), *INDEX ); - i = 0; - if ( astOK ) { /* Copy result */ - for ( ; result[ i ] && i < RESULT_length; i++ ) { - RESULT[ i ] = result[ i ]; - } - } - while ( i < RESULT_length ) RESULT[ i++ ] = ' '; /* Pad with blanks */ - ) -} - - -F77_SUBROUTINE(ast_columnshape)( INTEGER(THIS), - CHARACTER(COLUMN), - INTEGER(MXDIM), - INTEGER(NDIM), - INTEGER_ARRAY(DIMS), - INTEGER(STATUS) - TRAIL(COLUMN) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(COLUMN) - GENPTR_INTEGER(MXDIM) - GENPTR_INTEGER(NDIM) - GENPTR_INTEGER_ARRAY(DIMS) - char *column; - - astAt( "AST_COLUMNSHAPE", NULL, 0 ); - astWatchSTATUS( - column = astString( COLUMN, COLUMN_length ); - astColumnShape( astI2P( *THIS ), column, *MXDIM, NDIM, DIMS ); - astFree( column ); - ) -} - - -F77_LOGICAL_FUNCTION(ast_hascolumn)( INTEGER(THIS), - CHARACTER(COLUMN), - INTEGER(STATUS) - TRAIL(COLUMN) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(COLUMN) - F77_LOGICAL_TYPE(RESULT); - char *column; - - astWatchSTATUS( - astAt( "AST_HASCOLUMN", NULL, 0 ); - column = astString( COLUMN, COLUMN_length ); - RESULT = astHasColumn( astI2P( *THIS ), column ) ? F77_TRUE : F77_FALSE; - astFree( column ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_hasparameter)( INTEGER(THIS), - CHARACTER(PARAM), - INTEGER(STATUS) - TRAIL(PARAM) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(PARAM) - F77_LOGICAL_TYPE(RESULT); - char *param; - - astWatchSTATUS( - astAt( "AST_HASPARAMETER", NULL, 0 ); - param = astString( PARAM, PARAM_length ); - RESULT = astHasParameter( astI2P( *THIS ), param ) ? F77_TRUE : F77_FALSE; - astFree( param ); - ) - return RESULT; -} - diff --git a/ast/ftemplateclass.c b/ast/ftemplateclass.c deleted file mode 100644 index 28dca89..0000000 --- a/ast/ftemplateclass.c +++ /dev/null @@ -1,109 +0,0 @@ -1 - Replace TemplateClass with capitalised class name -2 - Replace templateclass with lower case class name -3 - Replace TEMPLATECLASS with upper case class name -4 - Replace TemplateParent with capitalised parent class name -5 - Replace templateparent with lower case parent class name -6 - Replace all occurrences of >>> with suitable text - -/* -*+ -* Name: -* ftemplateclass.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST TemplateClass class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the TemplateClass class. - -* Routines Defined: -* AST_ISATEMPLATECLASS -* AST_TEMPLATECLASS - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* >>> 20-NOV-2002 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "templateclass.h" /* C interface to the TemplateClass class */ - -F77_LOGICAL_FUNCTION(ast_isatemplateclass)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISATEMPLATECLASS", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsATemplateClass( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_templateclass)( >>> CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { ->>> - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_TEMPLATECLASS", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astTemplateClass( >>> "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - ->>> diff --git a/ast/ftimeframe.c b/ast/ftimeframe.c deleted file mode 100644 index f164c26..0000000 --- a/ast/ftimeframe.c +++ /dev/null @@ -1,114 +0,0 @@ -/* -*+ -* Name: -* ftimeframe.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST TimeFrame class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the TimeFrame class. - -* Routines Defined: -* AST_ISATIMEFRAME -* AST_TIMEFRAME -* AST_CURRENTTIME - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* NG: Norman Gray (Starlink) - -* History: -* 02-AUG-2003 (NG): -* Original version, heavily based on fspecframe.c. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "timeframe.h" /* C interface to the TimeFrame class */ - -F77_LOGICAL_FUNCTION(ast_isatimeframe)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISATIMEFRAME", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsATimeFrame( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_timeframe)( CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_TIMEFRAME", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astTimeFrame( "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_DOUBLE_FUNCTION(ast_currenttime)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_DOUBLE_TYPE(RESULT); - - astAt( "AST_CURRENTTIME", NULL, 0 ); - astWatchSTATUS( - RESULT = astCurrentTime( astI2P( *THIS ) ); - ) - return RESULT; -} - - diff --git a/ast/ftimemap.c b/ast/ftimemap.c deleted file mode 100644 index a9929f2..0000000 --- a/ast/ftimemap.c +++ /dev/null @@ -1,122 +0,0 @@ -/* -*+ -* Name: -* ftimemap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST TimeMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the TimeMap class. - -* Routines Defined: -* AST_ISATIMEMAP -* AST_TIMEADD -* AST_TIMEMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* NG: Norman Gray (Starlink) - -* History: -* 08-Sep-2003 (NG): -* Original version (heavily based on fspecmap.c) -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "timemap.h" /* C interface to the TimeMap class */ - -F77_LOGICAL_FUNCTION(ast_isatimemap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISATIMEMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsATimeMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_SUBROUTINE(ast_timeadd)( INTEGER(THIS), - CHARACTER(CVT), - INTEGER(NARG), - DOUBLE_ARRAY(ARGS), - INTEGER(STATUS) - TRAIL(CVT) ) { - GENPTR_INTEGER(THIS) - GENPTR_CHARACTER(CVT) - GENPTR_INTEGER(NARG) - GENPTR_DOUBLE_ARRAY(ARGS) - char *cvt; - - astAt( "AST_TIMEADD", NULL, 0 ); - astWatchSTATUS( - cvt = astString( CVT, CVT_length ); - astTimeAdd( astI2P( *THIS ), cvt, *NARG, ARGS ); - astFree( cvt ); - ) -} - -F77_INTEGER_FUNCTION(ast_timemap)( INTEGER(FLAGS), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(FLAGS) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_TIMEMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astTimeMap( *FLAGS, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/ftranmap.c b/ast/ftranmap.c deleted file mode 100644 index 155439b..0000000 --- a/ast/ftranmap.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -*+ -* Name: -* ftranmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST TranMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the TranMap class. - -* Routines Defined: -* AST_ISATRANMAP -* AST_TRANMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S.Berry (Starlink) - -* History: -* 10-FEB-2004 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "tranmap.h" /* C interface to the TranMap class */ - -F77_LOGICAL_FUNCTION(ast_isatranmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astWatchSTATUS( - astAt( "AST_ISATRANMAP", NULL, 0 ); - RESULT = astIsATranMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_tranmap)( INTEGER(MAP1), - INTEGER(MAP2), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(MAP1) - GENPTR_INTEGER(MAP2) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - int i; - char *options; - - astAt( "AST_TRANMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astTranMap( astI2P( *MAP1 ), astI2P( *MAP2 ), - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/funitmap.c b/ast/funitmap.c deleted file mode 100644 index 986a82d..0000000 --- a/ast/funitmap.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -*+ -* Name: -* funitmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST UnitMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the UnitMap class. - -* Routines Defined: -* AST_ISAUNITMAP -* AST_UNITMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 25-SEP-1996 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "unitmap.h" /* C interface to the UnitMap class */ - -F77_LOGICAL_FUNCTION(ast_isaunitmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAUNITMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAUnitMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_unitmap)( INTEGER(NCOORD), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NCOORD) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_UNITMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astUnitMap( *NCOORD, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/funitnormmap.c b/ast/funitnormmap.c deleted file mode 100644 index 8e88009..0000000 --- a/ast/funitnormmap.c +++ /dev/null @@ -1,105 +0,0 @@ -/* -*+ -* Name: -* fshiftmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST UnitNormMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the UnitNormMap class. - -* Routines Defined: -* AST_ISAUNITNORMMAP -* AST_UNITNORMMAP - -* Copyright: -* Copyright (C) 2016 AURA/LSST -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) -* TIMJ: Tim Jenness (LSST) - -* History: -* 18-AUG-2003 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "unitnormmap.h" /* C interface to the UnitNormMap class */ - -F77_LOGICAL_FUNCTION(ast_isaunitnormmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAUNITNORMMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAUnitNormMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_unitnormmap)( INTEGER(NCOORDS), - DOUBLE(CENTRE), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NCOORDS) - GENPTR_DOUBLE(CENTRE) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_UNITNORMMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astUnitNormMap( *NCOORDS, CENTRE, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fwcsmap.c b/ast/fwcsmap.c deleted file mode 100644 index 0b1e3a3..0000000 --- a/ast/fwcsmap.c +++ /dev/null @@ -1,108 +0,0 @@ -/* -*+ -* Name: -* fwcsmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST WcsMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the WcsMap class. - -* Routines Defined: -* AST_ISAWCSMAP -* AST_WCSMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 18-NOV-1996 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "wcsmap.h" /* C interface to the WcsMap class */ - -F77_LOGICAL_FUNCTION(ast_isawcsmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAWCSMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAWcsMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_wcsmap)( INTEGER(NAXES), - INTEGER(TYPE), - INTEGER(LONAX), - INTEGER(LATAX), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NAXES) - GENPTR_INTEGER(TYPE) - GENPTR_INTEGER(LONAX) - GENPTR_INTEGER(LATAX) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_WCSMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astWcsMap( *NAXES, *TYPE, *LONAX, *LATAX, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fwinmap.c b/ast/fwinmap.c deleted file mode 100644 index 41338a0..0000000 --- a/ast/fwinmap.c +++ /dev/null @@ -1,110 +0,0 @@ -/* -*+ -* Name: -* fwinmap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST WinMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the WinMap class. - -* Routines Defined: -* AST_ISAWINMAP -* AST_WINMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 23-OCT-1996 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "winmap.h" /* C interface to the WinMap class */ - -F77_LOGICAL_FUNCTION(ast_isawinmap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAWINMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAWinMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_winmap)( INTEGER(NAXES), - DOUBLE(C1_IN), - DOUBLE(C2_IN), - DOUBLE(C1_OUT), - DOUBLE(C2_OUT), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NAXES) - GENPTR_DOUBLE(C1_IN) - GENPTR_DOUBLE(C2_IN) - GENPTR_DOUBLE(C1_OUT) - GENPTR_DOUBLE(C2_OUT) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_WINMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astWinMap( *NAXES, C1_IN, C2_IN, C1_OUT, C2_OUT, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/fxmlchan.c b/ast/fxmlchan.c deleted file mode 100644 index 17efc50..0000000 --- a/ast/fxmlchan.c +++ /dev/null @@ -1,130 +0,0 @@ -/* -*+ -* Name: -* fxmlchan.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST XmlChan class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the XmlChan class. - -* Routines Defined: -* AST_XMLCHAN -* AST_ISAXMLCHAN - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 21-OCT-2003 (DSB): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "channel.h" /* Provides wrapper functions */ -#include "xmlchan.h" /* C interface to the XmlChan class */ - -#include - -/* Prototypes for external functions. */ -/* ================================== */ -/* This is the null function defined by the FORTRAN interface in fobject.c. */ -F77_SUBROUTINE(ast_null)( void ); - -/* FORTRAN interface functions. */ -/* ============================ */ -/* These functions implement the remainder of the FORTRAN interface. */ -F77_INTEGER_FUNCTION(ast_xmlchan)( void (* SOURCE)(), - void (* SINK)(), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - const char *(* source)( void ); - int i; - void (* sink)( const char * ); - - astAt( "AST_XMLCHAN", NULL, 0 ); - astWatchSTATUS( - -/* Set the source and sink function pointers to NULL if a pointer to - the null routine AST_NULL has been supplied. */ - source = (const char *(*)( void )) SOURCE; - if ( source == (const char *(*)( void )) F77_EXTERNAL_NAME(ast_null) ) { - source = NULL; - } - sink = (void (*)( const char * )) SINK; - if ( sink == (void (*)( const char * )) F77_EXTERNAL_NAME(ast_null) ) { - sink = NULL; - } - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astXmlChanFor( source, astSourceWrap, sink, astSinkWrap, - "%s", options ) ); - astFree( options ); - ) - return RESULT; -} - -F77_LOGICAL_FUNCTION(ast_isaxmlchan)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAXMLCHAN", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAXmlChan( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - - - - diff --git a/ast/fzoommap.c b/ast/fzoommap.c deleted file mode 100644 index d2c8e48..0000000 --- a/ast/fzoommap.c +++ /dev/null @@ -1,103 +0,0 @@ -/* -*+ -* Name: -* fzoommap.c - -* Purpose: -* Define a FORTRAN 77 interface to the AST ZoomMap class. - -* Type of Module: -* C source file. - -* Description: -* This file defines FORTRAN 77-callable C functions which provide -* a public FORTRAN 77 interface to the ZoomMap class. - -* Routines Defined: -* AST_ISAZOOMMAP -* AST_ZOOMMAP - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 18-JUL-1996 (RFWS): -* Original version. -*/ - -/* Define the astFORTRAN77 macro which prevents error messages from - AST C functions from reporting the file and line number where the - error occurred (since these would refer to this file, they would - not be useful). */ -#define astFORTRAN77 - -/* Header files. */ -/* ============= */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* F77 <-> C support functions/macros */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory handling facilities */ -#include "zoommap.h" /* C interface to the ZoomMap class */ - -F77_LOGICAL_FUNCTION(ast_isazoommap)( INTEGER(THIS), - INTEGER(STATUS) ) { - GENPTR_INTEGER(THIS) - F77_LOGICAL_TYPE(RESULT); - - astAt( "AST_ISAZOOMMAP", NULL, 0 ); - astWatchSTATUS( - RESULT = astIsAZoomMap( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; - ) - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_zoommap)( INTEGER(NAXES), - DOUBLE(ZOOM), - CHARACTER(OPTIONS), - INTEGER(STATUS) - TRAIL(OPTIONS) ) { - GENPTR_INTEGER(NAXES) - GENPTR_DOUBLE(ZOOM) - GENPTR_CHARACTER(OPTIONS) - F77_INTEGER_TYPE(RESULT); - char *options; - int i; - - astAt( "AST_ZOOMMAP", NULL, 0 ); - astWatchSTATUS( - options = astString( OPTIONS, OPTIONS_length ); - -/* Truncate the options string to exlucde any trailing spaces. */ - astChrTrunc( options ); - -/* Change ',' to '\n' (see AST_SET in fobject.c for why). */ - if ( astOK ) { - for ( i = 0; options[ i ]; i++ ) { - if ( options[ i ] == ',' ) options[ i ] = '\n'; - } - } - RESULT = astP2I( astZoomMap( *NAXES, *ZOOM, "%s", options ) ); - astFree( options ); - ) - return RESULT; -} diff --git a/ast/getatt b/ast/getatt deleted file mode 100755 index fb8bc78..0000000 --- a/ast/getatt +++ /dev/null @@ -1,163 +0,0 @@ -#! /usr/bin/env perl -# This script requires that Perl be in the path, and that the -# environment variable SST_DIR be set to the location of the prolat -# binary. - - $C = 1; - $fortran = 0; - $prologue = 0; - $name = ""; - $name_section = 0; - $key = ""; - $unix_script = 0; - $cmt = quotemeta( "*" ); - -# Read switches. - while ( $_ = $ARGV[0], /^-/ ) { - shift; - last if /^--$/; - if ( /^-f/ ) { $fortran = 1; $C = 0; }; - if ( /^-u/ ) { $unix_script = 1; $cmt = quotemeta( "#" ); }; - if ( /^-att/ ) { $key = "att" }; - if ( /^-class/ ) { $key = "class" }; - } - -# Set up pattern for matching language-dependent lines. - $language_symbol = "c"; - if ( $fortran ) { $language_symbol = "f"; } - if ( $unix_script ) { - $lang = $cmt . "[fc]"; - $thislang = quotemeta( "#" . $language_symbol ); - } else { - $lang = "[fc]"; - $thislang = quotemeta( $language_symbol ); - } - -# Read input lines. - line: while (<>) { - -# Skip language-specific lines that aren't wanted. - if ( /^$lang/ ) { - next line if ( !/^$thislang/ ); - -# Put "*" in first column. - s/^$thislang/\*/; - } - -# Detect end of prologue. - if ( /^$cmt$key--/o ) { - $prologue = 0; - -# Append "*-" to prologue text and save the whole prologue as an element -# in the "pro" associative array. - $pro{ $name } = $text . "*-\n"; - -# Clear the name ready for next prologue. - $name = ""; - } - -# Process the prologue contents. - if ( $prologue ) { - -# Remove trailing blanks. - s/ *$//; - -# Convert/remove sections that don't appear in external documentation. - if ( $unix_script ) { - ; - } elsif ( !$key && $C ) { - s/^($cmt *)Synopsis:$/$1Invocation:/; - s/^($cmt *)Parameters:$/$1Arguments:/; - } elsif ( !$key && $fortran ) { - s/^($cmt *)Synopsis:$/$1Invocation:/; - s/^($cmt *)Parameters:$/$1Arguments:/; - } elsif ( $key =~ /att/ ) { - s/^($cmt *)Synopsis:$/$1Invocation:/; - } elsif ( $key =~ /class/ ) { - s/^($cmt *)Constructor Function:$/$1Invocation:/; - } - -# Skip the contents of these sections... - if ( /^$cmt *Type:$/ || - /^$cmt *Class Membership:$/ || - /^$cmt *Copyright:$/ ) { - while ( <> ) { if ( /^ *$/ ) { next line } }; - } - -# Remove any #include directives from the C Synopsis (Invocation) section. - if ( !$key && $C && !$unix_script ) { - if ( /^$cmt *Invocation:$/ ) { - while ( <> && /^$cmt *#include/ ) {}; - } - } - -# If in the "Name:" section, search for the routine name, noting when -# found. - if ( $name_section && ( ( $name ) = /^. *([^ ]*) *$/ ) ) { - $name_section = 0; - }; - -# Detect the "Name:" line itself. - if ( /^$cmt *Name:$/ ) { $name_section = 1 }; - -# Change to use the standard comment character "*". - s/^$cmt/\*/; - -# Append each prologue line to the end of the prologue text. - $text = $text . $_; - } - -# Detect start of prologue and initialise prologue text. - if ( /^$cmt$key\+\+/o ) { - $prologue = 1; - $name_section = 0; - $text = "*+\n"; - }; - } - -# Output prologues in alphabetical order to a scratch file. - open( TEMP, '>/tmp/getatt' ); - foreach $name ( sort( keys( %pro ) ) ) { print( TEMP $pro{ $name } ); } - close( TEMP ); - -# Write the names to a log file, escaping special (to Latex) characters. - open( NAMES, '>getatt.labels' ); - foreach $name ( sort( keys( %pro ) ) ) { - $name =~ s/_/\\_/g; - $name =~ s/\>/\$\>\$/g; - $name =~ s/\ ) { - if ( $unix_script ) { - ; - } elsif ( !$key && $C ) { - s/\\sstinvocation{/\\sstsynopsis{/; - s/\\sstarguments{/\\sstparameters{/; - } elsif ( $key =~ /att/ ) { - s/\\sstinvocation{/\\sstattributetype{/; - } elsif ( $key =~ /class/ ) { - s/\\sstinvocation{/\\sstconstructor{/; - } - -# Fix up constructs that don't otherwise convert to HTML properly. - s/{\\tt \'}/'/g; - s/{\\tt \"}/{\\tt{\"}}/g; - print; - } - close( LATEX ); - -# Delete the output file from PROLAT. - print( STDERR `rm -f /tmp/prolat.tex` ); diff --git a/ast/getnewversion b/ast/getnewversion deleted file mode 100644 index b05f6d0..0000000 --- a/ast/getnewversion +++ /dev/null @@ -1,15 +0,0 @@ - -# Prompt for new AST version number and store in "version.number" -# file in repository. Don't prompt if $AST_VERSION already specifies -# a version to use (just store the new value in the file). -version="${AST_VERSION}" -if test ! -n "${version}"; then - old_version="`cat ./version.number`" - echo; - echo "Always include a release number !!! (e.g. \"2.0-1\")" - echo -n "New version number /${old_version}/ > " - read version; - echo; - if test ! -n "${version}"; then version="${old_version}"; fi -fi -echo "${version}" >version.number diff --git a/ast/globals.c b/ast/globals.c deleted file mode 100644 index 8f43a9a..0000000 --- a/ast/globals.c +++ /dev/null @@ -1,253 +0,0 @@ -#if defined( THREAD_SAFE ) - -#define astCLASS - -#include "globals.h" -#include "error.h" -#include -#include -#include - -/* Configuration results. */ -/* ---------------------- */ -#if HAVE_CONFIG_H -#include -#endif - -/* Select the appropriate memory management functions. These will be the - system's malloc, free and realloc unless AST was configured with the - "--with-starmem" option, in which case they will be the starmem - malloc, free and realloc. */ -#ifdef HAVE_STAR_MEM_H -# include -# define MALLOC starMalloc -# define FREE starFree -# define REALLOC starRealloc -#else -# define MALLOC malloc -# define FREE free -# define REALLOC realloc -#endif - -/* Module variables */ -/* ================ */ - -/* A count of the number of thread-specific data structures created so - far. Create a mutex to serialise access to this static variable. */ -static int nthread = 0; -static pthread_mutex_t nthread_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* External variables visible throughout AST */ -/* ========================================= */ - -/* Set a flag indicating that the thread-specific data key has not yet - been created. */ -pthread_once_t starlink_ast_globals_initialised = PTHREAD_ONCE_INIT; - -/* Declare the pthreads key that will be associated with the thread-specific - data for each thread. */ -pthread_key_t starlink_ast_globals_key; - -/* Declare the pthreads key that will be associated with the thread-specific - status value for each thread. */ -pthread_key_t starlink_ast_status_key; - - -/* Function definitions: */ -/* ===================== */ - - -void astGlobalsCreateKey_( void ) { -/* -*+ -* Name: -* astGlobalsCreateKey_ - -* Purpose: -* Create the thread specific data key used for accessing global data. - -* Type: -* Protected function. - -* Synopsis: -* #include "globals.h" -* astGlobalsCreateKey_() - -* Description: -* This function creates the thread-specific data key. It is called -* once only by the pthread_once function, which is invoked via the -* astGET_GLOBALS(this) macro by each AST function that requires access to -* global data. - -* Returned Value: -* Zero for success. - -*- -*/ - -/* Create the key used to access thread-specific global data values. - Report an error if it fails. */ - if( pthread_key_create( &starlink_ast_globals_key, NULL ) ) { - fprintf( stderr, "ast: Failed to create Thread-Specific Data key" ); - -/* If succesful, create the key used to access the thread-specific status - value. Report an error if it fails. */ - } else if( pthread_key_create( &starlink_ast_status_key, NULL ) ) { - fprintf( stderr, "ast: Failed to create Thread-Specific Status key" ); - - } - -} - -AstGlobals *astGlobalsInit_( void ) { -/* -*+ -* Name: -* astGlobalsInit - -* Purpose: -* Create and initialise a structure holding thread-specific global -* data values. - -* Type: -* Protected function. - -* Synopsis: -* #include "globals.h" -* AstGlobals *astGlobalsInit; - -* Description: -* This function allocates memory to hold thread-specific global data -* for use throughout AST, and initialises it. - -* Returned Value: -* Pointer to the structure holding global data values for the -* currently executing thread. - -*- -*/ - -/* Local Variables: */ - AstGlobals *globals; - AstStatusBlock *status; - -/* Allocate memory to hold the global data values for the currently - executing thread. Use malloc rather than astMalloc (the AST memory - module uses global data managed by this module and so using astMalloc - could put us into an infinite loop). */ - globals = MALLOC( sizeof( AstGlobals ) ); - - if ( !globals ){ - fprintf( stderr, "ast: Failed to allocate memory to hold AST " - "global data values" ); - -/* Initialise the global data values. */ - } else { - -/* Each thread has a unique integer identifier. */ - pthread_mutex_lock( &nthread_mutex ); - globals->thread_identifier = nthread++; - pthread_mutex_unlock( &nthread_mutex ); - -#define INIT(class) astInit##class##Globals_( &(globals->class) ); - INIT( Error ); - INIT( Memory ); - INIT( Object ); - INIT( Axis ); - INIT( Mapping ); - INIT( Frame ); - INIT( Channel ); - INIT( CmpMap ); - INIT( KeyMap ); - INIT( FitsChan ); - INIT( FitsTable ); - INIT( CmpFrame ); - INIT( DSBSpecFrame ); - INIT( FrameSet ); - INIT( LutMap ); - INIT( MathMap ); - INIT( PcdMap ); - INIT( PointSet ); - INIT( SkyAxis ); - INIT( SkyFrame ); - INIT( SlaMap ); - INIT( SpecFrame ); - INIT( SphMap ); - INIT( TimeFrame ); - INIT( WcsMap ); - INIT( ZoomMap ); - INIT( FluxFrame ); - INIT( SpecFluxFrame ); - INIT( GrismMap ); - INIT( IntraMap ); - INIT( Plot ); - INIT( Plot3D ); - INIT( Region ); - INIT( Xml ); - INIT( XmlChan ); - INIT( Box ); - INIT( Circle ); - INIT( CmpRegion ); - INIT( DssMap ); - INIT( Ellipse ); - INIT( Interval ); - INIT( MatrixMap ); - INIT( NormMap ); - INIT( NullRegion ); - INIT( PermMap ); - INIT( PointList ); - INIT( PolyMap ); - INIT( ChebyMap ); - INIT( Polygon ); - INIT( Prism ); - INIT( RateMap ); - INIT( SelectorMap ); - INIT( ShiftMap ); - INIT( SpecMap ); - INIT( Stc ); - INIT( StcCatalogEntryLocation ); - INIT( StcObsDataLocation ); - INIT( SwitchMap ); - INIT( Table ); - INIT( TimeMap ); - INIT( TranMap ); - INIT( UnitMap ); - INIT( UnitNormMap ); - INIT( WinMap ); - INIT( StcResourceProfile ); - INIT( StcSearchLocation ); - INIT( StcsChan ); -#undef INIT - -/* Save the pointer as the value of the starlink_ast_globals_key - thread-specific data key. */ - if( pthread_setspecific( starlink_ast_globals_key, globals ) ) { - fprintf( stderr, "ast: Failed to store Thread-Specific Data pointer." ); - -/* We also take this opportunity to allocate and initialise the - thread-specific status value. */ - } else { - status = MALLOC( sizeof( AstStatusBlock ) ); - if( status ) { - status->internal_status = 0; - status->status_ptr = &( status->internal_status ); - -/* If succesful, store the pointer to this memory as the value of the - status key for the currently executing thread. Report an error if - this fails. */ - if( pthread_setspecific( starlink_ast_status_key, status ) ) { - fprintf( stderr, "ast: Failed to store Thread-Specific Status pointer." ); - } - - } else { - fprintf( stderr, "ast: Failed to allocate memory for Thread-Specific Status pointer." ); - } - } - } - -/* Return a pointer to the data structure holding the global data values. */ - return globals; -} - -#endif - diff --git a/ast/globals.h b/ast/globals.h deleted file mode 100644 index 11fbd6b..0000000 --- a/ast/globals.h +++ /dev/null @@ -1,247 +0,0 @@ -#if !defined( GLOBALS_INCLUDED ) /* Include this file only once */ -#define GLOBALS_INCLUDED 1 - -/* If thread-safety is required... */ -#if defined( THREAD_SAFE ) && ( defined( astCLASS ) || defined( astFORTRAN77) ) - -/* Include files: */ -/* ============== */ - -/* AST includes */ -#include "axis.h" -#include "box.h" -#include "channel.h" -#include "chebymap.h" -#include "circle.h" -#include "cmpframe.h" -#include "cmpmap.h" -#include "cmpregion.h" -#include "dsbspecframe.h" -#include "dssmap.h" -#include "ellipse.h" -#include "error.h" -#include "fitschan.h" -#include "fitstable.h" -#include "fluxframe.h" -#include "frame.h" -#include "frameset.h" -#include "grismmap.h" -#include "interval.h" -#include "intramap.h" -#include "keymap.h" -#include "lutmap.h" -#include "mapping.h" -#include "mathmap.h" -#include "matrixmap.h" -#include "memory.h" -#include "normmap.h" -#include "nullregion.h" -#include "object.h" -#include "pcdmap.h" -#include "permmap.h" -#include "plot.h" -#include "plot3d.h" -#include "pointlist.h" -#include "pointset.h" -#include "polygon.h" -#include "polymap.h" -#include "prism.h" -#include "ratemap.h" -#include "region.h" -#include "selectormap.h" -#include "shiftmap.h" -#include "skyaxis.h" -#include "skyframe.h" -#include "slamap.h" -#include "specfluxframe.h" -#include "specframe.h" -#include "specmap.h" -#include "sphmap.h" -#include "stc.h" -#include "stccatalogentrylocation.h" -#include "stcobsdatalocation.h" -#include "stcresourceprofile.h" -#include "stcsearchlocation.h" -#include "stcschan.h" -#include "switchmap.h" -#include "table.h" -#include "timeframe.h" -#include "timemap.h" -#include "tranmap.h" -#include "unitmap.h" -#include "unitnormmap.h" -#include "wcsmap.h" -#include "winmap.h" -#include "xml.h" -#include "xmlchan.h" -#include "zoommap.h" - - - -/* System includes */ -#include - -/* Macros */ -/* ====== */ - -/* The name of the variable used to access thread-specific global data */ -#define AST__GLOBALS ast_globals - -/* Defines a macro that gives access to a specific global data item. */ -#define astGLOBAL(class,name) (AST__GLOBALS->class.name) - - -/* Declares the pointer for the structure holding thread-specific values - for AST global data. */ -#define astDECLARE_GLOBALS AstGlobals *AST__GLOBALS; - - -/* A macro that should be invoked in each function that refers to a - global data item. The "This" parameter should be a pointer to an - Object, or NULL. It ensures the thread-specific data key has been - created. It also allocates and initialises memory to hold the global - data. */ -#define astGET_GLOBALS(This) \ -\ -/* If the supplied Object pointer contains a pointer to the thread-specific \ - data structure, return it. */ \ - if( This && ((AstObject *)This)->globals ) { \ - AST__GLOBALS = ((AstObject *)This)->globals; \ -\ -/* Otherwise, ensure that the thread specific data key has been created. */ \ - } else if( pthread_once( &starlink_ast_globals_initialised, \ - astGlobalsCreateKey_ ) ) { \ - AST__GLOBALS = NULL; \ - fprintf( stderr, "Starlink AST package initialisation failed." ); \ -\ -/* If the current thread does not yet have a structure to hold \ - thread-specific global data, create one now (initialising its \ - contents) and associate it with the thread speciifc data key. */ \ - } else if( ( AST__GLOBALS = \ - pthread_getspecific( starlink_ast_globals_key ) ) == NULL ) { \ - AST__GLOBALS = astGlobalsInit_(); \ - if( pthread_setspecific( starlink_ast_globals_key, AST__GLOBALS ) ) { \ - fprintf( stderr, "Starlink AST failed to store Thread-Specific " \ - "Data pointer." ); \ - } \ - } - - -/* A macro that expands to the value of a unique integer identifier for - the calling thread. */ -#define AST__THREAD_ID (AST__GLOBALS->thread_identifier) \ - - -#define astMAKE_INITGLOBALS(class) \ -\ -void astInit##class##Globals_( Ast##class##Globals *globals ){ \ - GLOBAL_inits \ -} - -/* Type definitions */ -/* ================ */ - -typedef struct AstGlobals { - int thread_identifier; - AstMemoryGlobals Memory; - AstErrorGlobals Error; - AstObjectGlobals Object; - AstAxisGlobals Axis; - AstMappingGlobals Mapping; - AstFrameGlobals Frame; - AstChannelGlobals Channel; - AstCmpMapGlobals CmpMap; - AstKeyMapGlobals KeyMap; - AstFitsChanGlobals FitsChan; - AstFitsTableGlobals FitsTable; - AstCmpFrameGlobals CmpFrame; - AstDSBSpecFrameGlobals DSBSpecFrame; - AstFrameSetGlobals FrameSet; - AstLutMapGlobals LutMap; - AstMathMapGlobals MathMap; - AstPcdMapGlobals PcdMap; - AstPointSetGlobals PointSet; - AstSkyAxisGlobals SkyAxis; - AstSkyFrameGlobals SkyFrame; - AstSlaMapGlobals SlaMap; - AstSpecFrameGlobals SpecFrame; - AstSphMapGlobals SphMap; - AstTimeFrameGlobals TimeFrame; - AstWcsMapGlobals WcsMap; - AstZoomMapGlobals ZoomMap; - AstFluxFrameGlobals FluxFrame; - AstSpecFluxFrameGlobals SpecFluxFrame; - AstGrismMapGlobals GrismMap; - AstIntraMapGlobals IntraMap; - AstPlotGlobals Plot; - AstPlot3DGlobals Plot3D; - AstRegionGlobals Region; - AstBoxGlobals Box; - AstXmlGlobals Xml; - AstXmlChanGlobals XmlChan; - AstCircleGlobals Circle; - AstCmpRegionGlobals CmpRegion; - AstDssMapGlobals DssMap; - AstEllipseGlobals Ellipse; - AstIntervalGlobals Interval; - AstMatrixMapGlobals MatrixMap; - AstNormMapGlobals NormMap; - AstNullRegionGlobals NullRegion; - AstPermMapGlobals PermMap; - AstPointListGlobals PointList; - AstPolyMapGlobals PolyMap; - AstChebyMapGlobals ChebyMap; - AstPolygonGlobals Polygon; - AstPrismGlobals Prism; - AstRateMapGlobals RateMap; - AstSelectorMapGlobals SelectorMap; - AstShiftMapGlobals ShiftMap; - AstSpecMapGlobals SpecMap; - AstStcGlobals Stc; - AstStcCatalogEntryLocationGlobals StcCatalogEntryLocation; - AstStcObsDataLocationGlobals StcObsDataLocation; - AstSwitchMapGlobals SwitchMap; - AstTableGlobals Table; - AstTimeMapGlobals TimeMap; - AstTranMapGlobals TranMap; - AstUnitMapGlobals UnitMap; - AstUnitNormMapGlobals UnitNormMap; - AstWinMapGlobals WinMap; - AstStcResourceProfileGlobals StcResourceProfile; - AstStcSearchLocationGlobals StcSearchLocation; - AstStcsChanGlobals StcsChan; -} AstGlobals; - - -/* Externally declared variables */ -/* ============================= */ - - -/* The pthreads key that is associated with the thread-specific data for - each thread. Declared in global.c. */ -extern pthread_key_t starlink_ast_globals_key; - -/* The pthreads key that is associated with the thread-specific status - value for each thread. Declared in global.c. */ -extern pthread_key_t starlink_ast_status_key; - -/* This is a flag indicating that the thread-specific data key has not yet - been created. Declared in globals.c. */ -extern pthread_once_t starlink_ast_globals_initialised; - -/* Function Prototypes: */ -/* ==================== */ - -void astGlobalsCreateKey_( void ); -AstGlobals *astGlobalsInit_( void ); - - -/* If thread-safety is not required, define some null macros. */ -#else - -#define astDECLARE_GLOBALS -#define astGET_GLOBALS(This) -#define astINIT_GLOBALS - -#endif -#endif diff --git a/ast/grf.h b/ast/grf.h deleted file mode 100644 index 04294f3..0000000 --- a/ast/grf.h +++ /dev/null @@ -1,110 +0,0 @@ -#if !defined( GRF_INCLUDED ) /* Include this file only once */ -#define GRF_INCLUDED -/* -*+ -* Name: -* grf.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the grf module - -* Invocation: -* #include "grf.h" - -* Description: -* This include file defines the interface to the grf module and -* provides the type definitions, function prototypes and macros, etc. -* needed to use this module. - -* Inheritance: -* The grf module is not a class and does not inherit. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 27-JUN-1996 (DSB): -* Original version. -* 25-OCT-1996 (DSB): -* Primatives macros defined, extra parameter added to astGAttr. -* 17-FEB-2006 (DSB): -* Added GRF__ESH and GRF__ESG. -*- -*/ - -/* Constant Values. */ -/* ================ */ -/* Values identifying different graphics attributes. */ -#define GRF__STYLE 0 -#define GRF__WIDTH 1 -#define GRF__SIZE 2 -#define GRF__FONT 3 -#define GRF__COLOUR 4 - -/* Values identifying different graphics primatives. */ -#define GRF__TEXT 0 -#define GRF__LINE 1 -#define GRF__MARK 2 - -/* The number of different graphics attributes */ -#define GRF__NATTR 5 - -/* Values identifying capabilities */ -#define GRF__ESC 0 -#define GRF__MJUST 1 -#define GRF__SCALES 2 - -/* Values identifying types of graphics escape sequence */ -#define GRF__ESPER 1 -#define GRF__ESSUP 2 -#define GRF__ESSUB 3 -#define GRF__ESGAP 4 -#define GRF__ESBAC 5 -#define GRF__ESSIZ 6 -#define GRF__ESWID 7 -#define GRF__ESFON 8 -#define GRF__ESCOL 9 -#define GRF__ESSTY 10 -#define GRF__ESPOP 11 -#define GRF__ESPSH 12 -#define GRF__ESH 13 -#define GRF__ESG 14 - -/* Function prototypes. */ -/* ==================== */ -int astGAttr( int, double, double *, int ); -int astGScales( float *, float * ); -int astGBBuf( void ); -int astGEBuf( void ); -int astGFlush( void ); -int astGLine( int, const float *, const float * ); -int astGMark( int, const float *, const float *, int ); -int astGQch( float *, float * ); -int astGText( const char *, float, float, const char *, float, float ); -int astGTxExt( const char *, float, float, const char *, float, float, float *, float * ); -int astGCap( int, int ); - -#endif diff --git a/ast/grf3d.c b/ast/grf3d.c deleted file mode 100644 index c0c1a33..0000000 --- a/ast/grf3d.c +++ /dev/null @@ -1,102 +0,0 @@ -/* -* Name: -* grf3d.c - -* Purpose: -* Implement the grf3D interface if no graphics system is available. - -* Description: -* This file implements the low level 3D graphics functions required -* by the rest of AST. These implementations simply report an error -* when called. - -* Inheritance: -* This module is not a class and does not inherit. - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (JACH - UCLan) - -* History: -* 20-JUN-2007 (DSB): -* Original version. -*/ - -/* Header files */ -/* ============ */ -#include "grf3d.h" /* Declare the functions in this module */ -#include "error.h" /* AST error reporting facilities */ -#include "ast_err.h" /* AST error codes */ - -/* Function Prototypes */ -/* =================== */ -static void Report( const char * ); - -/* Function definitions */ -/* ==================== */ -int astG3DCap( int cap, int value ){ - return 0; -} - -int astG3DFlush( void ){ - Report( "astG3DFlush"); - return 0; -} - -int astG3DLine( int n, float *x, float *y, float *z ){ - Report( "astG3DLine" ); - return 0; -} - -int astG3DQch( float *ch ){ - Report( "astG3DQch" ); - return 0; -} - -int astG3DMark( int n, float *x, float *y, float *z, int type, float norm[3] ){ - Report( "astG3DMark" ); - return 0; -} - -int astG3DText( const char *text, float ref[3], const char *just, - float up[3], float norm[3] ){ - Report( "astG3DText" ); - return 0; -} - -int astG3DTxExt( const char *text, float ref[3], const char *just, - float up[3], float norm[3], float *xb, float *yb, - float *zb, float bl[3] ){ - Report( "astG3DTxExt" ); - return 0; -} - -int astG3DAttr( int attr, double value, double *old_value, int prim ){ - Report( "astG3DAttr" ); - return 0; -} - -static void Report( const char *name ){ - astError( AST__GRFER, "%s: No graphics facilities are available.", name ); - astError( AST__GRFER, "Re-link using an option such as '-pgplot' with " - "the ast_link script." ); -} diff --git a/ast/grf3d.h b/ast/grf3d.h deleted file mode 100644 index 6ab7195..0000000 --- a/ast/grf3d.h +++ /dev/null @@ -1,69 +0,0 @@ -#if !defined( GRF3D_INCLUDED ) /* Include this file only once */ -#define GRF3D_INCLUDED -/* -*+ -* Name: -* grf3d.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the grf3d module - -* Invocation: -* #include "grf3d.h" - -* Description: -* This include file defines the interface to the grf3d module and -* provides the type definitions, function prototypes and macros, etc. -* needed to use this module. - -* Inheritance: -* The grf3d module is not a class and does not inherit. - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (JACH - UCLan) - -* History: -* 20-JUN-2007 (DSB): -* Original version. -*- -*/ - -/* Include the 2D grf header file in order to inherit the GRF__ macros. */ -#include "grf.h" - -/* Function prototypes. */ -/* ==================== */ -int astG3DAttr( int, double, double *, int ); -int astG3DCap( int, int ); -int astG3DFlush( void ); -int astG3DLine( int, float *, float *, float * ); -int astG3DMark( int, float *, float *, float *, int, float[3] ); -int astG3DQch( float * ); -int astG3DText( const char *, float[3], const char *, float[3], float[3] ); -int astG3DTxExt( const char *, float[3], const char *, float[3], float[3], float *, float *, float *, float[3] ); - - -#endif diff --git a/ast/grf3d_pgplot.c b/ast/grf3d_pgplot.c deleted file mode 100644 index ab25085..0000000 --- a/ast/grf3d_pgplot.c +++ /dev/null @@ -1,3196 +0,0 @@ -/* -* Name: -* grf3d_pgplot.c - -* Purpose: -* Implement the grf3d interface using the PGPLOT graphics system. - -* Description: -* This file implements the low level 3D graphics functions required -* by the rest of AST, by calling suitable PGPLOT functions (the -* FORTRAN PGPLOT interface is used). -* -* This file can be used as a template for the development of -* similar implementations based on other graphics systems. -* -* Unlike world coordinates used by the 2D grf interface, the 3D world -* coordinates used by the grf3D interface are assume to be equally scaled -* (that is, they are assumed to have the same units). Therefore this -* module has no equivalent to the astGScales function defined by the -* 2D grf interface. - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 20-JUN-2007 (DSB): -* Original version. -*/ - - -/* Macros */ -/* ====== */ -#define MXDEV 16 /* Max no of concurrent PGPLOT devices */ -#define MXSTRLEN 80 /* Max PGPLOT string length */ -#define CAMERA_OK 123456789 /* Flags that a Camera has been initialised */ -#define TWOPI 6.28318530718 /* 2*PI */ -#define MXSIDE 32 /* Max no of sides in a marker polygon */ - - -/* Header files. */ -/* ============= */ -/* AST header files */ -#include "grf3d.h" /* The grf3D interface definition */ -#include "pg3d.h" /* Other public functions in this module */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* C to FORTRAN interface functions */ -#include "memory.h" /* Memory allocation facilities */ -#include "error.h" /* Error reporting facilities */ -#include "pointset.h" /* Defines AST__BAD */ -#include "ast_err.h" /* AST error codes */ - -/* System header files */ -#include -#include -#include -#include -#include - - -/* Type definitions. */ -/* ================= */ -/* Structure defining the position and orientation of the camera in 3D - world coords. This is specific to the PGPLOT implementation. Other - implementations need not include any equivalent to this structure. */ -typedef struct camera { - float eye_vector[3]; - float target_vector[3]; - float up_vector[3]; - float w2c_matrix[9]; - float screen_distance; - int ok_flag; -} Camera; - - -/* Module variables. */ -/* ================= */ -/* One camera structure for each PGPLOT device identifier. PGPLOT allows - a maximum of 8 concurrent devices at the moment. Make the array twice - this size to allow for some future expansion in PGPLOT. Again, this is - specific to the PGPLOT implementation of the grf3D interface. */ -static Camera cameras[ MXDEV ]; - -/* Function templates. */ -/* =================== */ -/* Templates for functions that are private to this module. */ -static Camera *getCamera( int ); -static float getCharHeight( void ); -static int Polygon( int, float *, float *, float *, float[3], float[3], float[3], float[3] ); -static int Text( int *, int, float[3], const char *, float[3], float[3], float[3] ); -static int TextCam( Camera *, float[3], float[3], float[3], float[3] ); -static int TxExt( int *, int, float[3], const char *, float[3], float[3], float[3], float *, float *, float *, float[3] ); -static int getTextAxes( float[3], float[3], float[3], const char *, float[3], float[3], float[3], char[3] ); -static int transform( Camera *, int, float *, float *, float *, float *, float * ); -static int vectorNorm( float * ); -static float vectorModulus( float * ); -static void getSymbolList( const char *, int, int *, int * ); -static void vectorProduct( float *, float *, float * ); -static float dotProduct( float *, float * ); -static void vectorSub( float *, float *, float * ); - -/* Templates for private functions that wrap PGPLOT Fortran routines. */ -static void ccgrsyds( int *, int *, const char *, int, int ); -static void ccgrsymk( int, int, int * ); -static void ccgrsyxd( int, int *, int * ); -static void ccpgline( int, float[], float[] ); -static void ccpgpoly( int, float[], float[] ); -static void ccpgqcf( int * ); -static void ccpgqcf(int *); -static void ccpgqch( float * ); -static void ccpgqci( int * ); -static void ccpgqclp( int * ); -static void ccpgqid( int * ); -static void ccpgqls( int * ); -static void ccpgqlw( int * ); -static void ccpgqvsz( int, float *, float *, float *, float * ); -static void ccpgqwin( float *, float *, float *, float * ); -static void ccpgscf( int ); -static void ccpgsch( float ); -static void ccpgsci( int ); -static void ccpgsclp( int ); -static void ccpgsls( int ); -static void ccpgslw( int ); -static void ccpgswin( float, float, float, float ); -static void ccpgupdt( void ); - - -/* Templates for Fortran PGPLOT routines needed by this module. */ -F77_SUBROUTINE(grsyds)( INTEGER_ARRAY(list), INTEGER(nlist), CHARACTER(text), INTEGER(font) TRAIL(text) ); -F77_SUBROUTINE(grsymk)( INTEGER(type), INTEGER(font), INTEGER(symbol) ); -F77_SUBROUTINE(grsyxd)( INTEGER(symbol), INTEGER_ARRAY(xygrid), INTEGER(unused) ); -F77_SUBROUTINE(pgline)( INTEGER(N), REAL_ARRAY(X), REAL_ARRAY(Y) ); -F77_SUBROUTINE(pgpoly)( INTEGER(N), REAL_ARRAY(X), REAL_ARRAY(Y) ); -F77_SUBROUTINE(pgqcf)( INTEGER(ival) ); -F77_SUBROUTINE(pgqch)( REAL(rval) ); -F77_SUBROUTINE(pgqci)( INTEGER(ival) ); -F77_SUBROUTINE(pgqclp)( INTEGER(clip) ); -F77_SUBROUTINE(pgqid)( INTEGER(id) ); -F77_SUBROUTINE(pgqls)( INTEGER(ival) ); -F77_SUBROUTINE(pgqlw)( INTEGER(ival) ); -F77_SUBROUTINE(pgqvsz)( INTEGER(units), REAL(x1), REAL(x2), REAL(y1), REAL(y2) ); -F77_SUBROUTINE(pgqwin)( REAL(wx1), REAL(wx2), REAL(wy1), REAL(wy2) ); -F77_SUBROUTINE(pgscf)( INTEGER(ival) ); -F77_SUBROUTINE(pgsch)( REAL(rval) ); -F77_SUBROUTINE(pgsci)( INTEGER(ival) ); -F77_SUBROUTINE(pgsclp)( INTEGER(clip) ); -F77_SUBROUTINE(pgsls)( INTEGER(ival) ); -F77_SUBROUTINE(pgslw)( INTEGER(ival) ); -F77_SUBROUTINE(pgswin)( REAL(X1), REAL(X2), REAL(Y1), REAL(Y2) ); -F77_SUBROUTINE(pgupdt)( void ); - - -/* Public functions defined by the grf3D interface. */ -/* ================================================ */ -/* All implementations of the grf3d interface must provide implementations - of all the functions in this block. The corresponding templates are in - grf3d.h */ - - -int astG3DAttr( int attr, double value, double *old_value, int prim ){ -/* -*+ -* Name: -* astG3DAttr - -* Purpose: -* Enquire or set a 3D graphics attribute value. - -* Synopsis: -* #include "grf3d.h" -* int int astG3DAttr( int attr, double value, double *old_value, int prim ) - -* Description: -* This function returns the current value of a specified 3D graphics -* attribute, and optionally establishes a new value. The supplied -* value is converted to an integer value if necessary before use. - -* Parameters: -* attr -* An integer value identifying the required attribute. The -* following symbolic values are defined in grf3d.h: -* -* GRF__STYLE - Line style. -* GRF__WIDTH - Line width. -* GRF__SIZE - Character and marker size scale factor. -* GRF__FONT - Character font. -* GRF__COLOUR - Colour index. -* value -* A new value to store for the attribute. If this is AST__BAD -* no value is stored. -* old_value -* A pointer to a double in which to return the attribute value. -* If this is NULL, no value is returned. -* prim -* The sort of graphics primitive to be drawn with the new attribute. -* Identified by the following values defined in grf.h: -* GRF__LINE -* GRF__MARK -* GRF__TEXT - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: - -*- -*/ - - int ival; - float rval, dx, dy, deflw, x1, x2, y1, y2; - -/* If required retrieve the current line style, and set a new line style. */ - if( attr == GRF__STYLE ){ - ccpgqls( &ival ); - if( old_value ) *old_value = (double) ival; - - if( value != AST__BAD ){ - ival = (int) ( value + 0.5 ); - if( value < 0.0 ) ival -= 1; - - ival = ( ival - 1 ) % 5; - ival += ( ival < 0 ) ? 6 : 1; - - ccpgsls( ival ); - } - -/* If required retrieve the current line width, and set a new line width. - Line width is stored in Plot as a scale factor (1.0 for the default line - width which is a fixed fraction of the diagonal of the view surface), but - pgplot stores it in units of 0.005 of an inch. */ - } else if( attr == GRF__WIDTH ){ - -/* Get the bounds of the view surface in inches. */ - ccpgqvsz( 1, &x1, &x2, &y1, &y2 ); - -/* Find the default line width in inches (i.e. 0.0005 of the length - of the view surface diagonal). */ - dx = ( x1 - x2 ); - dy = ( y1 - y2 ); - deflw = 0.0005*sqrt( (double )( dx*dx + dy*dy ) ); - -/* Get the current pgplot line width in units of 0.005 of an inch. */ - ccpgqlw( &ival ); - -/* If required, return the factor by which this exceeds the default line - width found above. */ - if( old_value ) *old_value = (double)( ival )/( 200.0 * deflw ); - -/* If a new line width has been provided, the pgplot line width needs to - be set to the corresponding absolute value. */ - if( value != AST__BAD ){ - ival = (int) ( 200.0*value*deflw ); - if( ival < 1 ) { - ival = 1; - } else if( ival > 201 ){ - ival = 201; - } - ccpgslw( ival ); - } - -/* If required retrieve the current character size, and set a new size. - The attribute value should be a factor by which to multiply the - default character size. */ - } else if( attr == GRF__SIZE ){ - ccpgqch( &rval ); - if( old_value ) *old_value = (double) rval; - - if( value != AST__BAD ){ - ccpgsch( (float) value ); - } - -/* If required retrieve the current character font, and set a new font. */ - } else if( attr == GRF__FONT ){ - ccpgqcf( &ival ); - if( old_value ) *old_value = (double) ival; - - if( value != AST__BAD ){ - ival = (int) ( value + 0.5 ); - if( value < 0.0 ) ival -= 1; - - ival = ( ival - 1 ) % 4; - ival += ( ival < 0 ) ? 5 : 1; - ccpgscf( ival ); - } - -/* If required retrieve the current colour index, and set a new colour - index. */ - } else if( attr == GRF__COLOUR ){ - ccpgqci( &ival ); - if( old_value ) *old_value = (double) ival; - - if( value != AST__BAD ){ - ival = (int) ( value + 0.5 ); - if( ival < 0 ) ival = 1; - ccpgsci( ival ); - } - -/* Give an error message for any other attribute value. */ - } else { - astError( AST__GRFER, "astG3DAttr: Unknown graphics attribute '%d' " - "requested.", attr ); - return 0; - } - -/* Return. */ - return 1; -} - -int astG3DCap( int cap, int value ){ -/* -*+ -* Name: -* astG3DCap - -* Purpose: -* Indicate if this grf3d module has a given capability. - -* Synopsis: -* #include "grf3d.h" -* int astG3DCap( int cap, int value ) - -* Description: -* This function is called by the AST Plot class to determine if the -* grf3d module has a given capability, as indicated by the "cap" -* argument. - -* Parameters: -* cap -* The capability being inquired about. This will be one of the -* following constants defined in grf3d.h: -* -* GRF3D__ESC: This function should return a non-zero value if the -* astG3DText and astG3DTxExt functions can recognise and interpret -* graphics escape sequences within the supplied string. These -* escape sequences are described below. Zero should be returned -* if escape sequences cannot be interpreted (in which case the -* Plot class will interpret them itself if needed). The supplied -* "value" argument should be ignored only if escape sequences cannot -* be interpreted by astG3DText and astG3DTxExt. Otherwise, "value" -* indicates whether astG3DText and astG3DTxExt should interpret escape -* sequences in subsequent calls. If "value" is non-zero then -* escape sequences should be interpreted by astG3DText and -* astG3DTxExt. Otherwise, they should be drawn as literal text. - -* Returned Value: -* The return value, as described above. Zero should be returned if -* the supplied capability is not recognised. - -* Escape Sequences: -* Escape sequences are introduced into the text string by a percent -* "%" character. The following escape sequences are currently recognised -* ("..." represents a string of one or more decimal digits): -* -* %% - Print a literal "%" character (type GRF__ESPER ). -* -* %^...+ - Draw subsequent characters as super-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the super-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text (type GRF__ESSUP ). -* %^+ - Draw subsequent characters with the normal base-line. -* -* %v...+ - Draw subsequent characters as sub-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the sub-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text (type GRF__ESSUB ). -* -* %v+ - Draw subsequent characters with the normal base-line -* (equivalent to %^+). -* -* %>...+ - Leave a gap before drawing subsequent characters. -* The digits "..." give the size of the gap, scaled -* so that a value of "100" corresponds to the height of -* "normal" text (type GRF__ESGAP ). -* -* %<...+ - Move backwards before drawing subsequent characters. -* The digits "..." give the size of the movement, scaled -* so that a value of "100" corresponds to the height of -* "normal" text (type GRF_ESBAC). -* -* %s...+ - Change the Size attribute for subsequent characters. The -* digits "..." give the new Size as a fraction of the -* "normal" Size, scaled so that a value of "100" corresponds -* to 1.0 (type GRF__ESSIZ ). -* -* %s+ - Reset the Size attribute to its "normal" value. -* -* %w...+ - Change the Width attribute for subsequent characters. The -* digits "..." give the new width as a fraction of the -* "normal" Width, scaled so that a value of "100" corresponds -* to 1.0 (type GRF__ESWID ). -* -* %w+ - Reset the Size attribute to its "normal" value. -* -* %f...+ - Change the Font attribute for subsequent characters. The -* digits "..." give the new Font value (type GRF__ESFON ). -* -* %f+ - Reset the Font attribute to its "normal" value. -* -* %c...+ - Change the Colour attribute for subsequent characters. The -* digits "..." give the new Colour value (type GRF__ESCOL ). -* -* %c+ - Reset the Colour attribute to its "normal" value. -* -* %t...+ - Change the Style attribute for subsequent characters. The -* digits "..." give the new Style value (type GRF__ESSTY ). -* -* %t+ - Reset the Style attribute to its "normal" value. -* -* %- - Push the current graphics attribute values onto the top of -* the stack - see "%+" (type GRF__ESPSH). -* -* %+ - Pop attributes values of the top the stack - see "%-". If -* the stack is empty, "normal" attribute values are restored -* (type GRF__ESPOP). -* -* The astFindEscape function (in libast.a) can be used to locate escape -* sequences within a text string. It has the following signature: -* -* #include "plot.h" -* int astFindEscape( const char *text, int *type, int *value, int *nc ) -* -* Parameters: -* text -* Pointer to the string to be checked. -* type -* Pointer to a location at which to return the type of escape -* sequence. Each type is identified by a symbolic constant defined -* in grf.h and is indicated in the above section. The returned value -* is undefined if the supplied text does not begin with an escape -* sequence. -* value -* Pointer to a lcation at which to return the integer value -* associated with the escape sequence. All usable values will be -* positive. Zero is returned if the escape sequence has no associated -* integer. A value of -1 indicates that the attribute identified by -* "type" should be reset to its "normal" value (as established using -* the astG3DAttr function, etc). The returned value is undefined if -* the supplied text does not begin with an escape sequence. -* nc -* Pointer to a location at which to return the number of -* characters read by this call. If the text starts with an escape -* sequence, the returned value will be the number of characters in -* the escape sequence. Otherwise, the returned value will be the -* number of characters prior to the first escape sequence, or the -* length of the supplied text if no escape sequence is found. - -* Returned Value: -* A non-zero value is returned if the supplied text starts with a -* graphics escape sequence, and zero is returned otherwise. - -*- -*/ - - return 0; -} - -int astG3DFlush( void ){ -/* -*+ -* Name: -* astG3DFlush - -* Purpose: -* Flush all pending graphics to the output device. - -* Synopsis: -* #include "grf3d.h" -* int astG3DFlush( void ) - -* Description: -* This function ensures that the display device is up-to-date, -* by flushing any pending graphics to the output device. - -* Parameters: -* None. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -*- -*/ - - ccpgupdt(); - return 1; -} - -int astG3DLine( int n, float *x, float *y, float *z ){ -/* -*+ -* Name: -* astG3DLine - -* Purpose: -* Draw a polyline (i.e. a set of connected lines). - -* Synopsis: -* #include "grf3d.h" -* int astG3DLine( int n, float *x, float *y, float *z ) - -* Description: -* This function displays lines joining the given positions. - -* Parameters: -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* z -* A pointer to an array holding the "n" z values. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - A camera must have been established prior to calling this -* function using either astG3DSetCamera or astG3DAutoCamera. -* - Nothing is done if "n" is less than 2, or if a NULL pointer is -* given for either "x", "y" or "z". - -*- -*/ - -/* Local Variables: */ - int clip; - int result = 0; - float *h, *r; - -/* Do nothing if we have less than 2 points, but do not indicate an error. */ - if( n < 2 ){ - result = 1; - -/* Check the pointers. */ - } else if( x && y && z ) { - -/* Save the current clipping flag, and ensure clipping is off. */ - ccpgqclp( &clip ); - ccpgsclp( 0 ); - -/* Allocate work space for the 2D world coordinate positions. */ - h = astMalloc( sizeof( float )*(size_t) n ); - r = astMalloc( sizeof( float )*(size_t) n ); - if( astOK ) { - -/* Convert the supplied points from 3D world coordinates to 2D world - (i.e. screen) coordinates. If succesful, plot the lines. */ - if( transform( NULL, n, x, y, z, h, r ) ) { - ccpgline( n, (float *) h, (float *) r ); - result = 1; - } - } - -/* Free work space. */ - h = astFree( h ); - r = astFree( r ); - -/* Re-instate original clipping flag. */ - ccpgsclp( clip ); - - } - return result; -} - -int astG3DMark( int n, float *x, float *y, float *z, int type, - float norm[3] ){ -/* -*+ -* Name: -* astG3DMark - -* Purpose: -* Draw a set of markers. - -* Synopsis: -* #include "grf.h" -* int astG3DMark( int n, float *x, float *y, float *z, int type, -* float norm[3] ) - -* Description: -* This function draws markers centred at the given positions, on a -* plane with a specified normal vector. - -* Parameters: -* n -* The number of markers to draw. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* z -* A pointer to an array holding the "n" z values. -* type -* An integer which can be used to indicate the type of marker symbol -* required. See the description of routine PGPT in the PGPLOT manual. -* norm -* The (x,y,z) components of a vector that is normal to the plane -* containing the marker. The given vector passes through the marker -* from the back to the front. If all components of this vector are -* zero, then a normal vector pointing from the position of the -* first marker towards the camera eye is used. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Nothing is done if "n" is less than 1, or if a NULL pointer is -* given for "x", "y" or "z". - -*- -*/ - -/* local Variables: */ - char just[3]; - float ref[3]; - float up[3]; - float tx[3], ty[3], tz[3]; - float vx[ MXSIDE ], vy[ MXSIDE ], vz[ MXSIDE ]; - float ch, ang, dang; - int clip; - int font; - int i; - int nlist; - int symnum; - int ns; - -/* Return if any of the coordinate pointers is NULL. */ - if( !x || !y || !z ) return 1; - -/* Initialise */ - ns = 0; - -/* Unless the "norm" vector is parallel to the z axis, we use an up vector - that is parallel to the z axis. Otherwise we use an up vector paralle - to the x axis. */ - if( norm[ 0 ] != 0.0 || norm[ 1 ] != 0.0 ) { - up[ 0 ] = 0.0; - up[ 1 ] = 0.0; - up[ 2 ] = 1.0; - } else { - up[ 0 ] = 1.0; - up[ 1 ] = 0.0; - up[ 2 ] = 0.0; - } - -/* Create unit vectors along the three axes of the text plane - coordinate system. */ - ref[ 0 ] = x[ 0 ]; - ref[ 1 ] = y[ 0 ]; - ref[ 2 ] = z[ 0 ]; - if( !getTextAxes( ref, up, norm, "CC", tx, ty, tz, just ) ) return 0; - -/* Calculate the pgplot symbol number for the given marker type. */ - if( type > 0 ) { - if( type > 127 ) { - symnum = type; - } else { - ccpgqcf( &font ); - ccgrsymk( type, font, &symnum ); - } - - } else if( type > -3 ) { - getSymbolList( ".", 1, &symnum, &nlist ); - -/* Regular polygons - create an array of text plane coordinates for the - vertices of the polygon. */ - } else { - symnum = type; - -/* Get the character height in world coordinate units. A PGPLOT - character height of 1.0 corresponds to 1/40 of the 2D window height. */ - ch = getCharHeight(); - -/* Limit the number of sides that can be produced. */ - ns = -type; - if( ns > MXSIDE ) ns = MXSIDE; - -/* Calculate the angle subtended by each edge of the polygon. */ - dang = TWOPI/ns; - ang = 0.0; - -/* Loop round each vertex. */ - for( i = 0; i < ns; i++ ) { - vx[ i ] = ch*sin( ang ); - vy[ i ] = ch*cos( ang ); - vz[ i ] = 0.0; - ang += dang; - } - } - -/* Save the current clipping flag, and ensure clipping is off. */ - ccpgqclp( &clip ); - ccpgsclp( 0 ); - -/* Draw each marker in turn. */ - for( i = 0; i < n; i++ ) { - -/* Store the centre world coords */ - ref[ 0 ] = x[ i ]; - ref[ 1 ] = y[ i ]; - ref[ 2 ] = z[ i ]; - -/* Draw the symbol, and return if anything goes wrong. */ - if( symnum >= 0 ) { - if( !Text( &symnum, 1, ref, "CC", tx, ty, tz ) ) return 0; - - } else { - if( !Polygon( ns, vx, vy, vz, ref, tx, ty, tz ) ) return 0; - - } - - } - -/* Re-instate original clipping flag. */ - ccpgsclp( clip ); - -/* If we arrive here we have been succesful, so return a non-zero value. */ - return 1; -} - -int astG3DQch( float *ch ){ -/* -*+ -* Name: -* astG3DQch - -* Purpose: -* Return the character height in world coordinates. - -* Synopsis: -* #include "grf3d.h" -* int astG3DQch( float *ch ) - -* Description: -* This function returns the height of characters drawn using astG3DText. - -* Parameters: -* ch -* A pointer to the double which is to receive the height of -* characters drawn with astG3DText. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Since the 3D world coordinate axes are assumed to be equally -* scaled, the height of text in world coordinate units is independent -* of the orientation of the text. Therefore, this function returns -* only one height value, unlike the equivalent 2D astGQch function -* that returns two heights. -*- -*/ - *ch = getCharHeight(); - return 1; -} - -int astG3DText( const char *text, float ref[3], const char *just, float up[3], - float norm[3] ){ -/* -*+ -* Name: -* astG3DText - -* Purpose: -* Draw a character string. - -* Synopsis: -* #include "grf3d.h" -* int astG3DText( const char *text, float ref[3], const char *just, -* float up[3], float norm[3] ) - -* Description: -* This function displays a character string at a given position -* on a given plane in 3D world coords, using a specified -* justification and up-vector. - -* Parameters: -* text -* Pointer to a null-terminated character string to be displayed. -* ref -* The reference (x,y,z) coordinates. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* up -* The (x,y,z) up-vector for the text. The actual up vector used is -* the projection of the supplied vector onto the plane specified by -* "norm". -* norm -* The (x,y,z) components of a vector that is normal to the plane -* containing the text. The given vector passes through the text -* from the back to the front. If all components of this vector are -* zero, then a normal vector pointing towards the camera eye is used. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - This routine does not recognise PGPLOT escape sequences. -* - A NULL value for "just" causes a value of "CC" to be used. -*- -*/ - -/* Local Constants: */ -#define MXLEN 256 - -/* Local Variables: */ - char newjust[3]; - float tx[3], ty[3], tz[3]; - int list[ MXLEN ]; - int nlist; - -/* Convert the supplied string into a list of PGPLOT symbol numbers */ - getSymbolList( text, MXLEN, &nlist, list ); - -/* Create unit vectors along the three axes of the text plane - coordinate system. */ - if( !getTextAxes( ref, up, norm, just, tx, ty, tz, newjust ) ) return 0; - -/* Draw the text. */ - return Text( list, nlist, ref, newjust, tx, ty, tz ); - -/* Clear local constants. */ -#undef MXLEN -} - -int astG3DTxExt( const char *text, float ref[3], const char *just, - float up[3], float norm[3], float *xb, float *yb, - float *zb, float bl[3] ){ -/* -*+ -* Name: -* astG3DTxExt - -* Purpose: -* Get the extent of a character string. - -* Synopsis: -* #include "grf3d.h" -* int astG3DTxExt( const char *text, float ref[3], const char *just, -* float up[3], float norm[3], float *xb, float *yb, -* float *zb, float bl[3] ) - -* Description: -* This function returns the corners of a box which would enclose the -* supplied character string if it were displayed using astG3DText. -* -* The returned box INCLUDES any leading or trailing spaces. - -* Parameters: -* text -* Pointer to a null-terminated character string to be displayed. -* ref -* The reference (x,y,z) coordinates. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", 'B' for "baseline", or "M" for "bottom", and -* specifies the vertical location of the reference position. Note, -* "baseline" corresponds to the base-line of normal text. Some -* characters (eg "y", "g", "p", etc) descend below the base-line, -* and so "M" and "B" will produce different effects for such -* characters. The second character may be 'L' for "left", 'C' for -* "centre", or 'R' for "right", and specifies the horizontal -* location of the reference position. If the string has less than -* 2 characters then 'C' is used for the missing characters. -* up -* The (x,y,z) up-vector for the text. The actual up vector used is -* the projection of the supplied vector onto the plane specified by -* "norm". -* norm -* The (x,y,z) components of a vector that is normal to the plane -* containing the text. The given vector passes through the text -* from the back to the front. If all components of this vector are -* zero, then a normal vector pointing towards the camera eye is used. -* xb -* An array of 4 elements in which to return the x coordinate of -* each corner of the bounding box. -* yb -* An array of 4 elements in which to return the y coordinate of -* each corner of the bounding box. -* zb -* An array of 4 elements in which to return the z coordinate of -* each corner of the bounding box. -* bl -* The 3D world coordinates at the left hand end of the text -* baseline. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - The order of the corners is anti-clockwise starting at the -* bottom left when viewing the text normally (i.e. face on). -* - This routine does not recognise PGPLOT escape sequences. -* - A NULL value for "just" causes a value of "CC" to be used. -*- -*/ - -/* Local Constants: */ -#define MXLEN 256 - -/* Local Variables: */ - char newjust[3]; - int i; - int list[ MXLEN ]; - int nlist; - float tx[3], ty[3], tz[3]; - -/* Initialise the returned values to indicate no box available. */ - for( i = 0; i < 4; i++ ){ - xb[ i ] = 0.0; - yb[ i ] = 0.0; - zb[ i ] = 0.0; - } - -/* Convert the supplied string into a list of symbol numbers */ - getSymbolList( text, MXLEN, &nlist, list ); - -/* Create unit vectors along the three axes of the text plane - coordinate system. */ - if( !getTextAxes( ref, up, norm, just, tx, ty, tz, newjust ) ) return 0; - -/* Find the bounding box of this list of symbols. */ - return TxExt( list, nlist, ref, newjust, tx, ty, tz, xb, yb, zb, bl ); - -/* Clear local constants. */ -#undef MXLEN -} - - -/* Public functions specific to this PGPLOT implementation. */ -/* ======================================================== */ -/* Other implementations of the grf3d interface can ignore the following - functions. They provide control of the 3D view. */ - -int PG3DSetCamera( float eye[3], float target[3], float up[3], float screen ){ -/* -*+ -* Name: -* PG3DSetCamera - -* Purpose: -* Store new camera settings for the current PGPLOT device. - -* Synopsis: -* #include "grf3d.h" -* int PG3DSetCamera( float eye[3], float target[3], float up[3], -* float screen ) - -* Description: -* This function stores new camera settings for the current PGPLOT -* device. -* -* A "camera" describes the projection of the 3D world coordinate -* space onto a 2D "screen". This screen corresponds to the 2D viewing -* surface used by PGPLOT. The 2D window used by PGPLOT (as set by -* PGSWIN, etc) defines the bounds of the screen area that is visible -* in the PGPLOT viewport. -* -* The 3D world coordinate axes (x,y,z) are such that if "z" is -* vertically upwards and "x" points to the right, then "y" goes -* out of the paper away from you. All 3 axes are assume to have equal -* scale. -* -* A camera defines a second set of 3D axes (called "(u,v,w)") with -* origin at the 3D world coordinates given by "eye": -* -* - the "w" axis points towards the position given by "target" -* - the "v" axis is perpendicular to the "w" axis and is in the plane -* spanned by the "w" axis and the supplied "up" vector -* - the "u" axis is perpendicular to both "w" and "v" and points to -* the left when looking from the eye along the w axis with the v -* axis upwards -* -* Thus the "v" axis is parallel to "vertically up" on the 2D screen, -* "u" is parallel to "horizontally to the left", and "w" is -* perpendicular to the screen, pointing towards the target. -* -* The screen is a plane perpendicular to the "w" axis, at the "w" axis -* value given by "screen". A 2D cartesian coordinate system (h,r) is -* defined on the screen, with origin at the point where the "w" axis -* intersects the screen. The "h" (horizontal) axis is parallel to the -* "u" axis but points in the opposite direction (to the left), and the -* "r" (vertical) axis is parallel to the "v" axis. The (h,r) system is -* taken to be the same as the PGPLOT 2D world coordinate system, and -* PGSWIN can therefore be used to specify the rectangular area on the -* screen that is mapped onto the PGPLOT viewport. -* -* It is assumed that all axes (x,y,z), (u,v,w) and (h,r) are measured -* in the same units. - -* Parameters: -* eye -* The position vector of the camera's "eye", in 3D world coordinates. -* target -* The position vector of a point in 3D world coordinates that is -* at the centre of the camera's view. In other words, the camera is -* looking towards this point. Zero will be returned if the target -* is the same position as the eye. -* up -* A vector in 3D world coordinates that will appear vertically -* upwards when projected onto the screen. Zero will be returned if -* the up vector has zero length or is parallel to the line joining -* the eye and the target. -* screen -* The distance from the camera's eye to the projection screen. If -* this is zero, then an orthographic projection is used. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Zero is returned if no PGPLOT device has been opened prior to -* calling this function. -*- -*/ - -/* Local Variables: */ - Camera *cam; - float *u, *v, *w; - int result = 0; - -/* Get a pointer to the Camera structure for the current PGPLOT device. - Return without action if no PGPLOT device is open. */ - cam = getCamera( 0 ); - if( cam ) { - result = 1; - -/* Store the supplied values in the camera. */ - memcpy( cam->target_vector, target, 3*sizeof( float ) ); - memcpy( cam->eye_vector, eye, 3*sizeof( float ) ); - cam->screen_distance = screen; - -/* Get pointers to the three rows of the w2c_matrix. This is a 3x3 matrix that - rotates vectors in the (x,y,z) system into vectors in the (u,v,w) - system. Each row in the matrix is a unit vector along the u, v or w - axes. */ - u = cam->w2c_matrix; - v = u + 3; - w = v + 3; - -/* The "w" axis points form the eye to the target, so get the vector from - the eye to the target and normalise it. */ - vectorSub( target, eye, w ); - if( ! vectorNorm( w ) ) result = 0; - -/* The "v" vector is in the plane spanned by the "w" axis and the "up" - vector. Get the normal to this plane, storing the result temporarily - in the "u" vector. . */ - vectorProduct( w, up, u ); - -/* The "v" vector is normal to the vector found above and is also normal - to the "w" axis. Get this vector and normalise it. */ - vectorProduct( u, w, v ); - if( ! vectorNorm( v ) ) result = 0; - -/* The "u" vector is perpendicualr to both the "w" and "v" vectors. */ - vectorProduct( v, w, u ); - if( ! vectorNorm( u ) ) result = 0; - -/* Use "v" as the stored up vector (the supplied "up" vector is not - necesarily the same as "v"). */ - memcpy( cam->up_vector, v, 3*sizeof( float ) ); - -/* Se a flag that indicates that the Camera is usable. */ - cam->ok_flag = result ? CAMERA_OK : CAMERA_OK/2; - } - - return result; -} - -int PG3DSetEye( float eye[3] ){ -/* -*+ -* Name: -* PG3DSetEye - -* Purpose: -* Store a new camera eye position for the current PGPLOT device. - -* Synopsis: -* #include "grf3d.h" -* int PG3DSetEye( float eye[3] ) - -* Description: -* This function modifies the camera eye position for the current -* PGPLOT device. Other camera settings are left unchanged. See -* PG3DSetCamera for more details. - -* Parameters: -* eye -* The position vector of the camera's "eye", in 3D world coordinates. -* Zero is returned if the new eye position is the same as the -* existing camera target position. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Zero is returned if no PGPLOT device has been opened prior to -* calling this function. -* - This function can only be called to modify an existing Camera. -* Consequently it returns zero if a camera has not already been set -* for the current PGPLOT device by calling PG3DSetCamera. -*- -*/ - -/* Local Variables: */ - Camera *cam; - int result = 0; - -/* Get a pointer to the Camera structure for the current PGPLOT device. - Return without action if no PGPLOT device is open. */ - cam = getCamera( 1 ); - if( cam ) { - -/* If so, modify the camera values, using the supplied eye position but - retaining the other camera settings. */ - result = PG3DSetCamera( eye, cam->target_vector, cam->up_vector, - cam->screen_distance ); - } - - return result; -} - -int PG3DRotateEye( int dir, float angle ){ -/* -*+ -* Name: -* PG3DRotateEye - -* Purpose: -* Move the eye on a great circle around the current target position. - -* Synopsis: -* #include "grf3d.h" -* int PG3DRotateEye( int dir, float angle ) - -* Description: -* This function modifies the camera eye position for the current -* PGPLOT device. Other camera settings are left unchanged. See -* PG3DSetCamera for more details. -* -* The eye is moved by a gven distance along an arc of a great circle -* centred on the current target position. The target position itself -* is left unchanged. - -* Parameters: -* dir -* The direction in which to move the eye position: -* 1 - Move eye upwards -* 2 - Move eye downwards -* 3 - Move eye left -* 4 - Move eye right -* angle -* The arc-distance, in degrees, by which to move the eye. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Zero is returned if no PGPLOT device has been opened prior to -* calling this function. -* - This function can only be called to modify an existing Camera. -* Consequently it returns zero if a camera has not already been set -* for the current PGPLOT device by calling PG3DSetCamera. -*- -*/ - -/* Local Variables: */ - Camera *cam; - int result = 0; - int i; - float e[3], f[3], emod, neweye[3], sina, cosa; - -/* Get a pointer to the Camera structure for the current PGPLOT device. - Return without action if no PGPLOT device is open. */ - cam = getCamera( 1 ); - if( cam ) { - -/* Get the cos and sine of the supplied angle. */ - cosa = cos( angle*TWOPI/360 ); - sina = sin( angle*TWOPI/360 ); - -/* Get the vector from the target to the eye, get its modulus. */ - vectorSub( cam->eye_vector, cam->target_vector, e ); - emod = vectorModulus( e ); - -/* If we are moving the eye upwards, find the new eye position. */ - if( dir == 1 ) { - for( i = 0; i < 3; i++ ) { - neweye[ i ] = e[ i ]*cosa + emod*cam->up_vector[ i ]*sina + - cam->target_vector[ i ]; - } - -/* If we are moving the eye downwards, find the new eye position. */ - } else if( dir == 2 ) { - for( i = 0; i < 3; i++ ) { - neweye[ i ] = e[ i ]*cosa - emod*cam->up_vector[ i ]*sina + - cam->target_vector[ i ]; - } - -/* If we are moving the eye left or right we need a vector in the plane - of rotation that is at right angles to "e", and points to the right - of the eye. */ - } else { - vectorProduct( cam->up_vector, e, f ); - vectorNorm( f ); - -/* Get the new eye position. */ - if( dir == 3 ) { - for( i = 0; i < 3; i++ ) { - neweye[ i ] = e[ i ]*cosa - emod*f[ i ]*sina + cam->target_vector[ i ]; - } - - } else { - for( i = 0; i < 3; i++ ) { - neweye[ i ] = e[ i ]*cosa + emod*f[ i ]*sina + cam->target_vector[ i ]; - } - } - } - -/* Modify the camera eye vector, retaining the other camera settings. */ - result = PG3DSetCamera( neweye, cam->target_vector, cam->up_vector, - cam->screen_distance ); - } - - return result; -} - -int PG3DForward( float distance ){ -/* -*+ -* Name: -* PG3DForward - -* Purpose: -* Move the eye forward towards the target. - -* Synopsis: -* #include "grf3d.h" -* int PG3DForward( float distance ) - -* Description: -* This function modifies the camera eye position for the current -* PGPLOT device. Other camera settings are left unchanged. See -* PG3DSetCamera for more details. -* -* The eye is moved forward by a given distance towards the target -* point, and the target point is also moved forward so that the -* distance between eye and target remains unchanged. - -* Parameters: -* distance -* The distance to move the eye and target, given as a fraction of -* the distance between the eye and the target. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Zero is returned if no PGPLOT device has been opened prior to -* calling this function. -* - This function can only be called to modify an existing Camera. -* Consequently it returns zero if a camera has not already been set -* for the current PGPLOT device by calling PG3DSetCamera. -*- -*/ - -/* Local Variables: */ - Camera *cam; - int result = 0; - int i; - float e[3], newtarg[3], neweye[3]; - -/* Get a pointer to the Camera structure for the current PGPLOT device. - Return without action if no PGPLOT device is open. */ - cam = getCamera( 1 ); - if( cam ) { - -/* Get the vector from the eye to the target. */ - vectorSub( cam->target_vector, cam->eye_vector, e ); - -/* Find the new eye and target positions. */ - for( i = 0; i < 3; i++ ){ - neweye[ i ] = cam->eye_vector[ i ] + e[ i ]*distance; - newtarg[ i ] = cam->target_vector[ i ] + e[ i ]*distance; - } - -/* Modify the camera eye and target vectors, retaining the other camera - settings. */ - result = PG3DSetCamera( neweye, newtarg, cam->up_vector, - cam->screen_distance ); - } - - return result; -} - - -int PG3DFindNearest( int n, float *x, float *y, float *z, int *iclose ){ -/* -*+ -* Name: -* PG3DForward - -* Purpose: -* Find the closest point to the eye. - -* Synopsis: -* #include "grf3d.h" -* int PG3DFindNearest( int n, float *x, float *y, float *z, int *iclose ) - -* Description: -* This function checks every supplied point and returns the index of -* the point that is closest to the eye. - -* Parameters: -* n -* The number of points to check. -* x -* Pointer to an array of "n" X values. -* y -* Pointer to an array of "n" Y values. -* z -* Pointer to an array of "n" Z values. -* iclose -* Pointer to an int in which to return the index of hte nearest -* point. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Zero is returned if no PGPLOT device has been opened prior to -* calling this function. -*- -*/ - -/* Local Variables: */ - Camera *cam; - int result = 0; - int i; - float c[3], v[3]; - float d; - float dmin; - - *iclose = 0; - -/* Get a pointer to the Camera structure for the current PGPLOT device. - Return without action if no PGPLOT device is open. */ - cam = getCamera( 1 ); - if( cam ) { - result = 1; - -/* Loop through all the supplied positions. */ - dmin = FLT_MAX; - for( i = 0; i < n; i++ ) { - -/* Get the required distance. */ - v[ 0 ] = x[ i ]; - v[ 1 ] = y[ i ]; - v[ 2 ] = z[ i ]; - vectorSub( v, cam->eye_vector, c ); - d = vectorModulus( c ); - -/* If this is the smallest distance so far, remember it. */ - if( d < dmin ) { - dmin = d; - *iclose = i; - } - } - } - - return result; -} - - -int PG3DSetTarget( float target[3] ){ -/* -*+ -* Name: -* PG3DSetTarget - -* Purpose: -* Store a new camera target position for the current PGPLOT device. - -* Synopsis: -* #include "grf3d.h" -* int PG3DSetTarget( float target[3] ) - -* Description: -* This function modifies the camera target position for the current -* PGPLOT device. Other camera settings are left unchanged. See -* PG3DSetCamera for more details. - -* Parameters: -* target -* The position vector of the camera's "target", in 3D world coordinates. -* Zero is returned if the new target position is the same as the -* existing camera eye position. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Zero is returned if no PGPLOT device has been opened prior to -* calling this function. -* - This function can only be called to modify an existing Camera. -* Consequently it returns zero if a camera has not already been set -* for the current PGPLOT device by calling PG3DSetCamera. -*- -*/ - -/* Local Variables: */ - Camera *cam; - int result = 0; - -/* Get a pointer to the Camera structure for the current PGPLOT device. - Return without action if no PGPLOT device is open. */ - cam = getCamera( 1 ); - if( cam ) { - -/* If so, modify the camera values, using the supplied target position but - retaining the other camera settings. */ - result = PG3DSetCamera( cam->eye_vector, target, cam->up_vector, - cam->screen_distance ); - } - - return result; -} - - -int PG3DSetUp( float up[3] ){ -/* -*+ -* Name: -* PG3DSetUp - -* Purpose: -* Store a new camera up vector for the current PGPLOT device. - -* Synopsis: -* #include "grf3d.h" -* int PG3DSetUp( float up[3] ) - -* Description: -* This function modifies the camera up vector for the current -* PGPLOT device. Other camera settings are left unchanged. See -* PG3DSetCamera for more details. - -* Parameters: -* up -* The new up vector, in 3D world coordinates. Zero is returned if -* the new up vector is parallel to the line joining the eye and -* the target positions. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Zero is returned if no PGPLOT device has been opened prior to -* calling this function. -* - This function can only be called to modify an existing Camera. -* Consequently it returns zero if a camera has not already been set -* for the current PGPLOT device by calling PG3DSetCamera. -*- -*/ - -/* Local Variables: */ - Camera *cam; - int result = 0; - -/* Get a pointer to the Camera structure for the current PGPLOT device. - Return without action if no PGPLOT device is open. */ - cam = getCamera( 1 ); - if( cam ) { - -/* If so, modify the camera values, using the supplied up vector but - retaining the other camera settings. */ - result = PG3DSetCamera( cam->eye_vector, cam->target_vector, up, - cam->screen_distance ); - } - - return result; -} - - -int PG3DSetScreen( float screen ){ -/* -*+ -* Name: -* PG3DSetScreen - -* Purpose: -* Store a new camera screen distance for the current PGPLOT device. - -* Synopsis: -* #include "grf3d.h" -* int PG3DSetScreen( float screen ) - -* Description: -* This function modifies the camera screen distance for the current -* PGPLOT device. Other camera settings are left unchanged. See -* PG3DSetCamera for more details. - -* Parameters: -* screen -* The distance from the camera's eye to the projection screen in -* 3D world coordinate units. If this is zero, then an orthographic -* projection is used. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Zero is returned if no PGPLOT device has been opened prior to -* calling this function. -* - This function can only be called to modify an existing Camera. -* Consequently it returns zero if a camera has not already been set -* for the current PGPLOT device by calling PG3DSetCamera. -*- -*/ - -/* Local Variables: */ - Camera *cam; - int result = 0; - -/* Get a pointer to the Camera structure for the current PGPLOT device. - Return without action if no PGPLOT device is open. */ - cam = getCamera( 1 ); - if( cam ) { - -/* If so, modify the camera values, using the supplied screen distance but - retaining the other camera settings. */ - result = PG3DSetCamera( cam->eye_vector, cam->target_vector, - cam->up_vector, screen ); - } - - return result; -} - -int PG3DAutoCamera( float lbnd[3], float ubnd[3] ){ -/* -*+ -* Name: -* PG3DAutoCamera - -* Purpose: -* Set up a default camera to view a given box of 3D world coords. - -* Synopsis: -* #include "grf3d.h" -* int PG3DAutoCamera( float lbnd[3], float ubnd[3] ) - -* Description: -* This function sets up the camera and the 2D PGPLOT window for the -* current device so that it produces a default view of a specified -* volume of 3D world coordinate space. - -* Parameters: -* lbnd -* The lower bounds of the volume of 3D world coordinates that -* is to be visible using the camera and 2D PGPLOT window. -* ubnd -* The upper bounds of the volume of 3D world coordinates that -* is to be visible using the camera and 2D PGPLOT window. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Zero is returned if no PGPLOT device has been opened prior to -* calling this function. -*- -*/ - -/* Local Variables: */ - float target[3], eye[3], up[3], screen, dx, dy, dz, hlo, hhi, rlo, rhi; - float x[8], y[8], z[8], h[8], r[8]; - Camera *cam; - int result = 0; - int i; - -/* Get a pointer to the Camera structure for the current PGPLOT device. - Return without action if no PGPLOT device is open. */ - cam = getCamera( 0 ); - if( cam ) { - -/* The target position (i.e. the position towards which the camera is - looking) is the middle of the volume. */ - target[ 0 ] = 0.5*( lbnd[ 0 ] + ubnd[ 0 ] ); - target[ 1 ] = 0.5*( lbnd[ 1 ] + ubnd[ 1 ] ); - target[ 2 ] = 0.5*( lbnd[ 2 ] + ubnd[ 2 ] ); - -/* The eye is slightly offset from a corner view. */ - eye[ 0 ] = 0.85*ubnd[ 0 ] + 0.15*lbnd[ 0 ]; - eye[ 1 ] = 0.75*ubnd[ 1 ] + 0.25*lbnd[ 1 ]; - eye[ 2 ] = 0.75*ubnd[ 2 ] + 0.25*lbnd[ 2 ]; - -/* The eye is seven times the size of the box away from the box centre. */ - eye[ 0 ] = 7*(eye[ 0 ] - target[ 0 ] ) + target[ 0 ]; - eye[ 1 ] = 7*(eye[ 1 ] - target[ 1 ] ) + target[ 1 ]; - eye[ 2 ] = 7*(eye[ 2 ] - target[ 2 ] ) + target[ 2 ]; - -/* The up vector is paralle to the Z axis. */ - up[ 0 ] = 0.0; - up[ 1 ] = 0.0; - up[ 2 ] = 1.0; - -/* The screen is at the centre of the box. */ - dx = eye[ 0 ] - target[ 0 ]; - dy = eye[ 1 ] - target[ 1 ]; - dz = eye[ 2 ] - target[ 2 ]; - screen = sqrtf( dx*dx + dy*dy + dz*dz ); - -/* Set the camera. */ - if( PG3DSetCamera( eye, target, up, screen ) ) { - -/* Get the 3D World coords at the corners of the volume. */ - x[ 0 ] = ubnd[ 0 ]; - x[ 1 ] = ubnd[ 0 ]; - x[ 2 ] = lbnd[ 0 ]; - x[ 3 ] = lbnd[ 0 ]; - x[ 4 ] = ubnd[ 0 ]; - x[ 5 ] = ubnd[ 0 ]; - x[ 6 ] = lbnd[ 0 ]; - x[ 7 ] = lbnd[ 0 ]; - - y[ 0 ] = lbnd[ 1 ]; - y[ 1 ] = ubnd[ 1 ]; - y[ 2 ] = ubnd[ 1 ]; - y[ 3 ] = lbnd[ 1 ]; - y[ 4 ] = lbnd[ 1 ]; - y[ 5 ] = ubnd[ 1 ]; - y[ 6 ] = ubnd[ 1 ]; - y[ 7 ] = lbnd[ 1 ]; - - z[ 0 ] = lbnd[ 2 ]; - z[ 1 ] = lbnd[ 2 ]; - z[ 2 ] = lbnd[ 2 ]; - z[ 3 ] = lbnd[ 2 ]; - z[ 4 ] = ubnd[ 2 ]; - z[ 5 ] = ubnd[ 2 ]; - z[ 6 ] = ubnd[ 2 ]; - z[ 7 ] = ubnd[ 2 ]; - -/* Transform these into screen coordinates. */ - if( transform( cam, 8, x, y, z, h, r ) ) { - -/* Find the bounds in h and r of the projection of the volume. */ - hlo = FLT_MAX; - hhi = -FLT_MAX; - rlo = FLT_MAX; - rhi = -FLT_MAX; - - for( i = 0; i < 8; i++ ) { - if( h[ i ] < hlo ) hlo = h[ i ]; - if( h[ i ] > hhi ) hhi = h[ i ]; - if( r[ i ] < rlo ) rlo = r[ i ]; - if( r[ i ] > rhi ) rhi = r[ i ]; - } - -/* Extend these bounds by 5% at each end */ - dx = 0.05*( hhi - hlo ); - hhi += dx; - hlo -= dx; - - dy = 0.05*( rhi - rlo ); - rhi += dy; - rlo -= dy; - -/* If the box has non-zero area, set it as the 2D PGPLOT window, and - indicate success. */ - if( rlo < rhi && hlo < hhi ) { - ccpgswin( hlo, hhi, rlo, rhi ); - result = 1; - } - } - } - } - return result; -} - - - - - -/* Private functions for this module */ -/* ================================= */ - -static int TextCam( Camera *textcam, float ref[3], float tx[3], float ty[3], - float tz[3] ){ -/* -* Name: -* TextCam - -* Purpose: -* Create a Camera that converts 3D text plane coordinates into 2D world -* coordinates. - -* Synopsis: -* #include "grf3d.h" -* int TextCam( Camera *textcam, float ref[3], float tx[3], float ty[3], -* float tz[3] ) - -* Description: -* This function initialises the contents of a supplied Camera -* structure so that the Camera describes the transformation from 3D -* "text plane" coordinates to 2D PGPLOT world coordinates. The text -* plane coordinate system is defined by three vectors along its x, y -* and z axes, and an origin position. -* -* Text plane coordinates describe a plane upon which 2D graphics such -* as text is drawn. The X axis is parallel to the text base line, the -* Y axis is the text up vector, and the Z axis is perpendicular to -* the text, passing from the back of the text to the front of the text. - -* Parameters: -* textcam -* The Camera structure which is to be modified. -* ref -* The (x,y,z) coordinates at the text plane origin. -* tx -* A unit vector (expressed in 3D world coords) along the text plane -* X axis. This is parallel to the text base line. -* ty -* A unit vector (expressed in 3D world coords) along the text plane -* Y axis. This is parallel to the projectionof ht eup vector on to -* the text plane. -* tz -* A unit vector (expressed in 3D world coords) along the text plane -* Z axis. This is perpendicular to the text plane, passing from -* the back of the text to the front of the text. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -*/ - - -/* Local Variables: */ - Camera *cam; - float dx, dy, dz; - int i; - float a, b, c; - -/* Get the Camera for the current device identifier. Abort if no camera - is available. This camera describes the transformation from 3D world - coordinates (x,y,z) to 2D world coordinates (screen coordinates) (h,r). */ - cam = getCamera( 1 ); - if( !cam ) return 0; - -/* Create a Camera structure that describes the transformation from - text plane coordinates to 2D world coords, putting the origin of text - plane coordinates at the given reference position. */ - dx = cam->eye_vector[ 0 ] - ref[ 0 ]; - dy = cam->eye_vector[ 1 ] - ref[ 1 ]; - dz = cam->eye_vector[ 2 ] - ref[ 2 ]; - - textcam->eye_vector[ 0 ] = tx[ 0 ]*dx + tx[ 1 ]*dy + tx[ 2 ]*dz; - textcam->eye_vector[ 1 ] = ty[ 0 ]*dx + ty[ 1 ]*dy + ty[ 2 ]*dz; - textcam->eye_vector[ 2 ] = tz[ 0 ]*dx + tz[ 1 ]*dy + tz[ 2 ]*dz; - - for( i = 0; i < 8; i += 3 ) { - a = cam->w2c_matrix[ i ]; - b = cam->w2c_matrix[ i + 1 ]; - c = cam->w2c_matrix[ i + 2 ]; - textcam->w2c_matrix[ i ] = a*tx[ 0 ] + b*tx[ 1 ] + c*tx[ 2 ]; - textcam->w2c_matrix[ i + 1 ] = a*ty[ 0 ] + b*ty[ 1 ] + c*ty[ 2 ]; - textcam->w2c_matrix[ i + 2 ] = a*tz[ 0 ] + b*tz[ 1 ] + c*tz[ 2 ]; - } - - textcam->screen_distance = cam->screen_distance; - textcam->ok_flag = CAMERA_OK; - - return 1; -} - -static int Polygon( int nside, float *vx, float *vy, float *vz, float ref[3], - float tx[3], float ty[3], float tz[3] ){ -/* -* Name: -* Polygon - -* Purpose: -* Draw a regular polygon. - -* Synopsis: -* #include "grf3d.h" -* int Polygon( int nside, float *vx, float *vy, float *vz, float ref[3], -* float tx[3], float ty[3], float tz[3] ) - -* Description: -* This function draws a polygon centred at a given position on a -* given plane in 3D world coords, using a specified up-vector. The -* polygon vertices are specified in text plane coordinates via vx, -* vy and vz. - -* Parameters: -* nside -* Number of sides for the polygon. Numbers higher than 32 are -* treated as 32. -* vx -* Pointer to an array of "nside" text plane X axis values. -* vy -* Pointer to an array of "nside" text plane Y axis values. -* vz -* Pointer to an array of "nside" text plane Z axis values. -* ref -* The (x,y,z) coordinates at the polygon centre. -* tx -* A unit vector (expressed in 3D world coords) along the text plane -* X axis. This is parallel to the text base line. -* ty -* A unit vector (expressed in 3D world coords) along the text plane -* Y axis. This is parallel to the projectionof ht eup vector on to -* the text plane. -* tz -* A unit vector (expressed in 3D world coords) along the text plane -* Z axis. This is perpendicular to the text plane, passing from -* the back of the text to the front of the text. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -*/ - - -/* Local Variables: */ - Camera *cam; - Camera newcam; - float h[ MXSIDE ], r[ MXSIDE ]; - -/* Get the Camera for the current device identifier. Abort if no camera - is available. */ - cam = getCamera( 1 ); - if( !cam ) return 0; - -/* Check the number of points. */ - if( nside > MXSIDE) return 0; - -/* Create a Camera structure that describes the transformation from - text plane coordinates to 2D world coords, putting the origin of text - plane coordinates at the given reference position. */ - if( !TextCam( &newcam, ref, tx, ty, tz ) ) return 0; - -/* Transform the given text plane coordinates into 2D world coordinates. */ - if( !transform( &newcam, nside, vx, vy, vz, h, r ) ) return 0; - -/* Draw the polygon. */ - ccpgpoly( nside, h, r ); - -/* If we get here we have succeeded so return a non-zero value. */ - return 1; -} - -static int Text( int *list, int nlist, float ref[3], const char *just, - float tx[3], float ty[3], float tz[3] ){ -/* -* Name: -* Text - -* Purpose: -* Draw a character string. - -* Synopsis: -* #include "grf3d.h" -* int Text( int *list, int nlist, float ref[3], const char *just, -* float tx[3], float ty[3], float tz[3] ) - -* Description: -* This function displays a symbol list at a given position on a given -* plane in 3D world coords, using a specified justification and up-vector. - -* Parameters: -* list -* Pointer to an array of pgplot symbol values. -* nlist -* Length of the "list" array. -* ref -* The reference (x,y,z) coordinates. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* tx -* A unit vector (expressed in 3D world coords) along the text plane -* X axis. This is parallel to the text base line. -* ty -* A unit vector (expressed in 3D world coords) along the text plane -* Y axis. This is parallel to the projection of the up vector on to -* the text plane. -* tz -* A unit vector (expressed in 3D world coords) along the text plane -* Z axis. This is perpendicular to the text plane, passing from -* the back of the text to the front of the text. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - This routine does not recognise PGPLOT escape sequences. -* - A NULL value for "just" causes a value of "CC" to be used. -*/ - -/* Local Constants: */ -#define MXLEN 256 - -/* Local Variables: */ - Camera *cam; - Camera newcam; - float ch; - float tm, txc, tyc; - float txleft, tybase; - float xt[ 150 ], yt[ 150 ], zt[ 150 ], h[ 150 ], r[ 150 ]; - float xb[3], yb[3], zb[3], bl[3]; - int clip; - int i; - int j; - int k; - int unused; - int xygrid[ 300 ]; - -/* If there is nothing to plot return without error. */ - if( nlist == 0 ) return 1; - -/* Find the 3D world coordinates at the left hand end of the text - baseline. */ - if( !TxExt( list, nlist, ref, just, tx, ty, tz, xb, yb, zb, bl ) ) return 0; - -/* Get the Camera for the current device identifier. Abort if no camera - is available. */ - if( ! (cam = getCamera( 1 ) ) ) return 0; - -/* Create a Camera structure that describes the transformation from - text plane coordinates to 2D world coords. */ - if( !TextCam( &newcam, ref, tx, ty, tz ) ) return 0; - -/* Save the current clipping flag, and ensure clipping is off. */ - ccpgqclp( &clip ); - ccpgsclp( 0 ); - -/* Calculate the text plane X coord of the left hand edge of the first - character. */ - txleft = tx[ 0 ]*( bl[ 0 ] - ref[ 0 ] ) + - tx[ 1 ]*( bl[ 1 ] - ref[ 1 ] ) + - tx[ 2 ]*( bl[ 2 ] - ref[ 2 ] ); - -/* Calculate the text plane Y coord at the text baseline. */ - tybase = ty[ 0 ]*( bl[ 0 ] - ref[ 0 ] ) + - ty[ 1 ]*( bl[ 1 ] - ref[ 1 ] ) + - ty[ 2 ]*( bl[ 2 ] - ref[ 2 ] ); - -/* Get the character height in world coordinate units. A PGPLOT - character height of 1.0 corresponds to 1/40 of the 2D window height. */ - ch = getCharHeight(); - -/* Get the polylines that correspond to the first symbol. */ - ccgrsyxd( list[ 0 ], xygrid, &unused ); - -/* Create a linear transformation that maps the font grid coordinate - system used by grsyxd onto text plane coordinates. This transformation - will be different for each character in the string. The initial - transformation set up now is appropriate for the first character. The - mapping is: - - Text_x = txc + tm*Font_x - Text_y = tyc + tm*Font_y - -*/ - tm = ch/( xygrid[ 2 ] - xygrid[ 1 ] ); - tyc = tybase - tm*xygrid[ 1 ]; - txc = txleft - tm*xygrid[ 3 ]; - -/* Loop round each symbol. */ - for( i = 0; i < nlist; i++ ) { - -/* Loop round each polyline that forms a segment of the character */ - k = 5; - while( 1 ) { - -/* Map the polyline vertices into text plane coordinates. */ - j = 0; - while( j < 150 ){ - if( xygrid[ k ] != -64 ) { - xt[ j ] = txc + tm*xygrid[ k++ ]; - yt[ j ] = tyc + tm*xygrid[ k++ ]; - zt[ j++ ] = 0.0; - } else { - break; - } - } - -/* Map the text plane coordinates into 2D world coordinates. */ - if( j > 0 ) { - (void) transform( &newcam, j, xt, yt, zt, h, r ); - -/* Draw the polyline. */ - ccpgline( j, h, r ); - } - -/* If this is the last segment in the character, pass on to the next - character. */ - if( xygrid[ k + 1 ] == -64 ) break; - -/* Otherwise, skip over the end markers in the xygrid array, and go on to - plot the next polyline segment. */ - k += 2; - } - -/* If this is not the last symbol... */ - if( i != nlist - 1 ) { - -/* Set the text x value at which to place the left edge of the next - character. This is the right hand edge of the character just drawn. */ - txleft += tm*( xygrid[ 4 ] - xygrid[ 3 ] ); - -/* Get the polylines that correspond to the next symbol. */ - ccgrsyxd( list[ i + 1 ], xygrid, &unused ); - -/* Modify the transformation from font grid coords to text plane coords - so that it is appropriate for the next character in the string. */ - txc = txleft - tm*xygrid[ 3 ]; - } - -/* Next symbol. */ - } - -/* Re-instate original clipping flag. */ - ccpgsclp( clip ); - -/* If we arrive here, we have been successful, so return a non-zero - value. */ - return 1; - -/* Clear local constants. */ -#undef MXLEN -} - -static int TxExt( int *list, int nlist, float ref[3], const char *just, - float tx[3], float ty[3], float tz[3], float *xb, float *yb, - float *zb, float bl[3] ){ -/* -* Name: -* TxExt - -* Purpose: -* Get the extent of a character string. - -* Synopsis: -* #include "grf3d.h" -* int TxExt( int *list, int nlist, float ref[3], const char *just, -* float tx[3], float ty[3], float tz[3], float *xb, float *yb, -* float *zb, float bl[3] ) - -* Description: -* This function returns the corners of a box which would enclose the -* supplied symbol list if it were displayed using Text. -* -* The returned box includes any leading or trailing spaces. - -* Parameters: -* list -* Pointer to an array of pgplot symbol numbers. -* nlist -* The length of the "list" array. -* ref -* The reference (x,y,z) coordinates. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", 'B' for "baseline", or "M" for "bottom", and -* specifies the vertical location of the reference position. Note, -* "baseline" corresponds to the base-line of normal text. Some -* characters (eg "y", "g", "p", etc) descend below the base-line, -* and so "M" and "B" will produce different effects for such -* characters. The second character may be 'L' for "left", 'C' for -* "centre", or 'R' for "right", and specifies the horizontal -* location of the reference position. If the string has less than -* 2 characters then 'C' is used for the missing characters. -* tx -* A unit vector (expressed in 3D world coords) along the text plane -* X axis. This is parallel to the text base line. -* ty -* A unit vector (expressed in 3D world coords) along the text plane -* Y axis. This is parallel to the projectionof ht eup vector on to -* the text plane. -* tz -* A unit vector (expressed in 3D world coords) along the text plane -* Z axis. This is perpendicular to the text plane, passing from -* the back of the text to the front of the text. -* xb -* An array of 4 elements in which to return the x coordinate of -* each corner of the bounding box. -* yb -* An array of 4 elements in which to return the y coordinate of -* each corner of the bounding box. -* zb -* An array of 4 elements in which to return the z coordinate of -* each corner of the bounding box. -* bl -* The 3D world coordinates at the left hand end of the text -* baseline. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - The order of the corners is anti-clockwise starting at the -* bottom left when viewing the text normally (i.e. face on). -* - This routine does not recognise PGPLOT escape sequences. -* - A NULL value for "just" causes a value of "CC" to be used. -*/ - -/* Local Constants: */ -#define MXLEN 256 - -/* Local Variables: */ - float ch; - float txlo, txhi, tylo, tyhi, tyzero; - float tm; - float w; - int i; - int unused; - int xygrid[ 300 ]; - int gylo, gyhi, width; - -/* Initialise the returned values to indicate no box available. */ - for( i = 0; i < 4; i++ ){ - xb[ i ] = 0.0; - yb[ i ] = 0.0; - zb[ i ] = 0.0; - } - -/* If there is nothing to plot return without error. */ - if( nlist == 0 ) return 1; - -/* We now find the bounding box of the text in "text plane coordinates". - These are (tx,ty,tz) axes that span the plane upon which the text is - writtens. The origin of (tx,ty,tz) is at the supplied 3D reference - position, the X axis increases along the text baseline, and Y axis - increases along the text up vector, and Z increases from the back - of the text to the front of the text (all are measured in 3D world - coord units). We first find the bounds of the text in these text plane - coordinates, assuming that the bottom left of the text baseline is - placed at the given reference position (i.e. at the origiin of text - plane coordinates). */ - -/* Get the character height in world coordinate units. A PGPLOT - character height of 1.0 corresponds to 1/40 of the 2D window height. */ - ch = getCharHeight(); - -/* Initialise the Y bounds of the text bounding box in grid coords. */ - gylo = INT_MAX; - gyhi = -INT_MAX; - -/* Initialise things. */ - width = 0; - tm = 1.0; - -/* Loop round each symbol. */ - for( i = 0; i < nlist; i++ ) { - -/* Get the polylines that correspond to this symbol. */ - ccgrsyxd( list[ i ], xygrid, &unused ); - -/* If this is the first symbol, set the scaling factor that converts - grid units to text plane units. */ - if( i == 0 ) tm = ch/( xygrid[ 2 ] - xygrid[ 1 ] ); - -/* Note the highest and lowest y grid value. */ - w = xygrid[ 2 ] - xygrid[ 1 ]; - if( w > gyhi ) gyhi = w; - - w = xygrid[ 0 ] - xygrid[ 1 ]; - if( w < gylo ) gylo = w; - -/* Increment the total width of the string in grid units. */ - width += xygrid[ 4 ] - xygrid[ 3 ]; - } - -/* Set up the bounding box in text plane coordinates. */ - txlo = 0.0; - txhi = width*tm; - tylo = gylo*tm; - tyhi = gyhi*tm; - tyzero = 0.0; - -/* Adjust the text plane bounding box to take account of the specified - text justification. The above process implicitly assumed a - justifiation of "BL". */ - if( !just || just[ 0 ] == 'C' || just[ 0 ] == 0 ){ - w = 0.5*( tyhi + tylo ); - tylo -= w; - tyhi -= w; - tyzero -= w; - - } else if( just[ 0 ] == 'T' ){ - w = tyhi; - tylo -= w; - tyhi -= w; - tyzero -= w; - - } else if( just[ 0 ] == 'M' ){ - w = -tylo; - tylo += w; - tyhi += w; - tyzero += w; - - } else if( just[ 0 ] != 'B' ) { - astError( AST__GRFER, "astG3DTxExt: Justification string '%s' " - "is invalid.", just ); - return 0; - } - - if( !just || just[ 1 ] == 'C' || just[ 1 ] == 0 ){ - w = 0.5*( txhi + txlo ); - txlo -= w; - txhi -= w; - - } else if( just[ 1 ] == 'R' ){ - w = txhi; - txlo -= w; - txhi -= w; - - } else if( just[ 1 ] == 'L' ){ - w = txlo; - txlo -= w; - txhi -= w; - - } else { - astError( AST__GRFER, "astG3DTxExt: Justification string '%s' " - "is invalid.", just ); - return 0; - } - -/* Use the supplied text plane axis vectors to transform the corners of - the text plane bounding box into 3D world coordinates. */ - xb[ 0 ] = tx[ 0 ]*txlo + ty[ 0 ]*tylo + ref[ 0 ]; - yb[ 0 ] = tx[ 1 ]*txlo + ty[ 1 ]*tylo + ref[ 1 ]; - zb[ 0 ] = tx[ 2 ]*txlo + ty[ 2 ]*tylo + ref[ 2 ]; - - xb[ 1 ] = tx[ 0 ]*txhi + ty[ 0 ]*tylo + ref[ 0 ]; - yb[ 1 ] = tx[ 1 ]*txhi + ty[ 1 ]*tylo + ref[ 1 ]; - zb[ 1 ] = tx[ 2 ]*txhi + ty[ 2 ]*tylo + ref[ 2 ]; - - xb[ 2 ] = tx[ 0 ]*txhi + ty[ 0 ]*tyhi + ref[ 0 ]; - yb[ 2 ] = tx[ 1 ]*txhi + ty[ 1 ]*tyhi + ref[ 1 ]; - zb[ 2 ] = tx[ 2 ]*txhi + ty[ 2 ]*tyhi + ref[ 2 ]; - - xb[ 3 ] = tx[ 0 ]*txlo + ty[ 0 ]*tyhi + ref[ 0 ]; - yb[ 3 ] = tx[ 1 ]*txlo + ty[ 1 ]*tyhi + ref[ 1 ]; - zb[ 3 ] = tx[ 2 ]*txlo + ty[ 2 ]*tyhi + ref[ 2 ]; - -/* Also transform the text plane coordinates at the bottom left of the - text baseline into 3D world coordinates. */ - bl[ 0 ] = tx[ 0 ]*txlo + ty[ 0 ]*tyzero + ref[ 0 ]; - bl[ 1 ] = tx[ 1 ]*txlo + ty[ 1 ]*tyzero + ref[ 1 ]; - bl[ 2 ] = tx[ 2 ]*txlo + ty[ 2 ]*tyzero + ref[ 2 ]; - -/* If we get here, we have been succesful, so return a non-zero value. */ - return 1; - -/* Clear local constants. */ -#undef MXLEN -} - -static float getCharHeight( void ){ -/* -* Name: -* getCharHeight - -* Purpose: -* Get the current text height setting. - -* Synopsis: -* #include "grf3d.h" -* float getCharHeight( void ) - -* Description: -* This function returns the PGPLOT character height, scaled into -* world coordinate units. - -* Returned Value: -* The character height, in world coordinate units. - -*/ - -/* Local Variables: */ - float wx1, wx2, wy1, wy2; - float ch; - -/* Get the bounds of the PGPLTO 2D window. */ - ccpgqwin( &wx1, &wx2, &wy1, &wy2 ); - -/* Get the normalised PGPLOT character height. */ - ccpgqch( &ch ); - -/* A PGPLOT character height of 1.0 corresponds to 1/40 of the 2D window - height. Scale the normalised character height into world coordinate - units, and return it. */ - return ch*fabs( wy1 - wy2 )/40.0; - -} - -static int getTextAxes( float ref[3], float up[3], float norm[3], - const char *just, float tx[3], float ty[3], - float tz[3], char newjust[3] ){ -/* -* Name: -* getTextAxes - -* Purpose: -* Get unit vectors along the text plane coordinate axes. - -* Synopsis: -* #include "grf3d.h" -* int getTextAxes( float ref[3], float up[3], float norm[3], -* const char *just, float tx[3], float ty[3], -* float tz[3], char newjust[3] ) - -* Description: -* This function returns three unit vectors that define the axes of a -* 3D Cartesian coordinate system known as "text plane coordinates". -* These axes span the plane upon which text (or other graphics) is to -* be written. The origin is at the supplied 3D reference position, the -* X axis increases along the text baseline, and Y axis increases along -* the text up vector, and Z increases from the back of the text to the -* front of the text (all are measured in 3D world coord units). -* -* The returned vectors are reversed if this will result in text -* appearing more "normal" (i.e. viewed from the front rather than -* the back, and viewed upright rather thna upside down). If the -* vectors are reversed, the justification string is also changed so -* that the text occupies the requested area on the screen. - -* Parameters: -* ref -* The reference (x,y,z) coordinates. -* up -* The (x,y,z) up-vector for the text. The actual up vector used is -* the projection of the supplied vector onto the plane specified by -* "norm". -* norm -* The (x,y,z) components of a vector that is normal to the plane -* containing the text. The given vector passes through the text -* from the back to the front. If all components of this vector are -* zero, then a normal vector pointing towards the camera eye is used. -* just -* The requested text justification, as supplied to astG3DText. -* tx -* A unit vector along the text plane X axis. -* ty -* A unit vector along the text plane X axis. -* tz -* A unit vector along the text plane X axis. -* newjust -* The text justification to use. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. -*/ - -/* Local Variables: */ - Camera *cam; - float eye[3]; - -/* Initialise the returned justification to equal the supplied - justification, supplying defaults if required. . */ - if( just ) { - strncpy( newjust, just, 2 ); - if( !newjust[ 0 ] ) newjust[ 0 ] = 'C'; - if( !newjust[ 1 ] ) newjust[ 1 ] = 'C'; - newjust[ 2 ] = 0; - } else { - strcpy( newjust, "CC" ); - } - -/* Get the Camera for the current device identifier. Abort if no camera - is available. */ - if( !( cam = getCamera( 1 ) ) ) return 0; - -/* Calculate the vector from the reference position to the eye, and store - it in "eye". */ - vectorSub( cam->eye_vector, ref, eye ); - -/* Create unit vectors along the three axes of the text plane coordinate - system. These unit vectors are represented in terms of the 3D world - coordinate axes. The text Z axis is parallel to the supplied "norm" - vector. */ - tz[ 0 ] = norm[ 0 ]; - tz[ 1 ] = norm[ 1 ]; - tz[ 2 ] = norm[ 2 ]; - -/* Attempt to normalise the "tz" vector. If it has zero length, use the - offset from the reference point to the eye. */ - if( ! vectorNorm( tz ) ){ - -/* Use the "eye" vector calculated above as the text plane Z axis. */ - tz[ 0 ] = eye[ 0 ]; - tz[ 1 ] = eye[ 1 ]; - tz[ 2 ] = eye[ 2 ]; - } - -/* Find vectors along the text plane x and y axes. */ - vectorProduct( up, tz, tx ); - vectorProduct( tz, tx, ty ); - -/* Normalise the three text plane axis vectors. If any vector has zero - length, abort. */ - if( !vectorNorm( tx ) || !vectorNorm( ty ) || !vectorNorm( tz ) ) return 0; - -/* We now reverse text plane vectors if this will help ther text to be - viewed "normally" on the screen. If the existing vectors cause the - text to be viewed from the back rather than the front, reverse the tx - and tz vectors so that he text is viewed from the front. */ - if( dotProduct( tz, eye ) < 0.0 ) { - tz[ 0 ] = -tz[ 0 ]; - tz[ 1 ] = -tz[ 1 ]; - tz[ 2 ] = -tz[ 2 ]; - tx[ 0 ] = -tx[ 0 ]; - tx[ 1 ] = -tx[ 1 ]; - tx[ 2 ] = -tx[ 2 ]; - -/* The text will have spun around the up vector (i.e. the ty axis), so - modify the horizontal justification so that thex text occupies the same - area on the screen. */ - if( newjust[ 1 ] == 'L' ) { - newjust[ 1 ] = 'R'; - } else if( newjust[ 1 ] == 'R' ) { - newjust[ 1 ] = 'L'; - } - } - -/* If the existing vectors cause the text to be viewed upside down, reverse - the tx and ty vectors so that he text is viewed right way up. */ - if( dotProduct( ty, cam->up_vector ) < 0.0 ) { - ty[ 0 ] = -ty[ 0 ]; - ty[ 1 ] = -ty[ 1 ]; - ty[ 2 ] = -ty[ 2 ]; - tx[ 0 ] = -tx[ 0 ]; - tx[ 1 ] = -tx[ 1 ]; - tx[ 2 ] = -tx[ 2 ]; - -/* The text will have spun around the tz vector (i.e. the viewing vector), - so modify both vertical and horizontal justification so that the text - occupies the same area on the screen. */ - if( newjust[ 0 ] == 'B' || newjust[ 0 ] == 'M' ) { - newjust[ 0 ] = 'T'; - } else if( newjust[ 0 ] == 'T' ) { - newjust[ 0 ] = 'M'; - } - - if( newjust[ 1 ] == 'L' ) { - newjust[ 1 ] = 'R'; - } else if( newjust[ 1 ] == 'R' ) { - newjust[ 1 ] = 'L'; - } - } - -/* If we arraive here we have been succesful, so return a non-zero value. */ - return 1; -} - -static void getSymbolList( const char *text, int mxlen, int *nlist, int *list ){ -/* -* Name: -* getSymbolList - -* Purpose: -* Get the extent of a character string. - -* Synopsis: -* #include "grf3d.h" -* void getSymbolList( const char *text, int mxlen, int *nlist, int *list ) - -* Description: -* This function converts a supplied text string into a list of PGPLOT -* symbol numbers for the current PGPLOT font. - -* Parameters: -* text -* Pointer to a null-terminated character string. -* mxlen -* The length of the "list" array. -* nlist -* Pointer to an integer in which to place the number of symbol -* values stored in the "list" array. This will be returned equal -* to zero if there are no non-blank characters in the supplied -* string. If there is one or more non-blank characters in "text", -* then the returned list will include any trailing spaces. -* list -* Pointer to an array in which to return the symbol numbers. The -* array should be at least "mxlen" elements long. -*/ - - -/* Local Variables: */ - int font; - int tlen; - -/* Assume we have no symbols. */ - *nlist = 0; - -/* Check there is something to plot. */ - if( astChrLen( text ) > 0 ) { - -/* Find the length of text that can be displayed. */ - tlen = strlen( text ); - if( tlen > mxlen ) tlen = mxlen; - -/* Get the current PGPLOT font. */ - ccpgqcf( &font ); - -/* Convert the supplied string into a list of symbol numbers */ - ccgrsyds( list, nlist, text, tlen, font ); - } -} - -static Camera *getCamera( int check ){ -/* -*+ -* Name: -* getCamera - -* Purpose: -* Return a pointer to the Camera structure for the current PGPLOT -* device. - -* Synopsis: -* #include "grf3d.h" -* Camera getCamera( int check ) - -* Description: -* This function returns a pointer to a static structure that defines the -* position and orientation of the camera in 3D world coords. It can -* be used to transform positions from 3D world coordinates (x,y,z) to -* 2D screen coordinates (h,r). - -* Parameters: -* check -* If non-zero, a check will be made that the Camera has been -* initialised, and NULL will be returned if the Camera has not -* been initialsied. If "check" is zero, a pointer to the Camera -* is returned even if it has not been initialised. - -* Returned Value: -* Pointer to the Camera, or NULL if an error occurs. -*- -*/ - -/* Local Variables: */ - int id; - Camera *cam = NULL; - -/* Get the pgplot current device identifier. Return NULL if no device is - currently open. */ - ccpgqid( &id ); - if( id > 0 && id <= MXDEV ) { - -/* Get a pointer to the required Camera structure. */ - cam = cameras + id - 1; - -/* If required, check that the structure has been initialised. */ - if( check && cam->ok_flag != CAMERA_OK ) cam = NULL; - } - - return cam; -} - -static int transform( Camera *cam, int n, float *x, float *y, float *z, - float *h, float *r ){ -/* -*+ -* Name: -* transform - -* Purpose: -* Transform positions from 3D world coords to 2D screen cooords. - -* Synopsis: -* #include "grf3d.h" -* int transform( Camera *cam, int n, float *x, float *y, float *z, -* float *h, float *r ) - -* Description: -* This function transforms a set of positions from 3D world -* coordinates (x,y,z) to 2D screen coordinates (h,r), using the -* supplied camera. - -* Parameters: -* cam -* Pointer to a structure descibing the projection from 3D world -* coords to 2D screen coords. If NULL, the camera for the current -* PGPLOT device is used. -* n -* The number of positions to transform. -* x -* An array of "n" values for the "x" axis of the 3D world -* coordinate system. -* y -* An array of "n" values for the "y" axis of the 3D world -* coordinate system. -* z -* An array of "n" values for the "z" axis of the 3D world -* coordinate system. -* h -* An array to receive the "n" values for the "h" axis of the 2D -* screen coordinate system. -* r -* An array to receive the "n" values for the "r" axis of the 2D -* screen coordinate system. - -* Returned Value: -* Zero if an error occurs. One otherwise. - -*- -*/ - -/* Local Variables: */ - float dx, dy, dz, u, v, w, f; - int i; - int result = 0; - -/* If no camera was supplied use the camera for the current PGPLOT - device. */ - if( ! cam ) cam = getCamera( 0 ); - -/* Check we now have a usable camera */ - if( cam && cam->ok_flag == CAMERA_OK ) { - result = 1; - -/* Loop round each position. */ - for( i = 0; i < n; i++ ) { - -/* Offset from supplied position to the camera eye. */ - dx = x[ i ] - (cam->eye_vector)[ 0 ]; - dy = y[ i ] - (cam->eye_vector)[ 1 ]; - dz = z[ i ] - (cam->eye_vector)[ 2 ]; - -/* Get the representation of this vector in the (u,v,w) system. */ - u = (cam->w2c_matrix)[ 0 ]*dx + - (cam->w2c_matrix)[ 1 ]*dy + - (cam->w2c_matrix)[ 2 ]*dz; - - v = (cam->w2c_matrix)[ 3 ]*dx + - (cam->w2c_matrix)[ 4 ]*dy + - (cam->w2c_matrix)[ 5 ]*dz; - - w = (cam->w2c_matrix)[ 6 ]*dx + - (cam->w2c_matrix)[ 7 ]*dy + - (cam->w2c_matrix)[ 8 ]*dz; - -/* Find the screen coords, using either a tangent plane or an - orothograhic projection. */ - if( cam->screen_distance != 0.0 ) { - if( w != 0.0 ) { - f = cam->screen_distance/w; - h[ i ] = -f*u; - r[ i ] = f*v; - } else { - h[ i ] = FLT_MAX; - r[ i ] = FLT_MAX; - } - } else { - h[ i ] = -u; - r[ i ] = v; - } - - } - } - return result; -} - - -/* Dot product of a pair of 3-vectors "a" and "b". */ -static float dotProduct( float *a, float *b ){ - return a[ 0 ]*b[ 0 ] + a[ 1 ]*b[ 1 ] + a[ 2 ]*b[ 2 ]; -} - -/* Vector product of a pair of 3-vectors "a" and "b". */ -static void vectorProduct( float *a, float *b, float *c ){ - c[ 0 ] = a[ 1 ]*b[ 2 ] - a[ 2 ]*b[ 1 ]; - c[ 1 ] = a[ 2 ]*b[ 0 ] - a[ 0 ]*b[ 2 ]; - c[ 2 ] = a[ 0 ]*b[ 1 ] - a[ 1 ]*b[ 0 ]; -} - -/* Vector from "b" to "a" (i.e. a minus b) . */ -static void vectorSub( float *a, float *b, float *c ){ - c[ 0 ] = a[ 0 ] - b[ 0 ]; - c[ 1 ] = a[ 1 ] - b[ 1 ]; - c[ 2 ] = a[ 2 ] - b[ 2 ]; -} - -/* Normalises a vector to a unit length. Returns zero if the vector has - zero length, and 1 otherwise. */ -static int vectorNorm( float *a ){ - float d; - d = vectorModulus( a ); - if( d > 0.0 ) { - a[ 0 ] /= d; - a[ 1 ] /= d; - a[ 2 ] /= d; - return 1; - } else { - return 0; - } -} - -/* Return the length of a vector. */ -static float vectorModulus( float *a ){ - return sqrtf( a[ 0 ]*a[ 0 ] + a[ 1 ]*a[ 1 ] + a[ 2 ]*a[ 2 ] ); -} - - - - - - - -/* PGPLOT interface functions */ -/* ========================== */ -static void ccpgqclp(int *clip){ - F77_INTEGER_TYPE CLIP; - F77_CALL(pgqclp)( INTEGER_ARG(&CLIP) ); - *clip = (int) CLIP; -} - -static void ccpgsclp(int clip){ - F77_INTEGER_TYPE CLIP; - CLIP = (F77_INTEGER_TYPE) clip; - F77_CALL(pgsclp)( INTEGER_ARG(&CLIP) ); -} - -static void ccpgqid(int *id){ - F77_INTEGER_TYPE ID; - F77_CALL(pgqid)( INTEGER_ARG(&ID) ); - *id = (int) ID; -} - - -static void ccpgswin(float x1, float x2, float y1, float y2){ - F77_REAL_TYPE X1; - F77_REAL_TYPE X2; - F77_REAL_TYPE Y1; - F77_REAL_TYPE Y2; - - X1 = x1; - X2 = x2; - Y1 = y1; - Y2 = y2; - - F77_CALL(pgswin)( REAL_ARG(&X1), REAL_ARG(&X2), REAL_ARG(&Y1), - REAL_ARG(&Y2) ); -} - -static void ccpgline(int n, float xpts[], float ypts[] ){ - F77_INTEGER_TYPE N; - F77_REAL_TYPE *XX; - F77_REAL_TYPE *YY; - int i; - - XX = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n ); - YY = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n ); - - if( astOK ){ - - for( i = 0; i < n; i++ ){ - XX[ i ] = (F77_REAL_TYPE) xpts[ i ]; - YY[ i ] = (F77_REAL_TYPE) ypts[ i ]; - } - - N = (F77_INTEGER_TYPE) n; - - F77_CALL(pgline)( INTEGER_ARG(&N), REAL_ARRAY_ARG(XX), - REAL_ARRAY_ARG(YY) ); - - XX = (F77_REAL_TYPE *) astFree( (void *) XX ); - YY = (F77_REAL_TYPE *) astFree( (void *) YY ); - } -} - -static void ccpgpoly(int n, float xpts[], float ypts[] ){ - F77_INTEGER_TYPE N; - F77_REAL_TYPE *XX; - F77_REAL_TYPE *YY; - int i; - - XX = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n ); - YY = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n ); - - if( astOK ){ - - for( i = 0; i < n; i++ ){ - XX[ i ] = (F77_REAL_TYPE) xpts[ i ]; - YY[ i ] = (F77_REAL_TYPE) ypts[ i ]; - } - - N = (F77_INTEGER_TYPE) n; - - F77_CALL(pgpoly)( INTEGER_ARG(&N), REAL_ARRAY_ARG(XX), - REAL_ARRAY_ARG(YY) ); - - XX = (F77_REAL_TYPE *) astFree( (void *) XX ); - YY = (F77_REAL_TYPE *) astFree( (void *) YY ); - } -} - -static void ccpgqwin(float *x1, float *x2, float *y1, float *y2){ - F77_REAL_TYPE X1; - F77_REAL_TYPE X2; - F77_REAL_TYPE Y1; - F77_REAL_TYPE Y2; - - F77_CALL(pgqwin)( REAL_ARG(&X1), REAL_ARG(&X2), REAL_ARG(&Y1), - REAL_ARG(&Y2) ); - *x1 = (float) X1; - *x2 = (float) X2; - *y1 = (float) Y1; - *y2 = (float) Y2; -} - -static void ccpgqch(float *ch){ - F77_REAL_TYPE CH; - F77_CALL(pgqch)( REAL_ARG(&CH) ); - *ch = (float) CH; -} - -static void ccpgqcf(int *cf){ - F77_INTEGER_TYPE CF; - F77_CALL(pgqcf)( INTEGER_ARG(&CF) ); - *cf = (int) CF; -} - -static void ccgrsyds( int *list, int *nlist, const char *text, int tlen, - int font ){ - F77_INTEGER_TYPE *LIST; - F77_INTEGER_TYPE NLIST; - DECLARE_CHARACTER(LTEXT,MXSTRLEN); - F77_INTEGER_TYPE FONT; - int ftext_length; - int i; - - ftext_length = tlen; - if( ftext_length > LTEXT_length ) ftext_length = LTEXT_length; - astStringExport( text, LTEXT, ftext_length ); - - LIST = (F77_INTEGER_TYPE *) astMalloc( sizeof( F77_INTEGER_TYPE )*(size_t) ftext_length ); - - if( astOK ){ - - FONT = (F77_INTEGER_TYPE) font; - - F77_CALL(grsyds)( INTEGER_ARRAY_ARG(LIST), INTEGER_ARG(&NLIST), - CHARACTER_ARG(LTEXT), INTEGER_ARG(&FONT) - TRAIL_ARG(ftext) ); - - *nlist = (int) NLIST; - for( i = 0; i < ftext_length; i++ ){ - list[ i ] = (int) LIST[ i ]; - } - - LIST = (F77_INTEGER_TYPE *) astFree( (void *) LIST ); - } -} - -static void ccgrsymk( int type, int font, int *symbol ){ - F77_INTEGER_TYPE TYPE; - F77_INTEGER_TYPE FONT; - F77_INTEGER_TYPE SYMBOL; - - TYPE = (F77_INTEGER_TYPE) type; - FONT = (F77_INTEGER_TYPE) font; - F77_CALL(grsymk)( INTEGER_ARG(&TYPE), INTEGER_ARG(&FONT), - INTEGER_ARG(&SYMBOL) ); - *symbol = (int) SYMBOL; -} - - -static void ccgrsyxd( int symbol, int *xygrid, int *unused ){ - F77_INTEGER_TYPE SYMBOL; - DECLARE_INTEGER_ARRAY(XYGRID,300); - F77_LOGICAL_TYPE UNUSED; - int i; - - SYMBOL = (F77_INTEGER_TYPE) symbol; - F77_CALL(grsyxd)( INTEGER_ARG(&SYMBOL), INTEGER_ARRAY_ARG(XYGRID), - LOGICAL_ARG(&UNUSED) ); - - *unused = ( UNUSED == F77_TRUE ); - for( i = 0; i < 5; i++ ) xygrid[ i ] = (int) XYGRID[ i ]; - for( ; i < 300; i++ ){ - xygrid[ i ] = (int) XYGRID[ i ]; - i++; - if( ( xygrid[ i ] = (int) XYGRID[ i ] ) == -64 ) break; - } -} - -static void ccpgupdt( void ){ - F77_CALL(pgupdt)(); -} - -static void ccpgqci(int *ci){ - F77_INTEGER_TYPE CI; - F77_CALL(pgqci)( INTEGER_ARG(&CI) ); - *ci = (int) CI; -} - -static void ccpgqls(int *ls){ - F77_INTEGER_TYPE LS; - F77_CALL(pgqls)( INTEGER_ARG(&LS) ); - *ls = (int) LS; -} - -static void ccpgqlw(int *lw){ - F77_INTEGER_TYPE LW; - F77_CALL(pgqlw)( INTEGER_ARG(&LW) ); - *lw = (int) LW; -} - -static void ccpgscf(int cf){ - F77_INTEGER_TYPE CF; - CF = (F77_INTEGER_TYPE) cf; - F77_CALL(pgscf)( INTEGER_ARG(&CF) ); -} - -static void ccpgsch(float ch){ - F77_REAL_TYPE CH; - CH = (F77_REAL_TYPE) ch; - F77_CALL(pgsch)( REAL_ARG(&CH) ); -} - -static void ccpgsci(int ci){ - F77_INTEGER_TYPE CI; - CI = (F77_INTEGER_TYPE) ci; - F77_CALL(pgsci)( INTEGER_ARG(&ci) ); -} - -static void ccpgsls(int ls){ - F77_INTEGER_TYPE LS; - LS = (F77_INTEGER_TYPE) ls; - F77_CALL(pgsls)( INTEGER_ARG(&LS) ); -} - -static void ccpgslw(int lw){ - F77_INTEGER_TYPE LW; - LW = (F77_INTEGER_TYPE) lw; - F77_CALL(pgslw)( INTEGER_ARG(&LW) ); -} - -static void ccpgqvsz(int units, float *x1, float *x2, float *y1, float *y2){ - F77_INTEGER_TYPE UNITS; - F77_REAL_TYPE X1; - F77_REAL_TYPE X2; - F77_REAL_TYPE Y1; - F77_REAL_TYPE Y2; - - UNITS = (F77_INTEGER_TYPE) units; - F77_CALL(pgqvsz)( INTEGER_ARG(&UNITS), REAL_ARG(&X1), REAL_ARG(&X2), - REAL_ARG(&Y1), REAL_ARG(&Y2) ); - *x1 = (float) X1; - *x2 = (float) X2; - *y1 = (float) Y1; - *y2 = (float) Y2; -} - - - -/* Fortran interfaces for public functions in this module. */ -/* ======================================================= */ - - -F77_LOGICAL_FUNCTION(pg3d_findnearest)( INTEGER(N), - REAL_ARRAY(X), - REAL_ARRAY(Y), - REAL_ARRAY(Z), - INTEGER(ICLOSE) ){ - GENPTR_INTEGER(N) - GENPTR_REAL_ARRAY(X) - GENPTR_REAL_ARRAY(Y) - GENPTR_REAL_ARRAY(Z) - GENPTR_INTEGER(ICLOSE) - return PG3DFindNearest( *N, X, Y, Z, ICLOSE ) ? F77_TRUE : F77_FALSE; -} - - - -F77_LOGICAL_FUNCTION(pg3d_setcamera)( REAL_ARRAY(EYE), - REAL_ARRAY(TARGET), - REAL_ARRAY(UP), - REAL(SCREEN) ){ - GENPTR_REAL_ARRAY(EYE) - GENPTR_REAL_ARRAY(TARGET) - GENPTR_REAL_ARRAY(UP) - GENPTR_REAL(SCREEN) - return PG3DSetCamera( EYE, TARGET, UP, *SCREEN ) ? F77_TRUE : F77_FALSE; -} - - -F77_LOGICAL_FUNCTION(pg3d_autocamera)( REAL_ARRAY(LBND), - REAL_ARRAY(UBND) ){ - GENPTR_REAL_ARRAY(LBND) - GENPTR_REAL_ARRAY(UBND) - return PG3DAutoCamera( LBND, UBND ) ? F77_TRUE : F77_FALSE; -} - -F77_LOGICAL_FUNCTION(pg3d_seteye)( REAL_ARRAY(EYE) ){ - GENPTR_REAL_ARRAY(EYE) - return PG3DSetEye( EYE ) ? F77_TRUE : F77_FALSE; -} - -F77_LOGICAL_FUNCTION(pg3d_setup)( REAL_ARRAY(UP) ){ - GENPTR_REAL_ARRAY(UP) - return PG3DSetUp( UP ) ? F77_TRUE : F77_FALSE; -} - -F77_LOGICAL_FUNCTION(pg3d_rotateeye)( INTEGER(DIR), REAL(ANGLE) ){ - GENPTR_INTEGER(DIR) - GENPTR_REAL(ANGLE) - return PG3DRotateEye( *DIR, *ANGLE ) ? F77_TRUE : F77_FALSE; -} - -F77_LOGICAL_FUNCTION(pg3d_forward)( REAL(DISTANCE) ){ - GENPTR_REAL(DISTANCE) - return PG3DForward( *DISTANCE ) ? F77_TRUE : F77_FALSE; -} - -F77_LOGICAL_FUNCTION(ast_g3dmark)( INTEGER(N), - REAL_ARRAY(X), - REAL_ARRAY(Y), - REAL_ARRAY(Z), - INTEGER(TYPE), - REAL_ARRAY(NORM)){ - GENPTR_INTEGER(N) - GENPTR_REAL_ARRAY(X) - GENPTR_REAL_ARRAY(Y) - GENPTR_REAL_ARRAY(Z) - GENPTR_INTEGER(TYPE) - GENPTR_REAL_ARRAY(NORM) - return astG3DMark( *N, X, Y, Z, *TYPE, NORM ) ? F77_TRUE : F77_FALSE; - -} - -F77_LOGICAL_FUNCTION(ast_g3dline)( INTEGER(N), - REAL_ARRAY(X), - REAL_ARRAY(Y), - REAL_ARRAY(Z) ){ - GENPTR_INTEGER(N) - GENPTR_REAL_ARRAY(X) - GENPTR_REAL_ARRAY(Y) - GENPTR_REAL_ARRAY(Z) - return astG3DLine( *N, X, Y, Z ) ? F77_TRUE : F77_FALSE; - -} - - -F77_INTEGER_FUNCTION(ast_g3dtext)( CHARACTER(TEXT), - REAL_ARRAY(REF), - CHARACTER(JUST), - REAL_ARRAY(UP), - REAL_ARRAY(NORM) - TRAIL(TEXT) - TRAIL(JUST) ){ - GENPTR_CHARACTER(TEXT) - GENPTR_REAL_ARRAY(REF) - GENPTR_CHARACTER(JUST) - GENPTR_REAL_ARRAY(UP) - GENPTR_REAL_ARRAY(NORM) - F77_INTEGER_TYPE(RESULT); - char *text, *just, *p; - - text = astString( TEXT, TEXT_length ); - just = astString( JUST, JUST_length ); - -/* Ignore trailing spaces in the text */ - p = text + TEXT_length; - while( !*p || *p == ' ' ) *(p--) = 0; - - if( astOK ) { - RESULT = (F77_INTEGER_TYPE) astG3DText( text, REF, just, UP, NORM ); - } else { - RESULT = 0; - } - - (void) astFree( text ); - (void) astFree( just ); - - return RESULT; -} - -F77_INTEGER_FUNCTION(ast_g3dtxext)( CHARACTER(TEXT), - REAL_ARRAY(REF), - CHARACTER(JUST), - REAL_ARRAY(UP), - REAL_ARRAY(NORM), - REAL_ARRAY(XB), - REAL_ARRAY(YB), - REAL_ARRAY(ZB), - REAL_ARRAY(BL) - TRAIL(TEXT) - TRAIL(JUST) ){ - GENPTR_CHARACTER(TEXT) - GENPTR_REAL_ARRAY(REF) - GENPTR_CHARACTER(JUST) - GENPTR_REAL_ARRAY(UP) - GENPTR_REAL_ARRAY(NORM) - GENPTR_REAL_ARRAY(XB) - GENPTR_REAL_ARRAY(YB) - GENPTR_REAL_ARRAY(ZB) - GENPTR_REAL_ARRAY(BL) - F77_INTEGER_TYPE(RESULT); - char *text, *just, *p; - - text = astString( TEXT, TEXT_length ); - just = astString( JUST, JUST_length ); - -/* Ignore trailing spaces in the text */ - p = text + TEXT_length; - while( !*p || *p == ' ' ) *(p--) = 0; - - if( astOK ) { - RESULT = (F77_INTEGER_TYPE) astG3DTxExt( text, REF, just, UP, NORM, - XB, YB, ZB, BL ); - } else { - RESULT = 0; - } - - (void) astFree( text ); - (void) astFree( just ); - - return RESULT; -} - - diff --git a/ast/grf_2.0.c b/ast/grf_2.0.c deleted file mode 100644 index 170c191..0000000 --- a/ast/grf_2.0.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -* Name: -* grf_2.0.c - -* Purpose: -* Implement the grf module required by AST V2.0 if no graphics system -* is available. - -* Description: -* This file implements the low level graphics functions required -* by the rest of AST V2.0, by reporting errors when called. - -* Inheritance: -* This module is not a class and does not inherit. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 23-OCT-1996 (DSB): -* Original version. -* 13-NOV-1996 (DSB): -* Modified to issue error messages using astError instead of printf. -* 23-NOV-2004 (DSB): -* Renamed from grf_null.c -*/ - -/* Header files */ -/* ============ */ -#include "grf.h" /* Declare the functions in this module */ -#include "error.h" /* AST error reporting facilities */ -#include "ast_err.h" /* AST error codes */ - -/* Function Prototypes */ -/* =================== */ -static void Report( const char * ); - -/* Function definitions */ -/* ==================== */ -int astGFlush( void ){ - Report( "astGFlush"); - return 0; -} - -int astGLine( int n, const float *x, const float *y ){ - Report( "astGLine" ); - return 0; -} - -int astGQch( float *chv, float *chh ){ - Report( "astGQch" ); - return 0; -} - -int astGMark( int n, const float *x, const float *y, int type ){ - Report( "astGMark" ); - return 0; -} - -int astGText( const char *text, float x, float y, const char *just, - float upx, float upy ){ - Report( "astGText" ); - return 0; -} - -int astGTxExt( const char *text, float x, float y, const char *just, - float upx, float upy, float *xb, float *yb ){ - Report( "astGTxExt" ); - return 0; -} - -int astGAttr( int attr, double value, double *old_value, int prim ){ - Report( "astGAttr" ); - return 0; -} - -static void Report( const char *name ){ - astError( AST__GRFER, "%s: No graphics facilities are available.", name ); - astError( AST__GRFER, "Re-link using an option such as '-pgplot' with " - "the ast_link script." ); -} diff --git a/ast/grf_3.2.c b/ast/grf_3.2.c deleted file mode 100644 index d6fc1a1..0000000 --- a/ast/grf_3.2.c +++ /dev/null @@ -1,74 +0,0 @@ -/* -* Name: -* grf_3.2.c - -* Purpose: -* Implement the grf module required by AST V3.2 if no graphics system -* is available. - -* Description: -* This file implements the low level graphics functions required -* by the rest of AST V3.2, except for those already defined in -* grf_2.0.c (i.e. those needed by AST V2.0). These implementations -* simply report an error when called. - -* Inheritance: -* This module is not a class and does not inherit. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 23-NOV-2004 (DSB): -* Original version. -*/ - -/* Header files */ -/* ============ */ -#include "grf.h" /* Declare the functions in this module */ -#include "error.h" /* AST error reporting facilities */ -#include "ast_err.h" /* AST error codes */ - -/* Function Prototypes */ -/* =================== */ -static void Report( const char * ); - -/* Function definitions */ -/* ==================== */ -int astGScales( float *alpha, float *beta ){ - Report( "astGScales" ); - return 0; -} - -int astGCap( int cap, int value ){ - return 0; -} - -static void Report( const char *name ){ - astError( AST__GRFER, "%s: The graphics facilities implement by %s " - "(introduced at AST V3.2) are needed but are unavailable.", - name, name ); - astError( AST__GRFER, "Re-link using a suitable option such as '-pgplot' " - "with the ast_link script, or add an implementation of this " - "function to your 'grf' module." ); -} diff --git a/ast/grf_5.6.c b/ast/grf_5.6.c deleted file mode 100644 index 3a77f58..0000000 --- a/ast/grf_5.6.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -* Name: -* grf_5.6.c - -* Purpose: -* Implement the grf module required by AST V5.6 if no graphics system -* is available. - -* Description: -* This file implements the low level graphics functions required -* by the rest of AST V5.6, except for those already defined in -* earlier grf_xxx.c files (i.e. those needed by ealier versions -* of AST). These implementations simply report an error when called. - -* Inheritance: -* This module is not a class and does not inherit. - -* Copyright: -* Copyright (C) 2011 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 4-MAR-2011 (DSB): -* Original version. -*/ - -/* Header files */ -/* ============ */ -#include "grf.h" /* Declare the functions in this module */ -#include "error.h" /* AST error reporting facilities */ -#include "ast_err.h" /* AST error codes */ - -/* Function Prototypes */ -/* =================== */ -static void Report( const char * ); - -/* Function definitions */ -/* ==================== */ -int astGBBuf( void ){ - Report( "astGBBuf" ); - return 0; -} - -int astGEBuf( void ){ - Report( "astGEBuf" ); - return 0; -} - -static void Report( const char *name ){ - astError( AST__GRFER, "%s: The graphics facilities implement by %s " - "(introduced at AST V5.6) are needed but are unavailable.", - name, name ); - astError( AST__GRFER, "Re-link using a suitable option such as '-pgplot' " - "with the ast_link script, or add an implementation of this " - "function to your 'grf' module." ); -} - - diff --git a/ast/grf_null.c b/ast/grf_null.c deleted file mode 100644 index ef7a97e..0000000 --- a/ast/grf_null.c +++ /dev/null @@ -1,98 +0,0 @@ -/* -* Name: -* grf_null.c - -* Purpose: -* Implement the grf module if no graphics system is available. - -* Description: -* This file implements the low level graphics functions required -* by the rest of AST, by reporting errors when called. - -* Inheritance: -* This module is not a class and does not inherit. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 23-OCT-1996 (DSB): -* Original version. -* 13-NOV-1996 (DSB): -* Modified to issue error messages using astError instead of printf. -*/ - -/* Header files */ -/* ============ */ -#include "grf.h" /* Declare the functions in this module */ -#include "error.h" /* AST error reporting facilities */ -#include "ast_err.h" /* AST error codes */ - -/* Function Prototypes */ -/* =================== */ -static void Report( const char * ); - -/* Function definitions */ -/* ==================== */ -int astGFlush( void ){ - Report( "astGFlush"); - return 0; -} - -int astGLine( int n, const float *x, const float *y ){ - Report( "astGLine" ); - return 0; -} - -int astGQch( float *chv, float *chh ){ - Report( "astGQch" ); - return 0; -} - -int astGMark( int n, const float *x, const float *y, int type ){ - Report( "astGMark" ); - return 0; -} - -int astGText( const char *text, float x, float y, const char *just, - float upx, float upy ){ - Report( "astGText" ); - return 0; -} - -int astGTxExt( const char *text, float x, float y, const char *just, - float upx, float upy, float *xb, float *yb ){ - Report( "astGTxExt" ); - return 0; -} - -int astGAttr( int attr, double value, double *old_value, int prim ){ - Report( "astGAttr" ); - return 0; -} - -static void Report( const char *name ){ - astError( AST__GRFER, "%s: No graphics facilities are available.", name ); - astError( AST__GRFER, "Re-link using an option such as '-pgplot' with " - "the ast_link script." ); -} diff --git a/ast/grf_pgplot.c b/ast/grf_pgplot.c deleted file mode 100644 index d0b1193..0000000 --- a/ast/grf_pgplot.c +++ /dev/null @@ -1,1494 +0,0 @@ -/* -* Name: -* grf_pgplot.c - -* Purpose: -* Implement the grf module using the PGPLOT graphics system. - -* Description: -* This file implements the low level graphics functions required -* by the rest of AST, by calling suitable PGPLOT functions (the -* FORTRAN PGPLOT interface is used). -* -* This file can be used as a template for the development of -* similar modules to support alternative graphics systems. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 27-JUN-1996 (DSB): -* Original version. -* 13-NOV-1996 (DSB): -* Use C wrappers for PGPLOT functions. -* 15-NOV-1996 (RFWS): -* Merged the C interface to PGPLOT into this file so that the -* interface functions can be static. -* 7-OCT-1997 (DSB): -* Corrected astGText and astGTxExt, by including a check for -* reversed axes. Previously, the up-vector was used as supplied -* even if the axes had been reversed. -* 15-OCT-1997 (DSB): -* o Corrected astGText and astGTxExt to take account of non-equal -* scales on the two axes. -* o Modified astGTxExt so that it includes any leading or trailing -* spaces in the returned box. -* o Added astGAxScale. -* 28-OCT-1998 (DSB): -* o Changed interpretation of the Width attribute from inches, to -* a multiple of a small line width. -* o Wrapper for pgplot F77 subroutine PGQVSZ added. -* 30-JAN-2004 (DSB): -* o Added GCap -* o Renamed GAxScale as GScales -* 4-MAR-2011 (DSB): -* Added astGBBuf and astGEBuf. -*/ - -/* Macros */ -/* ====== */ -#define MXSTRLEN 80 /* String length at which truncation starts - within pgqtxt and pgptxt. */ - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ -#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */ -#include "c2f77.h" /* C to FORTRAN interface functions */ -#include "pointset.h" /* Defines AST__BAD */ -#include "memory.h" /* Memory allocation facilities */ -#include "error.h" /* Error reporting facilities */ -#include "grf.h" /* Interface to this module */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include - -/* Constants. */ -/* ========== */ -#define R2D 57.29578 /* Radians to degrees factor */ - -/* Function Prototypes. */ -/* ==================== */ -/* These define a local C interface to the PGPLOT library. */ -static void ccpgline(int n, float xpts[], float ypts[] ); -static void ccpgpt(int n, float xpts[], float ypts[], int symbol); -static void ccpgptxt(float x, float y, float angle, float fjust, char *text ); -static void ccpgqcf(int *cf); -static void ccpgqch(float *ch); -static void ccpgqci(int *ci); -static void ccpglen(int units, char *text, float *xl, float *yl); -static void ccpgqcs(int units, float *xch, float *ych); -static void ccpgqls(int *ls); -static void ccpgqlw(int *lw); -static void ccpgqtbg(int *tbci); -static void ccpgqtxt(float x, float y, float angle, float fjust, char *text, float xbox[], float ybox[]); -static void ccpgqvp(int units, float *x1, float *x2, float *y1, float *y2); -static void ccpgqvsz(int units, float *x1, float *x2, float *y1, float *y2); -static void ccpgqwin(float *x1, float *x2, float *y1, float *y2); -static void ccpgscf(int cf); -static void ccpgsch(float ch); -static void ccpgsci(int ci); -static void ccpgsls(int ls); -static void ccpgslw(int lw); -static void ccpgstbg(int tbci); -static void ccpgupdt( void ); -static void ccpgbbuf( void ); -static void ccpgebuf( void ); - -/* These describe the native Fortran interface to the PGPLOT library. The - macros used come from the "f77.h" include file. */ -F77_SUBROUTINE(pgline)( INTEGER(n), REAL_ARRAY(x), REAL_ARRAY(y) ); -F77_SUBROUTINE(pgpt)( INTEGER(n), REAL_ARRAY(x), REAL_ARRAY(y), INTEGER(TYPE) ); -F77_SUBROUTINE(pgptxt)( REAL(x), REAL(y), REAL(angle), REAL(fjust), CHARACTER(text) TRAIL(text) ); -F77_SUBROUTINE(pgqcf)( INTEGER(ival) ); -F77_SUBROUTINE(pgqch)( REAL(rval) ); -F77_SUBROUTINE(pgqci)( INTEGER(ival) ); -F77_SUBROUTINE(pgqcs)( INTEGER(units), REAL(chv), REAL(chh) ); -F77_SUBROUTINE(pglen)( INTEGER(units), CHARACTER(text), REAL(xl), REAL(yl) TRAIL(text) ); -F77_SUBROUTINE(pgqls)( INTEGER(ival) ); -F77_SUBROUTINE(pgqlw)( INTEGER(ival) ); -F77_SUBROUTINE(pgqtbg)( INTEGER(tbg) ); -F77_SUBROUTINE(pgqtxt)( REAL(x), REAL(y), REAL(angle), REAL(fjust), CHARACTER(text), REAL_ARRAY(xbox), REAL_ARRAY(ybox) TRAIL(text) ); -F77_SUBROUTINE(pgqvp)( INTEGER(units), REAL(vx1), REAL(vx2), REAL(vy1), REAL(vy2) ); -F77_SUBROUTINE(pgqvsz)( INTEGER(units), REAL(x1), REAL(x2), REAL(y1), REAL(y2) ); -F77_SUBROUTINE(pgqwin)( REAL(wx1), REAL(wx2), REAL(wy1), REAL(wy2) ); -F77_SUBROUTINE(pgscf)( INTEGER(ival) ); -F77_SUBROUTINE(pgsch)( REAL(rval) ); -F77_SUBROUTINE(pgsci)( INTEGER(ival) ); -F77_SUBROUTINE(pgsls)( INTEGER(ival) ); -F77_SUBROUTINE(pgslw)( INTEGER(ival) ); -F77_SUBROUTINE(pgstbg)( INTEGER(tbg) ); -F77_SUBROUTINE(pgupdt)( ); -F77_SUBROUTINE(pgbbuf)( ); -F77_SUBROUTINE(pgebuf)( ); - -/* Externally visible functions. */ -/* ============================= */ -/* These implement the "grf" interface in terms of the local C interface - to PGPLOT. */ -int astGBBuf( void ){ -/* -*+ -* Name: -* astGBBuf - -* Purpose: -* Start a new graphics buffering context. - -* Synopsis: -* #include "grf.h" -* int astGBBuf( void ) - -* Description: -* This function begins saving graphical output commands in an -* internal buffer; the commands are held until a matching astGEBuf -* call (or until the buffer is emptied by astGFlush). This can -* greatly improve the efficiency of some graphics systems. astGBBuf -* increments an internal counter, while astGEBuf decrements this -* counter and flushes the buffer to the output device when the -* counter drops to zero. astGBBuf and astGEBuf calls should always -* be paired. - -* Parameters: -* None. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -*- -*/ - ccpgbbuf(); - return 1; -} - -int astGEBuf( void ){ -/* -*+ -* Name: -* astGEBuf - -* Purpose: -* End a graphics buffering context. - -* Synopsis: -* #include "grf.h" -* int astGEBuf( void ) - -* Description: -* This function marks the end of a batch of graphical output begun -* with the last call of astGBBuf. astGBBuf and astGEBUF calls should -* always be paired. Each call to astGBBuf increments a counter, while -* each call to astGEBuf decrements the counter. When the counter -* reaches 0, the batch of output is written on the output device. - -* Parameters: -* None. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -*- -*/ - ccpgebuf(); - return 1; -} - -int astGFlush( void ){ -/* -*+ -* Name: -* astGFlush - -* Purpose: -* Flush all pending graphics to the output device. - -* Synopsis: -* #include "grf.h" -* int astGFlush( void ) - -* Description: -* This function ensures that the display device is up-to-date, -* by flushing any pending graphics to the output device. - -* Parameters: -* None. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -*- -*/ - - ccpgupdt(); - return 1; -} - -int astGCap( int cap, int value ){ -/* -*+ -* Name: -* astGCap - -* Purpose: -* Indicate if this grf module has a given capability. - -* Synopsis: -* #include "grf.h" -* int astGCap( int cap, int value ) - -* Description: -* This function is called by the AST Plot class to determine if the -* grf module has a given capability, as indicated by the "cap" -* argument. - -* Parameters: -* cap -* The capability being inquired about. This will be one of the -* following constants defined in grf.h: -* -* GRF__SCALES: This function should return a non-zero value if -* it implements the astGScales function, and zero otherwise. The -* supplied "value" argument should be ignored. -* -* GRF__MJUST: This function should return a non-zero value if -* the astGText and astGTxExt functions recognise "M" as a -* character in the justification string. If the first character of -* a justification string is "M", then the text should be justified -* with the given reference point at the bottom of the bounding box. -* This is different to "B" justification, which requests that the -* reference point be put on the baseline of the text, since some -* characters hang down below the baseline. If the astGText or -* astGTxExt function cannot differentiate between "M" and "B", -* then this function should return zero, in which case "M" -* justification will never be requested by Plot. The supplied -* "value" argument should be ignored. -* -* GRF__ESC: This function should return a non-zero value if the -* astGText and astGTxExt functions can recognise and interpret -* graphics escape sequences within the supplied string. These -* escape sequences are described below. Zero should be returned -* if escape sequences cannot be interpreted (in which case the -* Plot class will interpret them itself if needed). The supplied -* "value" argument should be ignored only if escape sequences cannot -* be interpreted by astGText and astGTxExt. Otherwise, "value" -* indicates whether astGText and astGTxExt should interpret escape -* sequences in subsequent calls. If "value" is non-zero then -* escape sequences should be interpreted by astGText and -* astGTxExt. Otherwise, they should be drawn as literal text. - -* Returned Value: -* The return value, as described above. Zero should be returned if -* the supplied capability is not recognised. - -* Escape Sequences: -* Escape sequences are introduced into the text string by a percent -* "%" character. The following escape sequences are currently recognised -* ("..." represents a string of one or more decimal digits): -* -* %% - Print a literal "%" character (type GRF__ESPER ). -* -* %^...+ - Draw subsequent characters as super-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the super-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text (type GRF__ESSUP ). -* %^+ - Draw subsequent characters with the normal base-line. -* -* %v...+ - Draw subsequent characters as sub-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the sub-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text (type GRF__ESSUB ). -* -* %v+ - Draw subsequent characters with the normal base-line -* (equivalent to %^+). -* -* %>...+ - Leave a gap before drawing subsequent characters. -* The digits "..." give the size of the gap, scaled -* so that a value of "100" corresponds to the height of -* "normal" text (type GRF__ESGAP ). -* -* %<...+ - Move backwards before drawing subsequent characters. -* The digits "..." give the size of the movement, scaled -* so that a value of "100" corresponds to the height of -* "normal" text (type GRF_ESBAC). -* -* %s...+ - Change the Size attribute for subsequent characters. The -* digits "..." give the new Size as a fraction of the -* "normal" Size, scaled so that a value of "100" corresponds -* to 1.0 (type GRF__ESSIZ ). -* -* %s+ - Reset the Size attribute to its "normal" value. -* -* %w...+ - Change the Width attribute for subsequent characters. The -* digits "..." give the new width as a fraction of the -* "normal" Width, scaled so that a value of "100" corresponds -* to 1.0 (type GRF__ESWID ). -* -* %w+ - Reset the Size attribute to its "normal" value. -* -* %f...+ - Change the Font attribute for subsequent characters. The -* digits "..." give the new Font value (type GRF__ESFON ). -* -* %f+ - Reset the Font attribute to its "normal" value. -* -* %c...+ - Change the Colour attribute for subsequent characters. The -* digits "..." give the new Colour value (type GRF__ESCOL ). -* -* %c+ - Reset the Colour attribute to its "normal" value. -* -* %t...+ - Change the Style attribute for subsequent characters. The -* digits "..." give the new Style value (type GRF__ESSTY ). -* -* %t+ - Reset the Style attribute to its "normal" value. -* -* %- - Push the current graphics attribute values onto the top of -* the stack - see "%+" (type GRF__ESPSH). -* -* %+ - Pop attributes values of the top the stack - see "%-". If -* the stack is empty, "normal" attribute values are restored -* (type GRF__ESPOP). -* -* The astFindEscape function (in libast.a) can be used to locate escape -* sequences within a text string. It has the following signature: -* -* #include "plot.h" -* int astFindEscape( const char *text, int *type, int *value, int *nc ) -* -* Parameters: -* text -* Pointer to the string to be checked. -* type -* Pointer to a location at which to return the type of escape -* sequence. Each type is identified by a symbolic constant defined -* in grf.h and is indicated in the above section. The returned value -* is undefined if the supplied text does not begin with an escape -* sequence. -* value -* Pointer to a lcation at which to return the integer value -* associated with the escape sequence. All usable values will be -* positive. Zero is returned if the escape sequence has no associated -* integer. A value of -1 indicates that the attribute identified by -* "type" should be reset to its "normal" value (as established using -* the astGAttr function, etc). The returned value is undefined if -* the supplied text does not begin with an escape sequence. -* nc -* Pointer to a location at which to return the number of -* characters read by this call. If the text starts with an escape -* sequence, the returned value will be the number of characters in -* the escape sequence. Otherwise, the returned value will be the -* number of characters prior to the first escape sequence, or the -* length of the supplied text if no escape sequence is found. - -* Returned Value: -* A non-zero value is returned if the supplied text starts with a -* graphics escape sequence, and zero is returned otherwise. - -*- -*/ - - int result = 0; - if( cap == GRF__SCALES ) result = 1; - return result; -} - -int astGLine( int n, const float *x, const float *y ){ -/* -*+ -* Name: -* astGLine - -* Purpose: -* Draw a polyline (i.e. a set of connected lines). - -* Synopsis: -* #include "grf.h" -* int astGLine( int n, const float *x, const float *y ) - -* Description: -* This function displays lines joining the given positions. - -* Parameters: -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Nothing is done if "n" is less than 2, or if a NULL pointer is -* given for either "x" or "y". - -*- -*/ - - if( n > 1 && x && y ) ccpgline( n, (float *) x, (float *) y ); - return 1; -} - -int astGMark( int n, const float *x, const float *y, int type ){ -/* -*+ -* Name: -* astGMark - -* Purpose: -* Draw a set of markers. - -* Synopsis: -* #include "grf.h" -* int astGMark( int n, const float *x, const float *y, int type ) - -* Description: -* This function displays markers at the given positions. - -* Parameters: -* n -* The number of markers to draw. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* type -* An integer which can be used to indicate the type of marker symbol -* required. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Nothing is done if "n" is less than 1, or if a NULL pointer is -* given for either "x" or "y". - -*- -*/ - - if( n > 0 && x && y ) ccpgpt( n, (float *) x, (float *) y, type ); - return 1; -} - -int astGText( const char *text, float x, float y, const char *just, - float upx, float upy ){ -/* -*+ -* Name: -* astGText - -* Purpose: -* Draw a character string. - -* Synopsis: -* #include "grf.h" -* int astGText( const char *text, float x, float y, const char *just, -* float upx, float upy ) - -* Description: -* This function displays a character string at a given position -* using a specified justification and up-vector. - -* Parameters: -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - Any graphics within the rotated box enclosing the text are erased. -* - A NULL value for "just" causes a value of "CC" to be used. -* - Both "upx" and "upy" being zero causes an error. -* - Any unrecognised character in "just" causes an error. -*- -*/ - -/* Local Variables: */ - char lj[ 2 ]; - float uplen, xbox[ 4 ], ybox[ 4 ]; - float angle, fjust, hu, test, alpha, beta; - int i, tbg; - -/* Check that there is something to draw. */ - if( text && text[ 0 ] != 0 ){ - -/* Fill in any missing parts of the justification string. */ - if( just ){ - if( just[ 0 ] == 'T' || just[ 0 ] == 'C' || just[ 0 ] == 'B' ){ - lj[ 0 ] = just[ 0 ]; - } else { - astError( AST__GRFER, "astGText: Justification string '%s' is " - "invalid.", just ); - return 0; - } - - if( just[ 1 ] == 'L' || just[ 1 ] == 'C' || just[ 1 ] == 'R' ){ - lj[ 1 ] = just[ 1 ]; - } else { - astError( AST__GRFER, "astGText: Justification string '%s' " - "is invalid.", just ); - return 0; - } - - } else { - lj[ 0 ] = 'C'; - lj[ 1 ] = 'C'; - } - -/* Find the conversion factors between increment in world coordinate axes, - and the corresponding increments in millimetres ( Xmm = alpha*Xworld, - Ymm = beta*Yworld ). */ - if( !astGScales( &alpha, &beta ) ) return 0; - -/* If either axis is reversed, reverse the supplied up-vector components - so that they refer to the world-coordinates axes. */ - if( alpha < 0.0 ) upx = -upx; - if( beta < 0.0 ) upy = -upy; - -/* Get the angle between the text base-line and horizontal. */ - angle = atan2( -(double) upx*alpha, (double) upy*beta )*R2D; - -/* Get the fractional horizontal justification as needed by PGPLOT. */ - if( lj[ 1 ] == 'L' ) { - fjust = 0.0; - } else if( lj[ 1 ] == 'R' ) { - fjust = 1.0; - } else { - fjust = 0.5; - } - -/* Unless the requested justification is "Bottom", we need to adjust - the supplied reference position before we use it with PGPLOT because - PGPLOT assumes "Bottom" justification. */ - if( lj[0] != 'B' ) { - -/* Get the bounding box of the string. Note, only the size of the box is - significant here, not its position. Also note, leading and trailing - spaces are not included in the bounding box. */ - ccpgqtxt( x, y, angle, fjust, (char *) text, xbox, ybox ); - -/* Normalise the up-vector in world coordinates. */ - uplen = sqrt( (double) (upx*upx + upy*upy) ); - if( uplen > 0.0 ){ - upx /= uplen; - upy /= uplen; - } else { - astError( AST__GRFER, "astGText: Zero length up-vector supplied."); - return 0; - } - -/* Find the height of the text above the base-line. Note, the PGPLOT - manual is not clear about the order of the corners returned by - pgqtxt, so we have to find the largest distance between - the corners in the direction of the supplied up-vector. */ - hu = 0.0; - for( i = 0; i < 4; i++ ){ - test = upx*( xbox[ i ] - x ) + upy*( ybox[ i ] - y ); - if( test > hu ) hu = test; - } - -/* Adjust the vertical position of the reference point, since PGPLOT - requires it to be at the bottom of the text. */ - if( lj[ 0 ] == 'T' ){ - x -= upx*hu; - y -= upy*hu; - } else if( lj[ 0 ] == 'C' ){ - x -= 0.5*upx*hu; - y -= 0.5*upy*hu; - } - } - -/* Display the text, erasing any graphics. */ - ccpgqtbg( &tbg ); - ccpgstbg( 0 ); - ccpgptxt( x, y, angle, fjust, (char *) text ); - ccpgstbg( tbg ); - } - -/* Return. */ - return 1; -} - -int astGScales( float *alpha, float *beta ){ -/* -*+ -* Name: -* astGScales - -* Purpose: -* Get the axis scales. - -* Synopsis: -* #include "grf.h" -* int astGScales( float *alpha, float *beta ) - -* Description: -* This function returns two values (one for each axis) which scale -* increments on the corresponding axis into a "normal" coordinate -* system in which: -* 1 - The axes have equal scale in terms of (for instance) -* millimetres per unit distance. -* 2 - X values increase from left to right. -* 3 - Y values increase from bottom to top. - -* Parameters: -* alpha -* A pointer to the location at which to return the scale for the -* X axis (i.e. Xnorm = alpha*Xworld). -* beta -* A pointer to the location at which to return the scale for the -* Y axis (i.e. Ynorm = beta*Yworld). - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -*- -*/ - -/* Local Variables: */ - float nx1, nx2, ny1, ny2, wx1, wx2, wy1, wy2; - int ret; - -/* Find the conversion factors between increment in world coordinate axes, - and the corresponding increments in millimetres ( Xmm = alpha*Xworld, - Ymm = beta*Yworld ). */ - ccpgqvp( 2, &nx1, &nx2, &ny1, &ny2 ); - ccpgqwin( &wx1, &wx2, &wy1, &wy2 ); - - if( wx2 != wx1 && wy2 != wy1 && - nx2 != nx1 && ny2 != ny1 ) { - *alpha= ( nx2 - nx1 ) / ( wx2 - wx1 ); - *beta = ( ny2 - ny1 ) / ( wy2 - wy1 ); - ret = 1; - } else { - astError( AST__GRFER, "astGScales: The graphics window or viewport has zero size." ); - ret = 0; - } - - return ret; -} - -int astGTxExt( const char *text, float x, float y, const char *just, - float upx, float upy, float *xb, float *yb ){ -/* -*+ -* Name: -* astGTxExt - -* Purpose: -* Get the extent of a character string. - -* Synopsis: -* #include "grf.h" -* int astGTxExt( const char *text, float x, float y, const char *just, -* float upx, float upy, float *xb, float *yb ) - -* Description: -* This function returns the corners of a box which would enclose the -* supplied character string if it were displayed using astGText. -* -* The returned box INCLUDES any leading or trailing spaces. - -* Parameters: -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. -* xb -* An array of 4 elements in which to return the x coordinate of -* each corner of the bounding box. -* yb -* An array of 4 elements in which to return the y coordinate of -* each corner of the bounding box. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: -* - The order of the corners is anti-clockwise (in world coordinates) -* starting at the bottom left. -* - A NULL value for "just" causes a value of "CC" to be used. -* - Both "upx" and "upy" being zero causes an error. -* - Any unrecognised character in "just" causes an error. -* - Zero is returned for all bounds of the box if an error occurs. - -*- -*/ - -/* Local Variables: */ - char lj[ 2 ]; - float udx, udy, vdx, vdy, vx, vy, uplen, xbox[ 4 ], - ybox[ 4 ], uxu, uyu, uxd, uyd, ux, uy; - float angle, width, test, xl, yl; - float alpha, beta, xc, yc, hu, hd, a, b; - int i; - -/* Initialise the returned values to indicate no box available. */ - for( i = 0; i < 4; i++ ){ - xb[ i ] = 0.0; - yb[ i ] = 0.0; - } - -/* Check that there is something to draw. */ - if( text && text[ 0 ] != 0 ){ - -/* Fill in any missing parts of the justification string. */ - if( just ){ - if( just[ 0 ] == 'T' || just[ 0 ] == 'C' || just[ 0 ] == 'B' ){ - lj[ 0 ] = just[ 0 ]; - } else { - astError( AST__GRFER, "astGTxExt: Justification string '%s' is " - "invalid.", just ); - return 0; - } - - if( just[ 1 ] == 'L' || just[ 1 ] == 'C' || just[ 1 ] == 'R' ){ - lj[ 1 ] = just[ 1 ]; - } else { - astError( AST__GRFER, "astGTxExt: Justification string '%s' is " - "invalid.", just ); - return 0; - } - - } else { - lj[ 0 ] = 'C'; - lj[ 1 ] = 'C'; - } - -/* Find the conversion factors between increment in world coordinate axes, - and the corresponding increments in millimetres ( Xmm = alpha*Xworld, - Ymm = beta*Yworld ). */ - if( !astGScales( &alpha, &beta ) ) return 0; - -/* If either axis is reversed, reverse the supplied up-vector components - so that they refer to the world-coordinates axes. */ - if( alpha < 0.0 ) upx = -upx; - if( beta < 0.0 ) upy = -upy; - -/* Convert the up-vector into millimetres. */ - ux = alpha*upx; - uy = beta*upy; - -/* Normalise the up-vector to a length of 1 millimetre. */ - uplen = sqrt( (double) (ux*ux + uy*uy) ); - if( uplen > 0.0 ){ - ux /= uplen; - uy /= uplen; - } else { - astError( AST__GRFER, "astGText: Zero length up-vector supplied."); - return 0; - } - -/* Form the base-line vector by rotating the up-vector by 90 degrees - clockwise. */ - vx = uy; - vy = -ux; - -/* Get the angle between the text base-line and horizontal. */ - angle = atan2( (double) vy, (double) vx )*R2D; - -/* Get the bounding box of the string drawn with its bottom left corner - at the origin. */ - ccpgqtxt( 0.0, 0.0, angle, 0.0, (char *) text, xbox, ybox ); - -/* Convert the returned bounding box world coordinates into millimetres. */ - for( i = 0; i < 4; i++ ){ - xbox[ i ] *= alpha; - ybox[ i ] *= beta; - } - -/* Find the height of the bounding box, in millimetres. Note, - the PGPLOT manual is not clear about the order of the corners - returned by pgqtxt, so we have to find the largest distance between - the corners in the direction of the supplied up-vector. The reference - point is on the text base-line which is not usually at the bottom of - the bounding box (some letters - like "y" - extend below the base-line). - Find the distance from the base-line to the top (hu) and bottom (hd) - of the bounding box. */ - hu = -FLT_MAX; - hd = FLT_MAX; - for( i = 0; i < 4; i++ ){ - test = ux*xbox[ i ] + uy*ybox[ i ]; - if( test > hu ) hu = test; - if( test < hd ) hd = test; - } - -/* Get an up and a down vector scaled to the height/depth of the - bounding box above/below the text base-line . */ - uxu = ux*hu; - uyu = uy*hu; - uxd = ux*hd; - uyd = uy*hd; - -/* The bounding box returned by pgqtxt does not include any leading or - trailing spaces. We need to include such spaces in the returned box. - To do this we get the length of the text string in millimetres - using pglen instead of using the bounding box returned by pgqtxt. */ - ccpglen( 2, (char *) text, &xl, &yl ); - -/* The abolute width of the string in millimetres may depend on the - up-vector. The values returned by pglen are for horizontal and - vertical text. Find the width using the supplied up-vector. */ - a = uy*xl; - b = ux*yl; - width = sqrt( a*a + b*b ); - -/* The pglen function returns a value which is slightly smaller than - the area cleared to hold the text when written using pgptxt. Increase - the text width so that it is about equal to the area cleared. */ - width += 0.2*hu; - -/* Scale the base-line vector so that its length is equal to the width - of the bounding box (including spaces). */ - vx *= width; - vy *= width; - -/* Convert the base-line vector back into world coordinates. */ - vx /= alpha; - vy /= beta; - -/* Convert the up and down vectors into world coordinates. */ - uxu /= alpha; - uyu /= beta; - uxd /= alpha; - uyd /= beta; - -/* Find the coordinates at the centre of the bounding box in world - coordinates. */ - xc = x; - yc = y; - - if( lj[0] == 'B' ) { - xc += 0.5*uxu; - yc += 0.5*uyu; - } else if( lj[0] == 'T' ) { - xc -= 0.5*uxu; - yc -= 0.5*uyu; - } - - if( lj[1] == 'L' ) { - xc += 0.5*vx; - yc += 0.5*vy; - } else if( lj[1] == 'R' ) { - xc -= 0.5*vx; - yc -= 0.5*vy; - } - -/* Get the corners of the bounding box. */ - vdx = 0.5*vx; - vdy = 0.5*vy; - udx = 0.5*uxu; - udy = 0.5*uyu; - -/* Bottom left corner... */ - xb[ 0 ] = xc - vdx - udx + uxd; - yb[ 0 ] = yc - vdy - udy + uyd; - -/* Bottom right corner... */ - xb[ 1 ] = xc + vdx - udx + uxd; - yb[ 1 ] = yc + vdy - udy + uyd; - -/* Top right corner... */ - xb[ 2 ] = xc + vdx + udx; - yb[ 2 ] = yc + vdy + udy; - -/* Top left corner... */ - xb[ 3 ] = xc - vdx + udx; - yb[ 3 ] = yc - vdy + udy; - - } - -/* Return. */ - return 1; -} - -int astGQch( float *chv, float *chh ){ -/* -*+ -* Name: -* astGQch - -* Purpose: -* Return the character height in world coordinates. - -* Synopsis: -* #include "grf.h" -* int astGQch( float *chv, float *chh ) - -* Description: -* This function returns the heights of characters drawn vertically and -* horizontally in world coordinates. - -* Parameters: -* chv -* A pointer to the double which is to receive the height of -* characters drawn with a vertical baseline . This will be an -* increment in the X axis. -* chh -* A pointer to the double which is to receive the height of -* characters drawn with a horizontal baseline. This will be an -* increment in the Y axis. - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -*- -*/ - -/* Local Variables: */ - float vx1,vx2,vy1,vy2,wx1,wx2,wy1,wy2; - -/* Get the character height in normalised device coordinates */ - ccpgqcs( 0, chv, chh ); - -/* Get the bounds of the PGPLOT viewport in normalised device - coordinates. */ - ccpgqvp( 0, &vx1, &vx2, &vy1, &vy2 ); - -/* Get the bounds of the PGPLOT window in world coordinates. */ - ccpgqwin( &wx1, &wx2, &wy1, &wy2 ); - -/* Convert the text height from normalised device coordinates into world - coordinates for vertical text. Print an error message if the viewport - has zero size. */ - if( vx1 != vx2 ){ - *chv *= ( wx2 - wx1 )/( vx2 - vx1 ); - - } else { - astError( AST__GRFER, "astGQch: The graphics viewport has zero size " - "in the X direction."); - return 0; - } - -/* Convert the text height from normalised device coordinates into world - coordinates for horizontal text. Print an error message if the viewport - has zero size. */ - if( vy1 != vy2 ){ - *chh *= ( wy2 - wy1 )/( vy2 - vy1 ); - } else { - astError( AST__GRFER, "astGQch: The graphics viewport has zero size " - "in the Y direction."); - return 0; - } - -/* Return. */ - return 1; -} - -int astGAttr( int attr, double value, double *old_value, int prim ){ -/* -*+ -* Name: -* astGAttr - -* Purpose: -* Enquire or set a graphics attribute value. - -* Synopsis: -* #include "grf.h" -* int int astGAttr( int attr, double value, double *old_value, int prim ) - -* Description: -* This function returns the current value of a specified graphics -* attribute, and optionally establishes a new value. The supplied -* value is converted to an integer value if necessary before use. - -* Parameters: -* attr -* An integer value identifying the required attribute. The -* following symbolic values are defined in grf.h: -* -* GRF__STYLE - Line style. -* GRF__WIDTH - Line width. -* GRF__SIZE - Character and marker size scale factor. -* GRF__FONT - Character font. -* GRF__COLOUR - Colour index. -* value -* A new value to store for the attribute. If this is AST__BAD -* no value is stored. -* old_value -* A pointer to a double in which to return the attribute value. -* If this is NULL, no value is returned. -* prim -* The sort of graphics primitive to be drawn with the new attribute. -* Identified by the following values defined in grf.h: -* GRF__LINE -* GRF__MARK -* GRF__TEXT - -* Returned Value: -* A value of 0 is returned if an error occurs, and 1 is returned -* otherwise. - -* Notes: - -*- -*/ - - int ival; - float rval, dx, dy, deflw, x1, x2, y1, y2; - -/* If required retrieve the current line style, and set a new line style. */ - if( attr == GRF__STYLE ){ - ccpgqls( &ival ); - if( old_value ) *old_value = (double) ival; - - if( value != AST__BAD ){ - ival = (int) ( value + 0.5 ); - if( value < 0.0 ) ival -= 1; - - ival = ( ival - 1 ) % 5; - ival += ( ival < 0 ) ? 6 : 1; - - ccpgsls( ival ); - } - -/* If required retrieve the current line width, and set a new line width. - Line width is stored in Plot as a scale factor (1.0 for the default line - width which is a fixed fraction of the diagonal of the view surface), but - pgplot stores it in units of 0.005 of an inch. */ - } else if( attr == GRF__WIDTH ){ - -/* Get the bounds of the view surface in inches. */ - ccpgqvsz( 1, &x1, &x2, &y1, &y2 ); - -/* Find the default line width in inches (i.e. 0.0005 of the length - of the view surface diagonal). */ - dx = ( x1 - x2 ); - dy = ( y1 - y2 ); - deflw = 0.0005*sqrt( (double )( dx*dx + dy*dy ) ); - -/* Get the current pgplot line width in units of 0.005 of an inch. */ - ccpgqlw( &ival ); - -/* If required, return the factor by which this exceeds the default line - width found above. */ - if( old_value ) *old_value = (double)( ival )/( 200.0 * deflw ); - -/* If a new line width has been provided, the pgplot line width needs to - be set to the corresponding absolute value. */ - if( value != AST__BAD ){ - ival = (int) ( 200.0*value*deflw ); - if( ival < 1 ) { - ival = 1; - } else if( ival > 201 ){ - ival = 201; - } - ccpgslw( ival ); - } - -/* If required retrieve the current character size, and set a new size. - The attribute value should be a factor by which to multiply the - default character size. */ - } else if( attr == GRF__SIZE ){ - ccpgqch( &rval ); - if( old_value ) *old_value = (double) rval; - - if( value != AST__BAD ){ - ccpgsch( (float) value ); - } - -/* If required retrieve the current character font, and set a new font. */ - } else if( attr == GRF__FONT ){ - ccpgqcf( &ival ); - if( old_value ) *old_value = (double) ival; - - if( value != AST__BAD ){ - ival = (int) ( value + 0.5 ); - if( value < 0.0 ) ival -= 1; - - ival = ( ival - 1 ) % 4; - ival += ( ival < 0 ) ? 5 : 1; - ccpgscf( ival ); - } - -/* If required retrieve the current colour index, and set a new colour - index. */ - } else if( attr == GRF__COLOUR ){ - ccpgqci( &ival ); - if( old_value ) *old_value = (double) ival; - - if( value != AST__BAD ){ - ival = (int) ( value + 0.5 ); - if( ival < 0 ) ival = 1; - ccpgsci( ival ); - } - -/* Give an error message for any other attribute value. */ - } else { - astError( AST__GRFER, "astGAttr: Unknown graphics attribute '%d' " - "requested.", attr ); - return 0; - } - -/* Return. */ - return 1; -} - -/* Local Functions. */ -/* ================ */ -/* These implement the local C interface to PGPLOT in terms of its - native Fortran interface. Only those PGPLOT functions used within - this module are included. */ -static void ccpgline(int n, float xpts[], float ypts[] ){ - F77_INTEGER_TYPE N; - F77_REAL_TYPE *XX; - F77_REAL_TYPE *YY; - int i; - - XX = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n ); - YY = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n ); - - if( astOK ){ - - for( i = 0; i < n; i++ ){ - XX[ i ] = (F77_REAL_TYPE) xpts[ i ]; - YY[ i ] = (F77_REAL_TYPE) ypts[ i ]; - } - - N = (F77_INTEGER_TYPE) n; - - F77_CALL(pgline)( INTEGER_ARG(&N), REAL_ARRAY_ARG(XX), - REAL_ARRAY_ARG(YY) ); - - XX = (F77_REAL_TYPE *) astFree( (void *) XX ); - YY = (F77_REAL_TYPE *) astFree( (void *) YY ); - } -} - -static void ccpgpt(int n, float xpts[], float ypts[], int symbol){ - F77_INTEGER_TYPE N; - F77_REAL_TYPE *XX; - F77_REAL_TYPE *YY; - F77_INTEGER_TYPE SYMBOL; - int i; - - XX = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n ); - YY = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n ); - - if( astOK ){ - - for( i = 0; i < n; i++ ){ - XX[ i ] = (F77_REAL_TYPE) xpts[ i ]; - YY[ i ] = (F77_REAL_TYPE) ypts[ i ]; - } - - N = (F77_INTEGER_TYPE) n; - SYMBOL = (F77_INTEGER_TYPE) symbol; - - - F77_CALL(pgpt)( INTEGER_ARG(&N), REAL_ARRAY_ARG(XX), - REAL_ARRAY_ARG(YY), INTEGER_ARG(&SYMBOL) ); - - XX = (F77_REAL_TYPE *) astFree( (void *) XX ); - YY = (F77_REAL_TYPE *) astFree( (void *) YY ); - } -} - -static void ccpgptxt(float x, float y, float angle, float fjust, char *text ){ - F77_REAL_TYPE X; - F77_REAL_TYPE Y; - F77_REAL_TYPE ANGLE; - F77_REAL_TYPE FJUST; - DECLARE_CHARACTER(LTEXT,MXSTRLEN); - int ftext_length; - - X = (F77_REAL_TYPE) x; - Y = (F77_REAL_TYPE) y; - ANGLE = (F77_REAL_TYPE) angle; - FJUST = (F77_REAL_TYPE) fjust; - - ftext_length = strlen( text ); - if( ftext_length > LTEXT_length ) ftext_length = LTEXT_length; - astStringExport( text, LTEXT, ftext_length ); - - F77_CALL(pgptxt)( REAL_ARG(&X), REAL_ARG(&Y), REAL_ARG(&ANGLE), - REAL_ARG(&FJUST), CHARACTER_ARG(LTEXT) - TRAIL_ARG(ftext) ); -} - -static void ccpgqtxt(float x, float y, float angle, float fjust, char *text, - float xbox[], float ybox[]){ - F77_REAL_TYPE X; - F77_REAL_TYPE Y; - F77_REAL_TYPE ANGLE; - F77_REAL_TYPE FJUST; - DECLARE_CHARACTER(LTEXT,MXSTRLEN); - F77_REAL_TYPE XBOX[ 4 ]; - F77_REAL_TYPE YBOX[ 4 ]; - int i; - int ftext_length; - - X = (F77_REAL_TYPE) x; - Y = (F77_REAL_TYPE) y; - ANGLE = (F77_REAL_TYPE) angle; - FJUST = (F77_REAL_TYPE) fjust; - - ftext_length = strlen( text ); - if( ftext_length > LTEXT_length ) ftext_length = LTEXT_length; - astStringExport( text, LTEXT, ftext_length ); - - F77_CALL(pgqtxt)( REAL_ARG(&X), REAL_ARG(&Y), REAL_ARG(&ANGLE), - REAL_ARG(&FJUST), CHARACTER_ARG(LTEXT), - REAL_ARRAY_ARG(XBOX), REAL_ARRAY_ARG(YBOX) - TRAIL_ARG(ftext) ); - - for( i = 0; i < 4; i++ ){ - xbox[ i ] = (float) XBOX[ i ]; - ybox[ i ] = (float) YBOX[ i ]; - } - -} - -static void ccpgqtbg(int *tbci){ - F77_INTEGER_TYPE TBCI; - F77_CALL(pgqtbg)( INTEGER_ARG(&TBCI) ); - *tbci = (int) TBCI; -} - -static void ccpgstbg(int tbci){ - F77_INTEGER_TYPE TBCI; - TBCI = (F77_INTEGER_TYPE) tbci; - F77_CALL(pgstbg)( INTEGER_ARG(&TBCI) ); -} - -static void ccpgqcs(int units, float *xch, float *ych){ - F77_INTEGER_TYPE UNITS; - F77_REAL_TYPE XCH; - F77_REAL_TYPE YCH; - UNITS = (F77_INTEGER_TYPE) units; - - F77_CALL(pgqcs)( INTEGER_ARG(&UNITS), REAL_ARG(&XCH), REAL_ARG(&YCH) ); - - *xch = (float) XCH; - *ych = (float) YCH; -} - -static void ccpglen(int units, char *text, float *xl, float *yl ){ - F77_INTEGER_TYPE UNITS; - F77_REAL_TYPE XL; - F77_REAL_TYPE YL; - DECLARE_CHARACTER(LTEXT,MXSTRLEN); - int ftext_length; - - UNITS = (F77_INTEGER_TYPE) units; - - - ftext_length = strlen( text ); - if( ftext_length > LTEXT_length ) ftext_length = LTEXT_length; - astStringExport( text, LTEXT, ftext_length ); - - F77_CALL(pglen)( INTEGER_ARG(&UNITS), CHARACTER_ARG(LTEXT), - REAL_ARG(&XL), REAL_ARG(&YL) TRAIL_ARG(ftext) ); - - *xl = (float) XL; - *yl = (float) YL; -} - -static void ccpgqvp(int units, float *x1, float *x2, float *y1, float *y2){ - F77_INTEGER_TYPE UNITS; - F77_REAL_TYPE X1; - F77_REAL_TYPE X2; - F77_REAL_TYPE Y1; - F77_REAL_TYPE Y2; - - UNITS = (F77_INTEGER_TYPE) units; - F77_CALL(pgqvp)( INTEGER_ARG(&UNITS), REAL_ARG(&X1), REAL_ARG(&X2), - REAL_ARG(&Y1), REAL_ARG(&Y2) ); - *x1 = (float) X1; - *x2 = (float) X2; - *y1 = (float) Y1; - *y2 = (float) Y2; -} - -static void ccpgqvsz(int units, float *x1, float *x2, float *y1, float *y2){ - F77_INTEGER_TYPE UNITS; - F77_REAL_TYPE X1; - F77_REAL_TYPE X2; - F77_REAL_TYPE Y1; - F77_REAL_TYPE Y2; - - UNITS = (F77_INTEGER_TYPE) units; - F77_CALL(pgqvsz)( INTEGER_ARG(&UNITS), REAL_ARG(&X1), REAL_ARG(&X2), - REAL_ARG(&Y1), REAL_ARG(&Y2) ); - *x1 = (float) X1; - *x2 = (float) X2; - *y1 = (float) Y1; - *y2 = (float) Y2; -} - -static void ccpgqwin(float *x1, float *x2, float *y1, float *y2){ - F77_REAL_TYPE X1; - F77_REAL_TYPE X2; - F77_REAL_TYPE Y1; - F77_REAL_TYPE Y2; - - F77_CALL(pgqwin)( REAL_ARG(&X1), REAL_ARG(&X2), REAL_ARG(&Y1), - REAL_ARG(&Y2) ); - *x1 = (float) X1; - *x2 = (float) X2; - *y1 = (float) Y1; - *y2 = (float) Y2; -} - -static void ccpgqls(int *ls){ - F77_INTEGER_TYPE LS; - F77_CALL(pgqls)( INTEGER_ARG(&LS) ); - *ls = (int) LS; -} - -static void ccpgsls(int ls){ - F77_INTEGER_TYPE LS; - LS = (F77_INTEGER_TYPE) ls; - F77_CALL(pgsls)( INTEGER_ARG(&LS) ); -} - -static void ccpgqlw(int *lw){ - F77_INTEGER_TYPE LW; - F77_CALL(pgqlw)( INTEGER_ARG(&LW) ); - *lw = (int) LW; -} - -static void ccpgslw(int lw){ - F77_INTEGER_TYPE LW; - LW = (F77_INTEGER_TYPE) lw; - F77_CALL(pgslw)( INTEGER_ARG(&LW) ); -} - -static void ccpgqch(float *ch){ - F77_REAL_TYPE CH; - F77_CALL(pgqch)( REAL_ARG(&CH) ); - *ch = (float) CH; -} - -static void ccpgsch(float ch){ - F77_REAL_TYPE CH; - CH = (F77_REAL_TYPE) ch; - F77_CALL(pgsch)( REAL_ARG(&CH) ); -} - -static void ccpgqcf(int *cf){ - F77_INTEGER_TYPE CF; - F77_CALL(pgqcf)( INTEGER_ARG(&CF) ); - *cf = (int) CF; -} - -static void ccpgscf(int cf){ - F77_INTEGER_TYPE CF; - CF = (F77_INTEGER_TYPE) cf; - F77_CALL(pgscf)( INTEGER_ARG(&CF) ); -} - -static void ccpgqci(int *ci){ - F77_INTEGER_TYPE CI; - F77_CALL(pgqci)( INTEGER_ARG(&CI) ); - *ci = (int) CI; -} - -static void ccpgsci(int ci){ - F77_INTEGER_TYPE CI; - CI = (F77_INTEGER_TYPE) ci; - F77_CALL(pgsci)( INTEGER_ARG(&ci) ); -} - -static void ccpgupdt( void ){ - F77_CALL(pgupdt)(); -} - -static void ccpgbbuf( void ){ - F77_CALL(pgbbuf)(); -} - -static void ccpgebuf( void ){ - F77_CALL(pgebuf)(); -} diff --git a/ast/gridplot.pdf b/ast/gridplot.pdf deleted file mode 100644 index 1ba8733..0000000 Binary files a/ast/gridplot.pdf and /dev/null differ diff --git a/ast/gridplot_bw.pdf b/ast/gridplot_bw.pdf deleted file mode 100644 index c480928..0000000 Binary files a/ast/gridplot_bw.pdf and /dev/null differ diff --git a/ast/grismmap.c b/ast/grismmap.c deleted file mode 100644 index bc615d3..0000000 --- a/ast/grismmap.c +++ /dev/null @@ -1,2596 +0,0 @@ -/* -*class++ -* Name: -* GrismMap - -* Purpose: -* Transform 1-dimensional coordinates using a grism dispersion equation. - -* Constructor Function: -c astGrismMap -f AST_GRISMMAP - -* Description: -* A GrismMap is a specialised form of Mapping which transforms -* 1-dimensional coordinates using the spectral dispersion equation -* described in FITS-WCS paper III "Representation of spectral -* coordinates in FITS". This describes the dispersion produced by -* gratings, prisms and grisms. -* -* When initially created, the forward transformation of a GrismMap -* transforms input "grism parameter" values into output wavelength -* values. The "grism parameter" is a dimensionless value which is -* linearly related to position on the detector. It is defined in FITS-WCS -* paper III as "the offset on the detector from the point of intersection -* of the camera axis, measured in units of the effective local length". -* The units in which wavelength values are expected or returned is -* determined by the values supplied for the GrismWaveR, GrismNRP and -* GrismG attribute: whatever units are used for these attributes will -* also be used for the wavelength values. - -* Inheritance: -* The GrismMap class inherits from the Mapping class. - -* Attributes: -* In addition to those attributes common to all Mappings, every -* GrismMap also has the following attributes: -* -* - GrismNR: The refractive index at the reference wavelength -* - GrismNRP: Rate of change of refractive index with wavelength -* - GrismWaveR: The reference wavelength -* - GrismAlpha: The angle of incidence of the incoming light -* - GrismG: The grating ruling density -* - GrismM: The interference order -* - GrismEps: The angle between the normal and the dispersion plane -* - GrismTheta: Angle between normal to detector plane and reference ray - -* Functions: -c The GrismMap class does not define any new functions beyond those -f The GrismMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 18-JUN-2003 (DSB): -* Original version. -* 10-MAY-2006 (DSB): -* Override astEqual. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS GrismMap - - -/* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a method to clear an attribute value for a GrismMap. - -* Type: -* Private macro. - -* Synopsis: -* #include "grismmap.h" -* MAKE_CLEAR(class,attribute,component,assign) - -* Class Membership: -* Defined by the GrismMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstGrismMap *this ) -* -* and an external interface function of the form: -* -* void astClear_( AstGrismMap *this ) -* -* which implement a method for clearing a specified attribute value for -* a class. The derived constants stored in the GrismMap structure are -* updated after the attribute has been cleared. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attribute -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. Label in "astClearLabel"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(class,attribute,component,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attribute( Ast##class *this, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Report an error if the object has been cloned (i.e. has a reference \ - count that is greater than one). */ \ - if( astGetRefCount( this ) > 1 ) { \ - astError( AST__IMMUT, "astClear(%s): The " #attribute "attribute of " \ - "the supplied %s cannot be cleared because the %s has " \ - "been cloned (programming error).", status, \ - astGetClass(this), astGetClass(this), astGetClass(this) ); \ -\ -/* Otherwise, assign the "clear" value in the structure component. */ \ - } else { \ - this->component = (assign); \ - } \ -\ -/* Update the derived constants. */ \ - UpdateConstants( this, status ); \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attribute##_( Ast##class *this, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,class,Clear##attribute))( this, status ); \ -} - -/* -* Name: -* MAKE_SET - -* Purpose: -* Implement a method to set an attribute value for a GrismMap. - -* Type: -* Private macro. - -* Synopsis: -* #include "grismmap.h" -* astMAKE_SET(class,attribute,type,component,assign) - -* Class Membership: -* Defined by the GrismMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstGrismMap *this, value ) -* -* and an external interface function of the form: -* -* void astSet_( AstGrismMap *this, value ) -* -* which implement a method for setting a specified attribute value for a -* GrismMap. The derived constants stored in the GrismMap structure are -* updated after the attribute has been cleared. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attribute -* The name of the attribute to be set, as it appears in the function -* name (e.g. Label in "astSetLabel"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_SET(class,attribute,type,component,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attribute( Ast##class *this, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Report an error if the object has been cloned (i.e. has a reference \ - count that is greater than one). */ \ - if( astGetRefCount( this ) > 1 ) { \ - astError( AST__IMMUT, "astSet(%s): The " #attribute "attribute of " \ - "the supplied %s cannot be changed because the %s has " \ - "been cloned (programming error).", status, \ - astGetClass(this), astGetClass(this), astGetClass(this) ); \ -\ -/* Otherwise, store the new value in the structure component. */ \ - } else { \ - this->component = (assign); \ - } \ -\ -/* Update the derived constants. */ \ - UpdateConstants( this, status ); \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attribute##_( Ast##class *this, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,class,Set##attribute))( this, value, status ); \ -} - - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "unitmap.h" /* Unit Mappings */ -#include "channel.h" /* I/O channels */ -#include "zoommap.h" /* ZoomMap interface */ -#include "winmap.h" /* WinMap interface */ -#include "grismmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Macros which return the maximum and minimum of two values. */ -#define MAX(aa,bb) ((aa)>(bb)?(aa):(bb)) -#define MIN(aa,bb) ((aa)<(bb)?(aa):(bb)) - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(GrismMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(GrismMap,Class_Init) -#define class_vtab astGLOBAL(GrismMap,Class_Vtab) -#define getattrib_buff astGLOBAL(GrismMap,GetAttrib_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstGrismMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstGrismMap *astGrismMapId_( const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static AstMapping *CanMerge( AstMapping *, int, AstMapping *, int, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void UpdateConstants( AstGrismMap *, int * ); - -static double GetGrismNR( AstGrismMap *, int * ); -static int TestGrismNR( AstGrismMap *, int * ); -static void ClearGrismNR( AstGrismMap *, int * ); -static void SetGrismNR( AstGrismMap *, double, int * ); - -static double GetGrismNRP( AstGrismMap *, int * ); -static int TestGrismNRP( AstGrismMap *, int * ); -static void ClearGrismNRP( AstGrismMap *, int * ); -static void SetGrismNRP( AstGrismMap *, double, int * ); - -static double GetGrismWaveR( AstGrismMap *, int * ); -static int TestGrismWaveR( AstGrismMap *, int * ); -static void ClearGrismWaveR( AstGrismMap *, int * ); -static void SetGrismWaveR( AstGrismMap *, double, int * ); - -static double GetGrismAlpha( AstGrismMap *, int * ); -static int TestGrismAlpha( AstGrismMap *, int * ); -static void ClearGrismAlpha( AstGrismMap *, int * ); -static void SetGrismAlpha( AstGrismMap *, double, int * ); - -static double GetGrismG( AstGrismMap *, int * ); -static int TestGrismG( AstGrismMap *, int * ); -static void ClearGrismG( AstGrismMap *, int * ); -static void SetGrismG( AstGrismMap *, double, int * ); - -static int GetGrismM( AstGrismMap *, int * ); -static int TestGrismM( AstGrismMap *, int * ); -static void ClearGrismM( AstGrismMap *, int * ); -static void SetGrismM( AstGrismMap *, int, int * ); - -static double GetGrismEps( AstGrismMap *, int * ); -static int TestGrismEps( AstGrismMap *, int * ); -static void ClearGrismEps( AstGrismMap *, int * ); -static void SetGrismEps( AstGrismMap *, double, int * ); - -static double GetGrismTheta( AstGrismMap *, int * ); -static int TestGrismTheta( AstGrismMap *, int * ); -static void ClearGrismTheta( AstGrismMap *, int * ); -static void SetGrismTheta( AstGrismMap *, double, int * ); - -/* Member functions. */ -/* ================= */ -static AstMapping *CanMerge( AstMapping *map1, int inv1, AstMapping *map2, - int inv2, int *status ){ -/* -* -* Name: -* CanMerge - -* Purpose: -* Checks if two GrismMaps can be merged. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* AstMapping *CanMerge( AstMapping *map1, int inv1, AstMapping *map2, -* int inv2, int *status ) - -* Class Membership: -* GrismMap internal utility function. - -* Description: -* This function checks the two supplied Mappings to see if they can -* be merged into a single Mapping. One of the two Mappings should be -* a GrismMap. If they can be merged, the Merged Mapping is returned -* as the function value. Otherwise NULL is returned. - -* Parameters: -* map1 -* A pointer to the first mapping. -* map2 -* A pointer to the second mapping. -* inv1 -* The invert flag to use with the first mapping. -* inv2 -* The invert flag to use with the second mapping. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the merged Mapping if the supplied Mappings can be merged, -* NULL otherwise. - -*/ - -/* Local Variables: */ - AstGrismMap *gmap2; /* Pointer to second GrismMap */ - AstGrismMap *gmap; /* Pointer to first GrismMap */ - AstMapping *ret; /* Returned merged Mapping */ - double g; /* The value of the GrismG attribute */ - double nrp; /* The value of the GrismNRP attribute */ - double waver; /* The value of the GrismWaveR attribute */ - double z; /* Wavelength scaling */ - int invert_result; /* Is "ret" the inverse of the required Mapping? */ - -/* Initialise the returned value. */ - ret = NULL; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - gmap = NULL; - invert_result = 0; - -/* Initialise the zoom factor of the adjacent ZoomMap to indicate - that we have not yet found an adjacent ZoomMap. */ - z = AST__BAD; - -/* If the first Mapping is a GrismMap... */ - if( !strcmp( "GrismMap", astGetClass( map1 ) ) ) { - gmap = (AstGrismMap *) map1; - -/* If the second Mapping is also a GrismMap, they can be merged into a - UnitMap if one GrismMap is the inverse of the other. */ - if( !strcmp( "GrismMap", astGetClass( map2 ) ) ) { - gmap2 = (AstGrismMap *) map2; - -/* Check that the two GrismMaps have the same attribute values. */ - if( astEQUAL( astGetGrismNR( gmap ), astGetGrismNR( gmap2 )) && - astEQUAL( astGetGrismNRP( gmap ), astGetGrismNRP( gmap2 )) && - astEQUAL( astGetGrismWaveR( gmap ), astGetGrismWaveR( gmap2 )) && - astEQUAL( astGetGrismAlpha( gmap ), astGetGrismAlpha( gmap2 )) && - astEQUAL( astGetGrismG( gmap ), astGetGrismG( gmap2 )) && - astGetGrismM( gmap ) != astGetGrismM( gmap2 ) && - astEQUAL( astGetGrismEps( gmap ), astGetGrismEps( gmap2 )) && - astEQUAL( astGetGrismTheta( gmap ), astGetGrismTheta( gmap2 )) ){ - -/* If so, check that the GrismMaps are applied in opposite senses. If so - we can cancel the two GrismMaps, so return a UnitMap. */ - if( inv1 != inv2 ) ret = (AstMapping *) astUnitMap( 1, "", status ); - } - -/* If the first Mapping is a GrismMap but the second one is not... */ - } else { - -/* We can merge the GrismMap with the second Mapping if the GrismMap has - not been inverted (i.e. if the wavelength output produced by the - GrismMap is fed as input to the second Mapping), and if the second - Mapping is a ZoomMap. */ - if( !inv1 ) { - -/* Indicate that any merged Mapping to be created later will not need to - be inverted. */ - invert_result = 0; - -/* See if the second Mapping is a ZoomMap, and if so, get the zoom - factor. If the Invert attribute in the ZoomMap is not set to the - required value, invert the zoom factor. This gives us the required - *forward* transformation. */ - if( !strcmp( "ZoomMap", astGetClass( map2 ) ) ) { - z = astGetZoom( (AstZoomMap *) map2 ); - if( astGetInvert( map2 ) != inv2 && z != 0.0 ) z = 1.0/z; - } - } - } - -/* If the first Mapping is not a GrismMap, but the second one is... */ - } else if( !strcmp( "GrismMap", astGetClass( map2 ) ) ) { - gmap = (AstGrismMap *) map2; - -/* We can merge the GrismMap with the first Mapping if the GrismMap has - been inverted (i.e. if the wavelength output produced by the first - Mapping is fed as input to the inverted GrismMap), and if the first - Mapping is a ZoomMap. */ - if( inv2 ) { - -/* It is easier to consider pairs of Mappings in which an un-inverted - GrismMap is followed by a ZoomMap (as in the above case). For this - reason, we invert the Mappings here, so that the merged Mapping created - later will be in the inverse of the required Mapping. Indicate that the - merged Mapping will therefore need to be inverted before being returned. */ - invert_result = 1; - -/* See if the first Mapping is a ZoomMap. If so, get the zoom factor. If the - Invert attribute in the ZoomMap is not set to the opposite of the required - value, invert the zoom factor. This gives us the required *inverse* - transformation. */ - if( !strcmp( "ZoomMap", astGetClass( map1 ) ) ) { - z = astGetZoom( (AstZoomMap *) map1 ); - if( astGetInvert( map1 ) == inv1 && z != 0.0 ) z = 1.0/z; - } - } - } - -/* If required, produce the merged Mapping by merging the forward - GrismMap with the following ZoomMap (and then invert the - resulting Mapping if it is in the wrong direction). */ - if( !ret && z != AST__BAD && z != 0.0 ) { - -/* Ensure we have a forward GrismMap. */ - ret = astCopy( gmap ); - astSetInvert( ret, 0 ); - -/* Get the required GrismMap attribute values. */ - g = astGetGrismG( ret ); - nrp = astGetGrismNRP( ret ); - waver = astGetGrismWaveR( ret ); - -/* The above code ensures that z is the zoom factor from the wavelength - produced by the forward GrismMap to the final (modified) wavelength units. - Set the new GrismMap attribute values. GrismG, GrismNRP and GrismWaveR have - units of length and are scaled to represent new length units using the - zoom factor found above. */ - g /= z; - nrp /= z; - waver *= z; - - astSetGrismG( ret, g ); - astSetGrismNRP( ret, nrp ); - astSetGrismWaveR( ret, waver ); - -/* If required invert this GrismMap. */ - if( invert_result ) astInvert( ret ); - - } - -/* Return the answer. */ - return ret; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a GrismMap. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* GrismMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* GrismMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the GrismMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstGrismMap *this; /* Pointer to the GrismMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the GrismMap structure. */ - this = (AstGrismMap *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - if ( !strcmp( attrib, "grismnr" ) ) { - astClearGrismNR( this ); - - } else if ( !strcmp( attrib, "grismnrp" ) ) { - astClearGrismNRP( this ); - - } else if ( !strcmp( attrib, "grismwaver" ) ) { - astClearGrismWaveR( this ); - - } else if ( !strcmp( attrib, "grismalpha" ) ) { - astClearGrismAlpha( this ); - - } else if ( !strcmp( attrib, "grismg" ) ) { - astClearGrismG( this ); - - } else if ( !strcmp( attrib, "grismm" ) ) { - astClearGrismM( this ); - - } else if ( !strcmp( attrib, "grismeps" ) ) { - astClearGrismEps( this ); - - } else if ( !strcmp( attrib, "grismtheta" ) ) { - astClearGrismTheta( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two GrismMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* GrismMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two GrismMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a GrismMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the GrismMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstGrismMap *that; - AstGrismMap *this; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two GrismMap structures. */ - this = (AstGrismMap *) this_object; - that = (AstGrismMap *) that_object; - -/* Check the second object is a GrismMap. We know the first is a - GrismMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAGrismMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two GrismMaps differ, it may still be possible - for them to be equivalent. First compare the GrismMaps if their Invert - flags are the same. In this case all the attributes of the two GrismMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - - if( astEQUAL( this->nr, that->nr ) && - astEQUAL( this->nrp, that->nrp ) && - astEQUAL( this->waver, that->waver ) && - astEQUAL( this->alpha, that->alpha ) && - astEQUAL( this->g, that->g ) && - this->m == that->m && - astEQUAL( this->eps, that->eps ) && - astEQUAL( this->theta, that->theta ) && - astEQUAL( this->k1, that->k1 ) && - astEQUAL( this->k2, that->k2 ) && - astEQUAL( this->k3, that->k3 ) ) { - result = 1; - } - -/* If the Invert flags for the two GrismMaps differ, the attributes of the two - GrismMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a GrismMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a GrismMap. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* GrismMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a GrismMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the GrismMap. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the GrismMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the GrismMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstGrismMap *this; /* Pointer to the GrismMap structure */ - const char *result; /* Pointer value to return */ - double dval; /* Attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the GrismMap structure. */ - this = (AstGrismMap *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - - if ( !strcmp( attrib, "grismnr" ) ) { - dval = astGetGrismNR( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - } else if ( !strcmp( attrib, "grismnrp" ) ) { - dval = astGetGrismNRP( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - } else if ( !strcmp( attrib, "grismwaver" ) ) { - dval = astGetGrismWaveR( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - } else if ( !strcmp( attrib, "grismalpha" ) ) { - dval = astGetGrismAlpha( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - } else if ( !strcmp( attrib, "grismg" ) ) { - dval = astGetGrismG( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - } else if ( !strcmp( attrib, "grismm" ) ) { - dval = astGetGrismM( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - } else if ( !strcmp( attrib, "grismeps" ) ) { - dval = astGetGrismEps( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - } else if ( !strcmp( attrib, "grismtheta" ) ) { - dval = astGetGrismTheta( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -void astInitGrismMapVtab_( AstGrismMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitGrismMapVtab - -* Purpose: -* Initialise a virtual function table for a GrismMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "grismmap.h" -* void astInitGrismMapVtab( AstGrismMapVtab *vtab, const char *name ) - -* Class Membership: -* GrismMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the GrismMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAGrismMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->ClearGrismNR = ClearGrismNR; - vtab->GetGrismNR = GetGrismNR; - vtab->SetGrismNR = SetGrismNR; - vtab->TestGrismNR = TestGrismNR; - - vtab->ClearGrismNRP = ClearGrismNRP; - vtab->GetGrismNRP = GetGrismNRP; - vtab->SetGrismNRP = SetGrismNRP; - vtab->TestGrismNRP = TestGrismNRP; - - vtab->ClearGrismWaveR = ClearGrismWaveR; - vtab->GetGrismWaveR = GetGrismWaveR; - vtab->SetGrismWaveR = SetGrismWaveR; - vtab->TestGrismWaveR = TestGrismWaveR; - - vtab->ClearGrismAlpha = ClearGrismAlpha; - vtab->GetGrismAlpha = GetGrismAlpha; - vtab->SetGrismAlpha = SetGrismAlpha; - vtab->TestGrismAlpha = TestGrismAlpha; - - vtab->ClearGrismG = ClearGrismG; - vtab->GetGrismG = GetGrismG; - vtab->SetGrismG = SetGrismG; - vtab->TestGrismG = TestGrismG; - - vtab->ClearGrismM = ClearGrismM; - vtab->GetGrismM = GetGrismM; - vtab->SetGrismM = SetGrismM; - vtab->TestGrismM = TestGrismM; - - vtab->ClearGrismEps = ClearGrismEps; - vtab->GetGrismEps = GetGrismEps; - vtab->SetGrismEps = SetGrismEps; - vtab->TestGrismEps = TestGrismEps; - - vtab->ClearGrismTheta = ClearGrismTheta; - vtab->GetGrismTheta = GetGrismTheta; - vtab->SetGrismTheta = SetGrismTheta; - vtab->TestGrismTheta = TestGrismTheta; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the class dump, copy and delete functions.*/ - astSetDump( vtab, Dump, "GrismMap", - "Map 1-d coordinates using a spectral disperser" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a GrismMap. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* GrismMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated GrismMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated GrismMap with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated GrismMap which is to be merged with -* its neighbours. This should be a cloned copy of the GrismMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* GrismMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated GrismMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *merged_map; /* Merger of two Mappings */ - int i1; /* Lower index of the two GrismMaps being merged */ - int i2; /* Upper index of the two GrismMaps being merged */ - int i; /* Mapping index */ - int result; /* Result value to return */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - i1 = -1; - i2 = -1; - -/* See if the GrismMap can be merged with the Mappings on either side of it - in the list. This can only be done in series for a GrismMap. */ -/* ===================================================================== */ - if( series ) { - -/* Set a flag indicating that we have not yet found a neighbour with which - the GrismMap can be merged. */ - merged_map = NULL; - -/* First check the lower neighbour (if any). */ - if( where > 0 ) { - i1 = where - 1; - i2 = where; - merged_map = CanMerge( ( *map_list )[ i1 ], (* invert_list)[ i1 ], - ( *map_list )[ i2 ], (* invert_list)[ i2 ], status ); - } - -/* If the GrismMap can not be merged with its lower neighbour, check its - upper neighbour (if any) in the same way. */ - if( !merged_map && where < *nmap - 1 ) { - i1 = where; - i2 = where + 1; - merged_map = CanMerge( ( *map_list )[ i1 ], (* invert_list)[ i1 ], - ( *map_list )[ i2 ], (* invert_list)[ i2 ], status ); - } - -/* If either neighbour has passed these checks, replace the pair of - Mappings which have been merged with the single merged Mapping returned - above. */ - if( merged_map ) { - -/* Annul the two Mappings. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - (void) astAnnul( ( *map_list )[ i2 ] ); - -/* Store a pointer for the merged Mapping in place of the first of the - two replaced Mappings. */ - ( *map_list )[ i1 ] = merged_map; - ( *invert_list )[ i1 ] = astGetInvert( merged_map ); - -/* Shuffle down the remaining Mappings to fill the hole left by the - second of the replaced Mappings. */ - for ( i = i2 + 1; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - (*nmap)--; - result = i1; - - } - } - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a GrismMap. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* GrismMap member function (over-rides the astSetAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function assigns an attribute value for a GrismMap, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the GrismMap. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstGrismMap *this; /* Pointer to the GrismMap structure */ - double dval; /* Attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the GrismMap structure. */ - this = (AstGrismMap *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - - if ( nc = 0, ( 1 == astSscanf( setting, "grismnr= %lf %n", &dval, &nc ) ) && ( nc >= len ) ) { - astSetGrismNR( this, dval ); - - } else if ( nc = 0, ( 1 == astSscanf( setting, "grismnrp= %lf %n", &dval, &nc ) ) && ( nc >= len ) ) { - astSetGrismNRP( this, dval ); - - } else if ( nc = 0, ( 1 == astSscanf( setting, "grismwaver= %lf %n", &dval, &nc ) ) && ( nc >= len ) ) { - astSetGrismWaveR( this, dval ); - - } else if ( nc = 0, ( 1 == astSscanf( setting, "grismalpha= %lf %n", &dval, &nc ) ) && ( nc >= len ) ) { - astSetGrismAlpha( this, dval ); - - } else if ( nc = 0, ( 1 == astSscanf( setting, "grismg= %lf %n", &dval, &nc ) ) && ( nc >= len ) ) { - astSetGrismG( this, dval ); - - } else if ( nc = 0, ( 1 == astSscanf( setting, "grismm= %lf %n", &dval, &nc ) ) && ( nc >= len ) ) { - astSetGrismM( this, dval ); - - } else if ( nc = 0, ( 1 == astSscanf( setting, "grismeps= %lf %n", &dval, &nc ) ) && ( nc >= len ) ) { - astSetGrismEps( this, dval ); - - } else if ( nc = 0, ( 1 == astSscanf( setting, "grismtheta= %lf %n", &dval, &nc ) ) && ( nc >= len ) ) { - astSetGrismTheta( this, dval ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a GrismMap. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* GrismMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a GrismMap's attributes. - -* Parameters: -* this -* Pointer to the GrismMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstGrismMap *this; /* Pointer to the GrismMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the GrismMap structure. */ - this = (AstGrismMap *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - if ( !strcmp( attrib, "grismnr" ) ) { - result = astTestGrismNR( this ); - - } else if ( !strcmp( attrib, "grismnrp" ) ) { - result = astTestGrismNRP( this ); - - } else if ( !strcmp( attrib, "grismwaver" ) ) { - result = astTestGrismWaveR( this ); - - } else if ( !strcmp( attrib, "grismalpha" ) ) { - result = astTestGrismAlpha( this ); - - } else if ( !strcmp( attrib, "grismg" ) ) { - result = astTestGrismG( this ); - - } else if ( !strcmp( attrib, "grismm" ) ) { - result = astTestGrismM( this ); - - } else if ( !strcmp( attrib, "grismeps" ) ) { - result = astTestGrismEps( this ); - - } else if ( !strcmp( attrib, "grismtheta" ) ) { - result = astTestGrismTheta( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a GrismMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* GrismMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a GrismMap and a set of points encapsulated -* in a PointSet and transforms the points so as to apply the -* forward or inverse dispersal equation. - -* Parameters: -* this -* Pointer to the GrismMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate -* transformation should be applied, while a zero value requests -* the inverse transformation. -* out -* Pointer to a PointSet which will hold the transformed -* (output) coordinate values. A NULL value may also be given, -* in which case a new PointSet will be created by this -* function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -* - The number of coordinate values per point in the input -* PointSet must equal 1. -* - If an output PointSet is supplied, it must have space for -* sufficient number of points (with 1 coordinate value per point) -* to accommodate the result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstGrismMap *map; /* Pointer to GrismMap to be applied */ - AstPointSet *result; /* Pointer to output PointSet */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double sinbeta; /* Sin( beta ) (see FITS-WCS paper III) */ - double value_in; /* Input coordinate value */ - int npoint; /* Number of points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the GrismMap. */ - map = (AstGrismMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform - member function inherited from the parent Mapping class. This - function validates all arguments and generates an output PointSet - if necessary, but does not actually transform any coordinate - values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points from the input PointSet and obtain - pointers for accessing the input and output coordinate values. */ - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse mapping, - according to the direction specified and whether the mapping has - been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* If any of the parameters are undefined fill the output with bad - values (if possible). */ - if( map->k1 == AST__BAD || map->k2 == AST__BAD || map->k3 == AST__BAD ) { - if( astOK ) { - for ( point = 0; point < npoint; point++ ) { - ptr_out[ 0 ][ point ] = AST__BAD; - } - } - -/* Otherwise... */ - } else { - -/* Forward transformation. */ -/* ----------------------- */ - if ( forward ) { - -/* Loop to transform each input point. */ - for ( point = 0; point < npoint; point++ ) { - -/* Extract the input grism parameter value. */ - value_in = ptr_in[ 0 ][ point ]; - -/* Check for bad input coordinates and generate a bad result if necessary. */ - if( value_in == AST__BAD || map->k2 == 0.0 ) { - ptr_out[ 0 ][ point ] = AST__BAD; - -/* Otherwise, apply the algorithm described in FITS-WCS paper III. */ - } else { - ptr_out[ 0 ][ point ] = ( map->k1 + sin( atan( value_in ) + map->k3 ) )/map->k2; - } - } - -/* Inverse transformation. */ -/* ----------------------- */ - } else { - -/* Loop to transform each input point. */ - for ( point = 0; point < npoint; point++ ) { - -/* Extract the input wavelength value. */ - value_in = ptr_in[ 0 ][ point ]; - -/* Check for bad input coordinates and generate a bad result if necessary. */ - if ( value_in == AST__BAD ) { - ptr_out[ 0 ][ point ] = AST__BAD; - -/* Otherwise, apply the algorithm described in FITS-WCS paper III. */ - } else { - sinbeta = map->k2*value_in - map->k1; - if( sinbeta < -1.0 || sinbeta > 1.0 ) { - ptr_out[ 0 ][ point ] = AST__BAD; - } else { - ptr_out[ 0 ][ point ] = tan( asin( sinbeta ) - map->k3 ); - } - } - } - } - } - -/* Return a pointer to the output PointSet. */ - return result; -} - - -static void UpdateConstants( AstGrismMap *this, int *status ){ -/* -* Name: -* UpdateConstants - -* Purpose: -* Re-calculate the constants used within the transformation. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* void UpdateConstants( AstGrismMap *this, int *status ) - -* Class Membership: -* GrismMap member function - -* Description: -* This function re-calculates the constants used within the -* transformation on the basis of the current values of the -* GrismMap attributes. It should be called whenever a new value is -* set for an attribute, or an attribute is cleared. - -* Parameters: -* this -* Pointer to the GrismMap. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double alpha; /* The current vaue of the GrismAlpha attribute */ - double coseps; /* cos( eps ) */ - double sinalpha; /* sin( alpha ) */ - double eps; /* The current vaue of the GrismEps attribute */ - double g; /* The current vaue of the GrismG attribute */ - double nr; /* The current vaue of the GrismNR attribute */ - double nrp; /* The current vaue of the GrismNRP attribute */ - double sinbeta_r; /* sin( beta_r ) */ - double theta; /* The current vaue of the GrismTheta attribute */ - double wave_r; /* The current vaue of the GrismWaveR attribute */ - int m; /* The current vaue of the GrismM attribute */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the current attribute values. */ - nr = astGetGrismNR( this ); - nrp = astGetGrismNRP( this ); - wave_r = astGetGrismWaveR( this ); - alpha = astGetGrismAlpha( this ); - g = astGetGrismG( this ); - m = astGetGrismM( this ); - eps = astGetGrismEps( this ); - theta = astGetGrismTheta( this ); - -/* Re-calculate the constants. */ - coseps = cos( eps ); - sinalpha = sin( alpha ); - - this->k1 = sinalpha*( nr - nrp*wave_r ); - - if( coseps != 0.0 ) { - this->k2 = ( g*m/coseps ) - nrp*sinalpha; - - sinbeta_r = g*m*wave_r/coseps - nr*sinalpha; - if( sinbeta_r < -1.0 || sinbeta_r > 1.0 ) { - this->k3 = AST__BAD; - } else { - this->k3 = asin( sinbeta_r ) + theta; - } - - } else { - this->k2 = AST__BAD; - this->k3 = AST__BAD; - } - -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* GrismNR - -* Purpose: -* The refractive index at the reference wavelength. - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute holds refractive index of the grism material at the -* reference wavelength (given by attribute GrismWaveR). The default -* value is 1.0. -* -* Note, the value of this attribute may changed only if the GrismMap -* has no more than one reference. That is, an error is reported if the -* GrismMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* GrismMap -* All GrismMaps have this attribute. - -*att-- -*/ -MAKE_CLEAR(GrismMap,GrismNR,nr,(AST__BAD)) -astMAKE_GET(GrismMap,GrismNR,double,1.0,( ( this->nr == AST__BAD ) ? - 1.0 : this->nr )) -MAKE_SET(GrismMap,GrismNR,double,nr,(value) ) -astMAKE_TEST(GrismMap,GrismNR,( this->nr != AST__BAD )) - -/* -*att++ -* Name: -* GrismNRP - -* Purpose: -* The rate of change of refractive index with wavelength. - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute holds the rate of change of the refractive index of the -* grism material with respect to wavelength at the reference wavelength -* (given by attribute GrismWaveR). The default value is 0.0 (the -* appropriate value for a pure grating disperser with no prism). The -* units of this attribute should be consistent with those of attributes -* GrismWaveR and GrismG. -* -* Note, the value of this attribute may changed only if the GrismMap -* has no more than one reference. That is, an error is reported if the -* GrismMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* GrismMap -* All GrismMaps have this attribute. - -*att-- -*/ -MAKE_CLEAR(GrismMap,GrismNRP,nrp,(AST__BAD)) -astMAKE_GET(GrismMap,GrismNRP,double,0.0,( ( this->nrp == AST__BAD ) ? - 0.0 : this->nrp )) -MAKE_SET(GrismMap,GrismNRP,double,nrp,(value) ) -astMAKE_TEST(GrismMap,GrismNRP,( this->nrp != AST__BAD )) - -/* -*att++ -* Name: -* GrismWaveR - -* Purpose: -* The reference wavelength. - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute holds reference wavelength. The default value is -* 5000 (Angstrom). The units of this attribute should be consistent with -* those of attributes GrismNRP and GrismG. -* -* Note, the value of this attribute may changed only if the GrismMap -* has no more than one reference. That is, an error is reported if the -* GrismMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* GrismMap -* All GrismMaps have this attribute. - -*att-- -*/ -MAKE_CLEAR(GrismMap,GrismWaveR,waver,(AST__BAD)) -astMAKE_GET(GrismMap,GrismWaveR,double,5000.0,( ( this->waver == AST__BAD ) ? - 5000.0 : this->waver )) -MAKE_SET(GrismMap,GrismWaveR,double,waver,(value) ) -astMAKE_TEST(GrismMap,GrismWaveR,( this->waver != AST__BAD )) - -/* -*att++ -* Name: -* GrismAlpha - -* Purpose: -* The angle of incidence of the incoming light on the grating surface. - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute holds the angle between the incoming light and the -* normal to the grating surface, in radians. The default value is 0. -* -* Note, the value of this attribute may changed only if the GrismMap -* has no more than one reference. That is, an error is reported if the -* GrismMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* GrismMap -* All GrismMaps have this attribute. - -*att-- -*/ -MAKE_CLEAR(GrismMap,GrismAlpha,alpha,(AST__BAD)) -astMAKE_GET(GrismMap,GrismAlpha,double,0.0,( ( this->alpha == AST__BAD ) ? - 0.0 : this->alpha )) -MAKE_SET(GrismMap,GrismAlpha,double,alpha,(value) ) -astMAKE_TEST(GrismMap,GrismAlpha,( this->alpha != AST__BAD )) - -/* -*att++ -* Name: -* GrismG - -* Purpose: -* The grating ruling density. - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute holds the number of grating rulings per unit length. -* The unit of length used should be consistent with the units used -* for attributes GrismWaveR and GrismNRP. The default value is 0.0. -* (the appropriate value for a pure prism disperser with no grating). -* -* Note, the value of this attribute may changed only if the GrismMap -* has no more than one reference. That is, an error is reported if the -* GrismMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* GrismMap -* All GrismMaps have this attribute. - -*att-- -*/ -MAKE_CLEAR(GrismMap,GrismG,g,(AST__BAD)) -astMAKE_GET(GrismMap,GrismG,double,0.0,( ( this->g == AST__BAD ) ? - 0.0 : this->g )) -MAKE_SET(GrismMap,GrismG,double,g,(value) ) -astMAKE_TEST(GrismMap,GrismG,( this->g != AST__BAD )) - -/* -*att++ -* Name: -* GrismM - -* Purpose: -* The interference order - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute holds the interference order being considered. -* The default value is 0. -* -* Note, the value of this attribute may changed only if the GrismMap -* has no more than one reference. That is, an error is reported if the -* GrismMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* GrismMap -* All GrismMaps have this attribute. - -*att-- -*/ -MAKE_CLEAR(GrismMap,GrismM,m,(INT_MAX)) -astMAKE_GET(GrismMap,GrismM,int,0,( ( this->m == INT_MAX ) ? - 0 : this->m )) -MAKE_SET(GrismMap,GrismM,int,m,(value) ) -astMAKE_TEST(GrismMap,GrismM,( this->m != INT_MAX )) - -/* -*att++ -* Name: -* GrismEps - -* Purpose: -* The angle between the normal and the dispersion plane. - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute holds the angle (in radians) between the normal to -* the grating or exit prism face, and the dispersion plane. The -* dispersion plane is the plane spanned by the incoming and outgoing -* ray. The default value is 0.0. -* -* Note, the value of this attribute may changed only if the GrismMap -* has no more than one reference. That is, an error is reported if the -* GrismMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* GrismMap -* All GrismMaps have this attribute. - -*att-- -*/ -MAKE_CLEAR(GrismMap,GrismEps,eps,(AST__BAD)) -astMAKE_GET(GrismMap,GrismEps,double,0.0,( ( this->eps == AST__BAD ) ? - 0.0 : this->eps )) -MAKE_SET(GrismMap,GrismEps,double,eps,(value) ) -astMAKE_TEST(GrismMap,GrismEps,( this->eps != AST__BAD )) - -/* -*att++ -* Name: -* GrismTheta - -* Purpose: -* Angle between normal to detector plane and reference ray. - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute gives the angle of incidence of light of the -* reference wavelength (given by attribute GrismWaveR) onto the -* detector. Specifically, it holds the angle (in radians) between -* the normal to the detector plane and an incident ray at the reference -* wavelength. The default value is 0.0. -* -* Note, the value of this attribute may changed only if the GrismMap -* has no more than one reference. That is, an error is reported if the -* GrismMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* GrismMap -* All GrismMaps have this attribute. - -*att-- -*/ -MAKE_CLEAR(GrismMap,GrismTheta,theta,(AST__BAD)) -astMAKE_GET(GrismMap,GrismTheta,double,0.0,( ( this->theta == AST__BAD ) ? - 0.0 : this->theta )) -MAKE_SET(GrismMap,GrismTheta,double,theta,(value) ) -astMAKE_TEST(GrismMap,GrismTheta,( this->theta != AST__BAD )) - -/* Copy constructor. */ -/* ----------------- */ -/* No copy constructor is needed, as a byte-by-byte copy suffices. */ - -/* Destructor. */ -/* ----------- */ -/* No destructor is needed as no memory, etc. needs freeing. */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for GrismMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the GrismMap class to an output Channel. - -* Parameters: -* this -* Pointer to the GrismMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstGrismMap *this; /* Pointer to the GrismMap structure */ - double dval; /* Double value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the GrismMap structure. */ - this = (AstGrismMap *) this_object; - -/* Write out values representing the instance variables for the - GrismMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - - set = TestGrismNR( this, status ); - dval = set ? GetGrismNR( this, status ) : astGetGrismNR( this ); - astWriteDouble( channel, "GrmNR", set, 1, dval, "Refractive index at the ref. wavelength" ); - - set = TestGrismNRP( this, status ); - dval = set ? GetGrismNRP( this, status ) : astGetGrismNRP( this ); - astWriteDouble( channel, "GrmNRP", set, 1, dval, "Rate of change of refractive index" ); - - set = TestGrismWaveR( this, status ); - dval = set ? GetGrismWaveR( this, status ) : astGetGrismWaveR( this ); - astWriteDouble( channel, "GrmWR", set, 1, dval, "Ref. wavelength" ); - - set = TestGrismAlpha( this, status ); - dval = set ? GetGrismAlpha( this, status ) : astGetGrismAlpha( this ); - astWriteDouble( channel, "GrmAlp", set, 1, dval, "Angle of incidence of incoming light" ); - - set = TestGrismG( this, status ); - dval = set ? GetGrismG( this, status ) : astGetGrismG( this ); - astWriteDouble( channel, "GrmG", set, 1, dval, "Grating ruling density" ); - - set = TestGrismM( this, status ); - dval = set ? GetGrismM( this, status ) : astGetGrismM( this ); - astWriteDouble( channel, "GrmM", set, 1, dval, "The interference order" ); - - set = TestGrismEps( this, status ); - dval = set ? GetGrismEps( this, status ) : astGetGrismEps( this ); - astWriteDouble( channel, "GrmEps", set, 1, dval, "Angle between grating normal and dispersion plane" ); - - set = TestGrismTheta( this, status ); - dval = set ? GetGrismTheta( this, status ) : astGetGrismTheta( this ); - astWriteDouble( channel, "GrmTh", set, 1, dval, "Angle between detector normal and reference ray" ); - -} - - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAGrismMap and astCheckGrismMap functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(GrismMap,Mapping) -astMAKE_CHECK(GrismMap) - -AstGrismMap *astGrismMap_( const char *options, int *status, ...) { -/* -*++ -* Name: -c astGrismMap -f AST_GRISMMAP - -* Purpose: -* Create a GrismMap. - -* Type: -* Public function. - -* Synopsis: -c #include "grismmap.h" -c AstGrismMap *astGrismMap( const char *options, ... ) -f RESULT = AST_GRISMMAP( OPTIONS, STATUS ) - -* Class Membership: -* GrismMap constructor. - -* Description: -* This function creates a new GrismMap and optionally initialises -* its attributes. -* -* A GrismMap is a specialised form of Mapping which transforms -* 1-dimensional coordinates using the spectral dispersion equation -* described in FITS-WCS paper III "Representation of spectral -* coordinates in FITS". This describes the dispersion produced by -* gratings, prisms and grisms. -* -* When initially created, the forward transformation of a GrismMap -* transforms input "grism parameter" values into output wavelength -* values. The "grism parameter" is a dimensionless value which is -* linearly related to position on the detector. It is defined in FITS-WCS -* paper III as "the offset on the detector from the point of intersection -* of the camera axis, measured in units of the effective local length". -* The units in which wavelength values are expected or returned is -* determined by the values supplied for the GrismWaveR, GrismNRP and -* GrismG attribute: whatever units are used for these attributes will -* also be used for the wavelength values. - -* Parameters: -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new GrismMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new GrismMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGrismMap() -f AST_GRISMMAP = INTEGER -* A pointer to the new GrismMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstGrismMap *new; /* Pointer to new GrismMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the GrismMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitGrismMap( NULL, sizeof( AstGrismMap ), !class_init, - &class_vtab, "GrismMap" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - GrismMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new GrismMap. */ - return new; -} - -AstGrismMap *astGrismMapId_( const char *options, ... ) { -/* -* Name: -* astGrismMapId_ - -* Purpose: -* Create a GrismMap. - -* Type: -* Private function. - -* Synopsis: -* #include "grismmap.h" -* AstGrismMap *astGrismMapId( const char *options, int *status, ... ) - -* Class Membership: -* GrismMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astGrismMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astGrismMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astGrismMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astGrismMap_. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The ID value associated with the new GrismMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstGrismMap *new; /* Pointer to new GrismMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the GrismMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitGrismMap( NULL, sizeof( AstGrismMap ), !class_init, - &class_vtab, "GrismMap" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new GrismMap's - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new GrismMap. */ - return astMakeId( new ); -} - -AstGrismMap *astInitGrismMap_( void *mem, size_t size, int init, - AstGrismMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitGrismMap - -* Purpose: -* Initialise a GrismMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "grismmap.h" -* AstGrismMap *astInitGrismMap( void *mem, size_t size, int init, -* AstGrismMapVtab *vtab, const char *name ) - -* Class Membership: -* GrismMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new GrismMap object. It allocates memory (if necessary) to accommodate -* the GrismMap plus any additional data associated with the derived class. -* It then initialises a GrismMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a GrismMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the GrismMap is to be initialised. -* This must be of sufficient size to accommodate the GrismMap data -* (sizeof(GrismMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the GrismMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the GrismMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the GrismMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new GrismMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). - -* Returned Value: -* A pointer to the new GrismMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstGrismMap *new; /* Pointer to new GrismMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitGrismMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a Mapping structure (the parent class) as the first component - within the GrismMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstGrismMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - 1, 1, 1, 1 ); - if ( astOK ) { - -/* Initialise the GrismMap data. */ -/* ---------------------------- */ - new->nr = AST__BAD; - new->nrp = AST__BAD; - new->waver = AST__BAD; - new->alpha = AST__BAD; - new->g = AST__BAD; - new->m = INT_MAX; - new->eps = AST__BAD; - new->theta = AST__BAD; - -/* Set up the other required derived constants. */ - UpdateConstants( new, status ); - -/* If an error occurred, clean up by deleting the new GrismMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new GrismMap. */ - return new; -} - -AstGrismMap *astLoadGrismMap_( void *mem, size_t size, - AstGrismMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadGrismMap - -* Purpose: -* Load a GrismMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "grismmap.h" -* AstGrismMap *astLoadGrismMap( void *mem, size_t size, -* AstGrismMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* GrismMap loader. - -* Description: -* This function is provided to load a new GrismMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* GrismMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a GrismMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the GrismMap is to be -* loaded. This must be of sufficient size to accommodate the -* GrismMap data (sizeof(GrismMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the GrismMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the GrismMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstGrismMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new GrismMap. If this is NULL, a pointer -* to the (static) virtual function table for the GrismMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "GrismMap" is used instead. - -* Returned Value: -* A pointer to the new GrismMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstGrismMap *new; /* Pointer to the new GrismMap */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this GrismMap. In this case the - GrismMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstGrismMap ); - vtab = &class_vtab; - name = "GrismMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitGrismMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built GrismMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "GrismMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - - new->nr = astReadDouble( channel, "grmnr", AST__BAD ); - if ( TestGrismNR( new, status ) ) SetGrismNR( new, new->nr, status ); - - new->nrp = astReadDouble( channel, "grmnrp", AST__BAD ); - if ( TestGrismNRP( new, status ) ) SetGrismNRP( new, new->nrp, status ); - - new->waver = astReadDouble( channel, "grmwr", AST__BAD ); - if ( TestGrismWaveR( new, status ) ) SetGrismWaveR( new, new->waver, status ); - - new->alpha = astReadDouble( channel, "grmalp", AST__BAD ); - if ( TestGrismAlpha( new, status ) ) SetGrismAlpha( new, new->alpha, status ); - - new->g = astReadDouble( channel, "grmg", AST__BAD ); - if ( TestGrismG( new, status ) ) SetGrismG( new, new->g, status ); - - new->m = astReadInt( channel, "grmm", INT_MAX ); - if ( TestGrismM( new, status ) ) SetGrismM( new, new->m, status ); - - new->eps = astReadDouble( channel, "grmeps", AST__BAD ); - if ( TestGrismEps( new, status ) ) SetGrismEps( new, new->eps, status ); - - new->theta = astReadDouble( channel, "grmth", AST__BAD ); - if ( TestGrismTheta( new, status ) ) SetGrismTheta( new, new->theta, status ); - -/* Set up the other required derived constants. */ - UpdateConstants( new, status ); - } - -/* If an error occurred, clean up by deleting the new GrismMap. */ - if ( !astOK ) new = astDelete( new ); - -/* Return the new GrismMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions - defined by this class. Each simply checks the global error status - and then locates and executes the appropriate member function, - using the function pointer stored in the object's virtual function - table (this pointer is located using the astMEMBER macro defined in - "object.h"). - - Note that the member function may not be the one defined here, as - it may have been over-ridden by a derived class. However, it should - still have the same interface. */ - - - - - diff --git a/ast/grismmap.h b/ast/grismmap.h deleted file mode 100644 index 5655be0..0000000 --- a/ast/grismmap.h +++ /dev/null @@ -1,353 +0,0 @@ -#if !defined( GRISMMAP_INCLUDED ) /* Include this file only once */ -#define GRISMMAP_INCLUDED -/* -*+ -* Name: -* grismmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the GrismMap class. - -* Invocation: -* #include "grismmap.h" - -* Description: -* This include file defines the interface to the GrismMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The GrismMap class implements Mappings which perform a "zoom" -* transformation by multiplying all coordinate values by the same -* scale factor (the inverse transformation is performed by -* dividing by this scale factor). - -* Inheritance: -* The GrismMap class inherits from the Mapping class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 8-JUL-2003 (DSB): -* Initial version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* GrismMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstGrismMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double nr; - double nrp; - double waver; - double alpha; - double g; - int m; - double eps; - double theta; - double k1; - double k2; - double k3; - -} AstGrismMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstGrismMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - double (* GetGrismNR)( AstGrismMap *, int * ); - int (* TestGrismNR)( AstGrismMap *, int * ); - void (* ClearGrismNR)( AstGrismMap *, int * ); - void (* SetGrismNR)( AstGrismMap *, double, int * ); - - double (* GetGrismNRP)( AstGrismMap *, int * ); - int (* TestGrismNRP)( AstGrismMap *, int * ); - void (* ClearGrismNRP)( AstGrismMap *, int * ); - void (* SetGrismNRP)( AstGrismMap *, double, int * ); - - double (* GetGrismWaveR)( AstGrismMap *, int * ); - int (* TestGrismWaveR)( AstGrismMap *, int * ); - void (* ClearGrismWaveR)( AstGrismMap *, int * ); - void (* SetGrismWaveR)( AstGrismMap *, double, int * ); - - double (* GetGrismAlpha)( AstGrismMap *, int * ); - int (* TestGrismAlpha)( AstGrismMap *, int * ); - void (* ClearGrismAlpha)( AstGrismMap *, int * ); - void (* SetGrismAlpha)( AstGrismMap *, double, int * ); - - double (* GetGrismG)( AstGrismMap *, int * ); - int (* TestGrismG)( AstGrismMap *, int * ); - void (* ClearGrismG)( AstGrismMap *, int * ); - void (* SetGrismG)( AstGrismMap *, double, int * ); - - int (* GetGrismM)( AstGrismMap *, int * ); - int (* TestGrismM)( AstGrismMap *, int * ); - void (* ClearGrismM)( AstGrismMap *, int * ); - void (* SetGrismM)( AstGrismMap *, int, int * ); - - double (* GetGrismEps)( AstGrismMap *, int * ); - int (* TestGrismEps)( AstGrismMap *, int * ); - void (* ClearGrismEps)( AstGrismMap *, int * ); - void (* SetGrismEps)( AstGrismMap *, double, int * ); - - double (* GetGrismTheta)( AstGrismMap *, int * ); - int (* TestGrismTheta)( AstGrismMap *, int * ); - void (* ClearGrismTheta)( AstGrismMap *, int * ); - void (* SetGrismTheta)( AstGrismMap *, double, int * ); - -} AstGrismMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstGrismMapGlobals { - AstGrismMapVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 101 ]; -} AstGrismMapGlobals; - -#endif -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(GrismMap) /* Check class membership */ -astPROTO_ISA(GrismMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstGrismMap *astGrismMap_( const char *, int *, ...); -#else -AstGrismMap *astGrismMapId_( const char *, ... )__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstGrismMap *astInitGrismMap_( void *, size_t, int, AstGrismMapVtab *, - const char *, int * ); - -/* Vtab initialiser. */ -void astInitGrismMapVtab_( AstGrismMapVtab *, const char *, int * ); - -/* Loader. */ -AstGrismMap *astLoadGrismMap_( void *, size_t, AstGrismMapVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitGrismMapGlobals_( AstGrismMapGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ - - double astGetGrismNR_( AstGrismMap *, int * ); - int astTestGrismNR_( AstGrismMap *, int * ); - void astClearGrismNR_( AstGrismMap *, int * ); - void astSetGrismNR_( AstGrismMap *, double, int * ); - - double astGetGrismNRP_( AstGrismMap *, int * ); - int astTestGrismNRP_( AstGrismMap *, int * ); - void astClearGrismNRP_( AstGrismMap *, int * ); - void astSetGrismNRP_( AstGrismMap *, double, int * ); - - double astGetGrismWaveR_( AstGrismMap *, int * ); - int astTestGrismWaveR_( AstGrismMap *, int * ); - void astClearGrismWaveR_( AstGrismMap *, int * ); - void astSetGrismWaveR_( AstGrismMap *, double, int * ); - - double astGetGrismAlpha_( AstGrismMap *, int * ); - int astTestGrismAlpha_( AstGrismMap *, int * ); - void astClearGrismAlpha_( AstGrismMap *, int * ); - void astSetGrismAlpha_( AstGrismMap *, double, int * ); - - double astGetGrismG_( AstGrismMap *, int * ); - int astTestGrismG_( AstGrismMap *, int * ); - void astClearGrismG_( AstGrismMap *, int * ); - void astSetGrismG_( AstGrismMap *, double, int * ); - - int astGetGrismM_( AstGrismMap *, int * ); - int astTestGrismM_( AstGrismMap *, int * ); - void astClearGrismM_( AstGrismMap *, int * ); - void astSetGrismM_( AstGrismMap *, int, int * ); - - double astGetGrismEps_( AstGrismMap *, int * ); - int astTestGrismEps_( AstGrismMap *, int * ); - void astClearGrismEps_( AstGrismMap *, int * ); - void astSetGrismEps_( AstGrismMap *, double, int * ); - - double astGetGrismTheta_( AstGrismMap *, int * ); - int astTestGrismTheta_( AstGrismMap *, int * ); - void astClearGrismTheta_( AstGrismMap *, int * ); - void astSetGrismTheta_( AstGrismMap *, double, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckGrismMap(this) astINVOKE_CHECK(GrismMap,this,0) -#define astVerifyGrismMap(this) astINVOKE_CHECK(GrismMap,this,1) - -/* Test class membership. */ -#define astIsAGrismMap(this) astINVOKE_ISA(GrismMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astGrismMap astINVOKE(F,astGrismMap_) -#else -#define astGrismMap astINVOKE(F,astGrismMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitGrismMap(mem,size,init,vtab,name) \ -astINVOKE(O,astInitGrismMap_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitGrismMapVtab(vtab,name) astINVOKE(V,astInitGrismMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadGrismMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadGrismMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckGrismMap to validate GrismMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ - -#define astGetGrismNR(this) astINVOKE(V,astGetGrismNR_(astCheckGrismMap(this),STATUS_PTR)) -#define astTestGrismNR(this) astINVOKE(V,astTestGrismNR_(astCheckGrismMap(this),STATUS_PTR)) -#define astClearGrismNR(this) astINVOKE(V,astClearGrismNR_(astCheckGrismMap(this),STATUS_PTR)) -#define astSetGrismNR(this,value) astINVOKE(V,astSetGrismNR_(astCheckGrismMap(this),value,STATUS_PTR)) - -#define astGetGrismNRP(this) astINVOKE(V,astGetGrismNRP_(astCheckGrismMap(this),STATUS_PTR)) -#define astTestGrismNRP(this) astINVOKE(V,astTestGrismNRP_(astCheckGrismMap(this),STATUS_PTR)) -#define astClearGrismNRP(this) astINVOKE(V,astClearGrismNRP_(astCheckGrismMap(this),STATUS_PTR)) -#define astSetGrismNRP(this,value) astINVOKE(V,astSetGrismNRP_(astCheckGrismMap(this),value,STATUS_PTR)) - -#define astGetGrismWaveR(this) astINVOKE(V,astGetGrismWaveR_(astCheckGrismMap(this),STATUS_PTR)) -#define astTestGrismWaveR(this) astINVOKE(V,astTestGrismWaveR_(astCheckGrismMap(this),STATUS_PTR)) -#define astClearGrismWaveR(this) astINVOKE(V,astClearGrismWaveR_(astCheckGrismMap(this),STATUS_PTR)) -#define astSetGrismWaveR(this,value) astINVOKE(V,astSetGrismWaveR_(astCheckGrismMap(this),value,STATUS_PTR)) - -#define astGetGrismAlpha(this) astINVOKE(V,astGetGrismAlpha_(astCheckGrismMap(this),STATUS_PTR)) -#define astTestGrismAlpha(this) astINVOKE(V,astTestGrismAlpha_(astCheckGrismMap(this),STATUS_PTR)) -#define astClearGrismAlpha(this) astINVOKE(V,astClearGrismAlpha_(astCheckGrismMap(this),STATUS_PTR)) -#define astSetGrismAlpha(this,value) astINVOKE(V,astSetGrismAlpha_(astCheckGrismMap(this),value,STATUS_PTR)) - -#define astGetGrismG(this) astINVOKE(V,astGetGrismG_(astCheckGrismMap(this),STATUS_PTR)) -#define astTestGrismG(this) astINVOKE(V,astTestGrismG_(astCheckGrismMap(this),STATUS_PTR)) -#define astClearGrismG(this) astINVOKE(V,astClearGrismG_(astCheckGrismMap(this),STATUS_PTR)) -#define astSetGrismG(this,value) astINVOKE(V,astSetGrismG_(astCheckGrismMap(this),value,STATUS_PTR)) - -#define astGetGrismM(this) astINVOKE(V,astGetGrismM_(astCheckGrismMap(this),STATUS_PTR)) -#define astTestGrismM(this) astINVOKE(V,astTestGrismM_(astCheckGrismMap(this),STATUS_PTR)) -#define astClearGrismM(this) astINVOKE(V,astClearGrismM_(astCheckGrismMap(this),STATUS_PTR)) -#define astSetGrismM(this,value) astINVOKE(V,astSetGrismM_(astCheckGrismMap(this),value,STATUS_PTR)) - -#define astGetGrismEps(this) astINVOKE(V,astGetGrismEps_(astCheckGrismMap(this),STATUS_PTR)) -#define astTestGrismEps(this) astINVOKE(V,astTestGrismEps_(astCheckGrismMap(this),STATUS_PTR)) -#define astClearGrismEps(this) astINVOKE(V,astClearGrismEps_(astCheckGrismMap(this),STATUS_PTR)) -#define astSetGrismEps(this,value) astINVOKE(V,astSetGrismEps_(astCheckGrismMap(this),value,STATUS_PTR)) - -#define astGetGrismTheta(this) astINVOKE(V,astGetGrismTheta_(astCheckGrismMap(this),STATUS_PTR)) -#define astTestGrismTheta(this) astINVOKE(V,astTestGrismTheta_(astCheckGrismMap(this),STATUS_PTR)) -#define astClearGrismTheta(this) astINVOKE(V,astClearGrismTheta_(astCheckGrismMap(this),STATUS_PTR)) -#define astSetGrismTheta(this,value) astINVOKE(V,astSetGrismTheta_(astCheckGrismMap(this),value,STATUS_PTR)) - - -#endif -#endif - - - - - diff --git a/ast/interval.c b/ast/interval.c deleted file mode 100644 index a25768d..0000000 --- a/ast/interval.c +++ /dev/null @@ -1,4686 +0,0 @@ -/* -*class++ -* Name: -* Interval - -* Purpose: -* A region representing an interval on one or more axes of a Frame. - -* Constructor Function: -c astInterval -f AST_INTERVAL - -* Description: -* The Interval class implements a Region which represents upper -* and/or lower limits on one or more axes of a Frame. For a point to -* be within the region represented by the Interval, the point must -* satisfy all the restrictions placed on all the axes. The point is -* outside the region if it fails to satisfy any one of the restrictions. -* Each axis may have either an upper limit, a lower limit, both or -* neither. If both limits are supplied but are in reverse order (so -* that the lower limit is greater than the upper limit), then the -* interval is an excluded interval, rather than an included interval. -* -* Note, The Interval class makes no allowances for cyclic nature of -* some coordinate systems (such as SkyFrame coordinates). A Box -* should usually be used in these cases since this requires the user -* to think about suitable upper and lower limits, - -* Inheritance: -* The Interval class inherits from the Region class. - -* Attributes: -* The Interval class does not define any new attributes beyond -* those which are applicable to all Regions. - -* Functions: -c The Interval class does not define any new functions beyond those -f The Interval class does not define any new routines beyond those -* which are applicable to all Regions. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 29-OCT-2004 (DSB): -* Original version. -* 19-APR-2006 (DSB): -* Negate the cached equivalent Box if the Interval has been negated. -* 28-MAY-2007 (DSB): -* Re-implemented BndBaseMesh. -* 20-JAN-2009 (DSB): -* Over-ride astRegBasePick. -* 26-JAN-2009 (DSB): -* Over-ride astMapMerge. -* 4-NOV42-2013 (DSB): -* - Change RegCentre so that it does not report an error for an unbounded -* Interval if the centre is merely being inquired rather than set. This is -* the documented behaviour of the astRegCentre method. -* - Modify RegPins so that it can handle uncertainty regions that straddle -* a discontinuity. Previously, such uncertainty Regions could have a huge -* bounding box resulting in matching region being far too big. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Interval - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "region.h" /* Abstract coordinate regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "box.h" /* Box Regions */ -#include "nullregion.h" /* Null Regions */ -#include "wcsmap.h" /* Definitons of AST__DPI etc */ -#include "interval.h" /* Interface definition for this class */ -#include "ellipse.h" /* Interface definition for ellipse class */ -#include "mapping.h" /* Position mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "cmpframe.h" /* Compound Frames */ -#include "prism.h" /* Prism regions */ -#include "pointlist.h" /* Lists of points in a Frame */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstMapping *(* parent_simplify)( AstMapping *, int * ); -static int (* parent_overlap)( AstRegion *, AstRegion *, int * ); -static void (* parent_setregfs)( AstRegion *, AstFrame *, int * ); -static void (* parent_setunc)( AstRegion *, AstRegion *, int * ); -static void (* parent_resetcache)( AstRegion *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Interval) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Interval,Class_Init) -#define class_vtab astGLOBAL(Interval,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstIntervalVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstInterval *astIntervalId_( void *, const double[], const double[], void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstBox *Cache( AstInterval *, int * ); -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *BndBaseMesh( AstRegion *, double *, double *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *RegBasePick( AstRegion *this, int, const int *, int * ); -static AstRegion *GetDefUnc( AstRegion *, int * ); -static AstRegion *MergeInterval( AstInterval *, AstRegion *, int, int * ); -static double *RegCentre( AstRegion *this, double *, double **, int, int, int * ); -static int *OneToOne( AstMapping *, int * ); -static int GetBounded( AstRegion *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int Overlap( AstRegion *, AstRegion *, int * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static int RegTrace( AstRegion *, int, double *, double **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void IntervalPoints( AstInterval *, double *, double *, int *); -static void RegBaseBox( AstRegion *this, double *, double *, int * ); -static void ResetCache( AstRegion *this, int * ); -static void SetRegFS( AstRegion *, AstFrame *, int * ); -static void SetUnc( AstRegion *, AstRegion *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ - -static AstPointSet *BndBaseMesh( AstRegion *this, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* BndBaseMesh - -* Purpose: -* Return a PointSet containing points spread around part of the boundary -* of a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* AstPointSet *BndBaseMesh( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* Interval method (over-rides the astBndBaseMesh method inherited from -* the Region class). - -* Description: -* This function returns a PointSet containing a set of points on the -* boundary of the intersection between the supplied Region and the -* supplied box. The points refer to the base Frame of the -* encapsulated FrameSet. If the boundary of the supplied Region does -* not intersect the supplied box, then a PointSet containing a single -* bad point is returned. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array holding the lower limits of the axis values -* within the required box. -* ubnd -* Pointer to an array holding the upper limits of the axis values -* within the required box. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. The axis values in this PointSet will have -* associated accuracies derived from the uncertainties which were -* supplied when the Region was created. -* -* If the Region does not intersect the supplied box, the returned -* PointSet will contain a single point with a value of AST__BAD on -* every axis. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstBox *box; - AstFrame *bfrm; - AstInterval *this_interval; - AstMapping *map; - AstPointSet *result; - double *lbndb; - double *ubndb; - double **ptr; - int closed; - int i; - int nbase; - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Store a pointer to the interval. */ - this_interval = (AstInterval *) this; - -/* If the Interval is effectively a Box, invoke the astBndBaseMesh - function on the equivalent Box. A pointer to the equivalent Box will - be stored in the Interval structure. */ - box = Cache( (AstInterval *) this, status ); - if( box ) { - result = astBndBaseMesh( box, lbnd, ubnd ); - -/* If the Interval is not equivalent to a Box (i.e. if one or more bounds - are missing)... */ - } else { - -/* Find the base frame box that just encloses the supplied current Frame - box. */ - map = astGetMapping( this->frameset, AST__CURRENT, AST__BASE ); - nbase = astGetNout( map ); - lbndb = astMalloc( sizeof(double)*nbase ); - ubndb = astMalloc( sizeof(double)*nbase ); - if( astOK ) { - for( i = 0; i < nbase; i++ ) { - astMapBox( map, lbnd, ubnd, 1, i, lbndb + i, ubndb + i, - NULL, NULL ); - } - -/* Create a Box that is like this Interval except that missing bounds are - inherited from the supplied limits. Check that the resulting box is - closed. */ - closed = 1; - for( i = 0; i < nbase; i++ ) { - if( this_interval->ubnd[ i ] != DBL_MAX ) ubndb[ i ] = this_interval->ubnd[ i ]; - if( this_interval->lbnd[ i ] != -DBL_MAX ) lbndb[ i ] = this_interval->lbnd[ i ]; - if( lbndb[ i ] > ubndb[ i ] ) closed = 0; - } - -/* Cannot create the required mesh if the box is not closed. */ - if( closed ) { - -/* Create the Box. */ - bfrm = astGetFrame( this->frameset, AST__BASE ); - box = astBox( bfrm, 1, lbndb, ubndb, NULL, "", status ); - -/* Create the required mesh. */ - result = astRegBaseMesh( box ); - -/* Free resources */ - bfrm = astAnnul( bfrm ); - box = astAnnul( box ); - -/* If the boundary of the supplied Region does not intersect the box, - return a PointSet containing a single bad position. */ - } else { - result = astPointSet( 1, nbase, "", status ); - ptr = astGetPoints( result ); - if( astOK ) { - for( i = 0; i < nbase; i++ ) ptr[ i ][ 0 ] = AST__BAD; - } - } - } - -/* Free resources. */ - map = astAnnul( map ); - lbndb = astFree( lbndb ); - ubndb = astFree( ubndb ); - } - -/* Return NULL if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the required pointer. */ - return result; -} - -static AstBox *Cache( AstInterval *this, int *status ){ -/* -* Name: -* Cache - -* Purpose: -* Calculate intermediate values and cache them in the Interval structure. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* AstBox *Cache( AstInterval *this, int *status ) - -* Class Membership: -* Interval member function - -* Description: -* This function uses the PointSet stored in the parent Region to calculate -* some intermediate values which are useful in other methods. These -* values are stored within the Interval structure. - -* Parameters: -* this -* Pointer to the Interval. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If the Interval is equivalent to a Box, then a pointer to the -* equivalent Box is returned. This is a copy of the pointer stored in -* the Interval structure and should not be annulled. - -*/ - -/* Local Variables: */ - AstBox *bbox; /* Equivalent base Box */ - AstFrame *bfrm; /* Interval base Frame */ - AstFrame *cfrm; /* Interval current Frame */ - AstRegion *map; /* Interval base->current Mapping */ - AstRegion *reg; /* Pointer to this Region structure */ - AstRegion *unc; /* Pointer to uncertainty Region */ - double **ptr; /* Pointer to data holding all axis limits */ - double *lbnd; /* Pointer to array of lower axis limits */ - double *ubnd; /* Pointer to array of upper axis limits */ - int i; /* Axis index */ - int isBox; /* Is this Interval equivalent to a Box? */ - int nc; /* Number of base Frame axes */ - int neg; /* Is the equivalent Box negated? */ - -/* Check the global error status. Also return if the cached information - is up to date (i.e. not stale). */ - if( !this->stale || !astOK ) return this->box; - -/* Get a pointer to the Region structure */ - reg = (AstRegion *) this; - -/* The Interval structure contains a pointer to an equivalent Box - structure. This Box structure is created below if the Interval is - equivalent to a Box. Annul any previous box. */ - if( this->box ) this->box = astAnnul( this->box ); - -/* Get the number of axes in the base Frame of the FrameSet encapsulated - by the parent Region structure. */ - nc = astGetNin( reg->frameset ); - -/* Get a pointer to the array holding the axis limits held in the PointSet - encapsulated in the parent Region structure. */ - ptr = astGetPoints( reg->points ); - -/* Allocate memory to hold the limits organised per point rather than per - axis. */ - lbnd = astMalloc( sizeof( double )*(size_t)nc ); - ubnd = astMalloc( sizeof( double )*(size_t)nc ); - -/* Check these pointers can be used safely. */ - if( ubnd ) { - -/* See if the Interval is effectively a (possibly negated) Box. Assume it - is to begin with. */ - isBox = 1; - -/* Initialisation to prevent compiler warnings. */ - neg = 0; - -/* Check the limits on every axis. */ - for( i = 0; i < nc; i++ ) { - -/* Copy the axis limits into the allocated arrays (these are needed by the - Box constructor later on). */ - lbnd[ i ] = ptr[ i ][ 0 ]; - ubnd[ i ] = ptr[ i ][ 1 ]; - -/* The Interval is not a Box if any axis limit is missing. In this case - use -DBL_MAX or +DBL_MAX as the limit to be stored in the Interval - structure. */ - if( lbnd[ i ] == AST__BAD ) lbnd[ i ] = -DBL_MAX; - if( fabs( lbnd[ i ] ) == DBL_MAX ) isBox = 0; - - if( ubnd[ i ] == AST__BAD ) ubnd[ i ] = DBL_MAX; - if( fabs( ubnd[ i ] ) == DBL_MAX ) isBox = 0; - -/* If this is the first axis, note if the axis interval is included or - excluded. This is determined by whether the "lower limit" is greater - than or less than the "upper limit". If the axis interval is excluded - (lower limit greater than upper limit), then any equivalent Box will be - a negated Box (i.e. will represent the outside of a box rather than - the inside). */ - if( i == 0 ){ - neg = ( lbnd[ i ] > ubnd[ i ] ); - -/* The Interval is not a Box if the limits for this axis are not the same - way round as those of the first axis. */ - } else { - - if( neg ) { - if( lbnd[ i ] < ubnd[ i ] ) isBox = 0; - } else { - if( lbnd[ i ] > ubnd[ i ] ) isBox = 0; - } - - } - } - -/* If the Interval is effectively an unnegated Box, create the equivalent Box, - and store a pointer to it in the Interval structure. */ - if( isBox && !neg ) { - bfrm = astGetFrame( reg->frameset, AST__BASE ); - cfrm = astGetFrame( reg->frameset, AST__CURRENT ); - map = astGetMapping( reg->frameset, AST__BASE, AST__CURRENT ); - unc = astTestUnc( reg ) ? astGetUncFrm( reg, AST__BASE ) : NULL; - - bbox = astBox( bfrm, 1, lbnd, ubnd, unc, "", status ); - if( astIsAUnitMap( map ) ){ - this->box = astClone( bbox ); - } else { - this->box = astMapRegion( bbox, map, cfrm ); - } - - if( unc ) unc = astAnnul( unc ); - cfrm = astAnnul( cfrm ); - bfrm = astAnnul( bfrm ); - map = astAnnul( map ); - bbox = astAnnul( bbox ); - -/* If the supplied Interval has been negated, negate the equivalent Box. */ - if( astGetNegated( this ) ) astNegate( this->box ); - -/* If the supplied Interval is closed, ensure the equivalent Box is closed. */ - astSetClosed( this->box, astGetClosed( this ) ); - } - -/* Store the axis limits in the Interval structure. */ - if( this->lbnd ) astFree( this->lbnd ); - if( this->ubnd ) astFree( this->ubnd ); - this->lbnd = lbnd; - this->ubnd = ubnd; - } - -/* Indicate the cached information is no longer stale, and return a - pointer to any equivalent Box. */ - this->stale = 0; - return this->box; -} - -static int GetBounded( AstRegion *this, int *status ) { -/* -* Name: -* GetBounded - -* Purpose: -* Is the Region bounded? - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* int GetBounded( AstRegion *this, int *status ) - -* Class Membership: -* Interval method (over-rides the astGetBounded method inherited from -* the Region class). - -* Description: -* This function returns a flag indicating if the Region is bounded. -* The implementation provided by the base Region class is suitable -* for Region sub-classes representing the inside of a single closed -* curve (e.g. Circle, Interval, Box, etc). Other sub-classes (such as -* CmpRegion, PointList, etc ) may need to provide their own -* implementations. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Region is bounded. Zero otherwise. - -*/ - -/* Local Variables: */ - int result; /* Returned result */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* The unnegated Interval is bounded only if there is an equivalent Box - structure stored in the Interval structure. */ - if( Cache( (AstInterval *) this, status ) ) result = 1; - -/* Return the required pointer. */ - return result; -} - -static AstRegion *GetDefUnc( AstRegion *this_region, int *status ) { -/* -* Name: -* GetDefUnc - -* Purpose: -* Obtain a pointer to the default uncertainty Region for a given Region. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* AstRegion *GetDefUnc( AstRegion *this, int *status ) - -* Class Membership: -* Interval member function (over-rides the astGetDefUnc protected -* method inherited from the Region class). - -* Description: -* This function returns a pointer to a Region which represents the -* default uncertainty associated with a position on the boundary of the -* given Region. The returned Region refers to the base Frame within the -* FrameSet encapsulated by the supplied Region. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the Region. This should be annulled (using astAnnul) -* when no longer needed. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstBox *box; /* Pointer to equivalent Box */ - AstFrame *bfrm; /* Base Frame of supplied Region */ - AstInterval *this; /* Pointer to Interval structure */ - AstRegion *result; /* Returned pointer */ - double *lbnd; /* Ptr. to array holding axis lower bounds */ - double *ubnd; /* Ptr. to array holding axis upper bounds */ - double c; /* Central axis value */ - double hw; /* Half width of uncertainty interval */ - int i; /* Axis index */ - int nax; /* Number of base Frame axes */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Interval structure. */ - this = (AstInterval *) this_region; - -/* If this Interval is equivalent to a Box, get the default uncertainty - for the equivalent Box and return it. */ - box = Cache( this, status ); - if( box ) { - result = astGetDefUnc( box ); - -/* Otherwise, we use a box covering 1.0E-6 of each axis interval, centred on - the origin. */ - } else { - -/* Get a pointer to the base Frame. */ - bfrm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Get the number of base Frame axes. */ - nax = astGetNaxes( bfrm ); - -/* Allocate arrays to hold the bounds of the uncertainty Box. */ - lbnd = astMalloc( sizeof( double)*(size_t) nax ); - ubnd = astMalloc( sizeof( double)*(size_t) nax ); - if( astOK ) { - -/* Ensure cached information (e.g.bounds) is up to date. */ - Cache( this, status ); - -/* Do each axis in turn */ - for( i = 0; i < nax; i++ ) { - -/* If this axis has both limits, use 1.0E-6 of the difference between the - limits. */ - if( this->lbnd[ i ] != -DBL_MAX && - this->ubnd[ i ] != DBL_MAX ) { - hw = fabs( 0.5E-6*( this->ubnd[ i ] - this->lbnd[ i ] ) ); - c = 0.5*( this->ubnd[ i ] + this->lbnd[ i ] ); - if( hw == 0.0 ) hw = c*0.5E-6; - ubnd[ i ] = c + hw; - lbnd[ i ] = c - hw; - -/* Otherwise use zero. */ - } else { - ubnd[ i ] = 0.0; - lbnd[ i ] = 0.0; - } - } - -/* Create the Box. */ - result = (AstRegion *) astBox( bfrm, 1, lbnd, ubnd, NULL, "", status ); - } - -/* Free resources. */ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - bfrm = astAnnul( bfrm ); - } - -/* Return NULL if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the required pointer. */ - return result; -} - -void astInitIntervalVtab_( AstIntervalVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitIntervalVtab - -* Purpose: -* Initialise a virtual function table for a Interval. - -* Type: -* Protected function. - -* Synopsis: -* #include "interval.h" -* void astInitIntervalVtab( AstIntervalVtab *vtab, const char *name ) - -* Class Membership: -* Interval vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Interval class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAInterval) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->IntervalPoints = IntervalPoints; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - - parent_overlap = region->Overlap; - region->Overlap = Overlap; - - parent_setregfs = region->SetRegFS; - region->SetRegFS = SetRegFS; - - parent_resetcache = region->ResetCache; - region->ResetCache = ResetCache; - - parent_setunc = region->SetUnc; - region->SetUnc = SetUnc; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - mapping->MapMerge = MapMerge; - - region->RegCentre = RegCentre; - region->GetBounded = GetBounded; - region->GetDefUnc = GetDefUnc; - region->RegPins = RegPins; - region->RegTrace = RegTrace; - region->RegBaseMesh = RegBaseMesh; - region->BndBaseMesh = BndBaseMesh; - region->RegBaseBox = RegBaseBox; - region->RegBasePick = RegBasePick; - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "Interval", "Axis intervals" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -void IntervalPoints( AstInterval *this, double *lbnd, double *ubnd, - int *status) { -/* -*+ -* Name: -* astIntervalPoints - -* Purpose: -* Return the defining points of a Interval. - -* Type: -* Protected function. - -* Synopsis: -* #include "box.h" -* astIntervalPoints( AstInterval *this, double *lbnd, double *ubnd ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns the axis values at the points defining the -* supplied Interval. - -* Parameters: -* this -* Pointer to the Interval. -* lbnd -* A pointer to an array in which to return the "lbnd" values -* supplied when the Interval was constructed. These are in the -* base Frame of the encapsilated FrameSet. -* ubnd -* A pointer to an array in which to return the "ubnd" values -* supplied when the Interval was constructed. These are in the -* base Frame of the encapsilated FrameSet. - -* Notes: -* - It is assumed that the length of the supplied arrays is at least -* equal to the number of axes in the base frame of the encapsulated -* FrameSet. -*- -*/ - -/* Local Variables: */ - AstPointSet *pset; - double **ptr; - int nc; - int i; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Get a pointer to the PointSet holding the points defining the Interval. */ - pset = ((AstRegion *) this)->points; - -/* Get a pointer to the PointSet's data arrays. */ - ptr = astGetPoints( pset ); - -/* See how many axes each point in the PointSet has. */ - nc = astGetNcoord( pset ); - -/* Copy the axis values from the PointSet into the supplied arrays. */ - for( i = 0; i < nc; i++ ) { - lbnd[ i ] = ptr[ i ] [ 0 ]; - ubnd[ i ] = ptr[ i ] [ 1 ]; - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* Interval member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstInterval *this; /* Pointer to Interval structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the Interval structure. */ - this = (AstInterval *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->box, mode, extra, fail ); - - return result; - -} -#endif - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a Interval. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* Interval method (over-rides the protected astMapMerge method -* inherited from the Region class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated Interval in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated Interval with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated Interval which is to be merged with -* its neighbours. This should be a cloned copy of the Interval -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* Interval it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated Interval resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstInterval *oldint; /* Pointer to supplied Interval */ - AstMapping *map; /* Pointer to adjacent Mapping */ - AstMapping *new; /* Simplified or merged Region */ - int i1; /* Index of first Mapping merged */ - int i; /* Loop counter */ - int result; /* Result value to return */ - -/* Initialise. */ - result = -1; - i1 = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Interval. */ - oldint = (AstInterval *) this; - -/* First of all, see if the Interval can be replaced by a simpler Region, - without reference to the neighbouring Regions in the list. */ -/* =====================================================================*/ - -/* Try to simplify the Interval. If the pointer value has changed, we assume - some simplification took place. */ - new = astSimplify( oldint ); - if( new != (AstMapping *) oldint ) { - -/* Annul the Interval pointer in the list and replace it with the new Region - pointer, and indicate that the forward transformation of the returned - Region should be used (not really needed but keeps things clean). */ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = new; - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - -/* If the Interval itself could not be simplified, see if it can be merged - with the Regions on either side of it in the list. We can only merge - in parallel. */ -/* =====================================================================*/ - } else if( ! series ){ - new = astAnnul( new ); - -/* Attempt to merge the Interval with its lower neighbour (if any). */ - if( where > 0 ) { - i1 = where - 1; - map = ( *map_list )[ where - 1 ]; - if( astIsARegion( map ) ) { - new = (AstMapping *) MergeInterval( oldint, (AstRegion *) map, - 0, status ); - } - } - -/* If this did not produced a merged Region, attempt to merge the Interval - with its upper neighbour (if any). */ - if( !new && where < *nmap - 1 ) { - i1 = where; - map = ( *map_list )[ where + 1 ]; - if( astIsARegion( map ) ) { - new = (AstMapping *) MergeInterval( oldint, (AstRegion *) map, - 1, status ); - } - } - -/* If succesfull... */ - if( new ){ - -/* Annul the first of the two Mappings, and replace it with the merged - Region. Also clear the invert flag. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - ( *map_list )[ i1 ] = new; - ( *invert_list )[ i1 ] = 0; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ i1 + 1 ] ); - for ( i = i1 + 2; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = i1; - } - - } else { - new = astAnnul( new ); - } - -/* Return the result. */ - return result; -} - -static AstRegion *MergeInterval( AstInterval *this, AstRegion *reg, - int intfirst, int *status ) { -/* -* Name: -* MergeInterval - -* Purpose: -* Attempt to merge a Interval with another Region to form a Region of -* higher dimensionality. - -* Type: -* Private function. - -* Synopsis: -* #include "box.h" -* AstRegion *MergeInterval( AstInterval *this, AstRegion *reg, -* int intfirst, int *status ) - -* Class Membership: -* Interval member function. - -* Description: -* This function attempts to combine the supplied Regions together -* into a Region of higher dimensionality. - -* Parameters: -* this -* Pointer to a Interval. -* reg -* Pointer to another Region. -* intfirst -* If non-zero, then the Interval axes are put first in the new Region. -* Otherwise, the other Region's axes are put first. -* status -* Pointer to the inherited status value. - -* Returned Value: -* A pointer to a new region, or NULL if the supplied Regions could -* not be merged. -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* Pointer to base Frame for "result" */ - AstFrame *cfrm; /* Pointer to current Frame for "result" */ - AstFrame *frm_reg; /* Pointer to Frame from "reg" */ - AstFrame *frm_this; /* Pointer to Frame from "this" */ - AstMapping *bcmap; /* Base->current Mapping for "result" */ - AstMapping *map_reg; /* Base->current Mapping from "reg" */ - AstMapping *map_this; /* Base->current Mapping from "this" */ - AstMapping *sbunc; /* Simplified uncertainty */ - AstPointSet *pset_new; /* PointSet holding PointList axis values for new */ - AstPointSet *pset_reg; /* PointSet holding PointList axis values for reg */ - AstRegion *bunc; /* Base Frame uncertainty Region */ - AstRegion *new; /* Pointer to new Interval in base Frame */ - AstRegion *result; /* Pointer to returned Interval in current Frame */ - AstRegion *unc_reg; /* Current Frame uncertainty Region from "reg" */ - AstRegion *unc_this; /* Current Frame uncertainty Region from "this" */ - double **ptr_new; /* Pointers to arrays holding new axis values */ - double **ptr_reg; /* Pointers to arrays holding reg axis values */ - double *centre; /* Array to hold Interval centre axis values */ - double *corner; /* Array to hold Interval corner axis values */ - double *lbnd; /* Array to hold lower axis bounds */ - double *lbnd_unc; /* Array to hold uncertainty lower bounds */ - double *p; /* Pointer to next input value */ - double *q; /* Pointer to next output value */ - double *ubnd; /* Array to hold upper axis bounds */ - double *ubnd_unc; /* Array to hold uncertainty upper bounds */ - double fac_reg; /* Ratio of used to default MeshSize for "reg" */ - double fac_this; /* Ratio of used to default MeshSize for "this" */ - double temp; /* Temporary storage */ - int i; /* Loop count */ - int j; /* Loop count */ - int msz_reg; /* Original MeshSize for "reg" */ - int msz_reg_set; /* Was MeshSize originally set for "reg"? */ - int msz_this; /* Original MeshSize for "this" */ - int msz_this_set; /* Was MeshSize originally set for "this"? */ - int nax; /* Number of axes in "result" */ - int nax_reg; /* Number of axes in "reg" */ - int nax_this; /* Number of axes in "this" */ - int neg_reg; /* Negated attribute value for other supplied Region */ - int neg_this; /* Negated attribute value for supplied Interval */ - int npnt; /* Number of points in PointList */ - int ok; /* Can supplied Regions be merged? */ - -/* Initialise */ - result = NULL; - lbnd = NULL; - ubnd = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get the Closed attributes of the two Regions. They must be the same in - each Region if we are to merge the Regions. In addition, in order to - merge, either both Regions must have a defined uncertainty, or neither - Region must have a defined Uncertainty. */ - if( astGetClosed( this ) == astGetClosed( reg ) && - astTestUnc( this ) == astTestUnc( reg ) ) { - -/* Get the Nagated attributes of the two Regions. */ - neg_this = astGetNegated( this ); - neg_reg = astGetNegated( reg ); - -/* Get the number of axes in the two supplied Regions. */ - nax_reg = astGetNaxes( reg ); - nax_this = astGetNaxes( this ); - -/* If the Regions can be combined, get the number of axes the - combination will have. */ - nax = nax_reg + nax_this; - -/* Get the base Frames from the two Region FrameSets, and combine them - into a single CmpFrame that will be used to create any new Region. */ - frm_this = astGetFrame( ((AstRegion *) this)->frameset, AST__BASE ); - frm_reg = astGetFrame( reg->frameset, AST__BASE ); - - if( intfirst ) { - bfrm = (AstFrame *) astCmpFrame( frm_this, frm_reg, "", status ); - } else { - bfrm = (AstFrame *) astCmpFrame( frm_reg, frm_this, "", status ); - } - - frm_this = astAnnul( frm_this ); - frm_reg = astAnnul( frm_reg ); - -/* Indicate we do not yet have a merged Region. */ - new = NULL; - -/* First attempt to merge with another Interval. The result will be an - Interval. Both Intervals must be un-negated. */ - if( astIsAInterval( reg ) && !neg_this && !neg_reg ) { - -/* Allocate memory to store the bounds of the returned Interval. */ - lbnd = astMalloc( sizeof( double )*(size_t) nax ); - ubnd = astMalloc( sizeof( double )*(size_t) nax ); - -/* Copy the limits from the supplied Intervals into the above arrays, - in the requested order. */ - if( intfirst ) { - astIntervalPoints( this, lbnd, ubnd ); - astIntervalPoints( reg, lbnd + nax_this, ubnd + nax_this ); - } else { - astIntervalPoints( reg, lbnd, ubnd ); - astIntervalPoints( this, lbnd + nax_reg, ubnd + nax_reg ); - } - -/* Create the new Interval, initially with no uncertainty. */ - new = (AstRegion *) astInterval( bfrm, lbnd, ubnd, NULL, "", - status ); - -/* Free resources .*/ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - -/* Now attempt to merge with a Box. The result will be an Interval. Both - Regions must be un-negated. */ - } else if( astIsABox( reg ) && !neg_this && !neg_reg ) { - -/* Allocate memory to store the bounds of the returned Interval. */ - lbnd = astMalloc( sizeof( double )*(size_t) nax ); - ubnd = astMalloc( sizeof( double )*(size_t) nax ); - -/* Get the bounds from the Interval and add them into the above arrays. */ - if( intfirst ) { - astIntervalPoints( this, lbnd, ubnd ); - } else { - astIntervalPoints( this, lbnd + nax_reg, ubnd + nax_reg ); - } - -/* Copy the centre and corner from the supplied Box into the required part - of the above arrays. */ - if( intfirst ) { - centre = lbnd + nax_this; - corner = ubnd + nax_this; - } else { - centre = lbnd; - corner = ubnd; - } - astBoxPoints( reg, centre, corner ); - -/* Convert these centre and corner positions into upper and lower bounds. */ - if( astOK ) { - for( i = 0; i < nax_reg; i++ ) { - centre[ i ] = 2*centre[ i ] - corner[ i ]; - if( centre[ i ] > corner[ i ] ) { - temp = centre[ i ]; - centre[ i ] = corner[ i ]; - corner[ i ] = temp; - } - } - } - -/* Create the new Interval, initially with no uncertainty. */ - new = (AstRegion *) astInterval( bfrm, lbnd, ubnd, NULL, "", - status ); - -/* Free resources .*/ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - -/* Now attempt to merge with a NullRegion. The result will be an Interval. - The NullRegion must be negated and the Interval must not. */ - } else if( astIsANullRegion( reg ) && !neg_this && neg_reg ) { - -/* Allocate memory to store the bounds of the returned Interval. */ - lbnd = astMalloc( sizeof( double )*(size_t) nax ); - ubnd = astMalloc( sizeof( double )*(size_t) nax ); - -/* Copy the limits from the supplied Interval into the above arrays. - Store bad values for the other axes indicating they are unbounded. */ - if( intfirst ) { - astIntervalPoints( this, lbnd, ubnd ); - for( i = nax_this; i < nax; i++ ) { - lbnd[ i ] = AST__BAD; - ubnd[ i ] = AST__BAD; - } - } else { - for( i = 0; i < nax_reg; i++ ) { - lbnd[ i ] = AST__BAD; - ubnd[ i ] = AST__BAD; - } - astIntervalPoints( this, lbnd + nax_reg, ubnd + nax_reg ); - } - -/* Create the new Interval, initially with no uncertainty. */ - new = (AstRegion *) astInterval( bfrm, lbnd, ubnd, NULL, "", - status ); - -/* Free resources .*/ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - -/* Now attempt to merge with a PointList. The result will be a PointList. - Both Regions must be un-negated. */ - } else if( astIsAPointList( reg ) && !neg_this && !neg_reg ) { - -/* We can only do this if the Interval has zero width on each axis (i.e. - represents a point). Get the Interval bounds. */ - lbnd = astMalloc( sizeof( double )*(size_t) nax_this ); - ubnd = astMalloc( sizeof( double )*(size_t) nax_this ); - astRegBaseBox( this, lbnd, ubnd ); - -/* Get the size of the Interval's uncertainty region. */ - lbnd_unc = astMalloc( sizeof( double )*(size_t) nax_this ); - ubnd_unc = astMalloc( sizeof( double )*(size_t) nax_this ); - bunc = astGetUncFrm( this, AST__BASE ); - astGetRegionBounds( bunc, lbnd, ubnd ); - -/* Set "ok" to zero if the Interval does not have zero width on any axis. Here - "zero width" means a width less than half the uncertainty on the axis. - We also replace the lower bound values in the "lbnd" array by the central - values in the Interval. */ - if( astOK ) { - ok = 1; - for( i = 0; i < nax_this; i++ ) { - if( fabs( lbnd[ i ] - lbnd[ i ] ) > - 0.25*fabs( ubnd_unc[ i ] - lbnd_unc[ i ] ) ) { - ok = 0; - break; - } else { - lbnd[ i ] = 0.5*( lbnd[ i ] + ubnd[ i ] ); - } - } - -/* If the Interval is a point, we go on to create a new PointList. */ - if( ok ) { - -/* Get a PointSet holding the axis values in the supplied PointList data. - Also get the number of points in the PointSet and pointers to the arrays - holding the axis values. */ - astPointListPoints( reg, &pset_reg ); - npnt = astGetNpoint( pset_reg ); - ptr_reg = astGetPoints( pset_reg ); - -/* Create a new PointSet with room for the same number of points, but - with the extra required axes. Get pointers to its axis arrays. */ - pset_new = astPointSet( npnt, nax, "", status ); - ptr_new = astGetPoints( pset_new ); - -/* Copy the PointList axis values into the new PointSet, and then include - the extra axis values defined by the Interval to each point. */ - if( astOK ) { - - for( j = 0; j < nax_reg; j++ ) { - p = ptr_reg[ j ]; - q = ptr_new[ intfirst ? nax_this + j : j ]; - for( i = 0; i < npnt; i++ ) *(q++) = *(p++); - } - - for( j = 0; j < nax_this; j++ ) { - p = lbnd + j; - q = ptr_new[ intfirst ? j : nax_reg + j ]; - for( i = 0; i < npnt; i++ ) *(q++) = *p; - } - -/* Create the new PointList, initially with no uncertainty. */ - new = (AstRegion *) astPointList( bfrm, pset_new, NULL, - "", status ); - } - -/* Free resources .*/ - pset_new = astAnnul( pset_new ); - pset_reg = astAnnul( pset_reg ); - } - } - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - lbnd_unc = astFree( lbnd_unc ); - ubnd_unc = astFree( ubnd_unc ); - bunc = astAnnul( bunc ); - - } - -/* If a new Region was created above, propagate remaining attributes of - the supplied Region to it. */ - if( new ) { - astRegOverlay( new, this, 1 ); - -/* The above Prism constructors create the Prism with the correct value - for the Nagated attribute (i.e. zero). Ensure the above call to - astRegOverlay has not changed this. */ - astClearNegated( new ); - -/* If both the supplied Regions have uncertainty, assign the new Region an - uncertainty. */ - if( astTestUnc( this ) && astTestUnc( reg ) ) { - -/* Get the uncertainties from the two supplied Regions. */ - unc_this = astGetUncFrm( this, AST__BASE ); - unc_reg = astGetUncFrm( reg, AST__BASE ); - -/* Combine them into a single Region (a Prism), in the correct order. */ - if( intfirst ) { - bunc = (AstRegion *) astPrism( unc_this, unc_reg, "", status ); - } else { - bunc = (AstRegion *) astPrism( unc_reg, unc_this, "", status ); - } - -/* Attempt to simplify the Prism. */ - sbunc = astSimplify( bunc ); - -/* Use the simplified Prism as the uncertainty for the returned Region. */ - astSetUnc( new, sbunc ); - -/* Free resources. */ - sbunc = astAnnul( sbunc ); - bunc = astAnnul( bunc ); - unc_reg = astAnnul( unc_reg ); - unc_this = astAnnul( unc_this ); - } - -/* Get the current Frames from the two Region FrameSets, and combine them - into a single CmpFrame. */ - frm_this = astGetFrame( ((AstRegion *) this)->frameset, AST__CURRENT ); - frm_reg = astGetFrame( reg->frameset, AST__CURRENT ); - - if( intfirst ) { - cfrm = (AstFrame *) astCmpFrame( frm_this, frm_reg, "", status ); - } else { - cfrm = (AstFrame *) astCmpFrame( frm_reg, frm_this, "", status ); - } - -/* Get the base -> current Mappings from the two Region FrameSets, and - combine them into a single parallel CmpMap that connects bfrm and cfrm. */ - map_this = astGetMapping( ((AstRegion *) this)->frameset, AST__BASE, - AST__CURRENT ); - map_reg = astGetMapping( reg->frameset, AST__BASE, AST__CURRENT ); - - if( intfirst ) { - bcmap = (AstMapping *) astCmpMap( map_this, map_reg, 0, "", - status ); - } else { - bcmap = (AstMapping *) astCmpMap( map_reg, map_this, 0, "", - status ); - } - -/* Map the new Region into the new current Frame. */ - result = astMapRegion( new, bcmap, cfrm ); - -/* The filling factor in the returned is the product of the filling - factors for the two supplied Regions. */ - if( astTestFillFactor( reg ) || astTestFillFactor( this ) ) { - astSetFillFactor( result, astGetFillFactor( reg )* - astGetFillFactor( this ) ); - } - -/* If the MeshSize value is set in either supplied Region, set a value - for the returned Region which scales the default value by the - product of the scaling factors for the two supplied Regions. First see - if either MeshSize value is set. */ - msz_this_set = astTestMeshSize( this ); - msz_reg_set = astTestMeshSize( reg ); - if( msz_this_set || msz_reg_set ) { - -/* If so, get the two MeshSize values (one of which may be a default - value), and then clear them so that the default value will be returned - in future. */ - msz_this = astGetMeshSize( this ); - msz_reg = astGetMeshSize( reg ); - astClearMeshSize( this ); - astClearMeshSize( reg ); - -/* Get the ratio of the used MeshSize to the default MeshSize for both - Regions. */ - fac_this = (double)msz_this/(double)astGetMeshSize( this ); - fac_reg = (double)msz_reg/(double)astGetMeshSize( reg ); - -/* The MeshSize of the returned Returned is the default value scaled by - the product of the two ratios found above. */ - astSetMeshSize( result, fac_this*fac_reg*astGetMeshSize( result ) ); - -/* Re-instate the original MeshSize values for the supplied Regions (if - set) */ - if( msz_this_set ) astSetMeshSize( this, msz_this ); - if( msz_reg_set ) astSetMeshSize( reg, msz_reg ); - } - -/* Free remaining resources */ - frm_this = astAnnul( frm_this ); - frm_reg = astAnnul( frm_reg ); - map_this = astAnnul( map_this ); - map_reg = astAnnul( map_reg ); - bcmap = astAnnul( bcmap ); - new = astAnnul( new ); - cfrm = astAnnul( cfrm ); - } - bfrm = astAnnul( bfrm ); - - } - -/* If an error has occurred, annul the returned pointer. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int *OneToOne( AstMapping *map, int *status ){ -/* -* Name: -* OneToOne - -* Purpose: -* Does each output of the supplied Mapping depend on only one input? - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* int OneToOne( AstMapping *map, int *status ) - -* Class Membership: -* Interval method - -* Description: -* This function returns a flag indicating if the Mapping is 1-to-1. -* That is, if each output depends only on one input. - -* Parameters: -* map -* Pointer to the Mapping. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If the Mapping is 1-to-1, a pointer to an array of ints is returned -* (NULL is returned otherwise). There is one int for each output of -* the supplied Mapping. The value of each int is the index of the -* corresponding input which feeds the output. The array should be -* freed using astFree when no longer needed. - -*/ - -/* Local Variables: */ - int *result; - const char *class; - int nout; - int i; - int *tt; - AstMapping *tmap; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the number of outputs for the Mapping. */ - nout = astGetNout( map ); - -/* The Mapping cannot be 1-to-1 if the number of inputs is different.*/ - if( astGetNin( map ) == nout ) { - -/* Allocate an output array on the assumption that the Mapping is 1-to-1. */ - result = astMalloc( sizeof( int )*(size_t) nout ); - if( result ) { - -/* Check known specal cases for speed. */ - class = astGetClass( map ); - if( !strcmp( class, "WinMap" ) || - !strcmp( class, "ZoomMap" ) || - !strcmp( class, "UnitMap" ) || - !strcmp( class, "ShiftMap" ) ){ - -/* Each output is fed by the corresponding input for these classes of - Mapping. */ - for( i = 0; i < nout; i++ ) result[ i ] = i; - -/* Now do the general case. */ - } else { - -/* Loop round each input axis. */ - for( i = 0; i < nout; i++ ) { - -/* Use astMapSplit to see if this input corresponds to a single output. */ - tt = astMapSplit( map, 1, &i, &tmap ); - -/* If not, annul the returned array and break. */ - if( !tmap ) { - result = astFree( result ); - break; - -/* If so, store the index of the corresponding input in the returned - array and free resources. */ - } else { - result[ tt[ 0 ] ] = i; - tt = astFree( tt ); - if( astGetNout( tmap ) != 1 ) result = astFree( result ); - tmap = astAnnul( tmap ); - if( !result ) break; - } - } - } - } - } - -/* Return the result */ - return result; -} - -static int Overlap( AstRegion *this, AstRegion *that, int *status ){ -/* -* Name: -* Overlap - -* Purpose: -* Test if two regions overlap each other. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* int Overlap( AstRegion *this, AstRegion *that, int *status ) - -* Class Membership: -* Interval member function (over-rides the astOverlap method inherited -* from the Region class). - -* Description: -* This function returns an integer value indicating if the two -* supplied Regions overlap. The two Regions are converted to a commnon -* coordinate system before performing the check. If this conversion is -* not possible (for instance because the two Regions represent areas in -* different domains), then the check cannot be performed and a zero value -* is returned to indicate this. - -* Parameters: -* this -* Pointer to the first Region. -* that -* Pointer to the second Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* astOverlap() -* A value indicating if there is any overlap between the two Regions. -* Possible values are: -* -* 0 - The check could not be performed because the second Region -* could not be mapped into the coordinate system of the first -* Region. -* -* 1 - There is no overlap between the two Regions. -* -* 2 - The first Region is completely inside the second Region. -* -* 3 - The second Region is completely inside the first Region. -* -* 4 - There is partial overlap between the two Regions. -* -* 5 - The Regions are identical. -* -* 6 - The second Region is the negation of the first Region. - -* Notes: -* - The returned values 5 and 6 do not check the value of the Closed -* attribute in the two Regions. -* - A value of zero will be returned if this function is invoked with the -* AST error status set, or if it should fail for any reason. - -*/ - -/* Local Variables: */ - AstFrame *frm; - AstFrameSet *fs; - AstMapping *map; - AstMapping *map1; - AstMapping *map2; - AstMapping *map3; - AstMapping *smap; - AstMapping *tmap; - AstPointSet *pset_that; - AstRegion *unc_temp; - AstRegion *unc_that; - AstRegion *unc_this; - double **ptr_that; - double **ptr_thato; - double **ptr_this; - double *lbndu_that; - double *lbndu_this; - double *ubndu_that; - double *ubndu_this; - double err; - double err_that; - double err_this; - double lb_that; - double lb_this; - double tmp; - double ub_that; - double ub_this; - int *outperm; - int ic; - int inc_that; - int inc_this; - int lb_equal; - int nc; - int neg_that; - int neg_this; - int ov; - int result; - int ub_equal; - - static int newResult[ 5 ][ 5 ] = { { 1, 1, 1, 1, 1}, - { 1, 2, 4, 4, 2}, - { 1, 4, 3, 4, 3}, - { 1, 4, 4, 4, 4}, - { 1, 2, 3, 4, 5} }; - -/* Initialise */ - result = 0; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* If both Regions are Intervals, we provide a specialised implementation. - The implementation in the parent Region class assumes that at least one of - the two Regions can be represented using a finite mesh of points on the - boundary which is not the case with Intervals. The implementation in this - class sees if the Mapping between the base Frames of the Intervals allows - the axis limits to be transferred from one Frame to the other. */ - if( astIsAInterval( this ) && astIsAInterval( that ) ) { - -/* Get a FrameSet which connects the Frame represented by the second Interval - to the Frame represented by the first Interval. Check that the conection is - defined. */ - fs = astConvert( that, this, "" ); - if( fs ) { - -/* Get a pointer to the Mapping from base to current Frame in the second - Interval */ - map1 = astGetMapping( that->frameset, AST__BASE, AST__CURRENT ); - -/* Get the Mapping from the current Frame of the second Interval to the - current Frame of the first Interval. */ - map2 = astGetMapping( fs, AST__BASE, AST__CURRENT ); - -/* Get a pointer to the Mapping from current to base Frame in the first - Interval. */ - map3 = astGetMapping( this->frameset, AST__CURRENT, AST__BASE ); - -/* Combine these Mappings to get the Mapping from the base Frame of the - second Interval to the base Frame of the first Interval. */ - tmap = (AstMapping *) astCmpMap( map1, map2, 1, "", status ); - map = (AstMapping *) astCmpMap( tmap, map3, 1, "", status ); - -/* Simplify this Mapping. */ - smap = astSimplify( map ); - -/* We can only proceed if each output of the simplified Mapping depends - on only one input. Test this. */ - outperm = OneToOne( smap, status ); - if( outperm ){ - -/* Get the uncertainty Regions for both Intervals, expressed in the base - Frames of the Intervals. */ - unc_this = astGetUncFrm( this, AST__BASE ); - unc_temp = astGetUncFrm( that, AST__BASE ); - -/* Map the uncertainty Region for the second Interval from the base Frame - of the second Interval into the base Frame of the first Interval. */ - frm = astGetFrame( this->frameset, AST__BASE ); - unc_that = astMapRegion( unc_temp, smap, frm ); - -/* Get the bounding boxes of the two uncertainty Regions in the base - Frame of the first Interval. */ - nc = astGetNaxes( frm ); - lbndu_this = astMalloc( sizeof( double )*(size_t)nc ); - ubndu_this = astMalloc( sizeof( double )*(size_t)nc ); - astGetRegionBounds( unc_this, lbndu_this, ubndu_this ); - - lbndu_that = astMalloc( sizeof( double )*(size_t)nc ); - ubndu_that = astMalloc( sizeof( double )*(size_t)nc ); - astGetRegionBounds( unc_that, lbndu_that, ubndu_that ); - -/* Transform the PointSet holding the limits for the second Interval into - the Frame of the first Interval. */ - pset_that = astTransform( smap, that->points, 1, NULL ); - -/* Get pointers for accesing the limits of the two Intervals, expressed - in a common Frame (the base Frame of the first Interval). */ - ptr_that = astGetPoints( pset_that ); - ptr_thato = astGetPoints( that->points ); - ptr_this = astGetPoints( this->points ); - if( astOK ) { - -/* Check the limits on each base Frame axis in turn. */ - for( ic = 0; ic < nc; ic++ ) { - -/* Get the widths of the two uncertainty boxes on this axis. */ - err_this = ubndu_this[ ic ] - lbndu_this[ ic ]; - err_that = ubndu_that[ ic ] - lbndu_that[ ic ]; - -/* Add this together in quadrature to get the tolerance for two values on - the current axis to be considered equal. */ - err = sqrt( err_that*err_that + err_this*err_this ); - -/* Get the limits on this axis from both Intervals. */ - lb_this = ptr_this[ ic ][ 0 ]; - ub_this = ptr_this[ ic ][ 1 ]; - lb_that = ptr_that[ ic ][ 0 ]; - ub_that = ptr_that[ ic ][ 1 ]; - -/* The limits for "that" have been mapped, which may have resulted in - them being swapped. We need to unswap them in this case to prevent the - swapping being used as an indication of a desire to use an excluded - interval rather than an included interval. */ - if( lb_that != AST__BAD && ub_that != AST__BAD ) { - if( ptr_thato[ ic ][ 0 ] < ptr_thato[ ic ][ 1 ] ) { - if( lb_that > ub_that ) { - tmp = lb_that; - lb_that = ub_that; - ub_that = tmp; - } - } else { - if( lb_that < ub_that ) { - tmp = lb_that; - lb_that = ub_that; - ub_that = tmp; - } - } - } - -/* If the regions are not closed, reduce the limits by the smallest - amount possible. */ - if( !astGetClosed( that ) ) { - if( lb_that != AST__BAD && lb_that < DBL_MAX ) - lb_that += DBL_EPSILON*fabs(lb_that); - if( ub_that != AST__BAD && ub_that > -DBL_MAX ) - ub_that -= DBL_EPSILON*fabs(ub_that); - } - if( !astGetClosed( this ) ) { - if( lb_this != AST__BAD && lb_this < DBL_MAX ) - lb_this += DBL_EPSILON*fabs(lb_this); - if( ub_this != AST__BAD && ub_this > -DBL_MAX ) - ub_this -= DBL_EPSILON*fabs(ub_this); - } - -/* Replace any missing limits with suitable extreme values */ - if( lb_this == AST__BAD ) lb_this = -DBL_MAX; - if( ub_this == AST__BAD ) ub_this = DBL_MAX; - if( lb_that == AST__BAD ) lb_that = -DBL_MAX; - if( ub_that == AST__BAD ) ub_that = DBL_MAX; - -/* If the bounds are the wrong way round (indicating an excluded rather - than an included axis range), swap them. Also set a flag indicating if - the limits define an included or excluded range. */ - inc_this = ( lb_this <= ub_this ); - if( !inc_this ) { - tmp = lb_this; - lb_this = ub_this; - ub_this = tmp; - } - - inc_that = ( lb_that <= ub_that ); - if( !inc_that ) { - tmp = lb_that; - lb_that = ub_that; - ub_that = tmp; - } - - -/* Are the lower limits from the two Intervals effectively equal? Take care - about DBL_MAX values causing overflow. */ - lb_equal = astEQUALS( lb_this, lb_that, 1.0E9 ); - - if( !lb_equal && fabs(lb_this) != DBL_MAX && - fabs(lb_that) != DBL_MAX ) { - lb_equal = ( fabs( lb_this - lb_that) <= err ); - } - -/* Are the upper limits from the two Intervals effectively equal? */ - ub_equal = astEQUALS( ub_this, ub_that, 1.0E9 ); - if( !ub_equal && fabs(ub_this) != DBL_MAX && - fabs(ub_that) != DBL_MAX ) { - ub_equal = ( fabs( ub_this - ub_that) <= err ); - } - - - -/* If both the limits on this axis are effectively equal for the two Intervals, - set "ov" to 5 if both Interval ranges are inclusive or both are exclusive, - and set "ov" to 6 if one Interval range is exclusive and the other is - inclusive. */ - if( lb_equal && ub_equal ) { - ov = ( inc_this == inc_that ) ? 5 : 6; - -/* See if the limits on this axis indicate overlap for the two Intervals. "ov" - is set to 1 if there is no overlap, 2 if the first Interval range is - completely inside the second Interval range, 3 if the second Interval - range is completely inside the first Interval range, and 4 if there is - partial overlap between the Interval ranges. */ - } else if( inc_this ) { - if( inc_that ) { - if( lb_that <= lb_this && ub_that >= ub_this ) { - ov = 2; - } else if( lb_that >= lb_this && ub_that <= ub_this ) { - ov = 3; - } else if( ub_that >= lb_this && lb_that <= ub_this ) { - ov = 4; - } else { - ov = 1; - } - - } else { - - if( lb_that <= lb_this && ub_that >= ub_this ) { - ov = 1; - } else if( lb_that >= ub_this || ub_that <= lb_this ) { - ov = 2; - } else if( lb_this == -DBL_MAX && ub_this == DBL_MAX ) { - ov = 3; - } else { - ov = 4; - } - } - - } else { - - if( inc_that ) { - if( lb_this <= lb_that && ub_this >= ub_that ) { - ov = 1; - } else if( lb_this >= ub_that || ub_this <= lb_that ) { - ov = 3; - } else if( lb_that == -DBL_MAX && ub_that == DBL_MAX ) { - ov = 2; - } else { - ov = 4; - } - - } else { - ov = 4; - } - } - -/* The returned value is initialised on the basis of the first axis - overlap. */ - if( ic == 0 ) { - result = ov; - -/* For subsequent axes, combine the old result value with the new ov value - to get the new result value. */ - } else { - result = newResult[ result - 1 ][ ov - 1 ]; - } - -/* If we now know there is no overlap, there is no point in checking any - remaining axes. */ - if( result == 1 ) break; - - } - -/* The above logic assumed that neither of the Intervals has been negated. - Decide on the value to return, taking into account whether either of - the Intervals has been negated. */ - neg_this = astGetNegated( this ); - neg_that = astGetNegated( that ); - - if( result == 1 ) { - if( neg_this ) { - result = neg_that ? 4 : 3; - } else if( neg_that ){ - result = 2; - } - - } else if( result == 2) { - if( neg_this ) { - result = neg_that ? 3 : 4; - } else if( neg_that ){ - result = 1; - } - - } else if( result == 3) { - if( neg_this ) { - result = neg_that ? 2 : 1; - } else if( neg_that ){ - result = 4; - } - - } else if( result == 4) { - result = 4; - - } else if( result == 5) { - if( neg_this ) { - result = neg_that ? 5 : 6; - } else if( neg_that ){ - result = 6; - } - } - } - -/* Free resources. */ - pset_that = astAnnul( pset_that ); - unc_this = astAnnul( unc_this ); - unc_that = astAnnul( unc_that ); - unc_temp = astAnnul( unc_temp ); - frm = astAnnul( frm ); - lbndu_this = astFree( lbndu_this ); - ubndu_this = astFree( ubndu_this ); - lbndu_that = astFree( lbndu_that ); - ubndu_that = astFree( ubndu_that ); - outperm = astFree( outperm ); - } - - smap = astAnnul( smap ); - map = astAnnul( map ); - tmap = astAnnul( tmap ); - map3 = astAnnul( map3 ); - map2 = astAnnul( map2 ); - map1 = astAnnul( map1 ); - fs = astAnnul( fs ); - } - } - -/* If overlap could not be determined using the above implementation, try - using the implementation inherited from the parent Region class. */ - if( !result ) result = (*parent_overlap)( this, that, status ); - -/* If not OK, return zero. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static void RegBaseBox( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* Interval member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstInterval *this; - int nax; - int i; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Interval structure */ - this = (AstInterval *) this_region; - -/* Ensure the cached bounds are up to date. */ - Cache( this, status ); - -/* Copy the cached bounds into the supplied arrays. */ - nax = astGetNin( this_region->frameset ); - for( i = 0; i < nax; i++ ) { - lbnd[ i ] = this->lbnd[ i ]; - ubnd[ i ] = this->ubnd[ i ]; - } -} - -static AstPointSet *RegBaseMesh( AstRegion *this_region, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Return a PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* AstPointSet *astRegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* Interval member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. The axis values in this PointSet will have -* associated accuracies derived from the accuracies which were -* supplied when the Region was created. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - -/* Local Variables: */ - AstBox *box; /* The equivalent Box */ - AstPointSet *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the Interval is effectively a Box, invoke the astRegBaseMesh - function on the equivalent Box. A pointer to the equivalent Box will - be stored in the Interval structure. */ - box = Cache( (AstInterval *) this_region, status ); - if( box ) { - result = astRegBaseMesh( box ); - -/* If the Interval is not equivalent to a Box, report an error. */ - } else { - astError( AST__INTER, "astRegBaseMesh(%s): The %s given is " - "unbounded and therefore no boundary mesh can be " - "produced (internal AST programming error).", status, - astGetClass( this_region ), astGetClass( this_region ) ); - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -static AstRegion *RegBasePick( AstRegion *this_region, int naxes, - const int *axes, int *status ){ -/* -* Name: -* RegBasePick - -* Purpose: -* Return a Region formed by picking selected base Frame axes from the -* supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* AstRegion *RegBasePick( AstRegion *this, int naxes, const int *axes, -* int *status ) - -* Class Membership: -* Interval member function (over-rides the astRegBasePick protected -* method inherited from the Region class). - -* Description: -* This function attempts to return a Region that is spanned by selected -* axes from the base Frame of the encapsulated FrameSet of the supplied -* Region. This may or may not be possible, depending on the class of -* Region. If it is not possible a NULL pointer is returned. - -* Parameters: -* this -* Pointer to the Region. -* naxes -* The number of base Frame axes to select. -* axes -* An array holding the zero-based indices of the base Frame axes -* that are to be selected. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Region, or NULL if no region can be formed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* The base Frame in the supplied Region */ - AstFrame *frm; /* The base Frame in the returned Region */ - AstPointSet *pset; /* Holds axis values defining the supplied Region */ - AstRegion *bunc; /* The uncertainty in the supplied Region */ - AstRegion *result; /* Returned Region */ - AstRegion *unc; /* The uncertainty in the returned Region */ - double **ptr; /* Holds axis values defining the supplied Region */ - double *lbnd; /* Base Frm lower bound axis values */ - double *ubnd; /* Base Frm upper bound axis values */ - int i; /* Index of axis within returned Region */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the base Frame of the encapsulated FrameSet. */ - bfrm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Create a Frame by picking the selected axes from the base Frame of the - encapsulated FrameSet. */ - frm = astPickAxes( bfrm, naxes, axes, NULL ); - -/* Get the uncertainty Region (if any) within the base Frame of the supplied - Region, and select the required axes from it. If the resulting Object - is not a Region, annul it so that the returned Region will have no - uncertainty. */ - if( astTestUnc( this_region ) ) { - bunc = astGetUncFrm( this_region, AST__BASE ); - unc = astPickAxes( bunc, naxes, axes, NULL ); - bunc = astAnnul( bunc ); - - if( ! astIsARegion( unc ) ) unc = astAnnul( unc ); - - } else { - unc = NULL; - } - -/* Get pointers to the coordinate data in the parent Region structure. */ - pset = this_region->points; - ptr = astGetPoints( pset ); - -/* Get space to hold the limits of the Interval in the new Frame. */ - lbnd = astMalloc( sizeof( *lbnd )*naxes ); - ubnd = astMalloc( sizeof( *ubnd )*naxes ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Copy the limits for the selected axes into the arrays allocated above. */ - for( i = 0; i < naxes; i++ ) { - lbnd[ i ] = ptr[ axes[ i ] ][ 0 ]; - ubnd[ i ] = ptr[ axes[ i ] ][ 1 ]; - } - -/* Create the new Interval. */ - result = (AstRegion *) astInterval( frm, lbnd, ubnd, unc, "", status ); - - } - -/* Free resources */ - frm = astAnnul( frm ); - bfrm = astAnnul( bfrm ); - if( unc ) unc = astAnnul( unc ); - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - -/* Return a NULL pointer if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static double *RegCentre( AstRegion *this_region, double *cen, double **ptr, - int index, int ifrm, int *status ){ -/* -* Name: -* RegCentre - -* Purpose: -* Re-centre a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* double *RegCentre( AstRegion *this, double *cen, double **ptr, -* int index, int ifrm, int *status ) - -* Class Membership: -* Interval member function (over-rides the astRegCentre protected -* method inherited from the Region class). - -* Description: -* This function shifts the centre of the supplied Region to a -* specified position, or returns the current centre of the Region. - -* Parameters: -* this -* Pointer to the Region. -* cen -* Pointer to an array of axis values, giving the new centre. -* Supply a NULL value for this in order to use "ptr" and "index" to -* specify the new centre. -* ptr -* Pointer to an array of points, one for each axis in the Region. -* Each pointer locates an array of axis values. This is the format -* returned by the PointSet method astGetPoints. Only used if "cen" -* is NULL. -* index -* The index of the point within the arrays identified by "ptr" at -* which is stored the coords for the new centre position. Only used -* if "cen" is NULL. -* ifrm -* Should be AST__BASE or AST__CURRENT. Indicates whether the centre -* position is supplied and returned in the base or current Frame of -* the FrameSet encapsulated within "this". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If both "cen" and "ptr" are NULL then a pointer to a newly -* allocated dynamic array is returned which contains the centre -* coords of the Region. This array should be freed using astFree when -* no longer needed. If either of "ptr" or "cen" is not NULL, then a -* NULL pointer is returned. - -* Notes: -* - Some Region sub-classes do not have a centre. Such classes will report -* an AST__INTER error code if this method is called with either "ptr" or -* "cen" not NULL. If "ptr" and "cen" are both NULL, then no error is -* reported if this method is invoked on a Region of an unsuitable class, -* but NULL is always returned. - -*/ - -/* Local Variables: */ - AstInterval *this; /* Pointer to Interval structure */ - AstBox *box; /* Pointer to equivalent Box structure */ - double **bptr; /* Data pointers for Region PointSet */ - double *lbnd; /* Pointer to new lower bound values */ - double *ubnd; /* Pointer to new upper bound values */ - double *result; /* Returned pointer */ - int i; /* Coordinate index */ - int nax; /* Number of axes */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Interval structure. */ - this = (AstInterval *) this_region; - -/* The Interval can only be re-centred if it is effectively a Box. */ - box = Cache( (AstInterval *) this_region, status ); - if( box ) { - -/* If the centre is being changed... */ - if( cen || ptr ) { - -/* Set the new centre in the equivalent box. */ - astRegCentre( box, cen, ptr, index, ifrm ); - -/* Get the new base Frame bounds from the Box. */ - nax = astGetNin( this_region->frameset ); - lbnd = astMalloc( sizeof( double )*nax ); - ubnd = astMalloc( sizeof( double )*nax ); - astRegBaseBox( box, lbnd, ubnd ); - -/* Store these bounds in the Interval structure. */ - bptr = astGetPoints( this_region->points ); - if( astOK ) { - for( i = 0; i < nax; i++ ) { - bptr[ i ][ 0 ] = lbnd[ i ]; - bptr[ i ][ 1 ] = ubnd[ i ]; - } - } - -/* Free resources. */ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - -/* If the centre is not being changed, just invoke the method on the - equivalent box. */ - } else { - result = astRegCentre( box, NULL, NULL, 0, AST__BASE ); - } - -/* If the Interval is not equivalent to a Box, report an error */ - } else if( cen || ptr ) { - astError( AST__REGCN, "astRegCentre(%s): The supplied %s is not a " - "closed Interval and so cannot be re-centred.", status, - astGetClass( this ), astGetClass( this ) ); - } - -/* Return the result. */ - return result; -} - -static int RegPins( AstRegion *this_region, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -* Name: -* RegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given Interval. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask, int *status ) - -* Class Membership: -* Interval member function (over-rides the astRegPins protected -* method inherited from the Region class). - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given Interval. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied Interval "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the Interval. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "pset". -* Each element in the returned array is set to 1 if the -* corresponding position in "pset" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*/ - -/* Local variables: */ - AstBox *box; /* The equivalent Box */ - AstInterval *large_int; /* Interval slightly larger than "this" */ - AstInterval *small_int; /* Interval slightly smaller than "this" */ - AstInterval *this; /* Pointer to the Interval structure. */ - AstFrame *frm; /* Base Frame in supplied Interval */ - AstPointSet *ps1; /* Points masked by larger Interval */ - AstPointSet *ps2; /* Points masked by larger and smaller Intervals */ - AstRegion *tunc; /* Uncertainity Region from "this" */ - double **ptr; /* Pointer to axis values in "ps2" */ - double *large_lbnd; /* Lower bounds of larger interval */ - double *large_ubnd; /* Upper bounds of larger interval */ - double *lbnd_tunc; /* Lower bounds of "this" uncertainty Region */ - double *lbnd_unc; /* Lower bounds of supplied uncertainty Region */ - double *p; /* Pointer to next axis value */ - double *safe; /* An interior point in "this" */ - double *small_lbnd; /* Lower bounds of smaller interval */ - double *small_ubnd; /* Upper bounds of smaller interval */ - double *ubnd_tunc; /* Upper bounds of "this" uncertainty Region */ - double *ubnd_unc; /* Upper bounds of supplied uncertainty Region */ - double *wid; /* Widths of "this" border */ - double lb; /* Lower bound */ - double ub; /* Upper bound */ - double t; /* Swap space */ - double w; /* Width */ - int i; /* Axis index */ - int j; /* Point index */ - int nc; /* No. of axes in Interval base frame */ - int np; /* No. of supplied points */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - if( mask ) *mask = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the Interval structure. */ - this = (AstInterval *) this_region; - -/* If the Interval is effectively a Box, invoke the astRegPins function on - the equivalent Box. A pointer to the equivalent Box will be stored in the - Interval structure. */ - box = Cache( this, status ); - if( box ) return astRegPins( box, pset, unc, mask ); - -/* Arrive here only if the Interval is not equivalent to a box (i.e. has - at least one infinite boundary). Get the number of base Frame axes in the - Interval, and check the supplied PointSet has the same number of axis - values per point. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - nc = astGetNaxes( frm ); - if( astGetNcoord( pset ) != nc && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axis " - "values per point (%d) in the supplied PointSet - should be " - "%d (internal AST programming error).", status, astGetClass( this ), - astGetNcoord( pset ), nc ); - } - -/* Get the number of axes in the uncertainty Region and check it is the - same as above. */ - if( unc && astGetNaxes( unc ) != nc && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axes (%d) " - "in the supplied uncertainty Region - should be " - "%d (internal AST programming error).", status, astGetClass( this ), - astGetNaxes( unc ), nc ); - } - -/* Get the centre of the region in the base Frame. We use this as a "safe" - interior point within the region. */ - safe = astRegCentre( this, NULL, NULL, 0, AST__BASE ); - -/* We now find the maximum distance on each axis that a point can be from - the boundary of the Interval for it still to be considered to be on the - boundary. First get the Region which defines the uncertainty within the - Interval being checked (in its base Frame), re-centre it on the interior - point found above (to avoid problems if the uncertainty region straddles - a discontinuity), and get its bounding box. */ - tunc = astGetUncFrm( this, AST__BASE ); - if( safe ) astRegCentre( tunc, safe, NULL, 0, AST__CURRENT ); - lbnd_tunc = astMalloc( sizeof( double )*(size_t) nc ); - ubnd_tunc = astMalloc( sizeof( double )*(size_t) nc ); - astGetRegionBounds( tunc, lbnd_tunc, ubnd_tunc ); - -/* Also get the Region which defines the uncertainty of the supplied - points and get its bounding box. First re-centre the uncertainty at the - interior position to avoid problems from uncertainties that straddle a - discontinuity. */ - if( unc ) { - if( safe ) astRegCentre( unc, safe, NULL, 0, AST__CURRENT ); - lbnd_unc = astMalloc( sizeof( double )*(size_t) nc ); - ubnd_unc = astMalloc( sizeof( double )*(size_t) nc ); - astGetRegionBounds( unc, lbnd_unc, ubnd_unc ); - } else { - lbnd_unc = NULL; - ubnd_unc = NULL; - } - -/* The required border width for each axis is half of the total width of - the two bounding boxes. Use a zero sized box "unc" if no box was supplied. */ - wid = astMalloc( sizeof( double )*(size_t) nc ); - large_lbnd = astMalloc( sizeof( double )*(size_t) nc ); - large_ubnd = astMalloc( sizeof( double )*(size_t) nc ); - small_lbnd = astMalloc( sizeof( double )*(size_t) nc ); - small_ubnd = astMalloc( sizeof( double )*(size_t) nc ); - if( small_ubnd ) { - if( unc ) { - for( i = 0; i < nc; i++ ) { - wid[ i ] = 0.5*( fabs( astAxDistance( frm, i + 1, lbnd_tunc[ i ], - ubnd_tunc[ i ] ) ) - + fabs( astAxDistance( frm, i + 1, lbnd_unc[ i ], - ubnd_unc[ i ] ) ) ); - } - } else { - for( i = 0; i < nc; i++ ) { - wid[ i ] = 0.5*fabs( astAxDistance( frm, i + 1, lbnd_tunc[ i ], - ubnd_tunc[ i ] ) ); - } - } - -/* Create two new Intervals, one of which is larger than "this" by the widths - found above, and the other of which is smaller than "this" by the widths - found above. */ - for( i = 0; i < nc; i++ ) { - lb = this->lbnd[ i ]; - ub = this->ubnd[ i ]; - if( lb > ub ) { - t = ub; - ub = lb; - lb = t; - } - - w = fabs( wid[ i ] ); - if( lb != -DBL_MAX ){ - large_lbnd[ i ] = lb - w; - small_lbnd[ i ] = lb + w; - } else { - large_lbnd[ i ] = AST__BAD; - small_lbnd[ i ] = AST__BAD; - } - - if( ub != DBL_MAX ){ - large_ubnd[ i ] = ub + w; - small_ubnd[ i ] = ub - w; - } else { - large_ubnd[ i ] = AST__BAD; - small_ubnd[ i ] = AST__BAD; - } - - if( small_lbnd[ i ] > small_ubnd[ i ] ) { - small_lbnd[ i ] = small_ubnd[ i ]; - } - } - - large_int = astInterval( frm, large_lbnd, large_ubnd, NULL, "", status ); - small_int = astInterval( frm, small_lbnd, small_ubnd, NULL, "", status ); - -/* Negate the smaller interval.*/ - astNegate( small_int ); - -/* Points are on the boundary of "this" if they are inside both the large - interval and the negated small interval. First transform the supplied - PointSet using the large interval, then transform them using the negated - smaller Interval. */ - ps1 = astTransform( large_int, pset, 1, NULL ); - ps2 = astTransform( small_int, ps1, 1, NULL ); - -/* Get a point to the resulting axis values, and the number of axis - values per axis. */ - ptr = astGetPoints( ps2 ); - np = astGetNpoint( ps2 ); - -/* If a mask array is to be returned, create one. */ - if( mask ) { - *mask = astMalloc( sizeof(int)*(size_t) np ); - -/* Check all the resulting points, setting mask values for all of them. */ - if( astOK ) { - -/* Initialise the mask elements on the basis of the first axis values */ - result = 1; - p = ptr[ 0 ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ j ] = 0; - } else { - (*mask)[ j ] = 1; - } - } - -/* Now check for bad values on other axes. */ - for( i = 1; i < nc; i++ ) { - p = ptr[ i ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ j ] = 0; - } - } - } - } - -/* If no output mask is to be made, we can break out of the check as soon - as the first bad value is found. */ - } else if( astOK ) { - result = 1; - for( i = 0; i < nc && result; i++ ) { - p = ptr[ i ]; - for( j = 0; j < np; j++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - break; - } - } - } - } - -/* Free resources. */ - large_int = astAnnul( large_int ); - small_int = astAnnul( small_int ); - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - } - - tunc = astAnnul( tunc ); - frm = astAnnul( frm ); - lbnd_tunc = astFree( lbnd_tunc ); - ubnd_tunc = astFree( ubnd_tunc ); - if( unc ) lbnd_unc = astFree( lbnd_unc ); - if( unc ) ubnd_unc = astFree( ubnd_unc ); - wid = astFree( wid ); - large_lbnd = astFree( large_lbnd ); - large_ubnd = astFree( large_ubnd ); - small_lbnd = astFree( small_lbnd ); - small_ubnd = astFree( small_ubnd ); - safe = astFree( safe ); - -/* If an error has occurred, return zero. */ - if( !astOK ) { - result = 0; - if( mask ) *mask = astAnnul( *mask ); - } - -/* Return the result. */ - return result; -} - -static int RegTrace( AstRegion *this_region, int n, double *dist, double **ptr, - int *status ){ -/* -*+ -* Name: -* RegTrace - -* Purpose: -* Return requested positions on the boundary of a 2D Region. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* int astTraceRegion( AstRegion *this, int n, double *dist, double **ptr ); - -* Class Membership: -* Interval member function (overrides the astTraceRegion method -* inherited from the parent Region class). - -* Description: -* This function returns positions on the boundary of the supplied -* Region, if possible. The required positions are indicated by a -* supplied list of scalar parameter values in the range zero to one. -* Zero corresponds to some arbitrary starting point on the boundary, -* and one corresponds to the end (which for a closed region will be -* the same place as the start). - -* Parameters: -* this -* Pointer to the Region. -* n -* The number of positions to return. If this is zero, the function -* returns without action (but the returned function value still -* indicates if the method is supported or not). -* dist -* Pointer to an array of "n" scalar parameter values in the range -* 0 to 1.0. -* ptr -* A pointer to an array of pointers. The number of elements in -* this array should equal tthe number of axes in the Frame spanned -* by the Region. Each element of the array should be a pointer to -* an array of "n" doubles, in which to return the "n" values for -* the corresponding axis. The contents of the arrays are unchanged -* if the supplied Region belongs to a class that does not -* implement this method. - -* Returned Value: -* Non-zero if the astTraceRegion method is implemented by the class -* of Region supplied, and zero if not. - -*- -*/ - -/* Local Variables; */ - AstBox *box; - int result; - -/* Initialise */ - result = 0; - -/* Check inherited status. */ - if( ! astOK ) return result; - -/* If the Interval is effectively a Box, invoke the astRegTrace function on - the equivalent Box. A pointer to the equivalent Box will be stored in the - Interval structure. */ - box = Cache( (AstInterval *) this_region, status ); - if( box ) result = astRegTrace( box, n, dist, ptr ); - -/* Return the result. */ - return result; -} - - - -static void ResetCache( AstRegion *this, int *status ){ -/* -* Name: -* ResetCache - -* Purpose: -* Clear cached information within the supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* void ResetCache( AstRegion *this, int *status ) - -* Class Membership: -* Region member function (overrides the astResetCache method -* inherited from the parent Region class). - -* Description: -* This function clears cached information from the supplied Region -* structure. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. -*/ - if( this ) { - ( (AstInterval *) this )->stale = 1; - (*parent_resetcache)( this, status ); - } -} - -static void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) { -/* -* Name: -* SetRegFS - -* Purpose: -* Stores a new FrameSet in a Region - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) - -* Class Membership: -* Interval method (over-rides the astSetRegFS method inherited from -* the Region class). - -* Description: -* This function creates a new FrameSet and stores it in the supplied -* Region. The new FrameSet contains two copies of the supplied -* Frame, connected by a UnitMap. - -* Parameters: -* this -* Pointer to the Region. -* frm -* The Frame to use. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent method to store the FrameSet in the parent Region - structure. */ - (* parent_setregfs)( this_region, frm, status ); - -/* Indicate that the cached intermediate information is now stale and - should be recreated when next needed. */ - astResetCache( this_region ); -} - -static void SetUnc( AstRegion *this, AstRegion *unc, int *status ){ -/* -* Name: -* SetUnc - -* Purpose: -* Store uncertainty information in a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* void SetUnc( AstRegion *this, AstRegion *unc, int *status ) - -* Class Membership: -* Interval method (over-rides the astSetUnc method inherited from the -* Region class). - -* Description: -* Each Region (of any class) can have an "uncertainty" which specifies -* the uncertainties associated with the boundary of the Region. This -* information is supplied in the form of a second Region. The uncertainty -* in any point on the boundary of a Region is found by shifting the -* associated "uncertainty" Region so that it is centred at the boundary -* point being considered. The area covered by the shifted uncertainty -* Region then represents the uncertainty in the boundary position. -* The uncertainty is assumed to be the same for all points. -* -* The uncertainty is usually specified when the Region is created, but -* this function allows it to be changed at any time. - -* Parameters: -* this -* Pointer to the Region which is to be assigned a new uncertainty. -* unc -* Pointer to the new uncertainty Region. This must be either a Box, -* a Circle or an Ellipse. A deep copy of the supplied Region will be -* taken, so subsequent changes to the uncertainty Region using the -* supplied pointer will have no effect on the Region "this". -* status -* Pointer to the inherited status variable. -*/ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Invoke the astSetUnc method inherited from the parent Region class. */ - (*parent_setunc)( this, unc, status ); - -/* Indicate that the cached intermediate information is now stale and - should be recreated when next needed. */ - astResetCache( this ); -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mapping represented by a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* Interval method (over-rides the astSimplify method inherited -* from the Region class). - -* Description: -* This function invokes the parent Region Simplify method, and then -* performs any further region-specific simplification. -* -* If the Mapping from base to current Frame is not a UnitMap, this -* will include attempting to fit a new Region to the boundary defined -* in the current Frame. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the simplified Region. A cloned pointer to the -* supplied Region will be returned if no simplication could be -* performed. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstBox *box2; /* Box used to determine 1-to-1 axis correspondance */ - AstBox *box; /* Box used to determine 1-to-1 axis correspondance */ - AstInterval *this_interval;/* Pointer to Interval structure */ - AstMapping *bfrm; /* Pointer to base Frame in supplied Interval */ - AstMapping *cfrm; /* Pointer to current Frame in supplied Interval */ - AstMapping *map; /* Base -> current Mapping after parent simplification */ - AstMapping *result; /* Result pointer to return */ - AstPointSet *pset2; /* PointSet containing current Frame test points */ - AstPointSet *pset3; /* PointSet containing base Frame test points */ - AstPointSet *psetb; /* PointSet holding base positions */ - AstPointSet *psetc; /* PointSet holding current positions */ - AstRegion *new; /* Pointer to Region simplfied by parent class */ - AstRegion *sreg; /* Pointer to simplified Box */ - AstRegion *this; /* Pointer to supplied Region structure */ - AstRegion *unc; /* Pointer to uncertainty Region */ - double **ptr2; /* Pointer axis values in "pset2" */ - double **ptr3; /* Pointer axis values in "pset3" */ - double **ptr; /* Pointer to base Frame values defining Interval */ - double **ptrb; /* Pointer to "psetb" axis values */ - double **sptr; /* Pointer to simplified Interval bounds */ - double *lbnd; /* Pointer to array of base Frame lower bounds */ - double *slbnd; /* Pointer to array of current Frame lower bounds */ - double *subnd; /* Pointer to array of current Frame upper bounds */ - double *ubnd; /* Pointer to array of base Frame upper bounds */ - double d; /* Distance between axis values */ - double lb; /* Lower bound on axis values */ - double lwid; /* Axis width below the Interval lower limit */ - double maxd; /* Maximum currenrt Frame axis offset between test points */ - double tmp; /* Temporary storage for swapping variable values */ - double ub; /* Upperbound on axis values */ - double uwid; /* Axis width above the Interval upper limit */ - int bax; /* Base Frame axis index corresponding to "ic" */ - int ic; /* Axis index */ - int jc; /* Axis index */ - int nc; /* No. of base Frame axis values per point */ - int simpler; /* Has some simplication taken place? */ - int snc; /* No. of current Frame axis values per point */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the supplied Region structure. */ - this = (AstRegion *) this_mapping; - -/* Get a pointer to the supplied Interval structure. */ - this_interval = (AstInterval *) this; - -/* If this Interval is equivalent to a Box, use the astTransform method of - the equivalent Box. */ - box = Cache( this_interval, status ); - if( box ) { - result = astSimplify( box ); - -/* Otherwise, we use a new implementation appropriate for unbounded - intervals. */ - } else { - -/* Invoke the parent Simplify method inherited from the Region class. This - will simplify the encapsulated FrameSet and uncertainty Region. */ - new = (AstRegion *) (*parent_simplify)( this_mapping, status ); - if( new ) { - -/* Note if any simplification took place. This is assumed to be the case - if the pointer returned by the above call is different to the supplied - pointer. */ - simpler = ( new != this ); - -/* If the Mapping from base to current Frame is not a UnitMap, we attempt - to simplify the Interval by re-defining it within its current Frame. */ - map = astGetMapping( new->frameset, AST__BASE, AST__CURRENT ); - if( !astIsAUnitMap( map ) ){ - -/* Take a copy of the Interval bounds (defined in the base Frame of the - Intervals FrameSet) and replace any missing limits with arbitrary - non-BAD values. This will give us a complete set of bounds defining a - box within the base Frame of the Interval. */ - ptr = astGetPoints( new->points ); - nc = astGetNcoord( new->points ); - - lbnd = astMalloc( sizeof( double )*(size_t) nc ); - ubnd = astMalloc( sizeof( double )*(size_t) nc ); - - if( astOK ) { - for( ic = 0; ic < nc; ic++ ) { - lbnd[ ic ] = ptr[ ic ][ 0 ]; - ubnd[ ic ] = ptr[ ic ][ 1 ]; - -/* Ensure we have a good upper bound for this axis. */ - if( ubnd[ ic ] == AST__BAD ) { - if( lbnd[ ic ] == AST__BAD ) { - ubnd[ ic ] = 1.0; - - } else if( lbnd[ ic ] > 0.0 ) { - ubnd[ ic ] = lbnd[ ic ]*1.01; - - } else if( lbnd[ ic ] < 0.0 ) { - ubnd[ ic ] = lbnd[ ic ]*0.99; - - } else { - ubnd[ ic ] = 1.0; - } - } - -/* Ensure we have a good lower bound for this axis. */ - if( lbnd[ ic ] == AST__BAD ) { - if( ubnd[ ic ] > 0.0 ) { - lbnd[ ic ] = ubnd[ ic ]*0.99; - - } else if( ubnd[ ic ] < 0.0 ) { - lbnd[ ic ] = ubnd[ ic ]*1.01; - - } else { - lbnd[ ic ] = 1.0; - } - } - } - } - -/* Transform the box corners found above into the current frame and then back - into the base Frame, and ensure that the box encloses both the original - and the new bounds. PermMaps with fewer outputs than inputs can cause the - resulting base Frame positions to differ significantly from the original. */ - psetb =astPointSet( 2, nc,"", status ); - ptrb =astGetPoints( psetb ); - if( astOK ) { - for( ic = 0; ic < nc; ic++ ) { - ptrb[ ic ][ 0 ] = lbnd[ ic ]; - ptrb[ ic ][ 1 ] = ubnd[ ic ]; - } - } - psetc = astTransform( map, psetb, 1, NULL ); - (void) astTransform( map, psetc, 0, psetb ); - if( astOK ) { - for( ic = 0; ic < nc; ic++ ) { - lb = ptrb[ ic ][ 0 ]; - if( lb != AST__BAD ) { - if( lb < lbnd[ ic ] ) lbnd[ ic ] = lb; - if( lb > ubnd[ ic ] ) ubnd[ ic ] = lb; - } - ub = ptrb[ ic ][ 1 ]; - if( ub != AST__BAD ) { - if( ub < lbnd[ ic ] ) lbnd[ ic ] = ub; - if( ub > ubnd[ ic ] ) ubnd[ ic ] = ub; - } - } - } - psetb = astAnnul( psetb ); - psetc = astAnnul( psetc ); - -/* Limit this box to not exceed the limits imposed by the Interval.*/ - Cache( this_interval, status ); - for( ic = 0; ic < nc; ic++ ) { - lb = this_interval->lbnd[ ic ] ; - ub = this_interval->ubnd[ ic ] ; - if( lb <= ub ) { - if( lbnd[ ic ] < lb ) { - lbnd[ ic ] = lb; - } else if( lbnd[ ic ] > ub ) { - lbnd[ ic ] = ub; - } - if( ubnd[ ic ] < lb ) { - ubnd[ ic ] = lb; - } else if( ubnd[ ic ] > ub ) { - ubnd[ ic ] = ub; - } - } else { - lwid = lb - lbnd[ ic ]; - uwid = ubnd[ ic ] - ub; - if( lwid > uwid ) { - if( lbnd[ ic ] > lb ) lbnd[ ic ] = lb; - if( ubnd[ ic ] > lb ) ubnd[ ic ] = lb; - } else { - if( lbnd[ ic ] < ub ) lbnd[ ic ] = ub; - if( ubnd[ ic ] < ub ) ubnd[ ic ] = ub; - } - } - -/* Ensure the bounds are not equal */ - if( lbnd[ ic ] == 0.0 && ubnd[ ic ] == 0.0 ) { - ubnd[ ic ] = 1.0; - - } else if( astEQUALS( lbnd[ ic ], ubnd[ ic ], 1.0E9 ) ) { - ubnd[ ic ] = astMAX( ubnd[ ic ], lbnd[ ic ] )*( 1.0E6*DBL_EPSILON ); - } - } - -/* Create a new Box representing the box found above. */ - bfrm = astGetFrame( new->frameset, AST__BASE ); - unc = astTestUnc( new ) ? astGetUncFrm( new, AST__BASE ) : NULL; - box = astBox( bfrm, 1, lbnd, ubnd, unc, "", status ); - if( unc ) unc = astAnnul( unc ); - -/* Modify this Box so that it has the same current Frame as this Interval. */ - cfrm = astGetFrame( new->frameset, AST__CURRENT ); - box2 = astMapRegion( box, map, cfrm ); - -/* Try simplifying the Box. */ - sreg = (AstRegion *) astSimplify( box2 ); - -/* Only proceed if the Box was simplified */ - if( sreg != (AstRegion *) box2 ) { - -/* If the simplified Box is a NullRegion return it. */ - if( astIsANullRegion( sreg ) ) { - (void) astAnnul( new ); - new = astClone( sreg ); - simpler = 1; - -/* If the simplified Box is a Box or an Interval... */ - } else if( astIsABox( sreg ) || astIsAInterval( sreg ) ) { - -/* Get the bounds of the simplified Box. We assume that the base and - current Frames in the simplified Box are the same. */ - snc = astGetNin( sreg->frameset ); - slbnd = astMalloc( sizeof( double )*(size_t)snc ); - subnd = astMalloc( sizeof( double )*(size_t)snc ); - if( astIsAInterval( sreg ) ) { - sptr = astGetPoints( sreg->points ); - if( astOK ) { - for( ic = 0; ic < snc; ic++ ) { - slbnd[ ic ] = sptr[ ic ][ 0 ]; - subnd[ ic ] = sptr[ ic ][ 1 ]; - } - } - } else { - astRegBaseBox( sreg, slbnd, subnd ); - } - -/* Now create a PointSet containing one point for each axis in the - current (or equivalently, base ) Frame of the simplified Box, plus an - extra point. */ - pset2 = astPointSet( snc + 1, snc, "", status ); - ptr2 = astGetPoints( pset2 ); - -/* Put the lower bounds of the simplified Box into the first point in - this PointSet. The remaining points are displaced from this first point - along each axis in turn. The length of each displacement is determined - by the length of the box on the axis. */ - if( astOK ) { - for( ic = 0; ic < snc; ic++ ) { - for( jc = 0; jc < snc + 1; jc++ ) { - ptr2[ ic ][ jc ] = slbnd[ ic ]; - } - ptr2[ ic ][ ic + 1 ] = subnd[ ic ]; - } - } - -/* Transform this PointSet into the base Frame of this Interval using the - inverse of the base->current Mapping. */ - pset3 = astTransform( map, pset2, 0, NULL ); - ptr3 = astGetPoints( pset3 ); - if( astOK ) { - -/* Now consider each axis of the Interval's current Frame (i.e. each base - Frame axis in the simplified Box). */ - for( ic = 0; ic < snc; ic++ ) { - -/* Given that the Box simplified succesfully, we know that there is a one - to one connection between the axes of the base and current Frame in this - Interval, but we do not yet know which base Frame axis corresponds to - which current Frame axis (and the number of base and current Frame axes - need not be equal). We have two points on a line parallel to current - Frame axis number "ic" (points zero and "ic+1" in "pset2"). Look at the - corresponding base Frame positions (in "pset3), and see which base Frame - axis they are parallel to. We look for the largest base Frame axis - increment (this allows small non-zero displacements to occur on the - other axes due to rounding errors). */ - maxd = -DBL_MAX; - bax = -1; - for( jc = 0; jc < nc; jc++ ) { - d = fabs( astAxDistance( bfrm, jc + 1, ptr3[ jc ][ 0 ], - ptr3[ jc ][ ic + 1 ] ) ); - if( d != AST__BAD && d > maxd ) { - maxd = d; - bax = jc; - } - } - -/* If the largest base Frame axis increment is zero, it must mean that - the current Frame axis is not present in the base Frame. The only - plausable cause of this is if the base->current Mapping contains a - PermMap which introduces an extra axis, in which case the axis will - have a fixed value (any other Mapping arrangement would have prevented - the Box from simplifying). Therefore, set upper and lower limits for - this axis to the same value. */ - if( maxd <= 0.0 ) { - if( slbnd[ ic ] == AST__BAD || - subnd[ ic ] == AST__BAD ) { - slbnd[ ic ] = AST__BAD; - } else { - slbnd[ ic ] = 0.5*( slbnd[ ic ] + subnd[ ic ] ); - } - subnd[ ic ] = slbnd[ ic ]; - -/* If we have found a base Frame axis which corresponds to the current - Frame axis "ic", then look to see which limits are specified for the - base Frame axis, and transfer missing limits to the current Frame. */ - } else { - if( ptr[ bax ][ 0 ] == AST__BAD ) slbnd[ ic ] = AST__BAD; - if( ptr[ bax ][ 1 ] == AST__BAD ) subnd[ ic ] = AST__BAD; - -/* If the original limits were equal, ensure the new limits are equal - (the code above modified the upper limit to ensure it was different to - the lower limit). */ - if( ptr[ bax ][ 1 ] == ptr[ bax ][ 0 ] ) { - subnd[ ic ] = slbnd[ ic ]; - -/* If the original interval was an inclusion (ubnd > lbnd), ensure the new - interval is also an inclusion by swapping the limits if required. */ - } else if( ptr[ bax ][ 1 ] > ptr[ bax ][ 0 ] ) { - if( subnd[ ic ] < slbnd[ ic ] ) { - tmp = subnd[ ic ]; - subnd[ ic ] = slbnd[ ic ]; - slbnd[ ic ] = tmp; - } - -/* If the original interval was an exclusion (ubnd < lbnd), ensure the new - interval is also an exlusion by swapping the limits if required. */ - } else if( ptr[ bax ][ 1 ] < ptr[ bax ][ 0 ] ) { - if( subnd[ ic ] > slbnd[ ic ] ) { - tmp = subnd[ ic ]; - subnd[ ic ] = slbnd[ ic ]; - slbnd[ ic ] = tmp; - } - } - } - } - -/* Create the simplified Interval from the current Frame limits found - above, and use it in place of the original. */ - unc = astTestUnc( new ) ? astGetUncFrm( new, AST__CURRENT ) : NULL; - (void) astAnnul( new ); - new = (AstRegion *) astInterval( cfrm, slbnd, subnd, unc, "", status ); - if( unc ) unc = astAnnul( unc ); - simpler = 1; - } - -/* Free resources */ - pset2 = astAnnul( pset2 ); - pset3 = astAnnul( pset3 ); - slbnd = astFree( slbnd ); - subnd = astFree( subnd ); - } - } - -/* Free resources */ - bfrm = astAnnul( bfrm ); - cfrm = astAnnul( cfrm ); - box = astAnnul( box ); - box2 = astAnnul( box2 ); - sreg = astAnnul( sreg ); - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - } - -/* Free resources */ - map = astAnnul( map ); - -/* If any simplification could be performed, copy Region attributes from - the supplied Region to the returned Region, and return a pointer to it. - If the supplied Region had no uncertainty, ensure the returned Region - has no uncertainty. Otherwise, return a clone of the supplied pointer. */ - if( simpler ){ - astRegOverlay( new, this, 1 ); - result = (AstMapping *) new; - } else { - new = astAnnul( new ); - result = astClone( this ); - } - } - } - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a Interval to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* Interval member function (over-rides the astTransform protected -* method inherited from the Region class). - -* Description: -* This function takes a Interval and a set of points encapsulated in a -* PointSet and transforms the points by setting axis values to -* AST__BAD for all points which are outside the region. Points inside -* the region are copied unchanged from input to output. - -* Parameters: -* this -* Pointer to the Interval. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - The forward and inverse transformations are identical for a -* Region. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of axes in the Frame represented by the Interval. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstBox *box; /* Pointer to equivalent Box */ - AstInterval *this; /* Pointer to Interval structure */ - AstPointSet *pset_tmp; /* Pointer to PointSet holding base Frame positions*/ - AstPointSet *result; /* Pointer to output PointSet */ - AstRegion *reg; /* Pointer to Region structure */ - AstRegion *unc; /* Uncertainty Region */ - double **ptr_lims; /* Pointer to limits array */ - double **ptr_out; /* Pointer to output coordinate data */ - double **ptr_tmp; /* Pointer to base Frame coordinate data */ - double *lbnd_unc; /* Lower bounds of uncertainty Region */ - double *ubnd_unc; /* Upper bounds of uncertainty Region */ - double lb; /* Base Frame axis lower bound */ - double p; /* Input base Frame axis value */ - double ub; /* Base Frame axis upper bound */ - double wid; /* Half width of uncertainy Region */ - int coord; /* Zero-based index for coordinates */ - int ncoord_out; /* No. of coordinates per output point */ - int ncoord_tmp; /* No. of coordinates per base Frame point */ - int neg; /* Has the Region been negated? */ - int npoint; /* No. of points */ - int pass; /* Does this point pass the axis test? */ - int point; /* Loop counter for points */ - int setbad; /* Set the output point bad? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain pointers to the Region and to the Interval. */ - reg = (AstRegion *) this_mapping; - this = (AstInterval *) this_mapping; - -/* If this Interval is equivalent to a Box, use the astTransform method of - the equivalent Box. */ - box = Cache( this, status ); - if( box ) { - result = astTransform( box, in, forward, out ); - -/* Otherwise, we use a new implementation appropriate for unbounded - intervals. */ - } else { - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, - containing a copy of the input PointSet. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* First use the encapsulated FrameSet to transform the supplied positions - from the current Frame in the encapsulated FrameSet (the Frame - represented by the Region), to the base Frame (the Frame in which the - Region is defined). This call also returns a pointer to the base Frame - of the encapsulated FrameSet. Note, the returned pointer may be a - clone of the "in" pointer, and so we must be carefull not to modify the - contents of the returned PointSet. */ - pset_tmp = astRegTransform( reg, in, 0, NULL, NULL ); - -/* Determine the numbers of points and coordinates per point from the base - Frame PointSet and obtain pointers for accessing the base Frame and output - coordinate values. */ - npoint = astGetNpoint( pset_tmp ); - ncoord_tmp = astGetNcoord( pset_tmp ); - ptr_tmp = astGetPoints( pset_tmp ); - ncoord_out = astGetNcoord( result ); - ptr_out = astGetPoints( result ); - -/* Get a pointer to the array of axis limits */ - ptr_lims = astGetPoints( reg->points ); - -/* See if the Region is negated. */ - neg = astGetNegated( reg ); - -/* Indicate we have not yet got the bounding box of the uncertainty - Region. */ - lbnd_unc = NULL; - ubnd_unc = NULL; - unc = NULL; - -/* Perform coordinate arithmetic. */ - if ( astOK ) { - -/* First deal with closed unnegated Intervals. */ -/* ------------------------------------------- */ - if( astGetClosed( reg ) ) { - if( !neg ) { - -/* Loop round each point. */ - for ( point = 0; point < npoint; point++ ) { - -/* Assume this point is inside the Region. We change this flag when we find - the first axis for which the point does not pass the axis test. */ - setbad = 0; - -/* Loop round each base Frame axis */ - Cache( this, status ); - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - p = ptr_tmp[ coord ][ point ]; - lb = (this->lbnd)[ coord ]; - ub = (this->ubnd)[ coord ]; - -/* If the limits are equal separate them slightly to give some tolerance. */ - if( lb == ub ) { - -/* If not yet done so, get the bounding box of the uncertainty Region in the - base Frame of the Interval */ - if( !unc ) { - unc = astGetUncFrm( reg, AST__BASE ); - lbnd_unc = astMalloc( sizeof( double)*(size_t) ncoord_tmp ); - ubnd_unc = astMalloc( sizeof( double)*(size_t) ncoord_tmp ); - astGetRegionBounds( unc, lbnd_unc, ubnd_unc ); - } - -/* Set the gap between the limits to be equal to the uincertainty on this - axis. */ - if( astOK ) { - wid = 0.5*( ubnd_unc[ coord ] - lbnd_unc[ coord ] ); - lb -= wid; - ub += wid; - } - } - -/* Bad input points should always be bad in the output. */ - if( p == AST__BAD ) { - setbad = 1; - break; - -/* Does the current axis value pass the limits test for this axis? */ - } else if( lb <= ub ) { - pass = ( lb <= p && p <= ub ); - } else { - pass = ( p <= ub || lb <= p ); - } - -/* If this point does not pass the test for this axis, then indicate that - we should set the resulting output point bad and break since we now have - a definite value for the inside/outside flag. */ - if( !pass ) { - setbad = 1; - break; - } - } - -/* Set the axis values bad for this output point if required. */ - if( setbad ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - -/* Now deal with closed negated Intervals. */ -/* --------------------------------------- */ - } else { - -/* Loop round each point. */ - for ( point = 0; point < npoint; point++ ) { - -/* Assume this point is outside the negated Region (i.e. inside the - unnegated Region). We change this flag when we find the first axis for - which the point passes the axis test. */ - setbad = 1; - -/* Loop round each base Frame axis */ - Cache( this, status ); - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - p = ptr_tmp[ coord ][ point ]; - lb = (this->lbnd)[ coord ]; - ub = (this->ubnd)[ coord ]; - -/* Bad input points should always be bad in the output. */ - if( p == AST__BAD ) { - setbad = 1; - break; - -/* Does the current axis value pass the limits test for this axis? */ - } else if( lb <= ub ) { - pass = ( p <= lb || ub <= p ); - } else { - pass = ( ub <= p && p <= lb ); - } - -/* If this point passes the test for this axis, then indicate that we should - not set the resulting output point bad and break since we now have a - definite value for the inside/outside flag. */ - if( pass ) { - setbad = 0; - break; - } - } - -/* Set the axis values bad for this output point if required. */ - if( setbad ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - } - -/* Now deal with open unnegated Intervals. */ -/* --------------------------------------- */ - } else { - if( !neg ) { - -/* Loop round each point. */ - for ( point = 0; point < npoint; point++ ) { - -/* Assume this point is inside the Region. We change this flag when we find - the first axis for which the point does not pass the axis test. */ - setbad = 0; - -/* Loop round each base Frame axis */ - Cache( this, status ); - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - p = ptr_tmp[ coord ][ point ]; - lb = (this->lbnd)[ coord ]; - ub = (this->ubnd)[ coord ]; - -/* Bad input points should always be bad in the output. */ - if( p == AST__BAD ) { - setbad = 1; - break; - -/* Does the current axis value pass the limits test for this axis? */ - } else if( lb <= ub ) { - pass = ( lb < p && p < ub ); - } else { - pass = ( p < ub || lb < p ); - } - -/* If this point does not pass the test for this axis, then indicate that - we should set the resulting output point bad and break since we now have - a definite value for the inside/outside flag. */ - if( !pass ) { - setbad = 1; - break; - } - } - -/* Set the axis values bad for this output point if required. */ - if( setbad ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - -/* Now deal with open negated Intervals. */ -/* ------------------------------------- */ - } else { - -/* Loop round each point. */ - for ( point = 0; point < npoint; point++ ) { - -/* Assume this point is outside the negated Region (i.e. inside the - unnegated Region). We change this flag when we find the first axis for - which the point passes the axis test. */ - setbad = 1; - -/* Loop round each base Frame axis */ - Cache( this, status ); - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - p = ptr_tmp[ coord ][ point ]; - lb = (this->lbnd)[ coord ]; - ub = (this->ubnd)[ coord ]; - -/* If the limits are equal separate them slightly to give some tolerance. */ - if( lb == ub ) { - -/* If not yet done so, get the bounding box of the uncertainty Region in the - base Frame of the Interval */ - if( !unc ) { - unc = astGetUncFrm( reg, AST__BASE ); - lbnd_unc = astMalloc( sizeof( double)*(size_t) ncoord_tmp ); - ubnd_unc = astMalloc( sizeof( double)*(size_t) ncoord_tmp ); - astGetRegionBounds( unc, lbnd_unc, ubnd_unc ); - } - -/* Set the gap between the limits to be equal to the uincertainty on this - axis. */ - if( astOK ) { - wid = 0.5*( ubnd_unc[ coord ] - lbnd_unc[ coord ] ); - lb -= wid; - ub += wid; - } - } - -/* Bad input points should always be bad in the output. */ - if( p == AST__BAD ) { - setbad = 1; - break; - -/* Does the current axis value pass the limits test for this axis? */ - } else if( lb <= ub ) { - pass = ( p < lb || ub < p ); - } else { - pass = ( ub < p && p < lb ); - } - -/* If this point passes the test for this axis, then indicate that we should - not set the resulting output point bad and break since we now have a - definite value for the inside/outside flag. */ - if( pass ) { - setbad = 0; - break; - } - } - -/* Set the axis values bad for this output point if required. */ - if( setbad ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - } - } - } - -/* Free resources */ - pset_tmp = astAnnul( pset_tmp ); - if( lbnd_unc ) lbnd_unc = astFree( lbnd_unc ); - if( ubnd_unc ) ubnd_unc = astFree( ubnd_unc ); - if( unc ) unc = astAnnul( unc ); - } - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Interval objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Region objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstInterval *in; /* Pointer to input Interval */ - AstInterval *out; /* Pointer to output Interval */ - size_t nb; /* Number of bytes in limits array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Intervals. */ - in = (AstInterval *) objin; - out = (AstInterval *) objout; - -/* For safety, first clear any references to the input memory from - the output Interval. */ - out->box = NULL; - out->lbnd = NULL; - out->ubnd = NULL; - -/* Note the number of bytes in each limits array */ - nb = sizeof( double )*(size_t) astGetNin( ((AstRegion *) in)->frameset ); - -/* Copy dynamic memory contents */ - if( in->box ) out->box = astCopy( in->box ); - out->lbnd = astStore( NULL, in->lbnd, nb ); - out->ubnd = astStore( NULL, in->ubnd, nb ); -} - - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Interval objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Interval objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstInterval *this; /* Pointer to Interval */ - -/* Obtain a pointer to the Interval structure. */ - this = (AstInterval *) obj; - -/* Annul all resources. */ - if( this->box ) this->box = astAnnul( this->box ); - this->lbnd = astFree( this->lbnd ); - this->ubnd = astFree( this->ubnd ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Interval objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Interval class to an output Channel. - -* Parameters: -* this -* Pointer to the Interval whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstInterval *this; /* Pointer to the Interval structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Interval structure. */ - this = (AstInterval *) this_object; - -/* Write out values representing the instance variables for the - Interval class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* There are no values to write, so return without further action. */ -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAInterval and astCheckInterval functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Interval,Region) -astMAKE_CHECK(Interval) - -AstInterval *astInterval_( void *frame_void, const double lbnd[], - const double ubnd[], AstRegion *unc, - const char *options, int *status, ...) { -/* -*++ -* Name: -c astInterval -f AST_INTERVAL - -* Purpose: -* Create a Interval. - -* Type: -* Public function. - -* Synopsis: -c #include "interval.h" -c AstInterval *astInterval( AstFrame *frame, const double lbnd[], -c const double ubnd[], AstRegion *unc, -c const char *options, ... ) -f RESULT = AST_INTERVAL( FRAME, LBND, UBND, UNC, OPTIONS, STATUS ) - -* Class Membership: -* Interval constructor. - -* Description: -* This function creates a new Interval and optionally initialises its -* attributes. -* -* A Interval is a Region which represents upper and/or lower limits on -* one or more axes of a Frame. For a point to be within the region -* represented by the Interval, the point must satisfy all the -* restrictions placed on all the axes. The point is outside the region -* if it fails to satisfy any one of the restrictions. Each axis may have -* either an upper limit, a lower limit, both or neither. If both limits -* are supplied but are in reverse order (so that the lower limit is -* greater than the upper limit), then the interval is an excluded -* interval, rather than an included interval. -* -* At least one axis limit must be supplied. -* -* Note, The Interval class makes no allowances for cyclic nature of -* some coordinate systems (such as SkyFrame coordinates). A Box -* should usually be used in these cases since this requires the user -* to think about suitable upper and lower limits, - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* A pointer to the Frame in which the region is defined. A deep -* copy is taken of the supplied Frame. This means that any -* subsequent changes made to the Frame using the supplied pointer -* will have no effect the Region. -c lbnd -f LBND( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the lower limits on each axis. -* Set a value to AST__BAD to indicate that the axis has no lower -* limit. -c ubnd -f UBND( * ) = DOUBLE PRECISION (Given) -c An array of double, with one element for each Frame axis -f An array with one element for each Frame axis -* (Naxes attribute) containing the upper limits on each axis. -* Set a value to AST__BAD to indicate that the axis has no upper -* limit. -c unc -f UNC = INTEGER (Given) -* An optional pointer to an existing Region which specifies the -* uncertainties associated with the boundary of the Interval being created. -* The uncertainty in any point on the boundary of the Interval is found by -* shifting the supplied "uncertainty" Region so that it is centred at -* the boundary point being considered. The area covered by the -* shifted uncertainty Region then represents the uncertainty in the -* boundary position. The uncertainty is assumed to be the same for -* all points. -* -* If supplied, the uncertainty Region must be of a class for which -* all instances are centro-symetric (e.g. Box, Circle, Ellipse, etc.) -* or be a Prism containing centro-symetric component Regions. A deep -* copy of the supplied Region will be taken, so subsequent changes to -* the uncertainty Region using the supplied pointer will have no -* effect on the created Interval. Alternatively, -f a null Object pointer (AST__NULL) -c a NULL Object pointer -* may be supplied, in which case a default uncertainty is used -* equivalent to a box 1.0E-6 of the size of the Interval being created. -* -* The uncertainty Region has two uses: 1) when the -c astOverlap -f AST_OVERLAP -* function compares two Regions for equality the uncertainty -* Region is used to determine the tolerance on the comparison, and 2) -* when a Region is mapped into a different coordinate system and -* subsequently simplified (using -c astSimplify), -f AST_SIMPLIFY), -* the uncertainties are used to determine if the transformed boundary -* can be accurately represented by a specific shape of Region. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Interval. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Interval. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astInterval() -f AST_INTERVAL = INTEGER -* A pointer to the new Interval. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstInterval *new; /* Pointer to new Interval */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the supplied Frame structure. */ - frame = astCheckFrame( frame_void ); - -/* Initialise the Interval, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitInterval( NULL, sizeof( AstInterval ), !class_init, - &class_vtab, "Interval", frame, lbnd, ubnd, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Interval's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Interval. */ - return new; -} - -AstInterval *astIntervalId_( void *frame_void, const double lbnd[], - const double ubnd[], void *unc_void, - const char *options, ... ) { -/* -* Name: -* astIntervalId_ - -* Purpose: -* Create a Interval. - -* Type: -* Private function. - -* Synopsis: -* #include "interval.h" -* AstInterval *astIntervalId_( AstFrame *frame, const double lbnd[], -* const double ubnd[], AstRegion *unc, -* const char *options, ... ) - -* Class Membership: -* Interval constructor. - -* Description: -* This function implements the external (public) interface to the -* astInterval constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astInterval_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astInterval_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astInterval_. - -* Returned Value: -* The ID value associated with the new Interval. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstInterval *new; /* Pointer to new Interval */ - AstRegion *unc; /* Pointer to Region structure */ - va_list args; /* Variable argument list */ - - int *status; /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Frame pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Frame. */ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - -/* Obtain a Region pointer from the supplied "unc" ID and validate the - pointer to ensure it identifies a valid Region . */ - unc = unc_void ? astCheckRegion( astMakePointer( unc_void ) ) : NULL; - -/* Initialise the Interval, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitInterval( NULL, sizeof( AstInterval ), !class_init, &class_vtab, - "Interval", frame, lbnd, ubnd, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Interval's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Interval. */ - return astMakeId( new ); -} - -AstInterval *astInitInterval_( void *mem, size_t size, int init, AstIntervalVtab *vtab, - const char *name, AstFrame *frame, - const double lbnd[], const double ubnd[], - AstRegion *unc, int *status ) { -/* -*+ -* Name: -* astInitInterval - -* Purpose: -* Initialise a Interval. - -* Type: -* Protected function. - -* Synopsis: -* #include "interval.h" -* AstInterval *astInitInterval( void *mem, size_t size, int init, AstIntervalVtab *vtab, -* const char *name, AstFrame *frame, -* const double lbnd[], const double ubnd[], -* AstRegion *unc ) - -* Class Membership: -* Interval initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Interval object. It allocates memory (if necessary) to accommodate -* the Interval plus any additional data associated with the derived class. -* It then initialises a Interval structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Interval at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Interval is to be initialised. -* This must be of sufficient size to accommodate the Interval data -* (sizeof(Interval)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Interval (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Interval -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Interval's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Interval. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* A pointer to the Frame in which the region is defined. -* lbnd -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the lower limits on each axis. -* Set a value to AST__BAD to indicate that the axis has no lower -* limit. Upper and ower limits can be reversed to create an -* excluded interval rather than an included interval. -* ubnd -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the upper limits on each axis. -* Set a value to AST__BAD to indicate that the axis has no upper -* limit. -* unc -* A pointer to a Region which specifies the uncertainty in the -* supplied positions (all points on the boundary of the new Interval -* being initialised are assumed to have the same uncertainty). A NULL -* pointer can be supplied, in which case default uncertainties equal to -* 1.0E-6 of the dimensions of the new Interval's bounding box are used. -* If an uncertainty Region is supplied, it must be either a Box, a -* Circle or an Ellipse, and its encapsulated Frame must be related -* to the Frame supplied for parameter "frame" (i.e. astConvert -* should be able to find a Mapping between them). Two positions -* the "frame" Frame are considered to be co-incident if their -* uncertainty Regions overlap. The centre of the supplied -* uncertainty Region is immaterial since it will be re-centred on the -* point being tested before use. A deep copy is taken of the supplied -* Region. - -* Returned Value: -* A pointer to the new Interval. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstInterval *new; /* Pointer to new Interval */ - AstPointSet *pset; /* PointSet to pass to Region initialiser */ - double **ptr; /* Pointer to coords data in pset */ - int i; /* Axis index */ - int nc; /* No. of axes */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitIntervalVtab( &class_vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Get the number of axis values required for each position. */ - nc = astGetNaxes( frame ); - -/* Create a PointSet to hold the upper and lower bounds, and get pointers to - the data arrays. */ - pset = astPointSet( 2, nc, "", status ); - ptr = astGetPoints( pset ); - if( astOK ) { - -/* Copy the limits into the PointSet. */ - for( i = 0; i < nc; i++ ) { - ptr[ i ][ 0 ] = lbnd[ i ]; - ptr[ i ][ 1 ] = ubnd[ i ]; - } - -/* Initialise a Region structure (the parent class) as the first component - within the Interval structure, allocating memory if necessary. */ - new = (AstInterval *) astInitRegion( mem, size, 0, (AstRegionVtab *) vtab, - name, frame, pset, unc ); - - if ( astOK ) { - -/* Initialise the Interval data. */ -/* ----------------------------- */ - new->lbnd = NULL; - new->ubnd = NULL; - new->box = NULL; - new->stale = 1; - -/* If an error occurred, clean up by deleting the new Interval. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Free resources. */ - pset = astAnnul( pset ); - -/* Return a pointer to the new Interval. */ - return new; -} - -AstInterval *astLoadInterval_( void *mem, size_t size, AstIntervalVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadInterval - -* Purpose: -* Load a Interval. - -* Type: -* Protected function. - -* Synopsis: -* #include "interval.h" -* AstInterval *astLoadInterval( void *mem, size_t size, AstIntervalVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* Interval loader. - -* Description: -* This function is provided to load a new Interval using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Interval structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Interval at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the Interval is to be -* loaded. This must be of sufficient size to accommodate the -* Interval data (sizeof(Interval)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Interval (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Interval structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstInterval) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Interval. If this is NULL, a pointer -* to the (static) virtual function table for the Interval class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Interval" is used instead. - -* Returned Value: -* A pointer to the new Interval. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstInterval *new; /* Pointer to the new Interval */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Interval. In this case the - Interval belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstInterval ); - vtab = &class_vtab; - name = "Interval"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitIntervalVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Interval. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Interval" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* There are no values to read. */ -/* ---------------------------- */ - new->lbnd = NULL; - new->ubnd = NULL; - new->box = NULL; - new->stale = 1; - -/* If an error occurred, clean up by deleting the new Interval. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Interval pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astIntervalPoints_( AstInterval *this, double *lbnd, double *ubnd, - int *status) { - if ( !astOK ) return; - (**astMEMBER(this,Interval,IntervalPoints))( this, lbnd, ubnd, status ); - return; -} - - - - - - diff --git a/ast/interval.h b/ast/interval.h deleted file mode 100644 index 3397e24..0000000 --- a/ast/interval.h +++ /dev/null @@ -1,236 +0,0 @@ -#if !defined( INTERVAL_INCLUDED ) /* Include this file only once */ -#define INTERVAL_INCLUDED -/* -*+ -* Name: -* interval.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Interval class. - -* Invocation: -* #include "interval.h" - -* Description: -* This include file defines the interface to the Interval class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The Interval class implement a Region which represents a simple interval -* on each axis of the encapsulated Frame - -* Inheritance: -* The Interval class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 1-NOV-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "region.h" /* Coordinate regions (parent class) */ -#include "box.h" /* Closed box regions */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* Interval structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstInterval { - -/* Attributes inherited from the parent class. */ - AstRegion region; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *lbnd; /* Lower limits */ - double *ubnd; /* Lower limits */ - AstBox *box; /* Equivalent Box */ - int stale; /* Is cached information stale? */ - -} AstInterval; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstIntervalVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* IntervalPoints)( AstInterval *, double *, double *, int *); - -} AstIntervalVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstIntervalGlobals { - AstIntervalVtab Class_Vtab; - int Class_Init; -} AstIntervalGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitIntervalGlobals_( AstIntervalGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Interval) /* Check class membership */ -astPROTO_ISA(Interval) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstInterval *astInterval_( void *, const double[], const double[], AstRegion *, const char *, int *, ...); -#else -AstInterval *astIntervalId_( void *, const double[], const double[], AstRegion *, const char *, ... )__attribute__((format(printf,5,6))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstInterval *astInitInterval_( void *, size_t, int, AstIntervalVtab *, - const char *, AstFrame *, const double[], - const double[], AstRegion *, int * ); - -/* Vtab initialiser. */ -void astInitIntervalVtab_( AstIntervalVtab *, const char *, int * ); - -/* Loader. */ -AstInterval *astLoadInterval_( void *, size_t, AstIntervalVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -void astIntervalPoints_( AstInterval *, double *, double *, int *); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckInterval(this) astINVOKE_CHECK(Interval,this,0) -#define astVerifyInterval(this) astINVOKE_CHECK(Interval,this,1) - -/* Test class membership. */ -#define astIsAInterval(this) astINVOKE_ISA(Interval,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astInterval astINVOKE(F,astInterval_) -#else -#define astInterval astINVOKE(F,astIntervalId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitInterval(mem,size,init,vtab,name,frame,lbnd,ubnd,unc) \ -astINVOKE(O,astInitInterval_(mem,size,init,vtab,name,frame,lbnd,ubnd,unc,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitIntervalVtab(vtab,name) astINVOKE(V,astInitIntervalVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadInterval(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadInterval_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckInterval to validate Interval pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astIntervalPoints(this,lbnd,ubnd) astINVOKE(V,astIntervalPoints_(astCheckInterval(this),lbnd,ubnd,STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/intramap.c b/ast/intramap.c deleted file mode 100644 index 67eebb2..0000000 --- a/ast/intramap.c +++ /dev/null @@ -1,2942 +0,0 @@ -/* -*class++ -* Name: -* IntraMap - -* Purpose: -c Map points using a private transformation function. -f Map points using a private transformation routine. - -* Constructor Function: -c astIntraMap (also see astIntraReg) -f AST_INTRAMAP (also see AST_INTRAREG) - -* Description: -c The IntraMap class provides a specialised form of Mapping which -c encapsulates a privately-defined coordinate transformation -c other AST Mapping. This allows you to create Mappings that -c perform any conceivable coordinate transformation. -f The IntraMap class provides a specialised form of Mapping which -f encapsulates a privately-defined coordinate transformation -f routine (e.g. written in Fortran) so that it may be used like -f any other AST Mapping. This allows you to create Mappings that -f perform any conceivable coordinate transformation. -* -* However, an IntraMap is intended for use within a single program -* or a private suite of software, where all programs have access -* to the same coordinate transformation functions (i.e. can be -* linked against them). IntraMaps should not normally be stored in -* datasets which may be exported for processing by other software, -* since that software will not have the necessary transformation -* functions available, resulting in an error. -* -c You must register any coordinate transformation functions to be -c used using astIntraReg before creating an IntraMap. -f You must register any coordinate transformation functions to be -f used using AST_INTRAREG before creating an IntraMap. - -* Inheritance: -* The IntraMap class inherits from the Mapping class. - -* Attributes: -* In addition to those attributes common to all Mappings, every -* IntraMap also has the following attributes: -* -* - IntraFlag: IntraMap identification string - -* Functions: -c The IntraMap class does not define any new functions beyond those -f The IntraMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 16-MAR-1998 (RFWS): -* Original version. -* 15-SEP-1999 (RFWS): -* Added a "this" pointer to the external transformation function -* used by an IntraMap. -* 20-JUN-2001 (DSB): -* Add an "astClone" call to prevent the pointer for "this" being -* annulled at the end of the Transform method. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitIntraMapVtab -* method. -* 7-DEC-2005 (DSB): -* Free memory allocated by calls to astReadString. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 10-MAY-2006 (DSB): -* Override astEqual. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS IntraMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "unitmap.h" /* Unit (identity) Mappings */ -#include "intramap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Pointer to array of transformation function data. */ -static AstIntraMapTranData *tran_data = NULL; - -/* Number of transformation functions registered. */ -static int tran_nfun = 0; - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are used or extended by this - class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_getnin)( AstMapping *, int * ); -static int (* parent_getnout)( AstMapping *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(IntraMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(IntraMap,Class_Init) -#define class_vtab astGLOBAL(IntraMap,Class_Vtab) - - -/* A mutex used to serialise invocations of the IntraReg function (the - only function allowed to modify the contents of the static tran_data - array). */ -static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX1 pthread_mutex_lock( &mutex1 ); -#define UNLOCK_MUTEX1 pthread_mutex_unlock( &mutex1 ); - -/* A mutex used to serialise invocations of extrnal transformation - functions (which may not be thread-safe). */ -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstIntraMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX1 -#define UNLOCK_MUTEX1 - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstIntraMap *astIntraMapId_( const char *, int, int, const char *, ... ); -void astIntraRegFor_( const char *, int, int, void (* tran)( AstMapping *, int, int, const double *[], int, int, double *[] ), void (* tran_wrap)( void (*)( AstMapping *, int, int, const double *[], int, int, double *[] ), AstMapping *, int, int, const double *[], int, int, double *[], int * ), unsigned int, const char *, const char *, const char *, int * ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static char *CleanName( const char *, const char *, int * ); -static int GetObjSize( AstObject *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetIntraFlag( AstIntraMap *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestIntraFlag( AstIntraMap *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearIntraFlag( AstIntraMap *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static void IntraReg( const char *, int, int, void (*)( AstMapping *, int, int, const double *[], int, int, double *[] ), void (*)( void (*)( AstMapping *, int, int, const double *[], int, int, double *[] ), AstMapping *, int, int, const double *[], int, int, double *[], int * ), unsigned int, const char *, const char *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetIntraFlag( AstIntraMap *, const char *, int * ); -static void TranWrap( void (*)( AstMapping *, int, int, const double *[], int, int, double *[] ), AstMapping *, int, int, const double *[], int, int, double *[], int * ); - -/* Member functions. */ -/* ================= */ -static char *CleanName( const char *name, const char *caller, int *status ) { -/* -* Name: -* CleanName - -* Purpose: -* Clean (and validate) a transformation function name. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* char *CleanName( const char *name, const char *caller, int *status ) - -* Class Membership: -* IntraMap member function. - -* Description: -* This function cleans a transformation function name by removing -* all white space. It returns a copy of the cleaned name held in -* dynamically allocated memory. If the name is entirely blank, an -* error is reported. - -* Parameters: -* name -* Pointer to a null-terminated string containing the name to be -* cleaned. -* caller -* Pointer to a null-terminated string containing the name of -* the calling function. This is only used to construct error -* messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a dynamically-allocated null-terminated string -* containing the cleaned name. A NULL pointer is returned if the -* name was entirely blank. - -* Notes: -* - The memory holding the returned string should be deallocated -* (using astFree) when no longer required. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - char *result; /* Pointer to result string */ - int i; /* Loop counter for input characters */ - int len; /* Length of name */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Determine the number of non-blank characters in the name supplied. */ - len = 0; - for ( i = 0; name[ i ]; i++ ) if ( !isspace( (int) name[ i ] ) ) len++; - -/* If the name is entirely blank, then report an error. */ - if ( !len ) { - astError( AST__ITFNI, "%s: Invalid blank transformation function name " - "given.", status, caller ); - -/* Otherwise, allocate memory to hold the cleaned name. */ - } else { - result = astMalloc( (size_t) ( len + 1 ) ); - -/* If OK, make a copy of the name with white space removed. */ - if ( astOK ) { - len = 0; - for ( i = 0; name[ i ]; i++ ) { - if ( !isspace( (int) name[ i ] ) ) result[ len++ ] = name[ i ]; - } - -/* Terminate the result string. */ - result[ len ] = '\0'; - } - } - -/* Return the result pointer. */ - return result; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for an IntraMap. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* IntraMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for an -* IntraMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the IntraMap. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstIntraMap *this; /* Pointer to the IntraMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the IntraMap structure. */ - this = (AstIntraMap *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* IntraFlag. */ -/* ---------- */ - if ( !strcmp( attrib, "intraflag" ) ) { - astClearIntraFlag( this ); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two IntraMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* IntraMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two IntraMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a IntraMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the IntraMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstIntraMap *that; - AstIntraMap *this; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two IntraMap structures. */ - this = (AstIntraMap *) this_object; - that = (AstIntraMap *) that_object; - -/* Check the second object is a IntraMap. We know the first is a - IntraMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAIntraMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two IntraMaps differ, it may still be possible - for them to be equivalent. First compare the IntraMaps if their Invert - flags are the same. In this case all the attributes of the two IntraMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - - if( this->ifun == that->ifun && - this->intraflag && that->intraflag && - !strcmp( this->intraflag, that->intraflag ) ) { - result = 1; - } - -/* If the Invert flags for the two IntraMaps differ, the attributes of the two - IntraMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a IntraMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* IntraMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied IntraMap, -* in bytes. - -* Parameters: -* this -* Pointer to the IntraMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstIntraMap *this; /* Pointer to IntraMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the IntraMap structure. */ - this = (AstIntraMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astTSizeOf( this->intraflag ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for an IntraMap. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* IntraMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a IntraMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the IntraMap. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the IntraMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the IntraMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstIntraMap *this; /* Pointer to the IntraMap structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the IntraMap structure. */ - this = (AstIntraMap *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* IntraFlag. */ -/* ---------- */ - if ( !strcmp( attrib, "intraflag" ) ) { - result = astGetIntraFlag( this ); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -void astInitIntraMapVtab_( AstIntraMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitIntraMapVtab - -* Purpose: -* Initialise a virtual function table for an IntraMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "intramap.h" -* void astInitIntraMapVtab( AstIntraMapVtab *vtab, const char *name ) - -* Class Membership: -* IntraMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the IntraMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAIntraMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->ClearIntraFlag = ClearIntraFlag; - vtab->GetIntraFlag = GetIntraFlag; - vtab->SetIntraFlag = SetIntraFlag; - vtab->TestIntraFlag = TestIntraFlag; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Store pointers to inherited methods that will be invoked explicitly - by this class. */ - parent_getnin = mapping->GetNin; - parent_getnout = mapping->GetNout; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "IntraMap", - "Map points using a private transformation function" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void IntraReg( const char *name, int nin, int nout, - void (* tran)( AstMapping *, int, int, const double *[], - int, int, double *[] ), - void (* tran_wrap)( void (*)( AstMapping *, int, int, - const double *[], int, int, - double *[] ), - AstMapping *, int, int, - const double *[], int, int, - double *[], int * ), - unsigned int flags, - const char *purpose, const char *author, - const char *contact, int *status ) { -/* -* Name: -* IntraReg - -* Purpose: -* Register a transformation function for use by an IntraMap. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* void IntraReg( const char *name, int nin, int nout, -* void (* tran)( AstMapping *, int, int, const double *[], -* int, int, double *[] ), -* void (* tran_wrap)( void (*)( AstMapping *, int, int, -* const double *[], int, int, -* double *[] ), -* AstMapping *, int, int, -* const double *[], int, int, -* double *[], int * ), -* unsigned int flags, -* const char *purpose, const char *author, -* const char *contact, int *status ) - -* Class Membership: -* IntraMap member function. - -* Description: -* This function registers a transformation function which will -* later be used by an IntraMap and associates it with a name. It -* also stores related information which will be required by the -* IntraMap. - -* Parameters: -* name -* Pointer to a null-terminated string containing the name to be -* used to identify the transformation function. This string is -* case sensitive. All white space is removed before use. -* nin -* The number of input coordinates per point (or AST__ANY if any -* number are allowed). -* nout -* The number of output coordinates per point (or AST__ANY if -* any number are allowed). -* tran -* Pointer to the transformation function to be registered. -* This may have any form of interface, which need not be known -* to the implementation of the IntraMap class. Instead, the -* method of invoking the transformation function should be -* encapsulated in the "tran_wrap" function (below). -* tran_wrap -* Pointer to a wrapper function appropriate to the transformation -* function (above). This wrapper function should have the same -* interface as astTranP (from the Mapping class), except that it takes -* a pointer to a function like "tran" as an additional first argument. -* The purpose of this wrapper is to invoke the transformation function -* via the pointer supplied, to pass it the necessary information -* derived from the remainder of its arguments, and then to return the -* results. -* flags -* This argument may be used to supply a set of flags which -* control the behaviour of any IntraMap which uses the -* registered transformation function. See the public interface -* for astIntraReg for details. -* purpose -* Pointer to a null-terminated string containing a short (one -* line) textual comment to describe the purpose of the -* transformation function. -* author -* Pointer to a null-terminated string containing the name of -* the author of the transformation function. -* contact -* Pointer to a null-terminated string containing contact -* details for the author of the function (e.g. an e-mail or WWW -* address). -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char *clname; /* Pointer to cleaned name string */ - int found; /* Transformation function found? */ - int ifun; /* Loop counter for function information */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* This function modifies the global static tran_data array, so we use a - mutex to ensure that only one thread can run this function at any one - time. */ - LOCK_MUTEX1; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Indicate that subsequent memory allocations may never be freed (other - than by any AST exit handler). */ - astBeginPM; - -/* Clean (and validate) the name supplied. */ - clname = CleanName( name, "astIntraReg", status ); - -/* If OK, also validate the numbers of input and output - coordinates. Report an error if necessary. */ - if ( astOK ) { - if ( ( nin < 0 ) && ( nin != AST__ANY ) ) { - astError( AST__BADNI, "astIntraReg(%s): Bad number of input " - "coordinates (%d).", status, clname, nin ); - astError( AST__BADNI, "This number should be zero or more (or " - "AST__ANY)." , status); - - } else if ( ( nout < 0 ) && ( nout != AST__ANY ) ) { - astError( AST__BADNO, "astIntraReg(%s): Bad number of output " - "coordinates (%d).", status, clname, nout ); - astError( AST__BADNO, "This number should be zero or more (or " - "AST__ANY)." , status); - } - } - -/* Search the array of transformation function data to see if a - function with the same name has already been registered. */ - if ( astOK ) { - found = 0; - for ( ifun = 0; ifun < tran_nfun; ifun++ ) { - if ( ( found = !strcmp( clname, tran_data[ ifun ].name ) ) ) break; - } - -/* If so, then check that the information supplied this time is - identical to that supplied before. If any discrepancy is found, - report an error. */ - if ( found ) { - if ( ( nin != tran_data[ ifun ].nin ) || - ( nout != tran_data[ ifun ].nout ) || - ( tran != tran_data[ ifun ].tran ) || - ( tran_wrap != tran_data[ ifun ].tran_wrap ) || - ( flags != tran_data[ ifun ].flags ) || - strcmp( purpose, tran_data[ ifun ].purpose ) || - strcmp( author, tran_data[ ifun ].author ) || - strcmp( contact, tran_data[ ifun ].contact ) ) { - astError( AST__MRITF, "astIntraReg: Invalid attempt to register " - "the transformation function name \"%s\" " - "multiple times.", status, clname ); - } - -/* If this is a new function, extend the array of transformation - function data to accommodate it. */ - } else { - - tran_data = astGrow( tran_data, tran_nfun + 1, sizeof( AstIntraMapTranData ) ); - -/* Store the information supplied. */ - if ( astOK ) { - tran_data[ tran_nfun ].name = clname; - tran_data[ tran_nfun ].nin = nin; - tran_data[ tran_nfun ].nout = nout; - tran_data[ tran_nfun ].tran = tran; - tran_data[ tran_nfun ].tran_wrap = tran_wrap; - tran_data[ tran_nfun ].flags = flags; - tran_data[ tran_nfun ].purpose = - astStore( NULL, purpose, strlen( purpose ) + (size_t) 1 ); - tran_data[ tran_nfun ].author = - astStore( NULL, author, strlen( author ) + (size_t) 1 ); - tran_data[ tran_nfun ].contact = - astStore( NULL, contact, strlen( contact ) + (size_t) 1 ); - -/* If successful, increment the count of transformation functions - registered. */ - if ( astOK ) { - tran_nfun++; - -/* If an error occurred, free any memory that was allocated. */ - } else { - tran_data[ tran_nfun ].name = NULL; - tran_data[ tran_nfun ].purpose = - astFree( tran_data[ tran_nfun ].purpose ); - tran_data[ tran_nfun ].author = - astFree( tran_data[ tran_nfun ].author ); - tran_data[ tran_nfun ].contact = - astFree( tran_data[ tran_nfun ].contact ); - } - } - } - } - -/* If an error occurred, free the memory holding the cleaned function - name. */ - if ( !astOK ) clname = astFree( clname ); - -/* Mark the end of the section in which memory allocations may never be - freed (other than by any AST exit handler). */ - astEndPM; - -/* Unlock the mutex that ensures that only one thread can run this function - at any one time. */ - UNLOCK_MUTEX1; - -} - -void astIntraReg_( const char *name, int nin, int nout, - void (* tran)( AstMapping *, int, int, const double *[], - int, int, double *[] ), - unsigned int flags, const char *purpose, const char *author, - const char *contact, int *status ) { -/* -*++ -* Name: -c astIntraReg -f AST_INTRAREG - -* Purpose: -c Register a transformation function for use by an IntraMap. -f Register a transformation routine for use by an IntraMap. - -* Type: -* Public function. - -* Synopsis: -c #include "intramap.h" -c astIntraReg( const char *name, int nin, int nout, -c void (* tran)( AstMapping *, int, int, const double *[], -c int, int, double *[] ), -c unsigned int flags, const char *purpose, const char *author, -c const char *contact ) -f CALL AST_INTRAREG( NAME, NIN, NOUT, TRAN, FLAGS, PURPOSE, AUTHOR, -f CONTACT, STATUS ) - -* Class Membership: -* IntraMap member function. - -* Description: -c This function registers a privately-defined coordinate -c transformation function written in C so that it may be used to -c create an IntraMap. An IntraMap is a specialised form of Mapping -c which encapsulates the C function so that it may be used like -c any other AST Mapping. This allows you to create Mappings that -c perform any conceivable coordinate transformation. -f This function registers a privately-defined coordinate -f transformation routine written in Fortran so that it may be used -f to create an IntraMap. An IntraMap is a specialised form of -f Mapping which encapsulates the Fortran routine so that it may be -f used like any other AST Mapping. This allows you to create -f Mappings that perform any conceivable coordinate transformation. -* -c Registration of relevant transformation functions is required -c before using the astIntraMap constructor function to create an -c IntraMap or reading an external representation of an IntraMap -c from a Channel. -f Registration of relevant transformation routines is required -f before using the AST_INTRAMAP constructor function to create an -f IntraMap or reading an external representation of an IntraMap -f from a Channel. - -* Parameters: -c name -f NAME = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing a unique name -c to be associated with the transformation function in order to -c identify it. This name is case sensitive. All white space -c will be removed before use. -f A character string containing a unique name to be associated -f with the transformation routine in order to identify it. This -f name is case sensitive. All white space will be removed -f before use. -c nin -f NIN = INTEGER (Given) -c The number of input coordinates accepted by the -c transformation function (i.e. the number of dimensions of the -c space in which the input points reside). A value of AST__ANY -c may be given if the function is able to accommodate a -c variable number of input coordinates. -f The number of input coordinates accepted by the -f transformation routine (i.e. the number of dimensions of the -f space in which the input points reside). A value of AST__ANY -f may be given if the routine is able to accommodate a variable -f number of input coordinates. -c nout -f NOUT = INTEGER (Given) -c The number of output coordinates produced by the -c transformation function (i.e. the number of dimensions of the -c space in which the output points reside). A value of AST__ANY -c may be given if the function is able to produce a variable -c number of output coordinates. -f The number of output coordinates produced by the -f transformation routine (i.e. the number of dimensions of the -f space in which the output points reside). A value of AST__ANY -f may be given if the routine is able to produce a variable -f number of output coordinates. -c tran -f TRAN = SUBROUTINE (Given) -c Pointer to the transformation function to be registered. -c This function should perform whatever coordinate -c transformations are required and should have an interface -c like astTranP (q.v.). -f The transformation routine to be registered. This routine -f should perform whatever coordinate transformations are -f required and should have an interface like AST_TRANN (q.v.). -f -f This transformation routine must also appear in an EXTERNAL -f statement in the routine which calls AST_INTRAREG. -c flags -f FLAGS = INTEGER (Given) -c This value may be used to supply a set of flags which -c describe the transformation function and which may affect the -c behaviour of any IntraMap which uses it. Often, a value of -c zero will be given here, but you may also supply the bitwise -c OR of a set of flags as described in the "Transformation -c Flags" section (below). -f This value may be used to supply a set of flags which -f describe the transformation routine and which may affect the -f behaviour of any IntraMap which uses it. Often, a value of -f zero will be given here, but you may also supply the sum of a -f set of flags as described in the "Transformation Flags" -f section (below). -c purpose -f PURPOSE = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing a short (one -c line) textual comment to describe the purpose of the -c transformation function. -f A character string containing a short (one line) textual -f comment to describe the purpose of the transformation -f routine. -c author -f AUTHOR = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing the name of -c the author of the transformation function. -f A character string containing the name of the author of the -f transformation routine. -c contact -f CONTACT = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing contact -c details for the author of the transformation function -c (e.g. an e-mail or WWW address). If any IntraMap which uses -c this transformation function is exported as part of a dataset -c to an external user who does not have access to the function, -c then these contact details should allow them to obtain the -c necessary code. -f A character string containing contact details for the author -f of the transformation routine (e.g. an e-mail or WWW -f address). If any IntraMap which uses this transformation -f routine is exported as part of a dataset to an external user -f who does not have access to the routine, then these contact -f details should allow them to obtain the necessary code. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - Beware that an external representation of an IntraMap (created -c by writing it to a Channel) will not include the coordinate -c transformation function which it uses, so will only refer to the -c function by its name (as assigned using astIntraReg). -c Consequently, the external representation cannot be utilised by -c another program unless that program has also registered the same -c transformation function with the same name using an identical -c invocation of astIntraReg. If no such registration has been -c performed, then attempting to read the external representation -c will result in an error. -f - Beware that an external representation of an IntraMap (created -f by writing it to a Channel) will not include the coordinate -f transformation routine which it uses, so will only refer to the -f routine by its name (as assigned using AST_INTRAREG). -f Consequently, the external representation cannot be utilised by -f another program unless that program has also registered the same -f transformation routine with the same name using an identical -f invocation of AST_INTRAREG. If no such registration has been -f performed, then attempting to read the external representation -f will result in an error. -c - You may use astIntraReg to register a transformation function -c with the same name more than once, but only if the arguments -c supplied are identical on each occasion (i.e there is no way of -c changing things once a function has been successfully registered -c under a given name, and attempting to do so will result in an -c error). This feature simply allows registration to be performed -c independently, but consistently, at several places within your -c program, without having to check whether it has already been -c done. -f - You may use AST_INTRAREG to register a transformation routine -f with the same name more than once, but only if the arguments -f supplied are identical on each occasion (i.e there is no way of -f changing things once a routine has been successfully registered -f under a given name, and attempting to do so will result in an -f error). This feature simply allows registration to be performed -f independently, but consistently, at several places within your -f program, without having to check whether it has already been -f done. -c - If an error occurs in the transformation function, this may be -c indicated by setting the AST error status to an error value -c (using astSetStatus) before it returns. This will immediately -c terminate the current AST operation. The error value AST__ITFER -c is available for this purpose, but other values may also be used -c (e.g. if you wish to distinguish different types of error). -f - If an error occurs in the transformation routine, this may be -f indicated by setting its STATUS argument to an error value -f before it returns. This will immediately terminate the current -f AST operation. The error value AST__ITFER is available for this -f purpose, but other values may also be used (e.g. if you wish to -f distinguish different types of error). The AST__ITFER error -f value is defined in the AST_ERR include file. - -* Transformation Flags: -c The following flags are defined in the ``ast.h'' header file and -c allow you to provide further information about the nature of the -c transformation function. Having selected the set of flags which -c apply, you should supply the bitwise OR of their values as the -c ``flags'' argument to astIntraReg. -f The following flags are defined in the AST_PAR include file and -f allow you to provide further information about the nature of the -f transformation routine. Having selected the set of flags which -f apply, you should supply the sum of their values as the FLAGS -f argument to AST_INTRAREG. - -c - AST__NOFWD: If this flag is set, it indicates that the -c transformation function does not implement a forward coordinate -c transformation. In this case, any IntraMap which uses it will -c have a TranForward attribute value of zero and the -c transformation function itself will not be invoked with its -c ``forward'' argument set to a non-zero value. By default, it is -c assumed that a forward transformation is provided. -f - AST__NOFWD: If this flag is set, it indicates that the -f transformation routine does not implement a forward coordinate -f transformation. In this case, any IntraMap which uses it will -f have a TranForward attribute value of zero and the -f transformation routine itself will not be called with its -f FORWARD argument set to .TRUE.. By default, it is assumed that a -f forward transformation is provided. -c - AST__NOINV: If this flag is set, it indicates that the -c transformation function does not implement an inverse coordinate -c transformation. In this case, any IntraMap which uses it will -c have a TranInverse attribute value of zero and the -c transformation function itself will not be invoked with its -c ``forward'' argument set to zero. By default, it is assumed -c that an inverse transformation is provided. -f - AST__NOINV: If this flag is set, it indicates that the -f transformation routine does not implement an inverse coordinate -f transformation. In this case, any IntraMap which uses it will -f have a TranInverse attribute value of zero and the -f transformation routine itself will not be called with its -f FORWARD argument set to .FALSE.. By default, it is assumed that -f an inverse transformation is provided. -c - AST__SIMPFI: You may set this flag if applying the -c transformation function's forward coordinate transformation, -c followed immediately by the matching inverse transformation, -c should always restore the original set of coordinates. It -c indicates that AST may replace such a sequence of operations by -c an identity Mapping (a UnitMap) if it is encountered while -c simplifying a compound Mapping (e.g. using astSimplify). It is -c not necessary that both transformations have actually been -c implemented. -f - AST__SIMPFI: You may set this flag if applying the -f transformation routine's forward coordinate transformation, -f followed immediately by the matching inverse transformation, -f should always restore the original set of coordinates. It -f indicates that AST may replace such a sequence of operations by -f an identity Mapping (a UnitMap) if it is encountered while -f simplifying a compound Mapping (e.g. using AST_SIMPLIFY). It is -f not necessary that both transformations have actually been -f implemented. -c - AST__SIMPIF: You may set this flag if applying the -c transformation function's inverse coordinate transformation, -c followed immediately by the matching forward transformation, -c should always restore the original set of coordinates. It -c indicates that AST may replace such a sequence of operations by -c an identity Mapping (a UnitMap) if it is encountered while -c simplifying a compound Mapping (e.g. using astSimplify). It is -c not necessary that both transformations have actually been -c implemented. -f - AST__SIMPIF: You may set this flag if applying the -f transformation routine's inverse coordinate transformation, -f followed immediately by the matching forward transformation, -f should always restore the original set of coordinates. It -f indicates that AST may replace such a sequence of operations by -f an identity Mapping (a UnitMap) if it is encountered while -f simplifying a compound Mapping (e.g. using AST_SIMPLIFY). It is -f not necessary that both transformations have actually been -f implemented. -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Register the transformation function together with the appropriate - wrapper function for the C language. */ - IntraReg( name, nin, nout, tran, TranWrap, flags, purpose, author, - contact, status ); -} - -void astIntraRegFor_( const char *name, int nin, int nout, - void (* tran)( AstMapping *, int, int, const double *[], - int, int, double *[] ), - void (* tran_wrap)( void (*)( AstMapping *, int, int, - const double *[], int, int, - double *[] ), - AstMapping *, int, int, - const double *[], int, int, - double *[], int * ), - unsigned int flags, const char *purpose, - const char *author, const char *contact, int *status ) { -/* -*+ -* Name: -* astIntraRegFor - -* Purpose: -* Register a foreign language transformation function for an IntraMap. - -* Type: -* Public function. - -* Synopsis: -* #include "intramap.h" -* void astIntraRegFor( const char *name, int nin, int nout, -* void (* tran)( AstMapping *, int, int, -* const double *[], int, int, -* double *[] ), -* void (* tran_wrap)( void (*)( AstMapping *, int, -* int, const double *[], -* int, int, -* double *[] ), -* AstMapping *, int, int, -* const double *[], int, int, -* double *[], int * ), -* unsigned int flags, const char *purpose, -* const char *author, const char *contact ) - -* Class Membership: -* IntraMap member function. - -* Description: -* This function registers a transformation function provided by a -* foreign language interface which will later be used by an -* IntraMap, and associates it with a name. It also stores related -* information which will be required by the IntraMap. - -* Parameters: -* name -* Pointer to a null-terminated string containing the name to be -* used to identify the transformation function. This string is -* case sensitive. All white space is removed before use. -* nin -* The number of input coordinates per point (or AST__ANY if any -* number are allowed). -* nout -* The number of output coordinates per point (or AST__ANY if -* any number are allowed). -* tran -* Pointer to the foreign language transformation function to be -* registered. This may have any form of interface, which need -* not be known to the implementation of the IntraMap -* class. Instead, the method of invoking the transformation -* function should be encapsulated in the "tran_wrap" function -* (below). -* tran_wrap -* Pointer to a wrapper function appropriate to the foreign -* language interface. This wrapper function should have the -* same interface as astTranP (from the Mapping class), except -* that it takes a pointer to a function like "tran" as an additional -* first argument. The purpose of this wrapper is to invoke the -* transformation function via the pointer supplied, to pass it the -* necessary information derived from the remainder of its arguments, -* and then to return the results. -* flags -* This argument may be used to supply a set of flags which -* control the behaviour of any IntraMap which uses the -* registered transformation function. See the description of -* astIntraReg for details. -* purpose -* Pointer to a null-terminated string containing a short (one -* line) textual comment to describe the purpose of the -* transformation function. -* author -* Pointer to a null-terminated string containing the name of -* the author of the transformation function. -* contact -* Pointer to a null-terminated string containing contact -* details for the author of the transformation function -* (e.g. an e-mail address or URL). If any IntraMap using this -* transformation function is exported as part of a dataset to -* an external user who does not have access to the function, -* then these contact details should allow them to obtain the -* necessary code. - -* Notes: -* - This function is only available through the public interface -* to the IntraMap class (not the protected interface) and is -* intended solely for use in implementing foreign language -* interfaces to this class. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Register the transformation function together with the appropriate - wrapper function for the foreign language interface. */ - IntraReg( name, nin, nout, tran, tran_wrap, flags, purpose, author, - contact, status ); -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing an IntraMap. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* IntraMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated IntraMap in the sequence with its -* neighbours, so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated IntraMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated IntraMap which is to be merged with -* its neighbours. This should be a cloned copy of the IntraMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* IntraMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated IntraMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstIntraMap *intramap1; /* Pointer to first IntraMap */ - AstIntraMap *intramap2; /* Pointer to second IntraMap */ - AstMapping *new; /* Pointer to replacement Mapping */ - const char *class; /* Pointer to Mapping class string */ - int imap1; /* Index of first IntraMap */ - int imap2; /* Index of second IntraMap */ - int imap; /* Loop counter for Mappings */ - int invert1; /* Invert flag value (1st IntraMap) */ - int invert2; /* Invert flag value (2nd IntraMap) */ - int nin1; /* No. input coordinates (1st IntraMap) */ - int nout2; /* No. output coordinates (2nd IntraMap) */ - int result; /* Result value to return */ - int simpler; /* Mappings simplified? */ - -/* Initialise the returned result. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Further initialisation. */ - new = NULL; - simpler = 0; - nin1 = -1; - -/* We will only handle the case of IntraMaps in series and will - consider merging the nominated IntraMap with the Mapping which - follows it. Check that there is such a Mapping. */ - if ( series && ( ( where + 1 ) < *nmap ) ) { - -/* Obtain the indices of the two potential IntraMaps to be merged and - a pointer to the first one. */ - imap1 = where; - imap2 = where + 1; - intramap1 = (AstIntraMap *) ( *map_list )[ imap1 ]; - -/* Obtain the Class string of the second Mapping and determine if it - is an IntraMap. */ - class = astGetClass( ( *map_list )[ imap2 ] ); - if ( astOK && !strcmp( class, "IntraMap" ) ) { - -/* Obtain a pointer to the second IntraMap. */ - intramap2 = (AstIntraMap *) ( *map_list )[ imap2 ]; - -/* Check that the two IntraMaps use the same transformation function - and have the same IntraFlag string (if set). */ - if ( ( intramap1->ifun == intramap2->ifun ) && - !strcmp( intramap1->intraflag ? intramap1->intraflag : "", - intramap2->intraflag ? intramap2->intraflag : "" ) ) { - -/* Determine the number of input coordinates that the first IntraMap - would have if its Invert attribute were set to the value of the - associated invert flag. Take account of the current Invert - attribute in obtaining this value. */ - invert1 = ( *invert_list )[ imap1 ]; - if ( astGetInvert( intramap1 ) ) { - nin1 = invert1 ? astGetNin( intramap1 ) : - astGetNout( intramap1 ); - } else { - nin1 = invert1 ? astGetNout( intramap1 ) : - astGetNin( intramap1 ); - } - -/* Similarly, determine the number of output coordinates that the - second IntraMap would have. */ - invert2 = ( *invert_list )[ imap2 ]; - if ( astGetInvert( intramap2 ) ) { - nout2 = invert2 ? astGetNout( intramap2 ) : - astGetNin( intramap2 ); - } else { - nout2 = invert2 ? astGetNin( intramap2 ) : - astGetNout( intramap2 ); - } - -/* Check that the effect of applying the two IntraMaps will be to - preserve the number of coordinates. */ - if ( astOK && ( nin1 == nout2 ) ) { - -/* If so, check if the first transformation function is applied in the - forward direction and the second in the inverse direction. If so, - note if this configuration can be simplified. */ - if ( !invert1 && invert2 ) { - simpler = tran_data[ intramap1->ifun ].flags & AST__SIMPFI; - -/* Similarly, if the first transformation function is applied in the - inverse direction and the second in the forward direction, then - note if this configuration can be simplified. */ - } else if ( invert1 && !invert2 ) { - simpler = tran_data[ intramap1->ifun ].flags & AST__SIMPIF; - } - } - } - } - -/* If the two IntraMaps can be simplified, create a UnitMap to replace - them. */ - if ( simpler ) { - new = (AstMapping *) astUnitMap( nin1, "", status ); - -/* Annul the pointers to the IntraMaps. */ - if ( astOK ) { - ( *map_list )[ imap1 ] = astAnnul( ( *map_list )[ imap1 ] ); - ( *map_list )[ imap2 ] = astAnnul( ( *map_list )[ imap2 ] ); - -/* Insert the pointer to the replacement Mapping and initialise its - invert flag. */ - ( *map_list )[ imap1 ] = new; - ( *invert_list )[ imap1 ] = 0; - -/* Loop to close the resulting gap by moving subsequent elements down - in the arrays. */ - for ( imap = imap2 + 1; imap < *nmap; imap++ ) { - ( *map_list )[ imap - 1 ] = ( *map_list )[ imap ]; - ( *invert_list )[ imap - 1 ] = ( *invert_list )[ imap ]; - } - -/* Clear the vacated elements at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = imap1; - } - } - } - -/* If an error occurred, clear the returned result. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for an IntraMap. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* IntraMap member function (over-rides the astSetAttrib method inherited -* from the Mapping class). - -* Description: -* This function assigns an attribute value for a IntraMap, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the IntraMap. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Vaiables: */ - AstIntraMap *this; /* Pointer to the IntraMap structure */ - int intraflag; /* Offset of IntraFlag value in string */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the IntraMap structure. */ - this = (AstIntraMap *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* IntraFlag. */ -/* ---------- */ - if ( nc = 0, - ( 0 == astSscanf( setting, "intraflag=%n%*[^\n]%n", &intraflag, &nc ) ) - && ( nc >= len ) ) { - astSetIntraFlag( this, setting + intraflag ); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for an IntraMap. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* IntraMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a IntraMap's attributes. - -* Parameters: -* this -* Pointer to the IntraMap. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstIntraMap *this; /* Pointer to the IntraMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the IntraMap structure. */ - this = (AstIntraMap *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* IntraFlag. */ -/* ---------- */ - if ( !strcmp( attrib, "intraflag" ) ) { - result = astTestIntraFlag( this ); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply an IntraMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* IntraMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a IntraMap and a set of points encapsulated -* in a PointSet and transforms the points using the transformation -* function associated with the IntraMap. - -* Parameters: -* this -* Pointer to the IntraMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate -* transformation should be applied, while a zero value requests -* the inverse transformation. -* out -* Pointer to a PointSet which will hold the transformed -* (output) coordinate values. A NULL value may also be given, -* in which case a new PointSet will be created by this -* function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -* - The number of coordinate values per point in the input -* PointSet must match the number of coordinates for the IntraMap -* being applied. -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and coordinate values per point to -* accommodate the result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstIntraMap *this; /* Pointer to IntraMap structure */ - AstMapping *id; /* Public ID for the IntraMap supplied */ - AstPointSet *result; /* Pointer to output PointSet */ - const double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - int ncoord_in; /* Number of coordinates per input point */ - int ncoord_out; /* Number of coordinates per output point */ - int npoint; /* Number of points */ - int ok; /* AST status OK? */ - int status_value; /* AST status value */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_mapping); - -/* Obtain a pointer to the IntraMap structure. */ - this = (AstIntraMap *) this_mapping; - -/* Apply the parent mapping using the stored pointer to the Transform - member function inherited from the parent Mapping class. This - function validates all arguments and generates an output PointSet - if necessary, but does not actually transform any coordinate - values. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the - input and output PointSets and obtain pointers for accessing the - input and output coordinate values. */ - npoint = astGetNpoint( in ); - ncoord_in = astGetNcoord( in ); - ncoord_out = astGetNcoord( result ); - ptr_in = (const double **) astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse transformation, - according to the direction specified and whether the Mapping has - been inverted. */ - if ( astGetInvert( this ) ) forward = !forward; - -/* Obtain a public (external) ID for the IntraMap. This will be - required (instead of a true C pointer) by the transformation function, - since it is user-written. Clone the IntraMap pointer so that the call - to astAnnulID later on does not annul the IntraMap pointer. */ - id = (AstMapping *) astMakeId( astClone( this ) ); - -/* Locate the transformation function data associated with the - IntraMap and use the wrapper function to invoke the transformation - function itself. */ - if ( ( ok = astOK ) ) { - LOCK_MUTEX2; - ( *tran_data[ this->ifun ].tran_wrap )( tran_data[ this->ifun ].tran, - id, npoint, ncoord_in, ptr_in, - forward, ncoord_out, ptr_out, - status ); - UNLOCK_MUTEX2; - -/* If an error occurred, report a contextual error message. To ensure - that the location of the error appears in the message, we first clear - the global status (which makes the error system think this is the - first report). */ - if ( !( ok = astOK ) ) { - status_value = astStatus; - astClearStatus; - astError( status_value, - "astTransform(%s): Error signalled by \"%s\" " - "transformation function.", status, - astGetClass( this ), tran_data[ this->ifun ].name ); - } - } - -/* Annul the external identifier. */ - id = astMakeId( astAnnulId( id ) ); - -/* If an error occurred here, but earlier steps were successful, then - something has happened to the external ID, so report a contextual - error message. */ - if ( !astOK && ok ) { - astError( astStatus, - "astTransform(%s): %s pointer corrupted by \"%s\" " - "transformation function.", status, - astGetClass( this ), astGetClass( this ), - tran_data[ this->ifun ].name ); - } - -/* If an error occurred, clear the returned pointer. If a new output - PointSet has been created, then delete it. */ - if ( !astOK ) { - result = ( result == out ) ? NULL : astDelete( result ); - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -static void TranWrap( void (* tran)( AstMapping *, int, int, const double *[], - int, int, double *[] ), - AstMapping *this, int npoint, int ncoord_in, - const double *ptr_in[], int forward, int ncoord_out, - double *ptr_out[], int *status ) { -/* -* Name: -* TranWrap - -* Purpose: -* Wrapper function to invoke a C transformation function. - -* Type: -* Private function. - -* Synopsis: -* void TranWrap( void (* tran)( AstMapping *, int, int, const double *[], -* int, int, double *[] ), -* AstMapping *this, int npoint, int ncoord_in, -* const double *ptr_in[], int forward, int ncoord_out, -* double *ptr_out[], int *status ) - -* Class Membership: -* IntraMap member function. - -* Description: -* This function invokes a C implementation of a transformation -* function (which resembles the astTranP function from the Mapping -* class). -* -* This wrapper is essentially a dummy function for the C language. -* It may be replaced by alternative versions for foreign language -* interfaces, thus allowing transformation functions supplied by -* those languages to be invoked without knowledge of their -* interfaces. - -* Parameters: -* tran -* Pointer to the transformation function to be invoked. This -* should resemble astTranP (but with the first argument -* omitted). -* this -* An external Mapping ID associated with the internal (true C) pointer -* for the IntraMap whose transformation is being evaluated. -* npoint -* The number of points to be transformed. -* ncoord_in -* The number of coordinates being supplied for each input point -* (i.e. the number of dimensions of the space in which the -* input points reside). -* ptr_in -* An array of pointers to double, with "ncoord_in" -* elements. Element "ptr_in[coord]" should point at the first -* element of an array of double (with "npoint" elements) which -* contain the values of coordinate number "coord" for each -* input (untransformed) point. The value of coordinate number -* "coord" for input point number "point" is therefore given by -* "ptr_in[coord][point]". -* forward -* A non-zero value indicates that the forward coordinate -* transformation is to be applied, while a zero value indicates -* that the inverse transformation should be used. -* ncoord_out -* The number of coordinates being generated for each output -* point (i.e. the number of dimensions of the space in which -* the output points reside). This need not be the same as -* "ncoord_in". -* ptr_out -* An array of pointers to double, with "ncoord_out" -* elements. Element "ptr_out[coord]" should point at the first -* element of an array of double (with "npoint" elements) into -* which the values of coordinate number "coord" for each output -* (transformed) point will be written. The value of coordinate -* number "coord" for output point number "point" will therefore -* be found in "ptr_out[coord][point]". -* status -* Pointer to the inherited status value. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the transformation function. */ - ( *tran )( this, npoint, ncoord_in, ptr_in, forward, ncoord_out, ptr_out ); -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* IntraFlag - -* Purpose: -* IntraMap identification string. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -c This attribute allows an IntraMap to be flagged so that it is -c distinguishable from other IntraMaps. The transformation function -c associated with the IntraMap may then enquire the value of this -c attribute and adapt the transformation it provides according to the -c particular IntraMap involved. -f This attribute allows an IntraMap to be flagged so that it is -f distinguishable from other IntraMaps. The transformation routine -f associated with the IntraMap may then enquire the value of this -f attribute and adapt the transformation it provides according to the -f particular IntraMap involved. -* -c Although this is a string attribute, it may often be useful to store -c numerical values here, encoded as a character string, and to use these -c as data within the transformation function. Note, however, that this -c mechanism is not suitable for transferring large amounts of data (more -c than about 1000 characters) to an IntraMap. For that purpose, global -c variables are recommended, although the IntraFlag value can be used to -c supplement this approach. The default IntraFlag value is an empty -c string. -f Although this is a string attribute, it may often be useful to store -f numerical values here, encoded as a character string, and to use these -f as data within the transformation routine. Note, however, that this -f mechanism is not suitable for transferring large amounts of data (more -f than about 1000 characters) to an IntraMap. For that purpose, global -f variables are recommended, although the IntraFlag value can be used to -f supplement this approach. The default IntraFlag value is an empty -f string. - -* Applicability: -* IntraMap -* All IntraMaps have this attribute. - -* Notes: -c - A pair of IntraMaps whose transformations may potentially cancel -c cannot be simplified to produce a UnitMap (e.g. using astSimplify) -c unless they have the same IntraFlag values. The test for equality is -c case-sensitive. -f - A pair of IntraMaps whose transformations may potentially cancel -f cannot be simplified to produce a UnitMap (e.g. using AST_SIMPLIFY) -f unless they have the same IntraFlag values. The test for equality is -f case-sensitive. -*att-- -*/ - -/* Clear the IntraFlag value by freeing the allocated memory and - assigning a NULL pointer. */ -astMAKE_CLEAR(IntraMap,IntraFlag,intraflag,astFree( this->intraflag )) - -/* Return a pointer to the IntraFlag value. */ -astMAKE_GET(IntraMap,IntraFlag,const char *,NULL,this->intraflag) - -/* Set a IntraFlag value by freeing any previously allocated memory, - allocating new memory, storing the string and saving the pointer to - the copy. */ -astMAKE_SET(IntraMap,IntraFlag,const char *,intraflag,astStore( - this->intraflag, value, - strlen( value ) + - (size_t) 1 )) - -/* The IntraFlag value is set if the pointer to it is not NULL. */ -astMAKE_TEST(IntraMap,IntraFlag,( this->intraflag != NULL )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for IntraMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for IntraMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstIntraMap *in; /* Pointer to input IntraMap */ - AstIntraMap *out; /* Pointer to output IntraMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output IntraMaps. */ - in = (AstIntraMap *) objin; - out = (AstIntraMap *) objout; - -/* For safety, first clear any references to the input memory from - the output IntraMap. */ - out->intraflag = NULL; - -/* If necessary, allocate memory in the output IntraMap and store a - copy of the input IntraFlag string. */ - if ( in->intraflag ) out->intraflag = astStore( NULL, in->intraflag, - strlen( in->intraflag ) + - (size_t) 1 ); - -/* If an error occurred, free any allocated memory. */ - if ( !astOK ) { - out->intraflag = astFree( out->intraflag ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for IntraMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for IntraMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstIntraMap *this; /* Pointer to IntraMap */ - -/* Obtain a pointer to the IntraMap structure. */ - this = (AstIntraMap *) obj; - -/* Free the memory used for the IntraFlag string if necessary. */ - this->intraflag = astFree( this->intraflag ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for IntraMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the IntraMap class to an output Channel. - -* Parameters: -* this -* Pointer to the IntraMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstIntraMap *this; /* Pointer to the IntraMap structure */ - const char *sval; /* Pointer to string value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the IntraMap structure. */ - this = (AstIntraMap *) this_object; - -/* Write out values representing the instance variables for the - IntraMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* Transformation function name. */ -/* ----------------------------- */ - astWriteString( channel, "Fname", 1, 1, tran_data[ this->ifun ].name, - "Name of transformation function" ); - -/* IntraFlag string. */ -/* ----------------- */ - set = TestIntraFlag( this, status ); - sval = set ? GetIntraFlag( this, status ) : astGetIntraFlag( this ); - astWriteString( channel, "Iflag", set, 0, sval, - "IntraMap identification string" ); - -/* Purpose string. */ -/* --------------- */ - astWriteString( channel, "Purp", 1, 1, tran_data[ this->ifun ].purpose, - "Purpose of function" ); - -/* Author's name. */ -/* -------------- */ - astWriteString( channel, "Auth", 1, 1, tran_data[ this->ifun ].author, - "Author's name" ); - -/* Contact details. */ -/* ---------------- */ - astWriteString( channel, "Cntact", 1, 1, tran_data[ this->ifun ].contact, - "Contact address" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAIntraMap and astCheckIntraMap functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(IntraMap,Mapping) -astMAKE_CHECK(IntraMap) - -AstIntraMap *astIntraMap_( const char *name, int nin, int nout, - const char *options, int *status, ...) { -/* -*++ -* Name: -c astIntraMap -f AST_INTRAMAP - -* Purpose: -* Create an IntraMap. - -* Type: -* Public function. - -* Synopsis: -c #include "intramap.h" -c AstIntraMap *astIntraMap( const char *name, int nin, int nout, -c const char *options, ... ) -f RESULT = AST_INTRAMAP( NAME, NIN, NOUT, OPTIONS, STATUS ) - -* Class Membership: -* IntraMap constructor. - -* Description: -* This function creates a new IntraMap and optionally initialises -* its attributes. -* -c An IntraMap is a specialised form of Mapping which encapsulates -c a privately-defined coordinate transformation function -c (e.g. written in C) so that it may be used like any other AST -c Mapping. This allows you to create Mappings that perform any -c conceivable coordinate transformation. -f An IntraMap is a specialised form of Mapping which encapsulates -f a privately-defined coordinate transformation routine -f (e.g. written in Fortran) so that it may be used like any other -f AST Mapping. This allows you to create Mappings that perform any -f conceivable coordinate transformation. -* -* However, an IntraMap is intended for use within a single program -* or a private suite of software, where all programs have access -* to the same coordinate transformation functions (i.e. can be -* linked against them). IntraMaps should not normally be stored in -* datasets which may be exported for processing by other software, -* since that software will not have the necessary transformation -* functions available, resulting in an error. -* -c You must register any coordinate transformation functions to be -c used using astIntraReg before creating an IntraMap. -f You must register any coordinate transformation functions to be -f used using AST_INTRAREG before creating an IntraMap. - -* Parameters: -c name -f NAME = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing the name of -c the transformation function to use (which should previously -c have been registered using astIntraReg). This name is case -c sensitive. All white space will be removed before use. -f A character string containing the name of the transformation -f routine to use (which should previously have been registered -f using AST_INTRAREG). This name is case sensitive. All white -f space will be removed before use. -c nin -f NIN = INTEGER (Given) -c The number of input coordinates. This must be compatible with -c the number of input coordinates accepted by the -c transformation function (as specified when this function was -c registered using astIntraReg). -f The number of input coordinates. This must be compatible with -f the number of input coordinates accepted by the -f transformation routine (as specified when this routine was -f registered using AST_INTRAREG). -c nout -f NOUT = INTEGER (Given) -c The number of output coordinates. This must be compatible -c with the number of output coordinates produced by the -c transformation function (as specified when this function was -c registered using astIntraReg). -f The number of output coordinates. This must be compatible -f with the number of output coordinates produced by the -f transformation routine (as specified when this routine was -f registered using AST_INTRAREG). -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new IntraMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new IntraMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astIntraMap() -f AST_INTRAMAP = INTEGER -* A pointer to the new IntraMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstIntraMap *new; /* Pointer to new IntraMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the IntraMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitIntraMap( NULL, sizeof( AstIntraMap ), !class_init, - &class_vtab, "IntraMap", name, nin, nout ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - IntraMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new IntraMap. */ - return new; -} - -AstIntraMap *astIntraMapId_( const char *name, int nin, int nout, - const char *options, ... ) { -/* -* Name: -* astIntraMapId_ - -* Purpose: -* Create an IntraMap. - -* Type: -* Private function. - -* Synopsis: -* #include "intramap.h" -* AstIntraMap *astIntraMapId_( const char *name, int nin, int nout, -* const char *options, ... ) - -* Class Membership: -* IntraMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astIntraMap constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astIntraMap_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* -* The variable argument list also prevents this function from -* invoking astIntraMap_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. - -* Parameters: -* As for astIntraMap_. - -* Returned Value: -* The ID value associated with the new IntraMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstIntraMap *new; /* Pointer to new IntraMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the IntraMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitIntraMap( NULL, sizeof( AstIntraMap ), !class_init, - &class_vtab, "IntraMap", name, nin, nout ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - IntraMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new IntraMap. */ - return astMakeId( new ); -} - - -AstIntraMap *astInitIntraMap_( void *mem, size_t size, int init, - AstIntraMapVtab *vtab, const char *name, - const char *fname, int nin, int nout, int *status ) { -/* -*+ -* Name: -* astInitIntraMap - -* Purpose: -* Initialise an IntraMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "intramap.h" -* AstIntraMap *astInitIntraMap( void *mem, size_t size, int init, -* AstIntraMapVtab *vtab, const char *name, -* const char *fname, int nin, int nout ) - -* Class Membership: -* IntraMap initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new IntraMap object. It allocates memory (if -* necessary) to accommodate the IntraMap plus any additional data -* associated with the derived class. It then initialises a -* IntraMap structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual -* function table for a IntraMap at the start of the memory passed -* via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the IntraMap is to be -* initialised. This must be of sufficient size to accommodate -* the IntraMap data (sizeof(IntraMap)) plus any data used by -* the derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the IntraMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the IntraMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* init -* A logical flag indicating if the IntraMap's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new IntraMap. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* fname -* Pointer to a null-terminated string containing the name of -* the transformation function to be used, as previously -* registered using astIntraReg. -* nin -* The number of input coordinates. -* nout -* The number of output coordinates. - -* Returned Value: -* A pointer to the new IntraMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstIntraMap *new; /* Pointer to new IntraMap */ - char *clname; /* Cleaned transformation function name */ - int found; /* Transformation function name found? */ - int ifun; /* Loop counter for registered functions */ - -/* Initialise. */ - new = NULL; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - found = 0; - ifun = 0; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitIntraMapVtab( vtab, name ); - -/* Clean (and validate) the transformation function name supplied. */ - clname = CleanName( fname, "astIntraMap", status ); - -/* Search for a registered transformation function name which matches. */ - if ( astOK ) { - found = 0; - for ( ifun = 0; ifun < tran_nfun; ifun++ ) { - if ( ( found = !strcmp( clname, tran_data[ ifun ].name ) ) ) break; - } - } - -/* Free the memory containing the cleaned name string. */ - clname = astFree( clname ); - -/* If no match was found, then report an error. */ - if ( astOK ) { - if ( !found ) { - astError( AST__URITF, "astInitIntraMap(%s): The transformation " - "function \"%s\" has not been registered using " - "astIntraReg.", status, name, clname ); - -/* Check that the number of input coordinates is compatible with the - number used by the transformation function (as specified when it - was registered). Report an error if necessary. */ - } else { - if ( ( nin != tran_data[ ifun ].nin ) && - ( tran_data[ ifun ].nin != AST__ANY ) ) { - astError( AST__BADNI, "astInitIntraMap(%s): Number of input " - "coordinates (%d) does not match the number " - "used by the \"%s\" transformation function " - "(%d).", status, name, nin, tran_data[ ifun ].name, - tran_data[ ifun ].nin ); - -/* Similarly check the number of output coordinates. */ - } else if ( ( nout != tran_data[ ifun ].nout ) && - ( tran_data[ ifun ].nout != AST__ANY ) ) { - astError( AST__BADNO, "astInitIntraMap(%s): Number of output " - "coordinates (%d) does not match the number " - "used by the \"%s\" transformation function " - "(%d).", status, name, nout, tran_data[ ifun ].name, - tran_data[ ifun ].nout ); - -/* If OK, initialise a Mapping structure (the parent class) as the - first component within the IntraMap structure, allocating memory if - necessary (note that this also provides further checks on the - validity of "nin" and "nout"). Specify whether the forward and - inverse transformations are defined. */ - } else { - new = (AstIntraMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, nin, nout, - ( ( tran_data[ ifun ].flags & AST__NOFWD ) == 0 ), - ( ( tran_data[ ifun ].flags & AST__NOINV ) == 0 ) ); - - if ( astOK ) { - -/* Initialise the IntraMap data. */ -/* ---------------------------- */ -/* Initialise the IntraFlag string pointer. */ - new->intraflag = NULL; - -/* Store the index used to access the transformation function data. */ - new->ifun = ifun; - -/* If an error occurred, clean up by deleting the new IntraMap. */ - if ( !astOK ) new = astDelete( new ); - } - } - } - } - -/* Return a pointer to the new IntraMap. */ - return new; -} - -AstIntraMap *astLoadIntraMap_( void *mem, size_t size, - AstIntraMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadIntraMap - -* Purpose: -* Load an IntraMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "intramap.h" -* AstIntraMap *astLoadIntraMap( void *mem, size_t size, -* AstIntraMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* IntraMap loader. - -* Description: -* This function is provided to load a new IntraMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* IntraMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for an IntraMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the IntraMap is to be -* loaded. This must be of sufficient size to accommodate the -* IntraMap data (sizeof(IntraMap)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the IntraMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the IntraMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstIntraMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new IntraMap. If this is NULL, a pointer -* to the (static) virtual function table for the IntraMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "IntraMap" is used instead. - -* Returned Value: -* A pointer to the new IntraMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstIntraMap *new; /* Pointer to the new IntraMap */ - char *author; /* Pointer to author's name string */ - char *contact; /* Pointer to contact details string */ - char *fname; /* Pointer to transformation function name */ - char *purpose; /* Pointer to purpose comment string */ - int found; /* Function name found? */ - int ifun; /* Loop counter for registered functions */ - int nin; /* Number of IntraMap input coordinates */ - int nout; /* Number of IntraMap output coordinates */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this IntraMap. In this case the - IntraMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstIntraMap ); - vtab = &class_vtab; - name = "IntraMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitIntraMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built IntraMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "IntraMap" ); - -/* Now read each individual data item from this list. */ - -/* Transformation function name. */ -/* ----------------------------- */ - fname = astReadString( channel, "fname", "" ); - -/* IntraFlag string. */ -/* ----------------- */ - new->intraflag = astReadString( channel, "iflag", NULL ); - -/* Purpose string. */ -/* --------------- */ - purpose = astReadString( channel, "purp", "" ); - -/* Author's name. */ -/* -------------- */ - author = astReadString( channel, "auth", "" ); - -/* Contact details. */ -/* ---------------- */ - contact = astReadString( channel, "cntact", "" ); - -/* If OK, search the array of transformation function data to see if - the required transformation function has been registered. */ - if ( astOK ) { - found = 0; - for ( ifun = 0; ifun < tran_nfun; ifun++ ) { - if ( ( found = !strcmp( fname, tran_data[ ifun ].name ) ) ) break; - } - -/* If the transformation function has not been registered, report an - error explaining how to obtain it from the author and register - it. */ - if ( !found ) { - astError( AST__URITF, "astLoadIntraMap(%s): An IntraMap was read " - "which uses an unknown transformation " - "function.", status, astGetClass( channel ) ); - astError( AST__URITF, "This is a private extension to the AST " - "library: to handle it, you must obtain the " - "source code from its author." , status); - astError( AST__URITF, "You can then register it with AST in your " - "software by calling astIntraReg (see " - "SUN/211)." , status); - astError( AST__URITF, " " , status); - astError( AST__URITF, " Function name: \"%s\".", status, fname ); - astError( AST__URITF, " Purpose: \"%s\".", status, purpose ); - astError( AST__URITF, " Author: \"%s\".", status, author ); - astError( AST__URITF, " Contact address: \"%s\".", status, contact ); - astError( AST__URITF, " " , status); - -/* Obtain the numbers of input and output coordinates for the - IntraMap. Use parent methods for this, since if any derived class - has overridden these methods it may depend on data that have not - yet been loaded. */ - } else { - nin = ( *parent_getnin )( (AstMapping *) new, status ); - nout = ( *parent_getnout )( (AstMapping *) new, status ); - if ( astOK ) { - -/* Check that the numbers of coordinates are compatible with the - numbers used by the transformation function, as specified when it - was registered. */ - if ( ( nin != tran_data[ ifun ].nin ) && - ( tran_data[ ifun ].nin != AST__ANY ) ) { - astError( AST__BADNI, "astLoadIntraMap(%s): The number of " - "input coordinates for the IntraMap " - "read (%d) does not match the number " - "used by the registered \"%s\" " - "transformation function (%d).", status, - astGetClass( channel ), nin, - tran_data[ ifun ].name, - tran_data[ ifun ].nin ); - } else if ( ( nout != tran_data[ ifun ].nout ) && - ( tran_data[ ifun ].nout != AST__ANY ) ) { - astError( AST__BADNO, "astLoadIntraMap(%s): The number of " - "output coordinates for the IntraMap " - "read (%d) does not match the number " - "used by the registered \"%s\" " - "transformation function (%d).", status, - astGetClass( channel ), nout, - tran_data[ ifun ].name, - tran_data[ ifun ].nout ); - -/* If OK, store the index used to access the transformation function - data. */ - } else { - new->ifun = ifun; - } - } - } - } - -/* Free strings allocated by astReadString. */ - fname = astFree( fname ); - purpose = astFree( purpose ); - author = astFree( author ); - contact = astFree( contact ); - -/* If an error occurred, clean up by deleting the new IntraMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new IntraMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - diff --git a/ast/intramap.h b/ast/intramap.h deleted file mode 100644 index ac2d8cd..0000000 --- a/ast/intramap.h +++ /dev/null @@ -1,344 +0,0 @@ -#if !defined( INTRAMAP_INCLUDED ) /* Include this file only once */ -#define INTRAMAP_INCLUDED -/* -*+ -* Name: -* intramap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the IntraMap class. - -* Invocation: -* #include "intramap.h" - -* Description: -* This include file defines the interface to the IntraMap class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. -* -* The IntraMap class implements Mappings which transform -* coordinates using a privately-defined transformation function -* (e.g. written in C). - -* Inheritance: -* The IntraMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* IntraFlag -* IntraMap identification string. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astMapMerge -* Simplify a sequence of Mappings containing an IntraMap. -* astTransform -* Transform a set of points using an IntraMap. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* astClearIntraFlag -* Clear the IntraFlag attribute for an IntraMap. -* astGetIntraFlag -* Get the value of the IntraFlag attribute for an IntraMap. -* astSetIntraFlag -* Set the value of the IntraFlag attribute for an IntraMap. -* astTestIntraFlag -* Test whether a value has been set for the IntraFlag attribute of -* an IntraMap. - -* Other Class Functions: -* Public: -* astIntraMap -* Create an IntraMap. -* astIntraReg -* Register a transformation function for use by an IntraMap. -* astIsAIntraMap -* Test class membership. -* -* Protected: -* astCheckIntraMap -* Validate class membership. -* astInitIntraMap -* Initialise an IntraMap. -* astLoadIntraMap -* Load an IntraMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstIntraMap -* IntraMap object type. -* -* Protected: -* AstIntraMapVtab -* IntraMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 24-MAR-1998 (RFWS): -* Original version. -* 16-SEP-1999 (RFWS): -* Added the IntraFlag attribute and added a Mapping pointer as a new -* first argument to transformation functions. -* 8-JAN-2003 (DSB): -* Added protected astInitIntraMapVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macro Definitions. */ -/* ================== */ -#define AST__NOFWD (1U) /* No forward transformation defined */ -#define AST__NOINV (2U) /* No inverse transformation defined */ -#define AST__SIMPFI (4U) /* Forward-inverse may be simplified */ -#define AST__SIMPIF (8U) /* Inverse-forward may be simplified */ - -#define AST__ANY (-66) /* Allow any number of input/output coords */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* IntraMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstIntraMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - char *intraflag; /* Pointer to identification string */ - int ifun; /* Transformation function index */ -} AstIntraMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstIntraMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - const char *(* GetIntraFlag)( AstIntraMap *, int * ); - int (* TestIntraFlag)( AstIntraMap *, int * ); - void (* ClearIntraFlag)( AstIntraMap *, int * ); - void (* SetIntraFlag)( AstIntraMap *, const char *, int * ); -} AstIntraMapVtab; - - -/* Structure to hold data for transformation functions. */ -typedef struct AstIntraMapTranData { - void (* tran)( AstMapping *, int, int, const double *[], int, int, double *[] ); - /* Pointer to transformation function */ - void (* tran_wrap)( void (*)( AstMapping *, int, int, const double *[], int, int, double *[] ), AstMapping *, int, int, const double *[], int, int, double *[], int * ); - /* Pointer to wrapper function */ - char *author; /* Author's name */ - char *contact; /* Contact details (e.g. e-mail address) */ - char *name; /* Function name (assigned by caller) */ - char *purpose; /* Comment string describing purpose */ - int nin; /* Number of input coordinates per point */ - int nout; /* Number of output coordinates per point */ - unsigned int flags; /* Flags to describe function behaviour */ -} AstIntraMapTranData; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstIntraMapGlobals { - AstIntraMapVtab Class_Vtab; - int Class_Init; -} AstIntraMapGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(IntraMap) /* Check class membership */ -astPROTO_ISA(IntraMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstIntraMap *astIntraMap_( const char *, int, int, const char *, int *, ...); -#else -AstIntraMap *astIntraMapId_( const char *, int, int, const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstIntraMap *astInitIntraMap_( void *, size_t, int, AstIntraMapVtab *, - const char *, const char *, int, int, int * ); - -/* Vtab initialiser. */ -void astInitIntraMapVtab_( AstIntraMapVtab *, const char *, int * ); - -/* Loader. */ -AstIntraMap *astLoadIntraMap_( void *, size_t, AstIntraMapVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitIntraMapGlobals_( AstIntraMapGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -void astIntraReg_( const char *, int, int, void (*)( AstMapping *, int, int, const double *[], int, int, double *[] ), unsigned int, const char *, const char *, const char *, int * ); - -#if defined(astCLASS) /* Protected */ -const char *astGetIntraFlag_( AstIntraMap *, int * ); -int astTestIntraFlag_( AstIntraMap *, int * ); -void astClearIntraFlag_( AstIntraMap *, int * ); -void astSetIntraFlag_( AstIntraMap *, const char *, int * ); - -#else /* Public only */ -void astIntraRegFor_( const char *, int, int, void (*)( AstMapping *, int, int, const double *[], int, int, double *[] ), void (*)( void (*)( AstMapping *, int, int, const double *[], int, int, double *[]), AstMapping *, int, int, const double *[], int, int, double *[], int * ), unsigned int, const char *, const char *, const char *, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckIntraMap(this) astINVOKE_CHECK(IntraMap,this,0) -#define astVerifyIntraMap(this) astINVOKE_CHECK(IntraMap,this,1) - -/* Test class membership. */ -#define astIsAIntraMap(this) astINVOKE_ISA(IntraMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astIntraMap astINVOKE(F,astIntraMap_) -#else -#define astIntraMap astINVOKE(F,astIntraMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitIntraMap(mem,size,init,vtab,name,fname,nin,nout) \ -astINVOKE(O,astInitIntraMap_(mem,size,init,vtab,name,fname,nin,nout,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitIntraMapVtab(vtab,name) astINVOKE(V,astInitIntraMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadIntraMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadIntraMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckIntraMap to validate IntraMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astIntraReg(name,nin,nout,tran,flags,purpose,author,contact) \ -astIntraReg_(name,nin,nout,tran,flags,purpose,author,contact,STATUS_PTR) - -#if defined(astCLASS) /* Protected */ -#define astClearIntraFlag(this) \ -astINVOKE(V,astClearIntraFlag_(astCheckIntraMap(this),STATUS_PTR)) -#define astGetIntraFlag(this) \ -astINVOKE(V,astGetIntraFlag_(astCheckIntraMap(this),STATUS_PTR)) -#define astSetIntraFlag(this,value) \ -astINVOKE(V,astSetIntraFlag_(astCheckIntraMap(this),value,STATUS_PTR)) -#define astTestIntraFlag(this) \ -astINVOKE(V,astTestIntraFlag_(astCheckIntraMap(this),STATUS_PTR)) - -#else /* Public only */ -#define astIntraRegFor(name,nin,nout,tran,tran_wrap,flags,purpose,author,contact) \ -astIntraRegFor_(name,nin,nout,tran,tran_wrap,flags,purpose,author,contact,STATUS_PTR) -#endif -#endif - - - - - diff --git a/ast/keymap.c b/ast/keymap.c deleted file mode 100644 index df722ca..0000000 --- a/ast/keymap.c +++ /dev/null @@ -1,10972 +0,0 @@ -/* -*class++ -* Name: -* KeyMap - -* Purpose: -* Store a set of key/value pairs. - -* Constructor Function: -c astKeyMap -f AST_KEYMAP - -* Description: -* The KeyMap class is used to store a set of values with associated keys -* which identify the values. The keys are strings. These may be case -* sensitive or insensitive as selected by the KeyCase attribute, and -* trailing spaces are ignored. The value associated with a key can be -* integer (signed 4 and 2 byte, or unsigned 1 byte), floating point -* (single or double precision), -c void pointer, -* character string or AST Object pointer. Each -* value can be a scalar or a one-dimensional vector. A KeyMap is -* conceptually similar to a Mapping in that a KeyMap transforms an -* input into an output - the input is the key, and the output is the -* value associated with the key. However, this is only a conceptual -* similarity, and it should be noted that the KeyMap class inherits from -* the Object class rather than the Mapping class. The methods of the -* Mapping class cannot be used with a KeyMap. - -* Inheritance: -* The KeyMap class inherits from the Object class. - -* Attributes: -* In addition to those attributes common to all Objects, every -* KeyMap also has the following attributes: -* -* - KeyCase: Sets the case in which keys are stored -* - KeyError: Report an error if the requested key does not exist? -* - SizeGuess: The expected size of the KeyMap. -* - SortBy: Determines how keys are sorted in a KeyMap. -* - MapLocked: Prevent new entries being added to the KeyMap? - -* Functions: -c In addition to those functions applicable to all Objects, the -c following functions may also be applied to all KeyMaps: -f In addition to those routines applicable to all Objects, the -f following routines may also be applied to all KeyMaps: -* -c - astMapDefined: Does a KeyMap contain a defined value for a key? -c - astMapGetC: Get a scalar or vector entry as a single string. -c - astMapGet0: Get a named scalar entry from a KeyMap -c - astMapGet1: Get a named vector entry from a KeyMap -c - astMapGetElem: Get an element of a named vector entry from a KeyMap -c - astMapHasKey: Does the KeyMap contain a named entry? -c - astMapKey: Return the key name at a given index in the KeyMap -c - astMapLenC: Get the length of a named character entry in a KeyMap -c - astMapLength: Get the length of a named entry in a KeyMap -c - astMapCopy: Copy entries from one KeyMap into another -c - astMapPut0: Add a new scalar entry to a KeyMap -c - astMapPut1: Add a new vector entry to a KeyMap -c - astMapPutElem: Puts a value into a vector entry in a KeyMap -c - astMapPutU: Add a new entry to a KeyMap with an undefined value -c - astMapRemove: Removed a named entry from a KeyMap -c - astMapRename: Rename an existing entry in a KeyMap -c - astMapSize: Get the number of entries in a KeyMap -c - astMapType: Return the data type of a named entry in a map -f - AST_MAPDEFINED: Does a KeyMap contain a defined value for a key? -f - AST_MAPGETC: Get a scalar or vector entry as a single string. -f - AST_MAPGET0: Get a named scalar entry from a KeyMap -f - AST_MAPGET1: Get a named vector entry from a KeyMap -f - AST_MAPGETELEM: Get an element of a named vector entry from a KeyMap -f - AST_MAPHASKEY: Does the KeyMap contain a named entry? -f - AST_MAPKEY: Return the key name at a given index in the KeyMap -f - AST_MAPLENC: Get the length of a named character entry in a KeyMap -f - AST_MAPLENGTH: Get the length of a named entry in a KeyMap -f - AST_MAPCOPY: Copy entries from one KeyMap into another -f - AST_MAPPUT0: Add a new scalar entry to a KeyMap -f - AST_MAPPUT1: Add a new vector entry to a KeyMap -f - AST_MAPPUTELEM: Puts a value into a vector entry in a KeyMap -f - AST_MAPPUTU: Add a new entry to a KeyMap with an undefined value -f - AST_MAPREMOVE: Removed a named entry from a KeyMap -f - AST_MAPRENAME: Rename an existing entry in a KeyMap -f - AST_MAPSIZE: Get the number of entries in a KeyMap -f - AST_MAPTYPE: Return the data type of a named entry in a map - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2008-2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: B.S. Berry (Starlink) - -* History: -* 12-NOV-2004 (DSB): -* Original version. -* 5-JAN-2005 (DSB): -* Added astMapLenC method. -* 17-JAN-2005 (DSB): -* Remove "void *" arithmetic. -* 25-JAN-2005 (DSB): -* Added more DEBUG blocks -* 30-SEP-2005 (DSB): -* Allow an integer to be read from a formatted floating point value. -* 6-DEC-2005 (DSB): -* Remove astMapGet0C stuff from description of astMapGet1C. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 5-JUN-2006 (DSB): -* Added support for single precision entries. -* 30-NOV-2007 (DSB): -* Added SizeGuess attribute. -* 4-DEC-2007 (DSB): -* Allow size of hash table to grow dynamically as more entries are -* added to the KeyMap. -* 5-DEC-2007 (DSB): -* Ensure mapsize is always a power of 2. -* 6-DEC-2007 (DSB): -* - Define the minium table size rather than the default SizeGuess -* value, and derive the default SizeGuess value from the minimum -* table size. -* - Use "&" rather than "%" to get the hash table index from the -* full width hash value (& may be faster than %). -* 7-MAR-2008 (DSB): -* Added support for pointer ("P") entries. -* 31-MAR-2009 (DSB): -* Remove rounding errors from formatted double values. -* 27-APR-2009 (DSB): -* Added astMapGetElem. -* 1-SEP-2009 (DSB): -* Added KeyError attribute. -* 12-FEB-2010 (DSB): -* When converting an entry value between double and string, treat -* "" as the formatted version of AST__BAD. -* 3-MAR-2010 (DSB): -* Added astMapPutElem. -* 27-APR-2010 (DSB): -* Added MapLocked attribute. -* 4-MAY-2010 (DSB): -* - Propagate MapLocked and KeyError attributes to any encapsulated -* KeyMaps. -* - Added astMapCopy method. -* - Added astMapPutU method and AST__UNDEFTYPE data type. -* 11-AUG-2010 (DSB): -* Added SortBy attribute. -* 12-AUG-2010 (DSB): -* Speed up access to large KeyMaps. -* 13-AUG-2010 (DSB): -* - No need to sort all entries when doubling the table size since -* changing the table size does not change the linked list of sorted -* entries. -* - Initialise the sortby attribute to the cleared value, rather -* than the default value. -* 2-OCT-2010 (DSB): -* Added support for short int valued entries. -* 24-NOV-2010 (DSB): -* Fix memory leak in astMapPutElemC and astMapPutElemA. -* 26-NOV-2010 (DSB): -* Added support for unsigned byte valued entries. -* 3-DEC-2010 (DSB): -* Added KeyCase attribute. -* 14-JAN-2011 (DSB): -* Fix bug that prevented zero length strings being stored in a -* keymap. -* 17-SEP-2012 (DSB): -* Fix bug that prevented UNDEF entries from being read back in -* from a dump of a KeyMap. -* 18-MAR-2013 (DSB): -* Added astMapDefined. -* 18-JUL-2013 (DSB): -* Added SortBy options "KeyAgeUp" and "KeyAgeDown". -* 9-SEP-2016 (DSB): -* Guard against memory corruption that could occur after making -* 50 (AST__KEYMAP_CONVERTVALUE_MAX_STRINGS) calls to put a string -* into a KeyMap using astMapPutElemC. -* 16-MAR-2017 (DSB): -* Added astMapGetC. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS KeyMap - -/* Minimum size for the hash table. */ -#define MIN_TABLE_SIZE 16 - -/* The maximum number of entries per element of the hash table. If this - value is exceeded the hash table will be doubled in size. */ -#define MAX_ENTRIES_PER_TABLE_ENTRY 10 - -/* String used to represent the formatetd version of AST__BAD. */ -#define BAD_STRING "" - -/* Integer values to represent the different values of the SortBy attribute. */ -#define SORTBY_NONE 0 -#define SORTBY_AGEUP 1 -#define SORTBY_AGEDOWN 2 -#define SORTBY_KEYUP 3 -#define SORTBY_KEYDOWN 4 -#define SORTBY_KEYAGEUP 5 -#define SORTBY_KEYAGEDOWN 6 - - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* For AST__BAD */ -#include "channel.h" /* I/O channels */ -#include "keymap.h" /* Interface definition for this class */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Type Definitions */ -/* ================ */ - -/* This structure is a AstMapEntry holding a scalar int */ -typedef struct Entry0I { - struct AstMapEntry entry; /* The parent Entry information */ - int value; /* The integer value */ -} Entry0I; - -/* This structure is a AstMapEntry holding a scalar double */ -typedef struct Entry0D { - struct AstMapEntry entry; /* The parent Entry information */ - double value; /* The floating point value */ -} Entry0D; - -/* This structure is a AstMapEntry holding a scalar short int */ -typedef struct Entry0S { - struct AstMapEntry entry; /* The parent Entry information */ - short int value; /* The short int value */ -} Entry0S; - -/* This structure is a AstMapEntry holding a scalar unsigned byte - (unsigned char) */ -typedef struct Entry0B { - struct AstMapEntry entry; /* The parent Entry information */ - unsigned char value; /* The byte value */ -} Entry0B; - -/* This structure is a AstMapEntry holding a scalar float */ -typedef struct Entry0F { - struct AstMapEntry entry; /* The parent Entry information */ - float value; /* The floating point value */ -} Entry0F; - -/* This structure is a AstMapEntry holding a scalar string */ -typedef struct Entry0C { - struct AstMapEntry entry; /* The parent Entry information */ - const char *value; /* The string pointer */ -} Entry0C; - -/* This structure is a AstMapEntry holding a scalar AST Object */ -typedef struct Entry0A { - struct AstMapEntry entry; /* The parent Entry information */ - AstObject *value; /* The Object pointer */ - struct AstMapEntry *next; /* Pointer to next AST Object entry */ - struct AstMapEntry *prev; /* Pointer to previous AST Object entry */ -} Entry0A; - -/* This structure is a AstMapEntry holding a scalar void pointer */ -typedef struct Entry0P { - struct AstMapEntry entry; /* The parent Entry information */ - void *value; /* The pointer */ -} Entry0P; - -/* This structure is a AstMapEntry holding a 1D array of ints */ -typedef struct Entry1I { - struct AstMapEntry entry; /* The parent Entry information */ - int *value; /* The integer values */ -} Entry1I; - -/* This structure is a AstMapEntry holding a 1D array of doubles */ -typedef struct Entry1D { - struct AstMapEntry entry; /* The parent Entry information */ - double *value; /* The floating point values */ -} Entry1D; - -/* This structure is a AstMapEntry holding a 1D array of short ints */ -typedef struct Entry1S { - struct AstMapEntry entry; /* The parent Entry information */ - short int *value; /* The short int values */ -} Entry1S; - -/* This structure is a AstMapEntry holding a 1D array of unsigned bytes */ -typedef struct Entry1B { - struct AstMapEntry entry; /* The parent Entry information */ - unsigned char *value; /* The byte values */ -} Entry1B; - -/* This structure is a AstMapEntry holding a 1D array of floats */ -typedef struct Entry1F { - struct AstMapEntry entry; /* The parent Entry information */ - float *value; /* The floating point values */ -} Entry1F; - -/* This structure is a AstMapEntry holding a 1D array of strings */ -typedef struct Entry1C { - struct AstMapEntry entry; /* The parent Entry information */ - const char **value; /* The string pointers */ -} Entry1C; - -/* This structure is a AstMapEntry holding a 1D array of AST Objects */ -typedef struct Entry1A { - struct AstMapEntry entry; /* The parent Entry information */ - AstObject **value; /* The Object pointers */ - struct AstMapEntry *next; /* Pointer to next AST Object entry */ - struct AstMapEntry *prev; /* Pointer to previous AST Object entry */ -} Entry1A; - -/* This structure is a AstMapEntry holding a 1D array of void pointers. */ -typedef struct Entry1P { - struct AstMapEntry entry; /* The parent Entry information */ - void **value; /* The pointers */ -} Entry1P; - - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->ConvertValue_Init = 0; \ - globals->ConvertValue_Istr = 0; \ - globals->ConvertValue_Buff[ 0 ] = 0; \ - globals->MapKey_Init = 0; \ - globals->MapKey_Istr = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(KeyMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(KeyMap,Class_Init) -#define class_vtab astGLOBAL(KeyMap,Class_Vtab) -#define getattrib_buff astGLOBAL(KeyMap,GetAttrib_Buff) -#define convertvalue_strings astGLOBAL(KeyMap,ConvertValue_Strings) -#define convertvalue_istr astGLOBAL(KeyMap,ConvertValue_Istr) -#define convertvalue_init astGLOBAL(KeyMap,ConvertValue_Init) -#define convertvalue_buff astGLOBAL(KeyMap,ConvertValue_Buff) -#define mapkey_strings astGLOBAL(KeyMap,MapKey_Strings) -#define mapkey_istr astGLOBAL(KeyMap,MapKey_Istr) -#define mapkey_init astGLOBAL(KeyMap,MapKey_Init) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffer returned by GetAttrib. */ \ -static char getattrib_buff[ AST__KEYMAP_GETATTRIB_BUFF_LEN + 1 ]; - -/* Strings returned by ConvertValue */ \ -static char *convertvalue_strings[ AST__KEYMAP_CONVERTVALUE_MAX_STRINGS ]; - -/* Offset of next string in "ConvertValue_Strings" */ \ -static int convertvalue_istr; - -/* "ConvertValue_Strings" array initialised? */ \ -static int convertvalue_init; - -/* ConvertValue string buffer */ \ -static char convertvalue_buff[ AST__KEYMAP_CONVERTVALUE_BUFF_LEN + 1 ]; - -/* Strings returned by MapKey */ \ -static char *mapkey_strings[ AST__KEYMAP_MAPKEY_MAX_STRINGS ]; - -/* Offset of next string in "MapKey_Strings" */ \ -static int mapkey_istr; - -/* "MapKey_Strings" array initialised? */ \ -static int mapkey_init; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstKeyMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstKeyMap *astKeyMapId_( const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapEntry *AddTableEntry( AstKeyMap *, int, AstMapEntry *, int, int * ); -static AstMapEntry *CopyMapEntry( AstMapEntry *, int * ); -static AstMapEntry *FreeMapEntry( AstMapEntry *, int * ); -static AstMapEntry *RemoveTableEntry( AstKeyMap *, int, const char *, int * ); -static AstMapEntry *SearchTableEntry( AstKeyMap *, int, const char *, int * ); -static const char *ConvertKey( AstKeyMap *, const char *, char *, int, const char *, int * ); -static const char *GetKey( AstKeyMap *, int index, int * ); -static const char *MapIterate( AstKeyMap *, int, int * ); -static const char *MapKey( AstKeyMap *, int index, int * ); -static const char *SortByString( int, const char *, int * ); -static int CompareEntries( const void *, const void * ); -static int ConvertValue( void *, int, void *, int, int * ); -static int GetObjSize( AstObject *, int * ); -static int HashFun( const char *, int, unsigned long *, int * ); -static int KeyCmp( const char *, const char * ); -static int MapDefined( AstKeyMap *, const char *, int * ); -static int MapGet0A( AstKeyMap *, const char *, AstObject **, int * ); -static int MapGet0C( AstKeyMap *, const char *, const char **, int * ); -static int MapGet0D( AstKeyMap *, const char *, double *, int * ); -static int MapGet0S( AstKeyMap *, const char *, short int *, int * ); -static int MapGet0B( AstKeyMap *, const char *, unsigned char *, int * ); -static int MapGet0F( AstKeyMap *, const char *, float *, int * ); -static int MapGet0I( AstKeyMap *, const char *, int *, int * ); -static int MapGet0P( AstKeyMap *, const char *, void **, int * ); -static int MapGet1A( AstKeyMap *, const char *, int, int *, AstObject **, int * ); -static int MapGet1C( AstKeyMap *, const char *, int, int, int *, char *, int * ); -static int MapGet1D( AstKeyMap *, const char *, int, int *, double *, int * ); -static int MapGet1B( AstKeyMap *, const char *, int, int *, unsigned char *, int * ); -static int MapGet1S( AstKeyMap *, const char *, int, int *, short int *, int * ); -static int MapGet1F( AstKeyMap *, const char *, int, int *, float *, int * ); -static int MapGet1I( AstKeyMap *, const char *, int, int *, int *, int * ); -static int MapGet1P( AstKeyMap *, const char *, int, int *, void **, int * ); -static int MapGetC( AstKeyMap *, const char *, const char **, int * ); -static int MapGetElemA( AstKeyMap *, const char *, int, AstObject **, int * ); -static int MapGetElemC( AstKeyMap *, const char *, int, int, char *, int * ); -static int MapGetElemD( AstKeyMap *, const char *, int, double *, int * ); -static int MapGetElemB( AstKeyMap *, const char *, int, unsigned char *, int * ); -static int MapGetElemS( AstKeyMap *, const char *, int, short int *, int * ); -static int MapGetElemF( AstKeyMap *, const char *, int, float *, int * ); -static int MapGetElemI( AstKeyMap *, const char *, int, int *, int * ); -static int MapGetElemP( AstKeyMap *, const char *, int, void **, int * ); -static int MapHasKey( AstKeyMap *, const char *, int * ); -static int MapLenC( AstKeyMap *, const char *, int * ); -static int MapLength( AstKeyMap *, const char *, int * ); -static int MapSize( AstKeyMap *, int * ); -static int MapType( AstKeyMap *, const char *, int * ); -static int SortByInt( const char *, const char *, int * ); -static size_t SizeOfEntry( AstMapEntry *, int * ); -static void AddToObjectList( AstKeyMap *, AstMapEntry *, int * ); -static void AddToSortedList( AstKeyMap *, AstMapEntry *, int * ); -static void CheckCircle( AstKeyMap *, AstObject *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void CopyTableEntry( AstKeyMap *, AstKeyMap *, int, int * ); -static void Delete( AstObject *, int * ); -static void DoubleTableSize( AstKeyMap *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void DumpEntry( AstMapEntry *, AstChannel *, int, int * ); -static void FreeTableEntry( AstKeyMap *, int itab, int * ); -static void InitMapEntry( AstMapEntry *, int, int, int * ); -static void MapCopy( AstKeyMap *, AstKeyMap *, int * ); -static void MapPut0A( AstKeyMap *, const char *, AstObject *, const char *, int * ); -static void MapPut0C( AstKeyMap *, const char *, const char *, const char *, int * ); -static void MapPut0D( AstKeyMap *, const char *, double, const char *, int * ); -static void MapPut0B( AstKeyMap *, const char *, unsigned char, const char *, int * ); -static void MapPut0S( AstKeyMap *, const char *, short int, const char *, int * ); -static void MapPut0F( AstKeyMap *, const char *, float, const char *, int * ); -static void MapPut0I( AstKeyMap *, const char *, int, const char *, int * ); -static void MapPut0P( AstKeyMap *, const char *, void *, const char *, int * ); -static void MapPut1A( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * ); -static void MapPut1C( AstKeyMap *, const char *, int, const char *const [], const char *, int * ); -static void MapPut1D( AstKeyMap *, const char *, int, const double *, const char *, int * ); -static void MapPut1B( AstKeyMap *, const char *, int, const unsigned char *, const char *, int * ); -static void MapPut1S( AstKeyMap *, const char *, int, const short int *, const char *, int * ); -static void MapPut1F( AstKeyMap *, const char *, int, const float *, const char *, int * ); -static void MapPut1I( AstKeyMap *, const char *, int, const int *, const char *, int * ); -static void MapPut1P( AstKeyMap *, const char *, int, void *const [], const char *, int * ); -static void MapPutElemA( AstKeyMap *, const char *, int, AstObject *, int * ); -static void MapPutElemC( AstKeyMap *, const char *, int, const char *, int * ); -static void MapPutElemD( AstKeyMap *, const char *, int, double, int * ); -static void MapPutElemB( AstKeyMap *, const char *, int, unsigned char, int * ); -static void MapPutElemS( AstKeyMap *, const char *, int, short int, int * ); -static void MapPutElemF( AstKeyMap *, const char *, int, float, int * ); -static void MapPutElemI( AstKeyMap *, const char *, int, int, int * ); -static void MapPutElemP( AstKeyMap *, const char *, int, void *, int * ); -static void MapPutU( AstKeyMap *, const char *, const char *, int * ); -static void MapRemove( AstKeyMap *, const char *, int * ); -static void MapRename( AstKeyMap *, const char *, const char *, int * ); -static void NewTable( AstKeyMap *, int, int * ); -static void RemoveFromSortedList( AstKeyMap *, AstMapEntry *, int * ); -static void RemoveFromObjectList( AstKeyMap *, AstMapEntry *, int * ); -static void SortEntries( AstKeyMap *, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static int GetSizeGuess( AstKeyMap *, int * ); -static int TestSizeGuess( AstKeyMap *, int * ); -static void ClearSizeGuess( AstKeyMap *, int * ); -static void SetSizeGuess( AstKeyMap *, int, int * ); - -static int GetSortBy( AstKeyMap *, int * ); -static int TestSortBy( AstKeyMap *, int * ); -static void ClearSortBy( AstKeyMap *, int * ); -static void SetSortBy( AstKeyMap *, int, int * ); - -static int GetKeyError( AstKeyMap *, int * ); -static int TestKeyError( AstKeyMap *, int * ); -static void ClearKeyError( AstKeyMap *, int * ); -static void SetKeyError( AstKeyMap *, int, int * ); - -static int GetKeyCase( AstKeyMap *, int * ); -static int TestKeyCase( AstKeyMap *, int * ); -static void ClearKeyCase( AstKeyMap *, int * ); -static void SetKeyCase( AstKeyMap *, int, int * ); - -static int GetMapLocked( AstKeyMap *, int * ); -static int TestMapLocked( AstKeyMap *, int * ); -static void ClearMapLocked( AstKeyMap *, int * ); -static void SetMapLocked( AstKeyMap *, int, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ -static AstMapEntry *AddTableEntry( AstKeyMap *this, int itab, - AstMapEntry *entry, int keymember, - int *status ){ -/* -* Name: -* AddTableEntry - -* Purpose: -* Add an new entry to a linked-list of KeyMap entries. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* AstMapEntry *AddTableEntry( AstKeyMap *this, int itab, -* AstMapEntry *entry, int keymember, -* int *status ){ - -* Class Membership: -* KeyMap member function. - -* Description: -* This function adds the supplied MapEntry to the head of the linked -* list of MapEntries stored at the specified entry of the hash table. -* If this results in the linked list having too many entries, then a -* new larger hash table is allocated and the entries in the existing -* table are moved into the new table. - -* Parameters: -* this -* Pointer to the KeyMap. -* itab -* Index of the hash table element to be searched. -* entry -* Pointer to the MapEntry to be added. -* keymember -* A unique integer identifier for the key that increases -* monotonically with age of the key. If this is negative, -* the next available identifier will be used automatically. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A NULL pointer. - -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Put a pointer to the MapEntry which is currently at the head of the - linked list in the "next" component of the supplied MapEntry. */ - entry->next = this->table[ itab ]; - -/* Store the supplied MapEntry pointer in the requested element of the - hash table. */ - this->table[ itab ] = entry; - -/* Increment the length of linked list. */ - this->nentry[ itab ]++; - -/* Each new entry added to the KeyMap has a unique member index that is - never re-used. */ - entry->member = (this->member_count)++; - -/* Each key added to the KeyMap also has a separate unique member index, - but this index is re-used each time the same key is added into the - KeyMap. So changing the value associated with a key does not cause the - keymember value to change. */ - if( keymember >= 0 ) { - entry->keymember = keymember; - } else { - entry->keymember = (this->member_count)++; - } - -/* Insert the supplied MapEntry into a list sorted by key. */ - AddToSortedList( this, entry, status ); - -/* If the entry is of type AST__OBJECTTYPE, add it to the head of the - list of AST__OBJECTTYPE entries in the KeyMap. */ - AddToObjectList( this, entry, status ); - -/* If the population of this table entry is now too large, double the size - of the table, moving the table entries to appropriate places in the - new larger table. */ - if( this->nentry[ itab ] > MAX_ENTRIES_PER_TABLE_ENTRY ) { - DoubleTableSize( this, status ); - } - -/* Return a NULL pointer. */ - return NULL; -} - -static void AddToObjectList( AstKeyMap *this, AstMapEntry *entry, int *status ){ -/* -* Name: -* AddToObjectList - -* Purpose: -* Add AST__OBJECTTYPE entries into a linked-list of such entries. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void AddToObjectList( AstKeyMap *this, AstMapEntry *entry, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* If the supplied MapEntry holds one or more pointers to AST Objects, -* then the entry is added to a linked list of such entries. - -* Parameters: -* this -* Pointer to the KeyMap. -* entry -* Pointer to the MapEntry to be added. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - Entry0A *scalar; /* Pointer to a scalar AST__OBJECTTYPE entry */ - Entry1A *vector; /* Pointer to a vector AST__OBJECTTYPE entry */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do nothing if the entry does not hold AST Object pointers. */ - if( entry->type == AST__OBJECTTYPE ) { - -/* If the list is not currently empty, add the new entry into the list. */ - if( this->firstA ) { - -/* Store a pointer to the new entry as the previous link in the current - first entry in the list. */ - if( this->firstA->nel == 0 ) { - scalar = (Entry0A *) this->firstA; - scalar->prev = entry; - } else { - vector = (Entry1A *) this->firstA; - vector->prev = entry; - } - -/* Store a pointer to the current first entry as the next link in the new - entry, and nullify the previus link. */ - if( entry->nel == 0 ) { - scalar = (Entry0A *) entry; - scalar->next = this->firstA; - scalar->prev = NULL; - } else { - vector = (Entry1A *) entry; - vector->next = this->firstA; - vector->prev = NULL; - } - -/* If the list is currently empty, nullify both links in the entry. */ - } else { - if( entry->nel == 0 ) { - scalar = (Entry0A *) entry; - scalar->next = NULL; - scalar->prev = NULL; - } else { - vector = (Entry1A *) entry; - vector->next = NULL; - vector->prev = NULL; - } - - } - -/* Store the new entry as the first entry. */ - this->firstA = entry; - } -} - -static void AddToSortedList( AstKeyMap *this, AstMapEntry *entry, int *status ){ -/* -* Name: -* AddToSortedList - -* Purpose: -* Add an entry into the linked-list of sorted KeyMap entries. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void AddToSortedList( AstKeyMap *this, AstMapEntry *entry, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function adds the supplied MapEntry into the linked list of -* sorted MapEntries at a position that maintains the sorted order. - -* Parameters: -* this -* Pointer to the KeyMap. -* entry -* Pointer to the MapEntry to be added. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMapEntry *hi; /* MapEntry at high end of current range */ - AstMapEntry *lo; /* MapEntry at low end of current range */ - AstMapEntry *mid; /* MapEntry at middle of current range */ - int cmp; /* Result of comparing two entries */ - int istep; /* Step counter */ - int nstep; /* Number of entries in current range */ - int sortby; /* How to sort the keys */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the SortBy value. */ - sortby = astGetSortBy( this ); - -/* Do nothing if no sorting is required. */ - if( sortby != SORTBY_NONE ) { - -/* Get pointers to the entries at the start and end of the sorted list. */ - lo = this->first; - hi = lo ? lo->sprev : NULL; - -/* Store sortby value in the mapentry structures. */ - if( lo ) lo->sortby = sortby; - if( hi ) hi->sortby = sortby; - entry->sortby = sortby; - -/* If the sorted list is empty, just store the supplied entry at the - head, and set the links to point back to itself. */ - if( !lo ) { - this->first = entry; - entry->sprev = entry; - entry->snext = entry; - -/* If the new entry comes before the first entry or is equal to the first - entry, record it as the new first entry, and insert it into the linked - list before the original first entry. */ - } else if( CompareEntries( &entry, &lo ) <= 0 ) { - this->first = entry; - entry->snext = lo; - entry->sprev = hi; - lo->sprev = entry; - hi->snext = entry; - -/* If the new entry comes after the last entry or is equal to the last - entry, insert it into the linked list after the last entry. */ - } else if( CompareEntries( &entry, &hi ) >= 0 ) { - entry->snext = lo; - entry->sprev = hi; - lo->sprev = entry; - hi->snext = entry; - -/* If the list only contains two values, insert the new entry into the linked - list between the existing two entries. */ - } else if( lo->snext == hi ) { - entry->snext = hi; - entry->sprev = lo; - lo->snext = entry; - hi->sprev = entry; - -/* Otherwise we do a binary chop within the existing sorted list to find the - correct position for the new entry. */ - } else { - -/* Get a pointer to the entry mid way between the hi and lo entries. The - mid entry will be on the upper side of half way if there are an even - number of entries. */ - nstep = this->nsorted/2; - mid = lo; - for( istep = 0; istep < nstep; istep++ ) mid = mid->snext; - -/* Loop until we have a pointer to the first entry which is equal to or - higher than the new entry. */ - while( lo->snext != hi ) { - -/* The next step will be half the length of the previous step. Do not - allow the step size to fall to zero. */ - nstep = ( nstep > 1 ) ? nstep/2 : 1; - -/* Compare the new entry with the current mid-way entry. */ - mid->sortby = sortby; - cmp = CompareEntries( &entry, &mid ); - -/* If the new entry comes before the mid entry, use the mid entry as the - next hi entry, and go down the list by the new step size to find the - new mid-way entry. */ - if( cmp < 0 ) { - hi = mid; - for( istep = 0; istep < nstep; istep++ ) mid = mid->sprev; - -/* If the new entry comes after the mid entry, use the mid entry as the - next lo entry, and go up the list by the new step size to find the - new mid-way entry. */ - } else if( cmp > 0 ) { - lo = mid; - for( istep = 0; istep < nstep; istep++ ) mid = mid->snext; - -/* If the new entry is equal to the mid entry, use the mid entry as hi - and set lo to the previous entry. This causes the loop to quit. */ - } else { - hi = mid; - lo = mid->sprev; - } - } - -/* Insert the new entry into the list between lo and hi. */ - entry->sprev = lo; - entry->snext = hi; - lo->snext = entry; - hi->sprev = entry; - } - -/* Increment the number of entries in the sorted list. */ - (this->nsorted)++; - } -} - -static void CheckCircle( AstKeyMap *this, AstObject *obj, const char *method, int *status ) { -/* -* Name: -* CheckCircle - -* Purpose: -* Check for circular dependencies between KeyMaps. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void CheckCircle( AstKeyMap *this, AstObject *obj, const char *method, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function checks that the given AstObject is not a KeyMap which -* contains "this". If it is, an error is reported. - -* Parameters: -* this -* The KeyMap pointer. -* obj -* Pointer to the AstObject to be inserted into the KeyMap, or NULL. -* method -* Name of method to include in error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstKeyMap *keymap; /* The KeyMap being added to "this" */ - AstObject **vec; /* Pointer to list of AstObject pointers */ - const char *key; /* The i'th key within second KeyMap */ - int i; /* Index of entry within second KeyMap */ - int j; /* Index within the vector of values */ - int len; /* No. of AST pointers stored in the entry */ - int nkey; /* No. of entries in the second KeyMap */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Return if the AstObject is not a KeyMap. */ - if( obj && astIsAKeyMap( obj ) ) { - keymap = (AstKeyMap *) obj; - -/* First check if the supplied Objects are the same. You cannot store a - KeyMap as an entry within itself. */ - if( keymap == this ) { - astError( AST__KYCIR, "%s(%s): Cannot add a %s into another " - "%s because they are same %s.", status, method, - astGetClass( this ), astGetClass( this ), - astGetClass( this ), astGetClass( this ) ); - -/* Otherwise, loop through all the entries in the KeyMap looking for AstObject - entries. */ - } else { - nkey = astMapSize( keymap ); - for( i = 0; i < nkey && astOK; i++ ) { - key = astMapKey( keymap, i ); - if( astMapType( keymap, key ) == AST__OBJECTTYPE ) { - -/* Find the number of AstObject pointers stored in this entry, and - allocate memory to store a copy of the every pointer. */ - len = astMapLength( keymap, key ); - vec = astMalloc( sizeof( AstObject *) * len ); - if( vec ) { - -/* Extract pointers to the AstObjects at this entry, and loop round them. */ - astMapGet1A( keymap, key, len, &len, vec ); - for( j = 0; j < len; j++ ) { - -/* If this entry is a KeyMap, we need to check if is the same as "this" - or contains "this". */ - if( astIsAKeyMap( vec[ j ] ) ) { - -/* If it is the same as "this", report an error. */ - if( vec[ j ] == (AstObject *) this ) { - astError( AST__KYCIR, "%s(%s): Cannot add a KeyMap " - "into another KeyMap because the first " - "KeyMap contains the second KeyMap.", status, - method, astGetClass( this ) ); - break; - -/* Otherwise, see if it contains "this". */ - } else { - CheckCircle( this, vec[ j ], method, status ); - } - } - -/* Free resources. */ - vec[ j ] = astAnnul( vec[ j ] ); - } - vec = astFree( vec ); - } - } - } - } - } -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* KeyMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* KeyMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the KeyMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstKeyMap *this; /* Pointer to the KeyMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the KeyMap structure. */ - this = (AstKeyMap *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* SizeGuess. */ -/* ---------- */ - if ( !strcmp( attrib, "sizeguess" ) ) { - astClearSizeGuess( this ); - -/* KeyError. */ -/* --------- */ - } else if ( !strcmp( attrib, "keyerror" ) ) { - astClearKeyError( this ); - -/* KeyCase. */ -/* --------- */ - } else if ( !strcmp( attrib, "keycase" ) ) { - astClearKeyCase( this ); - -/* MapLocked. */ -/* --------- */ - } else if ( !strcmp( attrib, "maplocked" ) ) { - astClearMapLocked( this ); - -/* SortBy. */ -/* ------- */ - } else if ( !strcmp( attrib, "sortby" ) ) { - astClearSortBy( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearKeyCase( AstKeyMap *this, int *status ) { -/* -*+ -* Name: -* astClearKeyCase - -* Purpose: -* Clear the value of the KeyCase attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astSetKeyCase( AstKeyMap *this ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function Clears the KeyCase attribute of a KeyMap. It reports -* an error if the KeyMap contains any entries. - -* Parameters: -* this -* Pointer to the KeyMap. - -*- -*/ - -/* Local Variables: */ - int defval; /* Default KeyCase value */ - int itab; /* Index into hash table */ - int oldval; /* Old KeyCase value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Save the old value. */ - oldval = astGetKeyCase( this ); - -/* Clear it. */ - this->keycase = -1; - -/* Get the default value. */ - defval = astGetKeyCase( this ); - -/* If the old value and the default value are not the same, we must check - that the KeyMap is empty. If not, restore the old value and report an - error. */ - if( defval != oldval ) { - for( itab = 0; itab < this->mapsize; itab++ ) { - if( this->nentry[ itab ] > 0 ) { - this->keycase = oldval; - astError( AST__NOWRT, "astClearAttrib(KeyMap): Illegal attempt to " - "clear the KeyCase attribute of a non-empty KeyMap.", - status); - break; - } - } - } -} - -static void ClearKeyError( AstKeyMap *this, int *status ) { -/* -*+ -* Name: -* astClearKeyError - -* Purpose: -* Clear the value of the KeyError attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astClearKeyError( AstKeyMap *this ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function clears the value of the KeyError attribute for a -* KeyMap. It clears the attribute recursively in any KeyMaps -* contained within the supplied KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap. - -*- -*/ - -/* Local Variables: */ - AstMapEntry *next; /* Pointer to next Entry to copy */ - AstObject **obj_list; /* List of pointers to AST Object entries */ - int i; /* Index into hash table */ - int iel; /* Index of current vector element */ - int nel; /* Number of elements in vector */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Clear the KeyError value in the supplied KeyMap. */ - this->keyerror = -INT_MAX; - -/* Loop round each entry in the hash table. */ - for( i = 0; i < this->mapsize; i++ ) { - -/* Get a pointer to the next KeyMap entry. */ - next = this->table[ i ]; - -/* Loop round all entries in this element of the hash table. */ - while( next && astOK ) { - -/* If this entry has an Object data type, see if holds any KeyMaps. */ - if( next->type == AST__OBJECTTYPE ) { - -/* Get the number of objects to check, and a pointer to the first. */ - nel = next->nel; - if( nel == 0 ) { - obj_list = &( ((Entry0A *)next)->value ); - nel = 1; - } else { - obj_list = ((Entry1A *)next)->value; - } - -/* Loop round checking all Objects. */ - for( iel = 0; iel < nel; iel++ ) { - -/* If this Object is a KeyMap, clear its KeyError attribute. */ - if( astIsAKeyMap( obj_list[ iel ] ) ) { - astClearKeyError( (AstKeyMap *) obj_list[ iel ] ); - } - } - } - -/* Get a pointer to the next entry. */ - next = next->next; - } - } -} - -static void ClearMapLocked( AstKeyMap *this, int *status ) { -/* -*+ -* Name: -* astClearMapLocked - -* Purpose: -* Clear the value of the MapLocked attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astClearMapLocked( AstKeyMap *this ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function clears the value of the MapLocked attribute for a -* KeyMap. It clears the attribute recursively in any KeyMaps -* contained within the supplied KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap. - -*- -*/ - -/* Local Variables: */ - AstMapEntry *next; /* Pointer to next Entry to copy */ - AstObject **obj_list; /* List of pointers to AST Object entries */ - int i; /* Index into hash table */ - int iel; /* Index of current vector element */ - int nel; /* Number of elements in vector */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Clear the MapLocked value in the supplied KeyMap. */ - this->maplocked = -INT_MAX; - -/* Loop round each entry in the hash table. */ - for( i = 0; i < this->mapsize; i++ ) { - -/* Get a pointer to the next KeyMap entry. */ - next = this->table[ i ]; - -/* Loop round all entries in this element of the hash table. */ - while( next && astOK ) { - -/* If this entry has an Object data type, see if holds any KeyMaps. */ - if( next->type == AST__OBJECTTYPE ) { - -/* Get the number of objects to check, and a pointer to the first. */ - nel = next->nel; - if( nel == 0 ) { - obj_list = &( ((Entry0A *)next)->value ); - nel = 1; - } else { - obj_list = ((Entry1A *)next)->value; - } - -/* Loop round checking all Objects. */ - for( iel = 0; iel < nel; iel++ ) { - -/* If this Object is a KeyMap, clear its MapLocked attribute. */ - if( astIsAKeyMap( obj_list[ iel ] ) ) { - astClearMapLocked( (AstKeyMap *) obj_list[ iel ] ); - } - } - } - -/* Get a pointer to the next entry. */ - next = next->next; - } - } -} - -static void ClearSizeGuess( AstKeyMap *this, int *status ) { -/* -*+ -* Name: -* astClearSizeGuess - -* Purpose: -* Clear the value of the SizeGuess attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astClearSizeGuess( AstKeyMap *this ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function clears the value of the SizeGuess attribute for a -* KeyMap. It reports an error if the KeyMap contains any entries. - -* Parameters: -* this -* Pointer to the KeyMap. - -*- -*/ - -/* Local Variables: */ - int empty; /* Is the KeyMap empty? */ - int itab; /* Index into hash table */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* See if the KeyMap is empty. */ - empty = 1; - for( itab = 0; itab < this->mapsize; itab++ ) { - if( this->nentry[ itab ] > 0 ) { - empty = 0; - break; - } - } - -/* If not report an error. */ - if( !empty ) { - astError( AST__NOWRT, "astClearAttrib(KeyMap): Illegal attempt to " - "clear the SizeGuess attribute of a non-empty KeyMap." , status); - -/* Otherwise, store the "cleared" value and change the size of the hash - table. */ - } else { - this->sizeguess = INT_MAX; - NewTable( this, MIN_TABLE_SIZE, status ); - } -} - -static void ClearSortBy( AstKeyMap *this, int *status ) { -/* -*+ -* Name: -* astClearSortBy - -* Purpose: -* Clear the value of the SortBy attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astClearSortBy( AstKeyMap *this ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function clears the value of the SortBy attribute for a -* KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap. - -*- -*/ - -/* Local Variables: */ - int oldval; /* The old sortby value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the original SortBy value. */ - oldval = astGetSortBy( this ); - -/* Clear the SortBy value in the supplied KeyMap. */ - this->sortby = -INT_MAX; - -/* If the value has changed, re-sort the keys. */ - if( oldval != astGetSortBy( this ) ) SortEntries( this, status ); -} - -static int CompareEntries( const void *first_void, const void *second_void ) { -/* -* Name: -* CompareEntries - -* Purpose: -* Determine the sorting order of two mapEntries. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* int CompareEntries( const void *first, const void *second ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function returns a value indicating if the first MapEntry -* is less than, equal to, or greater than the second MapEntry using -* the indicated sorting method. It is designed for use with the -* "qsort" function, and therefore must used "void *" pointers. - -* Parameters: -* first -* Pointer to the address of the first MapEntry. -* second -* Pointer to the address of the second MapEntry. - -* Returned Value: -* -1 if "first" is less than "second". This implies that "first" -* should come before "second" in the sorted list. -* -* 0 if "first" is equal to "second". -* -* +1 if "first" is greater than "second". This implies that "first" -* should come after "second" in the sorted list. - -*/ - -/* Local Variables: */ - AstMapEntry *first; /* Pointer to first MapEntry structure */ - AstMapEntry *second; /* Pointer to second MapEntry structure */ - int result; /* Returned value */ - int sortby; /* Sorting method */ - -/* Initialise returned value */ - result = 0; - -/* Get pointers to the MapEntry structures, and get the sorting method. */ - first = *( (AstMapEntry **) first_void ); - second = *( (AstMapEntry **) second_void ); - sortby = first->sortby; - -/* First handle sorting by increasing age of the value */ - if( sortby == SORTBY_AGEUP ) { - if( first->member < second->member ) { - result = 1; - } else if( first->member > second->member ) { - result = -1; - } else { - result = 0; - } - -/* Next handle sorting by decreasing age of the value */ - } else if( sortby == SORTBY_AGEDOWN ) { - if( first->member < second->member ) { - result = -1; - } else if( first->member > second->member ) { - result = 1; - } else { - result = 0; - } - -/* Next handle sorting by increasing age of the key */ - } else if( sortby == SORTBY_KEYAGEUP ) { - if( first->keymember < second->keymember ) { - result = 1; - } else if( first->keymember > second->keymember ) { - result = -1; - } else { - result = 0; - } - -/* Next handle sorting by decreasing age of the key */ - } else if( sortby == SORTBY_KEYAGEDOWN ) { - if( first->keymember < second->keymember ) { - result = -1; - } else if( first->keymember > second->keymember ) { - result = 1; - } else { - result = 0; - } - -/* Next handle sorting by increasing alphabetical position. */ - } else if( sortby == SORTBY_KEYUP ) { - result = KeyCmp( first->key, second->key ); - -/* Next handle sorting by decreasing alphabetical position. */ - } else if( sortby == SORTBY_KEYDOWN ) { - result = KeyCmp( second->key, first->key ); - - } - -/* Return the result. */ - return result; - -} - -static const char *ConvertKey( AstKeyMap *this, const char *skey, char *keybuf, - int blen, const char *method, int *status ){ -/* -* Name: -* ConvertValue - -* Purpose: -* Convert the supplied key to upper case if required. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* const char *ConvertKey( AstKeyMap *this, const char *skey, char *keybuf, -* int blen, const char *method, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function converts the supplied key string to uppercase if the -* KeyCase attribute it currently set to zero in the supplied KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap. -* skey -* Pointer to the supplied key string. -* keybuf -* Pointer to a buffer in which to place the converted string. This -* will only be used if the supplied key string needs to be -* converted. -* blen -* The length of the "keybuf" buffer. This should include room for -* a terminating null character. -* method -* Pointer to a string holding the name of the method to include in -* any error message. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If the KeyMap's KeyCase attribute is currently set to a non-zero -* value, the returned value will be a copy of "skey". Otherwise it -* will be copy of "keybuf" (the buffer holding the upper case version -* of the supplied string). - -* Notes: -* - The valeu of "skey" will be returned if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - const char *result; - int len; - -/* Initialise. */ - result = skey; - -/* Check the global error status and the supplied pointers. */ - if( !astOK ) return result; - -/* If the KeyCase attribute is non-zero, return "skey". Otherwise, convert - the "skey" string to upper case and return "keybuf". Report an error if - the key is too long. */ - if( !astGetKeyCase( this ) && astOK ) { - len = astChrLen( skey ); - if( len >= blen ) { - astError( AST__BIGKEY, "%s(%s): Supplied key '%s' is too long " - "(keys must be no more than %d characters long).", - status, method, astGetClass( this ), skey, blen - 1 ); - } else { - astChrCase( skey, keybuf, 1, blen ); - result = keybuf; - } - } - -/* Return the result. */ - return result; -} - -static int ConvertValue( void *raw, int raw_type, void *out, int out_type, int *status ) { -/* -* Name: -* ConvertValue - -* Purpose: -* Convert a value from one KeyMap data type to another. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* int ConvertValue( void *raw, int raw_type, void *out, int out_type, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function converts a supplied value from one KeyMap data type to -* another, if possible. - -* Parameters: -* raw -* Pointer to input value. -* raw_type -* The data type of the input value. -* out -* Pointer to the location at which to store the output value. This -* may be NULL, in which case the conversion is still performed if -* possible, but the result of the conversion is thrown away. If the -* output value is a pointer to a string, it should not be modified -* by the caller in any way. Neither should it be freed by the caller. -* out_type -* The data type of the output value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the conversion was performed succesfully, otherwise zero. -* In the case of the output type being AST__STRINGTYPE, the returned -* non-zero value will be the length of the formatted string (including -* the terminating null character). This value will be returned correctly -* even if "out" is NULL. - -* Notes: -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstObject *aval; /* AstObject pointer value */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *cval; /* Pointer to string value */ - const char *cvalue; /* Pointer to output string value */ - double dval; /* Double precision value */ - float fval; /* Single precision value */ - int i; /* Loop count */ - int ival; /* Integer value */ - int n1; /* Number of characters at reduced precision */ - int n2; /* Number of characters at full precision */ - int nc; /* Number of characters read from string */ - int nval; /* Number of values read from string */ - int result; /* Returned flag */ - short int sval; /* Short int value */ - unsigned char bval; /* Byte value */ - -/* Initialise. */ - result = 0; - -/* Check the global error status and the supplied pointers. */ - if( !astOK || !raw ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* If the "convertvalue_strings" array has not been initialised, fill it with - NULL pointers. */ - if( !convertvalue_init ) { - convertvalue_init = 1; - for( i = 0; i < AST__KEYMAP_CONVERTVALUE_MAX_STRINGS; i++ ) convertvalue_strings[ i ] = NULL; - } - -/* Assume conversion is possible */ - result = 1; - cvalue = NULL; - -/* Do nothing if both data types are AST__UNDEFTYPE. */ - if( raw_type == AST__UNDEFTYPE && out_type == AST__UNDEFTYPE ) { - -/* Indicate failure if one of the two types is AST__UNDEFTYPE and the - other is not. */ - } else if( raw_type == AST__UNDEFTYPE || out_type == AST__UNDEFTYPE ) { - result = 0; - -/* Otherwise, consider conversion from "int". */ - } else if( raw_type == AST__INTTYPE ) { - ival = *( (int *) raw ); - -/* Consider conversion to "int". */ - if( out_type == AST__INTTYPE ) { - if( out ) *( (int *) out ) = ival; - -/* Consider conversion to "short int". */ - } else if( out_type == AST__SINTTYPE ) { - if( out ) *( (short int *) out ) = (short int) ival; - -/* Consider conversion to "byte". */ - } else if( out_type == AST__BYTETYPE ) { - if( out ) *( (unsigned char *) out ) = (unsigned char) ival; - -/* Consider conversion to "float". */ - } else if( out_type == AST__FLOATTYPE ) { - if( out ) *( (float *) out ) = (float) ival; - -/* Consider conversion to "double". */ - } else if( out_type == AST__DOUBLETYPE ) { - if( out ) *( (double *) out ) = (double) ival; - -/* Consider conversion to "const char *". */ - } else if( out_type == AST__STRINGTYPE ) { - (void) sprintf( convertvalue_buff, "%d", ival ); - cvalue = convertvalue_buff; - -/* Consider conversion to "AstObject *". */ - } else if( out_type == AST__OBJECTTYPE ) { - result = 0; - -/* Consider conversion to "void *". */ - } else if( out_type == AST__POINTERTYPE ) { - result = 0; - -/* Report an error if the data type is unknown. */ - } else { - result = 0; - astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - out_type ); - } - -/* Otherwise, consider conversion from "short int". */ - } else if( raw_type == AST__SINTTYPE ) { - sval = *( (short int *) raw ); - -/* Consider conversion to "int". */ - if( out_type == AST__INTTYPE ) { - if( out ) *( (int *) out ) = sval; - -/* Consider conversion to "short int". */ - } else if( out_type == AST__SINTTYPE ) { - if( out ) *( (short int *) out ) = sval; - -/* Consider conversion to "byte". */ - } else if( out_type == AST__BYTETYPE ) { - if( out ) *( (unsigned char *) out ) = sval; - -/* Consider conversion to "float". */ - } else if( out_type == AST__FLOATTYPE ) { - if( out ) *( (float *) out ) = (float) sval; - -/* Consider conversion to "double". */ - } else if( out_type == AST__DOUBLETYPE ) { - if( out ) *( (double *) out ) = (double) sval; - -/* Consider conversion to "const char *". */ - } else if( out_type == AST__STRINGTYPE ) { - (void) sprintf( convertvalue_buff, "%d", (int) sval ); - cvalue = convertvalue_buff; - -/* Consider conversion to "AstObject *". */ - } else if( out_type == AST__OBJECTTYPE ) { - result = 0; - -/* Consider conversion to "void *". */ - } else if( out_type == AST__POINTERTYPE ) { - result = 0; - -/* Report an error if the data type is unknown. */ - } else { - result = 0; - astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - out_type ); - } - -/* Otherwise, consider conversion from "byte". */ - } else if( raw_type == AST__BYTETYPE ) { - bval = *( (unsigned char *) raw ); - -/* Consider conversion to "int". */ - if( out_type == AST__INTTYPE ) { - if( out ) *( (int *) out ) = bval; - -/* Consider conversion to "short int". */ - } else if( out_type == AST__SINTTYPE ) { - if( out ) *( (short int *) out ) = bval; - -/* Consider conversion to "byte". */ - } else if( out_type == AST__BYTETYPE ) { - if( out ) *( (unsigned char *) out ) = bval; - -/* Consider conversion to "float". */ - } else if( out_type == AST__FLOATTYPE ) { - if( out ) *( (float *) out ) = (float) bval; - -/* Consider conversion to "double". */ - } else if( out_type == AST__DOUBLETYPE ) { - if( out ) *( (double *) out ) = (double) bval; - -/* Consider conversion to "const char *". */ - } else if( out_type == AST__STRINGTYPE ) { - (void) sprintf( convertvalue_buff, "%d", (int) bval ); - cvalue = convertvalue_buff; - -/* Consider conversion to "AstObject *". */ - } else if( out_type == AST__OBJECTTYPE ) { - result = 0; - -/* Consider conversion to "void *". */ - } else if( out_type == AST__POINTERTYPE ) { - result = 0; - -/* Report an error if the data type is unknown. */ - } else { - result = 0; - astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - out_type ); - } - -/* Consider conversion from "double". */ - } else if( raw_type == AST__DOUBLETYPE ) { - dval = *( (double *) raw ); - -/* Consider conversion to "int". */ - if( out_type == AST__INTTYPE ) { - if( out ) *( (int *) out ) = (int)( dval + 0.5 ); - -/* Consider conversion to "short int". */ - } else if( out_type == AST__SINTTYPE ) { - if( out ) *( (short int *) out ) = (int)( dval + 0.5 ); - -/* Consider conversion to "byte". */ - } else if( out_type == AST__BYTETYPE ) { - if( out ) *( (unsigned char *) out ) = (int)( dval + 0.5 ); - -/* Consider conversion to "double". */ - } else if( out_type == AST__DOUBLETYPE ) { - if( out ) *( (double *) out ) = dval; - -/* Consider conversion to "float". */ - } else if( out_type == AST__FLOATTYPE ) { - if( out ) *( (float *) out ) = (float) dval; - -/* Consider conversion to "const char *". If reducing the number of - decimal places by two produces a saving of 10 or more characters, - assume the least significant two characters are rounding error. */ - } else if( out_type == AST__STRINGTYPE ) { - if( dval != AST__BAD ) { - n1 = sprintf( convertvalue_buff, "%.*g", DBL_DIG - 2, dval ); - n2 = sprintf( convertvalue_buff, "%.*g", DBL_DIG, dval ); - if( n2 - n1 > 9 ) { - (void) sprintf( convertvalue_buff, "%.*g", DBL_DIG - 2, dval ); - } - cvalue = convertvalue_buff; - } else { - cvalue = BAD_STRING; - } - -/* Consider conversion to "AstObject *". */ - } else if( out_type == AST__OBJECTTYPE ) { - result = 0; - -/* Consider conversion to "void *". */ - } else if( out_type == AST__POINTERTYPE ) { - result = 0; - -/* Report an error if the data type is unknown. */ - } else { - result = 0; - astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - out_type ); - } - -/* Consider conversion from "float". */ - } else if( raw_type == AST__FLOATTYPE ) { - fval = *( (float *) raw ); - -/* Consider conversion to "int". */ - if( out_type == AST__INTTYPE ) { - if( out ) *( (int *) out ) = (int)( fval + 0.5 ); - -/* Consider conversion to "short int". */ - } else if( out_type == AST__SINTTYPE ) { - if( out ) *( (short int *) out ) = (int)( fval + 0.5 ); - -/* Consider conversion to "byte". */ - } else if( out_type == AST__BYTETYPE ) { - if( out ) *( (unsigned char *) out ) = (int)( fval + 0.5 ); - -/* Consider conversion to "double". */ - } else if( out_type == AST__DOUBLETYPE ) { - if( out ) *( (double *) out ) = (double) fval; - -/* Consider conversion to "float". */ - } else if( out_type == AST__FLOATTYPE ) { - if( out ) *( (float *) out ) = fval; - -/* Consider conversion to "const char *". */ - } else if( out_type == AST__STRINGTYPE ) { - (void) sprintf( convertvalue_buff, "%.*g", FLT_DIG, fval ); - cvalue = convertvalue_buff; - -/* Consider conversion to "AstObject *". */ - } else if( out_type == AST__OBJECTTYPE ) { - result = 0; - -/* Consider conversion to "void *". */ - } else if( out_type == AST__POINTERTYPE ) { - result = 0; - -/* Report an error if the data type is unknown. */ - } else { - result = 0; - astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - out_type ); - } - -/* Consider conversion from "const char *". */ - } else if( raw_type == AST__STRINGTYPE ) { - cval = *( (const char **) raw ); - -/* Consider conversion to "int". */ - if( out_type == AST__INTTYPE ) { - nc = 0; - nval = astSscanf( cval, " %d %n", &ival, &nc ); - if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) { - if( out ) *( (int *) out ) = ival; - } else { - nc = 0; - nval = astSscanf( cval, " %lf %n", &dval, &nc ); - if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) { - if( out ) *( (int *) out ) = (int) ( dval + 0.5 ); - } else { - result = 0; - } - } - -/* Consider conversion to "short int". */ - } else if( out_type == AST__SINTTYPE ) { - nc = 0; - nval = astSscanf( cval, " %d %n", &ival, &nc ); - if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) { - if( out ) *( (short int *) out ) = ival; - } else { - nc = 0; - nval = astSscanf( cval, " %lf %n", &dval, &nc ); - if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) { - if( out ) *( (short int *) out ) = (int) ( dval + 0.5 ); - } else { - result = 0; - } - } - -/* Consider conversion to "byte". */ - } else if( out_type == AST__BYTETYPE ) { - nc = 0; - nval = astSscanf( cval, " %d %n", &ival, &nc ); - if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) { - if( out ) *( (unsigned char *) out ) = ival; - } else { - nc = 0; - nval = astSscanf( cval, " %lf %n", &dval, &nc ); - if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) { - if( out ) *( (unsigned char *) out ) = (int) ( dval + 0.5 ); - } else { - result = 0; - } - } - -/* Consider conversion to "double". */ - } else if( out_type == AST__DOUBLETYPE ) { - nc = 0; - nval = astSscanf( cval, " " BAD_STRING " %n", &nc ); - if( ( astSscanf( cval, " " BAD_STRING " %n", &nc ) == 0 ) && - ( nc >= (int) strlen( cval ) ) ) { - if( out ) *( (double *) out ) = AST__BAD; - - } else if( ( astSscanf( cval, " %lf %n", &dval, &nc ) == 1 ) && - ( nc >= (int) strlen( cval ) ) ) { - if( out ) *( (double *) out ) = dval; - - } else { - result = 0; - } - -/* Consider conversion to "float". */ - } else if( out_type == AST__FLOATTYPE ) { - nc = 0; - nval = astSscanf( cval, " %f %n", &fval, &nc ); - if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) { - if( out ) *( (float *) out ) = fval; - } else { - result = 0; - } - -/* Consider conversion to "const char *". */ - } else if( out_type == AST__STRINGTYPE ) { - cvalue = cval; - -/* Consider conversion to "AstObject *". */ - } else if( out_type == AST__OBJECTTYPE ) { - result = 0; - -/* Consider conversion to "void *". */ - } else if( out_type == AST__POINTERTYPE ) { - result = 0; - -/* Report an error if the data type is unknown. */ - } else { - result = 0; - astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - out_type ); - } - -/* Consider conversion from "AstObject *". */ - } else if( raw_type == AST__OBJECTTYPE ) { - -/* Consider conversion to "int". */ - if( out_type == AST__INTTYPE ) { - result = 0; - -/* Consider conversion to "short int". */ - } else if( out_type == AST__SINTTYPE ) { - result = 0; - -/* Consider conversion to "byte". */ - } else if( out_type == AST__BYTETYPE ) { - result = 0; - -/* Consider conversion to "double". */ - } else if( out_type == AST__DOUBLETYPE ) { - result = 0; - -/* Consider conversion to "float". */ - } else if( out_type == AST__FLOATTYPE ) { - result = 0; - -/* Consider conversion to "const char *". */ - } else if( out_type == AST__STRINGTYPE ) { - result = 0; - -/* Consider conversion to "AstObject *". */ - } else if( out_type == AST__OBJECTTYPE ) { - aval = *( (AstObject **) raw ); - if( out ) *( (AstObject **) out ) = aval ? astClone( aval ) : NULL; - -/* Consider conversion to "void *". */ - } else if( out_type == AST__POINTERTYPE ) { - result = 0; - -/* Report an error if the data type is unknown. */ - } else { - result = 0; - astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - out_type ); - } - -/* Consider conversion from "void *". */ - } else if( raw_type == AST__POINTERTYPE ) { - -/* Consider conversion to "int". */ - if( out_type == AST__INTTYPE ) { - result = 0; - -/* Consider conversion to "short int". */ - } else if( out_type == AST__SINTTYPE ) { - result = 0; - -/* Consider conversion to "byte". */ - } else if( out_type == AST__BYTETYPE ) { - result = 0; - -/* Consider conversion to "double". */ - } else if( out_type == AST__DOUBLETYPE ) { - result = 0; - -/* Consider conversion to "float". */ - } else if( out_type == AST__FLOATTYPE ) { - result = 0; - -/* Consider conversion to "const char *". */ - } else if( out_type == AST__STRINGTYPE ) { - result = 0; - -/* Consider conversion to "AstObject *". */ - } else if( out_type == AST__OBJECTTYPE ) { - result = 0; - -/* Consider conversion to "void *". */ - } else if( out_type == AST__POINTERTYPE ) { - if( out ) *( (void **) out ) = *( (void **) raw ); - -/* Report an error if the data type is unknown. */ - } else { - result = 0; - astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - out_type ); - } - -/* Report an error if the data type is unknown. */ - } else { - result = 0; - astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - raw_type ); - } - -/* If the output is a string, store a copy of the resulting string in - dynamically allocated memory, putting a pointer to the copy into the next - element of the "convertvalue_strings" array. (This process also de-allocates - any previously allocated memory pointed at by this "convertvalue_strings" - element, so the earlier string is effectively replaced by the new - one.) */ - if( out_type == AST__STRINGTYPE && astOK && result && cvalue ) { - result = strlen( cvalue ) + 1; - - astBeginPM; - convertvalue_strings[ convertvalue_istr ] = astStore( convertvalue_strings[ convertvalue_istr ], cvalue, - (size_t) result ); - astEndPM; - -/* If OK, return a pointer to the copy and increment "convertvalue_istr" to use the - next element of "convertvalue_strings" on the next invocation. Recycle "convertvalue_istr" to - zero when all elements have been used. */ - if ( astOK ) { - if( out ) *( (const char **) out ) = convertvalue_strings[ convertvalue_istr++ ]; - if( convertvalue_istr == ( AST__KEYMAP_CONVERTVALUE_MAX_STRINGS - 1 ) ) convertvalue_istr = 0; - } - } - -/* If an error has occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - - -static AstMapEntry *CopyMapEntry( AstMapEntry *in, int *status ){ -/* -* Name: -* CopyMapEntry - -* Purpose: -* Produces a copy of the supplied KeyMap entry. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* AstMapEntry *CopyMapEntry( AstMapEntry *in, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function creates a deep copy of the supplied KeyMap entry. - -* Parameters: -* in -* Pointer to the MapEntry to be copied. NULL may be supplied in -* which case NULL will be returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new copy. The link to the next MapEntry in the -* linked list is set NULL in the returned copy. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapEntry *result; /* Returned pointer */ - AstObject **alist; /* Pointer to list of AST object pointers */ - AstObject *obj; /* Pointer to AstObject value */ - const char **slist; /* Pointer to list of text pointers */ - const char *text; /* Pointer to text string */ - int i; /* Loop count */ - int nel; /* No. of values in entry vector (0 => scalar) */ - int type; /* Entry data type */ - size_t size; /* Size of Entry structure */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status and the supplied pointer. */ - if ( !astOK || !in ) return result; - -/* Get the size, data type and length of the MapEntry. */ - size = SizeOfEntry( in, status ); - nel = in->nel; - type = in->type; - -/* Do a byte-for-byte copy of the supplied MapEntry. */ - result = astStore( NULL, in, size ); - -/* Copy or nullify pointers in the AstMapEntry structure. */ - result->next = NULL; - result->snext = NULL; - result->sprev = NULL; - text = in->key; - result->key = text ? astStore( NULL, text, strlen( text ) + 1 ) : NULL; - text = in->comment; - result->comment = text ? astStore( NULL, text, strlen( text ) + 1 ) : NULL; - -/* Nothing further to do for undefined values. */ - if( type == AST__UNDEFTYPE ) { - -/* Next deal with string entries. */ - } else if( type == AST__STRINGTYPE ) { - -/* Scalar valued entries... */ - if( nel == 0 ) { - -/* Take a copy of the single string in the input entry. */ - text = ( (Entry0C *) in )->value; - ( (Entry0C *) result )->value = text ? astStore( NULL, text, - strlen( text ) + 1 ) : NULL; -/* Vector valued entries... */ - } else { - -/* Allocate an array to store the string pointers. */ - slist = astMalloc( sizeof(char *)*(size_t)nel ); - ( (Entry1C *) result )->value = slist; - -/* Copy the strings. */ - if( slist ) { - for( i = 0; i < nel; i++ ) { - text = ( (Entry1C *) in )->value[ i ]; - slist[ i ] = text ? astStore( NULL, text, strlen( text ) + 1 ) : NULL; - } - } - } - -/* Similarly deal with AST Object entries. */ - } else if( type == AST__OBJECTTYPE ) { - if( nel == 0 ) { - obj = ( (Entry0A *) in )->value; - ( (Entry0A *) result )->value = obj ? astCopy( obj ) : NULL; - ( (Entry0A *) result )->next = NULL; - ( (Entry0A *) result )->prev = NULL; - } else { - alist = astMalloc( sizeof(AstObject *)*(size_t)nel ); - ( (Entry1A *) result )->value = alist; - if( alist ) { - for( i = 0; i < nel; i++ ) { - obj = ( (Entry1A *) in )->value[ i ]; - alist[ i ] = obj ? astCopy( obj ) : NULL; - } - ( (Entry1A *) result )->next = NULL; - ( (Entry1A *) result )->prev = NULL; - } - } - -/* Now deal with integer entries. Scalar entries do not need any further - action. If this is a vector entry copy the values array. */ - } else if( type == AST__INTTYPE ) { - if( nel > 0 ) { - ( (Entry1I *) result )->value = astStore( NULL, - ( (Entry1I *) in )->value, - sizeof( int )*(size_t)nel ); - } - -/* Now deal with short int entries. Scalar entries do not need any further - action. If this is a vector entry copy the values array. */ - } else if( type == AST__SINTTYPE ) { - if( nel > 0 ) { - ( (Entry1S *) result )->value = astStore( NULL, - ( (Entry1S *) in )->value, - sizeof( short int )*(size_t)nel ); - } - -/* Now deal with byte entries. Scalar entries do not need any further - action. If this is a vector entry copy the values array. */ - } else if( type == AST__BYTETYPE ) { - if( nel > 0 ) { - ( (Entry1B *) result )->value = astStore( NULL, - ( (Entry1B *) in )->value, - sizeof( unsigned char )*(size_t)nel ); - } - -/* Similarly deal with floating point entries. */ - } else if( type == AST__DOUBLETYPE ) { - if( nel > 0 ) { - ( (Entry1D *) result )->value = astStore( NULL, - ( (Entry1D *) in )->value, - sizeof( double )*(size_t)nel ); - } - - } else if( type == AST__FLOATTYPE ) { - if( nel > 0 ) { - ( (Entry1F *) result )->value = astStore( NULL, - ( (Entry1F *) in )->value, - sizeof( float )*(size_t)nel ); - } - -/* Similarly deal with void pointer entries. */ - } else if( type == AST__POINTERTYPE ) { - if( nel > 0 ) { - ( (Entry1P *) result )->value = astStore( NULL, - ( (Entry1P *) in )->value, - sizeof( void * )*(size_t)nel ); - } - -/* Report an error if the data type is unknown. */ - } else { - astError( AST__INTER, "CopyMapEntry(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - type ); - } - -/* If an error has occurred, attempt to delete the returned MapEntry. */ - if( !astOK ) result = FreeMapEntry( result, status ); - -/* Return the result. */ - return result; -} - -static void CopyTableEntry( AstKeyMap *in, AstKeyMap *out, int itab, int *status ){ -/* -* Name: -* CopyTableEntry - -* Purpose: -* Produces a deep copy of a hash table element. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void CopyTableEntry( AstKeyMap *in, AstKeyMap *out, int itab, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function creates a deep copy of the linked-list of KeyMap entries -* stored in the specified element of the input KeyMaps hash table. - -* Parameters: -* in -* Pointer to the input KeyMap. -* out -* Pointer to the output KeyMap. -* itab -* Index of the hash table element to be copied. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMapEntry **link; /* Address to store foward link */ - AstMapEntry *next; /* Pointer to next Entry to copy */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* The "link" variable holds the address of the location at which the - pointer to the next copied MapEntry should be stored. Initialise this to - be the address of the required element of the output hash table. */ - link = &( out->table[ itab ] ); - -/* The "next" variable holds the address of the next MapEntry to be - copied. Initialise this to the MapEntry at the head of the linked list - associated with the specified index of the input KeyMaps hash table. */ - next = in->table[ itab ]; - -/* If the hash table element is empty, store a null pointer and pass on. */ - if( !next ) { - out->table[ itab ] = NULL; - -/* Otherwise copy the liked list. */ - } else { - -/* Loop round until we have copied all entries. */ - while( next && astOK ) { - -/* Copy the next entry, storing the resulting pointer at the position - indicated by "link". */ - *link = CopyMapEntry( next, status ); - -/* If the entry is of type AST__OBJECTTYPE, add it to the head of the - list of AST__OBJECTTYPE entries in the output KeyMap. */ - AddToObjectList( out, *link, status ); - -/* Update "link" and "next" */ - next = next->next; - link = &( (*link)->next ); - } - } - -/* Set the number of entries in the output to be the same as the input. */ - out->nentry[ itab ] = in->nentry[ itab ]; - -/* If an error has occurred, attempt to delete the returned MapEntry. */ - if( !astOK ) FreeTableEntry( out, itab, status ); -} - -static void DoubleTableSize( AstKeyMap *this, int *status ) { -/* -* Name: -* DoubleTableSize - -* Purpose: -* Double the size of the hash table in a KeyMap - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void DoubleTableSize( AstKeyMap *this, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function creates a new hash table which has twice as many -* elements as the current hash table, and moves all the entries out -* of the old table into the new table (at their new positions). - -* Parameters: -* this -* The KeyMap pointer. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMapEntry **newtable; - AstMapEntry *next; - AstMapEntry *new_next; - int *newnentry; - int bitmask; - int i; - int newi; - int newmapsize; - -/* Check the global error status. */ - if( !astOK ) return; - -/* Determine the new hash table size. Since mapsize starts out as a power - of 2 (ensured by the NewTable function), the new mapsize will also be - a power of 2. Also, create a bit mask that can be used to zero the - upper bits in a full width hash value. */ - newmapsize = 2*this->mapsize; - bitmask = newmapsize - 1; - -/* Create the new arrays, leaving the old arrays intact for the moment. */ - newtable = astMalloc( newmapsize*sizeof( AstMapEntry * ) ); - newnentry = astMalloc( newmapsize*sizeof( int ) ); - if( astOK ) { - -/* Initialise the new table. */ - for( i = 0; i < newmapsize; i++ ) { - newtable[ i ] = NULL; - newnentry[ i ] = 0; - } - -/* Loop round each of the existing table entries. */ - for( i = 0; i < this->mapsize; i++ ) { - -/* The "next" variable holds the address of the next MapEntry to be - moved. Initialise this to the MapEntry at the head of the linked list - associated with the specified index of the input KeyMaps hash table. */ - next = this->table[ i ]; - -/* Loop round until we have moved all entries. */ - while( next && astOK ) { - -/* Find the index within the new table at which to store this entry. */ - newi = ( next->hash & bitmask ); - -/* Save the pointer to the next entry following the current one in the - linked list. */ - new_next = next->next; - -/* Put a pointer to the MapEntry which is currently at the head of the - linked list in the "next" component of the current MapEntry. */ - next->next = newtable[ newi ]; - -/* Store the supplied MapEntry pointer in the requested element of the - hash table. */ - newtable[ newi ] = next; - -/* Increment the length of linked list. */ - newnentry[ newi ]++; - -/* Use the pointer to the next map entry to be moved. */ - next = new_next; - } - } - } - -/* If OK, delete the existing table and use the new table */ - if( astOK ) { - this->mapsize = newmapsize; - - (void) astFree( this->table ); - this->table = newtable; - - (void) astFree( this->nentry ); - this->nentry = newnentry; - -/* If not OK, delete the new table. */ - } else { - newtable = astFree( newtable ); - newnentry = astFree( newnentry ); - } -} - -static void DumpEntry( AstMapEntry *entry, AstChannel *channel, int nentry, int *status ) { -/* -* Name: -* DumpEntry - -* Purpose: -* Dump a single AstMapEntry to a Channel. - -* Type: -* Private function. - -* Synopsis: -* void DumpEntry( AstMapEntry *entry, AstChannel *channel, int nentry ) - -* Description: -* This function dumps the supplied MapEntry to the supplied Channel. - -* Parameters: -* entry -* Pointer to the MapEntry whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* nentry -* The integer index value to use when describing the MapEntry in -* the dump. -*/ - -/* Local Variables: */ - char buff[20]; /* Buffer for item names */ - const char *com; /* Pointer to comment string */ - int index; /* Index into vector valued entry */ - int nel; /* Number of elements in value */ - int type; /* Entry data type */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Dump the entry key. */ - (void) sprintf( buff, "Key%d", nentry ); - astWriteString( channel, buff, 1, 1, entry->key, "Item name" ); - -/* Dump the comment if not blank. */ - if( entry->comment && *(entry->comment) ) { - (void) sprintf( buff, "Com%d", nentry ); - astWriteString( channel, buff, 1, 1, entry->comment, "Item comment" ); - } - -/* Get the data type and the length of the Entry. */ - type = entry->type; - nel = entry->nel; - -/* Dump the entry data type. */ - if( type == AST__STRINGTYPE ) { - com = "Item data type (string)"; - - } else if( type == AST__OBJECTTYPE ) { - com = "Item data type (AST Object)"; - - } else if( type == AST__INTTYPE ) { - com = "Item data type (int)"; - - } else if( type == AST__SINTTYPE ) { - com = "Item data type (short int)"; - - } else if( type == AST__BYTETYPE ) { - com = "Item data type (unsigned byte)"; - - } else if( type == AST__DOUBLETYPE ) { - com = "Item data type (double)"; - - } else if( type == AST__FLOATTYPE ) { - com = "Item data type (float)"; - - } else if( type == AST__POINTERTYPE ) { - com = "Item data type (pointer)"; - - } else if( type == AST__UNDEFTYPE ) { - com = "Item data type (undefined)"; - - } else { - com = ""; - astError( AST__INTER, "DumpEntry(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - type ); - } - (void) sprintf( buff, "Typ%d", nentry ); - astWriteInt( channel, buff, 1, 1, entry->type, com ); - -/* Dump the vector length */ - if( entry->nel > 0 ) { - (void) sprintf( buff, "Nel%d", nentry ); - astWriteInt( channel, buff, 1, 1, entry->nel, "Vector length" ); - } - -/* First deal with integer entries. */ - if( type == AST__INTTYPE ) { - if( entry->nel == 0 ) { - (void) sprintf( buff, "Val%d", nentry ); - astWriteInt( channel, buff, 1, 1, ((Entry0I *)entry)->value, "Item value" ); - } else { - com = "Item values"; - for( index = 0; index < nel; index++ ){ - (void) sprintf( buff, "V%d_%d", nentry, index + 1 ); - astWriteInt( channel, buff, 1, 1, ((Entry1I *)entry)->value[ index ], com ); - com = ""; - } - } - -/* Similarly, deal with short int entries. */ - } else if( type == AST__SINTTYPE ) { - if( entry->nel == 0 ) { - (void) sprintf( buff, "Val%d", nentry ); - astWriteInt( channel, buff, 1, 1, (int) ((Entry0S *)entry)->value, "Item value" ); - } else { - com = "Item values"; - for( index = 0; index < nel; index++ ){ - (void) sprintf( buff, "V%d_%d", nentry, index + 1 ); - astWriteInt( channel, buff, 1, 1, (int) ((Entry1S *)entry)->value[ index ], com ); - com = ""; - } - } - -/* Similarly, deal with byte entries. */ - } else if( type == AST__BYTETYPE ) { - if( entry->nel == 0 ) { - (void) sprintf( buff, "Val%d", nentry ); - astWriteInt( channel, buff, 1, 1, (int) ((Entry0B *)entry)->value, "Item value" ); - } else { - com = "Item values"; - for( index = 0; index < nel; index++ ){ - (void) sprintf( buff, "V%d_%d", nentry, index + 1 ); - astWriteInt( channel, buff, 1, 1, (int) ((Entry1B *)entry)->value[ index ], com ); - com = ""; - } - } - -/* Similarly deal with floating point entries. */ - } else if( type == AST__DOUBLETYPE ) { - if( entry->nel == 0 ) { - if( ((Entry0D *)entry)->value != AST__BAD ) { - (void) sprintf( buff, "Val%d", nentry ); - astWriteDouble( channel, buff, 1, 1, ((Entry0D *)entry)->value, "Item value" ); - } - } else { - com = "Item values"; - for( index = 0; index < nel; index++ ){ - if( ((Entry1D *)entry)->value[ index ] != AST__BAD ) { - (void) sprintf( buff, "V%d_%d", nentry, index + 1 ); - astWriteDouble( channel, buff, 1, 1, ((Entry1D *)entry)->value[ index ], com ); - com = ""; - } - } - } - -/* Similarly deal with single precision floating point entries. */ - } else if( type == AST__FLOATTYPE ) { - if( entry->nel == 0 ) { - (void) sprintf( buff, "Val%d", nentry ); - astWriteDouble( channel, buff, 1, 1, (double) ((Entry0F *)entry)->value, "Item value" ); - } else { - com = "Item values"; - for( index = 0; index < nel; index++ ){ - (void) sprintf( buff, "V%d_%d", nentry, index + 1 ); - astWriteDouble( channel, buff, 1, 1, (double) ((Entry1F *)entry)->value[ index ], com ); - com = ""; - } - } - -/* Do the same for string values. */ - } else if( type == AST__STRINGTYPE ) { - if( entry->nel == 0 ) { - (void) sprintf( buff, "Val%d", nentry ); - astWriteString( channel, buff, 1, 1, ((Entry0C *)entry)->value, "Item value" ); - } else { - com = "Item values"; - for( index = 0; index < nel; index++ ){ - (void) sprintf( buff, "V%d_%d", nentry, index + 1 ); - astWriteString( channel, buff, 1, 1, ((Entry1C *)entry)->value[ index ], com ); - com = ""; - } - } - -/* Do the same for Object values. */ - } else if( type == AST__OBJECTTYPE ) { - if( entry->nel == 0 ) { - if( ((Entry0A *)entry)->value ) { - (void) sprintf( buff, "Val%d", nentry ); - astWriteObject( channel, buff, 1, 1, ((Entry0A *)entry)->value, "Item value" ); - } - } else { - com = "Item values"; - for( index = 0; index < nel; index++ ){ - if( ((Entry1A *)entry)->value[ index ] ) { - (void) sprintf( buff, "V%d_%d", nentry, index + 1 ); - astWriteObject( channel, buff, 1, 1, ((Entry1A *)entry)->value[ index ], com ); - com = ""; - } - } - } - -/* Void pointer values cannot be dumped. */ - } else if( type == AST__POINTERTYPE ) { - astError( AST__INTER, "DumpEntry(KeyMap): Cannot dump KeyMaps in " - "which the values are arbitrary C pointers (possible " - "programming error)." , status); - -/* Nothing further to do for undefined values. */ - } else if( type == AST__UNDEFTYPE ) { - -/* Report an error if the data type is unknown. */ - } else if( astOK ) { - astError( AST__INTER, "DumpEntry(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - type ); - } -} - -static AstMapEntry *FreeMapEntry( AstMapEntry *in, int *status ){ -/* -* Name: -* FreeMapEntry - -* Purpose: -* Frees the supplied KeyMap entry. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* AstMapEntry *FreeMapEntry( AstMapEntry *in, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function frees resources used by the supplied MapEntry, then -* frees the MapEntry structure itself and returns a NULL pointer. - -* Parameters: -* in -* Pointer to the MapEntry to be freed. NULL may be supplied in -* which the function returns without action. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A NULL pointer. - -* Notes: -* - It is the callers responsibility to ensure that any other MapEntry -* which refers to the supplied MapEntry (e.g. through the "next" link -* in the MapEntry structure) is modified to take account of the -* freeing of the supplied MapEntry. -* - This function attempts to execute even if it is invoked with the -* global error status set. -*/ - -/* Local Variables: */ - AstObject **alist; /* Pointer to list of AST object pointers */ - AstObject *obj; /* Pointer to AST object */ - const char **slist; /* Pointer to list of text pointers */ - int i; /* Loop count */ - int nel; /* No. of values in entry vector (0 => scalar) */ - int type; /* Entry data type */ - -/* Check the supplied pointer. */ - if( !in ) return NULL; - -/* Get the data type and length of the MapEntry. */ - nel = in->nel; - type = in->type; - -/* First deal with string entries. */ - if( type == AST__STRINGTYPE ) { - -/* For scalar valued entries, free the single string in the input entry. */ - if( nel == 0 ) { - ( (Entry0C *) in )->value = (const char *) astFree( ( void *) ( (Entry0C *) in )->value ); - -/* For vector valued entries, free the strings, then free the array storing - the string pointers. */ - } else { - slist = ( (Entry1C *) in )->value; - if( slist ) { - for( i = 0; i < nel; i++ ) slist[ i ] = astFree( (void *) slist[ i ] ); - ( (Entry1C *) in )->value = astFree( (void *) slist ); - } - } - -/* Similarly deal with AST Object entries. */ - } else if( type == AST__OBJECTTYPE ) { - if( nel == 0 ) { - obj = ( (Entry0A *) in )->value; - if( obj ) ( (Entry0A *) in )->value = astAnnul( obj ); - ( (Entry0A *) in )->next = NULL; - ( (Entry0A *) in )->prev = NULL; - } else { - alist = ( (Entry1A *) in )->value; - if( alist ) { - for( i = 0; i < nel; i++ ) { - if( alist[ i ] ) alist[ i ] = astAnnul( alist[ i ] ); - } - ( (Entry1A *) in )->value = astFree( alist ); - ( (Entry1A *) in )->next = NULL; - ( (Entry1A *) in )->prev = NULL; - } - } - -/* Now deal with integer entries. Scalar entries do not need any further - action. If this is a vector entry free the values array. */ - } else if( type == AST__INTTYPE ) { - if( nel > 0 ) ( (Entry1I *) in )->value = astFree( ( (Entry1I *) in )->value ); - -/* Now deal with short int entries. Scalar entries do not need any further - action. If this is a vector entry free the values array. */ - } else if( type == AST__SINTTYPE ) { - if( nel > 0 ) ( (Entry1S *) in )->value = astFree( ( (Entry1S *) in )->value ); - -/* Now deal with byte entries. Scalar entries do not need any further - action. If this is a vector entry free the values array. */ - } else if( type == AST__BYTETYPE ) { - if( nel > 0 ) ( (Entry1B *) in )->value = astFree( ( (Entry1B *) in )->value ); - -/* Similarly deal with void * pointer entries. */ - } else if( type == AST__POINTERTYPE ) { - if( nel > 0 ) ( (Entry1P *) in )->value = astFree( ( (Entry1P *) in )->value ); - -/* Similarly deal with floating point entries. */ - } else if( type == AST__DOUBLETYPE ) { - if( nel > 0 ) ( (Entry1D *) in )->value = astFree( ( (Entry1D *) in )->value ); - -/* Similarly deal with single precision floating point entries. */ - } else if( type == AST__FLOATTYPE ) { - if( nel > 0 ) ( (Entry1F *) in )->value = astFree( ( (Entry1F *) in )->value ); - -/* Nothing further to do for undefined values. */ - } else if( type == AST__UNDEFTYPE ) { - -/* Report an error if the data type is unknown. */ - } else { - astError( AST__INTER, "FreeMapEntry(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - type ); - } - -/* Free or nullify pointers in the AstMapEntry structure. */ - in->next = NULL; - in->snext = NULL; - in->sprev = NULL; - in->key = astFree( (void *) in->key ); - in->comment = astFree( (void *) in->comment ); - -/* Free the complete AstMapEntry structure. */ - astFree( in ); - -/* Return a NULL pointer. */ - return NULL; -} - -static void FreeTableEntry( AstKeyMap *this, int itab, int *status ){ -/* -* Name: -* FreeTableEntry - -* Purpose: -* Frees the linked list of KeyMap entries stored in a given element of -* the hash table. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void FreeTableEntry( AstKeyMap *this, int itab, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function frees resources used by all the MapEntries in the -* linked list associated with the specified element of the hash table -* of the supplied KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap -* itab -* Index of the hash table element to free. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function attempts to execute even if it is invoked with the -* global error status set. -*/ - -/* Local Variables: */ - AstMapEntry *link; /* Pointer the next but one MapEntry to be freed */ - AstMapEntry *next; /* Pointer the next MapEntry to be freed */ - -/* Check it is safe to proceed. */ - if( this && itab >= 0 && itab < this->mapsize ) { - -/* Store a pointer to the MapEntry which is to be freed next. */ - next = this->table[ itab ]; - -/* Loop round freeing all MapEntries in the linked list. */ - while( next ) { - -/* Store a pointer to the MapEntry which will be freed after this one. */ - link = next->next; - -/* Free this MapEntry */ - (void) FreeMapEntry( next, status ); - -/* Set up the next MapEntry to be freed. */ - next = link; - } - -/* Store a NULL pointer in the table element. */ - this->table[ itab ] = NULL; - -/* Sets the number of entries in this hash table element to zero. */ - this->nentry[ itab ] = 0; - } -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* KeyMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a KeyMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the KeyMap. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the KeyMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the KeyMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstKeyMap *this; /* Pointer to the KeyMap structure */ - const char *result; /* Pointer value to return */ - int ival; /* Attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the KeyMap structure. */ - this = (AstKeyMap *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* SizeGuess. */ -/* ---------- */ - if ( !strcmp( attrib, "sizeguess" ) ) { - ival = astGetSizeGuess( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* KeyCase. */ -/* --------- */ - } else if ( !strcmp( attrib, "keycase" ) ) { - ival = astGetKeyCase( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* KeyError. */ -/* --------- */ - } else if ( !strcmp( attrib, "keyerror" ) ) { - ival = astGetKeyError( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* MapLocked. */ -/* --------- */ - } else if ( !strcmp( attrib, "maplocked" ) ) { - ival = astGetMapLocked( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* SortBy. */ -/* --------- */ - } else if ( !strcmp( attrib, "sortby" ) ) { - ival = astGetSortBy( this ); - if ( astOK ) { - result = SortByString( ival, "astGetAttrib", status ); - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; - -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* KeyMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied KeyMap, -* in bytes. - -* Parameters: -* this -* Pointer to the KeyMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstKeyMap *this; /* Pointer to KeyMap structure */ - AstMapEntry *next; /* Pointer the next MapEntry */ - AstObject **alist; /* Pointer to list of AST object pointers */ - AstObject *obj; /* Pointer to AST object */ - const char **slist; /* Pointer to list of text pointers */ - int i; /* Loop count */ - int itab; /* Table entry index */ - int nel; /* No. of values in entry vector (0 => scalar) */ - int result; /* Result value to return */ - int type; /* Entry data type */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the KeyMap structure. */ - this = (AstKeyMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - for( itab = 0; itab < this->mapsize; itab++ ) { - next = this->table[ itab ]; - while( next ) { - nel = next->nel; - type = next->type; - - if( type == AST__STRINGTYPE ) { - - if( nel == 0 ) { - result += astTSizeOf( ( void *) ( (Entry0C *) next )->value ); - - } else { - slist = ( (Entry1C *) next )->value; - if( slist ) { - for( i = 0; i < nel; i++ ) result += astTSizeOf( (void *) slist[ i ] ); - result += astTSizeOf( (void *) slist ); - } - } - - } else if( type == AST__OBJECTTYPE ) { - if( nel == 0 ) { - obj = ( (Entry0A *) next )->value; - result += astGetObjSize( obj ); - } else { - alist = ( (Entry1A *) next )->value; - if( alist ) { - for( i = 0; i < nel; i++ ) { - result += astGetObjSize( alist[ i ] ); - } - result += astTSizeOf( alist ); - } - } - - } else if( type == AST__POINTERTYPE ) { - if( nel > 0 ) result += astTSizeOf( ( (Entry1P *) next )->value ); - - } else if( type == AST__INTTYPE ) { - if( nel > 0 ) result += astTSizeOf( ( (Entry1I *) next )->value ); - - } else if( type == AST__SINTTYPE ) { - if( nel > 0 ) result += astTSizeOf( ( (Entry1S *) next )->value ); - - } else if( type == AST__BYTETYPE ) { - if( nel > 0 ) result += astTSizeOf( ( (Entry1B *) next )->value ); - - } else if( type == AST__DOUBLETYPE ) { - if( nel > 0 ) result += astTSizeOf( ( (Entry1D *) next )->value ); - - } else if( type == AST__FLOATTYPE ) { - if( nel > 0 ) result += astTSizeOf( ( (Entry1F *) next )->value ); - - } else if( type == AST__UNDEFTYPE ) { - - } else { - astError( AST__INTER, "astGetObjSize(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - type ); - } - - result += astTSizeOf( (void *) next->key ); - result += astTSizeOf( (void *) next->comment ); - result += astTSizeOf( next ); - - next = next->next; - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetKey( AstKeyMap *this, int index, int *status ) { -/* -* Name: -* GetKey - -* Purpose: -* Get the key at a given index within the KeyMap. - -* Type: -* Private member function. - -* Synopsis: -* #include "keymap.h" -* const char *GetKey( AstKeyMap *this, int index, int *status ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function returns a string holding the key for the entry with -* the given index within the KeyMap. The index associated with a -* given key is determined by the current setting of the SortBy attribute. - -* Parameters: -* this -* Pointer to the KeyMap. -* index -* The index into the KeyMap. The first entry has index zero, and the last -* has index "size-1", where "size" is the value returned by the -* astMapSize function. An error is reported if the supplied index is -* out of bounds. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a null-terminated string containing the key. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the AST error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapEntry *entry; /* Pointer to the entry */ - const char *result; /* Pointer value to return */ - int ifirst; /* Index of first entry in this table element */ - int ilast; /* Index of last entry in this table element */ - int istep; /* Entry count */ - int itab; /* Index into hash table */ - int nstep; /* No. of entries to skip */ - int sortby; /* The value of the SortBy attribute */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the SortBy value. */ - sortby = astGetSortBy( this ); - -/* First deal with unsorted keys. */ - if( sortby == SORTBY_NONE ) { - -/* Loop round each entry in the hash table. */ - ilast = -1; - for( itab = 0; itab < this->mapsize; itab++ ) { - -/* Find the index of the first and the last Entry in the linked list associated - with this element of the hash table. */ - ifirst = ilast + 1; - ilast += this->nentry[ itab ]; - -/* Pass on if we have not yet reached the element containing the required - key. */ - if( ilast >= index ) { - -/* Find how many steps we need to proceed down the linked list to reach - the required index. */ - nstep = index - ifirst; - -/* Make this many steps down the linked list.*/ - entry = this->table[ itab ]; - for( istep = 0; entry && istep < nstep; istep++ ) entry = entry->next; - -/* Return a pointer to the key string, and break out of the loop. */ - if( entry ) result = entry->key; - break; - - } - } - -/* Now deal with sorted keys. */ - } else { - -/* Get a pointer to the first entry in the sorted list. */ - entry = this->first; - -/* Move up the sorted list by the required number of entries. */ - for( istep = 0; entry && istep < index; istep++ ) entry = entry->snext; - -/* Return a pointer to the key string. */ - if( entry ) result = entry->key; - } - -/* Report an error if the element was not found. */ - if( !result && astOK ) { - astError( AST__MPIND, "astMapKey(%s): Cannot find element " - "%d (zero-based) of the %s.", status, astGetClass( this ), - index, astGetClass( this ) ); - } - -/* Return the result.*/ - return result; -} - -static int GetSizeGuess( AstKeyMap *this, int *status ) { -/* -*+ -* Name: -* astGetSizeGuess - -* Purpose: -* Get the value of the SizeGuess attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* int astGetSizeGuess( AstKeyMap *this ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function returns the value of the SizeGuess attribute for a -* KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap. - -* Returned Value: -* The value of the SizeGuess attribute. - -* Notes: -* - A value of zero is returned if this function is invoked with the -* global error status set. - -*- -*/ - -/* Local Variables: */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Return the attribute value using a default if not set. */ - return ( this->sizeguess == INT_MAX ) ? - MIN_TABLE_SIZE*MAX_ENTRIES_PER_TABLE_ENTRY : this->sizeguess; -} - -static int HashFun( const char *key, int bitmask, unsigned long *hash, int *status ){ -/* -* Name: -* HashFun - -* Purpose: -* Returns an integer hash code for a string - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* int HashFun( const char *key, int bitmask, int *hash, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function returns an integer hash code for the supplied string, -* This is the value that isused as the index into the hash table for -* the specified key. - -* Parameters: -* key -* Pointer to the string. Trailing spaces are ignored. -* bitmask -* A bit mask that is used to zero the upper bits of a full width -* hash value in order to produce the required array index. This -* should be one less than the length of the hash table. -* hash -* Pointer to a location at which to put the full width hash value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* An integer in the range zero to ( mapsize - 1 ). - -* Notes: -* - A value of zero is returned if this function is invoked with the -* global error status set. -*/ - -/* Local Variables: */ - int c; - -/* Check the local error status. */ - if ( !astOK ) return 0; - -/* djb2: This hash function was first reported by Dan Bernstein many years - ago in comp.lang.c Each through the "hile" loop corresponds to - "hash = hash*33 + c ". Ignore spaces so that trailing spaces used to - pad F77 character variables will be ignored. */ - *hash = 5381; - while( (c = *key++) ) { - if( c != ' ' ) { - *hash = ((*hash << 5) + *hash) + c; - } - } - return ( *hash & bitmask ); -} - -void astInitKeyMapVtab_( AstKeyMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitKeyMapVtab - -* Purpose: -* Initialise a virtual function table for a KeyMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "keymap.h" -* void astInitKeyMapVtab( AstKeyMapVtab *vtab, const char *name ) - -* Class Membership: -* KeyMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the KeyMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitObjectVtab( (AstObjectVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAKeyMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstObjectVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - - vtab->MapGet0P = MapGet0P; - vtab->MapGet0A = MapGet0A; - vtab->MapGet0C = MapGet0C; - vtab->MapGet0D = MapGet0D; - vtab->MapGet0F = MapGet0F; - vtab->MapGet0I = MapGet0I; - vtab->MapGet0B = MapGet0B; - vtab->MapGet0S = MapGet0S; - vtab->MapGet1P = MapGet1P; - vtab->MapGet1A = MapGet1A; - vtab->MapGet1C = MapGet1C; - vtab->MapGet1D = MapGet1D; - vtab->MapGet1F = MapGet1F; - vtab->MapGet1I = MapGet1I; - vtab->MapGet1B = MapGet1B; - vtab->MapGet1S = MapGet1S; - vtab->MapGetC = MapGetC; - vtab->MapGetElemP = MapGetElemP; - vtab->MapGetElemA = MapGetElemA; - vtab->MapGetElemC = MapGetElemC; - vtab->MapGetElemD = MapGetElemD; - vtab->MapGetElemF = MapGetElemF; - vtab->MapGetElemI = MapGetElemI; - vtab->MapGetElemS = MapGetElemS; - vtab->MapGetElemB = MapGetElemB; - vtab->MapPutElemP = MapPutElemP; - vtab->MapPutElemA = MapPutElemA; - vtab->MapPutElemC = MapPutElemC; - vtab->MapPutElemD = MapPutElemD; - vtab->MapPutElemF = MapPutElemF; - vtab->MapPutElemI = MapPutElemI; - vtab->MapPutElemS = MapPutElemS; - vtab->MapPutElemB = MapPutElemB; - vtab->MapPut0A = MapPut0A; - vtab->MapPut0P = MapPut0P; - vtab->MapPut0C = MapPut0C; - vtab->MapPut0D = MapPut0D; - vtab->MapPut0F = MapPut0F; - vtab->MapPut0I = MapPut0I; - vtab->MapPut0S = MapPut0S; - vtab->MapPut0B = MapPut0B; - vtab->MapPut1P = MapPut1P; - vtab->MapPut1A = MapPut1A; - vtab->MapPut1C = MapPut1C; - vtab->MapPut1D = MapPut1D; - vtab->MapPut1F = MapPut1F; - vtab->MapPut1I = MapPut1I; - vtab->MapPut1S = MapPut1S; - vtab->MapPut1B = MapPut1B; - vtab->MapPutU = MapPutU; - vtab->MapRemove = MapRemove; - vtab->MapRename = MapRename; - vtab->MapCopy = MapCopy; - vtab->MapDefined = MapDefined; - vtab->MapSize = MapSize; - vtab->MapLenC = MapLenC; - vtab->MapLength = MapLength; - vtab->MapType = MapType; - vtab->MapHasKey = MapHasKey; - vtab->MapKey = MapKey; - vtab->MapIterate = MapIterate; - - vtab->ClearSizeGuess = ClearSizeGuess; - vtab->SetSizeGuess = SetSizeGuess; - vtab->GetSizeGuess = GetSizeGuess; - vtab->TestSizeGuess = TestSizeGuess; - - vtab->ClearSortBy = ClearSortBy; - vtab->SetSortBy = SetSortBy; - vtab->GetSortBy = GetSortBy; - vtab->TestSortBy = TestSortBy; - - vtab->ClearKeyError = ClearKeyError; - vtab->SetKeyError = SetKeyError; - vtab->GetKeyError = GetKeyError; - vtab->TestKeyError = TestKeyError; - - vtab->ClearKeyCase = ClearKeyCase; - vtab->SetKeyCase = SetKeyCase; - vtab->GetKeyCase = GetKeyCase; - vtab->TestKeyCase = TestKeyCase; - - vtab->ClearMapLocked = ClearMapLocked; - vtab->SetMapLocked = SetMapLocked; - vtab->GetMapLocked = GetMapLocked; - vtab->TestMapLocked = TestMapLocked; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - -/* Declare the destructor, copy constructor and dump function. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "KeyMap", "Map of key/value pairs" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void InitMapEntry( AstMapEntry *entry, int type, int nel, int *status ){ -/* -* Name: -* InitMapEntry - -* Purpose: -* initialise a MapEntry structure to null values. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void InitMapEntry( AstMapEntry *entry, int type, int nel, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function initialises the contents of a MapEntry to null values. - -* Parameters: -* this -* Pointer to the MapEntry. -* type -* The type of the MapEntry. -* nel -* The number of elements in the entry: 0 = scalar, >0 = vector. -* status -* Pointer to the inherited status variable. - -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Initialise all elements with in the MapEntry structure. */ - entry->next = NULL; - entry->key = NULL; - entry->hash = 0; - entry->type = type; - entry->nel = nel; - entry->comment = NULL; - entry->defined = 0; - entry->snext = NULL; - entry->sprev = NULL; - entry->member = 0; - entry->keymember = 0; - entry->sortby = SORTBY_NONE; - - if( type == AST__OBJECTTYPE ) { - if( nel == 0 ) { - ( (Entry0A *) entry )->next = NULL; - ( (Entry0A *) entry )->prev = NULL; - } else { - ( (Entry1A *) entry )->next = NULL; - ( (Entry1A *) entry )->prev = NULL; - } - } - -} - -static int KeyCmp( const char *key1, const char *key2 ) { -/* -* Name: -* KeyCmp - -* Purpose: -* Compares keys for equality. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* int KeyCmp( const char *key1, const char *key2 ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function compares two strings. It is like strcmp except that it -* ignores trailing spaces. - -* Parameters: -* key1 -* Pointer to first string. -* key2 -* Pointer to second string. - -* Returned Value: -* One if the keys differ. Zero if they are identical (except for -* trailing spaces). - -*/ - -/* Local Variables: */ - const char *k1; /* Pointer to next "key1" character */ - const char *k2; /* Pointer to next "key2" character */ - int result; /* Returned flag */ - -/* Check the strings are deifned. */ - if ( !key1 || !key2 ) return 0; - -/* Get pointers to the first characters to differ, or to the first null - character, which ever comes first. */ - k1 = key1; - k2 = key2; - while( *k1 && ( *k1 == *k2 ) ) { - k1++; - k2++; - } - -/* If both characters are null, the strings are identical. If neither is null, - the string definitely differ. If one is null, we need to check if the - other one only has spaces to the end of the string. */ - if( *k1 ) { - if( *k2 ) { - result = ( *k1 > *k2 ) ? 1 : -1; - } else { - while( *k1 == ' ' ) k1++; - result = ( *k1 == 0 ) ? 0 : 1; - } - } else { - if( *k2 ) { - while( *k2 == ' ' ) k2++; - result = ( *k2 == 0 ) ? 0 : -1; - } else { - result = 0; - } - } - -/* Return the result. */ - return result; -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* KeyMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstKeyMap *this; /* Pointer to KeyMap structure */ - AstMapEntry *next; /* Pointer the next MapEntry */ - AstObject **alist; /* Pointer to list of AST object pointers */ - AstObject *obj; /* Pointer to AST object */ - int i; /* Loop count */ - int nel; /* No. of values in entry vector (0 => scalar) */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the KeyMap structure. */ - this = (AstKeyMap *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - - next = this->firstA; - while( next ) { - nel = next->nel; - if( nel == 0 ) { - obj = ( (Entry0A *) next )->value; - if( !result ) result = astManageLock( obj, mode, extra, fail ); - next = ( (Entry0A *) next)->next; - } else { - alist = ( (Entry1A *) next )->value; - if( alist ) { - for( i = 0; i < nel; i++ ) { - if( !result ) result = astManageLock( alist[ i ], mode, - extra, fail ); - } - } - next = ( (Entry1A *) next)->next; - } - } - - return result; - -} -#endif - -static void MapCopy( AstKeyMap *this, AstKeyMap *that, int *status ) { -/* -*++ -* Name: -c astMapCopy -f AST_MAPCOPY - -* Purpose: -* Copy entries from one KeyMap into another. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "keymap.h" -c void astMapCopy( AstKeyMap *this, AstKeyMap *that ) -f CALL AST_MAPCOPY( THIS, THAT, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -c This function -f This routine -* copies all entries from one KeyMap into another. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the destination KeyMap. -c that -f THAT = INTEGER (Given) -* Pointer to the source KeyMap. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Entries from the source KeyMap will replace any existing entries in -* the destination KeyMap that have the same key. -* - The one exception to the above rule is that if a source entry -* contains a scalar KeyMap entry, and the destination contains a -* scalar KeyMap entry with the same key, then the source KeyMap entry -* will be copied into the destination KeyMap entry using this function, -* rather than simply replacing the destination KeyMap entry. -* - If the destination entry has a non-zero value for its MapLocked -* attribute, then an error will be reported if the source KeyMap -* contains any keys that do not already exist within the destination -* KeyMap. - -*-- -*/ - -/* Local Variables: */ - AstMapEntry *in_entry; /* Pointer to next source entry to copy */ - AstMapEntry *out_entry;/* Pointer to existing destination entry */ - AstObject *in_obj; /* Pointer for source Object entry */ - AstObject *out_obj; /* Pointer for destination Object entry */ - const char *key; /* Key for current entry */ - int i; /* Index into source hash table */ - int itab; /* Index of destination hash table element */ - int keymember; /* Identifier for key */ - int merged; /* Were source and destination KeyMaps merged? */ - unsigned long hash; /* Full width hash value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Loop round all entries in the source hash table. */ - for( i = 0; i < that->mapsize; i++ ) { - -/* Get a pointer to the next source KeyMap entry. */ - in_entry = that->table[ i ]; - -/* Loop round all entries in this element of the source hash table. */ - while( in_entry && astOK ) { - -/* Get its key. */ - key = in_entry->key; - -/* Search for a destination entry with the same key. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - out_entry = SearchTableEntry( this, itab, key, status ); - -/* If the destination KeyMap does not contain an entry with the current - key, store a copy of the entry in the destination, or report an error - if the destination's MapLocked attribute is set. */ - if( !out_entry ) { - if( astGetMapLocked( this ) ) { - astError( AST__BADKEY, "astMapCopy(%s): Failed to copy " - "item \"%s\": \"%s\" is not a known item.", status, - astGetClass( this ), key, key ); - } else { - out_entry = CopyMapEntry( in_entry, status ); - out_entry = AddTableEntry( this, itab, out_entry, -1, status ); - } - -/* If the destination KeyMap contains an entry with the current key... */ - } else { - -/* The usual thing is to just replace the existing entry in the - destination with a copy of the source entry. The one case where this is - not done is if both entries are scalar KeyMaps. In this case the source - KeyMap is merged into the destination KeyMap using this function. First - see if we have this situation, and if so, copy the entries from the - source KeyMap to the destination KeyMap. */ - merged = 0; - if( in_entry->nel == 0 || in_entry->nel == 1 ) { - if( out_entry->nel == 0 || out_entry->nel == 1 ) { - if( in_entry->type == AST__OBJECTTYPE && - out_entry->type == AST__OBJECTTYPE ) { - - if( in_entry->nel == 0 ) { - in_obj = ((Entry0A *)in_entry)->value; - } else { - in_obj = (((Entry1A *)in_entry)->value)[ 0 ]; - } - - if( out_entry->nel == 0 ) { - out_obj = ((Entry0A *)out_entry)->value; - } else { - out_obj = (((Entry1A *)out_entry)->value)[ 0 ]; - } - - if( astIsAKeyMap( in_obj ) && - astIsAKeyMap( out_obj ) ) { - astMapCopy( (AstKeyMap *) out_obj, - (AstKeyMap *) in_obj ); - merged = 1; - } - } - } - } - -/* If the source and desination entries are not KeyMaps, then just remove - the entry in the desination KeyMap and add a copy of the source entry. - But retain the original keymember value since we are just changing the - value of an existing key. */ - if( ! merged ) { - out_entry = RemoveTableEntry( this, itab, key, status ); - keymember = out_entry->keymember; - (void) FreeMapEntry( out_entry, status ); - out_entry = CopyMapEntry( in_entry, status ); - out_entry = AddTableEntry( this, itab, out_entry, keymember, status ); - } - } - -/* Update the address of the next MapEntry in the source. */ - in_entry = in_entry->next; - } - } -} - -static const char *MapKey( AstKeyMap *this, int index, int *status ) { -/* -*++ -* Name: -c astMapKey -f AST_MAPKEY - -* Purpose: -* Get the key at a given index within the KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "keymap.h" -c const char *astMapKey( AstKeyMap *this, int index ) -f RESULT = AST_MAPKEY( THIS, INDEX, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function returns a string holding the key for the entry with -* the given index within the KeyMap. -* -* This function is intended primarily as a means of iterating round all -* the elements in a KeyMap. For this purpose, the number of entries in -* the KeyMap should first be found using -c astMapSize -f AST_MAPSIZE -* and this function should then be called in a loop, with the index -* value going from -c zero to one less than the size of the KeyMap. -f one to the size of the KeyMap. -* The index associated with a given entry is determined by the SortBy -* attribute. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c index -f INDEX = INTEGER (Given) -* The index into the KeyMap. The first entry has index -c zero, and the last has index "size-1", where "size" is the value -c returned by the astMapSize function. -f one, and the last has index SIZE, the value returned by the -f AST_MAPSIZE function. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapKey() -c A pointer to a null-terminated string containing the key. -f AST_MAPKEY = CHARACTER * ( AST__SZCHR ) -f The key value. - -* Notes: -c - The returned pointer is guaranteed to remain valid and the -c string to which it points will not be over-written for a total -c of 50 successive invocations of this function. After this, the -c memory containing the string may be re-used, so a copy of the -c string should be made if it is needed for longer than this. -c - A NULL pointer will be returned if this function is invoked -c with the AST error status set, or if it should fail for any -c reason. -f - A blank string will be returned if this function is invoked -f with STATUS set to an error value, or if it should fail for any -f reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *result; /* Pointer value to return */ - const char *value; /* Pointer to key value */ - int i; /* Loop counter for initialisation */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* If the "mapkey_strings" array has not been initialised, fill it with - NULL pointers. */ - if ( !mapkey_init ) { - mapkey_init = 1; - for ( i = 0; i < AST__KEYMAP_MAPKEY_MAX_STRINGS; i++ ) mapkey_strings[ i ] = NULL; - } - -/* Obtain a pointer to the required key value. */ - value = GetKey( this, index, status ); - -/* If OK, store a copy of the resulting string in dynamically - allocated memory, putting a pointer to the copy into the next - element of the "mapkey_strings" array. (This process also de-allocates - any previously allocated memory pointed at by this "mapkey_strings" - element, so the earlier string is effectively replaced by the new - one.) */ - if ( astOK ) { - astBeginPM; - mapkey_strings[ mapkey_istr ] = astStore( mapkey_strings[ mapkey_istr ], value, - strlen( value ) + (size_t) 1 ); - astEndPM; - -/* If OK, return a pointer to the copy and increment "mapkey_istr" to use the - next element of "mapkey_strings" on the next invocation. Recycle "mapkey_istr" to - zero when all elements have been used. */ - if ( astOK ) { - result = mapkey_strings[ mapkey_istr++ ]; - if ( mapkey_istr == ( AST__KEYMAP_MAPKEY_MAX_STRINGS - 1 ) ) mapkey_istr = 0; - } - } - -/* Return the result. */ - return result; - -} - -/* -*++ -* Name: -c astMapPut0 -f AST_MAPPUT0 - -* Purpose: -* Add a scalar value to a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ast.h" -c void astMapPut0( AstKeyMap *this, const char *key, type value, -c const char *comment ); -f CALL AST_MAPPUT0( THIS, KEY, VALUE, COMMENT, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -c This is a set of functions -f This is a set of routine -* for adding scalar values to a KeyMap. You should use a -c function -f routine -* which matches the data type of the data you wish to add to the KeyMap -* by replacing in the generic -c function name astMapPut0 -f routine name AST_MAPPUT0 -* by an appropriate 1-character type code (see the "Data Type Codes" -* section below for the code appropriate to each supported data type). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap in which to store the supplied value. -c key -f KEY = CHARACTER * ( * ) (Given) -* A character string to be stored with the value, which can later -* be used to identify the value. Trailing spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -c value -f VALUE = type (Given) -* The value to be stored. The data type of this value should match the -* 1-character type code appended to the -c function name (e.g. if you are using astMapPut0A, the type of this -c value should be "pointer to AstObject"). -f routine name (e.g. if you are using AST_MAPPUT0A, the type of this -f value should be "integer pointer for an AstObject"). -c comment -f COMMENT = CHARACTER * ( * ) (Given) -f A comment string to be stored with the value. -c A pointer to a null-terminated comment string to be stored with the -c value. A NULL pointer may be supplied, in which case no comment is -c stored. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the supplied key is already in use in the KeyMap, the new value -* will replace the old value. -* - If the stored value is an AST Object pointer, the Object's reference -* count is incremented by this call. Any subsequent changes made to -* the Object using the returned pointer will be reflected in any -* any other active pointers for the Object, including any obtained -* later using -c astMapget0A. -f AST_MAPGET0A. -* The reference count for the Object will be decremented when the -* KeyMap is destroyed, or the entry is removed or over-written with a -* different pointer. - -* Data Type Codes: -* To select the appropriate -c function, you should replace in the generic function name astMapPut0 -f routine, you should replace in the generic routine name AST_MAPPUT0 -* with a 1-character data type code, so as to match the data type type -* of the data you are processing, as follows: -c - D: double -c - F: float -c - I: int -c - C: "const" pointer to null terminated character string -c - A: Pointer to AstObject -c - P: Generic "void *" pointer -c - S: short int -c - B: unsigned byte (i.e. unsigned char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - C: CHARACTER -f - A: INTEGER used to identify an AstObject -f - S: INTEGER*2 (short integer) -f - B: Unsigned byte -* -c For example, astMapPut0D would be used to store a "double" value, -c while astMapPut0I would be used to store an "int", etc. -f For example, AST_MAPPUT0D would be used to store a DOUBLE PRECISION value, -f while AST_MAPPUT0I would be used to store an INTEGER, etc. -c -c Note that KeyMaps containing generic "void *" pointers cannot be -c written out using astShow or astWrite. An error will be reported if -c this is attempted. -*-- -*/ -/* Define a macro to implement the function for a specific data type. */ -#define MAKE_MAPPUT0(X,Xtype,Itype,ValExp) \ -static void MapPut0##X( AstKeyMap *this, const char *skey, Xtype value, \ - const char *comment, int *status ) { \ -\ -/* Local Variables: */ \ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \ - AstMapEntry *oldent; /* Pointer to existing MapEntry */ \ - Entry0##X *entry; /* Structure holding the data for the new Entry */ \ - const char *key; /* Pointer to key string to use */ \ - char *p; /* Pointer to next key character */ \ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - int itab; /* Index of hash table element to use */ \ - int keylen; /* Length of supplied key string */ \ - int keymember; /* Identifier for existing key */ \ - int there; /* Did the entry already exist in the KeyMap? */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Perform any necessary checks on the supplied value to be stored. */ \ - CHECK_##X \ -\ -/* Convert the supplied key to upper case if required. */ \ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPut0" #X, \ - status ); \ -\ -/* Allocate memory for the new MapEntry. */ \ - entry = astMalloc( sizeof( Entry0##X ) ); \ - if( astOK ) { \ -\ -/* Initialise the new structure.*/ \ - mapentry = (AstMapEntry *) entry; \ - InitMapEntry( mapentry, Itype, 0, status ); \ -\ -/* Now store the new values. */ \ - keylen = strlen( key ); \ - mapentry->key = astStore( NULL, key, keylen + 1 ); \ - if( comment ) mapentry->comment = astStore( NULL, comment, strlen( comment ) + 1 ); \ - mapentry->defined = 1; \ - entry->value = ValExp; \ -\ -/* Terminate the key string to exclude any trailing spaces. */ \ - if( astOK ) { \ - p = (char *) mapentry->key + keylen; \ - while( --p >= mapentry->key ) { \ - if( *p == ' ' ) { \ - *p = 0; \ - } else { \ - break; \ - } \ - } \ - } \ -\ -/* Use the hash function to determine the element of the hash table in \ - which to store the new entry. */ \ - itab = HashFun( mapentry->key, this->mapsize - 1, &(mapentry->hash), status ); \ -\ -/* Remove any existing entry with the given key from the table element. \ - First save the key identifier. */ \ - oldent = RemoveTableEntry( this, itab, mapentry->key, status ); \ - if( oldent ) { \ - keymember = oldent->keymember; \ - oldent = FreeMapEntry( oldent, status ); \ - there = 1; \ - } else { \ - keymember = -1; \ - there = 0; \ - } \ -\ -/* If the KeyMap is locked we report an error if an attempt is made to add a value for \ - a new key. */ \ - if( !there && astGetMapLocked( this ) ) { \ - astError( AST__BADKEY, "astMapPut0" #X "(%s): Failed to add item \"%s\" to a KeyMap: " \ - "\"%s\" is not a known item.", status, astGetClass( this ), key, key ); \ - } \ -\ -/* If all has gone OK, store the new entry at the head of the linked list \ - associated with the selected table entry. */ \ - if( astOK ) { \ - mapentry = AddTableEntry( this, itab, mapentry, keymember, status ); \ -\ -/* If anything went wrong, try to delete the new entry. */ \ - } else { \ - mapentry = FreeMapEntry( mapentry, status ); \ - } \ - } \ -} - -/* Define macros which perform any necessary checks on the supplied value - to be stored. For Object entries, check that we are not adding a KeyMap - which already contains "this". This avoids circular dependencies. - Other types do not need any checks. */ -#define CHECK_A CheckCircle( this, value, "astMapPut0A", status ); -#define CHECK_I -#define CHECK_D -#define CHECK_F -#define CHECK_C -#define CHECK_P -#define CHECK_S -#define CHECK_B - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPPUT0(I,int,AST__INTTYPE,value) -MAKE_MAPPUT0(D,double,AST__DOUBLETYPE,value) -MAKE_MAPPUT0(F,float,AST__FLOATTYPE,value) -MAKE_MAPPUT0(C,const char *,AST__STRINGTYPE,astStore(NULL,value,strlen(value)+1)) -MAKE_MAPPUT0(A,AstObject *,AST__OBJECTTYPE,(value?astClone(value):NULL)) -MAKE_MAPPUT0(P,void *,AST__POINTERTYPE,value) -MAKE_MAPPUT0(S,short int,AST__SINTTYPE,value) -MAKE_MAPPUT0(B,unsigned char,AST__BYTETYPE,value) - -/* Undefine the macro. */ -#undef MAKE_MAPPUT0 -#undef CHECK_A -#undef CHECK_I -#undef CHECK_S -#undef CHECK_D -#undef CHECK_F -#undef CHECK_C -#undef CHECK_P -#undef CHECK_B - -/* -*++ -* Name: -c astMapPut1 -f AST_MAPPUT1 - -* Purpose: -* Add a vector value to a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ast.h" -c void astMapPut1( AstKeyMap *this, const char *key, int size, -c const type value[], const char *comment ); -f CALL AST_MAPPUT1( THIS, KEY, SIZE, VALUE, COMMENT, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -c This is a set of functions -f This is a set of routine -* for adding vector values to a KeyMap. You should use a -c function -f routine -* which matches the data type of the data you wish to add to the KeyMap -* by replacing in the generic -c function name astMapPut1 -f routine name AST_MAPPUT1 -* by an appropriate 1-character type code (see the "Data Type Codes" -* section below for the code appropriate to each supported data type). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap in which to store the supplied values. -c key -f KEY = CHARACTER * ( * ) (Given) -* A character string to be stored with the values, which can later -* be used to identify the values. Trailing spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -c size -f SIZE = INTEGER (Given) -* The number of elements in the supplied array of values. -c value -f VALUE( * ) = type (Given) -* The array of values to be stored. The data type of this value should -* match the 1-character type code appended to the -c function name (e.g. if you are using astMapPut1A, the type of this -c value should be "array of pointers to AstObject"). -f routine name (e.g. if you are using AST_MAPPUT1A, the type of this -f value should be "integer pointer for an AstObject)". -c comment -f COMMENT = CHARACTER * ( * ) (Given) -f A comment string to be stored with the values. -c A pointer to a null-terminated comment string to be stored with the -c values. A NULL pointer may be supplied, in which case no comment is -c stored. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the supplied key is already in use in the KeyMap, the new values -* will replace the old values. - -* Data Type Codes: -* To select the appropriate -c function, you should replace in the generic function name astMapPut1 -f routine, you should replace in the generic routine name AST_MAPPUT1 -* with a 1-character data type code, so as to match the data type type -* of the data you are processing, as follows: -c - D: double -c - F: float -c - I: int -c - C: "const" pointer to null terminated character string -c - A: Pointer to AstObject -c - P: Generic "void *" pointer -c - S: short int -c - B: Unsigned byte (i.e. char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - C: CHARACTER -f - A: INTEGER used to identify an AstObject -f - S: INTEGER*2 (short integer) -f - B: Unsigned byte -* -c For example, astMapPut1D would be used to store "double" values, -c while astMapPut1I would be used to store "int", etc. -f For example, AST_MAPPUT1D would be used to store DOUBLE PRECISION values, -f while AST_MAPPUT1I would be used to store INTEGER, etc. -c -c Note that KeyMaps containing generic "void *" pointers cannot be -c written out using astShow or astWrite. An error will be reported if -c this is attempted. -*-- -*/ -/* Define a macro to implement the function for a specific data type. */ -#define MAKE_MAPPUT1(X,Xtype,Itype,ValExp) \ -static void MapPut1##X( AstKeyMap *this, const char *skey, int size, \ - Xtype value[], const char *comment, \ - int *status ) { \ -\ -/* Local Variables: */ \ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \ - AstMapEntry *oldent; /* Pointer to existing MapEntry */ \ - Entry1##X *entry; /* Structure holding the data for the new Entry */ \ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - const char *key; /* Pointer to key string to use */ \ - char *p; /* Pointer to next key character */ \ - int itab; /* Index of hash table element to use */ \ - int i; /* Loop count */ \ - int keylen; /* Length of supplied key string */ \ - int keymember; /* Identifier for existing key */ \ - int there; /* Did the entry already exist in the KeyMap? */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Perform any necessary checks on the supplied value to be stored. */ \ - CHECK_##X \ -\ -/* Convert the supplied key to upper case if required. */ \ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPut1" #X, \ - status ); \ -\ -/* Allocate memory for the new MapEntry. */ \ - entry = astMalloc( sizeof( Entry1##X ) ); \ - if( astOK ) { \ -\ -/* Initialise the new structure.*/ \ - mapentry = (AstMapEntry *) entry; \ - InitMapEntry( mapentry, Itype, size, status ); \ -\ -/* Now store the new values. */ \ - keylen = strlen( key ); \ - mapentry->key = astStore( NULL, key, keylen + 1 ); \ - if( comment ) mapentry->comment = astStore( NULL, comment, strlen( comment ) + 1 ); \ - mapentry->defined = 1; \ - entry->value = astMalloc( sizeof( Xtype )*(size_t)size ); \ -\ - if( astOK ) { \ - for( i = 0; i < size; i++ ) { \ - entry->value[ i ] = ValExp; \ - } \ -\ -/* Terminate the key string to exclude any trailing spaces. */ \ - p = (char *) mapentry->key + keylen; \ - while( --p >= mapentry->key ) { \ - if( *p == ' ' ) { \ - *p = 0; \ - } else { \ - break; \ - } \ - } \ - } \ -\ -/* Use the hash function to determine the element of the hash table in \ - which to store the new entry. */ \ - itab = HashFun( mapentry->key, this->mapsize - 1, &(mapentry->hash), status ); \ -\ -/* Remove any existing entry with the given key from the table element. \ - First save the key identifier. */ \ - oldent = RemoveTableEntry( this, itab, mapentry->key, status ); \ - if( oldent ) { \ - keymember = oldent->keymember; \ - oldent = FreeMapEntry( oldent, status ); \ - there = 1; \ - } else { \ - keymember = -1; \ - there = 0; \ - } \ -\ -/* If the KeyMap is locked we report an error if an attempt is made to add a value for \ - a new key. */ \ - if( !there && astGetMapLocked( this ) ) { \ - astError( AST__BADKEY, "astMapPut1" #X "(%s): Failed to add item \"%s\" to a KeyMap: " \ - "\"%s\" is not a known item.", status, astGetClass( this ), key, key ); \ - } \ -\ -/* If all has gone OK, store the new entry at the head of the linked list \ - associated with the selected table entry. */ \ - if( astOK ) { \ - mapentry = AddTableEntry( this, itab, mapentry, keymember, status ); \ -\ -/* If anything went wrong, try to delete the new entry. */ \ - } else { \ - mapentry = FreeMapEntry( mapentry, status ); \ - } \ - } \ -} - -/* Define macros which perform any necessary checks on the supplied values - to be stored. For Object entries, check that we are not adding a KeyMap - which already contains "this". This avoids circular dependencies. - Other types do not need any checks. */ -#define CHECK_A \ -for( i = 0; i < size; i++ ) { \ - CheckCircle( this, value[ i ], "astMapPut1A", status ); \ -} -#define CHECK_I -#define CHECK_S -#define CHECK_B -#define CHECK_D -#define CHECK_F -#define CHECK_C -#define CHECK_P - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPPUT1(D,const double,AST__DOUBLETYPE,value[i]) -MAKE_MAPPUT1(F,const float,AST__FLOATTYPE,value[i]) -MAKE_MAPPUT1(I,const int,AST__INTTYPE,value[i]) -MAKE_MAPPUT1(C,const char *const,AST__STRINGTYPE,astStore(NULL,value[i],strlen(value[i])+1)) -MAKE_MAPPUT1(A,AstObject *const,AST__OBJECTTYPE,(value[i]?astClone(value[i]):NULL)) -MAKE_MAPPUT1(P,void *const,AST__POINTERTYPE,value[i]) -MAKE_MAPPUT1(S,const short int,AST__SINTTYPE,value[i]) -MAKE_MAPPUT1(B,const unsigned char,AST__BYTETYPE,value[i]) - -/* Undefine the macro. */ -#undef MAKE_MAPPUT1 -#undef CHECK_A -#undef CHECK_I -#undef CHECK_B -#undef CHECK_S -#undef CHECK_D -#undef CHECK_F -#undef CHECK_C -#undef CHECK_P - -void astMapPut1AId_( AstKeyMap *this, const char *skey, int size, - AstObject *const value[], const char *comment, - int *status ) { -/* -* Name: -* astMapPut1AId_ - -* Purpose: -* Add a vector of AstObject pointers to a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "ast.h" -* void astMapPut1A( AstKeyMap *this, const char *key, int size, -* AstObject *const value[], const char *comment ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is the public implementation of the astMapPut1A function -* It is identical to astMapPut1A_ except that ID values are supplied -* via the "value" parameter instead of a true C pointers. - -* Parameters: -* (see astMapPut1) - -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ - AstMapEntry *oldent; /* Pointer to existing MapEntry */ - AstObject *op; /* Object pointer */ - Entry1A *entry; /* Structure holding the data for the new Entry */ - char *p; /* Pointer to next key character */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - const char *key; /* Pointer to key string to use */ \ - int i; /* Loop count */ - int itab; /* Index of hash table element to use */ - int keylen; /* Length of supplied key string */ - int keymember; /* Identifier for existing key */ - int there; /* Did the entry already exist in the KeyMap? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPut1A", - status ); - -/* Allocate memory for the new MapEntry. */ - entry = astMalloc( sizeof( Entry1A ) ); - if( astOK ) { - -/* Initialise the new structure.*/ - mapentry = (AstMapEntry *) entry; - InitMapEntry( mapentry, AST__OBJECTTYPE, size, status ); - -/* Now store the new values. */ - keylen = strlen( key ); - mapentry->key = astStore( NULL, key, keylen + 1 ); - if( comment ) mapentry->comment = astStore( NULL, comment, strlen( comment ) + 1 ); - mapentry->defined = 1; - entry->value = astMalloc( sizeof( AstObject * )*(size_t)size ); - - if( astOK ) { - for( i = 0; i < size; i++ ) { - op = value[ i ] ? astMakePointer( value[ i ] ) : NULL; - entry->value[ i ] = op ? astClone( op ) : NULL; - } - -/* Terminate the key string to exclude any trailing spaces. */ \ - p = (char *) mapentry->key + keylen; - while( --p >= mapentry->key ) { - if( *p == ' ' ) { - *p = 0; - } else { - break; - } - } - } - -/* Use the hash function to determine the element of the hash table in - which to store the new entry. */ - itab = HashFun( mapentry->key, this->mapsize - 1, &(mapentry->hash), status ); - -/* Remove any existing entry with the given key from the table element. */ - oldent = RemoveTableEntry( this, itab, mapentry->key, status ); - if( oldent ) { - keymember = oldent->keymember; - oldent = FreeMapEntry( oldent, status ); - there = 1; - } else { - there = 0; - keymember = -1; - } - -/* If the KeyMap is locked we report an error if an attempt is made to add a value for - a new key. */ - if( !there && astGetMapLocked( this ) ) { - astError( AST__BADKEY, "astMapPut1A(%s): Failed to add item \"%s\" to a KeyMap: " - "\"%s\" is not a known item.", status, astGetClass( this ), key, key ); - } - -/* If all has gone OK, store the new entry at the head of the linked list - associated with the selected table entry. */ - if( astOK ) { - mapentry = AddTableEntry( this, itab, mapentry, keymember, status ); - -/* If anything went wrong, try to delete the new entry. */ - } else { - mapentry = FreeMapEntry( mapentry, status ); - } - } -} - -static void MapPutU( AstKeyMap *this, const char *skey, const char *comment, - int *status ) { -/* -*++ -* Name: -c astMapPutU -f AST_MAPPUTU - -* Purpose: -* Add an entry to a KeyMap with an undefined value. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ast.h" -c void astMapPutU( AstKeyMap *this, const char *key, const char *comment ); -f CALL AST_MAPPUTU( THIS, KEY, COMMENT, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -c This function -f This routine -* adds a new entry to a KeyMap, but no value is stored with the -* entry. The entry therefore has a special data type represented by -* symbolic constant AST__UNDEFTYPE. -* -* An example use is to add entries with undefined values to a KeyMap -* prior to locking them with the MapLocked attribute. Such entries -* can act as placeholders for values that can be added to the KeyMap -* later. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap in which to store the supplied value. -c key -f KEY = CHARACTER * ( * ) (Given) -* A character string to be stored with the value, which can later -* be used to identify the value. Trailing spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -c comment -f COMMENT = CHARACTER * ( * ) (Given) -f A comment string to be stored with the value. -c A pointer to a null-terminated comment string to be stored with the -c value. A NULL pointer may be supplied, in which case no comment is -c stored. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the supplied key is already in use in the KeyMap, the value -* associated with the key will be removed. - -*-- -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ - AstMapEntry *oldent; /* Pointer to existing MapEntry */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - const char *key; /* Pointer to key string to use */ - char *p; /* Pointer to next key character */ - int itab; /* Index of hash table element to use */ - int keylen; /* Length of supplied key string */ - int keymember; /* Identifier for existing key */ - int there; /* Did the entry already exist in the KeyMap? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPutU", - status ); - -/* Allocate memory for the new MapEntry. */ - mapentry = astMalloc( sizeof( AstMapEntry ) ); - if( astOK ) { - -/* Initialise the new structure.*/ - InitMapEntry( mapentry, AST__UNDEFTYPE, 0, status ); - -/* Now store the new values. */ - keylen = strlen( key ); - mapentry->key = astStore( NULL, key, keylen + 1 ); - if( comment ) mapentry->comment = astStore( NULL, comment, strlen( comment ) + 1 ); - mapentry->defined = 0; - -/* Terminate the key string to exclude any trailing spaces. */ - if( astOK ) { - p = (char *) mapentry->key + keylen; - while( --p >= mapentry->key ) { - if( *p == ' ' ) { - *p = 0; - } else { - break; - } - } - } - -/* Use the hash function to determine the element of the hash table in - which to store the new entry. */ - itab = HashFun( mapentry->key, this->mapsize - 1, &(mapentry->hash), status ); - -/* Remove any existing entry with the given key from the table element. */ - oldent = RemoveTableEntry( this, itab, mapentry->key, status ); - if( oldent ) { - keymember = oldent->keymember; - oldent = FreeMapEntry( oldent, status ); - there = 1; - } else { - keymember = -1; - there = 0; - } - -/* If the KeyMap is locked we report an error if an attempt is made to add a value for - a new key. */ - if( !there && astGetMapLocked( this ) ) { - astError( AST__BADKEY, "astMapPutU(%s): Failed to add item \"%s\" to a KeyMap: " - "\"%s\" is not a known item.", status, astGetClass( this ), key, key ); - } - -/* If all has gone OK, store the new entry at the head of the linked list - associated with the selected table entry. */ - if( astOK ) { - mapentry = AddTableEntry( this, itab, mapentry, keymember, status ); - -/* If anything went wrong, try to delete the new entry. */ - } else { - mapentry = FreeMapEntry( mapentry, status ); - } - } -} - -/* -*++ -* Name: -c astMapGet0 -f AST_MAPGET0 - -* Purpose: -* Get a scalar value from a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ast.h" -c int astMapGet0( AstKeyMap *this, const char *key, type *value ); -f RESULT = AST_MAPGET0( THIS, KEY, VALUE, STATUS ) -f RESULT = AST_MAPGET0C( THIS, KEY, VALUE, L, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is a set of functions for retrieving a scalar value from a KeyMap. -* You should replace in the generic function name -c astMapGet0 -f AST_MAPGET0 -* by an appropriate 1-character type code (see the "Data Type Codes" -* section below for the code appropriate to each supported data type). -* The stored value is converted to the data type indiced by -* before being returned (an error is reported if it is not possible to -* convert the stored value to the requested data type). -f Note, the version of this function which returns character strings, -f AST_MAPGET0C, has an extra parameter in which is returned the number -f of characters written into the supplied CHARACTER variable. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the value to be retrieved. Trailing -* spaces are ignored. The supplied string is converted to upper -* case before use if the KeyCase attribute is currently set to zero. -c value -f VALUE = type (Returned) -c A pointer to a buffer in which to return the requested value. -f The requested value. -* If the requested key is not found, or if it is found but has an -* undefined value (see -c astMapPutU), -f AST_MAPPUTU), -* then the contents of the -* buffer on entry to this function will be unchanged on exit. -c For pointer types ("A" and "C"), the buffer should be a suitable -c pointer, and the address of this pointer should be supplied as the -c "value" parameter. -f L = INTEGER (Returned) -f This parameter is only present in the interface for the AST_MAPGET0C -f function. It is returned holding the number of characters -f written into the CHARACTER variable supplied for parameter VALUE. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapGet0() -f AST_MAPGET0 = LOGICAL -c A non-zero value -f .TRUE. -* is returned if the requested key name was found, and does not have -* an undefined value (see -c astMapPutU). Zero -f AST_MAPPUTU). .FALSE. -* is returned otherwise. - -* Notes: -* - No error is reported if the requested key cannot be found in the -* given KeyMap, but a -c zero -f .FALSE. -* value will be returned as the function value. The supplied buffer -* will be returned unchanged. -* - If the stored value is a vector value, then the first value in -* the vector will be returned. -c - A string pointer returned by astMapGet0C is guaranteed to remain valid -c and the string to which it points will not be over-written for a -c total of 50 successive invocations of this function. After this, -c the memory containing the string may be re-used, so a copy of -c the string should be made if it is needed for longer than this. The -c calling code should never attempt to free the returned pointer -c (for instance, using astFree). -* - If the returned value is an AST Object pointer, the Object's reference -* count is incremented by this call. Any subsequent changes made to -* the Object using the returned pointer will be reflected in any -* any other active pointers for the Object. The returned pointer -* should be annulled using -c astAnnul -f AST_ANNUL -* when it is no longer needed. - -* Data Type Codes: -* To select the appropriate -c function, you should replace in the generic function name astMapGet0 -f routine, you should replace in the generic routine name AST_MAPGET0 -* with a 1-character data type code, so as to match the data type type -* of the data you are processing, as follows: -c - F: float -c - D: double -c - I: int -c - C: "const" pointer to null terminated character string -c - A: Pointer to AstObject -c - P: Generic "void *" pointer -c - S: short int -c - B: Unsigned byte (i.e. word) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - C: CHARACTER -f - A: INTEGER used to identify an AstObject -f - S: INTEGER*2 (short integer) -f - B: Unsigned byte -* -c For example, astMapGet0D would be used to get a "double" value, -c while astMapGet0I would be used to get an "int", etc. -f For example, AST_MAPGET0D would be used to get a DOUBLE PRECISION value, -f while AST_MAPGET0I would be used to get an INTEGER, etc. -*-- -*/ -/* Define a macro to implement the function for a specific data type. */ -#define MAKE_MAPGET0(X,Xtype,Itype) \ -static int MapGet0##X( AstKeyMap *this, const char *skey, Xtype *value, int *status ) { \ -\ -/* Local Variables: */ \ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \ - const char *key; /* Pointer to key string to use */ \ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - int itab; /* Index of hash table element to use */ \ - int raw_type; /* Data type of stored value */ \ - int result; /* Returned flag */ \ - unsigned long hash; /* Full width hash value */ \ - void *raw; /* Pointer to stored value */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Convert the supplied key to upper case if required. */ \ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet0" #X, \ - status ); \ -\ -/* Use the hash function to determine the element of the hash table in \ - which the key will be stored. */ \ - itab = HashFun( key, this->mapsize - 1, &hash, status ); \ -\ -/* Search the relevent table entry for the required MapEntry. */ \ - mapentry = SearchTableEntry( this, itab, key, status ); \ -\ -/* Skip rest if the key was not found. */ \ - if( mapentry ) { \ -\ -/* Get the address of the raw value, and its data type. */ \ - raw_type = mapentry->type; \ - if( raw_type == AST__INTTYPE ){ \ - if( mapentry->nel == 0 ) { \ - raw = &( ((Entry0I *)mapentry)->value ); \ - } else { \ - raw = ((Entry1I *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__SINTTYPE ){ \ - if( mapentry->nel == 0 ) { \ - raw = &( ((Entry0S *)mapentry)->value ); \ - } else { \ - raw = ((Entry1S *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__BYTETYPE ){ \ - if( mapentry->nel == 0 ) { \ - raw = &( ((Entry0B *)mapentry)->value ); \ - } else { \ - raw = ((Entry1B *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__DOUBLETYPE ){ \ - if( mapentry->nel == 0 ) { \ - raw = &( ((Entry0D *)mapentry)->value ); \ - } else { \ - raw = ((Entry1D *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__FLOATTYPE ){ \ - if( mapentry->nel == 0 ) { \ - raw = &( ((Entry0F *)mapentry)->value ); \ - } else { \ - raw = ((Entry1F *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__POINTERTYPE ){ \ - if( mapentry->nel == 0 ) { \ - raw = &( ((Entry0P *)mapentry)->value ); \ - } else { \ - raw = ((Entry1P *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__STRINGTYPE ){ \ - if( mapentry->nel == 0 ) { \ - raw = &( ((Entry0C *)mapentry)->value ); \ - } else { \ - raw = ((Entry1C *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__OBJECTTYPE ){ \ - if( mapentry->nel == 0 ) { \ - raw = &( ((Entry0A *)mapentry)->value ); \ - } else { \ - raw = ((Entry1A *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__UNDEFTYPE ){ \ - raw = NULL; \ -\ - } else { \ - raw = NULL; \ - astError( AST__INTER, "astMapGet0(KeyMap): Illegal map entry data " \ - "type %d encountered (internal AST programming error).", status, \ - raw_type ); \ - } \ -\ -/* Convert the value, storing the result the supplied buffer. Report an \ - error if conversion is not possible. */ \ - if( !raw ) { \ - result = 0; \ -\ - } else if( !ConvertValue( raw, raw_type, value, Itype, status ) && astOK ){ \ - astError( AST__MPGER, "astMapGet0" #X "(%s): The value of KeyMap key " \ - "\"%s\" cannot be read using the requested data " \ - "type.", status,astGetClass( this ), key ); \ -\ - } else { \ - result = 1; \ - } \ -\ -/* If the KeyError attribute is non-zero, report an error if the key is not \ - found */ \ - } else if( astGetKeyError( this ) && astOK ) { \ - astError( AST__MPKER, "astMapGet0" #X "(%s): No value was found for " \ - "%s in the supplied KeyMap.", status, astGetClass( this ), \ - key ); \ - } \ -\ -/* If an error occurred, return zero. */ \ - if( !astOK ) result = 0; \ -\ -/* Return the result.*/ \ - return result; \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPGET0(I,int,AST__INTTYPE) -MAKE_MAPGET0(D,double,AST__DOUBLETYPE) -MAKE_MAPGET0(F,float,AST__FLOATTYPE) -MAKE_MAPGET0(C,const char *,AST__STRINGTYPE) -MAKE_MAPGET0(A,AstObject *,AST__OBJECTTYPE) -MAKE_MAPGET0(P,void *,AST__POINTERTYPE) -MAKE_MAPGET0(S,short int,AST__SINTTYPE) -MAKE_MAPGET0(B,unsigned char,AST__BYTETYPE) - -/* Undefine the macro. */ -#undef MAKE_MAPGET0 - -int astMapGet0AId_( AstKeyMap *this, const char *skey, AstObject **value, int *status ) { -/* -* Name: -* astMapGet0AId_ - -* Purpose: -* Get a scalar AstObject pointer from a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "ast.h" -* int astMapGet0A( AstKeyMap *this, const char *key, AstObject **value ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is the public implementation of the astMapGet0A function -* It is identical to astMapGet0A_ except that an ID value is returned -* via the "value" parameter instead of a true C pointer. This is required -* because this conversion cannot be performed by the macro that invokes -* the function. - -* Parameters: -* (see astMapGet0) - -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - const char *key; /* Pointer to key string to use */ \ - int itab; /* Index of hash table element to use */ - int raw_type; /* Data type of stored value */ - int result; /* Returned flag */ - unsigned long hash; /* Full width hash value */ - void *raw; /* Pointer to stored value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet0A", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Skip rest if the key was not found. */ - if( mapentry ) { - -/* Get the address of the raw value, and its data type. */ - raw_type = mapentry->type; - if( raw_type == AST__INTTYPE ){ - if( mapentry->nel == 0 ) { - raw = &( ((Entry0I *)mapentry)->value ); - } else { - raw = ((Entry1I *)mapentry)->value; - } - - } else if( raw_type == AST__POINTERTYPE ){ - if( mapentry->nel == 0 ) { - raw = &( ((Entry0P *)mapentry)->value ); - } else { - raw = ((Entry1P *)mapentry)->value; - } - - } else if( raw_type == AST__SINTTYPE ){ - if( mapentry->nel == 0 ) { - raw = &( ((Entry0S *)mapentry)->value ); - } else { - raw = ((Entry1S *)mapentry)->value; - } - - } else if( raw_type == AST__BYTETYPE ){ - if( mapentry->nel == 0 ) { - raw = &( ((Entry0B *)mapentry)->value ); - } else { - raw = ((Entry1B *)mapentry)->value; - } - - } else if( raw_type == AST__DOUBLETYPE ){ - if( mapentry->nel == 0 ) { - raw = &( ((Entry0D *)mapentry)->value ); - } else { - raw = ((Entry1D *)mapentry)->value; - } - - } else if( raw_type == AST__FLOATTYPE ){ - if( mapentry->nel == 0 ) { - raw = &( ((Entry0F *)mapentry)->value ); - } else { - raw = ((Entry1F *)mapentry)->value; - } - - } else if( raw_type == AST__STRINGTYPE ){ - if( mapentry->nel == 0 ) { - raw = &( ((Entry0C *)mapentry)->value ); - } else { - raw = ((Entry1C *)mapentry)->value; - } - - } else if( raw_type == AST__OBJECTTYPE ){ - if( mapentry->nel == 0 ) { - raw = &( ((Entry0A *)mapentry)->value ); - } else { - raw = ((Entry1A *)mapentry)->value; - } - - } else if( raw_type == AST__UNDEFTYPE ){ - raw = NULL; - - } else { - raw = NULL; - astError( AST__INTER, "astMapGet0(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - raw_type ); - } - -/* Convert the value, storing the result the supplied buffer. Report an - error if conversion is not possible. */ - if( !raw ) { - result = 0; - - } else if( !ConvertValue( raw, raw_type, value, AST__OBJECTTYPE, status ) && astOK ){ - astError( AST__MPGER, "astMapGet0A(%s): The value of KeyMap key " - "\"%s\" cannot be read using the requested data " - "type.", status, astGetClass( this ), key ); - - } else { - result = 1; - } - -/* If the KeyError attribute is non-zero, report an error if the key is not - found */ - } else if( astGetKeyError( this ) && astOK ) { - astError( AST__MPKER, "astMapGet0A(%s): No value was found for " - "%s in the supplied KeyMap.", status, astGetClass( this ), - key ); - } - -/* If required, return an ID value for the Object. */ - if( result && *value ) *value = astMakeId( *value ); - -/* Return the result.*/ - return result; -} - -/* -*++ -* Name: -c astMapGet1 -f AST_MAPGET1 - -* Purpose: -* Get a vector value from a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ast.h" -c int astMapGet1( AstKeyMap *this, const char *key, int mxval, -c int *nval, type *value ) -c int astMapGet1C( AstKeyMap *this, const char *key, int l, int mxval, -c int *nval, const char *value ) -f RESULT = AST_MAPGET1( THIS, KEY, MXVAL, NVAL, VALUE, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is a set of functions for retrieving a vector value from a KeyMap. -* You should replace in the generic function name -c astMapGet1 -f AST_MAPGET1 -* by an appropriate 1-character type code (see the "Data Type Codes" -* section below for the code appropriate to each supported data type). -* The stored value is converted to the data type indiced by -* before being returned (an error is reported if it is not possible to -* convert the stored value to the requested data type). -c Note, the astMapGet1C function has an extra parameter "l" which -c specifies the maximum length of each string to be stored in the -c "value" buffer (see the "astMapGet1C" section below). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the value to be retrieved. Trailing -* spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -c mxval -f MXVAL = INTEGER (Given) -* The number of elements in the -c "value" array. -f VALUE array. -c nval -f NVAL = INTEGER (Returned) -c The address of an integer in which to put the -f The -* number of elements stored in the -c "value" array. -* Any unused elements of the array are left unchanged. -c value -f VALUE( MXVAL ) = type (Returned) -c A pointer to an array in which to return the requested values. -f The requested values. -* If the requested key is not found, or if it is found but has an -* undefined value (see -c astMapPutU), -f AST_MAPPUTU), -* then the contents of the -* buffer on entry to this function will be unchanged on exit. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapGet1() -f AST_MAPGET1 = LOGICAL -c A non-zero value -f .TRUE. -* is returned if the requested key name was found, and does not have -* an undefined value (see -c astMapPutU). Zero -f AST_MAPPUTU). .FALSE. -* is returned otherwise. - -* Notes: -* - No error is reported if the requested key cannot be found in the -* given KeyMap, but a -c zero -f .FALSE. -* value will be returned as the function value. The supplied array -* will be returned unchanged. -* - If the stored value is a scalar value, then the value will be -* returned in the first element of the supplied array, and -c "nval" -f NVAL -* will be returned set to 1. - -c astMapGet1C: -c The "value" buffer supplied to the astMapGet1C function should be a -c pointer to a character array with "mxval*l" elements, where "l" is -c the maximum length of a string to be returned. The value of "l" -c should be supplied as an extra parameter following "key" when -c invoking astMapGet1C, and should include space for a terminating -c null character. - -* Data Type Codes: -* To select the appropriate -c function, you should replace in the generic function name astMapGet1 -f routine, you should replace in the generic routine name AST_MAPGET1 -* with a 1-character data type code, so as to match the data type type -* of the data you are processing, as follows: -c - D: double -c - F: float -c - I: int -c - C: "const" pointer to null terminated character string -c - A: Pointer to AstObject -c - P: Generic "void *" pointer -c - S: short int -c - B: Unsigned byte (i.e. char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - C: CHARACTER -f - A: INTEGER used to identify an AstObject -f - S: INTEGER*2 (short integer) -f - B: Unsigned byte -* -c For example, astMapGet1D would be used to get "double" values, while -c astMapGet1I would be used to get "int" values, etc. For D or I, the -c supplied "value" parameter should be a pointer to an array of doubles -c or ints, with "mxval" elements. For C, the supplied "value" parameter -c should be a pointer to a character string with "mxval*l" elements. -c For A, the supplied "value" parameter should be a pointer to an -c array of AstObject pointers. -f For example, AST_MAPGET1D would be used to get DOUBLE PRECISION values, -f while AST_MAPGET1I would be used to get INTEGER values, etc. - -*-- -*/ -/* Define a macro to implement the function for a specific data type -(excluding "C" since that needs an extra parameter). */ -#define MAKE_MAPGET1(X,Xtype,Itype) \ -static int MapGet1##X( AstKeyMap *this, const char *skey, int mxval, int *nval, Xtype *value, int *status ) { \ -\ -/* Local Variables: */ \ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \ - const char *key; /* Pointer to key string to use */ \ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - int i; /* Element index */ \ - int itab; /* Index of hash table element to use */ \ - int nel; /* Number of elements in raw vector */ \ - int raw_type; /* Data type of stored value */ \ - int result; /* Returned flag */ \ - size_t raw_size; /* Size of a single raw value */ \ - unsigned long hash; /* Full width hash value */ \ - void *raw; /* Pointer to stored value */ \ -\ -/* Initialise */ \ - result = 0; \ - *nval = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Convert the supplied key to upper case if required. */ \ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet1" #X, \ - status ); \ -\ -/* Use the hash function to determine the element of the hash table in \ - which the key will be stored. */ \ - itab = HashFun( key, this->mapsize - 1, &hash, status ); \ -\ -/* Search the relevent table entry for the required MapEntry. */ \ - mapentry = SearchTableEntry( this, itab, key, status ); \ -\ -/* Skip rest if the key was not found. */ \ - if( mapentry ) { \ - result = 1; \ -\ -/* Get the address of the first raw value, and its data type. Also get \ - the size of each element of the vector. */ \ - nel = mapentry->nel; \ - raw_type = mapentry->type; \ - if( raw_type == AST__INTTYPE ){ \ - raw_size = sizeof( int ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0I *)mapentry)->value ); \ - } else { \ - raw = ((Entry1I *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__DOUBLETYPE ){ \ - raw_size = sizeof( double ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0D *)mapentry)->value ); \ - } else { \ - raw = ((Entry1D *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__SINTTYPE ){ \ - raw_size = sizeof( short int ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0S *)mapentry)->value ); \ - } else { \ - raw = ((Entry1S *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__BYTETYPE ){ \ - raw_size = sizeof( unsigned char ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0B *)mapentry)->value ); \ - } else { \ - raw = ((Entry1B *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__POINTERTYPE ){ \ - raw_size = sizeof( void * ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0P *)mapentry)->value ); \ - } else { \ - raw = ((Entry1P *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__FLOATTYPE ){ \ - raw_size = sizeof( float ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0F *)mapentry)->value ); \ - } else { \ - raw = ((Entry1F *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__STRINGTYPE ){ \ - raw_size = sizeof( const char * ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0C *)mapentry)->value ); \ - } else { \ - raw = ((Entry1C *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__OBJECTTYPE ){ \ - raw_size = sizeof( AstObject * ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0A *)mapentry)->value ); \ - } else { \ - raw = ((Entry1A *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__UNDEFTYPE ){ \ - raw_size = 0; \ - raw = NULL; \ -\ - } else { \ - raw_size = 0; \ - raw = NULL; \ - astError( AST__INTER, "astMapGet1(KeyMap): Illegal map entry data " \ - "type %d encountered (internal AST programming error).", status, \ - raw_type ); \ - } \ -\ -/* Treat scalars as single-value vectors. */ \ - if( nel == 0 ) nel = 1; \ -\ -/* Ensure no more than "mxval" values are returned. */ \ - if( nel > mxval ) nel = mxval; \ -\ -/* Return the number of values stored in the buffer. */ \ - *nval = nel; \ -\ -/* Loop round all values in the vector. */ \ - for( i = 0; i < nel && astOK; i++ ) { \ -\ -/* Convert the value, storing the result in the supplied buffer. Report an \ - error if conversion is not possible. */ \ - if( !raw ) { \ - result = 0; \ -\ - } else if( !ConvertValue( raw, raw_type, value + i, Itype, status ) && astOK ){ \ - astError( AST__MPGER, "astMapGet1" #X "(%s): The value of " \ - "element %d of KeyMap key \"%s\" cannot be read using " \ - "the requested data type.", status,astGetClass( this ), i + 1, key ); \ - } \ -\ -/* Increment the pointers to the next raw value. */ \ - raw = (char *) raw + raw_size; \ - } \ -\ -/* If the KeyError attribute is non-zero, report an error if the key is not \ - found */ \ - } else if( astGetKeyError( this ) && astOK ) { \ - astError( AST__MPKER, "astMapGet1" #X "(%s): No value was found for " \ - "%s in the supplied KeyMap.", status, astGetClass( this ), \ - key ); \ - } \ -\ -/* If an error occurred,return zero. */ \ - if( !astOK ) result = 0; \ -\ -/* Return the result.*/ \ - return result; \ -} - -/* Expand the above macro to generate a function for each required - data type (except C which is done differently). */ -MAKE_MAPGET1(I,int,AST__INTTYPE) -MAKE_MAPGET1(D,double,AST__DOUBLETYPE) -MAKE_MAPGET1(F,float,AST__FLOATTYPE) -MAKE_MAPGET1(A,AstObject *,AST__OBJECTTYPE) -MAKE_MAPGET1(P,void *,AST__POINTERTYPE) -MAKE_MAPGET1(S,short int,AST__SINTTYPE) -MAKE_MAPGET1(B,unsigned char,AST__BYTETYPE) - -/* Undefine the macro. */ -#undef MAKE_MAPGET1 - - -static int MapGet1C( AstKeyMap *this, const char *skey, int l, int mxval, - int *nval, char *value, int *status ) { -/* -* Name: -* MapGet1C - -* Purpose: -* Get a vector value from a KeyMap. - -* Type: -* Private member function. - -* Synopsis: -* #include "ast.h" -* int MapGet1C( AstKeyMap *this, const char *key, int l, int mxval, -* int *nval, char *value, int *status ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is the implementation of astMapGet1 for = "C". We -* cannot use the MAKE_MAPGET1 macro for this because the string -* version of this function has an extra parameter giving the maximum -* length of each string which can be stored in the supplied buffer. - -* Parameters: -* (see astMapGet1) -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ - char *val; /* Pointer to next buffer element */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - const char *cvalue; /* Pointer to converted string */ - const char *key; /* Pointer to key string to use */ \ - int i; /* Element index */ - int itab; /* Index of hash table element to use */ - int nel; /* Number of elements in raw vector */ - int raw_type; /* Data type of stored value */ - int result; /* Returned flag */ - size_t raw_size; /* Size of a single raw value */ - unsigned long hash; /* Full width hash value */ - void *raw; /* Pointer to stored value */ - -/* Initialise */ - result = 0; - *nval = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet1C", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Skip rest if the key was not found. */ - if( mapentry ) { - result = 1; - -/* Get the address of the first raw value, and its data type. Also get - the size of each element of the vector. */ - nel = mapentry->nel; - raw_type = mapentry->type; - if( raw_type == AST__INTTYPE ){ - raw_size = sizeof( int ); - if( nel == 0 ) { - raw = &( ((Entry0I *)mapentry)->value ); - } else { - raw = ((Entry1I *)mapentry)->value; - } - - } else if( raw_type == AST__POINTERTYPE ){ - raw_size = sizeof( void * ); - if( nel == 0 ) { - raw = &( ((Entry0P *)mapentry)->value ); - } else { - raw = ((Entry1P *)mapentry)->value; - } - - } else if( raw_type == AST__DOUBLETYPE ){ - raw_size = sizeof( double ); - if( nel == 0 ) { - raw = &( ((Entry0D *)mapentry)->value ); - } else { - raw = ((Entry1D *)mapentry)->value; - } - - } else if( raw_type == AST__SINTTYPE ){ - raw_size = sizeof( short int ); - if( nel == 0 ) { - raw = &( ((Entry0S *)mapentry)->value ); - } else { - raw = ((Entry1S *)mapentry)->value; - } - - } else if( raw_type == AST__BYTETYPE ){ - raw_size = sizeof( unsigned char ); - if( nel == 0 ) { - raw = &( ((Entry0B *)mapentry)->value ); - } else { - raw = ((Entry1B *)mapentry)->value; - } - - } else if( raw_type == AST__FLOATTYPE ){ - raw_size = sizeof( float ); - if( nel == 0 ) { - raw = &( ((Entry0F *)mapentry)->value ); - } else { - raw = ((Entry1F *)mapentry)->value; - } - - } else if( raw_type == AST__STRINGTYPE ){ - raw_size = sizeof( const char * ); - if( nel == 0 ) { - raw = &( ((Entry0C *)mapentry)->value ); - } else { - raw = ((Entry1C *)mapentry)->value; - } - - } else if( raw_type == AST__OBJECTTYPE ){ - raw_size = sizeof( AstObject * ); - if( nel == 0 ) { - raw = &( ((Entry0A *)mapentry)->value ); - } else { - raw = ((Entry1A *)mapentry)->value; - } - - } else if( raw_type == AST__UNDEFTYPE ){ - raw_size = 0; - raw = NULL; - - } else { - raw_size = 0; - raw = NULL; - astError( AST__INTER, "astMapGet1C(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - raw_type ); - } - -/* Treat scalars as single-value vectors. */ - if( nel == 0 ) nel = 1; - -/* Ensure no more than "mxval" values are returned. */ - if( nel > mxval ) nel = mxval; - -/* Return the number of values stored in the buffer. */ - *nval = nel; - -/* Loop round all values in the vector. */ - val = value; - for( i = 0; i < nel && astOK; i++ ) { - -/* Convert the value, storing the result in the supplied buffer. Report an - error if conversion is not possible. */ - if( !raw ) { - result = 0; - - } else if( !ConvertValue( raw, raw_type, &cvalue, AST__STRINGTYPE, status ) && astOK ){ - astError( AST__MPGER, "astMapGet1C(%s): The value of " - "element %d of KeyMap key \"%s\" cannot be read using " - "the requested data type.", status,astGetClass( this ), i + 1, key ); - -/* If succesful, copy the string into the supplied buffer, or as much of - it as will fit. Leave room for a trailing null character. */ - } else { - strncpy( val, cvalue, l - 1 ); - val[ l - 1 ] = 0; - } - -/* Increment the pointers to the next raw value and the next buffer - location. */ - raw = (char *) raw + raw_size; - val += l; - } - -/* If the KeyError attribute is non-zero, report an error if the key is not - found */ - } else if( astGetKeyError( this ) && astOK ) { - astError( AST__MPKER, "astMapGet1C(%s): No value was found for " - "%s in the supplied KeyMap.", status, astGetClass( this ), - key ); - } - -/* If an error occurred,return zero. */ - if( !astOK ) result = 0; - -/* Return the result.*/ - return result; -} - -int astMapGet1AId_( AstKeyMap *this, const char *skey, int mxval, int *nval, - AstObject **value, int *status ) { -/* -* Name: -* astMapGet1AId_ - -* Purpose: -* Get a vector of AstObject pointers from a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "ast.h" -* int astMapGet1A( AstKeyMap *this, const char *key, int mxval, int *nval, -* AstObject **value ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is the public implementation of the astMapGet1A function -* It is identical to astMapGet1A_ except that ID values are returned -* via the "value" parameter instead of a true C pointers. This is required -* because this conversion cannot be performed by the macro that invokes -* the function. - -* Parameters: -* (see astMapGet1) - -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ - AstObject *avalue; /* Pointer to AstObject */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - const char *key; /* Pointer to key string to use */ \ - int i; /* Element index */ - int itab; /* Index of hash table element to use */ - int nel; /* Number of elements in raw vector */ - int raw_type; /* Data type of stored value */ - int result; /* Returned flag */ - size_t raw_size; /* Size of a single raw value */ - unsigned long hash; /* Full width hash value */ - void *raw; /* Pointer to stored value */ - -/* Initialise */ - result = 0; - *nval = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet1A", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Skip rest if the key was not found. */ - if( mapentry ) { - result = 1; - -/* Get the address of the first raw value, and its data type. Also get - the size of each element of the vector. */ - nel = mapentry->nel; - raw_type = mapentry->type; - if( raw_type == AST__INTTYPE ){ - raw_size = sizeof( int ); - if( nel == 0 ) { - raw = &( ((Entry0I *)mapentry)->value ); - } else { - raw = ((Entry1I *)mapentry)->value; - } - - } else if( raw_type == AST__DOUBLETYPE ){ - raw_size = sizeof( double ); - if( nel == 0 ) { - raw = &( ((Entry0D *)mapentry)->value ); - } else { - raw = ((Entry1D *)mapentry)->value; - } - - } else if( raw_type == AST__SINTTYPE ){ - raw_size = sizeof( short int ); - if( nel == 0 ) { - raw = &( ((Entry0S *)mapentry)->value ); - } else { - raw = ((Entry1S *)mapentry)->value; - } - - } else if( raw_type == AST__BYTETYPE ){ - raw_size = sizeof( unsigned char ); - if( nel == 0 ) { - raw = &( ((Entry0B *)mapentry)->value ); - } else { - raw = ((Entry1B *)mapentry)->value; - } - - } else if( raw_type == AST__POINTERTYPE ){ - raw_size = sizeof( void * ); - if( nel == 0 ) { - raw = &( ((Entry0P *)mapentry)->value ); - } else { - raw = ((Entry1P *)mapentry)->value; - } - - } else if( raw_type == AST__FLOATTYPE ){ - raw_size = sizeof( float ); - if( nel == 0 ) { - raw = &( ((Entry0F *)mapentry)->value ); - } else { - raw = ((Entry1F *)mapentry)->value; - } - - } else if( raw_type == AST__STRINGTYPE ){ - raw_size = sizeof( const char * ); - if( nel == 0 ) { - raw = &( ((Entry0C *)mapentry)->value ); - } else { - raw = ((Entry1C *)mapentry)->value; - } - - } else if( raw_type == AST__OBJECTTYPE ){ - raw_size = sizeof( AstObject * ); - if( nel == 0 ) { - raw = &( ((Entry0A *)mapentry)->value ); - } else { - raw = ((Entry1A *)mapentry)->value; - } - - } else if( raw_type == AST__UNDEFTYPE ){ - raw_size = 0; - raw = NULL; - - } else { - raw_size = 0; - raw = NULL; - astError( AST__INTER, "astMapGet1A(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", - status, raw_type ); - } - -/* Treat scalars as single-value vectors. */ - if( nel == 0 ) nel = 1; - -/* Ensure no more than "mxval" values are returned. */ - if( nel > mxval ) nel = mxval; - -/* Return the number of values stored in the buffer. */ - *nval = nel; - -/* Loop round all values in the vector. */ - for( i = 0; i < nel && astOK; i++ ) { - -/* Convert the value, storing the result in the supplied buffer. Report an - error if conversion is not possible. */ - if( !raw ) { - result = 0; - - } else if( !ConvertValue( raw, raw_type, &avalue, AST__OBJECTTYPE, status ) && astOK ){ - astError( AST__MPGER, "astMapGet1A(%s): The value of " - "element %d of KeyMap key \"%s\" cannot be read using " - "the requested data type.", status, astGetClass( this ), - i + 1, key ); - -/* If succesful, return an ID value for the Object. */ - } else { - value[ i ] = avalue ? astMakeId( avalue ) : NULL; - } - -/* Increment the pointers to the next raw value. */ - raw = (char *) raw + raw_size; - } - -/* If the KeyError attribute is non-zero, report an error if the key is not - found */ - } else if( astGetKeyError( this ) && astOK ) { - astError( AST__MPKER, "astMapGet1A(%s): No value was found for " - "%s in the supplied KeyMap.", status, astGetClass( this ), - key ); - } - -/* If an error occurred,return zero. */ - if( !astOK ) result = 0; - -/* Return the result.*/ - return result; -} - -static int MapGetC( AstKeyMap *this, const char *key, const char **value, int *status ) { -/* -*++ -* Name: -c astMapGetC -f AST_MAPGETC - -* Purpose: -* Get a scalar or vector value from a KeyMap as a single string. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ast.h" -c int astMapGetC( AstKeyMap *this, const char *key, const char **value ); -f RESULT = AST_MAPGETC( THIS, KEY, VALUE, L, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function gets a named value from a KeyMap as a single string. -* For scalar values it is equivalent to -c astMapGet0C. -f AST_MAPGET0C. -* If the value is a vector, the returned string is a comma-separated -* list of the vector elements, enclosed in parentheses. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the value to be retrieved. Trailing -* spaces are ignored. The supplied string is converted to upper -* case before use if the KeyCase attribute is currently set to zero. -c value -f VALUE = CHARACTER * ( * ) (Returned) -c Address at which to return a pointer to the required string value. -f The requested value. -* If the requested key is not found, or if it is found but has an -* undefined value (see -c astMapPutU), then the contents of the supplied pointer -f AST_MAPPUTU), then the contents of the supplied string -* are unchanged on exit. -f L = INTEGER (Returned) -f This parameter is only present in the interface for the AST_MAPGET0C -f function. It is returned holding the number of characters -f written into the CHARACTER variable supplied for parameter VALUE. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapGetC() -f AST_MAPGETC = LOGICAL -c A non-zero value -f .TRUE. -* is returned if the requested key name was found, and does not have -* an undefined value (see -c astMapPutU). Zero -f AST_MAPPUTU). .FALSE. -* is returned otherwise. - -* Notes: -* - No error is reported if the requested key cannot be found in the -* given KeyMap, but a -c zero -f .FALSE. -* value will be returned as the function value. The supplied buffer -* will be returned unchanged. -c - The string pointer returned by astMapGetC is guaranteed to remain valid -c and the string to which it points will not be over-written for a -c total of 50 successive invocations of this function. After this, -c the memory containing the string may be re-used, so a copy of -c the string should be made if it is needed for longer than this. The -c calling code should never attempt to free the returned pointer -c (for instance, using astFree). -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *buf; /* Buffer for all string values */ - char *cvalue; /* Pointer to returned string */ - char *pb; /* Pointer to start of next section of buffer */ - int i; /* Loop count */ - int mxlen; /* Max length of any string in the vector */ - int nval; /* No. of elements in vector */ - int result; /* Returned flag */ - int nc; /* Current length of total string */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* If the "convertvalue_strings" array has not been initialised, fill it with - NULL pointers. */ - if( !convertvalue_init ) { - convertvalue_init = 1; - for( i = 0; i < AST__KEYMAP_CONVERTVALUE_MAX_STRINGS; i++ ) convertvalue_strings[ i ] = NULL; - } - -/* See how many elements are stored in the requested entry. */ - nval = astMapLength( this, key ); - -/* If the requested entry does not exist, return without further action. */ - if( nval == 0 ) { - result = 0; - -/* If the requested entry is a scalar, just call astMapGet0C to get the - required string. */ - } else if( nval == 1 ) { - result = astMapGet0C( this, key, value ); - -/* If the requested entry is a vector, use astMapGet1C to get all the - strings stored in dynamic memory. */ - } else { - -/* First get the maximum length of any one string stored in the vector. */ - mxlen = astMapLenC( this, key ); - -/* Allocate a buffer big enough to hold all elements assuming they are - all the maximum length. Include room for a terminating null on each - string. */ - buf = astMalloc( (mxlen + 1)*nval*sizeof( *buf ) ); - if( astOK ) { - -/* Store the strings in the buffer. */ - result = astMapGet1C( this, key, mxlen+1, nval, &nval, buf ); - if( result ) { - -/* Combine the individual strings into a single comma-delimited list, - enclosed in parentheses, and stored in dynamic memory. */ - nc = 0; - cvalue = astAppendString( NULL, &nc, "(" ); - pb = buf; - for( i = 0; i < nval; i++ ) { - if( i ) cvalue = astAppendString( cvalue, &nc, "," ); - cvalue = astAppendString( cvalue, &nc, pb ); - pb += mxlen + 1; - } - cvalue = astAppendString( cvalue, &nc, ")" ); - -/* Put a pointer to the total string into the next element of the "convertvalue_strings" - array, freeing any value already stored in the next element first. */ - if( cvalue && astOK ) { - (void) astFree( convertvalue_strings[ convertvalue_istr ] ); - convertvalue_strings[ convertvalue_istr ] = cvalue; - -/* Increment "convertvalue_istr" to use the next element of "convertvalue_strings" on - the next invocation. Recycle "convertvalue_istr" to zero when all elements have been - used. */ - if( ++convertvalue_istr == ( AST__KEYMAP_CONVERTVALUE_MAX_STRINGS - 1 ) ) - convertvalue_istr = 0; - -/* Return a pointer to the striong now stored in the "convertvalue_strings" - array. */ - *value = cvalue; - } - } - } - -/* Free the space used to hold the values buffer. */ - buf = astFree( buf ); - } - -/* Return the result. */ - return result; -} - - -/* -*++ -* Name: -c astMapGetElem -f AST_MAPGETELEM - -* Purpose: -* Get a single element of a vector value from a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ast.h" -c int astMapGetElem( AstKeyMap *this, const char *key, int elem, -c type *value ) -c int astMapGetElemC( AstKeyMap *this, const char *key, int l, int elem, -c char *value ) -f RESULT = AST_MAPGETELEM( THIS, KEY, ELEM, VALUE, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is a set of functions for retrieving a single element of a vector -* value from a KeyMap. You should replace in the generic function name -c astMapGetElem -f AST_MAPGETELEM -* by an appropriate 1-character type code (see the "Data Type Codes" -* section below for the code appropriate to each supported data type). -* The stored value is converted to the data type indiced by -* before being returned (an error is reported if it is not possible to -* convert the stored value to the requested data type). -c Note, the astMapGetElemC function has an extra parameter "l" which -c specifies the maximum length of the string to be stored in the -c "value" buffer (see the "astMapGetElemC" section below). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the value to be retrieved. Trailing -* spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -c elem -f ELEM = INTEGER (Given) -* The index of the required vector element, starting at -c zero. -f one. -* An error will be reported if the value is outside the range of -* the vector. -c value -f VALUE = type (Returned) -c A pointer to a buffer in which to return the requested value. -f The requested value. -* If the requested key is not found, or if it is found but has an -* undefined value (see -c astMapPutU), -f AST_MAPPUTU), -* then the contents of the -* buffer on entry to this function will be unchanged on exit. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapGetElem() -f AST_MAPGETELEM = LOGICAL -c A non-zero value -f .TRUE. -* is returned if the requested key name was found, and does not have -* an undefined value (see -c astMapPutU). Zero -f AST_MAPPUTU). .FALSE. -* is returned otherwise. - -* Notes: -* - No error is reported if the requested key cannot be found in the -* given KeyMap, or if it has an undefined value, but a -c zero -f .FALSE. -* value will be returned as the function value. - -c astMapGetElemC: -c The "value" buffer supplied to the astMapGetElemC function should be a -c pointer to a character array with "l" elements, where "l" is the -c maximum length of the string to be returned. The value of "l" -c should be supplied as an extra parameter following "key" when -c invoking astMapGetElemC, and should include space for a terminating -c null character. - -* Data Type Codes: -* To select the appropriate -c function, you should replace in the generic function name -c astMapGetElem -f routine, you should replace in the generic routine name -f AST_MAPGETELEM -* with a 1-character data type code, so as to match the data type type -* of the data you are processing, as follows: -c - D: double -c - F: float -c - I: int -c - C: "const" pointer to null terminated character string -c - A: Pointer to AstObject -c - P: Generic "void *" pointer -c - S: short int -c - B: Unsigned byte (i.e. char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - C: CHARACTER -f - A: INTEGER used to identify an AstObject -f - S: INTEGER*2 (short integer) -f - B: Unsigned byte -* -c For example, astMapGetElemD would be used to get a "double" value, while -c astMapGetElemI would be used to get an "int" value, etc. For D or I, the -c supplied "value" parameter should be a pointer to a double or int. For -c C, the supplied "value" parameter should be a pointer to a character -c string with "l" elements. For A, the supplied "value" parameter should -c be a pointer to an AstObject pointer. -f For example, AST_MAPGETELEMD would be used to get a DOUBLE PRECISION -f value, while AST_MAPGETELEMI would be used to get an INTEGER value, etc. - -*-- -*/ -/* Define a macro to implement the function for a specific data type -(excluding "C" since that needs an extra parameter). */ -#define MAKE_MAPGETELEM(X,Xtype,Itype) \ -static int MapGetElem##X( AstKeyMap *this, const char *skey, int elem, \ - Xtype *value, int *status ) { \ -\ -/* Local Variables: */ \ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \ - const char *key; /* Pointer to key string to use */ \ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - int itab; /* Index of hash table element to use */ \ - int nel; /* Number of elements in raw vector */ \ - int raw_type; /* Data type of stored value */ \ - int result; /* Returned flag */ \ - size_t raw_size; /* Size of a single raw value */ \ - unsigned long hash; /* Full width hash value */ \ - void *raw; /* Pointer to stored value */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Convert the supplied key to upper case if required. */ \ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGetElem" #X, \ - status ); \ -\ -/* Use the hash function to determine the element of the hash table in \ - which the key will be stored. */ \ - itab = HashFun( key, this->mapsize - 1, &hash, status ); \ -\ -/* Search the relevent table entry for the required MapEntry. */ \ - mapentry = SearchTableEntry( this, itab, key, status ); \ -\ -/* Skip rest if the key was not found. */ \ - if( mapentry ) { \ - result = 1; \ -\ -/* Get the address of the first raw value, and its data type. Also get \ - the size of each element of the vector. */ \ - nel = mapentry->nel; \ - raw_type = mapentry->type; \ - if( raw_type == AST__INTTYPE ){ \ - raw_size = sizeof( int ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0I *)mapentry)->value ); \ - } else { \ - raw = ((Entry1I *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__DOUBLETYPE ){ \ - raw_size = sizeof( double ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0D *)mapentry)->value ); \ - } else { \ - raw = ((Entry1D *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__SINTTYPE ){ \ - raw_size = sizeof( short int ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0S *)mapentry)->value ); \ - } else { \ - raw = ((Entry1S *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__BYTETYPE ){ \ - raw_size = sizeof( unsigned char ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0B *)mapentry)->value ); \ - } else { \ - raw = ((Entry1B *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__POINTERTYPE ){ \ - raw_size = sizeof( void * ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0P *)mapentry)->value ); \ - } else { \ - raw = ((Entry1P *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__FLOATTYPE ){ \ - raw_size = sizeof( float ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0F *)mapentry)->value ); \ - } else { \ - raw = ((Entry1F *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__STRINGTYPE ){ \ - raw_size = sizeof( const char * ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0C *)mapentry)->value ); \ - } else { \ - raw = ((Entry1C *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__OBJECTTYPE ){ \ - raw_size = sizeof( AstObject * ); \ - if( nel == 0 ) { \ - raw = &( ((Entry0A *)mapentry)->value ); \ - } else { \ - raw = ((Entry1A *)mapentry)->value; \ - } \ -\ - } else if( raw_type == AST__UNDEFTYPE ){ \ - raw = NULL; \ -\ - } else { \ - raw_size = 0; \ - raw = NULL; \ - astError( AST__INTER, "astMapGetElem(KeyMap): Illegal map entry " \ - "data type %d encountered (internal AST programming " \ - "error).", status, raw_type ); \ - } \ -\ -/* Treat scalars as single-value vectors. */ \ - if( nel == 0 ) nel = 1; \ -\ -/* Ensure the requested element is within the bounds of the vector */ \ - if( elem >= nel || elem < 0 ) { \ - if( astOK ) { \ - astError( AST__MPVIN, "astMapGetElem(KeyMap): Illegal " \ - "zero-based vector index %d supplied for KeyMap " \ - "entry '%s' - the vector has %d elements.", status, \ - elem, key, nel ); \ - } \ -\ -/* Get a pointer to the requested raw value. */ \ - } else if( raw ) { \ - raw = (char *) raw + elem*raw_size; \ -\ -/* Convert the requested value, storing the result in the supplied buffer. \ - Report an error if conversion is not possible. */ \ - if( !ConvertValue( raw, raw_type, value, Itype, status ) && astOK ){ \ - astError( AST__MPGER, "astMapGetElem" #X "(%s): The value of " \ - "element %d of KeyMap key \"%s\" cannot be read using " \ - "the requested data type.", status, astGetClass( this ), \ - elem + 1, key ); \ - } \ - } \ -\ -/* If the KeyError attribute is non-zero, report an error if the key is not \ - found */ \ - } else if( astGetKeyError( this ) && astOK ) { \ - astError( AST__MPKER, "astMapGetElem" #X "(%s): No value was found for " \ - "%s in the supplied KeyMap.", status, astGetClass( this ), \ - key ); \ - } \ -\ -/* If an error occurred,return zero. */ \ - if( !astOK ) result = 0; \ -\ -/* Return the result.*/ \ - return result; \ -} - -/* Expand the above macro to generate a function for each required - data type (except C which is done differently). */ -MAKE_MAPGETELEM(I,int,AST__INTTYPE) -MAKE_MAPGETELEM(D,double,AST__DOUBLETYPE) -MAKE_MAPGETELEM(F,float,AST__FLOATTYPE) -MAKE_MAPGETELEM(A,AstObject *,AST__OBJECTTYPE) -MAKE_MAPGETELEM(P,void *,AST__POINTERTYPE) -MAKE_MAPGETELEM(S,short int,AST__SINTTYPE) -MAKE_MAPGETELEM(B,unsigned char,AST__BYTETYPE) - -/* Undefine the macro. */ -#undef MAKE_MAPGETELEM - - -static int MapGetElemC( AstKeyMap *this, const char *skey, int l, int elem, - char *value, int *status ) { -/* -* Name: -* MapGetElemC - -* Purpose: -* Get a single element of a vector value from a KeyMap. - -* Type: -* Private member function. - -* Synopsis: -* #include "ast.h" -* int MapGetElemC( AstKeyMap *this, const char *key, int l, int elem, -* char *value, int *status ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is the implementation of astMapGetElem for = "C". We -* cannot use the MAKE_MAPGETELEM macro for this because the string -* version of this function has an extra parameter giving the maximum -* length of each string which can be stored in the supplied buffer. - -* Parameters: -* (see astMapGetElem) -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ - const char *key; /* Pointer to key string to use */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - const char *cvalue; /* Pointer to converted string */ - int itab; /* Index of hash table element to use */ - int nel; /* Number of elements in raw vector */ - int raw_type; /* Data type of stored value */ - int result; /* Returned flag */ - size_t raw_size; /* Size of a single raw value */ - unsigned long hash; /* Full width hash value */ - void *raw; /* Pointer to stored value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGetElemC", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Skip rest if the key was not found. */ - if( mapentry ) { - result = 1; - -/* Get the address of the first raw value, and its data type. Also get - the size of each element of the vector. */ - nel = mapentry->nel; - raw_type = mapentry->type; - if( raw_type == AST__INTTYPE ){ - raw_size = sizeof( int ); - if( nel == 0 ) { - raw = &( ((Entry0I *)mapentry)->value ); - } else { - raw = ((Entry1I *)mapentry)->value; - } - - } else if( raw_type == AST__POINTERTYPE ){ - raw_size = sizeof( void * ); - if( nel == 0 ) { - raw = &( ((Entry0P *)mapentry)->value ); - } else { - raw = ((Entry1P *)mapentry)->value; - } - - } else if( raw_type == AST__DOUBLETYPE ){ - raw_size = sizeof( double ); - if( nel == 0 ) { - raw = &( ((Entry0D *)mapentry)->value ); - } else { - raw = ((Entry1D *)mapentry)->value; - } - - } else if( raw_type == AST__SINTTYPE ){ - raw_size = sizeof( short int ); - if( nel == 0 ) { - raw = &( ((Entry0S *)mapentry)->value ); - } else { - raw = ((Entry1S *)mapentry)->value; - } - - } else if( raw_type == AST__BYTETYPE ){ - raw_size = sizeof( unsigned char ); - if( nel == 0 ) { - raw = &( ((Entry0B *)mapentry)->value ); - } else { - raw = ((Entry1B *)mapentry)->value; - } - - } else if( raw_type == AST__FLOATTYPE ){ - raw_size = sizeof( float ); - if( nel == 0 ) { - raw = &( ((Entry0F *)mapentry)->value ); - } else { - raw = ((Entry1F *)mapentry)->value; - } - - } else if( raw_type == AST__STRINGTYPE ){ - raw_size = sizeof( const char * ); - if( nel == 0 ) { - raw = &( ((Entry0C *)mapentry)->value ); - } else { - raw = ((Entry1C *)mapentry)->value; - } - - } else if( raw_type == AST__OBJECTTYPE ){ - raw_size = sizeof( AstObject * ); - if( nel == 0 ) { - raw = &( ((Entry0A *)mapentry)->value ); - } else { - raw = ((Entry1A *)mapentry)->value; - } - - } else if( raw_type == AST__UNDEFTYPE ){ - raw = NULL; - - } else { - raw_size = 0; - raw = NULL; - astError( AST__INTER, "astMapGetElemC(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - raw_type ); - } - -/* Treat scalars as single-value vectors. */ - if( nel == 0 ) nel = 1; - -/* Ensure the requested element is within the bounds of the vector */ - if( elem >= nel || elem < 0 ) { - if( astOK ) { - astError( AST__MPVIN, "astMapGetElemC(KeyMap): Illegal vector " - "index %d supplied for KeyMap entry '%s' - should be " - "in the range 1 to %d.", status, elem + 1, key, nel + 1 ); - } - -/* Get a pointer to the requested raw value. */ - } else if( raw ){ - raw = (char *) raw + elem*raw_size; - -/* Convert the value, storing the result in the supplied buffer. Report an - error if conversion is not possible. */ - if( !ConvertValue( raw, raw_type, &cvalue, AST__STRINGTYPE, status ) && astOK ){ - astError( AST__MPGER, "astMapGetElemC(%s): The value of " - "element %d of KeyMap key \"%s\" cannot be read using " - "the requested data type.", status,astGetClass( this ), - elem + 1, key ); - -/* If succesful, copy the string into the supplied buffer, or as much of - it as will fit. Leave room for a trailing null character. */ - } else { - strncpy( value, cvalue, l - 1 ); - value[ l - 1 ] = 0; - } - } - -/* If the KeyError attribute is non-zero, report an error if the key is not - found */ - } else if( astGetKeyError( this ) && astOK ) { - astError( AST__MPKER, "astMapGetElemC(%s): No value was found for " - "%s in the supplied KeyMap.", status, astGetClass( this ), - key ); - } - -/* If an error occurred,return zero. */ - if( !astOK ) result = 0; - -/* Return the result.*/ - return result; -} - -int astMapGetElemAId_( AstKeyMap *this, const char *skey, int elem, - AstObject **value, int *status ) { -/* -* Name: -* astMapGetElemAId_ - -* Purpose: -* Get a single element of a vector of AstObject pointers from a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "ast.h" -* int astMapGetElemA( AstKeyMap *this, const char *key, int elem, -* AstObject **value ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is the public implementation of the astMapGetElemA function -* It is identical to astMapGetElemA_ except that an ID value is returned -* via the "value" parameter instead of a true C pointer. This is required -* because this conversion cannot be performed by the macro that invokes -* the function. - -* Parameters: -* (see astMapGet1) - -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ - AstObject *avalue; /* Pointer to AstObject */ - const char *key; /* Pointer to key string to use */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - int itab; /* Index of hash table element to use */ - int nel; /* Number of elements in raw vector */ - int raw_type; /* Data type of stored value */ - int result; /* Returned flag */ - size_t raw_size; /* Size of a single raw value */ - unsigned long hash; /* Full width hash value */ - void *raw; /* Pointer to stored value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGetElemA", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Skip rest if the key was not found. */ - if( mapentry ) { - result = 1; - -/* Get the address of the first raw value, and its data type. Also get - the size of each element of the vector. */ - nel = mapentry->nel; - raw_type = mapentry->type; - if( raw_type == AST__INTTYPE ){ - raw_size = sizeof( int ); - if( nel == 0 ) { - raw = &( ((Entry0I *)mapentry)->value ); - } else { - raw = ((Entry1I *)mapentry)->value; - } - - } else if( raw_type == AST__SINTTYPE ){ - raw_size = sizeof( short int ); - if( nel == 0 ) { - raw = &( ((Entry0S *)mapentry)->value ); - } else { - raw = ((Entry1S *)mapentry)->value; - } - - } else if( raw_type == AST__BYTETYPE ){ - raw_size = sizeof( unsigned char ); - if( nel == 0 ) { - raw = &( ((Entry0B *)mapentry)->value ); - } else { - raw = ((Entry1B *)mapentry)->value; - } - - } else if( raw_type == AST__DOUBLETYPE ){ - raw_size = sizeof( double ); - if( nel == 0 ) { - raw = &( ((Entry0D *)mapentry)->value ); - } else { - raw = ((Entry1D *)mapentry)->value; - } - - } else if( raw_type == AST__POINTERTYPE ){ - raw_size = sizeof( void * ); - if( nel == 0 ) { - raw = &( ((Entry0P *)mapentry)->value ); - } else { - raw = ((Entry1P *)mapentry)->value; - } - - } else if( raw_type == AST__FLOATTYPE ){ - raw_size = sizeof( float ); - if( nel == 0 ) { - raw = &( ((Entry0F *)mapentry)->value ); - } else { - raw = ((Entry1F *)mapentry)->value; - } - - } else if( raw_type == AST__STRINGTYPE ){ - raw_size = sizeof( const char * ); - if( nel == 0 ) { - raw = &( ((Entry0C *)mapentry)->value ); - } else { - raw = ((Entry1C *)mapentry)->value; - } - - } else if( raw_type == AST__OBJECTTYPE ){ - raw_size = sizeof( AstObject * ); - if( nel == 0 ) { - raw = &( ((Entry0A *)mapentry)->value ); - } else { - raw = ((Entry1A *)mapentry)->value; - } - - } else if( raw_type == AST__UNDEFTYPE ){ - raw = NULL; - - } else { - raw_size = 0; - raw = NULL; - astError( AST__INTER, "astMapGetElemA(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - raw_type ); - } - -/* Treat scalars as single-value vectors. */ - if( nel == 0 ) nel = 1; - -/* Ensure the requested element is within the bounds of the vector */ - if( elem >= nel || elem < 0 ) { - if( astOK ) { - astError( AST__MPVIN, "astMapGetElemA(KeyMap): Illegal vector " - "index %d supplied for KeyMap entry '%s' - should be " - "in the range 1 to %d.", status, elem + 1, key, nel + 1 ); - } - -/* Get a pointer to the requested raw value. */ - } else if( raw ){ - raw = (char *) raw + elem*raw_size; - -/* Convert the value, storing the result in the supplied buffer. Report an - error if conversion is not possible. */ - if( !ConvertValue( raw, raw_type, &avalue, AST__OBJECTTYPE, status ) && astOK ){ - astError( AST__MPGER, "astMapGetElemA(%s): The value of " - "element %d of KeyMap key \"%s\" cannot be read using " - "the requested data type.", status,astGetClass( this ), - elem + 1, key ); - -/* If succesful, return an ID value for the Object. */ - } else { - *value = avalue ? astMakeId( avalue ) : NULL; - } - } - -/* If the KeyError attribute is non-zero, report an error if the key is not - found */ - } else if( astGetKeyError( this ) && astOK ) { - astError( AST__MPKER, "astMapGetElemA(%s): No value was found for " - "%s in the supplied KeyMap.", status, astGetClass( this ), - key ); - } - -/* If an error occurred,return zero. */ - if( !astOK ) result = 0; - -/* Return the result.*/ - return result; -} - -static int MapDefined( AstKeyMap *this, const char *skey, int *status ) { -/* -*++ -* Name: -c astMapDefined -f AST_MAPDEFINED - -* Purpose: -* Check if a KeyMap contains a defined value for a key. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ast.h" -c int astMapDefined( AstKeyMap *this, const char *key ); -f RESULT = AST_MAPDEFINED( THIS, KEY, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function checks to see if a KeyMap contains a defined value for -* a given key. If the key is present in the KeyMap but has an -* undefined value it returns -c zero (unlike astMapHasKey which would return non-zero). -f .FALSE. (unlike AST_MAPHASKEY which would return .TRUE.). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the value to be retrieved. Trailing -* spaces are ignored. The supplied string is converted to upper -* case before use if the KeyCase attribute is currently set to zero. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapDefined() -f AST_MAPDEFINED = LOGICAL -c A non-zero value -f .TRUE. -* is returned if the requested key name is present in the KeyMap -* and has a defined value. - -*-- -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ - const char *key; /* Pointer to key string to use */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - int itab; /* Index of hash table element to use */ - int result; /* Returned flag */ - unsigned long hash; /* Full width hash value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapDefined", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Skip rest if the key was not found. */ - if( mapentry ) { - -/* Set the result depending on the entry data type. */ - if( mapentry->type == AST__UNDEFTYPE ){ - result = 0; - } else { - result = 1; - } - -/* If the KeyError attribute is non-zero, report an error if the key is not - found */ - } else if( astGetKeyError( this ) && astOK ) { - astError( AST__MPKER, "astMapDefined(%s): No value was found for " - "%s in the supplied KeyMap.", status, astGetClass( this ), - key ); - } - -/* If an error occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the result.*/ - return result; -} - -static int MapHasKey( AstKeyMap *this, const char *skey, int *status ) { -/* -*++ -* Name: -c astMapHasKey -f AST_MAPHASKEY - -* Purpose: -* Check if an entry with a given key exists in a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "keymap.h" -c int astMapHasKey( AstKeyMap *this, const char *key ) -f RESULT = AST_MAPHASKEY( THIS, KEY, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function returns a flag indicating if the KeyMap contains an -* entry with the given key. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the KeyMap entry. Trailing spaces are -* ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapHasKey() -f AST_MAPHASKEY = LOGICAL -c Non-zero if the key was found, and zero otherwise. -f .TRUE. if the key was found, and .FALSE. otherwise. - -* Notes: -c - A non-zero function value -f - .TRUE. -* is returned if the key exists but has an undefined value (that is, -* the returned value does not depend on whether the entry has a -* defined value or not). See also -c astMapDefined, which returns zero in such a case. -f AST_MAPDEFINED, which returns zero in such a case. -* - A function value of -c zero -f .FALSE. -* will be returned if an error has already occurred, or if this -* function should fail for any reason. - -*-- -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to entry in linked list */ - const char *key; /* Pointer to key string to use */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - int itab; /* Index of hash table element to use */ - int result; /* Returned value */ - unsigned long hash; /* Full width hash value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapHasKey", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Set a non-zero return value if the key was found. */ - if( mapentry ) result = 1; - -/* If an error has occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; - -} - -static void MapRemove( AstKeyMap *this, const char *skey, int *status ) { -/* -*++ -* Name: -c astMapRemove -f AST_MAPREMOVE - -* Purpose: -* Removed a named entry from a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "keymap.h" -c void astMapRemove( AstKeyMap *this, const char *key ) -f CALL AST_MAPREMOVE( THIS, KEY, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -c This function -f This routine -* removes a named entry from a KeyMap. It returns without action if the -* KeyMap does not contain the specified key. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the value to be retrieved. Trailing -* spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -f STATUS = INTEGER (Given and Returned) -f The global status. -*-- -*/ - -/* Local Variables: */ - const char *key; /* Pointer to key string to use */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - int itab; /* Index of hash table element to use */ - unsigned long hash; /* Full width hash value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapRemove", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry and remove it. */ - (void) FreeMapEntry( RemoveTableEntry( this, itab, key, status ), status ); -} - -static void MapRename( AstKeyMap *this, const char *soldkey, const char *snewkey, - int *status ) { -/* -*++ -* Name: -c astMapRename -f AST_MAPRENAME - -* Purpose: -* Rename an existing KeyMap entry. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "keymap.h" -c void astMapRename( AstKeyMap *this, const char *oldkey, const char *newkey ) -f CALL AST_MAPRENAME( THIS, OLDKEY, NEWKEY, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -c This function -f This routine -* associated a new key with an existing entry in a KeyMap. It returns -* without action if the oldkey does not exist in the KeyMap. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c oldkey -f OLDKEY = CHARACTER * ( * ) (Given) -* The character string identifying the entry to be renamed. Trailing -* spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -c newkey -f NEKEY = CHARACTER * ( * ) (Given) -* The new character string to associated with the renamed entry. -* Trailing spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -f STATUS = INTEGER (Given and Returned) -f The global status. -*-- -*/ - -/* Local Variables: */ - AstMapEntry *entry; /* Pointer to the entry being renamed */ - AstMapEntry *oldent; /* Pointer to old entry with new name */ - const char *oldkey; /* Pointer to key string to use */ - char oldkeybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - const char *newkey; /* Pointer to key string to use */ - char newkeybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - char *p; /* Pointer to next key character */ - int itab; /* Index of hash table element to use */ - int keylen; /* Length of supplied key string */ - int keymember; /* Identifier for new key */ - int there; /* Did the entry already exist in the KeyMap? */ - unsigned long hash; /* Full width hash value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Convert the supplied keys to upper case if required. */ - oldkey = ConvertKey( this, soldkey, oldkeybuf, AST__MXKEYLEN + 1, - "astMapRename", status ); - newkey = ConvertKey( this, snewkey, newkeybuf, AST__MXKEYLEN + 1, - "astMapRename", status ); - -/* Do nothing if the keys are the same. */ - if( strcmp( oldkey, newkey ) ){ - -/* Use the hash function to determine the element of the hash table in - which the old key will be stored. */ - itab = HashFun( oldkey, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. Remove it - from the list, but do not free it. */ - entry = RemoveTableEntry( this, itab, oldkey, status ); - -/* Skip rest if the key was not found. */ - if( entry ) { - -/* Store the new key string, and terminate it to exclude any trailing - spaces. */ - keylen = strlen( newkey ); - entry->key = astStore( (void *) entry->key, newkey, keylen + 1 ); - if( astOK ) { - p = (char *) entry->key + keylen; - while( --p >= entry->key ) { - if( *p == ' ' ) { - *p = 0; - } else { - break; - } - } - } - -/* Use the hash function to determine the element of the hash table in - which to store the entry with its new key. */ - itab = HashFun( entry->key, this->mapsize - 1, &(entry->hash), status ); - -/* Remove and free any existing entry with the given key from the table - element. */ - oldent = RemoveTableEntry( this, itab, entry->key, status ); - if( oldent ) { - keymember = oldent->keymember; - oldent = FreeMapEntry( oldent, status ); - there = 1; - } else { - keymember = -1; - there = 0; - } - -/* If the KeyMap is locked we report an error if an attempt is made to - introduce a new key. */ - if( !there && astGetMapLocked( this ) ) { - astError( AST__BADKEY, "astMapRename(%s): Failed to rename item " - "\"%s\" in a KeyMap to \"%s\": \"%s\" is not a known " - "item.", status, astGetClass( this ), oldkey, newkey, - newkey ); - } - -/* If all has gone OK, store the renamed entry at the head of the linked list - associated with the selected table entry. */ - if( astOK ) { - entry = AddTableEntry( this, itab, entry, keymember, status ); - -/* If anything went wrong, try to delete the renamed entry. */ - } else { - entry = FreeMapEntry( entry, status ); - } - } - } -} - -static int MapSize( AstKeyMap *this, int *status ) { -/* -*++ -* Name: -c astMapSize -f AST_MAPSIZE - -* Purpose: -* Get the number of entries in a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "keymap.h" -c int astMapSize( AstKeyMap *this ) -f RESULT = AST_MAPSIZE( THIS, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function returns the number of entries in a KeyMap. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapSize() -f AST_MAPSIZE = INTEGER -* The number of entries in the KeyMap. - -* Notes: -* - A function value of zero will be returned if an error has already -* occurred, or if this function should fail for any reason. - -*-- -*/ - -/* Local Variables: */ - int itab; /* Index of hash table element to use */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Add up the number of entries in all elements of the hash table. */ - for( itab = 0; itab < this->mapsize; itab++ ) result += this->nentry[ itab ]; - -/* Return the result. */ - return result; - -} - -static int MapLenC( AstKeyMap *this, const char *skey, int *status ) { -/* -*++ -* Name: -c astMapLenC -f AST_MAPLENC - -* Purpose: -* Get the number of characters in a character entry in a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "keymap.h" -c int astMapLenC( AstKeyMap *this, const char *key ) -f RESULT = AST_MAPLENC( THIS, KEY, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function returns the minimum length that a character variable -* must have in order to be able to store a specified entry in -* the supplied KeyMap. If the named entry is a vector entry, then the -* returned value is the length of the longest element of the vector -* value. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the KeyMap entry. Trailing -* spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapLenC() -f AST_MAPLENC = INTEGER -* The length (i.e. number of characters) of the longest formatted -* value associated with the named entry. -c This does not include the trailing null character. - -* Notes: -* - A function value of zero will be returned without error if the -* named entry cannot be formatted as a character string. -* - A function value of zero will be returned if an error has already -* occurred, or if this function should fail for any reason. - -*-- -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ - const char *key; /* Pointer to key string to use */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - int i; /* Element index */ - int itab; /* Index of hash table element to use */ - int l; /* Length of formatted vector element */ - int nel; /* Number of elements in raw vector */ - int raw_type; /* Data type of stored value */ - int result; /* Returned value */ - size_t raw_size; /* Size of a single raw value */ - unsigned long hash; /* Full width hash value */ - void *raw; /* Pointer to stored value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapLenC", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Skip rest if the key was not found. */ - if( mapentry ) { - -/* Get the address of the first raw value, and its data type. Also get - the size of each element of the vector. */ - nel = mapentry->nel; - raw_type = mapentry->type; - if( raw_type == AST__INTTYPE ){ - raw_size = sizeof( int ); - if( nel == 0 ) { - raw = &( ((Entry0I *)mapentry)->value ); - } else { - raw = ((Entry1I *)mapentry)->value; - } - - } else if( raw_type == AST__POINTERTYPE ){ - raw_size = sizeof( void * ); - if( nel == 0 ) { - raw = &( ((Entry0P *)mapentry)->value ); - } else { - raw = ((Entry1P *)mapentry)->value; - } - - } else if( raw_type == AST__DOUBLETYPE ){ - raw_size = sizeof( double ); - if( nel == 0 ) { - raw = &( ((Entry0D *)mapentry)->value ); - } else { - raw = ((Entry1D *)mapentry)->value; - } - - } else if( raw_type == AST__SINTTYPE ){ - raw_size = sizeof( short int ); - if( nel == 0 ) { - raw = &( ((Entry0S *)mapentry)->value ); - } else { - raw = ((Entry1S *)mapentry)->value; - } - - } else if( raw_type == AST__BYTETYPE ){ - raw_size = sizeof( unsigned char ); - if( nel == 0 ) { - raw = &( ((Entry0B *)mapentry)->value ); - } else { - raw = ((Entry1B *)mapentry)->value; - } - - } else if( raw_type == AST__FLOATTYPE ){ - raw_size = sizeof( float ); - if( nel == 0 ) { - raw = &( ((Entry0F *)mapentry)->value ); - } else { - raw = ((Entry1F *)mapentry)->value; - } - - } else if( raw_type == AST__STRINGTYPE ){ - raw_size = sizeof( const char * ); - if( nel == 0 ) { - raw = &( ((Entry0C *)mapentry)->value ); - } else { - raw = ((Entry1C *)mapentry)->value; - } - - } else if( raw_type == AST__OBJECTTYPE ){ - raw_size = sizeof( AstObject * ); - if( nel == 0 ) { - raw = &( ((Entry0A *)mapentry)->value ); - } else { - raw = ((Entry1A *)mapentry)->value; - } - - } else if( raw_type == AST__UNDEFTYPE ){ - raw_size = 0; - raw = NULL; - - } else { - raw_size = 0; - raw = NULL; - astError( AST__INTER, "astMapLenC(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - raw_type ); - } - -/* Treat scalars as single-value vectors. */ - if( nel == 0 ) nel = 1; - -/* Skip undefined values. */ - if( raw ) { - -/* Initialise the maximum length of any formatted value in the entry. */ - result= 0; - -/* Loop round all values in the vector. */ - for( i = 0; i < nel && astOK; i++ ) { - -/* Go through the motions of formatting the value. We do not actually - need the formatted string (just its length) so we provide a NULL pointer - for the output buffer. The entry is ignored if it cannot be formatted. - Note, the length returned by ConvertValue includes the terminating null, - so decrement it first. */ - l = ConvertValue( raw, raw_type, NULL, AST__STRINGTYPE, status ); - if( --l > result ) result = l; - -/* Increment the pointer to the next raw value. */ - raw = (char *) raw + raw_size; - } - } - } - -/* If an error has occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; - -} - -static int MapLength( AstKeyMap *this, const char *skey, int *status ) { -/* -*++ -* Name: -c astMapLength -f AST_MAPLENGTH - -* Purpose: -* Get the vector length of an entry in a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "keymap.h" -c int astMapLength( AstKeyMap *this, const char *key ) -f RESULT = AST_MAPLENGTH( THIS, KEY, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function returns the vector length of a named entry in a KeyMap, -* (that is, how many values are associated with the entry). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the KeyMap entry. Trailing -* spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapLength() -f AST_MAPLENGTH = INTEGER -* The length of the entry. One for a scalar, greater than one for -* a vector. A value of zero is returned if the KeyMap does not -* contain the named entry. - -* Notes: -* - A function value of zero will be returned if an error has already -* occurred, or if this function should fail for any reason. - -*-- -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to entry in linked list */ - const char *key; /* Pointer to key string to use */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - int itab; /* Index of hash table element to use */ - int result; /* Returned value */ - unsigned long hash; /* Full width hash value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapLength", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Skip rest if the key was not found. */ - if( mapentry ) { - -/* Store the netry length */ - result = mapentry->nel; - -/* Return 1 for a scalar. */ - if( result == 0 ) result = 1; - - } - -/* If an error has occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; - -} - -/* -*++ -* Name: -c astMapPutElem -f AST_MAPPUTELEM - -* Purpose: -* Put a value into an element of a vector value in a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "ast.h" -c void astMapPutElem( AstKeyMap *this, const char *key, int elem, -c type value ) -f CALL AST_MAPPUTELEM( THIS, KEY, ELEM, VALUE, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This is a set of functions for storing a value in a single element of -* a vector value in a KeyMap. You should replace in the generic -* function name -c astMapPutElem -f AST_MAPPUTELEM -* by an appropriate 1-character type code (see the "Data Type Codes" -* section below for the code appropriate to each supported data type). -* The supplied value is converted from the data type indicated by -* to the data type of the KeyMap entry before being stored (an error -* is reported if it is not possible to convert the value to the -* required data type). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the value to be retrieved. Trailing -* spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -c elem -f ELEM = INTEGER (Given) -* The index of the vector element to modify, starting at -c zero. -f one. -c value -f VALUE = type (Given) -* The value to store. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* KeyMap -* If the -c "elem" -f ELEM -* index is outside the range of the vector, the length of -* the vector will be increased by one element and the supplied -* value will be stored at the end of the vector in the new element. -* Table -* If the -c "elem" -f ELEM -* index is outside the range of the vector, an error will be -* reported. The number of elements in each cell of a column is -* specified when the column is created using -c astAddColumn. -f AST_ADDCOLUMN. - -* Notes: -* - If the entry originally holds a scalar value, it will be treated -* like a vector entry of length 1. -* - If the specified key cannot be found in the given KeyMap, or is -* found but has an undefined value, a new -* vector entry with the given name, and data type implied by , is -* created and the supplied value is stored in its first entry. - -* Data Type Codes: -* To select the appropriate -c function, you should replace in the generic function name -c astMapPutElem -f routine, you should replace in the generic routine name -f AST_MAPPUTELEM -* with a 1-character data type code, so as to match the data type type -* of the data you are processing, as follows: -c - D: double -c - F: float -c - I: int -c - C: "const" pointer to null terminated character string -c - A: Pointer to AstObject -c - P: Generic "void *" pointer -c - S: short int -c - B: Unsigned byte (i.e. char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - C: CHARACTER -f - A: INTEGER used to identify an AstObject -f - S: INTEGER*2 (short integer) -f - B: BYTE (unsigned) -* -c For example, astMapPutElemD would be used to put a "double" value, while -c astMapPutElemI would be used to put an "int" value, etc. For D or I, the -c supplied "value" parameter should be a double or int. For -c C, the supplied "value" parameter should be a pointer to a character -c string. For A, the supplied "value" parameter should be an AstObject -c pointer. -f For example, AST_MAPPUTELEMD would be used to put a DOUBLE PRECISION -f value, while AST_MAPPUTELEMI would be used to put an INTEGER value, etc. - -*-- -*/ -/* Define a macro to implement the function for a specific data type -(excluding "C" since that needs an extra parameter). */ -#define MAKE_MAPPUTELEM(X,Xtype,Itype) \ -static void MapPutElem##X( AstKeyMap *this, const char *skey, int elem, \ - Xtype value, int *status ) { \ -\ -/* Local Variables: */ \ - AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \ - const char *key; /* Pointer to key string to use */ \ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \ - int itab; /* Index of hash table element to use */ \ - int nel; /* Number of elements in raw vector */ \ - int new; /* Was a new uninitialised element created? */ \ - int raw_type; /* Data type of stored value */ \ - size_t raw_size; /* Size of a single raw value */ \ - unsigned long hash; /* Full width hash value */ \ - void *raw; /* Pointer to stored value */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Perform any necessary checks on the supplied value to be stored. */ \ - CHECK_##X \ -\ -/* Convert the supplied key to upper case if required. */ \ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPutElem" #X, \ - status ); \ -\ -/* Use the hash function to determine the element of the hash table in \ - which the key will be stored. */ \ - itab = HashFun( key, this->mapsize - 1, &hash, status ); \ -\ -/* Search the relevent table entry for the required MapEntry. */ \ - mapentry = SearchTableEntry( this, itab, key, status ); \ -\ -/* If the key was not found, or was found but has an undefined value, create \ - a new one with a single element, \ - and store the supplied value in it. */ \ - if( !mapentry || mapentry->type == AST__UNDEFTYPE ) { \ - astMapPut1##X( this, key, 1, &value, NULL ); \ -\ -/* If the key was found.... */ \ - } else { \ -\ -/* Get the current length of the vector (0=>scalar), and the data type. */ \ - nel = mapentry->nel; \ - raw_type = mapentry->type; \ -\ -/* Do each data type in turn. */ \ - if( raw_type == AST__INTTYPE ){ \ -\ -/* If the existing entry is scalar, create a new vector entry with the \ - same name, value, data type and comment. Then get a pointer to the new \ - entry, and indicate that we now have a vector entry of length 1. */ \ - if( nel == 0 ) { \ - astMapPut1I( this, key, 1, &( ((Entry0I *)mapentry)->value ), \ - mapentry->comment ); \ - mapentry = SearchTableEntry( this, itab, key, status ); \ - nel = 1; \ - } \ -\ -/* Get the address of the first raw value in the vector. Also get \ - the size of each element of the vector. */ \ - raw = ((Entry1I *)mapentry)->value; \ - raw_size = sizeof( int ); \ -\ -/* Handle other data type in the same way. */ \ - } else if( raw_type == AST__SINTTYPE ){ \ - if( nel == 0 ) { \ - astMapPut1S( this, key, 1, &( ((Entry0S *)mapentry)->value ), \ - mapentry->comment ); \ - mapentry = SearchTableEntry( this, itab, key, status ); \ - nel = 1; \ - } \ - raw = ((Entry1S *)mapentry)->value; \ - raw_size = sizeof( short int ); \ -\ - } else if( raw_type == AST__BYTETYPE ){ \ - if( nel == 0 ) { \ - astMapPut1B( this, key, 1, &( ((Entry0B *)mapentry)->value ), \ - mapentry->comment ); \ - mapentry = SearchTableEntry( this, itab, key, status ); \ - nel = 1; \ - } \ - raw = ((Entry1B *)mapentry)->value; \ - raw_size = sizeof( unsigned char ); \ -\ - } else if( raw_type == AST__DOUBLETYPE ){ \ - if( nel == 0 ) { \ - astMapPut1D( this, key, 1, &( ((Entry0D *)mapentry)->value ), \ - mapentry->comment ); \ - mapentry = SearchTableEntry( this, itab, key, status ); \ - nel = 1; \ - } \ - raw = ((Entry1D *)mapentry)->value; \ - raw_size = sizeof( double ); \ -\ - } else if( raw_type == AST__POINTERTYPE ){ \ - if( nel == 0 ) { \ - astMapPut1P( this, key, 1, &( ((Entry0P *)mapentry)->value ), \ - mapentry->comment ); \ - mapentry = SearchTableEntry( this, itab, key, status ); \ - nel = 1; \ - } \ - raw = ((Entry1P *)mapentry)->value; \ - raw_size = sizeof( void * ); \ -\ - } else if( raw_type == AST__FLOATTYPE ){ \ - if( nel == 0 ) { \ - astMapPut1F( this, key, 1, &( ((Entry0F *)mapentry)->value ), \ - mapentry->comment ); \ - mapentry = SearchTableEntry( this, itab, key, status ); \ - nel = 1; \ - } \ - raw = ((Entry1F *)mapentry)->value; \ - raw_size = sizeof( float ); \ -\ - } else if( raw_type == AST__STRINGTYPE ){ \ - if( nel == 0 ) { \ - astMapPut1C( this, key, 1, &( ((Entry0C *)mapentry)->value ), \ - mapentry->comment ); \ - mapentry = SearchTableEntry( this, itab, key, status ); \ - nel = 1; \ - } \ - raw = ((Entry1C *)mapentry)->value; \ - raw_size = sizeof( const char * ); \ -\ - } else if( raw_type == AST__OBJECTTYPE ){ \ - if( nel == 0 ) { \ - astMapPut1A( this, key, 1, &( ((Entry0A *)mapentry)->value ), \ - mapentry->comment ); \ - mapentry = SearchTableEntry( this, itab, key, status ); \ - nel = 1; \ - } \ - raw = ((Entry1A *)mapentry)->value; \ - raw_size = sizeof( AstObject * ); \ -\ - } else { \ - raw_size = 0; \ - raw = NULL; \ - astError( AST__INTER, "astMapPutElem(KeyMap): Illegal map entry " \ - "data type %d encountered (internal AST programming " \ - "error).", status, raw_type ); \ - } \ -\ -/* If the requested element is outside the bounds of the vector, extend \ - the vector by one element. */ \ - new = ( elem >= nel || elem < 0 ); \ - if( new ) { \ - elem = nel++; \ - raw = astGrow( raw, nel, raw_size ); \ - if( astOK ) { \ - mapentry->nel = nel; \ - if( raw_type == AST__INTTYPE ){ \ - ((Entry1I *)mapentry)->value = (int *) raw; \ - } else if( raw_type == AST__SINTTYPE ){ \ - ((Entry1S *)mapentry)->value = (short int *) raw; \ - } else if( raw_type == AST__BYTETYPE ){ \ - ((Entry1B *)mapentry)->value = (unsigned char *) raw; \ - } else if( raw_type == AST__DOUBLETYPE ){ \ - ((Entry1D *)mapentry)->value = (double *) raw; \ - } else if( raw_type == AST__POINTERTYPE ){ \ - ((Entry1P *)mapentry)->value = (void *) raw; \ - } else if( raw_type == AST__FLOATTYPE ){ \ - ((Entry1F *)mapentry)->value = (float *) raw; \ - } else if( raw_type == AST__STRINGTYPE ){ \ - ((Entry1C *)mapentry)->value = (const char **) raw; \ - } else if( raw_type == AST__OBJECTTYPE ){ \ - ((Entry1A *)mapentry)->value = (AstObject **) raw; \ - } \ - } \ - } \ -\ -/* Get a pointer to the requested element. */ \ - if( astOK ) { \ - raw = (char *) raw + elem*raw_size; \ -\ -/* Free any memory used by the value already in the requested element. */ \ - if( ! new ) { \ - if( raw_type == AST__STRINGTYPE ){ \ - char **cp = (char **) raw; \ - *cp = astFree( *cp ); \ - } else if( raw_type == AST__OBJECTTYPE ){ \ - AstObject **op = (AstObject **) raw; \ - if( *op ) *op = astAnnul( *op ); \ - } \ - } \ -\ -/* Convert the supplied value, storing the result in the requested element. \ - Report an error if conversion is not possible. */ \ - if( !ConvertValue( &value, Itype, raw, raw_type, status ) && astOK ){ \ - astError( AST__MPPER, "astMapPutElem" #X "(%s): The supplied " \ - "value cannot be converted to the data type of " \ - "KeyMap key \"%s\".", status, astGetClass( this ), \ - key ); \ -\ -/* For strings, the "raw" value is a copy of a pointer stored in the global \ - "convertvalue_strings" array. These pointers should never be freed other \ - than within the ConvertValue function (otherwise you can end up with \ - spurious "invalid pointer" errors). But the "raw" value will be freed \ - when as part of the KeyMap when the KeyMap is destroyed. So we replace \ - the "raw" value with a new copy. */ \ - } else if( raw_type == AST__STRINGTYPE ){ \ - char **cp = (char **) raw; \ - *cp = astStore( NULL, *cp, strlen( *cp ) + 1 ); \ - } \ - } \ - } \ -} - -/* Define macros which perform any necessary checks on the supplied value - to be stored. For Object entries, check that we are not adding a KeyMap - which already contains "this". This avoids circular dependencies. - Other types do not need any checks. */ -#define CHECK_A CheckCircle( this, value, "astMapPutElemA", status ); -#define CHECK_I -#define CHECK_B -#define CHECK_S -#define CHECK_D -#define CHECK_F -#define CHECK_C -#define CHECK_P - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPPUTELEM(I,int,AST__INTTYPE) -MAKE_MAPPUTELEM(D,double,AST__DOUBLETYPE) -MAKE_MAPPUTELEM(F,float,AST__FLOATTYPE) -MAKE_MAPPUTELEM(A,AstObject *,AST__OBJECTTYPE) -MAKE_MAPPUTELEM(P,void *,AST__POINTERTYPE) -MAKE_MAPPUTELEM(C,const char *,AST__STRINGTYPE) -MAKE_MAPPUTELEM(S,short int,AST__SINTTYPE) -MAKE_MAPPUTELEM(B,unsigned char,AST__BYTETYPE) - -/* Undefine the macro. */ -#undef MAKE_MAPPUTELEM -#undef CHECK_A -#undef CHECK_I -#undef CHECK_B -#undef CHECK_S -#undef CHECK_D -#undef CHECK_F -#undef CHECK_C -#undef CHECK_P - - -static int MapType( AstKeyMap *this, const char *skey, int *status ) { -/* -*++ -* Name: -c astMapType -f AST_MAPTYPE - -* Purpose: -* Get the data type of an entry in a KeyMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "keymap.h" -c int astMapType( AstKeyMap *this, const char *key ) -f RESULT = AST_MAPTYPE( THIS, KEY, STATUS ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function returns a value indicating the data type of a -* named entry in a KeyMap. This is the data type which was used when the -* entry was added to the KeyMap. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the KeyMap. -c key -f KEY = CHARACTER * ( * ) (Given) -* The character string identifying the KeyMap entry. Trailing -* spaces are ignored. -* The supplied string is converted to upper case before use if the -* KeyCase attribute is currently set to zero. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapType() -f AST_MAPTYPE = INTEGER -* One of AST__INTTYPE (for integer), AST__SINTTYPE (for -c short int), -f INTEGER*2), -* AST__BYTETYPE (for unsigned bytes -c - i.e. unsigned chars -* ) AST__DOUBLETYPE (for double -* precision floating point), AST__FLOATTYPE (for single -* precision floating point), AST__STRINGTYPE (for character string), -* AST__OBJECTTYPE (for AST Object pointer), AST__POINTERTYPE (for -* arbitrary C pointer) or AST__UNDEFTYPE (for undefined values -* created by -c astMapPutU). -f AST_MAPPUTU). -* AST__BADTYPE is returned if the supplied key is not found in the KeyMap. - -* Notes: -* - A function value of AST__BADTYPE will be returned if an error has -* already occurred, or if this function should fail for any reason. - -*-- -*/ - -/* Local Variables: */ - AstMapEntry *mapentry; /* Pointer to entry in linked list */ - const char *key; /* Pointer to key string to use */ - char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ - int itab; /* Index of hash table element to use */ - int result; /* Returned value */ - unsigned long hash; /* Full width hash value */ - -/* Initialise */ - result = AST__BADTYPE; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Convert the supplied key to upper case if required. */ - key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapType", - status ); - -/* Use the hash function to determine the element of the hash table in - which the key will be stored. */ - itab = HashFun( key, this->mapsize - 1, &hash, status ); - -/* Search the relevent table entry for the required MapEntry. */ - mapentry = SearchTableEntry( this, itab, key, status ); - -/* Store the type if found. */ - if( mapentry ) result = mapentry->type; - -/* If an error has occurred, return zero. */ - if( !astOK ) result = AST__BADTYPE; - -/* Return the result. */ - return result; - -} - -static const char *MapIterate( AstKeyMap *this, int reset, int *status ) { -/* -*+ -* Name: -* astMapIterate - -* Purpose: -* Iterate through the keys in a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* const char *astMapIterate( AstKeyMap *this, int reset, int *status ) - -* Class Membership: -* KeyMap method. - -* Description: -* If "reset" is non-zero, this function returns a pointer to a string -* holding the first key in the KeyMap. On subsequent invocation (if -* reset is zero) it returns a pointer to the next key in the KeyMap. The -* context is stored within the KeyMap structure, so calls on different -* KeyMaps can be mixed. -* -* The order in which keys are returned is determined by the KeyMap -* SortBy attribute. - -* Parameters: -* this -* Pointer to the KeyMap. -* reset -* If non-zero, return the first key in the KeyMap. Otherwise, -* returns the key following the one returned by the previous -* invocation of this function. - -* Returned Value: -* A pointer to the null-terminated string holding the next key, -* or NULL if there are no more keys in the KeyMap. The returned -* string should NOT be freed or modified. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the AST error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapEntry *entry; /* Pointer to the entry */ - const char *key; /* Pointer value to return */ - int itab; /* Index into hash table */ - int sortby; /* The value of the SortBy attribute */ - -/* Initialise. */ - key = NULL; - -/* Check the global error status. */ - if ( !astOK ) return key; - -/* Get the SortBy value. */ - sortby = astGetSortBy( this ); - -/* First deal with unsorted keys. */ - if( sortby == SORTBY_NONE ) { - -/* Get the index of the hash table to check first. Also get a pointer to - the entry within the hash table to check next. */ - if( reset ){ - itab = 0; - entry = this->table[ 0 ]; - } else { - itab = this->iter_itab; - entry = this->iter_entry; - } - -/* Move through elements of the hash table until we have a non-null entry. */ - while( !entry && ++itab < this->mapsize ) { - entry = this->table[ itab ]; - } - -/* Return a pointer to the key. */ - if( entry ) { - key = entry->key; - -/* Move on to the next entry in the unsorted linked list, saving the context - in the KeyMap structure. */ - this->iter_itab = itab; - this->iter_entry = entry->next; - } - -/* Now deal with sorted keys. */ - } else { - -/* If starting from the beginning, use the "first" entry. Otherwise, use - the nxt entry. */ - if( reset ) { - entry = this->first; - } else { - entry = this->iter_entry; - } - -/* If we have an entry, return a pointer to its key, and then update the - context to point to the next entry in the *sorted* list. */ - if( entry ) { - key = entry->key; - this->iter_entry = entry->snext; - } - } - -/* If no more entries were found, reset the context in the KeyMap - structure. */ - if( ! key ) { - this->iter_itab = 0; - this->iter_entry = NULL; - } - -/* Return the result.*/ - return key; -} - -static void NewTable( AstKeyMap *this, int size, int *status ){ -/* -* Name: -* NewTable - -* Purpose: -* Create a new hash table. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void NewTable( AstKeyMap *this, int size, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function removes any existing hash table and allocates memory -* for a new one of the specified size (except that the supplied size -* is modified to be the next higher power of 2). The table is -* initialised to indicate that it is empty. - -* Parameters: -* this -* Pointer to the KeyMap. -* size -* The reuqired size of the hash table. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int i; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Ensure the table size is at least MIN_TABLE_SIZE and is a power of 2. */ - if( size <= MIN_TABLE_SIZE ) { - size = MIN_TABLE_SIZE; - } else { - size = (int) ( 0.5 + pow( 2.0, ceil( log( size )/log( 2.0 ) ) ) ); - } - -/* Remove any existing entries. */ - for( i = 0; i < this->mapsize; i++ ) FreeTableEntry( this, i, status ); - -/* Do nothing more if the table size is not changing. */ - if( size != this->mapsize ) { - -/* Modify the size of the existing table. */ - this->mapsize = size; - this->table = astGrow( this->table, size, sizeof( AstMapEntry * ) ); - this->nentry = astGrow( this->nentry, size, sizeof( int ) ); - -/* Initialise the new table. */ - if( astOK ) { - for( i = 0; i < size; i++ ) { - this->table[ i ] = NULL; - this->nentry[ i ] = 0; - } - } - } -} - -static void RemoveFromObjectList( AstKeyMap *this, AstMapEntry *entry, - int *status ){ -/* -* Name: -* RemoveFromObjectList - -* Purpose: -* Remove an entry from the linked-list of AST__OBJECTTYPE entries. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void RemoveFromObjectList( AstKeyMap *this, AstMapEntry *entry, -* int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function removes the supplied MapEntry from the linked list of -* AST__OBJECTTYPE entries. - -* Parameters: -* this -* Pointer to the KeyMap. -* entry -* Pointer to the MapEntry to be removed. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMapEntry *a; /* Previous entry */ - AstMapEntry *b; /* Next entry */ - Entry0A *scalar; /* Pointer to a scalar AST__OBJECTTYPE entry */ - Entry1A *vector; /* Pointer to a vector AST__OBJECTTYPE entry */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do nothing if the entry does not hold AST Object pointers. */ - if( entry->type == AST__OBJECTTYPE ) { - -/* Get pointers to the MapEntries before and after the entry being - removed. At the same time, nullify both pointers in the entry itself. */ - if( entry->nel == 0 ) { - scalar = (Entry0A *) entry; - a = scalar->prev; - b = scalar->next; - scalar->prev = NULL; - scalar->next = NULL; - } else { - vector = (Entry1A *) entry; - a = vector->prev; - b = vector->next; - vector->prev = NULL; - vector->next = NULL; - } - -/* Set the forward link in the previous entry. */ - if( a ) { - if( a->nel == 0 ) { - scalar = (Entry0A *) a; - scalar->next = b; - } else { - vector = (Entry1A *) a; - vector->next = b; - } - -/* If we are removing the list head, store the following entry as the new head. */ - } else { - this->firstA = b; - } - -/* Set the backward link in the next entry. */ - if( b ) { - if( b->nel == 0 ) { - scalar = (Entry0A *) b; - scalar->prev = a; - } else { - vector = (Entry1A *) b; - vector->prev = a; - } - } - } -} - -static void RemoveFromSortedList( AstKeyMap *this, AstMapEntry *entry, - int *status ){ -/* -* Name: -* RemoveFromSortedList - -* Purpose: -* Remove an entry from the linked-list of sorted KeyMap entries. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void RemoveFromSortedList( AstKeyMap *this, AstMapEntry *entry, -* int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function removes the supplied MapEntry from the linked list of -* sorted MapEntries. - -* Parameters: -* this -* Pointer to the KeyMap. -* entry -* Pointer to the MapEntry to be removed. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMapEntry *next; /* Next higher MapEntry */ - AstMapEntry *prev; /* Next lower MapEntry */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get pointers to the entries on either side of the entry to be removed. */ - next = entry->snext; - prev = entry->sprev; - -/* If the entry is not in the sorted list, abort. */ - if( next && prev ) { - -/* Connect the previous to the next, bypassing the entry being removed. */ - next->sprev = prev; - prev->snext = next; - -/* NULLify the next and previous entries stored in the entry being - removed. */ - entry->snext = NULL; - entry->sprev = NULL; - -/* Decrement the number of entries in the sorted list. */ - (this->nsorted)--; - -/* If the entry being removed is the first entry, store a pointer to the new - first entry. */ - if( this->nsorted == 0 ) { - this->first = NULL; - } else if( entry == this->first ) { - this->first = next; - } - } -} - -static AstMapEntry *RemoveTableEntry( AstKeyMap *this, int itab, - const char *key, int *status ){ -/* -* Name: -* RemoveTableEntry - -* Purpose: -* Remove an entry from a linked-list of KeyMap entries. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* AstMapEntry *RemoveTableEntry( AstKeyMap *this, int itab, -* const char *key, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function removes any entries with the specified key from the -* linked-list of entries stored at the specified entry of the hash -* table. If the supplied key is found in the list, a pointer to the -* first removed entry is returned. Otherwise, a NULL pointer is returned. - -* Parameters: -* this -* Pointer to the KeyMap. -* itab -* Index of the hash table element to be searched. -* key -* The key string to be searched for. Trailing spaces are ignored. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the removed Entry, or NULL if no matching entry found. - -*/ - -/* Local Variables: */ - AstMapEntry **link; /* Address to store foward link */ - AstMapEntry *next; /* Pointer to next Entry to copy */ - AstMapEntry *result; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* The "next" variable holds the address of the next MapEntry to be - checked. Initialise this to the MapEntry at the head of the linked - list associated with the supplied element of the hash table. */ - next = this->table[ itab ]; - -/* The "link" variable holds the address of the location at which the - pointer to the MapEntry following the removed MapEntry should be stored. - Initialise this to be the address of the hash table element. */ - link = &( this->table[ itab ] ); - -/* Loop round until we have checked all entries. */ - while( next && astOK ) { - -/* If the key for the current entry macthes the supplied key... */ - if( !KeyCmp( next->key, key ) ) { - -/* Remove the MapEntry from the list sorted by key. */ - RemoveFromSortedList( this, next, status ); - -/* If the entry is of type AST__OBJECTTYPE, remove it from the - list of AST__OBJECTTYPE entries. */ - RemoveFromObjectList( this, next, status ); - -/* Store a pointer to the next MapEntry in the list, replacing the - original pointer to the MapEntry which is being deleted. */ - *link = next->next; - -/* Return a pointer to the first matching MapEntry. Free any subsequent - matching MapEntries. */ - if( result ) { - FreeMapEntry( next, status ); - } else { - result = next; - } - -/* Decrement the number of entries in the linked list. */ - this->nentry[ itab ]--; - -/* Set up the next MapEntry to be freed. */ - next = *link; - -/* If the key for the current entry does not match the supplied key... */ - } else { - -/* Update the address at which to store the pointer to the next MapEntry - in the list. */ - link = &(next->next); - -/* Update the address of the next MapEntry in the list. */ - next = next->next; - } - } - -/* Return the result */ - return result; -} - -static AstMapEntry *SearchTableEntry( AstKeyMap *this, int itab, const char *key, int *status ){ -/* -* Name: -* SearchTableEntry - -* Purpose: -* Search an element of a has table for a given key. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* AstMapEntry *SearchTableEntry( AstKeyMap *this, int itab, const char *key, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function searches the specified element of the KeyMaps hash table -* until an element is found which has a key matching the supplied key. -* The address of this entry is returned. If no suitable entry is found, -* then NULL is returned. - -* Parameters: -* this -* Pointer to the KeyMap. -* itab -* The index of the hash table to be searched. -* key -* The key string to be searched for. Trailing spaces are ignored. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The address of the first MapEntry in the linked list which refers -* to the given key, or NULL if the key is not found. - -*/ - -/* Local Variables: */ - AstMapEntry *next; /* Pointer to next Entry to check */ - AstMapEntry *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* The "next" variable holds the address of the next MapEntry to be - checked. Initialise this to the supplied MapEntry. */ - next = this->table[ itab ]; - -/* Loop round until we have checked all entries. */ - while( next ) { - -/* If the key for the current entry matches the supplied key, store the - MapEntry pointer and break. */ - if( !KeyCmp( next->key, key ) ) { - result = next; - break; - } - -/* Update the address of the next MapEntry in the list. */ - next = next->next; - - } - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* KeyMap member function (over-rides the astSetAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function assigns an attribute value for a KeyMap, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the KeyMap. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstKeyMap *this; /* Pointer to the KeyMap structure */ - int ival; /* Attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the KeyMap structure. */ - this = (AstKeyMap *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* SizeGuess. */ -/* ---------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "sizeguess= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetSizeGuess( this, ival ); - -/* KeyCase. */ -/* --------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "keycase= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetKeyCase( this, ival ); - -/* KeyError. */ -/* --------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "keyerror= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetKeyError( this, ival ); - -/* MapLocked. */ -/* --------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "maplocked= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetMapLocked( this, ival ); - -/* SortBy. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "sortby= %n%*s %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetSortBy( this, SortByInt( setting + ival, "astSetAttrib", status ) ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetKeyCase( AstKeyMap *this, int keycase, int *status ) { -/* -*+ -* Name: -* astSetKeyCase - -* Purpose: -* Set the value of the KeyCase attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astSetKeyCase( AstKeyMap *this, int keycase ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function sets a new value for the KeyCase attribute of a -* KeyMap. It reports an error if the KeyMap contains any entries. - -* Parameters: -* this -* Pointer to the KeyMap. -* keycase -* The new attribute value. - -*- -*/ - -/* Local Variables: */ - int ok; /* Can the KeyCase value be changed? */ - int itab; /* Index into hash table */ - int newval; /* New KeyCase value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Normalise the new value */ - newval = keycase ? 1 : 0; - -/* If the KeyCase value is to be changed, see if the KeyMap is empty. */ - ok = 1; - if( astGetKeyCase( this ) != newval ) { - for( itab = 0; itab < this->mapsize; itab++ ) { - if( this->nentry[ itab ] > 0 ) { - ok = 0; - break; - } - } - } - -/* If not report an error. */ - if( !ok ) { - astError( AST__NOWRT, "astSetAttrib(KeyMap): Illegal attempt to " - "change the KeyCase attribute of a non-empty KeyMap." , status); - -/* Otherwise, store the new value. */ - } else { - this->keycase = newval; - } -} - -static void SetKeyError( AstKeyMap *this, int keyerror, int *status ) { -/* -*+ -* Name: -* astSetKeyError - -* Purpose: -* Set the value of the KeyError attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astSetKeyError( AstKeyMap *this, int keyerror ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function sets the value of the KeyError attribute for a -* KeyMap. It also sets the attribute recursively in any KeyMaps -* contained within the supplied KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap. -* keyerror -* The new value for the attribute. -*- -*/ - -/* Local Variables: */ - AstMapEntry *next; /* Pointer to next Entry to copy */ - AstObject **obj_list; /* List of pointers to AST Object entries */ - int i; /* Index into hash table */ - int iel; /* Index of current vector element */ - int nel; /* Number of elements in vector */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Set the KeyError value in the supplied KeyMap. */ - this->keyerror = keyerror ? 1 : 0; - -/* Loop round each entry in the hash table. */ - for( i = 0; i < this->mapsize; i++ ) { - -/* Get a pointer to the next KeyMap entry. */ - next = this->table[ i ]; - -/* Loop round all entries in this element of the hash table. */ - while( next && astOK ) { - -/* If this entry has an Object data type, see if holds any KeyMaps. */ - if( next->type == AST__OBJECTTYPE ) { - -/* Get the number of objects to check, and a pointer to the first. */ - nel = next->nel; - if( nel == 0 ) { - obj_list = &( ((Entry0A *)next)->value ); - nel = 1; - } else { - obj_list = ((Entry1A *)next)->value; - } - -/* Loop round checking all Objects. */ - for( iel = 0; iel < nel; iel++ ) { - -/* If this Object is a KeyMap, set its KeyError attribute. */ - if( astIsAKeyMap( obj_list[ iel ] ) ) { - astSetKeyError( (AstKeyMap *) obj_list[ iel ], keyerror ); - } - } - } - -/* Get a pointer to the next entry. */ - next = next->next; - } - } -} - -static void SetMapLocked( AstKeyMap *this, int maplocked, int *status ) { -/* -*+ -* Name: -* astSetMapLocked - -* Purpose: -* Set the value of the MapLocked attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astSetMapLocked( AstKeyMap *this, int maplocked ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function sets the value of the MapLocked attribute for a -* KeyMap. It also sets the attribute recursively in any KeyMaps -* contained within the supplied KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap. -* maplocked -* The new value for the attribute. -*- -*/ - -/* Local Variables: */ - AstMapEntry *next; /* Pointer to next Entry to copy */ - AstObject **obj_list; /* List of pointers to AST Object entries */ - int i; /* Index into hash table */ - int iel; /* Index of current vector element */ - int nel; /* Number of elements in vector */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Set the MapLocked value in the supplied KeyMap. */ - this->maplocked = maplocked ? 1 : 0; - -/* Loop round each entry in the hash table. */ - for( i = 0; i < this->mapsize; i++ ) { - -/* Get a pointer to the next KeyMap entry. */ - next = this->table[ i ]; - -/* Loop round all entries in this element of the hash table. */ - while( next && astOK ) { - -/* If this entry has an Object data type, see if holds any KeyMaps. */ - if( next->type == AST__OBJECTTYPE ) { - -/* Get the number of objects to check, and a pointer to the first. */ - nel = next->nel; - if( nel == 0 ) { - obj_list = &( ((Entry0A *)next)->value ); - nel = 1; - } else { - obj_list = ((Entry1A *)next)->value; - } - -/* Loop round checking all Objects. */ - for( iel = 0; iel < nel; iel++ ) { - -/* If this Object is a KeyMap, set its MapLocked attribute. */ - if( astIsAKeyMap( obj_list[ iel ] ) ) { - astSetMapLocked( (AstKeyMap *) obj_list[ iel ], maplocked ); - } - } - } - -/* Get a pointer to the next entry. */ - next = next->next; - } - } -} - -static void SetSizeGuess( AstKeyMap *this, int sizeguess, int *status ) { -/* -*+ -* Name: -* astSetSizeGuess - -* Purpose: -* Set the value of the SizeGuess attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astSetSizeGuess( AstKeyMap *this, int sizeguess ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function sets a new value for the SizeGuess attribute of a -* KeyMap. It reports an error if the KeyMap contains any entries. - -* Parameters: -* this -* Pointer to the KeyMap. -* sizeguess -* The new attribute value. - -*- -*/ - -/* Local Variables: */ - int empty; /* Is the KeyMap empty? */ - int itab; /* Index into hash table */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* See if the KeyMap is empty. */ - empty = 1; - for( itab = 0; itab < this->mapsize; itab++ ) { - if( this->nentry[ itab ] > 0 ) { - empty = 0; - break; - } - } - -/* If not report an error. */ - if( !empty ) { - astError( AST__NOWRT, "astSetAttrib(KeyMap): Illegal attempt to " - "change the SizeGuess attribute of a non-empty KeyMap." , status); - -/* Otherwise, store the new value and change the size of the hash - table. */ - } else { - this->sizeguess = sizeguess; - NewTable( this, sizeguess/MAX_ENTRIES_PER_TABLE_ENTRY, status ); - } -} - -static void SetSortBy( AstKeyMap *this, int sortby, int *status ) { -/* -*+ -* Name: -* astSetSortBy - -* Purpose: -* Set the value of the SortBy attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* void astSetSortBy( AstKeyMap *this, int sortby ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function sets the value of the SortBy attribute for a -* KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap. -* sortby -* The new value for the attribute. -*- -*/ - -/* Local Variables: */ - int oldval; /* The old sortby value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the old SortBy value. */ - oldval = astGetSortBy( this ); - -/* Set the new SortBy value. */ - this->sortby = sortby; - -/* If the value has changed, re-sort the keys. */ - if( oldval != sortby ) SortEntries( this, status ); - -} - -static size_t SizeOfEntry( AstMapEntry *entry, int *status ){ -/* -* Name: -* SizeOfEntry - -* Purpose: -* Return the size of the supplied MapEntry structure. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* size_t SizeOfEntry( AstMapEntry *entry, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function returns the size of the supplied MapEntry structure. - -* Parameters: -* entry -* Pointer to the MapEntry. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The size of the MapEntry structure. This does not include the size -* of any data for which pointers are stored in the MapEntry structure. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - size_t result; /* Returned value */ - int nel; /* Entry length */ - int type; /* Data type */ - -/* Initialise. */ - result = 0; - -/* Check the global error status and the supplied pointer. */ - if ( !astOK || !entry ) return result; - -/* Get the data type and length of the MapEntry. */ - type = entry->type; - nel = entry->nel; - -/* Deal with each type. */ - if( type == AST__STRINGTYPE ) { - result = ( nel == 0 ) ? sizeof( Entry0C ) : sizeof( Entry1C ); - - } else if( type == AST__OBJECTTYPE ) { - result = ( nel == 0 ) ? sizeof( Entry0A ) : sizeof( Entry1A ); - - } else if( type == AST__INTTYPE ) { - result = ( nel == 0 ) ? sizeof( Entry0I ) : sizeof( Entry1I ); - - } else if( type == AST__POINTERTYPE ) { - result = ( nel == 0 ) ? sizeof( Entry0P ) : sizeof( Entry1P ); - - } else if( type == AST__SINTTYPE ) { - result = ( nel == 0 ) ? sizeof( Entry0S ) : sizeof( Entry1S ); - - } else if( type == AST__BYTETYPE ) { - result = ( nel == 0 ) ? sizeof( Entry0B ) : sizeof( Entry1B ); - - } else if( type == AST__DOUBLETYPE ) { - result = ( nel == 0 ) ? sizeof( Entry0D ) : sizeof( Entry1D ); - - } else if( type == AST__FLOATTYPE ) { - result = ( nel == 0 ) ? sizeof( Entry0F ) : sizeof( Entry1F ); - - } else if( type == AST__UNDEFTYPE ) { - result = sizeof( AstMapEntry ); - -/* Report an error if the data type is unknown. */ - } else { - astError( AST__INTER, "SizeOfEntry(KeyMap): Illegal map entry data " - "type %d encountered (internal AST programming error).", status, - type ); - } - -/* Return the result. */ - return result; -} - -static int SortByInt( const char *sortby, const char *method, int *status ){ -/* -* Name: -* SortByInt - -* Purpose: -* Get the integer associated with a string SortBy value. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* int SortByInt( const char *sortby, const char *method, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function returns the integer associated with the supplied -* string SortBy value. - -* Parameters: -* sortby -* Pointer to the string SortBy value (case insensitive). -* method -* Pointer to a string holding the name of the calling method for -* inclusion in error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The associated SortBy integer. - -*/ - -/* Local Variables: */ - int result; /* The returned integer */ - -/* Initialise. */ - result = SORTBY_NONE; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check each known value. */ - if( astChrMatch( sortby, "None" ) ) { - result = SORTBY_NONE; - - } else if( astChrMatch( sortby, "AgeUp" ) ) { - result = SORTBY_AGEUP; - - } else if( astChrMatch( sortby, "AgeDown" ) ) { - result = SORTBY_AGEDOWN; - - } else if( astChrMatch( sortby, "KeyAgeUp" ) ) { - result = SORTBY_KEYAGEUP; - - } else if( astChrMatch( sortby, "KeyAgeDown" ) ) { - result = SORTBY_KEYAGEDOWN; - - } else if( astChrMatch( sortby, "KeyUp" ) ) { - result = SORTBY_KEYUP; - - } else if( astChrMatch( sortby, "KeyDown" ) ) { - result = SORTBY_KEYDOWN; - - } else { - astError( AST__INTER, "%s(KeyMap): Illegal SortBy value %s " - "encountered.", status, method, sortby ); - } - -/* Return the result. */ - return result; -} - -static const char *SortByString( int sortby, const char *method, int *status ){ -/* -* Name: -* SortByString - -* Purpose: -* Get the string associated with an integer SortBy value. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* const char *SortByString( int sortby, const char *method, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function returns the string associated with the supplied -* integer SortBy value. - -* Parameters: -* sortby -* The integer SortBy value. -* method -* Pointer to a string holding the name of the calling method for -* inclusion in error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the associated SortBy string. - -*/ - -/* Local Variables: */ - const char *result; /* The returned string */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check each value. */ - if( sortby == SORTBY_NONE ) { - result = "None"; - - } else if( sortby == SORTBY_AGEUP ) { - result = "AgeUp"; - - } else if( sortby == SORTBY_AGEDOWN ) { - result = "AgeDown"; - - } else if( sortby == SORTBY_KEYAGEUP ) { - result = "KeyAgeUp"; - - } else if( sortby == SORTBY_KEYAGEDOWN ) { - result = "KeyAgeDown"; - - } else if( sortby == SORTBY_KEYUP ) { - result = "KeyUp"; - - } else if( sortby == SORTBY_KEYDOWN ) { - result = "KeyDown"; - - } else { - astError( AST__INTER, "%s(KeyMap): Illegal integer SortBy value %d " - "encountered (internal AST programming error).", status, - method, sortby ); - } - -/* Return the result. */ - return result; -} - -static void SortEntries( AstKeyMap *this, int *status ){ -/* -* Name: -* SortEntries - -* Purpose: -* Ensure the entries in a KeyMap are sorted correctly. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* void SortEntries( AstKeyMap *this, int *status ) - -* Class Membership: -* KeyMap member function. - -* Description: -* This function sorts all the entries in the supplied KeyMap in -* the manner indicated by the SortBy attribute value in the KeyMap. -* A double linked list is maintained indicating the ordering, with -* the first entry in the sorted list being pointed to by "this->first". -* Each entry contains "snext" and "sprev" pointers that point to the -* next and previous entries in the sorted list. The number of entries -* in the sorted list (which should usually equal the total number of -* entries currently in the KeyMap), is stored in "this->nsorted". - -* Parameters: -* this -* Pointer to the KeyMap. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMapEntry **ents; - AstMapEntry **pent; - AstMapEntry **a; - AstMapEntry **b; - AstMapEntry *entry; - int i; - int nent; - int sortby; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Empty the sorted list. */ - this->nsorted = 0; - this->first = NULL; - -/* Get the SortBy value. */ - sortby = astGetSortBy( this ); - -/* Do nothing more if no sorting is required. */ - if( sortby != SORTBY_NONE ) { - -/* Get the number of entries in the keyMap. */ - nent = astMapSize( this ); - -/* Only sort if the KeyMap is not empty. */ - if( nent > 0 ) { - -/* Allocate an array with one element for each entry. Each element is a - pointer to a MapEntry structure. */ - ents = astMalloc( sizeof( *ents )*nent ); - if( astOK ) { - -/* Loop round all entries in the hash table. */ - pent = ents; - for( i = 0; i < this->mapsize; i++ ) { - -/* Get a pointer to the next KeyMap entry. */ - entry = this->table[ i ]; - -/* Loop round all entries in this element of the hash table. */ - while( entry ) { - -/* Store the sorting method in the MapEntry. */ - entry->sortby = sortby; - -/* Put a pointer to the MapEntry into the array. */ - *(pent++) = entry; - -/* Update the address of the next MapEntry in the source. */ - entry = entry->next; - } - } - -/* No need for sorting if there is only one entry. */ - if( nent == 1 ) { - ents[ 0 ]->snext = ents[ 0 ]; - ents[ 0 ]->sprev = ents[ 0 ]; - -/* Sort the array of pointers if there is more than one entry... */ - } else { - qsort( ents, nent, sizeof( *ents ), CompareEntries ); - -/* Establish the double linked list. */ - a = ents; - b = ents + 1; - for( i = 1; i < nent; i++ ) { - (*b)->sprev = *a; - (*a)->snext = *b; - a = b++; - } - - b = ents; - (*b)->sprev = *a; - (*a)->snext = *b; - - } - -/* Store a pointer to the first entry in the sorted list. */ - this->first = ents[ 0 ]; - -/* Store the number of entrie sin the sorted list. */ - this->nsorted = nent; - } - -/* Free resources. */ - ents = astFree( ents ); - } - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* KeyMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a KeyMap's attributes. - -* Parameters: -* this -* Pointer to the KeyMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstKeyMap *this; /* Pointer to the KeyMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the KeyMap structure. */ - this = (AstKeyMap *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* SizeGuess. */ -/* ---------- */ - if ( !strcmp( attrib, "sizeguess" ) ) { - result = astTestSizeGuess( this ); - -/* KeyCase. */ -/* --------- */ - } else if ( !strcmp( attrib, "keycase" ) ) { - result = astTestKeyCase( this ); - -/* KeyError. */ -/* --------- */ - } else if ( !strcmp( attrib, "keyerror" ) ) { - result = astTestKeyError( this ); - -/* MapLocked. */ -/* --------- */ - } else if ( !strcmp( attrib, "maplocked" ) ) { - result = astTestMapLocked( this ); - -/* SortBy. */ -/* ------- */ - } else if ( !strcmp( attrib, "sortby" ) ) { - result = astTestSortBy( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static int TestSizeGuess( AstKeyMap *this, int *status ) { -/* -*+ -* Name: -* astTestSizeGuess - -* Purpose: -* Test the value of the SizeGuess attribute for a KeyMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "keymap.h" -* int astTestSizeGuess( AstKeyMap *this ) - -* Class Membership: -* KeyMap method. - -* Description: -* This function returns a non-zero value if the SizeGuess attribute -* has been set in a KeyMap. - -* Parameters: -* this -* Pointer to the KeyMap. - -* Returned Value: -* Non-zero if the SizeGuess attribute is set. - -* Notes: -* - A value of zero is returned if this function is invoked with the -* global error status set. - -*- -*/ - -/* Local Variables: */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Return non-zero if the attribute is still set to its "not set" value. */ - return ( this->sizeguess != INT_MAX ); -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ - -/* -*att++ -* Name: -* SizeGuess - -* Purpose: -* The expected size of the KeyMap. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This is attribute gives an estimate of the number of entries that -* will be stored in the KeyMap. It is used to tune the internal -* properties of the KeyMap for speed and efficiency. A larger value -* will result in faster access at the expense of increased memory -* requirements. However if the SizeGuess value is much larger than -* the actual size of the KeyMap, then there will be little, if any, -* speed gained by making the SizeGuess even larger. The default value -* is 300. -* -* The value of this attribute can only be changed if the KeyMap is -* empty. Its value can be set conveniently when creating the KeyMap. -* An error will be reported if an attempt is made to set or clear the -* attribute when the KeyMap contains any entries. - -* Applicability: -* KeyMap -* All KeyMaps have this attribute. -*att-- -*/ - -/* -*att++ -* Name: -* KeyCase - -* Purpose: -* Are keys case sensitive? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which controls how keys are -* used. If KeyCase is zero, then key strings supplied to any method -* are automatically converted to upper case before being used. If -* KeyCase is non-zero (the default), then supplied key strings are -* used without modification. -* -* The value of this attribute can only be changed if the KeyMap is -* empty. Its value can be set conveniently when creating the KeyMap. -* An error will be reported if an attempt is made to change the -* attribute value when the KeyMap contains any entries. - -* Applicability: -* KeyMap -* All KeyMaps have this attribute. -* Table -* The Table class over-rides this attribute by forcing it to zero. -* That is, keys within a Table are always case insensitive. -*att-- -*/ -astMAKE_GET(KeyMap,KeyCase,int,1,(this->keycase == -1 ? 1 : this->keycase)) -astMAKE_TEST(KeyMap,KeyCase,( this->keycase != -1 )) - -/* -*att++ -* Name: -* KeyError - -* Purpose: -* Report an error when getting the value of a non-existant KeyMap entry? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which controls how the -c astMapGet... -f AST_MAPGET... -* functions behave if the requested key is not found in the KeyMap. -* If KeyError is zero (the default), then these functions will return -c zero -f .FALSE. -* but no error will be reported. If KeyError is non-zero, then the -* same values are returned but an error is also reported. - -* Notes: -* - When setting a new value for KeyError, the supplied value is -* propagated to any KeyMaps contained within the supplied KeyMap. -* - When clearing the KeyError attribute, the attribute is also -* cleared in any KeyMaps contained within the supplied KeyMap. - -* Applicability: -* KeyMap -* All KeyMaps have this attribute. -*att-- -*/ -astMAKE_GET(KeyMap,KeyError,int,0,( ( this->keyerror != -INT_MAX ) ? - this->keyerror : 0 )) -astMAKE_TEST(KeyMap,KeyError,( this->keyerror != -INT_MAX )) - -/* -*att++ -* Name: -* MapLocked - -* Purpose: -* Prevent new entries being added to a KeyMap? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* If this boolean attribute is set to -c a non-zero value, -f .TRUE., -* an error will be reported if an attempt is made to add a new entry -* to the KeyMap. Note, the value associated with any existing entries -* can still be changed, but no new entries can be stored in the KeyMap. -* The default value -c (zero) -f (.FALSE.) -* allows new entries to be added to the KeyMap. - -* Notes: -* - When setting a new value for MapLocked, the supplied value is -* propagated to any KeyMaps contained within the supplied KeyMap. -* - When clearing the MapLocked attribute, the attribute is also -* cleared in any KeyMaps contained within the supplied KeyMap. - -* Applicability: -* KeyMap -* All KeyMaps have this attribute. -*att-- -*/ -astMAKE_GET(KeyMap,MapLocked,int,0,( ( this->maplocked != -INT_MAX ) ? - this->maplocked : 0 )) -astMAKE_TEST(KeyMap,MapLocked,( this->maplocked != -INT_MAX )) - -/* -*att++ -* Name: -* SortBy - -* Purpose: -* Determines how keys are sorted in a KeyMap. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute determines the order in which keys are returned by the -c astMapKey -f AST_MAPKEY -* function. It may take the following values (the default is "None"): -* -* - "None": The keys are returned in an arbitrary order. This is the -* fastest method as it avoids the need for a sorted list of keys to -* be maintained and used. -* -* - "AgeDown": The keys are returned in the order in which values were -* stored in the KeyMap, with the key for the most recent value being -* returned last. If the value of an existing entry is changed, it goes -* to the end of the list. -* -* - "AgeUp": The keys are returned in the order in which values were -* stored in the KeyMap, with the key for the most recent value being -* returned first. If the value of an existing entry is changed, it goes -* to the top of the list. -* -* - "KeyAgeDown": The keys are returned in the order in which they -* were originally stored in the KeyMap, with the most recent key being -* returned last. If the value of an existing entry is changed, its -* position in the list does not change. -* -* - "KeyAgeUp": The keys are returned in the order in which they -* were originally stored in the KeyMap, with the most recent key being -* returned first. If the value of an existing entry is changed, its -* position in the list does not change. -* -* - "KeyDown": The keys are returned in alphabetical order, with "A..." -* being returned last. -* -* - "KeyUp": The keys are returned in alphabetical order, with "A..." -* being returned first. - -* Notes: -* - If a new value is assigned to SortBy (or if SortBy is cleared), -* all entries currently in the KeyMap are re-sorted according to the -* new SortBy value. - -* Applicability: -* KeyMap -* All KeyMaps have this attribute. -*att-- -*/ -astMAKE_GET(KeyMap,SortBy,int,SORTBY_NONE,( ( this->sortby != -INT_MAX ) ? - this->sortby : SORTBY_NONE )) -astMAKE_TEST(KeyMap,SortBy,( this->sortby != -INT_MAX )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for KeyMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for KeyMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstKeyMap *in; /* Pointer to input KeyMap */ - AstKeyMap *out; /* Pointer to output KeyMap */ - int i; /* Index into hash table */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output KeyMap structures. */ - in = (AstKeyMap *) objin; - out = (AstKeyMap *) objout; - -/* For safety, first clear any references to the input memory from - the output KeyMap. */ - out->table = NULL; - out->nentry = NULL; - out->first = NULL; - out->firstA = NULL; - -/* Make copies of the table entries. */ - out->table = astMalloc( sizeof( AstMapEntry * )*( out->mapsize ) ); - out->nentry = astMalloc( sizeof( int )*( out->mapsize ) ); - - for( i = 0; i < out->mapsize; i++ ) CopyTableEntry( in, out, i, status ); - -/* Create the required sorted key list in the new KeyMap. */ - SortEntries( out, status ); - -/* If an error occurred, clean up by freeing all memory allocated above. */ - if ( !astOK ) { - for( i = 0; i < out->mapsize; i++ ) FreeTableEntry( out, i, status ); - out->table = astFree( out->table ); - out->nentry = astFree( out->nentry ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for KeyMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for KeyMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstKeyMap *this; /* Pointer to the KeyMap structure */ - int i; /* Loop count */ - -/* Obtain a pointer to the KeyMap structure. */ - this = (AstKeyMap *) obj; - -/* Free all allocated memory. */ - for( i = 0; i < this->mapsize; i++ ) FreeTableEntry( this, i, status ); - -/* Free memory used to hold tables. */ - this->table = astFree( this->table ); - this->nentry = astFree( this->nentry ); - -/* Nullify other pointers. */ - this->first = NULL; - this->firstA = NULL; -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for KeyMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the KeyMap class to an output Channel. - -* Parameters: -* this -* Pointer to the KeyMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstKeyMap *this; /* Pointer to the KeyMap structure */ - AstMapEntry *next; /* Pointer to the next AstMapEntry to dump */ - int i; /* Index into hash table */ - int nentry; /* Number of entries dumped so far */ - int set; /* Is attribute set? */ - int ival; /* Attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the KeyMap structure. */ - this = (AstKeyMap *) this_object; - -/* Initialise the number of KeyMap entries dumped so far. */ - nentry = 0; - -/* SizeGuess. */ -/* ---------- */ - set = TestSizeGuess( this, status ); - ival = set ? GetSizeGuess( this, status ) : astGetSizeGuess( this ); - astWriteInt( channel, "SzGss", set, 0, ival, "Guess at KeyMap size" ); - -/* SortBy. */ -/* ------- */ - set = TestSortBy( this, status ); - ival = set ? GetSortBy( this, status ) : astGetSortBy( this ); - astWriteString( channel, "SortBy", set, 0, SortByString( ival, "astDump", - status ), - "Sorting scheme for keys" ); - -/* KeyCase. */ -/* --------- */ - set = TestKeyCase( this, status ); - ival = set ? GetKeyCase( this, status ) : astGetKeyCase( this ); - astWriteInt( channel, "KyCas", set, 0, ival, "Are keys case sensitive?" ); - -/* KeyError. */ -/* --------- */ - set = TestKeyError( this, status ); - ival = set ? GetKeyError( this, status ) : astGetKeyError( this ); - astWriteInt( channel, "KyErr", set, 0, ival, "Report non-existant keys?" ); - -/* MapLocked. */ -/* --------- */ - set = TestMapLocked( this, status ); - ival = set ? GetMapLocked( this, status ) : astGetMapLocked( this ); - astWriteInt( channel, "MpLck", set, 0, ival, "Prevent addition of new entries?" ); - -/* MapSize. */ -/* -------- */ - astWriteInt( channel, "MapSz", 1, 1, this->mapsize, "Size of hash table" ); - -/* member count. */ - astWriteInt( channel, "MemCnt", 1, 1, this->member_count, "Total member count" ); - -/* Loop round each entry in the hash table. */ - for( i = 0; i < this->mapsize; i++ ) { - -/* Get a pointer to the next KeyMap entry to dump. */ - next = this->table[ i ]; - -/* Loop round dumping all KeyMap entries in this element of the hash table. */ - while( next && astOK ) { - DumpEntry( next, channel, ++nentry, status ); - -/* Get a pointer to the next entry to dump. */ - next = next->next; - - } - } -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAKeyMap and astCheckKeyMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(KeyMap,Object) -astMAKE_CHECK(KeyMap) - -AstKeyMap *astKeyMap_( const char *options, int *status, ...) { -/* -*++ -* Name: -c astKeyMap -f AST_KEYMAP - -* Purpose: -* Create a KeyMap. - -* Type: -* Public function. - -* Synopsis: -c #include "keymap.h" -c AstKeyMap *astKeyMap( const char *options, ... ) -f RESULT = AST_KEYMAP( OPTIONS, STATUS ) - -* Class Membership: -* KeyMap constructor. - -* Description: -* This function creates a new empty KeyMap and optionally initialises its -* attributes. Entries can then be added to the KeyMap using the -c astMapPut0 and astMapPut1 functions. -f AST_MAPPUT0 and AST_MAPPUT1 functions. -* -* The KeyMap class is used to store a set of values with associated keys -* which identify the values. The keys are strings. These may be case -* sensitive or insensitive as selected by the KeyCase attribute, and -* trailing spaces are ignored. The value associated with a key can be -* integer (signed 4 and 2 byte, or unsigned 1 byte), floating point -* (single or double precision), -c void pointer, -* character string or AST Object pointer. Each -* value can be a scalar or a one-dimensional vector. A KeyMap is -* conceptually similar to a Mapping in that a KeyMap transforms an -* input into an output - the input is the key, and the output is the -* value associated with the key. However, this is only a conceptual -* similarity, and it should be noted that the KeyMap class inherits from -* the Object class rather than the Mapping class. The methods of the -* Mapping class cannot be used with a KeyMap. - -* Parameters: -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new KeyMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new KeyMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astKeyMap() -f AST_MAP = INTEGER -* A pointer to the new KeyMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstKeyMap *new; /* Pointer to new KeyMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the KeyMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitKeyMap( NULL, sizeof( AstKeyMap ), !class_init, &class_vtab, "KeyMap" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new KeyMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new KeyMap. */ - return new; -} - -AstKeyMap *astKeyMapId_( const char *options, ... ) { -/* -* Name: -* astKeyMapId_ - -* Purpose: -* Create a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "keymap.h" -* AstKeyMap *astKeyMapId_( const char *options, ... ) - -* Class Membership: -* KeyMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astKeyMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astKeyMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astKeyMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astKeyMap_. - -* Returned Value: -* The ID value associated with the new KeyMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstKeyMap *new; /* Pointer to new KeyMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the KeyMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitKeyMap( NULL, sizeof( AstKeyMap ), !class_init, &class_vtab, "KeyMap" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new KeyMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new KeyMap. */ - return astMakeId( new ); -} - -AstKeyMap *astInitKeyMap_( void *mem, size_t size, int init, AstKeyMapVtab *vtab, - const char *name, int *status ) { -/* -*+ -* Name: -* astInitKeyMap - -* Purpose: -* Initialise a KeyMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "keymap.h" -* AstKeyMap *astInitKeyMap( void *mem, size_t size, int init, AstKeyMapVtab *vtab, -* const char *name ) - -* Class Membership: -* KeyMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new KeyMap object. It allocates memory (if necessary) to accommodate -* the KeyMap plus any additional data associated with the derived class. -* It then initialises a KeyMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a KeyMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the KeyMap is to be created. This -* must be of sufficient size to accommodate the KeyMap data -* (sizeof(KeyMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the KeyMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the KeyMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the KeyMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new KeyMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astClass -* method). - -* Returned Value: -* A pointer to the new KeyMap. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstKeyMap *new; /* Pointer to the new KeyMap */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitKeyMapVtab( vtab, name ); - -/* Initialise an Object structure (the parent class) as the first component - within the KeyMap structure, allocating memory if necessary. */ - new = (AstKeyMap *) astInitObject( mem, size, 0, (AstObjectVtab *) vtab, - name ); - - if ( astOK ) { - -/* Initialise the KeyMap data. */ -/* ---------------------------- */ -/* Initialise all attributes to their "undefined" values. */ - new->sizeguess = INT_MAX; - new->mapsize = 0; - new->table = NULL; - new->nentry = NULL; - new->keycase = -1; - new->keyerror = -INT_MAX; - new->maplocked = -INT_MAX; - new->sortby = -INT_MAX; - new->first = NULL; - new->nsorted = 0; - new->member_count = 0; - new->firstA = NULL; - new->iter_itab = 0; - new->iter_entry = NULL; - - NewTable( new, MIN_TABLE_SIZE, status ); - -/* If an error occurred, clean up by deleting the new KeyMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new KeyMap. */ - return new; -} - -AstKeyMap *astLoadKeyMap_( void *mem, size_t size, AstKeyMapVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadKeyMap - -* Purpose: -* Load a KeyMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "keymap.h" -* AstKeyMap *astLoadKeyMap( void *mem, size_t size, AstKeyMapVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* KeyMap loader. - -* Description: -* This function is provided to load a new KeyMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* KeyMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a KeyMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the KeyMap is to be -* loaded. This must be of sufficient size to accommodate the -* KeyMap data (sizeof(KeyMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the KeyMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the KeyMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstKeyMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new KeyMap. If this is NULL, a pointer -* to the (static) virtual function table for the KeyMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "KeyMap" is used instead. - -* Returned Value: -* A pointer to the new KeyMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstKeyMap *new; /* Pointer to the new KeyMap */ - AstObject **alist; /* Pointer to vector of entry values */ - AstObject *aval; /* AST Object value for an entry */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char *com; /* Pointer to comment string for an entry */ - char *key; /* Pointer to key string for an entry */ - char *sval; /* String value for an entry */ - char buff[ 30 ]; /* Buffer for key names */ - const char **slist; /* Pointer to vector of entry values */ - double *dlist; /* Pointer to vector of entry values */ - double dval; /* Floating point value for an entry */ - float *flist; /* Pointer to vector of entry values */ - int *ilist; /* Pointer to vector of entry values */ - int index; /* Index of next array element in a vector entry */ - int ival; /* Integer value for an entry */ - int mapsize; /* Size for new hash table */ - int nel; /* Vector length */ - int nentry; /* Number of KeyMap entries read so far */ - int type; /* Data type for an entry */ - short int *wlist; /* Pointer to vector of entry values */ - short int wval; /* Short int value for an entry */ - unsigned char *blist; /* Pointer to vector of entry values */ - unsigned char bval; /* Byte value for an entry */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this KeyMap. In this case the - KeyMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstKeyMap ); - vtab = &class_vtab; - name = "KeyMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitKeyMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built KeyMap. */ - new = astLoadObject( mem, size, (AstObjectVtab *) vtab, name, channel ); - - if ( astOK ) { - -/* Inidicate the KeyMap is empty. */ - new->mapsize = 0; - new->table = NULL; - new->nentry = NULL; - new->firstA = NULL; - new->iter_itab = 0; - new->iter_entry = NULL; - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "KeyMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* SizeGuess. */ -/* ---------- */ - new->sizeguess = astReadInt( channel, "szgss", INT_MAX ); - if ( TestSizeGuess( new, status ) ) SetSizeGuess( new, new->sizeguess, status ); - -/* KeyCase. */ -/* --------- */ - new->keycase = astReadInt( channel, "kycas", -INT_MAX ); - if ( TestKeyCase( new, status ) ) SetKeyCase( new, new->keycase, status ); - -/* KeyError. */ -/* --------- */ - new->keyerror = astReadInt( channel, "kyerr", -INT_MAX ); - if ( TestKeyError( new, status ) ) SetKeyError( new, new->keyerror, status ); - -/* MapLocked. */ -/* --------- */ - new->maplocked = astReadInt( channel, "mplck", -INT_MAX ); - if ( TestMapLocked( new, status ) ) SetMapLocked( new, new->maplocked, status ); - -/* SortBy. */ -/* ------- */ - sval = astReadString( channel, "sortby", " " ); - new->sortby = -INT_MAX; - if( astOK && strcmp( sval, " " ) ) { - new->sortby = SortByInt( sval, "astRead", status ); - } - if( TestSortBy( new, status ) ) SetSortBy( new, new->sortby, status ); - sval = astFree( sval ); - -/* MapSize. */ -/* -------- */ - mapsize = astReadInt( channel, "mapsz", MIN_TABLE_SIZE ); - NewTable( new, mapsize, status ); - -/* Entries... */ -/* ---------- */ - -/* Initialise the index of the next AstMapEntry to be read. */ - nentry = 0; - -/* Read Entries until no more are found */ - while( astOK ) { - nentry++; - -/* Get the entry key. */ - (void) sprintf( buff, "key%d", nentry ); - key = astReadString( channel, buff, NULL ); - -/* We have finished reading entries if no key was found. */ - if( !key ) break; - -/* Get the entry comment. */ - (void) sprintf( buff, "com%d", nentry ); - com = astReadString( channel, buff, NULL ); - -/* Get the entry data type. */ - (void) sprintf( buff, "typ%d", nentry ); - type = astReadInt( channel, buff, AST__BADTYPE ); - - if( type == AST__BADTYPE && astOK ) { - astError( AST__BDFTS, "astLoadKeyMap(%s): No data type code found " - "whilst reading a %s.", status, name, name ); - - } - -/* Get the vector length. */ - (void) sprintf( buff, "nel%d", nentry ); - nel = astReadInt( channel, buff, 0 ); - -/* Get the entry member number. Set the KeyMap member count to this value - so that the next entry added to the KeyMap will get this value as its - member index. */ - (void) sprintf( buff, "mem%d", nentry ); - new->member_count = astReadInt( channel, buff, 0 ); - -/* First deal with integer entries. */ - if( type == AST__INTTYPE ) { - -/* For scalar entries, use "val" to get the value then create a new - entry and add it to the KeyMap. */ - if( nel == 0 ) { - (void) sprintf( buff, "val%d", nentry ); - ival = astReadInt( channel, buff, 0 ); - MapPut0I( new, key, ival, com, status ); - -/* If we must have an array of values... */ - } else { - -/* Create an array to hold the values. */ - ilist = astMalloc( sizeof(int)*nel ); - -/* Loop round reading values. */ - for( index = 0; astOK && index < nel; index++ ) { - (void) sprintf( buff, "v%d_%d", nentry, index + 1 ); - ilist[ index ] = astReadInt( channel, buff, 0 ); - } - -/* Create the KeyMap entry. */ - MapPut1I( new, key, nel, ilist, com, status ); - -/* Free resources. */ - ilist = astFree( ilist ); - } - -/* Do the same for short int values. */ - } else if( type == AST__SINTTYPE ) { - if( nel == 0 ) { - (void) sprintf( buff, "val%d", nentry ); - wval = (short int) astReadInt( channel, buff, 0 ); - MapPut0S( new, key, wval, com, status ); - } else { - wlist = astMalloc( sizeof(short int)*nel ); - for( index = 0; astOK && index < nel; index++ ) { - (void) sprintf( buff, "v%d_%d", nentry, index + 1 ); - wlist[ index ] = (short int) astReadInt( channel, buff, 0 ); - } - MapPut1S( new, key, nel, wlist, com, status ); - wlist = astFree( wlist ); - } - -/* Do the same for byte values. */ - } else if( type == AST__BYTETYPE ) { - if( nel == 0 ) { - (void) sprintf( buff, "val%d", nentry ); - bval = (unsigned char) astReadInt( channel, buff, 0 ); - MapPut0B( new, key, bval, com, status ); - } else { - blist = astMalloc( sizeof(unsigned char)*nel ); - for( index = 0; astOK && index < nel; index++ ) { - (void) sprintf( buff, "v%d_%d", nentry, index + 1 ); - blist[ index ] = (unsigned char) astReadInt( channel, buff, 0 ); - } - MapPut1B( new, key, nel, blist, com, status ); - blist = astFree( blist ); - } - -/* Do the same for double values. */ - } else if( type == AST__DOUBLETYPE ) { - if( nel == 0 ) { - (void) sprintf( buff, "val%d", nentry ); - dval = astReadDouble( channel, buff, AST__BAD ); - MapPut0D( new, key, dval, com, status ); - } else { - dlist = astMalloc( sizeof(double)*nel ); - for( index = 0; astOK && index < nel; index++ ) { - (void) sprintf( buff, "v%d_%d", nentry, index + 1 ); - dlist[ index ] = astReadDouble( channel, buff, AST__BAD ); - } - MapPut1D( new, key, nel, dlist, com, status ); - dlist = astFree( dlist ); - } - -/* Do the same for float values. */ - } else if( type == AST__FLOATTYPE ) { - if( nel == 0 ) { - (void) sprintf( buff, "val%d", nentry ); - dval = astReadDouble( channel, buff, 0.0 ); - MapPut0F( new, key, (float) dval, com, status ); - } else { - flist = astMalloc( sizeof(float)*nel ); - for( index = 0; astOK && index < nel; index++ ) { - (void) sprintf( buff, "v%d_%d", nentry, index + 1 ); - flist[ index ] = (float) astReadDouble( channel, buff, 0.0 ); - } - MapPut1F( new, key, nel, flist, com, status ); - flist = astFree( flist ); - } - -/* Do the same for string values. */ - } else if( type == AST__STRINGTYPE ) { - if( nel == 0 ) { - (void) sprintf( buff, "val%d", nentry ); - sval = astReadString( channel, buff, "" ); - MapPut0C( new, key, sval, com, status ); - sval = astFree( sval ); - } else { - slist = astMalloc( sizeof(const char *)*nel ); - for( index = 0; astOK && index < nel; index++ ) { - (void) sprintf( buff, "v%d_%d", nentry, index + 1 ); - slist[ index ] = astReadString( channel, buff, "" ); - } - MapPut1C( new, key, nel, slist, com, status ); - for( index = 0; astOK && index < nel; index++ ) { - slist[ index ] = astFree( (void *) slist[ index ] ); - } - slist = astFree( slist ); - } - -/* Do the same for object values. */ - } else if( type == AST__OBJECTTYPE ) { - if( nel == 0 ) { - (void) sprintf( buff, "val%d", nentry ); - aval = astReadObject( channel, buff, NULL ); - MapPut0A( new, key, aval, com, status ); - if( aval ) aval = astAnnul( aval ); - } else { - alist = astMalloc( sizeof(AstObject *)*nel ); - for( index = 0; astOK && index < nel; index++ ) { - (void) sprintf( buff, "v%d_%d", nentry, index + 1 ); - alist[ index ] = astReadObject( channel, buff, NULL ); - } - MapPut1A( new, key, nel, alist, com, status ); - for( index = 0; astOK && index < nel; index++ ) { - if( alist[ index ] ) alist[ index ] = astAnnul( alist[ index ] ); - } - alist = astFree( alist ); - } - -/* Undef values have no value. */ - } else if( type == AST__UNDEFTYPE ) { - MapPutU( new, key, com, status ); - -/* Report an error if the data type is unknown. */ - } else if( astOK ) { - astError( AST__BDFTS, "astLoadKeyMap(%s): Unknown data type code " - "(%d) encountered whilst reading a %s.", status, name, type, - name ); - } -/* Free resources. */ - key = astFree( key ); - if( com ) com = astFree( com ); - - } - -/* Set the final member count for the KeyMap. */ - new->member_count = astReadInt( channel, "memcnt", 0 ); - -/* If an error occurred, clean up by deleting the new KeyMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new KeyMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -#define MAKE_MAPPUT0_(X,Xtype) \ -void astMapPut0##X##_( AstKeyMap *this, const char *key, Xtype value, \ - const char *comment, int *status ){ \ - if ( !astOK ) return; \ - (**astMEMBER(this,KeyMap,MapPut0##X))(this,key,value,comment, status ); \ -} -MAKE_MAPPUT0_(D,double) -MAKE_MAPPUT0_(F,float) -MAKE_MAPPUT0_(I,int) -MAKE_MAPPUT0_(C,const char *) -MAKE_MAPPUT0_(A,AstObject *) -MAKE_MAPPUT0_(P,void *) -MAKE_MAPPUT0_(S,short int) -MAKE_MAPPUT0_(B,unsigned char) -#undef MAKE_MAPPUT0_ - - -#define MAKE_MAPPUT1_(X,Xtype) \ -void astMapPut1##X##_( AstKeyMap *this, const char *key, int size, \ - Xtype value[], const char *comment, \ - int *status ){ \ - if ( !astOK ) return; \ - (**astMEMBER(this,KeyMap,MapPut1##X))(this,key,size,value,comment, status ); \ -} -MAKE_MAPPUT1_(S,const short int) -MAKE_MAPPUT1_(B,const unsigned char) -MAKE_MAPPUT1_(D,const double) -MAKE_MAPPUT1_(F,const float) -MAKE_MAPPUT1_(I,const int) -MAKE_MAPPUT1_(C,const char *const) -MAKE_MAPPUT1_(A,AstObject *const) -MAKE_MAPPUT1_(P,void *const) -#undef MAKE_MAPPUT1_ - -#define MAKE_MAPGET0_(X,Xtype) \ -int astMapGet0##X##_( AstKeyMap *this, const char *key, Xtype *value, int *status ){ \ - if ( !astOK ) return 0; \ - return (**astMEMBER(this,KeyMap,MapGet0##X))(this,key,value, status ); \ -} -MAKE_MAPGET0_(D,double) -MAKE_MAPGET0_(S,short int) -MAKE_MAPGET0_(B,unsigned char) -MAKE_MAPGET0_(F,float) -MAKE_MAPGET0_(I,int) -MAKE_MAPGET0_(C,const char *) -MAKE_MAPGET0_(A,AstObject *) -MAKE_MAPGET0_(P,void *) -#undef MAKE_MAPGET0_ - - -int astMapGetC_( AstKeyMap *this, const char *key, const char **value, int *status ){ \ - if ( !astOK ) return 0; \ - return (**astMEMBER(this,KeyMap,MapGetC))(this,key,value, status ); \ -} - - -#define MAKE_MAPGET1_(X,Xtype) \ -int astMapGet1##X##_( AstKeyMap *this, const char *key, int mxval, int *nval, \ - Xtype *value, int *status ){ \ - if ( !astOK ) return 0; \ - return (**astMEMBER(this,KeyMap,MapGet1##X))(this,key,mxval,nval,value,status); \ -} -MAKE_MAPGET1_(B,unsigned char) -MAKE_MAPGET1_(S,short int) -MAKE_MAPGET1_(D,double) -MAKE_MAPGET1_(F,float) -MAKE_MAPGET1_(I,int) -MAKE_MAPGET1_(A,AstObject *) -MAKE_MAPGET1_(P,void *) -#undef MAKE_MAPGET1_ - -#define MAKE_MAPGETELEM_(X,Xtype) \ -int astMapGetElem##X##_( AstKeyMap *this, const char *key, int elem, \ - Xtype *value, int *status ){ \ - if ( !astOK ) return 0; \ - return (**astMEMBER(this,KeyMap,MapGetElem##X))(this,key,elem,value,status); \ -} -MAKE_MAPGETELEM_(B,unsigned char) -MAKE_MAPGETELEM_(S,short int) -MAKE_MAPGETELEM_(D,double) -MAKE_MAPGETELEM_(F,float) -MAKE_MAPGETELEM_(I,int) -MAKE_MAPGETELEM_(A,AstObject *) -MAKE_MAPGETELEM_(P,void *) -#undef MAKE_MAPGETELEM_ - -int astMapGet1C_( AstKeyMap *this, const char *key, int l, int mxval, int *nval, - char *value, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,MapGet1C))(this,key,l,mxval,nval,value,status); -} - -int astMapGetElemC_( AstKeyMap *this, const char *key, int l, int elem, - char *value, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,MapGetElemC))(this,key,l,elem,value,status); -} - -#define MAKE_MAPPUTELEM_(X,Xtype) \ -void astMapPutElem##X##_( AstKeyMap *this, const char *key, int elem, \ - Xtype value, int *status ){ \ - if ( !astOK ) return; \ - (**astMEMBER(this,KeyMap,MapPutElem##X))(this,key,elem,value,status); \ -} -MAKE_MAPPUTELEM_(B,unsigned char) -MAKE_MAPPUTELEM_(S,short int) -MAKE_MAPPUTELEM_(D,double) -MAKE_MAPPUTELEM_(F,float) -MAKE_MAPPUTELEM_(I,int) -MAKE_MAPPUTELEM_(A,AstObject *) -MAKE_MAPPUTELEM_(C,const char *) -MAKE_MAPPUTELEM_(P,void *) -#undef MAKE_MAPPUTELEM_ - -void astMapPutU_( AstKeyMap *this, const char *key, const char *comment, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,KeyMap,MapPutU))(this,key,comment,status); -} - -void astMapRemove_( AstKeyMap *this, const char *key, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,KeyMap,MapRemove))(this,key,status); -} -void astMapRename_( AstKeyMap *this, const char *oldkey, const char *newkey, - int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,KeyMap,MapRename))(this,oldkey,newkey,status); -} -void astMapCopy_( AstKeyMap *this, AstKeyMap *that, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,KeyMap,MapCopy))(this,that,status); -} -int astMapDefined_( AstKeyMap *this, const char *key, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,MapDefined))(this,key,status); -} -int astMapSize_( AstKeyMap *this, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,MapSize))(this,status); -} -int astMapLenC_( AstKeyMap *this, const char *key, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,MapLenC))(this,key,status); -} -int astMapLength_( AstKeyMap *this, const char *key, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,MapLength))(this,key,status); -} -int astMapType_( AstKeyMap *this, const char *key, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,MapType))(this,key,status); -} -int astMapHasKey_( AstKeyMap *this, const char *key, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,MapHasKey))(this,key,status); -} -const char *astMapKey_( AstKeyMap *this, int index, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,KeyMap,MapKey))(this,index,status); -} -const char *astMapIterate_( AstKeyMap *this, int reset, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,KeyMap,MapIterate))(this,reset,status); -} -int astGetSizeGuess_( AstKeyMap *this, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,GetSizeGuess))(this,status); -} -int astTestSizeGuess_( AstKeyMap *this, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,KeyMap,TestSizeGuess))(this,status); -} -void astClearSizeGuess_( AstKeyMap *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,ClearSizeGuess))(this,status); -} -void astSetSizeGuess_( AstKeyMap *this, int sizeguess, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,SetSizeGuess))(this,sizeguess,status); -} - -void astClearMapLocked_( AstKeyMap *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,ClearMapLocked))(this,status); -} -void astSetMapLocked_( AstKeyMap *this, int maplocked, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,SetMapLocked))(this,maplocked,status); -} - -void astClearKeyError_( AstKeyMap *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,ClearKeyError))(this,status); -} -void astSetKeyError_( AstKeyMap *this, int keyerror, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,SetKeyError))(this,keyerror,status); -} - -void astClearSortBy_( AstKeyMap *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,ClearSortBy))(this,status); -} -void astSetSortBy_( AstKeyMap *this, int sortby, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,SetSortBy))(this,sortby,status); -} - -void astClearKeyCase_( AstKeyMap *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,ClearKeyCase))(this,status); -} -void astSetKeyCase_( AstKeyMap *this, int keycase, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,KeyMap,SetKeyCase))(this,keycase,status); -} - diff --git a/ast/keymap.h b/ast/keymap.h deleted file mode 100644 index a0ece66..0000000 --- a/ast/keymap.h +++ /dev/null @@ -1,569 +0,0 @@ -#if !defined( KEYMAP_INCLUDED ) /* Include this file only once */ -#define KEYMAP_INCLUDED -/* -*+ -* Name: -* keymap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the KeyMap class. - -* Invocation: -* #include "keymap.h" - -* Description: -* This include file defines the interface to the KeyMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The KeyMap class extends the Object class to represent a set of -* key/value pairs. Keys are strings, and values can be integer, -* floating point, string or Object - scalar of vector. - -* Inheritance: -* The KeyMap class inherits from the Object class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 13-NOV-2004 (DSB): -* Original version. -* 5-JUN-2006 (DSB): -* Added support for single precision entries. -* 7-MAR-2008 (DSB): -* Added support for pointer ("P") entries. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Coordinate objects (parent class) */ - -/* C header files. */ -/* --------------- */ - -/* Macros */ -/* ====== */ -/* Data type constants: */ -#define AST__BADTYPE 0 -#define AST__INTTYPE 1 -#define AST__DOUBLETYPE 2 -#define AST__STRINGTYPE 3 -#define AST__OBJECTTYPE 4 -#define AST__FLOATTYPE 5 -#define AST__POINTERTYPE 6 -#define AST__SINTTYPE 7 -#define AST__UNDEFTYPE 8 -#define AST__BYTETYPE 9 - -/* Define constants used to size global arrays in this module. */ -#define AST__KEYMAP_GETATTRIB_BUFF_LEN 50 /* Max length of string returned by GetAttrib */ -#define AST__KEYMAP_CONVERTVALUE_MAX_STRINGS 50 /* Number of string values to buffer in ConvertValue */ -#define AST__KEYMAP_CONVERTVALUE_BUFF_LEN 50 /* Max. characters in result buffer for ConvertValue */ -#define AST__KEYMAP_MAPKEY_MAX_STRINGS 50 /* Number of string values to buffer in MapKey */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Maximum key length when using case insensitive keymaps */ -#define AST__MXKEYLEN 200 - -/* Type Definitions. */ -/* ================= */ - -/* This structure contains information describing a single generic entry in - a KeyMap. This structure is extended by other structures to hold data of - specific data types. */ - -typedef struct AstMapEntry { - struct AstMapEntry *next; /* Pointer to next structure in unsorted list. */ - const char *key; /* The name used to identify the entry */ - unsigned long hash; /* The full width hash value */ - int type; /* Data type. */ - int nel; /* 0 => scalar, >0 => array with "nel" elements */ - const char *comment; /* Pointer to a comment for the entry */ - int defined; /* Non-zero if the entry value is defined */ - struct AstMapEntry *snext;/* Pointer to next structure in sorted list. */ - struct AstMapEntry *sprev;/* Pointer to previous structure in sorted list. */ - int member; /* No. of values added to KeyMap prior to this one */ - int keymember; /* No. of keys added to KeyMap prior to this one */ - int sortby; /* Used for comunnication with qsort function */ -} AstMapEntry; - -/* KeyMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstKeyMap { - -/* Attributes inherited from the parent class. */ - AstObject object; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int sizeguess; /* Guess at KeyMap size */ - AstMapEntry **table; /* Hash table containing pointers to - the KeyMap entries */ - int *nentry; /* No. of Entries in each table element */ - int mapsize; /* Length of table */ - int keycase; /* Are keys case sensitive? */ - int keyerror; /* Report error if no key? */ - int maplocked; /* Prevent addition of new entries? */ - int sortby; /* How the keys should be sorted */ - AstMapEntry *first; /* Pointer to first structure in sorted list. */ - int nsorted; /* Length of sorted list */ - int member_count; /* Total no. of values ever added to keyMap */ - AstMapEntry *firstA; /* Pointer to first "AST object"-type entry */ - int iter_itab; /* Next hash table entry to return */ - AstMapEntry *iter_entry; /* Next entry to return */ -} AstKeyMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstKeyMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstObjectVtab object_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* MapPut0I)( AstKeyMap *, const char *, int, const char *, int * ); - void (* MapPut0D)( AstKeyMap *, const char *, double, const char *, int * ); - void (* MapPut0B)( AstKeyMap *, const char *, unsigned char, const char *, int * ); - void (* MapPut0S)( AstKeyMap *, const char *, short int, const char *, int * ); - void (* MapPut0F)( AstKeyMap *, const char *, float, const char *, int * ); - void (* MapPut0C)( AstKeyMap *, const char *, const char *, const char *, int * ); - void (* MapPut0A)( AstKeyMap *, const char *, AstObject *, const char *, int * ); - void (* MapPut0P)( AstKeyMap *, const char *, void *, const char *, int * ); - void (* MapPut1I)( AstKeyMap *, const char *, int, const int[], const char *, int * ); - void (* MapPut1D)( AstKeyMap *, const char *, int, const double[], const char *, int * ); - void (* MapPut1B)( AstKeyMap *, const char *, int, const unsigned char[], const char *, int * ); - void (* MapPut1S)( AstKeyMap *, const char *, int, const short int[], const char *, int * ); - void (* MapPut1F)( AstKeyMap *, const char *, int, const float[], const char *, int * ); - void (* MapPut1C)( AstKeyMap *, const char *, int, const char *const [], const char *, int * ); - void (* MapPut1A)( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * ); - void (* MapPut1P)( AstKeyMap *, const char *, int, void *const [], const char *, int * ); - void (* MapPutU)( AstKeyMap *, const char *, const char *, int * ); - int (* MapGet0I)( AstKeyMap *, const char *, int *, int * ); - int (* MapGet0D)( AstKeyMap *, const char *, double *, int * ); - int (* MapGet0B)( AstKeyMap *, const char *, unsigned char *, int * ); - int (* MapGet0S)( AstKeyMap *, const char *, short int *, int * ); - int (* MapGet0F)( AstKeyMap *, const char *, float *, int * ); - int (* MapGet0C)( AstKeyMap *, const char *, const char **, int * ); - int (* MapGet0A)( AstKeyMap *, const char *, AstObject **, int * ); - int (* MapGet0P)( AstKeyMap *, const char *, void **, int * ); - int (* MapGet1A)( AstKeyMap *, const char *, int, int *, AstObject **, int * ); - int (* MapGet1P)( AstKeyMap *, const char *, int, int *, void **, int * ); - int (* MapGet1C)( AstKeyMap *, const char *, int, int, int *, char *, int * ); - int (* MapGet1D)( AstKeyMap *, const char *, int, int *, double *, int * ); - int (* MapGet1B)( AstKeyMap *, const char *, int, int *, unsigned char *, int * ); - int (* MapGet1S)( AstKeyMap *, const char *, int, int *, short int *, int * ); - int (* MapGet1F)( AstKeyMap *, const char *, int, int *, float *, int * ); - int (* MapGet1I)( AstKeyMap *, const char *, int, int *, int *, int * ); - int (* MapGetC)( AstKeyMap *, const char *, const char **, int * ); - int (* MapGetElemA)( AstKeyMap *, const char *, int, AstObject **, int * ); - int (* MapGetElemP)( AstKeyMap *, const char *, int, void **, int * ); - int (* MapGetElemC)( AstKeyMap *, const char *, int, int, char *, int * ); - int (* MapGetElemD)( AstKeyMap *, const char *, int, double *, int * ); - int (* MapGetElemB)( AstKeyMap *, const char *, int, unsigned char *, int * ); - int (* MapGetElemS)( AstKeyMap *, const char *, int, short int *, int * ); - int (* MapGetElemF)( AstKeyMap *, const char *, int, float *, int * ); - int (* MapGetElemI)( AstKeyMap *, const char *, int, int *, int * ); - void (* MapPutElemA)( AstKeyMap *, const char *, int, AstObject *, int * ); - void (* MapPutElemP)( AstKeyMap *, const char *, int, void *, int * ); - void (* MapPutElemC)( AstKeyMap *, const char *, int, const char *, int * ); - void (* MapPutElemD)( AstKeyMap *, const char *, int, double, int * ); - void (* MapPutElemB)( AstKeyMap *, const char *, int, unsigned char, int * ); - void (* MapPutElemS)( AstKeyMap *, const char *, int, short int, int * ); - void (* MapPutElemF)( AstKeyMap *, const char *, int, float, int * ); - void (* MapPutElemI)( AstKeyMap *, const char *, int, int, int * ); - void (* MapRemove)( AstKeyMap *, const char *, int * ); - void (* MapRename)( AstKeyMap *, const char *, const char *, int * ); - void (* MapCopy)( AstKeyMap *, AstKeyMap *, int * ); - int (* MapSize)( AstKeyMap *, int * ); - int (* MapLength)( AstKeyMap *, const char *, int * ); - int (* MapLenC)( AstKeyMap *, const char *, int * ); - int (* MapType)( AstKeyMap *, const char *, int * ); - int (* MapHasKey)( AstKeyMap *, const char *, int * ); - int (* MapDefined)( AstKeyMap *, const char *, int * ); - const char *(* MapIterate)( AstKeyMap *, int, int * ); - const char *(* MapKey)( AstKeyMap *, int, int * ); - - int (* GetSizeGuess)( AstKeyMap *, int * ); - int (* TestSizeGuess)( AstKeyMap *, int * ); - void (* SetSizeGuess)( AstKeyMap *, int, int * ); - void (* ClearSizeGuess)( AstKeyMap *, int * ); - - int (* GetMapLocked)( AstKeyMap *, int * ); - int (* TestMapLocked)( AstKeyMap *, int * ); - void (* ClearMapLocked)( AstKeyMap *, int * ); - void (* SetMapLocked)( AstKeyMap *, int, int * ); - - int (* GetKeyError)( AstKeyMap *, int * ); - int (* TestKeyError)( AstKeyMap *, int * ); - void (* ClearKeyError)( AstKeyMap *, int * ); - void (* SetKeyError)( AstKeyMap *, int, int * ); - - int (* GetKeyCase)( AstKeyMap *, int * ); - int (* TestKeyCase)( AstKeyMap *, int * ); - void (* ClearKeyCase)( AstKeyMap *, int * ); - void (* SetKeyCase)( AstKeyMap *, int, int * ); - - int (* GetSortBy)( AstKeyMap *, int * ); - int (* TestSortBy)( AstKeyMap *, int * ); - void (* ClearSortBy)( AstKeyMap *, int * ); - void (* SetSortBy)( AstKeyMap *, int, int * ); - -} AstKeyMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstKeyMapGlobals { - AstKeyMapVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ AST__KEYMAP_GETATTRIB_BUFF_LEN + 1 ]; - char *ConvertValue_Strings[ AST__KEYMAP_CONVERTVALUE_MAX_STRINGS ]; - int ConvertValue_Istr; - int ConvertValue_Init; - char ConvertValue_Buff[ AST__KEYMAP_CONVERTVALUE_BUFF_LEN + 1 ]; - char *MapKey_Strings[ AST__KEYMAP_MAPKEY_MAX_STRINGS ]; - int MapKey_Istr; - int MapKey_Init; -} AstKeyMapGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(KeyMap) /* Check class membership */ -astPROTO_ISA(KeyMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstKeyMap *astKeyMap_( const char *, int *, ...); -#else -AstKeyMap *astKeyMapId_( const char *, ... )__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstKeyMap *astInitKeyMap_( void *, size_t, int, AstKeyMapVtab *, const char *, int * ); - -/* Vtab initialiser. */ -void astInitKeyMapVtab_( AstKeyMapVtab *, const char *, int * ); - -/* Loader. */ -AstKeyMap *astLoadKeyMap_( void *, size_t, AstKeyMapVtab *, const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitKeyMapGlobals_( AstKeyMapGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -#if defined(astCLASS) /* Protected */ -int astMapGet0A_( AstKeyMap *, const char *, AstObject **, int * ); -int astMapGet1A_( AstKeyMap *, const char *, int, int *, AstObject **, int * ); -void astMapPut1A_( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * ); -int astMapGetElemA_( AstKeyMap *, const char *, int, AstObject **, int * ); -#else -int astMapGet0AId_( AstKeyMap *, const char *, AstObject **, int * ); -int astMapGet1AId_( AstKeyMap *, const char *, int, int *, AstObject **, int * ); -void astMapPut1AId_( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * ); -int astMapGetElemAId_( AstKeyMap *, const char *, int, AstObject **, int * ); -#endif - -const char *astMapKey_( AstKeyMap *, int, int * ); - - -int astMapGet0B_( AstKeyMap *, const char *, unsigned char *, int * ); -int astMapGet0C_( AstKeyMap *, const char *, const char **, int * ); -int astMapGet0D_( AstKeyMap *, const char *, double *, int * ); -int astMapGet0F_( AstKeyMap *, const char *, float *, int * ); -int astMapGet0I_( AstKeyMap *, const char *, int *, int * ); -int astMapGet0P_( AstKeyMap *, const char *, void **, int * ); -int astMapGet0S_( AstKeyMap *, const char *, short int *, int * ); -int astMapGet1B_( AstKeyMap *, const char *, int, int *, unsigned char *, int * ); -int astMapGet1C_( AstKeyMap *, const char *, int, int, int *, char *, int * ); -int astMapGet1D_( AstKeyMap *, const char *, int, int *, double *, int * ); -int astMapGet1F_( AstKeyMap *, const char *, int, int *, float *, int * ); -int astMapGet1I_( AstKeyMap *, const char *, int, int *, int *, int * ); -int astMapGet1P_( AstKeyMap *, const char *, int, int *, void **, int * ); -int astMapGet1S_( AstKeyMap *, const char *, int, int *, short int *, int * ); -int astMapGetC_( AstKeyMap *, const char *, const char **, int * ); -int astMapGetElemB_( AstKeyMap *, const char *, int, unsigned char *, int * ); -int astMapGetElemC_( AstKeyMap *, const char *, int, int, char *, int * ); -int astMapGetElemD_( AstKeyMap *, const char *, int, double *, int * ); -int astMapGetElemF_( AstKeyMap *, const char *, int, float *, int * ); -int astMapGetElemI_( AstKeyMap *, const char *, int, int *, int * ); -int astMapGetElemP_( AstKeyMap *, const char *, int, void **, int * ); -int astMapGetElemS_( AstKeyMap *, const char *, int, short int *, int * ); -int astMapHasKey_( AstKeyMap *, const char *, int * ); -int astMapDefined_( AstKeyMap *, const char *, int * ); -int astMapLenC_( AstKeyMap *, const char *, int * ); -int astMapLength_( AstKeyMap *, const char *, int * ); -int astMapSize_( AstKeyMap *, int * ); -int astMapType_( AstKeyMap *, const char *, int * ); -void astMapCopy_( AstKeyMap *, AstKeyMap *, int * ); -void astMapPut0A_( AstKeyMap *, const char *, AstObject *, const char *, int * ); -void astMapPut0B_( AstKeyMap *, const char *, unsigned char, const char *, int * ); -void astMapPut0C_( AstKeyMap *, const char *, const char *, const char *, int * ); -void astMapPut0D_( AstKeyMap *, const char *, double, const char *, int * ); -void astMapPut0F_( AstKeyMap *, const char *, float, const char *, int * ); -void astMapPut0I_( AstKeyMap *, const char *, int, const char *, int * ); -void astMapPut0P_( AstKeyMap *, const char *, void *, const char *, int * ); -void astMapPut0S_( AstKeyMap *, const char *, short int, const char *, int * ); -void astMapPut1B_( AstKeyMap *, const char *, int, const unsigned char[], const char *, int * ); -void astMapPut1C_( AstKeyMap *, const char *, int, const char *const [], const char *, int * ); -void astMapPut1D_( AstKeyMap *, const char *, int, const double *, const char *, int * ); -void astMapPut1F_( AstKeyMap *, const char *, int, const float *, const char *, int * ); -void astMapPut1I_( AstKeyMap *, const char *, int, const int *, const char *, int * ); -void astMapPut1P_( AstKeyMap *, const char *, int, void *const [], const char *, int * ); -void astMapPut1S_( AstKeyMap *, const char *, int, const short int *, const char *, int * ); -void astMapPutElemA_( AstKeyMap *, const char *, int, AstObject *, int * ); -void astMapPutElemB_( AstKeyMap *, const char *, int, unsigned char, int * ); -void astMapPutElemC_( AstKeyMap *, const char *, int, const char *, int * ); -void astMapPutElemD_( AstKeyMap *, const char *, int, double, int * ); -void astMapPutElemF_( AstKeyMap *, const char *, int, float, int * ); -void astMapPutElemI_( AstKeyMap *, const char *, int, int, int * ); -void astMapPutElemP_( AstKeyMap *, const char *, int, void *, int * ); -void astMapPutElemS_( AstKeyMap *, const char *, int, short int, int * ); -void astMapPutU_( AstKeyMap *, const char *, const char *, int * ); -void astMapRemove_( AstKeyMap *, const char *, int * ); -void astMapRename_( AstKeyMap *, const char *, const char *, int * ); - -#if defined(astCLASS) /* Protected */ -const char *astMapIterate_( AstKeyMap *, int, int * ); - -int astGetSizeGuess_( AstKeyMap *, int * ); -int astTestSizeGuess_( AstKeyMap *, int * ); -void astSetSizeGuess_( AstKeyMap *, int, int * ); -void astClearSizeGuess_( AstKeyMap *, int * ); - -int astGetKeyError_( AstKeyMap *, int * ); -int astTestKeyError_( AstKeyMap *, int * ); -void astSetKeyError_( AstKeyMap *, int, int * ); -void astClearKeyError_( AstKeyMap *, int * ); - -int astGetKeyCase_( AstKeyMap *, int * ); -int astTestKeyCase_( AstKeyMap *, int * ); -void astSetKeyCase_( AstKeyMap *, int, int * ); -void astClearKeyCase_( AstKeyMap *, int * ); - -int astGetSortBy_( AstKeyMap *, int * ); -int astTestSortBy_( AstKeyMap *, int * ); -void astSetSortBy_( AstKeyMap *, int, int * ); -void astClearSortBy_( AstKeyMap *, int * ); - -int astGetMapLocked_( AstKeyMap *, int * ); -int astTestMapLocked_( AstKeyMap *, int * ); -void astSetMapLocked_( AstKeyMap *, int, int * ); -void astClearMapLocked_( AstKeyMap *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckKeyMap(this) astINVOKE_CHECK(KeyMap,this,0) -#define astVerifyKeyMap(this) astINVOKE_CHECK(KeyMap,this,1) - -/* Test class membership. */ -#define astIsAKeyMap(this) astINVOKE_ISA(KeyMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astKeyMap astINVOKE(F,astKeyMap_) -#else -#define astKeyMap astINVOKE(F,astKeyMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitKeyMap(mem,size,init,vtab,name) astINVOKE(O,astInitKeyMap_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitKeyMapVtab(vtab,name) astINVOKE(V,astInitKeyMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadKeyMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadKeyMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckKeyMap to validate KeyMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -#define astMapPutU(this,key,comment) astINVOKE(V,astMapPutU_(astCheckKeyMap(this),key,comment,STATUS_PTR)) -#define astMapPut0I(this,key,value,comment) astINVOKE(V,astMapPut0I_(astCheckKeyMap(this),key,value,comment,STATUS_PTR)) -#define astMapPut0B(this,key,value,comment) astINVOKE(V,astMapPut0B_(astCheckKeyMap(this),key,value,comment,STATUS_PTR)) -#define astMapPut0S(this,key,value,comment) astINVOKE(V,astMapPut0S_(astCheckKeyMap(this),key,value,comment,STATUS_PTR)) -#define astMapPut0D(this,key,value,comment) astINVOKE(V,astMapPut0D_(astCheckKeyMap(this),key,value,comment,STATUS_PTR)) -#define astMapPut0F(this,key,value,comment) astINVOKE(V,astMapPut0F_(astCheckKeyMap(this),key,value,comment,STATUS_PTR)) -#define astMapPut0C(this,key,value,comment) astINVOKE(V,astMapPut0C_(astCheckKeyMap(this),key,value,comment,STATUS_PTR)) -#define astMapPut0A(this,key,value,comment) astINVOKE(V,astMapPut0A_(astCheckKeyMap(this),key,astCheckObject(value),comment,STATUS_PTR)) -#define astMapPut0P(this,key,value,comment) astINVOKE(V,astMapPut0P_(astCheckKeyMap(this),key,value,comment,STATUS_PTR)) -#define astMapPut1I(this,key,size,value,comment) astINVOKE(V,astMapPut1I_(astCheckKeyMap(this),key,size,value,comment,STATUS_PTR)) -#define astMapPut1B(this,key,size,value,comment) astINVOKE(V,astMapPut1B_(astCheckKeyMap(this),key,size,value,comment,STATUS_PTR)) -#define astMapPut1S(this,key,size,value,comment) astINVOKE(V,astMapPut1S_(astCheckKeyMap(this),key,size,value,comment,STATUS_PTR)) -#define astMapPut1D(this,key,size,value,comment) astINVOKE(V,astMapPut1D_(astCheckKeyMap(this),key,size,value,comment,STATUS_PTR)) -#define astMapPut1F(this,key,size,value,comment) astINVOKE(V,astMapPut1F_(astCheckKeyMap(this),key,size,value,comment,STATUS_PTR)) -#define astMapPut1C(this,key,size,value,comment) astINVOKE(V,astMapPut1C_(astCheckKeyMap(this),key,size,value,comment,STATUS_PTR)) -#define astMapGet0I(this,key,value) astINVOKE(V,astMapGet0I_(astCheckKeyMap(this),key,value,STATUS_PTR)) -#define astMapGet0B(this,key,value) astINVOKE(V,astMapGet0B_(astCheckKeyMap(this),key,value,STATUS_PTR)) -#define astMapGet0S(this,key,value) astINVOKE(V,astMapGet0S_(astCheckKeyMap(this),key,value,STATUS_PTR)) -#define astMapGet0D(this,key,value) astINVOKE(V,astMapGet0D_(astCheckKeyMap(this),key,value,STATUS_PTR)) -#define astMapGet0F(this,key,value) astINVOKE(V,astMapGet0F_(astCheckKeyMap(this),key,value,STATUS_PTR)) -#define astMapGet0C(this,key,value) astINVOKE(V,astMapGet0C_(astCheckKeyMap(this),key,value,STATUS_PTR)) -#define astMapGetC(this,key,value) astINVOKE(V,astMapGetC_(astCheckKeyMap(this),key,value,STATUS_PTR)) -#define astMapGet1I(this,key,mxval,nval,value) astINVOKE(V,astMapGet1I_(astCheckKeyMap(this),key,mxval,nval,value,STATUS_PTR)) -#define astMapGet1B(this,key,mxval,nval,value) astINVOKE(V,astMapGet1B_(astCheckKeyMap(this),key,mxval,nval,value,STATUS_PTR)) -#define astMapGet1S(this,key,mxval,nval,value) astINVOKE(V,astMapGet1S_(astCheckKeyMap(this),key,mxval,nval,value,STATUS_PTR)) -#define astMapGet1D(this,key,mxval,nval,value) astINVOKE(V,astMapGet1D_(astCheckKeyMap(this),key,mxval,nval,value,STATUS_PTR)) -#define astMapGet1F(this,key,mxval,nval,value) astINVOKE(V,astMapGet1F_(astCheckKeyMap(this),key,mxval,nval,value,STATUS_PTR)) -#define astMapGet1C(this,key,l,mxval,nval,value) astINVOKE(V,astMapGet1C_(astCheckKeyMap(this),key,l,mxval,nval,value,STATUS_PTR)) -#define astMapGetElemI(this,key,elem,value) astINVOKE(V,astMapGetElemI_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapGetElemB(this,key,elem,value) astINVOKE(V,astMapGetElemB_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapGetElemS(this,key,elem,value) astINVOKE(V,astMapGetElemS_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapGetElemD(this,key,elem,value) astINVOKE(V,astMapGetElemD_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapGetElemF(this,key,elem,value) astINVOKE(V,astMapGetElemF_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapGetElemC(this,key,l,elem,value) astINVOKE(V,astMapGetElemC_(astCheckKeyMap(this),key,l,elem,value,STATUS_PTR)) -#define astMapGetElemP(this,key,elem,value) astINVOKE(V,astMapGetElemP_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapPutElemA(this,key,elem,value) astINVOKE(V,astMapPutElemA_(astCheckKeyMap(this),key,elem,astCheckObject(value),STATUS_PTR)) -#define astMapPutElemI(this,key,elem,value) astINVOKE(V,astMapPutElemI_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapPutElemB(this,key,elem,value) astINVOKE(V,astMapPutElemB_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapPutElemS(this,key,elem,value) astINVOKE(V,astMapPutElemS_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapPutElemD(this,key,elem,value) astINVOKE(V,astMapPutElemD_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapPutElemF(this,key,elem,value) astINVOKE(V,astMapPutElemF_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapPutElemC(this,key,elem,value) astINVOKE(V,astMapPutElemC_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapPutElemP(this,key,elem,value) astINVOKE(V,astMapPutElemP_(astCheckKeyMap(this),key,elem,value,STATUS_PTR)) -#define astMapRemove(this,key) astINVOKE(V,astMapRemove_(astCheckKeyMap(this),key,STATUS_PTR)) -#define astMapRename(this,oldkey,newkey) astINVOKE(V,astMapRename_(astCheckKeyMap(this),oldkey,newkey,STATUS_PTR)) -#define astMapCopy(this,that) astINVOKE(V,astMapCopy_(astCheckKeyMap(this),astCheckKeyMap(that),STATUS_PTR)) -#define astMapSize(this) astINVOKE(V,astMapSize_(astCheckKeyMap(this),STATUS_PTR)) -#define astMapLength(this,key) astINVOKE(V,astMapLength_(astCheckKeyMap(this),key,STATUS_PTR)) -#define astMapLenC(this,key) astINVOKE(V,astMapLenC_(astCheckKeyMap(this),key,STATUS_PTR)) -#define astMapHasKey(this,key) astINVOKE(V,astMapHasKey_(astCheckKeyMap(this),key,STATUS_PTR)) -#define astMapDefined(this,key) astINVOKE(V,astMapDefined_(astCheckKeyMap(this),key,STATUS_PTR)) -#define astMapKey(this,index) astINVOKE(V,astMapKey_(astCheckKeyMap(this),index,STATUS_PTR)) -#define astMapType(this,key) astINVOKE(V,astMapType_(astCheckKeyMap(this),key,STATUS_PTR)) -#define astMapGet0P(this,key,value) astINVOKE(V,astMapGet0P_(astCheckKeyMap(this),key,value,STATUS_PTR)) -#define astMapGet1P(this,key,mxval,nval,value) astINVOKE(V,astMapGet1P_(astCheckKeyMap(this),key,mxval,nval,value,STATUS_PTR)) -#define astMapPut1P(this,key,size,value,comment) astINVOKE(V,astMapPut1P_(astCheckKeyMap(this),key,size,value,comment,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astMapGet0A(this,key,value) astINVOKE(V,astMapGet0A_(astCheckKeyMap(this),key,(AstObject **)(value),STATUS_PTR)) -#define astMapGet1A(this,key,mxval,nval,value) astINVOKE(V,astMapGet1A_(astCheckKeyMap(this),key,mxval,nval,(AstObject **)(value),STATUS_PTR)) -#define astMapPut1A(this,key,size,value,comment) astINVOKE(V,astMapPut1A_(astCheckKeyMap(this),key,size,value,comment,STATUS_PTR)) -#define astMapGetElemA(this,key,elem,value) astINVOKE(V,astMapGetElemA_(astCheckKeyMap(this),key,elem,(AstObject **)(value),STATUS_PTR)) -#define astMapIterate(this,reset) astINVOKE(V,astMapIterate_(astCheckKeyMap(this),reset,STATUS_PTR)) - -#define astClearSizeGuess(this) \ -astINVOKE(V,astClearSizeGuess_(astCheckKeyMap(this),STATUS_PTR)) -#define astGetSizeGuess(this) \ -astINVOKE(V,astGetSizeGuess_(astCheckKeyMap(this),STATUS_PTR)) -#define astSetSizeGuess(this,sizeguess) \ -astINVOKE(V,astSetSizeGuess_(astCheckKeyMap(this),sizeguess,STATUS_PTR)) -#define astTestSizeGuess(this) \ -astINVOKE(V,astTestSizeGuess_(astCheckKeyMap(this),STATUS_PTR)) - -#define astClearKeyError(this) \ -astINVOKE(V,astClearKeyError_(astCheckKeyMap(this),STATUS_PTR)) -#define astGetKeyError(this) \ -astINVOKE(V,astGetKeyError_(astCheckKeyMap(this),STATUS_PTR)) -#define astSetKeyError(this,keyerror) \ -astINVOKE(V,astSetKeyError_(astCheckKeyMap(this),keyerror,STATUS_PTR)) -#define astTestKeyError(this) \ -astINVOKE(V,astTestKeyError_(astCheckKeyMap(this),STATUS_PTR)) - -#define astClearKeyCase(this) \ -astINVOKE(V,astClearKeyCase_(astCheckKeyMap(this),STATUS_PTR)) -#define astGetKeyCase(this) \ -astINVOKE(V,astGetKeyCase_(astCheckKeyMap(this),STATUS_PTR)) -#define astSetKeyCase(this,keycase) \ -astINVOKE(V,astSetKeyCase_(astCheckKeyMap(this),keycase,STATUS_PTR)) -#define astTestKeyCase(this) \ -astINVOKE(V,astTestKeyCase_(astCheckKeyMap(this),STATUS_PTR)) - -#define astClearSortBy(this) \ -astINVOKE(V,astClearSortBy_(astCheckKeyMap(this),STATUS_PTR)) -#define astGetSortBy(this) \ -astINVOKE(V,astGetSortBy_(astCheckKeyMap(this),STATUS_PTR)) -#define astSetSortBy(this,sortby) \ -astINVOKE(V,astSetSortBy_(astCheckKeyMap(this),sortby,STATUS_PTR)) -#define astTestSortBy(this) \ -astINVOKE(V,astTestSortBy_(astCheckKeyMap(this),STATUS_PTR)) - -#define astClearMapLocked(this) \ -astINVOKE(V,astClearMapLocked_(astCheckKeyMap(this),STATUS_PTR)) -#define astGetMapLocked(this) \ -astINVOKE(V,astGetMapLocked_(astCheckKeyMap(this),STATUS_PTR)) -#define astSetMapLocked(this,maplocked) \ -astINVOKE(V,astSetMapLocked_(astCheckKeyMap(this),maplocked,STATUS_PTR)) -#define astTestMapLocked(this) \ -astINVOKE(V,astTestMapLocked_(astCheckKeyMap(this),STATUS_PTR)) - - -#else -#define astMapGet0A(this,key,value) astINVOKE(V,astMapGet0AId_(astCheckKeyMap(this),key,(AstObject **)(value),STATUS_PTR)) -#define astMapGet1A(this,key,mxval,nval,value) astINVOKE(V,astMapGet1AId_(astCheckKeyMap(this),key,mxval,nval,(AstObject **)(value),STATUS_PTR)) -#define astMapPut1A(this,key,size,value,comment) astINVOKE(V,astMapPut1AId_(astCheckKeyMap(this),key,size,value,comment,STATUS_PTR)) -#define astMapGetElemA(this,key,elem,value) astINVOKE(V,astMapGetElemAId_(astCheckKeyMap(this),key,elem,(AstObject **)(value),STATUS_PTR)) -#endif - -#endif - diff --git a/ast/leap-seconds.png b/ast/leap-seconds.png deleted file mode 100644 index bee2559..0000000 Binary files a/ast/leap-seconds.png and /dev/null differ diff --git a/ast/loader.c b/ast/loader.c deleted file mode 100644 index 82d477e..0000000 --- a/ast/loader.c +++ /dev/null @@ -1,199 +0,0 @@ -#define astCLASS -#include "axis.h" -#include "box.h" -#include "channel.h" -#include "chebymap.h" -#include "circle.h" -#include "cmpframe.h" -#include "cmpmap.h" -#include "cmpregion.h" -#include "dsbspecframe.h" -#include "dssmap.h" -#include "ellipse.h" -#include "fitschan.h" -#include "fluxframe.h" -#include "timeframe.h" -#include "timemap.h" -#include "frame.h" -#include "frameset.h" -#include "grismmap.h" -#include "interval.h" -#include "intramap.h" -#include "keymap.h" -#include "loader.h" -#include "lutmap.h" -#include "mapping.h" -#include "mathmap.h" -#include "matrixmap.h" -#include "nullregion.h" -#include "object.h" -#include "pcdmap.h" -#include "permmap.h" -#include "plot.h" -#include "plot3d.h" -#include "pointlist.h" -#include "pointset.h" -#include "polygon.h" -#include "polymap.h" -#include "prism.h" -#include "normmap.h" -#include "ratemap.h" -#include "region.h" -#include "shiftmap.h" -#include "skyaxis.h" -#include "skyframe.h" -#include "slamap.h" -#include "specfluxframe.h" -#include "specframe.h" -#include "specmap.h" -#include "sphmap.h" -#include "tranmap.h" -#include "selectormap.h" -#include "switchmap.h" -#include "unitmap.h" -#include "unitnormmap.h" -#include "wcsmap.h" -#include "winmap.h" -#include "xmlchan.h" -#include "zoommap.h" -#include "stc.h" -#include "stcresourceprofile.h" -#include "stcsearchlocation.h" -#include "stccatalogentrylocation.h" -#include "stcobsdatalocation.h" -#include "stcschan.h" -#include "table.h" -#include "fitstable.h" - -#include "error.h" -#include "ast_err.h" -#include -#include - -/* -*+ -* Copyright: -* Copyright (C) 1997-2016 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) -* RO: Russell Owen (LSST) - -* History: -* 18-NOV-1997 (RFWS): -* Original version. -* 18-MAR-1998 (RFWS): -* Added the IntraMap class. -* 3-JUN-1999 (RFWS): -* Added the PcdMap class. -* 17-AUG-1999 (RFWS): -* Added the MathMap class. -* 8-JAN-2003 (DSB): -* Added the SpecMap and SpecFrame classes. -* 15-JUL-2003 (DSB): -* Added the GrsimMap class. -* 6-FEB-2009 (DSB): -* Added the StcsChan class. -* 20-APR-2016 (RO): -* Added the UnitNormMap class. -*- -*/ - -AstLoaderType *astGetLoader( const char *class, int *status ) { - if ( !astOK ) return NULL; - -#define LOAD(name) \ -if ( !strcmp( class, #name ) ) return (AstLoaderType *) astLoad##name##_ - - LOAD(Axis); - LOAD(Box); - LOAD(Channel); - LOAD(ChebyMap); - LOAD(Circle); - LOAD(CmpFrame); - LOAD(CmpMap); - LOAD(CmpRegion); - LOAD(DSBSpecFrame); - LOAD(DssMap); - LOAD(Ellipse); - LOAD(FitsChan); - LOAD(FitsTable); - LOAD(FluxFrame); - LOAD(Frame); - LOAD(FrameSet); - LOAD(GrismMap); - LOAD(Interval); - LOAD(IntraMap); - LOAD(KeyMap); - LOAD(LutMap); - LOAD(Mapping); - LOAD(MathMap); - LOAD(MatrixMap); - LOAD(NullRegion); - LOAD(Object); - LOAD(PcdMap); - LOAD(PermMap); - LOAD(Plot); - LOAD(Plot3D); - LOAD(PointList); - LOAD(PointSet); - LOAD(PolyMap); - LOAD(Polygon); - LOAD(Prism); - LOAD(NormMap); - LOAD(RateMap); - LOAD(Region); - LOAD(ShiftMap); - LOAD(SkyAxis); - LOAD(SkyFrame); - LOAD(SlaMap); - LOAD(SpecFluxFrame); - LOAD(SpecFrame); - LOAD(SpecMap); - LOAD(SphMap); - LOAD(SelectorMap); - LOAD(SwitchMap); - LOAD(Table); - LOAD(TimeFrame); - LOAD(TimeMap); - LOAD(TranMap); - LOAD(UnitMap); - LOAD(UnitNormMap); - LOAD(WcsMap); - LOAD(WinMap); - LOAD(XmlChan); - LOAD(ZoomMap); - - LOAD(StcsChan); - LOAD(Stc); - LOAD(StcResourceProfile); - LOAD(StcSearchLocation); - LOAD(StcCatalogEntryLocation); - LOAD(StcObsDataLocation); - - astError( AST__OCLUK, "astGetLoader: Object of unknown class \"%s\" cannot " - "be loaded.", status, class ); - return NULL; -#undef LOAD -} - - - diff --git a/ast/loader.h b/ast/loader.h deleted file mode 100644 index 6227a81..0000000 --- a/ast/loader.h +++ /dev/null @@ -1,49 +0,0 @@ -#if !defined( LOADER_INCLUDED ) /* Include this file only once */ -#define LOADER_INCLUDED -/* -*+ - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 18-NOV-1997 (RFWS): -* Original version. -*- -*/ - -#include "object.h" -#include "channel.h" - -#if defined(astCLASS) /* Protected */ - -typedef AstObject *(AstLoaderType)( void *, size_t, AstObjectVtab *, - const char *, AstChannel *, int * ); - -AstLoaderType *astGetLoader( const char *, int * ); - -#endif -#endif - - - diff --git a/ast/lutmap.c b/ast/lutmap.c deleted file mode 100644 index 23925ea..0000000 --- a/ast/lutmap.c +++ /dev/null @@ -1,2629 +0,0 @@ -/* -*class++ -* Name: -* LutMap - -* Purpose: -* Transform 1-dimensional coordinates using a lookup table. - -* Constructor Function: -c astLutMap -f AST_LUTMAP - -* Description: -* A LutMap is a specialised form of Mapping which transforms -* 1-dimensional coordinates by using linear interpolation in a -* lookup table. -* -* Each input coordinate value is first scaled to give the index of -* an entry in the table by subtracting a starting value (the input -* coordinate corresponding to the first table entry) and dividing -* by an increment (the difference in input coordinate value -* between adjacent table entries). -* -* The resulting index will usually contain a fractional part, so -* the output coordinate value is then generated by interpolating -* linearly between the appropriate entries in the table. If the -* index lies outside the range of the table, linear extrapolation -* is used based on the two nearest entries (i.e. the two entries -* at the start or end of the table, as appropriate). If either of the -* entries used for the interplation has a value of AST__BAD, then the -* interpolated value is returned as AST__BAD. -* -* If the lookup table entries increase or decrease monotonically -* (ignoring any flat sections), then the inverse transformation may -* also be performed. - -* Inheritance: -* The LutMap class inherits from the Mapping class. - -* Attributes: -* In addition to those attributes common to all Mappings, every -* LutMap also has the following attributes: -* -* - LutEpsilon: The relative error of the values in the table. -* - LutInterp: The interpolation method to use between table entries. - -* Functions: -c The LutMap class does not define any new functions beyond those -f The LutMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2007-2011 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (JAC, UCLan) - -* History: -* 8-JUL-1997 (RFWS): -* Original version. -* 10-JUL-1997 (RFWS): -* Added the MapMerge function. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitLutMapVtab -* method. -* 12-JAN-2004 (DSB): -* Check for AST__BAD values in the supplied lut array. -* 17-MAR-2006 (DSB): -* - MapMerge changed so that a LutMap will cancel with its own -* inverse. -* - Added attribute LutInterp -* 10-MAY-2006 (DSB): -* Override astEqual. -* 4-OCT-2006 (DSB): -* - Correct "mintick" to "lutinterp" in SetAttrib. -* - Do not include bad values in the dumped LUT array. -* 8-NOV-2007 (DSB): -* - Take account of the requested invert flag when comparing two -* neighbouring LutMaps for equality in MapMerge. -* 19-NOV-2010 (DSB): -* Added (protected) astGetLutMapInfo function. -* 24-JAN-2011 (DSB): -* Implement an inverse transformation even if the coordinate -* array contains sections of equal or bad values. The inverse -* transformation will generate bad values if used within such -* regions of the coordinate array. -* 6-JUL-2011 (DSB): -* Avoid indexing the lut array beyond the end when doing an -* inverse transform. -* 2-OCT-2012 (DSB): -* Check for Infs as well as NaNs. -* 21-MAY-2015 (DSB): -* Aded LutEpsilon -* 23-SEP-2015 (DSB): -* The GetMonotonic function had a bug that caused all LutMaps -* to be considered monotonic, and thus have an inverse -* transformation. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS LutMap - -#define LINEAR 0 -#define NEAR 1 - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "winmap.h" /* Linear mappings between windows */ -#include "channel.h" /* I/O channels */ -#include "unitmap.h" /* Unit mappings */ -#include "lutmap.h" /* Interface definition for this class */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(LutMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(LutMap,Class_Init) -#define class_vtab astGLOBAL(LutMap,Class_Vtab) -#define getattrib_buff astGLOBAL(LutMap,GetAttrib_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstLutMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstLutMap *astLutMapId_( int, const double [], double, double, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int GetLinear( AstMapping *, int * ); -static int GetMonotonic( int, const double *, int *, double **, int **, int **, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static double *GetLutMapInfo( AstLutMap *, double *, double *, int *, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static int GetLutInterp( AstLutMap *, int * ); -static int TestLutInterp( AstLutMap *, int * ); -static void ClearLutInterp( AstLutMap *, int * ); -static void SetLutInterp( AstLutMap *, int, int * ); - -static double GetLutEpsilon( AstLutMap *, int * ); -static int TestLutEpsilon( AstLutMap *, int * ); -static void ClearLutEpsilon( AstLutMap *, int * ); -static void SetLutEpsilon( AstLutMap *, double, int * ); - -/* Member functions. */ -/* ================= */ -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a LutMap. - -* Type: -* Private function. - -* Synopsis: -* #include "lutmap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* LutMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* LutMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the LutMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstLutMap *this; /* Pointer to the LutMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the LutMap structure. */ - this = (AstLutMap *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* LutInterp. */ -/* ---------- */ - if ( !strcmp( attrib, "lutinterp" ) ) { - astClearLutInterp( this ); - -/* LutEpsilon. */ -/* ------------- */ - } else if ( !strcmp( attrib, "lutepsilon" ) ) { - astClearLutEpsilon( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two LutMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "lutmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* LutMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two LutMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a LutMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the LutMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstLutMap *that; - AstLutMap *this; - int i; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two LutMap structures. */ - this = (AstLutMap *) this_object; - that = (AstLutMap *) that_object; - -/* Check the second object is a LutMap. We know the first is a - LutMap since we have arrived at this implementation of the virtual - function. */ - if( astIsALutMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two LutMaps differ, it may still be possible - for them to be equivalent. First compare the LutMaps if their Invert - flags are the same. In this case all the attributes of the two LutMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - - if( astEQUAL( this->start, that->start ) && - astEQUAL( this->inc, that->inc ) && - this->nlut == that->nlut && - this->lutinterp == that->lutinterp ){ - - result = 1; - for( i = 0; i < this->nlut; i++ ) { - if( !astEQUAL( (this->lut)[ i ], (that->lut)[ i ] ) ) { - result = 0; - break; - } - } - } - -/* If the Invert flags for the two LutMaps differ, the attributes of the two - LutMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a LutMap, Invert flags must be equal. */ - result = 0; - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a LutMap. - -* Type: -* Private function. - -* Synopsis: -* #include "lutmap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* LutMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a LutMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the LutMap. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the LutMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the LutMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstLutMap *this; /* Pointer to the LutMap structure */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *result; /* Pointer value to return */ - double luteps; /* LutEpsilon attribute value */ - int lutinterp; /* LutInterp attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the LutMap structure. */ - this = (AstLutMap *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* LutInterp. */ -/* ---------- */ - if ( !strcmp( attrib, "lutinterp" ) ) { - lutinterp = astGetLutInterp( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", lutinterp ); - result = getattrib_buff; - } - -/* LutEpsilon. */ -/* ------------- */ - } else if ( !strcmp( attrib, "lutepsilon" ) ) { - luteps = astGetLutEpsilon( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, luteps ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; - -} - -static int GetLinear( AstMapping *this_mapping, int *status ) { -/* -* Name: -* GetLinear - -* Purpose: -* Determine if a LutMap implements a linear coordinate transformation. - -* Type: -* Private function. - -* Synopsis: -* #include "lutmap.h" -* int GetLinear( AstMapping *this, int *status ) - -* Class Membership: -* LutMap member function. - -* Description: -* This function returns a boolean value to indicate if the LutMap -* supplied is equivalent to a linear coordinate -* transformation. This will be the case if the lookup table -* elements increase or decrease linearly. - -* Parameters: -* this -* Pointer to the LutMap. -* status -* Pointer to the inherited status variable. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstLutMap *this; /* Pointer to the LutMap structure */ - double *lut; /* Pointer to the lookup table */ - double eps; /* Relative error on the table values */ - double fract; /* Fractional position within table */ - double hi; /* Largest value */ - double interp; /* Interpolated value */ - double lo; /* Smallest value */ - double tol1; /* First tolerance estimate */ - double tol2; /* Second tolerance estimate */ - double tol; /* Tolerance value used */ - int ilut; /* Loop counter for table elements */ - int linear; /* Result to be returned */ - int nlut; /* Number of lookup table elements */ - -/* Initialise. */ - linear = 0; - -/* Check the global error status. */ - if ( !astOK ) return linear; - -/* Obtain a pointer to the LutMap structure. */ - this = (AstLutMap *) this_mapping; - -/* Nearest neighbour LutMaps are not considered to be linear because of - the discontinuities at the start and end of the table. */ - if( astGetLutInterp( this ) != NEAR ) { - -/* Obtain the lookup table details. */ - lut = this->lut; - nlut = this->nlut; - -/* Loop to identify the largest and smallest values in the lookup - table. */ - lo = DBL_MAX; - hi = -DBL_MAX; - for ( ilut = 0; ilut < nlut; ilut++ ) { - if ( lut[ ilut ] > hi ) hi = lut[ ilut ]; - if ( lut[ ilut ] < lo ) lo = lut[ ilut ]; - } - -/* Check if the values are all the same (this makes the LutMap - linear, although it will have no inverse). */ - linear = ( hi == lo ); - if ( !linear ) { - -/* Get the relative error associated with the table values. */ - eps = astGetLutEpsilon( this ); - -/* Form a tolerance estimate based on the overall range of values in - the lookup table. */ - tol1 = fabs( hi - lo ) * eps; - -/* Now loop to inspect all the lookup table elements except the first - and last. */ - linear = 1; - for ( ilut = 1; ilut < ( nlut - 1 ); ilut++ ) { - -/* Calculate the fractional position of the current element within the - table. */ - fract = ( (double) ilut ) / ( (double) ( nlut - 1 ) ); - -/* Calculate the value it should have if the table is linear by - interpolating between the first and last values. */ - interp = lut[ 0 ] * ( 1.0 - fract ) + lut[ nlut - 1 ] * fract; - -/* Form a second tolerance estimate from this interpolated - value. Select whichever tolerance estimate is larger (this avoids - problems when values are near zero). */ - tol2 = fabs( interp ) * eps; - tol = ( tol1 > tol2 ) ? tol1 : tol2; - -/* Test for linearity within a small multiple of the tolerance. */ - linear = ( fabs( lut[ ilut ] - interp ) <= ( 2.0 * tol ) ); - if ( !linear ) break; - } - } - } - -/* Return the result. */ - return linear; -} - -static double *GetLutMapInfo( AstLutMap *this, double *start, double *inc, - int *nlut, int *status ){ -/* -* Name: -* GetLutMapInfo - -* Purpose: -* Return information about a LutMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "permmap.h" -* double *astGetLutMapInfo( AstLutMap *this, double *start, double *inc, -* int *nlut, int *status ) - -* Class Membership: -* LutMap method - -* Description: -* This function returns information about the supplied LutMap. - -* Parameters: -* this -* Pointer to the LutMap. -* start -* Pointer to a double in which to return the "start" value -* supplied when the LutMap was created. -* inc -* Pointer to a double in which to return the "inc" value -* supplied when the LutMap was created. -* nlut -* Pointer to a double in which to return the number of values in -* the LUT. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array holding a copy of the -* look-up table. This is an array of "nlut" elements, giving the -* output values for input values "start", "start+inc", "start+2*inc", -* etc. The pointer should be freed using astFree when no longer -* needed. - -* Notes: -* - A value of NULL will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Store the scalar values. */ - *start = this->start; - *inc = this->inc; - *nlut = this->nlut; - -/* Return a copy of the look up table. */ - return astStore( NULL, this->lut, sizeof( double )*this->nlut ); -} - -static int GetMonotonic( int nlut, const double *lut, int *nluti, double **luti, - int **flagsi, int **indexi, int *status ) { -/* -* Name: -* GetMonotonic - -* Purpose: -* Determine if a array is monotonic increasing or decreasing. - -* Type: -* Private function. - -* Synopsis: -* #include "lutmap.h" -* int GetMonotonic( int nlut, const double *lut, int *nluti, double **luti, -* int **flagsi, int **indexi, int *status ) - -* Class Membership: -* LutMap member function. - -* Description: -* This function returns a flag indiciating the supplied array is -* monotonic increasing, monotonic decreasing, or non-monotonic. -* Sections of equal or bad values do not invalidate an otherwise -* monotonic array. -* -* It also returns information needed to implement the inverse -* transformation of a LutMap. - -* Parameters: -* nlut -* The length of the array. -* lut -* The array to check. -* nluti -* Address of an int in which to store the length of the returned -* "luti" and "flags" arrays. -* luti -* Address at which to return a pointer to a newly allocated array -* containing "*nluti" elements. This is a copy of the supplied -* "lut" array but with any bad or NaN values omitted. Subsequent -* elements are shuffled down to fill the holes left by removing -* these bad values. A NULL pointer is returned if there are no bad -* values in "lut". -* flagsi -* Address at which to return a pointer to a newly allocated array -* containing "*nluti" elements. Each element is non-zero if the -* corresponding value stored in "luti" was adjacent to a bad value -* in the supplied "lut" array. A NULL pointer is returned if there -* are no bad values in "lut". -* indexi -* Address at which to return a pointer to a newly allocated array -* containing "*nluti" elements. Each element is the index within -* "lut" of the corresponding value stored in "luti". A NULL pointer -* is returned if there are no bad values in "lut". -* status -* Pointer to the inherited status variable. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - const double *p3; - double *p1; - double lval; - int *p2; - int *p4; - int ilut; - int nbad; - int result; - -/* Initialise. */ - result = 0; - *nluti = 0; - *luti = NULL; - *flagsi = NULL; - *indexi = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* As yet we have not found a good value. */ - lval = AST__BAD; - -/* As yet we have not found a bad value. */ - nbad = 0; - -/* Loop round the supplied array, ignoring bad (AST__BAD or NaN) values. */ - for ( ilut = 0; ilut < nlut; ilut++ ) { - if( !astISBAD( lut[ ilut ] ) ) { - -/* If this is the first good value, record it. */ - if( lval == AST__BAD ) { - lval = lut[ ilut ]; - -/* If this is not the first good value, ignore it if it is equal to the - previous god value. */ - } else if( lut[ ilut ] != lval ) { - -/* Set the returned flag on the basis of the first pair of good values. */ - if( result == 0 ) { - result = ( lut[ ilut ] > lval ) ? 1 : -1; - -/* For subsequent pairs of good values, check the pair increases or - decreases in the same way as the first pair. Reset the returned value - to zero and break if not. */ - } else if( result == 1 && lut[ ilut ] < lval ) { - result = 0; - break; - - } else if( result == -1 && lut[ ilut ] >lval ) { - result = 0; - break; - } - -/* Record the current good value. */ - lval = lut[ ilut ]; - } - } else { - nbad++; - } - } - -/* If any bad values were found, we now allocate the required returned - arrays. */ - if( nbad ) { - *nluti = nlut - nbad; - *luti = astMalloc( sizeof( double )*( *nluti ) ); - *flagsi = astMalloc( sizeof( double )*( *nluti ) ); - *indexi = astMalloc( sizeof( double )*( *nluti ) ); - - if( astOK ) { - -/* Into "luti" copy all good values from "lut", shuffling down values to - fill holes left by bad values. Into "flagsi", store a flag indicating - if the corresponding "luti" value was adjacent to a bad value in the - full "lut" array. */ - p1 = *luti; - p2 = *flagsi; - p3 = lut; - p4 = *indexi; - -/* Do the first input point (it has no lower neighbour). */ - if( !astISBAD( *p3 ) ) { - *(p1++) = *p3; - *(p2++) = astISBAD( p3[ +1 ] ); - *(p4++) = 0; - } - -/* Do all remaining input points except for the last one. */ - for ( ilut = 1,p3++; ilut < nlut-1; ilut++,p3++ ) { - if( !astISBAD( *p3 ) ) { - *(p1++) = *p3; - *(p2++) = astISBAD( p3[ -1 ] ) || astISBAD( p3[ +1 ] ); - *(p4++) = ilut; - } - } - -/* Do the last input point (it has no upper neighbour). */ - if( !astISBAD( *p3 ) ) { - *p1 = *p3; - *p2 = astISBAD( p3[ -1 ] ); - *p4 = ilut; - } - } - } - - -/* Return the result. */ - return result; -} - -void astInitLutMapVtab_( AstLutMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitLutMapVtab - -* Purpose: -* Initialise a virtual function table for a LutMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "lutmap.h" -* void astInitLutMapVtab( AstLutMapVtab *vtab, const char *name ) - -* Class Membership: -* LutMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the LutMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsALutMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->ClearLutInterp = ClearLutInterp; - vtab->GetLutInterp = GetLutInterp; - vtab->SetLutInterp = SetLutInterp; - vtab->TestLutInterp = TestLutInterp; - vtab->ClearLutEpsilon = ClearLutEpsilon; - vtab->GetLutEpsilon = GetLutEpsilon; - vtab->SetLutEpsilon = SetLutEpsilon; - vtab->TestLutEpsilon = TestLutEpsilon; - vtab->GetLutMapInfo = GetLutMapInfo; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the class dump, copy and delete functions.*/ - astSetDump( vtab, Dump, "LutMap", - "Map 1-d coordinates using a lookup table" ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - astSetDelete( (AstObjectVtab *) vtab, Delete ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a LutMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* LutMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated LutMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated LutMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated LutMap which is to be merged with -* its neighbours. This should be a cloned copy of the LutMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* LutMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated LutMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstLutMap *map; /* Pointer to LutMap */ - AstLutMap *neb; /* Pointer to neighbouring LutMap */ - AstMapping *new; /* Pointer to replacement Mapping */ - double a1; /* First input coordinate value */ - double a2; /* Second input coordinate value */ - double b1; /* First output coordinate value */ - double b2; /* Second output coordinate value */ - int equal; /* Are LutMaps equal? */ - int i; /* Mapping index */ - int ilo; /* Index of lower LutMap */ - int invneb; /* Should the neigbour be used inverted? */ - int old_inv; /* Original Invert value for neigbour */ - int result; /* Result value to return */ - int simpler; /* Mapping simplified? */ - -/* Initialise the returned result. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the nominated LutMap. */ - map = (AstLutMap *) ( *map_list )[ where ]; - -/* See if the LutMap is linear. If so, it can probably be - simplified. */ - simpler = GetLinear( (AstMapping *) map, status ); - if ( simpler ) { - -/* Obtain the range of input values corresponding to the first and - last lookup table elements. */ - a1 = map->start; - a2 = map->start + map->inc * ( map->nlut - 1 ); - -/* Obtain the corresponding range of output values and check these - values are not the same. */ - b1 = map->lut[ 0 ]; - b2 = map->lut[ map->nlut - 1 ]; - if ( b1 != b2 ) { - -/* Create a new WinMap that implements an equivalent linear Mapping, - allowing for the invert flag associated with the LutMap. */ - if ( !( *invert_list )[ where ] ) { - new = (AstMapping *) astWinMap( 1, &a1, &a2, &b1, &b2, "", status ); - } else { - new = (AstMapping *) astWinMap( 1, &b1, &b2, &a1, &a2, "", status ); - } - -/* If OK, annul the original LutMap pointer and substitute the new - one. Also clear the associated invert flag. */ - if ( astOK ) { - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = new; - ( *invert_list )[ where ] = 0; - -/* Assign the result value. */ - result = where; - } - } - -/* Otherwise, see if the LutMap is in series with its own inverse. If so - the pair of LutMaps can be replaced by a UnitMap. */ - } else if( series ) { - -/* Is the higher neighbour a LutMap? If so get a pointer to it, and - note the index of the lower of the two adjacent LutMaps. */ - if( where < ( *nmap - 1 ) && - astIsALutMap( ( *map_list )[ where + 1 ] ) ){ - neb = (AstLutMap *) ( *map_list )[ where + 1 ]; - invneb = ( *invert_list )[ where + 1 ]; - ilo = where; - -/* If not, is the lower neighbour a LutMap? If so get a pointer to it, - and note the index of the lower of the two adjacent LutMaps. */ - } else if( where > 0 && - astIsALutMap( ( *map_list )[ where - 1 ] ) ){ - neb = (AstLutMap *) ( *map_list )[ where - 1 ]; - invneb = ( *invert_list )[ where - 1 ]; - ilo = where - 1; - - } else { - neb = NULL; - } - -/* If a neighbouring LutMap was found, we can replace the pair by a - UnitMap if the two LutMaps are equal but have opposite values for - their Invert flags. Temporarily invert the neighbour, then compare - the two LutMaps for equality, then re-invert the neighbour. */ - if( neb ) { - old_inv = astGetInvert( neb ); - astSetInvert( neb, invneb ); - astInvert( neb ); - equal = astEqual( map, neb ); - astSetInvert( neb, old_inv ); - -/* If the two LutMaps are equal but opposite, annul the first of the two - Mappings, and replace it with a UnitMap. Also set the invert flag. */ - if( equal ) { - new = (AstMapping *) astUnitMap( 1, "", status ); - (void) astAnnul( ( *map_list )[ ilo ] ); - ( *map_list )[ ilo ] = new; - ( *invert_list )[ ilo ] = 0; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ ilo + 1 ] ); - for ( i = ilo + 2; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = where; - } - } - } - -/* If an error occurred, clear the returned result. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a LutMap. - -* Type: -* Private function. - -* Synopsis: -* #include "lutmap.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* LutMap member function (over-rides the astSetAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function assigns an attribute value for a LutMap, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the LutMap. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstLutMap *this; /* Pointer to the LutMap structure */ - double luteps; /* LutEpsilon attribute value */ - int lutinterp; /* LutInterp attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the LutMap structure. */ - this = (AstLutMap *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* LutInterp. */ -/* ---------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "lutinterp= %d %n", &lutinterp, &nc ) ) - && ( nc >= len ) ) { - astSetLutInterp( this, lutinterp ); - -/* LutEpsilon. */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "lutepsilon= %lf %n", &luteps, &nc ) ) - && ( nc >= len ) ) { - astSetLutEpsilon( this, luteps ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a LutMap. - -* Type: -* Private function. - -* Synopsis: -* #include "lutmap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* LutMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a LutMap's attributes. - -* Parameters: -* this -* Pointer to the LutMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstLutMap *this; /* Pointer to the LutMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the LutMap structure. */ - this = (AstLutMap *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* LutInterp. */ -/* ---------- */ - if ( !strcmp( attrib, "lutinterp" ) ) { - result = astTestLutInterp( this ); - -/* LutEpsilon. */ -/* ------------- */ - } else if ( !strcmp( attrib, "lutepsilon" ) ) { - result = astTestLutEpsilon( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a LutMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "lutmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* LutMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a LutMap and a set of points encapsulated -* in a PointSet and transforms the points so as to apply the -* lookup table transformation. - -* Parameters: -* this -* Pointer to the LutMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate -* transformation should be applied, while a zero value requests -* the inverse transformation. -* out -* Pointer to a PointSet which will hold the transformed -* (output) coordinate values. A NULL value may also be given, -* in which case a new PointSet will be created by this -* function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -* - The number of coordinate values per point in the input -* PointSet must equal 1. -* - If an output PointSet is supplied, it must have space for -* sufficient number of points (with 1 coordinate value per point) -* to accommodate the result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstLutMap *map; /* Pointer to LutMap to be applied */ - AstPointSet *result; /* Pointer to output PointSet */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *lut; /* Pointer to LUT */ - double d1; /* Offset to I1 value */ - double d2; /* Offset to I2 value */ - double fract; /* Fractional interpolation distance */ - double scale; /* Normalising scale factor */ - double value_in; /* Input coordinate value */ - double value_out; /* Output coordinate value */ - double x; /* Value normalised to LUT increment */ - double xi; /* Integer value of "x" */ - int *flags; /* Flags indicating an adjacent bad value */ - int *index; /* Translates reduced to original indices */ - int i1; /* Lower adjacent LUT index */ - int i2; /* Upper adjacent LUT index */ - int i; /* New LUT index */ - int istart; /* Original LUT index at start of interval */ - int ix; /* "x" converted to an int */ - int near; /* Perform nearest neighbour interpolation? */ - int nlut; /* Number of LUT entries */ - int nlutm1; /* Number of LUT entries minus one */ - int npoint; /* Number of points */ - int ok; /* Lookup table is not flat */ - int point; /* Loop counter for points */ - int up; /* LUT values are increasing? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the LutMap. */ - map = (AstLutMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform - member function inherited from the parent Mapping class. This - function validates all arguments and generates an output PointSet - if necessary, but does not actually transform any coordinate - values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points from the input PointSet and obtain - pointers for accessing the input and output coordinate values. */ - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse mapping, - according to the direction specified and whether the mapping has - been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Forward transformation. */ -/* ----------------------- */ - if( astOK ){ - if ( forward ) { - -/* Obtain lookup table details. */ - lut = map->lut; - nlut = map->nlut; - near = ( astGetLutInterp( map ) == NEAR ); - nlutm1 = nlut - 1; - -/* Calculate the scale factor required. */ - scale = 1.0 / map->inc; - -/* Loop to transform each input point. */ - for ( point = 0; point < npoint; point++ ) { - -/* Extract the input coordinate value. */ - value_in = ptr_in[ 0 ][ point ]; - -/* First check if this is the same value as we transformed last. If - so, re-use the last result. */ - if ( value_in == map->last_fwd_in ) { - value_out = map->last_fwd_out; - -/* Check for bad input coordinates and generate a bad result if - necessary. */ - } else if ( value_in == AST__BAD ) { - value_out = AST__BAD; - -/* For nearest-neighbour interpolation, return the value of the lookup table - entry corresponding to the input coordinate. */ - } else if( near ){ - x = ( value_in - map->start ) * scale; - xi = floor( x + 0.5 ); - ix = (int) xi; - if ( ix < 0 || ix >= nlut ) { - value_out = AST__BAD; - } else { - value_out = lut[ ix ]; - } - -/* Otherwise, (for linear interpolation) identify the lookup table entry - corresponding to the input coordinate. */ - } else { - x = ( value_in - map->start ) * scale; - xi = floor( x ); - ix = (int) xi; - -/* If the input value lies below the first lookup table entry, - extrapolate using the first two table values. */ - if ( ix < 0 ) { - if( lut[ 0 ] != AST__BAD && lut[ 1 ] != AST__BAD ) { - value_out = lut[ 0 ] + x * ( lut[ 1 ] - lut[ 0 ] ); - } else { - value_out = AST__BAD; - } - -/* If the input value lies above the last lookup table entry (or equals - it), extrapolate using the last two table values. */ - } else if ( ix >= nlutm1 ) { - if( lut[ nlutm1 ] != AST__BAD && - lut[ nlut - 2 ] != AST__BAD ) { - value_out = lut[ nlutm1 ] + - ( x - (double) ( nlutm1 ) ) * - ( lut[ nlutm1 ] - lut[ nlut - 2 ] ); - } else { - value_out = AST__BAD; - } - -/* Otherwise, interpolate between the adjacent entries. */ - } else { - if( lut[ ix ] != AST__BAD && - lut[ ix + 1 ] != AST__BAD ) { - fract = x - xi; - value_out = lut[ ix ] * ( 1.0 - fract ) + - lut[ ix + 1 ] * fract; - } else { - value_out = AST__BAD; - } - } - } - -/* Assign the output coordinate value. */ - ptr_out[ 0 ][ point ] = value_out; - -/* Retain the input and output coordinate values for possible re-use - in future. */ - map->last_fwd_in = value_in; - map->last_fwd_out = value_out; - } - -/* Inverse transformation. */ -/* ----------------------- */ - } else { - -/* Obtain details of the lookup table to be used by the inverse - transformation. This is the same as the forward transformation lookup - table, except that any bad values are omitted. Also, get a pointer to a - array of flags that indicate if the corresponding lookup table entries - were adjacent to a bad value or not in the full lookup table. */ - if( map->luti ) { - lut = map->luti; - flags = map->flagsi; - nlut = map->nluti; - index = map->indexi; - } else { - lut = map->lut; - flags = NULL; - nlut = map->nlut; - index = NULL; - } - near = ( astGetLutInterp( map ) == NEAR ); - nlutm1 = nlut - 1; - -/* Loop to transform each input point. */ - for ( point = 0; point < npoint; point++ ) { - -/* Extract the input coordinate value. */ - value_in = ptr_in[ 0 ][ point ]; - -/* First check if this is the same value as we transformed last. If - so, re-use the last result. */ - if ( value_in == map->last_inv_in ) { - value_out = map->last_inv_out; - -/* Check for bad input coordinates and generate a bad result if - necessary. */ - } else if ( value_in == AST__BAD ) { - value_out = AST__BAD; - -/* Otherwise, we can determine an inverse. Note the inverse transformation - will not be defined, so will not be attempted, unless all the table - entries are monotonically increasing or decreasing, possibly with sections - of equal or bad values. */ - } else { - up = ( lut[ nlutm1 ] > lut[ 0 ] ); - -/* Perform a binary search to identify two adjacent lookup table - elements whose values bracket the input coordinate value. */ - i1 = -1; - i2 = nlutm1; - while ( i2 > ( i1 + 1 ) ) { - i = ( i1 + i2 ) / 2; - *( ( ( value_in >= lut[ i ] ) == up ) ? &i1 : &i2 ) = i; - } - -/* If the lower table value is equal to the required value, and either of - its neighbours is also equal to the required value, then we have been - asked to find the inverse in a flat region of the table, so return - a bad value. Likewise, if the upper table value is equal to the required - value, and either of its neighbours is also equal to the required value, - then we have been asked to find the inverse in a flat region of the table, - so return a bad value. */ - ok = 1; - if( lut[ i1 ] == value_in ) { - if( i1 > 0 && lut[ i1 - 1 ] == value_in ) ok = 0; - if( lut[ i2 ] == value_in ) ok = 0; - } else if( lut[ i2 ] == value_in ) { - if( i2 < nlutm1 && lut[ i2 + 1 ] == value_in ) ok = 0; - if( lut[ i1 ] == value_in ) ok = 0; - } - - if( !ok ) { - value_out = AST__BAD; - -/* If both of the two table elements were adjacent to a bad value in the - full lookup table, return a bad output value. */ - } else if( flags && ( flags[ i1 ] && flags[ i2 ] ) ) { - value_out = AST__BAD; - -/* Nearest neighbour interpolation: return the closest of i1 or i2. Return - AST__BAD if the supplied value is less than either or greater than - either. */ - } else if( near ) { - d1 = lut[ i1 ] - value_in; - d2 = lut[ i2 ] - value_in; - if( ( d1 > 0.0 && d2 > 0.0 ) || - ( d1 < 0.0 && d2 < 0.0 ) ) { - value_out = AST__BAD; - - } else { - - if( fabs( d1 ) < fabs( d2 ) ){ - istart = index ? index[ i1 ] : i1; - } else { - istart = index ? index[ i2 ] : i2; - } - value_out = map->start + map->inc * istart; - - } - -/* Linear interpolation... */ - } else { - -/* We are interested in the lower bracketing table element. If - necessary, restrict this element's index to lie within the - table. This causes extrapolation to occur (instead of - interpolation) if the input value actually lies outside the range - of the lookup table. */ - if ( i1 < 0 ) i1 = 0; - if ( i1 > ( nlut - 2 ) ) i1 = nlut - 2; - -/* Interpolate (or extrapolate) to derive the output coordinate - value. */ - istart = index ? index[ i1 ] : i1; - value_out = map->start + map->inc * ( (double) istart + - ( ( value_in - lut[ i1 ] ) / - ( lut[ i1 + 1 ] - lut[ i1 ] ) ) ); - } - } - -/* Assign the output coordinate value. */ - ptr_out[ 0 ][ point ] = value_out; - -/* Retain the input and output coordinate values for possible re-use - in future. */ - map->last_inv_in = value_in; - map->last_inv_out = value_out; - } - } - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* LutInterp - -* Purpose: -* Look-up table interpolation method. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute indicates the method to be used when finding the -* output value of a LutMap for an input value part way between two -* table entries. If it is set to 0 (the default) then linear -* interpolation is used. Otherwise, nearest neighbour interpolation -* is used. -* -* Using nearest neighbour interpolation causes AST__BAD to be returned -* for any point which falls outside the bounds of the table. Linear -* interpolation results in an extrapolated value being returned based -* on the two end entries in the table. -* -* Note, the value of this attribute may changed only if the LutMap -* has no more than one reference. That is, an error is reported if the -* LutMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* LutMap -* All LutMaps have this attribute. - -*att-- -*/ -astMAKE_CLEAR1(LutMap,LutInterp,lutinterp,-INT_MAX) -astMAKE_GET(LutMap,LutInterp,int,LINEAR,( ( this->lutinterp == -INT_MAX ) ? - LINEAR : this->lutinterp )) -astMAKE_SET1(LutMap,LutInterp,int,lutinterp,(( value == LINEAR ) ? LINEAR : NEAR )) -astMAKE_TEST(LutMap,LutInterp,( this->lutinterp != -INT_MAX )) - -/* -*att++ -* Name: -* LutEpsilon - -* Purpose: -* The relative error of the values held in the took-up table. - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute holds the relative error of the values held in the -* took-up table. It is used when simplifying a LutMap, to determine -* if the LutMap should be considered linear. Setting a larger value -* makes it more likely that a LutMap will be replaced by a WinMap -* (i.e. a linear Mapping) when simplified. -* -* The default value is the value of the system constant DBL_EPSILON -* (typically around 1e-16 or 2E-16). If the values in the look-up -* table were derived from single precision data, it may be appropriate -* to set this attribute to a value around 1E-7. -* -* Note, the value of this attribute may changed only if the LutMap -* has no more than one reference. That is, an error is reported if the -* LutMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* LutMap -* All LutMaps have this attribute. - -*att-- -*/ -astMAKE_CLEAR1(LutMap,LutEpsilon,lutepsilon,AST__BAD) -astMAKE_GET(LutMap,LutEpsilon,double,DBL_EPSILON,( ( this->lutepsilon == AST__BAD ) ? - DBL_EPSILON : this->lutepsilon )) -astMAKE_SET1(LutMap,LutEpsilon,double,lutepsilon,(value)) -astMAKE_TEST(LutMap,LutEpsilon,( this->lutepsilon != AST__BAD )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for LutMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for LutMap objects. - -* Parameters: -* objin -* Pointer to the LutMap to be copied. -* objout -* Pointer to the LutMap being constructed. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstLutMap *out; /* Pointer to output LutMap */ - AstLutMap *in; /* Pointer to input LutMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the input and output LutMaps. */ - in= (AstLutMap *) objin; - out = (AstLutMap *) objout; - -/* Nullify all output pointers. */ - out->lut = NULL; - out->luti = NULL; - out->flagsi = NULL; - out->indexi = NULL; - -/* Allocate memory and store a copy of the lookup table data. */ - out->lut = astStore( NULL, in->lut, - sizeof( double ) * (size_t) in->nlut ); - -/* Do the arrays used for the inverse transformation, if they exist. */ - if( in->luti ) out->luti = astStore( NULL, in->luti, - sizeof( double ) * (size_t) in->nluti ); - if( in->flagsi ) out->flagsi = astStore( NULL, in->flagsi, - sizeof( double ) * (size_t) in->nluti ); - if( in->indexi ) out->indexi = astStore( NULL, in->indexi, - sizeof( double ) * (size_t) in->nluti ); -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for LutMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for LutMap objects. - -* Parameters: -* obj -* Pointer to the LutMap to be deleted. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstLutMap *this; /* Pointer to LutMap */ - -/* Obtain a pointer to the LutMap structure. */ - this = (AstLutMap *) obj; - -/* Free the memory holding the lookup tables, etc. */ - this->lut = astFree( this->lut ); - this->luti = astFree( this->luti ); - this->flagsi = astFree( this->flagsi ); - this->indexi = astFree( this->indexi ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for LutMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the LutMap class to an output Channel. - -* Parameters: -* this -* Pointer to the LutMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstLutMap *this; /* Pointer to the LutMap structure */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - double dval; /* Double value */ - int ilut; /* Loop counter for table elements */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the LutMap structure. */ - this = (AstLutMap *) this_object; - -/* Write out values representing the instance variables for the LutMap - class. Accompany these with appropriate comment strings, possibly - depending on the values being written. */ - -/* Number of lookup table elements. */ - astWriteInt( channel, "Nlut", 1, 1, this->nlut, - "Number of lookup table elements" ); - -/* Input coordinate at first element centre. */ - astWriteDouble( channel, "Start", ( this->start != 0.0 ), 1, this->start, - "Input value at first element" ); - -/* Element spacing. */ - astWriteDouble( channel, "Incr", ( this->inc != 1.0 ), 1, this->inc, - "Input value increment between elements" ); - -/* Interpolation method */ - set = TestLutInterp( this, status ); - ival = set ? GetLutInterp( this, status ) : astGetLutInterp( this ); - astWriteInt( channel, "LutInt", set, 1, ival, "Interpolation method" ); - -/* Precision */ - if( TestLutEpsilon( this, status ) ) { - dval = GetLutEpsilon( this, status ); - astWriteDouble( channel, "LutEps", 1, 1, dval, "Table relative error" ); - } - -/* Lookup table contents. */ - for ( ilut = 0; ilut < this->nlut; ilut++ ) { - if( this->lut[ ilut ] != AST__BAD ) { - (void) sprintf( buff, "L%d", ilut + 1 ); - astWriteDouble( channel, buff, 1, 1, this->lut[ ilut ], - ilut ? "" : "Lookup table elements..." ); - } - } - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsALutMap and astCheckLutMap functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(LutMap,Mapping) -astMAKE_CHECK(LutMap) - -AstLutMap *astLutMap_( int nlut, const double lut[], - double start, double inc, - const char *options, int *status, ...) { -/* -*++ -* Name: -c astLutMap -f AST_LUTMAP - -* Purpose: -* Create a LutMap. - -* Type: -* Public function. - -* Synopsis: -c #include "lutmap.h" -c AstLutMap *astLutMap( int nlut, const double lut[], -c double start, double inc, -c const char *options, ... ) -f RESULT = AST_LUTMAP( NLUT, LUT, START, INC, OPTIONS, STATUS ) - -* Class Membership: -* LutMap constructor. - -* Description: -* This function creates a new LutMap and optionally initialises -* its attributes. -* -* A LutMap is a specialised form of Mapping which transforms -* 1-dimensional coordinates by using linear interpolation in a -* lookup table. Each input coordinate value is first scaled to -* give the index of an entry in the table by subtracting a -* starting value (the input coordinate corresponding to the first -* table entry) and dividing by an increment (the difference in -* input coordinate value between adjacent table entries). -* -* The resulting index will usually contain a fractional part, so -* the output coordinate value is then generated by interpolating -* linearly between the appropriate entries in the table. If the -* index lies outside the range of the table, linear extrapolation -* is used based on the two nearest entries (i.e. the two entries -* at the start or end of the table, as appropriate). -* -* If the lookup table entries increase or decrease monotonically, -* then the inverse transformation may also be performed. - -* Parameters: -c nlut -f NLUT = INTEGER (Given) -* The number of entries in the lookup table. This value must be -* at least 2. -c lut -f LUT( NLUT ) = DOUBLE PRECISION (Given) -c An array containing the "nlut" -f An array containing the -* lookup table entries. -c start -f START = DOUBLE PRECISION (Given) -* The input coordinate value which corresponds to the first lookup -* table entry. -c inc -f INC = DOUBLE PRECISION (Given) -* The lookup table spacing (the increment in input coordinate -* value between successive lookup table entries). This value -* may be positive or negative, but must not be zero. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new LutMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new LutMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astLutMap() -f AST_LUTMAP = INTEGER -* A pointer to the new LutMap. - -* Notes: -* - If the entries in the lookup table either increase or decrease -* monotonically, then the new LutMap's TranInverse attribute will -* have a value of one, indicating that the inverse transformation -* can be performed. Otherwise, it will have a value of zero, so -* that any attempt to use the inverse transformation will result -* in an error. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstLutMap *new; /* Pointer to new LutMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the LutMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitLutMap( NULL, sizeof( AstLutMap ), !class_init, &class_vtab, - "LutMap", nlut, lut, start, inc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - LutMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new LutMap. */ - return new; -} - -AstLutMap *astLutMapId_( int nlut, const double lut[], - double start, double inc, - const char *options, ... ) { -/* -* Name: -* astLutMapId_ - -* Purpose: -* Create a LutMap. - -* Type: -* Private function. - -* Synopsis: -* #include "lutmap.h" -* AstLutMap *astLutMapId( int nlut, const double lut[], -* double start, double inc, -* const char *options, ... ) - -* Class Membership: -* LutMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astLutMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astLutMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astLutMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astLutMap_. - -* Returned Value: -* The ID value associated with the new LutMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstLutMap *new; /* Pointer to new LutMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the LutMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitLutMap( NULL, sizeof( AstLutMap ), !class_init, &class_vtab, - "LutMap", nlut, lut, start, inc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new LutMap's - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new LutMap. */ - return astMakeId( new ); -} - -AstLutMap *astInitLutMap_( void *mem, size_t size, int init, - AstLutMapVtab *vtab, const char *name, - int nlut, const double lut[], - double start, double inc, int *status ) { -/* -*+ -* Name: -* astInitLutMap - -* Purpose: -* Initialise a LutMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "lutmap.h" -* AstLutMap *astInitLutMap( void *mem, size_t size, int init, -* AstLutMapVtab *vtab, const char *name, -* int nlut, const double lut[], -* double start, double inc ) - -* Class Membership: -* LutMap initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new LutMap object. It allocates memory (if -* necessary) to accommodate the LutMap plus any additional data -* associated with the derived class. It then initialises a LutMap -* structure at the start of this memory. If the "init" flag is -* set, it also initialises the contents of a virtual function -* table for a LutMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the LutMap is to be -* initialised. This must be of sufficient size to accommodate -* the LutMap data (sizeof(LutMap)) plus any data used by the -* derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the LutMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the LutMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* init -* A logical flag indicating if the LutMap's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new LutMap. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* nlut -* The number of elements in the lookup table. This value must -* be at least 2. -* lut -* An array containing the "nlut" lookup table elements. -* start -* The input coordinate value which corresponds with the first -* lookup table element. -* inc -* The lookup table element spacing (i.e. the increment in input -* coordinate value between successive lookup table elements). - -* Returned Value: -* A pointer to the new LutMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstLutMap *new; /* Pointer to new LutMap */ - double *luti; /* Pointer to table for inverse transformation */ - double *p; /* Pointer to next lut element */ - int *flagsi; /* Pointer to flags for inverse transformation */ - int *indexi; /* Pointer to translation from original to reduced */ - int dirn; /* +1 => values increasing, -1 => values decreasing */ - int ilut; /* Loop counter for LUT elements */ - int nluti; /* Length of "luti" array */ - -/* Initialise. */ - new = NULL; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitLutMapVtab( vtab, name ); - -/* Check that the number of lookup table elements is valid. */ - if ( nlut < 2 ) { - astError( AST__LUTIN, "astInitLutMap(%s): Invalid number of lookup " - "table elements (%d).", status, name, nlut ); - astError( AST__LUTIN, "This value should be at least 2." , status); - -/* Also check that the input value increment is not zero. */ - } else if ( inc == 0.0 ) { - astError( AST__LUTII, "astInitLutMap(%s): An input value increment of " - "zero between lookup table elements is not allowed.", status, name ); - -/* Determine if the element values increase or decrease monotonically (except - that adjacent entries can be equal). We can only implement the inverse - transformation if this is so. The inverse transformation will generate - AST__BAD output values for sections of the table that contain equal - adjacent values, or hold AST__BAD values. */ - } else { - dirn = GetMonotonic( nlut, lut, &nluti, &luti, &flagsi, &indexi, - status ); - -/* Initialise a Mapping structure (the parent class) as the first - component within the LutMap structure, allocating memory if - necessary. Specify that the Mapping should be defined in the - forward direction, and conditionally in the inverse direction. */ - new = (AstLutMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - 1, 1, 1, ( dirn != 0 ) ); - - if ( astOK ) { - -/* Initialise the LutMap data. */ -/* ---------------------------- */ - new->nlut = nlut; - new->start = start; - new->inc = inc; - new->lutinterp = LINEAR; - new->lutepsilon = AST__BAD; - new->nluti = nluti; - new->luti = luti; - new->flagsi = flagsi; - new->indexi = indexi; - -/* Allocate memory and store the lookup table. */ - new->lut = astStore( NULL, lut, sizeof( double ) * (size_t) nlut ); - -/* Replace an NaN values by AST__BAD */ - p = new->lut; - for ( ilut = 0; ilut < nlut; ilut++, p++ ) { - if( !astISFINITE(*p) ) *p = AST__BAD; - } - -/* Initialise the retained input and output coordinate values. */ - new->last_fwd_in = AST__BAD; - new->last_fwd_out = AST__BAD; - new->last_inv_in = AST__BAD; - new->last_inv_out = AST__BAD; - } - -/* If an error occurred, clean up by deleting the new LutMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new LutMap. */ - return new; -} - -AstLutMap *astLoadLutMap_( void *mem, size_t size, - AstLutMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadLutMap - -* Purpose: -* Load a LutMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "lutmap.h" -* AstLutMap *astLoadLutMap( void *mem, size_t size, -* AstLutMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* LutMap loader. - -* Description: -* This function is provided to load a new LutMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* LutMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a LutMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the LutMap is to be -* loaded. This must be of sufficient size to accommodate the -* LutMap data (sizeof(LutMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the LutMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the LutMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstLutMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new LutMap. If this is NULL, a pointer -* to the (static) virtual function table for the LutMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "LutMap" is used instead. - -* Returned Value: -* A pointer to the new LutMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstLutMap *new; /* Pointer to the new LutMap */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int ilut; /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Loop counter for table elements */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this LutMap. In this case the - LutMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstLutMap ); - vtab = &class_vtab; - name = "LutMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitLutMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built LutMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "LutMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* Number of lookup table elements. */ - new->nlut = astReadInt( channel, "nlut", 2 ); - -/* Starting input coordinate value. */ - new->start = astReadDouble( channel, "start", 0.0 ); - -/* Input coordinate value increment. */ - new->inc = astReadDouble( channel, "incr", 1.0 ); - -/* Interpolation method */ - new->lutinterp = astReadInt( channel, "lutint", LINEAR ); - if ( TestLutInterp( new, status ) ) SetLutInterp( new, new->lutinterp, status ); - -/* Precision */ - new->lutepsilon = astReadDouble( channel, "luteps", AST__BAD ); - if ( TestLutEpsilon( new, status ) ) SetLutEpsilon( new, new->lutepsilon, status ); - -/* Allocate memory to hold the lookup table elements. */ - new->lut = astMalloc( sizeof( double ) * (size_t) new->nlut ); - -/* If OK, loop to read each element. */ - if ( astOK ) { - for ( ilut = 0; ilut < new->nlut; ilut++ ) { - (void) sprintf( buff, "l%d", ilut + 1 ); - new->lut[ ilut ] = astReadDouble( channel, buff, AST__BAD ); - } - -/* Initialise the retained input and output coordinate values. */ - new->last_fwd_in = AST__BAD; - new->last_fwd_out = AST__BAD; - new->last_inv_in = AST__BAD; - new->last_inv_out = AST__BAD; - -/* See if the array is monotonic increasing or decreasing. */ - (void) GetMonotonic( new->nlut, new->lut, &(new->nluti), - &(new->luti), &(new->flagsi), &(new->indexi), - status ); - } - } - -/* If an error occurred, clean up by deleting the new LutMap. */ - if ( !astOK ) new = astDelete( new ); - -/* Return the new LutMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions - defined by this class. Each simply checks the global error status - and then locates and executes the appropriate member function, - using the function pointer stored in the object's virtual function - table (this pointer is located using the astMEMBER macro defined in - "object.h"). - - Note that the member function may not be the one defined here, as - it may have been over-ridden by a derived class. However, it should - still have the same interface. */ - -double *astGetLutMapInfo_( AstLutMap *this, double *start, double *inc, - int *nlut, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,LutMap,GetLutMapInfo))( this, start, inc, nlut, - status ); -} - - - diff --git a/ast/lutmap.h b/ast/lutmap.h deleted file mode 100644 index 68fa194..0000000 --- a/ast/lutmap.h +++ /dev/null @@ -1,335 +0,0 @@ -#if !defined( LUTMAP_INCLUDED ) /* Include this file only once */ -#define LUTMAP_INCLUDED -/* -*+ -* Name: -* lutmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the LutMap class. - -* Invocation: -* #include "lutmap.h" - -* Description: -* This include file defines the interface to the LutMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The LutMap class implements Mappings which transform -* 1-dimensional coordinates using linear interpolation in a lookup -* table. - -* Inheritance: -* The LutMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astMapMerge -* Simplify a sequence of Mappings. -* astTransform -* Apply a LutMap to transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsALutMap -* Test class membership. -* astLutMap -* Create a LutMap. -* -* Protected: -* astCheckLutMap -* Validate class membership. -* astInitLutMap -* Initialise a LutMap. -* astInitLutMapVtab -* Initialise the virtual function table for the LutMap class. -* astLoadLutMap -* Load a LutMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstLutMap -* LutMap object type. -* -* Protected: -* AstLutMapVtab -* LutMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 8-JUL-1997 (RFWS): -* Original version. -* 8-JAN-2003 (DSB): -* Added protected astInitLutMapVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* LutMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstLutMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *lut; /* Pointer to lookup table */ - double *luti; /* Reduced lookup table for inverse trans. */ - double inc; /* Input increment between table entries */ - double last_fwd_in; /* Last input value (forward transfm.) */ - double last_fwd_out; /* Last output value (forward transfm.) */ - double last_inv_in; /* Last input value (inverse transfm.) */ - double last_inv_out; /* Last output value (inverse transfm.) */ - double start; /* Input value for first table entry */ - int *flagsi; /* Flags indicating adjacent bad values */ - int *indexi; /* Translates reduced to original indices */ - double lutepsilon; /* Relative error of table values */ - int lutinterp; /* Interpolation method */ - int nlut; /* Number of table entries */ - int nluti; /* Reduced number of table entries */ -} AstLutMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstLutMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - int (*GetLutInterp)( AstLutMap *, int * ); - int (* TestLutInterp)( AstLutMap *, int * ); - void (* ClearLutInterp)( AstLutMap *, int * ); - void (* SetLutInterp)( AstLutMap *, int, int * ); - double (*GetLutEpsilon)( AstLutMap *, int * ); - int (* TestLutEpsilon)( AstLutMap *, int * ); - void (* ClearLutEpsilon)( AstLutMap *, int * ); - void (* SetLutEpsilon)( AstLutMap *, double, int * ); - double *(* GetLutMapInfo)( AstLutMap *, double *, double *, int *, int * ); - -} AstLutMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstLutMapGlobals { - AstLutMapVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 101 ]; -} AstLutMapGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(LutMap) /* Check class membership */ -astPROTO_ISA(LutMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstLutMap *astLutMap_( int, const double [], double, double, const char *, int *, ...); -#else -AstLutMap *astLutMapId_( int, const double [], double, double, const char *, ... )__attribute__((format(printf,5,6))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstLutMap *astInitLutMap_( void *, size_t, int, AstLutMapVtab *, const char *, int, const double *, double, double, int * ); - -/* Vtab initialiser. */ -void astInitLutMapVtab_( AstLutMapVtab *, const char *, int * ); - -/* Loader. */ -AstLutMap *astLoadLutMap_( void *, size_t, AstLutMapVtab *, const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitLutMapGlobals_( AstLutMapGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ - int astGetLutInterp_( AstLutMap *, int * ); - int astTestLutInterp_( AstLutMap *, int * ); - void astClearLutInterp_( AstLutMap *, int * ); - void astSetLutInterp_( AstLutMap *, int, int * ); - - double astGetLutEpsilon_( AstLutMap *, int * ); - int astTestLutEpsilon_( AstLutMap *, int * ); - void astClearLutEpsilon_( AstLutMap *, int * ); - void astSetLutEpsilon_( AstLutMap *, double, int * ); - - double *astGetLutMapInfo_( AstLutMap *, double *, double *, int *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckLutMap(this) astINVOKE_CHECK(LutMap,this,0) -#define astVerifyLutMap(this) astINVOKE_CHECK(LutMap,this,1) - -/* Test class membership. */ -#define astIsALutMap(this) astINVOKE_ISA(LutMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astLutMap astINVOKE(F,astLutMap_) -#else -#define astLutMap astINVOKE(F,astLutMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define \ -astInitLutMap(mem,size,init,vtab,name,nlut,lut,start,inc) \ -astINVOKE(O,astInitLutMap_(mem,size,init,vtab,name,nlut,lut,start,inc,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitLutMapVtab(vtab,name) astINVOKE(V,astInitLutMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadLutMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadLutMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckLutMap to validate LutMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -#if defined(astCLASS) /* Protected */ - -#define astClearLutInterp(this) \ - astINVOKE(V,astClearLutInterp_(astCheckLutMap(this),STATUS_PTR)) -#define astGetLutInterp(this) \ - astINVOKE(V,astGetLutInterp_(astCheckLutMap(this),STATUS_PTR)) -#define astSetLutInterp(this,value) \ - astINVOKE(V,astSetLutInterp_(astCheckLutMap(this),value,STATUS_PTR)) -#define astTestLutInterp(this) \ - astINVOKE(V,astTestLutInterp_(astCheckLutMap(this),STATUS_PTR)) -#define astGetLutMapInfo(this,start,inc,nlut) \ - astINVOKE(V,astGetLutMapInfo_(astCheckLutMap(this),start,inc,nlut,STATUS_PTR)) -#define astClearLutEpsilon(this) \ - astINVOKE(V,astClearLutEpsilon_(astCheckLutMap(this),STATUS_PTR)) -#define astGetLutEpsilon(this) \ - astINVOKE(V,astGetLutEpsilon_(astCheckLutMap(this),STATUS_PTR)) -#define astSetLutEpsilon(this,value) \ - astINVOKE(V,astSetLutEpsilon_(astCheckLutMap(this),value,STATUS_PTR)) -#define astTestLutEpsilon(this) \ - astINVOKE(V,astTestLutEpsilon_(astCheckLutMap(this),STATUS_PTR)) - -#endif - -#endif - - - - - diff --git a/ast/makeh b/ast/makeh deleted file mode 100644 index c07d343..0000000 --- a/ast/makeh +++ /dev/null @@ -1,313 +0,0 @@ -#!/usr/bin/perl -#+ -# Name: -# makeh - -# Purpose: -# Generate the contents of the "ast.h" header file. - -# Type: -# Perl script. - -# Invocation: -# makeh file_list - -# Description: -# This script processes private header files used within the AST library -# in order to extract the public information they contain. This information -# is produced in a form suitable for use in the public "ast.h" header file, -# which defines the public interface to the library. - -# Parameters: -# file_list -# A space-separated list of the private AST header files whose public -# information is to be extracted. - -# Result: -# The contents of the "ast.h" header file are written to standard output. - -# Notes: -# - This script is specific to the AST library and contains some knowledge -# of the input file contents. - -# History: -# 10-JAN-2005 (DSB): -# Added second argument (mode) to the mkdir invocation which creates -# the temporary directory. -# 2-MAR-2006 (DSB): -# Check for "config.h" as well as -# 6-JAN-2010 (DSB): -# Add work-around for GCC 4.4.2 problem - the pre-processor seesm to simply -# throw away backslshes that escape newlines in the input header file. Reported -# by Bryan Irby at GSFC. -# 27-JUL-2011 (DSB): -# Include the process ID in the name of the temporary directory and -# file, so that simultaneous invocations of this script do not trample -# all over each other. -#- - -( $#ARGV >= 0 ) || Usage(); - -# Test whether we need to include config.h in the result. -$need_config_h = 0; - -# Location of source files (makefile variable $(srcdir)). -# This is most typically '.', but can be different. -$srcdir = '.'; - -while ( $ARGV[0] =~ /^-/ ) { - if ( $ARGV[0] eq '-s' ) { - shift @ARGV; - ( $#ARGV >= 0 ) || Usage(); - $srcdir = $ARGV[0]; - shift @ARGV; - } else { - Usage(); - } -} - -# Create a scratch directory. -$tmpdir="/tmp/makeh-$$.tmp"; -unless ( -d $tmpdir && -w $tmpdir ) { - if ( -e $tmpdir ) { - die "Temp $tmpdir exists, but is unwritable or is not a directory\n"; - } - mkdir $tmpdir, 0777 || - die "Failed to create temporary directory $tmpdir\n"; -} - -# Open each input file. -foreach $file ( @ARGV ) { - protect_copy_file( $file ); -} - - -# Open a pipe to a script (in the current directory) which runs the C -# preprocessor and direct its output to a scratch file. -open( CC, "| ./ast_cpp >/tmp/ast-$$.h" ) || - die "Can't open pipe to C preprocessor (cpp)"; - -if ( $need_config_h ) { -# Include this directory's config.h, unescaped, in the output. We -# need to pay attention to the values in this file, but don't want -# them unexpanded in the final ast.h. - chomp($cwd = `pwd`); - print(CC "#include \"$cwd/config.h\"\n"); -} - -# Before including each file, write an underlined heading in the form of -# C comments (with comment characters suitably protected so that they will -# be passed unchanged by cpp). -foreach $file ( @ARGV ) { - $comment = $file; - $comment =~ s|^.*/||; - $comment =~ s|.h$||; - print( CC "/_* " . $comment . ". *_/\n" ); - $comment =~ s/./=/g; - print( CC "/_* " . $comment . "= *_/\n" ); - -# Write #include "xxx.h" lines to cpp so that it includes (and -# preprocesses) each of the temporary files created above in turn. - $tmp_file = $file; - $tmp_file =~ s|^.*/||; - printf(CC "#include \"%s/%s\"\n", $tmpdir, $tmp_file); -}; - -# Close the pipe to cpp. -close( CC ) || die "C preprocessor (cpp) error"; - -# Remove the temporary directory and the files it contains. -print( stderr `rm -r $tmpdir` ); - -# Write the output preamble. -print( -'#if !defined(AST_INCLUDED) -#define AST_INCLUDED -/* -*+ -* Name: -* ast.h - -* Purpose: -* Define the public C interface to the AST library. - -* Language: -* ANSI C - -* Type of Module: -* C header file. - -* Description: -* This file defines the public C interface to the AST library. It contains -* all the type definitions, function prototypes, macro definitions, etc. -* needed to use the library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (STARLINK) -* RFWS: R.F. Warren-Smith (STARLINK) -* {enter_new_authors_here} - -* History: -* ' ); - -# Add the current date at this point. -( $sec, $min, $hour, $mday, $mon, $year ) = localtime; -print( $mday, '-', - ( 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', - 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC' )[ $mon ], '-', - ( $year > 95 ? 1900 : 2000 ) + $year ); - -print( ' (makeh): -* Original version, generated automatically from the internal header -* files by the "makeh" script. -* {enter_changes_here} -*- -*/ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -' ); - -# Open the scratch file created above and read it. -$space = 0; -open( TEMP, " ) { - -# Remove the underscores from the protected lines and macros. - s/^_#include(\s)/#include$1/; - s/^_#define(\s)/#define$1/; - s/___LINE__/__LINE__/g; - s/___FILE__/__FILE__/g; - -# Also un-protect protected comments. - s|/_\*|/*|g; - s|\*_/|*/|g; - -# Convert multiple blank lines (cpp creates lots of these) into single blank -# lines. - if ( /^\s*$/ ) { - $space = 1; - } else { - -# Remove additional unwanted lines that cpp creates. - if ( ! /^# \d+/ ) { - if ( $space ) { print( "\n" ) }; - $space = 0; - -# Output the lines we want to keep. - print; - } - } -} - -# Write closing output lines. -print( -' -#endif -' ); - -# Close and remove the scratch file. -close( TEMP ); -unlink "/tmp/ast-$$.h"; - - -sub protect_copy_file { - my $file = shift; - - open( INCLUDE, "$srcdir/$file" ) - || die "Can't open input file " . $srcdir/$file; - -# Inicate we have no deferred text to write out. - $total = ""; - -# Open an output file with the same name in the temporary directory. - $tmp_file = $file; - $tmp_file =~ s|^.*/||; - open( TEMP, ">$tmpdir/$tmp_file" ); - -# Read the input file and detect "#include <...>" lines, extracting the name -# of the header file being included. -line: while ( ) { -# Omit any config.h includes, and note that we saw this - if (/^\s*\#\s*include\s+/ || - /^\s*\#\s*include\s+"config.h"/) { - $need_config_h = 1; - next line; - } - - if ( ( $header ) = /^\#include\s+<(.+)>/ ) { - -# If this system header file has already been included, ignore it and go on to -# the next input line. - next line if $done{ $header }++; - -# Otherwise, protect the #include with an underscore to prevent the file -# actually being included. - s/^/_/; - } - -# Also protect "#define ..." lines, to prevent macro substitution being -# performed by the C preprocessor. Do not do this to lines of the form -# "#define XXX_INCLUDED" because these are still needed to determine which -# AST header files get included. - if ( /^\#define\s/ ) { - if ( ! /^\#define\s+\w*_INCLUDED/ ) { s/^/_/ }; - } - -# Similarly add underscores to protect standard C macros. - s/__LINE__/___LINE__/g; - s/__FILE__/___FILE__/g; - -# Some pre-processors (e.g. GCC 4.4.2) seem to simply throw away trailing -# backslashes used to concatenate consecutive lines, producing two -# independent lines in the output rather than one. This completely fouls -# up the resulting header file. To avoid this, we concatenate such lines -# explicitly, before writing them out to the temporary output file. -# If the current line ends with an escaped newline, remove the escape -# character and newline, and concatenate it with any previously deferred -# lines. - if( /^(.*)\\\s*$/ ) { - $total .= $1; - -# If the current line does not end with an escaped newline, concatenate it -# with any previously deferred lines, and write the total string out. Then -# reset the total string to indicate we have no deferred text. - } else { - $total .= $_; - print TEMP $total; - $total = ""; - } - } - -# Close each file when done. - close( INCLUDE ); - close( TEMP ); -} - -sub Usage { - print STDERR "$0 [-s srcdir] file...\n"; - exit (1); -} diff --git a/ast/mapping.c b/ast/mapping.c deleted file mode 100644 index 73dc546..0000000 --- a/ast/mapping.c +++ /dev/null @@ -1,24692 +0,0 @@ -/* -*class++ -* Name: -* Mapping - -* Purpose: -* Inter-relate two coordinate systems. - -* Constructor Function: -* None. - -* Description: -* This class provides the basic facilities for transforming a set -* of coordinates (representing "input" points) to give a new set -* of coordinates (representing "output" points). It is used to -* describe the relationship which exists between two different -* coordinate systems and to implement operations which make use of -* this (such as transforming coordinates and resampling grids of -* data). However, the Mapping class does not have a constructor -* function of its own, as it is simply a container class for a -* family of specialised Mappings which implement particular types -* of coordinate transformation. - -* Inheritance: -* The Mapping class inherits from the Object class. - -* Attributes: -* In addition to those attributes common to all Objects, every -* Mapping also has the following attributes: -* -* - Invert: Mapping inversion flag -* - IsLinear: Is the Mapping linear? -* - IsSimple: Has the Mapping been simplified? -* - Nin: Number of input coordinates for a Mapping -* - Nout: Number of output coordinates for a Mapping -* - Report: Report transformed coordinates? -* - TranForward: Forward transformation defined? -* - TranInverse: Inverse transformation defined? - -* Functions: -c In addition to those functions applicable to all Objects, the -c following functions may also be applied to all Mappings: -f In addition to those routines applicable to all Objects, the -f following routines may also be applied to all Mappings: -* -c - astDecompose: Decompose a Mapping into two component Mappings -c - astTranGrid: Transform a grid of positions -c - astInvert: Invert a Mapping -c - astLinearApprox: Calculate a linear approximation to a Mapping -c - astMapBox: Find a bounding box for a Mapping -c - astMapSplit: Split a Mapping up into parallel component Mappings -c - astQuadApprox: Calculate a quadratic approximation to a 2D Mapping -c - astRate: Calculate the rate of change of a Mapping output -c - astRebin: Rebin a region of a data grid -c - astRebinSeq: Rebin a region of a sequence of data grids -c - astResample: Resample a region of a data grid -c - astRemoveRegions: Remove any Regions from a Mapping -c - astSimplify: Simplify a Mapping -c - astTran1: Transform 1-dimensional coordinates -c - astTran2: Transform 2-dimensional coordinates -c - astTranN: Transform N-dimensional coordinates -c - astTranP: Transform N-dimensional coordinates held in separate arrays -f - AST_DECOMPOSE: Decompose a Mapping into two component Mappings -f - AST_TRANGRID: Transform a grid of positions -f - AST_INVERT: Invert a Mapping -f - AST_LINEARAPPROX: Calculate a linear approximation to a Mapping -f - AST_QUADAPPROX: Calculate a quadratic approximation to a 2D Mapping -f - AST_MAPBOX: Find a bounding box for a Mapping -f - AST_MAPSPLIT: Split a Mapping up into parallel component Mappings -f - AST_RATE: Calculate the rate of change of a Mapping output -f - AST_REBIN: Rebin a region of a data grid -f - AST_REBINSEQ: Rebin a region of a sequence of data grids -f - AST_REMOVEREGIONS: Remove any Regions from a Mapping -f - AST_RESAMPLE: Resample a region of a data grid -f - AST_SIMPLIFY: Simplify a Mapping -f - AST_TRAN1: Transform 1-dimensional coordinates -f - AST_TRAN2: Transform 2-dimensional coordinates -f - AST_TRANN: Transform N-dimensional coordinates - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* MBT: Mark Taylor (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 1-FEB-1996 (RFWS): -* Original version. -* 29-FEB-1996 (RFWS): -* Minor improvements to error messages. -* 15-JUL-1996 (RFWS): -* Support external interface. -* 13-DEC-1996 (RFWS): -* Added the astMapMerge method. -* 13-DEC-1996 (RFWS): -* Added the astSimplify method. -* 27-MAY-1997 (RFWS): -* Improved the astSimplify method to use astMapMerge to -* simplify a single Mapping where possible. -* 29-MAY-1998 (RFWS): -* Added the MapBox method. -* 13-NOV-1998 (RFWS): -* Made default MapBox convergence accuracy larger (i.e. less -* accurate). -* 10-DEC-1998 (RFWS): -* First useful implementation of astResample. -* 16-AUG-1999 (RFWS): -* Fixed bug in SpecialBounds - wrong number of coordinates being used -* when checking for bad output coordinate values. -* 17-AUG-1999 (RFWS): -* Improved the convergence security of MapBox (return to older but -* less efficient setting). -* 24-NOV-2000 (MBT): -* Fixed bug (function being invoked as wrong type) in AST__UINTERP -* scheme, and added new AST__BLOCKAVE scheme, in astResample. -* 9-JAN-2001 (DSB): -* Changed in and out arguments for TranN from type "double (*)[]" -* to "double *". -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitMappingVtab -* method. -* 10-JUL-2003 (DSB): -* Added method astRate. -* 2-SEP-2004 (DSB): -* Free resources before leaving astRate. -* 31-AUG-2004 (DSB): -* Make the LinearApprox function protected rather than private, -* rename it to astLinearApprox, and make the bounds parameters of -* type double rather than int. Also, correct the size of the fit -* coefficient array (was "(nin+1)*nout", now is "(nout+1)*nin"). -* Also correct the index of the first gradient coefficient from -* "fit+nout" to "fit+nin". These errors have probably never been -* noticed because they make no difference if nin=nout, which is -* usually the case. -* 6-SEP-2004 (DSB): -* Make astRate more robust by adding checks for unusal conditions. -* 20-SEP-2004 (DSB): -* Make the LinearApprox function public and change its interface -* to be more appropriate for public use. This involved swapping the -* direction of the fit (the original astLinearApprox fitted the -* inverse transformation, but the public version now fits the forwrd -* transformation). -* 4-OCT-2004 (DSB): -* Modify astMapList to return flag indicating presence of inverted -* CmpMaps in supplied Mapping. -* 9-NOV-2004 (DSB): -* Override astEqual method. -* 6-DEC-2004 (DSB): -* Remove the second derivative estimate from the astRate function -* since CmpMap has trouble calculating it. -* 17-DEC-2004 (DSB): -* Added astMapSplit -* 22-APR-2005 (DSB): -* Modified SpecialBounds to handle cases where some irrelevant -* output always produces bad values (e.g. a PermMap may do this). -* 30-JUN-2005 (DSB): -* Added astRebin. -* 7-JUL-2005 (DSB): -* Make MapSplit public rather than protected. -* 11-AUG-2005 (DSB): -* Added the AST__CONSERVEFLUX flag (used by astResampleX). -* 17-AUG-2005 (DSB): -* Added the AST__SOMBCOS kernel. -* 31-AUG-2005 (DSB): -* Added astRebinSeq. -* 9-SEP-2005 (DSB): -* Corrected axis indices returned by public interface for astMapSplit. -* 31-JAN-2006 (DSB): -* Added IsSimple attribute. -* 2-FEB-2006 (DSB): -* Corrections to prologue of astLinearApprox. -* 16-FEB-2006 (DSB): -* Some speed optimisations to rebinning code. -* 2-MAR-2006 (DSB): -* Use HAVE_LONG_DOUBLE in place of AST_LONG_DOUBLE -* 7-MAR-2006 (DSB): -* Added astTranGrid. -* 14-MAR-2006 (DSB): -* - The constructor no longer reports an error if the resulting -* Mapping cannot transform points in either direction. This is -* because it may be possible to simplify such a Mapping and the -* simplified Mapping may have defined transformations. E.g. if a -* Mapping which has only a forward transformation is combined in -* series with its own inverse, the combination CmpMap will simplify -* to a UnitMap (usually). -* - Reset the "issimple" flag when the Invert flag is changed. -* 9-MAY-2006 (DSB): -* Correct upper bounds for idim in RebinWithblocking. Also, remove -* the single precision "F" instantiation of the MAKE_REBINSEQ macro. -* Also correct the "nout = astGetNin" line in the MAKE_REBINSEQ -* macro to "nout = astGetNout". -* 12-MAY-2006 (DSB): -* Modify SpecialBounds to include points slightly inside the -* corners. This is because some Mappings may have singularies at -* the the edges. -* 17-MAY-2006 (DSB): -* Correct the "nout = astGetNin" line in the MAKE_RESAMPLE -* and MAKE_REBIN macros to "nout = astGetNout". -* 7-JUL-2006 (DSB): -* Change -CHAR_MAX value (used as a "not set" value for boolean -* attributes) to +CHAR_MAX, since some compilers do not allow -* chars to have negative values. -* 23-AUG-2006 (DSB): -* Change the Equal function so that it reports an error when -* called, rather than using astSimplify to determine if two Mappings -* are equal. All concrete Mapping classes should now provide -* their own implementation of astEqual, avoiding the use of -* astSimplify. This is so that astSimplify can use astEqual safely -* (i.e. without danger of entering an infinite loop). -* 24-NOV-2006 (DSB): -* Allow astRebinSeq to be called with a NULL pointer for the input -* data array. -* 14-MAR-2007 (DSB): -* Modify astRebinSeq to allow input variances to be used as weights. -* 19-MAR-2007 (DSB): -* Fix bug in LINEAR_2D macro that caused bad input pixel values to be -* treated as good. -* 16-APR-2007 (DSB): -* Account for reduction in number of degrees of freedom when -* calculating output variances on the basis of spread of input values in -* astReinSeq. -* 28-APR-2007 (DSB): -* Correct code within Rebin... and Resample... functions that provides -* optimal handling for 1- and 2- dimensional mappings. Previously, the -* check for whether or not to use these optimisations was based only on -* the dimensionality of either input (Rebin) or output (Resample). This -* could cause the optimised code to be used at inappropriate times, -* leading to an incorrect effective Mapping between input and output. The -* checks now check both input and output dimensionality in all cases. -* 3-MAY-2007 (DSB): -* An extra parameter ("nused") has been added to astRebinSeq, and -* all the rebinning stuff has been modified to keep "nused" up to date. -* This is needed to correct a fault in the generation of GENVAR -* variances. -* 12-DEC-2007 (DSB): -* Some rebinning kernels (e.g. SINCSINC) have negative values and -* can result in overall negative output weights. Therefore do not -* set output pixels with negative weights bad. -* 6-MAR-2008 (DSB): -* Add an option for astResample to leave unchanged any output pixels -* for which an interpolated value cannot be obtained. This is -* controlled by the new AST__NOBAD flag. -* 7-MAY-2008 (DSB): -* Clarified meaning of AST__GENVAR, AST__USEVAR and AST__VARWGT flags -* in astRebinSeq. -* 9-MAY-2008 (DSB): -* Prevent memory over-run in RebinSeq. -* 5-MAY-2009 (DSB): -* Added astRemoveRegions. -* 11-NOV-2009 (DSB): -* In astRebinSeq initialise "*nused" to zero (as documented) if the -* AST__REBININIT flag is supplied. -* 17-NOV-2009 (DSB): -* Added AST_DISVAR flag for use with astRebinSeq. -* 15-DEC-2009 (DSB): -* Ensure that all axes span at least one pixel when calling -* astLinearApprox. -* 18-DEC-2009 (DSB): -* When using a 1D spreading kernel (in astRebin(Seq)), if the kernel -* is not contained completely within the output array, reflect the -* section of the kernel that falls outside the output array back into -* the output array so that no flux is lost. Also discovered that the -* n-D code (i.e. the KERNEL_ND macro) incorrectly uses the first -* user-supplied parameter as the full kernel width rather than the -* half-width. This has been fixed. -* 26-FEB-2010 (DSB): -* Add astQuadApprox. -* 27-FEB-2010 (DSB): -* - Make astQuadApprox faster, and fix a bug in the calculation of -* the matrix. -* 7-JUN-2010 (DSB): -* In the KERNEL_D rebinning macros, correct the test for the -* central point being outside the bounds of the output image. -* 13-AUG-2010 (DSB): -* In astRebinSeq, scale WLIM to take account of weighting by -* input variances. -* 13-DEC-2010 (DSB): -* Ensure that astMapSplit returns a Mapping that is independent of -* the supplied Mapping (i.e. return a deep copy). This means that -* subsequent changes to the supplied Mapping cannot affect the returned -* Mapping. -* 10-FEB-2011 (DSB): -* When rebinning (in macros NEAR_1/2/ND, KERNEL_1/2/ND, LINEAR_1/2/ND), -* do not treat a zero variance as bad unless the reciprocals of the -* variances are being used as weights. -* 16-JUN-2011 (DSB): -* Allow a check for NaNs to be performed as a debugging tool after -* every invocation of astTransform. This is controlled by the -* AST_REPLACE_NAN environment variable: if unset, no check is -* performed, if set to "1" NaNs are changed to AST__BAD but no -* error is reported, if set to anything else NaNs are changed to -* AST__BAD and an error is reported. -* 6-JUL-2012 (DSB): -* The astRebinSeq family was normalising the returned data and -* variances values incorrectly, when the AST__REBINEND flag was -* supplied. The exact size of the error depended on the nature of -* the Mapping and the spreading method, and so is hard to predict. -* 20-JUL-2012 (DSB): -* Major re-structuring of astRebinSeq to add further -* corrections to the normalisation. The model is now that each -* input array is first rebinned and then scaled to preserve the -* total data sum, and then each final output pixel is the weighed -* mean of all the aligned rebinned pixels. -* 13-AUG-2012 (DSB): -* Added AST__NONORM flag for asstRebuinSeq. -* 30-AUG_2012 (DSB): -* Added AST__CONSERVEFLUX flag for astRebinSeq. -* 10-SEP-2012 (DSB): -* Cater for Mappings that have different numbers of inputs and -* outputs when finding the flux conservation factor within -* astRebinSeq and astResample. -* 1-OCT-2012 (DSB): -* Ensure astRebinSeq does not create any negative output -* variances. -* 2-OCT-2012 (DSB): -* - Check for Infs as well as NaNs. -* - In Rate, break out of the loop if the RMS is very small, not -* just if it is exactly zero. -* 5-OCT-2012 (DSB): -* Complete re-write of Rate. It's now much simpler, faster and -* more reliable. -* 16-OCT-2012 (DSB): -* In MatrixDet, ignore rows/columns filled with AST_BAD as well as -* rows/columns filled with zeros. -* 26-APR-2013 (DSB): -* Change the "nused" parameter of astRebinSeq from "int *" to -* "size_t *" to allow greater amounts of data to be pasted into -* the output array. -* 29-APR-2013 (DSB): -* Do not simplify Mappings that have a set value for their Ident -* attribute. If an Ident value has been set then it means that we -* should be trying to preserve the identify of the Mapping. This -* is implemented via a new protected method (astDoNotSimplify) which -* is overridden by the Frame class so that this restriction applies -* only to genuine Mappings, not Frames. -* 9-MAY-2013 (DSB): -* Change the "nused" parameter of astRebinSeq from "size_t *" to -* "int64_t *" to cater for systems where "size_t" is only 32 bits long. -* 20-MAY-2013 (DSB): -* Always perform a linear fit in RebinAdaptively if flux -* conservation is requested. -* 18-JUL-2013 (DSB): -* Correct logic for determining whether to divide or not in -* RebinAdaptively. The old logic could lead to infinite recursion. -* 1-SEP-2014 (DSB): -* Modify astLinearApprox to avoid using regularly placed -* test points, as such regular placement may result in -* non-representative behaviour. -* 25-SEP-2014 (DSB): -* Add support for B and UB data types to astRebin and astRebinSeq. -* 23-OCT-2014 (DSB): -* Report an error if arrays have too many pixels to count in a 32 -* bit int (astTranGrid, astResample, astRebin and astRebinSeq). -* 23-APR-2015 (DSB): -* Use one bit of this->flags to store the "IsSimple" attribute -* rather using a whole char (this->issimple). -* 16-JUN-2017 (DSB): -* If a simplification fails because the simplification process makes -* an inappropriate assumption about the supplied Mapping (e.g. that -* it has a defined inverse transformation) - thus causing an error to -* be reported, then clear the error status and return a clone of the -* unmodified supplied Mapping. Putting this check in the astSimplify_ -* wrapper function in the base Mapping class is much simpler and less -* error prone than performing tests on the appropriateness of the -* mapping in teh astMapMerge method of each and every mapping class. -* 9-JAN-2018 (DSB): -* Modify astLinearApprox so that a linear mapping in parallel with a -* mapping that generates bad values is considered linear. The returned -* coeffs for the bad outputs are set bad. -* -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to the header - files that define class interfaces that they should make "protected" - symbols available. */ -#define astCLASS Mapping - -/* Define numerical constants for use in thie module. */ -#define GETATTRIB_BUFF_LEN 50 -#define RATEFUN_MAX_CACHE 5 -#define RATE_ORDER 8 - -/* Include files. */ -/* ============== */ - -/* Configuration results */ -/* ---------------------- */ -#if HAVE_CONFIG_H -#include -#endif - -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#include "mapping.h" /* Interface definition for this class */ -#include "cmpmap.h" /* Compund Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "permmap.h" /* Axis permutations */ -#include "winmap.h" /* Window scalings */ -#include "pal.h" /* SLALIB interface */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Module type definitions. */ -/* ======================== */ -/* Enum to represent the data type when resampling a grid of data. */ -typedef enum DataType { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - TYPE_LD, -#endif - TYPE_D, - TYPE_F, - TYPE_L, - TYPE_UL, - TYPE_K, - TYPE_UK, - TYPE_I, - TYPE_UI, - TYPE_S, - TYPE_US, - TYPE_B, - TYPE_UB -} DataType; - -/* Data structure to hold information about a Mapping for use by - optimisation algorithms. */ -typedef struct MapData { - AstMapping *mapping; /* Pointer to the Mapping */ - AstPointSet *pset_in; /* Pointer to input PointSet */ - AstPointSet *pset_out; /* Pointer to output PointSet */ - double *lbnd; /* Pointer to lower constraints on input */ - double *ubnd; /* Pointer to upper constraints on input */ - double **ptr_in; /* Pointer to input PointSet coordinates */ - double **ptr_out; /* Pointer to output PointSet coordinates */ - int coord; /* Index of output coordinate to optimise */ - int forward; /* Use forward transformation? */ - int negate; /* Negate the output value? */ - int nin; /* Number of input coordinates per point */ - int nout; /* Number of output coordinates per point */ -} MapData; - -/* Convert from floating point to floating point or integer */ -#define CONV(IntType,val) ( ( IntType ) ? (int) ( (val) + (((val)>0)?0.5:-0.5) ) : (val) ) - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static int (* parent_equal)( AstObject *, AstObject *, int * ); - - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->Unsimplified_Mapping = NULL; \ - globals->Rate_Disabled = 0; - - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Mapping) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Mapping,Class_Init) -#define class_vtab astGLOBAL(Mapping,Class_Vtab) -#define getattrib_buff astGLOBAL(Mapping,GetAttrib_Buff) -#define unsimplified_mapping astGLOBAL(Mapping,Unsimplified_Mapping) -#define rate_disabled astGLOBAL(Mapping,Rate_Disabled) -#define ratefun_pset1_cache astGLOBAL(Mapping,RateFun_Pset1_Cache) -#define ratefun_pset2_cache astGLOBAL(Mapping,RateFun_Pset2_Cache) -#define ratefun_next_slot astGLOBAL(Mapping,RateFun_Next_Slot) -#define ratefun_pset_size astGLOBAL(Mapping,RateFun_Pset_Size) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ GETATTRIB_BUFF_LEN + 1 ]; - -/* Pointer to origin (unsimplified) Mapping, only used for reporting - error messages. */ -static AstMapping *unsimplified_mapping = NULL; - -/* A flag which indicates if the astRate method should be disabled in - order to improve algorithm speed in cases where the rate value is not - significant. If astRate is disabled then it always returns a constant - value of 1.0. */ -static int rate_disabled = 0; - -/* static values used in function "RateFun". */ -static AstPointSet *ratefun_pset1_cache[ RATEFUN_MAX_CACHE ]; -static AstPointSet *ratefun_pset2_cache[ RATEFUN_MAX_CACHE ]; -static int ratefun_next_slot; -static int ratefun_pset_size[ RATEFUN_MAX_CACHE ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstMappingVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* Prototypes for private member functions. */ -/* ======================================== */ - -#define DECLARE_GENERIC(X,Xtype) \ -static int InterpolateKernel1##X( AstMapping *, int, const int *, const int *, \ - const Xtype *, const Xtype *, int, \ - const int *, const double *const *, \ - void (*)( double, const double *, int, \ - double *, int * ), \ - void (*)( double, const double *, int, \ - double * ), \ - int, const double *, int, Xtype, \ - Xtype *, Xtype *, int * );\ -\ -static int InterpolateLinear##X( int, const int *, const int *, const Xtype *, \ - const Xtype *, int, const int *, \ - const double *const *, int, Xtype, Xtype *, \ - Xtype *, int * ); \ -\ -static int InterpolateNearest##X( int, const int *, const int *, const Xtype *, \ - const Xtype *, int, const int *, \ - const double *const *, int, Xtype, Xtype *, \ - Xtype *, int * ); \ -\ -static int Resample##X( AstMapping *, int, const int [], const int [], \ - const Xtype [], const Xtype [], int, \ - void (*)( void ), const double [], int, double, int, \ - Xtype, int, const int [], const int [], \ - const int [], const int [], Xtype [], Xtype [], int * ); \ -\ -static void ConserveFlux##X( double, int, const int *, Xtype, Xtype *, Xtype *, \ - int * ); \ -\ -static void InterpolateBlockAverage##X( int, const int[], const int[], \ - const Xtype [], const Xtype [], int, const int[], \ - const double *const[], const double[], int, \ - Xtype, Xtype *, Xtype *, int * ); - -DECLARE_GENERIC(B,signed char) -DECLARE_GENERIC(D,double) -DECLARE_GENERIC(F,float) -DECLARE_GENERIC(I,int) -DECLARE_GENERIC(K,INT_BIG) -DECLARE_GENERIC(L,long int) -DECLARE_GENERIC(S,short int) -DECLARE_GENERIC(UB,unsigned char) -DECLARE_GENERIC(UI,unsigned int) -DECLARE_GENERIC(UK,UINT_BIG) -DECLARE_GENERIC(UL,unsigned long int) -DECLARE_GENERIC(US,unsigned short int) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -DECLARE_GENERIC(LD,long double) -#endif - -#undef DECLARE_GENERIC - -#define DECLARE_GENERIC(X,Xtype) \ -static void Rebin##X( AstMapping *, double, int, const int [], const int [], \ - const Xtype [], const Xtype [], int, const double [], int, \ - double, int, Xtype, int, const int [], const int [], \ - const int [], const int [], Xtype [], Xtype [], int * ); \ -\ -static void RebinSeq##X( AstMapping *, double, int, const int [], const int [], \ - const Xtype [], const Xtype [], int, const double [], \ - int, double, int, Xtype, int, const int [], \ - const int [], const int [], const int [], Xtype [], \ - Xtype [], double [], int64_t *, int * ); \ -\ -static void SpreadKernel1##X( AstMapping *, int, const int *, const int *, \ - const Xtype *, const Xtype *, double, int, const int *, \ - const double *const *, \ - void (*)( double, const double *, int, double *, int * ), \ - int, const double *, int, Xtype, int, Xtype *, \ - Xtype *, double *, int64_t *, int * ); \ -\ -static void SpreadLinear##X( int, const int *, const int *, const Xtype *, \ - const Xtype *, double, int, const int *, const double *const *, \ - int, Xtype, int, Xtype *, Xtype *, double *, int64_t *, \ - int * ); \ -\ -static void SpreadNearest##X( int, const int *, const int *, const Xtype *, \ - const Xtype *, double, int, const int *, const double *const *, \ - int, Xtype, int, Xtype *, Xtype *, double *, \ - int64_t *, int * ); - -DECLARE_GENERIC(D,double) -DECLARE_GENERIC(F,float) -DECLARE_GENERIC(I,int) -DECLARE_GENERIC(UB,unsigned char) -DECLARE_GENERIC(B,signed char) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -DECLARE_GENERIC(LD,long double) -#endif - -#undef DECLARE_GENERIC - - - - - - -static AstMapping *RemoveRegions( AstMapping *, int * ); -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static double FindGradient( AstMapping *, double *, int, int, double, double, double *, int * ); -static double J1Bessel( double, int * ); -static double LocalMaximum( const MapData *, double, double, double [], int * ); -static double MapFunction( const MapData *, const double [], int *, int * ); -static double MatrixDet( int, int, const double *, int * ); -static double MaxD( double, double, int * ); -static double NewVertex( const MapData *, int, double, double [], double [], int *, double [], int * ); -static double Random( long int *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static double UphillSimplex( const MapData *, double, int, const double [], double [], double *, int *, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetInvert( AstMapping *, int * ); -static int GetIsLinear( AstMapping *, int * ); -static int GetIsSimple( AstMapping *, int * ); -static int GetNin( AstMapping *, int * ); -static int GetNout( AstMapping *, int * ); -static int GetReport( AstMapping *, int * ); -static int GetTranForward( AstMapping *, int * ); -static int GetTranInverse( AstMapping *, int * ); -static int LinearApprox( AstMapping *, const double *, const double *, double, double *, int * ); -static int MapList( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int MaxI( int, int, int * ); -static int MinI( int, int, int * ); -static int DoNotSimplify( AstMapping *, int * ); -static int QuadApprox( AstMapping *, const double[2], const double[2], int, int, double *, double *, int * ); -static int RebinAdaptively( AstMapping *, int, const int *, const int *, const void *, const void *, DataType, int, const double *, int, double, int, const void *, int, const int *, const int *, const int *, const int *, int, void *, void *, double *, int64_t *, int * ); -static int RebinWithBlocking( AstMapping *, const double *, int, const int *, const int *, const void *, const void *, DataType, int, const double *, int, const void *, int, const int *, const int *, const int *, const int *, int, void *, void *, double *, int64_t *, int * ); -static int ResampleAdaptively( AstMapping *, int, const int *, const int *, const void *, const void *, DataType, int, void (*)( void ), const double *, int, double, int, const void *, int, const int *, const int *, const int *, const int *, void *, void *, int * ); -static int ResampleSection( AstMapping *, const double *, int, const int *, const int *, const void *, const void *, DataType, int, void (*)( void ), const double *, double, int, const void *, int, const int *, const int *, const int *, const int *, void *, void *, int * ); -static int ResampleWithBlocking( AstMapping *, const double *, int, const int *, const int *, const void *, const void *, DataType, int, void (*)( void ), const double *, int, const void *, int, const int *, const int *, const int *, const int *, void *, void *, int * ); -static int SpecialBounds( const MapData *, double *, double *, double [], double [], int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestInvert( AstMapping *, int * ); -static int TestReport( AstMapping *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearInvert( AstMapping *, int * ); -static void ClearReport( AstMapping *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Decompose( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void Gauss( double, const double [], int, double *, int * ); -static void GlobalBounds( MapData *, double *, double *, double [], double [], int * ); -static void Invert( AstMapping *, int * ); -static void MapBox( AstMapping *, const double [], const double [], int, int, double *, double *, double [], double [], int * ); -static void RateFun( AstMapping *, double *, int, int, int, double *, double *, int * ); -static void RebinSection( AstMapping *, const double *, int, const int *, const int *, const void *, const void *, double, DataType, int, const double *, int, const void *, int, const int *, const int *, const int *, const int *, int, void *, void *, double *, int64_t *, int * ); -static void ReportPoints( AstMapping *, int, AstPointSet *, AstPointSet *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetInvert( AstMapping *, int, int * ); -static void SetReport( AstMapping *, int, int * ); -static void Sinc( double, const double [], int, double *, int * ); -static void SincCos( double, const double [], int, double *, int * ); -static void SincGauss( double, const double [], int, double *, int * ); -static void SincSinc( double, const double [], int, double *, int * ); -static void Somb( double, const double [], int, double *, int * ); -static void SombCos( double, const double [], int, double *, int * ); -static void Tran1( AstMapping *, int, const double [], int, double [], int * ); -static void Tran2( AstMapping *, int, const double [], const double [], int, double [], double [], int * ); -static void TranGrid( AstMapping *, int, const int[], const int[], double, int, int, int, int, double *, int * ); -static void TranGridAdaptively( AstMapping *, int, const int[], const int[], const int[], const int[], double, int, int, double *[], int * ); -static void TranGridSection( AstMapping *, const double *, int, const int *, const int *, const int *, const int *, int, double *[], int * ); -static void TranGridWithBlocking( AstMapping *, const double *, int, const int *, const int *, const int *, const int *, int, double *[], int * ); -static void TranN( AstMapping *, int, int, int, const double *, int, int, int, double *, int * ); -static void TranP( AstMapping *, int, int, const double *[], int, int, double *[], int * ); -static void ValidateMapping( AstMapping *, int, int, int, int, const char *, int * ); - - - -/* Member functions. */ -/* ================= */ -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Mapping member function (over-rides the astClearAttrib protected -* method inherited from the Object class). - -* Description: -* This function clears the value of a specified attribute for a -* Mapping, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Mapping. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstMapping *this; /* Pointer to the Mapping structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Mapping structure. */ - this = (AstMapping *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Invert. */ -/* ------- */ - if ( !strcmp( attrib, "invert" ) ) { - astClearInvert( this ); - -/* Report. */ -/* ------- */ - } else if ( !strcmp( attrib, "report" ) ) { - astClearReport( this ); - -/* If the name was not recognised, test if it matches any of the - read-only attributes of this class. If it does, then report an - error. */ - } else if ( !strcmp( attrib, "nin" ) || - !strcmp( attrib, "nout" ) || - !strcmp( attrib, "issimple" ) || - !strcmp( attrib, "islinear" ) || - !strcmp( attrib, "tranforward" ) || - !strcmp( attrib, "traninverse" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -/* -* Name: -* ConserveFlux - -* Purpose: -* Scale the output data and variance values produced by ResampleSection -* by the given flux conservation factor. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void ConserveFlux( double factor, int npoint, const int *offset, -* badval, *out, -* *out_var ) - -* Class Membership: -* Mapping member function. - -* Description: -* This is a set of functions which scale the supplied resampled data -* values by the given flux conservation factor. It also scales any -* variances by the square of the factor. - -* Parameters: -* factor -* The flux conservation factor. This should be the ratio of the -* output pixel size to the input pixel size, in the locality of -* the supplied data values. -* npoint -* The number of points at which the input grid was resampled. -* offset -* Pointer to an array of integers with "npoint" elements. For -* each output point, this array should contain the zero-based -* offset in the output array(s) (i.e. the "out" and, -* optionally, the "out_var" arrays) at which the resampled -* output value(s) is stored. -* badval -* This parameter specifies the value which is used to identify -* bad data and/or variance values in the output array(s). -* out -* Pointer to an array in which the resampled data is supplied. Note -* that details of how the output grid maps on to this array -* (e.g. the storage order, number of dimensions, etc.) is -* arbitrary and is specified entirely by means of the "offset" -* array. The "out" array should therefore contain sufficient -* elements to accommodate the "offset" values supplied. There -* is no requirement that all elements of the "out" array should -* be assigned values, and any which are not addressed by the -* contents of the "offset" array will be left unchanged. -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, in which variance estimates for -* the resampled values are supplied. If no output variance estimates -* are available, a NULL pointer should be given. - -* Notes: -* - There is a separate function for each numerical type of -* gridded data, distinguished by replacing the in the function -* name by the appropriate 1- or 2-character suffix. -*/ -/* Define a macro to implement the function for a specific data - type. */ -#define MAKE_CONSERVEFLUX(X,Xtype) \ -static void ConserveFlux##X( double factor, int npoint, const int *offset, \ - Xtype badval, Xtype *out, Xtype *out_var, int *status ) { \ -\ -/* Local Variables: */ \ - int off_out; /* Pixel offset into output array */ \ - int point; /* Loop counter for output points */ \ -\ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ - for ( point = 0; point < npoint; point++ ) { \ - off_out = offset[ point ]; \ - if( out[ off_out ] != badval ) out[ off_out ] *= factor; \ - } \ -\ - if( out_var ) { \ - factor *= factor; \ - for ( point = 0; point < npoint; point++ ) { \ - off_out = offset[ point ]; \ - if( out_var[ off_out ] != badval ) out_var[ off_out ] *= factor; \ - } \ - } \ -} - - -/* Expand the macro above to generate a function for each required - data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_CONSERVEFLUX(LD,long double) -#endif -MAKE_CONSERVEFLUX(D,double) -MAKE_CONSERVEFLUX(F,float) -MAKE_CONSERVEFLUX(K,INT_BIG) -MAKE_CONSERVEFLUX(L,long int) -MAKE_CONSERVEFLUX(I,int) -MAKE_CONSERVEFLUX(S,short int) -MAKE_CONSERVEFLUX(B,signed char) -MAKE_CONSERVEFLUX(UL,unsigned long int) -MAKE_CONSERVEFLUX(UI,unsigned int) -MAKE_CONSERVEFLUX(UK,UINT_BIG) -MAKE_CONSERVEFLUX(US,unsigned short int) -MAKE_CONSERVEFLUX(UB,unsigned char) - -/* Undefine the macros used above. */ -#undef MAKE_CONSERVEFLUX - -static void Decompose( AstMapping *this, AstMapping **map1, AstMapping **map2, - int *series, int *invert1, int *invert2, int *status ) { -/* -*+ -* Name: -* astDecompose - -* Purpose: -* Decompose a Mapping into two component Mappings. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* void astDecompose( AstMapping *this, AstMapping **map1, -* AstMapping **map2, int *series, int *invert1, -* int *invert2 ) - -* Class Membership: -* Mapping method. - -* Description: -* This function returns pointers to two Mappings which, when applied -* either in series or parallel, are equivalent to the supplied Mapping. -* -* Since the Frame class inherits from the Mapping class, Frames can -* be considered as special types of Mappings and so this method can -* be used to decompose CmpMaps, CmpFrames, CmpRegions or Prisms. - -* Parameters: -* this -* Pointer to the Mapping. -* map1 -* Address of a location to receive a pointer to first component -* Mapping. -* map2 -* Address of a location to receive a pointer to second component -* Mapping. -* series -* Address of a location to receive a value indicating if the -* component Mappings are applied in series or parallel. A non-zero -* value means that the supplied Mapping is equivalent to applying map1 -* followed by map2 in series. A zero value means that the supplied -* Mapping is equivalent to applying map1 to the lower numbered axes -* and map2 to the higher numbered axes, in parallel. -* invert1 -* The value of the Invert attribute to be used with map1. -* invert2 -* The value of the Invert attribute to be used with map2. - -* Applicability: -* CmpMap -* If the supplied Mapping is a CmpMap, then map1 and map2 will be -* returned holding pointers to the component Mappings used to -* create the CmpMap, either in series or parallel. -* Mapping -* For any class of Mapping other than a CmpMap, map1 will be -* returned holding a clone of the supplied Mapping pointer, and map2 -* will be returned holding a NULL pointer. -* CmpFrame -* If the supplied Mapping is a CmpFrame, then map1 and map2 will be -* returned holding pointers to the component Frames used to -* create the CmpFrame. The component Frames are considered to be in -* applied in parallel. -* Frame -* For any class of Frame other than a CmpFrame, map1 will be -* returned holding a clone of the supplied Frame pointer, and map2 -* will be returned holding a NULL pointer. - -* Notes: -* - Any changes made to the component Mappings using the returned -* pointers will be reflected in the supplied Mapping. -* - The returned Invert values should be used in preference to the -* current values of the Invert attribute in map1 and map2. This is -* because the attributes may have changed value since the Mappings -* were combined. - -* Implementation Notes: -* - This function implements the basic astDecompose method -* available via the protected interface to the Frame class. The -* public interface to this method is provided by the -* astDecomposeId_ function. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* The basic Mapping class returns a clone of the supplied Mapping as - map1 and a NULL pointer as map2. */ - if( map1 ) *map1 = astClone( this ); - if( map2 ) *map2 = NULL; - if( series ) *series = 1; - if( invert1 ) *invert1 = astGetInvert( this ); - if( invert2 ) *invert2 = 0; -} - -static int DoNotSimplify( AstMapping *this, int *status ) { -/* -*+ -* Name: -* astMapMerge - -* Purpose: -* Check if a Mapping is appropriate for simplification. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* int astDoNotSImplify( AstMapping *this ); - -* Class Membership: -* Mapping method. - -* Description: -* This function returns a flag indivating if the supplied Mapping is -* appropriate for simplification. - -* Parameters: -* this -* Pointer to the Mapping. - -* Returned Value: -* Non-zero if the supplied Mapping is not appropriate for -* simplification, and zero otherwise. - -* Notes: -* - A value of 0 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check inherited status. */ - if( !astOK ) return 0; - -/* Mappings that have a set value for the Ident attribute should not be - simplified since we want to preserve their individual identify (otherwise - why would the user have given them an Ident value?). */ - return astTestIdent( this ); -} - -int astRateState_( int disabled, int *status ) { -/* -*+ -* Name: -* astRateState - -* Purpose: -* Control whether the astRate method is disabled or not. - -* Type: -* Protected function. - -* Synopsis: -* #include "mapping.h" -* int astRateState( int disabled ) - -* Class Membership: -* Mapping member function - -* Description: -* Some algorithms which use use the astRate method do not actually need -* to know what the Rate value is. For instance, when the Plot class draws -* a border it evaluates the GRAPHICS->Current Mapping hundreds of time. -* If the Mapping includes a RateMap then this can be very very slow -* (depending on how the astRate method is implemented). In fact the -* border drawing algorithm onlyneeds to know if the result is bad or -* not - the actual value produced by the Mappign does not matter. -* -* Such algorithms can be speeded up by forcing the astRate method to -* return a constant value rather than actually doing the numerical -* differentiation. This can be accomplised by calling this method prior -* to implementing the algorithm. It should be called at the end in -* order to re-instate the original disabled flag. - -* Parameters: -* disabled -* The new value for the astRate disabled flag. - -* Returned Value: -* The original value of the astRate disabled flag. - -*- -*/ - astDECLARE_GLOBALS - int result; - astGET_GLOBALS(NULL); - - result = rate_disabled; - rate_disabled = disabled; - return result; -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two Mappings are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* Mapping member function (over-rides the astEqual protected -* method inherited from the Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two Mappings are equivalent. -* -* The implementation provided by this class (the base Mapping class) -* simply reports an error when called, since all concrete Mapping -* subclasses should provide their own implementation. -* -* Note, sub-class implementations should not use astSimplify (e.g. -* combining the two Mapping and then simplifying it), since the -* astSimplify method for certain classes (e.g. CmpMap) may use -* astEqual. Consequently, if astEqual called astSimplify, there would -* be possibilities for infinite loops. - -* Parameters: -* this -* Pointer to the first Object (a Mapping). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the Frames are equivalent, zero otherwise. - -* Notes: -* - The two Mappings are considered equivalent if the combination of -* the first in series with the inverse of the second simplifies to a -* UnitMap. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the Equal method inherited from the parent Object class. This checks - that the Objects are both of the same class (amongst other things). */ - if( (*parent_equal)( this_object, that_object, status ) ) { - -/* Report an error since the concrete sub-class should have over-riden - this method. */ - astError( AST__INTER, "astEqual(Mapping): The %s class does " - "not override the abstract astEqual method inherited " - "from the base Mapping class (internal AST programming " - "error).", status, astGetClass( this_object ) ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static double FindGradient( AstMapping *map, double *at, int ax1, int ax2, - double x0, double h, double *range, int *status ){ -/* -* Name: -* FindGradient - -* Purpose: -* Find the mean gradient in an interval, and the range of gradients -* within the interval. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* double FindGradient( AstMapping *map, double *at, int ax1, int ax2, -* double x0, double h, double *range, int *status ) - -* Class Membership: -* Mapping method. - -* Description: -* This function finds the mean gradient in an interval, and the range -* of gradients within the interval. - -* Parameters: -* map -* Pointer to a Mapping which yields the value of the function at x. -* The Mapping may have any number of inputs and outputs; the specific -* output representing the function value, f, is specified by ax1 and -* the specific input representing the argument, x, is specified by ax2. -* at -* A pointer to an array holding axis values at the position at which -* the function is to be evaluated. The number of values supplied -* must equal the number of inputs to the Mapping. The value supplied -* for axis "ax2" is ignored (the value of "x" is used for axis "ax2"). -* ax1 -* The zero-based index of the Mapping output which is to be -* differentiated. Set this to -1 to allocate, or -2 to release, -* the static resources used by this function. -* ax2 -* The zero-based index of the Mapping input which is to be varied. -* x0 -* The central axis value at which the function is to be evaluated. -* h -* The interval over which the fitting is to be performed. -* range -* A pointer to a location at which to return the range of -* gradients found within the interval. -* status -* Pointer to the inherited status variable. - -* Returns: -* The mean gradient, or AST__BAD if the mean gradient cannot be -* calculated. -*/ - -/* Local Variables: */ - double dh; - double g; - double gmax; - double gmin; - double ret; - double x1; - double x2; - double x[ RATE_ORDER + 2 ]; - double y1; - double y2; - double y[ RATE_ORDER + 2 ]; - int i0; - int i; - int ngood; - -/* Initialise */ - ret = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Store the x values at (RATE_ORDER+1) evenly spaced points over the interval - "h" centred on "x0". */ - i0 = RATE_ORDER/2; - dh = h/RATE_ORDER; - - for( i = 0; i <= RATE_ORDER; i++ ) { - x[ i ] = x0 + ( i - i0 )*dh; - } - -/* Get the function values at these positions. */ - RateFun( map, at, ax1, ax2, RATE_ORDER + 1, x, y, status ); - -/* Find the maximum and minimum mean gradient within any sub-interval, and - note the (x,y) values at the first and last good point within the - interval. */ - y1 = AST__BAD; - y2 = AST__BAD; - gmax = AST__BAD; - gmin = AST__BAD; - ngood = 0; - - for( i = 0; i < RATE_ORDER; i++ ) { - if( y[ i + 1 ] !=AST__BAD && y[ i ] != AST__BAD && - x[ i + 1 ] != x[ i ] ) { - ngood++; - - g = ( y[ i + 1 ] - y[ i ] )/( x[ i + 1 ] - x[ i ] ); - - if( ngood == 1 ) { - gmax = gmin = g; - } else if( g < gmin ) { - gmin = g; - } else if( g > gmax) { - gmax = g; - } - if( y1 == AST__BAD ) { - y1 = y[ i ]; - x1 = x[ i ]; - } - y2 = y[ i + 1 ]; - x2 = x[ i + 1 ]; - } - } - -/* If two or more sub-intervals were usable, return the range of - gradients found, and the mean gradient. */ - if( ngood > 1 ) { - ret = ( y2 - y1 )/( x2 - x1 ); - if( range ) *range = ( gmax - gmin ); - } - - return ret; -} - -static void Gauss( double offset, const double params[], int flags, - double *value, int *status ) { -/* -* Name: -* Gauss - -* Purpose: -* 1-dimensional Gaussian spreading kernel. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void Gauss( double offset, const double params[], int flags, -* double *value, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function calculates the value of a 1-dimensional sub-pixel -* spreading kernel. The function used is exp(-k*x*x). - -* Parameters: -* offset -* The offset of a pixel from the central output point, measured -* in pixels. -* params -* The first element of this array should give a value for "k" -* in the exp(-k*x*x) term. -* flags -* Not used. -* value -* Pointer to a double to receive the calculated kernel value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error checking and does not -* generate errors. -*/ - -/* Calculate the result. */ - *value = exp( -params[ 0 ] * offset * offset ); -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Mapping member function (over-rides the protected astGetAttrib -* method inherited from the Object class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Mapping, formatted as a character string. - -* Parameters: -* this -* Pointer to the Mapping. -* attrib -* Pointer to a null terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Mapping, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Mapping. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *this; /* Pointer to the Mapping structure */ - const char *result; /* Pointer value to return */ - int invert; /* Invert attribute value */ - int islinear; /* IsLinear attribute value */ - int issimple; /* IsSimple attribute value */ - int nin; /* Nin attribute value */ - int nout; /* Nout attribute value */ - int report; /* Report attribute value */ - int tran_forward; /* TranForward attribute value */ - int tran_inverse; /* TranInverse attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Mapping structure. */ - this = (AstMapping *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* Invert. */ -/* ------- */ - if ( !strcmp( attrib, "invert" ) ) { - invert = astGetInvert( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", invert ); - result = getattrib_buff; - } - -/* IsLinear. */ -/* --------- */ - } else if ( !strcmp( attrib, "islinear" ) ) { - islinear = astGetIsLinear( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", islinear ); - result = getattrib_buff; - } - -/* IsSimple. */ -/* --------- */ - } else if ( !strcmp( attrib, "issimple" ) ) { - issimple = astGetIsSimple( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", issimple ); - result = getattrib_buff; - } - -/* Nin. */ -/* ---- */ - } else if ( !strcmp( attrib, "nin" ) ) { - nin = astGetNin( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", nin ); - result = getattrib_buff; - } - -/* Nout. */ -/* ----- */ - } else if ( !strcmp( attrib, "nout" ) ) { - nout = astGetNout( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", nout ); - result = getattrib_buff; - } - -/* Report. */ -/* ------- */ - } else if ( !strcmp( attrib, "report" ) ) { - report = astGetReport( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", report ); - result = getattrib_buff; - } - -/* TranForward. */ -/* ------------ */ - } else if ( !strcmp( attrib, "tranforward" ) ) { - tran_forward = astGetTranForward( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", tran_forward ); - result = getattrib_buff; - } - -/* TranInverse. */ -/* ------------ */ - } else if ( !strcmp( attrib, "traninverse" ) ) { - tran_inverse = astGetTranInverse( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", tran_inverse ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static int GetIsLinear( AstMapping *this, int *status ) { -/* -*+ -* Name: -* astGetIsLinear - -* Purpose: -* Determine if a Mapping is an instance of a linear Mapping class. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* int astGetIsLinear( AstMapping *this ) - -* Class Membership: -* Mapping method. - -* Description: -* This function returns a value indicating whether a Mapping is -* a member of a class of linear Mappings. The base Mapping class -* returns a value of zero. Linear Mapping classes should over-ride -* this function to return a non-zero value. - -* Parameters: -* this -* Pointer to the Mapping. - -* Returned Value: -* One if the Mapping is a member of a linear Mapping class. Zero -* otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - return 0; -} - -static int GetNin( AstMapping *this, int *status ) { -/* -*+ -* Name: -* astGetNin - -* Purpose: -* Get the number of input coordinates for a Mapping. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* int astGetNin( AstMapping *this ) - -* Class Membership: -* Mapping method. - -* Description: -* This function returns the number of input coordinate values -* required per point by a Mapping (i.e. the number of dimensions -* of the space in which input points reside). - -* Parameters: -* this -* Pointer to the Mapping. - -* Returned Value: -* Number of coordinate values required. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - int invert; /* Invert attribute value */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Determine if the Mapping has been inverted. */ - invert = astGetInvert( this ); - -/* Obtain the Nin value. */ - if ( astOK ) result = invert ? this->nout : this->nin; - -/* Return the result. */ - return result; -} - -static int GetNout( AstMapping *this, int *status ) { -/* -*+ -* Name: -* astGetNout - -* Purpose: -* Get the number of output coordinates for a Mapping. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* int astGetNout( AstMapping *this ) - -* Class Membership: -* Mapping method. - -* Description: -* This function returns the number of output coordinate values -* generated per point by a Mapping (i.e. the number of dimensions -* of the space in which output points reside). - -* Parameters: -* this -* Pointer to the Mapping. - -* Returned Value: -* Number of coordinate values generated. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - int invert; /* Invert attribute value */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Determine if the Mapping has been inverted. */ - invert = astGetInvert( this ); - -/* Obtain the Nout value. */ - if ( astOK ) result = invert ? this->nin : this->nout; - -/* Return the result. */ - return result; -} - -static int GetTranForward( AstMapping *this, int *status ) { -/* -*+ -* Name: -* astGetTranForward - -* Purpose: -* Determine if a Mapping defines a forward coordinate transformation. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* int astGetTranForward( AstMapping *this ) - -* Class Membership: -* Mapping method. - -* Description: -* This function returns a value indicating whether a Mapping is -* able to perform a coordinate transformation in the "forward" -* direction. - -* Parameters: -* this -* Pointer to the Mapping. - -* Returned Value: -* Zero if the forward coordinate transformation is not defined, or -* 1 if it is. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - int invert; /* Mapping inverted? */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Determine if the Mapping has been inverted. */ - invert = astGetInvert( this ); - -/* If OK, obtain the result. */ - if ( astOK ) result = invert ? this->tran_inverse : this->tran_forward; - -/* Return the result. */ - return result; -} - -static int GetTranInverse( AstMapping *this, int *status ) { -/* -*+ -* Name: -* astGetTranInverse - -* Purpose: -* Determine if a Mapping defines an inverse coordinate transformation. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* int astGetTranInverse( AstMapping *this ) - -* Class Membership: -* Mapping method. - -* Description: -* This function returns a value indicating whether a Mapping is -* able to perform a coordinate transformation in the "inverse" -* direction. - -* Parameters: -* this -* Pointer to the Mapping. - -* Returned Value: -* Zero if the inverse coordinate transformation is not defined, or -* 1 if it is. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - int invert; /* Mapping inverted? */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Determine if the Mapping has been inverted. */ - invert = astGetInvert( this ); - -/* If OK, obtain the result. */ - if ( astOK ) result = invert ? this->tran_forward : this->tran_inverse; - -/* Return the result. */ - return result; -} - -static void GlobalBounds( MapData *mapdata, double *lbnd, double *ubnd, - double xl[], double xu[], int *status ) { -/* -* Name: -* GlobalBounds - -* Purpose: -* Estimate global coordinate bounds for a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GlobalBounds( MapData *mapdata, double *lbnd, double *ubnd, -* double xl[], double xu[], int *status ); - -* Class Membership: -* Mapping member function. - -* Description: -* This function estimates the global lower and upper bounds of a -* Mapping function within a constrained region of its input -* coordinate space. It uses a robust global optimisation algorithm -* based on the selection of pseudo-random starting positions, -* followed by the location of local minima and maxima using the -* downhill (or uphill) simplex method. The algorithm will cope -* with the case where there are several competing minima (or -* maxima) with nearly equal values. It attempts to locate the -* global bounds to full machine precision when possible. - -* Parameters: -* mapdata -* Pointer to a MapData structure describing the Mapping -* function, its coordinate constraints, etc. -* lbnd -* Pointer to a double. On entry, this should contain a -* previously-obtained upper limit on the global lower bound, or -* AST__BAD if no such limit is available. On exit, it will be -* updated with a new estimate of the global lower bound, if a -* better one has been found. -* ubnd -* Pointer to a double. On entry, this should contain a -* previously-obtained lower limit on the global upper bound, or -* AST__BAD if no such limit is available. On exit, it will be -* updated with a new estimate of the global upper bound, if a -* better one has been found. -* xl -* Pointer to an array of double, with one element for each -* input coordinate. On entry, if *lbnd is not equal to AST__OK, -* this should contain the input coordinates of a point at which -* the Mapping function takes the value *lbnd. On exit, this -* function returns the position of a (not necessarily unique) -* input point at which the Mapping function takes the value of -* the new global lower bound. This array is not altered if an -* improved estimate of the global lower bound cannot be found. -* xu -* Pointer to an array of double, with one element for each -* input coordinate. On entry, if *ubnd is not equal to AST__OK, -* this should contain the input coordinates of a point at which -* the Mapping function takes the value *ubnd. On exit, this -* function returns the position of a (not necessarily unique) -* input point at which the Mapping function takes the value of -* the new global upper bound. This array is not altered if an -* improved estimate of the global upper bound cannot be found. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The efficiency of this function will usually be improved if -* previously-obtained estimates of the extrema and their locations -* are provided. -* - The values returned via "lbnd", "ubnd", "xl" and "xu" will be -* set to the value AST__BAD if this function should fail for any -* reason. Their initial values on entry will not be altered if the -* function is invoked with the global error status set. -*/ - -/* Local Constants: */ - const double default_acc = 3.0e-5; /* Default convergence accuracy */ - const int maxiter = 10000; /* Maximum number of iterations */ - const int minsame = 5; /* Minimum no. consistent extrema required */ - const int nbatch = 32; /* No. function samples obtained per batch */ - -/* Local Variables: */ - AstPointSet *pset_in; /* Input PointSet for batch transformation */ - AstPointSet *pset_out; /* Output PointSet for batch transformation */ - double **ptr_in; /* Pointer to batch input coordinates */ - double **ptr_out; /* Pointer to batch output coordinates */ - double *active_hi; /* Estimated upper limits of active region */ - double *active_lo; /* Estimated lower limits of active region */ - double *sample_hi; /* Upper limits of sampled region */ - double *sample_lo; /* Lower limits of sampled region */ - double *sample_width; /* Nominal widths of sampled region */ - double *x; /* Pointer to array of coordinates */ - double acc; /* Convergence accuracy for finding maximum */ - double active_width; /* Estimated width of active region */ - double new_max; /* Value of new local maximum */ - double new_min; /* Value of new local minimum */ - double oversize; /* Over-size factor for sampled region */ - double random; /* Pseudo-random number */ - int bad; /* Transformed position is bad? */ - int batch; /* Next element to use in position batch */ - int coord; /* Loop counter for coordinates */ - int done_max; /* Satisfactory global maximum found? */ - int done_min; /* Satisfactory global minimum found? */ - int iter; /* Loop counter for iterations */ - int ncoord; /* Number of coordinates in search space */ - int nmax; /* Number of local maxima found */ - int nmin; /* Number of local minima found */ - int nsame_max; /* Number of equivalent local maxima found */ - int nsame_min; /* Number of equivalent local minima found */ - long int seed = 1776655449; /* Arbitrary pseudo-random number seed */ - -/* Check the global error status */ - if ( !astOK ) return; - -/* Initialise. */ - done_max = 0; - done_min = 0; - nmax = 0; - nmin = 0; - nsame_max = 0; - nsame_min = 0; - pset_in = NULL; - pset_out = NULL; - ptr_in = NULL; - ptr_out = NULL; - oversize = 0; - bad = 0; - -/* Extract the number of input coordinates for the Mapping function - and allocate workspace. */ - ncoord = mapdata->nin; - active_hi = astMalloc( sizeof( double ) * (size_t) ncoord ); - active_lo = astMalloc( sizeof( double ) * (size_t) ncoord ); - sample_hi = astMalloc( sizeof( double ) * (size_t) ncoord ); - sample_lo = astMalloc( sizeof( double ) * (size_t) ncoord ); - sample_width = astMalloc( sizeof( double ) * (size_t) ncoord ); - x = astMalloc( sizeof( double ) * (size_t) ncoord ); - if ( astOK ) { - -/* Calculate the factor by which the size of the region we sample will - exceed the size of the Mapping function's active region (the region - where the transformed coordinates are non-bad) in each - dimension. This is chosen so that the volume ratio will be 2. */ - oversize = pow( 2.0, 1.0 / (double) ncoord ); - -/* Initialise the limits of the active region to unknown. */ - for ( coord = 0; coord < ncoord; coord++ ) { - active_lo[ coord ] = DBL_MAX;; - active_hi[ coord ] = -DBL_MAX; - -/* Initialise the nominal widths of the sampled region to be the - actual widths of the search region times the over-size factor. */ - sample_width[ coord ] = ( mapdata->ubnd[ coord ] - - mapdata->lbnd[ coord ] ) * oversize; - -/* Initialise the sampled region to match the search region. */ - sample_lo[ coord ] = mapdata->lbnd[ coord ]; - sample_hi[ coord ] = mapdata->ubnd[ coord ]; - } - -/* Set up position buffer. */ -/* ======================= */ -/* Create two PointSets to act as buffers to hold a complete batch of - input and output coordinates. Obtain pointers to their coordinate - arrays. */ - pset_in = astPointSet( nbatch, ncoord, "", status ); - pset_out = astPointSet( nbatch, mapdata->nout, "", status ); - ptr_in = astGetPoints( pset_in ); - ptr_out = astGetPoints( pset_out ); - -/* Initialise the next element to be used in the position buffer to - indicate that the buffer is initially empty. */ - batch = nbatch; - } - -/* Define a macro to fill the position buffer with a set of - pseudo-random positions and to transform them. */ -#define FILL_POSITION_BUFFER {\ -\ -/* We first generate a suitable volume over which to distribute the\ - batch of pseudo-random positions. Initially, this will be the\ - entire search volume, but if we find that the only non-bad\ - transformed coordinates we obtain are restricted to a small\ - sub-region of this input volume, then we reduce the sampled volume\ - so as to concentrate more on the active region. */\ -\ -/* Loop through each input coordinate, checking that at least one\ - non-bad transformed point has been obtained. If not, we do not\ - adjust the sampled volume, as we do not yet know where the active\ - region lies. */\ - for ( coord = 0; coord < ncoord; coord++ ) {\ - if ( active_hi[ coord ] >= active_lo[ coord ] ) {\ -\ -/* Estimate the width of the active region from the range of input\ - coordinates that have so far produced non-bad transformed\ - coordinates. */\ - active_width = active_hi[ coord ] - active_lo[ coord ];\ -\ -/* If the current width of the sampled volume exceeds this estimate by\ - more than the required factor, then reduce the width of the sampled\ - volume. The rate of reduction is set so that the volume of the\ - sampled region can halve with every fourth batch of positions. */\ - if ( ( active_width * oversize ) < sample_width[ coord ] ) {\ - sample_width[ coord ] /= pow( oversize, 0.25 );\ -\ -/* If the width of the sampled volume does not exceed that of the\ - known active region by the required factor, then adjust it so that\ - it does. Note that we must continue to sample some points outside\ - the known active region in case we have missed any (in which case\ - the sampled region will expand again to include them). */\ - } else if ( ( active_width * oversize ) > sample_width[ coord ] ) {\ - sample_width[ coord ] = active_width * oversize;\ - }\ -\ -/* Calculate the lower and upper bounds on the sampled volume, using\ - the new width calculated above and centring it on the active\ - region, as currently known. */\ - sample_lo[ coord ] = ( active_lo[ coord ] + active_hi[ coord ] -\ - sample_width[ coord ] ) * 0.5;\ - sample_hi[ coord ] = ( active_lo[ coord ] + active_hi[ coord ] +\ - sample_width[ coord ] ) * 0.5;\ -\ -/* Ensure that the sampled region does not extend beyond the original\ - search region. */\ - if ( sample_lo[ coord ] < mapdata->lbnd[ coord ] ) {\ - sample_lo[ coord ] = mapdata->lbnd[ coord ];\ - }\ - if ( sample_hi[ coord ] > mapdata->ubnd[ coord ] ) {\ - sample_hi[ coord ] = mapdata->ubnd[ coord ];\ - }\ - }\ - }\ -\ -/* Having determined the size of the sampled volume, create a batch of\ - pseudo-random positions uniformly distributed within it. */\ - for ( batch = 0; batch < nbatch; batch++ ) {\ - for ( coord = 0; coord < ncoord; coord++ ) {\ - random = Random( &seed, status );\ - ptr_in[ coord ][ batch ] = sample_lo[ coord ] * random +\ - sample_hi[ coord ] * ( 1.0 - random );\ - }\ - }\ -\ -/* Transform these positions. We process them in a single batch in\ - order to minimise the overheads in doing this. */\ - (void) astTransform( mapdata->mapping, pset_in, mapdata->forward,\ - pset_out );\ -\ -/* Indicate that the position buffer is now full. */\ - batch = 0;\ -} - -/* Fill the position buffer using the above macro. (Note that because - we do not yet have an estimate of the size of the active region, - this does not change the sampled region size from our earlier - initialised values. */ - FILL_POSITION_BUFFER; - -/* Iterate. */ -/* ======== */ -/* Loop to perform up to "maxiter" iterations to estimate the global - minimum and maximum. */ - for ( iter = 0; astOK && ( iter < maxiter ); iter++ ) { - -/* Determine the search accuracy. */ -/* ============================== */ -/* Decide the accuracy to which local extrema should be found. The - intention here is to optimise performance, especially where one - extremum lies near zero and so could potentially be found to - unnecessarily high precision. If we make a mis-assumption (the code - below is not fool-proof), we will slow things down for this - iteration, but the error will be corrected in future iterations - once better estimates are available. */ - -/* If we have no current estimate of either global extremum, we assume - the values we eventually obtain will be of order unity and required - to the default accuracy. */ - acc = default_acc; - -/* If we already have an estimate of both global extrema, we set the - accuracy level so that the difference between them will be known to - the default accuracy. */ - if ( ( *lbnd != AST__BAD ) && ( *ubnd != AST__BAD ) ) { - acc = fabs( *ubnd - *lbnd ) * default_acc; - -/* If we have an estimate of only one global extremum, we assume that - the difference between the two global extrema will eventually be of - the same order as the estimate we currently have, so long as this - is not less than unity. */ - } else if ( *lbnd != AST__BAD ) { - if ( fabs( *lbnd ) > 1.0 ) acc = fabs( *lbnd) * default_acc; - } else if ( *ubnd != AST__BAD ) { - if ( fabs( *ubnd ) > 1.0 ) acc = fabs( *ubnd) * default_acc; - } - -/* Search for a new local minimum. */ -/* =============================== */ -/* If we are still searching for the global minimum, then obtain a set - of starting coordinates from which to find a new local minimum. */ - if ( !done_min ) { - -/* On the first iteration, start searching at the position where the - best estimate of the global minimum (if any) has previously been - found. We know that this produces non-bad transformed - coordinates. */ - bad = 0; - if ( !iter && ( *lbnd != AST__BAD ) ) { - for ( coord = 0; coord < ncoord; coord++ ) { - x[ coord ] = xl[ coord ]; - } - -/* Otherwise, if no estimate of the global minimum is available, then - start searching at the position where the best estimate of the - global maximum (if any) has been found. This may be a long way from - a local minimum, but at least it will yield a non-bad value for the - Mapping function, so some sort of estimate of the global minimum - will be obtained. This is important in cases where finding the - active region of the function is the main problem. Note that this - condition can only occur once, since the global minimum will have - an estimate on the next iteration. */ - } else if ( ( *lbnd == AST__BAD ) && ( *ubnd != AST__BAD ) ) { - for ( coord = 0; coord < ncoord; coord++ ) { - x[ coord ] = xu[ coord ]; - } - -/* Having exhausted the above possibilities, we use pseudo-random - starting positions which are uniformly distributed throughout the - search volume. First check to see if the buffer containing such - positions is empty and refill it if necessary. */ - } else { - if ( batch >= nbatch ) FILL_POSITION_BUFFER; - -/* Test the next available set of output (transformed) coordinates in - the position buffer to see if they are bad. */ - if ( astOK ) { - for ( coord = 0; coord < mapdata->nout; coord++ ) { - bad = ( ptr_out[ coord ][ batch ] == AST__BAD ); - if ( bad ) break; - } - -/* If not, we have a good starting position for finding a local - minimum, so extract the corresponding input coordinates. */ - if ( !bad ) { - for ( coord = 0; coord < ncoord; coord++ ) { - x[ coord ] = ptr_in[ coord ][ batch ]; - } - } - -/* Increment the position buffer location. */ - batch++; - } - } - -/* If we do not have a good starting position, we can't do anything - more on this iteration. A new position will be obtained and tested - on the next iteration and this (we hope) will eventually identify a - suitable starting point. */ - if ( astOK && !bad ) { - -/* Form estimates of the lower and upper limits of the active region - from the starting positions used. */ - for ( coord = 0; coord < ncoord; coord++ ) { - if ( x[ coord ] < active_lo[ coord ] ) { - active_lo[ coord ] = x[ coord ]; - } - if ( x[ coord ] > active_hi[ coord ] ) { - active_hi[ coord ] = x[ coord ]; - } - } - -/* Indicate that the Mapping function should be negated (because we - want a local minimum) and then search for a local maximum in this - negated function. If the result is non-bad (as it should always be, - barring an error), then negate it to obtain the value of the local - minimum found. */ - mapdata->negate = 1; - new_min = LocalMaximum( mapdata, acc, 0.01, x, status ); - if ( new_min != AST__BAD ) { - new_min = -new_min; - -/* Update the estimates of the lower and upper bounds of the active - region to take account of where the minimum was found. */ - for ( coord = 0; coord < ncoord; coord++ ) { - if ( x[ coord ] < active_lo[ coord ] ) { - active_lo[ coord ] = x[ coord ]; - } - if ( x[ coord ] > active_hi[ coord ] ) { - active_hi[ coord ] = x[ coord ]; - } - } - -/* Count the number of times we successfully locate a local minimum - (ignoring the fact they might all be the same one). */ - nmin++; - -/* Update the global minimum. */ -/* ========================== */ -/* If this is the first estimate of the global minimum, then set to - one the count of the number of consecutive iterations where this - estimate remains unchanged. Store the minimum value and its - position. */ - if ( *lbnd == AST__BAD ) { - nsame_min = 1; - *lbnd = new_min; - for ( coord = 0; coord < ncoord; coord++ ) { - xl[ coord ] = x[ coord ]; - } - -/* Otherwise, test if this local minimum is lower than the previous - estimate of the global minimum. If so, then reset the count of - unchanged estimates of the global mimimum to one if the difference - exceeds the accuracy with which the minimum was found (i.e. if we - have found a significantly different minimum). Otherwise, just - increment this count (because we have found the same minimum but by - chance with slightly improved accuracy). Store the new minimum and - its position. */ - } else if ( new_min < *lbnd ) { - nsame_min = ( ( *lbnd - new_min ) > acc ) ? 1 : - nsame_min + 1; - *lbnd = new_min; - for ( coord = 0; coord < ncoord; coord++ ) { - xl[ coord ] = x[ coord ]; - } - -/* If the latest local minimum is no improvement on previous estimates - of the global minimum, then increment the count of unchanged - estimates of the global mimimum, but do not save the new one. */ - } else { - nsame_min++; - } - -/* Determine if a satisfactory estimate of the global minimum has been - obtained. It has if the number of consecutive local minima which - have not significantly improved the estimate is at least equal to - "minsame", and at least 30% of the total number of local minima - found. */ - if ( ( nsame_min >= minsame ) && - ( nsame_min >= (int) ( 0.3f * (float) nmin + 0.5f ) ) ) { - done_min = 1; - } - } - } - } - -/* Search for a new local maximum. */ -/* =============================== */ -/* Now repeat all of the above to find a new local maximum which - estimates the global maximum. */ - if ( !done_max ) { - -/* Choose a suitable starting position, based on one already available - if appropriate. */ - if ( !iter && ( *ubnd != AST__BAD ) ) { - for ( coord = 0; coord < ncoord; coord++ ) { - x[ coord ] = xu[ coord ]; - } - - } else if ( ( *ubnd == AST__BAD ) && ( *lbnd != AST__BAD ) ) { - for ( coord = 0; coord < ncoord; coord++ ) { - x[ coord ] = xl[ coord ]; - } - -/* Otherwise use a pseudo-random position, refilling the position - buffer if necessary. Check if the transformed coordinates are - bad. */ - } else { - if ( batch >= nbatch ) FILL_POSITION_BUFFER; - if ( astOK ) { - for ( coord = 0; coord < mapdata->nout; coord++ ) { - bad = ( ptr_out[ coord ][ batch ] == AST__BAD ); - if ( bad ) break; - } - if ( !bad ) { - for ( coord = 0; coord < ncoord; coord++ ) { - x[ coord ] = ptr_in[ coord ][ batch ]; - } - } - batch++; - } - } - -/* If the coordinates are OK, update the active region limits. */ - if ( astOK && !bad ) { - for ( coord = 0; coord < ncoord; coord++ ) { - if ( x[ coord ] < active_lo[ coord ] ) { - active_lo[ coord ] = x[ coord ]; - } - if ( x[ coord ] > active_hi[ coord ] ) { - active_hi[ coord ] = x[ coord ]; - } - } - -/* Find a local maximum in the Mapping function. */ - mapdata->negate = 0; - new_max = LocalMaximum( mapdata, acc, 0.01, x, status ); - if ( new_max != AST__BAD ) { - -/* Use the result to further update the active region limits. */ - for ( coord = 0; coord < ncoord; coord++ ) { - if ( x[ coord ] < active_lo[ coord ] ) { - active_lo[ coord ] = x[ coord ]; - } - if ( x[ coord ] > active_hi[ coord ] ) { - active_hi[ coord ] = x[ coord ]; - } - } - -/* Count the number of local maxima found. */ - nmax++; - -/* Update the estimate of the global maximum. */ - if ( *ubnd == AST__BAD ) { - nsame_max = 1; - *ubnd = new_max; - for ( coord = 0; coord < ncoord; coord++ ) { - xu[ coord ] = x[ coord ]; - } - - } else if ( new_max > *ubnd ) { - nsame_max = ( ( new_max - *ubnd ) > acc ) ? 1 : - nsame_max + 1; - *ubnd = new_max; - for ( coord = 0; coord < ncoord; coord++ ) { - xu[ coord ] = x[ coord ]; - } - - } else { - nsame_max++; - } - -/* Test for a satisfactory global maximum estimate. */ - if ( ( nsame_max >= minsame ) && - ( nsame_max >= (int) ( 0.3f * (float) nmax + 0.5 ) ) ) { - done_max = 1; - } - } - } - } - -/* Quit iterating once both the global minimum and the global maximum - have been found. */ - if ( done_min && done_max ) break; - } - -/* Free workspace. */ - active_hi = astFree( active_hi ); - active_lo = astFree( active_lo ); - sample_hi = astFree( sample_hi ); - sample_lo = astFree( sample_lo ); - sample_width = astFree( sample_width ); - x = astFree( x ); - -/* Annul temporary PointSets. */ - pset_in = astAnnul( pset_in ); - pset_out = astAnnul( pset_out ); - -/* If the global minimum has been found, attempt to polish the result - to machine precision by requesting that it be found with an - accuracy tolerance of zero (subject to the maximum number of - iterations that LocalMaximum will perform,). */ - if ( astOK ) { - if ( *lbnd != AST__BAD ) { - mapdata->negate = 1; - *lbnd = LocalMaximum( mapdata, 0.0, sqrt( DBL_EPSILON ), xl, status ); - if ( *lbnd != AST__BAD ) *lbnd = - *lbnd; - } - -/* Similarly polish the estimate of the global maximum. */ - if ( *ubnd != AST__BAD ) { - mapdata->negate = 0; - *ubnd = LocalMaximum( mapdata, 0.0, sqrt( DBL_EPSILON ), xu, status ); - } - -/* If either extremum could not be found, then report an error. */ - if ( ( *lbnd == AST__BAD ) || ( *ubnd == AST__BAD ) ) { - astError( AST__MBBNF, "astMapBox(%s): No valid output coordinates " - "(after %d test points).", status, astGetClass( mapdata->mapping ), - 2 * maxiter ); - } - -/* If an error occurred, then return bad extremum values and - coordinates. */ - if ( !astOK ) { - *lbnd = AST__BAD; - *ubnd = AST__BAD; - for ( coord = 0; coord < ncoord; coord++ ) { - xl[ coord ] = AST__BAD; - xu[ coord ] = AST__BAD; - } - } - } - -/* Undefine macros local to this function. */ -#undef FILL_POSITION_BUFFER -} - -void astInitMappingVtab_( AstMappingVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitMappingVtab - -* Purpose: -* Initialise a virtual function table for a Mapping. - -* Type: -* Protected function. - -* Synopsis: -* #include "mapping.h" -* void astInitMappingVtab( AstMappingVtab *vtab, const char *name ) - -* Class Membership: -* Mapping vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Mapping class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitObjectVtab( (AstObjectVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAMapping) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstObjectVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ -#define VTAB_GENERIC(X) \ - vtab->Resample##X = Resample##X; - -VTAB_GENERIC(B) -VTAB_GENERIC(D) -VTAB_GENERIC(F) -VTAB_GENERIC(I) -VTAB_GENERIC(K) -VTAB_GENERIC(L) -VTAB_GENERIC(S) -VTAB_GENERIC(UB) -VTAB_GENERIC(UI) -VTAB_GENERIC(UK) -VTAB_GENERIC(UL) -VTAB_GENERIC(US) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -VTAB_GENERIC(LD) -#endif - -#undef VTAB_GENERIC - -#define VTAB_GENERIC(X) \ - vtab->Rebin##X = Rebin##X; \ - vtab->RebinSeq##X = RebinSeq##X; - -VTAB_GENERIC(D) -VTAB_GENERIC(F) -VTAB_GENERIC(I) -VTAB_GENERIC(B) -VTAB_GENERIC(UB) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -VTAB_GENERIC(LD) -#endif - -#undef VTAB_GENERIC - - - vtab->ClearInvert = ClearInvert; - vtab->ClearReport = ClearReport; - vtab->Decompose = Decompose; - vtab->DoNotSimplify = DoNotSimplify; - vtab->GetInvert = GetInvert; - vtab->GetIsLinear = GetIsLinear; - vtab->GetIsSimple = GetIsSimple; - vtab->GetNin = GetNin; - vtab->GetNout = GetNout; - vtab->GetReport = GetReport; - vtab->GetTranForward = GetTranForward; - vtab->GetTranInverse = GetTranInverse; - vtab->Invert = Invert; - vtab->LinearApprox = LinearApprox; - vtab->MapBox = MapBox; - vtab->MapList = MapList; - vtab->MapMerge = MapMerge; - vtab->MapSplit = MapSplit; - vtab->QuadApprox = QuadApprox; - vtab->Rate = Rate; - vtab->ReportPoints = ReportPoints; - vtab->RemoveRegions = RemoveRegions; - vtab->SetInvert = SetInvert; - vtab->SetReport = SetReport; - vtab->Simplify = Simplify; - vtab->TestInvert = TestInvert; - vtab->TestReport = TestReport; - vtab->Tran1 = Tran1; - vtab->Tran2 = Tran2; - vtab->TranGrid = TranGrid; - vtab->TranN = TranN; - vtab->TranP = TranP; - vtab->Transform = Transform; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - parent_equal = object->Equal; - object->Equal = Equal; - -/* Declare the destructor, copy constructor and dump function. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "Mapping", "Mapping between coordinate systems" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -/* -* Name: -* InterpolateKernel1 - -* Purpose: -* Resample a data grid, using a 1-d interpolation kernel. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int InterpolateKernel1( AstMapping *this, int ndim_in, -* const int *lbnd_in, const int *ubnd_in, -* const *in, const *in_var, -* int npoint, const int *offset, -* const double *const *coords, -* void (* kernel)( double, const double [], int, -* double *, int * ), -* void (* fkernel)( double, const double [], int, -* double * ), -* int neighb, const double *params, int flags, -* badval, -* *out, *out_var ) - -* Class Membership: -* Mapping member function. - -* Description: -* This is a set of functions which resample a rectangular input -* grid of data (and, optionally, associated statistical variance -* values) so as to place them into a new output grid. Each output -* grid point may be mapped on to a position in the input grid in -* an arbitrary way. The input and output grids may have any number -* of dimensions, not necessarily equal. -* -* Where the positions given do not correspond with a pixel centre -* in the input grid, interpolation is performed using a weighted -* sum of the surrounding pixel values. The weights are determined -* by a separable kernel which is the product of a 1-dimensional -* kernel function evaluated along each input dimension. A pointer -* should be supplied to the 1-dimensional kernel function to be -* used. - -* Parameters: -* this -* Pointer to the Mapping being used in the resampling operation -* (this is only used for constructing error messages). -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input grid, its extent along a particular -* (i'th) dimension being ubnd_in[i]-lbnd_in[i]+1 (assuming "i" -* is zero-based). They also define the input grid's coordinate -* system, with each pixel being of unit extent along each -* dimension with integral coordinate values at its centre. -* in -* Pointer to the array of data to be resampled (with an element -* for each pixel in the input grid). The numerical type of -* these data should match the function used, as given by the -* suffix on the function name. The storage order should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -* (i.e. Fortran array storage order). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and type as the "in" array), which -* represent estimates of the statistical variance associated -* with each element of the "in" array. If this second array is -* given (along with the corresponding "out_var" array), then -* estimates of the variance of the resampled data will also be -* returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* npoint -* The number of points at which the input grid is to be -* resampled. -* offset -* Pointer to an array of integers with "npoint" elements. For -* each output point, this array should contain the zero-based -* offset in the output array(s) (i.e. the "out" and, -* optionally, the "out_var" arrays) at which the resampled -* output value(s) should be stored. -* coords -* An array of pointers to double, with "ndim_in" -* elements. Element "coords[coord]" should point at the first -* element of an array of double (with "npoint" elements) which -* contains the values of coordinate number "coord" for each -* interpolation point. The value of coordinate number "coord" -* for interpolation point number "point" is therefore given by -* "coords[coord][point]" (assuming both indices to be -* zero-based). If any point has a coordinate value of AST__BAD -* associated with it, then the corresponding output data (and -* variance) will be set to the value given by "badval" (unles the -* AST__NOBAD flag is specified). -* kernel -* Pointer to the 1-dimensional kernel function to be used. -* fkernel -* Pointer to the 1-dimensional kernel function to be used with no -* trailing status argument. This is only used if "kernel" is NULL. -* neighb -* The number of neighbouring pixels in each dimension (on each -* side of the interpolation position) which are to contribute -* to the interpolated value. This value should be at least 1. -* params -* Pointer to an optional array of parameter values to be passed -* to the interpolation kernel function. If no parameters are -* required by this function, then a NULL pointer may be -* supplied. -* flags -* The bitwise OR of a set of flag values which provide -* additional control over the resampling operation. -* badval -* If the AST__USEBAD flag is set in the "flags" value (above), -* this parameter specifies the value which is used to identify -* bad data and/or variance values in the input array(s). Its -* numerical type must match that of the "in" (and "in_var") -* arrays. Unles the AST__NOBAD flag is specified in "flags", the -* same value will also be used to flag any output array elements -* for which resampled values could not be obtained. The output -* arrays(s) may be flagged with this value whether or not the -* AST__USEBAD flag is set (the function return value indicates -* whether any such values have been produced). -* out -* Pointer to an array with the same data type as the "in" -* array, into which the resampled data will be returned. Note -* that details of how the output grid maps on to this array -* (e.g. the storage order, number of dimensions, etc.) is -* arbitrary and is specified entirely by means of the "offset" -* array. The "out" array should therefore contain sufficient -* elements to accommodate the "offset" values supplied. There -* is no requirement that all elements of the "out" array should -* be assigned values, and any which are not addressed by the -* contents of the "offset" array will be left unchanged. -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the resampled values may be returned. This array will only be -* used if the "in_var" array has been given. It is addressed in -* exactly the same way (via the "offset" array) as the "out" -* array. The values returned are estimates of the statistical -* variance of the corresponding values in the "out" array, on -* the assumption that all errors in input grid values (in the -* "in" array) are statistically independent and that their -* variance estimates (in the "in_var" array) may simply be -* summed (with appropriate weighting factors). -* -* If no output variance estimates are required, a NULL pointer -* should be given. - -* Returned Value: -* The number of output grid points for which no valid output value -* could be obtained. - -* Notes: -* - There is a separate function for each numerical type of -* gridded data, distinguished by replacing the in the function -* name by the appropriate 1- or 2-character suffix. -* - A value of zero will be returned if any of these functions is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ -/* Define macros to implement the function for a specific data - type. */ -#define MAKE_INTERPOLATE_KERNEL1(X,Xtype,Xfloating,Xfloattype,Xsigned) \ -static int InterpolateKernel1##X( AstMapping *this, int ndim_in, \ - const int *lbnd_in, const int *ubnd_in, \ - const Xtype *in, const Xtype *in_var, \ - int npoint, const int *offset, \ - const double *const *coords, \ - void (* kernel)( double, const double [], \ - int, double *, int * ), \ - void (* fkernel)( double, const double [], \ - int, double * ), \ - int neighb, const double *params, \ - int flags, Xtype badval, \ - Xtype *out, Xtype *out_var, int *status ) { \ -\ -/* Local Variables: */ \ - astDECLARE_GLOBALS /* Thread-specific data */ \ - Xfloattype hi_lim; /* Upper limit on output values */ \ - Xfloattype lo_lim; /* Lower limit on output values */ \ - Xfloattype sum; /* Weighted sum of pixel data values */ \ - Xfloattype sum_var; /* Weighted sum of pixel variance values */ \ - Xfloattype val; /* Data value to be assigned to output */ \ - Xfloattype val_var; /* Variance to be assigned to output */ \ - Xfloattype wtsum; /* Sum of weight values */ \ - Xfloattype wtsum_sq; /* Square of sum of weights */ \ - Xtype var; /* Variance value */ \ - double **wtptr; /* Pointer to array of weight pointers */ \ - double **wtptr_last; /* Array of highest weight pointer values */ \ - double *kval; /* Pointer to array of kernel values */ \ - double *wtprod; /* Accumulated weight value array pointer */ \ - double *xn_max; /* Pointer to upper limits array (n-d) */ \ - double *xn_min; /* Pointer to lower limits array (n-d) */ \ - double pixwt; /* Weight to apply to individual pixel */ \ - double wt_y; /* Value of y-dependent pixel weight */ \ - double x; /* x coordinate value */ \ - double xmax; /* x upper limit */ \ - double xmin; /* x lower limit */ \ - double xn; /* Coordinate value (n-d) */ \ - double y; /* y coordinate value */ \ - double ymax; /* y upper limit */ \ - double ymin; /* y lower limit */ \ - int *hi; /* Pointer to array of upper indices */ \ - int *lo; /* Pointer to array of lower indices */ \ - int *stride; /* Pointer to array of dimension strides */ \ - int bad; /* Output pixel bad? */ \ - int bad_var; /* Output variance bad? */ \ - int done; /* All pixel indices done? */ \ - int hi_x; /* Upper pixel index (x dimension) */ \ - int hi_y; /* Upper pixel index (y dimension) */ \ - int idim; /* Loop counter for dimensions */ \ - int ii; /* Loop counter for dimensions */ \ - int ix; /* Pixel index in input grid x dimension */ \ - int ixn; /* Pixel index in input grid (n-d) */ \ - int iy; /* Pixel index in input grid y dimension */ \ - int kerror; /* Error signalled by kernel function? */ \ - int lo_x; /* Lower pixel index (x dimension) */ \ - int lo_y; /* Lower pixel index (y dimension) */ \ - int nobad; /* Was the AST__NOBAD flag set? */ \ - int off1; /* Input pixel offset due to y index */ \ - int off_in; /* Offset to input pixel */ \ - int off_out; /* Offset to output pixel */ \ - int pixel; /* Offset to input pixel containing point */ \ - int point; /* Loop counter for output points */ \ - int result; /* Result value to return */ \ - int s; /* Temporary variable for strides */ \ - int usebad; /* Use "bad" input pixel values? */ \ - int usevar; /* Process variance array? */ \ - int ystride; /* Stride along input grid y dimension */ \ -\ -/* Initialise. */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Get a pointer to a structure holding thread-specific global data values */ \ - astGET_GLOBALS(this); \ -\ -/* Further initialisation. */ \ - kerror = 0; \ - sum_var = 0; \ - val = 0; \ - val_var = 0; \ - wtsum = 0; \ - bad = 0; \ - bad_var = 0; \ - sum = 0.0; \ -\ -/* Determine if we are processing bad pixels or variances. */ \ - nobad = flags & AST__NOBAD; \ - usebad = flags & AST__USEBAD; \ - usevar = in_var && out_var; \ -\ -/* Set up limits for checking output values to ensure that they do not \ - overflow the range of the data type being used. */ \ - lo_lim = LO_##X; \ - hi_lim = HI_##X; \ -\ -/* Handle the 1-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - if ( ndim_in == 1 ) { \ -\ -/* Calculate the coordinate limits of the input grid. */ \ - xmin = (double) lbnd_in[ 0 ] - 0.5; \ - xmax = (double) ubnd_in[ 0 ] + 0.5; \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,1) \ - } \ - } \ - } \ -\ -/* Four more cases as above, but this time with the AST__NOBAD flag \ - un-set. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,0) \ - } \ - } \ - } \ - } \ -\ -/* Exit point on error in kernel function */ \ - Kernel_Error_1d: ; \ -\ -/* Handle the 2-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - } else if ( ndim_in == 2 ) { \ -\ -/* Allocate workspace. */ \ - kval = astMalloc( sizeof( double ) * (size_t) ( 2 * neighb ) ); \ - if ( astOK ) { \ -\ -/* Calculate the stride along the y dimension of the input grid. */ \ - ystride = ubnd_in[ 0 ] - lbnd_in[ 0 ] + 1; \ -\ -/* Calculate the coordinate limits of the input grid in each \ - dimension. */ \ - xmin = (double) lbnd_in[ 0 ] - 0.5; \ - xmax = (double) ubnd_in[ 0 ] + 0.5; \ - ymin = (double) lbnd_in[ 1 ] - 0.5; \ - ymax = (double) ubnd_in[ 1 ] + 0.5; \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,1) \ - } \ - } \ - } \ -\ -/* Another four cases, as above, but this time without the AST__NOBAD \ - flag. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,0) \ - } \ - } \ - } \ - } \ -\ -/* Exit point on error in kernel function */ \ - Kernel_Error_2d: ; \ - } \ -\ -/* Free the workspace. */ \ - kval = astFree( kval ); \ -\ -/* Handle other numbers of dimensions. */ \ -/* ----------------------------------- */ \ - } else { \ -\ -/* Allocate workspace. */ \ - hi = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - lo = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - stride = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - xn_max = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - xn_min = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - kval = astMalloc( sizeof( double ) * (size_t) \ - ( 2 * neighb * ndim_in ) ); \ - wtprod = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - wtptr = astMalloc( sizeof( double * ) * (size_t) ndim_in ); \ - wtptr_last = astMalloc( sizeof( double * ) * (size_t) ndim_in ); \ - if ( astOK ) { \ -\ -/* Calculate the stride along each dimension of the input grid. */ \ - for ( s = 1, idim = 0; idim < ndim_in; idim++ ) { \ - stride[ idim ] = s; \ - s *= ubnd_in[ idim ] - lbnd_in[ idim ] + 1; \ -\ -/* Calculate the coordinate limits of the input grid in each \ - dimension. */ \ - xn_min[ idim ] = (double) lbnd_in[ idim ] - 0.5; \ - xn_max[ idim ] = (double) ubnd_in[ idim ] + 0.5; \ - } \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,1) \ - } \ - } \ - } \ -\ -/* Another 4 cases as above, but this time with the AST__NOBAD flag \ - un-set. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,0) \ - } \ - } \ - } \ - } \ -\ -/* Exit point on error in kernel function */ \ - Kernel_Error_Nd: ;\ - } \ -\ -/* Free the workspace. */ \ - hi = astFree( hi ); \ - lo = astFree( lo ); \ - stride = astFree( stride ); \ - xn_max = astFree( xn_max ); \ - xn_min = astFree( xn_min ); \ - kval = astFree( kval ); \ - wtprod = astFree( wtprod ); \ - wtptr = astFree( wtptr ); \ - wtptr_last = astFree( wtptr_last ); \ - } \ -\ -/* If an error occurred in the kernel function, then report a \ - contextual error message. */ \ - if ( kerror ) { \ - astError( astStatus, "astResample"#X"(%s): Error signalled by " \ - "user-supplied 1-d interpolation kernel.", status, \ - astGetClass( unsimplified_mapping ) ); \ - } \ -\ -/* If an error has occurred, clear the returned result. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the 1-dimensional - case. */ -#define ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,Usebad,Usevar) \ -\ -/* Obtain the x coordinate of the current point and test if it lies \ - outside the input grid, or is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If input bad pixels must be detected, then obtain the offset along \ - the input grid x dimension of the input pixel which contains the \ - current coordinate, and calculate this pixel's offset from the \ - start of the input array. */ \ - if ( Usebad ) { \ - pixel = (int) floor( x + 0.5 ) - lbnd_in[ 0 ]; \ -\ -/* Test if the pixel is bad. */ \ - bad = ( in[ pixel ] == badval ); \ - } \ -\ -/* If OK, calculate the lowest and highest indices (in the x \ - dimension) of the region of neighbouring pixels that will \ - contribute to the interpolated result. Constrain these values to \ - lie within the input grid. */ \ - if ( !bad ) { \ - ix = (int) floor( x ); \ - lo_x = MaxI( ix - neighb + 1, lbnd_in[ 0 ], status ); \ - hi_x = MinI( ix + neighb, ubnd_in[ 0 ], status ); \ -\ -/* Initialise sums for forming the interpolated result. */ \ - sum = (Xfloattype) 0.0; \ - wtsum = (Xfloattype) 0.0; \ - if ( Usevar ) { \ - sum_var = (Xfloattype) 0.0; \ - bad_var = 0; \ - } \ -\ -/* Loop to inspect all the contributing pixels, calculating the offset \ - of each pixel from the start of the input array. */ \ - off_in = lo_x - lbnd_in[ 0 ]; \ - for ( ix = lo_x; ix <= hi_x; ix++, off_in++ ) { \ -\ -/* If necessary, test if the input pixel is bad. If not, calculate its \ - weight by evaluating the kernel function. */ \ - if ( !( Usebad ) || ( in[ off_in ] != badval ) ) { \ - if( kernel ) { \ - ( *kernel )( (double) ix - x, params, flags, &pixwt, status ); \ - } else { \ - ( *fkernel )( (double) ix - x, params, flags, &pixwt ); \ - } \ -\ -/* Check for errors arising in the kernel function. */ \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_Error_1d; \ - } \ -\ -/* Form the weighted sums required for finding the interpolated \ - value. */ \ - sum += ( (Xfloattype) pixwt ) * ( (Xfloattype) in[ off_in ] ); \ - wtsum += (Xfloattype) pixwt; \ -\ -/* If a variance estimate is required and it still seems possible to \ - obtain one, then obtain the variance value associated with the \ - current input pixel. */ \ - if ( Usevar ) { \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - var = in_var[ off_in ]; \ -\ -/* If necessary, test if this value is bad (if the data type is \ - signed, also check that it is not negative). */ \ - if ( Usebad ) bad_var = ( var == badval ); \ - CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ -\ -/* If any bad input variance value is obtained, we cannot generate a \ - valid output variance estimate. Otherwise, form the sum needed to \ - calculate this estimate. */ \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - sum_var += ( (Xfloattype) ( pixwt * pixwt ) ) * \ - ( (Xfloattype) var ); \ - } \ - } \ - } \ - } \ - } \ - } \ - } - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the 2-dimensional - case. */ -#define ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,Usebad,Usevar) \ -\ -/* Obtain the x coordinate of the current point and test if it lies \ - outside the input grid, or is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If not, then similarly obtain and test the y coordinate. */ \ - y = coords[ 1 ][ point ]; \ - bad = ( y < ymin ) || ( y >= ymax ) || ( y == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If input bad pixels must be detected, then obtain the offsets along \ - each input grid dimension of the input pixel which contains the \ - current coordinates, and calculate this pixel's offset from the \ - start of the input array. */ \ - if ( Usebad ) { \ - ix = (int) floor( x + 0.5 ); \ - iy = (int) floor( y + 0.5 ); \ - pixel = ix - lbnd_in[ 0 ] + ystride * ( iy - lbnd_in[ 1 ] ); \ -\ -/* Test if the pixel is bad. */ \ - bad = ( in[ pixel ] == badval ); \ - } \ -\ -/* If OK, calculate the lowest and highest indices (in each dimension) \ - of the region of neighbouring pixels that will contribute to the \ - interpolated result. Constrain these values to lie within the input \ - grid. */ \ - if ( !bad ) { \ - ix = (int) floor( x ); \ - lo_x = MaxI( ix - neighb + 1, lbnd_in[ 0 ], status ); \ - hi_x = MinI( ix + neighb, ubnd_in[ 0 ], status ); \ - iy = (int) floor( y ); \ - lo_y = MaxI( iy - neighb + 1, lbnd_in[ 1 ], status ); \ - hi_y = MinI( iy + neighb, ubnd_in[ 1 ], status ); \ -\ -/* Loop to evaluate the kernel function along the x dimension, storing \ - the resulting values. The function's argument is the offset of the \ - contributing pixel (along this dimension) from the input \ - position. */ \ - for ( ix = lo_x; ix <= hi_x; ix++ ) { \ - if( kernel ) { \ - ( *kernel )( (double) ix - x, params, flags, \ - kval + ix - lo_x, status ); \ - } else { \ - ( *fkernel )( (double) ix - x, params, flags, \ - kval + ix - lo_x ); \ - } \ -\ -/* Check for errors arising in the kernel function. */ \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_Error_2d; \ - } \ - } \ -\ -/* Initialise sums for forming the interpolated result. */ \ - sum = (Xfloattype) 0.0; \ - wtsum = (Xfloattype) 0.0; \ - if ( Usevar ) { \ - sum_var = (Xfloattype) 0.0; \ - bad_var = 0; \ - } \ -\ -/* Loop over the y index to inspect all the contributing pixels, while \ - keeping track of their offset within the input array. Evaluate the \ - kernel function for each y index value. */ \ - off1 = lo_x - lbnd_in[ 0 ] + ystride * ( lo_y - lbnd_in[ 1 ] ); \ - for ( iy = lo_y; iy <= hi_y; iy++, off1 += ystride ) { \ - if( kernel ) { \ - ( *kernel )( (double) iy - y, params, flags, &wt_y, status ); \ - } else { \ - ( *fkernel )( (double) iy - y, params, flags, &wt_y ); \ - } \ -\ -/* Check for errors arising in the kernel function. */ \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_Error_2d; \ - } \ -\ -/* Loop over the x index, calculating the pixel offset in the input \ - array. */ \ - off_in = off1; \ - for ( ix = lo_x; ix <= hi_x; ix++, off_in++ ) { \ -\ -/* If necessary, test if the input pixel is bad. If not, calculate its \ - weight as the product of the kernel function's value for the x and \ - y dimensions. */ \ - if ( !( Usebad ) || ( in[ off_in ] != badval ) ) { \ - pixwt = kval[ ix - lo_x ] * wt_y; \ -\ -/* Form the weighted sums required for finding the interpolated \ - value. */ \ - sum += ( (Xfloattype) pixwt ) * \ - ( (Xfloattype) in[ off_in ] ); \ - wtsum += (Xfloattype) pixwt; \ -\ -/* If a variance estimate is required and it still seems possible to \ - obtain one, then obtain the variance value associated with the \ - current input pixel. */ \ - if ( Usevar ) { \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - var = in_var[ off_in ]; \ -\ -/* If necessary, test if this value is bad (if the data type is \ - signed, also check that it is not negative). */ \ - if ( Usebad ) bad_var = ( var == badval ); \ - CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ -\ -/* If any bad input variance value is obtained, we cannot generate a \ - valid output variance estimate. Otherwise, form the sum needed to \ - calculate this estimate. */ \ - if ( !( ( Xsigned ) || ( Usebad ) ) || \ - !bad_var ) { \ - sum_var += ( (Xfloattype) ( pixwt * pixwt ) ) * \ - ( (Xfloattype) var ); \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } \ - } - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the n-dimensional - case. */ -#define ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,Usebad,Usevar) \ -\ -/* Initialise offsets into the input array. Then loop to obtain each \ - coordinate associated with the current output point. */ \ - pixel = 0; \ - off_in = 0; \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - xn = coords[ idim ][ point ]; \ -\ -/* Test if the coordinate lies outside the input grid, or is bad. If \ - either is true, the corresponding output pixel value will be bad, \ - so give up on this point. */ \ - bad = ( xn < xn_min[ idim ] ) || ( xn >= xn_max[ idim ] ) || \ - ( xn == AST__BAD ); \ - if ( bad ) break; \ -\ -/* If input bad pixels must be detected, then obtain the index along \ - the current input grid dimension of the pixel which contains this \ - coordinate and accumulate the pixel's offset from the start of the \ - input array. */ \ - if ( Usebad ) { \ - pixel += stride[ idim ] * \ - ( (int) floor( xn + 0.5 ) - lbnd_in[ idim ] ); \ - } \ -\ -/* Calculate the lowest and highest indices (in the current dimension) \ - of the region of neighbouring pixels that will contribute to the \ - interpolated result. Constrain these values to lie within the input \ - grid. */ \ - ixn = (int) floor( xn ); \ - lo[ idim ] = MaxI( ixn - neighb + 1, lbnd_in[ idim ], status ); \ - hi[ idim ] = MinI( ixn + neighb, ubnd_in[ idim ], status ); \ -\ -/* Accumulate the offset (from the start of the input array) of the \ - contributing pixel which has the lowest index in each dimension. */ \ - off_in += stride[ idim ] * ( lo[ idim ] - lbnd_in[ idim ] ); \ - } \ -\ -/* Once the input pixel which contains the required coordinates has \ - been identified, test if it is bad, if necessary. */ \ - if ( Usebad ) bad = bad || ( in[ pixel ] == badval ); \ -\ -/* If OK, loop to evaluate the kernel function which will be used to \ - weight the contributions from surrounding pixels. */ \ - if ( !bad ) { \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ -\ -/* Set up an array of pointers to locate kernel values (stored in the \ - "kval" array) for each dimension. Initially, each of these pointers \ - locates the first weight value which applies to the contributing \ - pixel with the lowest index in each dimension. */ \ - wtptr[ idim ] = kval + ( 2 * neighb * idim ); \ -\ -/* Also set up pointers to the last weight value in each dimension. */ \ - wtptr_last[ idim ] = wtptr[ idim ] + ( hi[ idim ] - lo[ idim ] ); \ -\ -/* Loop to evaluate the kernel function along each dimension, storing \ - the resulting values. The function's argument is the offset of the \ - contributing pixel (along the relevant dimension) from the input \ - point. */ \ - xn = coords[ idim ][ point ]; \ - for ( ixn = lo[ idim ]; ixn <= hi[ idim ]; ixn++ ) { \ - if( kernel ) { \ - ( *kernel )( (double) ixn - xn, params, flags, \ - wtptr[ idim ] + ixn - lo[ idim ], status ); \ - } else { \ - ( *fkernel )( (double) ixn - xn, params, flags, \ - wtptr[ idim ] + ixn - lo[ idim ] ); \ - } \ -\ -/* Check for errors arising in the kernel function. */ \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_Error_Nd; \ - } \ - } \ - } \ -\ -/* Initialise, and loop over the neighbouring input pixels to obtain \ - an interpolated value. */ \ - sum = (Xfloattype) 0.0; \ - wtsum = (Xfloattype) 0.0; \ - if ( Usevar ) { \ - sum_var = (Xfloattype) 0.0; \ - bad_var = 0; \ - } \ - idim = ndim_in - 1; \ - wtprod[ idim ] = 1.0; \ - done = 0; \ - do { \ -\ -/* Each contributing pixel is weighted by the product of the kernel \ - weight factors evaluated along each input dimension. However, since \ - we typically only change the index of one dimension at a time, we \ - can avoid forming this product repeatedly by retaining an array of \ - accumulated products for all higher dimensions. We need then only \ - update the lower elements in this array, corresponding to those \ - dimensions whose index has changed. We do this here, "idim" being \ - the index of the most significant dimension to have changed. Note \ - that on the first pass, all dimensions are considered changed, \ - causing this array to be initialised. */ \ - for ( ii = idim; ii >= 1; ii-- ) { \ - wtprod[ ii - 1 ] = wtprod[ ii ] * *( wtptr[ ii ] ); \ - } \ -\ -/* If necessary, test each pixel which may contribute to the result to \ - see if it is bad. If not, obtain its weight from the accumulated \ - product of weights. Also multiply by the weight for dimension zero, \ - which is not included in the "wtprod" array). */ \ - if ( !( Usebad ) || ( in[ off_in ] != badval ) ) { \ - pixwt = wtprod[ 0 ] * *( wtptr[ 0 ] ); \ -\ -/* Form the weighted sums required for finding the interpolated \ - value. */ \ - sum += ( (Xfloattype) pixwt ) * ( (Xfloattype) in[ off_in ] ); \ - wtsum += (Xfloattype) pixwt; \ -\ -/* If a variance estimate is required and it still seems possible to \ - obtain one, then obtain the variance value associated with the \ - current input pixel. */ \ - if ( Usevar ) { \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - var = in_var[ off_in ]; \ -\ -/* If necessary, test if this value is bad (if the data type is \ - signed, also check that it is not negative). */ \ - if ( Usebad ) bad_var = ( var == badval ); \ - CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ -\ -/* If any bad input variance value is obtained, we cannot generate a \ - valid output variance estimate. Otherwise, form the sum needed to \ - calculate this estimate. */ \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - sum_var += ( (Xfloattype) ( pixwt * pixwt ) ) * \ - ( (Xfloattype) var ); \ - } \ - } \ - } \ - } \ -\ -/* Now update the weight value pointers and pixel offset to refer to \ - the next input pixel to be considered. */ \ - idim = 0; \ - do { \ -\ -/* The first input dimension whose weight value pointer has not yet \ - reached its final value has this pointer incremented, and the pixel \ - offset into the input array is updated accordingly. */ \ - if ( wtptr[ idim ] != wtptr_last[ idim ] ) { \ - wtptr[ idim ]++; \ - off_in += stride[ idim ]; \ - break; \ -\ -/* Any earlier dimensions (which have reached the final pointer value) \ - have this pointer returned to its lowest value. Again, the pixel \ - offset into the input image is updated accordingly. */ \ - } else { \ - wtptr[ idim ] -= ( hi[ idim ] - lo[ idim ] ); \ - off_in -= stride[ idim ] * \ - ( hi[ idim ] - lo[ idim ] ); \ - done = ( ++idim == ndim_in ); \ - } \ - } while ( !done ); \ - } while ( !done ); \ - } - -/* This subsidiary macro calculates the interpolated output value (and - variance) from the sums over contributing pixels, checks the - results for validity, and assigns them to the output array(s). */ -#define CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Usebad,Usevar,Nobad) \ -\ -/* If the output data value has not yet been flagged as bad, then \ - check that an interpolated value can actually be produced. First \ - check that the sum of weights is not zero. */ \ - if ( !bad ) { \ - bad = ( wtsum == (Xfloattype) 0.0 ); \ -\ -/* If OK, calculate the interpolated value. Then, if the output data \ - type is not floating point, check that this value will not overflow \ - the available output range. */ \ - if ( !bad ) { \ - val = sum / wtsum; \ - if ( !( Xfloating ) ) { \ - bad = ( val <= lo_lim ) || ( val >= hi_lim ); \ - } \ - } \ -\ -/* If no interpolated data value can be produced, then no associated \ - variance will be required either. */ \ - if ( ( Usevar ) && bad ) bad_var = 1; \ - } \ -\ -/* Now perform similar checks on the output variance value (if \ - required). This time we check that the square of the sum of \ - weights is not zero (since this might underflow before the sum of \ - weights). Again we also check to prevent the result overflowing the \ - output data type. */ \ - if ( ( Usevar ) && !bad_var ) { \ - wtsum_sq = wtsum * wtsum; \ - bad_var = ( wtsum_sq == (Xfloattype) 0.0 ); \ - if ( !bad_var ) { \ - val_var = sum_var / wtsum_sq; \ - if ( !( Xfloating ) ) { \ - bad_var = ( val_var <= lo_lim ) || ( val_var >= hi_lim ); \ - } \ - } \ - } \ -\ -/* Obtain the pixel offset into the output array. */ \ - off_out = offset[ point ]; \ -\ -/* Assign a bad output value (and variance) if required and count it. */ \ - if ( bad ) { \ - if( !Nobad ) { \ - out[ off_out ] = badval; \ - if ( Usevar ) out_var[ off_out ] = badval; \ - } \ - result++; \ -\ -/* Otherwise, assign the interpolated value. If the output data type \ - is floating point, the result can be stored directly, otherwise we \ - must round to the nearest integer. */ \ - } else { \ - if ( Xfloating ) { \ - out[ off_out ] = (Xtype) val; \ - } else { \ - out[ off_out ] = (Xtype) ( val + ( ( val >= (Xfloattype) 0.0 ) ? \ - ( (Xfloattype) 0.5 ) : \ - ( (Xfloattype) -0.5 ) ) ); \ - } \ -\ -/* If a variance estimate is required but none can be obtained, then \ - store a bad output variance value and count it. */ \ - if ( Usevar ) { \ - if ( bad_var ) { \ - if( !Nobad ) { \ - out_var[ off_out ] = badval; \ - } \ - result++; \ -\ -/* Otherwise, store the variance estimate, rounding to the nearest \ - integer if necessary. */ \ - } else { \ - if ( Xfloating ) { \ - out_var[ off_out ] = (Xtype) val_var; \ - } else { \ - out_var[ off_out ] = (Xtype) ( val_var + \ - ( ( val_var >= (Xfloattype) 0.0 ) ? \ - ( (Xfloattype) 0.5 ) : \ - ( (Xfloattype) -0.5 ) ) ); \ - } \ - } \ - } \ - } - -/* These subsidiary macros define limits for range checking of results - before conversion to the final data type. For each data type code - , HI_ gives the least positive floating point value which - just overflows that data type towards plus infinity, while LO_ - gives the least negative floating point value which just overflows - that data type towards minus infinity. Thus, a floating point value - must satisfy LO is a floating point type, the limits are not actually used, - but must be present to permit error-free compilation. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#define HI_LD ( 0.0L ) -#define LO_LD ( 0.0L ) -#endif -#define HI_D ( 0.0 ) -#define LO_D ( 0.0 ) -#define HI_F ( 0.0f ) -#define LO_F ( 0.0f ) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#define HI_K ( 0.5L + (long double) LONG_MAX ) -#define LO_K ( -0.5L + (long double) LONG_MIN ) -#define HI_UK ( 0.5L + (long double) ULONG_MAX ) -#define LO_UK ( -0.5L ) -#define HI_L ( 0.5L + (long double) LONG_MAX ) -#define LO_L ( -0.5L + (long double) LONG_MIN ) -#define HI_UL ( 0.5L + (long double) ULONG_MAX ) -#define LO_UL ( -0.5L ) -#else -#define HI_K ( 0.5 + (double) LONG_MAX ) -#define LO_K ( -0.5 + (double) LONG_MIN ) -#define HI_UK ( 0.5 + (double) ULONG_MAX ) -#define LO_UK ( -0.5 ) -#define HI_L ( 0.5 + (double) LONG_MAX ) -#define LO_L ( -0.5 + (double) LONG_MIN ) -#define HI_UL ( 0.5 + (double) ULONG_MAX ) -#define LO_UL ( -0.5 ) -#endif - -#define HI_I ( 0.5 + (double) INT_MAX ) -#define LO_I ( -0.5 + (double) INT_MIN ) -#define HI_UI ( 0.5 + (double) UINT_MAX ) -#define LO_UI ( -0.5 ) -#define HI_S ( 0.5f + (float) SHRT_MAX ) -#define LO_S ( -0.5f + (float) SHRT_MIN ) -#define HI_US ( 0.5f + (float) USHRT_MAX ) -#define LO_US ( -0.5f ) -#define HI_B ( 0.5f + (float) SCHAR_MAX ) -#define LO_B ( -0.5f + (float) SCHAR_MIN ) -#define HI_UB ( 0.5f + (float) UCHAR_MAX ) -#define LO_UB ( -0.5f ) - -/* This subsidiary macro tests for negative variance values. This - check is required only for signed data types. */ -#define CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ - bad_var = bad_var || ( var < ( (Xtype) 0 ) ); - -/* Expand the main macro above to generate a function for each - required signed data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_INTERPOLATE_KERNEL1(LD,long double,1,long double,1) -MAKE_INTERPOLATE_KERNEL1(L,long int,0,long double,1) -MAKE_INTERPOLATE_KERNEL1(K,INT_BIG,0,long double,1) -#else -MAKE_INTERPOLATE_KERNEL1(L,long int,0,double,1) -MAKE_INTERPOLATE_KERNEL1(K,INT_BIG,0,double,1) -#endif -MAKE_INTERPOLATE_KERNEL1(D,double,1,double,1) -MAKE_INTERPOLATE_KERNEL1(F,float,1,float,1) -MAKE_INTERPOLATE_KERNEL1(I,int,0,double,1) -MAKE_INTERPOLATE_KERNEL1(S,short int,0,float,1) -MAKE_INTERPOLATE_KERNEL1(B,signed char,0,float,1) - -/* Re-define the macro for testing for negative variances to do - nothing. */ -#undef CHECK_FOR_NEGATIVE_VARIANCE -#define CHECK_FOR_NEGATIVE_VARIANCE(Xtype) - -/* Expand the main macro above to generate a function for each - required unsigned data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_INTERPOLATE_KERNEL1(UL,unsigned long int,0,long double,0) -MAKE_INTERPOLATE_KERNEL1(UK,UINT_BIG,0,long double,0) -#else -MAKE_INTERPOLATE_KERNEL1(UL,unsigned long int,0,double,0) -MAKE_INTERPOLATE_KERNEL1(UK,UINT_BIG,0,double,0) -#endif -MAKE_INTERPOLATE_KERNEL1(UI,unsigned int,0,double,0) -MAKE_INTERPOLATE_KERNEL1(US,unsigned short int,0,float,0) -MAKE_INTERPOLATE_KERNEL1(UB,unsigned char,0,float,0) - -/* Undefine the macros used above. */ -#undef CHECK_FOR_NEGATIVE_VARIANCE -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#undef HI_LD -#undef LO_LD -#endif -#undef HI_D -#undef LO_D -#undef HI_F -#undef LO_F -#undef HI_L -#undef LO_L -#undef HI_UL -#undef LO_UL -#undef HI_K -#undef LO_K -#undef HI_UK -#undef LO_UK -#undef HI_I -#undef LO_I -#undef HI_UI -#undef LO_UI -#undef HI_S -#undef LO_S -#undef HI_US -#undef LO_US -#undef HI_B -#undef LO_B -#undef HI_UB -#undef LO_UB -#undef CALC_AND_ASSIGN_OUTPUT -#undef ASSEMBLE_INPUT_ND -#undef ASSEMBLE_INPUT_2D -#undef ASSEMBLE_INPUT_1D -#undef MAKE_INTERPOLATE_KERNEL1 - -/* -* Name: -* InterpolateLinear - -* Purpose: -* Resample a data grid, using the linear interpolation scheme. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int InterpolateLinear( int ndim_in, -* const int *lbnd_in, const int *ubnd_in, -* const *in, const *in_var, -* int npoint, const int *offset, -* const double *const *coords, -* int flags, badval, -* *out, *out_var ) - -* Class Membership: -* Mapping member function. - -* Description: -* This is a set of functions which resample a rectangular input -* grid of data (and, optionally, associated statistical variance -* values) so as to place them into a new output grid. Each output -* grid point may be mapped on to a position in the input grid in -* an arbitrary way. Where the positions given do not correspond -* with a pixel centre in the input grid, the interpolation scheme -* used is linear interpolation between the centres of the nearest -* neighbouring pixels in each dimension (there are 2 nearest -* neighbours in 1 dimension, 4 in 2 dimensions, 8 in 3 dimensions, -* etc.). - -* Parameters: -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input grid, its extent along a particular -* (i'th) dimension being ubnd_in[i]-lbnd_in[i]+1 (assuming "i" -* is zero-based). They also define the input grid's coordinate -* system, with each pixel being of unit extent along each -* dimension with integral coordinate values at its centre. -* in -* Pointer to the array of data to be resampled (with an element -* for each pixel in the input grid). The numerical type of -* these data should match the function used, as given by the -* suffix on the function name. The storage order should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -* (i.e. Fortran array storage order). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and type as the "in" array), which -* represent estimates of the statistical variance associated -* with each element of the "in" array. If this second array is -* given (along with the corresponding "out_var" array), then -* estimates of the variance of the resampled data will also be -* returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* npoint -* The number of points at which the input grid is to be -* resampled. -* offset -* Pointer to an array of integers with "npoint" elements. For -* each output point, this array should contain the zero-based -* offset in the output array(s) (i.e. the "out" and, -* optionally, the "out_var" arrays) at which the resampled -* output value(s) should be stored. -* coords -* An array of pointers to double, with "ndim_in" -* elements. Element "coords[coord]" should point at the first -* element of an array of double (with "npoint" elements) which -* contains the values of coordinate number "coord" for each -* interpolation point. The value of coordinate number "coord" -* for interpolation point number "point" is therefore given by -* "coords[coord][point]" (assuming both indices to be -* zero-based). If any point has a coordinate value of AST__BAD -* associated with it, then the corresponding output data (and -* variance) will be set to the value given by "badval" (unles the -* AST__NOBAD flag is specified). -* flags -* The bitwise OR of a set of flag values which control the -* operation of the function. Currently, only the flag -* AST__USEBAD is significant and indicates whether there are -* "bad" (i.e. missing) data in the input array(s) which must be -* recognised and propagated to the output array(s). If this -* flag is not set, all input values are treated literally. -* badval -* If the AST__USEBAD flag is set in the "flags" value (above), -* this parameter specifies the value which is used to identify -* bad data and/or variance values in the input array(s). Its -* numerical type must match that of the "in" (and "in_var") -* arrays. Unles the AST__NOBAD flag is specified in "flags", the -* same value will also be used to flag any output array elements -* for which resampled values could not be obtained. The output -* arrays(s) may be flagged with this value whether or not the -* AST__USEBAD flag is set (the function return value indicates -* whether any such values have been produced). -* out -* Pointer to an array with the same data type as the "in" -* array, into which the resampled data will be returned. Note -* that details of how the output grid maps on to this array -* (e.g. the storage order, number of dimensions, etc.) is -* arbitrary and is specified entirely by means of the "offset" -* array. The "out" array should therefore contain sufficient -* elements to accommodate the "offset" values supplied. There -* is no requirement that all elements of the "out" array should -* be assigned values, and any which are not addressed by the -* contents of the "offset" array will be left unchanged. -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the resampled values may be returned. This array will only be -* used if the "in_var" array has been given. It is addressed in -* exactly the same way (via the "offset" array) as the "out" -* array. The values returned are estimates of the statistical -* variance of the corresponding values in the "out" array, on -* the assumption that all errors in input grid values (in the -* "in" array) are statistically independent and that their -* variance estimates (in the "in_var" array) may simply be -* summed (with appropriate weighting factors). -* -* If no output variance estimates are required, a NULL pointer -* should be given. - -* Returned Value: -* The number of output grid points to which a data value (or a -* variance value if relevant) equal to "badval" has been assigned -* because no valid output value could be obtained. - -* Notes: -* - There is a separate function for each numerical type of -* gridded data, distinguished by replacing the in the function -* name by the appropriate 1- or 2-character suffix. -* - A value of zero will be returned if any of these functions is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ -/* Define macros to implement the function for a specific data - type. */ -#define MAKE_INTERPOLATE_LINEAR(X,Xtype,Xfloating,Xfloattype,Xsigned) \ -static int InterpolateLinear##X( int ndim_in, \ - const int *lbnd_in, const int *ubnd_in, \ - const Xtype *in, const Xtype *in_var, \ - int npoint, const int *offset, \ - const double *const *coords, \ - int flags, Xtype badval, \ - Xtype *out, Xtype *out_var, int *status ) { \ -\ -/* Local Variables: */ \ - Xfloattype sum; /* Weighted sum of pixel data values */ \ - Xfloattype sum_var; /* Weighted sum of pixel variance values */ \ - Xfloattype val; /* Value to be asigned to output pixel */ \ - Xfloattype wtsum; /* Sum of weight values */ \ - Xtype var; /* Variance value */ \ - double *frac_hi; /* Pointer to array of weights */ \ - double *frac_lo; /* Pointer to array of weights */ \ - double *wt; /* Pointer to array of weights */ \ - double *wtprod; /* Array of accumulated weights pointer */ \ - double *xn_max; /* Pointer to upper limits array (n-d) */ \ - double *xn_min; /* Pointer to lower limits array (n-d) */ \ - double frac_hi_x; /* Pixel weight (x dimension) */ \ - double frac_hi_y; /* Pixel weight (y dimension) */ \ - double frac_lo_x; /* Pixel weight (x dimension) */ \ - double frac_lo_y; /* Pixel weight (y dimension) */ \ - double pixwt; /* Weight to apply to individual pixel */ \ - double x; /* x coordinate value */ \ - double xmax; /* x upper limit */ \ - double xmin; /* x lower limit */ \ - double xn; /* Coordinate value (n-d) */ \ - double y; /* y coordinate value */ \ - double ymax; /* y upper limit */ \ - double ymin; /* y lower limit */ \ - int *dim; /* Pointer to array of pixel indices */ \ - int *hi; /* Pointer to array of upper indices */ \ - int *lo; /* Pointer to array of lower indices */ \ - int *stride; /* Pointer to array of dimension strides */ \ - int bad; /* Output pixel bad? */ \ - int bad_var; /* Output variance bad? */ \ - int done; /* All pixel indices done? */ \ - int hi_x; /* Upper pixel index (x dimension) */ \ - int hi_y; /* Upper pixel index (y dimension) */ \ - int idim; /* Loop counter for dimensions */ \ - int ii; /* Loop counter for weights */ \ - int ix; /* Pixel index in input grid x dimension */ \ - int ixn; /* Pixel index (n-d) */ \ - int iy; /* Pixel index in input grid y dimension */ \ - int lo_x; /* Lower pixel index (x dimension) */ \ - int lo_y; /* Lower pixel index (y dimension) */ \ - int nobad; /* Was the AST__NOBAD flag set? */ \ - int off_in; /* Offset to input pixel */ \ - int off_lo; /* Offset to "first" input pixel */ \ - int off_out; /* Offset to output pixel */ \ - int pixel; /* Offset to input pixel containing point */ \ - int point; /* Loop counter for output points */ \ - int result; /* Result value to return */ \ - int s; /* Temporary variable for strides */ \ - int usebad; /* Use "bad" input pixel values? */ \ - int usevar; /* Process variance array? */ \ - int ystride; /* Stride along input grid y dimension */ \ -\ -/* Initialise. */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Initialise variables to avoid "used of uninitialised variable" \ - messages from dumb compilers. */ \ - sum = 0; \ - sum_var = 0; \ - wtsum = 0; \ - bad = 0; \ - bad_var = 0; \ -\ -/* Determine if we are processing bad pixels or variances. */ \ - nobad = flags & AST__NOBAD; \ - usebad = flags & AST__USEBAD; \ - usevar = in_var && out_var; \ -\ -/* Handle the 1-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - if ( ndim_in == 1 ) { \ -\ -/* Calculate the coordinate limits of the input grid. */ \ - xmin = (double) lbnd_in[ 0 ] - 0.5; \ - xmax = (double) ubnd_in[ 0 ] + 0.5; \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 0,0,1) \ - } \ - } \ - } \ -\ -/* Four more cases as above, but this time with the AST__NOBAD flag \ - un-set. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 0,0,0) \ - } \ - } \ - } \ - } \ -\ -/* Handle the 2-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - } else if ( ndim_in == 2 ) { \ -\ -/* Calculate the stride along the y dimension of the input grid. */ \ - ystride = ubnd_in[ 0 ] - lbnd_in[ 0 ] + 1; \ -\ -/* Calculate the coordinate limits of the input grid in each \ - dimension. */ \ - xmin = (double) lbnd_in[ 0 ] - 0.5; \ - xmax = (double) ubnd_in[ 0 ] + 0.5; \ - ymin = (double) lbnd_in[ 1 ] - 0.5; \ - ymax = (double) ubnd_in[ 1 ] + 0.5; \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 0,0,1) \ - } \ - } \ - } \ -\ -/* Four more case as above, but without the AST__NOBAD flag. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - 0,0,0) \ - } \ - } \ - } \ - } \ -\ -/* Handle other numbers of dimensions. */ \ -/* ----------------------------------- */ \ - } else { \ -\ -/* Allocate workspace. */ \ - dim = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - frac_hi = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - frac_lo = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - hi = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - lo = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - stride = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - wt = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - wtprod = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - xn_max = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - xn_min = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - if ( astOK ) { \ -\ -/* Calculate the stride along each dimension of the input grid. */ \ - for ( s = 1, idim = 0; idim < ndim_in; idim++ ) { \ - stride[ idim ] = s; \ - s *= ubnd_in[ idim ] - lbnd_in[ idim ] + 1; \ -\ -/* Calculate the coordinate limits of the input grid in each \ - dimension. */ \ - xn_min[ idim ] = (double) lbnd_in[ idim ] - 0.5; \ - xn_max[ idim ] = (double) ubnd_in[ idim ] + 0.5; \ - } \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype, \ - Xsigned,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype, \ - Xsigned,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype, \ - Xsigned,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype, \ - Xsigned,0,0,1) \ - } \ - } \ - } \ -\ -/* Four more case as above, but without the AST__NOBAD flag. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype, \ - Xsigned,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype, \ - Xsigned,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype, \ - Xsigned,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype, \ - Xsigned,0,0,0) \ - } \ - } \ - } \ - } \ - } \ -\ -/* Free the workspace. */ \ - dim = astFree( dim ); \ - frac_hi = astFree( frac_hi ); \ - frac_lo = astFree( frac_lo ); \ - hi = astFree( hi ); \ - lo = astFree( lo ); \ - stride = astFree( stride ); \ - wt = astFree( wt ); \ - wtprod = astFree( wtprod ); \ - xn_max = astFree( xn_max ); \ - xn_min = astFree( xn_min ); \ - } \ -\ -/* If an error has occurred, clear the returned result. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the 1-dimensional - case. */ -#define ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,Usebad,Usevar) \ -\ -/* Obtain the x coordinate of the current point and test if it lies \ - outside the input grid. Also test if it is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If input bad pixels must be detected, then obtain the offset along \ - the input grid x dimension of the input pixel which contains the \ - current coordinate and calculate this pixel's offset from the start \ - of the input array. */ \ - if ( Usebad ) { \ - pixel = (int) floor( x + 0.5 ) - lbnd_in[ 0 ]; \ -\ -/* Test if the pixel is bad. */ \ - bad = ( in[ pixel ] == badval ); \ - } \ -\ -/* If OK, obtain the indices along the input grid x dimension of the \ - two adjacent pixels which will contribute to the interpolated \ - result. Also obtain the fractional weight to be applied to each of \ - these pixels. */ \ - if ( !bad ) { \ - lo_x = (int) floor( x ); \ - hi_x = lo_x + 1; \ - frac_lo_x = (double) hi_x - x; \ - frac_hi_x = 1.0 - frac_lo_x; \ -\ -/* Obtain the offset within the input array of the first pixel to be \ - used for interpolation (the one with the smaller index). */ \ - off_lo = lo_x - lbnd_in[ 0 ]; \ -\ -/* Initialise sums for forming the interpolated result. */ \ - sum = (Xfloattype) 0.0; \ - wtsum = (Xfloattype) 0.0; \ - if ( Usevar ) { \ - sum_var = (Xfloattype) 0.0; \ - if ( ( Xsigned ) || ( Usebad ) ) bad_var = 0; \ - } \ -\ -/* For each of the two pixels which may contribute to the result, \ - test if the pixel index lies within the input grid. Where it does, \ - accumulate the sums required for forming the interpolated \ - result. In each case, we supply the pixel's offset within the input \ - array and the weight to be applied to it. */ \ - if ( lo_x >= lbnd_in[ 0 ] ) { \ - FORM_LINEAR_INTERPOLATION_SUM(off_lo,frac_lo_x,Xtype, \ - Xfloattype,Xsigned,Usebad,Usevar) \ - } \ - if ( hi_x <= ubnd_in[ 0 ] ) { \ - FORM_LINEAR_INTERPOLATION_SUM(off_lo + 1,frac_hi_x,Xtype, \ - Xfloattype,Xsigned,Usebad,Usevar) \ - } \ - } \ - } - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the 2-dimensional - case. */ -#define ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,Usebad,Usevar) \ -\ -/* Obtain the x coordinate of the current point and test if it lies \ - outside the input grid. Also test if it is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If OK, then similarly obtain and test the y coordinate. */ \ - y = coords[ 1 ][ point ]; \ - bad = ( y < ymin ) || ( y >= ymax ) || ( y == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If input bad pixels must be detected, then obtain the offsets along \ - each input grid dimension of the input pixel which contains the \ - current coordinates. */ \ - if ( Usebad ) { \ - ix = (int) floor( x + 0.5 ); \ - iy = (int) floor( y + 0.5 ); \ -\ -/* Calculate this pixel's offset from the start of the input array. */ \ - pixel = ix - lbnd_in[ 0 ] + ystride * ( iy - lbnd_in[ 1 ] ); \ -\ -/* Test if the pixel is bad. */ \ - bad = ( in[ pixel ] == badval ); \ - } \ -\ -/* If OK, obtain the indices along the input grid x dimension of the \ - two adjacent pixels which will contribute to the interpolated \ - result. Also obtain the fractional weight to be applied to each of \ - these pixels. */ \ - if ( !bad ) { \ - lo_x = (int) floor( x ); \ - hi_x = lo_x + 1; \ - frac_lo_x = (double) hi_x - x; \ - frac_hi_x = 1.0 - frac_lo_x; \ -\ -/* Repeat this process for the y dimension. */ \ - lo_y = (int) floor( y ); \ - hi_y = lo_y + 1; \ - frac_lo_y = (double) hi_y - y; \ - frac_hi_y = 1.0 - frac_lo_y; \ -\ -/* Obtain the offset within the input array of the first pixel to be \ - used for interpolation (the one with the smaller index along both \ - dimensions). */ \ - off_lo = lo_x - lbnd_in[ 0 ] + ystride * ( lo_y - lbnd_in[ 1 ] ); \ -\ -/* Initialise sums for forming the interpolated result. */ \ - sum = (Xfloattype) 0.0; \ - wtsum = (Xfloattype) 0.0; \ - if ( Usevar ) { \ - sum_var = (Xfloattype) 0.0; \ - if ( ( Xsigned ) || ( Usebad ) ) bad_var = 0; \ - } \ -\ -/* For each of the four pixels which may contribute to the result, \ - test if the pixel indices lie within the input grid. Where they do, \ - accumulate the sums required for forming the interpolated \ - result. In each case, we supply the pixel's offset within the input \ - array and the weight to be applied to it. */ \ - if ( lo_y >= lbnd_in[ 1 ] ) { \ - if ( lo_x >= lbnd_in[ 0 ] ) { \ - FORM_LINEAR_INTERPOLATION_SUM(off_lo, \ - frac_lo_x * frac_lo_y,Xtype, \ - Xfloattype, Xsigned, \ - Usebad,Usevar) \ - } \ - if ( hi_x <= ubnd_in[ 0 ] ) { \ - FORM_LINEAR_INTERPOLATION_SUM(off_lo + 1, \ - frac_hi_x * frac_lo_y,Xtype, \ - Xfloattype,Xsigned, \ - Usebad,Usevar) \ - } \ - } \ - if ( hi_y <= ubnd_in[ 1 ] ) { \ - if ( lo_x >= lbnd_in[ 0 ] ) { \ - FORM_LINEAR_INTERPOLATION_SUM(off_lo + ystride, \ - frac_lo_x * frac_hi_y,Xtype, \ - Xfloattype,Xsigned, \ - Usebad,Usevar) \ - } \ - if ( hi_x <= ubnd_in[ 0 ] ) { \ - FORM_LINEAR_INTERPOLATION_SUM(off_lo + ystride + 1, \ - frac_hi_x * frac_hi_y,Xtype, \ - Xfloattype,Xsigned, \ - Usebad,Usevar) \ - } \ - } \ - } \ - } \ - } - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the n-dimensional - case. */ -#define ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,Usebad,Usevar) \ -\ -/* Initialise offsets into the input array. Then loop to obtain each - coordinate associated with the current output point. */ \ - off_in = 0; \ - if ( Usebad ) pixel = 0; \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - xn = coords[ idim ][ point ]; \ -\ -/* Test if the coordinate lies outside the input grid. Also test if \ - it is bad. If either is true, the corresponding output pixel value \ - will be bad, so give up on this point. */ \ - bad = ( xn < xn_min[ idim ] ) || ( xn >= xn_max[ idim ] ) || \ - ( xn == AST__BAD ); \ - if ( bad ) break; \ -\ -/* If input bad pixels must be detected, obtain the index along the \ - current input grid dimension of the pixel which contains this \ - coordinate and accumulate the pixel's offset from the start of the \ - input array. */ \ - if ( Usebad ) { \ - pixel += stride[ idim ] * \ - ( (int) floor( xn + 0.5 ) - lbnd_in[ idim ] ); \ - } \ -\ -/* Obtain the indices along the current dimension of the input grid of \ - the two (usually adjacent) pixels which will contribute to the \ - output value. If necessary, however, restrict each index to ensure \ - it does not lie outside the input grid. Also calculate the \ - fractional weight to be given to each pixel in order to interpolate \ - linearly between them. */ \ - ixn = (int) floor( xn ); \ - lo[ idim ] = MaxI( ixn, lbnd_in[ idim ], status ); \ - hi[ idim ] = MinI( ixn + 1, ubnd_in[ idim ], status ); \ - frac_lo[ idim ] = 1.0 - fabs( xn - (double) lo[ idim ] ); \ - frac_hi[ idim ] = 1.0 - fabs( xn - (double) hi[ idim ] ); \ -\ -/* Store the lower index involved in interpolation along each \ - dimension and accumulate the offset from the start of the input \ - array of the pixel which has these indices. */ \ - dim[ idim ] = lo[ idim ]; \ - off_in += stride[ idim ] * ( lo[ idim ] - lbnd_in[ idim ] ); \ -\ -/* Also store the fractional weight associated with the lower pixel \ - along each dimension. */ \ - wt[ idim ] = frac_lo[ idim ]; \ - } \ -\ -/* If the input pixel which contains the required coordinates has \ - been identified, test if it is bad. */ \ - if ( Usebad ) bad = bad || ( in[ pixel ] == badval ); \ -\ -/* If OK, initialise and loop over adjacent input pixels to obtain an \ - interpolated value. */ \ - if ( !bad ) { \ - sum = (Xfloattype) 0.0; \ - wtsum = (Xfloattype) 0.0; \ - if ( Usevar ) { \ - sum_var = (Xfloattype) 0.0; \ - if ( ( Xsigned ) || ( Usebad ) ) bad_var = 0; \ - } \ - idim = ndim_in - 1; \ - wtprod[ idim ] = 1.0; \ - done = 0; \ - do { \ -\ -/* Each contributing pixel is weighted by the product of the weights \ - which account for the displacement of its centre from the required \ - position along each dimension. However, since we typically only \ - change the index of one dimension at a time, we can avoid forming \ - this product repeatedly by retaining an array of accumulated weight \ - products for all higher dimensions. We need then only update the \ - lower elements in this array, corresponding to those dimensions \ - whose index has changed. We do this here, "idim" being the index of \ - the most significant dimension to have changed. Note that on the \ - first pass, all dimensions are considered changed, causing this \ - array to be initialised. */ \ - for ( ii = idim; ii >= 1; ii-- ) { \ - wtprod[ ii - 1 ] = wtprod[ ii ] * wt[ ii ]; \ - } \ -\ -/* Accumulate the sums required for forming the interpolated \ - result. We supply the pixel's offset within the input array and the \ - weight to be applied to it. The pixel weight is formed by including \ - the weight factor for dimension zero, since this is not included in \ - the "wtprod" array. */ \ - FORM_LINEAR_INTERPOLATION_SUM(off_in,wtprod[ 0 ] * wt[ 0 ], \ - Xtype,Xfloattype,Xsigned, \ - Usebad,Usevar) \ -\ -/* Now update the indices, offset and weight factors to refer to the \ - next input pixel to be considered. */ \ - idim = 0; \ - do { \ -\ -/* The first input dimension which still refers to the pixel with the \ - lower of the two possible indices is switched to refer to the other \ - pixel (with the higher index). The offset into the input array and \ - the fractional weight factor for this dimension are also updated \ - accordingly. */ \ - if ( dim[ idim ] != hi[ idim ] ) { \ - dim[ idim ] = hi[ idim ]; \ - off_in += stride[ idim ]; \ - wt[ idim ] = frac_hi[ idim ]; \ - break; \ -\ -/* Any earlier dimensions (referring to the higher index) are switched \ - back to the lower index, if not already there, before going on to \ - consider the next dimension. (This process is the same as \ - incrementing a binary number and propagating overflows up through \ - successive digits, except that dimensions where the "lo" and "hi" \ - values are the same can only take one value.) The process stops at \ - the first attempt to return the final dimension to the lower \ - index. */ \ - } else { \ - if ( dim[ idim ] != lo[ idim ] ) { \ - dim[ idim ] = lo[ idim ]; \ - off_in -= stride[ idim ]; \ - wt[ idim ] = frac_lo[ idim ]; \ - } \ - done = ( ++idim == ndim_in ); \ - } \ - } while ( !done ); \ - } while ( !done ); \ - } - -/* This subsidiary macro adds the contribution from a specified input - pixel to the accumulated sums for forming the linearly interpolated - value. */ -#define FORM_LINEAR_INTERPOLATION_SUM(off,wt,Xtype,Xfloattype,Xsigned, \ - Usebad,Usevar) \ -\ -/* Obtain the offset of the input pixel to use. */ \ - off_in = ( off ); \ -\ -/* If necessary, test if this pixel is bad. If not, then obtain the \ - weight to apply to it. */ \ - if ( !( Usebad ) || ( in[ off_in ] != badval ) ) { \ - pixwt = ( wt ); \ -\ -/* Increment the weighted sum of pixel values and the sum of weights. */ \ - sum += ( (Xfloattype) in[ off_in ] ) * ( (Xfloattype) pixwt ); \ - wtsum += (Xfloattype) pixwt; \ -\ -/* If an output variance estimate is to be generated, and it still \ - seems possible to produce one, then obtain the input variance \ - value. */ \ - if ( Usevar ) { \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - var = in_var[ off_in ]; \ -\ -/* Test if the variance value is bad (if the data type is signed, also \ - check that it is not negative). */ \ - if ( Usebad ) bad_var = ( var == badval ); \ - CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ -\ -/* If OK, increment the weighted sum of variance values. */ \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - sum_var += ( (Xfloattype) ( pixwt * pixwt ) ) * \ - ( (Xfloattype) var ); \ - } \ - } \ - } \ - } - -/* This subsidiary macro calculates the interpolated output value (and - variance) from the sums over contributing pixels and assigns them - to the output array(s). */ -#define CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Xsigned, \ - Usebad,Usevar,Nobad) \ -\ -/* Obtain the pixel offset into the output array. */ \ - off_out = offset[ point ]; \ -\ -/* Assign a bad output value (and variance) if required and count it. */ \ - if ( bad ) { \ - if( !Nobad ) { \ - out[ off_out ] = badval; \ - if ( Usevar ) out_var[ off_out ] = badval; \ - } \ - result++; \ -\ -/* Otherwise, calculate the interpolated value. If the output data \ - type is floating point, this result can be stored directly, \ - otherwise we must round to the nearest integer. */ \ - } else { \ - val = sum / wtsum; \ - if ( Xfloating ) { \ - out[ off_out ] = (Xtype) val; \ - } else { \ - out[ off_out ] = (Xtype) ( val + ( ( val >= (Xfloattype) 0.0 ) ? \ - ( (Xfloattype) 0.5 ) : \ - ( (Xfloattype) -0.5 ) ) ); \ - } \ -\ -/* If a variance estimate is required but none can be obtained, then \ - store a bad output variance value and count it. */ \ - if ( Usevar ) { \ - if ( ( ( Xsigned ) || ( Usebad ) ) && bad_var ) { \ - if( !Nobad ) out_var[ off_out ] = badval; \ - result++; \ -\ -/* Otherwise, calculate the variance estimate and store it, rounding \ - to the nearest integer if necessary. */ \ - } else { \ - val = sum_var / ( wtsum * wtsum ); \ - if ( Xfloating ) { \ - out_var[ off_out ] = (Xtype) val; \ - } else { \ - out_var[ off_out ] = (Xtype) ( val + \ - ( ( val >= (Xfloattype) 0.0 ) ? \ - ( (Xfloattype) 0.5 ) : \ - ( (Xfloattype) -0.5 ) ) ); \ - } \ - } \ - } \ - } - -/* This subsidiary macro tests for negative variance values in the - macros above. This check is required only for signed data types. */ -#define CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ - bad_var = bad_var || ( var < ( (Xtype) 0 ) ); - -/* Expand the main macro above to generate a function for each - required signed data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_INTERPOLATE_LINEAR(LD,long double,1,long double,1) -MAKE_INTERPOLATE_LINEAR(L,long int,0,long double,1) -MAKE_INTERPOLATE_LINEAR(K,INT_BIG,0,long double,1) -#else -MAKE_INTERPOLATE_LINEAR(L,long int,0,double,1) -MAKE_INTERPOLATE_LINEAR(K,INT_BIG,0,double,1) -#endif -MAKE_INTERPOLATE_LINEAR(D,double,1,double,1) -MAKE_INTERPOLATE_LINEAR(F,float,1,float,1) -MAKE_INTERPOLATE_LINEAR(I,int,0,double,1) -MAKE_INTERPOLATE_LINEAR(S,short int,0,float,1) -MAKE_INTERPOLATE_LINEAR(B,signed char,0,float,1) - -/* Re-define the macro for testing for negative variances to do - nothing. */ -#undef CHECK_FOR_NEGATIVE_VARIANCE -#define CHECK_FOR_NEGATIVE_VARIANCE(Xtype) - -/* Expand the main macro above to generate a function for each - required unsigned data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_INTERPOLATE_LINEAR(UL,unsigned long int,0,long double,0) -MAKE_INTERPOLATE_LINEAR(UK,UINT_BIG,0,long double,0) -#else -MAKE_INTERPOLATE_LINEAR(UL,unsigned long int,0,double,0) -MAKE_INTERPOLATE_LINEAR(UK,UINT_BIG,0,double,0) -#endif -MAKE_INTERPOLATE_LINEAR(UI,unsigned int,0,double,0) -MAKE_INTERPOLATE_LINEAR(US,unsigned short int,0,float,0) -MAKE_INTERPOLATE_LINEAR(UB,unsigned char,0,float,0) - -/* Undefine the macros uxsed above. */ -#undef CHECK_FOR_NEGATIVE_VARIANCE -#undef CALC_AND_ASSIGN_OUTPUT -#undef FORM_LINEAR_INTERPOLATION_SUM -#undef ASSEMBLE_INPUT_ND -#undef ASSEMBLE_INPUT_2D -#undef ASSEMBLE_INPUT_1D -#undef MAKE_INTERPOLATE_LINEAR - -/* -* Name: -* InterpolateNearest - -* Purpose: -* Resample a data grid, using the nearest-pixel interpolation scheme. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int InterpolateNearest( int ndim_in, -* const int *lbnd_in, const int *ubnd_in, -* const *in, const *in_var, -* int npoint, const int *offset, -* const double *const *coords, -* int flags, badval, -* *out, *out_var ) - -* Class Membership: -* Mapping member function. - -* Description: -* This is a set of functions which resample a rectangular input -* grid of data (and, optionally, associated statistical variance -* values) so as to place them into a new output grid. Each output -* grid point may be mapped on to a position in the input grid in -* an arbitrary way. Where the positions given do not correspond -* with a pixel centre in the input grid, the interpolation scheme -* used is simply to select the nearest pixel (i.e. the one whose -* bounds contain the supplied position). - -* Parameters: -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input grid, its extent along a particular -* (i'th) dimension being ubnd_in[i]-lbnd_in[i]+1 (assuming "i" -* is zero-based). They also define the input grid's coordinate -* system, with each pixel being of unit extent along each -* dimension with integral coordinate values at its centre. -* in -* Pointer to the array of data to be resampled (with an element -* for each pixel in the input grid). The numerical type of -* these data should match the function used, as given by the -* suffix on the function name. The storage order should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -* (i.e. Fortran array storage order). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and type as the "in" array), which -* represent estimates of the statistical variance associated -* with each element of the "in" array. If this second array is -* given (along with the corresponding "out_var" array), then -* estimates of the variance of the resampled data will also be -* returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* npoint -* The number of points at which the input grid is to be -* resampled. -* offset -* Pointer to an array of integers with "npoint" elements. For -* each output point, this array should contain the zero-based -* offset in the output array(s) (i.e. the "out" and, -* optionally, the "out_var" arrays) at which the resampled -* output value(s) should be stored. -* coords -* An array of pointers to double, with "ndim_in" -* elements. Element "coords[coord]" should point at the first -* element of an array of double (with "npoint" elements) which -* contains the values of coordinate number "coord" for each -* interpolation point. The value of coordinate number "coord" -* for interpolation point number "point" is therefore given by -* "coords[coord][point]" (assuming both indices to be -* zero-based). If any point has a coordinate value of AST__BAD -* associated with it, then the corresponding output data (and -* variance) will be set to the value given by "badval" (unles the -* AST__NOBAD flag is specified). -* flags -* The bitwise OR of a set of flag values which control the -* operation of the function. Currently, only the flag -* AST__USEBAD is significant and indicates whether there are -* "bad" (i.e. missing) data in the input array(s) which must be -* recognised and propagated to the output array(s). If this -* flag is not set, all input values are treated literally. -* badval -* If the AST__USEBAD flag is set in the "flags" value (above), -* this parameter specifies the value which is used to identify -* bad data and/or variance values in the input array(s). Its -* numerical type must match that of the "in" (and "in_var") -* arrays. Unles the AST__NOBAD flag is specified in "flags", the -* same value will also be used to flag any output array elements -* for which resampled values could not be obtained. The output -* arrays(s) may be flagged with this value whether or not the -* AST__USEBAD flag is set (the function return value indicates -* whether any such values have been produced). -* out -* Pointer to an array with the same data type as the "in" -* array, into which the resampled data will be returned. Note -* that details of how the output grid maps on to this array -* (e.g. the storage order, number of dimensions, etc.) is -* arbitrary and is specified entirely by means of the "offset" -* array. The "out" array should therefore contain sufficient -* elements to accommodate the "offset" values supplied. There -* is no requirement that all elements of the "out" array should -* be assigned values, and any which are not addressed by the -* contents of the "offset" array will be left unchanged. -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the resampled values may be returned. This array will only be -* used if the "in_var" array has been given. It is addressed in -* exactly the same way (via the "offset" array) as the "out" -* array. The values returned are estimates of the statistical -* variance of the corresponding values in the "out" array, on -* the assumption that all errors in input grid values (in the -* "in" array) are statistically independent and that their -* variance estimates (in the "in_var" array) may simply be -* summed (with appropriate weighting factors). -* -* If no output variance estimates are required, a NULL pointer -* should be given. - -* Returned Value: -* The number of output grid points to which a data value (or a -* variance value if relevant) equal to "badval" has been assigned -* because no valid output value could be obtained. - -* Notes: -* - There is a separate function for each numerical type of -* gridded data, distinguished by replacing the in the function -* name by the appropriate 1- or 2-character suffix. -* - A value of zero will be returned if any of these functions is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ -/* Define a macro to implement the function for a specific data - type. */ -#define MAKE_INTERPOLATE_NEAREST(X,Xtype,Xsigned) \ -static int InterpolateNearest##X( int ndim_in, \ - const int *lbnd_in, const int *ubnd_in, \ - const Xtype *in, const Xtype *in_var, \ - int npoint, const int *offset, \ - const double *const *coords, \ - int flags, Xtype badval, \ - Xtype *out, Xtype *out_var, int *status ) { \ -\ -/* Local Variables: */ \ - Xtype var; /* Variance value */ \ - double *xn_max; /* Pointer to upper limits array (n-d) */ \ - double *xn_min; /* Pointer to lower limits array (n-d) */ \ - double x; /* x coordinate value */ \ - double xmax; /* x upper limit */ \ - double xmin; /* x lower limit */ \ - double xn; /* Coordinate value (n-d) */ \ - double y; /* y coordinate value */ \ - double ymax; /* y upper limit */ \ - double ymin; /* y lower limit */ \ - int *stride; /* Pointer to array of dimension strides */ \ - int bad; /* Output pixel bad? */ \ - int idim; /* Loop counter for dimensions */ \ - int ix; /* Number of pixels offset in x direction */ \ - int ixn; /* Number of pixels offset (n-d) */ \ - int iy; /* Number of pixels offset in y direction */ \ - int nobad; /* Was the AST__NOBAD flag set? */ \ - int off_in; /* Pixel offset into input array */ \ - int off_out; /* Pixel offset into output array */ \ - int point; /* Loop counter for output points */ \ - int result; /* Returned result value */ \ - int s; /* Temporary variable for strides */ \ - int usebad; /* Use "bad" input pixel values? */ \ - int usevar; /* Process variance array? */ \ - int ystride; /* Stride along input grid y direction */ \ -\ -/* Initialise. */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Initialise variables to avoid "used of uninitialised variable" \ - messages from dumb compilers. */ \ - bad = 0; \ - off_in = 0; \ -\ -/* Determine if we are processing bad pixels or variances. */ \ - nobad = flags & AST__NOBAD; \ - usebad = flags & AST__USEBAD; \ - usevar = in_var && out_var; \ -\ -/* Handle the 1-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - if ( ndim_in == 1 ) { \ -\ -/* Calculate the coordinate limits of the input array. */ \ - xmin = (double) lbnd_in[ 0 ] - 0.5; \ - xmax = (double) ubnd_in[ 0 ] + 0.5; \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,0,1) \ - } \ - } \ - } \ -\ -/* Four more cases as above, but without the AST__NOBAD flag. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,0,0) \ - } \ - } \ - } \ - } \ -\ -/* Handle the 2-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - } else if ( ndim_in == 2 ) { \ -\ -/* Calculate the stride along the y dimension of the input grid. */ \ - ystride = ubnd_in[ 0 ] - lbnd_in[ 0 ] + 1; \ -\ -/* Calculate the coordinate limits of the input array in each \ - dimension. */ \ - xmin = (double) lbnd_in[ 0 ] - 0.5; \ - xmax = (double) ubnd_in[ 0 ] + 0.5; \ - ymin = (double) lbnd_in[ 1 ] - 0.5; \ - ymax = (double) ubnd_in[ 1 ] + 0.5; \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,0,1) \ - } \ - } \ - } \ -\ -/* Four more cases as above, but without the AST__NOBAD flag. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,0,0) \ - } \ - } \ - } \ - } \ -\ -/* Handle other numbers of dimensions. */ \ -/* ----------------------------------- */ \ - } else { \ -\ -/* Allocate workspace. */ \ - stride = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - xn_max = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - xn_min = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - if ( astOK ) { \ -\ -/* Calculate the stride along each dimension of the input grid. */ \ - for ( s = 1, idim = 0; idim < ndim_in; idim++ ) { \ - stride[ idim ] = s; \ - s *= ubnd_in[ idim ] - lbnd_in[ idim ] + 1; \ -\ -/* Calculate the coordinate limits of the input grid in each \ - dimension. */ \ - xn_min[ idim ] = (double) lbnd_in[ idim ] - 0.5; \ - xn_max[ idim ] = (double) ubnd_in[ idim ] + 0.5; \ - } \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,0,1) \ - } \ - } \ - } \ -\ -/* Another 4 cases as above, but without the AST__NOBAD flag. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,0,0,0) \ - } \ - } \ - } \ - } \ - } \ -\ -/* Free the workspace. */ \ - stride = astFree( stride ); \ - xn_max = astFree( xn_max ); \ - xn_min = astFree( xn_min ); \ - } \ -\ -/* If an error has occurred, clear the returned result. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the 1-dimensional - case. */ -#define ASSEMBLE_INPUT_1D(X,Xtype,Usebad,Usevar) \ -\ -/* Obtain the x coordinate of the current point and test if it lies \ - outside the input grid, or is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If not, then obtain the offset within the input grid of the pixel \ - which contains the current point. */ \ - off_in = (int) floor( x + 0.5 ) - lbnd_in[ 0 ]; \ -\ -/* If necessary, test if the input pixel is bad. */ \ - if ( Usebad ) bad = ( in[ off_in ] == badval ); \ - } - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the 2-dimensional - case. */ -#define ASSEMBLE_INPUT_2D(X,Xtype,Usebad,Usevar) \ -\ -/* Obtain the x coordinate of the current point and test if it lies \ - outside the input grid, or is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If not, then similarly obtain and test the y coordinate. */ \ - y = coords[ 1 ][ point ]; \ - bad = ( y < ymin ) || ( y >= ymax ) || ( y == AST__BAD ); \ - if ( !bad ) { \ -\ -/* Obtain the offsets along each input grid dimension of the input \ - pixel which contains the current point. */ \ - ix = (int) floor( x + 0.5 ) - lbnd_in[ 0 ]; \ - iy = (int) floor( y + 0.5 ) - lbnd_in[ 1 ]; \ -\ -/* Calculate this pixel's offset from the start of the input array. */ \ - off_in = ix + ystride * iy; \ -\ -/* If necessary, test if the input pixel is bad. */ \ - if ( Usebad ) bad = ( in[ off_in ] == badval ); \ - } \ - } - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the n-dimensional - case. */ -#define ASSEMBLE_INPUT_ND(X,Xtype,Usebad,Usevar) \ -\ -/* Initialise the offset into the input array. Then loop to obtain \ - each coordinate associated with the current output point. */ \ - off_in = 0; \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - xn = coords[ idim ][ point ]; \ -\ -/* Test if the coordinate lies outside the input grid, or is bad. If \ - either is true, the corresponding output pixel value will be bad, \ - so give up on this point. */ \ - bad = ( xn < xn_min[ idim ] ) || ( xn >= xn_max[ idim ] ) || \ - ( xn == AST__BAD ); \ - if ( bad ) break; \ -\ -/* Obtain the offset along the current input grid dimension of the \ - input pixel which contains the current point. */ \ - ixn = (int) floor( xn + 0.5 ) - lbnd_in[ idim ]; \ -\ -/* Accumulate this pixel's offset from the start of the input \ - array. */ \ - off_in += ixn * stride[ idim ]; \ - } \ -\ -/* Once the required input pixel has been located, test if it is \ - bad, if necessary. */ \ - if ( Usebad ) bad = bad || ( in[ off_in ] == badval ); - -/* This subsidiary macro assigns the output value (and variance) to - the output array(s). */ -#define CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xsigned,Usebad,Usevar,Nobad) \ -\ -/* Obtain the pixel offset into the output array. */ \ - off_out = offset[ point ]; \ -\ -/* If the input data value is bad, assign a bad output value (and \ - variance, if required) and count it. */ \ - if ( bad ) { \ - if( !Nobad ) { \ - out[ off_out ] = badval; \ - if ( Usevar ) out_var[ off_out ] = badval; \ - } \ - result++; \ -\ -/* Otherwise, assign the value obtained from the input grid. */ \ - } else { \ - out[ off_out ] = in[ off_in ]; \ -\ -/* If required, obtain the associated variance value. If necessary, \ - test if it is bad (if the data type is signed, also check that it \ - is not negative). */ \ - if ( Usevar ) { \ - var = in_var[ off_in ]; \ - if ( Usebad ) bad = ( var == badval ); \ - CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ -\ -/* If the variance value can be bad, and is, then store a bad value in \ - the output array and count it. Otherwise, store the variance \ - value. */ \ - if ( ( ( Xsigned ) || ( Usebad ) ) && bad ) { \ - if( !Nobad ) out_var[ off_out ] = badval; \ - result++; \ - } else { \ - out_var[ off_out ] = var; \ - } \ - } \ - } - -/* This subsidiary macro tests for negative variance values in the - macros above. This check is required only for signed data - types. */ -#define CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ - bad = bad || ( var < ( (Xtype) 0 ) ); - -/* Expand the main macro above to generate a function for each - required signed data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_INTERPOLATE_NEAREST(LD,long double,1) -#endif -MAKE_INTERPOLATE_NEAREST(D,double,1) -MAKE_INTERPOLATE_NEAREST(F,float,1) -MAKE_INTERPOLATE_NEAREST(L,long int,1) -MAKE_INTERPOLATE_NEAREST(K,INT_BIG,1) -MAKE_INTERPOLATE_NEAREST(I,int,1) -MAKE_INTERPOLATE_NEAREST(S,short int,1) -MAKE_INTERPOLATE_NEAREST(B,signed char,1) - -/* Re-define the macro for testing for negative variances to do - nothing. */ -#undef CHECK_FOR_NEGATIVE_VARIANCE -#define CHECK_FOR_NEGATIVE_VARIANCE(Xtype) - -/* Expand the main macro above to generate a function for each - required unsigned data type. */ -MAKE_INTERPOLATE_NEAREST(UK,UINT_BIG,0) -MAKE_INTERPOLATE_NEAREST(UL,unsigned long int,0) -MAKE_INTERPOLATE_NEAREST(UI,unsigned int,0) -MAKE_INTERPOLATE_NEAREST(US,unsigned short int,0) -MAKE_INTERPOLATE_NEAREST(UB,unsigned char,0) - -/* Undefine the macros used above. */ -#undef CHECK_FOR_NEGATIVE_VARIANCE -#undef CALC_AND_ASSIGN_OUTPUT -#undef ASSEMBLE_INPUT_ND -#undef ASSEMBLE_INPUT_2D -#undef ASSEMBLE_INPUT_1D -#undef MAKE_INTERPOLATE_NEAREST - -/* -* Name: -* InterpolateBlockAverage - -* Purpose: -* Resample a data grid, using multidimensional block averaging. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void InterpolateBlockAverage( int ndim_in, -* const int lbnd_in[], -* const int ubnd_in[], -* const in[], -* const in_var[], -* int npoint, const int offset[], -* const double *const coords[], -* const double params[], int flags, -* badval, *out, -* *out_var, int *nbad ) - -* Class Membership: -* Mapping member function. - -* Description: -* This is a set of functions which resample a rectangular input -* grid of data (and, optionally, associated statistical variance -* values) so as to place them into a new output grid. To generate -* an output grid pixel, a block average is taken over an ndim- -* dimensional hypercube of pixels in the input grid. If variances -* are being used then the input pixels will be weighted according -* to the reciprocals of the corresponding variance values, and -* input pixels without a valid variance will be ignored; -* otherwise an unweighted average will be taken over -* all non-bad pixels in the cube. The size of the cube over which -* the average is taken is determined by the first element of the -* params array. -* -* This "interpolation" scheme is appropriate where an input grid -* is to be resampled onto a much coarser output grid. - -* Parameters: -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input grid, its extent along a particular -* (i'th) dimension being ubnd_in[i]-lbnd_in[i]+1 (assuming "i" -* is zero-based). They also define the input grid's coordinate -* system, with each pixel being of unit extent along each -* dimension with integral coordinate values at its centre. -* in -* Pointer to the array of data to be resampled (with an element -* for each pixel in the input grid). The numerical type of -* these data should match the function used, as given by the -* suffix on the function name. The storage order should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -* (i.e. Fortran array storage order). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and type as the "in" array), which -* represent estimates of the statistical variance associated -* with each element of the "in" array. If this second array is -* given (along with the corresponding "out_var" array), then -* estimates of the variance of the resampled data will also be -* returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* npoint -* The number of points at which the input grid is to be -* resampled. -* offset -* Pointer to an array of integers with "npoint" elements. For -* each output point, this array should contain the zero-based -* offset in the output array(s) (i.e. the "out" and, -* optionally, the "out_var" arrays) at which the resampled -* output value(s) should be stored. -* coords -* An array of pointers to double, with "ndim_in" -* elements. Element "coords[coord]" should point at the first -* element of an array of double (with "npoint" elements) which -* contains the values of coordinate number "coord" for each -* interpolation point. The value of coordinate number "coord" -* for interpolation point number "point" is therefore given by -* "coords[coord][point]" (assuming both indices to be -* zero-based). If any point has a coordinate value of AST__BAD -* associated with it, then the corresponding output data (and -* variance) will be set to the value given by "badval" (unles the -* AST__NOBAD flag is specified). -* params -* A pointer to an array of doubles giving further information -* about how the resampling is to proceed. Only the first -* element is significant; the nearest integer to this gives -* the number of pixels on either side of the central input -* grid pixel to use in each dimension. Therefore -* (1 + 2*params[0])**ndim_in pixels will be averaged over to -* generate each output pixel. -* flags -* The bitwise OR of a set of flag values which control the -* operation of the function. Currently, only the flag -* AST__USEBAD is significant and indicates whether there are -* "bad" (i.e. missing) data in the input array(s) which must be -* recognised and propagated to the output array(s). If this -* flag is not set, all input values are treated literally. -* badval -* If the AST__USEBAD flag is set in the "flags" value (above), -* this parameter specifies the value which is used to identify -* bad data and/or variance values in the input array(s). Its -* numerical type must match that of the "in" (and "in_var") -* arrays. Unles the AST__NOBAD flag is specified in "flags", the -* same value will also be used to flag any output array elements -* for which resampled values could not be obtained. The output -* arrays(s) may be flagged with this value whether or not the -* AST__USEBAD flag is set (the function return value indicates -* whether any such values have been produced). -* out -* Pointer to an array with the same data type as the "in" -* array, into which the resampled data will be returned. Note -* that details of how the output grid maps on to this array -* (e.g. the storage order, number of dimensions, etc.) is -* arbitrary and is specified entirely by means of the "offset" -* array. The "out" array should therefore contain sufficient -* elements to accommodate the "offset" values supplied. There -* is no requirement that all elements of the "out" array should -* be assigned values, and any which are not addressed by the -* contents of the "offset" array will be left unchanged. -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the resampled values may be returned. This array will only be -* used if the "in_var" array has been given. It is addressed in -* exactly the same way (via the "offset" array) as the "out" -* array. The values returned are estimates of the statistical -* variance of the corresponding values in the "out" array, on -* the assumption that all errors in input grid values (in the -* "in" array) are statistically independent and that their -* variance estimates (in the "in_var" array) may simply be -* summed (with appropriate weighting factors). -* -* If no output variance estimates are required, a NULL pointer -* should be given. -* nbad -* Pointer to an int in which to return the number of -* interpolation points at which an output data value (and/or a -* variance value if relevant) equal to "badval" has been -* assigned because no valid interpolated value could be -* obtained. The maximum value that will be returned is -* "npoint" and the minimum is zero (indicating that all output -* values were successfully obtained). - -* Notes: -* - There is a separate function for each numerical type of -* gridded data, distinguished by replacing the in the function -* name by the appropriate 1- or 2-character suffix. -*/ -/* Define a macro to implement the function for a specific data - type. */ -#define MAKE_INTERPOLATE_BLOCKAVE(X,Xtype,Xfloating,Xfloattype,Xsigned) \ -static void InterpolateBlockAverage##X( int ndim_in, \ - const int lbnd_in[], \ - const int ubnd_in[], \ - const Xtype in[], \ - const Xtype in_var[], \ - int npoint, const int offset[], \ - const double *const coords[], \ - const double params[], int flags, \ - Xtype badval, Xtype *out, \ - Xtype *out_var, int *nbad ) { \ -\ -/* Local Variables: */ \ - Xfloattype hi_lim; /* Upper limit on output values */ \ - Xfloattype lo_lim; /* Lower limit on output values */ \ - Xfloattype pixwt; /* Weight to apply to individual pixel */ \ - Xfloattype sum; /* Weighted sum of pixel data values */ \ - Xfloattype sum_var; /* Weighted sum of pixel variance values */ \ - Xfloattype val; /* Data value to be assigned to output */ \ - Xfloattype val_var; /* Variance to be assigned to output */ \ - Xfloattype wtsum; /* Sum of weight values */ \ - Xfloattype wtsum_sq; /* Square of sum of weights */ \ - Xtype var; /* Variance value */ \ - double *xn_max; /* Pointer to upper limits array (n-d) */ \ - double *xn_min; /* Pointer to lower limits array (n-d) */ \ - double x; /* x coordinate value */ \ - double xn; /* Coordinate value (n-d) */ \ - double y; /* y coordinate value */ \ - int *hi; /* Pointer to array of upper indices */ \ - int *ixm; /* Pointer to array of current indices */ \ - int *lo; /* Pointer to array of lower indices */ \ - int *status; /* Pointer to inherited status value */ \ - int *stride; /* Pointer to array of dimension strides */ \ - int bad; /* Output pixel bad? */ \ - int bad_var; /* Output variance bad? */ \ - int done; /* All pixel indices done? */ \ - int hi_x; /* Upper pixel index (x dimension) */ \ - int hi_y; /* Upper pixel index (y dimension) */ \ - int idim; /* Loop counter for dimensions */ \ - int ix; /* Pixel index in input grid x dimension */ \ - int ixn; /* Pixel index in input grid (n-d) */ \ - int iy; /* Pixel index in input grid y dimension */ \ - int lo_x; /* Lower pixel index (x dimension) */ \ - int lo_y; /* Lower pixel index (y dimension) */ \ - int neighb; /* Number of adjacent pixels on each side */ \ - int nobad; /* Was the AST__NOBAD flag set? */ \ - int off1; /* Input pixel offset due to y index */ \ - int off_in; /* Offset to input pixel */ \ - int off_out; /* Offset to output pixel */ \ - int point; /* Loop counter for output points */ \ - int s; /* Temporary variable for strides */ \ - int usebad; /* Use "bad" input pixel values? */ \ - int usevar; /* Process variance array? */ \ - int ystride; /* Stride along input grid y dimension */ \ -\ -/* Initialise. */ \ - *nbad = 0; \ -\ -/* Get a pointer to the inherited status argument. */ \ - status = astGetStatusPtr; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Initialise variables to avoid "used of uninitialised variable" \ - messages from dumb compilers. */ \ - val = 0; \ - val_var = 0; \ - sum_var = 0; \ - wtsum = 0; \ - bad = 0; \ - bad_var = 0; \ -\ -/* Determine if we are processing bad pixels or variances. */ \ - nobad = flags & AST__NOBAD; \ - usebad = flags & AST__USEBAD; \ - usevar = in_var && out_var; \ -\ -/* Set the number of pixels each side of central pixel to use. */ \ - neighb = (int) floor( params[ 0 ] + 0.5 ); \ -\ -/* Set up limits for checking output values to ensure that they do not \ - overflow the range of the data type being used. */ \ - lo_lim = LO_##X; \ - hi_lim = HI_##X; \ -\ -/* Handle the 1-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - if ( ndim_in == 1 ) { \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,1) \ - } \ - } \ - } \ -\ -/* Another 4 cases as above, but without the AST__NOBAD flag. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,0) \ - } \ - } \ - } \ - } \ -\ -/* Handle the 2-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - } else if ( ndim_in == 2 ) { \ -\ -/* Calculate the stride along the y dimension of the input grid. */ \ - ystride = ubnd_in[ 0 ] - lbnd_in[ 0 ] + 1; \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,1) \ - } \ - } \ - } \ -\ -/* Another 4 cases as above, but without the AST__NOBAD flag. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,0) \ - } \ - } \ - } \ - } \ -\ -/* Handle other numbers of dimensions. */ \ -/* ----------------------------------- */ \ - } else { \ -\ -/* Allocate workspace. */ \ - hi = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - lo = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - stride = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - ixm = astMalloc( sizeof( int ) * (size_t) ndim_in ); \ - xn_max = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - xn_min = astMalloc( sizeof( double ) * (size_t) ndim_in ); \ - if ( astOK ) { \ -\ -/* Calculate the stride along each dimension of the input grid. */ \ - for ( s = 1, idim = 0; idim < ndim_in; idim++ ) { \ - stride[ idim ] = s; \ - s *= ubnd_in[ idim ] - lbnd_in[ idim ] + 1; \ -\ -/* Calculate the coordinate limits of the input grid in each \ - dimension. */ \ - xn_min[ idim ] = (double) lbnd_in[ idim ] - 0.5; \ - xn_max[ idim ] = (double) ubnd_in[ idim ] + 0.5; \ - } \ -\ -/* Identify four cases, according to whether bad pixels and/or \ - variances are being processed. In each case, loop through all the \ - output points to (a) assemble the input data needed to form the \ - interpolated value, and (b) calculate the result and assign it to \ - the output arrays(s). In each case we assign constant values (0 or \ - 1) to the "Usebad" and "Usevar" flags so that code for handling bad \ - pixels and variances can be eliminated when not required. */ \ - if ( nobad ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,1) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,1) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,1) \ - } \ - } \ - } \ -\ -/* Another 4 cases as above, but this time without the AST__NOBAD flag. */ \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,1,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,1,0,0) \ - } \ - } \ - } else { \ - if ( usevar ) { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,1) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,1,0) \ - } \ - } else { \ - for ( point = 0; point < npoint; point++ ) { \ - ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,0,0) \ - CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,0,0,0) \ - } \ - } \ - } \ - } \ - } \ -\ -/* Free the workspace. */ \ - hi = astFree( hi ); \ - lo = astFree( lo ); \ - stride = astFree( stride ); \ - ixm = astFree( ixm ); \ - xn_max = astFree( xn_max ); \ - xn_min = astFree( xn_min ); \ - } \ -\ -/* If an error has occurred, clear the returned result. */ \ - if ( !astOK ) *nbad = 0; \ -\ -/* Return. */ \ -} - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the 1-dimensional - case. */ -#define ASSEMBLE_INPUT_1D(X,Xtype,Xfloating,Xfloattype,Xsigned,Usebad,Usevar) \ -\ -/* Obtain the x coordinate of the current point and test if it is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = ( x == AST__BAD ); \ -\ -/* Note we do not need to check here whether the pixel in this position is \ - bad; if any pixels in the cube are good we can form an average. */ \ -\ -/* If OK, calculate the lowest and highest indices (in the x \ - dimension) of the region of neighbouring pixels that will \ - contribute to the interpolated result. Constrain these values to \ - lie within the input grid. */ \ - if ( !bad ) { \ - ix = (int) floor( x ); \ - lo_x = MaxI( ix - neighb + 1, lbnd_in[ 0 ], status ); \ - hi_x = MinI( ix + neighb, ubnd_in[ 0 ], status ); \ -\ -/* Initialise sums for forming the interpolated result. */ \ - sum = (Xfloattype) 0.0; \ - wtsum = (Xfloattype) 0.0; \ - if ( Usevar ) { \ - sum_var = (Xfloattype) 0.0; \ - bad_var = 0; \ - } \ -\ -/* Loop to inspect all the contributing pixels, calculating the offset \ - of each pixel from the start of the input array. */ \ - off_in = lo_x - lbnd_in[ 0 ]; \ - for ( ix = lo_x; ix <= hi_x; ix++, off_in++ ) { \ -\ -/* If necessary, test if the input pixel is bad. */ \ - if ( !( Usebad ) || ( in[ off_in ] != badval ) ) { \ -\ -/* If we are using variances, then check that the variance is valid; \ - if it is invalid then ignore this pixel altogether. */ \ - if ( Usevar ) { \ - var = in_var[ off_in ]; \ - if ( Usebad ) bad_var = ( var == badval ); \ - CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ -\ -/* If variance is valid then accumulate suitably weighted values into \ - the totals. */ \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - pixwt = (Xfloattype) 1.0 / var; \ - sum += pixwt * ( (Xfloattype) in[ off_in ] ); \ - wtsum += pixwt; \ - sum_var += pixwt; \ - } \ -\ -/* If we are not using variances, then accumulate values into the \ - totals with a weighting of unity. */ \ - } else { \ - sum += (Xfloattype) in[ off_in ]; \ - wtsum++; \ - } \ - } \ - } \ - } - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the 2-dimensional - case. */ -#define ASSEMBLE_INPUT_2D(X,Xtype,Xfloating,Xfloattype,Xsigned,Usebad,Usevar) \ -\ -/* Obtain the x coordinate of the current point and test if it is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If not, then similarly obtain and test the y coordinate. */ \ - y = coords[ 1 ][ point ]; \ - bad = ( y == AST__BAD ); \ -\ -/* Note we do not need to check here whether the pixel in this position is \ - bad; if any pixels in the cube are good we can form an average. */ \ -\ -/* If OK, calculate the lowest and highest indices (in each dimension) \ - of the region of neighbouring pixels that will contribute to the \ - interpolated result. Constrain these values to lie within the input \ - grid. */ \ - if ( !bad ) { \ - ix = (int) floor( x ); \ - lo_x = MaxI( ix - neighb + 1, lbnd_in[ 0 ], status ); \ - hi_x = MinI( ix + neighb, ubnd_in[ 0 ], status ); \ - iy = (int) floor( y ); \ - lo_y = MaxI( iy - neighb + 1, lbnd_in[ 1 ], status ); \ - hi_y = MinI( iy + neighb, ubnd_in[ 1 ], status ); \ -\ -/* Initialise sums for forming the interpolated result. */ \ - sum = (Xfloattype) 0.0; \ - wtsum = (Xfloattype) 0.0; \ - if ( Usevar ) { \ - sum_var = (Xfloattype) 0.0; \ - bad_var = 0; \ - } \ -\ -/* Loop to inspect all the contributing pixels, calculating the offset \ - of each pixel from the start of the input array. */ \ - off1 = lo_x - lbnd_in[ 0 ] + ystride * ( lo_y - lbnd_in[ 1 ] ); \ - for ( iy = lo_y; iy <= hi_y; iy++, off1 += ystride ) { \ - off_in = off1; \ - for ( ix = lo_x; ix <= hi_x; ix++, off_in++ ) { \ -\ -/* If necessary, test if the input pixel is bad. */ \ - if ( !( Usebad ) || ( in[ off_in ] != badval ) ) { \ -\ -/* If we are using variances, then check that the variance is valid; \ - if it is invalid then ignore this pixel altogether. */ \ - if ( Usevar ) { \ - var = in_var[ off_in ]; \ - if ( Usebad ) bad_var = ( var == badval ); \ - CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ -\ -/* If variance is valid then accumulate suitably weighted values into \ - the totals. */ \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - pixwt = (Xfloattype) 1.0 / var; \ - sum += pixwt * ( (Xfloattype) in[ off_in ] ); \ - wtsum += pixwt; \ - sum_var += pixwt; \ - } \ -\ -/* If we are not using variances, then accumulate values into the \ - totals with a weighting of unity. */ \ - } else { \ - sum += (Xfloattype) in[ off_in ]; \ - wtsum++; \ - } \ - } \ - } \ - } \ - } \ - } - -/* This subsidiary macro assembles the input data needed in - preparation for forming the interpolated value in the n-dimensional - case. */ -#define ASSEMBLE_INPUT_ND(X,Xtype,Xfloating,Xfloattype,Xsigned,Usebad,Usevar) \ -\ -/* Initialise offsets into the input array. then loop to obtain each \ - coordinate associated with the current output poitn. */ \ - off_in = 0; \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - xn = coords[ idim ][ point ]; \ -\ -/* Test if the coordinate is bad. If so give up on this point. */ \ - bad = ( xn == AST__BAD ); \ - if ( bad ) break; \ -\ -/* Calculate the lowest and highest indices (in the current dimension) \ - of the region of neighbouring pixels that will contribute to the \ - interpolated result. Constrain these values to lie within the input \ - grid. */ \ - ixn = (int) floor( xn ); \ - lo[ idim ] = MaxI( ixn - neighb + 1, lbnd_in[ idim ], status ); \ - hi[ idim ] = MinI( ixn + neighb, ubnd_in[ idim ], status ); \ -\ -/* If the cube has a zero dimension then no data can come from it. */ \ - bad = ( lo[ idim ] > hi[ idim ] ); \ - if ( bad ) break; \ -\ -/* Accumulate the offset (from the start of the input array) of the \ - contributing pixel which has the lowest index in each dimension. */ \ - off_in += stride[ idim ] * ( lo[ idim ] - lbnd_in[ idim ] ); \ -\ -/* Initialise an array to keep track of the current position in the \ - input cube. */ \ - ixm[ idim ] = lo[ idim ]; \ - } \ -\ -/* Note we do not need to check here whether the pixel in this position is \ - bad; if any pixels in the cube are good we can form an average. */ \ -\ -/* If OK, initialise sums for forming the interpolated result. */ \ - if ( !bad ) { \ - sum = (Xfloattype) 0.0; \ - wtsum= (Xfloattype) 0.0; \ - if ( Usevar ) { \ - sum_var = (Xfloattype) 0.0; \ - bad_var = 0; \ - } \ -\ -/* Loop to inspect all the contributing pixels, calculating the offset \ - of each pixel from the start of the input array. */ \ - do { \ -\ -/* If necessary, test if the input pixel is bad. */ \ - if ( !( Usebad ) || ( in[ off_in ] != badval ) ) { \ -\ -/* If we are using variances, then check that the variance is valid; \ - if it is invalid then ignore this pixel altogether. */ \ - if ( Usevar ) { \ - var = in_var[ off_in ]; \ - if ( Usebad ) bad_var = ( var == badval ); \ - CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ -\ -/* If variance is valid then accumulate suitably weighted values into \ - the totals. */ \ - if ( !( ( Xsigned ) || ( Usebad ) ) || !bad_var ) { \ - pixwt = (Xfloattype) 1.0 / var; \ - sum += pixwt * ( (Xfloattype) in[ off_in ] ); \ - wtsum += pixwt; \ - sum_var += pixwt; \ - } \ -\ -/* If we are not using variances, then accumulate values into the \ - totals with a weighting of unity. */ \ - } else { \ - sum += (Xfloattype) in[ off_in ]; \ - wtsum++; \ - } \ - } \ -\ -/* Locate the next pixel in the input cube; try incrementing the lowest \ - dimension index first, if that rolls over increment the next \ - dimension index, and so on. */ \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - if ( ixm[ idim ] < hi[ idim ] ) { \ - off_in += stride[ idim ]; \ - ixm[ idim ]++; \ - break; \ - } else { \ - off_in -= stride[ idim ] * ( hi[ idim ] - lo[ idim ] ); \ - ixm[ idim ] = lo[ idim ]; \ - } \ - } \ -\ -/* If the highest dimension index has rolled over, we have done all \ - the pixels in the cube. */ \ - done = ( idim == ndim_in ); \ - } while ( !done ); \ - } - -/* This subsidiary macro calculates the interpolated output value (and - variance) from the sums over contributing pixels, checks the - results for validity, and assigns them to the output array(s). */ -#define CALC_AND_ASSIGN_OUTPUT(X,Xtype,Xfloating,Xfloattype,Usebad,Usevar,Nobad) \ -\ -/* If the output data value has not yet been flagged as bad, then \ - check that an interpolated value can actually be produced. First \ - check that the sum of weights is not zero. */ \ - if ( !bad ) { \ - bad = ( wtsum == (Xfloattype) 0.0 ); \ -\ -/* If OK, calculate the interpolated value. Then, if the output data \ - type is not floating point, check that this value will not overflow \ - the available output range. */ \ - if ( !bad ) { \ - val = sum / wtsum; \ - if ( !( Xfloating ) ) { \ - bad = ( val <= lo_lim ) || ( val >= hi_lim ); \ - } \ - } \ -\ -/* If no interpolated data value can be produced, then no associated \ - variance will be required either. */ \ - if ( ( Usevar ) && bad ) bad_var = 1; \ - } \ -\ -/* Now perform similar checks on the output variance value (if \ - required). This time we check that the square of the sum of \ - weights is not zero (since this might underflow before the sum of \ - weights). Again we also check to prevent the result overflowing the \ - output data type. */ \ - if ( ( Usevar ) && !bad_var ) { \ - wtsum_sq = wtsum * wtsum; \ - bad_var = ( wtsum_sq == (Xfloattype) 0.0 ); \ - if ( !bad_var ) { \ - val_var = sum_var / wtsum_sq; \ - if ( !( Xfloating ) ) { \ - bad_var = ( val_var <= lo_lim ) || ( val_var >= hi_lim ); \ - } \ - } \ - } \ -\ -/* Obtain the pixel offset into the output array. */ \ - off_out = offset[ point ]; \ -\ -/* Assign a bad output value (and variance) if required and count it. */ \ - if ( bad ) { \ - if( !Nobad ) { \ - out[ off_out ] = badval; \ - if ( Usevar ) out_var[ off_out ] = badval; \ - } \ - (*nbad)++; \ -\ -/* Otherwise, assign the interpolated value. If the output data type \ - is floating point, the result can be stored directly, otherwise we \ - must round to the nearest integer. */ \ - } else { \ - if ( Xfloating ) { \ - out[ off_out ] = (Xtype) val; \ - } else { \ - out[ off_out ] = (Xtype) ( val + ( ( val >= (Xfloattype) 0.0 ) ? \ - ( (Xfloattype) 0.5 ) : \ - ( (Xfloattype) -0.5 ) ) ); \ - } \ -\ -/* If a variance estimate is required but none can be obtained, then \ - store a bad output variance value and count it. */ \ - if ( Usevar ) { \ - if ( bad_var ) { \ - if( !Nobad ) out_var[ off_out ] = badval; \ - (*nbad)++; \ -\ -/* Otherwise, store the variance estimate, rounding to the nearest \ - integer if necessary. */ \ - } else { \ - if ( Xfloating ) { \ - out_var[ off_out ] = (Xtype) val_var; \ - } else { \ - out_var[ off_out ] = (Xtype) ( val_var + \ - ( ( val_var >= (Xfloattype) 0.0 ) ? \ - ( (Xfloattype) 0.5 ) : \ - ( (Xfloattype) -0.5 ) ) ); \ - } \ - } \ - } \ - } - -/* These subsidiary macros define limits for range checking of results - before conversion to the final data type. For each data type code - , HI_ gives the least positive floating point value which - just overflows that data type towards plus infinity, while LO_ - gives the least negative floating point value which just overflows - that data type towards minus infinity. Thus, a floating point value - must satisfy LO is a floating point type, the limits are not actually used, - but must be present to permit error-free compilation. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#define HI_LD ( 0.0L ) -#define LO_LD ( 0.0L ) -#endif -#define HI_D ( 0.0 ) -#define LO_D ( 0.0 ) -#define HI_F ( 0.0f ) -#define LO_F ( 0.0f ) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#define HI_L ( 0.5L + (long double) LONG_MAX ) -#define LO_L ( -0.5L + (long double) LONG_MIN ) -#define HI_UL ( 0.5L + (long double) ULONG_MAX ) -#define LO_UL ( -0.5L ) -#define HI_K ( 0.5L + (long double) LONG_MAX ) -#define LO_K ( -0.5L + (long double) LONG_MIN ) -#define HI_UK ( 0.5L + (long double) ULONG_MAX ) -#define LO_UK ( -0.5L ) -#else -#define HI_L ( 0.5 + (double) LONG_MAX ) -#define LO_L ( -0.5 + (double) LONG_MIN ) -#define HI_UL ( 0.5 + (double) ULONG_MAX ) -#define LO_UL ( -0.5 ) -#define HI_K ( 0.5 + (double) LONG_MAX ) -#define LO_K ( -0.5 + (double) LONG_MIN ) -#define HI_UK ( 0.5 + (double) ULONG_MAX ) -#define LO_UK ( -0.5 ) -#endif -#define HI_I ( 0.5 + (double) INT_MAX ) -#define LO_I ( -0.5 + (double) INT_MIN ) -#define HI_UI ( 0.5 + (double) UINT_MAX ) -#define LO_UI ( -0.5 ) -#define HI_S ( 0.5f + (float) SHRT_MAX ) -#define LO_S ( -0.5f + (float) SHRT_MIN ) -#define HI_US ( 0.5f + (float) USHRT_MAX ) -#define LO_US ( -0.5f ) -#define HI_B ( 0.5f + (float) SCHAR_MAX ) -#define LO_B ( -0.5f + (float) SCHAR_MIN ) -#define HI_UB ( 0.5f + (float) UCHAR_MAX ) -#define LO_UB ( -0.5f ) - -/* This subsidiary macro tests for negative variance values. This - check is required only for signed data types. */ -#define CHECK_FOR_NEGATIVE_VARIANCE(Xtype) \ - bad_var = bad_var || ( var < ( (Xtype) 0 ) ); - -/* Expand the main macro above to generate a function for each - required signed data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_INTERPOLATE_BLOCKAVE(LD,long double,1,long double,1) -MAKE_INTERPOLATE_BLOCKAVE(L,long int,0,long double,1) -MAKE_INTERPOLATE_BLOCKAVE(K,INT_BIG,0,long double,1) -#else -MAKE_INTERPOLATE_BLOCKAVE(L,long int,0,double,1) -MAKE_INTERPOLATE_BLOCKAVE(K,INT_BIG,0,double,1) -#endif -MAKE_INTERPOLATE_BLOCKAVE(D,double,1,double,1) -MAKE_INTERPOLATE_BLOCKAVE(F,float,1,float,1) -MAKE_INTERPOLATE_BLOCKAVE(I,int,0,double,1) -MAKE_INTERPOLATE_BLOCKAVE(S,short int,0,float,1) -MAKE_INTERPOLATE_BLOCKAVE(B,signed char,0,float,1) - -/* Re-define the macro for testing for negative variances to do - nothing. */ -#undef CHECK_FOR_NEGATIVE_VARIANCE -#define CHECK_FOR_NEGATIVE_VARIANCE(Xtype) - -/* Expand the main macro above to generate a function for each - required unsigned data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_INTERPOLATE_BLOCKAVE(UL,unsigned long int,0,long double,0) -MAKE_INTERPOLATE_BLOCKAVE(UK,UINT_BIG,0,long double,0) -#else -MAKE_INTERPOLATE_BLOCKAVE(UL,unsigned long int,0,double,0) -MAKE_INTERPOLATE_BLOCKAVE(UK,UINT_BIG,0,double,0) -#endif -MAKE_INTERPOLATE_BLOCKAVE(UI,unsigned int,0,double,0) -MAKE_INTERPOLATE_BLOCKAVE(US,unsigned short int,0,float,0) -MAKE_INTERPOLATE_BLOCKAVE(UB,unsigned char,0,float,0) - -/* Undefine the macros used above. */ -#undef CHECK_FOR_NEGATIVE_VARIANCE -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#undef HI_LD -#undef LO_LD -#endif -#undef HI_D -#undef LO_D -#undef HI_F -#undef LO_F -#undef HI_L -#undef LO_L -#undef HI_UL -#undef LO_UL -#undef HI_K -#undef LO_K -#undef HI_UK -#undef LO_UK -#undef HI_I -#undef LO_I -#undef HI_UI -#undef LO_UI -#undef HI_S -#undef LO_S -#undef HI_US -#undef LO_US -#undef HI_B -#undef LO_B -#undef HI_UB -#undef LO_UB -#undef CALC_AND_ASSIGN_OUTPUT -#undef ASSEMBLE_INPUT_ND -#undef ASSEMBLE_INPUT_2D -#undef ASSEMBLE_INPUT_1D -#undef MAKE_INTERPOLATE_BLOCKAVE - - -static void Invert( AstMapping *this, int *status ) { -/* -*++ -* Name: -c astInvert -f AST_INVERT - -* Purpose: -* Invert a Mapping. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astInvert( AstMapping *this ) -f CALL AST_INVERT( THIS, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -c This function inverts a Mapping by reversing the boolean sense -f This routine inverts a Mapping by reversing the boolean sense -* of its Invert attribute. If this attribute is zero (the -* default), the Mapping will transform coordinates in the way -* specified when it was created. If it is non-zero, the input and -* output coordinates will be inter-changed so that the direction -* of the Mapping is reversed. This will cause it to display the -* inverse of its original behaviour. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping. -f STATUS = INTEGER (Given and Returned) -f The global status. -*-- -*/ - -/* Local Variables: */ - int invert; /* New Invert attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Determine the new Invert attribute value. */ - invert = !astGetInvert( this ); - -/* Clear the old value. */ - astClearInvert( this ); - -/* If the resulting default value is not the one required, then set a - new value explicitly. */ - if ( astGetInvert( this ) != invert ) astSetInvert( this, invert ); -} - -static double J1Bessel( double x, int *status ) { -/* -* Name: -* J1Bessel - -* Purpose: -* Calculates the first-order Bessel function of the first kind. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* double J1Bessel( double x, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function calculates the value of the first-order Bessel function -* of the first kind. - -* Parameters: -* x -* The argument for J1. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The calculated J1(x) value. - -* Notes: -* - The algorithm is taken from the SCUBA routine SCULIB_BESSJ1, by -* J.Lightfoot. -* - This function does not perform error checking and does not -* generate errors. -*/ - -/* Local Variables: */ - static double p1 = 1.0; - static double p2 = 0.183105E-2; - static double p3 = -0.3516396496E-4; - static double p4 = 0.2457520174E-5; - static double p5 = -0.240337019E-6; - - static double q1 = 0.04687499995; - static double q2 = -0.2002690873E-3; - static double q3 = 0.8449199096E-5; - static double q4 = -0.88228987E-6; - static double q5 = 0.105787412E-6; - - static double r1 = 72362614232.0; - static double r2 = -7895059235.0; - static double r3 = 242396853.1; - static double r4 = -2972611.439; - static double r5 = 15704.48260; - static double r6 = -30.16036606; - - static double s1 = 144725228442.0; - static double s2 = 2300535178.0; - static double s3 = 18583304.74; - static double s4 = 99447.43394; - static double s5 = 376.9991397; - static double s6 = 1.0; - - double ax; - double xx; - double z; - double y; - double value; - int s; - -/* Calculate the value */ - ax = fabs( x ); - if( ax < 8.0 ) { - y = x*x; - value = x*( r1 + y*( r2 + y*( r3 + y*( r4 + y*( r5 + y*r6 ) ) ) ) ) / - ( s1 + y*( s2 + y*( s3 + y*( s4 + y*( s5 + y*s6 ) ) ) ) ); - } else { - s = ( x >= 0.0 ) ? 1 : -1; - z = 8.0 / ax; - y = z*z; - xx = ax - 2.356194491; - value = sqrt ( 0.636619772/ax )*( cos( xx )*( p1 + y*( p2 + y* - ( p3 + y*( p4 + y*p5 ) ) ) )-z*sin( xx )*( q1 + y*( q2 + y*( q3 + y* - ( q4 + y*q5 ) ) ) ) )*s; - } - - return value; - -} - -static int LinearApprox( AstMapping *this, const double *lbnd, - const double *ubnd, double tol, double *fit, int *status ) { -/* -*++ -* Name: -c astLinearApprox -f AST_LINEARAPPROX - -* Purpose: -* Obtain a linear approximation to a Mapping, if appropriate. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c int astLinearApprox( AstMapping *this, const double *lbnd, -c const double *ubnd, double tol, double *fit ) -f RESULT = AST_LINEARAPPROX( THIS, LBND, UBND, TOL, FIT, STATUS ) - -* Class Membership: -* Mapping function. - -* Description: -* This function tests the forward coordinate transformation -* implemented by a Mapping over a given range of input coordinates. If -* the transformation is found to be linear to a specified level of -* accuracy, then an array of fit coefficients is returned. These -* may be used to implement a linear approximation to the Mapping's -* forward transformation within the specified range of output coordinates. -* If the transformation is not sufficiently linear, no coefficients -* are returned. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping. -c lbnd -f LBND( * ) = DOUBLE PRECISION (Given) -c Pointer to an array of doubles -f An array -* containing the lower bounds of a box defined within the input -* coordinate system of the Mapping. The number of elements in this -* array should equal the value of the Mapping's Nin attribute. This -* box should specify the region over which linearity is required. -c ubnd -f UBND( * ) = DOUBLE PRECISION (Given) -c Pointer to an array of doubles -f An array -* containing the upper bounds of the box specifying the region over -* which linearity is required. -c tol -f TOL = DOUBLE PRECISION (Given) -* The maximum permitted deviation from linearity, expressed as -* a positive Cartesian displacement in the output coordinate -* space of the Mapping. If a linear fit to the forward -* transformation of the Mapping deviates from the true transformation -* by more than this amount at any point which is tested, then no fit -* coefficients will be returned. -c fit -f FIT( * ) = DOUBLE PRECISION (Returned) -c Pointer to an array of doubles -f An array -* in which to return the co-efficients of the linear -* approximation to the specified transformation. This array should -* have at least "( Nin + 1 ) * Nout", elements. The first Nout elements -* hold the constant offsets for the transformation outputs. The -* remaining elements hold the gradients. So if the Mapping has 2 inputs -* and 3 outputs the linear approximation to the forward transformation -* is: -* -c X_out = fit[0] + fit[3]*X_in + fit[4]*Y_in -f X_out = fit(1) + fit(4)*X_in + fit(5)*Y_in -* -c Y_out = fit[1] + fit[5]*X_in + fit[6]*Y_in -f Y_out = fit(2) + fit(6)*X_in + fit(7)*Y_in -* -c Z_out = fit[2] + fit[7]*X_in + fit[8]*Y_in -f Z_out = fit(3) + fit(8)*X_in + fit(9)*Y_in -* -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astLinearApprox() -f AST_LINEARAPPROX = LOGICAL -* If the forward transformation is sufficiently linear, -c a non-zero value is returned. Otherwise zero is returned -f .TRUE is returned. Otherwise .FALSE. is returned -* and the fit co-efficients are set to AST__BAD. - -* Notes: -* - This function fits the Mapping's forward transformation. To fit -* the inverse transformation, the Mapping should be inverted using -c astInvert -f AST_INVERT -* before invoking this function. -* - If a Mapping output is found to have a bad value (AST__BAD) at -* one or more of the test points used in the linearity test, then all -* the values in the returned fit that correspond to that output are -* set to AST__BAD. However, this does not affect the linearity tests -* on the other Mapping outputs - if they are all found to be linear -* then usable coefficients will be returned for them in the fit, and -* the function will return a -c non-zero value. -f .TRUE. value. -* Consequently, it may be necessary to check that the values in the -* returned fit are not AST__BAD before using them. If all Mapping -* outputs generate bad values, then -c zero is returned as the function value. -f .FALSE. is returned as the function value. -c - A value of zero -f - A value of .FALSE. -* will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*-- - -* Implementation Deficiencies: -* Sub-classes which implement linear mappings should probably -* over-ride this function to get better accuracy and faster execution, -* but currently they do not. - -*/ - -/* Local Variables: */ - AstPointSet *pset_in_f; /* PointSet for input fitting points */ - AstPointSet *pset_in_t; /* PointSet for input test points */ - AstPointSet *pset_out_f; /* PointSet for output fitting points */ - AstPointSet *pset_out_t; /* PointSet for output test points */ - double **ptr_in_f; /* Input coordinate array pointers */ - double **ptr_in_t; /* Input coordinate array pointers */ - double **ptr_out_f; /* Output coordinate array pointers */ - double **ptr_out_t; /* Output coordinate array pointers */ - double *grad; /* Pointer to matrix of gradients */ - double *zero; /* Pointer to array of zero point values */ - double diff; /* Difference in coordinate values */ - double err; /* Sum of squared error */ - double frac; /* Fraction of input coordinate range */ - double in1; /* Input coordinate value */ - double in2; /* Input coordinate value */ - double indiff; /* Difference in input coordinate values */ - double out1; /* Output coordinate value */ - double out2; /* Output coordinate value */ - double x0; /* Coordinate of grid centre */ - double y; /* Output coordinate (transformed) */ - double yfit; /* Coordinate resulting from fit */ - double z; /* Sum for calculating zero points */ - int *vertex; /* Pointer to flag array for vertices */ - int bad_output; /* Does the Mapping output generate bad values? */ - int coord_in; /* Loop counter for input coordinates */ - int coord_out; /* Loop counter for output coordinates. */ - int done; /* All vertices visited? */ - int face1; /* Index of first face coordinates */ - int face2; /* Index of second face coordinates */ - int face; /* Loop counter for faces */ - int ii; /* Index into gradient matrix */ - int linear; /* Mapping is linear? */ - int nc; /* Number of coeffs in fit */ - int ndim_in; /* Number of Mapping inputs */ - int ndim_out; /* Number of Mapping outputs */ - int npoint; /* Number of test points required */ - int point; /* Counter for points */ - int result; /* Returned flag */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialisation. */ - linear = 1; - grad = NULL; - zero = NULL; - -/* Get the number of Mapping output and inputs. */ - ndim_in = astGetNin( this ); - ndim_out = astGetNout( this ); - -/* Store the number of coefficients in the fit.*/ - nc = ( ndim_in + 1 ) * ndim_out; - -/* Initialise the supplied array to hold bad values. */ - for( ii = 0; ii < nc; ii++ ) fit[ ii ] = AST__BAD; - -/* Create a PointSet to hold input coordinates and obtain a pointer - to its coordinate arrays. */ - pset_in_f = astPointSet( 2 * ndim_in, ndim_in, "", status ); - ptr_in_f = astGetPoints( pset_in_f ); - if ( astOK ) { - -/* Set up and transform an initial set of points. */ -/* ---------------------------------------------- */ -/* Loop to set up input coordinates at the centre of each face of the - input grid, storing them in the PointSet created above. */ - point = 0; - for ( face = 0; face < ( 2 * ndim_in ); face++ ) { - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - ptr_in_f[ coord_in ][ point ] = - 0.5 * ( lbnd[ coord_in ] + ubnd[ coord_in ] ); - } - ptr_in_f[ face / 2 ][ point ] = ( face % 2 ) ? - ubnd[ face / 2 ] : lbnd[ face / 2 ]; - point++; - } - } - -/* Transform these coordinates into the output grid's coordinate system - and obtain an array of pointers to the resulting coordinate - data. */ - pset_out_f = astTransform( this, pset_in_f, 1, NULL ); - ptr_out_f = astGetPoints( pset_out_f ); - if ( astOK ) { - -/* Fit a linear approximation to the points. */ -/* ----------------------------------------- */ -/* Obtain pointers to the locations in the fit coefficients array - where the gradients and zero points should be stored. */ - grad = fit + ndim_out; - zero = fit; - -/* On the assumption that the transformation applied above is - approximately linear, loop to determine the matrix of gradients and - the zero points which describe it. */ - ii = 0; - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - bad_output = 0; - z = 0.0; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - -/* Find the indices of opposite faces in each input dimension. */ - face1 = 2 * coord_in; - face2 = face1 + 1; - -/* Obtain the input and output coordinates at these face centres. */ - in1 = ptr_in_f[ coord_in ][ face1 ]; - in2 = ptr_in_f[ coord_in ][ face2 ]; - out1 = ptr_out_f[ coord_out ][ face1 ]; - out2 = ptr_out_f[ coord_out ][ face2 ]; - -/* Check whether any transformed coordinates are bad. Mapping outputs - that are bad at one or more test points have bad values stored for the - corresponding coefficients in the returned fit, but do not invalidate - the linearity of the fit to other outputs. */ - if ( ( out1 == AST__BAD ) || ( out2 == AST__BAD ) ) { - bad_output = 1; - break; - } - -/* If possible, determine the gradient along this dimension, storing - it in the appropriate element of the gradient matrix. */ - indiff = in2 - in1; - if ( indiff != 0.0 ) { - grad[ ii++ ] = ( out2 - out1 ) / indiff; - } else { - grad[ ii++ ] = 0.0; - } - -/* Accumulate the sum used to determine the zero point. */ - z += ( out1 + out2 ); - } - -/* Determine the average zero point from all dimensions. */ - if( !bad_output ) zero[ coord_out ] = z / (double) ( 2 * ndim_in ); - } - -/* The zero points of the above fit will be appropriate to an input - coordinate system with an origin at the centre of the input grid - (we assume this to simplify the calculations above). To correct - for this, we transform the actual input coordinates of the - grid's centre through the matrix of gradients and subtract the - resulting coordinates from the zero point values. The zero points - are then correct for the actual output and input coordinate systems - we are using. Also, if all Mapping outputs generate bad values, flag - that we do not have a linear fit. */ - linear = 0; - ii = 0; - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - if( zero[ coord_out ] != AST__BAD ) { - linear = 1; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - x0 = 0.5 * ( lbnd[ coord_in ] + ubnd[ coord_in ] ); - zero[ coord_out ] -= grad[ ii++ ] * x0; - } - } else { - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - grad[ ii++ ] = AST__BAD; - } - } - } - } - -/* Annul the pointers to the PointSets used above. */ - pset_out_f = astAnnul( pset_out_f ); - pset_in_f = astAnnul( pset_in_f ); - -/* Calculate the number of test points required. */ -/* --------------------------------------------- */ -/* The linear fit obtained above, will (by construction) be exact - at the centre of each face of the input grid. However, it may - not fit anywhere else. We therefore set up some test points to - determine if it is an adequate approximation elsewhere. */ - if( astOK && linear ) { - -/* Calculate the number of test points required to place one at each - vertex of the grid. */ - npoint = 1; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - npoint *= 2; - } - -/* Now calculate the total number of test points required, also - allowing one at the centre, one at half the distance to each face, - and one at half the distance to each vertex. */ - npoint = 1 + 2 * ( ndim_in + npoint ); - -/* Set up test points in the input coordinate system. */ -/* --------------------------------------------------- */ -/* Create a PointSet to hold the test coordinates and obtain an array - of pointers to its coordinate data. */ - pset_in_t = astPointSet( npoint, ndim_in, "", status ); - ptr_in_t = astGetPoints( pset_in_t ); - if ( astOK ) { - -/* If the input array is 1-dimensional, the face and vertex positions - calculated below will co-incide. Therefore, we simply distribute - the required number of test points uniformly throughout the input - coordinate range (avoiding the end-points, where the fit has been - obtained). The coordinates are stored in the PointSet created - above. */ - if ( ndim_in == 1 ) { - for ( point = 0; point < npoint; point++ ) { - frac = ( (double) ( point + 1 ) ) / (double) ( npoint + 1 ); - ptr_in_t[ 0 ][ point ] = ( 1.0 - frac ) * lbnd[ 0 ] + - frac * ubnd[ 0 ]; - } - -/* Otherwise, generate one point at the grid centre (offset slightly - since the exact centre may not be very representative). */ - } else { - point = 0; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - ptr_in_t[ coord_in ][ point ] = - 0.49 * lbnd[ coord_in ] + 0.51 * ubnd[ coord_in ]; - } - point++; - -/* Similarly generate a point half way between the grid centre and the - centre of each face. Again introduce some small random offsets to break - any regularity in the grid. */ - for ( face = 0; face < ( 2 * ndim_in ); face++ ) { - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - ptr_in_t[ coord_in ][ point ] = - 0.48 * lbnd[ coord_in ] + 0.52 * ubnd[ coord_in ]; - } - ptr_in_t[ face / 2 ][ point ] = - ( 0.51 * ( ( ( face % 2 ) ? ubnd[ face / 2 ] : - lbnd[ face / 2 ] ) ) + - 0.49 * ptr_in_t[ face / 2 ][ 0 ] ); - point++; - } - -/* Allocate workspace and initialise flags for identifying the - vertices. */ - vertex = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - vertex[ coord_in ] = 0; - } - -/* Now loop to visit each input grid vertex. */ - done = 0; - do { - -/* Generate a test point at each vertex. */ - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - ptr_in_t[ coord_in ][ point ] = vertex[ coord_in ] ? - ubnd[ coord_in ] : - lbnd[ coord_in ]; - -/* Also place one half way between the grid centre and each vertex. */ - ptr_in_t[ coord_in ][ point + 1 ] = - ( 0.52 * ptr_in_t[ coord_in ][ point ] + - 0.48 * ptr_in_t[ coord_in ][ 0 ] ); - } - point += 2; - -/* Now update the array of vertex flags to identify the next vertex. */ - coord_in = 0; - do { - -/* The least significant dimension which does not have its upper bound - as one of the vertex coordinates is changed to use its upper bound - in the next vertex. */ - if ( !vertex[ coord_in ] ) { - vertex[ coord_in ] = 1; - break; - -/* Any less significant dimensions whose upper bounds are already - being used are changed to use their lower bounds in the next - vertex. */ - } else { - vertex[ coord_in ] = 0; - -/* All vertices have been visited when the most significant dimension - is changed back to using its lower bound. */ - done = ( ++coord_in == ndim_in ); - } - } while ( !done ); - } while ( !done ); - } - -/* Free the workspace used for vertex flags. */ - vertex = astFree( vertex ); - } - -/* Transform the test points. */ -/* -------------------------- */ -/* Use the Mapping to transform the test points into the output grid's - coordinate system, obtaining a pointer to the resulting arrays of - output coordinates. */ - pset_out_t = astTransform( this, pset_in_t, 1, NULL ); - ptr_out_t = astGetPoints( pset_out_t ); - -/* Test the linear fit for accuracy. */ -/* --------------------------------- */ -/* If OK so far, then loop to use this fit to transform each test - point and compare the result with the result of applying the - Mapping. */ - if ( astOK ) { - for ( point = 0; point < npoint; point++ ) { - -/* Initialise the fitting error for the current point. */ - err = 0.0; - -/* Obtain each output coordinate (produced by using the Mapping) in - turn and check that it is not bad. If it is, then store bad values for - the output's coefficients and pass on to the next output. */ - bad_output = 0; - ii = 0; - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - y = ptr_out_t[ coord_out ][ point ]; - if ( y == AST__BAD || zero[ coord_out ] == AST__BAD ) { - zero[ coord_out ] = AST__BAD; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - grad[ ii++ ] = AST__BAD; - } - bad_output++; - break; - } - -/* Apply the fitted transformation to the input coordinates to obtain - the approximate output coordinate value. */ - yfit = zero[ coord_out ]; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - yfit += grad[ ii++ ] * ptr_in_t[ coord_in ][ point ]; - } - -/* Form the sum of squared differences between the Mapping's - transformation and the fit. */ - diff = ( y - yfit ); - err += diff * diff; - } - -/* Test if the Cartesian distance between the true output coordinate - and the approximate one exceeds the accuracy tolerance. If this - happens for any test point, we declare the Mapping non-linear and - give up. Reduce the allowed tolerance in proproprtion to the number of - bad Mapping outputs that were found. */ - if ( sqrt( err ) > (tol*(ndim_out - bad_output))/ndim_out ) { - linear = 0; - break; - } - } - } - -/* Annul the pointers to the PointSets used above. */ - pset_out_t = astAnnul( pset_out_t ); - } - pset_in_t = astAnnul( pset_in_t ); - } - -/* If an error occurred, or the Mapping was found to be non-linear, - then set the coefficients to AST_BAD. Otherwise, set the returned flag - to indicate that the fit was succesful. */ - if ( !astOK || !linear ) { - for( ii = 0; ii < nc; ii++ ) fit[ ii ] = AST__BAD; - } else { - result = 1; - } - -/* Return the result. */ - return result; -} - -static double LocalMaximum( const MapData *mapdata, double acc, double fract, - double x[], int *status ) { -/* -* Name: -* LocalMaximum - -* Purpose: -* Find a local maximum in a Mapping function. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* double LocalMaximum( const MapData *mapdata, double acc, double fract, -* double x[], int *status ); - -* Class Membership: -* Mapping member function. - -* Description: -* This function finds a local maximum in the Mapping function -* supplied. It employs the modified simplex method (as -* implemented by UphillSimplex), but repeatedly re-starts the -* simplex algorithm and tests for convergence of successive -* maxima, so as to further improve robustness on difficult -* problems. - -* Parameters: -* mapdata -* Pointer to a MapData structure describing the Mapping -* function, its coordinate constraints, etc. -* acc -* The required accuracy with which the maximum is to be found. -* fract -* A value between 0.0 and 1.0 which determines the initial step -* length along each coordinate axis. It should be given as a -* fraction of the difference between the upper and lower -* constraint values for each axis (as specified in the -* "mapdata" structure). -* x -* Pointer to an array of double containing the coordinates of -* an initial estimate of the position of the maximum. On exit, -* this will be updated to contain the best estimate of the -* maximum's position, as found by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The best estimate of the Mapping function's maximum value. - -* Notes: -* - A value of AST__BAD will be returned, and no useful -* information about a solution will be produced, if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Constants: */ - const int maxcall = 1500; /* Maximum number of function evaluations */ - const int maxiter = 5; /* Maximum number of iterations */ - -/* Local Variables: */ - double *dx; /* Pointer to array of step lengths */ - double err; /* Simplex error estimate */ - double maximum; /* Simplex maximum value */ - double middle; /* Middle coordinate between bounds */ - double result; /* Result value to return */ - int coord; /* Loop counter for coordinates */ - int done; /* Iterations complete? */ - int iter; /* Loop counter for iterations */ - int ncall; /* Number of function calls (junk) */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialise to avoid compiler warnings. */ - err = 0.0; - -/* Allocate workspace. */ - dx = astMalloc( sizeof( double ) * (size_t) mapdata->nin ); - -/* Perform iterations to repeatedly identify a local maximum. */ - for ( iter = 0; astOK && ( iter < maxiter ); iter++ ) { - -/* Set up initial step lengths along each coordinate axis, adjusting - their signs to avoid placing points outside the coordinate - constraints (i.e. step away from the closer boundary on each - axis). */ - for ( coord = 0; coord < mapdata->nin; coord++ ) { - middle = 0.5 * ( mapdata->lbnd[ coord ] + mapdata->ubnd[ coord ] ); - dx[ coord ] = fract * ( mapdata->ubnd[ coord ] - - mapdata->lbnd[ coord ] ); - if ( x[ coord ] > middle ) dx[ coord ] = -dx[ coord ]; - } - -/* Find an approximation to a local maximum using the simplex method - and check for errors. */ - maximum = UphillSimplex( mapdata, acc, maxcall, dx, x, &err, &ncall, status ); - if ( astOK ) { - -/* Use this maximum value if no previous maximum has been found. */ - if ( result == AST__BAD ) { - result = maximum; - -/* Otherwise use it only if it improves on the previous maximum. */ - } else if ( maximum >= result ) { - -/* We iterate, re-starting the simplex algorithm from its previous - best position so as to guard against premature false - convergence. Iterations continue until the improvement in the - maximum is no greater than the required accuracy (and the simplex - algorithm itself has converged to the required accuracy). Note when - iterations should cease. */ - done = ( ( ( maximum - result ) <= acc ) && ( err <= acc ) ); - -/* Store the best maximum and quit iterating if appropriate. */ - result = maximum; - if ( done ) break; - } - -/* Otherwise, decrement the initial step size for the next iteration. */ - fract /= 1000.0; - } - } - -/* Free the workspace. */ - dx = astFree( dx ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* return the result. */ - return result; -} - -static void MapBox( AstMapping *this, - const double lbnd_in[], const double ubnd_in[], - int forward, int coord_out, - double *lbnd_out, double *ubnd_out, - double xl[], double xu[], int *status ) { -/* -*+ -* Name: -* astMapBox - -* Purpose: -* Find a bounding box for a Mapping. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* void astMapBox( AstMapping *this, -* const double lbnd_in[], const double ubnd_in[], -* int forward, int coord_out, -* double *lbnd_out, double *ubnd_out, -* double xl[], double xu[] ); - -* Class Membership: -* Mapping method. - -* Description: -* This function allows you to find the "bounding box" which just -* encloses another box after it has been transformed by a Mapping -* (using either its forward or inverse transformation). A typical -* use might be to calculate the size which an image would have -* after being transformed by the Mapping. -* -* The function works on one dimension at a time. When supplied -* with the lower and upper bounds of a rectangular region (box) of -* input coordinate space, it finds the lowest and highest values -* taken by a nominated output coordinate within that -* region. Optionally, it also returns the input coordinates where -* these bounding values are attained. It should be used repeatedly -* if the extent of the bounding box is required in more than one -* dimension. - -* Parameters: -* this -* Pointer to the Mapping. -* lbnd_in -* Pointer to an array of double, with one element for each -* Mapping input coordinate. This should contain the lower bound -* of the input box in each dimension. -* ubnd_in -* Pointer to an array of double, with one element for each -* Mapping input coordinate. This should contain the upper bound -* of the input box in each dimension. -* -* Note that it is permissible for the lower bound to exceed the -* corresponding upper bound, as the values will simply be -* swapped before use. -* forward -* If this value is non-zero, then the Mapping's forward -* transformation will be used to transform the input -* box. Otherwise, its inverse transformation will be used. -* -* (If the inverse transformation is selected, then references -* to "input" and "output" coordinates in this description -* should be transposed. For example, the size of the "lbnd_in" -* and "ubnd_in" arrays should match the number of output -* coordinates, as given by the Mapping's Nout attribute.) -* coord_out -* The (zero-based) index of the output coordinate for which the -* lower and upper bounds are required. -* lbnd_out -* Pointer to a double in which to return the lowest value taken -* by the nominated output coordinate within the specified -* region of input coordinate space. -* ubnd_out -* Pointer to a double in which to return the highest value -* taken by the nominated output coordinate within the specified -* region of input coordinate space. -* xl -* An optional pointer to an array of double, with one element -* for each Mapping input coordinate. If given, this array will -* be filled with the coordinates of an input point (although -* not necessarily a unique one) for which the nominated output -* coordinate takes the lower bound value returned in -* "*lbnd_out". -* -* If these coordinates are not required, a NULL pointer may be -* supplied. -* xu -* An optional pointer to an array of double, with one element -* for each Mapping input coordinate. If given, this array will -* be filled with the coordinates of an input point (although -* not necessarily a unique one) for which the nominated output -* coordinate takes the upper bound value returned in -* "*ubnd_out". -* -* If these coordinates are not required, a NULL pointer may be -* supplied. - -* Notes: -* - Any input points which are transformed by the Mapping to give -* output coordinates containing the value AST__BAD are regarded as -* invalid and are ignored, They will make no contribution to -* determining the output bounds, even although the nominated -* output coordinate might still have a valid value at such points. -* - An error will occur if the required output bounds cannot be -* found. Typically, this might occur if all the input points which -* the function considers turn out to be invalid (see above). The -* number of points considered before generating such an error is -* quite large, however, so this is unlikely to occur by accident -* unless valid points are restricted to a very small subset of the -* input coordinate space. -* - The values returned via "lbnd_out", "ubnd_out", "xl" and "xu" -* will be set to the value AST__BAD if this function should fail -* for any reason. Their initial values on entry will not be -* altered if the function is invoked with the global error status -* set. -*- - -* Implementation Notes: -* - This function implements the basic astMapBox method available -* via the protected interface to the Mapping class. The public -* interface to this method is provided by the astMapBoxId_ -* function. -*/ - -/* Local Variables: */ - MapData mapdata; /* Structure to describe Mapping function */ - double *x_l; /* Pointer to coordinate workspace */ - double *x_u; /* Pointer to coordinate workspace */ - double lbnd; /* Required lower bound */ - double ubnd; /* Required upper bound */ - int coord; /* Loop counter for coordinates. */ - int nin; /* Effective number of input coordinates */ - int nout; /* Effective number of output coordinates */ - int refine; /* Can bounds be refined? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialisation to avoid compiler warnings. */ - lbnd = AST__BAD; - ubnd = AST__BAD; - -/* Obtain the effective numbers of input and output coordinates for - the Mapping, taking account of which transformation is to be - used. */ - nin = forward ? astGetNin( this ) : astGetNout( this ); - nout = forward ? astGetNout( this ) : astGetNin( this ); - -/* Check that the output coordinate index supplied is valid and report - an error if it is not. Use public (one-based) coordinate numbering - in the error message. */ - if ( astOK ) { - if ( ( coord_out < 0 ) || ( coord_out >= nout ) ) { - astError( AST__BADCI, "astMapBox(%s): Output coordinate index (%d) " - "invalid - it should be in the range 1 to %d.", status, - astGetClass( this ), coord_out + 1, nout ); - } - } - -/* Initialise a MapData structure to describe the Mapping function - whose limits are to be found. Since it may be evaluated many - times, we attempt to simplify the Mapping supplied. */ - if ( astOK ) { - mapdata.mapping = astSimplify( this ); - -/* Store the number of input/output coordinates and the index of the - output coordinate in which we are interested. */ - mapdata.nin = nin; - mapdata.nout = nout; - mapdata.coord = coord_out; - -/* Note which Mapping transformation is being used. */ - mapdata.forward = forward; - -/* Store pointers to arrays which will contain the input coordinate - bounds. */ - mapdata.lbnd = astMalloc( sizeof( double ) * (size_t) nin ); - mapdata.ubnd = astMalloc( sizeof( double ) * (size_t) nin ); - -/* Create PointSets for passing coordinate data to and from the - Mapping. */ - mapdata.pset_in = astPointSet( 1, nin, "", status ); - mapdata.pset_out = astPointSet( 1, nout, "", status ); - -/* Obtain pointers to these PointSets' coordinate arrays. */ - mapdata.ptr_in = astGetPoints( mapdata.pset_in ); - mapdata.ptr_out = astGetPoints( mapdata.pset_out ); - -/* Allocate workspace for the returned input coordinates. */ - x_l = astMalloc( sizeof( double ) * (size_t) nin ); - x_u = astMalloc( sizeof( double ) * (size_t) nin ); - if ( astOK ) { - -/* Initialise the output bounds and corresponding input coordinates to - "unknown". */ - for ( coord = 0; coord < nin; coord++ ) { - x_l[ coord ] = AST__BAD; - x_u[ coord ] = AST__BAD; - -/* Initialise the input bounds, ensuring they are the correct way - around (if not already supplied this way). */ - mapdata.lbnd[ coord ] = ( lbnd_in[ coord ] < ubnd_in[ coord ] ) ? - lbnd_in[ coord ] : ubnd_in[ coord ]; - mapdata.ubnd[ coord ] = ( ubnd_in[ coord ] > lbnd_in[ coord ] ) ? - ubnd_in[ coord ] : lbnd_in[ coord ]; - } - -/* First examine a set of special input points to obtain an initial - estimate of the required output bounds. Do this only so long as the - number of points involved is not excessive. */ - if ( nin <= 12 ) { - refine = SpecialBounds( &mapdata, &lbnd, &ubnd, x_l, x_u, status ); - } else { - refine = 1; - } - -/* Then attempt to refine this estimate using a global search - algorithm. */ - if( refine ) GlobalBounds( &mapdata, &lbnd, &ubnd, x_l, x_u, status ); - -/* If an error occurred, generate a contextual error message. */ - if ( !astOK ) { - astError( astStatus, "Unable to find a bounding box for a %s.", status, - astGetClass( this ) ); - } - } - -/* Return the output bounds and, if required, the input coordinate - values which correspond with them. */ - if ( astOK ) { - *lbnd_out = lbnd; - *ubnd_out = ubnd; - for ( coord = 0; coord < nin; coord++ ) { - if ( xl ) xl[ coord ] = x_l[ coord ]; - if ( xu ) xu[ coord ] = x_u[ coord ]; - } - } - -/* Annul the simplified Mapping pointer and the temporary - PointSets. Also free the workspace. */ - mapdata.mapping = astAnnul( mapdata.mapping ); - mapdata.lbnd = astFree( mapdata.lbnd ); - mapdata.ubnd = astFree( mapdata.ubnd ); - mapdata.pset_in = astAnnul( mapdata.pset_in ); - mapdata.pset_out = astAnnul( mapdata.pset_out ); - x_l = astFree( x_l ); - x_u = astFree( x_u ); - } - -/* If an error occurred, then return bad bounds values and - coordinates. */ - if ( !astOK ) { - *lbnd_out = AST__BAD; - *ubnd_out = AST__BAD; - for ( coord = 0; coord < nin; coord++ ) { - if ( xl ) xl[ coord ] = AST__BAD; - if ( xu ) xu[ coord ] = AST__BAD; - } - } -} - -static double MapFunction( const MapData *mapdata, const double in[], - int *ncall, int *status ) { -/* -* Name: -* MapFunction - -* Purpose: -* Return the value of a selected transformed coordinate. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* double MapFunction( const MapData *mapdata, const double in[], -* int *ncall, int *status ); - -* Class Membership: -* Mapping member function. - -* Description: -* This function takes a set of input coordinates and applies a -* Mapping's coordinate transformation to them. It then returns the -* value of one of the transformed coordinates. -* -* It is provided for use by optimisation functions (e.g. those -* used for finding bounding boxes). The Mapping to be used and -* associated parameters (such as constraints on the range of input -* coordinates and the index of the output coordinate to be -* returned) are supplied in a MapData structure. The value -* returned will be negated if the "negate" component of this -* structure is non-zero. -* -* The value AST__BAD will be returned by this function if the -* input coordinates lie outside the constrained range given in -* the MapData structure, or if any of the transformed output -* coordinates is bad. - -* Parameters: -* mapdata -* Pointer to a MapData structure which describes the Mapping to -* be used. -* in -* A double array containing the input coordinates of a single point. -* ncall -* Pointer to an int containing a count of the number of times -* the Mapping's coordinate transformation has been used. This -* value will be updated to reflect any use made by this -* function. Normally, this means incrementing the value by 1, -* but this will be omitted if the input coordinates supplied -* are outside the constrained range so that no transformation -* is performed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The selected output coordinate value, or AST__BAD, as appropriate. - -* Notes: -* - A value of AST__BAD will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - double result; /* Result to be returned */ - int bad; /* Output coordinates invalid? */ - int coord_in; /* Loop counter for input coordinates */ - int coord_out; /* Loop counter for output coordinates */ - int outside; /* Input point outside bounds? */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* See if the input point lies outside the required bounds. */ - outside = 0; - for ( coord_in = 0; coord_in < mapdata->nin; coord_in++ ) { - if ( ( in[ coord_in ] < mapdata->lbnd[ coord_in ] ) || - ( in[ coord_in ] > mapdata->ubnd[ coord_in ] ) ) { - outside = 1; - break; - } - -/* Also store the input coordinates in the memory associated with the - Mapping's input PointSet. */ - mapdata->ptr_in[ coord_in ][ 0 ] = in[ coord_in ]; - } - -/* If the input coordinates are within bounds, transform them, using the - PointSets identified in the "mapdata" structure. */ - if ( !outside ) { - (void) astTransform( mapdata->mapping, mapdata->pset_in, - mapdata->forward, mapdata->pset_out ); - -/* Increment the number of calls to astTransform and check the error - status. */ - ( *ncall )++; - if ( astOK ) { - -/* If OK, test if any of the output coordinates is bad. */ - bad = 0; - for ( coord_out = 0; coord_out < mapdata->nout; coord_out++ ) { - if ( mapdata->ptr_out[ coord_out ][ 0 ] == AST__BAD ) { - bad = 1; - break; - } - } - -/* If not, then extract the required output coordinate, negating it if - necessary. */ - if ( !bad ) { - result = mapdata->ptr_out[ mapdata->coord ][ 0 ]; - if ( mapdata->negate ) result = -result; - } - } - } - -/* Return the result. */ - return result; -} - -static int MapList( AstMapping *this, int series, int invert, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -*+ -* Name: -* astMapList - -* Purpose: -* Decompose a Mapping into a sequence of simpler Mappings. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* int astMapList( AstMapping *this, int series, int invert, int *nmap, -* AstMapping ***map_list, int **invert_list ) - -* Class Membership: -* Mapping method. - -* Description: -* This function decomposes a Mapping (which, in derived classes, -* may be a compound Mapping) into a sequence of simpler Mappings -* which may be applied in sequence to achieve the same effect. The -* Mapping is decomposed as far as possible, but it is not -* guaranteed that this will necessarily yield any more than one -* Mapping, which may actually be the original one supplied. -* -* This function is provided to support both the simplification of -* compound Mappings, and the analysis of Mapping structure so that -* particular forms can be recognised. - -* Parameters: -* this -* Pointer to the Mapping to be decomposed (the Mapping is not -* actually modified by this function). -* series -* If this value is non-zero, an attempt will be made to -* decompose the Mapping into a sequence of equivalent Mappings -* which can be applied in series (i.e. one after the other). If -* it is zero, the decomposition will instead yield Mappings -* which can be applied in parallel (i.e. on successive sub-sets -* of the input/output coordinates). -* invert -* The value to which the Mapping's Invert attribute is to be -* (notionally) set before performing the -* decomposition. Normally, the value supplied here will be the -* actual Invert value obtained from the Mapping (e.g. using -* astGetInvert). Sometimes, however, when a Mapping is -* encapsulated within another structure, that structure may -* retain an Invert value (in order to prevent external -* interference) which should be used instead. -* -* Note that the actual Invert value of the Mapping supplied is -* not used (or modified) by this function. -* nmap -* The address of an int which holds a count of the number of -* individual Mappings in the decomposition. On entry, this -* should count the number of Mappings already in the -* "*map_list" array (below). On exit, it is updated to include -* any new Mappings appended by this function. -* map_list -* Address of a pointer to an array of Mapping pointers. On -* entry, this array pointer should either be NULL (if no -* Mappings have yet been obtained) or should point at a -* dynamically allocated array containing Mapping pointers -* ("*nmap" in number) which have been obtained from a previous -* invocation of this function. -* -* On exit, the dynamic array will be enlarged to contain any -* new Mapping pointers that result from the decomposition -* requested. These pointers will be appended to any previously -* present, and the array pointer will be updated as necessary -* to refer to the enlarged array (any space released by the -* original array will be freed automatically). -* -* The new Mapping pointers returned will identify a sequence of -* Mappings which, when applied in order, will perform a forward -* transformation equivalent to that of the original Mapping -* (after its Invert flag has first been set to the value -* requested above). The Mappings should be applied in series or -* in parallel according to the type of decomposition requested. -* -* All the Mapping pointers returned by this function should be -* annulled by the caller, using astAnnul, when no longer -* required. The dynamic array holding these pointers should -* also be freed, using astFree. -* invert_list -* Address of a pointer to an array of int. On entry, this array -* pointer should either be NULL (if no Mappings have yet been -* obtained) or should point at a dynamically allocated array -* containing Invert attribute values ("*nmap" in number) which -* have been obtained from a previous invocation of this -* function. -* -* On exit, the dynamic array will be enlarged to contain any -* new Invert attribute values that result from the -* decomposition requested. These values will be appended to any -* previously present, and the array pointer will be updated as -* necessary to refer to the enlarged array (any space released -* by the original array will be freed automatically). -* -* The new Invert values returned identify the values which must -* be assigned to the Invert attributes of the corresponding -* Mappings (whose pointers are in the "*map_list" array) before -* they are applied. Note that these values may differ from the -* actual Invert attribute values of these Mappings, which are -* not relevant. -* -* The dynamic array holding these values should be freed by the -* caller, using astFree, when no longer required. - -* Returned Value: -* A non-zero value is returned if the supplied Mapping contained any -* inverted CmpMaps. - -* Notes: -* - It is unspecified to what extent the original Mapping and the -* individual (decomposed) Mappings are -* inter-dependent. Consequently, the individual Mappings cannot be -* modified without risking modification of the original. -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then the *nmap value, the -* list of Mapping pointers and the list of Invert values will all -* be returned unchanged. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Since we are dealing with a basic Mapping, only one new Mapping - pointer will be returned. Extend the dynamic arrays to accommodate - this Mapping. */ - *map_list = astGrow( *map_list, *nmap + 1, sizeof( AstMapping * ) ); - *invert_list = astGrow( *invert_list, *nmap + 1, sizeof( int ) ); - if ( astOK ) { - -/* Return the invert flag value for the Mapping and a clone of the - Mapping pointer. */ - ( *invert_list )[ *nmap ] = ( invert != 0 ); - ( *map_list )[ *nmap ] = astClone( this ); - -/* If OK, return the new Mapping count. */ - if ( astOK ) ( *nmap )++; - } - - return 0; -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -*+ -* Name: -* astMapMerge - -* Purpose: -* Simplify a sequence of Mappings. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* int astMapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list ) - -* Class Membership: -* Mapping method. - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated Mapping in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated Mapping with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated Mapping which is to be merged with -* its neighbours. This should be a cloned copy of the Mapping -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* Mapping it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated Mapping resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* This is the default method which is inherited by all Mappings which - do not explicitly provide their own simplification method. Return - -1 to indicate that no simplification is provided. */ - return -1; -} - -static int *MapSplit( AstMapping *this, int nin, const int *in, - AstMapping **map, int *status ){ -/* -*+ -* Name: -* astMapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* Mapping. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* int *astMapSplit( AstMapping *this, int nin, const int *in, -* AstMapping **map ) - -* Class Membership: -* Mapping method. - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing Mapping. This is only possible if the specified inputs -* correspond to some subset of the Mapping outputs. That is, there -* must exist a subset of the Mapping outputs for which each output -* depends only on the selected Mapping inputs, and not on any of the -* inputs which have not been selected. Also, any output which is not in -* this subset must not depend on any of the selected inputs. If these -* conditions are not met by the supplied Mapping, then a NULL Mapping -* is returned. - -* Parameters: -* this -* Pointer to the Mapping to be split (the Mapping is not -* actually modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied Mapping, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be differetn to "nin"). A NULL pointer will be -* returned if the supplied Mapping has no subset of outputs which -* depend only on the selected inputs. The returned Mapping is a -* deep copy of the required parts of the supplied Mapping. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied Mapping. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*- - -* Implementation Notes: -* - This function implements the basic astMapSplit method available -* via the protected interface to the Mapping class. The public -* interface to this method is provided by the astMapSplitId_ -* function. -*/ - -/* Local Variables: */ - AstCmpMap *rmap; /* Unsimplified result mapping */ - AstPermMap *pm; /* PermMap which rearranges the inputs */ - int *outperm; /* PermMap output axis permutation array */ - int *result; /* Pointer to returned array */ - int iin; /* Input index */ - int iout; /* Output index */ - int mapnin; /* Number of Mapping inputs */ - int nout; /* No of outputs */ - int ok; /* Can the supplied "in" array be used? */ - int perm; /* Are the inputs permuted? */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Verify the input axis indices.*/ - mapnin = astGetNin( this ); - for( iin = 0; iin < nin; iin++ ){ - if( in[ iin ] < 0 || in[ iin ] >= mapnin ) { - astError( AST__AXIIN, "astMapSplit(%s): One of the supplied Mapping " - "input indices has value %d which is invalid; it should " - "be in the range 1 to %d.", status, astGetClass( this ), - in[ iin ] + 1, mapnin ); - break; - } - } - -/* Since we are dealing with a basic Mapping, we can only create the - required output Mapping if all inputs are being selected. */ - if( nin == mapnin ) { - -/* The inputs may have been selected in a different order to that in - which they occur in the supplied Mapping. We therefore create a - PermMap which rearranges the inputs into the order they have in the - supplied Mapping. The supplied "in" array can act as the PermMap's - "inperm" array. Allocate memory for the "outperm" array. */ - outperm = astMalloc( sizeof(int)*(size_t) nin ); - if( astOK ) { - -/* Store the input index for each output in the outperm array and check that - each input has been selected once and only once. Also set a flag - indicating if a PermMap is needed. */ - perm = 0; - ok = 1; - for( iout = 0; iout < nin; iout++ ) outperm[ iout ] = -1; - for( iin = 0; iin < nin; iin++ ) { - iout = in[ iin ]; - if( outperm[ iout ] != -1 ) { - ok = 0; - break; - } else { - outperm[ iout ] = iin; - } - } - for( iout = 0; iout < nin; iout++ ) { - if( outperm[ iout ] == -1 ) { - ok = 0; - break; - } else if( outperm[ iout ] != iout ) { - perm = 1; - } - } - if( ok ) { - -/* Allocate the array to hold the returned output indices. */ - nout = astGetNout( this ); - result = astMalloc( sizeof(int)*(size_t) nout ); - if( astOK ) { - -/* The outputs are copied from the supplied Mapping. */ - for( iout = 0; iout < nout; iout++ ) result[ iout ] = iout; - -/* If the inputs are to be permuted, create the PermMap. */ - if( perm ) { - pm = astPermMap( nin, in, nin, outperm, NULL, "", status ); - -/* The returned Mapping is a series CmpMap containing this PermMap - followed by the supplied Mapping. */ - rmap = astCmpMap( pm, this, 1, "", status ); - *map = astSimplify( rmap ); - rmap = astAnnul( rmap ); - -/* Annul the PermMap pointer. */ - pm = astAnnul( pm ); - -/* If no input permutation is needed, the resturned Mapping is just the - supplied Mapping. */ - } else { - *map = astClone( this ); - } - } - } - -/* Free resources. */ - outperm = astFree( outperm ); - } - } - -/* Free resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static double MatrixDet( int nrow, int ncol, const double *matrix, int *status ){ -/* -* Name: -* MatrixDet - -* Purpose: -* Return the determinant of a matrix. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* double MatrixDet( int nrow, int ncol, const double *matrix, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function returns the determinant of the supplied matrix. Any -* rows or columns that hold only zeros or AST_BAD values are first -* removed from the matrix. If the resulting matrix is not square, a -* value of AST__BAD is returned for the determinant. - -* Parameters: -* nrow -* The number of rows in the matrix. -* ncol -* The number of columns in the matrix. -* matrix -* The matrix element values. The first row of "ncol" elements -* should be supplied first, followed by the second row, etc. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The determinant, or AST__BAD if the determinant could not be -* caclculated. -*/ - -/* Local Variables: */ - const double *sqmat; - const double *m; - double *a; - double *y; - double result; - int *iw; - int *usecol; - int *userow; - int i; - int icol; - int irow; - int jf; - int ncoluse; - int ndim; - int nrowuse; - -/* Initialise */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise... */ - sqmat = NULL; - nrowuse = 0; - ncoluse = 0; - -/* Flag any rows and columns that should be ignored because they contain - only bad values or zeros. */ - userow = astCalloc( nrow, sizeof( *userow ) ); - usecol = astCalloc( ncol, sizeof( *userow ) ); - if( astOK ) { - m = matrix; - for( irow = 0; irow < nrow; irow++ ) { - for( icol = 0; icol < ncol; icol++,m++ ) { - if( *m != AST__BAD && *m != 0.0 ) { - usecol[ icol ] = 1; - userow[ irow ] = 1; - } - } - } - -/* Find the number of usable rows and columns. */ - for( irow = 0; irow < nrow; irow++ ) { - if( userow[ irow ] ) nrowuse++; - } - - for( icol = 0; icol < ncol; icol++ ) { - if( usecol[ icol ] ) ncoluse++; - } - } - -/* Return AST__BAD if the resulting matrix is not square. */ - if( ncoluse == nrowuse ) { - ndim = ncoluse; - -/* If any rows or columns contained just bad or zero values, create a new - matrix that excludes them. */ - if( ncol > ndim || nrow > ndim ) { - sqmat = astMalloc( ndim*ndim*sizeof(*sqmat) ); - if( astOK ) { - m = matrix; - a = (double *) sqmat; - for( irow = 0; irow < nrow; irow++ ) { - if( userow[ irow ] ) { - for( icol = 0; icol < ncol; icol++,m++ ) { - if( usecol[ icol ] ) *(a++) = *m; - } - } else { - m += ncol; - } - } - } - -/* If no rows or columns contained just bad values, use the supplied - matrix. */ - } else { - sqmat = matrix; - } - -/* Calculate the determinant of the modified matrix */ - if( ndim == 1 ) { - result = sqmat[ 0 ]; - - } else if( ndim == 2 ) { - result = sqmat[ 0 ]*sqmat[ 3 ] - sqmat[ 1 ]*sqmat[ 2 ]; - - } else { - a = astStore( NULL, sqmat, sizeof( double )*(size_t) (ndim*ndim) ); - iw = astMalloc( sizeof( int )*(size_t) ndim ); - y = astMalloc( sizeof( double )*(size_t) ndim ); - if( y ) { - for( i = 0; i < ndim; i++ ) y[ i ] = 1.0; - palDmat( ndim, a, y, &result, &jf, iw ); - } - y = astFree( y ); - iw = astFree( iw ); - a = astFree( a ); - } - - } - -/* Free the square matrix if it was allocated here. */ - if( sqmat != matrix ) sqmat = astFree( (void *) sqmat ); - -/* Free the usable row/column flags. */ - userow = astFree( userow ); - usecol = astFree( usecol ); - - return result; -} - -static double MaxD( double a, double b, int *status ) { -/* -* Name: -* MaxD - -* Purpose: -* Return the maximum of two double values. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* double MaxD( double a, double b, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function returns the maximum of two double values. - -* Parameters: -* a -* The first value. -* b -* The second value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The maximum. -*/ - -/* Return the larger value. */ - return ( a > b ) ? a : b; -} - -static int MaxI( int a, int b, int *status ) { -/* -* Name: -* MaxI - -* Purpose: -* Return the maximum of two integer values. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MaxI( int a, int b, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function returns the maximum of two integer values. - -* Parameters: -* a -* The first value. -* b -* The second value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The maximum. -*/ - -/* Return the larger value. */ - return ( a > b ) ? a : b; -} - -static int MinI( int a, int b, int *status ) { -/* -* Name: -* MinI - -* Purpose: -* Return the minimum of two integer values. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MinI( int a, int b, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function returns the minimum of two integer values. - -* Parameters: -* a -* The first value. -* b -* The second value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The minimum. -*/ - -/* Return the smaller value. */ - return ( a < b ) ? a : b; -} - -static double NewVertex( const MapData *mapdata, int lo, double scale, - double x[], double f[], int *ncall, double xnew[], int *status ) { -/* -* Name: -* NewVertex - -* Purpose: -* Locate a new vertex for a simplex. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* double NewVertex( const MapData *mapdata, int lo, double scale, -* double x[], double f[], int *ncall, double xnew[], int *status ); - -* Class Membership: -* Mapping member function. - -* Description: -* This function is provided for use during optimisation of a -* Mapping function using the simplex method. It generates the -* coordinates of a new simplex vertex and evaluates the Mapping -* function at that point. If the function's value is better then -* (i.e. larger than) the value at the previously worst vertex, -* then it is used to replace that vertex. - -* Parameters: -* mapdata -* Pointer to a MapData structure which describes the Mapping -* function to be used. -* lo -* The (zero-based) index of the simplex vertex which initially -* has the worst (lowest) value. -* scale -* The scale factor to be used to generate the new vertex. The -* distance of the worst vertex from the centre of the face -* opposite it is scaled by this factor to give the new vertex -* position. Negative factors result in reflection through this -* opposite face. -* x -* An array of double containing the coordinates of the vertices -* of the simplex. The coordinates of the first vertex are -* stored first, then those of the second vertex, etc. This -* array will be updated by this function if the new vertex is -* used to replace an existing one. -* f -* An array of double containing the Mapping function values at -* each vertex of the simplex. This array will be updated by -* this function if the new vertex is used to replace an -* existing one. -* ncall -* Pointer to an int containing a count of the number of times -* the Mapping function has been invoked. This value will be -* updated to reflect the actions of this function. -* xnew -* An array of double with one element for each input coordinate -* of the Mapping function. This is used as workspace. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Mapping function value at the new vertex. This value is -* returned whether or not the new vertex replaces an existing one. - -* Notes: -* - A value of AST__BAD will be returned by this function if it is -* invoked with the global error status set, or if it should fail -* for any reason. -* - A value of AST__BAD will also be returned if the new vertex -* lies outside the constrained range of input coordinates -* associated with the Mapping function (as specified in the -* MapData structure supplied) or if any of the transformed output -* coordinates produced by the underlying Mapping is bad. In either -* case the new vertex will not be used to replace an existing one. -*/ - -/* Local Variables: */ - double fnew; /* Function value at new vertex */ - double xface; /* Coordinate of centre of magnification */ - int coord; /* Loop counter for coordinates */ - int ncoord; /* Number of coordinates */ - int nvertex; /* Number of simplex vertices */ - int vertex; /* Loop counter for vertices */ - -/* Initialise. */ - fnew = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return fnew; - -/* Obtain the number of Mapping input coordinates from the MapData - structure and calculate the number of simplex vertices. */ - ncoord = mapdata->nin; - nvertex = ncoord + 1; - -/* Loop to obtain each coordinate of the new vertex. */ - for ( coord = 0; coord < ncoord; coord++ ) { - -/* Loop over all vertices except the lowest one and average their - coordinates. This gives the coordinate of the centre of the face - opposite the lowest vertex, which will act as the centre of - magnification. */ - xface = 0.0; - for ( vertex = 0; vertex < nvertex; vertex++ ) { - if ( vertex != lo ) { - -/* Divide each coordinate by the number of vertices as the sum is - accumulated in order to minimise the risk of overflow. */ - xface += x[ vertex * ncoord + coord ] / - ( (double ) ( nvertex - 1 ) ); - } - } - -/* Magnify the lowest vertex's distance from this point by the - required factor to give the coordinates of the new vertex. */ - xnew[ coord ] = xface + ( x[ lo * ncoord + coord ] - xface ) * scale; - } - -/* Evaluate the Mapping function at the new vertex. */ - fnew = MapFunction( mapdata, xnew, ncall, status ); - -/* If the result is not bad and exceeds the previous value at the - lowest vertex, then replace the lowest vertex with this new one. */ - if ( astOK && ( fnew != AST__BAD ) && ( fnew > f[ lo ] ) ) { - for ( coord = 0; coord < ncoord; coord++ ) { - x[ lo * ncoord + coord ] = xnew[ coord ]; - } - f[ lo ] = fnew; - } - -/* Return the value at the new vertex. */ - return fnew; -} - -static int QuadApprox( AstMapping *this, const double lbnd[2], - const double ubnd[2], int nx, int ny, double *fit, - double *rms, int *status ){ -/* -*++ -* Name: -c astQuadApprox -f AST_QUADAPPROX - -* Purpose: -* Obtain a quadratic approximation to a 2D Mapping. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c int QuadApprox( AstMapping *this, const double lbnd[2], -c const double ubnd[2], int nx, int ny, double *fit, -c double *rms ) -f RESULT = AST_QUADAPPROX( THIS, LBND, UBND, NX, NY, FIT, RMS, STATUS ) - -* Class Membership: -* Mapping function. - -* Description: -* This function returns the co-efficients of a quadratic fit to the -* supplied Mapping over the input area specified by -c "lbnd" and "ubnd". -f LBND and UBND. -* The Mapping must have 2 inputs, but may have any number of outputs. -* The i'th Mapping output is modelled as a quadratic function of the -* 2 inputs (x,y): -* -* output_i = a_i_0 + a_i_1*x + a_i_2*y + a_i_3*x*y + a_i_4*x*x + -* a_i_5*y*y -* -c The "fit" -f The FIT -* array is returned holding the values of the co-efficients a_0_0, -* a_0_1, etc. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping. -c lbnd -f LBND( * ) = DOUBLE PRECISION (Given) -c Pointer to an array of doubles -f An array -* containing the lower bounds of a box defined within the input -* coordinate system of the Mapping. The number of elements in this -* array should equal the value of the Mapping's Nin attribute. This -* box should specify the region over which the fit is to be -* performed. -c ubnd -f UBND( * ) = DOUBLE PRECISION (Given) -c Pointer to an array of doubles -f An array -* containing the upper bounds of the box specifying the region over -* which the fit is to be performed. -c nx -f NX = INTEGER (Given) -* The number of points to place along the first Mapping input. The -* first point is at -c "lbnd[0]" and the last is at "ubnd[0]". -f LBND( 1 ) and the last is at UBND( 1 ). -* If a value less than three is supplied a value of three will be used. -c ny -f NY = INTEGER (Given) -* The number of points to place along the second Mapping input. The -* first point is at -c "lbnd[1]" and the last is at "ubnd[1]". -f LBND( 2 ) and the last is at UBND( 2 ). -* If a value less than three is supplied a value of three will be used. -c fit -f FIT( * ) = DOUBLE PRECISION (Returned) -c Pointer to an array of doubles -f An array -* in which to return the co-efficients of the quadratic -* approximation to the specified transformation. This array should -* have at least "6*Nout", elements. The first 6 elements hold the -* fit to the first Mapping output. The next 6 elements hold the -* fit to the second Mapping output, etc. So if the Mapping has 2 -* inputs and 2 outputs the quadratic approximation to the forward -* transformation is: -* -c X_out = fit[0] + fit[1]*X_in + fit[2]*Y_in + fit[3]*X_in*Y_in + -c fit[4]*X_in*X_in + fit[5]*Y_in*Y_in -c Y_out = fit[6] + fit[7]*X_in + fit[8]*Y_in + fit[9]*X_in*Y_in + -c fit[10]*X_in*X_in + fit[11]*Y_in*Y_in -f X_out = fit(1) + fit(2)*X_in + fit(3)*Y_in + fit(4)*X_in*Y_in + -f fit(5)*X_in*X_in + fit(6)*Y_in*Y_in -f Y_out = fit(7) + fit(8)*X_in + fit(9)*Y_in + fit(10)*X_in*Y_in + -f fit(11)*X_in*X_in + fit(12)*Y_in*Y_in -* -c rms -f RMS = DOUBLE PRECISION (Returned) -c Pointer to a double in which to return the -f The -* RMS residual between the fit and the Mapping, summed over all -* Mapping outputs. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astQuadApprox() -f AST_QUADAPPROX = LOGICAL -* If a quadratic approximation was created, -c a non-zero value is returned. Otherwise zero is returned -f .TRUE is returned. Otherwise .FALSE. is returned -* and the fit co-efficients are set to AST__BAD. - -* Notes: -* - This function fits the Mapping's forward transformation. To fit -* the inverse transformation, the Mapping should be inverted using -c astInvert -f AST_INVERT -* before invoking this function. -c - A value of zero -f - A value of .FALSE. -* will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*-- - -*/ - -/* Local Variables: */ - AstPointSet *pset1; - AstPointSet *pset2; - double **pdat1; - double **pdat2; - double *ofit; - double *px; - double *py; - double *pz; - double det; - double dx; - double dy; - double mat[ 6*6 ]; - double sx2; - double sx2y2; - double sx2y; - double sx3; - double sx3y; - double sx4; - double sx; - double sxy2; - double sxy3; - double sxy; - double sy2; - double sy3; - double sy4; - double sy; - double sz; - double sz2; - double szx2; - double szx; - double szxy; - double szy2; - double szy; - double x; - double xx; - double xy; - double y; - double yy; - double z; - int i; - int iout; - int iw[ 6 ]; - int ix; - int iy; - int n; - int nin; - int nout; - int np; - int ntot; - int result; - int sing; - -/* Initialise the returned values. */ - result = 0; - fit[ 0 ] = AST__BAD; - *rms = AST__BAD; - ntot = 0; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Get the number of Mapping inputs and outputs. Report an error if not - correct. */ - nin = astGetI( this, "Nin" ); - nout = astGetI( this, "Nout" ); - if( nin != 2 && astOK ) { - astError( AST__BADNI, "astQuadApprox(%s): Input Mapping has %d %s - " - "it must have 2 inputs.", status, astGetClass( this ), nin, - (nin==1)?"input":"inputs" ); - } - -/* Ensure we are using at least 3 points on each of the two input axes. */ - if( nx < 3 ) nx = 3; - if( ny < 3 ) ny = 3; - -/* Get the total number of grid points. */ - np = nx*ny; - -/* Create a PointSet to hold the 2D grid of input positions. */ - pset1 = astPointSet( np, 2, " ", status ); - pdat1 = astGetPoints( pset1 ); - -/* Create a PointSet to hold the N-D grid of output positions. */ - pset2 = astPointSet( np, nout, " ", status ); - pdat2 = astGetPoints( pset2 ); - -/* Check the memory allocation (and everything else) was succesful. */ - if( astOK ) { - -/* Find the cell dimensions on X and Y input axes. */ - dx = ( ubnd[ 0 ] - lbnd[ 0 ] )/( nx - 1 ); - dy = ( ubnd[ 1 ] - lbnd[ 1 ] )/( ny - 1 ); - -/* Create a regular grid of input positions. */ - px = pdat1[ 0 ]; - py = pdat1[ 1 ]; - for( iy = 0; iy < ny; iy++ ) { - x = lbnd[ 0 ]; - y = lbnd[ 1 ] + iy*dy; - for( ix = 0; ix < nx; ix++ ) { - *(px++) = x; - *(py++) = y; - x += dx; - } - } - -/* Use the supplied Mapping to transform this grid into the output space. */ - (void) astTransform( this, pset1, 1, pset2 ); - -/* Assume the approximation can be created. */ - result = 1; - *rms = 0.0; - -/* Loop round each Mapping output. */ - for( iout = 0; iout < nout && astOK; iout++ ) { - -/* Get a pointer to the first element of the fit array for this output. */ - ofit = fit + 6*iout; - -/* Form the required sums. */ - n = 0; - sx = 0.0; - sy = 0.0; - sxy = 0.0; - sx2 = 0.0; - sy2 = 0.0; - sx2y = 0.0; - sx3 = 0.0; - sxy2 = 0.0; - sy3 = 0.0; - sx2y2 = 0.0; - sx3y = 0.0; - sxy3 = 0.0; - sx4 = 0.0; - sy4 = 0.0; - sz = 0.0; - sz2 = 0.0; - szx = 0.0; - szy = 0.0; - szxy = 0.0; - szx2 = 0.0; - szy2 = 0.0; - - px = pdat1[ 0 ]; - py = pdat1[ 1 ]; - pz = pdat2[ iout ]; - - for( i = 0; i < np; i++ ) { - x = *(px++); - y = *(py++); - z = *(pz++); - - if( z != AST__BAD ) { - xx = x*x; - yy = y*y; - xy = x*y; - - n++; - sx += x; - sy += y; - sxy += xy; - sx2 += xx; - sy2 += yy; - sx2y += xx*y; - sx3 += xx*x; - sxy2 += x*yy; - sy3 += yy*y; - sx2y2 += xx*yy; - sx3y += xx*xy; - sxy3 += xy*yy; - sx4 += xx*xx; - sy4 += yy*yy; - sz += z; - sz2 += z*z; - szx += z*x; - szy += z*y; - szxy += z*xy; - szx2 += z*xx; - szy2 += z*yy; - } - } - -/* Form a matrix (M) and vector (V) such that M.X = V, where X is the - solution vector holding the required best fit parameter values (V is - stored in ofit). */ - mat[ 0 ] = n; - mat[ 1 ] = sx; - mat[ 2 ] = sy; - mat[ 3 ] = sxy; - mat[ 4 ] = sx2; - mat[ 5 ] = sy2; - - mat[ 6 ] = sx; - mat[ 7 ] = sx2; - mat[ 8 ] = sxy; - mat[ 9 ] = sx2y; - mat[ 10 ] = sx3; - mat[ 11 ] = sxy2; - - mat[ 12 ] = sy; - mat[ 13 ] = sxy; - mat[ 14 ] = sy2; - mat[ 15 ] = sxy2; - mat[ 16 ] = sx2y; - mat[ 17 ] = sy3; - - mat[ 18 ] = sxy; - mat[ 19 ] = sx2y; - mat[ 20 ] = sxy2; - mat[ 21 ] = sx2y2; - mat[ 22 ] = sx3y; - mat[ 23 ] = sxy3; - - mat[ 24 ] = sx2; - mat[ 25 ] = sx3; - mat[ 26 ] = sx2y; - mat[ 27 ] = sx3y; - mat[ 28 ] = sx4; - mat[ 29 ] = sx2y2; - - mat[ 30 ] = sy2; - mat[ 31 ] = sxy2; - mat[ 32 ] = sy3; - mat[ 33 ] = sxy3; - mat[ 34 ] = sx2y2; - mat[ 35 ] = sy4; - - ofit[ 0 ] = sz; - ofit[ 1 ] = szx; - ofit[ 2 ] = szy; - ofit[ 3 ] = szxy; - ofit[ 4 ] = szx2; - ofit[ 5 ] = szy2; - -/* Now find the solution vector (the solution over-writes teh current - contents of "ofit"). */ - palDmat( 6, mat, ofit, &det, &sing, iw ); - -/* If the fit failed, fill the coefficient array with bad values. */ - if( sing != 0 ) { - for( i = 0; i < 6; i++ ) ofit[ i ] = AST__BAD; - result = 0; - break; - -/* If the fit succeeded, update the summ of the squared residuals. */ - } else { - ntot += n; - *rms += ofit[ 0 ]*ofit[ 0 ]*n + - 2*ofit[ 0 ]*ofit[ 1 ]*sx + - 2*ofit[ 0 ]*ofit[ 2 ]*sy + - 2*( ofit[ 0 ]*ofit[ 3 ] + ofit[ 1 ]*ofit[ 2 ] )*sxy + - ( 2*ofit[ 0 ]*ofit[ 4 ] + ofit[ 1 ]*ofit[ 1 ] )*sx2 + - ( 2*ofit[ 0 ]*ofit[ 5 ] + ofit[ 2 ]*ofit[ 2 ] )*sy2 + - 2*ofit[ 1 ]*ofit[ 4 ]*sx3 + - 2*( ofit[ 1 ]*ofit[ 3 ] + ofit[ 2 ]*ofit[ 4 ] )*sx2y + - 2*( ofit[ 1 ]*ofit[ 5 ] + ofit[ 2 ]*ofit[ 3 ] )*sxy2 + - 2*ofit[ 2 ]*ofit[ 5 ]*sy3 + - ofit[ 4 ]*ofit[ 4 ]*sx4 + - 2*ofit[ 3 ]*ofit[ 4 ]*sx3y + - ( 2*ofit[ 4 ]*ofit[ 5 ] + ofit[ 3 ]*ofit[ 3 ] )*sx2y2 + - 2*ofit[ 3 ]*ofit[ 5 ]*sxy3 + - ofit[ 5 ]*ofit[ 5 ]*sy4 + - sz2 - 2*( - ofit[ 0 ]*sz + - ofit[ 1 ]*szx + - ofit[ 2 ]*szy + - ofit[ 3 ]*szxy + - ofit[ 4 ]*szx2 + - ofit[ 5 ]*szy2 - ); - } - } - } - -/* Free resources. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Return AST__BAD if anything went wrong. */ - if( !astOK || ntot == 0 ) { - result = 0; - fit[ 0 ] = AST__BAD; - *rms = AST__BAD; - -/* Otherwise normalise the returned RMS. */ - } else { - if( *rms > 0.0 ) { - *rms = sqrt( *rms/ntot ); - } else { - *rms = 0.0; - } - } - -/* Return result */ - return result; -} - -static double Random( long int *seed, int *status ) { -/* -* Name: -* Random - -* Purpose: -* Return a pseudo-random value in the range 0 to 1. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* double Random( long int *seed, int *status ); - -* Class Membership: -* Mapping member function. - -* Description: -* This function returns a pseudo-random double value from a PDF -* uniformly distributed in the range 0 to 1. It also updates a -* seed value so that a sequence of pseudo-random values may be -* obtained with successive invocations. - -* Parameters: -* seed -* Pointer to a long int which should initially contain a -* non-zero seed value. This will be updated with a new seed -* which may be supplied on the next invocation in order to -* obtain a different pseudo-random value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The pseudo-random value. -*/ - -/* Local Variables: */ - long int i; /* Temporary storage */ - -/* This a basic random number generator using constants given in - Numerical Recipes (Press et al.). */ - i = *seed / 127773; - *seed = ( *seed - i * 127773 ) * 16807 - i * 2836; - if ( *seed < 0 ) *seed += 2147483647; - -/* Return the result as a double value in the range 0 to 1. */ - return ( (double) ( *seed - 1 ) ) / (double) 2147483646; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, - int *status ){ -/* -*+ -* Name: -* astRate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* result = astRate( AstMapping *this, double *at, int ax1, int ax2 ) - -* Class Membership: -* Mapping method. - -* Description: -* This function evaluates the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. -* -* The result is the mean gradient within a small interval centred on -* the supplied position. The interval size is selected automatically -* to minimise the error on the returned value. For large intervals, -* the error is dominated by changes in the gradient of the -* transformation. For small intervals, the error is dominated by -* rounding errors. The best interval is the one that gives the most -* consistent measure of the gradient within the interval. To find this -* consistency, each candidate interval is subdivided into eight -* sub-intervals, the mean gradient within each sub-interval is found, -* and the associated consistency measure is then the difference between -* the maximum and minimum sub-interval gradient found within the interval. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). - -* Returned Value: -* astRate() -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic astRate method available -* via the protected interface to the Mapping class. The public -* interface to this method is provided by the astRateId_ -* function. -*/ - -#define NN 50 - -/* Local Variables: */ - double h0; - double h; - double mean; - double minrange; - double range0; - double range; - double ret; - double x0; - double y[2*NN+1]; - double z[2*NN+1]; - int ibot; - int iin; - int iret; - int itop; - int nin; - int nout; - -/* Initialise */ - ret = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Allocate resources */ - RateFun( NULL, NULL, -1, 0, 0, NULL, NULL, status ); - -/* Obtain the numbers of input and output coordinates for the Mapping. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - -/* Validate the output index. */ - if ( astOK && ( ax1 < 0 || ax1 >= nout ) ) { - astError( AST__AXIIN, "astRate(%s): The supplied Mapping output " - "index (%d) is invalid; it should be in the range 1 to %d.", status, - astGetClass( this ), ax1 + 1, nout ); - } - -/* Validate the input index. */ - if ( astOK && ( ax2 < 0 || ax2 >= nin ) ) { - astError( AST__AXIIN, "astRate(%s): The supplied Mapping input " - "index (%d) is invalid; it should be in the range 1 to %d.", status, - astGetClass( this ), ax2 + 1, nin ); - } - -/* Check the Mapping has a forward transformation. */ - if ( astOK && !astGetTranForward( this ) ) { - astError( AST__NODEF, "astRate(%s): The supplied Mapping does not " - "have a defined forward transformation.", status, - astGetClass( this ) ); - } - -/* Save the central value on the Mapping input which is to be varied. */ - x0 = at[ ax2 ]; - -/* If it is bad, return bad values. */ - if( astOK && x0 != AST__BAD ) { - -/* The required derivative is formed by evaluating the transformation at - two positions close to "x0", and dividing the change in y by the - change in x. The complexity comes in deciding how close to "x0" the - two points should be. If the points are too far apart, the gradient of - the function may vary significantly between the two points and so we - have little confidence that he mean gradient in the interval is a good - estimate of the gradient at "x0". On the other hand if the points are - too close together, rounding errors will make the gradient value - unreliable. The optimal interval is found by testing a number of - different intervals as follows. Each interval is split into NDIV equal - sub-intervals, and the gradient in each sub-interval is found. The max - and min gradient for any of these sub-intervals is found, and the - difference between them is used as an estimate of the reliability of the - mean gradient within the whole interval. The interval with the - greatest reliability is used to define the returned gradient. - - The initial estimate of the interval size is a fixed small fraction of - the supplied "x0" value, or 1.0 if "x0" is zero. */ - h0 = ( x0 != 0.0 ) ? DBL_EPSILON*1.0E9*fabs( x0 ) : 1.0; - -/* Attempt to find the mean gradient, and the range of gradients, within - an interval of size "h0" centred on "x0". If this cannot be done, - increase "h0" by a factor fo ten repeatedly until it can be done, or a - silly large interval size is reached. */ - mean = AST__BAD; - while( mean == AST__BAD && h0 < 1.0E-10*DBL_MAX ) { - h0 *= 10; - mean = FindGradient( this, at, ax1, ax2, x0, h0, &range0, status ); - } - -/* If this was not successful, return AST__BAD as the function value. */ - if( mean != AST__BAD ) { - -/* We now search through a range of larger interval sizes, to see if any - produce a more reliable mean gradient estimate (i.e. have a smaller range - of gradients within the interval ). After that we search through a range - of smaller interval sizes. The gradient range and mean gradient for - each interval size are stored in arrays "y" and "z" respectively. "iret" - is the index of the most reliable interval found so far (i.e. the one - with the smallest range of sub-interval gradients). The original interval - "h0" is stored in the middle element of these arrays (index "NN"). - Intervals are stored in monotonic order of interval size in the arrays. */ - iret = NN; - y[ NN ] = range0; - z[ NN ] = mean; - minrange = range0; - -/* itop is the index of the last array elements to store calculated values. */ - itop = NN; - -/* Loop round increasing the interval size by a factor of four each time - round. */ - h = h0; - for( iin = NN + 1; iin <= 2*NN && astOK; iin++ ){ - h *= 4.0; - -/* Calculate the mean gradient, and the range of gradients, using the - current interval size. */ - mean = FindGradient( this, at, ax1, ax2, x0, h, &range, status ); - -/* If it could be done, store the values in the arrays. */ - if( mean != AST__BAD ) { - itop++; - z[ itop ] = mean; - y[ itop ] = range; - -/* Look for the smallest range, and note its index in the arrays. */ - if( range < minrange ) { - minrange = range; - iret = itop; - -/* If a range of zero is encountered, we only believe it if the previous - interval also had zero range. Otherwise, it's probably just a numerical - fluke. If the previous interval also had a range of zero, we can forget - the rest of the algorithm since the supplied transformation is linear - and we now have its gradient. So leave the loop. */ - } else if( range == 0.0 && y[ iin - 1 ] == 0 ) { - iret = itop; - break; - } - -/* Stop looping when the interval range is 100 times the original - interval range. */ - if( range > 100*range0 ) break; - } - } - -/* Record the minimum range found so far. */ - range0 = minrange; - -/* ibot is the index of the first array elements to store calculated values. */ - ibot = NN; - -/* Loop round decreasing the interval size by a factor of four each time - round. This is just like the last loop, but goes the other way, to - lower indices. */ - h = h0; - for( iin = NN - 1; iin >= 0 && astOK; iin-- ){ - h /= 4.0; - - mean = FindGradient( this, at, ax1, ax2, x0, h, &range, status ); - if( mean != AST__BAD ) { - ibot--; - z[ ibot ] = mean; - y[ ibot ] = range; - - if( range < minrange ) { - minrange = range; - iret = ibot; - } else if( range == 0.0 && y[ iin + 1 ] == 0 ) { - iret = ibot; - break; - } - - if( range > 100*range0 ) break; - } - } - -/* If the smallest gradient range in any interval was zero, we only - believe it if the adjacent interval size also had zero range. */ - if( minrange == 0.0 ) { - if( ( iret > ibot && y[ iret - 1 ] == 0 ) || - ( iret < itop && y[ iret + 1 ] == 0 ) ) { - ret = z[ iret ]; - -/* Otherwise, search for the smallest gradient range, ignoring values - exactly equal to zero, and return the corresponding mean interval - gradient. */ - } else { - for( iin = ibot; iin <= itop; iin++ ){ - if( y[ iin ] > 0.0 ){ - if( minrange == 0 || y[ iin ] < minrange ) { - minrange = y[ iin ]; - ret = z[ iin ]; - } - } - } - } - -/* If the minimum range was non-zero, we can just return the - corresponding mean gradient. */ - } else { - ret = z[ iret ]; - } - } - } - -/* Free resources */ - RateFun( NULL, NULL, -2, 0, 0, NULL, NULL, status ); - -/* Return the result. */ - return ret; - -#undef NN -} - -static void RateFun( AstMapping *map, double *at, int ax1, int ax2, - int n, double *x, double *y, int *status ) { -/* -* Name: -* RateFun - -* Purpose: -* Find the value of the function currently being differentiated by the -* astRate method. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void RateFun( AstMapping *map, double *at, int ax1, int ax2, -* int n, double *x, double *y, int *status ) - -* Class Membership: -* Mapping method. - -* Description: -* This is a service function for the astRate method. It evaluates the -* function being differentiated at specified axis values. -* -* This function uses static resources in order to avoid the overhead -* of creating new PointSets each time this function is called. These -* static resources which must be initialised before the first invocation -* with a given Mapping, and must be released after the final invocation. -* See "ax1". - -* Parameters: -* map -* Pointer to a Mapping which yields the value of the function at x. -* The Mapping may have any number of inputs and outputs; the specific -* output representing the function value, f, is specified by ax1 and -* the specific input representing the argument, x, is specified by ax2. -* at -* A pointer to an array holding axis values at the position at which -* the function is to be evaluated. The number of values supplied -* must equal the number of inputs to the Mapping. The value supplied -* for axis "ax2" is ignored (the value of "x" is used for axis "ax2"). -* ax1 -* The zero-based index of the Mapping output which is to be -* differentiated. Set this to -1 to allocate, or -2 to release, -* the static resources used by this function. -* ax2 -* The zero-based index of the Mapping input which is to be varied. -* n -* The number of elements in the "x" and "y" arrays. This should not -* be greater than 2*RATE_ORDER. -* x -* The value of the Mapping input specified by ax2 at which the -* function is to be evaluated. If "ax2" is set to -1, then the -* supplied value is used as flag indicating if the static resources -* used by this function should be initialised (if x >= 0 ) or -* freed (if x < 0). -* y -* An array in which to return the function values at the positions -* given in "x". -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - AstPointSet *pset1; - AstPointSet *pset2; - double **ptr1; - double **ptr2; - double *oldx; - double *oldy; - double *p; - double xx; - int i; - int k; - int nin; - int nout; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(map); - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - pset2 = NULL; - -/* If required, initialise things. */ - if( ax1 == -1 ) { - for( i = 0; i < RATEFUN_MAX_CACHE; i++ ) { - ratefun_pset_size[ i ] = 0; - ratefun_pset1_cache[ i ] = NULL; - ratefun_pset2_cache[ i ] = NULL; - } - ratefun_next_slot = 0; - -/* If required, clean up. */ - } else if( ax1 == -2 ) { - for( i = 0; i < RATEFUN_MAX_CACHE; i++ ) { - ratefun_pset_size[ i ] = 0; - if( ratefun_pset1_cache[ i ] ) ratefun_pset1_cache[ i ] = astAnnul( ratefun_pset1_cache[ i ] ); - if( ratefun_pset2_cache[ i ] ) ratefun_pset2_cache[ i ] = astAnnul( ratefun_pset2_cache[ i ] ); - } - ratefun_next_slot = 0; - -/* Otherwise do the transformations. */ - } else { - -/* See if we have already created PointSets of the correct size. */ - pset1 = NULL; - for( i = 0; i < RATEFUN_MAX_CACHE; i++ ) { - if( ratefun_pset_size[ i ] == n ) { - pset1 = ratefun_pset1_cache[ i ]; - pset2 = ratefun_pset2_cache[ i ]; - break; - } - } - -/* If we have not, create new PointSets now. */ - if( pset1 == NULL ) { - nin = astGetNin( map ); - pset1 = astPointSet( n, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - - nout = astGetNout( map ); - pset2 = astPointSet( n, nout, "", status ); - ptr2 = astGetPoints( pset2 ); - -/* Store the input position in the input PointSet. */ - for( i = 0; i < nin; i++ ) { - xx = at[ i ]; - p = ptr1[ i ]; - for( k = 0; k < n; k++, p++ ) *p = xx; - } - -/* Add these new PointSets to the cache, removing any existing - PointSets. */ - if( ratefun_pset_size[ ratefun_next_slot ] > 0 ) { - (void) astAnnul( ratefun_pset1_cache[ ratefun_next_slot ] ); - (void) astAnnul( ratefun_pset2_cache[ ratefun_next_slot ] ); - } - ratefun_pset1_cache[ ratefun_next_slot ] = pset1; - ratefun_pset2_cache[ ratefun_next_slot ] = pset2; - ratefun_pset_size[ ratefun_next_slot ] = n; - if( ++ratefun_next_slot == RATEFUN_MAX_CACHE ) ratefun_next_slot = 0; - -/* If existing PointSets were found, get there data arrays. */ - } else { - ptr1 = astGetPoints( pset1 ); - ptr2 = astGetPoints( pset2 ); - } - -/* Store the input X values in the input PointSet data array. */ - oldx = ptr1[ ax2 ]; - ptr1[ ax2 ] = x; - -/* Store the output Y values in the output PointSet data array. */ - oldy = ptr2[ ax1 ]; - ptr2[ ax1 ] = y; - -/* Transform the positions. */ - (void) astTransform( map, pset1, 1, pset2 ); - -/* Re-instate the original arrays in the PointSets. */ - ptr1[ ax2 ] = oldx; - ptr2[ ax1 ] = oldy; - - } -} - -/* -*++ -* Name: -c astRebin -f AST_REBIN - -* Purpose: -* Rebin a region of a data grid. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astRebin( AstMapping *this, double wlim, int ndim_in, -c const int lbnd_in[], const int ubnd_in[], -c const in[], const in_var[], -c int spread, const double params[], int flags, -c double tol, int maxpix, -c badval, int ndim_out, -c const int lbnd_out[], const int ubnd_out[], -c const int lbnd[], const int ubnd[], -c out[], out_var[] ); -f CALL AST_REBIN( THIS, WLIM, NDIM_IN, LBND_IN, UBND_IN, IN, IN_VAR, -f SPREAD, PARAMS, FLAGS, -f TOL, MAXPIX, BADVAL, -f NDIM_OUT, LBND_OUT, UBND_OUT, -f LBND, UBND, OUT, OUT_VAR, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -* This is a set of functions for rebinning gridded data (e.g. an -* image) under the control of a geometrical transformation, which -* is specified by a Mapping. The functions operate on a pair of -* data grids (input and output), each of which may have any number -* of dimensions. Rebinning may be restricted to a specified -* region of the input grid. An associated grid of error estimates -* associated with the input data may also be supplied (in the form -* of variance values), so as to produce error estimates for the -* rebined output data. Propagation of missing data (bad pixels) -* is supported. -* -* Note, if you will be rebining a sequence of input arrays and then -* co-adding them into a single array, the alternative -c astRebinSeq functions -f AST_REBINSEQ routines -* will in general be more efficient. -* -* You should use a rebinning function which matches the numerical -* type of the data you are processing by replacing in -c the generic function name astRebin by an appropriate 1- or -f the generic function name AST_REBIN by an appropriate 1- or -* 2-character type code. For example, if you are rebinning data -c with type "float", you should use the function astRebinF (see -f with type REAL, you should use the function AST_REBINR (see -* the "Data Type Codes" section below for the codes appropriate to -* other numerical types). -* -* Rebinning of the grid of input data is performed by transforming -* the coordinates of the centre of each input grid element (or pixel) -* into the coordinate system of the output grid. The input pixel -* value is then divided up and assigned to the output pixels in the -* neighbourhood of the central output coordinates. A choice of -* schemes are provided for determining how each input pixel value is -* divided up between the output pixels. In general, each output pixel -* may be assigned values from more than one input pixel. All -* contributions to a given output pixel are summed to produce the -* final output pixel value. Output pixels can be set to the supplied -* bad value if they receive contributions from an insufficient number -* of input pixels. This is controlled by the -c "wlim" parameter. -f WLIM argument. -* -* Input pixel coordinates are transformed into the coordinate -* system of the output grid using the forward transformation of the -* Mapping which is supplied. This means that geometrical features -* in the input data are subjected to the Mapping's forward -* transformation as they are transferred from the input to the -* output grid. -* -* In practice, transforming the coordinates of every pixel of a -* large data grid can be time-consuming, especially if the Mapping -* involves complicated functions, such as sky projections. To -* improve performance, it is therefore possible to approximate -* non-linear Mappings by a set of linear transformations which are -* applied piece-wise to separate sub-regions of the data. This -* approximation process is applied automatically by an adaptive -* algorithm, under control of an accuracy criterion which -* expresses the maximum tolerable geometrical distortion which may -* be introduced, as a fraction of a pixel. -* -* This algorithm first attempts to approximate the Mapping with a -* linear transformation applied over the whole region of the -* input grid which is being used. If this proves to be -* insufficiently accurate, the input region is sub-divided into -* two along its largest dimension and the process is repeated -* within each of the resulting sub-regions. This process of -* sub-division continues until a sufficiently good linear -* approximation is found, or the region to which it is being -* applied becomes too small (in which case the original Mapping is -* used directly). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to a Mapping, whose forward transformation will be -* used to transform the coordinates of pixels in the input -* grid into the coordinate system of the output grid. -* -* The number of input coordinates used by this Mapping (as -* given by its Nin attribute) should match the number of input -c grid dimensions given by the value of "ndim_in" -f grid dimensions given by the value of NDIM_IN -* below. Similarly, the number of output coordinates (Nout -* attribute) should match the number of output grid dimensions -c given by "ndim_out". -f given by NDIM_OUT. -c wlim -f WLIM = DOUBLE PRECISION (Given) -* Gives the required number of input pixel values which must contribute -* to an output pixel in order for the output pixel value to be -* considered valid. If the sum of the input pixel weights contributing -* to an output pixel is less than the supplied -c "wlim" -f WLIM -* value, then the output pixel value is returned set to the -* supplied bad value. -c ndim_in -f NDIM_IN = INTEGER (Given) -* The number of dimensions in the input grid. This should be at -* least one. -c lbnd_in -f LBND_IN( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the centre of the first pixel -* in the input grid along each dimension. -c ubnd_in -f UBND_IN( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the centre of the last pixel in -* the input grid along each dimension. -* -c Note that "lbnd_in" and "ubnd_in" together define the shape -f Note that LBND_IN and UBND_IN together define the shape -* and size of the input grid, its extent along a particular -c (j'th) dimension being ubnd_in[j]-lbnd_in[j]+1 (assuming the -c index "j" to be zero-based). They also define -f (J'th) dimension being UBND_IN(J)-LBND_IN(J)+1. They also define -* the input grid's coordinate system, each pixel having unit -* extent along each dimension with integral coordinate values -* at its centre. -c in -f IN( * ) = (Given) -c Pointer to an array, with one element for each pixel in the -f An array, with one element for each pixel in the -* input grid, containing the input data to be rebined. The -* numerical type of this array should match the 1- or -* 2-character type code appended to the function name (e.g. if -c you are using astRebinF, the type of each array element -c should be "float"). -f you are using AST_REBINR, the type of each array element -f should be REAL). -* -* The storage order of data within this array should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -c in_var -f IN_VAR( * ) = (Given) -c An optional pointer to a second array with the same size and -c type as the "in" array. If given, this should contain a set -c of non-negative values which represent estimates of the -c statistical variance associated with each element of the "in" -c array. If this array is supplied (together with the -c corresponding "out_var" array), then estimates of the -c variance of the rebined output data will be calculated. -c -c If no input variance estimates are being provided, a NULL -c pointer should be given. -f An optional second array with the same size and type as the -f IN array. If the AST__USEVAR flag is set via the FLAGS -f argument (below), this array should contain a set of -f non-negative values which represent estimates of the -f statistical variance associated with each element of the IN -f array. Estimates of the variance of the rebined output data -f will then be calculated. -f -f If the AST__USEVAR flag is not set, no input variance -f estimates are required and this array will not be used. A -f dummy (e.g. one-element) array may then be supplied. -c spread -f SPREAD = INTEGER (Given) -c This parameter specifies the scheme to be used for dividing -f This argument specifies the scheme to be used for dividing -* each input data value up amongst the corresponding output pixels. -* It may be used to select -* from a set of pre-defined schemes by supplying one of the -* values described in the "Pixel Spreading Schemes" -* section below. If a value of zero is supplied, then the -* default linear spreading scheme is used (equivalent to -* supplying the value AST__LINEAR). -c params -f PARAMS( * ) = DOUBLE PRECISION (Given) -c An optional pointer to an array of double which should contain -f An optional array which should contain -* any additional parameter values required by the pixel -* spreading scheme. If such parameters are required, this -* will be noted in the "Pixel Spreading Schemes" -* section below. -* -c If no additional parameters are required, this array is not -c used and a NULL pointer may be given. -f If no additional parameters are required, this array is not -f used. A dummy (e.g. one-element) array may then be supplied. -c flags -f FLAGS = INTEGER (Given) -c The bitwise OR of a set of flag values which may be used to -f The sum of a set of flag values which may be used to -* provide additional control over the rebinning operation. See -* the "Control Flags" section below for a description of the -* options available. If no flag values are to be set, a value -* of zero should be given. -c tol -f TOL = DOUBLE PRECISION (Given) -* The maximum tolerable geometrical distortion which may be -* introduced as a result of approximating non-linear Mappings -* by a set of piece-wise linear transformations. This should be -* expressed as a displacement in pixels in the output grid's -* coordinate system. -* -* If piece-wise linear approximation is not required, a value -* of zero may be given. This will ensure that the Mapping is -* used without any approximation, but may increase execution -* time. -* -* If the value is too high, discontinuities between the linear -* approximations used in adjacent panel will be higher, and may -* cause the edges of the panel to be visible when viewing the output -* image at high contrast. If this is a problem, reduce the -* tolerance value used. -c maxpix -f MAXPIX = INTEGER (Given) -* A value which specifies an initial scale size (in pixels) for -* the adaptive algorithm which approximates non-linear Mappings -* with piece-wise linear transformations. Normally, this should -* be a large value (larger than any dimension of the region of -* the input grid being used). In this case, a first attempt to -* approximate the Mapping by a linear transformation will be -* made over the entire input region. -* -* If a smaller value is used, the input region will first be -c divided into sub-regions whose size does not exceed "maxpix" -f divided into sub-regions whose size does not exceed MAXPIX -* pixels in any dimension. Only at this point will attempts at -* approximation commence. -* -* This value may occasionally be useful in preventing false -* convergence of the adaptive algorithm in cases where the -* Mapping appears approximately linear on large scales, but has -* irregularities (e.g. holes) on smaller scales. A value of, -* say, 50 to 100 pixels can also be employed as a safeguard in -* general-purpose software, since the effect on performance is -* minimal. -* -* If too small a value is given, it will have the effect of -* inhibiting linear approximation altogether (equivalent to -c setting "tol" to zero). Although this may degrade -f setting TOL to zero). Although this may degrade -* performance, accurate results will still be obtained. -c badval -f BADVAL = (Given) -* This argument should have the same type as the elements of -c the "in" array. It specifies the value used to flag missing -f the IN array. It specifies the value used to flag missing -* data (bad pixels) in the input and output arrays. -* -c If the AST__USEBAD flag is set via the "flags" parameter, -f If the AST__USEBAD flag is set via the FLAGS argument, -c then this value is used to test for bad pixels in the "in" -c (and "in_var") array(s). -f then this value is used to test for bad pixels in the IN -f (and IN_VAR) array(s). -* -* In all cases, this value is also used to flag any output -c elements in the "out" (and "out_var") array(s) for which -f elements in the OUT (and OUT_VAR) array(s) for which -* rebined values could not be obtained (see the "Propagation -* of Missing Data" section below for details of the -* circumstances under which this may occur). -c ndim_out -f NDIM_OUT = INTEGER (Given) -* The number of dimensions in the output grid. This should be -* at least one. It need not necessarily be equal to the number -* of dimensions in the input grid. -c lbnd_out -f LBND_OUT( NDIM_OUT ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_out" elements, -f An array -* containing the coordinates of the centre of the first pixel -* in the output grid along each dimension. -c ubnd_out -f UBND_OUT( NDIM_OUT ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_out" elements, -f An array -* containing the coordinates of the centre of the last pixel in -* the output grid along each dimension. -* -c Note that "lbnd_out" and "ubnd_out" together define the -f Note that LBND_OUT and UBND_OUT together define the -* shape, size and coordinate system of the output grid in the -c same way as "lbnd_in" and "ubnd_in" define the shape, size -f same way as LBND_IN and UBND_IN define the shape, size -* and coordinate system of the input grid. -c lbnd -f LBND( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the first pixel in the region -* of the input grid which is to be included in the rebined output -* array. -c ubnd -f UBND( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the last pixel in the region of -* the input grid which is to be included in the rebined output -* array. -* -c Note that "lbnd" and "ubnd" together define the shape and -f Note that LBND and UBND together define the shape and -* position of a (hyper-)rectangular region of the input grid -* which is to be included in the rebined output array. This region -* should lie wholly within the extent of the input grid (as -c defined by the "lbnd_in" and "ubnd_in" arrays). Regions of -f defined by the LBND_IN and UBND_IN arrays). Regions of -* the input grid lying outside this region will not be used. -c out -f OUT( * ) = (Returned) -c Pointer to an array, with one element for each pixel in the -f An array, with one element for each pixel in the -* output grid, in which the rebined data values will be -* returned. The numerical type of this array should match that -c of the "in" array, and the data storage order should be such -f of the IN array, and the data storage order should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -c out_var -f OUT_VAR( * ) = (Returned) -c An optional pointer to an array with the same type and size -c as the "out" array. If given, this array will be used to -c return variance estimates for the rebined data values. This -c array will only be used if the "in_var" array has also been -c supplied. -f An optional array with the same type and size as the OUT -f array. If the AST__USEVAR flag is set via the FLAGS argument, -f this array will be used to return variance estimates for the -f rebined data values. -* -* The output variance values will be calculated on the -* assumption that errors on the input data values are -* statistically independent and that their variance estimates -* may simply be summed (with appropriate weighting factors) -* when several input pixels contribute to an output data -* value. If this assumption is not valid, then the output error -* estimates may be biased. In addition, note that the -* statistical errors on neighbouring output data values (as -* well as the estimates of those errors) may often be -* correlated, even if the above assumption about the input data -* is correct, because of the pixel spreading schemes -* employed. -* -c If no output variance estimates are required, a NULL pointer -c should be given. -f If the AST__USEVAR flag is not set, no output variance -f estimates will be calculated and this array will not be -f used. A dummy (e.g. one-element) array may then be supplied. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Data Type Codes: -* To select the appropriate rebinning function, you should -c replace in the generic function name astRebin with a -f replace in the generic function name AST_REBIN with a -* 1- or 2-character data type code, so as to match the numerical -* type of the data you are processing, as follows: -c - D: double -c - F: float -c - I: int -c - B: byte (signed char) -c - UB: unsigned byte (unsigned char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - B: BYTE (treated as signed) -f - UB: BYTE (treated as unsigned) -* -c For example, astRebinD would be used to process "double" -c data, while astRebinI would be used to process "int" -c data, etc. -f For example, AST_REBIND would be used to process DOUBLE -f PRECISION data, while AST_REBINI would be used to process -f integer data (stored in an INTEGER array), etc. -* -* Note that, unlike -c astResample, the astRebin -f AST_RESAMPLE, the AST_REBIN -* set of functions does not yet support unsigned integer data types -* or integers of different sizes. - -* Pixel Spreading Schemes: -* The pixel spreading scheme specifies the Point Spread Function (PSF) -* applied to each input pixel value as it is copied into the output -* array. It can be thought of as the inverse of the sub-pixel -* interpolation schemes used by the -c astResample -f AST_RESAMPLE -* group of functions. That is, in a sub-pixel interpolation scheme the -* kernel specifies the weight to assign to each input pixel when -* forming the weighted mean of the input pixels, whereas the kernel in a -* pixel spreading scheme specifies the fraction of the input data value -* which is to be assigned to each output pixel. As for interpolation, the -* choice of suitable pixel spreading scheme involves stricking a balance -* between schemes which tend to degrade sharp features in the data by -* smoothing them, and those which attempt to preserve sharp features but -* which often tend to introduce unwanted artifacts. See the -c astResample -f AST_RESAMPLE -* documentation for further discussion. -* -* The binning algorithm used has the ability to introduce artifacts -* not seen when using a resampling algorithm. Particularly, when -* viewing the output image at high contrast, systems of curves lines -* covering the entire image may be visible. These are caused by a -* beating effect between the input pixel positions and the output pixels -* position, and their nature and strength depend critically upon the -* nature of the Mapping and the spreading function being used. In -* general, the nearest neighbour spreading function demonstrates this -* effect more clearly than the other functions, and for this reason -* should be used with caution. -* -* The following values (defined in the -c "ast.h" header file) -f AST_PAR include file) -* may be assigned to the -c "spread" -f SPREAD -* parameter. See the -c astResample -f AST_RESAMPLE -* documentation for details of these schemes including the use of the -c "fspread" and "params" parameters: -f FSPREAD and PARAMS arguments: -* -* - AST__NEAREST -* - AST__LINEAR -* - AST__SINC -* - AST__SINCSINC -* - AST__SINCCOS -* - AST__SINCGAUSS -* - AST__SOMBCOS -* -* In addition, the following schemes can be used with -f AST_REBIN but not with AST_RESAMPLE: -c astRebin but not with astResample: -* -* - AST__GAUSS: This scheme uses a kernel of the form exp(-k*x*x), with k -* a positive constant determined by the full-width at half-maximum (FWHM). -* The FWHM should be supplied in units of output pixels by means of the -c "params[1]" -f PARAMS(2) -* value and should be at least 0.1. The -c "params[0]" -f PARAMS(1) -* value should be used to specify at what point the Gaussian is truncated -* to zero. This should be given as a number of output pixels on either -* side of the central output point in each dimension (the nearest integer -* value is used). - -* Control Flags: -c The following flags are defined in the "ast.h" header file and -f The following flags are defined in the AST_PAR include file and -* may be used to provide additional control over the rebinning -* process. Having selected a set of flags, you should supply the -c bitwise OR of their values via the "flags" parameter: -f sum of their values via the FLAGS argument: -* -* - AST__USEBAD: Indicates that there may be bad pixels in the -* input array(s) which must be recognised by comparing with the -c value given for "badval" and propagated to the output array(s). -f value given for BADVAL and propagated to the output array(s). -* If this flag is not set, all input values are treated literally -c and the "badval" value is only used for flagging output array -f and the BADVAL value is only used for flagging output array -* values. -f - AST__USEVAR: Indicates that variance information should be -f processed in order to provide estimates of the statistical error -f associated with the rebined values. If this flag is not set, -f no variance processing will occur and the IN_VAR and OUT_VAR -f arrays will not be used. (Note that this flag is only available -f in the Fortran interface to AST.) - -* Propagation of Missing Data: -* Instances of missing data (bad pixels) in the output grid are -c identified by occurrences of the "badval" value in the "out" -f identified by occurrences of the BADVAL value in the OUT -* array. These are produced if the sum of the weights of the -* contributing input pixels is less than -c "wlim". -f WLIM. -* -* An input pixel is considered bad (and is consequently ignored) if -* its -c data value is equal to "badval" and the AST__USEBAD flag is -c set via the "flags" parameter. -f data value is equal to BADVAL and the AST__USEBAD flag is -f set via the FLAGS argument. -* -* In addition, associated output variance estimates (if -c calculated) may be declared bad and flagged with the "badval" -c value in the "out_var" array for similar reasons. -f calculated) may be declared bad and flagged with the BADVAL -f value in the OUT_VAR array for similar reasons. -*-- -*/ -/* Define a macro to implement the function for a specific data - type. */ -#define MAKE_REBIN(X,Xtype,IntType) \ -static void Rebin##X( AstMapping *this, double wlim, int ndim_in, \ - const int lbnd_in[], const int ubnd_in[], \ - const Xtype in[], const Xtype in_var[], \ - int spread, const double params[], int flags, \ - double tol, int maxpix, Xtype badval, \ - int ndim_out, const int lbnd_out[], \ - const int ubnd_out[], const int lbnd[], \ - const int ubnd[], Xtype out[], Xtype out_var[], int *status ) { \ -\ -/* Local Variables: */ \ - astDECLARE_GLOBALS /* Thread-specific data */ \ - const char *badflag; /* Name of illegal flag */ \ - AstMapping *simple; /* Pointer to simplified Mapping */ \ - Xtype *d; /* Pointer to next output data value */ \ - Xtype *v; /* Pointer to next output variance value */ \ - double *w; /* Pointer to next weight value */ \ - double *work; /* Pointer to weight array */ \ - int idim; /* Loop counter for coordinate dimensions */ \ - int ipix_out; /* Index into output array */ \ - int nin; /* Number of Mapping input coordinates */ \ - int nout; /* Number of Mapping output coordinates */ \ - int npix; /* Number of pixels in input region */ \ - int npix_out; /* Number of pixels in output array */ \ - int64_t mpix; /* Number of pixels for testing */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Get a pointer to a structure holding thread-specific global data values */ \ - astGET_GLOBALS(this); \ -\ -/* Obtain values for the Nin and Nout attributes of the Mapping. */ \ - nin = astGetNin( this ); \ - nout = astGetNout( this ); \ -\ -/* If OK, check that the number of input grid dimensions matches the \ - number required by the Mapping and is at least 1. Report an error \ - if necessary. */ \ - if ( astOK && ( ( ndim_in != nin ) || ( ndim_in < 1 ) ) ) { \ - astError( AST__NGDIN, "astRebin"#X"(%s): Bad number of input grid " \ - "dimensions (%d).", status, astGetClass( this ), ndim_in ); \ - if ( ndim_in != nin ) { \ - astError( AST__NGDIN, "The %s given requires %d coordinate value%s " \ - "to specify an input position.", status, \ - astGetClass( this ), nin, ( nin == 1 ) ? "" : "s" ); \ - } \ - } \ -\ -/* If OK, also check that the number of output grid dimensions matches \ - the number required by the Mapping and is at least 1. Report an \ - error if necessary. */ \ - if ( astOK && ( ( ndim_out != nout ) || ( ndim_out < 1 ) ) ) { \ - astError( AST__NGDIN, "astRebin"#X"(%s): Bad number of output grid " \ - "dimensions (%d).", status, astGetClass( this ), ndim_out ); \ - if ( ndim_out != nout ) { \ - astError( AST__NGDIN, "The %s given generates %s%d coordinate " \ - "value%s for each output position.", status, astGetClass( this ), \ - ( nout < ndim_out ) ? "only " : "", nout, \ - ( nout == 1 ) ? "" : "s" ); \ - } \ - } \ -\ -/* Check that the lower and upper bounds of the input grid are \ - consistent. Report an error if any pair is not. */ \ - mpix = 1; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - if ( lbnd_in[ idim ] > ubnd_in[ idim ] ) { \ - astError( AST__GBDIN, "astRebin"#X"(%s): Lower bound of " \ - "input grid (%d) exceeds corresponding upper bound " \ - "(%d).", status, astGetClass( this ), \ - lbnd_in[ idim ], ubnd_in[ idim ] ); \ - astError( AST__GBDIN, "Error in input dimension %d.", status, \ - idim + 1 ); \ - break; \ - } else { \ - mpix *= ubnd_in[ idim ] - lbnd_in[ idim ] + 1; \ - } \ - } \ - } \ -\ -/* Report an error if there are too many pixels in the input. */ \ - if ( astOK && (int) mpix != mpix ) { \ - astError( AST__EXSPIX, "astRebin"#X"(%s): Supplied input array " \ - "contains too many pixels (%g): must be fewer than %d.", \ - status, astGetClass( this ), (double) mpix, INT_MAX ); \ - } \ -\ -/* Check that the positional accuracy tolerance supplied is valid and \ - report an error if necessary. */ \ - if ( astOK && ( tol < 0.0 ) ) { \ - astError( AST__PATIN, "astRebin"#X"(%s): Invalid positional " \ - "accuracy tolerance (%.*g pixel).", status, \ - astGetClass( this ), AST__DBL_DIG, tol ); \ - astError( AST__PATIN, "This value should not be less than zero." , status); \ - } \ -\ -/* Check that the initial scale size in pixels supplied is valid and \ - report an error if necessary. */ \ - if ( astOK && ( maxpix < 0 ) ) { \ - astError( AST__SSPIN, "astRebin"#X"(%s): Invalid initial scale " \ - "size in pixels (%d).", status, astGetClass( this ), maxpix ); \ - astError( AST__SSPIN, "This value should not be less than zero." , status); \ - } \ -\ -/* Check that the lower and upper bounds of the output grid are \ - consistent. Report an error if any pair is not. */ \ - mpix = 1; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - if ( lbnd_out[ idim ] > ubnd_out[ idim ] ) { \ - astError( AST__GBDIN, "astRebin"#X"(%s): Lower bound of " \ - "output grid (%d) exceeds corresponding upper bound " \ - "(%d).", status, astGetClass( this ), \ - lbnd_out[ idim ], ubnd_out[ idim ] ); \ - astError( AST__GBDIN, "Error in output dimension %d.", status, \ - idim + 1 ); \ - break; \ - } else { \ - mpix *= ubnd_out[ idim ] - lbnd_out[ idim ] + 1; \ - } \ - } \ - } \ -\ -/* Report an error if there are too many pixels in the output. */ \ - if ( astOK && (int) mpix != mpix ) { \ - astError( AST__EXSPIX, "astRebin"#X"(%s): Supplied output array " \ - "contains too many pixels (%g): must be fewer than %d.", \ - status, astGetClass( this ), (double) mpix, INT_MAX ); \ - } \ -\ -/* Similarly check the bounds of the input region. */ \ - mpix = 1; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - if ( lbnd[ idim ] > ubnd[ idim ] ) { \ - astError( AST__GBDIN, "astRebin"#X"(%s): Lower bound of " \ - "input region (%d) exceeds corresponding upper " \ - "bound (%d).", status, astGetClass( this ), \ - lbnd[ idim ], ubnd[ idim ] ); \ -\ -/* Also check that the input region lies wholly within the input \ - grid. */ \ - } else if ( lbnd[ idim ] < lbnd_in[ idim ] ) { \ - astError( AST__GBDIN, "astRebin"#X"(%s): Lower bound of " \ - "input region (%d) is less than corresponding " \ - "bound of input grid (%d).", status, astGetClass( this ), \ - lbnd[ idim ], lbnd_in[ idim ] ); \ - } else if ( ubnd[ idim ] > ubnd_in[ idim ] ) { \ - astError( AST__GBDIN, "astRebin"#X"(%s): Upper bound of " \ - "input region (%d) exceeds corresponding " \ - "bound of input grid (%d).", status, astGetClass( this ), \ - ubnd[ idim ], ubnd_in[ idim ] ); \ - } else { \ - mpix *= ubnd[ idim ] - lbnd[ idim ] + 1; \ - } \ -\ -/* Say which dimension produced the error. */ \ - if ( !astOK ) { \ - astError( AST__GBDIN, "Error in output dimension %d.", status, \ - idim + 1 ); \ - break; \ - } \ - } \ - } \ -\ -/* Report an error if there are too many pixels in the input region. */ \ - if ( astOK && (int) mpix != mpix ) { \ - astError( AST__EXSPIX, "astRebin"#X"(%s): Supplied input region " \ - "contains too many pixels (%g): must be fewer than %d.", \ - status, astGetClass( this ), (double) mpix, INT_MAX ); \ - } \ -\ -/* If OK, loop to determine how many input pixels are to be binned. */ \ - simple = NULL; \ - npix = 1; \ - npix_out = 1; \ - unsimplified_mapping = this; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - npix *= ubnd[ idim ] - lbnd[ idim ] + 1; \ - } \ -\ -/* Loop to determine how many pixels the output array contains. */ \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - npix_out *= ubnd_out[ idim ] - lbnd_out[ idim ] + 1; \ - } \ -\ -/* If there are sufficient pixels to make it worthwhile, simplify the \ - Mapping supplied to improve performance. Otherwise, just clone the \ - Mapping pointer. Note we have already saved a pointer to the original \ - Mapping so that lower-level functions can use it if they need to report \ - an error. */ \ - if ( npix > 1024 ) { \ - simple = astSimplify( this ); \ - } else { \ - simple = astClone( this ); \ - } \ - } \ -\ -/* Report an error if the forward transformation of this simplified \ - Mapping is not defined. */ \ - if ( !astGetTranForward( simple ) && astOK ) { \ - astError( AST__TRNND, "astRebin"#X"(%s): An forward coordinate " \ - "transformation is not defined by the %s supplied.", status, \ - astGetClass( unsimplified_mapping ), \ - astGetClass( unsimplified_mapping ) ); \ - } \ -\ -/* Report an error if any illegal flags were supplied. */ \ - if( flags & AST__REBININIT ) { \ - badflag = "AST__REBININIT"; \ - } else if( flags & AST__REBINEND ) { \ - badflag = "AST__REBINEND"; \ - } else if( flags & AST__GENVAR ) { \ - badflag = "AST__GENVAR"; \ - } else if( flags & AST__DISVAR ) { \ - badflag = "AST__DISVAR"; \ - } else if( flags & AST__VARWGT ) { \ - badflag = "AST__VARWGT"; \ - } else if( flags & AST__NONORM ) { \ - badflag = "AST__NONORM"; \ - } else if( flags & AST__CONSERVEFLUX ) { \ - badflag = "AST__CONSERVEFLUX"; \ - } else if( flags & ~( AST__USEBAD + AST__USEVAR ) ) { \ - badflag = "unknown"; \ - } else { \ - badflag = NULL; \ - } \ - if ( badflag && astOK ) { \ - astError( AST__BADFLG, "astRebin"#X"(%s): An illegal flag (%s) " \ - "was included in the 'flags' argument.", status, \ - astGetClass( unsimplified_mapping ), badflag ); \ - } \ -\ -/* If required, allocate work array to hold the sum of the weights \ - contributing to each output pixel, and initialise it to zero. */ \ - if( wlim > 0.0 ) { \ - work = astMalloc( sizeof( double )*(size_t) npix_out ); \ - if( work ) { \ - w = work; \ - for( ipix_out = 0; ipix_out < npix_out; ipix_out++ ) *(w++) = 0.0; \ - } \ - } else { \ - work = NULL; \ - } \ -\ -/* Initialise the output arrays to hold zeros. */ \ - d = out; \ - if( out_var ) { \ - v = out_var; \ - for( ipix_out = 0; ipix_out < npix_out; ipix_out++, d++, v++ ) { \ - *d = 0; \ - *v = 0; \ - } \ - } else { \ - for( ipix_out = 0; ipix_out < npix_out; ipix_out++, d++ ) { \ - *d = 0; \ - } \ - } \ -\ -/* Perform the rebinning. Note that we pass all gridded data, the \ - spread function and the bad pixel value by means of pointer \ - types that obscure the underlying data type. This is to avoid \ - having to replicate functions unnecessarily for each data \ - type. However, we also pass an argument that identifies the data \ - type we have obscured. */ \ - if( RebinAdaptively( simple, ndim_in, lbnd_in, ubnd_in, \ - (const void *) in, (const void *) in_var, \ - TYPE_##X, spread, \ - params, flags, tol, maxpix, \ - (const void *) &badval, \ - ndim_out, lbnd_out, ubnd_out, \ - lbnd, ubnd, npix_out, \ - (void *) out, (void *) out_var, work, \ - NULL, status ) && astOK ) { \ - astError( AST__CNFLX, "astRebin"#X"(%s): Flux conservation was " \ - "requested but could not be performed because the " \ - "forward transformation of the supplied Mapping " \ - "is too non-linear.", status, astGetClass( this ) ); \ - } \ -\ -/* If required set output pixels bad if they have a total weight less \ - than "wlim". */ \ - if( work ) { \ - w = work; \ - d = out; \ - if( out_var ) { \ - v = out_var; \ - for( ipix_out = 0; ipix_out < npix_out; ipix_out++, d++, w++, v++ ) { \ - if( fabs( *w ) < wlim ) { \ - *d = badval; \ - *v = badval; \ - } \ - } \ - } else { \ - for( ipix_out = 0; ipix_out < npix_out; ipix_out++, d++, w++ ) { \ - if( fabs( *w ) < wlim ) *d = badval; \ - } \ - } \ -\ -/* Free the work array. */ \ - work = astFree( work ); \ - } \ -\ -/* Annul the pointer to the simplified/cloned Mapping. */ \ - simple = astAnnul( simple ); \ -\ -} - -/* Expand the above macro to generate a function for each required - data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_REBIN(LD,long double,0) -#endif -MAKE_REBIN(D,double,0) -MAKE_REBIN(F,float,0) -MAKE_REBIN(I,int,1) -MAKE_REBIN(B,signed char,1) -MAKE_REBIN(UB,unsigned char,1) - -/* Undefine the macro. */ -#undef MAKE_REBIN - -static int RebinAdaptively( AstMapping *this, int ndim_in, - const int *lbnd_in, const int *ubnd_in, - const void *in, const void *in_var, - DataType type, int spread, - const double *params, int flags, double tol, - int maxpix, const void *badval_ptr, - int ndim_out, const int *lbnd_out, - const int *ubnd_out, const int *lbnd, - const int *ubnd, int npix_out, - void *out, void *out_var, double *work, - int64_t *nused, int *status ){ -/* -* Name: -* RebinAdaptively - -* Purpose: -* Rebin a section of a data grid adaptively. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int RebinAdaptively( AstMapping *this, int ndim_in, -* const int *lbnd_in, const int *ubnd_in, -* const void *in, const void *in_var, -* DataType type, int spread, -* const double *params, int flags, double tol, -* int maxpix, const void *badval_ptr, -* int ndim_out, const int *lbnd_out, -* const int *ubnd_out, const int *lbnd, -* const int *ubnd, int npix_out, void *out, -* void *out_var, double *work, int64_t *nused, -* int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function rebins a specified section of a rectangular grid of -* data (with any number of dimensions) into another rectangular grid -* (with a possibly different number of dimensions). The coordinate -* transformation used to convert input pixel coordinates into positions -* in the output grid is given by the forward transformation of the -* Mapping which is supplied. Any pixel spreading scheme may be specified -* for distributing the flux of an input pixel amongst the output -* pixels. -* -* This function is very similar to RebinWithBlocking and RebinSection -* which lie below it in the calling hierarchy. However, this function -* also attempts to adapt to the Mapping supplied and to sub-divide the -* section being rebinned into smaller sections within which a linear -* approximation to the Mapping may be used. This reduces the number of -* Mapping evaluations, thereby improving efficiency particularly when -* complicated Mappings are involved. - -* Parameters: -* this -* Pointer to a Mapping, whose forward transformation may be -* used to transform the coordinates of pixels in the input -* grid into associated positions in the output grid. -* -* The number of input coordintes for the Mapping (Nin -* attribute) should match the value of "ndim_in" (below), and -* the number of output coordinates (Nout attribute) should -* match the value of "ndim_out". -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input data grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input data grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input data grid, its extent along a -* particular (i'th) dimension being (ubnd_in[i] - lbnd_in[i] + -* 1). They also define the input grid's coordinate system, with -* each pixel being of unit extent along each dimension with -* integral coordinate values at its centre. -* in -* Pointer to the input array of data to be rebinned (with one -* element for each pixel in the input grid). The numerical type -* of these data should match the "type" value (below). The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and data type as the "in" array), -* which represent estimates of the statistical variance -* associated with each element of the "in" array. If this -* second array is given (along with the corresponding "out_var" -* array), then estimates of the variance of the rebinned data -* will also be returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* type -* A value taken from the "DataType" enum, which specifies the -* data type of the input and output arrays containing the -* gridded data (and variance) values. -* spread -* A value selected from a set of pre-defined macros to identify -* which pixel spread function should be used. -* params -* Pointer to an optional array of parameters that may be passed -* to the pixel spread algorithm, if required. If no parameters -* are required, a NULL pointer should be supplied. -* flags -* The bitwise OR of a set of flag values which provide additional -* control over the resampling operation. -* tol -* The maximum permitted positional error in transforming input -* pixel positions into the output grid in order to rebin -* it. This should be expressed as a displacement in pixels in -* the output grid's coordinate system. If the Mapping's forward -* transformation can be approximated by piecewise linear functions -* to this accuracy, then such functions may be used instead of the -* Mapping in order to improve performance. Otherwise, every input -* pixel position will be transformed individually using the Mapping. -* -* If linear approximation is not required, a "tol" value of -* zero may be given. This will ensure that the Mapping is used -* without any approximation. -* maxpix -* A value which specifies the largest scale size on which to -* search for non-linearities in the Mapping supplied. This -* value should be expressed as a number of pixels in the input -* grid. The function will break the input section specified -* into smaller sub-sections (if necessary), each no larger than -* "maxpix" pixels in any dimension, before it attempts to -* approximate the Mapping by a linear function over each -* sub-section. -* -* If the value given is larger than the largest dimension of -* the input section (the normal recommendation), the function -* will initially search for non-linearity on a scale determined -* by the size of the input section. This is almost always -* satisfactory. Very occasionally, however, a Mapping may -* appear linear on this scale but nevertheless have smaller -* irregularities (e.g. "holes") in it. In such cases, "maxpix" -* may be set to a suitably smaller value so as to ensure this -* non-linearity is not overlooked. Typically, a value of 50 to -* 100 pixels might be suitable and should have little effect on -* performance. -* -* If too small a value is given, however, it will have the -* effect of preventing linear approximation occurring at all -* (equivalent to setting "tol" to zero). Although this may -* degrade performance, accurate results will still be obtained. -* badval_ptr -* If the AST__USEBAD flag is set (above), this parameter is a -* pointer to a value which is used to identify bad data and/or -* variance values in the input array(s). The referenced value's -* data type must match that of the "in" (and "in_var") -* arrays. The same value will also be used to flag any output -* array elements for which rebinned values could not be -* obtained. The output arrays(s) may be flagged with this -* value whether or not the AST__USEBAD flag is set (the -* function return value indicates whether any such values have -* been produced). -* ndim_out -* The number of dimensions in the output grid. This should be -* at least one. -* lbnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the first -* pixel in the output data grid along each dimension. -* ubnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the last -* pixel in the output data grid along each dimension. -* -* Note that "lbnd_out" and "ubnd_out" together define the shape -* and size of the output data grid in the same way as "lbnd_in" -* and "ubnd_in" define the shape and size of the input grid -* (see above). -* lbnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the first pixel in the -* section of the input data grid which is to be rebinned. -* ubnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the last pixel in the -* section of the input data grid which is to be rebinned. -* -* Note that "lbnd" and "ubnd" define the shape and position of -* the section of the input grid which is to be rebinned. This section -* should lie wholly within the extent of the input grid (as defined -* by the "lbnd_out" and "ubnd_out" arrays). Regions of the input -* grid lying outside this section will be ignored. -* npix_out -* The number of pixels in the output array. -* out -* Pointer to an array with the same data type as the "in" -* array, into which the rebinned data will be returned. The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the rebinned values may be returned. This array will only be -* used if the "in_var" array has been given. -* -* If no output variance estimates are required, a NULL pointer -* should be given. -* work -* An optional pointer to a double array with the same size as -* the "out" array. The contents of this array (if supplied) are -* incremented by the accumulated weights assigned to each output pixel. -* If no accumulated weights are required, a NULL pointer should be -* given. -* nused -* An optional pointer to a int64_t which will be incremented by the -* number of input values pasted into the output array. Ignored if NULL. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if "flags" included AST__CONSERVEFLUX (i.e. -* flux conservation was requested), but the forward transformation of the -* supplied Mapping had zero determinant everywhere within the region -* being binned (no error is reported if this happens). Zero is returned -* otherwise. - -*/ - -/* Local Variables: */ - double *flbnd; /* Array holding floating point lower bounds */ - double *fubnd; /* Array holding floating point upper bounds */ - double *linear_fit; /* Pointer to array of fit coefficients */ - int *hi; /* Pointer to array of section upper bounds */ - int *lo; /* Pointer to array of section lower bounds */ - int coord_in; /* Loop counter for input coordinates */ - int dim; /* Output section dimension size */ - int dimx; /* Dimension with maximum section extent */ - int divide; /* Sub-divide the output section? */ - int i; /* Loop count */ - int isLinear; /* Is the transformation linear? */ - int mxdim; /* Largest output section dimension size */ - int need_fit; /* Do we need to perform a linear fit? */ - int npix; /* Number of pixels in output section */ - int npoint; /* Number of points for obtaining a fit */ - int nvertex; /* Number of vertices of output section */ - int result; /* Returned value */ - int res1; /* Flux conservation error in 1st section? */ - int res2; /* Flux conservation error in 2nd section? */ - int toobig; /* Section too big (must sub-divide)? */ - int toosmall; /* Section too small to sub-divide? */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialisation. */ - npix = 1; - mxdim = 0; - dimx = 1; - nvertex = 1; - -/* Loop through the input grid dimensions. */ - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - -/* Obtain the extent in each dimension of the input section which is - to be rebinned, and calculate the total number of pixels it contains. */ - dim = ubnd[ coord_in ] - lbnd[ coord_in ] + 1; - npix *= dim; - -/* Find the maximum dimension size of this input section and note which - dimension has this size. */ - if ( dim > mxdim ) { - mxdim = dim; - dimx = coord_in; - } - -/* Calculate how many vertices the output section has. */ - nvertex *= 2; - } - -/* Calculate how many sample points will be needed (by the astLinearApprox - function) to obtain a linear fit to the Mapping's forward transformation. */ - npoint = 1 + 4 * ndim_in + 2 * nvertex; - -/* If the number of pixels in the input section is not at least 4 - times this number, we will probably not save significant time by - attempting to obtain a linear fit, so note that the input section - is too small. */ - toosmall = ( npix < ( 4 * npoint ) ); - -/* Note if the maximum dimension of the input section exceeds the - user-supplied scale factor. */ - toobig = ( maxpix < mxdim ); - -/* Indicate we do not yet have a linear fit. */ - linear_fit = NULL; - -/* Initialise a flag indicating if we need to perform a linear fit. This - is always the case if flux conservation was requested. */ - need_fit = ( flags & AST__CONSERVEFLUX ); - -/* If the output section is too small to be worth obtaining a linear - fit, or if the accuracy tolerance is zero, we will not - sub-divide. This means that the Mapping will be used to transform - each pixel's coordinates and no linear approximation will be - used. */ - if ( toosmall || ( tol == 0.0 ) ) { - divide = 0; - -/* Otherwise, if the largest input section dimension exceeds the - scale length given, we will sub-divide. This offers the possibility - of obtaining a linear approximation to the Mapping over a reduced - range of input coordinates (which will be handled by a recursive - invocation of this function). */ - } else if ( toobig ) { - divide = 1; - -/* If neither of the above apply, we need to do a fit regardless of - whether flux conservation was requested or not. Whether we divide or - not will depend on whether the Mapping is linear or not. Assume for - the moment that the Mapping is not linear and so we will divide. */ - } else { - need_fit = 1; - divide = 1; - } - -/* If required, attempt to fit a linear approximation to the Mapping's - forward transformation over the range of coordinates covered by the - input section. We need to temporarily copy the integer bounds into - floating point arrays to use astLinearApprox. */ - if( need_fit ) { - -/* Allocate memory for floating point bounds and for the coefficient array */ - flbnd = astMalloc( sizeof( double )*(size_t) ndim_in ); - fubnd = astMalloc( sizeof( double )*(size_t) ndim_in ); - linear_fit = astMalloc( sizeof( double )* - (size_t) ( ndim_out*( ndim_in + 1 ) ) ); - if( astOK ) { - -/* Copy the bounds into these arrays, and change them so that they refer - to the lower and upper edges of the cell rather than the centre. This - is essential if one of the axes is spanned by a single cell, since - otherwise the upper and lower bounds would be identical. */ - for( i = 0; i < ndim_in; i++ ) { - flbnd[ i ] = (double) lbnd[ i ] - 0.5; - fubnd[ i ] = (double) ubnd[ i ] + 0.5; - } - -/* Get the linear approximation to the forward transformation. */ - isLinear = astLinearApprox( this, flbnd, fubnd, tol, linear_fit ); - -/* Free the coeff array if the inverse transformation is not linear. */ - if( !isLinear ) linear_fit = astFree( linear_fit ); - - } else { - linear_fit = astFree( linear_fit ); - } - -/* Free resources */ - flbnd = astFree( flbnd ); - fubnd = astFree( fubnd ); - -/* If a linear fit was obtained, we will use it and therefore do not - wish to sub-divide further. Otherwise, we sub-divide (unless the - section is too small or too big as determined earlier) in the hope - that this may result in a linear fit next time. */ - if( linear_fit ) divide = 0; - } - -/* If no sub-division is required, perform rebinning (in a - memory-efficient manner, since the section we are rebinning might - still be very large). This will use the linear fit, if obtained - above. */ - if ( astOK ) { - if ( !divide ) { - result = RebinWithBlocking( this, linear_fit, ndim_in, lbnd_in, - ubnd_in, in, in_var, type, spread, - params, flags, badval_ptr, ndim_out, - lbnd_out, ubnd_out, lbnd, ubnd, npix_out, - out, out_var, work, nused, status ); - -/* Otherwise, allocate workspace to perform the sub-division. */ - } else { - lo = astMalloc( sizeof( int ) * (size_t) ndim_in ); - hi = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - -/* Initialise the bounds of a new input section to match the original - input section. */ - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - lo[ coord_in ] = lbnd[ coord_in ]; - hi[ coord_in ] = ubnd[ coord_in ]; - } - -/* Replace the upper bound of the section's largest dimension with the - mid-point of the section along this dimension, rounded downwards. */ - hi[ dimx ] = - (int) floor( 0.5 * (double) ( lbnd[ dimx ] + ubnd[ dimx ] ) ); - -/* Rebin the resulting smaller section using a recursive invocation - of this function. */ - res1 = RebinAdaptively( this, ndim_in, lbnd_in, ubnd_in, in, - in_var, type, spread, params, - flags, tol, maxpix, badval_ptr, ndim_out, - lbnd_out, ubnd_out, lo, hi, npix_out, out, - out_var, work, nused, status ); - -/* Now set up a second section which covers the remaining half of the - original input section. */ - lo[ dimx ] = hi[ dimx ] + 1; - hi[ dimx ] = ubnd[ dimx ]; - -/* If this section contains pixels, resample it in the same way, - summing the returned values. */ - if ( lo[ dimx ] <= hi[ dimx ] ) { - res2 = RebinAdaptively( this, ndim_in, lbnd_in, ubnd_in, in, - in_var, type, spread, params, - flags, tol, maxpix, badval_ptr, - ndim_out, lbnd_out, ubnd_out, - lo, hi, npix_out, out, out_var, work, - nused, status ); - } else { - res2 = 0; - } - -/* If neither section could be rebinned because of an indeterminant - mapping, return a result indicating this. */ - result = ( res1 && res2 ); - } - -/* Free the workspace. */ - lo = astFree( lo ); - hi = astFree( hi ); - } - } - -/* If coefficients for a linear fit were obtained, then free the space - they occupy. */ - if ( linear_fit ) linear_fit = astFree( linear_fit ); - -/* Retyurn a flag indicating if no part of the array could be binned - because of an indeterminate Mapping. */ - return result; -} - -static void RebinSection( AstMapping *this, const double *linear_fit, - int ndim_in, const int *lbnd_in, const int *ubnd_in, - const void *in, const void *in_var, double infac, - DataType type, int spread, const double *params, - int flags, const void *badval_ptr, int ndim_out, - const int *lbnd_out, const int *ubnd_out, - const int *lbnd, const int *ubnd, int npix_out, - void *out, void *out_var, double *work, - int64_t *nused, int *status ) { -/* -* Name: -* RebinSection - -* Purpose: -* Rebin a section of a data grid. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void RebinSection( AstMapping *this, const double *linear_fit, -* int ndim_in, const int *lbnd_in, const int *ubnd_in, -* const void *in, const void *in_var, double infac, -* DataType type, int spread, const double *params, -* int flags, const void *badval_ptr, int ndim_out, -* const int *lbnd_out, const int *ubnd_out, -* const int *lbnd, const int *ubnd, int npix_out, -* void *out, void *out_var, double *work, -* int64_t *nused, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function rebins a specified section of a rectangular grid of -* data (with any number of dimensions) into another rectangular grid -* (with a possibly different number of dimensions). The coordinate -* transformation used to convert input pixel coordinates into positions -* in the output grid is given by the forward transformation of the -* Mapping which is supplied or, alternatively, by a linear approximation -* fitted to a Mapping's forward transformation. Any pixel spreading scheme -* may be specified for distributing the flux of an input pixel amongst -* the output pixels. - -* Parameters: -* this -* Pointer to a Mapping, whose forward transformation may be -* used to transform the coordinates of pixels in the input -* grid into associated positions in the output grid. -* -* The number of input coordintes for the Mapping (Nin -* attribute) should match the value of "ndim_in" (below), and -* the number of output coordinates (Nout attribute) should -* match the value of "ndim_out". -* linear_fit -* Pointer to an optional array of double which contains the -* coefficients of a linear fit which approximates the above -* Mapping's forward coordinate transformation. If this is -* supplied, it will be used in preference to the above Mapping -* when transforming coordinates. This may be used to enhance -* performance in cases where evaluation of the Mapping's -* forward transformation is expensive. If no linear fit is -* available, a NULL pointer should be supplied. -* -* The way in which the fit coefficients are stored in this -* array and the number of array elements are as defined by the -* astLinearApprox function. -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input data grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input data grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input data grid, its extent along a -* particular (i'th) dimension being (ubnd_in[i] - lbnd_in[i] + -* 1). They also define the input grid's coordinate system, with -* each pixel being of unit extent along each dimension with -* integral coordinate values at its centre. -* in -* Pointer to the input array of data to be rebinned (with one -* element for each pixel in the input grid). The numerical type -* of these data should match the "type" value (below). The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and data type as the "in" array), -* which represent estimates of the statistical variance -* associated with each element of the "in" array. If this -* second array is given (along with the corresponding "out_var" -* array), then estimates of the variance of the rebinned data -* will also be returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* infac -* A factor by which to multiply the input data values before use. -* type -* A value taken from the "DataType" enum, which specifies the -* data type of the input and output arrays containing the -* gridded data (and variance) values. -* spread -* A value selected from a set of pre-defined macros to identify -* which pixel spread function should be used. -* params -* Pointer to an optional array of parameters that may be passed -* to the pixel spread algorithm, if required. If no parameters -* are required, a NULL pointer should be supplied. -* flags -* The bitwise OR of a set of flag values which provide additional -* control over the resampling operation. -* badval_ptr -* If the AST__USEBAD flag is set (above), this parameter is a -* pointer to a value which is used to identify bad data and/or -* variance values in the input array(s). The referenced value's -* data type must match that of the "in" (and "in_var") -* arrays. The same value will also be used to flag any output -* array elements for which rebinned values could not be -* obtained. The output arrays(s) may be flagged with this -* value whether or not the AST__USEBAD flag is set (the -* function return value indicates whether any such values have -* been produced). -* ndim_out -* The number of dimensions in the output grid. This should be -* at least one. -* lbnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the first -* pixel in the output data grid along each dimension. -* ubnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the last -* pixel in the output data grid along each dimension. -* -* Note that "lbnd_out" and "ubnd_out" together define the shape -* and size of the output data grid in the same way as "lbnd_in" -* and "ubnd_in" define the shape and size of the input grid -* (see above). -* lbnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the first pixel in the -* section of the input data grid which is to be rebinned. -* ubnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the last pixel in the -* section of the input data grid which is to be rebinned. -* -* Note that "lbnd" and "ubnd" define the shape and position of -* the section of the input grid which is to be rebinned. This section -* should lie wholly within the extent of the input grid (as defined -* by the "lbnd_out" and "ubnd_out" arrays). Regions of the input -* grid lying outside this section will be ignored. -* npix_out -* The number of pixels in the output array. -* out -* Pointer to an array with the same data type as the "in" -* array, into which the rebinned data will be returned. The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the rebinned values may be returned. This array will only be -* used if the "in_var" array has been given. -* -* If no output variance estimates are required, a NULL pointer -* should be given. -* work -* An optional pointer to a double array with the same size as -* the "out" array. The contents of this array (if supplied) are -* incremented by the accumulated weights assigned to each output pixel. -* If no accumulated weights are required, a NULL pointer should be -* given. -* nused -* An optional pointer to a int64_t which will be incremented by the -* number of input values pasted into the output array. Ignored if NULL. - -* Notes: -* - This function does not take steps to limit memory usage if the -* grids supplied are large. To resample large grids in a more -* memory-efficient way, the ResampleWithBlocking function should -* be used. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific data */ - AstPointSet *pset_in; /* Input PointSet for transformation */ - AstPointSet *pset_out; /* Output PointSet for transformation */ - const double *grad; /* Pointer to gradient matrix of linear fit */ - const double *zero; /* Pointer to zero point array of fit */ - double **ptr_in; /* Pointer to input PointSet coordinates */ - double **ptr_out; /* Pointer to output PointSet coordinates */ - double *accum; /* Pointer to array of accumulated sums */ - double x1; /* Interim x coordinate value */ - double xx1; /* Initial x coordinate value */ - double y1; /* Interim y coordinate value */ - double yy1; /* Initial y coordinate value */ - int *dim; /* Pointer to array of output pixel indices */ - int *offset; /* Pointer to array of output pixel offsets */ - int *stride; /* Pointer to array of output grid strides */ - int coord_in; /* Loop counter for input dimensions */ - int coord_out; /* Loop counter for output dimensions */ - int done; /* All pixel indices done? */ - int i1; /* Interim offset into "accum" array */ - int i2; /* Final offset into "accum" array */ - int idim; /* Loop counter for dimensions */ - int ix; /* Loop counter for output x coordinate */ - int iy; /* Loop counter for output y coordinate */ - int neighb; /* Number of neighbouring pixels */ - int npoint; /* Number of output points (pixels) */ - int off1; /* Interim pixel offset into output array */ - int off2; /* Interim pixel offset into output array */ - int off; /* Final pixel offset into output array */ - int point; /* Counter for output points (pixels ) */ - int s; /* Temporary variable for strides */ - const double *par; /* Pointer to parameter array */ - double fwhm; /* Full width half max. of gaussian */ - double lpar[ 1 ]; /* Local parameter array */ - void (* kernel)( double, const double [], int, double *, int * ); /* Kernel fn. */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to a structure holding thread-specific global data values */ - astGET_GLOBALS(this); - -/* Further initialisation. */ - pset_in = NULL; - ptr_in = NULL; - ptr_out = NULL; - pset_out = NULL; - neighb = 0; - kernel = NULL; - -/* Calculate the number of input points, as given by the product of - the input grid dimensions. */ - for ( npoint = 1, coord_in = 0; coord_in < ndim_in; coord_in++ ) { - npoint *= ubnd[ coord_in ] - lbnd[ coord_in ] + 1; - } - -/* Allocate workspace. */ - offset = astMalloc( sizeof( int ) * (size_t) npoint ); - stride = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - -/* Calculate the stride for each input grid dimension. */ - off = 0; - s = 1; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - stride[ coord_in ] = s; - s *= ubnd_in[ coord_in ] - lbnd_in[ coord_in ] + 1; - } - -/* A linear fit to the Mapping is available. */ -/* ========================================= */ - if ( linear_fit ) { - -/* If a linear fit to the Mapping has been provided, then obtain - pointers to the array of gradients and zero-points comprising the - fit. */ - grad = linear_fit + ndim_out; - zero = linear_fit; - -/* Create a PointSet to hold the output grid coordinates and obtain an - array of pointers to its coordinate data. */ - pset_out = astPointSet( npoint, ndim_out, "", status ); - ptr_out = astGetPoints( pset_out ); - if ( astOK ) { - -/* Initialise the count of input points. */ - point = 0; - -/* Handle the 1-dimensional case optimally. */ -/* ---------------------------------------- */ - if ( ( ndim_in == 1 ) && ( ndim_out == 1 ) ) { - -/* Loop through the pixels of the input grid and transform their x - coordinates into the output grid's coordinate system using the - linear fit supplied. Store the results in the PointSet created - above. */ - off = lbnd[ 0 ] - lbnd_in[ 0 ]; - xx1 = zero[ 0 ] + grad[ 0 ] * (double) lbnd[ 0 ]; - - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_out[ 0 ][ point ] = xx1; - xx1 += grad[ 0 ]; - offset[ point++ ] = off++; - } - -/* Handle the 2-dimensional case optimally. */ -/* ---------------------------------------- */ - } else if ( ( ndim_in == 2 ) && ( ndim_out == 2 ) ) { - -/* Loop through the range of y coordinates in the input grid and - calculate interim values of the output coordinates using the linear - fit supplied. */ - x1 = zero[ 0 ] + grad[ 1 ] * (double) ( lbnd[ 1 ] - 1 ); - y1 = zero[ 1 ] + grad[ 3 ] * (double) ( lbnd[ 1 ] - 1 ); - off1 = stride[ 1 ] * ( lbnd[ 1 ] - lbnd_in[ 1 ] - 1 ) - lbnd_in[ 0 ]; - for ( iy = lbnd[ 1 ]; iy <= ubnd[ 1 ]; iy++ ) { - x1 += grad[ 1 ]; - y1 += grad[ 3 ]; - -/* Also calculate an interim pixel offset into the input array. */ - off1 += stride[ 1 ]; - -/* Now loop through the range of input x coordinates and calculate - the final values of the input coordinates, storing the results in - the PointSet created above. */ - xx1 = x1 + grad[ 0 ] * (double) lbnd[ 0 ]; - yy1 = y1 + grad[ 2 ] * (double) lbnd[ 0 ]; - off = off1 + lbnd[ 0 ]; - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_out[ 0 ][ point ] = xx1; - xx1 += grad[ 0 ]; - ptr_out[ 1 ][ point ] = yy1; - yy1 += grad[ 2 ]; - -/* Also calculate final pixel offsets into the input array. */ - offset[ point++ ] = off++; - } - } - -/* Handle other numbers of dimensions. */ -/* ----------------------------------- */ - } else { - -/* Allocate workspace. */ - accum = astMalloc( sizeof( double ) * - (size_t) ( ndim_in * ndim_out ) ); - dim = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - -/* Initialise an array of pixel indices for the input grid which refer to the - first pixel which we will rebin. Also calculate the offset of this pixel - within the input array. */ - off = 0; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - dim[ coord_in ] = lbnd[ coord_in ]; - off += stride[ coord_in ] * - ( dim[ coord_in ] - lbnd_in[ coord_in ] ); - } - -/* To calculate each output grid coordinate we must perform a matrix - multiply on the input grid coordinates (using the gradient matrix) - and then add the zero points. However, since we will usually only - be altering one input coordinate at a time (the least - significant), we can avoid the full matrix multiply by accumulating - partial sums for the most significant input coordinates and only - altering those sums which need to change each time. The zero points - never change, so we first fill the "most significant" end of the - "accum" array with these. */ - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - accum[ ( coord_out + 1 ) * ndim_in - 1 ] = - zero[ coord_out ]; - } - coord_in = ndim_in - 1; - -/* Now loop to process each input pixel. */ - for ( done = 0; !done; point++ ) { - -/* To generate the output coordinate that corresponds to the current - input pixel, we work down from the most significant dimension - whose index has changed since the previous pixel we considered - (given by "coord_in"). For each affected dimension, we accumulate - in "accum" the matrix sum (including the zero point) for that - dimension and all higher input dimensions. We must accumulate a - separate set of sums for each output coordinate we wish to - produce. (Note that for the first pixel we process, all dimensions - are considered "changed", so we start by initialising the whole - "accum" array.) */ - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { -/* - ptr_out[ coord_out ][ point ] = zero[ coord_out ]; - for ( idim = 0; idim < ndim_in; idim++ ) { - ptr_out[ coord_out ][ point ] += - grad[ idim + coord_out*ndim_in ] * - dim[ idim ]; - } -*/ - - i1 = coord_out * ndim_in; - for ( idim = coord_in; idim >= 1; idim-- ) { - i2 = i1 + idim; - accum[ i2 - 1 ] = accum[ i2 ] + - dim[ idim ] * grad[ i2 ]; - } - -/* The output coordinate for each dimension is given by the accumulated - sum for input dimension zero (giving the sum over all input - dimensions). We do not store this in the "accum" array, but assign - the result directly to the coordinate array of the PointSet created - earlier. */ - ptr_out[ coord_out ][ point ] = accum[ i1 ] + - dim[ 0 ] * grad[ i1 ]; - } - -/* Store the offset of the current pixel in the input array. */ - offset[ point ] = off; - -/* Now update the array of pixel indices to refer to the next input pixel. */ - coord_in = 0; - do { - -/* The least significant index which currently has less than its maximum - value is incremented by one. The offset into the input array is updated - accordingly. */ - if ( dim[ coord_in ] < ubnd[ coord_in ] ) { - dim[ coord_in ]++; - off += stride[ coord_in ]; - break; - -/* Any less significant indices which have reached their maximum value - are returned to their minimum value and the input pixel offset is - decremented appropriately. */ - } else { - dim[ coord_in ] = lbnd[ coord_in ]; - off -= stride[ coord_in ] * - ( ubnd[ coord_in ] - lbnd[ coord_in ] ); - -/* All the output pixels have been processed once the most significant - pixel index has been returned to its minimum value. */ - done = ( ++coord_in == ndim_in ); - } - } while ( !done ); - } - } - -/* Free the workspace. */ - accum = astFree( accum ); - dim = astFree( dim ); - } - } - -/* No linear fit to the Mapping is available. */ -/* ========================================== */ - } else { - -/* Create a PointSet to hold the coordinates of the input pixels and - obtain a pointer to its coordinate data. */ - pset_in = astPointSet( npoint, ndim_in, "", status ); - ptr_in = astGetPoints( pset_in ); - if ( astOK ) { - -/* Initialise the count of input points. */ - point = 0; - -/* Handle the 1-dimensional case optimally. */ -/* ---------------------------------------- */ - if ( ndim_in == 1 && ndim_out == 1 ) { - -/* Loop through the required range of input x coordinates, assigning - the coordinate values to the PointSet created above. Also store a - pixel offset into the input array. */ - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_in[ 0 ][ point ] = (double) ix; - offset[ point++ ] = ix - lbnd_in[ 0 ]; - } - -/* Handle the 2-dimensional case optimally. */ -/* ---------------------------------------- */ - } else if ( ndim_in == 2 && ndim_out == 2) { - -/* Loop through the required range of input y coordinates, - calculating an interim pixel offset into the input array. */ - off1 = stride[ 1 ] * ( lbnd[ 1 ] - lbnd_in[ 1 ] - 1 ) - - lbnd_in[ 0 ]; - for ( iy = lbnd[ 1 ]; iy <= ubnd[ 1 ]; iy++ ) { - off1 += stride[ 1 ]; - -/* Loop through the required range of input x coordinates, assigning - the coordinate values to the PointSet created above. Also store a - final pixel offset into the input array. */ - off2 = off1 + lbnd[ 0 ]; - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_in[ 0 ][ point ] = (double) ix; - ptr_in[ 1 ][ point ] = (double) iy; - offset[ point++ ] = off2++; - } - } - -/* Handle other numbers of dimensions. */ -/* ----------------------------------- */ - } else { - -/* Allocate workspace. */ - dim = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - -/* Initialise an array of pixel indices for the input grid which - refer to the first pixel to be rebinned. Also calculate the offset - of this pixel within the input array. */ - off = 0; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - dim[ coord_in ] = lbnd[ coord_in ]; - off += stride[ coord_in ] * - ( dim[ coord_in ] - lbnd_in[ coord_in ] ); - } - -/* Loop to generate the coordinates of each input pixel. */ - for ( done = 0; !done; point++ ) { - -/* Copy each pixel's coordinates into the PointSet created above. */ - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - ptr_in[ coord_in ][ point ] = - (double) dim[ coord_in ]; - } - -/* Store the offset of the pixel in the input array. */ - offset[ point ] = off; - -/* Now update the array of pixel indices to refer to the next input - pixel. */ - coord_in = 0; - do { - -/* The least significant index which currently has less than its - maximum value is incremented by one. The offset into the input - array is updated accordingly. */ - if ( dim[ coord_in ] < ubnd[ coord_in ] ) { - dim[ coord_in ]++; - off += stride[ coord_in ]; - break; - -/* Any less significant indices which have reached their maximum value - are returned to their minimum value and the input pixel offset is - decremented appropriately. */ - } else { - dim[ coord_in ] = lbnd[ coord_in ]; - off -= stride[ coord_in ] * - ( ubnd[ coord_in ] - lbnd[ coord_in ] ); - -/* All the input pixels have been processed once the most significant - pixel index has been returned to its minimum value. */ - done = ( ++coord_in == ndim_in ); - } - } while ( !done ); - } - } - -/* Free the workspace. */ - dim = astFree( dim ); - } - -/* When all the input pixel coordinates have been generated, use the - Mapping's forward transformation to generate the output coordinates - from them. Obtain an array of pointers to the resulting coordinate - data. */ - pset_out = astTransform( this, pset_in, 1, NULL ); - ptr_out = astGetPoints( pset_out ); - } - -/* Annul the PointSet containing the input coordinates. */ - pset_in = astAnnul( pset_in ); - } - } - - -/* Rebin the input grid. */ -/* ------------------------ */ - if( astOK ) { - -/* Identify the pixel spreading scheme to be used. */ -/* Nearest pixel. */ -/* -------------- */ - switch ( spread ) { - case AST__NEAREST: - -/* Define a macro to use a "case" statement to invoke the - nearest-pixel spreading function appropriate to a given data - type. */ -#define CASE_NEAREST(X,Xtype) \ - case ( TYPE_##X ): \ - SpreadNearest##X( ndim_out, lbnd_out, ubnd_out, \ - (Xtype *) in, (Xtype *) in_var, \ - infac, npoint, offset, \ - (const double *const *) ptr_out, \ - flags, *( (Xtype *) badval_ptr ), \ - npix_out, (Xtype *) out, \ - (Xtype *) out_var, work, nused, status ); \ - break; - -/* Use the above macro to invoke the appropriate function. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_NEAREST(LD,long double) -#endif - CASE_NEAREST(D,double) - CASE_NEAREST(F,float) - CASE_NEAREST(I,int) - CASE_NEAREST(B,signed char) - CASE_NEAREST(UB,unsigned char) - - case ( TYPE_L ): break; - case ( TYPE_K ): break; - case ( TYPE_S ): break; - case ( TYPE_UL ): break; - case ( TYPE_UI ): break; - case ( TYPE_UK ): break; - case ( TYPE_US ): break; - } - break; - -/* Undefine the macro. */ -#undef CASE_NEAREST - -/* Linear spreading. */ -/* ----------------- */ -/* Note this is also the default if zero is given. */ - case AST__LINEAR: - case 0: - -/* Define a macro to use a "case" statement to invoke the linear - spreading function appropriate to a given data type. */ -#define CASE_LINEAR(X,Xtype) \ - case ( TYPE_##X ): \ - SpreadLinear##X( ndim_out, lbnd_out, ubnd_out,\ - (Xtype *) in, (Xtype *) in_var, \ - infac, npoint, offset, \ - (const double *const *) ptr_out, \ - flags, *( (Xtype *) badval_ptr ), \ - npix_out, (Xtype *) out, \ - (Xtype *) out_var, work, nused, status ); \ - break; - -/* Use the above macro to invoke the appropriate function. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_LINEAR(LD,long double) -#endif - CASE_LINEAR(D,double) - CASE_LINEAR(F,float) - CASE_LINEAR(I,int) - CASE_LINEAR(B,signed char) - CASE_LINEAR(UB,unsigned char) - - case ( TYPE_L ): break; - case ( TYPE_K ): break; - case ( TYPE_S ): break; - case ( TYPE_UL ): break; - case ( TYPE_UI ): break; - case ( TYPE_UK ): break; - case ( TYPE_US ): break; - } - break; - -/* Undefine the macro. */ -#undef CASE_LINEAR - -/* Spreading using a 1-d kernel. */ -/* ----------------------------- */ - case AST__SINC: - case AST__SINCCOS: - case AST__SINCGAUSS: - case AST__GAUSS: - case AST__SINCSINC: - case AST__SOMB: - case AST__SOMBCOS: - -/* Obtain a pointer to the appropriate 1-d kernel function (either - internal or user-defined) and set up any parameters it may - require. */ - par = NULL; - switch ( spread ) { - -/* sinc(pi*x) */ -/* ---------- */ -/* Assign the kernel function. */ - case AST__SINC: - kernel = Sinc; - -/* Calculate the number of neighbouring pixels to use. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) { - neighb = 2; - } else { - neighb = MaxI( 1, neighb, status ); - } - break; - -/* somb(pi*x) */ -/* ---------- */ -/* Assign the kernel function. */ - case AST__SOMB: - kernel = Somb; - -/* Calculate the number of neighbouring pixels to use. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) { - neighb = 2; - } else { - neighb = MaxI( 1, neighb, status ); - } - break; - -/* sinc(pi*x)*cos(k*pi*x) */ -/* ---------------------- */ -/* Assign the kernel function. */ - case AST__SINCCOS: - kernel = SincCos; - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 0.5 / MaxD( 1.0, params[ 1 ], status ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, the number will be calculated automatically below. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = INT_MAX; - -/* Calculate the maximum number of neighbouring pixels required by the - width of the kernel, and use this value if preferable. */ - neighb = MinI( neighb, - (int) ceil( MaxD( 1.0, params[ 1 ], status ) ), status ); - break; - -/* sinc(pi*x)*exp(-k*x*x) */ -/* ---------------------- */ -/* Assign the kernel function. */ - case AST__SINCGAUSS: - kernel = SincGauss; - -/* Constrain the full width half maximum of the gaussian factor. */ - fwhm = MaxD( 0.1, params[ 1 ], status ); - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 4.0 * log( 2.0 ) / ( fwhm * fwhm ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, use the number of neighbouring pixels required by the width - of the kernel (out to where the gaussian term falls to 1% of its - peak value). */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = (int) ceil( sqrt( -log( 0.01 ) / - lpar[ 0 ] ) ); - break; - -/* exp(-k*x*x) */ -/* ----------- */ -/* Assign the kernel function. */ - case AST__GAUSS: - kernel = Gauss; - -/* Constrain the full width half maximum of the gaussian. */ - fwhm = MaxD( 0.1, params[ 1 ], status ); - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 4.0 * log( 2.0 ) / ( fwhm * fwhm ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, use the number of neighbouring pixels required by the width - of the kernel (out to where the gaussian term falls to 1% of its - peak value). */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = (int) ceil( sqrt( -log( 0.01 ) / - lpar[ 0 ] ) ); - break; - -/* somb(pi*x)*cos(k*pi*x) */ -/* ---------------------- */ -/* Assign the kernel function. */ - case AST__SOMBCOS: - kernel = SombCos; - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 0.5 / MaxD( 1.0, params[ 1 ], status ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, the number will be calculated automatically below. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = INT_MAX; - -/* Calculate the maximum number of neighbouring pixels required by the - width of the kernel, and use this value if preferable. */ - neighb = MinI( neighb, - (int) ceil( MaxD( 1.0, params[ 1 ], status ) ), status ); - break; - -/* sinc(pi*x)*sinc(k*pi*x) */ -/* ----------------------- */ -/* Assign the kernel function. */ - case AST__SINCSINC: - kernel = SincSinc; - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 0.5 / MaxD( 1.0, params[ 1 ], status ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, the number will be calculated automatically below. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = INT_MAX; - -/* Calculate the maximum number of neighbouring pixels required by the - width of the kernel, and use this value if preferable. */ - neighb = MinI( neighb, - (int) ceil( MaxD( 1.0, params[ 1 ], status ) ), status ); - break; - } - -/* Define a macro to use a "case" statement to invoke the 1-d kernel - interpolation function appropriate to a given data type, passing it - the pointer to the kernel function obtained above. */ -#define CASE_KERNEL1(X,Xtype) \ - case ( TYPE_##X ): \ - SpreadKernel1##X( this, ndim_out, lbnd_out, ubnd_out, \ - (Xtype *) in, (Xtype *) in_var, \ - infac, npoint, offset, \ - (const double *const *) ptr_out, \ - kernel, neighb, par, flags, \ - *( (Xtype *) badval_ptr ), \ - npix_out, (Xtype *) out, \ - (Xtype *) out_var, work, nused, \ - status ); \ - break; - -/* Use the above macro to invoke the appropriate function. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_KERNEL1(LD,long double) -#endif - CASE_KERNEL1(D,double) - CASE_KERNEL1(F,float) - CASE_KERNEL1(I,int) - CASE_KERNEL1(B,signed char) - CASE_KERNEL1(UB,unsigned char) - - case ( TYPE_L ): break; - case ( TYPE_K ): break; - case ( TYPE_S ): break; - case ( TYPE_UL ): break; - case ( TYPE_UI ): break; - case ( TYPE_UK ): break; - case ( TYPE_US ): break; - } - break; - -/* Undefine the macro. */ -#undef CASE_KERNEL1 - -/* Error: invalid pixel spreading scheme specified. */ -/* ------------------------------------------------ */ - default: - -/* Define a macro to report an error message appropriate to a given - data type. */ -#define CASE_ERROR(X) \ - case TYPE_##X: \ - astError( AST__SISIN, "astRebin"#X"(%s): Invalid " \ - "pixel spreading scheme (%d) specified.", status, \ - astGetClass( unsimplified_mapping ), spread ); \ - break; - -/* Use the above macro to report an appropriate error message. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_ERROR(LD) -#endif - CASE_ERROR(D) - CASE_ERROR(F) - CASE_ERROR(I) - CASE_ERROR(B) - CASE_ERROR(UB) - - case ( TYPE_L ): break; - case ( TYPE_K ): break; - case ( TYPE_S ): break; - case ( TYPE_UL ): break; - case ( TYPE_UI ): break; - case ( TYPE_UK ): break; - case ( TYPE_US ): break; - } - break; - -/* Undefine the macro. */ -#undef CASE_ERROR - } - } - -/* Annul the PointSet used to hold output coordinates. */ - pset_out = astAnnul( pset_out ); - -/* Free the workspace. */ - offset = astFree( offset ); - stride = astFree( stride ); -} - -/* -*++ -* Name: -c astRebinSeq -f AST_REBINSEQ - -* Purpose: -* Rebin a region of a sequence of data grids. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astRebinSeq( AstMapping *this, double wlim, int ndim_in, -c const int lbnd_in[], const int ubnd_in[], -c const in[], const in_var[], -c int spread, const double params[], int flags, -c double tol, int maxpix, badval, -c int ndim_out, const int lbnd_out[], -c const int ubnd_out[], const int lbnd[], -c const int ubnd[], out[], out_var[], -c double weights[], int64_t *nused ); -f CALL AST_REBINSEQ( THIS, WLIM, NDIM_IN, LBND_IN, UBND_IN, IN, IN_VAR, -f SPREAD, PARAMS, FLAGS, TOL, MAXPIX, BADVAL, -f NDIM_OUT, LBND_OUT, UBND_OUT, LBND, UBND, OUT, -f OUT_VAR, WEIGHTS, NUSED, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -* This set of -c functions is identical to astRebin -f routines is identical to AST_REBIN -* except that the rebinned input data is added into the supplied -* output arrays, rather than simply over-writing the contents of the -* output arrays. Thus, by calling this -c function -f routine -* repeatedly, a sequence of input arrays can be rebinned and accumulated -* into a single output array, effectively forming a mosaic of the -* input data arrays. -* -* In addition, the weights associated with each output pixel are -* returned. The weight of an output pixel indicates the number of input -* pixels which have been accumulated in that output pixel. If the entire -* value of an input pixel is assigned to a single output pixel, then the -* weight of that output pixel is incremented by one. If some fraction of -* the value of an input pixel is assigned to an output pixel, then the -* weight of that output pixel is incremented by the fraction used. -* -* The start of a new sequence is indicated by specifying the -* AST__REBININIT flag via the -c "flags" parameter. -f FLAGS argument. -* This causes the supplied arrays to be filled with zeros before the -* rebinned input data is added into them. Subsequenct invocations -* within the same sequence should omit the AST__REBININIT flag. -* -* The last call in a sequence is indicated by specifying the -* AST__REBINEND flag. Depending on which flags are supplied, this may -* cause the output data and variance arrays to be normalised before -* being returned. This normalisation consists of dividing the data -* array by the weights array, and can eliminate artifacts which may be -* introduced into the rebinned data as a consequence of aliasing -* between the input and output grids. This results in each output -* pixel value being the weighted mean of the input pixel values that -* fall in the neighbourhood of the output pixel (rather like -c astResample). -f AST_RESAMPLE). -* Optionally, these normalised -* values can then be multiplied by a scaling factor to ensure that the -* total data sum in any small area is unchanged. This scaling factor -* is equivalent to the number of input pixel values that fall into each -* output pixel. In addition to -* normalisation of the output data values, any output variances are -* also appropriately normalised, and any output data values with -* weight less than -c "wlim" are set to "badval". -f WLIM are set to BADVAL. -* -* Output variances can be generated in two ways; by rebinning the supplied -* input variances with appropriate weights, or by finding the spread of -* input data values contributing to each output pixel (see the AST__GENVAR -* and AST__USEVAR flags). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to a Mapping, whose forward transformation will be -* used to transform the coordinates of pixels in the input -* grid into the coordinate system of the output grid. -* -* The number of input coordinates used by this Mapping (as -* given by its Nin attribute) should match the number of input -c grid dimensions given by the value of "ndim_in" -f grid dimensions given by the value of NDIM_IN -* below. Similarly, the number of output coordinates (Nout -* attribute) should match the number of output grid dimensions -c given by "ndim_out". -f given by NDIM_OUT. -c If "in" is NULL, the Mapping will not be used, but a valid -c Mapping must still be supplied. -c wlim -f WLIM = DOUBLE PRECISION (Given) -* This value is only used if the AST__REBINEND flag is specified -* via the -c "flags" parameter. -f FLAGS argument. -* It gives the required number of input pixel values which must -* contribute to an output pixel (i.e. the output pixel weight) in -* order for the output pixel value to be considered valid. If the sum -* of the input pixel weights contributing to an output pixel is less -* than the supplied -c "wlim" -f WLIM -* value, then the output pixel value is returned set to the -* supplied bad value. If the supplied value is less than 1.0E-10 -* then 1.0E-10 is used instead. -c ndim_in -f NDIM_IN = INTEGER (Given) -* The number of dimensions in the input grid. This should be at -* least one. -c Not used if "in" is NULL. -c lbnd_in -f LBND_IN( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the centre of the first pixel -* in the input grid along each dimension. -c Not used if "in" is NULL. -c ubnd_in -f UBND_IN( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the centre of the last pixel in -* the input grid along each dimension. -* -c Note that "lbnd_in" and "ubnd_in" together define the shape -f Note that LBND_IN and UBND_IN together define the shape -* and size of the input grid, its extent along a particular -c (j'th) dimension being ubnd_in[j]-lbnd_in[j]+1 (assuming the -c index "j" to be zero-based). They also define -f (J'th) dimension being UBND_IN(J)-LBND_IN(J)+1. They also define -* the input grid's coordinate system, each pixel having unit -* extent along each dimension with integral coordinate values -* at its centre. -c Not used if "in" is NULL. -c in -f IN( * ) = (Given) -c Pointer to an array, with one element for each pixel in the -f An array, with one element for each pixel in the -* input grid, containing the input data to be rebined. The -* numerical type of this array should match the 1- or -* 2-character type code appended to the function name (e.g. if -c you are using astRebinSeqF, the type of each array element -c should be "float"). -f you are using AST_REBINSEQR, the type of each array element -f should be REAL). -* -* The storage order of data within this array should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -c If a NULL pointer is supplied for "in", then no data is added to -c the output arrays, but any initialisation or normalisation -c requested by "flags" is still performed. -c in_var -f IN_VAR( * ) = (Given) -* An optional -c pointer to a -* second array with the same size and type as the -c "in" -f IN -* array. If given, this should contain a set of non-negative values -* which represent estimates of the statistical variance associated -* with each element of the -c "in" -f IN -* array. -* If neither the AST__USEVAR nor the AST__VARWGT flag is set, no -* input variance estimates are required and this -f array -c pointer -* will not be used. -f A dummy (e.g. one-element) array -c A NULL pointer -* may then be supplied. -c spread -f SPREAD = INTEGER (Given) -c This parameter specifies the scheme to be used for dividing -f This argument specifies the scheme to be used for dividing -* each input data value up amongst the corresponding output pixels. -* It may be used to select -* from a set of pre-defined schemes by supplying one of the -* values described in the "Pixel Spreading Schemes" -* section in the description of the -c astRebin functions. -f AST_REBIN routines. -* If a value of zero is supplied, then the default linear spreading -* scheme is used (equivalent to supplying the value AST__LINEAR). -c Not used if "in" is NULL. -c params -f PARAMS( * ) = DOUBLE PRECISION (Given) -c An optional pointer to an array of double which should contain -f An optional array which should contain -* any additional parameter values required by the pixel -* spreading scheme. If such parameters are required, this -* will be noted in the "Pixel Spreading Schemes" section in the -* description of the -c astRebin functions. -f AST_REBIN routines. -* -c If no additional parameters are required, this array is not -c used and a NULL pointer may be given. -f If no additional parameters are required, this array is not -f used. A dummy (e.g. one-element) array may then be supplied. -c Not used if "in" is NULL. -c flags -f FLAGS = INTEGER (Given) -c The bitwise OR of a set of flag values which may be used to -f The sum of a set of flag values which may be used to -* provide additional control over the rebinning operation. See -* the "Control Flags" section below for a description of the -* options available. If no flag values are to be set, a value -* of zero should be given. -c tol -f TOL = DOUBLE PRECISION (Given) -* The maximum tolerable geometrical distortion which may be -* introduced as a result of approximating non-linear Mappings -* by a set of piece-wise linear transformations. This should be -* expressed as a displacement in pixels in the output grid's -* coordinate system. -* -* If piece-wise linear approximation is not required, a value -* of zero may be given. This will ensure that the Mapping is -* used without any approximation, but may increase execution -* time. -* -* If the value is too high, discontinuities between the linear -* approximations used in adjacent panel will be higher, and may -* cause the edges of the panel to be visible when viewing the output -* image at high contrast. If this is a problem, reduce the -* tolerance value used. -c Not used if "in" is NULL. -c maxpix -f MAXPIX = INTEGER (Given) -* A value which specifies an initial scale size (in pixels) for -* the adaptive algorithm which approximates non-linear Mappings -* with piece-wise linear transformations. Normally, this should -* be a large value (larger than any dimension of the region of -* the input grid being used). In this case, a first attempt to -* approximate the Mapping by a linear transformation will be -* made over the entire input region. -* -* If a smaller value is used, the input region will first be -c divided into sub-regions whose size does not exceed "maxpix" -f divided into sub-regions whose size does not exceed MAXPIX -* pixels in any dimension. Only at this point will attempts at -* approximation commence. -* -* This value may occasionally be useful in preventing false -* convergence of the adaptive algorithm in cases where the -* Mapping appears approximately linear on large scales, but has -* irregularities (e.g. holes) on smaller scales. A value of, -* say, 50 to 100 pixels can also be employed as a safeguard in -* general-purpose software, since the effect on performance is -* minimal. -* -* If too small a value is given, it will have the effect of -* inhibiting linear approximation altogether (equivalent to -c setting "tol" to zero). Although this may degrade -f setting TOL to zero). Although this may degrade -* performance, accurate results will still be obtained. -c Not used if "in" is NULL. -c badval -f BADVAL = (Given) -* This argument should have the same type as the elements of -c the "in" array. It specifies the value used to flag missing -f the IN array. It specifies the value used to flag missing -* data (bad pixels) in the input and output arrays. -* -c If the AST__USEBAD flag is set via the "flags" parameter, -f If the AST__USEBAD flag is set via the FLAGS argument, -c then this value is used to test for bad pixels in the "in" -c (and "in_var") array(s). -f then this value is used to test for bad pixels in the IN -f (and IN_VAR) array(s). -* -* In all cases, this value is also used to flag any output -c elements in the "out" (and "out_var") array(s) for which -f elements in the OUT (and OUT_VAR) array(s) for which -* rebined values could not be obtained (see the "Propagation -* of Missing Data" section below for details of the -* circumstances under which this may occur). -c ndim_out -f NDIM_OUT = INTEGER (Given) -* The number of dimensions in the output grid. This should be -* at least one. It need not necessarily be equal to the number -* of dimensions in the input grid. -c lbnd_out -f LBND_OUT( NDIM_OUT ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_out" elements, -f An array -* containing the coordinates of the centre of the first pixel -* in the output grid along each dimension. -c ubnd_out -f UBND_OUT( NDIM_OUT ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_out" elements, -f An array -* containing the coordinates of the centre of the last pixel in -* the output grid along each dimension. -* -c Note that "lbnd_out" and "ubnd_out" together define the -f Note that LBND_OUT and UBND_OUT together define the -* shape, size and coordinate system of the output grid in the -c same way as "lbnd_in" and "ubnd_in" define the shape, size -f same way as LBND_IN and UBND_IN define the shape, size -* and coordinate system of the input grid. -c lbnd -f LBND( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the first pixel in the region -* of the input grid which is to be included in the rebined output -* array. -c Not used if "in" is NULL. -c ubnd -f UBND( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the last pixel in the region of -* the input grid which is to be included in the rebined output -* array. -* -c Note that "lbnd" and "ubnd" together define the shape and -f Note that LBND and UBND together define the shape and -* position of a (hyper-)rectangular region of the input grid -* which is to be included in the rebined output array. This region -* should lie wholly within the extent of the input grid (as -c defined by the "lbnd_in" and "ubnd_in" arrays). Regions of -f defined by the LBND_IN and UBND_IN arrays). Regions of -* the input grid lying outside this region will not be used. -c Not used if "in" is NULL. -c out -f OUT( * ) = (Given and Returned) -c Pointer to an array, with one element for each pixel in the -f An array, with one element for each pixel in the -* output grid. The rebined data values will be added into the -* original contents of this array. The numerical type of this array -* should match that of the -c "in" array, and the data storage order should be such -f IN array, and the data storage order should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -c out_var -f OUT_VAR( * ) = (Given and Returned) -* A -c pointer to an -* array with the same type and size as the -c "out" -f OUT -* array. This -c pointer -f array -* will only be used if the AST__USEVAR or AST__GENVAR flag is set -f via the FLAGS argument, -f via the "flags" parameter, -* in which case variance estimates for the rebined data values will -* be added into the array. If neither the AST__USEVAR flag nor the -* AST__GENVAR flag is set, no output variance estimates will be -* calculated and this -c pointer -f array -* will not be used. A -c NULL pointer -f dummy (e.g. one-element) array -* may then be supplied. -c weights -f WEIGHTS( * ) = DOUBLE PRECISION (Given and Returned) -c Pointer to an array of double, -f An array -* with one or two elements for each pixel in the output grid, -* depending on whether or not the AST__GENVAR flag has been supplied -* via the -c "flags" parameter. -f FLAGS parameter. -* If AST__GENVAR has not been specified then the array should have -* one element for each output pixel, and it will be used to -* accumulate the weight associated with each output pixel. -* If AST__GENVAR has been specified then the array should have -* two elements for each output pixel. The first half of the array -* is again used to accumulate the weight associated with each output -* pixel, and the second half is used to accumulate the square of -* the weights. In each half, the data storage order should be such that -* the index of the first grid dimension varies most rapidly and that of -* the final dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -c nused -f NUSED = INTEGER*8 (Given and Returned) -c A pointer to an int64_t containing the -f The -* number of input data values that have been added into the output -* array so far. The supplied value is incremented on exit by the -* number of input values used. The value is initially set to zero -* if the AST__REBININIT flag is set in -c "flags". -f FLAGS. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Data Type Codes: -* To select the appropriate rebinning function, you should -c replace in the generic function name astRebinSeq with a -f replace in the generic function name AST_REBINSEQ with a -* 1- or 2-character data type code, so as to match the numerical -* type of the data you are processing, as follows: -c - D: double -c - F: float -c - I: int -c - B: byte (signed char) -c - UB: unsigned byte (unsigned char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - B: BYTE (treated as signed) -f - UB: BYTE (treated as unsigned) -* -c For example, astRebinSeqD would be used to process "double" -c data, while astRebinSeqI would be used to process "int" -c data, etc. -f For example, AST_REBIND would be used to process DOUBLE -f PRECISION data, while AST_REBINI would be used to process -f integer data (stored in an INTEGER array), etc. -* -* Note that, unlike -c astResample, the astRebinSeq -f AST_RESAMPLE, the AST_REBINSEQ -* set of functions does not yet support unsigned integer data types -* or integers of different sizes. - -* Control Flags: -c The following flags are defined in the "ast.h" header file and -f The following flags are defined in the AST_PAR include file and -* may be used to provide additional control over the rebinning -* process. Having selected a set of flags, you should supply the -c bitwise OR of their values via the "flags" parameter: -f sum of their values via the FLAGS argument: -* -* - AST__REBININIT: Used to mark the first call in a sequence. It indicates -* that the supplied -c "out", "out_var" and "weights" -f OUT, OUT_VAR and WEIGHTS -* arrays should be filled with zeros (thus over-writing any supplied -* values) before adding the rebinned input data into them. This flag -* should be used when rebinning the first input array in a sequence. -* - AST__REBINEND: Used to mark the last call in a sequence. It causes -* each value in the -c "out" and "out_var" -f OUT and OUT_VAR -* arrays to be divided by a normalisation factor before being -* returned. The normalisation factor for each output data value is just -* the corresponding value from the weights array. The normalisation -* factor for each output variance value is the square of the data value -* normalisation factor (see also AST__CONSERVEFLUX). It also causes -* output data values to be set bad if the corresponding weight is less -* than the value supplied for -c parameter "wlim". -f argument WLIM. -* It also causes any temporary values stored in the output variance array -* (see flag AST__GENVAR below) to be converted into usable variance values. -* Note, this flag is ignored if the AST__NONORM flag is set. -* - AST__USEBAD: Indicates that there may be bad pixels in the -* input array(s) which must be recognised by comparing with the -c value given for "badval" and propagated to the output array(s). -f value given for BADVAL and propagated to the output array(s). -* If this flag is not set, all input values are treated literally -c and the "badval" value is only used for flagging output array -f and the BADVAL value is only used for flagging output array -* values. -* - AST__USEVAR: Indicates that output variance estimates should be -* created by rebinning the supplied input variance estimates. An -* error will be reported if both this flag and the AST__GENVAR flag -* are supplied. -* - AST__GENVAR: Indicates that output variance estimates should be -* created based on the spread of input data values contributing to each -* output pixel. An error will be reported if both this flag and the -* AST__USEVAR flag are supplied. If the AST__GENVAR flag is specified, -* the supplied output variance array is first used as a work array to -* accumulate the temporary values needed to generate the output -* variances. When the sequence ends (as indicated by the -* AST__REBINEND flag), the contents of the output variance array are -* converted into the required variance estimates. If the generation of -* such output variances is required, this flag should be used on every -* invocation of this -c function -f routine -* within a sequence, and any supplied input variances will have no effect -* on the output variances (although input variances will still be used -* to weight the input data if the AST__VARWGT flag is also supplied). -* The statistical meaning of these output varianes is determined by -* the presence or absence of the AST__DISVAR flag (see below). -* - AST__DISVAR: This flag is ignored unless the AST__GENVAR flag -* has also been specified. It determines the statistical meaning of -* the generated output variances. If AST__DISVAR is not specified, -* generated variances represent variances on the output mean values. If -* AST__DISVAR is specified, the generated variances represent the variance -* of the distribution from which the input values were taken. Each output -* variance created with AST__DISVAR will be larger than that created -* without AST__DISVAR by a factor equal to the number of input samples -* that contribute to the output sample. -* - AST__VARWGT: Indicates that the input data should be weighted by -* the reciprocal of the input variances. Otherwise, all input data are -* given equal weight. If this flag is specified, the calculation of the -* output variances (if any) is modified to take account of the -* varying weights assigned to the input data values. -* - AST__NONORM: If the simple unnormalised sum of all input data falling -* in each output pixel is required, then this flag should be set on -* each call in the sequence and the AST__REBINEND should not be used -* on the last call. In this case -c NULL pointers can be supplied for "weights" and "nused". -f WEIGHTS and NUSED are ignored. -* This flag cannot be used with the AST__CONSERVEFLUX, AST__GENVAR -* or AST__VARWGT flag. -* - AST__CONSERVEFLUX: Indicates that the normalized output pixel values -* generated by the AST__REBINEND flag should be scaled in such a way as -* to preserve the total data value in a feature on the sky. Without this -* flag, each normalised output pixel value represents a weighted mean -* of the input data values around the corresponding input position. -f (i.e. AST_REBINSEQ behaves similarly to AST_RESAMPLE). This -f (i.e. AST_REBINSEQ behaves similarly to AST_RESAMPLE). This -* is appropriate if the input data represents the spatial density of -* some quantity (e.g. surface brightness in Janskys per square -* arc-second) because the output pixel values will have the same -* normalisation and units as the input pixel values. However, if the -* input data values represent flux (or some other physical quantity) -* per pixel, then the AST__CONSERVEFLUX flag could be of use. It causes -* each output pixel value to be scaled by the ratio of the output pixel -* size to the input pixel size. -* -* This flag can only be used if the Mapping is successfully approximated -* by one or more linear transformations. Thus an error will be reported -* if it used when the -c "tol" parameter -f TOL argument -* is set to zero (which stops the use of linear approximations), or -* if the Mapping is too non-linear to be approximated by a piece-wise -* linear transformation. The ratio of output to input pixel size is -* evaluated once for each panel of the piece-wise linear approximation to -* the Mapping, and is assumed to be constant for all output pixels in the -* panel. The scaling factors for adjacent panels will in general -* differ slightly, and so the joints between panels may be visible when -* viewing the output image at high contrast. If this is a problem, -* reduce the value of the -c "tol" parameter -f TOL argument -* until the difference between adjacent panels is sufficiently small -* to be insignificant. -* -* This flag should normally be supplied on each invocation of -c astRebinSeq -f AST_REBINSEQ -* within a given sequence. -* -* Note, this flag cannot be used in conjunction with the AST__NOSCALE -* flag (an error will be reported if both flags are specified). - -* Propagation of Missing Data: -* Instances of missing data (bad pixels) in the output grid are -c identified by occurrences of the "badval" value in the "out" -f identified by occurrences of the BADVAL value in the OUT -* array. These are only produced if the AST__REBINEND flag is -* specified and a pixel has zero weight. -* -* An input pixel is considered bad (and is consequently ignored) if -* its -c data value is equal to "badval" and the AST__USEBAD flag is -c set via the "flags" parameter. -f data value is equal to BADVAL and the AST__USEBAD flag is -f set via the FLAGS argument. -* -* In addition, associated output variance estimates (if -c calculated) may be declared bad and flagged with the "badval" -c value in the "out_var" array for similar reasons. -f calculated) may be declared bad and flagged with the BADVAL -f value in the OUT_VAR array for similar reasons. - -*-- -*/ -/* Define a macro to implement the function for a specific data - type. */ -#define MAKE_REBINSEQ(X,Xtype,IntType) \ -static void RebinSeq##X( AstMapping *this, double wlim, int ndim_in, \ - const int lbnd_in[], const int ubnd_in[], \ - const Xtype in[], const Xtype in_var[], \ - int spread, const double params[], int flags, \ - double tol, int maxpix, Xtype badval, \ - int ndim_out, const int lbnd_out[], \ - const int ubnd_out[], const int lbnd[], \ - const int ubnd[], Xtype out[], Xtype out_var[], \ - double weights[], int64_t *nused, int *status ) { \ -\ -/* Local Variables: */ \ - AstMapping *simple; /* Pointer to simplified Mapping */ \ - Xtype *d; /* Pointer to next output data value */ \ - Xtype *v; /* Pointer to next output variance value */ \ - astDECLARE_GLOBALS /* Thread-specific data */ \ - double *w; /* Pointer to next weight value */ \ - double mwpip; /* Mean weight per input pixel */ \ - double neff; /* Effective number of contributing input pixels */ \ - double sw; /* Sum of weights at output pixel */ \ - double wgt; /* Output pixel weight */ \ - int i; /* Loop counter for output pixels */ \ - int idim; /* Loop counter for coordinate dimensions */ \ - int ipix_out; /* Index into output array */ \ - int nin; /* Number of Mapping input coordinates */ \ - int nout; /* Number of Mapping output coordinates */ \ - int npix; /* Number of pixels in input region */ \ - int npix_out; /* Number of pixels in output array */ \ - int64_t mpix; /* Number of pixels for testing */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Get a pointer to a structure holding thread-specific global data values */ \ - astGET_GLOBALS(this); \ -\ -/* Loop to determine how many pixels the output array contains. */ \ - npix_out = 1; \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - npix_out *= ubnd_out[ idim ] - lbnd_out[ idim ] + 1; \ - } \ -\ -/* Obtain values for the Nin and Nout attributes of the Mapping. */ \ - nin = astGetNin( this ); \ - nout = astGetNout( this ); \ -\ -/* If OK, also check that the number of output grid dimensions matches \ - the number required by the Mapping and is at least 1. Report an \ - error if necessary. */ \ - if ( astOK && ( ( ndim_out != nout ) || ( ndim_out < 1 ) ) ) { \ - astError( AST__NGDIN, "astRebinSeq"#X"(%s): Bad number of output grid " \ - "dimensions (%d).", status, astGetClass( this ), ndim_out ); \ - if ( ndim_out != nout ) { \ - astError( AST__NGDIN, "The %s given generates %s%d coordinate " \ - "value%s for each output position.", status, astGetClass( this ), \ - ( nout < ndim_out ) ? "only " : "", nout, \ - ( nout == 1 ) ? "" : "s" ); \ - } \ - } \ -\ -/* If no input data was supplied, jump to the normalisation section. */ \ - simple = NULL; \ - if( in ) { \ -\ -/* If OK, check that the number of input grid dimensions matches the \ - number required by the Mapping and is at least 1. Report an error \ - if necessary. */ \ - if ( astOK && ( ( ndim_in != nin ) || ( ndim_in < 1 ) ) ) { \ - astError( AST__NGDIN, "astRebinSeq"#X"(%s): Bad number of input grid " \ - "dimensions (%d).", status, astGetClass( this ), ndim_in ); \ - if ( ndim_in != nin ) { \ - astError( AST__NGDIN, "The %s given requires %d coordinate value%s " \ - "to specify an input position.", status, \ - astGetClass( this ), nin, ( nin == 1 ) ? "" : "s" ); \ - } \ - } \ -\ -/* Check that the lower and upper bounds of the input grid are \ - consistent. Report an error if any pair is not. */ \ - mpix = 1; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - if ( lbnd_in[ idim ] > ubnd_in[ idim ] ) { \ - astError( AST__GBDIN, "astRebinSeq"#X"(%s): Lower bound of " \ - "input grid (%d) exceeds corresponding upper bound " \ - "(%d).", status, astGetClass( this ), \ - lbnd_in[ idim ], ubnd_in[ idim ] ); \ - astError( AST__GBDIN, "Error in input dimension %d.", status, \ - idim + 1 ); \ - break; \ - } else { \ - mpix *= ubnd_in[ idim ] - lbnd_in[ idim ] + 1; \ - } \ - } \ - } \ -\ -/* Report an error if there are too many pixels in the input. */ \ - if ( astOK && (int) mpix != mpix ) { \ - astError( AST__EXSPIX, "astRebinSeq"#X"(%s): Supplied input array " \ - "contains too many pixels (%g): must be fewer than %d.", \ - status, astGetClass( this ), (double) mpix, INT_MAX ); \ - } \ -\ -/* Ensure any supplied "in_var" pointer is ignored if no input variances are \ - needed. */ \ - if( !( flags & AST__USEVAR ) && !( flags & AST__VARWGT ) ) { \ - in_var = NULL; \ - } \ -\ -/* Ensure any supplied "out_var" pointer is ignored if no output variances \ - being created. */ \ - if( !( flags & AST__USEVAR ) && !( flags & AST__GENVAR ) ) { \ - out_var = NULL; \ - } \ -\ -/* Check that the positional accuracy tolerance supplied is valid and \ - report an error if necessary. */ \ - if ( astOK && ( tol < 0.0 ) ) { \ - astError( AST__PATIN, "astRebinSeq"#X"(%s): Invalid positional " \ - "accuracy tolerance (%.*g pixel).", status, \ - astGetClass( this ), AST__DBL_DIG, tol ); \ - astError( AST__PATIN, "This value should not be less than zero." , status); \ - } \ -\ -/* Check that the initial scale size in pixels supplied is valid and \ - report an error if necessary. */ \ - if ( astOK && ( maxpix < 0 ) ) { \ - astError( AST__SSPIN, "astRebinSeq"#X"(%s): Invalid initial scale " \ - "size in pixels (%d).", status, astGetClass( this ), maxpix ); \ - astError( AST__SSPIN, "This value should not be less than zero." , status); \ - } \ -\ -/* Check that the lower and upper bounds of the output grid are \ - consistent. Report an error if any pair is not. */ \ - mpix = 1; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - if ( lbnd_out[ idim ] > ubnd_out[ idim ] ) { \ - astError( AST__GBDIN, "astRebinSeq"#X"(%s): Lower bound of " \ - "output grid (%d) exceeds corresponding upper bound " \ - "(%d).", status, astGetClass( this ), \ - lbnd_out[ idim ], ubnd_out[ idim ] ); \ - astError( AST__GBDIN, "Error in output dimension %d.", status, \ - idim + 1 ); \ - break; \ - } else { \ - mpix *= ubnd_out[ idim ] - lbnd_out[ idim ] + 1; \ - } \ - } \ - } \ -\ -/* Report an error if there are too many pixels in the output. */ \ - if ( astOK && (int) mpix != mpix ) { \ - astError( AST__EXSPIX, "astRebinSeq"#X"(%s): Supplied output array " \ - "contains too many pixels (%g): must be fewer than %d.", \ - status, astGetClass( this ), (double) mpix, INT_MAX ); \ - } \ -\ -/* Similarly check the bounds of the input region. */ \ - mpix = 1; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - if ( lbnd[ idim ] > ubnd[ idim ] ) { \ - astError( AST__GBDIN, "astRebinSeq"#X"(%s): Lower bound of " \ - "input region (%d) exceeds corresponding upper " \ - "bound (%d).", status, astGetClass( this ), \ - lbnd[ idim ], ubnd[ idim ] ); \ -\ -/* Also check that the input region lies wholly within the input \ - grid. */ \ - } else if ( lbnd[ idim ] < lbnd_in[ idim ] ) { \ - astError( AST__GBDIN, "astRebinSeq"#X"(%s): Lower bound of " \ - "input region (%d) is less than corresponding " \ - "bound of input grid (%d).", status, astGetClass( this ), \ - lbnd[ idim ], lbnd_in[ idim ] ); \ - } else if ( ubnd[ idim ] > ubnd_in[ idim ] ) { \ - astError( AST__GBDIN, "astRebinSeq"#X"(%s): Upper bound of " \ - "input region (%d) exceeds corresponding " \ - "bound of input grid (%d).", status, astGetClass( this ), \ - ubnd[ idim ], ubnd_in[ idim ] ); \ - } else { \ - mpix *= ubnd[ idim ] - lbnd[ idim ] + 1; \ - } \ -\ -/* Say which dimension produced the error. */ \ - if ( !astOK ) { \ - astError( AST__GBDIN, "Error in output dimension %d.", status, \ - idim + 1 ); \ - break; \ - } \ - } \ - } \ -\ -/* Report an error if there are too many pixels in the input region. */ \ - if ( astOK && (int) mpix != mpix ) { \ - astError( AST__EXSPIX, "astRebinSeq"#X"(%s): Supplied input region " \ - "contains too many pixels (%g): must be fewer than %d.", \ - status, astGetClass( this ), (double) mpix, INT_MAX ); \ - } \ -\ -/* Check that only one of AST__USEVAR and ASR__GENVAR has been supplied. */ \ - if( ( flags & AST__USEVAR ) && ( flags & AST__GENVAR ) ) { \ - if( astOK ) { \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): Incompatible flags " \ - "AST__GENVAR and AST__USEVAR have been specified " \ - "together (programming error).", status, astGetClass( this ) ); \ - } \ - } \ -\ -/* If AST__USEVAR or AST_VARWGT has been specified, check we have an \ - input variance array. */ \ - if( !in_var && astOK ) { \ - if( ( flags & AST__USEVAR ) ) { \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): The AST__USEVAR flag " \ - "was specified but no input variance array was supplied " \ - "(programming error).", status, astGetClass( this ) ); \ - } else if( ( flags & AST__VARWGT ) ) { \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): The AST__VARWGT flag " \ - "was specified but no input variance array was supplied " \ - "(programming error).", status, astGetClass( this ) ); \ - } \ - } \ -\ -/* If AST__USEVAR or AST_GENVAR has been specified, check we have an \ - output variance array. */ \ - if( !out_var && astOK ) { \ - if( ( flags & AST__USEVAR ) ) { \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): The AST__USEVAR flag " \ - "was specified but no output variance array was supplied " \ - "(programming error).", status, astGetClass( this ) ); \ - } else if( ( flags & AST__GENVAR ) ) { \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): The AST__GENVAR flag " \ - "was specified but no output variance array was supplied " \ - "(programming error).", status, astGetClass( this ) ); \ - } \ - } \ -\ -/* If the AST__NONORM flag has been supplied, check no incompatible flags have \ - been specified. */ \ - if( flags & AST__NONORM ) { \ - if( ( flags & AST__GENVAR ) && astOK ) { \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): Incompatible flags " \ - "AST__GENVAR and AST__NONORM have been specified " \ - "together (programming error).", status, astGetClass( this ) ); \ - } else if( ( flags & AST__VARWGT ) && astOK ) { \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): Incompatible flags " \ - "AST__VARWGT and AST__NONORM have been specified " \ - "together (programming error).", status, astGetClass( this ) ); \ - } else if( ( flags & AST__CONSERVEFLUX ) && astOK ) { \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): Incompatible flags " \ - "AST__CONSERVEFLUX and AST__NONORM have been specified " \ - "together (programming error).", status, astGetClass( this ) ); \ - } \ -\ -/* If the AST__NONORM flag has not been supplied, check that a weights array \ - and nused pointer have been supplied. */ \ - } else if( !weights ){ \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): No weights array " \ - "supplied (programming error).", status, \ - astGetClass( this ) ); \ - } else if( !nused ){ \ - astError( AST__BDPAR, "astRebinSeq"#X"(%s): No 'nused' pointer " \ - "supplied (programming error).", status, \ - astGetClass( this ) ); \ - } \ -\ -/* If OK, loop to determine how many input pixels are to be binned. */ \ - npix = 1; \ - unsimplified_mapping = this; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - npix *= ubnd[ idim ] - lbnd[ idim ] + 1; \ - } \ -\ -/* If there are sufficient pixels to make it worthwhile, simplify the \ - Mapping supplied to improve performance. Otherwise, just clone the \ - Mapping pointer. Note we have already saved a pointer to the original \ - Mapping so that lower-level functions can use it if they need to report \ - an error. */ \ - if ( npix > 1024 ) { \ - simple = astSimplify( this ); \ - } else { \ - simple = astClone( this ); \ - } \ - } \ -\ -/* Report an error if the forward transformation of this simplified \ - Mapping is not defined. */ \ - if ( !astGetTranForward( simple ) && astOK ) { \ - astError( AST__TRNND, "astRebinSeq"#X"(%s): An forward coordinate " \ - "transformation is not defined by the %s supplied.", status, \ - astGetClass( unsimplified_mapping ), \ - astGetClass( unsimplified_mapping ) ); \ - } \ -\ -/* If required, initialise the output arrays to hold zeros. */ \ - if( flags & AST__REBININIT ) { \ - d = out; \ - if( out_var ) { \ - v = out_var; \ - for( ipix_out = 0; ipix_out < npix_out; ipix_out++, d++, v++ ) { \ - *d = 0; \ - *v = 0; \ - } \ - } else { \ - for( ipix_out = 0; ipix_out < npix_out; ipix_out++, d++ ) { \ - *d = 0; \ - } \ - } \ - if( weights ) { \ - w = weights; \ - for( ipix_out = 0; ipix_out < npix_out; ipix_out++, w++ ) { \ - *w = 0; \ - } \ - if( flags & AST__GENVAR ) { \ - for( ipix_out = 0; ipix_out < npix_out; ipix_out++, w++ ) *w = 0; \ - } \ - } \ - if( nused ) *nused = 0; \ - } \ -\ -/* Paste the input values into the supplied output arrays. */ \ - if( RebinAdaptively( simple, ndim_in, lbnd_in, ubnd_in, \ - (const void *) in, (const void *) in_var, \ - TYPE_##X, spread, params, flags, \ - tol, maxpix, (const void *) &badval, \ - ndim_out, lbnd_out, ubnd_out, lbnd, \ - ubnd, npix_out, (void *) out, \ - (void *) out_var, weights, nused, status ) ) { \ - astError( AST__CNFLX, "astRebinSeq"#X"(%s): Flux conservation was " \ - "requested but could not be performed because the " \ - "forward transformation of the supplied Mapping " \ - "is too non-linear.", status, astGetClass( this ) ); \ - } \ -\ -/* Annul the pointer to the simplified/cloned Mapping. */ \ - simple = astAnnul( simple ); \ -\ - } \ -\ -/* If required, finalise the sequence. */ \ - if( ( flags & AST__REBINEND ) && !( flags & AST__NONORM ) && \ - weights && nused ) { \ -\ -/* Ensure "wlim" is not zero. */ \ - if( wlim < 1.0E-10 ) wlim = 1.0E-10; \ -\ -/* If it will be needed, find the average weight per input pixel. */ \ - if( !( flags & AST__GENVAR ) && *nused > 0 ) { \ - sw = 0.0; \ - for( i = 0; i < npix_out; i++ ) { \ - sw += weights[ i ]; \ - } \ - mwpip = sw/( *nused ); \ - } else { \ - mwpip = AST__BAD; \ - } \ -\ -/* Normalise each output pixel. */ \ - for( i = 0; i < npix_out; i++ ) { \ -\ -/* Find the effective number of input samples that contribute to the \ - output sample. To do this properly requires the sum of the squared \ - weights in each output pixel, but this is only available if AST__GENVAR \ - flag is in use. In order to avoid changing the API for astRebinSeq, we \ - honour this long-standing restriction, and use an approximation if \ - AST__GENVAR is not in use. */ \ - wgt = weights[ i ]; \ - if( flags & AST__GENVAR ) { \ - if( wgt > 0.0 && weights[ i + npix_out ] > 0 ) { \ - neff = (wgt*wgt)/weights[ i + npix_out ]; \ - } else { \ - neff = 0.0; \ - } \ -\ -/* If the sum of the squared weights is not available, compare the weight \ - for this output pixel with the mean weight per input pixel. */ \ - } else if( mwpip != AST__BAD ){ \ - neff = wgt/mwpip; \ -\ - } else if( astOK ) { \ - astError( AST__BADIN, "astRebinSeq"#X"(%s): The overlap " \ - "between the %d-d input array and the %d-d output " \ - "array contains no pixels with good data %svalues.", \ - status, astGetClass( this ), nin, nout, \ - in_var ? "and variance " : "" ); \ - } \ -\ -/* Assign bad values to unused output pixels. */ \ - if( neff < wlim || neff == 0.0 ) { \ - out[ i ] = badval; \ - if( out_var ) out_var[ i ] = badval; \ -\ -/* Otherwise, normalise the returned data value. No need to check "wgt" \ - since it must be larger than zero since neff is larger than wlim. */ \ - } else { \ - out[ i ] /= wgt; \ -\ -/* Normalise the returned variance: propagated from input variances... */ \ - if( out_var ) { \ - if( flags & AST__USEVAR ) { \ - out_var[ i ] /= wgt*wgt; \ -\ -/* Normalise the returned variance: from spread of input values... */ \ - } else if( flags & AST__GENVAR && neff > 1.0 ) { \ - out_var[ i ] /= wgt; \ - out_var[ i ] -= out[ i ]*out[ i ]; \ - if( out_var[ i ] < 0.0 ) out_var[ i ] = 0.0; \ -\ -/* If output variances are estimates of the variance of the distribution \ - from which the input values were sampled... */ \ - if( flags & AST__DISVAR ) { \ - out_var[ i ] *= neff/( neff - 1.0 ); \ -\ -/* If output variances are estimates of the error on the mean data value... */ \ - } else { \ - out_var[ i ] *= 1.0/( neff - 1.0 ); \ - } \ -\ - } else { \ - out_var[ i ] = badval; \ - } \ - } \ - } \ - } \ - } \ -\ -} - -/* Expand the above macro to generate a function for each required - data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_REBINSEQ(LD,long double,0) -#endif -MAKE_REBINSEQ(D,double,0) -MAKE_REBINSEQ(F,float,0) -MAKE_REBINSEQ(I,int,1) -MAKE_REBINSEQ(B,signed char,1) -MAKE_REBINSEQ(UB,unsigned char,1) - -/* Undefine the macro. */ -#undef MAKE_REBINSEQ - -static int RebinWithBlocking( AstMapping *this, const double *linear_fit, - int ndim_in, const int *lbnd_in, - const int *ubnd_in, const void *in, - const void *in_var, DataType type, - int spread, const double *params, int flags, - const void *badval_ptr, int ndim_out, - const int *lbnd_out, const int *ubnd_out, - const int *lbnd, const int *ubnd, int npix_out, - void *out, void *out_var, double *work, - int64_t *nused, int *status ) { -/* -* Name: -* RebinWithBlocking - -* Purpose: -* Rebin a section of a data grid in a memory-efficient way. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int RebinWithBlocking( AstMapping *this, const double *linear_fit, -* int ndim_in, const int *lbnd_in, -* const int *ubnd_in, const void *in, -* const void *in_var, DataType type, -* int spread, const double *params, int flags, -* const void *badval_ptr, int ndim_out, -* const int *lbnd_out, const int *ubnd_out, -* const int *lbnd, const int *ubnd, int npix_out, -* void *out, void *out_var, double *work, -* int64_t *nused, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function rebins a specified section of a rectangular grid of -* data (with any number of dimensions) into another rectangular grid -* (with a possibly different number of dimensions). The coordinate -* transformation used to convert input pixel coordinates into positions -* in the output grid is given by the forward transformation of the -* Mapping which is supplied. Any pixel spreading scheme may be specified -* for distributing the flux of an input pixel amongst the output -* pixels. -* -* This function is very similar to RebinSection, except that in -* order to limit memory usage and to ensure locality of reference, -* it divides the input grid up into "blocks" which have a limited -* extent along each input dimension. Each block, which will not -* contain more than a pre-determined maximum number of pixels, is -* then passed to RebinSection for resampling. - -* Parameters: -* this -* Pointer to a Mapping, whose forward transformation may be -* used to transform the coordinates of pixels in the input -* grid into associated positions in the output grid. -* -* The number of input coordintes for the Mapping (Nin -* attribute) should match the value of "ndim_in" (below), and -* the number of output coordinates (Nout attribute) should -* match the value of "ndim_out". -* linear_fit -* Pointer to an optional array of double which contains the -* coefficients of a linear fit which approximates the above -* Mapping's forward coordinate transformation. If this is -* supplied, it will be used in preference to the above Mapping -* when transforming coordinates. This may be used to enhance -* performance in cases where evaluation of the Mapping's -* forward transformation is expensive. If no linear fit is -* available, a NULL pointer should be supplied. -* -* The way in which the fit coefficients are stored in this -* array and the number of array elements are as defined by the -* astLinearApprox function. -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input data grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input data grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input data grid, its extent along a -* particular (i'th) dimension being (ubnd_in[i] - lbnd_in[i] + -* 1). They also define the input grid's coordinate system, with -* each pixel being of unit extent along each dimension with -* integral coordinate values at its centre. -* in -* Pointer to the input array of data to be rebinned (with one -* element for each pixel in the input grid). The numerical type -* of these data should match the "type" value (below). The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and data type as the "in" array), -* which represent estimates of the statistical variance -* associated with each element of the "in" array. If this -* second array is given (along with the corresponding "out_var" -* array), then estimates of the variance of the rebinned data -* will also be returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* type -* A value taken from the "DataType" enum, which specifies the -* data type of the input and output arrays containing the -* gridded data (and variance) values. -* spread -* A value selected from a set of pre-defined macros to identify -* which pixel spread function should be used. -* params -* Pointer to an optional array of parameters that may be passed -* to the pixel spread algorithm, if required. If no parameters -* are required, a NULL pointer should be supplied. -* flags -* The bitwise OR of a set of flag values which provide additional -* control over the resampling operation. -* badval_ptr -* If the AST__USEBAD flag is set (above), this parameter is a -* pointer to a value which is used to identify bad data and/or -* variance values in the input array(s). The referenced value's -* data type must match that of the "in" (and "in_var") -* arrays. The same value will also be used to flag any output -* array elements for which rebinned values could not be -* obtained. The output arrays(s) may be flagged with this -* value whether or not the AST__USEBAD flag is set (the -* function return value indicates whether any such values have -* been produced). -* ndim_out -* The number of dimensions in the output grid. This should be -* at least one. -* lbnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the first -* pixel in the output data grid along each dimension. -* ubnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the last -* pixel in the output data grid along each dimension. -* -* Note that "lbnd_out" and "ubnd_out" together define the shape -* and size of the output data grid in the same way as "lbnd_in" -* and "ubnd_in" define the shape and size of the input grid -* (see above). -* lbnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the first pixel in the -* section of the input data grid which is to be rebinned. -* ubnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the last pixel in the -* section of the input data grid which is to be rebinned. -* -* Note that "lbnd" and "ubnd" define the shape and position of -* the section of the input grid which is to be rebinned. This section -* should lie wholly within the extent of the input grid (as defined -* by the "lbnd_out" and "ubnd_out" arrays). Regions of the input -* grid lying outside this section will be ignored. -* npix_out -* The number of pixels in the output array. -* out -* Pointer to an array with the same data type as the "in" -* array, into which the rebinned data will be returned. The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the rebinned values may be returned. This array will only be -* used if the "in_var" array has been given. -* -* If no output variance estimates are required, a NULL pointer -* should be given. -* work -* An optional pointer to a double array with the same size as -* the "out" array. The contents of this array (if supplied) are -* incremented by the accumulated weights assigned to each output pixel. -* If no accumulated weights are required, a NULL pointer should be -* given. -* nused -* An optional pointer to a int64_t which will be incremented by the -* number of input values pasted into the output array. Ignored if NULL. - -* Returned Value: -* A non-zero value is returned if "flags" included AST__CONSERVEFLUX (i.e. -* flux conservation was requested), but the supplied linear fit to the -* forward transformation of the Mapping had zero determinant (no error -* is reported if this happens). Zero is returned otherwise. - -*/ - -/* Local Constants: */ - const int mxpix = 2 * 1024; /* Maximum number of pixels in a block (this - relatively small number seems to give best - performance) */ - -/* Local Variables: */ - double factor; /* Flux conservation factor */ - int *dim_block; /* Pointer to array of block dimensions */ - int *lbnd_block; /* Pointer to block lower bound array */ - int *ubnd_block; /* Pointer to block upper bound array */ - int dim; /* Dimension size */ - int done; /* All blocks rebinned? */ - int hilim; /* Upper limit on maximum block dimension */ - int idim; /* Loop counter for dimensions */ - int lolim; /* Lower limit on maximum block dimension */ - int mxdim_block; /* Maximum block dimension */ - int npix; /* Number of pixels in block */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Allocate workspace. */ - lbnd_block = astMalloc( sizeof( int ) * (size_t) ndim_in ); - ubnd_block = astMalloc( sizeof( int ) * (size_t) ndim_in ); - dim_block = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - -/* Find the optimum block size. */ -/* ---------------------------- */ -/* We first need to find the maximum extent which a block of input - pixels may have in each dimension. We determine this by taking the - input grid extent in each dimension and then limiting the maximum - dimension size until the resulting number of pixels is sufficiently - small. This approach allows the block shape to approximate (or - match) the input grid shape when appropriate. */ - -/* First loop to calculate the total number of input pixels and the - maximum input dimension size. */ - npix = 1; - mxdim_block = 0; - for ( idim = 0; idim < ndim_in; idim++ ) { - dim = ubnd[ idim ] - lbnd[ idim ] + 1; - npix *= dim; - if ( mxdim_block < dim ) mxdim_block = dim; - } - -/* If the number of input pixels is too large for a single block, we - perform iterations to determine the optimum upper limit on a - block's dimension size. Initialise the limits on this result. */ - if ( npix > mxpix ) { - lolim = 1; - hilim = mxdim_block; - -/* Loop to perform a binary chop, searching for the best result until - the lower and upper limits on the result converge to adjacent - values. */ - while ( ( hilim - lolim ) > 1 ) { - -/* Form a new estimate from the mid-point of the previous limits. */ - mxdim_block = ( hilim + lolim ) / 2; - -/* See how many pixels a block contains if its maximum dimension is - limited to this new value. */ - for ( npix = 1, idim = 0; idim < ndim_in; idim++ ) { - dim = ubnd[ idim ] - lbnd[ idim ] + 1; - npix *= ( dim < mxdim_block ) ? dim : mxdim_block; - } - -/* Update the appropriate limit, according to whether the number of - pixels is too large or too small. */ - *( ( npix <= mxpix ) ? &lolim : &hilim ) = mxdim_block; - } - -/* When iterations have converged, obtain the maximum limit on the - dimension size of a block which results in no more than the maximum - allowed number of pixels per block. However, ensure that all block - dimensions are at least 2. */ - mxdim_block = lolim; - } - if ( mxdim_block < 2 ) mxdim_block = 2; - -/* Calculate the block dimensions by applying this limit to the output - grid dimensions. */ - for ( idim = 0; idim < ndim_in; idim++ ) { - dim = ubnd[ idim ] - lbnd[ idim ] + 1; - dim_block[ idim ] = ( dim < mxdim_block ) ? dim : mxdim_block; - -/* Also initialise the lower and upper bounds of the first block of - output grid pixels to be rebinned, ensuring that this does not - extend outside the grid itself. */ - lbnd_block[ idim ] = lbnd[ idim ]; - ubnd_block[ idim ] = MinI( lbnd[ idim ] + dim_block[ idim ] - 1, - ubnd[ idim ], status ); - } - -/* Determine the flux conservation constant if needed. */ -/* --------------------------------------------------- */ - factor = 1.0; - if( flags & AST__CONSERVEFLUX ) { - if( linear_fit ) { - factor = MatrixDet( ndim_out, ndim_in, linear_fit + ndim_out, - status ); - if( factor != 0.0 ) { - factor = 1.0/factor; - } else { - result = 1; - } - } else { - result = 1; - } - } - -/* Rebin each block of input pixels. */ -/* --------------------------------- */ -/* Loop to generate the extent of each block of input pixels and to - rebin them. */ - done = result; - while ( !done && astOK ) { - -/* Rebin the current block, accumulating the sum of bad pixels produced. */ - RebinSection( this, linear_fit, ndim_in, lbnd_in, ubnd_in, in, - in_var, factor, type, spread, params, flags, badval_ptr, - ndim_out, lbnd_out, ubnd_out, lbnd_block, ubnd_block, - npix_out, out, out_var, work, nused, status ); - -/* Update the block extent to identify the next block of input pixels. */ - idim = 0; - do { - -/* We find the least significant dimension where the upper bound of - the block has not yet reached the upper bound of the region of the - input grid which we are rebinning. The block's position is then - incremented by one block extent along this dimension, checking that - the resulting extent does not go outside the region being rebinned. */ - if ( ubnd_block[ idim ] < ubnd[ idim ] ) { - lbnd_block[ idim ] = MinI( lbnd_block[ idim ] + - dim_block[ idim ], ubnd[ idim ], status ); - ubnd_block[ idim ] = MinI( lbnd_block[ idim ] + - dim_block[ idim ] - 1, - ubnd[ idim ], status ); - break; - -/* If any less significant dimensions are found where the upper bound - of the block has reached its maximum value, we reset the block to - its lowest position. */ - } else { - lbnd_block[ idim ] = lbnd[ idim ]; - ubnd_block[ idim ] = MinI( lbnd[ idim ] + dim_block[ idim ] - 1, - ubnd[ idim ], status ); - -/* All the blocks have been processed once the position along the most - significant dimension has been reset. */ - done = ( ++idim == ndim_in ); - } - } while ( !done ); - } - } - -/* Free the workspace. */ - lbnd_block = astFree( lbnd_block ); - ubnd_block = astFree( ubnd_block ); - dim_block = astFree( dim_block ); - -/* Return a flag indicating if there was an error conserving flux. */ - return result; -} - -static AstMapping *RemoveRegions( AstMapping *this, int *status ) { -/* -*++ -* Name: -c astRemoveRegions -f AST_REMOVEREGIONS - -* Purpose: -* Remove any Regions from a Mapping. - -* Type: -* Public function. - -* Synopsis: -c #include "mapping.h" -c AstMapping *astRemoveRegions( AstMapping *this ) -f RESULT = AST_REMOVEREGIONS( THIS, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -* This function searches the suppliedMapping (which may be a -* compound Mapping such as a CmpMap) for any component Mappings -* that are instances of the AST Region class. It then creates a new -* Mapping from which all Regions have been removed. If a Region -* cannot simply be removed (for instance, if it is a component of a -* parallel CmpMap), then it is replaced with an equivalent UnitMap -* in the returned Mapping. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the original Mapping. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astRemoveRegions() -f AST_REMOVEREGIONS = INTEGER -* A new pointer to the (possibly modified) Mapping. - -* Applicability: -* CmpFrame -* If the supplied Mapping is a CmpFrame, any component Frames that -* are instances of the Region class are replaced by the equivalent -* Frame. -* FrameSet -* If the supplied Mapping is a FrameSet, the returned Mapping -* will be a copy of the supplied FrameSet in which Regions have -* been removed from all the inter-Frame Mappings, and any Frames -* which are instances of the Region class are repalced by the -* equivalent Frame. -* Mapping -* This function applies to all Mappings. -* Region -* If the supplied Mapping is a Region, the returned Mapping will -* be the equivalent Frame. - -* Notes: -* - This function can safely be applied even to Mappings which -* contain no Regions. If no Regions are found, it -c behaves exactly like astClone and returns a pointer to the -f behaves exactly like AST_CLONE and returns a pointer to the -* original Mapping. -* - The Mapping returned by this function may not be independent -* of the original (even if some Regions were removed), and -* modifying it may therefore result in indirect modification of -* the original. If a completely independent result is required, a -c copy should be made using astCopy. -f copy should be made using AST_COPY. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* This base iplementation just returns a clone of the supplied Mapping - pointer. Sub-classes should override it as necessary. */ - return astClone( this ); -} - -static void ReportPoints( AstMapping *this, int forward, - AstPointSet *in_points, AstPointSet *out_points, int *status ) { -/* -*+ -* Name: -* astReportPoints - -* Purpose: -* Report the effect of transforming a set of points using a Mapping. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* void astReportPoints( AstMapping *this, int forward, -* AstPointSet *in_points, AstPointSet *out_points ) - -* Class Membership: -* Mapping method. - -* Description: -* This function reports the coordinates of a set of points before -* and after being transformed by a Mapping, by writing them to -* standard output. - -* Parameters: -* this -* Pointer to the Mapping. -* forward -* A non-zero value indicates that the Mapping's forward -* coordinate transformation has been applied, while a zero -* value indicates the inverse transformation. -* in_points -* Pointer to a PointSet which is associated with the -* coordinates of a set of points before the Mapping was -* applied. -* out_points -* Pointer to a PointSet which is associated with the -* coordinates of the same set of points after the Mapping has -* been applied. - -* Notes: -* - This method is provided as a development and debugging aid to -* be invoked when coordinates are transformed by public Mapping -* methods and under control of the "Report" Mapping attribute. -* - Derived clases may over-ride this method in order to change -* the way in which coordinates are formatted, etc. -*- -*/ - -/* Local Variables: */ - double **ptr_in; /* Pointer to array of input data pointers */ - double **ptr_out; /* Pointer to array of output data pointers */ - int coord; /* Loop counter for coordinates */ - int ncoord_in; /* Number of input coordinates per point */ - int ncoord_out; /* Number of output coordinates per point */ - int npoint; /* Number of points to report */ - int npoint_in; /* Number of input points */ - int npoint_out; /* Number of output points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the numbers of points and coordinates associated with each - PointSet. */ - npoint_in = astGetNpoint( in_points ); - npoint_out = astGetNpoint( out_points ); - ncoord_in = astGetNcoord( in_points ); - ncoord_out = astGetNcoord( out_points ); - -/* Obtain the pointers that give access to the coordinate data - associated with each PointSet. */ - ptr_in = astGetPoints( in_points ); - ptr_out = astGetPoints( out_points ); - -/* In the event that both PointSets don't contain equal numbers of - points (this shouldn't actually happen), simply use the minimum - number. */ - npoint = ( npoint_in < npoint_out ) ? npoint_in : npoint_out; - -/* Loop to report the effect of the Mapping on each point in turn. */ - for ( point = 0; point < npoint; point++ ) { - -/* Report the input coordinates (in parentheses and separated by - commas). Replace coordinate values of AST__BAD with the string - "" to indicate missing values. */ - printf( "(" ); - for ( coord = 0; coord < ncoord_in; coord++ ) { - if ( ptr_in[ coord ][ point ] == AST__BAD ) { - printf( "%s", coord ? ", " : "" ); - } else { - printf( "%s%.*g", coord ? ", " : "", - AST__DBL_DIG, ptr_in[ coord ][ point ] ); - } - } - -/* Similarly report the output coordinates. */ - printf( ") --> (" ); - for ( coord = 0; coord < ncoord_out; coord++ ) { - if ( ptr_out[ coord ][ point ] == AST__BAD ) { - printf( "%s", coord ? ", " : "" ); - } else { - printf( "%s%.*g", coord ? ", " : "", - AST__DBL_DIG, ptr_out[ coord ][ point ] ); - } - } - printf( ")\n" ); - } -} - -/* -*++ -* Name: -c astResample -f AST_RESAMPLE - -* Purpose: -* Resample a region of a data grid. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c int astResample( AstMapping *this, int ndim_in, -c const int lbnd_in[], const int ubnd_in[], -c const in[], const in_var[], -c int interp, void (* finterp)( void ), -c const double params[], int flags, -c double tol, int maxpix, -c badval, int ndim_out, -c const int lbnd_out[], const int ubnd_out[], -c const int lbnd[], const int ubnd[], -c out[], out_var[] ); -f RESULT = AST_RESAMPLE( THIS, NDIM_IN, LBND_IN, UBND_IN, IN, IN_VAR, -f INTERP, FINTERP, PARAMS, FLAGS, -f TOL, MAXPIX, BADVAL, -f NDIM_OUT, LBND_OUT, UBND_OUT, -f LBND, UBND, OUT, OUT_VAR, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -* This is a set of functions for resampling gridded data (e.g. an -* image) under the control of a geometrical transformation, which -* is specified by a Mapping. The functions operate on a pair of -* data grids (input and output), each of which may have any number -* of dimensions. Resampling may be restricted to a specified -* region of the output grid. An associated grid of error estimates -* associated with the input data may also be supplied (in the form -* of variance values), so as to produce error estimates for the -* resampled output data. Propagation of missing data (bad pixels) -* is supported. -* -* You should use a resampling function which matches the numerical -* type of the data you are processing by replacing in -c the generic function name astResample by an appropriate 1- or -f the generic function name AST_RESAMPLE by an appropriate 1- or -* 2-character type code. For example, if you are resampling data -c with type "float", you should use the function astResampleF (see -f with type REAL, you should use the function AST_RESAMPLER (see -* the "Data Type Codes" section below for the codes appropriate to -* other numerical types). -* -* Resampling of the grid of input data is performed by -* transforming the coordinates of the centre of each output grid -* element (or pixel) into the coordinate system of the input grid. -* Since the resulting coordinates will not, in general, coincide -* with the centre of an input pixel, sub-pixel interpolation is -* performed between the neighbouring input pixels. This produces a -* resampled value which is then assigned to the output pixel. A -* choice of sub-pixel interpolation schemes is provided, but you -* may also implement your own. -* -* This algorithm samples the input data value, it does not integrate -* it. Thus total data value in the input image will not, in general, -* be conserved. However, an option is provided (see the "Control Flags" -* section below) which can produce approximate flux conservation by -* scaling the output values using the ratio of the output pixel size -* to the input pixel size. However, if accurate flux conservation is -* important to you, consder using the -c astRebin or astRebinSeq family of functions -f AST_REBIN or AST_REBINSEQ family of routines -* instead. -* -* Output pixel coordinates are transformed into the coordinate -* system of the input grid using the inverse transformation of the -* Mapping which is supplied. This means that geometrical features -* in the input data are subjected to the Mapping's forward -* transformation as they are transferred from the input to the -* output grid (although the Mapping's forward transformation is -* not explicitly used). -* -* In practice, transforming the coordinates of every pixel of a -* large data grid can be time-consuming, especially if the Mapping -* involves complicated functions, such as sky projections. To -* improve performance, it is therefore possible to approximate -* non-linear Mappings by a set of linear transformations which are -* applied piece-wise to separate sub-regions of the data. This -* approximation process is applied automatically by an adaptive -* algorithm, under control of an accuracy criterion which -* expresses the maximum tolerable geometrical distortion which may -* be introduced, as a fraction of a pixel. -* -* This algorithm first attempts to approximate the Mapping with a -* linear transformation applied over the whole region of the -* output grid which is being used. If this proves to be -* insufficiently accurate, the output region is sub-divided into -* two along its largest dimension and the process is repeated -* within each of the resulting sub-regions. This process of -* sub-division continues until a sufficiently good linear -* approximation is found, or the region to which it is being -* applied becomes too small (in which case the original Mapping is -* used directly). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to a Mapping, whose inverse transformation will be -* used to transform the coordinates of pixels in the output -* grid into the coordinate system of the input grid. This -* yields the positions which are used to obtain resampled -* values by sub-pixel interpolation within the input grid. -* -* The number of input coordinates used by this Mapping (as -* given by its Nin attribute) should match the number of input -c grid dimensions given by the value of "ndim_in" -f grid dimensions given by the value of NDIM_IN -* below. Similarly, the number of output coordinates (Nout -* attribute) should match the number of output grid dimensions -c given by "ndim_out". -f given by NDIM_OUT. -c ndim_in -f NDIM_IN = INTEGER (Given) -* The number of dimensions in the input grid. This should be at -* least one. -c lbnd_in -f LBND_IN( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the centre of the first pixel -* in the input grid along each dimension. -c ubnd_in -f UBND_IN( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the centre of the last pixel in -* the input grid along each dimension. -* -c Note that "lbnd_in" and "ubnd_in" together define the shape -f Note that LBND_IN and UBND_IN together define the shape -* and size of the input grid, its extent along a particular -c (j'th) dimension being ubnd_in[j]-lbnd_in[j]+1 (assuming the -c index "j" to be zero-based). They also define -f (J'th) dimension being UBND_IN(J)-LBND_IN(J)+1. They also define -* the input grid's coordinate system, each pixel having unit -* extent along each dimension with integral coordinate values -* at its centre. -c in -f IN( * ) = (Given) -c Pointer to an array, with one element for each pixel in the -f An array, with one element for each pixel in the -* input grid, containing the input data to be resampled. The -* numerical type of this array should match the 1- or -* 2-character type code appended to the function name (e.g. if -c you are using astResampleF, the type of each array element -c should be "float"). -f you are using AST_RESAMPLER, the type of each array element -f should be REAL). -* -* The storage order of data within this array should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -c in_var -f IN_VAR( * ) = (Given) -c An optional pointer to a second array with the same size and -c type as the "in" array. If given, this should contain a set -c of non-negative values which represent estimates of the -c statistical variance associated with each element of the "in" -c array. If this array is supplied (together with the -c corresponding "out_var" array), then estimates of the -c variance of the resampled output data will be calculated. -c -c If no input variance estimates are being provided, a NULL -c pointer should be given. -f An optional second array with the same size and type as the -f IN array. If the AST__USEVAR flag is set via the FLAGS -f argument (below), this array should contain a set of -f non-negative values which represent estimates of the -f statistical variance associated with each element of the IN -f array. Estimates of the variance of the resampled output data -f will then be calculated. -f -f If the AST__USEVAR flag is not set, no input variance -f estimates are required and this array will not be used. A -f dummy (e.g. one-element) array may then be supplied. -c interp -f INTERP = INTEGER (Given) -c This parameter specifies the scheme to be used for sub-pixel -f This argument specifies the scheme to be used for sub-pixel -* interpolation within the input grid. It may be used to select -* from a set of pre-defined schemes by supplying one of the -* values described in the "Sub-Pixel Interpolation Schemes" -* section below. If a value of zero is supplied, then the -* default linear interpolation scheme is used (equivalent to -* supplying the value AST__LINEAR). -* -* Alternatively, you may supply a value which indicates that -c you will provide your own function to perform sub-pixel -c interpolation by means of the "finterp " parameter. Again, see -f you will provide your own routine to perform sub-pixel -f interpolation by means of the FINTERP argument. Again, see -* the "Sub-Pixel Interpolation Schemes" section below for -* details. -c finterp -f FINTERP = SUBROUTINE (Given) -c If the value given for the "interp" parameter indicates that -c you will provide your own function for sub-pixel -c interpolation, then a pointer to that function should be -c given here. For details of the interface which the function -c should have (several are possible, depending on the value of -c "interp"), see the "Sub-Pixel Interpolation Schemes" section -c below. -f If the value given for the INTERP argument indicates that you -f will provide your own routine for sub-pixel interpolation, -f then the name of that routine should be given here (the name -f should also appear in a Fortran EXTERNAL statement in the -f routine which invokes AST_RESAMPLE). For details of the -f interface which the routine should have (several are -f possible, depending on the value of INTERP), see the -f "Sub-Pixel Interpolation Schemes" section below. -* -c If the "interp" parameter has any other value, corresponding -c to one of the pre-defined interpolation schemes, then this -c function will not be used and you may supply a NULL pointer. -f If the INTERP argument has any other value, corresponding to -f one of the pre-defined interpolation schemes, then this -f routine will not be used and you may supply the null routine -f AST_NULL here (note only one underscore). No EXTERNAL -f statement is required for this routine, so long as the AST_PAR -f include file has been used. -c params -f PARAMS( * ) = DOUBLE PRECISION (Given) -c An optional pointer to an array of double which should contain -f An optional array which should contain -* any additional parameter values required by the sub-pixel -* interpolation scheme. If such parameters are required, this -* will be noted in the "Sub-Pixel Interpolation Schemes" -c section below (you may also use this array to pass values -c to your own interpolation function). -f section below (you may also use this array to pass values -f to your own interpolation routine). -* -c If no additional parameters are required, this array is not -c used and a NULL pointer may be given. -f If no additional parameters are required, this array is not -f used. A dummy (e.g. one-element) array may then be supplied. -c flags -f FLAGS = INTEGER (Given) -c The bitwise OR of a set of flag values which may be used to -f The sum of a set of flag values which may be used to -* provide additional control over the resampling operation. See -* the "Control Flags" section below for a description of the -* options available. If no flag values are to be set, a value -* of zero should be given. -c tol -f TOL = DOUBLE PRECISION (Given) -* The maximum tolerable geometrical distortion which may be -* introduced as a result of approximating non-linear Mappings -* by a set of piece-wise linear transformations. This should be -* expressed as a displacement in pixels in the input grid's -* coordinate system. -* -* If piece-wise linear approximation is not required, a value -* of zero may be given. This will ensure that the Mapping is -* used without any approximation, but may increase execution -* time. -c maxpix -f MAXPIX = INTEGER (Given) -* A value which specifies an initial scale size (in pixels) for -* the adaptive algorithm which approximates non-linear Mappings -* with piece-wise linear transformations. Normally, this should -* be a large value (larger than any dimension of the region of -* the output grid being used). In this case, a first attempt to -* approximate the Mapping by a linear transformation will be -* made over the entire output region. -* -* If a smaller value is used, the output region will first be -c divided into sub-regions whose size does not exceed "maxpix" -f divided into sub-regions whose size does not exceed MAXPIX -* pixels in any dimension. Only at this point will attempts at -* approximation commence. -* -* This value may occasionally be useful in preventing false -* convergence of the adaptive algorithm in cases where the -* Mapping appears approximately linear on large scales, but has -* irregularities (e.g. holes) on smaller scales. A value of, -* say, 50 to 100 pixels can also be employed as a safeguard in -* general-purpose software, since the effect on performance is -* minimal. -* -* If too small a value is given, it will have the effect of -* inhibiting linear approximation altogether (equivalent to -c setting "tol" to zero). Although this may degrade -f setting TOL to zero). Although this may degrade -* performance, accurate results will still be obtained. -c badval -f BADVAL = (Given) -* This argument should have the same type as the elements of -c the "in" array. It specifies the value used to flag missing -f the IN array. It specifies the value used to flag missing -* data (bad pixels) in the input and output arrays. -* -c If the AST__USEBAD flag is set via the "flags" parameter, -f If the AST__USEBAD flag is set via the FLAGS argument, -c then this value is used to test for bad pixels in the "in" -c (and "in_var") array(s). -f then this value is used to test for bad pixels in the IN -f (and IN_VAR) array(s). -* -c Unless the AST__NOBAD flag is set via the "flags" parameter, -f Unless the AST__NOBAD flag is set via the FLAGS argument, -* this value is also used to flag any output -c elements in the "out" (and "out_var") array(s) for which -f elements in the OUT (and OUT_VAR) array(s) for which -* resampled values could not be obtained (see the "Propagation -* of Missing Data" section below for details of the -c circumstances under which this may occur). The astResample -f circumstances under which this may occur). The AST_RESAMPLE -* function return value indicates whether any such values have -* been produced. If the AST__NOBAD flag is set. then output array -* elements for which no resampled value could be obtained are -* left set to the value they had on entry to this function. -c ndim_out -f NDIM_OUT = INTEGER (Given) -* The number of dimensions in the output grid. This should be -* at least one. It need not necessarily be equal to the number -* of dimensions in the input grid. -c lbnd_out -f LBND_OUT( NDIM_OUT ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_out" elements, -f An array -* containing the coordinates of the centre of the first pixel -* in the output grid along each dimension. -c ubnd_out -f UBND_OUT( NDIM_OUT ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_out" elements, -f An array -* containing the coordinates of the centre of the last pixel in -* the output grid along each dimension. -* -c Note that "lbnd_out" and "ubnd_out" together define the -f Note that LBND_OUT and UBND_OUT together define the -* shape, size and coordinate system of the output grid in the -c same way as "lbnd_in" and "ubnd_in" define the shape, size -f same way as LBND_IN and UBND_IN define the shape, size -* and coordinate system of the input grid. -c lbnd -f LBND( NDIM_OUT ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_out" elements, -f An array -* containing the coordinates of the first pixel in the region -* of the output grid for which a resampled value is to be -* calculated. -c ubnd -f UBND( NDIM_OUT ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_out" elements, -f An array -* containing the coordinates of the last pixel in the region of -* the output grid for which a resampled value is to be -* calculated. -* -c Note that "lbnd" and "ubnd" together define the shape and -f Note that LBND and UBND together define the shape and -* position of a (hyper-)rectangular region of the output grid -* for which resampled values should be produced. This region -* should lie wholly within the extent of the output grid (as -c defined by the "lbnd_out" and "ubnd_out" arrays). Regions of -f defined by the LBND_OUT and UBND_OUT arrays). Regions of -* the output grid lying outside this region will not be -* modified. -c out -f OUT( * ) = (Returned) -c Pointer to an array, with one element for each pixel in the -f An array, with one element for each pixel in the -* output grid, into which the resampled data values will be -* returned. The numerical type of this array should match that -c of the "in" array, and the data storage order should be such -f of the IN array, and the data storage order should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -c out_var -f OUT_VAR( * ) = (Returned) -c An optional pointer to an array with the same type and size -c as the "out" array. If given, this array will be used to -c return variance estimates for the resampled data values. This -c array will only be used if the "in_var" array has also been -c supplied. -f An optional array with the same type and size as the OUT -f array. If the AST__USEVAR flag is set via the FLAGS argument, -f this array will be used to return variance estimates for the -f resampled data values. -* -* The output variance values will be calculated on the -* assumption that errors on the input data values are -* statistically independent and that their variance estimates -* may simply be summed (with appropriate weighting factors) -* when several input pixels contribute to an output data -* value. If this assumption is not valid, then the output error -* estimates may be biased. In addition, note that the -* statistical errors on neighbouring output data values (as -* well as the estimates of those errors) may often be -* correlated, even if the above assumption about the input data -* is correct, because of the sub-pixel interpolation schemes -* employed. -* -c If no output variance estimates are required, a NULL pointer -c should be given. -f If the AST__USEVAR flag is not set, no output variance -f estimates will be calculated and this array will not be -f used. A dummy (e.g. one-element) array may then be supplied. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astResample() -f AST_RESAMPLE = INTEGER -* The number of output pixels for which no valid resampled value -* could be obtained. Thus, in the absence of any error, a returned -* value of zero indicates that all the required output pixels -* received valid resampled data values (and variances). See the -c "badval" and "flags" parameters. -f BADVAL and FLAGS arguments. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. - -* Data Type Codes: -* To select the appropriate resampling function, you should -c replace in the generic function name astResample with a -f replace in the generic function name AST_RESAMPLE with a -* 1- or 2-character data type code, so as to match the numerical -* type of the data you are processing, as follows: -c - D: double -c - F: float -c - L: long int (may be 32 or 64 bit) -c - K: 64 bit int -c - UL: unsigned long int (may be 32 or 64 bit) -c - UK: unsigned 64 bit int -c - I: int -c - UI: unsigned int -c - S: short int -c - US: unsigned short int -c - B: byte (signed char) -c - UB: unsigned byte (unsigned char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - UI: INTEGER (treated as unsigned) -f - S: INTEGER*2 (short integer) -f - US: INTEGER*2 (short integer, treated as unsigned) -f - B: BYTE (treated as signed) -f - UB: BYTE (treated as unsigned) -* -c For example, astResampleD would be used to process "double" -c data, while astResampleS would be used to process "short int" -c data, etc. -f For example, AST_RESAMPLED would be used to process DOUBLE -f PRECISION data, while AST_RESAMPLES would be used to process -f short integer data (stored in an INTEGER*2 array), etc. -f -f For compatibility with other Starlink facilities, the codes W -f and UW are provided as synonyms for S and US respectively (but -f only in the Fortran interface to AST). - -* Sub-Pixel Interpolation Schemes: -* There is no such thing as a perfect sub-pixel interpolation -* scheme and, in practice, all resampling will result in some -* degradation of gridded data. A range of schemes is therefore -* provided, from which you can choose the one which best suits -* your needs. -* -* In general, a balance must be struck between schemes which tend -* to degrade sharp features in the data by smoothing them, and -* those which attempt to preserve sharp features. The latter will -* often tend to introduce unwanted oscillations, typically visible -* as "ringing" around sharp features and edges, especially if the -* data are under-sampled (i.e. if the sharpest features are less -* than about two pixels across). In practice, a good interpolation -* scheme is likely to be a compromise and may exhibit some aspects -* of both these features. -* -* For under-sampled data, some interpolation schemes may appear to -* preserve data resolution because they transform single input -* pixels into single output pixels, rather than spreading their -* data between several output pixels. While this may look -* better cosmetically, it can result in a geometrical shift of -* sharp features in the data. You should beware of this if you -* plan to use such features (e.g.) for image alignment. -* -* The following are two easy-to-use sub-pixel interpolation -* schemes which are generally applicable. They are selected by -c supplying the appropriate value (defined in the "ast.h" header -c file) via the "interp" parameter. In these cases, the "finterp" -c and "params" parameters are not used: -f supplying the appropriate value (defined in the AST_PAR include -f file) via the INTERP argument. In these cases, the FINTERP -f and PARAMS arguments are not used: -* -* - AST__NEAREST: This is the simplest possible scheme, in which -* the value of the input pixel with the nearest centre to the -* interpolation point is used. This is very quick to execute and -* will preserve single-pixel features in the data, but may -* displace them by up to half their width along each dimension. It -* often gives a good cosmetic result, so is useful for quick-look -* processing, but is unsuitable if accurate geometrical -* transformation is required. -* - AST__LINEAR: This is the default scheme, which uses linear -* interpolation between the nearest neighbouring pixels in the -* input grid (there are two neighbours in one dimension, four -* neighbours in two dimensions, eight in three dimensions, -* etc.). It is superior to the nearest-pixel scheme (above) in not -* displacing features in the data, yet it still executes fairly -* rapidly. It is generally a safe choice if you do not have any -* particular reason to favour another scheme, since it cannot -* introduce oscillations. However, it does introduce some spatial -* smoothing which varies according to the distance of the -* interpolation point from the neighbouring pixels. This can -* degrade the shape of sharp features in the data in a -* position-dependent way. It may also show in the output variance -* grid (if used) as a pattern of stripes or fringes. -* -* An alternative set of interpolation schemes is based on forming -* the interpolated value from the weighted sum of a set of -* surrounding pixel values (not necessarily just the nearest -* neighbours). This approach has its origins in the theory of -* digital filtering, in which interpolated values are obtained by -* conceptually passing the sampled data (represented by a grid of -* delta functions) through a linear filter which implements a -* convolution. Because the convolution kernel is continuous, the -* convolution yields a continuous function which may then be -* evaluated at fractional pixel positions. The (possibly -* multi-dimensional) kernel is usually regarded as "separable" and -* formed from the product of a set of identical 1-dimensional -* kernel functions, evaluated along each dimension. Different -* interpolation schemes are then distinguished by the choice of -* this 1-dimensional interpolation kernel. The number of -* surrounding pixels which contribute to the result may also be -* varied. -* -* From a practical standpoint, it is useful to divide the weighted -* sum of pixel values by the sum of the weights when determining -* the interpolated value. Strictly, this means that a true -* convolution is no longer being performed. However, the -* distinction is rarely important in practice because (for -* slightly subtle reasons) the sum of weights is always -* approximately constant for good interpolation kernels. The -* advantage of this technique, which is used here, is that it can -* easily accommodate missing data and tends to minimise unwanted -* oscillations at the edges of the data grid. -* -* In the following schemes, which are based on a 1-dimensional -c interpolation kernel, the first element of the "params" array -f interpolation kernel, the first element of the PARAMS array -* should be used to specify how many pixels are to contribute to the -* interpolated result on either side of the interpolation point in -* each dimension (the nearest integer value is used). Execution time -* increases rapidly with this number. Typically, a value of 2 is -* appropriate and the minimum value used will be 1 (i.e. two pixels -* altogether, one on either side of the interpolation point). -c A value of zero or less may be given for "params[0]" -f A value of zero or less may be given for PARAMS(1) -* to indicate that a suitable number of pixels should be calculated -* automatically. -* -c In each of these cases, the "finterp" parameter is not used: -f In each of these cases, the FINTERP argument is not used: -* -* - AST__GAUSS: This scheme uses a kernel of the form exp(-k*x*x), with -* k a positive constant. The full-width at half-maximum (FWHM) is -* given by -c "params[1]" -f PARAMS(2) -f value, which should be at least 0.1 (in addition, setting PARAMS(1) -* to zero will select the number of contributing pixels so as to utilise -* the width of the kernel out to where the envelope declines to 1% of its -* maximum value). This kernel suppresses noise at the expense of -* smoothing the output array. -* - AST__SINC: This scheme uses a sinc(pi*x) kernel, where x is the -* pixel offset from the interpolation point and sinc(z)=sin(z)/z. This -* sometimes features as an "optimal" interpolation kernel in books on -* image processing. Its supposed optimality depends on the assumption -* that the data are band-limited (i.e. have no spatial frequencies above -* a certain value) and are adequately sampled. In practice, astronomical -* data rarely meet these requirements. In addition, high spatial -* frequencies are often present due (e.g.) to image defects and cosmic -* ray events. Consequently, substantial ringing can be experienced with -* this kernel. The kernel also decays slowly with distance, so that -* many surrounding pixels are required, leading to poor performance. -* Abruptly truncating it, by using only a few neighbouring pixels, -c improves performance and may reduce ringing (if "params[0]" is set to -f improves performance and may reduce ringing (if PARAMS(1) is set to -* zero, then only two pixels will be used on either side). However, a -* more gradual truncation, as implemented by other kernels, is generally -* to be preferred. This kernel is provided mainly so that you can -* convince yourself not to use it! -* - AST__SINCSINC: This scheme uses an improved kernel, of the form -* sinc(pi*x).sinc(k*pi*x), with k a constant, out to the point where -* sinc(k*pi*x) goes to zero, and zero beyond. The second sinc() factor -* provides an "envelope" which gradually rolls off the normal sinc(pi*x) -* kernel at large offsets. The width of this envelope is specified by -* giving the number of pixels offset at which it goes to zero by means -c of the "params[1]" value, which should be at least 1.0 (in addition, -c setting "params[0]" to zero will select the number of contributing -f of the PARAMS(2) value, which should be at least 1.0 (in addition, -f setting PARAMS(1) to zero will select the number of contributing -* pixels so as to utilise the full width of the kernel, out to where it -c reaches zero). The case given by "params[0]=2, params[1]=2" is typically -f reaches zero). The case given by PARAMS(1)=2, PARAMS(2)=2 is typically -* a good choice and is sometimes known as the Lanczos kernel. This is a -* valuable general-purpose interpolation scheme, intermediate in its -* visual effect on images between the AST__NEAREST and AST__LINEAR -* schemes. Although the kernel is slightly oscillatory, ringing is -* adequately suppressed if the data are well sampled. -* - AST__SINCCOS: This scheme uses a kernel of the form -* sinc(pi*x).cos(k*pi*x), with k a constant, out to the point where -* cos(k*pi*x) goes to zero, and zero beyond. As above, the cos() factor -* provides an envelope which gradually rolls off the sinc() kernel -* at large offsets. The width of this envelope is specified by giving -* the number of pixels offset at which it goes to zero by means -c of the "params[1]" value, which should be at least 1.0 (in addition, -c setting "params[0]" to zero will select the number of contributing -f of the PARAMS(2) value, which should be at least 1.0 (in addition, -f setting PARAMS(1) to zero will select the number of contributing -* pixels so as to utilise the full width of the kernel, out to where it -* reaches zero). This scheme gives similar results to the -* AST__SINCSINC scheme, which it resembles. -* - AST__SINCGAUSS: This scheme uses a kernel of the form -* sinc(pi*x).exp(-k*x*x), with k a positive constant. Here, the sinc() -* kernel is rolled off using a Gaussian envelope which is specified by -c giving its full-width at half-maximum (FWHM) by means of the "params[1]" -c value, which should be at least 0.1 (in addition, setting "params[0]" -f giving its full-width at half-maximum (FWHM) by means of the PARAMS(2) -f value, which should be at least 0.1 (in addition, setting PARAMS(1) -* to zero will select the number of contributing pixels so as to utilise -* the width of the kernel out to where the envelope declines to 1% of its -* maximum value). On astronomical images and spectra, good results are -* often obtained by approximately matching the FWHM of the -c envelope function, given by "params[1]", to the point spread function -f envelope function, given by PARAMS(2), to the point spread function -* of the input data. However, there does not seem to be any theoretical -* reason for this. -* - AST__SOMB: This scheme uses a somb(pi*x) kernel (a "sombrero" -* function), where x is the pixel offset from the interpolation point -* and somb(z)=2*J1(z)/z (J1 is a Bessel function of the first kind of -* order 1). It is similar to the AST__SINC kernel, and has the same -* parameter usage. -* - AST__SOMBCOS: This scheme uses a kernel of the form -* somb(pi*x).cos(k*pi*x), with k a constant, out to the point where -* cos(k*pi*x) goes to zero, and zero beyond. It is similar to the -* AST__SINCCOS kernel, and has the same parameter usage. -* -* In addition, the following schemes are provided which are not based -* on a 1-dimensional kernel: -* -* - AST__BLOCKAVE: This scheme simply takes an average of all the -* pixels on the input grid in a cube centred on the interpolation -* point. The number of pixels in the cube is determined by the -c value of the first element of the "params" array, which gives -f value of the first element of the PARAMS array, which gives -* the number of pixels in each dimension on either side of the -c central point. Hence a block of (2 * params[0])^ndim_in -f central point. Hence a block of (2 * PARAMS(1))**NDIM_IN -* pixels in the input grid will be examined to determine the -* value of the output pixel. If the variance is not being used -c (var_in or var_out = NULL) then all valid pixels in this cube -f (USEVAR = .FALSE.) then all valid pixels in this cube -* will be averaged in to the result with equal weight. -* If variances are being used, then each input pixel will be -* weighted proportionally to the reciprocal of its variance; any -* pixel without a valid variance will be discarded. This scheme -* is suitable where the output grid is much coarser than the -* input grid; if the ratio of pixel sizes is R then a suitable -c value of params[0] may be R/2. -f value of PARAMS(1) may be R/2. -* -c Finally, supplying the following values for "interp" allows you -c to implement your own sub-pixel interpolation scheme by means of -c your own function. You should supply a pointer to this function -c via the "finterp" parameter: -f Finally, supplying the following values for INTERP allows you to -f implement your own sub-pixel interpolation scheme by means of -f your own routine. You should supply the name of this routine via -f the FINTERP argument: -* -c - AST__UKERN1: In this scheme, you supply a function to evaluate -c your own 1-dimensional interpolation kernel, which is then used -c to perform sub-pixel interpolation (as described above). The -c function you supply should have the same interface as the -c fictitious astUkern1 function (q.v.). In addition, a value -c should be given via "params[0]" to specify the number of -c neighbouring pixels which are to contribute to each interpolated -c value (in the same way as for the pre-defined interpolation -c schemes described above). Other elements of the "params" array -c are available to pass values to your interpolation function. -f - AST__UKERN1: In this scheme, you supply a routine to evaluate -f your own 1-dimensional interpolation kernel, which is then used -f to perform sub-pixel interpolation (as described above). The -f routine you supply should have the same interface as the -f fictitious AST_UKERN1 routine (q.v.). In addition, a value -f should be given via PARAMS(1) to specify the number of -f neighbouring pixels which are to contribute to each interpolated -f value (in the same way as for the pre-defined interpolation -f schemes described above). Other elements of the PARAMS array -f are available to pass values to your interpolation routine. -* -c - AST__UINTERP: This is a completely general scheme, in which -c your interpolation function has access to all of the input -c data. This allows you to implement any interpolation algorithm -c you choose, which could (for example) be non-linear, or -c adaptive. In this case, the astResample functions play no -c role in the sub-pixel interpolation process and simply handle -c the geometrical transformation of coordinates and other -c housekeeping. The function you supply should have the same -c interface as the fictitious astUinterp function (q.v.). In this -c case, the "params" parameter is not used by astResample, but -c is available to pass values to your interpolation function. -f - AST__UINTERP: This is a completely general scheme, in which -f your interpolation routine has access to all of the input -f data. This allows you to implement any interpolation algorithm -f you choose, which could (for example) be non-linear, or -f adaptive. In this case, the AST_RESAMPLE functions play no -f role in the sub-pixel interpolation process and simply handle -f the geometrical transformation of coordinates and other -f housekeeping. The routine you supply should have the same -f interface as the fictitious AST_UINTERP routine (q.v.). In this -f case, the PARAMS argument is not used by AST_RESAMPLE, but -f is available to pass values to your interpolation routine. - -* Control Flags: -c The following flags are defined in the "ast.h" header file and -f The following flags are defined in the AST_PAR include file and -* may be used to provide additional control over the resampling -* process. Having selected a set of flags, you should supply the -c bitwise OR of their values via the "flags" parameter: -f sum of their values via the FLAGS argument: -* -* - AST__NOBAD: Indicates that any output array elements for which no -* resampled value could be obtained should be left set to the value -* they had on entry to this function. If this flag is not supplied, -* such output array elements are set to the value supplied for -c parameter "badval". Note, this flag cannot be used in conjunction -f argument BADVAL. Note, this flag cannot be used in conjunction -* with the AST__CONSERVEFLUX flag (an error will be reported if both -* flags are specified). -* - AST__URESAMP1, 2, 3 & 4: A set of four flags which are -* reserved for your own use. They may be used to pass private -c information to any sub-pixel interpolation function which you -f information to any sub-pixel interpolation routine which you -* implement yourself. They are ignored by all the pre-defined -* interpolation schemes. -* - AST__USEBAD: Indicates that there may be bad pixels in the -* input array(s) which must be recognised by comparing with the -c value given for "badval" and propagated to the output array(s). -f value given for BADVAL and propagated to the output array(s). -* If this flag is not set, all input values are treated literally -c and the "badval" value is only used for flagging output array -f and the BADVAL value is only used for flagging output array -* values. -f - AST__USEVAR: Indicates that variance information should be -f processed in order to provide estimates of the statistical error -f associated with the resampled values. If this flag is not set, -f no variance processing will occur and the IN_VAR and OUT_VAR -f arrays will not be used. (Note that this flag is only available -f in the Fortran interface to AST.) -* - AST__CONSERVEFLUX: Indicates that the output pixel values should -* be scaled in such a way as to preserve (approximately) the total data -* value in a feature on the sky. Without this flag, each output pixel -* value represents an instantaneous sample of the input data values at -* the corresponding input position. This is appropriate if the input -* data represents the spatial density of some quantity (e.g. surface -* brightness in Janskys per square arc-second) because the output -* pixel values will have the same normalisation and units as the -* input pixel values. However, if the input data values represent -* flux (or some other physical quantity) per pixel, then the -* AST__CONSERVEFLUX flag could be used. This causes each output -* pixel value to be scaled by the ratio of the output pixel size to -* the input pixel size. -* -* This flag can only be used if the Mapping is successfully approximated -* by one or more linear transformations. Thus an error will be reported -* if it used when the -c "tol" parameter -f TOL argument -* is set to zero (which stops the use of linear approximations), or -* if the Mapping is too non-linear to be approximated by a piece-wise -* linear transformation. The ratio of output to input pixel size is -* evaluated once for each panel of the piece-wise linear approximation to -* the Mapping, and is assumed to be constant for all output pixels in the -* panel. The scaling factors for adjacent panels will in general -* differ slightly, and so the joints between panels may be visible when -* viewing the output image at high contrast. If this is a problem, -* reduce the value of the -c "tol" parameter -f TOL argument -* until the difference between adjacent panels is sufficiently small -* to be insignificant. -* -* Note, this flag cannot be used in conjunction with the AST__NOBAD -* flag (an error will be reported if both flags are specified). - -* Propagation of Missing Data: -* Unless the AST__NOBAD flag is specified, instances of missing data -* (bad pixels) in the output grid are -c identified by occurrences of the "badval" value in the "out" -f identified by occurrences of the BADVAL value in the OUT -* array. These may be produced if any of the following happen: -* -* - The input position (the transformed position of the output -* pixel's centre) lies outside the boundary of the grid of input -* pixels. -* - The input position lies inside the boundary of a bad input -* pixel. In this context, an input pixel is considered bad if its -c data value is equal to "badval" and the AST__USEBAD flag is -c set via the "flags" parameter. -f data value is equal to BADVAL and the AST__USEBAD flag is -f set via the FLAGS argument. -* (Positions which have half-integral coordinate values, and -* therefore lie on a pixel boundary, are regarded as lying within -* the pixel with the larger, i.e. more positive, index.) -* - The set of neighbouring input pixels (excluding those which -* are bad) is unsuitable for calculating an interpolated -* value. Whether this is true may depend on the sub-pixel -* interpolation scheme in use. -* - The interpolated value lies outside the range which can be -c represented using the data type of the "out" array. -f represented using the data type of the OUT array. -* -* In addition, associated output variance estimates (if -c calculated) may be declared bad and flagged with the "badval" -c value in the "out_var" array under any of the following -f calculated) may be declared bad and flagged with the BADVAL -f value in the OUT_VAR array under any of the following -* circumstances: -* -c - The associated resampled data value (in the "out" array) is bad. -f - The associated resampled data value (in the OUT array) is bad. -* - The set of neighbouring input pixels which contributed to the -* output data value do not all have valid variance estimates -* associated with them. In this context, an input variance -* estimate may be regarded as bad either because it has the value -c "badval" (and the AST__USEBAD flag is set), or because it is -f BADVAL (and the AST__USEBAD flag is set), or because it is -* negative. -* - The set of neighbouring input pixels for which valid variance -* values are available is unsuitable for calculating an overall -* variance value. Whether this is true may depend on the sub-pixel -* interpolation scheme in use. -* - The variance value lies outside the range which can be -c represented using the data type of the "out_var" array. -f represented using the data type of the OUT_VAR array. -* -* If the AST__NOBAD flag is specified via -c parameter "flags", -f argument FLAGS, -* then output array elements that would otherwise be set to -c "badval" -f BADVAL -* are instead left holding the value they had on entry to this -* function. The number of such array elements is returned as -* the function value. -*-- -*/ -/* Define a macro to implement the function for a specific data - type. */ -#define MAKE_RESAMPLE(X,Xtype) \ -static int Resample##X( AstMapping *this, int ndim_in, \ - const int lbnd_in[], const int ubnd_in[], \ - const Xtype in[], const Xtype in_var[], \ - int interp, void (* finterp)( void ), \ - const double params[], int flags, double tol, \ - int maxpix, Xtype badval, \ - int ndim_out, const int lbnd_out[], \ - const int ubnd_out[], const int lbnd[], \ - const int ubnd[], Xtype out[], Xtype out_var[], int *status ) { \ -\ -/* Local Variables: */ \ - astDECLARE_GLOBALS /* Thread-specific data */ \ - AstMapping *simple; /* Pointer to simplified Mapping */ \ - int idim; /* Loop counter for coordinate dimensions */ \ - int nin; /* Number of Mapping input coordinates */ \ - int nout; /* Number of Mapping output coordinates */ \ - int npix; /* Number of pixels in output region */ \ - int result; /* Result value to return */ \ - int64_t mpix; /* Number of pixels for testing */ \ -\ -/* Initialise. */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Get a pointer to a structure holding thread-specific global data values */ \ - astGET_GLOBALS(this); \ -\ -/* Obtain values for the Nin and Nout attributes of the Mapping. */ \ - nin = astGetNin( this ); \ - nout = astGetNout( this ); \ -\ -/* If OK, check that the number of input grid dimensions matches the \ - number required by the Mapping and is at least 1. Report an error \ - if necessary. */ \ - if ( astOK && ( ( ndim_in != nin ) || ( ndim_in < 1 ) ) ) { \ - astError( AST__NGDIN, "astResample"#X"(%s): Bad number of input grid " \ - "dimensions (%d).", status, astGetClass( this ), ndim_in ); \ - if ( ndim_in != nin ) { \ - astError( AST__NGDIN, "The %s given requires %d coordinate value%s " \ - "to specify an input position.", status, \ - astGetClass( this ), nin, ( nin == 1 ) ? "" : "s" ); \ - } \ - } \ -\ -/* If OK, also check that the number of output grid dimensions matches \ - the number required by the Mapping and is at least 1. Report an \ - error if necessary. */ \ - if ( astOK && ( ( ndim_out != nout ) || ( ndim_out < 1 ) ) ) { \ - astError( AST__NGDIN, "astResample"#X"(%s): Bad number of output grid " \ - "dimensions (%d).", status, astGetClass( this ), ndim_out ); \ - if ( ndim_out != nout ) { \ - astError( AST__NGDIN, "The %s given generates %s%d coordinate " \ - "value%s for each output position.", status, astGetClass( this ), \ - ( nout < ndim_out ) ? "only " : "", nout, \ - ( nout == 1 ) ? "" : "s" ); \ - } \ - } \ -\ -/* Check that the lower and upper bounds of the input grid are \ - consistent. Report an error if any pair is not. Also get the number \ - of pixels in the input grid. */ \ - mpix = 1; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_in; idim++ ) { \ - if ( lbnd_in[ idim ] > ubnd_in[ idim ] ) { \ - astError( AST__GBDIN, "astResample"#X"(%s): Lower bound of " \ - "input grid (%d) exceeds corresponding upper bound " \ - "(%d).", status, astGetClass( this ), \ - lbnd_in[ idim ], ubnd_in[ idim ] ); \ - astError( AST__GBDIN, "Error in input dimension %d.", status, \ - idim + 1 ); \ - break; \ - } else { \ - mpix *= ubnd_in[ idim ] - lbnd_in[ idim ] + 1; \ - } \ - } \ - } \ -\ -/* Report an error if there are too many pixels in the input. */ \ - if ( astOK && (int) mpix != mpix ) { \ - astError( AST__EXSPIX, "astResample"#X"(%s): Supplied input array " \ - "contains too many pixels (%g): must be fewer than %d.", \ - status, astGetClass( this ), (double) mpix, INT_MAX ); \ - } \ -\ -/* Check that the positional accuracy tolerance supplied is valid and \ - report an error if necessary. */ \ - if ( astOK && ( tol < 0.0 ) ) { \ - astError( AST__PATIN, "astResample"#X"(%s): Invalid positional " \ - "accuracy tolerance (%.*g pixel).", status, \ - astGetClass( this ), AST__DBL_DIG, tol ); \ - astError( AST__PATIN, "This value should not be less than zero." , status); \ - } \ -\ -/* Check that the initial scale size in pixels supplied is valid and \ - report an error if necessary. */ \ - if ( astOK && ( maxpix < 0 ) ) { \ - astError( AST__SSPIN, "astResample"#X"(%s): Invalid initial scale " \ - "size in pixels (%d).", status, astGetClass( this ), maxpix ); \ - astError( AST__SSPIN, "This value should not be less than zero." , status); \ - } \ -\ -/* Check that the lower and upper bounds of the output grid are \ - consistent. Report an error if any pair is not. Also get the \ - number of pixels in the output array. */ \ - mpix = 1; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - if ( lbnd_out[ idim ] > ubnd_out[ idim ] ) { \ - astError( AST__GBDIN, "astResample"#X"(%s): Lower bound of " \ - "output grid (%d) exceeds corresponding upper bound " \ - "(%d).", status, astGetClass( this ), \ - lbnd_out[ idim ], ubnd_out[ idim ] ); \ - astError( AST__GBDIN, "Error in output dimension %d.", status, \ - idim + 1 ); \ - break; \ - } else { \ - mpix *= ubnd_out[ idim ] - lbnd_out[ idim ] + 1; \ - } \ - } \ - } \ -\ -/* Report an error if there are too many pixels in the output. */ \ - if ( astOK && (int) mpix != mpix ) { \ - astError( AST__EXSPIX, "astResample"#X"(%s): Supplied output array " \ - "contains too many pixels (%g): must be fewer than %d.", \ - status, astGetClass( this ), (double) mpix, INT_MAX ); \ - } \ -\ -/* Similarly check the bounds of the output region. */ \ - mpix = 1; \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - if ( lbnd[ idim ] > ubnd[ idim ] ) { \ - astError( AST__GBDIN, "astResample"#X"(%s): Lower bound of " \ - "output region (%d) exceeds corresponding upper " \ - "bound (%d).", status, astGetClass( this ), \ - lbnd[ idim ], ubnd[ idim ] ); \ -\ -/* Also check that the output region lies wholly within the output \ - grid. */ \ - } else if ( lbnd[ idim ] < lbnd_out[ idim ] ) { \ - astError( AST__GBDIN, "astResample"#X"(%s): Lower bound of " \ - "output region (%d) is less than corresponding " \ - "bound of output grid (%d).", status, astGetClass( this ), \ - lbnd[ idim ], lbnd_out[ idim ] ); \ - } else if ( ubnd[ idim ] > ubnd_out[ idim ] ) { \ - astError( AST__GBDIN, "astResample"#X"(%s): Upper bound of " \ - "output region (%d) exceeds corresponding " \ - "bound of output grid (%d).", status, astGetClass( this ), \ - ubnd[ idim ], ubnd_out[ idim ] ); \ - } else { \ - mpix *= ubnd[ idim ] - lbnd[ idim ] + 1; \ - } \ -\ -/* Say which dimension produced the error. */ \ - if ( !astOK ) { \ - astError( AST__GBDIN, "Error in output dimension %d.", status, \ - idim + 1 ); \ - break; \ - } \ - } \ - } \ -\ -/* Report an error if there are too many pixels in the output region. */ \ - if ( astOK && (int) mpix != mpix ) { \ - astError( AST__EXSPIX, "astResample"#X"(%s): Supplied output region " \ - "contains too many pixels (%g): must be fewer than %d.", \ - status, astGetClass( this ), (double) mpix, INT_MAX ); \ - } \ -\ -/* If we are conserving flux, check "tol" is not zero. */ \ - if( ( flags & AST__CONSERVEFLUX ) && astOK ) { \ - if( tol == 0.0 ) { \ - astError( AST__CNFLX, "astResample"#X"(%s): Flux conservation was " \ - "requested but cannot be performed because zero tolerance " \ - "was also specified.", status, astGetClass( this ) ); \ -\ -/* Also check "nin" and "nout" are equal. */ \ - } else if( nin != nout ) { \ - astError( AST__CNFLX, "astResample"#X"(%s): Flux conservation was " \ - "requested but cannot be performed because the Mapping " \ - "has different numbers of inputs and outputs.", status, \ - astGetClass( this ) ); \ - } \ - } \ -\ -/* If OK, loop to determine how many pixels require resampled values. */ \ - simple = NULL; \ - if ( astOK ) { \ - npix = 1; \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - npix *= ubnd[ idim ] - lbnd[ idim ] + 1; \ - } \ -\ -/* If there are sufficient pixels to make it worthwhile, simplify the \ - Mapping supplied to improve performance. Otherwise, just clone the \ - Mapping pointer. Note we save a pointer to the original Mapping so \ - that lower-level functions can use it if they need to report an \ - error. */ \ - unsimplified_mapping = this; \ - if ( npix > 1024 ) { \ - simple = astSimplify( this ); \ - } else { \ - simple = astClone( this ); \ - } \ - } \ -\ -/* Report an error if the inverse transformation of this simplified \ - Mapping is not defined. */ \ - if ( !astGetTranInverse( simple ) && astOK ) { \ - astError( AST__TRNND, "astResample"#X"(%s): An inverse coordinate " \ - "transformation is not defined by the %s supplied.", status, \ - astGetClass( unsimplified_mapping ), \ - astGetClass( unsimplified_mapping ) ); \ - } \ -\ -/* Perform the resampling. Note that we pass all gridded data, the \ - interpolation function and the bad pixel value by means of pointer \ - types that obscure the underlying data type. This is to avoid \ - having to replicate functions unnecessarily for each data \ - type. However, we also pass an argument that identifies the data \ - type we have obscured. */ \ - result = ResampleAdaptively( simple, ndim_in, lbnd_in, ubnd_in, \ - (const void *) in, (const void *) in_var, \ - TYPE_##X, interp, finterp, \ - params, flags, tol, maxpix, \ - (const void *) &badval, \ - ndim_out, lbnd_out, ubnd_out, \ - lbnd, ubnd, \ - (void *) out, (void *) out_var, status ); \ -\ -/* Annul the pointer to the simplified/cloned Mapping. */ \ - simple = astAnnul( simple ); \ -\ -/* If an error occurred, clear the returned result. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_RESAMPLE(LD,long double) -#endif -MAKE_RESAMPLE(D,double) -MAKE_RESAMPLE(F,float) -MAKE_RESAMPLE(L,long int) -MAKE_RESAMPLE(UL,unsigned long int) -MAKE_RESAMPLE(K,INT_BIG) -MAKE_RESAMPLE(UK,UINT_BIG) -MAKE_RESAMPLE(I,int) -MAKE_RESAMPLE(UI,unsigned int) -MAKE_RESAMPLE(S,short int) -MAKE_RESAMPLE(US,unsigned short int) -MAKE_RESAMPLE(B,signed char) -MAKE_RESAMPLE(UB,unsigned char) - -/* Undefine the macro. */ -#undef MAKE_RESAMPLE - -static int ResampleAdaptively( AstMapping *this, int ndim_in, - const int *lbnd_in, const int *ubnd_in, - const void *in, const void *in_var, - DataType type, int interp, void (* finterp)( void ), - const double *params, int flags, double tol, - int maxpix, const void *badval_ptr, - int ndim_out, const int *lbnd_out, - const int *ubnd_out, const int *lbnd, - const int *ubnd, void *out, void *out_var, int *status ) { -/* -* Name: -* ResampleAdaptively - -* Purpose: -* Resample a section of a data grid adaptively. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int ResampleAdaptively( AstMapping *this, int ndim_in, -* const int *lbnd_in, const int *ubnd_in, -* const void *in, const void *in_var, -* DataType type, int interp, void (* finterp)( void ), -* const double *params, int flags, double tol, -* int maxpix, const void *badval_ptr, -* int ndim_out, const int *lbnd_out, -* const int *ubnd_out, const int *lbnd, -* const int *ubnd, void *out, void *out_var ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function resamples a rectangular grid of data (with any -* number of dimensions) into a specified section of another -* rectangular grid (with a possibly different number of -* dimensions). The coordinate transformation used to convert -* output pixel coordinates into positions in the input grid is -* given by the inverse transformation of the Mapping which is -* supplied. Any pixel interpolation scheme may be specified for -* interpolating between the pixels of the input grid. -* -* This function is very similar to ResampleWithBlocking and -* ResampleSection which lie below it in the calling -* hierarchy. However, this function also attempts to adapt to the -* Mapping supplied and to sub-divide the section being resampled -* into smaller sections within which a linear approximation to the -* Mapping may be used. This reduces the number of Mapping -* evaluations, thereby improving efficiency particularly when -* complicated Mappings are involved. - -* Parameters: -* this -* Pointer to a Mapping, whose inverse transformation may be -* used to transform the coordinates of pixels in the output -* grid into associated positions in the input grid, from which -* the output pixel values should be derived (by interpolation -* if necessary). -* -* The number of input coordintes for the Mapping (Nin -* attribute) should match the value of "ndim_in" (below), and -* the number of output coordinates (Nout attribute) should -* match the value of "ndim_out". -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input data grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input data grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input data grid, its extent along a -* particular (i'th) dimension being (ubnd_in[i] - lbnd_in[i] + -* 1). They also define the input grid's coordinate system, with -* each pixel being of unit extent along each dimension with -* integral coordinate values at its centre. -* in -* Pointer to the input array of data to be resampled (with one -* element for each pixel in the input grid). The numerical type -* of these data should match the "type" value (below). The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and data type as the "in" array), -* which represent estimates of the statistical variance -* associated with each element of the "in" array. If this -* second array is given (along with the corresponding "out_var" -* array), then estimates of the variance of the resampled data -* will also be returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* type -* A value taken from the "DataType" enum, which specifies the -* data type of the input and output arrays containing the -* gridded data (and variance) values. -* interp -* A value selected from a set of pre-defined macros to identify -* which sub-pixel interpolation algorithm should be used. -* finterp -* If "interp" is set to a value which requires a user-supplied -* function, then a pointer to that function shoild be given -* here. Otherwise, this value is not used and may be a NULL -* pointer. -* params -* Pointer to an optional array of parameters that may be passed -* to the interpolation algorithm, if required. If no parameters -* are required, a NULL pointer should be supplied. -* flags -* The bitwise OR of a set of flag values which provide -* additional control over the resampling operation. -* tol -* The maximum permitted positional error in transforming output -* pixel positions into the input grid in order to resample -* it. This should be expressed as a displacement in pixels in -* the input grid's coordinate system. If the Mapping's inverse -* transformation can be approximated by piecewise linear -* functions to this accuracy, then such functions may be used -* instead of the Mapping in order to improve -* performance. Otherwise, every output pixel position will be -* transformed individually using the Mapping. -* -* If linear approximation is not required, a "tol" value of -* zero may be given. This will ensure that the Mapping is used -* without any approximation. -* maxpix -* A value which specifies the largest scale size on which to -* search for non-linearities in the Mapping supplied. This -* value should be expressed as a number of pixels in the output -* grid. The function will break the output section specified -* into smaller sub-sections (if necessary), each no larger than -* "maxpix" pixels in any dimension, before it attempts to -* approximate the Mapping by a linear function over each -* sub-section. -* -* If the value given is larger than the largest dimension of -* the output section (the normal recommendation), the function -* will initially search for non-linearity on a scale determined -* by the size of the output section. This is almost always -* satisfactory. Very occasionally, however, a Mapping may -* appear linear on this scale but nevertheless have smaller -* irregularities (e.g. "holes") in it. In such cases, "maxpix" -* may be set to a suitably smaller value so as to ensure this -* non-linearity is not overlooked. Typically, a value of 50 to -* 100 pixels might be suitable and should have little effect on -* performance. -* -* If too small a value is given, however, it will have the -* effect of preventing linear approximation occurring at all -* (equivalent to setting "tol" to zero). Although this may -* degrade performance, accurate results will still be obtained. -* badval_ptr -* If the AST__USEBAD flag is set (above), this parameter is a -* pointer to a value which is used to identify bad data and/or -* variance values in the input array(s). The referenced value's -* data type must match that of the "in" (and "in_var") -* arrays. Unless the AST__NOBAD flag is set, the same value will -* also be used to flag any output array elements for which -* resampled values could not be obtained. The output arrays(s) -* may be flagged with this value whether or not the AST__USEBAD -* flag is set (the function return value indicates whether any -* such values have been produced). -* ndim_out -* The number of dimensions in the output grid. This should be -* at least one. -* lbnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the first -* pixel in the output data grid along each dimension. -* ubnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the last -* pixel in the output data grid along each dimension. -* -* Note that "lbnd_out" and "ubnd_out" together define the shape -* and size of the output data grid in the same way as "lbnd_in" -* and "ubnd_in" define the shape and size of the input grid -* (see above). -* lbnd -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the first pixel in the -* section of the output data grid for which a value is -* required. -* ubnd -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the last pixel in the -* section of the output data grid for which a value is -* required. -* -* Note that "lbnd" and "ubnd" define the shape and position of -* the section of the output grid for which resampled values are -* required. This section should lie wholly within the extent of -* the output grid (as defined by the "lbnd_out" and "ubnd_out" -* arrays). Regions of the output grid lying outside this section -* will not be modified. -* out -* Pointer to an array with the same data type as the "in" -* array, into which the resampled data will be returned. The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the resampled values may be returned. This array will only be -* used if the "in_var" array has been given. -* -* If no output variance estimates are required, a NULL pointer -* should be given. - -* Returned Value: -* The number of output grid points for which no valid output value -* could be obtained. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - double *flbnd; /* Array holding floating point lower bounds */ - double *fubnd; /* Array holding floating point upper bounds */ - double *linear_fit; /* Pointer to array of fit coefficients */ - int *hi; /* Pointer to array of section upper bounds */ - int *lo; /* Pointer to array of section lower bounds */ - int coord_out; /* Loop counter for output coordinates */ - int dim; /* Output section dimension size */ - int dimx; /* Dimension with maximum section extent */ - int divide; /* Sub-divide the output section? */ - int i; /* Loop count */ - int isLinear; /* Is the transformation linear? */ - int mxdim; /* Largest output section dimension size */ - int npix; /* Number of pixels in output section */ - int npoint; /* Number of points for obtaining a fit */ - int nvertex; /* Number of vertices of output section */ - int result; /* Result value to return */ - int toobig; /* Section too big (must sub-divide)? */ - int toosmall; /* Section too small to sub-divide? */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialisation. */ - npix = 1; - mxdim = 0; - dimx = 1; - nvertex = 1; - -/* Loop through the output grid dimensions. */ - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - -/* Obtain the extent in each dimension of the output section which is - to receive resampled values, and calculate the total number of - pixels it contains. */ - dim = ubnd[ coord_out ] - lbnd[ coord_out ] + 1; - npix *= dim; - -/* Find the maximum dimension size of this output section and note - which dimension has this size. */ - if ( dim > mxdim ) { - mxdim = dim; - dimx = coord_out; - } - -/* Calculate how many vertices the output section has. */ - nvertex *= 2; - } - -/* Calculate how many sample points will be needed (by the - astLinearApprox function) to obtain a linear fit to the Mapping's - inverse transformation. */ - npoint = 1 + 4 * ndim_out + 2 * nvertex; - -/* If the number of pixels in the output section is not at least 4 - times this number, we will probably not save significant time by - attempting to obtain a linear fit, so note that the output section - is too small. */ - toosmall = ( npix < ( 4 * npoint ) ); - -/* Note if the maximum dimension of the output section exceeds the - user-supplied scale factor. */ - toobig = ( maxpix < mxdim ); - -/* Assume the Mapping is significantly non-linear before deciding - whether to sub-divide the output section. */ - linear_fit = NULL; - -/* If the output section is too small to be worth obtaining a linear - fit, or if the accuracy tolerance is zero, we will not - sub-divide. This means that the Mapping will be used to transform - each pixel's coordinates and no linear approximation will be - used. */ - if ( toosmall || ( tol == 0.0 ) ) { - divide = 0; - -/* Otherwise, if the largest output section dimension exceeds the - scale length given, we will sub-divide. This offers the possibility - of obtaining a linear approximation to the Mapping over a reduced - range of output coordinates (which will be handled by a recursive - invocation of this function). */ - } else if ( toobig ) { - divide = 1; - -/* If neither of the above apply, then attempt to fit a linear - approximation to the Mapping's inverse transformation over the - range of coordinates covered by the output section. We need to - temporarily copy the integer bounds into floating point arrays to - use astLinearApprox. */ - } else { - -/* Allocate memory for floating point bounds and for the coefficient array */ - flbnd = astMalloc( sizeof( double )*(size_t) ndim_out ); - fubnd = astMalloc( sizeof( double )*(size_t) ndim_out ); - linear_fit = astMalloc( sizeof( double )* - (size_t) ( ndim_in*( ndim_out + 1 ) ) ); - if( astOK ) { - -/* Copy the bounds into these arrays, and change them so that they refer - to the lower and upper edges of the cell rather than the centre. This - is essential if one of the axes is spanned by a single cell, since - otherwise the upper and lower bounds would be identical. */ - for( i = 0; i < ndim_out; i++ ) { - flbnd[ i ] = (double) lbnd[ i ] - 0.5; - fubnd[ i ] = (double) ubnd[ i ] + 0.5; - } - -/* Get the linear approximation to the inverse transformation. The - astLinearApprox function fits the forward transformation so temporarily - invert the Mapping in order to get a fit to the inverse transformation. */ - astInvert( this ); - isLinear = astLinearApprox( this, flbnd, fubnd, tol, linear_fit ); - astInvert( this ); - -/* Free the coeff array if the inverse transformation is not linear. */ - if( !isLinear ) linear_fit = astFree( linear_fit ); - - } else { - linear_fit = astFree( linear_fit ); - } - -/* Free resources */ - flbnd = astFree( flbnd ); - fubnd = astFree( fubnd ); - -/* If a linear fit was obtained, we will use it and therefore do not - wish to sub-divide further. Otherwise, we sub-divide in the hope - that this may result in a linear fit next time. */ - divide = !linear_fit; - } - -/* If no sub-division is required, perform resampling (in a - memory-efficient manner, since the section we are resampling might - still be very large). This will use the linear fit, if obtained - above. */ - if ( astOK ) { - if ( !divide ) { - result = ResampleWithBlocking( this, linear_fit, - ndim_in, lbnd_in, ubnd_in, - in, in_var, type, interp, finterp, - params, flags, badval_ptr, - ndim_out, lbnd_out, ubnd_out, - lbnd, ubnd, out, out_var, status ); - -/* Otherwise, allocate workspace to perform the sub-division. */ - } else { - lo = astMalloc( sizeof( int ) * (size_t) ndim_out ); - hi = astMalloc( sizeof( int ) * (size_t) ndim_out ); - if ( astOK ) { - -/* Initialise the bounds of a new output section to match the original - output section. */ - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - lo[ coord_out ] = lbnd[ coord_out ]; - hi[ coord_out ] = ubnd[ coord_out ]; - } - -/* Replace the upper bound of the section's largest dimension with the - mid-point of the section along this dimension, rounded - downwards. */ - hi[ dimx ] = - (int) floor( 0.5 * (double) ( lbnd[ dimx ] + ubnd[ dimx ] ) ); - -/* Resample the resulting smaller section using a recursive invocation - of this function. */ - result = ResampleAdaptively( this, ndim_in, lbnd_in, ubnd_in, - in, in_var, type, interp, finterp, - params, flags, tol, maxpix, - badval_ptr, ndim_out, - lbnd_out, ubnd_out, - lo, hi, out, out_var, status ); - -/* Now set up a second section which covers the remaining half of the - original output section. */ - lo[ dimx ] = hi[ dimx ] + 1; - hi[ dimx ] = ubnd[ dimx ]; - -/* If this section contains pixels, resample it in the same way, - summing the returned values. */ - if ( lo[ dimx ] <= hi[ dimx ] ) { - result += ResampleAdaptively( this, ndim_in, lbnd_in, ubnd_in, - in, in_var, type, interp, finterp, - params, flags, tol, maxpix, - badval_ptr, ndim_out, - lbnd_out, ubnd_out, - lo, hi, out, out_var, status ); - } - } - -/* Free the workspace. */ - lo = astFree( lo ); - hi = astFree( hi ); - } - } - -/* If coefficients for a linear fit were obtained, then free the space - they occupy. */ - if ( linear_fit ) linear_fit = astFree( linear_fit ); - -/* If an error occurred, clear the returned result. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int ResampleSection( AstMapping *this, const double *linear_fit, - int ndim_in, - const int *lbnd_in, const int *ubnd_in, - const void *in, const void *in_var, - DataType type, int interp, void (* finterp)( void ), - const double *params, double factor, int flags, - const void *badval_ptr, int ndim_out, - const int *lbnd_out, const int *ubnd_out, - const int *lbnd, const int *ubnd, - void *out, void *out_var, int *status ) { -/* -* Name: -* ResampleSection - -* Purpose: -* Resample a section of a data grid. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int ResampleSection( AstMapping *this, const double *linear_fit, -* int ndim_in, const int *lbnd_in, const int *ubnd_in, -* const void *in, const void *in_var, -* DataType type, int interp, void (* finterp)( void ), -* const double *params, double factor, int flags, -* const void *badval_ptr, int ndim_out, -* const int *lbnd_out, const int *ubnd_out, -* const int *lbnd, const int *ubnd, -* void *out, void *out_var ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function resamples a rectangular grid of data (with any -* number of dimensions) into a specified section of another -* rectangular grid (with a possibly different number of -* dimensions). The coordinate transformation used is given by the -* inverse transformation of the Mapping which is supplied or, -* alternatively, by a linear approximation fitted to a Mapping's -* inverse transformation. Any pixel interpolation scheme may be -* specified for interpolating between the pixels of the input -* grid. - -* Parameters: -* this -* Pointer to a Mapping, whose inverse transformation may be -* used to transform the coordinates of pixels in the output -* grid into associated positions in the input grid, from which -* the output pixel values should be derived (by interpolation -* if necessary). -* -* The number of input coordintes for the Mapping (Nin -* attribute) should match the value of "ndim_in" (below), and -* the number of output coordinates (Nout attribute) should -* match the value of "ndim_out". -* linear_fit -* Pointer to an optional array of double which contains the -* coefficients of a linear fit which approximates the above -* Mapping's inverse coordinate transformation. If this is -* supplied, it will be used in preference to the above Mapping -* when transforming coordinates. This may be used to enhance -* performance in cases where evaluation of the Mapping's -* inverse transformation is expensive. If no linear fit is -* available, a NULL pointer should be supplied. -* -* The way in which the fit coefficients are stored in this -* array and the number of array elements are as defined by the -* astLinearApprox function. -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input data grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input data grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input data grid, its extent along a -* particular (i'th) dimension being (ubnd_in[i] - lbnd_in[i] + -* 1). They also define the input grid's coordinate system, with -* each pixel being of unit extent along each dimension with -* integral coordinate values at its centre. -* in -* Pointer to the input array of data to be resampled (with one -* element for each pixel in the input grid). The numerical type -* of these data should match the "type" value (below). The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and data type as the "in" array), -* which represent estimates of the statistical variance -* associated with each element of the "in" array. If this -* second array is given (along with the corresponding "out_var" -* array), then estimates of the variance of the resampled data -* will also be returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* type -* A value taken from the "DataType" enum, which specifies the -* data type of the input and output arrays containing the -* gridded data (and variance) values. -* interp -* A value selected from a set of pre-defined macros to identify -* which sub-pixel interpolation algorithm should be used. -* finterp -* If "interp" is set to a value which requires a user-supplied -* function, then a pointer to that function shoild be given -* here. Otherwise, this value is not used and may be a NULL -* pointer. -* params -* Pointer to an optional array of parameters that may be passed -* to the interpolation algorithm, if required. If no parameters -* are required, a NULL pointer should be supplied. -* factor -* A factor by which to scale the resampled output data values before -* returning them. If flux is being conserved this should be set to -* the ratio of the output pixel size to the input pixel size in the -* section. Otherwise it should be set to 1.0. -* flags -* The bitwise OR of a set of flag values which provide -* additional control over the resampling operation. -* badval_ptr -* If the AST__USEBAD flag is set (above), this parameter is a -* pointer to a value which is used to identify bad data and/or -* variance values in the input array(s). The referenced value's -* data type must match that of the "in" (and "in_var") -* arrays. Unless the AST__NOBAD flag is set, the same value will -* also be used to flag any output array elements for which -* resampled values could not be obtained. The output arrays(s) -* may be flagged with this value whether or not the AST__USEBAD -* flag is set (the function return value indicates whether any -* such values have been produced). -* ndim_out -* The number of dimensions in the output grid. This should be -* at least one. -* lbnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the first -* pixel in the output data grid along each dimension. -* ubnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the last -* pixel in the output data grid along each dimension. -* -* Note that "lbnd_out" and "ubnd_out" together define the shape -* and size of the output data grid in the same way as "lbnd_in" -* and "ubnd_in" define the shape and size of the input grid -* (see above). -* lbnd -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the first pixel in the -* section of the output data grid for which a value is -* required. -* ubnd -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the last pixel in the -* section of the output data grid for which a value is -* required. -* -* Note that "lbnd" and "ubnd" define the shape and position of -* the section of the output grid for which resampled values are -* required. This section should lie wholly within the extent of -* the output grid (as defined by the "lbnd_out" and "ubnd_out" -* arrays). Regions of the output grid lying outside this section -* will not be modified. -* out -* Pointer to an array with the same data type as the "in" -* array, into which the resampled data will be returned. The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the resampled values may be returned. This array will only be -* used if the "in_var" array has been given. -* -* If no output variance estimates are required, a NULL pointer -* should be given. - -* Returned Value: -* The number of output grid points for which no valid output value -* could be obtained. - -* Notes: -* - This function does not take steps to limit memory usage if the -* grids supplied are large. To resample large grids in a more -* memory-efficient way, the ResampleWithBlocking function should -* be used. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific data */ - AstPointSet *pset_in; /* Input PointSet for transformation */ - AstPointSet *pset_out; /* Output PointSet for transformation */ - const double *grad; /* Pointer to gradient matrix of linear fit */ - const double *par; /* Pointer to parameter array */ - const double *zero; /* Pointer to zero point array of fit */ - double **ptr_in; /* Pointer to input PointSet coordinates */ - double **ptr_out; /* Pointer to output PointSet coordinates */ - double *accum; /* Pointer to array of accumulated sums */ - double fwhm; /* Full width half max. of gaussian */ - double lpar[ 1 ]; /* Local parameter array */ - double x1; /* Interim x coordinate value */ - double y1; /* Interim y coordinate value */ - int *dim; /* Pointer to array of output pixel indices */ - int *offset; /* Pointer to array of output pixel offsets */ - int *stride; /* Pointer to array of output grid strides */ - int conserve; /* Conserve flux? */ - int coord_in; /* Loop counter for input dimensions */ - int coord_out; /* Loop counter for output dimensions */ - int done; /* All pixel indices done? */ - int i1; /* Interim offset into "accum" array */ - int i2; /* Final offset into "accum" array */ - int idim; /* Loop counter for dimensions */ - int ix; /* Loop counter for output x coordinate */ - int iy; /* Loop counter for output y coordinate */ - int nbad; /* Number of pixels assigned a bad value */ - int neighb; /* Number of neighbouring pixels */ - int npoint; /* Number of output points (pixels) */ - int off1; /* Interim pixel offset into output array */ - int off; /* Final pixel offset into output array */ - int point; /* Counter for output points (pixels ) */ - int result; /* Result value to be returned */ - int s; /* Temporary variable for strides */ - int usevar; /* Process variance array? */ - void (* gifunc)( void ); /* General interpolation function */ - void (* kernel)( double, const double [], int, double *, int * ); /* Kernel fn. */ - void (* fkernel)( double, const double [], int, double * ); /* User kernel fn. */ - -/* Initialise. */ - result = 0; - -/* Get a pointer to a structure holding thread-specific global data values */ - astGET_GLOBALS(this); - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialisation. */ - pset_in = NULL; - ptr_in = NULL; - neighb = 0; - gifunc = NULL; - kernel = NULL; - fkernel = NULL; - -/* See if we are conserving flux */ - conserve = flags & AST__CONSERVEFLUX; - -/* If we are conserving flux, then we need some way to tell which output - array elements have been assigned a value and which have not. If the - AST__NOBAD flag has been specified then this is not possible to report - an error. */ - if( ( flags & AST__NOBAD ) && conserve ) { - astError( AST__BADFLG, "astResample: Cannot use the AST__NOBAD and " - "AST__CONSERVEFLUX flags together (programming error)." , status); - } - -/* Calculate the number of output points, as given by the product of - the output grid dimensions. */ - for ( npoint = 1, coord_out = 0; coord_out < ndim_out; coord_out++ ) { - npoint *= ubnd[ coord_out ] - lbnd[ coord_out ] + 1; - } - -/* Allocate workspace. */ - offset = astMalloc( sizeof( int ) * (size_t) npoint ); - stride = astMalloc( sizeof( int ) * (size_t) ndim_out ); - if ( astOK ) { - -/* Calculate the stride for each output grid dimension. */ - off = 0; - s = 1; - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - stride[ coord_out ] = s; - s *= ubnd_out[ coord_out ] - lbnd_out[ coord_out ] + 1; - } - -/* A linear fit to the Mapping is available. */ -/* ========================================= */ - if ( linear_fit ) { - -/* If a linear fit to the Mapping has been provided, then obtain - pointers to the array of gradients and zero-points comprising the - fit. */ - grad = linear_fit + ndim_in; - zero = linear_fit; - -/* Create a PointSet to hold the input grid coordinates and obtain an - array of pointers to its coordinate data. */ - pset_in = astPointSet( npoint, ndim_in, "", status ); - ptr_in = astGetPoints( pset_in ); - if ( astOK ) { - -/* Initialise the count of output points. */ - point = 0; - -/* Handle the 1-dimensional case optimally. */ -/* ---------------------------------------- */ - if ( ( ndim_in == 1 ) && ( ndim_out == 1 ) ) { - -/* Loop through the pixels of the output grid and transform their x - coordinates into the input grid's coordinate system using the - linear fit supplied. Store the results in the PointSet created - above. */ - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_in[ 0 ][ point ] = zero[ 0 ] + grad[ 0 ] * (double) ix; - -/* Calculate the offset of each pixel within the output array. */ - offset[ point ] = ix - lbnd_out[ 0 ]; - point++; - } - -/* Handle the 2-dimensional case optimally. */ -/* ---------------------------------------- */ - } else if ( ( ndim_in == 2 ) && ( ndim_out == 2 ) ) { - -/* Loop through the range of y coordinates in the output grid and - calculate interim values of the input coordinates using the linear - fit supplied. */ - for ( iy = lbnd[ 1 ]; iy <= ubnd[ 1 ]; iy++ ) { - x1 = zero[ 0 ] + grad[ 1 ] * (double) iy; - y1 = zero[ 1 ] + grad[ 3 ] * (double) iy; - -/* Also calculate an interim pixel offset into the output array. */ - off1 = stride[ 1 ] * ( iy - lbnd_out[ 1 ] ) - lbnd_out[ 0 ]; - -/* Now loop through the range of output x coordinates and calculate - the final values of the input coordinates, storing the results in - the PointSet created above. */ - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_in[ 0 ][ point ] = x1 + grad[ 0 ] * (double) ix; - ptr_in[ 1 ][ point ] = y1 + grad[ 2 ] * (double) ix; - -/* Also calculate final pixel offsets into the output array. */ - offset[ point ] = off1 + ix; - point++; - } - } - -/* Handle other numbers of dimensions. */ -/* ----------------------------------- */ - } else { - -/* Allocate workspace. */ - accum = astMalloc( sizeof( double ) * - (size_t) ( ndim_in * ndim_out ) ); - dim = astMalloc( sizeof( int ) * (size_t) ndim_out ); - if ( astOK ) { - -/* Initialise an array of pixel indices for the output grid which - refer to the first pixel for which we require a value. Also - calculate the offset of this pixel within the output array. */ - off = 0; - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - dim[ coord_out ] = lbnd[ coord_out ]; - off += stride[ coord_out ] * - ( dim[ coord_out ] - lbnd_out[ coord_out ] ); - } - -/* To calculate each input grid coordinate we must perform a matrix - multiply on the output grid coordinates (using the gradient matrix) - and then add the zero points. However, since we will usually only - be altering one output coordinate at a time (the least - significant), we can avoid the full matrix multiply by accumulating - partial sums for the most significant output coordinates and only - altering those sums which need to change each time. The zero points - never change, so we first fill the "most significant" end of the - "accum" array with these. */ - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - accum[ ( coord_in + 1 ) * ndim_out - 1 ] = - zero[ coord_in ]; - } - coord_out = ndim_out - 1; - -/* Now loop to process each output pixel. */ - for ( done = 0; !done; point++ ) { - -/* To generate the input coordinate that corresponds to the current - output pixel, we work down from the most significant dimension - whose index has changed since the previous pixel we considered - (given by "coord_out"). For each affected dimension, we accumulate - in "accum" the matrix sum (including the zero point) for that - dimension and all higher output dimensions. We must accumulate a - separate set of sums for each input coordinate we wish to - produce. (Note that for the first pixel we process, all dimensions - are considered "changed", so we start by initialising the whole - "accum" array.) */ - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - i1 = coord_in * ndim_out; - for ( idim = coord_out; idim >= 1; idim-- ) { - i2 = i1 + idim; - accum[ i2 - 1 ] = accum[ i2 ] + - dim[ idim ] * grad[ i2 ]; - } - -/* The input coordinate for each dimension is given by the accumulated - sum for output dimension zero (giving the sum over all output - dimensions). We do not store this in the "accum" array, but assign - the result directly to the coordinate array of the PointSet created - earlier. */ - ptr_in[ coord_in ][ point ] = accum[ i1 ] + - dim[ 0 ] * grad[ i1 ]; - } - -/* Store the offset of the current pixel in the output array. */ - offset[ point ] = off; - -/* Now update the array of pixel indices to refer to the next output - pixel. */ - coord_out = 0; - do { - -/* The least significant index which currently has less than its - maximum value is incremented by one. The offset into the output - array is updated accordingly. */ - if ( dim[ coord_out ] < ubnd[ coord_out ] ) { - dim[ coord_out ]++; - off += stride[ coord_out ]; - break; - -/* Any less significant indices which have reached their maximum value - are returned to their minimum value and the output pixel offset is - decremented appropriately. */ - } else { - dim[ coord_out ] = lbnd[ coord_out ]; - off -= stride[ coord_out ] * - ( ubnd[ coord_out ] - lbnd[ coord_out ] ); - -/* All the output pixels have been processed once the most significant - pixel index has been returned to its minimum value. */ - done = ( ++coord_out == ndim_out ); - } - } while ( !done ); - } - } - -/* Free the workspace. */ - accum = astFree( accum ); - dim = astFree( dim ); - } - } - -/* No linear fit to the Mapping is available. */ -/* ========================================== */ - } else { - -/* If flux conseravtion was requested, report an error, since we can only - conserve flux if a linear approximation is available. */ - if( conserve && astOK ) { - astError( AST__CNFLX, "astResampleSection(%s): Flux conservation " - "was requested but cannot be performed because either the Mapping " - "is too non-linear, or the requested tolerance is too small.", status, - astGetClass( this ) ); - } - -/* Create a PointSet to hold the coordinates of the output pixels and - obtain a pointer to its coordinate data. */ - pset_out = astPointSet( npoint, ndim_out, "", status ); - ptr_out = astGetPoints( pset_out ); - if ( astOK ) { - -/* Initialise the count of output points. */ - point = 0; - -/* Handle the 1-dimensional case optimally. */ -/* ---------------------------------------- */ - if ( ndim_out == 1 && ndim_in == 1 ) { - -/* Loop through the required range of output x coordinates, assigning - the coordinate values to the PointSet created above. Also store a - pixel offset into the output array. */ - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_out[ 0 ][ point ] = (double) ix; - offset[ point ] = ix - lbnd_out[ 0 ]; - -/* Increment the count of output pixels. */ - point++; - } - -/* Handle the 2-dimensional case optimally. */ -/* ---------------------------------------- */ - } else if ( ndim_out == 2 && ndim_in == 2 ) { - -/* Loop through the required range of output y coordinates, - calculating an interim pixel offset into the output array. */ - for ( iy = lbnd[ 1 ]; iy <= ubnd[ 1 ]; iy++ ) { - off1 = stride[ 1 ] * ( iy - lbnd_out[ 1 ] ) - lbnd_out[ 0 ]; - -/* Loop through the required range of output x coordinates, assigning - the coordinate values to the PointSet created above. Also store a - final pixel offset into the output array. */ - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_out[ 0 ][ point ] = (double) ix; - ptr_out[ 1 ][ point ] = (double) iy; - offset[ point ] = off1 + ix; - -/* Increment the count of output pixels. */ - point++; - } - } - -/* Handle other numbers of dimensions. */ -/* ----------------------------------- */ - } else { - -/* Allocate workspace. */ - dim = astMalloc( sizeof( int ) * (size_t) ndim_out ); - if ( astOK ) { - -/* Initialise an array of pixel indices for the output grid which - refer to the first pixel for which we require a value. Also - calculate the offset of this pixel within the output array. */ - off = 0; - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - dim[ coord_out ] = lbnd[ coord_out ]; - off += stride[ coord_out ] * - ( dim[ coord_out ] - lbnd_out[ coord_out ] ); - } - -/* Loop to generate the coordinates of each output pixel. */ - for ( done = 0; !done; point++ ) { - -/* Copy each pixel's coordinates into the PointSet created above. */ - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - ptr_out[ coord_out ][ point ] = - (double) dim[ coord_out ]; - } - -/* Store the offset of the pixel in the output array. */ - offset[ point ] = off; - -/* Now update the array of pixel indices to refer to the next output - pixel. */ - coord_out = 0; - do { - -/* The least significant index which currently has less than its - maximum value is incremented by one. The offset into the output - array is updated accordingly. */ - if ( dim[ coord_out ] < ubnd[ coord_out ] ) { - dim[ coord_out ]++; - off += stride[ coord_out ]; - break; - -/* Any less significant indices which have reached their maximum value - are returned to their minimum value and the output pixel offset is - decremented appropriately. */ - } else { - dim[ coord_out ] = lbnd[ coord_out ]; - off -= stride[ coord_out ] * - ( ubnd[ coord_out ] - lbnd[ coord_out ] ); - -/* All the output pixels have been processed once the most significant - pixel index has been returned to its minimum value. */ - done = ( ++coord_out == ndim_out ); - } - } while ( !done ); - } - } - -/* Free the workspace. */ - dim = astFree( dim ); - } - -/* When all the output pixel coordinates have been generated, use the - Mapping's inverse transformation to generate the input coordinates - from them. Obtain an array of pointers to the resulting coordinate - data. */ - pset_in = astTransform( this, pset_out, 0, NULL ); - ptr_in = astGetPoints( pset_in ); - } - -/* Annul the PointSet containing the output coordinates. */ - pset_out = astAnnul( pset_out ); - } - } - -/* Resample the input grid. */ -/* ------------------------ */ -/* Determine if a variance array is to be processed. */ - usevar = ( in_var && out_var ); - -/* If the input coordinates have been produced successfully, identify - the input grid resampling method to be used. */ - if ( astOK ) { - -/* Nearest pixel. */ -/* -------------- */ - switch ( interp ) { - case AST__NEAREST: - -/* Define a macro to use a "case" statement to invoke the - nearest-pixel interpolation function appropriate to a given data - type. */ -#define CASE_NEAREST(X,Xtype) \ - case ( TYPE_##X ): \ - result = \ - InterpolateNearest##X( ndim_in, lbnd_in, ubnd_in, \ - (Xtype *) in, (Xtype *) in_var, \ - npoint, offset, \ - (const double *const *) ptr_in, \ - flags, *( (Xtype *) badval_ptr ), \ - (Xtype *) out, (Xtype *) out_var, status ); \ - break; - -/* Use the above macro to invoke the appropriate function. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_NEAREST(LD,long double) -#endif - CASE_NEAREST(D,double) - CASE_NEAREST(F,float) - CASE_NEAREST(L,long int) - CASE_NEAREST(UL,unsigned long int) - CASE_NEAREST(K,INT_BIG) - CASE_NEAREST(UK,UINT_BIG) - CASE_NEAREST(I,int) - CASE_NEAREST(UI,unsigned int) - CASE_NEAREST(S,short int) - CASE_NEAREST(US,unsigned short int) - CASE_NEAREST(B,signed char) - CASE_NEAREST(UB,unsigned char) - } - break; - -/* Undefine the macro. */ -#undef CASE_NEAREST - -/* Linear interpolation. */ -/* --------------------- */ -/* Note this is also the default if zero is given. */ - case AST__LINEAR: - case 0: - -/* Define a macro to use a "case" statement to invoke the linear - interpolation function appropriate to a given data type. */ -#define CASE_LINEAR(X,Xtype) \ - case ( TYPE_##X ): \ - result = \ - InterpolateLinear##X( ndim_in, lbnd_in, ubnd_in,\ - (Xtype *) in, (Xtype *) in_var, \ - npoint, offset, \ - (const double *const *) ptr_in, \ - flags, *( (Xtype *) badval_ptr ), \ - (Xtype *) out, (Xtype *) out_var, status ); \ - break; - -/* Use the above macro to invoke the appropriate function. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_LINEAR(LD,long double) -#endif - CASE_LINEAR(D,double) - CASE_LINEAR(F,float) - CASE_LINEAR(L,long int) - CASE_LINEAR(UL,unsigned long int) - CASE_LINEAR(K,INT_BIG) - CASE_LINEAR(UK,UINT_BIG) - CASE_LINEAR(I,int) - CASE_LINEAR(UI,unsigned int) - CASE_LINEAR(S,short int) - CASE_LINEAR(US,unsigned short int) - CASE_LINEAR(B,signed char) - CASE_LINEAR(UB,unsigned char) - } - break; - -/* Undefine the macro. */ -#undef CASE_LINEAR - -/* Interpolation using a 1-d kernel. */ -/* --------------------------------- */ - case AST__GAUSS: - case AST__SINC: - case AST__SINCCOS: - case AST__SINCGAUSS: - case AST__SINCSINC: - case AST__SOMB: - case AST__SOMBCOS: - case AST__UKERN1: /* User-supplied 1-d kernel function */ - -/* Obtain a pointer to the appropriate 1-d kernel function (either - internal or user-defined) and set up any parameters it may - require. */ - par = NULL; - switch ( interp ) { - -/* sinc(pi*x) interpolation. */ -/* ------------------------- */ -/* Assign the kernel function. */ - case AST__SINC: - kernel = Sinc; - -/* Calculate the number of neighbouring pixels to use. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) { - neighb = 2; - } else { - neighb = MaxI( 1, neighb, status ); - } - break; - -/* sinc(pi*x)*cos(k*pi*x) interpolation. */ -/* ------------------------------------- */ -/* Assign the kernel function. */ - case AST__SINCCOS: - kernel = SincCos; - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 0.5 / MaxD( 1.0, params[ 1 ], status ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, the number will be calculated automatically below. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = INT_MAX; - -/* Calculate the maximum number of neighbouring pixels required by the - width of the kernel, and use this value if preferable. */ - neighb = MinI( neighb, - (int) ceil( MaxD( 1.0, params[ 1 ], status ) ), status ); - break; - -/* somb(pi*x) interpolation. */ -/* ------------------------- */ -/* Assign the kernel function. */ - case AST__SOMB: - kernel = Somb; - -/* Calculate the number of neighbouring pixels to use. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) { - neighb = 2; - } else { - neighb = MaxI( 1, neighb, status ); - } - break; - -/* somb(pi*x)*cos(k*pi*x) interpolation. */ -/* ------------------------------------- */ -/* Assign the kernel function. */ - case AST__SOMBCOS: - kernel = SombCos; - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 0.5 / MaxD( 1.0, params[ 1 ], status ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, the number will be calculated automatically below. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = INT_MAX; - -/* Calculate the maximum number of neighbouring pixels required by the - width of the kernel, and use this value if preferable. */ - neighb = MinI( neighb, - (int) ceil( MaxD( 1.0, params[ 1 ], status ) ), status ); - break; - -/* sinc(pi*x)*exp(-k*x*x) interpolation. */ -/* ------------------------------------- */ -/* Assign the kernel function. */ - case AST__SINCGAUSS: - kernel = SincGauss; - -/* Constrain the full width half maximum of the gaussian factor. */ - fwhm = MaxD( 0.1, params[ 1 ], status ); - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 4.0 * log( 2.0 ) / ( fwhm * fwhm ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, use the number of neighbouring pixels required by the width - of the kernel (out to where the gaussian term falls to 1% of its - peak value). */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = (int) ceil( sqrt( -log( 0.01 ) / - lpar[ 0 ] ) ); - break; - -/* exp(-k*x*x) interpolation. */ -/* -------------------------- */ -/* Assign the kernel function. */ - case AST__GAUSS: - kernel = Gauss; - -/* Constrain the full width half maximum of the gaussian. */ - fwhm = MaxD( 0.1, params[ 1 ], status ); - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 4.0 * log( 2.0 ) / ( fwhm * fwhm ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, use the number of neighbouring pixels required by the width - of the kernel (out to where the gaussian term falls to 1% of its - peak value). */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = (int) ceil( sqrt( -log( 0.01 ) / - lpar[ 0 ] ) ); - break; - -/* sinc(pi*x)*sinc(k*pi*x) interpolation. */ -/* -------------------------------------- */ -/* Assign the kernel function. */ - case AST__SINCSINC: - kernel = SincSinc; - -/* Store the required value of "k" in a local parameter array and pass - this array to the kernel function. */ - lpar[ 0 ] = 0.5 / MaxD( 1.0, params[ 1 ], status ); - par = lpar; - -/* Obtain the number of neighbouring pixels to use. If this is zero or - less, the number will be calculated automatically below. */ - neighb = (int) floor( params[ 0 ] + 0.5 ); - if ( neighb <= 0 ) neighb = INT_MAX; - -/* Calculate the maximum number of neighbouring pixels required by the - width of the kernel, and use this value if preferable. */ - neighb = MinI( neighb, - (int) ceil( MaxD( 1.0, params[ 1 ], status ) ), status ); - break; - -/* User-supplied kernel. */ -/* --------------------- */ -/* Assign the kernel function. */ - case AST__UKERN1: - fkernel = (void (*)( double, const double [], - int, double * )) finterp; - -/* Calculate the number of neighbouring pixels to use. */ - neighb = MaxI( 1, (int) floor( params[ 0 ] + 0.5 ), status ); - -/* Pass a pointer to the "params" array. */ - par = params; - break; - } - -/* Define a macro to use a "case" statement to invoke the 1-d kernel - interpolation function appropriate to a given data type, passing it - the pointer to the kernel function obtained above. */ -#define CASE_KERNEL1(X,Xtype) \ - case ( TYPE_##X ): \ - result = \ - InterpolateKernel1##X( this, ndim_in, lbnd_in, ubnd_in, \ - (Xtype *) in, (Xtype *) in_var, \ - npoint, offset, \ - (const double *const *) ptr_in, \ - kernel, fkernel, neighb, par, flags, \ - *( (Xtype *) badval_ptr ), \ - (Xtype *) out, (Xtype *) out_var, status ); \ - break; - -/* Use the above macro to invoke the appropriate function. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_KERNEL1(LD,long double) -#endif - CASE_KERNEL1(D,double) - CASE_KERNEL1(F,float) - CASE_KERNEL1(L,long int) - CASE_KERNEL1(UL,unsigned long int) - CASE_KERNEL1(K,INT_BIG) - CASE_KERNEL1(UK,UINT_BIG) - CASE_KERNEL1(I,int) - CASE_KERNEL1(UI,unsigned int) - CASE_KERNEL1(S,short int) - CASE_KERNEL1(US,unsigned short int) - CASE_KERNEL1(B,signed char) - CASE_KERNEL1(UB,unsigned char) - } - break; - -/* Undefine the macro. */ -#undef CASE_KERNEL1 - -/* General sub-pixel interpolation function. */ -/* ----------------------------------------- */ - case AST__BLOCKAVE: - case AST__UINTERP: - -/* Define a macro to use a "case" statement to invoke the general - sub-pixel interpolation function appropriate to a given type and - the selected value of the interp variable. */ -#define CASE_GINTERP(X,Xtype) \ - case ( TYPE_##X ): \ -\ -/* Obtain a pointer to the appropriate general interpolation function \ - (either internal or user-defined) and set up any parameters it may \ - require. */ \ - switch ( interp ) { \ -\ -/* Block averaging interpolation. */ \ -/* ------------------------------ */ \ - case AST__BLOCKAVE: \ - gifunc = (void (*)( void )) InterpolateBlockAverage##X; \ - break; \ -\ -/* User-supplied sub-pixel interpolation function. */ \ -/* ----------------------------------------------- */ \ - case AST__UINTERP: \ - gifunc = (void (*)( void )) finterp; \ - break; \ - } \ -\ -/* Invoke the general interpolation function. It has to be cast to the \ - right type (i.e. a function with the correctly typed arguments) \ - to prevent default promotion (to int or double) of its arguments. \ - The cast here corresponds to the declaration of - ast_resample_uinterp##Xtype. */ \ - ( *( (void (*)( int, const int[], const int[], \ - const Xtype[], \ - const Xtype[], \ - int, const int[], \ - const double *const[], \ - const double[], int, \ - Xtype, \ - Xtype *, \ - Xtype *, \ - int * )) \ - gifunc ) )( ndim_in, lbnd_in, ubnd_in, \ - (Xtype *) in, \ - (Xtype *) ( usevar ? in_var : NULL ), \ - npoint, offset, \ - (const double *const *) ptr_in, \ - params, flags, \ - *( (Xtype *) badval_ptr ), \ - (Xtype *) out, \ - (Xtype *) ( usevar ? out_var : NULL ), \ - &nbad ); \ - if ( astOK ) { \ - result += nbad; \ - } else { \ - astError( astStatus, "astResample"#X"(%s): Error " \ - "signalled by user-supplied sub-pixel " \ - "interpolation function.", status, \ - astGetClass( unsimplified_mapping ) ); \ - } \ - break; - -/* Use the above macro to invoke the function. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_GINTERP(LD,long double) -#endif - CASE_GINTERP(D,double) - CASE_GINTERP(F,float) - CASE_GINTERP(L,long int) - CASE_GINTERP(UL,unsigned long int) - CASE_GINTERP(K,INT_BIG) - CASE_GINTERP(UK,UINT_BIG) - CASE_GINTERP(I,int) - CASE_GINTERP(UI,unsigned int) - CASE_GINTERP(S,short int) - CASE_GINTERP(US,unsigned short int) - CASE_GINTERP(B,signed char) - CASE_GINTERP(UB,unsigned char) - } - break; - -/* Undefine the macro. */ -#undef CASE_GINTERP - -/* Error: invalid interpolation scheme specified. */ -/* ---------------------------------------------- */ - default: - -/* Define a macro to report an error message appropriate to a given - data type. */ -#define CASE_ERROR(X) \ - case TYPE_##X: \ - astError( AST__SISIN, "astResample"#X"(%s): Invalid " \ - "sub-pixel interpolation scheme (%d) specified.", status, \ - astGetClass( unsimplified_mapping ), interp ); \ - break; - -/* Use the above macro to report an appropriate error message. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_ERROR(LD) -#endif - CASE_ERROR(D) - CASE_ERROR(F) - CASE_ERROR(L) - CASE_ERROR(UL) - CASE_ERROR(K) - CASE_ERROR(UK) - CASE_ERROR(I) - CASE_ERROR(UI) - CASE_ERROR(S) - CASE_ERROR(US) - CASE_ERROR(B) - CASE_ERROR(UB) - } - break; - -/* Undefine the macro. */ -#undef CASE_ERROR - } - } - -/* Now scale the output values to conserve flux if required. */ - if( conserve ) { - -/* Define a macro to use a "case" statement to invoke the function - appropriate to a given data type. These simply multiple the output data - value by the factor, and the output variance by the square of the - factor. */ -#define CASE_CONSERVE(X,Xtype) \ - case ( TYPE_##X ): \ - ConserveFlux##X( factor, npoint, offset, *( (Xtype *) badval_ptr ), \ - (Xtype *) out, \ - (Xtype *) ( usevar ? out_var : NULL ), status ); \ - break; - -/* Use the above macro to invoke the appropriate function. */ - switch ( type ) { -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - CASE_CONSERVE(LD,long double) -#endif - CASE_CONSERVE(D,double) - CASE_CONSERVE(F,float) - CASE_CONSERVE(L,long int) - CASE_CONSERVE(UL,unsigned long int) - CASE_CONSERVE(K,INT_BIG) - CASE_CONSERVE(UK,UINT_BIG) - CASE_CONSERVE(I,int) - CASE_CONSERVE(UI,unsigned int) - CASE_CONSERVE(S,short int) - CASE_CONSERVE(US,unsigned short int) - CASE_CONSERVE(B,signed char) - CASE_CONSERVE(UB,unsigned char) - } - -/* Undefine the macro. */ -#undef CASE_CONSERVE - } - -/* Annul the PointSet used to hold input coordinates. */ - pset_in = astAnnul( pset_in ); - -/* Free the workspace. */ - offset = astFree( offset ); - stride = astFree( stride ); - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int ResampleWithBlocking( AstMapping *this, const double *linear_fit, - int ndim_in, - const int *lbnd_in, const int *ubnd_in, - const void *in, const void *in_var, - DataType type, int interp, void (* finterp)( void ), - const double *params, int flags, - const void *badval_ptr, int ndim_out, - const int *lbnd_out, const int *ubnd_out, - const int *lbnd, const int *ubnd, - void *out, void *out_var, int *status ) { -/* -* Name: -* ResampleWithBlocking - -* Purpose: -* Resample a section of a data grid in a memory-efficient way. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int ResampleWithBlocking( AstMapping *this, const double *linear_fit, -* int ndim_in, -* const int *lbnd_in, const int *ubnd_in, -* const void *in, const void *in_var, -* DataType type, int interp, void (* finterp)( void ), -* const double *params, int flags, -* const void *badval_ptr, int ndim_out, -* const int *lbnd_out, const int *ubnd_out, -* const int *lbnd, const int *ubnd, -* void *out, void *out_var, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function resamples a rectangular grid of data (with any -* number of dimensions) into a specified section of another -* rectangular grid (with a possibly different number of -* dimensions). The coordinate transformation used is given by the -* inverse transformation of the Mapping which is supplied or, -* alternatively, by a linear approximation fitted to a Mapping's -* inverse transformation. Any pixel interpolation scheme may be -* specified for interpolating between the pixels of the input -* grid. -* -* This function is very similar to ResampleSection, except that in -* order to limit memory usage and to ensure locality of reference, -* it divides the output grid up into "blocks" which have a limited -* extent along each output dimension. Each block, which will not -* contain more than a pre-determined maximum number of pixels, is -* then passed to ResampleSection for resampling. - -* Parameters: -* this -* Pointer to a Mapping, whose inverse transformation may be -* used to transform the coordinates of pixels in the output -* grid into associated positions in the input grid, from which -* the output pixel values should be derived (by interpolation -* if necessary). -* -* The number of input coordintes for the Mapping (Nin -* attribute) should match the value of "ndim_in" (below), and -* the number of output coordinates (Nout attribute) should -* match the value of "ndim_out". -* linear_fit -* Pointer to an optional array of double which contains the -* coefficients of a linear fit which approximates the above -* Mapping's inverse coordinate transformation. If this is -* supplied, it will be used in preference to the above Mapping -* when transforming coordinates. This may be used to enhance -* performance in cases where evaluation of the Mapping's -* inverse transformation is expensive. If no linear fit is -* available, a NULL pointer should be supplied. -* -* The way in which the fit coefficients are stored in this -* array and the number of array elements are as defined by the -* astLinearApprox function. -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input data grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input data grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input data grid, its extent along a -* particular (i'th) dimension being (ubnd_in[i] - lbnd_in[i] + -* 1). They also define the input grid's coordinate system, with -* each pixel being of unit extent along each dimension with -* integral coordinate values at its centre. -* in -* Pointer to the input array of data to be resampled (with one -* element for each pixel in the input grid). The numerical type -* of these data should match the "type" value (below). The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and data type as the "in" array), -* which represent estimates of the statistical variance -* associated with each element of the "in" array. If this -* second array is given (along with the corresponding "out_var" -* array), then estimates of the variance of the resampled data -* will also be returned. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* type -* A value taken from the "DataType" enum, which specifies the -* data type of the input and output arrays containing the -* gridded data (and variance) values. -* interp -* A value selected from a set of pre-defined macros to identify -* which sub-pixel interpolation algorithm should be used. -* finterp -* If "interp" is set to a value which requires a user-supplied -* function, then a pointer to that function shoild be given -* here. Otherwise, this value is not used and may be a NULL -* pointer. -* params -* Pointer to an optional array of parameters that may be passed -* to the interpolation algorithm, if required. If no parameters -* are required, a NULL pointer should be supplied. -* flags -* The bitwise OR of a set of flag values which provide -* additional control over the resampling operation. -* badval_ptr -* If the AST__USEBAD flag is set (above), this parameter is a -* pointer to a value which is used to identify bad data and/or -* variance values in the input array(s). The referenced value's -* data type must match that of the "in" (and "in_var") -* arrays. Unless the AST__NOBAD flag is set, the same value will -* also be used to flag any output array elements for which -* resampled values could not be obtained. The output arrays(s) -* may be flagged with this value whether or not the AST__USEBAD -* flag is set (the function return value indicates whether any -* such values have been produced). -* ndim_out -* The number of dimensions in the output grid. This should be -* at least one. -* lbnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the first -* pixel in the output data grid along each dimension. -* ubnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the last -* pixel in the output data grid along each dimension. -* -* Note that "lbnd_out" and "ubnd_out" together define the shape -* and size of the output data grid in the same way as "lbnd_in" -* and "ubnd_in" define the shape and size of the input grid -* (see above). -* lbnd -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the first pixel in the -* section of the output data grid for which a value is -* required. -* ubnd -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the last pixel in the -* section of the output data grid for which a value is -* required. -* -* Note that "lbnd" and "ubnd" define the shape and position of -* the section of the output grid for which resampled values are -* required. This section should lie wholly within the extent of -* the output grid (as defined by the "lbnd_out" and "ubnd_out" -* arrays). Regions of the output grid lying outside this section -* will not be modified. -* out -* Pointer to an array with the same data type as the "in" -* array, into which the resampled data will be returned. The -* storage order should be such that the coordinate of the first -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order is used). -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the resampled values may be returned. This array will only be -* used if the "in_var" array has been given. -* -* If no output variance estimates are required, a NULL pointer -* should be given. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of output grid points for which no valid output value -* could be obtained. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Constants: */ - const int mxpix = 2 * 1024; /* Maximum number of pixels in a block (this - relatively small number seems to give best - performance) */ - -/* Local Variables: */ - double factor; /* Flux conservation factor */ - int *dim_block; /* Pointer to array of block dimensions */ - int *lbnd_block; /* Pointer to block lower bound array */ - int *ubnd_block; /* Pointer to block upper bound array */ - int dim; /* Dimension size */ - int done; /* All blocks resampled? */ - int hilim; /* Upper limit on maximum block dimension */ - int idim; /* Loop counter for dimensions */ - int lolim; /* Lower limit on maximum block dimension */ - int mxdim_block; /* Maximum block dimension */ - int npix; /* Number of pixels in block */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Allocate workspace. */ - lbnd_block = astMalloc( sizeof( int ) * (size_t) ndim_out ); - ubnd_block = astMalloc( sizeof( int ) * (size_t) ndim_out ); - dim_block = astMalloc( sizeof( int ) * (size_t) ndim_out ); - if ( astOK ) { - -/* Find the optimum block size. */ -/* ---------------------------- */ -/* We first need to find the maximum extent which a block of output - pixels may have in each dimension. We determine this by taking the - output grid extent in each dimension and then limiting the maximum - dimension size until the resulting number of pixels is sufficiently - small. This approach allows the block shape to approximate (or - match) the output grid shape when appropriate. */ - -/* First loop to calculate the total number of output pixels and the - maximum output dimension size. */ - npix = 1; - mxdim_block = 0; - for ( idim = 0; idim < ndim_out; idim++ ) { - dim = ubnd[ idim ] - lbnd[ idim ] + 1; - npix *= dim; - if ( mxdim_block < dim ) mxdim_block = dim; - } - -/* If the number of output pixels is too large for a single block, we - perform iterations to determine the optimum upper limit on a - block's dimension size. Initialise the limits on this result. */ - if ( npix > mxpix ) { - lolim = 1; - hilim = mxdim_block; - -/* Loop to perform a binary chop, searching for the best result until - the lower and upper limits on the result converge to adjacent - values. */ - while ( ( hilim - lolim ) > 1 ) { - -/* Form a new estimate from the mid-point of the previous limits. */ - mxdim_block = ( hilim + lolim ) / 2; - -/* See how many pixels a block contains if its maximum dimension is - limited to this new value. */ - for ( npix = 1, idim = 0; idim < ndim_out ; idim++ ) { - dim = ubnd[ idim ] - lbnd[ idim ] + 1; - npix *= ( dim < mxdim_block ) ? dim : mxdim_block; - } - -/* Update the appropriate limit, according to whether the number of - pixels is too large or too small. */ - *( ( npix <= mxpix ) ? &lolim : &hilim ) = mxdim_block; - } - -/* When iterations have converged, obtain the maximum limit on the - dimension size of a block which results in no more than the maximum - allowed number of pixels per block. However, ensure that all block - dimensions are at least 2. */ - mxdim_block = lolim; - } - if ( mxdim_block < 2 ) mxdim_block = 2; - -/* Calculate the block dimensions by applying this limit to the output - grid dimensions. */ - for ( idim = 0; idim < ndim_out ; idim++ ) { - dim = ubnd[ idim ] - lbnd[ idim ] + 1; - dim_block[ idim ] = ( dim < mxdim_block ) ? dim : mxdim_block; - -/* Also initialise the lower and upper bounds of the first block of - output grid pixels to be resampled, ensuring that this does not - extend outside the grid itself. */ - lbnd_block[ idim ] = lbnd[ idim ]; - ubnd_block[ idim ] = MinI( lbnd[ idim ] + dim_block[ idim ] - 1, - ubnd[ idim ], status ); - } - -/* Determine the flux conservation constant if needed. */ -/* --------------------------------------------------- */ - if( ( flags & AST__CONSERVEFLUX ) && linear_fit ) { - factor = MatrixDet( ndim_in, ndim_out, linear_fit + ndim_in, status ); - } else { - factor = 1.0; - } - -/* Resample each block of output pixels. */ -/* ------------------------------------- */ -/* Loop to generate the extent of each block of output pixels and to - resample them. */ - done = 0; - while ( !done && astOK ) { - -/* Resample the current block, accumulating the sum of bad pixels - produced. */ - result += ResampleSection( this, linear_fit, - ndim_in, lbnd_in, ubnd_in, - in, in_var, type, interp, finterp, params, - factor, flags, badval_ptr, - ndim_out, lbnd_out, ubnd_out, - lbnd_block, ubnd_block, out, out_var, status ); - -/* Update the block extent to identify the next block of output - pixels. */ - idim = 0; - do { - -/* We find the least significant dimension where the upper bound of - the block has not yet reached the upper bound of the region of the - output grid which we are resampling. The block's position is then - incremented by one block extent along this dimension, checking that - the resulting extent does not go outside the region being - resampled. */ - if ( ubnd_block[ idim ] < ubnd[ idim ] ) { - lbnd_block[ idim ] = MinI( lbnd_block[ idim ] + - dim_block[ idim ], ubnd[ idim ], status ); - ubnd_block[ idim ] = MinI( lbnd_block[ idim ] + - dim_block[ idim ] - 1, - ubnd[ idim ], status ); - break; - -/* If any less significant dimensions are found where the upper bound - of the block has reached its maximum value, we reset the block to - its lowest position. */ - } else { - lbnd_block[ idim ] = lbnd[ idim ]; - ubnd_block[ idim ] = MinI( lbnd[ idim ] + dim_block[ idim ] - 1, - ubnd[ idim ], status ); - -/* All the blocks have been processed once the position along the most - significant dimension has been reset. */ - done = ( ++idim == ndim_out ); - } - } while ( !done ); - } - } - -/* Free the workspace. */ - lbnd_block = astFree( lbnd_block ); - ubnd_block = astFree( ubnd_block ); - dim_block = astFree( dim_block ); - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* Mapping member function (over-rides the astSetAttrib protected -* method inherited from the Object class). - -* Description: -* This function assigns an attribute value for a Mapping, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Mapping. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstMapping *this; /* Pointer to the Mapping structure */ - int invert; /* Invert attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - int report; /* Report attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Mapping structure. */ - this = (AstMapping *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* Invert. */ -/* ------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "invert= %d %n", &invert, &nc ) ) - && ( nc >= len ) ) { - astSetInvert( this, invert ); - -/* Report. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "report= %d %n", &report, &nc ) ) - && ( nc >= len ) ) { - astSetReport( this, report ); - -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* If the attribute was not recognised, use this macro to report an error - if a read-only attribute has been specified. */ - } else if ( MATCH( "nin" ) || - MATCH( "nout" ) || - MATCH( "islinear" ) || - MATCH( "issimple" ) || - MATCH( "tranforward" ) || - MATCH( "traninverse" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static void Sinc( double offset, const double params[], int flags, - double *value, int *status ) { -/* -* Name: -* Sinc - -* Purpose: -* 1-dimensional sinc(pi*x) interpolation kernel. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void Sinc( double offset, const double params[], int flags, -* double *value, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function calculates the value of a 1-dimensional sub-pixel -* interpolation kernel. The function used is sinc(pi*x), where -* sinc(z)=sin(z)/z. - -* Parameters: -* offset -* The offset of a pixel from the interpolation point, measured -* in pixels. -* params -* Not used. -* flags -* Not used. -* value -* Pointer to a double to receive the calculated kernel value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error checking and does not -* generate errors. -*/ - -/* Local Variables: */ - static double pi; /* Value of pi */ - static int init = 0; /* Initialisation flag */ - -/* On the first invocation, initialise a local value for pi. Do this - only once. */ - if ( !init ) { - pi = acos( -1.0 ); - init = 1; - } - -/* Scale the offset. */ - offset *= pi; - -/* Evaluate the function. */ - *value = ( offset != 0.0 ) ? ( sin( offset ) / offset ) : 1.0; -} - -static void SincCos( double offset, const double params[], int flags, - double *value, int *status ) { -/* -* Name: -* SincCos - -* Purpose: -* 1-dimensional sinc(pi*x)*cos(k*pi*x) interpolation kernel. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void SincCos( double offset, const double params[], int flags, -* double *value, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function calculates the value of a 1-dimensional sub-pixel -* interpolation kernel. The function used is sinc(pi*x)*cos(k*pi*x) -* out to the point where cos(k*pi*x) = 0, and zero beyond. Here, -* sinc(z)=sin(z)/z. - -* Parameters: -* offset -* The offset of a pixel from the interpolation point, measured -* in pixels. -* params -* The first element of this array should give a value for "k" -* in the cos(k*pi*x) term. -* flags -* Not used. -* value -* Pointer to a double to receive the calculated kernel value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error checking and does not -* generate errors. -*/ - -/* Local Variables: */ - double offset_k; /* Scaled offset */ - static double halfpi; /* Value of pi/2 */ - static double pi; /* Value of pi */ - static int init = 0; /* Initialisation flag */ - -/* On the first invocation, initialise local values for pi and - pi/2. Do this only once. */ - if ( !init ) { - pi = acos( -1.0 ); - halfpi = 0.5 * pi; - init = 1; - } - -/* Multiply the offset by pi and remove its sign. */ - offset = pi * fabs( offset ); - -/* Find the offset scaled by the "k" factor. */ - offset_k = offset * params[ 0 ]; - -/* If the cos(k*pi*x) term has not reached zero, calculate the - result. */ - if ( offset_k < halfpi ) { - *value = ( ( offset != 0.0 ) ? ( sin( offset ) / offset ) : 1.0 ) * - cos( offset_k ); - -/* Otherwise, the result is zero. */ - } else { - *value = 0.0; - } -} - -static void SincGauss( double offset, const double params[], int flags, - double *value, int *status ) { -/* -* Name: -* SincGauss - -* Purpose: -* 1-dimensional sinc(pi*x)*exp(-k*x*x) interpolation kernel. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void SincGauss( double offset, const double params[], int flags, -* double *value, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function calculates the value of a 1-dimensional sub-pixel -* interpolation kernel. The function used is sinc(pi*x)*exp(-k*x*x), -* where sinc(z)=sin(z)/z. - -* Parameters: -* offset -* The offset of a pixel from the interpolation point, measured -* in pixels. -* params -* The first element of this array should give a value for "k" -* in the exp(-k*x*x) term. -* flags -* Not used. -* value -* Pointer to a double to receive the calculated kernel value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error checking and does not -* generate errors. -*/ - -/* Local Variables: */ - double offset_pi; /* Offset multiplied by pi */ - static double pi; /* Value of pi */ - static int init = 0; /* Initialisation flag */ - -/* On the first invocation, initialise a local value for pi. Do this - only once. */ - if ( !init ) { - pi = acos( -1.0 ); - init = 1; - } - -/* Find the offset scaled by pi. */ - offset_pi = pi * offset; - -/* Calculate the result. */ - *value = ( ( offset_pi != 0.0 ) ? ( sin( offset_pi ) / offset_pi ) : 1.0 ) * - exp( -params[ 0 ] * offset * offset ); -} - -static void SincSinc( double offset, const double params[], int flags, - double *value, int *status ) { -/* -* Name: -* SincSinc - -* Purpose: -* 1-dimensional sinc(pi*x)*sinc(k*pi*x) interpolation kernel. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void SincSinc( double offset, const double params[], int flags, -* double *value, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function calculates the value of a 1-dimensional sub-pixel -* interpolation kernel. The function used is sinc(pi*x)*sinc(k*pi*x), -* out to the point where sinc(k*pi*x)=0, and zero beyond. Here, -* sinc(z)=sin(z)/z. - -* Parameters: -* offset -* The offset of a pixel from the interpolation point, measured -* in pixels. -* params -* The first element of this array should give a value for "k" -* in the sinc(k*pi*x) term. -* flags -* Not used. -* value -* Pointer to a double to receive the calculated kernel value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error checking and does not -* generate errors. -*/ - -/* Local Variables: */ - double offset_k; /* Scaled offset */ - static double halfpi; /* Value of pi/2 */ - static double pi; /* Value of pi */ - static int init = 0; /* Initialisation flag */ - -/* On the first invocation, initialise local values for pi and - pi/2. Do this only once. */ - if ( !init ) { - pi = acos( -1.0 ); - halfpi = 0.5 * pi; - init = 1; - } - -/* Multiply the offset by pi and remove its sign. */ - offset = pi * fabs( offset ); - -/* Find the offset scaled by the "k" factor. */ - offset_k = offset * params[ 0 ]; - -/* If the sinc(k*pi*x) term has not reached zero, calculate the - result. */ - if ( offset_k < halfpi ) { - *value = ( ( offset != 0.0 ) ? ( sin( offset ) / offset ) : 1.0 ) * - ( ( offset_k != 0.0 ) ? ( sin( offset_k ) / offset_k ) : 1.0 ); - -/* Otherwise, the result is zero. */ - } else { - *value = 0.0; - } -} - -static AstMapping *Simplify( AstMapping *this, int *status ) { -/* -*++ -* Name: -c astSimplify -f AST_SIMPLIFY - -* Purpose: -* Simplify a Mapping. - -* Type: -* Public function. - -* Synopsis: -c #include "mapping.h" -c AstMapping *astSimplify( AstMapping *this ) -f RESULT = AST_SIMPLIFY( THIS, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -* This function simplifies a Mapping (which may be a compound -* Mapping such as a CmpMap) to eliminate redundant computational -* steps, or to merge separate steps which can be performed more -* efficiently in a single operation. -* -* As a simple example, a Mapping which multiplied coordinates by -* 5, and then multiplied the result by 10, could be simplified to -* a single step which multiplied by 50. Similarly, a Mapping which -* multiplied by 5, and then divided by 5, could be reduced to a -* simple copying operation. -* -* This function should typically be applied to Mappings which have -* undergone substantial processing or have been formed by merging -* other Mappings. It is of potential benefit, for example, in -* reducing execution time if applied before using a Mapping to -* transform a large number of coordinates. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the original Mapping. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSimplify() -f AST_SIMPLIFY = INTEGER -* A new pointer to the (possibly simplified) Mapping. - -* Applicability: -* Mapping -* This function applies to all Mappings. -* FrameSet -* If the supplied Mapping is a FrameSet, the returned Mapping -* will be a copy of the supplied FrameSet in which all the -* inter-Frame Mappings have been simplified. - -* Notes: -* - Mappings that have a set value for their Ident attribute are -* left unchanged after simplification. This is so that their -* individual identity is preserved. This restriction does not -* apply to the simplification of Frames. -* - This function can safely be applied even to Mappings which -* cannot be simplified. If no simplification is possible, it -c behaves exactly like astClone and returns a pointer to the -f behaves exactly like AST_CLONE and returns a pointer to the -* original Mapping. -* - The Mapping returned by this function may not be independent -* of the original (even if simplification was possible), and -* modifying it may therefore result in indirect modification of -* the original. If a completely independent result is required, a -c copy should be made using astCopy. -f copy should be made using AST_COPY. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstMapping **map_list; /* Pointer to array of Mapping pointers */ - AstMapping *map; /* Cloned pointer to nominated Mapping */ - AstMapping *result; /* Pointer to result Mapping */ - int *invert_list; /* Pointer to array of invert flags */ - int imap; /* Loop counter for Mappings */ - int modified; /* Index of first modified element */ - int nmap; /* Number of Mappings */ - int simpler; /* Simplification achieved? */ - -/* Initialise. */ - result = NULL; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Initialise dynamic arrays of Mapping pointers and associated invert - flags. */ - nmap = 0; - map_list = NULL; - invert_list = NULL; - -/* Build a Mapping list to contain this Mapping (the list should only - have 1 element). */ - astMapList( this, 1, astGetInvert( this ), &nmap, &map_list, &invert_list ); - -/* Pass the list repeatedly to the "astMapMerge" method for - simplification. */ - simpler = 0; - while ( astOK ) { - map = astClone( map_list[ 0 ] ); - modified = astMapMerge( map, 0, 1, &nmap, &map_list, &invert_list ); - map = astAnnul( map ); - -/* Quit looping if the number of Mappings increases above 1, or if no - further change occurs. Note if any simplification was achieved. */ - if ( ( nmap > 1 ) || ( modified < 0 ) ) break; - simpler = 1; - } - -/* Check whether simplification has occurred. If not, simply clone the - original Mapping pointer. This is what will normally happen for - Mapping classes which inherit the default (null) "astMapMerge" - method from this class and do not define one of their own. */ - if ( astOK ) { - if ( !simpler || ( nmap > 1 ) ) { - result = astClone( this ); - -/* If simplification occurred, test if the resulting Mapping has the - Invert attribute value we want. If so, we can simply clone a - pointer to it. */ - } else { - if ( invert_list[ 0 ] == astGetInvert( map_list[ 0 ] ) ) { - result = astClone( map_list[ 0 ] ); - -/* If not, we must make a copy. */ - } else { - result = astCopy( map_list[ 0 ] ); - -/* Either clear the copy's Invert attribute, or set it to 1, as - required. */ - if ( invert_list[ 0 ] ) { - astSetInvert( result, 1 ); - } else { - astClearInvert( result ); - } - } - } - } - -/* Loop to annul all the pointers in the Mapping list. */ - for ( imap = 0; imap < nmap; imap++ ) { - map_list[ imap ] = astAnnul( map_list[ imap ] ); - } - -/* Free the dynamic arrays. */ - map_list = astFree( map_list ); - invert_list = astFree( invert_list ); - -/* If an error occurred, annul the returned Mapping. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void Somb( double offset, const double params[], int flags, - double *value, int *status ) { -/* -* Name: -* Somb - -* Purpose: -* 1-dimensional somb(pi*x) interpolation kernel. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void Somb( double offset, const double params[], int flags, -* double *value, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function calculates the value of a 1-dimensional sub-pixel -* interpolation kernel. The function used is somb(pi*x), where -* somb(z)=2*J1(z)/z (J1 is a Bessel function of the first kind of -* order 1). - -* Parameters: -* offset -* The offset of a pixel from the interpolation point, measured -* in pixels. -* params -* Not used. -* flags -* Not used. -* value -* Pointer to a double to receive the calculated kernel value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error checking and does not -* generate errors. -*/ - -/* Local Variables: */ - static double pi; /* Value of pi */ - static int init = 0; /* Initialisation flag */ - -/* On the first invocation, initialise a local value for pi. Do this - only once. */ - if ( !init ) { - pi = acos( -1.0 ); - init = 1; - } - -/* Scale the offset. */ - offset *= pi; - -/* Evaluate the function. */ - *value = ( offset != 0.0 ) ? ( 2.0*J1Bessel( offset, status ) / offset ) : 1.0; -} - -static void SombCos( double offset, const double params[], int flags, - double *value, int *status ) { -/* -* Name: -* SombCos - -* Purpose: -* 1-dimensional somb(pi*x)*cos(k*pi*x) interpolation kernel. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void SombCos( double offset, const double params[], int flags, -* double *value, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function calculates the value of a 1-dimensional sub-pixel -* interpolation kernel. The function used is somb(pi*x)*cos(k*pi*x) -* out to the point where cos(k*pi*x) = 0, and zero beyond. Here, -* somb(z)=2*J1(z)/z (J1 is a Bessel function of the first kind of -* order 1). - -* Parameters: -* offset -* The offset of a pixel from the interpolation point, measured -* in pixels. -* params -* The first element of this array should give a value for "k" -* in the cos(k*pi*x) term. -* flags -* Not used. -* value -* Pointer to a double to receive the calculated kernel value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error checking and does not -* generate errors. -*/ - -/* Local Variables: */ - double offset_k; /* Scaled offset */ - static double halfpi; /* Value of pi/2 */ - static double pi; /* Value of pi */ - static int init = 0; /* Initialisation flag */ - -/* On the first invocation, initialise local values for pi and - pi/2. Do this only once. */ - if ( !init ) { - pi = acos( -1.0 ); - halfpi = 0.5 * pi; - init = 1; - } - -/* Multiply the offset by pi and remove its sign. */ - offset = pi * fabs( offset ); - -/* Find the offset scaled by the "k" factor. */ - offset_k = offset * params[ 0 ]; - -/* If the cos(k*pi*x) term has not reached zero, calculate the - result. */ - if ( offset_k < halfpi ) { - *value = ( ( offset != 0.0 ) ? ( J1Bessel( offset, status ) / offset ) : 1.0 ) * - cos( offset_k ); - -/* Otherwise, the result is zero. */ - } else { - *value = 0.0; - } -} - -static int SpecialBounds( const MapData *mapdata, double *lbnd, double *ubnd, - double xl[], double xu[], int *status ) { -/* -* Name: -* SpecialBounds - -* Purpose: -* Estimate coordinate bounds using special points. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int SpecialBounds( const MapData *mapdata, double *lbnd, double *ubnd, -* double xl[], double xu[], int *status ); - -* Class Membership: -* Mapping member function. - -* Description: -* This function makes a rough estimate of the lower and upper -* bounds of a Mapping function over a constrained region of its -* input coordinate space by transforming a set of special test -* points. The points used lie at the corners of the constrained -* region, at the centre of each of its faces, at its centroid, and -* (if within the coordinate constraints) the origin. -* -* In many practical cases, the true extrema may actually lie at -* one or other of these points, in which case the true bounds will -* be found. In other cases, this function only provides an -* approximate limit on each bound (there is no way of telling if -* this is the case, however). In either case, having these initial -* estimates can speed subsequent searches to find the global -* extrema as well as making that search more secure - -* Parameters: -* mapdata -* Pointer to a MapData structure describing the Mapping -* function, its coordinate constraints, etc. -* lbnd -* Pointer to a double. On entry, this should contain a -* previously-obtained upper limit on the lower bound, or -* AST__BAD if no such limit is available. On exit, it will be -* updated with a new estimate of the lower bound, if a better -* one has been found. -* ubnd -* Pointer to a double. On entry, this should contain a -* previously-obtained lower limit on the upper bound, or -* AST__BAD if no such limit is available. On exit, it will be -* updated with a new estimate of the upper bound, if a better -* one has been found. -* xl -* Pointer to an array of double, with one element for each -* input coordinate, in which to return the position of a (not -* necessarily unique) input point at which the lower output -* bound is reached. This array is not altered if an improved -* estimate of the lower bound cannot be found. -* xu -* Pointer to an array of double, with one element for each -* input coordinate, in which to return the position of a (not -* necessarily unique) input point at which the upper output -* bound is reached. This array is not altered if an improved -* estimate of the upper bound cannot be found. -* status -* Pointer to the inherited status variable. - -* Returned: -* A flag indicating if the returned values can be refined. - -*/ - -/* Local Variables: */ - AstPointSet *pset_in; /* PointSet for input coordinates */ - AstPointSet *pset_out; /* PointSet for output coordinates */ - double **ptr_in; /* Pointer to input coordinates */ - double **ptr_out; /* Pointer to output coordinates */ - double *sxl; /* Secondary xl values */ - double *sxu; /* Secondary xu values */ - double f; /* Output coordinate value */ - double slbnd; /* Secondary lbnd value */ - double subnd; /* Secondary lbnd value */ - int *limit; /* Workspace for lower/upper limit flags */ - int bad; /* Output coordinate bad? */ - int coord; /* Loop counter for coordinates */ - int done; /* All corners done? */ - int face; /* Loop counter for faces */ - int ic; /* Index of corner */ - int icen; /* Index of centroid point */ - int ncorner; /* Number of corners */ - int ncoord; /* Number of input coordinates */ - int npoint; /* Number of points */ - int origin; /* Origin lies within bounds? */ - int point; /* Loop counter for points */ - int result; /* Returned flag */ - -/* Initialise */ - result = 1; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - pset_out = NULL; - -/* Obtain the number of coordinate axes and calculate the number of - points required in order to place one at every corner of the - constrained region of the coordinate space. */ - ncoord = mapdata->nin; - for ( npoint = 1, coord = 0; coord < ncoord; coord++ ) npoint *= 2; - -/* Also include a second point at each corner,offset slightly from the - corner towards the centroid */ - ncorner = npoint; - npoint *= 2; - -/* Also include placing one at the centre of every face and one at the - centroid of the constrained coordinate space. */ - npoint += 2 * ncoord + 1; - -/* Determine if the origin lies within the bounds. If so, include it - as a further point. */ - origin = 1; - for ( coord = 0; coord < ncoord; coord++ ) { - if ( ( mapdata->lbnd[ coord ] > 0.0 ) || - ( mapdata->ubnd[ coord ] < 0.0 ) ) { - origin = 0; - break; - } - } - if ( origin ) npoint++; - -/* Initialise secondary bounds to be the supplied primary bounds */ - slbnd = *lbnd; - subnd = *ubnd; - -/* Create workspace for ssecondary xl xu values */ - sxl = astMalloc( sizeof(double)*(size_t) ncoord ); - sxu = astMalloc( sizeof(double)*(size_t) ncoord ); - -/* Create a PointSet to hold the coordinates and obtain a pointer to - its coordinate values. Also allocate workspace for calculating the - corner coordinates. */ - pset_in = astPointSet( npoint, ncoord, "", status ); - ptr_in = astGetPoints( pset_in ); - limit = astMalloc( sizeof( int ) * (size_t) ncoord ); - if ( astOK ) { - -/* Initialise the workspace. */ - for ( coord = 0; coord < ncoord; coord++ ) limit[ coord ] = 0; - -/* Loop to visit every corner. */ - point = 0; - done = 0; - do { - -/* At each corner, translate the contents of the "limit" array - (containing zeros and ones) into the lower or upper bound on the - corresponding axis. This gives the coordinates of the corner, which - we store in the input PointSet. */ - for ( coord = 0; coord < ncoord; coord++ ) { - ptr_in[ coord ][ point ] = limit[ coord ] ? - mapdata->ubnd[ coord ] : - mapdata->lbnd[ coord ]; - } - -/* Increment the count of points (i.e. corners). */ - point++; - -/* Now update the limit array to identify the next corner. */ - coord = 0; - do { - -/* Flip the first zero found to become a one. This gives a new - corner. */ - if ( !limit[ coord ] ) { - limit[ coord ] = 1; - break; - -/* However, first flip any previous ones to become zeros and then - examine the next element. We have processed all corners once the - array is entirely filled with ones. */ - } else { - limit[ coord ] = 0; - done = ( ++coord == ncoord ); - } - } while ( !done ); - } while ( !done ); - -/* Once the corners have been processed, loop to consider the centre - of each face. */ - for ( face = 0; face < ( 2 * ncoord ); face++ ) { - -/* First calculate the centroid value for each coordinate. Then set - one of these coordinates to the bound where the face lies. */ - for ( coord = 0; coord < ncoord; coord++ ) { - ptr_in[ coord ][ point ] = 0.5 * ( mapdata->lbnd[ coord ] + - mapdata->ubnd[ coord ] ); - } - ptr_in[ face / 2 ][ point ] = ( face % 2 ) ? - mapdata->lbnd[ face / 2 ] : - mapdata->ubnd[ face / 2 ]; - -/* Increment the count of points. */ - point++; - } - -/* Place a point at the centroid of the constrained coordinate - space. */ - for ( coord = 0; coord < ncoord; coord++ ) { - ptr_in[ coord ][ point ] = 0.5 * ( mapdata->lbnd[ coord ] + - mapdata->ubnd[ coord ] ); - } - icen = point++; - -/* Add a set of positions which are offset slightly from each corner - towards the centroid. */ - for ( ic = 0; ic < ncorner; ic++ ) { - for ( coord = 0; coord < ncoord; coord++ ) { - ptr_in[ coord ][ point ] = 0.999*ptr_in[ coord ][ ic ] + - 0.001*ptr_in[ coord ][ icen ]; - } - point++; - } - -/* Finally, add the origin, if it lies within the constraints. */ - if ( origin ) { - for ( coord = 0; coord < ncoord; coord++ ) { - ptr_in[ coord ][ point ] = 0.0; - } - } - -/* Once all the input coordinates have been calculated, transform them - and obtain a pointer to the resulting coordinate values. */ - pset_out = astTransform( mapdata->mapping, pset_in, mapdata->forward, - NULL ); - ptr_out = astGetPoints( pset_out ); - if ( astOK ) { - -/* Loop through each point and test if any of its transformed - coordinates is bad. */ - for ( point = 0; point < npoint; point++ ) { - bad = 0; - for ( coord = 0; coord < mapdata->nout; coord++ ) { - if ( ptr_out[ coord ][ point ] == AST__BAD ) { - bad = 1; - break; - } - } - -/* If so, we ignore the point. Otherwise, extract the required - coordinate. */ - f = ptr_out[ mapdata->coord ][ point ]; - if ( !bad ) { - -/* Use this to update the lower and upper bounds we are seeking. If - either bound is updated, also store the coordinates of the - corresponding input point. */ - if ( ( *lbnd == AST__BAD ) || ( f < *lbnd ) ) { - *lbnd = f; - for ( coord = 0; coord < ncoord; coord++ ) { - xl[ coord ] = ptr_in[ coord ][ point ]; - } - } - if ( ( *ubnd == AST__BAD ) || ( f > *ubnd ) ) { - *ubnd = f; - for ( coord = 0; coord < ncoord; coord++ ) { - xu[ coord ] = ptr_in[ coord ][ point ]; - } - } - -/* If this point has a bad coord value, it may still be useful if the - required coord value is not bad. In this case, extract the required - coordinate. */ - } else if ( f != AST__BAD ) { - -/* Use this to update secondary lower and upper bounds we are seeking. - These will be returned if no primary values are found via the previous - code block. */ - if ( ( slbnd == AST__BAD ) || ( f < slbnd ) ) { - slbnd = f; - for ( coord = 0; coord < ncoord; coord++ ) { - sxl[ coord ] = ptr_in[ coord ][ point ]; - } - } - if ( ( subnd == AST__BAD ) || ( f > subnd ) ) { - subnd = f; - for ( coord = 0; coord < ncoord; coord++ ) { - sxu[ coord ] = ptr_in[ coord ][ point ]; - } - } - } - } - -/* If no primary values could be found, use secondary values. */ - if( *lbnd == AST__BAD && *ubnd == AST__BAD ) { - *lbnd = slbnd; - *ubnd = subnd; - for ( coord = 0; coord < ncoord; coord++ ) { - xu[ coord ] = sxu[ coord ]; - xl[ coord ] = sxl[ coord ]; - } - result = ( slbnd == AST__BAD || subnd == AST__BAD ); - } - } - } - -/* Free workspace */ - sxl = astFree( sxl ); - sxu = astFree( sxu ); - -/* Annul the temporary PointSets and free the workspace. */ - pset_in = astAnnul( pset_in ); - pset_out = astAnnul( pset_out ); - limit = astFree( limit ); - - return result; -} - -/* -* Name: -* SpreadKernel1 - -* Purpose: -* Rebin a data grid, using a 1-d interpolation kernel. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void SpreadKernel1( AstMapping *this, int ndim_out, -* const int *lbnd_out, const int *ubnd_out, -* const *in, const *in_var, -* double infac, int npoint, const int *offset, -* const double *const *coords, -* void (* kernel)( double, const double [], int, -* double *, int * ), -* int neighb, const double *params, int flags, -* badval, int npix_out, *out, -* *out_var, double *work, int64_t *nused, -* int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This is a set of functions which rebins a rectangular region of an -* input grid of data (and, optionally, associated statistical variance -* values) so as to place them into a new output grid. Each input -* grid point may be mapped on to a position in the output grid in -* an arbitrary way. The input and output grids may have any number -* of dimensions, not necessarily equal. -* -* Where the input positions given do not correspond with a pixel centre -* in the output grid, the each input pixel value is spread out between the -* surrounding output pixels using weights determined by a separable kernel -* which is the product of a 1-dimensional kernel function evaluated along -* each output dimension. A pointer should be supplied to the 1-dimensional -* kernel function to be used. - -* Parameters: -* this -* Pointer to the Mapping being used in the rebinning operation -* (this is only used for constructing error messages). -* ndim_out -* The number of dimensions in the output grid. This should be at -* least one. -* lbnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the first -* pixel in the output grid along each dimension. -* ubnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the last -* pixel in the output grid along each dimension. -* -* Note that "lbnd_out" and "ubnd_out" together define the shape -* and size of the output grid, its extent along a particular -* (i'th) dimension being ubnd_out[i]-lbnd_out[i]+1 (assuming "i" -* is zero-based). They also define the output grid's coordinate -* system, with each pixel being of unit extent along each -* dimension with integral coordinate values at its centre. -* in -* Pointer to the array of data to be rebinned. The numerical type -* of these data should match the function used, as given by the -* suffix on the function name. Note that details of how the input -* grid maps on to this array (e.g. the storage order, number of -* dimensions, etc.) is arbitrary and is specified entirely by means -* of the "offset" array. The "in" array should therefore contain -* sufficient elements to accommodate the "offset" values supplied. -* There is no requirement that all elements of the "in" array -* should be rebinned, and any which are not addressed by the -* contents of the "offset" array will be ignored. -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and type as the "in" array), which -* represent estimates of the statistical variance associated -* with each element of the "in" array. If this second array is -* given (along with the corresponding "out_var" array), then -* estimates of the variance of the resampled data will also be -* returned. It is addressed in exactly the same way (via the -* "offset" array) as the "in" array. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* infac -* A factor by which to multiply the input data values before use. -* npoint -* The number of input points which are to be rebinned. -* offset -* Pointer to an array of integers with "npoint" elements. For -* each input point, this array should contain the zero-based -* offset in the input array(s) (i.e. the "in" and, optionally, -* the "in_var" arrays) from which the value to be rebinned should -* be obtained. -* coords -* An array of pointers to double, with "ndim_out" elements. -* Element "coords[coord]" should point at the first element of -* an array of double (with "npoint" elements) which contains the -* values of coordinate number "coord" for each point being -* rebinned. The value of coordinate number "coord" for -* rebinning point number "point" is therefore given by -* "coords[coord][point]" (assuming both indices are -* zero-based). If any point has a coordinate value of AST__BAD -* associated with it, then the corresponding input data (and -* variance) value will be ignored. -* kernel -* Pointer to the 1-dimensional kernel function to be used. -* neighb -* The number of neighbouring pixels in each dimension (on each -* side of the interpolation position) which are to receive -* contributions from the input pixel value. This value should be at -* least 1. -* params -* Pointer to an optional array of parameter values to be passed -* to the kernel function. If no parameters are required by this -* function, then a NULL pointer may be supplied. -* flags -* The bitwise OR of a set of flag values which control the -* operation of the function. These are chosend from: -* -* - AST__USEBAD: indicates whether there are "bad" (i.e. missing) data -* in the input array(s) which must be recognised. If this flag is not -* set, all input values are treated literally. -* - AST__GENVAR: Indicates that output variances should be generated -* from the spread of values contributing to each output pixel. -* - AST__USEVAR: Indicates that output variances should be generated -* by rebinning the input variances. -* - AST__VARWGT: Indicates that input variances should be used to -* create weights for the input data values. -* -* Only one of AST__GENVAR and AST__USEVAR should be supplied. -* badval -* If the AST__USEBAD flag is set in the "flags" value (above), -* this parameter specifies the value which is used to identify -* bad data and/or variance values in the input array(s). Its -* numerical type must match that of the "in" (and "in_var") -* arrays. The same value will also be used to flag any output -* array elements for which resampled values could not be -* obtained. The output arrays(s) may be flagged with this -* value whether or not the AST__USEBAD flag is set (the -* function return value indicates whether any such values have -* been produced). -* npix_out -* Number of pixels in output array. -* out -* Pointer to an array with the same data type as the "in" -* array, into which the rebinned data will be returned. The -* storage order should be such that the index of the first grid -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order). -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the rebinned values may be returned. This array will only be -* used if the "in_var" array has been given. The values returned -* are estimates of the statistical variance of the corresponding -* values in the "out" array, on the assumption that all errors in -* input grid values (in the "in" array) are statistically independent -* and that their variance estimates (in the "in_var" array) may -* simply be summed (with appropriate weighting factors). -* -* If no output variance estimates are required, a NULL pointer -* should be given. -* work -* A pointer to an array with the same data type and size as the "out" -* array which is used as work space. The values in the supplied -* array are incremented on exit by the sum of the weights used -* with each output pixel. -* nused -* An optional pointer to a int64_t which will be incremented by the -* number of input values pasted into the output array. Ignored if NULL. - -* Notes: -* - There is a separate function for each numerical type of -* gridded data, distinguished by replacing the in the function -* name by the appropriate 1- or 2-character suffix. -*/ -/* Define macros to implement the function for a specific data - type. */ -#define MAKE_SPREAD_KERNEL1(X,Xtype,IntType) \ -static void SpreadKernel1##X( AstMapping *this, int ndim_out, \ - const int *lbnd_out, const int *ubnd_out, \ - const Xtype *in, const Xtype *in_var, \ - double infac, int npoint, const int *offset, \ - const double *const *coords, \ - void (* kernel)( double, const double [], \ - int, double *, int * ), \ - int neighb, const double *params, \ - int flags, Xtype badval, int npix_out, \ - Xtype *out, Xtype *out_var, double *work, \ - int64_t *nused, int *status ) { \ -\ -/* Local Variables: */ \ - astDECLARE_GLOBALS /* Thread-specific data */ \ - Xtype c; \ - Xtype in_val; /* Input pixel value */ \ - double **wtptr; /* Pointer to array of weight pointers */ \ - double **wtptr_last; /* Array of highest weight pointer values */ \ - double *filter; /* Pointer to Nd array of filter values */ \ - double *kp; /* Pointer to next weight values */ \ - double *kstart; /* Pointer to next kernel value */ \ - double *kval; /* Pointer to 1d array of kernel values */ \ - double *wtprod; /* Accumulated weight value array pointer */ \ - double *xfilter; /* Pointer to 1d array of x axis filter values */ \ - double *xnl; /* Pointer to previous ofset array (n-d) */ \ - double pfac; /* Input weight with extra supplied factor */ \ - double pixwt; /* Weight to apply to individual pixel */ \ - double sum; /* Sum of all filter values */ \ - double wgt; /* Weight for input value */ \ - double x; /* x coordinate value */ \ - double xn; /* Coordinate value (n-d) */ \ - double xx; /* X offset */ \ - double xxl; /* Previous X offset */ \ - double xxn; \ - double y; /* y coordinate value */ \ - double yy; /* Y offset */ \ - double yyl; /* Previous Y offset */ \ - int *hi; /* Pointer to array of upper indices */ \ - int *jhi; /* Pointer to array of filter upper indices */ \ - int *jlo; /* Pointer to array of filter lower indices */ \ - int *lo; /* Pointer to array of lower indices */ \ - int *stride; /* Pointer to array of dimension strides */ \ - int bad; /* Output pixel bad? */ \ - int done; /* All pixel indices done? */ \ - int genvar; /* Generate output variances? */ \ - int hi_ix; /* Upper output pixel index (x dimension) */ \ - int hi_iy; /* Upper output pixel index (y dimension) */ \ - int hi_jx; /* Upper filter pixel index (x dimension) */ \ - int hi_jy; /* Upper filter pixel index (y dimension) */ \ - int idim; /* Loop counter for dimensions */ \ - int ii; /* Loop counter for dimensions */ \ - int ix; /* Pixel index in output grid x dimension */ \ - int iy; /* Pixel index in output grid y dimension */ \ - int jjx; /* Reflected pixel index in filter grid x dimension */ \ - int jjy; /* Reflected pixel index in filter grid y dimension */ \ - int jx; /* Pixel index in filter grid x dimension */ \ - int jxn; \ - int jy; /* Pixel index in filter grid y dimension */ \ - int kerror; /* Error signalled by kernel function? */ \ - int lo_ix; /* Lower output pixel index (x dimension) */ \ - int lo_iy; /* Lower output pixel index (y dimension) */ \ - int lo_jx; /* Lower filter pixel index (x dimension) */ \ - int lo_jy; /* Lower filter pixel index (y dimension) */ \ - int nb2; /* The total number of neighbouring pixels */ \ - int nf; /* Number of pixels in filter array */ \ - int nwx; /* Used X width of kernel function (*2) */ \ - int nwy; /* Used Y width of kernel function (*2) */ \ - int off1; /* Input pixel offset due to y index */ \ - int off_in; /* Offset to input pixel */ \ - int off_out; /* Offset to output pixel */ \ - int off_xedge; /* Does filter box overlap array edge on the X axis? */ \ - int off_yedge; /* Does filter box overlap array edge on the Y axis? */ \ - int point; /* Loop counter for output points */ \ - int s; /* Temporary variable for strides */ \ - int usebad; /* Use "bad" input pixel values? */ \ - int usevar; /* Process variance array? */ \ - int varwgt; /* Use input variances as weights? */ \ - int ystride; /* Stride along input grid y dimension */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Get a pointer to a structure holding thread-specific global data values */ \ - astGET_GLOBALS(this); \ -\ -/* Further initialisation. */ \ - kerror = 0; \ - sum = 0.0; \ - bad = 0; \ -\ -/* Find the total number of pixels in the filter used to spread a single \ - input pixel into the output image. */ \ - nb2 = 2*neighb; \ - nf = 1; \ - for ( idim = 0; idim < ndim_out; idim++ ) nf *= nb2; \ -\ -/* Allocate workspace to hold the filter values. */ \ - filter = astMalloc( sizeof( double ) * (size_t) nf ); \ - if ( astOK ) { \ -\ -/* Determine if we are processing bad pixels or variances. */ \ - usebad = flags & AST__USEBAD; \ - usevar = 0; \ - genvar = 0; \ - if( flags & AST__GENVAR ) { \ - genvar = out_var && work; \ - } else if( flags & AST__USEVAR ) { \ - usevar = in_var && out_var; \ - } \ - varwgt = ( flags & AST__VARWGT ) && in_var && work; \ -\ -/* Handle the 1-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - if ( ndim_out == 1 ) { \ -\ -/* Identify eight cases, according to whether bad pixels and/or variances \ - are being processed and/or used. In each case we assign constant values \ - (0 or 1) to the "Usebad", "Usevar" and "Varwgt" flags so that code for \ - handling bad pixels and variances can be eliminated by the compiler's \ - optimisation system when not required. */ \ - if( varwgt ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - KERNEL_1D(X,Xtype,1,1,0,IntType,1) \ - } else if ( genvar ) { \ - KERNEL_1D(X,Xtype,1,0,1,IntType,1) \ - } else { \ - KERNEL_1D(X,Xtype,1,0,0,IntType,1) \ - } \ - } else { \ - if ( usevar ) { \ - KERNEL_1D(X,Xtype,0,1,0,IntType,1) \ - } else if ( genvar ) { \ - KERNEL_1D(X,Xtype,0,0,1,IntType,1) \ - } else { \ - KERNEL_1D(X,Xtype,0,0,0,IntType,1) \ - } \ - } \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - KERNEL_1D(X,Xtype,1,1,0,IntType,0) \ - } else if ( genvar ) { \ - KERNEL_1D(X,Xtype,1,0,1,IntType,0) \ - } else { \ - KERNEL_1D(X,Xtype,1,0,0,IntType,0) \ - } \ - } else { \ - if ( usevar ) { \ - KERNEL_1D(X,Xtype,0,1,0,IntType,0) \ - } else if ( genvar ) { \ - KERNEL_1D(X,Xtype,0,0,1,IntType,0) \ - } else { \ - KERNEL_1D(X,Xtype,0,0,0,IntType,0) \ - } \ - } \ - } \ -\ -/* Exit point on error in kernel function */ \ - Kernel_SError_1d: ; \ -\ -/* Handle the 2-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - } else if ( ndim_out == 2 ) { \ -\ -/* Allocate workspace to hold the X axis filter values. */ \ - xfilter = astMalloc( sizeof( double ) * (size_t) nb2 ); \ -\ -/* Calculate the stride along the y dimension of the output grid. */ \ - ystride = ubnd_out[ 0 ] - lbnd_out[ 0 ] + 1; \ -\ -/* Identify eight cases, according to whether bad pixels and/or variances \ - are being processed and/or used. In each case we assign constant values \ - (0 or 1) to the "Usebad", "Usevar" and "Varwgt" flags so that code for \ - handling bad pixels and variances can be eliminated by the compiler's \ - optimisation system when not required. */ \ - if( varwgt ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - KERNEL_2D(X,Xtype,1,1,0,IntType,1) \ - } else if ( genvar ) { \ - KERNEL_2D(X,Xtype,1,0,1,IntType,1) \ - } else { \ - KERNEL_2D(X,Xtype,1,0,0,IntType,1) \ - } \ - } else { \ - if ( usevar ) { \ - KERNEL_2D(X,Xtype,0,1,0,IntType,1) \ - } else if ( genvar ) { \ - KERNEL_2D(X,Xtype,0,0,1,IntType,1) \ - } else { \ - KERNEL_2D(X,Xtype,0,0,0,IntType,1) \ - } \ - } \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - KERNEL_2D(X,Xtype,1,1,0,IntType,0) \ - } else if ( genvar ) { \ - KERNEL_2D(X,Xtype,1,0,1,IntType,0) \ - } else { \ - KERNEL_2D(X,Xtype,1,0,0,IntType,0) \ - } \ - } else { \ - if ( usevar ) { \ - KERNEL_2D(X,Xtype,0,1,0,IntType,0) \ - } else if ( genvar ) { \ - KERNEL_2D(X,Xtype,0,0,1,IntType,0) \ - } else { \ - KERNEL_2D(X,Xtype,0,0,0,IntType,0) \ - } \ - } \ - } \ -\ -/* Free work space */ \ - xfilter = astFree( xfilter ); \ -\ -/* Exit point on error in kernel function */ \ - Kernel_SError_2d: ; \ -\ -/* Handle other numbers of dimensions. */ \ -/* ----------------------------------- */ \ - } else { \ -\ -/* Allocate workspace. */ \ - hi = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - lo = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - jhi = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - jlo = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - stride = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - xnl = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - kval = astMalloc( sizeof( double ) * (size_t) \ - ( nb2 * ndim_out ) ); \ - wtprod = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - wtptr = astMalloc( sizeof( double * ) * (size_t) ndim_out ); \ - wtptr_last = astMalloc( sizeof( double * ) * (size_t) ndim_out ); \ - if ( astOK ) { \ -\ -/* Calculate the stride along each dimension of the output grid. */ \ - for ( s = 1, idim = 0; idim < ndim_out; idim++ ) { \ - stride[ idim ] = s; \ - s *= ubnd_out[ idim ] - lbnd_out[ idim ] + 1; \ - xnl[ idim ] = AST__BAD; \ - } \ -\ -/* Identify eight cases, according to whether bad pixels and/or variances \ - are being processed and/or used. In each case we assign constant values \ - (0 or 1) to the "Usebad", "Usevar" and "Varwgt" flags so that code for \ - handling bad pixels and variances can be eliminated by the compiler's \ - optimisation system when not required. */ \ - if( varwgt ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - KERNEL_ND(X,Xtype,1,1,0,IntType,1) \ - } else if ( genvar ) { \ - KERNEL_ND(X,Xtype,1,0,1,IntType,1) \ - } else { \ - KERNEL_ND(X,Xtype,1,0,0,IntType,1) \ - } \ - } else { \ - if ( usevar ) { \ - KERNEL_ND(X,Xtype,0,1,0,IntType,1) \ - } else if ( genvar ) { \ - KERNEL_ND(X,Xtype,0,0,1,IntType,1) \ - } else { \ - KERNEL_ND(X,Xtype,0,0,0,IntType,1) \ - } \ - } \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - KERNEL_ND(X,Xtype,1,1,0,IntType,0) \ - } else if ( genvar ) { \ - KERNEL_ND(X,Xtype,1,0,1,IntType,0) \ - } else { \ - KERNEL_ND(X,Xtype,1,0,0,IntType,0) \ - } \ - } else { \ - if ( usevar ) { \ - KERNEL_ND(X,Xtype,0,1,0,IntType,0) \ - } else if ( genvar ) { \ - KERNEL_ND(X,Xtype,0,0,1,IntType,0) \ - } else { \ - KERNEL_ND(X,Xtype,0,0,0,IntType,0) \ - } \ - } \ - } \ -\ -/* Exit point on error in kernel function */ \ - Kernel_SError_Nd: ;\ - } \ -\ -/* Free the workspace. */ \ - hi = astFree( hi ); \ - lo = astFree( lo ); \ - jhi = astFree( jhi ); \ - jlo = astFree( jlo ); \ - stride = astFree( stride ); \ - xnl = astFree( xnl ); \ - kval = astFree( kval ); \ - wtprod = astFree( wtprod ); \ - wtptr = astFree( wtptr ); \ - wtptr_last = astFree( wtptr_last ); \ - } \ - filter = astFree( filter ); \ - }\ -\ -/* If an error occurred in the kernel function, then report a \ - contextual error message. */ \ - if ( kerror ) { \ - astError( astStatus, "astRebin"#X"(%s): Error signalled by " \ - "user-supplied 1-d interpolation kernel.", status, \ - astGetClass( unsimplified_mapping ) ); \ - } \ -\ -} - - - - -#define KERNEL_1D(X,Xtype,Usebad,Usevar,Genvar,IntType,Varwgt) \ -\ -/* We do not yet have a previous filter position. */ \ - xxl = AST__BAD; \ -\ -/* Loop round all input points which are to be rebinned. */ \ - for( point = 0; point < npoint; point++ ) { \ -\ -/* Obtain the input data value which is to be added into the output array. */ \ - off_in = offset[ point ]; \ - in_val = in[ off_in ]; \ -\ -/* If necessary, test if the input data value or variance is bad. If we \ - are using the reciprocal of the input variances as weights, then \ - variance values of zero are also effectively bad (but we can use input \ - variances of zero otherwise). */ \ - if ( Usebad ) { \ - bad = ( in_val == badval ); \ - if ( Varwgt ) { \ - bad = bad || ( in_var[ off_in ] == badval ) \ - || ( in_var[ off_in ] <= 0.0 ); \ - } else if ( Usevar ) { \ - bad = bad || ( in_var[ off_in ] == badval ); \ - } \ - } else { \ - if ( Varwgt ) { \ - bad = ( in_var[ off_in ] <= 0.0 ); \ - } else { \ - bad = 0; \ - } \ - } \ -\ -/* Obtain the x coordinate of the current point and test if it is bad. \ - Also test that the central point falls within the output array. */ \ - x = coords[ 0 ][ point ]; \ - ix = (int) floor( x + 0.5 ); \ - if( ix < lbnd_out[ 0 ] || ix > ubnd_out[ 0 ] ) bad = 1; \ - bad = bad || ( x == AST__BAD ); \ -\ -/* If OK, calculate the lowest and highest indices (in the x \ - dimension) of the region of neighbouring output pixels that will \ - receive contributions from the current input pixel. Constrain these \ - values to lie within the output grid. */ \ - if ( !bad ) { \ - ix = (int) floor( x ) - neighb + 1; \ - lo_ix = MaxI( ix, lbnd_out[ 0 ], status ); \ - hi_ix = MinI( ix + nb2 - 1, ubnd_out[ 0 ], status ); \ -\ -/* Skip to the next input point if the current input point makes no \ - contribution to any output pixel. */ \ - if( lo_ix <= hi_ix ) { \ -\ -/* Increment the number of input pixels pasted into the output array. */ \ - if( nused ) (*nused)++; \ -\ -/* Convert these output indices to the corresponding indices \ - within a box [ 0, 2*neighb ] holding the kernel values. */ \ - lo_jx = lo_ix - ix; \ - hi_jx = hi_ix - ix; \ -\ -/* See if the kernel extends off the edge of the output array. */ \ - nwx = hi_jx - lo_jx + 1; \ - off_xedge = ( nwx < nb2 ); \ -\ -/* Use the kernel function to fill the work array with weights for all output \ - pixels whether or not they fall within the output array. At the same \ - time find the sum of all the factors. */ \ - xx = (double) ix - x; \ - if( xx != xxl || off_xedge ) { \ - sum = 0.0; \ -\ -/* First handle cases where the kernel box overlaps an edge of the output \ - array. In these cases, in order to conserve flux, the bit of the \ - kernel function that is off the edge is reflected back onto the array. \ - Care must be taken since the reflected part of the kernel may itself \ - overlap the opposite edge of the array, in which case the overlapping \ - part must again be reflected back onto the array. This iterative \ - reflection is implemented using a fractional division (%) operator. */ \ - if( off_xedge ) { \ - nwx *= 2; \ - xxl = AST__BAD; \ - for( jx = 0; jx < nb2; jx++ ) filter[ jx ] = 0.0; \ -\ - for ( jx = 0; jx < nb2; jx++ ) { \ - ( *kernel )( xx, params, flags, &pixwt, status ); \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_SError_1d; \ - } \ -\ - jjx = ( jx - lo_jx ) % nwx + lo_jx; \ - if( jjx < lo_jx ) jjx += nwx; \ - if( jjx > hi_jx ) jjx = 2*hi_jx - jjx + 1; \ -\ - filter[ jjx ] += pixwt; \ - sum += pixwt; \ - xx += 1.0; \ - } \ -\ -/* Now handle cases where the kernel box is completely within the output \ - array. */ \ - } else { \ - xxl = xx; \ -\ - for ( jx = 0; jx < nb2; jx++ ) { \ - ( *kernel )( xx, params, flags, &pixwt, status ); \ -\ -/* Check for errors arising in the kernel function. */ \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_SError_1d; \ - } \ -\ -/* Store the kernel factor and increment the sum of all factors. */ \ - filter[ jx ] = pixwt; \ - sum += pixwt; \ - xx += 1.0; \ - } \ -\ - } \ -\ -/* Ensure we do not divide by zero. */ \ - if( sum == 0.0 ) sum = 1.0; \ - } \ -\ -/* If we are using the input data variances as weights, calculate the \ - total weight, incorporating the normalisation factor for the kernel. */ \ - if( Varwgt ) { \ - wgt = 1.0/(sum*in_var[ off_in ]); \ -\ -/* If we are not using input variances as weights, the weight is just the \ - kernel normalisation factor. */ \ - } else { \ - wgt = 1.0/sum; \ - } \ -\ -/* Loop round all the output pixels which receive contributions from this \ - input pixel, calculating the offset of each pixel from the start of the \ - input array. */ \ - off_out = lo_ix - lbnd_out[ 0 ]; \ - for ( jx = lo_jx; jx <= hi_jx; jx++, off_out++ ) { \ -\ -/* Retrieve the weight for the current output pixel and normalise it. */ \ - pixwt = wgt*filter[ jx ]; \ - pfac = pixwt*infac; \ -\ -/* Update the output pixel with the required fraction of the input pixel \ - value. */ \ - c = CONV(IntType,pfac*in_val); \ -\ - if( work ) { \ - out[ off_out ] += c; \ - work[ off_out ] += pixwt; \ - } else {\ - out[ off_out ] += c; \ - } \ -\ - if ( Usevar ) { \ - out_var[ off_out ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && pixwt != 0.0 ) { \ - out_var[ off_out ] += c*c/pixwt; \ - work[ off_out + npix_out ] += pixwt*pixwt; \ - } \ -\ - } \ - } \ - } \ - } - - - - -#define KERNEL_2D(X,Xtype,Usebad,Usevar,Genvar,IntType,Varwgt) \ -\ -/* We do not yet have a previous filter position. */ \ - xxl = AST__BAD; \ - yyl = AST__BAD; \ -\ -/* Loop round all input points which are to be rebinned. */ \ - for( point = 0; point < npoint; point++ ) { \ -\ -/* Obtain the input data value which is to be added into the output array. */ \ - off_in = offset[ point ]; \ - in_val = in[ off_in ]; \ -\ -/* If necessary, test if the input data value or variance is bad. If we \ - are using the reciprocal of the input variances as weights, then \ - variance values of zero are also effectively bad (but we can use input \ - variances of zero otherwise). */ \ - if ( Usebad ) { \ - bad = ( in_val == badval ); \ - if ( Varwgt ) { \ - bad = bad || ( in_var[ off_in ] == badval ) \ - || ( in_var[ off_in ] <= 0.0 ); \ - } else if ( Usevar ) { \ - bad = bad || ( in_var[ off_in ] == badval ); \ - } \ - } else { \ - if ( Varwgt ) { \ - bad = ( in_var[ off_in ] <= 0.0 ); \ - } else { \ - bad = 0; \ - } \ - } \ -\ -/* Obtain the x coordinate of the current point and test if it is bad. \ - Also test that the central point falls within the output array. */ \ - x = coords[ 0 ][ point ]; \ - ix = (int) floor( x + 0.5 ); \ - if( ix < lbnd_out[ 0 ] || ix > ubnd_out[ 0 ] ) bad = 1; \ - bad = bad || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* Similarly obtain and test the y coordinate. */ \ - y = coords[ 1 ][ point ]; \ - iy = (int) floor( y + 0.5 ); \ - if( iy < lbnd_out[ 1 ] || iy > ubnd_out[ 1 ] ) bad = 1; \ - bad = bad || ( y == AST__BAD ); \ - if ( !bad ) { \ -\ -/* If OK, calculate the lowest and highest indices (in each dimension) \ - of the region of neighbouring output pixels which will receive \ - contributions from the current input pixel. Constrain these values \ - to lie within the input grid. */ \ - ix = (int) floor( x ) - neighb + 1; \ - lo_ix = MaxI( ix, lbnd_out[ 0 ], status ); \ - hi_ix = MinI( ix + nb2 - 1, ubnd_out[ 0 ], status ); \ - iy = (int) floor( y ) - neighb + 1; \ - lo_iy = MaxI( iy, lbnd_out[ 1 ], status ); \ - hi_iy = MinI( iy + nb2 - 1, ubnd_out[ 1 ], status ); \ -\ -/* Skip to the next input point if the current input point makes no \ - contribution to any output pixel. */ \ - if( lo_ix <= hi_ix && lo_iy <= hi_iy ) { \ -\ -/* Increment the number of input pixels pasted into the output array. */ \ - if( nused ) (*nused)++; \ -\ -/* Convert these output indices to the corresponding indices \ - within a box [ 0:2*neighb, 0:2*neighb ] holding the kernel values. */ \ - lo_jx = lo_ix - ix; \ - hi_jx = hi_ix - ix; \ - lo_jy = lo_iy - iy; \ - hi_jy = hi_iy - iy; \ -\ -/* See if the kernel extends off the edge of the output array on either \ - axis. */ \ - nwx = hi_jx - lo_jx + 1; \ - nwy = hi_jy - lo_jy + 1; \ - off_xedge = ( nwx < nb2 ); \ - off_yedge = ( nwy < nb2 ); \ -\ -/* Loop to evaluate the kernel function along the y dimension, storing \ - the resulting weight values in all elements of each associated row \ - in the kvar array. The function's argument is the offset of the \ - output pixel (along this dimension) from the central output \ - position. */ \ - yy = (double) iy - y; \ - xx = (double) ix - x; \ - if( xx != xxl || yy != yyl || off_xedge || off_yedge ) { \ -\ -/* First handle cases where the kernel box extends beyond the top or \ - bottom edge of the output array. In these cases, in order to conserve \ - flux, the bit of the kernel function that is off the edge is reflected \ - back onto the array. Care must be taken since the reflected part of the \ - kernel may itself overlap the opposite edge of the array, in which \ - case the overlapping part must again be reflected back onto the \ - array. This iterative reflection is implemented using a fractional \ - division (%) operator. */ \ - if( off_yedge ) { \ - nwy *= 2; \ - xxl = AST__BAD; \ - yyl = AST__BAD; \ - for( jy = 0; jy < nb2*nb2; jy++ ) filter[ jy ] = 0.0; \ -\ - for ( jy = 0; jy < nb2; jy++ ) { \ - ( *kernel )( yy, params, flags, &pixwt, status ); \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_SError_2d; \ - } \ -\ - jjy = ( jy - lo_jy ) % nwy + lo_jy; \ - if( jjy < lo_jy ) jjy += nwy; \ - if( jjy > hi_jy ) jjy = 2*hi_jy - jjy + 1; \ -\ - kp = filter + jjy*nb2; \ - for( jx = 0; jx < nb2; jx++ ) *(kp++) += pixwt; \ - yy += 1.0; \ - } \ -\ -/* Now handles cases where the kernel does not overlap the top or bottom edge \ - of the output array. */ \ - } else { \ - xxl = xx; \ - yyl = yy; \ - kp = filter; \ - for ( jy = 0; jy < nb2; jy++ ) { \ - ( *kernel )( yy, params, flags, &pixwt, status ); \ -\ -/* Check for errors arising in the kernel function. */ \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_SError_2d; \ - } \ -\ -/* Store the kernel factor in all elements of the current row. */ \ - for( jx = 0; jx < nb2; jx++ ) *(kp++) = pixwt; \ -\ -/* Move on to the next row. */ \ - yy += 1.0; \ - } \ - } \ -\ -/* Loop to evaluate the kernel function along the x dimension, multiplying \ - the resulting weight values by the values already stored in the the \ - associated column in the kvar array. The function's argument is the \ - offset of the output pixel (along this dimension) from the central output \ - position. Also form the total data sum in the filter array. First \ - handle cases where the kernel overlaps the left or right edge of the \ - output array. */ \ - sum = 0.0; \ -\ -/* First deal with cases where the kernel extends beyond the left or \ - right edge of the output array. */ \ - if( off_xedge ) { \ - nwx *= 2; \ - xxl = AST__BAD; \ - for( jx = 0; jx < nb2; jx++ ) xfilter[ jx ] = 0.0; \ -\ - for ( jx = 0; jx < nb2; jx++ ) { \ - ( *kernel )( xx, params, flags, &pixwt, status ); \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_SError_2d; \ - } \ -\ - jjx = ( jx - lo_jx ) % nwx + lo_jx; \ - if( jjx < lo_jx ) jjx += nwx; \ - if( jjx > hi_jx ) jjx = 2*hi_jx - jjx + 1; \ -\ - xfilter[ jjx ] += pixwt; \ - xx += 1.0; \ - } \ -\ - for ( jx = 0; jx < nb2; jx++ ) { \ - kp = filter + jx; \ - for( jy = 0; jy < nb2; jy++, kp += nb2 ) { \ - *kp *= xfilter[ jx ]; \ - sum += *kp; \ - } \ - } \ -\ -/* Now deal with cases where the kernel does not extends beyond the left or \ - right edge of the output array. */ \ - } else { \ -\ - for ( jx = 0; jx < nb2; jx++ ) { \ - ( *kernel )( xx, params, flags, &pixwt, status ); \ -\ -/* Check for errors arising in the kernel function. */ \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_SError_2d; \ - } \ -\ -/* Multiply the kernel factor by all elements of the current column. */ \ - kp = filter + jx; \ - for( jy = 0; jy < nb2; jy++, kp += nb2 ) { \ - *kp *= pixwt; \ - sum += *kp; \ - } \ -\ -/* Move on to the next column. */ \ - xx += 1.0; \ - } \ - } \ -\ -/* Ensure we do not divide by zero. */ \ - if( sum == 0.0 ) sum = 1.0; \ - } \ -\ -/* If we are using the input data variances as weights, calculate the \ - total weight, incorporating the normalisation factor for the kernel. */ \ - if( Varwgt ) { \ - wgt = 1.0/(sum*in_var[ off_in ]); \ -\ -/* If we are not using input variances as weights, the weight is just the \ - kernel normalisation factor. */ \ - } else { \ - wgt = 1.0/sum; \ - } \ -\ -/* Find the offset into the output array at the first modified output pixel \ - in the first modified row. */ \ - off1 = lo_ix - lbnd_out[ 0 ] + ystride * ( lo_iy - lbnd_out[ 1 ] ); \ -\ -/* Loop over the affected output rows again. */ \ - for ( jy = lo_jy; jy <= hi_jy; jy++, off1 += ystride ) { \ -\ -/* Save the offset of the first output pixel to be modified in the \ - current row. */ \ - off_out = off1; \ -\ -/* Get a pointer to the first weight value which will be used. */ \ - kp = filter + lo_jx + jy*nb2; \ -\ -/* Loop over the affected output columns again. */ \ - for ( jx = lo_jx; jx <= hi_jx; jx++, off_out++, kp++ ) { \ -\ -/* Calculate the weight for this output pixel and normalise it. */ \ - pixwt = wgt*( *kp ); \ -\ -/* Update the output pixel with the required fraction of the input pixel \ - value. */ \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ -\ - out[ off_out ] += c; \ - if( work ) work[ off_out ] += pixwt; \ -\ - if ( Usevar ) { \ - out_var[ off_out ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && pixwt != 0.0 ) { \ - out_var[ off_out ] += c*c/pixwt; \ - work[ off_out + npix_out ] += pixwt*pixwt; \ - } \ - } \ - } \ - } \ - } \ - } \ - } - - - - -#define KERNEL_ND(X,Xtype,Usebad,Usevar,Genvar,IntType,Varwgt) \ -\ -/* We do not yet have a normalising factor */ \ - sum = AST__BAD; \ -\ -/* Loop round all input points which are to be rebinned. */ \ - for( point = 0; point < npoint; point++ ) { \ -\ -/* Obtain the input data value which is to be added into the output array. */ \ - off_in = offset[ point ]; \ - in_val = in[ off_in ]; \ -\ -/* If necessary, test if the input data value or variance is bad. If we \ - are using the reciprocal of the input variances as weights, then \ - variance values of zero are also effectively bad (but we can use input \ - variances of zero otherwise). */ \ - if ( Usebad ) { \ - bad = ( in_val == badval ); \ - if ( Varwgt ) { \ - bad = bad || ( in_var[ off_in ] == badval ) \ - || ( in_var[ off_in ] <= 0.0 ); \ - } else if ( Usevar ) { \ - bad = bad || ( in_var[ off_in ] == badval ); \ - } \ - } else { \ - if ( Varwgt ) { \ - bad = ( in_var[ off_in ] <= 0.0 ); \ - } else { \ - bad = 0; \ - } \ - } \ -\ -/* Initialise offsets into the output array. Then loop to obtain each \ - coordinate associated with the current output point. Set a flag \ - indicating if any output pixel will be modified. */ \ - if( !bad ) { \ - off_out = 0; \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - xn = coords[ idim ][ point ]; \ -\ -/* Test if the coordinate is bad. If true, the corresponding output pixel \ - value will be bad, so give up on this point. */ \ - ix = (int) floor( xn + 0.5 ); \ - if( ix < lbnd_out[ idim ] || ix > ubnd_out[ idim ] ) bad = 1; \ - bad = bad || ( xn == AST__BAD ); \ - if ( bad ) break; \ -\ -/* Calculate the lowest and highest indices (in the current dimension) \ - of the region of neighbouring output pixels that will be modified. \ - Constrain these values to lie within the output grid. */ \ - ix = (int) floor( xn ) - neighb + 1; \ - lo[ idim ] = MaxI( ix, lbnd_out[ idim ], status ); \ - hi[ idim ] = MinI( ix + nb2 - 1, ubnd_out[ idim ], status ); \ - jlo[ idim ] = lo[ idim ] - ix; \ - jhi[ idim ] = hi[ idim ] - ix; \ -\ -/* Check there is some overlap with the output array on this axis. */ \ - if( lo[ idim ] > hi[ idim ] ) { \ - bad = 1; \ - break; \ - } \ -\ -/* Accumulate the offset (from the start of the output array) of the \ - modified output pixel which has the lowest index in each dimension. */ \ - off_out += stride[ idim ] * ( lo[ idim ] - lbnd_out[ idim ] ); \ -\ -/* Set up an array of pointers to locate the first filter pixel (stored in the \ - "kval" array) for each dimension. */ \ - wtptr[ idim ] = kval + nb2*idim; \ - wtptr_last[ idim ] = wtptr[ idim ] + nb2 - 1; \ -\ -/* See if the kernel extends off the edge of the output array on the current \ - axis. */ \ - lo_jx = jlo[ idim ]; \ - hi_jx = jhi[ idim ]; \ - nwx = hi_jx - lo_jx + 1; \ - off_xedge = ( nwx < nb2 ); \ -\ -/* Loop to evaluate the kernel function along each dimension, storing \ - the resulting values. The function's argument is the offset of the \ - output pixel (along the relevant dimension) from the central output \ - point. */ \ - xxn = (double) ix - xn; \ - if( xxn != xnl[ idim ] || off_xedge ) { \ - sum = AST__BAD; \ -\ -/* First handle cases where the kernel box overlaps an edge of the output \ - array. In these cases, in order to conserve flux, the bit of the \ - kernel function that is off the edge is reflected back onto the array. \ - Care must be taken since the reflected part of the kernel may itself \ - overlap the opposite edge of the array, in which case the overlapping \ - part must again be reflected back onto the array. This iterative \ - reflection is implemented using a fractional division (%) operator. */ \ - if( off_xedge ) { \ - nwx *= 2; \ - xnl[ idim ] = AST__BAD; \ - kp = wtptr[ idim ]; \ - for( jx = 0; jx < nb2; jx++ ) *(kp++) = 0.0; \ -\ - kp = wtptr[ idim ]; \ - for ( jx = 0; jx < nb2; jx++ ) { \ - ( *kernel )( xxn, params, flags, &pixwt, status ); \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_SError_1d; \ - } \ -\ - jjx = ( jx - lo_jx ) % nwx + lo_jx; \ - if( jjx < lo_jx ) jjx += nwx; \ - if( jjx > hi_jx ) jjx = 2*hi_jx - jjx + 1; \ -\ - kp[ jjx ] += pixwt; \ - xxn += 1.0; \ - } \ -\ -/* Now handle cases where the kernel box is completely within the output \ - array. */ \ - } else { \ - xnl[ idim ] = xxn; \ - for ( jxn = 0; jxn < nb2; jxn++ ) { \ - ( *kernel )( xxn, params, flags, wtptr[ idim ] + jxn, status ); \ -\ -/* Check for errors arising in the kernel function. */ \ - if ( !astOK ) { \ - kerror = 1; \ - goto Kernel_SError_Nd; \ - } \ -\ -/* Increment the kernel position. */ \ - xxn += 1.0; \ - } \ - } \ - } \ - } \ -\ -/* If OK... */ \ - if ( !bad ) { \ -\ -/* We only need to modify the normalising factor if the weight values \ - have changed. */ \ - if( sum == AST__BAD ) { \ -\ -/* The kernel value to use for each output pixel is the product of the \ - kernel values for each individual axis at that point. To conserve \ - flux we need to make sure that the sum of these kernel products is unity. \ - So loop over the values now to find the total sum of all kernel values. */ \ - idim = ndim_out - 1; \ - wtprod[ idim ] = 1.0; \ - done = 0; \ - sum = 0; \ - do { \ -\ -/* Each modified output pixel has a weight equal to the product of the kernel \ - weight factors evaluated along each input dimension. However, since \ - we typically only change the index of one dimension at a time, we \ - can avoid forming this product repeatedly by retaining an array of \ - accumulated products for all higher dimensions. We need then only \ - update the lower elements in this array, corresponding to those \ - dimensions whose index has changed. We do this here, "idim" being \ - the index of the most significant dimension to have changed. Note \ - that on the first pass, all dimensions are considered changed, \ - causing this array to be initialised. */ \ - for ( ii = idim; ii >= 1; ii-- ) { \ - wtprod[ ii - 1 ] = wtprod[ ii ] * *( wtptr[ ii ] ); \ - } \ -\ -/* Obtain the weight of each pixel from the accumulated product of \ - weights. Also multiply by the weight for dimension zero, which is not \ - included in the "wtprod" array). Increment the sum of all weights. */ \ - sum += wtprod[ 0 ] * *( wtptr[ 0 ] ); \ -\ -/* Now update the weight value pointers and pixel offset to refer to \ - the next output pixel to be considered. */ \ - idim = 0; \ - do { \ -\ -/* The first input dimension whose weight value pointer has not yet \ - reached its final value has this pointer incremented. */ \ - if ( wtptr[ idim ] != wtptr_last[ idim ] ) { \ - wtptr[ idim ]++; \ - break; \ -\ -/* Any earlier dimensions (which have reached the final pointer value) \ - have this pointer returned to its lowest value. */ \ - } else { \ - wtptr[ idim ] -= nb2 - 1; \ - done = ( ++idim == ndim_out ); \ - } \ - } while ( !done ); \ - } while ( !done ); \ -\ -/* Ensure we do not divide by zero. */ \ - if( sum == 0.0 ) sum = 1.0; \ - } \ -\ -/* Re-initialise the weights pointers to refer to the first and last \ - filter pixels which overlaps the output array. */ \ - kstart = kval; \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - wtptr[ idim ] = kstart + jlo[ idim ]; \ - wtptr_last[ idim ] = kstart + jhi[ idim ]; \ - kstart += nb2; \ - } \ -\ -/* If we are using the input data variances as weights, calculate the \ - total weight, incorporating the normalisation factor for the kernel. */ \ - if( Varwgt ) { \ - wgt = 1.0/(sum*in_var[ off_in ]); \ -\ -/* If we are not using input variances as weights, the weight is just the \ - kernel normalisation factor. */ \ - } else { \ - wgt = 1.0/sum; \ - } \ -\ -/* Increment the number of input pixels pasted into the output array. */ \ - if( nused ) (*nused)++; \ -\ -/* Initialise, and loop over the neighbouring output pixels to divide up \ - the input pixel value between them. */ \ - idim = ndim_out - 1; \ - wtprod[ idim ] = 1.0; \ - done = 0; \ - do { \ -\ -/* Each modified output pixel has a weight equal to the product of the kernel \ - weight factors evaluated along each input dimension. However, since \ - we typically only change the index of one dimension at a time, we \ - can avoid forming this product repeatedly by retaining an array of \ - accumulated products for all higher dimensions. We need then only \ - update the lower elements in this array, corresponding to those \ - dimensions whose index has changed. We do this here, "idim" being \ - the index of the most significant dimension to have changed. Note \ - that on the first pass, all dimensions are considered changed, \ - causing this array to be initialised. */ \ - for ( ii = idim; ii >= 1; ii-- ) { \ - wtprod[ ii - 1 ] = wtprod[ ii ] * *( wtptr[ ii ] ); \ - } \ -\ -/* Obtain the weight of each pixel from the accumulated \ - product of weights. Also multiply by the weight for dimension zero, \ - which is not included in the "wtprod" array). */ \ - pixwt = ( wtprod[ 0 ] * *( wtptr[ 0 ] ) )*wgt; \ -\ -/* Update the output pixel with the required fraction of the input pixel \ - value. */ \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ -\ - if( work ) { \ - out[ off_out ] += c; \ - work[ off_out ] += pixwt; \ - } else {\ - out[ off_out ] += c; \ - } \ -\ - if ( Usevar ) { \ - out_var[ off_out ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && pixwt != 0.0 ) { \ - out_var[ off_out ] += c*c/pixwt; \ - work[ off_out + npix_out ] += pixwt*pixwt; \ - } \ -\ -/* Now update the weight value pointers and pixel offset to refer to \ - the next output pixel to be considered. */ \ - idim = 0; \ - do { \ -\ -/* The first input dimension whose weight value pointer has not yet \ - reached its final value has this pointer incremented, and the pixel \ - offset into the input array is updated accordingly. */ \ - if ( wtptr[ idim ] != wtptr_last[ idim ] ) { \ - wtptr[ idim ]++; \ - off_out += stride[ idim ]; \ - break; \ -\ -/* Any earlier dimensions (which have reached the final pointer value) \ - have this pointer returned to its lowest value. Again, the pixel \ - offset into the input image is updated accordingly. */ \ - } else { \ - wtptr[ idim ] -= ( hi[ idim ] - lo[ idim ] ); \ - off_out -= stride[ idim ] * \ - ( hi[ idim ] - lo[ idim ] ); \ - done = ( ++idim == ndim_out ); \ - } \ - } while ( !done ); \ - } while ( !done ); \ - } \ - } \ - } - - -/* Expand the main macro above to generate a function for each - required signed data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_SPREAD_KERNEL1(LD,long double,0) -#endif -MAKE_SPREAD_KERNEL1(D,double,0) -MAKE_SPREAD_KERNEL1(F,float,0) -MAKE_SPREAD_KERNEL1(I,int,1) -MAKE_SPREAD_KERNEL1(B,signed char,1) -MAKE_SPREAD_KERNEL1(UB,unsigned char,1) - -/* Undefine the macros used above. */ -#undef KERNEL_ND -#undef KERNEL_2D -#undef KERNEL_1D -#undef MAKE_SPREAD_KERNEL1 - -/* -* Name: -* SpreadLinear - -* Purpose: -* Rebin a data grid, using the linear spreading scheme. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void SpreadLinear( int ndim_out, -* const int *lbnd_out, const int *ubnd_out, -* const *in, const *in_var, -* double infac, int npoint, const int *offset, -* const double *const *coords, int flags, -* badval, int npix_out, *out, -* *out_var, double *work, int64_t *nused ) - -* Class Membership: -* Mapping member function. - -* Description: -* This is a set of functions which rebins a rectangular region of an -* input grid of data (and, optionally, associated statistical variance -* values) so as to place them into a new output grid. Each input -* grid point may be mapped on to a position in the output grid in -* an arbitrary way. Where the positions given do not correspond -* with a pixel centre in the input grid, the spreading scheme -* used divides the input pixel value up linearly between the -* nearest neighbouring output pixels in each dimension (there are 2 -* nearest neighbours in 1 dimension, 4 in 2 dimensions, 8 in 3 -* dimensions, etc.). - -* Parameters: -* ndim_out -* The number of dimensions in the output grid. This should be at -* least one. -* lbnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the first -* pixel in the output grid along each dimension. -* ubnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the last -* pixel in the output grid along each dimension. -* -* Note that "lbnd_out" and "ubnd_out" together define the shape -* and size of the output grid, its extent along a particular -* (i'th) dimension being ubnd_out[i]-lbnd_out[i]+1 (assuming "i" -* is zero-based). They also define the output grid's coordinate -* system, with each pixel being of unit extent along each -* dimension with integral coordinate values at its centre. -* in -* Pointer to the array of data to be rebinned. The numerical type -* of these data should match the function used, as given by the -* suffix on the function name. Note that details of how the input -* grid maps on to this array (e.g. the storage order, number of -* dimensions, etc.) is arbitrary and is specified entirely by means -* of the "offset" array. The "in" array should therefore contain -* sufficient elements to accommodate the "offset" values supplied. -* There is no requirement that all elements of the "in" array -* should be rebinned, and any which are not addressed by the -* contents of the "offset" array will be ignored. -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and type as the "in" array), which -* represent estimates of the statistical variance associated -* with each element of the "in" array. If this second array is -* given (along with the corresponding "out_var" array), then -* estimates of the variance of the resampled data will also be -* returned. It is addressed in exactly the same way (via the -* "offset" array) as the "in" array. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* infac -* A factor by which to multiply the input data values before use. -* npoint -* The number of input points which are to be rebinned. -* offset -* Pointer to an array of integers with "npoint" elements. For -* each input point, this array should contain the zero-based -* offset in the input array(s) (i.e. the "in" and, optionally, -* the "in_var" arrays) from which the value to be rebinned should -* be obtained. -* coords -* An array of pointers to double, with "ndim_out" elements. -* Element "coords[coord]" should point at the first element of -* an array of double (with "npoint" elements) which contains the -* values of coordinate number "coord" for each point being -* rebinned. The value of coordinate number "coord" for -* rebinning point number "point" is therefore given by -* "coords[coord][point]" (assuming both indices are -* zero-based). If any point has a coordinate value of AST__BAD -* associated with it, then the corresponding input data (and -* variance) value will be ignored. -* The bitwise OR of a set of flag values which control the -* operation of the function. These are chosend from: -* -* - AST__USEBAD: indicates whether there are "bad" (i.e. missing) data -* in the input array(s) which must be recognised. If this flag is not -* set, all input values are treated literally. -* - AST__GENVAR: Indicates that any input variances are to be -* ignored, and that the output variances should be generated from -* the spread of values contributing to each output pixel. -* badval -* If the AST__USEBAD flag is set in the "flags" value (above), -* this parameter specifies the value which is used to identify -* bad data and/or variance values in the input array(s). Its -* numerical type must match that of the "in" (and "in_var") -* arrays. The same value will also be used to flag any output -* array elements for which resampled values could not be -* obtained. The output arrays(s) may be flagged with this -* value whether or not the AST__USEBAD flag is set (the -* function return value indicates whether any such values have -* been produced). -* npix_out -* Number of pixels in output array. -* out -* Pointer to an array with the same data type as the "in" -* array, into which the rebinned data will be returned. The -* storage order should be such that the index of the first grid -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order). -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the rebinned values may be returned. This array will only be -* used if the "in_var" array has been given. The values returned -* are estimates of the statistical variance of the corresponding -* values in the "out" array, on the assumption that all errors in -* input grid values (in the "in" array) are statistically independent -* and that their variance estimates (in the "in_var" array) may -* simply be summed (with appropriate weighting factors). -* -* If no output variance estimates are required, a NULL pointer -* should be given. -* work -* An optional pointer to a double array with the same size as -* the "out" array. The contents of this array (if supplied) are -* incremented by the accumulated weights assigned to each output pixel. -* If no accumulated weights are required, a NULL pointer should be -* given. -* nused -* An optional pointer to a int64_t which will be incremented by the -* number of input values pasted into the output array. Ignored if NULL. - -* Notes: -* - There is a separate function for each numerical type of -* gridded data, distinguished by replacing the in the function -* name by the appropriate 1- or 2-character suffix. -*/ -/* Define macros to implement the function for a specific data - type. */ -#define MAKE_SPREAD_LINEAR(X,Xtype,IntType) \ -static void SpreadLinear##X( int ndim_out, \ - const int *lbnd_out, const int *ubnd_out, \ - const Xtype *in, const Xtype *in_var, \ - double infac, int npoint, const int *offset, \ - const double *const *coords, int flags, \ - Xtype badval, int npix_out, Xtype *out, \ - Xtype *out_var, double *work, int64_t *nused, \ - int *status ) { \ -\ -/* Local Variables: */ \ - Xtype c; /* Contribution to output value */ \ - Xtype in_val; /* Input value */ \ - double *frac_hi; /* Pointer to array of weights */ \ - double *frac_lo; /* Pointer to array of weights */ \ - double *wt; /* Pointer to array of weights */ \ - double *wtprod; /* Array of accumulated weights pointer */ \ - double *xn_max; /* Pointer to upper limits array (n-d) */ \ - double *xn_min; /* Pointer to lower limits array (n-d) */ \ - double frac_hi_x; /* Pixel weight (x dimension) */ \ - double frac_hi_y; /* Pixel weight (y dimension) */ \ - double frac_lo_x; /* Pixel weight (x dimension) */ \ - double frac_lo_y; /* Pixel weight (y dimension) */ \ - double pfac; /* Scaled pixel weight */ \ - double pixwt; /* Total pixel weight */ \ - double wgt; /* Weight for input value */ \ - double x; /* x coordinate value */ \ - double xmax; /* x upper limit */ \ - double xmin; /* x lower limit */ \ - double xn; /* Coordinate value (n-d) */ \ - double y; /* y coordinate value */ \ - double ymax; /* y upper limit */ \ - double ymin; /* y lower limit */ \ - int *dim; /* Pointer to array of pixel indices */ \ - int *hi; /* Pointer to array of upper indices */ \ - int *lo; /* Pointer to array of lower indices */ \ - int *stride; /* Pointer to array of dimension strides */ \ - int bad; /* Output pixel bad? */ \ - int done; /* All pixel indices done? */ \ - int genvar; /* Generate output variances? */ \ - int hi_x; /* Upper pixel index (x dimension) */ \ - int hi_y; /* Upper pixel index (y dimension) */ \ - int idim; /* Loop counter for dimensions */ \ - int ii; /* Loop counter for weights */ \ - int ixn; /* Pixel index (n-d) */ \ - int lo_x; /* Lower pixel index (x dimension) */ \ - int lo_y; /* Lower pixel index (y dimension) */ \ - int off; /* Total offset to input pixel */ \ - int off_in; /* Offset to input pixel */ \ - int off_lo; /* Offset to "first" input pixel */ \ - int off_out; /* Offset to output pixel */ \ - int point; /* Loop counter for output points */ \ - int s; /* Temporary variable for strides */ \ - int usebad; /* Use "bad" input pixel values? */ \ - int usevar; /* Process variance array? */ \ - int varwgt; /* Use input variances as weights? */ \ - int ystride; /* Stride along input grid y dimension */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Initialise variables to avoid "used of uninitialised variable" \ - messages from dumb compilers. */ \ - bad = 0; \ -\ -/* Determine if we are processing bad pixels or variances. */ \ - usebad = flags & AST__USEBAD; \ - usevar = 0; \ - genvar = 0; \ - if( flags & AST__GENVAR ) { \ - genvar = out_var && work; \ - } else if( flags & AST__USEVAR ) { \ - usevar = in_var && out_var; \ - } \ - varwgt = ( flags & AST__VARWGT ) && in_var && work; \ -\ -/* Handle the 1-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - if ( ndim_out == 1 ) { \ -\ -/* Calculate the coordinate limits of the input grid. */ \ - xmin = (double) lbnd_out[ 0 ] - 0.5; \ - xmax = (double) ubnd_out[ 0 ] + 0.5; \ -\ -/* Identify eight cases, according to whether bad pixels and/or variances \ - are being processed and/or used. In each case we assign constant values \ - (0 or 1) to the "Usebad", "Usevar" and "Varwgt" flags so that code for \ - handling bad pixels and variances can be eliminated by the compiler's \ - optimisation system when not required. */ \ - if( varwgt ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - LINEAR_1D(X,Xtype,1,1,0,IntType,1) \ - } else if ( genvar ) { \ - LINEAR_1D(X,Xtype,1,0,1,IntType,1) \ - } else { \ - LINEAR_1D(X,Xtype,1,0,0,IntType,1) \ - } \ - } else { \ - if ( usevar ) { \ - LINEAR_1D(X,Xtype,0,1,0,IntType,1) \ - } else if ( genvar ) { \ - LINEAR_1D(X,Xtype,0,0,1,IntType,1) \ - } else { \ - LINEAR_1D(X,Xtype,0,0,0,IntType,1) \ - } \ - } \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - LINEAR_1D(X,Xtype,1,1,0,IntType,0) \ - } else if ( genvar ) { \ - LINEAR_1D(X,Xtype,1,0,1,IntType,0) \ - } else { \ - LINEAR_1D(X,Xtype,1,0,0,IntType,0) \ - } \ - } else { \ - if ( usevar ) { \ - LINEAR_1D(X,Xtype,0,1,0,IntType,0) \ - } else if ( genvar ) { \ - LINEAR_1D(X,Xtype,0,0,1,IntType,0) \ - } else { \ - LINEAR_1D(X,Xtype,0,0,0,IntType,0) \ - } \ - } \ - } \ -\ -/* Handle the 2-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - } else if ( ndim_out == 2 ) { \ -\ -/* Calculate the stride along the y dimension of the output grid. */ \ - ystride = ubnd_out[ 0 ] - lbnd_out[ 0 ] + 1; \ -\ -/* Calculate the coordinate limits of the output grid in each \ - dimension. */ \ - xmin = (double) lbnd_out[ 0 ] - 0.5; \ - xmax = (double) ubnd_out[ 0 ] + 0.5; \ - ymin = (double) lbnd_out[ 1 ] - 0.5; \ - ymax = (double) ubnd_out[ 1 ] + 0.5; \ -\ -/* Identify eight cases, according to whether bad pixels and/or variances \ - are being processed and/or used. In each case we assign constant values \ - (0 or 1) to the "Usebad", "Usevar" and "Varwgt" flags so that code for \ - handling bad pixels and variances can be eliminated by the compiler's \ - optimisation system when not required. */ \ - if( varwgt ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - LINEAR_2D(X,Xtype,1,1,0,IntType,1) \ - } else if ( genvar ) { \ - LINEAR_2D(X,Xtype,1,0,1,IntType,1) \ - } else { \ - LINEAR_2D(X,Xtype,1,0,0,IntType,1) \ - } \ - } else { \ - if ( usevar ) { \ - LINEAR_2D(X,Xtype,0,1,0,IntType,1) \ - }else if ( genvar ) { \ - LINEAR_2D(X,Xtype,0,0,1,IntType,1) \ - } else { \ - LINEAR_2D(X,Xtype,0,0,0,IntType,1) \ - } \ - } \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - LINEAR_2D(X,Xtype,1,1,0,IntType,0) \ - } else if ( genvar ) { \ - LINEAR_2D(X,Xtype,1,0,1,IntType,0) \ - } else { \ - LINEAR_2D(X,Xtype,1,0,0,IntType,0) \ - } \ - } else { \ - if ( usevar ) { \ - LINEAR_2D(X,Xtype,0,1,0,IntType,0) \ - }else if ( genvar ) { \ - LINEAR_2D(X,Xtype,0,0,1,IntType,0) \ - } else { \ - LINEAR_2D(X,Xtype,0,0,0,IntType,0) \ - } \ - } \ - } \ -\ -/* Handle other numbers of dimensions. */ \ -/* ----------------------------------- */ \ - } else { \ -\ -/* Allocate workspace. */ \ - dim = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - frac_hi = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - frac_lo = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - hi = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - lo = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - stride = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - wt = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - wtprod = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - xn_max = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - xn_min = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - if ( astOK ) { \ -\ -/* Calculate the stride along each dimension of the output grid. */ \ - for ( s = 1, idim = 0; idim < ndim_out; idim++ ) { \ - stride[ idim ] = s; \ - s *= ubnd_out[ idim ] - lbnd_out[ idim ] + 1; \ -\ -/* Calculate the coordinate limits of the output grid in each \ - dimension. */ \ - xn_min[ idim ] = (double) lbnd_out[ idim ] - 0.5; \ - xn_max[ idim ] = (double) ubnd_out[ idim ] + 0.5; \ - } \ -\ -/* Identify eight cases, according to whether bad pixels and/or variances \ - are being processed and/or used. In each case we assign constant values \ - (0 or 1) to the "Usebad", "Usevar" and "Varwgt" flags so that code for \ - handling bad pixels and variances can be eliminated by the compiler's \ - optimisation system when not required. */ \ - if( varwgt ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - LINEAR_ND(X,Xtype,1,1,0,IntType,1) \ - } else if ( genvar ) { \ - LINEAR_ND(X,Xtype,1,0,1,IntType,1) \ - } else { \ - LINEAR_ND(X,Xtype,1,0,0,IntType,1) \ - } \ - } else { \ - if ( usevar ) { \ - LINEAR_ND(X,Xtype,0,1,0,IntType,1) \ - } else if ( genvar ) { \ - LINEAR_ND(X,Xtype,0,0,1,IntType,1) \ - } else { \ - LINEAR_ND(X,Xtype,0,0,0,IntType,1) \ - } \ - } \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - LINEAR_ND(X,Xtype,1,1,0,IntType,0) \ - } else if ( genvar ) { \ - LINEAR_ND(X,Xtype,1,0,1,IntType,0) \ - } else { \ - LINEAR_ND(X,Xtype,1,0,0,IntType,0) \ - } \ - } else { \ - if ( usevar ) { \ - LINEAR_ND(X,Xtype,0,1,0,IntType,0) \ - } else if ( genvar ) { \ - LINEAR_ND(X,Xtype,0,0,1,IntType,0) \ - } else { \ - LINEAR_ND(X,Xtype,0,0,0,IntType,0) \ - } \ - } \ - } \ - } \ -\ -/* Free the workspace. */ \ - dim = astFree( dim ); \ - frac_hi = astFree( frac_hi ); \ - frac_lo = astFree( frac_lo ); \ - hi = astFree( hi ); \ - lo = astFree( lo ); \ - stride = astFree( stride ); \ - wt = astFree( wt ); \ - wtprod = astFree( wtprod ); \ - xn_max = astFree( xn_max ); \ - xn_min = astFree( xn_min ); \ - } \ -\ -} - - - - - - -#define LINEAR_1D(X,Xtype,Usebad,Usevar,Genvar,IntType,Varwgt) \ -\ -/* Loop round all input points which are to be rebinned. */ \ - for( point = 0; point < npoint; point++ ) { \ -\ -/* Obtain the input data value which is to be added into the output array. */ \ - off_in = offset[ point ]; \ - in_val = in[ off_in ]; \ -\ -/* If necessary, test if the input data value or variance is bad. If we \ - are using the reciprocal of the input variances as weights, then \ - variance values of zero are also effectively bad (but we can use input \ - variances of zero otherwise). */ \ - if ( Usebad ) { \ - bad = ( in_val == badval ); \ - if ( Varwgt ) { \ - bad = bad || ( in_var[ off_in ] == badval ) \ - || ( in_var[ off_in ] <= 0.0 ); \ - } else if ( Usevar ) { \ - bad = bad || ( in_var[ off_in ] == badval ); \ - } \ - } else { \ - if ( Varwgt ) { \ - bad = ( in_var[ off_in ] <= 0.0 ); \ - } else { \ - bad = 0; \ - } \ - } \ -\ -/* Obtain the x coordinate of the current point and test if it lies \ - outside the output grid. Also test if it is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = bad || ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ -\ -/* If OK, obtain the indices along the output grid x dimension of the \ - two adjacent output pixels which will receive contributions from the \ - input pixel. Also obtain the fractional weight to be applied to each of \ - these pixels. */ \ - if ( !bad ) { \ - lo_x = (int) floor( x ); \ - hi_x = lo_x + 1; \ - frac_lo_x = (double) hi_x - x; \ - frac_hi_x = 1.0 - frac_lo_x; \ -\ -/* Increment the number of input pixels pasted into the output array. */ \ - if( nused ) (*nused)++; \ -\ -/* Obtain the offset within the output array of the first pixel to be \ - updated (the one with the smaller index). */ \ - off_lo = lo_x - lbnd_out[ 0 ]; \ -\ -/* If we are using the input data variances as weights, calculate the \ - weight, and scale the fractions of each input pixel by the weight. */ \ - if( Varwgt ) { \ - wgt = 1.0/in_var[ off_in ]; \ - frac_lo_x *= wgt; \ - frac_hi_x *= wgt; \ - } \ -\ -/* For each of the two pixels which may be updated, test if the pixel index \ - lies within the output grid. Where it does, update the output pixel \ - with the required fraction of the input pixel value. */ \ - if ( lo_x >= lbnd_out[ 0 ] ) { \ - pfac = frac_lo_x*infac; \ - c = CONV(IntType,pfac*in_val); \ - out[ off_lo ] += CONV(IntType, c ); \ - if( work ) work[ off_lo ] += frac_lo_x; \ - if ( Usevar ) { \ - out_var[ off_lo ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && frac_lo_x != 0.0 ) { \ - out_var[ off_lo ] += c*c/frac_lo_x; \ - work[ off_lo + npix_out ] += frac_lo_x*frac_lo_x; \ - } \ - } \ - if ( hi_x <= ubnd_out[ 0 ] ) { \ - pfac = frac_hi_x*infac; \ - c = CONV(IntType,pfac*in_val); \ - out[ off_lo + 1 ] += CONV(IntType, c ); \ - if( work ) work[ off_lo + 1 ] += frac_hi_x; \ - if ( Usevar ) { \ - out_var[ off_lo + 1 ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && frac_hi_x != 0.0 ) { \ - out_var[ off_lo + 1 ] += c*c/frac_hi_x; \ - work[ off_lo + 1 + npix_out ] += frac_hi_x*frac_hi_x; \ - } \ - } \ - } \ - } - - - - -#define LINEAR_2D(X,Xtype,Usebad,Usevar,Genvar,IntType,Varwgt) \ -\ -/* Loop round all input points which are to be rebinned. */ \ - for( point = 0; point < npoint; point++ ) { \ -\ -/* Obtain the input data value which is to be added into the output array. */ \ - off_in = offset[ point ]; \ - in_val = in[ off_in ]; \ -\ -/* If necessary, test if the input data value or variance is bad. If we \ - are using the reciprocal of the input variances as weights, then \ - variance values of zero are also effectively bad (but we can use input \ - variances of zero otherwise). */ \ - if ( Usebad ) { \ - bad = ( in_val == badval ); \ - if ( Varwgt ) { \ - bad = bad || ( in_var[ off_in ] == badval ) \ - || ( in_var[ off_in ] <= 0.0 ); \ - } else if ( Usevar ) { \ - bad = bad || ( in_var[ off_in ] == badval ); \ - } \ - } else { \ - if ( Varwgt ) { \ - bad = ( in_var[ off_in ] <= 0.0 ); \ - } else { \ - bad = 0; \ - } \ - } \ -\ -/* Obtain the x coordinate of the current point and test if it lies \ - outside the output grid. Also test if it is bad. */ \ - y = coords[ 1 ][ point ]; \ - bad = bad || ( y < ymin ) || ( y >= ymax ) || ( y == AST__BAD ); \ - if ( !bad ) { \ -\ -/* Similarly obtain and test the y coordinate. */ \ - x = coords[ 0 ][ point ]; \ - bad = bad || ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* Increment the number of input pixels pasted into the output array. */ \ - if( nused ) (*nused)++; \ -\ -/* If OK, obtain the indices along the output grid x dimension of the \ - two adjacent pixels which recieve contributions from the input pixel. \ - Also obtain the fractional weight to be applied to each of \ - these pixels. */ \ - lo_x = (int) floor( x ); \ - hi_x = lo_x + 1; \ - frac_lo_x = (double) hi_x - x; \ - frac_hi_x = 1.0 - frac_lo_x; \ -\ -/* Repeat this process for the y dimension. */ \ - lo_y = (int) floor( y ); \ - hi_y = lo_y + 1; \ - frac_lo_y = (double) hi_y - y; \ - frac_hi_y = 1.0 - frac_lo_y; \ -\ -/* If we are using the input data variances as weights, calculate the \ - weight, and scale the fractions of each input pixel by the weight. \ - Since the product of two fractions is always used to scale the input \ - data values, we use the square root of the reciprocal of the variance \ - as the weight (so that when the product of two fractions is taken, \ - the square roots multiply together to give the required 1/variance \ - weight). */ \ - if( Varwgt ) { \ - wgt = 1.0/sqrt( in_var[ off_in ] ); \ - frac_lo_x *= wgt; \ - frac_hi_x *= wgt; \ - frac_lo_y *= wgt; \ - frac_hi_y *= wgt; \ - } \ -\ -/* Obtain the offset within the output array of the first pixel to be \ - updated (the one with the smaller index along both dimensions). */ \ - off_lo = lo_x - lbnd_out[ 0 ] + ystride * ( lo_y - lbnd_out[ 1 ] ); \ -\ -/* For each of the four pixels which may be updated, test if the pixel indices \ - lie within the output grid. Where they do, update the output pixel \ - with the required fraction of the input pixel value. */ \ - if ( lo_y >= lbnd_out[ 1 ] ) { \ - if ( lo_x >= lbnd_out[ 0 ] ) { \ - pixwt = frac_lo_x * frac_lo_y; \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ - out[ off_lo ] += CONV(IntType, c ); \ - if( work ) work[ off_lo ] += pixwt; \ - if ( Usevar ) { \ - out_var[ off_lo ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && pixwt != 0.0 ) { \ - out_var[ off_lo ] += c*c/pixwt; \ - work[ off_lo + npix_out ] += pixwt*pixwt; \ - } \ - } \ - if ( hi_x <= ubnd_out[ 0 ] ) { \ - off = off_lo + 1; \ - pixwt = frac_hi_x * frac_lo_y; \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ - out[ off ] += CONV(IntType, c ); \ - if( work ) work[ off ] += pixwt; \ - if ( Usevar ) { \ - out_var[ off ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && pixwt != 0.0 ) { \ - out_var[ off ] += c*c/pixwt; \ - work[ off + npix_out ] += pixwt*pixwt; \ - } \ - } \ - } \ - if ( hi_y <= ubnd_out[ 1 ] ) { \ - if ( lo_x >= lbnd_out[ 0 ] ) { \ - off = off_lo + ystride; \ - pixwt = frac_lo_x * frac_hi_y; \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ - out[ off ] += CONV(IntType, c ); \ - if( work ) work[ off ] += pixwt; \ - if ( Usevar ) { \ - out_var[ off ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && pixwt != 0.0 ) { \ - out_var[ off ] += c*c/pixwt; \ - work[ off + npix_out ] += pixwt*pixwt; \ - } \ - } \ - if ( hi_x <= ubnd_out[ 0 ] ) { \ - off = off_lo + ystride + 1; \ - pixwt = frac_hi_x * frac_hi_y; \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ - out[ off ] += CONV(IntType, c ); \ - if( work ) work[ off ] += pixwt; \ - if ( Usevar ) { \ - out_var[ off ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && pixwt != 0.0 ) { \ - out_var[ off ] += c*c/pixwt; \ - work[ off + npix_out ] += pixwt*pixwt; \ - } \ - } \ - } \ - } \ - } \ - } - - -#define LINEAR_ND(X,Xtype,Usebad,Usevar,Genvar,IntType,Varwgt) \ -\ -/* Loop round all input points which are to be rebinned. */ \ - for( point = 0; point < npoint; point++ ) { \ -\ -/* Obtain the input data value which is to be added into the output array. */ \ - off_in = offset[ point ]; \ - in_val = in[ off_in ]; \ -\ -/* If necessary, test if the input data value or variance is bad. If we \ - are using the reciprocal of the input variances as weights, then \ - variance values of zero are also effectively bad (but we can use input \ - variances of zero otherwise). */ \ - if ( Usebad ) { \ - bad = ( in_val == badval ); \ - if ( Varwgt ) { \ - bad = bad || ( in_var[ off_in ] == badval ) \ - || ( in_var[ off_in ] <= 0.0 ); \ - } else if ( Usevar ) { \ - bad = bad || ( in_var[ off_in ] == badval ); \ - } \ - } else { \ - if ( Varwgt ) { \ - bad = ( in_var[ off_in ] <= 0.0 ); \ - } else { \ - bad = 0; \ - } \ - } \ -\ -/* Initialise offsets into the output array. Then loop to obtain each \ - coordinate associated with the current output point. */ \ - if( !bad ) { \ - off_out = 0; \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - xn = coords[ idim ][ point ]; \ -\ -/* Test if the coordinate lies outside the output grid. Also test if \ - it is bad. If either is true, the corresponding output pixel value \ - will be bad, so give up on this point. */ \ - bad = ( xn < xn_min[ idim ] ) || ( xn >= xn_max[ idim ] ) || \ - ( xn == AST__BAD ); \ - if ( bad ) break; \ -\ -/* Obtain the indices along the current dimension of the output grid of \ - the two (usually adjacent) pixels which will be updated. If necessary, \ - however, restrict each index to ensure it does not lie outside the \ - input grid. Also calculate the fractional weight to be given to each \ - pixel in order to divide the input value linearly between them. */ \ - ixn = (int) floor( xn ); \ - lo[ idim ] = MaxI( ixn, lbnd_out[ idim ], status ); \ - hi[ idim ] = MinI( ixn + 1, ubnd_out[ idim ], status ); \ - frac_lo[ idim ] = 1.0 - fabs( xn - (double) lo[ idim ] ); \ - frac_hi[ idim ] = 1.0 - fabs( xn - (double) hi[ idim ] ); \ -\ -/* Store the lower index involved in spreading along each \ - dimension and accumulate the offset from the start of the output \ - array of the pixel which has these indices. */ \ - dim[ idim ] = lo[ idim ]; \ - off_out += stride[ idim ] * ( lo[ idim ] - lbnd_out[ idim ] ); \ -\ -/* Also store the fractional weight associated with the lower pixel \ - along each dimension. */ \ - wt[ idim ] = frac_lo[ idim ]; \ - } \ -\ -/* If we are using the input data variances as weights, calculate the \ - weight, and scale the fractions of each input pixel by the weight. */ \ - if( Varwgt ) { \ - wgt = pow( in_var[ off_in ], -1.0/(double)ndim_out ); \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - frac_lo[ idim ] *= wgt; \ - frac_hi[ idim ] *= wgt; \ - wt[ idim ] = frac_lo[ idim ]; \ - } \ - } \ -\ -/* If OK, increment the number of input pixels pasted into the output array. */ \ - if ( !bad ) { \ - if( nused ) (*nused)++; \ -\ -/* Loop over adjacent output pixels to divide up the input value. */ \ - idim = ndim_out - 1; \ - wtprod[ idim ] = 1.0; \ - done = 0; \ - do { \ -\ -/* Each pixel pixel to be updated has a total weight equal to the product \ - of the weights which account for the displacement of its centre from \ - the required position along each dimension. However, since we typically \ - only change the index of one dimension at a time, we can avoid forming \ - this product repeatedly by retaining an array of accumulated weight \ - products for all higher dimensions. We need then only update the \ - lower elements in this array, corresponding to those dimensions \ - whose index has changed. We do this here, "idim" being the index of \ - the most significant dimension to have changed. Note that on the \ - first pass, all dimensions are considered changed, causing this \ - array to be initialised. */ \ - for ( ii = idim; ii >= 1; ii-- ) { \ - wtprod[ ii - 1 ] = wtprod[ ii ] * wt[ ii ]; \ - } \ -\ -/* Update the relevent output pixel. The pixel weight is formed by including \ - the weight factor for dimension zero, since this is not included in \ - the "wtprod" array. */ \ - pixwt = wtprod[ 0 ] * wt[ 0 ]; \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ - out[ off_out ] += CONV(IntType, c ); \ - if( work ) work[ off_out ] += pixwt; \ - if ( Usevar ) { \ - out_var[ off_out ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ - } else if ( Genvar && pixwt != 0.0 ) { \ - out_var[ off_out ] += c*c/pixwt; \ - work[ off_out + npix_out ] += pixwt*pixwt; \ - } \ -\ -/* Now update the indices, offset and weight factors to refer to the \ - next output pixel to be updated. */ \ - idim = 0; \ - do { \ -\ -/* The first input dimension which still refers to the pixel with the \ - lower of the two possible indices is switched to refer to the other \ - pixel (with the higher index). The offset into the output array and \ - the fractional weight factor for this dimension are also updated \ - accordingly. */ \ - if ( dim[ idim ] != hi[ idim ] ) { \ - dim[ idim ] = hi[ idim ]; \ - off_out += stride[ idim ]; \ - wt[ idim ] = frac_hi[ idim ]; \ - break; \ -\ -/* Any earlier dimensions (referring to the higher index) are switched \ - back to the lower index, if not already there, before going on to \ - consider the next dimension. (This process is the same as \ - incrementing a binary number and propagating overflows up through \ - successive digits, except that dimensions where the "lo" and "hi" \ - values are the same can only take one value.) The process stops at \ - the first attempt to return the final dimension to the lower \ - index. */ \ - } else { \ - if ( dim[ idim ] != lo[ idim ] ) { \ - dim[ idim ] = lo[ idim ]; \ - off_out -= stride[ idim ]; \ - wt[ idim ] = frac_lo[ idim ]; \ - } \ - done = ( ++idim == ndim_out ); \ - } \ - } while ( !done ); \ - } while ( !done ); \ - } \ - } \ - } - -/* Expand the main macro above to generate a function for each - required signed data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_SPREAD_LINEAR(LD,long double,0) -#endif -MAKE_SPREAD_LINEAR(D,double,0) -MAKE_SPREAD_LINEAR(F,float,0) -MAKE_SPREAD_LINEAR(I,int,1) -MAKE_SPREAD_LINEAR(B,signed char,1) -MAKE_SPREAD_LINEAR(UB,unsigned char,1) - -/* Undefine the macros used above. */ -#undef LINEAR_1D -#undef LINEAR_2D -#undef LINEAR_ND -#undef MAKE_SPREAD_LINEAR - -/* -* Name: -* SpreadNearest - -* Purpose: -* Rebin a data grid, using the nearest-pixel spreading scheme. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void SpreadNearest( int ndim_out, const int *lbnd_out, -* const int *ubnd_out, const *in, -* const *in_var, double infac, int npoint, -* const int *offset, const double *const *coords, -* int flags, badval, int npix_out, *out, -* *out_var, double *work, int64_t *nused, -* int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This is a set of functions which rebins a rectangular region of an -* input grid of data (and, optionally, associated statistical variance -* values) so as to place them into a new output grid. Each input -* grid point may be mapped on to a position in the output grid in -* an arbitrary way. Where the positions given do not correspond -* with a pixel centre in the output grid, the spreading scheme -* used is simply to select the nearest pixel (i.e. the one whose -* bounds contain the supplied position). - -* Parameters: -* ndim_out -* The number of dimensions in the output grid. This should be at -* least one. -* lbnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the first -* pixel in the output grid along each dimension. -* ubnd_out -* Pointer to an array of integers, with "ndim_out" elements. -* This should give the coordinates of the centre of the last -* pixel in the output grid along each dimension. -* -* Note that "lbnd_out" and "ubnd_out" together define the shape -* and size of the output grid, its extent along a particular -* (i'th) dimension being ubnd_out[i]-lbnd_out[i]+1 (assuming "i" -* is zero-based). They also define the output grid's coordinate -* system, with each pixel being of unit extent along each -* dimension with integral coordinate values at its centre. -* in -* Pointer to the array of data to be rebinned. The numerical type -* of these data should match the function used, as given by the -* suffix on the function name. Note that details of how the input -* grid maps on to this array (e.g. the storage order, number of -* dimensions, etc.) is arbitrary and is specified entirely by means -* of the "offset" array. The "in" array should therefore contain -* sufficient elements to accommodate the "offset" values supplied. -* There is no requirement that all elements of the "in" array -* should be rebinned, and any which are not addressed by the -* contents of the "offset" array will be ignored. -* in_var -* An optional pointer to a second array of positive numerical -* values (with the same size and type as the "in" array), which -* represent estimates of the statistical variance associated -* with each element of the "in" array. If this second array is -* given (along with the corresponding "out_var" array), then -* estimates of the variance of the resampled data will also be -* returned. It is addressed in exactly the same way (via the -* "offset" array) as the "in" array. -* -* If no variance estimates are required, a NULL pointer should -* be given. -* infac -* A factor by which to multiply the input data values before use. -* npoint -* The number of input points which are to be rebinned. -* offset -* Pointer to an array of integers with "npoint" elements. For -* each input point, this array should contain the zero-based -* offset in the input array(s) (i.e. the "in" and, optionally, -* the "in_var" arrays) from which the value to be rebinned should -* be obtained. -* coords -* An array of pointers to double, with "ndim_out" elements. -* Element "coords[coord]" should point at the first element of -* an array of double (with "npoint" elements) which contains the -* values of coordinate number "coord" for each point being -* rebinned. The value of coordinate number "coord" for -* rebinning point number "point" is therefore given by -* "coords[coord][point]" (assuming both indices are -* zero-based). If any point has a coordinate value of AST__BAD -* associated with it, then the corresponding input data (and -* variance) value will be ignored. -* flags -* The bitwise OR of a set of flag values which control the -* operation of the function. These are chosend from: -* -* - AST__USEBAD: indicates whether there are "bad" (i.e. missing) data -* in the input array(s) which must be recognised. If this flag is not -* set, all input values are treated literally. -* - AST__GENVAR: Indicates that output variances should be generated -* from the spread of values contributing to each output pixel. -* - AST__USEVAR: Indicates that output variances should be generated -* by rebinning the input variances. -* - AST__VARWGT: Indicates that input variances should be used to -* create weights for the input data values. -* -* Only one of AST__GENVAR and AST__USEVAR should be supplied. -* badval -* If the AST__USEBAD flag is set in the "flags" value (above), -* this parameter specifies the value which is used to identify -* bad data and/or variance values in the input array(s). Its -* numerical type must match that of the "in" (and "in_var") -* arrays. The same value will also be used to flag any output -* array elements for which resampled values could not be -* obtained. The output arrays(s) may be flagged with this -* value whether or not the AST__USEBAD flag is set (the -* function return value indicates whether any such values have -* been produced). -* npix_out -* Number of pixels in output array. -* out -* Pointer to an array with the same data type as the "in" -* array, into which the rebinned data will be returned. The -* storage order should be such that the index of the first grid -* dimension varies most rapidly and that of the final dimension -* least rapidly (i.e. Fortran array storage order). -* out_var -* An optional pointer to an array with the same data type and -* size as the "out" array, into which variance estimates for -* the rebinned values may be returned. This array will only be -* used if the "in_var" array has been given. The values returned -* are estimates of the statistical variance of the corresponding -* values in the "out" array, on the assumption that all errors in -* input grid values (in the "in" array) are statistically independent -* and that their variance estimates (in the "in_var" array) may -* simply be summed (with appropriate weighting factors). -* -* If no output variance estimates are required, a NULL pointer -* should be given. -* work -* A pointer to an array with the same data type and size as the "out" -* array which is used as work space. The values in the supplied -* array are incremented on exit by the sum of the weights used -* with each output pixel. -* nused -* An optional pointer to a size_t which will be incremented by the -* number of input values pasted into the output array. Ignored if NULL. - -* Notes: -* - There is a separate function for each numerical type of -* gridded data, distinguished by replacing the in the function -* name by the appropriate 1- or 2-character suffix. -*/ -/* Define a macro to implement the function for a specific data type. */ -#define MAKE_SPREAD_NEAREST(X,Xtype,IntType) \ -static void SpreadNearest##X( int ndim_out, \ - const int *lbnd_out, const int *ubnd_out, \ - const Xtype *in, const Xtype *in_var, \ - double infac, int npoint, const int *offset, \ - const double *const *coords, int flags, \ - Xtype badval, int npix_out, Xtype *out, \ - Xtype *out_var, double *work, int64_t *nused, \ - int *status ) { \ -\ -/* Local Variables: */ \ - Xtype c; /* Contribution to output value */ \ - Xtype in_val; /* Input data value */ \ - double *xn_max; /* Pointer to upper limits array (n-d) */ \ - double *xn_min; /* Pointer to lower limits array (n-d) */ \ - double pfac; /* Input weight with extra supplied factor */ \ - double pixwt; /* Weight for input value */ \ - double x; /* x coordinate value */ \ - double xmax; /* x upper limit */ \ - double xmin; /* x lower limit */ \ - double xn; /* Coordinate value (n-d) */ \ - double y; /* y coordinate value */ \ - double ymax; /* y upper limit */ \ - double ymin; /* y lower limit */ \ - int *stride; /* Pointer to array of dimension strides */ \ - int bad; /* Output pixel bad? */ \ - int genvar; /* Generate output variances? */ \ - int idim; /* Loop counter for dimensions */ \ - int ix; /* Number of pixels offset in x direction */ \ - int ixn; /* Number of pixels offset (n-d) */ \ - int iy; /* Number of pixels offset in y direction */ \ - int off_in; /* Pixel offset into input array */ \ - int off_out; /* Pixel offset into output array */ \ - int point; /* Loop counter for output points */ \ - int s; /* Temporary variable for strides */ \ - int usebad; /* Use "bad" input pixel values? */ \ - int usevar; /* Process variance array? */ \ - int varwgt; /* Use input variances as weights? */ \ - int ystride; /* Stride along input grid y direction */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Determine if we are processing bad pixels or variances. */ \ - usebad = flags & AST__USEBAD; \ - usevar = 0; \ - genvar = 0; \ - if( flags & AST__GENVAR ) { \ - genvar = out_var && work; \ - } else if( flags & AST__USEVAR ) { \ - usevar = in_var && out_var; \ - } \ - varwgt = ( flags & AST__VARWGT ) && in_var && work; \ -\ -/* Handle the 1-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - if ( ndim_out == 1 ) { \ -\ -/* Calculate the coordinate limits of the output array. */ \ - xmin = (double) lbnd_out[ 0 ] - 0.5; \ - xmax = (double) ubnd_out[ 0 ] + 0.5; \ -\ -/* Identify eight cases, according to whether bad pixels and/or variances \ - are being processed and/or used. In each case we assign constant values \ - (0 or 1) to the "Usebad", "Usevar" and "Varwgt" flags so that code for \ - handling bad pixels and variances can be eliminated by the compiler's \ - optimisation system when not required. */ \ - if( varwgt ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - NEAR_1D(X,Xtype,1,1,0,IntType,1) \ - } else if ( genvar ) { \ - NEAR_1D(X,Xtype,1,0,1,IntType,1) \ - } else { \ - NEAR_1D(X,Xtype,1,0,0,IntType,1) \ - } \ - } else { \ - if ( usevar ) { \ - NEAR_1D(X,Xtype,0,1,0,IntType,1) \ - } else if ( genvar ) { \ - NEAR_1D(X,Xtype,0,0,1,IntType,1) \ - } else { \ - NEAR_1D(X,Xtype,0,0,0,IntType,1) \ - } \ - } \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - NEAR_1D(X,Xtype,1,1,0,IntType,0) \ - } else if ( genvar ) { \ - NEAR_1D(X,Xtype,1,0,1,IntType,0) \ - } else { \ - NEAR_1D(X,Xtype,1,0,0,IntType,0) \ - } \ - } else { \ - if ( usevar ) { \ - NEAR_1D(X,Xtype,0,1,0,IntType,0) \ - } else if ( genvar ) { \ - NEAR_1D(X,Xtype,0,0,1,IntType,0) \ - } else { \ - NEAR_1D(X,Xtype,0,0,0,IntType,0) \ - } \ - } \ - } \ -\ -/* Handle the 2-dimensional case optimally. */ \ -/* ---------------------------------------- */ \ - } else if ( ndim_out == 2 ) { \ -\ -/* Calculate the stride along the y dimension of the output grid. */ \ - ystride = ubnd_out[ 0 ] - lbnd_out[ 0 ] + 1; \ -\ -/* Calculate the coordinate limits of the output array in each \ - dimension. */ \ - xmin = (double) lbnd_out[ 0 ] - 0.5; \ - xmax = (double) ubnd_out[ 0 ] + 0.5; \ - ymin = (double) lbnd_out[ 1 ] - 0.5; \ - ymax = (double) ubnd_out[ 1 ] + 0.5; \ -\ -/* Identify eight cases, according to whether bad pixels and/or variances \ - are being processed and/or used. In each case we assign constant values \ - (0 or 1) to the "Usebad", "Usevar" and "Varwgt" flags so that code for \ - handling bad pixels and variances can be eliminated by the compiler's \ - optimisation system when not required. */ \ - if( varwgt ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - NEAR_2D(X,Xtype,1,1,0,IntType,1) \ - } else if ( genvar ) { \ - NEAR_2D(X,Xtype,1,0,1,IntType,1) \ - } else { \ - NEAR_2D(X,Xtype,1,0,0,IntType,1) \ - } \ - } else { \ - if ( usevar ) { \ - NEAR_2D(X,Xtype,0,1,0,IntType,1) \ - } else if ( genvar ) { \ - NEAR_2D(X,Xtype,0,0,1,IntType,1) \ - } else { \ - NEAR_2D(X,Xtype,0,0,0,IntType,1) \ - } \ - } \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - NEAR_2D(X,Xtype,1,1,0,IntType,0) \ - } else if ( genvar ) { \ - NEAR_2D(X,Xtype,1,0,1,IntType,0) \ - } else { \ - NEAR_2D(X,Xtype,1,0,0,IntType,0) \ - } \ - } else { \ - if ( usevar ) { \ - NEAR_2D(X,Xtype,0,1,0,IntType,0) \ - } else if ( genvar ) { \ - NEAR_2D(X,Xtype,0,0,1,IntType,0) \ - } else { \ - NEAR_2D(X,Xtype,0,0,0,IntType,0) \ - } \ - } \ - } \ -\ -/* Handle other numbers of dimensions. */ \ -/* ----------------------------------- */ \ - } else { \ -\ -/* Allocate workspace. */ \ - stride = astMalloc( sizeof( int ) * (size_t) ndim_out ); \ - xn_max = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - xn_min = astMalloc( sizeof( double ) * (size_t) ndim_out ); \ - if ( astOK ) { \ -\ -/* Calculate the stride along each dimension of the output grid. */ \ - for ( s = 1, idim = 0; idim < ndim_out; idim++ ) { \ - stride[ idim ] = s; \ - s *= ubnd_out[ idim ] - lbnd_out[ idim ] + 1; \ -\ -/* Calculate the coordinate limits of the output grid in each \ - dimension. */ \ - xn_min[ idim ] = (double) lbnd_out[ idim ] - 0.5; \ - xn_max[ idim ] = (double) ubnd_out[ idim ] + 0.5; \ - } \ -\ -/* Identify eight cases, according to whether bad pixels and/or variances \ - are being processed and/or used. In each case we assign constant values \ - (0 or 1) to the "Usebad", "Usevar" and "Varwgt" flags so that code for \ - handling bad pixels and variances can be eliminated by the compiler's \ - optimisation system when not required. */ \ - if( varwgt ) { \ - if ( usebad ) { \ - if ( usevar ) { \ - NEAR_ND(X,Xtype,1,1,0,IntType,1) \ - } else if ( genvar ) { \ - NEAR_ND(X,Xtype,1,0,1,IntType,1) \ - } else { \ - NEAR_ND(X,Xtype,1,0,0,IntType,1) \ - } \ - } else { \ - if ( usevar ) { \ - NEAR_ND(X,Xtype,0,1,0,IntType,1) \ - } else if ( genvar ) { \ - NEAR_ND(X,Xtype,0,0,1,IntType,1) \ - } else { \ - NEAR_ND(X,Xtype,0,0,0,IntType,1) \ - } \ - } \ - } else { \ - if ( usebad ) { \ - if ( usevar ) { \ - NEAR_ND(X,Xtype,1,1,0,IntType,0) \ - } else if ( genvar ) { \ - NEAR_ND(X,Xtype,1,0,1,IntType,0) \ - } else { \ - NEAR_ND(X,Xtype,1,0,0,IntType,0) \ - } \ - } else { \ - if ( usevar ) { \ - NEAR_ND(X,Xtype,0,1,0,IntType,0) \ - } else if ( genvar ) { \ - NEAR_ND(X,Xtype,0,0,1,IntType,0) \ - } else { \ - NEAR_ND(X,Xtype,0,0,0,IntType,0) \ - } \ - } \ - } \ - } \ -\ -/* Free the workspace. */ \ - stride = astFree( stride ); \ - xn_max = astFree( xn_max ); \ - xn_min = astFree( xn_min ); \ - } \ -\ -} - - - - - -#define NEAR_1D(X,Xtype,Usebad,Usevar,Genvar,IntType,Varwgt) \ -\ -/* Loop round all input points which are to be rebinned. */ \ - for( point = 0; point < npoint; point++ ) { \ -\ -/* Obtain the input data value which is to be added into the output array. */ \ - off_in = offset[ point ]; \ - in_val = in[ off_in ]; \ -\ -/* If necessary, test if the input data value or variance is bad. If we \ - are using the reciprocal of the input variances as weights, then \ - variance values of zero are also effectively bad (but we can use input \ - variances of zero otherwise). */ \ - if ( Usebad ) { \ - bad = ( in_val == badval ); \ - if ( Varwgt ) { \ - bad = bad || ( in_var[ off_in ] == badval ) \ - || ( in_var[ off_in ] <= 0.0 ); \ - } else if ( Usevar ) { \ - bad = bad || ( in_var[ off_in ] == badval ); \ - } \ - } else { \ - if ( Varwgt ) { \ - bad = ( in_var[ off_in ] <= 0.0 ); \ - } else { \ - bad = 0; \ - } \ - } \ -\ -/* Obtain the output x coordinate corresponding to the centre of the \ - current input pixel and test if it lies outside the output grid, or \ - is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = bad || ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* Increment the number of input pixels pasted into the output array. */ \ - if( nused ) (*nused)++; \ -\ -/* If not, then obtain the offset within the output grid of the pixel \ - which contains the current input point. */ \ - off_out = (int) floor( x + 0.5 ) - lbnd_out[ 0 ]; \ -\ -/* If we are using the input data variances as weights, calculate the \ - weight. */ \ - if( Varwgt ) { \ - pixwt = 1.0/in_var[ off_in ]; \ - } else { \ - pixwt = 1.0; \ - } \ -\ -/* Get the weighted input data value, including any extra scaling. */ \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ -\ -/* Increment the value of this output pixel by the weighted input pixel \ - value, and increment the sum of the weights. */ \ - out[ off_out ] += CONV(IntType, c ); \ - if( work ) work[ off_out ] += pixwt; \ -\ -/* If output variances are being calculated on the basis of the input \ - variances, then we also store the required sum in "out_var". */ \ - if( Usevar ) { \ - out_var[ off_out ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ -\ -/* If output variances are being calculated on the basis of the spread of \ - input values, we need the sum of the squared weighted data values, the \ - sum of the weights (already in the first half of the "work" array), and \ - the sum of the squared weights. */ \ - } else if( Genvar && pixwt != 0.0 ) { \ - out_var[ off_out ] += c*c/pixwt; \ - work[ off_out + npix_out ] += pixwt*pixwt; \ - } \ - } \ - } - - - - - - -#define NEAR_2D(X,Xtype,Usebad,Usevar,Genvar,IntType,Varwgt) \ -\ -/* Loop round all input points which are to be rebinned. */ \ - for( point = 0; point < npoint; point++ ) { \ -\ -/* Obtain the input data value which is to be added into the output array. */ \ - off_in = offset[ point ]; \ - in_val = in[ off_in ]; \ -\ -/* If necessary, test if the input data value or variance is bad. If we \ - are using the reciprocal of the input variances as weights, then \ - variance values of zero are also effectively bad (but we can use input \ - variances of zero otherwise). */ \ - if ( Usebad ) { \ - bad = ( in_val == badval ); \ - if ( Varwgt ) { \ - bad = bad || ( in_var[ off_in ] == badval ) \ - || ( in_var[ off_in ] <= 0.0 ); \ - } else if ( Usevar ) { \ - bad = bad || ( in_var[ off_in ] == badval ); \ - } \ - } else { \ - if ( Varwgt ) { \ - bad = ( in_var[ off_in ] <= 0.0 ); \ - } else { \ - bad = 0; \ - } \ - } \ -\ -/* Obtain the output y coordinate corresponding to the centre of the \ - current input pixel and test if it lies outside the output grid, or \ - is bad. */ \ - y = coords[ 1 ][ point ]; \ - bad = bad || ( y < ymin ) || ( y >= ymax ) || ( y == AST__BAD ); \ - if ( !bad ) { \ -\ -/* Obtain the output x coordinate corresponding to the centre of the \ - current input pixel and test if it lies outside the output grid, or \ - is bad. */ \ - x = coords[ 0 ][ point ]; \ - bad = bad || ( x < xmin ) || ( x >= xmax ) || ( x == AST__BAD ); \ - if ( !bad ) { \ -\ -/* Increment the number of input pixels pasted into the output array. */ \ - if( nused ) (*nused)++; \ -\ -/* Obtain the offsets along each output grid dimension of the output \ - pixel which is to receive the input pixel value. */ \ - ix = (int) floor( x + 0.5 ) - lbnd_out[ 0 ]; \ - iy = (int) floor( y + 0.5 ) - lbnd_out[ 1 ]; \ -\ -/* Calculate this pixel's offset from the start of the output array. */ \ - off_out = ix + ystride * iy; \ -\ -/* If we are using the input data variances as weights, calculate the \ - weight. */ \ - if( Varwgt ) { \ - pixwt = 1.0/in_var[ off_in ]; \ - } else { \ - pixwt = 1.0; \ - } \ -\ -/* Get the weighted input data value, including any extra scaling. */ \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ -\ -/* Increment the value of this output pixel by the weighted input pixel \ - value, and increment the sum of the weights. */ \ - out[ off_out ] += CONV(IntType, c ); \ - if( work ) work[ off_out ] += pixwt; \ -\ -/* If output variances are being calculated on the basis of the input \ - variances, then we also store the required sum in "out_var". */ \ - if( Usevar ) { \ - out_var[ off_out ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ -\ -/* If output variances are being calculated on the basis of the spread of \ - input values, we need the sum of the squared weighted data values, the \ - sum of the weights (already in the first half of the "work" array), and \ - the sum of the squared weights. */ \ - } else if( Genvar && pixwt != 0.0 ) { \ - out_var[ off_out ] += c*c/pixwt; \ - work[ off_out + npix_out ] += pixwt*pixwt; \ - } \ - } \ - } \ - } - - - -#define NEAR_ND(X,Xtype,Usebad,Usevar,Genvar,IntType,Varwgt) \ -\ -/* Loop round all input points which are to be rebinned. */ \ - for( point = 0; point < npoint; point++ ) { \ -\ -/* Obtain the input data value which is to be added into the output array. */ \ - off_in = offset[ point ]; \ - in_val = in[ off_in ]; \ -\ -/* If necessary, test if the input data value or variance is bad. If we \ - are using the reciprocal of the input variances as weights, then \ - variance values of zero are also effectively bad (but we can use input \ - variances of zero otherwise). */ \ - if ( Usebad ) { \ - bad = ( in_val == badval ); \ - if ( Varwgt ) { \ - bad = bad || ( in_var[ off_in ] == badval ) \ - || ( in_var[ off_in ] <= 0.0 ); \ - } else if ( Usevar ) { \ - bad = bad || ( in_var[ off_in ] == badval ); \ - } \ - } else { \ - if ( Varwgt ) { \ - bad = ( in_var[ off_in ] <= 0.0 ); \ - } else { \ - bad = 0; \ - } \ - } \ -\ - if( !bad ) { \ -\ -/* Initialise the offset into the output array. Then loop to obtain \ - each coordinate associated with the current output point. */ \ - off_out = 0; \ - for ( idim = 0; idim < ndim_out; idim++ ) { \ - xn = coords[ idim ][ point ]; \ -\ -/* Test if the coordinate lies outside the output grid, or is bad. If \ - either is true, the corresponding input pixel value will be ignored, \ - so give up on this point. */ \ - bad = ( xn < xn_min[ idim ] ) || ( xn >= xn_max[ idim ] ) || \ - ( xn == AST__BAD ); \ - if ( bad ) { \ - break; \ - } \ -\ -/* Obtain the offset along the current output grid dimension of the \ - output pixel which is to receive the input pixel value. */ \ - ixn = (int) floor( xn + 0.5 ) - lbnd_out[ idim ]; \ -\ -/* Accumulate this pixel's offset from the start of the output array. */ \ - off_out += ixn * stride[ idim ]; \ - } \ -\ - if( !bad ) { \ -\ -/* Increment the number of input pixels pasted into the output array. */ \ - if( nused ) (*nused)++; \ -\ -/* If we are using the input data variances as weights, calculate the \ - weight. */ \ - if( Varwgt ) { \ - pixwt = 1.0/in_var[ off_in ]; \ - } else { \ - pixwt = 1.0; \ - } \ -\ -/* Get the weighted input data value, including any extra scaling. */ \ - pfac = pixwt*infac; \ - c = CONV(IntType,pfac*in_val); \ -\ -/* Increment the value of this output pixel by the weighted input pixel \ - value, and increment the sum of the weights. */ \ - out[ off_out ] += CONV(IntType, c ); \ - if( work ) work[ off_out ] += pixwt; \ -\ -/* If output variances are being calculated on the basis of the input \ - variances, then we also store the required sum in "out_var". */ \ - if( Usevar ) { \ - out_var[ off_out ] += CONV(IntType,in_var[ off_in ]*pfac*pfac); \ -\ -/* If output variances are being calculated on the basis of the spread of \ - input values, we need the sum of the squared weighted data values, the \ - sum of the weights (already in the first half of the "work" array), and \ - the sum of the squared weights. */ \ - } else if( Genvar && pixwt != 0.0 ) { \ - out_var[ off_out ] += c*c/pixwt; \ - work[ off_out + npix_out ] += pixwt*pixwt; \ - } \ - } \ - } \ - } - - - - - - -/* Expand the main macro above to generate a function for each - required signed data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_SPREAD_NEAREST(LD,long double,0) -#endif - -MAKE_SPREAD_NEAREST(D,double,0) -MAKE_SPREAD_NEAREST(F,float,0) -MAKE_SPREAD_NEAREST(I,int,1) -MAKE_SPREAD_NEAREST(B,signed char,1) -MAKE_SPREAD_NEAREST(UB,unsigned char,1) - -/* Undefine the macros used above. */ -#undef NEAR_ND -#undef NEAR_2D -#undef NEAR_1D -#undef MAKE_SPREAD_NEAREST - - - - - - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Mapping member function (over-rides the astTestAttrib protected -* method inherited from the Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Mapping's attributes. - -* Parameters: -* this -* Pointer to the Mapping. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *this; /* Pointer to the Mapping structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Mapping structure. */ - this = (AstMapping *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* Invert. */ -/* ------- */ - if ( !strcmp( attrib, "invert" ) ) { - result = astTestInvert( this ); - -/* Report. */ -/* ------- */ - } else if ( !strcmp( attrib, "report" ) ) { - result = astTestReport( this ); - -/* If the name is not recognised, test if it matches any of the - read-only attributes of this class. If it does, then return - zero. */ - } else if ( !strcmp( attrib, "nin" ) || - !strcmp( attrib, "islinear" ) || - !strcmp( attrib, "issimple" ) || - !strcmp( attrib, "nout" ) || - !strcmp( attrib, "tranforward" ) || - !strcmp( attrib, "traninverse" ) ) { - result = 0; - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static void Tran1( AstMapping *this, int npoint, const double xin[], - int forward, double xout[], int *status ) { -/* -*++ -* Name: -c astTran1 -f AST_TRAN1 - -* Purpose: -* Transform 1-dimensional coordinates. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astTran1( AstMapping *this, int npoint, const double xin[], -c int forward, double xout[] ) -f CALL AST_TRAN1( THIS, NPOINT, XIN, FORWARD, XOUT, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -c This function applies a Mapping to transform the coordinates of -f This routine applies a Mapping to transform the coordinates of -* a set of points in one dimension. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping to be applied. -c npoint -f NPOINT = INTEGER (Given) -* The number of points to be transformed. -c xin -f XIN( NPOINT ) = DOUBLE PRECISION (Given) -c An array of "npoint" coordinate values for the input -f An array of coordinate values for the input -* (untransformed) points. -c forward -f FORWARD = LOGICAL (Given) -c A non-zero value indicates that the Mapping's forward -c coordinate transformation is to be applied, while a zero -c value indicates that the inverse transformation should be -c used. -f A .TRUE. value indicates that the Mapping's forward -f coordinate transformation is to be applied, while a .FALSE. -f value indicates that the inverse transformation should be -f used. -c xout -f XOUT( NPOINT ) = DOUBLE PRECISION (Returned) -c An array (with "npoint" elements) into which the -f An array into which the -* coordinates of the output (transformed) points will be written. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The Mapping supplied must have the value 1 for both its Nin -* and Nout attributes. -*-- -*/ - -/* Local Variables: */ - AstPointSet *in_points; /* Pointer to input PointSet */ - AstPointSet *out_points; /* Pointer to output PointSet */ - const double *in_ptr[ 1 ]; /* Array of input data pointers */ - double *out_ptr[ 1 ]; /* Array of output data pointers */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the Mapping and numbers of points/coordinates. */ - ValidateMapping( this, forward, npoint, 1, 1, "astTran1", status ); - -/* Set up pointers to the input and output coordinate arrays. */ - if ( astOK ) { - in_ptr[ 0 ] = xin; - out_ptr[ 0 ] = xout; - -/* Create PointSets to describe the input and output points. */ - in_points = astPointSet( npoint, 1, "", status ); - out_points = astPointSet( npoint, 1, "", status ); - -/* Associate the data pointers with the PointSets (note we must - explicitly remove the "const" qualifier from the input data here, - although they will not be modified). */ - astSetPoints( in_points, (double **) in_ptr ); - astSetPoints( out_points, out_ptr ); - -/* Apply the required transformation to the coordinates. */ - (void) astTransform( this, in_points, forward, out_points ); - -/* If the Mapping's Report attribute is set, report the effect the - Mapping has had on the coordinates. */ - if ( astGetReport( this ) ) astReportPoints( this, forward, - in_points, out_points ); - -/* Delete the two PointSets. */ - in_points = astDelete( in_points ); - out_points = astDelete( out_points ); - } -} - -static void Tran2( AstMapping *this, - int npoint, const double xin[], const double yin[], - int forward, double xout[], double yout[], int *status ) { -/* -*++ -* Name: -c astTran2 -f AST_TRAN2 - -* Purpose: -* Transform 2-dimensional coordinates. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astTran2( AstMapping *this, -c int npoint, const double xin[], const double yin[], -c int forward, double xout[], double yout[] ) -f CALL AST_TRAN2( THIS, NPOINT, XIN, YIN, FORWARD, XOUT, YOUT, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -c This function applies a Mapping to transform the coordinates of -f This routine applies a Mapping to transform the coordinates of -* a set of points in two dimensions. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping to be applied. -c npoint -f NPOINT = INTEGER (Given) -* The number of points to be transformed. -c xin -f XIN( NPOINT ) = DOUBLE PRECISION (Given) -c An array of "npoint" X-coordinate values for the input -f An array of X-coordinate values for the input -* (untransformed) points. -c yin -f YIN( NPOINT ) = DOUBLE PRECISION (Given) -c An array of "npoint" Y-coordinate values for the input -f An array of Y-coordinate values for the input -* (untransformed) points. -c forward -f FORWARD = LOGICAL (Given) -c A non-zero value indicates that the Mapping's forward -c coordinate transformation is to be applied, while a zero -c value indicates that the inverse transformation should be -c used. -f A .TRUE. value indicates that the Mapping's forward -f coordinate transformation is to be applied, while a .FALSE. -f value indicates that the inverse transformation should be -f used. -c xout -f XOUT( NPOINT ) = DOUBLE PRECISION (Returned) -c An array (with "npoint" elements) into which the -f An array into which the -* X-coordinates of the output (transformed) points will be written. -c yout -f YOUT( NPOINT ) = DOUBLE PRECISION (Returned) -c An array (with "npoint" elements) into which the -f An array into which the -* Y-coordinates of the output (transformed) points will be written. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The Mapping supplied must have the value 2 for both its Nin -* and Nout attributes. -*-- -*/ - -/* Local Variables: */ - AstPointSet *in_points; /* Pointer to input PointSet */ - AstPointSet *out_points; /* Pointer to output PointSet */ - const double *in_ptr[ 2 ]; /* Array of input data pointers */ - double *out_ptr[ 2 ]; /* Array of output data pointers */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the Mapping and the numbers of points/coordinates. */ - ValidateMapping( this, forward, npoint, 2, 2, "astTran2", status ); - -/* Set up pointers to the input and output coordinate arrays. */ - if ( astOK ) { - in_ptr[ 0 ] = xin; - in_ptr[ 1 ] = yin; - out_ptr[ 0 ] = xout; - out_ptr[ 1 ] = yout; - -/* Create PointSets to describe the input and output points. */ - in_points = astPointSet( npoint, 2, "", status ); - out_points = astPointSet( npoint, 2, "", status ); - -/* Associate the data pointers with the PointSets (note we must - explicitly remove the "const" qualifier from the input data here, - although they will not be modified). */ - astSetPoints( in_points, (double **) in_ptr ); - astSetPoints( out_points, out_ptr ); - -/* Apply the required transformation to the coordinates. */ - (void) astTransform( this, in_points, forward, out_points ); - -/* If the Mapping's Report attribute is set, report the effect the - Mapping has had on the coordinates. */ - if ( astGetReport( this ) ) astReportPoints( this, forward, - in_points, out_points ); - -/* Delete the two PointSets. */ - in_points = astDelete( in_points ); - out_points = astDelete( out_points ); - } -} - -static void TranGrid( AstMapping *this, int ncoord_in, const int lbnd[], - const int ubnd[], double tol, int maxpix, int forward, - int ncoord_out, int outdim, double *out, int *status ) { -/* -*++ -* Name: -c astTranGrid -f AST_TRANGRID - -* Purpose: -* Transform a grid of positions - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astTranGrid( AstMapping *this, int ncoord_in, -c const int lbnd[], const int ubnd[], -c double tol, int maxpix, int forward, -c int ncoord_out, int outdim, double *out ); -f CALL AST_TRANGRID( THIS, NCOORD_IN, LBND, UBND, TOL, MAXPIX, -f FORWARD, NCOORD_OUT, OUTDIM, OUT, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -* This function uses the supplied Mapping to transforms a regular square -* grid of points covering a specified box. It attempts to do this -* quickly by first approximating the Mapping with a linear transformation -* applied over the whole region of the input grid which is being used. -* If this proves to be insufficiently accurate, the input region is -* sub-divided into two along its largest dimension and the process is -* repeated within each of the resulting sub-regions. This process of -* sub-division continues until a sufficiently good linear approximation -* is found, or the region to which it is being applied becomes too small -* (in which case the original Mapping is used directly). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping to be applied. -c ncoord_in -f NCOORD_IN = INTEGER (Given) -* The number of coordinates being supplied for each box corner -* (i.e. the number of dimensions of the space in which the -* input points reside). -c lbnd -f LBND( NCOORD_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ncoord_in" elements, -f An array -* containing the coordinates of the centre of the first pixel -* in the input grid along each dimension. -c ubnd -f UBND( NCOORD_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ncoord_in" elements, -f An array -* containing the coordinates of the centre of the last pixel in -* the input grid along each dimension. -* -c Note that "lbnd" and "ubnd" together define the shape -f Note that LBND and UBND together define the shape -* and size of the input grid, its extent along a particular -c (j'th) dimension being ubnd[j]-lbnd[j]+1 (assuming the -c index "j" to be zero-based). They also define -f (J'th) dimension being UBND(J)-LBND(J)+1. They also define -* the input grid's coordinate system, each pixel having unit -* extent along each dimension with integral coordinate values -* at its centre. -c tol -f TOL = DOUBLE PRECISION (Given) -* The maximum tolerable geometrical distortion which may be -* introduced as a result of approximating non-linear Mappings -* by a set of piece-wise linear transformations. This should be -* expressed as a displacement within the output coordinate system -* of the Mapping. -* -* If piece-wise linear approximation is not required, a value -* of zero may be given. This will ensure that the Mapping is -* used without any approximation, but may increase execution -* time. -* -* If the value is too high, discontinuities between the linear -* approximations used in adjacent panel will be higher. If this -* is a problem, reduce the tolerance value used. -c maxpix -f MAXPIX = INTEGER (Given) -* A value which specifies an initial scale size (in input grid points) -* for the adaptive algorithm which approximates non-linear Mappings -* with piece-wise linear transformations. Normally, this should -* be a large value (larger than any dimension of the region of -* the input grid being used). In this case, a first attempt to -* approximate the Mapping by a linear transformation will be -* made over the entire input region. -* -* If a smaller value is used, the input region will first be -c divided into sub-regions whose size does not exceed "maxpix" -f divided into sub-regions whose size does not exceed MAXPIX -* grid points in any dimension. Only at this point will attempts -* at approximation commence. -* -* This value may occasionally be useful in preventing false -* convergence of the adaptive algorithm in cases where the -* Mapping appears approximately linear on large scales, but has -* irregularities (e.g. holes) on smaller scales. A value of, -* say, 50 to 100 grid points can also be employed as a safeguard -* in general-purpose software, since the effect on performance is -* minimal. -* -* If too small a value is given, it will have the effect of -* inhibiting linear approximation altogether (equivalent to -c setting "tol" to zero). Although this may degrade -f setting TOL to zero). Although this may degrade -* performance, accurate results will still be obtained. -c forward -f FORWARD = LOGICAL (Given) -c A non-zero value indicates that the Mapping's forward -c coordinate transformation is to be applied, while a zero -c value indicates that the inverse transformation should be -c used. -f A .TRUE. value indicates that the Mapping's forward -f coordinate transformation is to be applied, while a .FALSE. -f value indicates that the inverse transformation should be -f used. -c ncoord_out -f NCOORD_OUT = INTEGER (Given) -* The number of coordinates being generated by the Mapping for -* each output point (i.e. the number of dimensions of the -* space in which the output points reside). This need not be -c the same as "ncoord_in". -f the same as NCOORD_IN. -c outdim -f OUTDIM = INTEGER (Given) -c The number of elements along the second dimension of the "out" -f The number of elements along the first dimension of the OUT -* array (which will contain the output coordinates). The value -* given should not be less than the number of points in the grid. -c out -f OUT( OUTDIM, NCOORD_OUT ) = DOUBLE PRECISION (Returned) -c The address of the first element in a 2-dimensional array of -c shape "[ncoord_out][outdim]", into -c which the coordinates of the output (transformed) points will -c be written. These will be stored such that the value of -c coordinate number "coord" for output point number "point" -c will be found in element "out[coord][point]". -f An array into which the coordinates of the output -f (transformed) points will be written. These will be stored -f such that the value of coordinate number COORD for output -f point number POINT will be found in element OUT(POINT,COORD). -* The points are ordered such that the first axis of the input -* grid changes most rapidly. For example, if the input grid is -* 2-dimensional and extends from (2,-1) to (3,1), the output -* points will be stored in the order (2,-1), (3, -1), (2,0), (3,0), -* (2,1), (3,1). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - If the forward coordinate transformation is being applied, the -c Mapping supplied must have the value of "ncoord_in" for its Nin -c attribute and the value of "ncoord_out" for its Nout attribute. If -c the inverse transformation is being applied, these values should -c be reversed. -f - If the forward coordinate transformation is being applied, the -f Mapping supplied must have the value of NCOORD_IN for its Nin -f attribute and the value of NCOORD_OUT for its Nout attribute. If -f the inverse transformation is being applied, these values should -f be reversed. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific data */ - AstMapping *simple; /* Pointer to simplified Mapping */ - double **out_ptr; /* Pointer to array of output data pointers */ - int coord; /* Loop counter for coordinates */ - int idim; /* Loop counter for coordinate dimensions */ - int npoint; /* Number of points in the grid */ - int64_t mpix; /* Number of points for testing */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to a structure holding thread-specific global data values */ - astGET_GLOBALS(this); - -/* Calculate the number of points in the grid, and check that the lower and - upper bounds of the input grid are consistent. Report an error if any - pair is not. */ - mpix = 1; - for ( idim = 0; idim < ncoord_in; idim++ ) { - if ( lbnd[ idim ] > ubnd[ idim ] ) { - astError( AST__GBDIN, "astTranGrid(%s): Lower bound of " - "input grid (%d) exceeds corresponding upper bound " - "(%d).", status, astGetClass( this ), - lbnd[ idim ], ubnd[ idim ] ); - astError( AST__GBDIN, "Error in input dimension %d.", status, - idim + 1 ); - break; - } else { - mpix *= ubnd[ idim ] - lbnd[ idim ] + 1; - } - } - -/* Report an error if there are too many pixels in the input. */ - npoint = mpix; - if ( astOK && npoint != mpix ) { - astError( AST__EXSPIX, "astTranGrid(%s): Supplied grid " - "contains too many points (%g): must be fewer than %d.", - status, astGetClass( this ), (double) mpix, INT_MAX/ncoord_out ); - } - - mpix = outdim*ncoord_out; - if ( astOK && (int) mpix != mpix ) { - astError( AST__EXSPIX, "astTranGrid(%s): Supplied output array " - "contains too many pixels (%g): must be fewer than %d.", - status, astGetClass( this ), (double) mpix, INT_MAX ); - } - - -/* Validate the mapping and numbers of points/coordinates. */ - ValidateMapping( this, forward, npoint, ncoord_in, ncoord_out, - "astTranGrid", status ); - -/* Check that the positional accuracy tolerance supplied is valid and - report an error if necessary. */ - if ( astOK && ( tol < 0.0 ) ) { - astError( AST__PATIN, "astTranGrid(%s): Invalid positional " - "accuracy tolerance (%.*g pixel).", status, - astGetClass( this ), AST__DBL_DIG, tol ); - astError( AST__PATIN, "This value should not be less than zero." , status); - } - -/* Check that the initial scale size in grid points supplied is valid and - report an error if necessary. */ - if ( astOK && ( maxpix < 0 ) ) { - astError( AST__SSPIN, "astTranGrid(%s): Invalid initial scale " - "size in grid points (%d).", status, astGetClass( this ), maxpix ); - astError( AST__SSPIN, "This value should not be less than zero." , status); - } - -/* Validate the output array dimension argument. */ - if ( astOK && ( outdim < npoint ) ) { - astError( AST__DIMIN, "astTranGrid(%s): The output array dimension value " - "(%d) is invalid.", status, astGetClass( this ), outdim ); - astError( AST__DIMIN, "This should not be less than the number of " - "grid points being transformed (%d).", status, npoint ); - } - -/* If there are sufficient pixels to make it worthwhile, simplify the - Mapping supplied to improve performance. Otherwise, just clone the - Mapping pointer. Note we save a pointer to the original Mapping so - that lower-level functions can use it if they need to report an error. */ - simple = NULL; - unsimplified_mapping = this; - if ( astOK ) { - if ( npoint > 1024 ) { - simple = astSimplify( this ); - -/* Report an error if the required transformation of this simplified - Mapping is not defined. */ - if( astOK ) { - if ( forward && !astGetTranForward( simple ) ) { - astError( AST__TRNND, "astTranGrid(%s): A forward coordinate " - "transformation is not defined by the %s supplied.", status, - astGetClass( unsimplified_mapping ), - astGetClass( unsimplified_mapping ) ); - } else if ( !forward && !astGetTranInverse( simple ) ) { - astError( AST__TRNND, "astTranGrid(%s): An inverse coordinate " - "transformation is not defined by the %s supplied.", status, - astGetClass( unsimplified_mapping ), - astGetClass( unsimplified_mapping ) ); - } - } - - } else { - simple = astClone( this ); - } - -/* Allocate memory to hold the array of output data pointers. */ - out_ptr = astMalloc( sizeof( double * ) * (size_t) ncoord_out ); - -/* Initialise the output data pointers to point into the "out" array. */ - if ( astOK ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - out_ptr[ coord ] = out + coord * outdim; - } - -/* If required, temporarily invert the Mapping. */ - if( !forward ) astInvert( simple ); - -/* Perform the transformation. */ - TranGridAdaptively( simple, ncoord_in, lbnd, ubnd, lbnd, ubnd, tol, - maxpix, ncoord_out, out_ptr, status ); - -/* If required, uninvert the Mapping. */ - if( !forward ) astInvert( simple ); - - } - -/* Free the memory used for the data pointers. */ - out_ptr = astFree( out_ptr ); - -/* Annul the pointer to the simplified/cloned Mapping. */ - simple = astAnnul( simple ); - } -} - -static void TranGridAdaptively( AstMapping *this, int ncoord_in, - const int *lbnd_in, const int *ubnd_in, - const int lbnd[], const int ubnd[], - double tol, int maxpix, int ncoord_out, - double *out[], int *status ){ -/* -* Name: -* TranGridAdaptively - -* Purpose: -* Transform grid positions adaptively. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void TranGridAdaptively( AstMapping *this, int ncoord_in, -* const int *lbnd_in, const int *ubnd_in, -* const int lbnd[], const int ubnd[], -* double tol, int maxpix, int ncoord_out, -* double *out[] ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function transforms grid points within a specified section of a -* rectangular grid (with any number of dimensions) using the forward -* transformation of the specified Mapping. -* -* This function is very similar to TranGridWithBlocking and TranGridSection -* which lie below it in the calling hierarchy. However, this function -* also attempts to adapt to the Mapping supplied and to sub-divide the -* section being transformed into smaller sections within which a linear -* approximation to the Mapping may be used. This reduces the number of -* Mapping evaluations, thereby improving efficiency particularly when -* complicated Mappings are involved. - -* Parameters: -* this -* Pointer to the Mapping to be applied. The forward transformation -* is used. -* ncoord_in -* The number of coordinates being supplied for each box corner -* (i.e. the number of dimensions of the space in which the -* input points reside). -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the whole input grid, its extent along a -* particular (i'th) dimension being (ubnd_in[i] - lbnd_in[i] + -* 1). They also define the input grid's coordinate system, with -* each pixel being of unit extent along each dimension with -* integral coordinate values at its centre. -* lbnd -* Pointer to an array of integers, with "ncoord_in" elements, -* containing the coordinates of the centre of the first pixel -* in the input grid along each dimension. -* ubnd -* Pointer to an array of integers, with "ncoord_in" elements, -* containing the coordinates of the centre of the last pixel in -* the input grid along each dimension. -* -* Note that "lbnd" and "ubnd" together define the shape -* and size of the input grid, its extent along a particular -* (j'th) dimension being ubnd[j]-lbnd[j]+1 (assuming the -* index "j" to be zero-based). They also define -* the input grid's coordinate system, each pixel having unit -* extent along each dimension with integral coordinate values -* at its centre. -* tol -* The maximum tolerable geometrical distortion which may be -* introduced as a result of approximating non-linear Mappings -* by a set of piece-wise linear transformations. This should be -* expressed as a displacement in pixels in the output grid's -* coordinate system. -* -* If piece-wise linear approximation is not required, a value -* of zero may be given. This will ensure that the Mapping is -* used without any approximation, but may increase execution -* time. -* -* If the value is too high, discontinuities between the linear -* approximations used in adjacent panel will be higher. If this -* is a problem, reduce the tolerance value used. -* maxpix -* A value which specifies an initial scale size (in grid points) -* for the adaptive algorithm which approximates non-linear Mappings -* with piece-wise linear transformations. Normally, this should -* be a large value (larger than any dimension of the region of -* the input grid being used). In this case, a first attempt to -* approximate the Mapping by a linear transformation will be -* made over the entire input region. -* -* If a smaller value is used, the input region will first be -* divided into sub-regions whose size does not exceed "maxpix" -* grid points in any dimension. Only at this point will attempts -* at approximation commence. -* -* This value may occasionally be useful in preventing false -* convergence of the adaptive algorithm in cases where the -* Mapping appears approximately linear on large scales, but has -* irregularities (e.g. holes) on smaller scales. A value of, -* say, 50 to 100 grid points can also be employed as a safeguard -* in general-purpose software, since the effect on performance is -* minimal. -* -* If too small a value is given, it will have the effect of -* inhibiting linear approximation altogether (equivalent to -* setting "tol" to zero). Although this may degrade -* performance, accurate results will still be obtained. -* ncoord_out -* The number of dimensions of the space in which the output points -* reside. -* out -* Pointer to an array with "ndim_out" elements. Element [i] of -* this array is a pointer to an array in which to store the -* transformed values for output axis "i". The points are ordered -* such that the first axis of the input grid changes most rapidly. -* For example, if the input grid is 2-dimensional and extends from -* (2,-1) to (3,1), the output points will be stored in the order -* (2,-1), (3, -1), (2,0), (3,0), (2,1), (3,1). - -*/ - -/* Local Variables: */ - double *flbnd; /* Array holding floating point lower bounds */ - double *fubnd; /* Array holding floating point upper bounds */ - double *linear_fit; /* Pointer to array of fit coefficients */ - int *hi; /* Pointer to array of section upper bounds */ - int *lo; /* Pointer to array of section lower bounds */ - int coord_in; /* Loop counter for input coordinates */ - int dim; /* Output section dimension size */ - int dimx; /* Dimension with maximum section extent */ - int divide; /* Sub-divide the output section? */ - int i; /* Loop count */ - int isLinear; /* Is the transformation linear? */ - int mxdim; /* Largest output section dimension size */ - int npix; /* Number of pixels in output section */ - int npoint; /* Number of points for obtaining a fit */ - int nvertex; /* Number of vertices of output section */ - int toobig; /* Section too big (must sub-divide)? */ - int toosmall; /* Section too small to sub-divide? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Further initialisation. */ - npix = 1; - mxdim = 0; - dimx = 1; - nvertex = 1; - -/* Loop through the input grid dimensions. */ - for ( coord_in = 0; coord_in < ncoord_in; coord_in++ ) { - -/* Obtain the extent in each dimension of the input section which is - to be rebinned, and calculate the total number of pixels it contains. */ - dim = ubnd[ coord_in ] - lbnd[ coord_in ] + 1; - npix *= dim; - -/* Find the maximum dimension size of this input section and note which - dimension has this size. */ - if ( dim > mxdim ) { - mxdim = dim; - dimx = coord_in; - } - -/* Calculate how many vertices the output section has. */ - nvertex *= 2; - } - -/* Calculate how many sample points will be needed (by the astLinearApprox - function) to obtain a linear fit to the Mapping's forward transformation. */ - npoint = 1 + 4 * ncoord_in + 2 * nvertex; - -/* If the number of pixels in the input section is not at least 4 - times this number, we will probably not save significant time by - attempting to obtain a linear fit, so note that the input section - is too small. */ - toosmall = ( npix < ( 4 * npoint ) ); - -/* Note if the maximum dimension of the input section exceeds the - user-supplied scale factor. */ - toobig = ( maxpix < mxdim ); - -/* Assume the Mapping is significantly non-linear before deciding - whether to sub-divide the output section. */ - linear_fit = NULL; - -/* If the output section is too small to be worth obtaining a linear - fit, or if the accuracy tolerance is zero, we will not - sub-divide. This means that the Mapping will be used to transform - each pixel's coordinates and no linear approximation will be - used. */ - if ( toosmall || ( tol == 0.0 ) ) { - divide = 0; - -/* Otherwise, if the largest input section dimension exceeds the - scale length given, we will sub-divide. This offers the possibility - of obtaining a linear approximation to the Mapping over a reduced - range of input coordinates (which will be handled by a recursive - invocation of this function). */ - } else if ( toobig ) { - divide = 1; - -/* If neither of the above apply, then attempt to fit a linear - approximation to the forward transformation of the Mapping over - the range of coordinates covered by the input section. We need to - temporarily copy the integer bounds into floating point arrays to - use astLinearApprox. */ - } else { - -/* Allocate memory for floating point bounds and for the coefficient array */ - flbnd = astMalloc( sizeof( double )*(size_t) ncoord_in ); - fubnd = astMalloc( sizeof( double )*(size_t) ncoord_in ); - linear_fit = astMalloc( sizeof( double )* - (size_t) ( ncoord_out*( ncoord_in + 1 ) ) ); - if( astOK ) { - -/* Copy the bounds into these arrays, and change them so that they refer - to the lower and upper edges of the cell rather than the centre. This - is essential if one of the axes is spanned by a single cell, since - otherwise the upper and lower bounds would be identical. */ - for( i = 0; i < ncoord_in; i++ ) { - flbnd[ i ] = (double) lbnd[ i ] - 0.5; - fubnd[ i ] = (double) ubnd[ i ] + 0.5; - } - -/* Get the linear approximation to the forward transformation. */ - isLinear = astLinearApprox( this, flbnd, fubnd, tol, linear_fit ); - -/* Free the coeff array if the inverse transformation is not linear. */ - if( !isLinear ) linear_fit = astFree( linear_fit ); - - } else { - linear_fit = astFree( linear_fit ); - } - -/* Free resources */ - flbnd = astFree( flbnd ); - fubnd = astFree( fubnd ); - -/* If a linear fit was obtained, we will use it and therefore do not - wish to sub-divide further. Otherwise, we sub-divide in the hope - that this may result in a linear fit next time. */ - divide = !linear_fit; - } - -/* If no sub-division is required, perform the transformation (in a - memory-efficient manner, since the section we are rebinning might - still be very large). This will use the linear fit, if obtained - above. */ - if ( astOK ) { - if ( !divide ) { - TranGridWithBlocking( this, linear_fit, ncoord_in, lbnd_in, - ubnd_in, lbnd, ubnd, ncoord_out, out, status ); - -/* Otherwise, allocate workspace to perform the sub-division. */ - } else { - lo = astMalloc( sizeof( int ) * (size_t) ncoord_in ); - hi = astMalloc( sizeof( int ) * (size_t) ncoord_in ); - if ( astOK ) { - -/* Initialise the bounds of a new input section to match the original - input section. */ - for ( coord_in = 0; coord_in < ncoord_in; coord_in++ ) { - lo[ coord_in ] = lbnd[ coord_in ]; - hi[ coord_in ] = ubnd[ coord_in ]; - } - -/* Replace the upper bound of the section's largest dimension with the - mid-point of the section along this dimension, rounded downwards. */ - hi[ dimx ] = - (int) floor( 0.5 * (double) ( lbnd[ dimx ] + ubnd[ dimx ] ) ); - -/* Rebin the resulting smaller section using a recursive invocation - of this function. */ - TranGridAdaptively( this, ncoord_in, lbnd_in, ubnd_in, lo, hi, - tol, maxpix, ncoord_out, out, status ); - -/* Now set up a second section which covers the remaining half of the - original input section. */ - lo[ dimx ] = hi[ dimx ] + 1; - hi[ dimx ] = ubnd[ dimx ]; - -/* If this section contains pixels, transform it in the same way. */ - if ( lo[ dimx ] <= hi[ dimx ] ) { - TranGridAdaptively( this, ncoord_in, lbnd_in, ubnd_in, lo, hi, - tol, maxpix, ncoord_out, out, status ); - } - } - -/* Free the workspace. */ - lo = astFree( lo ); - hi = astFree( hi ); - } - } - -/* If coefficients for a linear fit were obtained, then free the space - they occupy. */ - if ( linear_fit ) linear_fit = astFree( linear_fit ); -} - -static void TranGridSection( AstMapping *this, const double *linear_fit, - int ndim_in, const int *lbnd_in, - const int *ubnd_in, const int *lbnd, - const int *ubnd, int ndim_out, double *out[], int *status ){ -/* -* Name: -* TranGridSection - -* Purpose: -* Transform grid points within a section of a rectangular grid. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void TranGridSection( AstMapping *this, const double *linear_fit, -* int ndim_in, const int *lbnd_in, -* const int *ubnd_in, const int *lbnd, -* const int *ubnd, int ndim_out, double *out[] ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function transforms grid points within a specified section of a -* rectangular grid (with any number of dimensions) using a specified -* Mapping or, alternatively, a linear approximation fitted to the -* Mapping's forward transformation. - -* Parameters: -* this -* Pointer to a Mapping, whose forward transformation may be -* used to transform the coordinates of points in the input -* grid. -* -* The number of input coordintes for the Mapping (Nin -* attribute) should match the value of "ndim_in" (below), and -* the number of output coordinates (Nout attribute) should -* match the value of "ndim_out". -* linear_fit -* Pointer to an optional array of double which contains the -* coefficients of a linear fit which approximates the above -* Mapping's forward coordinate transformation. If this is -* supplied, it will be used in preference to the above Mapping -* when transforming coordinates. This may be used to enhance -* performance in cases where evaluation of the Mapping's -* forward transformation is expensive. If no linear fit is -* available, a NULL pointer should be supplied. -* -* The way in which the fit coefficients are stored in this -* array and the number of array elements are as defined by the -* astLinearApprox function. -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input data grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input data grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the input data grid, its extent along a -* particular (i'th) dimension being (ubnd_in[i] - lbnd_in[i] + -* 1). They also define the input grid's coordinate system, with -* each pixel being of unit extent along each dimension with -* integral coordinate values at its centre. -* lbnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the first pixel in the -* section of the input data grid which is to be rebinned. -* ubnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the last pixel in the -* section of the input data grid which is to be rebinned. -* -* Note that "lbnd" and "ubnd" define the shape and position of -* the section of the input grid which is to be rebinned. This section -* should lie wholly within the extent of the input grid (as defined -* by the "lbnd_out" and "ubnd_out" arrays). Regions of the input -* grid lying outside this section will be ignored. -* ndim_out -* The number of dimensions in the output grid. This should be -* at least one. -* out -* Pointer to an array with "ndim_out" elements. Element [i] of -* this array is a pointer to an array in which to store the -* transformed values for output axis "i". The points are ordered -* such that the first axis of the input grid changes most rapidly. -* For example, if the input grid is 2-dimensional and extends from -* (2,-1) to (3,1), the output points will be stored in the order -* (2,-1), (3, -1), (2,0), (3,0), (2,1), (3,1). - -* Notes: -* - This function does not take steps to limit memory usage if the -* grids supplied are large. To resample large grids in a more -* memory-efficient way, the ResampleWithBlocking function should -* be used. -*/ - -/* Local Variables: */ - AstPointSet *pset_in; /* Input PointSet for transformation */ - AstPointSet *pset_out; /* Output PointSet for transformation */ - const double *grad; /* Pointer to gradient matrix of linear fit */ - const double *zero; /* Pointer to zero point array of fit */ - double **ptr_in; /* Pointer to input PointSet coordinates */ - double **ptr_out; /* Pointer to output PointSet coordinates */ - double *accum; /* Pointer to array of accumulated sums */ - double x1; /* Interim x coordinate value */ - double xx1; /* Initial x coordinate value */ - double y1; /* Interim y coordinate value */ - double yy1; /* Initial y coordinate value */ - int *dim; /* Pointer to array of output pixel indices */ - int *offset; /* Pointer to array of output pixel offsets */ - int *stride; /* Pointer to array of output grid strides */ - int coord_in; /* Loop counter for input dimensions */ - int coord_out; /* Loop counter for output dimensions */ - int done; /* All pixel indices done? */ - int i1; /* Interim offset into "accum" array */ - int i2; /* Final offset into "accum" array */ - int idim; /* Loop counter for dimensions */ - int ix; /* Loop counter for output x coordinate */ - int iy; /* Loop counter for output y coordinate */ - int npoint; /* Number of output points (pixels) */ - int off1; /* Interim pixel offset into output array */ - int off2; /* Interim pixel offset into output array */ - int off; /* Final pixel offset into output array */ - int point; /* Counter for output points (pixels ) */ - int s; /* Temporary variable for strides */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Further initialisation. */ - pset_in = NULL; - ptr_in = NULL; - ptr_out = NULL; - pset_out = NULL; - -/* Calculate the number of input points, as given by the product of - the input grid dimensions. */ - for ( npoint = 1, coord_in = 0; coord_in < ndim_in; coord_in++ ) { - npoint *= ubnd[ coord_in ] - lbnd[ coord_in ] + 1; - } - -/* Allocate workspace. */ - offset = astMalloc( sizeof( int ) * (size_t) npoint ); - stride = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - -/* Calculate the stride for each input grid dimension. */ - off = 0; - s = 1; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - stride[ coord_in ] = s; - s *= ubnd_in[ coord_in ] - lbnd_in[ coord_in ] + 1; - } - -/* A linear fit to the Mapping is available. */ -/* ========================================= */ - if ( linear_fit ) { - -/* If a linear fit to the Mapping has been provided, then obtain - pointers to the array of gradients and zero-points comprising the - fit. */ - grad = linear_fit + ndim_out; - zero = linear_fit; - -/* Create a PointSet to hold the output grid coordinates and obtain an - array of pointers to its coordinate data. */ - pset_out = astPointSet( npoint, ndim_out, "", status ); - ptr_out = astGetPoints( pset_out ); - if ( astOK ) { - -/* Initialise the count of input points. */ - point = 0; - -/* Handle the 1-dimensional case optimally. */ -/* ---------------------------------------- */ - if ( ( ndim_in == 1 ) && ( ndim_out == 1 ) ) { - -/* Loop through the pixels of the input grid and transform their x - coordinates into the output grid's coordinate system using the - linear fit supplied. Store the results in the PointSet created - above. */ - off = lbnd[ 0 ] - lbnd_in[ 0 ]; - xx1 = zero[ 0 ] + grad[ 0 ] * (double) lbnd[ 0 ]; - - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_out[ 0 ][ point ] = xx1; - xx1 += grad[ 0 ]; - offset[ point++ ] = off++; - } - -/* Handle the 2-dimensional case optimally. */ -/* ---------------------------------------- */ - } else if ( ( ndim_in == 2 ) && ( ndim_out == 2 ) ) { - -/* Loop through the range of y coordinates in the input grid and - calculate interim values of the output coordinates using the linear - fit supplied. */ - x1 = zero[ 0 ] + grad[ 1 ] * (double) ( lbnd[ 1 ] - 1 ); - y1 = zero[ 1 ] + grad[ 3 ] * (double) ( lbnd[ 1 ] - 1 ); - off1 = stride[ 1 ] * ( lbnd[ 1 ] - lbnd_in[ 1 ] - 1 ) - lbnd_in[ 0 ]; - for ( iy = lbnd[ 1 ]; iy <= ubnd[ 1 ]; iy++ ) { - x1 += grad[ 1 ]; - y1 += grad[ 3 ]; - -/* Also calculate an interim pixel offset into the input array. */ - off1 += stride[ 1 ]; - -/* Now loop through the range of input x coordinates and calculate - the final values of the input coordinates, storing the results in - the PointSet created above. */ - xx1 = x1 + grad[ 0 ] * (double) lbnd[ 0 ]; - yy1 = y1 + grad[ 2 ] * (double) lbnd[ 0 ]; - off = off1 + lbnd[ 0 ]; - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_out[ 0 ][ point ] = xx1; - xx1 += grad[ 0 ]; - ptr_out[ 1 ][ point ] = yy1; - yy1 += grad[ 2 ]; - -/* Also calculate final pixel offsets into the input array. */ - offset[ point++ ] = off++; - } - } - -/* Handle other numbers of dimensions. */ -/* ----------------------------------- */ - } else { - -/* Allocate workspace. */ - accum = astMalloc( sizeof( double ) * - (size_t) ( ndim_in * ndim_out ) ); - dim = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - -/* Initialise an array of pixel indices for the input grid which refer to the - first pixel which we will rebin. Also calculate the offset of this pixel - within the input array. */ - off = 0; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - dim[ coord_in ] = lbnd[ coord_in ]; - off += stride[ coord_in ] * - ( dim[ coord_in ] - lbnd_in[ coord_in ] ); - } - -/* To calculate each output grid coordinate we must perform a matrix - multiply on the input grid coordinates (using the gradient matrix) - and then add the zero points. However, since we will usually only - be altering one input coordinate at a time (the least - significant), we can avoid the full matrix multiply by accumulating - partial sums for the most significant input coordinates and only - altering those sums which need to change each time. The zero points - never change, so we first fill the "most significant" end of the - "accum" array with these. */ - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - accum[ ( coord_out + 1 ) * ndim_in - 1 ] = - zero[ coord_out ]; - } - coord_in = ndim_in - 1; - -/* Now loop to process each input pixel. */ - for ( done = 0; !done; point++ ) { - -/* To generate the output coordinate that corresponds to the current - input pixel, we work down from the most significant dimension - whose index has changed since the previous pixel we considered - (given by "coord_in"). For each affected dimension, we accumulate - in "accum" the matrix sum (including the zero point) for that - dimension and all higher input dimensions. We must accumulate a - separate set of sums for each output coordinate we wish to - produce. (Note that for the first pixel we process, all dimensions - are considered "changed", so we start by initialising the whole - "accum" array.) */ - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - i1 = coord_out * ndim_in; - for ( idim = coord_in; idim >= 1; idim-- ) { - i2 = i1 + idim; - accum[ i2 - 1 ] = accum[ i2 ] + - dim[ idim ] * grad[ i2 ]; - } - -/* The output coordinate for each dimension is given by the accumulated - sum for input dimension zero (giving the sum over all input - dimensions). We do not store this in the "accum" array, but assign - the result directly to the coordinate array of the PointSet created - earlier. */ - ptr_out[ coord_out ][ point ] = accum[ i1 ] + - dim[ 0 ] * grad[ i1 ]; - } - -/* Store the offset of the current pixel in the input array. */ - offset[ point ] = off; - -/* Now update the array of pixel indices to refer to the next input pixel. */ - coord_in = 0; - do { - -/* The least significant index which currently has less than its maximum - value is incremented by one. The offset into the input array is updated - accordingly. */ - if ( dim[ coord_in ] < ubnd[ coord_in ] ) { - dim[ coord_in ]++; - off += stride[ coord_in ]; - break; - -/* Any less significant indices which have reached their maximum value - are returned to their minimum value and the input pixel offset is - decremented appropriately. */ - } else { - dim[ coord_in ] = lbnd[ coord_in ]; - off -= stride[ coord_in ] * - ( ubnd[ coord_in ] - lbnd[ coord_in ] ); - -/* All the output pixels have been processed once the most significant - pixel index has been returned to its minimum value. */ - done = ( ++coord_in == ndim_in ); - } - } while ( !done ); - } - } - -/* Free the workspace. */ - accum = astFree( accum ); - dim = astFree( dim ); - } - } - -/* No linear fit to the Mapping is available. */ -/* ========================================== */ - } else { - -/* Create a PointSet to hold the coordinates of the input pixels and - obtain a pointer to its coordinate data. */ - pset_in = astPointSet( npoint, ndim_in, "", status ); - ptr_in = astGetPoints( pset_in ); - if ( astOK ) { - -/* Initialise the count of input points. */ - point = 0; - -/* Handle the 1-dimensional case optimally. */ -/* ---------------------------------------- */ - if ( ndim_in == 1 && ndim_out == 1 ) { - -/* Loop through the required range of input x coordinates, assigning - the coordinate values to the PointSet created above. Also store a - pixel offset into the input array. */ - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_in[ 0 ][ point ] = (double) ix; - offset[ point++ ] = ix - lbnd_in[ 0 ]; - } - -/* Handle the 2-dimensional case optimally. */ -/* ---------------------------------------- */ - } else if ( ndim_in == 2 && ndim_out == 2 ) { - -/* Loop through the required range of input y coordinates, - calculating an interim pixel offset into the input array. */ - off1 = stride[ 1 ] * ( lbnd[ 1 ] - lbnd_in[ 1 ] - 1 ) - - lbnd_in[ 0 ]; - for ( iy = lbnd[ 1 ]; iy <= ubnd[ 1 ]; iy++ ) { - off1 += stride[ 1 ]; - -/* Loop through the required range of input x coordinates, assigning - the coordinate values to the PointSet created above. Also store a - final pixel offset into the input array. */ - off2 = off1 + lbnd[ 0 ]; - for ( ix = lbnd[ 0 ]; ix <= ubnd[ 0 ]; ix++ ) { - ptr_in[ 0 ][ point ] = (double) ix; - ptr_in[ 1 ][ point ] = (double) iy; - offset[ point++ ] = off2++; - } - } - -/* Handle other numbers of dimensions. */ -/* ----------------------------------- */ - } else { - -/* Allocate workspace. */ - dim = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - -/* Initialise an array of pixel indices for the input grid which - refer to the first pixel to be rebinned. Also calculate the offset - of this pixel within the input array. */ - off = 0; - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - dim[ coord_in ] = lbnd[ coord_in ]; - off += stride[ coord_in ] * - ( dim[ coord_in ] - lbnd_in[ coord_in ] ); - } - -/* Loop to generate the coordinates of each input pixel. */ - for ( done = 0; !done; point++ ) { - -/* Copy each pixel's coordinates into the PointSet created above. */ - for ( coord_in = 0; coord_in < ndim_in; coord_in++ ) { - ptr_in[ coord_in ][ point ] = - (double) dim[ coord_in ]; - } - -/* Store the offset of the pixel in the input array. */ - offset[ point ] = off; - -/* Now update the array of pixel indices to refer to the next input - pixel. */ - coord_in = 0; - do { - -/* The least significant index which currently has less than its - maximum value is incremented by one. The offset into the input - array is updated accordingly. */ - if ( dim[ coord_in ] < ubnd[ coord_in ] ) { - dim[ coord_in ]++; - off += stride[ coord_in ]; - break; - -/* Any less significant indices which have reached their maximum value - are returned to their minimum value and the input pixel offset is - decremented appropriately. */ - } else { - dim[ coord_in ] = lbnd[ coord_in ]; - off -= stride[ coord_in ] * - ( ubnd[ coord_in ] - lbnd[ coord_in ] ); - -/* All the input pixels have been processed once the most significant - pixel index has been returned to its minimum value. */ - done = ( ++coord_in == ndim_in ); - } - } while ( !done ); - } - } - -/* Free the workspace. */ - dim = astFree( dim ); - } - -/* When all the input pixel coordinates have been generated, use the - Mapping's forward transformation to generate the output coordinates - from them. Obtain an array of pointers to the resulting coordinate - data. */ - pset_out = astTransform( this, pset_in, 1, NULL ); - ptr_out = astGetPoints( pset_out ); - } - -/* Annul the PointSet containing the input coordinates. */ - pset_in = astAnnul( pset_in ); - } - } - -/* Copy the output coordinates into the correct positions within the - supplied "out" array. */ -/* ================================================================= */ - if( astOK ) { - for ( coord_out = 0; coord_out < ndim_out; coord_out++ ) { - for ( point = 0; point < npoint; point++ ) { - out[ coord_out ][ offset[ point ] ] = ptr_out[ coord_out ][ point ]; - } - } - } - -/* Annul the PointSet used to hold output coordinates. */ - pset_out = astAnnul( pset_out ); - -/* Free the workspace. */ - offset = astFree( offset ); - stride = astFree( stride ); -} - -static void TranGridWithBlocking( AstMapping *this, const double *linear_fit, - int ndim_in, const int *lbnd_in, - const int *ubnd_in, const int *lbnd, - const int *ubnd, int ndim_out, - double *out[], int *status ){ -/* -* Name: -* TranGridWithBlocking - -* Purpose: -* Transforms positions in a section of a grid in a memory-efficient way. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void TranGridWithBlocking( AstMapping *this, const double *linear_fit, -* int ndim_in, const int *lbnd_in, -* const int *ubnd_in, const int *lbnd, -* const int *ubnd, int ndim_out, -* double *out[], int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function transforms positions within a specified section of a -* rectangular grid (with any number of dimensions) using the forward -* transformation of the supplied Mapping. -* -* This function is very similar to TranGridSection, except that in -* order to limit memory usage and to ensure locality of reference, -* it divides the input grid up into "blocks" which have a limited -* extent along each input dimension. Each block, which will not -* contain more than a pre-determined maximum number of pixels, is -* then passed to TranGridSection for transformation. - -* Parameters: -* this -* Pointer to a Mapping, whose forward transformation may be -* used to transform the coordinates of pixels in the input -* grid into associated positions in the output grid. -* -* The number of input coordintes for the Mapping (Nin -* attribute) should match the value of "ndim_in" (below), and -* the number of output coordinates (Nout attribute) should -* match the value of "ndim_out". -* linear_fit -* Pointer to an optional array of double which contains the -* coefficients of a linear fit which approximates the above -* Mapping's forward coordinate transformation. If this is -* supplied, it will be used in preference to the above Mapping -* when transforming coordinates. This may be used to enhance -* performance in cases where evaluation of the Mapping's -* forward transformation is expensive. If no linear fit is -* available, a NULL pointer should be supplied. -* -* The way in which the fit coefficients are stored in this -* array and the number of array elements are as defined by the -* astLinearApprox function. -* ndim_in -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the first -* pixel in the input grid along each dimension. -* ubnd_in -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the centre of the last -* pixel in the input grid along each dimension. -* -* Note that "lbnd_in" and "ubnd_in" together define the shape -* and size of the whole input grid, its extent along a -* particular (i'th) dimension being (ubnd_in[i] - lbnd_in[i] + -* 1). They also define the input grid's coordinate system, with -* each pixel being of unit extent along each dimension with -* integral coordinate values at its centre. -* lbnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the first pixel in the -* section of the input data grid which is to be transformed. -* ubnd -* Pointer to an array of integers, with "ndim_in" elements. -* This should give the coordinates of the last pixel in the -* section of the input data grid which is to be transformed. -* -* Note that "lbnd" and "ubnd" define the shape and position of the -* section of the input grid which is to be transformed. -* ndim_out -* The number of dimensions in the output grid. This should be -* at least one. -* out -* Pointer to an array with "ndim_out" elements. Element [i] of -* this array is a pointer to an array in which to store the -* transformed values for output axis "i". The points are ordered -* such that the first axis of the input grid changes most rapidly. -* For example, if the input grid is 2-dimensional and extends from -* (2,-1) to (3,1), the output points will be stored in the order -* (2,-1), (3, -1), (2,0), (3,0), (2,1), (3,1). -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Constants: */ - const int mxpix = 2 * 1024; /* Maximum number of pixels in a block (this - relatively small number seems to give best - performance) */ - -/* Local Variables: */ - int *dim_block; /* Pointer to array of block dimensions */ - int *lbnd_block; /* Pointer to block lower bound array */ - int *ubnd_block; /* Pointer to block upper bound array */ - int dim; /* Dimension size */ - int done; /* All blocks rebinned? */ - int hilim; /* Upper limit on maximum block dimension */ - int idim; /* Loop counter for dimensions */ - int lolim; /* Lower limit on maximum block dimension */ - int mxdim_block; /* Maximum block dimension */ - int npix; /* Number of pixels in block */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Allocate workspace. */ - lbnd_block = astMalloc( sizeof( int ) * (size_t) ndim_in ); - ubnd_block = astMalloc( sizeof( int ) * (size_t) ndim_in ); - dim_block = astMalloc( sizeof( int ) * (size_t) ndim_in ); - if ( astOK ) { - -/* Find the optimum block size. */ -/* ---------------------------- */ -/* We first need to find the maximum extent which a block of input - pixels may have in each dimension. We determine this by taking the - input grid extent in each dimension and then limiting the maximum - dimension size until the resulting number of pixels is sufficiently - small. This approach allows the block shape to approximate (or - match) the input grid shape when appropriate. */ - -/* First loop to calculate the total number of input pixels and the - maximum input dimension size. */ - npix = 1; - mxdim_block = 0; - for ( idim = 0; idim < ndim_in; idim++ ) { - dim = ubnd[ idim ] - lbnd[ idim ] + 1; - npix *= dim; - if ( mxdim_block < dim ) mxdim_block = dim; - } - -/* If the number of input pixels is too large for a single block, we - perform iterations to determine the optimum upper limit on a - block's dimension size. Initialise the limits on this result. */ - if ( npix > mxpix ) { - lolim = 1; - hilim = mxdim_block; - -/* Loop to perform a binary chop, searching for the best result until - the lower and upper limits on the result converge to adjacent - values. */ - while ( ( hilim - lolim ) > 1 ) { - -/* Form a new estimate from the mid-point of the previous limits. */ - mxdim_block = ( hilim + lolim ) / 2; - -/* See how many pixels a block contains if its maximum dimension is - limited to this new value. */ - for ( npix = 1, idim = 0; idim < ndim_in; idim++ ) { - dim = ubnd[ idim ] - lbnd[ idim ] + 1; - npix *= ( dim < mxdim_block ) ? dim : mxdim_block; - } - -/* Update the appropriate limit, according to whether the number of - pixels is too large or too small. */ - *( ( npix <= mxpix ) ? &lolim : &hilim ) = mxdim_block; - } - -/* When iterations have converged, obtain the maximum limit on the - dimension size of a block which results in no more than the maximum - allowed number of pixels per block. However, ensure that all block - dimensions are at least 2. */ - mxdim_block = lolim; - } - if ( mxdim_block < 2 ) mxdim_block = 2; - -/* Calculate the block dimensions by applying this limit to the output - grid dimensions. */ - for ( idim = 0; idim < ndim_in; idim++ ) { - dim = ubnd[ idim ] - lbnd[ idim ] + 1; - dim_block[ idim ] = ( dim < mxdim_block ) ? dim : mxdim_block; - -/* Also initialise the lower and upper bounds of the first block of - output grid pixels to be rebinned, ensuring that this does not - extend outside the grid itself. */ - lbnd_block[ idim ] = lbnd[ idim ]; - ubnd_block[ idim ] = MinI( lbnd[ idim ] + dim_block[ idim ] - 1, - ubnd[ idim ], status ); - } - -/* Transform each block of input grid positions. */ -/* --------------------------------------------- */ -/* Loop to generate the extent of each block of input grid positions and to - transform them. */ - done = 0; - while ( !done && astOK ) { - -/* Rebin the current block, accumulating the sum of bad pixels produced. */ - TranGridSection( this, linear_fit, ndim_in, lbnd_in, ubnd_in, - lbnd_block, ubnd_block, ndim_out, out, status ); - -/* Update the block extent to identify the next block of input pixels. */ - idim = 0; - do { - -/* We find the least significant dimension where the upper bound of - the block has not yet reached the upper bound of the region of the - input grid which we are rebinning. The block's position is then - incremented by one block extent along this dimension, checking that - the resulting extent does not go outside the region being rebinned. */ - if ( ubnd_block[ idim ] < ubnd[ idim ] ) { - lbnd_block[ idim ] = MinI( lbnd_block[ idim ] + - dim_block[ idim ], ubnd[ idim ], status ); - ubnd_block[ idim ] = MinI( lbnd_block[ idim ] + - dim_block[ idim ] - 1, - ubnd[ idim ], status ); - break; - -/* If any less significant dimensions are found where the upper bound - of the block has reached its maximum value, we reset the block to - its lowest position. */ - } else { - lbnd_block[ idim ] = lbnd[ idim ]; - ubnd_block[ idim ] = MinI( lbnd[ idim ] + dim_block[ idim ] - 1, - ubnd[ idim ], status ); - -/* All the blocks have been processed once the position along the most - significant dimension has been reset. */ - done = ( ++idim == ndim_in ); - } - } while ( !done ); - } - } - -/* Free the workspace. */ - lbnd_block = astFree( lbnd_block ); - ubnd_block = astFree( ubnd_block ); - dim_block = astFree( dim_block ); -} - -static void TranN( AstMapping *this, int npoint, - int ncoord_in, int indim, const double *in, - int forward, - int ncoord_out, int outdim, double *out, int *status ) { -/* -*++ -* Name: -c astTranN -f AST_TRANN - -* Purpose: -* Transform N-dimensional coordinates. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astTranN( AstMapping *this, int npoint, -c int ncoord_in, int indim, const double *in, -c int forward, -c int ncoord_out, int outdim, double *out ) -f CALL AST_TRANN( THIS, NPOINT, -f NCOORD_IN, INDIM, IN, -f FORWARD, NCOORD_OUT, OUTDIM, OUT, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -c This function applies a Mapping to transform the coordinates of -f This routine applies a Mapping to transform the coordinates of -* a set of points in an arbitrary number of dimensions. It is the -* appropriate routine to use if the coordinates are not purely 1- -* or 2-dimensional and are stored in a single array (which they -* need not fill completely). -c -c If the coordinates are not stored in a single array, then the -c astTranP function might be more suitable. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping to be applied. -c npoint -f NPOINT = INTEGER (Given) -* The number of points to be transformed. -c ncoord_in -f NCOORD_IN = INTEGER (Given) -* The number of coordinates being supplied for each input point -* (i.e. the number of dimensions of the space in which the -* input points reside). -c indim -f INDIM = INTEGER (Given) -c The number of elements along the second dimension of the "in" -f The number of elements along the first dimension of the IN -* array (which contains the input coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -c given should not be less than "npoint". -f given should not be less than NPOINT. -c in -f IN( INDIM, NCOORD_IN ) = DOUBLE PRECISION (Given) -c The address of the first element in a 2-dimensional array of -c shape "[ncoord_in][indim]", -c containing the coordinates of the input (untransformed) -c points. These should be stored such that the value of -c coordinate number "coord" for input point number "point" is -c found in element "in[coord][point]". -f An array containing the coordinates of the input -f (untransformed) points. These should be stored such that the -f value of coordinate number COORD for input point number POINT -f is found in element IN(POINT,COORD). -c forward -f FORWARD = LOGICAL (Given) -c A non-zero value indicates that the Mapping's forward -c coordinate transformation is to be applied, while a zero -c value indicates that the inverse transformation should be -c used. -f A .TRUE. value indicates that the Mapping's forward -f coordinate transformation is to be applied, while a .FALSE. -f value indicates that the inverse transformation should be -f used. -c ncoord_out -f NCOORD_OUT = INTEGER (Given) -* The number of coordinates being generated by the Mapping for -* each output point (i.e. the number of dimensions of the -* space in which the output points reside). This need not be -c the same as "ncoord_in". -f the same as NCOORD_IN. -c outdim -f OUTDIM = INTEGER (Given) -c The number of elements along the second dimension of the "out" -f The number of elements along the first dimension of the OUT -* array (which will contain the output coordinates). This value -* is required so that the coordinate values can be correctly -* located if they will not entirely fill this array. The value -c given should not be less than "npoint". -f given should not be less than NPOINT. -c out -f OUT( OUTDIM, NCOORD_OUT ) = DOUBLE PRECISION (Returned) -c The address of the first element in a 2-dimensional array of -c shape "[ncoord_out][outdim]", into -c which the coordinates of the output (transformed) points will -c be written. These will be stored such that the value of -c coordinate number "coord" for output point number "point" -c will be found in element "out[coord][point]". -f An array into which the coordinates of the output -f (transformed) points will be written. These will be stored -f such that the value of coordinate number COORD for output -f point number POINT will be found in element OUT(POINT,COORD). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - If the forward coordinate transformation is being applied, the -c Mapping supplied must have the value of "ncoord_in" for its Nin -c attribute and the value of "ncoord_out" for its Nout attribute. If -c the inverse transformation is being applied, these values should -c be reversed. -f - If the forward coordinate transformation is being applied, the -f Mapping supplied must have the value of NCOORD_IN for its Nin -f attribute and the value of NCOORD_OUT for its Nout attribute. If -f the inverse transformation is being applied, these values should -f be reversed. -*-- -*/ - -/* Local Variables: */ - AstPointSet *in_points; /* Pointer to input PointSet */ - AstPointSet *out_points; /* Pointer to output PointSet */ - const double **in_ptr; /* Pointer to array of input data pointers */ - double **out_ptr; /* Pointer to array of output data pointers */ - int coord; /* Loop counter for coordinates */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the mapping and numbers of points/coordinates. */ - ValidateMapping( this, forward, npoint, ncoord_in, ncoord_out, "astTranN", status ); - -/* Also validate the input array dimension argument. */ - if ( astOK && ( indim < npoint ) ) { - astError( AST__DIMIN, "astTranN(%s): The input array dimension value " - "(%d) is invalid.", status, astGetClass( this ), indim ); - astError( AST__DIMIN, "This should not be less than the number of " - "points being transformed (%d).", status, npoint ); - } - -/* Similarly, validate the output array dimension argument. */ - if ( astOK && ( outdim < npoint ) ) { - astError( AST__DIMIN, "astTranN(%s): The output array dimension value " - "(%d) is invalid.", status, astGetClass( this ), outdim ); - astError( AST__DIMIN, "This should not be less than the number of " - "points being transformed (%d).", status, npoint ); - } - -/* Allocate memory to hold the arrays of input and output data - pointers. */ - if ( astOK ) { - in_ptr = (const double **) astMalloc( sizeof( const double * ) * - (size_t) ncoord_in ); - out_ptr = astMalloc( sizeof( double * ) * (size_t) ncoord_out ); - - -#ifdef DEBUG - { int i, ns; - ns = ncoord_out*outdim; - for( i = 0; i < ns; i++ ) out[ i ] = 0.0; - } -#endif - - -/* Initialise the input data pointers to locate the coordinate data in - the "in" array. */ - if ( astOK ) { - for ( coord = 0; coord < ncoord_in; coord++ ) { - in_ptr[ coord ] = in + coord * indim; - } - -/* Similarly initialise the output data pointers to point into the - "out" array. */ - for ( coord = 0; coord < ncoord_out; coord++ ) { - out_ptr[ coord ] = out + coord * outdim; - } - -/* Create PointSets to describe the input and output points. */ - in_points = astPointSet( npoint, ncoord_in, "", status ); - out_points = astPointSet( npoint, ncoord_out, "", status ); - -/* Associate the data pointers with the PointSets (note we must - explicitly remove the "const" qualifier from the input data here, - although they will not be modified). */ - astSetPoints( in_points, (double **) in_ptr ); - astSetPoints( out_points, out_ptr ); - -/* Apply the required transformation to the coordinates. */ - (void) astTransform( this, in_points, forward, out_points ); - -/* If the Mapping's Report attribute is set, report the effect the - Mapping has had on the coordinates. */ - if ( astGetReport( this ) ) astReportPoints( this, forward, - in_points, out_points ); - -/* Delete the two PointSets. */ - in_points = astDelete( in_points ); - out_points = astDelete( out_points ); - } - -/* Free the memory used for the data pointers. */ - in_ptr = (const double **) astFree( (void *) in_ptr ); - out_ptr = astFree( out_ptr ); - } -} - -static void TranP( AstMapping *this, int npoint, - int ncoord_in, const double *ptr_in[], - int forward, int ncoord_out, double *ptr_out[], int *status ) { -/* -c++ -* Name: -* astTranP - -* Purpose: -* Transform N-dimensional coordinates held in separate arrays. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "mapping.h" -* void astTranP( AstMapping *this, int npoint, -* int ncoord_in, const double *ptr_in[], -* int forward, int ncoord_out, double *ptr_out[] ) - -* Class Membership: -* Mapping method. - -* Description: -* This function applies a Mapping to transform the coordinates of -* a set of points in an arbitrary number of dimensions. It is the -* appropriate routine to use if the coordinates are not purely 1- -* or 2-dimensional and are stored in separate arrays, since each -* coordinate array is located by supplying a separate pointer to -* it. -* -* If the coordinates are stored in a single (2-dimensional) array, -* then the astTranN function might be more suitable. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* npoint -* The number of points to be transformed. -* ncoord_in -* The number of coordinates being supplied for each input point -* (i.e. the number of dimensions of the space in which the -* input points reside). -* ptr_in -* An array of pointers to double, with "ncoord_in" -* elements. Element "ptr_in[coord]" should point at the first -* element of an array of double (with "npoint" elements) which -* contain the values of coordinate number "coord" for each -* input (untransformed) point. The value of coordinate number -* "coord" for input point number "point" is therefore given by -* "ptr_in[coord][point]" (assuming both indices are -* zero-based). -* forward -* A non-zero value indicates that the Mapping's forward -* coordinate transformation is to be applied, while a zero -* value indicates that the inverse transformation should be -* used. -* ncoord_out -* The number of coordinates being generated by the Mapping for -* each output point (i.e. the number of dimensions of the space -* in which the output points reside). This need not be the same -* as "ncoord_in". -* ptr_out -* An array of pointers to double, with "ncoord_out" -* elements. Element "ptr_out[coord]" should point at the first -* element of an array of double (with "npoint" elements) into -* which the values of coordinate number "coord" for each output -* (transformed) point will be written. The value of coordinate -* number "coord" for output point number "point" will therefore -* be found in "ptr_out[coord][point]". - -* Notes: -* - If the forward coordinate transformation is being applied, the -* Mapping supplied must have the value of "ncoord_in" for its Nin -* attribute and the value of "ncoord_out" for its Nout -* attribute. If the inverse transformation is being applied, these -* values should be reversed. -* - This routine is not available in the Fortran 77 interface to -* the AST library. -c-- -*/ - -/* Local Variables: */ - AstPointSet *in_points; /* Pointer to input PointSet */ - AstPointSet *out_points; /* Pointer to output PointSet */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the Mapping and number of points/coordinates. */ - ValidateMapping( this, forward, npoint, ncoord_in, ncoord_out, "astTranP", status ); - -/* Create PointSets to describe the input and output points. */ - if ( astOK ) { - in_points = astPointSet( npoint, ncoord_in, "", status ); - out_points = astPointSet( npoint, ncoord_out, "", status ); - -/* Associate the data pointers with the PointSets (note we must - explicitly remove the "const" qualifier from the input data here, - although they will not be modified). */ - astSetPoints( in_points, (double **) ptr_in ); - astSetPoints( out_points, ptr_out ); - -/* Apply the required transformation to the coordinates. */ - (void) astTransform( this, in_points, forward, out_points ); - -/* If the Mapping's Report attribute is set, report the effect the - Mapping has had on the coordinates. */ - if ( astGetReport( this ) ) astReportPoints( this, forward, - in_points, out_points ); - -/* Delete the two PointSets. */ - in_points = astDelete( in_points ); - out_points = astDelete( out_points ); - } -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -*+ -* Name: -* astTransform - -* Purpose: -* Transform a set of points. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "mapping.h" -* AstPointSet *astTransform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out ) - -* Class Membership: -* Mapping method. - -* Description: -* This function takes a Mapping and a set of points encapsulated -* in a PointSet, and applies either the forward or inverse -* coordinate transformation (if defined by the Mapping) to the -* points. - -* Parameters: -* this -* Pointer to the Mapping. The nature of the coordinate -* transformation will depend on the class of Mapping -* supplied. Note that there is no constructor for the Mapping -* class itself, so this object should be from a derived class. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate -* transformation should be applied, while a zero value requests -* the inverse transformation. -* out -* Pointer to a PointSet which will hold the transformed -* (output) coordinate values. A NULL value may also be given, -* in which case a new PointSet will be created by this -* function. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - An error will result if the Mapping supplied does not define -* the requested coordinate transformation (either forward or -* inverse). -* - The number of coordinate values per point in the input -* PointSet must match the number of input coordinates for the -* Mapping being applied (or number of output coordinates if the -* inverse transformation is requested). -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and coordinate values per point to -* accommodate the result (e.g. the number of Mapping output -* coordinates, or number of input coordinates if the inverse -* transformation is requested). Any excess space will be ignored. -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - int def; /* Coordinate transformation defined? */ - int ncoord_in; /* Number of input PointSet coordinates */ - int ncoord_out; /* Number of coordinates in output PointSet */ - int nin; /* Number of input Mapping coordinates */ - int nout; /* Number of output Mapping coordinates */ - int npoint; /* Number of points to transform */ - int npoint_out; /* Number of points in output PointSet */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise. */ - result = NULL; - -/* Determine if a coordinate transformation is defined for the requested - direction. */ - def = forward ? astGetTranForward( this ) : astGetTranInverse( this ); - -/* Report an error if the transformation is not defined. */ - if ( astOK && !def ) { - astError( AST__TRNND, "astTransform(%s): %s coordinate transformation " - "is not defined by the %s supplied.", status, astGetClass( this ), - forward ? "A forward" : "An inverse", astGetClass( this ) ); - } - -/* Obtain the effective number of input and output coordinate values for the - transformation to be performed, taking account of the transformation - direction required. Note we use Mapping methods to obtain these values, as - this will take account of whether the Mapping has been inverted. */ - nin = forward ? astGetNin( this ) : astGetNout( this ); - nout = forward ? astGetNout( this ) : astGetNin( this ); - -/* Obtain the number of input points to transform and the number of coordinate - values per input point. */ - npoint = astGetNpoint( in ); - ncoord_in = astGetNcoord( in ); - -/* If OK, check that the number of input coordinates matches the number - required by the mapping. Report an error if these numbers do not match. */ - if ( astOK && ( ncoord_in != nin ) ) { - astError( AST__NCPIN, "astTransform(%s): Bad number of coordinate " - "values (%d) in input %s.", status, astGetClass( this ), ncoord_in, - astGetClass( in ) ); - astError( AST__NCPIN, "The %s given requires %d coordinate value(s) for " - "each input point.", status, astGetClass( this ), nin ); - } - -/* If still OK, and a non-NULL pointer has been given for the output PointSet, - then obtain the number of points and number of coordinates per point for - this PointSet. */ - if ( astOK && out ) { - npoint_out = astGetNpoint( out ); - ncoord_out = astGetNcoord( out ); - -/* Check that the dimensions of this PointSet are adequate to accommodate the - output coordinate values and report an error if they are not. */ - if ( astOK ) { - if ( npoint_out < npoint ) { - astError( AST__NOPTS, "astTransform(%s): Too few points (%d) in " - "output %s.", status, astGetClass( this ), npoint_out, - astGetClass( out ) ); - astError( AST__NOPTS, "The %s needs space to hold %d transformed " - "point(s).", status, astGetClass( this ), npoint ); - } else if ( ncoord_out < nout ) { - astError( AST__NOCTS, "astTransform(%s): Too few coordinate " - "values per point (%d) in output %s.", status, - astGetClass( this ), ncoord_out, astGetClass( out ) ); - astError( AST__NOCTS, "The %s supplied needs space to store %d " - "coordinate value(s) per transformed point.", status, - astGetClass( this ), nout ); - } - } - } - -/* If all the validation stages are passed successfully, and a NULL output - pointer was given, then create a new PointSet to encapsulate the output - coordinate data. */ - if ( astOK ) { - if ( !out ) { - result = astPointSet( npoint, nout, "", status ); - -/* Otherwise, use the PointSet supplied. */ - } else { - result = out; - } - } - -/* Return a pointer to the output PointSet. Note that we do not actually - transform (or even copy) the coordinates. This is left for derived classes - to implement. */ - return result; -} - -/* -*++ -* Name: -c astUinterp -f AST_UINTERP - -* Purpose: -* Perform sub-pixel interpolation on a grid of data. - -* Type: -* Fictitious function. - -* Synopsis: -c #include "mapping.h" -c void astUinterp( int ndim_in, const int lbnd_in[], const int ubnd_in[], -c const in[], const in_var[], -c int npoint, const int offset[], -c const double *const coords[], const double params[], -c int flags, badval, -c out[], out_var[], int *nbad ) -f CALL AST_UINTERP( NDIM_IN, LBND_IN, UBND_IN, IN, IN_VAR, -f NPOINT, OFFSET, COORDS, PARAMS, FLAGS, BADVAL, -f OUT, OUT_VAR, NBAD, STATUS ) - -* Class Membership: -* Mapping member function. - -* Description: -c This is a fictitious function which does not actually -c exist. Instead, this description constitutes a template so that -c you may implement a function with this interface for yourself -c (and give it any name you wish). A pointer to such a function -c may be passed via the "finterp" parameter of the astResample -c functions (q.v.) in order to perform sub-pixel interpolation -c during resampling of gridded data (you must also set the -c "interp" parameter of astResample to the value -c AST__UINTERP). This allows you to use your own interpolation -c algorithm in addition to those which are pre-defined. -f This is a fictitious routine which does not actually -f exist. Instead, this description constitutes a template so that -f you may implement a routine with this interface for yourself -f (and give it any name you wish). Such a routine -f may be passed via the FINTERP argument of the AST_RESAMPLE -f functions (q.v.) in order to perform sub-pixel interpolation -f during resampling of gridded data (you must also set the -f INTERP argument of AST_RESAMPLE to the value -f AST__UINTERP). This allows you to use your own interpolation -f algorithm in addition to those which are pre-defined. -* -c The function interpolates an input grid of data (and, -f The routine interpolates an input grid of data (and, -* optionally, processes associated statistical variance estimates) -* at a specified set of points. - -* Parameters: -c ndim_in -f NDIM_IN = INTEGER (Given) -* The number of dimensions in the input grid. This will be at -* least one. -c lbnd_in -f LBND_IN( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the centre of the first pixel -* in the input grid along each dimension. -c ubnd_in -f UBND_IN( NDIM_IN ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim_in" elements, -f An array -* containing the coordinates of the centre of the last pixel in -* the input grid along each dimension. -* -c Note that "lbnd_in" and "ubnd_in" together define the shape, -f Note that LBND_IN and UBND_IN together define the shape, -* size and coordinate system of the input grid in the same -c way as they do in astResample. -f way as they do in AST_RESAMPLE. -c in -f IN( * ) = (Given) -c Pointer to an array, with one element for each pixel in the -f An array, with one element for each pixel in the -* input grid, containing the input data. This will be the same -c array as was passed to astResample via the "in" parameter. -f array as was passed to AST_RESAMPLE via the IN argument. -* The numerical type of this array should match that of the -* data being processed. -c in_var -f IN_VAR( * ) = (Given) -c Pointer to an optional second array with the same size and -c type as the "in" array. If given, this will contain the set -c of variance values associated with the input data and will be -c the same array as was passed to astResample via the -c "in_var" parameter. -f An optional second array with the same size and type as the -f IN array. This will only be given if the AST__USEVAR flag is -f set via the FLAGS argument (below). If given, it will contain -f the set of variance values associated with the input data and -f will be the same array as was passed to AST_RESAMPLE via -f the IN_VAR argument. -* -c If no variance values are being processed, this will be a -c NULL pointer. -f If the AST__USEVAR flag is not set, then no variance values -f are being processed. In this case, this array of variance -f values may be a dummy (e.g. one-element) array and should not -f be used. -c npoint -f NPOINT = INTEGER (Given) -* The number of points at which the input grid is to be -* interpolated. This will be at least one. -c offset -f OFFSET( NPOINT ) = INTEGER (Given) -c Pointer to an array of integers with "npoint" elements. For -c each interpolation point, this will contain the zero-based -c index in the "out" (and "out_var") array(s) at which the -c interpolated value (and its variance, if required) should be -c stored. For example, the interpolated value for point number -c "point" should be stored in "out[offset[point]]" (assuming -c the index "point" is zero-based). -f For each interpolation point, this array will contain the -f offset from the start of the OUT (and OUT_VAR) array(s) at -f which the interpolated value (and its variance, if required) -f should be stored. For example, the interpolated value for -f point number POINT should be stored in OUT(1+OFFSET(POINT)). -c coords -f COORDS( NPOINT, NDIM_IN ) = DOUBLE PRECISION (Given) -c An array of pointers to double, with "ndim_in" -c elements. Element "coords[coord]" will point at the first -c element of an array of double (with "npoint" elements) which -c contains the values of coordinate number "coord" for each -c interpolation point. The value of coordinate number "coord" -c for interpolation point number "point" is therefore given by -c "coords[coord][point]" (assuming both indices are -c zero-based). -f A 2-dimensional array containing the coordinates of the -f points at which interpolation should be performed. These will -f be stored so that coordinate number COORD for interpolation -f point number POINT is found in element COORDS(POINT,COORD). -* -* If any interpolation point has any of its coordinates equal -c to the value AST__BAD (as defined in the "ast.h" header -f to the value AST__BAD (as defined in the AST_PAR include -* file), then the corresponding output data (and variance) -c should either be set to the value given by "badval", -f should either be set to the value given by BADVAL, -* or left unchanged, depending on whether the AST__NOBAD flag is -c specified by "flags". -f specified by FLAGS. -c params -f PARAMS( * ) = DOUBLE PRECISION (Given) -c This will be a pointer to the same array as was given via the -c "params" parameter of astResample. You may use this to -f This will be the same array as was given via the -f PARAMS argument of AST_RESAMPLE. You may use this to -* pass any additional parameter values required by your -* interpolation algorithm. -c flags -f FLAGS = INTEGER (Given) -c This will be the same value as was given via the "flags" -c parameter of astResample. You may test this value to -f This will be the same value as was given via the FLAGS -f argument of AST_RESAMPLE. You may test this value to -* provide additional control over the operation of your -* resampling algorithm. Note that the special flag values -* AST__URESAMP1, 2, 3 & 4 are reserved for you to use for your -* own purposes and will not clash with other pre-defined flag -c values (see astResample). -f values (see AST_RESAMPLE). -c badval -f BADVAL = (Given) -c This will be the same value as was given via the "badval" -c parameter of astResample, and will have the same numerical -c type as the data being processed (i.e. as elements of the -c "in" array). It should be used to test for bad pixels in the -c input grid (but only if the AST__USEBAD flag is set via the -c "flags" parameter) and (unless the AST__NOBAD flag is set in -c "flags") for identifying bad output values in -c the "out" (and "out_var") array(s). -f This will be the same value as was given for the BADVAL -f argument of AST_RESAMPLE, and will have the same numerical -f type as the data being processed (i.e. as elements of the IN -f array). It should be used to test for bad pixels in the -f input grid (but only if the AST__USEBAD flag is set via the -f FLAGS argument) and (unless the AST__NOBAD flag is set in -f FLAGS) for identifying bad output values in the OUT (and -f OUT_VAR) array(s). -c out -f OUT( * ) = (Returned) -c Pointer to an array with the same numerical type as the "in" -f An array with the same numerical type as the IN -* array, into which the interpolated data values should be -* returned. Note that details of the storage order and number -* of dimensions of this array are not required, since the -c "offset" array contains all necessary information about where -f OFFSET array contains all necessary information about where -* each returned value should be stored. -* -c In general, not all elements of this array (or the "out_var" -f In general, not all elements of this array (or the OUT_VAR -* array below) may be used in any particular invocation of the -c function. Those which are not used should be returned -f routine. Those which are not used should be returned -* unchanged. -c out_var -f OUT_VAR( * ) = (Returned) -c Pointer to an optional array with the same type and size as -c the "out" array, into which variance estimates for the -c resampled values should be returned. This array will only be -c given if the "in_var" array has also been given. -f An optional array with the same type and size as the OUT -f array, into which variance estimates for the resampled values -f should be returned. This array will only be given if the -f AST__USEVAR flag is set via the FLAGS argument. -* -c If given, it is addressed in exactly the same way (via the -c "offset" array) as the "out" array. The values returned -c should be estimates of the statistical variance of the -c corresponding values in the "out" array, on the assumption -c that all errors in input data values are statistically -c independent and that their variance estimates may simply be -c summed (with appropriate weighting factors). -f If given, it is addressed in exactly the same way (via the -f OFFSET array) as the OUT array. The values returned should be -f estimates of the statistical variance of the corresponding -f values in the OUT array, on the assumption that all errors in -f input data values are statistically independent and that -f their variance estimates may simply be summed (with -f appropriate weighting factors). -* -c If no output variance estimates are required, a NULL pointer -c will be given. -f If the AST__USEVAR flag is not set, then variance values are -f not being processed. In this case, this array may be a dummy -f (e.g. one-element) array and should not be used. -c nbad -f NBAD = INTEGER (Returned) -c Pointer to an int in which to return the number of interpolation -c points at -f This should return the number of interpolation points at -* which no valid interpolated value could be obtained. The maximum -c value that should be returned is "npoint", and the minimum is -f value that should be returned is NPOINT, and the minimum is -* zero (indicating that all output values were successfully -* obtained). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The data type indicates the numerical type of the data -c being processed, as for astResample. -f being processed, as for AST_RESAMPLE. -c - This function will typically be invoked more than once for each -c invocation of astResample. -f - This routine will typically be invoked more than once for each -f invocation of AST_RESAMPLE. -c - If an error occurs within this function, it should use -c astSetStatus to set the AST error status to an error value. -c This will cause an immediate return from astResample. The error -c value AST__UINER is available for this purpose, but other values may -c also be used (e.g. if you wish to distinguish different types of -c error). -f - If an error occurs within this routine, it should set the -f STATUS argument to an error value before returning. This will -f cause an immediate return from AST_RESAMPLE. The error value -f AST__UINER is available for this purpose, but other values may also -f be used (e.g. if you wish to distinguish different types of error). -f The AST__UINER error value is defined in the AST_ERR include file. -*-- -*/ -/* Note the above is just a description to act as a template. The - function does not actually exist. */ - -/* -*++ -* Name: -c astUkern1 -f AST_UKERN1 - -* Purpose: -* 1-dimensional sub-pixel interpolation kernel. - -* Type: -* Fictitious function. - -* Synopsis: -c #include "mapping.h" -c void astUkern1( double offset, const double params[], int flags, -c double *value ) -f CALL AST_UKERN1( OFFSET, PARAMS, FLAGS, VALUE, STATUS ) - -* Class Membership: -* Mapping member function. - -* Description: -c This is a fictitious function which does not actually -c exist. Instead, this description constitutes a template so that -c you may implement a function with this interface for yourself -c (and give it any name you wish). A pointer to such a function -c may be passed via the "finterp" parameter of the astResample -c functions (q.v.) in order to supply a 1-dimensional -c interpolation kernel to the algorithm which performs sub-pixel -c interpolation during resampling of gridded data (you must also -c set the "interp" parameter of astResample to the value -c AST__UKERN1). This allows you to use your own interpolation -c kernel in addition to those which are pre-defined. -f This is a fictitious routine which does not actually -f exist. Instead, this description constitutes a template so that -f you may implement a routine with this interface for yourself -f (and give it any name you wish). Such a routine -f may be passed via the FINTERP argument of the AST_RESAMPLE -f functions (q.v.) in order to supply a 1-dimensional -f interpolation kernel to the algorithm which performs sub-pixel -f interpolation during resampling of gridded data (you must also -f set the INTERP argument of AST_RESAMPLE to the value -f AST__UKERN1). This allows you to use your own interpolation -f kernel in addition to those which are pre-defined. -* -c The function calculates the value of a 1-dimensional sub-pixel -f The routine calculates the value of a 1-dimensional sub-pixel -* interpolation kernel. This determines how the weight given to -* neighbouring pixels in calculating an interpolated value depends -* on the pixel's offset from the interpolation point. In more than -* one dimension, the weight assigned to a pixel is formed by -* evaluating this 1-dimensional kernel using the offset along each -* dimension in turn. The product of the returned values is then -* used as the pixel weight. - -* Parameters: -c offset -f OFFSET = DOUBLE PRECISION (Given) -* This will be the offset of the pixel from the interpolation -* point, measured in pixels. This value may be positive or -* negative, but for most practical interpolation schemes its -* sign should be ignored. -c params -f PARAMS( * ) = DOUBLE PRECISION (Given) -c This will be a pointer to the same array as was given via the -c "params" parameter of astResample. You may use this to -f This will be the same array as was given via the -f PARAMS argument of AST_RESAMPLE. You may use this to -* pass any additional parameter values required by your kernel, -c but note that "params[0]" will already have been used to specify -f but note that PARAMS(1) will already have been used to specify -* the number of neighbouring pixels which contribute to the -* interpolated value. -c flags -f FLAGS = INTEGER (Given) -c This will be the same value as was given via the "flags" -c parameter of astResample. You may test this value to -f This will be the same value as was given via the FLAGS -f argument of AST_RESAMPLE. You may test this value to -* provide additional control over the operation of your -c function. Note that the special flag values AST__URESAMP1, 2, -f routine. Note that the special flag values AST__URESAMP1, 2, -* 3 & 4 are reserved for you to use for your own purposes and -* will not clash with other pre-defined flag -c values (see astResample). -f values (see AST_RESAMPLE). -c value -f VALUE = DOUBLE PRECISION (Returned) -c Pointer to a double to receive the calculated kernel value, -f The calculated kernel value, -* which may be positive or negative. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Not all functions make good interpolation kernels. In general, -* acceptable kernels tend to be symmetrical about zero, to have a -* positive peak (usually unity) at zero, and to evaluate to zero -* whenever the pixel offset has any other integral value (this -* ensures that the interpolated values pass through the original -* data). An interpolation kernel may or may not have regions with -* negative values. You should consult a good book on image -* processing for more details. -c - If an error occurs within this function, it should use -c astSetStatus to set the AST error status to an error value. -c This will cause an immediate return from astResample. The error -c value AST__UK1ER is available for this purpose, but other values may -c also be used (e.g. if you wish to distinguish different types of -c error). -f - If an error occurs within this routine, it should set the -f STATUS argument to an error value before returning. This will -f cause an immediate return from AST_RESAMPLE. The error value -f AST__UK1ER is available for this purpose, but other values may also -f be used (e.g. if you wish to distinguish different types of error). -f The AST__UK1ER error value is defined in the AST_ERR include file. -*-- -*/ -/* Note the above is just a description to act as a template. The - function does not actually exist. */ - -static double UphillSimplex( const MapData *mapdata, double acc, int maxcall, - const double dx[], double xmax[], double *err, - int *ncall, int *status ) { -/* -* Name: -* UphillSimplex - -* Purpose: -* Find a function maximum using a modification of the simplex method. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* double UphillSimplex( const MapData *mapdata, double acc, int maxcall, -* const double dx[], double xmax[], double *err, -* int *ncall, int *status ); - -* Class Membership: -* Mapping member function. - -* Description: -* This function applies a modification of the simplex method to -* find a local maximum in the value returned by a Mapping -* function. The modification used allows the method to cope with -* coordinate constraints and (equivalently) regions where the -* function returns "bad" values. The method is robust and not -* susceptible to overflow, so is suitable for applying to Mapping -* functions of unknown form. - -* Parameters: -* mapdata -* Pointer to a MapData structure which describes the Mapping -* function, its coordinate constraints, etc. -* acc -* The accuracy required in the value of the maximum. -* maxcall -* The maximum number of Mapping function evaluations to use. -* dx -* Pointer to an array of double containing an offset along each -* input coordinate for the Mapping function supplied. These -* offsets will be used to construct the initial simplex -* (i.e. they are the initial "step lengths" for each -* coordinate) and may be positive or negative. -* xmax -* Pointer to an array of double which contains the coordinates -* of an initial estimate of the location of the maximum. On -* exit, this will be updated to contain the best estimate of -* the location of the maximum as generated by this function. -* err -* Pointer to a double in which to return an estimate of the -* error in the value of the maximum found. For normal -* convergence, this should be no larger than "acc". However, if -* the maximum number of Mapping function evaluations is -* reached, the returned value may be larger than this, although -* it should still be valid. In such cases, re-starting the -* algorithm at the new location returned in "xmax" may be -* advisable. -* ncall -* Pointer to an int in which the number of Mapping function -* evaluations will be returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* An estimate of the Mapping function value at the local maximum. - -* Notes: -* - The function may return before the requested accuracy has been -* met and before all Mapping function evaluations have been -* made. This signifies that an excessive number of function values -* have been needed outside the coordinate constraints. This is -* only likely if the function is unable to make progress near such -* a constraint, in which case the algorithm should probably be -* re-started. -* - A value of AST__BAD will be returned if no maximum could be -* found. This means that all the Mapping function evaluations -* performed returned a value of AST__BAD. -* - A value of AST__BAD will also be returned and no useful -* information about a solution will be produced if this routine is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Constants: */ - const double factor = 3.0; /* Simplex contraction/expansion factor */ - -/* Local Variables: */ - double *f; /* Pointer to array of function values */ - double *x; /* Pointer to array of vertex coordinates */ - double *xnew; /* Pointer to workspace array */ - double fnew; /* New function value */ - double fsave; /* Saved function value */ - double offset; /* Coordinate difference between vertices */ - double range; /* Range of simplex values */ - double result; /* Value to return */ - double tmp; /* Temporary store for coordinate */ - int coord; /* Loop counter for coordinates */ - int hi; /* Index of best vertex */ - int lo; /* Index of worst vertex */ - int ncalla; /* Number of function calls attempted */ - int ncoord; /* Number of function dimensions */ - int nextlo; /* Index of second worst vertex */ - int nvertex; /* Number of simplex vertices */ - int vertex; /* Loop counter for vertices */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialisation. */ - *err = DBL_MAX; - *ncall = 0; - -/* Obtain the number of input coordinates for the Mapping function and - calculate the number of simplex vertices. */ - ncoord = mapdata->nin; - nvertex = ncoord + 1; - -/* Allocate workspace. */ - f = astMalloc( sizeof( double ) * (size_t) nvertex ); - x = astMalloc( sizeof( double ) * (size_t) ( ncoord * nvertex ) ); - xnew = astMalloc( sizeof( double ) * (size_t) ncoord ); - if ( astOK ) { - -/* Loop to set up an initial simplex. */ - for ( vertex = 0; vertex < nvertex; vertex++ ) { - for ( coord = 0; coord < ncoord; coord++ ) { - tmp = xmax[ coord ]; - -/* Displace each point (except the first) the required amount along - one of the axes to generate the coordinates of the simplex - vertices. */ - if ( coord == ( vertex - 1 ) ) tmp += dx[ coord ]; - x[ vertex * ncoord + coord ] = tmp; - } - -/* Evaluate the Mapping function at each vertex. */ - f[ vertex ] = MapFunction( mapdata, &x[ vertex * ncoord ], ncall, status ); - if ( f[ vertex ] == AST__BAD ) f[ vertex ] = -DBL_MAX; - } - -/* Initialise the number of times we attempt to call the Mapping - function (not necessarily the same as the number of times it was - actually called, which is stored in *ncall). */ - ncalla = nvertex; - -/* Loop until convergence is reached or an error occurs. */ - while( astOK ) { - -/* Initialise the index of the lowest vertex of the simplex, the next - lowest vertex and the highest vertex. */ - lo = ( f[ 0 ] < f[ 1 ] ) ? 0 : 1; - nextlo = 1 - lo; - hi = 0; - -/* Loop to inspect each vertex and update these values. Ensure that in - the case of equal vertices, the first one is taken to be the - highest. This makes the maximisation stable (so that if no better - maximum can be found, the original position is returned rather than - a nearby position that yields the same function value). */ - for ( vertex = 0; vertex < nvertex; vertex++ ) { - if ( f[ vertex ] <= f[ lo ] ) { - nextlo = lo; - lo = vertex; - } else if ( ( f[ vertex ] <= f[ nextlo ] ) && ( vertex != lo ) ) { - nextlo = vertex; - } - if ( f[ vertex ] > f[ hi ] ) hi = vertex; - } - -/* Estimate the error on the result as the difference between the - highest and lowest simplex vertices. */ - if ( ( f[ hi ] == -DBL_MAX ) || ( f[ lo ] == -DBL_MAX ) ) { - range = DBL_MAX; - } else { - range = f[ hi ] - f[ lo ]; - } - -/* Test for convergence. Ideally, the accuracy criterion should have - been met. However, also quit if the maximum number of Mapping - function evaluations has been reached, or the number of points at - which function values have been requested reaches three times this - limit (this latter number will typically be larger because points - lying outside the coordinate constraints do not result in the - Mapping function being evaluated). */ - if ( range <= fabs( acc ) || - ( *ncall >= maxcall ) || ( ncalla >= ( 3 * maxcall ) ) ) { - -/* If quitting, return the coordinates and function value at the best - simplex vertex, and the error estimate. */ - for ( coord = 0; coord < ncoord; coord++ ) { - xmax[ coord ] = x[ hi * ncoord + coord ]; - } - result = ( f[ hi ] == -DBL_MAX ) ? AST__BAD : f[ hi ]; - *err = range; - break; - } - -/* If performing another iteration, first try reflecting the worst - vertex through the opposite face of the simplex. Check for - errors. */ - fnew = NewVertex( mapdata, lo, -1.0, x, f, ncall, xnew, status ); - ncalla++; - if ( astOK ) { - -/* If this results in a point lying in a forbiddden region (either - outside the coordinate constraints or where the Mapping function - yields bad coordinate values), then we must make a departure from - the standard simplex algorithm. This is because the inability to - make forward progress in this case can cause the simplex to - repeatedly contract about each face (except one) in turn. This - mechanism normally results in lateral contraction as the simplex - attempts to squeeze through a narrow gap which is impeding - progress. However, in this case there is no gap to get through, so - the lateral contraction can eventually make the simplex become - degenerate (due to rounding). This prevents it from expanding - laterally again and exploring the region adjacent to the constraint - boundary once it has become small enough. */ - if ( fnew == AST__BAD ) { - -/* To overcome this, we instead contract the worst simplex vertex - towards the best vertex (this has the cumulative effect of - contracting the simplex without changing its shape). First find the - offset in each coordinate between these two vertices. */ - for ( coord = 0; coord < ncoord; coord++ ) { - offset = x[ lo * ncoord + coord ] - x[ hi * ncoord + coord ]; - -/* Scale the offset to obtain the new coordinate. */ - x[ lo * ncoord + coord ] = x[ hi * ncoord + coord ] + - offset / factor; - -/* If the distance between the two vertices has not decreased, we are - in a region where rounding errors prevent them approaching each - other any more closely, so simply set them equal. */ - if ( fabs( x[ lo * ncoord + coord ] - - x[ hi * ncoord + coord ] ) >= fabs( offset ) ) { - x[ lo * ncoord + coord ] = x[ hi * ncoord + coord ]; - } - } - -/* Evaluate the Mapping function at the new vertex. */ - f[ lo ] = MapFunction( mapdata, &x[ lo * ncoord ], ncall, status ); - if ( f[ lo ] == AST__BAD ) f[ lo ] = -DBL_MAX; - ncalla++; - -/* We now return to the standard simplex algorithm. If the new vertex - is a new maximum, then see if more of the same is even better by - trying to expand the best vertex away from the opposite face. */ - } else if ( fnew >= f[ hi ] ) { - fnew = NewVertex( mapdata, lo, factor, x, f, ncall, xnew, status ); - ncalla++; - -/* Otherwise, if the new vertex was no improvement on the second - worst, then try contracting the worst vertex towards the opposite - face. */ - } else if ( fnew <= f[ nextlo ] ) { - fsave = f[ lo ]; - fnew = NewVertex( mapdata, lo, 1.0 / factor, x, f, ncall, xnew, status ); - ncalla++; - -/* If this didn't result in any improvement, then contract the entire - simplex towards the best vertex. Use the same approach as earlier - to protect against rounding so that all the simplex vertices will - eventually coalesce if this process is repeated enough times. */ - if ( astOK && ( fnew <= fsave ) ) { - for ( vertex = 0; vertex < nvertex; vertex++ ) { - if ( vertex != hi ) { - for ( coord = 0; coord < ncoord; coord++ ) { - offset = x[ vertex * ncoord + coord ] - - x[ hi * ncoord + coord ]; - x[ vertex * ncoord + coord ] = - x[ hi * ncoord + coord ] + offset / factor; - if ( fabs( x[ vertex * ncoord + coord ] - - x[ hi * ncoord + coord ] ) >= - fabs( offset ) ) { - x[ vertex * ncoord + coord ] = - x[ hi * ncoord + coord ]; - } - } - -/* Evaluate the Mapping function at each new vertex. */ - f[ vertex ] = MapFunction( mapdata, - &x[ vertex * ncoord ], - ncall, status ); - if ( f[ vertex ] == AST__BAD ) f[ vertex ] = -DBL_MAX; - ncalla++; - } - } - } - } - } - } - } - -/* Free workspace. */ - f = astFree( f ); - x = astFree( x ); - xnew = astFree( xnew ); - -/* If an error occurred, clear the returned result. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static void ValidateMapping( AstMapping *this, int forward, - int npoint, int ncoord_in, int ncoord_out, - const char *method, int *status ) { -/* -* Name: -* ValidateMapping - -* Purpose: -* Validate a Mapping for use to transform coordinates. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void ValidateMapping( AstMapping *this, int forward, -* int npoint, int ncoord_in, int ncoord_out, -* const char *method, int *status ) - -* Class Membership: -* Mapping member function. - -* Description: -* This function checks that a Mapping is suitable for transforming -* a set of points. It also checks that the number of points and -* the number of coordinate values per point is valid. If an error -* is detected, the global error status is set and an error report -* made. Otherwise, the function returns without further action. - -* Parameters: -* this -* Pointer to the Mapping. -* forward -* A non-zero value indicates that the forward coordinate -* transformation is to be checked, while a zero value requests -* the inverse transformation. -* npoint -* The number of points being transformed. -* ncoord_in -* The number of coordinates associated with each input point. -* ncoord_out -* The number of coordinates associated with each output point. -* method -* Pointer to a null terminated character string containing the -* name of the method which invoked this function to validate a -* Mapping. This is used solely for constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int nin; /* Mapping Nin attribute value */ - int nout; /* Mapping Nout attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Report an error if the requested transformation is not defined. */ - if ( !( forward ? astGetTranForward( this ) : astGetTranInverse( this ) ) - && astOK ) { - astError( AST__TRNND, "%s(%s): %s coordinate transformation " - "is not defined by the %s supplied.", status, method, - astGetClass( this ), - ( forward ? "A forward" : "An inverse" ), - astGetClass( this ) ); - } - -/* Obtain the effective values of the Nin and Nout attributes for the - Mapping. */ - nin = forward ? astGetNin( this ) : astGetNout( this ); - nout = forward ? astGetNout( this ) : astGetNin( this ); - -/* If OK, check that the number of input coordinates matches the - number required by the Mapping. Report an error if these numbers do - not match. */ - if ( astOK && ( ncoord_in != nin ) ) { - astError( AST__NCPIN, "%s(%s): Bad number of input coordinate values " - "(%d).", status, method, astGetClass( this ), ncoord_in ); - astError( AST__NCPIN, "The %s given requires %d coordinate value%s for " - "each input point.", status, astGetClass( this ), nin, - ( nin == 1 ) ? "" : "s" ); - } - -/* If OK, also check that the number of output coordinates matches the - number required by the Mapping. Report an error if these numbers do - not match. */ - if ( astOK && ( ncoord_out != nout ) ) { - astError( AST__NCPIN, "%s(%s): Bad number of output coordinate values " - "(%d).", status, method, astGetClass( this ), ncoord_out ); - astError( AST__NCPIN, "The %s given generates %s%d coordinate value%s " - "for each output point.", status, astGetClass( this ), - ( nout < ncoord_out ) ? "only " : "", nout, - ( nout == 1 ) ? "" : "s" ); - } - -/* Check that the number of points being transformed is not negative - and report an error if necessary. */ - if ( astOK && ( npoint < 0 ) ) { - astError( AST__NPTIN, "%s(%s): Number of points to be transformed (%d) " - "is invalid.", status, method, astGetClass( this ), npoint ); - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. */ -/* -*att++ -* Name: -* Invert - -* Purpose: -* Mapping inversion flag. - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls which one of a Mapping's two possible -* coordinate transformations is considered the "forward" -* transformation (the other being the "inverse" -* transformation). If the attribute value is zero (the default), -* the Mapping's behaviour will be the same as when it was first -* created. However, if it is non-zero, its two transformations -* will be inter-changed, so that the Mapping displays the inverse -* of its original behaviour. -* -* Inverting the boolean sense of the Invert attribute will cause -* the values of a Mapping's Nin and Nout attributes to be -* interchanged. The values of its TranForward and TranInverse -* attributes will also be interchanged. This operation may be -c performed with the astInvert function. -f performed with the AST_INVERT routine. - -* Applicability: -* Mapping -* All Mappings have this attribute. -* UnitMap -* The value of the Invert attribute has no effect on the -* behaviour of a UnitMap. -* FrameSet -* Inverting the boolean sense of the Invert attribute for a -* FrameSet will cause its base and current Frames (and its Base -* and Current attributes) to be interchanged. This, in turn, -* may affect other properties and attributes of the FrameSet -* (such as Nin, Nout, Naxes, TranForward, TranInverse, -* etc.). The Invert attribute of a FrameSet is not itself -* affected by selecting a new base or current Frame. -*att-- -*/ -/* This ia a boolean value (0 or 1) with a value of CHAR_MAX when - undefined but yielding a default of zero. */ -astMAKE_CLEAR(Mapping,Invert,invert,CHAR_MAX) -astMAKE_GET(Mapping,Invert,int,0,( ( this->invert == CHAR_MAX ) ? - 0 : this->invert )) -astMAKE_SET(Mapping,Invert,int,invert,( (this->flags&=~AST__ISSIMPLE_FLAG),(value!=0) )) -astMAKE_TEST(Mapping,Invert,( this->invert != CHAR_MAX )) - -/* -*att++ -* Name: -* IsLinear - -* Purpose: -* Is the Mapping linear? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean), read-only. - -* Description: -* This attribute indicates whether a Mapping is an instance of a -* class that always represents a linear transformation. Note, some -* Mapping classes can represent linear or non-linear transformations -* (the MathMap class for instance). Such classes have a zero value for -* the IsLinear attribute. Specific instances of such classes can be -* tested for linearity using the -* astLinearApprox function. -* AST_LINEARAPPROX routine. - -* Applicability: -* Mapping -* All Mappings have this attribute. -* CmpMap -* The IsLinear value for a CmpMap is determined by the classes -* of the encapsulated Mappings. For instance, a CmpMap that combines -* a ZoomMap and a ShiftMap will have a non-zero value for its IsLinear -* attribute, but a CmpMap that contains a MathMap will have a -* value of zero for its IsLinear attribute. -* Frame -* The IsLinear value for a Frame is 1 (since a Frame is equivalent -* to a UnitMap). -* FrameSet -* The IsLinear value for a FrameSet is obtained from the Mapping -* from the base Frame to the current Frame. - -*att-- -*/ - -/* -*att++ -* Name: -* IsSimple - -* Purpose: -* Has the Mapping been simplified? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean), read-only. - -* Description: -* This attribute indicates whether a Mapping has been simplified -* by the -c astSimplify -f AST_SIMPLIFY -* method. If the IsSimple value is non-zero, then the Mapping has -* been simplified and so there is nothing to be gained by simplifying -* it again. Indeed, the -c astSimplify -f AST_SIMPLIFY -* method will immediately return the Mapping unchanged if the IsSimple -* attribute indicates that the Mapping has already been simplified. - -* Applicability: -* Mapping -* All Mappings have this attribute. -* Frame -* All classes of Frame return zero for the IsSimple attribute. -* This is because changes can be made to a Frame which affect the -* Mapping represented by the Frame, and so there can be no -* guarantee that the Mapping may not need re-simplifying. Most -* non-Frame Mappings, on the other hand, are immutable and so when -* they are simplified it is certain that they weill remain in a -* simple state. - -*att-- -*/ -astMAKE_GET(Mapping,IsSimple,int,0,((this->flags)&AST__ISSIMPLE_FLAG)) - -/* -*att++ -* Name: -* Nin - -* Purpose: -* Number of input coordinates for a Mapping. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the number of coordinate values required to -* specify an input point for a Mapping (i.e. the number of -* dimensions of the space in which the Mapping's input points -* reside). - -* Applicability: -* Mapping -* All Mappings have this attribute. -* CmpMap -* If a CmpMap's component Mappings are joined in series, then -* its Nin attribute is equal to the Nin attribute of the first -* component (or to the Nout attribute of the second component -* if the the CmpMap's Invert attribute is non-zero). -* -* If a CmpMap's component Mappings are joined in parallel, then -* its Nin attribute is given by the sum of the Nin attributes -* of each component (or to the sum of their Nout attributes if -* the CmpMap's Invert attribute is non-zero). -* Frame -* The Nin attribute for a Frame is always equal to the number -* of Frame axes (Naxes attribute). -* FrameSet -* The Nin attribute of a FrameSet is equal to the number of -* axes (Naxes attribute) of its base Frame (as specified by the -* FrameSet's Base attribute). The Nin attribute value may -* therefore change if a new base Frame is selected. -*att-- -*/ - -/* -*att++ -* Name: -* Nout - -* Purpose: -* Number of output coordinates for a Mapping. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the number of coordinate values generated -* by a Mapping to specify each output point (i.e. the number of -* dimensions of the space in which the Mapping's output points -* reside). - -* Applicability: -* Mapping -* All Mappings have this attribute. -* CmpMap -* If a CmpMap's component Mappings are joined in series, then -* its Nout attribute is equal to the Nout attribute of the -* second component (or to the Nin attribute of the first -* component if the the CmpMap's Invert attribute is non-zero). -* -* If a CmpMap's component Mappings are joined in parallel, then -* its Nout attribute is given by the sum of the Nout attributes -* of each component (or to the sum of their Nin attributes if -* the CmpMap's Invert attribute is non-zero). -* Frame -* The Nout attribute for a Frame is always equal to the number -* of Frame axes (Naxes attribute). -* FrameSet -* The Nout attribute of a FrameSet is equal to the number of -* FrameSet axes (Naxes attribute) which, in turn, is equal to -* the Naxes attribute of the FrameSet's current Frame (as -* specified by the Current attribute). The Nout attribute value -* may therefore change if a new current Frame is selected. -*att-- -*/ - -/* -*att++ -* Name: -* Report - -* Purpose: -* Report transformed coordinates? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls whether coordinate values are reported -* whenever a Mapping is used to transform a set of points. If its -* value is zero (the default), no report is made. However, if it -* is non-zero, the coordinates of each point are reported (both -* before and after transformation) by writing them to standard -* output. -* -* This attribute is provided as an aid to debugging, and to avoid -* having to report values explicitly in simple programs. - -* Applicability: -* Mapping -* All Mappings have this attribute. -* CmpMap -* When applied to a compound Mapping (CmpMap), only the Report -* attribute of the CmpMap, and not those of its component -* Mappings, is used. Coordinate information is never reported -* for the component Mappings individually, only for the -* complete CmpMap. -* Frame -* When applied to any Frame, the formatting capabilities of the -c Frame (as provided by the astFormat function) will be used to -f Frame (as provided by the AST_FORMAT function) will be used to -* format the reported coordinates. -* FrameSet -* When applied to any FrameSet, the formatting capabilities of -* the base and current Frames will be used (as above) to -* individually format the input and output coordinates, as -* appropriate. The Report attribute of a FrameSet is not itself -* affected by selecting a new base or current Frame, but the -* resulting formatting capabilities may be. - -* Notes: -* - Unlike most other attributes, the value of the Report -* attribute is not transferred when a Mapping is copied. Instead, -* its value is undefined (and therefore defaults to zero) in any -* copy. Similarly, it becomes undefined in any external -c representation of a Mapping produced by the astWrite function. -f representation of a Mapping produced by the AST_WRITE routine. -*att-- -*/ -/* This ia a boolean value (0 or 1) with a value of CHAR_MAX when - undefined but yielding a default of zero. */ -astMAKE_CLEAR(Mapping,Report,report,CHAR_MAX) -astMAKE_GET(Mapping,Report,int,0,( ( this->report == CHAR_MAX ) ? - 0 : this->report )) -astMAKE_SET(Mapping,Report,int,report,( value != 0 )) -astMAKE_TEST(Mapping,Report,( this->report != CHAR_MAX )) - -/* -*att++ -* Name: -* TranForward - -* Purpose: -* Forward transformation defined? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean), read-only. - -* Description: -* This attribute indicates whether a Mapping is able to transform -* coordinates in the "forward" direction (i.e. converting input -* coordinates into output coordinates). If this attribute is -* non-zero, the forward transformation is available. Otherwise, it -* is not. - -* Applicability: -* Mapping -* All Mappings have this attribute. -* CmpMap -* The TranForward attribute value for a CmpMap is given by the -* boolean AND of the value for each component Mapping. -* FrameSet -* The TranForward attribute of a FrameSet applies to the -* transformation which converts between the FrameSet's base -* Frame and its current Frame (as specified by the Base and -* Current attributes). This value is given by the boolean AND -* of the TranForward values which apply to each of the -* individual sub-Mappings required to perform this conversion. -* The TranForward attribute value for a FrameSet may therefore -* change if a new Base or Current Frame is selected. - -* Notes: -* - An error will result if a Mapping with a TranForward value of -* zero is used to transform coordinates in the forward direction. -*att-- -*/ - -/* -*att++ -* Name: -* TranInverse - -* Purpose: -* Inverse transformation defined? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean), readonly. - -* Description: -* This attribute indicates whether a Mapping is able to transform -* coordinates in the "inverse" direction (i.e. converting output -* coordinates back into input coordinates). If this attribute is -* non-zero, the inverse transformation is available. Otherwise, it -* is not. - -* Applicability: -* Mapping -* All Mappings have this attribute. -* CmpMap -* The TranInverse attribute value for a CmpMap is given by the -* boolean AND of the value for each component Mapping. -* FrameSet -* The TranInverse attribute of a FrameSet applies to the -* transformation which converts between the FrameSet's current -* Frame and its base Frame (as specified by the Current and -* Base attributes). This value is given by the boolean AND of -* the TranInverse values which apply to each of the individual -* sub-Mappings required to perform this conversion. -* The TranInverse attribute value for a FrameSet may therefore -* change if a new Base or Current Frame is selected. - -* Notes: -* - An error will result if a Mapping with a TranInverse value of -* zero is used to transform coordinates in the inverse direction. -*att-- -*/ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Mapping objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Mapping objects. - -* Parameters: -* objin -* Pointer to the Mapping to be copied. -* objout -* Pointer to the Mapping being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor exists simply to ensure that the "Report" -* attribute is cleared in any copy made of a Mapping. -*/ - -/* Local Variables: */ - AstMapping *out; /* Pointer to output Mapping */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the output Mapping. */ - out = (AstMapping *) objout; - -/* Clear the output Report attribute. */ - out->report = CHAR_MAX; -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Mapping objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Mapping objects. - -* Parameters: -* obj -* Pointer to the Mapping to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This destructor does nothing and exists only to maintain a -* one-to-one correspondence between destructors and copy -* constructors. -*/ - -/* Return without action. */ -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Mapping objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Mapping class to an output Channel. - -* Parameters: -* this -* Pointer to the Mapping whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstMapping *this; /* Pointer to the Mapping structure */ - int invert; /* Mapping inverted? */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Mapping structure. */ - this = (AstMapping *) this_object; - -/* Write out values representing the instance variables for the - Mapping class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Determine if the Mapping is inverted. The output values - (e.g. number of input and output coordinates) will refer to the - Mapping ***before*** this inversion flag is applied, but we need it - when using (e.g.) the astGetNin/astGetNout methods to determine - which one will return the required value. */ - invert = astGetInvert( this ); - -/* (NB. there is a subtle point here that dictates the extent to which - this inversion flag can be used... All use of methods (such as - astGetInvert, which might be over-ridden by derived classes) must - be restricted to determining the values of "unset" output - quantities only (below). This is because when re-loading the - Mapping, the derived classes will not have been loaded at the point - when these values are re-read - hence any value whose - interpretation depends on these methods cannot be reliably - recovered.) */ - -/* Nin. */ -/* ---- */ -/* Use the instance variable directly to avoid the effect of the - Invert attribute on the private member function. Treat zero as the - default. */ - set = ( this->nin != 0 ); - ival = set ? this->nin : ( !invert ? astGetNin( this ) : - astGetNout( this ) ); - astWriteInt( channel, "Nin", set, 0, ival, - "Number of input coordinates" ); - -/* Nout. */ -/* ----- */ -/* Use the instance variable directly. Treat zero as the default. */ - set = ( this->nout != this->nin ); - ival = set ? this->nout : ( !invert ? astGetNout( this ) : - astGetNin( this ) ); - astWriteInt( channel, "Nout", set, 0, ival, - "Number of output coordinates" ); - -/* IsSimple. */ -/* --------- */ - ival = astGetIsSimple( this ); - astWriteInt( channel, "IsSimp", ival, 0, ival, - ival ? "Mapping has been simplified" : - "Mapping has not been simplified" ); - -/* Invert. */ -/* ------- */ - set = TestInvert( this, status ); - ival = set ? GetInvert( this, status ) : astGetInvert( this ); - astWriteInt( channel, "Invert", set, 0, ival, - ival ? "Mapping inverted" : - "Mapping not inverted" ); - -/* TranForward. */ -/* ------------ */ -/* Use the instance variable directly. Treat 1 as the default. */ - set = ( this->tran_forward == 0 ); - ival = set ? this->tran_forward : ( !invert ? astGetTranForward( this ) : - astGetTranInverse( this ) ); - astWriteInt( channel, "Fwd", set, 0, ival, - ival ? "Forward transformation defined" : - "Forward transformation not defined" ); - -/* TranInverse. */ -/* ------------ */ -/* Use the instance variable directly. Treat 1 as the default. */ - set = ( this->tran_inverse == 0 ); - ival = set ? this->tran_inverse : ( !invert ? astGetTranInverse( this ) : - astGetTranForward( this ) ); - astWriteInt( channel, "Inv", set, 0, ival, - ival ? "Inverse transformation defined" : - "Inverse transformation not defined" ); - -/* Report. */ -/* ------- */ - set = TestReport( this, status ); - ival = set ? GetReport( this, status ) : astGetReport( this ); - astWriteInt( channel, "Report", set, 0, ival, - ival ? "Report coordinate transformations" : - "Don't report coordinate transformations" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAMapping and astCheckMapping functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Mapping,Object) -astMAKE_CHECK(Mapping) - -AstMapping *astInitMapping_( void *mem, size_t size, int init, - AstMappingVtab *vtab, const char *name, - int nin, int nout, - int tran_forward, int tran_inverse, int *status ) { -/* -*+ -* Name: -* astInitMapping - -* Purpose: -* Initialise a Mapping. - -* Type: -* Protected function. - -* Synopsis: -* #include "mapping.h" -* AstMapping *astInitMapping( void *mem, size_t size, int init, -* AstMappingVtab *vtab, const char *name, -* int nin, int nout, -* int tran_forward, int tran_inverse ) - -* Class Membership: -* Mapping initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Mapping object. It allocates memory (if necessary) to accommodate -* the Mapping plus any additional data associated with the derived class. -* It then initialises a Mapping structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Mapping at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Mapping is to be initialised. -* This must be of sufficient size to accommodate the Mapping data -* (sizeof(Mapping)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Mapping (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Mapping -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Mapping's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Mapping. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* nin -* The number of coordinate values per input point. -* nout -* The number of coordinate vales per output point. -* tran_forward -* A non-zero value indicates that the Mapping will be able to -* transform coordinates in the forward direction. A zero value -* indicates that it will not. -* tran_inverse -* A non-zero value indicates that the Mapping will be able to -* transform coordinates in the inverse direction. A zero value -* indicates that it will not. - -* Returned Value: -* A pointer to the new Mapping. - -* Notes: -* - The Mappings produced by this function implement all the basic methods -* defined by the Mapping class. However, their astTransform method does not -* actually perform any coordinate transformation (although it performs all -* necessary argument validation and creates an output PointSet if -* necessary, leaving its coordinate values undefined). -* - This means that Mappings produced by this function are of limited use -* on their own, but may easily be extended by a derived class simply by -* over-riding the astTransform method to add the necessary coordinate -* arithmetic. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstMapping *new; /* Pointer to new Mapping */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitMappingVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check the initialisation values for validity, reporting an error if - necessary. */ - if ( nin < 0 ) { - astError( AST__BADNI, "astInitMapping(%s): Bad number of input " - "coordinates (%d).", status, name, nin ); - astError( AST__BADNI, "This number should be zero or more." , status); - } else if ( nout < 0 ) { - astError( AST__BADNO, "astInitMapping(%s): Bad number of output " - "coordinates (%d).", status, name, nout ); - astError( AST__BADNI, "This number should be zero or more." , status); - } - -/* Initialise an Object structure (the parent class) as the first component - within the Mapping structure, allocating memory if necessary. */ - new = (AstMapping *) astInitObject( mem, size, 0, - (AstObjectVtab *) vtab, name ); - - if ( astOK ) { - -/* Initialise the Mapping data. */ -/* ---------------------------- */ -/* Store the numbers of input and output coordinates. */ - new->nin = nin; - new->nout = nout; - -/* Store the flags indicating which coordinate transformations are - defined (constrain these values to 0 or 1). */ - new->tran_forward = ( tran_forward != 0 ); - new->tran_inverse = ( tran_inverse != 0 ); - -/* Initialise other attributes to their undefined values. */ - new->invert = CHAR_MAX; - new->report = CHAR_MAX; - new->flags = 0; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstMapping *astLoadMapping_( void *mem, size_t size, - AstMappingVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadMapping - -* Purpose: -* Load a Mapping. - -* Type: -* Protected function. - -* Synopsis: -* #include "mapping.h" -* AstMapping *astLoadMapping( void *mem, size_t size, -* AstMappingVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* Mapping loader. - -* Description: -* This function is provided to load a new Mapping using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Mapping structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Mapping at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the Mapping is to be -* loaded. This must be of sufficient size to accommodate the -* Mapping data (sizeof(Mapping)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Mapping (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Mapping structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstMapping) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Mapping. If this is NULL, a pointer -* to the (static) virtual function table for the Mapping class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Mapping" is used instead. - -* Returned Value: -* A pointer to the new Mapping. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *new; /* Pointer to the new Mapping */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Mapping. In this case the - Mapping belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstMapping ); - vtab = &class_vtab; - name = "Mapping"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitMappingVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Mapping. */ - new = astLoadObject( mem, size, (AstObjectVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Mapping" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Initialise bitwise flags to zero. */ - new->flags = 0; - -/* Nin. */ -/* ---- */ - new->nin = astReadInt( channel, "nin", 0 ); - if ( new->nin < 0 ) new->nin = 0; - -/* Nout. */ -/* ----- */ - new->nout = astReadInt( channel, "nout", new->nin ); - if ( new->nout < 0 ) new->nout = 0; - -/* Invert. */ -/* ------- */ - new->invert = astReadInt( channel, "invert", CHAR_MAX ); - if ( TestInvert( new, status ) ) SetInvert( new, new->invert, status ); - -/* IsSimple. */ -/* --------- */ - if( astReadInt( channel, "issimp", 0 ) ) new->flags |= AST__ISSIMPLE_FLAG; - -/* TranForward. */ -/* ------------ */ - new->tran_forward = ( astReadInt( channel, "fwd", 1 ) != 0 ); - -/* TranInverse. */ -/* ------------ */ - new->tran_inverse = ( astReadInt( channel, "inv", 1 ) != 0 ); - -/* Report. */ -/* ------- */ - new->report = astReadInt( channel, "report", CHAR_MAX ); - if ( TestReport( new, status ) ) SetReport( new, new->report, status ); - -/* If an error occurred, clean up by deleting the new Mapping. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Mapping pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions - defined by this class. Each simply checks the global error status - and then locates and executes the appropriate member function, - using the function pointer stored in the object's virtual function - table (this pointer is located using the astMEMBER macro defined in - "object.h"). - - Note that the member function may not be the one defined here, as - it may have been over-ridden by a derived class. However, it should - still have the same interface. */ - -void astDecompose_( AstMapping *this, AstMapping **map1, AstMapping **map2, - int *series, int *invert1, int *invert2, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Mapping,Decompose))( this, map1, map2, series, invert1, invert2, status ); -} -int astGetNin_( AstMapping *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Mapping,GetNin))( this, status ); -} -int astGetNout_( AstMapping *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Mapping,GetNout))( this, status ); -} -int astGetIsLinear_( AstMapping *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Mapping,GetIsLinear))( this, status ); -} -int astGetTranForward_( AstMapping *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Mapping,GetTranForward))( this, status ); -} -int astGetTranInverse_( AstMapping *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Mapping,GetTranInverse))( this, status ); -} -void astInvert_( AstMapping *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Mapping,Invert))( this, status ); -} -void astMapBox_( AstMapping *this, - const double lbnd_in[], const double ubnd_in[], int forward, - int coord_out, double *lbnd_out, double *ubnd_out, - double xl[], double xu[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Mapping,MapBox))( this, lbnd_in, ubnd_in, forward, - coord_out, lbnd_out, ubnd_out, xl, xu, status ); -} -int astMapList_( AstMapping *this, int series, int invert, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Mapping,MapList))( this, series, invert, - nmap, map_list, invert_list, status ); -} -int *astMapSplit_( AstMapping *this, int nin, const int *in, AstMapping **map, - int *status ){ - int *result = NULL; - AstMapping *tmap; - - if( map ) *map = NULL; - if ( !astOK ) return NULL; - - result = (**astMEMBER(this,Mapping,MapSplit))( this, nin, in, &tmap, status ); - if( tmap ) { - *map = astCopy( tmap ); - tmap = astAnnul( tmap ); - } - - return result; -} -int astMapMerge_( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { - - if ( !astOK || astDoNotSimplify( this ) ) return -1; - return (**astMEMBER(this,Mapping,MapMerge))( this, where, series, nmap, - map_list, invert_list, status ); -} -int astDoNotSimplify_( AstMapping *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Mapping,DoNotSimplify))( this, status ); -} -void astReportPoints_( AstMapping *this, int forward, - AstPointSet *in_points, AstPointSet *out_points, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Mapping,ReportPoints))( this, forward, - in_points, out_points, status ); -} -#define MAKE_RESAMPLE_(X,Xtype) \ -int astResample##X##_( AstMapping *this, int ndim_in, const int *lbnd_in, \ - const int *ubnd_in, const Xtype *in, \ - const Xtype *in_var, int interp, \ - void (* finterp)( void ), const double *params, \ - int flags, double tol, int maxpix, Xtype badval, \ - int ndim_out, \ - const int *lbnd_out, const int *ubnd_out, \ - const int *lbnd, const int *ubnd, Xtype *out, \ - Xtype *out_var, int *status ) { \ - if ( !astOK ) return 0; \ - return (**astMEMBER(this,Mapping,Resample##X))( this, ndim_in, lbnd_in, \ - ubnd_in, in, in_var, \ - interp, finterp, params, \ - flags, tol, maxpix, \ - badval, ndim_out, \ - lbnd_out, ubnd_out, \ - lbnd, ubnd, \ - out, out_var, status ); \ -} -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_RESAMPLE_(LD,long double) -#endif -MAKE_RESAMPLE_(D,double) -MAKE_RESAMPLE_(F,float) -MAKE_RESAMPLE_(L,long int) -MAKE_RESAMPLE_(UL,unsigned long int) -MAKE_RESAMPLE_(I,int) -MAKE_RESAMPLE_(UI,unsigned int) -MAKE_RESAMPLE_(K,INT_BIG) -MAKE_RESAMPLE_(UK,UINT_BIG) -MAKE_RESAMPLE_(S,short int) -MAKE_RESAMPLE_(US,unsigned short int) -MAKE_RESAMPLE_(B,signed char) -MAKE_RESAMPLE_(UB,unsigned char) -#undef MAKE_RESAMPLE_ - -#define MAKE_REBIN_(X,Xtype) \ -void astRebin##X##_( AstMapping *this, double wlim, int ndim_in, const int *lbnd_in, \ - const int *ubnd_in, const Xtype *in, \ - const Xtype *in_var, int interp, \ - const double *params, \ - int flags, double tol, int maxpix, Xtype badval, \ - int ndim_out, \ - const int *lbnd_out, const int *ubnd_out, \ - const int *lbnd, const int *ubnd, Xtype *out, \ - Xtype *out_var, int *status ) { \ - if ( !astOK ) return; \ - (**astMEMBER(this,Mapping,Rebin##X))( this, wlim, ndim_in, lbnd_in, \ - ubnd_in, in, in_var, \ - interp, params, \ - flags, tol, maxpix, \ - badval, ndim_out, \ - lbnd_out, ubnd_out, \ - lbnd, ubnd, \ - out, out_var, status ); \ -} -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_REBIN_(LD,long double) -#endif -MAKE_REBIN_(D,double) -MAKE_REBIN_(F,float) -MAKE_REBIN_(I,int) -MAKE_REBIN_(B,signed char) -MAKE_REBIN_(UB,unsigned char) -#undef MAKE_REBIN_ - - -#define MAKE_REBINSEQ_(X,Xtype) \ -void astRebinSeq##X##_( AstMapping *this, double wlim, int ndim_in, const int *lbnd_in, \ - const int *ubnd_in, const Xtype *in, \ - const Xtype *in_var, int interp, \ - const double *params, \ - int flags, double tol, int maxpix, Xtype badval, \ - int ndim_out, \ - const int *lbnd_out, const int *ubnd_out, \ - const int *lbnd, const int *ubnd, Xtype *out, \ - Xtype *out_var, double *weights, int64_t *nused, \ - int *status ) { \ - if ( !astOK ) return; \ - (**astMEMBER(this,Mapping,RebinSeq##X))( this, wlim, ndim_in, lbnd_in, \ - ubnd_in, in, in_var, \ - interp, params, \ - flags, tol, maxpix, \ - badval, ndim_out, \ - lbnd_out, ubnd_out, \ - lbnd, ubnd, out, out_var, \ - weights, nused, status ); \ -} - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_REBINSEQ_(LD,long double) -#endif -MAKE_REBINSEQ_(D,double) -MAKE_REBINSEQ_(F,float) -MAKE_REBINSEQ_(I,int) -MAKE_REBINSEQ_(B,signed char) -MAKE_REBINSEQ_(UB,unsigned char) - -#undef MAKE_REBINSEQ_ - -double astRate_( AstMapping *this, double *at, int ax1, int ax2, int *status ){ - astDECLARE_GLOBALS - - if ( !astOK ) return AST__BAD; - - astGET_GLOBALS(this); - - if( ax1 < 0 || ax1 >= astGetNout( this ) ) { - astError( AST__AXIIN, "astRate(%s): Invalid output index (%d) " - "specified - should be in the range 1 to %d.", status, - astGetClass( this ), ax1 + 1, astGetNout( this ) ); - - } else if( ax2 < 0 || ax2 >= astGetNin( this ) ) { - astError( AST__AXIIN, "astRate(%s): Invalid input index (%d) " - "specified - should be in the range 1 to %d.", status, - astGetClass( this ), ax2 + 1, astGetNin( this ) ); - } - - if( rate_disabled ) { - return ( at[ ax2 ] != AST__BAD ) ? 1.0 : AST__BAD; - } else { - return (**astMEMBER(this,Mapping,Rate))( this, at, ax1, ax2, status ); - } -} -AstMapping *astRemoveRegions_( AstMapping *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Mapping,RemoveRegions))( this, status ); -} - -AstMapping *astSimplify_( AstMapping *this, int *status ) { - AstMapping *result; - AstErrorContext error_context; - - if ( !astOK ) return NULL; - -/* If this Mapping has already been simplified, or if it cannot be - simplified (e.g. because it is a Frame) we just returned a clone - of the upplied pointer. */ - if( !astGetIsSimple( this ) && !astDoNotSimplify( this ) ) { - -/* Start a new error reporting context. This is done so that errors - caused by the siplification process attempting to do inappropriate things - with the supplied mapping can be caught. */ - astErrorBegin( &error_context ); - -/* Do the simplification. */ - result = (**astMEMBER(this,Mapping,Simplify))( this, status ); - -/* If a result was returned, indicate it has been simplified and so does - not need to be simplified again. */ - if( result ) { - result->flags |= AST__ISSIMPLE_FLAG; - -/* If the simplification process failed due to the supplied Mappings - being inappropriate (e.g. because it attempted to ue an undefined - transformation), clear the error status and return a clone of the - supplied Mapping. */ - } else if( astStatus == AST__NODEF || astStatus == AST__TRNND ){ - astClearStatus; - result = astClone( this ); - } - -/* End the error reporting context. */ - astErrorEnd( &error_context ); - -/* If the Mapping has already been simplified just return a clone. */ - } else { - result = astClone( this ); - } - - return result; -} - -AstPointSet *astTransform_( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { - AstPointSet *result; - if ( !astOK ) return NULL; - result = (**astMEMBER(this,Mapping,Transform))( this, in, forward, out, status ); - (void) astReplaceNaN( result ); - return result; -} -void astTran1_( AstMapping *this, int npoint, const double xin[], - int forward, double xout[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Mapping,Tran1))( this, npoint, xin, forward, xout, status ); -} -void astTran2_( AstMapping *this, - int npoint, const double xin[], const double yin[], - int forward, double xout[], double yout[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Mapping,Tran2))( this, npoint, xin, yin, - forward, xout, yout, status ); -} -void astTranGrid_( AstMapping *this, int ncoord_in, const int lbnd[], - const int ubnd[], double tol, int maxpix, int forward, - int ncoord_out, int outdim, double *out, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Mapping,TranGrid))( this, ncoord_in, lbnd, ubnd, tol, - maxpix, forward, ncoord_out, outdim, - out, status ); -} -void astTranN_( AstMapping *this, int npoint, - int ncoord_in, int indim, const double *in, - int forward, int ncoord_out, int outdim, double *out, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Mapping,TranN))( this, npoint, - ncoord_in, indim, in, - forward, ncoord_out, outdim, out, status ); -} -void astTranP_( AstMapping *this, int npoint, - int ncoord_in, const double *ptr_in[], - int forward, int ncoord_out, double *ptr_out[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Mapping,TranP))( this, npoint, - ncoord_in, ptr_in, - forward, ncoord_out, ptr_out, status ); -} -int astLinearApprox_( AstMapping *this, const double *lbnd, - const double *ubnd, double tol, double *fit, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Mapping,LinearApprox))( this, lbnd, ubnd, tol, fit, status ); -} - - -int astQuadApprox_( AstMapping *this, const double lbnd[2], - const double ubnd[2], int nx, int ny, double *fit, - double *rms, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Mapping,QuadApprox))( this, lbnd, ubnd, nx, - ny, fit, rms, status ); -} - - - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -void DecomposeId_( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); -void MapBoxId_( AstMapping *, const double [], const double [], int, int, double *, double *, double [], double [], int * ); -double astRateId_( AstMapping *, double *, int, int, int * ); -void astMapSplitId_( AstMapping *, int, const int *, int *, AstMapping **, - int * ); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -void astDecomposeId_( AstMapping *this, AstMapping **map1, - AstMapping **map2, int *series, int *invert1, - int *invert2, int *status ) { -/* -*++ -* Name: -c astDecompose -f AST_DECOMPOSE - -* Purpose: -* Decompose a Mapping into two component Mappings. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astDecompose( AstMapping *this, AstMapping **map1, -c AstMapping **map2, int *series, int *invert1, -c int *invert2 ) -f CALL AST_DECOMPOSE( THIS, MAP1, MAP2, SERIES, INVERT1, INVERT2, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -c This function returns pointers to two Mappings which, when applied -f This routine returns pointers to two Mappings which, when applied -* either in series or parallel, are equivalent to the supplied Mapping. -* -* Since the Frame class inherits from the Mapping class, Frames can -* be considered as special types of Mappings and so this method can -* be used to decompose either CmpMaps or CmpFrames. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping. -c map1 -f MAP1 = INTEGER (Returned) -c Address of a location to receive a pointer to first component -f A pointer to first component -* Mapping. -c map2 -f MAP2 = INTEGER (Returned) -c Address of a location to receive a pointer to second component -f A pointer to second component -* Mapping. -c series -f SERIES = LOGICAL (Returned) -c Address of a location to receive a value indicating if the -c component Mappings are applied in series or parallel. A non-zero -c value means that the supplied Mapping is equivalent to applying map1 -c followed by map2 in series. A zero value means that the supplied -c Mapping is equivalent to applying map1 to the lower numbered axes -c and map2 to the higher numbered axes, in parallel. -f Indicates if the -f component Mappings are applied in series or parallel. A .TRUE. -f value means that the supplied Mapping is equivalent to applying MAP1 -f followed by MAP2 in series. A zero value means that the supplied -f Mapping is equivalent to applying MAP1 to the lower numbered axes -f and MAP2 to the higher numbered axes, in parallel. -c invert1 -f INVERT1 = INTEGER (Returned) -c The value of the Invert attribute to be used with map1. -f The value of the Invert attribute to be used with MAP1. -c invert2 -f INVERT2 = INTEGER (Returned) -c The value of the Invert attribute to be used with map2. -f The value of the Invert attribute to be used with MAP2. - -* Applicability: -* CmpMap -c If the supplied Mapping is a CmpMap, then map1 and map2 will be -f If the supplied Mapping is a CmpMap, then MAP1 and MAP2 will be -* returned holding pointers to the component Mappings used to -* create the CmpMap, either in series or parallel. Note, changing -* the Invert attribute of either of the component Mappings using -* the returned pointers will have no effect on the supplied CmpMap. -* This is because the CmpMap remembers and uses the original settings -* of the Invert attributes (that is, the values of the Invert -* attributes when the CmpMap was first created). These are the -c Invert values which are returned in invert1 and invert2. -f Invert values which are returned in INVERT1 and INVERT2. -* TranMap -c If the supplied Mapping is a TranMap, then map1 and map2 will be -f If the supplied Mapping is a TranMap, then MAP1 and MAP2 will be -* returned holding pointers to the forward and inverse Mappings -* represented by the TranMap (zero will be returned for -c series). -f SERIES). -* Note, changing the Invert attribute of -* either of the component Mappings using the returned pointers will -* have no effect on the supplied TranMap. This is because the TranMap -* remembers and uses the original settings of the Invert attributes -* (that is, the values of the Invert attributes when the TranMap was -* first created). These are the -c Invert values which are returned in invert1 and invert2. -f Invert values which are returned in INVERT1 and INVERT2. -* Mapping -c For any class of Mapping other than a CmpMap, map1 will be -c returned holding a clone of the supplied Mapping pointer, and map2 -c will be returned holding a NULL pointer. Invert1 will be returned -c holding the current value of the Invert attribute for the supplied -c Mapping, and invert2 will be returned holding zero. -f For any class of Mapping other than a CmpMap, MAP1 will be -f returned holding a clone of the supplied Mapping pointer, and MAP2 -f will be returned holding AST__NULL. INVERT1 will be returned -f holding the current value of the Invert attribute for the supplied -f Mapping, and INVERT2 will be returned holding zero. -* CmpFrame -c If the supplied Mapping is a CmpFrame, then map1 and map2 will be -f If the supplied Mapping is a CmpFrame, then MAP1 and MAP2 will be -* returned holding pointers to the component Frames used to -* create the CmpFrame. The component Frames are considered to be in -* applied in parallel. -* Frame -c For any class of Frame other than a CmpFrame, map1 will be -c returned holding a clone of the supplied Frame pointer, and map2 -c will be returned holding a NULL pointer. -f For any class of Frame other than a CmpFrame, MAP1 will be -f returned holding a clone of the supplied Frame pointer, and MAP2 -f will be returned holding AST__NULL. - -* Notes: -* - The returned Invert values should be used in preference to the -* current values of the Invert attribute in map1 and map2. This is -* because the attributes may have changed value since the Mappings -* were combined. -* - Any changes made to the component Mappings using the returned -* pointers will be reflected in the supplied Mapping. - -*-- - -* Implementation Notes: -* This function implements the public interface for the -* astDecompose method. It is identical to astDecompose_ except for -* the following: -* -* - ID values are returned via the "map1" and "map2" parameters -* instead of true C pointers. This is required because this -* conversion cannot be performed by the macro that invokes the -* function. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the normal astDecompose_ function to decompose the Mapping. */ - astDecompose( this, map1, map2, series, invert1, invert2 ); - -/* If required, return ID values for the component Mappings. */ - if ( map1 ) *map1 = astMakeId( *map1 ); - if ( map2 ) *map2 = astMakeId( *map2 ); - -} - -void astMapBoxId_( AstMapping *this, - const double lbnd_in[], const double ubnd_in[], - int forward, int coord_out, - double *lbnd_out, double *ubnd_out, - double xl[], double xu[], int *status ) { -/* -*++ -* Name: -c astMapBox -f AST_MAPBOX - -* Purpose: -* Find a bounding box for a Mapping. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astMapBox( AstMapping *this, -c const double lbnd_in[], const double ubnd_in[], -c int forward, int coord_out, -c double *lbnd_out, double *ubnd_out, -c double xl[], double xu[] ); -f CALL AST_MAPBOX( THIS, LBND_IN, UBND_IN, FORWARD, COORD_OUT, -f LBND_OUT, UBND_OUT, XL, XU, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -c This function allows you to find the "bounding box" which just -c encloses another box after it has been transformed by a Mapping -c (using either its forward or inverse transformation). A typical -c use might be to calculate the size of an image after being -c transformed by a Mapping. -f This routine allows you to find the "bounding box" which just -f encloses another box after it has been transformed by a Mapping -f (using either its forward or inverse transformation). A typical -f use might be to calculate the size of an image after being -f transformed by a Mapping. -* -c The function works on one dimension at a time. When supplied -c with the lower and upper bounds of a rectangular region (box) of -c input coordinate space, it finds the lowest and highest values -c taken by a nominated output coordinate within that -c region. Optionally, it also returns the input coordinates where -c these bounding values are attained. It should be used repeatedly -c to obtain the extent of the bounding box in more than one -c dimension. -f The routine works on one dimension at a time. When supplied with -f the lower and upper bounds of a rectangular region (box) of -f input coordinate space, it finds the lowest and highest values -f taken by a nominated output coordinate within that region. It -f also returns the input coordinates where these bounding values -f are attained. It should be used repeatedly to obtain the extent -f of the bounding box in more than one dimension. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping. -c lbnd_in -f LBND_IN( * ) = DOUBLE PRECISION (Given) -c Pointer to an array of double, with one element for each -c Mapping input coordinate. This should contain the lower bound -c of the input box in each input dimension. -f An array with one element for each Mapping input -f coordinate. This should contain the lower bound of the input -f box in each input dimension. -c ubnd_in -f UBND_IN( * ) = DOUBLE PRECISION (Given) -c Pointer to an array of double, with one element for each -c Mapping input coordinate. This should contain the upper bound -c of the input box in each input dimension. -f An array with one element for each Mapping input -f coordinate. This should contain the upper bound of the input -f box in each input dimension. -* -* Note that it is permissible for the upper bound to be less -* than the corresponding lower bound, as the values will simply -* be swapped before use. -c forward -f FORWARD = LOGICAL (Given) -c If this value is non-zero, then the Mapping's forward -c transformation will be used to transform the input -c box. Otherwise, its inverse transformation will be used. -f If this value is .TRUE., then the Mapping's forward -f transformation will be used to transform the input -f box. Otherwise, its inverse transformation will be used. -* -c (If the inverse transformation is selected, then references -c to "input" and "output" coordinates in this description -c should be transposed. For example, the size of the "lbnd_in" -c and "ubnd_in" arrays should match the number of output -c coordinates, as given by the Mapping's Nout -c attribute. Similarly, the "coord_out" parameter, below, -c should nominate one of the Mapping's input coordinates.) -f (If the inverse transformation is selected, then references -f to "input" and "output" coordinates in this description -f should be transposed. For example, the size of the LBND_IN -f and UBND_IN arrays should match the number of output -f coordinates, as given by the Mapping's Nout attribute. -f Similarly, the COORD_OUT argument, below, should nominate one -f of the Mapping's input coordinates.) -c coord_out -f COORD_OUT = INTEGER (Given) -* The index of the output coordinate for which the lower and -* upper bounds are required. This value should be at least one, -* and no larger than the number of Mapping output coordinates. -c lbnd_out -f LBND_OUT = DOUBLE PRECISION (Returned) -c Pointer to a double in which to return the lowest value taken -c by the nominated output coordinate within the specified -c region of input coordinate space. -f The lowest value taken by the nominated output coordinate -f within the specified region of input coordinate space. -c ubnd_out -f UBND_OUT = DOUBLE PRECISION (Returned) -c Pointer to a double in which to return the highest value -c taken by the nominated output coordinate within the specified -c region of input coordinate space. -f The highest value taken by the nominated output coordinate -f within the specified region of input coordinate space. -c xl -f XL( * ) = DOUBLE PRECISION (Returned) -c An optional pointer to an array of double, with one element -c for each Mapping input coordinate. If given, this array will -c be filled with the coordinates of an input point (although -c not necessarily a unique one) for which the nominated output -c coordinate attains the lower bound value returned in -c "*lbnd_out". -c -c If these coordinates are not required, a NULL pointer may be -c supplied. -f An array with one element for each Mapping input -f coordinate. This will return the coordinates of an input -f point (although not necessarily a unique one) for which the -f nominated output coordinate attains the lower bound value -f returned in LBND_OUT. -c xu -f XU( * ) = DOUBLE PRECISION (Returned) -c An optional pointer to an array of double, with one element -c for each Mapping input coordinate. If given, this array will -c be filled with the coordinates of an input point (although -c not necessarily a unique one) for which the nominated output -c coordinate attains the upper bound value returned in -c "*ubnd_out". -c -c If these coordinates are not required, a NULL pointer may be -c supplied. -f An array with one element for each Mapping input -f coordinate. This will return the coordinates of an input -f point (although not necessarily a unique one) for which the -f nominated output coordinate attains the upper bound value -f returned in UBND_OUT. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Any input points which are transformed by the Mapping to give -* output coordinates containing the value AST__BAD are regarded as -* invalid and are ignored. They will make no contribution to -* determining the output bounds, even although the nominated -* output coordinate might still have a valid value at such points. -c - An error will occur if the required output bounds cannot be -c found. Typically, this might happen if all the input points -c which the function considers turn out to be invalid (see -c above). The number of points considered before generating such -c an error is quite large, so this is unlikely to occur by -c accident unless valid points are restricted to a very small -c subset of the input coordinate space. -f - An error will occur if the required output bounds cannot be -f found. Typically, this might happen if all the input points -f which the routine considers turn out to be invalid (see -f above). The number of points considered before generating such -f an error is quite large, so this is unlikely to occur by -f accident unless valid points are restricted to a very small -f subset of the input coordinate space. -c - The values returned via "lbnd_out", "ubnd_out", "xl" and "xu" -c will be set to the value AST__BAD if this function should fail -c for any reason. Their initial values on entry will not be -c altered if the function is invoked with the AST error status -c set. -f - The values returned via LBND_OUT, UBND_OUT, XL and XU will be -f set to the value AST__BAD if this routine should fail for any -f reason. Their initial values on entry will not be altered if the -f routine is invoked with STATUS set to an error value. -*-- - -* Implementation Notes: -* This function implements the public interface for the astMapBox -* method. It is identical to astMapBox_ except that the nominated -* output coordinate given in "coord_out" is decremented by one -* before use. This is to allow the public interface to use -* one-based coordinate numbering (internally, zero-based -* coordinate numbering is used). -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the protected version of this function with the "coord_out" - value decremented. */ - astMapBox( this, lbnd_in, ubnd_in, forward, coord_out - 1, - lbnd_out, ubnd_out, xl, xu ); -} - -double astRateId_( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -*++ -* Name: -c astRate -f AST_RATE - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c double astRate( AstMapping *this, double *at, int ax1, int ax2 ) -f RESULT = AST_RATE( THIS, AT, AX1, AX2, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -c This function -f This routine -* evaluates the rate of change of a specified output of the supplied -* Mapping with respect to a specified input, at a specified input -* position. -* -* The result is estimated by interpolating the function using a -* fourth order polynomial in the neighbourhood of the specified -* position. The size of the neighbourhood used is chosen to minimise -* the RMS residual per unit length between the interpolating -* polynomial and the supplied Mapping function. This method produces -* good accuracy but can involve evaluating the Mapping 100 or more -* times. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping to be applied. -c at -f AT( * ) = DOUBLE PRECISION (Given) -c The address of an -f An -* array holding the axis values at the position at which the rate -* of change is to be evaluated. The number of elements in this -* array should equal the number of inputs to the Mapping. -c ax1 -f AX1 = INTEGER (Given) -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 1 for the first output). -c ax2 -f AX2 = INTEGER (Given) -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 1 for the first -* input). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astRate() -f AST_RATE = DOUBLE PRECISION -c The rate of change of Mapping output "ax1" with respect to input -c "ax2", evaluated at "at", or AST__BAD if the value cannot be -c calculated. -f The rate of change of Mapping output AX1 with respect to input -f AX2, evaluated at AT, or AST__BAD if the value cannot be -f calculated. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*-- - -* Implementation Notes: -* This function implements the public interface for the astRate -* method. It is identical to astRate_ except that the nominated -* coordinates given in "ax1" and "ax2" are decremented by one -* before use. This is to allow the public interface to use -* one-based coordinate numbering (internally, zero-based -* coordinate numbering is used). -*/ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Invoke the protected version of this function with the axis indices - decremented. */ - return astRate( this, at, ax1 - 1, ax2 - 1 ); -} - -void astMapSplitId_( AstMapping *this, int nin, const int *in, int *out, - AstMapping **map, int *status ){ -/* -*++ -* Name: -c astMapSplit -f AST_MAPSPLIT - -* Purpose: -* Split a Mapping up into parallel component Mappings. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "mapping.h" -c void astMapSplit( AstMapping *this, int nin, const int *in, int *out, -c AstMapping **map ) -f CALL AST_MAPSPLIT( THIS, NIN, IN, OUT, MAP, STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -c This function -f This routine -* creates a new Mapping which connects specified inputs within a -* supplied Mapping to the corresponding outputs of the supplied Mapping. -* This is only possible if the specified inputs correspond to some -* subset of the Mapping outputs. That is, there must exist a subset of -* the Mapping outputs for which each output depends only on the selected -* Mapping inputs, and not on any of the inputs which have not been -* selected. Also, any output which is not in this subset must not depend -* on any of the selected inputs. If these conditions are not met by the -* supplied Mapping, then -c a NULL -f an AST__NULL -* Mapping pointer is returned. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Mapping to be split. -c nin -f NIN = INTEGER (Given) -c The number of inputs to pick from "this". -f The number of inputs to pick from THIS. -c in -f IN( NIN ) = INTEGER (Given) -c Pointer to an -f An -* array holding the indices within the supplied Mapping of the inputs -* which are to be picked from the Mapping. -c This array should have "nin" elements. -* If "Nin" is the number of inputs of the supplied Mapping, then each -* element should have a value in the range 1 to Nin. -c out -f OUT( * ) = INTEGER (Returned) -c Pointer to an -f An -* array in which to return the indices of the outputs of the supplied -* Mapping which are fed by the picked inputs. A value of one is -* used to refer to the first Mapping output. The supplied array should -* have a length at least equal to the number of outputs in the -* supplied Mapping. The number of values stored in the array on -* exit will equal the number of outputs in the returned Mapping. -* The i'th element in the returned array holds the index within -* the supplied Mapping which corresponds to the i'th output of -* the returned Mapping. -c map -f MAP = INTEGER (Returned) -c Address of a location at which to return a pointer to the -f The -* returned Mapping. This Mapping will have -c "nin" inputs (the number of outputs may be different to "nin"). NULL -f NIN inputs (the number of outputs may be different to NIN). AST__NULL -* is returned if the supplied Mapping has no subset of outputs which -* depend only on the selected inputs. The returned Mapping is a -* deep copy of the required parts of the supplied Mapping. - -* Notes: -* - If this -c function -f routine -* is invoked with the global error status set, or if it should fail for -* any reason, then -c a NULL value -f AST__NULL -* will be returned for -c the "map" pointer. -f MAP. -*-- - -* Implementation Notes: -* - This function implements the astMapSplit method available via the -* public interface to the Mapping class and uses 1-based axis indices. -* The protected interface method is provided by the astMapSplit function -* and uses zero-based axis indices. Also, an ID value is returned for -* "map" rather than a pointer. -*/ - -/* Local Variables: */ - int *in_zero; /* Pointer to array of zero-based input indices */ - int *result; /* Pointer to array of zero-based output indices*/ - int i; /* Axis index */ - int nout; /* No of outputs */ - -/* Initialise */ - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Decrement the axis indices by 1. */ - in_zero = astMalloc( sizeof( int )*(size_t) nin ); - if( in_zero ) { - for( i = 0; i < nin; i++ ) in_zero[ i ] = in[ i ] - 1; - -/* Invoked the protected astMapSplit functon. */ - result = astMapSplit( this, nin, in_zero, map ); - -/* If succesful, copy the output axes to the supplied array. */ - if( result ) { - nout = astGetNout( *map ); - for( i = 0; i < nout; i++ ) out[ i ] = result[ i ] + 1; - -/* Free resurces. */ - result = astFree( result ); - } - in_zero = astFree( in_zero ); - } - -/* Free the returned Mapping if an error has occurred. */ - if( !astOK ) *map = astAnnul( *map ); - -/* Return an ID value for the Mapping. */ - *map = astMakeId( *map ); -} - - - - - - - - diff --git a/ast/mapping.h b/ast/mapping.h deleted file mode 100644 index 7b63fa2..0000000 --- a/ast/mapping.h +++ /dev/null @@ -1,856 +0,0 @@ -#if !defined( MAPPING_INCLUDED ) /* Include this file only once */ -#define MAPPING_INCLUDED -/* -*++ -* Name: -* mapping.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Mapping class. - -* Invocation: -* #include "mapping.h" - -* Description: -* This include file defines the interface to the Mapping class and -* provides the type definitions, function prototypes and macros, etc. -* needed to use this class. -* -* The Mapping class provides basic facilities for transforming a -* set of points to give a new set of points and for resampling -* grids of data. However, it does not have a constructor -* function. This is because the class only forms a template for -* deriving new classes which themselves implement specific forms -* of coordinate transformation. They do this by extending the -* protected astTransform method provided by this class. - -* Inheritance: -* The Mapping class inherits from the Object class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* Nin (integer) -* A read-only attribute giving the number of input coordinate -* values required per point by a Mapping (i.e. the number of -* dimensions of the space in which input points reside). -* Nout (integer) -* A read-only attribute giving the number of output coordinate -* values generated per point by a Mapping (i.e. the number of -* dimensions of the space in which output points reside). -* Invert (integer) -* A boolean value (0 or 1) which controls which of a Mapping's -* two possible coordinate transformations is considered the -* "forward" transformation and which is the "inverse" -* transformation. If this value is zero (the default), the -* behaviour will be as defined when the Mapping was first -* created. If it is non-zero, the transformations will be -* inter-changed, so that the Mapping displays the inverse of -* its original behaviour. -* -* Note that inverting the boolean sense of the Invert attribute -* will cause the values of the Nin/Nout and -* TranForward/TranInverse attributes to be interchanged. -* Report (integer) -* A boolean value (0 or 1) which controls whether to report -* coordinate values when a Mapping is used to transform a set -* of points. If this value is zero (the default), no report is -* made. If it is non-zero, the coordinates of each point -* (before and after transformation) are reported by writing -* them to standard output. -* -* This attribute is intended as an aid to debugging and to save -* having to report values explicitly in simple programs. -* Unlike other attributes, the value of the Report attribute is -* not inherited when a Mapping is copied (its value is -* initially undefined, and therefore defaults to zero, in any -* copy). -* IsSimple (boolean) -* A read-only attribute indicating if the Mapping has been -* simpified. -* TranForward (integer) -* A read-only boolean value (0 or 1) which indicates whether a -* Mapping is able to transform coordinates in the "forward" -* direction (i.e. converting input coordinates into output -* coordinates). -* TranInverse (integer) -* A read-only boolean value (0 or 1) which indicates whether a -* Mapping is able to transform coordinates in the "inverse" -* direction (i.e. converting output coordinates back into input -* coordinates). - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astClearAttrib -* Clear an attribute value for a Mapping. -* astGetAttrib -* Get an attribute value for a Mapping. -* astSetAttrib -* Set an attribute value for a Mapping. -* astTestAttrib -* Test if an attribute value has been set for a Mapping. - -* New Methods Defined: -* Public: -* astDecompose -* Decompose a Mapping into two component Mappings. -* astInvert -* Invert a Mapping. -* astLinearApprox -* Form a linear approximation to a Mapping -* astMapBox -* Find a bounding box for a Mapping. -* astQuadApprox -* Form a quadratic approximation to a Mapping -* astRate -* Find rate of change of a Mapping output -* astRebin -* Rebin a region of a data grid. -* astRebinSeq -* Rebin a region of a sequence of data grids. -* astResample -* Resample a region of a data grid. -* astSimplify -* Simplify a Mapping. -* astTran1 -* Transform 1-dimensional coordinates. -* astTran2 -* Transform 2-dimensional coordinates. -* astTranGrid -* Transform an N-dimensional regular grid of positions. -* astTranN -* Transform N-dimensional coordinates. -* astTranP (C only) -* Transform N-dimensional coordinates held in separate arrays. -* -* Protected: -* astClearInvert -* Clear the Invert attribute value for a Mapping. -* astClearReport -* Clear the Report attribute value for a Mapping. -* astGetInvert -* Get the Invert attribute value for a Mapping. -* astGetIsSimple -* Get the IsSimple attribute. -* astGetNin -* Get the number of input coordinates for a Mapping. -* astGetNout -* Get the number of output coordinates for a Mapping. -* astGetReport -* Get the Report attribute value for a Mapping. -* astGetTranForward -* Determine if a Mapping can perform a "forward" coordinate -* transformation. -* astGetTranInverse -* Determine if a Mapping can perform an "inverse" coordinate -* transformation. -* astMapList -* Decompose a Mapping into a sequence of simpler Mappings. -* astMapSplit -* Select a subset of Mapping inputs. -* astMapMerge -* Simplify a sequence of Mappings. -* astReportPoints -* Report the effect of transforming a set of points using a Mapping. -* astSetInvert -* Set the Invert attribute value for a Mapping. -* astSetReport -* Set the Report attribute value for a Mapping. -* astTestInvert -* Test if an Invert attribute value has been set for a Mapping. -* astTestReport -* Test if an Report attribute value has been set for a Mapping. -* astTransform -* Transform a set of points. - -* Other Class Functions: -* Public: -* astIsAMapping -* Test class membership. -* -* Protected: -* astCheckMapping -* Validate class membership. -* astInitMapping -* Initialise a Mapping. -* astInitMappingVtab -* Initialise the virtual function table for the Mapping class. -* astLoadMapping -* Load a Mapping. - -* Macros: -* Public: -* AST__BLOCKAVE -* Block averaging interpolation. -* AST__GAUSS -* Use exp(-k*x*x) spreading. -* AST__LINEAR -* Simple linear interpolation. -* AST__NEAREST -* Use nearest pixel centre. -* AST__SINC -* Use sinc(pi*x) interpolation. -* AST__SINCCOS -* Use sinc(pi*x)*cos(k*pi*x) interpolation. -* AST__SINCGAUSS -* Use sinc(pi*x)*exp(-k*x*x) interpolation. -* AST__SINCSINC -* Use sinc(pi*x)*sinc(k*pi*x) interpolation. -* AST__SOMB -* Use somb(pi*x) interpolation. -* AST__SOMBCOS -* Use somb(pi*x)*cos(k*pi*x) interpolation. -* AST__UINTERP -* Use general user-defined sub-pixel interpolation algorithm. -* AST__UKERN1 -* Use user-defined 1-d interpolation kernel. -* AST__URESAMP1, 2, 3 & 4 -* Flags reserved for user-defined purposes. -* AST__USEBAD -* Recognise bad pixels? -* AST__CONSERVEFLUX -* Conserve flux in astResample? -* AST__REBININIT -* Initialise a new sequnece of calls to astRebinSeq -* AST__REBINEND -* End a sequnece of calls to astRebinSeq -* AST__NOBAD -* Leave bad output pixels unchanged in calls to astResample -* AST__USEVAR -* Use variance arrays? - -* Type Definitions: -* Public: -* AstMapping -* Mapping object type. -* -* Protected: -* AstMappingVtab -* Mapping virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* MBT: Mark Taylor (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 30-JAN-1996 (RFWS): -* Original version. -* 12-JUL-1996 (RFWS): -* Updated to support the external interface plus various other -* additions. -* 12-DEC-1996 (RFWS): -* Added the astMapList method. -* 13-DEC-1996 (RFWS): -* Added the astMapMerge method. -* 13-DEC-1996 (RFWS): -* Added the astSimplify method. -* 28-MAY-1998 (RFWS): -* Added the astMapBox method. -* 12-NOV-1998 (RFWS): -* Added astResample and associated code. -* 24-NOV-2000 (MBT): -* Added AST__BLOCKAVE interpolation scheme. -* 9-JAN-2001 (DSB): -* Changed in and out arguments for TranN from type "double (*)[]" -* to "double *". -* 8-JAN-2003 (DSB): -* Added protected astInitMappingVtab method. -* 10-JUL-2003 (DSB): -* Added method astRate. -* 20-SEP-2004 (DSB): -* Added method astLinearApprox. -* 30-JUN-2005 (DSB): -* Added method astRebin -* 1-SEP-2005 (DSB): -* Added method astRebinSeq -* 31-JAN-2006 (DSB): -* Added IsSimple attribute. -* 2-MAR-2006 (DSB): -* Use HAVE_LONG_DOUBLE in place of AST_LONG_DOUBLE -* 8-MAR-2006 (DSB): -* Add astTranGrid. -* 5-MAY-2009 (DSB): -* Add astRemoveRegions. -* 26-FEB-2010 (DSB): -* Added method astQuadApprox. -*-- -*/ - -/* Include files. */ -/* ============== */ - -/* Configuration results */ -/* --------------------- */ -#if HAVE_CONFIG_H -#include -#endif - -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ - -/* C header files. */ -/* --------------- */ -#include -#include - -/* Macros. */ -/* ======= */ - -/* Sizes of global arrays */ - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif -#define AST__MAPPING_GETATTRIB_BUFF_LEN 50 -#define AST__MAPPING_RATEFUN_MAX_CACHE 5 - -/* Resampling flags. */ -/* ----------------- */ -/* These macros define flag values which may be passed to - astResample (via the "flags" argument) to provide control over - resampling operations. */ -#define AST__URESAMP1 (1) /* Flags reserved for user-defined purposes */ -#define AST__URESAMP2 (2) -#define AST__URESAMP3 (4) -#define AST__URESAMP4 (8) -#define AST__USEVAR (16) /* Use variance arrays? */ -#define AST__USEBAD (32) /* Recognise bad pixels? */ -#define AST__CONSERVEFLUX (64) /* Conserve flux? */ -#define AST__REBININIT (128) /* Initialise a new sequence of calls to astRebinSeq? */ -#define AST__REBINEND (256) /* End a sequence of calls to astRebinSeq? */ -#define AST__GENVAR (512) /* Generate output variances when rebinning? */ -#define AST__VARWGT (1024) /* Use input variances as weights? */ -#define AST__NOBAD (2048) /* Leave bad output values unchanged? */ -#define AST__DISVAR (4096) /* Generate distribution (not mean) variance? */ -#define AST__NONORM (8192) /* No normalisation required at end? */ - -/* These macros identify standard sub-pixel interpolation algorithms - for use by astResample. They are used by giving the macro's - value for the "interp" argument. */ -#define AST__UKERN1 (1) /* User-supplied 1-d interpolation kernel */ -#if 0 /* Not yet implemented */ -#define AST__UKERNN (2) /* User-supplied n-d interpolation kernel */ -#endif -#define AST__UINTERP (3) /* User-supplied interpolation function */ -#define AST__NEAREST (4) /* Use pixel with nearest centre */ -#define AST__LINEAR (5) /* Simple linear interpolation */ -#define AST__SINC (6) /* sinc(pi*x) interpolation */ -#define AST__SINCSINC (7) /* sinc(pi*x)*sinc(k*pi*x) interpolation */ -#define AST__SINCCOS (8) /* sinc(pi*x)*cos(k*pi*x) interpolation */ -#define AST__SINCGAUSS (9) /* sinc(pi*x)*exp(-k*x*x) interpolation */ -#define AST__BLOCKAVE (10) /* Block averaging interpolation */ -#define AST__GAUSS (11) /* exp(-k*x*x) spreading */ -#define AST__SOMB (12) /* somp(pi*x) interpolation */ -#define AST__SOMBCOS (13) /* somp(pi*x)*cos(k*pi*x) interpolation */ - -/* 64 bit types */ -#if HAVE_INT64_T && HAVE_UINT64_T -#include -typedef int64_t INT_BIG; -typedef uint64_t UINT_BIG; - -#elif SIZEOF_LONG == 8 -typedef long int INT_BIG; -typedef unsigned long int UINT_BIG; - -#elif SIZEOF_LONG_LONG == 8 -typedef long long int INT_BIG; -typedef unsigned long long int UINT_BIG; - -#else -#define INT_BIG "no int64_t type available" -#define UINT_BIG "no uint64_t type available" -#endif - -/* Flags defining the meaning of each bit in the "flags" field of the - Mapping structure. */ -#if defined(astCLASS) /* Protected */ -#define AST__ISSIMPLE_FLAG 1 /* Mapping has been simplified */ -#define AST__FROZEN_FLAG 2 /* Mapping cannot be nominated for simplification */ -#endif - - -/* Type Definitions. */ -/* ================= */ -/* Mapping structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstMapping { - -/* Attributes inherited from the parent class. */ - AstObject object; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - char invert; /* Mapping inverted? */ - char flags; /* Bit-wise flags describing the Mapping */ - int nin; /* Number of input coordinates */ - int nout; /* Number of output coordinates */ - char report; /* Report when converting coordinates? */ - char tran_forward; /* Forward transformation defined? */ - char tran_inverse; /* Inverse transformation defined? */ -} AstMapping; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstMappingVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstObjectVtab object_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstMapping *(* RemoveRegions)( AstMapping *, int * ); - AstMapping *(* Simplify)( AstMapping *, int * ); - AstPointSet *(* Transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); - double (* Rate)( AstMapping *, double *, int, int, int * ); - int (* DoNotSimplify)( AstMapping *, int * ); - int (* GetInvert)( AstMapping *, int * ); - int (* GetIsSimple)( AstMapping *, int * ); - int (* GetNin)( AstMapping *, int * ); - int (* GetNout)( AstMapping *, int * ); - int (* GetReport)( AstMapping *, int * ); - int (* GetTranForward)( AstMapping *, int * ); - int (* GetTranInverse)( AstMapping *, int * ); - int (* GetIsLinear)( AstMapping *, int * ); - int (* LinearApprox)( AstMapping *, const double *, const double *, double, double *, int * ); - int (* MapMerge)( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); - int (* QuadApprox)( AstMapping *, const double[2], const double[2], int, int, double *, double *, int * ); - int (* TestInvert)( AstMapping *, int * ); - int (* TestReport)( AstMapping *, int * ); - void (* ClearInvert)( AstMapping *, int * ); - void (* ClearReport)( AstMapping *, int * ); - void (* Decompose)( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); - void (* Invert)( struct AstMapping *, int * ); - void (* MapBox)( AstMapping *, const double [], const double [], int, int, double *, double *, double [], double [], int * ); - int (* MapList)( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); - int *(* MapSplit)( AstMapping *, int, const int *, AstMapping **, int * ); - void (* ReportPoints)( AstMapping *, int, AstPointSet *, AstPointSet *, int * ); - void (* SetInvert)( AstMapping *, int, int * ); - void (* SetReport)( AstMapping *, int, int * ); - void (* Tran1)( AstMapping *, int, const double [], int, double [], int * ); - void (* Tran2)( AstMapping *, int, const double [], const double [], int, double [], double [], int * ); - void (* TranGrid)( AstMapping *, int, const int[], const int[], double, int, int, int, int, double *, int * ); - void (* TranN)( AstMapping *, int, int, int, const double *, int, int, int, double *, int * ); - void (* TranP)( AstMapping *, int, int, const double *[], int, int, double *[], int * ); - -#define DECLARE_GENERIC_ALL(X,Xtype) \ - int (* Resample##X)( AstMapping *, int, const int [], const int [], \ - const Xtype [], const Xtype [], int, \ - void (*)( void ), const double [], int, double, int, \ - Xtype, int, const int [], const int [], \ - const int [], const int [], Xtype [], Xtype [], int * ); \ - -DECLARE_GENERIC_ALL(B,signed char) -DECLARE_GENERIC_ALL(D,double) -DECLARE_GENERIC_ALL(F,float) -DECLARE_GENERIC_ALL(I,int) -DECLARE_GENERIC_ALL(K,INT_BIG) -DECLARE_GENERIC_ALL(L,long int) -DECLARE_GENERIC_ALL(S,short int) -DECLARE_GENERIC_ALL(UB,unsigned char) -DECLARE_GENERIC_ALL(UI,unsigned int) -DECLARE_GENERIC_ALL(UK,UINT_BIG) -DECLARE_GENERIC_ALL(UL,unsigned long int) -DECLARE_GENERIC_ALL(US,unsigned short int) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -DECLARE_GENERIC_ALL(LD,long double) -#endif - -#undef DECLARE_GENERIC_ALL - -#define DECLARE_GENERIC_DFI(X,Xtype) \ - void (* Rebin##X)( AstMapping *, double, int, const int [], const int [], \ - const Xtype [], const Xtype [], int, const double [], int, \ - double, int, Xtype, int, const int [], const int [], \ - const int [], const int [], Xtype [], Xtype [], int * ); \ - void (* RebinSeq##X)( AstMapping *, double, int, const int [], const int [], \ - const Xtype [], const Xtype [], int, const double [], \ - int, double, int, Xtype, int, const int [], \ - const int [], const int [], const int [], Xtype [], \ - Xtype [], double [], int64_t *, int * ); - -DECLARE_GENERIC_DFI(D,double) -DECLARE_GENERIC_DFI(F,float) -DECLARE_GENERIC_DFI(I,int) -DECLARE_GENERIC_DFI(B,signed char) -DECLARE_GENERIC_DFI(UB,unsigned char) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -DECLARE_GENERIC_DFI(LD,long double) -#endif - -#undef DECLARE_GENERIC_DFI - -} AstMappingVtab; - - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstMappingGlobals { - AstMappingVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ AST__MAPPING_GETATTRIB_BUFF_LEN + 1 ]; - AstMapping *Unsimplified_Mapping; - int Rate_Disabled; - AstPointSet *RateFun_Pset1_Cache[ AST__MAPPING_RATEFUN_MAX_CACHE ]; - AstPointSet *RateFun_Pset2_Cache[ AST__MAPPING_RATEFUN_MAX_CACHE ]; - int RateFun_Next_Slot; - int RateFun_Pset_Size[ AST__MAPPING_RATEFUN_MAX_CACHE ]; -} AstMappingGlobals; - -#endif -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Mapping) /* Check class membership */ -astPROTO_ISA(Mapping) /* Test class membership */ - -/* NB. There is no constructor function for this class. */ - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstMapping *astInitMapping_( void *, size_t, int, AstMappingVtab *, - const char *, int, int, int, int, int * ); - -/* Vtab initialiser. */ -void astInitMappingVtab_( AstMappingVtab *, const char *, int * ); - -/* Loader. */ -AstMapping *astLoadMapping_( void *, size_t, AstMappingVtab *, - const char *, AstChannel *channel, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitMappingGlobals_( AstMappingGlobals * ); -#endif -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -#define PROTO_GENERIC_ALL(X,Xtype) \ - int astResample##X##_( AstMapping *, int, const int [], const int [], \ - const Xtype [], const Xtype [], int, \ - void (*)( void ), const double [], int, double, int, \ - Xtype, int, const int [], const int [], \ - const int [], const int [], Xtype [], Xtype [], int * ); \ - -PROTO_GENERIC_ALL(B,signed char) -PROTO_GENERIC_ALL(D,double) -PROTO_GENERIC_ALL(F,float) -PROTO_GENERIC_ALL(I,int) -PROTO_GENERIC_ALL(K,INT_BIG) -PROTO_GENERIC_ALL(L,long int) -PROTO_GENERIC_ALL(S,short int) -PROTO_GENERIC_ALL(UB,unsigned char) -PROTO_GENERIC_ALL(UI,unsigned int) -PROTO_GENERIC_ALL(UK,UINT_BIG) -PROTO_GENERIC_ALL(UL,unsigned long int) -PROTO_GENERIC_ALL(US,unsigned short int) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -PROTO_GENERIC_ALL(LD,long double) -#endif - -#undef PROTO_GENERIC_ALL - -#define PROTO_GENERIC_DFI(X,Xtype) \ - void astRebin##X##_( AstMapping *, double, int, const int [], const int [], \ - const Xtype [], const Xtype [], int, const double [], int, \ - double, int, Xtype, int, const int [], const int [], \ - const int [], const int [], Xtype [], Xtype [], int * ); \ - void astRebinSeq##X##_( AstMapping *, double, int, const int [], const int [], \ - const Xtype [], const Xtype [], int, const double [], \ - int, double, int, Xtype, int, const int [], \ - const int [], const int [], const int [], Xtype [], \ - Xtype [], double [], int64_t *, int * ); - -PROTO_GENERIC_DFI(D,double) -PROTO_GENERIC_DFI(F,float) -PROTO_GENERIC_DFI(I,int) -PROTO_GENERIC_DFI(B,signed char) -PROTO_GENERIC_DFI(UB,unsigned char) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -PROTO_GENERIC_DFI(LD,long double) -#endif - -#undef PROTO_GENERIC_DFI - -AstMapping *astRemoveRegions_( AstMapping *, int * ); -AstMapping *astSimplify_( AstMapping *, int * ); -void astInvert_( AstMapping *, int * ); -int astLinearApprox_( AstMapping *, const double *, const double *, double, double *, int * ); -int astQuadApprox_( AstMapping *, const double[2], const double[2], int, int, double *, double *, int * ); -void astTran1_( AstMapping *, int, const double [], int, double [], int * ); -void astTran2_( AstMapping *, int, const double [], const double [], int, double [], double [], int * ); -void astTranGrid_( AstMapping *, int, const int[], const int[], double, int, int, int, int, double *, int * ); -void astTranN_( AstMapping *, int, int, int, const double *, int, int, int, double *, int * ); -void astTranP_( AstMapping *, int, int, const double *[], int, int, double *[], int * ); - -#if defined(astCLASS) /* Protected */ -void astDecompose_( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); -void astMapBox_( AstMapping *, const double [], const double [], int, int, double *, double *, double [], double [], int * ); -double astRate_( AstMapping *, double *, int, int, int * ); -int *astMapSplit_( AstMapping *, int, const int *, AstMapping **, int * ); -#else -void astDecomposeId_( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); -void astMapBoxId_( AstMapping *, const double [], const double [], int, int, double *, double *, double [], double [], int * ); -double astRateId_( AstMapping *, double *, int, int, int * ); -void astMapSplitId_( AstMapping *, int, const int *, int *, AstMapping **, int * ); -#endif - -#if defined(astCLASS) /* Protected */ -int astRateState_( int, int * ); -AstPointSet *astTransform_( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -int astGetInvert_( AstMapping *, int * ); -int astGetIsSimple_( AstMapping *, int * ); -int astGetNin_( AstMapping *, int * ); -int astGetNout_( AstMapping *, int * ); -int astGetReport_( AstMapping *, int * ); -int astGetTranForward_( AstMapping *, int * ); -int astGetTranInverse_( AstMapping *, int * ); -int astGetIsLinear_( AstMapping *, int * ); -int astDoNotSimplify_( AstMapping *, int * ); -int astMapMerge_( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -int astTestInvert_( AstMapping *, int * ); -int astTestReport_( AstMapping *, int * ); -void astClearInvert_( AstMapping *, int * ); -void astClearReport_( AstMapping *, int * ); -int astMapList_( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -void astReportPoints_( AstMapping *, int, AstPointSet *, AstPointSet *, int * ); -void astSetInvert_( AstMapping *, int, int * ); -void astSetReport_( AstMapping *, int, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class to make - them easier to invoke (e.g. to avoid type mis-matches when passing pointers - to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them to - validate their own arguments. We must use a cast when passing object - pointers (so that they can accept objects from derived classes). */ - -/* Check class membership. */ -#define astCheckMapping(this) astINVOKE_CHECK(Mapping,this,0) -#define astVerifyMapping(this) astINVOKE_CHECK(Mapping,this,1) - -/* Test class membership. */ -#define astIsAMapping(this) astINVOKE_ISA(Mapping,this) - -/* NB. There is no constructor function for this class. */ - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitMapping(mem,size,init,vtab,name,nin,nout,tran_forward,tran_inverse) \ -astINVOKE(O,astInitMapping_(mem,size,init,vtab,name,nin,nout,tran_forward,tran_inverse,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitMappingVtab(vtab,name) astINVOKE(V,astInitMappingVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadMapping(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadMapping_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to member functions. */ -/* ------------------------------- */ -/* Here we make use of astCheckMapping (et al.) to validate Mapping - pointers before use. This provides a contextual error report if a - pointer to the wrong sort of object is supplied. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#define astResampleLD(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleLD_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#endif - -#define astInvert(this) \ -astINVOKE(V,astInvert_(astCheckMapping(this),STATUS_PTR)) -#define astLinearApprox(this,lbnd,ubnd,tol,fit) \ -astINVOKE(V,astLinearApprox_(astCheckMapping(this),lbnd,ubnd,tol,fit,STATUS_PTR)) -#define astQuadApprox(this,lbnd,ubnd,nx,ny,fit,rms) \ -astINVOKE(V,astQuadApprox_(astCheckMapping(this),lbnd,ubnd,nx,ny,fit,rms,STATUS_PTR)) -#define astRebinD(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astRebinD_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astRebinF(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astRebinF_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astRebinI(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astRebinI_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astRebinB(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astRebinB_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astRebinUB(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astRebinUB_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astRebinSeqD(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused) \ -astINVOKE(V,astRebinSeqD_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused,STATUS_PTR)) -#define astRebinSeqF(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused) \ -astINVOKE(V,astRebinSeqF_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused,STATUS_PTR)) -#define astRebinSeqI(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused) \ -astINVOKE(V,astRebinSeqI_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused,STATUS_PTR)) -#define astRebinSeqB(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused) \ -astINVOKE(V,astRebinSeqB_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused,STATUS_PTR)) -#define astRebinSeqUB(this,wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused) \ -astINVOKE(V,astRebinSeqUB_(astCheckMapping(this),wlim,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,weights,nused,STATUS_PTR)) -#define astResampleD(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleD_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleF(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleF_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleL(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleL_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleUL(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleUL_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleI(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleI_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleUI(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleUI_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleK(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleK_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleUK(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleUK_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleS(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleS_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleUS(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleUS_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleB(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleB_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astResampleUB(this,ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var) \ -astINVOKE(V,astResampleUB_(astCheckMapping(this),ndim_in,lbnd_in,ubnd_in,in,in_var,interp,finterp,params,flags,tol,maxpix,badval,ndim_out,lbnd_out,ubnd_out,lbnd,ubnd,out,out_var,STATUS_PTR)) -#define astRemoveRegions(this) astINVOKE(O,astRemoveRegions_(astCheckMapping(this),STATUS_PTR)) -#define astSimplify(this) astINVOKE(O,astSimplify_(astCheckMapping(this),STATUS_PTR)) -#define astTran1(this,npoint,xin,forward,xout) \ -astINVOKE(V,astTran1_(astCheckMapping(this),npoint,xin,forward,xout,STATUS_PTR)) -#define astTran2(this,npoint,xin,yin,forward,xout,yout) \ -astINVOKE(V,astTran2_(astCheckMapping(this),npoint,xin,yin,forward,xout,yout,STATUS_PTR)) -#define astTranGrid(this,ncoord_in,lbnd,ubnd,tol,maxpix,forward,ncoord_out,outdim,out) \ -astINVOKE(V,astTranGrid_(astCheckMapping(this),ncoord_in,lbnd,ubnd,tol,maxpix,forward,ncoord_out,outdim,out,STATUS_PTR)) -#define astTranN(this,npoint,ncoord_in,indim,in,forward,ncoord_out,outdim,out) \ -astINVOKE(V,astTranN_(astCheckMapping(this),npoint,ncoord_in,indim,in,forward,ncoord_out,outdim,out,STATUS_PTR)) -#define astTranP(this,npoint,ncoord_in,ptr_in,forward,ncoord_out,ptr_out) \ -astINVOKE(V,astTranP_(astCheckMapping(this),npoint,ncoord_in,ptr_in,forward,ncoord_out,ptr_out,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astDecompose(this,map1,map2,series,inv1,inv2) \ -astINVOKE(V,astDecompose_(astCheckMapping(this),(AstMapping **)(map1),(AstMapping **)(map2),series,inv1,inv2,STATUS_PTR)) -#define astMapBox(this,lbnd_in,ubnd_in,forward,coord_out,lbnd_out,ubnd_out,xl,xu) \ -astINVOKE(V,astMapBox_(astCheckMapping(this),lbnd_in,ubnd_in,forward,coord_out,lbnd_out,ubnd_out,xl,xu,STATUS_PTR)) -#define astRate(this,at,ax1,ax2) \ -astINVOKE(V,astRate_(astCheckMapping(this),at,ax1,ax2,STATUS_PTR)) -#define astMapSplit(this,nin,in,map) \ -astINVOKE(V,astMapSplit_(this,nin,in,map,STATUS_PTR)) -#else -#define astDecompose(this,map1,map2,series,inv1,inv2) \ -astINVOKE(V,astDecomposeId_(astCheckMapping(this),(AstMapping **)(map1),(AstMapping **)(map2),series,inv1,inv2,STATUS_PTR)) -#define astMapBox(this,lbnd_in,ubnd_in,forward,coord_out,lbnd_out,ubnd_out,xl,xu) \ -astINVOKE(V,astMapBoxId_(astCheckMapping(this),lbnd_in,ubnd_in,forward,coord_out,lbnd_out,ubnd_out,xl,xu,STATUS_PTR)) -#define astRate(this,at,ax1,ax2) \ -astINVOKE(V,astRateId_(astCheckMapping(this),at,ax1,ax2,STATUS_PTR)) -#define astMapSplit(this,nin,in,out,map) \ -astINVOKE(V,astMapSplitId_(astCheckMapping(this),nin,in,out,map,STATUS_PTR)) -#endif - -#if defined(astCLASS) /* Protected */ -#define astRateState(disabled) astRateState_(disabled,STATUS_PTR) -#define astClearInvert(this) \ -astINVOKE(V,astClearInvert_(astCheckMapping(this),STATUS_PTR)) -#define astClearReport(this) \ -astINVOKE(V,astClearReport_(astCheckMapping(this),STATUS_PTR)) -#define astGetInvert(this) \ -astINVOKE(V,astGetInvert_(astCheckMapping(this),STATUS_PTR)) -#define astGetIsSimple(this) \ -astINVOKE(V,astGetIsSimple_(astCheckMapping(this),STATUS_PTR)) -#define astGetNin(this) \ -astINVOKE(V,astGetNin_(astCheckMapping(this),STATUS_PTR)) -#define astGetNout(this) \ -astINVOKE(V,astGetNout_(astCheckMapping(this),STATUS_PTR)) -#define astGetReport(this) \ -astINVOKE(V,astGetReport_(astCheckMapping(this),STATUS_PTR)) -#define astGetTranForward(this) \ -astINVOKE(V,astGetTranForward_(astCheckMapping(this),STATUS_PTR)) -#define astGetTranInverse(this) \ -astINVOKE(V,astGetTranInverse_(astCheckMapping(this),STATUS_PTR)) -#define astGetIsLinear(this) \ -astINVOKE(V,astGetIsLinear_(astCheckMapping(this),STATUS_PTR)) -#define astMapList(this,series,invert,nmap,map_list,invert_list) \ -astINVOKE(V,astMapList_(this,series,invert,nmap,map_list,invert_list,STATUS_PTR)) -#define astMapMerge(this,where,series,nmap,map_list,invert_list) \ -astINVOKE(V,astMapMerge_(astCheckMapping(this),where,series,nmap,map_list,invert_list,STATUS_PTR)) -#define astReportPoints(this,forward,in_points,out_points) \ -astINVOKE(V,astReportPoints_(astCheckMapping(this),forward,astCheckPointSet(in_points),astCheckPointSet(out_points),STATUS_PTR)) -#define astSetInvert(this,value) \ -astINVOKE(V,astSetInvert_(astCheckMapping(this),value,STATUS_PTR)) -#define astSetReport(this,value) \ -astINVOKE(V,astSetReport_(astCheckMapping(this),value,STATUS_PTR)) -#define astTestInvert(this) \ -astINVOKE(V,astTestInvert_(astCheckMapping(this),STATUS_PTR)) -#define astTestReport(this) \ -astINVOKE(V,astTestReport_(astCheckMapping(this),STATUS_PTR)) -#define astDoNotSimplify(this) \ -astINVOKE(V,astDoNotSimplify_(astCheckMapping(this),STATUS_PTR)) - -/* Since a NULL PointSet pointer is acceptable here, we must omit the argument - checking in that case. (But unfortunately, "out" then gets evaluated - twice - this is unlikely to matter, but is there a better way?) */ -#define astTransform(this,in,forward,out) \ -astINVOKE(O,astTransform_(astCheckMapping(this),astCheckPointSet(in),forward,(out)?astCheckPointSet(out):NULL,STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/mapping.pdf b/ast/mapping.pdf deleted file mode 100644 index 95b5866..0000000 Binary files a/ast/mapping.pdf and /dev/null differ diff --git a/ast/mathmap.c b/ast/mathmap.c deleted file mode 100644 index f3a21f9..0000000 --- a/ast/mathmap.c +++ /dev/null @@ -1,7421 +0,0 @@ -/* -*class++ -* Name: -* MathMap - -* Purpose: -* Transform coordinates using mathematical expressions. - -* Constructor Function: -c astMathMap -f AST_MATHMAP - -* Description: -c A MathMap is a Mapping which allows you to specify a set of forward -c and/or inverse transformation functions using arithmetic operations -c and mathematical functions similar to those available in C. The -c MathMap interprets these functions at run-time, whenever its forward -c or inverse transformation is required. Because the functions are not -c compiled in the normal sense (unlike an IntraMap), they may be used to -c describe coordinate transformations in a transportable manner. A -c MathMap therefore provides a flexible way of defining new types of -c Mapping whose descriptions may be stored as part of a dataset and -c interpreted by other programs. -f A MathMap is a Mapping which allows you to specify a set of forward -f and/or inverse transformation functions using arithmetic operations -f and mathematical functions similar to those available in Fortran. The -f MathMap interprets these functions at run-time, whenever its forward -f or inverse transformation is required. Because the functions are not -f compiled in the normal sense (unlike an IntraMap), they may be used to -f describe coordinate transformations in a transportable manner. A -f MathMap therefore provides a flexible way of defining new types of -f Mapping whose descriptions may be stored as part of a dataset and -f interpreted by other programs. - -* Inheritance: -* The MathMap class inherits from the Mapping class. - -* Attributes: -* In addition to those attributes common to all Mappings, every -* MathMap also has the following attributes: -* - Seed: Random number seed -* - SimpFI: Forward-inverse MathMap pairs simplify? -* - SimpIF: Inverse-forward MathMap pairs simplify? - -* Functions: -c The MathMap class does not define any new functions beyond those -f The MathMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 3-SEP-1999 (RFWS): -* Original version. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitMathMapVtab -* method. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 14-MAR-2006 (DSB): -* - Add QIF function. -* - Override astEqual method. -* 20-NOV-2006 (DSB): -* Re-implement the Equal method to avoid use of astSimplify. -* 30-AUG-2012 (DSB): -* Fix bug in undocumented Gaussian noise function. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS MathMap - -/* Allocate pointer array. */ -/* ----------------------- */ -/* This macro allocates an array of pointers. If successful, each element - of the array is initialised to NULL. */ -#define MALLOC_POINTER_ARRAY(array_name,array_type,array_size) \ -\ -/* Allocate the array. */ \ - (array_name) = astMalloc( sizeof(array_type) * (size_t) (array_size) ); \ - if ( astOK ) { \ -\ -/* If successful, loop to initialise each element. */ \ - int array_index_; \ - for ( array_index_ = 0; array_index_ < (array_size); array_index_++ ) { \ - (array_name)[ array_index_ ] = NULL; \ - } \ - } - -/* Free pointer array. */ -/* ------------------- */ -/* This macro frees a dynamically allocated array of pointers, each of - whose elements may point at a further dynamically allocated array - (which is also to be freed). It also allows for the possibility of any - of the pointers being NULL. */ -#define FREE_POINTER_ARRAY(array_name,array_size) \ -\ -/* Check that the main array pointer is not NULL. */ \ - if ( (array_name) ) { \ -\ -/* If OK, loop to free each of the sub-arrays. */ \ - int array_index_; \ - for ( array_index_ = 0; array_index_ < (array_size); array_index_++ ) { \ -\ -/* Check that each sub-array pointer is not NULL before freeing it. */ \ - if ( (array_name)[ array_index_ ] ) { \ - (array_name)[ array_index_ ] = \ - astFree( (array_name)[ array_index_ ] ); \ - } \ - } \ -\ -/* Free the main pointer array. */ \ - (array_name) = astFree( (array_name) ); \ - } - -/* SizeOf pointer array. */ -/* --------------------- */ -/* This macro increments "result" by the number of bytes allocated for an - array of pointers, each of whose elements may point at a further - dynamically allocated array (which is also to be included). It also - allows for the possibility of any of the pointers being NULL. */ -#define SIZEOF_POINTER_ARRAY(array_name,array_size) \ -\ -/* Check that the main array pointer is not NULL. */ \ - if ( (array_name) ) { \ -\ -/* If OK, loop to measure each of the sub-arrays. */ \ - int array_index_; \ - for ( array_index_ = 0; array_index_ < (array_size); array_index_++ ) { \ -\ -/* Check that each sub-array pointer is not NULL before measuring it. */ \ - if ( (array_name)[ array_index_ ] ) { \ - result += astTSizeOf( (array_name)[ array_index_ ] ); \ - } \ - } \ -\ -/* Include the main pointer array. */ \ - result += astTSizeOf( (array_name) ); \ - } - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ -#include "channel.h" /* I/O channels */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "cmpmap.h" /* Compound Mappings */ -#include "mathmap.h" /* Interface definition for this class */ -#include "memory.h" /* Memory allocation facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points */ -#include "unitmap.h" /* Unit Mapping */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ -/* This type is made obscure since it is publicly accessible (but not - useful). Provide shorthand for use within this module. */ -typedef AstMathMapRandContext_ Rcontext; - - - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -/* This declaration enumerates the operation codes recognised by the - EvaluateFunction function which evaluates arithmetic expressions. */ -typedef enum { - -/* User-supplied constants and variables. */ - OP_LDCON, /* Load constant */ - OP_LDVAR, /* Load variable */ - -/* System constants. */ - OP_LDBAD, /* Load bad value (AST__BAD) */ - OP_LDDIG, /* Load # decimal digits (AST__DBL_DIG) */ - OP_LDEPS, /* Load relative precision (DBL_EPSILON) */ - OP_LDMAX, /* Load largest value (DBL_MAX) */ - OP_LDMAX10E, /* Max. decimal exponent (DBL_MAX_10_EXP) */ - OP_LDMAXE, /* Load maximum exponent (DBL_MAX_EXP) */ - OP_LDMDIG, /* Load # mantissa digits (DBL_MANT_DIG) */ - OP_LDMIN, /* Load smallest value (DBL_MIN) */ - OP_LDMIN10E, /* Min. decimal exponent (DBL_MIN_10_EXP) */ - OP_LDMINE, /* Load minimum exponent (DBL_MIN_EXP) */ - OP_LDRAD, /* Load floating radix (FLT_RADIX) */ - OP_LDRND, /* Load rounding mode (FLT_ROUNDS) */ - -/* Mathematical constants. */ - OP_LDE, /* Load e (base of natural logarithms) */ - OP_LDPI, /* Load pi */ - -/* Functions with one argument. */ - OP_ABS, /* Absolute value (sign removal) */ - OP_ACOS, /* Inverse cosine (radians) */ - OP_ACOSD, /* Inverse cosine (degrees) */ - OP_ACOSH, /* Inverse hyperbolic cosine */ - OP_ACOTH, /* Inverse hyperbolic cotangent */ - OP_ACSCH, /* Inverse hyperbolic cosecant */ - OP_ASECH, /* Inverse hyperbolic secant */ - OP_ASIN, /* Inverse sine (radians) */ - OP_ASIND, /* Inverse sine (degrees) */ - OP_ASINH, /* Inverse hyperbolic sine */ - OP_ATAN, /* Inverse tangent (radians) */ - OP_ATAND, /* Inverse tangent (degrees) */ - OP_ATANH, /* Inverse hyperbolic tangent */ - OP_CEIL, /* C ceil function (round up) */ - OP_COS, /* Cosine (radians) */ - OP_COSD, /* Cosine (degrees) */ - OP_COSH, /* Hyperbolic cosine */ - OP_COTH, /* Hyperbolic cotangent */ - OP_CSCH, /* Hyperbolic cosecant */ - OP_EXP, /* Exponential function */ - OP_FLOOR, /* C floor function (round down) */ - OP_INT, /* Integer value (round towards zero) */ - OP_ISBAD, /* Test for bad value */ - OP_LOG, /* Natural logarithm */ - OP_LOG10, /* Base 10 logarithm */ - OP_NINT, /* Fortran NINT function (round to nearest) */ - OP_POISS, /* Poisson random number */ - OP_SECH, /* Hyperbolic secant */ - OP_SIN, /* Sine (radians) */ - OP_SINC, /* Sinc function [= sin(x)/x] */ - OP_SIND, /* Sine (degrees) */ - OP_SINH, /* Hyperbolic sine */ - OP_SQR, /* Square */ - OP_SQRT, /* Square root */ - OP_TAN, /* Tangent (radians) */ - OP_TAND, /* Tangent (degrees) */ - OP_TANH, /* Hyperbolic tangent */ - -/* Functions with two arguments. */ - OP_ATAN2, /* Inverse tangent (2 arguments, radians) */ - OP_ATAN2D, /* Inverse tangent (2 arguments, degrees) */ - OP_DIM, /* Fortran DIM (positive difference) fn. */ - OP_GAUSS, /* Gaussian random number */ - OP_MOD, /* Modulus function */ - OP_POW, /* Raise to power */ - OP_RAND, /* Uniformly distributed random number */ - OP_SIGN, /* Transfer of sign function */ - -/* Functions with three arguments. */ - OP_QIF, /* C "question mark" operator "a?b:c" */ - -/* Functions with variable numbers of arguments. */ - OP_MAX, /* Maximum of 2 or more values */ - OP_MIN, /* Minimum of 2 or more values */ - -/* Unary arithmetic operators. */ - OP_NEG, /* Negate (change sign) */ - -/* Unary boolean operators. */ - OP_NOT, /* Boolean NOT */ - -/* Binary arithmetic operators. */ - OP_ADD, /* Add */ - OP_DIV, /* Divide */ - OP_MUL, /* Multiply */ - OP_SUB, /* Subtract */ - -/* Bit-shift operators. */ - OP_SHFTL, /* Shift bits left */ - OP_SHFTR, /* Shift bits right */ - -/* Relational operators. */ - OP_EQ, /* Relational equal */ - OP_GE, /* Greater than or equal */ - OP_GT, /* Greater than */ - OP_LE, /* Less than or equal */ - OP_LT, /* Less than */ - OP_NE, /* Not equal */ - -/* Bit-wise operators. */ - OP_BITAND, /* Bit-wise AND */ - OP_BITOR, /* Bit-wise OR */ - OP_BITXOR, /* Bit-wise exclusive OR */ - -/* Binary boolean operators. */ - OP_AND, /* Boolean AND */ - OP_EQV, /* Fortran logical .EQV. operation */ - OP_OR, /* Boolean OR */ - OP_XOR, /* Boolean exclusive OR */ - -/* Null operation. */ - OP_NULL /* Null operation */ -} Oper; - -/* This structure holds a description of each symbol which may appear - in an expression. */ -typedef struct { - const char *text; /* Symbol text as it appears in expressions */ - const int size; /* Size of symbol text */ - const int operleft; /* An operator when seen from the left? */ - const int operright; /* An operator when seen from the right? */ - const int unarynext; /* May be followed by a unary +/- ? */ - const int unaryoper; /* Is a unary +/- ? */ - const int leftpriority; /* Priority when seen from the left */ - const int rightpriority; /* Priority when seen from the right */ - const int parincrement; /* Change in parenthesis level */ - const int stackincrement; /* Change in evaluation stack size */ - const int nargs; /* Number of function arguments */ - const Oper opcode; /* Resulting operation code */ -} Symbol; - -/* This initialises an array of Symbol structures to hold data on all - the supported symbols. The order is not important, but symbols are - arranged here in approximate order of descending evaluation - priority. The end of the array is indicated by an element with a NULL - "text" component. */ -static const Symbol symbol[] = { - -/* User-supplied constants and variables. */ - { "" , 0, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDCON }, - { "" , 0, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDVAR }, - -/* System constants. */ - { "" , 5, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDBAD }, - { "" , 5, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDDIG }, - { "" , 9, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDEPS }, - { "" , 10, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDMDIG }, - { "" , 5, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDMAX }, - { "", 12, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDMAX10E }, - { "" , 9, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDMAXE }, - { "" , 5, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDMIN }, - { "", 12, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDMIN10E }, - { "" , 9, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDMINE }, - { "" , 7, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDRAD }, - { "" , 8, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDRND }, - -/* Mathematical constants. */ - { "" , 3, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDE }, - { "" , 4, 0, 0, 0, 0, 19, 19, 0, 1, 0, OP_LDPI }, - -/* Functions with one argument. */ - { "abs(" , 4, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ABS }, - { "acos(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ACOS }, - { "acosd(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ACOSD }, - { "acosh(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ACOSH }, - { "acoth(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ACOTH }, - { "acsch(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ACSCH }, - { "aint(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_INT }, - { "asech(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ASECH }, - { "asin(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ASIN }, - { "asind(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ASIND }, - { "asinh(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ASINH }, - { "atan(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ATAN }, - { "atand(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ATAND }, - { "atanh(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ATANH }, - { "ceil(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_CEIL }, - { "cos(" , 4, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_COS }, - { "cosd(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_COSD }, - { "cosh(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_COSH }, - { "coth(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_COTH }, - { "csch(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_CSCH }, - { "exp(" , 4, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_EXP }, - { "fabs(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ABS }, - { "floor(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_FLOOR }, - { "int(" , 4, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_INT }, - { "isbad(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_ISBAD }, - { "log(" , 4, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_LOG }, - { "log10(" , 6, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_LOG10 }, - { "nint(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_NINT }, - { "poisson(" , 8, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_POISS }, - { "sech(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_SECH }, - { "sin(" , 4, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_SIN }, - { "sinc(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_SINC }, - { "sind(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_SIND }, - { "sinh(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_SINH }, - { "sqr(" , 4, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_SQR }, - { "sqrt(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_SQRT }, - { "tan(" , 4, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_TAN }, - { "tand(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_TAND }, - { "tanh(" , 5, 0, 1, 1, 0, 19, 1, 1, 0, 1, OP_TANH }, - -/* Functions with two arguments. */ - { "atan2(" , 6, 0, 1, 1, 0, 19, 1, 1, -1, 2, OP_ATAN2 }, - { "atan2d(" , 7, 0, 1, 1, 0, 19, 1, 1, -1, 2, OP_ATAN2D }, - { "dim(" , 4, 0, 1, 1, 0, 19, 1, 1, -1, 2, OP_DIM }, - { "fmod(" , 5, 0, 1, 1, 0, 19, 1, 1, -1, 2, OP_MOD }, - { "gauss(" , 6, 0, 1, 1, 0, 19, 1, 1, -1, 2, OP_GAUSS }, - { "mod(" , 4, 0, 1, 1, 0, 19, 1, 1, -1, 2, OP_MOD }, - { "pow(" , 4, 0, 1, 1, 0, 19, 1, 1, -1, 2, OP_POW }, - { "rand(" , 5, 0, 1, 1, 0, 19, 1, 1, -1, 2, OP_RAND }, - { "sign(" , 5, 0, 1, 1, 0, 19, 1, 1, -1, 2, OP_SIGN }, - -/* Functions with two arguments. */ - { "qif(" , 4, 0, 1, 1, 0, 19, 1, 1, -2, 3, OP_QIF }, - -/* Functions with variable numbers of arguments. */ - { "max(" , 4, 0, 1, 1, 0, 19, 1, 1, -1, -2, OP_MAX }, - { "min(" , 4, 0, 1, 1, 0, 19, 1, 1, -1, -2, OP_MIN }, - -/* Parenthesised expressions. */ - { ")" , 1, 1, 0, 0, 0, 2, 19, -1, 0, 0, OP_NULL }, - { "(" , 1, 0, 1, 1, 0, 19, 1, 1, 0, 0, OP_NULL }, - -/* Unary arithmetic operators. */ - { "+" , 1, 0, 1, 1, 1, 17, 16, 0, 0, 0, OP_NULL }, - { "-" , 1, 0, 1, 1, 1, 17, 16, 0, 0, 0, OP_NEG }, - -/* Unary boolean operators. */ - { "!" , 1, 0, 1, 1, 0, 17, 16, 0, 0, 0, OP_NOT }, - { ".not." , 5, 0, 1, 1, 0, 17, 16, 0, 0, 0, OP_NOT }, - -/* Binary arithmetic operators. */ - { "**" , 2, 1, 1, 1, 0, 18, 15, 0, -1, 0, OP_POW }, - { "*" , 1, 1, 1, 1, 0, 14, 14, 0, -1, 0, OP_MUL }, - { "/" , 1, 1, 1, 1, 0, 14, 14, 0, -1, 0, OP_DIV }, - { "+" , 1, 1, 1, 1, 0, 13, 13, 0, -1, 0, OP_ADD }, - { "-" , 1, 1, 1, 1, 0, 13, 13, 0, -1, 0, OP_SUB }, - -/* Bit-shift operators. */ - { "<<" , 2, 1, 1, 1, 0, 12, 12, 0, -1, 0, OP_SHFTL }, - { ">>" , 2, 1, 1, 1, 0, 12, 12, 0, -1, 0, OP_SHFTR }, - -/* Relational operators. */ - { "<" , 1, 1, 1, 1, 0, 11, 11, 0, -1, 0, OP_LT }, - { ".lt." , 4, 1, 1, 1, 0, 11, 11, 0, -1, 0, OP_LT }, - { "<=" , 2, 1, 1, 1, 0, 11, 11, 0, -1, 0, OP_LE }, - { ".le." , 4, 1, 1, 1, 0, 11, 11, 0, -1, 0, OP_LE }, - { ">" , 1, 1, 1, 1, 0, 11, 11, 0, -1, 0, OP_GT }, - { ".gt." , 4, 1, 1, 1, 0, 11, 11, 0, -1, 0, OP_GT }, - { ">=" , 2, 1, 1, 1, 0, 11, 11, 0, -1, 0, OP_GE }, - { ".ge." , 4, 1, 1, 1, 0, 11, 11, 0, -1, 0, OP_GE }, - { "==" , 2, 1, 1, 1, 0, 10, 10, 0, -1, 0, OP_EQ }, - { ".eq." , 4, 1, 1, 1, 0, 10, 10, 0, -1, 0, OP_EQ }, - { "!=" , 2, 1, 1, 1, 0, 10, 10, 0, -1, 0, OP_NE }, - { ".ne." , 4, 1, 1, 1, 0, 10, 10, 0, -1, 0, OP_NE }, - -/* Bit-wise operators. */ - { "&" , 1, 1, 1, 1, 0, 9, 9, 0, -1, 0, OP_BITAND }, - { "^" , 1, 1, 1, 1, 0, 8, 8, 0, -1, 0, OP_BITXOR }, - { "|" , 1, 1, 1, 1, 0, 7, 7, 0, -1, 0, OP_BITOR }, - -/* Binary boolean operators. */ - { "&&" , 2, 1, 1, 1, 0, 6, 6, 0, -1, 0, OP_AND }, - { ".and." , 5, 1, 1, 1, 0, 6, 6, 0, -1, 0, OP_AND }, - { "^^" , 2, 1, 1, 1, 0, 5, 5, 0, -1, 0, OP_XOR }, - { "||" , 2, 1, 1, 1, 0, 4, 4, 0, -1, 0, OP_OR }, - { ".or." , 4, 1, 1, 1, 0, 4, 4, 0, -1, 0, OP_OR }, - { ".eqv." , 5, 1, 1, 1, 0, 3, 3, 0, -1, 0, OP_EQV }, - { ".neqv." , 6, 1, 1, 1, 0, 3, 3, 0, -1, 0, OP_XOR }, - { ".xor." , 5, 1, 1, 1, 0, 3, 3, 0, -1, 0, OP_XOR }, - -/* Separators. */ - { "," , 1, 1, 1, 1, 0, 2, 2, 0, 0, 0, OP_NULL }, - -/* End of symbol data. */ - { NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, OP_NULL } -}; - -/* These variables identify indices in the above array which hold - special symbols used explicitly in the code. */ -static const int symbol_ldcon = 0; /* Load a constant */ -static const int symbol_ldvar = 1; /* Load a variable */ - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(MathMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(MathMap,Class_Init) -#define class_vtab astGLOBAL(MathMap,Class_Vtab) -#define getattrib_buff astGLOBAL(MathMap,GetAttrib_Buff) - - - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -static pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX3 pthread_mutex_lock( &mutex3 ); -#define UNLOCK_MUTEX3 pthread_mutex_unlock( &mutex3 ); - -static pthread_mutex_t mutex4 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX4 pthread_mutex_lock( &mutex4 ); -#define UNLOCK_MUTEX4 pthread_mutex_unlock( &mutex4 ); - -static pthread_mutex_t mutex5 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX5 pthread_mutex_lock( &mutex5 ); -#define UNLOCK_MUTEX5 pthread_mutex_unlock( &mutex5 ); - -static pthread_mutex_t mutex6 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX6 pthread_mutex_lock( &mutex6 ); -#define UNLOCK_MUTEX6 pthread_mutex_unlock( &mutex6 ); - -static pthread_mutex_t mutex7 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX7 pthread_mutex_lock( &mutex7 ); -#define UNLOCK_MUTEX7 pthread_mutex_unlock( &mutex7 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 51 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstMathMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#define LOCK_MUTEX3 -#define UNLOCK_MUTEX3 - -#define LOCK_MUTEX4 -#define UNLOCK_MUTEX4 - -#define LOCK_MUTEX5 -#define UNLOCK_MUTEX5 - -#define LOCK_MUTEX6 -#define UNLOCK_MUTEX6 - -#define LOCK_MUTEX7 -#define UNLOCK_MUTEX7 - -#endif - - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstMathMap *astMathMapId_( int, int, int, const char *[], int, const char *[], const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int GetObjSize( AstObject *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static double Gauss( Rcontext *, int * ); -static double LogGamma( double, int * ); -static double Poisson( Rcontext *, double, int * ); -static double Rand( Rcontext *, int * ); -static int DefaultSeed( const Rcontext *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetSeed( AstMathMap *, int * ); -static int GetSimpFI( AstMathMap *, int * ); -static int GetSimpIF( AstMathMap *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestSeed( AstMathMap *, int * ); -static int TestSimpFI( AstMathMap *, int * ); -static int TestSimpIF( AstMathMap *, int * ); -static void CleanFunctions( int, const char *[], char ***, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearSeed( AstMathMap *, int * ); -static void ClearSimpFI( AstMathMap *, int * ); -static void ClearSimpIF( AstMathMap *, int * ); -static void CompileExpression( const char *, const char *, const char *, int, const char *[], int **, double **, int *, int * ); -static void CompileMapping( const char *, const char *, int, int, int, const char *[], int, const char *[], int ***, int ***, double ***, double ***, int *, int *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void EvaluateFunction( Rcontext *, int, const double **, const int *, const double *, int, double *, int * ); -static void EvaluationSort( const double [], int, int [], int **, int *, int * ); -static void ExtractExpressions( const char *, const char *, int, const char *[], int, char ***, int * ); -static void ExtractVariables( const char *, const char *, int, const char *[], int, int, int, int, int, char ***, int * ); -static void ParseConstant( const char *, const char *, const char *, int, int *, double *, int * ); -static void ParseName( const char *, int, int *, int * ); -static void ParseVariable( const char *, const char *, const char *, int, int, const char *[], int *, int *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetSeed( AstMathMap *, int, int * ); -static void SetSimpFI( AstMathMap *, int, int * ); -static void SetSimpIF( AstMathMap *, int, int * ); -static void ValidateSymbol( const char *, const char *, const char *, int, int, int *, int **, int **, int *, double **, int * ); - -/* Member functions. */ -/* ================= */ -static void CleanFunctions( int nfun, const char *fun[], char ***clean, int *status ) { -/* -* Name: -* CleanFunctions - -* Purpose: -* Make a clean copy of a set of functions. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void CleanFunctions( int nfun, const char *fun[], char ***clean, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This function copies an array of strings, eliminating any white space -* characters and converting to lower case. It is intended for cleaning -* up arrays of function definitions prior to compilation. The returned -* copy is stored in dynamically allocated memory. - -* Parameters: -* nfun -* The number of functions to be cleaned. -* fun -* Pointer to an array, with "nfun" elements, of pointers to null -* terminated strings which contain each of the functions. -* clean -* Address in which to return a pointer to an array (with "nfun" -* elements) of pointers to null terminated strings containing the -* cleaned functions (i.e. this returns an array of strings). -* -* Both the returned array of pointers, and the strings to which they -* point, will be dynamically allocated and should be freed by the -* caller (using astFree) when no longer required. -* status -* Pointer to the inherited status variable. - -* Notes: -* - A NULL value will be returned for "*clean" if this function is -* invoked with the global error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - char c; /* Character from function string */ - int i; /* Loop counter for characters */ - int ifun; /* Loop counter for functions */ - int nc; /* Count of non-blank characters */ - -/* Initialise. */ - *clean = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Allocate and initialise an array to hold the returned pointers. */ - MALLOC_POINTER_ARRAY( *clean, char *, nfun ) - -/* Loop through all the input functions. */ - if ( astOK ) { - for ( ifun = 0; ifun < nfun; ifun++ ) { - -/* Count the number of non-blank characters in each function string. */ - nc = 0; - for ( i = 0; ( c = fun[ ifun ][ i ] ); i++ ) nc += !isspace( c ); - -/* Allocate a string long enough to hold the function with all the - white space removed, storing its pointer in the array allocated - earlier. Check for errors. */ - ( *clean )[ ifun ] = astMalloc( sizeof( char ) * - (size_t) ( nc + 1 ) ); - if ( !astOK ) break; - -/* Loop to copy the non-blank function characters into the new - string. */ - nc = 0; - for ( i = 0; ( c = fun[ ifun ][ i ] ); i++ ) { - if ( !isspace( c ) ) ( *clean )[ ifun ][ nc++ ] = tolower( c ); - } - -/* Null-terminate the result. */ - ( *clean )[ ifun ][ nc ] = '\0'; - } - -/* If an error occurred, then free the main pointer array together - with any strings that have been allocated, resetting the output - value. */ - if ( !astOK ) { - FREE_POINTER_ARRAY( *clean, nfun ) - } - } -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a MathMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* MathMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* MathMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the MathMap. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstMathMap *this; /* Pointer to the MathMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the MathMap structure. */ - this = (AstMathMap *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Seed. */ -/* ----- */ - if ( !strcmp( attrib, "seed" ) ) { - astClearSeed( this ); - -/* SimpFI. */ -/* ------- */ - } else if ( !strcmp( attrib, "simpfi" ) ) { - astClearSimpFI( this ); - -/* SimpIF. */ -/* ------- */ - } else if ( !strcmp( attrib, "simpif" ) ) { - astClearSimpIF( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void CompileExpression( const char *method, const char *class, - const char *exprs, int nvar, const char *var[], - int **code, double **con, int *stacksize, int *status ) { -/* -* Name: -* CompileExpression - -* Purpose: -* Compile a mathematical expression. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void CompileExpression( const char *method, const char *class, -* const char *exprs, int nvar, const char *var[], -* int **code, double **con, int *stacksize ) - -* Class Membership: -* MathMap member function. - -* Description: -* This function checks and compiles a mathematical expression. It -* produces a sequence of operation codes (opcodes) and a set of -* numerical constants which may subsequently be used to evaluate the -* expression on a push-down stack. - -* Parameters: -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function. -* This method name is used solely for constructing error messages. -* class -* Pointer to a constant null-terminated character string containing the -* class name of the Object being processed. This name is used solely -* for constructing error messages. -* exprs -* Pointer to a null-terminated string containing the expression -* to be compiled. This is case sensitive and should contain no white -* space. -* nvar -* The number of variable names defined for use in the expression. -* var -* An array of pointers (with "nvar" elements) to null-terminated -* strings. Each of these should contain a variable name which may -* appear in the expression. These strings are case sensitive and -* should contain no white space. -* code -* Address of a pointer which will be set to point at a dynamically -* allocated array of int containing the set of opcodes (cast to int) -* produced by this function. The first element of this array will -* contain a count of the number of opcodes which follow. -* -* The allocated space must be freed by the caller (using astFree) when -* no longer required. -* con -* Address of a pointer which will be set to point at a dynamically -* allocated array of double containing the set of constants -* produced by this function (this may be NULL if no constants are -* produced). -* -* The allocated space must be freed by the caller (using astFree) when -* no longer required. -* stacksize -* Pointer to an int in which to return the size of the push-down stack -* required to evaluate the expression using the returned opcodes and -* constants. - -* Algorithm: -* The function passes through the input expression searching for -* symbols. It looks for standard symbols (arithmetic operators, -* parentheses, function calls and delimiters) in the next part of the -* expression to be parsed, using identification information stored in -* the static "symbol" array. It ignores certain symbols, according to -* whether they appear to be operators or operands. The choice depends on -* what the previous symbol was; for instance, two operators may not -* occur in succession. Unary +/- operators are also ignored in -* situations where they are not permitted. -* -* If a standard symbol is found, it is passed to the ValidateSymbol -* function, which keeps track of the current level of parenthesis in the -* expression and of the number of arguments supplied to any (possibly -* nested) function calls. This function then accepts or rejects the -* symbol according to whether it is valid within the current context. An -* error is reported if it is rejected. -* -* If the part of the expression currently being parsed did not contain a -* standard symbol, an attempt is made to parse it first as a constant, -* then as a variable name. If either of these succeeds, an appropriate -* symbol number is added to the list of symbols identified so far, and a -* value is added to the list of constants - this is either the value of -* the constant itself, or the identification number of the variable. If -* the expression cannot be parsed, an error is reported. -* -* When the entire expression has been analysed as a sequence of symbols -* (and associated constants), the EvaluationSort function is -* invoked. This sorts the symbols into evaluation order, which is the -* order in which the associated operations must be performed on a -* push-down arithmetic stack to evaluate the expression. This routine -* also substitutes operation codes (defined in the "Oper" enum) for the -* symbol numbers and calculates the size of evaluation stack which will -* be required. - -* Notes: -* - A value of NULL will be returned for the "*code" and "*con" pointers -* and a value of zero will be returned for the "*stacksize" value if this -* function is invoked with the global error status set, or if it should -* fail for any reason. -*/ - -/* Local Variables: */ - double c; /* Value of parsed constant */ - int *argcount; /* Array of argument count information */ - int *opensym; /* Array of opening parenthesis information */ - int *symlist; /* Array of symbol indices */ - int found; /* Standard symbol identified? */ - int iend; /* Ending index in the expression string */ - int istart; /* Staring index in the expression string */ - int isym; /* Loop counter for symbols */ - int ivar; /* Index of variable name */ - int lpar; /* Parenthesis level */ - int ncon; /* Number of constants generated */ - int nsym; /* Number of symbols identified */ - int opernext; /* Next symbol an operator (from left)? */ - int size; /* Size of symbol matched */ - int sym; /* Index of symbol in static "symbol" array */ - int unarynext; /* Next symbol may be unary +/- ? */ - -/* Initialise. */ - *code = NULL; - *con = NULL; - *stacksize = 0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Further initialisation. */ - argcount = NULL; - lpar = 0; - ncon = 0; - nsym = 0; - opensym = NULL; - symlist = NULL; - sym = 0; - ivar = 0; - -/* The first symbol to be encountered must not look like an operator - from the left. It may be a unary + or - operator. */ - opernext = 0; - unarynext = 1; - -/* Search through the expression to classify each symbol which appears - in it. Stop when there are no more input characters or an error is - detected. */ - istart = 0; - for ( istart = 0; astOK && exprs[ istart ]; istart = iend + 1 ) { - -/* Compare each of the symbols in the symbol data with the next - section of the expression, looking for the longest symbol text which - will match. Stop if a NULL "text" value is found, which acts as the - end flag. */ - found = 0; - size = 0; - for ( isym = 0; symbol[ isym ].text; isym++ ) { - -/* Only consider symbols which have text associated with them and - which look like operators or operands from the left, according to the - setting of the "opernext" flag. Thus, if an operator or operand is - missing from the input expression, the next symbol will not be - identified, because it will be of the wrong type. Also exclude unary - +/- operators if they are out of context. */ - if ( symbol[ isym ].size && - ( symbol[ isym ].operleft == opernext ) && - ( !symbol[ isym ].unaryoper || unarynext ) ) { - -/* Test if the text of the symbol matches the expression at the - current position. If so, note that a match has been found. */ - if ( !strncmp( exprs + istart, symbol[ isym ].text, - (size_t) symbol[ isym ].size ) ) { - found = 1; - -/* If this symbol matches more characters than any previous symbol, - then store the symbol's index and note its size. */ - if ( symbol[ isym ].size > size ) { - sym = isym; - size = symbol[ isym ].size; - -/* Calculate the index of the last symbol character in the expression - string. */ - iend = istart + size - 1; - } - } - } - } - -/* If the symbol was identified as one of the standard symbols, then - validate it, updating the parenthesis level and argument count - information at the same time. */ - if ( found ) { - ValidateSymbol( method, class, exprs, iend, sym, &lpar, &argcount, - &opensym, &ncon, con, status ); - -/* If it was not one of the standard symbols, then check if the next - symbol was expected to be an operator. If so, then there is a missing - operator, so report an error. */ - } else { - if ( opernext ) { - astError( AST__MIOPR, - "%s(%s): Missing or invalid operator in the expression " - "\"%.*s\".", status, - method, class, istart + 1, exprs ); - -/* If the next symbol was expected to be an operand, then it may be a - constant, so try to parse it as one. */ - } else { - ParseConstant( method, class, exprs, istart, &iend, &c, status ); - if ( astOK ) { - -/* If successful, set the symbol number to "symbol_ldcon" (load - constant) and extend the "*con" array to accommodate a new - constant. Check for errors. */ - if ( iend >= istart ) { - sym = symbol_ldcon; - *con = astGrow( *con, ncon + 1, sizeof( double ) ); - if ( astOK ) { - -/* Append the constant to the "*con" array. */ - ( *con )[ ncon++ ] = c; - } - -/* If the symbol did not parse as a constant, then it may be a - variable name, so try to parse it as one. */ - } else { - ParseVariable( method, class, exprs, istart, nvar, var, - &ivar, &iend, status ); - if ( astOK ) { - -/* If successful, set the symbol to "symbol_ldvar" (load variable) and - extend the "*con" array to accommodate a new constant. Check for - errors. */ - if ( ivar != -1 ) { - sym = symbol_ldvar; - *con = astGrow( *con, ncon + 1, sizeof( double ) ); - if ( astOK ) { - -/* Append the variable identification number as a constant to the - "*con" array. */ - ( *con )[ ncon++ ] = (double) ivar; - } - -/* If the expression did not parse as a variable name, then there is a - missing operand in the expression, so report an error. */ - } else { - astError( AST__MIOPA, - "%s(%s): Missing or invalid operand in the " - "expression \"%.*s\".", status, - method, class, istart + 1, exprs ); - } - } - } - } - } - } - -/* If there has been no error, then the next symbol in the input - expression has been identified and is valid. */ - if ( astOK ) { - -/* Decide whether the next symbol should look like an operator or an - operand from the left. This is determined by the nature of the symbol - just identified (seen from the right) - two operands or two operators - cannot be adjacent. */ - opernext = !symbol[ sym ].operright; - -/* Also decide whether the next symbol may be a unary +/- operator, - according to the "unarynext" symbol data entry for the symbol just - identified. */ - unarynext = symbol[ sym ].unarynext; - -/* Extend the "symlist" array to accommodate the symbol just - identified. Check for errors. */ - symlist = astGrow( symlist, nsym + 1, sizeof( int ) ); - if ( astOK ) { - -/* Append the symbol's index to the end of this list. */ - symlist[ nsym++ ] = sym; - } - } - } - -/* If there has been no error, check the final context after - identifying all the symbols... */ - if ( astOK ) { - -/* If an operand is still expected, then there is an unsatisfied - operator on the end of the expression, so report an error. */ - if ( !opernext ) { - astError( AST__MIOPA, - "%s(%s): Missing or invalid operand in the expression " - "\"%s\".", status, - method, class, exprs ); - -/* If the final parenthesis level is positive, then there is a missing - right parenthesis, so report an error. */ - } else if ( lpar > 0 ) { - astError( AST__MRPAR, - "%s(%s): Missing right parenthesis in the expression " - "\"%s\".", status, - method, class, exprs ); - } - } - -/* Sort the symbols into evaluation order to produce output opcodes. */ - EvaluationSort( *con, nsym, symlist, code, stacksize, status ); - -/* Free any memory used as workspace. */ - if ( argcount ) argcount = astFree( argcount ); - if ( opensym ) opensym = astFree( opensym ); - if ( symlist ) symlist = astFree( symlist ); - -/* If OK, re-allocate the "*con" array to have the correct size (since - astGrow may have over-allocated space). */ - if ( astOK && *con ) { - *con = astRealloc( *con, sizeof( double ) * (size_t) ncon ); - } - -/* If an error occurred, free any allocated memory and reset the - output values. */ - if ( !astOK ) { - *code = astFree( *code ); - *con = astFree( *con ); - *stacksize = 0; - } -} - -static void CompileMapping( const char *method, const char *class, - int nin, int nout, - int nfwd, const char *fwdfun[], - int ninv, const char *invfun[], - int ***fwdcode, int ***invcode, - double ***fwdcon, double ***invcon, - int *fwdstack, int *invstack, int *status ) { -/* -* Name: -* CompileMapping - -* Purpose: -* Compile the transformation functions for a MathMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void CompileMapping( const char *method, const char *class, -* int nin, int nout, -* int nfwd, const char *fwdfun[], -* int ninv, const char *invfun[], -* int ***fwdcode, int ***invcode, -* double ***fwdcon, double ***invcon, -* int *fwdstack, int *invstack, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This function checks and compiles the transformation functions required -* to create a MathMap. It produces sequences of operation codes (opcodes) -* and numerical constants which may subsequently be used to evaluate the -* functions on a push-down stack. - -* Parameters: -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function. -* This method name is used solely for constructing error messages. -* class -* Pointer to a constant null-terminated character string containing the -* class name of the Object being processed. This name is used solely -* for constructing error messages. -* nin -* Number of input variables for the MathMap. -* nout -* Number of output variables for the MathMap. -* nfwd -* The number of forward transformation functions being supplied. -* This must be at least equal to "nout". -* fwdfun -* Pointer to an array, with "nfwd" elements, of pointers to null -* terminated strings which contain each of the forward transformation -* functions. These must be in lower case and should contain no white -* space. -* ninv -* The number of inverse transformation functions being supplied. -* This must be at least equal to "nin". -* invfun -* Pointer to an array, with "ninv" elements, of pointers to null -* terminated strings which contain each of the inverse transformation -* functions. These must be in lower case and should contain no white -* space. -* fwdcode -* Address in which to return a pointer to an array (with "nfwd" -* elements) of pointers to arrays of int containing the set of opcodes -* (cast to int) for each forward transformation function. The number -* of opcodes produced for each function is given by the first element -* of the opcode array. -* -* Both the returned array of pointers, and the arrays of int to which -* they point, will be stored in dynamically allocated memory and should -* be freed by the caller (using astFree) when no longer required. -* -* If the right hand sides (including the "=" sign) of all the supplied -* functions are absent, then this indicates an undefined transformation -* and the returned pointer value will be NULL. An error results if -* an "=" sign is present but no expression follows it. -* invcode -* Address in which to return a pointer to an array (with "ninv" -* elements) of pointers to arrays of int containing the set of opcodes -* (cast to int) for each inverse transformation function. The number -* of opcodes produced for each function is given by the first element -* of the opcode array. -* -* Both the returned array of pointers, and the arrays of int to which -* they point, will be stored in dynamically allocated memory and should -* be freed by the caller (using astFree) when no longer required. -* -* If the right hand sides (including the "=" sign) of all the supplied -* functions are absent, then this indicates an undefined transformation -* and the returned pointer value will be NULL. An error results if -* an "=" sign is present but no expression follows it. -* fwdcon -* Address in which to return a pointer to an array (with "nfwd" -* elements) of pointers to arrays of double containing the set of -* constants for each forward transformation function. -* -* Both the returned array of pointers, and the arrays of double to which -* they point, will be stored in dynamically allocated memory and should -* be freed by the caller (using astFree) when no longer required. Note -* that any of the pointers to the arrays of double may be NULL if no -* constants are associated with a particular function. -* -* If the forward transformation is undefined, then the returned pointer -* value will be NULL. -* invcon -* Address in which to return a pointer to an array (with "ninv" -* elements) of pointers to arrays of double containing the set of -* constants for each inverse transformation function. -* -* Both the returned array of pointers, and the arrays of double to which -* they point, will be stored in dynamically allocated memory and should -* be freed by the caller (using astFree) when no longer required. Note -* that any of the pointers to the arrays of double may be NULL if no -* constants are associated with a particular function. -* -* If the inverse transformation is undefined, then the returned pointer -* value will be NULL. -* fwdstack -* Pointer to an int in which to return the size of the push-down stack -* required to evaluate the forward transformation functions. -* invstack -* Pointer to an int in which to return the size of the push-down stack -* required to evaluate the inverse transformation functions. -* status -* Pointer to the inherited status variable. - -* Notes: -* - A value of NULL will be returned for the "*fwdcode", "*invcode", -* "*fwdcon" and "*invcon" pointers and a value of zero will be returned -* for the "*fwdstack" and "*invstack" values if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - char **exprs; /* Pointer to array of expressions */ - char **var; /* Pointer to array of variable names */ - const char **strings; /* Pointer to temporary array of strings */ - int ifun; /* Loop counter for functions */ - int nvar; /* Number of variables to extract */ - int stacksize; /* Required stack size */ - -/* Initialise. */ - *fwdcode = NULL; - *invcode = NULL; - *fwdcon = NULL; - *invcon = NULL; - *fwdstack = 0; - *invstack = 0; - nvar = 0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Further initialisation. */ - exprs = NULL; - var = NULL; - -/* Compile the forward transformation. */ -/* ----------------------------------- */ -/* Allocate space for an array of pointers to the functions from which - we will extract variable names. */ - strings = astMalloc( sizeof( char * ) * (size_t) ( nin + nfwd ) ); - -/* Fill the first elements of this array with pointers to the inverse - transformation functions ("nin" in number) which yield the final input - values. These will have the names of the input variables on their left - hand sides. */ - if ( astOK ) { - nvar = 0; - for ( ifun = ninv - nin; ifun < ninv; ifun++ ) { - strings[ nvar++ ] = invfun[ ifun ]; - } - -/* Fill the remaining elements of the array with pointers to the - forward transformation functions. These will have the names of any - intermediate variables plus the final output variables on their left - hand sides. */ - for ( ifun = 0; ifun < nfwd; ifun++ ) strings[ nvar++ ] = fwdfun[ ifun ]; - -/* Extract the variable names from the left hand sides of these - functions and check them for validity and absence of duplication. */ - ExtractVariables( method, class, nvar, strings, nin, nout, nfwd, ninv, 1, - &var, status ); - } - -/* Free the temporary array of string pointers. */ - strings = astFree( strings ); - -/* Extract the expressions from the right hand sides of the forward - transformation functions. */ - ExtractExpressions( method, class, nfwd, fwdfun, 1, &exprs, status ); - -/* If OK, and the forward transformation is defined, then allocate and - initialise space for an array of pointers to the opcodes for each - expression and, similarly, for the constants for each expression. */ - if ( astOK && exprs ) { - MALLOC_POINTER_ARRAY( *fwdcode, int *, nfwd ) - MALLOC_POINTER_ARRAY( *fwdcon, double *, nfwd ) - -/* If OK, loop to compile each of the expressions, storing pointers to - the resulting opcodes and constants in the arrays allocated above. On - each loop, we make progressively more of the variable names in "var" - visible to the compilation function. This ensures that each expression - can only use variables which have been defined earlier. */ - if ( astOK ) { - for ( ifun = 0; ifun < nfwd; ifun++ ) { - CompileExpression( method, class, exprs[ ifun ], - nin + ifun, (const char **) var, - &( *fwdcode )[ ifun ], &( *fwdcon )[ ifun ], - &stacksize, status ); - -/* If an error occurs, then report contextual information and quit. */ - if ( !astOK ) { - astError( astStatus, - "Error in forward transformation function %d.", status, - ifun + 1 ); - break; - } - -/* If OK, calculate the maximum evaluation stack size required by any - of the expressions. */ - *fwdstack = ( *fwdstack > stacksize ) ? *fwdstack : stacksize; - } - } - } - -/* Free the memory containing the extracted expressions and variables. */ - FREE_POINTER_ARRAY( exprs, nfwd ) - FREE_POINTER_ARRAY( var, nvar ) - -/* Compile the inverse transformation. */ -/* ----------------------------------- */ -/* Allocate space for an array of pointers to the functions from which - we will extract variable names. */ - strings = astMalloc( sizeof( char * ) * (size_t) ( nout + ninv ) ); - -/* Fill the first elements of this array with pointers to the forward - transformation functions ("nout" in number) which yield the final - output values. These will have the names of the output variables on - their left hand sides. */ - if ( astOK ) { - nvar = 0; - for ( ifun = nfwd - nout; ifun < nfwd; ifun++ ) { - strings[ nvar++ ] = fwdfun[ ifun ]; - } - -/* Fill the remaining elements of the array with pointers to the - inverse transformation functions. These will have the names of any - intermediate variables plus the final input variables on their left - hand sides. */ - for ( ifun = 0; ifun < ninv; ifun++ ) strings[ nvar++ ] = invfun[ ifun ]; - -/* Extract the variable names from the left hand sides of these - functions and check them for validity and absence of duplication. */ - ExtractVariables( method, class, nvar, strings, nin, nout, nfwd, ninv, 0, - &var, status ); - } - -/* Free the temporary array of string pointers. */ - strings = astFree( strings ); - -/* Extract the expressions from the right hand sides of the inverse - transformation functions. */ - ExtractExpressions( method, class, ninv, invfun, 0, &exprs, status ); - -/* If OK, and the forward transformation is defined, then allocate and - initialise space for an array of pointers to the opcodes for each - expression and, similarly, for the constants for each expression. */ - if ( astOK && exprs ) { - MALLOC_POINTER_ARRAY( *invcode, int *, ninv ) - MALLOC_POINTER_ARRAY( *invcon, double *, ninv ) - -/* If OK, loop to compile each of the expressions, storing pointers to - the resulting opcodes and constants in the arrays allocated above. On - each loop, we make progressively more of the variable names in "var" - visible to the compilation function. This ensures that each expression - can only use variables which have been defined earlier. */ - if ( astOK ) { - for ( ifun = 0; ifun < ninv; ifun++ ) { - CompileExpression( method, class, exprs[ ifun ], - nout + ifun, (const char **) var, - &( *invcode )[ ifun ], &( *invcon )[ ifun ], - &stacksize, status ); - -/* If an error occurs, then report contextual information and quit. */ - if ( !astOK ) { - astError( astStatus, - "Error in inverse transformation function %d.", status, - ifun + 1 ); - break; - } - -/* If OK, calculate the maximum evaluation stack size required by any - of the expressions. */ - *invstack = ( *invstack > stacksize ) ? *invstack : stacksize; - } - } - } - -/* Free the memory containing the extracted expressions and variables. */ - FREE_POINTER_ARRAY( exprs, ninv ) - FREE_POINTER_ARRAY( var, nvar ) - -/* If an error occurred, then free all remaining allocated memory and - reset the output values. */ - if ( !astOK ) { - FREE_POINTER_ARRAY( *fwdcode, nfwd ) - FREE_POINTER_ARRAY( *invcode, ninv ) - FREE_POINTER_ARRAY( *fwdcon, nfwd ) - FREE_POINTER_ARRAY( *invcon, ninv ) - *fwdstack = 0; - *invstack = 0; - } -} - -static int DefaultSeed( const Rcontext *context, int *status ) { -/* -* Name: -* DefaultSeed - -* Purpose: -* Generate an unpredictable seed for a random number generator. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* int DefaultSeed( Rcontext *context, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* On each invocation this function returns an integer value which is -* highly unpredictable. This value may be used as a default seed for the -* random number generator associated with a MathMap, so that it -* generates a different sequence on each occasion. - -* Parameters: -* context -* Pointer to the random number generator context associated with -* the MathMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The unpredictable integer. - -* Notes: -* - This function does not perform error checking and will execute even -* if the global error status is set. -*/ - -/* Local Constants: */ - const int nwarm = 5; /* Number of warm-up iterations */ - const long int a = 8121L; /* Constants for random number generator... */ - const long int c = 28411L; - const long int m = 134456L; - -/* Local Variables; */ - int iwarm; /* Loop counter for warm-up iterations */ - static long init = 0; /* Local initialisation performed? */ - static long int rand; /* Local random integer */ - unsigned long int bits; /* Bit pattern for producing result */ - -/* On the first invocation, initialise a local random number generator - to a value derived by combining bit patterns obtained from the system - clock and the processor time used. The result needs to be positive and - lie in the range 0 to "m-1". */ - LOCK_MUTEX5 - if ( !init ) { - rand = (long int) ( ( (unsigned long int) time( NULL ) ^ - (unsigned long int) clock() ) % - (unsigned long int) m ); - -/* These values will typically only change in their least significant - bits between programs run successively, but by using the bit pattern - as a seed, we ensure that these differences are rapidly propagated to - other bits. To hasten this process, we "warm up" the local generator - with a few iterations. This is a quick and dirty generator using - constants from Press et al. (Numerical recipes). */ - for ( iwarm = 0; iwarm < nwarm; iwarm++ ) { - rand = ( rand * a + c ) % m; - } - -/* Note that this initialisation has been performed. */ - init = 1; - } - UNLOCK_MUTEX5 - -/* Generate a new bit pattern from the system time. Apart from the - first invocation, this will be a different time to that used above. */ - bits = (unsigned long int) time( NULL ); - -/* Mask in a pattern derived from the CPU time used. */ - bits ^= (unsigned long int) clock(); - -/* The system time may change quite slowly (e.g. every second), so - also mask in the address of the random number generator context - supplied. This makes the seed depend on which MathMap is in use. */ - bits ^= (unsigned long int) context; - -/* Now mask in the last random integer produced by the random number - generator whose context has been supplied. This makes the seed depend - on the MathMap's past use of random numbers. */ - bits ^= (unsigned long int) context->random_int; - -/* Finally, in order to produce different seeds when this function is - invoked twice in rapid succession on the same object (with no - intermediate processing), we also mask in a pseudo-random value - generated here. Generate the next local random integer. */ - rand = ( rand * a + c ) % m; - -/* We then scale this value to give an integer in the range 0 to - ULONG_MAX and mask the corresponding bit pattern into our seed. */ - bits ^= (unsigned long int) ( ( (double) rand / (double) ( m - 1UL ) ) * - ( ( (double) ULONG_MAX + 1.0 ) * - ( 1.0 - DBL_EPSILON ) ) ); - -/* Return the integer value of the seed (which may involve discarding - some unwanted bits). */ - return (int) bits; -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two MathMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* MathMap member function (over-rides the astEqual protected -* method inherited from the Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two MathMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a MathMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the MathMaps are equivalent, zero otherwise. - -* Notes: -* - The two MathMaps are considered equivalent if the combination of -* the first in series with the inverse of the second simplifies to a -* UnitMap. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMathMap *that; /* Pointer to the second MathMap structure */ - AstMathMap *this; /* Pointer to the first MathMap structure */ - double **that_con; /* Lists of constants from "that" */ - double **this_con; /* Lists of constants from "this" */ - int **that_code; /* Lists of opcodes from "that" */ - int **this_code; /* Lists of opcodes from "this" */ - int code; /* Opcode value */ - int icode; /* Opcode index */ - int icon; /* Constant index */ - int ifun; /* Function index */ - int ncode; /* No. of opcodes for current "this" function */ - int ncode_that; /* No. of opcodes for current "that" function */ - int nin; /* Number of inputs */ - int nout; /* Number of outputs */ - int pass; /* Check fwd or inv */ - int result; /* Result value to return */ - int that_nfun; /* Number of functions from "that" */ - int this_nfun; /* Number of functions from "this" */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two MathMap structures. */ - this = (AstMathMap *) this_object; - that = (AstMathMap *) that_object; - -/* Check the second object is a MathMap. We know the first is a - MathMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAMathMap( that ) ) { - -/* Check they have the same number of inputs and outputs */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNout( that ) == nout && astGetNin( that ) == nin ) { - -/* Assume equality. */ - result = 1; - -/* The first pass through this next loop compares forward functions, and - the second pass compares inverse functions. */ - for( pass = 0; pass < 2 && result; pass++ ) { - -/* On the first pass, get pointers to the lists of opcodes and constants for - the effective forward transformations (taking into account the value - of the Invert attribute), together with the number of such functions. */ - if( pass == 0 ) { - if( !astGetInvert( this ) ) { - this_code = this->fwdcode; - this_con = this->fwdcon; - this_nfun = this->nfwd; - } else { - this_code = this->invcode; - this_con = this->invcon; - this_nfun = this->ninv; - } - - if( !astGetInvert( that ) ) { - that_code = that->fwdcode; - that_con = that->fwdcon; - that_nfun = that->nfwd; - } else { - that_code = that->invcode; - that_con = that->invcon; - that_nfun = that->ninv; - } - -/* On the second pass, get pointers to the lists of opcodes and constants for - the effective inverse transformations, together with the number of such - functions. */ - } else { - - if( astGetInvert( this ) ) { - this_code = this->fwdcode; - this_con = this->fwdcon; - this_nfun = this->nfwd; - } else { - this_code = this->invcode; - this_con = this->invcon; - this_nfun = this->ninv; - } - - if( astGetInvert( that ) ) { - that_code = that->fwdcode; - that_con = that->fwdcon; - that_nfun = that->nfwd; - } else { - that_code = that->invcode; - that_con = that->invcon; - that_nfun = that->ninv; - } - } - -/* Check that "this" and "that" have the same number of functions */ - if( that_nfun != this_nfun ) result = 0; - -/* Loop round each function. */ - for( ifun = 0; ifun < this_nfun && result; ifun++ ) { - -/* The first element in the opcode array is the number of subsequent - opcodes. Obtain and compare these counts. */ - ncode = this_code ? this_code[ ifun ][ 0 ] : 0; - ncode_that = that_code ? that_code[ ifun ][ 0 ] : 0; - if( ncode != ncode_that ) result = 0; - -/* Compare the following opcodes. Some opcodes consume constants from the - list of constants associated with the MathMap. Compare the constants - for such opcodes. */ - icon = 0; - for( icode = 0; icode < ncode && result; icode++ ){ - code = this_code[ ifun ][ icode ]; - if( that_code[ ifun ][ icode ] != code ) { - result = 0; - - } else if( code == OP_LDCON || - code == OP_LDVAR || - code == OP_MAX || - code == OP_MIN ) { - - if( this_con[ ifun ][ icon ] != - that_con[ ifun ][ icon ] ) { - result = 0; - } else { - icon++; - } - } - } - } - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void EvaluateFunction( Rcontext *rcontext, int npoint, - const double **ptr_in, const int *code, - const double *con, int stacksize, double *out, int *status ) { -/* -* Name: -* EvaluateFunction - -* Purpose: -* Evaluate a compiled function. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void EvaluateFunction( Rcontext *rcontext, int npoint, -* const double **ptr_in, const int *code, -* const double *con, int stacksize, double *out, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This function implements a "virtual machine" which executes operations -* on an arithmetic stack in order to evaluate transformation functions. -* Each operation is specified by an input operation code (opcode) and -* results in the execution of a vector operation on a stack. The final -* result, after executing all the supplied opcodes, is returned as a -* vector. -* -* This function detects arithmetic errors (such as overflow and division -* by zero) and propagates any "bad" coordinate values, including those -* present in the input, to the output. - -* Parameters: -* npoint -* The number of points to be transformd (i.e. the size of the vector -* of values on which operations are to be performed). -* ptr_in -* Pointer to an array of pointers to arrays of double (with "npoint" -* elements). These arrays should contain the input coordinate values, -* such that coordinate number "coord" for point number "point" can be -* found in "ptr_in[coord][point]". -* code -* Pointer to an array of int containing the set of opcodes (cast to int) -* for the operations to be performed. The first element of this array -* should contain a count of the number of opcodes which follow. -* con -* Pointer to an array of double containing the set of constants required -* to evaluate the function (this may be NULL if no constants are -* required). -* stacksize -* The size of the stack required to evaluate the expression using the -* opcodes and constants supplied. This value should be calculated during -* expression compilation. -* out -* Pointer to an array of double (with "npoint" elements) in which to -* return the vector of result values. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ - const int bits = /* Number of bits in an unsigned long */ - sizeof( unsigned long ) * CHAR_BIT; - const double eps = /* Smallest number subtractable from 2.0 */ - 2.0 * DBL_EPSILON; - const double scale = /* 2.0 raised to the power "bits" */ - ldexp( 1.0, bits ); - const double scale1 = /* 2.0 raised to the power "bits-1" */ - scale * 0.5; - const double rscale = /* Reciprocal scale factor */ - 1.0 / scale; - const double rscale1 = /* Reciprocal initial scale factor */ - 1.0 / scale1; - const int nblock = /* Number of blocks of bits to process */ - ( sizeof( double ) + sizeof( unsigned long ) - 1 ) / - sizeof( unsigned long ); - const unsigned long signbit = /* Mask for extracting sign bit */ - 1UL << ( bits - 1 ); - -/* Local Variables: */ - double **stack; /* Array of pointers to stack elements */ - double *work; /* Pointer to stack workspace */ - double *xv1; /* Pointer to first argument vector */ - double *xv2; /* Pointer to second argument vector */ - double *xv3; /* Pointer to third argument vector */ - double *xv; /* Pointer to sole argument vector */ - double *y; /* Pointer to result */ - double *yv; /* Pointer to result vector */ - double abs1; /* Absolute value (temporary variable) */ - double abs2; /* Absolute value (temporary variable) */ - double frac1; /* First (maybe normalised) fraction */ - double frac2; /* Second (maybe normalised) fraction */ - double frac; /* Sole normalised fraction */ - double newexp; /* New power of 2 exponent value */ - double ran; /* Random number */ - double result; /* Function result value */ - double unscale; /* Factor for removing scaling */ - double value; /* Value to be assigned to stack vector */ - double x1; /* First argument value */ - double x2; /* Second argument value */ - double x3; /* Third argument value */ - double x; /* Sole argument value */ - int expon1; /* First power of 2 exponent */ - int expon2; /* Second power of 2 exponent */ - int expon; /* Sole power of 2 exponent */ - int iarg; /* Loop counter for arguments */ - int iblock; /* Loop counter for blocks of bits */ - int icode; /* Opcode value */ - int icon; /* Counter for number of constants used */ - int istk; /* Loop counter for stack elements */ - int ivar; /* Input variable number */ - int narg; /* Number of function arguments */ - int ncode; /* Number of opcodes to process */ - int point; /* Loop counter for stack vector elements */ - int sign; /* Argument is non-negative? */ - int tos; /* Top of stack index */ - static double d2r; /* Degrees to radians conversion factor */ - static double log2; /* Natural logarithm of 2.0 */ - static double pi; /* Value of PI */ - static double r2d; /* Radians to degrees conversion factor */ - static double rsafe_sq; /* Reciprocal of "safe_sq" */ - static double safe_sq; /* Huge value that can safely be squared */ - static int init = 0; /* Initialisation performed? */ - unsigned long b1; /* Block of bits from first argument */ - unsigned long b2; /* Block of bits from second argument */ - unsigned long b; /* Block of bits for result */ - unsigned long neg; /* Result is negative? (sign bit) */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If this is the first invocation of this function, then initialise - constant values. */ - LOCK_MUTEX2 - if ( !init ) { - -/* Trigonometrical conversion factors. */ - pi = acos( -1.0 ); - r2d = 180.0 / pi; - d2r = pi / 180.0; - -/* Natural logarithm of 2.0. */ - log2 = log( 2.0 ); - -/* This value must be safe to square without producing overflow, yet - large enough that adding or subtracting 1.0 from the square makes no - difference. We also need its reciprocal. */ - safe_sq = 0.9 * sqrt( DBL_MAX ); - rsafe_sq = 1.0 / safe_sq; - -/* Note that initialisation has been performed. */ - init = 1; - } - UNLOCK_MUTEX2 - -/* Allocate space for an array of pointers to elements of the - workspace stack (each stack element being an array of double). */ - stack = astMalloc( sizeof( double * ) * (size_t) stacksize ); - -/* Allocate space for the stack itself. */ - work = astMalloc( sizeof( double ) * - (size_t) ( npoint * ( stacksize - 1 ) ) ); - -/* If OK, then initialise the stack pointer array to identify the - start of each vector on the stack. The first element points at the - output array (in which the result will be accumulated), while other - elements point at successive vectors within the workspace allocated - above. */ - if ( astOK ) { - stack[ 0 ] = out; - for ( istk = 1; istk < stacksize; istk++ ) { - stack[ istk ] = work + ( istk - 1 ) * npoint; - } - -/* Define stack operations. */ -/* ======================== */ -/* We now define a set of macros for performing vector operations on - elements of the stack. Each is in the form of a "case" block for - execution in response to the appropriate operation code (opcode). */ - -/* Zero-argument operation. */ -/* ------------------------ */ -/* This macro performs a zero-argument operation, which results in the - insertion of a new vector on to the stack. */ -#define ARG_0(oper,setup,function) \ -\ -/* Test for the required opcode value. */ \ - case oper: \ -\ -/* Perform any required initialisation. */ \ - {setup;} \ -\ -/* Increment the top of stack index and obtain a pointer to the new stack \ - element (vector). */ \ - yv = stack[ ++tos ]; \ -\ -/* Loop to access each vector element, obtaining a pointer to it. */ \ - for ( point = 0; point < npoint; point++ ) { \ - y = yv + point; \ -\ -/* Perform the processing, which results in assignment to this element. */ \ - {function;} \ - } \ -\ -/* Break out of the "case" block. */ \ - break; - -/* One-argument operation. */ -/* ----------------------- */ -/* This macro performs a one-argument operation, which processes the - top stack element without changing the stack size. */ -#define ARG_1(oper,function) \ -\ -/* Test for the required opcode value. */ \ - case oper: \ -\ -/* Obtain a pointer to the top stack element (vector). */ \ - xv = stack[ tos ]; \ -\ -/* Loop to access each vector element, obtaining its value and \ - checking that it is not bad. */ \ - for ( point = 0; point < npoint; point++ ) { \ - if ( ( x = xv[ point ] ) != AST__BAD ) { \ -\ -/* Also obtain a pointer to the element. */ \ - y = xv + point; \ -\ -/* Perform the processing, which uses the element's value and then \ - assigns the result to this element. */ \ - {function;} \ - } \ - } \ -\ -/* Break out of the "case" block. */ \ - break; - -/* One-argument boolean operation. */ -/* ------------------------------- */ -/* This macro is similar in function to ARG_1 above, except that no - checks are made for bad argument values. It is intended for use with - boolean functions where bad values are handled explicitly. */ -#define ARG_1B(oper,function) \ -\ -/* Test for the required opcode value. */ \ - case oper: \ -\ -/* Obtain a pointer to the top stack element (vector). */ \ - xv = stack[ tos ]; \ -\ -/* Loop to access each vector element, obtaining the argument value \ - and a pointer to the element. */ \ - for ( point = 0; point < npoint; point++ ) { \ - x = xv[ point ]; \ - y = xv + point; \ -\ -/* Perform the processing, which uses the element's value and then \ - assigns the result to this element. */ \ - {function;} \ - } \ -\ -/* Break out of the "case" block. */ \ - break; - -/* Two-argument operation. */ -/* ----------------------- */ -/* This macro performs a two-argument operation, which processes the - top two stack elements and produces a single result, resulting in the - stack size decreasing by one. In this case, we first define a macro - without the "case" block statements present. */ -#define DO_ARG_2(function) \ -\ -/* Obtain pointers to the top two stack elements (vectors), decreasing \ - the top of stack index by one. */ \ - xv2 = stack[ tos-- ]; \ - xv1 = stack[ tos ]; \ -\ -/* Loop to access each vector element, obtaining the value of the \ - first argument and checking that it is not bad. */ \ - for ( point = 0; point < npoint; point++ ) { \ - if ( ( x1 = xv1[ point ] ) != AST__BAD ) { \ -\ -/* Also obtain a pointer to the element which is to receive the \ - result. */ \ - y = xv1 + point; \ -\ -/* Obtain the value of the second argument, again checking that it is \ - not bad. */ \ - if ( ( x2 = xv2[ point ] ) != AST__BAD ) { \ -\ -/* Perform the processing, which uses the two argument values and then \ - assigns the result to the appropriate top of stack element. */ \ - {function;} \ -\ -/* If the second argument was bad, so is the result. */ \ - } else { \ - *y = AST__BAD; \ - } \ - } \ - } - -/* This macro simply wraps the one above up in a "case" block. */ -#define ARG_2(oper,function) \ - case oper: \ - DO_ARG_2(function) \ - break; - -/* Two-argument boolean operation. */ -/* ------------------------------- */ -/* This macro is similar in function to ARG_2 above, except that no - checks are made for bad argument values. It is intended for use with - boolean functions where bad values are handled explicitly. */ -#define ARG_2B(oper,function) \ -\ -/* Test for the required opcode value. */ \ - case oper: \ -\ -/* Obtain pointers to the top two stack elements (vectors), decreasing \ - the top of stack index by one. */ \ - xv2 = stack[ tos-- ]; \ - xv1 = stack[ tos ]; \ -\ -/* Loop to access each vector element, obtaining the value of both \ - arguments and a pointer to the element which is to receive the \ - result. */ \ - for ( point = 0; point < npoint; point++ ) { \ - x1 = xv1[ point ]; \ - x2 = xv2[ point ]; \ - y = xv1 + point; \ -\ -/* Perform the processing, which uses the two argument values and then \ - assigns the result to the appropriate top of stack element. */ \ - {function;} \ - } \ -\ -/* Break out of the "case" block. */ \ - break; - -/* Three-argument boolean operation. */ -/* --------------------------------- */ -/* This macro is similar in function to ARG_2B above, except that it - takes three values of the stack and puts one back. It performs no - checks for bad values. */ -#define ARG_3B(oper,function) \ -\ -/* Test for the required opcode value. */ \ - case oper: \ -\ -/* Obtain pointers to the top three stack elements (vectors), decreasing \ - the top of stack index by two. */ \ - xv3 = stack[ tos-- ]; \ - xv2 = stack[ tos-- ]; \ - xv1 = stack[ tos ]; \ -\ -/* Loop to access each vector element, obtaining the value of all 3 \ - arguments and a pointer to the element which is to receive the \ - result. */ \ - for ( point = 0; point < npoint; point++ ) { \ - x1 = xv1[ point ]; \ - x2 = xv2[ point ]; \ - x3 = xv3[ point ]; \ - y = xv1 + point; \ -\ -/* Perform the processing, which uses the three argument values and then \ - assigns the result to the appropriate top of stack element. */ \ - {function;} \ - } \ -\ -/* Break out of the "case" block. */ \ - break; - -/* Define arithmetic operations. */ -/* ============================= */ -/* We now define macros for performing some of the arithmetic - operations we will require in a "safe" way - i.e. trapping numerical - problems such as overflow and invalid arguments and translating them - into the AST__BAD value. */ - -/* Absolute value. */ -/* --------------- */ -/* This is just shorthand. */ -#define ABS(x) ( ( (x) >= 0.0 ) ? (x) : -(x) ) - -/* Integer part. */ -/* ------------- */ -/* This implements rounding towards zero without involving conversion - to an integer (which could overflow). */ -#define INT(x) ( ( (x) >= 0.0 ) ? floor( (x) ) : ceil( (x) ) ) - -/* Trap maths overflow. */ -/* -------------------- */ -/* This macro calls a C maths library function and checks for overflow - in the result. */ -#define CATCH_MATHS_OVERFLOW(function) \ - ( \ -\ -/* Clear the "errno" value. */ \ - errno = 0, \ -\ -/* Evaluate the function. */ \ - result = (function), \ -\ -/* Check if "errno" and the returned result indicate overflow and \ - return the appropriate result. */ \ - ( ( errno == ERANGE ) && ( ABS( result ) == HUGE_VAL ) ) ? AST__BAD : \ - result \ - ) - -/* Trap maths errors. */ -/* ------------------ */ -/* This macro is similar to the one above, except that it also checks - for domain errors (i.e. invalid argument values). */ -#define CATCH_MATHS_ERROR(function) \ - ( \ -\ -/* Clear the "errno" value. */ \ - errno = 0, \ -\ -/* Evaluate the function. */ \ - result = (function), \ -\ -/* Check if "errno" and the returned result indicate a domain error or \ - overflow and return the appropriate result. */ \ - ( ( errno == EDOM ) || \ - ( ( errno == ERANGE ) && ( ABS( result ) == HUGE_VAL ) ) ) ? \ - AST__BAD : result \ - ) - -/* Tri-state boolean OR. */ -/* --------------------- */ -/* This evaluates a boolean OR using tri-state logic. For example, - "a||b" may evaluate to 1 if "a" is bad but "b" is non-zero, so that - the normal rules of bad value propagation do not apply. */ -#define TRISTATE_OR(x1,x2) \ -\ -/* Test if the first argument is bad. */ \ - ( (x1) == AST__BAD ) ? ( \ -\ -/* If so, test the second argument. */ \ - ( ( (x2) == 0.0 ) || ( (x2) == AST__BAD ) ) ? AST__BAD : 1.0 \ - ) : ( \ -\ -/* Test if the second argument is bad. */ \ - ( (x2) == AST__BAD ) ? ( \ -\ -/* If so, test the first argument. */ \ - ( (x1) == 0.0 ) ? AST__BAD : 1.0 \ -\ -/* If neither argument is bad, use the normal OR operator. */ \ - ) : ( \ - ( (x1) != 0.0 ) || ( (x2) != 0.0 ) \ - ) \ - ) - -/* Tri-state boolean AND. */ -/* ---------------------- */ -/* This evaluates a boolean AND using tri-state logic. */ -#define TRISTATE_AND(x1,x2) \ -\ -/* Test if the first argument is bad. */ \ - ( (x1) == AST__BAD ) ? ( \ -\ -/* If so, test the second argument. */ \ - ( (x2) != 0.0 ) ? AST__BAD : 0.0 \ - ) : ( \ -\ -/* Test if the second argument is bad. */ \ - ( (x2) == AST__BAD ) ? ( \ -\ -/* If so, test the first argument. */ \ - ( (x1) != 0.0 ) ? AST__BAD : 0.0 \ -\ -/* If neither argument is bad, use the normal AND operator. */ \ - ) : ( \ - ( (x1) != 0.0 ) && ( (x2) != 0.0 ) \ - ) \ - ) - -/* Safe addition. */ -/* -------------- */ -/* This macro performs addition while avoiding possible overflow. */ -#define SAFE_ADD(x1,x2) ( \ -\ -/* Test if the first argument is non-negative. */ \ - ( (x1) >= 0.0 ) ? ( \ -\ -/* If so, then we can perform addition if the second argument is \ - non-positive. Otherwise, we must calculate the most positive safe \ - second argument value that can be added and test for this (the test \ - itself is safe against overflow). */ \ - ( ( (x2) <= 0.0 ) || ( ( (DBL_MAX) - (x1) ) >= (x2) ) ) ? ( \ -\ -/* Perform addition if it is safe, otherwise return AST__BAD. */ \ - (x1) + (x2) \ - ) : ( \ - AST__BAD \ - ) \ -\ -/* If the first argument is negative, then we can perform addition if \ - the second argument is non-negative. Otherwise, we must calculate the \ - most negative second argument value that can be added and test for \ - this (the test itself is safe against overflow). */ \ - ) : ( \ - ( ( (x2) >= 0.0 ) || ( ( (DBL_MAX) + (x1) ) >= -(x2) ) ) ? ( \ -\ -/* Perform addition if it is safe, otherwise return AST__BAD. */ \ - (x1) + (x2) \ - ) : ( \ - AST__BAD \ - ) \ - ) \ -) - -/* Safe subtraction. */ -/* ----------------- */ -/* This macro performs subtraction while avoiding possible overflow. */ -#define SAFE_SUB(x1,x2) ( \ -\ -/* Test if the first argument is non-negative. */ \ - ( (x1) >= 0.0 ) ? ( \ -\ -/* If so, then we can perform subtraction if the second argument is \ - also non-negative. Otherwise, we must calculate the most negative safe \ - second argument value that can be subtracted and test for this (the \ - test itself is safe against overflow). */ \ - ( ( (x2) >= 0.0 ) || ( ( (DBL_MAX) - (x1) ) >= -(x2) ) ) ? ( \ -\ -/* Perform subtraction if it is safe, otherwise return AST__BAD. */ \ - (x1) - (x2) \ - ) : ( \ - AST__BAD \ - ) \ -\ -/* If the first argument is negative, then we can perform subtraction \ - if the second argument is non-positive. Otherwise, we must calculate \ - the most positive second argument value that can be subtracted and \ - test for this (the test itself is safe against overflow). */ \ - ) : ( \ - ( ( (x2) <= 0.0 ) || ( ( (DBL_MAX) + (x1) ) >= (x2) ) ) ? ( \ -\ -/* Perform subtraction if it is safe, otherwise return AST__BAD. */ \ - (x1) - (x2) \ - ) : ( \ - AST__BAD \ - ) \ - ) \ -) - -/* Safe multiplication. */ -/* -------------------- */ -/* This macro performs multiplication while avoiding possible overflow. */ -#define SAFE_MUL(x1,x2) ( \ -\ -/* Multiplication is safe if the absolute value of either argument is \ - unity or less. Otherwise, we must use the first argument to calculate \ - the maximum absolute value that the second argument may have and test \ - for this (the test itself is safe against overflow). */ \ - ( ( ( abs1 = ABS( (x1) ) ) <= 1.0 ) || \ - ( ( abs2 = ABS( (x2) ) ) <= 1.0 ) || \ - ( ( (DBL_MAX) / abs1 ) >= abs2 ) ) ? ( \ -\ -/* Perform multiplication if it is safe, otherwise return AST__BAD. */ \ - (x1) * (x2) \ - ) : ( \ - AST__BAD \ - ) \ -) - -/* Safe division. */ -/* -------------- */ -/* This macro performs division while avoiding possible overflow. */ -#define SAFE_DIV(x1,x2) ( \ -\ -/* Division is unsafe if the second argument is zero. Otherwise, it is \ - safe if the abolute value of the second argument is unity or \ - more. Otherwise, we must use the second argument to calculate the \ - maximum absolute value that the first argument may have and test for \ - this (the test itself is safe against overflow). */ \ - ( ( (x2) != 0.0 ) && \ - ( ( ( abs2 = ABS( (x2) ) ) >= 1.0 ) || \ - ( ( (DBL_MAX) * abs2 ) >= ABS( (x1) ) ) ) ) ? ( \ -\ -/* Perform division if it is safe, otherwise return AST__BAD. */ \ - (x1) / (x2) \ - ) : ( \ - AST__BAD \ - ) \ -) - -/* Bit-shift operation. */ -/* -------------------- */ -/* This macro shifts the bits in a double value a specified number of - places to the left, which simply corresponds to multiplying by the - appropriate power of two. */ -#define SHIFT_BITS(x1,x2) ( \ -\ -/* Decompose the value into a normalised fraction and a power of 2. */ \ - frac = frexp( (x1), &expon ), \ -\ -/* Calculate the new power of 2 which should apply after the shift, \ - rounding towards zero to give an integer value. */ \ - newexp = INT( (x2) ) + (double) expon, \ -\ -/* If the new exponent is too negative to convert to an integer, then \ - the result must underflow to zero. */ \ - ( newexp < (double) -INT_MAX ) ? ( \ - 0.0 \ -\ -/* Otherwise, if it is too positive to convert to an integer, then the \ - result must overflow, unless the normalised fraction is zero. */ \ - ) : ( ( newexp > (double) INT_MAX ) ? ( \ - ( frac == 0.0 ) ? 0.0 : AST__BAD \ -\ -/* Otherwise, convert the new exponent to an integer and apply \ - it. Trap any overflow which may still occur. */ \ - ) : ( \ - CATCH_MATHS_OVERFLOW( ldexp( frac, (int) newexp ) ) \ - ) ) \ -) - -/* Two-argument bit-wise boolean operation. */ -/* ---------------------------------------- */ -/* This macro expands to code which performs a bit-wise boolean - operation on a pair of arguments and assigns the result to the - variable "result". It operates on floating point (double) values, - which are regarded as if they are fixed-point binary numbers with - negative values expressed in twos-complement notation. This means that - it delivers the same results for integer values as the normal - (integer) C bit-wise operations. However, it will also operate on the - fraction bits of floating point numbers. It also offers greater - precision (the first 53 or so significant bits of the result being - preserved for typical IEEE floating point implementations). */ -#define BIT_OPER(oper,x1,x2) \ -\ -/* Convert each argument to a normalised fraction in the range \ - [0.5,1.0) and a power of two exponent, removing any sign \ - information. */ \ - frac1 = frexp( ABS( (x1) ), &expon1 ); \ - frac2 = frexp( ABS( (x2) ), &expon2 ); \ -\ -/* Set "expon" to be the larger of the two exponents. If the two \ - exponents are not equal, divide the fraction with the smaller exponent \ - by 2 to the power of the exponent difference. This gives both \ - fractions the same effective exponent (although one of them may no \ - longer be normalised). Note that overflow is avoided because all \ - numbers remain less than 1.0, but underflow may occur. */ \ - expon = expon1; \ - if ( expon2 > expon1 ) { \ - expon = expon2; \ - frac1 = ldexp( frac1, expon1 - expon ); \ - } else if ( expon1 > expon2 ) { \ - frac2 = ldexp( frac2, expon2 - expon ); \ - } \ -\ -/* If either of the original arguments is negative, we now subtract \ - the corresponding fraction from 2.0. If we think of the fraction as \ - represented in fixed-point binary notation, this corresponds to \ - converting negative numbers into the twos-complement form normally used \ - for integers (the sign bit being the bit with value 1) instead \ - of having a separate sign bit as for floating point numbers. \ -\ - Note that one of the fractions may have underflowed during the \ - scaling above. In that case (if the original argument was negative), \ - we must subtract the value "eps" (= 2.0 * DBL_EPSILON) from 2.0 \ - instead, so that we produce the largest number less than 2.0. In \ - twos-complement notation this represents the smallest possible \ - negative number and corresponds to extending the sign bit of the \ - original number up into more significant bits. This causes all bits to \ - be set as we require (rather than all being clear if the underflow \ - is simply ignored). */ \ - if ( (x1) < 0.0 ) frac1 = 2.0 - ( ( frac1 > eps ) ? frac1 : eps ); \ - if ( (x2) < 0.0 ) frac2 = 2.0 - ( ( frac2 > eps ) ? frac2 : eps ); \ -\ -/* We now extract the bits from the fraction values into integer \ - variables so that we may perform bit-wise operations on them. However, \ - since a double may be longer than any available integer, we may \ - have to handle several successive blocks of bits individually. */ \ -\ -/* Extract the first block of bits by scaling by the required power of \ - 2 to shift the required bits to the left of the binary point. Then \ - extract the integer part. Note that this initial shift is one bit less \ - than the number of bits in an unsigned long, because we have \ - introduced an extra sign bit. */ \ - frac1 *= scale1; \ - frac2 *= scale1; \ - b1 = (unsigned long) frac1; \ - b2 = (unsigned long) frac2; \ -\ -/* Perform the required bit-wise operation on the extracted blocks of \ - bits. */ \ - b = b1 oper b2; \ -\ -/* Extract the sign bit from this initial result. This determines \ - whether the final result bit pattern should represent a negative \ - floating point number. */ \ - neg = b & signbit; \ -\ -/* Initialise the floating point result by setting it to the integer \ - result multipled by the reciprocal of the scale factor used to shift \ - the bits above. This returns the result bits to their correct \ - significance. */ \ - unscale = rscale1; \ - result = (double) b * unscale; \ -\ -/* We now loop to extract and process further blocks of bits (if \ - present). The number of blocks is determined by the relative lengths \ - of a double and an unsigned long. In practice, some bits of the double \ - will be used by its exponent, so the last block may be incomplete and \ - will simply be padded with zeros. */ \ - for ( iblock = 1; iblock < nblock; iblock++ ) { \ -\ -/* Subtract the integer part (which has already been processed) from \ - each fraction, to leave the bits which remain to be processed. Then \ - multiply by a scale factor to shift the next set of bits to the left \ - of the binary point. This time, we use as many bits as will fit into \ - an unsigned long. */ \ - frac1 = ( frac1 - (double) b1 ) * scale; \ - frac2 = ( frac2 - (double) b2 ) * scale; \ -\ -/* Extract the integer part, which contains the required bits. */ \ - b1 = (unsigned long) frac1; \ - b2 = (unsigned long) frac2; \ -\ -/* Perform the required bit-wise operation on the extracted blocks of \ - bits. */ \ - b = b1 oper b2; \ -\ -/* Update the result floating point value by adding the new integer \ - result multiplied by a scale factor to return the bits to their \ - original significance. */ \ - unscale *= rscale; \ - result += (double) b * unscale; \ - } \ -\ -/* If the (normalised fraction) result represents a negative number, \ - then subtract 2.0 from it (equivalent to subtracting it from 2 and \ - negating the result). This converts back to using a separate sign bit \ - instead of twos-complement notation. */ \ - if ( neg ) result -= 2.0; \ -\ -/* Scale by the required power of 2 to remove the initial \ - normalisation applied and assign the result to the "result" \ - variable. */ \ - result = ldexp( result, expon ) - -/* Gaussian random number. */ -/* ----------------------- */ -/* This macro expands to code which assigns a pseudo-random value to - the "result" variable. The value is drawn from a Gaussian distribution - with mean "x1" and standard deviation "ABS(x2)". */ -#define GAUSS(x1,x2) \ -\ -/* Loop until a satisfactory result is obtained. */ \ - do { \ -\ -/* Obtain a value drawn from a standard Gaussian distribution. */ \ - ran = Gauss( rcontext, status ); \ -\ -/* Multiply by "ABS(x2)", trapping possible overflow. */ \ - result = ABS( (x2) ); \ - result = SAFE_MUL( ran, result ); \ -\ -/* If OK, add "x1", again trapping possible overflow. */ \ - if ( result != AST__BAD ) result = SAFE_ADD( result, (x1) ); \ -\ -/* Continue generating values until one is found which does not cause \ - overflow. */ \ - } while ( result == AST__BAD ); - -/* Implement the stack-based arithmetic. */ -/* ===================================== */ -/* Initialise the top of stack index and constant counter. */ - tos = -1; - icon = 0; - -/* Determine the number of opcodes to be processed and loop to process - them, executing the appropriate "case" block for each one. */ - ncode = code[ 0 ]; - for ( icode = 1; icode <= ncode; icode++ ) { - switch ( (Oper) code[ icode ] ) { - -/* Ignore any null opcodes (which shouldn't occur). */ - case OP_NULL: break; - -/* Otherwise, perform the required vector operation on the stack... */ - -/* User-supplied constants and variables. */ -/* -------------------------------------- */ -/* Loading a constant involves incrementing the constant count and - assigning the next constant's value to the top of stack element. */ - ARG_0( OP_LDCON, value = con[ icon++ ], *y = value ) - -/* Loading a variable involves obtaining the variable's index by - consuming a constant (as above), and then copying the variable's - values into the top of stack element. */ - ARG_0( OP_LDVAR, ivar = (int) ( con[ icon++ ] + 0.5 ), - *y = ptr_in[ ivar ][ point ] ) - -/* System constants. */ -/* ----------------- */ -/* Loading a "bad" value simply means assigning AST__BAD to the top of - stack element. */ - ARG_0( OP_LDBAD, ;, *y = AST__BAD ) - -/* The following load constants associated with the (double) floating - point representation into the top of stack element. */ - ARG_0( OP_LDDIG, ;, *y = (double) AST__DBL_DIG ) - ARG_0( OP_LDEPS, ;, *y = DBL_EPSILON ) - ARG_0( OP_LDMAX, ;, *y = DBL_MAX ) - ARG_0( OP_LDMAX10E, ;, *y = (double) DBL_MAX_10_EXP ) - ARG_0( OP_LDMAXE, ;, *y = (double) DBL_MAX_EXP ) - ARG_0( OP_LDMDIG, ;, *y = (double) DBL_MANT_DIG ) - ARG_0( OP_LDMIN, ;, *y = DBL_MIN ) - ARG_0( OP_LDMIN10E, ;, *y = (double) DBL_MIN_10_EXP ) - ARG_0( OP_LDMINE, ;, *y = (double) DBL_MIN_EXP ) - ARG_0( OP_LDRAD, ;, *y = (double) FLT_RADIX ) - ARG_0( OP_LDRND, ;, *y = (double) FLT_ROUNDS ) - -/* Mathematical constants. */ -/* ----------------------- */ -/* The following load mathematical constants into the top of stack - element. */ - ARG_0( OP_LDE, value = exp( 1.0 ), *y = value ) - ARG_0( OP_LDPI, ;, *y = pi ) - -/* Functions with one argument. */ -/* ---------------------------- */ -/* The following simply evaluate a function of the top of stack - element and assign the result to the same element. */ - ARG_1( OP_ABS, *y = ABS( x ) ) - ARG_1( OP_ACOS, *y = ( ABS( x ) <= 1.0 ) ? - acos( x ) : AST__BAD ) - ARG_1( OP_ACOSD, *y = ( ABS( x ) <= 1.0 ) ? - acos( x ) * r2d : AST__BAD ) - ARG_1( OP_ACOSH, *y = ( x < 1.0 ) ? AST__BAD : - ( ( x > safe_sq ) ? log( x ) + log2 : - log( x + sqrt( x * x - 1.0 ) ) ) ) - ARG_1( OP_ACOTH, *y = ( ABS( x ) <= 1.0 ) ? AST__BAD : - 0.5 * ( log( ( x + 1.0 ) / - ( x - 1.0 ) ) ) ) - ARG_1( OP_ACSCH, *y = ( ( x == 0.0 ) ? AST__BAD : - ( sign = ( x >= 0.0 ), x = ABS( x ), - ( sign ? 1.0 : -1.0 ) * - ( ( x < rsafe_sq ) ? log2 - log( x ) : - ( x = 1.0 / x, - log( x + sqrt( x * x + 1.0 ) ) ) ) ) ) ) - ARG_1( OP_ASECH, *y = ( ( x <= 0 ) || ( x > 1.0 ) ) ? AST__BAD : - ( ( x < rsafe_sq ) ? log2 - log( x ) : - ( x = 1.0 / x, - log( x + sqrt( x * x - 1.0 ) ) ) ) ) - ARG_1( OP_ASIN, *y = ( ABS( x ) <= 1.0 ) ? - asin( x ) : AST__BAD ) - ARG_1( OP_ASIND, *y = ( ABS( x ) <= 1.0 ) ? - asin( x ) * r2d : AST__BAD ) - ARG_1( OP_ASINH, *y = ( sign = ( x >= 0.0 ), x = ABS( x ), - ( sign ? 1.0 : -1.0 ) * - ( ( x > safe_sq ) ? log( x ) + log2 : - log( x + sqrt( x * x + 1.0 ) ) ) ) ) - ARG_1( OP_ATAN, *y = atan( x ) ) - ARG_1( OP_ATAND, *y = atan( x ) * r2d ) - ARG_1( OP_ATANH, *y = ( ABS( x ) >= 1.0 ) ? AST__BAD : - 0.5 * ( log( ( 1.0 + x ) / - ( 1.0 - x ) ) ) ) - ARG_1( OP_CEIL, *y = ceil( x ) ) - ARG_1( OP_COS, *y = cos( x ) ) - ARG_1( OP_COSD, *y = cos( x * d2r ) ) - ARG_1( OP_COSH, *y = CATCH_MATHS_OVERFLOW( cosh( x ) ) ) - ARG_1( OP_COTH, *y = ( x = tanh( x ), SAFE_DIV( 1.0, x ) ) ) - ARG_1( OP_CSCH, *y = ( x = CATCH_MATHS_OVERFLOW( sinh( x ) ), - ( x == AST__BAD ) ? - 0.0 : SAFE_DIV( 1.0, x ) ) ) - ARG_1( OP_EXP, *y = CATCH_MATHS_OVERFLOW( exp( x ) ) ) - ARG_1( OP_FLOOR, *y = floor( x ) ) - ARG_1( OP_INT, *y = INT( x ) ) - ARG_1B( OP_ISBAD, *y = ( x == AST__BAD ) ) - ARG_1( OP_LOG, *y = ( x > 0.0 ) ? log( x ) : AST__BAD ) - ARG_1( OP_LOG10, *y = ( x > 0.0 ) ? log10( x ) : AST__BAD ) - ARG_1( OP_NINT, *y = ( x >= 0 ) ? - floor( x + 0.5 ) : ceil( x - 0.5 ) ) - ARG_1( OP_POISS, *y = Poisson( rcontext, x, status ) ) - ARG_1( OP_SECH, *y = ( x = CATCH_MATHS_OVERFLOW( cosh( x ) ), - ( x == AST__BAD ) ? 0.0 : 1.0 / x ) ) - ARG_1( OP_SIN, *y = sin( x ) ) - ARG_1( OP_SINC, *y = ( x == 0.0 ) ? 1.0 : sin( x ) / x ) - ARG_1( OP_SIND, *y = sin( x * d2r ) ) - ARG_1( OP_SINH, *y = CATCH_MATHS_OVERFLOW( sinh( x ) ) ) - ARG_1( OP_SQR, *y = SAFE_MUL( x, x ) ) - ARG_1( OP_SQRT, *y = ( x >= 0.0 ) ? sqrt( x ) : AST__BAD ) - ARG_1( OP_TAN, *y = CATCH_MATHS_OVERFLOW( tan( x ) ) ) - ARG_1( OP_TAND, *y = tan( x * d2r ) ) - ARG_1( OP_TANH, *y = tanh( x ) ) - -/* Functions with two arguments. */ -/* ----------------------------- */ -/* These evaluate a function of the top two entries on the stack. */ - ARG_2( OP_ATAN2, *y = atan2( x1, x2 ) ) - ARG_2( OP_ATAN2D, *y = atan2( x1, x2 ) * r2d ) - ARG_2( OP_DIM, *y = ( x1 > x2 ) ? x1 - x2 : 0.0 ) - ARG_2( OP_GAUSS, GAUSS( x1, x2 ); *y = result ) - ARG_2( OP_MOD, *y = ( x2 != 0.0 ) ? - fmod( x1, x2 ) : AST__BAD ) - ARG_2( OP_POW, *y = CATCH_MATHS_ERROR( pow( x1, x2 ) ) ) - ARG_2( OP_RAND, ran = Rand( rcontext, status ); - *y = x1 * ran + x2 * ( 1.0 - ran ); ) - ARG_2( OP_SIGN, *y = ( ( x1 >= 0.0 ) == ( x2 >= 0.0 ) ) ? - x1 : -x1 ) - -/* Functions with three arguments. */ -/* ------------------------------- */ -/* These evaluate a function of the top three entries on the stack. */ - ARG_3B( OP_QIF, *y = ( ( x1 ) ? ( x2 ) : ( x3 ) ) ) - - -/* Functions with variable numbers of arguments. */ -/* --------------------------------------------- */ -/* These operations take a variable number of arguments, the actual - number being determined by consuming a constant. We then loop to - perform a 2-argument operation on the stack (as above) the required - number of times. */ - case OP_MAX: - narg = (int) ( con[ icon++ ] + 0.5 ); - for ( iarg = 0; iarg < ( narg - 1 ); iarg++ ) { - DO_ARG_2( *y = ( x1 >= x2 ) ? x1 : x2 ) - } - break; - case OP_MIN: - narg = (int) ( con[ icon++ ] + 0.5 ); - for ( iarg = 0; iarg < ( narg - 1 ); iarg++ ) { - DO_ARG_2( *y = ( x1 <= x2 ) ? x1 : x2 ) - } - break; - -/* Unary arithmetic operators. */ -/* --------------------------- */ - ARG_1( OP_NEG, *y = -x ) - -/* Unary boolean operators. */ -/* ------------------------ */ - ARG_1( OP_NOT, *y = ( x == 0.0 ) ) - -/* Binary arithmetic operators. */ -/* ---------------------------- */ - ARG_2( OP_ADD, *y = SAFE_ADD( x1, x2 ) ) - ARG_2( OP_SUB, *y = SAFE_SUB( x1, x2 ) ) - ARG_2( OP_MUL, *y = SAFE_MUL( x1, x2 ) ) - ARG_2( OP_DIV , *y = SAFE_DIV( x1, x2 ) ) - -/* Bit-shift operators. */ -/* -------------------- */ - ARG_2( OP_SHFTL, *y = SHIFT_BITS( x1, x2 ) ) - ARG_2( OP_SHFTR, *y = SHIFT_BITS( x1, -x2 ) ) - -/* Relational operators. */ -/* --------------------- */ - ARG_2( OP_EQ, *y = ( x1 == x2 ) ) - ARG_2( OP_GE, *y = ( x1 >= x2 ) ) - ARG_2( OP_GT, *y = ( x1 > x2 ) ) - ARG_2( OP_LE, *y = ( x1 <= x2 ) ) - ARG_2( OP_LT, *y = ( x1 < x2 ) ) - ARG_2( OP_NE, *y = ( x1 != x2 ) ) - -/* Bit-wise operators. */ -/* ------------------- */ - ARG_2( OP_BITOR, BIT_OPER( |, x1, x2 ); *y = result ) - ARG_2( OP_BITXOR, BIT_OPER( ^, x1, x2 ); *y = result ) - ARG_2( OP_BITAND, BIT_OPER( &, x1, x2 ); *y = result ) - -/* Binary boolean operators. */ -/* ------------------------- */ - ARG_2B( OP_AND, *y = TRISTATE_AND( x1, x2 ) ) - ARG_2( OP_EQV, *y = ( ( x1 != 0.0 ) == ( x2 != 0.0 ) ) ) - ARG_2B( OP_OR, *y = TRISTATE_OR( x1, x2 ) ) - ARG_2( OP_XOR, *y = ( ( x1 != 0.0 ) != ( x2 != 0.0 ) ) ) - } - } - } - -/* When all opcodes have been processed, the result of the function - evaluation will reside in the lowest stack entry - i.e. the output - array. */ - -/* Free the workspace arrays. */ - work = astFree( work ); - stack = astFree( stack ); - -/* Undefine macros local to this function. */ -#undef ARG_0 -#undef ARG_1 -#undef ARG_1B -#undef DO_ARG_2 -#undef ARG_2 -#undef ARG_2B -#undef ABS -#undef INT -#undef CATCH_MATHS_OVERFLOW -#undef CATCH_MATHS_ERROR -#undef TRISTATE_OR -#undef TRISTATE_AND -#undef SAFE_ADD -#undef SAFE_SUB -#undef SAFE_MUL -#undef SAFE_DIV -#undef SHIFT_BITS -#undef BIT_OPER -#undef GAUSS -} - -static void EvaluationSort( const double con[], int nsym, int symlist[], - int **code, int *stacksize, int *status ) { -/* -* Name: -* EvaluationSort - -* Purpose: -* Perform an evaluation-order sort on parsed expression symbols. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void EvaluationSort( const double con[], int nsym, int symlist[], -* int **code, int *stacksize, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This function sorts a sequence of numbers representing symbols -* identified in an expression. The symbols (i.e. the expression syntax) -* must have been fully validated beforehand, as no validation is -* performed here. -* -* The symbols are sorted into the order in which corresponding -* operations must be performed on a push-down arithmetic stack in order -* to evaluate the expression. Operation codes (opcodes), as defined in -* the "Oper" enum, are then substituted for the symbol numbers. - -* Parameters: -* con -* Pointer to an array of double containing the set of constants -* generated while parsing the expression (these are required in order -* to determine the number of arguments associated with functions which -* take a variable number of arguments). -* nsym -* The number of symbols identified while parsing the expression. -* symlist -* Pointer to an array of int, with "nsym" elements. On entry, this -* should contain the indices in the static "symbol" array of the -* symbols identified while parsing the expression. On exit, the -* contents are undefined. -* code -* Address of a pointer which will be set to point at a dynamically -* allocated array of int containing the set of opcodes (cast to int) -* produced by this function. The first element of this array will -* contain a count of the number of opcodes which follow. -* -* The allocated space must be freed by the caller (using astFree) when -* no longer required. -* stacksize -* Pointer to an int in which to return the size of the push-down stack -* required to evaluate the expression using the returned opcodes. -* status -* Pointer to the inherited status variable. - -* Notes: -* - A value of NULL will be returned for the "*code" pointer and a value -* of zero will be returned for the "*stacksize" value if this function is -* invoked with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - int flush; /* Flush parenthesised symbol sequence? */ - int icon; /* Input constant counter */ - int isym; /* Input symbol counter */ - int ncode; /* Number of opcodes generated */ - int nstack; /* Evaluation stack size */ - int push; /* Push a new symbol on to stack? */ - int sym; /* Variable for symbol number */ - int tos; /* Top of sort stack index */ - -/* Initialise */ - *code = NULL; - *stacksize = 0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Further initialisation. */ - flush = 0; - icon = 0; - isym = 0; - ncode = 0; - nstack = 0; - tos = -1; - -/* Loop to generate output opcodes until the sort stack is empty and - there are no further symbols to process, or an error is detected. */ - while ( astOK && ( ( tos > -1 ) || ( isym < nsym ) ) ) { - -/* Decide whether to push a symbol on to the sort stack (which - "diverts" it so that higher-priority symbols can be output), or to pop - the top symbol off the sort stack and send it to the output - stream... */ - -/* We must push a symbol on to the sort stack if the stack is - currently empty. */ - if ( tos == -1 ) { - push = 1; - -/* We must pop the top symbol off the sort stack if there are no more - input symbols to process. */ - } else if ( isym >= nsym ) { - push = 0; - -/* If the sort stack is being flushed to complete the evaluation of a - parenthesised expression, then the top symbol (which will be the - opening parenthesis or function call) must be popped. This is only - done once, so reset the "flush" flag before the next loop. */ - } else if ( flush ) { - push = 0; - flush = 0; - -/* In all other circumstances, we must push a symbol on to the sort - stack if its evaluation priority (seen from the left) is higher than - that of the current top of stack symbol (seen from the right). This - means it will eventually be sent to the output stream ahead of the - current top of stack symbol. */ - } else { - push = ( symbol[ symlist[ isym ] ].leftpriority > - symbol[ symlist[ tos ] ].rightpriority ); - } - -/* If a symbol is being pushed on to the sort stack, then get the next - input symbol which is to be used. */ - if ( push ) { - sym = symlist[ isym++ ]; - -/* If the symbol decreases the parenthesis level (a closing - parenthesis), then all the sort stack entries down to the symbol which - opened the current level of parenthesis (the matching opening - parenthesis or function call) will already have been sent to the - output stream as a consequence of the evaluation priority defined for - a closing parenthesis in the symbol data. The opening parenthesis (or - function call) must next be flushed from the sort stack, so set the - "flush" flag which is interpreted on the next loop. Ignore the current - symbol, which cancels with the opening parenthesis on the stack. */ - if ( symbol[ sym ].parincrement < 0 ) { - flush = 1; - -/* All other symbols are pushed on to the sort stack. The stack - occupies that region of the "symlist" array from which the input - symbol numbers have already been extracted. */ - } else { - symlist[ ++tos ] = sym; - } - -/* If a symbol is being popped from the top of the sort stack, then - the top of stack entry is transferred to the output stream. Obtain the - symbol number from the stack. Increment the local constant counter if - the associated operation will use a constant. */ - } else { - sym = symlist[ tos-- ]; - icon += ( ( sym == symbol_ldvar ) || ( sym == symbol_ldcon ) ); - -/* If the output symbol does not represent a "null" operation, - increase the size of the output opcode array to accommodate it, - checking for errors. Note that we allocate one extra array element - (the first) which will eventually hold a count of all the opcodes - generated. */ - if ( symbol[ sym ].opcode != OP_NULL ) { - *code = astGrow( *code, ncode + 2, sizeof( int ) ); - if ( astOK ) { - -/* Append the new opcode to the end of this array. */ - ( *code )[ ++ncode ] = (int) symbol[ sym ].opcode; - -/* Increment/decrement the counter representing the stack size - required for evaluation of the expression. If the symbol is a - function with a variable number of arguments (indicated by a negative - "nargs" entry in the symbol data table), then the change in stack size - must be determined from the argument number stored in the constant - table. */ - if ( symbol[ sym ].nargs >= 0 ) { - nstack += symbol[ sym ].stackincrement; - } else { - nstack -= (int) ( con[ icon++ ] + 0.5 ) - 1; - } - -/* Note the maximum size of the stack. */ - *stacksize = ( nstack > *stacksize ) ? nstack : *stacksize; - } - } - } - } - -/* If no "*code" array has been allocated, then allocate one simply to - store the number of opcodes generated, i.e. zero (this shouldn't - normally happen as this represents an invalid expression). */ - if ( !*code ) *code = astMalloc( sizeof( int ) ); - -/* If no error has occurred, store the count of opcodes generated in - the first element of the "*code" array and re-allocate the array to - its final size (since astGrow may have over-allocated space). */ - if ( astOK ) { - ( *code )[ 0 ] = ncode; - *code = astRealloc( *code, sizeof( int ) * (size_t) ( ncode + 1 ) ); - } - -/* If an error occurred, free any memory that was allocated and reset - the output values. */ - if ( !astOK ) { - *code = astFree( *code ); - *stacksize = 0; - } -} - -static void ExtractExpressions( const char *method, const char *class, - int nfun, const char *fun[], int forward, - char ***exprs, int *status ) { -/* -* Name: -* ExtractExpressions - -* Purpose: -* Extract and validate expressions. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void ExtractExpressions( const char *method, const char *class, -* int nfun, const char *fun[], int forward, -* char ***exprs, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This function extracts expressions from the right hand sides of a set -* of functions. These expressions are then validated to check that they -* are either all present, or all absent (absence indicating an undefined -* transformation). An error is reported if anything is found to be -* wrong. -* -* Note that the syntax of the expressions is not checked by this function -* (i.e. they are not compiled). - -* Parameters: -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function. -* This method name is used solely for constructing error messages. -* class -* Pointer to a constant null-terminated character string containing the -* class name of the Object being processed. This name is used solely -* for constructing error messages. -* nfun -* The number of functions to be analysed. -* fun -* Pointer to an array, with "nfun" elements, of pointers to null -* terminated strings which contain each of the functions. These -* strings should contain no white space. -* forward -* A non-zero value indicates the the MathMap's forward transformation -* functions are being processed, while a zero value indicates processing -* of the inverse transformation functions. This value is used solely for -* constructing error messages. -* exprs -* Address in which to return a pointer to an array (with "nfun" -* elements) of pointers to null terminated strings containing the -* extracted expressions (i.e. this returns an array of strings). -* -* Both the returned array of pointers, and the strings to which they -* point, will be stored in dynamically allocated memory and should -* be freed by the caller (using astFree) when no longer required. -* -* If the right hand sides (including the "=" sign) of all the supplied -* functions are absent, then this indicates an undefined transformation -* and the returned pointer value will be NULL. An error results if -* an "=" sign is present but no expression follows it. -* status -* Pointer to the inherited status variable. - -* Notes: -* - A NULL value will be returned for "*exprs" if this function is -* invoked with the global error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - char *ex; /* Pointer to start of expression string */ - int ifun; /* Loop counter for functions */ - int iud; /* Index of first undefined function */ - int nud; /* Number of undefined expressions */ - -/* Initialise. */ - *exprs = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Further initialisation. */ - nud = 0; - iud = 0; - -/* Allocate and initialise memory for the returned array of pointers. */ - MALLOC_POINTER_ARRAY( *exprs, char *, nfun ) - -/* Loop to inspect each function in turn. */ - if ( astOK ) { - for ( ifun = 0; ifun < nfun; ifun++ ) { - -/* Search for the first "=" sign. */ - if ( ( ex = strchr( fun[ ifun ], '=' ) ) ) { - -/* If found, and there are more characters after the "=" sign, then - find the length of the expression which follows. Allocate a string to - hold this expression, storing its pointer in the array allocated - above. Check for errors. */ - if ( *++ex ) { - ( *exprs )[ ifun ] = astMalloc( strlen( ex ) + (size_t) 1 ); - if ( !astOK ) break; - -/* If OK, extract the expression string. */ - (void) strcpy( ( *exprs )[ ifun ], ex ); - -/* If an "=" sign was found but there are no characters following it, - then there is a missing right hand side to a function, so report an - error and quit. */ - } else { - astError( AST__NORHS, - "%s(%s): Missing right hand side in expression: " - "\"%s\".", status, - method, class, fun[ ifun ] ); - astError( astStatus, - "Error in %s transformation function %d.", status, - forward ? "forward" : "inverse", ifun + 1 ); - break; - } - -/* If no "=" sign was found, then the transformation may be undefined, - in which case each function should only contain a variable name. Count - the number of times this happens and record the index of the first - instance. */ - } else { - nud++; - if ( nud == 1 ) iud = ifun; - } - } - } - -/* Either all functions should have an "=" sign (in which case the - transformation is defined), or none of them should have (in which case - it is undefined). If some do and some don't, then report an error, - citing the first instance of a missing "=" sign. */ - if ( astOK && ( nud != 0 ) && ( nud != nfun ) ) { - astError( AST__NORHS, - "%s(%s): Missing right hand side in function: \"%s\".", status, - method, class, fun[ iud ] ); - astError( astStatus, - "Error in %s transformation function %d.", status, - forward ? "forward" : "inverse", iud + 1 ); - } - -/* If an error occurred, or all the expressions were absent, then free any - allocated memory and reset the output value. */ - if ( !astOK || nud ) { - FREE_POINTER_ARRAY( *exprs, nfun ) - } -} - -static void ExtractVariables( const char *method, const char *class, - int nfun, const char *fun[], - int nin, int nout, int nfwd, int ninv, - int forward, char ***var, int *status ) { -/* -* Name: -* ExtractVariables - -* Purpose: -* Extract and validate variable names. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void ExtractVariables( const char *method, const char *class, -* int nfun, const char *fun[], -* int nin, int nout, int nfwd, int ninv, -* int forward, char ***var, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This function extracts variable names from the left hand sides of a -* set of transformation functions belonging to a MathMap. These variable -* names are then validated to check for correct syntax and no -* duplication. An error is reported if anything is wrong with the -* variable names obtained. - -* Parameters: -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function. -* This method name is used solely for constructing error messages. -* class -* Pointer to a constant null-terminated character string containing the -* class name of the Object being processed. This name is used solely -* for constructing error messages. -* nfun -* The number of functions to be analysed. -* fun -* Pointer to an array, with "nfun" elements, of pointers to null -* terminated strings which contain each of the functions. These strings -* are case sensitive and should contain no white space. -* -* The first elements of this array should point to the functions that -* define the primary input/output variables (depending on direction). -* These should be followed by any functions which define intermediate -* variables (taken from the set of functions which transform in the -* opposite direction to the first ones). -* nin -* Number of input variables for the MathMap. -* nout -* Number of output variables for the MathMap. -* nfwd -* Number of forward transformation functions for the MathMap. -* ninv -* Number of inverse transformation functions for the MathMap. -* forward -* A non-zero value indicates the the MathMap's forward transformation -* functions are being processed, while a zero value indicates processing -* of the inverse transformation functions. This value, together with -* "nin", "nout", "nfwd" and "ninv" are used solely for constructing -* error messages. -* var -* Address in which to return a pointer to an array (with "nfun" -* elements) of pointers to null terminated strings containing the -* extracted variable names (i.e. this returns an array of strings). -* -* Both the returned array of pointers, and the strings to which they -* point, will be stored in dynamically allocated memory and should -* be freed by the caller (using astFree) when no longer required. -* status -* Pointer to the inherited status variable. - -* Notes: -* - A NULL value will be returned for "*var" if this function is -* invoked with the global error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - char *duser1; /* Transformation direction for function */ - char *duser2; /* Transformation direction for function */ - char c; /* Extracted character */ - int i1; /* Loop counter for detecting duplicates */ - int i2; /* Loop counter for detecting duplicates */ - int i; /* Loop counter for characters */ - int iend; /* Last character index in parsed name */ - int ifun; /* Loop counter for functions */ - int iuser1; /* Function number as known to the user */ - int iuser2; /* Function number as known to the user */ - int nc; /* Character count */ - int nextra; /* Number of intermediate functions */ - int nprimary; /* Number of primary input/output variables */ - -/* Initialise. */ - *var = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the number of primary input/output variables, depending on - the direction of the coordinate transformation. */ - nprimary = ( forward ? nin : nout ); - -/* Deterine the number of extra (intermediate) functions that come - before these primary ones. These affect the numbering of - transformation functions as known to the user, and must be accounted - for when reporting error messages. */ - nextra = ( forward ? ninv - nin : nfwd - nout ); - -/* Allocate and initialise memory for the returned array of pointers. */ - MALLOC_POINTER_ARRAY( *var, char *, nfun ) - -/* Loop to process each function in turn. */ - if ( astOK ) { - for ( ifun = 0; ifun < nfun; ifun++ ) { - -/* Count the number of characters appearing before the "=" sign (or in - the entire string if the "=" is absent). */ - for ( nc = 0; ( c = fun[ ifun ][ nc ] ); nc++ ) if ( c == '=' ) break; - -/* If no characters were counted, then report an appropriate error - message, depending on whether the function string was entirely - blank. */ - if ( !nc ) { - if ( c ) { - astError( AST__MISVN, - "%s(%s): No left hand side in expression: \"%s\".", status, - method, class, fun[ ifun ] ); - } else { - astError( AST__MISVN, - "%s: Transformation function contains no variable " - "name.", status, - method ); - } - break; - } - -/* If OK, allocate memory to hold the output string and check for - errors. */ - ( *var )[ ifun ] = astMalloc( sizeof( char ) * (size_t) ( nc + 1 ) ) ; - if ( !astOK ) break; - -/* If OK, copy the characters before the "=" sign to the new - string. */ - nc = 0; - for ( i = 0; ( c = fun[ ifun ][ i ] ); i++ ) { - if ( c == '=' ) break; - ( *var )[ ifun ][ nc++] = c; - } - -/* Null terminate the result. */ - ( *var )[ ifun ][ nc ] = '\0'; - -/* Try to parse the contents of the extracted string as a name. */ - ParseName( ( *var )[ ifun ], 0, &iend, status ); - -/* If unsuccessful, or if all the characters were not parsed, then we - have an invalid variable name, so report an error and quit. */ - if ( ( iend < 0 ) || ( *var )[ ifun ][ iend + 1 ] ) { - astError( AST__VARIN, - "%s(%s): Variable name is invalid: \"%s\".", status, - method, class, ( *var )[ ifun ] ); - break; - } - } - -/* If an error occurred above, then determine the function number, and - the direction of the transformation of which it forms part, as known - to the user. */ - if ( !astOK ) { - if ( ifun < nprimary ) { - iuser1 = ifun + 1 + nextra; - duser1 = ( forward ? "inverse" : "forward" ); - } else { - iuser1 = ifun + 1 - nprimary; - duser1 = ( forward ? "forward" : "inverse" ); - } - -/* Report a contextual error message. */ - astError( astStatus, - "Error in %s transformation function %d.", status, - duser1, iuser1 ); - } - } - -/* If there has been no error, loop to compare all the variable names - with each other to detect duplication. */ - if ( astOK ) { - for ( i1 = 1; i1 < nfun; i1++ ) { - for ( i2 = 0; i2 < i1; i2++ ) { - -/* If a duplicate variable name is found, report an error. */ - if ( !strcmp( ( *var )[ i1 ], ( *var )[ i2 ] ) ) { - astError( AST__DUVAR, - "%s(%s): Duplicate definition of variable name: " - "\"%s\".", status, - method, class, ( *var )[ i1 ] ); - -/* For each transformation function involved, determine the function - number and the direction of the transformation of which it forms part, - as known to the user. */ - if ( i1 < nprimary ) { - iuser1 = i1 + 1 + nextra; - duser1 = ( forward ? "inverse" : "forward" ); - } else { - iuser1 = i1 + 1 - nprimary; - duser1 = ( forward ? "forward" : "inverse" ); - } - if ( i2 < nprimary ) { - iuser2 = i2 + 1 + nextra; - duser2 = ( forward ? "inverse" : "forward" ); - } else { - iuser2 = i2 + 1 - nprimary; - duser2 = ( forward ? "forward" : "inverse" ); - } - -/* Report a contextual error message. */ - astError( astStatus, - "Conflict between %s function %d and %s function %d.", status, - duser1, iuser1, duser2, iuser2 ); - break; - } - } - if ( !astOK ) break; - } - } - -/* If an error occurred, free any allocated memory and reset the - output value. */ - if ( !astOK ) { - FREE_POINTER_ARRAY( *var, nfun ) - } -} - -static double Gauss( Rcontext *context, int *status ) { -/* -* Name: -* Gauss - -* Purpose: -* Produce a pseudo-random sample from a standard Gaussian distribution. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* double Gauss( Rcontext *context, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* On each invocation, this function returns a pseudo-random sample drawn -* from a standard Gaussian distribution with mean zero and standard -* deviation unity. The Box-Muller transformation method is used. - -* Parameters: -* context -* Pointer to an Rcontext structure which holds the random number -* generator's context between invocations. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A sample from a standard Gaussian distribution. - -* Notes: -* - The sequence of numbers returned is determined by the "seed" -* value in the Rcontext structure supplied. -* - If the seed value is changed, the "active" flag must also be cleared -* so that this function can re-initiallise the Rcontext structure before -* generating the next pseudo-random number. The "active" flag should -* also be clear to force initialisation the first time an Rcontext -* structure is used. -* - This function does not perform error checking and does not generate -* errors. It will execute even if the global error status is set. -*/ - -/* Local Variables: */ - double rsq; /* Squared radius */ - double s; /* Scale factor */ - double x; /* First result value */ - static double y; /* Second result value */ - static int ysaved = 0; /* Previously-saved value available? */ - - LOCK_MUTEX7 - -/* If the random number generator context is not active, then it will - be (re)initialised on the first invocation of Rand (below). Ensure - that any previously-saved value within this function is first - discarded. */ - if ( !context->active ) ysaved = 0; - -/* If there is a previously-saved value available, then use it and - mark it as no longer available. */ - if ( ysaved ) { - x = y; - ysaved = 0; - -/* Otherwise, loop until a suitable new pair of values has been - obtained. */ - } else { - while ( 1 ) { - -/* Loop to obtain two random values uniformly distributed inside the - unit circle, while avoiding the origin (which maps to an infinite - result). */ - do { - x = 2.0 * Rand( context, status ) - 1.0; - y = 2.0 * Rand( context, status ) - 1.0; - rsq = x * x + y * y; - } while ( ( rsq >= 1.0 ) || ( rsq == 0.0 ) ); - -/* Perform the Box-Muller transformation, checking that this will not - produce overflow (which is extremely unlikely). If overflow would - occur, we simply repeat the above steps with a new pair of random - numbers. */ - s = -2.0 * log( rsq ); - if ( ( DBL_MAX * rsq ) >= s ) { - s = sqrt( s / rsq ); - -/* Scale the original random values to give a pair of results. One will be - returned and the second kept until next time. */ - x *= s; - y *= s; - break; - } - } - -/* Note that a saved value is available. */ - ysaved = 1; - } - - UNLOCK_MUTEX7 - -/* Return the current result. */ - return x; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* MathMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied MathMap, -* in bytes. - -* Parameters: -* this -* Pointer to the MathMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMathMap *this; /* Pointer to MathMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the MathMap structure. */ - this = (AstMathMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - SIZEOF_POINTER_ARRAY( this->fwdfun, this->nfwd ) - SIZEOF_POINTER_ARRAY( this->invfun, this->ninv ) - SIZEOF_POINTER_ARRAY( this->fwdcode, this->nfwd ) - SIZEOF_POINTER_ARRAY( this->invcode, this->ninv ) - SIZEOF_POINTER_ARRAY( this->fwdcon, this->nfwd ) - SIZEOF_POINTER_ARRAY( this->invcon, this->ninv ) - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a MathMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* MathMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a MathMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the MathMap. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the MathMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the MathMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMathMap *this; /* Pointer to the MathMap structure */ - const char *result; /* Pointer value to return */ - int ival; /* Integer attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the MathMap structure. */ - this = (AstMathMap *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* Seed. */ -/* ----- */ - if ( !strcmp( attrib, "seed" ) ) { - ival = astGetSeed( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* SimpFI. */ -/* ------- */ - } else if ( !strcmp( attrib, "simpfi" ) ) { - ival = astGetSimpFI( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* SimpIF. */ -/* ------- */ - } else if ( !strcmp( attrib, "simpif" ) ) { - ival = astGetSimpIF( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; - -} - -void astInitMathMapVtab_( AstMathMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitMathMapVtab - -* Purpose: -* Initialise a virtual function table for a MathMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "mathmap.h" -* void astInitMathMapVtab( AstMathMapVtab *vtab, const char *name ) - -* Class Membership: -* MathMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the MathMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAMathMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->ClearSeed = ClearSeed; - vtab->ClearSimpFI = ClearSimpFI; - vtab->ClearSimpIF = ClearSimpIF; - vtab->GetSeed = GetSeed; - vtab->GetSimpFI = GetSimpFI; - vtab->GetSimpIF = GetSimpIF; - vtab->SetSeed = SetSeed; - vtab->SetSimpFI = SetSimpFI; - vtab->SetSimpIF = SetSimpIF; - vtab->TestSeed = TestSeed; - vtab->TestSimpFI = TestSimpFI; - vtab->TestSimpIF = TestSimpIF; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "MathMap", - "Transformation using mathematical functions" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static double LogGamma( double x, int *status ) { -/* -* Name: -* LogGamma - -* Purpose: -* Calculate the logarithm of the gamma function. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* double LogGamma( double x, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This function returns the natural logarithm of the gamma function -* for real arguments x>0. It uses the approximation of Lanczos, with -* constants from Press et al. (Numerical Recipes), giving a maximum -* fractional error (on the gamma function) of less than 2e-10. - -* Parameters: -* x -* The function argument, which must be greater than zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The natural logarithm of the gamma function with "x" as argument, -* or AST__BAD if "x" is not greater than zero. - -* Notes: -* - This function does not generate errors and does not perform error -* reporting. It will execute even if the global error status is set. -*/ - -/* Local Constants: */ - const double c0 = 1.000000000190015; /* Coefficients for series sum... */ - const double c1 = 76.18009172947146; - const double c2 = -86.50532032941677; - const double c3 = 24.01409824083091; - const double c4 = -1.231739572450155; - const double c5 = 0.1208650973866179e-2; - const double c6 = -0.5395239384953e-5; - const double g = 5.0; - -/* Local Variables: */ - double result; /* Result value to return */ - double sum; /* Series sum */ - double xx; /* Denominator for summing series */ - static double root_twopi; /* sqrt( 2.0 * pi ) */ - static int init = 0; /* Initialisation performed? */ - -/* If initialisation has not yet been performed, calculate the - constant required below. */ - LOCK_MUTEX3 - if ( !init ) { - root_twopi = sqrt( 2.0 * acos( -1.0 ) ); - -/* Note that initialisation has been performed. */ - init = 1; - } - UNLOCK_MUTEX3 - -/* Return a bad value if "x" is not greater than zero. */ - if ( x <= 0.0 ) { - result = AST__BAD; - -/* Otherwise, form the series sum. Since we only use 6 terms, the loop - that would normally be used has been completely unrolled here. */ - } else { - xx = x; - sum = c0; - sum += c1 / ++xx; - sum += c2 / ++xx; - sum += c3 / ++xx; - sum += c4 / ++xx; - sum += c5 / ++xx; - sum += c6 / ++xx; - -/* Calculate the result. */ - result = x + g + 0.5; - result -= ( x + 0.5 ) * log( result ); - result = log( root_twopi * sum / x ) - result; - } - -/* Return the result. */ - return result; -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a MathMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* MathMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated MathMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated MathMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated MathMap which is to be merged with -* its neighbours. This should be a cloned copy of the MathMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* MathMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated MathMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *new; /* Pointer to replacement Mapping */ - AstMathMap *mathmap1; /* Pointer to first MathMap */ - AstMathMap *mathmap2; /* Pointer to second MathMap */ - char **fwd1; /* Pointer to first forward function array */ - char **fwd2; /* Pointer to second forward function array */ - char **inv1; /* Pointer to first inverse function array */ - char **inv2; /* Pointer to second inverse function array */ - int ifun; /* Loop counter for functions */ - int imap1; /* Index of first Mapping */ - int imap2; /* Index of second Mapping */ - int imap; /* Loop counter for Mappings */ - int invert1; /* Invert flag for first MathMap */ - int invert2; /* Invert flag for second MathMap */ - int nfwd1; /* No. forward functions for first MathMap */ - int nfwd2; /* No. forward functions for second MathMap */ - int nin1; /* Number input coords for first MathMap */ - int ninv1; /* No. inverse functions for first MathMap */ - int ninv2; /* No. inverse functions for second MathMap */ - int nout2; /* Number output coords for second MathMap */ - int result; /* Result value to return */ - int simplify; /* Mappings may simplify? */ - -/* Initialise the returned result. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - mathmap1 = NULL; - mathmap2 = NULL; - imap1 = 0; - imap2 = 0; - invert1 = 0; - invert2 = 0; - nfwd1 = 0; - nin1 = 0; - ninv1 = 0; - -/* MathMaps are only worth simplifying if they occur in series. */ - simplify = series; - -/* If simplification appears possible, then obtain the indices of the - nominated mapping and of the one which follows it. Check that a - mapping exists for the second index. */ - if ( simplify ) { - imap1 = where; - imap2 = imap1 + 1; - simplify = ( imap2 < *nmap ); - } - -/* If OK, check whether the class of both Mappings is "MathMap" (a - MathMap can only combine with another MathMap). */ - if ( simplify ) { - simplify = !strcmp( astGetClass( ( *map_list )[ imap1 ] ), "MathMap" ); - } - if ( astOK && simplify ) { - simplify = !strcmp( astGetClass( ( *map_list )[ imap2 ] ), "MathMap" ); - } - -/* If still OK, obtain pointers to the two MathMaps and the associated - invert flag values. */ - if ( astOK && simplify ) { - mathmap1 = (AstMathMap *) ( *map_list )[ imap1 ]; - mathmap2 = (AstMathMap *) ( *map_list )[ imap2 ]; - invert1 = ( *invert_list )[ imap1 ]; - invert2 = ( *invert_list )[ imap2 ]; - -/* Depending on the invert flag values, obtain the SimpFI or SimpIF - attribute value from each MathMap and check whether they are set so as - to permit simplification. */ - simplify = ( ( invert1 ? astGetSimpIF( mathmap1 ) : - astGetSimpFI( mathmap1 ) ) && - ( invert2 ? astGetSimpFI( mathmap2 ) : - astGetSimpIF( mathmap2 ) ) ); - } - -/* If still OK, obtain the effective numbers of input coordinates for - the first MathMap and output coordinates for the second. Take account - of the associated invert flags and the way the Invert attribute of - each MathMap is currently set. */ - if ( astOK && simplify ) { - nin1 = ( invert1 == astGetInvert( mathmap1 ) ) ? - astGetNin( mathmap1 ) : astGetNout( mathmap1 ); - nout2 = ( invert2 == astGetInvert( mathmap2 ) ) ? - astGetNout( mathmap2 ) : astGetNin( mathmap2 ); - -/* Simplification is only possible if these two numbers are equal - (otherwise the the two MathMaps cannot be identical). */ - simplify = ( nin1 == nout2 ); - } - -/* If still OK, obtain the effective number of forward transformation - functions for the first MathMap (allowing for the associated invert - flag). Similarly, obtain the effective number of inverse - transformation functions for the second MathMap. */ - if ( astOK && simplify ) { - nfwd1 = !invert1 ? mathmap1->nfwd : mathmap1->ninv; - ninv2 = !invert2 ? mathmap2->ninv : mathmap2->nfwd; - -/* Check whether these values are equal. The MathMaps cannot be - identical if they are not. */ - simplify = ( nfwd1 == ninv2 ); - } - -/* As above, obtain pointers to the array of effective forward - transformation functions for the first MathMap, and the effective - inverse transformation functions for the second MathMap. */ - if ( astOK && simplify ) { - fwd1 = !invert1 ? mathmap1->fwdfun : mathmap1->invfun; - inv2 = !invert2 ? mathmap2->invfun : mathmap2->fwdfun; - -/* Loop to check whether these two sets of functions are - identical. The MathMaps cannot be merged unless they are. */ - for ( ifun = 0; ifun < nfwd1; ifun++ ) { - simplify = !strcmp( fwd1[ ifun ], inv2[ ifun ] ); - if ( !simplify ) break; - } - } - -/* If OK, repeat the above process to compare the effective inverse - transformation functions of the first MathMap with the forward - functions of the second one. */ - if ( astOK && simplify ) { - ninv1 = !invert1 ? mathmap1->ninv : mathmap1->nfwd; - nfwd2 = !invert2 ? mathmap2->nfwd : mathmap2->ninv; - simplify = ( ninv1 == nfwd2 ); - } - if ( astOK && simplify ) { - inv1 = !invert1 ? mathmap1->invfun : mathmap1->fwdfun; - fwd2 = !invert2 ? mathmap2->fwdfun : mathmap2->invfun; - for ( ifun = 0; ifun < ninv1; ifun++ ) { - simplify = !strcmp( inv1[ ifun ], fwd2[ ifun ] ); - if ( !simplify ) break; - } - } - -/* If the two MathMaps can be merged, create a UnitMap as a - replacement. */ - if ( astOK && simplify ) { - new = (AstMapping *) astUnitMap( nin1, "", status ); - -/* If OK, annul the pointers to the original MathMaps. */ - if ( astOK ) { - ( *map_list )[ imap1 ] = astAnnul( ( *map_list )[ imap1 ] ); - ( *map_list )[ imap2 ] = astAnnul( ( *map_list )[ imap2 ] ); - -/* Insert the pointer to the replacement UnitMap and store the - associated invert flag. */ - ( *map_list )[ imap1 ] = new; - ( *invert_list )[ imap1 ] = 0; - -/* Loop to move the following Mapping pointers and invert flags down - in their arrays to close the gap. */ - for ( imap = imap2 + 1; imap < *nmap; imap++ ) { - ( *map_list )[ imap - 1 ] = ( *map_list )[ imap ]; - ( *invert_list )[ imap - 1 ] = ( *invert_list )[ imap ]; - } - -/* Clear the final entry in each array. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = imap1; - } - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static void ParseConstant( const char *method, const char *class, - const char *exprs, int istart, int *iend, - double *con, int *status ) { -/* -* Name: -* ParseConstant - -* Purpose: -* Parse a constant. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void ParseConstant( const char *method, const char *class, -* const char *exprs, int istart, int *iend, -* double *con, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This routine parses an expression, looking for a constant starting at -* the character with index "istart" in the string "exprs". If it -* identifies the constant successfully, "*con" it will return its value -* and "*iend" will be set to the index of the final constant character -* in "exprs". -* -* If the characters encountered are clearly not part of a constant (it -* does not begin with a numeral or decimal point) the function returns -* with "*con" set to zero and "*iend" set to -1, but without reporting -* an error. However, if the first character appears to be a constant but -* its syntax proves to be invalid, then an error is reported. -* -* The expression must be in lower case with no embedded white space. -* The constant must not have a sign (+ or -) in front of it. - -* Parameters: -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function. -* This method name is used solely for constructing error messages. -* class -* Pointer to a constant null-terminated character string containing the -* class name of the Object being processed. This name is used solely -* for constructing error messages. -* exprs -* Pointer to a null-terminated string containing the expression -* to be parsed. -* istart -* Index of the first character in "exprs" to be considered by this -* function. -* iend -* Pointer to an int in which to return the index in "exprs" of the -* final character which forms part of the constant. If no constant is -* found, a value of -1 is returned. -* con -* Pointer to a double, in which the value of the constant, if found, -* will be returned. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - char *str; /* Pointer to temporary string */ - char c; /* Single character from the expression */ - int dpoint; /* Decimal point encountered? */ - int expon; /* Exponent character encountered? */ - int i; /* Loop counter for characters */ - int iscon; /* Character is part of the constant? */ - int n; /* Number of values read by astSscanf */ - int nc; /* Number of characters read by astSscanf */ - int numer; /* Numeral encountered in current field? */ - int sign; /* Sign encountered? */ - int valid; /* Constant syntax valid? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise. */ - *con = 0.0; - *iend = -1; - -/* Check if the expression starts with a numeral or a decimal point. */ - c = exprs[ istart ]; - numer = isdigit( c ); - dpoint = ( c == '.' ); - -/* If it begins with any of these, the expression is clearly intended - to be a constant, so any failure beyond this point will result in an - error. Otherwise, failure to find a constant is not an error. */ - if ( numer || dpoint ) { - -/* Initialise remaining variables specifying the parser context. */ - expon = 0; - sign = 0; - valid = 1; - -/* Loop to increment the last constant character position until the - following character in the expression does not look like part of the - constant. */ - *iend = istart; - iscon = 1; - while ( ( c = exprs[ *iend + 1 ] ) && iscon ) { - iscon = 0; - -/* It may be part of a numerical constant if it is a numeral, wherever - it occurs. */ - if ( isdigit( c ) ) { - numer = 1; - iscon = 1; - -/* Or a decimal point, so long as it is the first one and is not in - the exponent field. Otherwise it is invalid. */ - } else if ( c == '.' ) { - if ( !( dpoint || expon ) ) { - dpoint = 1; - iscon = 1; - } else { - valid = 0; - } - -/* Or if it is a 'd' or 'e' exponent character, so long as it is the - first one and at least one numeral has been encountered first. - Otherwise it is invalid. */ - } else if ( ( c == 'd' ) || ( c == 'e' ) ) { - if ( !expon && numer ) { - expon = 1; - numer = 0; - iscon = 1; - } else { - valid = 0; - } - -/* Or if it is a sign, so long as it is in the exponent field and is - the first sign with no previous numerals in the same field. Otherwise - it is invalid (unless numerals have been encountered, in which case it - marks the end of the constant). */ - } else if ( ( c == '+' ) || ( c == '-' ) ) { - if ( expon && !sign && !numer ) { - sign = 1; - iscon = 1; - } else if ( !numer ) { - valid = 0; - } - } - -/* Increment the character count if the next character may be part of - the constant, or if it was invalid (it will then form part of the - error message). */ - if ( iscon || !valid ) ( *iend )++; - } - -/* Finally, check that the last field contained a numeral. */ - valid = ( valid && numer ); - -/* If the constant appears valid, allocate a temporary string to hold - it. */ - if ( valid ) { - str = astMalloc( (size_t) ( *iend - istart + 2 ) ); - if ( astOK ) { - -/* Copy the constant's characters, changing 'd' to 'e' so that - "astSscanf" will recognise it as an exponent character. */ - for ( i = istart; i <= *iend; i++ ) { - str[ i - istart ] = ( exprs[ i ] == 'd' ) ? 'e' : exprs[ i ]; - } - str[ *iend - istart + 1 ] = '\0'; - -/* Attempt to read the constant as a double, noting how many values - are read and how many characters consumed. */ - n = astSscanf( str, "%lf%n", con, &nc ); - -/* Check that one value was read and all the characters consumed. If - not, then the constant's syntax is invalid. */ - if ( ( n != 1 ) || ( nc < ( *iend - istart + 1 ) ) ) valid = 0; - } - -/* Free the temporary string. */ - str = astFree( str ); - } - -/* If the constant syntax is invalid, and no other error has occurred, - then report an error. */ - if ( astOK && !valid ) { - astError( AST__CONIN, - "%s(%s): Invalid constant syntax in the expression " - "\"%.*s\".", status, - method, class, *iend + 1, exprs ); - } - -/* If an error occurred, reset the output values. */ - if ( !astOK ) { - *iend = -1; - *con = 0.0; - } - } -} - -static void ParseName( const char *exprs, int istart, int *iend, int *status ) { -/* -* Name: -* ParseName - -* Purpose: -* Parse a name. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void ParseName( const char *exprs, int istart, int *iend, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This routine parses an expression, looking for a name starting at the -* character with index "istart" in the string "exprs". If it identifies -* a name successfully, "*iend" will return the index of the final name -* character in "exprs". A name must begin with an alphabetic character -* and subsequently contain only alphanumeric characters or underscores. -* -* If the expression does not contain a name at the specified location, -* "*iend" is set to -1. No error results. -* -* The expression should not contain embedded white space. - -* Parameters: -* exprs -* Pointer to a null-terminated string containing the expression -* to be parsed. -* istart -* Index of the first character in "exprs" to be considered by this -* function. -* iend -* Pointer to an int in which to return the index in "exprs" of the -* final character which forms part of the name. If no name is -* found, a value of -1 is returned. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - char c; /* Single character from expression */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise. */ - *iend = -1; - -/* Check the first character is valid for a name (alphabetic). */ - if ( isalpha( exprs[ istart ] ) ) { - -/* If so, loop to inspect each subsequent character until one is found - which is not part of a name (not alphanumeric or underscore). */ - for ( *iend = istart; ( c = exprs[ *iend + 1 ] ); ( *iend )++ ) { - if ( !( isalnum( c ) || ( c == '_' ) ) ) break; - } - } -} - -static void ParseVariable( const char *method, const char *class, - const char *exprs, int istart, int nvar, - const char *var[], int *ivar, int *iend, int *status ) { -/* -* Name: -* ParseVariable - -* Purpose: -* Parse a variable name. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void ParseVariable( const char *method, const char *class, -* const char *exprs, int istart, int nvar, -* const char *var[], int *ivar, int *iend, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This routine parses an expression, looking for a recognised variable -* name starting at the character with index "istart" in the string -* "exprs". If it identifies a variable name successfully, "*ivar" will -* return a value identifying it and "*iend" will return the index of the -* final variable name character in "exprs". To be recognised, a name -* must begin with an alphabetic character and subsequently contain only -* alphanumeric characters or underscores. It must also appear in the -* list of defined variable names supplied to this function. -* -* If the expression does not contain a name at the specified location, -* "*ivar" and "*iend" are set to -1 and no error results. However, if -* the expression contains a name but it is not in the list of defined -* variable names supplied, then an error is reported. -* -* This function is case sensitive. The expression should not contain -* embedded white space. - -* Parameters: -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function. -* This method name is used solely for constructing error messages. -* class -* Pointer to a constant null-terminated character string containing the -* class name of the Object being processed. This name is used solely -* for constructing error messages. -* exprs -* Pointer to a null-terminated string containing the expression -* to be parsed. -* istart -* Index of the first character in "exprs" to be considered by this -* function. -* nvar -* The number of defined variable names. -* var -* An array of pointers (with "nvar" elements) to null-terminated -* strings. Each of these should contain a variable name to be -* recognised. These strings are case sensitive and should contain -* no white space. -* ivar -* Pointer to an int in which to return the index in "vars" of the -* variable name found. If no variable name is found, a value of -1 -* is returned. -* iend -* Pointer to an int in which to return the index in "exprs" of the -* final character which forms part of the variable name. If no variable -* name is found, a value of -1 is returned. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int found; /* Variable name recognised? */ - int nc; /* Number of characters in variable name */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise. */ - *ivar = -1; - *iend = -1; - -/* Determine if the characters in the expression starting at index - "istart" constitute a valid name. */ - ParseName( exprs, istart, iend, status ); - -/* If so, calculate the length of the name. */ - if ( *iend >= istart ) { - nc = *iend - istart + 1; - -/* Loop to compare the name with the list of variable names - supplied. */ - found = 0; - for ( *ivar = 0; *ivar < nvar; ( *ivar )++ ) { - found = ( nc == (int) strlen( var[ *ivar ] ) ) && - !strncmp( exprs + istart, var[ *ivar ], (size_t) nc ); - -/* Break if the name is recognised. */ - if ( found ) break; - } - -/* If it was not recognised, then report an error and reset the output - values. */ - if ( !found ) { - astError( AST__UDVOF, - "%s(%s): Undefined variable or function in the expression " - "\"%.*s\".", status, - method, class, *iend + 1, exprs ); - *ivar = -1; - *iend = -1; - } - } -} - -static double Poisson( Rcontext *context, double mean, int *status ) { -/* -* Name: -* Poisson - -* Purpose: -* Produce a pseudo-random sample from a Poisson distribution. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* double Poisson( Rcontext *context, double mean, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* On each invocation, this function returns a pseudo-random sample drawn -* from a Poisson distribution with a specified mean. A combination of -* methods is used, depending on the value of the mean. The algorithm is -* based on that given by Press et al. (Numerical Recipes), but -* re-implemented and extended. - -* Parameters: -* context -* Pointer to an Rcontext structure which holds the random number -* generator's context between invocations. -* mean -* The mean of the Poisson distribution, which should not be -* negative. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A sample (which will only take integer values) from the Poisson -* distribution, or AST__BAD if the mean supplied is negative. - -* Notes: -* - The sequence of numbers returned is determined by the "seed" -* value in the Rcontext structure supplied. -* - If the seed value is changed, the "active" flag must also be cleared -* so that this function can re-initiallise the Rcontext structure before -* generating the next pseudo-random number. The "active" flag should -* also be clear to force initialisation the first time an Rcontext -* structure is used. -* - This function does not perform error checking and does not generate -* errors. It will execute even if the global error status is set. -*/ - -/* Local Constants: */ - const double small = 9.3; /* "Small" distribution mean value */ - -/* Local Variables: */ - double pfract; /* Probability of accepting sample */ - double product; /* Product of random samples */ - double ran; /* Sample from Lorentzian distribution */ - double result; /* Result value to return */ - static double beta; /* Constant for forming acceptance ratio */ - static double huge; /* Large mean where std. dev. is negligible */ - static double last_mean; /* Value of "mean" on last invocation */ - static double log_mean; /* Logarithm of "mean" */ - static double pi; /* Value of pi */ - static double ranmax; /* Maximum safe value of "ran" */ - static double root_2mean; /* sqrt( 2.0 * mean ) */ - static double sqrt_point9; /* Square root of 0.9 */ - static double thresh; /* Threshold for product of samples */ - static int init = 0; /* Local initialisation performed? */ - - LOCK_MUTEX6 - -/* If initialisation has not yet been performed, then perform it - now. */ - if ( !init ) { - -/* Initialise the mean value from the previous invocation. */ - last_mean = -1.0; - -/* Calculate simple constants. */ - pi = acos( -1.0 ); - sqrt_point9 = sqrt( 0.9 ); - -/* Calculate the value of the distribution mean for which the smallest - representable deviation from the mean permitted by the machine - precision is one thousand standard deviations. */ - huge = pow( 1.0e3 / DBL_EPSILON, 2.0 ); - -/* Calculate the largest value such that - (0.9+(sqrt_point9*ranmax)*(sqrt_point9*ranmax)) doesn't overflow, - allowing a small margin for rounding error. */ - ranmax = ( sqrt( DBL_MAX - 0.9 ) / sqrt( 0.9 ) ) * - ( 1.0 - 4.0 * DBL_EPSILON ); - -/* Note that initialisation has been performed. */ - init = 1; - } - -/* If the distribution mean is less than zero, then return a bad - result. */ - if ( mean < 0.0 ) { - result = AST__BAD; - -/* If the mean is zero, then the result can only be zero. */ - } else if ( mean == 0.0 ) { - result = 0.0; - -/* Otherwise, if the mean is sufficiently small, we can use the direct - method of summing a series of exponentially distributed random samples - and counting the number which occur before the mean is exceeded. This - is equivalent to multiplying a series of uniformly distributed - samples and counting the number which occur before the product - becomes less then an equivalent threshold. */ - } else if ( mean <= small ) { - -/* If the mean has changed since the last invocation, store the new - mean and calculate a new threshold. */ - if ( mean != last_mean ) { - last_mean = mean; - thresh = exp( -mean ); - } - -/* Initialise the product and the result. */ - product = 1.0; - result = -1.0; - -/* Multiply the random samples, counting the number needed to reach - the threshold. */ - do { - product *= Rand( context, status ); - result += 1.0; - } while ( product > thresh ); - -/* Otherwise, if the distribution mean is large (but not huge), we - must use an indirect rejection method. */ - } else if ( mean <= huge ) { - -/* If the mean has changed since the last invocation, then - re-calculate the constants required below. Note that because of the - restrictions we have placed on "mean", these calculations are safe - against overflow. */ - if ( mean != last_mean ) { - last_mean = mean; - log_mean = log( mean ); - root_2mean = sqrt( 2.0 * mean ); - beta = mean * log_mean - LogGamma( mean + 1.0, status ); - } - -/* Loop until a suitable random sample has been generated. */ - do { - do { - -/* First transform a sample from a uniform distribution to obtain a - sample from a Lorentzian distribution. Check that the result is not so - large as to cause overflow later. Also check for overflow in the maths - library. If necessary, obtain a new sample. */ - do { - errno = 0; - ran = tan( pi * Rand( context, status ) ); - } while ( ( ran > ranmax ) || - ( ( errno == ERANGE ) && - ( ( ( ran >= 0.0 ) ? ran : -ran ) == HUGE_VAL ) ) ); - -/* If OK, scale the sample and add a constant so that the sample's - distribution approximates the Poisson distribution we - require. Overflow is prevented by the check on "ran" above, together - with the restricted value of "mean". */ - result = ran * root_2mean + mean; - -/* If the result is less than zero (where the Poisson distribution has - value zero), then obtain a new sample. */ - } while ( result < 0.0 ); - -/* Round down to an integer, so that the sample is valid for a Poisson - distribution. */ - result = floor( result ); - -/* Calculate the ratio between the required Poisson distribution and - the Lorentzian from which we have sampled (the factor of 0.9 prevents - this exceeding 1.0, and overflow is again prevented by the checks - performed above). */ - ran *= sqrt_point9; - pfract = ( 0.9 + ran * ran ) * - exp( result * log_mean - LogGamma( result + 1.0, status ) - beta ); - -/* Accept the sample with this fractional probability, otherwise - obtain a new sample. */ - } while ( Rand( context, status ) > pfract ); - -/* If the mean is huge, the relative standard deviation will be - negligible compared to the machine precision. In such cases, the - probability of getting a result that differs from the mean is - effectively zero, so we can simply return the mean. */ - } else { - result = mean; - } - - UNLOCK_MUTEX6 - -/* Return the result. */ - return result; -} - -static double Rand( Rcontext *context, int *status ) { -/* -* Name: -* Rand - -* Purpose: -* Produce a uniformly distributed pseudo-random number. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* double Rand( Rcontext *context, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* On each invocation, this function returns a pseudo-random number -* uniformly distributed in the range 0.0 to 1.0 (inclusive). The -* underlying algorithm is that used by the "ran2" function of Press et -* al. (Numerical Recipes), which has a long period and good statistical -* properties. This independent implementation returns double precision -* values. - -* Parameters: -* context -* Pointer to an Rcontext structure which holds the random number -* generator's context between invocations. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The sequence of numbers returned is determined by the "seed" -* value in the Rcontext structure supplied. -* - If the seed value is changed, the "active" flag must also be cleared -* so that this function can re-initiallise the Rcontext structure before -* generating the next pseudo-random number. The "active" flag should -* also be clear to force initialisation the first time an Rcontext -* structure is used. -* - This function does not perform error checking and does not generate -* errors. It will execute even if the global error status is set. -*/ - -/* Local Constants: */ - const long int a1 = 40014L; /* Random number generator constants... */ - const long int a2 = 40692L; - const long int m1 = 2147483563L; - const long int m2 = 2147483399L; - const long int q1 = 53668L; - const long int q2 = 52774L; - const long int r1 = 12211L; - const long int r2 = 3791L; - const int ntab = /* Size of shuffle table */ - AST_MATHMAP_RAND_CONTEXT_NTAB_; - const int nwarm = 8; /* Number of warm-up iterations */ - -/* Local Variables: */ - double result; /* Result value to return */ - double scale; /* Scale factor for random integers */ - double sum; /* Sum for forming normalisation constant */ - int dbits; /* Approximate bits in double mantissa */ - int irand; /* Loop counter for random integers */ - int itab; /* Loop counter for shuffle table */ - int lbits; /* Approximate bits used by generators */ - long int seed; /* Random number seed */ - long int tmp; /* Temporary variable */ - static double norm; /* Normalisation constant */ - static double scale0; /* Scale decrement for successive integers */ - static int init = 0; /* Local initialisation performed? */ - static int nrand; /* Number of random integers to use */ - -/* If the random number generator context is not active, then - initialise it. */ - if ( !context->active ) { - -/* First, perform local initialisation for this function, if not - already done. */ - LOCK_MUTEX4 - if ( !init ) { - -/* Obtain the approximate number of bits used by the random integer - generator from the value "m1". */ - (void) frexp( (double) m1, &lbits ); - -/* Obtain the approximate number of bits used by the mantissa of the - double value we want to produce, allowing for the (unlikely) - possibility that the mantissa's radix isn't 2. */ - dbits = (int) ceil( (double) DBL_MANT_DIG * - log( (double) FLT_RADIX ) / log( 2.0 ) ); - -/* Hence determine how many random integers we need to combine to - produce each double value, so that all the mantissa's bits will be - used. */ - nrand = ( dbits + lbits - 1 ) / lbits; - -/* Calculate the scale factor by which each successive random - integer's contribution to the result is reduced so as to generate - progressively less significant bits. */ - scale0 = 1.0 / (double) ( m1 - 1L ); - -/* Loop to sum the maximum contributions from each random integer - (assuming that each takes the largest possible value, of "m1-1", - from which we will later subtract 1). This produces the normalisation - factor by which the result must be scaled so as to lie between 0.0 and - 1.0 (inclusive). */ - sum = 0.0; - scale = 1.0; - for ( irand = 0; irand < nrand; irand++ ) { - scale *= scale0; - sum += scale; - } - norm = 1.0 / ( sum * (double) ( m1 - 2L ) ); - -/* Note that local initialisation has been done. */ - init = 1; - } - UNLOCK_MUTEX4 - -/* Obtain the seed value, enforcing positivity. */ - seed = (long int) context->seed; - if ( seed < 1 ) seed = seed + LONG_MAX; - if ( seed < 1 ) seed = LONG_MAX; - -/* Initialise the random number generators with this seed. */ - context->rand1 = context->rand2 = seed; - -/* Now loop to initialise the shuffle table with an initial set of - random values. We generate more values than required in order to "warm - up" the generator before recording values in the table. */ - for ( itab = ntab + nwarm - 1; itab >= 0; itab-- ) { - -/* Repeatedly update "rand1" from the expression "(rand1*a1)%m1" while - avoiding overflow. */ - tmp = context->rand1 / q1; - context->rand1 = a1 * ( context->rand1 - tmp * q1 ) - tmp * r1; - if ( context->rand1 < 0L ) context->rand1 += m1; - -/* After warming up, start recording values in the table. */ - if ( itab < ntab ) context->table[ itab ] = context->rand1; - } - -/* Record the last entry in the table as the "previous" random - integer. */ - context->random_int = context->table[ 0 ]; - -/* Note the random number generator context is active. */ - context->active = 1; - } - -/* Generate a random value. */ -/* ------------------------ */ -/* Initialise. */ - result = 0.0; - -/* Loop to generate sufficient random integers to combine into a - double value. */ - scale = norm; - for ( irand = 0; irand < nrand; irand++ ) { - -/* Update the first generator "rand1" from the expression - "(a1*rand1)%m1" while avoiding overflow. */ - tmp = context->rand1 / q1; - context->rand1 = a1 * ( context->rand1 - tmp * q1 ) - tmp * r1; - if ( context->rand1 < 0L ) context->rand1 += m1; - -/* Similarly, update the second generator "rand2" from the expression - "(a2*rand2)%m2". */ - tmp = context->rand2 / q2; - context->rand2 = a2 * ( context->rand2 - tmp * q2 ) - tmp * r2; - if ( context->rand2 < 0L ) context->rand2 += m2; - -/* Use the previous random integer to generate an index into the - shuffle table. */ - itab = (int) ( context->random_int / - ( 1L + ( m1 - 1L ) / (long int) ntab ) ); - -/* The algorithm left by RFWS seems to have a bug that "itab" can - sometimes be outside the range of [0.,ntab-1] causing the context->table - array to be addressed out of bounds. To avoid this, use the - following sticking plaster, since I'm not sure what the correct fix is. */ - if( itab < 0 ) itab = -itab; - itab = itab % ntab; - -/* Extract the table entry and replace it with a new random value from - the first generator "rand1". This is the Bays-Durham shuffle. */ - context->random_int = context->table[ itab ]; - context->table[ itab ] = context->rand1; - -/* Combine the extracted value with the latest value from the second - generator "rand2". */ - context->random_int -= context->rand2; - if ( context->random_int < 1L ) context->random_int += m1 - 1L; - -/* Update the scale factor to apply to the resulting random integer - and accumulate its contribution to the result. */ - scale *= scale0; - result += scale * (double) ( context->random_int - 1L ); - } - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a MathMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* MathMap member function (extends the astSetAttrib method inherited from -* the Mapping class). - -* Description: -* This function assigns an attribute value for a MathMap, the attribute -* and its value being specified by means of a string of the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in lower -* case with no white space present. The value to the right of the "=" -* should be a suitable textual representation of the value to be assigned -* and this will be interpreted according to the attribute's data type. -* White space surrounding the value is only significant for string -* attributes. - -* Parameters: -* this -* Pointer to the MathMap. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void -*/ - -/* Local Vaiables: */ - AstMathMap *this; /* Pointer to the MathMap structure */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the MathMap structure. */ - this = (AstMathMap *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* Seed. */ -/* ----- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "seed= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetSeed( this, ival ); - -/* SimpFI. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "simpfi= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetSimpFI( this, ival ); - -/* SimpIF. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "simpif= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetSimpIF( this, ival ); - -/* Pass any unrecognised setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a MathMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* MathMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a MathMap's attributes. - -* Parameters: -* this -* Pointer to the MathMap. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMathMap *this; /* Pointer to the MathMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the MathMap structure. */ - this = (AstMathMap *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* Seed. */ -/* ----- */ - if ( !strcmp( attrib, "seed" ) ) { - result = astTestSeed( this ); - -/* SimpFI. */ -/* ------- */ - } else if ( !strcmp( attrib, "simpfi" ) ) { - result = astTestSimpFI( this ); - -/* SimpIF. */ -/* ------- */ - } else if ( !strcmp( attrib, "simpif" ) ) { - result = astTestSimpIF( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *map, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a MathMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* AstPointSet *Transform( AstMapping *map, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* MathMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a MathMap and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required coordinate -* transformation. - -* Parameters: -* map -* Pointer to the MathMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the MathMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstMathMap *this; /* Pointer to MathMap to be applied */ - AstPointSet *result; /* Pointer to output PointSet */ - double **data_ptr; /* Array of pointers to coordinate data */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *work; /* Workspace for intermediate results */ - int idata; /* Loop counter for data pointer elements */ - int ifun; /* Loop counter for functions */ - int ncoord_in; /* Number of coordinates per input point */ - int ncoord_out; /* Number of coordinates per output point */ - int ndata; /* Number of data pointer elements filled */ - int nfun; /* Number of functions to evaluate */ - int npoint; /* Number of points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - work = NULL; - -/* Obtain a pointer to the MathMap. */ - this = (AstMathMap *) map; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( map, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - transformation needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - and output PointSets and obtain pointers for accessing the input and output - coordinate values. */ - ncoord_in = astGetNcoord( in ); - ncoord_out = astGetNcoord( result ); - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse transformation, according - to the direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( this ) ) forward = !forward; - -/* Obtain the number of transformation functions that must be - evaluated to perform the transformation. This will include any that - produce intermediate results from which the final results are - calculated. */ - nfun = forward ? this->nfwd : this->ninv; - -/* If intermediate results are to be calculated, then allocate - workspace to hold them (each intermediate result being a vector of - "npoint" double values). */ - if ( nfun > ncoord_out ) { - work = astMalloc( sizeof( double) * - (size_t) ( npoint * ( nfun - ncoord_out ) ) ); - } - -/* Also allocate space for an array to hold pointers to the input - data, intermediate results and output data. */ - data_ptr = astMalloc( sizeof( double * ) * (size_t) ( ncoord_in + nfun ) ); - -/* We now set up the "data_ptr" array to locate the data to be - processed. */ - if ( astOK ) { - -/* The first elements of this array point at the input data - vectors. */ - ndata = 0; - for ( idata = 0; idata < ncoord_in; idata++ ) { - data_ptr[ ndata++ ] = ptr_in[ idata ]; - } - -/* The following elements point at successive vectors within the - workspace array (if allocated). These vectors will act first as output - arrays for intermediate results, and then as input arrays for - subsequent calculations which use these results. */ - for ( idata = 0; idata < ( nfun - ncoord_out ); idata++ ) { - data_ptr[ ndata++ ] = work + ( idata * npoint ); - } - -/* The final elements point at the output coordinate data arrays into - which the final results will be written. */ - for ( idata = 0; idata < ncoord_out; idata++ ) { - data_ptr[ ndata++ ] = ptr_out[ idata ]; - } - -/* Perform coordinate transformation. */ -/* ---------------------------------- */ -/* Loop to evaluate each transformation function in turn. */ - for ( ifun = 0; ifun < nfun; ifun++ ) { - -/* Invoke the function that evaluates compiled expressions. Pass the - appropriate code and constants arrays, depending on the direction of - coordinate transformation, together with the required stack size. The - output array is the vector located by successive elements of the - "data_ptr" array (skipping the input data elements), while the - function has access to all previous elements of the "data_ptr" array - to locate the required input data. */ - EvaluateFunction( &this->rcontext, npoint, (const double **) data_ptr, - forward ? this->fwdcode[ ifun ] : - this->invcode[ ifun ], - forward ? this->fwdcon[ ifun ] : - this->invcon[ ifun ], - forward ? this->fwdstack : this->invstack, - data_ptr[ ifun + ncoord_in ], status ); - } - } - -/* Free the array of data pointers and any workspace allocated for - intermediate results. */ - data_ptr = astFree( data_ptr ); - if ( nfun > ncoord_out ) work = astFree( work ); - -/* If an error occurred, then return a NULL pointer. If no output - PointSet was supplied, also delete any new one that may have been - created. */ - if ( !astOK ) { - result = ( result == out ) ? NULL : astDelete( result ); - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -static void ValidateSymbol( const char *method, const char *class, - const char *exprs, int iend, int sym, - int *lpar, int **argcount, int **opensym, - int *ncon, double **con, int *status ) { -/* -* Name: -* ValidateSymbol - -* Purpose: -* Validate a symbol in an expression. - -* Type: -* Private function. - -* Synopsis: -* #include "mathmap.h" -* void ValidateSymbol( const char *method, const char *class, -* const char *exprs, int iend, int sym, int *lpar, -* int **argcount, int **opensym, int *ncon, -* double **con, int *status ) - -* Class Membership: -* MathMap member function. - -* Description: -* This function validates an identified standard symbol during -* compilation of an expression. Its main task is to keep track of the -* level of parenthesis in the expression and to count the number of -* arguments supplied to functions at each level of parenthesis (for -* nested function calls). On this basis it is able to interpret and -* accept or reject symbols which represent function calls, parentheses -* and delimiters. Other symbols are accepted automatically. - -* Parameters: -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function. -* This method name is used solely for constructing error messages. -* class -* Pointer to a constant null-terminated character string containing the -* class name of the Object being processed. This name is used solely -* for constructing error messages. -* exprs -* Pointer to a null-terminated string containing the expression -* being parsed. This is only used for constructing error messages. -* iend -* Index in "exprs" of the last character belonging to the most -* recently identified symbol. This is only used for constructing error -* messages. -* sym -* Index in the static "symbol" array of the most recently identified -* symbol in the expression. This is the symbol to be verified. -* lpar -* Pointer to an int which holds the current level of parenthesis. On -* the first invocation, this should be zero. The returned value should -* be passed to subsequent invocations. -* argcount -* Address of a pointer to a dynamically allocated array of int in -* which argument count information is maintained for each level of -* parenthesis (e.g. for nested function calls). On the first invocation, -* "*argcount" should be NULL. This function will allocate the required -* space as needed and update this pointer. The returned pointer value -* should be passed to subsequent invocations. -* -* The allocated space must be freed by the caller (using astFree) when -* no longer required. -* opensym -* Address of a pointer to a dynamically allocated array of int, in which -* information is maintained about the functions associated with each -* level of parenthesis (e.g. for nested function calls). On the first -* invocation, "*opensym" should be NULL. This function will allocate the -* required space as needed and update this pointer. The returned pointer -* value should be passed to subsequent invocations. -* -* The allocated space must be freed by the caller (using astFree) when -* no longer required. -* ncon -* Pointer to an int which holds a count of the constants associated -* with the expression (and determines the size of the "*con" array). -* This function will update the count to reflect any new constants -* appended to the "*con" array and the returned value should be passed -* to subsequent invocations. -* con -* Address of a pointer to a dynamically allocated array of double, in -* which the constants associated with the expression being parsed are -* accumulated. On entry, "*con" should point at a dynamic array with -* at least "*ncon" elements containing existing constants (or may be -* NULL if no constants have yet been stored). This function will -* allocate the required space as needed and update this pointer (and -* "*ncon") appropriately. The returned pointer value should be passed -* to subsequent invocations. -* -* The allocated space must be freed by the caller (using astFree) when -* no longer required. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The dynamically allocated arrays normally returned by this function -* will be freed and NULL pointers will be returned if this function is -* invoked with the global error status set, or if it should fail for any -* reason. -*/ - -/* Check the global error status, but do not return at this point - because dynamic arrays may require freeing. */ - if ( astOK ) { - -/* Check if the symbol is a comma. */ - if ( ( symbol[ sym ].text[ 0 ] == ',' ) && - ( symbol[ sym ].text[ 1 ] == '\0' ) ) { - -/* A comma is only used to delimit function arguments. If the current - level of parenthesis is zero, or the symbol which opened the current - level of parenthesis was not a function call (indicated by an argument - count of zero at the current level of parenthesis), then report an - error. */ - if ( ( *lpar <= 0 ) || ( ( *argcount )[ *lpar - 1 ] == 0 ) ) { - astError( AST__COMIN, - "%s(%s): Spurious comma encountered in the expression " - "\"%.*s\".", status, - method, class, iend + 1, exprs ); - -/* If a comma is valid, then increment the argument count at the - current level of parenthesis. */ - } else { - ( *argcount )[ *lpar - 1 ]++; - } - -/* If the symbol is not a comma, check if it increases the current - level of parenthesis. */ - } else if ( symbol[ sym ].parincrement > 0 ) { - -/* Increase the size of the arrays which hold parenthesis level - information and check for errors. */ - *argcount = astGrow( *argcount, *lpar + 1, sizeof( int ) ); - *opensym = astGrow( *opensym, *lpar + 1, sizeof( int ) ); - if ( astOK ) { - -/* Increment the level of parenthesis and initialise the argument - count at the new level. This count is set to zero if the symbol which - opens the parenthesis level is not a function call (indicated by a - zero "nargs" entry in the symbol data), and it subsequently remains at - zero. If the symbol is a function call, the argument count is - initially set to 1 and increments whenever a comma is encountered at - this parenthesis level. */ - ( *argcount )[ ++( *lpar ) - 1 ] = ( symbol[ sym ].nargs != 0 ); - -/* Remember the symbol which opened this parenthesis level. */ - ( *opensym )[ *lpar - 1 ] = sym; - } - -/* Check if the symbol decreases the current parenthesis level. */ - } else if ( symbol[ sym ].parincrement < 0 ) { - -/* Ensure that the parenthesis level is not already at zero. If it is, - then there is a missing left parenthesis in the expression being - compiled, so report an error. */ - if ( *lpar == 0 ) { - astError( AST__MLPAR, - "%s(%s): Missing left parenthesis in the expression " - "\"%.*s\".", status, - method, class, iend + 1, exprs ); - -/* If the parenthesis level is valid and the symbol which opened this - level of parenthesis was a function call with a fixed number of - arguments (indicated by a positive "nargs" entry in the symbol data), - then we must check the number of function arguments which have been - encountered. */ - } else if ( symbol[ ( *opensym )[ *lpar - 1 ] ].nargs > 0 ) { - -/* Report an error if the number of arguments is wrong. */ - if ( ( *argcount )[ *lpar - 1 ] != - symbol[ ( *opensym )[ *lpar - 1 ] ].nargs ) { - astError( AST__WRNFA, - "%s(%s): Wrong number of function arguments in the " - "expression \"%.*s\".", status, - method, class, iend + 1, exprs ); - -/* If the number of arguments is valid, decrement the parenthesis - level. */ - } else { - ( *lpar )--; - } - -/* If the symbol which opened this level of parenthesis was a function - call with a variable number of arguments (indicated by a negative - "nargs" entry in the symbol data), then we must check and process the - number of function arguments. */ - } else if ( symbol[ ( *opensym )[ *lpar - 1 ] ].nargs < 0 ) { - -/* Check that the minimum required number of arguments have been - supplied. Report an error if they have not. */ - if ( ( *argcount )[ *lpar - 1 ] < - ( -symbol[ ( *opensym )[ *lpar - 1 ] ].nargs ) ) { - astError( AST__WRNFA, - "%s(%s): Insufficient function arguments in the " - "expression \"%.*s\".", status, - method, class, iend + 1, exprs ); - -/* If the number of arguments is valid, increase the size of the - constants array and check for errors. */ - } else { - *con = astGrow( *con, *ncon + 1, sizeof( double ) ); - if ( astOK ) { - -/* Append the argument count to the end of the array of constants and - decrement the parenthesis level. */ - ( *con )[ ( *ncon )++ ] = - (double) ( *argcount )[ --( *lpar ) ]; - } - } - -/* Finally, if the symbol which opened this level of parenthesis was - not a function call ("nargs" entry in the symbol data is zero), then - decrement the parenthesis level. In this case there is no need to - check the argument count, because it will not have been - incremented. */ - } else { - ( *lpar )--; - } - } - } - -/* If an error occurred (or the global error status was set on entry), - then reset the parenthesis level and free any memory which may have - been allocated. */ - if ( !astOK ) { - *lpar = 0; - if ( *argcount ) *argcount = astFree( *argcount ); - if ( *opensym ) *opensym = astFree( *opensym ); - if ( *con ) *con = astFree( *con ); - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* Seed - -* Purpose: -* Random number seed for a MathMap. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute, which may take any integer value, determines the -* sequence of random numbers produced by the random number functions in -* MathMap expressions. It is set to an unpredictable default value when -* a MathMap is created, so that by default each MathMap uses a different -* set of random numbers. -* -* If required, you may set this Seed attribute to a value of your -* choosing in order to produce repeatable behaviour from the random -* number functions. You may also enquire the Seed value (e.g. if an -* initially unpredictable value has been used) and then use it to -* reproduce the resulting sequence of random numbers, either from the -* same MathMap or from another one. -* -* Clearing the Seed attribute gives it a new unpredictable default -* value. - -* Applicability: -* MathMap -* All MathMaps have this attribute. -*att-- -*/ -/* Clear the Seed value by setting it to a new unpredictable value - produced by DefaultSeed and clearing the "seed_set" flag in the - MathMap's random number generator context. Also clear the "active" - flag, so that the generator will be re-initialised to use this seed - when it is next invoked. */ -astMAKE_CLEAR(MathMap,Seed,rcontext.seed,( this->rcontext.seed_set = 0, - this->rcontext.active = 0, - DefaultSeed( &this->rcontext, status ) )) - -/* Return the "seed" value from the random number generator - context. */ -astMAKE_GET(MathMap,Seed,int,0,this->rcontext.seed) - -/* Store the new seed value in the MathMap's random number generator - context and set the context's "seed_set" flag. Also clear the "active" - flag, so that the generator will be re-initialised to use this seed - when it is next invoked. */ -astMAKE_SET(MathMap,Seed,int,rcontext.seed,( this->rcontext.seed_set = 1, - this->rcontext.active = 0, - value )) - -/* Test the "seed_set" flag in the random number generator context. */ -astMAKE_TEST(MathMap,Seed,( this->rcontext.seed_set )) - -/* -*att++ -* Name: -* SimpFI - -* Purpose: -* Forward-inverse MathMap pairs simplify? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -c This attribute should be set to a non-zero value if applying a -c MathMap's forward transformation, followed immediately by the matching -c inverse transformation will always restore the original set of -c coordinates. It indicates that AST may replace such a sequence of -c operations by an identity Mapping (a UnitMap) if it is encountered -c while simplifying a compound Mapping (e.g. using astSimplify). -f This attribute should be set to a non-zero value if applying a -f MathMap's forward transformation, followed immediately by the matching -f inverse transformation will always restore the original set of -f coordinates. It indicates that AST may replace such a sequence of -f operations by an identity Mapping (a UnitMap) if it is encountered -f while simplifying a compound Mapping (e.g. using AST_SIMPLIFY). -* -* By default, the SimpFI attribute is zero, so that AST will not perform -* this simplification unless you have set SimpFI to indicate that it is -* safe to do so. - -* Applicability: -* MathMap -* All MathMaps have this attribute. - -* Notes: -* - For simplification to occur, the two MathMaps must be in series and -* be identical (with textually identical transformation -* functions). Functional equivalence is not sufficient. -* - The consent of both MathMaps is required before simplification can -* take place. If either has a SimpFI value of zero, then simplification -* will not occur. -* - The SimpFI attribute controls simplification only in the case where -* a MathMap's forward transformation is followed by the matching inverse -* transformation. It does not apply if an inverse transformation is -* followed by a forward transformation. This latter case is controlled -* by the SimpIF attribute. -c - The "forward" and "inverse" transformations referred to are those -c defined when the MathMap is created (corresponding to the "fwd" and -c "inv" parameters of its constructor function). If the MathMap is -c inverted (i.e. its Invert attribute is non-zero), then the role of the -c SimpFI and SimpIF attributes will be interchanged. -f - The "forward" and "inverse" transformations referred to are those -f defined when the MathMap is created (corresponding to the FWD and -f INV arguments of its constructor function). If the MathMap is -f inverted (i.e. its Invert attribute is non-zero), then the role of the -f SimpFI and SimpIF attributes will be interchanged. -*att-- -*/ -/* Clear the SimpFI value by setting it to -INT_MAX. */ -astMAKE_CLEAR(MathMap,SimpFI,simp_fi,-INT_MAX) - -/* Supply a default of 0 if no SimpFI value has been set. */ -astMAKE_GET(MathMap,SimpFI,int,0,( ( this->simp_fi != -INT_MAX ) ? - this->simp_fi : 0 )) - -/* Set a SimpFI value of 1 if any non-zero value is supplied. */ -astMAKE_SET(MathMap,SimpFI,int,simp_fi,( value != 0 )) - -/* The SimpFI value is set if it is not -INT_MAX. */ -astMAKE_TEST(MathMap,SimpFI,( this->simp_fi != -INT_MAX )) - -/* -*att++ -* Name: -* SimpIF - -* Purpose: -* Inverse-forward MathMap pairs simplify? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -c This attribute should be set to a non-zero value if applying a -c MathMap's inverse transformation, followed immediately by the matching -c forward transformation will always restore the original set of -c coordinates. It indicates that AST may replace such a sequence of -c operations by an identity Mapping (a UnitMap) if it is encountered -c while simplifying a compound Mapping (e.g. using astSimplify). -f This attribute should be set to a non-zero value if applying a -f MathMap's inverse transformation, followed immediately by the matching -f forward transformation will always restore the original set of -f coordinates. It indicates that AST may replace such a sequence of -f operations by an identity Mapping (a UnitMap) if it is encountered -f while simplifying a compound Mapping (e.g. using AST_SIMPLIFY). -* -* By default, the SimpIF attribute is zero, so that AST will not perform -* this simplification unless you have set SimpIF to indicate that it is -* safe to do so. - -* Applicability: -* MathMap -* All MathMaps have this attribute. - -* Notes: -* - For simplification to occur, the two MathMaps must be in series and -* be identical (with textually identical transformation -* functions). Functional equivalence is not sufficient. -* - The consent of both MathMaps is required before simplification can -* take place. If either has a SimpIF value of zero, then simplification -* will not occur. -* - The SimpIF attribute controls simplification only in the case where -* a MathMap's inverse transformation is followed by the matching forward -* transformation. It does not apply if a forward transformation is -* followed by an inverse transformation. This latter case is controlled -* by the SimpFI attribute. -c - The "forward" and "inverse" transformations referred to are those -c defined when the MathMap is created (corresponding to the "fwd" and -c "inv" parameters of its constructor function). If the MathMap is -c inverted (i.e. its Invert attribute is non-zero), then the role of the -c SimpFI and SimpIF attributes will be interchanged. -f - The "forward" and "inverse" transformations referred to are those -f defined when the MathMap is created (corresponding to the FWD and -f INV arguments of its constructor function). If the MathMap is -f inverted (i.e. its Invert attribute is non-zero), then the role of the -f SimpFI and SimpIF attributes will be interchanged. -*att-- -*/ -/* Clear the SimpIF value by setting it to -INT_MAX. */ -astMAKE_CLEAR(MathMap,SimpIF,simp_if,-INT_MAX) - -/* Supply a default of 0 if no SimpIF value has been set. */ -astMAKE_GET(MathMap,SimpIF,int,0,( ( this->simp_if != -INT_MAX ) ? - this->simp_if : 0 )) - -/* Set a SimpIF value of 1 if any non-zero value is supplied. */ -astMAKE_SET(MathMap,SimpIF,int,simp_if,( value != 0 )) - -/* The SimpIF value is set if it is not -INT_MAX. */ -astMAKE_TEST(MathMap,SimpIF,( this->simp_if != -INT_MAX )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for MathMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for MathMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstMathMap *in; /* Pointer to input MathMap */ - AstMathMap *out; /* Pointer to output MathMap */ - int ifun; /* Loop counter for functions */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output MathMaps. */ - in = (AstMathMap *) objin; - out = (AstMathMap *) objout; - -/* For safety, first clear any references to the input memory from - the output MathMap. */ - out->fwdfun = NULL; - out->invfun = NULL; - out->fwdcode = NULL; - out->invcode = NULL; - out->fwdcon = NULL; - out->invcon = NULL; - -/* Now allocate and initialise each of the output pointer arrays - required. */ - if ( in->fwdfun ) { - MALLOC_POINTER_ARRAY( out->fwdfun, char *, out->nfwd ) - } - if ( in->invfun ) { - MALLOC_POINTER_ARRAY( out->invfun, char *, out->ninv ) - } - if ( in->fwdcode ) { - MALLOC_POINTER_ARRAY( out->fwdcode, int *, out->nfwd ) - } - if ( in->invcode ) { - MALLOC_POINTER_ARRAY( out->invcode, int *, out->ninv ) - } - if ( in->fwdcon ) { - MALLOC_POINTER_ARRAY( out->fwdcon, double *, out->nfwd ) - } - if ( in->invcon ) { - MALLOC_POINTER_ARRAY( out->invcon, double *, out->ninv ) - } - -/* If OK, loop to make copies of the data (where available) associated - with each forward transformation function, storing pointers to the - copy in the output pointer arrays allocated above. */ - if ( astOK ) { - for ( ifun = 0; ifun < out->nfwd; ifun++ ) { - if ( in->fwdfun && in->fwdfun[ ifun ] ) { - out->fwdfun[ ifun ] = astStore( NULL, in->fwdfun[ ifun ], - astSizeOf( in->fwdfun[ ifun ] ) ); - } - if ( in->fwdcode && in->fwdcode[ ifun ] ) { - out->fwdcode[ ifun ] = astStore( NULL, in->fwdcode[ ifun ], - astSizeOf( in->fwdcode[ ifun ] ) ); - } - if ( in->fwdcon && in->fwdcon[ ifun ] ) { - out->fwdcon[ ifun ] = astStore( NULL, in->fwdcon[ ifun ], - astSizeOf( in->fwdcon[ ifun ] ) ); - } - if ( !astOK ) break; - } - } - -/* Repeat this process for the inverse transformation functions. */ - if ( astOK ) { - for ( ifun = 0; ifun < out->ninv; ifun++ ) { - if ( in->invfun && in->invfun[ ifun ] ) { - out->invfun[ ifun ] = astStore( NULL, in->invfun[ ifun ], - astSizeOf( in->invfun[ ifun ] ) ); - } - if ( in->invcode && in->invcode[ ifun ] ) { - out->invcode[ ifun ] = astStore( NULL, in->invcode[ ifun ], - astSizeOf( in->invcode[ ifun ] ) ); - } - if ( in->invcon && in->invcon[ ifun ] ) { - out->invcon[ ifun ] = astStore( NULL, in->invcon[ ifun ], - astSizeOf( in->invcon[ ifun ] ) ); - } - if ( !astOK ) break; - } - } - -/* If an error occurred, clean up by freeing all output memory - allocated above. */ - if ( !astOK ) { - FREE_POINTER_ARRAY( out->fwdfun, out->nfwd ) - FREE_POINTER_ARRAY( out->invfun, out->ninv ) - FREE_POINTER_ARRAY( out->fwdcode, out->nfwd ) - FREE_POINTER_ARRAY( out->invcode, out->ninv ) - FREE_POINTER_ARRAY( out->fwdcon, out->nfwd ) - FREE_POINTER_ARRAY( out->invcon, out->ninv ) - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for MathMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for MathMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstMathMap *this; /* Pointer to MathMap */ - -/* Obtain a pointer to the MathMap structure. */ - this = (AstMathMap *) obj; - -/* Free all memory allocated by the MathMap. */ - FREE_POINTER_ARRAY( this->fwdfun, this->nfwd ) - FREE_POINTER_ARRAY( this->invfun, this->ninv ) - FREE_POINTER_ARRAY( this->fwdcode, this->nfwd ) - FREE_POINTER_ARRAY( this->invcode, this->ninv ) - FREE_POINTER_ARRAY( this->fwdcon, this->nfwd ) - FREE_POINTER_ARRAY( this->invcon, this->ninv ) -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for MathMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the MathMap class to an output Channel. - -* Parameters: -* this -* Pointer to the MathMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define COMMENT_LEN 150 /* Maximum length of a comment string */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstMathMap *this; /* Pointer to the MathMap structure */ - char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment strings */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword strings */ - int ifun; /* Loop counter for functions */ - int invert; /* MathMap inverted? */ - int ival; /* Integer attribute value */ - int nin; /* True number of input coordinates */ - int nout; /* True number of output coordinates */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the MathMap structure. */ - this = (AstMathMap *) this_object; - -/* Determine if the MathMap is inverted and obtain the "true" number - of input and output coordinates by un-doing the effects of any - inversion. */ - invert = astGetInvert( this ); - nin = !invert ? astGetNin( this ) : astGetNout( this ); - nout = !invert ? astGetNout( this ) : astGetNin( this ); - -/* Write out values representing the instance variables for the - MathMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Number of forward transformation functions. */ -/* ------------------------------------------- */ -/* We regard this value as set if it differs from the number of output - coordinates for the MathMap. */ - set = ( this->nfwd != nout ); - astWriteInt( channel, "Nfwd", set, 0, this->nfwd, - "Number of forward transformation functions" ); - -/* Forward transformation functions. */ -/* --------------------------------- */ -/* Loop to write out each forward transformation function, generating - a suitable keyword and comment for each one. */ - for ( ifun = 0; ifun < this->nfwd; ifun++ ) { - (void) sprintf( key, "Fwd%d", ifun + 1 ); - (void) sprintf( comment, "Forward function %d", ifun + 1 ); - astWriteString( channel, key, 1, 1, this->fwdfun[ ifun ], comment ); - } - -/* Number of inverse transformation functions. */ -/* ------------------------------------------- */ -/* We regard this value as set if it differs from the number of input - coordinates for the MathMap. */ - set = ( this->ninv != nin ); - astWriteInt( channel, "Ninv", set, 0, this->ninv, - "Number of inverse transformation functions" ); - -/* Inverse transformation functions. */ -/* --------------------------------- */ -/* Similarly, loop to write out each inverse transformation - function. */ - for ( ifun = 0; ifun < this->ninv; ifun++ ) { - (void) sprintf( key, "Inv%d", ifun + 1 ); - (void) sprintf( comment, "Inverse function %d", ifun + 1 ); - astWriteString( channel, key, 1, 1, this->invfun[ ifun ], comment ); - } - -/* SimpFI. */ -/* ------- */ -/* Write out the forward-inverse simplification flag. */ - set = TestSimpFI( this, status ); - ival = set ? GetSimpFI( this, status ) : astGetSimpFI( this ); - astWriteInt( channel, "SimpFI", set, 0, ival, - ival ? "Forward-inverse pairs may simplify" : - "Forward-inverse pairs do not simplify" ); - -/* SimpIF. */ -/* ------- */ -/* Write out the inverse-forward simplification flag. */ - set = TestSimpIF( this, status ); - ival = set ? GetSimpIF( this, status ) : astGetSimpIF( this ); - astWriteInt( channel, "SimpIF", set, 0, ival, - ival ? "Inverse-forward pairs may simplify" : - "Inverse-forward pairs do not simplify" ); - -/* Seed. */ -/* ----- */ -/* Write out any random number seed value which is set. Prefix this with - a separate flag which indicates if the seed has been set. */ - set = TestSeed( this, status ); - ival = set ? GetSeed( this, status ) : astGetSeed( this ); - astWriteInt( channel, "Seeded", set, 0, set, - set? "Explicit random number seed set" : - "No random number seed set" ); - astWriteInt( channel, "Seed", set, 0, ival, - set ? "Random number seed value" : - "Default random number seed used" ); - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAMathMap and astCheckMathMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(MathMap,Mapping) -astMAKE_CHECK(MathMap) - -AstMathMap *astMathMap_( int nin, int nout, - int nfwd, const char *fwd[], - int ninv, const char *inv[], - const char *options, int *status, ...) { -/* -*+ -* Name: -* astMathMap - -* Purpose: -* Create a MathMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "mathmap.h" -* AstMathMap *astMathMap( int nin, int nout, -* int nfwd, const char *fwd[], -* int ninv, const char *inv[], -* const char *options, ..., int *status ) - -* Class Membership: -* MathMap constructor. - -* Description: -* This function creates a new MathMap and optionally initialises its -* attributes. - -* Parameters: -* nin -* Number of input variables for the MathMap. -* nout -* Number of output variables for the MathMap. -* nfwd -* The number of forward transformation functions being supplied. -* This must be at least equal to "nout". -* fwd -* Pointer to an array, with "nfwd" elements, of pointers to null -* terminated strings which contain each of the forward transformation -* functions. -* ninv -* The number of inverse transformation functions being supplied. -* This must be at least equal to "nin". -* inv -* Pointer to an array, with "ninv" elements, of pointers to null -* terminated strings which contain each of the inverse transformation -* functions. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new MathMap. The syntax used is the same as -* for the astSet method and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of arguments may follow it in order to -* supply values to be substituted for these specifiers. The -* rules for supplying these are identical to those for the -* astSet method (and for the C "printf" function). - -* Returned Value: -* A pointer to the new MathMap. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic MathMap constructor which is -* available via the protected interface to the MathMap class. A -* public interface is provided by the astMathMapId_ function. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMathMap *new; /* Pointer to new MathMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the MathMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitMathMap( NULL, sizeof( AstMathMap ), !class_init, &class_vtab, - "MathMap", nin, nout, nfwd, fwd, ninv, inv ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new MathMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new MathMap. */ - return new; -} - -AstMathMap *astMathMapId_( int nin, int nout, - int nfwd, const char *fwd[], - int ninv, const char *inv[], - const char *options, ... ) { -/* -*++ -* Name: -c astMathMap -f AST_MATHMAP - -* Purpose: -* Create a MathMap. - -* Type: -* Public function. - -* Synopsis: -c #include "mathmap.h" -c AstMathMap *astMathMap( int nin, int nout, -c int nfwd, const char *fwd[], -c int ninv, const char *inv[], -c const char *options, ... ) -f RESULT = AST_MATHMAP( NIN, NOUT, NFWD, FWD, NINV, INV, OPTIONS, STATUS ) - -* Class Membership: -* MathMap constructor. - -* Description: -* This function creates a new MathMap and optionally initialises its -* attributes. -* -c A MathMap is a Mapping which allows you to specify a set of forward -c and/or inverse transformation functions using arithmetic operations -c and mathematical functions similar to those available in C. The -c MathMap interprets these functions at run-time, whenever its forward -c or inverse transformation is required. Because the functions are not -c compiled in the normal sense (unlike an IntraMap), they may be used to -c describe coordinate transformations in a transportable manner. A -c MathMap therefore provides a flexible way of defining new types of -c Mapping whose descriptions may be stored as part of a dataset and -c interpreted by other programs. -f A MathMap is a Mapping which allows you to specify a set of forward -f and/or inverse transformation functions using arithmetic operations -f and mathematical functions similar to those available in Fortran. The -f MathMap interprets these functions at run-time, whenever its forward -f or inverse transformation is required. Because the functions are not -f compiled in the normal sense (unlike an IntraMap), they may be used to -f describe coordinate transformations in a transportable manner. A -f MathMap therefore provides a flexible way of defining new types of -f Mapping whose descriptions may be stored as part of a dataset and -f interpreted by other programs. - -* Parameters: -c nin -f NIN = INTEGER -* Number of input variables for the MathMap. This determines the -* value of its Nin attribute. -c nout -f NOUT = INTEGER -* Number of output variables for the MathMap. This determines the -* value of its Nout attribute. -c nfwd -f NFWD = INTEGER -* The number of forward transformation functions being supplied. -c This must be at least equal to "nout", but may be increased to -f This must be at least equal to NOUT, but may be increased to -* accommodate any additional expressions which define intermediate -* variables for the forward transformation (see the "Calculating -* Intermediate Values" section below). -c fwd -f FWD = CHARACTER * ( * )( NFWD ) -c An array (with "nfwd" elements) of pointers to null terminated strings -c which contain the expressions defining the forward transformation. -f An array which contains the expressions defining the forward -f transformation. -* The syntax of these expressions is described below. -c ninv -f NINV = INTEGER -* The number of inverse transformation functions being supplied. -c This must be at least equal to "nin", but may be increased to -f This must be at least equal to NIN, but may be increased to -* accommodate any additional expressions which define intermediate -* variables for the inverse transformation (see the "Calculating -* Intermediate Values" section below). -c inv -f INV = CHARACTER * ( * )( NINV ) -c An array (with "ninv" elements) of pointers to null terminated strings -c which contain the expressions defining the inverse transformation. -f An array which contains the expressions defining the inverse -f transformation. -* The syntax of these expressions is described below. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new MathMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new MathMap. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMathMap() -f AST_MATHMAP = INTEGER -* A pointer to the new MathMap. - -* Defining Transformation Functions: -c A MathMap's transformation functions are supplied as a set of -c expressions in an array of character strings. Normally you would -c supply the same number of expressions for the forward transformation, -c via the "fwd" parameter, as there are output variables (given by the -c MathMap's Nout attribute). For instance, if Nout is 2 you might use: -c - "r = sqrt( x * x + y * y )" -c - "theta = atan2( y, x )" -c -c which defines a transformation from Cartesian to polar -c coordinates. Here, the variables that appear on the left of each -c expression ("r" and "theta") provide names for the output variables -c and those that appear on the right ("x" and "y") are references to -c input variables. -f A MathMap's transformation functions are supplied as a set of -f expressions in an array of character strings. Normally you would -f supply the same number of expressions for the forward transformation, -f via the FWD argument, as there are output variables (given by the -f MathMap's Nout attribute). For instance, if Nout is 2 you might use: -f - 'R = SQRT( X * X + Y * Y )' -f - 'THETA = ATAN2( Y, X )' -f -f which defines a transformation from Cartesian to polar -f coordinates. Here, the variables that appear on the left of each -f expression (R and THETA) provide names for the output variables and -f those that appear on the right (X and Y) are references to input -f variables. -* -c To complement this, you must also supply expressions for the inverse -c transformation via the "inv" parameter. In this case, the number of -c expressions given would normally match the number of MathMap input -c coordinates (given by the Nin attribute). If Nin is 2, you might use: -c - "x = r * cos( theta )" -c - "y = r * sin( theta )" -c -c which expresses the transformation from polar to Cartesian -c coordinates. Note that here the input variables ("x" and "y") are -c named on the left of each expression, and the output variables ("r" -c and "theta") are referenced on the right. -f To complement this, you must also supply expressions for the inverse -f transformation via the INV argument. In this case, the number of -f expressions given would normally match the number of MathMap input -f coordinates (given by the Nin attribute). If Nin is 2, you might use: -f - 'X = R * COS( THETA )' -f - 'Y = R * SIN( THETA )' -f -f which expresses the transformation from polar to Cartesian -f coordinates. Note that here the input variables (X and Y) are named on -f the left of each expression, and the output variables (R and THETA) -f are referenced on the right. -* -* Normally, you cannot refer to a variable on the right of an expression -* unless it is named on the left of an expression in the complementary -* set of functions. Therefore both sets of functions (forward and -* inverse) must be formulated using the same consistent set of variable -* names. This means that if you wish to leave one of the transformations -* undefined, you must supply dummy expressions which simply name each of -* the output (or input) variables. For example, you might use: -c - "x" -c - "y" -f - 'X' -f - 'Y' -* -* for the inverse transformation above, which serves to name the input -* variables but without defining an inverse transformation. - -* Calculating Intermediate Values: -c It is sometimes useful to calculate intermediate values and then to -c use these in the final expressions for the output (or input) -c variables. This may be done by supplying additional expressions for -c the forward (or inverse) transformation functions. For instance, the -c following array of five expressions describes 2-dimensional pin-cushion -c distortion: -c - "r = sqrt( xin * xin + yin * yin )" -c - "rout = r * ( 1 + 0.1 * r * r )" -c - "theta = atan2( yin, xin )" -c - "xout = rout * cos( theta )" -c - "yout = rout * sin( theta )" -f It is sometimes useful to calculate intermediate values and then to -f use these in the final expressions for the output (or input) -f variables. This may be done by supplying additional expressions for -f the forward (or inverse) transformation functions. For instance, the -f following array of five expressions describes 2-dimensional pin-cushion -f distortion: -f - 'R = SQRT( XIN * XIN + YIN * YIN )' -f - 'ROUT = R * ( 1 + 0.1 * R * R )' -f - 'THETA = ATAN2( YIN, XIN )', -f - 'XOUT = ROUT * COS( THETA )' -f - 'YOUT = ROUT * SIN( THETA )' -* -c Here, we first calculate three intermediate results ("r", "rout" -c and "theta") and then use these to calculate the final results ("xout" -c and "yout"). The MathMap knows that only the final two results -c constitute values for the output variables because its Nout attribute -c is set to 2. You may define as many intermediate variables in this -c way as you choose. Having defined a variable, you may then refer to it -c on the right of any subsequent expressions. -f Here, we first calculate three intermediate results (R, ROUT -f and THETA) and then use these to calculate the final results (XOUT -f and YOUT). The MathMap knows that only the final two results -f constitute values for the output variables because its Nout attribute -f is set to 2. You may define as many intermediate variables in this -f way as you choose. Having defined a variable, you may then refer to it -f on the right of any subsequent expressions. -* -c Note that when defining the inverse transformation you may only refer -c to the output variables "xout" and "yout". The intermediate variables -c "r", "rout" and "theta" (above) are private to the forward -c transformation and may not be referenced by the inverse -c transformation. The inverse transformation may, however, define its -c own private intermediate variables. -f Note that when defining the inverse transformation you may only refer -f to the output variables XOUT and YOUT. The intermediate variables R, -f ROUT and THETA (above) are private to the forward transformation and -f may not be referenced by the inverse transformation. The inverse -f transformation may, however, define its own private intermediate -f variables. - -* Expression Syntax: -c The expressions given for the forward and inverse transformations -c closely follow the syntax of the C programming language (with some -c extensions for compatibility with Fortran). They may contain -c references to variables and literal constants, together with -c arithmetic, boolean, relational and bitwise operators, and function -c invocations. A set of symbolic constants is also available. Each of -c these is described in detail below. Parentheses may be used to -c over-ride the normal order of evaluation. There is no built-in limit -c to the length of expressions and they are insensitive to case or the -c presence of additional white space. -f The expressions given for the forward and inverse transformations -f closely follow the syntax of Fortran (with some extensions for -f compatibility with the C language). They may contain references to -f variables and literal constants, together with arithmetic, logical, -f relational and bitwise operators, and function invocations. A set of -f symbolic constants is also available. Each of these is described in -f detail below. Parentheses may be used to over-ride the normal order of -f evaluation. There is no built-in limit to the length of expressions -f and they are insensitive to case or the presence of additional white -f space. - -* Variables: -* Variable names must begin with an alphabetic character and may contain -* only alphabetic characters, digits, and the underscore character -* "_". There is no built-in limit to the length of variable names. - -* Literal Constants: -c Literal constants, such as "0", "1", "0.007" or "2.505e-16" may appear -c in expressions, with the decimal point and exponent being optional (a -c "D" may also be used as an exponent character for compatibility with -c Fortran). A unary minus "-" may be used as a prefix. -f Literal constants, such as "0", "1", "0.007" or "2.505E-16" may appear -f in expressions, with the decimal point and exponent being optional (a -f "D" may also be used as an exponent character). A unary minus "-" may -f be used as a prefix. - -* Arithmetic Precision: -* All arithmetic is floating point, performed in double precision. - -* Propagation of Missing Data: -* Unless indicated otherwise, if any argument of a function or operator -* has the value AST__BAD (indicating missing data), then the result of -* that function or operation is also AST__BAD, so that such values are -* propagated automatically through all operations performed by MathMap -* transformations. The special value AST__BAD can be represented in -* expressions by the symbolic constant "". -* -* A result (i.e. equal to AST__BAD) is also produced in response -* to any numerical error (such as division by zero or numerical -* overflow), or if an invalid argument value is provided to a function -* or operator. - -* Arithmetic Operators: -* The following arithmetic operators are available: -c - x1 + x2: Sum of "x1" and "x2". -f - X1 + X2: Sum of X1 and X2. -c - x1 - x2: Difference of "x1" and "x2". -f - X1 - X2: Difference of X1 and X2. -c - x1 * x2: Product of "x1" and "x1". -f - X1 * X2: Product of X1 and X2. -c - x1 / x2: Ratio of "x1" and "x2". -f - X1 / X2: Ratio of X1 and X2. -c - x1 ** x2: "x1" raised to the power of "x2". -f - X1 ** X2: X1 raised to the power of X2. -c - + x: Unary plus, has no effect on its argument. -f - + X: Unary plus, has no effect on its argument. -c - - x: Unary minus, negates its argument. -f - - X: Unary minus, negates its argument. - -c Boolean Operators: -f Logical Operators: -c Boolean values are represented using zero to indicate false and -c non-zero to indicate true. In addition, the value AST__BAD is taken to -c mean "unknown". The values returned by boolean operators may therefore -c be 0, 1 or AST__BAD. Where appropriate, "tri-state" logic is -c implemented. For example, "a||b" may evaluate to 1 if "a" is non-zero, -c even if "b" has the value AST__BAD. This is because the result of the -c operation would not be affected by the value of "b", so long as "a" is -c non-zero. -f Logical values are represented using zero to indicate .FALSE. and -f non-zero to indicate .TRUE.. In addition, the value AST__BAD is taken to -f mean "unknown". The values returned by logical operators may therefore -f be 0, 1 or AST__BAD. Where appropriate, "tri-state" logic is -f implemented. For example, A.OR.B may evaluate to 1 if A is non-zero, -f even if B has the value AST__BAD. This is because the result of the -f operation would not be affected by the value of B, so long as A is -f non-zero. -* -c The following boolean operators are available: -f The following logical operators are available: -c - x1 && x2: Boolean AND between "x1" and "x2", returning 1 if both "x1" -c and "x2" are non-zero, and 0 otherwise. This operator implements -c tri-state logic. (The synonym ".and." is also provided for compatibility -c with Fortran.) -f - X1 .AND. X2: Logical AND between X1 and X2, returning 1 if both X1 -f and X2 are non-zero, and 0 otherwise. This operator implements -f tri-state logic. (The synonym "&&" is also provided for compatibility -f with C.) -c - x1 || x2: Boolean OR between "x1" and "x2", returning 1 if either "x1" -c or "x2" are non-zero, and 0 otherwise. This operator implements -c tri-state logic. (The synonym ".or." is also provided for compatibility -c with Fortran.) -f - X1 .OR. X2: Logical OR between X1 and X2, returning 1 if either X1 -f or X2 are non-zero, and 0 otherwise. This operator implements -f tri-state logic. (The synonym "||" is also provided for compatibility -f with C.) -c - x1 ^^ x2: Boolean exclusive OR (XOR) between "x1" and "x2", returning -c 1 if exactly one of "x1" and "x2" is non-zero, and 0 otherwise. Tri-state -c logic is not used with this operator. (The synonyms ".neqv." and ".xor." -c are also provided for compatibility with Fortran, although the second -c of these is not standard.) -f - X1 .NEQV. X2: Logical exclusive OR (XOR) between X1 and X2, -f returning 1 if exactly one of X1 and X2 is non-zero, and 0 -f otherwise. Tri-state logic is not used with this operator. (The -f synonym ".XOR." is also provided, although this is not standard -f Fortran. In addition, the C-like synonym "^^" may be used, although -f this is also not standard.) -c - x1 .eqv. x2: This is provided only for compatibility with Fortran -c and tests whether the boolean states of "x1" and "x2" (i.e. true/false) -c are equal. It is the negative of the exclusive OR (XOR) function. -c Tri-state logic is not used with this operator. -f - X1 .EQV. X2: Tests whether the logical states of X1 and X2 -f (i.e. .TRUE./.FALSE.) are equal. It is the negative of the exclusive OR -f (XOR) function. Tri-state logic is not used with this operator. -c - ! x: Boolean unary NOT operation, returning 1 if "x" is zero, and -c 0 otherwise. (The synonym ".not." is also provided for compatibility -c with Fortran.) -f - .NOT. X: Logical unary NOT operation, returning 1 if X is zero, and -f 0 otherwise. (The synonym "!" is also provided for compatibility with -f C.) - -* Relational Operators: -c Relational operators return the boolean result (0 or 1) of comparing -c the values of two floating point values for equality or inequality. The -c value AST__BAD may also be returned if either argument is . -f Relational operators return the logical result (0 or 1) of comparing -f the values of two floating point values for equality or inequality. The -f value AST__BAD may also be returned if either argument is . -* -* The following relational operators are available: -c - x1 == x2: Tests whether "x1" equals "x1". (The synonym ".eq." is -c also provided for compatibility with Fortran.) -f - X1 .EQ. X2: Tests whether X1 equals X2. (The synonym "==" is also -f provided for compatibility with C.) -c - x1 != x2: Tests whether "x1" is unequal to "x2". (The synonym ".ne." -c is also provided for compatibility with Fortran.) -f - X1 .NE. X2: Tests whether X1 is unequal to X2. (The synonym "!=" is -f also provided for compatibility with C.) -c - x1 > x2: Tests whether "x1" is greater than "x2". (The synonym -c ".gt." is also provided for compatibility with Fortran.) -f - X1 .GT. X2: Tests whether X1 is greater than X2. (The synonym ">" is -f also provided for compatibility with C.) -c - x1 >= x2: Tests whether "x1" is greater than or equal to "x2". (The -c synonym ".ge." is also provided for compatibility with Fortran.) -f - X1 .GE. X2: Tests whether X1 is greater than or equal to X2. (The -f synonym ">=" is also provided for compatibility with C.) -c - x1 < x2: Tests whether "x1" is less than "x2". (The synonym ".lt." -c is also provided for compatibility with Fortran.) -f - X1 .LT. X2: Tests whether X1 is less than X2. (The synonym "<" is also -f provided for compatibility with C.) -c - x1 <= x2: Tests whether "x1" is less than or equal to "x2". (The -c synonym ".le." is also provided for compatibility with Fortran.) -f - X1 .LE. X2: Tests whether X1 is less than or equal to X2. (The synonym -f "<=" is also provided for compatibility with C.) -* -c Note that relational operators cannot usefully be used to compare -c values with the value (representing missing data), because the -c result is always . The isbad() function should be used instead. -f Note that relational operators cannot usefully be used to compare -f values with the value (representing missing data), because the -f result is always . The ISBAD() function should be used instead. -f -f Note, also, that because logical operators can operate on floating -f point values, care must be taken to use parentheses in some cases -f where they would not normally be required in Fortran. For example, -f the expresssion: -f - .NOT. A .EQ. B -f -f must be written: -f - .NOT. ( A .EQ. B ) -f -f to prevent the .NOT. operator from associating with the variable A. - -* Bitwise Operators: -c The bitwise operators provided by C are often useful when operating on -c raw data (e.g. from instruments), so they are also provided for use in -c MathMap expressions. In this case, however, the values on which they -c operate are floating point values rather than pure integers. In order -c to produce results which match the pure integer case, the operands are -c regarded as fixed point binary numbers (i.e. with the binary -c equivalent of a decimal point) with negative numbers represented using -c twos-complement notation. For integer values, the resulting bit -c pattern corresponds to that of the equivalent signed integer (digits -c to the right of the point being zero). Operations on the bits -c representing the fractional part are also possible, however. -f Bitwise operators are often useful when operating on raw data -f (e.g. from instruments), so they are provided for use in MathMap -f expressions. In this case, however, the values on which they operate -f are floating point values rather than the more usual pure integers. In -f order to produce results which match the pure integer case, the -f operands are regarded as fixed point binary numbers (i.e. with the -f binary equivalent of a decimal point) with negative numbers -f represented using twos-complement notation. For integer values, the -f resulting bit pattern corresponds to that of the equivalent signed -f integer (digits to the right of the point being zero). Operations on -f the bits representing the fractional part are also possible, however. -* -* The following bitwise operators are available: -c - x1 >> x2: Rightward bit shift. The integer value of "x2" is taken -c (rounding towards zero) and the bits representing "x1" are then -c shifted this number of places to the right (or to the left if the -c number of places is negative). This is equivalent to dividing "x1" by -c the corresponding power of 2. -f - X1 >> X2: Rightward bit shift. The integer value of X2 is taken -f (rounding towards zero) and the bits representing X1 are then -f shifted this number of places to the right (or to the left if the -f number of places is negative). This is equivalent to dividing X1 by -f the corresponding power of 2. -c - x1 << x2: Leftward bit shift. The integer value of "x2" is taken -c (rounding towards zero), and the bits representing "x1" are then -c shifted this number of places to the left (or to the right if the -c number of places is negative). This is equivalent to multiplying "x1" -c by the corresponding power of 2. -f - X1 << X2: Leftward bit shift. The integer value of X2 is taken -f (rounding towards zero), and the bits representing X1 are then -f shifted this number of places to the left (or to the right if the -f number of places is negative). This is equivalent to multiplying X1 -f by the corresponding power of 2. -c - x1 & x2: Bitwise AND between the bits of "x1" and those of "x2" -c (equivalent to a boolean AND applied at each bit position in turn). -f - X1 & X2: Bitwise AND between the bits of X1 and those of X2 -f (equivalent to a logical AND applied at each bit position in turn). -c - x1 | x2: Bitwise OR between the bits of "x1" and those of "x2" -c (equivalent to a boolean OR applied at each bit position in turn). -f - X1 | X2: Bitwise OR between the bits of X1 and those of X2 -f (equivalent to a logical OR applied at each bit position in turn). -c - x1 ^ x2: Bitwise exclusive OR (XOR) between the bits of "x1" and -c those of "x2" (equivalent to a boolean XOR applied at each bit -c position in turn). -f - X1 ^ X2: Bitwise exclusive OR (XOR) between the bits of X1 and -f those of X2 (equivalent to a logical XOR applied at each bit -f position in turn). -* -c Note that no bit inversion operator ("~" in C) is provided. This is -c because inverting the bits of a twos-complement fixed point binary -c number is equivalent to simply negating it. This differs from the -c pure integer case because bits to the right of the binary point are -c also inverted. To invert only those bits to the left of the binary -c point, use a bitwise exclusive OR with the value -1 (i.e. "x^-1"). -f Note that no bit inversion operator is provided. This is -f because inverting the bits of a twos-complement fixed point binary -f number is equivalent to simply negating it. This differs from the -f pure integer case because bits to the right of the binary point are -f also inverted. To invert only those bits to the left of the binary -f point, use a bitwise exclusive OR with the value -1 (i.e. X^-1). - -* Functions: -* The following functions are available: -c - abs(x): Absolute value of "x" (sign removal), same as fabs(x). -f - ABS(X): Absolute value of X (sign removal), same as FABS(X). -c - acos(x): Inverse cosine of "x", in radians. -f - ACOS(X): Inverse cosine of X, in radians. -c - acosd(x): Inverse cosine of "x", in degrees. -f - ACOSD(X): Inverse cosine of X, in degrees. -c - acosh(x): Inverse hyperbolic cosine of "x". -f - ACOSH(X): Inverse hyperbolic cosine of X. -c - acoth(x): Inverse hyperbolic cotangent of "x". -f - ACOTH(X): Inverse hyperbolic cotangent of X. -c - acsch(x): Inverse hyperbolic cosecant of "x". -f - ACSCH(X): Inverse hyperbolic cosecant of X. -c - aint(x): Integer part of "x" (round towards zero), same as int(x). -f - AINT(X): Integer part of X (round towards zero), same as INT(X). -c - asech(x): Inverse hyperbolic secant of "x". -f - ASECH(X): Inverse hyperbolic secant of X. -c - asin(x): Inverse sine of "x", in radians. -f - ASIN(X): Inverse sine of X, in radians. -c - asind(x): Inverse sine of "x", in degrees. -f - ASIND(X): Inverse sine of X, in degrees. -c - asinh(x): Inverse hyperbolic sine of "x". -f - ASINH(X): Inverse hyperbolic sine of X. -c - atan(x): Inverse tangent of "x", in radians. -f - ATAN(X): Inverse tangent of X, in radians. -c - atand(x): Inverse tangent of "x", in degrees. -f - ATAND(X): Inverse tangent of X, in degrees. -c - atanh(x): Inverse hyperbolic tangent of "x". -f - ATANH(X): Inverse hyperbolic tangent of X. -c - atan2(x1, x2): Inverse tangent of "x1/x2", in radians. -f - ATAN2(X1, X2): Inverse tangent of X1/X2, in radians. -c - atan2d(x1, x2): Inverse tangent of "x1/x2", in degrees. -f - ATAN2D(X1, X2): Inverse tangent of X1/X2, in degrees. -c - ceil(x): Smallest integer value not less then "x" (round towards -c plus infinity). -f - CEIL(X): Smallest integer value not less then X (round towards -f plus infinity). -c - cos(x): Cosine of "x" in radians. -f - COS(X): Cosine of X in radians. -c - cosd(x): Cosine of "x" in degrees. -f - COSD(X): Cosine of X in degrees. -c - cosh(x): Hyperbolic cosine of "x". -f - COSH(X): Hyperbolic cosine of X. -c - coth(x): Hyperbolic cotangent of "x". -f - COTH(X): Hyperbolic cotangent of X. -c - csch(x): Hyperbolic cosecant of "x". -f - CSCH(X): Hyperbolic cosecant of X. -c - dim(x1, x2): Returns "x1-x2" if "x1" is greater than "x2", otherwise 0. -f - DIM(X1, X2): Returns X1-X2 if X1 is greater than X2, otherwise 0. -c - exp(x): Exponential function of "x". -f - EXP(X): Exponential function of X. -c - fabs(x): Absolute value of "x" (sign removal), same as abs(x). -f - FABS(X): Absolute value of X (sign removal), same as ABS(X). -c - floor(x): Largest integer not greater than "x" (round towards -c minus infinity). -f - FLOOR(X): Largest integer not greater than X (round towards -f minus infinity). -c - fmod(x1, x2): Remainder when "x1" is divided by "x2", same as -c mod(x1, x2). -f - FMOD(X1, X2): Remainder when X1 is divided by X2, same as -f MOD(X1, X2). -c - gauss(x1, x2): Random sample from a Gaussian distribution with mean -c "x1" and standard deviation "x2". -f - GAUSS(X1, X2): Random sample from a Gaussian distribution with mean -f X1 and standard deviation X2. -c - int(x): Integer part of "x" (round towards zero), same as aint(x). -f - INT(X): Integer part of X (round towards zero), same as AINT(X). -c - isbad(x): Returns 1 if "x" has the value (AST__BAD), otherwise 0. -f - ISBAD(X): Returns 1 if X has the value (AST__BAD), otherwise 0. -c - log(x): Natural logarithm of "x". -f - LOG(X): Natural logarithm of X. -c - log10(x): Logarithm of "x" to base 10. -f - LOG10(X): Logarithm of X to base 10. -c - max(x1, x2, ...): Maximum of two or more values. -f - MAX(X1, X2, ...): Maximum of two or more values. -c - min(x1, x2, ...): Minimum of two or more values. -f - MIN(X1, X2, ...): Minimum of two or more values. -c - mod(x1, x2): Remainder when "x1" is divided by "x2", same as -c fmod(x1, x2). -f - MOD(X1, X2): Remainder when X1 is divided by X2, same as -f FMOD(X1, X2). -c - nint(x): Nearest integer to "x" (round to nearest). -f - NINT(X): Nearest integer to X (round to nearest). -c - poisson(x): Random integer-valued sample from a Poisson -c distribution with mean "x". -f - POISSON(X): Random integer-valued sample from a Poisson -f distribution with mean X. -c - pow(x1, x2): "x1" raised to the power of "x2". -f - POW(X1, X2): X1 raised to the power of X2. -c - qif(x1, x2, x3): Returns "x2" if "x1" is true, and "x3" otherwise. -f - QIF(x1, x2, x3): Returns X2 if X1 is true, and X3 otherwise. -c - rand(x1, x2): Random sample from a uniform distribution in the -c range "x1" to "x2" inclusive. -f - RAND(X1, X2): Random sample from a uniform distribution in the -f range X1 to X2 inclusive. -c - sech(x): Hyperbolic secant of "x". -f - SECH(X): Hyperbolic secant of X. -c - sign(x1, x2): Absolute value of "x1" with the sign of "x2" -c (transfer of sign). -f - SIGN(X1, X2): Absolute value of X1 with the sign of X2 -f (transfer of sign). -c - sin(x): Sine of "x" in radians. -f - SIN(X): Sine of X in radians. -c - sinc(x): Sinc function of "x" [= "sin(x)/x"]. -f - SINC(X): Sinc function of X [= SIN(X)/X]. -c - sind(x): Sine of "x" in degrees. -f - SIND(X): Sine of X in degrees. -c - sinh(x): Hyperbolic sine of "x". -f - SINH(X): Hyperbolic sine of X. -c - sqr(x): Square of "x" (= "x*x"). -f - SQR(X): Square of X (= X*X). -c - sqrt(x): Square root of "x". -f - SQRT(X): Square root of X. -c - tan(x): Tangent of "x" in radians. -f - TAN(X): Tangent of X in radians. -c - tand(x): Tangent of "x" in degrees. -f - TAND(X): Tangent of X in degrees. -c - tanh(x): Hyperbolic tangent of "x". -f - TANH(X): Hyperbolic tangent of X. - -* Symbolic Constants: -* The following symbolic constants are available (the enclosing "<>" -* brackets must be included): -c - : The "bad" value (AST__BAD) used to flag missing data. Note -c that you cannot usefully compare values with this constant because the -c result is always . The isbad() function should be used instead. -f - : The "bad" value (AST__BAD) used to flag missing data. Note -f that you cannot usefully compare values with this constant because the -f result is always . The ISBAD() function should be used instead. -c - : Number of decimal digits of precision available in a -c floating point (double) value. -f - : Number of decimal digits of precision available in a -f floating point (double precision) value. -* - : Base of natural logarithms. -* - : Smallest positive number such that 1.0+ is -* distinguishable from unity. -c - : The number of base digits stored in the -c mantissa of a floating point (double) value. -f - : The number of base digits stored in the -f mantissa of a floating point (double precision) value. -c - : Maximum representable floating point (double) value. -f - : Maximum representable floating point (double precision) value. -c - : Maximum integer such that 10 raised to that power -c can be represented as a floating point (double) value. -f - : Maximum integer such that 10 raised to that power -f can be represented as a floating point (double precision) value. -c - : Maximum integer such that raised to that -c power minus 1 can be represented as a floating point (double) value. -f - : Maximum integer such that raised to that -f power minus 1 can be represented as a floating point (double precision) -f value. -c - : Smallest positive number which can be represented as a -c normalised floating point (double) value. -f - : Smallest positive number which can be represented as a -f normalised floating point (double precision) value. -c - : Minimum negative integer such that 10 raised to that -c power can be represented as a normalised floating point (double) value. -f - : Minimum negative integer such that 10 raised to that -f power can be represented as a normalised floating point (double -f precision) value. -c - : Minimum negative integer such that raised to -c that power minus 1 can be represented as a normalised floating point -c (double) value. -f - : Minimum negative integer such that raised to -f that power minus 1 can be represented as a normalised floating point -f (double precision) value. -* - : Ratio of the circumference of a circle to its diameter. -c - : The radix (number base) used to represent the mantissa of -c floating point (double) values. -f - : The radix (number base) used to represent the mantissa of -f floating point (double precision) values. -* - : The mode used for rounding floating point results after -* addition. Possible values include: -1 (indeterminate), 0 (toward -* zero), 1 (to nearest), 2 (toward plus infinity) and 3 (toward minus -* infinity). Other values indicate machine-dependent behaviour. - -* Evaluation Precedence and Associativity: -* Items appearing in expressions are evaluated in the following order -* (highest precedence first): -* - Constants and variables -* - Function arguments and parenthesised expressions -* - Function invocations -* - Unary + - ! .not. -* - ** -* - * / -* - + - -* - << >> -* - < .lt. <= .le. > .gt. >= .ge. -* - == .eq. != .ne. -* - & -* - ^ -* - | -* - && .and. -* - ^^ -* - || .or -* - .eqv. .neqv. .xor. -* -* All operators associate from left-to-right, except for unary +, -* unary -, !, .not. and ** which associate from right-to-left. - -* Notes: -* - The sequence of numbers produced by the random number functions -* available within a MathMap is normally unpredictable and different for -* each MathMap. However, this behaviour may be controlled by means of -* the MathMap's Seed attribute. -c - Normally, compound Mappings (CmpMaps) which involve MathMaps will -c not be subject to simplification (e.g. using astSimplify) because AST -c cannot know how different MathMaps will interact. However, in the -c special case where a MathMap occurs in series with its own inverse, -c then simplification may be possible. Whether simplification does, in -c fact, occur under these circumstances is controlled by the MathMap's -c SimpFI and SimpIF attributes. -f - Normally, compound Mappings (CmpMaps) which involve MathMaps will -f not be subject to simplification (e.g. using AST_SIMPLIFY) because AST -f cannot know how different MathMaps will interact. However, in the -f special case where a MathMap occurs in series with its own inverse, -f then simplification may be possible. Whether simplification does, in -f fact, occur under these circumstances is controlled by the MathMap's -f SimpFI and SimpIF attributes. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astMathMap constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astMathMap_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - The variable argument list also prevents this function from -* invoking astMathMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMathMap *new; /* Pointer to new MathMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the MathMap, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitMathMap( NULL, sizeof( AstMathMap ), !class_init, &class_vtab, - "MathMap", nin, nout, nfwd, fwd, ninv, inv ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new MathMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new MathMap. */ - return astMakeId( new ); -} - -AstMathMap *astInitMathMap_( void *mem, size_t size, int init, - AstMathMapVtab *vtab, const char *name, - int nin, int nout, - int nfwd, const char *fwd[], - int ninv, const char *inv[], int *status ) { -/* -*+ -* Name: -* astInitMathMap - -* Purpose: -* Initialise a MathMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "mathmap.h" -* AstMathMap *astInitMathMap_( void *mem, size_t size, int init, -* AstMathMapVtab *vtab, const char *name, -* int nin, int nout, -* int nfwd, const char *fwd[], -* int ninv, const char *inv[] ) - -* Class Membership: -* MathMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new MathMap object. It allocates memory (if necessary) to accommodate -* the MathMap plus any additional data associated with the derived class. -* It then initialises a MathMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a MathMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the MathMap is to be initialised. -* This must be of sufficient size to accommodate the MathMap data -* (sizeof(MathMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the MathMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the MathMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the MathMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new MathMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* nin -* Number of input variables for the MathMap. -* nout -* Number of output variables for the MathMap. -* nfwd -* The number of forward transformation functions being supplied. -* This must be at least equal to "nout". -* fwd -* Pointer to an array, with "nfwd" elements, of pointers to null -* terminated strings which contain each of the forward transformation -* functions. -* ninv -* The number of inverse transformation functions being supplied. -* This must be at least equal to "nin". -* inv -* Pointer to an array, with "ninv" elements, of pointers to null -* terminated strings which contain each of the inverse transformation -* functions. - -* Returned Value: -* A pointer to the new MathMap. - -* Notes: -* - This function does not attempt to ensure that the forward and inverse -* transformations performed by the resulting MathMap are consistent in any -* way. -* - This function makes a copy of the contents of the strings supplied. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstMathMap *new; /* Pointer to new MathMap */ - char **fwdfun; /* Array of cleaned forward functions */ - char **invfun; /* Array of cleaned inverse functions */ - double **fwdcon; /* Constants for forward functions */ - double **invcon; /* Constants for inverse functions */ - int **fwdcode; /* Code for forward functions */ - int **invcode; /* Code for inverse functions */ - int fwdstack; /* Stack size for forward functions */ - int invstack; /* Stack size for inverse functions */ - -/* Initialise. */ - new = NULL; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitMathMapVtab( vtab, name ); - -/* Check the numbers of input and output variables for validity, - reporting an error if necessary. */ - if ( nin < 1 ) { - astError( AST__BADNI, - "astInitMathMap(%s): Bad number of input coordinates (%d).", status, - name, nin ); - astError( AST__BADNI, - "This number should be one or more." , status); - } else if ( nout < 1 ) { - astError( AST__BADNO, - "astInitMathMap(%s): Bad number of output coordinates (%d).", status, - name, nout ); - astError( AST__BADNI, - "This number should be one or more." , status); - -/* Check that sufficient number of forward and inverse transformation - functions have been supplied and report an error if necessary. */ - } else if ( nfwd < nout ) { - astError( AST__INNTF, - "astInitMathMap(%s): Too few forward transformation functions " - "given (%d).", status, - name, nfwd ); - astError( astStatus, - "At least %d forward transformation functions must be " - "supplied. ", status, - nout ); - } else if ( ninv < nin ) { - astError( AST__INNTF, - "astInitMathMap(%s): Too few inverse transformation functions " - "given (%d).", status, - name, ninv ); - astError( astStatus, - "At least %d inverse transformation functions must be " - "supplied. ", status, - nin ); - -/* Of OK, clean the forward and inverse functions provided. This makes - a lower-case copy with white space removed. */ - } else { - CleanFunctions( nfwd, fwd, &fwdfun, status ); - CleanFunctions( ninv, inv, &invfun, status ); - -/* Compile the cleaned functions. From the returned pointers (if - successful), we can now tell which transformations (forward and/or - inverse) are defined. */ - CompileMapping( "astInitMathMap", name, nin, nout, - nfwd, (const char **) fwdfun, - ninv, (const char **) invfun, - &fwdcode, &invcode, &fwdcon, &invcon, - &fwdstack, &invstack, status ); - -/* Initialise a Mapping structure (the parent class) as the first - component within the MathMap structure, allocating memory if - necessary. Specify that the Mapping should be defined in the required - directions. */ - new = (AstMathMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, nout, - ( fwdcode != NULL ), - ( invcode != NULL ) ); - - -/* If an error has occurred, free all the memory which may have been - allocated by the cleaning and compilation steps above. */ - if ( !astOK ) { - FREE_POINTER_ARRAY( fwdfun, nfwd ) - FREE_POINTER_ARRAY( invfun, ninv ) - FREE_POINTER_ARRAY( fwdcode, nfwd ) - FREE_POINTER_ARRAY( invcode, ninv ) - FREE_POINTER_ARRAY( fwdcon, nfwd ) - FREE_POINTER_ARRAY( invcon, ninv ) - } - -/* Initialise the MathMap data. */ -/* ---------------------------- */ -/* Store pointers to the compiled function information, together with - other MathMap data. */ - if ( new ) { - new->fwdfun = fwdfun; - new->invfun = invfun; - new->fwdcode = fwdcode; - new->invcode = invcode; - new->fwdcon = fwdcon; - new->invcon = invcon; - new->fwdstack = fwdstack; - new->invstack = invstack; - new->nfwd = nfwd; - new->ninv = ninv; - new->simp_fi = -INT_MAX; - new->simp_if = -INT_MAX; - -/* Initialise the random number generator context associated with the - MathMap, using an unpredictable default seed value. */ - new->rcontext.active = 0; - new->rcontext.random_int = 0; - new->rcontext.seed_set = 0; - new->rcontext.seed = DefaultSeed( &new->rcontext, status ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new object. */ - return new; -} - -AstMathMap *astLoadMathMap_( void *mem, size_t size, - AstMathMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadMathMap - -* Purpose: -* Load a MathMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "mathmap.h" -* AstMathMap *astLoadMathMap( void *mem, size_t size, -* AstMathMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* MathMap loader. - -* Description: -* This function is provided to load a new MathMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* MathMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a MathMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the MathMap is to be -* loaded. This must be of sufficient size to accommodate the -* MathMap data (sizeof(MathMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the MathMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the MathMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstMathMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new MathMap. If this is NULL, a pointer -* to the (static) virtual function table for the MathMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "MathMap" is used instead. - -* Returned Value: -* A pointer to the new MathMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstMathMap *new; /* Pointer to the new MathMap */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword strings */ - int ifun; /* Loop counter for functions */ - int invert; /* Invert attribute value */ - int nin; /* True number of input coordinates */ - int nout; /* True number of output coordinates */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this MathMap. In this case the - MathMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstMathMap ); - vtab = &class_vtab; - name = "MathMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitMathMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built MathMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "MathMap" ); - -/* Determine if the MathMap is inverted and obtain the "true" number - of input and output coordinates by un-doing the effects of any - inversion. */ - invert = astGetInvert( new ); - nin = invert ? astGetNout( new ) : astGetNin( new ); - nout = invert ? astGetNin( new ) : astGetNout( new ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Numbers of transformation functions. */ -/* ------------------------------------ */ -/* Read the numbers of forward and inverse transformation functions, - supplying appropriate defaults. */ - new->nfwd = astReadInt( channel, "nfwd", nout ); - new->ninv = astReadInt( channel, "ninv", nin ); - if ( astOK ) { - -/* Allocate memory for the MathMap's transformation function arrays. */ - MALLOC_POINTER_ARRAY( new->fwdfun, char *, new->nfwd ) - MALLOC_POINTER_ARRAY( new->invfun, char *, new->ninv ) - if ( astOK ) { - -/* Forward transformation functions. */ -/* --------------------------------- */ -/* Create a keyword for each forward transformation function and read - the function's value as a string. */ - for ( ifun = 0; ifun < new->nfwd; ifun++ ) { - (void) sprintf( key, "fwd%d", ifun + 1 ); - new->fwdfun[ ifun ] = astReadString( channel, key, "" ); - } - -/* Inverse transformation functions. */ -/* --------------------------------- */ -/* Repeat this process for the inverse transformation functions. */ - for ( ifun = 0; ifun < new->ninv; ifun++ ) { - (void) sprintf( key, "inv%d", ifun + 1 ); - new->invfun[ ifun ] = astReadString( channel, key, "" ); - } - -/* Forward-inverse simplification flag. */ -/* ------------------------------------ */ - new->simp_fi = astReadInt( channel, "simpfi", -INT_MAX ); - if ( TestSimpFI( new, status ) ) SetSimpFI( new, new->simp_fi, status ); - -/* Inverse-forward simplification flag. */ -/* ------------------------------------ */ - new->simp_if = astReadInt( channel, "simpif", -INT_MAX ); - if ( TestSimpIF( new, status ) ) SetSimpIF( new, new->simp_if, status ); - -/* Random number context. */ -/* ---------------------- */ -/* Initialise the random number generator context. */ - new->rcontext.active = 0; - new->rcontext.random_int = 0; - -/* Read the flag that determines if the Seed value is set, and the - Seed value itself. */ - new->rcontext.seed_set = astReadInt( channel, "seeded", 0 ); - if ( TestSeed( new, status ) ) { - new->rcontext.seed = astReadInt( channel, "seed", 0 ); - SetSeed( new, new->rcontext.seed, status ); - -/* Supply an unpredictable default Seed value if necessary. */ - } else { - new->rcontext.seed = DefaultSeed( &new->rcontext, status ); - } - -/* Compile the MathMap's transformation functions. */ - CompileMapping( "astLoadMathMap", name, nin, nout, - new->nfwd, (const char **) new->fwdfun, - new->ninv, (const char **) new->invfun, - &new->fwdcode, &new->invcode, - &new->fwdcon, &new->invcon, - &new->fwdstack, &new->invstack, status ); - } - -/* If an error occurred, clean up by deleting the new MathMap. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return the new MathMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - - - - - diff --git a/ast/mathmap.h b/ast/mathmap.h deleted file mode 100644 index e3b4004..0000000 --- a/ast/mathmap.h +++ /dev/null @@ -1,410 +0,0 @@ -#if !defined( MATHMAP_INCLUDED ) /* Include this file only once */ -#define MATHMAP_INCLUDED -/* -*+ -* Name: -* mathmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the MathMap class. - -* Invocation: -* #include "mathmap.h" - -* Description: -* This include file defines the interface to the MathMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The MathMap class implements Mappings that are specified by a series -* of arithmetic expressions that relate output variables to input -* variables (and vice versa). - -* Inheritance: -* The MathMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* Seed -* Random number seed. -* SimpFI -* Forward-inverse MathMap pairs simplify? -* SimpIF -* Inverse-forward MathMap pairs simplify? - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astClearAttrib -* Clear an attribute value for a Frame. -* astGetAttrib -* Get an attribute value for a Frame. -* astMapMerge -* Simplify a sequence of Mappings containing a MathMap. -* astSetAttrib -* Set an attribute value for a Frame. -* astTestAttrib -* Test if an attribute value has been set for a Frame. -* astTransform -* Transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* astClearSeed -* Clear the Seed attribute for a MathMap. -* astClearSimpFI -* Clear the SimpFI attribute for a MathMap. -* astClearSimpIF -* Clear the SimpIF attribute for a MathMap. -* astGetSeed -* Get the value of the Seed attribute for a MathMap. -* astGetSimpFI -* Get the value of the SimpFI attribute for a MathMap. -* astGetSimpIF -* Get the value of the SimpIF attribute for a MathMap. -* astSetSeed -* Set the value of the Seed attribute for a MathMap. -* astSetSimpFI -* Set the value of the SimpFI attribute for a MathMap. -* astSetSimpIF -* Set the value of the SimpIF attribute for a MathMap. -* astTestSeed -* Test whether a value has been set for the Seed attribute of a -* MathMap. -* astTestSimpFI -* Test whether a value has been set for the SimpFI attribute of a -* MathMap. -* astTestSimpIF -* Test whether a value has been set for the SimpIF attribute of a -* MathMap. - -* Other Class Functions: -* Public: -* astIsAMathMap -* Test class membership. -* astMathMap -* Create a MathMap. -* -* Protected: -* astCheckMathMap -* Validate class membership. -* astInitMathMap -* Initialise a MathMap. -* astInitMathMapVtab -* Initialise the virtual function table for the MathMap class. -* astLoadMathMap -* Load a MathMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstMathMap -* MathMap object type. -* -* Protected: -* AstMathMapVtab -* MathMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 3-SEP-1999 (RFWS): -* Original version. -* 8-JAN-2003 (DSB): -* Added protected astInitMathMapVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#include "pointset.h" /* Sets of points/coordinates */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros. */ -/* ======= */ -/* This value defines the size of an internal table in the AstMathMap - data type. Since it will be publicly accessible (but of no external - use), we give it an obscure name. */ - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif -#define AST_MATHMAP_RAND_CONTEXT_NTAB_ (32) - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* Random number generator context. */ -/* -------------------------------- */ -/* This structure holds the context for the random number generator - used by each MathMap. This ensures that the random number sequences - used by different MathMaps are independent, and can be independently - controlled by setting/clearing their Seed attributes. Random numbers - are produced by combining the output of two internal generators. */ -typedef struct AstMathMapRandContext_ { - long int rand1; /* State of first internal generator */ - long int rand2; /* State of second internal generator */ - long int random_int; /* Last random integer produced */ - long int table[ AST_MATHMAP_RAND_CONTEXT_NTAB_ ]; /* Shuffle table */ - int active; /* Generator has been initialised? */ - int seed; /* Seed to be used during initialisation */ - int seed_set; /* Seed value set via "Seed" attribute? */ -} AstMathMapRandContext_; - -/* MathMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstMathMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstMathMapRandContext_ rcontext; /* Random number generator context */ - char **fwdfun; /* Array of forward functions */ - char **invfun; /* Array of inverse functions */ - double **fwdcon; /* Array of constants for forward functions */ - double **invcon; /* Array of constants for inverse functions */ - int **fwdcode; /* Array of opcodes for forward functions */ - int **invcode; /* Array of opcodes for inverse functions */ - int fwdstack; /* Stack size required by forward functions */ - int invstack; /* Stack size required by inverse functions */ - int nfwd; /* Number of forward functions */ - int ninv; /* Number of inverse functions */ - int simp_fi; /* Forward-inverse MathMap pairs simplify? */ - int simp_if; /* Inverse-forward MathMap pairs simplify? */ -} AstMathMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstMathMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - int (* GetSeed)( AstMathMap *, int * ); - int (* GetSimpFI)( AstMathMap *, int * ); - int (* GetSimpIF)( AstMathMap *, int * ); - int (* TestSeed)( AstMathMap *, int * ); - int (* TestSimpFI)( AstMathMap *, int * ); - int (* TestSimpIF)( AstMathMap *, int * ); - void (* ClearSeed)( AstMathMap *, int * ); - void (* ClearSimpFI)( AstMathMap *, int * ); - void (* ClearSimpIF)( AstMathMap *, int * ); - void (* SetSeed)( AstMathMap *, int, int * ); - void (* SetSimpFI)( AstMathMap *, int, int * ); - void (* SetSimpIF)( AstMathMap *, int, int * ); -} AstMathMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstMathMapGlobals { - AstMathMapVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 51 ]; -} AstMathMapGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(MathMap) /* Check class membership */ -astPROTO_ISA(MathMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstMathMap *astMathMap_( int, int, int, const char *[], int, const char *[], - const char *, int *, ...); -#else -AstMathMap *astMathMapId_( int, int, int, const char *[], int, const char *[], - const char *, ... )__attribute__((format(printf,7,8))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstMathMap *astInitMathMap_( void *, size_t, int, AstMathMapVtab *, - const char *, int, int, - int, const char *[], int, const char *[], int * ); - -/* Vtab initialiser. */ -void astInitMathMapVtab_( AstMathMapVtab *, const char *, int * ); - -/* Loader. */ -AstMathMap *astLoadMathMap_( void *, size_t, AstMathMapVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitMathMapGlobals_( AstMathMapGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -#if defined(astCLASS) /* Protected */ -int astGetSeed_( AstMathMap *, int * ); -int astGetSimpFI_( AstMathMap *, int * ); -int astGetSimpIF_( AstMathMap *, int * ); -int astTestSeed_( AstMathMap *, int * ); -int astTestSimpFI_( AstMathMap *, int * ); -int astTestSimpIF_( AstMathMap *, int * ); -void astClearSeed_( AstMathMap *, int * ); -void astClearSimpFI_( AstMathMap *, int * ); -void astClearSimpIF_( AstMathMap *, int * ); -void astSetSeed_( AstMathMap *, int, int * ); -void astSetSimpFI_( AstMathMap *, int, int * ); -void astSetSimpIF_( AstMathMap *, int, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckMathMap(this) astINVOKE_CHECK(MathMap,this,0) -#define astVerifyMathMap(this) astINVOKE_CHECK(MathMap,this,1) - -/* Test class membership. */ -#define astIsAMathMap(this) astINVOKE_ISA(MathMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astMathMap astINVOKE(F,astMathMap_) -#else -#define astMathMap astINVOKE(F,astMathMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitMathMap(mem,size,init,vtab,name,nin,nout,nfwd,fwd,ninv,inv) \ -astINVOKE(O,astInitMathMap_(mem,size,init,vtab,name,nin,nout,nfwd,fwd,ninv,inv,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitMathMapVtab(vtab,name) astINVOKE(V,astInitMathMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadMathMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadMathMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckMathMap to validate MathMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -#if defined(astCLASS) /* Protected */ -#define astClearSeed(this) \ -astINVOKE(V,astClearSeed_(astCheckMathMap(this),STATUS_PTR)) -#define astClearSimpFI(this) \ -astINVOKE(V,astClearSimpFI_(astCheckMathMap(this),STATUS_PTR)) -#define astClearSimpIF(this) \ -astINVOKE(V,astClearSimpIF_(astCheckMathMap(this),STATUS_PTR)) -#define astGetSeed(this) \ -astINVOKE(V,astGetSeed_(astCheckMathMap(this),STATUS_PTR)) -#define astGetSimpFI(this) \ -astINVOKE(V,astGetSimpFI_(astCheckMathMap(this),STATUS_PTR)) -#define astGetSimpIF(this) \ -astINVOKE(V,astGetSimpIF_(astCheckMathMap(this),STATUS_PTR)) -#define astSetSeed(this,value) \ -astINVOKE(V,astSetSeed_(astCheckMathMap(this),value,STATUS_PTR)) -#define astSetSimpFI(this,value) \ -astINVOKE(V,astSetSimpFI_(astCheckMathMap(this),value,STATUS_PTR)) -#define astSetSimpIF(this,value) \ -astINVOKE(V,astSetSimpIF_(astCheckMathMap(this),value,STATUS_PTR)) -#define astTestSeed(this) \ -astINVOKE(V,astTestSeed_(astCheckMathMap(this),STATUS_PTR)) -#define astTestSimpFI(this) \ -astINVOKE(V,astTestSimpFI_(astCheckMathMap(this),STATUS_PTR)) -#define astTestSimpIF(this) \ -astINVOKE(V,astTestSimpIF_(astCheckMathMap(this),STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/matrixmap.c b/ast/matrixmap.c deleted file mode 100644 index 2e6420a..0000000 --- a/ast/matrixmap.c +++ /dev/null @@ -1,5731 +0,0 @@ -/* -*class++ -* Name: -* MatrixMap - -* Purpose: -* Map coordinates by multiplying by a matrix. - -* Constructor Function: -c astMatrixMap -f AST_MATRIXMAP - -* Description: -* A MatrixMap is form of Mapping which performs a general linear -* transformation. Each set of input coordinates, regarded as a -* column-vector, are pre-multiplied by a matrix (whose elements -* are specified when the MatrixMap is created) to give a new -* column-vector containing the output coordinates. If appropriate, -* the inverse transformation may also be performed. - -* Inheritance: -* The MatrixMap class inherits from the Mapping class. - -* Attributes: -* The MatrixMap class does not define any new attributes beyond -* those which are applicable to all Mappings. - -* Functions: -c The MatrixMap class does not define any new functions beyond those -f The MatrixMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 9-FEB-1996 (DSB): -* Original version. -* 13-NOV-1996 (DSB): -* Updated to support attributes, I/O and an external interface. -* 3-JUN-1997 (DSB): -* astMtrMult and astMtrRot made protected instead of public. -* 16-JUN-1997 (RFWS): -* Tidied public prologues. -* 24-JUN-1997 (DSB): -* Zero returned for coordinates which are indeterminate as a -* result of using an inverted, non-square, diagonal matrix. -* 10-OCT-1997 (DSB): -* o The inverse matrix is no longer dumped by the Dump function. -* Instead, it is re-calculated by the Load function. -* o The description of argument "form" in astMatrixMap corrected -* to indicate that a value of 2 produces a unit matrix. -* o String values used to represent choices externally, instead -* of integers. -* 24-NOV-1997 (DSB): -* Use of error code AST__OPT replaced by AST__RDERR. -* 28-JAN-1998 (DSB): -* Bug fix in astMtrMult: the matrix (forward or inverse) used for -* the "a" MatrixMap was determined by the Invert flag of the other -* ("this") MatrixMap. -* 14-APR-1998 (DSB): -* Bug fix in Dump. Previously, matrix elements with value AST__BAD -* were explicitly written out. Now they are not written out, since -* AST__BAD can have different values on different machines. Missing -* elements default to AST__BAD when read back in using astLoadMatrixMap. -* 20-APR-1998 (DSB): -* Bug fix in astLoadMatrixMap: initialise the pointer to the inverse -* matrix array to NULL if no inverse matrix is needed. -* 25-AUG-1998 (DSB): -* - Transform changed so that bad input axis values are not -* propagated to output axes which are independant of the input axis. -* - CompressMatrix changed to allow a tolerance of DBL_EPSILON when -* determining if a matrix is a unit matrix, or a diagonal matrix. -* - MapMerge changed to allow MatrixMaps to swap with PermMaps -* in order to move the MatrixMap closer to a Mapping with which it -* could merge. -* 22-FEB-1999 (DSB): -* Changed logic of MapMerge to avoid infinite looping. -* 5-MAY-1999 (DSB): -* More corrections to MapMerge: Cleared up errors in the use of the -* supplied invert flags, and corrected logic for deciding which -* neighbouring Mapping to swap with. -* 16-JUL-1999 (DSB): -* Fixed memory leaks in MatWin and MapMerge. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitatrixMapVtab -* method. -* 11-SEP-2003 (DSB): -* Increased tolerance on checks for unit matrices within -* CompressMatrix. Now uses sqrt(DBL_EPSILON)*diag (previously was -* DBL_EPSILON*DIAG ). -* 10-NOV-2003 (DSB): -* Modified functions which swap a MatrixMap with another Mapping -* (e.g. MatSwapPerm, etc), to simplify the returned Mappings. -* 13-JAN-2003 (DSB): -* Modified the tolerance used by CompressMatrix when checking for -* zero matrix elements. Old system compared each element to thre -* size of the diagonal, but different scalings on different axes could -* cause this to trat as zero values which should nto be treated as -* zero. -* 23-APR-2004 (DSB): -* Changes to simplification algorithm. -* 8-JUL-2004 (DSB): -* astMtrMult - Report an error if either MatrixMap does not have a -* defined forward transformation. -* 1-SEP-2004 (DSB): -* Ensure do1 and do2 are initialised before use in MapMerge. -* 7-SEP-2005 (DSB): -* Take account of the Invert flag when using the zoom factor from -* a ZoomMap. -* 14-FEB-2006 (DSB): -* Correct row/col confusion in CompressMatrix. -* 15-MAR-2006 (DSB): -* Override astEqual. -* 15-MAR-2009 (DSB): -* MapSplit: Only create the returned Mapping if it would have some -* outputs. Also, do not create the returned Mapping if any output -* depends on a mixture of selected and unselected inputs. -* 16-JUL-2009 (DSB): -* MatPerm: Fix memory leak (mm2 was not being annulled). -* 2-OCT-2012 (DSB): -* - Check for Infs as well as NaNs. -* - In MapSplit do not split the MatrixMap if the resulting -* matrix would contain only bad elements. -* - Report an error if an attempt is made to create a MatrixMap -* containing only bad elements. -* 4-NOV-2013 (DSB): -* Allow a full form MatrixMap to be simplified to a diagonal form -* MatrixMap if all the off-diagonal values are zero. -* 23-APR-2015 (DSB): -* Improve MapMerge. If a MatrixMap can merge with its next-but-one -* neighbour, then swap the MatrixMap with its neighbour, so that -* it is then next its next-but-one neighbour, and then merge the -* two Mappings into a single Mapping. Previously, only the swap -* was performed - not the merger. And the swap was only performed -* if the intervening neighbour could not itself merge. This could -* result in an infinite simplification loop, which was detected by -* CmpMap and and aborted, resulting in no useful simplification. -* 15-JUN-2017 (DSB): -* A diagonal MatrixMap in which the diagonal elements are all zero -* cannot be simplified to a ZoomMap, since ZoomMaps cannot have -* zero zoom factor. -* 16-JUN-2017 (DSB): -* Fix error checking bug in MtrMult - it was checking for the -* inverse transformation of "this" instead of the forward -* transformation of "a". -* 7-NOW-2017 (DSB): -* Allow a diagonal MatrixMap to merge with a WinMap. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS MatrixMap - -/* Define identifiers for the different forms of matrix storage. */ -#define FULL 0 -#define DIAGONAL 1 -#define UNIT 2 - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "matrixmap.h" /* Interface definition for this class */ -#include "pal.h" /* SLALIB function definitions */ -#include "permmap.h" -#include "zoommap.h" -#include "unitmap.h" -#include "winmap.h" - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; -static const char *Form[3] = { "Full", "Diagonal", "Unit" }; /* Text values - used to represent storage form externally */ - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int *(* parent_mapsplit)( AstMapping *, int, const int *, AstMapping **, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(MatrixMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(MatrixMap,Class_Init) -#define class_vtab astGLOBAL(MatrixMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstMatrixMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstMatrixMap *astMatrixMapId_( int, int, int, const double [], const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMatrixMap *MatMat( AstMapping *, AstMapping *, int, int, int * ); -static AstMatrixMap *MatPerm( AstMatrixMap *, AstPermMap *, int, int, int, int * ); -static AstMatrixMap *MatZoom( AstMatrixMap *, AstZoomMap *, int, int, int * ); -static AstMatrixMap *MtrMult( AstMatrixMap *, AstMatrixMap *, int * ); -static AstMatrixMap *MtrRot( AstMatrixMap *, double, const double[], int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstWinMap *MatWin2( AstMatrixMap *, AstWinMap *, int, int, int, int * ); -static double *InvertMatrix( int, int, int, double *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int FindString( int, const char *[], const char *, const char *, const char *, const char *, int * ); -static int Ustrcmp( const char *, const char *, int * ); -static int GetTranForward( AstMapping *, int * ); -static int GetIsLinear( AstMapping *, int * ); -static int GetTranInverse( AstMapping *, int * ); -static int CanSwap( AstMapping *, AstMapping *, int, int, int *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int PermOK( AstMapping *, int * ); -static int ScalingRowCol( AstMatrixMap *, int, int * ); -static void CompressMatrix( AstMatrixMap *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *obj, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void ExpandMatrix( AstMatrixMap *, int * ); -static void MatWin( AstMapping **, int *, int, int * ); -static void MatPermSwap( AstMapping **, int *, int, int * ); -static void PermGet( AstPermMap *, int **, int **, double **, int * ); -static void SMtrMult( int, int, int, const double *, double *, double*, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); - -/* Member functions. */ -/* ================= */ -static int CanSwap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, - int *simpler, int *status ){ -/* -* Name: -* CanSwap - -* Purpose: -* Determine if two Mappings could be swapped. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* int CanSwap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, -* int *simpler, int *status ) - -* Class Membership: -* MatrixMap member function - -* Description: -* This function returns a flag indicating if the pair of supplied -* Mappings could be replaced by an equivalent pair of Mappings from the -* same classes as the supplied pair, but in reversed order. Each pair -* of Mappings is considered to be compunded in series. The supplied -* Mapings are not changed in any way. - -* Parameters: -* map1 -* The Mapping to be applied first. -* map2 -* The Mapping to be applied second. -* inv1 -* The invert flag to use with map1. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* inv2 -* The invert flag to use with map2. -* simpler -* Addresss of a location at which to return a flag indicating if -* the swapped Mappings would be intrinsically simpler than the -* original Mappings. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* 1 if the Mappings could be swapped, 0 otherwise. - -* Notes: -* - One of the supplied pair of Mappings must be a MatrixMap. -* - A value of 0 is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstMatrixMap *mat; /* Pointer to MatrixMap Mapping */ - AstMapping *nomat; /* Pointer to non-MatrixMap Mapping */ - const char *class1; /* Pointer to map1 class string */ - const char *class2; /* Pointer to map2 class string */ - const char *nomat_class; /* Pointer to non-MatrixMap class string */ - double *consts; /* Pointer to constants array */ - int *inperm; /* Pointer to input axis permutation array */ - int *outperm; /* Pointer to output axis permutation array */ - int i; /* Loop count */ - int invert[ 2 ]; /* Original invert flags */ - int nax; /* No. of in/out coordinates for the MatrixMap */ - int nin; /* No. of input coordinates for the PermMap */ - int nout; /* No. of output coordinates for the PermMap */ - int ret; /* Returned flag */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise */ - ret = 0; - *simpler = 0; - -/* Temporarily set the Invert attributes of both Mappings to the supplied - values. */ - invert[ 0 ] = astGetInvert( map1 ); - astSetInvert( map1, inv1 ); - - invert[ 1 ] = astGetInvert( map2 ); - astSetInvert( map2, inv2 ); - -/* Get the classes of the two mappings. */ - class1 = astGetClass( map1 ); - class2 = astGetClass( map2 ); - if( astOK ){ - -/* Get a pointer to the MatrixMap and non-MatrixMap Mappings. */ - if( !strcmp( class1, "MatrixMap" ) ){ - mat = (AstMatrixMap *) map1; - nomat = map2; - nomat_class = class2; - } else { - nomat = map1; - mat = (AstMatrixMap *) map2; - nomat_class = class1; - } - -/* Get the number of input axes for the MatrixMap. */ - nax = astGetNin( mat ); - -/* If it is a WinMap, the Mappings can be swapped. */ - if( !strcmp( nomat_class, "WinMap" ) ){ - ret = 1; - -/* If it is a PermMap, the Mappings can be swapped so long as: - 1) all links between input and output axes in the PermMap are - bi-directional. This does not preclude the existence of unconnected - axes, which do not have links (bi-directional or otherwise). - 2) The MatrixMap is square, and invertable. - 3) If the permMap is applied first, then each output of the PermMap - which is assigned a constant value must correspond to a "scaling" row - and column in the MatrixMap. I.e. if PermMap output axis "i" is - assigned a constant value, then row i and column i of the following - MatrixMap must contain only zeros, EXCEPT for the diagonal term (row - i, column i) which must be non-zero. If the Mappings are in the other - order, then the same applies to PermMap input axes assigned a constant - value. */ - -/* Check the other Mapping is a PermMap, and that the MatrixMap is square - and has an inverse. */ - } else if( !strcmp( nomat_class, "PermMap" ) && - nax == astGetNout( mat ) && ( mat->form == UNIT || - ( mat->i_matrix != NULL && - mat->f_matrix != NULL ) ) ) { - -/* Get the number of input and output coordinates for the PermMap. */ - nin = astGetNin( nomat ); - nout = astGetNout( nomat ); - -/* We need to know the axis permutation arrays and constants array for - the PermMap. */ - PermGet( (AstPermMap *) nomat, &outperm, &inperm, &consts, status ); - if( astOK ) { - -/* Indicate we can swap with the PermMap. */ - ret = 1; - -/* Check each output axis. If any links between axes are found which are - not bi-directional, indicate that we cannot swap with the PermMap. */ - for( i = 0; i < nout; i++ ){ - if( outperm[ i ] >= 0 && outperm[ i ] < nin ) { - if( inperm[ outperm[ i ] ] != i ) { - ret = 0; - break; - } - } - } - -/* Check each input axis. If any links between axes are found which are - not bi-directional, indicate that we cannot swap with the PermMap. */ - for( i = 0; i < nin; i++ ){ - if( inperm[ i ] >= 0 && inperm[ i ] < nout ) { - if( outperm[ inperm[ i ] ] != i ) { - ret = 0; - break; - } - } - } - -/* If the PermMap is suitable, check that any constant values fed from the - PermMap into the MatrixMap (in either forward or inverse direction) - are not changed by the MatrixMap. This requires the row and column for - each constant axis to be zeros, ecept for a value of 1.0 on the - diagonal. First deal with the cases where the PermMap is applied - first, so the outputs of the PermMap are fed into the MatrixMap in the - forward direction. */ - if( ret && ( nomat == map1 ) ) { - - if( nout != nax ){ - astError( AST__RDERR, "PermMap produces %d outputs, but the following" - "MatrixMap has %d inputs\n", status, nout, nax ); - ret = 0; - } - -/* Consider each output axis of the PermMap. */ - for( i = 0; i < nout && astOK ; i++ ) { - -/* If this PermMap output is assigned a constant... */ - if( outperm[ i ] < 0 || outperm[ i ] >= nin ) { - -/* Check the i'th row of the MatrixMap is all zero except for the i'th - column which must be non-zero. If not indicate that the MatrixMap cannot - swap with the PermMap and leave the loop. */ - if( !ScalingRowCol( mat, i, status ) ) { - ret = 0; - break; - } - } - } - } - -/* Now deal with the cases where the PermMap is applied second, so the inputs - of the PermMap are fed into the MatrixMap in the inverse direction. */ - if( ret && ( nomat == map2 ) ) { - - if( nin != nax ){ - astError( AST__RDERR, "Inverse PermMap produces %d inputs, but the " - "preceding MatrixMap has %d outputs\n", status, nin, nax ); - ret = 0; - } - -/* Consider each input axis of the PermMap. */ - for( i = 0; i < nin && astOK; i++ ){ - -/* If this PermMap input is assigned a constant (by the inverse Mapping)... */ - if( inperm[ i ] < 0 || inperm[ i ] >= nout ) { - -/* Check the i'th row of the MatrixMap is all zero except for the i'th - column which must be non-zero. If not indicate that the MatrixMap cannot - swap with the PermMap and leave the loop. */ - if( !ScalingRowCol( mat, i, status ) ) { - ret = 0; - break; - } - } - } - } - -/* If we can swap with the PermMap, the swapped Mappings may be - intrinsically simpler than the original mappings. */ - if( ret ) { - -/* If the PermMap precedes the WinMap, this will be the case if the PermMap - has more outputs than inputs. If the WinMap precedes the PermMap, this - will be the case if the PermMap has more inputs than outputs. */ - *simpler = ( nomat == map1 ) ? nout > nin : nin > nout; - } - -/* Free the axis permutation and constants arrays. */ - outperm = (int *) astFree( (void *) outperm ); - inperm = (int *) astFree( (void *) inperm ); - consts = (double *) astFree( (void *) consts ); - } - } - } - -/* Re-instate the original settings of the Invert attributes for the - supplied MatrixMaps. */ - astSetInvert( map1, invert[ 0 ] ); - astSetInvert( map2, invert[ 1 ] ); - -/* Return the answer. */ - return astOK ? ret : 0; -} - -static void CompressMatrix( AstMatrixMap *this, int *status ){ -/* -* Name: -* CompressMatrix - -* Purpose: -* If possible, reduce the amount of storage needed to store a MatrixMap. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* void CompressMatrix( AstMatrixMap *this, int *status ) - -* Class Membership: -* MatrixMap member function. - -* Description: -* The supplid MatrixMap is converted to its most compressed form -* (i.e no element values if it is a unit matrix, diagonal elements only -* if it is a diagonal matrix, or all elements otherwise). - -* Parameters: -* this -* A pointer to the MatrixMap to be compressed. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double *a; /* Pointer to next element */ - double *colmax; /* Pointer to array holding column max values */ - double *fmat; /* Pointer to compressed forward matrix */ - double *rowmax; /* Pointer to array holding row max values */ - double mval; /* Matrix element value */ - int i; /* Loop count */ - int j; /* Loop count */ - int k; /* Loop count */ - int ncol; /* No. of columns in forward matrix */ - int ndiag; /* No. of diagonal elements in matrix */ - int new_form; /* Compressed storage form */ - int new_inv; /* New inverse requied? */ - int next_diag; /* Index of next diagonal element */ - int nrow; /* No. of rows in forward matrix */ - -/* Check the global error status. */ - if ( !astOK || !this ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - new_inv = 0; - -/* Get the dimensions of the forward matrix. */ - if( astGetInvert( this ) ){ - nrow = astGetNin( this ); - ncol = astGetNout( this ); - } else { - ncol = astGetNin( this ); - nrow = astGetNout( this ); - } - -/* Store the number of diagonal elements in the matrix. This is the - minimum of the number of rows and columns. */ - if( ncol < nrow ){ - ndiag = ncol; - } else { - ndiag = nrow; - } - -/* If the MatrixMap is already stored in UNIT form, it cannot be compressed - any further. */ - if( this->form == UNIT){ - return; - -/* Otherwise, if the MatrixMap is stored in DIAGONAL form, it could be - compressed into a UNIT MatrixMap if all the supplied element values are - one. */ - } else if( this->form == DIAGONAL ){ - new_form = UNIT; - for( i = 0; i < ndiag; i++ ){ - if( !astEQUAL( (this->f_matrix)[ i ], 1.0 ) ){ - new_form = DIAGONAL; - break; - } - } - -/* If it can be compressed, change the storage form and free the arrays - holding the diagonal element values. */ - if( new_form == UNIT ) { - this->f_matrix = (double *) astFree( (void *)( this->f_matrix ) ); - this->i_matrix = (double *) astFree( (void *)( this->i_matrix ) ); - this->form = UNIT; - } - -/* Otherwise, a full MatrixMap has been supplied, but this could be stored - in a unit or diagonal MatrixMap if the element values are appropriate. */ - } else { - new_form = FULL; - -/* Find the maximum absolute value in each column. Scale by - sqrt(DBL_EPSILON) to be come a lower limit for non-zero values. */ - colmax = astMalloc( ncol*sizeof( double ) ); - if( colmax ) { - for( j = 0; j < ncol; j++ ) { - colmax[ j ] = 0.0; - i = j; - for( k = 0; k < nrow; k++ ) { - mval = (this->f_matrix)[ i ]; - if( mval != AST__BAD ) { - mval = fabs( mval ); - if( mval > colmax[ j ] ) colmax[ j ] = mval; - } - i += ncol; - } - colmax[ j ] *= sqrt( DBL_EPSILON ); - } - } - -/* Find the maximum absolute value in each row. Scale by - sqrt(DBL_EPSILON) to be come a lower limit for non-zero values. */ - rowmax = astMalloc( nrow*sizeof( double ) ); - if( rowmax ) { - for( k = 0; k < nrow; k++ ) { - rowmax[ k ] = 0.0; - i = k*ncol; - for( j = 0; j < ncol; j++ ) { - mval = (this->f_matrix)[ i ]; - if( mval != AST__BAD ) { - mval = fabs( mval ); - if( mval > rowmax[ k ] ) rowmax[ k ] = mval; - } - i++; - } - rowmax[ k ] *= sqrt( DBL_EPSILON ); - } - } - -/* Check memory can be used */ - if( astOK ) { - -/* Initialise a flag indicating that the inverse matrix does not need to - be re-calculated. */ - new_inv = 0; - -/* Initially assume that the forward matrix is a unit matrix. */ - new_form = UNIT; - -/* Store a pointer to the next matrix element. */ - a = this->f_matrix; - -/* Loop through all the rows in the forward matrix array. */ - for( k = 0; k < nrow; k++ ) { - -/* Loop through all the elements in this column. */ - for( j = 0; j < ncol; j++, a++ ) { - -/* If this element is bad, use full form. */ - if( *a == AST__BAD ) { - new_form = FULL; - -/* Otherwise, if this is a diagonal term, check its value. If it is not one, - then the matrix cannot be a unit matrix, but it could still be a diagonal - matrix. */ - } else { - if( j == k ) { - if( *a != 1.0 && new_form == UNIT ) new_form = DIAGONAL; - -/* If this is not a diagonal element, and the element value is not zero, - then the matrix is not a diagonal matrix. Allow a tolerance of - SQRT(DBL_EPSILON) times the largest value in the same row or column as - the current matrix element. That is, an element must be insignificant - to both its row and its column to be considered as effectively zero. - Replace values less than this limit with zero. */ - } else { - mval = fabs( *a ); - if( mval <= rowmax[ k ] && - mval <= colmax[ j ] ) { - -/* If the element will change value, set a flag indicating that the inverse - matrix needs to be re-calculated. */ - if( *a != 0.0 ) new_inv = 1; - -/* Ensure this element value is zero. */ - *a = 0.0; - - } else { - new_form = FULL; - } - } - } - } - } - } - -/* Free memory. */ - colmax = astFree( colmax ); - rowmax = astFree( rowmax ); - -/* If it can be compressed into a UNIT MatrixMap, change the storage form and - free the arrays holding the element values. */ - if( new_form == UNIT ) { - this->f_matrix = (double *) astFree( (void *)( this->f_matrix ) ); - this->i_matrix = (double *) astFree( (void *)( this->i_matrix ) ); - this->form = UNIT; - -/* Otherwise, if it can be compressed into a DIAGONAL MatrixMap, copy the - diagonal elements from the full forward matrix into a newly allocated - array, use this array to replace the forward matrix array in the MatrixMap, - create a new inverse matrix, and change the storage form. */ - } else if( new_form == DIAGONAL ) { - fmat = astMalloc( sizeof(double)*(size_t)ndiag ); - if( fmat ){ - - next_diag = 0; - for( i = 0; i < ndiag; i++ ){ - fmat[ i ] = (this->f_matrix)[ next_diag ]; - next_diag += ncol + 1; - } - - (void) astFree( (void *) this->f_matrix ); - (void) astFree( (void *) this->i_matrix ); - - this->f_matrix = fmat; - this->i_matrix = InvertMatrix( DIAGONAL, nrow, ncol, fmat, status ); - this->form = DIAGONAL; - - } - -/* Calculate a new inverse matrix if necessary. */ - } else if( new_inv ) { - (void) astFree( (void *) this->i_matrix ); - this->i_matrix = InvertMatrix( FULL, nrow, ncol, this->f_matrix, status ); - } - } - - return; - -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two MatrixMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* MatrixMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two MatrixMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a MatrixMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the MatrixMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMatrixMap *that; - AstMatrixMap *this; - double *that_matrix; - double *this_matrix; - int i; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two MatrixMap structures. */ - this = (AstMatrixMap *) this_object; - that = (AstMatrixMap *) that_object; - -/* Check the second object is a MatrixMap. We know the first is a - MatrixMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAMatrixMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNout( that ) == nout && astGetNin( that ) == nin ) { - -/* Assume the MatrixMaps are equivalent. */ - result = 1; - -/* Ensure both MatrixMaps are stored in full form. */ - ExpandMatrix( this, status ); - ExpandMatrix( that, status ); - -/* Get pointers to the arrays holding the elements of the forward matrix - for both MatrixMaps. */ - if( astGetInvert( this ) ) { - this_matrix = this->i_matrix; - } else { - this_matrix = this->f_matrix; - } - - if( astGetInvert( that ) ) { - that_matrix = that->i_matrix; - } else { - that_matrix = that->f_matrix; - } - -/* If either of the above arrays is not available, try to get the inverse - matrix arrays. */ - if( !this_matrix || !that_matrix ) { - if( astGetInvert( this ) ) { - this_matrix = this->f_matrix; - } else { - this_matrix = this->i_matrix; - } - - if( astGetInvert( that ) ) { - that_matrix = that->f_matrix; - } else { - that_matrix = that->i_matrix; - } - } - -/* If both arrays are now available compare their elements. */ - if( this_matrix && that_matrix ) { - result = 1; - for( i = 0; i < nin*nout; i++ ) { - if( !astEQUAL( this_matrix[ i ], that_matrix[ i ] ) ){ - result = 0; - break; - } - } - } - -/* Ensure the supplied MatrixMaps are stored back in compressed form. */ - CompressMatrix( this, status ); - CompressMatrix( that, status ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void ExpandMatrix( AstMatrixMap *this, int *status ){ -/* -* Name: -* ExpandMatrix - -* Purpose: -* Ensure the MatrixMap is stored in full (non-compressed) form. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* void ExpandMatrix( AstMatrixMap *this, int *status ) - -* Class Membership: -* MatrixMap member function. - -* Description: -* If the supplid MatrixMap is stored in a compressed form (i.e no -* element values if it is a unit matrix, diagonal elements only -* if it is a diagonal matrix), it is expanded into a full MatrixMap -* in which all elements are stored. - -* Parameters: -* this -* A pointer to the MatrixMap to be expanded. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double *fmat; /* Pointer to full forward matrix */ - double *imat; /* Pointer to full inverse matrix */ - int i; /* Loop count */ - int ncol; /* No. of columns in forward matrix */ - int ndiag; /* No. of diagonal elements in matrix */ - int nrow; /* No. of rows in forward matrix */ - -/* Check the global error status. Also return if the MatrixMap - pointer is null. */ - if ( !astOK || !this ) return; - -/* Return without action if the MatrixMap is already in full form. */ - if( this->form == FULL ) return; - -/* Get the dimensions of the forward matrix. */ - if( astGetInvert( this ) ){ - nrow = astGetNin( this ); - ncol = astGetNout( this ); - } else { - ncol = astGetNin( this ); - nrow = astGetNout( this ); - } - -/* Store the number of diagonal elements. */ - if( nrow > ncol ){ - ndiag = ncol; - } else { - ndiag = nrow; - } - -/* Allocate arrays to hold the full forward and inverse matrices. */ - fmat = (double *) astMalloc( sizeof( double )*(size_t)( nrow*ncol ) ); - imat = (double *) astMalloc( sizeof( double )*(size_t)( nrow*ncol ) ); - if( imat && fmat ){ - -/* Fill them both with zeros. */ - for( i = 0; i < nrow*ncol; i++ ) { - fmat[ i ] = 0.0; - imat[ i ] = 0.0; - } - -/* If a unit MatrixMap was supplied, put ones on the diagonals. */ - if( this->form == UNIT ){ - for( i = 0; i < ndiag; i++ ) { - fmat[ i*( ncol + 1 ) ] = 1.0; - imat[ i*( nrow + 1 ) ] = 1.0; - } - -/* If a diagonal MatrixMap was supplied, copy the diagonal terms from - the supplied MatrixMap. */ - } else if( this->form == DIAGONAL ){ - for( i = 0; i < ndiag; i++ ) { - fmat[ i*( ncol + 1 ) ] = (this->f_matrix)[ i ]; - imat[ i*( nrow + 1 ) ] = (this->i_matrix)[ i ]; - } - } - -/* Free any existing arrays in the MatrixMap and store the new ones. */ - (void) astFree( (void *) this->f_matrix ); - (void) astFree( (void *) this->i_matrix ); - - this->f_matrix = fmat; - this->i_matrix = imat; - -/* Update the storage form. */ - this->form = FULL; - -/* If either of the new matrices could not be allocated, ensure that - both have been freed. */ - } else { - fmat = (double *) astFree( (void *) fmat ); - imat = (double *) astFree( (void *) imat ); - } - - return; - -} - -static int FindString( int n, const char *list[], const char *test, - const char *text, const char *method, - const char *class, int *status ){ -/* -* Name: -* FindString - -* Purpose: -* Find a given string within an array of character strings. - -* Type: -* Private function. - -* Synopsis: -* #include "matrix.h" -* int FindString( int n, const char *list[], const char *test, -* const char *text, const char *method, const char *class, int *status ) - -* Class Membership: -* MatrixMap method. - -* Description: -* This function identifies a supplied string within a supplied -* array of valid strings, and returns the index of the string within -* the array. The test option may not be abbreviated, but case is -* insignificant. - -* Parameters: -* n -* The number of strings in the array pointed to be "list". -* list -* A pointer to an array of legal character strings. -* test -* A candidate string. -* text -* A string giving a description of the object, parameter, -* attribute, etc, to which the test value refers. -* This is only for use in constructing error messages. It should -* start with a lower case letter. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The index of the identified string within the supplied array, starting -* at zero. - -* Notes: -* - A value of -1 is returned if an error has already occurred, or -* if this function should fail for any reason (for instance if the -* supplied option is not specified in the supplied list). - -*/ - -/* Local Variables: */ - int ret; /* The returned index */ - -/* Check global status. */ - if( !astOK ) return -1; - -/* Compare the test string with each element of the supplied list. Leave - the loop when a match is found. */ - for( ret = 0; ret < n; ret++ ) { - if( !Ustrcmp( test, list[ ret ], status ) ) break; - } - -/* Report an error if the supplied test string does not match any element - in the supplied list. */ - if( ret >= n ) { - astError( AST__RDERR, "%s(%s): Illegal value '%s' supplied for %s.", status, - method, class, test, text ); - ret = -1; - } - -/* Return the answer. */ - return ret; -} - -static int GetIsLinear( AstMapping *this_mapping, int *status ){ -/* -* Name: -* GetIsLinear - -* Purpose: -* Return the value of the IsLinear attribute for a MatrixMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GetIsLinear( AstMapping *this, int *status ) - -* Class Membership: -* MatrixMap member function (over-rides the protected astGetIsLinear -* method inherited from the Mapping class). - -* Description: -* This function returns the value of the IsLinear attribute for a -* Frame, which is always one. - -* Parameters: -* this -* Pointer to the MatrixMap. -* status -* Pointer to the inherited status variable. -*/ - return 1; -} - -static int Ustrcmp( const char *a, const char *b, int *status ){ -/* -* Name: -* Ustrncmp - -* Purpose: -* A case blind version of strcmp. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* int Ustrcmp( const char *a, const char *b ) - -* Class Membership: -* MatrixMap member function. - -* Description: -* Returns 0 if there are no differences between the two strings, and 1 -* otherwise. Comparisons are case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference between -* the two strings, whereas "strcmp" does. -* - This function attempts to execute even if an error has occurred. - -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int ret; /* Returned value */ - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Loop round each character. */ - while( 1 ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - - } - - } - -/* Return the result. */ - return ret; - -} - -void astInitMatrixMapVtab_( AstMatrixMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitMatrixMapVtab - -* Purpose: -* Initialise a virtual function table for a MatrixMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "matrixmap.h" -* void astInitMatrixMapVtab( AstMatrixMapVtab *vtab, const char *name ) - -* Class Membership: -* MatrixMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the MatrixMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAMatrixMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->MtrRot = MtrRot; - vtab->MtrMult = MtrMult; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_mapsplit = mapping->MapSplit; - mapping->MapSplit = MapSplit; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->GetIsLinear = GetIsLinear; - mapping->GetTranForward = GetTranForward; - mapping->GetTranInverse = GetTranInverse; - mapping->MapMerge = MapMerge; - mapping->Rate = Rate; - -/* Declare the destructor and copy constructor. */ - astSetDelete( (AstObjectVtab *) vtab, Delete ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - -/* Declare the class dump function. */ - astSetDump( vtab, Dump, "MatrixMap", "Matrix transformation" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - - -static double *InvertMatrix( int form, int nrow, int ncol, double *matrix, int *status ){ -/* -* Name: -* InvertMatrix - -* Purpose: -* Invert a suplied matrix. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* double *InvertMatrix( int form, int nrow, int ncol, double *matrix, int *status ) - -* Class Membership: -* MatrixMap member function. - -* Description: -* This function returns a pointer to a matrix holding the inverse of -* the supplied matrix, or a NULL pointer if the inverse is not defined. -* The memory to store the inverse matrix is allocated internally, and -* should be freed using astFree when no longer required. -* -* The correspondence between a full matrix and its inverse is only -* unique if the matrix is square, and so a NULL pointer is returned if -* the supplied matrix is not square. - -* Parameters: -* form -* The form of the MatrixMap; UNIT, DIAGONAL or FULL. -* nrow -* Number of rows in the supplied matrix. -* ncol -* Number of columns in the supplied matrix. -* matrix -* A pointer to the input matrix. Elements should be stored in row -* order (i.e. (row 1,column 1 ), (row 1,column 2 )... (row 2,column 1), -* etc). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output matrix. - -* Notes: -* - A NULL pointer is returned if a unit matrix is supplied. -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - No error is reported if the inverse is not defined. -*/ - -/* Local Variables: */ - double det; /* Determinant of supplied matrix */ - double mval; /* Matrix element value */ - double *out; /* Pointer to returned inverse matrix */ - double *vector; /* Pointer to vector used by palDmat */ - int i; /* Matrix element number */ - int *iw; /* Pointer to workspace used by palDmat */ - int nel; /* No. of elements in square matrix */ - int ndiag; /* No. of diagonal elements */ - int ok; /* Zero if any bad matrix values found */ - int sing; /* Zero if matrix is not singular */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Return a NULL pointer if the input matrix is NULL. */ - if( !matrix ) return NULL; - -/* If a unit matrix map has been supplied, return NULL. */ - if( form == UNIT ){ - return NULL; - -/* If a diagonal matrix has been supplied, allocate an array to hold - the diagonal terms of the inverse matrix. Store the reciprocal - of the input matrix diagonal terms in it. If any of the input diagonal - terms are zero or BAD, set the associated elements of the inverse matrix - BAD. */ - } else if( form == DIAGONAL ){ - if( nrow > ncol ) { - ndiag = ncol; - } else { - ndiag = nrow; - } - - out = (double *) astMalloc( sizeof( double )*(size_t)ndiag ); - - if( out ) { - for( i = 0; i < ndiag; i++ ) { - mval = matrix[ i ]; - if( mval != 0.0 && mval != AST__BAD ){ - out[ i ] = 1.0/mval; - } else { - out[ i ] = AST__BAD; - } - } - } - -/* If a full matrix has been supplied, initialise the returned pointer. */ - } else { - out = NULL; - -/* Check that the matrix is square. */ - if( nrow == ncol ){ - -/* Find the number of elements in the matrix. */ - nel = nrow*ncol; - -/* See if there are any bad values in the matrix. */ - ok = 1; - for ( i=0; iform == UNIT && nin == nout ){ - map2 = (AstMapping *) astUnitMap( nin, "", status ); - -/* If the MatrixMap is a square diagonal matrix with equal diagonal - terms, then it can be replaced by a ZoomMap, so long as the - diagonal elements are not all zero. */ - } else if( mm->form == DIAGONAL && nin == nout && - mm->f_matrix && mm->i_matrix && - (mm->f_matrix)[ 0 ] != AST__BAD ){ - zoom = 1; - b = mm->f_matrix + 1; - for( i = 1; i < nin; i++ ){ - if( !astEQUAL( *b, *( b - 1 ) ) ){ - zoom = 0; - break; - } - b++; - } - - if( zoom ){ - if( ( *invert_list )[ where ] ){ - factor = (mm->i_matrix)[ 0 ]; - } else { - factor = (mm->f_matrix)[ 0 ]; - } - - if( factor != 0.0 ){ - map2 = (AstMapping *) astZoomMap( nin, factor, "", status ); - } - } - -/* If the MatrixMap is a full matrix but all off-diagonal elements are - zero, it can be replaced by a diagonal MatrixMap. */ - } else if( mm->form == FULL && nin == nout && mm->f_matrix ){ - new_mat = astMalloc( sizeof( double )*nin ); - b = mm->f_matrix; - for( i = 0; i < nin && new_mat; i++ ){ - for( j = 0; j < nout; j++,b++ ){ - if( i == j ) { - new_mat[ i ] = *b; - } else if( *b != 0.0 ) { - new_mat = astFree( new_mat ); - break; - } - } - } - - if( new_mat ) { - map2 = (AstMapping *) astMatrixMap( nin, nout, 1, new_mat, "", - status ); - new_mat = astFree( new_mat ); - } - } - -/* If the MatrixMap can be replaced, annul the MatrixMap pointer in the - list and replace it with the new Mapping pointer, and indicate that the - forward transformation of the returned Mapping should be used. */ - if( map2 ){ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = map2; - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - -/* If the MatrixMap itself could not be simplified, see if it can be merged - with the Mappings on either side of it in the list. */ -/*==========================================================================*/ - } else { - -/* Store the classes of the neighbouring Mappings in the list. */ - class1 = ( where > 0 ) ? astGetClass( ( *map_list )[ where - 1 ] ) : NULL; - class2 = ( where < *nmap - 1 ) ? astGetClass( ( *map_list )[ where + 1 ] ) : NULL; - -/* In series. */ -/* ========== */ - if ( series ) { - -/* We first look to see if the MatrixMap can be merged with one of its - neighbours, resulting in a reduction of one in the number of Mappings - in the list. MatrixMaps can merge directly with another MatrixMap, a - ZoomMap, an invertable PermMap, or a UnitMap. */ - if( class1 && ( !strcmp( class1, "MatrixMap" ) || - !strcmp( class1, "ZoomMap" ) || - !strcmp( class1, "PermMap" ) || - !strcmp( class1, "UnitMap" ) ) ){ - nclass = class1; - i1 = where - 1; - i2 = where; - - } else if( class2 && ( !strcmp( class2, "MatrixMap" ) || - !strcmp( class2, "ZoomMap" ) || - !strcmp( class2, "PermMap" ) || - !strcmp( class2, "UnitMap" ) ) ){ - nclass = class2; - i1 = where; - i2 = where + 1; - - } else { - nclass = NULL; - } - -/* Only some PermMaps can be merged with (those which have consistent - forward and inverse mappings). If this is not one of them, set nclass - NULL to indicate this. */ - if( nclass && !strcmp( nclass, "PermMap" ) && - !PermOK( ( *map_list )[ (i1==where)?i2:i1 ], status ) ) nclass = NULL; - -/* If the MatrixMap is diagonal it can also merge with a WinMap. */ - if( !nclass && mm->form == DIAGONAL) { - if( class1 && ( !strcmp( class1, "WinMap" ) ) ){ - nclass = class1; - i1 = where - 1; - i2 = where; - - } else if( class2 && ( !strcmp( class2, "WinMap" ) ) ){ - nclass = class2; - i1 = where; - i2 = where + 1; - - } - } - -/* If the MatrixMap can merge with one of its neighbours, create the merged - Mapping. */ - if( nclass ){ - - if( !strcmp( nclass, "MatrixMap" ) ){ - newmap = (AstMapping *) MatMat( ( *map_list )[ i1 ], ( *map_list )[ i2 ], - ( *invert_list )[ i1 ], ( *invert_list )[ i2 ], status ); - invert = 0; - - } else if( !strcmp( nclass, "ZoomMap" ) ){ - if( i1 == where ){ - newmap = (AstMapping *) MatZoom( (AstMatrixMap *)( *map_list )[ i1 ], - (AstZoomMap *)( *map_list )[ i2 ], - ( *invert_list )[ i1 ], ( *invert_list )[ i2 ], status ); - } else { - newmap = (AstMapping *) MatZoom( (AstMatrixMap *)( *map_list )[ i2 ], - (AstZoomMap *)( *map_list )[ i1 ], - ( *invert_list )[ i2 ], ( *invert_list )[ i1 ], status ); - } - invert = 0; - - } else if( !strcmp( nclass, "PermMap" ) ){ - if( i1 == where ){ - newmap = (AstMapping *) MatPerm( (AstMatrixMap *)( *map_list )[ i1 ], - (AstPermMap *)( *map_list )[ i2 ], - ( *invert_list )[ i1 ], ( *invert_list )[ i2 ], 1, status ); - } else { - newmap = (AstMapping *) MatPerm( (AstMatrixMap *)( *map_list )[ i2 ], - (AstPermMap *)( *map_list )[ i1 ], - ( *invert_list )[ i2 ], ( *invert_list )[ i1 ], 0, status ); - } - invert = 0; - - } else if( !strcmp( nclass, "WinMap" ) ){ - if( i1 == where ){ - newmap = (AstMapping *) MatWin2( (AstMatrixMap *)( *map_list )[ i1 ], - (AstWinMap *)( *map_list )[ i2 ], - ( *invert_list )[ i1 ], ( *invert_list )[ i2 ], 1, status ); - } else { - newmap = (AstMapping *) MatWin2( (AstMatrixMap *)( *map_list )[ i2 ], - (AstWinMap *)( *map_list )[ i1 ], - ( *invert_list )[ i2 ], ( *invert_list )[ i1 ], 0, status ); - } - invert = 0; - - } else { - newmap = astClone( ( *map_list )[ where ] ); - invert = ( *invert_list )[ where ]; - } - -/* If succesfull... */ - if( astOK ){ - -/* Annul the first of the two Mappings, and replace it with the merged - MatrixMap. Also set the invert flag. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - ( *map_list )[ i1 ] = newmap; - ( *invert_list )[ i1 ] = invert; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ i2 ] ); - for ( i = i2 + 1; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = i1; - - } - -/* If the MatrixMap could not merge directly with either of its neighbours, - we consider whether it would be worthwhile to swap the MatrixMap with - either of its neighbours. This can only be done for certain classes - of Mapping (WinMaps and some PermMaps), and will usually require both - Mappings to be modified (unless they are commutative). The advantage of - swapping the order of the Mappings is that it may result in the MatrixMap - being adjacent to a Mapping with which it can merge directly on the next - invocation of this function, thus reducing the number of Mappings - in the list. */ - } else { - -/* Set a flag if we could swap the MatrixMap with its higher neighbour. "do2" - is returned if swapping the Mappings would simplify either of the Mappings. */ - if( where + 1 < *nmap ){ - swaphi = CanSwap( ( *map_list )[ where ], - ( *map_list )[ where + 1 ], - ( *invert_list )[ where ], - ( *invert_list )[ where + 1 ], &do2, status ); - } else { - swaphi = 0; - do2 = 0; - } - -/* If so, step through each of the Mappings which follow the MatrixMap, - looking for a Mapping with which the MatrixMap could merge directly. Stop - when such a Mapping is found, or if a Mapping is found with which the - MatrixMap could definitely not swap. Note the number of Mappings which - separate the MatrixMap from the Mapping with which it could merge (if - any). */ - nstep2 = -1; - if( swaphi ){ - for( i2 = where + 1; i2 < *nmap; i2++ ){ - -/* See if we can merge with this Mapping. If so, note the number of steps - between the two Mappings and leave the loop. */ - nclass = astGetClass( ( *map_list )[ i2 ] ); - if( !strcmp( nclass, "MatrixMap" ) || - !strcmp( nclass, "ZoomMap" ) || - ( !strcmp( nclass, "PermMap" ) && PermOK( ( *map_list )[ i2 ], status ) ) || - !strcmp( nclass, "UnitMap" ) ) { - nstep2 = i2 - where - 1; - break; - } - -/* If there is no chance that we can swap with this Mapping, leave the loop - with -1 for the number of steps to indicate that no merging is possible. - MatrixMaps can swap with WinMaps and some permmaps. */ - if( strcmp( nclass, "WinMap" ) && - strcmp( nclass, "PermMap" ) ) { - break; - } - - } - - } - -/* Do the same working forward from the MatrixMap towards the start of the map - list. */ - if( where > 0 ){ - swaplo = CanSwap( ( *map_list )[ where - 1 ], - ( *map_list )[ where ], - ( *invert_list )[ where - 1 ], - ( *invert_list )[ where ], &do1, status ); - } else { - swaplo = 0; - do1 = 0; - } - - nstep1 = -1; - if( swaplo ){ - for( i1 = where - 1; i1 >= 0; i1-- ){ - - nclass = astGetClass( ( *map_list )[ i1 ] ); - if( !strcmp( nclass, "MatrixMap" ) || - ( !strcmp( nclass, "PermMap" ) && PermOK( ( *map_list )[ i1 ], status ) ) || - !strcmp( nclass, "ZoomMap" ) || - !strcmp( nclass, "UnitMap" ) ) { - nstep1 = where - 1 - i1; - break; - } - - if( strcmp( nclass, "WinMap" ) && - strcmp( nclass, "PermMap" ) ) { - break; - } - - } - - } - -/* Choose which neighbour to swap with so that the MatrixMap moves towards the - nearest Mapping with which it can merge. */ - if( do1 || ( - nstep1 != -1 && ( nstep2 == -1 || nstep2 > nstep1 ) ) ){ - nclass = class1; - i1 = where - 1; - i2 = where; - } else if( do2 || nstep2 != -1 ){ - nclass = class2; - i1 = where; - i2 = where + 1; - } else { - nclass = NULL; - } - -/* If there is a target Mapping in the list with which the MatrixMap could - merge, consider replacing the supplied Mappings with swapped Mappings to - bring the MatrixMap closer to the target Mapping. */ - if( nclass ){ - -/* Swap the Mappings. */ - if (!strcmp( nclass, "WinMap" ) ){ - MatWin( (*map_list) + i1, (*invert_list) + i1, where - i1, status ); - - } else if( !strcmp( nclass, "PermMap" ) ){ - MatPermSwap( (*map_list) + i1, (*invert_list) + i1, where - i1, status ); - } - -/* And then merge them. */ - if( where == i1 && where + 1 < *nmap ) { /* Merging upwards */ - map2 = astClone( (*map_list)[ where + 1 ] ); - nmapt = *nmap - where - 1; - maplt = *map_list + where + 1; - invlt = *invert_list + where + 1; - - (void) astMapMerge( map2, 0, series, &nmapt, &maplt, &invlt ); - map2 = astAnnul( map2 ); - *nmap = where + 1 + nmapt; - - } else if( where - 2 >= 0 ) { /* Merging downwards */ - map2 = astClone( (*map_list)[ where - 2 ] ); - nmapt = *nmap - where + 2; - maplt = *map_list + where - 2 ; - invlt = *invert_list + where - 2; - - (void) astMapMerge( map2, 0, series, &nmapt, &maplt, &invlt ); - map2 = astAnnul( map2 ); - *nmap = where - 2 + nmapt; - } - - result = i1; - -/* If there is no Mapping available for merging, it may still be - advantageous to swap with a neighbour because the swapped Mapping may - be simpler than the original Mappings. For instance, a PermMap may - strip rows of the MatrixMap leaving only a UnitMap. */ - } else if( swaphi || swaplo ) { - -/* Try swapping with each possible neighbour in turn. */ - for( i = 0; i < 2; i++ ) { - -/* Set up the class and pointers for the mappings to be swapped, first - the lower neighbour, then the upper neighbour. */ - if( i == 0 && swaplo ){ - nclass = class1; - i1 = where - 1; - i2 = where; - - } else if( i == 1 && swaphi ){ - nclass = class2; - i1 = where; - i2 = where + 1; - - } else { - nclass = NULL; - } - -/* If we have a Mapping to swap with... */ - if( nclass ) { - -/* Take copies of the Mapping and Invert flag arrays so we do not change - the supplied values. */ - mc[ 0 ] = (AstMapping *) astCopy( ( (*map_list) + i1 )[0] ); - mc[ 1 ] = (AstMapping *) astCopy( ( (*map_list) + i1 )[1] ); - ic[ 0 ] = ( (*invert_list) + i1 )[0]; - ic[ 1 ] = ( (*invert_list) + i1 )[1]; - -/* Swap these Mappings. */ - if( !strcmp( nclass, "WinMap" ) ){ - MatWin( mc, ic, where - i1, status ); - } else if( !strcmp( nclass, "PermMap" ) ){ - MatPermSwap( mc, ic, where - i1, status ); - } - -/* If neither of the swapped Mappings can be simplified further, then there - is no point in swapping the Mappings, so just annul the map copies. */ - smc0 = astSimplify( mc[0] ); - smc1 = astSimplify( mc[1] ); - - if( astGetClass( smc0 ) == astGetClass( mc[0] ) && - astGetClass( smc1 ) == astGetClass( mc[1] ) ) { - - mc[ 0 ] = (AstMapping *) astAnnul( mc[ 0 ] ); - mc[ 1 ] = (AstMapping *) astAnnul( mc[ 1 ] ); - -/* If one or both of the swapped Mappings could be simplified, then annul - the supplied Mappings and return the swapped mappings, storing the index - of the first modified Mapping. */ - } else { - (void ) astAnnul( ( (*map_list) + i1 )[0] ); - (void ) astAnnul( ( (*map_list) + i1 )[1] ); - - ( (*map_list) + i1 )[0] = mc[ 0 ]; - ( (*map_list) + i1 )[1] = mc[ 1 ]; - - ( (*invert_list) + i1 )[0] = ic[ 0 ]; - ( (*invert_list) + i1 )[1] = ic[ 1 ]; - - result = i1; - break; - } - -/* Annul the simplied Mappings */ - smc0 = astAnnul( smc0 ); - smc1 = astAnnul( smc1 ); - - } - } - } - } - } - } - -/* Return the result. */ - return result; -} - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* MatrixMap. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* MatrixMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing MatrixMap. This is only possible if the specified inputs -* correspond to some subset of the MatrixMap outputs. That is, there -* must exist a subset of the MatrixMap outputs for which each output -* depends only on the selected MatrixMap inputs, and not on any of the -* inputs which have not been selected. In addition, outputs that are -* not in this subset must not depend on any selected inputs. If these -* conditions are not met by the supplied MatrixMap, then a NULL Mapping -* is returned. - -* Parameters: -* this -* Pointer to the MatrixMap to be split (the MatrixMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied MatrixMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied MatrixMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied MatrixMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstMatrixMap *this; /* Pointer to MatrixMap structure */ - double *mat; /* Pointer to matrix for supplied MatrixMap */ - double *pmat; /* Pointer to row start in returned matrix */ - double *prow; /* Pointer to row start in supplied matrix */ - double *rmat; /* Pointer to matrix for returned MatrixMap */ - double el; /* Next element value in supplied matrix */ - int *result; /* Pointer to returned array */ - int good; /* Would new matrix contain any good values/ */ - int i; /* Loop count */ - int icol; /* Column index within supplied MatrixMap */ - int iel; /* Index of next element from the input matrix */ - int irow; /* Row index within supplied MatrixMap */ - int isel; /* Does output depend on any selected inputs? */ - int ncol; /* Number of columns (inputs) in supplied MatrixMap */ - int nout; /* Number of outputs in returned MatrixMap */ - int nrow; /* Number of rows (outputs) in supplied MatrixMap */ - int ok; /* Are input indices OK? */ - int sel; /* Does any output depend on selected inputs? */ - int unsel; /* Does any output depend on unselected inputs? */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the parent astMapSplit method to see if it can do the job. */ - result = (*parent_mapsplit)( this_map, nin, in, map, status ); - -/* If not, we provide a special implementation here. */ - if( !result ) { - -/* Get a pointer to the MatrixMap structure. */ - this = (AstMatrixMap *) this_map; - -/* Get the number of inputs and outputs. */ - ncol = astGetNin( this ); - nrow = astGetNout( this ); - -/* Check the supplied input indices are usable. */ - ok = 1; - for( i = 0; i < nin; i++ ) { - if( in[ i ] < 0 || in[ i ] >= ncol ) { - ok = 0; - break; - } - } - - if( ok ) { - -/* Ensure the MatrixMap is stored in full form. */ - ExpandMatrix( this, status ); - -/* Allocate the largest array that could be necessary to hold the - returned array of Mapping outputs. */ - result = astMalloc( sizeof(int)*(size_t) nrow ); - -/* Allocate the largest array that could be necessary to hold the - matrix representing the returned MatrixMap. */ - rmat = astMalloc( sizeof(double)*(size_t) (nrow*ncol) ); - -/* Get the matrix which defines the current forward transformation. This - takes into account whether the MatrixMap has been inverted or not. */ - if( astGetInvert( this ) ) { - mat = this->i_matrix; - } else { - mat = this->f_matrix; - } - -/* We cannot create the require Mapping if the matrix is undefined. */ - if( !mat || !astOK ) { - ok = 0; - nout = 0; - good = 0; - -/* Otherwise, loop round all the rows in the matrix. */ - } else { - nout = 0; - good = 0; - pmat = rmat; - iel = 0; - for( irow = 0; irow < nrow; irow++ ) { - -/* Indicate that this output (i.e. row of the matrix) depends on neither - selected nor unselected inputs as yet. */ - sel = 0; - unsel = 0; - -/* Save a pointer to the first element of this row in the MatrixMap - matrix. */ - prow = mat + iel; - -/* Loop round all the elements in the current row of the matrix. */ - for( icol = 0; icol < ncol; icol++ ) { - -/* If this element is non-zero and non-bad, then output "irow" depends on - input "icol". */ - el = mat[ iel++ ]; - if( el != 0.0 && el != AST__BAD ) { - -/* Is input "icol" one of the selected inputs? */ - isel = 0; - for( i = 0; i < nin; i++ ) { - if( in[ i ] == icol ) { - isel = 1; - break; - } - } - -/* If so, note that this output depends on selected inputs. Otherwise note - it depends on unselected inputs. */ - if( isel ) { - sel = 1; - } else { - unsel = 1; - } - } - } - -/* If this output depends only on selected inputs, we can include it in - the returned Mapping.*/ - if( sel && !unsel ) { - -/* Store the index of the output within the original MatrixMap. */ - result[ nout ] = irow; - -/* Increment the number of outputs in the returned Mapping. */ - nout++; - -/* Copy the elements of the current matrix row which correspond to the - selected inputs into the new matrix. */ - for( i = 0; i < nin; i++ ) { - if( astISGOOD( prow[ in[ i ] ] ) ) { - *(pmat++) = prow[ in[ i ] ]; - good = 1; - } - } - } - -/* If this output depends on a selected input, but also depends on an - unselected input, we cannot split the MatrixMap. */ - if( sel && unsel ) { - ok = 0; - break; - } - } - } - - -/* If the returned Mapping can be created, create it. */ - if( ok && nout > 0 && good ) { - *map = (AstMapping *) astMatrixMap( nin, nout, 0, rmat, "", status ); - -/* Otherwise, free the returned array. */ - } else { - result = astFree( result ); - } - -/* Free resources. */ - rmat = astFree( rmat ); - -/* Re-compress the supplied MatrixMap. */ - CompressMatrix( this, status ); - } - } - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static AstMatrixMap *MatMat( AstMapping *map1, AstMapping *map2, int inv1, - int inv2, int *status ){ -/* -* Name: -* MatMat - -* Purpose: -* Create a merged MatrixMap from two supplied MatrixMaps. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* AstMatrixMap *MatMat( AstMapping *map1, AstMapping *map2, int inv1, -* int inv2, int *status ) - -* Class Membership: -* MatrixMap member function - -* Description: -* This function creates a new MatrixMap which performs a mapping -* equivalent to applying the two supplied MatrixMaps in series, in the -* directions specified by the "invert" flags (the Invert attributes of -* the supplied MatrixMaps are ignored). - -* Parameters: -* map1 -* A pointer to the MatrixMap to apply first. -* map2 -* A pointer to the MatrixMap to apply second. -* inv1 -* The invert flag to use with map1. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* inv2 -* The invert flag to use with map2. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new MatrixMap. - -* Notes: -* - The forward direction of the returned MatrixMap is equivalent to the -* combined effect of the two supplied MatrixMap, operating in the -* directions specified by "inv1" and "inv2". -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMatrixMap *result; /* Pointer to output MatrixMap */ - int invert[ 2 ]; /* Original invert flags */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the returned pointer. */ - result = NULL; - -/* Temporarily set their Invert attributes to the supplied values. */ - invert[ 0 ] = astGetInvert( map1 ); - astSetInvert( map1, inv1 ); - - invert[ 1 ] = astGetInvert( map2 ); - astSetInvert( map2, inv2 ); - -/* Create a new MatrixMap by multiplying them together. */ - result = astMtrMult( (AstMatrixMap *) map1, (AstMatrixMap *) map2 ); - -/* Re-instate the original settings of the Invert attributes for the - supplied MatrixMaps. */ - astSetInvert( map1, invert[ 0 ] ); - astSetInvert( map2, invert[ 1 ] ); - -/* If an error has occurred, annull the returned MatrixMap. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output MatrixMap. */ - return result; -} - -static AstMatrixMap *MatPerm( AstMatrixMap *mm, AstPermMap *pm, int minv, - int pinv, int mat1, int *status ){ -/* -* Name: -* MatPerm - -* Purpose: -* Create a MatrixMap by merging a MatrixMap and a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* AstMatrixMap *MatPerm( AstMatrixMap *mm, AstPermMap *pm, int minv, -* int pinv, int mat1, int *status ) - -* Class Membership: -* MatrixMap member function - -* Description: -* This function creates a new MatrixMap which performs a mapping -* equivalent to applying the two supplied Mappings in series in the -* directions specified by the "invert" flags (the Invert attributes of -* the supplied MatrixMaps are ignored). - -* Parameters: -* mm -* A pointer to the MatrixMap. -* pm -* A pointer to the PermMap. -* minv -* The invert flag to use with mm. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* pinv -* The invert flag to use with pm. -* mat1 -* If non-zero, then "mm" is applied first followed by "pm". Otherwise, -* "pm" is applied first followed by "mm". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new MatrixMap. - -* Notes: -* - The forward direction of the returned MatrixMap is equivalent to the -* combined effect of the two supplied Mappings, operating in the -* directions specified by "pinv" and "minv". -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMatrixMap *mm2; /* Pointer to an intermediate MatrixMap */ - AstMatrixMap *result; /* Pointer to output MatrixMap */ - AstPointSet *pset1; /* Pointer to a PointSet holding unpermuted unit vectors */ - AstPointSet *pset2; /* Pointer to a PointSet holding permuted unit vectors */ - double *matrix; /* Pointer to a matrix representing the PermMap */ - double *p; /* Pointer to next matrix element */ - double **ptr1; /* Pointer to the data in pset1 */ - double **ptr2; /* Pointer to the data in pset2 */ - int i; /* Axis index */ - int j; /* Point index */ - int nax; /* No. of axes in the PermMap */ - int old_minv; /* Original setting of MatrixMap Invert attribute */ - int old_pinv; /* Original setting of PermMap Invert attribute */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the returned pointer. */ - result = NULL; - -/* Temporarily set the Invert attributes of both Mappings to the supplied - values. */ - old_minv = astGetInvert( mm ); - astSetInvert( mm, minv ); - - old_pinv = astGetInvert( pm ); - astSetInvert( pm, pinv ); - -/* Get the number of axes in the PermMap. The PermMap will have the same - number of input and output axes because a check has already been made on - it to ensure that this is so (in function PermOK). */ - nax = astGetNin( pm ); - -/* We first represent the PermMap as a MatrixMap containing elements with - values zero or one. Each row of this matrix is obtained by transforming a - unit vector along each axis using the inverse PermMap. Allocate memory - to hold the matrix array, and create a PointSet holding the unit - vectors. */ - matrix = (double *) astMalloc( sizeof( double )*(size_t)( nax*nax ) ); - - pset1 = astPointSet( nax, nax, "", status ); - ptr1 = astGetPoints( pset1 ); - - pset2 = astPointSet( nax, nax, "", status ); - ptr2 = astGetPoints( pset2 ); - - if( astOK ){ - for( i = 0; i < nax; i++ ){ - for( j = 0; j < nax; j++ ) ptr1[ i ][ j ] = 0.0; - ptr1[ i ][ i ] = 1.0; - } - -/* Transform these unit vectors using the inverse PermMap. */ - (void) astTransform( pm, pset1, 0, pset2 ); - -/* Copy the transformed vectors into the matrix array. */ - p = matrix; - for( j = 0; j < nax; j++ ){ - for( i = 0; i < nax; i++ ) *(p++) = ptr2[ i ][ j ]; - } - -/* Create a MatrixMap holding this array. */ - mm2 = astMatrixMap( nax, nax, 0, matrix, "", status ); - -/* Create a new MatrixMap equal to the product of the supplied MatrixMap - and the MatrixMap just created from the PermMap. */ - if( mat1 ){ - result = astMtrMult( mm, mm2 ); - } else { - result = astMtrMult( mm2, mm ); - } - -/* Free everything. */ - mm2 = astAnnul( mm2 ) ; - } - - pset2 = astAnnul( pset2 ); - pset1 = astAnnul( pset1 ); - matrix = (double *) astFree( (void *) matrix ); - -/* Re-instate the original settings of the Invert attribute for the - supplied Mappings. */ - astSetInvert( mm, old_minv ); - astSetInvert( pm, old_pinv ); - -/* If an error has occurred, annull the returned MatrixMap. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output MatrixMap. */ - return result; -} - -static void MatPermSwap( AstMapping **maps, int *inverts, int imm, int *status ){ -/* -* Name: -* MatPermSwap - -* Purpose: -* Swap a PermMap and a MatrixMap. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* void MatPermSwap( AstMapping **maps, int *inverts, int imm ) - -* Class Membership: -* MatrixMap member function - -* Description: -* A list of two Mappings is supplied containing a PermMap and a -* MatrixMap. These Mappings are annulled, and replaced with -* another pair of Mappings consisting of a PermMap and a MatrixMap -* in the opposite order. These Mappings are chosen so that their -* combined effect is the same as the original pair of Mappings. - -* Parameters: -* maps -* A pointer to an array of two Mapping pointers. -* inverts -* A pointer to an array of two invert flags. -* imm -* The index within "maps" of the MatrixMap. - -* Notes: -* - There are restictions on the sorts of PermMaps which can be -* swapped with a MatrixMap -- see function CanSwap. It is assumed -* that the supplied MatrixMap and PermMap satisfy these requirements. - -*/ - -/* Local Variables: */ - AstMatrixMap *mm; /* Pointer to the supplied MatrixMap */ - AstMatrixMap *mmnew; /* Pointer to new MatrixMap */ - AstMatrixMap *smmnew; /* Pointer to new simplified MatrixMap */ - AstPermMap *pm; /* Pointer to the supplied PermMap */ - AstPermMap *pmnew; /* Pointer to new PermMap */ - AstPermMap *spmnew; /* Pointer to new simplified PermMap */ - double *consts; /* Pointer to constants array */ - double *matrix; /* Supplied array of matrix elements */ - double *out_el; /* Pointer to next element of new MatrixMap */ - double *out_mat; /* Matrix elements for new MatrixMap */ - double c; /* Constant */ - double matel; /* Matrix element */ - int *inperm; /* Pointer to input axis permutation array */ - int *outperm; /* Pointer to output axis permutation array */ - int col; /* Index of matrix column */ - int i; /* Axis count */ - int k; /* Axis count */ - int nin; /* No. of axes in supplied PermMap */ - int nout; /* No. of axes in returned PermMap */ - int old_pinv; /* Invert value for the supplied PermMap */ - int row; /* Index of matrix row */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - mmnew = NULL; - pmnew = NULL; - -/* Store pointers to the supplied PermMap and the MatrixMap. */ - pm = (AstPermMap *) maps[ 1 - imm ]; - mm = (AstMatrixMap *) maps[ imm ]; - -/* Temporarily set the Invert attribute of the supplied PermMap to the - supplied value. */ - old_pinv = astGetInvert( pm ); - astSetInvert( pm, inverts[ 1 - imm ] ); - -/* Ensure the MatrixMap is stored in full form. */ - ExpandMatrix( mm, status ); - -/* Store a pointer to the required array of matrix elements. */ - if( inverts[ imm ] ) { - matrix = mm->i_matrix; - } else { - matrix = mm->f_matrix; - } - -/* Get the number of input and output axes of the PermMap. */ - nin = astGetNin( pm ); - nout = astGetNout( pm ); - -/* Allocate memory to hold the matrix elements for the swapped MatrixMap. - The number of rows and olumns in the new matrix must equal the number of - input or output axes for the PermMap, depending on whether the PermMap - or MatrixMap is applied first. */ - if( imm == 0 ) { - out_mat = (double *) astMalloc( sizeof( double )*(size_t)( nout*nout ) ); - } else { - out_mat = (double *) astMalloc( sizeof( double )*(size_t)( nin*nin ) ); - } - -/* We need to know the axis permutation arrays and constants array for - the PermMap. */ - PermGet( pm, &outperm, &inperm, &consts, status ); - if( astOK ) { - -/* First deal with cases where the MatrixMap is applied first. */ - if( imm == 0 ) { - -/* Consider each output axis of the PermMap. */ - for( i = 0; i < nout; i++ ) { - -/* If this output is connected to one of the input axes... */ - row = outperm[ i ]; - if( row >= 0 && row < nin ) { - -/* Permute the row of the supplied matrix which feeds the corresponding - PermMap input axis (i.e. axis outperm[k] ) using the forward PermMap. - Store zeros for any output axes which are assigned constants. This forms - row i of the new MatrixMap. */ - out_el = out_mat + nout*i; - for( k = 0; k < nout; k++ ){ - col = outperm[ k ]; - if( col >= 0 && col < nin ) { - *(out_el++) = *( matrix + nin*row + col ); - } else { - *(out_el++) = 0.0; - } - } - -/* If this output is asigned a constant value, use a "diagonal" vector for - row i of the new MatrixMap (i.e. all zeros except for a 1.0 in column - i ). */ - } else { - out_el = out_mat + nout*i; - for( k = 0; k < nout; k++ ) { - if( k != i ) { - *(out_el++) = 0.0; - } else { - *(out_el++) = 1.0; - } - } - } - } - -/* Create the new MatrixMap. */ - mmnew = astMatrixMap( nout, nout, 0, out_mat, "", status ); - -/* Any PermMap inputs which are assigned a constant value need to be - changed now, since they will no longer be scaled by the inverse - MatrixMap. CanSwap ensures that the inverse MatrixMap produces a - simple scaling for constant axes, so we change the PermMap constant - to be the constant AFTER scaling by the inverse MatrixMap. - - Consider each input axis of the PermMap. */ - for( i = 0; i < nin; i++ ) { - -/* If this input is assigned a constant value... */ - if( inperm[ i ] < 0 ) { - -/* Divide the supplied constant value by the corresponding diagonal term - in the supplied MatrixMap. */ - c = consts[ -inperm[ i ] - 1 ]; - if( c != AST__BAD ) { - matel = matrix[ i*( nin + 1 ) ]; - if( matel != 0.0 && matel != AST__BAD ) { - consts[ -inperm[ i ] - 1 ] /= matel; - } else { - consts[ -inperm[ i ] - 1 ] = AST__BAD; - } - } - } - } - -/* Now deal with cases where the PermMap is applied first. */ - } else { - -/* Consider each input axis of the PermMap. */ - for( i = 0; i < nin; i++ ) { - -/* If this input is connected to one of the output axes... */ - row = inperm[ i ]; - if( row >= 0 && row < nout ) { - -/* Permute the row of the supplied matrix which feeds the corresponding - PermMap output axis (i.e. axis inperm[k] ) using the inverse PermMap. - Store zeros for any input axes which are assigned constants. This forms - row i of the new MatrixMap. */ - out_el = out_mat + nin*i; - for( k = 0; k < nin; k++ ){ - col = inperm[ k ]; - if( col >= 0 && col < nout ) { - *(out_el++) = *( matrix + nout*row + col ); - } else { - *(out_el++) = 0.0; - } - } - -/* If this input is asigned a constant value, use a "diagonal" vector for - row i of the new MatrixMap (i.e. all zeros except for a 1.0 in column - i ). */ - } else { - out_el = out_mat + nin*i; - for( k = 0; k < nin; k++ ) { - if( k != i ) { - *(out_el++) = 0.0; - } else { - *(out_el++) = 1.0; - } - } - } - } - -/* Create the new MatrixMap. */ - mmnew = astMatrixMap( nin, nin, 0, out_mat, "", status ); - -/* Any PermMap outputs which are assigned a constant value need to be - changed now, since they will no longer be scaled by the forward - MatrixMap. CanSwap ensures that the forward MatrixMap produces a - simple scaling for constant axes, so we change the PermMap constant - to be the constant AFTER scaling by the forward MatrixMap. - - Consider each output axis of the PermMap. */ - for( i = 0; i < nout; i++ ) { - -/* If this output is assigned a constant value... */ - if( outperm[ i ] < 0 ) { - -/* Multiple the supplied constant value by the corresponding diagonal term in - the supplied MatrixMap. */ - c = consts[ -outperm[ i ] - 1 ]; - if( c != AST__BAD ) { - matel = matrix[ i*( nout + 1 ) ]; - if( matel != AST__BAD ) { - consts[ -outperm[ i ] - 1 ] *= matel; - } else { - consts[ -outperm[ i ] - 1 ] = AST__BAD; - } - } - } - } - } - -/* Create a new PermMap (since the constants may have changed). */ - pmnew = astPermMap( nin, inperm, nout, outperm, consts, "", status ); - -/* Free the axis permutation and constants arrays. */ - outperm = (int *) astFree( (void *) outperm ); - inperm = (int *) astFree( (void *) inperm ); - consts = (double *) astFree( (void *) consts ); - } - -/* Free the memory used to hold the new matrix elements. */ - out_mat = (double *) astFree( (void *) out_mat ); - -/* Ensure the supplied MatrixMap is stored back in compressed form. */ - CompressMatrix( mm, status ); - -/* Re-instate the original value of the Invert attribute of the supplied - PermMap. */ - astSetInvert( pm, old_pinv ); - - if( astOK ) { - -/* Annul the supplied PermMap. */ - (void) astAnnul( pm ); - -/* Simplify the returned Mappings. */ - spmnew = astSimplify( pmnew ); - pmnew = astAnnul( pmnew ); - - smmnew = astSimplify( mmnew ); - mmnew = astAnnul( mmnew ); - -/* Store a pointer to the new PermMap in place of the supplied MatrixMap. This - PermMap should be used in its forward direction. */ - maps[ imm ] = (AstMapping *) spmnew; - inverts[ imm ] = astGetInvert( spmnew ); - -/* Annul the supplied matrixMap. */ - (void) astAnnul( mm ); - -/* Store a pointer to the new MatrixMap. This MatrixMap should be used in - its forward direction. */ - maps[ 1 - imm ] = (AstMapping *) smmnew; - inverts[ 1 - imm ] = astGetInvert( smmnew ); - } - -/* Return. */ - return; -} - -static void MatWin( AstMapping **maps, int *inverts, int imm, int *status ){ -/* -* Name: -* MatWin - -* Purpose: -* Swap a WinMap and a MatrixMap. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* void MatWin( AstMapping **maps, int *inverts, int imm, int *status ) - -* Class Membership: -* WinMap member function - -* Description: -* A list of two Mappings is supplied containing a WinMap and a -* MatrixMap. These Mappings are annulled, and replaced with -* another pair of Mappings consisting of a WinMap and a MatrixMap -* in the opposite order. These Mappings are chosen so that their -* combined effect is the same as the original pair of Mappings. -* The scale factors in the returned WinMap are always unity (i.e. -* the differences in scaling get absorbed into the returned -* MatrixMap). - -* Parameters: -* maps -* A pointer to an array of two Mapping pointers. -* inverts -* A pointer to an array of two invert flags. -* imm -* The index within "maps" of the MatrixMap. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMatrixMap *m1; /* Pointer to Diagonal scale factor MatrixMap */ - AstMatrixMap *m2; /* Pointer to returned MatrixMap */ - AstMatrixMap *sm2; /* Pointer to simplified returned MatrixMap */ - AstMatrixMap *mm; /* Pointer to the supplied MatrixMap */ - AstPointSet *pset1; /* Shift terms from supplied WinMap */ - AstPointSet *pset2; /* Shift terms for returned WinMap */ - AstWinMap *w1; /* Pointer to the returned WinMap */ - AstWinMap *sw1; /* Pointer to the simplified returned WinMap */ - AstWinMap *wm; /* Pointer to the supplied WinMap */ - double **ptr1; /* Pointer to pset1 data */ - double **ptr2; /* Pointer to pset2 data */ - double *a; /* Array of shift terms from supplied WinMap */ - double *aa; /* Pointer to next shift term */ - double *b; /* Array of scale terms from supplied WinMap */ - double *bb; /* Pointer to next scale term */ - int i; /* Axis count */ - int nin; /* No. of axes in supplied WinMap */ - int nout; /* No. of axes in returned WinMap */ - int old_minv; /* Invert value for the supplied MatrixMap */ - int old_winv; /* Invert value for the supplied WinMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store pointers to the supplied WinMap and the MatrixMap. */ - wm = (AstWinMap *) maps[ 1 - imm ]; - mm = (AstMatrixMap *) maps[ imm ]; - -/* Temporarily set the Invert attribute of the supplied Mappings to the - supplied values. */ - old_winv = astGetInvert( wm ); - astSetInvert( wm, inverts[ 1 - imm ] ); - - old_minv = astGetInvert( mm ); - astSetInvert( mm, inverts[ imm ] ); - -/* Get copies of the shift and scale terms used by the WinMap. This - also returns the number of axes in the WinMap. */ - nin = astWinTerms( wm, &a, &b ); - -/* Create a diagonal MatrixMap holding the scale factors from the - supplied WinMap. */ - m1 = astMatrixMap( nin, nin, 1, b, "", status ); - -/* Create a PointSet holding a single position given by the shift terms - in the supplied WinMap. */ - pset1 = astPointSet( 1, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - if( astOK ){ - aa = a; - for( i = 0; i < nin; i++ ) ptr1[ i ][ 0 ] = *(aa++); - } - -/* First deal with cases when the WinMap is applied first, followed by - the MatrixMap. */ - if( imm == 1 ){ - -/* Multiply the diagonal matrix holding the WinMap scale factors by the - supplied matrix. The resulting MatrixMap is the one to return in the - map list. */ - m2 = astMtrMult( m1, mm ); - -/* Transform the position given by the shift terms from the supplied - WinMap using the supplied MatrixMap to get the shift terms for - the returned WinMap. */ - pset2 = astTransform( mm, pset1, 1, NULL ); - -/* Now deal with cases when the MatrixMap is applied first, followed by - the WinMap. */ - } else { - -/* Multiply the supplied MatrixMap by the diagonal matrix holding scale - factors from the supplied WinMap. The resulting MatrixMap is the one to - return in the map list. */ - m2 = astMtrMult( mm, m1 ); - -/* Transform the position given by the shift terms from the supplied - WinMap using the inverse of the returned MatrixMap to get the shift - terms for the returned WinMap. */ - pset2 = astTransform( m2, pset1, 0, NULL ); - - } - -/* Re-instate the original value of the Invert attributes of the supplied - Mappings. */ - astSetInvert( wm, old_winv ); - astSetInvert( mm, old_minv ); - -/* Get pointers to the shift terms for the returned WinMap. */ - ptr2 = astGetPoints( pset2 ); - -/* Create the returned WinMap, initially with undefined corners. The number of - axes in the WinMap must equal the number of shift terms. */ - nout = astGetNcoord( pset2 ); - w1 = astWinMap( nout, NULL, NULL, NULL, NULL, "", status ); - -/* If succesful, store the scale and shift terms in the WinMap. The scale - terms are always unity. */ - if( astOK ){ - bb = w1->b; - aa = w1->a; - for( i = 0; i < nout; i++ ) { - *(bb++) = 1.0; - *(aa++) = ptr2[ i ][ 0 ]; - } - -/* Replace the supplied Mappings and invert flags with the ones found - above. Remember that the order of the Mappings is now swapped */ - (void) astAnnul( maps[ 0 ] ); - (void) astAnnul( maps[ 1 ] ); - - sw1 = astSimplify( w1 ); - w1 = astAnnul( w1 ); - - maps[ imm ] = (AstMapping *) sw1; - inverts[ imm ] = astGetInvert( sw1 ); - - sm2 = astSimplify( m2 ); - m2 = astAnnul( m2 ); - - maps[ 1 - imm ] = (AstMapping *) sm2; - inverts[ 1 - imm ] = astGetInvert( sm2 ); - - } - -/* Annul the MatrixMap and PointSet holding the scale and shift terms from the - supplied WinMap. */ - m1 = astAnnul( m1 ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Free the copies of the scale and shift terms from the supplied WinMap. */ - b = (double *) astFree( (void *) b ); - a = (double *) astFree( (void *) a ); - -/* Return. */ - return; -} - -static AstWinMap *MatWin2( AstMatrixMap *mm, AstWinMap *wm, int minv, - int winv, int mat1, int *status ){ -/* -* Name: -* MatWin2 - -* Purpose: -* Create a WinMap by merging a diagonal MatrixMap and a WinMap. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* AstWinMap *MatWin2( AstMatrixMap *mm, AstWinMap *wm, int minv, -* int winv, int mat1, int *status ) - -* Class Membership: -* MatrixMap member function - -* Description: -* This function creates a new WinMap which performs a mapping -* equivalent to applying the two supplied Mappings in series in the -* directions specified by the "invert" flags (the Invert attributes of -* the supplied MatrixMaps are ignored), in the order specified by -* "mat1". - -* Parameters: -* mm -* A pointer to the MatrixMap. Assumed to be diagonal. -* wm -* A pointer to the WinMap. -* minv -* The invert flag to use with mm. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* winv -* The invert flag to use with wm. -* mat1 -* If non-zero, then "mm" is applied first followed by "wm". Otherwise, -* "wm" is applied first followed by "mm". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new MatrixMap. - -* Notes: -* - The forward direction of the returned MatrixMap is equivalent to the -* combined effect of the two supplied Mappings, operating in the -* directions specified by "winv" and "minv". -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstWinMap *result; /* Pointer to output WinMap */ - double *ina; /* Input corner A in new WinMap */ - double *inb; /* Input corner B in new WinMap */ - double *newscales; /* Scales for new WinMap */ - double *newshifts; /* Shifts for new WinMap */ - double *outa; /* Output corner A in new WinMap */ - double *outb; /* Output corner B in new WinMap */ - double *scales2; /* Pointer to extended WinMap scales array */ - double *scales; /* Pointer to WinMap scales array */ - double *shifts; /* Pointer to WinMap shifts array */ - int i; /* Axis index */ - int ncol; /* No. of columns in the MatrixMap */ - int nrow; /* No. of rows in the MatrixMap */ - int nt; /* Number of axes in WinMap */ - int old_minv; /* Original setting of MatrixMap Invert attribute */ - int old_winv; /* Original setting of WinMap Invert attribute */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the returned pointer. */ - result = NULL; - -/* Temporarily set the Invert attributes of both Mappings to the supplied - values. */ - old_minv = astGetInvert( mm ); - astSetInvert( mm, minv ); - - old_winv = astGetInvert( wm ); - astSetInvert( wm, winv ); - -/* Get the number of inputs (columns) and outputs (rows) for the MatrixMap. */ - ncol = astGetNin( mm ); - nrow = astGetNout( mm ); - -/* Get the scales and shifts implemented by the WinMap. These take into - account the current Invert attribute of the WinMap. */ - nt = astWinTerms( wm, &shifts, &scales ); - -/* First deal with cases where the MatrixMap is applied first. */ - if( mat1 ){ - -/* Sanity check. */ - if( nt != nrow ) { - if( astOK ) astError( AST__INTER, "astMapMerge(%s): WinMap has %d axes, " - "but MatrixMap has %d rows (internal AST programming " - "error).", status, astGetClass(mm), nt, nrow ); - - } else { - -/* Allocate the array to hold the scale terms for the new WinMap. */ - newscales = astMalloc( nrow*sizeof(double) ); - -/* Ensure that the original scales array is padded with sufficient zeros - to allow it to be transformed using the matrixmap. */ - scales2 = astCalloc( ncol, sizeof(double) ); - if( astOK ) memcpy( scales2, scales, - (ncoli_matrix : this->f_matrix; - a_matrix = astGetInvert( a ) ? a->i_matrix : a->f_matrix; - -/* Get memory to hold the product matrix in full form. */ - new_matrix = (double *) astMalloc( sizeof( double )* - (size_t)( nrow_a*ncol_this ) ); - if( astOK ){ - -/* First deal with cases where the "a" MatrixMap represents a unit - matrix. */ - if( a->form == UNIT ){ - -/* Copy the required number of rows from "this" to "new". */ - (void) memcpy( (void *) new_matrix, (const void *) this_matrix, - sizeof(double)*(size_t)( minrow*ncol_this ) ); - -/* If there are insufficient rows in "this", append some zero-filled rows. */ - if( minrow < nrow_a ){ - for( i = minrow*ncol_this; i < nrow_a*ncol_this; i++ ){ - new_matrix[ i ] = 0.0; - } - } - -/* Now deal with cases where the "a" MatrixMap represents a diagonal - matrix. */ - } else if( a->form == DIAGONAL ){ - -/* Scale the required number of rows from "this" storing them in "new", - and checking for bad values. */ - i = 0; - - for( row = 0; row < minrow; row++ ){ - factor = a_matrix[ row ]; - - if( factor != AST__BAD ){ - - for( col = 0; col < ncol_this; col++ ){ - this_val = this_matrix[ i ]; - if( this_val != AST__BAD ){ - new_matrix[ i ] = this_val*factor; - } else { - new_matrix[ i ] = AST__BAD; - } - i++; - } - - } else { - - for( col = 0; col < ncol_this; col++ ){ - new_matrix[ i++ ] = AST__BAD; - } - - } - } - -/* If there are insufficient rows in "this", append some zero-filled rows. */ - if( minrow < nrow_a ){ - for( i = minrow*ncol_this; i < nrow_a*ncol_this; i++ ){ - new_matrix[ i ] = 0.0; - } - } - - -/* Now deal with cases where the "a" MatrixMap represents a full, non-diagonal - matrix. */ - } else { - -/* Initialise a pointer to the next element in the product matrix. */ - new_val = new_matrix; - -/* Get a pointer to the start of each row of the "a" matrix. */ - for( row = 0; row < nrow_a; row++ ){ - a_row = a_matrix + ncol_a*row; - -/* Get a pointer to the start of each column of the "this" matrix. */ - for( col = 0; col < ncol_this; col++ ){ - this_col = this_matrix + col; - -/* Form the dot product of the current row from "a", and the current - column from "this", checking for bad values. */ - sum = 0.0; - for( i = 0; i < ncol_a; i++ ){ - a_val = a_row[ i ]; - this_val = this_col[ i*ncol_this ]; - if( a_val != AST__BAD && this_val != AST__BAD ){ - sum += a_val*this_val; - } else { - sum = AST__BAD; - break; - } - } - -/* Store the output matrix element value. */ - *(new_val++) = sum; - - } - } - } - -/* Create the new MatrixMap. */ - new = astInitMatrixMap( NULL, sizeof( AstMatrixMap ), !class_init, - &class_vtab, "MatrixMap", ncol_this, nrow_a, - FULL, new_matrix ); - -/* If possible, compress the new MatrixMap by removing off-diagonal zero - elements. */ - CompressMatrix( new, status ); - -/* Re-compress the original "this" MatrixMap. */ - CompressMatrix( this, status ); - - } - -/* Free the memory used to hold the product matrix in full form. */ - new_matrix = (double *) astFree( (void *) new_matrix ); - - return new; - -} - -static AstMatrixMap *MtrRot( AstMatrixMap *this, double theta, - const double axis[], int *status ){ -/* -*+ -* Name: -* astMtrRot - -* Purpose: -* Multiply a MatrixMap by a rotation matrix. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "matrixmap.h" -* AstMatrixMap *astMtrRot( astMatrixMap *this, double theta, -* const double axis[] ) - -* Class Membership: -* MatrixMap method. - -* Description: -* This function creates a new MatrixMap which is a copy of "this", -* rotated by a specified angle. It can only be used on MatrixMaps which -* have either 2 or 3 output coordinates. In the 3-D case, the rotation -* is about an arbitrary axis passing through the origin. - -* Parameters: -* this -* Pointer to the MatrixMap. -* theta -* The angle by which to rotate the matrix, in radians. If the matrix -* is applied to a 2-D vector position, the resulting vector is -* rotated clockwise about the origin (i.e. from the positive direction -* of the second axis to the positive direction of the first axis). If -* the vector positions are three dimensional, the rotation is clockwise -* when looking along the vector given by "axis". Note, "theta" measures -f when looking along the vector given by AXIS. Note, THETA measures -* the movemement of the vectors relative to a fixed reference frame. -* Alternatively, the reference frame can be thought of as rotating by -* (-theta) relative to the fixed vectors. -* axis -* A 3-D vector specifying the axis of rotation. This parameter is -* ignored if the output from MatrixMap is 2-dimensional. - -* Returned Value: -* A pointer to the rotated MatrixMap. - -* Notes: -* - A null Object pointer will also be returned if this function -* is invoked with the AST error status set, or if it should fail -* for any reason. -*- -*/ - -/* Local variables. */ - AstMatrixMap *new; /* New MatrixMap holding the rotated matrix */ - double as,a,b,c,d,e,f,g; /* Intermediate quantities */ - double axlen; /* Length of axis vector */ - double axlen2; /* Squared length of axis vector */ - double costh; /* Cos(rotation angle) */ - double sinth; /* Sin(rotation angle) */ - double rotmat[9]; /* Rotation matrix */ - double work[3]; /* Work space for matrix multiplication */ - int ncol; /* No. of columns in the MatrixMap */ - int nrow; /* No. of rows in the MatrixMap */ - -/* Return a NULL pointer if an error has already occurred. */ - if ( !astOK ) return NULL; - -/* Initialise the returned MarixMap to be a copy of the supplied MatrixMap. */ - new = astCopy( this ); - -/* Save the cos and sin of the rotation angle for future use. */ - costh = cos( theta ); - sinth = sin( theta ); - -/* Return without changing the MatrixMap if the rotation angle is a - multiple of 360 degrees. */ - if ( costh == 1.0 ) return new; - -/* Get the dimensions of the MatrixMap. */ - nrow = astGetNout( new ); - ncol = astGetNin( new ); - -/* First do rotation of a plane about the origin. */ - if( nrow == 2 ){ - -/* Ensure that the MatrixMap is stored in full form rather than - compressed form. */ - ExpandMatrix( new, status ); - -/* Form the 2x2 forward rotation matrix. Theta is the clockwise angle - of rotation. */ - rotmat[0] = costh; - rotmat[1] = sinth; - rotmat[2] = -sinth; - rotmat[3] = costh; - -/* Post-multiply the current forward matrix (depending on whether or not - the MatrixMap has been inverted) by the forward rotation matrix. */ - if( !astGetInvert( new ) ){ - SMtrMult( 1, 2, ncol, rotmat, new->f_matrix, work, status ); - } else { - SMtrMult( 1, 2, ncol, rotmat, new->i_matrix, work, status ); - } - -/* Now form the 2x2 inverse rotation matrix (the diagonal elements - don't change). */ - rotmat[1] = -sinth; - rotmat[2] = sinth; - -/* Pre-multiply the current inverse matrix (depending on whether or - not the MatrixMap has been inverted) by the inverse rotation matrix. */ - if( !astGetInvert( new ) ){ - SMtrMult( 0, ncol, 2, rotmat, new->i_matrix, work, status ); - } else { - SMtrMult( 0, ncol, 2, rotmat, new->f_matrix, work, status ); - } - -/* See if the matrix can be stored as a UNIT or DIAGONAL matrix. */ - CompressMatrix( new, status ); - -/* Now do rotation of a volume about an axis passing through the origin. */ - } else if( nrow == 3 ){ - -/* Find the length of the axis vector. Report an error if it has zero - length or has not been supplied. */ - if( axis ) { - axlen2 = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]; - } else { - axlen2 = 0.0; - } - if( axlen2 <= 0.0 ) { - astError( AST__MTRAX, "astMtrRot(%s): NULL or zero length " - "axis vector supplied.", status, astClass(new) ); - } - axlen = sqrt( axlen2 ); - -/* Ensure that the MatrixMap is stored in full form rather than - compressed form. */ - ExpandMatrix( new, status ); - -/* Form commonly used terms in the rotation matrix. */ - as = sinth/axlen; - a = (1.0 - costh)/axlen2; - b = a*axis[0]*axis[1]; - c = as*axis[2]; - d = a*axis[0]*axis[2]; - e = as*axis[1]; - f = a*axis[1]*axis[2]; - g = as*axis[0]; - -/* Form the 3x3 forward rotation matrix. Theta is the clockwise angle - of rotation looking in the direction of the axis vector. */ - rotmat[0] = a*axis[0]*axis[0] + costh; - rotmat[1] = b - c; - rotmat[2] = d + e; - rotmat[3] = b + c; - rotmat[4] = a*axis[1]*axis[1] + costh; - rotmat[5] = f - g; - rotmat[6] = d - e; - rotmat[7] = f + g; - rotmat[8] = a*axis[2]*axis[2] + costh; - -/* Post-multiply the current forward matrix (depending on whether or not - the MatrixMap has been inverted) by the forward rotation matrix. */ - if( !astGetInvert( new ) ){ - SMtrMult( 1, 3, ncol, rotmat, new->f_matrix, work, status ); - } else { - SMtrMult( 1, 3, ncol, rotmat, new->i_matrix, work, status ); - } - -/* Now form the 3x3 inverse rotation matrix (the diagonal elements - don't change). */ - rotmat[1] = b + c; - rotmat[2] = d - e; - rotmat[3] = b - c; - rotmat[5] = f + g; - rotmat[6] = d + e; - rotmat[7] = f - g; - -/* Pre-multiply the current inverse matrix (depending on whether or - not the MatrixMap has been inverted) by the inverse rotation matrix. */ - if( !astGetInvert( new ) ){ - SMtrMult( 0, ncol, 3, rotmat, new->i_matrix, work, status ); - } else { - SMtrMult( 0, ncol, 3, rotmat, new->f_matrix, work, status ); - } - -/* See if the matrix can be stored as a UNIT or DIAGONAL matrix. */ - CompressMatrix( new, status ); - -/* Report an error if the matrix is not suitable for rotation. */ - } else { - astError( AST__MTR23, "astMtrRot(%s): Cannot rotate a %dx%d" - " MatrixMap.", status, astClass(new), nrow, ncol ); - } - -/* Delete the new MatrixMap if an error has occurred. */ - if( !astOK ) new = astDelete( new ); - - return new; - -} - -static void PermGet( AstPermMap *map, int **outperm, int **inperm, - double **consts, int *status ){ -/* -* Name: -* PermGet - -* Purpose: -* Get the axis permutation and constants array for a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* void PermGet( AstPermMap *map, int **outperm, int **inperm, -* double **const, int *status ) - -* Class Membership: -* MatrixMap member function - -* Description: -* This function returns axis permutation and constants arrays which can -* be used to create a PermMap which is equivalent to the supplied PermMap. - -* Parameters: -* map -* The PermMap. -* outperm -* An address at which to return a popinter to an array of ints -* holding the output axis permutation array. The array should be -* released using astFree when no longer needed. -* inperm -* An address at which to return a popinter to an array of ints -* holding the input axis permutation array. The array should be -* released using astFree when no longer needed. -* consts -* An address at which to return a popinter to an array of doubles -* holding the constants array. The array should be released using -* astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - NULL pointers are returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* PointSet holding input positions for PermMap */ - AstPointSet *pset2; /* PointSet holding output positions for PermMap */ - double **ptr1; /* Pointer to pset1 data */ - double **ptr2; /* Pointer to pset2 data */ - double *cnst; /* Pointer to constants array */ - double cn; /* Potential new constant value */ - double ip; /* Potential output axis index */ - double op; /* Potential input axis index */ - int *inprm; /* Pointer to input axis permutation array */ - int *outprm; /* Pointer to output axis permutation array */ - int i; /* Axis count */ - int nc; /* Number of constants stored so far */ - int nin; /* No. of input coordinates for the PermMap */ - int nout; /* No. of output coordinates for the PermMap */ - -/* Initialise. */ - if( outperm ) *outperm = NULL; - if( inperm ) *inperm = NULL; - if( consts ) *consts = NULL; - -/* Check the global error status and the supplied pointers. */ - if ( !astOK || !outperm || !inperm || !consts ) return; - -/* Get the number of input and output axes for the supplied PermMap. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - -/* Allocate the memory for the returned arrays. */ - outprm = (int *) astMalloc( sizeof( int )* (size_t) nout ); - inprm = (int *) astMalloc( sizeof( int )* (size_t) nin ); - cnst = (double *) astMalloc( sizeof( double )* (size_t) ( nout + nin ) ); - -/* Returned the pointers to these arrays.*/ - *outperm = outprm; - *inperm = inprm; - *consts = cnst; - -/* Create two PointSets, each holding two points, which can be used for - input and output positions with the PermMap. */ - pset1 = astPointSet( 2, nin, "", status ); - pset2 = astPointSet( 2, nout, "", status ); - -/* Set up the two input positions to be [0,1,2...] and [-1,-1,-1,...]. The - first position is used to enumerate the axes, and the second is used to - check for constant axis values. */ - ptr1 = astGetPoints( pset1 ); - if( astOK ){ - for( i = 0; i < nin; i++ ){ - ptr1[ i ][ 0 ] = ( double ) i; - ptr1[ i ][ 1 ] = -1.0; - } - } - -/* Use the PermMap to transform these positions in the forward direction. */ - (void) astTransform( map, pset1, 1, pset2 ); - -/* No constant axis valeus found yet. */ - nc = 0; - -/* Look at the mapped positions to determine the output axis permutation - array. */ - ptr2 = astGetPoints( pset2 ); - if( astOK ){ - -/* Do each output axis. */ - for( i = 0; i < nout; i++ ){ - -/* If the output axis value is copied from an input axis value, the index - of the appropriate input axis will be in the mapped first position. */ - op = ptr2[ i ][ 0 ]; - -/* If the output axis value is assigned a constant value, the result of - mapping the two different input axis values will be the same. */ - cn = ptr2[ i ][ 1 ]; - if( op == cn ) { - -/* We have found another constant. Store it in the constants array, and - store the index of the constant in the output axis permutation array. */ - cnst[ nc ] = cn; - outprm[ i ] = -( nc + 1 ); - nc++; - -/* If the output axis values are different, then the output axis value - must be copied from the input axis value. */ - } else { - outprm[ i ] = (int) ( op + 0.5 ); - } - } - } - -/* Now do the same thing to determine the input permutation array. */ - if( astOK ){ - for( i = 0; i < nout; i++ ){ - ptr2[ i ][ 0 ] = ( double ) i; - ptr2[ i ][ 1 ] = -1.0; - } - } - - (void) astTransform( map, pset2, 0, pset1 ); - - if( astOK ){ - - for( i = 0; i < nin; i++ ){ - - ip = ptr1[ i ][ 0 ]; - cn = ptr1[ i ][ 1 ]; - if( ip == cn ) { - - cnst[ nc ] = cn; - inprm[ i ] = -( nc + 1 ); - nc++; - - } else { - inprm[ i ] = (int) ( ip + 0.5 ); - } - } - } - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* If an error has occurred, attempt to free the returned arrays. */ - if( !astOK ) { - *outperm = (int *) astFree( (void *) *outperm ); - *inperm = (int *) astFree( (void *) *inperm ); - *consts = (double *) astFree( (void *) *consts ); - } - -/* Return. */ - return; -} - -static int PermOK( AstMapping *pm, int *status ){ -/* -* Name: -* PermOK - -* Purpose: -* Determine if a PermMap can be merged with a MatrixMap. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* int PermOK( AstMapping *pm, int *status ) - -* Class Membership: -* PermMap member function - -* Description: -* This function returns a flag indicating if the supplied PermMap -* could be merged with a MatrixMap. For thios to be possible, the -* PermMap must have the same number of input and output axes, and the -* inverse and forward mappings must be consistent. - -* Parameters: -* pm -* The PermMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* 1 if the PermMap can be merged, 0 otherwise. - -* Notes: -* - A value of 0 is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* PointSet holding input positions for PermMap */ - AstPointSet *pset2; /* PointSet holding output positions for PermMap */ - double **ptr1; /* Pointer to pset1 data */ - int i; /* Loop count */ - int nin; /* No. of input coordinates for the PermMap */ - int nout; /* No. of output coordinates for the PermMap */ - int ret; /* Returned flag */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise */ - ret = 0; - -/* The PermMap must have the same number of input and output coordinates. */ - nin = astGetNin( pm ); - nout = astGetNout( pm ); - if( nin == nout ){ - -/* Create two PointSets, each holding two points, which can be used for - the input and output positions with the PermMap. */ - pset1 = astPointSet( 2, nin, "", status ); - pset2 = astPointSet( 2, nout, "", status ); - -/* Set up the two input positions to be [1,2,3...] and [0,-1,-2,...] */ - ptr1 = astGetPoints( pset1 ); - if( astOK ){ - for( i = 0; i < nin; i++ ){ - ptr1[ i ][ 0 ] = ( double )( i + 1 ); - ptr1[ i ][ 1 ] = ( double )( -i ); - } - - } - -/* Use the PermMap to transform these positions in the forward direction. */ - (void) astTransform( pm, pset1, 1, pset2 ); - -/* Now transform the results back again using the inverse PermMap. */ - (void) astTransform( pm, pset2, 0, pset1 ); - -/* See if the input positions have changed. If they have, then the PermMap - does not have a consistent pair of transformations. If they have not, - then the transformations must be consistent because we used two - different input positions and only one could come out unchanged by - chance. */ - if( astOK ){ - ret = 1; - for( i = 0; i < nin; i++ ){ - if( ptr1[ i ][ 0 ] != ( double )( i + 1 ) || - ptr1[ i ][ 1 ] != ( double )( -i ) ){ - ret = 0; - break; - } - } - } - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - } - -/* Return the answer. */ - return astOK ? ret : 0; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* MatrixMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -*/ - -/* Local Variables: */ - AstMatrixMap *map; - double *matrix; - double result; - -/* Check inherited status */ - if( !astOK ) return AST__BAD; - -/* Get a pointer to the MatrixMap structure. */ - map = (AstMatrixMap *) this; - -/* Get a pointer to the array holding the required matrix elements, according - to whether the MatrixMap has been inverted. */ - if( !astGetInvert( this ) ) { - matrix = map->f_matrix; - } else { - matrix = map->i_matrix; - } - -/* First deal with full MatrixMaps in which all matrix elements are stored. */ - if( map->form == FULL ){ - result = matrix[ ax1*astGetNin( this ) + ax2 ]; - -/* For unit matrices, the rate is unity if the input and output axes are - equal, and zero otherwise. */ - } else if( map->form == UNIT ){ - result = (ax1 == ax2 ) ? 1.0 : 0.0; - -/* For diagonal matrices, the rate is zero for off diagonal elements and - the matrix array stored the on-diagonal rates. */ - } else if( ax1 == ax2 ) { - result = matrix[ ax1 ]; - - } else { - result = 0.0; - } - -/* Return the result. */ - return result; -} - -static void SMtrMult( int post, int m, int n, const double *mat1, - double *mat2, double *work, int *status ){ -/* -* Name: -* SMtrMult - -* Purpose: -* Multiply a square matrix and a non-square matrix. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* void SMtrMult( int post, int m, int n, const double *mat1, -* double *mat2, double *work, int *status ) - -* Class Membership: -* MatrixMap member function. - -* Description: -* The matrix pointed to by "mat2" is modified by multiplying it by -* the square matrix pointed to by "mat1". If "post" is 1, then: -* -* mat2 -> mat1*mat2 (mat1 is mxm and mat2 is mxn) -* -* If "post" is zero, then: -* -* mat2 -> mat2*mat1 (mat1 is nxn and mat2 is mxn) -* -* The restriction that "mat1" must be square is imposed so that the -* returned matrix will have the same shape as the supplied matrix (mat1). - -* Parameters: -* post -* Specifies whether to post- or pre- multiply mat2 by mat1. -* m -* The number of rows in mat2. -* n -* The number of columns in mat2. -* mat1 -* The multiplier matrix. It must be square of size m or n, depending -* on "post". -* mat2 -* The multiplicand matrix. -* work -* Pointer to work space containing room for m doubles (if "post" -* is 1), or n doubles (if "post" is 0). -* status -* Pointer to the inherited status variable. - -* Notes: -* - No error is reported if "mat2" is supplied NULL. In this case -* it will also be returned NULL. -*/ - -/* Local Variables */ - double dot; /* Output matrix element value */ - const double *mat1_col; /* Pointer to start of current column of mat1 */ - const double *mat1_row; /* Pointer to start of current row of mat1 */ - double *mat2_col; /* Pointer to start of current column of mat2 */ - double *mat2_row; /* Pointer to start of current row of mat2 */ - double cel; /* Column element value */ - double rel; /* Row element value */ - int i; /* Index of current output row */ - int j; /* Index of current output column */ - int k; /* Dot product index */ - -/* Do nothing if mat2 is NULL */ - if ( mat2 ){ - -/* First deal with cases where the supplied matrix is post-multiplied - (i.e. the returned matrix is mat1*mat2). */ - if( post ){ - -/* Loop round each column of the output matrix, storing a pointer to - the start of the corresponding column of mat2. */ - for( j=0; jform == UNIT ) { - result = 1; - -/* Otherwise, check that the appropriate array is defined in the - MatrixMap. */ - } else { - -/* Determine if the Mapping has been inverted. */ - invert = astGetInvert( this ); - -/* If OK, obtain the result. */ - if ( astOK ) { - - if( invert ){ - result = ( map->i_matrix != NULL ); - } else { - result = ( map->f_matrix != NULL ); - } - - } - - } - -/* Return the result. */ - return result; - -} - -static int GetTranInverse( AstMapping *this, int *status ) { -/* -* -* Name: -* GetTranInverse - -* Purpose: -* Determine if a MatrixMap defines an inverse coordinate transformation. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* int GetTranInverse( AstMapping *this, int *status ) - -* Class Membership: -* MatrixMap member function (over-rides the astGetTranInverse method -* inherited from the Mapping class). - -* Description: -* This function returns a value indicating if the MatrixMap is able -* to perform an inverse coordinate transformation. - -* Parameters: -* this -* Pointer to the MatrixMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the inverse coordinate transformation is not defined, or 1 if it -* is. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMatrixMap *map; /* Pointer to MatrixMap to be queried */ - int invert; /* Has the mapping been inverted? */ - int result; /* The returned value */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the MatrixMap. */ - map = (AstMatrixMap *) this; - -/* All unit MatrixMaps are defined in both directions. */ - if( map->form == UNIT ) { - result = 1; - -/* Otherwise, check that the appropriate array is defined in the - MatrixMap. */ - } else { - -/* Determine if the Mapping has been inverted. */ - invert = astGetInvert( this ); - -/* If OK, obtain the result. */ - if ( astOK ) { - - if( invert ){ - result = ( map->f_matrix != NULL ); - } else { - result = ( map->i_matrix != NULL ); - } - - } - - } - -/* Return the result. */ - return result; - -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a MatrixMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* MatrixMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a MatrixMap and a set of points encapsulated in a -* PointSet and transforms the points by multiplying them by the matrix. - -* Parameters: -* this -* Pointer to the MatrixMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of columns in the MatrixMap being applied. -* - The number of coordinate values per point in the output PointSet will -* equal the number of rows in the MatrixMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstMatrixMap *map; /* Pointer to MatrixMap to be applied */ - double diag_term; /* Current diagonal element value */ - double *indata; /* Pointer to next input data value */ - double *matrix; /* Pointer to start of matrix element array */ - double *matrix_element; /* Pointer to current matrix element value */ - double *outdata; /* Pointer to next output data value */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double sum; /* Partial output value */ - double val; /* Data value */ - int in_coord; /* Index of output coordinate */ - int nax; /* Output axes for which input axes exist */ - int ncoord_in; /* Number of coordinates per input point */ - int ncoord_out; /* Number of coordinates per output point */ - int npoint; /* Number of points */ - int out_coord; /* Index of output coordinate */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the MatrixMap. */ - map = (AstMatrixMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - and output PointSets and obtain pointers for accessing the input and - output coordinate values. */ - ncoord_in = astGetNcoord( in ); - ncoord_out = astGetNcoord( result ); - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse mapping, according to the - direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Get a pointer to the array holding the required matrix elements, according - to the direction of mapping required. */ - if ( forward ) { - matrix = map->f_matrix; - } else { - matrix = map->i_matrix; - } - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - -/* First deal with full MatrixMaps in which all matrix elements are stored. */ - if( map->form == FULL ){ - -/* Loop to apply the matrix to each point in turn, checking for - (and propagating) bad values in the process. The matrix elements are - accessed sequentially in row order. The next matrix element to be - used is identified by a pointer which is initialised to point to the - first element of the matrix prior to processing each point. */ - for ( point = 0; point < npoint; point++ ) { - matrix_element = matrix; - -/* Each output co-ordinate value is created by summing the product of the - corresponding input co-ordinates and the elements of one row of the - matrix. */ - for ( out_coord = 0; out_coord < ncoord_out; out_coord++ ) { - sum = 0.0; - - for ( in_coord = 0; in_coord < ncoord_in; in_coord++ ) { - -/* Check the current input coordinate value and the current matrix element. - If the coordinate value is bad, then the output value will also be - bad unless the matrix element is zero. That is, a zero matrix element - results in the input coordinate value being ignored, even if it is bad. - This prevents bad input values being propagated to output axes which - are independant of the bad input axis. A bad matrix element always results - in the output value being bad. In either of these cases, break out of the - loop, remembering to advance the pointer to the next matrix element so - that it points to the start of the next row ready for doing the next - output coordinate. */ - if ( ( ptr_in[ in_coord ][ point ] == AST__BAD && - (*matrix_element) != 0.0 ) || - (*matrix_element) == AST__BAD ) { - sum = AST__BAD; - matrix_element += ncoord_in - in_coord; - break; - -/* If the input coordinate and the current matrix element are both - valid, increment the sum by their product, and step to the next matrix - element pointer If we arrive here with a bad input value, then the - matrix element must be zero, in which case the running sum is left - unchanged. */ - } else { - if ( ptr_in[ in_coord ][ point ] != AST__BAD ) { - sum += ptr_in[ in_coord ][ point ] * (*matrix_element); - } - matrix_element++; - } - } - -/* Store the output coordinate value. */ - ptr_out[ out_coord ][ point ] = sum; - - } - - } - -/* Now deal with unit and diagonal MatrixMaps. */ - } else { - -/* Find the number of output axes for which input data is available. */ - if( ncoord_in < ncoord_out ){ - nax = ncoord_in; - } else { - nax = ncoord_out; - } - -/* For unit matrices, copy the input axes to the corresponding output axes. */ - if( map->form == UNIT ){ - for( out_coord = 0; out_coord < nax; out_coord++ ) { - (void) memcpy( ptr_out[ out_coord ], - (const void *) ptr_in[ out_coord ], - sizeof( double )*(size_t)npoint ); - } - -/* For diagonal matrices, scale each input axis using the appropriate - diagonal element from the matrix, and store in the output. */ - } else { - for( out_coord = 0; out_coord < nax; out_coord++ ){ - diag_term = matrix[ out_coord ]; - outdata = ptr_out[ out_coord ]; - indata = ptr_in[ out_coord ]; - - if( diag_term != AST__BAD ){ - for( point = 0; point < npoint; point++ ){ - val = *(indata++); - if( val != AST__BAD ){ - *(outdata++) = diag_term*val; - } else { - *(outdata++) = AST__BAD; - } - } - - } else { - for( point = 0; point < npoint; point++ ){ - *(outdata++) = AST__BAD; - } - } - } - } - -/* If there are any remaining output axes, fill the first one with zeros. */ - if( nax < ncoord_out ){ - outdata = ptr_out[ nax ]; - for( point = 0; point < npoint; point++ ) *(outdata++) = 0.0; - -/* Copy this axis to any remaining output axes. */ - outdata = ptr_out[ nax ]; - for( out_coord = nax + 1; out_coord < ncoord_out; out_coord++ ) { - (void) memcpy( ptr_out[ out_coord ], (const void *) outdata, - sizeof( double )*(size_t)npoint ); - } - } - } - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -static int ScalingRowCol( AstMatrixMap *map, int axis, int *status ){ -/* -* Name: -* ScalingRowCol - -* Purpose: -* Determine if a given row and column of a MatrixMap are zeros -* with a non-zero diagonal term. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* int ScalingRowCol( AstMatrixMap *map, int axis, int *status ) - -* Class Membership: -* MatrixMap member function - -* Description: -* This function returns a flag indicating if a MatrixMap presents a -* simple scaling for a given axis in both directions. The MatrixMap -* must be square. A value of one is returned if every element of the -* row and column corresponding to the given axis is zero, except for -* the diagonal term which must be non-zero. - -* Parameters: -* map -* The MatrixMap. -* axis -* The zero-based index of the axis to check. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* 1 if the row/column produces a simple scaling, 0 otherwise. - -*/ - -/* Local Variables: */ - double *el; /* Pointer to matrix element */ - int i; /* Element count */ - int ncol; /* No. of input coordinates */ - int ret; /* Returned flag */ - -/* Initialise */ - ret = 0; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* If a unit or diagonal MatrixMap has been supplied, return 1. */ - if( map->form != FULL ){ - ret = 1; - -/* If a full matrix has been supplied... */ - } else { - -/* Assume the row/column gives a unit mapping. */ - ret = 1; - -/* Get the number of input axes for the MatrixMap. */ - ncol = astGetNin( map ); - -/* Check that all elements of the "axis"th row are effectively zero, except - for the "axis"th element which must be non-zero. */ - el = map->f_matrix + axis*ncol; - for( i = 0; i < ncol; i++ ) { - if( i == axis ) { - if( fabs( *el ) <= DBL_EPSILON ) { - ret = 0; - break; - } - } else if( fabs( *el ) > DBL_EPSILON ) { - ret = 0; - break; - } - el++; - } - -/* Check that all elements of the "axis"th column are effectively zero, except - for the "axis"th element which must be non-zero. */ - if( ret ) { - el = map->f_matrix + axis; - for( i = 0; i < ncol; i++ ) { - if( i == axis ) { - if( fabs( *el ) <= DBL_EPSILON ) { - ret = 0; - break; - } - } else if( fabs( *el ) > DBL_EPSILON ) { - ret = 0; - break; - } - el += ncol; - } - } - } - -/* Return the answer. */ - return astOK ? ret : 0; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for MatrixMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for MatrixMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the matrix -* element values associated with the input MatrixMap. -*/ - - -/* Local Variables: */ - AstMatrixMap *in; /* Pointer to input MatrixMap */ - AstMatrixMap *out; /* Pointer to output MatrixMap */ - int nel; /* No. of elements in the matrix */ - int nin; /* No. of input coordinates */ - int nout; /* No. of output coordinates */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output MatrixMaps. */ - in = (AstMatrixMap *) objin; - out = (AstMatrixMap *) objout; - -/* Nullify the pointers stored in the output object since these will - currently be pointing at the input data (since the output is a simple - byte-for-byte copy of the input). Otherwise, the input data could be - freed by accidient if the output object is deleted due to an error - occuring in this function. */ - out->f_matrix = NULL; - out->i_matrix = NULL; - -/* If the input MatrixMap is a unit mapping, then no matrix elements are - stored with it, so do nothing in this case. */ - if( out->form != UNIT ){ - -/* Obtain the number of stored values in the MatrixMap. This is independant of - whether the Mapping has been inverted or not. If the MatrixMap is diagonal, - only the diagonal terms are stored. */ - nin = astGetNin( in ); - nout = astGetNout( in ); - - if( out->form == DIAGONAL ){ - if( nin < nout ){ - nel = nin; - } else { - nel = nout; - } - - } else { - nel = nin*nout; - } - -/* Store the forward matrix elements in the output MatrixMap. */ - out->f_matrix = (double *) astStore( NULL, (void *) in->f_matrix, - sizeof( double )*(size_t) nel ); - -/* Store the inverse matrix elements (if defined) in the output - MatrixMap. */ - if( in->i_matrix ){ - out->i_matrix = (double *) astStore( NULL, (void *) in->i_matrix, - sizeof( double )*(size_t) nel ); - } - -/* If an error has occurred, free the output MatrixMap arrays. */ - if( !astOK ) { - out->f_matrix = (double *) astFree( (void *) out->f_matrix ); - out->i_matrix = (double *) astFree( (void *) out->i_matrix ); - } - } - - return; - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for MatrixMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for MatrixMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstMatrixMap *this; /* Pointer to MatrixMap */ - -/* Obtain a pointer to the MatrixMap structure. */ - this = (AstMatrixMap *) obj; - -/* Free the arrays used to store element values for forward and inverse - matrices. */ - this->f_matrix = (double *) astFree( (void *) this->f_matrix ); - this->i_matrix = (double *) astFree( (void *) this->i_matrix ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for MatrixMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the MatrixMap class to an output Channel. - -* Parameters: -* this -* Pointer to the MatrixMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstMatrixMap *this; /* Pointer to the MatrixMap structure */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int el; /* Element index */ - int nel; /* No. of elements in the matrix */ - int nin; /* No. of input coords */ - int nout; /* No. of output coords */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the MatrixMap structure. */ - this = (AstMatrixMap *) this_object; - -/* Find the number of elements stored for each matrix. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - - if( this->form == FULL ){ - nel = nin*nout; - - } else if( this->form == DIAGONAL ){ - nel = astMIN( nin, nout ); - - } else { - nel = 0; - } - -/* Write out values representing the instance variables for the - MatrixMap class. */ - -/* The forward matrix. The inverse matrix not written out since it can be - re-calculated when the MatrixMap is read back in. Note BAD values are - not written out as the AST__BAD value may differ on different machines. - If a matrix element is not found when reading the matrix back in - again (in astLoadMatrixMap), then it is assigned a default value of - AST__BAD. */ - if( this->f_matrix ){ - for( el = 0; el < nel; el++ ){ - if( (this->f_matrix)[ el ] != AST__BAD ) { - (void) sprintf( buff, "M%d", el ); - astWriteDouble( channel, buff, 1, 1, (this->f_matrix)[ el ], - "Forward matrix value" ); - } - } - } - -/* The matrix storage form. */ - astWriteString( channel, "Form", 1, 1, Form[ this->form ], - "Matrix storage form" ); - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAMatrixMap and astCheckMatrixMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(MatrixMap,Mapping) -astMAKE_CHECK(MatrixMap) - -AstMatrixMap *astMatrixMap_( int nin, int nout, int form, - const double matrix[], const char *options, int *status, ...){ -/* -*++ -* Name: -c astMatrixMap -f AST_MATRIXMAP - -* Purpose: -* Create a MatrixMap. - -* Type: -* Public function. - -* Synopsis: -c #include "matrixmap.h" -c AstMatrixMap *astMatrixMap( int nin, int nout, int form, -c const double matrix[], -c const char *options, ... ) -f RESULT = AST_MATRIXMAP( NIN, NOUT, FORM, MATRIX, OPTIONS, STATUS ) - -* Class Membership: -* MatrixMap constructor. - -* Description: -* This function creates a new MatrixMap and optionally initialises -* its attributes. -* -* A MatrixMap is a form of Mapping which performs a general linear -* transformation. Each set of input coordinates, regarded as a -* column-vector, are pre-multiplied by a matrix (whose elements -* are specified when the MatrixMap is created) to give a new -* column-vector containing the output coordinates. If appropriate, -* the inverse transformation may also be performed. - -* Parameters: -c nin -f NIN = INTEGER (Given) -* The number of input coordinates, which determines the number -* of columns in the matrix. -c nout -f NOUT = INTEGER (Given) -* The number of output coordinates, which determines the number -* of rows in the matrix. -c form -f FORM = INTEGER (Given) -* An integer which indicates the form in which the matrix -* elements will be supplied. -* -c A value of zero indicates that a full "nout" x "nin" matrix -f A value of zero indicates that a full NOUT x NIN matrix -c of values will be supplied via the "matrix" parameter -f of values will be supplied via the MATRIX argument -* (below). In this case, the elements should be given in row -* order (the elements of the first row, followed by the -* elements of the second row, etc.). -* -* A value of 1 indicates that only the diagonal elements of the -* matrix will be supplied, and that all others should be -c zero. In this case, the elements of "matrix" should contain -f zero. In this case, the elements of MATRIX should contain -* only the diagonal elements, stored consecutively. -* -* A value of 2 indicates that a "unit" matrix is required, -* whose diagonal elements are set to unity (with all other -c elements zero). In this case, the "matrix" parameter is -c ignored and a NULL pointer may be supplied. -f elements zero). In this case, the MATRIX argument is not used. -c matrix -f MATRIX( * ) = DOUBLE PRECISION (Given) -* The array of matrix elements to be used, stored according to -c the value of "form". -f the value of FORM. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new MatrixMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new MatrixMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMatrixMap() -f AST_MATRIXMAP = INTEGER -* A pointer to the new MatrixMap. - -* Notes: -* - In general, a MatrixMap's forward transformation will always -* be available (as indicated by its TranForward attribute), but -* its inverse transformation (TranInverse attribute) will only be -* available if the associated matrix is square and non-singular. -* - As an exception to this, the inverse transformation is always -* available if a unit or diagonal matrix is specified. In this -* case, if the matrix is not square, one or more of the input -* coordinate values may not be recoverable from a set of output -* coordinates. Any coordinates affected in this way will simply be -* set to the value zero. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMatrixMap *new; /* Pointer to new MatrixMap */ - va_list args; /* Variable argument list */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise the MatrixMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitMatrixMap( NULL, sizeof( AstMatrixMap ), !class_init, - &class_vtab, "MatrixMap", nin, nout, form, matrix); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new MatrixMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new MatrixMap. */ - return new; -} - -AstMatrixMap *astMatrixMapId_( int nin, int nout, int form, const double matrix[], - const char *options, ... ) { -/* -* Name: -* astMatrixMapId_ - -* Purpose: -* Create a MatrixMap. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* AstMatrixMap *astMatrixMapId_( int nin, int nout, int form, -* const double matrix[], const char *options, -* ... ) - -* Class Membership: -* MatrixMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astMatrixMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astMatrixMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astMatrixMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astMatrixMap_. - -* Returned Value: -* The ID value associated with the new MatrixMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMatrixMap *new; /* Pointer to new MatrixMap */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the MatrixMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitMatrixMap( NULL, sizeof( AstMatrixMap ), !class_init, &class_vtab, - "MatrixMap", nin, nout, form, matrix ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new MatrixMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new MatrixMap. */ - return astMakeId( new ); -} - -AstMatrixMap *astInitMatrixMap_( void *mem, size_t size, int init, - AstMatrixMapVtab *vtab, const char *name, - int nin, int nout, int form, - const double *matrix, int *status ) { -/* -*+ -* Name: -* astInitMatrixMap - -* Purpose: -* Initialise a MatrixMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "matrixmap.h" -* AstMatrixMap *astInitMatrixMap( void *mem, size_t size, int init, -* AstMatrixMapVtab *vtab, const char *name, -* int nin, int nout, int form, -* const double *matrix ) - -* Class Membership: -* MatrixMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new MatrixMap object. It allocates memory (if necessary) to accommodate -* the MatrixMap plus any additional data associated with the derived class. -* It then initialises a MatrixMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a MatrixMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the MatrixMap is to be initialised. -* This must be of sufficient size to accommodate the MatrixMap data -* (sizeof(MatrixMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the MatrixMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the MatrixMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the MatrixMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new MatrixMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* nin -* The number of input coordinate values per point. This is the -* same as the number of columns in the matrix. -* nout -* The number of output coordinate values per point. This is the -* same as the number of rows in the matrix. -* form -* If "form" is 2 or larger, then a unit MatrixMap is created. In this -* case "matrix" is ignored and can be supplied as NULL. If "form" is -* 1, then a diagonal MatrixMap is created. In this case, the number of -* values in "matrix" should be equal to the minimum of nin and nout, -* and "matrix" should contain the corresponding diagonal terms, in row -* order. If "form" is 0 or less, then a full MatrixMap is created, and -* "matrix" should contain all nin*nout element values. -* matrix -* A pointer to an array of matrix element values. The values should be -* supplied in row order. The content of this array is determined by -* "form". If a full MatrixMap is to be created then the array starts -* with (row 1, column 1), then comes (row 1, column 2), up to (row 1, -* column nin), then (row 2, column 1), (row 2, column 2), and so on, -* finishing with (row nout, column nin) ). An error is reported if a -* NULL value is supplied unless "form" is 2 or more. - -* Returned Value: -* A pointer to the new MatrixMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstMatrixMap *new; /* Pointer to new MatrixMap */ - double *fmat; /* Pointer to the forward matrix */ - double *imat; /* Pointer to the inverse matrix */ - int i; /* Loop count */ - int nel; /* No. of elements in matrix array */ - int nuse; /* Number of usable matrix elements */ - int used_form; /* Form limited to 0, 1 or 2 */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitMatrixMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Report an error if a NULL matrix was supplied, unless a unit MatrixMap - has been requested. */ - if( form < 2 && !matrix ){ - astError( AST__MTRMT, "astInitMatrixMap(%s): NULL matrix supplied.", status, - name ); - - } else { - -/* Initialise a Mapping structure (the parent class) as the first component - within the MatrixMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstMatrixMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, nout, 1, 1 ); - - if ( astOK ) { - -/* Initialise the MatrixMap data. */ -/* ---------------------------- */ -/* If a unit MatrixMap is being created, then no additional storage is - required. */ - if( form > 1 ){ - nel = 0; - used_form = UNIT; - -/* If a diagonal MatrixMap is being created, then memory is needed to hold - the diagonal terms. */ - } else if( form == 1 ){ - if( nin < nout ){ - nel = nin; - } else { - nel = nout; - } - used_form = DIAGONAL; - -/* If a full MatrixMap is being created, then memory is needed to hold - all the terms. */ - } else { - nel = nin*nout ; - used_form = FULL; - } - -/* Allocate memory for the forward matrix, storing the supplied matrix - values in it. */ - fmat = (double *) astStore( NULL, (void *) matrix, - sizeof(double)*(size_t)nel ); - -/* Replace any NaNs by AST__BAD and count the number of usable values. */ - if( nel > 0 ) { - nuse = 0; - for( i = 0; i < nel; i++ ) { - if( !astISFINITE(fmat[ i ]) ) { - fmat[ i ] = AST__BAD; - } else if( fmat[ i ] != AST__BAD ) { - nuse++; - } - } - -/* Report an error if there are no usable values. */ - if( nuse == 0 && astOK ) { - astError( AST__MTRMT, "astInitMatrixMap(%s): Supplied matrix " - "contains only bad values.", status, name ); - } - } - -/* Create an inverse matrix if possible. */ - imat = InvertMatrix( used_form, nout, nin, fmat, status ); - -/* Store the matrix arrays. */ - new->form = used_form; - new->f_matrix = fmat; - new->i_matrix = imat; - -/* Attempt to compress the MatrixMap into DIAGONAL or UNIT form. */ - CompressMatrix( new, status ); - -/* If an error occurred, clean up by deleting the new MatrixMap. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new MatrixMap. */ - return new; -} - -AstMatrixMap *astLoadMatrixMap_( void *mem, size_t size, - AstMatrixMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadMatrixMap - -* Purpose: -* Load a MatrixMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "matrixmap.h" -* AstMatrixMap *astLoadMatrixMap( void *mem, size_t size, -* AstMatrixMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* MatrixMap loader. - -* Description: -* This function is provided to load a new MatrixMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* MatrixMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a MatrixMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the MatrixMap is to be -* loaded. This must be of sufficient size to accommodate the -* MatrixMap data (sizeof(MatrixMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the MatrixMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the MatrixMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstMatrixMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new MatrixMap. If this is NULL, a pointer -* to the (static) virtual function table for the MatrixMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "MatrixMap" is used instead. - -* Returned Value: -* A pointer to the new MatrixMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -/* Local Variables: */ - AstMatrixMap *new; /* Pointer to the new MatrixMap */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - const char *form; /* String form */ - int def; /* Is the matrix defined? */ - int el; /* Element index */ - int nel; /* No. of elements in the matrix */ - int nin; /* No. of input coords */ - int nout; /* No. of output coords */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this MatrixMap. In this case the - MatrixMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstMatrixMap ); - vtab = &class_vtab; - name = "MatrixMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitMatrixMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built MatrixMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "MatrixMap" ); - -/* Now obtain the Matrix storage form from this list. */ - form = astReadString( channel, "form", Form[FULL] ); - new->form = FindString( 3, Form, form, "the MatrixMap component 'Form'", - "astRead", astGetClass( channel ), status ); - form = astFree( (void *) form ); - -/* Find the number of elements stored for each matrix. */ - nin = astGetNin( (AstMapping *) new ); - nout = astGetNout( (AstMapping *) new ); - - if( new->form == FULL ){ - nel = nin*nout; - - } else if( new->form == DIAGONAL ){ - nel = astMIN( nin, nout ); - - } else { - nel = 0; - } - -/* Allocate memory to hold the forward matrix. */ - new->f_matrix = (double *) astMalloc( sizeof(double)*(size_t)nel ); - -/* Now read the other data items from the list and use them to - initialise the appropriate instance variable(s) for this class. */ - -/* The forward matrix. */ - if( new->f_matrix ){ - def = 0; - - for( el = 0; el < nel; el++ ){ - (void) sprintf( buff, "m%d", el ); - (new->f_matrix)[ el ] = astReadDouble( channel, buff, AST__BAD ); - if( (new->f_matrix)[ el ] != AST__BAD ) def = 1; - } - -/* Store a NULL pointer if no elements of the matrix were found. */ - if( !def ) new->f_matrix = (double *) astFree( (void *) new->f_matrix ); - - } - -/* Create an inverse matrix if possible, otherwise store a NULL pointer. */ - if( new->f_matrix ){ - new->i_matrix = InvertMatrix( new->form, nout, nin, new->f_matrix, status ); - } else { - new->i_matrix = NULL; - } - -/* If an error occurred, clean up by deleting the new MatrixMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new MatrixMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -AstMatrixMap *astMtrRot_( AstMatrixMap *this, double theta, - const double axis[], int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,MatrixMap,MtrRot))( this, theta, axis, status ); -} - -AstMatrixMap *astMtrMult_( AstMatrixMap *this, AstMatrixMap *a, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,MatrixMap,MtrMult))( this, a, status ); -} - - - - diff --git a/ast/matrixmap.h b/ast/matrixmap.h deleted file mode 100644 index b24565a..0000000 --- a/ast/matrixmap.h +++ /dev/null @@ -1,318 +0,0 @@ -#if !defined( MATRIXMAP_INCLUDED ) /* Include this file only once */ -#define MATRIXMAP_INCLUDED -/* -*+ -* Name: -* matrixmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the MatrixMap class. - -* Invocation: -* #include "matrixmap.h" - -* Description: -* This include file defines the interface to the MatrixMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The MatrixMap class implements Mappings that transform a set of -* coordinates by multiplying them by a matrix. The inverse transformation -* can only be applied if the associated matrix is square and non-singular. - -* Inheritance: -* The MatrixMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* TranForward (integer) -* A read-only boolean value (0 or 1) which indicates whether a -* MatrixMap is able to transform coordinates in the "forward" -* direction (i.e. converting input coordinates into output -* coordinates). -* TranInverse (integer) -* A read-only boolean value (0 or 1) which indicates whether a -* MatrixMap is able to transform coordinates in the "inverse" -* direction (i.e. converting output coordinates back into input -* coordinates). - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astTransform -* Apply a MatrixMap to transform a set of points. -* astGetTranForward -* Determine if a MatrixMap can perform a "forward" coordinate -* transformation. -* astGetTranInverse -* Determine if a MatrixMap can perform an "inverse" coordinate -* transformation. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* astMtrMult -* Multiply a MatrixMap by another MatrixMap. -* astMtrRot -* Rotate a MatrixMap. - -* Other Class Functions: -* Public: -* astIsAMatrixMap -* Test class membership. -* astMatrixMap -* Create a MatrixMap. -* -* Protected: -* astCheckMatrixMap -* Validate class membership. -* astInitMatrixMap -* Initialise a MatrixMap. -* astInitMatrixMapVtab -* Initialise the virtual function table for the MatrixMap class. -* astLoadMatrixMap -* Load a MatrixMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstMatrixMap -* MatrixMap object type. -* -* Protected: -* AstMatrixMapVtab -* MatrixMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 12-Feb-1996 (DSB): -* Original version. -* 22-Feb-1996 (DSB): -* Method "astMatrixRotate" added. -* 5-Mar-1996 (DSB): -* Method "astMatrixMult" added. -* 14-NOV-1996 (DSB): -* External interface and I/O added. Public method names shortened. -* 3-JUN-1997 (DSB): -* astMtrMult and astMtrRot made protected instead of public. -* 8-JAN-2003 (DSB): -* Added protected astInitMatrixMapVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* MatrixMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstMatrixMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *f_matrix; /* Pointer to forward matrix */ - double *i_matrix; /* Pointer to inverse matrix */ - int form; /* Matrix storage form */ - -} AstMatrixMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstMatrixMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstMatrixMap *(* MtrRot)( AstMatrixMap *, double, const double[], int * ); - AstMatrixMap *(* MtrMult)( AstMatrixMap *, AstMatrixMap *, int * ); - -} AstMatrixMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstMatrixMapGlobals { - AstMatrixMapVtab Class_Vtab; - int Class_Init; -} AstMatrixMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitMatrixMapGlobals_( AstMatrixMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(MatrixMap) /* Check class membership */ -astPROTO_ISA(MatrixMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstMatrixMap *astMatrixMap_( int, int, int, const double[], const char *, int *, ...); -#else -AstMatrixMap *astMatrixMapId_( int, int, int, const double[], const char *, ... )__attribute__((format(printf,5,6))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstMatrixMap *astInitMatrixMap_( void *, size_t, int, AstMatrixMapVtab *, - const char *, int, int, int, const double[], int * ); - -/* Vtab initialiser. */ -void astInitMatrixMapVtab_( AstMatrixMapVtab *, const char *, int * ); - -/* Loader. */ -AstMatrixMap *astLoadMatrixMap_( void *, size_t, AstMatrixMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -AstMatrixMap *astMtrRot_( AstMatrixMap *, double, const double[], int * ); -AstMatrixMap *astMtrMult_( AstMatrixMap *, AstMatrixMap *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckMatrixMap(this) astINVOKE_CHECK(MatrixMap,this,0) -#define astVerifyMatrixMap(this) astINVOKE_CHECK(MatrixMap,this,1) - -/* Test class membership. */ -#define astIsAMatrixMap(this) astINVOKE_ISA(MatrixMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astMatrixMap astINVOKE(F,astMatrixMap_) -#else -#define astMatrixMap astINVOKE(F,astMatrixMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitMatrixMap(mem,size,init,vtab,name,nin,nout,form,matrix) \ -astINVOKE(O,astInitMatrixMap_(mem,size,init,vtab,name,nin,nout,form,matrix,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitMatrixMapVtab(vtab,name) astINVOKE(V,astInitMatrixMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadMatrixMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadMatrixMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckMatrixMap to validate MatrixMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astMtrRot(this,theta,axis) \ -astINVOKE(O,astMtrRot_(astCheckMatrixMap(this),theta,axis,STATUS_PTR)) - -#define astMtrMult(this,a) \ -astINVOKE(O,astMtrMult_(astCheckMatrixMap(this),astCheckMatrixMap(a),STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/memory.c b/ast/memory.c deleted file mode 100644 index 2339e8c..0000000 --- a/ast/memory.c +++ /dev/null @@ -1,5470 +0,0 @@ -/* -* Name: -* memory.c - -* Purpose: -* Implement memory allocation/deallocation functions. - -* Description: -* This file implements the Memory module which is used for -* allocating and freeing memory in the AST library. For a -* description of the module and its interface, see the .h file of -* the same name. - -* Note, it is assumed that malloc, free and realloc are thread-safe. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009-2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: D.S. Berry (Starlink) - -* History: -* 2-JAN-1996 (RFWS): -* Original version. -* 26-JAN-1996 (RFWS): -* Removed trailing underscores from static functions and -* changed to use new error function interfaces. -* 20-JUN-1996 (RFWS): -* Added astString. -* 15-JUL-1996 (RFWS): -* Make IsDynamic execute under error conditions to avoid memory -* leaks in such situations. -* 11-SEP-1996 (RFWS): -* Added astStringArray (original written by DSB). -* 18-MAR-1998 (RFWS): -* Added notes about these functions being available for writing -* foreign language and graphics interfaces, etc. -* 29-JAN-2002 (DSB): -* Added astChrLen and astSscanf. -* 15-FEB-2002 (DSB): -* Removed use of non-ANSI vsscanf from astSscanf. -* 15-NOV-2002 (DSB): -* Moved ChrMatch from SkyFrame (etc) to here. Included stdio.h and -* ctype.h. -* 10-FEB-2003 (DSB): -* Added facilities for detecting and tracing memory leaks. These -* are only included if AST is compiled with the -DDEBUG flag. -* 3-MAR-2004 (DSB): -* Modified astSscanf to avoid use of uninitialised values -* corresponding to "%n" fields in the format string. -* 26-JAN-2004 (DSB): -* Modified astRealloc to clarify the nature of the returned pointer -* (which is not a "Memory *"). Also correct issuing and deissuing -* of pointers in DEBUG code within astRealloc. -* 16-FEB-2006 (DSB): -* Convert Magic from a function to a macro for extra speed. -* 21-FEB-2006 (DSB): -* Convert IsDynamic from a function to a macro for extra speed. -* 23-FEB-2006 (DSB): -* Added the caching system for allocated but unused memory blocks, -* controlled by AST tuning parameter MemoryCaching. -* 2-MAR-2006 (DSB): -* Added astFlushMemory, and renamed the memory debugging functions. -* These are now conditionally compiled if the MEM_DEBUG macros is -* defined (set by configuring AST with the --with-memdebug option). -* Also modified them to take into account MemoryCaching. -* 24-MAY-2006 (DSB): -* Ensure that pointers to memory returned by this module are all -* aligned on 8 byte boundaries. This fixes problems with ualigned -* memory access that could cause bus errors on Solaris. -* 26-MAY-2006 (DSB): -* Cast (void *) pointers to (char *) before doing arithmetic on -* them (changes supplied by Micah Johnson). -* 4-DEC-2006 (DSB): -* Fix bug in astMalloc that caused a non-null pointer to be -* returned on error. -* 4-JAN-2007 (DSB): -* Move definition of astCLASS macro so that it comes before the -* inclusion of the AST include files (which test for astCLASS). -* 27-JUN-2007 (DSB): -* Added astIsDynamic. -* 24-OCT-2007 (DSB): -* Zero the size of memory blocks stored in the Cache so that an -* error will be reported if an attempt is made to free a memory -* block that has already been freed. -* 25-OCT-2007 (DSB): -* Added astRemoveLeadingBlanks. -* 28-FEB-2008 (DSB): -* Added astChrSub. -* 17-MAR-2008 (DSB): -* Added "{nnn}" quantifier to astChrSub. -* 27-MAR-2008 (DSB): -* Added astChrSplitRE, and re-structured regexp functions. -* 18-NOV-2008 (DSB): -* In astFlushMemory, do not release permanent memory blocks as -* they may still be needed. -* 9-FEB-2009 (DSB): -* Added astChr2Double. -* 25-JUN-2009 (DSB): -* Fix handling of escape characters in astSplitC. -* 19-MAY-2010 (DSB): -* - Added astStringCase. -* - Changed access from protected to public for commonly used -* functions. -* 26-MAY-2010 (DSB): -* Added astCalloc. -* 18-AUG-2010 (DSB): -* Added astMemoryStats -* 19-AUG-2010 (DSB): -* Added astMemoryWarning -* 8-OCT-2010 (DSB): -* Modify memory allocation to use "calloc" directly, rather than -* using "malloc+memset". -* 12-APR-2011 (DSB): -* Fix regular expression problem where a ".*" template field failed to -* match a null string if it occurred before a closing parenthesis at -* the end of the template. -* 26-MAY-2011 (DSB): -* - Changed API for astCalloc to match RTL (i.e. remove "init"). -* - Changed astChr2Double to check for strigs like "2.", which -* some sscanfs fail to read as a floating point value. -* 27-MAY-2011 (DSB): -* Added astFreeDouble to free a dynamically allocated array of -* pointers to other dynamically allocated arrays. -* 21-JUN-2011 (DSB): -* Added astCheckMemory - an alternative to astFlushMemory that does -* not free any memory. -* 21-NOV-2011 (DSB): -* Correct matchend value returned by astChrSplitRE. -* 6-JAN-2014 (DSB): -* Optimise access to cache to avoid valgrind warnings. -* 16-JAN-2014 (DSB): -* Dump details of all active memory blocks if the total memory allocation -* specified by astMemoryWarning is exceeded. -* 23-SEP-2014 (DSB): -* Modify astAppendString to allow printf conversion specifications to -* be included in the appended string. -* 20-OCT-2014 (DSB): -* Revert the change to astAppendString made on 23-SEP-2014 as it is -* insecure. Instead add new function astAppendStringf. -* 26-MAR-2015 (DSB): -* Added astChrTrunc. -* 17-MAR-2017 (DSB): -* Remove unnecessary checks that supplied size_t argument values -* are not less than zero - size_t is unsigned and so is never negative. -*/ - -/* Configuration results. */ -/* ---------------------- */ -#if HAVE_CONFIG_H -#include -#endif - -/* Module Macros. */ -/* ============== */ -/* Define the astCLASS macro (even although this is not a class - implementation) to obtain access to the protected error handling - functions. */ -#define astCLASS memory - -/* The maximum number of fields within a format string allowed by astSscanf. */ -#define VMAXFLD 20 - -/* The maximum number of nested astBeginPM/astEndPM contexts. */ -#define PM_STACK_MAXSIZE 20 - -/* Select the appropriate memory management functions. These will be the - system's malloc, calloc, free and realloc unless AST was configured with - the "--with-starmem" option, in which case they will be the starmem - malloc, calloc, free and realloc. */ -#ifdef HAVE_STAR_MEM_H -# include -# define MALLOC starMalloc -# define CALLOC starCalloc -# define FREE starFree -# define REALLOC starRealloc -#else -# define MALLOC malloc -# define CALLOC calloc -# define FREE free -# define REALLOC realloc -#endif - - -#ifdef MEM_DEBUG -#define ISSUED "issued" -#define FREED "freed" -#endif - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "error.h" /* Error reporting facilities */ -#include "globals.h" /* Thread-specific global data */ -#include "memory.h" /* Interface to this module */ -#include "pointset.h" /* For AST__BAD */ - -#ifdef MEM_DEBUG -#include "object.h" /* For astMakePointer */ -#endif - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -#ifdef THREAD_SAFE -#include -#endif - -#ifdef MEM_PROFILE -#include -#endif - -/* Function Macros. */ -/* =============== */ -/* These are defined as macros rather than functions to avoid the - overhead of a function call since they are called extremely frequently. */ - -/* -* Name: -* IS_DYNAMIC - -* Purpose: -* Test whether a memory region has been dynamically allocated. - -* Type: -* Private macro - -* Synopsis: -* #include "memory.h" -* IS_DYNAMIC( ptr, dynamic ) - -* Description: -* This macro takes a pointer to a region of memory and tests if -* the memory has previously been dynamically allocated using other -* functions from this module. It does this by checking for the -* presence of a "magic" number in the header which precedes the -* allocated memory. If the magic number is not present (or the -* pointer is invalid for any other reason), an error is reported -* and the global error status is set. -* -* The result of the test is written to the variable specified by "res". - -* Parameters: -* ptr -* Pointer to the start (as known to the external user) of the -* dynamically allocated memory. -* dynamic -* Name of an "int" variable to recieve the result of the test. -* If the memory was allocated dynamically, a value of 1 is -* stored in this variable. Otherwise, zero is stored and an error -* results. - -* Notes: -* - A NULL pointer value produces an error report from this -* function, although other functions may wish to regard a NULL -* pointer as valid. -* - This function attempts to execute even if the global error -* status is set, although no further error report will be made if -* the memory is not dynamically allocated under these -* circumstances. -* - The test performed by this function is not 100% secure as the -* "magic" value could occur by accident (although this is -* unlikely). It is mainly intended to provide security against -* programming errors, including accidental corruption of the -* memory header and attempts to allocate the same region of memory -* more than once. -*/ - -#define IS_DYNAMIC(ptr,dynamic) \ -\ -/* Initialise. */ \ - dynamic = 0; \ -\ -/* Check that a NULL pointer has not been supplied and report an error \ - if it has (but not if the global status is already set). */ \ - if ( !ptr ) { \ - if ( astOK ) { \ - astError( AST__PTRIN, "Invalid NULL pointer (address %p).", status, ptr ); \ - } \ -\ -/* If OK, derive a pointer to the memory header that precedes the \ - allocated region of memory. */ \ - } else { \ - Memory *isdynmem; /* Pointer to memory header */ \ - isdynmem = (Memory *) ( (char *) ptr - SIZEOF_MEMORY ); \ -\ -/* Check if the "magic number" in the header is valid and report an \ - error if it is not (but not if the global status is already \ - set). */ \ - if ( isdynmem->magic != MAGIC( isdynmem, isdynmem->size ) ) { \ - if ( astOK ) { \ - astError( AST__PTRIN, \ - "Invalid pointer or corrupted memory at address %p.", status, \ - ptr ); \ - } \ -\ -/* Note if the magic number is OK. */ \ - } else { \ - dynamic = 1; \ - } \ - } - - - -/* -* Name: -* MAGIC - -* Purpose: -* Generate a "magic number". - -* Type: -* Private macro. - -* Synopsis: -* #include "memory.h" -* unsigned long MAGIC( void *ptr, size_t size ) - -* Description: -* This macro generates a "magic number" which is a function of -* a memory address and an object size. This number may be stored -* in a region of dynamically allocated memory to allow it to be -* recognised as dynamically allocated by other routines, and also -* to provide security against memory leaks, etc. - -* Parameters: -* ptr -* The memory pointer. -* size -* The object size. - -* Returned Value: -* The function returns the magic number. - -* Notes: -* This function does not perform error checking. -*/ - -/* Form the bit-wise exclusive OR between the memory address and the - object size, then add 1 and invert the bits. Return the result as - an unsigned long integer. */ -#define MAGIC(ptr,size) \ - ( ~( ( ( (unsigned long) ptr ) ^ ( (unsigned long) size ) ) + \ - ( (unsigned long) 1 ) ) ) - -/* A macro that returns the size of the a Memory structure padded to a - multiple of 8 bytes. */ -#define SIZEOF_MEMORY \ - ( ( sizeof_memory != 0 ) ? sizeof_memory : SizeOfMemory( status ) ) - - -/* Type Definitions. */ -/* ================= */ - -#ifdef MEM_PROFILE - -/* Structure used to record the time spent between matching calls to - astStartTimer and astStopTimer. */ -typedef struct AstTimer { - int id; /* Unique integer identifier for timer */ - clock_t e0; /* Absolute elapsed time at timer start */ - clock_t u0; /* Absolute user time at timer start */ - clock_t s0; /* Absolute system time at timer start */ - clock_t et; /* Cumulative elapsed time within timer */ - clock_t ut; /* Cumulative user time within timer */ - clock_t st; /* Cumulative system time within timer */ - int nentry; /* Number of entries into the timer */ - const char *name; /* An identifying label for the timer */ - const char *file; /* Name of source file where timer was started */ - int line; /* Source file line no. where timer was started */ - struct AstTimer *parent; /* The parent enclosing timer */ - int nchild; /* Number of child timers */ - struct AstTimer **children;/* Timers that count time within this timer */ -} AstTimer; - -#endif - -/* Module Variables. */ -/* ================= */ - -/* Extra stuff for profiling (can only be used in single threaded - environments). */ -#ifdef MEM_PROFILE -static AstTimer *Current_Timer = NULL; -static int Enable_Timers = 0; -static int Timer_Count = 0; -#endif - -/* Extra stuff for debugging of memory management (tracking of leaks - etc). */ -#ifdef MEM_DEBUG - -/* The identifier for the memory block which is to be tracked. */ -static int Watched_ID = -1; - -/* The next integer to use to identify an active memory block pointer. */ -static int Next_ID = -1; - -/* Indicates if future memory allocations are permanent (i.e. will not - usually be freed explicitly by AST). */ -static int Perm_Mem = 0; - -/* A "first in, last out" stack of Perm_Mem values used by nested - astBeginPM/astEndPM contexts. */ -static int PM_Stack[ PM_STACK_MAXSIZE ]; - -/* The number of values currently in the PM_Stack array. */ -static int PM_Stack_Size = 0; - -/* A pointer to a double linked list holding pointers to currently active - memory blocks (i.e. memory blocks for which a pointer has been issued - but not yet freed). This does not include the memory blocks in the - Cache array (these are not considered to be active). */ -static Memory *Active_List = NULL; - -/* Should a new ID be issued each time a cached memory block is returned - by astMalloc? Otherwise, the same ID value is used throughout the - life of a memory block. */ -static int Keep_ID = 0; - -/* Suppress all memory use reports except for issuing and freeing? */ -static int Quiet_Use = 0; - -/* Report the ID of every cached block when the cache is emptied? */ -static int List_Cache = 0; - -/* Memory allocation at which to issue a warning. */ -static size_t Warn_Usage = 0; - -/* Current memory allocated by AST. */ -static size_t Current_Usage = 0; - -/* Peak memory allocated by AST. */ -static size_t Peak_Usage = 0; - -#ifdef THREAD_SAFE -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_DEBUG_MUTEX pthread_mutex_lock( &mutex2 ); -#define UNLOCK_DEBUG_MUTEX pthread_mutex_unlock( &mutex2 ); -#else -#define LOCK_DEBUG_MUTEX -#define UNLOCK_DEBUG_MUTEX -#endif - -#endif - -/* Define macros for accessing all items of thread-safe global data - used by this module. */ -#ifdef THREAD_SAFE - -#define sizeof_memory astGLOBAL(Memory,Sizeof_Memory) -#define cache astGLOBAL(Memory,Cache) -#define cache_init astGLOBAL(Memory,Cache_Init) -#define use_cache astGLOBAL(Memory,Use_Cache) - -/* Define the initial values for the global data for this module. */ -#define GLOBAL_inits \ - globals->Sizeof_Memory = 0; \ - globals->Cache_Init = 0; \ - globals->Use_Cache = 0; \ - -/* Create the global initialisation function. */ -astMAKE_INITGLOBALS(Memory) - -/* If thread safety is not needed, declare globals at static variables. */ -/* -------------------------------------------------------------------- */ -#else - -/* The size of a Memory header structure, padded to a multiple of 8 - bytes. This value is initialised by the SizeOfMemory function, and - should be accessed using the SIZEOF_MEMORY macro. */ -static size_t sizeof_memory = 0; - -/* A cache of allocated but currently unused memory block. This cache is - maintained in order to avoid the overhead of continual calls to malloc to - allocate small blocks of memory. The vast majority of memory blocks - allocated by AST are under 200 bytes in size. Each element in this array - stores a pointer to the header for a free (i.e. allocated but currently - unused) memory block. The size of the memory block (not including the - Memory header) will equal the index at which the pointer is stored within - "cache". Each free memory block contains (in its Memory header) a pointer - to the header for another free memory block of the same size (or a NULL - pointer if there are no other free memory blocks of the same size). */ -static Memory *cache[ MXCSIZE + 1 ]; - -/* Has the "cache" array been initialised? */ -static int cache_init = 0; - -/* Should the cache be used? */ -static int use_cache = 0; - -#endif - -/* Prototypes for Private Functions. */ -/* ================================= */ -static size_t SizeOfMemory( int * ); -static char *CheckTempStart( const char *, const char *, const char *, char *, int *, int *, int *, int *, int *, int *, int *, int * ); -static char *ChrMatcher( const char *, const char *, const char *, const char *, const char *[], int, int, int, char ***, int *, const char **, int * ); -static char *ChrSuber( const char *, const char *, const char *[], int, int, char ***, int *, const char **, int * ); - -#ifdef MEM_DEBUG -static void Issue( Memory *, int * ); -static void DeIssue( Memory *, int * ); -#endif - -#ifdef MEM_PROFILE -static AstTimer *ReportTimer( AstTimer *, int, AstTimer **, int *, int * ); -static int CompareTimers( const void *, const void * ); -static int CompareTimers2( const void *, const void * ); -#endif - -/* Function implementations. */ -/* ========================= */ -char *astAppendString_( char *str1, int *nc, const char *str2, int *status ) { -/* -*++ -* Name: -* astAppendString - -* Purpose: -* Append a string to another string which grows dynamically. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* char *astAppendString( char *str1, int *nc, const char *str2 ) - -* Description: -* This function appends one string to another dynamically -* allocated string, extending the dynamic string as necessary to -* accommodate the new characters (plus the final null). - -* Parameters: -* str1 -* Pointer to the null-terminated dynamic string, whose memory -* has been allocated using an AST memory allocation function. -* If no space has yet been allocated for this string, a NULL -* pointer may be given and fresh space will be allocated by this -* function. -* nc -* Pointer to an integer containing the number of characters in -* the dynamic string (excluding the final null). This is used -* to save repeated searching of this string to determine its -* length and it defines the point where the new string will be -* appended. Its value is updated by this function to include -* the extra characters appended. -* -* If "str1" is NULL, the initial value supplied for "*nc" will -* be ignored and zero will be used. -* str2 -* Pointer to a constant null-terminated string, a copy of which -* is to be appended to "str1". - -* Returned Value: -* astAppendString() -* A possibly new pointer to the dynamic string with the new string -* appended (its location in memory may have to change if it has to -* be extended, in which case the original memory is automatically -* freed by this function). When the string is no longer required, -* its memory should be freed using astFree. - -* Notes: -* - If this function is invoked with the global error status set -* or if it should fail for any reason, then the returned pointer -* will be equal to "str1" and the dynamic string contents will be -* unchanged. -*-- -*/ - - -/* Local Variables: */ - char *result; /* Pointer value to return */ - int len; /* Length of new string */ - -/* Initialise. */ - result = str1; - -/* If the first string pointer is NULL, also initialise the character - count to zero. */ - if ( !str1 ) *nc = 0; - -/* Check the global error status. */ - if ( !astOK || !str2 ) return result; - -/* Calculate the total string length once the two strings have been - concatenated. */ - len = *nc + (int) strlen( str2 ); - -/* Extend the first (dynamic) string to the required length, including - a final null. Save the resulting pointer, which will be - returned. */ - result = astGrow( str1, len + 1, sizeof( char ) ); - -/* If OK, append the second string and update the total character - count. */ - if ( astOK ) { - (void) strcpy( result + *nc, str2 ); - *nc = len; - } - -/* Return the result pointer. */ - return result; -} - -char *astAppendStringf_( char *str1, int *nc, const char *str2, ... ) { -/* -*++ -* Name: -* astAppendStringf - -* Purpose: -* Append a string to another string, allowing printf format specifiers. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* char *astAppendStringf( char *str1, int *nc, const char *str2, ... ) - -* Description: -* This function appends one string to another dynamically -* allocated string, extending the dynamic string as necessary to -* accommodate the new characters (plus the final null). It is the -* same as astAppendString, except that the "str2" string ay include -* printf format specifiers. - -* Parameters: -* str1 -* Pointer to the null-terminated dynamic string, whose memory -* has been allocated using an AST memory allocation function. -* If no space has yet been allocated for this string, a NULL -* pointer may be given and fresh space will be allocated by this -* function. -* nc -* Pointer to an integer containing the number of characters in -* the dynamic string (excluding the final null). This is used -* to save repeated searching of this string to determine its -* length and it defines the point where the new string will be -* appended. Its value is updated by this function to include -* the extra characters appended. -* -* If "str1" is NULL, the initial value supplied for "*nc" will -* be ignored and zero will be used. -* str2 -* Pointer to a constant null-terminated string, a copy of which -* is to be appended to "str1". It may contain format -* specifications such as used with the C "printf" family of -* functions. -* ... -* Additional optional arguments (as used by e.g. "printf") -* which specify values which are to be substituted into the "str2" -* string in place of any format specifications. - -* Returned Value: -* astAppendString() -* A possibly new pointer to the dynamic string with the new string -* appended (its location in memory may have to change if it has to -* be extended, in which case the original memory is automatically -* freed by this function). When the string is no longer required, -* its memory should be freed using astFree. - -* Notes: -* - If this function is invoked with the global error status set -* or if it should fail for any reason, then the returned pointer -* will be equal to "str1" and the dynamic string contents will be -* unchanged. -*-- -*/ - -/* Local Variables: */ - char *pbuf; /* Pointer to buffer for expanded "str2" */ - char *result; /* Pointer value to return */ - char buf[1000]; /* A large buffer for the expanded "str2" */ - int *status; /* Pointer to inherited status variable */ - int buf_size; /* Size of buffer for expanded "str2" */ - int len; /* Length of new string */ - int nexp; /* Number of characters written to "pbuf". */ - va_list args; /* Variable argument list pointer */ - -/* Initialise. */ - result = str1; - -/* If the first string pointer is NULL, also initialise the character - count to zero. */ - if( !str1 ) *nc = 0; - -/* Get a pointer to the integer holding the inherited status value. This - function cannot have a "status" argument like most other functions - because of the variable argument list. */ - status = astGetStatusPtr; - -/* Check the global error status. */ - if ( !astOK || !str2 ) return result; - -/* If available use vsnprintf to determine the amount of memory needed to - hold the expanded version of "str2". Then allocate the required memory. */ -#if HAVE_VSNPRINTF - va_start( args, str2 ); - buf_size = vsnprintf( buf, sizeof( buf ), str2, args ) + 1; - va_end( args ); - pbuf = astMalloc( buf_size ); - -/* Otherwise, all we can do is use a big buffer and hope for the best. */ -#else - buf_size = sizeof( buf ); - pbuf = buf; -#endif - -/* Expand any conversion specifications in "str2". */ - va_start( args, str2 ); - nexp = vsprintf( pbuf, str2, args ); - va_end( args ); - -/* Check that the result buffer did not overflow (should only be - possible if vsnprintf is not available). If it did, memory may - have been corrupted. Report the error and abort. */ - if( nexp >= buf_size ) { - if( astOK ) astError( AST__ATSER, "astAppendString: Internal buffer " - "overflow while appending a string - the " - "result exceeds %d characters.", status, - buf_size - 1 ); - } - -/* Calculate the total string length once the two strings have been - concatenated. */ - len = *nc + nexp; - -/* Extend the first (dynamic) string to the required length, including - a final null. Save the resulting pointer, which will be - returned. */ - result = astGrow( str1, len + 1, sizeof( char ) ); - -/* If OK, append the second string and update the total character - count. */ - if ( astOK ) { - (void) strcpy( result + *nc, pbuf ); - *nc = len; - } - -/* If required, free the buffer holding the expanded version of "str2". */ -#if HAVE_VSNPRINTF - pbuf = astFree( pbuf ); -#endif - -/* Return the result pointer. */ - return result; -} - -void *astCalloc_( size_t nmemb, size_t size, int *status ) { -/* -*++ -* Name: -* astCalloc - -* Purpose: -* Allocate and initialise memory. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void *astCalloc( size_t nmemb, size_t size ) - -* Description: -* This function allocates memory in a similar manner to the -* standard C "calloc" function, but with improved security -* (against memory leaks, etc.) and with error reporting. It also -* fills the allocated memory with zeros. -* -* Like astMalloc, it allows zero-sized memory allocation -* (without error), resulting in a NULL returned pointer value. - -* Parameters: -* nmemb -* The number of array elements for which memory is to be allocated. -* size -* The size of each array element, in bytes. - -* Returned Value: -* astCalloc() -* If successful, the function returns a pointer to the start of -* the allocated memory region. If the size allocated is zero, this -* will be a NULL pointer. - -* Notes: -* - A pointer value of NULL is returned if this function is -* invoked with the global error status set or if it fails for any -* reason. -*-- -*/ -/* Local Variables: */ - void *result; /* Returned pointer */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Attempt to allocate and initialise the required amount of memory. */ - result = astMallocInit( nmemb*size ); - -/* If the above call failed due to failure of the system malloc function, - issue an extra error giving the number of elements and element size. */ - if( astStatus == AST__NOMEM ) { - astError( AST__NOMEM, "(%lu elements, each of %lu bytes).", status, - (unsigned long) nmemb, (unsigned long) size ); - } - -/* Return the result. */ - return result; -} - -static char *CheckTempStart( const char *template, const char *temp, - const char *pattern, - char *allowed, int *ntemp, int *allow, - int *min_nc, int *max_nc, int *start_sub, - int *end_sub, int *greedy, int *status ){ -/* -* Name: -* CheckTempStart - -* Purpose: -* Examine the leading field in an astChrSub template. - -* Type: -* Private function. - -* Synopsis: -* char *CheckTempStart( const char *template, const char *temp, -* const char *pattern, -* char *allowed, int *ntemp, int *allow, -* int *min_nc, int *max_nc, int *start_sub, -* int *end_sub, int *greedy, int *status ) - -* Description: -* This function returns inforation about the leading field in a -* template string supplied to astChrSub. - -* Parameters: -* template -* The full template string (used for error messages). -* temp -* Pointer to the next character to read from the template string. -* pattern -* Pointer to the user supplied pattern string (only used in error -* messages). -* allowed -* Pointer to a buffer in which to store a string of characters -* that the leading temeplate field will match. A NULL pointer may -* be supplied in which case new memory will be allocated. The -* supplied memory is expanded as necessary, and a pointer to it is -* returned as the function value. -* ntemp -* Address of an int in which to return the number of characters -* consumed from the start of "temp". -* allow -* Address of an int in which to return a flag which is non-zero if -* the returned string contains characters that are allowed in the -* test field, or zero if the returned string contains characters that -* are disallowed in the test field. -* min_nc -* Address of an int in which to return the minimum number of -* test characters that must belong to the returned set of -* allowed characters. -* max_nc -* Address of an int in which to return the maximum number of -* test characters that must belong to the returned set of -* allowed characters. -* start_sub -* Address of an int in which to return a flag which is non-zero if -* the leading template field indicates the start of a field to be -* substituted. In this case the supplied "allowed" pointer is -* returned without change as the function value, "Min_nc" is -* returned as zero, and max_nc is returned as zero. -* end_sub -* Address of an int in which to return a flag which is non-zero if -* the leading template field indicates the end of a field to be -* substituted. In this case the supplied "allowed" pointer is -* returned without change as the function value, "Min_nc" is -* returned as zero, and limit is returned as zero. -* greedy -* Address of an int in which to return a flag which is non-zero if -* the template starts with a greedy quantifier. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a (possibly newly allocated) memory area holding a -* string of characters that the leading temeplate field will match. -* This string should be released using astFree when no longer needed. -* If a NULL pointyer is returned, then all characters are allowed -* (or disallowed if "*allow" is zero). - -* Notes: -* - The returned value is also stored in the module variable -* sizeof_memory. -*/ - -/* Local Variables: */ - char *result; - const char *start; - const char *end; - -/* Initialise. */ - result = allowed; - *ntemp = 0; - *allow = 1; - *min_nc = 0; - *max_nc = 0; - *start_sub = 0; - *end_sub = 0; - *greedy = 1; - -/* Check global status */ - if( !astOK ) return result; - -/* If the next character is an opening parenthesis, this marks the start - of a substitution field. */ - if( *temp == '(' ) { - *start_sub = 1; - *ntemp = 1; - -/* If the next character is an closing parenthesis, this marks the end - of a substitution field. */ - } else if( *temp == ')' ) { - *end_sub = 1; - *ntemp = 1; - -/* If the next character is an opening bracket, this marks the start of a - field of allowed or disallowed characters. */ - } else { - if( *temp == '[' ) { - -/* If the first character in the brackets is "^" this is a field of - disallowed characters, otherwise they are allowed. */ - if( temp[ 1 ] == '^' ) { - *allow = 0; - start = temp + 2; - } else { - start = temp + 1; - } - -/* Get a pointer to the closing bracket. */ - end = strchr( temp, ']' ); - -/* Copy the intervening string into the returned string. */ - if( end ) { - result = astStore( allowed, start, end - start + 1 ); - if( result ) result[ end - start ] = 0; - -/* Report an error if no closing bracket was found. */ - } else { - astError( AST__BADSUB, "Invalid pattern matching template \"%s\": " - "missing ']'.", status, pattern ); - } - -/* Indicate how many template characters have been used. */ - *ntemp = end - temp + 1; - -/* A single dot matches any character. */ - } else if( *temp == '.' ) { - result = astFree( result ); - *ntemp = 1; - -/* Now deal with escape sequences. */ - } else if( *temp == '\\' ) { - -/* Digits... */ - if( temp[ 1 ] == 'd' || temp[ 1 ] == 'D' ) { - result = astStore( allowed, "0123456789", 11 ); - result[ 10 ] = 0; - if( temp[ 1 ] == 'D' ) *allow = 0; - -/* White space... */ - } else if( temp[ 1 ] == 's' || temp[ 1 ] == 'S' ) { - result = astStore( allowed, " \n\r", 5 ); - result[ 4 ] = 0; - if( temp[ 1 ] == 'S' ) *allow = 0; - -/* Word characters... */ - } else if( temp[ 1 ] == 'w' || temp[ 1 ] == 'W' ) { - result = astStore( allowed, "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", - 64 ); - result[ 63 ] = 0; - if( temp[ 1 ] == 'W' ) *allow = 0; - -/* Any other character is treated literally. */ - } else { - result = astStore( allowed, temp + 1, 2 ); - result[ 1 ] = 0; - } - -/* Set number of template characters consumed. */ - *ntemp = 2; - -/* Everything else must be matched literally. */ - } else { - - if( *temp == '*' || *temp == '?' || *temp == '+' ){ - astError( AST__BADSUB, "Invalid pattern matching template \"%s\": " - "field starts with '%c'.", status, pattern, temp[ *ntemp ] ); - } else { - result = astStore( allowed, temp, 2 ); - result[ 1 ] = 0; - *ntemp = 1; - } - - } - -/* Now see if there is any quantifier. */ - if( temp[ *ntemp ] == '*' ) { - *min_nc = 0; - *max_nc = INT_MAX; - (*ntemp)++; - if( temp[ *ntemp ] == '?' ){ - *greedy = 0; - (*ntemp)++; - } - - } else if( temp[ *ntemp ] == '+' ) { - *min_nc = 1; - *max_nc = INT_MAX; - (*ntemp)++; - if( temp[ *ntemp ] == '?' ){ - *greedy = 0; - (*ntemp)++; - } - - } else if( temp[ *ntemp ] == '?' ) { - *min_nc = 0; - *max_nc = 1; - (*ntemp)++; - - } else { - -/* See if the remaining string starts with "{nnn}". If so, extract the - "nnn" and use it as the minimum and maximum field length. */ - if( temp[ *ntemp ] == '{' ) { - - start = temp + *ntemp + 1; - while( isdigit( (int) *start ) ) { - *min_nc = 10*( *min_nc ) + (int )( ( *start ) - '0' ); - start++; - } - - if( *start == '}' ) { - *max_nc = *min_nc; - *ntemp = start - temp + 1; - } else { - start = NULL; - } - - } else { - start = NULL; - } - -/* If the remaining string does not start with "{nnn}", use a minimum and - maximum field length of 1. */ - if( !start ) { - *min_nc = 1; - *max_nc = 1; - } - } - } - -/* Return the string of allowed characters. */ - return result; -} - -double astChr2Double_( const char *str, int *status ) { -/* -*++ -* Name: -* astChr2Double - -* Purpose: -* read a double value from a string. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* double astChr2Double( const char *str ) - -* Description: -* This function reads a double from the supplied null-terminated string, -* ignoring leading and trailing white space. AST__BAD is ereturned -* without error if the string is not a numerical value. - -* Parameters: -* str -* Pointer to the string. - -* Returned Value: -* astChr2Double() -* The double value, or AST__BAD. - -* Notes: -* - A value of AST__BAD is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*-- -*/ - -/* Local Variables: */ - double result; /* The returned value */ - int ival; /* Integer value read from string */ - int len; /* Length of supplied string */ - int nc; /* Number of characters read from the string */ - -/* Check the global error status and supplied pointer. */ - if ( !astOK || !str ) return AST__BAD; - -/* Save the length of the supplied string. */ - len = strlen( str ); - -/* Use scanf to read the floating point value. This fails if either 1) the - string does not begin with a numerical value (in which case astSscanf - returns zero), or 2) there are non-white characters following the - numerical value (in which case "nc" - the number of characters read from - the string - is less than the length of the string). */ - if ( nc = 0, - ( 1 != astSscanf( str, " %lg %n", &result, &nc ) ) || ( nc < len ) ) { - result = AST__BAD; - } - -/* If the above failed, try again allowing the string to be an integer - followed by a dot (e.g. "1."). Some implementations of sscanf do not - consider this to be a floating point value. */ - if( 1 || result == AST__BAD ) { - if ( nc = 0, - ( 1 == astSscanf( str, " %d. %n", &ival, &nc ) ) && ( nc >= len ) ) { - result = ival; - } - } - -/* Return the result. */ - return result; -} - -void astChrCase_( const char *in, char *out, int upper, int blen, int *status ) { -/* -*++ -* Name: -* astChrCase - -* Purpose: -* Convert a string to upper or lower case. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void astChrCase( const char *in, char *out, int upper, int blen, int *status ) - -* Description: -* This function converts a supplied string to upper or lower case, -* storing the result in a supplied buffer. The astStringCase function -* is similar, but stores the result in a dynamically allocated buffer. - -* Parameters: -* in -* Pointer to the null terminated string to be converted. If this -* is NULL, the supplied contents of the "out" string are used as -* the input string. -* out -* Pointer to the buffer to receive the converted string. The -* length of this buffer is given by "blen". If NULL is supplied -* for "in", then the supplied contents of "out" are converted and -* written back into "out" over-writing the supplied contents. -* upper -* If non-zero, the string is converted to upper case. Otherwise it -* is converted to lower case. -* blen -* The length of the output buffer. Ignored if "in" is NULL. No -* more than "blen - 1" characters will be copied from "in" to -* "out", and a terminating null character will then be added. - -*-- -*/ - -/* Local Variables: */ - const char *pin; - char *pout; - int i; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* The simple case of over-writing the supplied string. */ - if( ! in ) { - pout = out - 1; - while( *(++pout) ) *pout = toupper( (int) *pout ); - -/* If a separate output buffer has been supplied... */ - } else { - -/* Initialise pointers to the input and output buffers. */ - pin = in; - pout = out; - -/* Copy the string character by character, converting the case in the - process. Start counting from 1, not 0, in order to ensure that we are - left with room for a terminating null. */ - for( i = 1; i < blen && *pin; i++ ) { - *(pout++) = toupper( (int) *(pin++) ); - } - -/* Terminate the returned string. */ - *pout = 0; - } -} - -int astChrMatch_( const char *str1, const char *str2, int *status ) { -/* -*++ -* Name: -* astChrMatch - -* Purpose: -* Case insensitive string comparison. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* int astChrMatch( const char *str1, const char *str2 ) - -* Description: -* This function compares two null terminated strings for equality, -* discounting differences in case and any trailing white space in either -* string. - -* Parameters: -* str1 -* Pointer to the first string. -* str2 -* Pointer to the second string. - -* Returned Value: -* astChrMatch() -* Non-zero if the two strings match, otherwise zero. - -* Notes: -* - A value of zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*-- -*/ - -/* Local Variables: */ - int match; /* Strings match? */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise. */ - match = 1; - -/* Loop to compare characters in the two strings until a mis-match occurs or - we reach the end of the longer string. */ - while ( match && ( *str1 || *str2 ) ) { - -/* Two characters match if (a) we are at the end of one string and the other - string contains white space or (b) both strings contain the same character - when converted to lower case. */ - match = ( !*str1 && isspace( *str2 ) ) || - ( !*str2 && isspace( *str1 ) ) || - ( tolower( *str1 ) == tolower( *str2 ) ); - -/* Step through each string a character at a time until its end is reached. */ - if ( *str1 ) str1++; - if ( *str2 ) str2++; - } - -/* Return the result. */ - return match; -} - -int astChrMatchN_( const char *str1, const char *str2, size_t n, int *status ) { -/* -*++ -* Name: -* astChrMatchN - -* Purpose: -* Case insensitive string comparison of at most N characters - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* int astChrMatchN( const char *str1, const char *str2, size_t n ) - -* Description: -* This function compares two null terminated strings for equality, -* discounting differences in case and any trailing white space in either -* string. No more than "n" characters are compared. - -* Parameters: -* str1 -* Pointer to the first string. -* str2 -* Pointer to the second string. -* n -* Maximum number of characters to compare. - -* Returned Value: -* astChrMatchN() -* Non-zero if the two strings match, otherwise zero. - -* Notes: -* - A value of zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*-- -*/ - -/* Local Variables: */ - int match; /* Strings match? */ - int nc; /* Number of characters compared so far */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise. */ - match = 1; - -/* So far we have compared zero characters */ - nc = 0; - -/* Loop to compare characters in the two strings until a mis-match occurs or - we reach the end of the longer string, or we reach the specified - maximum number of characters. */ - while ( match && ( *str1 || *str2 ) && nc++ < n ) { - -/* Two characters match if (a) we are at the end of one string and the other - string contains white space or (b) both strings contain the same character - when converted to lower case. */ - match = ( !*str1 && isspace( *str2 ) ) || - ( !*str2 && isspace( *str1 ) ) || - ( tolower( *str1 ) == tolower( *str2 ) ); - -/* Step through each string a character at a time until its end is reached. */ - if ( *str1 ) str1++; - if ( *str2 ) str2++; - } - -/* Return the result. */ - return match; -} - -char **astChrSplit_( const char *str, int *n, int *status ) { -/* -*++ -* Name: -* astChrSplit - -* Purpose: -* Extract words from a supplied string. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* char **astChrSplit_( const char *str, int *n ) - -* Description: -* This function extracts all space-separated words form the supplied -* string and returns them in an array of dynamically allocated strings. - -* Parameters: -* str -* Pointer to the string to be split. -* n -* Address of an int in which to return the number of words returned. - -* Returned Value: -* astChrSplit() -* A pointer to a dynamically allocated array containing "*n" elements. -* Each element is a pointer to a dynamically allocated character -* string containing a word extracted from the supplied string. Each -* of these words will have no leading or trailing white space. - -* Notes: -* - A NULL pointer is returned if this function is invoked with the -* global error status set or if it should fail for any reason, or if -* the supplied string contains no words. -*-- -*/ - -/* Local Variables: */ - char **result; - char *w; - const char *p; - const char *ws; - int first; - int state; - int wl; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise. */ - result = NULL; - ws = NULL; - *n = 0; - -/* State 0 is "looking for the next non-white character which marks the - start of the next word". State 1 is "looking for the next white character - which marks the end of the current word". */ - state = 0; - -/* Loop through all characters in the supplied string, including the - terminating null. */ - p = str - 1; - first = 1; - while( *(p++) || first ) { - first = 0; - -/* If this is the terminating null or a space, and we are currently looking - for the end of a word, allocate memory for the new word, copy the text - in, terminate it, extend the returned array by one element, and store - the new word in it. */ - if( !*p || isspace( *p ) ) { - if( state == 1 ) { - wl = p - ws; - w = astMalloc( wl + 1 ); - if( w ) { - strncpy( w, ws, wl ); - w[ wl ] = 0; - result = astGrow( result, *n + 1, sizeof( char * ) ); - if( result ) result[ (*n)++ ] = w; - } - state = 0; - } - -/* If this is non-blank character, and we are currently looking for the - start of a word, note the address of the start of the word, and - indicate that we are now looking for the end of a word. */ - } else { - if( state == 0 ) { - state = 1; - ws = p; - } - } - } - -/* Return the result. */ - return result; -} - -char **astChrSplitC_( const char *str, char c, int *n, int *status ) { -/* -*++ -* Name: -* astChrSplitC - -* Purpose: -* Split a string using a specified character delimiter. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* char **astChrSplitC( const char *str, char c, int *n ) - -* Description: -* This function extracts all sub-strings separated by a given -* character from the supplied string and returns them in an array -* of dynamically allocated strings. The delimiter character itself -* is not included in the returned strings. -* -* Delimiter characters that are preceded by "\" are not used as -* delimiters but are included in the returned word instead (without -* the "\"). - -* Parameters: -* str -* Pointer to the string to be split. -* c -* The delimiter character. -* n -* Address of an int in which to return the number of words returned. - -* Returned Value: -* astChrSplitC() -* A pointer to a dynamically allocated array containing "*n" elements. -* Each element is a pointer to a dynamically allocated character -* string containing a word extracted from the supplied string. - -* Notes: -* - A NULL pointer is returned if this function is invoked with the -* global error status set or if it should fail for any reason, or if -* the supplied string contains no words. -*-- -*/ - -/* Local Variables: */ - char **result; - char *word; - const char *p; - int escaped; - int wordlen; - -/* Initialise returned values. */ - *n = 0; - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* More initialisations. */ - word = NULL; - wordlen = 0; - escaped = 0; - -/* Loop through all characters in the supplied string, including the - terminating null. */ - p = str; - while( *p ) { - -/* Is this a delimiter character? */ - if( *p == c ) { - -/* If it is escaped, it does not mark the end of a word. Put it into the - current output buffer instead, overwriting the escape character that - preceded it. */ - if( escaped ) { - word[ wordlen - 1 ] = c; - -/* The next character is not escaped. */ - escaped = 0; - -/* If the delimiter is not escaped, terminate the current word and store - a pointer to it in the returned array. */ - } else { - result = astGrow( result, *n + 1, sizeof( char * ) ); - word = astGrow( word, wordlen + 1, 1 ); - if( result && word ) { - word[ wordlen ] = 0; - result[ (*n)++ ] = word; - wordlen = 0; - word = NULL; - } - } - -/* If this is not a delimitier character, store it in the returned word. */ - } else { - word = astGrow( word, wordlen + 1, 1 ); - if( word ) word[ wordlen++ ] = *p; - -/* If the current character was escaped, indicate that the next character - is not escaped. */ - if( escaped ) { - escaped = 0; - -/* If this character is a unescaped backslash, set a flag indicating that the - next character is escaped. */ - } else if( *p == '\\' ){ - escaped = 1; - } - } - -/* Move on to the next character. */ - p++; - } - -/* Store the text following the final delimitier. */ - result = astGrow( result, *n + 1, sizeof( char * ) ); - word = astGrow( word, wordlen + 1, 1 ); - if( result && word ) { - word[ wordlen ] = 0; - result[ (*n)++ ] = word; - } - -/* Return the result. */ - return result; -} - -char **astChrSplitRE_( const char *str, const char *regexp, int *n, - const char **matchend, int *status ) { -/* -*++ -* Name: -* astChrSplitRE - -* Purpose: -* Extract sub-strings matching a specified regular expression. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* char **astChrSplitRE( const char *str, const char *regexp, int *n, -* const char **matchend ) - -* Description: -* This function compares the supplied string with the supplied -* regular expression. If they match, each section of the test string -* that corresponds to a parenthesised sub-string in the regular -* expression is copied and stored in the returned array. - -* Parameters: -* str -* Pointer to the string to be split. -* regexp -* The regular expression. See "Template Syntax:" in the astChrSub -* prologue. Note, this function differs from astChrSub in that any -* equals signs (=) in the regular expression are treated literally. -* n -* Address of an int in which to return the number of sub-strings -* returned. -* matchend -* A pointer to a location at which to return a pointer to the -* character that follows the last character within the supplied test -* string that matched any parenthesises sub-section of "regexp". A -* NULL pointer is returned if no matches were found. A NULL pointer -* may be supplied if the location of the last matching character is -* not needed. - -* Returned Value: -* astChrSplitRE() -* A pointer to a dynamically allocated array containing "*n" elements. -* Each element is a pointer to a dynamically allocated character -* string containing a sub-string extracted from the supplied string. -* The array itself, and the strings within it, should all be freed -* using astFree when no longer needed. - -* Notes: -* - If a parenthesised sub-string in the regular expression is matched -* by more than one sub-string within the test string, then only the -* first is returned. To return multiple matches, the regular -* expression should include multiple copies of the parenthesised -* sub-string (for instance, separated by ".+?" if the intervening -* string is immaterial). -* - A NULL pointer is returned if this function is invoked with the -* global error status set or if it should fail for any reason, or if -* the supplied string contains no words. -*-- -*/ - -/* Local Variables: */ - char **result; - char *temp; - int i; - -/* Initialise returned values. */ - *n = 0; - result = NULL; - -/* Check global status */ - if( !astOK ) return result; - -/* Call ChrSuber to do the work, saving the matching parts of the test - string. */ - temp = ChrSuber( str, regexp, NULL, 0, 1, &result, n, matchend, status ); - if( temp ) { - temp = astFree( temp ); - -/* Free all results if no match was found. */ - } else if( result ) { - for( i = 0; i < *n; i++ ) result[ i ] = astFree( result[ i ] ); - result = astFree( result ); - *n = 0; - } - -/* Return the result */ - return result; -} - -char *ChrSuber( const char *test, const char *pattern, const char *subs[], - int nsub, int ignore_equals, char ***parts, int *npart, - const char **matchend, int *status ){ -/* -* Name: -* ChrSuber - -* Purpose: -* Performs substitutions on a supplied string. - -* Type: -* Private function. - -* Synopsis: -* #include "memory.h" -* char *ChrSuber( const char *test, const char *pattern, -* const char *subs[], int nsub, int ignore_equals, -* char ***parts, int *npart, const char **matchend, -* int *status ) - -* Description: -* This function performs the work for astChrSub and astChrSplitRE. - -* Parameters: -* test -* The string to be tested. -* pattern -* The template string. See "Template Syntax:" in the astChrSub - prologue. -* subs -* An array of strings that are to replace the sections of the test -* string that match each parenthesised sub-string in "pattern". The -* first element of "subs" replaces the part of the test string that -* matches the first parenthesised sub-string in the template, etc. -* -* If "nsub" is zero, then the "subs" pointer is ignored. In this -* case, and if parameter "ignore_equals" is zero, substitution strings -* may be specified by appended them to the end of the "pattern" string, -* separated by "=" characters -* nsub -* The number of substitution strings supplied in array "subs". -* ignore_equals -* If non-zero, any equals signs in the supplied pattern are -* treated literally, rather than being used to split the template -* from any substitution strigs. -* parts -* Address of a location at which to return a pointer to an array -* of character string pointers. The strings are the sub-sections -* of "test" that matched the parenthesised sub-sections of -* "template". The array will have "*npart" elements. Ignored if NULL. -* npart -* Address of a location at which to return the length of the -* "parts" array. Ignored if "parts" is NULL. -* matchend -* A pointer to a location at which to return a pointer to the -* character that follows the last character within the supplied test -* string that matched any parenthesises sub-section of "regexp". A -* NULL pointer is returned if no matches were found. A NULL pointer -* may be supplied if the location of the last matching character is -* not needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated string holding the result -* of the substitutions, or NULL if the test string does not match -* the template string. This string should be freed using astFree -* when no longer needed. If no substituions are specified then a -* copy of the test string is returned if it matches the template. - -* Notes: -* - A NULL pointer is returned if this function is invoked with the -* global error status set or if it should fail for any reason, or if -* the supplied test string does not match the template. - -*/ - -/* Local Variables: */ - char **sections; - char **temps; - char *cptr; - char *result; - char *temp; - char *template; - int i; - int nsec; - int ntemp; - size_t tlen; - -/* Initialise */ - result = NULL; - if( parts ) *npart = 0; - -/* Check global status */ - if( !astOK ) return result; - -/* If required, split the total "pattern" string into sections, using - (unescaped) "=" characters as the delimiter. The first section is the - actual template, and each subsequent section (if any) holds a - substitution string. */ - if( ! ignore_equals ) { - sections = astChrSplitC( pattern, '=', &nsec ); - -/* If equals signs are being treated literally, just take a copy of the - supplied pattern. */ - } else { - cptr = astStore( NULL, pattern, strlen( pattern ) + 1 ); - sections = &cptr; - nsec = 1; - } - - if( sections ) { - -/* If the caller did not provide any substitution strings, use the ones - appended to the end of the pattern string (if any). */ - if( nsub == 0 ) { - subs = (void *) ( sections + 1 ); - nsub = nsec - 1; - } - -/* Split the template section into sub-sections, using (unescaped) "|" - characters as the delimiter. Each sub-section is an alternate pattern - matching template. */ - temps = astChrSplitC( sections[ 0 ], '|', &ntemp ); - - } else { - temps = 0; - ntemp = 0; - } - -/* Loop round each template until all templates have been checked or a - match occurs.. */ - for( i = 0; i < ntemp && !result; i++ ) { - temp = temps[ i ]; - tlen = strlen( temp ); - -/* If the template starts with "^" or "(^", remove the "^" character. - Otherwise insert ".*?" at the start. Allocate three extra characters - in case we later need to add ".*?" to the end of the string. */ - if( temp[ 0 ] == '^' ) { - template = astMalloc( tlen + 3 ); - if( template ) { - strcpy( template, temp + 1 ); - tlen--; - } - - } else if( temp[ 0 ] == '(' && temp[ 1 ] == '^') { - template = astMalloc( tlen + 3 ); - if( template ) { - template[ 0 ] = '('; - strcpy( template + 1, temp + 2 ); - tlen--; - } - - } else { - template = astMalloc( tlen + 7 ); - if( template ) { - template[ 0 ] = '.'; - template[ 1 ] = '*'; - template[ 2 ] = '?'; - strcpy( template + 3, temp ); - tlen += 3; - } - } - -/* If the pattern ends with "$" or "$)", remove the "$" character. Otherwise - insert ".*?" at the end. */ - if( template[ tlen - 1 ] == '$' ) { - tlen--; - - } else if( template[ tlen - 2 ] == '$' && template[ tlen - 1 ] == ')' ) { - template[ tlen - 2 ] = ')'; - tlen--; - - } else { - template[ tlen ] = '.'; - template[ tlen + 1 ] = '*'; - template[ tlen + 2 ] = '?'; - tlen += 3; - } - -/* Ensure the string is terminated */ - template[ tlen ] = 0; - -/* See if the test string matches the current template. */ - result = ChrMatcher( test, test + strlen( test ), template, pattern, - subs, nsub, 0, 1, parts, npart, matchend, status ); - -/* Free resources. */ - template = astFree( template ); - } - - if( temps ) { - for( i = 0; i < ntemp; i++ ) temps[ i ] = astFree( temps[ i ] ); - temps = astFree( temps ); - } - - if( sections ) { - for( i = 0; i < nsec; i++ ) sections[ i ] = astFree( sections[ i ] ); - if( ! ignore_equals ) sections = astFree( sections ); - } - -/* Return a NULL pointer if an error has occurred. */ - if( !astOK ) result = astFree( result ); - -/* Return the result */ - return result; -} - -char *astChrSub_( const char *test, const char *pattern, const char *subs[], - int nsub, int *status ){ -/* -*++ -* Name: -c astChrSub -f AST_CHRSUB - -* Purpose: -* Performs substitutions on a supplied string. - -* Type: -* Public function. - -* Synopsis: -c #include "memory.h" -c char *astChrSub( const char *test, const char *pattern, -c const char *subs[], int nsub ) -f MATCH = AST_CHRSUB( TEST, PATTERN, RESULT, STATUS ) - -* Description: -* This function checks a supplied test string to see if it matches a -* supplied template. If it does, specified sub-sections of the test -* string may optionally be replaced by supplied substitution strings. -* The resulting string is returned. - -* Parameters: -c test -f TEST = CHARACTER * ( * ) (Given) -* The string to be tested. -* pattern -f PATTERN = CHARACTER * ( * ) (Given) -* The template string. See "Template Syntax:" below. -* subs -* An array of strings that are to replace the sections of the test -* string that match each parenthesised sub-string in "pattern". The -* first element of "subs" replaces the part of the test string that -* matches the first parenthesised sub-string in the template, etc. -* -* If "nsub" is zero, then the "subs" pointer is ignored. In this -* case, substitution strings may be specified by appended them to -* the end of the "pattern" string, separated by "=" characters. -* Note, if you need to include a literal "=" character in the -* pattern, precede it by an escape "\" character. -* nsub -* The number of substitution strings supplied in array "subs". -f RESULT = CHARACTER * ( * ) (Returned) -f Returned holding the result of the substitutions. If the test -f string does not match the template, then a blank string is -f returned. - -* Returned Value: -c astChrSub() -c A pointer to a dynamically allocated string holding the result -c of the substitutions, or NULL if the test string does not match -c the template string. This string should be freed using astFree -c when no longer needed. If no substituions are specified then a -c copy of the test string is returned if it matches the template. -f AST_CHRSUB = LOGICAL -f .TRUE. if the test string matched the supplied template, and -f .FALSE. otherwise. - -* Template Syntax: -* The template syntax is a minimal form of regular expression, The -* quantifiers allowed are "*", "?", "+", "{n}", "*?" and "+?" (the -* last two are non-greedy - they match the minimum length possible -* that still gives an overall match to the template). The only -* constraints allowed are "^" and "$". The following atoms are allowed: -* -* - [chars]: Matches any of the specified characters. -* -* - [^chars]: Matches anything but the specified characters. -* -* - .: Matches any single character. -* -* - x: Matches the character x so long as x has no other significance. -* -* - \x: Always matches the character x (except for [dDsSwW]). -* -* - \d: Matches a single digit. -* -* - \D: Matches anything but a single digit. -* -* - \w: Matches any alphanumeric character, and "_". -* -* - \W: Matches anything but alphanumeric characters, and "_". -* -* - \s: Matches white space. -* -* - \S: Matches anything but white space. -* -* Note, minus signs ("-") within brackets have no special significance, -* so ranges of characters must be specified explicitly. -* -* Multiple template strings can be concatenated, using the "|" -* character to separate them. The test string is compared against -* each one in turn until a match is found. -* -c Parentheses are used within each template to identify sub-strings -c that are to be replaced by the strings supplied in "sub". -c -c If "nsub" is supplied as zero, then substitution strings may be -c specified by appended them to the end of the "pattern" string, -c separated by "=" characters. If "nsub" is not zero, then any -c substitution strings appended to the end of "pattern" are ignored. -f -f Parentheses are used within each template to identify sub-strings -f that are to be replaced by new strings. The new strings are -f specified by appended them to the end of the "pattern" string, -f separated by "=" characters. -* -c Each element of "subs" -f Each new string -* may contain a reference to a token of the -* form "$1", "$2", etc. The "$1" token will be replaced by the part -* of the test string that matched the first parenthesised sub-string -* in "pattern". The "$2" token will be replaced by the part of the -* test string that matched the second parenthesised sub-string in -* "pattern", etc. -* - -c Notes: -c - A NULL pointer is returned if this function is invoked with the -c global error status set or if it should fail for any reason, or if -c the supplied test string does not match the template. - -*-- -*/ - -/* Call ChrSuber to do the work, without saving the matching parts of the - test string. */ - return ChrSuber( test, pattern, subs, nsub, 0, NULL, NULL, NULL, status ); -} - -void astChrTrunc_( char *text, int *status ){ -/* -*++ -* Name: -* astChrTrunc - -* Purpose: -* Terminate a string to exclude trailing spaces. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void astChrTrunc( char *text ) - -* Description: -* This function pokes a null character into the supplied string to -* remove any trailing spaces. - -* Parameters: -* text -* The string to be truncated. - -*-- -*/ - if( !text ) return; - text[ astChrLen( text ) ] = 0; -} - -void *astFree_( void *ptr, int *status ) { -/* -*++ -* Name: -* astFree - -* Purpose: -* Free previously allocated memory. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void *astFree( void *ptr ) - -* Description: -* This function frees memory that has previouly been dynamically -* allocated using one of the AST memory function. - -* Parameters: -* ptr -* Pointer to previously allocated memory. An error will result -* if the memory has not previously been allocated by another -* function in this module. However, a NULL pointer value is -* accepted (without error) as indicating that no memory has yet -* been allocated, so that no action is required. - -* Returned Value: -* astFree() -* Always returns a NULL pointer. - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - Memory *mem; /* Pointer to memory header */ - int isdynamic; /* Is the memory dynamically allocated? */ - size_t size; /* The usable size of the memory block */ - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* If the incoming pointer is NULL, do nothing. Otherwise, check if it - points at dynamically allocated memory (IsDynamic sets the global - error status if it does not). */ - if( ptr ) { - IS_DYNAMIC( ptr, isdynamic ); - } else { - isdynamic = 0; - } - if ( isdynamic ) { - -/* If OK, obtain a pointer to the memory header. */ - mem = (Memory *) ( (char *) ptr - SIZEOF_MEMORY ); - -#ifdef MEM_DEBUG - DeIssue( mem, status ); -#endif - -/* If the memory block is small enough, and the cache is being used, put it - into the cache rather than freeing it, so that it can be reused. */ - size = mem->size; - if( use_cache && size <= MXCSIZE ) { - mem->next = cache[ size ]; - cache[ size ] = mem; - -/* Set the size to zero to indicate that the memory block has been freed. - The size of the block is implied by the Cache element it is stored in. */ - mem->size = (size_t) 0; - -/* Simply free other memory blocks, clearing the "magic number" and size - values it contains. This helps prevent accidental re-use of the memory. */ - } else { - mem->magic = (unsigned long) 0; - mem->size = (size_t) 0; - -/* Free the allocated memory. */ - FREE( mem ); - } - } - -/* Always return a NULL pointer. */ - return NULL; - -} - -void *astFreeDouble_( void *ptr, int *status ) { -/* -*++ -* Name: -* astFreeDouble - -* Purpose: -* Free previously double allocated memory. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void *astFreeDouble( void *ptr ) - -* Description: -* This function frees memory that has previouly been dynamically -* allocated using one of the AST memory function. It assumes that -* the supplied pointer is a pointer to an array of pointers. Each -* of these pointers is first freed, and then the supplied pointer -* is freed. -* -* Note, this routine should not be used with arrays allocated -* by astGrow since astGrow over-allocates and so there may be -* non-initialised pointers at the end of the array. - -* Parameters: -* ptr -* Pointer to previously allocated memory. An error will result -* if the memory has not previously been allocated by another -* function in this module. However, a NULL pointer value is -* accepted (without error) as indicating that no memory has yet -* been allocated, so that no action is required. - -* Returned Value: -* astFreeDouble() -* Always returns a NULL pointer. - -*-- -*/ - -/* Local Variables: */ - int iptr; /* Index of sub-pointer */ - int nptr; /* Number of sub-pointers */ - size_t size; /* The usable size of the memory block */ - void **ptrs; /* Pointer to array of pointers */ - -/* Check a pointer was supplied. */ - if( ! ptr ) return NULL; - -/* Get the size of the memory area. */ - size = astSizeOf( ptr ); - -/* Get the number of points this amount of memory could hold. */ - nptr = size/sizeof( void * ); - -/* Report an error if the size is not an integer multiple of an address - size. */ - if( nptr*sizeof( void * ) != size ) { - astError( AST__MEMIN, "Invalid attempt to free double allocated " - "memory: the supplied memory size (%lu bytes) is not " - "an integer multiple of %lu.", status, size, - sizeof( void * ) ); - - } else { - -/* Free each sub-pointer. */ - ptrs = (void **) ptr; - for( iptr = 0; iptr < nptr; iptr++ ) { - ptrs[ iptr ] = astFree( ptrs[ iptr ] ); - } - -/* Free the supplied pointer. */ - ptr = astFree( ptr ); - } - -/* Always return a NULL pointer. */ - return NULL; -} - -void *astGrow_( void *ptr, int n, size_t size, int *status ) { -/* -*++ -* Name: -* astGrow - -* Purpose: -* Allocate memory for an adjustable array. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void *astGrow( void *ptr, int n, size_t size ) - -* Description: -* This function allocates memory in which to store an array of -* data whose eventual size is unknown. It should be invoked -* whenever a new array size is determined and will appropriately -* increase the amount of memory allocated when necessary. In -* general, it will over-allocate in anticipation of future growth -* so that the amount of memory does not need adjusting on every -* invocation. - -* Parameters: -* ptr -* Pointer to previously allocated memory (or NULL if none has -* yet been allocated). -* n -* Number of array elements to be stored (may be zero). -* size -* The size of each array element. - -* Returned Value: -* astGrow() -* If the memory was allocated successfully, a pointer to the start -* of the possibly new memory region is returned (this may be the -* same as the original pointer). - -* Notes: -* - When new memory is allocated, the existing contents are preserved. -* - This function does not free memory once it is allocated, so -* the size allocated grows to accommodate the maximum size of the -* array (or "high water mark"). Other memory handling routines may -* be used to free the memory (or alter its size) if necessary. -* - If this function is invoked with the global error status set, -* or if it fails for any reason, the original pointer value is -* returned and the memory contents are unchanged. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int isdynamic; /* Is the memory dynamically allocated? */ - Memory *mem; /* Pointer to memory header */ - size_t newsize; /* New size to allocate */ - void *new; /* Result pointer */ - -/* Check the global error status. */ - if ( !astOK ) return ptr; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - new = ptr; - -/* Calculate the total size of memory needed. */ - size *= (size_t) n; - -/* If no memory has yet been allocated, allocate exactly the amount - required. */ - if ( !ptr ) { - new = astMalloc( size ); - -/* Otherwise, check that the incoming pointer identifies previously - allocated memory. */ - } else { - IS_DYNAMIC( ptr, isdynamic ); - if ( isdynamic ) { - -/* Obtain a pointer to the memory header and check if the new size - exceeds that already allocated. */ - mem = (Memory *) ( (char *) ptr - SIZEOF_MEMORY ); - if ( mem->size < size ) { - -/* If so, calculate a possible new size by doubling the old - size. Increase this further if necessary. */ - newsize = mem->size * ( (size_t) 2 ); - if ( size > newsize ) newsize = size; - -/* Re-allocate the memory. */ - new = astRealloc( ptr, newsize ); - } - } - } - -/* Return the result. */ - return new; -} - -int astIsDynamic_( const void *ptr, int *status ) { -/* -*++ -* Name: -* astIsDynamic - -* Purpose: -* Returns a flag indicating if memory was allocated dynamically. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* int astIsDynamic_( const void *ptr ) - -* Description: -* This function takes a pointer to a region of memory and tests if -* the memory has previously been dynamically allocated using other -* functions from this module. It does this by checking for the -* presence of a "magic" number in the header which precedes the -* allocated memory. If the magic number is not present (or the -* pointer is invalid for any other reason), zero is returned. -* Otherwise 1 is returned. - -* Parameters: -* ptr -* Pointer to test. - -* Returned Value: -* astIsDynamic() -* Non-zero if the memory was allocated dynamically. Zero is returned -* if the supplied pointer is NULL. - -* Notes: -* - A value of zero is returned if this function is invoked with -* the global error status set, or if it fails for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - Memory *isdynmem; /* Pointer to memory header */ \ - -/* Check the global error status and the supplied pointer. */ - if ( !astOK || ! ptr ) return 0; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Derive a pointer to the memory header that precedes the - supplied region of memory. */ - isdynmem = (Memory *) ( (char *) ptr - SIZEOF_MEMORY ); - -/* Check if the "magic number" in the header is valid, returning non-zero - if it is. */ - return ( isdynmem->magic == MAGIC( isdynmem, isdynmem->size ) ); -} - -void *astMalloc_( size_t size, int init, int *status ) { -/* -*++ -* Name: -* astMalloc - -* Purpose: -* Allocate memory. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void *astMalloc( size_t size ) - -* Description: -* This function allocates memory in a similar manner to the -* standard C "malloc" function, but with improved security -* (against memory leaks, etc.) and with error reporting. It also -* allows zero-sized memory allocation (without error), resulting -* in a NULL returned pointer value. - -* Parameters: -* size -* The size of the memory region required (may be zero). - -* Returned Value: -* astMalloc() -* If successful, the function returns a pointer to the start of -* the allocated memory region. If the size allocated is zero, this -* will be a NULL pointer. - -* Notes: -* - A pointer value of NULL is returned if this function is -* invoked with the global error status set or if it fails for any -* reason. -*-- - -* astMallocInit: -* - This function can be invoked using either the public astMalloc -* macro documented above, or the private astMallocInit macro. -* astMallocInit has the same interface as astMalloc, but calls calloc -* rather than malloc so that the allocated memory is filled with zeros. -* Ideally, we should use an extra layer in the calling heirarchy to -* remove the hidden "init" argument in the astMalloc_ interface, but -* astMalloc is time-critical in many situations and so it is included -* as a "hidden" argument. - -*/ - -/* Local Constants: */ -#define ERRBUF_LEN 80 - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */ - char *errstat; /* Pointer to system error message */ - Memory *mem; /* Pointer to space allocated by malloc */ - void *result; /* Returned pointer */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* If the size is greater than zero, either get a previously - allocated memory block from the cache, or attempt to use malloc - to allocate the memory, including space for the header structure. */ - if ( size > (size_t ) 0 ) { - -/* If the cache is being used and a cached memory block of the required size - is available, remove it from the cache array and use it. */ - mem = ( use_cache && size <= MXCSIZE ) ? cache[ size ] : NULL; - if( mem ) { - cache[ size ] = mem->next; - mem->next = NULL; - mem->size = (size_t) size; - -/* Initialise the memory (but not the header) if required. */ - if( init ) (void) memset( (char *) mem + SIZEOF_MEMORY, 0, size ); - -/* Otherwise, allocate a new memory block using "malloc" or "calloc". */ - } else { - if( init ) { - mem = CALLOC( 1, SIZEOF_MEMORY + size ); - } else { - mem = MALLOC( SIZEOF_MEMORY + size ); - } - -/* Report an error if malloc failed. */ - if ( !mem ) { - -#if HAVE_STRERROR_R - strerror_r( errno, errbuf, ERRBUF_LEN ); - errstat = errbuf; -#else - errstat = strerror( errno ); -#endif - astError( AST__NOMEM, "malloc: %s", status, errstat ); - astError( AST__NOMEM, "Failed to allocate %lu bytes of memory.", status, - (unsigned long) size ); - -/* If successful, set the "magic number" in the header and also store - the size. */ - } else { - mem->magic = MAGIC( mem, size ); - mem->size = size; - mem->next = NULL; - -#ifdef MEM_DEBUG - mem->id = -1; - mem->prev = NULL; -#endif - - } - } - -/* Do nothing more if no memory is being returned. */ - if( mem ) { - -#ifdef MEM_DEBUG - Issue( mem, status ); -#endif - -/* Increment the memory pointer to the start of the region of - allocated memory to be used by the caller.*/ - result = mem; - result = (char *) result + SIZEOF_MEMORY; - } - } - -/* Return the result. */ - return result; -} -#undef ERRBUF_LEN - -static char *ChrMatcher( const char *test, const char *end, const char *template, - const char *pattern, const char *subs[], int nsub, - int ignore, int expdoll, char ***mres, int *mlen, - const char **matchend, int *status ){ -/* -* Name: -* ChrMatcher - -* Purpose: -* Performs substitutions on a supplied string. - -* Type: -* Private function. - -* Synopsis: -* #include "memory.h" -* char *ChrMatcher( const char *test, const char *end, const char *template, -* const char *pattern, const char *subs[], int nsub, -* int ignore, int expdoll, char ***mres, int *mlen, -* const char **matchend, int *status ) - -* Description: -* This function is performs most of the work for astChrSub. - -* Parameters: -* test -* The string to be tested. -* end -* Pointer to the terminating null character at the end of "test". -* template -* The template string. See astChrSub for details. -* pattern -* The user supplied "pattern" string (only used for error messages). -* subs -* An array of strings holding the values that are to be substituted -* into each parenthesised substring in "test". -* nsub -* The length of the subs arrays. -* ignore -* If non-zero, then no substitutions are performed, and any -* inbalance in parentheses is ignored. -* expdoll -* If non-zero, then any "$1", "$2", etc, tokens in the -* substitution fields will be repalced by the corresponding fields -* in the test string. -* mres -* Address of a location at which to return a pointer to an array -* of character string pointers. The strings are the sub-sections -* of "test" that matched the parenthesised sub-sections of -* "template". The array will have "*m" elements. Ignored if NULL. -* mlen -* Address of a location at which to return the length of the -* returned "mres" array. Ignored if "mres" is NULL. -* matchend -* A pointer to a location at which to return a pointer to the -* character that follows the last character within the supplied test -* string that matched any parenthesises sub-section of "regexp". A -* NULL pointer is returned if no matches were found. A NULL pointer -* may be supplied if the location of the last matching character is -* not needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated string holding the result of the -* substitutions, or NULL if the test string does not match the template -* string. This string should be freed using astFree when no longer -* needed. - -* Notes: -* - A NULL pointer is returned if this function is invoked with the -* global error status set or if it should fail for any reason, or if -* the supplied test string does not match the template. -*/ - -/* Local Variables: */ - char **matches; - char **newsubs; - char **parts; - char *allowed; - char *r; - char *result; - char *sres; - char *stest; - char stemp[10]; - const char *aaa; - const char *aa; - const char *a; - const char *b; - int allow; - int dollar; - int end_sub; - int greedy; - int i; - int in_sub; - int ipart; - int match; - int matchlen; - int max_na; - int min_na; - int na; - int nb; - int nmatch; - int npart; - int partlen; - int reslen; - int start_sub; - size_t stl; - -/* Initialisation. */ - if( mres ) *mlen = 0; - aaa = NULL; - if( matchend ) *matchend = NULL; - -/* Check the global error status. */ - if( !astOK ) return NULL; - -/* more initialisation. */ - result = NULL; - allowed = NULL; - -/* Get memory for a set of pointers to copies of the test sub-strings that - fall between the sub-strings being replaced. */ - parts = astMalloc( sizeof( char *)*(size_t) ( nsub + 1 ) ); - -/* Get memory for a set of pointers to copies of the test sub-strings that - match the parenthesised sub-strings in the template. */ - matches = astMalloc( sizeof( char *)*(size_t) nsub ); - -/* Initialise pointers to the next test and template characters to read. */ - a = test; - b = template; - -/* Initialise the pointer to the start of the previous test character */ - aa = test; - -/* Assume the test string matches the template. */ - match = 1; - -/* The template pointer is not currently in a substitution field. */ - in_sub = 0; - -/* Initialise the number of substitution fields found so far. */ - npart = 0; - nmatch = 0; - -/* Loop until we have reached the end of either the test or template - string. We break out of the loop early if we find that the test string - does not match the template string. */ - while( match && *a && *b ) { - -/* Examine the string at the start of the template string. This returns a - string of allowed (or disallowed) characters that the next test character - can match, the number of template characters consumed, the minimum number - of test characters that must match the allowed character set, and a flag - indicating if the number of matching test characters can exceed the - minimum number or must be exactly equal to the minimum number. */ - allowed = CheckTempStart( template, b, pattern, allowed, &nb, &allow, - &min_na, &max_na, &start_sub, &end_sub, - &greedy, status ); - if( !astOK ) break; - -/* Increment the the pointer to the next template character. */ - b += nb; - -/* If the leading field in the template indicates the start of a - substitution field, record the test string up to the current point. */ - if( start_sub ){ - -/* Do nothing if we are ignoring substitutions. */ - if( ! ignore ){ - -/* Store a pointer to the first test character that matches the - substitution template. */ - aaa = a; - -/* Report an error and abort if we are already inside a substitution - field */ - if( in_sub ) { - astError( AST__BADSUB, "Invalid pattern matching template \"%s\": " - "missing ')'.", status, pattern ); - break; - } - -/* Indicate that we are now in a substitution field. */ - in_sub = 1; - -/* If possible, store a copy of the test string that started at the end - of the previous substitution field and ends at the current point. - First ensure the "parts" array is large enough since the string may - contain more than "nsub" parenthesised sub-strings. */ - parts = astGrow( parts, npart + 1, sizeof( char * ) ); - if( parts ) { - partlen = ( a - aa ); - parts[ npart ] = astStore( NULL, aa, partlen + 1 ); - if( parts[ npart ] ) { - parts[ npart ][ partlen ] = 0; - npart++; - } - } - } - -/* If the leading field in the template indicates the end of a - substitution field, initialise the start of the next part of the test - string. */ - } else if( end_sub ){ - -/* Do nothing if we are ignoring substitutions. */ - if( ! ignore ){ - -/* Report an error and abort if we are not currently in a substitution - field. */ - if( ! in_sub ) { - astError( AST__BADSUB, "Invalid pattern matching template \"%s\": " - "missing '('.", status, pattern ); - break; - } - -/* We are no longer in a substitution field. */ - in_sub = 0; - -/* If possible, store a copy of the test string that matched the - substitution template. */ - matches = astGrow( matches, nmatch + 1, sizeof( char * ) ); - if( matches ) { - matchlen = ( a - aaa ); - matches[ nmatch ] = astStore( NULL, aaa, matchlen + 1 ); - if( matches[ nmatch ] ) { - matches[ nmatch ][ matchlen ] = 0; - nmatch++; - if( matchend ) *matchend = a; - } - } - -/* Record the start of the next test string part. */ - aa = a; - } - -/* Otherwise, find how many characters at the front of the test string - match the leading field in the template. Find the number of leading - characters in the test string that are contained in the set of - characters allowed by the leading field in the template. */ - } else { - if( !allowed ) { - na = strlen( a ); - - } else if( allow ) { - na = strspn( a, allowed ); - - } else { - na = strcspn( a, allowed ); - } - -/* Check that the minmum number of matching characters is available. */ - if( na < min_na ){ - match = 0; - break; - } - -/* Dont match more characters than are needed. */ - if( na > max_na ) na = max_na; - -/* We cannot match more characters than are available. */ - if( na < max_na ) max_na = na; - -/* If we have exhausted the template, match the maximum number of - characters. */ - if( ! *b ) { - na = max_na; - -/* If we still have a match, we may choose to use fewer than the max - allowed number of test characters in order to allow the next template - field to be matched. Don't need to do this if we have reached the end - of the template. */ - } else if( max_na > min_na ) { - match = 0; - -/* If a greedy quantifier was used, try using a decreasing number of test - characters, starting at the maximum allowed and decreasing down to the - minimum, until a number is found which allows the rest of the string - to be matched. */ - if( greedy ) { - for( na = max_na; na >= min_na; na-- ) { - r = ChrMatcher( a + na, end, b, pattern, NULL, 0, 1, 0, - NULL, NULL, NULL, status ); - if( r ) { - match = 1; - r = astFree( r ); - break; - } - } - -/* If a non-greedy quantifier was used, try using an increasing number of - test characters, starting at the minimum allowed and increasing up to - the maximum, until a number is found which allows the rest of the string - to be matched. */ - } else { - for( na = min_na; na <= max_na; na++ ) { - r = ChrMatcher( a + na, end, b, pattern, NULL, 0, 1, 0, - NULL, NULL, NULL, status ); - if( r ) { - match = 1; - r = astFree( r ); - break; - } - } - } - } - -/* Increment the the pointer to the next test character. */ - a += na; - if( a > end ) a = end; - } - } - -/* If the test string is finished but the template string is not, see if - the next part of the template string will match a null test string. - But ignore the ends of substitution fields. */ - if( !*a && *b && match ) { - while( *b && *b != ')' ) { - allowed = CheckTempStart( template, b, pattern, allowed, &nb, &allow, - &min_na, &max_na, &start_sub, &end_sub, - &greedy, status ); - b += nb; - allowed = astFree( allowed ); - - if( min_na > 0 ) { - match = 0; - break; - } - } - } - -/* If the next character in the template is a closing parenthesis, then - we are finishing a substitution field. */ - if( match && *b == ')' ) { - -/*Check we are not ignoring substitutions. */ - if( ! ignore ){ - -/* Report an error and abort if we are not currently in a substitution - field. */ - if( ! in_sub ) { - astError( AST__BADSUB, "Invalid pattern matching template \"%s\": " - "missing '('.", status, pattern ); - } - -/* We are no longer in a substitution field. */ - in_sub = 0; - -/* If possible, store a copy of the test string that matched the - substitution field. */ - matches = astGrow( matches, nmatch + 1, sizeof( char * ) ); - if( matches ) { - matchlen = ( a - aaa ); - matches[ nmatch ] = astStore( NULL, aaa, matchlen + 1 ); - if( matches[ nmatch ] ) { - matches[ nmatch ][ matchlen ] = 0; - nmatch++; - if( matchend ) *matchend = a; - } - } - - aa = a; - } - b++; - } - -/* If the test string is finished but the template string is not, see if - the rest of the template string will match a null test string. */ - if( !*a && *b && match ) { - - while( *b ) { - allowed = CheckTempStart( template, b, pattern, allowed, &nb, &allow, - &min_na, &max_na, &start_sub, &end_sub, - &greedy, status ); - b += nb; - allowed = astFree( allowed ); - - if( min_na > 0 ) { - match = 0; - break; - } - } - - } - -/* No match if either string was not used completely. */ - if( *a || *b ) match = 0; - -/* Report an error if we are still inside a substitution field */ - if( match && in_sub && !ignore ) { - astError( AST__BADSUB, "Invalid pattern matching template \"%s\": " - "missing ')'.", status, pattern ); - match = 0; - } - -/* If we have a match, construct the returned string. */ - if( match && parts ) { - -/* Store the test string following the final substitution field. */ - parts = astGrow( parts, npart + 1, sizeof( char * ) ); - if( parts ) { - partlen = ( a - aa ); - parts[ npart ] = astStore( NULL, aa, partlen + 1 ); - if( parts[ npart ] ) { - parts[ npart ][ partlen ] = 0; - npart++; - } - } - -/* If required, expand $1, $2, etc within the replacement strings. */ - if( expdoll) { - newsubs = astMalloc( sizeof( char * )*nsub ); - if( newsubs ) { - for( i = 0; i < nsub; i++ ) { - stl = strlen( subs[ i ] ); - stest = astStore( NULL, subs[ i ], stl + 1 ); - for( dollar = 1; dollar <= nsub; dollar++ ) { - sprintf( stemp, ".*($%d).*", dollar ); - sres = ChrMatcher( stest, stest + stl, stemp, stemp, - (void *) ( matches + dollar - 1 ), - 1, 0, 0, NULL, NULL, NULL, status ); - if( sres ) { - (void) astFree( stest ); - stest = sres; - } - } - newsubs[ i ] = stest; - } - } - - } else { - newsubs = (char **) subs; - } - -/* Concatenate the sub-strings to form the final string. */ - reslen = 0; - for( ipart = 0; ipart < npart - 1; ipart++ ) { - result = astAppendString( result, &reslen, parts[ ipart ] ); - if( ipart < nsub ) { - result = astAppendString( result, &reslen, newsubs[ ipart ] ); - } else { - result = astAppendString( result, &reslen, matches[ ipart ] ); - } - } - result = astAppendString( result, &reslen, parts[ ipart ] ); - -/* Free resources. */ - if( newsubs && newsubs != (char **) subs ) { - for( i = 0; i < nsub; i++ ) { - newsubs[ i ] = astFree( newsubs[ i ] ); - } - newsubs = astFree( newsubs ); - } - } - - allowed = astFree( allowed ); - for( ipart = 0; ipart < npart; ipart++ ) { - parts[ ipart ] = astFree( parts[ ipart ] ); - } - parts = astFree( parts ); - -/* If required, return the array holding the test sub-strings that - matched the parenthesised template sub-strings, together with - the length of the array. Otherwise, free the memory holding these - strings. */ - if( mres ) { - *mres = matches; - *mlen = nmatch; - - } else if( matches ) { - for( i = 0; i < nmatch; i++ ) { - matches[ i ] = astFree( matches[ i ] ); - } - matches = astFree( matches ); - - } - -/* Return the result. */ - return result; -} - -int astMemCaching_( int newval, int *status ){ -/* -*++ -* Name: -* astMemCaching - -* Purpose: -* Controls whether allocated but unused memory is cached in this module. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* int astMemCaching( int newval ) - -* Description: -* This function sets a flag indicating if allocated but unused memory -* should be cached or not. It also returns the original value of the -* flag. -* -* If caching is switched on or off as a result of this call, then the -* current contents of the cache are discarded. -* -* Note, each thread has a separate cache. Calling this function -* affects only the currently executing thread. - -* Parameters: -* newval -* The new value for the MemoryCaching tuning parameter (see -* astTune in objectc.c). If AST__TUNULL is supplied, the current -* value is left unchanged. - -* Returned Value: -* astMemCaching() -* The original value of the MemoryCaching tuning parameter. - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - int i; - int result; - Memory *mem; - -#ifdef MEM_DEBUG - int id_list_size; - int *id_list; -#endif - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Store the original value of the tuning parameter. */ - result = use_cache; - -/* If a new value is to be set. */ - if( newval != AST__TUNULL ) { - -/* If the cache has been initialised, empty it. */ - if( cache_init ) { - -/* If we are listing the ID of every memory block in the cache, count the - number of blocks in the cache and then allocate an array to store the ID - values in. This is done so that we can sort them before displaying them. */ -#ifdef MEM_DEBUG - if( List_Cache ) { - Memory *next; - - id_list_size = 0; - for( i = 0; i <= MXCSIZE; i++ ) { - next = cache[ i ]; - while( next ) { - id_list_size++; - next = next->next; - } - } - - id_list = MALLOC( sizeof(int)*id_list_size ); - if( !id_list ) { - astError( AST__INTER, "astMemCaching: Cannot allocate %lu " - "bytes of memory", status, (unsigned long)(sizeof(int)*id_list_size) ); - } - - id_list_size = 0; - - } else { - id_list = NULL; - } -#endif - - for( i = 0; i <= MXCSIZE; i++ ) { - while( cache[ i ] ) { - mem = cache[ i ]; - cache[ i ] = mem->next; - mem->size = (size_t) i; - -#ifdef MEM_DEBUG - if( id_list ) { - id_list[ id_list_size++ ] = mem->id; - } -#endif - - FREE( mem ); - } - } - -/* If we are displaying the IDs of memory blocks still in the cache, sort - them using a bubblesort algorithm, then display them. */ -#ifdef MEM_DEBUG - if( id_list ) { - - if( id_list_size == 0 ) { - printf( "Emptying the AST memory cache - (the cache is " - "already empty)\n" ); - - } else { - int sorted, j, t; - - sorted = 0; - for( j = id_list_size - 2; !sorted && j >= 0; j-- ) { - sorted = 1; - for( i = 0; i <= j; i++ ) { - if( id_list[ i ] > id_list[ i + 1 ] ) { - sorted = 0; - t = id_list[ i ]; - id_list[ i ] = id_list[ i + 1 ]; - id_list[ i + 1 ] = t; - } - } - } - - printf( "Emptying the AST memory cache - freeing the " - "following memory blocks: "); - for( i = 0; i < id_list_size; i++ ) printf( "%d ", id_list[ i ] ); - printf( "\n" ); - - } - } -#endif - -/* Otherwise, initialise the cache array to hold a NULL pointer at every - element. */ - } else { - for( i = 0; i <= MXCSIZE; i++ ) cache[ i ] = NULL; - cache_init = 1; - } - -/* Store the new value. */ - use_cache = newval; - - } - -/* Return the original value. */ - return result; -} - -void *astRealloc_( void *ptr, size_t size, int *status ) { -/* -*++ -* Name: -* astRealloc - -* Purpose: -* Change the size of a dynamically allocated region of memory. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void *astRealloc( void *ptr, size_t size ) - -* Description: -* This function changes the size of a dynamically allocated region -* of memory, preserving its contents up to the minimum of the old -* and new sizes. This may involve copying the contents to a new -* location, so a new pointer is returned (and the old memory freed -* if necessary). -* -* This function is similar to the standard C "realloc" function -* except that it provides better security against programming -* errors and also supports the allocation of zero-size memory -* regions (indicated by a NULL pointer). - -* Parameters: -* ptr -* Pointer to previously allocated memory (or NULL if the -* previous size of the allocated memory was zero). -* size -* New size required for the memory region. This may be zero, in -* which case a NULL pointer is returned (no error results). It -* should not be negative. - -* Returned Value: -* astRealloc() -* If the memory was reallocated successfully, a pointer to the -* start of the new memory region is returned (this may be the same -* as the original pointer). If size was given as zero, a NULL -* pointer is returned. - -* Notes: -* - If this function is invoked with the error status set, or if -* it fails for any reason, the original pointer value is returned -* and the memory contents are unchanged. Note that this behaviour -* differs from that of the standard C "realloc" function which -* returns NULL if it fails. -*-- -*/ - -/* Local Constants: */ -#define ERRBUF_LEN 80 - -/* Local Variables: */ - astDECLARE_GLOBALS - char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */ - char *errstat; /* Pointer to system error message */ - int isdynamic; /* Was memory allocated dynamically? */ - void *result; /* Returned pointer */ - Memory *mem; /* Pointer to memory header */ - -/* Check the global error status. */ - if ( !astOK ) return ptr; - -/* Initialise. */ - result = ptr; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* If a NULL pointer was supplied, use astMalloc to allocate some new - memory. */ - if ( !ptr ) { - result = astMalloc( size ); - -/* Otherwise, check that the pointer supplied points at memory - allocated by a function in this module (IsDynamic sets the global - error status if it does not). */ - } else { - IS_DYNAMIC( ptr, isdynamic ); - if ( isdynamic ) { - -/* Obtain a pointer to the memory header. */ - mem = (Memory *) ( (char *) ptr - SIZEOF_MEMORY ); - -/* If the new size is zero, free the old memory and set a NULL return - pointer value. */ - if ( size == (size_t) 0 ) { - astFree( ptr ); - result = NULL; - -/* Otherwise, reallocate the memory. */ - } else { - -/* If the cache is being used, for small memory blocks, do the equivalent of - mem = REALLOC( mem, SIZEOF_MEMORY + size ); - - using astMalloc, astFree and memcpy explicitly in order to ensure - that the memory blocks are cached. */ - if( use_cache && ( mem->size <= MXCSIZE || size <= MXCSIZE ) ) { - result = astMalloc( size ); - if( result ) { - if( mem->size < size ) { - memcpy( result, ptr, mem->size ); - } else { - memcpy( result, ptr, size ); - } - astFree( ptr ); - - } else { - result = ptr; - } - -/* For other memory blocks simply use realloc. */ - } else { - -#ifdef MEM_DEBUG - DeIssue( mem, status ); -#endif - - mem = REALLOC( mem, SIZEOF_MEMORY + size ); - -/* If this failed, report an error and return the original pointer - value. */ - if ( !mem ) { -#if HAVE_STRERROR_R - strerror_r( errno, errbuf, ERRBUF_LEN ); - errstat = errbuf; -#else - errstat = strerror( errno ); -#endif - astError( AST__NOMEM, "realloc: %s", status, errstat ); - astError( AST__NOMEM, "Failed to reallocate a block of " - "memory to %ld bytes.", status, (long) size ); - -/* If successful, set the new "magic" value and size in the memory - header and obtain a pointer to the start of the region of memory to - be used by the caller. */ - } else { - mem->magic = MAGIC( mem, size ); - mem->size = size; - mem->next = NULL; -#ifdef MEM_DEBUG - mem->id = -1; - mem->prev = NULL; - Issue( mem, status ); -#endif - result = mem; - result = (char *) result + SIZEOF_MEMORY; - } - } - } - } - } - -/* Return the result. */ - return result; -} -#undef ERRBUF_LEN - -void astRemoveLeadingBlanks_( char *string, int *status ) { -/* -*++ -* Name: -* astRemoveLeadingBlanks - -* Purpose: -* Remove any leading white space from a string. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void astRemoveLeadingBlanks( char *string ) - -* Description: -* This function moves characters in the supplied string to the left -* in order to remove any leading white space. - -* Parameters: -* string -* Pointer to the string. - -*-- -*/ - -/* Local Variables: */ - char *c, *d; - -/* Check a string has been supplied. */ - if( string ){ - -/* Get a pointer to the first non-white character in the string. */ - c = string; - while( *c && isspace( *c ) ) c++; - -/* Do nothing more if there are no leading spaces. */ - if( c > string ) { - -/* Copy all characters (excluding the trailing null) to the left to - over-write the leading spaces. */ - d = string; - while( *c ) *(d++) = *(c++); - -/* Terminate the returned string. */ - *d = 0; - } - } -} - -size_t astSizeOf_( const void *ptr, int *status ) { -/* -*++ -* Name: -* astSizeOf - -* Purpose: -* Determine the size of a dynamically allocated region of memory. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* size_t astSizeOf( const void *ptr ) - -* Description: -* This function returns the size of a region of dynamically -* allocated memory. - -* Parameters: -* ptr -* Pointer to dynamically allocated memory (or NULL if the size -* of the allocated memory was zero). - -* Returned Value: -* astSizeOf() -* The allocated size. This will be zero if a NULL pointer was -* supplied (no error will result). - -* Notes: -* - A value of zero is returned if this function is invoked with -* the global error status set, or if it fails for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int isdynamic; /* Was the memory allocated dynamically? */ - size_t size; /* Memory size */ - -/* Check the global error status. */ - if ( !astOK ) return (size_t) 0; - -/* Initialise. */ - size = (size_t) 0; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check if a non-NULL valid pointer has been given. If so, extract - the memory size from the header which precedes it. */ - if ( ptr ){ - IS_DYNAMIC( ptr, isdynamic ); - if( isdynamic ) size = ( (Memory *) ( (char *) ptr - SIZEOF_MEMORY ) )->size; - } - -/* Return the result. */ - return size; -} - -static size_t SizeOfMemory( int *status ){ -/* -* Name: -* SizeOfMemory - -* Purpose: -* Returns the size of a Memory structure, padded to an 8 byte -* boundary. - -* Type: -* Private function. - -* Synopsis: -* size_t SizeOfMemory( int *status ) - -* Description: -* This function returns the size of a Memory structure used to -* store header information about any block of memory allocated by this -* module. The returned value may be larger than the actual size of -* the Memory structure in order to ensure that the pointer returned by -* astMalloc etc points to an 8 byte boundary. Failure to do this can -* result in some operating systems having problems. E.g Solaris -* requires this alignment if the returned pointer is going to be used to -* store doubles. - -* Parameters: -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The size to use for a Memory structure. - -* Notes: -* - The returned value is also stored in the module variable -* sizeof_memory. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get the basic size of a Memory structure. */ - sizeof_memory = sizeof( Memory ); - -/* Now increase the returned value to ensure it is a multiple of 8. Mask - off all but the last 3 bits, xor with 0x7 to get the remainder, add 1 - to make it a multiple of 8 bytes. */ - sizeof_memory += ((sizeof_memory & 0x7) ? ((sizeof_memory & 0x7) ^ 0x7) + 1 : 0); - -/* Return the value */ - return sizeof_memory; - -} - -size_t astTSizeOf_( const void *ptr, int *status ) { -/* -*+ -* Name: -* astTSizeOf - -* Purpose: -* Determine the total size of a dynamically allocated region of memory. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* size_t astTSizeOf( const void *ptr ) - -* Description: -* This function returns the size of a region of dynamically -* allocated memory, including the extra memory used to store -* the header information for the memory block (size and magic number). - -* Parameters: -* ptr -* Pointer to dynamically allocated memory (or NULL if the size -* of the allocated memory was zero). - -* Returned Value: -* The allocated size. This will be zero if a NULL pointer was -* supplied (no error will result). - -* Notes: -* - A value of zero is returned if this function is invoked with -* the global error status set, or if it fails for any reason. -* - This function is documented as protected because it should not -* be invoked by external code. However, it is available via the -* external C interface so that it may be used when writing (e.g.) -* foreign language or graphics interfaces. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int isdynamic; /* Was the memory allocated dynamically? */ - size_t size; /* Memory size */ - -/* Check the global error status. */ - if ( !astOK ) return (size_t) 0; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - size = (size_t) 0; - -/* Check if a non-NULL valid pointer has been given. If so, extract - the memory size from the header which precedes it. */ - if ( ptr ){ - IS_DYNAMIC( ptr, isdynamic ); - if( isdynamic ) size = SIZEOF_MEMORY + - ( (Memory *) ( (char *) ptr - SIZEOF_MEMORY ) )->size; - } - -/* Return the result. */ - return size; -} - -void *astStore_( void *ptr, const void *data, size_t size, int *status ) { -/* -*++ -* Name: -* astStore - -* Purpose: -* Store data in dynamically allocated memory. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* void *astStore( void *ptr, const void *data, size_t size ) - -* Description: -* This function stores data in dynamically allocated memory, -* allocating the memory (or adjusting the size of previously -* allocated memory) to match the amount of data to be stored. - -* Parameters: -* ptr -* Pointer to previously allocated memory (or NULL if none has -* yet been allocated). -* data -* Pointer to the start of the data to be stored. This may be -* given as NULL if there are no data, in which case it will be -* ignored and this function behaves like astRealloc, preserving -* the existing memory contents. -* size -* The total size of the data to be stored and/or the size of -* memory to be allocated. This may be zero, in which case the -* data parameter is ignored, any previously-allocated memory is -* freed and a NULL pointer is returned. - -* Returned Value: -* astStore() -* If the data were stored successfully, a pointer to the start of -* the possibly new memory region is returned (this may be the same -* as the original pointer). If size was given as zero, a NULL -* pointer is returned. - -* Notes: -* - This is a convenience function for use when storing data of -* arbitrary size in memory which is to be allocated -* dynamically. It is appropriate when the size of the data will -* not change frequently because the size of the memory region will -* be adjusted to fit the data on every invocation. -* - If this function is invoked with the error status set, or if -* it fails for any reason, the original pointer value is returned -* and the memory contents are unchanged. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int valid; /* Is the memory pointer usable? */ - void *new; /* Pointer to returned memory */ - -/* Check the global error status. */ - if ( !astOK ) return ptr; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - new = ptr; - -/* If the new size is zero, use astRealloc to free any previously - allocated memory. Also re-allocate the memory if the data pointer - is NULL (in which case we want to preserve its contents). */ - if ( ( size == (size_t) 0 ) || !data ) { - new = astRealloc( ptr, size ); - -/* In other cases, we do not want to preserve any memory - contents. Check if the incoming memory pointer is valid (IsDynamic - sets the global error status if it is not). */ - } else { - if ( !ptr ){ - valid = 1; - } else { - IS_DYNAMIC( ptr, valid ); - } - if( valid ) { - -/* Allocate the new memory. If successful, free the old memory (if - necessary) and copy the data into it. */ - new = astMalloc( size ); - if ( astOK ) { - if ( ptr ) ptr = astFree( ptr ); - (void) memcpy( new, data, size ); - -/* If memory allocation failed, do not free the old memory but return - a pointer to it. */ - } else { - new = ptr; - } - } - } - -/* Return the result. */ - return new; -} - -char *astString_( const char *chars, int nchars, int *status ) { -/* -*++ -* Name: -* astString - -* Purpose: -* Create a C string from an array of characters. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* char *astString( const char *chars, int nchars ) - -* Description: -* This function allocates memory to hold a C string and fills the -* string with the sequence of characters supplied. It then -* terminates the string with a null character and returns a -* pointer to its start. The memory used for the string may later -* be de-allocated using astFree. -* -* This function is intended for constructing null terminated C -* strings from arrays of characters which are not null terminated, -* such as when importing a character argument from a Fortran 77 -* program. - -* Parameters: -* chars -* Pointer to the array of characters to be used to fill the string. -* nchars -* The number of characters in the array (zero or more). - -* Returned Value: -* astString() -* If successful, the function returns a pointer to the start of -* the allocated string. If the number of characters is zero, a -* zero-length string is still allocated and a pointer to it is -* returned. - -* Notes: -* - A pointer value of NULL is returned if this function is -* invoked with the global error status set or if it fails for any -* reason. -*-- -*/ - -/* Local Variables: */ - char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check that the number of characters in the string is valid and - report an error if it is not. */ - if ( nchars < 0 ) { - astError( AST__NCHIN, "astString: Invalid attempt to allocate a string " - "with %d characters.", status, nchars); - -/* Allocate memory to hold the string. */ - } else { - result = (char *) astMalloc( (size_t) ( nchars + 1 ) ); - -/* If successful, copy the characters into the string. */ - if ( astOK && result ) { - (void) memcpy( result, chars, (size_t) nchars ); - -/* Terminate the string. */ - result[ nchars ] = '\0'; - } - } - -/* Return the result. */ - return result; -} - -char **astStringArray_( const char *chars, int nel, int len, int *status ) { -/* -*++ -* Name: -* astStringArray - -* Purpose: -* Create an array of C strings from an array of characters. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* char **astStringArray( const char *chars, int nel, int len ) - -* Description: -* This function turns an array of fixed-length character data into -* a dynamicllay allocated array of null-terminated C strings with -* an index array that may be used to access them. -* -* The array of character data supplied is assumed to hold "nel" -* adjacent fixed-length strings (without terminating nulls), each -* of length "len" characters. This function allocates memory and -* creates a null-terminated copy of each of these strings. It also -* creates an array of "nel" pointers which point at the start of -* each of these new strings. A pointer to this index array is -* returned. -* -* The memory used is allocated in a single block and should later -* be de-allocated using astFree. -s -* Parameters: -* chars -* Pointer to the array of input characters. The number of characters -* in this array should be at least equal to (nel * len). -* nel -* The number of fixed-length strings in the input character -* array. This may be zero but should not be negative. -* len -* The number of characters in each fixed-length input -* string. This may be zero but should not be negative. - -* Returned Value: -* astStringArray() -* A pointer to the start of the index array, which contains "nel" -* pointers pointing at the start of each null-terminated output -* string. -* -* The returned pointer should be passed to astFree to de-allocate -* the memory used when it is no longer required. This will free -* both the index array and the memory used by the strings it -* points at. - -* Notes: -* - A NULL pointer will also be returned if the value of "nel" is -* zero, in which case no memory is allocated. -* - A pointer value of NULL will also be returned if this function -* is invoked with the global error status set or if it fails for -* any reason. -*-- -*/ - -/* Local Variables: */ - char **result; /* Result pointer to return */ - char *out_str; /* Pointer to start of next output string */ - const char *in_str; /* Pointer to start of next input string */ - int i; /* Loop counter for array elements */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check that the array size is valid and report an error if it is - not. */ - if ( nel < 0 ) { - astError( AST__NELIN, - "astStringArray: Invalid attempt to allocate an array of " - "%d strings.", status, nel ); - -/* If the string length will be used, check that it is valid and - report an error if it is not. */ - } else if ( ( nel > 0 ) && ( len < 0 ) ) { - astError( AST__NCHIN, - "astStringArray: Invalid attempt to allocate an " - "array of strings with %d characters in each.", status, len ); - -/* Allocate memory to hold the array of string pointers plus the - string data (with terminating nulls). */ - } else { - result = astMalloc( sizeof( char * ) * (size_t) nel + - (size_t) ( nel * ( len + 1 ) ) ); - -/* If successful, initialise pointers to the start of the current - input and output strings. */ - if( astOK ){ - in_str = chars; - out_str = (char *) ( result + nel ); - -/* Loop to copy each string. */ - for ( i = 0; i < nel; i++ ) { - (void) memcpy( out_str, in_str, (size_t) len ); - -/* Terminate the output string. */ - out_str[ len ] = '\0'; - -/* Store a pointer to the start of the output string in the array of - character pointers. */ - result[ i ] = out_str; - -/* Increment the pointers to the start of the next string. */ - out_str += len + 1; - in_str += len; - } - } - } - -/* Return the result. */ - return result; -} - -char *astStringCase_( const char *string, int upper, int *status ) { -/* -*++ -* Name: -* astStringCase - -* Purpose: -* Convert a string to upper or lower case. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* char *astStringCase( const char string, int upper ) - -* Description: -* This function converts a supplied string to upper or lower case, -* storing the result in dynamically allocated memory. The astChrCase -* function is similar, but stores the result in a supplied buffer. - -* Parameters: -* string -* Pointer to the null terminated string to be converted. -* upper -* If non-zero, the string is converted to upper case. Otherwise it -* is converted to lower case. - -* Returned Value: -* astStringCase() -* If successful, the function returns a pointer to the start of -* the allocated string. The returned memory should be freed using -* astFree when no longer needed. - -* Notes: -* - A pointer value of NULL is returned if this function is -* invoked with the global error status set or if it fails for any -* reason. -*-- -*/ - -/* Local Variables: */ - char *pout; /* Pointer to next output character */ - char *result; /* Pointer value to return */ - const char *pin; /* Pointer to next input character */ - int i; /* Character index */ - int len; /* String length */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the length of the supplied string, excluding the trailing null. */ - len = strlen( string ); - -/* Allocate memory to hold the converted string, plus terminating null. */ - result = (char *) astMalloc( (size_t) ( len + 1 ) ); - -/* If successful, copy the characters into the string, converting each - one to the requested case. */ - if ( result ) { - pin = string; - pout = result; - - if( upper ) { - for( i = 0; i < len; i++ ) { - *(pout++) = toupper( (int) *(pin++) ); - } - - } else { - - for( i = 0; i < len; i++ ) { - *(pout++) = tolower( (int) *(pin++) ); - } - } - -/* Terminate the string. */ - *pout = '\0'; - } - -/* Return the result. */ - return result; -} - -size_t astChrLen_( const char *string, int *status ) { -/* -*++ -* Name: -* astChrLen - -* Purpose: -* Determine the used length of a string. - -* Type: -* Public function. - -* Synopsis: -* #include "memory.h" -* size_t astChrLen( const char *string ) - -* Description: -* This function returns the used length of a string. This excludes any -* trailing white space or non-printable characters (such as the -* trailing null character). - -* Parameters: -* string -* Pointer to the string. - -* Returned Value: -* astChrLen() -* The number of characters in the supplied string, not including the -* trailing newline, and any trailing white-spaces or non-printable -* characters. - -*-- -*/ - -/* Local Variables: */ - const char *c; /* Pointer to the next character to check */ - size_t ret; /* The returned string length */ - -/* Initialise the returned string length. */ - ret = 0; - -/* Check a string has been supplied. */ - if( string ){ - -/* Check each character in turn, starting with the last one. */ - ret = strlen( string ); - c = string + ret - 1; - while( ret ){ - if( isprint( (int) *c ) && !isspace( (int) *c ) ) break; - c--; - ret--; - } - } - -/* Return the answer. */ - return ret; - -} - -int astSscanf_( const char *str, const char *fmt, ...) { -/* -*+ -* Name: -* astSscanf - -* Purpose: -* A wrapper for the ANSI sscanf function. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* int astSscanf( const char *str, const char *fmt, ...) - -* Description: -* This function is a direct plug-in replacement for sscanf. It ensures ANSI -* behaviour is available on all platforms, including those (such as -* MacOS) on which have the native sscanf function exhibits non-ANSI -* behaviour. - -* Parameters: -* str -* Pointer to the string to be scanned. -* fmt -* Pointer to the format string which defines the fields to be -* looked for within "str". -* ... -* Pointers to locations at which to return the value of each -* succesfuly converted field, in the order specified in "fmt". - -* Returned Value: -* The number of fields which were succesfully read from "str". -*- -*/ - -/* Local Variables: */ - char *c; /* Pointer to the next character to check */ - char *newfor; /* Pointer to modified format string */ - const char *d; /* Pointer to the next character to check */ - int *status; /* Pointer to inherited status value */ - int iptr; /* Index into ptr array */ - int lfor; /* No. of characters in format string */ - int lstr; /* No. of characters in scanned string */ - int nc; /* No. of characters read from str */ - int nfld; /* No. of counted field specifiers found so far */ - int nptr; /* Np. of pointers stored */ - int ret; /* The returned number of conversions */ - va_list args; /* Variable argument list pointer */ - void *fptr; /* The next supplied pointer */ - void *ptr[ VMAXFLD ]; /* Array of supplied pointers */ - -/* Initialise the variable argument list pointer. */ - va_start( args, fmt ); - -/* Get a pointer to the integer holding the inherited status value. */ - status = astGetStatusPtr; - -/* Initialise the returned string length. */ - ret = 0; - -/* Check a string and format have been supplied. */ - if( str && fmt ){ - -/* Go through the format string, counting the number of field specifiers which - will return a value, and storing the corresponding points in the ptr - array. */ - nptr = 0; - c = (char *) fmt; - while( *c ) { - -/* Field specifiers are marked by a % sign. */ - if( *c == '%' ) { - -/* Look at the character following the % sign. Quit if the end of the string - has been reached. */ - c++; - if( *c ) { - -/* If the % sign is followed by a "*" or another "%", then there will be no - corresponding pointer in the variable argument list "args". Ignore such - field specifiers. */ - if( *c != '*' && *c != '%' ) { - -/* If possible store the corresponding pointer from the variable argument - list supplied to this function. Report an error if there are too many. */ - if ( nptr < VMAXFLD ) { - ptr[ nptr++ ] = va_arg( args, void *); - -/* If the current field specifier is "%n" the corresponding pointer - should be a pointer to an integer. We initialise the integer to zero. - We need to do this because sscanf does not include "%n" values in the - returned count of succesful conversions, and so there is no sure way - of knowing whether a value has been stored for a "%n" field, and so - whether it is safe to use it as an index into the supplied. */ - if( *c == 'n' ) *( (int *) ptr[ nptr - 1 ] ) = 0; - - } else { - astError( AST__INTER, "astSscanf: Format string " - "'%s' contains more than %d fields " - "(AST internal programming error).", status, - fmt, VMAXFLD ); - break; - } - } - -/* Move on the first character following the field specifier. */ - c++; - } - -/* If this is not the start of a field specifier, pass on. */ - } else { - c++; - } - } - -/* Fill any unused pointers with NULL. */ - for( iptr = nptr; iptr < VMAXFLD; iptr++ ) ptr[iptr] = NULL; - -/* Get the length of the string to be scanned. */ - lstr = strlen( str ); - -/* Get the length of the format string excluding any trailing white space. */ - lfor = astChrLen( fmt ); - -/* Bill Joye reports that MacOS sscanf fails to return the correct number of - characters read (using a %n conversion) if there is a space before the - %n. So check for this. Does the format string contain " %n"? */ - c = strstr( fmt, " %n" ); - if( c && astOK ) { - -/* Take a copy of the supplied format string (excluding any trailing spaces). */ - newfor = (char *) astStore( NULL, (void *) fmt, (size_t) lfor + 1 ); - if( newfor ) { - -/* Ensure the string is terminated (in case the supplied format string - has any trailing spaces). */ - newfor[ lfor ] = 0; - -/* Remove all spaces from before any %n. */ - c = strstr( (const char *) newfor, " %n" ); - while( c ) { - while( *(c++) ) *( c - 1 ) = *c; - c = strstr( newfor, " %n" ); - } - -/* Use the native sscanf with the modified format string. Note, we cannot - use vsscanf because it is not ANSI C. Instead, we list the pointers - explicitly. */ - ret = sscanf( str, newfor, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], - ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], - ptr[15], ptr[16], ptr[17], ptr[18], ptr[19] ); - -/* Now look through the original format string for conversions specifiers. - If any %n conversions are found which are preceded by a space, then - correct the returned character counts to include any spaces following the - corresponding point in the scanned string. */ - nfld = 0; - iptr = 0; - c = (char *) fmt; - while( *c ) { - -/* Field specifiers are marked by a % sign. */ - if( *c == '%' ) { - -/* Look at the character following the % sign. Quit if the end of the string - has been reached. */ - c++; - if( *c ) { - -/* If the % sign is followed by a "*" or another "%", then there will be no - corresponding pointer in the variable argument list "args". Ignore such - field specifiers. */ - if( *c != '*' && *c != '%' ) { - -/* Get the supplied pointer corresponding to this field specifier. */ - fptr = ptr[ iptr++ ]; - -/* Increment the number of matched fields required. "%n" specifiers are not - included in the value returned by sscanf so skip over them. */ - if( *c != 'n' ) { - nfld++; - -/* If the % sign is followed by a "n", and was preceded by a space, we - may need to correct the returned character count. */ - } else if( c > fmt + 1 && *(c-2) == ' ' ) { - -/* Do not correct the returned value if sscanf did not get as far as this - field specifier before an error occurred. */ - if( ret >= nfld ) { - -/* Get the original character count produced by sscanf. */ - nc = *( (int *) fptr ); - -/* For each space in "str" which follows, increment the returned count by - one (so long as the original count is not zero or more than the length - of the string - this is not foolproof, but I can't think of a better - check - all uses of %n in AST initialize the supplied count to zero - before calling sscanf so a value fo zero is a safe (ish) bet that the - supplied string doesn't match the supplied format). */ - if( nc > 0 && nc < lstr ) { - d = str + nc; - while( *(d++) == ' ' ) nc++; - *( (int *) fptr ) = nc; - } - } - } - } - -/* Move on the first character following the field specifier. */ - c++; - } - -/* If this is not the start of a field specifier, pass on. */ - } else { - c++; - } - } - -/* Release the temporary copy of the format string. */ - newfor = (char *) astFree( (void *) newfor ); - } - -/* If the format string should not trigger any known problems, use sscanf - directly. */ - } else if( astOK ) { - ret = sscanf( str, fmt, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], - ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], - ptr[15], ptr[16], ptr[17], ptr[18], ptr[19] ); - } - } - -/* Tidy up the argument pointer. */ - va_end( args ); - -/* Return the answer. */ - return ret; - -} - - -/* The next functions are used only when memory debugging is - switched on via the MEM_DEBUG macro. They can be used for locating - memory leaks, etc. */ -#ifdef MEM_DEBUG - -void astActiveMemory_( const char *label ) { -/* -*+ -* Name: -* astActiveMemory - -* Purpose: -* Display a list of any currently active AST memory pointers. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* astActiveMemory( const char *label ) - -* Description: -* This function displays a list of the identifiers for all currently -* active AST memory chunks. The list is written to standard output -* using "printf", preceded by the supplied text. - -* Parameters: -* label -* A textual label to display before the memody id values (may be -* NULL). - -* Notes: -* - This function attempts to execute even if an error has occurred. -* - Memory blocks which are not usually freed are not reported. Such -* blocks are typically used by AST to hold internal state information. -*- -*/ - - Memory *next; - - if( label ) printf("%s: ", label ); - next = Active_List; - if( next ) { - while( next ) { - if( !next->perm ) { - printf( "%d(%s:%d) ", next->id, next->file, next->line ); - } - next = next->next; - } - } else { - printf("There are currently no active AST memory blocks."); - } - printf("\n"); - -} - -void astWatchMemory_( int id ) { -/* -*+ -* Name: -* astWatchMemory - -* Purpose: -* Indicate uses of the memory block with the specified identifier -* should be reported. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* astWatchMemory( int id ) - -* Description: -* This function forces astMemoryAlarm to be invoked when key -* operations are performed on a specified memory block. These key -* operations include; allocation, freeing, copying and cloning of -* Objects, etc. -* -* astMemoryAlarm reports a message when called identifying the memory -* block and the action performed on it. When using a debugger, these -* events can be trapped and investigated by setting a debugger -* breakpoint in astMemoryAlarm_. - -* Parameters: -* id -* The identifier of the memory block which is to be watched. - -* Notes: -* - This function attempts to execute even if an error has occurred. -*- -*/ - Watched_ID = id; -} - -int astMemoryId_( const void *ptr, int *status ){ -/* -*+ -* Name: -* astMemoryId - -* Purpose: -* Return the integer identifier for a memory block. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* int astMemoryId( const void *ptr ) - -* Description: -* This function returns the integer identifier associated with a -* memory block allocated by function sin this module. - -* Parameters: -* ptr -* The pointer (a genuine C pointer, not an encoded object -* identifier). - -* Returned Value: -* The integer identifier. A value of -1 is returned if "ptr" is NULL. - -*- -*/ - astDECLARE_GLOBALS - astGET_GLOBALS(NULL); - return ptr ? ((Memory *)(ptr-SIZEOF_MEMORY))->id : -1; -} - -void *astMemoryPtr_( int id ){ -/* -*+ -* Name: -* astMemoryPtr - -* Purpose: -* Return a pointer to the memory block with a given identifier. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* void *astMemoryPtr( int id ) - -* Description: -* This function returns a pointer to the memory block with a given -* identifier. NULL is returned if the given identifier is not active. - -* Parameters: -* id -* The identifier for an active memory block. - -* Returned Value: -* The pointer to the memory block. NULL is returned if no active memory -* with the given ID can be found. Note, this is always a genuine C -* pointer (even for public Object pointers). - -*- -*/ - Memory *next; - void *ret; - - ret = NULL; - next = Active_List; - while( next ) { - if( next->id == id ) { - ret = next + 1; - break; - } - } - - return ret; -} - -void astMemoryAlarm_( const char *verb ){ -/* -*+ -* Name: -* astMemoryAlarm - -* Purpose: -* Called when a watched memory ID is used. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* void astMemoryAlarm( const char *verb ) - -* Description: -* This function is called when a watched memory ID is used. See -* astWatchMemory. - -* Parameters: -* verb -* Text to include in message. -*- -*/ - - printf( "astMemoryAlarm: Memory id %d has been %s.\n", Watched_ID, verb ); -} - -void astMemoryStats_( int reset, size_t *peak, size_t *current, int *status ) { -/* -*+ -* Name: -* astMemoryStats - -* Purpose: -* Return the current and peak AST memory usage. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* astMemoryStats( int reset, size_t *peak, size_t *current ) - -* Description: -* This function returns the current amount of memory allocated -* using AST memory management functions, and the peak amount of -* simultaneously allocated memory since the last time the peak value -* was reset. - -* Parameters: -* reset -* If non-zero, the peak value is reset to the current usage -* upon return. -* peak -* Address at which to return the peak memory usage since the last -* reset, in bytes. -* current -* Address at which to return the current memory usage, in bytes. - -*- -*/ - - LOCK_DEBUG_MUTEX; - - if( peak ) *peak = Peak_Usage; - if( current ) *current = Current_Usage; - if( reset ) Peak_Usage = Current_Usage; - - UNLOCK_DEBUG_MUTEX; -} - -void astMemoryWarning_( size_t threshold, int *status ) { -/* -*+ -* Name: -* astMemoryWarning - -* Purpose: -* Issues a warning memory goes over a specified threshold. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* astMemoryWarning( size_t threshold ) - -* Description: -* This function prints a warning message to standard output if the -* AST memory usage exceeds the specified threshold. - -* Parameters: -* threshold -* The memory allocation, in bytes, at which a warning should be issued, -* Supply zero to suppress warnings. - -* Notes: -* - This function is used to reset the threshold to zero when the first -* warning is issued in order to prevent a flood of warnings appearing. -* Therefore, setting a debugger breakpoint in this function -* ("astMemoryWarning_" - do not forget the trailing underscore) -* allows you to locate the point at which memory allocation first -* exceeds the threshold. - -*- -*/ - - LOCK_DEBUG_MUTEX; - - Warn_Usage = threshold; - - UNLOCK_DEBUG_MUTEX; -} - -void astMemoryUse_( const void *ptr, const char *verb, int *status ){ -/* -*+ -* Name: -* astMemoryUse - -* Purpose: -* Called to report the use of a memory block pointer. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* void astMemoryUse( void *ptr, const char *verb ) - -* Description: -* If the supplied memory block is being watched, astMemoryAlarm is -* called to report the use of the pointer. The reported text includes -* the supplied "verb". A memory block can be watched by calling -* astWatchMemory. - -* Parameters: -* ptr -* A pointer to the memory block being used. The pointer must have -* been returned by one of the AST memory management functions (e.g. -* astMalloc, astRealloc, etc). -* verb -* A verb indicating what is being done to the pointer. -*- -*/ - - astDECLARE_GLOBALS - astGET_GLOBALS(NULL); - - if( ptr && astMemoryId( ptr ) == Watched_ID ) { - if( !Quiet_Use || !strcmp( verb, ISSUED ) || - !strcmp( verb, FREED ) ) { - astMemoryAlarm( verb ); - } - } -} - -int astMemoryTune_( const char *name, int value, int *status ){ -/* -*+ -* Name: -* astMemoryTune - -* Purpose: -* Set a tuning parameter for the memory debugging functions. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* int astMemoryTune( const char *name, int value ) - -* Description: -* There are a few tuning parameters which control the behaviour of -* the memory debugging functions. This function allows these tuning -* parameters to be queried or set. - -* Parameters: -* name -* The name of the tuning parameter to query or set. Valid names are: -* -* "Keep_ID": A boolean flag indicating if a new ID should be issued -* for a cached memory block each time it is returned by astMalloc? -* Otherwise, the same ID value is used throughtout the life of a -* memory block. Default is zero (false). -* -* "List_Cache": A boolean flag which if non-zero (true) causes the -* ID of every memory block in the cache to be reported when the -* cache is emptied by astFlushMemory. -* -* "Quiet_Use": A boolean flag controlling the number of reports issued -* when a memory block is being watched (see astWatchMemory). If -* non-zero (true), then the only events which are reported are the -* issuing of a memory block pointer by astMalloc or astRealloc,and -* the freeing (or caching) of a memory block by astFree. If Quiet_Use -* is zero (the default), then additional reports are made for -* memory blocks used to hold AST Objects whenever the Object is -* copied, cloned, or checked. -* value -* The new value for the tuning parameter. If AST__TUNULL is -* supplied, the original value is left unchanged. - -* Returned Value: -* The original value of the tuning parameter. - -*- -*/ - - int result = AST__TUNULL; - - if( name ) { - - if( astChrMatch( name, "Keep_ID" ) ) { - result = Keep_ID; - if( value != AST__TUNULL ) Keep_ID = value; - - } else if( astChrMatch( name, "Quiet_Use" ) ) { - result = Quiet_Use; - if( value != AST__TUNULL ) Quiet_Use = value; - - } else if( astChrMatch( name, "List_Cache" ) ) { - result = List_Cache; - if( value != AST__TUNULL ) List_Cache = value; - - } else if( astOK ) { - astError( AST__TUNAM, "astMemoryTune: Unknown AST memory tuning " - "parameter specified \"%s\".", status, name ); - } - } - - return result; -} - -void astBeginPM_( int *status ) { -/* -*+ -* Name: -* astBeginPM - -* Purpose: -* Start a block of permanent memory allocations. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* astBeginPM - -* Description: -* This function indicates that all memory allocations made by calls -* to other functions in this module (e.g. astMalloc), up to the -* astEndPM call which matches the astBeginPM call, will not usually -* be freed explicitly. Matching astBeginPM/astEndPM calls should be -* used to enclose all code which allocates memory which is never -* freed explitly by AST. Such memory allocations may be freed if -* required, using the astFlushMemory function (but note this should -* only be done once all use of AST by an application has finished). -* -* Matching pairs of astBeginPM/astEndPM calls can be nested up to a -* maximum depth of 20. - -*- -*/ - - LOCK_DEBUG_MUTEX; - -/* The global Perm_Mem flag indicates whether or not subsequent memory - management functions in this module should store pointers to allocated - blocks in the PM_List array. Push the current value of this flag - onto a stack, and set the value to 1. */ - if( PM_Stack_Size >= PM_STACK_MAXSIZE ){ - if( astOK ) { - astError( AST__INTER, "astBeginPM: Maximum stack size has been " - "exceeded (internal AST programming error)." , status); - } - - } else { - PM_Stack[ PM_Stack_Size++ ] = Perm_Mem; - Perm_Mem = 1; - } - UNLOCK_DEBUG_MUTEX; -} - -void astEndPM_( int *status ) { -/* -*+ -* Name: -* astEndPM - -* Purpose: -* End a block of permanent memory allocations. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* astEndPM - -* Description: -* This function indicates the end of the block of permanent memory -* allocations started by the matching call to astBeginPM. See -* astBeginPM for further details. - -*- -*/ - - LOCK_DEBUG_MUTEX; - -/* The global Perm_Mem flag indicates whether or not subsequent memory - management functions in this module should store pointers to allocated - blocks in the PM_List array. Pop the value from the top of this stack. */ - if( PM_Stack_Size == 0 ){ - if( astOK ) { - astError( AST__INTER, "astEndPM: astEndPM called without " - "matching astBeginPM (internal AST programming error)." , status); - } - - } else { - Perm_Mem = PM_Stack[ --PM_Stack_Size ]; - } - - UNLOCK_DEBUG_MUTEX; -} - -void astFlushMemory_( int leak, int *status ) { -/* -*+ -* Name: -* astFlushMemory - -* Purpose: -* Free all permanent and cached memory blocks. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* astFlushMemory( int leak ); - -* Description: -* This function should only be called once all use of AST by an -* application has finished. It frees any allocated but currently -* unused memory stored in an internal cache of unused memory -* pointers. (Note, it does not free any memory used permanently to -* store internal AST state information). -* -* It is not normally necessary to call this function since the memory -* will be freed anyway by the operating system when the application -* terminates. However, it can be called if required in order to -* stop memory management tools such as valgrind from reporting that -* the memory has not been freed at the end of an application. -* -* In addition, if "leak" is non-zero this function will also report -* an error if any active AST memory pointers remain which have not -* been freed (other than pointers for the cached and permanent -* memory described above). Leakage of active memory blocks can be -* investigated using astActiveMemory and astWatchMemory. - -* Parameters: -* leak -* Should an error be reported if any non-permanent memory blocks -* are found to be active? - -*- -*/ - -/* Local Variables: */ - Memory *next; - int nact; - int istat; - -/* Empty the cache. */ - astMemCaching( astMemCaching( AST__TUNULL ) ); - -/* Free and count all non-permanent memory blocks. */ - nact = 0; - next = Active_List; - while( Active_List ) { - next = Active_List->next; - if( !Active_List->perm ) { - nact++; - FREE( Active_List ); - } - Active_List = next; - } - -/* Report an error if any active pointers remained. if an error has - already occurred, use the existing status value. */ - if( nact && leak ){ - - if( astOK ) { - istat = AST__INTER; - } else { - istat = astStatus; - } - astError( istat, "astFlushMemory: %d AST memory blocks have not " - "been released (programming error).", status, nact ); - - } else { - printf("astFlushMemory: All AST memory blocks were released correctly.\n" ); - } -} - -void astCheckMemory_( int *status ) { -/* -*+ -* Name: -* astCheckMemory - -* Purpose: -* Check that all AST memory blocks have been released. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* astCheckMemory - -* Description: -* This macro reports an error if any active AST memory pointers -* remain which have not been freed (other than pointers for cached -* and "permanently allocated" memory). Leakage of active memory blocks -* can be investigated using astActiveMemory and astWatchMemory. -*- -*/ - -/* Local Variables: */ - Memory *next; - int nact; - int istat; - -/* Empty the cache. */ - astMemCaching( astMemCaching( AST__TUNULL ) ); - -/* Count all non-permanent memory blocks. */ - nact = 0; - next = Active_List; - while( Active_List ) { - next = Active_List->next; - if( !Active_List->perm ) nact++; - Active_List = next; - } - -/* Report an error if any active pointers remained. If an error has - already occurred, use the existing status value. */ - if( nact ){ - - if( astOK ) { - istat = AST__INTER; - } else { - istat = astStatus; - } - astError( istat, "astCheckMemory: %d AST memory blocks have not " - "been released (programming error).", status, nact ); - - } else { - printf("astCheckMemory: All AST memory blocks were released correctly.\n" ); - } -} - -static void Issue( Memory *mem, int *status ) { -/* -* Name: -* Issue - -* Purpose: -* Indicate that a pointer to a memory block has been issued. - -* Type: -* Private function. - -* Synopsis: -* #include "memory.h" -* void Issue( Memory *mem, int *status ); - -* Description: -* Initialises the extra debug items in the Memory header, and adds the -* Memory structure to the list of active memory blocks. - -* Parameters: -* mem -* Pointer to the Memory structure. -* status -* Pointer to the inherited status value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - -/* Return if no pointer was supplied. */ - if( !mem ) return; - - LOCK_DEBUG_MUTEX; - astGET_GLOBALS(NULL); - -/* Store a unique identifier for this pointer. Unless global Keep_ID is - non-zero, a new identifier is used each time the pointer becomes active - (i.e. each time it is remove from the cache or malloced). */ - if( !Keep_ID || mem->id < 0 ) mem->id = ++Next_ID; - -/* Record the file name and line number where it was issued. */ - if( AST__GLOBALS && AST__GLOBALS->Error.Current_File ) { - strncpy( mem->file, AST__GLOBALS->Error.Current_File, sizeof(mem->file) ); - mem->file[ sizeof(mem->file) - 1 ] = 0; - mem->line = AST__GLOBALS->Error.Current_Line; - } else { - mem->file[ 0 ] = 0; - mem->line = 0; - } - -/* Indicate if this is a permanent memory block (i.e. it will usually not - be freed by AST). */ - mem->perm = Perm_Mem; - -/* Add it to the double linked list of active pointers. */ - mem->next = Active_List; - mem->prev = NULL; - if( Active_List ) Active_List->prev = mem; - Active_List = mem; - -/* Report that the pointer is being issued. */ - astMemoryUse( (void *) mem + SIZEOF_MEMORY, ISSUED ); - -/* Update the current and peak memory usage. */ - Current_Usage += mem->size + SIZEOF_MEMORY; - if( Current_Usage > Peak_Usage ) Peak_Usage = Current_Usage; - -/* If the current allocation is above the threshold set using - astMemoryWarning, issue a warning message, and then reset the threshold - to zero to prevent further warnings being issued, and to allow a - debugger breakpoint to be set. */ - if( Current_Usage > Warn_Usage && - Warn_Usage > 0 ) { - printf( "Warning - AST memory allocation has exceeded %ld bytes - " - "dumping catalogue of active memory blocks to file 'memory.dump'\n", - Warn_Usage ); - -/* Create a file holding the details of all currently active memory blocks. It can be - examined using topcat. */ - FILE *fd = fopen( "memory.dump", "w" ); - if( fd ) { - Memory *next; - - fprintf( fd, "# id size perm file line\n"); - next = Active_List; - if( next ) { - while( next ) { - if( !next->perm ) { - fprintf( fd, "%d %zu %d %s %d\n", next->id, next->size, - next->perm, next->file, next->line ); - } - next = next->next; - } - } - - fclose(fd ); - } - - Warn_Usage = 0; - } - - UNLOCK_DEBUG_MUTEX; -} - -static void DeIssue( Memory *mem, int *status ) { -/* -* Name: -* DeIssue - -* Purpose: -* Indicate that a pointer to a memory block has been freed. - -* Type: -* Private function. - -* Synopsis: -* #include "memory.h" -* void DeIssue( Memeory *mem, int *status ); - -* Description: -* Initialises the extra debug items in the Memory header, and adds the -* Memory structure to the list of active memory blocks. - -* Parameters: -* mem -* Pointer to the Memory structure. -* status -* Pointer to the inherited status value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - Memory *next; - Memory *prev; - -/* Return if no pointer was supplied. */ - if( !mem ) return; - - LOCK_DEBUG_MUTEX; - astGET_GLOBALS(NULL); - -/* Report that the pointer is being freed. */ - astMemoryUse( (void *) mem + SIZEOF_MEMORY, FREED ); - -/* Remove the block from the double linked list of active pointers. */ - next = mem->next; - prev = mem->prev; - if( prev ) prev->next = next; - if( next ) next->prev = prev; - if( mem == Active_List ) Active_List = next; - mem->next = NULL; - mem->prev = NULL; - -/* Update the current memory usage. */ - Current_Usage -= mem->size + SIZEOF_MEMORY; - - UNLOCK_DEBUG_MUTEX; -} - - -#endif - - - - - - -/* The next functions are used only when profiling AST application. */ -#ifdef MEM_PROFILE - - -void astStartTimer_( const char *file, int line, const char *name, int *status ) { -/* -*+ -* Name: -* astStartTimer - -* Purpose: -* Measure the time spent until the corresponding call to astStopTimer. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* void astStartTimer( const char *name ); - -* Description: -* This function looks for a timer with the specified name within the -* current parent timer. If no timer with the given name is found, a -* new timer is created and initialised to zero. The current absolute -* time (elapsed, user and system) is recorded in the timer. The new -* timer then becomes the current timer. - -* Parameters: -* name -* A label for the timer. This should be unique within the -* enclosing parent timer. - -* Notes: -* - This function should only be used in a single-threaded environment. -* - This function returns without action if timers are currently -* disabled (see astEnableTimers). - -*- -*/ - -/* Local Variables: */ - int n, found, i; - AstTimer *t; - struct tms buf; - -/* Check inherited status. Also return if timers are currently disabled. */ - if( !Enable_Timers || *status != 0 ) return; - -/* See if a timer with the given name exists in the list of child timers - within the current timer. */ - found = 0; - if( Current_Timer ) { - for( i = 0; i < Current_Timer->nchild; i++ ) { - t = Current_Timer->children[ i ]; - if( !strcmp( t->name, name ) ) { - found = 1; - break; - } - } - } - -/* If not, create and initialise one now, and add it into the list of - children within the current timer. */ - if( !found ) { - t = astMalloc( sizeof( AstTimer ) ); - t->id = Timer_Count++; - t->et = 0; - t->ut = 0; - t->st = 0; - t->nentry = 0; - t->name = name; - t->file = file; - t->line = line; - t->parent = Current_Timer; - t->nchild = 0; - t->children = NULL; - - if( Current_Timer ) { - n = (Current_Timer->nchild)++; - Current_Timer->children = astGrow( Current_Timer->children, - sizeof( AstTimer *), - Current_Timer->nchild ); - Current_Timer->children[ n ] = t; - } - } - -/* Record the current absolute times (elapsed, user and system) within - the new timer. */ - t->e0 = times(&buf); - t->u0 = buf.tms_utime; - t->s0 = buf.tms_stime; - -/* Increment the number of entries into the timer. */ - (t->nentry)++; - -/* Use the new timer as the current timer until the corresponding call to - astStopTimer. */ - Current_Timer = t; -} - -void astEnableTimers_( int enable, int *status ) { -/* -*+ -* Name: -* astEnableTimers - -* Purpose: -* Set a global flag indicating if the use of AST timers is enabled. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* void astStartTimer( int enable ); - -* Description: -* This function sets a global flag that enables otr disables the user -* of AST Timers. If timers are disabled, the astStartTimer and -* astStopTimer functions will return without action. - -* Parameters: -* enable -* If non-zero, timers will be used. - -* Notes: -* - This function should only be used in a single-threaded environment. - -*- -*/ - Enable_Timers = enable; -} - -void astStopTimer_( int *status ) { -/* -*+ -* Name: -* astStopTimer - -* Purpose: -* Record the time spent since the corresponding call to astStartTimer. - -* Type: -* Protected function. - -* Synopsis: -* #include "memory.h" -* void astStopTimer; - -* Description: -* This function obtains the time increments since the corresponding -* call to astStartTimer, and adds these increments onto the total -* times stored in the current timer. It then changes the current -* timer to be the parent timer associated the current timer on entry. -* -* If the current timer on entry has no parent (i.e. is a top level -* timer), the times spent in the top-level timer, and all its -* descendent timers, are displayed. - -* Notes: -* - This function should only be used in a single-threaded environment. -* - This function returns without action if timers are currently -* disabled (see astEnableTimers). - -*- -*/ - -/* Local Variables: */ - AstTimer *flat; - AstTimer *t; - int i; - int nflat; - struct tms buf; - -/* Check inherited status. Also return if timers are currently disabled. */ - if( !Enable_Timers || !Current_Timer || *status != 0 ) return; - -/* Get the current absolute times, and thus find the elapsed times since the - corresponding call to astStartTimer. Use these elapsed times to increment - the total times spent in the timer. */ - Current_Timer->et += ( times(&buf) - Current_Timer->e0 ); - Current_Timer->st += ( buf.tms_stime - Current_Timer->s0 ); - Current_Timer->ut += ( buf.tms_utime - Current_Timer->u0 ); - -/* If this is a top level timer, display the times spent in the current - timer, and in all its descendent timers. This also frees the memory - used by the timers. */ - if( !Current_Timer->parent ) { - flat = NULL; - nflat = 0; - Current_Timer = ReportTimer( Current_Timer, 0, &flat, &nflat, status ); - -/* Sort and display the flat list of timers, then free the memory used by - the flat list. */ - qsort( flat, nflat, sizeof( AstTimer), CompareTimers2 ); - printf("\n\n"); - t = flat; - for( i = 0; i < nflat; i++,t++ ) { - printf( "%s (%s:%d): ", t->name, t->file, t->line ); - printf( "elapsed=%ld ", (long int) t->et ); -/* - printf( "system=%ld ", (long int) t->st ); - printf( "user=%ld ", (long int) t->ut ); -*/ - printf( "calls=%d ", t->nentry ); - printf("\n"); - } - flat = astFree( flat ); - -/* If this is not a top level timer, restore the parent timer as the - curent timer. */ - } else { - Current_Timer = Current_Timer->parent; - } -} - -static AstTimer *ReportTimer( AstTimer *t, int ind, AstTimer **flat, - int *nflat, int *status ) { -/* -* Name: -* ReportTimer - -* Purpose: -* Free and report the times spent in a given timer, and all descendents. - -* Type: -* Private function. - -* Synopsis: -* #include "memory.h" -* AstTimer *ReportTimer( AstTimer *t, int ind, AstTimer **flat, -* int *nflat, int *status ) - -* Description: -* This routines reports to standard output the times spent in the -* supplied timer. It then calls itself recursively to report the times -* spent in each of the child timers of the supplied timer. -* -* It also frees the memory used to hold the supplied timer. - -* Parameters: -* t -* Pointer to the AstTimer structure. -* ind -* The number of spaces of indentation to display before the timer -* details. -* flat -* Address of a pointer to the start of an array of AstTimers. The -* number of elements in this array is given by "*nflat". Each -* Timer in this array holds the accumulated total for all entries -* into a given timer, from all parent contexts. -* nflat -* Address of an int holding the current length of the "*flat" array. -* status -* Pointer to the inherited status value. -*/ - -/* Local Variables: */ - int found; - int i; - AstTimer *ft; - AstTimer *parent; - -/* Check inherited status */ - if( *status != 0 ) return NULL; - -/* Display a single line of text containing the times stored in the supplied - timer, preceded by the requested number of spaces. */ - for( i = 0; i < ind; i++ ) printf(" "); - printf( "%s (%s:%d): ", t->name, t->file, t->line ); - - printf( "id=%d ", t->id ); - printf( "elapsed=%ld ", (long int) t->et ); -/* - printf( "system=%ld ", (long int) t->st ); - printf( "user=%ld ", (long int) t->ut ); -*/ - printf( "calls=%d ", t->nentry ); - -/* If there are any children, end the line with an opening bvrace. */ - if( t->nchild ) printf("{"); - printf("\n"); - -/* If there is more than one child, sort them into descending order of - elapsed time usage. */ - if( t->nchild > 1 ) qsort( t->children, t->nchild, sizeof( AstTimer * ), - CompareTimers ); - -/* Increment the indentation and call this function recursively to - display and free each child timer. */ - ind += 3; - for( i = 0; i < t->nchild; i++ ) { - (t->children)[ i ] = ReportTimer( (t->children)[ i ], ind, flat, - nflat, status ); - } - -/* Delimit the children by displaying a closing brace. */ - if( t->nchild ) { - for( i = 0; i < ind - 3; i++ ) printf(" "); - printf("}\n"); - } - -/* See if this timer is contained within itself at a higher level. */ - parent = t->parent; - while( parent && ( parent->line != t->line || - strcmp( parent->file, t->file ) ) ) { - parent = parent->parent; - } - -/* If not, search for a timer in the "flat" array of timers that has the same - source file and line number. */ - if( !parent ) { - found = 0; - ft = *flat; - for( i = 0; i < *nflat; i++, ft++ ) { - if( ft->line == t->line && - !strcmp( ft->file, t->file ) ) { - found = 1; - break; - } - } - -/* If not found, add a new timer to the end of the "flat" array and - initialise it. */ - if( !found ) { - i = (*nflat)++; - *flat = astGrow( *flat, *nflat, sizeof( AstTimer ) ); - ft = (*flat) + i; - ft->id = 0; - ft->et = t->et; - ft->ut = t->ut; - ft->st = t->st; - ft->nentry = t->nentry; - ft->name = t->name; - ft->file = t->file; - ft->line = t->line; - ft->parent = NULL; - ft->nchild = 0; - ft->children = NULL; - - -/* If found, increment the properites to include the supplied timer. */ - } else { - ft->et += t->et; - ft->ut += t->ut; - ft->st += t->st; - ft->nentry += t->nentry; - } - } - -/* Free the memory used by the supplied timer. */ - t->children = astFree( t->children ); - return astFree( t ); -} - - -static int CompareTimers( const void *a, const void *b ){ - return ((*((AstTimer **) b ))->et) - ((*((AstTimer **) a ))->et); -} - -static int CompareTimers2( const void *a, const void *b ){ - return (((AstTimer *) b )->et) - (((AstTimer *) a )->et); -} - -#endif diff --git a/ast/memory.h b/ast/memory.h deleted file mode 100644 index 7a631fb..0000000 --- a/ast/memory.h +++ /dev/null @@ -1,347 +0,0 @@ -#if !defined( MEMORY_INCLUDED ) /* Include this file only once */ -#define MEMORY_INCLUDED -/* -*+ -* Name: -* memory.h - -* Purpose: -* Define the interface to the Memory module. - -* Description: -* This module defines functions which wrap up and extend the -* standard C functions for performing memory allocation. They -* provide better security against memory leaks, etc., and should -* not be inter-mixed with the standard C functions. -* -* Note that this module is not a class implementation, although it -* resembles one. - -* Functions Defined: -* Public: -* None. -* -* Protected: -* astAppendString -* Append a string to another string which grows dynamically. -* astCalloc -* Allocate memory. -* astChrMatch -* Case-insensitive string comparison. -* astChrMatchN -* Case-insensitive string comparison of an most N characters. -* astFree -* Free previously allocated memory. -* astGrow -* Allocate memory for an adjustable array. -* astMalloc -* Allocate memory. -* astRealloc -* Change the size of a dynamically allocated region of memory. -* astSizeOf -* Determine the size of a dynamically allocated region of memory. -* astStore -* Store data in dynamically allocated memory. -* astString -* Create a C string from an array of characters. -* astStringArray -* Create an array of C strings from an array of characters. -* astStringCase -* Convert a string to upper or lower case. -* astChrLen -* Returns length of a string without trailing white space, etc. -* astChrTrunc -* Terminate a string to exclude trailing spaces. -* astSscanf -* Like sscanf, but fixes certain platform-specific bugs in the -* native sscanf implementation. -* astTSizeOf -* Determine the total size of a dynamically allocated region of memory. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: D.S. Berry (Starlink) - -* History: -* 8-JAN-1996 (RFWS): -* Original version. -* 26-JAN-1996 (RFWS) -* Added function interfaces. -* 20-JUN-1996 (RFWS): -* Added astString. -* 15-JUL-1996 (RFWS): -* Use improved prologue style, etc. and make all functions protected. -* 11-SEP-1996 (RFWS): -* Added astStringArray (original written by DSB). -* 18-MAR-1998 (RFWS): -* Make interface available for writing foreign language and -* graphics interfaces, etc. -* 18-MAR-1998 (RFWS): -* Added explicit arguments to function macros. -* 29-JAN-2002 (DSB): -* Added astChrLen and astSscanf. -* 15-NOV-2002 (DSB): -* Added astChrMatch astChrMatchN. -* 23-FEB-2006 (DSB): -* Added astMemCaching and AST__TUNULL. -* 2-MAR-2006 (DSB): -* Only use astSscanf if the system on which AST was configured -* showed the non-ANSI behaviour reported by Bill Joye. -* 27-JUN-2007 (DSB): -* Added astIsDynamic. -* 25-OCT-2007 (DSB): -* Added astRemoveLeadingBlanks. -* 22-FEB-2008 (DSB): -* Added astChrSub. -* 19-MAY-2010 (DSB): -* Added astStringCase. -* 26-MAR-2015 (DSB): -* Added astChrTrunc. - -*- -*/ - -/* Include files. */ -/* ============== */ -/* Configuration results. */ -/* ---------------------- */ -#if HAVE_CONFIG_H -#include -#endif - -/* C header files. */ -/* --------------- */ -#include -#include "error.h" - -/* Macros. */ -/* ======= */ - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif -#define AST__TUNULL -99999 -#define AST__TUNULLC "" - -/* Type definitions */ -/* ================ */ - -#if defined(astCLASS) - -/* Header for allocated memory. */ -/* ---------------------------- */ -/* This stores a "magic" value so that dynamically allocated memory - can be recognised, together with the allocated size. It also - ensures correct alignment. */ -typedef struct Memory { - struct Memory *next; - unsigned long magic; - size_t size; - -#ifdef MEM_DEBUG - struct Memory *prev; /* Pointer to the previous linked Memory structure */ - int id; /* A unique identifier for every allocated memory chunk */ - int perm; /* Is this chunk part of an acceptable once-off "memory leak"? */ - int line; /* Line number in "file" (below). */ - char file[50];/* The source file that made the top-level call to AST */ -#endif - -} Memory; - -/* Define the largest size of a cached memory block in bytes. This does - not include the size of the Memory header. This does not need to be - too big because the vast majority of memory blocks allocated by AST are - less than a few hundred bytes. */ -#define MXCSIZE 300 - -#endif - - -#if defined(THREAD_SAFE) && defined(astCLASS) - -/* Define a structure holding all data items that are global within the - memory.c file. */ -typedef struct AstMemoryGlobals { - size_t Sizeof_Memory; - int Cache_Init; - int Use_Cache; - Memory *Cache[ MXCSIZE + 1 ]; - -} AstMemoryGlobals; - -#endif - -/* Function prototypes. */ -/* ==================== */ - -#if defined(THREAD_SAFE) && defined(astCLASS) -void astInitMemoryGlobals_( AstMemoryGlobals * ); -#endif - -#if defined(astCLASS) || 1 /* Nominally protected, but available for */ - /* use in developing (e.g.) foreign */ - /* language or graphics interfaces. */ -int astMemCaching_( int, int * ); -void astChrCase_( const char *, char *, int, int, int * ); -char **astChrSplit_( const char *, int *, int * ); -char **astChrSplitRE_( const char *, const char *, int *, const char **, int * ); -char **astChrSplitC_( const char *, char, int *, int * ); -int astChrMatch_( const char *, const char *, int * ); -int astChrMatchN_( const char *, const char *, size_t, int * ); -char **astStringArray_( const char *, int, int, int * ); -char *astStringCase_( const char *, int, int * ); -char *astString_( const char *, int, int * ); -int astSscanf_( const char *str, const char *format, ...); -size_t astSizeOf_( const void *, int * ); -int astIsDynamic_( const void *, int * ); -size_t astTSizeOf_( const void *, int * ); -void *astFree_( void *, int * ); -void *astFreeDouble_( void *, int * ); -void *astGrow_( void *, int, size_t, int * ); -void *astCalloc_( size_t, size_t, int * ); -void *astMalloc_( size_t, int, int * ); -void *astRealloc_( void *, size_t, int * ); -void *astStore_( void *, const void *, size_t, int * ); -size_t astChrLen_( const char *, int * ); -double astChr2Double_( const char *, int * ); -void astRemoveLeadingBlanks_( char *, int * ); -char *astAppendString_( char *, int *, const char *, int * ); -char *astAppendStringf_( char *, int *, const char *, ... )__attribute__((format(printf,3,4))); -char *astChrSub_( const char *, const char *, const char *[], int, int * ); -void astChrTrunc_( char *, int * ); - -#ifdef MEM_PROFILE -void astStartTimer_( const char *, int, const char *, int * ); -void astStopTimer_( int * ); -void astEnableTimers_( int, int * ); -#endif - - -#ifdef MEM_DEBUG -void astActiveMemory_( const char * ); -void astWatchMemory_( int ); -void astCheckMemory_( int * ); -void astFlushMemory_( int, int * ); -int astMemoryTune_( const char *, int, int * ); -void *astMemoryPtr_( int ); -void astMemoryAlarm_( const char * ); -void astMemoryStats_( int , size_t *, size_t *, int * ); -void astMemoryWarning_( size_t, int * ); -void astMemoryUse_( const void *, const char *, int * ); -int astMemoryId_( const void *, int * ); -void astBeginPM_( int * ); -void astEndPM_( int * ); -#endif - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These wrap up the functions defined by this module. */ - -#define astCalloc(nmemb,size) astERROR_INVOKE(astCalloc_(nmemb,size,STATUS_PTR)) -#define astChrMatch(str1,str2) astERROR_INVOKE(astChrMatch_(str1,str2,STATUS_PTR)) -#define astChrMatchN(str1,str2,n) astERROR_INVOKE(astChrMatchN_(str1,str2,n,STATUS_PTR)) -#define astFree(ptr) astERROR_INVOKE(astFree_(ptr,STATUS_PTR)) -#define astFreeDouble(ptr) astERROR_INVOKE(astFreeDouble_(ptr,STATUS_PTR)) -#define astGrow(ptr,n,size) astERROR_INVOKE(astGrow_(ptr,n,size,STATUS_PTR)) -#define astMalloc(size) astERROR_INVOKE(astMalloc_(size,0,STATUS_PTR)) -#define astMemCaching(flag) astERROR_INVOKE(astMemCaching_(flag,STATUS_PTR)) -#define astRealloc(ptr,size) astERROR_INVOKE(astRealloc_(ptr,size,STATUS_PTR)) -#define astSizeOf(ptr) astERROR_INVOKE(astSizeOf_(ptr,STATUS_PTR)) -#define astIsDynamic(ptr) astERROR_INVOKE(astIsDynamic_(ptr,STATUS_PTR)) -#define astTSizeOf(ptr) astERROR_INVOKE(astTSizeOf_(ptr,STATUS_PTR)) -#define astStore(ptr,data,size) astERROR_INVOKE(astStore_(ptr,data,size,STATUS_PTR)) -#define astAppendString(str1,nc,str2) astERROR_INVOKE(astAppendString_(str1,nc,str2,STATUS_PTR)) -#define astAppendStringf astAppendStringf_ -#define astString(chars,nchars) astERROR_INVOKE(astString_(chars,nchars,STATUS_PTR)) -#define astStringArray(chars,nel,len) astERROR_INVOKE(astStringArray_(chars,nel,len,STATUS_PTR)) -#define astStringCase(string,toupper) astERROR_INVOKE(astStringCase_(string,toupper,STATUS_PTR)) -#define astChrLen(string) astERROR_INVOKE(astChrLen_(string,STATUS_PTR)) -#define astChrTrunc(string) astERROR_INVOKE(astChrTrunc_(string,STATUS_PTR)) -#define astChr2Double(string) astERROR_INVOKE(astChr2Double_(string,STATUS_PTR)) -#define astRemoveLeadingBlanks(string) astERROR_INVOKE(astRemoveLeadingBlanks_(string,STATUS_PTR)) -#define astChrSub(test,template,subs,nsub) astERROR_INVOKE(astChrSub_(test,template,subs,nsub,STATUS_PTR)) -#define astChrCase(in,out,upper,blen) astERROR_INVOKE(astChrCase_(in,out,upper,blen,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astMallocInit(size) astMalloc_(size,1,STATUS_PTR) -#endif - -#ifdef HAVE_NONANSI_SSCANF -#define astSscanf astERROR_INVOKE(astSscanf_) -#else -#define astSscanf astERROR_INVOKE(sscanf) -#endif -#define astChrSplit(str,n) astERROR_INVOKE(astChrSplit_(str,n,STATUS_PTR)) -#define astChrSplitC(str,c,n) astERROR_INVOKE(astChrSplitC_(str,c,n,STATUS_PTR)) -#define astChrSplitRE(str,c,n,m) astERROR_INVOKE(astChrSplitRE_(str,c,n,m,STATUS_PTR)) - - -#ifdef MEM_PROFILE -#define astStartTimer(name) astERROR_INVOKE(astStartTimer_(__FILE__,__LINE__,name,STATUS_PTR)) -#define astStopTimer astERROR_INVOKE(astStopTimer_(STATUS_PTR)) -#define astEnableTimers(enable) astERROR_INVOKE(astEnableTimers_(enable,STATUS_PTR)) -#endif - - -/* Functions used for debugging memory leaks, etc */ -#ifdef MEM_DEBUG - -#define astActiveMemory(label) astERROR_INVOKE(astActiveMemory_(label)) -#define astMemoryTune(name,value) astERROR_INVOKE(astMemoryTune_(name,value,STATUS_PTR)) -#define astWatchMemory(id) astERROR_INVOKE(astWatchMemory_(id)) -#define astCheckMemory astERROR_INVOKE(astCheckMemory_(STATUS_PTR)) -#define astFlushMemory(leak) astERROR_INVOKE(astFlushMemory_(leak,STATUS_PTR)) -#define astBeginPM astERROR_INVOKE(astBeginPM_(STATUS_PTR)) -#define astEndPM astERROR_INVOKE(astEndPM_(STATUS_PTR)) -#define astMemoryPtr(id) astERROR_INVOKE(astMemoryPtr_(id)) -#define astMemoryAlarm(text) astERROR_INVOKE(astMemoryAlarm_(text)) -#define astMemoryStats(reset,peak,current) astERROR_INVOKE(astMemoryStats_(reset,peak,current,STATUS_PTR)) -#define astMemoryWarning(threshold) astERROR_INVOKE(astMemoryWarning_(threshold,STATUS_PTR)) -#define astMemoryUse(ptr,text) astERROR_INVOKE(astMemoryUse_(ptr,text,STATUS_PTR)) -#define astMemoryId(ptr) astERROR_INVOKE(astMemoryId_(ptr,STATUS_PTR)) -#else - -#define astActiveMemory(label) -#define astMemoryTune(name,value) -#define astWatchMemory(id) -#define astCheckMemory -#define astFlushMemory(leak) -#define astBeginPM -#define astEndPM -#define astMemoryPtr(id) NULL -#define astMemoryAlarm(text) -#define astMemoryStats(reset,peak,current) -#define astMemoryUse(ptr,text) -#define astMemoryId(ptr) -#define astMemoryWarning(threshold) - -#endif - -#endif - - - diff --git a/ast/normmap.c b/ast/normmap.c deleted file mode 100644 index 3739739..0000000 --- a/ast/normmap.c +++ /dev/null @@ -1,1720 +0,0 @@ -/* -*class++ -* Name: -* NormMap - -* Purpose: -* Normalise coordinates using a supplied Frame. - -* Constructor Function: -c astNormMap -f AST_NORMMAP - -* Description: -* The NormMap class implements a Mapping which normalises coordinate -* values using the -c astNorm function -f AST_NORM routine -* of a supplied Frame. The number of inputs and outputs of a NormMap -* are both equal to the number of axes in the supplied Frame. -* -* The forward and inverse transformation of a NormMap are both -* defined but are identical (that is, they do not form a real inverse -* pair in that the inverse transformation does not undo the -* normalisation, instead it reapplies it). However, the -c astSimplify -f AST_SIMPLIFY -* function will replace neighbouring pairs of forward and inverse -* NormMaps by a single UnitMap (so long as the Frames encapsulated by -* the two NormMaps are equal - i.e. have the same class and the same -* attribute values). This means, for instance, that if a CmpMap contains -* a NormMap, the CmpMap will still cancel with its own inverse. - -* Inheritance: -* The NormMap class inherits from the Mapping class. - -* Attributes: -* The NormMap class does not define any new attributes beyond -* those which are applicable to all Mappings. - -* Functions: -c The NormMap class does not define any new functions beyond those -f The NormMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 11-JUL-2005 (DSB): -* Original version. -* 23-AUG-2006 (DSB): -* Override astEqual. -* 8-NOV-2016 (DSB): -* - Allow multiple identical NormMaps in series to be simplified to -* a single NormMap. -* - Allow a NormMap that contains a basic Frame to be simplified -* to a UnitMap. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS NormMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "unitmap.h" /* Unit Mappings */ -#include "normmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int *(* parent_mapsplit)( AstMapping *, int, const int *, AstMapping **, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(NormMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(NormMap,Class_Init) -#define class_vtab astGLOBAL(NormMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstNormMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstNormMap *astNormMapId_( void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *RemoveRegions( AstMapping *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Member functions. */ -/* ================= */ - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two NormMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "normmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* NormMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two NormMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a NormMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the NormMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstNormMap *that; - AstNormMap *this; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two NormMap structures. */ - this = (AstNormMap *) this_object; - that = (AstNormMap *) that_object; - -/* Check the second object is a NormMap. We know the first is a - NormMap since we have arrived at this implementation of the virtual - function. */ - if( astIsANormMap( that ) ) { - -/* Check the Invert flags for the two NormMaps are equal. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - -/* Check the two Frames are equal. */ - if( astEqual( this->frame, that->frame ) ) { - result = 1; - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -void astInitNormMapVtab_( AstNormMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitNormMapVtab - -* Purpose: -* Initialise a virtual function table for a NormMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "normmap.h" -* void astInitNormMapVtab( AstNormMapVtab *vtab, const char *name ) - -* Class Membership: -* NormMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the NormMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsANormMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - - mapping->RemoveRegions = RemoveRegions; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_mapsplit = mapping->MapSplit; - mapping->MapSplit = MapSplit; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - mapping->MapSplit = MapSplit; - mapping->Rate = Rate; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetDump( vtab, Dump, "NormMap", "Normalise axis values" ); - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* NormMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstNormMap *this; /* Pointer to NormMap structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the NormMap structure. */ - this = (AstNormMap *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->frame, mode, extra, fail ); - - return result; - -} -#endif - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a NormMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* NormMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated NormMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated NormMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated NormMap which is to be merged with -* its neighbours. This should be a cloned copy of the NormMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* NormMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated NormMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *frm1; - AstFrame *frm2; - AstMapping *smap; - AstNormMap *map; - AstNormMap *nmap1; - AstNormMap *nmap2; - const char *class; - int cancel; - int map_inv; - int nax; - int result; - -/* Initialise. */ - result = -1; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Initialisation to avoid compiler warnings. */ - nax = 0; - -/* Get a pointer to this NormMap. */ - map = (AstNormMap *) this; - -/* Temporarily set its Invert flag to the requested value. */ - map_inv = astGetInvert( map ); - astSetInvert( map, ( *invert_list )[ where ] ); - -/* First try to simplify the NormMap by simplifying its encapsulated - Frame. Get its class. */ - smap = astSimplify( map->frame ); - class = astGetClass( smap ); - -/* If any simplification took place, create a new NormMap with the - simplified Frame. */ - if( smap != (AstMapping *) map->frame ) { - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) astNormMap( (AstFrame *) smap, - "", status ); - result = where; - -/* If the encapsulated Frame is a basic Frame, we can safely assume that - the astNorm method does nothing, and so we can replace the NormMap with - a UnitMap. */ - } else if( class && !strcmp( class, "Frame" ) ) { - nax = astGetNin( smap ); - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) astUnitMap( nax, "", status ); - result = where; - -/* The only other simplications which can be performed are a) to cancel a NormMap - with its own inverse in series, or b) to remove duplicated adjacent - NormMaps in series. */ - } else if( series ) { - -/* Indicate we have nothing to cancel with as yet. */ - cancel = -1; - -/* First consider the lower neighbour. */ - if( where > 0 && astIsANormMap( ( *map_list )[ where - 1 ] ) ) { - -/* Check the Invert flags are opposite */ - if( ( *invert_list )[ where ] != ( *invert_list )[ where - 1 ] ) { - nmap1 = map; - nmap2 = (AstNormMap *) ( *map_list )[ where - 1 ]; - -/* Check the encapsulated Frames are equal. */ - frm1 = nmap1->frame; - frm2 = nmap2->frame; - if( astEqual( frm1, frm2 ) ) cancel = where - 1; - nax = astGetNout( nmap1 ); - } - } - -/* Likewise consider the upper neighbour. */ - if( cancel == -1 && where + 1 < *nmap && - astIsANormMap( ( *map_list )[ where + 1 ] ) ) { - - if( ( *invert_list )[ where ] != ( *invert_list )[ where + 1 ] ) { - nmap1 = map; - nmap2 = (AstNormMap *) ( *map_list )[ where + 1 ]; - frm1 = nmap1->frame; - frm2 = nmap2->frame; - if( astEqual( frm1, frm2 ) ) cancel = where + 1; - nax = astGetNin( nmap1 ); - } - } - -/* If we can cancel with a neightbour, do so. */ - if( cancel != -1 ) { - (void) astAnnul( ( *map_list )[ where ] ); - (void) astAnnul( ( *map_list )[ cancel ] ); - ( *map_list )[ where ] = (AstMapping *) astUnitMap( nax, "", status ); - ( *invert_list )[ where ] = 0; - ( *map_list )[ cancel ] = (AstMapping *) astUnitMap( nax, "", status ); - ( *invert_list )[ cancel ] = 0; - result = ( cancel < where ) ? cancel : where; - -/* Otherwise, see if the nominated NormMap is followed by one or more - identical NormMaps, in which case we can remove all but one of the - NormMaps. */ - } else { - -/* Loop round all subsequent Mappings until the end of the list is - reached, or a Mapping that is not a NormMap is reached. On each pass - we replace the NormMap with a UnitMap. */ - nax = astGetNin( map ); - cancel = where; - while( ++cancel < *nmap && - astIsANormMap( ( *map_list )[ cancel ] ) ) { - -/* Check the Invert flags are equal. */ - if( ( *invert_list )[ where ] == ( *invert_list )[ cancel ] ) { - -/* Check the Frames are equal .*/ - nmap2 = (AstNormMap *) ( *map_list )[ cancel ]; - if( astEqual( map->frame, nmap2->frame ) ) { - -/* Replace the later NormMap with a UnitMap. */ - (void) astAnnul( ( *map_list )[ cancel ] ); - ( *map_list )[ cancel ] = (AstMapping *) astUnitMap( nax, - "", status ); - -/* We return the index of the first modified Mapping in the list, so do - not update "result" if this is not the first change. */ - if( result == -1 ) result = cancel; - } - } - } - } - } - -/* Free resources. */ - smap = astAnnul( smap ); - -/* Reset the original Invert attribute for the specified NormMap */ - astSetInvert( map, map_inv ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* NormMap. - -* Type: -* Private function. - -* Synopsis: -* #include "normmap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* NormMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing NormMap. This is only possible if the specified inputs -* correspond to some subset of the NormMap outputs. That is, there -* must exist a subset of the NormMap outputs for which each output -* depends only on the selected NormMap inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied NormMap, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the NormMap to be split (the NormMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied NormMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied NormMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied NormMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstFrame *frm2; /* Pointer to new Frame */ - AstNormMap *this; /* Pointer to NormMap structure */ - int *result; /* Pointer to returned array */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the parent astMapSplit method to see if it can do the job. */ - result = (*parent_mapsplit)( this_map, nin, in, map, status ); - -/* If not, we provide a special implementation here. */ - if( !result ) { - -/* Get a pointer to the NormMap structure. */ - this = (AstNormMap *) this_map; - -/* Pick the requried axes from the encapsulated Frame. */ - frm2 = astPickAxes( this->frame, nin, in, NULL ); - -/* Create a new NormMap from this. */ - *map = (AstMapping *) astNormMap( frm2, "", status ); - -/* The returned list of output axes is a copy the supplied list of input - axes. */ - result = astStore( NULL, in, sizeof( int )*(size_t) nin ); - -/* Free resources. */ - frm2 = astAnnul( frm2 ); - } - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "normmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* NormMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -*/ - - return ( ax1 == ax2 ) ? 1.0 : 0.0; -} - -static AstMapping *RemoveRegions( AstMapping *this_mapping, int *status ) { -/* -* Name: -* RemoveRegions - -* Purpose: -* Remove any Regions from a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "normmap.h" -* AstMapping *RemoveRegions( AstMapping *this, int *status ) - -* Class Membership: -* NormMap method (over-rides the astRemoveRegions method inherited -* from the Mapping class). - -* Description: -* This function searches the supplied Mapping (which may be a -* compound Mapping such as a CmpMap) for any component Mappings -* that are instances of the AST Region class. It then creates a new -* Mapping from which all Regions have been removed. If a Region -* cannot simply be removed (for instance, if it is a component of a -* parallel CmpMap), then it is replaced with an equivalent UnitMap -* in the returned Mapping. -* -* The implementation provided by the NormMap class invokes the -* astRemoveRegions method on the encapsulated Frame, and returns a -* new NormMap containing the resulting Frame. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the modified mapping. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *newfrm; /* New component Frame */ - AstMapping *result; /* Result pointer to return */ - AstNormMap *new; /* Pointer to new MormMap */ - AstNormMap *this; /* Pointer to NormMap structure */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the NormMap. */ - this = (AstNormMap *) this_mapping; - -/* Invoke the astRemoveRegions method on the component Frame. */ - newfrm = astRemoveRegions( this->frame ); - -/* If the Frame was not modified, just return a clone of the supplied - pointer. */ - if( this->frame == newfrm ) { - result = astClone( this ); - -/* Otherwise, we need to create a new NormMap to return. We take a deep - copy of the supplied NormMap and then modify the Frame so that we - retain any extra information in the supplied NormMap. */ - } else { - new = astCopy( this ); - (void) astAnnul( new->frame ); - new->frame = astClone( newfrm ); - result = (AstMapping *) new; - } - -/* Free resources. */ - newfrm = astAnnul( newfrm ); - -/* Annul the returned Mapping if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a NormMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "normmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* NormMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a NormMap and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required zoom -* factor. - -* Parameters: -* this -* Pointer to the NormMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the NormMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstNormMap *map; /* Pointer to NormMap to be applied */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *work; /* Work space for a single point */ - int coord; /* Loop counter for coordinates */ - int ncoord_in; /* Number of coordinates per input point */ - int npoint; /* Number of points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the NormMap. */ - map = (AstNormMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - ncoord_in = astGetNcoord( in ); - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - work = astMalloc( sizeof( double )* ncoord_in ); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - for ( point = 0; point < npoint; point++ ) { - for ( coord = 0; coord < ncoord_in; coord++ ) { - work[ coord ] = ptr_in[ coord ][ point ]; - } - astNorm( map->frame, work ); - for ( coord = 0; coord < ncoord_in; coord++ ) { - ptr_out[ coord ][ point ] = work[ coord ]; - } - } - } - -/* Free resources */ - work = astFree( work ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for NormMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for NormMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the -* Frame within the NormMap. -*/ - -/* Local Variables: */ - AstNormMap *in; /* Pointer to input NormMap */ - AstNormMap *out; /* Pointer to output NormMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - - in = (AstNormMap *) objin; - out = (AstNormMap *) objout; - out->frame = astCopy( in->frame ); -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for NormMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for NormMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstNormMap *this; /* Pointer to NormMap */ - - this = (AstNormMap *) obj; - this->frame = astAnnul( this->frame ); - -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for NormMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the NormMap class to an output Channel. - -* Parameters: -* this -* Pointer to the NormMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstNormMap *this; /* Pointer to the NormMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the NormMap structure. */ - this = (AstNormMap *) this_object; - -/* Write out values representing the instance variables for the - NormMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* Frame. */ -/* ------ */ - astWriteObject( channel, "Frame", 1, 1, this->frame, - "Frame defining the normalisation" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsANormMap and astCheckNormMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(NormMap,Mapping) -astMAKE_CHECK(NormMap) - -AstNormMap *astNormMap_( void *frame_void, const char *options, int *status, ...) { -/* -*++ -* Name: -c astNormMap -f AST_NORMMAP - -* Purpose: -* Create a NormMap. - -* Type: -* Public function. - -* Synopsis: -c #include "normmap.h" -c AstNormMap *astNormMap( AstFrame *frame, const char *options, ... ) -f RESULT = AST_NORMMAP( FRAME, OPTIONS, STATUS ) - -* Class Membership: -* NormMap constructor. - -* Description: -* This function creates a new NormMap and optionally initialises its -* attributes. -* -* A NormMap is a Mapping which normalises coordinate values using the -c astNorm function -f AST_NORM routine -* of the supplied Frame. The number of inputs and outputs of a NormMap -* are both equal to the number of axes in the supplied Frame. -* -* The forward and inverse transformation of a NormMap are both -* defined but are identical (that is, they do not form a real inverse -* pair in that the inverse transformation does not undo the -* normalisation, instead it reapplies it). However, the -c astSimplify -f AST_SIMPLIFY -* function will replace neighbouring pairs of forward and inverse -* NormMaps by a single UnitMap (so long as the Frames encapsulated by -* the two NormMaps are equal - i.e. have the same class and the same -* attribute values). This means, for instance, that if a CmpMap contains -* a NormMap, the CmpMap will still cancel with its own inverse. - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* A pointer to the Frame which is to be used to normalise the -* supplied axis values. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new NormMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new NormMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astNormMap() -f AST_NORMMAP = INTEGER -* A pointer to the new NormMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* The Frame pointer */ - AstNormMap *new; /* Pointer to new NormMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate pointers to the Frame structures provided. */ - frame = astCheckFrame( frame_void ); - -/* Initialise the NormMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitNormMap( NULL, sizeof( AstNormMap ), !class_init, &class_vtab, - "NormMap", frame ); - if( astOK ) { - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new NormMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new NormMap. */ - return new; -} - -AstNormMap *astNormMapId_( void *frame_void, const char *options, ... ) { -/* -* Name: -* astNormMapId_ - -* Purpose: -* Create a NormMap. - -* Type: -* Private function. - -* Synopsis: -* #include "normmap.h" -* AstNormMap *astNormMapId_( int ncoord, double zoom, -* const char *options, ... ) - -* Class Membership: -* NormMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astNormMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astNormMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astNormMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astNormMap_. - -* Returned Value: -* The ID value associated with the new NormMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* The Frame pointer */ - AstNormMap *new; /* Pointer to new NormMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate pointers to the Frame structures provided. */ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - -/* Initialise the NormMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitNormMap( NULL, sizeof( AstNormMap ), !class_init, &class_vtab, - "NormMap", frame ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new NormMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new NormMap. */ - return astMakeId( new ); -} - -AstNormMap *astInitNormMap_( void *mem, size_t size, int init, - AstNormMapVtab *vtab, const char *name, - AstFrame *frame, int *status ) { -/* -*+ -* Name: -* astInitNormMap - -* Purpose: -* Initialise a NormMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "normmap.h" -* AstNormMap *astInitNormMap( void *mem, size_t size, int init, -* AstNormMapVtab *vtab, const char *name, -* AstFrame *frame ) - -* Class Membership: -* NormMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new NormMap object. It allocates memory (if necessary) to accommodate -* the NormMap plus any additional data associated with the derived class. -* It then initialises a NormMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a NormMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the NormMap is to be initialised. -* This must be of sufficient size to accommodate the NormMap data -* (sizeof(NormMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the NormMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the NormMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the NormMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new NormMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* The Frame to use to do the normalisations. - -* Returned Value: -* A pointer to the new NormMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstNormMap *new; /* Pointer to new NormMap */ - int ncoord; /* Number of input and output coords */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitNormMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Get the number of axes in the Frame. */ - ncoord = astGetNaxes( frame ); - -/* Initialise a Mapping structure (the parent class) as the first component - within the NormMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstNormMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - ncoord, ncoord, 1, 1 ); - - if ( astOK ) { - -/* Initialise the NormMap data. */ -/* ---------------------------- */ -/* Store a pointer to the Frame. */ - new->frame = astClone( frame ); - -/* If an error occurred, clean up by deleting the new NormMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new NormMap. */ - return new; -} - -AstNormMap *astLoadNormMap_( void *mem, size_t size, - AstNormMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadNormMap - -* Purpose: -* Load a NormMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "normmap.h" -* AstNormMap *astLoadNormMap( void *mem, size_t size, -* AstNormMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* NormMap loader. - -* Description: -* This function is provided to load a new NormMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* NormMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a NormMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the NormMap is to be -* loaded. This must be of sufficient size to accommodate the -* NormMap data (sizeof(NormMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the NormMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the NormMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstNormMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new NormMap. If this is NULL, a pointer -* to the (static) virtual function table for the NormMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "NormMap" is used instead. - -* Returned Value: -* A pointer to the new NormMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstNormMap *new; /* Pointer to the new NormMap */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this NormMap. In this case the - NormMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstNormMap ); - vtab = &class_vtab; - name = "NormMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitNormMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built NormMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "NormMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Frame. */ -/* ------ */ - new->frame = astReadObject( channel, "frame", NULL ); - -/* If an error occurred, clean up by deleting the new NormMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new NormMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - diff --git a/ast/normmap.h b/ast/normmap.h deleted file mode 100644 index 5336e56..0000000 --- a/ast/normmap.h +++ /dev/null @@ -1,217 +0,0 @@ -#if !defined( NORMMAP_INCLUDED ) /* Include this file only once */ -#define NORMMAP_INCLUDED -/* -*+ -* Name: -* normmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the NormMap class. - -* Invocation: -* #include "normmap.h" - -* Description: -* This include file defines the interface to the NormMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The NormMap class implements Mappings which use a Frame to -* normalise the input axis values. - -* Inheritance: -* The NormMap class inherits from the Mapping class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 11-JUL-2005 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "frame.h" /* Coordinate Frames */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* NormMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstNormMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstFrame *frame; /* Encapsulated Frame */ -} AstNormMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstNormMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -} AstNormMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstNormMapGlobals { - AstNormMapVtab Class_Vtab; - int Class_Init; -} AstNormMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitNormMapGlobals_( AstNormMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(NormMap) /* Check class membership */ -astPROTO_ISA(NormMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstNormMap *astNormMap_( void *, const char *, int *, ...); -#else -AstNormMap *astNormMapId_( void *, const char *, ... )__attribute__((format(printf,2,3))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstNormMap *astInitNormMap_( void *, size_t, int, AstNormMapVtab *, - const char *, AstFrame *, int * ); - -/* Vtab initialiser. */ -void astInitNormMapVtab_( AstNormMapVtab *, const char *, int * ); - -/* Loader. */ -AstNormMap *astLoadNormMap_( void *, size_t, AstNormMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckNormMap(this) astINVOKE_CHECK(NormMap,this,0) -#define astVerifyNormMap(this) astINVOKE_CHECK(NormMap,this,1) - -/* Test class membership. */ -#define astIsANormMap(this) astINVOKE_ISA(NormMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astNormMap astINVOKE(F,astNormMap_) -#else -#define astNormMap astINVOKE(F,astNormMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitNormMap(mem,size,init,vtab,name,frame) \ -astINVOKE(O,astInitNormMap_(mem,size,init,vtab,name,frame,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitNormMapVtab(vtab,name) astINVOKE(V,astInitNormMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadNormMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadNormMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckNormMap to validate NormMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#endif -#endif - - - - - diff --git a/ast/nullregion.c b/ast/nullregion.c deleted file mode 100644 index 6ef9cfa..0000000 --- a/ast/nullregion.c +++ /dev/null @@ -1,2093 +0,0 @@ -/* -*class++ -* Name: -* NullRegion - -* Purpose: -* A boundless region within a Frame. - -* Constructor Function: -c astNullRegion -f AST_NULLREGION - -* Description: -* The NullRegion class implements a Region with no bounds within a Frame. -* If the Negated attribute of a NullRegion is false, the NullRegion -* represents a Region containing no points. If the Negated attribute of -* a NullRegion is true, the NullRegion represents an infinite Region -* (that is, all points in the coordinate system are inside the NullRegion). - -* Inheritance: -* The NullRegion class inherits from the Region class. - -* Attributes: -* The NullRegion class does not define any new attributes beyond -* those which are applicable to all Regions. - -* Functions: -c The NullRegion class does not define any new functions beyond those -f The NullRegion class does not define any new routines beyond those -* which are applicable to all Regions. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 11-OCT-2004 (DSB): -* Original version. -* 20-JAN-2009 (DSB): -* Over-ride astRegBasePick. -* 26-JAN-2009 (DSB): -* Over-ride astMapMerge. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS NullRegion - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "region.h" /* Coordinate regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "nullregion.h" /* Interface definition for this class */ -#include "mapping.h" /* Position mappings */ -#include "circle.h" /* Circle regions */ -#include "prism.h" /* Extruded Regions */ -#include "unitmap.h" /* Unit Mapping */ -#include "cmpframe.h" /* Compound Frames */ -#include "cmpmap.h" /* Compound Mappings */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstMapping *(* parent_simplify)( AstMapping *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(NullRegion) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(NullRegion,Class_Init) -#define class_vtab astGLOBAL(NullRegion,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstNullRegionVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstNullRegion *astNullRegionId_( void *, void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *RegMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *RegBasePick( AstRegion *this, int, const int *, int * ); -static AstRegion *GetDefUnc( AstRegion *, int * ); -static AstRegion *MergeNullRegion( AstNullRegion *, AstRegion *, int, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int Overlap( AstRegion *, AstRegion *, int * ); -static int OverlapX( AstRegion *, AstRegion *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void RegBaseBox( AstRegion *this, double *, double *, int * ); -static void GetRegionBounds( AstRegion *this, double *, double *, int * ); - -/* Member functions. */ -/* ================= */ -static AstRegion *GetDefUnc( AstRegion *this, int *status ) { -/* -*+ -* Name: -* astGetDefUnc - -* Purpose: -* Obtain a pointer to the default uncertainty Region for a given Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "nullregion.h" -* AstRegion *astGetDefUnc( AstRegion *this ) - -* Class Membership: -* NullRegion member function (over-rides the astGetDefUnc protected -* method inherited from the Region class). - -* Description: -* This function returns a pointer to a Region which represents the -* default uncertainty associated with a position on the boundary of the -* given Region. The returned Region refers to the base Frame within the -* FrameSet encapsulated by the supplied Region. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* A pointer to the Region. This should be annulled (using astAnnul) -* when no longer needed. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstRegion *result; - double *cen; - double rad; - int i; - int n; - -/* Initialise */ - result = NULL; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Create a Circle centred on the origin with zero radius. */ - n = astGetNaxes( this ); - cen = astMalloc( sizeof(double)*(size_t) n ); - if( cen ) { - for( i = 0; i < n; i++ ) cen[ i ] = 0.0; - rad = 0.0; - result = (AstRegion *) astCircle( this, 1, cen, &rad, NULL, "", status ); - cen = astFree( cen ); - } - -/* Return the default uncertainty Region. */ - return result; -} - -void astInitNullRegionVtab_( AstNullRegionVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitNullRegionVtab - -* Purpose: -* Initialise a virtual function table for a NullRegion. - -* Type: -* Protected function. - -* Synopsis: -* #include "nullregion.h" -* void astInitNullRegionVtab( AstNullRegionVtab *vtab, const char *name ) - -* Class Membership: -* NullRegion vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the NullRegion class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsANullRegion) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - mapping->MapMerge = MapMerge; - - region->GetDefUnc = GetDefUnc; - region->Overlap = Overlap; - region->OverlapX = OverlapX; - region->RegBaseBox = RegBaseBox; - region->RegBaseMesh = RegBaseMesh; - region->GetRegionBounds = GetRegionBounds; - region->RegMesh = RegMesh; - region->RegBasePick = RegBasePick; - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDump( vtab, Dump, "NullRegion", "Boundless region" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a NullRegion. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* NullRegion method (over-rides the protected astMapMerge method -* inherited from the Region class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated NullRegion in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated NullRegion with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated NullRegion which is to be merged with -* its neighbours. This should be a cloned copy of the NullRegion -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* NullRegion it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated NullRegion resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstNullRegion *oldint; /* Pointer to supplied NullRegion */ - AstMapping *map; /* Pointer to adjacent Mapping */ - AstMapping *new; /* Simplified or merged Region */ - int i1; /* Index of first Mapping merged */ - int i; /* Loop counter */ - int result; /* Result value to return */ - -/* Initialise. */ - result = -1; - i1 = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the NullRegion. */ - oldint = (AstNullRegion *) this; - -/* First of all, see if the NullRegion can be replaced by a simpler Region, - without reference to the neighbouring Regions in the list. */ -/* =====================================================================*/ - -/* Try to simplify the NullRegion. If the pointer value has changed, we assume - some simplification took place. */ - new = astSimplify( oldint ); - if( new != (AstMapping *) oldint ) { - -/* Annul the NullRegion pointer in the list and replace it with the new Region - pointer, and indicate that the forward transformation of the returned - Region should be used (not really needed but keeps things clean). */ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = new; - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - -/* If the NullRegion itself could not be simplified, see if it can be merged - with the Regions on either side of it in the list. We can only merge - in parallel. */ -/* =====================================================================*/ - } else if( ! series ){ - new = astAnnul( new ); - -/* Attempt to merge the NullRegion with its lower neighbour (if any). */ - if( where > 0 ) { - i1 = where - 1; - map = ( *map_list )[ where - 1 ]; - if( astIsARegion( map ) ) { - new = (AstMapping *) MergeNullRegion( oldint, (AstRegion *) map, - 0, status ); - } - } - -/* If this did not produced a merged Region, attempt to merge the NullRegion - with its upper neighbour (if any). */ - if( !new && where < *nmap - 1 ) { - i1 = where; - map = ( *map_list )[ where + 1 ]; - if( astIsARegion( map ) ) { - new = (AstMapping *) MergeNullRegion( oldint, (AstRegion *) map, - 1, status ); - } - } - -/* If succesfull... */ - if( new ){ - -/* Annul the first of the two Mappings, and replace it with the merged - Region. Also clear the invert flag. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - ( *map_list )[ i1 ] = new; - ( *invert_list )[ i1 ] = 0; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ i1 + 1 ] ); - for ( i = i1 + 2; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = i1; - } - - } else { - new = astAnnul( new ); - } - -/* Return the result. */ - return result; -} - -static AstRegion *MergeNullRegion( AstNullRegion *this, AstRegion *reg, - int intfirst, int *status ) { -/* -* Name: -* MergeNullRegion - -* Purpose: -* Attempt to merge a NullRegion with another Region to form a Region of -* higher dimensionality. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* AstRegion *MergeNullRegion( AstNullRegion *this, AstRegion *reg, -* int intfirst, int *status ) - -* Class Membership: -* NullRegion member function. - -* Description: -* This function attempts to combine the supplied Regions together -* into a Region of higher dimensionality. - -* Parameters: -* this -* Pointer to a NullRegion. -* reg -* Pointer to another Region. -* intfirst -* If non-zero, then the NullRegion axes are put first in the new Region. -* Otherwise, the other Region's axes are put first. -* status -* Pointer to the inherited status value. - -* Returned Value: -* A pointer to a new region, or NULL if the supplied Regions could -* not be merged. -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* Pointer to base Frame for "result" */ - AstFrame *cfrm; /* Pointer to current Frame for "result" */ - AstFrame *frm_reg; /* Pointer to Frame from "reg" */ - AstFrame *frm_this; /* Pointer to Frame from "this" */ - AstMapping *bcmap; /* Base->current Mapping for "result" */ - AstMapping *map_reg; /* Base->current Mapping from "reg" */ - AstMapping *map_this; /* Base->current Mapping from "this" */ - AstMapping *sbunc; /* Simplified uncertainty */ - AstRegion *bunc; /* Base Frame uncertainty Region */ - AstRegion *new; /* Pointer to new NullRegion in base Frame */ - AstRegion *result; /* Pointer to returned NullRegion in current Frame */ - AstRegion *unc_reg; /* Current Frame uncertainty Region from "reg" */ - AstRegion *unc_this; /* Current Frame uncertainty Region from "this" */ - double fac_reg; /* Ratio of used to default MeshSize for "reg" */ - double fac_this; /* Ratio of used to default MeshSize for "this" */ - int msz_reg; /* Original MeshSize for "reg" */ - int msz_reg_set; /* Was MeshSize originally set for "reg"? */ - int msz_this; /* Original MeshSize for "this" */ - int msz_this_set; /* Was MeshSize originally set for "this"? */ - int nax; /* Number of axes in "result" */ - int nax_reg; /* Number of axes in "reg" */ - int nax_this; /* Number of axes in "this" */ - int neg_reg; /* Negated attribute value for other supplied Region */ - int neg_this; /* Negated attribute value for supplied NullRegion */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get the Closed attributes of the two Regions. They must be the same in - each Region if we are to merge the Regions. In addition, in order to - merge, either both Regions must have a defined uncertainty, or neither - Region must have a defined Uncertainty. */ - if( astGetClosed( this ) == astGetClosed( reg ) && - astTestUnc( this ) == astTestUnc( reg ) ) { - -/* Get the Nagated attributes of the two Regions. */ - neg_this = astGetNegated( this ); - neg_reg = astGetNegated( reg ); - -/* Get the number of axes in the two supplied Regions. */ - nax_reg = astGetNaxes( reg ); - nax_this = astGetNaxes( this ); - -/* If the Regions can be combined, get the number of axes the - combination will have. */ - nax = nax_reg + nax_this; - -/* Get the base Frames from the two Region FrameSets, and combine them - into a single CmpFrame that will be used to create any new Region. */ - frm_this = astGetFrame( ((AstRegion *) this)->frameset, AST__BASE ); - frm_reg = astGetFrame( reg->frameset, AST__BASE ); - - if( intfirst ) { - bfrm = (AstFrame *) astCmpFrame( frm_this, frm_reg, "", status ); - } else { - bfrm = (AstFrame *) astCmpFrame( frm_reg, frm_this, "", status ); - } - - frm_this = astAnnul( frm_this ); - frm_reg = astAnnul( frm_reg ); - -/* Indicate we do not yet have a merged Region. */ - new = NULL; - -/* We only check for merging with another NullRegion (other classes such - as Box and Interval check for merging of NullRegions with other classes). - The result will be an NullRegion. Both Regions must have the same value - for the Negated flag. */ - if( astIsANullRegion( reg ) && neg_this == neg_reg ) { - new = (AstRegion *) astNullRegion( bfrm, NULL, "", status ); - -/* Propagate remaining attributes of the supplied Region to it. */ - astRegOverlay( new, this, 1 ); - -/* Ensure the Negated flag is set correctly in the returned NullRegion. */ - if( neg_this ) { - astSetNegated( new, neg_this ); - } else { - astClearNegated( new ); - } - -/* If both the supplied Regions have uncertainty, assign the new Region an - uncertainty. */ - if( astTestUnc( this ) && astTestUnc( reg ) ) { - -/* Get the uncertainties from the two supplied Regions. */ - unc_this = astGetUncFrm( this, AST__BASE ); - unc_reg = astGetUncFrm( reg, AST__BASE ); - -/* Combine them into a single Region (a Prism), in the correct order. */ - if( intfirst ) { - bunc = (AstRegion *) astPrism( unc_this, unc_reg, "", status ); - } else { - bunc = (AstRegion *) astPrism( unc_reg, unc_this, "", status ); - } - -/* Attempt to simplify the Prism. */ - sbunc = astSimplify( bunc ); - -/* Use the simplified Prism as the uncertainty for the returned Region. */ - astSetUnc( new, sbunc ); - -/* Free resources. */ - sbunc = astAnnul( sbunc ); - bunc = astAnnul( bunc ); - unc_reg = astAnnul( unc_reg ); - unc_this = astAnnul( unc_this ); - } - -/* Get the current Frames from the two Region FrameSets, and combine them - into a single CmpFrame. */ - frm_this = astGetFrame( ((AstRegion *) this)->frameset, AST__CURRENT ); - frm_reg = astGetFrame( reg->frameset, AST__CURRENT ); - - if( intfirst ) { - cfrm = (AstFrame *) astCmpFrame( frm_this, frm_reg, "", status ); - } else { - cfrm = (AstFrame *) astCmpFrame( frm_reg, frm_this, "", status ); - } - -/* Get the base -> current Mappings from the two Region FrameSets, and - combine them into a single parallel CmpMap that connects bfrm and cfrm. */ - map_this = astGetMapping( ((AstRegion *) this)->frameset, AST__BASE, - AST__CURRENT ); - map_reg = astGetMapping( reg->frameset, AST__BASE, AST__CURRENT ); - - if( intfirst ) { - bcmap = (AstMapping *) astCmpMap( map_this, map_reg, 0, "", - status ); - } else { - bcmap = (AstMapping *) astCmpMap( map_reg, map_this, 0, "", - status ); - } - -/* Map the new Region into the new current Frame. */ - result = astMapRegion( new, bcmap, cfrm ); - -/* The filling factor in the returned is the product of the filling - factors for the two supplied Regions. */ - if( astTestFillFactor( reg ) || astTestFillFactor( this ) ) { - astSetFillFactor( result, astGetFillFactor( reg )* - astGetFillFactor( this ) ); - } - -/* If the MeshSize value is set in either supplied Region, set a value - for the returned Region which scales the default value by the - product of the scaling factors for the two supplied Regions. First see - if either MeshSize value is set. */ - msz_this_set = astTestMeshSize( this ); - msz_reg_set = astTestMeshSize( reg ); - if( msz_this_set || msz_reg_set ) { - -/* If so, get the two MeshSize values (one of which may be a default - value), and then clear them so that the default value will be returned - in future. */ - msz_this = astGetMeshSize( this ); - msz_reg = astGetMeshSize( reg ); - astClearMeshSize( this ); - astClearMeshSize( reg ); - -/* Get the ratio of the used MeshSize to the default MeshSize for both - Regions. */ - fac_this = (double)msz_this/(double)astGetMeshSize( this ); - fac_reg = (double)msz_reg/(double)astGetMeshSize( reg ); - -/* The MeshSize of the returned Returned is the default value scaled by - the product of the two ratios found above. */ - astSetMeshSize( result, fac_this*fac_reg*astGetMeshSize( result ) ); - -/* Re-instate the original MeshSize values for the supplied Regions (if - set) */ - if( msz_this_set ) astSetMeshSize( this, msz_this ); - if( msz_reg_set ) astSetMeshSize( reg, msz_reg ); - } - -/* Free remaining resources */ - frm_this = astAnnul( frm_this ); - frm_reg = astAnnul( frm_reg ); - map_this = astAnnul( map_this ); - map_reg = astAnnul( map_reg ); - bcmap = astAnnul( bcmap ); - new = astAnnul( new ); - cfrm = astAnnul( cfrm ); - } - } - -/* If an error has occurred, annul the returned pointer. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int Overlap( AstRegion *this, AstRegion *that, int *status ){ -/* -* Name: -* Overlap - -* Purpose: -* Test if two regions overlap each other. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* int Overlap( AstRegion *this, AstRegion *that ) - -* Class Membership: -* NullRegion member function (over-rides the astOverlap method inherited -* from the Region class). - -* Description: -* This function returns an integer value indicating if the two -* supplied Regions overlap. The two Regions are converted to a commnon -* coordinate system before performing the check. If this conversion is -* not possible (for instance because the two Regions represent areas in -* different domains), then the check cannot be performed and a zero value -* is returned to indicate this. - -* Parameters: -* this -* Pointer to the first Region. -* that -* Pointer to the second Region. - -* Returned Value: -* astOverlap() -* A value indicating if there is any overlap between the two Regions. -* Possible values are: -* -* 0 - The check could not be performed because the second Region -* could not be mapped into the coordinate system of the first -* Region. -* -* 1 - There is no overlap between the two Regions. -* -* 2 - The first Region is completely inside the second Region. -* -* 3 - The second Region is completely inside the first Region. -* -* 4 - There is partial overlap between the two Regions. -* -* 5 - The Regions are identical. -* -* 6 - The second Region is the negation of the first Region. - -* Notes: -* - The returned values 5 and 6 do not check the value of the Closed -* attribute in the two Regions. -* - A value of zero will be returned if this function is invoked with the -* AST error status set, or if it should fail for any reason. - -* Implementation Notes: -* - This function is simply a wrap-up for the OverlapX function -* which performs the required processing but swaps the order of the -* two arguments. This is a trick to allow the astOverlap -* method to be over-ridden by derived classes on the basis of the -* class of either of the two arguments. -*/ - -/* Check the inherited status. */ - if ( !astOK ) return 0; - -/* Invoke the private "OverlapX" member function with the two arguments - swapped. */ - return OverlapX( that, this, status ); -} - -static int OverlapX( AstRegion *that, AstRegion *this, int *status ){ -/* -* Name: -* OverlapX - -* Purpose: -* Test if two regions overlap each other. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* int OverlapX( AstRegion *that, AstRegion *this ) - -* Class Membership: -* NullRegion member function (over-rides the astOverlapX method inherited -* from the Region class). - -* Description: -* This function performs the processing for the public astOverlap -* method (as inherited from the Region class and over-ridden by the -* NullRegion class) and has exactly the same interface except that -* the order of the two arguments is swapped. This is a trick -* to allow the astOverlap method to be over-ridden by derived -* classes on the basis of the class of either of its two -* arguments. -* -* See the astOverlap method for details of the interface. - -*/ - -/* Local Variables: */ - AstFrameSet *fs; /* FrameSet connecting Region Frames */ - int result; /* Returned value */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check that the Regions can be compared meaningfully. */ - fs = astConvert( this, that, "" ); - if( fs ) { - fs = astAnnul( fs ); - -/* If both the supplied Regions are NullRegion... */ - if( astIsANullRegion( this ) && astIsANullRegion( that ) ) { - -/* If the Negated attributes are equal, the Regions are identical. - Otherwise they are mutually exclusive. */ - if( astGetNegated( this ) == astGetNegated( that ) ) { - result = 5; - } else { - result = 6; - } - -/* If one of the supplied Region is a NullRegion containing no points, - then there is no overlap. */ - } else if( ( astIsANullRegion( this ) && !astGetNegated( this ) ) || - ( astIsANullRegion( that ) && !astGetNegated( that ) ) ) { - result = 1; - -/* If "that" is infinite and "this" is not infinite, then "this" is - entirely inside "that". */ - } else if( astIsANullRegion( that ) && astGetNegated( that ) ) { - result = 2; - -/* If "this" is infinite and "that" is not infinite, then "that" is - entirely inside "this". */ - } else if( astIsANullRegion( this ) && astGetNegated( this ) ){ - result = 3; - -/* Otherwise there is partial overlap. */ - } else { - result = 4; - } - } - -/* If not OK, return zero. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static void RegBaseBox( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* NullRegion member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstNullRegion *this; /* Pointer to NullRegion structure */ - int i; /* Axis index */ - int nc; /* No. of axes in base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the NullRegion structure */ - this = (AstNullRegion *) this_region; - -/* Get the number of base Frame axes. */ - nc = astGetNin( this_region->frameset ); - -/* Set the upper bound less than the lower bound to indicate that the region - contains no points. */ - for( i = 0; i < nc; i++ ) { - lbnd[ i ] = 1.0; - ubnd[ i ] = -1.0; - } - -} - -static AstPointSet *RegBaseMesh( AstRegion *this, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Return a PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* AstPointSet *astRegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* NullRegion member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. Note, a NullRegion has no boundary. This -* is indicated by returned a PointSet containing a single point with a -* value of AST__BAD on every axis. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a new PointSet containing a single point with value of -* AST__BAD on every axis. - -*- -*/ - -/* Local Variables: */ - AstPointSet *result; - double **ptr; - int i; - int nc; - -/* Initialise */ - result = NULL; - -/* Check the inherited status */ - if( !astOK ) return result; - -/* If the Region structure contains a pointer to a PointSet holding - a previously created mesh, return it. */ - if( this->basemesh ) { - result = astClone( this->basemesh ); - -/* Otherwise, create a new mesh. */ - } else { - -/* Get the number of base Frame axes */ - nc = astGetNin( this->frameset ); - -/* Create the PointSet. */ - result = astPointSet( 1, nc, "", status ); - -/* Get a pointer to the axis values. */ - ptr = astGetPoints( result ); - -/* If OK, store AST__BAD on every axis. */ - if( ptr ) for( i = 0; i < nc; i++ ) ptr[ i ][ 0 ] = AST__BAD; - -/* Same the returned pointer in the Region structure so that it does not - need to be created again next time this function is called. */ - if( astOK && result ) this->basemesh = astClone( result ); - - } - -/* Return the result. */ - return result; -} - -static AstRegion *RegBasePick( AstRegion *this_region, int naxes, - const int *axes, int *status ){ -/* -* Name: -* RegBasePick - -* Purpose: -* Return a Region formed by picking selected base Frame axes from the -* supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* AstRegion *RegBasePick( AstRegion *this, int naxes, const int *axes, -* int *status ) - -* Class Membership: -* NullRegion member function (over-rides the astRegBasePick protected -* method inherited from the Region class). - -* Description: -* This function attempts to return a Region that is spanned by selected -* axes from the base Frame of the encapsulated FrameSet of the supplied -* Region. This may or may not be possible, depending on the class of -* Region. If it is not possible a NULL pointer is returned. - -* Parameters: -* this -* Pointer to the Region. -* naxes -* The number of base Frame axes to select. -* axes -* An array holding the zero-based indices of the base Frame axes -* that are to be selected. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Region, or NULL if no region can be formed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* The base Frame in the supplied Region */ - AstFrame *frm; /* The base Frame in the returned Region */ - AstRegion *bunc; /* The uncertainty in the supplied Region */ - AstRegion *result; /* Returned Region */ - AstRegion *unc; /* The uncertainty in the returned Region */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the base Frame of the encapsulated FrameSet. */ - bfrm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Create a Frame by picking the selected axes from the base Frame of the - encapsulated FrameSet. */ - frm = astPickAxes( bfrm, naxes, axes, NULL ); - -/* Get the uncertainty Region (if any) within the base Frame of the supplied - Region, and select the required axes from it. If the resulting Object - is not a Region, annul it so that the returned Region will have no - uncertainty. */ - if( astTestUnc( this_region ) ) { - bunc = astGetUncFrm( this_region, AST__BASE ); - unc = astPickAxes( bunc, naxes, axes, NULL ); - bunc = astAnnul( bunc ); - - if( ! astIsARegion( unc ) ) unc = astAnnul( unc ); - - } else { - unc = NULL; - } - -/* Create the new NullRegion. */ - result = (AstRegion *) astNullRegion( frm, unc, "", status ); - -/* Free resources */ - frm = astAnnul( frm ); - bfrm = astAnnul( bfrm ); - if( unc ) unc = astAnnul( unc ); - -/* Return a NULL pointer if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void GetRegionBounds( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* GetRegionBounds - -* Purpose: -* Returns the bounding box of an un-negated Region in the current Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* void astGetRegionBounds( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* NullRegion member function (over-rides the astGetRegionBounds protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the current Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the current Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the Region. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the current Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the Region. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstNullRegion *this; /* Pointer to NullRegion structure */ - int i; /* Axis index */ - int nc; /* No. of axes in base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the NullRegion structure */ - this = (AstNullRegion *) this_region; - -/* Get the number of base Frame axes. */ - nc = astGetNin( this_region->frameset ); - -/* Set the upper bound less than the lower bound to indicate that the region - contains no points. */ - for( i = 0; i < nc; i++ ) { - lbnd[ i ] = 1.0; - ubnd[ i ] = -1.0; - } - -} - -static AstPointSet *RegMesh( AstRegion *this, int *status ){ -/* -* Name: -* RegMesh - -* Purpose: -* Return a PointSet containing points spread over the boundary of a -* Region. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* AstPointSet *astRegMesh( AstRegion *this, int *status ) - -* Class Membership: -* NullRegion member function (over-rides the astRegMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the current Frame of -* the encapsulated FrameSet. Note, a NullRegion has no boundary and -* so an error is reported if this function is called. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* NULL pointer. - -* Notes: -* - This implementation reports and error and returns NULL since a -* NullRegion has no boundary. -*- -*/ - - astError( AST__INTER, "astRegMesh(%s): The %s class does not implement " - "the astRegMesh method inherited from the Region class " - "(internal AST programming error).", status, astGetClass( this ), - astGetClass( this ) ); - return NULL; -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mapping represented by a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* NullRegion method (over-rides the astSimplify method inherited -* from the Region class). - -* Description: -* This function invokes the parent Region Simplify method, and then -* performs any further region-specific simplification. -* -* If the Mapping from base to current Frame is not a UnitMap, this -* will include attempting to fit a new Region to the boundary defined -* in the current Frame. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the simplified Region. A cloned pointer to the -* supplied Region will be returned if no simplication could be -* performed. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Current Frame */ - AstMapping *map; /* Base->current Mapping */ - AstMapping *result; /* Result pointer to return */ - AstRegion *new; /* Simplified Region */ - AstRegion *this; /* Pointer to supplied Region structure */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the supplied Region structure. */ - this = (AstRegion *) this_mapping; - -/* Invoke the parent Simplify method inherited from the Region class. This - will simplify the encapsulated FrameSet and uncertainty Region. */ - new = (AstRegion *) (*parent_simplify)( this_mapping, status ); - -/* Is the Mapping from base Frame to current Frame in the Region a - UnitMap? If so, no simplification is possible. */ - map = astGetMapping( new->frameset, AST__BASE, AST__CURRENT ); - if( astIsAUnitMap( map ) ){ - result = astClone( new ); - - } else { - -/* Create a NullRegion from the current Frame. */ - frm = astGetFrame( new->frameset, AST__CURRENT ); - result = (AstMapping *) astNullRegion( frm, astGetUnc( new, 0 ), "", status ); - -/* Free resources. */ - frm = astAnnul( frm ); - - } - map = astAnnul( map ); - new = astAnnul( new ); - -/* If any simplification could be performed, copy Region attributes from - the supplied Region to the returned Region, and return a pointer to it. - If the supplied Region had no uncertainty, ensure the returned Region - has no uncertainty. Otherwise, return a clone of the supplied pointer. */ - if( result != this_mapping ) astRegOverlay( result, this, 1 ); - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a NullRegion to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* NullRegion member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a NullRegion and a set of points encapsulated in a -* PointSet and transforms the points by setting axis values to -* AST__BAD for all points which are outside the region. Points inside -* the region are copied unchanged from input to output. - -* Parameters: -* this -* Pointer to the NullRegion. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - The forward and inverse transformations are identical for a -* Region. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of axes in the Frame represented by the NullRegion. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstNullRegion *this; /* Pointer to NullRegion */ - AstPointSet *result; /* Pointer to output PointSet */ - double **ptr_out; /* Pointer to output coordinate data */ - double *p; /* Pointer to next axis value */ - int coord; /* Zero-based index for coordinates */ - int ncoord_out; /* No. of coordinates per output point */ - int npoint_out; /* No. of points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the NullRegion structure. */ - this = (AstNullRegion *) this_mapping; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, - containing a copy of the input PointSet. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* If the NullRegion has been inverted, it represents an infinite region - which includes all points, so just retain the copy of the supplied - PointSet created by the parent Transform method above. If the NullRegion - has not been inverted, it contains no points and so set all output points - bad. */ - if( !astGetNegated( this ) ) { - ncoord_out = astGetNcoord( result ); - npoint_out = astGetNpoint( result ); - ptr_out = astGetPoints( result ); - if ( astOK ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - p = ptr_out[ coord ]; - for ( point = 0; point < npoint_out; point++ ) { - *(p++) = AST__BAD; - } - } - } - } - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -/* None */ - -/* Destructor. */ -/* ----------- */ -/* None */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for NullRegion objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the NullRegion class to an output Channel. - -* Parameters: -* this -* Pointer to the NullRegion whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstNullRegion *this; /* Pointer to the NullRegion structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the NullRegion structure. */ - this = (AstNullRegion *) this_object; - -/* Write out values representing the instance variables for the - NullRegion class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* There are no values to write, so return without further action. */ -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsANullRegion and astCheckNullRegion functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(NullRegion,Region) -astMAKE_CHECK(NullRegion) - -AstNullRegion *astNullRegion_( void *frame_void, AstRegion *unc, const char *options, int *status, ...) { -/* -*++ -* Name: -c astNullRegion -f AST_NULLREGION - -* Purpose: -* Create a NullRegion. - -* Type: -* Public function. - -* Synopsis: -c #include "nullregion.h" -c AstNullRegion *astNullRegion( AstFrame *frame, AstRegion *unc, const char *options, ... ) -f RESULT = AST_NULLREGION( FRAME, UNC, OPTIONS, STATUS ) - -* Class Membership: -* NullRegion constructor. - -* Description: -* This function creates a new NullRegion and optionally initialises its -* attributes. -* -* A NullRegion is a Region with no bounds. If the Negated attribute of a -* NullRegion is false, the NullRegion represents a Region containing no -* points. If the Negated attribute of a NullRegion is true, the NullRegion -* represents an infinite Region containing all points within the -* coordinate system. - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* A pointer to the Frame in which the region is defined. A deep -* copy is taken of the supplied Frame. This means that any -* subsequent changes made to the Frame using the supplied pointer -* will have no effect the Region. -c unc -f UNC = INTEGER (Given) -* An optional pointer to an existing Region which specifies the -* uncertainties associated with positions in the supplied Frame. -* The uncertainty in any point in the Frame is found by shifting the -* supplied "uncertainty" Region so that it is centred at the point -* being considered. The area covered by the shifted uncertainty -* Region then represents the uncertainty in the position. The -* uncertainty is assumed to be the same for all points. -* -* If supplied, the uncertainty Region must be of a class for which -* all instances are centro-symetric (e.g. Box, Circle, Ellipse, etc.) -* or be a Prism containing centro-symetric component Regions. A deep -* copy of the supplied Region will be taken, so subsequent changes to -* the uncertainty Region using the supplied pointer will have no -* effect on the created NullRegion. Alternatively, -f a null Object pointer (AST__NULL) -c a NULL Object pointer -* may be supplied, in which case a default uncertainty of zero is -* used. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new NullRegion. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new NullRegion. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astNullRegion() -f AST_NULLREGION = INTEGER -* A pointer to the new NullRegion. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstNullRegion *new; /* Pointer to new NullRegion */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the supplied Frame structure. */ - frame = astCheckFrame( frame_void ); - -/* Initialise the NullRegion, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitNullRegion( NULL, sizeof( AstNullRegion ), !class_init, - &class_vtab, "NullRegion", frame, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new NullRegion's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new NullRegion. */ - return new; -} - -AstNullRegion *astNullRegionId_( void *frame_void, void *unc_void, - const char *options, ... ) { -/* -* Name: -* astNullRegionId_ - -* Purpose: -* Create a NullRegion. - -* Type: -* Private function. - -* Synopsis: -* #include "nullregion.h" -* AstNullRegion *astNullRegionId_( AstFrame *frame, AstRegion *unc, const char *options, ... ) - -* Class Membership: -* NullRegion constructor. - -* Description: -* This function implements the external (public) interface to the -* astNullRegion constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astNullRegion_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astNullRegion_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astNullRegion_. - -* Returned Value: -* The ID value associated with the new NullRegion. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstNullRegion *new; /* Pointer to new NullRegion */ - AstRegion *unc; /* Pointer to Region structure */ - va_list args; /* Variable argument list */ - - int *status; /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Frame pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Frame. */ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - -/* Obtain a Region pointer from the supplied "unc" ID and validate the - pointer to ensure it identifies a valid Region . */ - unc = unc_void ? astCheckRegion( astMakePointer( unc_void ) ) : NULL; - -/* Initialise the NullRegion, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitNullRegion( NULL, sizeof( AstNullRegion ), !class_init, - &class_vtab, "NullRegion", frame, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new NullRegion's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new NullRegion. */ - return astMakeId( new ); -} - -AstNullRegion *astInitNullRegion_( void *mem, size_t size, int init, - AstNullRegionVtab *vtab, const char *name, - AstFrame *frame, AstRegion *unc, int *status ) { -/* -*+ -* Name: -* astInitNullRegion - -* Purpose: -* Initialise a NullRegion. - -* Type: -* Protected function. - -* Synopsis: -* #include "nullregion.h" -* AstNullRegion *astInitNullRegion_( void *mem, size_t size, int init, -* AstNullRegionVtab *vtab, const char *name, -* AstFrame *frame, AstRegion *unc ) - -* Class Membership: -* NullRegion initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new NullRegion object. It allocates memory (if necessary) to accommodate -* the NullRegion plus any additional data associated with the derived class. -* It then initialises a NullRegion structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a NullRegion at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the NullRegion is to be initialised. -* This must be of sufficient size to accommodate the NullRegion data -* (sizeof(NullRegion)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the NullRegion (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the NullRegion -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the NullRegion's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new NullRegion. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* A pointer to the Frame in which the region is defined. -* unc -* A pointer to a Region which specifies the uncertainty of positions -* within the supplied Frame. A NULL pointer can be supplied, in which -* case default uncertainties of zero are used. If an uncertainty -* Region is supplied, it must be either a Box, a Circle or an Ellipse, -* and its encapsulated Frame must be related to the Frame supplied -* for parameter "frame" (i.e. astConvert should be able to find a -* Mapping between them). The centre of the supplied uncertainty -* Region is immaterial since it will be re-centred on the point -* being tested before use. A deep copy is taken of the supplied -* Region. - -* Returned Value: -* A pointer to the new NullRegion. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstNullRegion *new; /* Pointer to new NullRegion */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitNullRegionVtab( vtab, name ); - -/* Initialise a Region structure (the parent class) as the first component - within the NullRegion structure, allocating memory if necessary. */ - new = (AstNullRegion *) astInitRegion( mem, size, 0, (AstRegionVtab *) vtab, - name, frame, NULL, unc ); - -/* If an error occurred, clean up by deleting the new NullRegion. */ - if ( !astOK ) new = astDelete( new ); - -/* Return a pointer to the new NullRegion. */ - return new; -} - -AstNullRegion *astLoadNullRegion_( void *mem, size_t size, AstNullRegionVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadNullRegion - -* Purpose: -* Load a NullRegion. - -* Type: -* Protected function. - -* Synopsis: -* #include "nullregion.h" -* AstNullRegion *astLoadNullRegion( void *mem, size_t size, AstNullRegionVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* NullRegion loader. - -* Description: -* This function is provided to load a new NullRegion using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* NullRegion structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a NullRegion at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the NullRegion is to be -* loaded. This must be of sufficient size to accommodate the -* NullRegion data (sizeof(NullRegion)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the NullRegion (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the NullRegion structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstNullRegion) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new NullRegion. If this is NULL, a pointer -* to the (static) virtual function table for the NullRegion class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "NullRegion" is used instead. - -* Returned Value: -* A pointer to the new NullRegion. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstNullRegion *new; /* Pointer to the new NullRegion */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this NullRegion. In this case the - NullRegion belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstNullRegion ); - vtab = &class_vtab; - name = "NullRegion"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitNullRegionVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built NullRegion. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "NullRegion" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* There are no values to read. */ -/* ---------------------------- */ - -/* If an error occurred, clean up by deleting the new NullRegion. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new NullRegion pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - - - - - - diff --git a/ast/nullregion.h b/ast/nullregion.h deleted file mode 100644 index bcfc501..0000000 --- a/ast/nullregion.h +++ /dev/null @@ -1,221 +0,0 @@ -#if !defined( NULLREGION_INCLUDED ) /* Include this file only once */ -#define NULLREGION_INCLUDED -/* -*+ -* Name: -* nullregion.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the NullRegion class. - -* Invocation: -* #include "nullregion.h" - -* Description: -* This include file defines the interface to the NullRegion class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The NullRegion class implement a Region with no boundaries. - -* Inheritance: -* The NullRegion class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 11-OCT-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "region.h" /* Coordinate regions (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* NullRegion structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstNullRegion { - -/* Attributes inherited from the parent class. */ - AstRegion region; /* Parent class structure */ - -} AstNullRegion; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstNullRegionVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -} AstNullRegionVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstNullRegionGlobals { - AstNullRegionVtab Class_Vtab; - int Class_Init; -} AstNullRegionGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitNullRegionGlobals_( AstNullRegionGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(NullRegion) /* Check class membership */ -astPROTO_ISA(NullRegion) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstNullRegion *astNullRegion_( void *, AstRegion *, const char *, int *, ...); -#else -AstNullRegion *astNullRegionId_( void *, AstRegion *, const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstNullRegion *astInitNullRegion_( void *, size_t, int, AstNullRegionVtab *, - const char *, AstFrame *, AstRegion *, int * ); - -/* Vtab initialiser. */ -void astInitNullRegionVtab_( AstNullRegionVtab *, const char *, int * ); - -/* Loader. */ -AstNullRegion *astLoadNullRegion_( void *, size_t, AstNullRegionVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckNullRegion(this) astINVOKE_CHECK(NullRegion,this,0) -#define astVerifyNullRegion(this) astINVOKE_CHECK(NullRegion,this,1) - -/* Test class membership. */ -#define astIsANullRegion(this) astINVOKE_ISA(NullRegion,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astNullRegion astINVOKE(F,astNullRegion_) -#else -#define astNullRegion astINVOKE(F,astNullRegionId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitNullRegion(mem,size,init,vtab,name,frame,unc) \ -astINVOKE(O,astInitNullRegion_(mem,size,init,vtab,name,frame,unc,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitNullRegionVtab(vtab,name) astINVOKE(V,astInitNullRegionVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadNullRegion(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadNullRegion_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckNullRegion to validate NullRegion pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#endif -#endif - - - - - diff --git a/ast/object.c b/ast/object.c deleted file mode 100644 index 2f8d869..0000000 --- a/ast/object.c +++ /dev/null @@ -1,8950 +0,0 @@ -/* -*class++ - -* Name: -* Object - -* Purpose: -* Base class for all AST Objects. - -* Constructor Function: -* None. - -* Description: -* This class is the base class from which all other classes in the -* AST library are derived. It provides all the basic Object -* behaviour and Object manipulation facilities required throughout -* the library. There is no Object constructor, however, as Objects -* on their own are not useful. - -* Inheritance: -* The Object base class does not inherit from any other class. - -* Attributes: -* All Objects have the following attributes: -* -* - Class: Object class name -* - ID: Object identification string -* - Ident: Permanent Object identification string -* - Nobject: Number of Objects in class -* - ObjSize: The in-memory size of the Object in bytes -* - RefCount: Count of active Object pointers -* - UseDefs: Allow use of default values for Object attributes? - -* Functions: -c The following functions may be applied to all Objects: -f The following routines may be applied to all Objects: -* -c - astAnnul: Annul a pointer to an Object -c - astBegin: Begin a new AST context -c - astClear: Clear attribute values for an Object -c - astClone: Clone a pointer to an Object -c - astCopy: Copy an Object -c - astCreatedAt: Returns information about where an object was created -c - astDelete: Delete an Object -c - astEnd: End an AST context -c - astEscapes: Control whether graphical escape sequences are removed -c - astExempt: Exempt an Object pointer from AST context handling -c - astExport: Export an Object pointer to an outer context -c - astGet: Get an attribute value for an Object -c - astHasAttribute: Test if an Object has a named attribute -c - astImport: Import an Object pointer to the current context -c - astIsA: Test class membership -c - astLock: Lock an Object for use by the calling thread -c - astToString: Create an in-memory serialisation of an Object -c - astSame: Do two AST pointers refer to the same Object? -c - astSet: Set attribute values for an Object -c - astSet: Set an attribute value for an Object -c - astShow: Display a textual representation of an Object on standard -c output -c - astTest: Test if an attribute value is set for an Object -c - astTune: Set or get an integer AST tuning parameter -c - astTuneC: Set or get a character AST tuning parameter -c - astUnlock: Unlock an Object for use by other threads -c - astFromString: Re-create an Object from an in-memory serialisation -c - astVersion: Return the verson of the AST library being used. -f - AST_ANNUL: Annul a pointer to an Object -f - AST_BEGIN: Begin a new AST context -f - AST_CLEAR: Clear attribute values for an Object -f - AST_CLONE: Clone a pointer to an Object -f - AST_COPY: Copy an Object -f - AST_DELETE: Delete an Object -f - AST_END: End an AST context -f - AST_ESCAPES: Control whether graphical escape sequences are removed -f - AST_EXEMPT: Exempt an Object pointer from AST context handling -f - AST_EXPORT: Export an Object pointer to an outer context -f - AST_GET: Get an attribute value for an Object -f - AST_HASATTRIBUTE: Test if an Object has a named attribute -f - AST_IMPORT: Import an Object pointer to the current context -f - AST_ISA: Test class membership -f - AST_SAME: Do two AST pointers refer to the same Object? -f - AST_SET: Set attribute values for an Object -f - AST_SET: Set an attribute value for an Object -f - AST_SHOW: Display a textual representation of an Object on standard -f output -f - AST_TEST: Test if an attribute value is set for an Object -f - AST_TUNE: Set or get an integer AST tuning parameter -f - AST_TUNEC: Set or get a character AST tuning parameter -f - AST_VERSION: Return the verson of the AST library being used. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 1-FEB-1996 (RFWS): -* Original version. -* 22-APR-1996 (RFWS): -* Added attribute setting functions. -* 2-JUL-1996 (RFWS): -* Added functions to support the external interface (using -* identfiers). -* 10-SEP-1996 (RFWS): -* Added I/O facilities. -* 30-MAY-1997 (RFWS): -* Add ID attribute. -* 14-JUL-1997 (RFWS): -* Add astExempt function. -* 14-OCT-1997 (RFWS): -* Fixed uninitialised use of "dynamic" in astCopy_. -* 14-NOV-1997 (RFWS): -* Remove the subversive C "strtok" function. -* 20-JAN-1998 (RFWS): -* Make the astClear and astRVSet methods virtual. -* 29-APR-1998 (RFWS): -* Fixed bug in algorithm for encoding Object IDs. -* 15-SEP-1999 (RFWS) -* Made astAnnulId accessible from protected code. -* 12-APR-2000 (DSB): -* Zero all memory allocated for a new Object in InitObject before -* storing any new values in the memory. -* 3-APR-2001 (DSB): -* Added the Ident attribute. -* 28-SEP-2001 (DSB): -* Modified VSet to ensure a non-null string always follows the equal -* sign in the attribute setting passed to SetAttrib. -* 27-NOV-2002 (DSB): -* Modified astShow to use astWrite instead of astDump, so that -* invocations of astShow will be included in the count of the -* number of invocations of astWrite returned by astWriteInvocations. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitObjectVtab -* method. -* 8-FEB-2004 (DSB): -* Added astEscapes. -* 10-FEB-2004 (DSB): -* Added debug conditional code to keep track of memory leaks. -* 22-AUG-2004 (DSB): -* Added astEqual -* 27-JAN-2005 (DSB): -* Correct use of ->ident pointers, and added further DEBUG blocks. -* 11-MAR-2005 (DSB): -* Added attribute UseDefs. -* 14-FEB-2006 (DSB): -* Added attribute ObjSize. -* 23-FEB-2006 (DSB): -* Added MemoryCaching tuning parameter. -* 27-FEB-2006 (DSB): -* Include Objects returned by astCopy in the ObjectCaching system. -* 28-FEB-2006 (DSB): -* Use astOK to protect against errors within astGrow. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 26-MAY-2006 (DSB): -* Correct handling of commas within the attribute value supplied -* to astSetC. -* 30-MAY-2006 (DSB): -* Correct the correction made to handle commas within attribute -* 6-JUN-2007 (DSB): -* Fix harmless compiler warnings. -* 21-JUN-2007 (DSB): -* In astSet, ignore trailing spaces in the attribute name. -* 22-JUN-2007 (DSB): -* - Make astVSet return a pointer to dynamic memory holding the -* expanded setting string. -* - Add astSetVtab, and astCast. -* 27-JUN-2007 (DSB): -* Modify astInitObject so that it ignores the supplied "size" value -* if some memory is supplied. -* 2-JULY-2007 (DSB): -* Fix memory access problem in VSet. -* 20-SEP-2007 (DSB): -* In astDelete, ensure the error status is reset before calling -* astGrow to extend the vtab free list. -* 22-APR-2008 (DSB): -* Added astSame. -* 24-OCT-2008 (DSB): -* Prevent a mutex deadlock that could occur when annulling an -* Object ID. -* 28-JAN-2008 (DSB): -* Allow unlocked objects to be annulled using astAnnul. -* 14-OCT-2009 (DSB): -* Modify astCast to make it a virtual function and add type -* checking. -* 7-APR-2010 (DSB): -* Added method astHasAttribute. -* 24-AUG-2010 (DSB): -* Allow commas to be included in attribute values supplied to -* astSet or astVSet by putting quotes around the attribute value. -* 16-JUN-2011 (DSB): -* Added component "iref" to the Object structure. This is an -* integer identifier for each object that is unique within the -* class of the object. Useful for debugging. -* 22-JUL-2011 (DSB): -* Add methods astSetProxy and astGetProxy. -* 2-SEP-2011 (DSB): -* Add functions astToString and astFromString. -* 13-SEP-2013 (DSB): -* Report an error in astAnnul if the supplied object handle is owned by -* a different thread. Note, the Object itself does not need to be owned -* by the current thread, since it should be possible for a thread to -* relinquish a pointer to an object (i.e. a handle) without actually -* owning the object itself. -* 6-JAN-2014 (DSB): -* Added method astEnvSet. -* 9-APR-2015 (DSB): -* Modify VSet to handle "%s" setting strings (i.e. where the whole -* list of settings is provided as a single variable argument). -* This is needed because supplying the while settings string in -* place of "%s" is considered a security issue by many compilers. -* 4-JUL-2017 (DSB): -* Within astLockId, perform the correct check that the supplied -* object handle is not locked by another thread. -* 17-SEP-2017 (DSB): -* Add function astCreatedAt. This increases the size of a Handle -* structure by 20 bytes. If this turns out to be problematic -* this facility could be controlled using a configure option. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Object - -#define INVALID_CONTEXT -1 /* Context value for handles that have no - associated Object */ -#define UNOWNED_CONTEXT -2 /* Context value for handles for objects - that are not locked by any thread */ - - -/* Include files. */ -/* ============== */ - -/* Configuration information */ -/* ------------------------ */ -#include "version.h" /* Version numbers */ -#if HAVE_CONFIG_H -#include -#endif - -/* Interface definitions. */ -/* ---------------------- */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "channel.h" /* I/O channels */ -#include "keymap.h" /* Hash tables */ -#include "object.h" /* Interface definition for this class */ -#include "plot.h" /* Plot class (for astStripEscapes) */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Type Definitions */ -/* ================ */ -/* Structure used to pass data between astToString/FromString and the - corresponding Channel source and sink functions. */ -typedef struct StringData { - char *ptr; /* Pointer to serialisation text */ - char *buff; /* Pointer to a buffer for a single line of text */ - int len; /* Current length of serialisation text */ -} StringData; - -/* Module Variables. */ -/* ================= */ - -/* The following globals have the same values in all threads and so do - not need to be in thread-specific data. */ -/* ------------------------------------------------------------------ */ - -/* Character-valued tuning parameters. */ -#define MAXLEN_TUNEC 200 -static char hrdel[ MAXLEN_TUNEC ] = "%-%^50+%s70+h%+"; -static char mndel[ MAXLEN_TUNEC ] = "%-%^50+%s70+m%+"; -static char scdel[ MAXLEN_TUNEC ] = "%-%^50+%s70+s%+"; -static char dgdel[ MAXLEN_TUNEC ] = "%-%^53+%s60+o%+"; -static char amdel[ MAXLEN_TUNEC ] = "%-%^20+%s85+'%+"; -static char asdel[ MAXLEN_TUNEC ] = "%-%^20+%s85+\"%+"; -static char exdel[ MAXLEN_TUNEC ] = "10%-%^50+%s70+"; - -/* A pointer full of zeros. */ -static AstObject *zero_ptr; - -/* A flag which indicates what should happen when an AST Object is - deleted. If this flag is non-zero, the memory used by the Object is - not freed, but a pointer to it is placed on the end of a list of free - memory chunk pointers so that the memory can be re-used if necessary - avoiding the need to re-allocate memory with malloc (which is slow). - A separate list of free memory chunks is kept for each class because - each class object will require chunks of a different size. Pointers - to these lists are stored in the virtual function table associated - with each class. All memory on these lists is freed when object - caching is switched off via the astTune function. */ -static int object_caching = 0; - -/* Set up global data access, mutexes, etc, needed for thread safety. */ -#ifdef THREAD_SAFE - -/* Define the initial values for the global data for this module. */ -#define GLOBAL_inits \ - globals->Retain_Esc = 0; \ - globals->Context_Level = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->AstGetC_Init = 0; \ - globals->AstGetC_Istr = 0; \ - globals->Active_Handles = NULL; \ - globals->Class_Init = 0; \ - globals->Nvtab = 0; \ - globals->Known_Vtabs = NULL; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Object) - -/* Define macros for accessing each item of thread specific global data. */ -#define retain_esc astGLOBAL(Object,Retain_Esc) -#define context_level astGLOBAL(Object,Context_Level) -#define active_handles astGLOBAL(Object,Active_Handles) -#define getattrib_buff astGLOBAL(Object,GetAttrib_Buff) -#define astgetc_strings astGLOBAL(Object,AstGetC_Strings) -#define astgetc_istr astGLOBAL(Object,AstGetC_Istr) -#define astgetc_init astGLOBAL(Object,AstGetC_Init) -#define class_init astGLOBAL(Object,Class_Init) -#define class_vtab astGLOBAL(Object,Class_Vtab) -#define nvtab astGLOBAL(Object,Nvtab) -#define known_vtabs astGLOBAL(Object,Known_Vtabs) - -/* mutex1 is used to prevent tuning parameters being accessed by more - than one thread at any one time. */ -static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX1 pthread_mutex_lock( &mutex1 ); -#define UNLOCK_MUTEX1 pthread_mutex_unlock( &mutex1 ); - -/* mutex2 is used to prevent the global lists of object handles being - accessed by more than one thread at any one time. */ -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -/* Each Object contains two mutexes. The primary mutex (mutex1) is used - to guard access to all aspects of the Object except for the "locker" - and "ref_count" items. The secondary mutex (mutex2) is used to guard - access to these two remaining items. We need this secondary mutex - since the "locker" and "ref_count" items need to be accessable within - a thread even if that thread has not locked the Object using astLock. - Define macros for accessing these two mutexes. */ -#define LOCK_PMUTEX(this) (pthread_mutex_lock(&((this)->mutex1))) -#define UNLOCK_PMUTEX(this) (pthread_mutex_unlock(&((this)->mutex1))) -#define LOCK_SMUTEX(this) (pthread_mutex_lock(&((this)->mutex2))) -#define UNLOCK_SMUTEX(this) (pthread_mutex_unlock(&((this)->mutex2))) - - - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Define the class virtual function table and its initialisation flag as - static variables. */ -static int class_init = 0; /* Virtual function table initialised? */ -static AstObjectVtab class_vtab; /* Virtual function table */ - -/* A list of pointers to all the known class virtual function tables. */ -static int nvtab = 0; -static AstObjectVtab **known_vtabs = NULL; - -/* A flag which indicates if AST functions which return text strings - should retain any graphical escape sequences (as interpreted by the - Plot class). */ -static int retain_esc = 0; - -/* Context level (Begin/End/Exempt/Export) */ -static int context_level = 0; - -/* Array of list heads for each context (each list is a list of Handle - structures). */ -static int *active_handles = NULL; - -/* String returned by GetAttrib. */ -static char getattrib_buff[ AST__GETATTRIB_BUFF_LEN + 1 ] = ""; - -/* Pointers to string buffers returned by astGetC. */ -static char *astgetc_strings[ AST__ASTGETC_MAX_STRINGS ]; - -/* Offset of next string in "AstGetC_Strings" */ -static int astgetc_istr = 0; - -/* "AstGetC_Strings" array initialised? */ -static int astgetc_init = 0; - -/* Null macros for mutex locking and unlocking */ -#define LOCK_MUTEX1 -#define UNLOCK_MUTEX1 -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 -#define LOCK_PMUTEX(this) -#define LOCK_SMUTEX(this) -#define UNLOCK_PMUTEX(this) -#define UNLOCK_SMUTEX(this) - -#endif - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstObject *Cast( AstObject *, AstObject *, int * ); -static const char *GetID( AstObject *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetIdent( AstObject *, int * ); -static const char *Get( AstObject *, const char *, int * ); -static const char *FromStringSource( void ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetObjSize( AstObject *, int * ); -static int HasAttribute( AstObject *, const char *, int * ); -static int Same( AstObject *, AstObject *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestID( AstObject *, int * ); -static int TestIdent( AstObject *, int * ); -static unsigned long Magic( const AstObject *, size_t, int * ); -static void CleanAttribs( AstObject *, int * ); -static void Clear( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearIdent( AstObject *, int * ); -static void ClearID( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void EmptyObjectCache( int * ); -static void ToStringSink( const char * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetID( AstObject *, const char *, int * ); -static void SetIdent( AstObject *, const char *, int * ); -static void Show( AstObject *, int * ); -static void VSet( AstObject *, const char *, char **, va_list, int * ); -static void EnvSet( AstObject *, int * ); - -static int GetUseDefs( AstObject *, int * ); -static int TestUseDefs( AstObject *, int * ); -static void ClearUseDefs( AstObject *, int * ); -static void SetUseDefs( AstObject *, int, int * ); - -#if defined(THREAD_SAFE) -static void ChangeThreadVtab( AstObject *, int * ); -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ -AstObject *astAnnul_( AstObject *this, int *status ) { -/* -*++ -* Name: -c astAnnul -f AST_ANNUL - -* Purpose: -* Annul a pointer to an Object. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c AstObject *astAnnul( AstObject *this ) -f CALL AST_ANNUL( THIS, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function annuls a pointer to an Object so that it is no -f This routine annuls a pointer to an Object so that it is no -* longer recognised as a valid pointer by the AST library. Any -* resources associated with the pointer are released and made -* available for re-use. -* -c This function also decrements the Object's RefCount attribute by -f This routine also decrements the Object's RefCount attribute by -* one. If this attribute reaches zero (which happens when the last -* pointer to the Object is annulled), then the Object is deleted. - -* Parameters: -c this -c The Object pointer to be annulled. -f THIS = INTEGER (Given and Returned) -f The Object pointer to be annulled. A null pointer value (AST__NULL) -f is always returned. -f STATUS = INTEGER (Given and Returned) -f The global status. - -c Returned Value: -c astAnnul() -c A null Object pointer (AST__NULL) is always returned. -c -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. - -* Notes: -c - This function will attempt to annul the pointer even if the -c Object is not currently locked by the calling thread (see astLock). -c - This function attempts to execute even if the AST error -c status is set -f - This routine attempts to execute even if STATUS is set to an -f error value -* on entry, although no further error report will be -* made if it subsequently fails under these circumstances. In -* particular, it will fail if the pointer suppled is not valid, -* but this will only be reported if the error status is clear on -* entry. -*-- -*/ - -/* Check the pointer to ensure it identifies a valid Object (this - generates an error if it doesn't). */ - if ( !astIsAObject( this ) ) return NULL; - -/* Get a lock on the object's secondary mutex. This mutex guards access - to the "ref_count" and "locker" components of the AstObject structure. */ - LOCK_SMUTEX(this); - -#ifdef MEM_DEBUG - { int rc; - char buf[100]; - rc = this->ref_count; - sprintf(buf,"annulled (refcnt: %d -> %d)", rc, rc-1 ); - astMemoryUse( this, buf ); - } -#endif - -/* Decrement the Object's reference count. */ - --(this->ref_count); - -/* Unlock the object's secondary mutex. */ - UNLOCK_SMUTEX(this); - -/* Decrement the Object's reference count and delete the Object if - necessary. */ - if ( !this->ref_count ) (void) astDelete( this ); - -/* Always return NULL. */ - return NULL; -} - -static AstObject *Cast( AstObject *this, AstObject *obj, int *status ) { -/* -*+ -* Name: -* astCast - -* Purpose: -* Cast an Object into an instance of a sub-class. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "object.h" -* AstObject *astCast( AstObject *this, AstObject *obj ) - -* Class Membership: -* Object method. - -* Description: -* This function returns a deep copy of an ancestral component of the -* supplied object. The required class of the ancestral component is -* specified by another object. Specifically, if "this" and "new" are -* of the same class, a copy of "this" is returned. If "this" is an -* instance of a subclass of "obj", then a copy of the component -* of "this" that matches the class of "obj" is returned. Otherwise, -* a NULL pointer is returned without error. - -* Parameters: -* this -* Pointer to the Object to be cast. -* obj -* Pointer to an Object that defines the class of the returned Object. -* The returned Object will be of the same class as "obj". - -* Returned Value: -* A pointer to the new Object. NULL if "this" is not a sub-class of -* "obj", or if an error occurs. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstObject *new; - int generation_gap; - -/* Initialise */ - new = NULL; - -/* Check inherited status */ - if( !astOK ) return new; - -/* Check pointer have been supplied. */ - if( this && obj ) { - -/* See how many steps up the class inheritance ladder it is from "this" to - "obj". A positive value is returned if "this" is a sub-class of "obj". - A negative value is returned if "obj" is a sub-class of "this". Zero - is returned if they are of the same class. AST__COUSIN is returned if - they share a common ancestor but are not on the same line of descent. */ - generation_gap = astClassCompare( astVTAB( this ), astVTAB( obj ) ); - -/* If the two objects are of the same class, just return a copy of - "this". */ - if( generation_gap == 0 ) { - new = astCopy( this ); - -/* If "this" is a subclass of "obj", return a deep copy of "this" cast - into the class of "obj". */ - } else if( generation_gap != AST__COUSIN && generation_gap > 0 ) { - new = astCastCopy( this, obj ); - - } - } - -/* Return the new pointer. */ - return new; -} - -AstObject *astCastCopy_( AstObject *this, AstObject *obj, int *status ) { -/* -*+ -* Name: -* astCastCopy - -* Purpose: -* Cast an Object into an instance of a sub-class, without type-checking. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* AstObject *astCastCopy( AstObject *this, AstObject *obj ) - -* Class Membership: -* Object method. - -* Description: -* This function returns a deep copy of an ancestral component of the -* supplied object. The required class of the ancestral component is -* specified by another object. No checks are performed that "this" is -* a sub-class of "obj". -* -* It works by temporarily changing the vtab in "this" to be the same -* as in "obj", and then doing a deep copy, and then re-instating the -* original vtab. - -* Parameters: -* this -* Pointer to the Object to be cast. -* obj -* Pointer to an Object that defines the class of the returned Object. -* The returned Object will be of the same class as "obj". - -* Returned Value: -* A pointer to the new Object. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstObject *new; - AstObjectVtab *this_vtab; - size_t this_size; - -/* Initialise */ - new = NULL; - -/* Check inherited status */ - if( !astOK ) return new; - -/* Check pointer have been supplied. */ - if( this && obj ) { - -/* Save a pointer to the original virtual function tables for "this". */ - this_vtab = astVTAB( this ); - -/* Temporarily change the vtab of "this" to that of "obJ". */ - this->vtab = astVTAB( obj ); - -/* Temporarily change the size of "this" to be the size of "obj". */ - this_size = this->size; - this->size = obj->size; - -/* Now take a copy of the object (now considered to be an instance of the - class specified by "obj"). */ - new = astCopy( this ); - -/* Re-instate the original Object vtab and size. */ - this->vtab = this_vtab; - this->size = this_size; - -/* The sub-clas to which "this" originally belonged may have extended the - range of values allowed for one or more of the attributes inherited from - the "obj" class. This means that the current attribute values stored - in the returned object may be inappropriate for the class of "obj". An - example is the System attribute defined by the Frame class, and extended - by sub-classes of Frame. So we now call astCleanAttribs to ensure that - any inappropriate attribute values are cleared in the returned object. */ - astCleanAttribs( new ); - } - -/* Return the new pointer. */ - return new; -} - -#if defined(THREAD_SAFE) -static void ChangeThreadVtab( AstObject *this, int *status ){ -/* -* Name: -* ChangeThreadVtab - -* Purpose: -* Modify an Object structure so that it refers to a vtab created by -* the currently executing thread. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* void ChangeThreadVtab( AstObject *this, int *status ) - -* Class Membership: -* Object member function. - -* Description: -* Each Object structure contains a pointer to a virtual function -* table (vtab) that identifies information about the class to -* which the Object belongs (function pointers, Object caches, -* etc). In order to avoid use of mutexes (which can slow down AST -* applications enormously), each thread has its own set of vtab -* structures (one for each AST class) stored in thread-specific -* data. Each time an Object is locked by the currently executing -* thread, this function should be called to change the vtab pointer -* in the Object to refer to the vtab relevant to the currently -* executing thread. - -* Parameters: -* this -* Pointer to the Object. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - const char *class; - int i; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to Thread-specific data for the currently executing thread. */ - astGET_GLOBALS(this); - -/* Get the class name for the supplied Object. This uses the existing - vtab pointer in the Object structure to locate the required GetClass - method and the class name. This vtab pointer may be for a vtab created - by a different thread to the one currently executing, but this shouldn't - matter since we are not modifying the vtab contents. */ - class = astGetClass( this ); - -/* Check a class name was obtained */ - if( class ) { - -/* Loop round the vtab structures created by the currently executing thread. */ - for( i = 0; i < nvtab; i++ ) { - -/* If the current vtab is for a class that matches the class of the - supplied Object, then store a pointer to the vtab in the Object - structure, and exit. */ - if( !strcmp( class, known_vtabs[ i ]->class ) ) { - this->vtab = known_vtabs[ i ]; - break; - } - } - } -} -#endif - -AstObject *astCheckLock_( AstObject *this, int *status ) { -/* -*+ -* Name: -* astCheckLock - -* Purpose: -* Check that supplied Object is locked by the calling thread. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* AstObject *astCheckLock( AstObject *this ) - -* Class Membership: -* Object method. - -* Description: -* This function reports an error if the supplied object has not -* previously been locked (using astLock) by the calling thread. - -* Parameters: -* this -* Pointer to the Object. - -* Returned Value: -* A copy of the supplied pointer ("this") is returned. The Object -* reference count is not changed. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. - -*- -*/ - -/* This function does nothing in the non-threads version of libast. */ -#if defined(THREAD_SAFE) - -/* Local Variables; */ - AstObject *fail; - -/* Check the supplied pointer. */ - if( this ) { - -/* First use the private ManageLock function rather than the virtual - astManageLock method to check the top level Object is locked for use - by the current thread. This saves time and allows a more appropriate - error message to be issued. */ - if( ManageLock( this, AST__CHECKLOCK, 0, NULL, status ) ) { - if( astOK ) { - astError( AST__LCKERR, "astCheckLock(%s): The supplied %s cannot " - "be used since it is not locked for use by the current " - "thread (programming error).", status, astGetClass( this ), - astGetClass( this ) ); - } - -/* If the top level Object is locked, now use the virtual astManageLock - method to check any objects contained within the top level Object. */ - } else if( astManageLock( this, AST__CHECKLOCK, 0, &fail ) ) { - if( astOK ) { - astError( AST__LCKERR, "astCheckLock(%s): The supplied %s cannot " - "be used since a %s contained within the %s is not " - "locked for use by the current thread (programming " - "error).", status, astGetClass( this ), - astGetClass( this ), astGetClass( fail ), - astGetClass( this ) ); - } - } - } -#endif - -/* Return the supploed pointer. */ - return this; - -} - -int astClassCompare_( AstObjectVtab *class1, AstObjectVtab *class2, - int *status ) { -/* -*+ -* Name: -* astClassCompare - -* Purpose: -* Determine the relationship between two AST classes. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* int astClassCompare( AstObjectVtab *class1, AstObjectVtab *class2 ) - -* Class Membership: -* Object method. - -* Description: -* This function returns the number of steps up the class inheritance -* ladder from the class specified by "class1" to the class specified -* by "class2". - -* Parameters: -* class1 -* Pointer to a virtual function table describing the first AST class. -* class2 -* Pointer to a virtual function table describing the second AST class. - -* Returned Value: -* The generation gap between "class1" and "class2". The result will be -* positive if "class1" is a subclass of "class2", negative if "class2" -* is a subclass of "class1", zero if they are of the same class (or -* an error occurs), or AST__COUSIN if they are not on the same line -* of descent. - -*- -*/ - -/* Local Variables: */ - AstClassIdentifier *class1_id; - AstClassIdentifier *class2_id; - AstClassIdentifier *id; - int *class1_check; - int *class2_check; - int result; - -/* Initialise */ - result = 0; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Check pointer have been supplied. */ - if( class1 && class2 ) { - -/* Get pointers to the AstClassIdentifier that identifies the top-level - class of each vtab. */ - class1_id = class1->top_id; - class2_id = class2->top_id; - -/* Class membership is specified by the "check" value in each class - identifier. Get the check values for both vtabs. */ - class1_check = class1_id->check; - class2_check = class2_id->check; - -/* Try walking up the class heirarchy of "class1" until the class of - "class2" is reached. The top-level AstObject class has a NULL "parent" - pointer in its class identifier structure. */ - id = class1_id; - while( id && ( id->check != class2_check ) ) { - id = id->parent; - result++; - } - -/* If "class1" is not a subclass of "class2", try walking up the class - heirarchy of "class2" until the class of "class1" is reached. */ - if( !id ) { - result = 0; - id = class2_id; - while( id && ( id->check != class1_check ) ) { - id = id->parent; - result--; - } - -/* If "class2" is not a subclass of "class1", return AST__COUSIN. */ - if( !id ) result = AST__COUSIN; - } - } - -/* Return the generation gap. */ - return result; -} - -static void CleanAttribs( AstObject *this_object, int *status ) { -/* -*+ -* Name: -* astCleanAttribs - -* Purpose: -* Clear any invalid set attribute values. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "object.h" -* void astCleanAttribs( AstObject *this, int *status ) - -* Class Membership: -* Object method. - -* Description: -* This function clears any attributes that are currently set to -* invalid values in the supplied object. This can happen for instance -* when an object is cast into an instance of a parent class using -* astCast, since sub-classes can extend the range of valid values -* an attribute can take. - -* Parameters: -* this -* Pointer to the Object to be cleaned. -*- -*/ - -/* The base Object class has no attributes that need cleaning. */ - -} - -static void Clear( AstObject *this, const char *attrib, int *status ) { -/* -*++ -* Name: -c astClear -f AST_CLEAR - -* Purpose: -* Clear attribute values for an Object. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "object.h" -c void astClear( AstObject *this, const char *attrib ) -f CALL AST_CLEAR( THIS, ATTRIB, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function clears the values of a specified set of attributes -f This routine clears the values of a specified set of attributes -* for an Object. Clearing an attribute cancels any value that has -* previously been explicitly set for it, so that the standard -* default attribute value will subsequently be used instead. This -c also causes the astTest function to return the value zero for -f also causes the AST_TEST function to return the value .FALSE. for -* the attribute, indicating that no value has been set. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Object. -c attrib -f ATTRIB = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing a -c comma-separated list of the names of the attributes to be cleared. -f A character string containing a comma-separated list of the -f names of the attributes to be cleared. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. - -* Notes: -* - Attribute names are not case sensitive and may be surrounded -* by white space. -* - It does no harm to clear an attribute whose value has not been -* set. -* - An error will result if an attempt is made to clear the value -* of a read-only attribute. -*-- -*/ - -/* Local Variables: */ - char *buff; /* Pointer to character buffer */ - char *name; /* Pointer to individual attribute name */ - char *name_end; /* Pointer to null at end of name */ - int i; /* Loop counter for characters */ - int j; /* Non-blank character count */ - int len; /* Length of attrib string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the length of the attrib string. */ - len = (int) strlen( attrib ); - if ( len != 0 ) { - -/* Allocate memory and store a copy of the string. */ - buff = astStore( NULL, attrib, (size_t) ( len + 1 ) ); - if ( astOK ) { - -/* Loop to process each element in the comma-separated list. */ - name = buff; - while ( name ) { - -/* Change the comma at the end of each element to a null to terminate - the name. */ - if ( ( name_end = strchr( name, ',' ) ) ) *name_end = '\0'; - -/* Remove white space and upper case characters from the attribute - name. */ - for ( i = j = 0; name[ i ]; i++ ) { - if ( !isspace( name[ i ] ) ) name[ j++ ] = tolower( name[ i ] ); - } - -/* Terminate the attribute name and pass it to astClearAttrib to clear - the attribute (unless it is all blank, in which case we ignore - it). */ - name[ j ] = '\0'; - if ( j ) astClearAttrib( this, name ); - -/* Check for errors and abort if any clear operation fails. Otherwise, - process the next attribute. */ - if ( !astOK ) break; - name = name_end ? name_end + 1 : NULL; - } - } - -/* Free the memory allocated for the string buffer. */ - buff = astFree( buff ); - } -} - -static void ClearAttrib( AstObject *this, const char *attrib, int *status ) { -/* -*+ -* Name: -* astClearAttrib - -* Purpose: -* Clear an attribute value for an Object. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "object.h" -* void astClearAttrib( AstObject *this, const char *attrib ) - -* Class Membership: -* Object method. - -* Description: -* This function clears the value of a specified attribute for an -* Object, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Object. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. - -* Notes: -* - The Object class does not have any writable attributes, so -* this function merely reports an error. It is intended to be -* extended by other class definitions. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* ID. */ -/* --- */ - if ( !strcmp( attrib, "id" ) ) { - astClearID( this ); - -/* Ident. */ -/* ------ */ - } else if ( !strcmp( attrib, "ident" ) ) { - astClearIdent( this ); - -/* UseDefs. */ -/* -------- */ - } else if ( !strcmp( attrib, "usedefs" ) ) { - astClearUseDefs( this ); - -/* Read-only attributes. */ -/* --------------------- */ -/* Test if the attribute string matches any of the read-only - attributes of this class. If it does, then report an error. */ - } else if ( !strcmp( attrib, "class" ) || - !strcmp( attrib, "nobject" ) || - !strcmp( attrib, "objsize" ) || - !strcmp( attrib, "refcount" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Since no writable attributes are defined for the Object class, any - attempt to clear a value for anything else is also an error. */ - } else { - astError( AST__BADAT, "astClear: The attribute name \"%s\" is invalid " - "for a %s.", status, attrib, astGetClass( this ) ); - } -} - -AstObject *astClone_( AstObject *this, int *status ) { -/* -*++ -* Name: -c astClone -f AST_CLONE - -* Purpose: -* Clone (duplicate) an Object pointer. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c AstObject *astClone( AstObject *this ) -f RESULT = AST_CLONE( THIS, STATUS ) - -* Class Membership: -* Object method. - -* Description: -* This function returns a duplicate pointer to an existing -* Object. It also increments the Object's RefCount attribute to -* keep track of how many pointers have been issued. -* -* Note that this function is NOT equivalent to an assignment -* statement, as in general the two pointers will not have the same -* value. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Original pointer to the Object. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astClone() -f AST_CLONE = INTEGER -* A duplicate pointer to the same Object. - -* Applicability: -* Object -* This function applies to all Objects. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a lock on the object's secondary mutex. This mutex guards access - to the "ref_count" and "locker" components of the AstObject structure. */ - LOCK_SMUTEX(this); - -#ifdef MEM_DEBUG - { int rc; - char buf[100]; - rc = this->ref_count; - sprintf(buf,"cloned (refcnt: %d -> %d)", rc, rc+1 ); - astMemoryUse( this, buf ); - } -#endif - -/* Increment the Object's reference count. */ - this->ref_count++; - -/* Unlock the object's secondary mutex. */ - UNLOCK_SMUTEX(this); - -/* Return a new pointer to the Object. */ - return this; -} - -AstObject *astCopy_( const AstObject *this, int *status ) { -/* -*++ -* Name: -c astCopy -f AST_COPY - -* Purpose: -* Copy an Object. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c AstObject *astCopy( const AstObject *this ) -f RESULT = AST_COPY( THIS, STATUS ) - -* Class Membership: -* Object method. - -* Description: -* This function creates a copy of an Object and returns a pointer -* to the resulting new Object. It makes a "deep" copy, which -* contains no references to any other Object (i.e. if the original -* Object contains references to other Objects, then the actual -* data are copied, not simply the references). This means that -* modifications may safely be made to the copy without indirectly -* affecting any other Object. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Object to be copied. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astCopy() -f AST_COPY = INTEGER -* Pointer to the new Object. - -* Applicability: -* Object -* This function applies to all Objects. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstObject *new; /* Pointer to new object */ - AstObjectVtab *vtab; /* Pointer to object vtab */ - int i; /* Loop counter for copy constructors */ - -/* Initiallise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Re-use cached memory, or allocate new memory using the size of the input - object, to store the output Object. */ - - vtab = this->vtab; - if( object_caching ){ - - if( vtab->nfree > 0 ) { - new = vtab->free_list[ --(vtab->nfree) ]; - vtab->free_list[ vtab->nfree ] = NULL; - } else { - new = astMalloc( this->size ); - } - - } else { - new = astMalloc( this->size ); - } - - if ( astOK ) { - -/* Perform an initial byte-by-byte copy of the entire object - structure. */ - (void) memcpy( (void *) new, (const void *) this, this->size ); - -/* Initialise any components of the new Object structure that need to - differ from the input. */ - new->check = Magic( new, new->size, status ); - new->dynamic = 1; - new->ref_count = 1; - new->id = NULL; /* ID attribute is not copied (but Ident is copied) */ - new->proxy = NULL; - -/* Copy the persistent identifier string. */ - if( this->ident ) { - new->ident = astStore( NULL, this->ident, strlen( this->ident ) + 1 ); - } - -/* Create a new mutex for the new Object, and lock it for use by the - current thread. */ -#ifdef THREAD_SAFE - if( pthread_mutex_init( &(new->mutex1), NULL ) != 0 && astOK ) { - astError( AST__INTER, "astInitObject(%s): Failed to " - "initialise POSIX mutex1 for the new Object.", status, - vtab->class ); - } - if( pthread_mutex_init( &(new->mutex2), NULL ) != 0 && astOK ) { - astError( AST__INTER, "astInitObject(%s): Failed to " - "initialise POSIX mutex2 for the new Object.", status, - vtab->class ); - } - new->locker = -1; - new->globals = NULL; - (void) ManageLock( new, AST__LOCK, 0, NULL, status ); -#endif - -/* Loop to execute any copy constructors declared by derived classes. */ - for ( i = 0; i < vtab->ncopy; i++ ) { - -/* Invoke each copy constructor in turn. */ - (*vtab->copy[ i ])( this, new, status ); - -/* If any copy constructor fails, work backwards through the - corresponding destructor functions, invoking each in turn to undo - the copy operations that have been completed so far. */ - if ( !astOK ) { - for ( ; i >= 0; i-- ) { - (*vtab->delete[ i ])( new, status ); - } - -/* Zero the entire new Object structure (to prevent accidental re-use - of any of its values after deletion). */ - (void) memset( new, 0, new->size ); - -/* Free the Object's memory and ensure that a NULL pointer will be - returned. */ - new = astFree( new ); - -/* Quit trying to copy the Object. */ - break; - } - } - } - -/* If OK, increment the count of active objects. */ - if ( astOK ) vtab->nobject++; - -/* Return a pointer to the new Object. */ - return new; -} - -AstObject *astDelete_( AstObject *this, int *status ) { -/* -*++ -* Name: -c astDelete -f AST_DELETE - -* Purpose: -* Delete an Object. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c AstObject *astDelete( AstObject *this ) -f CALL AST_DELETE( THIS, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function deletes an Object, freeing all resources -f This routine deletes an Object, freeing all resources -* associated with it and rendering any remaining pointers to the -* Object invalid. -* -* Note that deletion is unconditional, regardless of whether other -* pointers to the Object are still in use (possibly within other -* Objects). A safer approach is to defer deletion, until all -c references to an Object have expired, by using astBegin/astEnd -c (together with astClone and astAnnul if necessary). -f references to an Object have expired, by using AST_BEGIN/AST_END -f (together with AST_CLONE and AST_ANNUL if necessary). - -* Parameters: -c this -c Pointer to the Object to be deleted. -f THIS = INTEGER (Given and Returned) -f Pointer to the Object to be deleted. A null pointer value -f (AST__NULL) is always returned. -f STATUS = INTEGER (Given and Returned) -f The global status. - -c Returned Value: -c astDelete() -c A null Object pointer (AST__NULL) is always returned. -c -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. - -* Notes: -c - This function attempts to execute even if the AST error status -c is set -f - This routine attempts to execute even if STATUS is set to an error -f value -* on entry, although no further error report will be -* made if it subsequently fails under these circumstances. -*-- -*/ - -/* Local Variables: */ - AstObjectVtab *vtab; /* Pointer to virtual function table */ - int dynamic; /* Was memory allocated dynamically? */ - int i; /* Loop counter for destructors */ - int ifree; /* Index of next slot on free list */ - int status_value; /* AST error status value */ - size_t size; /* Object size */ - -/* Check the pointer to ensure it identifies a valid Object (this - generates an error if it doesn't). */ - if ( !astIsAObject( this ) ) return NULL; - -/* Loop through all the destructors associated with the Object by derived - classes (working up the class hierarchy). */ - for ( i = this->vtab->ndelete - 1; i >= 0; i-- ) { - -/* Invoke each destructor in turn. Attempt to continue even if destructors - fail. */ - ( *this->vtab->delete[ i ] )( this, status ); - } - -/* Free the ID strings. */ - this->id = astFree( this->id ); - this->ident = astFree( this->ident ); - -/* Attempt to unlock the Object and destroy its mutexes. */ -#if defined(THREAD_SAFE) - (void) ManageLock( this, AST__UNLOCK, 0, NULL, status ); - pthread_mutex_destroy( &(this->mutex1) ); - pthread_mutex_destroy( &(this->mutex2) ); -#endif - -/* Save the virtual function table address and note if the Object's - memory was allocated dynamically. Also note its size. */ - vtab = this->vtab; - dynamic = this->dynamic; - size = this->size; - -/* Zero the entire Object structure (to prevent accidental re-use of - any of its values after deletion). */ - (void) memset( this, 0, size ); - -/* If necessary, free the Object's memory. If object caching is switched - on, the memory is not in fact freed; it is merely placed onto the end - of the list of free memory blocks included in the virtual function table - of the AST class concerned. astGrow returns immediately if an error - has already occurred, so we need to reset the error status explicitly - before calling astGrow. */ - if ( dynamic ) { - if( object_caching ) { - ifree = (vtab->nfree)++; - - status_value = astStatus; - astClearStatus; - vtab->free_list = astGrow( vtab->free_list, vtab->nfree, - sizeof(AstObject *) ); - astSetStatus( status_value ); - - if( vtab->free_list ) vtab->free_list[ ifree ] = this; - } else { - (void) astFree( this ); - } - } - -/* Decrement the count of active Objects. */ - vtab->nobject--; - -/* Always return NULL. */ - return NULL; -} - -static void Dump( AstObject *this, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astDump - -* Purpose: -* Write an Object to a Channel. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* void astDump( AstObject *this, AstChannel *channel ) - -* Class Membership: -* Object method. - -* Description: -* This function writes an Object to a Channel, appending it to any -* previous Objects written to that Channel. - -* Parameters: -* this -* Pointer to the Object to be written. -* channel -* Pointer to the output Channel. -*- -*/ - -/* Local Variables: */ - AstObjectVtab *vtab; /* Pointer to virtual function table */ - const char *sval; /* Pointer to string value */ - int helpful; /* Helpful to show value even if not set? */ - int idump; /* Loop counter for dump functions */ - int ival; /* Attribute value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Write an initial "Begin" item, giving the class name of the Object - being written. Also supply a pointer to the comment associated with - the most recently-declared dump function in the Object's virtual - function table. This should describe the class to which the Object - belongs (assuming it has correctly declared its dump function). */ - astWriteBegin( channel, astGetClass( this ), - this->vtab->dump_comment[ this->vtab->ndump - 1 ] ); - -/* Write out instance variable information for the base Object - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* ID. */ -/* --- */ - set = TestID( this, status ); - sval = set ? GetID( this, status ) : astGetID( this ); - -/* Don't show an un-set ID value if it is blank. */ - helpful = ( sval && *sval ); - astWriteString( channel, "ID", set, helpful, sval, - "Object identification string" ); - -/* Ident. */ -/* --- */ - set = TestIdent( this, status ); - sval = set ? GetIdent( this, status ) : astGetIdent( this ); - -/* Don't show an un-set Ident value if it is blank. */ - helpful = ( sval && *sval ); - astWriteString( channel, "Ident", set, helpful, sval, - "Permanent Object identification string" ); - -/* UseDefs */ -/* ------- */ - set = TestUseDefs( this, status ); - ival = set ? GetUseDefs( this, status ) : astGetUseDefs( this ); - astWriteInt( channel, "UseDfs", set, 0, ival, - ival ? "Default attribute values can be used" : - "Default values cannot be used" ); - -/* RefCnt. */ -/* ------- */ - LOCK_SMUTEX(this); - ival = this->ref_count; - UNLOCK_SMUTEX(this); - - astWriteInt( channel, "RefCnt", 0, 0, ival, - "Count of active Object pointers" ); - - -/* Nobj. */ -/* ----- */ - vtab = this->vtab; - astWriteInt( channel, "Nobj", 0, 0, vtab->nobject, - "Count of active Objects in same class" ); - -/* Terminate the information above with an "IsA" item for the base - Object class. */ - astWriteIsA( channel, "Object", "AST Object" ); - -/* Now loop to perform the same operation for each additional class - from which the Object inherits (the Object class itself does not - declare a dump function). Invoke the dump function for each class - in turn, working down the class hierarchy, to write out instance - variable information for that class. */ - for ( idump = 0; idump < this->vtab->ndump; idump++ ) { - ( *this->vtab->dump[ idump ] )( this, channel, status ); - -/* Terminate the output from all except the final dump function with - an appropriate "IsA" item describing the class whose data have just - been written. */ - if ( idump != ( this->vtab->ndump - 1 ) ) { - astWriteIsA( channel, this->vtab->dump_class[ idump ], - this->vtab->dump_comment[ idump ] ); - } - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - -/* Terminate the output from the final dump function with an "End" - item to match the initial "Begin" item. */ - astWriteEnd( channel, astGetClass( this ) ); -} - -static void EmptyObjectCache( int *status ){ -/* -* Name: -* EmptyObjectCache - -* Purpose: -* Free all memory blocks currently on the free list of any class. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* EmptyObjectCache( int *status ) - -* Class Membership: -* Object member function. - -* Description: -* This function empties the cache of Object memory by freeing all -* memory blocks on the free_list of all classes. - -* Parameters: -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function attempts to execute even if an error has occurred. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int iblock; /* Index of next entry in free list */ - int itab; /* Index of next virtual function table */ - AstObjectVtab *vtab; /* Pointer to next virtual function table */ - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Loop round all the virtual function tables which are known about. */ - for( itab = 0; itab < nvtab; itab++ ) { - vtab = known_vtabs[ itab ]; - -/* Free all memory blocks stored on the free list for this class. */ - for( iblock = 0; iblock < vtab->nfree; iblock++ ) { - (vtab->free_list)[ iblock ] = astFree( (vtab->free_list)[ iblock ] ); - } - -/* Free the memory used to hold the free list, and indicate it has zero - length. */ - vtab->free_list = astFree( vtab->free_list ); - vtab->nfree = 0; - } -} - -static void EnvSet( AstObject *this, int *status ) { -/* -*+ -* Name: -* astEnvSet - -* Purpose: -* Set default values for an Object's attributes. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "object.h" -* void astEnvSet( AstObject *this ) - -* Class Membership: -* Object method. - -* Description: -* This function assigns a set of attribute values for an Object, -* the attributes and their values being specified by means of an -* environment variable of the form "_OPTIONS" that has -* a value of the form: -* -* "attribute1 = value1, attribute2 = value2, ... " -* -* Here, "attribute" specifies an attribute name and the value to -* the right of each "=" sign should be a suitable textual -* representation of the value to be assigned to that -* attribute. This will be interpreted according to the attribute's -* data type. - -* Parameters: -* this -* Pointer to the Object. - -* Notes: -* - See astVSet for details of how the setting strings are -* interpreted. -*- -*/ - -/* Local Variables: */ - char varname[ 100 ]; - const char *attrs = NULL; - const char *class = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the string holding default attribute values for the class of the - supplied object. This string is held in the class virtual function - table. */ - attrs = this->vtab->defaults; - -/* If this is the first time the defaults have been requested, get the - list of defaults from the environment variable "_OPTIONS" - and store in the virtual function table. */ - if( !attrs ) { - -/* Get the class name. */ - class = astGetClass( this ); - -/* Form the upper-case name of the environment variable. */ - if( class ) { - sprintf( varname, "%s_OPTIONS", class ); - astChrCase( NULL, varname, 1, sizeof( varname ) ); - -/* Get the value of the environment variable. */ - attrs = getenv( varname ); - -/* If no defaults were specified store the string "None". */ - if( ! attrs ) attrs = "None"; - -/* Store a copy in the virtual function table. */ - astBeginPM; - this->vtab->defaults = astStore( NULL, attrs, strlen( attrs ) + 1 ); - astEndPM; - } - } - -/* If any defaults were specified, set the corresponding attributes. */ - if( attrs && strcmp( attrs, "None" ) ) astSet( this, attrs, status ); - -} - -static int Equal( AstObject *this, AstObject *that, int *status ){ -/* -*+ -* Name: -* astEqual - -* Purpose: -* Check equality of two AST Objects. - -* Type: -* Public (but undocumented) function. - -* Synopsis: -* #include "object.h" -* int astEqual( AstObject *this, AstObject *this ) - -* Class Membership: -* Object virtual function. - -* Description: -* This function returns non-zero if the two pointers identify -* equivalent objects. - -* Parameters: -* this -* Pointer to the first Object. -* that -* Pointer to the second Object. - -* Returned Value: -* Non-zero if the objects are equivalent. - -* Notes: -* - This function is available in the public interface even though it is -* documented as protected. This is because it is difficult to document -* precisely which aspects of two Objects must be equal in order for this -* function to return a non-zero value. Each class of Object supplies -* its own Equal method that tests which-ever attributes the class -* considers to be significiant. -* - The implementation of this function provided by the base Object -* class simply compares the class names and the structure size. -* Sub-classes should override this method to provide more appropriate tests. -* - Zero is returned if an error has already occurred, or if -* this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - int result; - -/* Check inherited status */ - if( !astOK ) return 0; - -/* Objects are equivalent if they are the same object. */ - if( this == that ) { - result = 1; - -/* Otherwise, check the structure size and class names */ - } else { - result = ( this->size == that->size && - !strcmp( astGetClass( this ), astGetClass( that ) ) ); - } - - return result; -} - -static const char *Get( AstObject *this, const char *attrib, int *status ) { -/* -* Name: -* Get - -* Purpose: -* Get the value of a specified attribute for an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* const char *Get( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Object member function. - -* Description: -* This function returns a pointer to the value of a specified -* attribute for an Object, formatted as a character string. It is -* mainly a wrap-up used internally for invoking the astGetAttrib -* method. It converts the attribute name to lower case and removes -* white space before invoking the method. This saves derived -* classes that over-ride the astGetAttrib method from having to do -* this themselves. - -* Parameters: -* this -* Pointer to the Object. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This may contain mixed -* case and white space, but should not be composed entirely of -* white space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Object, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Object. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - char *buff; /* Pointer to local string buffer */ - const char *result; /* Pointer value to return */ - int i; /* Loop counter for characters */ - int j; /* Non-blank character count */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Allocate a local buffer long enough to hold the attribute name - string. */ - buff = astMalloc( strlen( attrib ) + (size_t) 1 ); - if ( astOK ) { - -/* Copy the attribute name characters into the buffer, omitting all - white space and converting to lower case. */ - for ( i = j = 0; attrib[ i ]; i++ ) { - if ( !isspace( attrib[ i ] ) ) buff[ j++ ] = tolower( attrib[ i ] ); - } - -/* Terminate the copied string. */ - buff[ j ] = '\0'; - -/* If no characters were copied, the attribute name was blank, so - report an error. */ - if ( !j ) { - if( astOK ) astError( AST__BADAT, "astGet(%s): A blank attribute " - "name was given.", status, astGetClass( this ) ); - -/* Of OK, invoke astGetAttrib to obtain a pointer to the attribute - value formatted as a character string. */ - } else { - result = astGetAttrib( this, buff ); - -/* If required, strip out graphical escape sequences. */ - if( !astEscapes( -1 ) ) result = astStripEscapes( result ); - } - } - -/* Free the local string buffer. */ - buff = astFree( buff ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static const char *GetAttrib( AstObject *this, const char *attrib, int *status ) { -/* -*+ -* Name: -* astGetAttrib - -* Purpose: -* Get the value of a specified attribute for an Object. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "object.h" -* const char *astGetAttrib( AstObject *this, const char *attrib ) - -* Class Membership: -* Object method. - -* Description: -* This function returns a pointer to the value of a specified -* attribute for an Object, formatted as a character string. - -* Parameters: -* this -* Pointer to the Object. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Object, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Object. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - const char *result; /* Pointer value to return */ - int nobject; /* Nobject attribute value */ - int objsize; /* ObjSize attribute value */ - int ref_count; /* RefCount attribute value */ - int usedefs; /* UseDefs attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(this); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an - appropriate format. Set "result" to point at the result string. */ - -/* Class. */ -/* ------ */ - if ( !strcmp( attrib, "class" ) ) { - result = astGetClass( this ); - -/* ID. */ -/* --- */ - } else if ( !strcmp( attrib, "id" ) ) { - result = astGetID( this ); - -/* Ident. */ -/* ------ */ - } else if ( !strcmp( attrib, "ident" ) ) { - result = astGetIdent( this ); - -/* UseDefs */ -/* ------- */ - } else if ( !strcmp( attrib, "usedefs" ) ) { - usedefs = astGetUseDefs( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", usedefs ); - result = getattrib_buff; - } - -/* Nobject. */ -/* -------- */ - } else if ( !strcmp( attrib, "nobject" ) ) { - nobject = astGetNobject( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", nobject ); - result = getattrib_buff; - } - -/* ObjSize */ -/* ------- */ - } else if ( !strcmp( attrib, "objsize" ) ) { - objsize = astGetObjSize( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", objsize ); - result = getattrib_buff; - } - -/* RefCount. */ -/* --------- */ - } else if ( !strcmp( attrib, "refcount" ) ) { - ref_count = astGetRefCount( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ref_count ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, then report an error. */ - } else if( astOK ){ - astError( AST__BADAT, "astGet: The %s given does not have an attribute " - "called \"%s\".", status, astGetClass( this ), attrib ); - } - -/* Return the result. */ - return result; -} - -const char *astGetClass_( const AstObject *this, int *status ) { -/* -*+ -* Name: -* astGetClass - -* Purpose: -* Obtain the value of the Class attribute for an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* const char *astGetClass( const AstObject *this ) - -* Class Membership: -* Object method. - -* Description: -* This function returns a pointer to the Class string for an -* Object. This contains the name of the class which created the -* Object. - -* Parameters: -* this -* Pointer to the Object. - -* Returned Value: -* Pointer to a string containing the class name. - -* Notes: -* - This function does not check the global error status before -* executing. This is to allow it to be used to obtain class names -* for inclusion in error messages. -* - A pointer to an explanatory string will be returned if this -* function is given a pointer which does not identify an Object. -*- -*/ - -/* Local Variables: */ - const char *name; /* Pointer to returned string */ - -/* First check if the Object pointer supplied is NULL, and set the - returned pointer accordingly. */ - if ( !this ) { - name = ""; - -/* Also check if the supposed Object has the correct "magic number" in - its check field. If not, it is not an Object. */ - } else if ( this->check != Magic( this, this->size, status ) ) { - name = ""; - -/* If OK, obtain a pointer to the class name from the Object's virtual - function table. */ - } else { - name = this->vtab->class; - } - -/* Return the result. */ - return name; -} - -int astGetNobject_( const AstObject *this, int *status ) { -/* -*+ -* Name: -* astGetNobject - -* Purpose: -* Obtain the value of the Nobject attribute for an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* int astGetNobject( const AstObject *this ) - -* Class Membership: -* Object method. - -* Description: -* This function returns the value of the Nobject attribute for an -* Object. This is a count of the number of active Objects in the -* same class as the Object supplied. This count does not include -* Objects in derived classes. - -* Parameters: -* this -* Pointer to the Object. - -* Returned Value: -* The number of active Objects. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the active object count. */ - return this->vtab->nobject; -} - -static int GetObjSize( AstObject *this, int *status ) { -/* -*+ -* Name: -* astGetObjSize - -* Purpose: -* Determine the in-memory size of the Object. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "object.h" -* int astGetObjSize( AstObject *this ) - -* Class Membership: -* Object method. - -* Description: -* This function returns the in-memory size of an Object. - -* Parameters: -* this -* Pointer to the Object. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the object size. */ - return this->size; -} - -void *astGetProxy_( AstObject *this, int *status ) { -/* -*+ -* Name: -* astGetProxy - -* Purpose: -* Get a pointer to the foreign language proxy used to represent a -* given AST Object. - -* Type: -* Undocumented public function. - -* Synopsis: -* #include "object.h" -* void *astGetProxy( AstObject *this ) - -* Class Membership: -* Object method. - -* Description: -* This function returns any pointer stored previously in the AST -* Object using astSetProxy. If no such pointer has been stored, a -* NULL pointer is returned. - -* Parameters: -* this -* Pointer to the Object. - -* Returned Value: -* Pointer to the proxy object, or NULL. - -* Notes: -* - This function is public, but is currently undocumented since it -* is only of interest to people writing AST interfaces for other -* languages. -* - This function attempts to execute even if the AST error status -* is set on entry, although no further error report will be made -* if it subsequently fails under these circumstances. -*- -*/ - return this ? this->proxy : NULL; -} - -int astGetRefCount_( AstObject *this, int *status ) { -/* -*+ -* Name: -* astGetRefCount - -* Purpose: -* Obtain the value of the RefCount attribute for an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* int astGetRefCount( const AstObject *this ) - -* Class Membership: -* Object method. - -* Description: -* This function returns the value of the read-only RefCount -* attribute for an Object. This is a "reference count" of the -* number of active pointers to it, as accounted for by astClone -* and astAnnul (plus the pointer issued when it was created). If -* the reference count for an Object falls to zero when astAnnul is -* invoked, the object will be deleted. - -* Parameters: -* this -* Pointer to the Object. - -* Returned Value: -* The reference count. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables; */ - int result; /* Returned value */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get a lock on the object's secondary mutex. This mutex guards access - to the "ref_count" and "locker" components of the AstObject structure. */ - LOCK_SMUTEX(this); - -/* Get the reference count. */ - result = this->ref_count; - -/* Unlock the object's secondary mutex. */ - UNLOCK_SMUTEX(this); - -/* Return the result. */ - return result; -} - -/* -*++ -* Name: -c astGet -f AST_GET - -* Purpose: -* Get an attribute value for an Object. - -* Type: -* Public functions. - -* Synopsis: -c #include "object.h" -c type astGet( AstObject *this, const char *attrib ) -f RESULT = AST_GET( THIS, ATTRIB, STATUS ) - -* Class Membership: -* Object methods. - -* Description: -* This is a family of functions which return a specified attribute -* value for an Object using one of several different data -* types. The type is selected by replacing in the function name -c by C, D, F, I or L, to obtain a result in const char* (i.e. string), -c double, float, int, or long format, respectively. -f by C, D, I, L or R, to obtain a result in Character, Double -f precision, Integer, Logical or Real format, respectively. -* -* If possible, the attribute value is converted to the type you -* request. If conversion is not possible, an error will result. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Object. -c attrib -f ATTRIB = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing the name of -c the attribute whose value is required. -f A character string containing the name of the attribute whose -f value is required. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGet() -f AST_GET = type -c The attribute value, in the data type corresponding to (or, -c in the case of astGetC, a pointer to a constant null-terminated -c character string containing this value). -f The attribute value, in the data type corresponding to . - -* Applicability: -* Object -* These functions apply to all Objects. - -* Examples: -c printf( "RefCount = %d\n", astGetI( z, "RefCount" ) ); -c Prints the RefCount attribute value for Object "z" as an int. -c title = astGetC( axis, "Title" ); -c Obtains a pointer to a null-terminated character string containing -c the Title attribute of Object "axis". -f WRITE( *, '('' RefCount = '', A10 )' ) AST_GETC( Z, 'RefCount', STATUS ) -f Prints the RefCount attribute value for Object Z as a character -f string. -f NAXES = AST_GETI( FRAME, 'Naxes', STATUS ) -f Obtains the value of the Naxes attribute for Object FRAME as an -f integer. - -* Notes: -* - Attribute names are not case sensitive and may be surrounded -* by white space. -* - An appropriate "null" value will be returned if this function -c is invoked with the AST error status set, or if it should -f is invoked with STATUS set to an error value, or if it should -* fail for any reason. This null value is zero for numeric -c values and NULL for pointer values. -f values, .FALSE. for logical values, and blank for character values. -f - Numerical attribute values of zero translate to logical value -f .FALSE. and all other numerical values translate to .TRUE.. -c - The pointer returned by astGetC is guaranteed to remain valid -c and the string to which it points will not be over-written for a -c total of 50 successive invocations of this function. After this, -c the memory containing the string may be re-used, so a copy of -c the string should be made if it is needed for longer than this. -*-- -*/ - -/* Define a macro that expands to implement the astGetX_ member - functions required. The arguments to this macro are: - - code - The character that appears at the end of the function name. - type - The C type of the function return value. - format - A quoted string containing a astSscanf format specifier that - will read the attribute value into a variable of the required - data type. This format should transfer 1 astSscanf value. -*/ -#define MAKE_GETX(code,type,format) \ -type astGet##code##_( AstObject *this, const char *attrib, int *status ) { \ -\ -/* Local Variables: */ \ - const char *str; /* Pointer to string attribute value */ \ - int nc; /* Number of characters read from string */ \ - int nval; /* Number of values read from string */ \ - type result; /* Value to return */ \ - type value; /* Converted value */ \ -\ -/* Initialise. */ \ - result = (type) 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Obtain the attribute value as a string. */ \ - str = Get( this, attrib, status ); \ - if ( astOK ) { \ -\ -/* Read the value from the string, ignoring surrounding white \ - space. */ \ - nc = 0; \ - nval = astSscanf( str, " " format " %n", &value, &nc ); \ -\ -/* Check that the number of values read was 1 and that all the \ - string's characters were consumed. If so, use the result. */ \ - if ( ( nval == 1 ) && ( nc >= (int) strlen( str ) ) ) { \ - result = value; \ -\ -/* If the read was unsuccessful, report an error. */ \ - } else if( astOK ) { \ - astError( AST__ATGER, "astGet" #code "(%s): The attribute " \ - "value \"%s=%s\" cannot be read using the requested data " \ - "type.", status,astGetClass( this ), attrib, str ); \ - } \ - } \ -\ -/* Return the result. */ \ - return result; \ -} - -/* Use this macro to create all the GetX_ private member functions, - except SetC (which is handled separately). */ -MAKE_GETX(D,double,"%lf") -MAKE_GETX(F,float,"%f") -MAKE_GETX(I,int,"%d") -MAKE_GETX(L,long,"%ld") - -/* Handle GetC separately because memory must be allocated to hold the - returned character values. */ -const char *astGetC_( AstObject *this, const char *attrib, int *status ) { - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - const char *result; /* Pointer value to return */ - const char *value; /* Pointer to attribute value */ - int i; /* Loop count */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(this); - -/* If the "strings" array has not been initialised, fill it with - NULL pointers. */ - if ( !astgetc_init ) { - astgetc_init = 1; - for ( i = 0; i < AST__ASTGETC_MAX_STRINGS; i++ ) astgetc_strings[ i ] = NULL; - } - -/* Obtain a pointer to the required attribute value, formatted as a - character string. */ - value = Get( this, attrib, status ); - -/* Use a null string if a NULL pointer was returned by Get. */ - if( !value ) value = ""; - -/* If OK, store a copy of the resulting string in dynamically - allocated memory, putting a pointer to the copy into the next - element of the "astgetc_strings" array. (This process also de-allocates - any previously allocated memory pointed at by this "strings" - element, so the earlier string is effectively replaced by the new - one.) */ - if ( astOK ) { - - astBeginPM; - astgetc_strings[ astgetc_istr ] = astStore( astgetc_strings[ astgetc_istr ], - value, strlen( value ) + (size_t) 1 ); - astEndPM; - -/* If OK, return a pointer to the copy and increment "astgetc_istr" to use the - next element of "astgetc_strings" on the next invocation. Recycle - "astgetc_istr" to zero when all elements have been used. */ - if ( astOK ) { - result = astgetc_strings[ astgetc_istr++ ]; - if ( astgetc_istr == ( AST__ASTGETC_MAX_STRINGS - 1 ) ) astgetc_istr = 0; - } - } - -/* Return the result. */ - return result; - -} - -static int HasAttribute( AstObject *this, const char *attrib, int *status ) { -/* -*++ -* Name: -c astHasAttribute -f AST_HASATTRIBUTE - -* Purpose: -* Test if an Object has a named attribute. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c int astHasAttribute( AstObject *this, const char *attrib ) -f RESULT = AST_HASATTRIBUTE( THIS, ATTRIB, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function returns a boolean result (0 or 1) to indicate -f This function returns a logical result to indicate -* whether the supplied Object has an attribute with the supplied name. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the first Object. -c attrib -f ATTRIB = INTEGER (Given) -c Pointer to a string holding the -f The -* name of the attribute to be tested. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astHasAttribute() -c One if the Object has the named attribute, otherwise zero. -f AST_SAME = LOGICAL -f .TRUE. if the Object has the named attribute, otherwise -f .FALSE. - -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. - -* Notes: -c - A value of zero will be returned if this function is invoked -c with the AST error status set, or if it should fail for any reason. -f - A value of .FALSE. will be returned if this function is invoked -f with STATUS set to an error value, or if it should fail for any reason. -*-- -*/ - -/* Local Variables: */ - int oldrep; /* Original AST error reporting flag */ - int result; /* Returned value */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Temporarily switch off error reporting. */ - oldrep = astReporting( 0 ); - -/* Attempt to get a value for the specified attribute. */ - (void) Get( this, attrib, status ); - -/* An error will have been reported if the object does not have the - requested attribute. Set the result and clear the error status. */ - if( !astOK ) { - result = 0; - astClearStatus; - } else { - result = 1; - } - -/* Re-instate the original error reporting flag. */ - (void) astReporting( oldrep ); - -/* Return the result. */ - return result; -} - -static unsigned long Magic( const AstObject *this, size_t size, int *status ) { -/* -* Name: -* Magic - -* Purpose: -* Generate a "magic number" for an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* unsigned long Magic( const AstObject *this, size_t size, int *status ) - -* Class Membership: -* Object member function. - -* Description: -* This function generates a "magic number" which is a function of an Object -* pointer (address) and an Object size. This number may be stored in an -* Object to allow it to be recognised as a valid Object by other routines -* and to provide security against argument passing errors, etc. - -* Parameters: -* this -* Pointer to an Object. -* size -* The Object size. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The magic number. - -* Notes: -* - This function does not perform any error checking. -*/ - -/* Form the bit-wise exclusive OR between the Object address and the Object - size, then add 2 and invert the bits. Return the result as an unsigned - long integer. */ - return ~( ( ( (unsigned long) this ) ^ ( (unsigned long) size ) ) + - ( (unsigned long) 2 ) ); -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this, int mode, int extra, - AstObject **fail, int *status ) { -/* -*+ -* Name: -* astManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* int astManageLock( AstObject *this, int mode, int extra, -* AstObject **fail ) - -* Class Membership: -* Object method. - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread. -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. - -* Returned Value: -* A status value: -* 0 - Success. -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. -* 5 - Check failed - object is locked by a different thread -* 6 - Check failed - object is unlocked -* - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. - -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - if( fail ) *fail = NULL; - -/* Check the supplied point is not NULL. */ - if( ! this ) return result; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Get a lock on the object's secondary mutex. This gives us exclusive - access to the "locker" (and "ref_count") component in the AstObject - structure. All other components in the structure are guarded by the - primary mutex (this->mutex1). */ - if( LOCK_SMUTEX(this) ) { - result = 2; - -/* If the secondary mutex was locked succesfully, first deal with cases - where the caller wants to lock the Object for exclusive use by the - calling thread. */ - } else if( mode == AST__LOCK ) { - -/* If the Object is not currently locked, lock the Object primary mutex - and record the identity of the calling thread in the Object. */ - if( this->locker == -1 ) { - if( LOCK_PMUTEX(this) ) result = 2; - this->locker = AST__THREAD_ID; - this->globals = AST__GLOBALS; - ChangeThreadVtab( this, status ); - -/* If the Object is already locked by the calling thread, do nothing. */ - } else if( this->locker == AST__THREAD_ID ) { - -/* If the object is locked by a different thread, and the caller is - willing to wait, attempt to lock the Object primary mutex. This will - cause the calling thread to block until the Object is release by the - thread that currently has it locked. Then store the identity of the - calling thread (the new lock owner). We first need to release the - secondary mutex so that the other thread can modify the "locker" - component in the AstObject structure when it releases the Object - (using this function). We then re-lock the secondary mutex so this - thread can change the "locker" component safely. */ - } else if( extra ) { - if( UNLOCK_SMUTEX(this) ) { - result = 3; - } else if( LOCK_PMUTEX(this) ) { - result = 2; - } else if( LOCK_SMUTEX(this) ) { - result = 2; - } - this->locker = AST__THREAD_ID; - this->globals = AST__GLOBALS; - ChangeThreadVtab( this, status ); - -/* If the caller does not want to wait until the Object is available, - return a status of 1. */ - } else { - result = 1; - } - -/* Unlock the Object for use by other threads. */ - } else if( mode == AST__UNLOCK ) { - -/* Do nothing if the Object is currently unlocked. */ - if( this->locker == -1 ) { - -/* If the object is currently locked by the calling thread, clear the - identity of the thread that owns the lock and unlock the primary - mutex. */ - } else if( this->locker == AST__THREAD_ID ) { - this->locker = -1; - this->globals = NULL; - if( UNLOCK_PMUTEX(this) ) result = 3; - -/* Return an error status value if the Object is locked by another - thread. */ - } else { - result = 1; - } - -/* Check the Object is locked by the calling thread. Return a status of 1 if - not. */ - } else if( mode == AST__CHECKLOCK ) { - if( this->locker == -1 ) { - result = 6; - } else if( this->locker != AST__THREAD_ID ) { - result = 5; - } - -/* Return a status of 4 for any other modes. */ - } else { - result = 4; - } - -/* Unlock the secondary mutex so that other threads can access the "locker" - component in the Object to see if it is locked. */ - if( UNLOCK_SMUTEX(this) ) result = 3; - -/* If the operation failed, return a pointer to the failed object. */ - if( result && fail ) *fail = this; - -/* Return the status value */ - return result; -} -#endif - -char *astToString_( AstObject *this, int *status ) { -/* -c++ -* Name: -* astToString - -* Purpose: -* Create an in-memory serialisation of an Object - -* Type: -* Public function. - -* Synopsis: -* #include "object.h" -* char *astToString( AstObject *this ) - -* Class Membership: -* Object method. - -* Description: -* This function returns a string holding a minimal textual -* serialisation of the supplied AST Object. The Object can re -* re-created from the serialisation using astFromString. - -* Parameters: -* this -* Pointer to the Object to be serialised. - -* Returned Value: -* astToString() -* Pointer to dynamically allocated memory holding the -* serialisation, or NULL if an error occurs. The pointer -* should be freed when no longer needed using astFree. - -c-- -*/ - -/* Local Variables: */ - StringData data; /* Data passed to the sink function */ - AstChannel *channel; /* Pointer to output Channel */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Create a Channel which will write to an expanding dynamically - allocated memory buffer. Set Channel attributes to exclude all - non-essential characters. */ - channel = astChannel( NULL, ToStringSink, "Comment=0,Full=-1,Indent=0", - status ); - -/* Initialise the data structure used to communicate with the sink - function, and store a pointer to it in the Channel. */ - data.ptr = NULL; - data.buff = NULL; - data.len = 0; - astPutChannelData( channel, &data ); - -/* Write the Object to the Channel. */ - astWrite( channel, this ); - -/* Annul the Channel pointer. */ - channel = astAnnul( channel ); - -/* Free the returned string if an error has occurred. */ - if( !astOK ) data.ptr = astFree( data.ptr ); - -/* Return the pointer. */ - return data.ptr; -} - -static void ToStringSink( const char *text ){ -/* -* Name: -* ToStringSink - -* Purpose: -* A Channel sink function for use by the astToString method. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* ToStringSink( const char *text ) - -* Class Membership: -* Object member function. - -* Description: -* This function appends the supplied line of text to the end of a -* dynamically growing memory block. - -* Parameters: -* text -* Pointer to the null-terminated line of text to be stored. - -*/ - -/* Local Variables: */ - StringData *data; /* Data passed to the sink function */ - int *status; /* Pointer to local status value */ - int status_value; /* Local status value */ - -/* Set up the local status */ - status_value = 0; - status = &status_value; - -/* Get a pointer to the structure holding the current memory pointer and - the length of the currently allocated memory. */ - data = astChannelData; - -/* Append the supplied text to the end of the string, and update the - string length. */ - data->ptr = astAppendString( data->ptr, &(data->len), text ); - -/* Append a newline character to the end of the string, and update the - string length. */ - data->ptr = astAppendString( data->ptr, &(data->len), "\n" ); -} - -void astSet_( void *this_void, const char *settings, int *status, ... ) { -/* -*++ -* Name: -c astSet -f AST_SET - -* Purpose: -* Set attribute values for an Object. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c void astSet( AstObject *this, const char *settings, ... ) -f CALL AST_SET( THIS, SETTINGS, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function assigns a set of attribute values to an Object, -f This routine assigns a set of attribute values to an Object, -* over-riding any previous values. The attributes and their new -* values are specified via a character string, which should -* contain a comma-separated list of the form: -* -* "attribute_1 = value_1, attribute_2 = value_2, ... " -* -* where "attribute_n" specifies an attribute name, and the value -* to the right of each "=" sign should be a suitable textual -* representation of the value to be assigned. This value will be -* interpreted according to the attribute's data type. -c -c The string supplied may also contain "printf"-style format -c specifiers, identified by "%" signs in the usual way. If -c present, these will be substituted by values supplied as -c additional optional arguments (using the normal "printf" rules) -c before the string is used. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Object. -c settings -f SETTINGS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing a -c comma-separated list of attribute settings in the form described -c above. -f A character string containing a comma-separated list of -f attribute settings in the form described above. -c ... -c Optional additional arguments which supply values to be -c substituted for any "printf"-style format specifiers that -c appear in the "settings" string. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. - -* Examples: -c astSet( map, "Report = 1, Zoom = 25.0" ); -c Sets the Report attribute for Object "map" to the value 1 and -c the Zoom attribute to 25.0. -c astSet( frame, "Label( %d ) =Offset along axis %d", axis, axis ); -c Sets the Label(axis) attribute for Object "frame" to a -c suitable string, where the axis number is obtained from -c "axis", a variable of type int. -c astSet( frame, "Title =%s", mystring ); -c Sets the Title attribute for Object "frame" to the contents of -c the string "mystring". -f CALL AST_SET( MAP, 'Report = 1, Zoom = 25.0', STATUS ) -f Sets the Report attribute for Object MAP to the value 1 and -f the Zoom attribute to 25.0. -f CALL AST_SET( FRAME, 'Label( 1 ) =Offset from cluster axis', STATUS ) -f Sets the Label(1) attribute for Object FRAME to a suitable -f string. - -* Notes: -* - Attribute names are not case sensitive and may be surrounded -* by white space. -* - White space may also surround attribute values, where it will -* generally be ignored (except for string-valued attributes where -* it is significant and forms part of the value to be assigned). -* - To include a literal comma in the value assigned to an attribute, -* the whole attribute value should be enclosed in quotation markes. -c Alternatively, you can use "%s" format and supply the value as a -c separate additional argument to astSet (or use the astSetC -c function instead). -c - The same procedure may be adopted if "%" signs are to be included -c and are not to be interpreted as format specifiers (alternatively, -c the "printf" convention of writing "%%" may be used). -* - An error will result if an attempt is made to set a value for -* a read-only attribute. -*-- - -* Implementation Notes: -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* Object identifier is of type (void *) and is converted and -* validated within the function itself. -* - This implementation of astSet is designed to be used within AST, -* and has an explicit status parameter. From outside AST, the astSet -* macro will invoke the astSetId_ function which does not have an -* status parameter. - -*-- -*/ - -/* Local Variables: */ - AstObject *this; /* Pointer to the Object structure */ - va_list args; /* Variable argument list */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain and validate a pointer to the Object structure. */ - this = astCheckObject( this_void ); - if ( astOK ) { - -/* Obtain the variable argument list and pass all arguments to the - astVSet method for interpretation. */ - va_start( args, status ); - astVSet( this, settings, NULL, args ); - va_end( args ); - } -} - -static void SetAttrib( AstObject *this, const char *setting, int *status ) { -/* -*+ -* Name: -* astSetAttrib - -* Purpose: -* Set an attribute value for an Object. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "object.h" -* void astSetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* Object method. - -* Description: -* This function assigns an attribute value for an Object, the attribute and -* its value being specified by means of a string of the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in lower -* case with no white space present. The value to the right of the "=" -* should be a suitable textual representation of the value to be assigned -* and this will be interpreted according to the attribute's data type. -* White space surrounding the value is only significant for string -* attributes. - -* Parameters: -* this -* Pointer to the Object. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. - -* Notes: -* - The Object class does not have any writable attributes, so -* this function merely reports an error. It is intended to be -* extended by other class definitions. -*- -*/ - -/* Local Variables: */ - int id; /* Offset of ID string */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* ID. */ -/* --- */ - if ( nc = 0, ( 0 == astSscanf( setting, "id=%n%*[^\n]%n", &id, &nc ) ) - && ( nc >= len ) ) { - astSetID( this, setting + id ); - -/* Ident. */ -/* ------ */ - } else if ( nc = 0, ( 0 == astSscanf( setting, "ident=%n%*[^\n]%n", &id, &nc ) ) - && ( nc >= len ) ) { - astSetIdent( this, setting + id ); - -/* UseDefs */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "usedefs= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetUseDefs( this, ival ); - -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class and use this to report an error - if it does. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - - } else if ( MATCH( "class" ) || - MATCH( "nobject" ) || - MATCH( "objsize" ) || - MATCH( "refcount" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Since no writable attributes are defined for the Object class, any - attempt to set a value for anything else is also an error. */ - } else { - astError( AST__BADAT, "astSet: The attribute setting \"%s\" is invalid " - "for a %s.", status, setting, astGetClass( this ) ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -void astSetCopy_( AstObjectVtab *vtab, - void (* copy)( const AstObject *, AstObject *, int * ), int *status ) { -/* -*+ -* Name: -* astSetCopy - -* Purpose: -* Declare a copy constructor for an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* void astSetCopy( AstObjectVtab *vtab, -* void (* copy)( const AstObject *, AstObject * ) ) - -* Class Membership: -* Object method. - -* Description: -* This function is provided so that class definitions can declare a copy -* constructor to be associated with an Object that is being constructed. -* When a copy is later performed on the Object, the copy constructor of -* each class to which the Object belongs will be invoked in turn (working -* down the class hierarchy). The copy constructor is passed pointers to the -* source and destination Objects. It should implement the copy and return -* void. - -* Parameters: -* vtab -* Pointer to the Object's virtual function table, in which the copy -* constructor's pointer is to be stored for future use. -* copy -* Pointer to the copy constructor function. - -* Notes: -* - When an Object is copied, a byte-by-byte copy of its structure is -* automatically made before any copy constructors are invoked. A copy -* constructor need only be provided if this does not suffice (e.g. if the -* structure contains pointers to other data). -* - If a copy constructor is declared for a class, then a -* destructor for that class must also be declared (using -* astSetDelete) so that there is a one-to-one correspondence -* between copy constructors and their associated destructors. -* - Copy constructors should check the global error status in the normal -* way and should set it (and report an error) if they fail. -*- -*/ - - -/* Check the global status. */ - if ( !astOK ) return; - -/* Indicate that subsequent memory allocations may never be freed (other - than by any AST exit handler). */ - astBeginPM; - -/* Expand the array of copy constructor pointers in the virtual function table - (if necessary) to accommodate the new one. */ - vtab->copy = astGrow( vtab->copy, vtab->ncopy + 1, - sizeof( void (*)( const AstObject *, AstObject * ) ) ); - -/* If OK, store the new function pointer and increment the count of copy - constructors. */ - if ( astOK ) { - vtab->copy[ vtab->ncopy++ ] = copy; - } - -/* Mark the end of the section in which memory allocations may never be freed - (other than by any AST exit handler). */ - astEndPM; - -} - -void astSetDelete_( AstObjectVtab *vtab, void (* delete)( AstObject *, int * ), int *status ) { -/* -*+ -* Name: -* astSetDelete - -* Purpose: -* Declare a destructor for an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* void astSetDelete( AstObjectVtab *vtab, void (* delete)( AstObject * ) ) - -* Class Membership: -* Object method. - -* Description: -* This function is provided so that class definitions can declare a -* destructor to be associated with an Object. When the Object is later -* deleted, the destructor declared by each class to which the Object -* belongs will be invoked in turn (working up the class hierarchy). The -* destructor is passed a pointer to the Object. It should free any -* resources (e.g. memory) associated with it and return void. It should -* not free the memory containing the Object itself. - -* Parameters: -* vtab -* Pointer to the Object's virtual function table, in which the -* destructor's pointer is to be stored for future use. -* delete -* Pointer to the destructor function. - -* Notes: -* - A destructor need not be declared for a class if there are no -* resources to free. -* - If a destructor is declared for a class, then a copy -* constructor for that class must also be declared (using -* astSetCopy) so that there is a one-to-one correspondence between -* copy constructors and their associated destructors. -* - A destructor function should generally attempt to execute even -* if the global error status is set on entry, but should not -* report further errors in that case (errors should be reported -* normally if status is not set on entry). -*- -*/ - - -/* Check the global status. */ - if ( !astOK ) return; - -/* Indicate that subsequent memory allocations may never be freed (other - than by any AST exit handler). */ - astBeginPM; - -/* Expand the array of destructor pointers in the virtual function table (if - necessary) to accommodate the new one. */ - vtab->delete = astGrow( vtab->delete, vtab->ndelete + 1, - sizeof( void (*)( AstObject * ) ) ); - -/* If OK, store the new function pointer and increment the count of - destructors. */ - if ( astOK ) { - vtab->delete[ vtab->ndelete++ ] = delete; - } - -/* Mark the end of the section in which memory allocations may never be freed - (other than by any AST exit handler). */ - astEndPM; - -} - -void astSetDump_( AstObjectVtab *vtab, - void (* dump)( AstObject *, AstChannel *, int * ), - const char *class, const char *comment, int *status ) { -/* -*+ -* Name: -* astSetDump - -* Purpose: -* Declare a dump function for an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* void astSetDump( AstObjectVtab *vtab, -* void (* dump)( AstObject *, AstChannel * ), -* const char *class, const char *comment ) - -* Class Membership: -* Object method. - -* Description: -* This function is provided so that class definitions can declare -* a dump function to be associated with an Object that is being -* constructed. When the astWrite (or astShow or astToString) method -* is later used to write the Object to a Channel, the dump function -* of each class to which the Object belongs will be invoked in turn -* (working down the class hierarchy). The dump function is passed -* pointers to the Object and the output Channel. It should write -* out any internal values (e.g. instance variables) for its class -* that are to be kept (using the protected astWrite... methods of -* the Channel) and return void. - -* Parameters: -* vtab -* Pointer to the Object's virtual function table, in which the -* dump function's pointer is to be stored for future use. -* dump -* Pointer to the dump function. -* class -* Pointer to a constant null-terminated string (residing in -* static memory) containing the name of the class that is -* declaring the dump function. -* comment -* Pointer to a constant null-terminated string (residing in -* static memory) containing a comment to associate with the -* dump function. This should normally describe the purpose of -* the class that is declaring the dump function. - -* Notes: -* - Dump functions should check the global error status in the -* normal way and should set it (and report an error) if they fail. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Indicate that subsequent memory allocations may never be freed (other - than by any AST exit handler). */ - astBeginPM; - -/* Expand the arrays of pointers to dump functions and related data in - the virtual function table (if necessary) to accommodate the new - one. */ - vtab->dump = astGrow( vtab->dump, vtab->ndump + 1, - sizeof( void (*)( AstObject *, AstChannel * ) ) ); - vtab->dump_class = astGrow( vtab->dump_class, vtab->ndump + 1, - sizeof( char * ) ); - vtab->dump_comment = astGrow( vtab->dump_comment, vtab->ndump + 1, - sizeof( char * ) ); - -/* If OK, store the new pointers (to the dump function, class name and - comment) and increment the count of dump functions. */ - if ( astOK ) { - vtab->dump[ vtab->ndump ] = dump; - vtab->dump_class[ vtab->ndump ] = class; - vtab->dump_comment[ vtab->ndump ] = comment; - vtab->ndump++; - } - -/* Mark the end of the section in which memory allocations may never be - freed (other than by any AST exit handler). */ - astEndPM; -} - -void astSetProxy_( AstObject *this, void *proxy, int *status ) { -/* -*+ -* Name: -* astSetProxy - -* Purpose: -* Store a pointer to the foreign language proxy used to represent a -* given AST Object. - -* Type: -* Undocumented public function. - -* Synopsis: -* #include "object.h" -* void astSetProxy( AstObject *this, void *proxy ) - -* Class Membership: -* Object method. - -* Description: -* This function stores the supplied pointer in the AST Object so that -* it can be retrieved later using astGetProxy. -* -* The supplied pointer should point to a structure that is used -* to represent the AST Object within some external system. It is -* expected that the external system will check each object reference -* returned by AST to see if it has an associated proxy object. If not -* (i.e. if astGetProxy returns NULL), a new external object will be -* created to represent the AST Object, and a pointer to it will be -* stored in the AST Object using astSetProxy. If the AST Object -* already has a proxy, the AST reference is annulled and the existing -* proxy object is used by the external system. - -* Parameters: -* this -* Pointer to the Object. -* proxy -* Pointer to the proxy object, or NULL. - -* Notes: -* - The suppied pointer is not used within AST itself, other than to -* be returned by the astGetProxy method. -* - This function is public, but is currently undocumented since it -* is only of interest to people writing AST interfaces for other -* languages. -*- -*/ - if( !astOK ) return; - this->proxy = proxy; -} - -void astSetVtab_( AstObject *this, AstObjectVtab *vtab, int *status ) { -/* -*+ -* Name: -* astSetVtab - -* Purpose: -* Change the virtual function table associated with an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* void astSetVtab( AstObject *this, AstObjectVtab *vtab ) - -* Class Membership: -* Object method. - -* Description: -* This function changes the virtual function table associated with an -* Object. This may be needed, for instance, if a super-class -* initialises a parent class structure with a NULL vtab, causing the -* vtab of the parent class to be used instead of the super-class. -* Whilst the super-class object is being constructed its inherited methods -* will be determined by the parent class. Once the super-class object -* has been constructed, it can invoke this fuction in order to -* set the vtab to the super-class vtab, thus causing the method -* implementations provided by the super-cvlass to be used. - -* Parameters: -* this -* Pointer to the Object to be modified. -* vtab -* Pointer to the virtual function table to store in the Object. -*- -*/ - if( this ) this->vtab = vtab; -} - -static int Same( AstObject *this, AstObject *that, int *status ) { -/* -*++ -* Name: -c astSame -f AST_SAME - -* Purpose: -* Test if two AST pointers refer to the same Object. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c int astSame( AstObject *this, AstObject *that ) -f RESULT = AST_SAME( THIS, THAT, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function returns a boolean result (0 or 1) to indicate -f This function returns a logical result to indicate -* whether two pointers refer to the same Object. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the first Object. -c that -f THAT = INTEGER (Given) -* Pointer to the second Object. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSame() -c One if the two pointers refer to the same Object, otherwise zero. -f AST_SAME = LOGICAL -f .TRUE. if the two pointers refer to the same Object, otherwise -f .FALSE. - -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. - -* Notes: -* - Two independent Objects that happen to be identical are not -* considered to be the same Object by this function. -c - A value of zero will be returned if this function is invoked -c with the AST error status set, or if it should fail for any reason. -f - A value of .FALSE. will be returned if this function is invoked -f with STATUS set to an error value, or if it should fail for any reason. -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the result. */ - return ( this == that ) ? 1 : 0; -} - -/* -*++ -* Name: -c astSet -f AST_SET - -* Purpose: -* Set an attribute value for an Object. - -* Type: -* Public functions. - -* Synopsis: -c #include "object.h" -c void astSet( AstObject *this, const char *attrib, type value ) -f CALL AST_SET( THIS, ATTRIB, VALUE, STATUS ) - -* Class Membership: -* Object methods. - -* Description: -c This is a family of functions which set a specified attribute -f This is a family of routines which set a specified attribute -* value for an Object using one of several different data -c types. The type is selected by replacing in the function name -f types. The type is selected by replacing in the routine name -c by C, D, F, I or L, to supply a value in const char* (i.e. string), -c double, float, int, or long format, respectively. -f by C, D, I, L or R, to supply a value in Character, Double -f precision, Integer, Logical or Real format, respectively. -* -* If possible, the value you supply is converted to the type of -* the attribute. If conversion is not possible, an error will -* result. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Object. -c attrib -f ATTRIB = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing the -c name of the attribute whose value is to be set. -f A character string containing the name of the attribute whose -f value is to be set. -c value -f VALUE = type (Given) -c The value to be set for the attribute, in the data type corresponding -c to (or, in the case of astSetC, a pointer to a null-terminated -c character string containing this value). -f The value to be set for the attribute, in the data type corresponding -f to . -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Object -c These functions apply to all Objects. -f These routines apply to all Objects. - -* Examples: -c astSetI( frame, "Preserve", 1 ); -c Sets the Preserve attribute value for Object "frame" to 1. -c astSetC( plot, "Format(1)", "%.2g" ); -c Sets the Format(1) attribute value for Object "plot" to the -c character string "%.2g". -f CALL AST_SETC( PLOT, 'Title', CVALUE, STATUS ) -f Sets the Title attribute value for Object PLOT to the contents -f of the character variable CVALUE. -f CALL AST_SETL( FRAME, 'Preserve', .TRUE., STATUS ); -f Sets the Preserve attribute value for Object FRAME to 1 (true). - -* Notes: -* - Attribute names are not case sensitive and may be surrounded -* by white space. -f - The logical value .FALSE. will translate to a numerical attribute -f value of zero and logical .TRUE. will translate to one. -* - An error will result if an attempt is made to set a value for -* a read-only attribute. -*-- -*/ - -/* Define a macro that expands to implement the astSetX_ member - functions required. The arguments to this macro are: - - code - The character that appears at the end of the function name. - type - The C type of the function "value" parameter. - format - A quoted string containing a sprintf format specifier that will - format the supplied value as a character string. This format should - consume 2 sprintf arguments: a field width and the value to be - formatted. - fmtlen - The number of characters in the format specifier (above). - fieldsz - The value of the field width to be used by the format specifier. -*/ -#define MAKE_SETX(code,type,format,fmtlen,fieldsz) \ -void astSet##code##_( AstObject *this, const char *attrib, type value, int *status ) { \ -\ -/* Local Variables: */ \ - char *setting; /* Pointer to attribute setting string */ \ - int len; /* Length of attribute name */ \ -\ -/* Check the global status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain the length of the attribute name and allocate memory to hold \ - this name plus the format specifier to be appended to it. */ \ - len = (int) astChrLen( attrib ); \ - setting = astMalloc( (size_t) ( len + fmtlen + 2 ) ); \ -\ -/* Make a copy of the attribute name in the allocated memory. */ \ - if ( astOK ) { \ - (void) memcpy( setting, attrib, (size_t) len ); \ - setting[ len ] = 0; \ -\ -/* Append "=", followed by the format specifier, to construct a \ - suitable "setting" string for use by astSet. */ \ - (void) strcat( setting, "=" format ); \ -\ -/* Invoke astSet to set the attribute value. */ \ - astSet( this, setting, status, fieldsz, value ); \ - } \ -\ -/* Free the allocated memory. */ \ - setting = astFree( setting ); \ -} - -/* Use this macro to create all the SetX_ private member functions. */ -MAKE_SETX(D,double,"%.*g",4,AST__DBL_DIG) -MAKE_SETX(F,float,"%.*g",4,FLT_DIG) -MAKE_SETX(I,int,"%.*d",4,1) -MAKE_SETX(L,long,"%.*ld",5,1) - - -/* The astSetC_ function is implemented separately so that commas can be - handled. Since astSetC can only be used to set a single attribute - value, we know that any commas in the supplied value are included - within the attribuite value, rather than being used as delimiters - between adjacent attribute settings. To avoid VSet using them as - delimiters, they are replaced here by '\r' before calling astSet, and - VSet then converts them back to commas. */ - -void astSetC_( AstObject *this, const char *attrib, const char *value, int *status ) { - -/* Local Variables: */ - char *d; /* Pointer to next setting character */ - char *newv; /* Pointer to new attribute value string */ - char *setting; /* Pointer to attribute setting string */ - const char *c; /* Pointer to next value character */ - int len; /* Length of attribute name */ - -/* Check the global status. */ - if ( !astOK ) return; - -/* Produce a copy of the supplied attribute value in which any commas - are replaced by carriage returns ("\r"). */ - newv = astMalloc( (size_t)( strlen( value ) + 1 ) ); - if( newv ) { - d = newv; - c = value; - while( *c ) { - if( *c == ',' ) { - *d = '\r'; - } else { - *d = *c; - } - c++; - d++; - } - *d = 0; - -/* Obtain the length of the attribute name and allocate memory to hold - this name plus the format specifier to be appended to it. */ - len = (int) astChrLen( attrib ); - setting = astMalloc( (size_t) ( len + 5 ) ); - -/* Make a copy of the attribute name in the allocated memory. */ - if ( astOK ) { - (void) memcpy( setting, attrib, (size_t) len ); - setting[ len ] = 0; - -/* Append "=", followed by the format specifier, to construct a - suitable "setting" string for use by astSet. */ - (void) strcat( setting, "=%*s" ); - -/* Invoke astSet to set the attribute value. */ - astSet( this, setting, status, 0, newv ); - } - -/* Free the allocated memory. */ - setting = astFree( setting ); - } - newv = astFree( newv ); -} - -static void Show( AstObject *this, int *status ) { -/* -*++ -* Name: -c astShow -f AST_SHOW - -* Purpose: -* Display a textual representation of an Object on standard output. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c void astShow( AstObject *this ) -f CALL AST_SHOW( THIS, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function displays a textual description of any AST Object -f This routine displays a textual description of any AST Object -* on standard output. It is provided primarily as an aid to -* debugging. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Object to be displayed. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. -*-- -*/ - -/* Local Variables: */ - AstChannel *channel; /* Pointer to output Channel */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Create a Channel which will write to standard output. */ - channel = astChannel( NULL, NULL, "", status ); - -/* Write the Object to the Channel. */ - astWrite( channel, this ); - -/* Annul the Channel pointer. */ - channel = astAnnul( channel ); -} - -int astTest_( AstObject *this, const char *attrib, int *status ) { -/* -*++ -* Name: -c astTest -f AST_TEST - -* Purpose: -* Test if an Object attribute value is set. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c int astTest( AstObject *this, const char *attrib ) -f RESULT = AST_TEST( THIS, ATTRIB, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function returns a boolean result (0 or 1) to indicate -f This function returns a logical result to indicate -* whether a value has been explicitly set for one of an Object's -* attributes. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Object. -c attrib -f ATTRIB = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing -c the name of the attribute to be tested. -f A character string containing the name of the attribute to be -f tested. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astTest() -c One if a value has previously been explicitly set for the attribute -c (and hasn't been cleared), otherwise zero. -f AST_TEST = LOGICAL -f .TRUE. if a value has previously been explicitly set for the -f attribute (and hasn't been cleared), otherwise .FALSE.. - -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. - -* Notes: -* - Attribute names are not case sensitive and may be surrounded -* by white space. -c - A value of zero will be returned if this function is invoked -f - A value of .FALSE. will be returned if this function is invoked -c with the AST error status set, or if it should fail for any reason. -f with STATUS set to an error value, or if it should fail for any reason. -c - A value of zero will also be returned if this function is used -f - A value of .FALSE. will also be returned if this function is used -* to test a read-only attribute, although no error will result. -*-- -*/ - -/* Local Variables: */ - char *buff; /* Pointer to character buffer */ - int i; /* Loop counter for characters */ - int j; /* Non-blank character count */ - int len; /* Length of attrib string */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain the length of the attrib string. */ - len = (int) strlen( attrib ); - -/* Allocate memory and store a copy of the string. */ - buff = astStore( NULL, attrib, (size_t) ( len + 1 ) ); - if ( astOK ) { - -/* Remove white space and upper case characters. */ - for ( i = j = 0; buff[ i ]; i++ ) { - if ( !isspace( buff[ i ] ) ) buff[ j++ ] = tolower( buff[ i ] ); - } - -/* Terminate the attribute name and pass it to astTestAttrib to test - the attribute. */ - buff[ j ] = '\0'; - result = astTestAttrib( this, buff ); - } - -/* Free the memory allocated for the string buffer. */ - buff = astFree( buff ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int TestAttrib( AstObject *this, const char *attrib, int *status ) { -/* -*+ -* Name: -* astTestAttrib - -* Purpose: -* Test if a specified attribute value is set for an Object. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "object.h" -* int astTestAttrib( AstObject *this, const char *attrib ) - -* Class Membership: -* Object method. - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of an Object's attributes. - -* Parameters: -* this -* Pointer to the Object. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check the attribute name and test the appropriate attribute. */ - -/* ID. */ -/* --- */ - if ( !strcmp( attrib, "id" ) ) { - result = astTestID( this ); - -/* Ident. */ -/* ------ */ - } else if ( !strcmp( attrib, "ident" ) ) { - result = astTestIdent( this ); - -/* UseDefs */ -/* ------- */ - } else if ( !strcmp( attrib, "usedefs" ) ) { - result = astTestUseDefs( this ); - -/* Test if the attribute string matches any of the read-only - attributes of this class. If it does, then return zero. */ - } else if ( !strcmp( attrib, "class" ) || - !strcmp( attrib, "nobject" ) || - !strcmp( attrib, "objsize" ) || - !strcmp( attrib, "refcount" ) ) { - result = 0; - -/* Any attempt to test any other attribute is an error. */ - } else if( astOK ){ - astError( AST__BADAT, "astTest: The attribute name \"%s\" is invalid " - "for a %s.", status, attrib, astGetClass( this ) ); - } - -/* Return the result, */ - return result; -} - -int astTune_( const char *name, int value, int *status ) { -/* -*++ -* Name: -c astTune -f AST_TUNE - -* Purpose: -* Set or get an integer-valued AST global tuning parameter. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c int astTune( const char *name, int value ) -f RESULT = AST_TUNE( NAME, VALUE, STATUS ) - -* Class Membership: -* Object function. - -* Description: -* This function returns the current value of an integer-valued AST -* global tuning parameter, optionally storing a new value for the -* parameter. For character-valued tuning parameters, see -c astTuneC. -f AST_TUNEC. - -* Parameters: -c name -f NAME = CHARACTER * ( * ) (Given) -* The name of the tuning parameter (case-insensitive). -c value -f VALUE = INTEGER (Given) -* The new value for the tuning parameter. If this is AST__TUNULL, -* the existing current value will be retained. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astTune() -f AST_TUNE = INTEGER -c The original value of the tuning parameter. A default value will -* be returned if no value has been set for the parameter. - -* Tuning Parameters: -* ObjectCaching -* A boolean flag which indicates what should happen -* to the memory occupied by an AST Object when the Object is deleted -* (i.e. when its reference count falls to zero or it is deleted using -c astDelete). -f AST_DELETE). -* If this is zero, the memory is simply freed using the systems "free" -* function. If it is non-zero, the memory is not freed. Instead a -* pointer to it is stored in a pool of such pointers, all of which -* refer to allocated but currently unused blocks of memory. This allows -* AST to speed up subsequent Object creation by re-using previously -* allocated memory blocks rather than allocating new memory using the -* systems malloc function. The default value for this parameter is -* zero. Setting it to a non-zero value will result in Object memory -* being cached in future. Setting it back to zero causes any memory -* blocks currently in the pool to be freed. Note, this tuning parameter -* only controls the caching of memory used to store AST Objects. To -* cache other memory blocks allocated by AST, use MemoryCaching. -* MemoryCaching -* A boolean flag similar to ObjectCaching except -* that it controls caching of all memory blocks of less than 300 bytes -* allocated by AST (whether for internal or external use), not just -* memory used to store AST Objects. - -* Notes: -c - This function attempts to execute even if the AST error -c status is set -f - This routine attempts to execute even if STATUS is set to an -f error value -* on entry, although no further error report will be -* made if it subsequently fails under these circumstances. -* - All threads in a process share the same AST tuning parameters -* values. -*-- -*/ - - int result = AST__TUNULL; - - if( name ) { - - LOCK_MUTEX1; - - if( astChrMatch( name, "ObjectCaching" ) ) { - result = object_caching; - if( value != AST__TUNULL ) { - object_caching = value; - if( !object_caching ) EmptyObjectCache( status ); - } - - } else if( astChrMatch( name, "MemoryCaching" ) ) { - result = astMemCaching( value ); - - } else if( astOK ) { - astError( AST__TUNAM, "astTune: Unknown AST tuning parameter " - "specified \"%s\".", status, name ); - } - - UNLOCK_MUTEX1; - - } - - return result; -} - -void astTuneC_( const char *name, const char *value, char *buff, - int bufflen, int *status ) { -/* -*++ -* Name: -c astTuneC -f AST_TUNEC - -* Purpose: -* Set or get a character-valued AST global tuning parameter. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c void astTuneC( const char *name, const char *value, char *buff, -c int bufflen ) -f CALL AST_TUNEC( NAME, VALUE, BUFF, STATUS ) - -* Class Membership: -* Object function. - -* Description: -* This function returns the current value of a character-valued -* AST global tuning parameter, optionally storing a new value -* for the parameter. For integer-valued tuning parameters, see -c astTune. -f AST_TUNE. - -* Parameters: -c name -f NAME = CHARACTER * ( * ) (Given) -* The name of the tuning parameter (case-insensitive). -c value -f VALUE = CHARACTER * ( ) (Given) -* The new value for the tuning parameter. If this is -f AST__TUNULLC, -c NULL, -* the existing current value will be retained. -c buff -f BUFF = CHARACTER * ( ) (Given) -* A character string in which to return the original value of -* the tuning parameter. An error will be reported if the buffer -* is too small to hold the value. -c NULL may be supplied if the old value is not required. -c bufflen -c The size of the supplied "buff" array. Ignored if "buff" is NULL. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Tuning Parameters: -* HRDel -* A string to be drawn following the hours field in a formatted -* sky axis value when "g" format is in use (see the Format -* attribute). This string may include escape sequences to produce -* super-scripts, etc. (see the Escapes attribute for details -* of the escape sequences allowed). The default value is -* "%-%^50+%s70+h%+" which produces a super-script "h". -* MNDel -* A string to be drawn following the minutes field in a formatted -* sky axis value when "g" format is in use. The default value is -* "%-%^50+%s70+m%+" which produces a super-script "m". -* SCDel -* A string to be drawn following the seconds field in a formatted -* sky axis value when "g" format is in use. The default value is -* "%-%^50+%s70+s%+" which produces a super-script "s". -* DGDel -* A string to be drawn following the degrees field in a formatted -* sky axis value when "g" format is in use. The default value is -* "%-%^53+%s60+o%+" which produces a super-script "o". -* AMDel -* A string to be drawn following the arc-minutes field in a formatted -* sky axis value when "g" format is in use. The default value is -* "%-%^20+%s85+'%+" which produces a super-script "'" (single quote). -* ASDel -* A string to be drawn following the arc-seconds field in a formatted -* sky axis value when "g" format is in use. The default value is -* "%-%^20+%s85+\"%+" which produces a super-script """ (double quote). -* EXDel -* A string to be drawn to introduce the exponent in a value when "g" -* format is in use. The default value is "10%-%^50+%s70+" which -* produces "10" followed by the exponent as a super-script. - -* Notes: -c - This function attempts to execute even if the AST error -c status is set -f - This routine attempts to execute even if STATUS is set to an -f error value -* on entry, although no further error report will be -* made if it subsequently fails under these circumstances. -* - All threads in a process share the same AST tuning parameters -* values. -*-- -*/ - -/* Local Variables: */ - char *p = NULL; - int len; - -/* Check the name of a tuning parameter was supplied. */ - if( name ) { - -/* Serialise access to the tuning parameters since they are common to all - threads. */ - LOCK_MUTEX1; - -/* Get a pointer to the buffer that holds the value of the requested - tuning parameter. */ - if( astChrMatch( name, "hrdel" ) ) { - p = hrdel; - } else if( astChrMatch( name, "mndel" ) ) { - p = mndel; - } else if( astChrMatch( name, "scdel" ) ) { - p = scdel; - } else if( astChrMatch( name, "dgdel" ) ) { - p = dgdel; - } else if( astChrMatch( name, "amdel" ) ) { - p = amdel; - } else if( astChrMatch( name, "asdel" ) ) { - p = asdel; - } else if( astChrMatch( name, "exdel" ) ) { - p = exdel; - -/* Report an error if an the tuning parameter name is unknown. */ - } else if( astOK ) { - p = NULL; - astError( AST__TUNAM, "astTuneC: Unknown AST tuning parameter " - "specified \"%s\".", status, name ); - } - -/* If the existing value was found. */ - if( p ) { - -/* And is to be returned in the supplied buffer... */ - if( buff ) { - -/* Check that the buffer is long enough. If so, copy the current value - into the buffer, otherwise report an error. */ - len = strlen( p ) ; - if( len < bufflen ) { - strcpy( buff, p ); - } else { - astError( AST__TUNAM, "astTuneC: Supplied string variable " - "is too small - the current '%s' value (%s) has " - "%d characters.", status, name, p, len ); - } - } - -/* If a new value is to be stored.... */ - if( value ) { - -/* Report an error if it is too long to fit in the static buffer. */ - len = strlen( value ) ; - if( len >= MAXLEN_TUNEC ) { - astError( AST__TUNAM, "astTuneC: Supplied value for '%s' " - "(%s) is too long - must not be longer than %d " - "characters.", status, name, value, MAXLEN_TUNEC ); - -/* Otherwise, copy the new value into the static buffer. */ - } else { - strcpy( p, value ); - } - } - } - - UNLOCK_MUTEX1; - } -} - -AstObject *astFromString_( const char *string, int *status ) { -/* -c++ -* Name: -* astFromString - -* Purpose: -* Re-create an Object from an in-memory serialisation - -* Type: -* Public function. - -* Synopsis: -* #include "object.h" -* AstObject *astFromString( const char *string ) - -* Class Membership: -* Object method. - -* Description: -* This function returns a pointer to a new Object created from the -* supplied text string, which should have been created by astToString. - -* Parameters: -* string -* Pointer to a text string holding an Object serialisation created -* previously by astToString. - -* Returned Value: -* astFromString() -* Pointer to a new Object created from the supplied serialisation, -* or NULL if the serialisation was invalid, or an error occurred. - -c-- -*/ - -/* Local Variables: */ - StringData data; /* Data passed to the source function */ - AstChannel *channel; /* Pointer to output Channel */ - AstObject *result; /* Pointer to returned Object */ - -/* Check the global error status and supplied serialisation. */ - if ( !astOK || !string ) return NULL; - -/* Create a Channel which will read from the supplied serialisation. */ - channel = astChannel( FromStringSource, NULL, "", status ); - -/* Initialise the data structure used to communicate with the source - function, and store a pointer to it in the Channel. */ - data.ptr = (char *) string; - data.buff = NULL; - data.len = 0; - astPutChannelData( channel, &data ); - -/* Read an Object from the Channel. */ - result = astRead( channel ); - -/* Annul the Channel pointer. */ - channel = astAnnul( channel ); - -/* Free the line buffer. */ - data.buff = astFree( data.buff ); - -/* Annul the returned Object if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the Object pointer. */ - return result; -} - -static const char *FromStringSource( void ){ -/* -* Name: -* FromStringSource - -* Purpose: -* A Channel source function for use by the astFromString method. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* result = FromStringSource( void ) - -* Class Membership: -* Object member function. - -* Description: -* This function reads the next line of text from a serialisation and -* returns a pointer to it, or NULL if no lines remain. - -* Returned Value: -* Pointer to the null terminated line of text or NULL if no lines -* remain. -*/ - -/* Local Variables: */ - StringData *data; /* Data passed to the sink function */ - char *nl; /* Pointer to next newline character */ - int *status; /* Pointer to local status value */ - int nc; /* Number of characters to read from serialisation */ - int status_value; /* Local status value */ - -/* Set up the local status */ - status_value = 0; - status = &status_value; - -/* Get a pointer to the structure holding a pointer to the next line, and - to the buffer to return. */ - data = astChannelData; - -/* Return NULL if no text remains to be read. */ - if( !data->ptr || (data->ptr)[0] == 0 ) return NULL; - -/* Find the next newline (if any) in the serialisation. */ - nl = strchr( data->ptr, '\n' ); - -/* Get the number of characters to copy. */ - nc = nl ? nl - data->ptr : strlen( data->ptr ); - -/* Copy them into the returned buffer, including an extra character for - the terminating null. */ - data->buff = astStore( data->buff, data->ptr, nc + 1 ); - -/* Store the terminating null. */ - (data->buff)[ nc ] = 0; - -/* Update the pointer to the next character to read from the - serialisation. */ - data->ptr = nl ? nl + 1 : NULL; - -/* Return the buffer. */ - return data->buff; -} - -static void VSet( AstObject *this, const char *settings, char **text, - va_list args, int *status ) { -/* -*+ -* Name: -* astVSet - -* Purpose: -* Set values for an Object's attributes. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "object.h" -* void astVSet( AstObject *this, const char *settings, char **text, -* va_list args ) - -* Class Membership: -* Object method. - -* Description: -* This function assigns a set of attribute values for an Object, -* the attributes and their values being specified by means of a -* string containing a comma-separated list of the form: -* -* "attribute1 = value1, attribute2 = value2, ... " -* -* Here, "attribute" specifies an attribute name and the value to -* the right of each "=" sign should be a suitable textual -* representation of the value to be assigned to that -* attribute. This will be interpreted according to the attribute's -* data type. -* -* The string supplied may also contain "printf"-style format -* specifiers identified by a "%" sign in the usual way. If -* present, these will be substituted by values supplied as -* optional arguments (as a va_list variable argument list), using -* the normal "printf" rules, before the string is used. - -* Parameters: -* this -* Pointer to the Object. -* settings -* Pointer to a null-terminated string containing a -* comma-separated list of attribute settings. -* text -* Pointer to a location at which to return a pointer to dynamic -* memory holding a copy of the expanded setting string. This memory -* should be freed using astFree when no longer needed. If a NULL -* pointer is supplied, no string is created. -* args -* The variable argument list which contains values to be -* substituted for any "printf"-style format specifiers that -* appear in the "settings" string. - -* Notes: -* - Attribute names are not case sensitive. -* - White space may surround attribute names and will be ignored. -* - White space may also surround attribute values where it will -* be ignored (except for string-valued attributes where it is -* significant and forms part of the value to be assigned). -* - After this function has substituted values for "printf"-style -* format specifiers it splits the "settings" string into -* individual attribute settings which it passes one at a time to -* the protected astSetAttrib method (after removal of white space -* and conversion of attribute names to lower case). The -* astSetAttrib method should therefore be extended by derived -* classes which define new attributes, and this will allow the -* astVSet (and astSet) methods to have access to those attributes. -* - This function provides the same functionality as the astSet -* public method but accepts a va_list variable argument list -* instead of a variable number of arguments. It is provided for -* use by functions in other class implementations which accept a -* variable number of arguments and must therefore pass their -* argument list to this method in va_list form. -*- -*/ - -#define MIN_BUFF_LEN 1024 -#define ERRBUF_LEN 80 - -/* Local Variables: */ - char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */ - char setting_buf[ MIN_BUFF_LEN ]; /* Expanded "%s" settting string */ - char *dyn_buf; /* Pointer to dynamic buffer for expanded setting */ - char *errstat; /* Pointer to error message */ - char *assign; /* Pointer to assigment substring */ - char *assign_end; /* Pointer to null at end of assignment */ - char *buff1; /* Pointer to temporary string buffer */ - char *buff2; /* Pointer to temporary string buffer */ - char *buff3; /* Pointer to temporary string buffer */ - char *eq1; /* Pointer to 1st equals sign */ - int buff_len; /* Length of temporary buffer */ - int expanded; /* Has the Settings string been expanded yet? */ - int i; /* Loop counter for characters */ - int j; /* Offset for revised assignment character */ - int len; /* Length of settings string */ - int lo; /* Convert next character to lower case? */ - int nc; /* Number of vsprintf output characters */ - int quoted; /* Are we in a quoted string? */ - int stat; /* Value of errno after an error */ - int tq; /* Test if the next non-space is a quote? */ - -/* Initialise */ - if( text ) *text = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the length of the "settings" string and test it is not - zero. If it is, there is nothing more to do. */ - len = (int) strlen( settings ); - if ( len != 0 ) { - -/* If the setting string is just "%s" (with optional trailing and leading - white space) then the variable argument potentially contains more than - one attribute setting, in which case we expand the setting string now - and use the expanded string in place of the supplied string in the rest - of this function. */ - nc = 0; - sscanf( settings, " %%s %n", &nc ); - if( nc == len ) { - -/* Expand the supplied string using a fixed-length buffer. This writes at - most MIN_BUFF_LEN characters to "buf", but returns the number of - characters that would have been needed to write the whole string. */ - len = vsnprintf( setting_buf, sizeof(setting_buf), settings, args ); - -/* If the fixed-length buffer is too short, use a dynamically allocated - buffer instead. */ - if( len + 1 > MIN_BUFF_LEN ) { - dyn_buf = astMalloc( len + 1 ); - if( astOK ) { - len = vsnprintf( dyn_buf, len + 1, settings, args ); - settings = dyn_buf; - } - } else { - dyn_buf = NULL; - settings = setting_buf; - } - -/* Indicate that "settings" has been expanded. */ - expanded = 1; - - } else { - expanded = 0; - dyn_buf = NULL; - } - -/* Allocate memory and store a copy of the string. */ - buff1 = astStore( NULL, settings, (size_t) ( len + 1 ) ); - if ( astOK ) { - -/* Convert each comma in the string into '\n'. This is to distinguish - commas initially present from those introduced by the formatting to - be performed below. We only do this if there is more than one equals - sign in the setting string, since otherwise any commas are probably - characters contained within a string attribute value. Ignore commas - that occur within quoted strings. */ - eq1 = strchr( buff1, '=' ); - if( eq1 && strchr( eq1 + 1, '=' ) ) { - quoted = 0; - for ( i = 0; i < len; i++ ) { - if( !quoted ) { - if ( buff1[ i ] == ',' ) { - buff1[ i ] = '\n'; - } else if( buff1[ i ] == '"' ) { - quoted = 1; - } - } else if( buff1[ i ] == '"' ){ - quoted = 0; - } - } - } - -/* Calculate a size for a further buffer twice the size of the first - one. Ensure it is not less than a minimum size and then allocate - this buffer. */ - buff_len = 2 * len; - if ( buff_len < MIN_BUFF_LEN ) buff_len = MIN_BUFF_LEN; - buff2 = astMalloc( (size_t) ( buff_len + 1 ) ); - if ( astOK ) { - -/* Use "vsprintf" to substitute values for any format specifiers in - the "settings" string, writing the resulting string into the second - buffer. If the "settings" string has already been expanded, then just - copy it. */ - errno = 0; - if( !expanded ) { - nc = vsprintf( buff2, buff1, args ); - } else { - strcpy( buff2, buff1 ); - nc = strlen( buff1 ); - } - -/* Get a copy of the expanded string to return as the function value and - convert newlines back to commas. */ - if( text ) { - *text = astStore( NULL, buff2, nc + 1 ); - if( *text ) { - for ( i = 0; i <= nc; i++ ) { - if ( (*text)[ i ] == '\n' ) (*text)[ i ] = ','; - } - } - } - -/* The possibilities for error detection are limited here, but check - if an error value was returned and report an error. Include - information from errno if it was set. */ - if ( nc < 0 ) { - if( astOK ) { - stat = errno; - - if( stat ) { -#if HAVE_STRERROR_R - strerror_r( stat, errbuf, ERRBUF_LEN ); - errstat = errbuf; -#else - errstat = strerror( stat ); -#endif - } else { - *errbuf = 0; - errstat = errbuf; - } - - astError( AST__ATSER, "astVSet(%s): Error formatting an " - "attribute setting%s%s.", status, astGetClass( this ), - stat? " - " : "", errstat ); - astError( AST__ATSER, "The setting string was \"%s\".", status, - settings ); - } - -/* Also check that the result buffer did not overflow. If it did, - memory will probably have been corrupted but this cannot be - prevented with "vsprintf" (although we try and make the buffer - large enough). Report the error and abort. */ - } else if ( nc > buff_len ) { - if( astOK ) { - astError( AST__ATSER, "astVSet(%s): Internal buffer overflow " - "while formatting an attribute setting - the result " - "exceeds %d characters.", status, astGetClass( this ), - buff_len ); - astError( AST__ATSER, "The setting string was \"%s\".", status, - settings ); - } - -/* If all is OK, loop to process each formatted attribute assignment - (these are now separated by '\n' characters). */ - } else { - assign = buff2; - while ( assign ) { - -/* Change the '\n' at the end of each assignment to a null to - terminate it. */ - if ( ( assign_end = strchr( assign, '\n' ) ) ) { - *assign_end = '\0'; - } - -/* Before making the assignment, loop to remove white space and upper - case characters from the attribute name. */ - lo = 1; - tq = -1; - quoted = 0; - for ( i = j = 0; assign[ i ]; i++ ) { - -/* Note when an '=' sign is encountered (this signals the end of the - attribute name). */ - if ( assign[ i ] == '=' ) lo = 0; - -/* Before the '=' sign, convert all characters to lower case and move - everything to the left to eliminate white space. Afer the '=' sign, - copy all characters to their new location unchanged, except for any - delimiting quotes, which are removed. astSetC replaces commas in the - attribute value by '\r' characters. Reverse this now. */ - if ( !lo || !isspace( assign[ i ] ) ) { - if( assign[ i ] == '\r' ) { - assign[ j++ ] = ','; - - } else if( lo ) { - assign[ j++ ] = tolower( assign[ i ] ); - - } else { - assign[ j++ ] = assign[ i ]; - - if( tq > 0 && !isspace( assign[ i ] ) ) { - if( assign[ i ] == '"' ) { - quoted = 1; - j--; - } - tq = 0; - } - - } - } - -/* If the current character is the initial '=' sign, set "tq" positive, - meaning "check if the next non-space character is a quote". */ - if ( assign[ i ] == '=' && tq == -1 ) tq = 1; - } - -/* if the value was quoted. remove the trailing quote. */ - if( quoted ) { - j--; - while( isspace( assign[ j ] ) ) j--; - if( assign[ j ] == '"' ) j--; - j++; - } - -/* Terminate the revised assignment string and pass it to astSetAttrib - to make the assignment (unless the string was all blank, in which - case we ignore it). */ - assign[ j ] = '\0'; - if ( j ) { - -/* If there are no characters to the right of the equals sign append a - space after the equals sign. Without this, a string such as "Title=" - would not be succesfully matched against the attribute name "Title" - within SetAttrib. */ - if( assign[ j - 1 ] == '=' ) { - buff3 = astStore( NULL, assign, - (size_t) j + 2 ); - if ( astOK ) { - buff3[ j ] = ' '; - buff3[ j + 1 ] = '\0'; - astSetAttrib( this, buff3 ); - } - buff3 = astFree( buff3 ); - - } else { - astSetAttrib( this, assign ); - } - } - -/* Check for errors and abort if any assignment fails. Otherwise, - process the next assignment substring. */ - if ( !astOK ) break; - assign = assign_end ? assign_end + 1 : NULL; - } - } - } - -/* Free the memory allocated for string buffers. */ - buff2 = astFree( buff2 ); - dyn_buf = astFree( dyn_buf ); - } - buff1 = astFree( buff1 ); - } -} -#undef ERRBUF_LEN -#undef MIN_BUFF_LEN - -/* Attribute access functions. */ -/* --------------------------- */ -/* -*att++ -* Name: -* Class - -* Purpose: -* Object class name. - -* Type: -* Public attribute. - -* Synopsis: -* Character string, read-only. - -* Description: -* This attribute gives the name of the class to which an Object -* belongs. - -* Applicability: -* Object -* All Objects have this attribute. -*att-- -*/ - -/* -*att++ -* Name: -* ID - -* Purpose: -* Object identification string. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute contains a string which may be used to identify -* the Object to which it is attached. There is no restriction on -* the contents of this string, which is not used internally by the -* AST library, and is simply returned without change when -* required. The default value is an empty string. -* -* An identification string can be valuable when, for example, -c several Objects have been stored in a file (using astWrite) and -f several Objects have been stored in a file (using AST_WRITE) and -c are later retrieved (using astRead). Consistent use of the ID -f are later retrieved (using AST_READ). Consistent use of the ID -* attribute allows the retrieved Objects to be identified without -* depending simply on the order in which they were stored. -* -* This attribute may also be useful during debugging, to -c distinguish similar Objects when using astShow to display them. -f distinguish similar Objects when using AST_SHOW to display them. - -* Applicability: -* Object -* All Objects have this attribute. - -* Notes: -* - Unlike most other attributes, the value of the ID attribute is -* not transferred when an Object is copied. Instead, its value is -* undefined (and therefore defaults to an empty string) in any -* copy. However, it is retained in any external representation of -c an Object produced by the astWrite function. -f an Object produced by the AST_WRITE routine. -*att-- -*/ -/* Clear the ID value by freeing the allocated memory and assigning a - NULL pointer. */ -astMAKE_CLEAR(Object,ID,id,astFree( this->id )) - -/* If the ID value is not set, supply a default in the form of a - pointer to the constant string "". */ -astMAKE_GET(Object,ID,const char *,NULL,( this->id ? this->id : "" )) - -/* Set an ID value by freeing any previously allocated memory, - allocating new memory and storing the string. */ -astMAKE_SET(Object,ID,const char *,id,astStore( this->id, value, - strlen( value ) + (size_t) 1 )) - -/* The ID value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Object,ID,( this->id != NULL )) - -/* -*att++ -* Name: -* Ident - -* Purpose: -* Permanent Object identification string. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute is like the ID attribute, in that it contains a -* string which may be used to identify the Object to which it is -* attached. The only difference between ID and Ident is that Ident -* is transferred when an Object is copied, but ID is not. - -* Applicability: -* Object -* All Objects have this attribute. - -*att-- -*/ -/* Clear the Ident value by freeing the allocated memory and assigning a - NULL pointer. */ -astMAKE_CLEAR(Object,Ident,ident,astFree( this->ident )) - -/* If the Ident value is not set, supply a default in the form of a - pointer to the constant string "". */ -astMAKE_GET(Object,Ident,const char *,NULL,( this->ident ? this->ident : "" )) - -/* Set an Ident value by freeing any previously allocated memory, - allocating new memory and storing the string. */ -astMAKE_SET(Object,Ident,const char *,ident,astStore( this->ident, value, - strlen( value ) + (size_t) 1 )) - -/* The Ident value is set if the pointer to it is not NULL. */ -astMAKE_TEST(Object,Ident,( this->ident != NULL )) - -/* -*att++ -* Name: -* UseDefs - -* Purpose: -* Use default values for unspecified attributes? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute specifies whether default values should be used -* internally for object attributes which have not been assigned a -* value explicitly. If a non-zero value (the default) is supplied for -* UseDefs, then default values will be used for attributes which have -* not explicitly been assigned a value. If zero is supplied for UseDefs, -* then an error will be reported if an attribute for which no explicit -* value has been supplied is needed internally within AST. -* -* Many attributes (including the UseDefs attribute itself) are unaffected -* by the setting of the UseDefs attribute, and default values will always -* be used without error for such attributes. The "Applicability:" section -* below lists the attributes which are affected by the setting of UseDefs. - -* Note, UseDefs only affects access to attributes internally within -* AST. The public accessor functions such as -c astGetC -f AST_GETC -* is unaffected by the UseDefs attribute - default values will always -* be returned if no value has been set. Application code should use the -c astTest -f AST_TEST -* function if required to determine if a value has been set for an -* attribute. - -* Applicability: -* Object -* All Objects have this attribute, but ignore its setting except -* as described below for individual classes. -* FrameSet -* The default value of UseDefs for a FrameSet is redefined to be -* the UseDefs value of its current Frame. -* CmpFrame -* The default value of UseDefs for a CmpFrame is redefined to be -* the UseDefs value of its first component Frame. -* Region -* The default value of UseDefs for a Region is redefined to be -* the UseDefs value of its encapsulated Frame. -* Frame -* If UseDefs is zero, an error is reported when aligning Frames if the -* Epoch, ObsLat or ObsLon attribute is required but has not been -* assigned a value explicitly. -* SkyFrame -* If UseDefs is zero, an error is reported when aligning SkyFrames -* if any of the following attributes are required but have not been -* assigned a value explicitly: Epoch, Equinox. -* SpecFrame -* If UseDefs is zero, an error is reported when aligning SpecFrames -* if any of the following attributes are required but have not been -* assigned a value explicitly: Epoch, RefRA, RefDec, RestFreq, -* SourceVel, StdOfRest. -* DSBSpecFrame -* If UseDefs is zero, an error is reported when aligning DSBSpecFrames -* or when accessing the ImagFreq attribute if any of the following -* attributes are required but have not been assigned a value explicitly: -* Epoch, DSBCentre, IF. -*att-- -*/ -astMAKE_CLEAR(Object,UseDefs,usedefs,CHAR_MAX) -astMAKE_GET(Object,UseDefs,int,1,((this->usedefs!=CHAR_MAX)?this->usedefs:1)) -astMAKE_SET(Object,UseDefs,int,usedefs,((value)?1:0)) -astMAKE_TEST(Object,UseDefs,(this->usedefs!=CHAR_MAX)) - -/* -*att++ -* Name: -* Nobject - -* Purpose: -* Number of Objects in class. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the total number of Objects currently in -* existence in the same class as the Object whose attribute value -* is requested. This count does not include Objects which belong -* to derived (more specialised) classes. -* -* This attribute is mainly intended for debugging. It can be used -* to detect whether Objects which should have been deleted have, -* in fact, been deleted. - -* Applicability: -* Object -* All Objects have this attribute. -*att-- -*/ - -/* -*att++ -* Name: -* ObjSize - -* Purpose: -* The in-memory size of the Object. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the total number of bytes of memory used by -* the Object. This includes any Objects which are encapsulated within -* the supplied Object. - -* Applicability: -* Object -* All Objects have this attribute. -*att-- -*/ - -/* -*att++ -* Name: -* RefCount - -* Purpose: -* Count of active Object pointers. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the number of active pointers associated -* with an Object. It is modified whenever pointers are created or -c annulled (by astClone, astAnnul or astEnd for example). The count -f annulled (by AST_CLONE, AST_ANNUL or AST_END for example). The count -* includes the initial pointer issued when the Object was created. -* -* If the reference count for an Object falls to zero as the result -* of annulling a pointer to it, then the Object will be deleted. - -* Applicability: -* Object -* All Objects have this attribute. -*att-- -*/ - -/* Standard class functions. */ -/* ========================= */ -/* -*+ -* Name: -* astCheck - -* Purpose: -* Validate class membership. - -* Type: -* Protected function. - -* Synopsis: -* #include "class.h" -* Ast *astCheck( Ast *this ) - -* Class Membership: -* class function. - -* Description: -* This function validates membership of the class called , -* or of any class derived from it. If the Object is not a member, -* or the pointer supplied does not identify a valid Object, an -* error is reported and the global error status is set to -* AST__OBJIN. - -* Parameters: -* this -* Pointer to the Object. - -* Returned Value: -* The function always returns a copy of the "this" pointer -* (whether it finds it valid or not). - -* Notes: -* - Each class provides a function (astCheck) of this form, -* where and are replaced by the class name (with -* appropriate capitalisation). -* - Normal error status checking is performed, so this function -* will not execute if the global error status is set on entry (the -* usual function value will be returned, however). -* - This function is primarily intended for validating Object -* pointers passed to member functions as part of a class -* interface. -*- -*/ - -/* Implement the astCheckObject function using the macro defined for this - purpose in the "object.h" header file. */ -astMAKE_CHECK(Object) - -int astIsAObject_( const AstObject *this, int *status ) { -/* -*++ -* Name: -c astIsA -f AST_ISA - -* Purpose: -* Test membership of a class by an Object. - -* Type: -* Public function. - -* Synopsis: -c #include "class.h" -c int astIsA( const Ast *this ) -f RESULT = AST_ISA( THIS, STATUS ) - -* Class Membership: -* Class function. - -* Description: -* This is a family of functions which test whether an Object is a -c member of the class called , or of any class derived from -f member of the class called , or of any class derived from -* it. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Object. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astIsA() -c One if the Object belongs to the class called (or to a -c class derived from it), otherwise zero. -f AST_ISA = LOGICAL -f .TRUE. if the Object belongs to the class called (or to -f a class derived from it), otherwise .FALSE.. - -* Applicability: -* Object -* These functions apply to all Objects. - -* Examples: -c member = astIsAFrame( obj ); -c Tests whether Object "obj" is a member of the Frame class, or -c of any class derived from a Frame. -f MEMBER = AST_ISAFRAME( OBJ, STATUS ); -f Tests whether Object OBJ is a member of the Frame class, or -f of any class derived from a Frame. - -* Notes: -c - Every AST class provides a function (astIsA) of this -c form, where should be replaced by the class name. -f - Every AST class provides a function (AST_ISA) of this -f form, where should be replaced by the class name. -c - This function attempts to execute even if the AST error status -c is set -f - This function attempts to execute even if STATUS is set to an -f error value -* on entry, although no further error report will be made -* if it subsequently fails under these circumstances. -c - A value of zero will be returned if this function should fail -f - A value of .FALSE. will be returned if this function should fail -* for any reason. In particular, it will fail if the pointer -* supplied does not identify an Object of any sort. -*-- -*/ - -/* Local Variables: */ - int valid; /* Valid object? */ - -/* Since this is the base class, the implementation of this function - differs from that in derived classes (in that it fails and - potentially reports an error if the returned result is zero). */ - -/* Initialise. */ - valid = 0; - -/* Check if a NULL pointer was supplied (this can never be valid). If - OK, check if the Object contains the correct "magic number" in its - check field. */ - if ( !this || ( this->check != Magic( this, this->size, status ) ) ) { - -/* If it is not a valid Object, then report an error (but only if the - global error status has not already been set). */ - if ( astOK ) { - astError( AST__OBJIN, "astIsAObject(%s): Invalid Object pointer " - "given (points at address %p).", status, astGetClass( this ), - (void *) this ); - } - -/* Otherwise, note that the Object is valid. */ - } else { - valid = 1; - } - -/* Return the result. */ - return valid; -} - -void astInitObjectVtab_( AstObjectVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitObjectVtab - -* Purpose: -* Initialise a virtual function table for a Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* void astInitObjectVtab( AstObjectVtab *vtab, const char *name ) - -* Class Membership: -* Object vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Object class. - -* Parameters: -* vtab -* Pointer to the virtual function table. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int ivtab; /* Index of next entry in known_vtabs */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Initialise the contents of the class identifier. Since this is the - base class, we assign null values to the fields. */ - vtab->id.check = NULL; - vtab->id.parent = NULL; - -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->Clear = Clear; - vtab->ClearAttrib = ClearAttrib; - vtab->ClearID = ClearID; - vtab->ClearIdent = ClearIdent; - vtab->Dump = Dump; - vtab->Equal = Equal; - vtab->GetAttrib = GetAttrib; - vtab->GetID = GetID; - vtab->GetIdent = GetIdent; - vtab->HasAttribute = HasAttribute; - vtab->Same = Same; - vtab->SetAttrib = SetAttrib; - vtab->SetID = SetID; - vtab->SetIdent = SetIdent; - vtab->Show = Show; - vtab->TestAttrib = TestAttrib; - vtab->TestID = TestID; - vtab->TestIdent = TestIdent; - vtab->EnvSet = EnvSet; - vtab->VSet = VSet; - vtab->Cast = Cast; - vtab->GetObjSize = GetObjSize; - vtab->CleanAttribs = CleanAttribs; - - vtab->TestUseDefs = TestUseDefs; - vtab->SetUseDefs = SetUseDefs; - vtab->ClearUseDefs = ClearUseDefs; - vtab->GetUseDefs = GetUseDefs; - -#if defined(THREAD_SAFE) - vtab->ManageLock = ManageLock; -#endif - -/* Store the pointer to the class name. */ - vtab->class = name; - -/* Initialise the count of active objects and the number of destructors, - copy constructors and dump functions. */ - vtab->nobject = 0; - vtab->ndelete = 0; - vtab->ncopy = 0; - vtab->ndump = 0; - -/* Initialise the arrays of destructor, copy constructor and dump - function pointers. */ - vtab->delete = NULL; - vtab->copy = NULL; - vtab->dump = NULL; - vtab->dump_class = NULL; - vtab->dump_comment = NULL; - -/* Initialise the default attributes to use when creating objects. */ - vtab->defaults = NULL; - -/* The virtual function table for each class contains a list of pointers - to memory blocks which have previously been used to store an Object of - the same class, but which have since been deleted using astDelete. - These memory blocks are free to be re-used when a new Object of the - same class is initialised. This saves on the overheads associated with - continuously allocating small blocks of memory using malloc. */ - vtab->nfree = 0; - vtab->free_list = NULL; - -/* Add the supplied virtual function table pointer to the end of the list - of known vtabs. */ - ivtab = nvtab++; - - astBeginPM; - known_vtabs = astGrow( known_vtabs, nvtab, sizeof( AstObjectVtab *) ); - astEndPM; - - if( astOK && known_vtabs ) known_vtabs[ ivtab ] = vtab; - -/* Fill a pointer value with zeros (not necessarily the same thing as a - NULL pointer) for subsequent use. */ - (void) memset( &zero_ptr, 0, sizeof( AstObject * ) ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised. */ - if( vtab == &class_vtab ) class_init = 1; -} - -AstObject *astInitObject_( void *mem, size_t size, int init, - AstObjectVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitObject - -* Purpose: -* Initialise an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* AstObject *astInitObject( void *mem, size_t size, int init, -* AstObjectVtab *vtab, const char *name ) - -* Class Membership: -* Object initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Object. It allocates memory (if necessary) to accommodate the -* Object plus any additional data associated with the derived class. It -* then initialises an Object structure at the start of this memory. If the -* "init" flag is set, it also initialises the contents of a virtual -* function table for an Object at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Object is to be initialised. -* This must be of sufficient size to accommodate the Object data -* (sizeof(Object)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Object (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Object -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Object's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Object. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). - -* Returned Value: -* A pointer to the new Object. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstObject *new; /* Pointer to new Object */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Determine if memory must be allocated dynamically. If so, use the last - block of memory in the list of previously allocated but currently - unused blocks identified by the vtab "free_list" array, reducing the - length of the free list by one, and nullifying the entry in the list - for safety. If the list is originally empty, allocate memory for a new - object using astMalloc. */ - if( !mem ) { - if( object_caching ) { - if( vtab->nfree > 0 ) { - mem = vtab->free_list[ --(vtab->nfree) ]; - vtab->free_list[ vtab->nfree ] = NULL; - if( astSizeOf( mem ) != size && astOK ) { - astError( AST__INTER, "astInitObject(%s): Free block has size " - "%d but the %s requires %d bytes (internal AST " - "programming error).", status, vtab->class, - (int) astSizeOf( mem ), vtab->class, (int) size ); - } - } else { - mem = astMalloc( size ); - } - - } else { - mem = astMalloc( size ); - } - -/* If memory had already been allocated, adjust the "size" value to match - the size of the allocated memory. */ - } else { - size = astSizeOf( mem ); - } - -/* Obtain a pointer to the new Object. */ - if ( astOK ) { - new = (AstObject *) mem; - -/* Zero the entire new Object structure (to prevent accidental re-use - of any of its values after deletion). */ - (void) memset( new, 0, size ); - -/* If necessary, initialise the virtual function table. */ -/* ---------------------------------------------------- */ - if ( init ) astInitObjectVtab( vtab, name ); - if( astOK ) { - -/* Initialise the Object data. */ -/* --------------------------- */ -/* Store a unique "magic" value in the Object structure. This will be - used (e.g. by astIsAObject) to determine if a pointer identifies a - valid Object. Note that this differs from the practice in derived - classes, where this number is stored in the virtual function - table. We take a different approach here so that we need not follow - a pointer to the virtual function table obtained from a structure - that hasn't yet been validated as an Object. This minimises the - risk of a memory access violation. */ - new->check = Magic( new, size, status ); - -/* Associate the Object with its virtual function table. */ - new->vtab = vtab; - -/* Store the Object size and note if its memory was dynamically allocated. */ - new->size = size; - new->dynamic = astIsDynamic( new ); - -/* Initialise the reference count (of Object pointers in use). */ - new->ref_count = 1; - -/* Initialise the ID strings. */ - new->id = NULL; - new->ident = NULL; - -/* Use default values for unspecified attributes. */ - new->usedefs = CHAR_MAX; - -/* Increment the count of active Objects in the virtual function table. - Use the count as a unique identifier (unique within the class) for - the Object. */ - new->iref = vtab->nobject++; - -/* Initialise the pointer to an external object that acts as a proxy for - the AST Object within foreign language interfaces. */ - new->proxy = NULL; - } - -/* If an error occurred, clean up by deleting the new Object. Otherwise - lock the object for use by the currently executing thread. */ - if ( !astOK ) { - new = astDelete( new ); - -#ifdef THREAD_SAFE - } else { - if( pthread_mutex_init( &(new->mutex1), NULL ) != 0 && astOK ) { - astError( AST__INTER, "astInitObject(%s): Failed to " - "initialise POSIX mutex1 for the new Object.", status, - vtab->class ); - } - if( pthread_mutex_init( &(new->mutex2), NULL ) != 0 && astOK ) { - astError( AST__INTER, "astInitObject(%s): Failed to " - "initialise POSIX mutex2 for the new Object.", status, - vtab->class ); - } - new->locker = -1; - new->globals = NULL; - (void) ManageLock( new, AST__LOCK, 0, NULL, status ); - if( !astOK ) new = astDelete( new ); -#endif - } - } - -/* Return a pointer to the new Object. */ - return new; -} - -AstObject *astLoadObject_( void *mem, size_t size, - AstObjectVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadObject - -* Purpose: -* Load an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* AstObject *astLoadObject( void *mem, size_t size, -* AstObjectVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* Object loader. - -* Description: -* This function is provided to load a new Object using data read -* from a Channel, and to allocate memory for it if necessary. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for an Object at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the Object is to be -* loaded. This must be of sufficient size to accommodate the -* Object data (sizeof(Object)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Object (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Object structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstObject) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Object. If this is NULL, a pointer to -* the (static) virtual function table for the Object class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new Object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Object" is used instead. - -* Returned Value: -* A pointer to the new Object. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - AstObject *new; /* Pointer to the new Object */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Object. In this case the - Object belongs to this class, so supply appropriate values for - initialising it and its virtual function table. */ - if ( !vtab ) { - size = sizeof( AstObject ); - vtab = &class_vtab; - name = "Object"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitObjectVtab( vtab, name ); - class_init = 1; - } - } - -/* There is no parent class to load, so simply initialise a new Object - structure as if a new Object were being created from scratch. */ - new = astInitObject( mem, size, 0, vtab, name ); - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Object" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - new->id = astReadString( channel, "id", NULL ); - new->ident = astReadString( channel, "ident", NULL ); - new->usedefs = astReadInt( channel, "usedfs", CHAR_MAX ); - -/* We simply read the values for the read-only attributes (just in - case they've been un-commented in the external representation) and - discard them. This prevents any possibility of error due to un-read - input. */ - (void) astReadInt( channel, "refcnt", 0 ); - (void) astReadInt( channel, "nobj", 0 ); - -/* Initialise the pointer to an external object that acts as a proxy for - the AST Object within foreign language interfaces. */ - new->proxy = NULL; - -/* If an error occurred, clean up by deleting the new Object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Object pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -void astClear_( AstObject *this, const char *attrib, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Object,Clear))( this, attrib, status ); -} -void astClearAttrib_( AstObject *this, const char *attrib, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Object,ClearAttrib))( this, attrib, status ); -} -void astDump_( AstObject *this, AstChannel *channel, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Object,Dump))( this, channel, status ); -} - -#if defined(THREAD_SAFE) -int astManageLock_( AstObject *this, int mode, int extra, AstObject **fail, - int *status ) { - if( !this ) return 0; - return (**astMEMBER(this,Object,ManageLock))( this, mode, extra, fail, status ); -} -#endif - -int astEqual_( AstObject *this, AstObject *that, int *status ) { - if ( !astOK ) return 0; - if( this == that ) return 1; - return (**astMEMBER(this,Object,Equal))( this, that, status ); -} -const char *astGetAttrib_( AstObject *this, const char *attrib, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Object,GetAttrib))( this, attrib, status ); -} -void astSetAttrib_( AstObject *this, const char *setting, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Object,SetAttrib))( this, setting, status ); -} -void astShow_( AstObject *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Object,Show))( this, status ); -} -int astTestAttrib_( AstObject *this, const char *attrib, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Object,TestAttrib))( this, attrib, status ); -} -void astEnvSet_( AstObject *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Object,EnvSet))( this, status ); -} -void astVSet_( AstObject *this, const char *settings, char **text, va_list args, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Object,VSet))( this, settings, text, args, status ); -} -int astGetObjSize_( AstObject *this, int *status ) { - if ( !astOK || !this ) return 0; - return (**astMEMBER(this,Object,GetObjSize))( this, status ); -} -void astCleanAttribs_( AstObject *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Object,CleanAttribs))( this, status ); -} -AstObject *astCast_( AstObject *this, AstObject *obj, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Object,Cast))( this, obj, status ); -} -int astSame_( AstObject *this, AstObject *that, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Object,Same))( this, that, status ); -} -int astHasAttribute_( AstObject *this, const char *attrib, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Object,HasAttribute))( this, attrib, status ); -} - -/* External interface. */ -/* =================== */ -/* The following relates to the external interface to Objects and not - specifically to the implementation of the Object class itself - (although it contains external functions which replace the internal - versions defined earlier). */ - - -/* Type Definitions. */ -/* ----------------- */ -/* Define the Handle structure. This is attached to Objects when they - are accessed via the public (external, user-callable) interface. - Handles provide a buffer between the Object identifiers issued to - external users and the naked C pointers used to handle Objects - internally. They also implement the context levels used by - astBegin, astEnd, astExempt and astExport (which are only available - to external users). */ -typedef struct Handle { - AstObject *ptr; /* C Pointer to the associated Object */ - int context; /* Context level for this Object */ - int check; /* Check value to ensure validity */ - -#if defined(THREAD_SAFE) - int thread; /* Identifier for owning thread */ -#endif - -#if defined(MEM_DEBUG) - int id; /* The id associated with the memory block - holding the Object last associated with - this handle. */ - AstObjectVtab *vtab; /* Pointer to the firtual function table of - the Object last associated with this - handle. */ -#endif - -/* Links between Handles are implemented using integer offsets rather - than through pointers. */ - int flink; /* Backward link to previous Handle */ - int blink; /* Forward link to next Handle */ - -/* Information that records where the Handle was created. */ - const char *routine; /* Routine name */ - const char *file; /* File name */ - int line; /* Line number */ - -} Handle; - -/* Define a union with an overlapping int and AstObject*. This is used - to transfer an integer bit pattern into and out of a pointer - variable used to store an Object identifier. This avoids any - implementation dependent aspects of integer-to-pointer - conversions. */ -typedef union IdUnion { - AstObject *pointer; - int integer; -} IdUnion; - -/* Define a union which allows a bit pattern to be accessed as a - signed or unsigned int. */ -typedef union MixedInts { - int i; - unsigned u; -} MixedInts; - -/* Static Variables. */ -/* ----------------- */ -/* The array of Handle structures is a pool of resources available to all - threads. Each thread has its own conext level and its own "active_handles" - array to identify the first Handle at each context level. */ -static Handle *handles = NULL; /* Pointer to allocated array of Handles */ -static int free_handles = -1; /* Offset to head of free Handle list */ -static int nhandles = 0; /* Number of Handles in "handles" array */ -static unsigned nids = 0; /* Number of IDs issued to external users */ - -#if defined(THREAD_SAFE) -static int unowned_handles = -1; /* Offset to head of unowned Handle - list. In a single threaded environment, - all handles must be owned by a thread. */ -#endif - -#ifdef MEM_DEBUG -static int Watched_Handle = -1; /* A handle index to be watched. Activity - on this handle is reported using - astHandleUse and astHandleAlarm. */ -#endif - - -/* External Interface Function Prototypes. */ -/* --------------------------------------- */ -/* MYSTATIC should normally be set to "static" to make the following - function have local symbols. But it may be set to blank for debugging - purposes in order to enable these functions to appear in a backtrace - such as produced by the astBacktrace function. */ -#define MYSTATIC - -/* Private functions associated with the external interface. */ -MYSTATIC AstObject *AssocId( int, int * ); -MYSTATIC int CheckId( AstObject *, int, int * ); -MYSTATIC void AnnulHandle( int, int * ); -MYSTATIC void InitContext( int * ); -MYSTATIC void InsertHandle( int, int *, int * ); -MYSTATIC void RemoveHandle( int, int *, int * ); - -#if defined(MEM_DEBUG) -MYSTATIC void CheckList( int *, int * ); -MYSTATIC void CheckInList( int, int *, int, int * ); -MYSTATIC int CheckThread( int, int *, int * ); -MYSTATIC const char *HandleString( int, char * ); -MYSTATIC const char *HeadString( int *, char * ); -#endif - - -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstObject *astDeleteId_( AstObject *, int * ); -void astBegin_( void ); -void astEnd_( int * ); -void astExemptId_( AstObject *, int * ); -void astImportId_( AstObject *, int * ); -void astSetId_( void *, const char *, ... ); -void astLockId_( AstObject *, int, int * ); -void astUnlockId_( AstObject *, int, int * ); - - -/* External Interface Functions. */ -/* ----------------------------- */ -AstKeyMap *astActiveObjects_( const char *class, int subclass, int current, - int *status ) { -/* -c++ -* Name: -* astActiveObjects - -* Purpose: -* Return pointers for all active Objects. - -* Type: -* Public function. - -* Synopsis: -* #include "object.h" -* AstKeyMap *astActiveObjects( const char *class, int subclass, -* int current ) - -* Class Membership: -* Object method. - -* Description: -* This function returns a KeyMap holding currently active AST Object -* pointers. Each entry in the KeyMap will have a key that is an AST -* class name such as "FrameSet", "SkyFrame", "ZoomMap", etc. The -* value of the entry will be a 1-dimensional list of pointers for -* objects of the same class. Note, the returned pointers should NOT -* be annulled when they are no longer needed. -* -* The pointers to return in the KeyMap may be restricted either by -* class or by context level using the function arguments. - -* Parameters: -* class -* If NULL, then the returned KeyMap will contain pointers ofr -* Objects of all classes. If not NULL, then "class" should be a -* pointer to a null-terminated string holding the name of an AST -* class. The returned KeyMap will contain pointers only for the -* specified class. See also "subclass". -* subclass -* A Boolean flag indicating if all subclasses of the class -* specified by "class" should be included in the returned KeyMap. -* If zero, then subclass objects are not returned. Otherwise they -* are returned. The supplied "subclass" value is ignored if -* "class" is NULL. -* current -* A Boolean flag indicating if the returned list of pointers -* should be restricted to pointers issued within the current AST -* object context (see astBegin and astEnd). - -* Returned Value: -* astActiveObjects() -* A pointer to a new KeyMap holding the required object pointers. -* They KeyMap pointer should be annulled when it is no longer -* needed, but the object pointers within the KeyMap should not be -* annulled. A NULL pointer is returned if an error has occurred -* prior to calling this function. -* -* The values stored in the KeyMap should be accessed as generic C -* pointers using the KeyMap "P" data type (e.g. using function -* astMapGetlemP etc). - -* Notes: -* - This function will only return objects locked by the currently -* executing thread. -* - The KeyMap pointer returned by this function is not included in the -* list of active objects stored in the KeyMap. -* - Objects that were created using the Fortran interface will have a -* null "file" value and will have a routine name equal to the upper case -* Fortran routine that issued the pointer (e.g. "AST_CLONE", "AST_FRAME", -* etc). - -c-- -*/ - -/* Local Variables: */ - AstKeyMap *result; /* Returned KeyMap */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int i; /* Loop count */ - int ihandle; /* Offset of Handle to be annulled */ - AstObjectVtab *req_vtab; /* Vtab for requested class */ - Handle *handle; /* Pointer to current Handle */ - int generation_gap; /* Hereditary relationshp between two classes */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Create an empty KeyMap to hold the results. */ - result = astKeyMap( " ", status ); - -/* If we will need to check if each object is a subclass of a specified - class, we need a pointer to the VTAB descriibing the specified class. */ - req_vtab = NULL; - if( class && subclass ) { - -/* Loop round the vtab structures created by the currently executing thread. */ - for( i = 0; i < nvtab; i++ ) { - -/* If the current vtab is for a class that matches the requested class, - store a pointer to the vtab. */ - if( !strcmp( class, known_vtabs[ i ]->class ) ) { - req_vtab = known_vtabs[ i ]; - break; - } - } - } - -/* Get exclusive access to the handles array. */ - LOCK_MUTEX2; - -/* Get the index of the first Handle to check. If we are checking only the - current context level, then get this index from the appropriate element - of the active_handles array. Otherwise, we check the whole of the - handles array, starting at element zero. */ - if( current && active_handles ) { - ihandle = active_handles[ context_level ]; - } else { - ihandle = 0; - } - -/* Loop over the Handles array, starting from the above element. */ - handle = handles + ihandle; - for( ; ihandle < nhandles; ihandle++,handle++ ) { - -/* Skip Handles that have no associated object. */ - if( !handle->ptr ) continue; - -/* Skip handles that are in an unrequired context. */ - if( current && handle->context != context_level ) continue; - -#if defined(THREAD_SAFE) -/* Skip handles that are not locked for use by the current thread. */ - if( handle->thread != AST__THREAD_ID ) continue; -#endif - -/* If required, check that the current handle is for an object of the - specified class. */ - if( class ) { - -/* Skip the handle if no VTAB was found for the requested class. */ - if( !req_vtab ) continue; - -/* Get the generation gap between the current handle's object and the - specified class. */ - generation_gap = astClassCompare( astVTAB( handle->ptr ), req_vtab ); - -/* Skip the handle if it is not for the specified class or a subclass. */ - if( generation_gap < 0 || generation_gap == AST__COUSIN || - ( generation_gap > 0 && !subclass ) ) continue; - } - -/* Get the integer identifier associated with the handle, convert it to a - pointer and append to the end of the KeyMap entry describing the handle's - class. */ - astMapPutElemP( result, astGetClass( handle->ptr ), -1, - astI2P( handle->check ) ); - } - -/* Relinquish access to the handles array. */ - UNLOCK_MUTEX2; - -/* Return the KeyMap. */ - return result; -} - -MYSTATIC void AnnulHandle( int ihandle, int *status ) { -/* -* Name: -* AnnulHandle - -* Purpose: -* Annul a Handle and its associated Object pointer. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* void AnnulHandle( int ihandle, int *status ) - -* Class Membership: -* Object member function. - -* Description: -* This function annuls an active Handle by annulling the Object -* pointer it is associated with, deactivating the Handle and -* returning it to the free Handle list for re-use. -* -* The reference count for the associated Object is decremented by -* this function and the Object will be deleted if this reference -* count falls to zero. - -* Parameters: -* ihandle -* Array offset that identifies the Handle to be annulled in the -* "handles" array. This is fully validated by this function. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The Handle supplied should be active, otherwise an error will -* result and the Handle will not be touched (but no error report -* will be made if the global error status has already been set). -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - AstObject *ptr; /* Object pointer */ - int context; /* Context level where Handle was issued */ - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Check that the handle offset supplied is valid and report an error - if it is not (but only if the global error status has not already - been set). */ - if ( ( ihandle < 0 ) || ( ihandle >= nhandles ) ) { - if ( astOK ) { - astError( AST__INHAN, "astAnnulHandle: Invalid attempt to annul an " - "Object Handle (no. %u).", status, ihandle ); - astError( AST__INHAN, "This Handle number is not valid (possible " - "internal programming error)." , status); - } - -/* If OK, obtain the Handle's context level. */ - } else { - context = handles[ ihandle ].context; - -/* If this indicates that the Handle isn't active, then report an - error (but only if the global error status has not already been - set). We allow handles that are currently not owned by any thread to - be annulled. */ - if ( context < 0 && context != UNOWNED_CONTEXT ) { - if ( astOK ) { - astError( AST__INHAN, "astAnnulHandle: Invalid attempt to annul " - "an Object Handle (no. %u).", status, ihandle ); - astError( AST__INHAN, "This Handle is not active (possible " - "internal programming error)." , status); - } - -/* If the Handle is active, annul its Object pointer. The astAnnul - function may call Delete functions supplied by any class, and these - Delete functions may involve annulling external Object IDs, which in - turn requires access to the handles array. For this reason, we release - the mutex that protects access to the handles arrays so that it can - potentially be re-aquired within astAnnul without causing deadlock. */ - } else { - -#ifdef MEM_DEBUG - astHandleUse( ihandle, "annulled using check value %d ", - handles[ ihandle ].check ); -#endif - - ptr = handles[ ihandle ].ptr; - UNLOCK_MUTEX2; - ptr = astAnnul( ptr ); - LOCK_MUTEX2; - -/* Remove the Handle from the active list for its context level. */ - if( context == UNOWNED_CONTEXT ) { - -#if defined(THREAD_SAFE) - RemoveHandle( ihandle, &unowned_handles, status ); -#else - if( astOK ) astError( AST__INTER, "AnnulHandle: reference to " - "'unowned_handles' in a non-thread-safe context " - "(internal AST programming error).", status ); -#endif - - } else if( active_handles ) { - RemoveHandle( ihandle, &active_handles[ context ], status ); - - } else if( astOK ){ - astError( AST__INTER, "AnnulHandle: active_handles array has " - "not been initialised (internal AST programming error).", - status ); - } - -/* Reset the Handle's "context" value (making it inactive) and its "check" - value (so it is no longer associated with an identifier value). */ - handles[ ihandle ].ptr = NULL; - handles[ ihandle ].context = INVALID_CONTEXT; - handles[ ihandle ].check = 0; -#if defined(THREAD_SAFE) - handles[ ihandle ].thread = -1; -#endif - -/* Place the modified Handle on the free Handles list ready for re-use. */ - InsertHandle( ihandle, &free_handles, status ); - - } - } -} - -AstObject *astAnnulId_( AstObject *this_id, int *status ) { -/* -*+ -* Name: -* AnnulId - -* Purpose: -* Annul an external Object identifier. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* AstObject *astAnnulId( AstObject *this ) - -* Class Membership: -* Object member function. - -* Description: -* This function implements the external (public) interface to the -* astAnnul method. It accepts an active Object identifier, which -* it annuls, causing the associated Handle to be deactivated and -* returned to the free Handles list for re-use. It also causes the -* reference count of the associated Object to be decremented and -* the Object to be deleted if this reference count falls to zero. - -* Parameters: -* this -* The Object identifier to be annulled. - -* Returned Value: -* A NULL C pointer is always returned (this should be translated -* into an identifier value of zero for external use). - -* Notes: -* - This function attempts to execute even if the global error -* status is set. -* - The identifier supplied should be associated with an active -* Object, otherwise an error will result (but no error report will -* be made if the global error status has already been set). -* - This function is invoked via the astAnnul macro for external use. -* For internal use (from protected code which needs to handle external -* IDs) it should be invoked via the astAnnulId macro (since astAnnul -* expects a true C pointer as its argument when used internally). -*- -*/ - -/* Obtain the Object pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Object (this generates an - error if it doesn't). Note, we use "astMakePointer_NoLockCheck", - rather than the usual "astMakePointer" since a thread should be able - to renounce interest in an object without needing to own the object. - If we used "astMakePointer" then a thread could not annul a pointer - unless it owned the object. But having annulled the pointer it could - then not unlock the object for use by another thread (since the - pointer it would need to do this has just been annulled). */ - if ( !astIsAObject( astMakePointer_NoLockCheck( this_id ) ) ) return NULL; - -/* Obtain the Handle offset for this Object and annul the Handle and - its associated Object pointer. Report an error if the handle is - currently owned by a different thread. That is, the *Object* need - not be locked by the current thread (as indicated by the use of - astMakePointer above), but the *handle* must be owned by the current - thread. */ - LOCK_MUTEX2; - AnnulHandle( CheckId( this_id, 1, status ), status ); - UNLOCK_MUTEX2; - -/* Always return a NULL pointer value. */ - return NULL; -} - -MYSTATIC AstObject *AssocId( int ihandle, int *status ) { -/* -* Name: -* AssocId - -* Purpose: -* Associate an identifier value with a Handle. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *AssocId( int ihandle ) - -* Class Membership: -* Object member function. - -* Description: -* This function takes a zero-based offset into the "handles" array -* that identifies a Handle associated with an active Object. It -* encodes this into an identifier value to be issued to an -* external user to identify that Handle and its Object, and then -* associates this identifier value with the Handle. - -* Parameters: -* ihandle -* Offset in the "handles" array that identifies the Handle, -* which should be active (i.e. associated with an active -* Object). This function will modify the "check" field in this -* Handle to associate it with the identifier value it returns. - -* Returned Value: -* The resulting identifier value. - -* Notes: -* - The returned identifier value is, in fact, an int. This -* allows the value to be passed easily to other languages -* (e.g. Fortran) and stored as an integer without loss of -* information. -* - The value is stored within C code as type AstObject*. This -* means that C code (e.g. function prototypes, etc.) need not be -* aware that an identifier (as opposed to an Object pointer) is -* being used, even though the actual bit patterns will be -* different. The same C code can then be used for both internal -* and external purposes so long as care is taken to convert -* between the two representations at appropriate points. -* - The reverse operation (conversion of an ID back to a handle -* offset) is performed by CheckId. -* - A zero identifier value will be returned if this function is -* invoked with the global status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstObject *result; /* Pointer value to return */ - MixedInts test; /* Union for testing encoding */ - MixedInts work; /* Union for encoding ID value */ - -/* Initialise. */ - result = astI2P( 0 ); - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Copy the Handle offset and clear the lowest 8 bits by shifting - left. */ - work.i = ihandle; - work.u = work.u << 8U; - -/* Make a copy of the result shifted right again. Test if any bits - have been lost in this process. If so, there are too many Handles - in use at once to encode them into IDs, so report an error. */ - test.u = work.u >> 8U; - if ( test.i != ihandle ) { - astError( AST__XSOBJ, "AssocId(%s): There are too many AST Objects in " - "use at once.", status, astGetClass( handles[ ihandle ].ptr ) ); - -/* If OK, scramble the value by exclusive-ORing with the bit pattern - in AST__FAC (a value unique to this library), also shifted left by - 8 bits. This makes it even less likely that numbers from other - sources will be accepted in error as valid IDs. */ - } else { - work.u ^= ( ( (unsigned) AST__FAC ) << 8U ); - -/* Fill the lowest 8 bits with a count of the total number of IDs - issued so far (which we increment here). This makes each ID unique, - so that an old one that identifies a Handle that has been annulled - and re-used (i.e. associated with a new ID) can be spotted. We - only use the lowest 8 bits of this count because this provides - adequate error detection to reveal programming errors and we do not - need higher security than this. We also prevent a count of zero - being used, as this could result in a zero identifier value (this - being reserved as the "null" value). */ - if ( ++nids > 255U ) nids = 1U; - work.u |= nids; - -/* Store the value as a check count in the Handle. This will be used - to validate the ID in future. */ - handles[ ihandle ].check = work.i; - -/* Pack the value into the pointer to be returned. */ - result = astI2P( work.i ); - } - -/* Return the result. */ - return result; -} - -void astBegin_( void ) { -/* -*++ -* Name: -c astBegin -f AST_BEGIN - -* Purpose: -* Begin a new AST context. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c void astBegin -f CALL AST_BEGIN( STATUS ) - -* Class Membership: -* Object class function. - -* Description: -c This macro invokes a function to begin a new AST context. -c Any Object pointers -f This routine begins a new AST context. Any Object pointers -* created within this context will be annulled when it is later -c ended using astEnd (just as if astAnnul had been invoked), -f ended using AST_END (just as if AST_ANNUL had been invoked), -c unless they have first been exported using astExport or rendered -c exempt using astExempt. If -f unless they have first been exported using AST_EXPORT or rendered -f exempt using AST_EXEMPT. If -* annulling a pointer causes an Object's RefCount attribute to -* fall to zero (which happens when the last pointer to it is -* annulled), then the Object will be deleted. - -f Parameters: -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Object -c This macro applies to all Objects. -f This routine applies to all Objects. - -* Notes: -c - astBegin attempts to execute even if the AST error status -c is set on entry. -f - This routine attempts to execute even if STATUS is set to an -f error value. -c - Contexts delimited by astBegin and astEnd may be nested to any -c depth. -f - Contexts delimited by AST_BEGIN and AST_END may be nested to any -f depth. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int stat; /* Copy of global status */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Now that the thread-specific data has been initialised, we can get a - pointer to the threads inherited status value. */ - status = astGetStatusPtr; - -/* Save and clear the global status so that memory allocation can be - performed within this function even under error conditions. */ - stat = astStatus; - astClearStatus; - -/* Ensure that the active_handles array has been initialised. */ - if ( !active_handles ) InitContext( status ); - -/* Extend the "active handles" array to accommodate a new context - level. This array contains integer offsets into the "handles" array - to identify the handle which is at the head of the list of active - handles for each context level. */ - astBeginPM; - active_handles = astGrow( active_handles, context_level + 2, - sizeof( int ) ); - astEndPM; - -/* Initialise the array element for the new context level to indicate - an empty Handle list. */ - if ( astOK ) active_handles[ ++context_level ] = -1; - -/* Restore the original global status value. */ - astSetStatus( stat ); -} - -MYSTATIC int CheckId( AstObject *this_id, int lock_check, int *status ) { -/* -* Name: -* CheckId - -* Purpose: -* Check an identifier value and convert it into a Handle offset. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* int CheckId( AstObject *this, int lock_check, int *status ) - -* Class Membership: -* Object member function. - -* Description: -* This function takes an identifier value encoded by AssocId and -* validates it to ensure it is associated with an active -* Handle. If valid, it converts it back into a zero-based offset -* which may be used to access the Handle in the "handles" -* array. Otherwise, an error is reported. - -* Parameters: -* this -* The identifier value to be decoded. -* lock_check -* Should an error be reported if the handle is in an Object -* context for a different thread? -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The resulting Handle offset, or -1 if the identifier is not -* valid or any other error occurs. - -* Notes: -* - This function attempts to execute even if the global error -* status is set, but no further error report will be made if it -* fails under these circumstances. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - MixedInts work; /* Union for decoding ID value */ - int id; /* ID value as an int */ - int ihandle; /* Result to return */ - -#ifdef MEM_DEBUG - int oldok = astOK; -#endif - -/* Initialise. */ - ihandle = -1; - -/* Get a pointer to thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Retrieve the integer Object identifier value from the pointer - supplied. */ - id = astP2I( this_id ); - -/* Check if a value of zero has been supplied and report an error if - it has. */ - if ( !id ) { - if ( astOK ) { - astError( AST__OBJIN, "Invalid Object pointer given (value is " - "zero)." , status); - } - -/* If OK, reverse the encoding process performed by AssocId to - retrieve the Handle offset. */ - } else { - work.i = id; - work.u = ( work.u ^ ( ( (unsigned) AST__FAC ) << 8U ) ) >> 8U; - -/* Check that the offset obtained doesn't extend beyond the limits of - the "handles" array. Report an error if it does. */ - if ( ( work.i < 0 ) || ( work.i >= nhandles ) ) { - if ( astOK ) { - astError( AST__OBJIN, "Invalid Object pointer given (value is " - "%d).", status, id ); - } - -/* See if the "check" field matches the ID value and the Handle is - valid (i.e. is associated with an active Object). If not, the - Handle has been annulled and possibly re-used, so report an - error. */ - } else if ( ( handles[ work.i ].check != id ) || - ( handles[ work.i ].context == INVALID_CONTEXT ) ) { - if ( astOK ) { - astError( AST__OBJIN, "Invalid Object pointer given (value is " - "%d).", status, id ); - astError( AST__OBJIN, "This pointer has been annulled, or the " - "associated Object deleted." , status); - } -#if defined(THREAD_SAFE) - } else if( lock_check && handles[ work.i ].context != UNOWNED_CONTEXT && - handles[ work.i ].thread != AST__THREAD_ID ) { - if ( astOK ) { - astError( AST__OBJIN, "Invalid Object pointer given (value is " - "%d).", status, id ); - astError( AST__OBJIN, "This pointer is currently owned by " - "another thread (possible programming error)." , status); - } -#endif - -/* If OK, set the Handle offset to be returned. */ - } else { - ihandle = work.i; - } - -#ifdef MEM_DEBUG - if ( oldok && !astOK && ( work.i >= 0 ) && ( work.i < nhandles ) ) { - char buf[200]; - astError( astStatus, "Handle properties: %s ", status, - HandleString( work.i, buf ) ); - } -#endif - - } - -/* Return the result. */ - return ihandle; -} - -void astCreatedAtId_( AstObject *this_id, const char **routine, - const char **file, int *line, int *status ){ -/* -c++ -* Name: -* astCreatedAt - -* Purpose: -* Return the routine, file and line number at which an Object was -* created. - -* Type: -* Public function. - -* Synopsis: -* #include "object.h" -* void astCreatedAt( AstObject *this, const char **routine, -* const char **file, int *line ) - -* Class Membership: -* Object method. - -* Description: -* This function returns pointers to two strings containing the -* name of the routine or function within which the object was created -* and the name of the source file containing that routine. It also -* returns the number of the line within the file at which the object -* was created. It is intended for use in debugging memory leaks etc. -* -* Precisely, the information returned identifies the point at which -* the Object's public identifier (i.e. the supplied pointer) was -* first issued. This may not correspond to the actual creation of the -* Object if the object is contained within some higher level Object. -* For instance, if the astGetFrame method is used to get a pointer to -* a Frame within a FrameSet, the information returned by this -* function if supplied with the Frame pointer would identify the call -* to astGetFrame, rather than the line at which the FrameSet created -* its internal copy of the Frame. Likewise, if this function is used -* to get information from an Object pointer returned by astClone, the -* information will describe the call to astClone, not the call that -* created the original Object. - -* Parameters: -* this -* Pointer to the Object. -* routine -* Address of a pointer to a null terminated C string in which to -* return the routine name (the string will reside in static memory). -* The pointer will be set to NULL on exit if no routine name is -* available. -* file -* Address of a pointer to a null terminated C string in which to -* return the file name (the string will reside in static memory). -* The pointer will be set to NULL on exit if no file name is -* available. -* line -* Address of an int in which to store the line number in the file. -* A line number of zero is returned if no line number is available. - -* Notes: -* - NULL pointers and a line number of zero are returned if an error -* has already occurred prior to calling this function. - -c-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int ihandle; /* Result to return */ - -/* Initialise */ - *routine = NULL; - *file = NULL; - *line = 0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Gain exclusive access to the handles array. */ - LOCK_MUTEX2; - -/* Obtain the Handle offset for this Object. */ - ihandle = CheckId( this_id, 1, status ); - if ( ihandle != -1 ) { - -/* Copy the required pointers etc to the supplied addresses. */ - *routine = handles[ ihandle ].routine; - *file = handles[ ihandle ].file; - *line = handles[ ihandle ].line; - } - -/* Unlock the mutex that guards access to the handles array */ - UNLOCK_MUTEX2; - -} - -AstObject *astDeleteId_( AstObject *this_id, int *status ) { -/* -*+ -* Name: -* astDeleteId - -* Purpose: -* Delete an Object via an identifier. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* AstObject *astDeleteId_( AstObject *this ) - -* Class Membership: -* Object member function. - -* Description: -* This function implements the external (public) interface to the -* astDelete method. It accepts an active Object identifier and -* deletes the associated Object. Before doing so, it annuls all -* active identifiers associated with the object, deactivates their -* Handles and returns these Handles to the free Handles list for -* re-use. - -* Parameters: -* this -* An identifier for the Object to be deleted. - -* Returned Value: -* A NULL C pointer is always returned (this should be translated -* into an identifier value of zero for external use). - -* Notes: -* - This function attempts to execute even if the global error -* status is set. -* - The identifier supplied should be associated with an active -* Object, otherwise an error will result (but no error report will -* be made if the global error status has already been set). -* - Although this function is documented as "private" and should -* not be invoked directly from outside this class, it is not a -* static function and has a public prototype. This is because it -* must be invoked via the astDelete macro (defined in the -* "object.h" include file) as part of the public interface. -*- -*/ - -/* Local Variables: */ - AstObject *this; /* Pointer to Object */ - int i; /* Loop counter for Handles */ - int ihandle; /* Object Handle offset */ - -/* Obtain the Object pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Object (this generates an - error if it doesn't). */ - if ( !astIsAObject( this = astMakePointer( this_id ) ) ) return NULL; - -/* Gain exclusive access to the handles array. */ - LOCK_MUTEX2; - -/* Obtain the Handle offset for this Object. */ - ihandle = CheckId( this_id, 1, status ); - if ( ihandle != -1 ) { - -/* Since the Object is to be deleted, we must annul all identifiers - that refer to it. Loop to inspect each currently allocated Handle - in the "handles" array. */ - for ( i = 0; i < nhandles; i++ ) { - -/* Select active handles and test if their Object pointer refers to - the Object to be deleted. */ - if ( ( handles[ i ].context != INVALID_CONTEXT ) && - ( handles[ i ].ptr == this ) ) { - -/* If so, explicitly set the reference count for the Object to 2 so - that it will not be deleted (yet) when we annul the pointer - associated with the Handle. */ - handles[ i ].ptr->ref_count = 2; - -/* Annul the Handle, which frees its resources, decrements the Object - reference count and makes any ID associated with the Handle become - invalid. */ - AnnulHandle( i, status ); - } - } - -/* If required, tell the user that the handle's object has been deleted. */ -#ifdef MEM_DEBUG - astHandleUse( ihandle, "object-deleted" ); -#endif - } - - UNLOCK_MUTEX2; - -/* When all Handles associated with the Object have been annulled, - delete the object itself. This over-rides the reference count and - causes any remaining pointers to the Object (e.g. in internal code - or within other Objects) to become invalid. */ - this = astDelete( this ); - -/* Always return a NULL pointer value. */ - return NULL; -} - -void astEnd_( int *status ) { -/* -*++ -* Name: -c astEnd -f AST_END - -* Purpose: -* End an AST context. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c void astEnd -f CALL AST_END( STATUS ) - -* Class Membership: -* Object class function. - -* Description: -c This macro invokes a function to end an AST context which was -f This routine ends an AST context which was -c begun with a matching invocation of astBegin. Any Object -f begun with a matching invocation of AST_BEGIN. Any Object -* pointers created within this context will be annulled (just as -c if astAnnul had been invoked) and will cease to be valid -f if AST_ANNUL had been invoked) and will cease to be valid -* afterwards, unless they have previously been exported using -c astExport or rendered exempt using astExempt. -f AST_EXPORT or rendered exempt using AST_EXEMPT. -* If annulling a pointer causes an Object's RefCount attribute to -* fall to zero (which happens when the last pointer to it is -* annulled), then the Object will be deleted. - -* Parameters: -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Object -c This macro applies to all Objects. -f This routine applies to all Objects. - -* Notes: -c - astEnd attempts to execute even if the AST error status is set. -f - This routine attempts to execute even if STATUS is set to an -f error value. -c - Contexts delimited by astBegin and astEnd may be nested to any -c depth. -f - Contexts delimited by AST_BEGIN and AST_END may be nested to any -f depth. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int ihandle; /* Offset of Handle to be annulled */ - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Check that the current context level is at least 1, otherwise there - has been no matching use of astBegin, so report an error (unless - the global status has already been set). */ - if ( context_level < 1 ) { - if ( astOK ) { - astError( AST__ENDIN, "astEnd: Invalid use of astEnd without a " - "matching astBegin." , status); - } - -/* If OK, loop while there are still active Handles associated with - the current context level. First gain exclusive access to the handles - array. */ - } else if ( active_handles ) { - LOCK_MUTEX2; - while ( ( ihandle = active_handles[ context_level ] ) != -1 ) { - -/* Annul the Handle at the head of the active Handles list. */ - AnnulHandle( ihandle, status ); - -/* It is just posible that under error conditions inactive Handles - might get left in the active_handles list and AnnulHandle would - then fail. Since this would result in an infinite loop, we check to - see if the handle we have just annulled is still in the list. If - so, transfer it to the free Handles list for re-use. */ - if ( ihandle == active_handles[ context_level ] ) { - RemoveHandle( ihandle, &active_handles[ context_level ], status ); - InsertHandle( ihandle, &free_handles, status ); - } - } - -/* Ensure the context level is decremented unless it was zero to start - with. */ - context_level--; - -/* Relinquish access to the handles array. */ - UNLOCK_MUTEX2; - } - -} - -void astExemptId_( AstObject *this_id, int *status ) { -/* -*++ -* Name: -c astExempt -f AST_EXEMPT - -* Purpose: -* Exempt an Object pointer from AST context handling. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c void astExempt( AstObject *this ) -f CALL AST_EXEMPT( THIS, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function exempts an Object pointer from AST context -f This routine exempts an Object pointer from AST context -c handling, as implemented by astBegin and astEnd. This means that -f handling, as implemented by AST_BEGIN and AST_END. This means that -c the pointer will not be affected when astEnd is invoked and will -f the pointer will not be affected when AST_END is called and will -* remain active until the end of the program, or until explicitly -c annulled using astAnnul. -f annulled using AST_ANNUL. -* -c If possible, you should avoid using this function when writing -f If possible, you should avoid using this routine when writing -* applications. It is provided mainly for developers of other -* libraries, who may wish to retain references to AST Objects in -* internal data structures, and who therefore need to avoid the -c effects of astBegin and astEnd. -f effects of AST_BEGIN and AST_END. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Object pointer to be exempted from context handling. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. -*-- - -* Implementation Notes: -* - This function does not exist in the "protected" interface to -* the Object class and is not available to other class -* implementations. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int context; /* Handle context level */ - int ihandle; /* Offset of Handle in "handles" array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Obtain the Object pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Object. */ - (void) astCheckObject( astMakePointer( this_id ) ); - if ( astOK ) { - -/* Gain exclusive access to the handles array. */ - LOCK_MUTEX2; - -/* Obtain the Handle offset for this Object. */ - ihandle = CheckId( this_id, 1, status ); - if ( ihandle != -1 ) { - -/* Extract the context level at which the Object was created. */ - context = handles[ ihandle ].context; - -/* Set the new context level to zero, where it cannot be affected by - ending any context. */ - handles[ ihandle ].context = 0; - -/* Remove the object's Handle from its original active Handles list - and insert it into the list appropriate to its new context - level. */ - -#if defined(THREAD_SAFE) - if( context == UNOWNED_CONTEXT ) { - RemoveHandle( ihandle, &unowned_handles, status ); - } else { - RemoveHandle( ihandle, &active_handles[ context ], status ); - } -#else - RemoveHandle( ihandle, &active_handles[ context ], status ); -#endif - - InsertHandle( ihandle, &active_handles[ 0 ], status ); - -/* If required, tell the user that the handle has been exempted. */ -#ifdef MEM_DEBUG - astHandleUse( ihandle, "exempted" ); -#endif - } - - UNLOCK_MUTEX2; - } -} - -void astExportId_( AstObject *this_id, int *status ) { -/* -*++ -* Name: -c astExport -f AST_EXPORT - -* Purpose: -* Export an Object pointer to an outer context. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c void astExport( AstObject *this ) -f CALL AST_EXPORT( THIS, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function exports an Object pointer from the current AST context -f This routine exports an Object pointer from the current AST context -* into the context that encloses the current one. This means that -* the pointer will no longer be annulled when the current context -c is ended (with astEnd), but only when the next outer context (if -f is ended (with AST_END), but only when the next outer context (if -* any) ends. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Object pointer to be exported. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. - -* Notes: -c - It is only sensible to apply this function to pointers that -f - It is only sensible to apply this routine to pointers that -* have been created within (or exported to) the current context -c and have not been rendered exempt using astExempt. -f and have not been rendered exempt using AST_EXEMPT. -* Applying it to an unsuitable Object pointer has no effect. -*-- - -* Implementation Notes: -* - This function does not exist in the "protected" interface to -* the Object class and is not available to other class -* implementations. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int context; /* Handle context level */ - int ihandle; /* Offset of Handle in "handles" array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Obtain the Object pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Object. */ - (void) astCheckObject( astMakePointer( this_id ) ); - if ( astOK ) { - -/* Gain exclusive access to the handles array. */ - LOCK_MUTEX2; - -/* Obtain the Handle offset for this Object. */ - ihandle = CheckId( this_id, 1, status ); - if ( ihandle != -1 ) { - -/* Check that the current context level is at least 1 and report an - error if it is not. */ - if ( context_level < 1 ) { - if( astOK ) astError( AST__EXPIN, "astExport(%s): Attempt to export an Object " - "from context level zero.", status, - astGetClass( handles[ ihandle ].ptr ) ); - -/* Extract the context level at which the Object was created. */ - } else { - context = handles[ ihandle ].context; - -/* Check that the Object's existing context level is high enough to be - affected by being exported to the next outer context level. If not, - do nothing. */ - if ( context > ( context_level - 1 ) ) { - -/* Set the new context level. */ - handles[ ihandle ].context = context_level - 1; - -/* Remove the object's Handle from its original active Handles list - and insert it into the list appropriate to its new context - level. */ - RemoveHandle( ihandle, &active_handles[ context ], status ); - InsertHandle( ihandle, &active_handles[ context_level - 1 ], - status ); - -/* If required, tell the user that the handle has been exempted. */ -#ifdef MEM_DEBUG - astHandleUse( ihandle, "exported from context level %d", - context_level ); -#endif - } - } - } - UNLOCK_MUTEX2; - } -} - -void astImportId_( AstObject *this_id, int *status ) { -/* -*++ -* Name: -c astImport -f AST_IMPORT - -* Purpose: -* Import an Object pointer to the current context. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c void astImport( AstObject *this ) -f CALL AST_IMPORT( THIS, STATUS ) - -* Class Membership: -* Object method. - -* Description: -c This function -f This routine -* imports an Object pointer that was created in a higher or lower -* level context, into the current AST context. -* This means that the pointer will be annulled when the current context -c is ended (with astEnd). -f is ended (with AST_END). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Object pointer to be imported. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Object -c This function applies to all Objects. -f This routine applies to all Objects. - -*-- - -* Implementation Notes: -* - This function does not exist in the "protected" interface to -* the Object class and is not available to other class -* implementations. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int context; /* Handle context level */ - int ihandle; /* Offset of Handle in "handles" array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Obtain the Object pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Object. */ - (void) astCheckObject( astMakePointer( this_id ) ); - if ( astOK ) { - -/* Gain exclusive access to the handles array. */ - LOCK_MUTEX2; - -/* Obtain the Handle offset for this Object. */ - ihandle = CheckId( this_id, 1, status ); - if ( ihandle != -1 ) { - -/* Extract the context level at which the Object was created. */ - context = handles[ ihandle ].context; - -/* Do nothing if the Identifier already belongs to the current context. */ - if( context != context_level ) { - -/* Set the new context level. */ - handles[ ihandle ].context = context_level; - -/* Remove the object's Handle from its original active Handles list - and insert it into the list appropriate to its new context - level. */ - RemoveHandle( ihandle, &active_handles[ context ], status ); - InsertHandle( ihandle, &active_handles[ context_level ], status ); - -/* If required, tell the user that the handle has been imported. */ -#ifdef MEM_DEBUG - astHandleUse( ihandle, "imported into context level %d", - context_level ); -#endif - } - } - UNLOCK_MUTEX2; - } -} - -void astLockId_( AstObject *this_id, int wait, int *status ) { -/* -c++ -* Name: -* astLock - -* Purpose: -* Lock an Object for exclusive use by the calling thread. - -* Type: -* Public function. - -* Synopsis: -* #include "object.h" -* void astLock( AstObject *this, int wait ) - -* Class Membership: -* Object method. - -* Description: -* The thread-safe public interface to AST is designed so that an -* error is reported if any thread attempts to use an Object that it -* has not previously locked for its own exclusive use using this -* function. When an Object is created, it is initially locked by the -* thread that creates it, so newly created objects do not need to be -* explicitly locked. However, if an Object pointer is passed to -* another thread, the original thread must first unlock it (using -* astUnlock) and the new thread must then lock it (using astLock) -* before the new thread can use the Object. -* -* The "wait" parameter determines what happens if the supplied Object -* is curently locked by another thread when this function is invoked. - -* Parameters: -* this -* Pointer to the Object to be locked. -* wait -* If the Object is curently locked by another thread then this -* function will either report an error or block. If a non-zero value -* is supplied for "wait", the calling thread waits until the object -* is available for it to use. Otherwise, an error is reported and -* the function returns immediately without locking the Object. - -* Applicability: -* Object -* This function applies to all Objects. - -* Notes: -* - The astAnnul function is exceptional in that it can be used on -* pointers for Objects that are not currently locked by the calling -* thread. All other AST functions will report an error. -* - The Locked object will belong to the current AST context. -* - This function returns without action if the Object is already -* locked by the calling thread. -* - If simultaneous use of the same object is required by two or more -* threads, astCopy should be used to to produce a deep copy of -* the Object for each thread. Each copy should then be unlocked by -* the parent thread (i.e. the thread that created the copy), and then -* locked by the child thread (i.e. the thread that wants to use the -* copy). -* - This function is only available in the C interface. -* - This function returns without action if the AST library has -* been built without POSIX thread support (i.e. the "-with-pthreads" -* option was not specified when running the "configure" script). -c-- -*/ - -/* This function odes nothing if thread support is not enabvled. */ -#if defined(THREAD_SAFE) - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - AstObject *fail; /* Pointer to Object that failed to lock */ - AstObject *this; /* Pointer to Object */ - int ihandle; /* Index of supplied objetc handle */ - int lstat; /* Local status value */ - -/* Obtain the Object pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Object (this generates an - error if it doesn't). Note, we use the "astMakePointer_NoLockCheck", - since the usual "astMakePointer" macro invokes astCheckLock to report - an error if the Object is not currently locked by the calling thread. */ - if ( !astIsAObject( this = astMakePointer_NoLockCheck( this_id ) ) ) return; - -/* Ensure the global data for this class is accessable. Do not use the - globals pointer stored in "*this" because "*this" may be locked by - another thread and so we would pick up the wrong globals. */ - astGET_GLOBALS(NULL); - -/* Ensure the running thread has sole access to the static handles arrays. */ - LOCK_MUTEX2; - -/* Ensure the Handles arrays have been initialised. */ - if ( !active_handles ) InitContext( status ); - -/* Get the Handle index for the supplied object identifier. No error is - reported if the handle is not curently associated with a thread. - However, an error is reported if the Handle is associated with any - thread other than the running thread. */ - ihandle = CheckId( this_id, 1, status ); - -/* We've finished with the handles arrays, for the moment. */ - UNLOCK_MUTEX2; - -/* Check the object pointer was valid. */ - if( ihandle != -1 ){ - -/* The protected astManageLock function implements the public functions, - astLock and astUnlock. */ - lstat = astManageLock( this, AST__LOCK, wait, &fail ); - if( astOK ) { - if( lstat == 1 ) { - if( fail == this ) { - astError( AST__LCKERR, "astLock(%s): Failed to lock the %s because" - " it is already locked by another thread (programming " - "error).", status, astGetClass( this ), - astGetClass( this ) ); - - } else { - astError( AST__LCKERR, "astLock(%s): Failed to lock the %s because" - " a %s contained within it is already locked by another " - "thread (programming error).", status, - astGetClass( this ), astGetClass( this ), - astGetClass( fail ) ); - } - - } else if( lstat == 2 ) { - astError( AST__LCKERR, "astLock(%s): Failed to lock a POSIX mutex.", status, - astGetClass( this ) ); - -/* If the Object is now locked for the running thread... */ - } else { - -/* We need access to the handles arrays again. */ - LOCK_MUTEX2; - -/* If the supplied handle is not currently assigned to any thread, assign - it to the running thread. */ - if( handles[ ihandle ].context == UNOWNED_CONTEXT ) { - RemoveHandle( ihandle, &unowned_handles, status ); - -#if defined(MEM_DEBUG) - astHandleUse( ihandle, "locked by thread %d at context level %d", - handles[ ihandle ].thread, context_level ); -#endif - - handles[ ihandle ].thread = AST__THREAD_ID; - handles[ ihandle ].context = context_level; - InsertHandle( ihandle, &active_handles[ context_level ], - status ); - } - -/* Finished with the handles arrays again. */ - UNLOCK_MUTEX2; - } - } - } -#endif -} - -void astUnlockId_( AstObject *this_id, int report, int *status ) { -/* -c++ -* Name: -* astUnlock - -* Purpose: -* Unlock an Object for use by other threads. - -* Type: -* Public function. - -* Synopsis: -* #include "object.h" -* void astUnlock( AstObject *this, int report ) - -* Class Membership: -* Object method. - -* Description: -* Unlocks an Object previously locked using astLock, so that other -* threads can use the Object. See astLock for further details. - -* Parameters: -* this -* Pointer to the Object to be unlocked. -* report -* If non-zero, an error will be reported if the supplied Object, -* or any Object contained within the supplied Object, is not -* currently locked by the running thread. If zero, such Objects -* will be left unchanged, and no error will be reported. - -* Applicability: -* Object -* This function applies to all Objects. - -* Notes: -* - This function attempts to execute even if the global error -* status is set, but no further error report will be made if it -* subsequently fails under these circumstances. -* - All unlocked Objects are excluded from AST context handling until -* they are re-locked using astLock. -* - This function is only available in the C interface. -* - This function returns without action if the Object is not currently -* locked by any thread. If it is locked by the running thread, it is -* unlocked. If it is locked by another thread, an error will be reported -* if "error" is non-zero. -* - This function returns without action if the AST library has -* been built without POSIX thread support (i.e. the "-with-pthreads" -* option was not specified when running the "configure" script). -c-- -*/ - -/* This function odes nothing if thread support is not enabvled. */ -#if defined(THREAD_SAFE) - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - AstErrorContext error_context;/* Info about the current error context */ - AstObject *fail; /* Pointer to Object that failed */ - AstObject *this; /* Pointer to Object */ - int ihandle; /* Index of supplied objetc handle */ - int lstat; /* Local status value */ - -/* Obtain the Object pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Object (this generates an - error if it doesn't). Note, we use the "astMakePointer_NoLockCheck", - since the usual "astMakePointer" macro invokes astCheckLock to report - an error if the Object is not currently locked by the calling thread. */ - if ( !astIsAObject( this = astMakePointer_NoLockCheck( this_id ) ) ) return; - -/* Ensure the global data for this class is accessable. */ - astGET_GLOBALS(this); - -/* Start a new error reporting context. This saves any existing error status - and then clear the status value. It also defer further error reporting. */ - astErrorBegin( &error_context ); - -/* Ensure the running thread has sole access to the static handles arrays. */ - LOCK_MUTEX2; - -/* Ensure the Handles arrays have been initialised. */ - if ( !active_handles ) InitContext( status ); - -/* Get the Handle index for the supplied object identifier. Report an - error if the handle is associated with a different thread (no error - if the handle has no associated thread or is associated with the - current thread). */ - ihandle = CheckId( this_id, 1, status ); - -/* Break the associated of the handle with the current thread so that the - handle is not assigned to any thread. We do this before unlocking the - Object structure (using astManageLock) since as soon as astManageLock - returns, another thread that is waiting for the object to be unlocked - may start up and modify the handle properties. */ - if( ihandle >= 0 && handles[ ihandle ].context >= 0 ) { - RemoveHandle( ihandle, &active_handles[ handles[ ihandle ].context ], - status ); -#if defined(MEM_DEBUG) - astHandleUse( ihandle, "unlocked from thread %d at context " - "level %d", handles[ ihandle ].thread, - handles[ ihandle ].context ); -#endif - handles[ ihandle ].thread = -1; - handles[ ihandle ].context = UNOWNED_CONTEXT; - InsertHandle( ihandle, &unowned_handles, status ); - } - -/* We've finished with the handles arrays, for the moment. */ - UNLOCK_MUTEX2; - -/* Check the supplied object pointer was valid. */ - if( ihandle != -1 ){ - -/* The protected astManageLock function implements the public functions, - astLock and astUnlock. */ - lstat = astManageLock( this, AST__UNLOCK, 0, &fail ); - if( astOK ) { - if( lstat == 1 ) { - if( report ) { - if( fail == this ) { - astError( AST__LCKERR, "astUnlock(%s): Failed to unlock the %s " - "because it is locked by another thread (programming " - "error).", status, astGetClass( this ), - astGetClass( this ) ); - - } else { - astError( AST__LCKERR, "astUnlock(%s): Failed to unlock the %s " - "because a %s contained within it is locked by another " - "thread (programming error).", status, - astGetClass( this ), astGetClass( this ), - astGetClass( fail ) ); - } - } - - } else if( lstat == 3 ) { - astError( AST__LCKERR, "astUnlock(%s): Failed to unlock a POSIX mutex.", status, - astGetClass( this ) ); - - } - } - } - -/* End the error reporting context. If an error has occurred within this - function, then this will display the deferred error messages so long - as there was no error condition on entry to this function. If there - was an error condition on entry, then the original status value will be - re-instated. */ - astErrorEnd( &error_context ); - -#endif -} - -AstObject *astI2P_( int integer, int *status ) { -/* -*+ -* Name: -* astI2P - -* Purpose: -* Pack an integer Object ID into a pointer. - -* Type: -* Public function. - -* Synopsis: -* #include "object.h" -* AstObject *astI2P( int integer ) - -* Class Membership: -* Object class function. - -* Description: -* This function accepts an integer (int) value representing an -* Object identifier and packs its bit pattern into a pointer value -* (from which it may subsequently be retrieved using astP2I). -* -* These functions should be used to avoid any dependency on -* integer-to-pointer conversions (given that the values are not -* true pointers) which might affect the exchange of Object -* identifier values with other languages, such as Fortran 77, -* where they are stored as integers. - -* Parameters: -* integer -* The integer value to be stored. - -* Returned Value: -* The resulting pointer value (which is not usually a valid C pointer). - -* Notes: -* - This function does not perform error checking and does not -* generate errors. -* - This is a protected function in the sense that it is not -* intended that external users should invoke it directly. It is -* accessible from external code, however, in order that public -* macros invoked from that code can make use of it. -*- -*/ - -/* Local Variables: */ - IdUnion temp; /* Overlapping int and pointer */ - -/* Clear the pointer value in the "temp" IdUnion and then set the - integer part of it to the value to be stored. */ - temp.pointer = zero_ptr; - temp.integer = integer; - -/* Return the resulting pointer value. */ - return temp.pointer; -} - -MYSTATIC void InitContext( int *status ) { -/* -* Name: -* InitContext - -* Purpose: -* Initialise the first AST context level. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* void InitContext( int *status ) - -* Class Membership: -* Object member function. - -* Description: -* This function initialises the first AST context level (the level -* before any call to astBegin has been made). It should be invoked -* once, before any use is made of context levels. - -* Parameters: -* status -* Pointer to the inherited status variable. - -* Parameters: -* None. - -* Notes: -* - This function does nothing after the first successful invocation. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Check that the active_handles array hasn't already been allocated. */ - if ( !active_handles ) { - -/* Allocate and initialise the "active_handles" array. */ - - astBeginPM; - active_handles = astMalloc( sizeof( int ) ); - astEndPM; - - if ( astOK ) active_handles[ 0 ] = -1; - } -} - -MYSTATIC void InsertHandle( int ihandle, int *head, int *status ) { -/* -* Name: -* InsertHandle - -* Purpose: -* Insert a Handle into a list. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* void InsertHandle( int ihandle, int *head, int *status ) - -* Class Membership: -* Object member function. - -* Description: -* This function inserts a Handle structure into a doubly linked -* list of such structures composed of elements drawn from the -* "handles" array. The new list member is inserted in front of the -* member previously occupying the "head of list" position. - -* Parameters: -* ihandle -* Offset in the "handles" array that identifies the handle to -* be added to the list. -* head -* Address of an int which holds the offset in the "handles" -* array of the element at the head of the list (or -1 if the -* list is empty). This value will be updated to identify the -* new list member. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function does not perform error chacking and does not -* generate errors. -* - The lists generated by this function use integer offsets into -* the "handles" array for their links, rather than pointers. This -* is because the array may be re-located in memory when it needs -* to be extended, so pointers to its element would not remain -* valid. -* - The list elements are drawn from the "handles" array in the -* first place so that they can be addressed by small integers (the -* offset in the array). This allows references to Handles to be -* encoded along with security information into an integer that is -* sufficiently short to be exported to other languages -* (e.g. Fortran) which might not be able to accommodate -* full-length C pointers. -*/ - - -#if defined(MEM_DEBUG) - char buf[80]; - astHandleUse( ihandle, "about to be inserted into %s (%d)", - HeadString( head, buf ), head ); - CheckList( head, status ); - CheckInList( ihandle, head, 0, status ); -#endif - -/* Check a head pointer was supplied (may not be if an error has - occurred). */ - if( ! head ) return; - -/* If the list is empty, the sole new element points at itself. */ - if ( *head == -1 ) { - handles[ ihandle ].flink = ihandle; - handles[ ihandle ].blink = ihandle; - -/* Otherwise, insert the new element in front of the element at the - head of the list. */ - } else { - handles[ ihandle ].flink = *head; - handles[ ihandle ].blink = handles[ *head ].blink; - handles[ ( handles[ *head ].blink) ].flink = ihandle; - handles[ *head ].blink = ihandle; - } - -/* Update the list head to identify the new element. */ - *head = ihandle; - -#if defined(MEM_DEBUG) - CheckList( head, status ); - astHandleUse( ihandle, "has been inserted into %s", buf ); -#endif -} - -AstObject *astMakeId_( AstObject *this, int *status ) { -/* -*+ -* Name: -* astMakeId - -* Purpose: -* Issue an identifier for an Object. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* AstObject *astMakeId( AstObject *this ) - -* Class Membership: -* Object member function. - -* Description: -* This function takes a normal C pointer to an Object and -* associates an identifier with it. - -* Parameters: -* this -* Pointer to an Object. Note that this function copies this -* value (it is not cloned), so the caller should not annul the -* pointer afterwards. - -* Returned Value: -* The resulting identifier value. - -* Notes: -* - An identifier value of zero will be returned and the supplied -* Object pointer will be annulled if this function is invoked with -* the global error status set or if it should fail for any reason. -* - A zero identifier value will also be returned if a NULL object -* pointer is supplied, but this will not provoke an error. -* - This is a protected function in the sense that it is not -* intended that external users should invoke it directly. It is -* accessible from external code, however, in order that public -* macros invoked from that code can make use of it. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - AstObject *id; /* ID value to return */ - int ihandle; /* Handle offset */ - -/* Initialise. */ - id = astI2P( 0 ); - ihandle = 0; - -/* Check the global error status. */ - if ( astOK ) { - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(this); - -/* Gain exclusive access to the handles array. */ - LOCK_MUTEX2; - -/* If a non-NULL Object pointer was given, we must obtain a Handle - structure to associate with it (otherwise a zero identifier value - is returned without error). */ - if ( this ) { - -/* If the free Handles list is not empty, obtain a Handle from it. */ - if ( free_handles != -1 ) { - ihandle = free_handles; - RemoveHandle( ihandle, &free_handles, status ); - -/* Otherwise, allocate a new Handle by extending the "handles" array - and using the offset of the new element. */ - } else { - - astBeginPM; - handles = astGrow( handles, nhandles + 1, sizeof( Handle ) ); - astEndPM; - - if ( astOK ) { - ihandle = nhandles++; - - handles[ ihandle ].ptr = NULL; - handles[ ihandle ].context = INVALID_CONTEXT; - handles[ ihandle ].check = 0; - handles[ ihandle ].flink = -1; - handles[ ihandle ].blink = -1; - handles[ ihandle ].line = 0; - handles[ ihandle ].file = NULL; - handles[ ihandle ].routine = NULL; -#if defined(THREAD_SAFE) - handles[ ihandle ].thread = 0; -#endif - -#if defined(MEM_DEBUG) - handles[ ihandle ].id = 0; - handles[ ihandle ].vtab = NULL; -#endif - } - } - -/* If the first AST context level has not yet been initialised, invoke - InitContext to initialise it and allocate memory for the - "active_handles" array which stores context information. */ - if ( astOK ) { - if ( !active_handles ) InitContext( status ); - -/* Store the Object pointer and current context level in the Handle. */ - if ( astOK ) { - handles[ ihandle ].ptr = this; - handles[ ihandle ].context = context_level; -#if defined(THREAD_SAFE) - handles[ ihandle ].thread = AST__THREAD_ID; -#endif - -/* Store information that records where the Handle is created - routine - name, file name and line number. */ - astGetAt( &handles[ ihandle ].routine, - &handles[ ihandle ].file, - &handles[ ihandle ].line ); - -/* Store extra debugging information in the handle if enabled */ -#if defined(MEM_DEBUG) - handles[ ihandle ].id = astMemoryId( this ); - handles[ ihandle ].vtab = this->vtab; - astHandleUse( ihandle, "associated with a %s (id %d)", - astGetClass( this ), astMemoryId( this )); -#endif - -/* Insert the Handle into the active Handles list for the current - context level. */ - InsertHandle( ihandle, &active_handles[ context_level ], status ); - -/* Associate an identifier value with the Handle. */ - id = AssocId( ihandle, status ); - -/* If an error occurred, clean up by annulling the Handle. This - ensures that the Object pointer is annulled and returns the unused - Handle to the Free Handle list. */ - if ( !astOK ) { - AnnulHandle( ihandle, status ); - this = NULL; - } - -/* If the Handle wasn't used (because of an earlier error), return it - to the free Handles list. */ - } else { - InsertHandle( ihandle, &free_handles, status ); - } - } - } - UNLOCK_MUTEX2; - } - -/* If a bad status value was either supplied or generated within this - function, then annul the supplied pointer (unless it is NULL). */ - if ( !astOK && this ) (void) astAnnul( this ); - -/* Return the identifier value. */ - return id; -} - -AstObject *astMakePointer_( AstObject *this_id, int *status ) { -/* -*+ -* Name: -* astMakePointer - -* Purpose: -* Obtain a true C pointer from an Object identifier. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* AstObject *astMakePointer( AstObject *this ) - -* Class Membership: -* Object class function. - -* Description: -* This function accepts an external Object identifier and returns -* a true C Object pointer that may be de-referenced to access the -* Object's data and methods. - -* Parameters: -* this -* The identifier value. - -* Returned Value: -* The true C pointer value. - -* Notes: -* - In a thread-safe context, an error is reported if the supplied -* Object has not been locked by the calling thread (using astLock) -* prior to invoking this function. -* - The object reference count is not modified by this function, -* so the returned pointer should not be annulled by the caller. -* - Typically, this function should be used whenever a public -* function must accept identifier values directly (rather than -* having them translated automatically into pointers during -* argument validation by the astCheck range of functions). -* - Note that this function will NOT accept a true C pointer as an -* argument, even when invoked from internal code (with astCLASS -* defined). An identifier value MUST be supplied, and an error -* will result if it is not associated with an active Object. -* - This function attempts to execute even if the global error -* status is set, but no further error report will be made if it -* subsequently fails under these circumstances. -* - This is a protected function in the sense that it is not -* intended that external users should invoke it directly. It is -* accessible from external code, however, in order that public -* macros invoked from that code can make use of it. -*- -*/ - -/* Local Variables: */ - AstObject *ptr; /* Pointer value to return */ - int ihandle; /* Handle offset in "handles" array */ - -/* Initialise. */ - ptr = NULL; - -/* Gain exclusive access to the handles array. */ - LOCK_MUTEX2; - -/* Validate the identifier supplied and derive the Handle offset. */ - ihandle = CheckId( this_id, 1, status ); - -/* If the identifier was valid, extract the Object pointer from the - Handle. */ - if ( ihandle != -1 ) ptr = handles[ ihandle ].ptr; - - UNLOCK_MUTEX2; - -/* Return the result. */ - return ptr; -} - -AstObject *astMakePointer_NoLockCheck_( AstObject *this_id, int *status ) { -/* -*+ -* Name: -* astMakePointer_NoLockCheck - -* Purpose: -* Obtain a true C pointer from an Object identifier. - -* Type: -* Protected function. - -* Synopsis: -* #include "object.h" -* AstObject *astMakePointer_NoLockCheck( AstObject *this ) - -* Class Membership: -* Object class function. - -* Description: -* This function accepts an external Object identifier and returns -* a true C Object pointer that may be de-referenced to access the -* Object's data and methods. -* -* It is identicial to astMakePointer except that it does not check -* that the supplied Object is locked by the running thread. - -* Parameters: -* this -* The identifier value. - -* Returned Value: -* The true C pointer value. - -* Notes: -* - The object reference count is not modified by this function, -* so the returned pointer should not be annulled by the caller. -* - Typically, this function should be used whenever a public -* function must accept identifier values directly (rather than -* having them translated automatically into pointers during -* argument validation by the astCheck range of functions). -* - Note that this function will NOT accept a true C pointer as an -* argument, even when invoked from internal code (with astCLASS -* defined). An identifier value MUST be supplied, and an error -* will result if it is not associated with an active Object. -* - This function attempts to execute even if the global error -* status is set, but no further error report will be made if it -* subsequently fails under these circumstances. -* - This is a protected function in the sense that it is not -* intended that external users should invoke it directly. It is -* accessible from external code, however, in order that public -* macros invoked from that code can make use of it. -*- -*/ - -/* Local Variables: */ - AstObject *ptr; /* Pointer value to return */ - int ihandle; /* Handle offset in "handles" array */ - -/* Initialise. */ - ptr = NULL; - -/* Gain exclusive access to the handles array. */ - LOCK_MUTEX2; - -/* Validate the identifier supplied and derive the Handle offset. */ - ihandle = CheckId( this_id, 0, status ); - -/* If the identifier was valid, extract the Object pointer from the - Handle. */ - if ( ihandle != -1 ) ptr = handles[ ihandle ].ptr; - - UNLOCK_MUTEX2; - -/* Return the result. */ - return ptr; -} - -int astP2I_( AstObject *pointer, int *status ) { -/* -*+ -* Name: -* astP2I - -* Purpose: -* Extract an integer Object ID from a pointer. - -* Type: -* Public function. - -* Synopsis: -* #include "object.h" -* int astP2I( AstObject *pointer ) - -* Class Membership: -* Object class function. - -* Description: -* This function retrieves an integer (int) value representing an -* Object identifier from a pointer value (into which it has -* previously been packed using astI2P). -* -* These functions should be used to avoid any dependency on -* integer-to-pointer conversions (given that the values are not -* true pointers) which might affect the exchange of Object -* identifier values with other languages, such as Fortran 77, -* where they are stored as integers. - -* Parameters: -* pointer -* The pointer value into which the ID has previously been packed. - -* Returned Value: -* The extracted Object identifier value as an integer (int). - -* Notes: -* - This function does not perform error checking and does not -* generate errors. -* - This is a protected function in the sense that it is not -* intended that external users should invoke it directly. It is -* accessible from external code, however, in order that public -* macros invoked from that code can make use of it. -*- -*/ - -/* Local Variables: */ - IdUnion temp; /* Overlapping int and pointer */ - -/* Store the pointer value supplied. */ - temp.pointer = pointer; - -/* Return the integer part of it. */ - return temp.integer; -} - -MYSTATIC void RemoveHandle( int ihandle, int *head, int *status ) { -/* -* Name: -* RemoveHandle - -* Purpose: -* Remove a Handle from a list. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* void RemoveHandle( int ihandle, int *head ) - -* Class Membership: -* Object member function. - -* Description: -* This function removes a Handle structure from a doubly linked -* list of such structures composed of elements drawn from the -* "handles" array. The "head of list" position is updated if -* necessary. - -* Parameters: -* ihandle -* Offset in the "handles" array that identifies the Handle to -* be removed from the list (note that the Handle must actually -* be in the list, although this function does not check this). -* head -* Address of an int which holds the offset in the "handles" -* array of the element at the head of the list. This value will -* be updated if necessary to identify the new list head (or set -* to -1 if removing the Handle causes the list to become -* empty). - -* Notes: -* - This function does not perform error chacking and does not -* generate errors. -* - See the InsertHandle function for details of how and why lists -* of Handles are constructed. -*/ - - -#if defined(MEM_DEBUG) - char buf[80]; - astHandleUse( ihandle, "about to be removed from %s", HeadString( head, buf ) ); - CheckList( head, status ); - CheckInList( ihandle, head, 1, status ); -#endif - -/* Check a head pointer was supplied (may not be if an error has - occurred). */ - if( ! head ) return; - -/* Remove the Handle from the list by re-establishing links between - the elements on either side of it. */ - handles[ ( handles[ ihandle ].blink ) ].flink = handles[ ihandle ].flink; - handles[ ( handles[ ihandle ].flink ) ].blink = handles[ ihandle ].blink; - -/* If the element removed was at the head of the list, update the head - of list offset to identify the following element. */ - if ( ihandle == *head ) { - *head = handles[ ihandle ].flink; - -/* If the head of list still identifies the removed element, then note - that the list is now empty. */ - if ( *head == ihandle ) *head = -1; - } - -/* Make the removed element point at itself. */ - handles[ ihandle ].flink = ihandle; - handles[ ihandle ].blink = ihandle; - -#if defined(MEM_DEBUG) - astHandleUse( ihandle, "has been removed from %s", buf ); - CheckList( head, status ); -#endif -} - -void astSetId_( void *this_id_void, const char *settings, ... ) { -/* -* Name: -* astSetId_ - -* Purpose: -* Set values for an Object's attributes via an identifier. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* void astSetId_( AstObject *this, const char *settings, ... ) - -* Class Membership: -* Object member function. - -* Description: -* This function implements the axternal interface to the astSet -* method (q.v.). It accepts an Object identifier, but otherwise -* behaves identically to astSet. - -* Parameters: -* this -* Object identifier. -* settings -* Pointer to a null-terminated string containing a -* comma-separated list of attribute settings. -* ... -* Optional arguments which supply values to be substituted for -* any "printf"-style format specifiers that appear in the -* "settings" string. - -* Notes: -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* Object identifier is of type (void *) and is converted and -* validated within the function itself. -*/ - -/* Local Variables: */ - AstObject *this; /* Pointer to the Object structure */ - int *status; /* Pointer to inherited status variable */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the integer holding the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the Object pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Object. */ - this = astCheckObject( astMakePointer( this_id_void ) ); - if ( astOK ) { - -/* Obtain the variable argument list and pass all arguments to the - astVSet method for interpretation. */ - va_start( args, settings ); - astVSet( this, settings, NULL, args ); - va_end( args ); - } -} - -int astThreadId_( AstObject *this_id, int ptr, int *status ) { -/* -c++ -* Name: -* astThread - -* Purpose: -* Determine the thread that owns an Object. - -* Type: -* Public function. - -* Synopsis: -* #include "object.h" -* int astThread( AstObject *this, int ptr ) - -* Class Membership: -* Object method. - -* Description: -* Returns an integer that indicates whether the supplied Object (or -* Object pointer) is currently unlocked, or is currently locked by -* the running thread, or another thread. - -* Parameters: -* this -* Pointer to the Object to be checked. -* ptr -* If non-zero, returns information about the supplied Object -* pointer, rather than the Object structure itself. See "Object -* Pointers and Structures" below. - -* Returned Value: -* astThread() -* A value of AST__UNLOCKED is returned if the Object (or pointer) -* is currently unlocked (i.e. has been unlocked using astUnlock -* but has not yet been locked using astLock). A value of -* AST__RUNNING is returned if the Object (or pointer) is currently -* locked by the running thread. A value of AST__OTHER is returned -* if the Object (or pointer) is currently locked by the another -* thread. - -* Object Pointers and Structures: -* At any one time, an AST Object can have several distinct pointers, -* any one of which can be used to access the Object structure. For -* instance, the astClone function will produce a new distinct pointer -* for a given Object. In fact, an AST "pointer" is not a real pointer -* at all - it is an identifier for a "handle" structure, encoded to -* make it look like a pointer. Each handle contains (amongst othere -* things) a "real" pointer to the Object structure. This allows more -* than one handle to refer to the same Object structure. So when you -* call astClone (for instance) you get back an identifier for a new -* handle that refers to the same Object as the supplied handle. -* -* In order to use an Object for anything useful, it must be locked -* for use by the running thread (either implicitly at creation or -* explicitly using astLock). The identity of the thread is stored in -* both the Object structure, and in the handle that was passed to -* astLock (or returned by the constructor function). Thus it is -* possible for a thread to have active pointers for Objects that are -* currently locked by another thread. In general, if such a pointer is -* passed to an AST function an error will be reported indicating that -* the Object is currently locked by another thread. The two exceptions -* to this is that astAnnul can be used to annull such a pointer, and -* this function can be used to return information about the pointer. -* -* The other practical consequence of this is that when astEnd is -* called, all active pointers currently owned by the running thread -* (at the current context level) are annulled. This includes pointers -* for Objects that are currently locked by other threads. -* -* If the "ptr" parameter is zero, then the returned value describes -* the Object structure itself. If "ptr" is non-zero, then the returned -* value describes the supplied Object pointer (i.e. handle), rather -* than the Object structure. - -* Notes: -* - This function attempts to execute even if the global error -* status is set, but no further error report will be made if it -* subsequently fails under these circumstances. -* - This function is only available in the C interface. -* - This function always returns AST__RUNNING if the AST library has -* been built without POSIX thread support (i.e. the "-with-pthreads" -* option was not specified when running the "configure" script). -c-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Thread-specific global data */ - int result; /* The returned value */ - -#if defined(THREAD_SAFE) - -/* More local Variables: */ - AstObject *this; - int ihandle; - int check; - -/* Ensure global variables are accessable. */ - astGET_GLOBALS(NULL); -#endif - -/* Initialise the returned value */ - result = AST__RUNNING; - -/* Nothing more to do if AST was not build with thread support. */ -#if defined(THREAD_SAFE) - -/* If the ownership of the handle is being queried... */ - if( ptr ) { - -/* Lock the mutex that guards access to the handles array */ - LOCK_MUTEX2; - -/* Check the supplied object identifier is valid and get the - corresponding index into the handles array. */ - ihandle = CheckId( this_id, 1, status ); - if( ihandle != -1 ) { - -/* Set the returned value on the basis of the threa didentifier stored in - the handle structure. */ - if( handles[ ihandle ].thread == -1 ) { - result = AST__UNLOCKED; - } else if( handles[ ihandle ].thread != AST__THREAD_ID ) { - result = AST__OTHER; - } - } - -/* Unlock the mutex that guards access to the handles array */ - UNLOCK_MUTEX2; - -/* Otherwise, the ownership of the Object is being queried. Obtain the - Object pointer from the ID supplied and validate the pointer to ensure - it identifies a valid Object (this generates an error if it doesn't). - Note, we use the "astMakePointer_NoLockCheck", since the usual - "astMakePointer" macro invokes astCheckLock to report an error if the - Object is not currently locked by the calling thread. */ - } else if( astIsAObject( this = astMakePointer_NoLockCheck( this_id ) ) ) { - -/* Determine which thread (if any) has the object locked, and set an - appropriate return value. */ - check = astManageLock( this, AST__CHECKLOCK, 0, NULL ); - - if( check == 5 ) { - result = AST__OTHER; - } else if( check == 6 ) { - result = AST__UNLOCKED; - } - } - -#endif - -/* Return the result. */ - return result; -} - -int astVersion_( int *status ) { -/* -*++ -* Name: -c astVersion -f AST_VERSION - -* Purpose: -* Return the version of the AST library being used. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c int astVersion -f RESULT = AST_VERSION() - -* Class Membership: -* Object class function. - -* Description: -c This macro invokes a function which -f This function -* returns an integer representing the version of the AST library -* being used. The library version is formatted as a string such as -* "2.0-7" which contains integers representing the "major version" (2), -* the "minor version" (0) and the "release" (7). The integer returned -* by this function combines all three integers together into a single -* integer using the expresion: -* -* (major version)*1E6 + (minor version)*1E3 + (release) - -* Returned Value: -c astVersion -f AST_VERSION = INTEGER -* The major version, minor version and release numbers for the AST -* library, encoded as a single integer. - -* Applicability: -* Object -c This macro applies to all Objects. -f This routine applies to all Objects. - -*-- -*/ - - return (int) AST__VMAJOR*1E6 + AST__VMINOR*1E3 + AST__RELEASE; -} - -int astEscapes_( int new_value, int *status ) { -/* -*++ -* Name: -c astEscapes -f AST_ESCAPES - -* Purpose: -* Control whether graphical escape sequences are included in strings. - -* Type: -* Public function. - -* Synopsis: -c #include "object.h" -c int astEscapes( int new_value ) -f RESULT = AST_ESCAPES( NEWVAL, STATUS ) - -* Class Membership: -* Object class function. - -* Description: -* The Plot class defines a set of escape sequences which can be -* included within a text string in order to control the appearance of -* sub-strings within the text. See the Escape attribute for a -* description of these escape sequences. It is usually inappropriate -* for AST to return strings containing such escape sequences when -* called by application code. For instance, an application which -* displays the value of the Title attribute of a Frame usually does -* not want the displayed string to include potentially long escape -* sequences which a human read would have difficuly interpreting. -* Therefore the default behaviour is for AST to strip out such escape -* sequences when called by application code. This default behaviour -* can be changed using this function. - -* Parameters: -c new_value -f NEWVAL = INTEGER (Given) -* A flag which indicates if escapes sequences should be included -* in returned strings. If zero is supplied, escape sequences will -* be stripped out of all strings returned by any AST function. If -* a positive value is supplied, then any escape sequences will be -* retained in the value returned to the caller. If a negative -* value is supplied, the current value of the flag will be left -* unchanged. - -* Returned Value: -c astEscapes -f AST_ESCAPES = INTEGER -* The value of the flag on entry to this function. - -* Applicability: -* Object -c This macro applies to all Objects. -f This routine applies to all Objects. - -* Notes: -* - This function also controls whether the -c astStripEscapes -f AST_STRIPESCAPES -* function removes escape sequences from the supplied string, or -* returns the supplied string without change. -* - This function attempts to execute even if an error has already -* occurred. - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - int old_val; - -/* Get a pointer to Thread-specific global data. */ - astGET_GLOBALS(NULL); - -/* Save the old value. */ - old_val = retain_esc; - -/* Set the new value. */ - if( new_value > 0 ) { - retain_esc = 1; - - } else if( new_value == 0 ) { - retain_esc = 0; - } - -/* Return the old value. */ - return old_val; -} - - -#if defined(MEM_DEBUG) - -/* Check each handle in a list is uniquely connected to one other handle - in both the forward and backward directions. */ - -void CheckList( int *head, int *status ) { - int ok; - int ihandle; - char buf[200]; - astDECLARE_GLOBALS - if( !astOK ) return; - - astGET_GLOBALS(NULL); - - ok = 1; - if ( *head != -1 ) { - ihandle = *head; - if( handles[ handles[ ihandle ].blink ].flink != ihandle || - handles[ handles[ ihandle ].flink ].blink != ihandle ) { - ok = 0; - - } else { - if( CheckThread( ihandle, head, status ) ) { - ihandle= handles[ *head ].blink; - while( ihandle != *head ) { - if( handles[ handles[ ihandle ].blink ].flink != ihandle || - handles[ handles[ ihandle ].flink ].blink != ihandle || - CheckThread( ihandle, head, status ) == 0 ) { - ok = 0; - break; - } - ihandle= handles[ ihandle ].blink; - } - } - } - } - - if( !ok ) { - printf("CheckList error in %s\n", HeadString( head, buf ) ); - printf(" Central handle: %s\n", HandleString( ihandle, buf ) ); - - if( handles[ handles[ ihandle ].blink ].flink != ihandle ) { - printf(" Central handle->blink: %s\n", - HandleString( handles[ ihandle ].blink, buf ) ); - printf(" Central handle->blink->flink: %s\n", - HandleString( handles[ handles[ ihandle ].blink ].flink, buf ) ); - } - - if( handles[ handles[ ihandle ].flink ].blink != ihandle ) { - printf(" Central handle->flink: %s\n", - HandleString( handles[ ihandle ].flink, buf ) ); - printf(" Central handle->flink->blink: %s\n", - HandleString( handles[ handles[ ihandle ].flink ].blink, buf ) ); - } - } - -} - - -/* Check if a specified handle is, or is not, in a given list of handles. */ - -void CheckInList( int ihandle, int *head, int in, int *status ){ - char list[80], buf[200]; - int found = 0; - if( !astOK ) return; - - if ( *head != -1 ) { - if( ihandle == *head ) { - found = 1; - } else { - if( CheckThread( ihandle, head, status ) ) { - int jhandle= handles[ *head ].blink; - while( jhandle != *head ) { - if( ihandle == jhandle ) { - found = 1; - break; - } - jhandle= handles[ jhandle ].blink; - } - } - } - } - - if( in && !found ) { - printf("Error: Handle %s not in %s\n", HandleString( ihandle, buf ), - HeadString( head, list ) ); - } else if( !in && found ) { - printf("Error: Handle %s is in %s\n", HandleString( ihandle, buf ), - HeadString( head, list ) ); - } - -} - -/* Check that a handle is owned by the currently executing thread. */ - -int CheckThread( int ihandle, int *head, int *status ) { - int result = 1; - -#if defined(THREAD_SAFE) - - char buf[200]; - astDECLARE_GLOBALS - if( !astOK ) return result; - - astGET_GLOBALS(NULL); - - if( *head == unowned_handles ) { - if( handles[ ihandle ].thread != -1 ) { - printf("Handle %s has wrong thread: is %d, should " - "be -1 (i.e. unowned)\n", HandleString( ihandle, buf ), - handles[ ihandle ].thread ); - - result = 0; - } - - } else if( *head == free_handles ) { - if( handles[ ihandle ].thread != -1 ) { - printf("Handle %s has wrong thread: is %d, should " - "be -1 (i.e. free)\n", HandleString( ihandle, buf ), - handles[ ihandle ].thread ); - result = 0; - } - - } else if( handles[ ihandle ].thread != AST__THREAD_ID ) { - printf("Handle %s has wrong thread: is %d, should " - "be %d\n", HandleString( ihandle, buf ), - handles[ ihandle ].thread, AST__THREAD_ID ); - result = 0; - } - -#endif - - return result; -} - -void astWatchHandle_( int handle ){ - Watched_Handle = handle; -} - -void astHandleUse_( int handle, const char *verb, ... ){ - va_list args; - if( handle == Watched_Handle ) { - va_start( args, verb ); - astHandleAlarm( verb, args ); - va_end( args ); - } -} - -void astHandleAlarm_( const char *verb, va_list args ){ - char buff[200], hbuf[200]; - astDECLARE_GLOBALS - astGET_GLOBALS(NULL); - - vsprintf( buff, verb, args ); - -#if defined(THREAD_SAFE) - printf( "astHandleAlarm: Handle %s %s (current thread is %d).\n\n", - HandleString( Watched_Handle, hbuf ), buff, AST__THREAD_ID ); -#else - printf( "astHandleAlarm: Handle %s %s.\n\n", - HandleString( Watched_Handle, hbuf ), buff ); -#endif -} - -MYSTATIC const char *HandleString( int ihandle, char *buf ){ -#if defined(THREAD_SAFE) - astDECLARE_GLOBALS - astGET_GLOBALS(NULL); - - if( ihandle >= 0 ) { - sprintf( buf, "(index:%d v:%d c:%d t:%d i:%d cl:%s) [cur. thread: %d]", - ihandle, - handles[ ihandle ].check, - handles[ ihandle ].context, handles[ ihandle ].thread, - handles[ ihandle ].id, - handles[ ihandle ].vtab ? handles[ ihandle ].vtab->class : "", - AST__THREAD_ID ); - } else { - sprintf( buf, "(index:%d ) [cur. thread: %d]", ihandle, - AST__THREAD_ID ); - } - -#else - if( ihandle >= 0 ) { - sprintf( buf, "(index:%d v:%d c:%d i:%d cl:%s)", ihandle, - handles[ ihandle ].check, - handles[ ihandle ].context, handles[ ihandle ].id, - handles[ ihandle ].vtab ? handles[ ihandle ].vtab->class : "" ); - } else { - sprintf( buf, "(index:%d )", ihandle ); - } -#endif - return buf; -} - -MYSTATIC const char *HeadString( int *head, char *list ){ - int i; - astDECLARE_GLOBALS - astGET_GLOBALS(NULL); - - if( head == &free_handles ) { - strcpy( list, "free_handles" ); - -#if defined(THREAD_SAFE) - } else if( head == &unowned_handles ) { - strcpy( list, "unowned_handles" ); -#endif - - } else { - *list = 0; - for( i = 0; i <= context_level; i++ ) { - if( *head == active_handles[ i ] ) { - sprintf( list, "active_handles[%d]", i ); - break; - } - } - if( *list == 0 ) sprintf( list, "unknown handles list with head %d", - *head ); - } - return list; -} - -#endif diff --git a/ast/object.f b/ast/object.f deleted file mode 100644 index 34f92b2..0000000 --- a/ast/object.f +++ /dev/null @@ -1,70 +0,0 @@ - CHARACTER * ( * ) FUNCTION AST_GETC( THIS, ATTRIB ) -*+ -* Name: -* AST_GETC - -* Purpose: -* Wrap up the C ast_getc_a function. - -* Language: -* Fortran 77 - -* Invocation: -* RESULT = AST_GETC( THIS, ATTRIB ) - -* Description: -* This function is a wrap-up of the C ast_getc_a function. It will -* rarely need to be used, but is provided for use on platforms -* where the normal mechanism for returning character strings as -* function results from C to Fortran (as defined in the f77.h -* include file) doesn't work. -* -* If this problem is encountered, the C macro NO_CHAR_FUNCTION -* should be defined (in CFLAGS) during C compilation. This will -* cause the function ast_getc_a to be built (instead of ast_getc) -* and this returns its the result via an additional initial -* argument. This Fortran function is then used simply to transfer -* the argument value to the function result. - -* Arguments: -* As for the C version of the Fortran-callable function ast_getc. - -* Returned Value: -* AST_GETC = CHARACTER * ( * ) -* The character return value required. - -* Notes: -* - The length of the returned result is limited to 200 characters -* by a local buffer. This length can be increased if necessary. - -* Authors: -* RFWS: R.F. Warren-Smith (STARLINK, RAL) -* {enter_new_authors_here} - -* History: -* 3-JUL-1996 (RFWS): -* Original version. -* {enter_changes_here} - -* Bugs: -* {note_any_bugs_here} - -*- - -* Type Definitions: - IMPLICIT NONE ! No implicit typing - -* Arguments Given: - INTEGER THIS - CHARACTER * ( * ) ATTRIB - -* Local Variables: - CHARACTER * ( 200 ) BUFF ! Local buffer for result -*. - -* Invoke the C function (with the additional argument). - CALL AST_GETC_A( BUFF, THIS, ATTRIB ) - -* Return the argument value as the function result. - AST_GETC = BUFF - END diff --git a/ast/object.h.in b/ast/object.h.in deleted file mode 100644 index 64720ff..0000000 --- a/ast/object.h.in +++ /dev/null @@ -1,1960 +0,0 @@ -#if !defined( OBJECT_INCLUDED ) /* Include this file only once */ -#define OBJECT_INCLUDED -/* -*++ -* Name: -* object.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Object class. - -* Invocation: -* #include "object.h" - -* Description: -* This include file defines the interface to the Object class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. - -* The Object class is the base class from which all other classes -* in the AST library are derived. This class provides all the -* basic Object behaviour and Object manipulation facilities -* required throughout the library. There is no Object constructor, -* however, as Objects on their own are not of much use. - -* Inheritance: -* The Object base class does not inherit from any other class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* Class (string) -* This is a read-only attribute containing the name of the -* class to which an Object belongs. -* ID (string) -* An identification string which may be used to identify the -* Object (e.g.) in debugging output, or when stored in an -* external medium such as a data file. There is no restriction -* on the string's contents. The default is an empty string. -* Ident (string) -* Like ID, this is an identification string which may be used -* to identify the Object. Unlike ID, Ident is transferred when an -* Object is copied. -* UseDefs (int) -* Should default values be used for unset attributes? -* Nobject (integer) -* This is a read-only attribute which gives the total number of -* Objects currently in existence in the same class as the -* Object given. It does not include Objects which belong to -* derived (more specialised) classes. This value is mainly -* intended for debugging, as it can be used to show whether -* Objects which should have been deleted have, in fact, been -* deleted. -* ObjSize (int) -* The in-memory size of the Object in bytes. -* RefCount (integer) -* This is a read-only Attribute which gives the "reference -* count" (the number of active pointers) associated with an -* Object. It is modified whenever pointers are created or -* annulled (by astClone or astAnnul/astEnd for example) and -* includes the initial pointer issued when the Object was -* created. If the reference count for an Object falls to zero -* as the result of annulling a pointer to it, then the Object -* will be deleted. - -* Methods Over-Ridden: -* None. - -* New Methods Defined: -* Public: -* astAnnul -* Annul a pointer to an Object. -* astClear -* Clear attribute values for an Object. -* astClone -* Clone a pointer to an Object. -* astCopy -* Copy an Object. -* astDelete -* Delete an Object. -* astExempt -* Exempt an Object pointer from AST context handling -* astExport -* Export an Object pointer to an outer context. -* astGet, where = C, D, F, I, L -* Get an attribute value for an Object. -* astImport -* Import an Object pointer into the current context. -* astSame -* Return true if two pointers refer to the same object. -* astSet -* Set attribute values for an Object. -* astSet, where = C, D, F, I, L -* Set an attribute value for an Object. -* astShow -* Display a textual representation of an Object on standard output. -* astTest -* Test if an attribute value is set for an Object. -* astTune -* Get or set the value of a global AST tuning parameter. -* -* Protected: -* astAnnulId -* Annul an external ID for an Object (for use from protected code -* which must handle external IDs). -* astClearAttrib -* Clear the value of a specified attribute for an Object. -* astClearID -* Clear the value of the ID attribute for an Object. -* astClearIdent -* Clear the value of the Ident attribute for an Object. -* astCast -* Return a deep copy of an object, cast into an instance of a -* parent class. -* astDump -* Write an Object to a Channel. -* astEqual -* Are two Objects equivalent? -* astGetAttrib -* Get the value of a specified attribute for an Object. -* astGetClass (deprecated synonym astClass) -* Obtain the value of the Class attribute for an Object. -* astGetID -* Obtain the value of the ID attribute for an Object. -* astGetIdent -* Obtain the value of the Ident attribute for an Object. -* astGetNobject -* Obtain the value of the Nobject attribute for an Object. -* astGetRefCount -* Obtain the value of the RefCount attribute for an Object. -* astSetAttrib -* Set the value of a specified attribute for an Object. -* astSetCopy -* Declare a copy constructor for an Object. -* astSetDelete -* Declare a destructor for an Object. -* astSetDump -* Declare a dump function for an Object. -* astSetVtab -* Chaneg the virtual function table associated with an Object. -* astSetID -* Set the value of the ID attribute for an Object. -* astSetIdent -* Set the value of the Ident attribute for an Object. -* astTestAttrib -* Test if a specified attribute value is set for an Object. -* astTestID -* Test whether the ID attribute for an Object is set. -* astTestIdent -* Test whether the Ident attribute for an Object is set. -* astVSet -* Set values for an Object's attributes. - -* Other Class Functions: -* Public: -* astBegin -* Begin a new AST context. -* astEnd -* End an AST context. -* astIsAObject -* Test class membership. -* astVersion -* Returns the AST library version number. -* astEscapes -* Remove escape sequences from returned text strings? -* astP2I -* Retrieve an int from a pointer. -* astI2P -* Pack an int into a pointer. -* -* Protected: -* astCheckObject -* Validate class membership. -* astInitObject -* Initialise an Object. -* astInitObjectVtab -* Initialise the virtual function table for the Object class. -* astLoadObject -* Load an Object. -* astMakeId -* Issue an identifier for an Object. -* astMakePointer -* Obtain a true C pointer from an Object identifier. - -* Macros: -* Public: -* AST__NULL -* Null Object pointer value. -* AST__VMAJOR -* The AST library major version number. -* AST__VMINOR -* The AST library minor version number. -* AST__RELEASE -* The AST library release number. -* -* Protected: -* astEQUAL -* Compare two doubles for equality. -* astMAX -* Return maximum of two values. -* astMIN -* Return minimum of two values. -* astMAKE_CHECK -* Implement the astCheck_ function for a class. -* astMAKE_CLEAR -* Implement a method to clear an attribute value for a class. -* astMAKE_GET -* Implement a method to get an attribute value for a class. -* astMAKE_ISA -* Implement the astIsA_ function for a class. -* astMAKE_SET -* Implement a method to set an attribute value for a class. -* astMAKE_TEST -* Implement a method to test if an attribute has been set for a -* class. -* astMEMBER -* Locate a member function. - -* Type Definitions: -* Public: -* AstObject -* Object type. -* -* Protected: -* AstObjectVtab -* Object virtual function table type. - -* Feature Test Macros: -* AST_CHECK_CLASS -* If the AST_CHECK_CLASS macro is defined, then Object class -* checking is enabled for all internal function invocations -* within the AST library. Otherwise, this checking is -* omitted. This macro should normally be defined as a compiler -* option during library development and debugging, but left -* undefined for software releases, so as to improve -* peformance. Class checking by the AST public interface is not -* affected by this macro. -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. -* astFORTRAN77 -* If the astFORTRAN77 macro is defined, reporting of error -* context information is suppressed. This is necessary when -* implementing foreign language interfaces to the AST library, as -* otherwise the file names and line numbers given would refer -* to the interface implementation rather than the user's own -* code. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 30-JAN-1996 (RFWS): -* Original version. -* 19-APR-1996 (RFWS): -* Added macros for implementing attribute access methods. -* 3-JUL-1996 (RFWS): -* Added new definitions to support the external interface. -* 10-SEP-1996 (RFWS): -* Added loader and related facilities. -* 30-MAY-1997 (RFWS): -* Add the ID attribute. -* 14-JUL-1997 (RFWS): -* Add astExempt function. -* 20-JAN-1998 (RFWS): -* Make the astClear and astVSet methods virtual. -* 15-SEP-1999 (RFWS): -* Made the astAnnulId function accessible to protected code. -* 3-APR-2001 (DSB): -* Added Ident attribute. -* 8-JAN-2003 (DSB): -* Added protected astInitObjectVtab method. -* 30-APR-2003 (DSB): -* Added macros AST__VMAJOR, AST__VMINOR and AST__RELEASE. -* Added astVersion function. -* 7-FEB-2004 (DSB): -* Added astEscapes function. -* 11-MAR-2005 (DSB): -* Added UseDefs attribute. -* 7-FEB-2006 (DSB): -* Added astTune function. -* 14-FEB-2006 (DSB): -* Added ObjSize attribute. -* 23-FEB-2006 (DSB): -* Moved AST__TUNULL from this file to memory.h. -* 10-MAY-2006 (DSB): -* Added astEQUAL, astMAX and astMIN. -* 26-MAY-2006 (DSB): -* Make all system includes unconditional, so that makeh is not -* confused when creating ast.h. -* 22-JUN-2007 (DSB): -* - Make astVSet return a pointer to dynamic memory holding the -* expanded setting string. -* - Add ast astSetVtab and astCast. -* 22-APR-2008 (DSB): -* Added astSame. -* 7-APR-2010 (DSB): -* Added astHasAttribute. -*-- -*/ - -/* Include files. */ -/* ============== */ -/* Configuration results. */ -/* ---------------------- */ -#if HAVE_CONFIG_H -#include -#endif - -/* Interface definitions. */ -/* ---------------------- */ -#include "error.h" /* Error reporting facilities */ -#include "version.h" /* Version number macros */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -#if defined(THREAD_SAFE) -#include -#endif - -/* Macros. */ -/* ======= */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Set to "1" (yes) or "0" (no) to indicate if AST was build with threads - support. */ -#define AST__THREADSAFE @THREADS@ - -#if defined(astCLASS ) -#define AST__GETATTRIB_BUFF_LEN 50 /* Length of string returned by GetAttrib. */ -#define AST__ASTGETC_MAX_STRINGS 50 /* Number of string values to buffer within astGetC */ - -/* Values supplied to astManageLock */ -#define AST__LOCK 1 /* Lock the object */ -#define AST__UNLOCK 2 /* Unlock the object */ -#define AST__CHECKLOCK 3 /* Check if the object is locked */ - -/* Values returned by astThread */ -#define AST__UNLOCKED 1 /* Object is unlocked */ -#define AST__RUNNING 2 /* Object is locked by the running thread */ -#define AST__OTHER 3 /* Object is locked by another thread */ - -#endif - -/* Value that indicates that two classes are not in direct line from each - other. */ -#if defined(astCLASS ) -#define AST__COUSIN -1000000 -#endif - -/* Number of digits to use when formatting double precision floating point - values. DBL_DIG ensures no loss when round-tripping from text to - binary to text, but we want no loss when round-tripping from binary to - text to binary, so we use DBL_DECIMAL_DIG instead. If this is not - avaialable we use DBL_DIG but add on an extra 3 digits. */ -#ifdef DBL_DECIMAL_DIG - #define AST__DBL_DIG (DBL_DECIMAL_DIG) -#else - #define AST__DBL_DIG (DBL_DIG + 3) -#endif - -#ifdef FLT_DECIMAL_DIG - #define AST__FLT_DIG (FLT_DECIMAL_DIG) -#else - #define AST__FLT_DIG (FLT_DIG + 3) -#endif - - - - -/* -*+ -* Name: -* astINVOKE - -* Type: -* Protected macro. - -* Purpose: -* Invoke an AST function. - -* Synopsis: -* #include "object.h" -* astINVOKE(rettype,function) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro expands to an invocation of an AST function, together -* with any additional actions required to support it. The actual -* expansion depends on whether the macro is expanded in internal -* code (astCLASS defined) or external code (astCLASS undefined) -* and it therefore hides the differences between these two -* interfaces. - -* Parameters: -* rettype -* A character to indicate the type of result returned by the function: -* -* V -* The function returns a value (including void or a pointer -* value, but excluding an Object pointer). astINVOKE will -* return the value unchanged. -* O -* The function returns an Object pointer. astINVOKE will -* convert it to an Object identifier if necessary. -* F -* The function returns a function pointer. astINVOKE will -* return it unchanged. This is typically used when the -* function has a variable argument list. In this case the -* function name is passed to astINVOKE without its argument -* list and a pointer to the function is returned which can -* then be supplied with an argument list. This avoids the -* need to define a macro with a variable number of arguments -* (which isn't allowed). -* function -* A normal invocation of the function returning the required -* result. In the case of a variable argument list, the -* argument list should be omitted so that the function is not -* invoked but a function pointer is returned that may then be -* used to invoke it. - -* Examples: -* #define astGetNobject(this) \ -* astINVOKE(V,astGetNobject_(astCheckObject(this))) -* Defines a macro to invoke the astGetNobject_ function which -* returns an int. -* #define astClone(this) \ -* astINVOKE(O,astClone_(astCheckObject(this))) -* Defines a macro to invoke the astClone_ function which -* returns an Object pointer. -* #define astSet astINVOKE(F,astSet_) -* Defines a macro to invoke the astSet_ function which has a -* variable argument list and returns void. The macro result is -* a pointer to the astSet_ function. This function must perform -* its own argument validation, as (e.g) astCheckObject cannot -* be invoked on its arguments via a macro. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*- -*/ - -/* Define astINVOKE, which records the current file and line number - (in case of error) using astAt, and then invokes the function - supplied as an argument of the astRetV_, astRetO_ or astRetF_ - macro. - - Suppress reporting of the file and line number from internal code - and from foreign language interfaces by not using astAt in these - cases. */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define astINVOKE(rettype,function) astRet##rettype##_(function) -#else -#define astINVOKE(rettype,function) \ -astERROR_INVOKE(astRet##rettype##_(function)) -#endif - -/* astRetF_ and astRetV_ currently do nothing. */ -#define astRetF_(x) (x) -#define astRetV_(x) (x) - -/* However, astRetO_ converts a pointer to an ID if necessary. */ -#if defined(astCLASS) -#define astRetO_(x) ((void *)(x)) -#else -#define astRetO_(x) ((void *)astMakeId_((AstObject *)(x),STATUS_PTR)) -#endif - -/* -*+ -* Name: -* astINVOKE_CHECK -* astINVOKE_ISA - -* Type: -* Protected macros. - -* Purpose: -* Invoke the astCheck_ and astIsA_ functions. - -* Synopsis: -* #include "object.h" -* astINVOKE_CHECK(class,this,force) -* astINVOKE_ISA(class,this) - -* Class Membership: -* Defined by the Object class. - -* Description: -* These macros expand to invocations of the standard -* astCheck_ and astIsA_ functions for a class. - -* Parameters: -* class -* The name (not the type) of the class for which the function -* is to be invoked. -* this -* The "this" argument (the Object pointer) to be passed to the -* function. -* force -* Type checking takes time, and so can be disabled within the -* protected context in order to save time. Setting "force" to -* zero causes the astINVOKE_CHECK macro to skip the class check -* in a protected context (it assumes that AST "knows what it is -* doing"). Setting "force" to a non-zero value forces the class -* check even in a protected context. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*- -*/ - -/* For the public interface (and also internally if AST_CHECK_CLASS is - defined), define astINVOKE_CHECK to invoke the astCheck - function. */ -#if !defined(astCLASS) || defined(AST_CHECK_CLASS) -#define astINVOKE_CHECK(class,this,force) \ -astCheck##class##_((Ast##class *)astEnsurePointer_(this),astGetStatusPtr) - -/* For the internal interface, astINVOKE_CHECK omits the - astCheck function (unless AST_CHECK_CLASS is defined). */ -#else - -#define astINVOKE_CHECK(class,this,force) ( (force) ? \ - ( astCheck##class##_((Ast##class *)astEnsurePointer_(this),astGetStatusPtr) ) : \ - ( (Ast##class *) astEnsurePointer_(this) ) ) - -#endif - -/* Define astINVOKE_ISA to invoke the astIsA function. */ -#if defined(astCLASS) /* Protected */ -#define astINVOKE_ISA(class,this) \ -astIsA##class##_((const Ast##class *)(this),status) -#else /* Public */ -#define astINVOKE_ISA(class,this) \ -astINVOKE(V,astIsA##class##_((const Ast##class *)astEnsurePointer_(this),astGetStatusPtr)) -#endif - -/* The astEnsurePointer_ macro ensures a true C pointer, converting - from an ID if necessary. */ -#if defined(astCLASS) /* Protected */ -#define astEnsurePointer_(x) ((void *)(x)) -#else /* Public */ -#define astEnsurePointer_(x) ((void *)astCheckLock_(astMakePointer_((AstObject *)(x),STATUS_PTR),STATUS_PTR)) -#endif - -#if defined(astCLASS) /* Protected */ -/* -*+ -* Name: -* astMAKE_CHECK - -* Type: -* Protected macro. - -* Purpose: -* Implement the astCheck_ function for a class. - -* Synopsis: -* #include "object.h" -* astMAKE_CHECK(class) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro expands to an implementation of the public astCheck_ -* function (q.v.) which validates membership of a specified class. - -* Parameters: -* class -* The name (not the type) of the class whose membership is to be -* validated. - -* Notes: -* - This macro is provided so that class definitions can easiy -* implement the astCheck_ function, which is essentially the same -* for each class apart for a change of name. -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -#ifndef MEM_DEBUG - -/* Define the macro. */ -#define astMAKE_CHECK(class) \ -\ -/* Declare the function (see the object.c file for a prologue). */ \ -Ast##class *astCheck##class##_( Ast##class *this, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return this; \ -\ -/* Check if the object is a class member. */ \ - if ( !astIsA##class( this ) ) { \ -\ -/* If not, but the pointer was valid (which means it identifies an Object \ - of some sort), then report more information about why this Object is \ - unsuitable. */ \ - if ( astOK ) { \ - astError( AST__OBJIN, "Pointer to " #class " required, but pointer " \ - "to %s given.", status, astGetClass( this ) ); \ - } \ - } \ -\ -/* Return the pointer value supplied. */ \ - return this; \ -} - -/* Define the macro with memory debugging facilities. */ -#else - -#define astMAKE_CHECK(class) \ -\ -/* Declare the function (see the object.c file for a prologue). */ \ -Ast##class *astCheck##class##_( Ast##class *this, int *status ) { \ -\ - char buf[100]; \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return this; \ -\ -/* Check if the object is a class member. */ \ - if ( !astIsA##class( this ) ) { \ -\ -/* If not, but the pointer was valid (which means it identifies an Object \ - of some sort), then report more information about why this Object is \ - unsuitable. */ \ - if ( astOK ) { \ - astError( AST__OBJIN, "Pointer to " #class " required, but pointer " \ - "to %s given.", status, astGetClass( this ) ); \ - }\ -\ - } else { \ -\ -/* Call the astMemoryUse function to report it if the memory block is \ - being watched. */ \ - sprintf( buf, "checked (refcnt: %d)", astGetRefCount_( (AstObject *) this, status ) ); \ - astMemoryUse( this, buf ); \ - } \ -\ -/* Return the pointer value supplied. */ \ - return this; \ -} -#endif -#endif - -#if defined(astCLASS) /* Protected */ -/* -*+ -* Name: -* astMAKE_CLEAR - -* Purpose: -* Implement a method to clear an attribute value for a class. - -* Type: -* Protected macro. - -* Synopsis: -* #include "object.h" -* astMAKE_CLEAR(class,attribute,component,assign) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( Ast *this ) -* -* and an external interface function of the form: -* -* void astClear_( Ast *this ) -* -* which implement a method for clearing a specified attribute value for -* a class. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attribute -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. Label in "astClearLabel"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. - -* Examples: -* astMAKE_CLEAR(MyStuff,Flag,flag,-1) -* Implements the astClearFlag method for the MyStuff class which -* operates by setting the "flag" structure component to -1 to indicate -* that it has no value. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define astMAKE_CLEAR(class,attribute,component,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attribute( Ast##class *this, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return; \ -\ -/* Assign the "clear" value. */ \ - this->component = (assign); \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attribute##_( Ast##class *this, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,class,Clear##attribute))( this, status ); \ -} -#endif - -#if defined(astCLASS) /* Protected */ -/* -*+ -* Name: -* astMAKE_CLEAR1 - -* Purpose: -* Implement a method to clear an attribute value for a class, reporting -* an error if the object has more than one reference. - -* Type: -* Protected macro. - -* Synopsis: -* #include "object.h" -* astMAKE_CLEAR1(class,attribute,component,assign) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( Ast *this ) -* -* and an external interface function of the form: -* -* void astClear_( Ast *this ) -* -* which implement a method for clearing a specified attribute value for -* a class. An error is reported if the object has a reference count that -* is greater than one. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attribute -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. Label in "astClearLabel"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define astMAKE_CLEAR1(class,attribute,component,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attribute( Ast##class *this, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return; \ -\ -/* Report an error if the object has been cloned (i.e. has a reference \ - count that is greater than one). */ \ - if( astGetRefCount( this ) > 1 ) { \ - astError( AST__IMMUT, "astClear(%s): The " #attribute "attribute of " \ - "the supplied %s cannot be cleared because the %s has " \ - "been cloned (programming error).", status, \ - astGetClass(this), astGetClass(this), astGetClass(this) ); \ -\ -/* Otherwise, assign the "clear" value in the structure component. */ \ - } else { \ - this->component = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attribute##_( Ast##class *this, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,class,Clear##attribute))( this, status ); \ -} -#endif - -#if defined(astCLASS) /* Protected */ -/* -*+ -* Name: -* astMAKE_GET - -* Purpose: -* Implement a method to get an attribute value for a class. - -* Type: -* Protected macro. - -* Synopsis: -* #include "object.h" -* astMAKE_GET(class,attribute,type,bad_value,assign) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( Ast *this ) -* -* and an external interface function of the form: -* -* astGet_( Ast *this ) -* -* which implement a method for getting a specified attribute value for a -* class. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attribute -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the inherited error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. - -* Examples: -* astMAKE_GET(MyStuff,Flag,int,0,( this->flag == 1 )) -* Implements the astGetFlag method for the MyStuff class which operates -* by examining the integer "flag" structure component and comparing it -* with the value 1 to see if it is set. A value of 0 is returned if the -* method fails to complete successfully. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define astMAKE_GET(class,attribute,type,bad_value,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attribute( Ast##class *this, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Assign the result value. */ \ - result = (assign); \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -type astGet##attribute##_( Ast##class *this, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,class,Get##attribute))( this, status ); \ -} -#endif - -#if defined(astCLASS) /* Protected */ -/* -*+ -* Name: -* astMAKE_ISA - -* Type: -* Protected macro. - -* Purpose: -* Implement the astIsA_ function for a class. - -* Synopsis: -* #include "object.h" -* astMAKE_ISA(class,parent) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro expands to an implementation of the public -* astIsA_ function (q.v.) which checks membership of a -* specified class. - -* Parameters: -* class -* The name (not the type) of the class whose membership is to be -* tested. -* parent -* The name of the parent class. - -* Notes: -* - This macro is provided so that class definitions can easiy -* implement the astIsA_ function, which is essentially the -* same for each class apart for a change of name. -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define astMAKE_ISA(class,parent) \ -\ -/* Declare the function (see the object.c file for a prologue). */ \ -int astIsA##class##_( const Ast##class *this, int *status ) { \ -\ -/* Local Variables: */ \ - int isa = 0; /* Is object a member? */ \ -\ -/* To test if the object is correctly constructed, we first test if it is a \ - member of the parent class. This improves the security of the test by \ - checking the object structure from the base Object class downwards \ - (without this, the "magic numbers" that identify classes might be \ - encountered by accident or we might address parts of the Object which \ - don't exist). */ \ - if ( astIsA##parent( this ) ) { \ -\ -/* Obtain the Object's size and check it is adequate for an object of the \ - proposed type (this avoids any attempt to access derived class data that \ - doesn't exist and therefore lies outside the memory allocated for the \ - object). */ \ - if ( ( (AstObject *) this )->size >= sizeof( Ast##class ) ) { \ -\ -/* If OK, see whether the check component in the object's virtual function \ - table matches the expected "magic" value. */ \ - isa = ( *astMEMBER(this,class,id.check) == &class_check ); \ - } \ - } \ -\ -/* Return the result. */ \ - return isa; \ -} -#endif - -#if defined(astCLASS) /* Protected */ -/* -*+ -* Name: -* astMAKE_SET - -* Purpose: -* Implement a method to set an attribute value for a class. - -* Type: -* Protected macro. - -* Synopsis: -* #include "object.h" -* astMAKE_SET(class,attribute,type,component,assign) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( Ast *this, value ) -* -* and an external interface function of the form: -* -* void astSet_( Ast *this, value ) -* -* which implement a method for setting a specified attribute value for a -* class. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attribute -* The name of the attribute to be set, as it appears in the function -* name (e.g. Label in "astSetLabel"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. - -* Examples: -* astMAKE_SET(MyStuff,Flag,int,flag,( value != 0 )) -* Implements the astSetFlag method for the MyStuff class which operates -* by setting the "flag" structure component to 0 or 1 depending on -* whether the "value" parameter is non-zero or not. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define astMAKE_SET(class,attribute,type,component,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attribute( Ast##class *this, type value, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return; \ -\ -/* Store the new value in the structure component. */ \ - this->component = (assign); \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attribute##_( Ast##class *this, type value, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,class,Set##attribute))( this, value, status ); \ -} -#endif - -#if defined(astCLASS) /* Protected */ -/* -*+ -* Name: -* astMAKE_SET1 - -* Purpose: -* Implement a method to set an attribute value for a class, reporting -* an error if the object has more than one reference. - -* Type: -* Protected macro. - -* Synopsis: -* #include "object.h" -* astMAKE_SET1(class,attribute,type,component,assign) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( Ast *this, value ) -* -* and an external interface function of the form: -* -* void astSet_( Ast *this, value ) -* -* which implement a method for setting a specified attribute value for a -* class. An error is reported if the object has a reference count that -* is greater than one. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attribute -* The name of the attribute to be set, as it appears in the function -* name (e.g. Label in "astSetLabel"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. - -*- -*/ - -/* Define the macro. */ -#define astMAKE_SET1(class,attribute,type,component,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attribute( Ast##class *this, type value, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return; \ -\ -/* Report an error if the object has been cloned (i.e. has a reference \ - count that is greater than one). */ \ - if( astGetRefCount( this ) > 1 ) { \ - astError( AST__IMMUT, "astSet(%s): The " #attribute "attribute of " \ - "the supplied %s cannot be changed because the %s has " \ - "been cloned (programming error).", status, \ - astGetClass(this), astGetClass(this), astGetClass(this) ); \ -\ -/* Otherwise, store the new value in the structure component. */ \ - } else { \ - this->component = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attribute##_( Ast##class *this, type value, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,class,Set##attribute))( this, value, status ); \ -} -#endif - -#if defined(astCLASS) /* Protected */ -/* -*+ -* Name: -* astMAKE_TEST - -* Purpose: -* Implement a method to test if an attribute has been set for a class. - -* Type: -* Protected macro. - -* Synopsis: -* #include "object.h" -* astMAKE_TEST(class,attribute,assign) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static int Test( Ast *this ) -* -* and an external interface function of the form: -* -* int astTest_( Ast *this ) -* -* which implement a method for testing if a specified attribute has been -* set for a class. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attribute -* The name of the attribute to be tested, as it appears in the function -* name (e.g. Label in "astTestLabel"). -* assign -* An expression that evaluates to 0 or 1, to be used as the returned -* value. - -* Examples: -* astMAKE_TEST(MyStuff,Flag,( this->flag != -1 )) -* Implements the astTestFlag method for the MyStuff class which operates -* by testing the "flag" structure component to see if it is set to a -* value other than -1. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define astMAKE_TEST(class,attribute,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static int Test##attribute( Ast##class *this, int *status ) { \ - int result; /* Value to return */ \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Assign the result value. */ \ - result = (assign); \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -int astTest##attribute##_( Ast##class *this, int *status ) { \ -\ -/* Check the inherited error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,class,Test##attribute))( this, status ); \ -} -#endif - -#if defined(astCLASS) /* Protected */ -/* -*+ -* Name: -* astMEMBER - -* Purpose: -* Locate a member function. - -* Type: -* Protected macro. - -* Synopsis: -* #include "object.h" -* astMEMBER(this,class,method) - -* Class Membership: -* Defined by the Object class. - -* Description: -* This macro evaluates to the address where the pointer to a -* specified Object member function is stored. Typically, this will -* be used to obtain a pointer to the member function so that it -* can be invoked. It may also be used to assign a new function -* pointer so that a derived class can re-define a virtual function -* and hence over-ride an inherited method. - -* Parameters: -* this -* Pointer to an Object belonging to the class for which the -* virtual function is required. This must either be the class -* that originally defined the method, or one derived from it. -* class -* Name of the class that originally defined the method. This -* may differ from (i.e. be an ancestor of) the class to which -* "this" belongs. -* method -* Name of the method whose member function is to be located. - -* Returned Value: -* The address where the member function pointer is stored (the -* type of the result is determined by the type of the member -* function itself). - -* Examples: -* astMEMBER(this,Gnome,astFish) -* Returns the address where the pointer to the function that -* implements the astFish method for the "this" object is -* stored. The Gnome class should be where the astFish method -* was first defined (i.e. from where it was inherited by -* "this"). -* (**astMEMBER(this,Gnome,astFish))( this, arg1, arg2 ); -* Invokes the virtual function that implements the astFish -* method for object "this" and passes it additional arguments -* "arg2" and "arg2". Again, Gnome should be the class that -* originally defined the astFish method. -* *astMEMBER(this,Gnome,astFish) = myFish; -* Stores a pointer to the myFish function so that it replaces -* the virtual function that previously implemented the astFish -* method for the "this" object. Note that all objects in the -* same class as "this" are affected, but objects in class -* "class" are not affected (unless it happens to be the class -* to which "this" belongs). - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*- -*/ - -/* A subsiduary macro that returns a pointer to the vtab of an object, - cast to an AstObjectVtab. */ -#define astVTAB(this) (((AstObject*)(this))->vtab) - -/* Define the macro. This functions by (a) casting the Object pointer - to type (AstObject *) and locating the Object's virtual function - table (b) casting the table pointer to the correct type - (AstClassVtab *) for the class in which the method pointer resides, - (c) locating the component holding the member function pointer, and - (d) taking its address. */ -#define astMEMBER(this,class,method) \ -(&((Ast##class##Vtab*)astVTAB(this))->method) - -#endif - -/* -*+ -* Name: -* astPROTO_CHECK -* astPROTO_ISA - -* Type: -* Protected macros. - -* Purpose: -* Prototype the astCheck_ and astIsA_ functions. - -* Synopsis: -* #include "object.h" -* astPROTO_CHECK(class) -* astPROTO_ISA(class) - -* Class Membership: -* Defined by the Object class. - -* Description: -* These macros expands to function prototypes for the -* astCheck_ and astIsA_ functions (q.v.) which -* validate and test for membership of a specified class. - -* Parameters: -* class -* The name (not the type) of the class whose membership is to -* be validated. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*- -*/ - -/* Define the macros. */ -#define astPROTO_CHECK(class) Ast##class *astCheck##class##_( Ast##class *, int * ); -#define astPROTO_ISA(class) int astIsA##class##_( const Ast##class *, int * ); - -/* Macros which return the maximum and minimum of two values. */ -#define astMAX(aa,bb) ((aa)>(bb)?(aa):(bb)) -#define astMIN(aa,bb) ((aa)<(bb)?(aa):(bb)) - -/* Check for equality of floating point values. We cannot compare bad values - directly because of the danger of floating point exceptions, so bad - values are dealt with explicitly. */ -#define astEQUALS(aa,bb,tol) (((aa)==AST__BAD)?(((bb)==AST__BAD)?1:0):(((bb)==AST__BAD)?0:(fabs((aa)-(bb))<=(tol)*astMAX((fabs(aa)+fabs(bb))*DBL_EPSILON,DBL_MIN)))) -#define astEQUAL(aa,bb) astEQUALS(aa,bb,1.0E5) - - -/* AST__NULL. */ -/* ---------- */ -/* Define the AST__NULL macro, which evaluates to a null Object - pointer. */ -#define AST__NULL (astI2P(0)) - - -#if defined(astCLASS) /* Protected */ - -/* Test the validy of an attribute value */ -/* ------------------------------------- */ -/* If the set attribute value is invalid, clear it. These macros should - be used in a context in which error reporting has been deferred by - calling astReporting( 0 ). */ - -#define astCLEAN_ATTRIB(attr) \ - if( astTest##attr(this) ) { \ - astSet##attr( this, astGet##attr( this ) ); \ - if( !astOK ) { \ - astClearStatus; \ - astClear##attr( this ); \ - } \ - } - -#define astCLEAN_INDEXED_ATTRIB(attr,index) \ - if( astTest##attr(this,index) ) { \ - astSet##attr( this, index, astGet##attr( this, index ) ); \ - if( !astOK ) { \ - astClearStatus; \ - astClear##attr( this, index ); \ - } \ - } - -#endif - - -#if defined(astCLASS) /* Protected */ -#define astSetVtabClassIdentifier(vtab,id_ptr) \ - ((AstObjectVtab *)(vtab))->top_id = (id_ptr) -#endif - -/* Type Definitions. */ -/* ================= */ - -/* Object structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstObject { - -/* Attributes specific to objects in this class. */ - unsigned long check; /* Check value to identify Objects */ - size_t size; /* Amount of memory used by Object */ - struct AstObjectVtab *vtab; /* Pointer to virtual function table */ - char dynamic; /* Memory allocated dynamically? */ - int ref_count; /* Number of active pointers to the Object */ - char *id; /* Pointer to ID string */ - char *ident; /* Pointer to Ident string */ - char usedefs; /* Use default attribute values? */ - int iref; /* Object index (unique within class) */ - void *proxy; /* A pointer to an external object that - acts as a foreign language proxy for the - AST object */ -#if defined(THREAD_SAFE) - int locker; /* Thread that has locked this Object */ - pthread_mutex_t mutex1; /* Guards access to all elements of the - Object except for the "locker" and - "ref_count" components */ - pthread_mutex_t mutex2; /* Guards access to the "locker" and - "ref_count" components */ - struct AstGlobals *globals; /* Pointer to thread-specific global data */ -#endif - -} AstObject; - -/* Class identifier structure */ -typedef struct AstClassIdentifier { - int *check; - struct AstClassIdentifier *parent; -} AstClassIdentifier; - -/* Virtual function table. */ -/* ----------------------- */ -/* The virtual function table makes a forward reference to the - AstChannel structure which is not defined until "channel.h" is - included (below). Hence make a preliminary definition available - now. */ -struct AstChannel; -struct KeyMap; - -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstObjectVtab { - -/* A unique identifier for this class. */ - AstClassIdentifier id; - -/* Pointer to the structure that identifies the top-level class described - by the whole vtab (of which the AstObjectVtab is just the first, - lowest-level, component). */ - AstClassIdentifier *top_id; - -/* Pointer to a dynamically allocated string holding the default - attribute values to use when creating new objects. These are read from - environment variables of the form "_OPTIONS". */ - const char *defaults; - -/* Properties specific to this class. */ - void ( *CleanAttribs )( AstObject *, int * ); - AstObject *( *Cast )( AstObject *, AstObject *, int * ); - const char *( *GetID )( AstObject *, int * ); - const char *( *GetIdent )( AstObject *, int * ); - const char *(* GetAttrib)( AstObject *, const char *, int * ); - int (* TestAttrib)( AstObject *, const char *, int * ); - int (* TestID)( AstObject *, int * ); - int (* Same)( AstObject *, AstObject *, int * ); - int (* HasAttribute)( AstObject *, const char *, int * ); - int (* TestIdent)( AstObject *, int * ); - void (* Clear)( AstObject *, const char *, int * ); - void (* ClearAttrib)( AstObject *, const char *, int * ); - void (* ClearID)( AstObject *, int * ); - void (* ClearIdent)( AstObject *, int * ); - void (* Dump)( AstObject *, struct AstChannel *, int * ); - int (* Equal)( AstObject *, AstObject *, int * ); - void (* SetAttrib)( AstObject *, const char *, int * ); - void (* SetID)( AstObject *, const char *, int * ); - void (* SetIdent)( AstObject *, const char *, int * ); - void (* Show)( AstObject *, int * ); - void (* VSet)( AstObject *, const char *, char **, va_list, int * ); - void (* EnvSet)( AstObject *, int * ); - - void *(* GetProxy)( AstObject *, int * ); - void (* SetProxy)( AstObject *, void *, int * ); - - int (* GetObjSize)( AstObject *, int * ); - - int (* TestUseDefs)( AstObject *, int * ); - int (* GetUseDefs)( AstObject *, int * ); - void (* SetUseDefs)( AstObject *, int, int * ); - void (* ClearUseDefs)( AstObject *, int * ); - - const char *class; /* Pointer to class name string */ - void (** delete)( AstObject *, int * ); /* Pointer to array of destructors */ - void (** copy)( const AstObject *, AstObject *, int * ); /* Copy constructors */ - void (** dump)( AstObject *, struct AstChannel *, int * ); /* Dump functions */ - const char **dump_class; /* Dump function class string pointers */ - const char **dump_comment; /* Dump function comment string pointers */ - int ndelete; /* Number of destructors */ - int ncopy; /* Number of copy constructors */ - int ndump; /* Number of dump functions */ - int nobject; /* Number of active objects in the class */ - int nfree; /* No. of entries in "free_list" */ - AstObject **free_list; /* List of pointers for freed Objects */ - -#if defined(THREAD_SAFE) - int (* ManageLock)( AstObject *, int, int, AstObject **, int * ); -#endif - -} AstObjectVtab; -#endif - -#if defined(THREAD_SAFE) && defined(astCLASS) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstObjectGlobals { - AstObjectVtab Class_Vtab; - int Class_Init; - int Retain_Esc; - int Context_Level; - int *Active_Handles; - char GetAttrib_Buff[ AST__GETATTRIB_BUFF_LEN + 1 ]; - char *AstGetC_Strings[ AST__ASTGETC_MAX_STRINGS ]; - int AstGetC_Istr; - int AstGetC_Init; - int Nvtab; - AstObjectVtab **Known_Vtabs; -} AstObjectGlobals; - -#endif - -/* More include files. */ -/* =================== */ -/* The interface to the Channel class must be included here (after the - type definitions for the Object class) because "channel.h" itself - includes this file ("object.h"), although "object.h" refers to the - AstChannel structure above. This seems a little strange at first, - but is simply analogous to making a forward reference to a - structure type when recursively defining a normal C structure - (except that here the definitions happen to be in separate include - files). */ -#include "channel.h" - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Object) /* Validate class membership */ -astPROTO_ISA(Object) /* Test class membership */ - -/* NB. There is no constructor function for this class. */ - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstObject *astInitObject_( void *, size_t, int, AstObjectVtab *, - const char *, int * ); - -/* Vtab Initialiser. */ -void astInitObjectVtab_( AstObjectVtab *, const char *, int * ); - -/* Loader. */ -AstObject *astLoadObject_( void *, size_t, AstObjectVtab *, - const char *, AstChannel *channel, int * ); - -#if defined(THREAD_SAFE) -void astInitObjectGlobals_( AstObjectGlobals * ); -#endif - -#endif - -/* Prototypes for other class functions. */ -/* ------------------------------------- */ -#if !defined(astCLASS) /* Public */ -void astBegin_( void ); -void astEnd_( int * ); -#endif - -AstObject *astI2P_( int, int * ); -AstObject *astMakeId_( AstObject *, int * ); -AstObject *astMakePointer_( AstObject *, int * ); -AstObject *astMakePointer_NoLockCheck_( AstObject *, int * ); -int astP2I_( AstObject *, int * ); -int astVersion_( int * ); -int astEscapes_( int, int * ); -int astTune_( const char *, int, int * ); -void astTuneC_( const char *, const char *, char *, int, int * ); - -/* Prototypes for member functions. */ -/* -------------------------------- */ -#if defined(astCLASS) /* Protected */ -AstObject *astAnnul_( AstObject *, int * ); -AstObject *astDelete_( AstObject *, int * ); -void astSet_( void *, const char *, int *, ... ); - -#else /* Public */ -AstObject *astDeleteId_( AstObject *, int * ); -int astThreadId_( AstObject *, int, int * ); -void astExportId_( AstObject *, int * ); -void astImportId_( AstObject *, int * ); -void astSetId_( void *, const char *, ... )__attribute__((format(printf,2,3))); -#endif - -struct AstKeyMap *astActiveObjects_( const char *, int, int, int *); -AstObject *astAnnulId_( AstObject *, int * ); -AstObject *astCheckLock_( AstObject *, int * ); -AstObject *astClone_( AstObject *, int * ); -AstObject *astCopy_( const AstObject *, int * ); -AstObject *astFromString_( const char *, int * ); -char *astToString_( AstObject *, int * ); -const char *astGetC_( AstObject *, const char *, int * ); -double astGetD_( AstObject *, const char *, int * ); -float astGetF_( AstObject *, const char *, int * ); -int astEqual_( AstObject *, AstObject *, int * ); -int astGetI_( AstObject *, const char *, int * ); -int astHasAttribute_( AstObject *, const char *, int * ); -int astSame_( AstObject *, AstObject *, int * ); -int astTest_( AstObject *, const char *, int * ); -long astGetL_( AstObject *, const char *, int * ); -void astCreatedAtId_( AstObject *, const char **, const char **, int *, int *); -void *astGetProxy_( AstObject *, int * ); -void astClear_( AstObject *, const char *, int * ); -void astExemptId_( AstObject *, int * ); -void astLockId_( AstObject *, int, int * ); -void astSetC_( AstObject *, const char *, const char *, int * ); -void astSetD_( AstObject *, const char *, double, int * ); -void astSetF_( AstObject *, const char *, float, int * ); -void astSetI_( AstObject *, const char *, int, int * ); -void astSetL_( AstObject *, const char *, long, int * ); -void astSetProxy_( AstObject *, void *, int * ); -void astShow_( AstObject *, int * ); -void astUnlockId_( AstObject *, int, int * ); - -#if defined(astCLASS) /* Protected */ - -void astCleanAttribs_( AstObject *, int * ); -AstObject *astCast_( AstObject *, AstObject *, int * ); -AstObject *astCastCopy_( AstObject *, AstObject *, int * ); - -#if defined(THREAD_SAFE) -int astManageLock_( AstObject *, int, int, AstObject **, int * ); -#endif - -int astGetObjSize_( AstObject *, int * ); - -int astTestUseDefs_( AstObject *, int * ); -int astGetUseDefs_( AstObject *, int * ); -void astSetUseDefs_( AstObject *, int, int * ); -void astClearUseDefs_( AstObject *, int * ); - -const char *astGetAttrib_( AstObject *, const char *, int * ); -const char *astGetClass_( const AstObject *, int * ); -const char *astGetID_( AstObject *, int * ); -const char *astGetIdent_( AstObject *, int * ); -int astClassCompare_( AstObjectVtab *, AstObjectVtab *, int * ); -int astGetNobject_( const AstObject *, int * ); -int astGetRefCount_( AstObject *, int * ); -int astTestAttrib_( AstObject *, const char *, int * ); -int astTestID_( AstObject *, int * ); -int astTestIdent_( AstObject *, int * ); -void astClearAttrib_( AstObject *, const char *, int * ); -void astClearID_( AstObject *, int * ); -void astClearIdent_( AstObject *, int * ); -void astDump_( AstObject *, AstChannel *, int * ); -void astSetAttrib_( AstObject *, const char *, int * ); -void astSetCopy_( AstObjectVtab *, void (*)( const AstObject *, AstObject *, int * ), int * ); -void astSetDelete_( AstObjectVtab *, void (*)( AstObject *, int * ), int * ); -void astSetDump_( AstObjectVtab *, void (*)( AstObject *, AstChannel *, int * ), const char *, const char *, int * ); -void astSetVtab_( AstObject *, AstObjectVtab *, int * ); -void astSetID_( AstObject *, const char *, int * ); -void astSetIdent_( AstObject *, const char *, int * ); -void astEnvSet_( AstObject *, int * ); -void astVSet_( AstObject *, const char *, char **, va_list, int * ); - -#endif - - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Check class membership. */ -#define astCheckObject(this) astINVOKE_CHECK(Object,this,0) -#define astVerifyObject(this) astINVOKE_CHECK(Object,this,1) - -/* Test class membership. */ -#define astIsAObject(this) astINVOKE_ISA(Object,this) - -/* NB. There is no constructor function for this class. */ - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitObject(mem,size,init,vtab,name) \ -astINVOKE(O,astInitObject_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitObjectVtab(vtab,name) astINVOKE(V,astInitObjectVtab_(vtab,name,STATUS_PTR)) - -/* Loader. */ -#define astLoadObject(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadObject_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to other class functions. */ -/* ------------------------------------ */ -#if !defined(astCLASS) /* Public */ -#define astBegin astBegin_() -#define astEnd astINVOKE(V,astEnd_(STATUS_PTR)) -#else /* Protected */ -#define astMakePointer_NoLockCheck(id) ((void *)astMakePointer_NoLockCheck_((AstObject *)(id),STATUS_PTR)) -#endif - -#define astVersion astVersion_(STATUS_PTR) -#define astEscapes(int) astEscapes_(int,STATUS_PTR) -#define astTune(name,val) astTune_(name,val,STATUS_PTR) -#define astTuneC(name,value,buff,bufflen) astTuneC_(name,value,buff,bufflen,STATUS_PTR) -#define astI2P(integer) ((void *)astI2P_(integer,STATUS_PTR)) -#define astMakeId(pointer) ((void *)astMakeId_((AstObject *)(pointer),STATUS_PTR)) -#define astP2I(pointer) astP2I_((AstObject *)(pointer),STATUS_PTR) -#define astMakePointer(id) ((void *)astCheckLock_(astMakePointer_((AstObject *)(id),STATUS_PTR),STATUS_PTR)) -#define astToString(this) astINVOKE(V,astToString_(astCheckObject(this),STATUS_PTR)) -#define astFromString(string) astINVOKE(O,astFromString_(string,STATUS_PTR)) -#define astCreatedAt(this,routine,file,line) astINVOKE(V,astCreatedAtId_((AstObject *)this,routine,file,line,STATUS_PTR)) -#define astActiveObjects(class,subclass,current) astINVOKE(O,astActiveObjects_(class,subclass,current,STATUS_PTR)) - - -/* Interfaces to member functions. */ -/* ------------------------------- */ -/* Here we make use of astCheckObject (et al.) to validate Object - pointers before use. This provides a contextual error report if a - pointer to the wrong sort of object is supplied. In the case of an - external caller, it also performs the required conversion from an - Object identifier to a true C pointer. */ - -/* These functions require special treatment for external use because - they handle Object identifiers and their resources explicitly, and - must therefore be passed identifier values without conversion to C - pointers. */ - -#if defined(astCLASS) || defined(astFORTRAN77) /* Protected or Fotran interface */ -#define astAnnulId(this) astINVOKE(O,astAnnulId_((AstObject *)(this),STATUS_PTR)) -#endif - -#if defined(astCLASS) /* Protected only */ -#define astAnnul(this) astINVOKE(O,astAnnul_(astCheckObject(this),STATUS_PTR)) -#define astDelete(this) astINVOKE(O,astDelete_(astCheckObject(this),STATUS_PTR)) -#define astSet astINVOKE(F,astSet_) - -#else /* Public only */ -#define astAnnul(this) astINVOKE(O,astAnnulId_((AstObject *)(this),STATUS_PTR)) -#define astDelete(this) astINVOKE(O,astDeleteId_((AstObject *)(this),STATUS_PTR)) -#define astExport(this) astINVOKE(V,astExportId_((AstObject *)(this),STATUS_PTR)) -#define astImport(this) astINVOKE(V,astImportId_((AstObject *)(this),STATUS_PTR)) -#define astSet astINVOKE(F,astSetId_) -#define astThread(this,ptr) astINVOKE(V,astThreadId_((AstObject *)(this),ptr,STATUS_PTR)) -#endif - -/* Both.... */ -#define astLock(this,wait) astINVOKE(V,astLockId_((AstObject *)(this),wait,STATUS_PTR)) -#define astUnlock(this,report) astINVOKE(V,astUnlockId_((AstObject *)(this),report,STATUS_PTR)) -#define astEqual(this,that) astINVOKE(V,(((AstObject*)this==(AstObject*)that)||astEqual_(astCheckObject(this),astCheckObject(that),STATUS_PTR))) -#define astExempt(this) astINVOKE(V,astExemptId_((AstObject *)(this),STATUS_PTR)) -#define astClear(this,attrib) astINVOKE(V,astClear_(astCheckObject(this),attrib,STATUS_PTR)) -#define astClone(this) astINVOKE(O,astClone_(astCheckObject(this),STATUS_PTR)) -#define astCopy(this) astINVOKE(O,astCopy_(astCheckObject(this),STATUS_PTR)) -#define astGetC(this,attrib) astINVOKE(V,astGetC_(astCheckObject(this),attrib,STATUS_PTR)) -#define astGetD(this,attrib) astINVOKE(V,astGetD_(astCheckObject(this),attrib,STATUS_PTR)) -#define astGetF(this,attrib) astINVOKE(V,astGetF_(astCheckObject(this),attrib,STATUS_PTR)) -#define astGetI(this,attrib) \ -astINVOKE(V,astGetI_(astCheckObject(this),attrib,STATUS_PTR)) -#define astGetL(this,attrib) \ -astINVOKE(V,astGetL_(astCheckObject(this),attrib,STATUS_PTR)) -#define astSetC(this,attrib,value) \ -astINVOKE(V,astSetC_(astCheckObject(this),attrib,value,STATUS_PTR)) -#define astSetD(this,attrib,value) \ -astINVOKE(V,astSetD_(astCheckObject(this),attrib,value,STATUS_PTR)) -#define astSetF(this,attrib,value) \ -astINVOKE(V,astSetF_(astCheckObject(this),attrib,value,STATUS_PTR)) -#define astSetI(this,attrib,value) \ -astINVOKE(V,astSetI_(astCheckObject(this),attrib,value,STATUS_PTR)) -#define astSetL(this,attrib,value) \ -astINVOKE(V,astSetL_(astCheckObject(this),attrib,value,STATUS_PTR)) -#define astShow(this) \ -astINVOKE(V,astShow_(astCheckObject(this),STATUS_PTR)) -#define astTest(this,attrib) \ -astINVOKE(V,astTest_(astCheckObject(this),attrib,STATUS_PTR)) -#define astSame(this,that) \ -astINVOKE(V,astSame_(astCheckObject(this),astCheckObject(that),STATUS_PTR)) -#define astHasAttribute(this,attrib) \ -astINVOKE(V,astHasAttribute_(astCheckObject(this),attrib,STATUS_PTR)) -#define astGetProxy(this) \ -astINVOKE(V,astGetProxy_(astCheckObject(this),STATUS_PTR)) -#define astSetProxy(this,proxy) \ -astINVOKE(V,astSetProxy_(astCheckObject(this),proxy,STATUS_PTR)) - - -#if defined(astCLASS) /* Protected */ - -#if defined(THREAD_SAFE) -#define astManageLock(this,mode,extra,fail) \ -astINVOKE(V,astManageLock_(astCheckObject(this),mode, extra,fail,STATUS_PTR)) -#else -#define astManageLock(this,mode,extra,fail) -#endif - -#define astCleanAttribs(this) astINVOKE(V,astCleanAttribs_(astCheckObject(this),STATUS_PTR)) -#define astGetObjSize(this) astINVOKE(V,astGetObjSize_(astCheckObject(this),STATUS_PTR)) -#define astCast(this,obj) astINVOKE(O,astCast_(astCheckObject(this),astCheckObject(obj),STATUS_PTR)) -#define astCastCopy(this,obj) astCastCopy_((AstObject*)this,(AstObject*)obj,STATUS_PTR) - -#define astClearUseDefs(this) astINVOKE(V,astClearUseDefs_(astCheckObject(this),STATUS_PTR)) -#define astTestUseDefs(this) astINVOKE(V,astTestUseDefs_(astCheckObject(this),STATUS_PTR)) -#define astGetUseDefs(this) astINVOKE(V,astGetUseDefs_(astCheckObject(this),STATUS_PTR)) -#define astSetUseDefs(this,val) astINVOKE(V,astSetUseDefs_(astCheckObject(this),val,STATUS_PTR)) - -#define astClearAttrib(this,attrib) \ -astINVOKE(V,astClearAttrib_(astCheckObject(this),attrib,STATUS_PTR)) -#define astClearID(this) astINVOKE(V,astClearID_(astCheckObject(this),STATUS_PTR)) -#define astClearIdent(this) astINVOKE(V,astClearIdent_(astCheckObject(this),STATUS_PTR)) -#define astDump(this,channel) \ -astINVOKE(V,astDump_(astCheckObject(this),astCheckChannel(channel),STATUS_PTR)) - -#define astGetAttrib(this,attrib) \ -astINVOKE(V,astGetAttrib_(astCheckObject(this),attrib,STATUS_PTR)) -#define astGetClass(this) astINVOKE(V,astGetClass_((const AstObject *)(this),STATUS_PTR)) -#define astGetID(this) astINVOKE(V,astGetID_(astCheckObject(this),STATUS_PTR)) -#define astGetIdent(this) astINVOKE(V,astGetIdent_(astCheckObject(this),STATUS_PTR)) -#define astGetNobject(this) astINVOKE(V,astGetNobject_(astCheckObject(this),STATUS_PTR)) -#define astClassCompare(class1,class2) astClassCompare_(class1,class2,STATUS_PTR) -#define astGetRefCount(this) astINVOKE(V,astGetRefCount_(astCheckObject(this),STATUS_PTR)) -#define astSetAttrib(this,setting) \ -astINVOKE(V,astSetAttrib_(astCheckObject(this),setting,STATUS_PTR)) -#define astSetCopy(vtab,copy) \ -astINVOKE(V,astSetCopy_((AstObjectVtab *)(vtab),copy,STATUS_PTR)) -#define astSetDelete(vtab,delete) \ -astINVOKE(V,astSetDelete_((AstObjectVtab *)(vtab),delete,STATUS_PTR)) -#define astSetDump(vtab,dump,class,comment) \ -astINVOKE(V,astSetDump_((AstObjectVtab *)(vtab),dump,class,comment,STATUS_PTR)) -#define astSetVtab(object,vtab) \ -astINVOKE(V,astSetVtab_((AstObject *)object,(AstObjectVtab *)(vtab),STATUS_PTR)) -#define astSetID(this,id) astINVOKE(V,astSetID_(astCheckObject(this),id,STATUS_PTR)) -#define astSetIdent(this,id) astINVOKE(V,astSetIdent_(astCheckObject(this),id,STATUS_PTR)) -#define astVSet(this,settings,text,args) \ -astINVOKE(V,astVSet_(astCheckObject(this),settings,text,args,STATUS_PTR)) -#define astEnvSet(this) \ -astINVOKE(V,astEnvSet_(astCheckObject(this),STATUS_PTR)) -#define astTestAttrib(this,attrib) \ -astINVOKE(V,astTestAttrib_(astCheckObject(this),attrib,STATUS_PTR)) -#define astTestID(this) astINVOKE(V,astTestID_(astCheckObject(this),STATUS_PTR)) -#define astTestIdent(this) astINVOKE(V,astTestIdent_(astCheckObject(this),STATUS_PTR)) - -/* Deprecated synonym. */ -#define astClass(this) astGetClass(this) -#endif - -/* Extra stuff for debuging probnlems with object handles and memory usage */ -#ifdef MEM_DEBUG - -void astWatchHandle_( int ); -void astHandleUse_( int, const char *, ... ); -void astHandleAlarm_( const char *, va_list ); - -#define astWatchHandle astWatchHandle_ -#define astHandleUse astHandleUse_ -#define astHandleAlarm astHandleAlarm_ - -#else - -#define astWatchHandle -#define astHandleUse -#define astHandleAlarm - -#endif - -#endif - diff --git a/ast/overgrid.pdf b/ast/overgrid.pdf deleted file mode 100644 index 21922e8..0000000 Binary files a/ast/overgrid.pdf and /dev/null differ diff --git a/ast/overgrid_bw.pdf b/ast/overgrid_bw.pdf deleted file mode 100644 index 457b75e..0000000 Binary files a/ast/overgrid_bw.pdf and /dev/null differ diff --git a/ast/pal.h b/ast/pal.h deleted file mode 100644 index 31ff8c7..0000000 --- a/ast/pal.h +++ /dev/null @@ -1,582 +0,0 @@ -#ifndef PALHDEF -#define PALHDEF - -/* -*+ -* Name: -* pal.h - -* Purpose: -* Function prototypes for PAL routines. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Include file - -* Description: -* Function prototypes for PAL routines. - -* Authors: -* TIMJ: Tim Jenness (JAC, Hawaii) -* DSBJ: David S Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-08 (TIMJ): -* Initial version. Define all SLA prototypes in PAL form even -* though none are implemented. -* 16-FEB-2012 (DSB): -* If the PAL and ERFA libraries distributed within AST are being -* used, rename the public symbols defined by both to avoid clashes -* with any external PAL or ERFA library. -* 11-JAN-2017 (DSB): -* Update to PAL V0.9.7. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 3 of -* the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be -* useful, but WITHOUT ANY WARRANTY; without even the implied -* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 -* USA. - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -/* Include configuration results in order to get any definition for the - EXTERNAL_PAL macro. This macro is set if the --with-external_pal - option was set when AST was configured. */ -#if HAVE_CONFIG_H -#include -#endif - -/* If we not using external PAL and ERFA libraries, rename all PAL - functions so that references to "palXxx" below get translated to - "astPalXxx". */ -#ifndef EXTERNAL_PAL -#include "pal2ast.h" -#endif - -/* Prototypes for all PAL functions. Note, these should be copied - verbatim from the pal.h file included in the pal library. We cannot - simply "include pal./pal.h" here as the macros established in - pal2ast.h above would then not be used to replace the names of the pal - function. */ - -/* ------------- start of pal/pal.h ------------------------------ */ - - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -void palAddet ( double rm, double dm, double eq, double *rc, double *dc ); - -void palAfin ( const char *string, int *iptr, float *a, int *j ); - -double palAirmas ( double zd ); - -void palAltaz ( double ha, double dec, double phi, - double *az, double *azd, double *azdd, - double *el, double *eld, double *eldd, - double *pa, double *pad, double *padd ); - -void palAmp ( double ra, double da, double date, double eq, - double *rm, double *dm ); - -void palAmpqk ( double ra, double da, double amprms[21], - double *rm, double *dm ); - -void palAop ( double rap, double dap, double date, double dut, - double elongm, double phim, double hm, double xp, - double yp, double tdk, double pmb, double rh, - double wl, double tlr, - double *aob, double *zob, double *hob, - double *dob, double *rob ); - -void palAoppa ( double date, double dut, double elongm, double phim, - double hm, double xp, double yp, double tdk, double pmb, - double rh, double wl, double tlr, double aoprms[14] ); - -void palAoppat ( double date, double aoprms[14] ); - -void palAopqk ( double rap, double dap, const double aoprms[14], - double *aob, double *zob, double *hob, - double *dob, double *rob ); - -void palAtmdsp ( double tdk, double pmb, double rh, double wl1, - double a1, double b1, double wl2, double *a2, double *b2 ); - -void palAv2m ( float axvec[3], float rmat[3][3] ); - -float palBear ( float a1, float b1, float a2, float b2 ); - -void palCaf2r ( int ideg, int iamin, float asec, float *rad, int *j ); - -void palCaldj ( int iy, int im, int id, double *djm, int *j ); - -void palCalyd ( int iy, int im, int id, int *ny, int *nd, int *j ); - -void palCc2s ( float v[3], float *a, float *b ); - -void palCc62s ( float v[6], float *a, float *b, float *r, - float *ad, float *bd, float *rd ); - -void palCd2tf ( int ndp, float days, char *sign, int ihmsf[4] ); - -void palCldj ( int iy, int im, int id, double *djm, int *j ); - -void palClyd ( int iy, int im, int id, int *ny, int *nd, int *jstat ); - -void palCombn ( int nsel, int ncand, int list[], int *j ); - -void palCr2af ( int ndp, float angle, char *sign, int idmsf[4] ); - -void palCr2tf ( int ndp, float angle, char *sign, int ihmsf[4] ); - -void palCs2c ( float a, float b, float v[3] ); - -void palCs2c6 ( float a, float b, float r, float ad, - float bd, float rd, float v[6] ); - -void palCtf2d ( int ihour, int imin, float sec, float *days, int *j ); - -void palCtf2r ( int ihour, int imin, float sec, float *rad, int *j ); - -void palDaf2r ( int ideg, int iamin, double asec, double *rad, int *j ); - -void palDafin ( const char *string, int *iptr, double *a, int *j ); - -double palDat ( double dju ); - -void palDav2m ( double axvec[3], double rmat[3][3] ); - -double palDbear ( double a1, double b1, double a2, double b2 ); - -void palDbjin ( const char *string, int *nstrt, - double *dreslt, int *jf1, int *jf2 ); - -void palDc62s ( double v[6], double *a, double *b, double *r, - double *ad, double *bd, double *rd ); - -void palDcc2s ( double v[3], double *a, double *b ); - -void palDcmpf ( double coeffs[6], double *xz, double *yz, double *xs, - double *ys, double *perp, double *orient ); - -void palDcs2c ( double a, double b, double v[3] ); - -void palDd2tf ( int ndp, double days, char *sign, int ihmsf[4] ); - -void palDe2h ( double ha, double dec, double phi, - double *az, double *el ); - -void palDeuler ( const char *order, double phi, double theta, double psi, - double rmat[3][3] ); - -void palDfltin ( const char *string, int *nstrt, double *dreslt, int *jflag ); - -void palDh2e ( double az, double el, double phi, double *ha, double *dec); - -void palDimxv ( double dm[3][3], double va[3], double vb[3] ); - -void palDjcal ( int ndp, double djm, int iymdf[4], int *j ); - -void palDjcl ( double djm, int *iy, int *im, int *id, double *fd, int *j ); - -void palDm2av ( double rmat[3][3], double axvec[3] ); - -void palDmat ( int n, double *a, double *y, double *d, int *jf, int *iw ); - -void palDmoon ( double date, double pv[6] ); - -void palDmxm ( double a[3][3], double b[3][3], double c[3][3] ); - -void palDmxv ( double dm[3][3], double va[3], double vb[3] ); - -double palDpav ( double v1[3], double v2[3] ); - -void palDr2af ( int ndp, double angle, char *sign, int idmsf[4] ); - -void palDr2tf ( int ndp, double angle, char *sign, int ihmsf[4] ); - -double palDrange ( double angle ); - -double palDranrm ( double angle ); - -void palDs2c6 ( double a, double b, double r, double ad, double bd, - double rd, double v[6] ); - -void palDs2tp ( double ra, double dec, double raz, double decz, - double *xi, double *eta, int *j ); - -double palDsep ( double a1, double b1, double a2, double b2 ); - -double palDsepv ( double v1[3], double v2[3] ); - -double palDt ( double epoch ); - -void palDtf2d ( int ihour, int imin, double sec, double *days, int *j ); - -void palDtf2r ( int ihour, int imin, double sec, double *rad, int *j ); - -void palDtp2s ( double xi, double eta, double raz, double decz, - double *ra, double *dec ); - -void palDtp2v ( double xi, double eta, double v0[3], double v[3] ); - -void palDtps2c ( double xi, double eta, double ra, double dec, - double *raz1, double *decz1, - double *raz2, double *decz2, int *n ); - -void palDtpv2c ( double xi, double eta, double v[3], - double v01[3], double v02[3], int *n ); - -double palDtt ( double dju ); - -void palDv2tp ( double v[3], double v0[3], double *xi, double *eta, int *j ); - -double palDvdv ( double va[3], double vb[3] ); - -void palDvn ( double v[3], double uv[3], double *vm ); - -void palDvxv ( double va[3], double vb[3], double vc[3] ); - -void palE2h ( float ha, float dec, float phi, float *az, float *el ); - -void palEarth ( int iy, int id, float fd, float posvel[6] ); - -void palEcleq ( double dl, double db, double date, double *dr, double *dd ); - -void palEcmat ( double date, double rmat[3][3] ); - -void palEcor ( float rm, float dm, int iy, int id, float fd, - float *rv, float *tl ); - -void palEg50 ( double dr, double dd, double *dl, double *db ); - -void palEl2ue ( double date, int jform, double epoch, double orbinc, - double anode, double perih, double aorq, double e, - double aorl, double dm, double u[13], int *jstat ); - -double palEpb ( double date ); - -double palEpb2d ( double epb ); - -double palEpco ( char k0, char k, double e ); - -double palEpj ( double date ); - -double palEpj2d ( double epj ); - -void palEpv( double date, double ph[3], double vh[3], - double pb[3], double vb[3] ); - -void palEqecl ( double dr, double dd, double date, double *dl, double *db ); - -double palEqeqx ( double date ); - -void palEqgal ( double dr, double dd, double *dl, double *db ); - -void palEtrms ( double ep, double ev[3] ); - -void palEuler ( const char *order, float phi, float theta, float psi, - float rmat[3][3] ); - -void palEvp ( double date, double deqx, - double dvb[3], double dpb[3], - double dvh[3], double dph[3] ); - -void palFitxy ( int itype, int np, double xye[][2], double xym[][2], - double coeffs[6], int *j ); - -void palFk425 ( double r1950, double d1950, double dr1950, - double dd1950, double p1950, double v1950, - double *r2000, double *d2000, double *dr2000, - double *dd2000, double *p2000, double *v2000 ); - -void palFk45z ( double r1950, double d1950, double bepoch, - double *r2000, double *d2000 ); - -void palFk524 ( double r2000, double d2000, double dr2000, - double dd2000, double p2000, double v2000, - double *r1950, double *d1950, double *dr1950, - double *dd1950, double *p1950, double *v1950 ); - -void palFk52h ( double r5, double d5, double dr5, double dd5, - double *dr, double *dh, double *drh, double *ddh ); - -void palFk54z ( double r2000, double d2000, double bepoch, - double *r1950, double *d1950, - double *dr1950, double *dd1950 ); - -void palFk5hz ( double r5, double d5, double epoch, - double *rh, double *dh ); - -void palFlotin ( const char *string, int *nstrt, float *reslt, int *jflag ); - -void palGaleq ( double dl, double db, double *dr, double *dd ); - -void palGalsup ( double dl, double db, double *dsl, double *dsb ); - -void palGe50 ( double dl, double db, double *dr, double *dd ); - -void palGeoc ( double p, double h, double *r, double *z ); - -double palGmst ( double ut1 ); - -double palGmsta ( double date, double ut1 ); - -void palH2e ( float az, float el, float phi, float *ha, float *dec ); - -void palH2fk5 ( double dr, double dh, double drh, double ddh, - double *r5, double *d5, double *dr5, double *dd5 ); - -void palHfk5z ( double rh, double dh, double epoch, - double *r5, double *d5, double *dr5, double *dd5 ); - -void palImxv ( float rm[3][3], float va[3], float vb[3] ); - -void palInt2in ( const char *string, int *nstrt, int *ireslt, int *jflag ); - -void palIntin ( const char *string, int *nstrt, long *ireslt, int *jflag ); - -void palInvf ( double fwds[6], double bkwds[6], int *j ); - -void palKbj ( int jb, double e, char *k, int *j ); - -void palM2av ( float rmat[3][3], float axvec[3] ); - -void palMap ( double rm, double dm, double pr, double pd, - double px, double rv, double eq, double date, - double *ra, double *da ); - -void palMappa ( double eq, double date, double amprms[21] ); - -void palMapqk ( double rm, double dm, double pr, double pd, - double px, double rv, double amprms[21], - double *ra, double *da ); - -void palMapqkz ( double rm, double dm, double amprms[21], - double *ra, double *da ); - -void palMoon ( int iy, int id, float fd, float posvel[6] ); - -void palMxm ( float a[3][3], float b[3][3], float c[3][3] ); - -void palMxv ( float rm[3][3], float va[3], float vb[3] ); - -void palNut ( double date, double rmatn[3][3] ); - -void palNutc ( double date, double *dpsi, double *deps, double *eps0 ); - -void palNutc80 ( double date, double *dpsi, double *deps, double *eps0 ); - -void palOap ( const char *type, double ob1, double ob2, double date, - double dut, double elongm, double phim, double hm, - double xp, double yp, double tdk, double pmb, - double rh, double wl, double tlr, - double *rap, double *dap ); - -void palOapqk ( const char *type, double ob1, double ob2, const double aoprms[14], - double *rap, double *dap ); - -int palObs( size_t n, const char * c, - char * ident, size_t identlen, - char * name, size_t namelen, - double * w, double * p, double * h ); - -double palPa ( double ha, double dec, double phi ); - -double palPav ( float v1[3], float v2[3] ); - -void palPcd ( double disco, double *x, double *y ); - -void palPda2h ( double p, double d, double a, - double *h1, int *j1, double *h2, int *j2 ); - -void palPdq2h ( double p, double d, double q, - double *h1, int *j1, double *h2, int *j2 ); - -void palPermut ( int n, int istate[], int iorder[], int *j ); - -void palPertel (int jform, double date0, double date1, - double epoch0, double orbi0, double anode0, - double perih0, double aorq0, double e0, double am0, - double *epoch1, double *orbi1, double *anode1, - double *perih1, double *aorq1, double *e1, double *am1, - int *jstat ); - -void palPertue ( double date, double u[13], int *jstat ); - -void palPlanel ( double date, int jform, double epoch, double orbinc, - double anode, double perih, double aorq, double e, - double aorl, double dm, double pv[6], int *jstat ); - -void palPlanet ( double date, int np, double pv[6], int *j ); - -void palPlante ( double date, double elong, double phi, int jform, - double epoch, double orbinc, double anode, double perih, - double aorq, double e, double aorl, double dm, - double *ra, double *dec, double *r, int *jstat ); - -void palPlantu ( double date, double elong, double phi, const double u[13], - double *ra, double *dec, double *r, int *jstat ); - -void palPm ( double r0, double d0, double pr, double pd, - double px, double rv, double ep0, double ep1, - double *r1, double *d1 ); - -void palPolmo ( double elongm, double phim, double xp, double yp, - double *elong, double *phi, double *daz ); - -void palPrebn ( double bep0, double bep1, double rmatp[3][3] ); - -void palPrec ( double ep0, double ep1, double rmatp[3][3] ); - -void palPrecl ( double ep0, double ep1, double rmatp[3][3] ); - -void palPreces ( const char sys[3], double ep0, double ep1, - double *ra, double *dc ); - -void palPrenut ( double epoch, double date, double rmatpn[3][3] ); - -void palPv2el ( const double pv[6], double date, double pmass, int jformr, - int *jform, double *epoch, double *orbinc, - double *anode, double *perih, double *aorq, double *e, - double *aorl, double *dm, int *jstat ); - -void palPv2ue ( const double pv[6], double date, double pmass, - double u[13], int *jstat ); - -void palPvobs ( double p, double h, double stl, double pv[6] ); - -void palPxy ( int np, double xye[][2], double xym[][2], - double coeffs[6], - double xyp[][2], double *xrms, double *yrms, double *rrms ); - -float palRange ( float angle ); - -float palRanorm ( float angle ); - -double palRcc ( double tdb, double ut1, double wl, double u, double v ); - -void palRdplan ( double date, int np, double elong, double phi, - double *ra, double *dec, double *diam ); - -void palRefco ( double hm, double tdk, double pmb, double rh, - double wl, double phi, double tlr, double eps, - double *refa, double *refb ); - -void palRefcoq ( double tdk, double pmb, double rh, double wl, - double *refa, double *refb ); - -void palRefro ( double zobs, double hm, double tdk, double pmb, - double rh, double wl, double phi, double tlr, double eps, - double *ref ); - -void palRefv ( double vu[3], double refa, double refb, double vr[3] ); - -void palRefz ( double zu, double refa, double refb, double *zr ); - -double palRverot ( double phi, double ra, double da, double st ); - -double palRvgalc ( double r2000, double d2000 ); - -double palRvlg ( double r2000, double d2000 ); - -double palRvlsrd ( double r2000, double d2000 ); - -double palRvlsrk ( double r2000, double d2000 ); - -void palS2tp ( float ra, float dec, float raz, float decz, - float *xi, float *eta, int *j ); - -float palSep ( float a1, float b1, float a2, float b2 ); - -float palSepv ( float v1[3], float v2[3] ); - -void palSmat ( int n, float *a, float *y, float *d, int *jf, int *iw ); - -void palSubet ( double rc, double dc, double eq, - double *rm, double *dm ); - -void palSupgal ( double dsl, double dsb, double *dl, double *db ); - -void palSvd ( int m, int n, int mp, int np, - double *a, double *w, double *v, double *work, - int *jstat ); - -void palSvdcov ( int n, int np, int nc, - double *w, double *v, double *work, double *cvm ); - -void palSvdsol ( int m, int n, int mp, int np, - double *b, double *u, double *w, double *v, - double *work, double *x ); - -void palTp2s ( float xi, float eta, float raz, float decz, - float *ra, float *dec ); - -void palTp2v ( float xi, float eta, float v0[3], float v[3] ); - -void palTps2c ( float xi, float eta, float ra, float dec, - float *raz1, float *decz1, - float *raz2, float *decz2, int *n ); - -void palTpv2c ( float xi, float eta, float v[3], - float v01[3], float v02[3], int *n ); - -void palUe2el ( const double u[13], int jformr, - int *jform, double *epoch, double *orbinc, - double *anode, double *perih, double *aorq, double *e, - double *aorl, double *dm, int *jstat ); - -void palUe2pv ( double date, double u[13], double pv[], int *jstat ); - -void palUnpcd ( double disco, double *x, double *y ); - -void palV2tp ( float v[3], float v0[3], float *xi, float *eta, int *j ); - -float palVdv ( float va[3], float vb[3] ); - -int palVers ( char * verstring, size_t verlen ); - -void palVn ( float v[3], float uv[3], float *vm ); - -void palVxv ( float va[3], float vb[3], float vc[3] ); - -void palXy2xy ( double x1, double y1, double coeffs[6], - double *x2, double *y2 ); - -double palZd ( double ha, double dec, double phi ); - -#ifdef __cplusplus -} -#endif - -/* ------------- end of pal/pal.h ------------------------------ */ - - - - -#endif diff --git a/ast/pal/pal.h b/ast/pal/pal.h deleted file mode 100644 index a588168..0000000 --- a/ast/pal/pal.h +++ /dev/null @@ -1,551 +0,0 @@ -#ifndef PALHDEF -#define PALHDEF - -/* -*+ -* Name: -* pal.h - -* Purpose: -* Function prototypes for PAL routines. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Include file - -* Description: -* Function prototypes for PAL routines. - -* Authors: -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* - -* History: -* 2012-02-08 (TIMJ): -* Initial version. Define all SLA prototypes in PAL form even -* though none are implemented. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -void palAddet ( double rm, double dm, double eq, double *rc, double *dc ); - -void palAfin ( const char *string, int *iptr, float *a, int *j ); - -double palAirmas ( double zd ); - -void palAltaz ( double ha, double dec, double phi, - double *az, double *azd, double *azdd, - double *el, double *eld, double *eldd, - double *pa, double *pad, double *padd ); - -void palAmp ( double ra, double da, double date, double eq, - double *rm, double *dm ); - -void palAmpqk ( double ra, double da, double amprms[21], - double *rm, double *dm ); - -void palAop ( double rap, double dap, double date, double dut, - double elongm, double phim, double hm, double xp, - double yp, double tdk, double pmb, double rh, - double wl, double tlr, - double *aob, double *zob, double *hob, - double *dob, double *rob ); - -void palAoppa ( double date, double dut, double elongm, double phim, - double hm, double xp, double yp, double tdk, double pmb, - double rh, double wl, double tlr, double aoprms[14] ); - -void palAoppat ( double date, double aoprms[14] ); - -void palAopqk ( double rap, double dap, const double aoprms[14], - double *aob, double *zob, double *hob, - double *dob, double *rob ); - -void palAtmdsp ( double tdk, double pmb, double rh, double wl1, - double a1, double b1, double wl2, double *a2, double *b2 ); - -void palAv2m ( float axvec[3], float rmat[3][3] ); - -float palBear ( float a1, float b1, float a2, float b2 ); - -void palCaf2r ( int ideg, int iamin, float asec, float *rad, int *j ); - -void palCaldj ( int iy, int im, int id, double *djm, int *j ); - -void palCalyd ( int iy, int im, int id, int *ny, int *nd, int *j ); - -void palCc2s ( float v[3], float *a, float *b ); - -void palCc62s ( float v[6], float *a, float *b, float *r, - float *ad, float *bd, float *rd ); - -void palCd2tf ( int ndp, float days, char *sign, int ihmsf[4] ); - -void palCldj ( int iy, int im, int id, double *djm, int *j ); - -void palClyd ( int iy, int im, int id, int *ny, int *nd, int *jstat ); - -void palCombn ( int nsel, int ncand, int list[], int *j ); - -void palCr2af ( int ndp, float angle, char *sign, int idmsf[4] ); - -void palCr2tf ( int ndp, float angle, char *sign, int ihmsf[4] ); - -void palCs2c ( float a, float b, float v[3] ); - -void palCs2c6 ( float a, float b, float r, float ad, - float bd, float rd, float v[6] ); - -void palCtf2d ( int ihour, int imin, float sec, float *days, int *j ); - -void palCtf2r ( int ihour, int imin, float sec, float *rad, int *j ); - -void palDaf2r ( int ideg, int iamin, double asec, double *rad, int *j ); - -void palDafin ( const char *string, int *iptr, double *a, int *j ); - -double palDat ( double dju ); - -void palDav2m ( double axvec[3], double rmat[3][3] ); - -double palDbear ( double a1, double b1, double a2, double b2 ); - -void palDbjin ( const char *string, int *nstrt, - double *dreslt, int *jf1, int *jf2 ); - -void palDc62s ( double v[6], double *a, double *b, double *r, - double *ad, double *bd, double *rd ); - -void palDcc2s ( double v[3], double *a, double *b ); - -void palDcmpf ( double coeffs[6], double *xz, double *yz, double *xs, - double *ys, double *perp, double *orient ); - -void palDcs2c ( double a, double b, double v[3] ); - -void palDd2tf ( int ndp, double days, char *sign, int ihmsf[4] ); - -void palDe2h ( double ha, double dec, double phi, - double *az, double *el ); - -void palDeuler ( const char *order, double phi, double theta, double psi, - double rmat[3][3] ); - -void palDfltin ( const char *string, int *nstrt, double *dreslt, int *jflag ); - -void palDh2e ( double az, double el, double phi, double *ha, double *dec); - -void palDimxv ( double dm[3][3], double va[3], double vb[3] ); - -void palDjcal ( int ndp, double djm, int iymdf[4], int *j ); - -void palDjcl ( double djm, int *iy, int *im, int *id, double *fd, int *j ); - -void palDm2av ( double rmat[3][3], double axvec[3] ); - -void palDmat ( int n, double *a, double *y, double *d, int *jf, int *iw ); - -void palDmoon ( double date, double pv[6] ); - -void palDmxm ( double a[3][3], double b[3][3], double c[3][3] ); - -void palDmxv ( double dm[3][3], double va[3], double vb[3] ); - -double palDpav ( double v1[3], double v2[3] ); - -void palDr2af ( int ndp, double angle, char *sign, int idmsf[4] ); - -void palDr2tf ( int ndp, double angle, char *sign, int ihmsf[4] ); - -double palDrange ( double angle ); - -double palDranrm ( double angle ); - -void palDs2c6 ( double a, double b, double r, double ad, double bd, - double rd, double v[6] ); - -void palDs2tp ( double ra, double dec, double raz, double decz, - double *xi, double *eta, int *j ); - -double palDsep ( double a1, double b1, double a2, double b2 ); - -double palDsepv ( double v1[3], double v2[3] ); - -double palDt ( double epoch ); - -void palDtf2d ( int ihour, int imin, double sec, double *days, int *j ); - -void palDtf2r ( int ihour, int imin, double sec, double *rad, int *j ); - -void palDtp2s ( double xi, double eta, double raz, double decz, - double *ra, double *dec ); - -void palDtp2v ( double xi, double eta, double v0[3], double v[3] ); - -void palDtps2c ( double xi, double eta, double ra, double dec, - double *raz1, double *decz1, - double *raz2, double *decz2, int *n ); - -void palDtpv2c ( double xi, double eta, double v[3], - double v01[3], double v02[3], int *n ); - -double palDtt ( double dju ); - -void palDv2tp ( double v[3], double v0[3], double *xi, double *eta, int *j ); - -double palDvdv ( double va[3], double vb[3] ); - -void palDvn ( double v[3], double uv[3], double *vm ); - -void palDvxv ( double va[3], double vb[3], double vc[3] ); - -void palE2h ( float ha, float dec, float phi, float *az, float *el ); - -void palEarth ( int iy, int id, float fd, float posvel[6] ); - -void palEcleq ( double dl, double db, double date, double *dr, double *dd ); - -void palEcmat ( double date, double rmat[3][3] ); - -void palEcor ( float rm, float dm, int iy, int id, float fd, - float *rv, float *tl ); - -void palEg50 ( double dr, double dd, double *dl, double *db ); - -void palEl2ue ( double date, int jform, double epoch, double orbinc, - double anode, double perih, double aorq, double e, - double aorl, double dm, double u[13], int *jstat ); - -double palEpb ( double date ); - -double palEpb2d ( double epb ); - -double palEpco ( char k0, char k, double e ); - -double palEpj ( double date ); - -double palEpj2d ( double epj ); - -void palEpv( double date, double ph[3], double vh[3], - double pb[3], double vb[3] ); - -void palEqecl ( double dr, double dd, double date, double *dl, double *db ); - -double palEqeqx ( double date ); - -void palEqgal ( double dr, double dd, double *dl, double *db ); - -void palEtrms ( double ep, double ev[3] ); - -void palEuler ( const char *order, float phi, float theta, float psi, - float rmat[3][3] ); - -void palEvp ( double date, double deqx, - double dvb[3], double dpb[3], - double dvh[3], double dph[3] ); - -void palFitxy ( int itype, int np, double xye[][2], double xym[][2], - double coeffs[6], int *j ); - -void palFk425 ( double r1950, double d1950, double dr1950, - double dd1950, double p1950, double v1950, - double *r2000, double *d2000, double *dr2000, - double *dd2000, double *p2000, double *v2000 ); - -void palFk45z ( double r1950, double d1950, double bepoch, - double *r2000, double *d2000 ); - -void palFk524 ( double r2000, double d2000, double dr2000, - double dd2000, double p2000, double v2000, - double *r1950, double *d1950, double *dr1950, - double *dd1950, double *p1950, double *v1950 ); - -void palFk52h ( double r5, double d5, double dr5, double dd5, - double *dr, double *dh, double *drh, double *ddh ); - -void palFk54z ( double r2000, double d2000, double bepoch, - double *r1950, double *d1950, - double *dr1950, double *dd1950 ); - -void palFk5hz ( double r5, double d5, double epoch, - double *rh, double *dh ); - -void palFlotin ( const char *string, int *nstrt, float *reslt, int *jflag ); - -void palGaleq ( double dl, double db, double *dr, double *dd ); - -void palGalsup ( double dl, double db, double *dsl, double *dsb ); - -void palGe50 ( double dl, double db, double *dr, double *dd ); - -void palGeoc ( double p, double h, double *r, double *z ); - -double palGmst ( double ut1 ); - -double palGmsta ( double date, double ut1 ); - -void palH2e ( float az, float el, float phi, float *ha, float *dec ); - -void palH2fk5 ( double dr, double dh, double drh, double ddh, - double *r5, double *d5, double *dr5, double *dd5 ); - -void palHfk5z ( double rh, double dh, double epoch, - double *r5, double *d5, double *dr5, double *dd5 ); - -void palImxv ( float rm[3][3], float va[3], float vb[3] ); - -void palInt2in ( const char *string, int *nstrt, int *ireslt, int *jflag ); - -void palIntin ( const char *string, int *nstrt, long *ireslt, int *jflag ); - -void palInvf ( double fwds[6], double bkwds[6], int *j ); - -void palKbj ( int jb, double e, char *k, int *j ); - -void palM2av ( float rmat[3][3], float axvec[3] ); - -void palMap ( double rm, double dm, double pr, double pd, - double px, double rv, double eq, double date, - double *ra, double *da ); - -void palMappa ( double eq, double date, double amprms[21] ); - -void palMapqk ( double rm, double dm, double pr, double pd, - double px, double rv, double amprms[21], - double *ra, double *da ); - -void palMapqkz ( double rm, double dm, double amprms[21], - double *ra, double *da ); - -void palMoon ( int iy, int id, float fd, float posvel[6] ); - -void palMxm ( float a[3][3], float b[3][3], float c[3][3] ); - -void palMxv ( float rm[3][3], float va[3], float vb[3] ); - -void palNut ( double date, double rmatn[3][3] ); - -void palNutc ( double date, double *dpsi, double *deps, double *eps0 ); - -void palNutc80 ( double date, double *dpsi, double *deps, double *eps0 ); - -void palOap ( const char *type, double ob1, double ob2, double date, - double dut, double elongm, double phim, double hm, - double xp, double yp, double tdk, double pmb, - double rh, double wl, double tlr, - double *rap, double *dap ); - -void palOapqk ( const char *type, double ob1, double ob2, const double aoprms[14], - double *rap, double *dap ); - -int palObs( size_t n, const char * c, - char * ident, size_t identlen, - char * name, size_t namelen, - double * w, double * p, double * h ); - -double palPa ( double ha, double dec, double phi ); - -double palPav ( float v1[3], float v2[3] ); - -void palPcd ( double disco, double *x, double *y ); - -void palPda2h ( double p, double d, double a, - double *h1, int *j1, double *h2, int *j2 ); - -void palPdq2h ( double p, double d, double q, - double *h1, int *j1, double *h2, int *j2 ); - -void palPermut ( int n, int istate[], int iorder[], int *j ); - -void palPertel (int jform, double date0, double date1, - double epoch0, double orbi0, double anode0, - double perih0, double aorq0, double e0, double am0, - double *epoch1, double *orbi1, double *anode1, - double *perih1, double *aorq1, double *e1, double *am1, - int *jstat ); - -void palPertue ( double date, double u[13], int *jstat ); - -void palPlanel ( double date, int jform, double epoch, double orbinc, - double anode, double perih, double aorq, double e, - double aorl, double dm, double pv[6], int *jstat ); - -void palPlanet ( double date, int np, double pv[6], int *j ); - -void palPlante ( double date, double elong, double phi, int jform, - double epoch, double orbinc, double anode, double perih, - double aorq, double e, double aorl, double dm, - double *ra, double *dec, double *r, int *jstat ); - -void palPlantu ( double date, double elong, double phi, const double u[13], - double *ra, double *dec, double *r, int *jstat ); - -void palPm ( double r0, double d0, double pr, double pd, - double px, double rv, double ep0, double ep1, - double *r1, double *d1 ); - -void palPolmo ( double elongm, double phim, double xp, double yp, - double *elong, double *phi, double *daz ); - -void palPrebn ( double bep0, double bep1, double rmatp[3][3] ); - -void palPrec ( double ep0, double ep1, double rmatp[3][3] ); - -void palPrecl ( double ep0, double ep1, double rmatp[3][3] ); - -void palPreces ( const char sys[3], double ep0, double ep1, - double *ra, double *dc ); - -void palPrenut ( double epoch, double date, double rmatpn[3][3] ); - -void palPv2el ( const double pv[6], double date, double pmass, int jformr, - int *jform, double *epoch, double *orbinc, - double *anode, double *perih, double *aorq, double *e, - double *aorl, double *dm, int *jstat ); - -void palPv2ue ( const double pv[6], double date, double pmass, - double u[13], int *jstat ); - -void palPvobs ( double p, double h, double stl, double pv[6] ); - -void palPxy ( int np, double xye[][2], double xym[][2], - double coeffs[6], - double xyp[][2], double *xrms, double *yrms, double *rrms ); - -float palRange ( float angle ); - -float palRanorm ( float angle ); - -double palRcc ( double tdb, double ut1, double wl, double u, double v ); - -void palRdplan ( double date, int np, double elong, double phi, - double *ra, double *dec, double *diam ); - -void palRefco ( double hm, double tdk, double pmb, double rh, - double wl, double phi, double tlr, double eps, - double *refa, double *refb ); - -void palRefcoq ( double tdk, double pmb, double rh, double wl, - double *refa, double *refb ); - -void palRefro ( double zobs, double hm, double tdk, double pmb, - double rh, double wl, double phi, double tlr, double eps, - double *ref ); - -void palRefv ( double vu[3], double refa, double refb, double vr[3] ); - -void palRefz ( double zu, double refa, double refb, double *zr ); - -double palRverot ( double phi, double ra, double da, double st ); - -double palRvgalc ( double r2000, double d2000 ); - -double palRvlg ( double r2000, double d2000 ); - -double palRvlsrd ( double r2000, double d2000 ); - -double palRvlsrk ( double r2000, double d2000 ); - -void palS2tp ( float ra, float dec, float raz, float decz, - float *xi, float *eta, int *j ); - -float palSep ( float a1, float b1, float a2, float b2 ); - -float palSepv ( float v1[3], float v2[3] ); - -void palSmat ( int n, float *a, float *y, float *d, int *jf, int *iw ); - -void palSubet ( double rc, double dc, double eq, - double *rm, double *dm ); - -void palSupgal ( double dsl, double dsb, double *dl, double *db ); - -void palSvd ( int m, int n, int mp, int np, - double *a, double *w, double *v, double *work, - int *jstat ); - -void palSvdcov ( int n, int np, int nc, - double *w, double *v, double *work, double *cvm ); - -void palSvdsol ( int m, int n, int mp, int np, - double *b, double *u, double *w, double *v, - double *work, double *x ); - -void palTp2s ( float xi, float eta, float raz, float decz, - float *ra, float *dec ); - -void palTp2v ( float xi, float eta, float v0[3], float v[3] ); - -void palTps2c ( float xi, float eta, float ra, float dec, - float *raz1, float *decz1, - float *raz2, float *decz2, int *n ); - -void palTpv2c ( float xi, float eta, float v[3], - float v01[3], float v02[3], int *n ); - -void palUe2el ( const double u[13], int jformr, - int *jform, double *epoch, double *orbinc, - double *anode, double *perih, double *aorq, double *e, - double *aorl, double *dm, int *jstat ); - -void palUe2pv ( double date, double u[13], double pv[], int *jstat ); - -void palUnpcd ( double disco, double *x, double *y ); - -void palV2tp ( float v[3], float v0[3], float *xi, float *eta, int *j ); - -float palVdv ( float va[3], float vb[3] ); - -int palVers ( char * verstring, size_t verlen ); - -void palVn ( float v[3], float uv[3], float *vm ); - -void palVxv ( float va[3], float vb[3], float vc[3] ); - -void palXy2xy ( double x1, double y1, double coeffs[6], - double *x2, double *y2 ); - -double palZd ( double ha, double dec, double phi ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ast/pal/pal1sofa.h b/ast/pal/pal1sofa.h deleted file mode 100644 index 11f7446..0000000 --- a/ast/pal/pal1sofa.h +++ /dev/null @@ -1,142 +0,0 @@ -/* -*+ -* Name: -* pal1sofa.h - -* Purpose: -* Mappings of ERFA names to SOFA names - -* Language: -* Starlink ANSI C - -* Type of Module: -* Include file - -* Invocation: -* #include "pal1sofa.h" - -* Description: -* PAL will work with both SOFA and ERFA libraries and the -* difference is generally a change in prefix. This include -* file maps the ERFA form of functions to the SOFA form -* and includes the relevant sofa.h vs erfa.h file. - -* Authors: -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* - PAL uses the ERFA form by default. - -* History: -* 2014-07-29 (TIMJ): -* Initial version -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2014 Tim Jenness -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#ifndef PAL1SOFAHDEF -#define PAL1SOFAHDEF - -#if HAVE_CONFIG_H -# include -#endif - -# if HAVE_SOFA_H - -# include "sofa.h" -# include "sofam.h" - - /* Must replace ERFA with SOFA */ - -# define eraA2af iauA2af -# define eraA2tf iauA2tf -# define eraAf2a iauAf2a -# define eraAnp iauAnp -# define eraAnpm iauAnpm -# define eraC2s iauC2s -# define eraCal2jd iauCal2jd -# define eraD2tf iauD2tf -# define eraDat iauDat -# define eraEe06a iauEe06a -# define eraEpb iauEpb -# define eraEpb2jd iauEpb2jd -# define eraEpj iauEpj -# define eraEpj2jd iauEpj2jd -# define eraEpv00 iauEpv00 -# define eraFk5hz iauFk5hz -# define eraGd2gc iauGd2gc -# define eraGmst06 iauGmst06 -# define eraHfk5z iauHfk5z -# define eraIr iauIr -# define eraJd2cal iauJd2cal -# define eraNut06a iauNut06a -# define eraObl06 iauObl06 -# define eraP06e iauP06e -# define eraPap iauPap -# define eraPas iauPas -# define eraPdp iauPdp -# define eraPlan94 iauPlan94 -# define eraPmat06 iauPmat06 -# define eraPn iauPn -# define eraPnm06a iauPnm06a -# define eraPxp iauPxp -# define eraRefco iauRefco -# define eraRm2v iauRm2v -# define eraRv2m iauRv2m -# define eraRx iauRx -# define eraRxp iauRxp -# define eraRxpv iauRxpv -# define eraRxr iauRxr -# define eraRy iauRy -# define eraRz iauRz -# define eraS2c iauS2c -# define eraSepp iauSepp -# define eraSeps iauSeps -# define eraStarpm iauStarpm -# define eraTf2a iauTf2a -# define eraTf2d iauTf2d -# define eraTr iauTr -# define eraTrxp iauTrxp - -/* These are from sofam.h */ - -# define ERFA_WGS84 WGS84 - -# define ERFA_DJ00 DJ00 -# define ERFA_DJY DJY -# define ERFA_DAU DAU - -# else - -# include "erfa.h" -# include "erfam.h" - -/* No further action required */ - -# endif - -#endif diff --git a/ast/pal/palAddet.c b/ast/pal/palAddet.c deleted file mode 100644 index ce3ddab..0000000 --- a/ast/pal/palAddet.c +++ /dev/null @@ -1,112 +0,0 @@ -/* -*+ -* Name: -* palAddet - -* Purpose: -* Add the E-terms to a pre IAU 1976 mean place - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palAddet ( double rm, double dm, double eq, -* double *rc, double *dc ); - -* Arguments: -* rm = double (Given) -* RA without E-terms (radians) -* dm = double (Given) -* Dec without E-terms (radians) -* eq = double (Given) -* Besselian epoch of mean equator and equinox -* rc = double * (Returned) -* RA with E-terms included (radians) -* dc = double * (Returned) -* Dec with E-terms included (radians) - -* Description: -* Add the E-terms (elliptic component of annual aberration) -* to a pre IAU 1976 mean place to conform to the old -* catalogue convention. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* Most star positions from pre-1984 optical catalogues (or -* derived from astrometry using such stars) embody the -* E-terms. If it is necessary to convert a formal mean -* place (for example a pulsar timing position) to one -* consistent with such a star catalogue, then the RA,Dec -* should be adjusted using this routine. - -* See Also: -* Explanatory Supplement to the Astronomical Ephemeris, -* section 2D, page 48. - -* History: -* 2012-02-12(TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1999 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palAddet ( double rm, double dm, double eq, double *rc, double *dc ) { - double a[3]; /* The E-terms */ - double v[3]; - int i; - - /* Note the preference for IAU routines */ - - /* Retrieve the E-terms */ - palEtrms( eq, a ); - - /* Spherical to Cartesian */ - eraS2c( rm, dm, v ); - - /* Include the E-terms */ - for (i=0; i<3; i++) { - v[i] += a[i]; - } - - /* Cartesian to spherical */ - eraC2s( v, rc, dc ); - - /* Bring RA into conventional range */ - *rc = eraAnp( *rc ); - -} diff --git a/ast/pal/palAmpqk.c b/ast/pal/palAmpqk.c deleted file mode 100644 index ce698b8..0000000 --- a/ast/pal/palAmpqk.c +++ /dev/null @@ -1,159 +0,0 @@ -/* -*+ -* Name: -* palAmpqk - -* Purpose: -* Convert star RA,Dec from geocentric apparent to mean place. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palAmpqk ( double ra, double da, double amprms[21], -* double *rm, double *dm ) - -* Arguments: -* ra = double (Given) -* Apparent RA (radians). -* da = double (Given) -* Apparent Dec (radians). -* amprms = double[21] (Given) -* Star-independent mean-to-apparent parameters (see palMappa): -* (0) time interval for proper motion (Julian years) -* (1-3) barycentric position of the Earth (AU) -* (4-6) heliocentric direction of the Earth (unit vector) -* (7) (grav rad Sun)*2/(Sun-Earth distance) -* (8-10) abv: barycentric Earth velocity in units of c -* (11) sqrt(1-v*v) where v=modulus(abv) -* (12-20) precession/nutation (3,3) matrix -* rm = double (Returned) -* Mean RA (radians). -* dm = double (Returned) -* Mean Dec (radians). - -* Description: -* Convert star RA,Dec from geocentric apparent to mean place. The "mean" -* coordinate system is in fact close to ICRS. Use of this function -* is appropriate when efficiency is important and where many star -* positions are all to be transformed for one epoch and equinox. The -* star-independent parameters can be obtained by calling the palMappa -* function. - -* Note: -* Iterative techniques are used for the aberration and -* light deflection corrections so that the routines -* palAmp (or palAmpqk) and palMap (or palMapqk) are -* accurate inverses; even at the edge of the Sun's disc -* the discrepancy is only about 1 nanoarcsecond. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness -* {enter_new_authors_here} - -* History: -* 2012-02-13 (PTW): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* 2016-12-19 (TIMJ): -* Add in light deflection (was missed in the initial port). -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2000 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* Copyright (C) 2016 Tim Jenness -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palAmpqk ( double ra, double da, double amprms[21], double *rm, - double *dm ){ - -/* Local Variables: */ - double ab1; /* sqrt(1-v*v) where v=modulus of Earth vel */ - double abv[3]; /* Earth velocity wrt SSB (c, FK5) */ - double p1[3], p2[3], p3[3]; /* work vectors */ - double ab1p1, p1dv, p1dvp1, w; - double gr2e, pde, pdep1, ehn[3], p[3]; - int i, j; - -/* Unpack some of the parameters */ - gr2e = amprms[7]; - ab1 = amprms[11]; - for( i = 0; i < 3; i++ ) { - ehn[i] = amprms[i + 4]; - abv[i] = amprms[i + 8]; - } - -/* Apparent RA,Dec to Cartesian */ - eraS2c( ra, da, p3 ); - -/* Precession and nutation */ - eraTrxp( (double(*)[3]) &rms[12], p3, p2 ); - -/* Aberration */ - ab1p1 = ab1 + 1.0; - for( i = 0; i < 3; i++ ) { - p1[i] = p2[i]; - } - for( j = 0; j < 2; j++ ) { - p1dv = eraPdp( p1, abv ); - p1dvp1 = 1.0 + p1dv; - w = 1.0 + p1dv / ab1p1; - for( i = 0; i < 3; i++ ) { - p1[i] = ( p1dvp1 * p2[i] - w * abv[i] ) / ab1; - } - eraPn( p1, &w, p3 ); - for( i = 0; i < 3; i++ ) { - p1[i] = p3[i]; - } - } - -/* Light deflection */ - for( i = 0; i < 3; i++ ) { - p[i] = p1[i]; - } - for( j = 0; j < 5; j++ ) { - pde = eraPdp( p, ehn ); - pdep1 = 1.0 + pde; - w = pdep1 - gr2e*pde; - for( i = 0; i < 3; i++ ) { - p[i] = (pdep1*p1[i] - gr2e*ehn[i])/w; - } - eraPn( p, &w, p2 ); - for( i = 0; i < 3; i++ ) { - p[i] = p2[i]; - } - } - -/* Mean RA,Dec */ - eraC2s( p, rm, dm ); - *rm = eraAnp( *rm ); -} diff --git a/ast/pal/palCaldj.c b/ast/pal/palCaldj.c deleted file mode 100644 index 03c6b97..0000000 --- a/ast/pal/palCaldj.c +++ /dev/null @@ -1,99 +0,0 @@ -/* -*+ -* Name: -* palCaldj - -* Purpose: -* Gregorian Calendar to Modified Julian Date - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palCaldj ( int iy, int im, int id, double *djm, int *j ); - -* Arguments: -* iy = int (Given) -* Year in the Gregorian calendar -* im = int (Given) -* Month in the Gergorian calendar -* id = int (Given) -* Day in the Gregorian calendar -* djm = double * (Returned) -* Modified Julian Date (JD-2400000.5) for 0 hrs -* j = status (Returned) -* 0 = OK. See eraCal2jd for other values. - -* Description: -* Modified Julian Date to Gregorian Calendar with special -* behaviour for 2-digit years relating to 1950 to 2049. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-11 (TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Notes: -* - Uses eraCal2jd -* - Unlike eraCal2jd this routine treats the years 0-100 as -* referring to the end of the 20th Century and beginning of -* the 21st Century. If this behaviour is not acceptable -* use the SOFA/ERFA routine directly or palCldj. -* Acceptable years are 00-49, interpreted as 2000-2049, -* 50-99, " " 1950-1999, -* all others, interpreted literally. -* - Unlike SLA this routine will work with negative years. - - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include "pal1sofa.h" - -void palCaldj ( int iy, int im, int id, double *djm, int *j ) { - int adj = 0; /* Year adjustment */ - double djm0; - - if (iy >= 0 && iy <= 49) { - adj = 2000; - } else if (iy >= 50 && iy <= 99) { - adj = 1900; - } - iy += adj; - - *j = eraCal2jd( iy, im, id, &djm0, djm ); -} diff --git a/ast/pal/palDat.c b/ast/pal/palDat.c deleted file mode 100644 index f869681..0000000 --- a/ast/pal/palDat.c +++ /dev/null @@ -1,95 +0,0 @@ -/* -*+ -* Name: -* palDat - -* Purpose: -* Return offset between UTC and TAI - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* dat = palDat( double utc ); - -* Arguments: -* utc = double (Given) -* UTC date as a modified JD (JD-2400000.5) - -* Returned Value: -* dat = double -* TAI-UTC in seconds - -* Description: -* Increment to be applied to Coordinated Universal Time UTC to give -* International Atomic Time (TAI). - -* Authors: -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* - This routine converts the MJD argument to calendar date before calling -* the SOFA/ERFA eraDat function. -* - This routine matches the slaDat interface which differs from the eraDat -* interface. Consider coding directly to the SOFA/ERFA interface. -* - See eraDat for a description of error conditions when calling this function -* with a time outside of the UTC range. -* - The status argument from eraDat is ignored. This is reasonable since the -* error codes are mainly related to incorrect calendar dates when calculating -* the JD internally. - -* History: -* 2012-02-08 (TIMJ): -* Initial version -* Adapted with permission from the Fortran SLALIB library -* although the core algorithm is now from SOFA. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" - -#include "pal1sofa.h" - -double palDat ( double dju ) { - int iy; - int im; - int id; - int status; - double fd; - double deltat; - - eraJd2cal( PAL__MJD0, dju, - &iy, &im, &id, &fd ); - - status = eraDat( iy, im, id, fd, &deltat ); - return deltat; -} diff --git a/ast/pal/palDe2h.c b/ast/pal/palDe2h.c deleted file mode 100644 index a250e9e..0000000 --- a/ast/pal/palDe2h.c +++ /dev/null @@ -1,142 +0,0 @@ -/* -*+ -* Name: -* palDe2h - -* Purpose: -* Equatorial to horizon coordinates: HA,Dec to Az,E - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDe2h( double ha, double dec, double phi, double * az, double * el ); - -* Arguments: -* ha = double * (Given) -* Hour angle (radians) -* dec = double * (Given) -* Declination (radians) -* phi = double (Given) -* Observatory latitude (radians) -* az = double * (Returned) -* Azimuth (radians) -* el = double * (Returned) -* Elevation (radians) - -* Description: -* Convert equatorial to horizon coordinates. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* - All the arguments are angles in radians. -* - Azimuth is returned in the range 0-2pi; north is zero, -* and east is +pi/2. Elevation is returned in the range -* +/-pi/2. -* - The latitude must be geodetic. In critical applications, -* corrections for polar motion should be applied. -* - In some applications it will be important to specify the -* correct type of hour angle and declination in order to -* produce the required type of azimuth and elevation. In -* particular, it may be important to distinguish between -* elevation as affected by refraction, which would -* require the "observed" HA,Dec, and the elevation -* in vacuo, which would require the "topocentric" HA,Dec. -* If the effects of diurnal aberration can be neglected, the -* "apparent" HA,Dec may be used instead of the topocentric -* HA,Dec. -* - No range checking of arguments is carried out. -* - In applications which involve many such calculations, rather -* than calling the present routine it will be more efficient to -* use inline code, having previously computed fixed terms such -* as sine and cosine of latitude, and (for tracking a star) -* sine and cosine of declination. - -* History: -* 2012-02-08 (TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include - -void -palDe2h ( double ha, double dec, double phi, double *az, double *el) { - - double sh; - double ch; - double sd; - double cd; - double sp; - double cp; - - double a; - - double x; - double y; - double z; - double r; - - /* Useful trig functions */ - sh = sin(ha); - ch = cos(ha); - sd = sin(dec); - cd = cos(dec); - sp = sin(phi); - cp = cos(phi); - - /* Az,El as x,y,z */ - x = -ch * cd * sp + sd * cp; - y = -sh * cd; - z = ch * cd * cp + sd * sp; - - /* To spherical */ - r = sqrt(x * x + y * y); - if (r == 0.) { - a = 0.; - } else { - a = atan2(y, x); - } - if (a < 0.) { - a += PAL__D2PI; - } - *az = a; - *el = atan2(z, r); - - return; -} diff --git a/ast/pal/palDeuler.c b/ast/pal/palDeuler.c deleted file mode 100644 index 17e536b..0000000 --- a/ast/pal/palDeuler.c +++ /dev/null @@ -1,141 +0,0 @@ -/* -*+ -* Name: -* palDeuler - -* Purpose: -* Form a rotation matrix from the Euler angles - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palDeuler ( const char *order, double phi, double theta, double psi, -* double rmat[3][3] ); - -* Arguments: -* order = const char[] (Given) -* Specifies about which axes the rotation occurs -* phi = double (Given) -* 1st rotation (radians) -* theta = double (Given) -* 2nd rotation (radians) -* psi = double (Given) -* 3rd rotation (radians) -* rmat = double[3][3] (Given & Returned) -* Rotation matrix - -* Description: -* A rotation is positive when the reference frame rotates -* anticlockwise as seen looking towards the origin from the -* positive region of the specified axis. -* -* The characters of ORDER define which axes the three successive -* rotations are about. A typical value is 'ZXZ', indicating that -* RMAT is to become the direction cosine matrix corresponding to -* rotations of the reference frame through PHI radians about the -* old Z-axis, followed by THETA radians about the resulting X-axis, -* then PSI radians about the resulting Z-axis. -* -* The axis names can be any of the following, in any order or -* combination: X, Y, Z, uppercase or lowercase, 1, 2, 3. Normal -* axis labelling/numbering conventions apply; the xyz (=123) -* triad is right-handed. Thus, the 'ZXZ' example given above -* could be written 'zxz' or '313' (or even 'ZxZ' or '3xZ'). ORDER -* is terminated by length or by the first unrecognized character. -* -* Fewer than three rotations are acceptable, in which case the later -* angle arguments are ignored. If all rotations are zero, the -* identity matrix is produced. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-08 (TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1997 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void -palDeuler( const char *order, double phi, double theta, double psi, - double rmat[3][3] ) { - int i = 0; - double rotations[3]; - - /* Initialise rmat */ - eraIr( rmat ); - - /* copy the rotations into an array */ - rotations[0] = phi; - rotations[1] = theta; - rotations[2] = psi; - - /* maximum three rotations */ - while (i < 3 && order[i] != '\0') { - - switch (order[i]) { - case 'X': - case 'x': - case '1': - eraRx( rotations[i], rmat ); - break; - - case 'Y': - case 'y': - case '2': - eraRy( rotations[i], rmat ); - break; - - case 'Z': - case 'z': - case '3': - eraRz( rotations[i], rmat ); - break; - - default: - /* break out the loop if we do not recognize something */ - i = 3; - - } - - /* Go to the next position */ - i++; - } - - return; -} diff --git a/ast/pal/palDh2e.c b/ast/pal/palDh2e.c deleted file mode 100644 index 65434b7..0000000 --- a/ast/pal/palDh2e.c +++ /dev/null @@ -1,133 +0,0 @@ -/* -*+ -* Name: -* palDh2e - -* Purpose: -* Horizon to equatorial coordinates: Az,El to HA,Dec - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDh2e( double az, double el, double phi, double * ha, double * dec ); - -* Arguments: -* az = double (Given) -* Azimuth (radians) -* el = double (Given) -* Elevation (radians) -* phi = double (Given) -* Observatory latitude (radians) -* ha = double * (Returned) -* Hour angle (radians) -* dec = double * (Returned) -* Declination (radians) - -* Description: -* Convert horizon to equatorial coordinates. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* - All the arguments are angles in radians. -* - The sign convention for azimuth is north zero, east +pi/2. -* - HA is returned in the range +/-pi. Declination is returned -* in the range +/-pi/2. -* - The latitude is (in principle) geodetic. In critical -* applications, corrections for polar motion should be applied. -* - In some applications it will be important to specify the -* correct type of elevation in order to produce the required -* type of HA,Dec. In particular, it may be important to -* distinguish between the elevation as affected by refraction, -* which will yield the "observed" HA,Dec, and the elevation -* in vacuo, which will yield the "topocentric" HA,Dec. If the -* effects of diurnal aberration can be neglected, the -* topocentric HA,Dec may be used as an approximation to the -* "apparent" HA,Dec. -* - No range checking of arguments is done. -* - In applications which involve many such calculations, rather -* than calling the present routine it will be more efficient to -* use inline code, having previously computed fixed terms such -* as sine and cosine of latitude. - -* History: -* 2012-02-08 (TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1996 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include - -void -palDh2e ( double az, double el, double phi, double *ha, double *dec) { - - double sa; - double ca; - double se; - double ce; - double sp; - double cp; - - double x; - double y; - double z; - double r; - - /* Useful trig functions */ - sa = sin(az); - ca = cos(az); - se = sin(el); - ce = cos(el); - sp = sin(phi); - cp = cos(phi); - - /* HA,Dec as x,y,z */ - x = -ca * ce * sp + se * cp; - y = -sa * ce; - z = ca * ce * cp + se * sp; - - /* To HA,Dec */ - r = sqrt(x * x + y * y); - if (r == 0.) { - *ha = 0.; - } else { - *ha = atan2(y, x); - } - *dec = atan2(z, r); - - return; -} diff --git a/ast/pal/palDjcal.c b/ast/pal/palDjcal.c deleted file mode 100644 index b6aac9e..0000000 --- a/ast/pal/palDjcal.c +++ /dev/null @@ -1,97 +0,0 @@ -/* -*+ -* Name: -* palDjcal - -* Purpose: -* Modified Julian Date to Gregorian Calendar - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palDjcal ( int ndp, double djm, int iymdf[4], int *j ); - -* Arguments: -* ndp = int (Given) -* Number of decimal places of days in fraction. -* djm = double (Given) -* Modified Julian Date (JD-2400000.5) -* iymdf[4] = int[] (Returned) -* Year, month, day, fraction in Gregorian calendar. -* j = status (Returned) -* 0 = OK. See eraJd2cal for other values. - -* Description: -* Modified Julian Date to Gregorian Calendar, expressed -* in a form convenient for formatting messages (namely -* rounded to a specified precision, and with the fields -* stored in a single array) - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-10 (TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Notes: -* - Uses eraJd2cal - -* Copyright: -* Copyright (C) 2004 Patrick T. Wallace -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include - -#include "pal.h" -#include "palmac.h" -#include "pal1sofa.h" - -void palDjcal ( int ndp, double djm, int iymdf[4], int *j ) { - double frac = 0.0; - double nfd; - - *j = eraJd2cal( PAL__MJD0, djm, &(iymdf[0]), - &(iymdf[1]), &(iymdf[2]), - &frac); - - /* Convert ndp to a power of 10 */ - nfd = pow( 10., (double)ndp ); - - /* Multiply the fraction */ - frac *= nfd; - - /* and now we want to round to the nearest integer */ - iymdf[3] = (int)DNINT(frac); - -} diff --git a/ast/pal/palDmat.c b/ast/pal/palDmat.c deleted file mode 100644 index 2948f92..0000000 --- a/ast/pal/palDmat.c +++ /dev/null @@ -1,182 +0,0 @@ -/* -*+ -* Name: -* palDmat - -* Purpose: -* Matrix inversion & solution of simultaneous equations - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palDmat( int n, double *a, double *y, double *d, int *jf, -* int *iw ); - -* Arguments: -* n = int (Given) -* Number of simultaneous equations and number of unknowns. -* a = double[] (Given & Returned) -* A non-singular NxN matrix (implemented as a contiguous block -* of memory). After calling this routine "a" contains the -* inverse of the matrix. -* y = double[] (Given & Returned) -* On input the vector of N knowns. On exit this vector contains the -* N solutions. -* d = double * (Returned) -* The determinant. -* jf = int * (Returned) -* The singularity flag. If the matrix is non-singular, jf=0 -* is returned. If the matrix is singular, jf=-1 & d=0.0 are -* returned. In the latter case, the contents of array "a" on -* return are undefined. -* iw = int[] (Given) -* Integer workspace of size N. - -* Description: -* Matrix inversion & solution of simultaneous equations -* For the set of n simultaneous equations in n unknowns: -* A.Y = X -* this routine calculates the inverse of A, the determinant -* of matrix A and the vector of N unknowns. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-11 (TIMJ): -* Combination of a port of the Fortran and a comparison -* with the obfuscated GPL C routine. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Notes: -* - Implemented using Gaussian elimination with partial pivoting. -* - Optimized for speed rather than accuracy with errors 1 to 4 -* times those of routines optimized for accuracy. - -* Copyright: -* Copyright (C) 2001 Rutherford Appleton Laboratory. -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" - -void palDmat ( int n, double *a, double *y, double *d, int *jf, int *iw ) { - - const double SFA = 1e-20; - - int k; - double*aoff; - - *jf=0; - *d=1.0; - for(k=0,aoff=a; kamx){ - amx=t; - imx=i; - aoff2=apos2; - } - } - } - if(amx0;){ - int ki=iw[k]; - if(k!=ki){ - int i; - double *apos = a; - for(i=0;i. - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include - -double palDrange( double angle ){ - double result = fmod( angle, PAL__D2PI ); - if( result > PAL__DPI ) { - result -= PAL__D2PI; - } else if( result < -PAL__DPI ) { - result += PAL__D2PI; - } - return result; -} - diff --git a/ast/pal/palDs2tp.c b/ast/pal/palDs2tp.c deleted file mode 100644 index cbf582a..0000000 --- a/ast/pal/palDs2tp.c +++ /dev/null @@ -1,127 +0,0 @@ -/* -*+ -* Name: -* palDs2tp - -* Purpose: -* Spherical to tangent plane projection - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDs2tp( double ra, double dec, double raz, double decz, -* double *xi, double *eta, int *j ); - -* Arguments: -* ra = double (Given) -* RA spherical coordinate of point to be projected (radians) -* dec = double (Given) -* Dec spherical coordinate of point to be projected (radians) -* raz = double (Given) -* RA spherical coordinate of tangent point (radians) -* decz = double (Given) -* Dec spherical coordinate of tangent point (radians) -* xi = double * (Returned) -* First rectangular coordinate on tangent plane (radians) -* eta = double * (Returned) -* Second rectangular coordinate on tangent plane (radians) -* j = int * (Returned) -* status: 0 = OK, star on tangent plane -* 1 = error, star too far from axis -* 2 = error, antistar on tangent plane -* 3 = error, antistar too far from axis - -* Description: -* Projection of spherical coordinates onto tangent plane: -* "gnomonic" projection - "standard coordinates" - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-08 (TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1996 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include - -void -palDs2tp ( double ra, double dec, double raz, double decz, - double *xi, double *eta, int *j ) { - - const double TINY = 1.0e-6; - - double cdec; - double sdec; - double radif; - double cdecz; - double denom; - double sdecz; - double cradif; - double sradif; - - /* Trig functions */ - sdecz = sin(decz); - sdec = sin(dec); - cdecz = cos(decz); - cdec = cos(dec); - radif = ra - raz; - sradif = sin(radif); - cradif = cos(radif); - - /* Reciprocal of star vector length to tangent plane */ - denom = sdec * sdecz + cdec * cdecz * cradif; - - /* Handle vectors too far from axis */ - if (denom > TINY) { - *j = 0; - } else if (denom >= 0.) { - *j = 1; - denom = TINY; - } else if (denom > -TINY) { - *j = 2; - denom = -TINY; - } else { - *j = 3; - } - - /* Compute tangent plane coordinates (even in dubious cases) */ - *xi = cdec * sradif / denom; - *eta = (sdec * cdecz - cdec * sdecz * cradif) / denom; - - return; -} diff --git a/ast/pal/palDtp2s.c b/ast/pal/palDtp2s.c deleted file mode 100644 index 583a56d..0000000 --- a/ast/pal/palDtp2s.c +++ /dev/null @@ -1,95 +0,0 @@ -/* -*+ -* Name: -* palDtp2s - -* Purpose: -* Tangent plane to spherical coordinates - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDtp2s( double xi, double eta, double raz, double decz, -* double *ra, double *dec); - -* Arguments: -* xi = double (Given) -* First rectangular coordinate on tangent plane (radians) -* eta = double (Given) -* Second rectangular coordinate on tangent plane (radians) -* raz = double (Given) -* RA spherical coordinate of tangent point (radians) -* decz = double (Given) -* Dec spherical coordinate of tangent point (radians) -* ra = double * (Returned) -* RA spherical coordinate of point to be projected (radians) -* dec = double * (Returned) -* Dec spherical coordinate of point to be projected (radians) - -* Description: -* Transform tangent plane coordinates into spherical. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-08 (TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -#include - -void -palDtp2s ( double xi, double eta, double raz, double decz, - double *ra, double *dec ) { - - double cdecz; - double denom; - double sdecz; - double d; - - sdecz = sin(decz); - cdecz = cos(decz); - denom = cdecz - eta * sdecz; - d = atan2(xi, denom) + raz; - *ra = eraAnp(d); - *dec = atan2(sdecz + eta * cdecz, sqrt(xi * xi + denom * denom)); - - return; -} diff --git a/ast/pal/palDtps2c.c b/ast/pal/palDtps2c.c deleted file mode 100644 index ecb3090..0000000 --- a/ast/pal/palDtps2c.c +++ /dev/null @@ -1,151 +0,0 @@ -/* -*+ -* Name: -* palDtps2c - -* Purpose: -* Determine RA,Dec of tangent point from coordinates - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDtps2c( double xi, double eta, double ra, double dec, -* double * raz1, double decz1, -* double * raz2, double decz2, int *n); - -* Arguments: -* xi = double (Given) -* First rectangular coordinate on tangent plane (radians) -* eta = double (Given) -* Second rectangular coordinate on tangent plane (radians) -* ra = double (Given) -* RA spherical coordinate of star (radians) -* dec = double (Given) -* Dec spherical coordinate of star (radians) -* raz1 = double * (Returned) -* RA spherical coordinate of tangent point, solution 1 (radians) -* decz1 = double * (Returned) -* Dec spherical coordinate of tangent point, solution 1 (radians) -* raz2 = double * (Returned) -* RA spherical coordinate of tangent point, solution 2 (radians) -* decz2 = double * (Returned) -* Dec spherical coordinate of tangent point, solution 2 (radians) -* n = int * (Returned) -* number of solutions: 0 = no solutions returned (note 2) -* 1 = only the first solution is useful (note 3) -* 2 = both solutions are useful (note 3) - - -* Description: -* From the tangent plane coordinates of a star of known RA,Dec, -* determine the RA,Dec of the tangent point. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* - The RAZ1 and RAZ2 values are returned in the range 0-2pi. -* - Cases where there is no solution can only arise near the poles. -* For example, it is clearly impossible for a star at the pole -* itself to have a non-zero XI value, and hence it is -* meaningless to ask where the tangent point would have to be -* to bring about this combination of XI and DEC. -* - Also near the poles, cases can arise where there are two useful -* solutions. The argument N indicates whether the second of the -* two solutions returned is useful. N=1 indicates only one useful -* solution, the usual case; under these circumstances, the second -* solution corresponds to the "over-the-pole" case, and this is -* reflected in the values of RAZ2 and DECZ2 which are returned. -* - The DECZ1 and DECZ2 values are returned in the range +/-pi, but -* in the usual, non-pole-crossing, case, the range is +/-pi/2. -* - This routine is the spherical equivalent of the routine sla_DTPV2C. - -* History: -* 2012-02-08 (TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -#include - -void -palDtps2c( double xi, double eta, double ra, double dec, - double * raz1, double * decz1, - double * raz2, double * decz2, int *n) { - - double x2; - double y2; - double sd; - double cd; - double sdf; - double r2; - - x2 = xi * xi; - y2 = eta * eta; - sd = sin(dec); - cd = cos(dec); - sdf = sd * sqrt(x2 + 1. + y2); - r2 = cd * cd * (y2 + 1.) - sd * sd * x2; - if (r2 >= 0.) { - double r; - double s; - double c; - - r = sqrt(r2); - s = sdf - eta * r; - c = sdf * eta + r; - if (xi == 0. && r == 0.) { - r = 1.; - } - *raz1 = eraAnp(ra - atan2(xi, r)); - *decz1 = atan2(s, c); - r = -r; - s = sdf - eta * r; - c = sdf * eta + r; - *raz2 = eraAnp(ra - atan2(xi, r)); - *decz2 = atan2(s, c); - if (fabs(sdf) < 1.) { - *n = 1; - } else { - *n = 2; - } - } else { - *n = 0; - } - return; -} diff --git a/ast/pal/palDtt.c b/ast/pal/palDtt.c deleted file mode 100644 index f6a3714..0000000 --- a/ast/pal/palDtt.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -*+ -* Name: -* palDtt - -* Purpose: -* Return offset between UTC and TT - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* dtt = palDtt( double utc ); - -* Arguments: -* utc = double (Given) -* UTC date as a modified JD (JD-2400000.5) - -* Returned Value: -* dtt = double -* TT-UTC in seconds - -* Description: -* Increment to be applied to Coordinated Universal Time UTC to give -* Terrestrial Time TT (formerly Ephemeris Time ET) - -* Authors: -* TIMJ: Tim Jenness (JAC, Hawaii) -* PTW: Patrick T. Wallace -* {enter_new_authors_here} - -* Notes: -* - Consider a comprehensive upgrade to use the time transformations in SOFA's time -* cookbook: http://www.iausofa.org/sofa_ts_c.pdf. -* - See eraDat for a description of error conditions when calling this function -* with a time outside of the UTC range. This behaviour differs from slaDtt. - -* History: -* 2012-02-08 (TIMJ): -* Initial version -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" - -double palDtt( double utc ) { - return 32.184 + palDat( utc ); -} diff --git a/ast/pal/palEcmat.c b/ast/pal/palEcmat.c deleted file mode 100644 index e9d9aeb..0000000 --- a/ast/pal/palEcmat.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -*+ -* Name: -* palEcmat - -* Purpose: -* Form the equatorial to ecliptic rotation matrix - IAU 2006 -* precession model. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palEcmat( double date, double rmat[3][3] ) - -* Arguments: -* date = double (Given) -* TT as Modified Julian Date (JD-2400000.5). The difference -* between TT and TDB is of the order of a millisecond or two -* (i.e. about 0.02 arc-seconds). -* rmat = double[3][3] (Returned) -* Rotation matrix - -* Description: -* The equatorial to ecliptic rotation matrix is found and returned. -* The matrix is in the sense V(ecl) = RMAT * V(equ); the -* equator, equinox and ecliptic are mean of date. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-10 (DSB): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1996 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include "pal1sofa.h" - -void palEcmat( double date, double rmat[3][3] ) { - -/* Mean obliquity (the angle between the ecliptic and mean equator of - date). */ - double eps0 = eraObl06( PAL__MJD0, date ); - -/* Matrix */ - palDeuler( "X", eps0, 0.0, 0.0, rmat ); - -} diff --git a/ast/pal/palEqgal.c b/ast/pal/palEqgal.c deleted file mode 100644 index 9df3d09..0000000 --- a/ast/pal/palEqgal.c +++ /dev/null @@ -1,118 +0,0 @@ -/* -*+ -* Name: -* palEqgal - -* Purpose: -* Convert from J2000.0 equatorial coordinates to Galactic - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palEqgal ( double dr, double dd, double *dl, double *db ); - -* Arguments: -* dr = double (Given) -* J2000.0 RA (radians) -* dd = double (Given) -* J2000.0 Dec (radians -* dl = double * (Returned) -* Galactic longitude (radians). -* db = double * (Returned) -* Galactic latitude (radians). - -* Description: -* Transformation from J2000.0 equatorial coordinates -* to IAU 1958 galactic coordinates. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* The equatorial coordinates are J2000.0. Use the routine -* palGe50 if conversion to B1950.0 'FK4' coordinates is -* required. - -* See Also: -* Blaauw et al, Mon.Not.R.Astron.Soc.,121,123 (1960) - -* History: -* 2012-02-12(TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1998 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palEqgal ( double dr, double dd, double *dl, double *db ) { - - double v1[3]; - double v2[3]; - -/* -* L2,B2 system of galactic coordinates -* -* P = 192.25 RA of galactic north pole (mean B1950.0) -* Q = 62.6 inclination of galactic to mean B1950.0 equator -* R = 33 longitude of ascending node -* -* P,Q,R are degrees -* -* Equatorial to galactic rotation matrix (J2000.0), obtained by -* applying the standard FK4 to FK5 transformation, for zero proper -* motion in FK5, to the columns of the B1950 equatorial to -* galactic rotation matrix: -*/ - double rmat[3][3] = { - { -0.054875539726,-0.873437108010,-0.483834985808 }, - { +0.494109453312,-0.444829589425,+0.746982251810 }, - { -0.867666135858,-0.198076386122,+0.455983795705 } - }; - - /* Spherical to Cartesian */ - eraS2c( dr, dd, v1 ); - - /* Equatorial to Galactic */ - eraRxp( rmat, v1, v2 ); - - /* Cartesian to spherical */ - eraC2s( v2, dl, db ); - - /* Express in conventional ranges */ - *dl = eraAnp( *dl ); - *db = eraAnpm( *db ); - -} diff --git a/ast/pal/palEtrms.c b/ast/pal/palEtrms.c deleted file mode 100644 index 4484682..0000000 --- a/ast/pal/palEtrms.c +++ /dev/null @@ -1,106 +0,0 @@ -/* -*+ -* Name: -* palEtrms - -* Purpose: -* Compute the E-terms vector - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palEtrms ( double ep, double ev[3] ); - -* Arguments: -* ep = double (Given) -* Besselian epoch -* ev = double [3] (Returned) -* E-terms as (dx,dy,dz) - -* Description: -* Computes the E-terms (elliptic component of annual aberration) -* vector. -* -* Note the use of the J2000 aberration constant (20.49552 arcsec). -* This is a reflection of the fact that the E-terms embodied in -* existing star catalogues were computed from a variety of -* aberration constants. Rather than adopting one of the old -* constants the latest value is used here. -* -* See also: -* - Smith, C.A. et al., 1989. Astr.J. 97, 265. -* - Yallop, B.D. et al., 1989. Astr.J. 97, 274. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-12 (TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1996 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" - -void palEtrms ( double ep, double ev[3] ) { - - /* Use the J2000 aberration constant */ - const double ABCONST = 20.49552; - - double t, e, e0, p, ek, cp; - - /* Julian centuries since B1950 */ - t = (ep - 1950.) * .0100002135903; - - /* Eccentricity */ - e = .01673011 - (t * 1.26e-7 + 4.193e-5) * t; - - /* Mean obliquity */ - e0 = (84404.836 - ((t * .00181 + .00319) * t + 46.8495) * t) * - PAL__DAS2R; - - /* Mean longitude of perihelion */ - p = (((t * .012 + 1.65) * t + 6190.67) * t + 1015489.951) * - PAL__DAS2R; - - /* E-terms */ - ek = e * ABCONST * PAL__DAS2R; - cp = cos(p); - ev[0] = ek * sin(p); - ev[1] = -ek * cp * cos(e0); - ev[2] = -ek * cp * sin(e0); - -} diff --git a/ast/pal/palEvp.c b/ast/pal/palEvp.c deleted file mode 100644 index b30a3a9..0000000 --- a/ast/pal/palEvp.c +++ /dev/null @@ -1,110 +0,0 @@ -/* -*+ -* Name: -* palEvp - -* Purpose: -* Returns the barycentric and heliocentric velocity and position of the -* Earth. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palEvp( double date, double deqx, double dvb[3], double dpb[3], -* double dvh[3], double dph[3] ) - -* Arguments: -* date = double (Given) -* TDB (loosely ET) as a Modified Julian Date (JD-2400000.5) -* deqx = double (Given) -* Julian epoch (e.g. 2000.0) of mean equator and equinox of the -* vectors returned. If deqx <= 0.0, all vectors are referred to the -* mean equator and equinox (FK5) of epoch date. -* dvb = double[3] (Returned) -* Barycentric velocity (AU/s, AU) -* dpb = double[3] (Returned) -* Barycentric position (AU/s, AU) -* dvh = double[3] (Returned) -* heliocentric velocity (AU/s, AU) -* dph = double[3] (Returned) -* Heliocentric position (AU/s, AU) - -* Description: -* Returns the barycentric and heliocentric velocity and position of the -* Earth at a given epoch, given with respect to a specified equinox. -* For information about accuracy, see the function eraEpv00. - -* Authors: -* PTW: Pat Wallace (STFC) -* {enter_new_authors_here} - -* History: -* 2012-02-13 (PTW): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2005 Patrick T. Wallace -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include "pal1sofa.h" - -void palEvp( double date, double deqx, double dvb[3], double dpb[3], - double dvh[3], double dph[3] ){ - -/* Local Variables; */ - int i; - double pvh[2][3], pvb[2][3], d1, d2, r[3][3]; - -/* BCRS PV-vectors. */ - eraEpv00 ( 2400000.5, date, pvh, pvb ); - -/* Was precession to another equinox requested? */ - if ( deqx > 0.0 ) { - -/* Yes: compute precession matrix from J2000.0 to deqx. */ - eraEpj2jd ( deqx, &d1, &d2 ); - eraPmat06 ( d1, d2, r ); - -/* Rotate the PV-vectors. */ - eraRxpv ( r, pvh, pvh ); - eraRxpv ( r, pvb, pvb ); - } - -/* Return the required vectors. */ - for ( i = 0; i < 3; i++ ) { - dvh[i] = pvh[1][i] / PAL__SPD; - dvb[i] = pvb[1][i] / PAL__SPD; - dph[i] = pvh[0][i]; - dpb[i] = pvb[0][i]; - } -} diff --git a/ast/pal/palFk45z.c b/ast/pal/palFk45z.c deleted file mode 100644 index 643fd74..0000000 --- a/ast/pal/palFk45z.c +++ /dev/null @@ -1,186 +0,0 @@ -/* -*+ -* Name: -* palFk45z - -* Purpose: -* Convert B1950.0 FK4 star data to J2000.0 FK5 assuming zero -* proper motion in the FK5 frame - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palFk45z( double r1950, double d1950, double bepoch, double *r2000, -* double *d2000 ) - -* Arguments: -* r1950 = double (Given) -* B1950.0 FK4 RA at epoch (radians). -* d1950 = double (Given) -* B1950.0 FK4 Dec at epoch (radians). -* bepoch = double (Given) -* Besselian epoch (e.g. 1979.3) -* r2000 = double (Returned) -* J2000.0 FK5 RA (Radians). -* d2000 = double (Returned) -* J2000.0 FK5 Dec(Radians). - -* Description: -* Convert B1950.0 FK4 star data to J2000.0 FK5 assuming zero -* proper motion in the FK5 frame (double precision) -* -* This function converts stars from the Bessel-Newcomb, FK4 -* system to the IAU 1976, FK5, Fricke system, in such a -* way that the FK5 proper motion is zero. Because such a star -* has, in general, a non-zero proper motion in the FK4 system, -* the routine requires the epoch at which the position in the -* FK4 system was determined. -* -* The method is from Appendix 2 of Ref 1, but using the constants -* of Ref 4. - -* Notes: -* - The epoch BEPOCH is strictly speaking Besselian, but if a -* Julian epoch is supplied the result will be affected only to -* a negligible extent. -* -* - Conversion from Besselian epoch 1950.0 to Julian epoch 2000.0 -* only is provided for. Conversions involving other epochs will -* require use of the appropriate precession, proper motion, and -* E-terms routines before and/or after palFk45z is called. -* -* - In the FK4 catalogue the proper motions of stars within 10 -* degrees of the poles do not embody the differential E-term effect -* and should, strictly speaking, be handled in a different manner -* from stars outside these regions. However, given the general lack -* of homogeneity of the star data available for routine astrometry, -* the difficulties of handling positions that may have been -* determined from astrometric fields spanning the polar and non-polar -* regions, the likelihood that the differential E-terms effect was not -* taken into account when allowing for proper motion in past -* astrometry, and the undesirability of a discontinuity in the -* algorithm, the decision has been made in this routine to include the -* effect of differential E-terms on the proper motions for all stars, -* whether polar or not. At epoch 2000, and measuring on the sky rather -* than in terms of dRA, the errors resulting from this simplification -* are less than 1 milliarcsecond in position and 1 milliarcsecond per -* century in proper motion. -* -* References: -* - Aoki,S., et al, 1983. Astron.Astrophys., 128, 263. -* - Smith, C.A. et al, 1989. "The transformation of astrometric -* catalog systems to the equinox J2000.0". Astron.J. 97, 265. -* - Yallop, B.D. et al, 1989. "Transformation of mean star places -* from FK4 B1950.0 to FK5 J2000.0 using matrices in 6-space". -* Astron.J. 97, 274. -* - Seidelmann, P.K. (ed), 1992. "Explanatory Supplement to -* the Astronomical Almanac", ISBN 0-935702-68-7. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-10 (DSB): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1998 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include "pal1sofa.h" - -void palFk45z( double r1950, double d1950, double bepoch, double *r2000, - double *d2000 ){ - -/* Local Variables: */ - double w; - int i; - int j; - double r0[3], a1[3], v1[3], v2[6]; /* Position and position+velocity vectors */ - - -/* CANONICAL CONSTANTS (see references) */ - -/* Vector A. */ - double a[3] = { -1.62557E-6, -0.31919E-6, -0.13843E-6 }; - -/* Vectors Adot. */ - double ad[3] = { 1.245E-3, -1.580E-3, -0.659E-3 }; - -/* Matrix M (only half of which is needed here). */ - double em[6][3] = { {0.9999256782, -0.0111820611, -0.0048579477}, - {0.0111820610, 0.9999374784, -0.0000271765}, - {0.0048579479, -0.0000271474, 0.9999881997}, - {-0.000551, -0.238565, 0.435739}, - {0.238514, -0.002667, -0.008541}, - {-0.435623, 0.012254, 0.002117} }; - - -/* Spherical to Cartesian. */ - eraS2c( r1950, d1950, r0 ); - -/* Adjust vector A to give zero proper motion in FK5. */ - w = ( bepoch - 1950.0 )/PAL__PMF; - for( i = 0; i < 3; i++ ) { - a1[ i ] = a[ i ] + w*ad[ i ]; - } - -/* Remove e-terms. */ - w = r0[ 0 ]*a1[ 0 ] + r0[ 1 ]*a1[ 1 ] + r0[ 2 ]*a1[ 2 ]; - for( i = 0; i < 3; i++ ) { - v1[ i ] = r0[ i ] - a1[ i ] + w*r0[ i ]; - } - -/* Convert position vector to Fricke system. */ - for( i = 0; i < 6; i++ ) { - w = 0.0; - for( j = 0; j < 3; j++ ) { - w += em[ i ][ j ]*v1[ j ]; - } - v2[ i ] = w; - } - -/* Allow for fictitious proper motion in FK4. */ - w = ( palEpj( palEpb2d( bepoch ) ) - 2000.0 )/PAL__PMF; - for( i = 0; i < 3; i++ ) { - v2[ i ] += w*v2[ i + 3 ]; - } - -/* Revert to spherical coordinates. */ - eraC2s( v2, &w, d2000 ); - *r2000 = eraAnp( w ); -} - - diff --git a/ast/pal/palFk524.c b/ast/pal/palFk524.c deleted file mode 100644 index 47c3abb..0000000 --- a/ast/pal/palFk524.c +++ /dev/null @@ -1,259 +0,0 @@ -/* -*+ -* Name: -* palFk524 - -* Purpose: -* Convert J2000.0 FK5 star data to B1950.0 FK4. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palFk524( double r2000, double d2000, double dr2000, double dd2000, -* double p2000, double v2000, double *r1950, double *d1950, -* double *dr1950, double *dd1950, double *p1950, double *v1950 ) - -* Arguments: -* r2000 = double (Given) -* J2000.0 FK5 RA (radians). -* d2000 = double (Given) -* J2000.0 FK5 Dec (radians). -* dr2000 = double (Given) -* J2000.0 FK5 RA proper motion (rad/Jul.yr) -* dd2000 = double (Given) -* J2000.0 FK5 Dec proper motion (rad/Jul.yr) -* p2000 = double (Given) -* J2000.0 FK5 parallax (arcsec) -* v2000 = double (Given) -* J2000.0 FK5 radial velocity (km/s, +ve = moving away) -* r1950 = double * (Returned) -* B1950.0 FK4 RA (radians). -* d1950 = double * (Returned) -* B1950.0 FK4 Dec (radians). -* dr1950 = double * (Returned) -* B1950.0 FK4 RA proper motion (rad/Jul.yr) -* dd1950 = double * (Returned) -* B1950.0 FK4 Dec proper motion (rad/Jul.yr) -* p1950 = double * (Returned) -* B1950.0 FK4 parallax (arcsec) -* v1950 = double * (Returned) -* B1950.0 FK4 radial velocity (km/s, +ve = moving away) - -* Description: -* This function converts stars from the IAU 1976, FK5, Fricke -* system, to the Bessel-Newcomb, FK4 system. The precepts -* of Smith et al (Ref 1) are followed, using the implementation -* by Yallop et al (Ref 2) of a matrix method due to Standish. -* Kinoshita's development of Andoyer's post-Newcomb precession is -* used. The numerical constants from Seidelmann et al (Ref 3) are -* used canonically. - -* Notes: -* - The proper motions in RA are dRA/dt rather than -* cos(Dec)*dRA/dt, and are per year rather than per century. -* - Note that conversion from Julian epoch 2000.0 to Besselian -* epoch 1950.0 only is provided for. Conversions involving -* other epochs will require use of the appropriate precession, -* proper motion, and E-terms routines before and/or after -* FK524 is called. -* - In the FK4 catalogue the proper motions of stars within -* 10 degrees of the poles do not embody the differential -* E-term effect and should, strictly speaking, be handled -* in a different manner from stars outside these regions. -* However, given the general lack of homogeneity of the star -* data available for routine astrometry, the difficulties of -* handling positions that may have been determined from -* astrometric fields spanning the polar and non-polar regions, -* the likelihood that the differential E-terms effect was not -* taken into account when allowing for proper motion in past -* astrometry, and the undesirability of a discontinuity in -* the algorithm, the decision has been made in this routine to -* include the effect of differential E-terms on the proper -* motions for all stars, whether polar or not. At epoch 2000, -* and measuring on the sky rather than in terms of dRA, the -* errors resulting from this simplification are less than -* 1 milliarcsecond in position and 1 milliarcsecond per -* century in proper motion. -* -* References: -* - Smith, C.A. et al, 1989. "The transformation of astrometric -* catalog systems to the equinox J2000.0". Astron.J. 97, 265. -* - Yallop, B.D. et al, 1989. "Transformation of mean star places -* from FK4 B1950.0 to FK5 J2000.0 using matrices in 6-space". -* Astron.J. 97, 274. -* - Seidelmann, P.K. (ed), 1992. "Explanatory Supplement to -* the Astronomical Almanac", ISBN 0-935702-68-7. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-13 (DSB): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include "math.h" - -void palFk524( double r2000, double d2000, double dr2000, double dd2000, - double p2000, double v2000, double *r1950, double *d1950, - double *dr1950, double *dd1950, double *p1950, double *v1950 ){ - -/* Local Variables; */ - double r, d, ur, ud, px, rv; - double sr, cr, sd, cd, x, y, z, w; - double v1[ 6 ], v2[ 6 ]; - double xd, yd, zd; - double rxyz, wd, rxysq, rxy; - int i, j; - -/* Small number to avoid arithmetic problems. */ - static const double tiny = 1.0E-30; - -/* Canonical constants (see references). Constant vector and matrix. */ - double a[ 6 ] = { -1.62557E-6, -0.31919E-6, -0.13843E-6, - +1.245E-3, -1.580E-3, -0.659E-3 }; - double emi[ 6 ][ 6 ] = { - { 0.9999256795, 0.0111814828, 0.0048590039, - -0.00000242389840, -0.00000002710544, -0.00000001177742}, - {-0.0111814828, 0.9999374849, -0.0000271771, - 0.00000002710544, -0.00000242392702, 0.00000000006585 }, - {-0.0048590040, -0.0000271557, 0.9999881946, - 0.00000001177742, 0.00000000006585, -0.00000242404995 }, - {-0.000551, 0.238509, -0.435614, - 0.99990432, 0.01118145, 0.00485852 }, - {-0.238560, -0.002667, 0.012254, - -0.01118145, 0.99991613, -0.00002717}, - { 0.435730, -0.008541, 0.002117, - -0.00485852, -0.00002716, 0.99996684 } }; - -/* Pick up J2000 data (units radians and arcsec/JC). */ - r = r2000; - d = d2000; - ur = dr2000*PAL__PMF; - ud = dd2000*PAL__PMF; - px = p2000; - rv = v2000; - -/* Spherical to Cartesian. */ - sr = sin( r ); - cr = cos( r ); - sd = sin( d ); - cd = cos( d ); - - x = cr*cd; - y = sr*cd; - z = sd; - - w = PAL__VF*rv*px; - - v1[ 0 ] = x; - v1[ 1 ] = y; - v1[ 2 ] = z; - - v1[ 3 ] = -ur*y - cr*sd*ud + w*x; - v1[ 4 ] = ur*x - sr*sd*ud + w*y; - v1[ 5 ] = cd*ud + w*z; - -/* Convert position+velocity vector to BN system. */ - for( i = 0; i < 6; i++ ) { - w = 0.0; - for( j = 0; j < 6; j++ ) { - w += emi[ i ][ j ]*v1[ j ]; - } - v2[ i ] = w; - } - -/* Position vector components and magnitude. */ - x = v2[ 0 ]; - y = v2[ 1 ]; - z = v2[ 2 ]; - rxyz = sqrt( x*x + y*y + z*z ); - -/* Apply E-terms to position. */ - w = x*a[ 0 ] + y*a[ 1 ] + z*a[ 2 ]; - x += a[ 0 ]*rxyz - w*x; - y += a[ 1 ]*rxyz - w*y; - z += a[ 2 ]*rxyz - w*z; - -/* Recompute magnitude. */ - rxyz = sqrt( x*x + y*y + z*z ); - -/* Apply E-terms to both position and velocity. */ - x = v2[ 0 ]; - y = v2[ 1 ]; - z = v2[ 2 ]; - w = x*a[ 0 ] + y*a[ 1 ] + z*a[ 2 ]; - wd = x*a[ 3 ] + y*a[ 4 ] + z*a[ 5 ]; - x += a[ 0 ]*rxyz - w*x; - y += a[ 1 ]*rxyz - w*y; - z += a[ 2 ]*rxyz - w*z; - xd = v2[ 3 ] + a[ 3 ]*rxyz - wd*x; - yd = v2[ 4 ] + a[ 4 ]*rxyz - wd*y; - zd = v2[ 5 ] + a[ 5 ]*rxyz - wd*z; - -/* Convert to spherical. */ - rxysq = x*x + y*y; - rxy = sqrt( rxysq ); - - if( x == 0.0 && y == 0.0 ) { - r = 0.0; - } else { - r = atan2( y, x ); - if( r < 0.0 ) r += PAL__D2PI; - } - d = atan2( z, rxy ); - - if( rxy > tiny ) { - ur = ( x*yd - y*xd )/rxysq; - ud = ( zd*rxysq - z*( x*xd + y*yd ) )/( ( rxysq + z*z )*rxy ); - } - -/* Radial velocity and parallax. */ - if( px > tiny ) { - rv = ( x*xd + y*yd + z*zd )/( px*PAL__VF*rxyz ); - px /= rxyz; - } - -/* Return results. */ - *r1950 = r; - *d1950 = d; - *dr1950 = ur/PAL__PMF; - *dd1950 = ud/PAL__PMF; - *p1950 = px; - *v1950 = rv; -} diff --git a/ast/pal/palFk54z.c b/ast/pal/palFk54z.c deleted file mode 100644 index b902b0d..0000000 --- a/ast/pal/palFk54z.c +++ /dev/null @@ -1,113 +0,0 @@ -/* -*+ -* Name: -* palFk54z - -* Purpose: -* Convert a J2000.0 FK5 star position to B1950.0 FK4 assuming -* zero proper motion and parallax. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palFk54z( double r2000, double d2000, double bepoch, double *r1950, -* double *d1950, double *dr1950, double *dd1950 ) - -* Arguments: -* r2000 = double (Given) -* J2000.0 FK5 RA (radians). -* d2000 = double (Given) -* J2000.0 FK5 Dec (radians). -* bepoch = double (Given) -* Besselian epoch (e.g. 1950.0). -* r1950 = double * (Returned) -* B1950 FK4 RA (radians) at epoch "bepoch". -* d1950 = double * (Returned) -* B1950 FK4 Dec (radians) at epoch "bepoch". -* dr1950 = double * (Returned) -* B1950 FK4 proper motion (RA) (radians/trop.yr)). -* dr1950 = double * (Returned) -* B1950 FK4 proper motion (Dec) (radians/trop.yr)). - -* Description: -* This function converts star positions from the IAU 1976, -* FK5, Fricke system to the Bessel-Newcomb, FK4 system. - -* Notes: -* - The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt. -* - Conversion from Julian epoch 2000.0 to Besselian epoch 1950.0 -* only is provided for. Conversions involving other epochs will -* require use of the appropriate precession functions before and -* after this function is called. -* - The FK5 proper motions, the parallax and the radial velocity -* are presumed zero. -* - It is the intention that FK5 should be a close approximation -* to an inertial frame, so that distant objects have zero proper -* motion; such objects have (in general) non-zero proper motion -* in FK4, and this function returns those fictitious proper -* motions. -* - The position returned by this function is in the B1950 -* reference frame but at Besselian epoch BEPOCH. For comparison -* with catalogues the "bepoch" argument will frequently be 1950.0. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-13 (DSB): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palFk54z( double r2000, double d2000, double bepoch, double *r1950, - double *d1950, double *dr1950, double *dd1950 ){ - -/* Local Variables: */ - double r, d, px, rv, y; - -/* FK5 equinox J2000 (any epoch) to FK4 equinox B1950 epoch B1950. */ - palFk524( r2000, d2000, 0.0, 0.0, 0.0, 0.0, &r, &d, dr1950, dd1950, - &px, &rv ); - -/* Fictitious proper motion to epoch "bepoch". */ - y = bepoch - 1950.0; - *r1950 = r + *dr1950*y; - *d1950 = d + *dd1950*y; - -} - diff --git a/ast/pal/palGaleq.c b/ast/pal/palGaleq.c deleted file mode 100644 index d0da1ee..0000000 --- a/ast/pal/palGaleq.c +++ /dev/null @@ -1,118 +0,0 @@ -/* -*+ -* Name: -* palGaleq - -* Purpose: -* Convert from galactic to J2000.0 equatorial coordinates - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palGaleq ( double dl, double db, double *dr, double *dd ); - -* Arguments: -* dl = double (Given) -* Galactic longitude (radians). -* db = double (Given) -* Galactic latitude (radians). -* dr = double * (Returned) -* J2000.0 RA (radians) -* dd = double * (Returned) -* J2000.0 Dec (radians) - -* Description: -* Transformation from IAU 1958 galactic coordinates to -* J2000.0 equatorial coordinates. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* The equatorial coordinates are J2000.0. Use the routine -* palGe50 if conversion to B1950.0 'FK4' coordinates is -* required. - -* See Also: -* Blaauw et al, Mon.Not.R.Astron.Soc.,121,123 (1960) - -* History: -* 2012-02-12(TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1998 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palGaleq ( double dl, double db, double *dr, double *dd ) { - - double v1[3]; - double v2[3]; - -/* -* L2,B2 system of galactic coordinates -* -* P = 192.25 RA of galactic north pole (mean B1950.0) -* Q = 62.6 inclination of galactic to mean B1950.0 equator -* R = 33 longitude of ascending node -* -* P,Q,R are degrees -* -* Equatorial to galactic rotation matrix (J2000.0), obtained by -* applying the standard FK4 to FK5 transformation, for zero proper -* motion in FK5, to the columns of the B1950 equatorial to -* galactic rotation matrix: -*/ - double rmat[3][3] = { - { -0.054875539726,-0.873437108010,-0.483834985808 }, - { +0.494109453312,-0.444829589425,+0.746982251810 }, - { -0.867666135858,-0.198076386122,+0.455983795705 } - }; - - /* Spherical to Cartesian */ - eraS2c( dl, db, v1 ); - - /* Galactic to equatorial */ - eraTrxp( rmat, v1, v2 ); - - /* Cartesian to spherical */ - eraC2s( v2, dr, dd ); - - /* Express in conventional ranges */ - *dr = eraAnp( *dr ); - *dd = eraAnpm( *dd ); - -} diff --git a/ast/pal/palGalsup.c b/ast/pal/palGalsup.c deleted file mode 100644 index e469fb7..0000000 --- a/ast/pal/palGalsup.c +++ /dev/null @@ -1,116 +0,0 @@ -/* -*+ -* Name: -* palGalsup - -* Purpose: -* Convert from galactic to supergalactic coordinates - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palGalsup ( double dl, double db, double *dsl, double *dsb ); - -* Arguments: -* dl = double (Given) -* Galactic longitude. -* db = double (Given) -* Galactic latitude. -* dsl = double * (Returned) -* Supergalactic longitude. -* dsb = double * (Returned) -* Supergalactic latitude. - -* Description: -* Transformation from IAU 1958 galactic coordinates to -* de Vaucouleurs supergalactic coordinates. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* See Also: -* - de Vaucouleurs, de Vaucouleurs, & Corwin, Second Reference -* Catalogue of Bright Galaxies, U. Texas, page 8. -* - Systems & Applied Sciences Corp., Documentation for the -* machine-readable version of the above catalogue, -* Contract NAS 5-26490. -* -* (These two references give different values for the galactic -* longitude of the supergalactic origin. Both are wrong; the -* correct value is L2=137.37.) - -* History: -* 2012-02-12(TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1999 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palGalsup ( double dl, double db, double *dsl, double *dsb ) { - - double v1[3]; - double v2[3]; - -/* -* System of supergalactic coordinates: -* -* SGL SGB L2 B2 (deg) -* - +90 47.37 +6.32 -* 0 0 - 0 -* -* Galactic to supergalactic rotation matrix: -*/ - double rmat[3][3] = { - { -0.735742574804,+0.677261296414,+0.000000000000 }, - { -0.074553778365,-0.080991471307,+0.993922590400 }, - { +0.673145302109,+0.731271165817,+0.110081262225 } - }; - - /* Spherical to Cartesian */ - eraS2c( dl, db, v1 ); - - /* Galactic to Supergalactic */ - eraRxp( rmat, v1, v2 ); - - /* Cartesian to spherical */ - eraC2s( v2, dsl, dsb ); - - /* Express in conventional ranges */ - *dsl = eraAnp( *dsl ); - *dsb = eraAnpm( *dsb ); - -} diff --git a/ast/pal/palGeoc.c b/ast/pal/palGeoc.c deleted file mode 100644 index 9954d92..0000000 --- a/ast/pal/palGeoc.c +++ /dev/null @@ -1,83 +0,0 @@ -/* -*+ -* Name: -* palGeoc - -* Purpose: -* Convert geodetic position to geocentric - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palGeoc( double p, double h, double * r, double *z ); - -* Arguments: -* p = double (Given) -* latitude (radians) -* h = double (Given) -* height above reference spheroid (geodetic, metres) -* r = double * (Returned) -* distance from Earth axis (AU) -* z = double * (Returned) -* distance from plane of Earth equator (AU) - -* Description: -* Convert geodetic position to geocentric. - -* Authors: -* PTW: Patrick T. Wallace -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* - Geocentric latitude can be obtained by evaluating atan2(z,r) -* - Uses WGS84 reference ellipsoid and calls eraGd2gc - -* History: -* 2012-03-01 (TIMJ): -* Initial version moved from palOne2One -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2004 Patrick T. Wallace -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palGeoc ( double p, double h, double *r, double *z ) { - double xyz[3]; - const double elong = 0.0; /* Use zero longitude */ - const double AU = 1.49597870E11; - /* WGS84 looks to be the closest match */ - eraGd2gc( ERFA_WGS84, elong, p, h, xyz ); - *r = xyz[0] / (AU * cos(elong) ); - *z = xyz[2] / AU; -} diff --git a/ast/pal/palMappa.c b/ast/pal/palMappa.c deleted file mode 100644 index 4e7ee64..0000000 --- a/ast/pal/palMappa.c +++ /dev/null @@ -1,129 +0,0 @@ -/* -*+ -* Name: -* palMappa - -* Purpose: -* Compute parameters needed by palAmpqk and palMapqk. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palMappa( double eq, double date, double amprms[21] ) - -* Arguments: -* eq = double (Given) -* epoch of mean equinox to be used (Julian) -* date = double (Given) -* TDB (JD-2400000.5) -* amprms = double[21] (Returned) -* star-independent mean-to-apparent parameters: -* - (0) time interval for proper motion (Julian years) -* - (1-3) barycentric position of the Earth (AU) -* - (4-6) heliocentric direction of the Earth (unit vector) -* - (7) (Schwarzschild radius of Sun)/(Sun-Earth distance) -* - (8-10) abv: barycentric Earth velocity in units of c -* - (11) sqrt(1-v^2) where v=modulus(abv) -* - (12-20) precession/nutation (3,3) matrix - -* Description: -* Compute star-independent parameters in preparation for -* transformations between mean place and geocentric apparent place. -* -* The parameters produced by this function are required in the -* parallax, aberration, and nutation/bias/precession parts of the -* mean/apparent transformations. -* -* The reference systems and timescales used are IAU 2006. - -* Notes: -* - For date, the distinction between the required TDB and TT -* is always negligible. Moreover, for all but the most -* critical applications UTC is adequate. -* - The vector amprms(1-3) is referred to the mean equinox and -* equator of epoch eq. -* - The parameters amprms produced by this function are used by -* palAmpqk, palMapqk and palMapqkz. - -* Authors: -* PTW: Pat Wallace (STFC) -* {enter_new_authors_here} - -* History: -* 2012-02-13 (PTW): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2003 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include "pal1sofa.h" - -#include - -void palMappa( double eq, double date, double amprms[21] ){ - -/* Local constants */ - -/* Gravitational radius of the Sun x 2 (2*mu/c**2, AU) */ - const double GR2 = 2.0 * 9.87063e-9; - -/* Local Variables; */ - int i; - double ebd[ 3 ], ehd[ 3 ], eh[ 3 ], e, vn[ 3 ], vm; - -/* Initialise so that unsused values are returned holding zero */ - memset( amprms, 0, 21*sizeof( *amprms ) ); - -/* Time interval for proper motion correction. */ - amprms[ 0 ] = eraEpj( PAL__MJD0, date ) - eq; - -/* Get Earth barycentric and heliocentric position and velocity. */ - palEvp( date, eq, ebd, &rms[ 1 ], ehd, eh ); - -/* Heliocentric direction of Earth (normalized) and modulus. */ - eraPn( eh, &e, &rms[ 4 ] ); - -/* Light deflection parameter */ - amprms[7] = GR2 / e; - -/* Aberration parameters. */ - for( i = 0; i < 3; i++ ) { - amprms[ i + 8 ] = ebd[ i ]*PAL__CR; - } - eraPn( &rms[8], &vm, vn ); - amprms[ 11 ] = sqrt( 1.0 - vm*vm ); - -/* NPB matrix. */ - palPrenut( eq, date, (double(*)[ 3 ]) &rms[ 12 ] ); -} diff --git a/ast/pal/palMapqkz.c b/ast/pal/palMapqkz.c deleted file mode 100644 index 44a2c79..0000000 --- a/ast/pal/palMapqkz.c +++ /dev/null @@ -1,150 +0,0 @@ -/* -*+ -* Name: -* palMapqkz - -* Purpose: -* Quick mean to apparent place (no proper motion or parallax). - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palMapqkz( double rm, double dm, double amprms[21], -* double *ra, double *da ) - -* Arguments: -* rm = double (Given) -* Mean RA (radians). -* dm = double (Given) -* Mean Dec (radians). -* amprms = double[21] (Given) -* Star-independent mean-to-apparent parameters (see palMappa): -* (0-3) not used -* (4-6) heliocentric direction of the Earth (unit vector) -* (7) not used -* (8-10) abv: barycentric Earth velocity in units of c -* (11) sqrt(1-v^2) where v=modulus(abv) -* (12-20) precession/nutation (3,3) matrix -* ra = double * (Returned) -* Apparent RA (radians). -* da = double * (Returned) -* Apparent Dec (radians). - -* Description: -* Quick mean to apparent place: transform a star RA,dec from -* mean place to geocentric apparent place, given the -* star-independent parameters, and assuming zero parallax -* and proper motion. -* -* Use of this function is appropriate when efficiency is important -* and where many star positions, all with parallax and proper -* motion either zero or already allowed for, and all referred to -* the same equator and equinox, are to be transformed for one -* epoch. The star-independent parameters can be obtained by -* calling the palMappa function. -* -* The corresponding function for the case of non-zero parallax -* and proper motion is palMapqk. - -* Notes: -* - The reference systems and timescales used are IAU 2006. -* - The mean place rm, dm and the vectors amprms[1-3] and amprms[4-6] -* are referred to the mean equinox and equator of the epoch -* specified when generating the precession/nutation matrix -* amprms[12-20]. In the call to palMappa (q.v.) normally used -* to populate amprms, this epoch is the first argument (eq). -* - The vector amprms(4-6) is referred to the mean equinox and -* equator of epoch eq. -* - Strictly speaking, the routine is not valid for solar-system -* sources, though the error will usually be extremely small. -* However, to prevent gross errors in the case where the -* position of the Sun is specified, the gravitational -* deflection term is restrained within about 920 arcsec of the -* centre of the Sun's disc. The term has a maximum value of -* about 1.85 arcsec at this radius, and decreases to zero as -* the centre of the disc is approached. - -* Authors: -* PTW: Pat Wallace (STFC) -* {enter_new_authors_here} - -* History: -* 2012-02-13 (PTW): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1999 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palMapqkz ( double rm, double dm, double amprms[21], double *ra, - double *da ){ - -/* Local Variables: */ - int i; - double ab1, abv[3], p[3], w, p1dv, p2[3], p3[3]; - double gr2e, pde, pdep1, ehn[3], p1[3]; - -/* Unpack scalar and vector parameters. */ - ab1 = amprms[11]; - gr2e = amprms[7]; - for( i = 0; i < 3; i++ ) { - abv[i] = amprms[i+8]; - ehn[i] = amprms[i+4]; - } - -/* Spherical to x,y,z. */ - eraS2c( rm, dm, p ); - -/* Light deflection (restrained within the Sun's disc) */ - pde = eraPdp( p, ehn ); - pdep1 = pde + 1.0; - w = gr2e / ( pdep1 > 1.0e-5 ? pdep1 : 1.0e-5 ); - for( i = 0; i < 3; i++) { - p1[i] = p[i] + w * ( ehn[i] - pde * p[i] ); - } - -/* Aberration. */ - p1dv = eraPdp( p1, abv ); - w = 1.0 + p1dv / ( ab1 + 1.0 ); - for( i = 0; i < 3; i++ ) { - p2[i] = ( ( ab1 * p1[i] ) + ( w * abv[i] ) ); - } - -/* Precession and nutation. */ - eraRxp( (double(*)[3]) &rms[12], p2, p3 ); - -/* Geocentric apparent RA,dec. */ - eraC2s( p3, ra, da ); - *ra = eraAnp( *ra ); -} diff --git a/ast/pal/palOne2One.c b/ast/pal/palOne2One.c deleted file mode 100644 index a8d8072..0000000 --- a/ast/pal/palOne2One.c +++ /dev/null @@ -1,1482 +0,0 @@ -/* -*+ -* Name: -* palOne2One - -* Purpose: -* File containing simple PAL wrappers for SLA routines that are identical in SOFA - -* Invocation: -* Matches SLA API - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Description: -* Some SOFA/ERFA routines are identical to their SLA counterparts. PAL provides -* direct counterparts to these although it is generally a better idea to -* use the SOFA/ERFA routine directly in new code. -* -* The PAL routines with direct equivalents in SOFA/ERFA are: -* - palCldj -* - palDbear -* - palDaf2r -* - palDav2m -* - palDcc2s -* - palDcs2c -* - palDd2tf -* - palDimxv -* - palDm2av -* - palDjcl -* - palDmxm -* - palDmxv -* - palDpav -* - palDr2af -* - palDr2tf -* - palDranrm -* - palDsep -* - palDsepv -* - palDtf2d -* - palDtf2r -* - palDvdv -* - palDvn -* - palDvxv -* - palEpb -* - palEpb2d -* - palEpj -* - palEpj2d -* - palEqeqx -* - palFk5hz -* - palGmst -* - palGmsta -* - palHfk5z -* - palRefcoq - -* Authors: -* TIMJ: Tim Jenness (JAC, Hawaii) -* DSB: David S Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* - Do not call these functions from other PAL functions. Always use -* the SOFA/ERFA routines directly in new code. -* - These are implemented as real functions rather than C preprocessor -* macros so there may be a performance penalty in using the PAL -* version instead of the SOFA/ERFA version. -* - Routines that take MJDs have SOFA/ERFA equivalents that have an explicit -* MJD offset included. -* - palEqeqx, palGmst and palGmsta use the IAU 2006 precession model. - -* History: -* 2012-02-10 (TIMJ): -* Initial version -* Adapted with permission from the Fortran SLALIB library. -* 2012-03-23 (TIMJ): -* Update prologue. -* 2012-05-09 (DSBJ): -* Move palDrange into a separate file. -* 2014-07-15 (TIMJ): -* SOFA now has palRefcoq equivalent. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2014 Tim Jenness -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include "pal1sofa.h" - -/* -*+ -* Name: -* palCldj - -* Purpose: -* Gregorian Calendar to Modified Julian Date - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palCldj( int iy, int im, int id, double *djm, int *j ); - -* Arguments: -* iy = int (Given) -* Year in Gregorian calendar -* im = int (Given) -* Month in Gregorian calendar -* id = int (Given) -* Day in Gregorian calendar -* djm = double * (Returned) -* Modified Julian Date (JD-2400000.5) for 0 hrs -* j = int * (Returned) -* status: 0 = OK, 1 = bad year (MJD not computed), -* 2 = bad month (MJD not computed), 3 = bad day (MJD computed). - -* Description: -* Gregorian calendar to Modified Julian Date. - -* Notes: -* - Uses eraCal2jd(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palCldj ( int iy, int im, int id, double *djm, int *j ) { - double djm0; - *j = eraCal2jd( iy, im, id, &djm0, djm ); -} - -/* -*+ -* Name: -* palDbear - -* Purpose: -* Bearing (position angle) of one point on a sphere relative to another - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* pa = palDbear( double a1, double b1, double a2, double b2 ); - -* Arguments: -* a1 = double (Given) -* Longitude of point A (e.g. RA) in radians. -* a2 = double (Given) -* Latitude of point A (e.g. Dec) in radians. -* b1 = double (Given) -* Longitude of point B in radians. -* b2 = double (Given) -* Latitude of point B in radians. - -* Returned Value: -* The result is the bearing (position angle), in radians, of point -* A2,B2 as seen from point A1,B1. It is in the range +/- pi. If -* A2,B2 is due east of A1,B1 the bearing is +pi/2. Zero is returned -* if the two points are coincident. - -* Description: -* Bearing (position angle) of one point in a sphere relative to another. - -* Notes: -* - Uses eraPas(). See SOFA/ERFA documentation for details. - -*- -*/ - -double palDbear ( double a1, double b1, double a2, double b2 ) { - return eraPas( a1, b1, a2, b2 ); -} - -/* -*+ -* Name: -* palDaf2r - -* Purpose: -* Convert degrees, arcminutes, arcseconds to radians - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDaf2r( int ideg, int iamin, double asec, double *rad, int *j ); - -* Arguments: -* ideg = int (Given) -* Degrees. -* iamin = int (Given) -* Arcminutes. -* iasec = double (Given) -* Arcseconds. -* rad = double * (Returned) -* Angle in radians. -* j = int * (Returned) -* Status: 0 = OK, 1 = "ideg" out of range 0-359, -* 2 = "iamin" outside of range 0-59, -* 2 = "asec" outside range 0-59.99999 - -* Description: -* Convert degrees, arcminutes, arcseconds to radians. - -* Notes: -* - Uses eraAf2a(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Arguments differ slightly. Assumes that the sign is always positive - and dealt with externally. */ -void palDaf2r ( int ideg, int iamin, double asec, double *rad, int *j ) { - *j = eraAf2a( ' ', ideg, iamin, asec, rad ); -} - -/* -*+ -* Name: -* palDav2m - -* Purpose: -* Form the rotation matrix corresponding to a given axial vector. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDav2m( double axvec[3], double rmat[3][3] ); - -* Arguments: -* axvec = double [3] (Given) -* Axial vector (radians) -* rmat = double [3][3] (Returned) -* Rotation matrix. - -* Description: -* A rotation matrix describes a rotation about some arbitrary axis, -* called the Euler axis. The "axial vector" supplied to this routine -* has the same direction as the Euler axis, and its magnitude is the -* amount of rotation in radians. - -* Notes: -* - Uses eraRv2m(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDav2m ( double axvec[3], double rmat[3][3] ) { - eraRv2m( axvec, rmat ); -} - -/* -*+ -* Name: -* palDcc2s - -* Purpose: -* Cartesian to spherical coordinates - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDcc2s( double v[3], double *a, double *b ); - -* Arguments: -* v = double [3] (Given) -* x, y, z vector. -* a = double * (Returned) -* Spherical coordinate (radians) -* b = double * (Returned) -* Spherical coordinate (radians) - -* Description: -* The spherical coordinates are longitude (+ve anticlockwise looking -* from the +ve latitude pole) and latitude. The Cartesian coordinates -* are right handed, with the x axis at zero longitude and latitude, and -* the z axis at the +ve latitude pole. - -* Notes: -* - Uses eraC2s(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDcc2s ( double v[3], double *a, double *b ) { - eraC2s( v, a, b ); -} - -/* -*+ -* Name: -* palDcs2c - -* Purpose: -* Spherical coordinates to direction cosines - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDcs2c( double a, double b, double v[3] ); - -* Arguments: -* a = double (Given) -* Spherical coordinate in radians (ra, long etc). -* b = double (Given) -* Spherical coordinate in radians (dec, lat etc). -* v = double [3] (Returned) -* x, y, z vector - -* Description: -* The spherical coordinates are longitude (+ve anticlockwise looking -* from the +ve latitude pole) and latitude. The Cartesian coordinates -* are right handed, with the x axis at zero longitude and latitude, and -* the z axis at the +ve latitude pole. - -* Notes: -* - Uses eraS2c(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDcs2c ( double a, double b, double v[3] ) { - eraS2c( a, b, v ); -} - -/* -*+ -* Name: -* palDd2tf - -* Purpose: -* Convert an interval in days into hours, minutes, seconds - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDd2tf( int ndp, double days, char *sign, int ihmsf[4] ); - -* Arguments: -* ndp = int (Given) -* Number of decimal places of seconds -* days = double (Given) -* Interval in days -* sign = char * (Returned) -* '+' or '-' (single character, not string) -* ihmsf = int [4] (Returned) -* Hours, minutes, seconds, fraction - -* Description: -* Convert and interval in days into hours, minutes, seconds. - -* Notes: -* - Uses eraD2tf(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDd2tf ( int ndp, double days, char *sign, int ihmsf[4] ) { - eraD2tf( ndp, days, sign, ihmsf ); -} - -/* -*+ -* Name: -* palDimxv - -* Purpose: -* Perform the 3-D backward unitary transformation - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDimxv( double dm[3][3], double va[3], double vb[3] ); - -* Arguments: -* dm = double [3][3] (Given) -* Matrix -* va = double [3] (Given) -* vector -* vb = double [3] (Returned) -* Result vector - -* Description: -* Perform the 3-D backward unitary transformation. - -* Notes: -* - Uses eraTrxp(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDimxv ( double dm[3][3], double va[3], double vb[3] ) { - eraTrxp( dm, va, vb ); -} - -/* -*+ -* Name: -* palDm2av - -* Purpose: -* From a rotation matrix, determine the corresponding axial vector - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDm2av( double rmat[3][3], double axvec[3] ); - -* Arguments: -* rmat = double [3][3] (Given) -* Rotation matrix -* axvec = double [3] (Returned) -* Axial vector (radians) - -* Description: -* A rotation matrix describes a rotation about some arbitrary axis, -* called the Euler axis. The "axial vector" returned by this routine -* has the same direction as the Euler axis, and its magnitude is the -* amount of rotation in radians. (The magnitude and direction can be -* separated by means of the routine palDvn.) - -* Notes: -* - Uses eraRm2v(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDm2av ( double rmat[3][3], double axvec[3] ) { - eraRm2v( rmat, axvec ); -} - -/* -*+ -* Name: -* palDjcl - -* Purpose: -* Modified Julian Date to Gregorian year, month, day and fraction of day - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDjcl( double djm, int *iy, int *im, int *id, double *fd, int *j ); - -* Arguments: -* djm = double (Given) -* modified Julian Date (JD-2400000.5) -* iy = int * (Returned) -* year -* im = int * (Returned) -* month -* id = int * (Returned) -* day -* fd = double * (Returned) -* Fraction of day. - -* Description: -* Modified Julian Date to Gregorian year, month, day and fraction of day. - -* Notes: -* - Uses eraJd2cal(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Requires additional SLA MJD reference date */ -void palDjcl ( double djm, int *iy, int *im, int *id, double *fd, int *j ) { - *j = eraJd2cal( PAL__MJD0, djm, iy, im, id, fd ); -} - -/* -*+ -* Name: -* palDmxm - -* Purpose: -* Product of two 3x3 matrices - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDmxm( double a[3][3], double b[3][3], double c[3][3] ); - -* Arguments: -* a = double [3][3] (Given) -* Matrix -* b = double [3][3] (Given) -* Matrix -* c = double [3][3] (Returned) -* Matrix result - -* Description: -* Product of two 3x3 matrices. - -* Notes: -* - Uses eraRxr(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDmxm ( double a[3][3], double b[3][3], double c[3][3] ) { - eraRxr( a, b, c ); -} - -/* -*+ -* Name: -* palDmxv - -* Purpose: -* Performs the 3-D forward unitary transformation - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDmxv( double dm[3][3], double va[3], double vb[3] ); - -* Arguments: -* dm = double [3][3] (Given) -* matrix -* va = double [3] (Given) -* vector -* dp = double [3] (Returned) -* result vector - -* Description: -* Performs the 3-D forward unitary transformation. - -* Notes: -* - Uses eraRxp(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDmxv ( double dm[3][3], double va[3], double vb[3] ) { - eraRxp( dm, va, vb ); -} - -/* -*+ -* Name: -* palDpav - -* Purpose: -* Position angle of one celestial direction with respect to another - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* pa = palDpav( double v1[3], double v2[3] ); - -* Arguments: -* v1 = double [3] (Given) -* direction cosines of one point. -* v2 = double [3] (Given) -* direction cosines of the other point. - -* Returned Value: -* The result is the bearing (position angle), in radians, of point -* V2 with respect to point V1. It is in the range +/- pi. The -* sense is such that if V2 is a small distance east of V1, the -* bearing is about +pi/2. Zero is returned if the two points -* are coincident. - -* Description: -* Position angle of one celestial direction with respect to another. - -* Notes: -* - The coordinate frames correspond to RA,Dec, Long,Lat etc. -* - Uses eraPap(). See SOFA/ERFA documentation for details. - -*- -*/ - -double palDpav ( double v1[3], double v2[3] ) { - return eraPap( v1, v2 ); -} - -/* -*+ -* Name: -* palDr2af - -* Purpose: -* Convert an angle in radians to degrees, arcminutes, arcseconds - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDr2af( int ndp, double angle, char *sign, int idmsf[4] ); - -* Arguments: -* ndp = int (Given) -* number of decimal places of arcseconds -* angle = double (Given) -* angle in radians -* sign = char * (Returned) -* '+' or '-' (single character) -* idmsf = int [4] (Returned) -* Degrees, arcminutes, arcseconds, fraction - -* Description: -* Convert an angle in radians to degrees, arcminutes, arcseconds. - -* Notes: -* - Uses eraA2af(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDr2af ( int ndp, double angle, char *sign, int idmsf[4] ) { - eraA2af( ndp, angle, sign, idmsf ); -} - -/* -*+ -* Name: -* palDr2tf - -* Purpose: -* Convert an angle in radians to hours, minutes, seconds - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDr2tf ( int ndp, double angle, char *sign, int ihmsf[4] ); - -* Arguments: -* ndp = int (Given) -* number of decimal places of arcseconds -* angle = double (Given) -* angle in radians -* sign = char * (Returned) -* '+' or '-' (single character) -* idmsf = int [4] (Returned) -* Hours, minutes, seconds, fraction - -* Description: -* Convert an angle in radians to hours, minutes, seconds. - -* Notes: -* - Uses eraA2tf(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDr2tf( int ndp, double angle, char *sign, int ihmsf[4] ) { - eraA2tf( ndp, angle, sign, ihmsf ); -} - -/* -*+ -* Name: -* palDranrm - -* Purpose: -* Normalize angle into range 0-2 pi - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* norm = palDranrm( double angle ); - -* Arguments: -* angle = double (Given) -* angle in radians - -* Returned Value: -* Angle expressed in the range 0-2 pi - -* Description: -* Normalize angle into range 0-2 pi. - -* Notes: -* - Uses eraAnp(). See SOFA/ERFA documentation for details. - -*- -*/ - -double palDranrm ( double angle ) { - return eraAnp( angle ); -} - -/* -*+ -* Name: -* palDsep - -* Purpose: -* Angle between two points on a sphere - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* ang = palDsep( double a1, double b1, double a2, double b2 ); - -* Arguments: -* a1 = double (Given) -* Spherical coordinate of one point (radians) -* b1 = double (Given) -* Spherical coordinate of one point (radians) -* a2 = double (Given) -* Spherical coordinate of other point (radians) -* b2 = double (Given) -* Spherical coordinate of other point (radians) - -* Returned Value: -* Angle, in radians, between the two points. Always positive. - -* Description: -* Angle between two points on a sphere. - -* Notes: -* - The spherical coordinates are [RA,Dec], [Long,Lat] etc, in radians. -* - Uses eraSeps(). See SOFA/ERFA documentation for details. - -*- -*/ - -double palDsep ( double a1, double b1, double a2, double b2 ) { - return eraSeps( a1, b1, a2, b2 ); -} - -/* -*+ -* Name: -* palDsepv - -* Purpose: -* Angle between two vectors - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* ang = palDsepv( double v1[3], double v2[3] ); - -* Arguments: -* v1 = double [3] (Given) -* First vector -* v2 = double [3] (Given) -* Second vector - -* Returned Value: -* Angle, in radians, between the two points. Always positive. - -* Description: -* Angle between two vectors. - -* Notes: -* - Uses eraSepp(). See SOFA/ERFA documentation for details. - -*- -*/ - -double palDsepv ( double v1[3], double v2[3] ) { - return eraSepp( v1, v2 ); -} - -/* -*+ -* Name: -* palDtf2d - -* Purpose: -* Convert hours, minutes, seconds to days - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDtf2d( int ihour, int imin, double sec, double *days, int *j ); - -* Arguments: -* ihour = int (Given) -* Hours -* imin = int (Given) -* Minutes -* sec = double (Given) -* Seconds -* days = double * (Returned) -* Interval in days -* j = int * (Returned) -* status: 0 = ok, 1 = ihour outside range 0-23, -* 2 = imin outside range 0-59, 3 = sec outside range 0-59.999... - -* Description: -* Convert hours, minutes, seconds to days. - -* Notes: -* - Uses eraTf2d(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Assumes that the sign is always positive and is dealt with externally */ -void palDtf2d ( int ihour, int imin, double sec, double *days, int *j ) { - *j = eraTf2d( ' ', ihour, imin, sec, days ); -} - -/* -*+ -* Name: -* palDtf2r - -* Purpose: -* Convert hours, minutes, seconds to radians - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDtf2r( int ihour, int imin, double sec, double *rad, int *j ); - -* Arguments: -* ihour = int (Given) -* Hours -* imin = int (Given) -* Minutes -* sec = double (Given) -* Seconds -* days = double * (Returned) -* Angle in radians -* j = int * (Returned) -* status: 0 = ok, 1 = ihour outside range 0-23, -* 2 = imin outside range 0-59, 3 = sec outside range 0-59.999... - -* Description: -* Convert hours, minutes, seconds to radians. - -* Notes: -* - Uses eraTf2a(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Assumes that the sign is dealt with outside this routine */ -void palDtf2r ( int ihour, int imin, double sec, double *rad, int *j ) { - *j = eraTf2a( ' ', ihour, imin, sec, rad ); -} - -/* -*+ -* Name: -* palDvdv - -* Purpose: -* Scalar product of two 3-vectors - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* prod = palDvdv ( double va[3], double vb[3] ); - -* Arguments: -* va = double [3] (Given) -* First vector -* vb = double [3] (Given) -* Second vector - -* Returned Value: -* Scalar product va.vb - -* Description: -* Scalar product of two 3-vectors. - -* Notes: -* - Uses eraPdp(). See SOFA/ERFA documentation for details. - -*- -*/ - -double palDvdv ( double va[3], double vb[3] ) { - return eraPdp( va, vb ); -} - -/* -*+ -* Name: -* palDvn - -* Purpose: -* Normalizes a 3-vector also giving the modulus - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDvn( double v[3], double uv[3], double *vm ); - -* Arguments: -* v = double [3] (Given) -* vector -* uv = double [3] (Returned) -* unit vector in direction of "v" -* vm = double * (Returned) -* modulus of "v" - -* Description: -* Normalizes a 3-vector also giving the modulus. - -* Notes: -* - Uses eraPn(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Note that the arguments are flipped */ -void palDvn ( double v[3], double uv[3], double *vm ) { - eraPn( v, vm, uv ); -} - -/* -*+ -* Name: -* palDvxv - -* Purpose: -* Vector product of two 3-vectors - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palDvxv( double va[3], double vb[3], double vc[3] ); - -* Arguments: -* va = double [3] (Given) -* First vector -* vb = double [3] (Given) -* Second vector -* vc = double [3] (Returned) -* Result vector - -* Description: -* Vector product of two 3-vectors. - -* Notes: -* - Uses eraPxp(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palDvxv ( double va[3], double vb[3], double vc[3] ) { - eraPxp( va, vb, vc ); -} - -/* -*+ -* Name: -* palEpb - -* Purpose: -* Conversion of modified Julian Data to Besselian Epoch - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* epb = palEpb ( double date ); - -* Arguments: -* date = double (Given) -* Modified Julian Date (JD - 2400000.5) - -* Returned Value: -* Besselian epoch. - -* Description: -* Conversion of modified Julian Data to Besselian Epoch. - -* Notes: -* - Uses eraEpb(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Requires additional SLA MJD reference date */ -double palEpb ( double date ) { - return eraEpb( PAL__MJD0, date ); -} - -/* -*+ -* Name: -* palEpb2d - -* Purpose: -* Conversion of Besselian Epoch to Modified Julian Date - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* mjd = palEpb2d ( double epb ); - -* Arguments: -* epb = double (Given) -* Besselian Epoch - -* Returned Value: -* Modified Julian Date (JD - 2400000.5) - -* Description: -* Conversion of Besselian Epoch to Modified Julian Date. - -* Notes: -* - Uses eraEpb2jd(). See SOFA/ERFA documentation for details. - -*- -*/ - - -double palEpb2d ( double epb ) { - double djm0, djm; - eraEpb2jd( epb, &djm0, &djm ); - return djm; -} - -/* -*+ -* Name: -* palEpj - -* Purpose: -* Conversion of Modified Julian Date to Julian Epoch - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* epj = palEpj ( double date ); - -* Arguments: -* date = double (Given) -* Modified Julian Date (JD - 2400000.5) - -* Returned Value: -* The Julian Epoch. - -* Description: -* Conversion of Modified Julian Date to Julian Epoch. - -* Notes: -* - Uses eraEpj(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Requires additional SLA MJD reference date */ -double palEpj ( double date ) { - return eraEpj( PAL__MJD0, date ); -} - -/* -*+ -* Name: -* palEpj2d - -* Purpose: -* Conversion of Julian Epoch to Modified Julian Date - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* mjd = palEpj2d ( double epj ); - -* Arguments: -* epj = double (Given) -* Julian Epoch. - -* Returned Value: -* Modified Julian Date (JD - 2400000.5) - -* Description: -* Conversion of Julian Epoch to Modified Julian Date. - -* Notes: -* - Uses eraEpj2d(). See SOFA/ERFA documentation for details. - -*- -*/ -double palEpj2d ( double epj ) { - double djm0, djm; - eraEpj2jd( epj, &djm0, &djm ); - return djm; -} - -/* -*+ -* Name: -* palEqeqx - -* Purpose: -* Equation of the equinoxes (IAU 2000/2006) - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palEqeqx( double date ); - -* Arguments: -* date = double (Given) -* TT as Modified Julian Date (JD-400000.5) - -* Description: -* Equation of the equinoxes (IAU 2000/2006). - -* Notes: -* - Uses eraEe06a(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Requires additional SLA MJD reference date */ -double palEqeqx ( double date ) { - return eraEe06a( PAL__MJD0, date ); -} - -/* -*+ -* Name: -* palFk5hz - -* Purpose: -* Transform an FK5 (J2000) star position into the frame of the -* Hipparcos catalogue. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palFk5hz ( double r5, double d5, double epoch, -* double *rh, double *dh ); - -* Arguments: -* r5 = double (Given) -* FK5 RA (radians), equinox J2000, epoch "epoch" -* d5 = double (Given) -* FK5 dec (radians), equinox J2000, epoch "epoch" -* epoch = double (Given) -* Julian epoch -* rh = double * (Returned) -* RA (radians) -* dh = double * (Returned) -* Dec (radians) - -* Description: -* Transform an FK5 (J2000) star position into the frame of the -* Hipparcos catalogue. - -* Notes: -* - Assumes zero Hipparcos proper motion. -* - Uses eraEpj2jd() and eraFk5hz. -* See SOFA/ERFA documentation for details. - -*- -*/ - -void palFk5hz ( double r5, double d5, double epoch, - double *rh, double *dh ) { - /* Need to convert epoch to Julian date first */ - double date1, date2; - eraEpj2jd( epoch, &date1, &date2 ); - eraFk5hz( r5, d5, date1, date2, rh, dh ); -} - -/* -*+ -* Name: -* palGmst - -* Purpose: -* Greenwich mean sidereal time (consistent with IAU 2006 precession). - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* mst = palGmst ( double ut1 ); - -* Arguments: -* ut1 = double (Given) -* Universal time (UT1) expressed as modified Julian Date (JD-2400000.5) - -* Returned Value: -* Greenwich mean sidereal time - -* Description: -* Greenwich mean sidereal time (consistent with IAU 2006 precession). - -* Notes: -* - Uses eraGmst06(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Note that SOFA/ERFA has more accurate time arguments - and we use the 2006 precession model */ -double palGmst ( double ut1 ) { - return eraGmst06( PAL__MJD0, ut1, PAL__MJD0, ut1 ); -} - -/* -*+ -* Name: -* palGmsta - -* Purpose: -* Greenwich mean sidereal time (consistent with IAU 2006 precession). - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* mst = palGmsta ( double date, double ut1 ); - -* Arguments: -* date = double (Given) -* UT1 date (MJD: integer part of JD-2400000.5) -* ut1 = double (Given) -* UT1 time (fraction of a day) - -* Returned Value: -* Greenwich mean sidereal time (in range 0 to 2 pi) - -* Description: -* Greenwich mean sidereal time (consistent with IAU 2006 precession). - -* Notes: -* - For best accuracy use eraGmst06() directly. -* - Uses eraGmst06(). See SOFA/ERFA documentation for details. - -*- -*/ - -/* Slightly better but still not as accurate as SOFA/ERFA */ - -double palGmsta( double date, double ut ) { - date += PAL__MJD0; - return eraGmst06( date, ut, date, ut ); -} - -/* -*+ -* Name: -* palHfk5z - -* Purpose: -* Hipparcos star position to FK5 J2000 - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palHfk5z( double rh, double dh, double epoch, -* double *r5, double *d5, double *dr5, double *dd5 ); - -* Arguments: -* rh = double (Given) -* Hipparcos RA (radians) -* dh = double (Given) -* Hipparcos Dec (radians) -* epoch = double (Given) -* Julian epoch (TDB) -* r5 = double * (Returned) -* RA (radians, FK5, equinox J2000, epoch "epoch") -* d5 = double * (Returned) -* Dec (radians, FK5, equinox J2000, epoch "epoch") - -* Description: -* Transform a Hipparcos star position into FK5 J2000, assuming -* zero Hipparcos proper motion. - -* Notes: -* - Uses eraEpj2jd and eraHfk5z(). See SOFA/ERFA documentation for details. - -*- -*/ - -void palHfk5z ( double rh, double dh, double epoch, - double *r5, double *d5, double *dr5, double *dd5 ) { - /* Need to convert epoch to Julian date first */ - double date1, date2; - eraEpj2jd( epoch, &date1, &date2 ); - eraHfk5z( rh, dh, date1, date2, r5, d5, dr5, dd5 ); -} - -/* -*+ -* Name: -* palRefcoq - -* Purpose: -* Determine the constants A and B in the atmospheric refraction model - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palRefcoq( double tdk, double pmb, double rh, double wl, -* double *refa, double *refb ); - -* Arguments: -* tdk = double (Given) -* Ambient temperature at the observer (K) -* pmb = double (Given) -* Pressure at the observer (millibar) -* rh = double (Given) -* Relative humidity at the observer (range 0-1) -* wl = double (Given) -* Effective wavelength of the source (micrometre). -* Radio refraction is chosen by specifying wl > 100 micrometres. -* refa = double * (Returned) -* tan Z coefficient (radian) -* refb = double * (Returned) -* tan**3 Z coefficient (radian) - -* Description: -* Determine the constants A and B in the atmospheric refraction -* model dZ = A tan Z + B tan**3 Z. This is a fast alternative -* to the palRefco routine. -* -* Z is the "observed" zenith distance (i.e. affected by refraction) -* and dZ is what to add to Z to give the "topocentric" (i.e. in vacuo) -* zenith distance. - -* Notes: -* - Uses eraRefco(). See SOFA/ERFA documentation for details. -* - Note that the SOFA/ERFA routine uses different order of -* of arguments and uses deg C rather than K. - -*- -*/ - -void palRefcoq ( double tdk, double pmb, double rh, double wl, - double *refa, double *refb ) { - /* Note that SLA (and therefore PAL) uses units of kelvin - but SOFA/ERFA uses deg C */ - eraRefco( pmb, tdk - 273.15, rh, wl, refa, refb ); -} diff --git a/ast/pal/palPrebn.c b/ast/pal/palPrebn.c deleted file mode 100644 index 989ce59..0000000 --- a/ast/pal/palPrebn.c +++ /dev/null @@ -1,98 +0,0 @@ -/* -*+ -* Name: -* palPrebn - -* Purpose: -* Generate the matrix of precession between two objects (old) - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palPrebn ( double bep0, double bep1, double rmatp[3][3] ); - -* Arguments: -* bep0 = double (Given) -* Beginning Besselian epoch. -* bep1 = double (Given) -* Ending Besselian epoch -* rmatp = double[3][3] (Returned) -* precession matrix in the sense V(BEP1) = RMATP * V(BEP0) - -* Description: -* Generate the matrix of precession between two epochs, -* using the old, pre-IAU1976, Bessel-Newcomb model, using -* Kinoshita's formulation - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* See Also: -* Kinoshita, H. (1975) 'Formulas for precession', SAO Special -* Report No. 364, Smithsonian Institution Astrophysical -* Observatory, Cambridge, Massachusetts. - -* History: -* 2012-02-12(TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1996 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" - -void palPrebn ( double bep0, double bep1, double rmatp[3][3] ) { - - double t,bigt, zeta, theta, z, tas2r, w; - - /* Interval between basic epoch B1850.0 and beginning epoch in TC */ - bigt = (bep0-1850)/100.; - - /* Interval over which precession required, in tropical centuries */ - t = (bep1-bep0)/100.; - - /* Euler angles */ - tas2r = t * PAL__DAS2R; - w = 2303.5548 + ( 1.39720 + 0.000059 * bigt) * bigt; - - zeta = ( w + ( 0.30242 - 0.000269 * bigt + 0.017996 * t ) * t ) * tas2r; - z = ( w + ( 1.09478 + 0.000387 * bigt + 0.018324 * t ) * t ) * tas2r; - theta = ( 2005.1125 + ( -0.85294 - 0.000365 * bigt ) * bigt + - (-0.42647 - 0.000365 * bigt - 0.041802 * t ) * t ) * tas2r; - - /* Rotation matrix */ - palDeuler("ZYZ", -zeta, theta, -z, rmatp); - -} diff --git a/ast/pal/palPrec.c b/ast/pal/palPrec.c deleted file mode 100644 index 678770d..0000000 --- a/ast/pal/palPrec.c +++ /dev/null @@ -1,107 +0,0 @@ -/* -*+ -* Name: -* palPrec - -* Purpose: -* Form the matrix of precession between two epochs (IAU 2006) - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palPrec( double ep0, double ep1, double rmatp[3][3] ) - -* Arguments: -* ep0 = double (Given) -* Beginning epoch -* ep1 = double (Given) -* Ending epoch -* rmatp = double[3][3] (Returned) -* Precession matrix - -* Description: -* The IAU 2006 precession matrix from ep0 to ep1 is found and -* returned. The matrix is in the sense V(EP1) = RMATP * V(EP0). -* The epochs are TDB (loosely TT) Julian epochs. -* -* Though the matrix method itself is rigorous, the precession -* angles are expressed through canonical polynomials which are -* valid only for a limited time span of a few hundred years around -* the current epoch. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-10 (DSB): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1996 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palPrec( double ep0, double ep1, double rmatp[3][3] ){ - -/* Local Variables: */ - double rmatq[3][3]; - double ep0_days; - double ep1_days; - -/* Convert supplied dates to days since J2000 */ - ep0_days = ( ep0 - 2000.0 )*ERFA_DJY; - ep1_days = ( ep1 - 2000.0 )*ERFA_DJY; - -/* If beginning epoch is J2000, just return the rotation matrix from - J2000 to EP1. */ - if( ep0 == 2000.0 ) { - eraPmat06( ERFA_DJ00, ep1_days, rmatp ); - -/* If end epoch is J2000, get the rotation matrix from J2000 to EP0 and - then transpose it to get the rotation matrix from EP0 to J2000. */ - } else if( ep1 == 2000.0 ) { - eraPmat06( ERFA_DJ00, ep0_days, rmatp ); - eraTr( rmatp, rmatp ); - -/* Otherwise. get the two matrices used above and multiply them - together. */ - } else { - eraPmat06( ERFA_DJ00, ep0_days, rmatp ); - eraTr( rmatp, rmatp ); - eraPmat06( ERFA_DJ00, ep1_days, rmatq ); - eraRxr( rmatp, rmatq, rmatp ); - } - -} diff --git a/ast/pal/palPrenut.c b/ast/pal/palPrenut.c deleted file mode 100644 index 04e36f3..0000000 --- a/ast/pal/palPrenut.c +++ /dev/null @@ -1,111 +0,0 @@ -/* -*+ -* Name: -* palPrenut - -* Purpose: -* Form the matrix of bias-precession-nutation (IAU 2006/2000A) - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palPrenut( double epoch, double date, double rmatpn[3][3] ) - -* Arguments: -* epoch = double (Returned) -* Julian epoch for mean coordinates. -* date = double (Returned) -* Modified Julian Date (JD-2400000.5) for true coordinates. -* rmatpn = double[3][3] (Returned) -* combined NPB matrix - -* Description: -* Form the matrix of bias-precession-nutation (IAU 2006/2000A). -* The epoch and date are TT (but TDB is usually close enough). -* The matrix is in the sense v(true) = rmatpn * v(mean). - -* Authors: -* PTW: Pat Wallace (STFC) -* {enter_new_authors_here} - -* History: -* 2012-02-10 (PTW): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include "pal1sofa.h" - -void palPrenut ( double epoch, double date, double rmatpn[3][3] ){ - -/* Local Variables: */ - double bpa; - double bpia; - double bqa; - double chia; - double d1; - double d2; - double eps0; - double epsa; - double gam; - double oma; - double pa; - double phi; - double pia; - double psi; - double psia; - double r1[3][3]; - double r2[3][3]; - double thetaa; - double za; - double zetaa; - -/* Specified Julian epoch as a 2-part JD. */ - eraEpj2jd( epoch, &d1, &d2 ); - -/* P matrix, from specified epoch to J2000.0. */ - eraP06e( d1, d2, &eps0, &psia, &oma, &bpa, &bqa, &pia, &bpia, &epsa, - &chia, &za, &zetaa, &thetaa, &pa, &gam, &phi, &psi ); - eraIr( r1 ); - eraRz( -chia, r1 ); - eraRx( oma, r1 ); - eraRz( psia, r1 ); - eraRx( -eps0, r1 ); - -/* NPB matrix, from J2000.0 to date. */ - eraPnm06a( PAL__MJD0, date, r2 ); - -/* NPB matrix, from specified epoch to date. */ - eraRxr( r2, r1, rmatpn ); -} diff --git a/ast/pal/palPvobs.c b/ast/pal/palPvobs.c deleted file mode 100644 index 763d202..0000000 --- a/ast/pal/palPvobs.c +++ /dev/null @@ -1,108 +0,0 @@ -/* -*+ -* Name: -* palPvobs - -* Purpose: -* Position and velocity of an observing station. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* palPvobs( double p, double h, double stl, double pv[6] ) - -* Arguments: -* p = double (Given) -* Latitude (geodetic, radians). -* h = double (Given) -* Height above reference spheroid (geodetic, metres). -* stl = double (Given) -* Local apparent sidereal time (radians). -* pv = double[ 6 ] (Returned) -* position/velocity 6-vector (AU, AU/s, true equator -* and equinox of date). - -* Description: -* Returns the position and velocity of an observing station. - -* Notes: -* - The WGS84 reference ellipsoid is used. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-16 (DSB): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "palmac.h" -#include "palmac.h" -#include "pal1sofa.h" - -void palPvobs( double p, double h, double stl, double pv[6] ){ - -/* Local Variables: */ - double xyz[3], z, r, s, c, v; - -/* Geodetic to geocentric conversion (WGS84 reference ellipsoid). */ - eraGd2gc( ERFA_WGS84, 0.0, p, h, xyz ); - -/* Convert from metres to AU */ - r = xyz[ 0 ]/ERFA_DAU; - z = xyz[ 2 ]/ERFA_DAU; - -/* Functions of ST. */ - s = sin( stl ); - c = cos( stl ); - -/* Speed. */ - v = PAL__SR*r; - -/* Position. */ - pv[ 0 ] = r*c; - pv[ 1 ] = r*s; - pv[ 2 ] = z; - -/* Velocity. */ - pv[ 3 ] = -v*s; - pv[ 4 ] = v*c; - pv[ 5 ] = 0.0; - -} - - diff --git a/ast/pal/palRvgalc.c b/ast/pal/palRvgalc.c deleted file mode 100644 index 2f01576..0000000 --- a/ast/pal/palRvgalc.c +++ /dev/null @@ -1,111 +0,0 @@ -/* -*+ -* Name: -* palRvgalc - -* Purpose: -* Velocity component in a given direction due to the rotation -* of the Galaxy. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* double palRvgalc( double r2000, double d2000 ) - -* Arguments: -* r2000 = double (Given) -* J2000.0 mean RA (radians) -* d2000 = double (Given) -* J2000.0 mean Dec (radians) - -* Returned Value: -* Component of dynamical LSR motion in direction R2000,D2000 (km/s). - -* Description: -* This function returns the Component of dynamical LSR motion in -* the direction of R2000,D2000. The result is +ve when the dynamical -* LSR is receding from the given point on the sky. -* -* Notes: -* - The Local Standard of Rest used here is a point in the -* vicinity of the Sun which is in a circular orbit around -* the Galactic centre. Sometimes called the "dynamical" LSR, -* it is not to be confused with a "kinematical" LSR, which -* is the mean standard of rest of star catalogues or stellar -* populations. -* -* Reference: -* - The orbital speed of 220 km/s used here comes from Kerr & -* Lynden-Bell (1986), MNRAS, 221, p1023. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-16 (DSB): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -double palRvgalc( double r2000, double d2000 ){ - -/* Local Variables: */ - double vb[ 3 ]; - -/* -* LSR velocity due to Galactic rotation -* -* Speed = 220 km/s -* Apex = L2,B2 90deg, 0deg -* = RA,Dec 21 12 01.1 +48 19 47 J2000.0 -* -* This is expressed in the form of a J2000.0 x,y,z vector: -* -* VA(1) = X = -SPEED*COS(RA)*COS(DEC) -* VA(2) = Y = -SPEED*SIN(RA)*COS(DEC) -* VA(3) = Z = -SPEED*SIN(DEC) -*/ - - double va[ 3 ] = { -108.70408, +97.86251, -164.33610 }; - -/* Convert given J2000 RA,Dec to x,y,z. */ - eraS2c( r2000, d2000, vb ); - -/* Compute dot product with LSR motion vector. */ - return eraPdp( va, vb ); -} diff --git a/ast/pal/palRvlg.c b/ast/pal/palRvlg.c deleted file mode 100644 index 255801e..0000000 --- a/ast/pal/palRvlg.c +++ /dev/null @@ -1,106 +0,0 @@ -/* -*+ -* Name: -* palRvlg - -* Purpose: -* Velocity component in a given direction due to Galactic rotation -* and motion of the local group. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* double palRvlg( double r2000, double d2000 ) - -* Arguments: -* r2000 = double (Given) -* J2000.0 mean RA (radians) -* d2000 = double (Given) -* J2000.0 mean Dec (radians) - -* Returned Value: -* Component of SOLAR motion in direction R2000,D2000 (km/s). - -* Description: -* This function returns the velocity component in a given -* direction due to the combination of the rotation of the -* Galaxy and the motion of the Galaxy relative to the mean -* motion of the local group. The result is +ve when the Sun -* is receding from the given point on the sky. -* -* Reference: -* - IAU Trans 1976, 168, p201. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-16 (DSB): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -double palRvlg( double r2000, double d2000 ){ - -/* Local Variables: */ - double vb[ 3 ]; - -/* -* -* Solar velocity due to Galactic rotation and translation -* -* Speed = 300 km/s -* -* Apex = L2,B2 90deg, 0deg -* = RA,Dec 21 12 01.1 +48 19 47 J2000.0 -* -* This is expressed in the form of a J2000.0 x,y,z vector: -* -* VA(1) = X = -SPEED*COS(RA)*COS(DEC) -* VA(2) = Y = -SPEED*SIN(RA)*COS(DEC) -* VA(3) = Z = -SPEED*SIN(DEC) -*/ - - double va[ 3 ] = { -148.23284, +133.44888, -224.09467 }; - -/* Convert given J2000 RA,Dec to x,y,z. */ - eraS2c( r2000, d2000, vb ); - -/* Compute dot product with Solar motion vector. */ - return eraPdp( va, vb ); -} diff --git a/ast/pal/palRvlsrd.c b/ast/pal/palRvlsrd.c deleted file mode 100644 index 6302c4f..0000000 --- a/ast/pal/palRvlsrd.c +++ /dev/null @@ -1,116 +0,0 @@ -/* -*+ -* Name: -* palRvlsrd - -* Purpose: -* Velocity component in a given direction due to the Sun's motion -* with respect to the dynamical Local Standard of Rest. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* double palRvlsrd( double r2000, double d2000 ) - -* Arguments: -* r2000 = double (Given) -* J2000.0 mean RA (radians) -* d2000 = double (Given) -* J2000.0 mean Dec (radians) - -* Returned Value: -* Component of "peculiar" solar motion in direction R2000,D2000 (km/s). - -* Description: -* This function returns the velocity component in a given direction -* due to the Sun's motion with respect to the dynamical Local Standard -* of Rest. The result is +ve when the Sun is receding from the given -* point on the sky. - -* Notes: -* - The Local Standard of Rest used here is the "dynamical" LSR, -* a point in the vicinity of the Sun which is in a circular orbit -* around the Galactic centre. The Sun's motion with respect to the -* dynamical LSR is called the "peculiar" solar motion. -* - There is another type of LSR, called a "kinematical" LSR. A -* kinematical LSR is the mean standard of rest of specified star -* catalogues or stellar populations, and several slightly different -* kinematical LSRs are in use. The Sun's motion with respect to an -* agreed kinematical LSR is known as the "standard" solar motion. -* To obtain a radial velocity correction with respect to an adopted -* kinematical LSR use the routine palRvlsrk. - -* Reference: -* - Delhaye (1965), in "Stars and Stellar Systems", vol 5, p73. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-16 (DSB): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -double palRvlsrd( double r2000, double d2000 ){ - -/* Local Variables: */ - double vb[ 3 ]; - -/* -* Peculiar solar motion from Delhaye 1965: in Galactic Cartesian -* coordinates (+9,+12,+7) km/s. This corresponds to about 16.6 km/s -* towards Galactic coordinates L2 = 53 deg, B2 = +25 deg, or RA,Dec -* 17 49 58.7 +28 07 04 J2000. -* -* The solar motion is expressed here in the form of a J2000.0 -* equatorial Cartesian vector: -* -* VA(1) = X = -SPEED*COS(RA)*COS(DEC) -* VA(2) = Y = -SPEED*SIN(RA)*COS(DEC) -* VA(3) = Z = -SPEED*SIN(DEC) -*/ - - double va[ 3 ] = { +0.63823, +14.58542, -7.80116 }; - -/* Convert given J2000 RA,Dec to x,y,z. */ - eraS2c( r2000, d2000, vb ); - -/* Compute dot product with Solar motion vector. */ - return eraPdp( va, vb ); -} diff --git a/ast/pal/palRvlsrk.c b/ast/pal/palRvlsrk.c deleted file mode 100644 index 968188a..0000000 --- a/ast/pal/palRvlsrk.c +++ /dev/null @@ -1,116 +0,0 @@ -/* -*+ -* Name: -* palRvlsrk - -* Purpose: -* Velocity component in a given direction due to the Sun's motion -* with respect to an adopted kinematic Local Standard of Rest. - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* double palRvlsrk( double r2000, double d2000 ) - -* Arguments: -* r2000 = double (Given) -* J2000.0 mean RA (radians) -* d2000 = double (Given) -* J2000.0 mean Dec (radians) - -* Returned Value: -* Component of "standard" solar motion in direction R2000,D2000 (km/s). - -* Description: -* This function returns the velocity component in a given direction -* due to the Sun's motion with respect to an adopted kinematic -* Local Standard of Rest. The result is +ve when the Sun is receding -* from the given point on the sky. - -* Notes: -* - The Local Standard of Rest used here is one of several -* "kinematical" LSRs in common use. A kinematical LSR is the mean -* standard of rest of specified star catalogues or stellar -* populations. The Sun's motion with respect to a kinematical LSR -* is known as the "standard" solar motion. -* - There is another sort of LSR, the "dynamical" LSR, which is a -* point in the vicinity of the Sun which is in a circular orbit -* around the Galactic centre. The Sun's motion with respect to -* the dynamical LSR is called the "peculiar" solar motion. To -* obtain a radial velocity correction with respect to the -* dynamical LSR use the routine palRvlsrd. - -* Reference: -* - Delhaye (1965), in "Stars and Stellar Systems", vol 5, p73. - -* Authors: -* PTW: Pat Wallace (STFC) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* History: -* 2012-02-16 (DSB): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -double palRvlsrk( double r2000, double d2000 ){ - -/* Local Variables: */ - double vb[ 3 ]; - -/* -* Standard solar motion (from Methods of Experimental Physics, ed Meeks, -* vol 12, part C, sec 6.1.5.2, p281): -* -* 20 km/s towards RA 18h Dec +30d (1900). -* -* The solar motion is expressed here in the form of a J2000.0 -* equatorial Cartesian vector: -* -* VA(1) = X = -SPEED*COS(RA)*COS(DEC) -* VA(2) = Y = -SPEED*SIN(RA)*COS(DEC) -* VA(3) = Z = -SPEED*SIN(DEC) -*/ - - double va[ 3 ] = { -0.29000, +17.31726, -10.00141 }; - -/* Convert given J2000 RA,Dec to x,y,z. */ - eraS2c( r2000, d2000, vb ); - -/* Compute dot product with Solar motion vector. */ - return eraPdp( va, vb ); -} diff --git a/ast/pal/palSubet.c b/ast/pal/palSubet.c deleted file mode 100644 index ada122a..0000000 --- a/ast/pal/palSubet.c +++ /dev/null @@ -1,112 +0,0 @@ -/* -*+ -* Name: -* palSubet - -* Purpose: -* Remove the E-terms from a pre IAU 1976 catalogue RA,Dec - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palSubet ( double rc, double dc, double eq, -* double *rm, double *dm ); - -* Arguments: -* rc = double (Given) -* RA with E-terms included (radians) -* dc = double (Given) -* Dec with E-terms included (radians) -* eq = double (Given) -* Besselian epoch of mean equator and equinox -* rm = double * (Returned) -* RA without E-terms (radians) -* dm = double * (Returned) -* Dec without E-terms (radians) - -* Description: -* Remove the E-terms (elliptic component of annual aberration) -* from a pre IAU 1976 catalogue RA,Dec to give a mean place. - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* Most star positions from pre-1984 optical catalogues (or -* derived from astrometry using such stars) embody the -* E-terms. This routine converts such a position to a -* formal mean place (allowing, for example, comparison with a -* pulsar timing position). - -* See Also: -* Explanatory Supplement to the Astronomical Ephemeris, -* section 2D, page 48. - -* History: -* 2012-02-12(TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palSubet ( double rc, double dc, double eq, double *rm, double *dm ) { - double a[3]; /* The E-terms */ - double v[3]; - double f; - int i; - - /* Note the preference for IAU routines */ - - /* Retrieve the E-terms */ - palEtrms( eq, a ); - - /* Spherical to Cartesian */ - eraS2c( rc, dc, v ); - - /* Include the E-terms */ - f = 1.0 + eraPdp( v, a ); - for (i=0; i<3; i++) { - v[i] = f*v[i] - a[i]; - } - - /* Cartesian to spherical */ - eraC2s( v, rm, dm ); - - /* Bring RA into conventional range */ - *rm = eraAnp( *rm ); - -} diff --git a/ast/pal/palSupgal.c b/ast/pal/palSupgal.c deleted file mode 100644 index 1f4aeb2..0000000 --- a/ast/pal/palSupgal.c +++ /dev/null @@ -1,116 +0,0 @@ -/* -*+ -* Name: -* palSupgal - -* Purpose: -* Convert from supergalactic to galactic coordinates - -* Language: -* Starlink ANSI C - -* Type of Module: -* Library routine - -* Invocation: -* void palSupgal ( double dsl, double dsb, double *dl, double *db ); - -* Arguments: -* dsl = double (Given) -* Supergalactic longitude. -* dsb = double (Given) -* Supergalactic latitude. -* dl = double * (Returned) -* Galactic longitude. -* db = double * (Returned) -* Galactic latitude. - -* Description: -* Transformation from de Vaucouleurs supergalactic coordinates -* to IAU 1958 galactic coordinates - -* Authors: -* PTW: Pat Wallace (STFC) -* TIMJ: Tim Jenness (JAC, Hawaii) -* {enter_new_authors_here} - -* See Also: -* - de Vaucouleurs, de Vaucouleurs, & Corwin, Second Reference -* Catalogue of Bright Galaxies, U. Texas, page 8. -* - Systems & Applied Sciences Corp., Documentation for the -* machine-readable version of the above catalogue, -* Contract NAS 5-26490. -* -* (These two references give different values for the galactic -* longitude of the supergalactic origin. Both are wrong; the -* correct value is L2=137.37.) - -* History: -* 2012-02-12(TIMJ): -* Initial version with documentation taken from Fortran SLA -* Adapted with permission from the Fortran SLALIB library. -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 1995 Rutherford Appleton Laboratory -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -#include "pal.h" -#include "pal1sofa.h" - -void palSupgal ( double dsl, double dsb, double *dl, double *db ) { - - double v1[3]; - double v2[3]; - -/* -* System of supergalactic coordinates: -* -* SGL SGB L2 B2 (deg) -* - +90 47.37 +6.32 -* 0 0 - 0 -* -* Galactic to supergalactic rotation matrix: -*/ - double rmat[3][3] = { - { -0.735742574804,+0.677261296414,+0.000000000000 }, - { -0.074553778365,-0.080991471307,+0.993922590400 }, - { +0.673145302109,+0.731271165817,+0.110081262225 } - }; - - /* Spherical to Cartesian */ - eraS2c( dsl, dsb, v1 ); - - /* Supergalactic to galactic */ - eraTrxp( rmat, v1, v2 ); - - /* Cartesian to spherical */ - eraC2s( v2, dl, db ); - - /* Express in conventional ranges */ - *dl = eraAnp( *dl ); - *db = eraAnpm( *db ); - -} diff --git a/ast/pal/palmac.h b/ast/pal/palmac.h deleted file mode 100644 index 207b843..0000000 --- a/ast/pal/palmac.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef PALMACDEF -#define PALMACDEF - -/* -*+ -* Name: -* palmac.h - -* Purpose: -* Macros used by the PAL library - -* Language: -* Starlink ANSI C - -* Type of Module: -* Include file - -* Description: -* A collection of useful macros provided and used by the PAL library - -* Authors: -* TIMJ: Tim Jenness (JAC, Hawaii) -* DSB: David Berry (JAC, Hawaii) -* {enter_new_authors_here} - -* Notes: -* - -* History: -* 2012-02-08 (TIMJ): -* Initial version. -* Adapted with permission from the Fortran SLALIB library. -* 2012-04-13 (DSB): -* Added PAL__DR2H and PAL__DR2S -* {enter_further_changes_here} - -* Copyright: -* Copyright (C) 2012 Science and Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Bugs: -* {note_any_bugs_here} -*- -*/ - -/* Pi */ -static const double PAL__DPI = 3.1415926535897932384626433832795028841971693993751; - -/* 2Pi */ -static const double PAL__D2PI = 6.2831853071795864769252867665590057683943387987502; - -/* pi/2: 90 degrees in radians */ -static const double PAL__DPIBY2 = 1.5707963267948966192313216916397514420985846996876; - -/* pi/180: degrees to radians */ -static const double PAL__DD2R = 0.017453292519943295769236907684886127134428718885417; - -/* Radians to arcseconds */ -static const double PAL__DR2AS = 2.0626480624709635515647335733077861319665970087963e5; - -/* Arcseconds to radians */ -static const double PAL__DAS2R = 4.8481368110953599358991410235794797595635330237270e-6; - -/* Radians to degrees */ -static const double PAL__DR2D = 57.295779513082320876798154814105170332405472466564; - -/* Hours to radians */ -static const double PAL__DH2R = 0.26179938779914943653855361527329190701643078328126; - -/* Radians to hours */ -static const double PAL__DR2H = 3.8197186342054880584532103209403446888270314977709; - -/* Radians to seconds of time */ -static const double PAL__DR2S = 1.3750987083139757010431557155385240879777313391975e4; - -/* Seconds of time to radians */ -static const double PAL__DS2R = 7.272205216643039903848712e-5; - -/* Start of SLA modified Julian date epoch */ -static const double PAL__MJD0 = 2400000.5; - -/* Light time for 1 AU (sec) */ -static const double PAL__CR = 499.004782; - -/* Seconds per day */ -static const double PAL__SPD = 86400.0; - -/* Km per sec to AU per tropical century - = 86400 * 36524.2198782 / 149597870 */ -static const double PAL__VF = 21.095; - -/* Radians per year to arcsec per century. This needs to be a macro since it - is an expression including other constants. */ -#define PAL__PMF (100.0*60.0*60.0*360.0/PAL__D2PI); - -/* Mean sidereal rate - the rotational angular velocity of Earth - in radians/sec from IERS Conventions (2003). */ -static const double PAL__SR = 7.2921150e-5; - -/* Gaussian gravitational constant (exact) */ -static const double PAL__GCON = 0.01720209895; - -/* DINT(A) - truncate to nearest whole number towards zero (double) */ -#define DINT(A) ((A)<0.0?ceil(A):floor(A)) - -/* DNINT(A) - round to nearest whole number (double) */ -#define DNINT(A) ((A)<0.0?ceil((A)-0.5):floor((A)+0.5)) - -/* DMAX(A,B) - return maximum value - evaluates arguments multiple times */ -#define DMAX(A,B) ((A) > (B) ? (A) : (B) ) - -/* DMIN(A,B) - return minimum value - evaluates arguments multiple times */ -#define DMIN(A,B) ((A) < (B) ? (A) : (B) ) - -/* We actually prefer to use C99 copysign() but we define this here as a backup - but it will not detect -0.0 so is not useful for palDfltin. */ -/* DSIGN(A,B) - magnitude of A with sign of B (double) */ -#define DSIGN(A,B) ((B)<0.0?-fabs(A):fabs(A)) - -#endif diff --git a/ast/pal2ast.h b/ast/pal2ast.h deleted file mode 100644 index 83bab9a..0000000 --- a/ast/pal2ast.h +++ /dev/null @@ -1,134 +0,0 @@ -#if !defined( PAL2AST_INCLUDED ) /* Include this file only once */ -#define PAL2AST_INCLUDED -/* -* Name: -* pal2ast.h - -* Type: -* C include file. - -* Purpose: -* Defines new names for symbols exported by the PAL library. - -* Invocation: -* #include "pal2ast.h" - -* Description: -* This include file defines a new name for each public function -* defined by the pal library. The names defined by PAL itself are -* of the form "palXxx" (e.g. palPvobs) - this include file defines -* a macro that translates each such name to the form "astPalXxx" -* (e.g. astPalPvobs). This is done so that the names do not clash -* with any external PAL library with which the application is linked. -* -* It should be included at the start of any AST source file that refers -* to PAL functions using the standard names (e.g. palPvobs). - -* Copyright: -* Copyright (C) 2012 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 16-FEB-2012 (DSB): -* Original version. -*/ - -/* Rename all PAL functions */ -#define palAddet astPalAddet -#define palAmpqk astPalAmpqk -#define palCaldj astPalCaldj -#define palDat astPalDat -#define palDe2h astPalDe2h -#define palDeuler astPalDeuler -#define palDh2e astPalDh2e -#define palDjcal astPalDjcal -#define palDmat astPalDmat -#define palDs2tp astPalDs2tp -#define palDtp2s astPalDtp2s -#define palDtps2c astPalDtps2c -#define palDtt astPalDtt -#define palEcmat astPalEcmat -#define palEqgal astPalEqgal -#define palEtrms astPalEtrms -#define palEvp astPalEvp -#define palFk45z astPalFk45z -#define palFk524 astPalFk524 -#define palFk54z astPalFk54z -#define palGaleq astPalGaleq -#define palGalsup astPalGalsup -#define palMappa astPalMappa -#define palMapqkz astPalMapqkz -#define palPrebn astPalPrebn -#define palPrec astPalPrec -#define palPrenut astPalPrenut -#define palPvobs astPalPvobs -#define palRvgalc astPalRvgalc -#define palRvlg astPalRvlg -#define palRvlsrd astPalRvlsrd -#define palRvlsrk astPalRvlsrk -#define palSubet astPalSubet -#define palSupgal astPalSupgal -#define palCldj astPalCldj -#define palDaf2r astPalDaf2r -#define palDav2m astPalDav2m -#define palDbear astPalDbear -#define palDcc2s astPalDcc2s -#define palDcs2c astPalDcs2c -#define palDd2tf astPalDd2tf -#define palDimxv astPalDimxv -#define palDjcl astPalDjcl -#define palDm2av astPalDm2av -#define palDmxm astPalDmxm -#define palDmxv astPalDmxv -#define palDpav astPalDpav -#define palDrange astPalDrange -#define palDranrm astPalDranrm -#define palDsep astPalDsep -#define palDsepv astPalDsepv -#define palDtf2d astPalDtf2d -#define palDtf2r astPalDtf2r -#define palDvdv astPalDvdv -#define palDvn astPalDvn -#define palDvxv astPalDvxv -#define palEpb astPalEpb -#define palEpb2d astPalEpb2d -#define palEpj astPalEpj -#define palEpj2d astPalEpj2d -#define palEqeqx astPalEqeqx -#define palFk5hz astPalFk5hz -#define palGeoc astPalGeoc -#define palGmst astPalGmst -#define palHfk5z astPalHfk5z - -/* Rename all PAL global variables */ -#define PAL__DPI AST__PALDPI -#define PAL__D2PI AST__PALD2PI -#define PAL__DD2R AST__PALDD2R -#define PAL__DR2AS AST__PALDR2AS -#define PAL__DAS2R AST__PALDAS2R -#define PAL__MJD0 AST__PALMJD0 -#define PAL__CR AST__PALCR -#define PAL__VF AST__PALVF -#define PAL__SR AST__PALSR - - -#endif diff --git a/ast/palwrap.c b/ast/palwrap.c deleted file mode 100644 index ca9a38f..0000000 --- a/ast/palwrap.c +++ /dev/null @@ -1,301 +0,0 @@ -#if !defined( PAL_INCLUDED ) /* Include this file only once */ -#define PAL_INCLUDED -/* -* Name: -* pal.c - -* Purpose: -* A wrapper for all PAL functions used by AST. - -* Description: -* This file is a wrapper that includes all the source files from -* the PAL and ERFA libraries. This is done so that the function -* names can be changed from the usual "palXxx" and "eraXxx" forms to -* the private "astPalXxx" and "astIauXxx" forms. This renaming is -* performed via the macros defined in the pal2ast.h and erfa2ast.h -* include files. This is done in order to prevent clashes with any -* external PAL or ERFA libraries with which an application is linked. -* -* This file expects to find the publicly distributed and unmodified -* PAL and ERFA source code in a pair of subdirectory called "pal" and -* "erfa" within the current directory. The files within these -* subdirectories do not need to be compiled - only this wrapper file -* needs to be compiled. - -* Copyright: -* Copyright (C) 2011 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (JAC, Hawaii) - -* History: -* 16-FEB-2012 (DSB): -* Original version. -*/ - -/* Include configuration results in order to get any definition for the - EXTERNAL_PAL macro. This macro is set if the --with-external_pal - option was set when AST was configured. */ -#if HAVE_CONFIG_H -#include -#endif - -/* If an external PAL library is being used, we leave this file empty. */ -#ifndef EXTERNAL_PAL - -/* Rename all PAL functions so that references to "palXxx" in the files - included below get translated to "astPalXxx". */ -#include "pal2ast.h" - -/* Rename all ERFA functions so that references to "eraXxx" in the files - included below get translated to "astEraXxx". */ -#include "erfa2ast.h" - -/* Include code from all PAL source files */ -#include "pal/palAddet.c" -#include "pal/palAmpqk.c" -#include "pal/palCaldj.c" -#include "pal/palDat.c" -#include "pal/palDe2h.c" -#include "pal/palDeuler.c" -#include "pal/palDh2e.c" -#include "pal/palDjcal.c" -#include "pal/palDmat.c" -#include "pal/palDrange.c" -#include "pal/palDs2tp.c" -#include "pal/palDtp2s.c" -#include "pal/palDtps2c.c" -#include "pal/palDtt.c" -#include "pal/palEcmat.c" -#include "pal/palEqgal.c" -#include "pal/palEtrms.c" -#include "pal/palEvp.c" -#include "pal/palFk45z.c" -#include "pal/palFk524.c" -#include "pal/palFk54z.c" -#include "pal/palGaleq.c" -#include "pal/palGalsup.c" -#include "pal/palGeoc.c" -#include "pal/palMappa.c" -#include "pal/palMapqkz.c" -#include "pal/palOne2One.c" -#include "pal/palPrebn.c" -#include "pal/palPrec.c" -#include "pal/palPrenut.c" -#include "pal/palPvobs.c" -#include "pal/palRvgalc.c" -#include "pal/palRvlg.c" -#include "pal/palRvlsrd.c" -#include "pal/palRvlsrk.c" -#include "pal/palSubet.c" -#include "pal/palSupgal.c" - -/* Include code from all ERFA source files */ -#include "erfa/a2af.c" -#include "erfa/a2tf.c" -#include "erfa/af2a.c" -#include "erfa/anp.c" -#include "erfa/anpm.c" -#include "erfa/bi00.c" -#include "erfa/bp00.c" -#include "erfa/bp06.c" -#include "erfa/bpn2xy.c" -#include "erfa/c2i00a.c" -#include "erfa/c2i00b.c" -#include "erfa/c2i06a.c" -#include "erfa/c2ibpn.c" -#include "erfa/c2ixy.c" -#include "erfa/c2ixys.c" -#include "erfa/c2s.c" -#include "erfa/c2t00a.c" -#include "erfa/c2t00b.c" -#include "erfa/c2t06a.c" -#include "erfa/c2tcio.c" -#include "erfa/c2teqx.c" -#include "erfa/c2tpe.c" -#include "erfa/c2txy.c" -#include "erfa/cal2jd.c" -#include "erfa/cp.c" -#include "erfa/cpv.c" -#include "erfa/cr.c" -#include "erfa/d2dtf.c" -#include "erfa/d2tf.c" -#include "erfa/dat.c" -#include "erfa/dtdb.c" -#include "erfa/dtf2d.c" -#include "erfa/ee00.c" -#include "erfa/ee00a.c" -#include "erfa/ee00b.c" -#include "erfa/ee06a.c" -#include "erfa/eect00.c" -#include "erfa/eform.c" -#include "erfa/eo06a.c" -#include "erfa/eors.c" -#include "erfa/epb.c" -#include "erfa/epb2jd.c" -#include "erfa/epj.c" -#include "erfa/epj2jd.c" -#include "erfa/epv00.c" -#include "erfa/eqeq94.c" -#include "erfa/era00.c" -#include "erfa/fad03.c" -#include "erfa/fae03.c" -#include "erfa/faf03.c" -#include "erfa/faju03.c" -#include "erfa/fal03.c" -#include "erfa/falp03.c" -#include "erfa/fama03.c" -#include "erfa/fame03.c" -#include "erfa/fane03.c" -#include "erfa/faom03.c" -#include "erfa/fapa03.c" -#include "erfa/fasa03.c" -#include "erfa/faur03.c" -#include "erfa/fave03.c" -#include "erfa/fk52h.c" -#include "erfa/fk5hip.c" -#include "erfa/fk5hz.c" -#include "erfa/fw2m.c" -#include "erfa/fw2xy.c" -#include "erfa/gc2gd.c" -#include "erfa/gc2gde.c" -#include "erfa/gd2gc.c" -#include "erfa/gd2gce.c" -#include "erfa/gmst00.c" -#include "erfa/gmst06.c" -#include "erfa/gmst82.c" -#include "erfa/gst00a.c" -#include "erfa/gst00b.c" -#include "erfa/gst06.c" -#include "erfa/gst06a.c" -#include "erfa/gst94.c" -#include "erfa/h2fk5.c" -#include "erfa/hfk5z.c" -#include "erfa/ir.c" -#include "erfa/jd2cal.c" -#include "erfa/jdcalf.c" -#include "erfa/num00a.c" -#include "erfa/num00b.c" -#include "erfa/num06a.c" -#include "erfa/numat.c" -#include "erfa/nut00a.c" -#include "erfa/nut00b.c" -#include "erfa/nut06a.c" -#include "erfa/nut80.c" -#include "erfa/nutm80.c" -#include "erfa/obl06.c" -#include "erfa/obl80.c" -#include "erfa/p06e.c" -#include "erfa/p2pv.c" -#include "erfa/p2s.c" -#include "erfa/pap.c" -#include "erfa/pas.c" -#include "erfa/pb06.c" -#include "erfa/pdp.c" -#include "erfa/pfw06.c" -#include "erfa/plan94.c" -#include "erfa/pm.c" -#include "erfa/pmat00.c" -#include "erfa/pmat06.c" -#include "erfa/pmat76.c" -#include "erfa/pmp.c" -#include "erfa/pn.c" -#include "erfa/pn00.c" -#include "erfa/pn00a.c" -#include "erfa/pn00b.c" -#include "erfa/pn06.c" -#include "erfa/pn06a.c" -#include "erfa/pnm00a.c" -#include "erfa/pnm00b.c" -#include "erfa/pnm06a.c" -#include "erfa/pnm80.c" -#include "erfa/pom00.c" -#include "erfa/ppp.c" -#include "erfa/ppsp.c" -#include "erfa/pr00.c" -#include "erfa/prec76.c" -#include "erfa/pv2p.c" -#include "erfa/pv2s.c" -#include "erfa/pvdpv.c" -#include "erfa/pvm.c" -#include "erfa/pvmpv.c" -#include "erfa/pvppv.c" -#include "erfa/pvstar.c" -#include "erfa/pvu.c" -#include "erfa/pvup.c" -#include "erfa/pvxpv.c" -#include "erfa/pxp.c" -#include "erfa/refco.c" -#include "erfa/rm2v.c" -#include "erfa/rv2m.c" -#include "erfa/rx.c" -#include "erfa/rxp.c" -#include "erfa/rxpv.c" -#include "erfa/rxr.c" -#include "erfa/ry.c" -#include "erfa/rz.c" -#include "erfa/s00.c" -#include "erfa/s00a.c" -#include "erfa/s00b.c" -#include "erfa/s06.c" -#include "erfa/s06a.c" -#include "erfa/s2c.c" -#include "erfa/s2p.c" -#include "erfa/s2pv.c" -#include "erfa/s2xpv.c" -#include "erfa/sepp.c" -#include "erfa/seps.c" -#include "erfa/sp00.c" -#include "erfa/starpm.c" -#include "erfa/starpv.c" -#include "erfa/sxp.c" -#include "erfa/sxpv.c" -#include "erfa/taitt.c" -#include "erfa/taiut1.c" -#include "erfa/taiutc.c" -#include "erfa/tcbtdb.c" -#include "erfa/tcgtt.c" -#include "erfa/tdbtcb.c" -#include "erfa/tdbtt.c" -#include "erfa/tf2a.c" -#include "erfa/tf2d.c" -#include "erfa/tr.c" -#include "erfa/trxp.c" -#include "erfa/trxpv.c" -#include "erfa/tttai.c" -#include "erfa/tttcg.c" -#include "erfa/tttdb.c" -#include "erfa/ttut1.c" -#include "erfa/ut1tai.c" -#include "erfa/ut1tt.c" -#include "erfa/ut1utc.c" -#include "erfa/utctai.c" -#include "erfa/utcut1.c" -#include "erfa/xy06.c" -#include "erfa/xys00a.c" -#include "erfa/xys00b.c" -#include "erfa/xys06a.c" -#include "erfa/zp.c" -#include "erfa/zpv.c" -#include "erfa/zr.c" - -#endif - -#endif diff --git a/ast/parallel.pdf b/ast/parallel.pdf deleted file mode 100644 index c02ef03..0000000 Binary files a/ast/parallel.pdf and /dev/null differ diff --git a/ast/pcdmap.c b/ast/pcdmap.c deleted file mode 100644 index 7c043d6..0000000 --- a/ast/pcdmap.c +++ /dev/null @@ -1,3218 +0,0 @@ -/* -*class++ -* Name: -* PcdMap - -* Purpose: -* Apply 2-dimensional pincushion/barrel distortion. - -* Constructor Function: -c astPcdMap -f AST_PCDMAP - -* Description: -* A PcdMap is a non-linear Mapping which transforms 2-dimensional -* positions to correct for the radial distortion introduced by some -* cameras and telescopes. This can take the form either of pincushion -* or barrel distortion, and is characterized by a single distortion -* coefficient. -* -* A PcdMap is specified by giving this distortion coefficient and the -* coordinates of the centre of the radial distortion. The forward -* transformation of a PcdMap applies the distortion: -* -* RD = R * ( 1 + C * R * R ) -* -* where R is the undistorted radial distance from the distortion -* centre (specified by attribute PcdCen), RD is the radial distance -* from the same centre in the presence of distortion, and C is the -* distortion coefficient (given by attribute Disco). -* -* The inverse transformation of a PcdMap removes the distortion -* produced by the forward transformation. The expression used to derive -* R from RD is an approximate inverse of the expression above. - -* Inheritance: -* The PcdMap class inherits from the Mapping class. - -* Attributes: -* In addition to those attributes common to all Mappings, every -* PcdMap also has the following attributes: -* -* - Disco: PcdMap pincushion/barrel distortion coefficient -* - PcdCen(axis): Centre coordinates of pincushion/barrel distortion - -* Functions: -c The PcdMap class does not define any new functions beyond those -f The PcdMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David Berry (Starlink) - -* History: -* 18-MAY-1999 (DSB): -* Original version. -* 25-OCT-1999 (DSB): -* Fixed memory leak in MapMerge. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitPcdMapVtab -* method. -* 23-AUG-2006 (DSB): -* Override astEqual. -* 23-APR-2015 (DSB): -* Improve MapMerge. If a PcdMap can merge with its next-but-one -* neighbour, then swap the PcdMap with its neighbour, so that -* it is then next its next-but-one neighbour, and then merge the -* two Mappings into a single Mapping. Previously, only the swap -* was performed - not the merger. And the swap was only performed -* if the intervening neighbour could not itself merge. This could -* result in an infinite simplification loop, which was detected by -* CmpMap and and aborted, resulting in no useful simplification. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS PcdMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "unitmap.h" /* Unit mappings */ -#include "zoommap.h" /* Zoom mappings */ -#include "permmap.h" /* Axis permutations */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "pcdmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(PcdMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(PcdMap,Class_Init) -#define class_vtab astGLOBAL(PcdMap,Class_Vtab) -#define getattrib_buff astGLOBAL(PcdMap,GetAttrib_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPcdMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstPcdMap *astPcdMapId_( double, const double [2], const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ - -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static double GetDisco( AstPcdMap *, int * ); -static double GetPcdCen( AstPcdMap *, int, int * ); -static int CanMerge( AstMapping *, AstMapping *, int, int, int * ); -static int CanSwap( AstMapping *, AstMapping *, int, int, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestDisco( AstPcdMap *, int * ); -static int TestPcdCen( AstPcdMap *, int, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearDisco( AstPcdMap *, int * ); -static void ClearPcdCen( AstPcdMap *, int, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void PcdPerm( AstMapping **, int *, int, int * ); -static void PcdZoom( AstMapping **, int *, int, int * ); -static void PermGet( AstPermMap *, int **, int **, double **, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetDisco( AstPcdMap *, double, int * ); -static void SetPcdCen( AstPcdMap *, int, double, int * ); - -/* Function Macros */ -/* =============== */ -/* Macros which return the maximum and minimum of two values. */ -#define MAX(aa,bb) ((aa)>(bb)?(aa):(bb)) -#define MIN(aa,bb) ((aa)<(bb)?(aa):(bb)) - -/* Macro to check for equality of floating point values. We cannot -compare bad values directory because of the danger of floating point -exceptions, so bad values are dealt with explicitly. */ -#define EQUAL(aa,bb) (((aa)==AST__BAD)?(((bb)==AST__BAD)?1:0):(((bb)==AST__BAD)?0:(fabs((aa)-(bb))<=1.0E5*MAX((fabs(aa)+fabs(bb))*DBL_EPSILON,DBL_MIN)))) - -/* -* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a method to clear a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "pcdmap.h" -* MAKE_CLEAR(attr,component,assign,nval) - -* Class Membership: -* Defined by the PcdMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstPcdMap *this, int axis ) -* -* and an external interface function of the form: -* -* void astClear_( AstPcdMap *this, int axis ) -* -* which implement a method for clearing a single value in a specified -* multi-valued attribute for an axis of a PcdMap. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. PcdCen in "astClearPcdCen"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attr,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstPcdMap *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astClear" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Report an error if the object has been cloned (i.e. has a reference \ - count that is greater than one). */ \ - } else if( astGetRefCount( this ) > 1 ) { \ - astError( AST__IMMUT, "astClear(%s): The " #attr "attribute of " \ - "the supplied %s cannot be cleared because the %s has " \ - "been cloned (programming error).", status, \ - astGetClass(this), astGetClass(this), astGetClass(this) ); \ -\ -/* Assign the "clear" value. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attr##_( AstPcdMap *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,PcdMap,Clear##attr))( this, axis, status ); \ -} - - -/* -* -* Name: -* MAKE_GET - -* Purpose: -* Implement a method to get a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "pcdmap.h" -* MAKE_GET(attr,type,bad_value,assign,nval) - -* Class Membership: -* Defined by the PcdMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( AstPcdMap *this, int axis ) -* -* and an external interface function of the form: -* -* astGet_( AstPcdMap *this, int axis ) -* -* which implement a method for getting a single value from a specified -* multi-valued attribute for an axis of a PcdMap. - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. PcdCen in "astGetPcdCen"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. This can -* use the string "axis" to represent the zero-based value index. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET(attr,type,bad_value,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attr( AstPcdMap *this, int axis, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Initialise */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astGet" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -type astGet##attr##_( AstPcdMap *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,PcdMap,Get##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_SET - -* Purpose: -* Implement a method to set a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "pcdmap.h" -* MAKE_SET(attr,type,component,assign,nval) - -* Class Membership: -* Defined by the PcdMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstPcdMap *this, int axis, value ) -* -* and an external interface function of the form: -* -* void astSet_( AstPcdMap *this, int axis, value ) -* -* which implement a method for setting a single value in a specified -* multi-valued attribute for a PcdMap. - -* Parameters: -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. PcdCen in "astSetPcdCen"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET(attr,type,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstPcdMap *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astSet" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Report an error if the object has been cloned (i.e. has a reference \ - count that is greater than one). */ \ - } else if( astGetRefCount( this ) > 1 ) { \ - astError( AST__IMMUT, "astSet(%s): The " #attr "attribute of " \ - "the supplied %s cannot be changed because the %s has " \ - "been cloned (programming error).", status, \ - astGetClass(this), astGetClass(this), astGetClass(this) ); \ -\ -/* Store the new value in the structure component. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attr##_( AstPcdMap *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,PcdMap,Set##attr))( this, axis, value, status ); \ -} - -/* -* -* Name: -* MAKE_TEST - -* Purpose: -* Implement a method to test if a single value has been set in a -* multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "pcdmap.h" -* MAKE_TEST(attr,assign,nval) - -* Class Membership: -* Defined by the PcdMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static int Test( AstPcdMap *this, int axis ) -* -* and an external interface function of the form: -* -* int astTest_( AstPcdMap *this, int axis ) -* -* which implement a method for testing if a single value in a specified -* multi-valued attribute has been set for a class. - -* Parameters: -* attr -* The name of the attribute to be tested, as it appears in the function -* name (e.g. PcdCen in "astTestPcdCen"). -* assign -* An expression that evaluates to 0 or 1, to be used as the returned -* value. This can use the string "axis" to represent the zero-based -* index of the value within the attribute. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_TEST(attr,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static int Test##attr( AstPcdMap *this, int axis, int *status ) { \ - int result; /* Value to return */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astTest" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -int astTest##attr##_( AstPcdMap *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,PcdMap,Test##attr))( this, axis, status ); \ -} - -/* Member functions. */ -/* ================= */ -static int CanMerge( AstMapping *map1, AstMapping *map2, int inv1, int inv2, int *status ){ -/* -* -* Name: -* CanMerge - -* Purpose: -* Checks if two Mappings can be merged. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* int CanMerge( AstMapping *map1, AstMapping *map2, int inv1, int inv2, int *status ) - -* Class Membership: -* PcdMap internal utility function. - -* Description: -* This function checks the two supplied Mappings to see if they -* can be merged into a single Mapping. One of the pair must be a PcdMap. - -* Parameters: -* map1 -* A pointer to the first mapping. -* map2 -* A pointer to the second mapping. -* inv1 -* The invert flag to use with the first mapping. -* inv2 -* The invert flag to use with the second mapping. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* 1 if the Mappings can be merged, zero otherwise. - -*/ - - AstPcdMap *pcd; /* Pointer to PcdMap Mapping */ - AstPcdMap *pcd2; /* Pointer to second PcdMap Mapping */ - AstMapping *nopcd; /* Pointer to non-PcdMap Mapping */ - const char *class1; /* Pointer to map1 class string */ - const char *class2; /* Pointer to map2 class string */ - const char *nopcd_class; /* Pointer to non-PcdMap class string */ - int invert[ 2 ]; /* Original invert flags */ - int ret; /* Returned flag */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise */ - ret = 0; - pcd = NULL; - nopcd = NULL; - -/* Temporarily set the Invert attributes of both Mappings to the supplied - values. */ - invert[ 0 ] = astGetInvert( map1 ); - astSetInvert( map1, inv1 ); - - invert[ 1 ] = astGetInvert( map2 ); - astSetInvert( map2, inv2 ); - -/* Get the classes of the two mappings. */ - class1 = astGetClass( map1 ); - class2 = astGetClass( map2 ); - if( astOK ){ - -/* Get pointers to the PcdMap and the non-PcdMap Mapping. */ - if( !strcmp( class1, "PcdMap" ) ){ - pcd = (AstPcdMap * ) map1; - nopcd = map2; - nopcd_class = class2; - } else if( !strcmp( class2, "PcdMap" ) ){ - nopcd = map1; - pcd = (AstPcdMap * ) map2; - nopcd_class = class1; - } else { - nopcd_class = "unusable"; - } - -/* The Mappings can merge if the other Mapping is a UnitMap. */ - if( !strcmp( nopcd_class, "UnitMap" ) ){ - ret = 1; - -/* They can also merge if the other Mapping is also a PcdMap, and is the - invert of the other. */ - } else if( !strcmp( nopcd_class, "PcdMap" ) ){ - pcd2 = (AstPcdMap *) nopcd; - -/* Check the distortion coefficients are equal. */ - if( EQUAL( astGetDisco( pcd ), astGetDisco( pcd2 ) ) ){ - -/* Check the axis 0 centres are equal. */ - if( EQUAL( astGetPcdCen( pcd, 0 ), astGetPcdCen( pcd2, 0 ) ) ){ - -/* Check the axis 1 centres are equal. */ - if( EQUAL( astGetPcdCen( pcd, 1 ), astGetPcdCen( pcd2, 1 ) ) ){ - -/* Check the Invert flags are different. */ - if( astGetInvert( pcd ) != astGetInvert( pcd2 ) ){ - -/* If the Mappings have passed all these tests, they can be merged. */ - ret = 1; - } - } - } - } - } - } - -/* Re-instate the original settings of the Invert attributes for the - supplied Mappings. */ - astSetInvert( map1, invert[ 0 ] ); - astSetInvert( map2, invert[ 1 ] ); - -/* Return the answer. */ - return astOK ? ret : 0; -} - -static int CanSwap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, int *status ){ -/* -* Name: -* CanSwap - -* Purpose: -* Determine if two Mappings could be swapped. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* int CanSwap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, int *status ) - -* Class Membership: -* PcdMap member function - -* Description: -* This function returns a flag indicating if the pair of supplied -* Mappings could be replaced by an equivalent pair of Mappings from the -* same classes as the supplied pair, but in reversed order. Each pair -* of Mappings is considered to be compounded in series. The supplied -* Mappings are not changed in any way. - -* Parameters: -* map1 -* The Mapping to be applied first. -* map2 -* The Mapping to be applied second. -* inv1 -* The invert flag to use with map1. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* inv2 -* The invert flag to use with map2. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* 1 if the Mappings could be swapped, 0 otherwise. - -* Notes: -* - One of the supplied pair of Mappings must be a PcdMap. -* - A value of 0 is returned if the two Mappings could be merged into -* a single Mapping. -* - A value of 0 is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *nopcd; /* Pointer to non-PcdMap Mapping */ - const char *class1; /* Pointer to map1 class string */ - const char *class2; /* Pointer to map2 class string */ - const char *nopcd_class; /* Pointer to non-PcdMap class string */ - double *consts; /* Pointer to constants array */ - int *inperm; /* Pointer to input axis permutation array */ - int *outperm; /* Pointer to output axis permutation array */ - int invert[ 2 ]; /* Original invert flags */ - int nin; /* No. of input coordinates for the PermMap */ - int nout; /* No. of output coordinates for the PermMap */ - int ret; /* Returned flag */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise */ - ret = 0; - -/* Temporarily set the Invert attributes of both Mappings to the supplied - values. */ - invert[ 0 ] = astGetInvert( map1 ); - astSetInvert( map1, inv1 ); - - invert[ 1 ] = astGetInvert( map2 ); - astSetInvert( map2, inv2 ); - -/* Get the classes of the two mappings. */ - class1 = astGetClass( map1 ); - class2 = astGetClass( map2 ); - if( astOK ){ - -/* Get a pointer to the non-PcdMap Mapping. */ - if( !strcmp( class1, "PcdMap" ) ){ - nopcd = map2; - nopcd_class = class2; - } else { - nopcd = map1; - nopcd_class = class1; - } - -/* If the other Mapping is a ZoomMap, the Mappings can be swapped. */ - if( !strcmp( nopcd_class, "ZoomMap" ) ){ - ret = 1; - -/* If it is a PermMap, the Mappings can be swapped so long as the PermMap - simply swaps the two axes. */ - } else if( !strcmp( nopcd_class, "PermMap" ) ){ - -/* Get the number of input and output coordinates for the PermMap. */ - nin = astGetNin( nopcd ); - nout = astGetNout( nopcd ); - -/* Must be 2-dimensional to swap. */ - if( nin == 2 && nout == 2 ) { - -/* Get the axis permutation arrays and constants array for the PermMap. */ - PermGet( (AstPermMap *) nopcd, &outperm, &inperm, &consts, status ); - if( astOK ) { - -/* If the PermMap simply swaps the 2 axes (in both direction) we can - swap the two mappings. */ - ret = ( outperm[0] == 1 && outperm[1] == 0 && - inperm[0] == 1 && inperm[1] == 0 ); - -/* Free the axis permutation and constants arrays. */ - outperm = (int *) astFree( (void *) outperm ); - inperm = (int *) astFree( (void *) inperm ); - consts = (double *) astFree( (void *) consts ); - } - } - } - } - -/* Re-instate the original settings of the Invert attributes for the - supplied Mappings. */ - astSetInvert( map1, invert[ 0 ] ); - astSetInvert( map2, invert[ 1 ] ); - -/* Return the answer. */ - return astOK ? ret : 0; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a PcdMap. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PcdMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* PcdMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the PcdMap. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPcdMap *this; /* Pointer to the PcdMap structure */ - int axis; /* Axis number */ - int len; /* Length of attrib string */ - int nc; /* No. characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PcdMap structure. */ - this = (AstPcdMap *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* PcdCen(axis). */ -/* ------------- */ - if ( nc = 0, - ( 1 == astSscanf( attrib, "pcdcen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearPcdCen( this, axis - 1 ); - -/* PcdCen. */ -/* ------- */ - } else if ( !strcmp( attrib, "pcdcen" ) ) { - astClearPcdCen( this, 0 ); - astClearPcdCen( this, 1 ); - -/* Disco. */ -/* ------ */ - } else if ( !strcmp( attrib, "disco" ) ) { - astClearDisco( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two PcdMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* PcdMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two PcdMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a PcdMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the PcdMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPcdMap *that; - AstPcdMap *this; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two PcdMap structures. */ - this = (AstPcdMap *) this_object; - that = (AstPcdMap *) that_object; - -/* Check the second object is a PcdMap. We know the first is a - PcdMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAPcdMap( that ) ) { - -/* Check the Invert flags for the two PcdMaps are equal. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - -/* Check all the attributes are equal. */ - if( astEQUAL( this->pcdcen[0], that->pcdcen[0] ) && - astEQUAL( this->pcdcen[1], that->pcdcen[1] ) && - astEQUAL( this->disco, that->disco ) ) { - result = 1; - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a PcdMap. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PcdMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a PcdMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the PcdMap. -* attrib -* Pointer to a null terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the PcdMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the PcdMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPcdMap *this; /* Pointer to the PcdMap structure */ - const char *result; /* Pointer value to return */ - double dval; /* Double attribute value */ - int axis; /* Axis number */ - int len; /* Length of attrib string */ - int nc; /* No. characters read by astSscanf */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the PcdMap structure. */ - this = (AstPcdMap *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* Disco. */ -/* ------ */ - if ( !strcmp( attrib, "disco" ) ) { - dval = astGetDisco( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* PcdCen(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "pcdcen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetPcdCen( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* PcdCen. */ -/* ------- */ - } else if ( !strcmp( attrib, "pcdcen" ) ) { - dval = astGetPcdCen( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -void astInitPcdMapVtab_( AstPcdMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitPcdMapVtab - -* Purpose: -* Initialise a virtual function table for a PcdMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "pcdmap.h" -* void astInitPcdMapVtab( AstPcdMapVtab *vtab, const char *name ) - -* Class Membership: -* PcdMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the PcdMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAPcdMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->ClearDisco = ClearDisco; - vtab->SetDisco = SetDisco; - vtab->GetDisco = GetDisco; - vtab->TestDisco = TestDisco; - vtab->ClearPcdCen = ClearPcdCen; - vtab->SetPcdCen = SetPcdCen; - vtab->GetPcdCen = GetPcdCen; - vtab->TestPcdCen = TestPcdCen; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - object->Equal = Equal; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - mapping->MapMerge = MapMerge; - -/* Declare the class dump function.*/ - astSetDump( vtab, Dump, "PcdMap", "Apply pincushion distortion" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a PcdMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* PcdMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated PcdMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated PcdMap with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated PcdMap which is to be merged with -* its neighbours. This should be a cloned copy of the PcdMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* PcdMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated PcdMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping **maplt; /* New mappings list pointer */ - AstMapping *map2; /* First mapping to check */ - AstMapping *newmap; /* Pointer to replacement Mapping */ - AstMapping *mc[2]; /* Copies of supplied Mappings to swap */ - AstMapping *smc0; /* Simplied Mapping */ - AstMapping *smc1; /* Simplied Mapping */ - const char *class1; /* Pointer to first Mapping class string */ - const char *class2; /* Pointer to second Mapping class string */ - const char *nclass; /* Pointer to neighbouring Mapping class */ - int i1; /* Index of first PcdMap to merge */ - int i2; /* Index of last PcdMap to merge */ - int i; /* Loop counter */ - int ic[2]; /* Copies of supplied invert flags to swap */ - int invert; /* Should the inverted Mapping be used? */ - int *invlt; /* New invert flags list pointer */ - int nmapt; /* No. of Mappings in list */ - int nstep1; /* No. of Mappings backwards to next mergable Mapping */ - int nstep2; /* No. of Mappings forward to next mergable Mapping */ - int result; /* Result value to return */ - int swaphi; /* Can PcdMap be swapped with higher neighbour? */ - int swaplo; /* Can PcdMap be swapped with lower neighbour? */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - i1 = 0; - i2 = 0; - -/* First of all, see if the PcdMap can be replaced by a simpler Mapping, - without reference to the neighbouring Mappings in the list. */ -/* ======================================================================*/ -/* If the distortion coefficient in the PcdMap is zero, the PcdMap can be - replaced by a UnitMap. */ - if( EQUAL( astGetDisco( (AstPcdMap *) ( *map_list )[ where ] ), 0.0 ) ){ - -/* Annul the PcdMap pointer in the list and replace it with a UnitMap - pointer, and indicate that the forward transformation of the returned - UnitMap should be used. */ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) astUnitMap( 2, "", status ); - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - -/* If the PcdMap itself could not be simplified, see if it can be merged - with the Mappings on either side of it in the list. */ - } else { - -/* Store the classes of the neighbouring Mappings in the list. */ - class1 = ( where > 0 ) ? astGetClass( ( *map_list )[ where - 1 ] ) : NULL; - class2 = ( where < *nmap - 1 ) ? astGetClass( ( *map_list )[ where + 1 ] ) : NULL; - -/* In series. */ -/* ========== */ - if ( series ) { - -/* We first look to see if the PcdMap can be merged with one of its - neighbours, resulting in a reduction of one in the number of Mappings - in the list. A PcdMap can only merge directly with its own inverse, or - a UnitMap. */ - if( class1 && CanMerge( ( *map_list )[ where - 1 ], - ( *map_list )[ where ], - ( *invert_list )[ where - 1 ], - ( *invert_list )[ where ], status ) ){ - nclass = class1; - i1 = where - 1; - i2 = where; - - } else if( class2 && CanMerge( ( *map_list )[ where ], - ( *map_list )[ where + 1 ], - ( *invert_list )[ where ], - ( *invert_list )[ where + 1 ], status ) ){ - nclass = class2; - i1 = where; - i2 = where + 1; - - } else { - nclass = NULL; - } - -/* If the PcdMap can merge with one of its neighbours, create the merged - Mapping. */ - if( nclass ){ - -/* If the neighbour is a PcdMap, it must be the inverse of the nominated - Mapping, and so they merge to form a UnitMap. */ - if( !strcmp( nclass, "PcdMap" ) ){ - newmap = (AstMapping *) astUnitMap( 2, "", status ); - invert = 0; - -/* If the neighbour is a UnitMap, they merge to form a clone of the - nominated PcdMap. */ - } else { - newmap = (AstMapping *) astClone( ( *map_list )[ where ] ); - invert = ( *invert_list )[ where ]; - } - -/* If succesfull... */ - if( astOK ){ - -/* Annul the first of the two Mappings, and replace it with the merged - Mapping. Also set the invert flag. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - ( *map_list )[ i1 ] = newmap; - ( *invert_list )[ i1 ] = invert; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ i2 ] ); - for ( i = i2 + 1; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = i1; - - } - -/* If the PcdMap could not merge directly with either of its neighbours, - we consider whether it would be worthwhile to swap the PcdMap with - either of its neighbours. This can only be done for certain classes - of Mapping (ZoomMaps & some PermMaps), and will usually require both - Mappings to be modified (unless they are commutative). The advantage of - swapping the order of the Mappings is that it may result in the PcdMap - being adjacent to a Mapping with which it can merge directly on the next - invocation of this function, thus reducing the number of Mappings - in the list. */ - } else { - -/* Set a flag if we could swap the PcdMap with its higher neighbour. */ - if( where + 1 < *nmap ){ - swaphi = CanSwap( ( *map_list )[ where ], - ( *map_list )[ where + 1 ], - ( *invert_list )[ where ], - ( *invert_list )[ where + 1 ], status ); - } else { - swaphi = 0; - } - -/* If so, step through each of the Mappings which follow the PcdMap, - looking for a Mapping with which the PcdMap could merge directly. Stop - when such a Mapping is found, or if a Mapping is found with which the - PcdMap could definitely not swap. Note the number of Mappings which - separate the PcdMap from the Mapping with which it could merge (if - any). */ - nstep2 = -1; - if( swaphi ){ - for( i2 = where + 1; i2 < *nmap; i2++ ){ - -/* See if we may be able to merge with this Mapping. If so, note the number - of steps between the two Mappings and leave the loop. */ - nclass = astGetClass( ( *map_list )[ i2 ] ); - - if( !strcmp( nclass, "UnitMap" ) || - !strcmp( nclass, "PcdMap" ) ){ - nstep2 = i2 - where - 1; - break; - } - -/* If there is no chance that we can swap with this Mapping, leave the loop - with -1 for the number of steps to indicate that no merging is possible. - PcdMaps can swap with ZoomMaps and some PermMaps. */ - if( strcmp( nclass, "ZoomMap" ) && - strcmp( nclass, "PermMap" ) ) { - break; - } - - } - - } - -/* Do the same working forward from the PcdMap towards the start of the map - list. */ - if( where > 0 ){ - swaplo = CanSwap( ( *map_list )[ where - 1 ], - ( *map_list )[ where ], - ( *invert_list )[ where - 1 ], - ( *invert_list )[ where ], status ); - } else { - swaplo = 0; - } - - nstep1 = -1; - if( swaplo ){ - for( i1 = where - 1; i1 >= 0; i1-- ){ - - nclass = astGetClass( ( *map_list )[ i1 ] ); - - if( !strcmp( nclass, "UnitMap" ) || - !strcmp( nclass, "PcdMap" ) ){ - nstep1 = where - 1 - i1; - break; - } - - if( strcmp( nclass, "ZoomMap" ) && - strcmp( nclass, "PermMap" ) ) { - break; - } - - } - - } - -/* Choose which neighbour to swap with so that the PcdMap moves towards the - nearest Mapping with which it can merge. */ - if( nstep1 != -1 && ( nstep2 == -1 || nstep2 > nstep1 ) ){ - nclass = class1; - i1 = where - 1; - i2 = where; - } else if( nstep2 != -1 ){ - nclass = class2; - i1 = where; - i2 = where + 1; - } else { - nclass = NULL; - } - -/* If there is a target Mapping in the list with which the PcdMap could - merge, replace the supplied Mappings with swapped Mappings to bring a - PcdMap closer to the target Mapping. */ - if( nclass ){ - -/* Swap the Mappings. */ - if( !strcmp( nclass, "ZoomMap" ) ){ - PcdZoom( (*map_list) + i1, (*invert_list) + i1, where - i1, status ); - - } else if( !strcmp( nclass, "PermMap" ) ){ - PcdPerm( (*map_list) + i1, (*invert_list) + i1, where - i1, status ); - } - -/* And then merge them. */ - if( where == i1 && where + 1 < *nmap ) { /* Merging upwards */ - map2 = astClone( (*map_list)[ where + 1 ] ); - nmapt = *nmap - where - 1; - maplt = *map_list + where + 1; - invlt = *invert_list + where + 1; - - (void) astMapMerge( map2, 0, series, &nmapt, &maplt, &invlt ); - map2 = astAnnul( map2 ); - *nmap = where + 1 + nmapt; - - } else if( where - 2 >= 0 ) { /* Merging downwards */ - map2 = astClone( (*map_list)[ where - 2 ] ); - nmapt = *nmap - where + 2; - maplt = *map_list + where - 2 ; - invlt = *invert_list + where - 2; - - (void) astMapMerge( map2, 0, series, &nmapt, &maplt, &invlt ); - map2 = astAnnul( map2 ); - *nmap = where - 2 + nmapt; - } - - result = i1; - -/* If there is no Mapping available for merging, it may still be - advantageous to swap with a neighbour because the swapped Mapping may - be simpler than the original Mappings. */ - } else if( swaphi || swaplo ) { - -/* Try swapping with each possible neighbour in turn. */ - for( i = 0; i < 2; i++ ) { - -/* Set up the class and pointers for the mappings to be swapped, first - the lower neighbour, then the upper neighbour. */ - if( i == 0 && swaplo ){ - nclass = class1; - i1 = where - 1; - i2 = where; - - } else if( i == 1 && swaphi ){ - nclass = class2; - i1 = where; - i2 = where + 1; - - } else { - nclass = NULL; - } - -/* If we have a Mapping to swap with... */ - if( nclass ) { - -/* Take copies of the Mapping and Invert flag arrays so we do not change - the supplied values. */ - mc[ 0 ] = (AstMapping *) astCopy( ( (*map_list) + i1 )[0] ); - mc[ 1 ] = (AstMapping *) astCopy( ( (*map_list) + i1 )[1] ); - ic[ 0 ] = ( (*invert_list) + i1 )[0]; - ic[ 1 ] = ( (*invert_list) + i1 )[1]; - -/* Swap these Mappings. */ - if( !strcmp( nclass, "ZoomMap" ) ){ - PcdZoom( mc, ic, where - i1, status ); - } else if( !strcmp( nclass, "PermMap" ) ){ - PcdPerm( mc, ic, where - i1, status ); - } - -/* If neither of the swapped Mappings can be simplified further, then there - is no point in swapping the Mappings, so just annul the map copies. */ - smc0 = astSimplify( mc[0] ); - smc1 = astSimplify( mc[1] ); - - if( astGetClass( smc0 ) == astGetClass( mc[0] ) && - astGetClass( smc1 ) == astGetClass( mc[1] ) ) { - - mc[ 0 ] = (AstMapping *) astAnnul( mc[ 0 ] ); - mc[ 1 ] = (AstMapping *) astAnnul( mc[ 1 ] ); - -/* If one or both of the swapped Mappings could be simplified, then annul - the supplied Mappings and return the swapped mappings, storing the index - of the first modified Mapping. */ - } else { - (void ) astAnnul( ( (*map_list) + i1 )[0] ); - (void ) astAnnul( ( (*map_list) + i1 )[1] ); - - ( (*map_list) + i1 )[0] = mc[ 0 ]; - ( (*map_list) + i1 )[1] = mc[ 1 ]; - - ( (*invert_list) + i1 )[0] = ic[ 0 ]; - ( (*invert_list) + i1 )[1] = ic[ 1 ]; - - result = i1; - break; - } - -/* Annul the simplied Mappings */ - smc0 = astAnnul( smc0 ); - smc1 = astAnnul( smc1 ); - - } - } - } - } - -/* In parallel. */ -/* ============ */ -/* PcdMaps cannot combine in parallel with any other Mappings. */ - } - } - -/* Return the result. */ - return result; -} - -static void PermGet( AstPermMap *map, int **outperm, int **inperm, - double **consts, int *status ){ -/* -* Name: -* PermGet - -* Purpose: -* Get the axis permutation and constants array for a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* void PermGet( AstPermMap *map, int **outperm, int **inperm, -* double **const, int *status ) - -* Class Membership: -* PcdMap member function - -* Description: -* This function returns axis permutation and constants arrays which can -* be used to create a PermMap which is equivalent to the supplied PermMap. - -* Parameters: -* map -* The PermMap. -* outperm -* An address at which to return a popinter to an array of ints -* holding the output axis permutation array. The array should be -* released using astFree when no longer needed. -* inperm -* An address at which to return a popinter to an array of ints -* holding the input axis permutation array. The array should be -* released using astFree when no longer needed. -* consts -* An address at which to return a popinter to an array of doubles -* holding the constants array. The array should be released using -* astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - NULL pointers are returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* PointSet holding input positions for PermMap */ - AstPointSet *pset2; /* PointSet holding output positions for PermMap */ - double **ptr1; /* Pointer to pset1 data */ - double **ptr2; /* Pointer to pset2 data */ - double *cnst; /* Pointer to constants array */ - double cn; /* Potential new constant value */ - double ip; /* Potential output axis index */ - double op; /* Potential input axis index */ - int *inprm; /* Pointer to input axis permutation array */ - int *outprm; /* Pointer to output axis permutation array */ - int i; /* Axis count */ - int nc; /* Number of constants stored so far */ - int nin; /* No. of input coordinates for the PermMap */ - int nout; /* No. of output coordinates for the PermMap */ - -/* Initialise. */ - if( outperm ) *outperm = NULL; - if( inperm ) *inperm = NULL; - if( consts ) *consts = NULL; - -/* Check the global error status and the supplied pointers. */ - if ( !astOK || !outperm || !inperm || !consts ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - nc = 0; - -/* Get the number of input and output axes for the supplied PermMap. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - -/* Allocate the memory for the returned arrays. */ - outprm = (int *) astMalloc( sizeof( int )* (size_t) nout ); - inprm = (int *) astMalloc( sizeof( int )* (size_t) nin ); - cnst = (double *) astMalloc( sizeof( double )* (size_t) ( nout + nin ) ); - -/* Returned the pointers to these arrays.*/ - *outperm = outprm; - *inperm = inprm; - *consts = cnst; - -/* Create two PointSets, each holding two points, which can be used for - input and output positions with the PermMap. */ - pset1 = astPointSet( 2, nin, "", status ); - pset2 = astPointSet( 2, nout, "", status ); - -/* Set up the two input positions to be [0,1,2...] and [-1,-1,-1,...]. The - first position is used to enumerate the axes, and the second is used to - check for constant axis values. */ - ptr1 = astGetPoints( pset1 ); - if( astOK ){ - for( i = 0; i < nin; i++ ){ - ptr1[ i ][ 0 ] = ( double ) i; - ptr1[ i ][ 1 ] = -1.0; - } - } - -/* Use the PermMap to transform these positions in the forward direction. */ - (void) astTransform( map, pset1, 1, pset2 ); - -/* Look at the mapped positions to determine the output axis permutation - array. */ - ptr2 = astGetPoints( pset2 ); - if( astOK ){ - -/* No constant axis valeus found yet. */ - nc = 0; - -/* Do each output axis. */ - for( i = 0; i < nout; i++ ){ - -/* If the output axis value is copied from an input axis value, the index - of the appropriate input axis will be in the mapped first position. */ - op = ptr2[ i ][ 0 ]; - -/* If the output axis value is assigned a constant value, the result of - mapping the two different input axis values will be the same. */ - cn = ptr2[ i ][ 1 ]; - if( op == cn ) { - -/* We have found another constant. Store it in the constants array, and - store the index of the constant in the output axis permutation array. */ - cnst[ nc ] = cn; - outprm[ i ] = -( nc + 1 ); - nc++; - -/* If the output axis values are different, then the output axis value - must be copied from the input axis value. */ - } else { - outprm[ i ] = (int) ( op + 0.5 ); - } - } - } - -/* Now do the same thing to determine the input permutation array. */ - if( astOK ){ - for( i = 0; i < nout; i++ ){ - ptr2[ i ][ 0 ] = ( double ) i; - ptr2[ i ][ 1 ] = -1.0; - } - } - - (void) astTransform( map, pset2, 0, pset1 ); - - if( astOK ){ - - for( i = 0; i < nin; i++ ){ - - ip = ptr1[ i ][ 0 ]; - cn = ptr1[ i ][ 1 ]; - if( ip == cn ) { - - cnst[ nc ] = cn; - inprm[ i ] = -( nc + 1 ); - nc++; - - } else { - inprm[ i ] = (int) ( ip + 0.5 ); - } - } - } - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* If an error has occurred, attempt to free the returned arrays. */ - if( !astOK ) { - *outperm = (int *) astFree( (void *) *outperm ); - *inperm = (int *) astFree( (void *) *inperm ); - *consts = (double *) astFree( (void *) *consts ); - } - -/* Return. */ - return; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a PcdMap. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* PcdMap member function (over-rides the astSetAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function assigns an attribute value for a PcdMap, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the PcdMap. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPcdMap *this; /* Pointer to the PcdMap structure */ - double dval; /* Double attribute value */ - int axis; /* Index for the axis */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PcdMap structure. */ - this = (AstPcdMap *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* Disco. */ -/* ------ */ - if ( nc = 0, - ( 1 == astSscanf( setting, "disco= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetDisco( this, dval ); - -/* PcdCen(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "pcdcen(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetPcdCen( this, axis - 1, dval ); - -/* PcdCen. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "pcdcen= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetPcdCen( this, 0, dval ); - astSetPcdCen( this, 1, dval ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a PcdMap. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PcdMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a PcdMap's attributes. - -* Parameters: -* this -* Pointer to the PcdMap. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPcdMap *this; /* Pointer to the PcdMap structure */ - int axis; /* Axis number */ - int len; /* Length of attrib string */ - int nc; /* No. characters read by astSscanf */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the PcdMap structure. */ - this = (AstPcdMap *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* Disco. */ -/* ------ */ - if ( !strcmp( attrib, "disco" ) ) { - result = astTestDisco( this ); - -/* PcdCen. */ -/* ------- */ - } else if ( !strcmp( attrib, "pcdcen" ) ) { - result = astTestPcdCen( this, 0 ); - -/* PcdCen(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "pcdcen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestPcdCen( this, axis - 1 ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a PcdMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* PcdMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a PcdMap and a set of points encapsulated in a -* PointSet and transforms the points so as to map them into the -* required window. - -* Parameters: -* this -* Pointer to the PcdMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the PcdMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstPcdMap *map; /* Pointer to PcdMap to be applied */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *axin_0; /* Pointer to next input axis 0 value */ - double *axin_1; /* Pointer to next input axis 1 value */ - double *axout_0; /* Pointer to next output axis 0 value */ - double *axout_1; /* Pointer to next output axis 1 value */ - int npoint; /* Number of points */ - int point; /* Loop counter for points */ - double dx; /* Undistorted X increment from centre */ - double dy; /* Undistorted Y increment from centre */ - double dxp; /* Distorted X increment from centre */ - double dyp; /* Distorted Y increment from centre */ - double disco; /* Distortion coefficient */ - double cen0; /* Centre of distortion on axis 0 */ - double cen1; /* Centre of distortion on axis 1 */ - double cr2; /* Constant */ - double a; /* Constant */ - double cr2a2; /* Constant */ - double f; /* Expansion factor */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the PcdMap. */ - map = (AstPcdMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse mapping, according to the - direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Get the distortion coefficient and centre. */ - disco = astGetDisco( map ); - cen0 = astGetPcdCen( map, 0 ); - cen1 = astGetPcdCen( map, 1 ); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if( astOK ){ - -/* Store pointers to the first input and output values on both axes. */ - axin_0 = ptr_in[ 0 ]; - axin_1 = ptr_in[ 1 ]; - axout_0 = ptr_out[ 0 ]; - axout_1 = ptr_out[ 1 ]; - -/* First deal with forward transformations. */ - if( forward ){ - - for( point = 0; point < npoint; point++ ){ - if( *axin_0 != AST__BAD && *axin_1 != AST__BAD ){ - dx = ( *axin_0 - cen0 ); - dy = ( *axin_1 - cen1 ); - f = 1.0 + disco*( dx*dx + dy*dy ); - dxp = dx*f; - dyp = dy*f; - *(axout_0++) = dxp + cen0; - *(axout_1++) = dyp + cen1; - - } else { - *(axout_0++) = AST__BAD; - *(axout_1++) = AST__BAD; - } - axin_0++; - axin_1++; - } - -/* Now deal with inverse transformations. */ - } else { - - for( point = 0; point < npoint; point++ ){ - if( *axin_0 != AST__BAD && *axin_1 != AST__BAD ){ - dxp = ( *axin_0 - cen0 ); - dyp = ( *axin_1 - cen1 ); - - cr2 = disco*( dxp*dxp + dyp*dyp ); - a = ( 2.0*cr2 + 1.0 )/( 3.0*cr2 + 1.0 ); - cr2a2 = cr2*a*a; - f = ( 2.0*cr2a2*a + 1.0 )/( 3.0*cr2a2 + 1.0 ); - - dx = dxp*f; - dy = dyp*f; - -/* The above approximate inverse is taken from SLA_UNPCD. If more accuracy -c is needed, the following code can be uncommented to iterate to a better -c solution. -c -c fl = 1.0 + disco*( dx*dx + dy*dy ); -c dx = dxp/fl; -c dy = dyp/fl; -c -c df = fabs( fl ); -c while( df > fabs( fl*1.0E-6 ) ){ -c f = 1.0 + disco*( dx*dx + dy*dy ); -c df = fabs( f - fl ); -c fl = f; -c -c dx = dxp/f; -c dy = dyp/f; -c } -*/ - *(axout_0++) = dx + cen0; - *(axout_1++) = dy + cen1; - - } else { - *(axout_0++) = AST__BAD; - *(axout_1++) = AST__BAD; - } - axin_0++; - axin_1++; - } - - } - - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -static void PcdZoom( AstMapping **maps, int *inverts, int ipc, int *status ){ -/* -* Name: -* PcdZoom - -* Purpose: -* Swap a PcdMap and a ZoomMap. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* void PcdZoom( AstMapping **maps, int *inverts, int ipc, int *status ) - -* Class Membership: -* PcdMap member function - -* Description: -* A list of two Mappings is supplied containing a PcdMap and a -* ZoomMap. These Mappings are annulled, and replaced with -* another pair of Mappings consisting of a PcdMap and a ZoomMap -* in the opposite order. These Mappings are chosen so that their -* combined effect is the same as the original pair of Mappings. - -* Parameters: -* maps -* A pointer to an array of two Mapping pointers. -* inverts -* A pointer to an array of two invert flags. -* ipc -* The index within "maps" of the PcdMap. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPcdMap *pm2; /* Pointer to the returned PcdMap */ - AstPcdMap *pm; /* Pointer to the supplied PcdMap */ - AstZoomMap *zm2; /* Pointer to the returned ZoomMap */ - AstZoomMap *zm; /* Pointer to the supplied ZoomMap */ - double cen[2]; /* New distortion centre */ - double disc; /* Distortion coeff. for returned PcdMap */ - double disco; /* Distortion coeff. for supplied PcdMap */ - double xcen; /* Axis 0 centre for supplied PcdMap */ - double ycen; /* Axis 1 centre for supplied PcdMap */ - double zoom; /* Zoom factor for supplied ZoomMap */ - int old_pinv; /* Invert value for the supplied PcdMap */ - int old_zinv; /* Invert value for the supplied ZoomMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store pointers to the supplied PcdMap and the ZoomMap. */ - pm = (AstPcdMap *) maps[ ipc ]; - zm = (AstZoomMap *) maps[ 1 - ipc ]; - -/* Temporarily set the Invert attribute of the supplied Mappings to the - supplied values. */ - old_pinv = astGetInvert( pm ); - astSetInvert( pm, inverts[ ipc ] ); - - old_zinv = astGetInvert( zm ); - astSetInvert( zm, inverts[ 1 - ipc ] ); - -/* Get the zoom factor from the ZoomMap. */ - zoom = astGetZoom( zm ); - -/* Get the distortion coefficient from the PcdMap. */ - disco = astGetDisco( pm ); - -/* Get the distortion centre from the PcdMap. */ - xcen = astGetPcdCen( pm, 0 ); - ycen = astGetPcdCen( pm, 1 ); - -/* Re-instate the original value of the Invert attributes of the supplied - Mappings. */ - astSetInvert( pm, old_pinv ); - astSetInvert( zm, old_zinv ); - -/* Create the returned ZoomMap. */ - zm2 = astZoomMap( 2, zoom, "", status ); - -/* Find the attributes of the returned PcdMap. If the PCD map is applied - first... */ - if( ipc == 0 ) { - cen[ 0 ] = xcen*zoom; - cen[ 1 ] = ycen*zoom; - disc = disco/(zoom*zoom); - -/* If the PCD map is applied second... */ - } else { - cen[ 0 ] = xcen/zoom; - cen[ 1 ] = ycen/zoom; - disc = disco*zoom*zoom; - } - -/* Create the returned PcdMap. */ - pm2 = astPcdMap( disc, cen, "", status ); - if( inverts[ ipc ] ) astInvert( pm2 ); - -/* Replace the supplied Mappings with the ones created above, swapping the - order. */ - if( astOK ){ - (void) astAnnul( pm ); - (void) astAnnul( zm ); - - maps[ 1 - ipc ] = (AstMapping *) pm2; - inverts[ 1 - ipc ] = inverts[ ipc ]; - - maps[ ipc ] = (AstMapping *) zm2; - inverts[ ipc ] = 0; - - } - -/* Return. */ - return; -} - -static void PcdPerm( AstMapping **maps, int *inverts, int ipc, int *status ){ -/* -* Name: -* PcdPerm - -* Purpose: -* Swap a PcdMap and a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* void PcdPerm( AstMapping **maps, int *inverts, int ipc, int *status ) - -* Class Membership: -* PcdMap member function - -* Description: -* A list of two Mappings is supplied containing a PcdMap and a -* PermMap. These Mappings are annulled, and replaced with -* another pair of Mappings consisting of a PcdMap and a PermMap -* in the opposite order. These Mappings are chosen so that their -* combined effect is the same as the original pair of Mappings. - -* Parameters: -* maps -* A pointer to an array of two Mapping pointers. -* inverts -* A pointer to an array of two invert flags. -* ipc -* The index within "maps" of the PcdMap. -* status -* Pointer to the inherited status variable. - -* Notes: -* - It should have been checked previously that the PermMap simply -* swaps axes 0 and 1. This is the only sort of PermMap which can be -* used here. - -*/ - - AstPermMap *rm; /* Pointer to the supplied PermMap */ - AstPermMap *rm2; /* Pointer to the returned PermMap */ - AstPcdMap *pm; /* Pointer to the supplied PcdMap */ - AstPcdMap *pm2; /* Pointer to the returned PcdMap */ - double cen[2]; /* Centre for new PcdMap */ - double disco; /* Distortion coeff. for supplied PcdMap */ - double xcen; /* Axis 0 centre for supplied PcdMap */ - double ycen; /* Axis 1 centre for supplied PcdMap */ - int old_rinv; /* Invert value for the supplied PermMap */ - int old_pinv; /* Invert value for the supplied PcdMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store pointers to the supplied PcdMap and the PermMap. */ - pm = (AstPcdMap *) maps[ ipc ]; - rm = (AstPermMap *) maps[ 1 - ipc ]; - -/* Temporarily set the Invert attribute of the supplied Mappings to the - supplied values. */ - old_pinv = astGetInvert( pm ); - astSetInvert( pm, inverts[ ipc ] ); - - old_rinv = astGetInvert( rm ); - astSetInvert( rm, inverts[ 1 - ipc ] ); - -/* Get the distortion coefficient from the PcdMap. */ - disco = astGetDisco( pm ); - -/* Get the distortion centre from the PcdMap. */ - xcen = astGetPcdCen( pm, 0 ); - ycen = astGetPcdCen( pm, 1 ); - -/* Re-instate the original value of the Invert attributes of the supplied - Mappings. */ - astSetInvert( pm, old_pinv ); - astSetInvert( rm, old_rinv ); - -/* Create the returned PermMap (unchanged). */ - rm2 = astClone( rm ); - -/* Create the returned PcdMap. */ - cen[ 0 ] = ycen; - cen[ 1 ] = xcen; - pm2 = astPcdMap( disco, cen, "", status ); - if( inverts[ ipc ] ) astInvert( pm2 ); - -/* Replace the supplied Mappings with the ones created above, swapping the - order. */ - if( astOK ){ - (void) astAnnul( pm ); - (void) astAnnul( rm ); - - old_pinv = inverts[ ipc ]; - - maps[ ipc ] = (AstMapping *) rm2; - inverts[ ipc ] = inverts[ 1 - ipc ]; - - maps[ 1 - ipc ] = (AstMapping *) pm2; - inverts[ 1 - ipc ] = old_pinv; - } - -/* Return. */ - return; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ -/* -*att++ -* Name: -* Disco - -* Purpose: -* PcdMap pincushion/barrel distortion coefficient. - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute specifies the pincushion/barrel distortion coefficient -* used by a PcdMap. This coefficient is set when the PcdMap is created, -* but may later be modified. If the attribute is cleared, its default -* value is zero, which gives no distortion. For pincushion distortion, -* the value should be positive. For barrel distortion, it should be -* negative. -* -* Note that the forward transformation of a PcdMap applies the -* distortion specified by this attribute and the inverse -* transformation removes this distortion. If the PcdMap is inverted -c (e.g. using astInvert), then the forward transformation will -f (e.g. using AST_INVERT), then the forward transformation will -* remove the distortion and the inverse transformation will apply -* it. The distortion itself will still be given by the same value of -* Disco. -* -* Note, the value of this attribute may changed only if the PcdMap -* has no more than one reference. That is, an error is reported if the -* PcdMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* PcdMap -* All PcdMaps have this attribute. - -*att-- -*/ -/* This ia a double value with a value of AST__BAD when undefined but - yielding a default of 0.0. */ -astMAKE_CLEAR1(PcdMap,Disco,disco,AST__BAD) -astMAKE_GET(PcdMap,Disco,double,0.0,( ( this->disco == AST__BAD ) ? - 0.0 : this->disco )) -astMAKE_SET1(PcdMap,Disco,double,disco,value) -astMAKE_TEST(PcdMap,Disco,( this->disco != AST__BAD )) - - -/* -*att++ -* Name: -* PcdCen(axis) - -* Purpose: -* Centre coordinates of pincushion/barrel distortion. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the centre of the pincushion/barrel -* distortion implemented by a PcdMap. It takes a separate value for -* each axis of the PcdMap so that, for instance, the settings -* "PcdCen(1)=345.0,PcdCen(2)=-104.4" specify that the pincushion -* distortion is centred at positions of 345.0 and -104.4 on axes 1 and 2 -* respectively. This attribute is set when a PcdMap is created, but may -* later be modified. If the attribute is cleared, the default value for -* both axes is zero. -* -* Note, the value of this attribute may changed only if the PcdMap -* has no more than one reference. That is, an error is reported if the -* PcdMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* PcdMap -* All PcdMaps have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "PcdCen" instead of -* "PcdCen(2)"), then a "set" or "clear" operation will affect -* the attribute value of both axes, while a "get" or "test" -* operation will use just the PcdCen(1) value. -*att-- -*/ -/* The centre of the distortion. AST__BAD is stored if no value has been - supplied, resulting in default values of zero being used. */ -MAKE_CLEAR(PcdCen,pcdcen,AST__BAD,2) -MAKE_SET(PcdCen,double,pcdcen,value,2) -MAKE_TEST(PcdCen,( this->pcdcen[axis] != AST__BAD ),2) -MAKE_GET(PcdCen,double,0.0,(( this->pcdcen[axis] == AST__BAD ) ? - 0.0 : this->pcdcen[axis] ),2) - -/* Copy constructor. */ -/* ----------------- */ -/* No copy constructor is needed, as a byte-by-byte copy suffices. */ - -/* Destructor. */ -/* ----------- */ -/* No destructor is needed as no memory, etc. needs freeing. */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for PcdMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the PcdMap class to an output Channel. - -* Parameters: -* this -* Pointer to the PcdMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPcdMap *this; /* Pointer to the PcdMap structure */ - double dval; /* Attribute value */ - int set; /* Is a value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PcdMap structure. */ - this = (AstPcdMap *) this_object; - -/* Write out values representing the instance variables for the - PcdMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* PcdCen(0). */ -/* ---------- */ - set = TestPcdCen( this, 0, status ); - dval = set ? GetPcdCen( this, 0, status ) : astGetPcdCen( this, 0 ); - astWriteDouble( channel, "PcdCn0", set, 1, dval, "Distortion centre on first axis" ); - -/* PcdCen(1). */ -/* ---------- */ - set = TestPcdCen( this, 1, status ); - dval = set ? GetPcdCen( this, 1, status ) : astGetPcdCen( this, 1 ); - astWriteDouble( channel, "PcdCn1", set, 1, dval, "Distortion centre on second axis" ); - -/* Disco. */ -/* ------ */ - set = TestDisco( this, status ); - dval = set ? GetDisco( this, status ) : astGetDisco( this ); - astWriteDouble( channel, "Disco", set, 1, dval, "Distortion coefficient" ); - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPcdMap and astCheckPcdMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(PcdMap,Mapping) -astMAKE_CHECK(PcdMap) - -AstPcdMap *astPcdMap_( double disco, const double pcdcen[2], - const char *options, int *status, ...) { -/* -*++ -* Name: -c astPcdMap -f AST_PCDMAP - -* Purpose: -* Create a PcdMap. - -* Type: -* Public function. - -* Synopsis: -c #include "pcdmap.h" -c AstPcdMap *astPcdMap( double disco, const double pcdcen[2], -c const char *options, ... ) -f RESULT = AST_PCDMAP( DISCO, PCDCEN, OPTIONS, STATUS ) - -* Class Membership: -* PcdMap constructor. - -* Description: -* This function creates a new PcdMap and optionally initialises its -* attributes. -* -* A PcdMap is a non-linear Mapping which transforms 2-dimensional -* positions to correct for the radial distortion introduced by some -* cameras and telescopes. This can take the form either of pincushion -* or barrel distortion, and is characterized by a single distortion -* coefficient. -* -* A PcdMap is specified by giving this distortion coefficient and the -* coordinates of the centre of the radial distortion. The forward -* transformation of a PcdMap applies the distortion: -* -* RD = R * ( 1 + C * R * R ) -* -* where R is the undistorted radial distance from the distortion -* centre (specified by attribute PcdCen), RD is the radial distance -* from the same centre in the presence of distortion, and C is the -* distortion coefficient (given by attribute Disco). -* -* The inverse transformation of a PcdMap removes the distortion -* produced by the forward transformation. The expression used to derive -* R from RD is an approximate inverse of the expression above, obtained -* from two iterations of the Newton-Raphson method. The mismatch between -* the forward and inverse expressions is negligible for astrometric -* applications (to reach 1 milliarcsec at the edge of the Anglo-Australian -* Telescope triplet or a Schmidt field would require field diameters of -* 2.4 and 42 degrees respectively). -* -c If a PcdMap is inverted (e.g. using astInvert) then the roles of the -f If a PcdMap is inverted (e.g. using AST_INVERT) then the roles of the -* forward and inverse transformations are reversed; the forward -* transformation will remove the distortion, and the inverse -* transformation will apply it. - -* Parameters: -c disco -f DISCO = DOUBLE PRECISION (Given) -* The distortion coefficient. Negative values give barrel -* distortion, positive values give pincushion distortion, and -* zero gives no distortion. -c pcdcen -f PCDCEN( 2 ) = DOUBLE PRECISION (Given) -c A 2-element array containing the coordinates of the centre of the -f An array containing the coordinates of the centre of the -* distortion. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new PcdMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new PcdMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPcdMap() -f AST_PCDMAP = INTEGER -* A pointer to the new PcdMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPcdMap *new; /* Pointer to new PcdMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the PcdMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPcdMap( NULL, sizeof( AstPcdMap ), !class_init, &class_vtab, - "PcdMap", disco, pcdcen ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new PcdMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new PcdMap. */ - return new; -} - -AstPcdMap *astPcdMapId_( double disco, const double pcdcen[2], - const char *options, ... ) { -/* -* Name: -* astPcdMapId_ - -* Purpose: -* Create a PcdMap. - -* Type: -* Private function. - -* Synopsis: -* #include "pcdmap.h" -* AstPcdMap *astPcdMapId_( double disco, const double pcdcen[2], -* const char *options, ... ) - -* Class Membership: -* PcdMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astPcdMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astPcdMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astPcdMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astPcdMap_. - -* Returned Value: -* The ID value associated with the new PcdMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPcdMap *new; /* Pointer to new PcdMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the PcdMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPcdMap( NULL, sizeof( AstPcdMap ), !class_init, &class_vtab, - "PcdMap", disco, pcdcen ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new PcdMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new PcdMap. */ - return astMakeId( new ); -} - -AstPcdMap *astInitPcdMap_( void *mem, size_t size, int init, - AstPcdMapVtab *vtab, const char *name, - double disco, const double pcdcen[2], int *status ){ -/* -*+ -* Name: -* astInitPcdMap - -* Purpose: -* Initialise a PcdMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "pcdmap.h" -* AstPcdMap *astInitPcdMap( void *mem, size_t size, int init, -* AstPcdMapVtab *vtab, const char *name, -* double disco, const double pcdcen[2] ) - -* Class Membership: -* PcdMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new PcdMap object. It allocates memory (if necessary) to accommodate -* the PcdMap plus any additional data associated with the derived class. -* It then initialises a PcdMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a PcdMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the PcdMap is to be initialised. -* This must be of sufficient size to accommodate the PcdMap data -* (sizeof(PcdMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the PcdMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the PcdMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the PcdMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new PcdMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* disco -* Distortion coefficient. -* pcdcen -* Distortion centre. - -* Returned Value: -* A pointer to the new PcdMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstPcdMap *new; /* Pointer to new PcdMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitPcdMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a Mapping structure (the parent class) as the first component - within the PcdMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstPcdMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - 2, 2, 1, 1 ); - - if ( astOK ) { - -/* Initialise the PcdMap data. */ -/* ---------------------------- */ -/* Store the shift and scale for each axis. */ - new->pcdcen[0] = pcdcen[0]; - new->pcdcen[1] = pcdcen[1]; - new->disco = disco; - -/* If an error occurred, clean up by deleting the new PcdMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new PcdMap. */ - return new; -} - -AstPcdMap *astLoadPcdMap_( void *mem, size_t size, - AstPcdMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPcdMap - -* Purpose: -* Load a PcdMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "pcdmap.h" -* AstPcdMap *astLoadPcdMap( void *mem, size_t size, -* AstPcdMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* PcdMap loader. - -* Description: -* This function is provided to load a new PcdMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* PcdMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a PcdMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the PcdMap is to be -* loaded. This must be of sufficient size to accommodate the -* PcdMap data (sizeof(PcdMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the PcdMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the PcdMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPcdMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new PcdMap. If this is NULL, a pointer -* to the (static) virtual function table for the PcdMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "PcdMap" is used instead. - -* Returned Value: -* A pointer to the new PcdMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPcdMap *new; /* Pointer to the new PcdMap */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this PcdMap. In this case the - PcdMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPcdMap ); - vtab = &class_vtab; - name = "PcdMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPcdMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built PcdMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "PcdMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* PcdCen(0). */ -/* ---------- */ - new->pcdcen[0] = astReadDouble( channel, "pcdcn0", AST__BAD ); - if ( TestPcdCen( new, 0, status ) ) SetPcdCen( new, 0, new->pcdcen[0], status ); - -/* PcdCen(1). */ -/* ---------- */ - new->pcdcen[1] = astReadDouble( channel, "pcdcn1", AST__BAD ); - if ( TestPcdCen( new, 1, status ) ) SetPcdCen( new, 1, new->pcdcen[1], status ); - -/* Disco. */ -/* ------ */ - new->disco = astReadDouble( channel, "disco", AST__BAD ); - if ( TestDisco( new, status ) ) SetDisco( new, new->disco, status ); - -/* If an error occurred, clean up by deleting the new PcdMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new PcdMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - diff --git a/ast/pcdmap.h b/ast/pcdmap.h deleted file mode 100644 index ca8fc24..0000000 --- a/ast/pcdmap.h +++ /dev/null @@ -1,357 +0,0 @@ -#if !defined( PCDMAP_INCLUDED ) /* Include this file only once */ -#define PCDMAP_INCLUDED -/* -*+ -* Name: -* pcdmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the PcdMap class. - -* Invocation: -* #include "pcdmap.h" - -* Description: -* This include file defines the interface to the PcdMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The PcdMap class implements Mappings which perform pincushion -* distortion. - -* Inheritance: -* The PcdMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* Disco (double) -* This attribute holds the PcdMap distortion coefficient used by -* the forward transformation. This coefficient is set when a -* PcdMap is created, but may later be modified. The default value -* is zero, which gives no distortion. For pincushion distortion, -* the supplied value should be positive. For barrel distortion, it -* should be negative. -* -* Note that the forward transformation of a PcdMap applies the -* distortion corresponding to this attribute, and the inverse -* transformation removes this distortion. If a PcdMap is inverted -* (e.g. by using astInvert), then the forward transformation will -* remove the distortion and the inverse transformation will apply -* it. The distortion itself will still be given by the same value of -* Disco. -* PcdCen(axis) -* This attribute specifies the centre of a pincushion distortion. -* It takes a separate value for each axis of the PcdMap so that, for -* instance, the settings "PcdCen(1)=345.0,PcdCen(2)=-104.4" specify -* that the pincushion distortion is centred at values of 345.0 and -* -104.4 on axes 1 and 2 of the PcdMap. The default for both axes is -* zero. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astClearAttrib -* Clear an attribute value for a PcdMap. -* astGetAttrib -* Get an attribute value for a PcdMap. -* astSetAttrib -* Set an attribute value for a PcdMap. -* astTestAttrib -* Test if an attribute value has been set for a PcdMap. -* astTransform -* Apply a PcdMap to transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* astClearDisco -* Clear the Disco attribute value for a PcdMap. -* astGetDisco -* Get the Disco attribute value for a PcdMap. -* astSetDisco -* Set the Disco attribute value for a PcdMap. -* astTestDisco -* Test if a Disco attribute value has been set for a PcdMap. -* astClearPcdCen -* Clear the PcdCen attribute value for a PcdMap. -* astGetPcdCen -* Get the PcdCen attribute value for a PcdMap. -* astSetPcdCen -* Set the PcdCen attribute value for a PcdMap. -* astTestPcdCen -* Test if a PcdCen attribute value has been set for a PcdMap. - -* Other Class Functions: -* Public: -* astIsAPcdMap -* Test class membership. -* astPcdMap -* Create a PcdMap. -* -* Protected: -* astCheckPcdMap -* Validate class membership. -* astInitPcdMap -* Initialise a PcdMap. -* astInitPcdMapVtab -* Initialise the virtual function table for the PcdMap class. -* astLoadPcdMap -* Load a PcdMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstPcdMap -* PcdMap object type. -* -* Protected: -* AstPcdMapVtab -* PcdMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 18-MAY-1999 (DSB): -* Original version. -* 8-JAN-2003 (DSB): -* Added protected astInitPcdMapVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* PcdMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstPcdMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double disco; /* Distortion coefficient */ - double pcdcen[2]; /* Distortion centre */ - -} AstPcdMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstPcdMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - double (*GetDisco)( AstPcdMap *, int * ); - int (* TestDisco)( AstPcdMap *, int * ); - void (* ClearDisco)( AstPcdMap *, int * ); - void (* SetDisco)( AstPcdMap *, double, int * ); - double (*GetPcdCen)( AstPcdMap *, int, int * ); - int (* TestPcdCen)( AstPcdMap *, int, int * ); - void (* ClearPcdCen)( AstPcdMap *, int, int * ); - void (* SetPcdCen)( AstPcdMap *, int, double, int * ); -} AstPcdMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstPcdMapGlobals { - -/* Define the thread-specific globals. */ - char GetAttrib_Buff[ 101 ]; - AstPcdMapVtab Class_Vtab; - int Class_Init; -} AstPcdMapGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(PcdMap) /* Check class membership */ -astPROTO_ISA(PcdMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstPcdMap *astPcdMap_( double, const double [2], const char *, int *, ...); -#else -AstPcdMap *astPcdMapId_( double, const double [2], const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstPcdMap *astInitPcdMap_( void *, size_t, int, AstPcdMapVtab *, - const char *, double, const double [2], int * ); - -/* Vtab initialiser. */ -void astInitPcdMapVtab_( AstPcdMapVtab *, const char *, int * ); - -/* Loader. */ -AstPcdMap *astLoadPcdMap_( void *, size_t, AstPcdMapVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitPcdMapGlobals_( AstPcdMapGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -double astGetDisco_( AstPcdMap *, int * ); -int astTestDisco_( AstPcdMap *, int * ); -void astClearDisco_( AstPcdMap *, int * ); -void astSetDisco_( AstPcdMap *, double, int * ); -double astGetPcdCen_( AstPcdMap *, int, int * ); -int astTestPcdCen_( AstPcdMap *, int, int * ); -void astClearPcdCen_( AstPcdMap *, int, int * ); -void astSetPcdCen_( AstPcdMap *, int, double, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckPcdMap(this) astINVOKE_CHECK(PcdMap,this,0) -#define astVerifyPcdMap(this) astINVOKE_CHECK(PcdMap,this,1) - -/* Test class membership. */ -#define astIsAPcdMap(this) astINVOKE_ISA(PcdMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astPcdMap astINVOKE(F,astPcdMap_) -#else -#define astPcdMap astINVOKE(F,astPcdMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitPcdMap(mem,size,init,vtab,name,disco,pcdcen) \ -astINVOKE(O,astInitPcdMap_(mem,size,init,vtab,name,disco,pcdcen,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitPcdMapVtab(vtab,name) astINVOKE(V,astInitPcdMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadPcdMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadPcdMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckPcdMap to validate PcdMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astClearDisco(this) astINVOKE(V,astClearDisco_(astCheckPcdMap(this),STATUS_PTR)) -#define astGetDisco(this) astINVOKE(V,astGetDisco_(astCheckPcdMap(this),STATUS_PTR)) -#define astSetDisco(this,value) \ -astINVOKE(V,astSetDisco_(astCheckPcdMap(this),value,STATUS_PTR)) -#define astTestDisco(this) astINVOKE(V,astTestDisco_(astCheckPcdMap(this),STATUS_PTR)) - -#define astClearPcdCen(this,axis) \ -astINVOKE(V,astClearPcdCen_(astCheckPcdMap(this),axis,STATUS_PTR)) -#define astGetPcdCen(this,axis) \ -astINVOKE(V,astGetPcdCen_(astCheckPcdMap(this),axis,STATUS_PTR)) -#define astSetPcdCen(this,axis,value) \ -astINVOKE(V,astSetPcdCen_(astCheckPcdMap(this),axis,value,STATUS_PTR)) -#define astTestPcdCen(this,axis) \ -astINVOKE(V,astTestPcdCen_(astCheckPcdMap(this),axis,STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/permmap.c b/ast/permmap.c deleted file mode 100644 index 69b0962..0000000 --- a/ast/permmap.c +++ /dev/null @@ -1,3204 +0,0 @@ -/* -*class++ -* Name: -* PermMap - -* Purpose: -* Coordinate permutation Mapping. - -* Constructor Function: -c astPermMap -f AST_PERMMAP - -* Description: -* A PermMap is a Mapping which permutes the order of coordinates, -* and possibly also changes the number of coordinates, between its -* input and output. -* -* In addition to permuting the coordinate order, a PermMap may -* also assign constant values to coordinates. This is useful when -* the number of coordinates is being increased as it allows fixed -* values to be assigned to any new ones. - -* Inheritance: -* The PermMap class inherits from the Mapping class. - -* Attributes: -* The PermMap class does not define any new attributes beyond -* those which are applicable to all Mappings. - -* Functions: -c The PermMap class does not define any new functions beyond those -f The PermMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 29-FEB-1996 (RFWS): -* Original version. -* 26-SEP-1996 (RFWS): -* Added external interface and I/O facilities. -* 3-JUN-1997 (RFWS): -* Over-ride the MapMerge method. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitPermMapVtab -* method. -* 11-SEP-2003 (DSB): -* Added methods astGetInPerm and astGetOutPerm. -* 2-NOV-2004 (DSB): -* Added method astGetConstants. -* 14-MAR-2006 (DSB): -* Override astEqual. -* 2-MAY-2007 (DSB): -* Change MapSplit so that it does not try to use the -* implementation from the parent Mapping class, since this -* class can do a better job. -* 11-SEP-2007 (DSB): -* In MapSplit, check that the permuted axis index is less than the -* number of axes available. Use AST__BAD otherwise. -* 10-JAN-2011 (DSB): -* Add protected PermSplit attribute. -* 11-FEB-2011 (DSB): -* Do not allow MapSplit to return a Mapping with zero outputs. -* 22-NOV-2012 (DSB): -* When using a default inperm array (as indicated by a NULL pointer -* for inperm), ensure the array is padded with "-1" values if the -* number of inputs exceeds the number of outputs. Also do the -* equivalent for default outperm arrays. -* 26-MAY-2016 (DSB): -* Allow the PermSplit attribute to be changed at any time. This is -* because it does not directly affect either the forward or inverse -* transformation of the PermMap. The FitsCHan class needs to be able -* to change it to determine when checking if the -TAB algorithm can -* be used. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS PermMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "unitmap.h" /* Unit Mappings */ -#include "permmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Macros */ -/* ============= */ -/* A macro that returns the inperm or outperm value to use for a given - index, taking account of the possibility that the inperm or outperm may - be NULL (implying a unit permutation), and that he numbers of inputs - and outputs may not be equal. "perms" is a pointer to the integer - permutation array (inperm or outperm), "i" is the index of the required - element of the permutation array, and "maxperm" is one more than the - maximum value allowed in the permutation array (i.e. the number of - PermMap outputs if "perms" is inperm, or PermMap inputs if "perms" is - outperm). */ -#define PERMVAL( perms, i, maxperm ) ( perms ? perms[ i ] : ( i < maxperm ? i : -1 )) - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(PermMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(PermMap,Class_Init) -#define class_vtab astGLOBAL(PermMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPermMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstPermMap *astPermMapId_( int, const int [], int, const int [], const double [], const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double *GetConstants( AstPermMap *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int *GetInPerm( AstPermMap *, int * ); -static int *GetOutPerm( AstPermMap *, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int NullPerm( AstPermMap *, int, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); - -static void SetPermSplit( AstPermMap *, int, int * ); -static void ClearPermSplit( AstPermMap *, int * ); -static int TestPermSplit( AstPermMap *, int * ); -static int GetPermSplit( AstPermMap *, int * ); - - -/* Member functions. */ -/* ================= */ - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two PermMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "permmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* PermMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two PermMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a PermMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the PermMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPermMap *that; - AstPermMap *this; - int *that_inp; - int *that_outp; - int *this_inp; - int *this_outp; - int i; - int nin; - int nin_that; - int nout; - int nout_that; - int p1; - int p2; - int result; - int that_inp_len; - int that_outp_len; - int this_inp_len; - int this_outp_len; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two PermMap structures. */ - this = (AstPermMap *) this_object; - that = (AstPermMap *) that_object; - -/* Check the second object is a PermMap. We know the first is a - PermMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAPermMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNout( that ) == nout && astGetNin( that ) == nin ) { - -/* Assume the PermMaps are equivalent. */ - result = 1; - -/* Get the number of inputs and outputs in the second PermMap. */ - nin_that = astGetNin( that ); - nout_that = astGetNout( that ); - -/* Get pointers to the effective inperm and outperm array for each PermMap. - If the Invert flags of the two PermMaps are not equal, we swap the - arrays for the second PermMap in order to take account of the relative - inversion of the second PermMap. */ - this_inp = this->inperm; - this_outp = this->outperm; - - if( astGetInvert( this ) ) { - this_inp_len = nout; - this_outp_len = nin; - } else { - this_inp_len = nin; - this_outp_len = nout; - } - - if( astGetInvert( this ) != astGetInvert( that ) ) { - that_inp = that->outperm; - that_outp = that->inperm; - - if( astGetInvert( that ) ) { - that_inp_len = nin_that; - that_outp_len = nout_that; - } else { - that_inp_len = nout_that; - that_outp_len = nin_that; - } - - } else { - that_inp = that->inperm; - that_outp = that->outperm; - - if( astGetInvert( that ) ) { - that_inp_len = nout_that; - that_outp_len = nin_that; - } else { - that_inp_len = nin_that; - that_outp_len = nout_that; - } - } - -/* Loop round every PermMap input. */ - for( i = 0; i < nin; i++ ) { - -/* See what is fed to this input by the inverse transformation. A zero or - positive integer "p" value indicates that the input is fed from the - output with the corresponding index. A negative integer "p" value means - the input is fed a constant value stored at index (-p-1) in the - associated constants array. */ - p1 = PERMVAL( this_inp, i, this_outp_len ); - p2 = PERMVAL( that_inp, i, that_outp_len ); - -/* If the "p" values differ, we may have evidence that the PermMaps are - not equivalent. */ - if( p1 != p2 ) { - -/* If either "p" value is zero or positive, then the PermMaps are - definitely different since input "i" is fed from differing outputs, or - one is fed from an input and the other is fed a constant. */ - if( p1 >= 0 || p2 >= 0 ) { - result = 0; - break; - -/* If both "p" values are negative, then both inputs are fed a constant - value. The PermMaps differ if these constants differ. */ - } else if( this->constant[ -p1 - 1 ] != - that->constant[ -p2 - 1 ] ) { - result = 0; - break; - } - } - } - -/* If we have not yet discovered any evidence that the PermMaps differ, - go on to check each output in the same way that we have just checked the - inputs. */ - if( result ) { - for( i = 0; i < nout; i++ ) { - p1 = PERMVAL( this_outp, i, this_inp_len ); - p2 = PERMVAL( that_outp, i, that_inp_len ); - - if( p1 != p2 ) { - if( p1 >= 0 || p2 >= 0 ) { - result = 0; - break; - } else if( this->constant[ -p1 - 1 ] != - that->constant[ -p2 - 1 ] ) { - result = 0; - break; - } - } - } - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static double *GetConstants( AstPermMap *this, int *status ){ -/* -*+ -* Name: -* astGetConstants - -* Purpose: -* Return a pointer to the constants array of a PermMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "permmap.h" -* double *astGetConstants( AstPermMap *this ) - -* Class Membership: -* PermMap method - -* Description: -* This function returns a pointer to a dynamically allocated array -* holding a copy of the constants array supplied when the PermMap was -* created. -* -* Negative values in the arrays returned by the astGetInPerm and -* astGetOutPerm methods can be used as indices into the constants -* array returned by this method, if they are first negated and then -* decrement by one. Thus an inperm value of -3 refers to element 2 of -* the constants array. - -* Parameters: -* this -* Pointer to the PermMap. - -* Returned Value: -* A pointer to a dynamically allocated array holding a copy of the -* constants array. The pointer should be freed using astFree when it is -* no longer needed. NULL will be returned if the PermMap has no -* constants. - -* Notes: -* - A value of NULL will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - double *result; /* Pointer to the returned array */ - -/* Initialise the returned result. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Allocate memory and put a copy of the InPerm array in it. */ - result = (double *) astStore( NULL, this->constant, astSizeOf( this->constant ) ); - -/* Return the result. */ - return result; -} - -static int *GetInPerm( AstPermMap *this, int *status ){ -/* -* Name: -* GetInPerm - -* Purpose: -* Return a pointer to the InPerm array of a PermMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "permmap.h" -* int *astGetInPerm( AstPermMap *this, int *status ) - -* Class Membership: -* PermMap method - -* Description: -* This function returns a pointer to a dynamically allocated array -* holding a copy of the InPerm array supplied when thre PermMap was -* created. - -* Parameters: -* this -* Pointer to the PermMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array holding a copy of the -* InPerm array. The pointer should be freed using astFree when it is -* no longer needed. The number of elements in the array will be given -* by the value of the Nin attribute. The value in element "i" is the -* zero-based index of the output axis which provides values for input -* "i" when the inverse transformation is used. If the value in element -* "i" is less than zero, then input "i" is fed a constant value. This -* constant value is stored in the "constants" array (see astGetConstants) -* at an index equal to the absolute value of inperm[i], minus 1. Thus -* if element 3 of the array returned by this function has value -2, -* then input axis 3 is fed the value held in constants[1]. If the -* value of element "i" of the returned inperm array is greater than -* or equal to the number of output axes, then input "i" will be fed -* the constant AST__BAD. - -* Notes: -* - A value of NULL will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - int i; /* Loop count */ - int nin; /* Number of inputs. */ - int *result; /* Pointer to the returned array */ - -/* Initialise the returned result. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If no inperm array is stored, every input is derived from the - corresponding output. Therefore, return an array holding 0 to Nin-1. */ - if( !this->inperm ) { - nin = astGetNin( this ); - result = (int *) astMalloc( sizeof( int ) * (size_t) nin ); - if( astOK ) for( i = 0; i < nin; i++ ) result[ i ] = i; - -/* Otherwise, allocate memoy and put a copy of the InPerm array in it. */ - } else { - result = (int *) astStore( NULL, this->inperm, - sizeof( int ) * (size_t) astGetNin( this ) ); - } - -/* Return the result. */ - return result; -} - -static int *GetOutPerm( AstPermMap *this, int *status ){ -/* -* Name: -* GetOutPerm - -* Purpose: -* Return a pointer to the OutPerm array of a PermMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "permmap.h" -* int *astGetOutPerm( AstPermMap *this, int *status ) - -* Class Membership: -* PermMap method - -* Description: -* This function returns a pointer to a dynamically allocated array -* holding a copy of the OutPerm array supplied when thre PermMap was -* created. - -* Parameters: -* this -* Pointer to the PermMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array holding a copy of the -* OutPerm array. The pointer should be freed using astFree when it is -* no longer needed. The number of elements in the array will be given -* by the value of the Nout attribute. The value in element "i" is the -* zero-based index of the input axis which provides values for output -* "i" when the forward transformation is used. If the value in element -* "i" is less than zero, then output "i" is fed a constant value. This -* constant value is stored in the "constants" array (see astGetConstants) -* at an index equal to the absolute value of outperm[i], minus 1. Thus -* if element 3 of the array returned by this function has value -2, -* then output axis 3 is fed the value held in constants[1]. If the -* value of element "i" of the returned outperm array is greater than -* or equal to the number of input axes, then output "i" will be fed -* the constant AST__BAD. - -* Notes: -* - A value of NULL will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - int i; /* Loop count */ - int nout; /* Number of outputs. */ - int *result; /* Pointer to the returned array */ - -/* Initialise the returned result. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If no outperm array is stored, every output is derived from the - corresponding input. Therefore, return an array holding 0 to Nout-1. */ - if( !this->outperm ) { - nout = astGetNout( this ); - result = (int *) astMalloc( sizeof( int ) * (size_t) nout ); - if( astOK ) for( i = 0; i < nout; i++ ) result[ i ] = i; - -/* Otherwise, allocate memory and put a copy of the OutPerm array in it. */ - } else { - result = (int *) astStore( NULL, this->outperm, - sizeof( int ) * (size_t) astGetNout( this ) ); - } - -/* Return the result. */ - return result; -} - -void astInitPermMapVtab_( AstPermMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitPermMapVtab - -* Purpose: -* Initialise a virtual function table for a PermMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "permmap.h" -* void astInitPermMapVtab( AstPermMapVtab *vtab, const char *name ) - -* Class Membership: -* PermMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the PermMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAPermMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->GetConstants = GetConstants; - vtab->GetInPerm = GetInPerm; - vtab->GetOutPerm = GetOutPerm; - vtab->ClearPermSplit = ClearPermSplit; - vtab->GetPermSplit = GetPermSplit; - vtab->SetPermSplit = SetPermSplit; - vtab->TestPermSplit = TestPermSplit; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - mapping->MapSplit = MapSplit; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - mapping->Rate = Rate; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "PermMap", "Coordinate permutation" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* PermMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated PermMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated PermMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated PermMap which is to be merged with -* its neighbours. This should be a cloned copy of the PermMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* PermMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated PermMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *map; /* Pointer to Mapping */ - AstMapping *new; /* Pointer to replacement Mapping */ - AstPermMap *permmap; /* Pointer to PermMap */ - const char *class; /* Pointer to Mapping class string */ - double *con; /* Pointer to constants array */ - double constant; /* Constant value */ - int *inperm; /* Pointer to "inperm" permutation array */ - int *newperm; /* Pointer to new permutation array */ - int *outperm; /* Pointer to "outperm" permutation array */ - int *perm; /* Pointer to individual permutation array */ - int back; /* Considering inverse transformation? */ - int coord; /* Loop counter for coordinates */ - int icon; /* Loop counter for constants */ - int iend; /* Loop ending value */ - int imap1; /* Index of first Mapping */ - int imap2; /* Index of last Mapping */ - int imap; /* Loop counter for Mappings */ - int inc; /* Loop increment */ - int invert; /* Invert attribute value */ - int istart; /* Loop starting value */ - int maxperm; /* Max value (+1) allowed in permutation array */ - int ncon; /* Number of constants */ - int ncoord_in; /* Effective number of input coordinates */ - int ncoord_out; /* Effective number of output coordinates */ - int ngone; /* Number of Mappings eliminated */ - int nin; /* Total number of input coordinates */ - int ninsum; /* Accumulated count of input coordinates */ - int nout; /* Total number of output coordinates */ - int noutsum; /* Accumulated count of output coordinates */ - int nperm; /* Number of permutation array elements */ - int p; /* Permuted coordinate index */ - int result; /* Result value to return */ - int simpler; /* Mapping(s) simplified? */ - int store_in; /* Need to store "inperm" array contents? */ - int store_out; /* Need to store "outperm" array contents? */ - int unit; /* Replacement Mapping is a UnitMap? */ - -/* Initialise the returned result. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialisation. */ - con = NULL; - inperm = outperm = NULL; - ncon = 0; - permmap = NULL; - -/* In series. */ -/* ---------- */ -/* Handle the case where the Mappings are connected in series. */ - if ( series ) { - -/* Search adjacent lower-numbered Mappings until one is found which is - not a PermMap or a UnitMap. */ - imap1 = where; - while ( ( imap1 - 1 ) >= 0 ) { - class = astGetClass( ( *map_list )[ imap1 - 1 ] ); - if ( astOK ) { - if ( strcmp( class, "PermMap" ) && - strcmp( class, "UnitMap" ) ) break; - imap1--; - } - } - -/* Similarly search adjacent higher-numbered Mappings. */ - imap2 = where; - while ( ( imap2 + 1 ) < *nmap ) { - class = astGetClass( ( *map_list )[ imap2 + 1 ] ); - if ( astOK ) { - if ( strcmp( class, "PermMap" ) && - strcmp( class, "UnitMap" ) ) break; - imap2++; - } - } - -/* Obtain a pointer to the first Mapping found and determine if it is - to be applied with its Invert attribute set. */ - map = ( *map_list )[ imap1 ]; - invert = ( *invert_list )[ imap1 ]; - -/* Use this first Mapping (allowing for how its Invert attribute is - currently set) to determine the number of input coordinates that - the simplified Mapping should have. */ - if ( astGetInvert( map ) ) { - nin = invert ? astGetNin( map ) : astGetNout( map ); - } else { - nin = invert ? astGetNout( map ) : astGetNin( map ); - } - -/* Repeat this process for the last Mapping found, to determine the - number of output coordinates for the simplified Mapping. */ - map = ( *map_list )[ imap2 ]; - invert = ( *invert_list )[ imap2 ]; - if ( astGetInvert( map ) ) { - nout = invert ? astGetNout( map ) : astGetNin( map ); - } else { - nout = invert ? astGetNin( map ) : astGetNout( map ); - } - -/* Allocate memory to hold input and output permutation arrays for the - simplified Mapping, together with a list of constants. */ - inperm = astMalloc( sizeof( int ) * (size_t) nin ); - outperm = astMalloc( sizeof( int ) * (size_t) nout ); - con = astMalloc( sizeof( double ) * (size_t) ( nin + nout ) ); - if ( astOK ) { - -/* Initialise the number of constants. */ - ncon = 0; - -/* Loop twice, to calculate the forward and inverse (backward) - simplified permutation arrays in turn. */ - for ( back = 0; back <= 1; back++ ) { - -/* Obtain a pointer to the appropriate (forward/inverse) permutation - array that we wish to fill, and obtain the number of elements it - will contain. Initialise the array contents to represent a null - permutation.*/ - newperm = back ? outperm : inperm; - nperm = back ? nout : nin; - for ( coord = 0; coord < nperm; coord++ ) newperm[ coord ] = coord; - -/* Set up limits to scan through the list of Mappings being merged in - either the forward or reverse order, as required. */ - istart = back ? imap2 : imap1; - iend = back ? imap1 - 1 : imap2 + 1; - inc = back ? -1 : 1; - -/* Loop through the Mappings, obtaining a pointer to each, together - with the value to be used for its Invert attribute. Invert this - attribute value if calculating the overall inverse (backward) - permutation array. */ - for ( imap = istart; imap != iend; imap += inc ) { - map = ( *map_list )[ imap ]; - invert = ( *invert_list )[ imap ]; - if ( back ) invert = !invert; - -/* Determine the class to which the Mapping belongs. */ - class = astGetClass( map ); - if ( astOK ) { - -/* If it is a PermMap, obtain a pointer to the PermMap structure and - hence to the relevant permutation array. Otherwise (if it is a - UnitMap), leave the permutation array pointer NULL, which indicates - a null permutation. */ - perm = NULL; - maxperm = astGetNout( map ); - if ( !strcmp( class, "PermMap" ) ) { - permmap = (AstPermMap *) map; - perm = invert ? permmap->outperm : permmap->inperm; - } - -/* Obtain the effective number of output coordinates associated with - this individual Mapping (when transforming points in the direction - to which this permutation array applies). */ - if ( astGetInvert( map ) ) { - ncoord_out = invert ? astGetNout( map ) : - astGetNin( map ); - } else { - ncoord_out = invert ? astGetNin( map ) : - astGetNout( map ); - } - -/* Loop through the elements of the simplified permutation array to - accumulate the effects of the current individual Mapping. */ - if ( astOK ) { - for ( coord = 0; coord < nperm; coord++ ) { - -/* Find the effective input coordinate for the current Mapping from - the permutation accumulated so far, and check this is not - negative. If it is, the accumulated permutation refers to a "bad" - coordinate value or a constant, so the current Mapping makes no - further difference. */ - p = newperm[ coord ]; - if ( p >= 0 ) { - -/* Otherwise, obtain the permuting effect of the current Mapping, - allowing for the possibility of its permutation array being NULL - (implying a null permutation). */ - p = PERMVAL( perm, p, maxperm ); - -/* If the permuted index refers to a valid (effective) output - coordinate for the individual Mapping, then accumulate its effect - in the overall permutation array. */ - if ( ( p >= 0 ) && ( p < ncoord_out ) ) { - newperm[ coord ] = p; - -/* Otherwise (this can only occur if the individual Mapping is a - PermMap), determine whether it refers to a "bad" coordinate value - or a constant. If the former, extract the constant's value, - otherwise use a constant value of AST__BAD. */ - } else { - if ( ( p < 0 ) && permmap->constant ) { - constant = permmap->constant[ (-p) - 1 ]; - } else { - constant = AST__BAD; - } - -/* If the result (however reached) is a coordinate value of AST__BAD, - then mark the accumulated permutation array with a value of -1 to - indicate this. */ - if ( constant == AST__BAD ) { - newperm[ coord ] = -1; - -/* Otherwise, search the array of constants to see if this one has - been encountered before. If not, append the new constant to the - list. */ - } else { - for ( icon = 0; icon < ncon; icon++ ) { - if ( con[ icon ] == constant ) break; - } - if ( icon == ncon ) con[ ncon++ ] = constant; - -/* Store a (negative) reference to the new constant in the accumulated - permutation array (note we use an extra offset of -1 here in - forming these references, so that the value -1 itself can be used - to indicate a "bad" coordinate value without an entry in the - constants array). */ - newperm[ coord ] = (-icon) - 2; - } - } - } - } - } - } - } - } - } - -/* In parallel. */ -/* ------------ */ -/* Handle the case where the Mappings are connected in parallel. */ - } else { - -/* Obtain a pointer to the nominated Mapping (which is a PermMap) and - determine if it is to be applied with its Invert attribute set. */ - map = ( *map_list )[ where ]; - invert = ( *invert_list )[ where ]; - -/* Use this nominated Mapping to initialise the counts of input and - output coordinates for the simplified Mapping (allowing for how its - Invert attribute is currently set). */ - if ( astGetInvert( map ) ) { - nin = invert ? astGetNin( map ) : astGetNout( map ); - nout = invert ? astGetNout( map ) : astGetNin( map ); - } else { - nin = invert ? astGetNout( map ) : astGetNin( map ); - nout = invert ? astGetNin( map ) : astGetNout( map ); - } - -/* Search adjacent lower-numbered Mappings until one is found which is - not a PermMap or a UnitMap. */ - imap1 = where; - while ( astOK && ( ( imap1 - 1 ) >= 0 ) ) { - map = ( *map_list )[ imap1 - 1 ]; - class = astGetClass( map ); - if ( astOK ) { - if ( strcmp( class, "PermMap" ) && - strcmp( class, "UnitMap" ) ) break; - -/* For each Mapping found, obtain the effective numbers of input and - output coordinates (allowing for all the direction flags, as above) - and accumulate the total count of input and output coordinates for - the overall simplified Mapping. */ - invert = ( *invert_list )[ imap1 - 1 ]; - if ( astGetInvert( map ) ) { - nin += ( invert ? astGetNin( map ) : astGetNout( map ) ); - nout += ( invert ? astGetNout( map ) : astGetNin( map ) ); - } else { - nin += ( invert ? astGetNout( map ) : astGetNin( map ) ); - nout += ( invert ? astGetNin( map ) : astGetNout( map ) ); - } - imap1--; - } - } - -/* Similarly search higher-numbered Mappings and accumulate their - coordinate counts. */ - imap2 = where; - while ( astOK && ( ( imap2 + 1 ) < *nmap ) ) { - map = ( *map_list )[ imap2 + 1 ]; - class = astGetClass( map ); - if ( astOK ) { - if ( strcmp( class, "PermMap" ) && - strcmp( class, "UnitMap" ) ) break; - invert = ( *invert_list )[ imap2 + 1 ]; - if ( astGetInvert( map ) ) { - nin += ( invert ? astGetNin( map ) : astGetNout( map ) ); - nout += ( invert ? astGetNout( map ) : astGetNin( map ) ); - } else { - nin += ( invert ? astGetNout( map ) : astGetNin( map ) ); - nout += ( invert ? astGetNin( map ) : astGetNout( map ) ); - } - imap2++; - } - } - -/* Allocate memory to hold input and output permutation arrays for the - simplified Mapping, together with a list of constants. */ - inperm = astMalloc( sizeof( int ) * (size_t) nin ); - outperm = astMalloc( sizeof( int ) * (size_t) nout ); - con = astMalloc( sizeof( double ) * (size_t) ( nin + nout ) ); - if ( astOK ) { - -/* Initialise the number of constants. */ - ncon = 0; - -/* Loop twice, to calculate the forward and inverse (backward) - simplified permutation arrays in turn. */ - for ( back = 0; back <= 1; back++ ) { - -/* Obtain a pointer to the appropriate (forward/inverse) permutation - array that we wish to fill, and obtain the number of elements it - will contain. */ - newperm = back ? outperm : inperm; - nperm = back ? nout : nin; - -/* Initialise counts of (effective) input and output coordinates. */ - ninsum = noutsum = 0; - -/* Loop through the Mappings, obtaining a pointer to each, together - with the value to be used for its Invert attribute. Invert this - attribute value if calculating the overall inverse (backward) - permutation array. */ - for ( imap = imap1; imap <= imap2; imap++ ) { - map = ( *map_list )[ imap ]; - invert = ( *invert_list )[ imap ]; - if ( back ) invert = !invert; - -/* Determine the class to which the Mapping belongs. */ - class = astGetClass( map ); - if ( astOK ) { - -/* If it is a PermMap, obtain a pointer to the PermMap structure and - hence to the relevant permutation array. Otherwise (if it is a - UnitMap), leave the permutation array pointer NULL, which indicates - a null permutation. */ - perm = NULL; - maxperm = astGetNout( map ); - if ( !strcmp( class, "PermMap" ) ) { - permmap = (AstPermMap *) map; - perm = invert ? permmap->outperm : permmap->inperm; - } - -/* Obtain the effective number of input and output coordinates - associated with this individual Mapping (when transforming points - in the direction to which this permutation array applies). */ - if ( astGetInvert( map ) ) { - ncoord_in = invert ? astGetNin( map ) : - astGetNout( map ); - ncoord_out = invert ? astGetNout( map ) : - astGetNin( map ); - } else { - ncoord_in = invert ? astGetNout( map ) : - astGetNin( map ); - ncoord_out = invert ? astGetNin( map ) : - astGetNout( map ); - } - -/* Loop through the (effective) input coordinates of the current - individual Mapping to accumulate their effect on the overall - permutation array. */ - if ( astOK ) { - for ( coord = 0; coord < ncoord_in; coord++ ) { - -/* Obtain the permuting effect of the current Mapping, allowing for - the possibility of its permutation array being NULL. */ - p = PERMVAL( perm, coord, maxperm ); - -/* If the permuted index refers to a valid (effective) output - coordinate for the individual Mapping, then accumulate its effect - on the overall permutation array, allowing for the coordinate - numbering offset produced by any Mappings already accumulated. */ - if ( ( p >= 0 ) && ( p < ncoord_out ) ) { - newperm[ coord + ninsum ] = p + noutsum; - -/* Otherwise (this can only occur if the individual Mapping is a - PermMap), determine whether it refers to a "bad" coordinate value - or a constant. If the former, extract the constant's value, - otherwise use a constant value of AST__BAD. */ - } else { - if ( ( p < 0 ) && permmap->constant ) { - constant = permmap->constant[ (-p) - 1 ]; - } else { - constant = AST__BAD; - } - -/* If the result (however reached) is a coordinate value of AST__BAD, - then mark the accumulated permutation array with a value of -1 to - indicate this. */ - if ( constant == AST__BAD ) { - newperm[ coord + ninsum ] = -1; - -/* Otherwise, search the array of constants to see if this one has - been encountered before. If not, append the new constant to the - list. */ - } else { - int icon; - for ( icon = 0; icon < ncon; icon++ ) { - if ( con[ icon ] == constant ) break; - } - if ( icon == ncon ) con[ ncon++ ] = constant; - -/* Store a (negative) reference to the new constant in the accumulated - permutation array (note we use an extra offset of -1 here in - forming these references, so that the value -1 itself can be used - to indicate a "bad" coordinate value without an entry in the - constants array). */ - newperm[ coord + ninsum ] = (-icon) - 2; - } - } - } - } - -/* Accumulate the counts of (effective) input and output coordinates - for each individual Mapping. */ - ninsum += ncoord_in; - noutsum += ncoord_out; - } - } - } - } - } - -/* Inspect each element of the accumulated "inperm" array to determine - if it needs to be stored by the replacement PermMap. */ - if ( astOK ) { - store_in = 0; - for ( coord = 0; coord < nin; coord++ ) { - -/* It need not be stored if it produces a null permutation, where each - input coordinate takes its value from the corresponding output - coordinate (or where a "bad" value results if there is no - corresponding output coordinate). Note any deviation from this - pattern. */ - if ( coord < nout ) { - store_in = store_in || ( inperm[ coord ] != coord ); - } else { - store_in = store_in || ( inperm[ coord ] != -1 ); - } - -/* Also convert permutation array values of -1 into non-existent - positive coordinate indices (indicating "bad" coordinate values) - and adjust (negative) references to constants by +1 to eliminate - the extra offset of -1 used temporarily above. This returns the - permutation array values to normal. */ - if ( inperm[ coord ] < 0 ) { - if ( !++inperm[ coord ] ) inperm[ coord ] = nout; - } - } - -/* Similarly inspect the "outperm" array and return its values to - normal. */ - store_out = 0; - for ( coord = 0; coord < nout; coord++ ) { - if ( coord < nin ) { - store_out = store_out || ( outperm[ coord ] != coord ); - } else { - store_out = store_out || ( outperm[ coord ] != -1 ); - } - if ( outperm[ coord ] < 0 ) { - if ( !++outperm[ coord ] ) outperm[ coord ] = nin; - } - } - -/* Determine how many adjacent Mappings can be eliminated by merging - them. */ - ngone = imap2 - imap1; - -/* Determine if the resultant PermMap can be simplified still further - to become a UnitMap (a null Mapping). This will be the case if both - the forward and inverse coordinate permutations it produces are - null, and if the number of input and output coordinates are - equal. */ - unit = !store_in && !store_out && ( nin == nout ); - -/* We must now determine whether we have actually produced any - simplification. This is important, because if we indicate a - simplification when none has, in fact, been achieved, then this - function may get called over and over again without end. */ - -/* Simplification is clearly evident if (a) Mappings have been - eliminated ("ngone" is non-zero), or (b) a PermMap has been reduced - to a UnitMap, or (c) where there was originally only one PermMap to - simplify, its invert flag was set (the replacement Mapping will - always have this flag cleared). */ - simpler = ngone || unit || ( *invert_list )[ where ]; - -/* If the above tests do not indicate simplification, then we can only - be considering the case where there was a single initial - PermMap. In this case we have also achieved simplification if - either the "inperm" or "outperm" array no longer needs storing - whereas previously it was stored. */ - permmap = (AstPermMap *) ( *map_list )[ where ]; - if ( !simpler ) { - simpler = ( !store_in && !NullPerm( permmap, 0, status ) ) || - ( !store_out && !NullPerm( permmap, 1, status ) ); - } - -/* If we still haven't detected any simplification, then compare the - original and replacement "inperm" arrays (if present) in detail for - equality. We declare simplification to have occurred if they - differ. */ - if ( !simpler && store_in ) { - for ( coord = 0; coord < nin; coord++ ) { - simpler = ( inperm[ coord ] != permmap->inperm[ coord ] ); - if ( simpler ) break; - } - } - -/* Similarly, if necessary, compare the original and replacement - "outperm" arrays. */ - if ( !simpler && store_out ) { - for ( coord = 0; coord < nout; coord++ ) { - simpler = ( outperm[ coord ] != permmap->outperm[ coord ] ); - if ( simpler ) break; - } - } - -/* Do nothing more unless there has been some simplification. */ - if ( simpler ) { - -/* If the PermMaps (and UnitMaps) can be replaced by a UnitMap, then - create the replacement. */ - if ( unit ) { - new = (AstMapping *) astUnitMap( nin, "", status ); - -/* Otherwise, create a replacement PermMap, setting as many arguments - to NULL in the constructor function as can be achieved without - affecting the result. */ - } else { - new = (AstMapping *) astPermMap( nin, store_in ? inperm : NULL, - nout, store_out ? outperm : NULL, - ncon ? con : NULL, "", status ); - } - -/* Annul the pointers to all the Mappings that are being replaced. */ - if ( astOK ) { - for ( imap = imap1; imap <= imap2; imap++ ) { - ( *map_list )[ imap ] = astAnnul( ( *map_list )[ imap ] ); - } - -/* Insert the new pointer and the associated invert flag. */ - ( *map_list )[ imap1 ] = new; - ( *invert_list )[ imap1 ] = 0; - -/* Loop to close the resulting gap by moving subsequent elements down - in the arrays. */ - for ( imap = imap2 + 1; imap < *nmap; imap++ ) { - ( *map_list )[ imap - ngone ] = ( *map_list )[ imap ]; - ( *invert_list )[ imap - ngone ] = ( *invert_list )[ imap ]; - } - -/* Clear the vacated elements at the end. */ - for ( imap = *nmap - ngone; imap < *nmap; imap++ ) { - ( *map_list )[ imap ] = NULL; - ( *invert_list )[ imap ] = 0; - } - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap ) -= ngone; - result = imap1; - } - } - } - -/* Free the workspace arrays. */ - inperm = astFree( inperm ); - outperm = astFree( outperm ); - con = astFree( con ); - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "permmap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* PermMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing PermMap. This is only possible if the specified inputs -* correspond to some subset of the PermMap outputs. That is, there -* must exist a subset of the PermMap outputs for which each output -* depends only on the selected PermMap inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied PermMap, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the PermMap to be split (the PermMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied PermMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied PermMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied PermMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstPermMap *this; /* Pointer to PermMap structure */ - double *con; /* Pointer to constants array */ - int *inp; /* Input perm array to use with supplied PermMap */ - int *inpm; /* Input perm array to use with new PermMap */ - int *outp; /* Output perm array to use with supplied PermMap */ - int *outpm; /* Output perm array to use with new PermMap */ - int *result; /* Pointer to returned array */ - int i; /* Loop count */ - int iin; /* Mapping input index */ - int iout; /* Output index */ - int j; /* Loop count */ - int nout; /* No. of outputs in the new PermMap */ - int npin; /* No. of inputs in the supplied Mapping */ - int npout; /* No. of outputs in the supplied Mapping */ - int ok; /* Are input indices OK? */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - - -/* Get a pointer to the PermMap structure. */ - this = (AstPermMap *) this_map; - -/* Get the number of inputs and outputs in the supplied PermMap. */ - npin = astGetNin( this ); - npout = astGetNout( this ); - -/* Check all input axis indices are valid. */ - ok = 1; - for( i = 0; i < nin; i++ ) { - if( in[ i ] < 0 || in[ i ] >= npin ) { - ok = 0; - break; - } - } - -/* Get pointers to the input and output permutation arrays and constant - array taking account of whether the PermMap has been inverted. */ - if( astGetInvert( this ) ) { - outp = this->inperm; - inp = this->outperm; - } else { - outp = this->outperm; - inp = this->inperm; - } - con = this->constant; - -/* The "normal" method, as described in the prologue. */ - if( astGetPermSplit( this ) == 0 ) { - -/* Allocate memory for the returned array of output indices. */ - result = astMalloc( sizeof( int )*(size_t) npout ); - -/* Allocate memory for the inperm and outperm arrays of the returned - PermMap. Make these the largest they could possible need to be. */ - inpm = astMalloc( sizeof( int )*(size_t) npin ); - outpm = astMalloc( sizeof( int )*(size_t) npout ); - if( astOK ) { - -/* Initialise number of outputs in returned PermMap. */ - nout = 0; - -/* Loop round each output of the supplied PermMap. */ - for( iout = 0; iout < npout; iout++ ) { - -/* Is this output fed by one of the selected inputs? If so store the input - index of the returned Mapping, which feeds this output and add this - output index to the list of returned outputs. */ - iin = PERMVAL( outp, iout, npin ); - if( iin >= 0 && iin < npin ) { - for( i = 0; i < nin; i++ ) { - if( in[ i ] == iin ) { - outpm[ nout ] = i; - result[ nout ] = iout; - nout++; - break; - } - } - } - } - -/* We now need to set up the inperm array for the returned PermMap. This - ensures that the inverse transformation in the returned Mapping provides - values for the selected inputs. Loop round all the selected inputs. */ - for( i = 0; i < nin; i++ ) { - iin = in[ i ]; - -/* Is this input constant or fed by one of the selected outputs? If so store - the output or constant index in the returned Mapping which feeds this - input. */ - ok = 0; - iout = PERMVAL( inp, iin, npout ); - if( iout >= 0 && iout < npout ) { - for( j = 0; j < nout; j++ ) { - if( result[ j ] == iout ) { - ok = 1; - inpm[ i ] = j; - break; - } - } - } else { - inpm[ i ] = iout; - ok = 1; - } - -/* If this input is fed by an output which has not been selected, then we - cannot produce the required Mapping. */ - if( !ok ) break; - } - -/* If possible produce the returned PermMap. Otherwise, free the returned - array. */ - if( ok && nout > 0 ) { - *map = (AstMapping *) astPermMap( nin, inpm, nout, outpm, con, "", status ); - } else { - result = astFree( result ); - } - -/* Free other resources. */ - inpm = astFree( inpm ); - outpm = astFree( outpm ); - } - -/* The "alternative" method. Only the inperm array is used - the outperm - array is assumed to be an exact inverse of the inperm array. In other - words, only the inverse transformation is used, and the forward - transformation is assumed to be the exact opposite. */ - } else { - -/* The returned array of output indices holds the "inperm" values for the - selected inputs. */ - result = astMalloc( sizeof( int )*(size_t) nin ); - if( astOK ) { - for( i = 0; i < nin; i++ ) { - result[ i ] = PERMVAL( inp, in[ i ], npout ); - -/* Check the input is not fed by a constant. */ - if( result[ i ] < 0 ) { - result = astFree( result ); - break; - -/* Check that the the output has not already been used. */ - } else { - for( j = 0; j < i; j++ ) { - if( result[ j ] == result[ i ] ) { - result = astFree( result ); - break; - } - } - } - } - -/* If the split was possible, the returned Mapping is a UnitMap. */ - if( result ) *map = (AstMapping *) astUnitMap( nin, " ", status ); - } - } - -/* If the returned Mapping has no outputs, do not return it. */ - if( !result && *map ) { - *map = astAnnul( *map ); - } - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static int NullPerm( AstPermMap *this, int forward, int *status ){ -/* -* Name: -* NullPerm - -* Purpose: -* See if a PermMap transformation represents a null axis permutation. - -* Type: -* Private function. - -* Synopsis: -* #include "permmap.h" -* int NullPerm( AstPermMap *this, int forward, int *status ) - -* Class Membership: -* PermMap method - -* Description: -* This function returns a logical value indicating if the specified -* transformation of the supplied PermMap is a null (i.e. unit) -* transformation. - -* Parameters: -* this -* Pointer to the PermMap. -* forward -* Check the forward transformation? Otherise, check the inverse -* transformation. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the specified transformation is a null axis permutation. -* Zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - int i; /* Coordinate index */ - int nin; /* Number of Mapping inputs */ - int nout; /* Number of Mapping outputs */ - int result; /* Returned value */ - -/* Initialise the returned result. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* First check the forward transformation, given by the outperm array. */ - if( forward ) { - -/* If no outperm array is stored, every output is derived from the - corresponding input. Therefore, return 1 indicating a null axis - permutation. */ - if( !this->outperm ) { - result = 1; - -/* Otherwise, check that every element in the outperm array indicates - that the output is derived from the input with the saem index. */ - } else { - result = 1; - nout = astGetNout( this ); - for( i = 0; i < nout; i++ ) { - if( this->outperm[ i ] != i ) { - result = 0; - break; - } - } - } - -/* Now check the inverse transformation, given by the inperm array. */ - } else { - -/* If no inperm array is stored, every input is derived from the - corresponding output. Therefore, return 1 indicating a null axis - permutation. */ - if( !this->inperm ) { - result = 1; - -/* Otherwise, check that every element in the inperm array indicates - that the input is derived from the output with the same index. */ - } else { - result = 1; - nin = astGetNin( this ); - for( i = 0; i < nin; i++ ) { - if( this->inperm[ i ] != i ) { - result = 0; - break; - } - } - } - } - -/* If an error has occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "permmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* PermMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -*/ - -/* Local Variables: */ - AstPermMap *map; - int *outperm; - int result; - -/* Check inherited status */ - if( !astOK ) return AST__BAD; - -/* Get a pointer to the PermMap structure. */ - map = (AstPermMap *) this; - -/* Obtain a pointer to the appropriate output coordinate permutation array, - according to whether the PermMap has been inverted. If the specified - output is derived from the specified input then the rate is unity. - Otherwise it is zero. */ - outperm = astGetInvert( this ) ? map->inperm : map->outperm; - if( outperm ) { - result = ( ax2 == outperm[ ax1 ] ) ? 1.0 : 0.0; - } else { - result = ( ax2 == ax1 ) ? 1.0 : 0.0; - } - - return result; -} - -static AstPointSet *Transform( AstMapping *map, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a PermMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "permmap.h" -* AstPointSet *Transform( AstMapping *map, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* PermMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a PermMap and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required coordinate -* permutation. - -* Parameters: -* map -* Pointer to the PermMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the PermMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPermMap *this; /* Pointer to PermMap to be applied */ - AstPointSet *result; /* Pointer to output PointSet */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double constant; /* Constant coordinate value */ - int *perm; /* Pointer to permutation array */ - int coord; /* Loop counter for coordinates */ - int maxperm; /* Max value in permutation array */ - int ncoord_in; /* Number of coordinates per input point */ - int ncoord_out; /* Number of coordinates per output point */ - int npoint; /* Number of points */ - int p; /* Permuted coordinate index */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the PermMap. */ - this = (AstPermMap *) map; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( map, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - permutation needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - and output PointSets and obtain pointers for accessing the input and output - coordinate values. */ - ncoord_in = astGetNcoord( in ); - ncoord_out = astGetNcoord( result ); - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Obtain a pointer to the appropriate coordinate permutation array, according - to the direction of transformation required and whether the PermMap has - been inverted. Also get the maximum allowed value in the permutation array. */ - if ( ( astGetInvert( this ) != 0 ) == ( forward != 0 ) ) { - perm = this->inperm; - maxperm = ncoord_out; - } else { - perm = this->outperm; - maxperm = ncoord_in; - } - -/* Perform coordinate permutation. */ -/* ------------------------------- */ - if ( astOK ) { - -/* Loop to generate values for each output coordinate. */ - for ( coord = 0; coord < ncoord_out; coord++ ) { - -/* If the permutation array is not NULL, use it to look up which input - coordinate to use. Otherwise, use the corresponding input coordinate. */ - p = PERMVAL( perm, coord, maxperm ); - -/* If a valid input coordinate has been identified, simply copy the required - coordinate values from input to output. */ - if ( ( p >= 0 ) && ( p < ncoord_in ) ) { - (void) memcpy( ptr_out[ coord ], ptr_in[ p ], - sizeof( double ) * (size_t) npoint ); - -/* If the permuted coordinate index is negative, use it to index the "constant" - array to obtain a constant value to assign. If this array is NULL, use - AST__BAD as the constant. */ - } else if ( p < 0 ) { - constant = this->constant ? this->constant[ (-p) - 1 ] : AST__BAD; - -/* Assign the constant value to the output coordinate for all points. */ - for ( point = 0; point < npoint; point++ ) { - ptr_out[ coord ][ point ] = constant; - } - -/* In all other cases, simply assign the value AST__BAD to the output - coordinate for all points. */ - } else { - for ( point = 0; point < npoint; point++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* -*att+ -* Name: -* PermSplit - -* Purpose: -* The method to use when splitting a PermMap using astMapSplit. - -* Type: -* Protected attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute controls the behaviour of the implementation of the -* astMapSplit method provided by the PermMap class. If set to zero (the -* default), astMapSplit will split PermMaps according to the public -* documentation for the method. If set non-zero, the forward transformation -* of the PermMap defined by the "outperm" array will be ignored. -* Instead, the forward transformation is assumed to be the exact -* inverse of the inverse transformation. The Mapping returned will -* then be a UnitMap with Nin equal to the number of picked inputs, -* and the returned array of output indices will hold the "inperm" -* values for the picked inputs. Note, if any of these "inperm" values -* are negative (indicating that the inverse transformation supplies a -* constant value for the input), or if more than one of the selected -* inputs are fed (by the inverse transformation) by the same output, -* then the PermMap cannot be split. -* -* Note, unlike most Mapping attributes, the value of this attribute -* may be changed at any time. This is because it does not change the -* nature of either the forward or inverse transformation of the Mapping. - -* Applicability: -* PermMap -* All PermMaps have this attribute. -*att- -*/ -astMAKE_CLEAR(PermMap,PermSplit,permsplit,-INT_MAX) -astMAKE_GET(PermMap,PermSplit,int,0,( this->permsplit != -INT_MAX ? - this->permsplit : 0 )) -astMAKE_SET(PermMap,PermSplit,int,permsplit,( value != 0 )) -astMAKE_TEST(PermMap,PermSplit,( this->permsplit != -INT_MAX )) - - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for PermMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for PermMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstPermMap *in; /* Pointer to input PermMap */ - AstPermMap *out; /* Pointer to output PermMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output PermMaps. */ - in = (AstPermMap *) objin; - out = (AstPermMap *) objout; - -/* For safety, first clear any references to the input memory from - the output PermMap. */ - out->inperm = NULL; - out->outperm = NULL; - out->constant = NULL; - -/* For each input array which is not NULL, make a copy in allocated memory, - storing a pointer to it in the output PermMap structure. */ - if ( in->inperm ) out->inperm = astStore( NULL, in->inperm, - astSizeOf( in->inperm ) ); - if ( in->outperm ) out->outperm = astStore( NULL, in->outperm, - astSizeOf( in->outperm ) ); - if ( in->constant ) out->constant = astStore( NULL, in->constant, - astSizeOf( in->constant ) ); - -/* If an error occurred, clean up by freeing all memory allocated above. */ - if ( !astOK ) { - out->inperm = astFree( out->inperm ); - out->outperm = astFree( out->outperm ); - out->constant = astFree( out->constant ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for PermMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for PermMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstPermMap *this; /* Pointer to PermMap */ - -/* Obtain a pointer to the PermMap structure. */ - this = (AstPermMap *) obj; - -/* Free all memory allocated by the PermMap. */ - this->inperm = astFree( this->inperm ); - this->outperm = astFree( this->outperm ); - this->constant = astFree( this->constant ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for PermMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the PermMap class to an output Channel. - -* Parameters: -* this -* Pointer to the PermMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define COMMENT_LEN 150 /* Maximum length of a comment string */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstPermMap *this; /* Pointer to the PermMap structure */ - char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment strings */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword strings */ - int coord; /* Loop counter for coordinates */ - int iconst; /* Loop counter for constants */ - int invert; /* Invert attribute value */ - int ival; /* Integer value */ - int nconst; /* Number of constants */ - int nin; /* Number of input coordinates */ - int nout; /* Number of output coordinates */ - int set; /* Value is "set"? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PermMap structure. */ - this = (AstPermMap *) this_object; - -/* Determine if the PermMap is inverted and obtain the "true" number - of input and output coordinates by un-doing the effects of any - inversion. */ - invert = astGetInvert( this ); - nin = !invert ? astGetNin( this ) : astGetNout( this ); - nout = !invert ? astGetNout( this ) : astGetNin( this ); - -/* Initialise the count of constants in use. */ - nconst = 0; - -/* Write out values representing the instance variables for the - PermMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* PermSplit */ -/* --------- */ - set = TestPermSplit( this, status ); - ival = set ? GetPermSplit( this, status ) : astGetPermSplit( this ); - astWriteInt( channel, "pmsplt", set, 0, ival, - ival ? "Use alternative astMapSplit implementation" : - "Use normal astMapSplit implementation" ); - -/* "outperm" array contents. */ -/* ------------------------- */ -/* Write the boolean "OutCpy" value to indicate if output coordinates - are obtained simply by copying corresponding input - coordinates. This will be the case if "this->outperm" is NULL. */ - ival = this->outperm ? 0 : 1; - set = ( ival != 0 ); - astWriteInt( channel, "OutCpy", set, 0, ival, - ival ? "Output coordinates = input coordinates" : - "Output coordinates specified individually" ); - -/* If output coordinates are specified individually, create a keyword - for each element of the "outperm" array. */ - if ( this->outperm ) { - for ( coord = 0; coord < nout; coord++ ) { - (void) sprintf( key, "Out%d", coord + 1 ); - -/* Obtain the array value. If it refers to a coordinate that does not - exist, change the value to zero (indicating a "bad" value for this - coordinate). Create an appropriate comment. */ - ival = this->outperm[ coord ]; - if ( ival >= nin ) { - ival = 0; - (void) sprintf( comment, "Output coordinate %d is \"bad\"", - coord + 1 ); - -/* If the coordinate reference is valid, convert to 1-based coordinate - numbering and create an appropriate comment. */ - } else if ( ival >= 0 ) { - ival++; - (void) sprintf( comment, - "Output coordinate %d = input coordinate %d", - coord + 1, ival ); - -/* If the reference is to a constant, create an appropriate comment - (which depends on whether there are any constants). */ - } else { - if ( this->constant ) { - (void) sprintf( comment, - "Output coordinate %d = constant no. %d", - coord + 1, -ival ); - } else { - (void) sprintf( comment, "Output coordinate %d is \"bad\"", - coord + 1 ); - } - -/* Update the top constant number referenced. */ - if ( nconst < -ival ) nconst = -ival; - } - -/* Write out the array value with accompanying comment. */ - astWriteInt( channel, key, 1, 1, ival, comment ); - } - } - -/* "inperm" array contents. */ -/* ------------------------ */ -/* Write the boolean "InCpy" value to indicate if input coordinates - are obtained simply by copying corresponding output - coordinates. This will be the case if "this->inperm" is NULL. */ - ival = this->inperm ? 0 : 1; - set = ( ival != 0 ); - astWriteInt( channel, "InCpy", set, 0, ival, - ival ? "Input coordinates = output coordinates" : - "Input coordinates specified individually" ); - -/* If input coordinates are specified individually, create a keyword - for each element of the "inperm" array. */ - if ( this->inperm ) { - for ( coord = 0; coord < nin; coord++ ) { - (void) sprintf( key, "In%d", coord + 1 ); - -/* Obtain the array value. If it refers to a coordinate that does not - exist, change the value to zero (indicating a "bad" value for this - coordinate). Create an appropriate comment. */ - ival = this->inperm[ coord ]; - if ( ival >= nout ) { - ival = 0; - (void) sprintf( comment, "Input coordinate %d is \"bad\"", - coord + 1 ); - -/* If the coordinate reference is valid, convert to 1-based coordinate - numbering and create an appropriate comment. */ - } else if ( ival >= 0 ) { - ival++; - (void) sprintf( comment, - "Input coordinate %d = output coordinate %d", - coord + 1, ival ); - -/* If the reference is to a constant, create an appropriate comment - (which depends on whether there are any constants). */ - } else { - if ( this->constant ) { - (void) sprintf( comment, - "Input coordinate %d = constant no. %d", - coord + 1, -ival ); - } else { - (void) sprintf( comment, "Input coordinate %d is \"bad\"", - coord + 1 ); - } - -/* Update the top constant number referenced. */ - if ( nconst < -ival ) nconst = -ival; - } - -/* Write out the array value with accompanying comment. */ - astWriteInt( channel, key, 1, 1, ival, comment ); - } - } - -/* Number of constants. */ -/* -------------------- */ -/* First check if there are any constants, then write out how many - there are. */ - if ( !this->constant ) nconst = 0; - set = ( nconst != 0 ); - astWriteInt( channel, "Nconst", set, 0, nconst, "Number of constants" ); - -/* Constants. */ -/* ---------- */ -/* Loop to create a keyword and comment for each constant. */ - for ( iconst = 0; iconst < nconst; iconst++ ) { - (void) sprintf( key, "Con%d", iconst + 1 ); - (void) sprintf( comment, "Constant number %d", iconst + 1 ); - -/* Write out each constant value and comment. */ - set = ( this->constant[ iconst ] != AST__BAD ); - if ( set ) { - astWriteDouble( channel, key, 1, 1, this->constant[ iconst ], - comment ); - } else { - astWriteString( channel, key, 0, 1, "", comment ); - } - } - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPermMap and astCheckPermMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(PermMap,Mapping) -astMAKE_CHECK(PermMap) - -AstPermMap *astPermMap_( int nin, const int inperm[], int nout, - const int outperm[], const double constant[], - const char *options, int *status, ...) { -/* -*++ -* Name: -c astPermMap -f AST_PERMMAP - -* Purpose: -* Create a PermMap. - -* Type: -* Public function. - -* Synopsis: -c #include "permmap.h" -c AstPermMap *astPermMap( int nin, const int inperm[], int nout, -c const int outperm[], double constant[], -c const char *options, ... ) -f RESULT = AST_PERMMAP( NIN, INPERM, NOUT, OUTPERM, CONSTANT, OPTIONS, -f STATUS ) - -* Class Membership: -* PermMap constructor. - -* Description: -* This function creates a new PermMap and optionally initialises its -* attributes. -* -* A PermMap is a Mapping which permutes the order of coordinates, -* and possibly also changes the number of coordinates, between its -* input and output. -* -* In addition to permuting the coordinate order, a PermMap may -* also assign constant values to coordinates. This is useful when -* the number of coordinates is being increased as it allows fixed -* values to be assigned to any new ones. - -* Parameters: -c nin -f NIN = INTEGER (Given) -* The number of input coordinates. -c inperm -f INPERM = INTEGER( NIN ) (Given) -c An optional array with "nin" elements which, for each input -f An array which, for each input -* coordinate, should contain the number of the output -* coordinate whose value is to be used (note that this array -* therefore defines the inverse coordinate transformation). -* Coordinates are numbered starting from 1. -* -* For details of additional special values that may be used in -c this array, see the description of the "constant" parameter. -f this array, see the description of the CONSTANT argument. -c -c If a NULL pointer is supplied instead of an array, each input -c coordinate will obtain its value from the corresponding -c output coordinate (or will be assigned the value AST__BAD if -c there is no corresponding output coordinate). -c nout -f NOUT = INTEGER (Given) -* The number of output coordinates. -c outperm -f OUTPERM = INTEGER( NOUT ) (Given) -c An optional array with "nout" elements which, for each output -f An array which, for each output -* coordinate, should contain the number of the input coordinate -* whose value is to be used (note that this array therefore -* defines the forward coordinate transformation). Coordinates -* are numbered starting from 1. -* -* For details of additional special values that may be used in -c this array, see the description of the "constant" parameter. -f this array, see the description of the CONSTANT argument. -c -c If a NULL pointer is supplied instead of an array, each output -c coordinate will obtain its value from the corresponding -c input coordinate (or will be assigned the value AST__BAD if -c there is no corresponding input coordinate). -c constant -f CONSTANT = DOUBLE PRECISION( * ) (Given) -c An optional array containing values which may be assigned to -f An array containing values which may be assigned to -* input and/or output coordinates instead of deriving them -c from other coordinate values. If either of the "inperm" or -f from other coordinate values. If either of the INPERM or -c "outperm" arrays contains a negative value, it is used to -f OUTPERM arrays contains a negative value, it is used to -c address this "constant" array (such that -1 addresses the -f address this CONSTANT array (such that -1 addresses the -* first element, -2 addresses the second element, etc.) and the -* value obtained is used as the corresponding coordinate value. -* -* Care should be taken to ensure that locations lying outside -* the extent of this array are not accidentally addressed. The -c array is not used if the "inperm" and "outperm" arrays do not -f array is not used if the INPERM and OUTPERM arrays do not -* contain negative values. -c -c If a NULL pointer is supplied instead of an array, the -c behaviour is as if the array were of infinite length and -c filled with the value AST__BAD. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new PermMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new PermMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPermMap() -f AST_PERMMAP = INTEGER -* A pointer to the new PermMap. - -* Notes: -c - If either of the "inperm" or "outperm" arrays contains a -f - If either of the INPERM or OUTPERM arrays contains a -* zero value (or a positive value which does not identify a valid -* output/input coordinate, as appropriate), then the value -* AST__BAD is assigned as the new coordinate value. -* - This function does not attempt to ensure that the forward and -* inverse transformations performed by the PermMap are -* self-consistent in any way. You are therefore free to supply -* coordinate permutation arrays that achieve whatever effect is -* desired. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPermMap *new; /* Pointer to new PermMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the PermMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPermMap( NULL, sizeof( AstPermMap ), !class_init, &class_vtab, - "PermMap", nin, inperm, nout, outperm, constant ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new PermMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new PermMap. */ - return new; -} - -AstPermMap *astPermMapId_( int nin, const int inperm[], int nout, - const int outperm[], const double constant[], - const char *options, ... ) { -/* -* Name: -* astPermMapId_ - -* Purpose: -* Create a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "permmap.h" -* AstPermMap *astPermMapId_( int nin, const int inperm[], int nout, -* const int outperm[], const double constant[], -* const char *options, ... ) - -* Class Membership: -* PermMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astPermMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astPermMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* This function also converts the coordinate numbering in the -* permutation arrays from 1-based (used externally) to zero-based -* (used internally). -* -* The variable argument list also prevents this function from -* invoking astPermMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astPermMap_. - -* Returned Value: -* The ID value associated with the new PermMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPermMap *new; /* Pointer to new PermMap */ - int *inperm1; /* Pointer to temporary copy of "inperm" */ - int *outperm1; /* Pointer to temporary copy of "outperm" */ - int coord; /* Loop counter for coordinates */ - -/* Variable argument list */ - va_list args; /* Get a pointer to the thread specific global data structure. */ - - int *status; /* Pointer to inherited status value */ - - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If the "nin" and "nout" values are acceptable, allocate memory to - hold temporary copies of the "inperm" and "outperm" arrays (but - only if these arrays are not NULL). */ - inperm1 = NULL; - outperm1 = NULL; - if ( ( nin >= 0 ) && ( nout >= 0 ) ) { - if ( inperm ) inperm1 = astMalloc( sizeof( int ) * (size_t) nin ); - if ( outperm ) outperm1 = astMalloc( sizeof( int ) * (size_t) nout ); - if ( astOK ) { - -/* If necessary, make a copy of the "inperm" array, converting any - zero values into (zero-based) coordinate numbers that do not exist, - indicating a "bad" coordinate value. */ - if ( inperm ) { - for ( coord = 0; coord < nin; coord++ ) { - if ( inperm[ coord ] < 0 ) { - inperm1[ coord ] = inperm[ coord ]; - } else if ( inperm[ coord ] == 0 ) { - inperm1[ coord ] = nout; - -/* Convert valid coordinate references from 1-based (used externally) - to zero-based (used internally). */ - } else { - inperm1[ coord ] = inperm[ coord ] - 1; - } - } - } - -/* Repeat this process on the "outperm" array. */ - if ( outperm ) { - for ( coord = 0; coord < nout; coord++ ) { - if ( outperm[ coord ] < 0 ) { - outperm1[ coord ] = outperm[ coord ]; - } else if ( outperm[ coord ] == 0 ) { - outperm1[ coord ] = nin; - } else { - outperm1[ coord ] = outperm[ coord ] - 1; - } - } - } - } - } - -/* Initialise the PermMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPermMap( NULL, sizeof( AstPermMap ), !class_init, &class_vtab, - "PermMap", nin, inperm1, nout, outperm1, constant ); - -/* If necessary, free the temporary arrays allocated above. */ - if ( ( nin >= 0 ) && ( nout >= 0 ) ) { - if ( inperm ) inperm1 = astFree( inperm1 ); - if ( outperm ) outperm1 = astFree( outperm1 ); - } - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new PermMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new PermMap. */ - return astMakeId( new ); -} - -AstPermMap *astInitPermMap_( void *mem, size_t size, int init, - AstPermMapVtab *vtab, const char *name, - int nin, const int inperm[], - int nout, const int outperm[], - const double constant[], int *status ) { -/* -*+ -* Name: -* astInitPermMap - -* Purpose: -* Initialise a PermMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "permmap.h" -* AstPermMap *astInitPermMap( void *mem, size_t size, int init, -* AstPermMapVtab *vtab, const char *name, -* int nin, const int inperm[], -* int nout, const int outperm[], -* const double constant[] ) - -* Class Membership: -* PermMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new PermMap object. It allocates memory (if necessary) to accommodate -* the PermMap plus any additional data associated with the derived class. -* It then initialises a PermMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a PermMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the PermMap is to be initialised. -* This must be of sufficient size to accommodate the PermMap data -* (sizeof(PermMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the PermMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the PermMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the PermMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new PermMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* nin -* The number of input coordinate values per point. -* inperm -* Pointer to an array of int, with nin elements. For each input -* coordinate, the corresponding element of this array should contain the -* (zero-based) index of the output coordinate whose value is to be used. -* (Note that this array therefore defines the inverse coordinate -* transformation.) If a NULL value is supplied, the corresponding output -* coordinate value is used (or AST__BAD if there is no corresponding -* output coordinate). -* -* For details of additional special values that may be used in this -* array, see the description of the "constant" parameter. -* nout -* The number of output coordinate values per point. -* outperm -* Pointer to an array of int, with nout elements. For each output -* coordinate, the corresponding element of this array should contain the -* (zero-based) index of the input coordinate whose value is to be used. -* (Note that this array therefore defines the forward coordinate -* transformation.) If a NULL value is supplied, the corresponding input -* coordinate value is used (or AST__BAD if there is no corresponding -* input coordinate). -* -* For details of additional special values that may be used in this -* array, see the description of the "constant" parameter. -* constant -* Pointer to an array of double, which contains optional values which -* may be assigned to input and/or output coordinate values (instead of -* deriving them from other coordinate values). If either of the -* "inperm" or "outperm" arrays contains a negative value, it is used to -* address this "constant" array (such that -1 addresses the first -* element, -2 addresses the second element, etc.) and the value obtained -* is used as the corresponding coordinate value. Care should be taken -* to ensure that locations lying outside the extent of this array are -* not accidentally addressed. -* -* If a NULL value is supplied for this parameter, the behaviour is as -* if the constant array were of infinite length and filled with the -* value AST__BAD. - -* Returned Value: -* A pointer to the new PermMap. - -* Notes: -* - This function does not attempt to ensure that the forward and inverse -* transformations performed by the resulting PermMap are consistent in any -* way. The caller is therefore free to define the permutation arrays to -* achieve whatever effect is desired. -* - If either of the "inperm" or "outperm" arrays contains a positive -* value which does not identify a valid output/input coordinate (as -* appropriate), then the value AST__BAD is assigned as the new coordinate -* value. -* - This function makes a copy of the contents of the arrays supplied. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstPermMap *new; /* Pointer to new PermMap */ - int i; /* Loop counter for coordinates */ - int neg; /* Most negative permutation index */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitPermMapVtab( vtab, name ); - -/* Initialise a Mapping structure (the parent class) as the first component - within the PermMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstPermMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, nout, 1, 1 ); - - if ( astOK ) { - -/* Initialise the PermMap data. */ -/* ---------------------------- */ - new->permsplit = -INT_MAX; - -/* Initialise the array pointers. */ - new->inperm = NULL; - new->outperm = NULL; - new->constant = NULL; - -/* If an "inperm" and/or "outperm" array has been supplied, allocate memory - and store a copy. */ - if ( inperm ) new->inperm = astStore( NULL, inperm, sizeof( int ) * - (size_t) nin ); - if ( outperm ) new->outperm = astStore( NULL, outperm, sizeof( int ) * - (size_t) nout ); - -/* If a "constant" array has been supplied, we must also store a copy of it, - but must first determine how many of its elements we need. */ - if ( constant ) { - -/* Loop through the "inperm" array (if supplied) to find the most negative - value it contains. This corresponds with the maximum index into the - constant array. */ - neg = 0; - if ( inperm ) { - for ( i = 0; i < nin; i++ ) { - if ( inperm[ i ] < neg ) neg = inperm[ i ]; - } - } - -/* Also perform this process on the "outperm" array (if supplied). */ - if ( outperm ) { - for ( i = 0; i < nout; i++ ) { - if ( outperm[ i ] < neg ) neg = outperm[ i ]; - } - } - -/* If a negative value was found, use its size to determine how many elements - of the "constant" array to store in allocated memory. */ - if ( neg < 0 ) { - new->constant = astStore( NULL, constant, sizeof( double ) * - (size_t) (-neg) ); - } - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) { - new = astDelete( new ); - } - } - -/* Return a pointer to the new object. */ - return new; -} - -AstPermMap *astLoadPermMap_( void *mem, size_t size, - AstPermMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPermMap - -* Purpose: -* Load a PermMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "permmap.h" -* AstPermMap *astLoadPermMap( void *mem, size_t size, -* AstPermMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* PermMap loader. - -* Description: -* This function is provided to load a new PermMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* PermMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a PermMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the PermMap is to be -* loaded. This must be of sufficient size to accommodate the -* PermMap data (sizeof(PermMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the PermMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the PermMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPermMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new PermMap. If this is NULL, a pointer -* to the (static) virtual function table for the PermMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "PermMap" is used instead. - -* Returned Value: -* A pointer to the new PermMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstPermMap *new; /* Pointer to the new PermMap */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword strings */ - int coord; /* Loop counter for coordinates */ - int iconst; /* Loop counter for constants */ - int in_cpy; /* Input coordinates obtained by copying? */ - int invert; /* Invert attribute value */ - int ival; /* Integer value */ - int nconst; /* Number of constants */ - int nin; /* Number of input coordinates */ - int nout; /* Number of output coordinates */ - int out_cpy; /* Output coordinates obtained by copying? */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this PermMap. In this case the - PermMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPermMap ); - vtab = &class_vtab; - name = "PermMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPermMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built PermMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "PermMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Initialise the PermMap's pointers. */ - new->inperm = NULL; - new->outperm = NULL; - new->constant = NULL; - -/* Determine if the PermMap is inverted and obtain the "true" number - of input and output coordinates by un-doing the effects of any - inversion. */ - invert = astGetInvert( new ); - nin = !invert ? astGetNin( new ) : astGetNout( new ); - nout = !invert ? astGetNout( new ) : astGetNin( new ); - -/* PermSplit. */ -/* ---------- */ - new->permsplit = astReadInt( channel, "pmsplt", -INT_MAX ); - if ( TestPermSplit( new, status ) ) SetPermSplit( new, new->permsplit, status ); - -/* InCpy and OutCpy. */ -/* ----------------- */ -/* Obtain boolean values via the "InCpy" and "OutCpy" keywords which - indicate if input/output coordinates should be obtained simply by - copying the corresponding output/input coordinates. */ - in_cpy = astReadInt( channel, "incpy", 0 ); - out_cpy = astReadInt( channel, "outcpy", 0 ); - -/* If coordinates are specified individually (not simply copied), then - allocate memory for the coordinate permutation arrays. */ - if ( !in_cpy ) new->inperm = astMalloc( sizeof( int ) * (size_t) nin ); - if ( !out_cpy ) new->outperm = astMalloc( sizeof( int ) * - (size_t) nout ); - -/* If an error occurred, ensure that all allocated memory is freed. */ - if ( !astOK ) { - if ( !in_cpy ) new->inperm = astFree( new->inperm ); - if ( !out_cpy ) new->outperm = astFree( new->outperm ); - -/* Otherwise read data into these arrays... */ - } else { - -/* "inperm" array contents. */ -/* ------------------------ */ -/* If required, create a keyword for each element of the "inperm" - array and read the element's value. */ - if ( !in_cpy ) { - for ( coord = 0; coord < nin; coord++ ) { - (void) sprintf( key, "in%d", coord + 1 ); - ival = astReadInt( channel, key, 0 ); - -/* If the value is zero (indicating a "bad" coordinate), convert it to - a (zero-based) coordinate number that doesn't exist. */ - if ( ival == 0 ) { - ival = nout; - -/* If the coordinate reference is valid, convert to zero-based - coordinate numbering for internal use. */ - } else if ( ival > 0 ) { - ival--; - } - -/* Store the value. */ - new->inperm[ coord ] = ival; - } - } - -/* "outperm" array contents. */ -/* ------------------------- */ -/* If required, create a keyword for each element of the "outperm" - array and read the element's value. */ - if ( !out_cpy ) { - for ( coord = 0; coord < nout; coord++ ) { - (void) sprintf( key, "out%d", coord + 1 ); - ival = astReadInt( channel, key, 0 ); - -/* If the value is zero (indicating a "bad" coordinate), convert it to - a (zero-based) coordinate number that doesn't exist. */ - if ( ival == 0 ) { - ival = nin; - -/* If the coordinate reference is valid, convert to zero-based - coordinate numbering for internal use. */ - } else if ( ival > 0 ) { - ival--; - } - -/* Store the value. */ - new->outperm[ coord ] = ival; - } - } - -/* Number of constants. */ -/* -------------------- */ -/* Determine the number of constants and allocate memory to hold - them. */ - nconst = astReadInt( channel, "nconst", 0 ); - if ( nconst < 0 ) nconst = 0; - new->constant = astMalloc( sizeof( double ) * (size_t) nconst ); - if ( astOK ) { - -/* Constants. */ -/* ---------- */ -/* Create a keyword for each constant and read its value. */ - for ( iconst = 0; iconst < nconst; iconst++ ) { - (void) sprintf( key, "con%d", iconst + 1 ); - new->constant[ iconst ] = - astReadDouble( channel, key, AST__BAD ); - } - } - } - -/* If an error occurred, clean up by deleting the new PermMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new PermMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -double *astGetConstants_( AstPermMap *this, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,PermMap,GetConstants))( this, status ); -} - -int *astGetInPerm_( AstPermMap *this, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,PermMap,GetInPerm))( this, status ); -} - -int *astGetOutPerm_( AstPermMap *this, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,PermMap,GetOutPerm))( this, status ); -} - - - - - - diff --git a/ast/permmap.h b/ast/permmap.h deleted file mode 100644 index 0115783..0000000 --- a/ast/permmap.h +++ /dev/null @@ -1,322 +0,0 @@ -#if !defined( PERMMAP_INCLUDED ) /* Include this file only once */ -#define PERMMAP_INCLUDED -/* -*+ -* Name: -* permmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the PermMap class. - -* Invocation: -* #include "permmap.h" - -* Description: -* This include file defines the interface to the PermMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The PermMap class implements Mappings that perform permutation -* of the order of coordinate values, possibly also accompanied by -* changes in the number of coordinates (between input and output). -* -* In addition to permuting the coordinate order, coordinates may -* also be assigned constant values which are unrelated to other -* coordinate values. This facility is useful when the number of -* coordinates is being increased, as it allows fixed values to be -* assigned to the new coordinates. - -* Inheritance: -* The PermMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astTransform -* Transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* astGetConstants -* Obtain a copy of the constants array -* astGetInPerm -* Obtain a copy of the input permutation array -* astGetOutPerm -* Obtain a copy of the output permutation array - -* Other Class Functions: -* Public: -* astIsAPermMap -* Test class membership. -* astPermMap -* Create a PermMap. -* -* Protected: -* astCheckPermMap -* Validate class membership. -* astInitPermMap -* Initialise a PermMap. -* astInitPermMapVtab -* Initialise the virtual function table for the PermMap class. -* astLoadPermMap -* Load a PermMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstPermMap -* PermMap object type. -* -* Protected: -* AstPermMapVtab -* PermMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 29-FEB-1996 (RFWS): -* Original version. -* 26-SEP-1996 (RFWS): -* Added external interface and I/O facilities. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitPermMapVtab -* method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* PermMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstPermMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int *inperm; /* Pointer to input permutation array */ - int *outperm; /* Pointer to output permutation array */ - double *constant; /* Pointer to array of constant values */ - int permsplit; /* Method to use within MapSplit */ -} AstPermMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstPermMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - double *(* GetConstants)( AstPermMap *, int * ); - int *(* GetInPerm)( AstPermMap *, int * ); - int *(* GetOutPerm)( AstPermMap *, int * ); - void (* SetPermSplit)( AstPermMap *, int, int * ); - void (* ClearPermSplit)( AstPermMap *, int * ); - int (* TestPermSplit)( AstPermMap *, int * ); - int (* GetPermSplit)( AstPermMap *, int * ); - -} AstPermMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstPermMapGlobals { - AstPermMapVtab Class_Vtab; - int Class_Init; -} AstPermMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitPermMapGlobals_( AstPermMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(PermMap) /* Check class membership */ -astPROTO_ISA(PermMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstPermMap *astPermMap_( int, const int [], int, const int [], - const double [], const char *, int *, ...); -#else -AstPermMap *astPermMapId_( int, const int [], int, const int [], - const double [], const char *, ... )__attribute__((format(printf,6,7))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstPermMap *astInitPermMap_( void *, size_t, int, AstPermMapVtab *, - const char *, int, const int [], int, - const int [], const double [], int * ); - -/* Vtab initialiser. */ -void astInitPermMapVtab_( AstPermMapVtab *, const char *, int * ); - -/* Loader. */ -AstPermMap *astLoadPermMap_( void *, size_t, AstPermMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -double *astGetConstants_( AstPermMap *, int * ); -int *astGetInPerm_( AstPermMap *, int * ); -int *astGetOutPerm_( AstPermMap *, int * ); -void astSetPermSplit_( AstPermMap *, int, int * ); -void astClearPermSplit_( AstPermMap *, int * ); -int astTestPermSplit_( AstPermMap *, int * ); -int astGetPermSplit_( AstPermMap *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckPermMap(this) astINVOKE_CHECK(PermMap,this,0) -#define astVerifyPermMap(this) astINVOKE_CHECK(PermMap,this,1) - -/* Test class membership. */ -#define astIsAPermMap(this) astINVOKE_ISA(PermMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astPermMap astINVOKE(F,astPermMap_) -#else -#define astPermMap astINVOKE(F,astPermMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitPermMap(mem,size,init,vtab,name,nin,inperm,nout,outperm,constant) \ -astINVOKE(O,astInitPermMap_(mem,size,init,vtab,name,nin,inperm,nout,outperm,constant,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitPermMapVtab(vtab,name) astINVOKE(V,astInitPermMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadPermMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadPermMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckPermMap to validate PermMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astGetConstants(this) astINVOKE(V,astGetConstants_(astCheckPermMap(this),STATUS_PTR)) -#define astGetInPerm(this) astINVOKE(V,astGetInPerm_(astCheckPermMap(this),STATUS_PTR)) -#define astGetOutPerm(this) astINVOKE(V,astGetOutPerm_(astCheckPermMap(this),STATUS_PTR)) -#define astSetPermSplit(this,permsplit) astINVOKE(V,astSetPermSplit_(astCheckPermMap(this),permsplit,STATUS_PTR)) -#define astClearPermSplit(this) astINVOKE(V,astClearPermSplit_(astCheckPermMap(this),STATUS_PTR)) -#define astTestPermSplit(this) astINVOKE(V,astTestPermSplit_(astCheckPermMap(this),STATUS_PTR)) -#define astGetPermSplit(this) astINVOKE(V,astGetPermSplit_(astCheckPermMap(this),STATUS_PTR)) -#endif - -#endif - - - - - diff --git a/ast/pg3d.h b/ast/pg3d.h deleted file mode 100644 index e4dab63..0000000 --- a/ast/pg3d.h +++ /dev/null @@ -1,68 +0,0 @@ -#if !defined( PG3D_INCLUDED ) /* Include this file only once */ -#define PG3D_INCLUDED -/* -*+ -* Name: -* pg3d.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the pg3d module - -* Invocation: -* #include "pg3d.h" - -* Description: -* This include file defines the interface to the pg3d module -* (implemented in file grf3d_pgplot.c) and provides the type -* definitions, function prototypes and macros, etc. needed to -* use this module. -* -* The functions in the pg3d interface provide control of the view -* of the 3D world coordinate system visible on the 2D PGPLOT -* viewport. They are provided for users of the PGPLOT implementation -* of the grf3D interface distributed with AST. No calls to these -* functions are made from within AST itself. - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (JACH - UCLan) - -* History: -* 20-JUN-2007 (DSB): -* Original version. -*- -*/ - -int PG3DRotateEye( int, float ); -int PG3DSetCamera( float[3], float[3], float[3], float ); -int PG3DSetEye( float[3] ); -int PG3DSetTarget( float[3] ); -int PG3DSetUp( float[3] ); -int PG3DSetScreen( float ); -int PG3DForward( float ); -int PG3DAutoCamera( float[3], float[3] ); -int PG3DFindNearest( int, float *, float *, float *, int * ); - -#endif diff --git a/ast/plot.c b/ast/plot.c deleted file mode 100644 index a701116..0000000 --- a/ast/plot.c +++ /dev/null @@ -1,32074 +0,0 @@ -/* -*class++ -* Name: -* Plot - -* Purpose: -* Provide facilities for 2D graphical output. - -* Constructor Function: -c astPlot -f AST_PLOT - -* Description: -* This class provides facilities for producing 2D graphical output. -* A Plot is a specialised form of FrameSet, in which the base -* Frame describes a "graphical" coordinate system and is -* associated with a rectangular plotting area in the underlying -* graphics system. This plotting area is where graphical output -* appears. It is defined when the Plot is created. -* -* The current Frame of a Plot describes a "physical" coordinate -* system, which is the coordinate system in which plotting -* operations are specified. The results of each plotting operation -* are automatically transformed into graphical coordinates so as -* to appear in the plotting area (subject to any clipping which -* may be in effect). -* -* Because the Mapping between physical and graphical coordinates -* may often be non-linear, or even discontinuous, most plotting -* does not result in simple straight lines. The basic plotting -* element is therefore not a straight line, but a geodesic curve -c (see astCurve, astGenCurve and astPolyCurve). A Plot also provides facilities for -c drawing markers or symbols (astMark), text (astText) and grid lines -c (astGridLine). It is also possible to draw curvilinear axes with -c optional coordinate grids (astGrid). -f (see AST_CURVE, AST_GENCURVE and AST_POLYCURVE). A Plot also provides facilities -f for drawing markers or symbols (AST_MARK), text (AST_TEXT) and grid -f lines (AST_GRIDLINE). It is also possible to draw curvilinear axes -f with optional coordinate grids (AST_GRID). -* A range of Plot attributes is available to allow precise control -* over the appearance of graphical output produced by these -c functions. -f routines. -* -* You may select different physical coordinate systems in which to -* plot (including the native graphical coordinate system itself) -* by selecting different Frames as the current Frame of a Plot, -* using its Current attribute. You may also set up clipping (see -c astClip) to limit the extent of any plotting you perform, and -f AST_CLIP) to limit the extent of any plotting you perform, and -* this may be done in any of the coordinate systems associated -* with the Plot, not necessarily the one you are plotting in. -* -* Like any FrameSet, a Plot may also be used as a Frame. In this -* case, it behaves like its current Frame, which describes the -* physical coordinate system. -* -* When used as a Mapping, a Plot describes the inter-relation -* between graphical coordinates (its base Frame) and physical -* coordinates (its current Frame). It differs from a normal -* FrameSet, however, in that an attempt to transform points which -* lie in clipped areas of the Plot will result in bad coordinate -* values (AST__BAD). - -* Inheritance: -* The Plot class inherits from the FrameSet class. - -* Attributes: -* In addition to those attributes common to all FrameSets, every -* Plot also has the following attributes: -* -* - Abbrev: Abbreviate leading fields? -* - Border: Draw a border around valid regions of a Plot? -* - Clip: Clip lines and/or markers at the Plot boundary? -* - ClipOp: Combine Plot clipping limits using a boolean OR? -* - Colour(element): Colour index for a Plot element -* - DrawAxes(axis): Draw axes for a Plot? -* - DrawTitle: Draw a title for a Plot? -* - Escape: Allow changes of character attributes within strings? -* - Edge(axis): Which edges to label in a Plot -* - Font(element): Character font for a Plot element -* - Gap(axis): Interval between linearly spaced major axis values -* - Grf: Select the graphics interface to use. -* - Grid: Draw grid lines for a Plot? -* - Invisible: Draw graphics in invisible ink? -* - LabelAt(axis): Where to place numerical labels for a Plot -* - LabelUnits(axis): Use axis unit descriptions in a Plot? -* - LabelUp(axis): Draw numerical Plot labels upright? -* - Labelling: Label and tick placement option for a Plot -* - LogGap(axis): Interval between logarithmically spaced major axis values -* - LogPlot(axis): Map the plot onto the screen logarithmically? -* - LogTicks(axis): Space the major tick marks logarithmically? -* - MajTickLen(axis): Length of major tick marks for a Plot -* - MinTickLen(axis): Length of minor tick marks for a Plot -* - MinTick(axis): Density of minor tick marks for a Plot -* - NumLab(axis): Draw numerical axis labels for a Plot? -* - NumLabGap(axis): Spacing of numerical axis labels for a Plot -* - Size(element): Character size for a Plot element -* - Style(element): Line style for a Plot element -* - TextLab(axis): Draw descriptive axis labels for a Plot? -* - TextLabGap(axis): Spacing of descriptive axis labels for a Plot -* - TickAll: Draw tick marks on all edges of a Plot? -* - TitleGap: Vertical spacing for a Plot title -* - Tol: Plotting tolerance -* - Width(element): Line width for a Plot element - -* Functions: -c In addition to those functions applicable to all FrameSets, the -c following functions may also be applied to all Plots: -f In addition to those routines applicable to all FrameSets, the -f following routines may also be applied to all Plots: -* -c - astBBuf: Begin a new graphical buffering context -c - astBorder: Draw a border around valid regions of a Plot -c - astBoundingBox: Returns a bounding box for previously drawn graphics -c - astClip: Set up or remove clipping for a Plot -c - astCurve: Draw a geodesic curve -c - astEBuf: End the current graphical buffering context -c - astGenCurve: Draw a generalized curve -c - astGetGrfContext: Get the graphics context for a Plot -c - astGrfPop: Retrieve previously saved graphics functions -c - astGrfPush: Save the current graphics functions -c - astGrfSet: Register a graphics routine for use by a Plot -c - astGrid: Draw a set of labelled coordinate axes -c - astGridLine: Draw a grid line (or axis) for a Plot -c - astMark: Draw a set of markers for a Plot -c - astPolyCurve: Draw a series of connected geodesic curves -c - astRegionOutline: Draw the outline of an AST Region -c - astText: Draw a text string for a Plot -f - AST_BBUF: Begin a new graphical buffering context -f - AST_BORDER: Draw a border around valid regions of a Plot -f - AST_BOUNDINGBOX: Returns a bounding box for previously drawn graphics -f - AST_CLIP: Set up or remove clipping for a Plot -f - AST_CURVE: Draw a geodesic curve -f - AST_EBUF: End the current graphical buffering context -f - AST_GENCURVE: Draw a generalized curve -f - AST_GETGRFCONTEXT: Get the graphics context for a Plot -f - AST_GRFPOP: Retrieve previously saved graphics functions -f - AST_GRFPUSH: Save the current graphics functions -f - AST_GRFSET: Register a graphics routine for use by the Plot class -f - AST_GRID: Draw a set of labelled coordinate axes -f - AST_GRIDLINE: Draw a grid line (or axis) for a Plot -f - AST_MARK: Draw a set of markers for a Plot -f - AST_POLYCURVE: Draw a series of connected geodesic curves -f - AST_REGIONOUTLINE: Draw the outline of an AST Region -f - AST_TEXT: Draw a text string for a Plot - -* Graphical Elements: -* The colour index, character font, character size, line style and -* line width used for plotting can be set independently for -* various elements of the graphical output produced by a Plot. -* The different graphical elements are identified by appending the -* strings listed below as subscripts to the Plot attributes -* Colour(element), Font(element), Size(element), Style(element) -* and Width(element). These strings are case-insensitive and -* unambiguous abbreviations may be used. Elements of the graphical -* output which relate to individual axes can be referred to either -* independently (e.g. "(Grid1)" and "(Grid2)" ) or together (e.g. -* "(Grid)"): -* -c - Axes: Axis lines drawn through tick marks using astGrid -f - Axes: Axis lines drawn through tick marks using AST_GRID -c - Axis1: Axis line drawn through tick marks on axis 1 using astGrid -f - Axis1: Axis line drawn through tick marks on axis 1 using AST_GRID -c - Axis2: Axis line drawn through tick marks on axis 2 using astGrid -f - Axis2: Axis line drawn through tick marks on axis 2 using AST_GRID -c - Border: The Plot border drawn using astBorder, astGrid or astRegionOutline -f - Border: The Plot border drawn using AST_BORDER, AST_GRID or AST_REGIONOUTLINE -c - Curves: Geodesic curves drawn using astCurve, astGenCurve or astPolyCurve -f - Curves: Geodesic curves drawn using AST_CURVE, AST_GENCURVE or AST_POLYCURVE -c - Grid: Grid lines drawn using astGridLine or astGrid -f - Grid: Grid lines drawn using AST_GRIDLINE or AST_GRID -c - Grid1: Grid lines which cross axis 1, drawn using astGridLine or astGrid -f - Grid1: Grid lines which cross axis 1, drawn using AST_GRIDLINE or AST_GRID -c - Grid2: Grid lines which cross axis 2, drawn using astGridLine or astGrid -f - Grid2: Grid lines which cross axis 2, drawn using AST_GRIDLINE or AST_GRID -c - Markers: Graphical markers (symbols) drawn using astMark -f - Markers: Graphical markers (symbols) drawn using AST_MARK -c - NumLab: Numerical axis labels drawn using astGrid -f - NumLab: Numerical axis labels drawn using AST_GRID -c - NumLab1: Numerical labels for axis 1 drawn using astGrid -f - NumLab1: Numerical labels for axis 1 drawn using AST_GRID -c - NumLab2: Numerical labels for axis 2 drawn using astGrid -f - NumLab2: Numerical labels for axis 2 drawn using AST_GRID -c - Strings: Text strings drawn using astText -f - Strings: Text strings drawn using AST_TEXT -c - TextLab: Descriptive axis labels drawn using astGrid -f - TextLab: Descriptive axis labels drawn using AST_GRID -c - TextLab1: Descriptive label for axis 1 drawn using astGrid -f - TextLab1: Descriptive label for axis 1 drawn using AST_GRID -c - TextLab2: Descriptive label for axis 2 drawn using astGrid -f - TextLab2: Descriptive label for axis 2 drawn using AST_GRID -c - Ticks: Tick marks (both major and minor) drawn using astGrid -f - Ticks: Tick marks (both major and minor) drawn using AST_GRID -c - Ticks1: Tick marks (both major and minor) for axis 1 drawn using astGrid -f - Ticks1: Tick marks (both major and minor) for axis 1 drawn using AST_GRID -c - Ticks2: Tick marks (both major and minor) for axis 2 drawn using astGrid -f - Ticks2: Tick marks (both major and minor) for axis 2 drawn using AST_GRID -c - Title: The Plot title drawn using astGrid -f - Title: The Plot title drawn using AST_GRID - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 18-SEP-1996 (DSB): -* Original version. -* 25-FEB-1997 (RFWS): -* Tidied all public prologues. -* 18-AUG-1997 (DSB): -* Changes made to ensure that the first label on each axis is -* never abbreviated, and to avoid segmentation violation when NumLab -* is set to zero. -* 1-SEP-1997 (DSB): -* astGetGap changed so that it returns the default value which will -* be used (instead of AST__BAD) if no value has been set for Gap. -* The Border attribute modified so that it is off (zero) by default. -* 19-SEP-1997 (DSB): -* o Check that something has been plotted before using the bounding -* box to determine title and label positions. -* o Fixed bug which caused a tick mark at the pole to be draw at -* a random angle. -* o The size of the increment used to determine the tangent to a grid -* line at the position to a label has been reduced to make sure the -* labls are drawn parallel to grid line. -* o Correct the logic for catering with reversed axes when determining -* the displacement of a label's reference point from the associated -* axis. -* o Corrected logic which determined if two numerical labels overlap. -* o Corrected logic for determining when to abbreviate numerical -* labels. -* o Use of strtok replaced by local function FindWord. -* o Correct logic which determines which side of the axis to draw -* tick marks when using interior labelling. -* o If the base Frame of the FrameSet supplied to astPlot has more -* than 2 axes, then use a sub-frame formed from the first two axes, -* instead of simply reporting an error. -* o If the current Frame of the Plot supplied to astGrid or -* astBorder has more than 2 axes, then use a sub-frame formed from -* the first two axes, instead of simply reporting an error. -* o Default for Border is now to draw the border if exterior -* Labelling is used, but not to draw it if interior labelling is -* used. -* o Public astGet function now returns actual used values for all -* attributes. Protected astGetXyz functions still return the requested -* value (which may differ from the used value), or the "unset" value -* if no value has been set for the attribute. -* o The defaults for Edge now depend on Labelling. If exterior -* labelling was requested but cannot be produced using defaults of -* Edge(1)=Bottom and Edge(2)=Left, then these default Edge values -* are swapped. If exterior labelling is still not possible, the -* original default Edge values are re-instated. -* o Unset attributes which use dynamic defaults are now flagged as -* "unhelpful" in the dump function. -* o Added attribute Escape which allows text strings to include -* escape sequences (see function GrText). This attribute and -* associated functionality is currently not available for use, search -* for all occurences of ENABLE-ESCAPE for instructions on how to -* enable the facilities. -* o Strings now used instead of integers to represent "choice" -* attributes externally (eg Edge and Labelling). -* 24-NOV-1997 (DSB): -* o Fixed bug in function Grid which caused units to be included in -* SkyFrame axis labels by default. -* o Replaced calls to DrawText by calls to astGText, and replaced -* references to "U" and "D" justifications by "T" and "B". This -* stops labels drifting to the bottom left when GAIA zooms. -* 23-MAR-1998 (DSB): -* Added extra checks on global status into routine Grid to avoid -* segmentation violations occuring due to null pointers being used. -* 10-JUN-1998 (DSB): -* Modify DrawTicks so that ticks are drawn closer to singularities -* than previously. Also normalise this constraint to the screen size -* rather than the length of a major tick mark. -* 28-OCT-1998 (DSB): -* o Added method astPolyCurve. -* o Extract the Current Frame from the Plot prior to using Frame -* methods such as astOffset, astNorm, etc. -* o PlotLabel modified to ensure labels are abbreviated even if -* they are next to the "root" label (i.e. the label with most -* trailing zeros). -* o Modified description of Width attribute. Width no longer gives -* the absolute line width in inches. Instead it is a scale factor, -* where 1.0 corresponds to a "typical thin line" on the device. -* o Modified LabelUnits attribute so that the default value is zero -* for SkyAxes and non-zero for other Axes. -* 10-DEC-1998 (DSB): -* Modified all calls to the "pow" maths function to avoid using -* literal constants as arguments. This seems to cause segmentation -* violations on some systems. -* 16-JUL-1999 (DSB): -* Fixed memory leaks in EdgeCrossings and EdgeLabels. -* 16-SEP-1999 (DSB): -* Avoid writing out clipping limits if they are undefined. -* 12-OCT-1999 (DSB): -* o Modified use of the NumLab attribute so that setting it to zero -* does not prevent exterior labels from being produced. -* o Allow length of tick marks to be specified separately for -* both axes. -* 13-OCT-2000 (DSB): -* o Purge zero length sections from CurveData structures. -* o Increase tolerance for edge labels from 0.0005 to 0.005. -* 9-JAN-2001 (DSB): -* o Change argument "in" for astMark and astPolyCurve from type -* "const double (*)[]" to "const double *". -* o Check success of astReadString before using the returned -* pointer. -* o Change method for choosing default LabelAt values to ignore -* values which produce no visible labels. -* 10-JAN-2001 (DSB): -* o Modified FindMajTick to choose the size of fillable holes in -* the axis range on the basis of the number of ticks on the axis. -* This avoids holes being visible in the displayed tick marks when -* using very small gaps. -* 22-MAY-2001 (DSB): -* Added a check when using interior labelling, to ensure that the -* most appropriate edges are used for text labels. -* 13-JUN-2001 (DSB): -* Added public method astGenCurve, astGrfSet, astGrfPop, astGrfPush. -* Made DrawAxes attribute axis specific. -* 4-JUL-2001 (DSB): -* The Crv function used to have a restriction that if *any* -* subsection was very short, then *none* of the subsections were -* subdivided. This meant that long subsections which needed -* subdividing were not subdivided if there was also a very short -* subsection. To get round this problem the restriction was changed -* to "if *all* subsections are very short then none are divided. -* This was implemented by changing dl2_min to dl2_max, and adding -* a check for very short segments (which are then not sub-divided). -* 16-AUG-2001 (DSB): -* Remove the check for very short segments introduced above, as it -* caused south pole tan projection to include some spurious lines. -* 20-SEP-2001 (DSB): -* - Initialize baseframe to NULL in astInitPlot (prevents segvios). -* - Modified astInitPlot to allow the "frame" argument to the astPlot -* constructor to be a Plot. -* 10-JAN-2002 (DSB): -* - Added axis-specific graphical elements "axis1", "axis2", etc. -* - FullForm returns a match without ambiguity if the test string -* matches an option exactly, including length. -* 31-JAN-2002 (DSB): -* - Added RejectOOB to reject tick marks which are not in their primary -* domain. -* 14-FEB-2002 (DSB): -* - Relaxed the conditions for equality within the EQUALS macro. -* Guard aginst no ticks being found. -* 18-FEB-2002 (DSB): -* - Make a permanent copy of any old axis format string in TickMarks. -* Previously a mere pointer into the astGet string buffer was stored, -* which could be over-written after many calls to astGet. -* - If a user specifies an axis format, use it whether or not it -* results in any identical adjacent labels. -* 4-MAR-2002 (DSB): -* - Made fairly extesive changes to the creation and use of tick -* mark values in order to circumvent problems with CAR projections, -* and "1 to many" mappings (such as 2D cartesian->polar). The -* policy now is that axis normalization is only performed when -* necessary (i.e. to create labels for display, etc). Tick mark -* values are stored and handled as non-normalized values as much as -* possible. -* 13-JUN-2002 (DSB): -* Modified Norm1 to prevent major tick value from being removed if -* the supplied reference value is out of bounds, resulting in the -* Mapping producing bad values -* 14-JUN-2002 (DSB): -* Re-wrote PlotLabels to improve abbreviation of labels and the -* choice of which labels not to print. -* 14-AUG-2002 (DSB): -* - Added method astBoundingBox. -* - Added attribute Invisible. -* - Correct handling of "axis specific" plot elements cuch as -* (Axis1), (Axis2), etc. -* 12-SEP-2002 (DSB): -* - Modified Map1 to remove slow normalization method (it is now -* faster but the changes result in some longer-than-needed grids -* lines when (e.g.) plotting pixel coordins in Polar coords). -* - Modified Axlot so that SkyFrames positions which are out of -* their normal ranges are not rejected by Map1. -* 10-OCT-2002 (DSB): -* grfAttrs:Modified to test element attributes explicitly using the -* relevant TestUse functions, instead of relying on the -* "GetUse" function returning the NO constant if not set. -* - Modified Axplot so that SkyFrames positions which are out of -* their normal ranges are not rejected by Map1. -* - Only use tick marks which are within the axis range given by the -* Bottom and Top Axis attributes. -* - Norm1: If the normalized current frame coords are bad, do not -* reinstate the original unnormalized values. For instance, current -* Frame values which are outside the valid domain of the projection -* should result in bad values when normalized, not the original -* good values. The original comment stated "If the normalization -* produced bad coords (e.g. as may happen if the supplied refernce -* value corresponds to a point on the line through the tick mark -* which is outside the valid region of the mapping) leave the original -* tick mark values unchanged". -* - GetTicks: Limit maxticks to be no less than 8. -* 8-JAN-2003 (DSB): -* - Changed private InitVtab method to protected astInitPlotVtab -* method. -* - Use private IsASkyFrame method in place of astIsASkyFrame. -* - Modify PlotLabels to excluding exponents when counting trailing -* zeros, and also to pad trailing fields with trailing zeros up to -* the max number of decimal places when estimating label priorities. -* - Modified Overlap to ensure that axis labels are speced by at -* least two spaces. -* 22-JAN-2003 (DSB): -* - Modified PlotLabels so that labels are rejected in a regular -* pattern rather than semi-random. -* - Modified the way PlotLabels abbreviates leading fields. -* - Introdued the skipbad parameter for the Crv function, in order -* to provide some degree of protection against the Crv algorithm -* skipping over small sections of valid coordinates (such as when -* a curve crosses the plot very close to a corner of the plot). -* 25-MAR-2003 (DSB): -* - Modified FindMajTicks to avoid losing tick marks when dealing -* with high precision data. -* 8-AUG-2003 (DSB): -* - Modified PlotLabels to ensure that the root label for the -* second axis is not omitted due to it overlapping a label from -* the first axis (a different root label is now chosen if this would -* be the case). -* - Modify FindMajTicks to avoid tick marks which should be at -* exactly zero being placed at some very small non-zero axis value. -* 22-OCT-2003 (DSB): -* - DrawTicks modified to correctly reset graphical attributes and -* pass on to the next axis if an axis has zero length major and minor -* tick marks. -* 9-JAN-2004 (DSB): -* DrawGrid: Report error if no grid curves can be drawn. -* AxPlot: Initialise returned CDATA structure before checking argument -* validity. -* GetTicks: Calculate the reference value on the other axis using -* function "Typical" rather than simply using the man of the supplied -* values (the supplied values may be clustered around 0 and 2*PI if the -* field is centred on the origin, resulting in the mean being at about -* 1.PI and therefore inappropriate). -* 13-JAN-2004 (DSB): -* - Added LogPlot attribute, and the facility for mapping the base -* coordinate system logarithmically onto the plotting area instead of -* linearly. -* - Added LogTicks attribute, and the facility for spacing the -* major tick marks logarithmically instead of linearly. -* - Added LogGap attribute, and the facility for storing separate -* gap sizes for linear and log tick spacing. -* 15-JAN-2004 (DSB): -* - Added LogLabel attribute. -* - Re-instated the inclusion of escape sequences in strings (see -* function GrText). -* 12-FEB-2004 (DSB): -* - RightVector: Corrected usage of chh and chv. -* - GQch and GScales: Check that values returned by grf module are -* usable. -* - DrawAxis: Extend axis section by one section (if possible) at -* each end (overcomes problems where the axis does not reach a pole). -* - DrawAxis: Check axis does not extend beyond a pole. -* - Labels: Correct logic of loop which plots interior labels -* (previously it missed out labels if there were only 3) -* - Allow for some rounding error in FindMajTicks when comparing an -* axis value with a loweror upper axis limit. -* 19-FEB-2004 (DSB): -* - Reduced the dynamic range restriction for log ticks from 2 decades -* to 1. -* - Temporarily clear any error status before re-instating the -* original Format in TickMarks. -* - Add LogTicks to the GetAttrib function so that the value of the -* LogTicks attribute can be got by the public. -* - Modify Crv to include a check that he vector scale has not -* changed much between adjacent segments. -* - Modify Crv so that a segment is only subdivided if at least -* half of the subsegments are longer than the shortest significant -* length. Also put a restriction on subdivision so that -* subdivision only occurs if the bounding box of the segment being -* sub-divided is smaller than the bounding box of its parent -* segment. -* 27-FEB-2004 (DSB): -* - Reduce the default Tol value from 0.001 to 0.01 in order to -* speed up curve drawing.. -* - Use 0.1*Tol in Boundary because the boundary tracing algorithm -* seems to produce much worse visible errors than it should do for a -* given Tol. -* 2-MAR-2004 (DSB): -* - Corrected handling of bounding boxes in Crv so that -* subdivision is allowed if the bounding box shrinks on only 1 axis -* (previously required shrinkage on both axes but this fails if -* all the points are on a horizontal or vertical line). -* - Modified FindMajTicks to use a better algorithm for finding an -* appropriate nfill value (previously logplot=1 axes could have -* unfilled holes at the high end). -* - Modified GetTicks so that FindMajTicks is not called -* repeatedly with the same gap size. -* - Modify AxPlot/Map1 so that the axis curve is sampled logarithmically -* if the corresponding axis is mapped logarithmically. -* 10-MAR-2004 (DSB): -* - Modified Typical to give less weight to vaalues close to the -* edges of the range covered by the plotting area. -* - Increased minimum angle between curve and edge required to -* create an edge label from 3 degs to 5 degs. -* - Modified PlotLabels to ignore duplicate adjacent labels which -* determining overlap of labels. -* 17-MAR-2004 (DSB): -* - Modified Typical to give normal weight to edge bins in -* histogram if these bins contain all the counts. -* - Modified DrawTicks to add extra minor ticks below first major -* tick value and above last major tick value. -* - Norm1 can reject usable tick mark values because of an -* inappropriate value being used on the other axis (i.e. one for -* which the position is undefined in grapics coords). Therfoer -* Norm1 has been modified to use 3 different reference values -* in an attempt to find one which gives good axis values. -* 25-AUG-2004 (DSB): -* - Correct handling of "fmt" pointer in TickMarks function (identified -* and reported by Bill Joye). -* 14-SEP-2004 (DSB): -* - In EdgeLabels change definition of "distinct labels". Used to -* be that labels were distinct if they had different formatted -* labels. Now they are distinct if they have different floating -* point numerical values. Fixes a bug reported by Micah Johnson. -* - TickMarks re-structured to optimise the precision (no. of digits) -* even if a value has been assigned for the Format attribute, but only -* if the format specifier includes a wildcard precision specifier. For -* instance, to get graphical separators a format must be specified -* which included the "g" flag. As things were, this would prevent -* the optimisation of the digits value. Can now use "dms.*g" to -* allow the number of digits to be optimised. -* 29-SEP-2004 (DSB): -* - In FindMajTicks, begin the process of increasing "nfill" from -* a value of zero rather than one (in many cases no filling is -* needed). -* - In GetTicks (linear tick marks section) ensure that 10 -* *different* gap sizes are used before giving up. Previously, the -* 10 tests could include duplicated gap values. -* 8-NOV-2004 (DSB): -* - In Norm1, try more alternative "other axis" values before -* accepting that a tick mark value cannot be normalised. -* 2-FEB-2005 (DSB): -* - Avoid using astStore to allocate more storage than is supplied -* in the "data" pointer. This can cause access violations since -* astStore will then read beyond the end of the "data" area. -* 15-MAR-2005 (DSB): -* - Modified GridLines to use appropriate algorithm for choosing -* start of grid lines in cases where one axis has logarithmic tick -* spacing and the other has linear tick spacing. -* 21-MAR-2005 (DSB): -* - Added the Clip attribute. -* 12-JUL-2005 (DSB): -* - Modified AxPlot so that Map1 only normalises if neither axis -* is a SkyAxis. Previously it normalised if either axis was not a -* SkyAxis. -* 7-DEC-2005 (DSB): -* Free memory allocated by calls to astReadString. -* 18-JAN-2006 (DSB) -* Add Abbrev attribute. -* 14-FEB-2006 (DSB) -* Correct EdgeLabels to use gap size rather than EQUAL macro when -* comparing label values. -* 17-FEB-2006 (DSB) -* Added escape sequences "%h+" and "%g+". -* 21-MAR-2006 (DSB) -* Added extra status checks in TickMarks. -* 18-MAY-2006 (DSB) -* Trans: use correct PointSet when tranforming to arbitrary -* clipping frame. -* 26-MAY-2006 (DSB) -* Added LabelAt to TestAttrib. -* 2-JUN-2006 (DSB) -* - In MAKE_GET2, return the set value if a value has been set -* without recalculating the defaults. -* - Fix bug that could cause segvio in Grid if clipping is used. -* 5-JUN-2006 (DSB) -* Do not change the box returned by astBoundBox as a consequence -* of calling astGetAttrib. -* 19-JUN-2006 (DSB) -* Changed the default line 0.0 from zero to 1.0. -* 22-JUN-2006 (DSB) -* Include axis textual labels and title in the bounding box -* created by AST_GRID and returned by AST_BOUNDINGBOX. -* 26-JUN-2006 (DSB) -* Set the Direction attribute in the base Frame of a Plot if an -* axis is reversed. -* 29-JUN-2006 (DSB) -* - Guard against astGap calls that reach a minimum gap size. -* - Sort out splitting of long axis labels (such as date/time -* strings produced by TimeFrames). -* 30-JUN-2006 (DSB) -* If abbreviating labels, display the last field for identical -* neighbours rather than the whole value. -* 10-JUL-2006 (DSB) -* Make astStripEscapes public so it can be used by the NDF library. -* 7-AUG-2006 (DSB) -* Increase the number of attempts to find a new gap size from 5 to -* 25 in GetTicks. -* 24-OCT-2006 (DSB) -* Add the ForceExterior attribute so that SPLAT can have external -* axes even if there are no usable horizontal axis ticks (as requested -* by PWD). Currently this attribute is not included in the public -* documentation, as it may cause problems. If it seems to work OK -* then it can be made public. -* 25-JAN-2006 (DSB) -* Do not draw ticks marks that start outside the bounds of the -* axis they are labelling. -* 27-FEB-2007 (DSB) -* - Change nominal Crv_scerr value from 5.0 to 1.5 (this avoids gaps -* in HPX grid plots being bridged by grid lines). -* - Double the dimension of the grid used by GoodGrid to avoid -* missing the pointy bits in a HPX projection. -* 17-MAY-2007 (DSB) -* Exclude corner positions when determining the range of axis -* values covered by the plot. This gives better default gap sizes. -* 11-JUN-2007 (DSB) -* Plug memory leaks. -* 20-JUN-2007 (DSB) -* - Add attribute GrfContext. -* - Pass the GrfContext attribute value to each external grf function. -* External code that uses the astGrfSet function must be changed -* so that the external grf functions registered using astGrfSet -* accept this new parameter. -* 21-JUN-2007 (DSB) -* - Change GrfContext to be an Object rather than an integer. -* 22-JUN-2007 (DSB) -* - Do not dump the GrfContext Object since it may cause an -* infinite dumping loop. -* - Allow a NULL vtab to be supplied when initialising a Plot -* structure. This causes the vtab defined locally within this -* class to be used so that the new object behaves as a simple Plot. -* 25-JUN-2007 (DSB) -* - Free the graphics context object when then the Plot is deleted. -* - Fix memory leak in FullForm. -* - Since the grfcontext object is only used by external code, store -* a public object identifier for it in the Plot structure rather -* than a true C pointer. -* 26-JUN-2007 (DSB) -* Honour the LabelUp attribute value even if labels are drawn -* around the edges of the plot. -* 28-JUN-2007 (DSB) -* - Make all axis attribute arrays 3 elements long rather than 2. -* - Add the protected methods astCopyPlotDefaults and astMirror. -* - Add public method astGetGrfContext, remove astSetGrfContext. -* - Fix memory leak. -* 6-SEP-2007 (DSB): -* Dump and load any user-specified tick mark values. -* 20-OCT-2009 (DSB): -* - Modify SplitValue so that it only splits long values if -* previous long values were split, or if the value contains a -* space. -* - Take account of zero height bounding boxes in UpdateConcat. -* - Correct Dump so that it dumps attributes for all available -* axes (2 for a Plot, 3 for a Plot3D). -* 12-JAN-2010 (DSB): -* Fix various memory leaks. -* 4-MAR-2011 (DSB): -* - Added grf functions BBuf and EBuf. -* - Added public method astBBuf and astEBuf. -* 23-AUG-2011 (DSB): -* - If exterior labelling was requested but would produced too -* few labels, only swap to interior labelling if doing so would -* allow more labels to be drawn (i.e. do not swap to interior if -* it does not gain us anything). -* - Slightly decrease the dynamic range of an axis needed to produce -* logarithmic ticks (this is to avoid problems with round errors). -* 6-OCT-2011 (DSB): -* - Prevent grf qch and scales functions being called lots of times -* during each drawing operation (since the information returned by -* these functions will not change during the course of a single drawing -* operation). -* 11-OCT-2011 (DSB): -* - Combine multiple continuous polylines into a single polyline -* before calling the grf polyline function. Reducing the number of -* calls to the underlying graphics system can make a big difference -* if the graphics system is written in an interpreted language -* such as python. -* - Take account of differing axis scales when rotating vectors by -* 90 degrees. -* 12-OCT-2011 (DSB): -* - Fix the change made yesterday to correct rotation of numerical axis -* rotations. I forgot that the astGText function in the grf module -* expects the up vector in equally scaled coords, not graphics coords. -* - Take account of unequal axis scales when working out the -* length of each grid curve. -* 15-OCT-2011 (DSB): -* Always check that the grf module implements the scales function -* before trying to invoke the scales function. -* 21-MAY-2012 (DSB): -* Correct text strings used to represent the "Labelling" attribute -* within dumps of a Plot. Previously they were reversed. -* 7-JUN-2012 (DSB): -* Speed up plotting of CmpRegion boundaries by splitting the -* CmpRegion up into a set of disjoint Regions, and plotting each -* one separately. -* 16-JUN-2014 (DSB): -* - Prevent seg fault in PlotLabels caused by accessing -* uninitialised "atext" field stored within purged labels. -* - Choose a label with non-negative priority as the fall-back root label. -* 17-APR-2015 (DSB): -* Added method astRegionOutline. -* 20-APR-2015 (DSB): -* Draw Regions with higher accuracy, because Regions (i.e. Polygons) -* can be very non-smooth. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to the header - files that define class interfaces that they should make "protected" - symbols available. */ -#define astCLASS Plot - -/* Values for constants used in this class. */ -#define CRV_NSEG 14 /* No. of curve segments drawn by function Crv */ -#define CRV_NPNT 15 /* CRV_NSEG plus one */ -#define CRV_MXENT 10 /* Max. no. of recursive entries into function Crv */ -#define MAJTICKS_OPT 10 /* Optimum number of major axiss or grid lines */ -#define MAJTICKS_MAX 14 /* Max. number of major ticks or grid lines */ -#define MAJTICKS_MIN 6 /* Min. number of major ticks or grid lines */ -#define EDGETICKS_DIM 100 /* No. of edge samples used to find tick marks */ -#define LEFT 0 /* Id for the left edge of the plotting area */ -#define TOP 1 /* Id for the top edge of the plotting area */ -#define RIGHT 2 /* Id for the right edge of the plotting area */ -#define BOTTOM 3 /* Id for the bottom edge of the plotting area */ -#define NOSTYLE -999 /* A value which represents a null Style value */ -#define NOWIDTH -99.9 /* A value which represents a null Style value */ -#define NOFONT -999 /* A value which represents a null Style value */ -#define NOCOLOUR -999 /* A value which represents a null Style value */ -#define NOSIZE -99.9 /* A value which represents a null Style value */ - -#if defined(THREAD_SAFE) -#define GLOBALS_PROTO , AstGlobals * -#define GLOBALS_ARG , AstGlobals *AST__GLOBALS -#define GLOBALS_NAME , AST__GLOBALS -#else -#define GLOBALS_PROTO -#define GLOBALS_ARG -#define GLOBALS_NAME -#endif - -/* -* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a method to clear a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot.h" -* MAKE_CLEAR(attr,component,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstPlot *this, int axis ) -* -* and an external interface function of the form: -* -* void astClear_( AstPlot *this, int axis ) -* -* which implement a method for clearing a single value in a specified -* multi-valued attribute for an axis of a Plot. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. LabelAt in "astClearLabelAt"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attr,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstPlot *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astClear" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Assign the "clear" value. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attr##_( AstPlot *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,Plot,Clear##attr))( this, axis, status ); \ -} - - -/* -* -* Name: -* MAKE_GET - -* Purpose: -* Implement a method to get a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot.h" -* MAKE_GET(attr,type,bad_value,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( AstPlot *this, int axis ) -* -* and an external interface function of the form: -* -* astGet_( AstPlot *this, int axis ) -* -* which implement a method for getting a single value from a specified -* multi-valued attribute for an axis of a Plot. - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. This can -* use the string "axis" to represent the zero-based value index. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET(attr,type,bad_value,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attr( AstPlot *this, int axis, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Initialise */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astGet" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -type astGet##attr##_( AstPlot *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,Plot,Get##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_SET - -* Purpose: -* Implement a method to set a single value in a multi-valued attribute -* for a Plot. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot.h" -* MAKE_SET(attr,type,component,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstPlot *this, int axis, value ) -* -* and an external interface function of the form: -* -* void astSet_( AstPlot *this, int axis, value ) -* -* which implement a method for setting a single value in a specified -* multi-valued attribute for a Plot. - -* Parameters: -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. LabelAt in "astSetLabelAt"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET(attr,type,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstPlot *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astSet" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Store the new value in the structure component. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attr##_( AstPlot *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,Plot,Set##attr))( this, axis, value, status ); \ -} - -/* -* -* Name: -* MAKE_TEST - -* Purpose: -* Implement a method to test if a single value has been set in a -* multi-valued attribute for a class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot.h" -* MAKE_TEST(attr,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static int Test( AstPlot *this, int axis ) -* -* and an external interface function of the form: -* -* int astTest_( AstPlot *this, int axis ) -* -* which implement a method for testing if a single value in a specified -* multi-valued attribute has been set for a class. - -* Parameters: -* attr -* The name of the attribute to be tested, as it appears in the function -* name (e.g. LabelAt in "astTestLabelAt"). -* assign -* An expression that evaluates to 0 or 1, to be used as the returned -* value. This can use the string "axis" to represent the zero-based -* index of the value within the attribute. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_TEST(attr,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static int Test##attr( AstPlot *this, int axis, int *status ) { \ - int result; /* Value to return */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astTest" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -int astTest##attr##_( AstPlot *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,Plot,Test##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_GET3 - -* Purpose: -* Implement a method to get a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* MAKE_GET3(attr,attr,type,bad_value,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( AstPlot *this, int axis ) -* -* which implements a method for getting a single value from a specified -* multi-valued attribute for an axis of a Plot. Note, no public -* interface function is created. -* -* The value returned is the value which would actually be used if -* astGrid was called with the current set of Plot attributes. This -* includes calculating any dynamic defaults which would be used, and is -* consequently rather slow. - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). The -* string "Used" is added on to the front of the supplied value. -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. This can -* use the string "axis" to represent the zero-based value index. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET3(attr,type,bad_value,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type GetUsed##attr( AstPlot *, int, int *status ); \ -static type GetUsed##attr( AstPlot *this, int axis, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Initialise */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astGetUsed" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* If the attribute is set, use its normal accessor. */\ - } else if( astTest##attr( this, axis ) ) {\ - result = astGet##attr( this, axis );\ -\ -/* Otherwise, re-calculate dynamic defaults by going through the motions of \ - drawing the grid. Nothing is actually drawn because we set the protected \ - attribute Ink to zero first. The calculated values are stored in the \ - Plot structure. */ \ - } else { \ - astSetInk( this, 0 ); \ - astGrid( this ); \ - astClearInk( this ); \ -\ -/* Assign the result value. */ \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* -* Name: -* MAKE_SET3 - -* Purpose: -* Implement a method to set a single value in a multi-valued attribute -* for a Plot. This is identical to MAKE_SET except that no external -* interface function is created. - -* Type: -* Private macro. - -* Synopsis: -* MAKE_SET3(attr,type,component,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstPlot *this, int axis, value ) -* -* which implements a method for setting a single value in a specified -* multi-valued attribute for a Plot. - -* Parameters: - * attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astSetLabel"). The -* string "Used" is added on to the front of the supplied value. -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET3(attr,type,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void SetUsed##attr( AstPlot *, int, type, int *status ); \ -static void SetUsed##attr( AstPlot *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astSetUsed" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Store the new value in the structure component. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} - -/* -*+ -* Name: -* MAKE_GET2 - -* Purpose: -* Implement a method to get an attribute value for a class. - -* Type: -* Protected macro. - -* Synopsis: -* MAKE_GET2(class,attr,type,bad_value,assign) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static GetUsed( AstPlot *this ) -* -* which implement a method for getting a specified attribute value for a -* class. Note, no public interface function is created. -* -* The value returned is the value which would actually be used if -* astGrid was called with the current set of Plot attributes. This -* includes calculating any dynamic defaults which would be used, and is -* consequently rather slow. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). The -* string "Used" is added on to the front of the supplied value. -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_GET2(class,attr,type,bad_value,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type GetUsed##attr( Ast##class *, int *status ); \ -static type GetUsed##attr( Ast##class *this, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* If the attribute is set, use its normal accessor. */\ - if( astTest##attr( this ) ) {\ - result = astGet##attr( this );\ -\ -/* Otherwise, re-calculate dynamic defaults by going through the motions of \ - drawing the grid. Nothing is actually drawn because we set the protected \ - attribute Ink to zero first. The calculated values are stored in the \ - Plot structure. */ \ - } else { \ - astSetInk( this, 0 ); \ - astGrid( this ); \ - astClearInk( this ); \ -\ -/* Assign the result value. */ \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -*+ -* Name: -* MAKE_SET2 - -* Purpose: -* Implement a method to set an attribute value for a class. This -* is identical to astMAKE_SET except that it does not create an -* external interface function, and it does create a private function -* prototype. - -* Type: -* Protected macro. - -* Synopsis: -* MAKE_SET2(class,attr,type,component,assign) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void SetUsed( AstPlot *this, value ) -* -* which implements a method for setting a specified attribute value for a -* class. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. Label in "astSetLabel"). The string "Used" is added -* to the front. -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET2(class,attr,type,component,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void SetUsed##attr( Ast##class *, type, int *status ); \ -static void SetUsed##attr( Ast##class *this, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Store the new value in the structure component. */ \ - this->component = (assign); \ -} - - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ -#include "channel.h" /* I/O channels */ -#include "cmpmap.h" /* Compound mapping class */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "frame.h" /* Coordinate frame descriptions */ -#include "frameset.h" /* Parent FrameSet class */ -#include "grf.h" /* Low-level graphics interface */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "plot.h" /* Interface definition for this class */ -#include "pointset.h" /* Class holding lists of positions */ -#include "keymap.h" /* Hash maps */ -#include "skyaxis.h" /* Sky coordinate axes */ -#include "skyframe.h" /* Sky coordinate frames */ -#include "winmap.h" /* Scale and shift mappings */ -#include "mathmap.h" /* Algebraic mappings */ -#include "wcsmap.h" /* FITS-WCS projectsions */ -#include "unitmap.h" /* Unit mappings */ -#include "permmap.h" /* Axis permutations */ -#include "region.h" /* Frame regions */ -#include "globals.h" /* Thread-safe global data access */ - - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Module Type Definitions */ -/* ======================= */ -typedef struct LabelList { - double index; - char *text; - double x; - double y; - char *just; - double upx; - double upy; - double val; - int priority; - const char *atext; - int saved_prio; -} LabelList; - -/* Structure to hold static data used internally within the Crv function. */ -typedef struct CrvStatics { - double *pdl2; /* Pointer to next squared segment length */ - double *pdx; /* Pointer to next segment X increment */ - double *pdy; /* Pointer to next segment Y increment */ - double cosang; /* Cosine of angle between adjacent segments */ - double d0; /* Distance to start of first sub-segment */ - double delta; /* Distance between adjacent sub-segments */ - double dl; /* Segment length in graphics coordinates */ - double dll; /* Segment length for previous segment */ - double last_x; /* Graphics X at the end of the previous segment */ - double last_y; /* Graphics Y at the end of the previous segment */ - double limit2; /* Shortest acceptable squared segment length */ - double t1; /* Increment in X */ - double t2; /* Increment in Y */ - double t3; /* Squared segment length */ - double vx; /* X component of unit vector for current segment */ - double vxl; /* X component of unit vector for previous segment */ - double vy; /* Y component of unit vector for current segment */ - double vyl; /* Y component of unit vector for previous segment */ - int *seg0; /* Pointer to current segment OK flag */ - int *segm; /* Pointer to previous segment OK flag */ - int *segp; /* Pointer to next segment OK flag */ - int all_bad; /* Are all supplied positions bad or clipped? */ - int el; /* Total sub-segment count */ - int j; /* Sub-segment index */ - int last_ok; /* Was the previous position defined? */ - int nel; /* Total number of sub-segments */ - int nlong; /* No.of segments longer than limit2 */ - int nseg; /* Number of segments being sub-divided */ - int nshort; /* No.of segments shorter than limit2 */ - -#ifdef CRV_TRACE - int levels[100]; -#endif - -} CrvStatics; - -/* Structure to hold static data used internally within the Crv function. */ -typedef struct GetTicksStatics { - AstFrame *frame; /* Pointer to the current Frame */ - AstMapping *map; /* Pointer to Base->Current Mapping */ - AstPointSet *pset; /* Pointer to a PointSet holding physical coords */ - double **ptr; /* Pointer to physical coordinate values */ - double defgaps[ 2 ]; /* Initial test gaps for each axis */ - double typval[ 2 ]; /* Typical value on each axis */ - double width[ 2 ]; /* Range of used axis values */ - int maxticks; /* Max. number of ticks on each axis */ - int mintick; /* Min. number of ticks on each axis */ - int ngood[ 2 ]; /* No. of good physical values on each axis */ - int bad; /* Were any bad pixels found? */ -} GetTicksStatics; - -/* Structure to hold static data used internally within the EdgeCrossings - function. */ -typedef struct EdgeCrossingsStatics { - AstFrame *frame; /* Pointer to current Frame in Plot */ - AstPointSet *pset1; /* Graphics cooords at edge samples */ - AstPointSet *pset2; /* Physical cooords at edge samples */ - AstPointSet *pset4; /* Graphics cooords at offset edge samples */ - double **ptr1; /* Pointer to graphics coord. data */ - double **ptr2; /* Pointer to physical coord. data */ - double **ptr4; /* Pointer to graphics coord. data */ - double edgehi; /* High bound on varying graphics axis */ - double edgelo; /* Low bound on varying graphics axis */ - double edgeval; /* Constant graphics axis value along edge */ - double limit; /* Three times the RMS step size */ - int dim; /* Extended number of samples */ - int edgeax; /* Graphics axis to which edgeval refers */ - int paxis; /* Axis used in first invocation */ - int pedge; /* Edge used in first invocation */ -} EdgeCrossingsStatics; - - -/* Structure to hold static data used internally within the Map1 - function. */ -typedef struct Map1Statics { - AstPointSet *pset1; /* PointSet holding physical coords */ - AstPointSet *pset2; /* PointSet holding graphics coords */ - double **ptr1; /* Pointer to physical coord data */ - double *pax; /* Pointer to start of axis data */ - double *ptr2[ 2 ]; /* Pointers to graphics coord data */ - double *work1; /* Pointer to work space */ - double *work2; /* Pointer to work space */ - double axorig; /* Distance offset */ - double axscale; /* Distance scale */ - int neg; /* Negate axis values? */ - int nl; /* No. of points in pset1 and pset2 */ -} Map1Statics; - -/* Structure to hold static data used internally within the Map2 - function. */ -typedef struct Map2Statics { - AstPointSet *pset1; /* PointSet holding graphics coords */ - AstPointSet *pset2; /* PointSet holding physical coords */ - double **ptr2; /* Pointer to physical coord data */ - double *ptr1[ 2 ]; /* Pointers to graphics coord data */ - int nl; /* No. of points in pset1 and pset2 */ -} Map2Statics; - -/* Structure to hold static data used internally within the Map3 - function. */ -typedef struct Map3Statics { - AstPointSet *pset1; /* PointSet holding physical coords */ - AstPointSet *pset2; /* PointSet holding graphics coords */ - double **ptr1; /* Pointer to physical coord data */ - double *ptr2[ 2 ]; /* Pointers to graphics coord data */ - int nc; /* No. of physical axes */ - int nl; /* No. of points in pset1 and pset2 */ - double *pos; /* Pointer to memory for a single position */ -} Map3Statics; - -/* Structure to hold static data used internally within the Map4 - function. */ -typedef struct Map4Statics { - AstPointSet *pset1; /* PointSet holding distances */ - AstPointSet *pset2; /* PointSet holding physical coords */ - AstPointSet *pset3; /* PointSet holding graphics coords */ - int nl; /* No. of points in pset1 and pset2 */ -} Map4Statics; - -/* Structure to hold static data used internally within the Map5 - function. */ -typedef struct Map5Statics { - AstPointSet *pset1; /* PointSet holding physical coords */ - AstPointSet *pset2; /* PointSet holding graphics coords */ - double **ptr1; /* Pointer to physical coord data */ - double *ptr2[ 2 ]; /* Pointers to graphics coord data */ - int nl; /* No. of points in pset1 and pset2 */ -} Map5Statics; - -/* Structure to hold information about tick marks for a single axis. */ -typedef struct TickInfo{ - int nmajor; /* No. of major tick marks */ - int nminor; /* No. of minor tick marks */ - double *ticks; /* Pointer to array of major tick mark values */ - double *minticks; /* Pointer to array of minor tick mark values */ - char **labels; /* Pointer to array of major tick mark labels */ - double *start; /* Start pos'n on other axis for each curve section */ - double *length; /* Length on other axis of each curve section */ - int nsect; /* No. of sections in curve */ - char *fmt; /* Pointer to format string used to create labels */ - double gap; /* The gap between major ticks */ -} TickInfo; - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static void (* parent_removeframe)( AstFrameSet *, int, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, - AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Strings giving the label for the graphics items corresponding to - AST__BORDER_ID, AST__GRIDLINE_ID, etc. */ -static char *GrfLabels = "Border Curves Title Markers Strings Axis1 Axis2 Axis3 " - "NumLab1 NumLab2 NumLab3 TextLab1 TextLab2 TextLab3 " - "Ticks1 Ticks2 Ticks3 Grid1 Grid2 Grid3 Axes NumLab " - "TextLab Grid Ticks"; - -/* Text values used to represent edges externally. */ -static const char *xedge[4] = { "left", "top", "right", "bottom" }; - -/* Text values used to represent Labelling externally. */ -static const char *xlbling[2] = { "exterior", "interior" }; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GrfAttrs_nesting_t = 0; \ - globals->Crv_nent_t = 0; \ - globals->Box_lbnd_t[ 0 ] = FLT_MAX; \ - globals->Box_ubnd_t[ 0 ] = FLT_MIN; \ - globals->Boxp_lbnd_t[ 0 ] = FLT_MAX; \ - globals->Boxp_ubnd_t[ 0 ] = FLT_MIN; \ - globals->Box_lbnd_t[ 1 ] = FLT_MAX; \ - globals->Box_ubnd_t[ 1 ] = FLT_MIN; \ - globals->Boxp_lbnd_t[ 1 ] = FLT_MAX; \ - globals->Boxp_ubnd_t[ 1 ] = FLT_MIN; \ - globals->Boxp_freeze_t = 0; \ - globals->Map1_plot_t = NULL; \ - globals->Map1_map_t = NULL; \ - globals->Map1_frame_t = NULL; \ - globals->Map1_origin_t = NULL; \ - globals->Map1_statics_t = NULL; \ - globals->Map2_plot_t = NULL; \ - globals->Map2_map_t = NULL; \ - globals->Map2_statics_t = NULL; \ - globals->Map3_plot_t = NULL; \ - globals->Map3_map_t = NULL; \ - globals->Map3_frame_t = NULL; \ - globals->Map3_origin_t = NULL; \ - globals->Map3_end_t = NULL; \ - globals->Map3_statics_t = NULL; \ - globals->Map4_plot_t = NULL; \ - globals->Map4_map_t = NULL; \ - globals->Map4_umap_t = NULL; \ - globals->Map4_statics_t = NULL; \ - globals->Map5_plot_t = NULL; \ - globals->Map5_region_t = NULL; \ - globals->Map5_map_t = NULL; \ - globals->Map5_statics_t = NULL; \ - globals->Poly_n_t = 0; \ - globals->Poly_x_t = NULL; \ - globals->Poly_y_t = NULL; \ - globals->Poly_npoly_t = 0; \ - globals->Poly_np_t = NULL; \ - globals->Poly_xp_t = NULL; \ - globals->Poly_yp_t = NULL; \ - globals->Curve_data_t.nbrk = -1; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->SplitValue_Buff[ 0 ] = 0; \ - globals->StripEscapes_Buff[ 0 ] = 0; \ - globals->Grf_chv_t = AST__BAD; \ - globals->Grf_chh_t = AST__BAD; \ - globals->Grf_alpha_t = 0.0; \ - globals->Grf_beta_t = 0.0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Plot) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Plot,Class_Init) -#define class_vtab astGLOBAL(Plot,Class_Vtab) -#define grfattrs_nesting astGLOBAL(Plot,GrfAttrs_nesting_t) -#define grfattrs_attrs astGLOBAL(Plot,GrfAttrs_attrs_t) -#define Crv_limit astGLOBAL(Plot,Crv_limit_t) -#define Crv_scerr astGLOBAL(Plot,Crv_scerr_t) -#define Crv_tol astGLOBAL(Plot,Crv_tol_t) -#define Crv_ux0 astGLOBAL(Plot,Crv_ux0_t) -#define Crv_uy0 astGLOBAL(Plot,Crv_uy0_t) -#define Crv_vxl astGLOBAL(Plot,Crv_vxl_t) -#define Crv_vyl astGLOBAL(Plot,Crv_vyl_t) -#define Crv_xhi astGLOBAL(Plot,Crv_xhi_t) -#define Crv_xl astGLOBAL(Plot,Crv_xl_t) -#define Crv_xlo astGLOBAL(Plot,Crv_xlo_t) -#define Crv_yhi astGLOBAL(Plot,Crv_yhi_t) -#define Crv_yl astGLOBAL(Plot,Crv_yl_t) -#define Crv_ylo astGLOBAL(Plot,Crv_ylo_t) -#define Crv_vxbrk astGLOBAL(Plot,Crv_vxbrk_t) -#define Crv_vybrk astGLOBAL(Plot,Crv_vybrk_t) -#define Crv_xbrk astGLOBAL(Plot,Crv_xbrk_t) -#define Crv_ybrk astGLOBAL(Plot,Crv_ybrk_t) -#define Crv_len astGLOBAL(Plot,Crv_len_t) -#define Crv_ink astGLOBAL(Plot,Crv_ink_t) -#define Crv_nbrk astGLOBAL(Plot,Crv_nbrk_t) -#define Crv_nent astGLOBAL(Plot,Crv_nent_t) -#define Crv_out astGLOBAL(Plot,Crv_out_t) -#define Crv_clip astGLOBAL(Plot,Crv_clip_t) -#define Crv_map astGLOBAL(Plot,Crv_map_t) -#define Box_lbnd astGLOBAL(Plot,Box_lbnd_t) -#define Box_ubnd astGLOBAL(Plot,Box_ubnd_t) -#define Boxp_lbnd astGLOBAL(Plot,Boxp_lbnd_t) -#define Boxp_ubnd astGLOBAL(Plot,Boxp_ubnd_t) -#define Boxp_freeze astGLOBAL(Plot,Boxp_freeze_t) -#define Poly_x astGLOBAL(Plot,Poly_x_t) -#define Poly_y astGLOBAL(Plot,Poly_y_t) -#define Poly_n astGLOBAL(Plot,Poly_n_t) -#define Poly_xp astGLOBAL(Plot,Poly_xp_t) -#define Poly_yp astGLOBAL(Plot,Poly_yp_t) -#define Poly_np astGLOBAL(Plot,Poly_np_t) -#define Poly_npoly astGLOBAL(Plot,Poly_npoly_t) -#define Map1_ncoord astGLOBAL(Plot,Map1_ncoord_t) -#define Map1_plot astGLOBAL(Plot,Map1_plot_t) -#define Map1_map astGLOBAL(Plot,Map1_map_t) -#define Map1_frame astGLOBAL(Plot,Map1_frame_t) -#define Map1_origin astGLOBAL(Plot,Map1_origin_t) -#define Map1_length astGLOBAL(Plot,Map1_length_t) -#define Map1_axis astGLOBAL(Plot,Map1_axis_t) -#define Map1_statics astGLOBAL(Plot,Map1_statics_t) -#define Map1_norm astGLOBAL(Plot,Map1_norm_t) -#define Map1_log astGLOBAL(Plot,Map1_log_t) -#define Map2_ncoord astGLOBAL(Plot,Map2_ncoord_t) -#define Map2_plot astGLOBAL(Plot,Map2_plot_t) -#define Map2_map astGLOBAL(Plot,Map2_map_t) -#define Map2_x0 astGLOBAL(Plot,Map2_x0_t) -#define Map2_y0 astGLOBAL(Plot,Map2_y0_t) -#define Map2_deltax astGLOBAL(Plot,Map2_deltax_t) -#define Map2_deltay astGLOBAL(Plot,Map2_deltay_t) -#define Map2_statics astGLOBAL(Plot,Map1_statics_t) -#define Map3_ncoord astGLOBAL(Plot,Map3_ncoord_t) -#define Map3_plot astGLOBAL(Plot,Map3_plot_t) -#define Map3_map astGLOBAL(Plot,Map3_map_t) -#define Map3_frame astGLOBAL(Plot,Map3_frame_t) -#define Map3_origin astGLOBAL(Plot,Map3_origin_t) -#define Map3_end astGLOBAL(Plot,Map3_end_t) -#define Map3_scale astGLOBAL(Plot,Map3_scale_t) -#define Map3_statics astGLOBAL(Plot,Map3_statics_t) -#define Map4_ncoord astGLOBAL(Plot,Map4_ncoord_t) -#define Map4_plot astGLOBAL(Plot,Map4_plot_t) -#define Map4_map astGLOBAL(Plot,Map4_map_t) -#define Map4_umap astGLOBAL(Plot,Map4_umap_t) -#define Map4_statics astGLOBAL(Plot,Map4_statics_t) -#define Map5_plot astGLOBAL(Plot,Map5_plot_t) -#define Map5_region astGLOBAL(Plot,Map5_region_t) -#define Map5_map astGLOBAL(Plot,Map5_map_t) -#define Map5_ncoord astGLOBAL(Plot,Map5_ncoord_t) -#define Map5_statics astGLOBAL(Plot,Map5_statics_t) -#define Curve_data astGLOBAL(Plot,Curve_data_t) -#define getattrib_buff astGLOBAL(Plot,GetAttrib_Buff) -#define splitvalue_buff astGLOBAL(Plot,SplitValue_Buff) -#define stripescapes_buff astGLOBAL(Plot,StripEscapes_Buff) -#define Grf_chv astGLOBAL(Plot,Grf_chv_t) -#define Grf_chh astGLOBAL(Plot,Grf_chh_t) -#define Grf_alpha astGLOBAL(Plot,Grf_alpha_t) -#define Grf_beta astGLOBAL(Plot,Grf_beta_t) - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Variables used within astGrfAttrs_ */ -static double grfattrs_attrs[ GRF__NATTR ]; /* Saved attribute values */ -static int grfattrs_nesting = 0; /* Nesting level. */ - -/* Variables used to pass information to the curve drawing functions. See - the prologues of functions Crv and CrvLine for details. */ -static double Crv_limit; -static double Crv_scerr; -static double Crv_tol; -static double Crv_ux0; -static double Crv_uy0; -static double Crv_vxl; -static double Crv_vyl; -static double Crv_xhi; -static double Crv_xl; -static double Crv_xlo; -static double Crv_yhi; -static double Crv_yl; -static double Crv_ylo; -static float *Crv_vxbrk; -static float *Crv_vybrk; -static float *Crv_xbrk; -static float *Crv_ybrk; -static float Crv_len; -static int Crv_ink; -static int Crv_nbrk; -static int Crv_nent = 0; -static int Crv_out; -static int Crv_clip; -static void (*Crv_map)( int, double *, double *, double *, const char *, const char *, int * ); - -/* A cache of information calculated by the grf module. */ -static double Grf_chv = AST__BAD; -static double Grf_chh = AST__BAD; -static float Grf_alpha = 0.0; -static float Grf_beta = 0.0; - -/* The lower and upper bounds of the graphics coordinates enclosing all - lines and numerical labels drawn by astGrid. */ -static float Box_lbnd[ 2 ] = {FLT_MAX, FLT_MAX }; -static float Box_ubnd[ 2 ] = {FLT_MIN, FLT_MIN }; - -/* The lower and upper bounds of the graphics coordinates enclosing all - drawn graphics primatives, maintained by functions GLine, GMark and - DrawText. */ -static float Boxp_lbnd[ 2 ] = {FLT_MAX, FLT_MAX }; -static float Boxp_ubnd[ 2 ] = {FLT_MIN, FLT_MIN }; -static int Boxp_freeze = 0; - -/* Variables used to stored buffered poly lines (see functions Opoly, Bpoly - and Apoly). */ -static float *Poly_x = NULL; -static float *Poly_y = NULL; -static int Poly_n = 0; -static float **Poly_xp = NULL; -static float **Poly_yp = NULL; -static int *Poly_np = NULL; -static int Poly_npoly = 0; - -/* Variables used by function Map1. See the prologue of Map1 for details. */ -static int Map1_ncoord; -static AstPlot *Map1_plot = NULL; -static AstMapping *Map1_map = NULL; -static AstFrame *Map1_frame = NULL; -static const double *Map1_origin = NULL; -static double Map1_length; -static void *Map1_statics = NULL; -static int Map1_axis; -static int Map1_norm; -static int Map1_log; - -/* Variables used by function Map2. See the prologue of Map2 for details. */ -static int Map2_ncoord; -static AstPlot *Map2_plot = NULL; -static AstMapping *Map2_map = NULL; -static double Map2_x0; -static double Map2_y0; -static double Map2_deltax; -static double Map2_deltay; -static void *Map2_statics = NULL; - -/* Variables used by function Map3. See the prologue of Map3 for details. */ -static int Map3_ncoord; -static AstPlot *Map3_plot = NULL; -static AstMapping *Map3_map = NULL; -static AstFrame *Map3_frame = NULL; -static const double *Map3_origin = NULL; -static const double *Map3_end = NULL; -static double Map3_scale; -static void *Map3_statics = NULL; - -/* Variables used by function Map4. See the prologue of Map4 for details. */ -static int Map4_ncoord; -static AstPlot *Map4_plot = NULL; -static AstMapping *Map4_map = NULL; -static AstMapping *Map4_umap = NULL; -static void *Map4_statics = NULL; - -/* Variables used by function Map5. See the prologue of Map5 for details. */ -static AstPlot *Map5_plot = NULL; -static AstMapping *Map5_map = NULL; -static AstRegion *Map5_region = NULL; -static void *Map5_statics = NULL; -static int Map5_ncoord; - -/* A structure which stores information about the breaks in the last curve - drawn using the public methods "astGridLine" and "astCurve". */ -static AstPlotCurveData Curve_data; - -/* Buffers for strings returned by various functions. */ -static char splitvalue_buff[ 200 ]; -static char stripescapes_buff[ AST__PLOT_STRIPESCAPES_BUFF_LEN + 1 ]; -static char getattrib_buff[ 200 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPlotVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#endif - -/* Macro to reset the cache of values caclulated by the grf module. */ -#define RESET_GRF \ - Grf_chh = AST__BAD; \ - Grf_chv = AST__BAD; \ - Grf_alpha = 0.0; \ - Grf_beta = 0.0; - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ - -static double GetTol( AstPlot *, int * ); -static int TestTol( AstPlot *, int * ); -static void ClearTol( AstPlot *, int * ); -static void SetTol( AstPlot *, double, int * ); - -static int GetGrid( AstPlot *, int * ); -static int TestGrid( AstPlot *, int * ); -static void ClearGrid( AstPlot *, int * ); -static void SetGrid( AstPlot *, int, int * ); - -static int GetTickAll( AstPlot *, int * ); -static int TestTickAll( AstPlot *, int * ); -static void ClearTickAll( AstPlot *, int * ); -static void SetTickAll( AstPlot *, int, int * ); - -static int GetForceExterior( AstPlot *, int * ); -static int TestForceExterior( AstPlot *, int * ); -static void ClearForceExterior( AstPlot *, int * ); -static void SetForceExterior( AstPlot *, int, int * ); - -static int GetBorder( AstPlot *, int * ); -static int TestBorder( AstPlot *, int * ); -static void ClearBorder( AstPlot *, int * ); -static void SetBorder( AstPlot *, int, int * ); - -static int GetInvisible( AstPlot *, int * ); -static int TestInvisible( AstPlot *, int * ); -static void ClearInvisible( AstPlot *, int * ); -static void SetInvisible( AstPlot *, int, int * ); - -static int GetInk( AstPlot *, int * ); -static int TestInk( AstPlot *, int * ); -static void ClearInk( AstPlot *, int * ); -static void SetInk( AstPlot *, int, int * ); - -static int GetClipOp( AstPlot *, int * ); -static int TestClipOp( AstPlot *, int * ); -static void ClearClipOp( AstPlot *, int * ); -static void SetClipOp( AstPlot *, int, int * ); - -static int GetClip( AstPlot *, int * ); -static int TestClip( AstPlot *, int * ); -static void ClearClip( AstPlot *, int * ); -static void SetClip( AstPlot *, int, int * ); - -static int GetGrf( AstPlot *, int * ); -static int TestGrf( AstPlot *, int * ); -static void ClearGrf( AstPlot *, int * ); -static void SetGrf( AstPlot *, int, int * ); - -static int GetDrawTitle( AstPlot *, int * ); -static int TestDrawTitle( AstPlot *, int * ); -static void ClearDrawTitle( AstPlot *, int * ); -static void SetDrawTitle( AstPlot *, int, int * ); - -static int GetDrawAxes( AstPlot *, int, int * ); -static int TestDrawAxes( AstPlot *, int, int * ); -static void ClearDrawAxes( AstPlot *, int, int * ); -static void SetDrawAxes( AstPlot *, int, int, int * ); - -static int GetAbbrev( AstPlot *, int, int * ); -static int TestAbbrev( AstPlot *, int, int * ); -static void ClearAbbrev( AstPlot *, int, int * ); -static void SetAbbrev( AstPlot *, int, int, int * ); - -static int GetEscape( AstPlot *, int * ); -static int TestEscape( AstPlot *, int * ); -static void ClearEscape( AstPlot *, int * ); -static void SetEscape( AstPlot *, int, int * ); - -static double GetLabelAt( AstPlot *, int, int * ); -static int TestLabelAt( AstPlot *, int, int * ); -static void ClearLabelAt( AstPlot *, int, int * ); -static void SetLabelAt( AstPlot *, int, double, int * ); - -static double GetNumLabGap( AstPlot *, int, int * ); -static int TestNumLabGap( AstPlot *, int, int * ); -static void ClearNumLabGap( AstPlot *, int, int * ); -static void SetNumLabGap( AstPlot *, int, double, int * ); - -static double GetTextLabGap( AstPlot *, int, int * ); -static int TestTextLabGap( AstPlot *, int, int * ); -static void ClearTextLabGap( AstPlot *, int, int * ); -static void SetTextLabGap( AstPlot *, int, double, int * ); - -static double GetCentre( AstPlot *, int, int * ); -static int TestCentre( AstPlot *, int, int * ); -static void ClearCentre( AstPlot *, int, int * ); -static void SetCentre( AstPlot *, int, double, int * ); - -static double GetGap( AstPlot *, int, int * ); -static int TestGap( AstPlot *, int, int * ); -static void ClearGap( AstPlot *, int, int * ); -static void SetGap( AstPlot *, int, double, int * ); - -static int GetLabelling( AstPlot *, int * ); -static int TestLabelling( AstPlot *, int * ); -static void ClearLabelling( AstPlot *, int * ); -static void SetLabelling( AstPlot *, int, int * ); - -static double GetMajTickLen( AstPlot *, int, int * ); -static int TestMajTickLen( AstPlot *, int, int * ); -static void ClearMajTickLen( AstPlot *, int, int * ); -static void SetMajTickLen( AstPlot *, int, double, int * ); - -static double GetLogGap( AstPlot *, int, int * ); -static int TestLogGap( AstPlot *, int, int * ); -static void ClearLogGap( AstPlot *, int, int * ); -static void SetLogGap( AstPlot *, int, double, int * ); - -static double GetTitleGap( AstPlot *, int * ); -static int TestTitleGap( AstPlot *, int * ); -static void ClearTitleGap( AstPlot *, int * ); -static void SetTitleGap( AstPlot *, double, int * ); - -static double GetMinTickLen( AstPlot *, int, int * ); -static int TestMinTickLen( AstPlot *, int, int * ); -static void ClearMinTickLen( AstPlot *, int, int * ); -static void SetMinTickLen( AstPlot *, int, double, int * ); - -static int GetEdge( AstPlot *, int, int * ); -static int TestEdge( AstPlot *, int, int * ); -static void ClearEdge( AstPlot *, int, int * ); -static void SetEdge( AstPlot *, int, int, int * ); - -static int GetLabelUp( AstPlot *, int, int * ); -static int TestLabelUp( AstPlot *, int, int * ); -static void ClearLabelUp( AstPlot *, int, int * ); -static void SetLabelUp( AstPlot *, int, int, int * ); - -static int GetLogPlot( AstPlot *, int, int * ); -static int TestLogPlot( AstPlot *, int, int * ); -static void ClearLogPlot( AstPlot *, int, int * ); -static void SetLogPlot( AstPlot *, int, int, int * ); - -static int GetLogTicks( AstPlot *, int, int * ); -static int TestLogTicks( AstPlot *, int, int * ); -static void ClearLogTicks( AstPlot *, int, int * ); -static void SetLogTicks( AstPlot *, int, int, int * ); - -static int GetLogLabel( AstPlot *, int, int * ); -static int TestLogLabel( AstPlot *, int, int * ); -static void ClearLogLabel( AstPlot *, int, int * ); -static void SetLogLabel( AstPlot *, int, int, int * ); - -static int GetNumLab( AstPlot *, int, int * ); -static int TestNumLab( AstPlot *, int, int * ); -static void ClearNumLab( AstPlot *, int, int * ); -static void SetNumLab( AstPlot *, int, int, int * ); - -static int GetMinTick( AstPlot *, int, int * ); -static int TestMinTick( AstPlot *, int, int * ); -static void ClearMinTick( AstPlot *, int, int * ); -static void SetMinTick( AstPlot *, int, int, int * ); - -static int GetTextLab( AstPlot *, int, int * ); -static int TestTextLab( AstPlot *, int, int * ); -static void ClearTextLab( AstPlot *, int, int * ); -static void SetTextLab( AstPlot *, int, int, int * ); - -static int GetLabelUnits( AstPlot *, int, int * ); -static int TestLabelUnits( AstPlot *, int, int * ); -static void ClearLabelUnits( AstPlot *, int, int * ); -static void SetLabelUnits( AstPlot *, int, int, int * ); - -static int GetStyle( AstPlot *, int, int * ); -static int TestStyle( AstPlot *, int, int * ); -static void ClearStyle( AstPlot *, int, int * ); -static void SetStyle( AstPlot *, int, int, int * ); - -static int GetFont( AstPlot *, int, int * ); -static int TestFont( AstPlot *, int, int * ); -static void ClearFont( AstPlot *, int, int * ); -static void SetFont( AstPlot *, int, int, int * ); - -static int GetColour( AstPlot *, int, int * ); -static int TestColour( AstPlot *, int, int * ); -static void ClearColour( AstPlot *, int, int * ); -static void SetColour( AstPlot *, int, int, int * ); - -static double GetWidth( AstPlot *, int, int * ); -static int TestWidth( AstPlot *, int, int * ); -static void ClearWidth( AstPlot *, int, int * ); -static void SetWidth( AstPlot *, int, double, int * ); - -static double GetSize( AstPlot *, int, int * ); -static int TestSize( AstPlot *, int, int * ); -static void ClearSize( AstPlot *, int, int * ); -static void SetSize( AstPlot *, int, double, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static AstFrameSet *Fset2D( AstFrameSet *, int, int * ); -static AstKeyMap *GetGrfContext( AstPlot *, int * ); -static AstPlotCurveData **CleanCdata( AstPlotCurveData **, int * ); -static AstPlotCurveData **DrawGrid( AstPlot *, TickInfo **, int, const char *, const char *, int * ); -static AstPointSet *DefGap( AstPlot *, double *, int *, double *, int *, const char *, const char *, int * ); -static AstPointSet *GetDrawnTicks( AstPlot *, int, int, int * ); -static AstPointSet *Trans( AstPlot *, AstFrame *, AstMapping *, AstPointSet *, int, AstPointSet *, int, const char *, const char *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static TickInfo **CleanGrid( TickInfo **, int * ); -static TickInfo **GridLines( AstPlot *, double *, double *, int *, const char *, const char *, int * ); -static TickInfo *TickMarks( AstPlot *, int, double *, double *, int *, GetTicksStatics **, const char *, const char *, int * ); -static char **CheckLabels2( AstPlot *, AstFrame *, int, double *, int, char **, double, int * ); -static char *FindWord( char *, const char *, const char **, int * ); -static char *GrfItem( int, const char *, int *, int * ); -static const char *JustMB( AstPlot *, int, const char *, float *, float *, float, float, const char *, float, float, float, float, float *, float *, const char *, const char *, int * ); -static const char *SplitValue( AstPlot *, const char *, int, int *, int * ); -static double **MakeGrid( AstPlot *, AstFrame *, AstMapping *, int, int, double, double, double, double, int, AstPointSet **, AstPointSet**, int, const char *, const char *, int * ); -static double GetTicks( AstPlot *, int, double *, double **, int *, double **, int *, int, int *, double *, GetTicksStatics **, const char *, const char *, int * ); -static double GetUseSize( AstPlot *, int, int * ); -static double GetUseWidth( AstPlot *, int, int * ); -static double GoodGrid( AstPlot *, int *, AstPointSet **, AstPointSet **, const char *, const char *, int * ); -static double Typical( int, double *, double, double, double *, int * ); -static int Border( AstPlot *, int * ); -static int Boundary( AstPlot *, const char *, const char *, int * ); -static int BoxCheck( float *, float *, float *, float *, int * ); -static int CGAttrWrapper( AstPlot *, int, double, double *, int, int * ); -static int CGBBufWrapper( AstPlot *, int * ); -static int CGCapWrapper( AstPlot *, int, int, int * ); -static int CGEBufWrapper( AstPlot *, int * ); -static int CGFlushWrapper( AstPlot *, int * ); -static int CGLineWrapper( AstPlot *, int, const float *, const float *, int * ); -static int CGMarkWrapper( AstPlot *, int, const float *, const float *, int, int * ); -static int CGQchWrapper( AstPlot *, float *, float *, int * ); -static int CGScalesWrapper( AstPlot *, float *, float *, int * ); -static int CGTextWrapper( AstPlot *, const char *, float, float, const char *, float, float, int * ); -static int CGTxExtWrapper( AstPlot *, const char *, float, float, const char *, float, float, float *, float *, int * ); -static int CheckLabels( AstPlot *, AstFrame *, int, double *, int, int, char **, double, int * ); -static int ChrLen( const char *, int * ); -static int Compare_LL( const void *, const void * ); -static int Compared( const void *, const void * ); -static int CountGood( int, double *, int * ); -static int Cross( float, float, float, float, float, float, float, float, int * ); -static int CvBrk( AstPlot *, int, double *, double *, double *, int * ); -static int DrawRegion( AstPlot *, AstFrame *, const char *, const char *, int * ); -static int EdgeCrossings( AstPlot *, int, int, double, double *, double **, EdgeCrossingsStatics **, const char *, const char *, int * ); -static int EdgeLabels( AstPlot *, int, TickInfo **, AstPlotCurveData **, int, const char *, const char *, int * ); -static int FindDPTZ( AstFrame *, int, const char *, const char *, int *, int *, int * ); -static int FindMajTicks( AstMapping *, AstFrame *, int, double, double, double , double *, int, double *, double **, int * ); -static int FindMajTicks2( int, double, double, int, double *, double **, int * ); -static int FindString( int, const char *[], const char *, const char *, const char *, const char *, int * ); -static int Fpoly_ecmp( const void *, const void * ); -static int Fpoly_scmp( const void *, const void * ); -static int FullForm( const char *, const char *, const char *, const char *, const char *, int * ); -static int GCap( AstPlot *, int, int, int * ); -static int GVec( AstPlot *, AstMapping *, double *, int, double, AstPointSet **, AstPointSet **, double *, double *, double *, double *, int *, const char *, const char *, int * ); -static int GetUseColour( AstPlot *, int, int * ); -static int GetUseFont( AstPlot *, int, int * ); -static int GetUseStyle( AstPlot *, int, int * ); -static int GraphGrid( int, int, double, double, double, double, double **, int * ); -static int HasEscapes( const char *, int * ); -static int IdFind( int, int, int *, int *, int *, int * ); -static int Inside( int, float *, float *, float, float, int * ); -static int IsASkyAxis( AstFrame *, int, int * ); -static int IsASkyFrame( AstObject *, int * ); -static int Labelat( AstPlot *, TickInfo **, AstPlotCurveData **, double *, const char *, const char *, int * ); -static int Overlap( AstPlot *, int, int, const char *, float, float, const char *, float, float, float **, const char *, const char *, int * ); -static int PopGat( AstPlot *, float *, const char *, const char *, int * ); -static int TestUseColour( AstPlot *, int, int * ); -static int TestUseFont( AstPlot *, int, int * ); -static int TestUseSize( AstPlot *, int, int * ); -static int TestUseStyle( AstPlot *, int, int * ); -static int TestUseWidth( AstPlot *, int, int * ); -static int ToggleLogLin( AstPlot *, int, int, const char *, int * ); -static int TraceBorder( AstPlot *, AstMapping *, double, double, double, double, int, double, int[ 4 ], const char *, const char *, int * ); -static int Ustrcmp( const char *, const char *, int * ); -static int Ustrncmp( const char *, const char *, size_t, int * ); -static int swapEdges( AstPlot *, TickInfo **, AstPlotCurveData **, int * ); -static void AddCdt( AstPlotCurveData *, AstPlotCurveData *, const char *, const char *, int * ); -static void Apoly( AstPlot *, float, float, int * ); -static void AxPlot( AstPlot *, int, const double *, double, int, AstPlotCurveData *, const char *, const char *, int * ); -static void BBuf( AstPlot *, int * ); -static void BoundingBox( AstPlot *, float[2], float[2], int * ); -static void Bpoly( AstPlot *, float, float, int * ); -static void Clip( AstPlot *, int, const double [], const double [], int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void CopyPlotDefaults( AstPlot *, int, AstPlot *, int, int * ); -static void Crv( AstPlot *this, double *, double *, double *, int, double *, CrvStatics *, const char *, const char *, int * ); -static void CrvLine( AstPlot *this, double, double, double, double, const char *, const char *, int * ); -static void Curve( AstPlot *, const double [], const double [], int * ); -static void CurvePlot( AstPlot *, const double *, const double *, int , AstPlotCurveData *, const char *, const char *, int * ); -static void Delete( AstObject *, int * ); -static void DrawAxis( AstPlot *, TickInfo **, double *, double *, const char *, const char *, int * ); -static void DrawText( AstPlot *, int, int, const char *, float, float, const char *, float, float, float *, float *, float *, const char *, const char *, int * ); -static void DrawTicks( AstPlot *, TickInfo **, int, double *, double *, const char *, const char *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void EBuf( AstPlot *, int * ); -static void Fpoly( AstPlot *, const char *, const char *, int * ); -static void GAttr( AstPlot *, int, double, double *, int, const char *, const char *, int * ); -static void GBBuf( AstPlot *, const char *, const char *, int * )__attribute__((unused)); -static void GEBuf( AstPlot *, const char *, const char *, int * )__attribute__((unused)); -static void GFlush( AstPlot *, const char *, const char *, int * )__attribute__((unused)); -static void GLine( AstPlot *, int, const float *, const float *, const char *, const char *, int * ); -static void GMark( AstPlot *, int, const float *, const float *, int, const char *, const char *, int * ); -static void GQch( AstPlot *, float *, float *, const char *, const char *, int * ); -static void GScales( AstPlot *, float *, float *, const char *, const char *, int * ); -static void GText( AstPlot *, const char *, float, float, const char *, float, float, const char *, const char *, int * ); -static void GTxExt( AstPlot *, const char *, float , float, const char *, float, float, float *, float *, const char *, const char *, int * ); -static void GenCurve( AstPlot *, AstMapping *, int * ); -static void GrfPop( AstPlot *, int * ); -static void GrfPush( AstPlot *, int * ); -static void GrfSet( AstPlot *, const char *, AstGrfFun, int * ); -static void GrfWrapper( AstPlot *, const char *, AstGrfWrap, int * ); -static void Grid( AstPlot *, int * ); -static void GridLine( AstPlot *, int, const double [], double, int * ); -static void InterpEscape( AstPlot *, int, double, float *, float *, float, float, float, float, const char *, float *, double, double, double, double, double, const char *, const char *, int * ); -static void Labels( AstPlot *, TickInfo **, AstPlotCurveData **, double *, double *, const char *, const char *, int * ); -static void LinePlot( AstPlot *, double, double, double, double, int, AstPlotCurveData *, const char *, const char *, int * ); -static void Map1( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Map2( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Map3( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Map4( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Map5( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Mark( AstPlot *, int, int, int, const double *, int, int * ); -static void Mirror( AstPlot *, int, int * ); -static void Norm1( AstMapping *, int, int, double *, double, double, int * ); -static void Opoly( AstPlot *, int * ); -static void PlotLabels( AstPlot *, int, AstFrame *, int, LabelList *, char *, int, float **, const char *, const char *, int * ); -static void PolyCurve( AstPlot *, int, int, int, const double *, int * ); -static void PurgeCdata( AstPlotCurveData *, int * ); -static void PushGat( AstPlot *, float, const char *, const char *, int * ); -static void RegionOutline( AstPlot *, AstRegion *, int * ); -static void RemoveFrame( AstFrameSet *, int, int * ); -static void RightVector( AstPlot *, float *, float *, float *, float *, const char *, const char *, int * ); -static void SaveTick( AstPlot *, int, double, double, int, int * ); -static void SetTickValues( AstPlot *, int, int, double *, int, double *, int * ); -static void Text( AstPlot *, const char *, const double [], const float [], const char *, int * ); -static void TextLabels( AstPlot *, int, int *, const char *, const char *, int * ); -static void Ticker( AstPlot *, int, int, double, double *, double, int, int, EdgeCrossingsStatics **, const char *, const char *, int * ); -static void UpdateConcat( float *, float *, float, float, float, float, float *, float *, float, float, float *, float *, float *, float *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Functions which access class attributes. */ -/* ======================================= */ -/* Implement member functions to access the attributes associated with this - class using the macros defined for this purpose in the "object.h" file. For - a description of each attribute, see the class interface (in the associated - .h file). */ - -/* Tol. */ -/* ---- */ -/* -*att++ -* Name: -* Tol - -* Purpose: -* Plotting tolerance. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the plotting tolerance (or resolution) -* to be used for the graphical output produced by a Plot. Smaller -* values will result in smoother and more accurate curves being -* drawn, but may slow down the plotting process. Conversely, -* larger values may speed up the plotting process in cases where -* high resolution is not required. -* -* The Tol value should be given as a fraction of the minimum -* dimension of the plotting area, and should lie in the range -c from 1.0e-7 to 1.0. By default, a value of 0.01 is used. -f from 1.0E-7 to 1.0. By default, a value of 0.01 is used. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ -/* The plotting tolerance. Has a value of -1.0 when not set yielding a -default value of 0.01. Usable values are in the range 1.0E-7 to 1.0. */ -astMAKE_CLEAR(Plot,Tol,tol,-1.0) -astMAKE_GET(Plot,Tol,double,0.01,(this->tol == -1.0 ? 0.01 : this->tol)) -astMAKE_SET(Plot,Tol,double,tol,astMIN(astMAX(value,1.0E-7),1.0)) -astMAKE_TEST(Plot,Tol,( this->tol != -1.0 )) - -/* Grid. */ -/* ----- */ -/* -*att++ -* Name: -* Grid - -* Purpose: -* Draw grid lines for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether grid lines (a grid of curves marking the "major" values -* on each axis) are drawn across the plotting area. -* -* If the Grid value of a Plot is non-zero, then grid lines will be -* drawn. Otherwise, short tick marks on the axes are used to mark -* the major axis values. The default behaviour is to use tick -* marks if the entire plotting area is filled by valid physical -* coordinates, but to draw grid lines otherwise. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The spacing between major axis values, which determines the -* spacing of grid lines, may be set using the Gap(axis) attribute. -*att-- -*/ -/* If non-zero use lines instead of tick marks in a coordinate grid. Has a -value of -1 when not set yielding a default value of 0. */ -astMAKE_CLEAR(Plot,Grid,grid,-1) -astMAKE_GET(Plot,Grid,int,0,(this->grid == -1 ? 0 : this->grid)) -astMAKE_SET(Plot,Grid,int,grid,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Grid,( this->grid != -1 )) - -MAKE_GET2(Plot,Grid,int,0,this->ugrid) -MAKE_SET2(Plot,Grid,int,ugrid,( value ? 1 : 0 )) - -/* Invisible. */ -/* ---------- */ -/* -*att++ -* Name: -* Invisible - -* Purpose: -* Draw graphics using invisible ink? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of all graphics produced by -* Plot methods by determining whether graphics should be visible or -* invisible. -* -* If the Invisible value of a Plot is non-zero, then all the Plot -* methods which normally generate graphical output do not do so (you -* can think of them drawing with "invisible ink"). Such methods do, -* however, continue to do all the calculations which would be needed to -* produce the graphics. In particular, the bounding box enclosing the -* graphics is still calculated and can be retrieved as normal using -c astBoundingBox. The default value is zero, resulting in all methods -f AST_BOUNDINGBOX. The default value is zero, resulting in all methods -* drawing graphics as normal, using visible ink. - -* Applicability: -* Plot -* All Plots have this attribute. - -*att-- -*/ -/* If non-zero use invisible ink. Has a value of -1 when not set yielding -a default value of 0. */ -astMAKE_CLEAR(Plot,Invisible,invisible,-1) -astMAKE_GET(Plot,Invisible,int,0,(this->invisible == -1 ? 0 : this->invisible)) -astMAKE_SET(Plot,Invisible,int,invisible,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Invisible,( this->invisible != -1 )) - -/* TickAll */ -/* ------- */ -/* -*att++ -* Name: -* TickAll - -* Purpose: -* Draw tick marks on all edges of a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether tick marks should be drawn on all edges of a Plot. -* -* If the TickAll value of a Plot is non-zero (the default), then -* tick marks will be drawn on all edges of the Plot. Otherwise, -* they will be drawn only on those edges where the numerical and -* descriptive axis labels are drawn (see the Edge(axis) -* attribute). - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - In some circumstances, numerical labels and tick marks are -* drawn along grid lines inside the plotting area, rather than -* around its edges (see the Labelling attribute). In this case, -* the value of the TickAll attribute is ignored. -*att-- -*/ -/* If non-zero put tick marks on opposite edges. Has a value of -1 when not -set yielding a default value of 1. */ -astMAKE_CLEAR(Plot,TickAll,tickall,-1) -astMAKE_GET(Plot,TickAll,int,1,(this->tickall == -1 ? 1 : this->tickall)) -astMAKE_SET(Plot,TickAll,int,tickall,( value ? 1 : 0 )) -astMAKE_TEST(Plot,TickAll,( this->tickall != -1 )) - -/* ForceExterior */ -/* ------------- */ -/* -*att+ -* Name: -* ForceExterior - -* Purpose: -* Force the use of exterior labelling? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by forcing -f coordinate grid (drawn with the AST_GRID routine) by forcing -* labels and tick marks to be drawn round the edges of the plot -* (rather than across the middle of the plot), even if there appear -* to be insufficient edge crossings to justify the use of exterior -* labelling. -* -* The default value of zero results in the decision about whether to -* use interior or exterior labelling being made purely on the basis -* of the value of the Labelling attribute. If ForceExterior is set to -* a non-zero value, then the Labelling attribute is ignored and exterior -* labelling will always be attempted, even if there appear to be -* insufficient edge labels to justify their use. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The value of this attribute is currently under investigation, and -* so this attribute prologue is currently marked as protected rather -* than public (in order to prevent it being included in the public -* documentation). -*att- -*/ -astMAKE_CLEAR(Plot,ForceExterior,forceexterior,-1) -astMAKE_GET(Plot,ForceExterior,int,0,(this->forceexterior == -1 ? 0 : this->forceexterior)) -astMAKE_SET(Plot,ForceExterior,int,forceexterior,( value ? 1 : 0 )) -astMAKE_TEST(Plot,ForceExterior,( this->forceexterior != -1 )) - -/* -*att++ -* Name: -* Border - -* Purpose: -* Draw a border around valid regions of a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether a border is drawn around regions corresponding to the -c valid physical coordinates of a Plot (c.f. astBorder). -f valid physical coordinates of a Plot (c.f. AST_BORDER). -* -* If the Border value of a Plot is non-zero, then this border will -* be drawn as part of the grid. Otherwise, the border is not drawn -* (although axis labels and tick marks will still appear, unless -* other relevant Plot attributes indicate that they should -* not). The default behaviour is to draw the border if tick marks -* and numerical labels will be drawn around the edges of the -* plotting area (see the Labelling attribute), but to omit it -* otherwise. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ -/* If non-zero draw the border. Has a value of -1 when not set, yeilding - a default of 1. */ -astMAKE_CLEAR(Plot,Border,border,-1) -astMAKE_SET(Plot,Border,int,border,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Border,( this->border != -1 )) -astMAKE_GET(Plot,Border,int,1,(this->border == -1 ? 1 : this->border)) - -MAKE_SET2(Plot,Border,int,uborder,( value ? 1 : 0 )) -MAKE_GET2(Plot,Border,int,1,this->uborder) - -/* Clip */ -/* ---- */ -/* -*att++ -* Name: -* Clip - -* Purpose: -* Clip lines and/or markers at the Plot boundary? - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute controls whether curves and markers are clipped at the -* boundary of the graphics box specified when the Plot was created. A -* value of 3 implies both markers and curves are clipped at the Plot -* boundary. A value of 2 implies markers are clipped, but not curves. A -* value of 1 implies curves are clipped, but not markers. A value of -* zero implies neither curves nor markers are clipped. The default -* value is 1. Note, this attributes controls only the clipping -* performed internally within AST. The underlying graphics system may -* also apply clipping. In such cases, removing clipping using this -* attribute does not guarantee that no clipping will be visible in the -* final plot. -* -c The astClip function -f The AST_CLIP routine -* can be used to establish generalised clipping within arbitrary -* regions of the Plot. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ -astMAKE_CLEAR(Plot,Clip,clip,-1) -astMAKE_GET(Plot,Clip,int,0,(this->clip == -1 ? 1 : this->clip)) -astMAKE_TEST(Plot,Clip,( this->clip != -1 )) -astMAKE_SET(Plot,Clip,int,clip,((value>=0&&value<=3)?value:(astError( AST__ATTIN, "astSetClip(Plot): Invalid value %d supplied for Clip attribute", status, value ), this->clip))) - -/* ClipOp */ -/* ------ */ -/* -*att++ -* Name: -* ClipOp - -* Purpose: -* Combine Plot clipping limits using a boolean OR? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls how the clipping limits specified for -c each axis of a Plot (using the astClip function) are -f each axis of a Plot (using the AST_CLIP routine) are -* combined. This, in turn, determines which parts of the graphical -* output will be visible. -* -* If the ClipOp attribute of a Plot is zero (the default), -* graphical output is visible only if it satisfies the clipping -* limits on all the axes of the clipping Frame (a boolean -* AND). Otherwise, if ClipOp is non-zero, output is visible if it -* satisfies the clipping limits on one or more axes (a boolean -* OR). -* -* An important use of this attribute is to allow areas of a Plot -* to be left clear (e.g. as a background for some text). To -* achieve this, the lower and upper clipping bounds supplied to -c astClip should be reversed, and the ClipOp attribute of the -f AST_CLIP should be reversed, and the ClipOp attribute of the -* Plot should be set to a non-zero value. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ -/* If non-zero only 1axis need be within the clipping bounds to avoid a -point being clipped. Otherwise, all axes must be within bounds. */ -astMAKE_CLEAR(Plot,ClipOp,clipop,-1) -astMAKE_GET(Plot,ClipOp,int,0,(this->clipop == -1 ? 0 : this->clipop)) -astMAKE_SET(Plot,ClipOp,int,clipop,( value ? 1 : 0 )) -astMAKE_TEST(Plot,ClipOp,( this->clipop != -1 )) - -/* Grf. */ -/* ---- */ -/* -*att++ -* Name: -* Grf - -* Purpose: -c Use Grf functions registered through astGrfSet? -f Use Grf routines registered through AST_GRFSET? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -c This attribute selects the functions which are used to draw graphics by -c the Plot class. If it is zero, then the functions in the graphics -c interface selected at link-time are used (see the ast_link script). -c Otherwise, functions registered using astGrfSet are used. In this -c case, if a function is needed which has not been registered, -c then the function in the graphics interface selected at link-time is -c used. -f This attribute selects the routines which are used to draw graphics by -f the Plot class. If it is zero, then the routines in the graphics -f interface selected at link-time are used (see the ast_link script). -f Otherwise, routines registered using AST_GRFSET are used. In this -f case, if a routine is needed which has not been registered, -f then the routine in the graphics interface selected at link-time is -f used. - -* The default is to use the graphics interface - -* Applicability: -* Plot -* All Plots have this attribute. -* Plot3D -* The Plot3D class ignores this attributes, assuming a value of -* zero. - -* Notes: -* - The value of this attribute is not saved when the Plot is written -* out through a Channel to an external data store. On re-loading such -c a Plot using astRead, the attribute will be cleared, resulting in the -f a Plot using AST_READ, the attribute will be cleared, resulting in the -* graphics interface selected at link-time being used. - -*att-- -*/ -/* Use Grf routines registered using astGrfSet? Has a -value of -1 when not set yielding a default of 0. */ -astMAKE_CLEAR(Plot,Grf,grf,-1) -astMAKE_GET(Plot,Grf,int,0,(this->grf == -1 ? 0 : this->grf)) -astMAKE_SET(Plot,Grf,int,grf,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Grf,( this->grf != -1 )) - -/* DrawTitle */ -/* --------- */ -/* -*att++ -* Name: -* DrawTitle - -* Purpose: -* Draw a title for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether a title is drawn. -* -* If the DrawTitle value of a Plot is non-zero (the default), then -* the title will be drawn, otherwise it will be omitted. - -* Applicability: -* Plot -* All Plots have this attribute. -* Plot3D -* The Plot3D class ignores this attributes, assuming a value of -* zero. - -* Notes: -* - The text used for the title is obtained from the Plot's Title -* attribute. -* - The vertical placement of the title can be controlled using -* the TitleGap attribute. -*att-- -*/ -/* If non-zero add a title to the grid. Has a value of -1 when not -set yielding a default value of 1. */ -astMAKE_CLEAR(Plot,DrawTitle,drawtitle,-1) -astMAKE_GET(Plot,DrawTitle,int,1,(this->drawtitle == -1 ? 1 : this->drawtitle)) -astMAKE_SET(Plot,DrawTitle,int,drawtitle,( value ? 1 : 0 )) -astMAKE_TEST(Plot,DrawTitle,( this->drawtitle != -1 )) - -/* LabelUp. */ -/* ------- */ -/* -*att++ -* Name: -* LabelUp(axis) - -* Purpose: -* Draw numerical Plot labels upright? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether the numerical labels for each axis of a Plot should be -* drawn upright or not. It takes a separate value for each -* physical axis of a Plot so that, for instance, the setting -* "LabelUp(2)=1" specifies that numerical labels for the second -* axis should be drawn upright. -* -* If the LabelUp value of a Plot axis is non-zero, it causes -* numerical labels for that axis to be plotted upright (i.e. as -* normal, horizontal text), otherwise labels are drawn parallel to -* the axis to which they apply. -* -* The default is to produce upright labels if the labels are placed -* around the edge of the plot, and to produce labels that follow the -* axes if the labels are placed within the interior of the plot (see -* attribute Labelling). - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - In some circumstances, numerical labels and tick marks are -* drawn around the edges of the plotting area (see the Labelling -* attribute). In this case, the value of the LabelUp attribute is -* ignored. -* - If no axis is specified, (e.g. "LabelUp" instead of -* "LabelUp(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the LabelUp(1) value. -*att-- -*/ -/* Are numerical labels to be displayed on each axis? Has a value of -1 when -not set yielding a value of 0 (no) for both axes. */ -MAKE_CLEAR(LabelUp,labelup,-1,0) -MAKE_GET(LabelUp,int,0,( this->labelup[axis] == -1 ? 0 : this->labelup[axis] ),0) -MAKE_TEST(LabelUp,( this->labelup[axis] != -1 ),0) -MAKE_SET(LabelUp,int,labelup,( value ? 1 : 0 ),0) - -/* DrawAxes */ -/* -------- */ -/* -*att++ -* Name: -* DrawAxes(axis) - -* Purpose: -* Draw axes for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether curves representing coordinate axes should be drawn. -* It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "DrawAxes(2)=0" -* specifies that no axis should be drawn for the second axis. -* -* If drawn, these axis lines will pass through any tick marks -* associated with numerical labels drawn to mark values on the -* axes. The location of these tick marks and labels (and hence the -* axis lines) is determined by the Plot's LabelAt(axis) attribute. -* -* If the DrawAxes value of a Plot is non-zero (the default), then -* axis lines will be drawn, otherwise they will be omitted. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - Axis lines are drawn independently of any coordinate grid -* lines (see the Grid attribute) so grid lines may be used to -* substitute for axis lines if required. -* - In some circumstances, numerical labels and tick marks are -* drawn around the edges of the plotting area (see the Labelling -* attribute). In this case, the value of the DrawAxes attribute -* is ignored. -* - If no axis is specified, (e.g. "DrawAxes" instead of -* "DrawAxes(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the DrawAxes(1) value. -*att-- -*/ -/* If non-zero draw a curve through the tick marks. Has a value of -1 - when not set yielding a default value of 1. */ -MAKE_CLEAR(DrawAxes,drawaxes,-1,0) -MAKE_GET(DrawAxes,int,1,( this->drawaxes[axis] == -1 ? 1 : this->drawaxes[axis] ),0) -MAKE_TEST(DrawAxes,( this->drawaxes[axis] != -1 ),0) -MAKE_SET(DrawAxes,int,drawaxes,( value ? 1 : 0 ),0) - -/* Abbrev */ -/* -------- */ -/* -*att++ -* Name: -* Abbrev(axis) - -* Purpose: -* Abbreviate leading fields within numerical axis labels? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether matching leading fields should be removed from adjacent -* numerical axis labels. It takes a separate value for each physical -* axis of a Plot so that, for instance, the setting "Abbrev(2)=0" -* specifies that matching leading fields should not be removed on -* the second axis. -* -* If the Abbrev value of a Plot is non-zero (the default), then -* leading fields will be removed from adjacent axis labels if they -* are equal. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "Abbrev" instead of -* "Abbrev(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the Abbrev(1) value. -*att-- -*/ -MAKE_CLEAR(Abbrev,abbrev,-1,0) -MAKE_GET(Abbrev,int,1,( this->abbrev[axis] == -1 ? 1 : this->abbrev[axis] ),0) -MAKE_TEST(Abbrev,( this->abbrev[axis] != -1 ),0) -MAKE_SET(Abbrev,int,abbrev,( value ? 1 : 0 ),0) - -/* Escape. */ -/* ------- */ -/* -*att++ -* Name: -* Escape - -* Purpose: -* Allow changes of character attributes within strings? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of text strings and numerical -c labels drawn by the astGrid and (for the Plot class) astText functions, -f labels drawn by the AST_GRID and (for the Plot class) AST_TEXT routines, -* by determining if any escape sequences contained within the strings -* should be used to control the appearance of the text, or should -* be printed literally. Note, the Plot3D class only interprets escape -* sequences within the -c astGrid function. -f AST_GRID routine. -* -* If the Escape value of a Plot is one (the default), then any -* escape sequences in text strings produce the effects described -* below when printed. Otherwise, they are printed literally. -* -c See also the astEscapes function. -f See also the AST_ESCAPES function. - -* Escape Sequences: -* Escape sequences are introduced into the text string by a percent -* "%" character. Any unrecognised, illegal or incomplete escape sequences -* are printed literally. The following escape sequences are -* currently recognised ("..." represents a string of one or more -* decimal digits): -* -* %% - Print a literal "%" character. -* -* %^...+ - Draw subsequent characters as super-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the super-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* %^+ - Draw subsequent characters with the normal base-line. -* -* %v...+ - Draw subsequent characters as sub-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the sub-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %v+ - Draw subsequent characters with the normal base-line -* (equivalent to %^+). -* -* %>...+ - Leave a gap before drawing subsequent characters. -* The digits "..." give the size of the gap, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %<...+ - Move backwards before drawing subsequent characters. -* The digits "..." give the size of the movement, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %s...+ - Change the Size attribute for subsequent characters. The -* digits "..." give the new Size as a fraction of the -* "normal" Size, scaled so that a value of "100" corresponds -* to 1.0; -* -* %s+ - Reset the Size attribute to its "normal" value. -* -* %w...+ - Change the Width attribute for subsequent characters. The -* digits "..." give the new width as a fraction of the -* "normal" Width, scaled so that a value of "100" corresponds -* to 1.0; -* -* %w+ - Reset the Size attribute to its "normal" value. -* -* %f...+ - Change the Font attribute for subsequent characters. The -* digits "..." give the new Font value. -* -* %f+ - Reset the Font attribute to its "normal" value. -* -* %c...+ - Change the Colour attribute for subsequent characters. The -* digits "..." give the new Colour value. -* -* %c+ - Reset the Colour attribute to its "normal" value. -* -* %t...+ - Change the Style attribute for subsequent characters. The -* digits "..." give the new Style value. -* -* %t+ - Reset the Style attribute to its "normal" value. -* -* %h+ - Remember the current horizontal position (see "%g+") -* -* %g+ - Go to the horizontal position of the previous "%h+" (if any). -* -* %- - Push the current graphics attribute values onto the top of -* the stack (see "%+"). -* -* %+ - Pop attributes values of the top the stack (see "%-"). If -* the stack is empty, "normal" attribute values are restored. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ - -/* Has a value of -1 when not set yeilding a default of 1. */ -astMAKE_GET(Plot,Escape,int,1,(this->escape == -1 ? 1 : this->escape)) -astMAKE_CLEAR(Plot,Escape,escape,-1) -astMAKE_SET(Plot,Escape,int,escape,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Escape,( this->escape != -1 )) - -/* LabelAt(axis). */ -/* -------------- */ -/* -*att++ -* Name: -* LabelAt(axis) - -* Purpose: -* Where to place numerical labels for a Plot - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* where numerical axis labels and associated tick marks are -* placed. It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "LabelAt(2)=10.0" -* specifies where the numerical labels and tick marks for the -* second axis should be drawn. -* -* For each axis, the LabelAt value gives the value on the other -* axis at which numerical labels and tick marks should be placed -c (remember that Plots suitable for use with astGrid may only -f (remember that Plots suitable for use with AST_GRID may only -* have two axes). For example, in a celestial (RA,Dec) coordinate -* system, LabelAt(1) gives a Dec value which defines a line (of -* constant Dec) along which the numerical RA labels and their -* associated tick marks will be drawn. Similarly, LabelAt(2) gives -* the RA value at which the Dec labels and ticks will be drawn. -* -* The default bahaviour is for the Plot to generate its own -* position for numerical labels and tick marks. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The LabelAt value should use the same units as are used -* internally for storing coordinate values on the appropriate -* axis. For example, with a celestial coordinate system, the -* LabelAt value should be in radians, not hours or degrees. -* - Normally, the LabelAt value also determines where the lines -* representing coordinate axes will be drawn, so that the tick -* marks will lie on these lines (but also see the DrawAxes -* attribute). -* - In some circumstances, numerical labels and tick marks are -* drawn around the edges of the plotting area (see the Labelling -* attribute). In this case, the value of the LabelAt attribute is -* ignored. -*att-- -*/ -/* The constant value on the other axis at which to place labels for - each axis. */ -MAKE_CLEAR(LabelAt,labelat,AST__BAD,0) -MAKE_GET(LabelAt,double,AST__BAD,this->labelat[axis],0) -MAKE_SET(LabelAt,double,labelat,value,0) -MAKE_TEST(LabelAt,( this->labelat[axis] != AST__BAD ),0) - -MAKE_GET3(LabelAt,double,AST__BAD,this->ulblat[axis],0) -MAKE_SET3(LabelAt,double,ulblat,value,0) - -/* Centre(axis). */ -/* ------------ */ -/* A value at which to place a tick mark. Other ticks marks are spaced at -regular distances from this one. AST__BAD is stored if no value is supplied, -resulting in Plot choosing its own value. */ -MAKE_CLEAR(Centre,centre,AST__BAD,0) -MAKE_GET(Centre,double,AST__BAD,this->centre[axis],0) -MAKE_SET(Centre,double,centre,value,0) -MAKE_TEST(Centre,( this->centre[axis] != AST__BAD ),0) - -MAKE_GET3(Centre,double,AST__BAD,this->ucentre[axis],0) -MAKE_SET3(Centre,double,ucentre,value,0) - -/* Ink */ -/* --- */ -/* A protected attribute indicating if astGrid should draw using visible -ink. The unset value is -1, yeilding a default value of 1. */ -astMAKE_CLEAR(Plot,Ink,ink,-1) -astMAKE_GET(Plot,Ink,int,1,(this->ink == -1 ? 1 : this->ink)) -astMAKE_SET(Plot,Ink,int,ink,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Ink,( this->ink != -1 )) - -/* Gap(axis). */ -/* ---------- */ -/* -*att++ -* Name: -* Gap(axis) - -* Purpose: -* Interval between linearly spaced major axis values of a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the linear interval between the "major" axis values of a Plot, at -* which (for example) major tick marks are drawn. It takes a separate -* value for each physical axis of the Plot so that, for instance, -* the setting "Gap(2)=3.0" specifies the difference between adjacent major -* values along the second axis. The Gap attribute is only used when -* the LogTicks attribute indicates that the spacing between major axis -* values is to be linear. If major axis values are logarithmically spaced -* then the gap is specified using attribute LogGap. -* -* The Gap value supplied will usually be rounded to the nearest -* "nice" value, suitable (e.g.) for generating axis labels, before -* use. To avoid this "nicing" you should set an explicit format -* for the axis using the Format(axis) or Digits/Digits(axis) -* attribute. The default behaviour is for the Plot to generate its -* own Gap value when required, based on the range of axis values -* to be represented. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The Gap value should use the same units as are used internally -* for storing coordinate values on the corresponding axis. For -* example, with a celestial coordinate system, the Gap value -* should be in radians, not hours or degrees. -* - If no axis is specified, (e.g. "Gap" instead of "Gap(2)"), -* then a "set" or "clear" operation will affect the attribute -* value of all the Plot axes, while a "get" or "test" operation -* will use just the Gap(1) value. -*att-- -*/ -/* The gap between tick marks on each axis. AST__BAD is stored if no -value has been supplied, resulting in default values being found. */ -MAKE_CLEAR(Gap,gap,AST__BAD,0) -MAKE_SET(Gap,double,gap,value,0) -MAKE_TEST(Gap,( this->gap[axis] != AST__BAD ),0) -MAKE_GET(Gap,double,AST__BAD,this->gap[axis],0) - -MAKE_SET3(Gap,double,ugap,value,0) -MAKE_GET3(Gap,double,AST__BAD,this->ugap[axis],0) - -/* LogGap(axis). */ -/* ---------- */ -/* -*att++ -* Name: -* LogGap(axis) - -* Purpose: -* Interval between major axis values of a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the logarithmic interval between the "major" axis values of a Plot, at -* which (for example) major tick marks are drawn. It takes a separate -* value for each physical axis of the Plot so that, for instance, -* the setting "LogGap(2)=100.0" specifies the ratio between adjacent major -* values along the second axis. The LogGap attribute is only used when -* the LogTicks attribute indicates that the spacing between major axis -* values is to be logarithmic. If major axis values are linearly spaced -* then the gap is specified using attribute Gap. -* -* The LogGap value supplied will be rounded to the nearest power of 10. -* The reciprocal of the supplied value may be used if this is necessary -* to produce usable major axis values. If a zero or negative value is -* supplied, an error will be reported when the grid is drawn. The default -* behaviour is for the Plot to generate its own LogGap value when -* required, based on the range of axis values to be represented. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The LogGap value is a ratio between axis values and is therefore -* dimensionless. -* - If no axis is specified, (e.g. "LogGap" instead of "LogGap(2)"), -* then a "set" or "clear" operation will affect the attribute -* value of all the Plot axes, while a "get" or "test" operation -* will use just the LogGap(1) value. -*att-- -*/ -/* The logarithmic gap between tick marks on each axis. AST__BAD is stored if - no value has been supplied, resulting in default values being found. */ -MAKE_CLEAR(LogGap,loggap,AST__BAD,0) -MAKE_SET(LogGap,double,loggap,value,0) -MAKE_TEST(LogGap,( this->loggap[axis] != AST__BAD ),0) -MAKE_GET(LogGap,double,AST__BAD,this->loggap[axis],0) - -MAKE_SET3(LogGap,double,uloggap,value,0) -MAKE_GET3(LogGap,double,AST__BAD,this->uloggap[axis],0) - -/* LogPlot. */ -/* ------- */ -/* -*att++ -* Name: -* LogPlot(axis) - -* Purpose: -* Map the plot logarithmically onto the screen? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of all graphics produced by -* the Plot, by determining whether the axes of the plotting surface -* are mapped logarithmically or linearly onto the base Frame of the -* FrameSet supplied when the Plot was constructed. It takes a separate -* value for each axis of the graphics coordinate system (i.e. the -* base Frame in the Plot) so that, for instance, the setting -* "LogPlot(2)=1" specifies that the second axis of the graphics -* coordinate system (usually the vertical axis) should be mapped -* logarithmically onto the second axis of the base Frame of the -* FrameSet supplied when the Plot was constructed. -* -* If the LogPlot value of a Plot axis is non-zero, it causes that -* axis to be mapped logarithmically, otherwise (the default) the axis -* is mapped linearly. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The setting of the LogPlot attribute provides the default value -* for the related LogTicks attribute. By selecting suitable values for -* LogPlot and LogTicks, it is possible to have tick marks which are evenly -* spaced in value but which are mapped logarithmically onto the screen -* (and vice-versa). -* - An axis may only be mapped logarithmically if the visible part of -* the axis does not include the value zero. The visible part of the -* axis is that part which is mapped onto the plotting area, and is -* measured within the base Frame of the FrameSet which was supplied when -* the Plot was constructed. Any attempt to set LogPlot to a non-zero value -* will be ignored (without error) if the visible part of the axis -* includes the value zero -* - If no axis is specified, (e.g. "LogPlot" instead of -* "LogPlot(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the LogPlot(1) value. -*att-- -*/ -/* Are plot axes to be mapped logarithmically? Has a value of -1 when -not set yielding a value of 0 (no) for both axes. */ -MAKE_GET(LogPlot,int,0,( this->logplot[axis] == -1 ? 0 : this->logplot[axis] ),0) -MAKE_TEST(LogPlot,( this->logplot[axis] != -1 ),0) - -/* LogTicks. */ -/* ------- */ -/* -*att++ -* Name: -* LogTicks(axis) - -* Purpose: -* Space the major tick marks logarithmically? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether the major tick marks should be spaced logarithmically or -* linearly in axis value. It takes a separate value for each physical -* axis of the Plot so that, for instance, the setting "LogTicks(2)=1" -* specifies that the major tick marks on the second axis should be -* spaced logarithmically. -* -* If the LogTicks value for a physical axis is non-zero, the major -* tick marks on that axis will be spaced logarithmically (that is, -* there will be a constant ratio between the axis values at adjacent -* major tick marks). An error will be reported if the dynamic range of -* the axis (the ratio of the largest to smallest displayed axis value) -* is less than 10.0. If the LogTicks value is zero, the major tick marks -* will be evenly spaced (that is, there will be a constant difference -* between the axis values at adjacent major tick marks). The default is -* to produce logarithmically spaced tick marks if the corresponding -* LogPlot attribute is non-zero and the ratio of maximum axis value -* to minimum axis value is 100 or more. If either of these conditions -* is not met, the default is to produce linearly spaced tick marks. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The setting of the LogTicks attribute does not affect the mapping -* of the plot onto the screen, which is controlled by attribute LogPlot. -* By selecting suitable values for LogPlot and LogTicks, it is possible to -* have tick marks which are evenly spaced in value but which are mapped -* logarithmically onto the screen (and vica-versa). -* - An error will be reported when drawing an annotated axis grid if -* the visible part of the physical axis includes the value zero. -* - If no axis is specified, (e.g. "LogTicks" instead of -* "LogTicks(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the LogTicks(1) value. -*att-- -*/ -/* Are ticksto be spaced logarithmically? Has a value of -1 when - not set, yeielding a default value equal to the corresponding - LogPlot value. */ -MAKE_CLEAR(LogTicks,logticks,-1,0) -MAKE_GET(LogTicks,int,0,( this->logticks[axis] == -1 ? astGetLogPlot(this,axis) : this->logticks[axis] ),0) -MAKE_TEST(LogTicks,( this->logticks[axis] != -1 ),0) -MAKE_SET(LogTicks,int,logticks,( value ? 1 : 0 ),0) - -MAKE_SET3(LogTicks,int,ulgtk,value,0) -MAKE_GET3(LogTicks,int,0,this->ulgtk[axis],0) - -/* LogLabel. */ -/* -------- */ -/* -*att++ -* Name: -* LogLabel(axis) - -* Purpose: -* Use exponential format for numerical axis labels? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether the numerical axis labels should be in normal decimal form -* or should be represented as 10 raised to the appropriate power. -* That is, an axis value of 1000.0 will be drawn as "1000.0" if -* LogLabel is zero, but as "10^3" if LogLabel is non-zero. If -* graphical escape sequences are supported (see attribute Escape), -* the power in such exponential labels will be drawn as a small -* superscript instead of using a "^" character to represent -* exponentiation. -* -* The default is to produce exponential labels if the major tick -* marks are logarithmically spaced (see the LogTicks attribute). - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "LogLabel" instead of -* "LogLabel(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the LogLabel(1) value. -*att-- -*/ -/* Are labels to be drawn as 10**x? Has a value of -1 when not set, yeielding - a default value equal to the corresponding LogTicks value. */ -MAKE_CLEAR(LogLabel,loglabel,-1,0) -MAKE_GET(LogLabel,int,0,( this->loglabel[axis] == -1 ? astGetLogTicks(this,axis) : this->loglabel[axis] ),0) -MAKE_TEST(LogLabel,( this->loglabel[axis] != -1 ),0) -MAKE_SET(LogLabel,int,loglabel,( value ? 1 : 0 ),0) - -MAKE_SET3(LogLabel,int,ulglb,value,0) -MAKE_GET3(LogLabel,int,0,this->ulglb[axis],0) - -/* MajTickLen. */ -/* ----------- */ -/* -*att++ -* Name: -* MajTickLen(axis) - -* Purpose: -* Length of major tick marks for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the length of the major tick marks drawn on the axes of a Plot. -* It takes a separate value for each physical axis of the Plot so -* that, for instance, the setting "MajTickLen(2)=0" specifies the -* length of the major tick marks drawn on the second axis. -* -* The MajTickLen value should be given as a fraction of the -* minimum dimension of the plotting area. Negative values cause -* major tick marks to be placed on the outside of the -* corresponding grid line or axis (but subject to any clipping -* imposed by the underlying graphics system), while positive -* values cause them to be placed on the inside. -* -* The default behaviour depends on whether a coordinate grid is -* drawn inside the plotting area (see the Grid attribute). If so, -* the default MajTickLen value is zero (so that major ticks are -* not drawn), otherwise the default is +0.015. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "MajTickLen" instead of -* "MajTickLen(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the MajTickLen(1) value. - -*att-- -*/ -/* Fractional length of major tick marks. Has a value of AST__BAD when not -set yielding a default value of 0.015. */ -MAKE_CLEAR(MajTickLen,majticklen,AST__BAD,0) -MAKE_SET(MajTickLen,double,majticklen,value,0) -MAKE_TEST(MajTickLen,( this->majticklen[axis] != AST__BAD ),0) -MAKE_GET(MajTickLen,double,0.0,( this->majticklen[axis] == AST__BAD ? 0.015 : this->majticklen[axis]),0) - -MAKE_SET3(MajTickLen,double,umjtkln,value,0) -MAKE_GET3(MajTickLen,double,0.0,this->umjtkln[axis],0) - -/* TitleGap. */ -/* --------- */ -/* -*att++ -* Name: -* TitleGap - -* Purpose: -* Vertical spacing for a Plot title. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* where the title of a Plot is drawn. -* -* Its value gives the spacing between the bottom edge of the title -* and the top edge of a bounding box containing all the other parts -* of the annotated grid. Positive values cause the title to be -* drawn outside the box, while negative values cause it to be drawn -* inside. -* -* The TitleGap value should be given as a fraction of the minimum -* dimension of the plotting area, the default value being +0.05. - -* Applicability: -* Plot -* All Plots have this attribute. -* Plot3D -* The Plot3D class ignores this attributes since it does not draw -* a Title. - -* Notes: -* - The text used for the title is obtained from the Plot's Title -* attribute. -*att-- -*/ -/* Fractional gap between titile and top edge. Has a value of AST__BAD when -not set yielding a default value of 0.05. */ -astMAKE_CLEAR(Plot,TitleGap,titlegap,AST__BAD) -astMAKE_GET(Plot,TitleGap,double,0.0,( this->titlegap == AST__BAD ? 0.05 : this->titlegap)) -astMAKE_SET(Plot,TitleGap,double,titlegap,value) -astMAKE_TEST(Plot,TitleGap,( this->titlegap != AST__BAD )) - -/* MinTickLen. */ -/* ----------- */ -/* -*att++ -* Name: -* MinTickLen(axis) - -* Purpose: -* Length of minor tick marks for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the length of the minor tick marks drawn on the axes of a Plot. -* It takes a separate value for each physical axis of the Plot so -* that, for instance, the setting "MinTickLen(2)=0" specifies the -* length of the minor tick marks drawn on the second axis. -* -* The MinTickLen value should be given as a fraction of the -* minimum dimension of the plotting area. Negative values cause -* minor tick marks to be placed on the outside of the -* corresponding grid line or axis (but subject to any clipping -* imposed by the underlying graphics system), while positive -* values cause them to be placed on the inside. -* -* The default value is +0.007. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The number of minor tick marks drawn is determined by the -* Plot's MinTick(axis) attribute. -* - If no axis is specified, (e.g. "MinTickLen" instead of -* "MinTickLen(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the MinTickLen(1) value. - -*att-- -*/ -/* Fractional length of minor tick marks. Has a value of AST__BAD when not -set yielding a default value of 0.007. */ -MAKE_CLEAR(MinTickLen,minticklen,AST__BAD,0) -MAKE_SET(MinTickLen,double,minticklen,value,0) -MAKE_TEST(MinTickLen,( this->minticklen[axis] != AST__BAD ),0) -MAKE_GET(MinTickLen,double,0.0,( this->minticklen[axis] == AST__BAD ? 0.007 : this->minticklen[axis]),0) - -/* Labelling. */ -/* ---------- */ -/* -*att++ -* Name: -* Labelling - -* Purpose: -* Label and tick placement option for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the strategy for placing numerical labels and tick marks for a Plot. -* -* If the Labelling value of a Plot is "exterior" (the default), then -* numerical labels and their associated tick marks are placed -* around the edges of the plotting area, if possible. If this is -* not possible, or if the Labelling value is "interior", then they -* are placed along grid lines inside the plotting area. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The LabelAt(axis) attribute may be used to determine the exact -* placement of labels and tick marks that are drawn inside the -* plotting area. -*att-- -*/ -astMAKE_CLEAR(Plot,Labelling,labelling,-9999) -astMAKE_SET(Plot,Labelling,int,labelling,(value?1:0)) -astMAKE_TEST(Plot,Labelling,( this->labelling != -9999 )) -astMAKE_GET(Plot,Labelling,int,0,(this->labelling == -9999 ? 0 : this->labelling)) - -MAKE_SET2(Plot,Labelling,int,ulbling,(value?1:0)) -MAKE_GET2(Plot,Labelling,int,0,this->ulbling) - -/* Edge. */ -/* ----- */ -/* -*att++ -* Name: -* Edge(axis) - -* Purpose: -* Which edges to label in a Plot - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* which edges of a Plot are used for displaying numerical and -* descriptive axis labels. It takes a separate value for each -* physical axis of the Plot so that, for instance, the setting -* "Edge(2)=left" specifies which edge to use to display labels for -* the second axis. -* -* The values "left", "top", "right" and "bottom" (or any -* abbreviation) can be supplied for this attribute. The default is -* usually "bottom" for the first axis and "left" for the second -* axis. However, if exterior labelling was requested (see the -* Labelling attribute) but cannot be produced using these default -* Edge values, then the default values will be swapped if this -* enables exterior labelling to be produced. - -* Applicability: -* Plot -* All Plots have this attribute. -* Plot3D -* The Plot3D class ignores this attributes. Instead it uses its -* own RootCorner attribute to determine which edges of the 3D plot -* to label. - -* Notes: -* - In some circumstances, numerical labels will be drawn along -* internal grid lines instead of at the edges of the plotting area -* (see the Labelling attribute). In this case, the Edge attribute -* only affects the placement of the descriptive labels (these are -* drawn at the edges of the plotting area, rather than along the -* axis lines). -*att-- -*/ -/* The edges of the plotting area on which to place numerical labels - for axes 0 and 1. Has a value of -1 when not set yielding a value - of 3 (the bottom edge) for axis 0 and 0 (the left-hand edge) for - axis 1. */ -MAKE_CLEAR(Edge,edge,-1,0) -MAKE_GET(Edge,int,0,( this->edge[axis] == -1 ? (axis?LEFT:BOTTOM) : this->edge[axis] ),0) -MAKE_SET(Edge,int,edge,(abs( value % 4 )),0) -MAKE_TEST(Edge,( this->edge[axis] != -1 ),0) - -MAKE_GET3(Edge,int,0,this->uedge[axis],0) -MAKE_SET3(Edge,int,uedge,(abs( value % 4 )),0) - -/* NumLab. */ -/* -------- */ -/* -*att++ -* Name: -* NumLab(axis) - -* Purpose: -* Draw numerical axis labels for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether labels should be drawn to represent the numerical values -* along each axis of a Plot. It takes a separate value for each -* physical axis of a Plot so that, for instance, the setting -* "NumLab(2)=1" specifies that numerical labels should be drawn -* for the second axis. -* -* If the NumLab value of a Plot axis is non-zero (the default), -* then numerical labels will be drawn for that axis, otherwise -* they will be omitted. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The drawing of associated descriptive axis labels for a Plot -* (describing the quantity being plotted along each axis) is -* controlled by the TextLab(axis) attribute. -* - If no axis is specified, (e.g. "NumLab" instead of -* "NumLab(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the NumLab(1) value. -*att-- -*/ -/* Are numerical labels to be displayed on each axis? Has a value of - -1 when not set yielding a value of 1 (yes) for both axes. */ -MAKE_CLEAR(NumLab,numlab,-1,0) -MAKE_GET(NumLab,int,1,( this->numlab[axis] == -1 ? 1 : this->numlab[axis] ),0) -MAKE_TEST(NumLab,( this->numlab[axis] != -1 ),0) -MAKE_SET(NumLab,int,numlab,( value ? 1 : 0 ),0) - -/* NumLabGap. */ -/* --------- */ -/* -*att++ -* Name: -* NumLabGap(axis) - -* Purpose: -* Spacing of numerical labels for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* where numerical axis labels are placed relative to the axes they -* describe. It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "NumLabGap(2)=-0.01" -* specifies where the numerical label for the second axis should -* be drawn. -* -* For each axis, the NumLabGap value gives the spacing between the -* axis line (or edge of the plotting area, if appropriate) and the -* nearest edge of the corresponding numerical axis -* labels. Positive values cause the descriptive label to be placed -* on the opposite side of the line to the default tick marks, -* while negative values cause it to be placed on the same side. -* -* The NumLabGap value should be given as a fraction of the minimum -* dimension of the plotting area, the default value being +0.01. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "NumLabGap" instead of -* "NumLabGap(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the NumLabGap(1) value. -*att-- -*/ -/* Fractional spacing between numeric labels and axes. Has a value of AST__BAD -when not set yielding a default value of 0.01. */ -MAKE_CLEAR(NumLabGap,numlabgap,AST__BAD,0) -MAKE_GET(NumLabGap,double,0.0,( this->numlabgap[ axis ] == AST__BAD ? 0.01 : this->numlabgap[axis]),0) -MAKE_SET(NumLabGap,double,numlabgap,value,0) -MAKE_TEST(NumLabGap,( this->numlabgap[axis] != AST__BAD ),0) - -/* MinTick. */ -/* -------- */ -/* -*att++ -* Name: -* MinTick(axis) - -* Purpose: -* Density of minor tick marks for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the density of minor tick marks which appear between the major -* axis values of a Plot. It takes a separate value for each -* physical axis of a Plot so that, for instance, the setting -* "MinTick(2)=2" specifies the density of minor tick marks along -* the second axis. -* -* The value supplied should be the number of minor divisions -* required between each pair of major axis values, this being one -* more than the number of minor tick marks to be drawn. By -* default, a value is chosen that depends on the gap between major -* axis values and the nature of the axis. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "MinTick" instead of -* "MinTick(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the MinTick(1) value. -*att-- -*/ -/* How many divisions are there between major tick marks? Has a value -of -1 when not set yielding a value of 1 for both axes. */ -MAKE_CLEAR(MinTick,mintick,-1,0) -MAKE_GET(MinTick,int,1,( this->mintick[axis] == -1 ? 1 : this->mintick[axis] ),0) -MAKE_TEST(MinTick,( this->mintick[axis] != -1 ),0) -MAKE_SET(MinTick,int,mintick,( (value < 1)? 1 : value ),0) - -MAKE_GET3(MinTick,int,1,this->umintk[axis],0) -MAKE_SET3(MinTick,int,umintk,( (value < 1)? 1 : value ),0) - -/* TextLab. */ -/* --------- */ -/* -*att++ -* Name: -* TextLab(axis) - -* Purpose: -* Draw descriptive axis labels for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether textual labels should be drawn to describe the quantity -* being represented on each axis of a Plot. It takes a separate -* value for each physical axis of a Plot so that, for instance, -* the setting "TextLab(2)=1" specifies that descriptive labels -* should be drawn for the second axis. -* -* If the TextLab value of a Plot axis is non-zero, then -* descriptive labels will be drawn for that axis, otherwise they -* will be omitted. The default behaviour is to draw descriptive -* labels if tick marks and numerical labels are being drawn around -* the edges of the plotting area (see the Labelling attribute), -* but to omit them otherwise. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The text used for the descriptive labels is derived from the -* Plot's Label(axis) attribute, together with its Unit(axis) -* attribute if appropriate (see the LabelUnits(axis) attribute). -* - The drawing of numerical axis labels for a Plot (which -* indicate values on the axis) is controlled by the NumLab(axis) -* attribute. -* - If no axis is specified, (e.g. "TextLab" instead of -* "TextLab(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the TextLab(1) value. -*att-- -*/ -/* Are textual labels to be displayed on each axis? Has a value of -1 - when not set yielding a value of 1 (yes) for both axes. */ -MAKE_CLEAR(TextLab,textlab,-1,0) -MAKE_GET(TextLab,int,1,( this->textlab[axis] == -1 ? 1 : this->textlab[axis] ),0) -MAKE_TEST(TextLab,( this->textlab[axis] != -1 ),0) -MAKE_SET(TextLab,int,textlab,( value ? 1 : 0 ),0) - -MAKE_GET3(TextLab,int,1,this->utxtlb[axis],0) -MAKE_SET3(TextLab,int,utxtlb,( value ? 1 : 0 ),0) - -/* TextLabGap. */ -/* ----------- */ -/* -*att++ -* Name: -* TextLabGap(axis) - -* Purpose: -* Spacing of descriptive axis labels for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* where descriptive axis labels are placed relative to the axes they -* describe. It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "TextLabGap(2)=0.01" -* specifies where the descriptive label for the second axis should -* be drawn. -* -* For each axis, the TextLabGap value gives the spacing between the -* descriptive label and the edge of a box enclosing all other parts -* of the annotated grid (excluding other descriptive labels). The gap -* is measured to the nearest edge of the label (i.e. the top or the -* bottom). Positive values cause the descriptive label to be placed -* outside the bounding box, while negative values cause it to be placed -* inside. -* -* The TextLabGap value should be given as a fraction of the minimum -* dimension of the plotting area, the default value being +0.01. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If drawn, descriptive labels are always placed at the edges of -* the plotting area, even although the corresponding numerical -* labels may be drawn along axis lines in the interior of the -* plotting area (see the Labelling attribute). -* - If no axis is specified, (e.g. "TextLabGap" instead of -* "TextLabGap(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the TextLabGap(1) value. -*att-- -*/ -/* Fractional spacing between numeric labels and axes. Has a value of AST__BAD -when not set yielding a default value of 0.01. */ -MAKE_CLEAR(TextLabGap,textlabgap,AST__BAD,0) -MAKE_GET(TextLabGap,double,0.0,( this->textlabgap[ axis ] == AST__BAD ? 0.01 : this->textlabgap[axis]),0) -MAKE_SET(TextLabGap,double,textlabgap,value,0) -MAKE_TEST(TextLabGap,( this->textlabgap[axis] != AST__BAD ),0) - -/* LabelUnits. */ -/* ----------- */ -/* -*att++ -* Name: -* LabelUnits(axis) - -* Purpose: -* Use axis unit descriptions in a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether the descriptive labels drawn for each axis of a Plot -* should include a description of the units being used on the -* axis. It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "LabelUnits(2)=1" -* specifies that a unit description should be included in the -* label for the second axis. -* -* If the LabelUnits value of a Plot axis is non-zero, a unit -* description will be included in the descriptive label for that -* axis, otherwise it will be omitted. The default behaviour is to -* include a unit description unless the current Frame of the Plot -* is a SkyFrame representing equatorial, ecliptic, galactic or -* supergalactic coordinates, in which case it is omitted. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The text used for the unit description is obtained from the -* Plot's Unit(axis) attribute. -* - If no axis is specified, (e.g. "LabelUnits" instead of -* "LabelUnits(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the LabelUnits(1) value. -* - If the current Frame of the Plot is not a SkyFrame, but includes -* axes which were extracted from a SkyFrame, then the default behaviour -* is to include a unit description only for those axes which were not -* extracted from a SkyFrame. -*att-- -*/ -/* Are textual labels to include a string describing the axis units? Has a -value of -1 when not set yielding a default of 1. */ -MAKE_CLEAR(LabelUnits,labelunits,-1,0) -MAKE_TEST(LabelUnits,( this->labelunits[axis] != -1 ),0) -MAKE_SET(LabelUnits,int,labelunits,( value ? 1 : 0 ),0) - -MAKE_GET3(LabelUnits,int,1,this->ulbunit[axis],0) -MAKE_SET3(LabelUnits,int,ulbunit,( value ? 1 : 0 ),0) - -/* Style. */ -/* ------ */ -/* -*att++ -* Name: -* Style(element) - -* Purpose: -* Line style for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute determines the line style used when drawing each -* element of graphical output produced by a Plot. It takes a -* separate value for each graphical element so that, for instance, -* the setting "Style(border)=2" causes the Plot border to be drawn -* using line style 2 (which might result in, say, a dashed line). -* -* The range of integer line styles available and their appearance -* is determined by the underlying graphics system. The default -* behaviour is for all graphical elements to be drawn using the -* default line style supplied by this graphics system (normally, -* this is likely to give a solid line). - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Style" instead of -* "Style(border)"), then a "set" or "clear" operation will affect -* the attribute value of all graphical elements, while a "get" or -* "test" operation will use just the Style(Border) value. -*att-- -*/ -/* Line styles. Has a value of -1 when not set yielding a default of 1. */ -MAKE_CLEAR(Style,style,-1,AST__NPID) -MAKE_GET(Style,int,1,( this->style[axis] == -1 ? 1 : this->style[axis] ),AST__NPID) -MAKE_TEST(Style,( this->style[axis] != -1 ),AST__NPID) -MAKE_SET(Style,int,style,value,AST__NPID) - -/* Font. */ -/* ----- */ -/* -*att++ -* Name: -* Font(element) - -* Purpose: -* Character font for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute determines the character font index used when -* drawing each element of graphical output produced by a Plot. It -* takes a separate value for each graphical element so that, for -* instance, the setting "Font(title)=2" causes the Plot title to -* be drawn using font number 2. -* -* The range of integer font indices available and the appearance -* of the resulting text is determined by the underlying graphics -* system. The default behaviour is for all graphical elements to -* be drawn using the default font supplied by this graphics -* system. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Font" instead -* of "Font(title)"), then a "set" or "clear" operation will -* affect the attribute value of all graphical elements, while a -* "get" or "test" operation will use just the Font(TextLab) -* value. -*att-- -*/ -/* Character fonts. Has a value of -1 when not set yielding a default of 1. */ -MAKE_CLEAR(Font,font,-1,AST__NPID) -MAKE_GET(Font,int,1,( this->font[axis] == -1 ? 1 : this->font[axis] ),AST__NPID) -MAKE_TEST(Font,( this->font[axis] != -1 ),AST__NPID) -MAKE_SET(Font,int,font,value,AST__NPID) - -/* Colour. */ -/* ------- */ -/* -*att++ -* Name: -* Colour(element) - -* Purpose: -* Colour index for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute determines the colour index used when drawing -* each element of graphical output produced by a Plot. It takes a -* separate value for each graphical element so that, for instance, -* the setting "Colour(title)=2" causes the Plot title to be drawn -* using colour index 2. The synonym "Color" may also be used. -* -* The range of integer colour indices available and their -* appearance is determined by the underlying graphics system. The -* default behaviour is for all graphical elements to be drawn -* using the default colour index supplied by this graphics system -* (normally, this is likely to result in white plotting on a black -* background, or vice versa). -d -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Colour" instead -* of "Colour(title)"), then a "set" or "clear" operation will -* affect the attribute value of all graphical elements, while a -* "get" or "test" operation will use just the Colour(TextLab) -* value. -*att-- -*/ -/* Colours. Has a value of -1 when not set yielding a default of 1. */ -MAKE_CLEAR(Colour,colour,-1,AST__NPID) -MAKE_GET(Colour,int,1,( this->colour[axis] == -1 ? 1 : this->colour[axis] ),AST__NPID) -MAKE_TEST(Colour,( this->colour[axis] != -1 ),AST__NPID) -MAKE_SET(Colour,int,colour,value,AST__NPID) - -/* Width. */ -/* ------ */ -/* -*att++ -* Name: -* Width(element) - -* Purpose: -* Line width for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute determines the line width used when drawing each -* element of graphical output produced by a Plot. It takes a -* separate value for each graphical element so that, for instance, -* the setting "Width(border)=2.0" causes the Plot border to be -* drawn using a line width of 2.0. A value of 1.0 results in a -* line thickness which is approximately 0.0005 times the length of -* the diagonal of the entire display surface. -* -* The actual appearance of lines drawn with any particular width, -* and the range of available widths, is determined by the -* underlying graphics system. The default behaviour is for all -* graphical elements to be drawn using the default line width -* supplied by this graphics system. This will not necessarily -* correspond to a Width value of 1.0. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Width" instead of -* "Width(border)"), then a "set" or "clear" operation will affect -* the attribute value of all graphical elements, while a "get" or -* "test" operation will use just the Width(Border) value. -*att-- -*/ -/* Line widths. Has a value of AST__BAD when not set yielding a - default of 1.0. */ -MAKE_CLEAR(Width,width,AST__BAD,AST__NPID) -MAKE_GET(Width,double,1.0,( this->width[axis] == AST__BAD ? 1.0 : this->width[axis] ),AST__NPID) -MAKE_TEST(Width,( this->width[axis] != AST__BAD ),AST__NPID) -MAKE_SET(Width,double,width,(value!=0.00)?value:(astError(AST__ATTIN,"astSetWidth(Plot):Invalid zero value supplied for Width(%s) attribute", status,GrfItem(axis,NULL,NULL, status )),this->width[axis]),AST__NPID) - -/* Size. */ -/* ----- */ -/* -*att++ -* Name: -* Size(element) - -* Purpose: -* Character size for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Floating Point. - -* Description: -* This attribute determines the character size used when drawing -* each element of graphical output produced by a Plot. It takes a -* separate value for each graphical element so that, for instance, -* the setting "Size(title)=2.0" causes the Plot title to be drawn -* using twice the default character size. -* -* The range of character sizes available and the appearance of the -* resulting text is determined by the underlying graphics system. -* The default behaviour is for all graphical elements to be drawn -* using the default character size supplied by this graphics -* system. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Size" instead -* of "Size(title)"), then a "set" or "clear" operation will -* affect the attribute value of all graphical elements, while a -* "get" or "test" operation will use just the Size(TextLab) -* value. -*att-- -*/ -/* Character sizes. Has a value of AST__BAD when not set yielding a default - of 1.0. */ -MAKE_CLEAR(Size,size,AST__BAD,AST__NPID) -MAKE_GET(Size,double,1.0,( this->size[axis] == AST__BAD ? 1.0 : this->size[axis] ),AST__NPID) -MAKE_TEST(Size,( this->size[axis] != AST__BAD ),AST__NPID) -MAKE_SET(Size,double,size,(value!=0.00)?value:(astError(AST__ATTIN,"astSetSize(Plot): Invalid zero value supplied for Size(%s) attribute", status,GrfItem(axis,NULL,NULL, status )),this->size[axis]),AST__NPID) - -/* Member functions. */ -/* ================= */ -static void AddCdt( AstPlotCurveData *cdt1, AstPlotCurveData *cdt2, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* AddCdt - -* Purpose: -* Append one AstPlotCurveData structure to another. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void AddCdt( AstPlotCurveData *cdt1, AstPlotCurveData *cdt2, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* The contents of the structure pointed to by "cdt2" is appended -* to the structure pointed to by "cdt1". - -* Parameters: -* cdt1 -* Pointer to the AstPlotCurveData structure to be modified. -* cdt2 -* Pointer to the AstPlotCurveData structure to be appended to cdt1. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - An error is reported if there is insufficient room in "cdt1" to -* store the information in "cdt2". - -*/ - -/* Local Variables: */ - int nbrk, i, j; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the total number of breaks described by both structures. */ - nbrk = cdt1->nbrk + cdt2->nbrk; - -/* Report an error if this number of breaks cannot be stored in a AstPlotCurveData - structure. */ - if( nbrk > AST__MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__MXBRK ); - -/* Otherwise, append the information. */ - } else { - -/* Store the index within "cdt1" of the next break to be added. */ - j = cdt1->nbrk; - -/* Add each the position and direction information for each of the breaks - in "cdt2". */ - for( i = 0; i < cdt2->nbrk; i++ ){ - cdt1->xbrk[ j ] = cdt2->xbrk[ i ]; - cdt1->ybrk[ j ] = cdt2->ybrk[ i ]; - cdt1->vxbrk[ j ] = cdt2->vxbrk[ i ]; - cdt1->vybrk[ j ] = cdt2->vybrk[ i ]; - -/* Increment the index of the next break in "cdt1". */ - j++; - } - -/* Update the number of breaks in "cdt1". */ - cdt1->nbrk = nbrk; - -/* Update the length of the curve described by "cdt1". */ - cdt1->length += cdt2->length; - -/* Update the flag indicating if the entire curve is outside the plotting - zone. */ - if( !cdt2->out ) cdt1->out = 0; - - } - -/* Return. */ - return; - -} - -static void Apoly( AstPlot *this, float x, float y, int *status ){ -/* -* Name: -* Apoly - -* Purpose: -* Append a another point to a poly line. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Apoly( AstPlot *this, float x, float y, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function appends the supplied point to the current poly line. - -* Parameters: -* x -* The graphics x coordinate. -* y -* The graphics y coordinate. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int ipoint; - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Extend the buffers, and add the supplied point to the end. */ - ipoint = Poly_n++; - Poly_x = astGrow( Poly_x, Poly_n, sizeof(*Poly_x) ); - Poly_y = astGrow( Poly_y, Poly_n, sizeof(*Poly_y) ); - if( astOK ) { - Poly_x[ ipoint ] = x; - Poly_y[ ipoint ] = y; - } - -/* Update the box containing all plotted lines. */ - Box_lbnd[ 0 ] = astMIN( x, Box_lbnd[ 0 ] ); - Box_ubnd[ 0 ] = astMAX( x, Box_ubnd[ 0 ] ); - Box_lbnd[ 1 ] = astMIN( y, Box_lbnd[ 1 ] ); - Box_ubnd[ 1 ] = astMAX( y, Box_ubnd[ 1 ] ); - -} - -static void AxPlot( AstPlot *this, int axis, const double *start, double length, - int ink, AstPlotCurveData *cdata, const char *method, const char *class, int *status ){ -/* -* -* Name: -* AxPlot - -* Purpose: -* Draw a curve with constant axis value. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void AxPlot( AstPlot *this, int axis, const double *start, double length, -* int ink, AstPlotCurveData *cdata, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a section of a curve of the specified length -* with constant value on a specified axis in the current Frame of the -* Plot, starting at the specified position. The algorithm used can handle -* discontinuities in the Mapping between the current Frame and graphics -* coordinates, and information describing any breaks in the curve -* (including the start and end of the curve) are returned in the supplied -* AstPlotCurveData structure. - -* Parameters: -* this -* Pointer to the Plot. -* axis -* The zero-based index of an axis within the current Frame of the Plot. -* The curve has a varying value on this axis. -* start -* A pointer to a an array holding the coordinates of the start of the -* curve within the current Frame of the Plot. -* length -* The length of the section of the curve to be drawn, given as an -* increment along the axis specified by parameter "axis". -* ink -* If zero, the curve is not actually drawn, but information about -* the breaks is still returned. If non-zero, the curve is also drawn. -* cdata -* A pointer to a structure in which to return information about the -* breaks in the curve. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - No curve is draw if the "start" array contains any bad values -* (i.e. values equal to AST__BAD), or if the "length" value is bad, -* or if a NULL pointer is supplied for "cdata". No errors are reported -* in these cases. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - int i; /* Loop count */ - int naxes; /* No. of axes in the base Frame */ - int ok; /* Are all start coords good? */ - int gridid; /* Identifier value for element being drawn */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -#ifdef CRV_TRACE - printf("AXPLOT: axis %d, start (%.*g,%.*g), length %.*g\n", - axis, AST__DBL_DIG, start[0], AST__DBL_DIG, start[1], AST__DBL_DIG, length ); - getchar(); -#endif - - -/* Initialise any supplied cdata structure to hold safe values. */ - if( cdata ){ - cdata->length = 0.0; - cdata->out = 1; - cdata->nbrk = 0; - } - -/* Get the number of axes in the current Frame. */ - naxes = astGetNout( this ); - -/* Check the "start" parameter for bad values. */ - ok = 1; - for( i = 0; i < naxes; i++ ) { - if( start[ i ] == AST__BAD ){ - ok = 0; - break; - } - } - -/* Check the "length" parameter for bad values. */ - if( length == AST__BAD ) ok = 0; - -/* Check that the "cdata" pointer can be used. */ - if( !cdata ) ok = 0; - -/* Only proceed if the parameters are OK, and there has been no error. */ - if( ok && astOK ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - if( axis == 0 ) { - gridid = AST__GRIDLINE2_ID; - } else { - gridid = AST__GRIDLINE1_ID; - } - astGrfAttrs( this, gridid, 1, GRF__LINE, method, class ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Set up the externals used to communicate with the Map1 function... - The number of axes in the physical coordinate system (i.e. the current - Frame). */ - Map1_ncoord = naxes; - -/* See if tick marks are logarithmically or linearly spaced. */ - Map1_log = astGetLogTicks( this, axis ); - -/* A pointer to the Plot, the Current Frame and the Mapping. */ - Map1_plot = this; - Map1_frame = astGetFrame( this, AST__CURRENT ); - Map1_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Physical coords at the start of the curve (dist=0). */ - Map1_origin = start; - -/* Length of the curve. */ - Map1_length = length; - -/* The index of the axis which the curve follows. */ - Map1_axis = axis; - -/* Decide whether to omit points not in their normal ranges. */ - Map1_norm = !IsASkyAxis( Map1_frame, 0, status ) && - !IsASkyAxis( Map1_frame, 1, status ); - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map1; - Crv_ink = ink; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = cdata->xbrk; - Crv_ybrk = cdata->ybrk; - Crv_vxbrk = cdata->vxbrk; - Crv_vybrk = cdata->vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Set up a list of points spread evenly over the curve. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Map these points into graphics coordinates. */ - Map1( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map1 to draw the curve. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map1. */ - Map1( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - if( cdata ){ - cdata->length = Crv_len; - cdata->out = Crv_out; - cdata->nbrk = Crv_nbrk; - PurgeCdata( cdata, status ); - } - -/* Annul the Frame and Mapping. */ - Map1_frame = astAnnul( Map1_frame ); - Map1_map = astAnnul( Map1_map ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gridid, 0, GRF__LINE, method, class ); - - } - -/* Return. */ - return; - -} - -static void BBuf( AstPlot *this, int *status ) { -/* -*++ -* Name: -c astBBuf -f AST_BBUF - -* Purpose: -* Begin a new graphical buffering context. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astBBuf( AstPlot *this ) -f CALL AST_BBUF( THIS STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function -f This routine -* starts a new graphics buffering context. A matching call to the -c function astEBuf -f routine AST_EBUF -* should be used to end the context. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The nature of the buffering is determined by the underlying -* graphics system (as defined by the current grf module). Each call -c to this function -f to this routine -c to this function -f to this routine -* simply invokes the astGBBuf function in the grf module. - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the active GRF BBuf function. */ - GBBuf( this, "astBBuf", astGetClass( this ), status ); - -} - -static int Boundary( AstPlot *this, const char *method, const char *class, int *status ){ -/* -* Name: -* Boundary - -* Purpose: -* Draw a boundary around regions containing valid physical positions. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Boundary( AstPlot *this, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function draws a boundary around the regions of the plotting -* area which contain valid, unclipped, physical coordinates, but does -* not include the intersections with the edges of the plotting area. -* -* Broadly, the algorithm is as follows: An initial coarse grid is -* created covering the entire plotting area. This grid consists of a -* regular square matrix of points in graphics coordinates, and the -* corresponding physical coordinates. An array of flags is created, -* one for each grid cell, indicating if the boundary passes through the -* cell. This is assumed to be the case if the cell has a mix of good and -* bad corners (i.e corners which have good or bad physical coordinates). -* This assumption does not locate all boundary cells though, since if -* the boundary passes into and out of a cell throught the same edge, -* the corners of the cell will be either all good or all bad. But for -* the moment, we just concentrate on the ones found using this simple -* assumption. For each such cell, a finer grid is then created covering -* the cell, and the boundary is drawn through this fine grid using -* TraceBorder. TraceBorder returns a set of four flags indicating which -* edges of the cell were intersected by the boundary. A check is then -* made on any of the four neighbouring cells into which the curve -* passes. If any of these cells were not flagged as boundary cells using -* the simple assumption described earlier, then they are flagged now -* (with a different flag value). Once all the cells located using the -* simple assumption have been processed, any further cells flagged -* with the new flag value are also processed using TraceBorder in the -* same way. This process is repeated until no extra boundary cells are -* found. - -* Parameters: -* this -* Pointer to a Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A flag indicating if any regions containing invalid physical -* coordinates were found within the plotting area. - -* Notes: -* - This function assumes the physical coordinate Frame is -* 2-dimensional, and it should not be used if this is not the case. -* - A value of zero is returned if an error has already occurred, or -* if this function should fail for any reason. - -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* Pointer to base Plot Frame */ - AstFrame *cfrm; /* Pointer to current Plot Frame */ - AstMapping *map; /* Pointer to Plot mapping (graphics -> physical) */ - AstMapping *rmap; /* Pointer to Plot mapping (graphics -> physical) */ - AstRegion *breg; /* Region mapped into base Plot Frame */ - double blbnd[ 2 ]; /* Lower grid bounds in base frame */ - double bubnd[ 2 ]; /* Upper grid bounds in base frame */ - double dx; /* Plotting area width */ - double dy; /* Plotting area height */ - double power; /* Exponent in pow call */ - double rat; /* Ratio by which to reduce DIM */ - double tol; /* Fractional plotting tolerance */ - int dim; /* No. of points along each edge of coarse grid */ - int edges[ 4 ]; /* Flags indicating edges bisected by boundary */ - int rate_disabled; /* Was the astRate method initially disabled? */ - int ret; /* Any regions containing bad physical coords? */ - -/* Check global status. */ - if( !astOK ) return 0; - -/* Initialise the answer to indicate that no regions containing invalid - physical coordinates have been found. */ - ret = 0; - -/* Get the current Frame from the Plot. */ - cfrm = astGetFrame( this, AST__CURRENT ); - -/* If it is a region, we use a special method, if possible, to trace the - Region boundary. Otherwise, we use a grid tracing method that makes no - assumptions about the nature of the Mapping or Frame. */ - if( !DrawRegion( this, cfrm, method, class, status ) ) { - -/* Each basic element of the boundary drawn by the following algorithm - will be drawn at a multiple of 45 degrees to the horizontal. This can - cause noticable aliasing. For instance, if the border is a straight - line at 50 degrees to the horizontal, it will be drawn at 45 degrees - for long sections, followed by a vertical leap to catch up with where - it should be. Because of this we use a finer tolerance than for other - drawing. */ - tol = 0.25*astGetTol( this ); - -/* Set up the dimension of a coarse grid in graphics coordinates to cover the - whole plotting area. This is chosen to give a finer grid for smaller - plotting tolerances. Note, putting the power as a literal constant in - the call to pow seems to cause a segmentation violation on some systems. */ - power = -0.666666666; - dim = (int) 4*pow( tol, power ) + 10; - if( dim > 400 ) dim = 400; - if( dim < 3 ) dim = 3; - -/* Store the required plotting tolerance as a distance in graphics - coords. */ - dx = fabs( this->xhi - this->xlo ); - dy = fabs( this->xhi - this->xlo ); - tol *= ( ( dx > dy ) ? dx : dy ); - -/* Extract the Mapping from the Plot. */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Select the area covered by the coarse grid. If the current Frame is a - Region, we use the bounding box of Region after being mapped into - graphics coords. */ - if( astIsARegion( cfrm ) ) { - bfrm = astGetFrame( this, AST__BASE ); - -/* Get the Mapping from the current to the base Frame in the Plot, and - remove the effects of any Regions. */ - - astInvert( map ); - rmap = astRemoveRegions( map ); - astInvert( map ); - -/* Map the Region into the GRAPHICS frame. */ - breg = astMapRegion( cfrm, rmap, bfrm ); - astGetRegionBounds( breg, blbnd, bubnd ); - - rmap = astAnnul( rmap ); - bfrm = astAnnul( bfrm ); - breg = astAnnul( breg ); - - rat = ( ( bubnd[ 0 ] - blbnd[ 0 ] )*( bubnd[ 1 ] - blbnd[ 1 ] ) )/ - ( ( this->xhi - this->xlo )*( this->yhi - this->ylo ) ); - rat = sqrt( rat ); - dim = (int) ( rat*dim ); - if( dim < 3 ) dim = 3; - -/* If the current Frame is not a Region, use the whole plot. */ - } else { - blbnd[ 0 ] = this->xlo; - blbnd[ 1 ] = this->ylo; - bubnd[ 0 ] = this->xhi; - bubnd[ 1 ] = this->yhi; - } - -/* Disable the astRate method in order to improve the speed of - evaluating the Mapping in cases where the Mapping includes an - AstRateMap. Note the original value of the flag so that it can be - re-instated at the end. */ - rate_disabled = astRateState( 1 ); - -/* Draw the boundary. */ - ret = TraceBorder( this, map, blbnd[ 0 ], bubnd[ 0 ], blbnd[ 1 ], - bubnd[ 1 ], dim, tol, edges, method, class, status ); - -/* Re-instate the original setting of the "astRate disabled" flag. */ - astRateState( rate_disabled ); - -/* Release the remaining resources. */ - map = astAnnul( map ); - } - cfrm = astAnnul( cfrm ); - -/* If an error has occurred, return 0. */ - if( !astOK ) ret = 0; - -/* Return the answer. */ - return ret; -} - -static int Border( AstPlot *this_nd, int *status ){ -/* -*++ -* Name: -c astBorder -f AST_BORDER - -* Purpose: -* Draw a border around valid regions of a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c int astBorder( AstPlot *this ) -f RESULT = AST_BORDER( THIS, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -* This function draws a (line) border around regions of the -* plotting area of a Plot which correspond to valid, unclipped -* physical coordinates. For example, when plotting using an -* all-sky map projection, this function could be used to draw the -* boundary of the celestial sphere when it is projected on to the -* plotting surface. -* -* If the entire plotting area contains valid, unclipped physical -* coordinates, then the boundary will just be a rectangular box -* around the edges of the plotting area. -* -* If the Plot is a Plot3D, this method is applied individually to -* each of the three 2D Plots encapsulated within the Plot3D (each of -* these Plots corresponds to a single 2D plane in the 3D graphics -* system). In addition, if the entire plotting volume has valid -* coordinates in the 3D current Frame of the Plot3D, then additional -* lines are drawn along the edges of the 3D plotting volume so that -* the entire plotting volume is enclosed within a cuboid grid. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astBorder() -f AST_BORDER = LOGICAL -c Zero is returned if the plotting space is completely filled by -f .FALSE. is returned if the plotting space is completely filled by -* valid, unclipped physical coordinates (so that only a -c rectangular box was drawn around the edge). Otherwise, one is -f rectangular box was drawn around the edge). Otherwise, .TRUE. is -* returned. - -* Notes: -c - A value of zero will be returned if this function is invoked -f - A value of .FALSE. will be returned if this function is invoked -c with the AST error status set, or if it should fail for any -f with STATUS set to an error value, or if it should fail for any -* reason. -* - An error results if either the current Frame or the base Frame -* of the Plot is not 2-dimensional or (for a Plot3D) 3-dimensional. -* - An error also results if the transformation between the base -* and current Frames of the Plot is not defined (i.e. the Plot's -* TranForward attribute is zero). -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPlot *this; /* Plot with no more than 2 current axes */ - AstPlotCurveData cdata; /* Structure to receive break information */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int inval; /* Were any bad regions found? */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_nd); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astBorder"; - class = astGetClass( this_nd ); - -/* Initialise the bounding box for primitives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this_nd ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Get a Plot with a 2D (or 1D) current Frame. */ - this = (AstPlot *) Fset2D( (AstFrameSet *) this_nd, AST__CURRENT, status ); - -/* Check the current Frame of the Plot is 2-D. */ - naxes = astGetNout( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the current " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__BORDER_ID, 1, GRF__LINE, method, class ); - -/* We first draw the intersections of the regions containing valid - physical coordinates with the edges of the plotting area. First do - the bottom edge. */ - LinePlot( this, this->xlo, this->ylo, this->xhi, this->ylo, - 1, &cdata, method, class, status ); - -/* Now do the right-hand edge. */ - LinePlot( this, this->xhi, this->ylo, this->xhi, this->yhi, - 1, &cdata, method, class, status ); - -/* Now do the top edge. */ - LinePlot( this, this->xhi, this->yhi, this->xlo, this->yhi, - 1, &cdata, method, class, status ); - -/* Now do the left-hand edge. */ - LinePlot( this, this->xlo, this->yhi, this->xlo, this->ylo, - 1, &cdata, method, class, status ); - -/* Now draw a curve following the boundary through the interior of the - plotting area. If the current Frame in the Plot is a Region, we use a - shorter method if possible. If this is not possible, we use a longer - method. */ - inval = Boundary( this, method, class, status ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__BORDER_ID, 0, GRF__LINE, method, class ); - -/* Annul the 2d plot. */ - this = astAnnul( this ); - -/* Return. */ - return inval; - -} - -static void BoundingBox( AstPlot *this, float lbnd[2], float ubnd[2], int *status ){ -/* -*++ -* Name: -c astBoundingBox -f AST_BOUNDINGBOX - -* Purpose: -* Return a bounding box for previously drawn graphics. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astBoundingBox( AstPlot *this, float lbnd[2], float ubnd[2] ) -f CALL AST_BOUNDINGBOX( THIS, LBND, UBND, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function returns the bounds of a box which just encompasess the -f This routine returns the bounds of a box which just encompasess the -* graphics produced by the previous call to any of the Plot methods -* which produce graphical output. If no such previous call has yet -* been made, or if the call failed for any reason, then the bounding box -c returned by this function is undefined. -f returned by this routine is undefined. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c lbnd -f LBND( 2 ) = REAL (Returned) -* A two element array in which is returned the lower limits of the -* bounding box on each of the two axes of the graphics coordinate -* system (the base Frame of the Plot). -c ubnd -f UBND( 2 ) = REAL (Returned) -* A two element array in which is returned the upper limits of the -* bounding box on each of the two axes of the graphics coordinate -* system (the base Frame of the Plot). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - An error results if the base Frame of the Plot is not -* 2-dimensional. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameSet *fset; /* Pointer to the Plot's FrameSet */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Get a pointer to the FrameSet at the start of the Plot. */ - fset = (AstFrameSet *) this; - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( fset ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "astBoundingBox(%s): Number of axes (%d) in the " - "base Frame of the supplied %s is invalid - this number " - "should be 2.", status, astGetClass( this ), naxes, - astGetClass( this ) ); - } - -/* Return the bounding box. */ - lbnd[ 0 ] = Boxp_lbnd[ 0 ]; - lbnd[ 1 ] = Boxp_lbnd[ 1 ]; - ubnd[ 0 ] = Boxp_ubnd[ 0 ]; - ubnd[ 1 ] = Boxp_ubnd[ 1 ]; - -/* Return. */ - return; - -} - -static int BoxCheck( float *bx, float *by, float *cx, float *cy, int *status ) { -/* -* Name: -* BoxCheck - -* Purpose: -* See if two boxes overlap. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int BoxCheck( float *bx, float *by, float *cx, float *cy, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns a flag indicating if two trapezoidal boxes -* (box "b" and box "c") overlap or not. - -* Parameters: -* bx -* Pointer to an array holding the X coordinates at the 4 corners -* of box "b". -* by -* Pointer to an array holding the Y coordinates at the 4 corners -* of box "b". -* cx -* Pointer to an array holding the X coordinates at the 4 corners -* of box "c". -* cy -* Pointer to an array holding the Y coordinates at the 4 corners -* of box "c". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the boxes do not overlap or an error has -* already occurred. Otherwise, 1 is returned. - -*/ - -/* Local Variables: */ - float x2; - float y2; - int i; - int ip; - int j; - int jp; - int ret; - -/* Assume the boxes do not overlap. */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Check each corner of box b to see if it is inside box c. */ - for( j = 0; j < 4 && ret == 0; j++ ){ - if( Inside( 4, cx, cy, bx[ j ], by[ j ], status ) ) ret = 1; - } - -/* Now check each corner of box c to see if it is inside box b. */ - for( j = 0; j < 4 && ret == 0; j++ ){ - if( Inside( 4, bx, by, cx[ j ], cy[ j ], status ) ) ret = 1; - } - -/* If no overlap has yet been found, we need to see if any of the edges - of the boxes intersect. For instance, in the case of a cross formed by - a vertical rectangle crossing a horizontal rectangle, the above checks - on the corners would not have revealed any overlap. */ - if( !ret ) { - -/* The following code assumes that the corners with indices 0, 1, 2, 3 - are adjacent round the edge of the box. This is the case if the line - joining corners 0 and 1 does not cross the line joining corners 2 and - 3 AND the line joining corners 1 and 2 does not cross the line joining - corners 3 and 0. If either of these conditions is not met swap the - corners around to correct it. First do box b. */ - if( Cross( bx[0], by[0], bx[1], by[1], - bx[2], by[2], bx[3], by[3], status ) ) { - x2 = bx[2]; - y2 = by[2]; - bx[2] = bx[1]; - by[2] = by[1]; - bx[1] = x2; - by[1] = y2; - - } else if( Cross( bx[1], by[1], bx[2], by[2], - bx[3], by[3], bx[0], by[0], status ) ) { - x2 = bx[2]; - y2 = by[2]; - bx[2] = bx[3]; - by[2] = by[3]; - bx[3] = x2; - by[3] = y2; - } - -/* Now do box c. */ - if( Cross( cx[0], cy[0], cx[1], cy[1], - cx[2], cy[2], cx[3], cy[3], status ) ) { - x2 = cx[2]; - y2 = cy[2]; - cx[2] = cx[1]; - cy[2] = cy[1]; - cx[1] = x2; - cy[1] = y2; - - } else if( Cross( cx[1], cy[1], cx[2], cy[2], - cx[3], cy[3], cx[0], cy[0], status ) ) { - x2 = cx[2]; - y2 = cy[2]; - cx[2] = cx[3]; - cy[2] = cy[3]; - cx[3] = x2; - cy[3] = y2; - } - -/* We now check each edge of box b to see if it overlaps any edge of box c. */ - for( j = 0; j < 4 && ret == 0; j++ ) { - -/* This edge of box b starts at the corner with index j. Get the index of the - corner at which the edge ends. */ - jp = j + 1; - if( jp == 4 ) jp = 0; - -/* Check to see if this edge of box b crosses each edge of box c in turn. */ - for( i = 0; i < 4 && ret == 0; i++ ) { - ip = i + 1; - if( ip == 4 ) ip = 0; - - ret = Cross( bx[j], by[j], bx[jp], by[jp], - cx[i], cy[i], cx[ip], cy[ip], status ); - - } - } - } - - return ret; -} - -static void Bpoly( AstPlot *this, float x, float y, int *status ){ -/* -* Name: -* Bpoly - -* Purpose: -* Begin a new poly line. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Bpoly( AstPlot *this, float x, float y, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws any current poly line, and then starts a new one -* at the supplied position. - -* Parameters: -* x -* The graphics x coordinate. -* y -* The graphics y coordinate. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int ignore; /* Is the new point the end of the current polyline? */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* See if the new point is co-incident with the end of the current - polyline. If so we assume the current polyline is to be re-started, - rather than starting a new polyline. */ - if( Poly_n > 0 ) { - ignore = ( astEQUALS( Poly_x[ Poly_n - 1 ], x, 1.0E8 ) && - astEQUALS( Poly_y[ Poly_n - 1 ], y, 1.0E8 ) ); - } else { - ignore = 0; - } - -/* If the supplied point is not at the end of the current polyline, draw - any existing poly line. This will empty the buffer. Then add the - supplied point into the buffer. */ - if( !ignore ) { - Opoly( this, status ); - Apoly( this, x, y, status ); - } - -} - - -static int CGCapWrapper( AstPlot *this, int cap, int value, int *status ) { -/* -* -* Name: -* CGCapWrapper - -* Purpose: -* Call a C implementation of the GCap Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGCapWrapper( AstPlot *this, int cap, int value, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GCap -* grf function to enquire or set a graphics attribute value. - -* Parameters: -* this -* The Plot. -* cap -* The capability to be inquired aboue. -* value -* The value to assign to the capability. -* status -* Pointer to the inherited status value. - -* Returned Value: -* Non-zero if the grf module is capabale of performing the action -* requested by "cap". - -*/ - if( !astOK ) return 0; - return ( (AstGCapFun) this->grffun[ AST__GCAP ] )( astGrfConID(this), cap, value ); -} - -static int CGAttrWrapper( AstPlot *this, int attr, double value, - double *old_value, int prim, int *status ) { -/* -* -* Name: -* CGAttrWrapper - -* Purpose: -* Call a C implementation of the GAttr Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGAttrWrapper( AstPlot *this, int attr, double value, -* double *old_value, int prim, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GAttr -* grf function to enquire or set a graphics attribute value. - -* Parameters: -* this -* The Plot. -* attr -* An integer value identifying the required attribute. The -* following symbolic values are defined in grf.h: -* -* GRF__STYLE - Line style. -* GRF__WIDTH - Line width. -* GRF__SIZE - Character and marker size scale factor. -* GRF__FONT - Character font. -* GRF__COLOUR - Colour index. -* value -* A new value to store for the attribute. If this is AST__BAD -* no value is stored. -* old_value -* A pointer to a double in which to return the attribute value. -* If this is NULL, no value is returned. -* prim -* The sort of graphics primitive to be drawn with the new attribute. -* Identified by the following values defined in grf.h: -* GRF__LINE -* GRF__MARK -* GRF__TEXT -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGAttrFun) this->grffun[ AST__GATTR ] )( astGrfConID(this), attr, value, old_value, prim ); -} - -static int CGBBufWrapper( AstPlot *this, int *status ) { -/* -* -* Name: -* CGBBufWrapper - -* Purpose: -* Call a C implementation of the GBBuf Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGBBufWrapper( AstPlot *this ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GBBuf -* grf function to start a new graphics context. - -* Parameters: -* this -* The Plot. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGBBufFun) this->grffun[ AST__GBBUF ])( astGrfConID(this) ); -} - -static int CGEBufWrapper( AstPlot *this, int *status ) { -/* -* -* Name: -* CGEBufWrapper - -* Purpose: -* Call a C implementation of the GEBuf Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGEBufWrapper( AstPlot *this ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GEBuf -* grf function to start a new graphics context. - -* Parameters: -* this -* The Plot. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGEBufFun) this->grffun[ AST__GEBUF ])( astGrfConID(this) ); -} - -static int CGFlushWrapper( AstPlot *this, int *status ) { -/* -* -* Name: -* CGFlushWrapper - -* Purpose: -* Call a C implementation of the GFlush Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGFlushWrapper( AstPlot *this ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GFlush -* grf function to flush graphics. - -* Parameters: -* this -* The Plot. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGFlushFun) this->grffun[ AST__GFLUSH ])( astGrfConID(this) ); -} - -static int CGLineWrapper( AstPlot *this, int n, const float *x, - const float *y, int *status ) { -/* -* -* Name: -* CGLineWrapper - -* Purpose: -* Call a C implementation of the GLine Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGLineWrapper( AstPlot *this, int n, const float *x, -* const float *y, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GLine -* grf function to draw a polyline. - -* Parameters: -* this -* The Plot. -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* status -* Pointer to the inherited status variable. - -*/ - if( !astOK ) return 0; - return ( (AstGLineFun) this->grffun[ AST__GLINE ])( astGrfConID(this), n, x, y ); -} - -static int CGMarkWrapper( AstPlot *this, int n, const float *x, - const float *y, int type, int *status ) { -/* -* -* Name: -* CGMarkWrapper - -* Purpose: -* Call a C implementation of the GMark Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGMarkWrapper( AstPlot *this, int n, const float *x, -* const float *y, int type, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GMark grf -* function to draw markers. - -* Parameters: -* this -* The Plot. -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* type -* An integer which can be used to indicate the type of marker symbol -* required. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGMarkFun) this->grffun[ AST__GMARK ])( astGrfConID(this), n, x, y, type ); -} - -static int CGTextWrapper( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy, int *status ) { -/* -* -* Name: -* CGTextWrapper - -* Purpose: -* Call a C implementation of the GText Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGTextWrapper( AstPlot *this, const char *text, float x, float y, -* const char *just, float upx, float upy, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GText grf -* function to draw a text string. - -* Parameters: -* this -* The Plot. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGTextFun) this->grffun[ AST__GTEXT ])( astGrfConID(this), text, x, y, just, upx, upy ); -} - -static int CGTxExtWrapper( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy, float *xb, - float *yb, int *status ) { -/* -* -* Name: -* CGTxExtWrapper - -* Purpose: -* Call a C implementation of the GTxExt Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGTxExtWrapper( AstPlot *this, const char *text, float x, float y, -* const char *just, float upx, float upy, float *xb, -* float *yb, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GTxExt -* grf function to find the extent of a text string. - -* Parameters: -* this -* The Plot. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. -* xb -* An array of 4 elements in which to return the x coordinate of -* each corner of the bounding box. -* yb -* An array of 4 elements in which to return the y coordinate of -* each corner of the bounding box. -* status -* Pointer to the inherited status variable. - -*/ - if( !astOK ) return 0; - return ( (AstGTxExtFun) this->grffun[ AST__GTXEXT ])( astGrfConID(this), text, x, y, just, upx, upy, xb, yb ); -} - -static int CGQchWrapper( AstPlot *this, float *chv, float *chh, int *status ) { -/* -* -* Name: -* CGQchWrapper - -* Purpose: -* Call a C implementation of the GQch Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGQchWrapper( AstPlot *this, float *chv, float *chh, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GQch -* grf function to find the extent of a text string. - -* Parameters: -* this -* The Plot. -* chv -* A pointer to the double which is to receive the height of -* characters drawn vertically. This will be an increment in the X -* axis -* chh -* A pointer to the double which is to receive the height of -* characters drawn vertically. This will be an increment in the Y -* axis -* status -* Pointer to the inherited status value. -*/ - if( !astOK ) return 0; - return ( (AstGQchFun) this->grffun[ AST__GQCH ])( astGrfConID(this), chv, chh ); -} - -static int CGScalesWrapper( AstPlot *this, float *alpha, float *beta, int *status ) { -/* -* -* Name: -* CGScalesWrapper - -* Purpose: -* Call a C implementation of the GScales Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGScalesWrapper( AstPlot *this, float *alpha, float *beta, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GScales -* grf function to find the extent of a text string. - -* Parameters: -* this -* The Plot. -* alpha -* A pointer to the location at which to return the scale for the -* X axis (i.e. Xnorm = alpha*Xworld). -* beta -* A pointer to the location at which to return the scale for the -* Y axis (i.e. Ynorm = beta*Yworld). -* status -* Pointer to the inherited status value. -*/ - if( !astOK ) return 0; - return ( (AstGScalesFun) this->grffun[ AST__GSCALES ])( astGrfConID(this), alpha, beta ); -} - -static int CheckLabels( AstPlot *this, AstFrame *frame, int axis, - double *ticks, int nticks, int force, char **list, - double refval, int *status ){ -/* -* Name: -* CheckLabels - -* Purpose: -* Create tick mark labels and check that adjacent labels are different. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CheckLabels( AstPlot *this, AstFrame *frame, int axis, double *ticks, -* int nticks, int force, char **list, double refval, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function formats the supplied ticks mark values using the -* astFormat method for the supplied Frame. Unless force is non-zero, it -* then checks all pairs of adjacent labels. If a pair is found which are -* identical then the memory holding the labels is released, and a value -* of zero is returned. Otherwise, a value of one is returned, indicating -* that adjacent labels are all different and the labels are returned. - -* Parameters: -* this -* Pointer to the Plot. -* frame -* Pointer to the Frame. -* axis -* The zero-based index of the axis to which the tick marks refer. -* ticks -* Pointer to an array holding the tick mark values. -* nticks -* The number of tick marks supplied by parameter "ticks". -* force -* If non-zero, then no check for identical adjacent labels is -* performed, and the labels are always considered to be OK. -* list -* Pointer to the start of an array of pointers. Each of the -* elements in this array receives a pointer to a string holding a -* formatted label. Each of these strings should be freed using -* astFree when no longer needed. -* refval -* A value to use for the other axis when normalizing. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if any pairs of identical adjacent labels were found. One -* otherwise. - -* Notes: -* - No error is reported if a pair of identical adjacent labels is -* found. -* - If an error has already occurred, or if this function should -* fail for any reason, a value of zero is returned, and the array of -* pointers identified by "list" is filled with NULL pointers. - - -*/ - -/* Local Variables: */ - const char *label; /* Pointer to formatted tick value */ - double val[ 2 ]; /* Workspace for normalizing */ - int i; /* Tick index */ - int len; /* Number of characters in curent label */ - int ok; /* The returned flag */ - -/* Fill the supplied label list with NULL pointers. */ - if( list ) { - for( i = 0; i < nticks; i++ ) list[ i ] = NULL; - } - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise the returned flag to indicate that all adjacent labels are - different. */ - ok = 1; - -/* Normalize and format the first tick mark value. */ - val[ axis ] = ticks[ 0 ]; - val[ 1 - axis ] = refval; - astNorm( frame, val ); - label = astFormat( frame, axis, val[ axis ] ); - -/* Allocate memory holding a copy of the formatted value, and store a - pointer to this copy in the list of labels. */ - if( label ){ - len = strlen( label ) + 1; - list[ 0 ] = (char *) astStore( NULL, (void *) label, len ); - } else { - ok = 0; - } - -/* Normalize and format each of the tick mark values in this batch. */ - for( i = 1; i < nticks && astOK && ok; i++ ){ - val[ axis ] = ticks[ i ]; - val[ 1 - axis ] = refval; - astNorm( frame, val ); - label = astFormat( frame, axis, val[ axis ] ); - if( label ){ - -/* Unless checks have been supressed, compare this label with the previous - label. If they are identical clear the returned flag. */ - if( !force && !strcmp( label, list[ i - 1 ] ) ) { - ok = 0; - -/* Allocate memory holding a copy of the label, and store a - pointer to this copy in the list of labels. */ - } else { - list[ i ] = (char *) astStore( NULL, (void *) label, strlen( label ) + 1 ); - } - - } else { - ok = 0; - } - - } - -/* If two adjacent labels were identical, or an error occurred, release the - memory used to store the labels. */ - if( !ok || !astOK ){ - for( i = 0; i < nticks; i++ ){ - if( list[ i ] ) list[ i ] = (char *) astFree( (void *) list[ i ] ); - } - } - -/* Ensure a value of zero is returned if an error has occurred. */ - if( !astOK ) ok = 0; - -/* Return the answer. */ - return ok; - -} - -static char **CheckLabels2( AstPlot *this, AstFrame *frame, int axis, - double *ticks, int nticks, char **old_list, - double refval, int *status ){ -/* -* Name: -* CheckLabels2 - -* Purpose: -* Check that labels cannot be shortened. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* char **CheckLabels2( AstPlot *this, AstFrame *frame, int axis, -* double *ticks, int nticks, char **old_list, -* double refval, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function formats the supplied ticks mark values using the -* astFormat method for the supplied Frame. It then compares the labels -* with the corresponding labels supplied in "old_list". If all of the -* new labels are shorter than, or equal in length to, the old labels, -* then memory is allocated to hold the new (shorter) labels, and a -* pointer to this memory is returned. If any new label is longer than -* the corresponding old label, then a NULL pointer is returned. -* -* No check is performed on whether or not there are any identical -* adjacent labels. - -* Parameters: -* this -* Pointer to the Plot. -* frame -* Pointer to the Frame. -* axis -* The zero-based index of the axis to which the tick marks refer. -* ticks -* Pointer to an array holding the tick mark values. -* nticks -* The number of tick marks supplied by parameter "ticks". -* old_list -* Pointer to the start of an array of pointers. Each of the -* elements in this array should hold a pointer to a string holding a -* formatted label. -* refval -* A value to use for the other axis when normalizing. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to an array of pointers. Each of these pointers points to -* a text string holding a shortened label. If a complete set of -* shortened labels could not be found (or if an error occurs), a NULL -* pointer is returned. - -* Notes: -* - The memory holding the returned shortened labels should be -* freed by cthe caller, together with the memory holding the pointers to -* the labels. -* - No error is reported if a pair of identical adjacent labels is -* found. -* - If an error has already occurred, or if this function should -* fail for any reason, a value of NULL is returned. - -*/ - -/* Local Variables: */ - char **list; /* The returned pointer */ - const char *label; /* Pointer to formatted tick value */ - double val[ 2 ]; /* Workspace for normalizing */ - int i; /* Tick index */ - int llen; /* Number of characters in curent label */ - int ok; /* Are the old labels OK to be used? */ - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Allocate memory to hold the pointers to the new labels. */ - list = (char **) astMalloc( sizeof( char * )*(size_t) nticks ); - if( list ) { - -/* Fill this array with NULLs for safety. */ - for( i = 0; i < nticks; i++ ) list[ i ] = NULL; - -/* Initialise a flag to indicate that all the new labels are - shorter than the old labels. */ - ok = 0; - -/* Normalize and format each of the tick mark values in this batch. */ - for( i = 0; i < nticks && astOK; i++ ){ - val[ axis ] = ticks[ i ]; - val[ 1 - axis ] = refval; - astNorm( frame, val ); - label = astFormat( frame, axis, val[ axis ] ); - if( label ){ - -/* Get the length of the new label. */ - llen = strlen( label ); - -/* Compare this label with the corresponding old label. If the new one is - longer than the old one, set the flag and leave the loop. */ - if( llen > strlen( old_list[ i ] ) ) { - ok = 1; - break; - } - -/* Store the new label. */ - list[ i ] = (char *) astStore( NULL, (void *) label, - (size_t) (llen + 1) ); - } - } - -/* If the old labels are to be used, or an error occurred, release the memory - used to store the new labels. */ - if( ok || !astOK ){ - for( i = 0; i < nticks; i++ ){ - if( list[ i ] ) list[ i ] = (char *) astFree( (void *) list[ i ] ); - } - list = (char **) astFree( (void *) list ); - } - - } - -/* Return the answer. */ - return list; - -} - -static int ChrLen( const char *string, int *status ){ -/* -* Name: -* ChrLen - -* Purpose: -* Return the length of a string excluding any trailing white space. - -* Type: -* Private function. - -* Synopsis: -* int ChrLen( const char *string, int *status ) - -* Class Membership: -* Plot - -* Description: -* This function returns the length of a string excluding any trailing -* white space. - -* Parameters: -* string -* Pointer to the string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The length of a string excluding any trailing white space. - -* Notes: -* - A value of zero is returned if a NULL pointer is supplied, or if an -* error has already occurred. - -*/ - -/* Local Variables: */ - const char *c; /* Pointer to the next character to check */ - int ret; /* The returned string length */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise the returned string length. */ - ret = 0; - -/* Check a string has been supplied. */ - if( string ){ - -/* Check each character in turn, starting with the last one. */ - ret = strlen( string ); - c = string + ret - 1; - while( ret ){ - if( !isspace( (int) *c ) ) break; - c--; - ret--; - } - } - -/* Return the answer. */ - return ret; - -} - -static AstPlotCurveData **CleanCdata( AstPlotCurveData **cdata, int *status ){ -/* -* Name: -* CleanCdata - -* Purpose: -* Release the structures holding curve break information. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPlotCurveData **CleanCdata( AstPlotCurveData **cdata, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function releases the memory used to hold the curve break -* information returned by function DrawGrid, and returns a NULL pointer. - -* Parameters: -* cdata -* Pointer to the information to be freed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A NULL pointer. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. - -*/ - -/* Return if a NULL pointer has been supplied. */ - if( !cdata ) return NULL; - -/* Release each of the two structures in turn (if they exist). */ - (void) astFree( (void *) cdata[ 0 ] ); - (void) astFree( (void *) cdata[ 1 ] ); - -/* Release the memory used to hold the two AstPlotCurveData pointers. */ - (void) astFree( (void *) cdata ); - -/* Return. */ - return NULL; - -} - -static TickInfo **CleanGrid( TickInfo **grid, int *status ){ -/* -* Name: -* CleanGrid - -* Purpose: -* Release the structures holding grid information. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* TickInfo **CleanGrid( TickInfo **grid ) - -* Class Membership: -* Plot member function. - -* Description: -* This function releases the memory used to hold the grid information -* returned by function GridLines, and returns a NULL pointer. - -* Parameters: -* grid -* Pointer to the information to be freed. - -* Returned Value: -* A NULL pointer. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. - -*/ - -/* Local Variables: */ - TickInfo *info; /* Pointer to TickInfo structure being freed */ - int i; /* Axis index */ - int j; /* Tick mark index */ - -/* Return if a NULL pointer has been supplied. */ - if( !grid ) return NULL; - -/* Release each of the TickInfo structures in turn (if they exist). */ - for( i = 0; i < 2; i++ ){ - if( ( info = grid[ i ] ) ){ - -/* Release the memory holding major tick mark values. */ - (void) astFree( (void *) info->ticks ); - -/* Release the memory holding minor tick mark values. */ - (void) astFree( (void *) info->minticks ); - -/* Release the memory holding curve section starting positions. */ - (void) astFree( (void *) info->start ); - -/* Release the memory holding curve section lengths. */ - (void) astFree( (void *) info->length ); - -/* If there are any tick mark labels in the structure... */ - if( info->labels ){ - -/* Release the memory holding each tick mark label. */ - for( j = 0; j < info->nmajor; j++ ){ - (void) astFree( (void *) info->labels[ j ] ); - } - -/* Release the memory holding the pointers to the tick mark labels. */ - (void) astFree( (void *) info->labels ); - -/* Release the memory holding the format specification string. */ - (void) astFree( (void *) info->fmt ); - - } - -/* Release the TickInfo structure. */ - (void) astFree( (void *) info ); - } - } - -/* Release the memory used to hold the two TickInfo pointers. */ - (void) astFree( (void *) grid ); - -/* Return. */ - return NULL; - -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Plot. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Plot member function (over-rides the astClearAttrib protected -* method inherited from the FrameSet class). - -* Description: -* This function clears the value of a specified attribute for a -* Plot, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Plot. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to the Plot structure */ - char label[21]; /* Graphics item label */ - const char *class; /* Pointer to class string */ - int axis; /* Axis number */ - int id1; /* Plot object id */ - int id2; /* Plot object id */ - int id; /* Plot object id */ - int len; /* Length of attrib string */ - int nax; /* Number of base Frame axes */ - int nc; /* No. characters read by astSscanf */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Get the number of base Frame axis (2 for a Plot, 3 for a Plot3D). */ - nax = astGetNin( this ); - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Edge(axis). */ -/* ------------ */ - if ( nc = 0, - ( 1 == astSscanf( attrib, "edge(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearEdge( this, axis - 1 ); - -/* Grid. */ -/* ----- */ - } else if ( !strcmp( attrib, "grid" ) ) { - astClearGrid( this ); - -/* LabelUp */ -/* ------- */ - } else if ( !strcmp( attrib, "labelup" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLabelUp( this, axis ); - -/* LabelUp(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelup(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLabelUp( this, axis - 1 ); - -/* LogPlot */ -/* ------- */ - } else if ( !strcmp( attrib, "logplot" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLogPlot( this, axis ); - -/* LogPlot(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logplot(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLogPlot( this, axis - 1 ); - -/* LogTicks */ -/* ------- */ - } else if ( !strcmp( attrib, "logticks" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLogTicks( this, axis ); - -/* LogTicks(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logticks(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLogTicks( this, axis - 1 ); - -/* LogLabel */ -/* ------- */ - } else if ( !strcmp( attrib, "loglabel" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLogLabel( this, axis ); - -/* LogLabel(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loglabel(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLogLabel( this, axis - 1 ); - -/* NumLab. */ -/* ---------- */ - } else if ( !strcmp( attrib, "numlab" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearNumLab( this, axis ); - -/* NumLab(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearNumLab( this, axis - 1 ); - -/* MinTick. */ -/* ---------- */ - } else if ( !strcmp( attrib, "mintick" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearMinTick( this, axis ); - -/* MinTick(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "mintick(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearMinTick( this, axis - 1 ); - -/* TextLab. */ -/* ---------- */ - } else if ( !strcmp( attrib, "textlab" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearTextLab( this, axis ); - -/* TextLab(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearTextLab( this, axis - 1 ); - -/* LabelUnits. */ -/* --------- */ - } else if ( !strcmp( attrib, "labelunits" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLabelUnits( this, axis ); - -/* LabelUnits(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelunits(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLabelUnits( this, axis - 1 ); - -/* Style. */ -/* ------ */ - } else if ( !strcmp( attrib, "style" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearStyle( this, id ); - -/* Style(label). */ -/* --------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "style(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearStyle( this, id1 ); - if( nid > 1 ) astClearStyle( this, id2 ); - if( nid > 2 ) astClearStyle( this, id3 ); - -/* Font. */ -/* ----- */ - } else if ( !strcmp( attrib, "font" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearFont( this, id ); - -/* Font(label). */ -/* -------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "font(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearFont( this, id1 ); - if( nid > 1 ) astClearFont( this, id2 ); - if( nid > 2 ) astClearFont( this, id3 ); - -/* Colour. */ -/* ------- */ - } else if ( !strcmp( attrib, "colour" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearColour( this, id ); - -/* Colour(label). */ -/* ---------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "colour(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearColour( this, id1 ); - if( nid > 1 ) astClearColour( this, id2 ); - if( nid > 2 ) astClearColour( this, id3 ); - -/* Color. */ -/* ------ */ - } else if ( !strcmp( attrib, "color" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearColour( this, id ); - -/* Color(label). */ -/* --------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "color(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearColour( this, id1 ); - if( nid > 1 ) astClearColour( this, id2 ); - if( nid > 2 ) astClearColour( this, id3 ); - -/* Width. */ -/* ------ */ - } else if ( !strcmp( attrib, "width" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearWidth( this, id ); - -/* Width(label). */ -/* --------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "width(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - - astClearWidth( this, id1 ); - if( nid > 1 ) astClearWidth( this, id2 ); - if( nid > 2 ) astClearWidth( this, id3 ); - -/* Size. */ -/* ----- */ - } else if ( !strcmp( attrib, "size" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearSize( this, id ); - -/* Size(label). */ -/* -------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "size(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearSize( this, id1 ); - if( nid > 1 ) astClearSize( this, id2 ); - if( nid > 2 ) astClearSize( this, id3 ); - -/* LabelAt(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelat(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLabelAt( this, axis - 1 ); - -/* Centre(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "centre(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearCentre( this, axis - 1 ); - -/* Gap. */ -/* ---- */ - } else if ( !strcmp( attrib, "gap" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearGap( this, axis ); - -/* Gap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "gap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearGap( this, axis - 1 ); - -/* LogGap. */ -/* ----------- */ - } else if ( !strcmp( attrib, "loggap" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLogGap( this, axis ); - -/* LogGap(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loggap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLogGap( this, axis - 1 ); - -/* NumLabGap. */ -/* ---------- */ - } else if ( !strcmp( attrib, "numlabgap" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearNumLabGap( this, axis ); - -/* NumLabGap(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearNumLabGap( this, axis - 1 ); - -/* TextLabGap. */ -/* ----------- */ - } else if ( !strcmp( attrib, "textlabgap" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearTextLabGap( this, axis ); - -/* TextLabGap(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearTextLabGap( this, axis - 1 ); - -/* TitleGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "titlegap" ) ) { - astClearTitleGap( this ); - -/* MajTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "majticklen" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearMajTickLen( this, axis ); - -/* MajTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "majticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearMajTickLen( this, axis - 1 ); - -/* MinTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "minticklen" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearMinTickLen( this, axis ); - -/* MinTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "minticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearMinTickLen( this, axis - 1 ); - -/* Labelling. */ -/* -------- */ - } else if ( !strcmp( attrib, "labelling" ) ) { - astClearLabelling( this ); - -/* TickAll. */ -/* -------- */ - } else if ( !strcmp( attrib, "tickall" ) ) { - astClearTickAll( this ); - -/* ForceExterior */ -/* ------------- */ - } else if ( !strcmp( attrib, "forceexterior" ) ) { - astClearForceExterior( this ); - -/* Invisible. */ -/* ---------- */ - } else if ( !strcmp( attrib, "invisible" ) ) { - astClearInvisible( this ); - -/* Border. */ -/* ------- */ - } else if ( !strcmp( attrib, "border" ) ) { - astClearBorder( this ); - -/* ClipOp. */ -/* ------- */ - } else if ( !strcmp( attrib, "clipop" ) ) { - astClearClipOp( this ); - -/* Clip. */ -/* ----- */ - } else if ( !strcmp( attrib, "clip" ) ) { - astClearClip( this ); - -/* Grf. */ -/* ---- */ - } else if ( !strcmp( attrib, "grf" ) ) { - astClearGrf( this ); - -/* DrawTitle. */ -/* ---------- */ - } else if ( !strcmp( attrib, "drawtitle" ) ) { - astClearDrawTitle( this ); - -/* DrawAxes. */ -/* --------- */ - } else if ( !strcmp( attrib, "drawaxes" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearDrawAxes( this, axis ); - -/* Abbrev */ -/* ------ */ - } else if ( !strcmp( attrib, "abbrev" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearAbbrev( this, axis ); - -/* DrawAxes(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "drawaxes(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearDrawAxes( this, axis - 1 ); - -/* Abbrev(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "abbrev(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearAbbrev( this, axis - 1 ); - -/* Escape. */ -/* ------- */ - } else if ( !strcmp( attrib, "escape" ) ) { - astClearEscape( this ); - -/* Tol. */ -/* ---- */ - } else if ( !strcmp( attrib, "tol" ) ) { - astClearTol( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearLogPlot( AstPlot *this, int axis, int *status ){ -/* -* -* Name: -* ClearLogPlot - -* Purpose: -* Clear the value for a LogPlot attribute - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void ClearLogPlot( AstPlot *this, int axis, int *status ) - -* Class Membership: -* Plot member function - -* Description: -* Assigns the default value to the LogPlot attribute of the specified -* axis, and also re-maps the base Frame of the Plot if necessary. - -* Parameters: -* this -* The Plot. -* axis -* Zero based axis index. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int oldval; /* Original value of the attribute */ - int newval; /* Cleared (default) value of the attribute */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the axis index. */ - if( axis < 0 || axis >= 2 ){ - astError( AST__AXIIN, "astClearLogPlot(%s): Index (%d) is invalid for " - "attribute LogPlot - it should be in the range 1 to 2.", status, - astGetClass( this ), axis + 1 ); - -/* Do nothing if the attribute is not currently set. */ - } else if( astTestLogPlot( this, axis ) ){ - -/* Get the original value of the attribute. clear the value, and then get - the new (default) value. */ - oldval = this->logplot[ axis ]; - this->logplot[ axis ] = -1; - newval = astGetLogPlot( this, axis ); - -/* If the effective value has changed, attempt to remap the axis. If this - fails, re-instate the original value. */ - if( ( oldval != 0 ) != ( newval != 0 ) ) { - if( !ToggleLogLin( this, axis, oldval, "astClearLogPlot", status ) ) { - this->logplot[ axis ] = oldval; - } - } - } -} - -static void Clip( AstPlot *this, int iframe, const double lbnd[], - const double ubnd[], int *status ){ -/* -*++ -* Name: -c astClip -f AST_CLIP - -* Purpose: -* Set up or remove clipping for a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astClip( AstPlot *this, int iframe, const double lbnd[], -c const double ubnd[] ) -f CALL AST_CLIP( THIS, IFRAME, LBND, UBND, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function defines regions of a Plot which are to be clipped. -f This routine defines regions of a Plot which are to be clipped. -* Any subsequent graphical output created using the Plot will then -* be visible only within the unclipped regions of the plotting -* area. See also the Clip attribute. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c iframe -f IFRAME = INTEGER (Given) -* The index of the Frame within the Plot to which the clipping -c limits supplied in "lbnd" and "ubnd" (below) refer. Clipping -f limits supplied in LBND and UBND (below) refer. Clipping -* may be applied to any of the coordinate systems associated -* with a Plot (as defined by the Frames it contains), so this -* index may take any value from 1 to the number of Frames in -* the Plot (Nframe attribute). In addition, the values -* AST__BASE and AST__CURRENT may be used to specify the base -* and current Frames respectively. -* -* For example, a value of AST__CURRENT causes clipping to be -* performed in physical coordinates, while a value of AST__BASE -* would clip in graphical coordinates. Clipping may also be -* removed completely by giving a value of AST__NOFRAME. In this -* case any clipping bounds supplied (below) are ignored. -c lbnd -f LBND( * ) = DOUBLE PRECISION (Given) -* An array with one element for each axis of the clipping Frame -c (identified by the index "iframe"). This should contain the -f (identified by the index IFRAME). This should contain the -* lower bound, on each axis, of the region which is to remain -* visible (unclipped). -c ubnd -f UBND( * ) = DOUBLE PRECISION (Given) -* An array with one element for each axis of the clipping Frame -c (identified by the index "iframe"). This should contain the -f (identified by the index IFRAME). This should contain the -* upper bound, on each axis, of the region which is to remain -* visible (unclipped). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - Only one clipping Frame may be active at a time. This function -f - Only one clipping Frame may be active at a time. This routine -* will deactivate any previously-established clipping Frame before -* setting up new clipping limits. -c - The clipping produced by this function is in addition to that -f - The clipping produced by this routine is in addition to that -* specified by the Clip attribute which occurs at the edges of the -* plotting area -c established when the Plot is created (see astPlot). The -f established when the Plot is created (see AST_PLOT). The -* underlying graphics system may also impose further clipping. -* - When testing a graphical position for clipping, it is first -* transformed into the clipping Frame. The resulting coordinate on -* each axis is then checked against the clipping limits (given by -c "lbnd" and "ubnd"). By default, a position is clipped if any -f LBND and UBND). By default, a position is clipped if any -* coordinate lies outside these limits. However, if a non-zero -* value is assigned to the Plot's ClipOp attribute, then a -* position is only clipped if the coordinates on all axes lie -* outside their clipping limits. -* - If the lower clipping limit exceeds the upper limit for any -* axis, then the sense of clipping for that axis is reversed (so -* that coordinate values lying between the limits are clipped -* instead of those lying outside the limits). To produce a "hole" -* in a coordinate space (that is, an internal region where nothing -* is plotted), you should supply all the bounds in reversed order, -* and set the ClipOp attribute for the Plot to a non-zero value. -* - Either clipping limit may be set to the value AST__BAD, which -* is equivalent to setting it to infinity (or minus infinity for a -* lower bound) so that it is not used. -* - If a graphical position results in any bad coordinate values -* (AST__BAD) when transformed into the clipping Frame, then it is -* treated (for the purposes of producing graphical output) as if -* it were clipped. -* - When a Plot is used as a Mapping to transform points -c (e.g. using astTran2), any clipped output points are assigned -f (e.g. using AST_TRAN2), any clipped output points are assigned -* coordinate values of AST__BAD. -* - An error results if the base Frame of the Plot is not -* 2-dimensional. -*-- -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to the clipping Frame */ - AstFrameSet *fset; /* Pointer to the Plot's FrameSet */ - int i; /* Axis index */ - int ifrm; /* The validated frame index */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - ifrm = 0; - -/* Get a pointer to the FrameSet at the start of the Plot. */ - fset = (AstFrameSet *) this; - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( fset ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "astClip(%s): Number of axes (%d) in the " - "base Frame of the supplied %s is invalid - this number " - "should be 2.", status, astGetClass( this ), naxes, - astGetClass( this ) ); - } - -/* If clipping is to be switched on, check the supplied frame index and - bounds. */ - if( iframe != AST__NOFRAME && astOK ) { - -/* Report an error if either of the bounds pointers is NULL.*/ - if( !lbnd ){ - astError( AST__CLPAX, "astClip(%s): A NULL pointer was " - "supplied for the array holding the lower bounds of " - "the clipping volume.", status, astGetClass( this ) ); - } else if( !ubnd ){ - astError( AST__CLPAX, "astClip(%s): A NULL pointer was " - "supplied for the array holding the upper bounds of " - "the clipping volume.", status, astGetClass( this ) ); - } - -/* Validate the clipping frame index. */ - ifrm = astValidateFrameIndex( fset, iframe, "astClip" ); - -/* Get the number of axes in the clipping frame. */ - fr = astGetFrame( this, ifrm ); - naxes = astGetNaxes( fr ); - fr = astAnnul( fr ); - - } - -/* Leave the current clipping information unchanged if an error has - occurred. */ - if( astOK ){ - -/* Remove all clipping information from the Plot. */ - this->clip_lbnd = (double *) astFree( (void *) this->clip_lbnd ); - this->clip_ubnd = (double *) astFree( (void *) this->clip_ubnd ); - this->clip_frame = AST__NOFRAME; - this->clip_axes = 0; - -/* If bounds have been supplied, set up new clipping information. */ - if( iframe != AST__NOFRAME ){ - -/* Store the information. */ - this->clip_frame = ifrm; - this->clip_lbnd = astStore( NULL, lbnd, sizeof(double)*(size_t)naxes ); - this->clip_ubnd = astStore( NULL, ubnd, sizeof(double)*(size_t)naxes ); - this->clip_axes = naxes; - -/* If an error has occurred, remove all clipping information. */ - if( !astOK ){ - this->clip_lbnd = (double *) astFree( (void *) this->clip_lbnd ); - this->clip_ubnd = (double *) astFree( (void *) this->clip_ubnd ); - this->clip_frame = AST__NOFRAME; - this->clip_axes = 0; - -/* Otherwise, replace any bounds of AST__BAD with suitable default - values. */ - } else { - for( i = 0; i < naxes; i++ ){ - if( this->clip_lbnd[ i ] == AST__BAD ) this->clip_lbnd[ i ] = -DBL_MAX; - if( this->clip_ubnd[ i ] == AST__BAD ) this->clip_ubnd[ i ] = DBL_MAX; - } - - } - - } - - } - -/* Return. */ - return; - -} - -static int Compared( const void *elem1, const void *elem2 ){ -/* -* Name: -* Compared - -* Purpose: -* Compare two "double" values. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Compared( const void *elem1, const void *elem2 ) - -* Class Membership: -* Plot method. - -* Description: -* This function compares the two "double" values to which pointers -* are supplied, and returns an integer indicating which is larger, -* checking for AST__BAD values. It is intended for use with the C -* Run-Time-Library sorting function "qsort". - -* Parameters: -* elem1 -* Pointer to the first "double". -* elem2 -* Pointer to the second "double". - -* Returned Value: -* Zero is returned if the values are equal. If the first is larger -* than the second then +1 is returned. Otherwise, -1 is returned. - -* Notes: -* - Values of AST__BAD are considered to be larger than any other -* value (other than another value of AST__BAD). -* - If both values are AST__BAD, then zero is returned. -* - This function executes even if an error has occurred. - -*/ - -/* Local Variables: */ - double *delem1; /* Pointer to the first "double" value */ - double *delem2; /* Pointer to the second "double" value */ - int ret; /* The returned value */ - -/* Get pointers to the two "double" values. */ - delem1 = (double *) elem1; - delem2 = (double *) elem2; - -/* Check the values for equality (including both values being AST__BAD). */ - if( *delem1 == *delem2 ){ - ret = 0; - -/* If the first is bad, then it is considered to be larger than the - second. */ - } else if( *delem1 == AST__BAD ){ - ret = 1; - -/* If the second is bad, then it is considered to be larger than the - first. */ - } else if( *delem2 == AST__BAD ){ - ret = -1; - -/* If the first is larger than the second, return 1. */ - } else if( *delem1 > *delem2 ){ - ret = 1; - -/* If the first is smaller than the second, return -1. */ - } else { - ret = -1; - - } - -/* Return the answer. */ - return ret; - -} - -static int Compare_LL( const void *elem1, const void *elem2 ){ -/* -* Name: -* Compare_LL - -* Purpose: -* Compare two LabelList structures as used by function PlotLabels. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Compare_LL( const void *elem1, const void *elem2 ) - -* Class Membership: -* Plot method. - -* Description: -* This function compares two "LabelList" structures as used by function -* PlotLabels, and returns an integer indicating which has a larger -* "index" value. This function is intended to be used with the C -* Run-Time-Library sorting function "qsort". - -* Parameters: -* elem1 -* Pointer to the first LabelList. -* elem2 -* Pointer to the second LabelList. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the values are equal. If the first is larger -* than the second then +1 is returned. Otherwise, -1 is returned. - -* Notes: -* - This function executes even if an error has occurred. - -*/ - -/* Local Variables: */ - LabelList *ll1; /* Pointer to the first LabelList */ - LabelList *ll2; /* Pointer to the second LabelList */ - int ret; /* The returned value */ - -/* Get pointers to the two LabelList structures. */ - ll1 = (LabelList *) elem1; - ll2 = (LabelList *) elem2; - -/* Compare the indices for the two label's. */ - if( ll1->index < ll2->index ){ - ret = -1; - - } else if( ll1->index > ll2->index ){ - ret = 1; - - } else { - ret = 0; - } - -/* Return the answer. */ - return ret; - -} - -static void CopyPlotDefaults( AstPlot *this, int axis, AstPlot *dplot, - int daxis, int *status ){ -/* -*+ -* Name: -* astCopyPlotDefaults - -* Purpose: -* Copy used attribute defaults from one Plot to another. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* void astCopyPlotDefaults( AstPlot *this, int axis, AstPlot *dplot, -* int daxis ) - -* Class Membership: -* Plot method. - -* Description: -* Some of the attributes used by the Plot class have dynamic default -* values that are determined during the process of drawing an annotated -* grid using astGrid. The dynamic default values are stored in a -* separate set of components within the Plot structure. This function -* copies these components from one Plot to another. - -* Parameters: -* this -* Pointer to a Plot containing the values to be copied. -* axis -* The zero-based index of the axis within "this" for which the -* used defaults are to be copied. -* dplot -* A pointer to another Plot into which the default attribute -* values are to be copied. -* daxis -* The zero based index of the axis within "dplot" which is to -* receive the new values. - -*- -*/ - -/* Check the global status. */ - if( !astOK ) return; - - dplot->ulglb[ daxis ] = this->ulglb[ axis ]; - dplot->ulgtk[ daxis ] = this->ulgtk[ axis ]; - dplot->uloggap[ daxis ] = this->uloggap[ axis ]; - dplot->ugap[ daxis ] = this->ugap[ axis ]; - dplot->ucentre[ daxis ] = this->ucentre[ axis ]; - dplot->uedge[ daxis ] = this->uedge[ axis ]; - dplot->ulblat[ daxis ] = this->ulblat[ axis ]; - dplot->ulbunit[ daxis ] = this->ulbunit[ axis ]; - dplot->umintk[ daxis ] = this->umintk[ axis ]; - dplot->utxtlb[ daxis ] = this->utxtlb[ axis ]; - dplot->umjtkln[ daxis ] = this->umjtkln[ axis ]; - - dplot->ugrid = this->ugrid; - dplot->ulbling = this->ulbling; - dplot->uborder = this->uborder; -} - -static int CountGood( int n, double *data, int *status ){ -/* -* Name: -* CountGood - -* Purpose: -* Coount the number of non-bad values in an array. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CountGood( int n, double *data, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns the number of elements in the supplied array -* which do not have the value AST__BAD. - -* Parameters: -* n -* The total number of elements in the array. -* data -* Pointer to the start of the array. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of good points in the array. - -* Notes: -* - A value of zero is returned if an error has already occurred. - -*/ - -/* Local Variables: */ - int i; - int ngood; - double *value; - -/* Check global status. */ - if( !astOK ) return 0; - -/* Initialise a pointer to the next array element, and the number of - good elements found so far. */ - value = data; - ngood = 0; - -/* Check each element. */ - for( i = 0; i < n; i++ ){ - if( *(value++) != AST__BAD ) ngood++; - } - -/* Return the answer. */ - return ngood; - -} - -static int Cross( float ax, float ay, float bx, float by, - float cx, float cy, float dx, float dy, int *status ){ -/* -* Name: -* Cross - -* Purpose: -* See if two line segments intersect. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Cross( float ax, float ay, float bx, float by, -* float cx, float cy, float dx, float dy, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function sees if the line segment (A,B) intersects the line -* segment (C,D). - -* Parameters: -* ax, ay -* The coordinates of A. -* bx, by -* The coordinates of B. -* cx, cy -* The coordinates of C. -* dx, dy -* The coordinates of D. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the line segments do not cross or if an error has already -* occurred, and 1 if they do. - -*/ - -/* Local Variables: */ - int ret; - float m1, m2, denom, num, t1, t2; - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Get the fraction of the distance from A to B at which the line AB - intersects the line CD. */ - m1 = dx - cx; - m2 = dy - cy; - denom = (bx - ax)*m2 - (by-ay)*m1; - num = (ay - cy)*m1 - (ax - cx)*m2; - - if( denom != 0.0 ) { - t1 = num / denom; - -/* If the the intersection occurs within the segment of the line between A - and B... */ - if( t1 >= 0.0 && t1 <= 1.0 ){ - -/* ... then get the fraction of the distance from C to D at which the - line CD intersects the line AB. */ - m1 = bx - ax; - m2 = by - ay; - denom = (dx - cx)*m2 - (dy-cy)*m1; - num = (cy - ay)*m1 - (cx - ax)*m2; - - if( denom != 0.0 ) { - t2 = num / denom; - -/* If the the intersection occurs within the segment of the line between C - and D then the line segments intersect. */ - if( t2 >= 0.0 && t2 <= 1.0 ){ - ret = 1; - } else { - ret = 0; - } - -/* If the two lines are parallel, then they do not intersect. */ - } else { - ret = 0; - } - - } else { - ret = 0; - } - - } else { - ret = 0; - - } - - return ret; -} - -static void Crv( AstPlot *this, double *d, double *x, double *y, int skipbad, - double *box, CrvStatics *pstatics, const char *method, - const char *class, int *status ){ -/* -* Name: -* Crv - -* Purpose: -* Draw a curve. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Crv( AstPlot *this, double *d, double *x, double *y, int skipbad, -* double *box, CrvStatics *pstatics, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a curve parameterised by the distance from some -* starting point. The function pointed to by the external variable -* Crv_map is used to transform distances along the curve into graphics -* coordinates (X,Y). The supplied function parameters defined the -* section of the curve to be drawn. -* -* The algorithm used needs no knowledge about the nature of the mapping -* performed by Crv_map, and can handle discontinuities in the curve. It -* first of all determines if any of the segments of the curve can be -* adequately represented by simply drawing a straight line through the -* supplied end points. This decision is based on several requirements such -* as keeping the angle between adjacent sections low and both ends being -* defined (i.e. X and Y not equal to AST__BAD). Any segments of the curve -* which satisfy the requirements are draw as straight lines. If any of -* the supplied curve segments cannot be drawn in this way, then they are -* split up into a set of evenly-spaced sub-segments and the graphics -* coordinates at the ends of these sub-segments are found using Crv_map. -* This function is then called recursively to draw the sub-segments. This -* recursion is limited in depth by the requirement that all the -* sub-segments must be longer than a specified lower limit. If this is not -* the case, then the curve is assumed to be dis-continuous and and the -* sub-segments are ignored. - -* Parameters: -* d -* Pointer to an array of CRV_NPNT values giving the distance along -* the curve from the starting point to each of CRV_NPNT points. They -* should increase monotonically, and should be in whatever units are -* used by the function pointed to by Crv_map. The curve is drawn from -* d[0] to d[CRV_NPNT]. -* x -* Pointer to an array of CRV_NPNT values giving the graphics X -* coordinate for the positions supplied in the array pointed to by -* parameter "d". -* y -* Pointer to an array of CRV_NPNT values giving the graphics Y -* coordinate for the positions supplied in the array pointed to by -* parameter "d". -* skipbad -* Controls what happens if all the supplied points are bad or -* outside the plotting area. If skipbad is non-zero, then it is -* assumed that the supplied points represent an entirely bad (or -* out of bounds) section of the curve, and this function will -* return without attempt to sub-divide any of the supplied points. -* If skipbad is zero, then it is assumed that we may be able to find -* some good points between the supplied bad points, and therefore -* this function will attempt to sub-divide the supplied points. -* Should be supplied as zero on the initial invocation. -* box -* Pointer to an array of 4 doubles houlding a bounding box within -* which the current segment must reside if it is to be sub-divided. -* Supplied in the order xlo, xhi, ylo, yhi. May be NULL in which -* case, no check is made on the bounding box. -* pstatics -* Pointer to a structure holding values for variables which were -* statically defined within this function prior to the thread-safe -* version of AST. If a NULL pointer is supplied, a new structure -* is created in dynamic memory and initialised. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* External Variables: -* Crv_nent = int (Read/Write) -* The number of recursive entries which have been made into -* this function. This should be set to zero before entering -* this function for the first time. -* Crv_ux0 = double (Read/Write) -* The X component in graphics coordinates of the unit vector -* along the previous segment of the curve. This should be set -* to AST__BAD initially to indicate that the previous section -* is not defined. -* Crv_uy0 = double (Read/Write) -* The Y component of the unit vector along the previous segment. -* Crv_limit = double (Read) -* The square of the maximum acceptable residual between the -* drawn curve and the true curve, in graphics coordinates. -* Crv_scerr = double (Read) -* If the ratio of the lengths of adjacent sub-segments is larger -* than Crv_scerr,then the seub-segments will be sub-divided. Note, -* if either axis is mapped logarithmically onto the screen, then -* there will naturally be large changes in scale. Crv_scerr should -* always be larger than 1.0. -* Crv_map = void (*)( int n, double *dd, double *xx, double *yy, -* const char *method, const char *class ) (Read) -* A pointer to a function which can be called to map "n" distances -* along the curve (supplied in "dd") into graphics coordinates -* (stored in "xx" and "yy"). See function "Map1" as an example. -* Crv_clip = int (Read) -* Should lines be clipped at the edge of the plotting area? - -* Notes: -* - The CRV_TRACE conditional compilation blocks in this function -* provide code which displays the recursive entries made to this -* function (and also pauses on initial entry until return is pressed). -* It is useful for investigating the details of the drawing of a -* curve. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - CrvStatics *statics; /* Pointer to structure holding static values */ - double *dd; /* Pointer to array holding sub-segment distances */ - double *pd; /* Pointer to next sub-segment distance */ - double *px; /* Pointer to next sub-segment x coord. */ - double *py; /* Pointer to next sub-segment y coord. */ - double *xx; /* Pointer to array holding sub-segment x coord.s */ - double *yy; /* Pointer to array holding sub-segment x coord.s */ - double bbox[4]; /* Bounding box for this segment */ - double dl2[ CRV_NSEG ];/* Squred segment lengths */ - double dx[ CRV_NSEG ]; /* X increment along each segment */ - double dy[ CRV_NSEG ]; /* Y increment along each segment */ - int i; /* Segment index */ - int seg_ok[ CRV_NSEG ];/* Flags indicating which segments can be drawn */ - int subdivide; /* Flag indicating if segments can be subdivided */ - -/* Check inherited status */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* If required, allocate memory for a structure to hold the static - variables need by this function. */ - if( ! pstatics ) { - statics = astMalloc( sizeof( CrvStatics ) ); - } else { - statics = pstatics; - } - -/* If this is the first entry, set up the minimum length for a - sub-segment in graphics coordinates. If any segment is less than - this minimum length, then recursion will stop and the curve will - be assumed to be dis-continuous. */ - if( !Crv_nent ) { - statics->limit2 = 20.0*Crv_limit/(CRV_NSEG*CRV_NSEG); - -#ifdef CRV_TRACE - statics->levels[ 0 ] = 0; -#endif - } - - -/* Increment the number of entries into this function. */ - Crv_nent++; - -#ifdef CRV_TRACE - for( i = 0; i < Crv_nent; i++ ) { - printf("%d ",statics->levels[ i ] ); - } - printf("\n"); - - if( getchar() == 'm' ) { - float ffx,ffy; - for( i = 0; i < CRV_NPNT; i++ ) { - ffx = x[i]; ffy = y[i]; - GMark( this, 1, &ffx, &ffy, 2, method, class, status ); - GFlush( this, method, class, status ); - } - } -#endif - -/* ====================================================================== - The first section of this function sets up some arrays holding - information which will be used later on. It looks at each of the segments - joing adjacent tabulated points, and finds and stores the increments in - X and Y along each segment, and the square of the segment length. It - also checks to see if the tabulated points are all bad, or if they are - all good. It also finds the lowest squared segment length. - ======================================================================*/ - -/* Look at the first tabulated point. If it is good, set a flag to indicate - that it can be used, store it as "the previous position" (i.e. the start of - the current segment). Also set a flag ("all_bad") to indicate if all - points looked at so far have been bad, or outside the plotting area. */ - if( *x != AST__BAD && *y != AST__BAD ){ - statics->last_ok = 1; - statics->last_x = *x; - statics->last_y = *y; - statics->all_bad = ( *x < Crv_xlo || *x > Crv_xhi || - *y < Crv_ylo || *y > Crv_yhi ) && Crv_clip; - } else { - statics->last_ok = 0; - statics->all_bad = 1; - } - -/* Initialise the bouding box for the this segment. */ - bbox[ 0 ] = DBL_MAX; - bbox[ 1 ] = -DBL_MAX; - bbox[ 2 ] = DBL_MAX; - bbox[ 3 ] = -DBL_MAX; - -/* Store pointers to the X and Y values for the "current position". This - is the position at the end of the current segment. This is initially - the second tabulated point. */ - px = x + 1; - py = y + 1; - -/* Store pointers to the increments and squared length for the current - segment. */ - statics->pdx = dx; - statics->pdy = dy; - statics->pdl2 = dl2; - -/* Initialise the number of long and short segments. */ - statics->nlong = 0; - statics->nshort = 0; - -/* Loop round each segment. */ - for( i = 0; i < CRV_NSEG; i++ ){ - -/* If the tabulated point marking the end of the segment is good... */ - if( *px != AST__BAD && *py != AST__BAD ){ - -/* Update the bounding box. */ - if( *px < bbox[ 0 ] ) bbox[ 0 ] = *px; - if( *px > bbox[ 1 ] ) bbox[ 1 ] = *px; - if( *py < bbox[ 2 ] ) bbox[ 2 ] = *py; - if( *py > bbox[ 3 ] ) bbox[ 3 ] = *py; - -/* If the point is within the plotting area, set the "statics->all_bad" flag to - indicate that at least 1 point is within the plotting area. */ - if( !Crv_clip || ( *px >= Crv_xlo && *px <= Crv_xhi && - *py >= Crv_ylo && *py <= Crv_yhi ) ) statics->all_bad = 0; - -/* If the point marking the start of the segment was also good, find and - store the increments and squared length for the segment, incrementing - the pointers ready for the next segment. */ - if( statics->last_ok ){ - statics->t1 = *px - statics->last_x; - statics->t2 = *py - statics->last_y; - statics->t3 = statics->t1*statics->t1 + statics->t2*statics->t2; - *(statics->pdx++) = statics->t1; - *(statics->pdy++) = statics->t2; - *(statics->pdl2++) = statics->t3; - -/* Count the number of segments which are, and are not, shorter than the - minimum significant length. */ - if( statics->t3 > statics->limit2 ) { - statics->nlong++; - } else { - statics->nshort++; - } - -/* If the start was bad, the length of the segment is not defined so store - bad values. */ - } else { - *(statics->pdx++) = AST__BAD; - *(statics->pdy++) = AST__BAD; - *(statics->pdl2++) = AST__BAD; - } - -/* The point at the end of the current segment becomes the point at the - start of the next segment. */ - statics->last_ok = 1; - statics->last_x = *(px++); - statics->last_y = *(py++); - -/* If the tabulated point marking the end of the current segment is bad, - the segment length is undefined so store bad values. */ - } else { - *(statics->pdx++) = AST__BAD; - *(statics->pdy++) = AST__BAD; - *(statics->pdl2++) = AST__BAD; - -/* The point at the end of the current segment becomes the point at the - start of the next segment. */ - statics->last_ok = 0; - px++; - py++; - } - } - -/* ====================================================================== - The next section of this function checks to see lines can be drawn - directly through any of the tabulated points. The flags in "seg_ok" - indicates if this is the case for each segment. - ======================================================================*/ - -/* The unit vector along the previous segment is supplied in external - variables Crv_ux0 and Crv_uy0. These will be AST__BAD if the direction - of the previous segment is undefined. */ - statics->vxl = Crv_ux0; - statics->vyl = Crv_uy0; - -/* The length of the previous segment is initially bad. */ - statics->dll = AST__BAD; - -/* Set up some pointers used to walk through the arrays holding the lengths - of each segment. */ - statics->pdl2 = dl2; - statics->pdx = dx; - statics->pdy = dy; - -/* Check each segment in turn to see if it can be drawn as a single - straight line. */ - for( i = 0; i < CRV_NSEG; i++ ){ - -/* A segment can only be drawn as a single line if both ends are good - and the distance between them is not zero. */ - if( *statics->pdl2 != AST__BAD && *statics->pdl2 > 0.0 ){ - -/* Get a unit vector in the direction of the current segment. */ - statics->dl = sqrt( *statics->pdl2 ); - statics->vx = *statics->pdx/statics->dl; - statics->vy = *statics->pdy/statics->dl; - -/* If a unit vector in the direction of the previous segment is available, - we check that the angle between the previous segment and the current - segment is not too high. */ - if( statics->vxl != AST__BAD ){ - statics->cosang = statics->vxl*statics->vx + statics->vyl*statics->vy; - -/* If the angle is too high, set a flag to indicate that the segment cannot - be drawn as a single line. Also, set the flag for the previous segment as - well. */ - if( statics->cosang < 0.8 || - ( *statics->pdl2 )*( 1.0 - statics->cosang*statics->cosang ) > Crv_limit ) { - seg_ok[ i ] = 0; - if( i > 0 ) seg_ok[ i - 1 ] = 0; - - -/* If the angle between this segment and the previous segment is not too - high, check that the scale has not changed too much. */ - } else { - -/* If the scale (=vector length) has changed a lot, set a flag to indicate - that the segment cannot be drawn as a single line. Also, set the flag for - the previous segment as well. */ - if( statics->dll != AST__BAD && ( statics->dl < statics->dll/Crv_scerr || statics->dl > statics->dll*Crv_scerr ) ) { - seg_ok[ i ] = 0; - if( i > 0 ) seg_ok[ i - 1 ] = 0; - -/* If the orientation and scale of this segment has not changed much from - the previous segment, the segment can be drawn as a straight line. */ - } else { - seg_ok[ i ] = 1; - } - } - -/* If no unit vector is available for the previous segment, then assume - we are re-starting the curve after a discontinuity. In this case, we - can draw it as a straight line. */ - } else { - seg_ok[ i ] = 1; - } - -/* Save the unit vector along the current segment for use next time. */ - statics->vxl = statics->vx; - statics->vyl = statics->vy; - -/* Save the length if the current segment for use next time. */ - statics->dll = statics->dl; - -/* If the length of the current segment is undefined, or zero, we cannot - draw it as a single line. Also, there is no direction vector to pass - on to the next time, so set them bad. */ - } else { - seg_ok[ i ] = 0; - statics->vxl = AST__BAD; - statics->vyl = AST__BAD; - statics->dll = AST__BAD; - } - -/* Point to the next segment. */ - statics->pdl2++; - statics->pdx++; - statics->pdy++; - - } - -/* Do not allow isolated segments to be OK. If a segment is flagged as being - OK, but both its neighbours are not OK, set the segment not OK as well. */ - statics->seg0 = seg_ok + 1; - statics->segm = seg_ok; - statics->segp = seg_ok + 2; - - if( !(*statics->seg0) ) *statics->segm = 0; - - for( i = 1; i < CRV_NSEG - 1; i++ ){ - if( !(*statics->segm) && !(*statics->segp) ) *statics->seg0 = 0; - statics->seg0++; - statics->segm++; - statics->segp++; - } - - if( !(*statics->segm) ) *statics->seg0 = 0; - -/* ====================================================================== - The next section of this function draws the curve. Each segment is drawn - as a straight line if the corresponding flag in "seg_ok" is set. - Segments for which the flag is not set are drawn by calling this function - recursivly. - ======================================================================*/ - -/* Get the parametric length (i.e. the increment in "d") of the sub-segments - within each subdivided segment. */ - statics->delta = ( d[ CRV_NSEG ] - d[ 0 ] )/(double)( CRV_NSEG*CRV_NSEG ); - -/* If we have made the maximum number of recursive entries into this - function, or if every supplied point was bad or outside the plotting - area, or if most of the segments were very short in graphics space, we will - not be attempting to subdivide any segments which cannot be drawn directly - as a straight line. If "skipbad" was supplied as zero, we ignore the - restriction which says that we must have some good points (since we - may find some good poits by a further sub-division). */ - subdivide = ( Crv_nent < CRV_MXENT && - ( !statics->all_bad || !skipbad ) && - statics->nlong > statics->nshort ); - -/* We do not sub-divide if the bounding box of the supplied points - is not at least 10% smaller than the supplied bouding box on either axis. */ - if( box && bbox[ 0 ] != DBL_MAX ) { - if( bbox[ 1 ] - bbox[ 0 ] > 0.9*( box[ 1 ] - box[ 0 ] ) && - bbox[ 3 ] - bbox[ 2 ] > 0.9*( box[ 3 ] - box[ 2 ] ) ) { - subdivide = 0; - } - } - -/* Initialise some pointers to the data defineding the subsegments. */ - dd = NULL; - xx = NULL; - yy = NULL; - -/* If we may be subdividing any segments, find which segments they are - and set up the offset to each sub-segment. */ - if( subdivide ){ - -/* Initialise the number of segments being subdivided. */ - statics->nseg = 0; - -/* Loop round each segment. */ - for( i = 0; i < CRV_NSEG; i++ ){ - -/* If the segment cannot be drawn directly as a straight line, we will - subdivide it. */ - if( !seg_ok[ i ] ){ - -/* Increment the number of segments being subdivided, and let the array - of subsegment offsets grow to accomodate it. */ - statics->nseg++; - dd = (double *) astGrow( dd, statics->nseg, sizeof(double)*( CRV_NSEG + 1 ) ); - if( !astOK ) break; - -/* Append the offset to each new subsegment to the "dd" array. */ - statics->el = ( statics->nseg - 1 )*( CRV_NSEG + 1 ); - statics->d0 = d[ i ]; - for( statics->j = 0; statics->j <= CRV_NSEG; statics->j++ ){ - dd[ statics->el++ ] = statics->d0; - statics->d0 += statics->delta; - } - } - } - -/* If any segments needed subdividing, get room to store the graphics - coordinates at each point, and then fill these arrays by calling - Crv_map to map the offsets in "dd" into graphics coordinates. */ - if( statics->nseg > 0 ){ - statics->nel = statics->nseg*( CRV_NSEG + 1 ); - xx = (double *) astMalloc( sizeof(double)*(size_t)statics->nel ); - yy = (double *) astMalloc( sizeof(double)*(size_t)statics->nel ); - Crv_map( statics->nel, dd, xx, yy, method, class, status GLOBALS_NAME ); - } - } - -/* If all has gone OK, we will draw each segment. Initialise pointers - used to walk through the "xx", "yy" and "dd" arrays. */ - if( astOK ){ - px = xx; - py = yy; - pd = dd; - -/* Draw each segment in turn. */ - for( i = 0; i < CRV_NSEG; i++ ){ - -/* If possible, draw it as a single straight line, and then store the - unit vector along the line in the appropriate external variables for - use by the next invocation of this function. */ - if( seg_ok[ i ] ){ - CrvLine( this, x[ i ], y[ i ], x[ i + 1 ], y[ i + 1 ], method, class, status ); - statics->dl = sqrt( dl2[ i ] ); - Crv_ux0 = dx[ i ]/statics->dl; - Crv_uy0 = dy[ i ]/statics->dl; - -/* Otherwise, if we are subdividing, and if the current segment is - not very short, we call this function recursively to draw the segment. - Increment pointers into the "xx", "yy" and "dd" arrays so that they - point to the start of the subsegment information for the next segment - to be subdivided. If all the graphics positions at this level were - bad or outside the plot, tell the next invocation of Crv to do no - further sub-divisions if it too finds all graphics positions to be bad or - outside the plot. */ - } else if( subdivide ) { - -#ifdef CRV_TRACE - statics->levels[ Crv_nent ] = i; -#endif - - Crv( this, pd, px, py, statics->all_bad, bbox, statics, method, - class, status ); - pd += CRV_NSEG + 1; - px += CRV_NSEG + 1; - py += CRV_NSEG + 1; - -/* Otherwise, we assume we have hit a discontinuity in the curve. Store - bad values for the unit vector along the previous sgment, and do not - draw anything. */ - } else { - Crv_ux0 = AST__BAD; - Crv_uy0 = AST__BAD; - } - } - } - -/* Free any memory used to store subsegment information. */ - if( dd ) dd = (double *) astFree( (void *) dd ); - if( xx ) xx = (double *) astFree( (void *) xx ); - if( yy ) yy = (double *) astFree( (void *) yy ); - -/* Decrement the number of recursive entries into this function. */ - Crv_nent--; - -/* Free the memory holding the static data values if we are leaving the - final entry. */ - if( ! pstatics ) statics = astFree( statics ); - -/* Return. */ - return; -} - -static int CvBrk( AstPlot *this, int ibrk, double *brk, double *vbrk, - double *len, int *status ){ -/* -*+ -* Name: -* astCvBrk - -* Purpose: -* Return information about breaks in the last curve drawn by astGridLine, -* astCurve or astGenCurve. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* int CvBrk( AstPlot *this, int ibrk, double *brk, double *vbrk, -* double *len ) - -* Class Membership: -* Plot method. - -* Description: -* Curves drawn by astGridLine, astCurve or astGenCurve may contain breaks -* for several reasons (for instance, it may go outside the plotting area, -* or the mapping between physical and graphics coordinates may be -* discontinuous). This function returns information about such breaks. - -* Parameters: -* this -* Pointer to a Plot. -* ibrk -* The index of the break for which information is required. The first -* break has index 1. An error is reported if no break with the -* required index exists. The exception to this is that zero can be -* supplied, in which case the "brk" and "vbrk" parameters -* are ignored, but all other information is returned. -* brk -* A pointer to an array of 2 elements -* in which to return the X and Y graphics coordinates of the break. -* vbrk -* A pointer to an array of 2 elements -* in which to return the X and Y components of a unit vector in the -* graphics coordinate system. The vector is tangential to the curve -* at the requested break, and points back along the drawn section of -* the curve. -* len -* A pointer to a "double" in which to return the -* length of the drawn curve, in the graphics coordinate system. - -* Returned Value: -* astCvBrk() -* The number of breaks which occurred in the curve. - -* Notes: -* - Currently, this function may not be used to return information -* about curves drawn using astPolyCurve. -* - All curves contain at least two breaks; one at the start and one -* at the end. This is true even if the start and end of the curve are -* coincident. However, if the entire curve was outside the plotting area -* (i.e. if the length of the drawn curve is zero), then it will have no -* breaks. -* - If no curve has yet been drawn by astGridLine or astCurve, then -1 is -* returned for the function value, and the function parameter values are -* left unchanged. -* - The returned information refers to the most recent curve drawn by -* astGridLine or astCurve, even if that curve was drawn by a Plot other than -* the one supplied to this function. -* - NULL pointers may be supplied for "brk", "vbrk" or "len", in which -* case the corresponding values are not returned. -* - Zero is returned by this function if an error has already occurred, -* or if this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int ret; /* The number of breaks in the curve. */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Information about the most recent curve drawn by astGridLine or astCurve is - stored in the external structure "Curve_data". Get the number of breaks - in the last curve. This is initialised to -1 in astInitPlot when the - virtual function table for this class is initialised. */ - ret = Curve_data.nbrk; - -/* If a curve has been drawn, store the length of the drawn curve if - required. */ - if( ret != -1 ){ - if( len ) *len = (double) Curve_data.length; - -/* If a legal break index has been supplied, return the position and - direction at the requested break (if required). */ - if( ibrk > 0 && ibrk <= ret ){ - if( brk ){ - brk[ 0 ] = (double) Curve_data.xbrk[ ibrk - 1 ]; - brk[ 1 ] = (double) Curve_data.ybrk[ ibrk - 1 ]; - } - if( vbrk ){ - vbrk[ 0 ] = (double) Curve_data.vxbrk[ ibrk - 1 ]; - vbrk[ 1 ] = (double) Curve_data.vybrk[ ibrk - 1 ]; - } - -/* If an illegal break index has been supplied (other than zero), report - an error, and set the number of breaks to zero. */ - } else if( ibrk ){ - if( ret > 0 ){ - astError( AST__BDBRK, "astCvBrk(%s): The supplied break index " - "(%d) should be in the range [1,%d].", status, astGetClass(this), - ibrk, ret ); - ret = 0; - } else { - astError( AST__BDBRK, "astCvBrk(%s): The most recent curve " - "plotted by method astGridLine or astCurve had no breaks.", status, - astGetClass(this) ); - } - } - } - -/* If an error has occurred, return 0. */ - if( !astOK ) ret = 0; - -/* Return the result. */ - return ret; - -} - -static void CrvLine( AstPlot *this, double xa, double ya, double xb, double yb, - const char *method, const char *class, int *status ){ -/* -* Name: -* CrvLine - -* Purpose: -* Draw a straight line between two points, with clipping. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void CrvLine( AstPlot *this, double xa, double ya, double xb, double yb, -* const char *method, const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* This functions draws a straight line from (xa,ya) to (xb,yb), breaking -* the line at the edges of the plotting area defined by Crv_xlo, Crv_xhi, -* Crv_ylo and Crv_yhi if Crv_clip is non-zero. If the line does not start -* at the end of the previous line plotted by this function, then -* information describing the break in the curve is stored in external -* arrays. - -* Parameters: -* xa -* The graphics X coordinate at the start of the line. -* ya -* The graphics Y coordinate at the start of the line. -* xb -* The graphics X coordinate at the end of the line. -* yb -* The graphics Y coordinate at the end of the line. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* External Variables: -* Crv_ink = int (Read) -* If zero then no line is drawn even if the line intersects the -* plotting space, but break information (etc) is still returned. -* Crv_clip = double (Read) -* Clip lines at boundary of plotting space? -* Crv_xlo = double (Read) -* Lower x limit of the plotting space. -* Crv_xhi = double (Read) -* Upper x limit of the plotting space. -* Crv_ylo = double (Read) -* Lower y limit of the plotting space. -* Crv_yhi = double (Read) -* Upper y limit of the plotting space. -* Crv_tol = double (Read) -* The tolerance for determining if 2 points are coincident. -* Crv_out = int (Read/Write) -* Returned as zero if the line intersects the plotting space. -* Unchanged otherwise. -* Crv_xbrk = float * (Read/Write) -* Pointer to the next available element in an array of AST__PLOT_CRV_MXBRK -* values containing the graphics X coordinates at which each break -* in the plotted curve occurred. A break is recorded if the starting -* point of the current line is not the same as the end point of -* the previous line. -* Crv_ybrk = float * (Read/Write) -* Pointer to the next available element in an array of AST__PLOT_CRV_MXBRK -* values containing the graphics Y coordinates at which each break -* in the plotted curve occurred. -* Crv_vxbrk = float * (Read/Write) -* Pointer to the next available element in an array of AST__PLOT_CRV_MXBRK -* values containing the X component of the unit vector (within the -* graphics coordinate system) parallel to the tangent to the curve -* at each break. The sense is such that the vector always points back -* along the plotted section of the curve. -* Crv_vybrk = float * (Read/Write) -* Pointer to the next available element in an array of AST__PLOT_CRV_MXBRK -* values containing the Y component of the unit vector parallel to -* the tangent to the curve at each break. -* Crv_nbrk = int (Write) -* The number of breaks for which information is returned in Crv_xbrk, -* etc. -* Crv_len = float (Write) -* The length of the section of the curve which has been drawn so far. -* Crv_xl = double (Write) -* The graphics X coordinate at the end of the last line drawn. -* Crv_yl = double (Write) -* The graphics Y coordinate at the end of the last line drawn. -* Crv_vxl = double (Write) -* The X component of the unit vector along the last line drawn. -* Crv_vyl = double (Write) -* The Y component of the unit vector along the last line drawn. -* Grf_alpha = float (Read) -* The factor for scaling graphics X axis values into equal scaled -* X axis values. -* Grf_beta = float (Read) -* The factor for scaling graphics Y axis values into equal scaled -* Y axis values. - -*/ - -/* local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double a1; /* Distance from B to the lower x boundary */ - double a2; /* Distance from B to the upper x boundary */ - double a3; /* Distance from B to the lower y boundary */ - double a4; /* Distance from B to the upper y boundary */ - double aamax; /* Distance from supplied point B to the plotable point A */ - double aamin; /* Distance from supplied point B to the plotable point B */ - double dl; /* Length of plotted line segment */ - double dx; /* Difference in x between supplied points */ - double dy; /* Difference in y between supplied points */ - double t; /* Temporary storage */ - double xam; /* Modified xa position */ - double xbm; /* Modified xb position */ - double yam; /* Modified ya position */ - double ybm; /* Modified yb position */ - int plot; /* True if a line can be plotted */ - -/* Check inherited global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - dl = 0.0; - xam = 0.0; - xbm = 0.0; - yam = 0.0; - ybm = 0.0; - -/* Store the shifts in x and y. */ - dx = xb - xa; - dy = yb - ya; - -/* Do nothing if the line is of zero length. */ - if( dx == 0.0 && dy == 0.0 ) return; - -/* If either end is outside the zone, replace the given coordinates with - the end coordinates of the section of the line which lies within the - zone. */ - if( Crv_clip && ( xa < Crv_xlo || xa > Crv_xhi || - xb < Crv_xlo || xb > Crv_xhi || - ya < Crv_ylo || ya > Crv_yhi || - yb < Crv_ylo || yb > Crv_yhi ) ){ - -/* Find the distance from point B towards point A at which the - line cuts the two x bounds of the zone (distance at point B is - 0.0, and at point A is 1.0). */ - if( dx != 0.0 ){ - a1 = ( xb - Crv_xlo )/dx; - a2 = ( xb - Crv_xhi )/dx; - -/* Ensure that a1 represents the highest plottable offset, and a2 the - lowest. */ - if( a1 < a2 ){ - t = a1; - a1 = a2; - a2 = t; - } - -/* If the line joining A and B is vertical... */ - } else { - -/* If the line is within the plottable x range, indicate that all - offsets are plottable (as far as the x range is concerned at least). */ - if( ( xa > Crv_xlo || astEQUALS( xa, Crv_xlo, 1.0E8 ) ) && - ( xa < Crv_xhi || astEQUALS( xa, Crv_xhi, 1.0E8 ) ) ){ - a1 = DBL_MAX; - a2 = -DBL_MAX; - -/* If the line is ouside the plottable x range, indicate that no - offsets are plottable. */ - } else { - a1 = 0.0; - a2 = 0.0; - } - } - -/* Find the fractional distance from point A to point B at which the - line cuts the two y bounds of the zone. */ - if( dy != 0.0 ){ - a3 = ( yb - Crv_ylo )/dy; - a4 = ( yb - Crv_yhi )/dy; - -/* Ensure that a3 represents the highest plottable offset, and a4 the - lowest. */ - if( a3 < a4 ){ - t = a3; - a3 = a4; - a4 = t; - } - -/* If the line joining A and B is horizontal... */ - } else { - -/* If the line is within the plottable y range, indicate that all - offsets are plottable (as far as the y range is concerned at least). */ - if( ( ya > Crv_ylo || astEQUALS( ya, Crv_ylo, 1.0E8 ) ) && - ( ya < Crv_yhi || astEQUALS( ya, Crv_yhi, 1.0E8 ) ) ){ - a3 = DBL_MAX; - a4 = -DBL_MAX; - -/* If the line is ouside the plottable y range, indicate that no - offsets are plottable. */ - } else { - a3 = 0.0; - a4 = 0.0; - } - } - -/* Find the fractional distances from point A to point B at the ends - of the plotable line. */ - aamin = astMIN( 1.0, astMAX( 0.0, astMAX( a2, a4 ) ) ); - aamax = astMAX( 0.0, astMIN( 1.0, astMIN( a1, a3 ) ) ); - -/* Store the end coordinates of the line joining the plotable points. */ - if( aamax > aamin ){ - xam = xb - aamax*dx; - yam = yb - aamax*dy; - xbm = xb - aamin*dx; - ybm = yb - aamin*dy; - plot = 1; - -/* Get the unit vector along the line and the length of the plotted section. */ - dx *= Grf_alpha; - dy *= Grf_beta; - dl = sqrt( dx*dx + dy*dy ); - dx /= dl; - dy /= dl; - dl *= astMAX( 0.0, aamax - aamin ); - -/* Clear the "plot" flag if the line does not intersect the plotting area. */ - } else { - plot = 0; - } - -/* If both ends of the line are within the plotting zone, draw the whole - line between the supplied end points. */ - } else { - xam = xa; - yam = ya; - xbm = xb; - ybm = yb; - plot = 1; - -/* Get the length of the line and the unit vector along the line. */ - dx *= Grf_alpha; - dy *= Grf_beta; - dl = sqrt( dx*dx + dy*dy ); - dx /= dl; - dy /= dl; - } - -/* If a line is to be plotted... */ - if( plot ){ - -/* If this is the first line to be plotted in the current curve, save - the start of the line as a break, and indicate that some of the curve - falls within the plotting zone. */ - if( Crv_out ){ - Crv_nbrk = 1; - *(Crv_xbrk++) = (float) xam; - *(Crv_ybrk++) = (float) yam; - *(Crv_vxbrk++) = (float) dx; - *(Crv_vybrk++) = (float) dy; - Crv_out = 0; - -/* Set the length of the curve plotted so far to the length of this first - segment. */ - Crv_len = (float) dl; - -/* Start a poly line. */ - if( Crv_ink ) Bpoly( this, (float) xam, (float) yam, status ); - -/* If this is not the first line to be plotted... */ - } else { - -/* ... increment the length of the curve plotted so far. */ - Crv_len += (float) dl; - -/* If the start of this line is not coincident with the end - of the previous line, save the previous and current positions as - breaks in the curve. Note, the previous vector is reversed so that - it points back towards the drawn section of the curve. Report an - error if the arrays are full. */ - if( fabs( xam - Crv_xl ) > Crv_tol || - fabs( yam - Crv_yl ) > Crv_tol ){ - Crv_nbrk += 2; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in plotted " - "curve exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - *(Crv_xbrk++) = (float) xam; - *(Crv_ybrk++) = (float) yam; - *(Crv_vxbrk++) = (float) dx; - *(Crv_vybrk++) = (float) dy; - } - -/* Start a poly line. */ - if( Crv_ink ) Bpoly( this, (float) xam, (float) yam, status ); - } - } - -/* Append a section to the current poly line. */ - if( Crv_ink ) Apoly( this, (float) xbm, (float) ybm, status ); - -/* Save the position and vector at the end of the current line. */ - Crv_xl = xbm; - Crv_yl = ybm; - Crv_vxl = dx; - Crv_vyl = dy; - } - -/* Return. */ - return; -} - - -static void Curve( AstPlot *this, const double start[], - const double finish[], int *status ){ -/* -*++ -* Name: -c astCurve -f AST_CURVE - -* Purpose: -* Draw a geodesic curve. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astCurve( AstPlot *this, const double start[], -c const double finish[] ) -f CALL AST_CURVE( THIS, START, FINISH, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a geodesic curve between two points in the -f This routine draws a geodesic curve between two points in the -* physical coordinate system of a Plot. The curve drawn is the -* path of shortest distance joining the two points (as defined by -c the astDistance function for the current Frame of the Plot). -f the AST_DISTANCE function for the current Frame of the Plot). -* For example, if the current Frame is a basic Frame, then the -* curve joining the two points will be a straight line in physical -* coordinate space. If the current Frame is more specialised and -* describes, for instance, a sky coordinate system, then the -* geodesic curve would be a great circle in physical coordinate -* space passing through the two sky positions given. -* -* Note that the geodesic curve is transformed into graphical -* coordinate space for plotting, so that a straight line in -* physical coordinates may result in a curved line being drawn if -* the Mapping involved is non-linear. Any discontinuities in the -* Mapping between physical and graphical coordinates are -c catered for, as is any clipping established using astClip. -f catered for, as is any clipping established using AST_CLIP. -* -c If you need to draw many geodesic curves end-to-end, then the -c astPolyCurve function is equivalent to repeatedly using -c astCurve, but will usually be more efficient. -f If you need to draw many geodesic curves end-to-end, then the -f AST_POLYCURVE routine is equivalent to repeatedly calling -f AST_CURVE, but will usually be more efficient. -* -c If you need to draw curves which are not geodesics, see astGenCurve -c or astGridLine. -f If you need to draw curves which are not geodesics, see AST_GENCURVE -f or AST_GRIDLINE. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c start -f START( * ) = DOUBLE PRECISION (Given) -* An array, with one element for each axis of the Plot, giving -* the physical coordinates of the first point on the geodesic -* curve. -c finish -f FINISH( * ) = DOUBLE PRECISION (Given) -* An array, with one element for each axis of the Plot, giving -* the physical coordinates of the second point on the geodesic -* curve. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - No curve is drawn if either of the "start" or "finish" arrays -c contains any coordinates with the value AST__BAD. -f - No curve is drawn if either of the START or FINISH arrays -f contains any coordinates with the value AST__BAD. -* - An error results if the base Frame of the Plot is not 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astCurve"; - class = astGetClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Initialise the bounding box for primitives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Draw the curve. The break information is stored in an external structure - where it can be accessed by public methods which return information - about the most recently drawn curve. */ - CurvePlot( this, start, finish, 1, &Curve_data, method, class, status ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Return. */ - return; -} - -static void CurvePlot( AstPlot *this, const double *start, const double *finish, - int ink, AstPlotCurveData *cdata, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* CurvePlot - -* Purpose: -* Draw a geodesic curve. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void CurvePlot( AstPlot *this, const double *start, const double *finish, -* int ink, AstPlotCurveData *cdata, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a geodesic curve between the supplied starting and -* finishing positions. The algorithm used can handle discontinuities in the -* Mapping between the current Frame and graphics coordinates, and -* information describing any breaks in the curve (including the start and -* end of the curve) are returned in the supplied AstPlotCurveData structure. - -* Parameters: -* this -* Pointer to the Plot. -* start -* A pointer to a an array holding the coordinates of the start of the -* curve within the current Frame of the Plot. -* finish -* A pointer to a an array holding the coordinates of the finish of the -* curve within the current Frame of the Plot. -* ink -* If zero, the curve is not actually drawn, but information about -* the breaks is still returned. If non-zero, the curve is also drawn. -* cdata -* A pointer to a structure in which to return information about the -* breaks in the curve. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - No curve is draw if the "start" or "finish" arrays contains any bad -* values, or if a NULL pointer is supplied for "cdata". No errors are -* reported in these cases. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - int i; /* Loop count */ - int naxes; /* No. of axes in the base Frame */ - int ok; /* Are all start coords good? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Get the number of axes in the current Frame. */ - naxes = astGetNout( this ); - -/* Check the "start" and "finish" parameter for bad values. */ - ok = 1; - for( i = 0; i < naxes; i++ ) { - if( start[ i ] == AST__BAD || finish[ i ] == AST__BAD ){ - ok = 0; - break; - } - } - -/* Check that the "cdata" pointer can be used. */ - if( !cdata ) ok = 0; - -/* Only proceed if the parameters are OK, and there has been no error. */ - if( ok && astOK ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__CURVE_ID, 1, GRF__LINE, method, class ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Set up the externals used to communicate with the Map3 function... - The number of axes in the physical coordinate system (i.e. the current - Frame). */ - Map3_ncoord = naxes; - -/* A pointer to the Plot, the Curretn Frame, and and Mapping. */ - Map3_plot = this; - Map3_frame = astGetFrame( this, AST__CURRENT ); - Map3_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* The physical coordinates at the start of the curve. */ - Map3_origin = start; - -/* The physical coordinates at the end of the curve. */ - Map3_end = finish; - -/* The scale factor to convert "dist" values into physical offset values. */ - Map3_scale = astDistance( Map3_frame, start, finish ); - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map3; - Crv_ink = ink; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = cdata->xbrk; - Crv_ybrk = cdata->ybrk; - Crv_vxbrk = cdata->vxbrk; - Crv_vybrk = cdata->vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Set up a list of points spread evenly over the curve. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Map these points into graphics coordinates. */ - Map3( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map3 to draw the curve. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map3. */ - Map3( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - if( cdata ){ - cdata->length = Crv_len; - cdata->out = Crv_out; - cdata->nbrk = Crv_nbrk; - PurgeCdata( cdata, status ); - } - -/* Annul the Frame and Mapping. */ - Map3_frame = astAnnul( Map3_frame ); - Map3_map = astAnnul( Map3_map ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__CURVE_ID, 0, GRF__LINE, method, class ); - - } - -/* Return. */ - return; - -} - - -static AstPointSet *DefGap( AstPlot *this, double *gaps, int *ngood, - double *frac, int *inval, const char *method, - const char *class, int *status ){ -/* -* Name: -* DefGap - -* Purpose: -* Find default gap sizes for the tick marks on the axes of a 2-D -* physical coordinate system. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPointSet *DefGap( AstPlot *this, double *gaps, int *ngood, -* double *frac, int *inval, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns default gap sizes for each axis in a 2-D Frame. -* The values are found by first obtaining a grid of points spread over -* the region containing good physical coordinates. The physical -* coordinate values (non-normalized) for each axis are sorted into -* increasing order. -* -* For linearly spaced tick marks, a set of quantile axis values is then -* found, and the median of the gaps between these quantiles is returned -* as the default gap for the axis. -* -* For logarithmically spaced tick marks, the returned gap size is the -* ratio between adjacent tick mark values, chosen to give an optimal -* number of ticks between the maximum and minimum axis values found in -* the grid. - -* Parameters: -* this -* Pointer to a Plot. -* gaps -* Pointer to an array in which to return the default gap value for -* each axis. -* ngood -* Pointer to an array in which toi return the number of good -* values in the returned PointSet for each axis. -* frac -* Pointer to a double in which to return the fraction of the -* plotting area containing good physical coordinates. -* inval -* Pointer to a location at which to return a flag indicating if -* any bad physical coordinates were encountered. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a PointSet holding the physical coordinate values at a -* set of points spread across the plotting area. The values on each -* axis are sorted into increasing order. The values will not have -* been normalized. - -* Notes: -* - The returned PointSet should be annulled when no longer needed. -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - Gap sizes of 1.0, zero good points, and a NULL pointer are returned -* if an error has already occurred, or if this function should fail for -* any reason. - -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* Pointer to PointSet holding graphics coords */ - AstPointSet *pset2; /* Pointer to PointSet holding physical coords */ - double **ptr1; /* Pointer to graphics axis values */ - double **ptr2; /* Pointer to physical axis values */ - double dran; /* Dynamic range */ - double maxv; /* Maximum axis value */ - double minv; /* Minimum axis value */ - double qgap[ MAJTICKS_OPT ];/* Gaps between physical coordinate quantiles */ - int dim; /* Dimension of grid */ - int dk; /* The number of points between quantiles */ - int i; /* The quantile index */ - int j; /* Axis index */ - int k; /* Index into the sorted array of axis values */ - int logticks; /* Logarithmically spaced tick marks? */ - int n; /* Target number fo ticks */ - int psize; /* Total number of axis value */ - -/* Initialise the returned values. */ - gaps[ 0 ] = 1.0; - gaps[ 1 ] = 1.0; - ngood[ 0 ] = 0; - ngood[ 1 ] = 0; - *frac = 0.0; - *inval = 0; - -/* Check global status. */ - if( !astOK ) return NULL; - -/* Get two PointSets, one holding a grid of 2D graphics coordinates, - and one holding the corresponding (non-normalized) physical - coordinates. */ - dim = 0; - *frac = GoodGrid( this, &dim, &pset1, &pset2, method, class, status ); - -/* Get pointers to the data values in each PointSet. */ - ptr1 = astGetPoints( pset1 ); - ptr2 = astGetPoints( pset2 ); - -/* Store the number of elements in each PointSet. */ - psize = astGetNpoint( pset1 ); - -/* For each axis... */ - for( j = 0; j < 2 && astOK; j++ ){ - -/* Sort the axis values into increasing order. Any bad values are stored at - the end of the array on return. */ - qsort( (void *) ptr2[ j ], (size_t) psize, sizeof(double), Compared ); - -/* Count the number of non-bad values returned. */ - ngood[ j ] = CountGood( psize, ptr2[ j ], status ); - -/* Set the returned flag to indicate if any bad values were found. */ - if( ngood[ j ] < psize ) *inval = 1; - -/* Report an error if there are too few good points. */ - if( ngood[ j ] < MAJTICKS_OPT ){ - astError( AST__VSMAL, "%s(%s): The range of coordinate values " - "covered by axis %d is too small to plot.", status, method, - class, j + 1 ); - break; - } - -/* Get the maximum and minimum axis value */ - minv = ptr2[ j ][ 0 ]; - maxv = ptr2[ j ][ ngood[ j ] - 1 ]; - -/* See if ticks on this axis are spaced linearly or logarithmically. If a - value has been set for LogTicks used it, otherwise find a default value. - The default is 0 unless LogPlot is non-zero, the axis range does not - encompass zero and and the dynamic range is 90 or more. Set this - default value explicitly so that later functions will pick it up (it will - be cleared at the end of the astGrid function). */ - if( astTestLogTicks( this, j ) ) { - logticks = astGetLogTicks( this, j ); - } else { - logticks = 0; - if( astGetLogPlot( this, j ) && minv*maxv > 0.0 ) { - dran = maxv/minv; - if( dran >= 90.0 || dran <= 1.0/90.0 ) logticks = 1; - } - astSetLogTicks( this, j, logticks ); - } - -/* If no value has been supplied for LogLabel use the value of LogTicks - as the default. */ - if( !astTestLogLabel( this, j ) ) astSetLogLabel( this, j, logticks ); - -/* For linear gaps, find the gaps between adjacent evenly spaced quantiles. - The number of quantiles used equals the optimal number of major tick - marks. */ - if( !logticks ) { - dk = (int)( (double)ngood[ j ]/MAJTICKS_OPT ); - i = 0; - for( k = dk; k < ngood[ j ] && i < MAJTICKS_OPT; k += dk ){ - qgap[ i++ ] = ptr2[ j ][ k ] - ptr2[ j ][ k - dk ]; - } - -/* Find the median of the gaps between adjacent quantiles. */ - qsort( (void *) qgap, (size_t) i, sizeof(double), Compared ); - gaps[ j ] = qgap[ i/2 ]; - -/* If the test gap size is zero, use a fraction of the total range. Report - an error if the total range is zero. */ - if( gaps[ j ] <= 0.0 ){ - gaps[ j ] = ( ptr2[ j ][ ngood[ j ] - 1 ] - ptr2[ j ][ 0 ] )/MAJTICKS_OPT;; - if( gaps[ j ] <= 0.0 ){ - astError( AST__VSMAL, "%s(%s): The range of coordinate values " - "covered by axis %d is too small to plot.", status, method, - class, j + 1 ); - } - } - -/* For logarithmic gaps, use the Nth root of the ratio of the maximum and - minimum data value found. */ - } else if( astOK ) { - -/* Report an error if the max and min values are of opposite signs or - zero or equal. */ - if( maxv*minv <= 0.0 ) { - astError( AST__ZERAX, "%s(%s): The range of coordinate values " - "covered by axis %d includes the origin and so " - "logarithmic ticks cannot be produced.", status, method, - class, j + 1 ); - - } else if( maxv == minv ) { - astError( AST__VSMAL, "%s(%s): The range of coordinate values " - "covered by axis %d is too small to plot.", status, method, - class, j + 1 ); - -/* Otherwise find the gap to use. */ - } else { - -/* Store the maximum and minimum number of major tick marks along each - axis. These numbers are reduced if only a small part of the plotting - area contains valid coordinates, so that the tick marks do not end up - to close together. */ - n = (int) ( 0.5 + MAJTICKS_OPT*sqrt( *frac ) ); - if( n < 5 ) n = 5; - -/* Choose a gap size which makes this many gaps. */ - gaps[ j ] = pow( maxv/minv, 1.0/( n - 1.0 ) ); - } - } - } - -/* Annul the PointSet holding Graphics coordinates. */ - pset1 = astAnnul( pset1 ); - -/* If an error has occurred, annul the PointSet holding physical - coordinates, and return gaps of 1.0. */ - if( !astOK ) { - pset2 = astAnnul( pset2 ); - gaps[ 0 ] = 1.0; - gaps[ 1 ] = 1.0; - ngood[ 0 ] = 0; - ngood[ 1 ] = 0; - *frac = 0.0; - *inval = 0; - } - -/* Return the physical PointSet. */ - return pset2; - -} - -static void DrawAxis( AstPlot *this, TickInfo **grid, double *labelat, - double *gap, const char *method, const char *class, int *status ){ -/* -* -* Name: -* DrawAxis - -* Purpose: -* Draw a curve joining the major tick marks. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void DrawAxis( AstPlot *this, TickInfo **grid, double *labelat, -* double *gap, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a curve through interior tick marks on both axes. -* The curve is drawn even if it has already been drawn as part of a -* grid of curves, because it may have been assigned different graphics -* attributes to the grid curves. - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick marks on the axis. See function GridLines. -* labelat -* A pointer to a 2 element array giving the constant axis values at -* which tick marks are put. Element 0 should give the axis 1 value at -* which tick marks for axis 0 are placed. Element 1 should give the -* axis 0 value at which tick marks for axis 1 are placed. -* gap -* Pointer to array of two values holding the gap between major -* tick marks on the two axes. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function assumes the current Frame of the Plot is 2 -* dimensional, and it should not be called if this is not the case. - -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to current Frame */ - AstPlotCurveData cdata;/* Somewhere to put the unneeded curve information */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - double *value; /* Current tick value */ - double bot; /* Lowest axis value to be displayed */ - double diff; /* Difference between adjacent tick marks */ - double udiff; /* Used section length */ - double start[ 2 ]; /* The start of the curve in physical coordinates */ - double tmp; /* Temporary storage */ - double top; /* Highest axis value to be displayed */ - int axis; /* Current axis index */ - int axisid; /* ID value for current axis plotting attributes */ - int logticks; /* Are major ticks spaced logarithmically? */ - int tick; /* Current tick index */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Not the id value for the first axis. */ - axisid = AST__AXIS1_ID; - -/* Get a pointer to the current Frame. */ - frm = astGetFrame( this, AST__CURRENT ); - -/* Consider drawing a curve parallel to each axis in turn. */ - for( axis = 0; axis < 2; axis++ ){ - -/* Establish the correct graphical attributes for this axis as defined by - attributes with the supplied Plot. */ - astGrfAttrs( this, axisid, 1, GRF__LINE, method, class ); - -/* Check the axis is required. */ - if( astGetDrawAxes( this, axis ) ){ - -/* If the tick marks have been placed round the edges of the plotting - area, we do not need to draw the curves. */ - if( labelat[ axis ] != AST__BAD ){ - -/* Get the max and min values allowed on this axis. */ - bot = astGetBottom( frm, axis ); - top = astGetTop( frm, axis ); - if( bot > top ) { - tmp = top; - top = bot; - bot = tmp; - } - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along the current axis. */ - info = grid[ axis ]; - -/* Get a pointer to the axis value at the first major tick mark. */ - value = info->ticks; - -/* See if the major tick marks are logarithmically spaced on this axis. */ - logticks = astGetLogTicks( this, axis ); - -/* Initialise the difference between major tick marks. */ - diff = logticks ? 0.0 : gap[ axis ]; - -/* Loop round all ticks. */ - for( tick = 0; tick < info->nmajor; tick++, value++ ){ - -/* Update the difference between major tick marks if we are producing - logarithmically spaced ticks (in which "gap" is a ratio, not a - difference). */ - if( logticks ) diff = (*value)*( gap[ axis ] - 1.0 ); - -/* Note the starting point for this section. */ - start[ axis ] = *value; - start[ 1 - axis ] = labelat[ axis ]; - -/* If this is the first tick, draw an axis section going "backwards" in - case the first tick isn't at the lower visible bound. Limit the length - of this backwards section so that it does not extend beyond the minimum - axis value. */ - if( tick == 0 ) { - udiff = *value - bot; - if( udiff > diff ) udiff = diff; - if( udiff > 0.0 ) { - AxPlot( this, axis, start, -udiff, 1, &cdata, method, - class, status ); - } - } - -/* Limit the length of the section so that it does not extend beyond the - maximum axis value. */ - udiff = ( *value + diff > top ) ? top - *value : diff; - -/* Do not draw zero length sections. */ - if( udiff > 0.0 ) { - -/* Draw a curve parallel to the current axis, starting at the tick mark, - with length equal to the gap between tick marks. Do not draw sections - of the curve which are outside the primary domains of the physical axes. */ - AxPlot( this, axis, start, udiff, 1, &cdata, method, - class, status ); - } - - } - -/* Once the last section has been drawn, draw another axis section in case the - last tick isn't at the upper visible bound. Limit the length of this - section so that it does not extend beyond the maximum axis value. */ - udiff = top - start[ axis ]; - if( udiff > diff ) udiff = diff; - if( udiff > 0.0 ) { - AxPlot( this, axis, start, udiff, 1, &cdata, method, - class, status ); - } - } - } - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, axisid, 0, GRF__LINE, method, class ); - -/* Set up the id value for the next axis. */ - axisid = AST__AXIS2_ID; - - } - -/* Free the pointer to the current Frame. */ - frm = astAnnul( frm ); - -} - - -static AstPlotCurveData **DrawGrid( AstPlot *this, TickInfo **grid, int drawgrid, - const char *method, const char *class, int *status ){ -/* -* Name: -* DrawGrid - -* Purpose: -* Draw a grid of lines at the major tick mark positions on both axes. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPlotCurveData **DrawGrid( AstPlot *this, TickInfo **grid, int drawgrid, -* const char *method, const char *class ) - -* Class Membership: -* Plot method. - -* Description: -* This function draw a grid of curves at the major tick mark -* positions on both axes, and returns information describing the -* breaks in the curves. If short tick marks are required rather -* than long curves (as specified by the Grid attribute of the supplied -* Plot), then the curves are not drawn but the break information is -* still returned. - -* Parameters: -* this -* Pointer to a Plot. -* grid -* A pointer to an array of two pointers (one for each axis), each -* pointing to a TickInfo structure. These describe the positions -* of the tick marks and should have been produced by function -* GridLines. -* drawgrid -* If non-zero, draw a grid of curves marking the major axis -* values. Otherwise, tick marks will be drawn at these values later. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* Returned Value: -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structures (one for each tick -* value). - -* Notes: -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned. - -*/ - -/* Local Variables: */ - AstPlotCurveData **cdata;/* The returned pointer */ - AstPlotCurveData *cdt; /* Pointer to break info. for current tick mark */ - AstPlotCurveData tcdt; /* Pointer to break info. for current curve section */ - TickInfo *info; /* Tick mark information for a single axis */ - double start[ 2 ]; /* Strting position for current curve section */ - double total_length; /* Total curve length for all axis ticks */ - int i; /* Axis index */ - int j; /* Tick mark index */ - int k; /* Curve section index */ - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Allocate memory to hold two pointers, each pointing to an array of - AstPlotCurveData structure. */ - cdata = (AstPlotCurveData **) astMalloc( 2*sizeof( AstPlotCurveData *) ); - -/* If succesful, initialise the pointers. */ - if( astOK ){ - cdata[ 0 ] = NULL; - cdata[ 1 ] = NULL; - -/* Draw the curves marking the major tick values on each axis. If no grid is - required, we still do this in order to get information about the breaks - in the curves which will be used later to decide where to put the labels, - but we use "invisible ink". */ - for( i = 0; i < 2; i++ ){ - -/* Get a pointer to the TickInfo structure for this axis holding information - about where to put tick marks on this axis. */ - info = grid[ i ]; - -/* Allocate memory to hold information describing the breaks in each tick - mark curve. This takes the form of an array of AstPlotCurveData structures, - one for each tick mark. */ - cdata[ i ] = (AstPlotCurveData *) astMalloc( sizeof(AstPlotCurveData)* - (size_t) info->nmajor ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Initialise a pointer to the first AstPlotCurveData structure for this axis. */ - cdt = cdata[ i ]; - total_length = 0.0; - -/* Do each tick mark. */ - for( j = 0; j < info->nmajor; j++ ){ - -/* Store the starting point of the first section of the curve. */ - start[ i ] = (info->ticks)[ j ]; - start[ 1 - i ] = (info->start)[ 0 ]; - -/* Draw the first section of the curve parallel to the other axis, starting - at the values in "start", and extending for a length given in the TickInfo - structure. We use invisible ink if short tick marks are required instead - of a grid of curves. */ - AxPlot( this, 1 - i, start, (info->length)[ 0 ], - drawgrid, cdt, method, class, status ); - -/* Now draw any other sections in the curve. */ - for( k = 1; k < info->nsect; k++ ){ - -/* Modify the starting value on the other axis. The starting value on - the current axis remains set to the tick mark value. */ - start[ 1 - i ] = (info->start)[ k ]; - -/* Draw the curve, the information describing the breaks goes into - temporary storage in the local structure "tcdt". */ - AxPlot( this, 1 - i, start, (info->length)[ k ], - drawgrid, &tcdt, method, class, status ); - -/* Concatenate the break information for this section with the break - information describing the previous sections. */ - AddCdt( cdt, &tcdt, method, class, status ); - - } - -/* Increment the total length of curves drawn for all ticks on this axis. */ - total_length += cdt->length; - -/* Point to the AstPlotCurveData structure for the next tick mark. */ - cdt++; - - } - -/* Report an error if the total length of all curves on this axis is zero. - This can be caused for instance by bugs in the algorithm for finding - major tick values (which may cause AST__BAD tick mark values). */ - if( total_length == 0.0 && astOK ) { - astError( AST__INTER, "%s(%s): No grid curves can be drawn for " - "axis %d.", status, method, class, i + 1 ); - } - - } - - } - - } - -/* If an error has occurred, clean up the returned structures. */ - if( !astOK ) cdata = CleanCdata( cdata, status ); - -/* Return. */ - return cdata; - -} - -static int DrawRegion( AstPlot *this, AstFrame *frm, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* DrawRegion - -* Purpose: -* Draw the outline of a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int DrawRegion( AstPlot *this, AstFrame *frm, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* If the current Frame in the supplied Plot is a Region, this function -* draws a curve marking the outline of the Region. It returns without -* action otherwise. - -* Parameters: -* this -* Pointer to the Plot. -* frm -* Pointer to the current Frame in the Plot (possibly a Region). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if and only if a Region outline was drawn. - -*/ - -/* Local Variables: */ - AstMapping *map; /* Mapping with Region masking included */ - AstPlotCurveData cdata; /* Stores information about curve breaks */ - AstRegion **comps; /* List of component Regions */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - int i; /* Loop count */ - int icomp; /* Index of component Region */ - int ncomp; /* Number of component Regions */ - int result; /* The returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Check the current Frame is a Region, and is of a class that implements - the astRegTrace method. */ - if( astIsARegion( frm ) && - astRegTrace( (AstRegion *) frm, 0, NULL, NULL ) ){ - -/* Set up the externals used to communicate with the Map5 function... - The number of axes in the physical coordinate system (i.e. the - Region). */ - Map5_ncoord = astGetNaxes( frm ); - -/* A pointer to the Plot, the Region, and the Mapping. */ - Map5_plot = this; - Map5_region = (AstRegion *) frm; - -/* Also store a pointer to the Mapping, ensuring that the Mapping does - not contain any masking effects from the Region. */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - Map5_map = astRemoveRegions( map ); - map = astAnnul( map ); - -/* Convert the tolerance from relative to absolute graphics coordinates. - Make the tolerance smaller by a factor of 10 because Regions - (specifically Polygonsd) can have very crinkly edges. */ - tol = 0.1* astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map5; - Crv_ink = 1; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = cdata.xbrk; - Crv_ybrk = cdata.ybrk; - Crv_vxbrk = cdata.vxbrk; - Crv_vybrk = cdata.vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Attempt to split the Region into a set of disjoint component Regions. */ - comps = astRegSplit( (AstRegion *) frm, &ncomp ); - -/* Draw each one. */ - for( icomp = 0; icomp < ncomp; icomp++ ) { - -/* A pointer to the Region. */ - Map5_region = comps[ icomp ]; - -/* Set up a list of points spread evenly over the curve. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Map these points into graphics coordinates. */ - Map5( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map5 to draw the curve. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map5. */ - Map5( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* Annul the component Region pointer. */ - comps[ icomp ] = astAnnul( Map5_region ); - } - -/* Free the memory holding the list of component Region pointers. */ - comps = astFree( comps ); - -/* Annul the Mapping. */ - Map5_map = astAnnul( Map5_map ); - -/* Indicate the outline was drawn. */ - result = 1; - } - -/* Return. */ - return result; -} - -static void DrawText( AstPlot *this, int ink, int esc, const char *text, - float x, float y, const char *just, float upx, - float upy, float *xbn, float *ybn, float *drop, - const char *method, const char *class, int *status ){ -/* -* Name: -* DrawText - -* Purpose: -* Draw a character string, potentially including superscripts and -* subscripts. - -* Synopsis: -* #include "plot.h" -* void DrawText( AstPlot *this, int ink, int esc, const char *text, -* float x, float y, const char *just, float upx, -* float upy, float *xbn, float *ybn, float *drop, -* const char *method, const char *class, int *status ) - -* Description: -* This function displays a character string at a given position -* using a specified up-vector, optionally interpreting any Plot escape -* sequences contained within the text. It also returns its bounding -* box. - -* Parameters: -* this -* The plot. -* ink -* If zero, nothing is drawn but the bounding box is still returned. -* esc -* Should escape sequences be interpreted? They will be printed -* literally otherwise. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The graphics X coordinate of the label's reference point. -* y -* The graphics Y coordinate of the label's reference point. -* just -* Pointer to a null-terminated character string identifying the -* reference point for the text being drawn. The first character in -* this string identifies the reference position in the "up" direction -* and may be "M", "B", "C" or "T" (for bottom, baseline, centre or -* top). The second character identifies the side-to-side reference -* position and may be "L", "C" or "R" (for left, centre or right). The -* string is case-insensitive, and only the first two characters are -* significant. -* upx -* The x component of the up-vector for the text. Positive values -* always refer to displacements from left to right on the screen, -* even if the graphics x axis increases in the opposite sense. -* upy -* The y component of the up-vector for the text. Positive values -* always refer to displacements from left to right on the screen, -* even if the graphics y axis increases in the opposite sense. -* xbn -* An array in which is returned the x coordinates at the corners -* of the bounding box. The order is: bottom left, top left, top -* right, bottom right. -* ybn -* An array in which is returned the Y coordinates at the corners -* of the bounding box (see xbn). -* drop -* Address of a float in which to return the distance between the -* bottom of the bounding box and the baseline of normal text. May -* be NULL. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The "B" option for the justification in the "up" direction refers -* to the base-line on which the text is written. Some characters -* ("y", "p", "g", etc) descend below this line. In addition, if the -* supplied text string includes any escape sequences which produce -* sub-scripts, then these will also descend below the base-line. To -* justify the bottom of the entire string (instead of just the -* base-line), specify "M" instead of "B" in the justification string. -* - See function astFindEscape for details of the supported escape -* sequences. -*/ - - -/* Local Variables: */ - astDECLARE_GLOBALS - char *a; - char *lt; - char cc; - const char *lj; - double ncol; - double nfont; - double nsize; - double nstyle; - double nwidth; - float alpha_hi; - float alpha_lo; - float beta_lo; - float beta_hi; - float cy; - float cx; - float dy; - float dx; - float height; - float hmx; - float hmy; - float ly; - float lx; - float rx; - float rlen; - float rise; - float rxu; - float ryu; - float ry; - float tdrop; - float tybn[ 4 ]; - float txbn[ 4 ]; - float ulen; - float uyu; - float uxu; - float uy; - float ux; - float width; - float x0; - float y0; - int estype; - int esval; - int got_esc; - int grfcap; - int i; - int nc; - -/* Check the global error status, and that we have something to plot, and - the reference position is good, and that the up vector is not zero. */ - if ( !astOK || !text || !text[ 0 ] || x == AST__BAD || y == AST__BAD || - ( upx == 0.0 && upy == 0.0 ) ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Initialise variables to avoid compiler warnings. */ - rx = 0.0f; - ry = 0.0f; - x0 = 0.0f; - y0 = 0.0f; - -/* Get an up vector which refers to the graphics coordinates in their correct - senses (the supplied values are reversed if the corresponding axis is - reversed). */ - ux = ( this->xrev ) ? -upx : upx; - uy = ( this->yrev ) ? -upy : upy; - -/* Find a vector which points from left to right along the text - baseline, taking account of any difference in the scales of the x - and y axes (is possible). This also scales the up vector so that it - has a length equal to the height of normal text, and scales the right - vector to have the same length (on the screen) as the up vector. */ - RightVector( this, &ux, &uy, &rx, &ry, method, class, status ); - -/* Create a unit right vector. */ - rlen = sqrt( rx*rx + ry*ry ); - rxu = rx/rlen; - ryu = ry/rlen; - -/* Create a unit up vector. */ - ulen = sqrt( ux*ux + uy*uy ); - uxu = ux/ulen; - uyu = uy/ulen; - -/* Some older GRF modules cannot plot strings with vertical justification - of "M". Check the capabilities of the grf module, and, if necessary, - modify the justification and the coords of the reference point to use - "B" instead of "M". This call also returns us the coords at the left - end of the baseline of normal text. */ - lx = x; - ly = y; - lj = JustMB( this, esc, text, &lx, &ly, upx, upy, just, uxu, uyu, rxu, - ryu, &x0, &y0, method, class, status ); - -/* Initialise the horizontal and verical limits of the total bounding box. */ - alpha_lo = FLT_MAX; - alpha_hi = -FLT_MAX; - beta_lo = FLT_MAX; - beta_hi = -FLT_MAX; - -/* Tell the grf module whether or not to interpret escape sequences,and - also note if the grf module is capable of interpreting escape - sequences. */ - grfcap = GCap( this, GRF__ESC, esc, status ); - -/* Forget the horizontal position remembered by any "%h+" escape sequences - from any previous string. */ - this->hmarkx = FLT_MAX; - this->hmarky = FLT_MAX; - -/* If escape sequences are being interpreted and the string contains some - escape sequences, but the grf module cannot interpret escape sequences, - split the supplied text up into sub-strings delimited by escape sequences - and plot each sub-string individually, modifying the reference point and - graphics attributes as indicated by the escape sequences. */ - if( esc && HasEscapes( text, status ) && !grfcap ) { - -/* Take a copy of the supplied text so that we can temporarily terminate - each sub-string by poking a null (0) character into it. */ - lt = (char *) astStore( NULL, (void *) text, strlen( text ) + 1 ); - -/* Indicate that the current baseline is at its normal height. */ - rise = 0.0; - -/* Get the graphical attribute values for normal text. */ - GAttr( this, GRF__SIZE, AST__BAD, &nsize, GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, AST__BAD, &nwidth, GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, AST__BAD, &nfont, GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, AST__BAD, &nstyle, GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, AST__BAD, &ncol, GRF__TEXT, method, class, status ); - -/* The "concatenation point" (cx,cy) is the point where the normal baseline - crosses the left hand edge of the substring bounding box. Initialise - this to the left edge of the first substring. */ - cx = x0; - cy = y0; - -/* Loop round the whole string, drawing each sub-string. */ - a = lt; - while( *a && astOK ) { - -/* Examine the start of the remaining string and note if it begins with - an escape sequence. If so, the type and value of the escape sequnece - is returned. In either case the number of characters to the next - delimiter is returned. */ - got_esc = astFindEscape( a, &estype, &esval, &nc ); - -/* If the string starts with an escaped percent sign, modify things so that - we can draw the percent sign with the normal text drawing code below. */ - if( got_esc && estype == GRF__ESPER ) { - got_esc = 0; - a++; - nc = 1; - } - -/* If the string starts with any other escape sequence, modify the graphics - attributes and concatenation point as required by the escape sequence. */ - if( got_esc ) { - InterpEscape( this, estype, (double) esval, &cx, &cy, ux, uy, - rx, ry, lj, &rise, nsize, nstyle, nwidth, ncol, - nfont, method, class, status ); - -/* If the remaining string starts with normal text, draw it. */ - } else { - -/* Temporarily terminate the sub-string which ends with the next escape - sequence. */ - cc = a[ nc ]; - a[ nc ] = 0; - -/* We now have to decide on the reference point for this sub-string. If - the justification is "BL" then the reference point is just the current - concatenation point. */ - if( lj[ 0 ] == 'B' && lj[ 1 ] == 'L' ) { - lx = cx; - ly = cy; - -/* Otherwise, the reference point is offset from the concatenation point. - It would be simpler to draw all substrings with "BL" justification but - this causes problems with some grf modules (such as GAIA) which zoom - the display by modifying the position of text strings without also - modifying the size of text strings. Using the correct reference point - for all sub-strings minimises the drift which occurs when such a grf - modules zooms the display. */ - } else { - -/* Find the width and height of this substring, and the distance between the - bottom of the bounding box and the baseline (the drop). We do this - by calling this function recursively, using "BL" justification to - avoid infinite recursion. */ - -/* Forget the horizontal position remembered by any "%h+" escape sequences - from any previous string. Save and re-instate the position of the - horizontal mark since the call to DrawText may change it. */ - hmx = this->hmarkx; - hmy = this->hmarky; - - DrawText( this, 0, esc, a, cx, cy, "BL", upx, upy, txbn, tybn, - &tdrop, method, class, status ); - - this->hmarkx = hmx; - this->hmarky = hmy; - - dx = txbn[ 0 ] - txbn[ 3 ]; - dy = tybn[ 0 ] - tybn[ 3 ]; - width = sqrt( dx*dx + dy*dy ); - - dx = txbn[ 0 ] - txbn[ 1 ]; - dy = tybn[ 0 ] - tybn[ 1 ]; - height = sqrt( dx*dx + dy*dy ); - -/* First move right from the concatenation point by a fraction of the width - of the substring (0.5 for "C" and 1.0 for "R"). */ - if( lj[ 1 ] == 'C' ) { - width *= 0.5; - } else if( lj[ 1 ] != 'R' ) { - width = 0; - } - lx = cx + rxu*width; - ly = cy + ryu*width; - -/* Now move vertically by an amount which produes the requested vertical - justification. */ - if( lj[ 0 ] == 'T' ) { - height -= tdrop; - lx += height*uxu; - ly += height*uyu; - - } else if( lj[ 0 ] == 'C' ) { - height = 0.5*height - tdrop; - lx += height*uxu; - ly += height*uyu; - - } else if( lj[ 0 ] == 'M' ) { - lx -= tdrop*uxu; - ly -= tdrop*uyu; - } - } - -/* Draw it, and then find its real bounding box (i.e. using the correct - reference position found above). */ - if( ink ) GText( this, a, lx, ly, lj, upx, upy, method, class, status ); - GTxExt( this, a, lx, ly, lj, upx, upy, txbn, tybn, method, class, status ); - -/* Re-instate the orignal value of the terminator character.*/ - a[ nc ] = cc; - -/* Move the concatenation point to the right (i.e. in the direction of the text - baseline) by an amount equal to the width of the bounding box. Also - update the total bounding box limits.*/ - UpdateConcat( txbn, tybn, ux, uy, rx, ry, &cx, &cy, - x0, y0, &alpha_lo, &alpha_hi, &beta_lo, &beta_hi, status ); - } - -/* Move on to the next character. */ - a += nc; - } - -/* Free resources. */ - lt = astFree( lt ); - -/* Reset all attributes to their normal values. */ - GAttr( this, GRF__SIZE, nsize, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, nwidth, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, ncol, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, nfont, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, nstyle, NULL, GRF__TEXT, method, class, status ); - -/* If any escape sequences can be interpreted by the grf module, just pass - the text string on to the grf module. */ - } else { - if( ink ) GText( this, text, lx, ly, lj, upx, upy, method, class, status ); - GTxExt( this, text, lx, ly, lj, upx, upy, txbn, tybn, method, class, status ); - -/* The corners in the bounding box returned by GTxExt are in no - particular order. But this function is contracted to return them - in a specified order. So we use UpdateConcat to find the verical and - horizontal limits of the box in a form which can be used to produce - the correct order. UpdateConcat will also update the concatenation point, - but that is irrelevant in this context. */ - UpdateConcat( txbn, tybn, ux, uy, rx, ry, &lx, &ly, x0, y0, &alpha_lo, - &alpha_hi, &beta_lo, &beta_hi, status ); - } - -/* Return the total bounding box,in the order bottom left, topleft, top - right, bottom right. */ - xbn[ 0 ] = x0 + alpha_lo*ux + beta_lo*rx; - ybn[ 0 ] = y0 + alpha_lo*uy + beta_lo*ry; - - xbn[ 1 ] = x0 + alpha_hi*ux + beta_lo*rx; - ybn[ 1 ] = y0 + alpha_hi*uy + beta_lo*ry; - - xbn[ 2 ] = x0 + alpha_hi*ux + beta_hi*rx; - ybn[ 2 ] = y0 + alpha_hi*uy + beta_hi*ry; - - xbn[ 3 ] = x0 + alpha_lo*ux + beta_hi*rx; - ybn[ 3 ] = y0 + alpha_lo*uy + beta_hi*ry; - -/* Return the drop. */ - if( drop ) *drop = -alpha_lo*ulen; - -/* Free memory.*/ - lj = astFree( (void *) lj ); - -/* If OK, update the box containing all drawn graphics primitives. */ - if( ink && astOK && !Boxp_freeze ) { - for( i = 0; i < 4; i++ ){ - Boxp_lbnd[ 0 ] = astMIN( xbn[ i ], Boxp_lbnd[ 0 ] ); - Boxp_ubnd[ 0 ] = astMAX( xbn[ i ], Boxp_ubnd[ 0 ] ); - Boxp_lbnd[ 1 ] = astMIN( ybn[ i ], Boxp_lbnd[ 1 ] ); - Boxp_ubnd[ 1 ] = astMAX( ybn[ i ], Boxp_ubnd[ 1 ] ); - } - } -} - -static void DrawTicks( AstPlot *this, TickInfo **grid, int drawgrid, - double *labelat, double *gap, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* DrawTicks - -* Purpose: -* Draw tick marks for a 2-D annotated coordinate grid. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void DrawTicks( AstPlot *this, TickInfo **grid, int drawgrid, -* double *labelat, double *gap, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws major and minor tick marks. It uses a different -* technique depending on whether the tick marks are to be put along the -* edges of the plotting area, or along a curve through the middle of the -* plotting area. The physical axis values at which to put tick marks -* are supplied in parameter "grid". -* -* If the ticks are placed on the edges of the plotting area, The -* EdgeCrossings function is used to find all points along the edge which -* have a physical axis value correspoinding to a tick value (there can in -* general be more than one point on an edge with a given physical axis -* value). Ticks are put at all such crossings. -* -* If ticks are placed within the plotting area, then they are put -* along a curve defined by the "other axis" values supplied in -* parameter "labelat". - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick marks on the axis. See function GridLines. -* drawgrid -* If non-zero, then a grid of curves has been drawn to mark the -* major axis values. -* labelat -* A pointer to a 2 element array in holding the constant axis -* values at which tick marks are to be put. Element 0 should hold -* the axis 1 value at which tick marks for axis 0 are placed. Element -* 1 should hold the axis 0 value at which tick marks for axis -* 1 are placed. If ticks are to be placed round the edges of the -* plotting zone instead of within the plotting zone, then values of -* AST__BAD should be supplied. -* gap -* Pointer to array of two values holding the gap between major -* tick marks on the two axes. This will be the difference between, -* or the ratio of, adjacent tick mark values, depending on the -* setting of the LogTicks attribute. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function assumes the current Frame of the Plot is 2 -* dimensional, and it should not be called if this is not the case. -*/ - -/* Local Variables: */ - AstFrame *frame; /* Pointer to current Frame in Plot */ - AstMapping *mapping; /* Pointer to graphics->physical Mapping */ - AstPointSet *pset1; /* Pointer to PointSet holding physical coords. */ - AstPointSet *pset2; /* Pointer to PointSet holding graphics coords. */ - AstPointSet *pset3; /* Pointer to PointSet holding clipped graphics coords. */ - EdgeCrossingsStatics *ecstatics = NULL; /* For static data structure */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - double *ptr1[2]; /* Pointer to physical data */ - double **ptr2; /* Pointer to graphics data */ - double **ptr3; /* Pointer to clipped graphics data */ - double *a; /* Pointer to next current axis value */ - double *b; /* Pointer to next other axis value */ - double *value; /* Current tick value */ - double *x; /* Pointer to next X value */ - double *xc; /* Pointer to next clipped X value */ - double *y; /* Pointer to next Y value */ - double *yc; /* Pointer to next clipped Y value */ - double a0; /* Physical axis value at base of tick */ - double axmax; /* Upper axis limit */ - double axmin; /* Lower axis limit */ - double delta1; /* Increment between minor ticks above major tick */ - double delta2; /* Increment between minor ticks below major tick */ - double diff; /* Difference between adjacent major ticks */ - double dl2; /* Squared increment between points */ - double dl2_limit; /* Minimum usable squared increment between points */ - double dl; /* Increment between points */ - double dx; /* X component of increment along tick mark */ - double dy; /* Y component of increment along tick mark */ - double ex; /* X component of increment between points */ - double ey; /* Y component of increment between points */ - double lblat2; /* Other axis value part way up each tick */ - double lblat; /* Other axis value at base of each tick */ - double mindim; /* Shortest dimension of plotting area */ - double minval; /* Current axis value at next minor tick */ - double mjsign; /* Sign of the major tick mark length */ - double mjtklen; /* Length of major tick marks */ - double mnsign; /* Sign of the minor tick mark length */ - double mntklen; /* Length of minor tick marks */ - double ux; /* X component of unit vector along tick mark */ - double uy; /* Y component of unit vector along tick mark */ - double val; /* Major axis value */ - double x0; /* X at base of tick */ - double x1; /* X at end of tick */ - double x2; /* Clipped X at base of tick */ - double y0; /* Y at base of tick */ - double y1; /* Y at end of tick */ - double y2; /* Clipped Y at base of tick */ - int *majflag; /* Pointer to next major/minor flag */ - int *majflags; /* Pointer to aray of major/minor flags */ - int axis; /* Current axis index */ - int ed; /* Doing a secondary edge? */ - int edge; /* Index of edge being ticked */ - int first; /* Is this the first tick to be drawn? */ - int gelid; /* ID for next graphical element to be drawn */ - int i; /* Minor tick mark index */ - int logticks; /* Are major tick marks logarithmically spaced? */ - int minhi; /* Highest minor tick mark index */ - int minlo; /* Lowest minor tick mark index */ - int nedge; /* No. of edges to be ticked for each axis */ - int nel; /* Actual number of tick marks to draw */ - int ntot; /* Maximum number of tick marks */ - int tick; /* Tick index */ - int lasttick; /* Index of last major tick mark */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - a = NULL; - delta1 = 0.0; - delta2 = 0.0; - lblat2 = 0.0; - uy = 0.0; - logticks = 0; - -/* Get the minimum dimension of the plotting ares. */ - mindim = astMIN( this->xhi - this->xlo, this->yhi - this->ylo ); - -/* Information about the drawn tick marks is saved in the Plot structure. - Reset this information now so that we are ready to store information - about the new ticks that will be drawn by this function invocation. */ - SaveTick( this, -1, 0.0, 0.0, 0, status ); - -/* If ticks are to be put round the edges of the plotting area... */ -/* ============================================================== */ - if( labelat[ 0 ] == AST__BAD || labelat[ 1 ] == AST__BAD ){ - -/* Store the number of edges to be ticked for each axis. */ - nedge = astGetTickAll( this )? 2 : 1; - -/* Do each required edge. */ - for( ed = 0; ed < nedge; ed++ ){ - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__TICKS1_ID; - -/* Do each axis. */ - for( axis = 0; axis < 2; axis++ ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__LINE, method, class ); - -/* Store the length in graphics coordinates of major tick marks for this - axis. Use a default of zero if a grid has been drawn. */ - if( astTestMajTickLen( this, axis ) || !drawgrid ){ - mjtklen = astGetMajTickLen( this, axis )*mindim; - } else { - mjtklen = 0.0; - } - -/* Store the length in graphics coordinates of minor tick marks. */ - mntklen = astGetMinTickLen( this, axis )*mindim; - -/* Get the edge to be labelled with the axis values. Edge 0 is the left hand - edge. Edge 1 is the top edge. Edge 2 is the right-hand edge. Edge 3 is - the bottom edge. */ - edge = ( astGetEdge( this, axis ) + ed*2 ) % 4; - if( edge < 0 ) edge = -edge; - -/* Store a pointer to the structure containing information describing the - positions of the major tick marks along this axis. */ - info = grid[ axis ]; - -/* Store a pointer to the axis value at the first major tick mark. */ - value = info->ticks; - -/* Minor tick marks are drawn on both sides of each major tick mark. They - are identified by an index number relative to major tick mark at zero. - Store the indices of the first and last minor tick marks. */ - minlo = ( 1 - info->nminor )/2; - minhi = info->nminor/2; - -/* If major ticks are linear, store the difference between minor tick marks. - This value will be the same for all major ticks. */ - logticks = astGetLogTicks( this, axis ); - if( !logticks ) { - delta1 = gap[ axis ]/(double)info->nminor; - delta2 = delta1; - } - -/* Loop round until all ticks have been done. */ - for( tick = 0; tick < info->nmajor; tick++ ){ - -/* Draw tick marks at all occurrences of the current major tick value on - the selected edge of the plotting area. */ - Ticker( this, edge, axis, *value, gap, mjtklen, - 1, ( ed == 0 ), &ecstatics, method, class, status ); - -/* If minor tick mark values were not supplied, calculate them as even - intervals between the major tick values. */ - if( !info->minticks ) { - -/* If major ticks are logarithmic, store the difference between minor tick - marks. This value will be different for each major tick. Also, since - the minor ticks are drawn on either side of the major tick, the minor - tick spacing above the major tick will be different to that below the - minor tick when using logarathmic ticks. "delta1" is the minor gap - above the major value, and "delta2" is the minor gap below the major - value. */ - if( logticks ) { - delta1 = (*value) * ( gap[ axis ] - 1.0 )/ - (double)info->nminor; - delta2 = delta1 / gap[ axis ]; - } - -/* Extra minor tick marks are drawn below the first major tick mark and - above the last major tick mark to fill in any gaps caused by axis - limits being exceeded. */ - if( tick == 0 ) { - minlo = 1 - info->nminor; - } if( tick == 1 ) { - minlo = ( 1 - info->nminor )/2; - } else if( tick == info->nmajor - 1 ) { - minhi = info->nminor - 1; - } - -/* Store the axis value at the first minor tick mark. */ - minval = *value + minlo*delta2; - -/* Loop round all the minor tick marks, storing the physical coordinates - defining the tick mark. */ - for( i = minlo; i <= minhi; i++ ){ - -/* Draw tick marks at all occurrences of the current minor tick value on - the selected edge of the plotting area. Do not do the minor tick mark - with index zero, since this corresponds to the position of the major - tick mark. */ - if( i ) Ticker( this, edge, axis, minval, gap, mntklen, - 0, ( ed == 0 ), &ecstatics, method, class, status ); - -/* Get the axis value at the next minor tick mark. */ - minval += ( i < 0 ) ? delta2 : delta1; - } - } - -/* Point to the next major tick value. */ - value++; - - } - -/* If minor tick mark values have been supplied, used them. */ - if( info->minticks ) { - value = info->minticks; - for( tick = 0; tick < info->nminor; tick++, value++ ){ - Ticker( this, edge, axis, *value, gap, mntklen, 0, - ( ed == 0 ), &ecstatics, method, class, status ); - } - } - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__LINE, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__TICKS2_ID; - } - } - -/* Free the static resources allocated within EdgeCrossings (called - by Ticker). */ - (void) EdgeCrossings( NULL, 0, 0, 0.0, NULL, NULL, &ecstatics, method, - class, status ); - -/* If ticks are to put within the interior of the plotting area... */ -/* ============================================================== */ - } else { - -/* Get the mapping from base Frame (graphics coords) to current Frame - (physical coords). */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Get the current Frame from the Plot. */ - frame = astGetFrame( this, AST__CURRENT ); - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__TICKS1_ID; - -/* Do each axis. */ - for( axis = 0; axis < 2; axis++ ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__LINE, method, class ); - -/* Store the length in graphics coordinates of major tick marks for this - axis. Use a default of zero if a grid has been drawn. */ - if( astTestMajTickLen( this, axis ) || !drawgrid ){ - mjtklen = astGetMajTickLen( this, axis )*mindim; - } else { - mjtklen = 0.0; - } - -/* Store the length in graphics coordinates of minor tick marks. */ - mntklen = astGetMinTickLen( this, axis )*mindim; - -/* Indicate that the tick mark lengths should not be negatated. */ - mjsign = 1.0; - mnsign = 1.0; - -/* Store the smallest squared distance in graphics coordinates which - can reliably be used to determine the direction of a tick mark. */ - dl2_limit = 0.0001*mindim; - dl2_limit *= dl2_limit; - -/* Store a pointer to the structure containing information describing the - positions of the major tick marks along this axis. */ - info = grid[ axis ]; - -/* Store a pointer to the axis value at the first major tick mark. */ - value = info->ticks; - -/* Get the maximum number of tick marks to be drawn on this axis. */ - ntot = 0; - ntot = info->nmajor; - if( info->minticks ) { - ntot += info->nmajor + info->nminor; - } else { - ntot += ( info->nmajor + 1 )*( info->nminor - 1 ); - } - -/* Pass on to the next axis if no ticks are to be drawn. */ - if( ntot ) { - -/* Allocate memory to hold the physical coordinates defining all the - required tick marks. Each tick mark is defined by 2 points. */ - ptr1[ 0 ] = (double *) astMalloc( sizeof(double)*(size_t)(2*ntot) ); - ptr1[ 1 ] = (double *) astMalloc( sizeof(double)*(size_t)(2*ntot) ); - -/* Allocate memory to hold a set of flags indicating whether each tick - mark is minor or major. */ - majflags = (int *) astMalloc( sizeof(int)*(size_t)ntot ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* If the tick values have been supplied using astSetTickValues, just - copy them into the above arrays. */ - if( info->minticks ) { - - a = ptr1[ axis ]; - b = ptr1[ 1 - axis ]; - majflag = majflags; - - for( tick = 0; tick <= info->nmajor; tick++ ){ - - val = info->ticks[ tick ]; - if( logticks ) { - diff = val * ( gap[ axis ] - 1.0 ); - lblat2 = labelat[ axis ] + 0.2*diff; - } else { - lblat2 = labelat[ axis ] + 0.2*gap[ 1 - axis ]; - } - - *(a++) = val; - *(b++) = labelat[ axis ]; - *(a++) = val; - *(b++) = lblat2; - *(majflag++) = 1; - } - - for( tick = 0; tick <= info->nminor; tick++ ){ - - val = info->minticks[ tick ]; - if( logticks ) { - diff = val * ( gap[ axis ] - 1.0 ); - lblat2 = labelat[ axis ] + 0.2*diff; - } else { - lblat2 = labelat[ axis ] + 0.2*gap[ 1 - axis ]; - } - - *(a++) = val; - *(b++) = labelat[ axis ]; - *(a++) = val; - *(b++) = lblat2; - *(majflag++) = 0; - } - -/* If the tick values were not supplied using astSetTickValues, then we - need to calculate the minor tick positions explicitly. */ - } else { - -/* Store pointers to the next point on each axis. "a" always refers to the - current axis. Also store the value on the other axis at which the tick - marks starts, and another value on the other axis which is used to - defined the tick mark directions. */ - a = ptr1[ axis ]; - b = ptr1[ 1 - axis ]; - majflag = majflags; - lblat = labelat[ axis ]; - -/* Store another value on the other axis which is used to defined the tick - mark directions, and the difference between minor tick marks. For - linearly spaced tick marks these values will be the same for all major - ticks. Minor ticks are always drawn above the correponding major - value (i.e. minlo == 1 ) and so we do not need to set delta2. */ - logticks = astGetLogTicks( this, axis ); - if( !logticks ) { - lblat2 = labelat[ axis ] + 0.2*gap[ 1 - axis ]; - delta1 = gap[ axis ]/(double)info->nminor; - } - -/* Store the indices of the first and last minor tick marks, relative to - a major tick mark. */ - minlo = 1; - minhi = info->nminor - 1; - -/* Get the axis limits. */ - axmin = astGetBottom( frame, axis ); - axmax = astGetTop( frame, axis ); - -/* Loop round until all ticks have been done. We include a hypothetical tick - at index -1 (i.e. one gap below the first listed tick value) in order - to get minor tick marks below the first major tick. But the - hypothetical major tick value is not included in the list of major tick - values to draw. */ - lasttick = info->nmajor - 1; - for( tick = -1; tick <= lasttick; tick++ ){ - -/* Get the major tick value. */ - if( tick == -1 ) { - if( !logticks ) { - val = (*value) - gap[ axis ]; - }else { - val = (*value)/gap[ axis ]; - } - } else { - val = *(value++); - } - -/* Now find the value on the other axis which is used to defined the tick - mark directions, and the difference between minor tick marks, in the - case of logarithmically spaced tick marks. These values will be - different for every major tick. Minor ticks are always drawn above the - correponding major value (i.e. minlo == 1 ) and so we do not need to set - delta2. */ - if( logticks ) { - diff = val * ( gap[ axis ] - 1.0 ); - lblat2 = labelat[ axis ] + 0.2*diff; - delta1 = diff / (double)info->nminor; - } - -/* If major tick marks are required, store the physical coordinates at the - start of the major tick mark, and at a point a little way up the major - tick mark. */ - if( tick > -1 ){ - *(a++) = val; - *(b++) = lblat; - *(a++) = val; - *(b++) = lblat2; - *(majflag++) = 1; - } - -/* Store the points defining the minor tick marks on either side of - this major tick mark. First store the axis value at the first minor - tick mark. */ - minval = val + minlo*delta1; - -/* Loop round all the minor tick marks, storing the physical coordinates - defining the tick mark. */ - for( i = minlo; i <= minhi; i++ ){ - -/* Do not do the minor tick mark with index zero, since this corresponds - to the position of the major tick mark. Do not do any minor ticks that - are outside the axis range. */ - if( i && minval >= axmin && minval <= axmax ){ - *(a++) = minval; - *(b++) = lblat; - *(a++) = minval; - *(b++) = lblat2; - *(majflag++) = 0; - } - -/* Get the axis value at the next minor tick mark. */ - minval += delta1; - } - } - } - } - -/* Adjust the size of the arrays to exclude any unused space. */ - nel = a - ptr1[axis]; - ptr1[axis] = (double *) astRealloc( (void *) ptr1[axis], - sizeof(double)*nel ); - ptr1[1-axis] = (double *) astRealloc( (void *) ptr1[1-axis], - sizeof(double)*nel ); - -/* Create a pointset holding these coordinates. */ - pset1 = astPointSet( nel, 2, "", status ); - astSetPoints( pset1, ptr1 ); - -/* Transform these physical coordinates into graphics coordinates, without - doing any clipping (this is so that tick marks are still drawn even if - they extend into the area containing clipped physical coordinates). */ - pset2 = astTransform( mapping, pset1, 0, NULL ); - ptr2 = astGetPoints( pset2 ); - -/* Transform them again this time with clipping. */ - pset3 = Trans( this, NULL, mapping, pset1, 0, NULL, 0, method, class, status ); - ptr3 = astGetPoints( pset3 ); - -/* Check the pointers can be used.*/ - if( astOK ){ - -/* Store pointers to the next point on each axis. */ - a = ptr1[ axis ]; - - x = ptr2[ 0 ]; - y = ptr2[ 1 ]; - - xc = ptr3[ 0 ]; - yc = ptr3[ 1 ]; - - majflag = majflags; - -/* Loop round all ticks (major and minor). */ - ux = AST__BAD; - first = 1; - for( tick = 0; tick < nel/2; tick++ ){ - -/* Store the physical axis value at the base of the tick mark (skip over - the physical axis value at the point up the tick mark). */ - a0 = *(a++); - a++; - -/* Store the x and y coordinates at the base of the tick mark. */ - x0 = *(x++); - y0 = *(y++); - -/* Store the x and y coordinates at a point up the tick mark. */ - x1 = *(x++); - y1 = *(y++); - -/* Store the clipped x and y coordinates at the base of the tick mark. */ - x2 = *(xc++); - y2 = *(yc++); - -/* Skip over the clipped x and y coordinates at the point up the tick mark. */ - xc++; - yc++; - -/* Check they are all valid, and that the start of the tick mark is within - the plotting area. */ - if( x0 != AST__BAD && y0 != AST__BAD && - x1 != AST__BAD && y1 != AST__BAD && - x2 != AST__BAD && y2 != AST__BAD && - x0 <= this->xhi && x0 >= this->xlo && - y0 <= this->yhi && y0 >= this->ylo ){ - -/* Get the increments in X and Y beyween the two points, and the squared - distance between the two points. */ - dx = x1 - x0; - dy = y1 - y0; - dl2 = dx*dx + dy*dy; - -/* Check the two points are not co-incident. */ - if( dl2 > dl2_limit ){ - -/* Store the distance between the two points. */ - dl = sqrt( dl2 ); - -/* If this is the first tick to be drawn on this axis, decide which - direction to draw the tick mark so that they will appear on the right - hand side of the axis as seen by someone moving along the axis in the - positive direction (the numerical labels are also drawn on the same - side). */ - if( first ){ - first = 0; - -/* If the next tick mark is not defined, make an arbitrary decision by - leaving the sign of the tick mark length unchanged. */ - if( tick + 1 < nel/2 && - *x != AST__BAD && *y != AST__BAD && - a0 != AST__BAD && *a != AST__BAD ){ - -/* Form the vector joining this tick mark to the next. */ - ex = *x - x0; - ey = *y - y0; - -/* Ensure this vector is in the positive direction of the axis. */ - if( *a < a0 ) { - ex = -ex; - ey = -ey; - } - -/* If a positive tick mark length would put the marks on the wrong side, - negate the tick mark length. */ - if( ex*dy > ey*dx ){ - mjsign = -1.0; - mnsign = -1.0; - } - } - } - -/* Store the unit vector in the direction of the tick mark. This is used - as the default vector for the next tick mark if the direction of the - next tick mark is indeterminate. */ - ux = dx/dl; - uy = dy/dl; - } - -/* Only draw this tickmark if its direction is known. */ - if( ux != AST__BAD ) { - -/* Get the position of the end of the tick mark. The length of the tick - mark depends on whether it is a major or minor tick mark. */ - if( *majflag ){ - x1 = x0 + mjsign*mjtklen*ux; - y1 = y0 + mjsign*mjtklen*uy; - } else { - x1 = x0 + mnsign*mntklen*ux; - y1 = y0 + mnsign*mntklen*uy; - } - -/* Save and draw the tick mark. */ - SaveTick( this, axis, x0, y0, *majflag, status ); - if( x0 != x1 || y0 != y1 ) { - Bpoly( this, (float) x0, (float) y0, status ); - Apoly( this, (float) x1, (float) y1, status ); - Opoly( this, status ); - } - } - } - -/* Point to the next major/minor flag. */ - majflag++; - } - } - -/* Free the memory holding the physical coordinates. */ - ptr1[ 0 ] = (double *) astFree( ( void *) ptr1[ 0 ] ); - ptr1[ 1 ] = (double *) astFree( ( void *) ptr1[ 1 ] ); - majflags = (int *) astFree( (void *) majflags ); - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - pset3 = astAnnul( pset3 ); - } - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__LINE, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__TICKS2_ID; - } - -/* Annul the pointers to the Mapping and Frame. */ - mapping = astAnnul( mapping ); - frame = astAnnul( frame ); - - } - -/* Return. */ - return; - -} - -static void EBuf( AstPlot *this, int *status ) { -/* -*++ -* Name: -c astEBuf -f AST_EBUF - -* Purpose: -* End the current graphical buffering context. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astEBuf( AstPlot *this ) -f CALL AST_EBUF( THIS STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function -f This routine -* ends the current graphics buffering context. It should match a -* corresponding call to the -c astBBuf function. -f AST_EBUF routine. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The nature of the buffering is determined by the underlying -* graphics system (as defined by the current grf module). Each call -c to this function -f to this routine -* simply invokes the astGEBuf function in the grf module. - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the active GRF EBuf function. */ - GEBuf( this, "astEBuf", astGetClass( this ), status ); -} - -static int EdgeLabels( AstPlot *this, int ink, TickInfo **grid, - AstPlotCurveData **cdata, int force, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* EdgeLabels - -* Purpose: -* Attempts to display labels for the major tick values around the edges -* of the plotting area. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int EdgeLabels( AstPlot *this, int ink, TickInfo **grid, -* AstPlotCurveData **cdata, int force, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function determines how many major tick value labels could be -* placed on the specified edges of the plotting area, and then if -* requested, and if sufficient such labels are found (more than 3 on -* each axis), they are drawn. To place a label on an edge, the curve -* defining the major tick value must cross the edge at a reasonably -* angle (at least 3 degrees). Labels are not drawn which would overlap -* other, previously drawn, labels. A flag is returned indicating if -* edge labels were (or could be) drawn. - -* Parameters: -* this -* A pointer to the Plot. -* ink -* If zero, then no labels are drawn, but the decision whether or -* not to draw them is still made and indicated in the returned function -* value. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick marks on the axis. See function GridLines. -* cdata -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structure (one for each -* major tick value on the axis), holding information about breaks -* in the curves drawn to mark the major tick values. See function -* DrawGrid. -* force -* If non-zero, then an attempt is made to draw edge labels even if -* it looks like insufficient edge labels can be produced. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If edge labels were drawn, 1 is returned. Otherwise 0 is returned. - -* Notes: -* - Zero is returned if an error has already occurred. -*/ - - -/* Local Variables: */ - AstFrame *frame; /* Pointer to current Frame */ - AstPlotCurveData *cdt; /* Pointer to the AstPlotCurveData for the next tick */ - LabelList *labellist; /* Pointer to a ingle list of labels to be plotted */ - LabelList *ll; /* Pointer to next label to be plotted */ - LabelList *llist[2]; /* Pointers to both lists of labels to be plotted */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - const char *just[ 2 ]; /* Justification string */ - const char *text; /* Pointer to label text */ - double edgeval; /* Axis value at the labelled edge */ - double mindim; /* Minimum dimension of the plotting area */ - double oppval; /* Axis value on the edge opposite to the labels */ - double tol; /* Max. distance between a break and the edge */ - double txtgap; /* Absolute gap between labels and edges */ - float *box; /* Pointer to array of label bounding boxes */ - float *vxbrk; /* X component of unit vector at current break */ - float *vybrk; /* Y component of unit vector at current break */ - float *xbrk; /* X coord. of current break */ - float *ybrk; /* Y coord. of current break */ - float xref; /* X coordinate at label's reference position */ - float yref; /* Y coordinate at label's reference position */ - int axis; /* Current axis index */ - int brk; /* Current break index */ - int edge; /* The edge to be labelled */ - int edgeax; /* Index of axis parallel to the labelled edge */ - int edgelabs; /* Can edge labels be produced? */ - int esc; /* INterpret escape sequences? */ - int gelid; /* ID for next graphical element to be drawn */ - int ii; /* Index into existing labels */ - int maxlab; /* Number of distinct edge labels */ - int medge[2]; /* No. of distinct edge labels for each axis */ - int naxlab; /* Number of edge labels */ - int near; /* Draw a label on the near edge? */ - int nedge[2]; /* No. of edge labels for each axis */ - int ok; /* Can the current tick mark be labelled on the edge? */ - int labfound; /* Label value has already been used? */ - int tick; /* Tick index */ - int upright; /* Draw all labels upright? */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - xref = 0.0; - yref = 0.0; - -/* See if escape sequences in text strings are to be interpreted. */ - esc = astGetEscape( this ); - -/* Initialise the returned flag to indicate that edge labels cannot be - produced. */ - edgelabs = 0; - -/* Get the minimum dimension of the plotting ares. */ - mindim = astMIN( this->xhi - this->xlo, this->yhi - this->ylo ); - -/* Set up the tolerance for curve breaks occuring on an edge of - the plotting zone. */ - tol = 0.005*mindim; - -/* First, we get a list of all the labels which can be produced on each - axis. The list includes the labels reference position in graphics - coordinates, and the index of the major tick value which it - represents. We do not yet know whether enough of the grid lines cross - the required edge to make it feasable to use edge labelling, so we do - not yet draw the labels. - =====================================================================*/ - -/* Initialise pointers to arrays of structures holding information - about the labels which can be draw round the edge for both axes. */ - llist[ 0 ] = NULL; - llist[ 1 ] = NULL; - -/* Indicate that no labels can yet be drawn on either axis. */ - nedge[ 0 ] = 0; - nedge[ 1 ] = 0; - -/* The "nedge" array counts the number of labels on each edge. But some - of these labels may be for the same tick mark (if the tick mark curve has - more than 1 intersection with the edge). The "medge" array counts the - number of *distinct* tick mark labels (i.e. the number of tick mark - values which have 1 or more interesections with the edge). */ - medge[ 0 ] = 0; - medge[ 1 ] = 0; - -/* For each axis, identify the the usable edge labels. */ - for( axis = 0; axis < 2; axis++ ){ - -/* See if labels for this axis are to be drawn upright. */ - if( astTestLabelUp( this, axis ) ) { - upright = astGetLabelUp( this, axis ); - } else { - upright = 1; - } - -/* Store the required gap between the label text and the axis. */ - txtgap = astGetNumLabGap( this, axis )*mindim; - -/* Get the edge to be labelled with the axis values. Edge 0 is the left hand - edge. Edge 1 is the top edge. Edge 2 is the right-hand edge. Edge 3 is - the bottom edge. */ - edge = astGetEdge( this, axis ) % 4; - if( edge < 0 ) edge = -edge; - -/* If edge labels for the current axis are to go on the left hand edge of - the plotting area... */ - if( edge == 0 ){ - -/* Choose the justification based on the sign of the text gap. */ - if( !upright ) { - just[ axis ] = "BC"; - } else if( txtgap > 0.0 ){ - just[ axis ] = "CR"; - } else if( txtgap < 0.0 ){ - just[ axis ] = "CL"; - } else { - just[ axis ] = "CC"; - } - -/* Store the constant X axis value at the edge being labelled. Also store - the X value to use for the reference position for all labels. Take into - account whether or not the X axis is displayed reversed (i.e. with high - X values at the left hand side of the screen ). */ - if( !this->xrev ){ - edgeval = this->xlo; - oppval = this->xhi; - xref = (float)( edgeval - txtgap ); - } else { - edgeval = this->xhi; - oppval = this->xlo; - xref = (float)( edgeval + txtgap ); - } - -/* Indicate that the "edgeval" value refers to axis 1 (the X axis). */ - edgeax = 1; - -/* Do the same if the labels are to go on the top edge. */ - } else if( edge == 1 ){ - if( txtgap > 0.0 ){ - just[ axis ] = "BC"; - } else if( txtgap < 0.0 ){ - just[ axis ] = "TC"; - } else { - just[ axis ] = "CC"; - } - - if( !this->yrev ){ - edgeval = this->yhi; - oppval = this->ylo; - yref = (float)( edgeval + txtgap ); - } else { - edgeval = this->ylo; - oppval = this->yhi; - yref = (float)( edgeval - txtgap ); - } - - edgeax = 0; - -/* Do the same if the labels are to go on the right-hand edge. */ - } else if( edge == 2 ){ - - if( !upright ) { - just[ axis ] = "BC"; - } else if( txtgap > 0.0 ){ - just[ axis ] = "CL"; - } else if( txtgap < 0.0 ){ - just[ axis ] = "CR"; - } else { - just[ axis ] = "CC"; - } - - if( !this->xrev ){ - edgeval = this->xhi; - oppval = this->xlo; - xref = (float)( edgeval + txtgap ); - } else { - edgeval = this->xlo; - oppval = this->xhi; - xref = (float)( edgeval - txtgap ); - } - - edgeax = 1; - -/* Do the same if the labels are to go on the bottom edge. */ - } else { - if( txtgap > 0.0 ){ - just[ axis ] = "TC"; - } else if( txtgap < 0.0 ){ - just[ axis ] = "BC"; - } else { - just[ axis ] = "CC"; - } - - if( !this->yrev ){ - edgeval = this->ylo; - oppval = this->yhi; - yref = (float)( edgeval - txtgap ); - } else { - edgeval = this->yhi; - oppval = this->ylo; - yref = (float)( edgeval + txtgap ); - } - - edgeax = 0; - - } - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along this axis. */ - info = grid[ axis ]; - -/* Get a pointer to the structure containing information describing the - breaks in the curve which is parallel to the other axis and passes - through the first major tick mark. */ - cdt = cdata[ axis ]; - -/* Initialise the pointer to the list of text strings to be drawn. */ - labellist = NULL; - -/* Initialise the number of labels which can be placed on the near edge of - the plotting zone (some of which may be the same). */ - naxlab = 0; - -/* Initialise the number of distinct labelled tick mark values. */ - maxlab = 0; - -/* Loop round each of the major tick marks on the current axis. */ - for( tick = 0; cdt && info && tick < info->nmajor; tick++ ){ - -/* Store pointers to the values giving the position and unit direction - vector of the curve at the first break. */ - xbrk = cdt->xbrk; - ybrk = cdt->ybrk; - vxbrk = cdt->vxbrk; - vybrk = cdt->vybrk; - -/* Loop round each of the breaks in the curve which passes through the - current major tick mark, and is parallel to the other axis. */ - ok = 0; - for( brk = 0; brk < cdt->nbrk; brk++ ){ - -/* A label can be produced on the near edge of the plotting zone if the - current break occurs on, or close to, the edge, and the curve is not - nearly parallel to the axis (limit is 5 degs). */ - near = ( ( edgeax == 0 && - fabs( (double) *ybrk - edgeval ) < tol && - fabs( (double) *vybrk ) > 0.09 ) || - ( edgeax == 1 && - fabs( (double) *xbrk - edgeval ) < tol && - fabs( (double) *vxbrk ) > 0.09 ) ); - -/* Get the label text. */ - if( info->labels ) { - text = (info->labels)[ tick ]; - } else { - text = NULL; - } - -/* If a label can be produced, record the information needed to draw the - label. */ - if( near && text ){ - - labellist = (LabelList *) astGrow( (void *) labellist, naxlab + 1, sizeof(LabelList) ); - if ( !astOK ) break; - - if( edgeax == 0 ){ - (labellist + naxlab)->index = (double) *xbrk; - (labellist + naxlab)->x = (double) *xbrk; - (labellist + naxlab)->y = (double) yref; - } else { - (labellist + naxlab)->index = (double) *ybrk; - (labellist + naxlab)->x = (double) xref; - (labellist + naxlab)->y = (double) *ybrk; - } - - (labellist + naxlab)->text = (char *) astStore( NULL, (void *) text, strlen(text) + 1 ); - (labellist + naxlab)->just = (char *) astStore( NULL, (void *) just[ axis ], strlen(just[ axis ]) + 1 ); - -/* The up vector depends on which edge is being labelled and whether all - labels are being drawn upright or not. */ - if( edge == 1 || edge == 3 || upright ) { - (labellist + naxlab)->upx = 0.0; - (labellist + naxlab)->upy = 1.0; - } else if( edge == 0 ) { - (labellist + naxlab)->upx = -1.0; - (labellist + naxlab)->upy = 0.0; - } else { - (labellist + naxlab)->upx = 1.0; - (labellist + naxlab)->upy = 0.0; - } - - (labellist + naxlab)->val = (info->ticks)[ tick ]; - naxlab++; - -/* If this label has not already been included in the label list, indicate - that we have found another usable label. */ - labfound = 0; - for( ii = 0; ii < naxlab-1; ii++ ) { - if( fabs( (info->ticks)[ tick ] - - (labellist + ii)->val ) < 0.2*info->gap ) { - labfound = 1; - break; - } - } - if( !labfound ) ok = 1; - - } - -/* Increment the pointers to the values giving the position and unit direction - vector of the next break. */ - xbrk++; - ybrk++; - vxbrk++; - vybrk++; - - } - -/* If an error has occurred, break out of the loop. */ - if( !astOK ) break; - -/* If one or more labels could be produced for this tick mark value, - increment the number of labeled tick marks found. */ - if( ok ) maxlab++; - -/* Get a pointer to the curve through the next major tick mark. */ - cdt++; - - } - -/* If an error has occurred, break out of the loop. */ - if( !astOK ) break; - -/* Store the number of labels for this axis, and the pointer to the - drawable labels. */ - nedge[ axis ] = naxlab; - medge[ axis ] = maxlab; - llist[ axis ] = labellist; - } - -/* We now know how many labels would be produced on each axis if edge - labelling were to be used. We also know what those labelled values are, - and where the labels would be drawn. We now take the decision as to - whether there are enough of these labels to make edge labelling - feasable. If so, we carry on and draw the labels. There need to be - at least 3 labels on each axis for linear tick spacing and 2 for log - tick spacing (or a non-zero value supplied for "force")... - ================================================================= */ - if( astOK && ( ( medge[ 0 ] > ( astGetLogTicks( this, 0 ) ? 1 : 2 ) && - medge[ 1 ] > ( astGetLogTicks( this, 1 ) ? 1 : 2 ) ) - || force ) ) { - -/* Set the returned flag to indicate that edge labelling is being used. */ - edgelabs = 1; - -/* Initialise the pointer to the memory holding the bounding boxes for - all labels (used by function Overlap). */ - box = NULL; - -/* Get a pointer to the current Frame in the Plot. */ - frame = astGetFrame( this, AST__CURRENT ); - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__NUMLAB1_ID; - -/* If required, draw the labels for each axis in turn. */ - for( axis = 0; axis < 2 && ink; axis++ ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__TEXT, method, class ); - -/* Plot them. */ - info = grid[ axis ]; - PlotLabels( this, esc, frame, axis, llist[ axis ], info->fmt, - nedge[ axis ], &box, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__TEXT, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__NUMLAB2_ID; - - } - -/* Free the memory used to hold the bounding boxes. */ - box = (float *) astFree( (void *) box ); - -/* Annul the pointer to the Frame. */ - frame = astAnnul( frame ); - } - -/* Free the memory used to store the label information. */ - for( axis = 0; axis < 2; axis++ ){ - ll = llist[ axis ]; - if( ll ) { - for( tick = 0; tick < nedge[ axis ]; tick ++ ) { - ll->text = (char *) astFree( (void *) ll->text ); - ll->just = (char *) astFree( (void *) ll->just ); - ll++; - } - llist[ axis ] = (LabelList *) astFree( (void *) llist[ axis ] ); - } - } - -/* Return the flag indicating if edge labels were produced. */ - return edgelabs; - -} - -static int EdgeCrossings( AstPlot *this, int edge, int axis, double axval, - double *gap, double **cross, - EdgeCrossingsStatics **pstatics, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* EdgeCrossings - -* Purpose: -* Find all occurrences of a given physical axis value on an edge of the -* plotting area. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int EdgeCrossings( AstPlot *this, int edge, int axis, double axval, -* double *gap, double **cross, -* EdgeCrossingsStatics **pstatics, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function finds all occurences of a given physical axis value -* along a specified edge of the plotting area. Firstly, a set of evenly -* spaced points ("edge samples") are placed along the edge and the -* corresponding physical coordinates are found. These physical coordinates -* are then offset slightly from their original positions in the direction -* of the "other" axis (i.e. index [ 1 - axis ] ), and transformed back -* into graphics coordinates. These coordinates give the tangent vector -* at each of the edge samples. -* -* To find the crossings, the supplied axis value is compared with the axis -* value at each sample in turn, starting from one end of the edge and -* working through to the other end. When a crossing is found, linear -* interpolation is used between the two adjacent edge samples to find a -* more accurate estimate of the crossing. The vector at the crossing -* is also estimated by linear interpolation between the vectors at the two -* adjacent samples. -* -* This basic algorithm fails if there is a discontinuity in the axis -* values along the edge. For instance, if the edge covers a range of -* Right Ascension from 23h to 1h, there will be a discontinuity at 0h -* at which the RA values suddenly jump from 2*PI to zero. This jump -* encompasses all normalised RA values and so every axis value would be -* given a crossing at this point. To avoid this, a bad sample is -* interposed between the two samples on either side of the -* discontinuity. This prevents any crossings from being placed at the -* discontinuity. -* -* There is a second problem related to discontinuities. If the supplied -* axis value is zero (using the above RA example again), then no -* crossings will be found, not only because of the extra bad sample, -* but also because the samples will not quite cover the range of axis -* values covered by the discontinuity because of the discrete nature -* of the samples). To get round this, the sections on either side -* of the discontinity are extended by a single sample. These extra -* samples are assumed to be conincident with the neighbouring sample, -* except that the value for the searched axis is modified to be a -* linear extension from the neighbouring samples. - - -* Parameters: -* this -* A pointer to the Plot. Supply a NULL pointer to release resources. -* edge -* The edge of the plotting area to be used. Edge 0 is the left hand -* edge. Edge 1 is the top edge. Edge 2 is the right-hand edge. Edge 3 -* is the bottom edge. -* axis -* The index of the axis to which "axval" refers. -* axval -* The physical axis value to be searched for. -* gap -* Pointer to array of two values holding the gap between major -* tick marks on the two axes. -* cross -* A pointer to the location at which to return a pointer to an -* array of doubles holding the crossing information. Each crossing -* is described by 4 doubles. The first pair are the graphiucs (x,y) -* coordinates of the point on the edge at which the crossing occurs. -* The second pair represents a unit vector in graphics coordinates -* which is tangential to the curve of constant axis value at the -* crossing. The memory allocated within this function to hold this -* data should be freed using astFree when no longer needed. If no -* crossings are found a NULL pointer is returned. -* pstatics -* Address of a pointer to a structure holding values for variables -* which were statically defined within this function prior to the -* thread-safe version of AST. If the pointer is supplied as NULL, -* then a new structure is allocated and initialised. Any supplied -* structure is freed if a NULL pointer is supplied for "this". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Return Value: -* The number of crossings found. - -* Notes: -* - This function allocates static resource on the first invocation -* which should be freed when no more calls are to be made, by making a -* final call with a NULL pointer supplied for "this". All other parameters -* are then ignored. -* - The static resources are re-initialised each time "edge" or -* "axis" changes, and so the calling function should be structure in -* order to minimise the number of times these parameter values change. -* - If an error has already occurred, or if this function should -* fail for any reason, zero is returned, and a NULL pointer is stored at -* "cross". - -*/ - -/* Local Variables: */ - EdgeCrossingsStatics *statics; /* Structure holding static data */ - AstMapping *mapping; /* Pointer to graphics->physical mapping */ - AstPointSet *pset1a; /* Physical cooords at offset edge samples */ - AstPointSet *pset2a; /* Physical cooords at offset edge samples */ - AstPointSet *pset3; /* Physical cooords at offset edge samples */ - AstPointSet *pset4a; /* Physical cooords at offset edge samples */ - double **ptr1a; /* Pointer to physical coord. data */ - double **ptr2a; /* Pointer to physical coord. data */ - double **ptr3; /* Pointer to physical coord. data */ - double **ptr4a; /* Pointer to physical coord. data */ - double *data; /* Pointer to next item of crossing information */ - double *p1; /* Pointer to graphics axis with constant value */ - double *p1a; /* Pointer to graphics axis with constant value */ - double *p2; /* Pointer to graphics axis with varying value */ - double *p2a; /* Pointer to graphics axis with varying value */ - double *q1; /* Pointer to physical axis being searched */ - double *q1a; /* Pointer to physical axis being searched */ - double *q2; /* Pointer to other physical axis */ - double *q2a; /* Pointer to other physical axis */ - double *v1; /* Pointer to vector component on axis 0 */ - double *v2; /* Pointer to vector component on axis 1 */ - double *v1a; /* Pointer to vector component on axis 0 */ - double *v2a; /* Pointer to vector component on axis 1 */ - double dd; /* The gap between edge samples */ - double diff; /* Squared differences between adjacent edge samples */ - double dl2; /* Squared vector length */ - double dl; /* Vector length */ - double dx; /* Vector X component */ - double dy; /* Vector Y component */ - double f; /* Weight for the current edge sample */ - double offset; /* Physical offset */ - double pp2; /* Varying graphics axis value at previous sample */ - double pq1; /* Required physical axis value at previous sample */ - double pv1; /* Previous vector component on axis 0 */ - double pv2; /* Previous vector component on axis 1 */ - double sum; /* Sum of squared differences between adjacent edge samples */ - double value; /* The current graphics axis value */ - double vx; /* Vector component on axis 0 at crossing */ - double vy; /* Vector component on axis 1 at crossing */ - double z; /* Varying graphics axis value at crossing */ - int i; /* Edge sample index */ - int iter; /* Iteration index */ - int larger; /* Is current axis value larger than target? */ - int logticks; /* Are major ticks logarithmically spaced? */ - int ncross; /* No. of crossings */ - int ndisc; /* No. of discontinuities along the edge */ - int nsum; /* Number of values summed in "sum" */ - int plarger; /* Was previous axis value larger than target? */ - -/* Get a pointer to the supplied statics object. */ - statics = *pstatics; - -/* If a NULL Plot pointer has been supplied, release the static - resources, and return. */ - if( !this ){ - if( statics ){ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->pset4 ) statics->pset4 = astAnnul( statics->pset4 ); - if( statics->frame ) statics->frame = astAnnul( statics->frame ); - *pstatics = astFree( statics ); - } - return 0; - } - -/* Initialise the number of crossings found, and the pointer to the place - to store them. */ - ncross = 0; - *cross = NULL; - -/* Check the global status. */ - if( !astOK ) return 0; - -/* If no statics structure was supplied, create one now and initialise it. */ - if( !statics ) { - statics = astMalloc( sizeof( EdgeCrossingsStatics ) ); - if( statics ) { - statics->frame = NULL; - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->pset4 = NULL; - statics->ptr1 = NULL; - statics->ptr2 = NULL; - statics->ptr4 = NULL; - statics->paxis = -1; - statics->pedge = -1; - *pstatics = statics; - } - } - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - pp2 = 0.0; - pv1 = 0.0; - pv2 = 0.0; - plarger = 0; - -/* See if the major ticks on the other axis are logarithmically or - linearly spaced. */ - logticks = astGetLogTicks( this, 1 - axis ); - -/* Ensure that "edge" is in the range 0 - 3. */ - edge = edge % 4; - if( edge < 0 ) edge = -edge; - -/* If the edge or axis has changed since the last invocation, or if this is - the first invocation, initialise some static data. */ -/* ======================================================================*/ - if( statics->pedge == -1 || statics->pedge != edge || statics->paxis != axis ){ - -/* Save the edge and axis. */ - statics->pedge = edge; - statics->paxis = axis; - -/* Annull any previous static data objects */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->pset4 ) statics->pset4 = astAnnul( statics->pset4 ); - if( statics->frame ) statics->frame = astAnnul( statics->frame ); - -/* Store some values so that the code does not need to consider each edge - separately. First deal with the left hand edge. */ - if( edge == 0 ){ - statics->edgeax = 0; - if( this->xrev ){ - statics->edgeval = this->xhi; - } else { - statics->edgeval = this->xlo; - } - statics->edgehi = this->yhi; - statics->edgelo = this->ylo; - -/* Now deal with the right hand edge. */ - } else if( edge == 2 ){ - statics->edgeax = 0; - if( this->xrev ){ - statics->edgeval = this->xlo; - } else { - statics->edgeval = this->xhi; - } - statics->edgehi = this->yhi; - statics->edgelo = this->ylo; - -/* Now deal with the bottom edge. */ - } else if( edge == 3 ){ - statics->edgeax = 1; - if( this->yrev ){ - statics->edgeval = this->yhi; - } else { - statics->edgeval = this->ylo; - } - statics->edgehi = this->xhi; - statics->edgelo = this->xlo; - - -/* Finally deal with the top edge. */ - } else { - statics->edgeax = 1; - if( this->yrev ){ - statics->edgeval = this->ylo; - } else { - statics->edgeval = this->yhi; - } - statics->edgehi = this->xhi; - statics->edgelo = this->xlo; - - } - -/* Get a pointer to the current Frame in the supplied Plot. */ - statics->frame = astGetFrame( this, AST__CURRENT ); - -/* Get a pointer to the mapping from base to current Frame in the supplied - Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Create a PointSet to hold the graphics coordinates at a set of - regularly spaced points along the specified edge of the plotting area. */ - pset1a = astPointSet( EDGETICKS_DIM, 2, "", status ); - ptr1a = astGetPoints( pset1a ); - -/* Create a PointSet to hold the corresponding physical coordinates. */ - pset2a = astPointSet( EDGETICKS_DIM, 2, "", status ); - ptr2a = astGetPoints( pset2a ); - -/* Check they can be used. */ - if( astOK ){ - -/* Set up the graphics coordinates. */ - dd = ( statics->edgehi - statics->edgelo )/(double)( EDGETICKS_DIM - 1 ); - value = statics->edgelo; - - p1 = ptr1a[ statics->edgeax ]; - p2 = ptr1a[ 1 - statics->edgeax ]; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - *(p1++) = statics->edgeval; - *(p2++) = value; - value += dd; - } - } - -/* Transform the graphics coordinates to physical coordinates, - *without* normalising them into their normal ranges. */ - (void) Trans( this, statics->frame, mapping, pset1a, 1, pset2a, 0, method, class, status ); - -/* Find the RMS step size along the axis. This is used to locate - discontinuities along the edge. Do three rejection iterations. */ - statics->limit = DBL_MAX; - for( iter = 0; iter < 3; iter ++ ){ - q1 = ptr2a[ axis ]; - pq1 = AST__BAD; - sum = 0.0; - nsum = 0; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - if( *q1 != AST__BAD && pq1 != AST__BAD ){ - diff = *q1 - pq1; - if( fabs( diff ) < statics->limit ){ - sum += diff*diff; - nsum++; - } - } - pq1 = *(q1++); - } - - if( nsum == 0 ) break; - statics->limit = 3.0*sqrt( sum/(double)nsum ); - } - -/* Now create another PointSet holding positions slightly offset from the - physical coordinates at the edge samples. The offset is in the direction - of the other physical axis. These positions are used to determine the - vector at the crossings. */ - if( nsum > 0 ){ - pset3 = astPointSet( EDGETICKS_DIM, 2, "", status ); - ptr3 = astGetPoints( pset3 ); - -/* Create a PointSet to hold the corresponding graphics coordinates. */ - pset4a = astPointSet( EDGETICKS_DIM, 2, "", status ); - ptr4a = astGetPoints( pset4a ); - -/* Check they can be used. */ - if( astOK ){ - -/* Copy the physical coordinates from PointSet 2 to PointSet 3, offseting - them slightly along the other axis. */ - p1 = ptr2a[ axis ]; - p2 = ptr2a[ 1 - axis ]; - - q1 = ptr3[ axis ]; - q2 = ptr3[ 1 - axis ]; - - offset = 0.2*gap[ 1 - axis ]; - - pq1 = AST__BAD; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - if( *p1 != AST__BAD && *p2 != AST__BAD ){ - if( logticks ) offset = 0.2*(*p2)*( gap[ 1 -axis ] - 1.0 ); - *(q2++) = *p2 + offset; - } else { - *(q2++) = AST__BAD; - } - pq1 = *(p1++); - *(q1++) = pq1; - p2++; - } - - } - -/* Transform the physical coordinates to graphics coordinates. */ - (void) Trans( this, NULL, mapping, pset3, 0, pset4a, 0, method, class, status ); - -/* Check they can be used. */ - if( astOK ){ - -/* Modify the contents of PointSet 4 to represent the unit vector in - graphics coordinates at each edge sample. */ - p1 = ptr1a[ 0 ]; - p2 = ptr1a[ 1 ]; - q1 = ptr4a[ 0 ]; - q2 = ptr4a[ 1 ]; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - if( *p1 != AST__BAD && *p2 != AST__BAD && - *q1 != AST__BAD && *q2 != AST__BAD ){ - - dx = *q1 - *p1; - dy = *q2 - *p2; - dl2 = dx*dx + dy*dy; - - if( dl2 > 0.0 ){ - dl = sqrt( dl2 ); - *q1 = dx/dl; - *q2 = dy/dl; - } else { - *q1 = AST__BAD; - *q2 = AST__BAD; - } - - } else { - *q1 = AST__BAD; - *q2 = AST__BAD; - } - - p1++; - p2++; - q1++; - q2++; - - } - - } - -/* Annul the PointSet holding offset physical cooridnates. */ - pset3 = astAnnul( pset3 ); - -/* Discontinuities in the axis values can cause problems. For instance, - using the above PointSets, no tick mark could be put at 0 hours RA - because of the discontinuity there. To get round this, 3 extra samples - are added at each discontinuity, the first extends the continuous section - which ends at the discontinuity, and the third extends the secion which - starts at the discontinuity. This results in the two sections overlapping - by one sample. The second is placed between these two and has a bad - axis value. It prevents crossings from being found in between the values - at the ends of the two sections. - - First count the number of discontinuities in the axis values. - Discontinuites are defined as steps of more than 9 times the RMS step - size. */ - q1 = ptr2a[ axis ]; - pq1 = AST__BAD; - statics->limit *= 3.0; - ndisc = 0; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - if( *q1 != AST__BAD && pq1 != AST__BAD ){ - if( fabs( *q1 - pq1 ) > statics->limit ) ndisc++; - } - pq1 = *(q1++); - } - -/* Store the size of the new PointSets holding the extra samples. */ - statics->dim = EDGETICKS_DIM + 3*ndisc; - -/* If there are no discontinuities, just clone the existing PointSets. */ - if( !ndisc ){ - statics->pset1 = astClone( pset1a ); - statics->pset2 = astClone( pset2a ); - statics->pset4 = astClone( pset4a ); - statics->ptr1 = astGetPoints( statics->pset1 ); - statics->ptr2 = astGetPoints( statics->pset2 ); - statics->ptr4 = astGetPoints( statics->pset4 ); - -/* Otherwise, create new PointSets. */ - } else { - statics->pset1 = astPointSet( statics->dim, 2, "", status ); - statics->ptr1 = astGetPoints( statics->pset1 ); - statics->pset2 = astPointSet( statics->dim, 2, "", status ); - statics->ptr2 = astGetPoints( statics->pset2 ); - statics->pset4 = astPointSet( statics->dim, 2, "", status ); - statics->ptr4 = astGetPoints( statics->pset4 ); - -/* Set up pointers used to walk through the arrays in the original - PointSets and the new PointSets. */ - p1 = statics->ptr1[ 0 ]; - p2 = statics->ptr1[ 1 ]; - q1 = statics->ptr2[ axis ]; - q2 = statics->ptr2[ 1 - axis ]; - v1 = statics->ptr4[ 0 ]; - v2 = statics->ptr4[ 1 ]; - - p1a = ptr1a[ 0 ]; - p2a = ptr1a[ 1 ]; - q1a = ptr2a[ axis ]; - q2a = ptr2a[ 1 - axis ]; - v1a = ptr4a[ 0 ]; - v2a = ptr4a[ 1 ]; - -/* Initialise the axis value at the previous sample. */ - pq1 = AST__BAD; - -/* Check all samples in the original PointSets. */ - for( i = 0; i < EDGETICKS_DIM; i++ ){ - -/* If this is the first point after a discontinuity... */ - if( *q1a != AST__BAD && pq1 != AST__BAD ){ - if( fabs( *q1a - pq1 ) > statics->limit ) { - -/* Insert an extra sample with the coordinates of the previous sample, - but with an axis value which is linearly extrapolated from the previous - samples. */ - *(p1++) = p1a[ 0 ]; - *(p2++) = p2a[ 0 ]; - *(v1++) = v1a[ -1 ]; - *(v2++) = v2a[ -1 ]; - *(q2++) = q2a[ -1 ]; - if( i > 1 && q1a[ -2 ] != AST__BAD ){ - *(q1++) = 2.0*pq1 - q1a[ -2 ]; - } else { - *(q1++) = pq1; - } - -/* Insert an extra sample with bad coordinates. */ - *(p1++) = AST__BAD; - *(p2++) = AST__BAD; - *(v1++) = AST__BAD; - *(v2++) = AST__BAD; - *(q2++) = AST__BAD; - *(q1++) = AST__BAD; - -/* Insert an extra sample with the cooridnates of the current sample, - but with an axis value which is linearly extrapolated from the - subsequent samples. */ - *(p1++) = p1a[ -1 ]; - *(p2++) = p2a[ -1 ]; - *(v1++) = *v1a; - *(v2++) = *v2a; - *(q2++) = *q2a; - if( i < EDGETICKS_DIM - 1 && q1a[ 1 ] != AST__BAD ){ - *(q1++) = 2.0*(*q1a) - q1a[ 1 ]; - } else { - *(q1++) = pq1; - } - - } - - } - -/* Save the current axis value. */ - pq1 = *q1a; - -/* Copy the current input values to the new PointSets, and move on the next - point in the original PointSets. */ - *(p1++) = *(p1a++); - *(p2++) = *(p2a++); - *(q1++) = *(q1a++); - *(q2++) = *(q2a++); - *(v1++) = *(v1a++); - *(v2++) = *(v2a++); - - } - - } - -/* Anull the original PointSets. */ - pset4a = astAnnul( pset4a ); - -/* If all the physical coordinates are bad, indicate this by setting the - limiting step size bad. */ - } else { - statics->limit = AST__BAD; - } - -/* Anull the original PointSets. */ - pset1a = astAnnul( pset1a ); - pset2a = astAnnul( pset2a ); - -/* Annul the pointer to the mapping from base to current Frame. */ - mapping = astAnnul( mapping ); - - } - -/* ======================================================================*/ -/* The initialisation has now been done. Check the physical coordinate data - can be used. */ - if( astOK && statics->limit != AST__BAD ){ - -/* Store pointers to the graphics and physical coordinates at the first - edge sample. */ - p1 = statics->ptr1[ statics->edgeax ]; /* Graphics axis with constant value */ - p2 = statics->ptr1[ 1 - statics->edgeax ]; /* Graphics axis with varying value */ - q1 = statics->ptr2[ axis ]; /* Physical axis values to be searched */ - q2 = statics->ptr2[ 1 - axis ]; /* The other physical axis */ - -/* Store pointers to the components of the unit vector at the first - edge sample. */ - v1 = statics->ptr4[ 0 ]; - v2 = statics->ptr4[ 1 ]; - -/* Inidicate that there is currently no "previous sample". */ - pq1 = AST__BAD; - -/* Check each point in turn... */ - for( i = 0; i < statics->dim; i++ ){ - -/* Skip this point if the physical coordinates are undefined. */ - if( *q1 != AST__BAD && *q2 != AST__BAD ){ - -/* Get a flag indicating if the required axis value has been exceeded at - the current edge sample. */ - larger = ( *q1 > axval ); - -/* If the state of this flag has changed since the previous edge sample, - and if we know where the previous sample was, we have found a - crossing. */ - if( pq1 != AST__BAD && larger != plarger ){ - -/* Find the distance from the previous physical axis value to the required - axis value, as a fraction of the distance from the previous axis value - to the current axis value. Since the flag has changed, we know that the - q1 value at this edge sample and the previous one must be different, so - we know that the denominator is not zero. */ - f = ( axval - pq1 )/( *q1 - pq1 ); - -/* Use linear interpolation to estimate the graphics axis value at the - crossing. */ - if( f != -1.0 ){ - z = pp2 + f*( *p2 - pp2 ); - -/* Use linear interpolation to estimate the two components of the unit - vector at the crossing. */ - if( *v1 != AST__BAD && pv1 != AST__BAD && - *v2 != AST__BAD && pv2 != AST__BAD ){ - vx = pv1 + f*( *v1 - pv1 ); - vy = pv2 + f*( *v2 - pv2 ); - -/* Normalise the vector. */ - dl2 = vx*vx + vy*vy; - if( dl2 > 0.0 ){ - dl = sqrt( dl2 ); - vx /= dl; - vy /= dl; - } else { - vx = AST__BAD; - vy = AST__BAD; - } - - } else { - vx = AST__BAD; - vy = AST__BAD; - } - -/* Grow the returned array to hold another crossing. */ - ncross++; - *cross = (double *) astGrow( (void *) *cross, ncross, - 4*sizeof( double ) ); - -/* If succesful, store the crossing. */ - if( astOK ) { - - data = *cross + 4*( ncross - 1 ); - if( statics->edgeax ){ - *(data++) = z; - *(data++) = statics->edgeval; - } else { - *(data++) = statics->edgeval; - *(data++) = z; - } - *(data++) = vx; - *(data++) = vy; - - } - - } - - } - -/* Save the flag for use on the next pass through this loop. */ - plarger = larger; - - } - -/* Save the varying graphics axis value and the required physical axis - value at the current edge sample (also save the vector). */ - pp2 = *p2; - pq1 = *q1; - pv1 = *v1; - pv2 = *v2; - -/* Point to the next edge sample. */ - p1++; - p2++; - q1++; - q2++; - v1++; - v2++; - - } - - } - -/* If an error has occurred, free the array holding the crossings, and - indicate that there are zero corssing. */ - if( !astOK ) { - *cross = (double *) astFree( (void *) *cross ); - ncross = 0; - } - -/* Return the answer. */ - return ncross; - -} - -int astFindEscape_( const char *text, int *type, int *value, int *nc, int *status ){ -/* -*+ -* Name: -* astFindEscape - -* Purpose: -* Check if a string starts with a graphics escape sequence. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* int astFindEscape( const char *text, int *type, int *value, int *nc ) - -* Description: -* This function returns a flag indiciating if the first character in -* the supplied string is the start of a graphics escape sequence. If -* so, the type and associated value (if any) of the escape sequence -* are returned in "type" and "value", and the number of characters -* occupied by the escape sequence is returned in "nc". If the -* supplied text string does not begin with an escape sequence, the -* number of characters before the first escape sequence is returned in -* "nc" (the length of the string is returned in "nc" if the string -* contains no escape sequences). -* -* This function can be used by grf modules which wish to implement -* interpretation of escape sequences internally, rather than allowing the -* Plot class to do the interpretation. - -* Parameters: -* text -* Pointer to the string to be checked. -* type -* Pointer to a location at which to return the type of escape -* sequence. Each type is identified by a symbolic constant defined -* in grf.h. The returned value is undefined if the supplied text -* does not begin with an escape sequence. -* value -* Pointer to a lcation at which to return the integer value -* associated with the escape sequence. All usable values will be -* positive. Zero is returned if the escape sequence has no associated -* integer. A value of -1 indicates that the attribute identified by -* "type" should be reset to its "normal" value (as established using -* the astGAttr function, etc). The returned value is undefined if the -* supplied text does not begin with an escape sequence. -* nc -* Pointer to a location at which to return the number of -* characters read by this call. If the text starts with an escape -* sequence, the returned value will be the number of characters in -* the escape sequence. Otherwise, the returned value will be the -* number of characters prior to the first escape sequence, or the -* length of the supplied text if no escape sequence is found. - -* Returned Value: -* A non-zero value is returned if the supplied text starts with a -* graphics escape sequence, and zero is returned otherwise. - -* Escape Sequences: -* Escape sequences are introduced into the text string by a percent -* "%" character. The following escape sequences are currently recognised -* ("..." represents a string of one or more decimal digits): -* -* %% - Print a literal "%" character. -* -* %^...+ - Draw subsequent characters as super-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the super-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* %^+ - Draw subsequent characters with the normal base-line. -* -* %v...+ - Draw subsequent characters as sub-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the sub-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %v+ - Draw subsequent characters with the normal base-line -* (equivalent to %^+). -* -* %>...+ - Leave a gap before drawing subsequent characters. -* The digits "..." give the size of the gap, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %<...+ - Move backwards before drawing subsequent characters. -* The digits "..." give the size of the movement, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %s...+ - Change the Size attribute for subsequent characters. The -* digits "..." give the new Size as a fraction of the -* "normal" Size, scaled so that a value of "100" corresponds -* to 1.0; -* -* %s+ - Reset the Size attribute to its "normal" value. -* -* %w...+ - Change the Width attribute for subsequent characters. The -* digits "..." give the new width as a fraction of the -* "normal" Width, scaled so that a value of "100" corresponds -* to 1.0; -* -* %w+ - Reset the Size attribute to its "normal" value. -* -* %f...+ - Change the Font attribute for subsequent characters. The -* digits "..." give the new Font value. -* -* %f+ - Reset the Font attribute to its "normal" value. -* -* %c...+ - Change the Colour attribute for subsequent characters. The -* digits "..." give the new Colour value. -* -* %c+ - Reset the Colour attribute to its "normal" value. -* -* %t...+ - Change the Style attribute for subsequent characters. The -* digits "..." give the new Style value. -* -* %t+ - Reset the Style attribute to its "normal" value. -* -* %h+ - Remember the current horizontal position (see "%g+") -* -* %g+ - Go to the horizontal position of the previous "%h+" (if any). -* -* %- - Push the current graphics attribute values onto the top of -* the stack (see "%+"). -* -* %+ - Pop attributes values of the top the stack (see "%-"). If -* the stack is empty, "normal" attribute values are restored. - -* Notes: -* - Zero is returned if an error has already occurred. -*- -*/ - -/* Local Variables: */ - int result; - const char *a; - const char *b; - int nd; - const char *perc; - -/* Initialise */ - result = 0; - *type = GRF__ESPER; - *value = 0; - *nc = 0; - perc = NULL; - -/* Check inherited status and supplied pointer. */ - if( !astOK || !text ) return result; - -/* Loop round, looking for percent signs. Break out of the loop when a - complete escape sequence has been found and read, leaving the "b" pointer - pointing to the first character following the escape sequence. */ - b = NULL; - a = text; - while( ( a = strchr( a, '%' ) ) ) { - perc = a; - -/* Compare the following character to each known escape sequence type. */ - a++; - if( *a == '%') { - *type = GRF__ESPER; - b = a + 1; - break; - - } else if( *a == '^') { - *type = GRF__ESSUP; - - } else if( *a == 'v') { - *type = GRF__ESSUB; - - } else if( *a == '>') { - *type = GRF__ESGAP; - - } else if( *a == '<') { - *type = GRF__ESBAC; - - } else if( *a == 's') { - *type = GRF__ESSIZ; - - } else if( *a == 'w') { - *type = GRF__ESWID; - - } else if( *a == 'f') { - *type = GRF__ESFON; - - } else if( *a == 'c') { - *type = GRF__ESCOL; - - } else if( *a == 'g') { - *type = GRF__ESG; - - } else if( *a == 'h') { - *type = GRF__ESH; - - } else if( *a == 't') { - *type = GRF__ESSTY; - - } else if( *a == '-') { - *type = GRF__ESPSH; - b = a + 1; - break; - - } else if( *a == '+') { - *type = GRF__ESPOP; - b = a + 1; - break; - -/* If the next character is illegal, skip to the next percent sign. */ - } else { - continue; - } - -/* The escape sequence looks legal so far, so move on to the next - character (if any). */ - if( *(++a) ){ - -/* If the next character is a "+" sign, the attribute needs to be reset - to its "normal" value. Indicate this by returning a value of "-1" (all - usable values will be positive). */ - if( *a == '+' ) { - *value = -1; - b = a + 1; - break; - -/* Otherwise, to be a legal escape sequence, this character must be the - first in a sequence of digits, terminated by a "+" sign.*/ - } else if( (nd = 0, astSscanf( a, "%d%n+", value, &nd ))) { - b = a + nd + 1; - break; - } - } - } - -/* Was a usable escape sequence found at the start of the supplied text? - If so, return a function value of 1 and store the number of characters in - the escape sequence. */ - if( b && perc == text ) { - result = 1; - *nc = b - perc; - -/* Otherwise, return the preset function value of zero. If an escape - sequence was found later in the text, return the number of characters - prior to the escape sequence. */ - } else if( b ) { - *nc = perc - text; - -/* Otherwise, if no escape sequence was found, return the length of the - supplied text. */ - } else { - *nc = strlen( text ); - } - -/* Return the result. */ - return result; -} - -static int FindMajTicks( AstMapping *map, AstFrame *frame, int axis, - double refval, double width, double gap, double *cen, int ngood, - double *data, double **tick_data, int *status ){ -/* -* Name: -* FindMajTicks - -* Purpose: -* Place the major tick marks for a physical coordinate axis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FindMajTicks( AstMapping *map, AstFrame *frame, int axis, -* double refval, double width, double gap, double *cen, int ngood, -* double *data, double **tick_data ) - -* Class Membership: -* Plot member function. - -* Description: -* The caller supplies an array of axis values (non-normalized), sorted -* into ascending order (with any bad values at the end), together with -* the gap size for the axis. The array of axis values is assumed to cover -* the entire range which the axis can take within the plotting zone. The -* first tick mark is placed just below the smallest axis value, at a -* position which is an integral number of gaps away from the value -* supplied in "cen" (if a value of AST__BAD is supplied for "cen" then -* "cen = 0.0" is assumed). Notionally, tick marks are then placed at -* intervals given by "gap" all the way upto, and just beyond, the -* largest axis value. However, it could be that large sections of the -* axis are not actually present within the plotting zone. For instance, -* an RA axis covering the two hour range from 23h to 1h (centred on -* 0h), will have some values at zero and some at 23.999.., but there -* will be a large range inbetween these limits which is not represented -* in the plotting area (i.e. the 22h range from 1h to 23h centred on -* 12h). For this reason, tick marks are removed if there are no axis -* values inbetween the tick mark and either of its neighbours. However, -* small "holes" in the axis coverage are allowed, and ticks marks are -* returned covering such small holes. Extra tick marks are also placed -* at each end of the range to guard against the supplied array of axis -* values not entirely covering the range of axis values in the plotting -* area. -* -* For SkyFrames, positions which have latitude values outside the -* normal ranges are ignored. Longitude ranges are not checked to -* avoid problems with CAR projections. -* -* The returned tick mark values are placed into their primary domain -* using the Norm1 method, but are NOT normalised using the astNorm -* method for the supplied Frame. Duplicate tick marks values are -* removed from the returned list. - -* Parameters: -* map -* Mapping from the Plot Base Frame to Plot Current Frame. -* frame -* Pointer to the Frame. -* axis -* Zero-based index of the axis being used. -* refval -* Value to use for the other axis (index [1-axis]) when placing -* the tick mark values into their primary domain. -* width -* Range of used values on the other axis (index [1-axis]). -* gap -* The supplied value for the gaps between ticks on the axis. -* cen -* Pointer to the supplied axis value at which to put a central tick. -* Other ticks will be placed evenly on either side of this tick. If -* AST__BAD is provided, a value will be used which would put a tick -* at an axis value of zero. The used value is returned. -* ngood -* The number of good values in the array pointer to by "data" (i.e. -* values not equal to AST__BAD). -* data -* A pointer to an array holding sorted axis values (non-normalized) -* covering the entire plotting area. -* tick_data -* A pointer to a place at which to store a pointer to an array -* holding the returned tick mark values for the axis. - -* Returned Value: -* The number of major tick mark values stored in the array pointer to -* by "*tick_data". - -* Notes: -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned in "tick_data", and zero -* is returned for the function value. -*/ - -/* Local Variables: */ - double *r; /* Pointer to next tick value to be read */ - double *ticks; /* Pointer to the axis values at the major tick marks */ - double *w; /* Pointer to last tick value to be written */ - double bot; /* Lowest axis value to be displayed */ - double centre; /* The axis value at the first tick mark */ - double delta; /* A safe distance from an axis limit */ - double f; /* The nearest acceptable tick mark index */ - double tmp; /* Temporary storage */ - double top; /* Highest axis value to be displayed */ - int inc; /* This times increase in nticks */ - int k; /* Tick mark index */ - int linc; /* Last times increase in nticks */ - int lnfill; /* Last used value for nfill */ - int nfill; /* No of tick marks to extend by at edges of coverage */ - int nsame; /* Number of equal inc values there have been */ - int nticks; /* Number of major tick marks used */ - int ntnew; /* This times new value of nticks */ - int use_nfill; /* nfill value which started this run of equal inc values */ - -/* Initialise the returned pointer. */ - *tick_data = NULL; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - nsame = 0; - use_nfill = 0; - -/* Decide where to put the first major tick. Use any value supplied by - the caller. Otherwise put it an integral number of gaps away from the - origin. This would result in the origin being at a major tick mark. */ - if( cen && *cen != AST__BAD ) { - centre = *cen; - } else { - centre = astCentre( frame, axis, data[ 0 ], gap ); - if( cen ) *cen = centre; - } - -/* Find the number of candidate tick marks assuming an nfill value of 0. */ - nfill = 0; - nticks = FindMajTicks2( nfill, gap, centre, ngood, data, &ticks, status ); - -/* Loop round increasing the nfill value until an unreasonably large value - of nfill is reached. The loop will exit early via a break statement when - all small holes in the axis coverage are filled in. */ - lnfill = nfill; - linc = -100000; - while( nfill < 100 && astOK ){ - -/* Increment the number of ticks added as "padding" at the edges of any - gaps in the coverage of axis values. */ - nfill++; - -/* Form a new set of tick mark values using this new nfill value */ - ticks = (double *) astFree( (void *) ticks ); - ntnew = FindMajTicks2( nfill, gap, centre, ngood, data, &ticks, status ); - -/* We need to know if the rate of increase of nticks has settled down to - a constant value. Inititially increasing nfill will cause the total - number of ticks (nticks) to increase rapidly. But this rate of - increase will get less as any small gaps in axis coverage are filled in. - We break out of the while loop when the rate of increase has settled - down to a constant value (indicating that only very large holes are left - in the axis coverage). Find the increase in the number of ticks caused by - the increase in the nfill value made in this loop. If this increase is the - same as the increase caused by the previous loop, increment the number of - equal increases there have been. If the increase is different to last time, - reset the number of equal increases to zero. */ - inc = ntnew - nticks; - if( inc == linc ) { - nsame++; - } else { - nsame = 0; - use_nfill = nfill; - } - -/* If the past 3 increases in nfill has not caused any change in the rate - of increase of nticks, then re-create the ticks for the value of nfill - which started the current run of equal increment values, and leave the - loop. */ - if( nsame == 3 ) { - ticks = (double *) astFree( (void *) ticks ); - nticks = FindMajTicks2( use_nfill, gap, centre, ngood, data, &ticks, status ); - break; - } - -/* Save this times values for use in the next loop. */ - linc = inc; - nticks = ntnew; - } - -/* Remove ticks which are not within the axis ranges to be displayed. - Ticks which are very close to the limit are moved to a safe (but - visually negligable) distance away from the limit). */ - bot = astGetBottom( frame, axis ); - top = astGetTop( frame, axis ); - if( bot > top ) { - tmp = top; - top = bot; - bot = tmp; - } - delta = 0.05*gap; - r = ticks; - for( k = 0; k < nticks; k++ ){ - if( *r != AST__BAD ) { - if( fabs( *r - bot ) < delta ) { - *r = bot + delta; - } else if( fabs( *r - top ) < delta ) { - *r = top - delta; - } else if( *r < bot || *r > top ) { - *r = AST__BAD; - } - } - r++; - } - -/* Use the Mapping to place each tick mark value in its primary domain. - This is a sort of normalization, similar but different to that performed - by the astNorm method. */ - Norm1( map, axis, nticks, ticks, refval, width, status ); - -/* Check for success. */ - if( astOK ){ - -/* Ensure that all ticks marks are offset from the "centre" value by an - integer multiple of the gap size. This is done by changing each tick - value to the closest acceptable value. Also ensure that values close to - zero (i.e. less than 1E-10 of the gap size) are set exactly to zero. */ - r = ticks; - for( k = 0; k < nticks; k++ ){ - if( *r != AST__BAD ) { - f = floor( 0.5 + ( *r - centre )/gap ); - *r = f*gap + centre; - if( fabs( *r ) < 1.0E-10*gap ) *r = 0.0; - r++; - } else { - r++; - } - } - -/* Sort the tick values into increasing order. */ - qsort( (void *) ticks, (size_t) nticks, sizeof(double), Compared ); - -/* Remove any duplicate or BAD tick values by shuffling the higher unique - values down to over-write them. We subtract the centre value of both - tick values before comparing them for equality in order to avoid - unnecessarily removing tick marks in high precsion data. */ - r = ticks + 1; - w = ticks; - for( k = 1; k < nticks && astOK; k++ ){ - if( *r != AST__BAD && !astEQUALS( *r-centre, *w-centre, 1.0E8 ) ){ - w++; - *w = *r; - } - r++; - } - -/* Modify the number of ticks to exclude the duplicate ones. */ - nticks = (int) ( w - ticks ) + 1; - - } - -/* If an error has occurred, free the memory holding the major tick mark - values, and indicate that zero tick marks have been found. */ - if( !astOK ){ - ticks = (double *) astFree( (void *) ticks ); - nticks = 0; - } - -/* Store the pointer to the major tick mark values. */ - *tick_data = ticks; - -/* Return the number of major ticks. */ - return nticks; - -} -static int FindMajTicks2( int nfill, double gap, double centre, int ngood, - double *data, double **tick_data, int *status ){ -/* -* Name: -* FindMajTicks2 - -* Purpose: -* Find candidate major tick marks for FindMajTicks. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FindMajTicks2( int nfill, double gap, double centre, int ngood, -* double *data, double **tick_data, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* A service routine for function FindMajTicks. - -* Parameters: -* nfill -* Number of tick marks to extend by at edges of coverage -* gap -* The supplied value for the gaps between ticks on the axis. -* centre -* The supplied axis value at which to put a central tick. -* ngood -* The number of good values in the array pointer to by "data" (i.e. -* values not equal to AST__BAD). -* data -* A pointer to an array holding sorted axis values covering the -* entire plotting area. -* tick_data -* A pointer to a place at which to store a pointer to an array -* holding the returned tick mark values for the axis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of major tick mark values stored in the array pointer to -* by "*tick_data". - -* Notes: -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned in "tick_data", and zero -* is returned for the function value. -*/ - -/* Local Variables: */ - double *ticks; /* Pointer to the axis values at the major tick marks */ - int i; /* Index of current axis value */ - int j; /* Index of filled in tick */ - int k; /* Tick mark index */ - int klast; /* Index of the previous tick mark */ - int nticks; /* Number of major tick marks used */ - -/* Initialise the returned pointer. */ - *tick_data = NULL; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - nticks = 0; - -/* Reserve memory to hold a reasonable number of tick mark axis values. - This memory is later extended as necessary. */ - ticks = (double *) astMalloc( sizeof(double)*( 6*nfill + 14 ) ); - -/* Check that the pointer can be used. */ - if( astOK ){ - -/* Put the first tick marks just below the lowest axis value (in case - the grid did not sample the entire range of the axis). */ - k = floor( ( data[ 0 ] - centre )/gap ); - - for ( i = 0; i < nfill; i++ ){ - ticks[ i ] = gap*(double)( k - nfill + i ) + centre; - } - ticks[ nfill ] = gap*(double)( k ) + centre; - -/* Initialise the number of major tick marks found so far. */ - nticks = nfill + 1; - -/* Loop round each of the remaining good ordered axis values. */ - klast = k; - for( i = 1; i < ngood && astOK; i++ ) { - -/* Find the tick marks enclosing the axis value. The tick mark placed at - "centre" is called tick mark zero, and tick marks are indexed (positive - or negative) from an origin at "centre". Find the index of the more - negative of the two tick marks enclosing the axis value. */ - k = floor( ( data[ i ] - centre )/gap ); - -/* Ensure that the tick marks enclosing the current axis value are used. - Some extra tick marks are used at the start and end of any gaps in - the axis coverage. This is done to "fill in" small holes caused by the - grid of physical coordinate values not completely covering the - plotting area. Large holes, such as occur on an RA axis covering the 2 - hour range from 23 hours to 1 hour are left without any tick marks in - them (the "hole" in this case is the 22 hours range from 1 hour to 23 - hours). */ - for( j = 0; j < nfill + 1; j++ ){ - if( k - klast > nfill + 2 - j ) { - ticks = (double *) astGrow( ticks, nticks + 1, sizeof( double ) ); - if( astOK ) ticks[ nticks++ ] = - gap*(double)( klast + nfill + 1 - j ) + centre; - } - if( k - klast > nfill - j ) { - ticks = (double *) astGrow( ticks, nticks + 1, sizeof( double ) ); - if( astOK ) ticks[ nticks++ ] = - gap*(double)( k - nfill + j ) + centre; - } - } - -/* Save the index of the current tick mark. */ - klast = k; - - } - -/* Add extra tick marks beyond the end in case the grid did not sample - the entire range of the axis. */ - ticks = (double *) astGrow( ticks, nticks + nfill + 1, sizeof( double ) ); - for( i = 0; i < nfill && astOK; i++ ){ - ticks[ nticks++ ] = gap*(double)( klast + i + 1 ) + centre; - } - - } - -/* If an error has occurred, free the memory holding the major tick mark - values, and indicate that zero tick marks have been found. */ - if( !astOK ){ - ticks = (double *) astFree( (void *) ticks ); - nticks = 0; - } - -/* Store the pointer to the major tick mark values. */ - *tick_data = ticks; - -/* Return the number of major ticks. */ - return nticks; - -} - -static int FindDPTZ( AstFrame *fr, int axis, const char *fmt, - const char *text, int *ndp, int *ntz, int *status ) { -/* -* Name: -* FindDPTZ - -* Purpose: -* Find the number of decimal places and trailing zeros in a label. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FindDPTZ( AstFrame *fr, int axis, const char *fmt, -* const char *text, int *ndp, int *ntz, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied label is split into fields using the astFields method of -* the supplied frame. The number of decimal places in the last -* field is returned in *ndp, and the total number of trailing zeros -* (excluding exponents) is returned in *ntz. - -* Parameters: -* fr -* The frame. -* axis -* The axis index to which the label applies. -* fmt -* The format string used to format the label. -* text -* The text of the label. -* ndp -* Pointer to an int in which to return the number of decimal -* places in the final field. -* ntz -* Pointer to an int in which to return the number of trailing zeros. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if and only if a non-zero digit is found in any field. - -*/ - -/* Local Constants: */ -#define MAXFLD 10 - -/* Local Variables: */ - char *fields[ MAXFLD ]; - const char *a; - const char *dot; - const char *ff; - double junk; - int fnc; - int i; - int j; - int l; - int mxnd; - int nc[ MAXFLD ]; - int nf; - int result; - -/* Initialise */ - *ndp = 0; - *ntz = 0; - result = 0; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Split the label up into fields. */ - nf = astFields( fr, axis, fmt, text, MAXFLD, fields, nc, &junk ); - if( nf > 0 ) { - -/* Search the last fields (assumed to be the least significant) for a - decimal point. */ - ff = fields[ nf - 1 ]; - fnc = nc[ nf - 1 ]; - dot = strchr( ff, '.' ); - if( dot && ( ff - dot >= fnc ) ) dot = NULL; - -/* Find the number of digits following the decimal point. */ - if( dot ) { - *ndp = strspn( dot + 1, "0123456789" ); - mxnd = fnc - ( dot - ff ) - 1; - if( *ndp > mxnd ) *ndp = mxnd; - } else { - *ndp = 0; - } - -/* Loop through all the fields, from least significant to most significant, - counting the number of trailing zeros. */ - *ntz = 0; - for( i = nf - 1; i >= 0; i-- ) { - l = strspn( fields[ i ], "-+0123456789." ); - if( l > nc[ i ] ) l = nc[ i ]; - a = fields[ i ] + l - 1; - for( j = l - 1; j >= 0; j--,a-- ){ - if( *a == '0' ) { - (*ntz)++; - } else if( isdigit( *a ) ) { - result = 1; - break; - } - } - if( j >= 0 ) break; - } - } - -/* Return the result. */ - return result; - -/* Undefine local constants: */ -#undef MAXFLD - -} - -static int FindString( int n, const char *list[], const char *test, - const char *text, const char *method, - const char *class, int *status ){ -/* -* Name: -* FindString - -* Purpose: -* Find a given string within an array of character strings. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FindString( int n, const char *list[], const char *test, -* const char *text, const char *method, const char *class, -* int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function identifies a supplied string within a supplied -* array of valid strings, and returns the index of the string within -* the array. The test option may not be abbreviated, but case is -* insignificant. - -* Parameters: -* n -* The number of strings in the array pointed to be "list". -* list -* A pointer to an array of legal character strings. -* test -* A candidate string. -* text -* A string giving a description of the object, parameter, -* attribute, etc, to which the test value refers. -* This is only for use in constructing error messages. It should -* start with a lower case letter. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The index of the identified string within the supplied array, starting -* at zero. - -* Notes: -* - A value of -1 is returned if an error has already occurred, or -* if this function should fail for any reason (for instance if the -* supplied option is not specified in the supplied list). - -*/ - -/* Local Variables: */ - int ret; /* The returned index */ - -/* Check global status. */ - if( !astOK ) return -1; - -/* Compare the test string with each element of the supplied list. Leave - the loop when a match is found. */ - for( ret = 0; ret < n; ret++ ) { - if( !Ustrcmp( test, list[ ret ], status ) ) break; - } - -/* Report an error if the supplied test string does not match any element - in the supplied list. */ - if( ret >= n ) { - astError( AST__OPT, "%s(%s): Illegal value '%s' supplied for %s.", status, - method, class, test, text ); - ret = -1; - } - -/* Return the answer. */ - return ret; -} - -static char *FindWord( char *ptr, const char *d, const char **p, int *status ) { -/* -* Name: -* FindWord - -* Purpose: -* Return a copy of the next word in a supplied string. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* char *FindWord( char *ptr, const char *d, const char **p, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function locates the start and end of the first word in the -* string pointed to by *p, and returns a copy of the word. The pointer -* *p is modified to point to the start of the following word (if any). -* The characters which delimit words are supplied in string "d". - -* Parameters: -* ptr -* A pointer to a character string in which to store the returned -* word. The memory holding this string should have been allocated -* using one of the functions in the AST "memory" module. The memory -* area will be modified in size to fit the returned word. A NULL -* pointer may be supplied if no memory has yet been allocated. -* Any memory pointed to by ptr is freed if a NULL pointer is -* returned by this function (i.e. if no word is found). -* d -* A string holding the characters which are to be used as word -* delimiters. -* p -* The address of a character string pointer. On entry, this pointer -* identifies the start of the string to be searched. On exit, it is -* modified to point to the start of the following word. It is -* returned NULL if there are no more words. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated character string holding the -* next word, or NULL if no word could be found. - -*/ - -/* Local Variables: */ - const char *a, *b, *c; - char *ret; - int nc; - -/* Free any allocated memory and return if any of the supplied pointers - (except ptr) is NULL, or if an error has occurred. */ - if( !astOK || !d || !p || !*p ) { - (void) astFree( (void *) ptr ); - return NULL; - } - -/* Get a pointer to the first character which is not in "d". Terminate - the loop if a null character is encountered. */ - a = *p; - while( *a && strchr( d, (int) *a ) ) a++; - -/* Get a pointer to the next character which is in "d". Terminate - the loop if a null character is encountered. */ - b = a; - while( *b && !strchr( d, (int) *b ) ) b++; - -/* Get a pointer to the next character which is not in "d". Terminate - the loop if a null character is encountered. */ - c = b; - while( *c && strchr( d, (int) *c ) ) c++; - -/* Adjust the supplied pointer so that it points to the start of the next - word. */ - if( *c ){ - *p = c; - } else { - *p = NULL; - } - -/* Get a null-terminated copy of the word between a and b. */ - nc = b - a; - if( nc > 0 ) { - ret = (char *) astStore( (void *) ptr, (void *) a, (size_t) (nc + 1) ); - ret[ nc ] = 0; - } else { - ret = astFree( (void *) ptr ); - } - - return ret; -} - -static const char *SplitValue( AstPlot *this, const char *value, int axis, - int *split, int *status ) { -/* -* Name: -* FormatValue - -* Purpose: -* Format a coordinate value for a Frame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* const char *SplitValue( AstPlot *this, const char *value, -* int axis, int *split ) - -* Class Membership: -* Plot member function - -* Description: -* This function splits long formatted values (such as the date/time -* format produced by the TimeFrame class) if possible onto two lines -* by inclusion of Plot escape sequences. - -* Parameters: -* this -* Pointer to the Plot. -* value -* The formatted coordinate value. -* axis -* Indicates whether or not short lines should be split by -* including a blank first line. If zero, and if "*split" is non-zero, -* then short lines are put onto the second line,and the first line -* is blank. -* split -* Pointer to an integer that controls behaviour: -* -* 0 - Split the line if it is too long, and return a value of +1 -* in *split. -* 1 - Split the line even if it does not need splitting, making -* the first line blank and the second line containing all the -* supplied text (*split is unchanged on exit). - -* Returned Value: -* A pointer to a static buffer containing a null-terminated string -* holding the (possibly split) formatted value. This will be a copy of -* the supplied pointer if the string does not need to be split. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - char *d; - const char *result; - float rsp; - int aft_end; - int aft_start; - int bef_end; - int bef_start; - int i; - int id; - int idmin; - int imin; - int l; - int naft; - int nbef; - int nlong; - int nshort; - int nsp; - -/* Initialise */ - result = value; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Do nothing more if the formatted value already contains graphical - escape sequences, or if graphical escapes sequences are not being - interpreted. */ - if( value && astGetEscape( this ) && !HasEscapes( value, status ) ) { - -/* Attempt to find a space close to the centre of the formatted string. */ - l = strlen( value ); - idmin = 2*l; - imin = -1; - for( i = 0; i < l; i++ ) { - if( isspace( value[ i ] ) ) { - id = abs( i - l/2 ); - if( id < idmin ) { - idmin = id; - imin = i; - } - } - } - -/* We split the line if previous lines have been split (i.e. if *split was - non-zero on entry) or if this line is long AND it contains a space. This - means that a sequence of long labels will not be split unless they contain - spaces. */ - if( *split || ( l > 9 && imin != -1 ) ) { - *split = 1; - -/* Initialse the pointer into the returned buffer at which the next - character will be placed. */ - d = splitvalue_buff; - -/* If no spaces were found... */ - if( imin == -1 ) { - -/* If axis is zero, we add a blank first line. */ - if( axis == 0 ) { - -/* Fill the first line with spaces. */ - for( i = 0; i < l; i++ ) *(d++) = ' '; - -/* Add an escape sequence that moves down by one character height. */ - d += sprintf( d, "%%v170+" ); - } - -/* Add the whole of the supplied text. */ - for( i = 0; i < l; i++ ) *(d++) = value[ i ]; - -/* If a space was found... */ - } else { - -/* Find the first and last non-blank characters before the mid-space. */ - bef_start = -1; - bef_end = -1; - for( i = 0; i < imin; i++ ) { - if( !isspace( value[ i ] ) ) { - if( bef_start == -1 ) bef_start = i; - bef_end = i; - } - } - -/* Find the first and last non-blank characters after the mid-space. */ - aft_start = -1; - aft_end = -1; - for( i = imin + 1; i < l; i++ ) { - if( !isspace( value[ i ] ) ) { - if( aft_start == -1 ) aft_start = i; - aft_end = i; - } - } - -/* How many significant characters before and after the space? */ - nbef = bef_end - bef_start + 1; - naft = aft_end - aft_start + 1; - -/* Get the lengths of the longer and shorter line. */ - if( nbef > naft ) { - nlong = nbef; - nshort = naft; - } else { - nlong = naft; - nshort = nbef; - } - -/* Find the fractional number of spaces before the significant text of the - shorter line.*/ - rsp = 0.5*( nlong - nshort + 1 ); - -/* If the top line is the shorter line, put some spaces in at the start. */ - if( nbef < naft ) { - nsp = (int) rsp; - for( i = 0; i < nsp; i++ ) *(d++) = ' '; - } - -/* Add the significant text from the top line. */ - for( i = bef_start; i <= bef_end; i++ ) *(d++) = value[ i ]; - -/* Add an escape sequence that moves down by one character height. */ - d += sprintf( d, "%%v100+" ); - - -/* Add an escape sequence that moves to the left by the required amount. */ - d += sprintf( d, "%%<%d+", (int) ( 60.0*( (float) nlong - rsp )) ); - -/* Add the significant text from the bottom line. */ - for( i = aft_start; i <= aft_end; i++ ) *(d++) = value[ i ]; - - } - -/* Terminate it. */ - *d = 0; - -/* Return a pointer to the buffer. */ - result = splitvalue_buff; - } - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static void Fpoly( AstPlot *this, const char *method, const char *class, - int *status ){ -/* -* Name: -* Fpoly - -* Purpose: -* Flush all stored poly lines to the graphics system. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Fpoly( AstPlot *this, const char *method, const char *class, -* int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function sends all previously drawn poly lines to the graphics -* system for rendering, and frees the memory used to hold the poly -* lines. It attempts to reduce the number of graphics calls by -* concatenating continuous polylines together. - -* Parameters: -* this -* Pointer to the Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - float xmid; - float xt; - float ymid; - float *xnew; - float *ynew; - int polylen; - float *xp1; - float *xp2; - float *yp1; - float *yp2; - float yt; - int *ekey; - int *p; - int *skey; - int *drawn; - int ihi; - int ikey; - int ilo; - int imid; - int ipass; - int ipoint; - int ipoly; - int jpoly; - int kpoly; - int *polylist; - int npoly; - int np; - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Output any pending polyline. */ - Opoly( this, status ); - -/* If there is just one polyline to output, just draw it and then free - the memory used to hold the polyline. */ - if( Poly_npoly == 1 ) { - GLine( this, Poly_np[ 0 ], Poly_xp[ 0 ], Poly_yp[ 0 ], method, class, - status ); - Poly_xp[ 0 ] = astFree( Poly_xp[ 0 ] ); - Poly_yp[ 0 ] = astFree( Poly_yp[ 0 ] ); - Poly_np[ 0 ] = 0; - -/* If there are multiple polylines to output, see if any of them can be - combined before drawing them. */ - } else if( Poly_npoly > 1 ) { - -/* No polyline buffer allocated yet. */ - xnew = NULL; - ynew = NULL; - -/* Allocate an array to hold the order in which polylines should be - concatenated. Each value in this array will be the index of one of the - original polylines. A positive index indicates that the polyline - should be appended in its original order. A negative index indicates - that the polyline should be appended in reversed order. Polyline zero - is always appended in its original order. */ - polylist = astMalloc( Poly_npoly*sizeof( int ) ); - npoly = 0; - -/* Create an array of drawn, one for each individual polyline. The flag - is zero if the corresponding polyline has not yet been drawn. */ - drawn = astCalloc( Poly_npoly, sizeof( int ) ); - -/* Create two sorted keys for the polylines - one that sorts them into - increasing x at the start of the polyline, and another that sorts them - into increasing x at the end of the polyline. */ - skey = astMalloc( Poly_npoly*sizeof( int ) ); - ekey = astMalloc( Poly_npoly*sizeof( int ) ); - if( astOK ) { - - p = skey; - for( ipoly = 0; ipoly < Poly_npoly; ipoly++ ) *(p++) = ipoly; - qsort( skey, Poly_npoly, sizeof(int), Fpoly_scmp ); - - p = ekey; - for( ipoly = 0; ipoly < Poly_npoly; ipoly++ ) *(p++) = ipoly; - qsort( ekey, Poly_npoly, sizeof(int), Fpoly_ecmp ); - - } - -/* Continue to search for separate polylines that can be combined together - until we know there are no more. */ - while( astOK ) { - -/* Search for the first polyline that has not already been drawn. */ - for( ipoly = 0; ipoly < Poly_npoly; ipoly++ ) { - if( !drawn[ ipoly ] ) break; - } - -/* Leave the loop if no more polylines remain to be plotted. */ - if( ipoly == Poly_npoly ) break; - -/* Initialise the list of polylines to hold the polyline found above, in - its forward sense. */ - polylist[ 0 ] = ipoly; - npoly = 1; - drawn[ 0 ] = 1; - -/* Initialise the concatenation point to be the end of the polyline found - above. Also, initialise the total number of points in the combined - polyline (polylen). */ - ipoint = Poly_np[ ipoly ] - 1; - xt = Poly_xp[ ipoly ][ ipoint ]; - yt = Poly_yp[ ipoly ][ ipoint ]; - polylen = ipoint + 1; - -/* Loop until we can find no more polylines to append to the list. - A polyline can be appended if it starts or ends at the current - concatenation point. */ - while( astOK ) { - -/* On the first pass through the next loop, search for a polyline that - starts at the concatenation point. If no such polyline is found, do - a second pass in which we search for a polyline that ends at the - concatenation point. Do not include any previously drawn polylines - in the search. */ - for( ipass = 0; ipass < 2; ipass++ ) { - -/* We use a binary chop to find a polyline which starts (or ends) at the - x value of the concatenation point. */ - jpoly = -1; - ilo = 0; - ihi = Poly_npoly - 1; - while( 1 ) { - imid = ( ilo + ihi )/2; - if( ipass == 0 ) { - jpoly = skey[ imid ]; - xmid = Poly_xp[ jpoly ][ 0 ]; - } else { - jpoly = ekey[ imid ]; - xmid = Poly_xp[ jpoly ][ Poly_np[ jpoly ] - 1 ]; - } - if( astEQUALS( xmid, xt, 1.0E8 ) ) { - ikey = imid; - break; - } else if( xmid > xt ) { - if( ihi == imid ) { - if( ipass == 0 ) { - jpoly = skey[ ilo ]; - xmid = Poly_xp[ jpoly ][ 0 ]; - } else { - jpoly = ekey[ ilo ]; - xmid = Poly_xp[ jpoly ][ Poly_np[ jpoly ] - 1 ]; - } - if( !astEQUALS( xmid, xt, 1.0E8 ) ) jpoly = -1; - ikey = ilo; - break; - } - ihi = imid; - } else { - if( ilo == imid ) { - if( ipass == 0 ) { - jpoly = skey[ ihi ]; - xmid = Poly_xp[ jpoly ][ 0 ]; - } else { - jpoly = ekey[ ihi ]; - xmid = Poly_xp[ jpoly ][ Poly_np[ jpoly ] - 1 ]; - } - if( !astEQUALS( xmid, xt, 1.0E8 ) ) jpoly = -1; - ikey = ihi; - break; - } - ilo = imid; - } - } - -/* If found, there may be more than one such polyline. So we now search - for a polyline that also has the y value of the concatenation point. */ - if( jpoly != -1 ) { - -/* If the polyline found above starts (or ends) at the same Y value as the - concatenation point, then we have found the required polyline. */ - if( ipass == 0 ) { - ymid = Poly_yp[ jpoly ][ 0 ]; - } else { - ymid = Poly_yp[ jpoly ][ Poly_np[ jpoly ] - 1 ]; - } - if( astEQUALS( ymid, yt, 1.0E8 ) && !drawn[ jpoly ] ) break; - jpoly = -1; - -/* Otherwise, search down the list, starting at the polyline found above. */ - if( imid > 0 ) { - for( ikey = imid - 1; ikey >= 0; ikey-- ) { - if( ipass == 0 ) { - kpoly = skey[ ikey ]; - xmid = Poly_xp[ kpoly ][ 0 ]; - ymid = Poly_yp[ kpoly ][ 0 ]; - } else { - kpoly = ekey[ ikey ]; - xmid = Poly_xp[ kpoly ][ Poly_np[ kpoly ] - 1 ]; - ymid = Poly_yp[ kpoly ][ Poly_np[ kpoly ] - 1 ]; - } - if( astEQUALS( xmid, xt, 1.0E8 ) ) { - if( astEQUALS( ymid, yt, 1.0E8 ) && !drawn[ kpoly ] ) { - jpoly = kpoly; - break; - } - } else { - break; - } - } - if( jpoly != -1 ) break; - } - -/* Now search up the list, starting at the polyline found above. */ - if( imid < Poly_npoly - 1 ) { - for( ikey = imid + 1; ikey < Poly_npoly; ikey++ ) { - if( ipass == 0 ) { - kpoly = skey[ ikey ]; - xmid = Poly_xp[ kpoly ][ 0 ]; - ymid = Poly_yp[ kpoly ][ 0 ]; - } else { - kpoly = ekey[ ikey ]; - xmid = Poly_xp[ kpoly ][ Poly_np[ kpoly ] - 1 ]; - ymid = Poly_yp[ kpoly ][ Poly_np[ kpoly ] - 1 ]; - } - if( astEQUALS( xmid, xt, 1.0E8 ) ) { - if( astEQUALS( ymid, yt, 1.0E8 ) && !drawn[ kpoly ] ) { - jpoly = kpoly; - break; - } - } else { - break; - } - } - if( jpoly != -1 ) break; - } - } - } - -/* If a polyline was found that can be combined with the total polyline, - increment the total number of points in the total polyline, add it to - the list, and update the concatenation point. Note, we can omit the - start or end point of the new polyline since it will already be - present in the total polyline, hence the " - 1 " below. */ - if( ipass < 2 ) { - ipoint = Poly_np[ jpoly ] - 1; - - if( ipass == 0 ) { - polylist[ npoly++ ] = jpoly; - xt = Poly_xp[ jpoly ][ ipoint ]; - yt = Poly_yp[ jpoly ][ ipoint ]; - } else { - polylist[ npoly++ ] = -jpoly; - xt = Poly_xp[ jpoly ][ 0 ]; - yt = Poly_yp[ jpoly ][ 0 ]; - } - - polylen += ipoint; - -/* Indicate the polyline has been drawn. */ - drawn[ jpoly ] = 1; - -/* If we cannot find any polyline that starts or ends at the - concatenation point, then we have completed the total polyline. So break - out of the loop, and move on to draw the total polyline. */ - } else { - break; - } - } - -/* If a single polyline is to be drawn, just draw it. */ - if( npoly == 1 ) { - jpoly = polylist[ 0 ]; - GLine( this, Poly_np[ jpoly ], Poly_xp[ jpoly ], - Poly_yp[ jpoly ], method, class, status ); - -/* If more than one polyline is to be drawn, ensure we have arrays that - are large enough to hold all the vertices in the combined polyline. */ - } else { - xnew = astRealloc( xnew, polylen*sizeof( float ) ); - ynew = astRealloc( ynew, polylen*sizeof( float ) ); - if( astOK ) { - -/* Loop round all the polylines that are to be combined to form the total - polyline, and copy all the vertex coordinates into the above arrays. */ - xp1 = xnew; - yp1 = ynew; - for( ipoly = 0; ipoly < npoly; ipoly++ ) { - -/* Index of the next polyline to include in the total polyline. */ - jpoly = polylist[ ipoly ]; - -/* The jpoly value is positive if the polylline is to be inclued in its - original direction. */ - if( jpoly >= 0 ) { - -/* Use the whole of the first polyline. */ - if( ipoly == 0 ) { - np = Poly_np[ jpoly ]; - xp2 = Poly_xp[ jpoly ]; - yp2 = Poly_yp[ jpoly ]; - -/* Omit eh first point of subsequent polylines since it will be the same - as the last pointy already in the total polyline. */ - } else { - np = Poly_np[ jpoly ] - 1; - xp2 = Poly_xp[ jpoly ] + 1; - yp2 = Poly_yp[ jpoly ] + 1; - } - -/* Copy the vertex values in their original order, and update the - pointers to the next element of the total polyline. */ - memcpy( xp1, xp2, np*sizeof(float) ); - memcpy( yp1, yp2, np*sizeof(float) ); - xp1 += np; - yp1 += np; - -/* The jpoly value is negative if the polyline is to be included in its - reversed direction. */ - } else { - jpoly = -jpoly; - -/* Get the number of points to copy. Omit the last point if this is not - the first polyline, since it is already in the total polyline. */ - if( ipoly == 0 ) { - np = Poly_np[ jpoly ]; - } else { - np = Poly_np[ jpoly ] - 1; - } - -/* Copy the individual values in reversed order. */ - xp2 = Poly_xp[ jpoly ] + np - 1; - yp2 = Poly_yp[ jpoly ] + np - 1; - for( ipoint = 0; ipoint < np; ipoint++ ) { - *(xp1++) = *(xp2--); - *(yp1++) = *(yp2--); - } - } - } - -/* And finally, draw the total polyline. */ - GLine( this, polylen, xnew, ynew, method, class, status ); - } - } - } - -/* Free all the individual polylines. */ - for( ipoly = 0; ipoly < Poly_npoly; ipoly++ ) { - Poly_xp[ ipoly ] = astFree( Poly_xp[ ipoly ] ); - Poly_yp[ ipoly ] = astFree( Poly_yp[ ipoly ] ); - Poly_np[ ipoly ] = 0; - } - -/* Free other resources. */ - polylist = astFree( polylist ); - drawn = astFree( drawn ); - xnew = astFree( xnew ); - ynew = astFree( ynew ); - skey = astFree( skey ); - ekey = astFree( ekey ); - } - -/* Indicate that all polylines have been sent to the graphics system. */ - Poly_npoly = 0; -} - -static int Fpoly_ecmp( const void *a, const void *b ){ -/* -* Name: -* Fpoly_ecmp - -* Purpose: -* Compare two polylines ending X position - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Fpoly_ecmp( const void *a, const void *b ) - -* Class Membership: -* Plot member function. - -* Description: -* This function is designed to be used as a comparison function with -* the "qsort" function. It is used in function Fpoly. -* -* If orders the two polylines on the basis of the X coordinate at -* their ends. - -* Parameters: -* a -* Pointer to an int holding the index of the first polyline. -* b -* Pointer to an int holding the index of the second polyline. - -* Returned Value: -* -1 if the first polyline ends at a lower X than the second. -* +1 if the first polyline ends at a higher X than the second. -* 0 if the two polylines end at the same X. - -*/ - -/* Local Variables: */ - float xa; /* X at end of first polyline */ - float xb; /* X at end of second polyline */ - int result = 0; /* Returned value */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get the x coord at the end of the two polylines. */ - xa = Poly_xp[ *( (int *) a) ][ Poly_np[ *( (int *) a) ] - 1 ]; - xb = Poly_xp[ *( (int *) b) ][ Poly_np[ *( (int *) b) ] - 1 ]; - -/* Compare them. */ - if( xa < xb ) { - result = -1; - } else if( xa > xb ){ - result = 1; - } - - return result; -} - -static int Fpoly_scmp( const void *a, const void *b ){ -/* -* Name: -* Fpoly_scmp - -* Purpose: -* Compare two polylines starting X position - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Fpoly_scmp( const void *a, const void *b ) - -* Class Membership: -* Plot member function. - -* Description: -* This function is designed to be used as a comparison function with -* the "qsort" function. It is used in function Fpoly. -* -* If orders the two polylines on the basis of the X coordinate at -* their starts. - -* Parameters: -* a -* Pointer to an int holding the index of the first polyline. -* b -* Pointer to an int holding the index of the second polyline. - -* Returned Value: -* -1 if the first polyline starts at a lower X than the second. -* +1 if the first polyline starts at a higher X than the second. -* 0 if the two polylines starts at the same X. - -*/ - -/* Local Variables: */ - float xa; /* X at start of first polyline */ - float xb; /* X at start of second polyline */ - int result = 0; /* Returned value */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get the x coord at the start of the two polylines. */ - xa = Poly_xp[ *( (int *) a) ][ 0 ]; - xb = Poly_xp[ *( (int *) b) ][ 0 ]; - -/* Compare them. */ - if( xa < xb ) { - result = -1; - } else if( xa > xb ){ - result = 1; - } - - return result; -} - -static AstFrameSet *Fset2D( AstFrameSet *fset, int ifrm, int *status ) { -/* -* Name: -* Fset2D - -* Purpose: -* Create a FrameSet with no more than 2 dimensions for a given Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstFrameSet *Fset2D( AstFrameSet *fset, int ifrm, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function checks a specified Frame in the supplied FrameSet. -* If the Frame has more than 2 dimensions, a new Frame is added to -* the FrameSet containing just the first two axes of the specified -* Frame. A PermMap is used to connect this Frame to the specified -* Frame, which supplied bad values for any missing axes. If the -* specified Frame is the base Frame in the supplied FrameSet, then the -* new Frame becomes the base Frame in the returned FrameSet. Like-wise, -* if the specified Frame is the current Frame, then the new Frame -* will be the current Frame in the returned FrameSet. -* -* If the specified Frame does not have more than 2 axes, then a clone -* of the FrameSet pointer is returned, otherwise the returned pointer -* points to a copy of the supplied FrameSet with the new 2-D Frame -* added. - -* Parameters: -* fset -* Pointer to the FrameSet. -* ifrm -* The index of the Frame to check. This should be AST__BASE or -* AST_CURRENT. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a FrameSet in which the Frame with index given by ifrm -* has no more than 2 axes. -*/ - -/* Local Variables: */ - AstFrame *frm; - AstFrame *newfrm; - AstFrameSet *ret; - AstPermMap *map; - double zero; - int *inperm; - int axes[2]; - int i; - int ic; - int nax; - -/* Check the inherited status. */ - if( !astOK ) return NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - map = NULL; - -/* Get a pointer to the requested Frame in the supplied FrameSet. */ - frm = astGetFrame( fset, ifrm ); - -/* See how many dimensions the specified Frame of the supplied FrameSet - has. */ - nax = astGetNaxes( frm ); - -/* If it is more than 2-dimensionbal, create a 2D Frame by picking - axes 1 and 2 from the original Frame. */ - if( nax > 2 ) { - axes[ 0 ] = 0; - axes[ 1 ] = 1; - newfrm = astPickAxes( frm, 2, axes, NULL ); - -/* Create a PermMap to describe the mapping between the two Frames. - Use zero as the value for unknown axes (the optional mapping which - can be returned by astPickAxes uses AST__BAD for unknown axes). */ - inperm = (int *) astMalloc( sizeof(int)*(size_t) nax ); - if( astOK ){ - inperm[ 0 ] = 0; - inperm[ 1 ] = 1; - for( i = 2; i < nax; i++ ) inperm[ i ] = -1; - zero = 0.0; - map = astPermMap( nax, inperm, 2, axes, &zero, "", status ); - inperm = (int *) astFree( (void *) inperm ); - } - -/* Get a copy of the supplied FrameSet. */ - ret = astCopy( fset ); - -/* Add the new Frame to the FrameSet (it becomes the current Frame). */ - ic = astGetCurrent( ret ); - astAddFrame( ret, ifrm, map, newfrm ); - newfrm = astAnnul( newfrm ); - -/* If the new Frame was derived from the base frame, set the new base - Frame, and re-instate the original current Frame */ - if( ifrm == AST__BASE ){ - astSetBase( ret, astGetCurrent( ret ) ); - astSetCurrent( ret, ic ); - } - -/* If the specified Frame in the supplied FrameSet is 2-dimensional, just - return a clone of it. */ - } else { - ret = astClone( fset ); - } - -/* Annul the pointer to the original Frame. */ - frm = astAnnul( frm ); - - return ret; - -} - -static int FullForm( const char *list, const char *test, const char *text, - const char *method, const char *class, int *status ){ -/* -* Name: -* FullForm - -* Purpose: -* Identify the full form of an option string. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FullForm( const char *list, const char *test, const char *text, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function identifies a supplied test option within a supplied -* list of valid options, and returns the index of the option within -* the list. The test option may be abbreviated, and case is -* insignificant. - -* Parameters: -* list -* A list of space separated option strings. -* test -* A candidate option string. -* text -* A string giving the context in which the supplied test option -* was supplied. For instance, this may be an attribute setting string. -* This is only for use in constructing error messages. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The index of the identified option within the supplied list, starting -* at zero. - -* Notes: -* - A value of -1 is returned if an error has already occurred, or -* if this function should fail for any reason (for instance if the -* supplied option is not uniquely specified in the supplied list). - -*/ - -/* Local Variables: */ - char *option; /* Pointer to a copy of the next option */ - const char *p; /* Pointer to the start of the next word */ - int i; /* Current option index */ - int len; /* Length of supplied option */ - int nmatch; /* Number of matching options */ - int ret; /* The returned index */ - -/* Initialise the answer to indicate that the option has not been - uniquely identified. */ - ret = -1; - -/* Check global status. */ - if( !astOK ) return ret; - -/* Save the number of characters in the supplied test option (excluding - trailing spaces). */ - len = ChrLen( test, status ); - -/* Compare the supplied test option against each of the known options in - turn. Count the number of matches. */ - nmatch = 0; - p = list; - option = FindWord( NULL, " ", &p, status ); - i = 0; - while( option ){ - -/* If the test string and the current option are identical (including - length). use the current option. */ - -/* If every character in the supplied label matches the corresponding - character in the current test label we have a match. Increment the - number of matches and save the current item index. If the test string - and the current option are identical (including length), use the - current option. */ - - if( !Ustrncmp( test, option, len, status ) ) { - ret = i; - if( ChrLen( option, status ) == len ) { - nmatch = 1; - option = astFree( option ); - break; - } else { - nmatch++; - } - } - -/* Get a pointer to the next option. */ - option = FindWord( option, " ", &p, status ); - i++; - } - -/* Report an error if no match was found, and return -1. */ - if( !nmatch ){ - astError( AST__OPT, "%s(%s): Option '%.*s' is unknown in '%.*s'.", status, - method, class, len, test, ChrLen( text, status ), text ); - ret = -1; - -/* Report an error if the label was ambiguous, and return -1. */ - } else if( nmatch > 1 ){ - astError( AST__OPT, "%s(%s): Option '%.*s' is ambiguous in '%.*s'.", status, - method, class, len, test, ChrLen( text, status ), text ); - ret = -1; - } - -/* Return the answer. */ - return ret; -} - -static void GAttr( AstPlot *this, int attr, double value, double *old_value, - int prim, const char *method, const char *class, int *status ) { -/* -* -* Name: -* GAttr - -* Purpose: -* Call the GAttr Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GAttr( AstPlot *this, int attr, double value, double *old_value, -* int prim, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GAttr grf function to enquire or set a -* graphics attribute value. It either calls the version registered using -* astGrfSet, or the version in the linked grf module. The linked version -* is used if the Grf attribute is zero, or if no function has been -* registered for GAttr using astGrfSet. - -* Parameters: -* this -* The Plot. -* attr -* An integer value identifying the required attribute. The -* following symbolic values are defined in grf.h: -* -* GRF__STYLE - Line style. -* GRF__WIDTH - Line width. -* GRF__SIZE - Character and marker size scale factor. -* GRF__FONT - Character font. -* GRF__COLOUR - Colour index. -* value -* A new value to store for the attribute. If this is AST__BAD -* no value is stored. -* old_value -* A pointer to a double in which to return the attribute value. -* If this is NULL, no value is returned. -* prim -* The sort of graphics primitive to be drawn with the new attribute. -* Identified by the following values defined in grf.h: -* GRF__LINE -* GRF__MARK -* GRF__TEXT -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. Also return if there is nothing to do. */ - if ( !astOK || ( !old_value && value == AST__BAD ) ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GATTR ] ) { - grf_status = ( *( this->GAttr ) )( this, attr, value, old_value, prim, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGAttr( attr, value, old_value, prim ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGAttr. ", status, method, - class ); - } - -} - -static AstKeyMap *GetGrfContext( AstPlot *this, int *status ){ -/* -*++ -* Name: -c astGetGrfContext -f AST_GETGRFCONTEXT - -* Purpose: -* Return the KeyMap that describes a Plot's graphics context. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c AstKeyMap *astGetGrfContext( AstPlot *this ) -f RESULT = AST_GETGRFCONTEXT( THIS, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function -f This routine -* returns a reference to a KeyMap that will be passed to any drawing -c functions registered using astGrfSet. -f routines registered using AST_GRFSET. -* This KeyMap can be used by an application to pass information to -c the drawing functions -f the drawing routines -* about the context in which they are being called. The contents of -* the KeyMap are never accessed byt the Plot class itself. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetGrfContext() -f AST_GETGRFCONTEXT = INTEGER -* A pointer to the graphics context KeyMap. The returned pointer -* should be annulled when it is no longer needed. - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Ensure that a grfcon KeyMap exists. */ - (void) astGrfConID(this); - -/* Return a cloned pointer to the KeyMap. */ - return astClone( this->grfcontext ); -} - -AstKeyMap *astGrfConID_( AstPlot *this, int *status ) { -/* -*+ -* -* Name: -* astGrfConID - -* Purpose: -* Ensure a GrfContext KeyMap exists and return an ID for it. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* AstKeyMap *astGrfConID( AstPlot *this ) - -* Class Membership: -* Plot private function. - -* Description: -* This function creates a GrfContext KeyMap if the Plot does not -* currently have one, and returns an ID for it. - -* Parameters: -* this -* The Plot. - -* Returned Value: -* ID for the GrfContext KeyMap. - -*- -*/ - if( !this->grfcontext ) { - this->grfcontext = astKeyMap("", status ); - this->grfcontextID = astMakeId( astClone( this->grfcontext ) ); - astExempt( this->grfcontextID ); - } - return this->grfcontextID; -} - -static void GScales( AstPlot *this, float *alpha, float *beta, - const char *method, const char *class, int *status ) { -/* -* -* Name: -* GScales - -* Purpose: -* Call the GScales Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GScales( AstPlot *this, float *alpha, float *beta, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GScales grf function, either calling the -* version registered using astGrfSet, or the version in the linked grf -* module. The linked version is used if the Grf attribute is zero, or if -* no function has been registered for GScales using astGrfSet. - -* Parameters: -* this -* The Plot. -* alpha -* A pointer to the location at which to return the scale for the -* X axis (i.e. Xnorm = alpha*Xworld). -* beta -* A pointer to the location at which to return the scale for the -* Y axis (i.e. Ynorm = beta*Yworld). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* if we already have the required values, return them. */ - if( Grf_alpha != 0.0 && Grf_beta != 0.0 ) { - if( alpha ) *alpha = Grf_alpha; - if( beta ) *beta = Grf_beta; - return; - } - -/* Check that the grf mdoule can give us scales information. */ - if( GCap( this, GRF__SCALES, 1, status ) ) { - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GSCALES ] ) { - grf_status = ( *( this->GScales ) )( this, &Grf_alpha, &Grf_beta, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGScales( &Grf_alpha, &Grf_beta ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Check neither value is zero. */ - if( grf_status && ( Grf_alpha == 0.0 || Grf_beta == 0.0 ) ) { - astError( AST__GRFER, "astGScales: Returned axis scales are %g and %g " - "but zero is illegal!", status, Grf_alpha, Grf_beta ); - grf_status = 0; - } - -/* Report an error if anything went wrong, and return safe values. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGScales. ", status, method, - class ); - Grf_alpha = 1.0; - Grf_beta = 1.0; - } - -/* If the grf module is not capable of giving us scale information, then - just assume the the axes are equally scaled, except for any axis reversal - indicated in the supplied Plot. */ - } else { - Grf_alpha = ( this->xrev ) ? -1.0 : 1.0; - Grf_beta = ( this->yrev ) ? -1.0 : 1.0; - } - -/* Store them for future use. */ - if( alpha ) *alpha = Grf_alpha; - if( beta ) *beta = Grf_beta; -} - -static int GCap( AstPlot *this, int cap, int value, int *status ){ -/* -* -* Name: -* GCap - -* Purpose: -* Call the GCap Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GCap( AstPlot *this, int cap, int value, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GCap grf function to inquire a capability -* of the grf module, either calling the version registered using -* astGrfSet, or the version in the linked grf module. The linked -* version is used if the Grf attribute is zero, or if no function -* has been registered for GCap using astGrfSet. - -* Parameters: -* this -* The Plot. -* cap -* The capability to be inquired aboue. -* value -* The value to assign to the capability. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the grf module is capabale of performing the action -* requested by "cap". - -*/ - -/* Local Variables: */ - int result; /* Value retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GCAP ] ) { - result = ( *( this->GCap ) )( this, cap, value, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - result = astGCap( cap, value ); - - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Return the result. */ - return result; -} - -static void GenCurve( AstPlot *this, AstMapping *map, int *status ){ -/* -*++ -* Name: -c astGenCurve -f AST_GENCURVE - -* Purpose: -* Draw a generalized curve. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astGenCurve( AstPlot *this, astMapping *map ) -f CALL AST_GENCURVE( THIS, MAP ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a general user-defined curve defined by the -f This routine draws a general user-defined curve defined by the -* supplied Mapping. Note that the curve is transformed into graphical -* coordinate space for plotting, so that a straight line in -* physical coordinates may result in a curved line being drawn if -* the Mapping involved is non-linear. Any discontinuities in the -* Mapping between physical and graphical coordinates are -c catered for, as is any clipping established using astClip. -f catered for, as is any clipping established using AST_CLIP. -* -c If you need to draw simple straight lines (geodesics), astCurve -c or astPolyCurve will usually be easier to use and faster. -f If you need to draw simple straight lines (geodesics), AST_CURVE -f or AST_POLYCURVE will usually be easier to use and faster. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c map -f MAP = INTEGER (Given) -* Pointer to a Mapping. This Mapping should have 1 input -* coordinate representing offset along the required curve, -* normalized so that the start of the curve is at offset 0.0, -* and the end of the curve is at offset 1.0. Note, this offset -* does not need to be linearly related to distance along the curve. -* The number of output coordinates should equal the number of axes -* in the current Frame of the Plot. The Mapping should map a -* specified offset along the curve, into the corresponding -* coordinates in the current Frame of the Plot. The inverse -* transformation need not be defined. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - An error results if the base Frame of the Plot is not 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *class; /* Object class */ - const char *method; /* Current method */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - int i; /* Loop count */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astGenCurve"; - class = astGetClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Only proceed if there has been no error. */ - if( astOK ){ - -/* Initialise the bounding box for primitives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__CURVE_ID, 1, GRF__LINE, method, class ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Set up the externals used to communicate with the Map4 function... */ - Map4_ncoord = astGetNout( this ); - Map4_plot = this; - Map4_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - Map4_umap = map; - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map4; - Crv_ink = 1; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = Curve_data.xbrk; - Crv_ybrk = Curve_data.ybrk; - Crv_vxbrk = Curve_data.vxbrk; - Crv_vybrk = Curve_data.vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Set up a list of points spread evenly over the curve. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Map these points into graphics coordinates. */ - Map4( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map4 to draw the curve. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map4. */ - Map4( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - Curve_data.length = Crv_len; - Curve_data.out = Crv_out; - Curve_data.nbrk = Crv_nbrk; - PurgeCdata( &Curve_data, status ); - -/* Annul the Mapping. */ - Map4_map = astAnnul( Map4_map ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__CURVE_ID, 0, GRF__LINE, method, class ); - } - -/* Return. */ - return; - -} - -static int GetLabelUnits( AstPlot *this, int axis, int *status ) { -/* -* Name: -* GetLabelUnits - -* Purpose: -* Return the value of the LabelUnits attribute for a Plot axis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GetLabelUnits( AstPlot *this, int axis, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns the value of the LabelUnits attribute for a -* Plot axis, supplying a suitable default if not set. - -* Parameters: -* this -* The Plot. -* axis -* The axis index (zero based). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The attribute value. - -*/ - -/* Local Variables: */ - AstFrame *fr; /* The current Frame in the Plot */ - AstFrame *primframe; /* The primary Frame holding the requested axis */ - AstSystemType system; /* The SkyFrame System attribute */ - int primaxis; /* Index of requested axis in the primary frame */ - int ret; /* The returned value */ - -/* Initialise. */ - ret = 0; - -/* Check global status. */ - if( !astOK ) return ret; - -/* If a value has been set, return it. */ - ret = this->labelunits[ axis ]; - -/* If no value has been set, find a default. */ - if( ret == -1 ) { - -/* Assume "no" for any SkyAxis axes within the current frame of the Plot, - and "yes" for other axes. Get a pointer to the current Frame of the - Plot. */ - fr = astGetFrame( this, AST__CURRENT ); - -/* The current Frame may be a CmpFrame. So find the primary Frame containing - the requested axis. The primary Frame is guaranteed not to be a CmpFrame. */ - astPrimaryFrame( fr, axis, &primframe, &primaxis ); - -/* If the primary Frame is a SkyFrame representing ICRS, equatorial, ecliptic, - galactic or supergalactic coords, use a default of "no" for LabelUnits. - Otherwise use a default of "yes". */ - ret = 1; - if( IsASkyFrame( (AstObject *) primframe, status ) ) { - system = astGetSystem( primframe ); - if( system == AST__ICRS || - system == AST__FK4 || - system == AST__FK4_NO_E || - system == AST__FK5 || - system == AST__GAPPT || - system == AST__ECLIPTIC || - system == AST__GALACTIC || - system == AST__SUPERGALACTIC ) ret = 0; - } - -/* Annul the frame pointers. */ - primframe = astAnnul( primframe ); - fr = astAnnul( fr ); - } - -/* Return the answer. */ - return ret; -} - -static void GBBuf( AstPlot *this, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GBBuf - -* Purpose: -* Call the GBBuf Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GBBuf( AstPlot *this, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GBBuf grf function to begin a new graphics -* context, either calling the version registered using astGrfSet, or -* the version in the linked grf module. The linked version is used -* if the Grf attribute is zero, or if no function has been registered -* for GBBuf using astGrfSet. - -* Parameters: -* this -* The Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GBBUF ] ) { - grf_status = ( *( this->GBBuf ) )( this, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGBBuf(); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGBBuf. ", status, method, - class ); - } - -} - -static void GEBuf( AstPlot *this, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GEBuf - -* Purpose: -* Call the GEBuf Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GEBuf( AstPlot *this, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GEBuf grf function to end the current graphics -* context, either calling the version registered using astGrfSet, or -* the version in the linked grf module. The linked version is used -* if the Grf attribute is zero, or if no function has been registered -* for GEBuf using astGrfSet. - -* Parameters: -* this -* The Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GEBUF ] ) { - grf_status = ( *( this->GEBuf ) )( this, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGEBuf(); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGEBuf. ", status, method, - class ); - } - -} - -static void GFlush( AstPlot *this, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GFlush - -* Purpose: -* Call the Gflush Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GFlush( AstPlot *this, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the Gflush grf function to flush graphics, either -* calling the version registered using astGrfSet, or the version in the -* linked grf module. The linked version is used if the Grf attribute -* is zero, or if no function has been registered for Gflush using -* astGrfSet. - -* Parameters: -* this -* The Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GFLUSH ] ) { - grf_status = ( *( this->GFlush ) )( this, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGFlush(); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGFlush. ", status, method, - class ); - } - -} - -static void GLine( AstPlot *this, int n, const float *x, - const float *y, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GLine - -* Purpose: -* Call the Gline Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GLine( AstPlot *this, int n, const float *x, -* const float *y, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the Gline grf function to draw a polyline, either -* calling the version registered using astGrfSet, or the version in the -* linked grf module. The linked version is used if the Grf attribute -* is zero, or if no function has been registered for Gline using -* astGrfSet. - -* Parameters: -* this -* The Plot. -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int i; /* Loop count */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Do not draw anything if we are using "invisible ink". */ - if( astGetInvisible( this ) ) { - grf_status = 1; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - } else if( astGetGrf( this ) && this->grffun[ AST__GLINE ] ) { - grf_status = ( *( this->GLine ) )( this, n, x, y, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGLine( n, x, y ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGLine. ", status, method, - class ); - -/* Otherwise, update the box containing all drawn graphics primitives. */ - } else if( !Boxp_freeze ){ - for( i = 0; i < n; i++ ) { - Boxp_lbnd[ 0 ] = astMIN( x[ i ], Boxp_lbnd[ 0 ] ); - Boxp_ubnd[ 0 ] = astMAX( x[ i ], Boxp_ubnd[ 0 ] ); - Boxp_lbnd[ 1 ] = astMIN( y[ i ], Boxp_lbnd[ 1 ] ); - Boxp_ubnd[ 1 ] = astMAX( y[ i ], Boxp_ubnd[ 1 ] ); - } - } - -} - -static void GMark( AstPlot *this, int n, const float *x, - const float *y, int type, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GMark - -* Purpose: -* Call the GMark Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GMark( AstPlot *this, int n, const float *x, -* const float *y, int type, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GMark grf function to draw markers, either -* calling the version registered using astGrfSet, or the version in the -* linked grf module. The linked version is used if the Grf attribute -* is zero, or if no function has been registered for GMark using -* astGrfSet. - -* Parameters: -* this -* The Plot. -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* type -* An integer which can be used to indicate the type of marker symbol -* required. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int i; /* Loop count */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Do not draw anything if we are using "invisible ink". */ - if( astGetInvisible( this ) ) { - grf_status = 1; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - } else if( astGetGrf( this ) && this->grffun[ AST__GMARK ] ) { - grf_status = ( *( this->GMark ) )( this, n, x, y, type, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGMark( n, x, y, type ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGMark. ", status, method, - class ); - -/* Otherwise, update the box containing all drawn graphics primitives. */ - } else if( !Boxp_freeze ){ - for( i = 0; i < n; i++ ) { - Boxp_lbnd[ 0 ] = astMIN( x[ i ], Boxp_lbnd[ 0 ] ); - Boxp_ubnd[ 0 ] = astMAX( x[ i ], Boxp_ubnd[ 0 ] ); - Boxp_lbnd[ 1 ] = astMIN( y[ i ], Boxp_lbnd[ 1 ] ); - Boxp_ubnd[ 1 ] = astMAX( y[ i ], Boxp_ubnd[ 1 ] ); - } - } - -} - -static void GQch( AstPlot *this, float *chv, float *chh, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GQch - -* Purpose: -* Call the GQch Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GQch( AstPlot *this, float *chv, float *chh, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GQch grf function, either calling the -* version registered using astGrfSet, or the version in the linked grf -* module. The linked version is used if the Grf attribute is zero, or if -* no function has been registered for GQch using astGrfSet. - -* Parameters: -* this -* The Plot. -* chv -* A pointer to the double which is to receive the height of -* characters drawn with a vertical baseline . This will be an -* increment in the X axis. -* chh -* A pointer to the double which is to receive the height of -* characters drawn with a horizontal baseline. This will be an -* increment in the Y axis. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* if we already have the required values, return them. */ - if( Grf_chh != AST__BAD && Grf_chv != AST__BAD ) { - *chh = Grf_chh; - *chv = Grf_chv; - return; - } - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GQCH ] ) { - grf_status = ( *( this->GQch ) )( this, chv, chh, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGQch( chv, chh ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Check neither value is zero. */ - if( grf_status && ( *chh == 0.0 || *chv == 0.0 ) ) { - astError( AST__GRFER, "astGQch: Returned text heights are %g and %g " - "but zero is illegal!", status, *chv, *chh ); - grf_status = 0; - } - -/* Report an error if anything went wrong, and return safe values. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGQch. ", status, method, - class ); - *chh = 1.0; - *chv = 1.0; - } - -/* Store them for future use. */ - Grf_chh = *chh; - Grf_chv = *chv; -} - -static void GText( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy, - const char *method, const char *class, int *status ) { -/* -* -* Name: -* GText - -* Purpose: -* Call the GText Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GText( AstPlot *this, const char *text, float x, float y, -* const char *just, float upx, float upy, -* const char *method, const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GText grf function to draw a text string, either -* calling the version registered using astGrfSet, or the version in the -* linked grf module. The linked version is used if the Grf attribute -* is zero, or if no function has been registered for GText using -* astGrfSet. - -* Parameters: -* this -* The Plot. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Do not draw anything if we are using "invisible ink". */ - if( astGetInvisible( this ) ) { - grf_status = 1; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - } else if( astGetGrf( this ) && this->grffun[ AST__GTEXT ] ) { - grf_status = ( *( this->GText ) )( this, text, x, y, just, upx, upy, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGText( text, x, y, just, upx, upy ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGText. ", status, method, - class ); - } - -} - -static void GTxExt( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy, float *xbn, - float *ybn, const char *method, const char *class, int *status ) { -/* -* -* Name: -* GTxExt - -* Purpose: -* Call the GTxExt Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GTxExt( AstPlot *this, const char *text, float x, float y, -* const char *just, float upx, float upy, float *xbn, -* float *ybn, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GTxExt grf function to find the extent -* of a text string, either calling the version registered using -* astGrfSet, or the version in the linked grf module. The linked -* version is used if the Grf attribute is zero, or if no function -* has been registered for GTxExt using astGrfSet. - -* Parameters: -* this -* The Plot. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. -* xbn -* An array of 4 elements in which to return the x coordinate of -* each corner of the bounding box. -* ybn -* An array of 4 elements in which to return the y coordinate of -* each corner of the bounding box. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The corners are returned in no particular order. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GTXEXT ] ) { - grf_status = ( *( this->GTxExt ) )( this, text, x, y, just, upx, upy, - xbn, ybn, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGTxExt( text, x, y, just, upx, upy, xbn, ybn ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGTxExt. ", status, method, - class ); - } -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Plot. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Plot member function (over-rides the protected astGetAttrib -* method inherited from the FrameSet class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Plot, formatted as a character string. -* -* The value returned is the value which would actually be used if -* astGrid was called with the current set of attribute values. This -* may not always be the same as the value set by the user. For -* instance, if Labelling is set to "exterior" by the user, it may not -* be possible to produce exterior labels, in which case interior labels -* will be produced. If this function is used to get the value of -* Labelling in this situation, then the value actually used (i.e. -* interior) will be returned instead of the requested value (i.e. -* exterior). -* -* Some attributes have dynamic defaults, (i.e. the behaviour if not -* set depends on the values of other attributes). If the value for -* such an attribute is enquired using this function, then the dynamic -* default value actually used will be returned if no value has been -* set explicitly for the attribute. - -* Parameters: -* this -* Pointer to the Plot. -* attrib -* Pointer to a null terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Plot, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Plot. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPlot *this; /* Pointer to the Plot structure */ - const char *result; /* Pointer value to return */ - char label[21]; /* Graphics item label */ - double dval; /* Double attribute value */ - int axis; /* Axis number */ - int ival; /* Int attribute value */ - int len; /* Length of attrib string */ - int nax; /* Number of base Frame axes */ - int nc; /* No. characters read by astSscanf */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Get the number of base Frame axis (2 for a Plot, 3 for a Plot3D). */ - nax = astGetNin( this ); - -/* Indicate that the current bound box should not be changed during the - execution of this function (this may happen if a grid is drawn to get - the default value for an attribute such as Labelling). */ - Boxp_freeze = 1; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* Tol. */ -/* ---- */ - if ( !strcmp( attrib, "tol" ) ) { - dval = astGetTol( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Grid. */ -/* ----- */ - } else if ( !strcmp( attrib, "grid" ) ) { - ival = GetUsedGrid( this, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TickAll. */ -/* -------- */ - } else if ( !strcmp( attrib, "tickall" ) ) { - ival = astGetTickAll( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* ForceExterior. */ -/* -------------- */ - } else if ( !strcmp( attrib, "forceexterior" ) ) { - ival = astGetForceExterior( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Invisible. */ -/* ---------- */ - } else if ( !strcmp( attrib, "invisible" ) ) { - ival = astGetInvisible( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Border. */ -/* ------- */ - } else if ( !strcmp( attrib, "border" ) ) { - ival = GetUsedBorder( this, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* ClipOp. */ -/* ------- */ - } else if ( !strcmp( attrib, "clipop" ) ) { - ival = astGetClipOp( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Clip. */ -/* ----- */ - } else if ( !strcmp( attrib, "clip" ) ) { - ival = astGetClip( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Grf. */ -/* ---- */ - } else if ( !strcmp( attrib, "grf" ) ) { - ival = astGetGrf( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* DrawTitle. */ -/* --------- */ - } else if ( !strcmp( attrib, "drawtitle" ) ) { - ival = astGetDrawTitle( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Escape. */ -/* ------- */ - } else if ( !strcmp( attrib, "escape" ) ) { - ival = astGetEscape( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LabelAt(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelat(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedLabelAt( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Centre(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "centre(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedCentre( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Gap. */ -/* ---- */ - } else if ( !strcmp( attrib, "gap" ) ) { - dval = GetUsedGap( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Gap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "gap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedGap( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* LogGap. */ -/* ---- */ - } else if ( !strcmp( attrib, "loggap" ) ) { - dval = GetUsedLogGap( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* LogGap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loggap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedLogGap( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* NumLabGap. */ -/* -------- */ - } else if ( !strcmp( attrib, "numlabgap" ) ) { - dval = astGetNumLabGap( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* NumLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetNumLabGap( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* TextLabGap. */ -/* ----------- */ - } else if ( !strcmp( attrib, "textlabgap" ) ) { - dval = astGetTextLabGap( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* TextLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetTextLabGap( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* LabelUp. */ -/* -------- */ - } else if ( !strcmp( attrib, "labelup" ) ) { - ival = astGetLabelUp( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LabelUp(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelup(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = astGetLabelUp( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogPlot. */ -/* -------- */ - } else if ( !strcmp( attrib, "logplot" ) ) { - ival = astGetLogPlot( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogPlot(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logplot(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = astGetLogPlot( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogLabel. */ -/* -------- */ - } else if ( !strcmp( attrib, "loglabel" ) ) { - ival = GetUsedLogLabel( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogLabel(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loglabel(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedLogLabel( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogTicks. */ -/* -------- */ - } else if ( !strcmp( attrib, "logticks" ) ) { - ival = GetUsedLogTicks( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogTicks(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logticks(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedLogTicks( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* NumLab. */ -/* -------- */ - } else if ( !strcmp( attrib, "numlab" ) ) { - ival = astGetNumLab( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* NumLab(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = astGetNumLab( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* MinTick. */ -/* -------- */ - } else if ( !strcmp( attrib, "mintick" ) ) { - ival = GetUsedMinTick( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* MinTick(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "mintick(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedMinTick( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TextLab. */ -/* ---------- */ - } else if ( !strcmp( attrib, "textlab" ) ) { - ival = GetUsedTextLab( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TextLab(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedTextLab( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* DrawAxes. */ -/* ----------- */ - } else if ( !strcmp( attrib, "drawaxes" ) ) { - ival = astGetDrawAxes( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* DrawAxes(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "drawaxes(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetDrawAxes( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Abbrev. */ -/* ----------- */ - } else if ( !strcmp( attrib, "abbrev" ) ) { - ival = astGetAbbrev( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Abbrev(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "abbrev(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetAbbrev( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LabelUnits. */ -/* ----------- */ - } else if ( !strcmp( attrib, "labelunits" ) ) { - ival = GetUsedLabelUnits( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LabelUnits(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelunits(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedLabelUnits( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Style. */ -/* ------ */ - } else if ( !strcmp( attrib, "style" ) ) { - ival = GetUseStyle( this, AST__BORDER_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Style(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "style(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - ival = GetUseStyle( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Font. */ -/* ----- */ - } else if ( !strcmp( attrib, "font" ) ) { - ival = GetUseFont( this, AST__TEXTLABS_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Font(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "font(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - ival = GetUseFont( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Colour. */ -/* ------- */ - } else if ( !strcmp( attrib, "colour" ) ) { - ival = GetUseColour( this, AST__TEXTLABS_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Colour(label). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "colour(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - ival = GetUseColour( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Color. */ -/* ------ */ - } else if ( !strcmp( attrib, "color" ) ) { - ival = GetUseColour( this, AST__TEXTLABS_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Color(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "color(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - ival = GetUseColour( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Width. */ -/* ------ */ - } else if ( !strcmp( attrib, "width" ) ) { - dval = GetUseWidth( this, AST__BORDER_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - -/* Width(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "width(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - dval = GetUseWidth( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Size. */ -/* ----- */ - } else if ( !strcmp( attrib, "size" ) ) { - dval = GetUseSize( this, AST__TEXTLABS_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Size(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "size(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - dval = GetUseSize( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* TitleGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "titlegap" ) ) { - dval = astGetTitleGap( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* MajTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "majticklen" ) ) { - dval = GetUsedMajTickLen( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* MajTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "majticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedMajTickLen( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* MinTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "minticklen" ) ) { - dval = astGetMinTickLen( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* MinTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "minticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetMinTickLen( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Labelling. */ -/* ---------- */ - } else if ( !strcmp( attrib, "labelling" ) ) { - ival = GetUsedLabelling( this, status ); - if ( astOK ) { - result = ival ? xlbling[1] : xlbling[0]; - } - -/* Edge(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "edge(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedEdge( this, axis - 1, status ); - if ( astOK ) { - if( ival == LEFT ){ - result = "left"; - } else if( ival == RIGHT ){ - result = "right"; - } else if( ival == TOP ){ - result = "top"; - } else if( ival == BOTTOM ){ - result = "bottom"; - } else { - result = ""; - } - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Unfreeze the bound box so that it may be updated by subsequent - plotting functions. */ - Boxp_freeze = 0; - -/* Return the result. */ - return result; -} - -static AstPointSet *GetDrawnTicks( AstPlot *this, int axis, int major, int *status ){ -/* -*+ -* Name: -* astGetDrawnTicks - -* Purpose: -* Return information about the ticks last drawn by astGrid. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* AstPointSet *GetDrawnTicks( AstPlot *this, int axis, int major ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns a PointSet holding information about the -* tick marks (either major and minor) that were drawn by the previous -* invocation of astGrid. A NULL pointer is returned if astGrid has -* not yet been invoked. - -* Parameters: -* this -* Pointer to a Plot. -* axis -* The zero-based axis of the axis for which tick mark information -* is required. -* major -* Supply a non-zero value if information about the major tick -* marks is to be returned, and zero if information about the minor -* tick marks is to be returned. - -* Returned Value: -* A pointSet with one point for every tick of the requested type drawn -* by astGrid for the specified axis. Each point has 2 coordinate values, -* being the graphics coordinates at the start of the tick mark. The -* returned PointSet pointer should be annulled when no longer needed. - -*- -*/ - -/* Local Variables: */ - AstPointSet *result = NULL; - double *ptr[ 3 ]; - int n; - -/* Check the global status. */ - if( !astOK ) return result; - -/* Report an error if the supplied axis value is incorrect. */ - if( axis < 0 || axis > 1 ) { - astError( AST__INTER, "astGetDrawnTicks(Plot): Supplied \"axis\" " - "value is %d - should 0 or 1 (internal AST programming " - "error).", status, axis ); - n = 0; - -/* If OK, get the number of stored tick marks. */ - } else { - n = major ? this->majtickcount[ axis ] : this->mintickcount[ axis ]; - } - -/* Check that information is available. */ - if( n > 0 && astOK ) { - -/* Create a PointSet with the required size. */ - result = astPointSet( n, 2, "", status ); - -/* Store pointers to the arrays within the Plot that hold the required - tick marks positions and types. */ - ptr[ 0 ] = major ? this->majtickgx[ axis ] : this->mintickgx[ axis ]; - ptr[ 1 ] = major ? this->majtickgy[ axis ] : this->mintickgy[ axis ]; - astSetPoints( result, ptr ); - } - -/* Return the PointSet. */ - return result; -} - -static double GetTicks( AstPlot *this, int axis, double *cen, double **ticks, - int *nmajor, double **minticks, int *nminor, - int format_set, int *inval, double *refval, - GetTicksStatics **pstatics, const char *method, - const char *class, int *status ){ -/* -* Name: -* GetTicks - -* Purpose: -* Obtain a list of logarithmically or linearly spaced tick mark values for -* a single axis in a 2-D physical coordinate Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double GetTicks( AstPlot *this, int axis, double *cen, double **ticks, -* int *nmajor, double **minticks, int *nminor, -* int format_set, int *inval, double *refval, -* GetTicksStatics **pstatics, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* For linearly spaced major ticks the "gap" returned by this function -* is the constant difference between adjacent major tick marks. For -* logarithmically spaced major ticks the "gap" returned by this -* function is the constant ratio between adjacent major tick marks. -* -* If a gap size has been specified using attribute Gap (or LogGap for -* logarithmic ticks) supplied, the specified value is returned, and used -* to determine the tick values. If no gap size is supplied, a default -* gap size is used and returned. -* -* All this is over-ridden if the astSetTickValues method has been -* called to store explicit tick mark values in the Plot structure. -* In this case, the values supplied using astSetTickValues are -* returned. - -* Parameters: -* this -* The Plot. Supplying a NULL pointer will cause statics resources -* to be released. -* axis -* The zero-based index of the axis to use. -* cen -* Pointer to the supplied axis value at which to put a single -* central tick. Other ticks will be placed evenly on either side -* of this tick. If AST__BAD is provided, a value will be used -* which would put a tick at an axis value of one. The used value -* is returned. -* ticks -* Pointer to a place at which to return a pointer to the memory in -* which are stored the major tick values to be used. This pointer -* should be freed using astFree when no longer needed. The number of -* values in the array is given by the value returned by parameter -* "nmajor". -* nmajor -* A pointer to a location at which to return the number of major -* ticks. -* minticks -* Pointer to a place at which to return a pointer to the memory in -* which are stored the minor tick values to be used. This pointer -* should be freed using astFree when no longer needed. The number of -* values in the array is given by the value returned by parameter -* "nminor". The minor tick marks values returned in this array are -* the ones stored in the Plot via a call to the astSetTickValues -* function. If this function has not been called, then a NULL -* pointer is returned, and the "nminor" value is returned holding the -* number of divisions between major ticks. -* nminor -* A pointer to a location at which to return either the number of -* division into which each gap should be divided when drawing minor -* tick marks (if "*minticks" is returned holding NULL), or the -* total number of minor tick values stored in "*minticks" (if -* "*minticks" is returned non-NULL). The number of divisions -* between major tick values is one more than the number of minor -* tick marks. -* format_set -* Indicates if an explicit format has been set for the axis. If -* not, "cen" is always assumed to be AST__BAD, and any specified -* Gap value is rounded to the nearest "nice" value. This has -* to be done because the algorithm for choosing a format avoiding -* unnecessary precision only works if the gap size causes 1 digit to -* change between adjacent labels. -* inval -* A pointer to a location at which to return a flag indicating if -* any invalid physical coordinates were encountered. -* refval -* A pointer to a location at which to return a value for the other -* axis which can be used when normalizing the returned tick mark -* values. -* pstatics -* Address of a pointer to a structure holding static data values -* used within this function. A NULL pointer should be supplied on -* the first invocation (dynamic memory will then be allocated to -* hold ths structure). The memory is freed when a NULL value for -* "this" is supplied. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The used gap size. - -* Notes: -* - This function allocates some static resources on its first -* invocation, which should be released when no longer needed, or when -* a different Plot is supplied, by calling this function with a NULL -* pointer for parameter "this". All other parameters are ignored. -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - An error is reported if the region containing valid physical -* coordinates is too small to use. -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned in "ticks", zero -* is returned for the number of major and minor ticks marks. -*/ - -/* Local Variables: */ - GetTicksStatics *statics; /* Pointer to statics structure */ - double *tick; /* Pointer to next tick value */ - double cen0; /* Supplied value of cen */ - double dran; /* Dynamic range of axis values */ - double frac; /* Fraction of plot area holding good coords */ - double gap; /* Supplied value for Gap or LogGap */ - double log_used_gap; /* Log10( the used gap size ) */ - double maxv; /* Max axis value */ - double minv; /* Min axis value */ - double new_used_gap; /* New value for the used gap size */ - double old_used_gap; /* Old value for the used gap size */ - double test_gap; /* Trial gap size */ - double used_cen; /* Used value of cen */ - double used_gap; /* The used gap size */ - int findcen; /* Find a new centre value? */ - int gap_too_small; /* Test gap too small? */ - int gap_too_large; /* Test gap too large? */ - int i; /* Axis index */ - int ihi; /* Highest tick mark index */ - int ilo; /* Lowest tick mark index */ - int nochange; /* No. of ineffective attempts to change gap size */ - -/* Initialise the returned information. */ - *ticks = NULL; - *minticks = NULL; - *nmajor = 0; - *nminor = 0; - -/* Get a pointer to the supplied statics object. */ - statics = *pstatics; - -/* If a NULL pointer has been supplied for "this", release the resources - allocated on the first call to this function, and return. */ - if( !this ){ - if( statics ) { - if( statics->map ) statics->map = astAnnul( statics->map ); - if( statics->pset ) statics->pset = astAnnul( statics->pset ); - if( statics->frame ) statics->frame = astAnnul( statics->frame ); - *pstatics = astFree( statics ); - } - return 0.0; - } - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* If no statics structure was supplied, create one now and initialise it. */ - if( !statics ) { - statics = astMalloc( sizeof( GetTicksStatics ) ); - if( statics ) { - statics->pset=NULL; - *pstatics = statics; - } - } - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - maxv = 0.0; - minv = 0.0; - used_cen = 0.0; - used_gap = 0.0; - ihi = 0; - ilo = 0; - -/* If this is the first call to this function, do some initialisation. */ - if( !statics->pset ){ - -/* Get the Mapping from Base to Current Frame in the Plot. */ - statics->map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Get a pointer to the current Frame from the Plot. */ - statics->frame = astGetFrame( this, AST__CURRENT ); - -/* Get initial guesses at suitable gaps for each axis. A PointSet is - returned holding sorted values (non-normalized) for the physical axes. */ - statics->pset = DefGap( this, statics->defgaps, statics->ngood, &frac, &statics->bad, method, class, status ); - -/* Store the maximum and minimum number of major tick marks along each - axis. These numbers are reduced if only a small part of the plotting - area contains valid coordinates, so that the tick marks do not end up - to close together. */ - statics->maxticks = (int) ( 0.5 + MAJTICKS_MAX*sqrt( frac ) ); - statics->mintick = (int) ( 0.5 + MAJTICKS_MIN*sqrt( frac ) ); - if( statics->mintick < 3 ) statics->mintick = 3; - if( statics->maxticks < 8 ) statics->maxticks = 8; - if( statics->maxticks < statics->mintick ) statics->maxticks = statics->mintick; - -/* Get a pointer to the data in the PointSet. */ - statics->ptr = astGetPoints( statics->pset ); - -/* Find a typical value on each axis. */ - for( i = 0; i < 2 && astOK; i++ ){ - statics->typval[ i ] = Typical( statics->ngood[ i ], statics->ptr[ i ], -DBL_MAX, DBL_MAX, - statics->width + i, status ); - } - } - -/* Return the flag indicating if any regions of invalid physical coordinates - were found. */ - *inval = statics->bad; - -/* Return the typical value on the other axis. */ - *refval = statics->typval[ 1 - axis ]; - -/* See if any tick marks values have been stored in the Plot structure - using astSetTickValues. If so, copy the tick mark values to the - returned arrays and exit with a gap size determined by the first two - ticks. */ - if( this->nmajtickval[ axis ] > 0 ) { - *ticks = astStore( NULL, this->majtickval[ axis ], - this->nmajtickval[ axis ]*sizeof(double) ); - *minticks = astStore( NULL, this->mintickval[ axis ], - this->nmintickval[ axis ]*sizeof(double) ); - *nmajor = this->nmajtickval[ axis ]; - *nminor = this->nmintickval[ axis ]; - - if( *nmajor > 1 && (*ticks)[ 0 ] != AST__BAD && - (*ticks)[ 1 ] != AST__BAD ) { - used_gap = fabs( (*ticks)[ 1 ] - (*ticks)[ 0 ] ); - } else { - used_gap = AST__BAD; - } - - return used_gap; - - } - -/* See if the user has specified a gap size. The default for astGetLogTicks is - determined in DefGaps, so we can now decide whether to use attribute Gap - or LogGap to get the user-supplied gap size. Obtain the requested gap - attribute values for both physical axes. */ - if( astGetLogTicks( this, axis ) ) { - gap = astGetLogGap( this, axis ); - } else { - gap = astGetGap( this, axis ); - } - -/* Find the maximum and minimum value in the plotting area. DefGap will - have reported an error if minv*maxv is negative or zero. */ - if( astOK ) { - maxv = statics->ptr[ axis ][ statics->ngood[ axis ] - 1 ]; - minv = statics->ptr[ axis ][ 0 ]; - } - -/* First deal with logarithmically spaced ticks. */ - dran = ( minv != 0.0 ) ? maxv/minv : 0.0; - if( astGetLogTicks( this, axis ) ) { - -/* If the ratio of max and min data value is not larger than 10, report an - error. */ - dran = ( minv != 0.0 ) ? maxv/minv :0.0; - if( dran < 10.0 && dran > 0.1 ) { - astError( AST__VSMAL, "%s(%s): Cannot produce logarithmically " - "spaced major tick marks on axis %d since the dynamic " - "range of the axis is too small.", status, method, class, axis + 1 ); - } - -/* Should we find a new value for "cen"? */ - findcen = !cen || *cen == AST__BAD || !format_set; - -/* Try to find a "nice" gap size, so long as the caller has not supplied - a gap size. The default gap size obtained above is our initial guess. */ - if( gap == AST__BAD && astOK ){ - -/* Start off using the default gap found during the initialisation. */ - test_gap = statics->defgaps[ axis ]; - -/* Loop round until a gap size is found which gives an acceptable number - of tick marks. Upto 10 gap sizes are tried. */ - for( i = 0; i < 10 && astOK; i++ ){ - -/* Find a "nice" gap size close to the current test gap size. Also find - the number of minor tick marks to use with the nice gap size. Gaps for - logarithmic axes are always powers of ten. */ - log_used_gap = (int) ( log10( test_gap ) + 0.5 ); - if( log_used_gap == 0.0 ) { - log_used_gap = ( test_gap > 1.0 ) ? 1.0 : -1.0; - } - *nminor = 9; - used_gap = pow( 10.0, log_used_gap ); - -/* If no value has been supplied for *cen, choose a value which would put - a major tick mark at the value 1 (or -1), and which is mid way between - the maximum and minimum axis value. */ - if( findcen ) { - used_cen = pow( used_gap, (int) ( 0.5*log10( maxv*minv ) / - log_used_gap ) ); - if( maxv < 0 ) used_cen = -used_cen; - } else { - used_cen = *cen; - } - -/* Find the index of the highest tick which is not larger than the lowest - axis value. */ - if( log_used_gap > 0.0 ) { - ilo = floor( log10( minv/used_cen )/log_used_gap ); - } else { - ilo = ceil( log10( minv/used_cen )/log_used_gap ); - } - -/* Find the index of the lowest tick which is not less than the highest - axis value. */ - if( log_used_gap > 0.0 ) { - ihi = ceil( log10( maxv/used_cen )/log_used_gap ); - } else { - ihi = floor( log10( maxv/used_cen )/log_used_gap ); - } - -/* Find the total number of tick marks. */ - *nmajor = ihi - ilo + 1; - -/* If the number of ticks is unacceptable, try a different gap size. If the - gap was too large to produce any ticks, try using half the gap size. */ - if( *nmajor <= 0 ) { - test_gap = sqrt( test_gap ); - -/* If there were some ticks, but not enough, decrease the gap size in - proportion to the shortfall. */ - } else if( *nmajor < statics->mintick ){ - test_gap = pow( test_gap, (double)( *nmajor )/(double)( statics->mintick ) ); - -/* If there were too many ticks, increase the gap size in proportion to the - excess. */ - } else if( *nmajor > statics->maxticks ){ - test_gap = pow( test_gap, (double)( *nmajor )/(double)( statics->maxticks ) ); - -/* If the number of ticks is acceptable, break out of the loop early.*/ - } else { - break; - } - } - -/* Increase the tick coverage by one at each end to cover up the gaps. */ - ilo--; - ihi++; - *nmajor += 2; - -/* If an explicit gap size was supplied, use it. */ - } else if( astOK ) { - -/* Check it is usable. */ - if( gap == 0.0 && astOK ) { - astError( AST__ATTIN, "%s(%s): Invalid value zero given for " - "attribute LogGap(%d).", status, method, class, axis + 1 ); - - } else if( gap < 0.0 && astOK ) { - astError( AST__ATTIN, "%s(%s): Invalid negative value %f given for " - "attribute LogGap(%d).", status, method, class, gap, axis + 1 ); - -/* If necessary, take its reciprocal in order to ensure that the absolute - tick mark values get smaller or larger as required. */ - } else { - - used_gap = gap; - if( fabs( maxv ) < fabs( minv ) ) { - if( gap > 1.0 ) used_gap = 1.0/gap; - } else { - if( gap < 1.0 ) used_gap = 1.0/gap; - } - -/* Find the nearest power of 10 ( do not allow 10**0 (=1.0) to be used). */ - log_used_gap = (int) ( log10( used_gap ) + 0.5 ); - if( log_used_gap == 0.0 ) { - log_used_gap = ( gap > 1.0 ) ? 1.0 : -1.0; - } - used_gap = pow( 10.0, log_used_gap ); - -/* We always use 9 minor intervals. */ - *nminor = 9; - -/* If no value has been supplied for *cen, choose a value which would put - a major tick mark at the value 1 (or -1), and which is mid way between - the maximum and minimum axis value. */ - if( findcen ) { - used_cen = pow( used_gap, (int) ( 0.5*log10( maxv*minv ) / - log_used_gap ) ); - if( maxv < 0 ) used_cen = -used_cen; - } else { - used_cen = *cen; - } - -/* Find the index of the highest tick which is not larger than the lowest - axis value. */ - if( log_used_gap > 0.0 ) { - ilo = floor( log10( minv/used_cen )/log_used_gap ); - } else { - ilo = ceil( log10( minv/used_cen )/log_used_gap ); - } - -/* Find the index of the lowest tick which is not less than the highest - axis value. */ - if( log_used_gap > 0.0 ) { - ihi = ceil( log10( maxv/used_cen )/log_used_gap ); - } else { - ihi = floor( log10( maxv/used_cen )/log_used_gap ); - } - -/* Find the total number of tick marks. */ - *nmajor = ihi - ilo + 1; - if( *nmajor < 2 && astOK ) { - astError( AST__ATTIN, "%s(%s): Unusable value %f given for " - "attribute LogGap(%d).", status, method, class, gap, axis + 1 ); - - } - } - } - -/* Allocate memory to hold the tick values themselves. */ - *ticks = (double *) astMalloc( sizeof( double )*( *nmajor ) ); - if( astOK ) { - -/* Store them. */ - tick = *ticks; - for( i = ilo; i <= ihi; i++, tick++ ) { - *tick = used_cen*pow( used_gap, i ); - } - } - -/* Store returned centre value. */ - if( cen ) *cen = used_cen; - -/* Now deal with linearly spaced ticks */ - } else { - -/* Store the supplied value of cen. */ - cen0 = ( cen ) ? *cen : AST__BAD; - -/* If no format has been set for the axis, ensure AST__BAD is used for cen. */ - if( !format_set ) cen0 = AST__BAD; - -/* Try to find a "nice" gap size, so long as the caller has not supplied - a gap size. The default gap size obtained above is our initial guess. */ - if( gap == AST__BAD ){ - old_used_gap = AST__BAD; - -/* Start of using the default gap found during the initialisation. */ - test_gap = statics->defgaps[ axis ]; - used_gap = 0.0; - -/* Initialise flags saying the test gap is too large or too small */ - gap_too_large = 0; - gap_too_small = 0; - -/* So far, there have been no ineffective attempts to change the gap - size. */ - nochange = 0; - -/* Loop round until a gap size is found which gives an acceptable number - of tick marks. Upto 10 gap sizes are tried. */ - for( i = 0; i < 10 && astOK; i++ ){ - -/* Find a "nice" gap size close to the current test gap size. Also find - the number of minor tick marks to use with the nice gap size. */ - new_used_gap = astGap( statics->frame, axis, test_gap, nminor ); - -/* Find the number and positions of major tick marks which would result - from using this gap size. Annul the memory used to hold any previous tick - data first. Only do this if the gap being used has actually changed, - otherwise we just retain the values created from the previous run with - this gap size. */ - if( new_used_gap != used_gap ) { - nochange = 0; - old_used_gap = used_gap; - used_gap = new_used_gap; - if( *ticks ) *ticks = astFree( *ticks ); - if( cen ) *cen = cen0; - *nmajor = FindMajTicks( statics->map, statics->frame, axis, *refval, statics->width[ 1-axis ], - used_gap, cen, statics->ngood[ axis ], - statics->ptr[ axis ], ticks, status ); - -/* If the gap size has not changed do an extra pass through this loop, - but only do this a maximum of 25 times in succession. */ - } else if( nochange < 25 ) { - nochange++; - i--; - - } else if( astOK ){ - astError( AST__VSMAL, "%s(%s): Cannot produce enough major " - "tick marks on axis %d using the current axis " - "format (\"%s\").", status, method, class, axis + 1, - astGetFormat( statics->frame, axis ) ); - break; - } - -/* If the number of ticks is unacceptable, try a different gap size. If the - gap was too large to produce any ticks, try using half the gap size. */ - if( *nmajor == 0 ) { - test_gap *= 0.5; - gap_too_large = 1; - gap_too_small = 0; - -/* If there were some ticks, but not enough... */ - } else if( *nmajor < statics->mintick ){ - -/* If the previous test gap produced too many ticks, use the current gap - size. */ - if( gap_too_small ) { - break; - -/* Otherwise, decrease the gap size in proportion to the shortfall. */ - } else { - test_gap *= (double)( *nmajor )/(double)( statics->mintick ); - gap_too_large = 1; - gap_too_small = 0; - } - -/* If there were too many ticks... */ - } else if( *nmajor > statics->maxticks ){ - -/* If the previous test gap produced too few ticks, use the previous gap - size. */ - if( gap_too_large ) { - used_gap = old_used_gap; - if( *ticks ) *ticks = astFree( *ticks ); - if( cen ) *cen = cen0; - *nmajor = FindMajTicks( statics->map, statics->frame, axis, *refval, statics->width[ 1-axis ], - used_gap, cen, statics->ngood[ axis ], - statics->ptr[ axis ], ticks, status ); - break; - -/* Otherwise, increase the gap size in proportion to the excess. */ - } else { - test_gap *= (double)( *nmajor )/(double)( statics->maxticks ); - gap_too_small = 1; - gap_too_large = 0; - } - -/* If the number of ticks is acceptable, break out of the loop early.*/ - } else { - break; - } - } - -/* If an explicit gap size was supplied, use it. */ - } else { - -/* Find a likely value for the number of minor tick marks to use, and find - a nice gap close to the supplied gap (unless an explicit format has - been set). */ - if( format_set ){ - used_gap = gap; - (void) astGap( statics->frame, axis, used_gap, nminor ); - } else { - used_gap = astGap( statics->frame, axis, gap, nminor ); - } - -/* Find where the major ticks should be put. */ - if( cen ) *cen = cen0; - *nmajor = FindMajTicks( statics->map, statics->frame, axis, *refval, statics->width[ 1-axis ], - used_gap, cen, statics->ngood[ axis ], statics->ptr[ axis ], - ticks, status ); - } - } - -/* Report an error if no ticks can be found. */ - if( *nmajor == 0 && astOK ) { - astError( AST__GRFER, "%s(%s): Cannot find any usable tick mark values. ", status, method, - class ); - } - -/* If an error has occurred, annul the memory used to hold tick data, and - return zero ticks. */ - if( !astOK ) { - *ticks = (double *) astFree( (void *) *ticks ); - *nmajor = 0; - *nminor = 0; - used_gap = 0.0; - } - -/* Return. */ - return used_gap; -} - -static double GoodGrid( AstPlot *this, int *dim, AstPointSet **pset1, - AstPointSet **pset2, const char *method, - const char *class, int *status ){ -/* -* Name: -* GoodGrid - -* Purpose: -* Create a grid covering the region containing good coordinates in a -* 2-D physical coordinate Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double GoodGrid( AstPlot *this, int *dim, AstPointSet **pset1, -* AstPointSet **pset2, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function creates two PointSets, one holding a square grid of -* graphics coordinates, and the other holding the corresponding physical -* coordinates (not normalized). The grid covers just the area containing -* good physical coordinates. The points are stored row by row in the -* returned PointSets. - -* Parameters: -* this -* The Plot. -* dim -* A pointer to an integer in which to store the number of samples -* along each edge of the returned grid. -* pset1 -* A pointer to a location at which to store a pointer to the -* PointSet holding the graphics coordinates. -* pset2 -* A pointer to a location at which to store a pointer to the -* PointSet holding the physical coordinates. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The fraction of the plotting area containing good physical -* coordinates. - -* Notes: -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - The returned PointSets should be annulled when no longer needed, -* using astAnnul. -* - An error is reported if the region containing valid physical -* coordinates is too small to use. -* - A function value of zero, and NULL pointers are returned if an error -* has already occurred, or if this function should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to the Current Frame in the Plot */ - AstMapping *map; /* Pointer to "graphics to physical" mapping */ - double **ptr1; /* Pointer to physical axis value data */ - double **ptr2; /* Pointer to graphics axis value data */ - double *pa; /* Pointer to next value on 1st physical axis */ - double *pb; /* Pointer to next value on 2nd physical axis */ - double *px; /* Pointer to next value on 1st graphics axis */ - double *py; /* Pointer to next value on 2nd graphics axis */ - double dx; /* Cell size along graphics X (1st) axis */ - double dy; /* Cell size along graphics Y (2nd) axis */ - double frac; /* Fraction of good physical coordinates */ - double xmax; /* High X bound of region containing good phy. coords */ - double xmin; /* Low X bound of region containing good phy. coords */ - double ymax; /* High Y bound of region containing good phy. coords */ - double ymin; /* Low Y bound of region containing good phy. coords */ - int j; /* Element offset */ - int ngood; /* Number of grid points with good physical coords */ - int size; /* Number of grid points */ - -/* Initialise the returned PointSet pointers. */ - *pset1 = NULL; - *pset2 = NULL; - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - ptr1 = NULL; - frac = 0.0; - xmax = 0.0; - xmin = 0.0; - ymax = 0.0; - ymin = 0.0; - -/* Get the Mapping from base (graphics) to current (physical) Frame in the - supplied Plot. */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Get a pointer to the Current Frame in the Plot. */ - frm = astGetFrame( this, AST__CURRENT ); - -/* Initialise the grid dimension. */ - *dim = 16; - -/* We need a grid which has at least 4 good points. */ - ngood = 0; - while( ngood < 4 && astOK ){ - -/* Double the grid dimension. */ - *dim *= 2; - -/* Report an error if the grid is now too big. */ - if( *dim >= 512 ){ - astError( AST__VSMAL, "%s(%s): The area of the plot containing " - "usable coordinates on both axes is too small.", status, method, - class ); - break; - } - -/* Get two PointSets, one holding a regular grid of graphics coordinates, - and the other holding the corresponding physical coordinates. The grid - covers the entire plotting area with the current grid dimension. A - pointer to the physical axis values is returned. */ - ptr2 = MakeGrid( this, frm, map, 1, *dim, this->xlo, this->xhi, this->ylo, - this->yhi, 2, pset1, pset2, 0, method, class, status ); - -/* Get the number of graphics axis values. */ - size = astGetNpoint( *pset1 ); - -/* Get a pointer to the graphics axis values. */ - ptr1 = astGetPoints( *pset1 ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Find the bounds in graphics coordinates of the area enclosing the - good physical positions in the grid, and count the good positions. */ - ngood = 0; - - pa = ptr2[ 0 ]; - pb = ptr2[ 1 ]; - px = ptr1[ 0 ]; - py = ptr1[ 1 ]; - - xmin = DBL_MAX; - xmax = -DBL_MAX; - ymin = DBL_MAX; - ymax = -DBL_MAX; - - for( j = 0; j < size; j++ ){ - if( *pa != AST__BAD && *pb != AST__BAD ){ - if( *px < xmin ) xmin = *px; - if( *px > xmax ) xmax = *px; - if( *py < ymin ) ymin = *py; - if( *py > ymax ) ymax = *py; - ngood++; - } - px++; - py++; - pa++; - pb++; - } - } - } - -/* Store approximate fraction of the plotting area containing good - physical coordinates. */ - if( astOK ) { - frac = ( (double) ngood )/(double)( astGetNpoint( *pset1 ) ); - -/* Get the size of each grid cell. */ - dx = ptr1[0][1] - ptr1[0][0]; - dy = ptr1[1][1] - ptr1[1][0]; - -/* Extend the area containing good points by one grid cell. */ - xmax += dx; - xmin -= dx; - ymax += dy; - ymin -= dy; - -/* If the area containing good points is significantly smaller than - the supplied area, create a new grid covering just the area containing - good positions. */ - if( ( xmax - xmin ) < 0.9*( this->xhi - this->xlo ) || - ( ymax - ymin ) < 0.9*( this->yhi - this->ylo ) ){ - -/* Find a new grid dimension which results in a cell size similar to - the one used to create the grid, but covering only the region containing - good physical coordinates. */ - *dim *= astMAX( (xmax - xmin)/(this->xhi - this->xlo), - (ymax - ymin)/(this->yhi - this->ylo) ); - if( *dim < 32 ) *dim = 32; - -/* Annul the PointSet holding the current grid. */ - *pset1 = astAnnul( *pset1 ); - *pset2 = astAnnul( *pset2 ); - -/* Create the new grid covering the region containing good physical - coordinates. */ - (void) MakeGrid( this, frm, map, 1, *dim, xmin, xmax, ymin, ymax, 2, - pset1, pset2, 0, method, class, status ); - } - } - -/* Annul the Mapping from base to current Frame, and the pointer to the - Current Frame. */ - map = astAnnul( map ); - frm = astAnnul( frm ); - -/* If an error has occurred, annul the two pointsets and indicate that - there are no good points in the plotting area. */ - if( !astOK ){ - *pset1 = astAnnul( *pset1 ); - *pset2 = astAnnul( *pset2 ); - frac = 0.0; - } - -/* Return. */ - return frac; - -} - -static int GraphGrid( int dim, int disk, double xlo, double xhi, double ylo, - double yhi, double **ptr1, int *status ){ -/* -* Name: -* GraphGrid - -* Purpose: -* Fill an array with a square grid of graphics coordinates. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GraphGrid( int dim, int disk, double xlo, double xhi, double ylo, -* double yhi, double **ptr1, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function fills the supplied array with a square grid of graphics -* coordinates covering the supplied area. The points are stored row by -* row, i.e. if the cell size for the grid is (dx,dy), the first point -* is (xmin,ymin), followed by (xmin+dx,ymin), (xmin+2*dx,ymin), up to -* (xmin+(dim-1)*dx,ymin), followed by the next row (xmin,ymin+dy), -* (xmin+dx,ymin+dy), etc. - -* Parameters: -* dim -* The number of samples along each edge of the grid. -* disk -* If non-zero, the corners of the grid are omitted, resulting in a -* grid that is more disk like than rectangular. -* xlo -* The lower bound on the first axis of the region to be covered -* by the grid. -* xhi -* The upper bound on the first axis of the region to be covered -* by the grid. -* ylo -* The lower bound on the second axis of the region to be covered -* by the grid. -* yhi -* The upper bound on the second axis of the region to be covered -* by the grid. -* ptr1 -* A pointer to an array of two pointers giving the start of the two -* arrays to receive the values for each of the two axes of the graphics -* coordinate data. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of points in the grid. If "disk" is zero, this will be -* the square of "dim". If "disk" is non-zero, this will be less than -* the square of "dim" to account for the lack of corner points. - -*/ - -/* Local Variables: */ - double *px; - double *py; - double cen; - double dx; - double dy2; - double dy; - double dx2; - double r2; - double y; - int i; - int j; - int ok; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Find the cell size. */ - dx = ( xhi - xlo )/(double)( dim - 1 ); - dy = ( yhi - ylo )/(double)( dim - 1 ); - -/* Store the mid cell index. */ - cen = 0.5*( dim - 1 ); - -/* Store the squared radius of the disk. */ - r2 = 1.9*cen*cen; - -/* Initialise pointers to the start of the two arrays to recieve the - returned graphics values for each axis. */ - px = ptr1[ 0 ]; - py = ptr1[ 1 ]; - -/* Loop round row. */ - for( j = 0; j < dim; j++ ){ - dy2 = j - cen; - dy2 *= dy2; - -/* Get the Y coordinate of the current row. */ - y = ylo + j*dy; - -/* Loop round each column in the current row. */ - for( i = 0; i < dim; i++ ){ - -/* If we are forming a disk rather than a square, check if this point is - sufficiently close to the centre to be included in the disk. */ - if( disk ) { - dx2 = i - cen; - dx2 *= dx2; - ok = ( dx2 + dy2 <= r2 ); - } else { - ok = 1; - } - -/* Store the coordinates of the current grid point. */ - if( ok ) { - *(px++) = xlo + i*dx; - *(py++) = y; - } - } - } - -/* Return the used length of the PointSet. */ - return (int)( px - ptr1[ 0 ] ); -} - -static void GrfPop( AstPlot *this, int *status ) { -/* -*++ -* Name: -c astGrfPop -f AST_GRFPOP - -* Purpose: -* Restore previously saved graphics functions used by a Plot. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astGrfPop( AstPlot *this ) -f CALL AST_GRFPOP( THIS STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function restores a snapshot of the graphics functions -c stored previously by calling astGrfPush. The restored graphics -c functions become the current graphics functions used by the Plot. -* -c The astGrfPush and astGrfPop functions are intended for situations -c where it is necessary to make temporary changes to the graphics -c functions used by the Plot. The current functions should first be -c saved by calling astGrfPush. New functions should then be registered -c using astGrfSet. The required graphics should then be produced. -c Finally, astGrfPop should be called to restore the original graphics -c functions. -f The AST_GRFPUSH and AST_GRFPOP functions are intended for situations -f where it is necessary to make temporary changes to the graphics -f functions used by the Plot. The current functions should first be -f saved by calling AST_GRFPUSH. New functions should then be registered -f using AST_GRFSET. The required graphics should then be produced. -f Finally, AST_GRFPOP should be called to restore the original graphics -f functions. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -f - This routine returns without action if there are no snapshots to -c - This function returns without action if there are no snapshots to -* restore. No error is reported in this case. - -*-- -*/ - -/* Local Variables: */ - AstGrfPtrs *newframe; /* Pointer to the stack frame to restore */ - int i; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check the stack is not already empty. */ - if( this->grfnstack > 0 ) { - this->grfnstack--; - - if( astOK ) { - newframe = this->grfstack + this->grfnstack; - - for( i = 0; i < AST__NGRFFUN; i++ ) { - this->grffun[i] = (newframe->grffun)[i]; - } - this->GAttr = newframe->GAttr; - this->GBBuf = newframe->GBBuf; - this->GEBuf = newframe->GEBuf; - this->GFlush = newframe->GFlush; - this->GLine = newframe->GLine; - this->GMark = newframe->GMark; - this->GText = newframe->GText; - this->GCap = newframe->GCap; - this->GTxExt = newframe->GTxExt; - this->GScales = newframe->GScales; - this->GQch = newframe->GQch; - } - } -} - -static void GrfPush( AstPlot *this, int *status ) { -/* -*++ -* Name: -c astGrfPush -f AST_GRFPUSH - -* Purpose: -* Save the current graphics functions used by a Plot. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astGrfPush( AstPlot *this ) -f CALL AST_GRFPUSH( THIS STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function takes a snapshot of the graphics functions which are -f This routine takes a snapshot of the graphics functions which are -* currently registered with the supplied Plot, and saves the snapshot -* on a first-in-last-out stack within the Plot. The snapshot can be -* restored later using function -c astGrfPop. -f AST_GRFPOP. -* -c The astGrfPush and astGrfPop functions are intended for situations -c where it is necessary to make temporary changes to the graphics -c functions used by the Plot. The current functions should first be -c saved by calling astGrfPush. New functions should then be registered -c using astGrfSet. The required graphics should then be produced. -c Finally, astGrfPop should be called to restore the original graphics -c functions. -f The AST_GRFPUSH and AST_GRFPOP functions are intended for situations -f where it is necessary to make temporary changes to the graphics -f functions used by the Plot. The current functions should first be -f saved by calling AST_GRFPUSH. New functions should then be registered -f using AST_GRFSET. The required graphics should then be produced. -f Finally, AST_GRFPOP should be called to restore the original graphics -f functions. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - AstGrfPtrs *newframe; /* Pointer to the new stack frame */ - int i; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Increment the number of frames on the stack. */ - this->grfnstack++; - -/* Ensure the stack is large enough to hold this many frames. */ - this->grfstack = (AstGrfPtrs *) astGrow( (void *) this->grfstack, - this->grfnstack, sizeof( AstGrfPtrs ) ); - if( astOK ) { - -/* Get a pointer to the new stack frame. */ - newframe = this->grfstack + this->grfnstack - 1; - -/* Copy the graphics function pointers from the main Plot attributes - to the new stack frame. */ - for( i = 0; i < AST__NGRFFUN; i++ ) { - (newframe->grffun)[i] = this->grffun[i]; - } - newframe->GAttr = this->GAttr; - newframe->GBBuf = this->GBBuf; - newframe->GEBuf = this->GEBuf; - newframe->GFlush = this->GFlush; - newframe->GLine = this->GLine; - newframe->GMark = this->GMark; - newframe->GText = this->GText; - newframe->GCap = this->GCap; - newframe->GTxExt = this->GTxExt; - newframe->GQch = this->GQch; - newframe->GScales = this->GScales; - } -} - -static void GrfSet( AstPlot *this, const char *name, AstGrfFun fun, int *status ){ -/* -*++ -* Name: -c astGrfSet -f AST_GRFSET - -* Purpose: -c Register a graphics function for use by a Plot. -f Register a graphics routine for use by a Plot. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astGrfSet( AstPlot *this, const char *name, AstGrfFun fun ) -f CALL AST_GRFSET( THIS, NAME, FUN, STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function can be used to select the underlying graphics -c functions to be used when the supplied Plot produces graphical output. -c If this function is not called prior to producing graphical -c output, then the underlying graphics functions selected at -c link-time (using the ast_link command) will be used. To use -c alternative graphics functions, call this function before -c the graphical output is created, specifying the graphics -c functions to be used. This will register the function for future -c use, but the function will not actually be used until the Grf -c attribute is given a non-zero value. -f This routine can be used to select the underlying graphics -f routines to be used when the supplied Plot produces graphical output. -f If this routine is not called prior to producing graphical -f output, then the underlying graphics routines selected at -f link-time (using the ast_link command) will be used. To use -f alternative graphics routines, call this routine before -f the graphical output is created, specifying the graphics -f routines to be used. This will register the routine for future -f use, but the routine will not actually be used until the Grf -f attribute is given a non-zero value. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c name -f NAME = CHARACTER * ( * ) (Given) -c A name indicating the graphics function to be replaced. -c Various graphics functions are used by the -c Plot class, and any combination of them may be supplied by calling -c this function once for each function to be replaced. If any of the -c graphics functions are not replaced in this way, the -c corresponding functions in the graphics interface selected at -c link-time (using the ast_link command) are used. The allowed -c names are: -f A name indicating the graphics routine to be replaced. -f Various graphics routines are used by the -f Plot class, and any combination of them may be supplied by calling -f this routine once for each routine to be replaced. If any of the -f graphics routines are not replaced in this way, the -f corresponding routines in the graphics interface selected at -f link-time (using the ast_link command) are used. The allowed -f function names are: -* -* - Attr - Enquire or set a graphics attribute value -* - BBuf - Start a new graphics buffering context -* - Cap - Inquire a capability -* - EBuf - End the current graphics buffering context -* - Flush - Flush all pending graphics to the output device -* - Line - Draw a polyline (i.e. a set of connected lines) -* - Mark - Draw a set of markers -* - Qch - Return the character height in world coordinates -* - Scales - Get the axis scales -* - Text - Draw a character string -* - TxExt - Get the extent of a character string -* -* The string is case insensitive. For details of the interface -* required for each, see the sections below. -c fun -f FUN = INTEGER FUNCTION (Given) -c A Pointer to the function to be used to provide the -c functionality indicated by parameter name. The interface for -c each function is described below, but the function pointer should -c be cast to a type of AstGrfFun when calling astGrfSet. -f The name of the routine to be used to provide the -f functionality indicated by parameter NAME (the name -f should also appear in a Fortran EXTERNAL statement in the -f routine which invokes AST_GRFSET). -* -c Once a function has been provided, a null pointer can be supplied -c in a subsequent call to astGrfSet to reset the function to the -c corresponding function in the graphics interface selected at -c link-time. -f Once a routine has been provided, the "null" routine AST_NULL can -f be supplied in a subsequent call to astGrfSet to reset the routine -f to the corresponding routine in the graphics interface selected at -f link-time. AST_NULL is defined in the AST_PAR include file. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Function Interfaces: -* All the functions listed below (except for "Cap") should return an -* integer value of 0 if an error occurs, and 1 otherwise. All x and y -* values refer -f to "graphics cordinates" as defined by the GRAPHBOX parameter of -f the AST_PLOT call which created the Plot. -c to "graphics cordinates" as defined by the graphbox parameter of -c the astPlot call which created the Plot. -* -c The first parameter ("grfcon") -f The first argument (GRFCON) -* for each function is an AST KeyMap pointer that can be used by the -* called function to establish the context in which it is being called. -* The contents of the KeyMap are determined by the calling -* application, which should obtain a pointer to the KeyMap using the -f AST_GETGRFCONTEXT routine, -c astGetGrfContext function, -* and then store any necessary information in the KeyMap using the -* methods of the KeyMap class. Note, the functions listed below -* should never annul or delete the supplied KeyMap pointer. - -* Attr: -* The "Attr" function returns the current value of a specified graphics -* attribute, and optionally establishes a new value. The supplied -* value is converted to an integer value if necessary before use. -* It requires the following interface: -* -c int Attr( AstObject *grfcon, int attr, double value, double *old_value, int prim ) -f INTEGER FUNCTION ATTR( GRFCON, ATT, VAL, OLDVAL, PRIM ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - attr - An integer value identifying the required attribute. -c The following symbolic values are defined in grf.h: -f - ATT = INTEGER (Given) - An integer identifying the required attribute. -f The following symbolic values are defined in GRF_PAR: -* GRF__STYLE (Line style), -* GRF__WIDTH (Line width), -* GRF__SIZE (Character and marker size scale factor), -* GRF__FONT (Character font), -* GRF__COLOUR (Colour index). -c - value - -f - VAL = DOUBLE PRECISION (Given) - -c A new value to store for the attribute. If this is AST__BAD -* no value is stored. -c - old_value - A pointer to a double in which to return -f - OLDVAL = DOUBLE PRECISION (Returned) - Returned holding -* the attribute value. -c If this is NULL, no value is returned. -c - prim - -f - PRIM = INTEGER (Given) - -* The sort of graphics primitive to be drawn with the new attribute. -c Identified by the following values defined in grf.h: -f Identified by the following values defined in GRF_PAR: -* GRF__LINE, -* GRF__MARK, -* GRF__TEXT. - -* BBuf: -* The "BBuf" function should start a new graphics buffering context. -* A matching call to the function "EBuf" should be used to end the -* context. The nature of the buffering is determined by the underlying -* graphics system. -* -c int BBuf( AstObject *grfcon ) -f INTEGER FUNCTION BBUF( GRFCON ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. - -* Cap: -* The "Cap" function is called to determine if the grf module has a -* given capability, as indicated by the "cap" argument: -* -c int Cap( AstObject *grfcon, int cap, int value ) -f INTEGER FUNCTION CAP( GRFCON, CAP, VALUE ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - cap - -f - CAP = INTEGER (Given) -* The capability being inquired about. This will be one of the -c following constants defined in grf.h: -f following constants defined in GRF_PAR: -* -* GRF__SCALES: This function should return a non-zero value if the -* "Scales" function is implemented, and zero otherwise. The supplied -c "value" argument should be ignored. -f VALUE argument should be ignored. -* -* GRF__MJUST: This function should return a non-zero value if -* the "Text" and "TxExt" functions recognise "M" as a -* character in the justification string. If the first character of -* a justification string is "M", then the text should be justified -* with the given reference point at the bottom of the bounding box. -* This is different to "B" justification, which requests that the -* reference point be put on the baseline of the text, since some -* characters hang down below the baseline. If the "Text" or -* "TxExt" function cannot differentiate between "M" and "B", -* then this function should return zero, in which case "M" -* justification will never be requested by Plot. The supplied -c "value" argument should be ignored. -f VALUE argument should be ignored. -* -* GRF__ESC: This function should return a non-zero value if the -* "Text" and "TxExt" functions can recognise and interpret -* graphics escape sequences within the supplied string (see -* attribute Escape). Zero should be returned if escape sequences -* cannot be interpreted (in which case the Plot class will interpret -c them itself if needed). The supplied "value" argument should be -f them itself if needed). The supplied VALUE argument should be -* ignored only if escape sequences cannot be interpreted by "Text" and -c "TxExt". Otherwise, "value" indicates whether "Text" and "TxExt" -c should interpret escape sequences in subsequent calls. If "value" is -f "TxExt". Otherwise, VALUE indicates whether "Text" and "TxExt" -f should interpret escape sequences in subsequent calls. If VALUE is -* non-zero then escape sequences should be interpreted by "Text" and -* "TxExt". Otherwise, they should be drawn as literal text. -* -c - value - -f - VALUE = INTEGER (Given) -c The use of this parameter depends on the value of "cap" as -f The use of this parameter depends on the value of CAP as -* described above. - -* - Returned Function Value: -c The value returned by the function depends on the value of "cap" -f The value returned by the function depends on the value of CAP -* as described above. Zero should be returned if the supplied -* capability is not recognised. - -* EBuf: -* The "EBuf" function should end the current graphics buffering -* context. See the description of "BBuf" above for further details. -* It requires the following interface: -* -c int EBuf( AstObject *grfcon ) -f INTEGER FUNCTION EBUF( GRFCON ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. - -* Flush: -* The "Flush" function ensures that the display device is up-to-date, -* by flushing any pending graphics to the output device. It -* requires the following interface: -* -c int Flush( AstObject *grfcon ) -f INTEGER FUNCTION FLUSH( GRFCON ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. - -* Line: -* The "Line" function displays lines joining the given positions and -* requires the following interface: -* -c int Line( AstObject *grfcon, int n, const float *x, const float *y ) -f INTEGER FUNCTION LINE( GRFCON, N, X, Y ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - n - The number of positions to be joined together. -f - N = INTEGER (Given) - The number of positions to be joined together. -c - x - A pointer to an array holding the "n" x values. -f - X( N ) = REAL (Given) - An array holding the "n" x values. -c - y - A pointer to an array holding the "n" y values. -f - Y( N ) = REAL (Given) - An array holding the "n" y values. - -* Mark: -* The "Mark" function displays markers at the given positions. It -* requires the following interface: -* -c int Mark( AstObject *grfcon, int n, const float *x, const float *y, int type ) -f INTEGER FUNCTION MARK( GRFCON, N, X, Y, TYPE ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - n - The number of positions to be marked. -f - N = INTEGER (Given) - The number of positions to be marked. -c - x - A pointer to an array holding the "n" x values. -f - X( N ) = REAL (Given) - An array holding the "n" x values. -c - y - A pointer to an array holding the "n" y values. -f - Y( N ) = REAL (Given) - An array holding the "n" y values. -c - type - An integer which can be used to indicate the type of marker -c symbol required. -f - TYPE = INTEGER (Given) - An integer which can be used to indicate -f the type of marker symbol required. - -* Qch: -* The "Qch" function returns the heights of characters drawn vertically -* and horizontally in graphics coordinates. It requires the following -* interface: -* -c int Qch( AstObject *grfcon, float *chv, float *chh ) -f INTEGER FUNCTION QCH( GRFCON, CHV, CHH ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - chv - A pointer to the float which is to receive the height of -f - CHV = REAL (Returned) The height of -* characters drawn with a vertical baseline. This will be an -* increment in the X axis. -c - chh - A pointer to the float which is to receive the height of -f - CHH = REAL (Returned) The height of -* characters drawn with a horizontal baseline. This will be an -* increment in the Y axis. - -* Scales: -* The "Scales" function returns two values (one for each axis) which -* scale increments on the corresponding axis into a "normal" coordinate -* system in which: 1) the axes have equal scale in terms of (for instance) -* millimetres per unit distance, 2) X values increase from left to -* right, and 3) Y values increase from bottom to top. It requires the -* following interface: -* -c int Scales( AstObject *grfcon, float *alpha, float *beta ) -f INTEGER FUNCTION SCALES( GRFCON, ALPHA, BETA ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - alpha - A pointer to the float which is to receive the -f - ALPHA = REAL (Returned) The -* scale for the X axis (i.e. Xnorm = alpha*Xworld). -c - beta - A pointer to the float which is to receive the -f - BETA = REAL (Returned) The -* scale for the Y axis (i.e. Ynorm = beta*Yworld). - -* Text: -* The "Text" function displays a character string at a given -* position using a specified justification and up-vector. It -* requires the following interface: -* -c int Text( AstObject *grfcon, const char *text, float x, float y, const char *just, -c float upx, float upy ) -f INTEGER FUNCTION TEXT( GRFCON, TEXT, X, Y, JUST, UPX, UPY ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - text - Pointer to a null-terminated character string to be displayed. -f - TEXT = CHARACTER * ( * ) (Given) - The string to be displayed. -c - x - The reference x coordinate. -f - X = REAL (Given) - The reference x coordinate. -c - y - The reference y coordinate. -f - Y = REAL (Given) - The reference y coordinate. -c - just - A character string which specifies the location within the -f - JUST = CHARACTER * ( * ) (Given ) - A string which specifies the -f location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -c - upx - The x component of the up-vector for the text. -f - UPX = REAL (Given) - The x component of the up-vector for the text. -* If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -c - upy - The y component of the up-vector for the text. -f - UPX = REAL (Given) - The y component of the up-vector for the text. -* If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. - -* TxExt: -* The "TxExt" function returns the corners of a box which would enclose -* the supplied character string if it were displayed using the -* Text function described above. The returned box includes any leading -* or trailing spaces. It requires the following interface: -* -c int TxExt( AstObject *grfcon, const char *text, float x, float y, const char *just, -c float upx, float upy, float *xb, float *yb ) -f INTEGER FUNCTION TXEXT( GRFCON, TEXT, X, Y, JUST, UPX, UPY, XB, YB ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - text - Pointer to a null-terminated character string to be displayed. -f - TEXT = CHARACTER * ( * ) (Given) - The string to be displayed. -c - x - The reference x coordinate. -f - X = REAL (Given) - The reference x coordinate. -c - y - The reference y coordinate. -f - Y = REAL (Given) - The reference y coordinate. -c - just - A character string which specifies the location within the -f - JUST = CHARACTER * ( * ) (Given ) - A string which specifies the -f location within the -* text string which is to be placed at the reference position -* given by x and y. See "Text" above. -c - upx - The x component of the up-vector for the text. -f - UPX = REAL (Given) - The x component of the up-vector for the text. -* See "Text" above. -c - upy - The y component of the up-vector for the text. -f - UPX = REAL (Given) - The y component of the up-vector for the text. -* See "Text" above. -c - xb - An array of 4 elements in which to return the x coordinate of -f - XB( 4 ) = REAL (Returned) - Returned holding the x coordinate of -* each corner of the bounding box. -c - yb - An array of 4 elements in which to return the y coordinate of -f - YB( 4 ) = REAL (Returned) - Returned holding the y coordinate of -* each corner of the bounding box. - -*-- -*/ - -/* Local Variables: */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int ifun; /* Index into grf function list */ - void (* wrapper)(); /* Wrapper function for C Grf routine*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - wrapper = NULL; - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astGrfSet"; - class = astClass( this ); - -/* Identify the supplied function name and get its integer index into the - list of grf functions. */ - ifun = astGrfFunID( name, method, class ); - -/* Store the pointer. */ - if( astOK ) { - this->grffun[ifun] = fun; - -/* In general, the interface to each Grf function will differ for - different languages. So we need a wrapper function with a known fixed - interface which can be used to invoke the actual Grf function with - an interface suited to the language in use. Call astGrfWrapper to store - a wrapper to a suitable function which can invoke the supplied - grf function. Here, we assume that the supplied function has a C - interface, so we set up a C wrapper. If this function is being called - from another language, then the interface for this function within - that language should set up an appropriate wrapper after calling this - function, thus over-riding the C wrapper set up here. */ - if( ifun == AST__GATTR ) { - wrapper = (AstGrfWrap) CGAttrWrapper; - - } else if( ifun == AST__GBBUF ) { - wrapper = (AstGrfWrap) CGBBufWrapper; - - } else if( ifun == AST__GEBUF ) { - wrapper = (AstGrfWrap) CGEBufWrapper; - - } else if( ifun == AST__GFLUSH ) { - wrapper = (AstGrfWrap) CGFlushWrapper; - - } else if( ifun == AST__GLINE ) { - wrapper = (AstGrfWrap) CGLineWrapper; - - } else if( ifun == AST__GMARK ) { - wrapper = (AstGrfWrap) CGMarkWrapper; - - } else if( ifun == AST__GTEXT ) { - wrapper = (AstGrfWrap) CGTextWrapper; - - } else if( ifun == AST__GCAP ) { - wrapper = (AstGrfWrap) CGCapWrapper; - - } else if( ifun == AST__GTXEXT ) { - wrapper = (AstGrfWrap) CGTxExtWrapper; - - } else if( ifun == AST__GSCALES ) { - wrapper = (AstGrfWrap) CGScalesWrapper; - - } else if( ifun == AST__GQCH ) { - wrapper = (AstGrfWrap) CGQchWrapper; - - } else if( astOK ) { - astError( AST__INTER, "%s(%s): AST internal programming error - " - "Grf function id %d not yet supported.", status, method, class, - ifun ); - } - astGrfWrapper( this, name, wrapper ); - } -} - -int astGrfFunID_( const char *name, const char *method, const char *class, int *status ) { -/* -*+ -* Name: -* astGrfFunID - -* Purpose: -* Return the integer identifier for a given GRF routine. - -* Type: -* Hidden public function. - -* Synopsis: -* #include "plot.h" -* int astGrfFunID( const char *name, const char *method, -* const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* This function returns an integer identifying the named grf function. -* An error is reported if the named function is unknown. This function -* is used by non-class modules within AST (e.g. fplot.c) which is why -* it is public. It is not intended to be used by the public. - -* Parameters: -* name -* The grf function name. Any unambiguous abbreviation will do. -* Case is ignored. The full list of grf function names is: -* "Attr BBuf EBuf Scales Flush Line Mark Qch Text TxExt". See -* grf_pgplot.c for details of these functions. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -*- -*/ - -/* Note that the list of identifiers here must be in the same order as the - sorted values of the constants AST__GATTR, AST__GFLUSH, etc */ - return FullForm( "Attr Flush Line Mark Text TxExt Scales Qch Cap BBuf " - "EBuf", name, "Grf function name (programming error)", - method, class, status ); -} - -static char *GrfItem( int item, const char *text, int *axis, int *status ){ -/* -* Name: -* GrfItem - -* Purpose: -* Return the textual name corresponding to a specified graphical item -* index. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* char *GrfItem( int item, const char *text, int *axis, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function returns a textual description of the graphical item -* with the supplied index. - -* Parameters: -* item -* The index of the graphical item. -* text -* A pointer to a string which will be appended to the textual -* description of the graphical item. May be NULL. -* axis -* Pointer to a place in which to return the index (0,1, or 2) of -* the axis to which the attribute refers, If the attribute does -* not refer to a specific axis, -1 is returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated string holding the textual -* description of the graphical item, followed by any supplied "text". - -* Notes: -* - An error is reported and a NULL pointer returned if the -* index does not correspond to any graphical item. -* - The returned pointer should be freed using astFree when it is no -* longer needed. -* - This function attempts to execute even if an error has already -* occurred. - -*/ - -/* Local Variables: */ - char *desc; /* Pointer to the item description */ - char *ret; /* Pointer to the returned string */ - int dlen; /* Length of the item description */ - - if( axis ) *axis = -1; - - if( item == AST__BORDER_ID ) { - desc = "Border"; - - } else if ( item == AST__GRIDLINE_ID ) { - desc = "Gridline"; - - } else if ( item == AST__GRIDLINE1_ID ) { - desc = "Axis 1 gridline"; - if( axis ) *axis = 0; - - } else if ( item == AST__GRIDLINE2_ID ) { - desc = "Axis 2 gridline"; - if( axis ) *axis = 1; - - } else if ( item == AST__GRIDLINE3_ID ) { - desc = "Axis 3 gridline"; - if( axis ) *axis = 2; - - } else if ( item == AST__CURVE_ID ) { - desc = "Curve"; - - } else if ( item == AST__NUMLABS_ID ) { - desc = "Numerical labels"; - - } else if ( item == AST__TEXTLABS_ID ) { - desc = "Textual labels"; - - } else if ( item == AST__TITLE_ID ) { - desc = "Title"; - - } else if ( item == AST__MARKS_ID ) { - desc = "Markers"; - - } else if ( item == AST__TEXT_ID ) { - desc = "Text string"; - - } else if ( item == AST__TICKS_ID ) { - desc = "Major and minor ticks"; - - } else if ( item == AST__AXIS1_ID ) { - desc = "Axis 1"; - if( axis ) *axis = 0; - - } else if ( item == AST__AXIS2_ID ) { - desc = "Axis 2"; - if( axis ) *axis = 1; - - } else if ( item == AST__AXIS3_ID ) { - desc = "Axis 3"; - if( axis ) *axis = 2; - - } else if ( item == AST__NUMLAB1_ID ) { - desc = "Axis 1 numerical labels"; - if( axis ) *axis = 0; - - } else if ( item == AST__NUMLAB2_ID ) { - desc = "Axis 2 numerical labels"; - if( axis ) *axis = 1; - - } else if ( item == AST__NUMLAB3_ID ) { - desc = "Axis 3 numerical labels"; - if( axis ) *axis = 2; - - } else if ( item == AST__TEXTLAB1_ID ) { - desc = "Axis 1 textual label"; - if( axis ) *axis = 0; - - } else if ( item == AST__TEXTLAB2_ID ) { - desc = "Axis 2 textual label"; - if( axis ) *axis = 1; - - } else if ( item == AST__TEXTLAB3_ID ) { - desc = "Axis 3 textual label"; - if( axis ) *axis = 2; - - } else if ( item == AST__TICKS1_ID ) { - desc = "Axis 1 tick marks"; - if( axis ) *axis = 0; - - } else if ( item == AST__TICKS2_ID ) { - desc = "Axis 2 tick marks"; - if( axis ) *axis = 1; - - } else if ( item == AST__TICKS3_ID ) { - desc = "Axis 3 tick marks"; - if( axis ) *axis = 2; - - } else { - desc = NULL; - if( astOK ){ - astError( AST__INTER, "GrfItem: AST internal programming error - " - "Invalid graphical item index %d supplied to GrfItem.", status, - item ); - } - } - - if( desc ) { - dlen = strlen( desc ); - - if( text ) { - ret = astStore( NULL, desc, dlen + strlen( text ) + 1 ); - if( ret ) strcpy( ret + dlen, text ); - } else { - ret = astStore( NULL, desc, dlen + 1 ); - } - - } else { - ret = NULL; - } - -/* Return the answer. */ - return ret; -} - -static void GrfWrapper( AstPlot *this, const char *name, AstGrfWrap wrapper, int *status ) { -/* -*+ -* Name: -* astGrfWrapper - -* Purpose: -* Register a wrapper function for a F77 or C Grf function. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* void astGrfWrapper( AstPlot *this, const char *name, AstGrfWrap wrapper) - -* Description: -* This function stores a pointer to the supplied wrapper function -* within the plot, associating it with the grf function indicated by -* the "name" parameter. The supplied wrapper function should call the -* named grf function, using an interface appropriate to the language -* in which the grf function is written. - -* Parameters: -* this -* The plot. -* name -* A name indicating the graphics function which is called by the -* supplied wrapper function. See astGrfSet for details. -* wrapper -* A pointer to the wrapper function. This will be cast to a -* specific type for the named grf function before being store -* in the Plot. -*- -*/ - -/* Local Variables: */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int ifun; /* Index into grf function list */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astGrfWrapper"; - class = astClass( this ); - -/* Identify the supplied function name and get its integer index into the - list of grf functions. */ - ifun = astGrfFunID( name, method, class ); - -/* Cast the wrapper to an interface appropriate for the wrapped grf - function, and store it in the appropriate component of the Plot. */ - if( ifun == AST__GATTR ) { - this->GAttr = (AstGAttrWrap) wrapper; - - } else if( ifun == AST__GBBUF ) { - this->GBBuf = (AstGBBufWrap) wrapper; - - } else if( ifun == AST__GEBUF ) { - this->GEBuf = (AstGEBufWrap) wrapper; - - } else if( ifun == AST__GFLUSH ) { - this->GFlush = (AstGFlushWrap) wrapper; - - } else if( ifun == AST__GLINE ) { - this->GLine = (AstGLineWrap) wrapper; - - } else if( ifun == AST__GMARK ) { - this->GMark = (AstGMarkWrap) wrapper; - - } else if( ifun == AST__GTEXT ) { - this->GText = (AstGTextWrap) wrapper; - - } else if( ifun == AST__GCAP ) { - this->GCap = (AstGCapWrap) wrapper; - - } else if( ifun == AST__GTXEXT ) { - this->GTxExt = (AstGTxExtWrap) wrapper; - - } else if( ifun == AST__GSCALES ) { - this->GScales = (AstGScalesWrap) wrapper; - - } else if( ifun == AST__GQCH ) { - this->GQch = (AstGQchWrap) wrapper; - - } else if( astOK ) { - astError( AST__INTER, "%s(%s): AST internal programming error - " - "Grf function id %d not yet supported.", status, method, class, - ifun ); - } -} - -static void Grid( AstPlot *this_nd, int *status ){ -/* -*++ -* Name: -c astGrid -f AST_GRID - -* Purpose: -* Draw a set of labelled coordinate axes. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astGrid( AstPlot *this ) -f CALL AST_GRID( THIS, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a complete annotated set of -f This routine draws a complete annotated set of -* coordinate axes for a Plot with (optionally) a coordinate grid -* superimposed. Details of the axes and grid can be controlled by -* setting values for the various attributes defined by the Plot -* class (q.v.). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the supplied Plot is a Plot3D, the axes will be annotated -* using three 2-dimensional Plots, one for each 2D plane in the 3D -* current coordinate system. The plots will be "pasted" onto 3 faces -* of the cuboid graphics volume specified when the Plot3D was -* constructed. The faces to be used can be controlled by the "RootCorner" -* attribute. -* - An error results if either the current Frame or the base Frame -* of the Plot is not 2-dimensional or (for a Plot3D) 3-dimensional. -* - An error also results if the transformation between the base -* and current Frames of the Plot is not defined in either -* direction (i.e. the Plot's TranForward or TranInverse attribute -* is zero). -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPlot *this; /* Plot with 2d current Frame */ - AstPlotCurveData **cdata;/* Pointer to info. about breaks in curves */ - TickInfo **grid; /* Pointer to info. about tick marks */ - const char *class; /* Object class */ - const char *method; /* Current method */ - double cen[ 2 ]; /* Position of first tick mark */ - double gap[ 2 ]; /* Gap between tick marks */ - double labelat[ 2 ]; /* Axis values at which tick marks are put */ - int axis; /* Physical axis index */ - int border; /* Draw a border? */ - int clip; /* Original Clip attribute value */ - int dounits[2]; /* Include Units in each axis label? */ - int drawgrid; /* Is a grid of lines to be drawn? */ - int clredge; /* Clear the Edge attributes before returning? */ - int edgeticks; /* Draw labels round edges of plotting area? */ - int escs; /* Original astEscapes value */ - int ink; /* Draw the grid with visible ink? */ - int inval; /* Were areas of invalid coordinates found? */ - int labelling; /* Value of Labelling attribute */ - int loglabelset[2]; /* Were the LogLabel attributes set initially? */ - int logticksset[2]; /* Were the LogTicks attributes set initially? */ - int naxes; /* No. of axes in the base or current Frame */ - int oldedge0; /* Default value for Edge(1) */ - int oldedge1; /* Default value for Edge(2) */ - int useint; /* Do interior labels give us an advantage? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_nd); - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astGrid"; - class = astClass( this_nd ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this_nd ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Ensure AST functions included graphical escape sequences in any - returned text strings. */ - escs = astEscapes( 1 ); - -/* Note if attributes which have complex dynamic defaults are set - initially. */ - logticksset[0] = astTestLogTicks( this_nd, 0 ); - logticksset[1] = astTestLogTicks( this_nd, 1 ); - loglabelset[0] = astTestLogLabel( this_nd, 0 ); - loglabelset[1] = astTestLogLabel( this_nd, 1 ); - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Get a Plot with a 2D (or 1D) current Frame. */ - this = (AstPlot *) Fset2D( (AstFrameSet *) this_nd, AST__CURRENT, status ); - -/* Check the current Frame of the Plot is 2-D. */ - naxes = astGetNout( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the current " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Ensure that all lines are clipped at the plot boundary.*/ - if( astTestClip( this ) ) { - clip = astGetClip( this ); - astSetClip( this, 1 ); - } else { - clip = -1; - } - -/* If the protected attribute "Ink" is set to zero, then the plot - is drawn in "invisble ink" (i.e. all the calculations needed to - produce the grid are performed, but nothing is actually drawn). */ - ink = astGetInk( this ); - -/* Initialise the bounds of the box containing all plotted lines and - numerical labels. */ - Box_lbnd[ 0 ] = FLT_MAX; - Box_lbnd[ 1 ] = FLT_MAX; - Box_ubnd[ 0 ] = FLT_MIN; - Box_ubnd[ 1 ] = FLT_MIN; - -/* Obtain the requested centre attribute values for both physical axes. */ - for( axis = 0; axis < 2; axis++ ){ - cen[ axis ] = astGetCentre( this, axis ); - } - -/* Determine where to put the major axis values. */ - grid = GridLines( this, cen, gap, &inval, method, class, status ); - -/* If the user has set an explicit value for Grid, use it. */ - if( astTestGrid( this ) ){ - drawgrid = astGetGrid( this ); - -/* If not, the default for Grid is based on whether or not there are any - invalid regions. */ - } else if( inval ){ - drawgrid = 1; - - } else { - drawgrid = 0; - } - -/* Draw the curves marking the major tick values on each axis. Information - is returned describing the positions of the breaks in these curves. */ - cdata = DrawGrid( this, grid, ( ink && drawgrid ), method, class, status ); - -/* See if labels and tick marks will be drawn round the edges of the - plotting area, rather than within it (no labels are actually drawn - yet). Interior labels can always be produced, in which case edgeticks - is set explicitly to zero to indicate that ticks will be internal. - Exterior labelling may or may not be possible. If it is requested, - check to see if it is possible. */ - clredge = 0; - labelling = astGetLabelling( this ); - if( labelling ){ - edgeticks = 0; - } else { - edgeticks = EdgeLabels( this, 0, grid, cdata, 0, method, class, status ); - -/* If the external labelling was requested, but could not be produced... */ - if( !edgeticks ) { - -/* and if the Edge attributes have not been set... */ - if( !astTestEdge( this, 0 ) && !astTestEdge( this, 1 ) ) { - -/* Try flipping the default Edge values, to see if this allows us to - honour the requested Labelling scheme. */ - oldedge0 = astGetEdge( this, 0 ); - oldedge1 = astGetEdge( this, 1 ); - astSetEdge( this, 0, oldedge1 ); - astSetEdge( this, 1, oldedge0 ); - -/* See if exterior labels could be drawn with these new edges. */ - edgeticks = EdgeLabels( this, 0, grid, cdata, 0, method, class, status ); - -/* If this would allow us to use the requested labelling scheme, retain - the new Edge values, setting a flag to indicate that they will need to be - cleared before returning. Otherwise, clear them. */ - if( edgeticks ) { - clredge = 1; - - } else { - astClearEdge( this, 0 ); - astClearEdge( this, 1 ); - } - } - } - } - -/* If edge ticks can still not be produced, but the ForceExterior attribute - has a non-zero value, attempt to create exterior labels even though it - looks like there may be insufficient of them to justify their use. */ - if( !edgeticks && astGetForceExterior( this ) ) { - edgeticks = EdgeLabels( this, 0, grid, cdata, 1, method, class, status ); - } - -/* We may also need to swap edge values when using interior labelling in - order to ensure that the text labels are placed on appropriate edges of - the plotting box. */ - if( !edgeticks && !astTestEdge( this, 0 ) && !astTestEdge( this, 1 ) ) { - if( swapEdges( this, grid, cdata, status ) ) { - oldedge0 = astGetEdge( this, 0 ); - oldedge1 = astGetEdge( this, 1 ); - astSetEdge( this, 0, oldedge1 ); - astSetEdge( this, 1, oldedge0 ); - clredge = 1; - } - } - -/* If edge ticks are being used, store bad values for the labelat values to - indicate that labels are not being drawn within the interior of the - plotting area. */ - if( edgeticks ){ - labelat[ 0 ] = AST__BAD; - labelat[ 1 ] = AST__BAD; - -/* Otherwise, see where interior labels and tick marks should go (the axis - values are put in "labelat"). */ - } else { - useint = Labelat( this, grid, cdata, labelat, method, class, status ); - -/* If interior labelling does not allow us to draw any more ticks, revert - to edge labelling if that is what the user requested. */ - if( !useint && !labelling ) { - labelat[ 0 ] = AST__BAD; - labelat[ 1 ] = AST__BAD; - edgeticks = EdgeLabels( this, 0, grid, cdata, 1, method, class, status ); - } - } - -/* See if a border is required. By default, a border is drawn only when - using exterior labelling. */ - if( astTestBorder( this ) ) { - border = astGetBorder( this ); - } else { - border = edgeticks; - } - -/* See if the Units string is to be inluded in the label. */ - dounits[ 0 ] = astGetLabelUnits( this, 0 ); - dounits[ 1 ] = astGetLabelUnits( this, 1 ); - -/* The rest is not done if no output is required. */ - if( ink ) { - -/* Draw tick marks (major and minor). */ - DrawTicks( this, grid, drawgrid, labelat, gap, method, class, status ); - -/* If required, ensure that curves through the tick marks have been drawn */ - DrawAxis( this, grid, labelat, gap, method, class, status ); - -/* If required, draw a curve around the edge of the area containing valid - physical coordinates. */ - if( border ) (void) astBorder( this ); - -/* Draw the numerical labels at the major tick values. */ - Labels( this, grid, cdata, gap, labelat, method, class, status ); - -/* Draw the textual labels for each axis and a title. */ - TextLabels( this, edgeticks, dounits, method, class, status ); - } - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Store the actual values used for all attributes which have dynamic - defaults. Check the global status to ensure the pointer "grid" can be - used without the possibility of a segmentation violation. */ - for( axis = 0; axis < 2 && astOK ; axis++ ) { - SetUsedLogTicks( this_nd, axis, astGetLogTicks( this, axis ), status ); - SetUsedLogLabel( this_nd, axis, astGetLogLabel( this, axis ), status ); - - if( astGetLogTicks( this, axis ) ) { - SetUsedLogGap( this_nd, axis, gap[ axis ], status ); - } else { - SetUsedGap( this_nd, axis, gap[ axis ], status ); - } - SetUsedCentre( this_nd, axis, cen[ axis ], status ); - SetUsedEdge( this_nd, axis, astGetEdge( this, axis ), status ); - SetUsedLabelAt( this_nd, axis, labelat[ axis ], status ); - SetUsedLabelUnits( this_nd, axis, dounits[ axis ], status ); - -/* If explicit minor tick values were supplied using astSetTickValues, - then set MinTick to the average number of minor tick divisions per major - tick division. */ - if( grid[ axis ]->minticks ) { - SetUsedMinTick( this_nd, axis, - ( grid[ axis ]->nminor + grid[ axis ]->nmajor )/ - ( grid[ axis ]->nmajor - 1 ), status ); - } else { - SetUsedMinTick( this_nd, axis, grid[ axis ]->nminor, status ); - } - - if( astTestTextLab( this, axis ) ) { - SetUsedTextLab( this_nd, axis, astGetTextLab( this, axis ), status ); - } else { - SetUsedTextLab( this_nd, axis, edgeticks, status ); - } - - if( astTestMajTickLen( this, axis ) ) { - SetUsedMajTickLen( this_nd, axis, astGetMajTickLen( this, axis ), status ); - } else { - SetUsedMajTickLen( this_nd, axis, drawgrid ? 0.0 : - astGetMajTickLen( this, axis ), status ); - } - - } - - SetUsedGrid( this_nd, drawgrid, status ); - SetUsedLabelling( this_nd, edgeticks ? 0 : 1, status ); - SetUsedBorder( this_nd, border, status ); - -/* Free the memory used to hold information about the curves. */ - cdata = CleanCdata( cdata, status ); - -/* Free the memory used to hold information about the tick marks. */ - grid = CleanGrid( grid, status ); - -/* If required clear attributes. */ - if( clredge ) { - astClearEdge( this, 0 ); - astClearEdge( this, 1 ); - } - - if( !logticksset[ 0 ] ) astClearLogTicks( this, 0 ); - if( !logticksset[ 1 ] ) astClearLogTicks( this, 1 ); - if( !loglabelset[ 0 ] ) astClearLogLabel( this, 0 ); - if( !loglabelset[ 1 ] ) astClearLogLabel( this, 1 ); - -/* Restore the original value of the Clip attribute. */ - if( clip != -1 ) astSetClip( this, clip ); - -/* Free the 2D Plot. */ - this = astAnnul( this ); - -/* Restore the original value of the flag which says whether graphical - escape sequences should be incldued in any returned text strings. */ - astEscapes( escs ); - -/* Copy the total bounding box to the box which is returned by - astBoundingBox. */ - if( !Boxp_freeze ){ - Boxp_lbnd[ 0 ] = Box_lbnd[ 0 ]; - Boxp_lbnd[ 1 ] = Box_lbnd[ 1 ]; - Boxp_ubnd[ 0 ] = Box_ubnd[ 0 ]; - Boxp_ubnd[ 1 ] = Box_ubnd[ 1 ]; - } - -/* Return. */ - return; - -} - -static void GridLine( AstPlot *this, int axis, const double start[], - double length, int *status ){ -/* -*++ -* Name: -c astGridLine -f AST_GRIDLINE - -* Purpose: -* Draw a grid line (or axis) for a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astGridLine( AstPlot *this, int axis, const double start[], -c double length ) -f CALL AST_GRIDLINE( THIS, AXIS, START, LENGTH, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a curve in the physical coordinate system of -f This routine draws a curve in the physical coordinate system of -* a Plot by varying only one of the coordinates along the length -* of the curve. It is intended for drawing coordinate axes, -* coordinate grids, and tick marks on axes (but note that these -c are also available via the more comprehensive astGrid function). -f are also available via the more comprehensive AST_GRID routine). -* -* The curve is transformed into graphical coordinate space for -* plotting, so that a straight line in physical coordinates may -* result in a curved line being drawn if the Mapping involved is -* non-linear. Any discontinuities in the Mapping between physical -* and graphical coordinates are catered for, as is any -c clipping established using astClip. -f clipping established using AST_CLIP. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c axis -f AXIS = INTEGER (Given) -* The index of the Plot axis whose physical coordinate value is -* to be varied along the length of the curve (all other -* coordinates will remain fixed). This value should lie in the -* range from 1 to the number of Plot axes (Naxes attribute). -c start -f START( * ) = DOUBLE PRECISION (Given) -* An array, with one element for each axis of the Plot, giving -* the physical coordinates of the start of the curve. -c length -f LENGTH = DOUBLE PRECISION (Given) -* The length of curve to be drawn, given as an increment along -* the selected physical axis. This may be positive or negative. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - No curve is drawn if the "start" array contains any -c coordinates with the value AST__BAD, nor if "length" has this value. -f - No curve is drawn if the START array contains any -f coordinates with the value AST__BAD, nor if LENGTH has this value. -* - An error results if the base Frame of the Plot is not 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astGridLine"; - class = astGetClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Initialise the bounding box for primatives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Validate the axis index, converting the axis index to be zero-based. */ - (void) astValidateAxis( this, axis - 1, 1, method ); - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Draw the curve. The break information is stored in an external structure - where it can be accessed by public methods which return information - about the most recently drawn curve. */ - AxPlot( this, axis - 1, start, length, 1, &Curve_data, method, class, status ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); -} - -static TickInfo **GridLines( AstPlot *this, double *cen, double *gap, - int *inval, const char *method, const char *class, int *status ){ -/* -* Name: -* GridLines - -* Purpose: -* Obtain information desribing the major tick values within the plotting -* area. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* TickInfo **GridLines( AstPlot *this, double *cen, double *gap, -* int *inval, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* A pointer is returned which points to an array of two pointers. Each -* of these pointers points to a TickInfo structure which holds -* information about the ticks on a single axis. These structures, -* together with the array holding the two pointers, should be released -* when no longer needed using CleanGrid. - -* Parameters: -* this -* The Plot. -* cen -* A pointer to an array holding axis values at which to put a single -* central tick. Other ticks are placed evenly on either side of this -* tick. If AST__BAD is provided, a value will be used which would put a -* tick at an axis value of zero. -* gap -* A pointer to an array holding the gaps between ticks required on -* each axis. If this is AST__BAD a suitable default value will be used -* and returned in place of the AST__BAD value. -* inval -* A pointer to a location at which to return a flag indicating if -* any invalid physical coordinates were encountered while deciding on -* the tick values. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to an array of two TickInfo pointers. - -* Notes: -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - GetTicksStatics *statics = NULL; /* Pointer to static data for GetTicks */ - TickInfo **info; /* Returned array of two TickInfo pointers */ - double *lengths; /* Pointer to lengths of each curve section */ - double *starts; /* Pointer to start of each curve section */ - double *ticks; /* Pointer to tick mark values */ - double bot; /* Lowest axis value to display */ - double end; /* Axis value at end of curve section */ - double tmp; /* Temp storage */ - double top; /* Highest axis value to display */ - int i; /* Tick mark index */ - int j; /* Axis index */ - int k; /* Section index */ - int logticks[ 2 ]; /* Uses logarithmicaly spaced tick marks? */ - int nticks; /* Number of tick marks */ - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Get memory to hold two TickInfo pointers. */ - info = (TickInfo **) astMalloc( 2*sizeof( TickInfo *) ); - -/* If succesfull... */ - if( astOK ){ - -/* Initialise the two pointers. */ - info[ 0 ] = NULL; - info[ 1 ] = NULL; - -/* Obtain the tick mark values, and the corresponding formatted labels for - each axis. */ - for( j = 0; j < 2; j++ ){ - info[ j ] = TickMarks( this, j, cen + j, gap + j, inval, - &statics, method, class, status ); - logticks[ j ] = astGetLogTicks( this, j ); - } - -/* Release the resources allocated in the first call to TickMarks. */ - for( j = 0; j < 2; j++ ){ - (void) TickMarks( NULL, j, NULL, gap, NULL, &statics, method, class, - status ); - } - -/* Each major tick value for axis "j" may be marked with a curve parallel - to axis "1-j" drawn across the entire plotting area. We need to decide - where to start drawing this curve and how long it should be. We can - simply use the minimum value on axis "1-j" together with the tick value - on axis "j" to define the starting position. The length could be taken - as the difference between the maximum and minimum values on axis "1-j". - However, this may not be right in some situations. For instance if the - plotting area covers a small range of Right Ascension from 23:59:59 to - 00:00:01. Using the difference between the maximum and minimum values - to give the length of the curve would result in the curve starting at - 00:00:00 (the minimum axis value) and extending for a length of 23:59:59 - (the axis range). To get round this sort of problem, the curve is split - up into sections with lengths and starting positions determined by the - tick mark values on axis "1-j". The first section starts at the minimum - axis value and extends upto the first missing tick mark (in the RA - example, this would be at 00:00:01). Subsequent sections starts at the - next tick mark (23:59:59 in the RA example) and extends upto the next - missing tick mark, or the last tick mark if none are missing. */ - -/* Get the current frame. */ - fr = astGetFrame( this, AST__CURRENT ); - -/* If either axis has log tick spacing, use the simple approach which - assumes that each curve has only one section. */ - if( logticks[ 0 ] || logticks[ 1 ] ) { - -/* Find the start and length of the curve for each tick mark on axis "j". */ - for( j = 0; j < 2 && astOK; j++ ){ - -/* Find the axis range to display on the other axis. */ - bot = astGetBottom( fr, 1 - j ); - top = astGetTop( fr, 1 - j ); - if( bot > top ) { - tmp = top; - top = bot; - bot = tmp; - } - -/* Get a pointer to the major tick mark values on the other axis ("1-j"), - together with the number of them. */ - ticks = info[ 1 - j ]->ticks; - nticks = info[ 1 - j ]->nmajor; - -/* Reserve memory to hold the starts and lengths of each section of the - grid line marking the major ticks on the axis "j". There will only be - one section. */ - starts = (double *) astMalloc( sizeof(double) ); - lengths = (double *) astMalloc( sizeof(double) ); - info[ j ]->start = starts; - info[ j ]->length = lengths; - -/* Check that the pointers can be used. */ - if( astOK ) { - -/* The section starts one gap below the first tick, and ends one gap above - the first tick. Limit both to the displayed range of the axis. */ - if( logticks[ 1 - j ] ) { - starts[ 0 ] = astMIN( top, astMAX( bot, ticks[ 0 ]/gap[ 1 - j ] ) ); - end = astMIN( top, astMAX( bot, ticks[ nticks - 1 ]*gap[ 1 - j ] ) ); - } else { - starts[ 0 ] = astMIN( top, astMAX( bot, ticks[ 0 ] - gap[ 1 - j ] ) ); - end = astMIN( top, astMAX( bot, ticks[ nticks - 1 ] + gap[ 1 - j ] ) ); - } - -/* Store the length of the section. */ - lengths[ 0 ] = end - starts[ 0 ]; - -/* Store the number of sections in the returned structure. */ - info[ 0 ]->nsect = 1; - - } - } - -/* If both axes have linear tick spacing, use the complete approach. */ - } else { - -/* Find the start and length of each section of the curve for each tick - mark on axis "j". */ - for( j = 0; j < 2 && astOK; j++ ){ - -/* Find the axis range to display on the other axis. */ - bot = astGetBottom( fr, 1 - j ); - top = astGetTop( fr, 1 - j ); - if( bot > top ) { - tmp = top; - top = bot; - bot = tmp; - } - -/* Get a pointer to the major tick mark values on the other axis ("1-j"), - together with the number of them. */ - ticks = info[ 1 - j ]->ticks; - nticks = info[ 1 - j ]->nmajor; - -/* Reserve memory to hold the starts and lengths of each section of the - grid line marking the major ticks on the axis "j". The allocated - arrays are the largest that could possibly be needed (i.e. if every - tick mark starts a new section). */ - starts = (double *) astMalloc( sizeof(double)*(size_t) nticks ); - lengths = (double *) astMalloc( sizeof(double)*(size_t) nticks ); - info[ j ]->start = starts; - info[ j ]->length = lengths; - -/* Check that the pointers can be used. */ - if( astOK ) { - -/* Loop round each of the major tick marks on axis "1-j". */ - k = 0; - i = 0; - while( i < nticks ){ - -/* Record the start of the next section of the grid lines. */ - starts[ k ] = ticks[ i++ ]; - -/* Tick marks should be regularly spaced by the values in "gap". Check each - tick mark until a missing tick mark is found. The section ends at the - start of the gap. */ - while( i < nticks && - ( ticks[ i ] - ticks[ i - 1 ] ) < 1.5*gap[ 1 - j ] ) i++; - -/* Record the length of the section. */ - lengths[ k ] = ticks[ i - 1 ] - starts[ k ]; - -/* The section is extended at start and end by one gap in order to "cover - up the joins". Limit this to the displayed range of the axis. */ - starts[ k ] -= gap[ 1 - j]; - lengths[ k ] += 2.0*gap[ 1 - j ]; - -/* Limit the start and end to the displayed range of the axis. */ - end = starts[ k ] + lengths[ k ]; - starts[ k ] = astMIN( top, astMAX( bot, starts[ k ] ) ); - lengths[ k ] = astMIN( top, astMAX( bot, end ) ) - starts[ k ]; - -/* Increment the number of sections. */ - k++; - } - -/* Store the number of sections in the returned structure. */ - info[j]->nsect = k; - - } - } - } - -/* Annull the current frame. */ - fr = astAnnul( fr ); - - } - -/* If an error has occurred, clean up the returned TickInfo structures. */ - if( !astOK ) info = CleanGrid( info, status ); - -/* Return. */ - return info; - -} - -void astGrfAttrs_( AstPlot *this, int id, int set, int prim, const char *method, const char *class, int *status ){ -/* -*+ -* Name: -* astGrfAttrs - -* Purpose: -* Establish values for the graphics attributes for a given object. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* void astGrfAttrs( AstPlot *this, int id, int set, int prim, const char *method, const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* This function should be called with "set=1" to establish the correct -* graphics attributes prior to drawing specific graphical objects. Once -* the object has been drawn, it should be called again with "set=0" to -* re-establish the original graphics attributes. -* -* NOTE, each type of graphical object identified by "id" should be -* drawn entirely by calls to just one of GMark, GText or GLine -* as indicated by argument "prim". - -* Parameters: -* this -* A pointer to the Plot. -* id -* An integer specifying the graphical object to be drawn. -* set -* If non-zero then the attributes for the specified object are set -* to the values indicated by the corresponding Plot attributes, -* and the current values are saved in a static array. If zero, then -* the values are set to the values stored in the static array. -* prim -* Indicates the sort of graphics primative used to draw the -* object. This must be one of (defined in grf.h) : -* -* GRF__LINE -* GRF__MARK -* GRF__TEXT -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* Notes: -* - This function should always be called in pairs with set=1 on the -* first call and set=0 on the second call. -* - If a pair of calls is nested within another pair of calls, the -* inner pair has no effect. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double *attr; /* Pointer to the next attribute value */ - double dval; /* Floating point attribute value */ - int ival; /* Integer attribute value */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Set up a pointer to the next element in "grfattrs_attrs". */ - attr = grfattrs_attrs; - -/* If we are setting new values, increment the nesting level, otherwise - decrement it. */ - if( set ){ - grfattrs_nesting++; - } else { - grfattrs_nesting--; - } - -/* If we are changing any line attributes, ensure all lines are flushed to - the graphics system. */ - if( prim == GRF__LINE ) Fpoly( this, method, class, status ); - -/* First deal with cases where we are establishing new values for the - graphics attributes by setting them to the values of the corresponding - Plot attributes. Only do this if we are at nesting level one. */ - if( set && grfattrs_nesting == 1 ){ - -/* See if a value has been set in the Plot for the line style attribute for - the specified object, If so, use the value. */ - if( TestUseStyle( this, id, status ) ) { - ival = GetUseStyle( this, id, status ); - -/* Save the current value, and establish the new value. */ - GAttr( this, GRF__STYLE, (double) ival, attr++, prim, method, - class, status ); - -/* If no style was specified, retain the current value. Indicate that no - new value has been established by setting the old value bad. */ - } else { - *(attr++) = AST__BAD; - } - -/* Do the same for the line width attribute. */ - if( TestUseWidth( this, id, status ) ){ - dval = GetUseWidth( this, id, status ); - GAttr( this, GRF__WIDTH, dval, attr++, prim, method, class, status ); - } else { - *(attr++) = AST__BAD; - } - -/* Do the same for the character size attribute. */ - if( TestUseSize( this, id, status ) ) { - dval = GetUseSize( this, id, status ); - GAttr( this, GRF__SIZE, dval, attr++, prim, method, class, status ); - } else { - *(attr++) = AST__BAD; - } - -/* Do the same for the character font attribute. */ - if( TestUseFont( this, id, status ) ){ - ival = GetUseFont( this, id, status ); - GAttr( this, GRF__FONT, (double) ival, attr++, prim, method, class, status ); - } else { - *(attr++) = AST__BAD; - } - -/* Do the same for the colour attribute. */ - if( TestUseColour( this, id, status ) ) { - ival = GetUseColour( this, id, status ); - GAttr( this, GRF__COLOUR, (double) ival, attr++, prim, method, - class, status ); - } else { - *(attr++) = AST__BAD; - } - - } - -/* Now deal with cases where we are re-establishing old values saved on a - previous call to this function. Only do this if we are at nesting - level zero. */ - if( !set && !grfattrs_nesting ){ - GAttr( this, GRF__STYLE, *(attr++), NULL, prim, method, class, status ); - GAttr( this, GRF__WIDTH, *(attr++), NULL, prim, method, class, status ); - GAttr( this, GRF__SIZE, *(attr++), NULL, prim, method, class, status ); - GAttr( this, GRF__FONT, *(attr++), NULL, prim, method, class, status ); - GAttr( this, GRF__COLOUR, *(attr++), NULL, prim, method, class, status ); - } - -/* Return. */ - return; - -} - -static int GVec( AstPlot *this, AstMapping *mapping, double *phy, - int axis, double delta, AstPointSet **pset1, - AstPointSet **pset2, double *gx, double *gy, - double *dx, double *dy, int *flag, const char *method, - const char *class, int *status ){ -/* -* Name: -* GVec - -* Purpose: -* Returns a unit vector parallel to a physical axis at a given point. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GVec( AstPlot *this, AstMapping *mapping, double *phy, -* int axis, double delta, AstPointSet **pset1, -* AstPointSet **pset2, double *gx, double *gy, -* double *dx, double *dy, int *flag, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function returns a unit vector (in the graphics coordinate -* system) in the positive direction of the specified physical axis, -* at the given physical position. It works by transforming the given -* physical position, together with another very close position, and -* returning the vector between them. It is possible for a -* discontinuity to occur between these two close positions, -* resulting in a very large meaningless vector prior to -* normalisation. For this reason two vectors are found, one joining -* the given position to a close position higher up the axis, and one -* joining a close position lower down the axis to the given position. -* If these two vectors differ in magnitude by a large factor, then -* the shorter of the two vectors is normalised and returned. -* Otherwise, the vector which is closest in direction to the vector -* supplied in [dx,dy] is returned. The returned vector is reversed if -* necessary so that it always points in the positive direction of the -* axis. -* -* If neither of the two vectors can be found (i.e. if the graphics -* coordinates are bad, or coincident), then the vector supplied in -* [dx,dy] is returned unchanged, and a function value of zero is -* returned. Otherwise, a function value of one is returned. - -* Parameters: -* this -* Pointer to the Plot. -* mapping -* Pointer to the Mapping from the base Frame of the Plot to the -* current Frame. -* phy -* Pointer to an array holding the coordinates in the current Frame -* of the Plot at which the tangent vector is required. -* axis -* The index of the axis within the current Frame for which the -* tangent vector is required. -* delta -* The increment in the axis value to use between positions defining -* the vectors. -* pset1 -* A pointer to a place at which to store a pointer to a PointSet -* holding current Frame coordinates. This PointSet pointer should -* be supplied as NULL on the first call to this function, resulting -* in a new PointSet being created and a pointer to it returned. -* Subsequent calls to this function shopuld retain the pointer -* returned by the first call. The PointSet pointer should be -* annulled using astAnnul when no longer needed. -* pset2 -* A pointer to a place at which to store a pointer to a PointSet -* holding base Frame coordinates. This PointSet is managed in the -* same way as "pset1". -* gx -* A pointer to a double in which to return the graphics X -* coordinate of the position supplied by "phy". -* gy -* A pointer to a double in which to return the graphics Y -* coordinate of the position supplied by "phy". -* dx -* A pointer to a double in which to return the X component -* of the unit tangent vector. This should be supplied holding a -* "default" unit vector which is left unchanged if no new vector -* can be found. -* dy -* A pointer to a double in which to return the Y component -* of the unit tangent vector. This should be supplied holding a -* "default" unit vector which is left unchanged if no new vector -* can be found. -* flag -* A pointer to an int in which to return a flag indicating which -* of the two vectors was returned. Zero is returned if the vector -* was estimated by moving in a positive direction along the axis -* from the position supplied by "phy". One is returned if the vector -* was estimated by moving in a negative direction along the axis -* from the position supplied by "phy" (in this case the returned -* vector will have been negated so that it refers to the positive -* direction). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One is returned if the vector was found succesfully, Zero is returned -* if the vector could not be estimated for any reason. No error is -* reported if the failure was due to the nature of the mapping. - -* Notes: -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned. -*/ - -/* Local Variables: */ - double dd1; /* Length of positive vector */ - double dd2; /* Length of negative vector */ - double dx1; /* X component of positive vector */ - double dx2; /* X component of negative vector */ - double dy1; /* Y component of positive vector */ - double dy2; /* Y component of negative vector */ - double **ptr1; /* Pointers to physical coordinate data */ - double **ptr2; /* Pointers to graphics coordinate data */ - int i; /* Axis index */ - int nphy; /* No. of axes in current (physical) Frame */ - int ret; /* Was a vector estimated succesfully? */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - dx1 = 0.0; - dx2 = 0.0; - dy1 = 0.0; - dy2 = 0.0; - -/* Initialise the returned value to indicate that the vector can not - be found. */ - ret = 0; - -/* Get the number of physical coordinates from the mapping. */ - nphy = astGetNout( mapping ); - -/* If no PointSets have been supplied, create some now. PointSet 1 - contains physical coordinates, PointSet 2 contains graphics - coordinates. */ - if( !(*pset1) ) *pset1 = astPointSet( 3, nphy, "", status ); - if( !(*pset2) ) *pset2 = astPointSet( 3, 2, "", status ); - -/* Get pointers to the PointSet data. */ - ptr1 = astGetPoints( *pset1 ); - ptr2 = astGetPoints( *pset2 ); - -/* Check the PointSets can be used. */ - if( astOK ){ - -/* Store the physical coordinates of three close points on a curve - parallel to the given axis, with the centre point at the given - position. */ - for( i = 0; i < nphy; i++ ){ - ptr1[ i ][ 0 ] = phy[ i ]; - ptr1[ i ][ 1 ] = phy[ i ]; - ptr1[ i ][ 2 ] = phy[ i ]; - } - - if( phy[ axis ] != AST__BAD ){ - ptr1[ axis ][ 0 ] = phy[ axis ] - delta; - ptr1[ axis ][ 2 ] = phy[ axis ] + delta; - } - -/* Find the corresponding graphics coordinates. */ - (void) Trans( this, NULL, mapping, *pset1, 0, *pset2, 0, method, class, status ); - -/* Check the central position is OK. */ - *gx = ptr2[ 0 ][ 1 ]; - *gy = ptr2[ 1 ][ 1 ]; - if( astOK && *gx != AST__BAD && *gy != AST__BAD ){ - -/* Get the unit vector between the central position and the position at - the higher physical axis value. Also get the length of the vector - joining the two positions. */ - if( ptr2[ 0 ][ 2 ] != AST__BAD && ptr2[ 1 ][ 2 ] != AST__BAD ){ - dx1 = ptr2[ 0 ][ 2 ] - *gx; - dy1 = ptr2[ 1 ][ 2 ] - *gy; - dd1 = dx1*dx1 + dy1*dy1; - - if( dd1 > 0.0 ) { - dd1 = sqrt( dd1 ); - dx1 /= dd1; - dy1 /= dd1; - } else { - dd1 = AST__BAD; - } - - } else { - dd1 = AST__BAD; - } - -/* Do the same for the position with lower physical axis value, - reversing the direction of the vector so that it refers to the - positive direction. */ - if( ptr2[ 0 ][ 0 ] != AST__BAD && ptr2[ 1 ][ 0 ] != AST__BAD ){ - dx2 = *gx - ptr2[ 0 ][ 0 ]; - dy2 = *gy - ptr2[ 1 ][ 0 ]; - dd2 = dx2*dx2 + dy2*dy2; - - if( dd2 > 0.0 ) { - dd2 = sqrt( dd2 ); - dx2 /= dd2; - dy2 /= dd2; - } else { - dd2 = AST__BAD; - } - - } else { - dd2 = AST__BAD; - } - -/* Only overwrite the supplied vector if at least one of the two tangent - vectors was defined. */ - if( dd1 != AST__BAD || dd2 != AST__BAD ){ - -/* If the first vector was not defined, return the second. */ - if( dd1 == AST__BAD ){ - *dx = dx2; - *dy = dy2; - *flag = 1; - ret = 1; - -/* If the second vector was not defined, return the first. */ - } else if( dd2 == AST__BAD ){ - *dx = dx1; - *dy = dy1; - *flag = 0; - ret = 1; - -/* If the first vector is much longer than the second, return the - second. */ - } else if( dd1 > 100.0*dd2 ){ - *dx = dx2; - *dy = dy2; - *flag = 1; - ret = 1; - -/* If the second vector is much longer than the first, return the - first. */ - } else if( dd2 > 100.0*dd1 ){ - *dx = dx1; - *dy = dy1; - *flag = 0; - ret = 1; - -/* If both vectors are defined and of comparable length, return the - vector which is most nearly parallel to the supplied vector. Note, we - assume that the supplied vector [dx,dy] is a unit vector. */ - } else if( *dx != AST__BAD && *dx != AST__BAD ){ - if( ( dx1*(*dx) + dy1*(*dy) )/dd1 > - ( dx2*(*dx) + dy2*(*dy) )/dd2 ){ - *dx = dx1; - *dy = dy1; - *flag = 0; - ret = 1; - - } else { - *dx = dx2; - *dy = dy2; - *flag = 1; - ret = 1; - } - -/* If no vector was supplied, return the shorter of the two vectors. */ - } else if( dd1 < dd2 ){ - *dx = dx1; - *dy = dy1; - *flag = 0; - ret = 1; - - } else { - *dx = dx2; - *dy = dy2; - *flag = 1; - ret = 1; - - } - - } - - } - - } - -/* Return the answer. */ - return ret; - -} - -static int HasEscapes( const char *text, int *status ) { -/* -* Name: -* HasEscapes - -* Purpose: -* Check if a text string contains any escape sequences. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int HasEscapes( const char *text, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function checks if a text string contains any escape sequences -* (see attribute Escape). - -* Parameters: -* text -* The text to check. -* status -* Pointer to the inherited status variable. - -* Returned: -* Non-zero if any escape sequences are found in the text. Zero -* otherwise. - -*/ - -/* Local Variables: */ - int result; - int type; - int value; - int nc; - -/* Initialise. */ - result = 0; - -/* Check the global error status and the supplied pointer. */ - if ( !astOK || ! text ) return result; - -/* Does the string begin with an escape sequence? */ - if( astFindEscape( text, &type, &value, &nc ) ){ - result = 1; - -/* If not, there must be an escape sequence later in the string if the - number of characters skipped by the above call to astFindEscape is less - than the length of the string. */ - } else if( nc < strlen( text ) ) { - result = 1; - } - -/* Return the result. */ - return result; -} - -static int IdFind( int id, int nax, int *id1, int *id2, int *id3, int *status ) { -/* -* Name: -* IdFind - -* Purpose: -* Find the numerical identifiers to use for a given identifier. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int IdFind( int id, int nax, int *id1, int *id2, int *id3, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied integer should be a numerical identifier for a -* graphical element of a plot (AST__MARKS_ID, AST__CURVES_ID, etc), or a -* "psuedo-identifier" which represents two other genuine identifiers. -* If the supplied value is a genuine identifier then it is returned -* in *id1, and *id2 is returned equal to -1. If the supplied value -* is a pseudo-identifier then the two corresponding genuine -* identifiers are returned in *id1 and *id2 - -* For instance, if "id" is AST__AXIS1_ID (a genuine id), then *id1 is -* returned equal to AST__AXIS1_ID and *id2 is returned equal to -1. If -* "id" is AST__AXES_ID (a pseudo-identifier), then *id1 is returned equal -* to AST__AXIS1_ID and *id2 is returned equal to AST__AXIS2_ID. - -* Genuine identifiers all have values which are less than the value -* of AST__NPID. Pseudo-identifiers have values which are greater than -* or equal to the value of AST__NPID. - -* Parameters: -* id -* The supplied identifier (genuine or pseudo). -* nax -* The number of axes spanning graphics space (2 or 3). -* id1 -* Pointer to the int at which to return the first genuine -* identifier corresponding to "id". -* id2 -* Pointer to the int at which to return the second genuine -* identifier corresponding to "id" (or -1 if "id" is a genuine -* identifier). -* id3 -* Pointer to the int at which to return the third genuine -* identifier corresponding to "id" (or -1 if "id" has no third -* genuine identifier). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of genuine identifiers corresponding to the supplied -* (possibly Pseudo-) identifier. This will be in the range 1 to 3. - -*/ - -/* Local Variables: */ - int ret; - -/* Initialise returned values. */ - *id1 = id; - *id2 = -1; - *id3 = -1; - ret = 0; - -/* Check the local error status. */ - if ( !astOK ) return ret; - -/* Assume a genuine identifier was supplied. */ - ret = 1; - -/* Check against all known pseudo-identifier. */ - if( id == AST__AXES_ID ) { - ret = nax; - *id1 = AST__AXIS1_ID; - *id2 = AST__AXIS2_ID; - if( nax == 3 ) *id3 = AST__AXIS3_ID; - - } else if( id == AST__GRIDLINE_ID ) { - ret = nax; - *id1 = AST__GRIDLINE1_ID; - *id2 = AST__GRIDLINE2_ID; - if( nax == 3 ) *id3 = AST__GRIDLINE3_ID; - - } else if( id == AST__NUMLABS_ID ) { - ret = nax; - *id1 = AST__NUMLAB1_ID; - *id2 = AST__NUMLAB2_ID; - if( nax == 3 ) *id3 = AST__NUMLAB3_ID; - - } else if( id == AST__TEXTLABS_ID ) { - ret = nax; - *id1 = AST__TEXTLAB1_ID; - *id2 = AST__TEXTLAB2_ID; - if( nax == 3 ) *id3 = AST__TEXTLAB3_ID; - - } else if( id == AST__TICKS_ID ) { - ret = nax; - *id1 = AST__TICKS1_ID; - *id2 = AST__TICKS2_ID; - if( nax == 3 ) *id3 = AST__TICKS3_ID; - - } else if( id >= AST__NPID ) { - astError( AST__INTER, "AST internal programming error - " - "function IdFind in class Plot does not yet support " - "pseudo-identifier value %d", status, id ); - } - -/* Return the answer. */ - return ret; - -} - -void astInitPlotVtab_( AstPlotVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitPlotVtab - -* Purpose: -* Initialise a virtual function table for a Plot. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* void astInitPlotVtab( AstPlotVtab *vtab, const char *name ) - -* Class Membership: -* Plot vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Plot class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameSetVtab *fset; /* Pointer to FrameSet component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameSetVtab( (AstFrameSetVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This will be - used (by astIsAPlot) to determine if an object belongs to this class. - We can conveniently use the address of the (static) class_init variable to - generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameSetVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->BBuf = BBuf; - vtab->Border = Border; - vtab->BoundingBox = BoundingBox; - vtab->ClearGrid = ClearGrid; - vtab->ClearTol = ClearTol; - vtab->Clip = Clip; - vtab->CopyPlotDefaults = CopyPlotDefaults; - vtab->Curve = Curve; - vtab->CvBrk = CvBrk; - vtab->EBuf = EBuf; - vtab->GenCurve = GenCurve; - vtab->GetDrawnTicks = GetDrawnTicks; - vtab->GetGrid = GetGrid; - vtab->GetTol = GetTol; - vtab->GrfPop = GrfPop; - vtab->GrfPush = GrfPush; - vtab->GrfSet = GrfSet; - vtab->GrfWrapper = GrfWrapper; - vtab->Grid = Grid; - vtab->GridLine = GridLine; - vtab->Mark = Mark; - vtab->Mirror = Mirror; - vtab->PolyCurve = PolyCurve; - vtab->RegionOutline = RegionOutline; - vtab->SetGrid = SetGrid; - vtab->SetTickValues = SetTickValues; - vtab->SetTol = SetTol; - vtab->TestGrid = TestGrid; - vtab->TestTol = TestTol; - vtab->Text = Text; - - vtab->ClearTickAll = ClearTickAll; - vtab->SetTickAll = SetTickAll; - vtab->GetTickAll = GetTickAll; - vtab->TestTickAll = TestTickAll; - - vtab->ClearForceExterior = ClearForceExterior; - vtab->SetForceExterior = SetForceExterior; - vtab->GetForceExterior = GetForceExterior; - vtab->TestForceExterior = TestForceExterior; - - vtab->ClearInvisible = ClearInvisible; - vtab->SetInvisible = SetInvisible; - vtab->GetInvisible = GetInvisible; - vtab->TestInvisible = TestInvisible; - vtab->ClearBorder = ClearBorder; - vtab->SetBorder = SetBorder; - vtab->GetBorder = GetBorder; - vtab->TestBorder = TestBorder; - vtab->ClearInk = ClearInk; - vtab->SetInk = SetInk; - vtab->GetInk = GetInk; - vtab->TestInk = TestInk; - vtab->ClearClipOp = ClearClipOp; - vtab->SetClipOp = SetClipOp; - vtab->GetClipOp = GetClipOp; - vtab->TestClipOp = TestClipOp; - vtab->ClearClip = ClearClip; - vtab->SetClip = SetClip; - vtab->GetClip = GetClip; - vtab->TestClip = TestClip; - vtab->ClearGrf = ClearGrf; - vtab->SetGrf = SetGrf; - vtab->GetGrf = GetGrf; - vtab->TestGrf = TestGrf; - vtab->ClearDrawTitle = ClearDrawTitle; - vtab->SetDrawTitle = SetDrawTitle; - vtab->GetDrawTitle = GetDrawTitle; - vtab->TestDrawTitle = TestDrawTitle; - vtab->ClearLabelUp = ClearLabelUp; - vtab->SetLabelUp = SetLabelUp; - vtab->GetLabelUp = GetLabelUp; - vtab->TestLabelUp = TestLabelUp; - vtab->ClearLogPlot = ClearLogPlot; - vtab->SetLogPlot = SetLogPlot; - vtab->GetLogPlot = GetLogPlot; - vtab->TestLogPlot = TestLogPlot; - vtab->ClearLogTicks = ClearLogTicks; - vtab->SetLogTicks = SetLogTicks; - vtab->GetLogTicks = GetLogTicks; - vtab->TestLogTicks = TestLogTicks; - vtab->ClearLogLabel = ClearLogLabel; - vtab->SetLogLabel = SetLogLabel; - vtab->GetLogLabel = GetLogLabel; - vtab->TestLogLabel = TestLogLabel; - vtab->ClearDrawAxes = ClearDrawAxes; - vtab->SetDrawAxes = SetDrawAxes; - vtab->GetDrawAxes = GetDrawAxes; - vtab->TestDrawAxes = TestDrawAxes; - vtab->ClearAbbrev = ClearAbbrev; - vtab->SetAbbrev = SetAbbrev; - vtab->GetAbbrev = GetAbbrev; - vtab->TestAbbrev = TestAbbrev; - vtab->ClearEscape = ClearEscape; - vtab->SetEscape = SetEscape; - vtab->GetEscape = GetEscape; - vtab->TestEscape = TestEscape; - vtab->ClearLabelling = ClearLabelling; - vtab->SetLabelling = SetLabelling; - vtab->GetLabelling = GetLabelling; - vtab->TestLabelling = TestLabelling; - vtab->ClearMajTickLen = ClearMajTickLen; - vtab->SetMajTickLen = SetMajTickLen; - vtab->GetMajTickLen = GetMajTickLen; - vtab->TestMajTickLen = TestMajTickLen; - vtab->ClearLogGap = ClearLogGap; - vtab->SetLogGap = SetLogGap; - vtab->GetLogGap = GetLogGap; - vtab->TestLogGap = TestLogGap; - vtab->ClearTitleGap = ClearTitleGap; - vtab->SetTitleGap = SetTitleGap; - vtab->GetTitleGap = GetTitleGap; - vtab->TestTitleGap = TestTitleGap; - vtab->ClearMinTickLen = ClearMinTickLen; - vtab->SetMinTickLen = SetMinTickLen; - vtab->GetMinTickLen = GetMinTickLen; - vtab->TestMinTickLen = TestMinTickLen; - vtab->ClearNumLabGap = ClearNumLabGap; - vtab->SetNumLabGap = SetNumLabGap; - vtab->GetNumLabGap = GetNumLabGap; - vtab->TestNumLabGap = TestNumLabGap; - vtab->ClearTextLabGap = ClearTextLabGap; - vtab->SetTextLabGap = SetTextLabGap; - vtab->GetTextLabGap = GetTextLabGap; - vtab->TestTextLabGap = TestTextLabGap; - vtab->ClearLabelAt = ClearLabelAt; - vtab->SetLabelAt = SetLabelAt; - vtab->GetLabelAt = GetLabelAt; - vtab->TestLabelAt = TestLabelAt; - vtab->ClearCentre = ClearCentre; - vtab->SetCentre = SetCentre; - vtab->GetCentre = GetCentre; - vtab->TestCentre = TestCentre; - vtab->ClearGap = ClearGap; - vtab->SetGap = SetGap; - vtab->GetGap = GetGap; - vtab->TestGap = TestGap; - vtab->ClearEdge = ClearEdge; - vtab->SetEdge = SetEdge; - vtab->GetEdge = GetEdge; - vtab->TestEdge = TestEdge; - vtab->ClearNumLab = ClearNumLab; - vtab->SetNumLab = SetNumLab; - vtab->GetNumLab = GetNumLab; - vtab->TestNumLab = TestNumLab; - vtab->ClearMinTick = ClearMinTick; - vtab->SetMinTick = SetMinTick; - vtab->GetMinTick = GetMinTick; - vtab->TestMinTick = TestMinTick; - vtab->ClearTextLab = ClearTextLab; - vtab->SetTextLab = SetTextLab; - vtab->GetTextLab = GetTextLab; - vtab->TestTextLab = TestTextLab; - vtab->ClearLabelUnits = ClearLabelUnits; - vtab->SetLabelUnits = SetLabelUnits; - vtab->GetLabelUnits = GetLabelUnits; - vtab->TestLabelUnits = TestLabelUnits; - vtab->ClearStyle = ClearStyle; - vtab->SetStyle = SetStyle; - vtab->GetStyle = GetStyle; - vtab->TestStyle = TestStyle; - vtab->ClearFont = ClearFont; - vtab->SetFont = SetFont; - vtab->GetFont = GetFont; - vtab->TestFont = TestFont; - vtab->ClearColour = ClearColour; - vtab->SetColour = SetColour; - vtab->GetColour = GetColour; - vtab->TestColour = TestColour; - vtab->ClearWidth = ClearWidth; - vtab->SetWidth = SetWidth; - vtab->GetWidth = GetWidth; - vtab->TestWidth = TestWidth; - vtab->ClearSize = ClearSize; - vtab->SetSize = SetSize; - vtab->GetSize = GetSize; - vtab->TestSize = TestSize; - vtab->GetGrfContext = GetGrfContext; - -/* Save the inherited pointers to methods that will be extended, and replace - them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - fset = (AstFrameSetVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_removeframe = fset->RemoveFrame; - fset->RemoveFrame = RemoveFrame; - -/* Declare the destructor and copy constructor. */ - astSetDelete( (AstObjectVtab *) vtab, Delete ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - -/* Declare the class dump function. */ - astSetDump( vtab, Dump, "Plot", "Provide facilities for 2D graphical output" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int Inside( int n, float *cx, float *cy, float x, float y, int *status ){ -/* -* Name: -* Inside - -* Purpose: -* See if a given point is inside a 2-d polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Inside( int n, float *cx, float *cy, float x, float y, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function determines if the position given by x and y, is inside -* or outside the polygon specified by the vertices given in arrays cx -* and cy. - -* Parameters: -* n -* The number of vertices in the polygon. -* cx -* A pointer to an array holding the x coordinates at the "n" vertices. -* cy -* A pointer to an array holding the y coordinates at the "n" vertices. -* x -* The x coordinate of the test point. -* y -* The y coordinate of the test point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A boolean flag indicating if the test point is inside the polygon. - -* Notes: -* - The algorithm used only works for convex polygons. -* - The polygon is closed by joining the last vertex to the first -* vertex. -* - Zero is returned if an error has occurred. - -*/ - -/* Local Variables: */ - int i; /* Index of the current vertex */ - int j; /* Index of the next vertex */ - int ret; /* Is the test point inside the polygon? */ - int sgn; /* Which side of the first edge is the test point? */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise the returned value to indicate that the point is inside the - box. */ - ret = 1; - -/* Get the sign of the angle between the vector joining vertex 1 to vertex - 0, and the vector joining the test point to vertex zero. */ - if( ( cx[ 1 ] - cx[ 0 ] )*( y - cy[ 0 ] ) > - ( x - cx[ 0 ] )*( cy[ 1 ] - cy[ 0 ] ) ){ - sgn = 1; - } else { - sgn = -1; - } - -/* Check that the remaining test point is on the same side of the remaining - sides. */ - for( i = 1; i < n; i++ ){ - -/* Get the index of the next vertex, joining the last vertex up with - vertex zero. */ - j = i + 1; - if( j >= n ) j -= n; - -/* Get the sign of the angle between the vector joining vertex j to vertex - i, and the vector joining the test point to vertex i. If the sign is - opposite to that found for vertex zero, then the test point is outside - the polygon. Break out of the loop if this is the case. */ - if( ( cx[ j ] - cx[ i ] )*( y - cy[ i ] ) > - ( x - cx[ i ] )*( cy[ j ] - cy[ i ] ) ){ - - if( sgn == -1 ) { - ret = 0; - break; - } - - } else { - - if( sgn == 1 ) { - ret = 0; - break; - } - - } - - } - - -/* Return the answer. */ - return ret; - -} - -static void InterpEscape( AstPlot *this, int type, double value, float *x, - float *y, float ux, float uy, float rx, float ry, - const char *just, float *rise, double nsize, - double nstyle, double nwidth, double ncol, - double nfont, const char *method, const char *class, int *status ){ -/* -* Name: -* InterpEscape - -* Purpose: -* Prepare things for drawing the next part of a string which includes -* graphics escape sequences. - -* Synopsis: -* #include "plot.h" -* void InterpEscape( AstPlot *this, int type, double value, float *x, -* float *y, float ux, float uy, float rx, float ry, -* const char *just, float *rise, double nsize, -* double nstyle, double nwidth, double ncol, -* double nfont, const char *method, const char *class, int *status ) - -* Description: -* This function modifies the current graphics attributes, the supplied -* reference position, in preparation for drawing another sub-string -* from a string containing graphics escape sequences. The type and -* value of an escape sequence preceding the substring is supplied. -* Note, this function ignored escape sequences which represent an -* escaped percent sign. Such escape sequences are drawn as normal -* text by the claling function. - -* Parameters: -* this -* The plot. -* type -* The type of escape sequence. Each type is identified by a symbolic -* constant defined in grf.h. -* value -* The value associated with the escape sequence. All usable values -* will be positive. A value of -1 shold be supplied if the attribute -* identified by "type" should be reset to its "normal" value (as -* established using the astGAttr function, etc). -* x -* Pointer to a double holding the x coordinate at the concatenation -* point. This will be modified on exit if the escape sequence -* requires it. -* y -* Pointer to a double holding the y coordinate at the concatenation -* point. This will be modified on exit if the escape sequence -* requires it. -* ux -* The x component of the up-vector for the text, in graphics coords. -* The length of this vector should be equal to the height of normal -* text drawn with this up-vector. -* uy -* The y component of the up-vector for the text. See "ux". -* rx -* The x component of the right-vector for the text. The length of this -* vector should be equal to the height of normal text drawn with the -* supplied up-vector. -* ry -* The y component of the right-vector for the text. see "rx". -* just -* The justification being used for each substring. -* rise -* Pointer to a float holding the height of the current baseline -* above the normal baseline, given as a percentage of the height of -* normal text. May be negative for sub-scripts. May be modified on -* exit if the escape sequence effects the height of the baseline. -* nsize -* The size of normal text. -* nstyle -* The style of normal text. -* nwidth -* The width of normal text. -* ncol -* The colour of normal text. -* nfont -* The font of normal text. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - float new_rise; - float t1, t2; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Type GRF__ESSUP: Move the concatenation point in the up direction, and - update the current baseline height. If the value is -1, then reset the - baseline to its normal height. */ - if( type == GRF__ESSUP ) { - if( value > 0 ) { - *x += 0.01*ux*( value - *rise ); - *y += 0.01*uy*( value - *rise ); - *rise = value; - } else { - *x -= 0.01*ux*(*rise); - *y -= 0.01*uy*(*rise); - *rise = 0; - } - -/* Type GRF__ESSUB: Move the concatenation point in the down direction, and - update the current baseline height. If the value is -1, then reset the - baseline to its normal height. */ - } else if( type == GRF__ESSUB ) { - if( value > 0 ) { - *x -= 0.01*ux*( value + *rise ); - *y -= 0.01*uy*( value + *rise ); - *rise = -value; - } else { - *x -= 0.01*ux*(*rise); - *y -= 0.01*uy*(*rise); - *rise = 0; - } - -/* Type GRF__ESGAP: Move the concatenation point to the right. */ - } else if( type == GRF__ESGAP ) { - *x += 0.01*rx*value; - *y += 0.01*ry*value; - -/* Type GRF__ESBAC: Move the concatenation point to the left. */ - } else if( type == GRF__ESBAC ) { - *x -= 0.01*rx*value; - *y -= 0.01*ry*value; - -/* Remember the current horizontal position. */ - } else if( type == GRF__ESH ) { - this->hmarkx = *x; - this->hmarky = *y; - -/* Go to the previously stored horizontal position. */ - } else if( type == GRF__ESG ) { - if( this->hmarkx != FLT_MAX && this->hmarky != FLT_MAX ) { - t1 = ( *x - this->hmarkx )*rx + ( *y - this->hmarky )*ry; - t2 = rx*rx + ry*ry; - *x -= rx*t1/t2; - *y -= ry*t1/t2; - } - -/* Type GRF__ESSIZ: Change the text size. */ - } else if( type == GRF__ESSIZ ) { - if( value < 0 ) value = 100.0; - GAttr( this, GRF__SIZE, 0.01*value*nsize, NULL, GRF__TEXT, - method, class, status ); - -/* Type GRF__ESWID: Change the text width. */ - } else if( type == GRF__ESWID ) { - if( value < 0 ) value = 100.0; - GAttr( this, GRF__WIDTH, 0.01*value*nwidth, NULL, GRF__TEXT, - method, class, status ); - -/* Type GRF__ESFON: Change the text font. */ - } else if( type == GRF__ESFON ) { - if( value < 0 ) value = nfont; - GAttr( this, GRF__FONT, value, NULL, GRF__TEXT, method, class, status ); - -/* Type GRF__ESCOL: Change the text colour. */ - } else if( type == GRF__ESCOL ) { - if( value < 0 ) value = ncol; - GAttr( this, GRF__COLOUR, value, NULL, GRF__TEXT, method, class, status ); - -/* Type GRF__ESSTY: Change the text style. */ - } else if( type == GRF__ESSTY ) { - if( value < 0 ) value = nstyle; - GAttr( this, GRF__STYLE, value, NULL, GRF__TEXT, method, class, status ); - -/* Type GRF__ESPSH: Push current attributes onto a stack. */ - } else if( type == GRF__ESPSH ) { - PushGat( this, *rise, method, class, status ); - -/* Type GRF__ESSTY: Reset everything to normal. */ - } else if( type == GRF__ESPOP ) { - - if( !PopGat( this, &new_rise, method, class, status ) ) { - new_rise = 0.0; - GAttr( this, GRF__SIZE, nsize, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, nwidth, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, ncol, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, nfont, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, nstyle, NULL, GRF__TEXT, method, class, status ); - } - - *x -= 0.01*ux*( *rise - new_rise ); - *y -= 0.01*uy*( *rise - new_rise ); - *rise = new_rise; - - } -} - -static int IsASkyAxis( AstFrame *frm, int axis, int *status ) { -/* -* Name: -* IsASkyAxis - -* Purpose: -* Checks if a specified axis of the supplied Frame is a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int IsASkyAxis( AstFrame *frm, int axis, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function checks if if a specified axis of the supplied Frame is -* a SkyAxis. - -* Parameters: -* frm -* The Frame. -* axis -* The zero-based axis index. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A boolean flag indicating if the axis is a SkyAxis. - -*/ - -/* Local Variables: */ - int ret; - AstAxis *ax; - -/* initialise */ - ret = 0; - -/* Check the global status. */ - if( !astOK ) return ret; - -/* Extract the required axis from the Frame and test if it is a SkyAxis. - Then free the axis memory. */ - ax = astGetAxis( frm, axis ); - ret = astIsASkyAxis( ax ); - ax = astAnnul( ax ); - -/* Return the answer. */ - return ret; - -} - -static int IsASkyFrame( AstObject *obj, int *status ) { -/* -* Name: -* IsASkyFrame - -* Purpose: -* Checks if the supplied Object ca be treated as a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int IsASkyFrame( AstObject *obj, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function checks if the supplied Object is a SkyFrame or a -* FrameSet which has a SkyFrame as its current Frame. - -* Parameters: -* obj -* The object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A boolean flag indicating if the Object can be treated as SkyFrame. - -*/ - -/* Local Variables: */ - int ret; - AstFrame *frm; - -/* initialise */ - ret = 0; - -/* Check the global status. */ - if( !astOK ) return ret; - -/* If the Object is a SkyFrame, return 1. */ - if( astIsASkyFrame( obj ) ) { - ret = 1; - -/* If the Object is a FrameSet, check its current Frame recursively, - using this method. */ - } else if( astIsAFrameSet( obj ) ) { - frm = astGetFrame( (AstFrameSet *) obj, AST__CURRENT ); - ret = IsASkyFrame( (AstObject *) frm, status ); - frm = astAnnul( frm ); - } - -/* Return the answer. */ - return ret; - -} - -static const char *JustMB( AstPlot *this, int esc, const char *text, float *x, - float *y, float upx, float upy, const char *just, - float uxu, float uyu, float rxu, float ryu, - float *x0, float *y0, const char *method, - const char *class, int *status ){ -/* -* Name: -* JustMB - -* Purpose: -* Modifies a "M" vertical reference point to be a "B" reference point, -* if necessary. - -* Synopsis: -* #include "plot.h" -* const char *JustMB( AstPlot *this, int esc, const char *text, float *x, -* float *y, float upx, float upy, const char *just, -* float uxu, float uyu, float rxu, float ryu, -* float *x0, float *y0, const char *method, -* const char *class, int *status ) - -* Description: -* This function is used to modify the reference point and justification -* of a string by converting the vertical "M" justification option (which -* indicates that the reference point refers to the bottom of the -* bounding box) into a corresponding "B" option (which indicates that -* the reference point refers to the text baseline). The reference -* point is modified accordingly. -* -* This is only done if the grf module does not support "M" -* justification. Otherwise, the supplied justification string and -* reference point coordinates are returned unchanged. - -* Parameters: -* this -* The plot. -* esc -* Should escape sequences be interpreted? They will be printed -* literally otherwise. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* Pointer to a double holding the x coordinate at the reference -* point. This is modified on exit if the supplied "just" string -* indicates that the supplied value refers to the bottom of the -* bounding box, and the grf module does not support such -* justification. In this case, the returned value is a point on -* the baseline of the text which would result in the bottom of -* the bounding box being at the supplied position. -* y -* Pointer to a double holding the y coordinate at the reference -* point. This is modified on exit if the supplied "just" string -* indicates that the supplied value refers to the bottom of the -* bounding box, and the grf module does not support such -* justification. In this case, the returned value is a point on -* the baseline of the text which would result in the bottom of -* the bounding box being at the supplied position. -* upx -* The x component of the up-vector for the text. Positive values -* always refer to displacements from left to right on the screen, -* even if the graphics x axis increases in the opposite sense. -* upy -* The y component of the up-vector for the text. Positive values -* always refer to displacements from left to right on the screen, -* even if the graphics y axis increases in the opposite sense. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", 'B' for "baseline" or "M" for "bottom", and -* specifies the vertical location of the reference position. Note, -* "baseline" corresponds to the base-line of normal text,and "M" -* corresponds to the bottom of the bounding box. Some characters -* (eg "y", "g", "p", etc) and sub-scripts descend below the base-line. -* The second character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* uxu -* X component of normalised up-vector, in graphics coords. -* uyu -* Y component of normalised up-vector, in graphics coords. -* rxu -* X component of normalised right-vector, in graphics coords. -* ryu -* Y component of normalised right-vector, in graphics coords. -* x0 -* Address of a float at which to return the x coordinate at the -* left end of the baseline of the whole string. -* y0 -* Address of a float at which to return the y coordinate at the -* left end of the baseline of the whole string. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated string which contains the -* justification to use in future. This pointer should be freed using -* astFree when no longer needed. This string will contain a full -* upper-case justification string which can be used by the current -* grf module. - -* Notes; -* - NULL is returned if an error has occurred. - -*/ - -/* Local Variables: */ - char cc; - float drop; - float dx; - float dy; - float f; - float height; - float width; - float xbn[ 4 ]; - float ybn[ 4 ]; - int called; - char *result; - -/* Check inherited status */ - if( !astOK ) return NULL; - -/* Allocate memory for the returned string. */ - result = astMalloc( sizeof( char )*3 ); - if( astOK ) { - -/* Fill in any missing parts of the justification string. */ - if( just ){ - cc = toupper( just[ 0 ] ); - result[ 0 ] = ( cc == 'T' || cc == 'C' || cc == 'B' || cc == 'M' ) ? cc : 'C'; - - cc = toupper( just[ 1 ] ); - result[ 1 ] = ( cc == 'L' || cc == 'C' || cc == 'R' ) ? cc : 'C'; - - } else { - result[ 0 ] = 'C'; - result[ 1 ] = 'C'; - } - - result[ 2 ] = 0; - -/* Indicate that DrawText has not been called. */ - called = 0; - -/* The justfication need not be changed unless the requested vertical - justification is "bottom" (m), AND the grf module does not support "M" - justification. */ - if( ( result[ 0 ] == 'M' ) && !GCap( this, GRF__MJUST, 1, status ) ){ - -/* Find the bounding box which would result from putting the left end of - the baseline at the specified position. */ - DrawText( this, 0, esc, text, *x, *y, "BL", upx, upy, xbn, ybn, - &drop, method, class, status ); - -/* Indicate that DrawText has not been called. */ - called = 1; - -/* Get the vector from the bottom left corner of the bounding box to the - reference point (on the base-line), and add this vector on to the reference - point. */ - *x += *x - xbn[ 0 ]; - *y += *y - ybn[ 0 ]; - -/* Modified the returned justification string. */ - result[ 0 ] = 'B'; - } - -/* If the returned justification is "BL", then the left end of the - baseline is just the returned reference point. */ - if( result[ 0 ] == 'B' && result[ 1 ] == 'L' ) { - *x0 = *x; - *y0 = *y; - -/* Otherwise, we work out the coords of the left end of the baseline from - the values returned by DrawText above. Call DrawText now if it was not - called above. */ - } else { - if( ! called ) { - DrawText( this, 0, esc, text, *x, *y, "BL", upx, upy, xbn, ybn, - &drop, method, class, status ); - } - -/* Find the height and width of the bounding box. */ - dx = xbn[ 0 ] - xbn[ 3 ]; - dy = ybn[ 0 ] - ybn[ 3 ]; - width = sqrt( dx*dx + dy*dy ); - - dx = xbn[ 0 ] - xbn[ 1 ]; - dy = ybn[ 0 ] - ybn[ 1 ]; - height = sqrt( dx*dx + dy*dy ); - -/* For "C" and "R" horizontal justification we first need to move the - returned reference point left by 0.5 or 1.0 times the width of the whole - string respectively. */ - if( result[ 1 ] == 'C' ) { - f = 0.5; - - } else if( result[ 1 ] == 'R' ) { - f = 1.0; - - } else { - f = 0.0; - } - - f *= width; - - *x0 = *x - f*rxu; - *y0 = *y - f*ryu; - -/* Unless the vertical justification is "B", we also need to move the - concatenation point vertically to put it on the baseline. */ - if( result[ 0 ] == 'T' ) { - f = height - drop; - - } else if( result[ 0 ] == 'C' ) { - f = 0.5*height - drop; - - } else if( result[ 0 ] == 'M' ) { - f = -drop; - - } else { - f = 0.0; - } - - *x0 -= f*uxu; - *y0 -= f*uyu; - } - } - -/* Return the result. */ - return result; -} - -static int Labelat( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, - double *labelat, const char *method, const char *class, - int *status ){ -/* -* -* Name: -* Labelat - -* Purpose: -* Determine the other axis value at which to place interior labels -* and tick marks. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Labelat( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, -* double *labelat, const char *method, const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* If tick marks and labels are to be placed within the plotting area, -* the tick values stored in "grid" determine their position on one -* axis, and their position on the other axis is determined by this -* function. If a value has been set for the "LabelAt" attribute, then -* it is used, otherwise the "other axis" value on the longest curve -* parallel to the "other axis" is used (although the curve "other axis -* = zero" is used if it passes through the plotting area and is not too -* short). The effective length assigned to each curve is reduced in -* proportion to the number of tick marks which are close to the edge -* of the plotting area. -* -* A flag is returned indicating if the two axes appear to be -* independent, in which case there is nothing to be gained by using -* interior labelling. - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick values on the axis. See function GridLines. -* cdata -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structure (one for each -* major tick value on the axis), holding information about breaks -* in the curves drawn to mark the major tick values. See function -* DrawGrid. -* labelat -* A pointer to a 2 element array in which to store the constant axis -* values at which tick marks are put. Element 0 is returned holding -* the axis 1 value at which tick marks for axis 0 are placed. Element -* 1 is returned holding the axis 0 value at which tick marks for axis -* 1 are placed. -* flags -* A pointer to a 2 element array. Each element is a flag which is -* returned non-zero if the corresponding axis -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* Returned Value: -* Zero if and only if the lines of constant axis value are all the -* same length for all tick marks on either axis. If this is so, using -* interior labelling will not enable any more major ticks to be -* drawn, and so there is no reason to switch to interior labelling (unless -* the user has specifically requested interior labelling). - -* Notes: -* - This function assumes the current Frame of the Plot is 2 -* dimensional, and it should not be called if this is not the case. -*/ - -/* Local Variables: */ - AstMapping *mapping; /* Mapping from graphics to physical coords */ - AstPointSet *pset2; /* Pointset for graphical tick positions */ - AstPointSet *pset[ 2 ];/* Pointsets for physical tick positions */ - AstPlotCurveData *cdt; /* Pointer to the AstPlotCurveData for the next tick */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - double **ptr2; /* Pointers to graphics pointset data */ - double *ptr1[ 2 ]; /* Pointers to physical pointset data */ - double *tvals[ 2 ]; /* Pointers to arrays of other axis values */ - double *value; /* Current tick value */ - double efflen; /* Effective length of current curve */ - double lim; /* Largest insignificant axis value */ - double margin; /* Width of margin around plotting area */ - double maxlen; /* Effective length of longest curve */ - double minlen; /* Effective length of shortest (non-zero) curve */ - double x; /* Tick X value */ - double xhi; /* Upper limit on acceptable X range */ - double xlo; /* Lower limit on acceptable X range */ - double y; /* Tick Y value */ - double yhi; /* Upper limit on acceptable Y range */ - double ylo; /* Lower limit on acceptable Y range */ - double zerolen; /* Effective length of curve for other axis = 0.0 */ - int axis; /* Current axis index */ - int i; /* Tick index for this axis */ - int nin; /* No. of counted ticks */ - int result; /* Does interior labelling allow more ticks to be drawn? */ - int tick; /* Tick index */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise */ - result = 1; - -/* Create two PointSets to hold a set of tick mark positions along each - axis. The values on "axis" will be taken from the info structure. For - each axis create an array to hold values for the "other" axis. */ - for( axis = 0; axis < 2; axis++ ){ - info = grid[ axis ]; - pset[ axis ] = astPointSet( info->nmajor, 2, "", status ); - tvals[ axis ] = (double *) astMalloc( sizeof(double)*(size_t)(info->nmajor) ); - } - -/* Get the mapping from Base (graphics) frame the Current (physical) */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Get the bounds of the area in which tick marks must occur to be - counted. This is the total plotting area minus a 5% margin at each - edge. */ - margin = 0.05*( this->xhi - this->xlo ); - xlo = this->xlo + margin; - xhi = this->xhi - margin; - - margin = 0.05*( this->yhi - this->ylo ); - ylo = this->ylo + margin; - yhi = this->yhi - margin; - -/* Do each axis. */ - for( axis = 0; axis < 2 && astOK; axis++ ){ - -/* Find the longest and shortest curves parallel to the axis being labelled. - Also find the length of the curve which passes through the origin of the - other axis which is within the plotting area. We need to do this even - if LabelAt has been set since we need to calculate the returned flag. */ - -/* Store pointers to the arrays holding tick mark physical coordinates, - and set these in the PointSet. */ - ptr1[ axis ] = grid[ axis ]->ticks; - ptr1[ 1 - axis ] = tvals[ axis ]; - astSetPoints( pset[ axis ], ptr1 ); - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along the other axis. */ - info = grid[ 1 - axis ]; - -/* Get a pointer to the other axis value at the first other axis major tick - mark. */ - value = info->ticks; - -/* Get a limit on absolute magnitude for an axis value to be consider - equal to zero. */ - lim = 1.0E-6*fabs( value[ 1 ] - value [ 0 ] ); - -/* Get a pointer to the structure containing information describing the - breaks in the curve which passes through the first major tick mark. */ - cdt = cdata[ 1 - axis ]; - -/* Initialise the effective length of the longest and shortest curves, and - the curve passing through the origin. */ - maxlen = -1.0; - minlen = DBL_MAX; - zerolen = 0.0; - labelat[ axis ] = AST__BAD; - -/* Loop round each of the major tick marks on the other axis. */ - for( tick = 0; tick < info->nmajor && astOK; tick++ ){ - -/* Fill the array of other axis values with the current other axis value. */ - for( i = 0; i < grid[ axis ]->nmajor; i++ ){ - tvals[ axis ][ i ] = *value; - } - -/* Transform the tick positions from the current frame (i.e. physical - coordinates) to the base frame (i.e. graphics coordinates) using - the inverse Mapping. */ - pset2 = Trans( this, NULL, mapping, pset[ axis ], 0, NULL, 0, - method, class, status ); - -/* Get pointers to the graphics coordinates. */ - ptr2 = astGetPoints( pset2 ); - if( astOK ) { - -/* Count the number of graphics positions which are well within the plotting - area. */ - nin = 0; - for( i = 0; i < grid[ axis ]->nmajor; i++ ){ - x = ptr2[ 0 ][ i ]; - y = ptr2[ 1 ][ i ]; - if( x != AST__BAD && x > xlo && x < xhi && - y != AST__BAD && y > ylo && y < yhi ) nin++; - } - -/* Find the effective length of this curve.*/ - efflen = sqrt( (float) nin )*cdt->length; - -/* If the curve through this tick mark has a greater effective length than any - other found so far, record it. */ - if( efflen > maxlen ){ - maxlen = efflen; - labelat[ axis ] = *value; - } - -/* If the curve through this tick mark has a smaller non-zero effective length - than any other found so far, record it. */ - if( efflen < minlen && efflen > 0.0 ) minlen = efflen; - -/* If this tick mark is at the origin, note the effective length. */ - if( fabs( *value ) <= lim ) zerolen = efflen; - -/* Get a pointer to the curve through the next major tick mark. */ - cdt++; - -/* Get a pointer to the axis value at the next major tick mark. */ - value++; - - } - -/* Free resources. */ - pset2 = astAnnul( pset2 ); - } - -/* Use the curve through the origin unless it is significantly shorter - than the longest curve. */ - if( zerolen > 0.4*maxlen ) labelat[ axis ] = 0.0; - -/* Return a flag if the lengths of the shortest and longest curves are nearly - equal. */ - if( ( maxlen - minlen )/( maxlen + minlen ) < 1.0E-5 ) result = 0; - -/* If the LabelAt attribute has been set, use it in preference to the - value found above. */ - if( astTestLabelAt( this, axis ) ){ - labelat[ axis ] = astGetLabelAt( this, axis ); - } - } - -/* Release resources. */ - for( axis = 0; axis < 2; axis++ ){ - if( pset[ axis ] ) pset[ axis ] = astAnnul( pset[ axis ] ); - if( tvals[ axis ] ) tvals[ axis ] = (double *) astFree( (void *) tvals[ axis ] ); - } - mapping = astAnnul( mapping ); - -/* Return. */ - return result; - -} - -static void Labels( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, - double *gap, double *labelat, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* Labels - -* Purpose: -* Draw numerical axis labels for a 2-D annotated coordinate grid. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Labels( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, -* double *gap, double *labelat, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The policy for placing labels for the major tick values is broadly as -* follows: if possible, labels for a given physical axis are placed on -* one edge of the plotting area, at the place where the curve for a -* major tick value crosses the edge. If very few of the curves cross -* the edge, then the label for a curve is placed at the intersection -* of that curve with the longest of the curves representing the major -* tick values on the other axis. - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick values on the axis. See function GridLines. -* cdata -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structure (one for each -* major tick value on the axis), holding information about breaks -* in the curves drawn to mark the major tick values. See function -* DrawGrid. -* gap -* Pointer to array of two values holding the gap between major -* tick values on the two axes. -* labelat -* A pointer to a 2 element array holding the constant axis -* values at which tick marks are put. Element 0 should hold -* the axis 1 value at which tick marks for axis 0 are placed. Element -* 1 should hold the axis 0 value at which tick marks for axis -* 1 are placed. If labels are to be placed round the edges of the -* plotting zone instead of within the plotting zone, then values of -* AST__BAD should be supplied. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function assumes the current Frame of the Plot is 2 -* dimensional, and it should not be called if this is not the case. -*/ - -/* Local Variables: */ - AstFrame *frame; /* Pointer to current Frame */ - AstMapping *mapping; /* Pointer to graphics->physical Mapping */ - AstPointSet *pset1; /* Pointer to PointSet holding physical coords. */ - AstPointSet *pset2; /* Pointer to PointSet holding graphics coords. */ - AstPlotCurveData *cdt; /* Pointer to the AstPlotCurveData for the next tick */ - LabelList *labellist; /* Pointer to list of labels to be plotted */ - LabelList *ll; /* Pointer to next label to be plotted */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - char just_buf[3]; /* Buffer to hold a justification string */ - const char *just; /* Justification string */ - const char *text; /* Pointer to label text */ - double *used; /* Pointer to list of used label values */ - double *value; /* Current tick value */ - double diff; /* Difference between adjacent major tick marks */ - double dx; /* Text base-line X component */ - double dy; /* Text base-line Y component */ - double gx; /* Reference position graphics X coord. */ - double gy; /* Reference position graphics Y coord. */ - double mindim; /* Shortest dimension of plotting area */ - double offx; /* X component of offset vector */ - double offy; /* Y component of offset vector */ - double rlen; /* Length of perpendicular vector */ - double rx; /* X comp of vector perpendicular to (dx,dy) */ - double ry; /* Y comp of vector perpendicular to (dx,dy) */ - double sin45; /* Sine of 45 degrees */ - double txtgap; /* Absolute gap between labels and edges */ - double upx; /* Text up-vector X component */ - double upy; /* Text up-vector Y component */ - double val[ 2 ]; /* Physical coordinates */ - float *box; /* Pointer to array of label bounding boxes */ - float alpha; /* Factor to convert graphics X to equal scaled X */ - float beta; /* Factor to convert graphics Y to equal scaled Y */ - int axis; /* Current axis index */ - int esc; /* Interpret escape sequences? */ - int flag; /* Flag indicating which way the base-vector points */ - int iused; /* Index into list of used axis values */ - int last; /* The index of the last tick to use */ - int logticks; /* ARe major ticks spaced logarithmically? */ - int nlab; /* The number of labels to be plotted */ - int nused; /* Number of used axis values */ - int t0; /* Index of central tick */ - int tick; /* Current tick index */ - int tinc; /* Increment between ticks */ - int upfree; /* Are we free to change the up-vector? */ - int gelid; /* ID for next graphical element to be drawn */ - -/* Check the global status. */ - if( !astOK ) return; - -/* See if escape sequences in text strings are to be interpreted */ - esc = astGetEscape( this ); - -/* Empty the list of bounding boxes kept by the Overlap function. */ - (void) Overlap( this, 0, 0, NULL, 0.0, 0.0, NULL, 0.0, 0.0, NULL, - method, class, status ); - -/* If required, draw the labels around the edges of the plotting area. */ - if( labelat[ 0 ] == AST__BAD || labelat[ 1 ] == AST__BAD ){ - (void) EdgeLabels( this, 1, grid, cdata, 1, method, class, status ); - -/* Otherwise, draw labels within the interior of the plotting area. */ - } else { - -/* Find the scale factors for the two axes which scale graphics coordinates - into a "standard" equal scaled coordinate system in which: 1) the axes - have equal scale in terms of (for instance) millimetres per unit distance, - 2) X values increase from left to right, 3) Y values increase from bottom - to top. */ - GScales( this, &alpha, &beta, method, class, status ); - -/* Get the minimum dimension of the plotting area in equal scaled coords. */ - mindim = astMIN( fabs( alpha*(this->xhi - this->xlo) ), - fabs( beta*(this->yhi - this->ylo) ) ); - -/* Store a value for the sine of 45 degrees. */ - sin45 = 1.0/sqrt( 2.0 ); - -/* Initialise the pointer to the memory holding the bounding boxes for - all labels (used by function Overlap). */ - box = NULL; - -/* Get a pointer to the current Frame in the Plot. */ - frame = astGetFrame( this, AST__CURRENT ); - -/* Get a pointer to the mapping form the base Frame to the current Frame in - the Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__NUMLAB1_ID; - -/* Do each axis. */ - for( axis = 0; axis < 2; axis++ ){ - -/* See of major ticks are spaced logarithmically on this axis. */ - logticks = astGetLogTicks( this, axis ); - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__TEXT, method, class ); - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along this axis. */ - info = grid[ axis ]; - -/* Only progress if there are some labels stored within the structure. */ - if( info->labels ) { - -/* Initialise the pointer to the list of text strings to be drawn. */ - labellist = NULL; - nlab = 0; - -/* See if numerical labels are always to be drawn horizontal. If so, set - a flag and initialise a vertical up-vector. */ - if( astGetLabelUp( this, axis ) ){ - upfree = 0; - upx = 0.0; - upy = 1.0; - -/* Otherwise, clear the flag and indicate that we do not yet have an - up-vector. */ - } else { - upfree = 1; - upx = AST__BAD; - upy = AST__BAD; - } - -/* Indicate that the tangent vector to the other axis is not yet - known. */ - dx = AST__BAD; - dy = AST__BAD; - gx = AST__BAD; - gy = AST__BAD; - -/* Store the gap to put next to the label text. This is in equal scaled - coords, not graphics coords. */ - txtgap = astGetNumLabGap( this, axis )*mindim; - -/* Get a pointer to the structure containing information describing the - breaks in the curve which passes through the first major tick mark. */ - cdt = cdata[ axis ]; - -/* Get a pointer to the axis value at the first major tick mark. */ - value = info->ticks; - -/* Initialise pointers to two PointSets which will be created and used - within function GVec. */ - pset1 = NULL; - pset2 = NULL; - -/* Get memory to hold the axis values at which labels have been put. */ - used = (double *) astMalloc( sizeof(double)*(size_t)info->nmajor ); - nused = 0; - -/* The tick marks are done in two batches, each batch working out from the - middle. This is done because there may be extra tick marks outside the - normal ranges at the extremes, and these should not be given the - priority caused by doing them first. Store the mid-tick index, the - current tick index, and the increment between ticks. The ticks from the - middle up to the highest index are done first. */ - t0 = info->nmajor/2; - tick = t0 - 1; - tinc = 1; - -/* Loop round until all ticks have been done. */ - last = info->nmajor - 1; - while( (tick += tinc) >= 0 && astOK ){ - -/* If we have done the highest tick index, start again at the tick just - below middle, and work done towards index zero. */ - if( tick == info->nmajor ){ - tick = t0 - 1; - tinc = -1; - } - -/* Store the reference position for the label . */ - val[ axis ] = value[ tick ]; - val[ 1 - axis ] = labelat[ axis ]; - -/* Store the difference between this tick and the next. */ - if( logticks ) { - diff = value[ tick ]*( gap[ axis ] - 1.0 ); - } else { - diff = gap[ axis ]; - } - -/* See if this axis value has already been used. */ - for( iused = 0; iused < nused; iused++ ){ - if( fabs( val[ axis ] - used[ iused ] ) < - 1.0E-3*diff ) break; - } - -/* If the axis value has already been used, don't use it again. */ - if( iused >= nused || nused == 0 ){ - used[ nused++ ] = val[ axis ]; - -/* We now need to decide where to put the reference point for the text - string, and what justification to use. Assuming that NumLabGap is +ve, - the labels are drawn on the left hand side of the axis as seen by - someone moving along the axis in the positive direction, with an - up-vector which is normal to the axis tangent. First, find the graphics - coordinates at the point being labelled, and the unit tangent-vector - parallel to the axis being labelled. If the tangent vector is not defined, - then the tangent vector used for the previous label is re-used. This - unit tangent vector is expressed in graphics coords. */ - GVec( this, mapping, val, axis, 0.01*diff, &pset1, - &pset2, &gx, &gy, &dx, &dy, &flag, method, class, - status ); - -/* If we now have a tangent vector and good graphics coordinates for the - label's reference position... */ - if( dx != AST__BAD && dy != AST__BAD && - gx != AST__BAD && gy != AST__BAD ){ - -/* Convert the unit tangent vector from graphics coords to equal-scaled coords. */ - dx *= alpha; - dy *= beta; - -/* Rotate through 90 degrees to get a vector perpendicular to the axis in - equal scaled coords. This vector points to the left as you move along - the physical axis in the positive direction. Find its length. */ - rx = -dy; - ry = dx; - rlen = sqrt( rx*rx + ry*ry ); - -/* The reference position for the text is displaced away from the - reference position normal to the axis on the left hand side by the - "txtgap" value. */ - offx = rx*txtgap/rlen; - offy = ry*txtgap/rlen; - gx += offx/alpha; - gy += offy/beta; - -/* The up-vector and justification for the text depends on whether or - not the up-vector is free to rotate. If it is free, the up-vector is - chosen so that the text is not upside-down. Note, the up-vector is - specified in the equally scaled coordinate system. */ - if( upfree ){ - - if( dx < -0.01*fabs( alpha ) ){ - upx = -rx; - upy = -ry; - just = ( txtgap < 0.0 )? "BC" : "TC"; - } else { - upx = rx; - upy = ry; - just = ( txtgap < 0.0 )? "TC" : "BC"; - } - if( txtgap == 0.0 ) just = "CC"; - -/* If the up vector is required to be vertical, a system is used which - tries to put the centre of the text string on or near the offset - vector. */ - } else { - upx = 0.0; - upy = 1.0; - - if( offy > fabs(txtgap)*sin45 ){ - just_buf[0] = 'B'; - } else if( offy < -fabs(txtgap)*sin45 ){ - just_buf[0] = 'T'; - } else { - just_buf[0] = 'C'; - } - if( txtgap == 0.0 ) just_buf[0] = 'C'; - - if( offx < -fabs(txtgap)*sin45 ){ - just_buf[1] = 'R'; - } else if( offx > fabs(txtgap)*sin45 ){ - just_buf[1] = 'L'; - } else { - just_buf[1] = 'C'; - } - if( txtgap == 0.0 ) just_buf[1] = 'C'; - - just_buf[2] = 0; - just = just_buf; - } - -/* Get the label text. */ - text = (info->labels)[ tick ]; - if( text ){ - -/* Check that the reference position is within the plotting area. - If so, add it to the list of labels to be drawn. */ - if( gx >= this->xlo && gx <= this->xhi && - gy >= this->ylo && gy <= this->yhi ){ - - labellist = (LabelList *) astGrow( (void *) labellist, nlab + 1, sizeof(LabelList) ); - if ( astOK ) { - (labellist + nlab)->index = tick; - (labellist + nlab)->text = (char *) astStore( NULL, (void *) text, strlen(text) + 1 ); - (labellist + nlab)->x = gx; - (labellist + nlab)->y = gy; - (labellist + nlab)->just = (char *) astStore( NULL, (void *) just, strlen(just) + 1 ); - (labellist + nlab)->upx = upx; - (labellist + nlab)->upy = upy; - (labellist + nlab)->val = val[ axis ]; - nlab++; - } else { - break; - } - } - } - } - } - } - -/* If any labels were stored, draw the text strings, and then release the - memory used to hold the text, etc. */ - if( nlab > 0 ) { - PlotLabels( this, esc, frame, axis, labellist, info->fmt, nlab, - &box, method, class, status ); - ll = labellist; - for( tick = 0; tick < nlab; tick ++ ) { - ll->text = (char *) astFree( (void *) ll->text ); - ll->just = (char *) astFree( (void *) ll->just ); - ll++; - } - labellist = (LabelList *) astFree( (void *) labellist ); - } - -/* Free the memory used to hold the axis values at which labels have - been put. */ - used = (double *) astFree( (void *) used ); - -/* Annul the PointSets (if used). */ - if( pset1 ) pset1 = astAnnul( pset1 ); - if( pset2 ) pset2 = astAnnul( pset2 ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__TEXT, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__NUMLAB2_ID; - - } - } - -/* Free the memory used to hold the bounding boxes. */ - box = (float *) astFree( (void *) box ); - -/* Annul the pointers to the Frame and the Mapping. */ - mapping = astAnnul( mapping ); - frame = astAnnul( frame ); - - } - -/* Return. */ - return; - -} - -static void LinePlot( AstPlot *this, double xa, double ya, double xb, - double yb, int ink, AstPlotCurveData *cdata, - const char *method, const char *class, int *status ){ -/* -* -* Name: -* LinePlot - -* Purpose: -* Draws a straight line omitting bad regions. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void LinePlot( AstPlot *this, double xa, double ya, double xb, -* double yb, int ink, AstPlotCurveData *cdata, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a straight line between two positions in graphics -* coordinates but leaves gaps in the line where it passes through -* regions which have no corresponding physical coordinates. - -* Parameters: -* this -* Pointer to the Plot. -* xa -* The graphics X coordinate at the start of the line. -* ya -* The graphics Y coordinate at the start of the line. -* xb -* The graphics X coordinate at the end of the line. -* yb -* The graphics Y coordinate at the end of the line. -* ink -* If zero, the line is not actually drawn, but information about -* the breaks is still returned. If non-zero, the line is also drawn. -* cdata -* A pointer to a structure in which to return information about the -* breaks in the line. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - No curve is draw if any of the start or end positions are bad -* (i.e. equal to AST__BAD), or if a NULL pointer is supplied for "cdata". -* No errors are reported in these cases. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - int i; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Check the supplied values are usable. */ - if( xa == AST__BAD || ya == AST__BAD || - xb == AST__BAD || yb == AST__BAD || - !cdata ) return; - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, this->yhi - this->ylo ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Set up the external variables used by the Crv and CrvLine function (see - their prologues for details). */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_limit = 0.5*tol*tol; - Crv_tol = tol; - Crv_map = Map2; - Crv_ink = ink; - Crv_len = 0.0F; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = cdata->xbrk; - Crv_ybrk = cdata->ybrk; - Crv_vxbrk = cdata->vxbrk; - Crv_vybrk = cdata->vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Create a set of evenly spaced values between 0.0 and 1.0. These are the - offsets the edge of the plotting zone at which the mapping is tested. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Now set up the externals used to communicate with the Map2 function. - Map2 transforms a set of offsets between zero and one into a set of - corresponding graphics coordinates, with bad values substituted for any - offsets which correspond to points outside the domain of the mapping. */ - -/* The number of axes in the physical coordinate system (i.e. the current - Frame). */ - Map2_ncoord = astGetNout( this ); - -/* A pointer to the mapping from graphics world cordinates to physical - coordinates. */ - Map2_plot = this; - Map2_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* The graphics coordinates corresponding to an offset of zero (i.e. - the start of the line). */ - Map2_x0 = xa; - Map2_y0 = ya; - -/* The increments in X and Y between offset zero (the start of the - line) and offset 1 (the end of the line). */ - Map2_deltax = xb - xa; - Map2_deltay = yb - ya; - -/* Get the graphics coordinates corresponding to the initial set of - offsets. */ - Map2( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map2 to draw the intersection of the straight line with - the region containing valid physical coordinates. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map2. */ - Map2( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - if( cdata ){ - cdata->length = Crv_len; - cdata->out = Crv_out; - cdata->nbrk = Crv_nbrk; - PurgeCdata( cdata, status ); - } - -/* Annul the Mapping. */ - Map2_map = astAnnul( Map2_map ); - -/* Return. */ - return; - -} - -static double **MakeGrid( AstPlot *this, AstFrame *frm, AstMapping *map, - int disk, int dim, double xlo, double xhi, - double ylo, double yhi, int nphy, AstPointSet **pset1, - AstPointSet **pset2, int norm, const char *method, - const char *class, int *status ){ -/* -* Name: -* MakeGrid - -* Purpose: -* Create a square grid of graphics coordinates and the corresponding -* physical coordinates. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double **MakeGrid( AstPlot *this, AstFrame *frm, AstMapping *map, -* int disk, int dim, double xlo, double xhi, double ylo, -* double yhi, int nphy, AstPointSet **pset1, -* AstPointSet **pset2, int norm, const char *method, -* const char *class, int *status ){ - -* Class Membership: -* Plot member function. - -* Description: -* This function creates two PointSets, one holding a square grid of -* graphics coordinates covering the supplied area, and the other -* holding the corresponding physical coordinates. The points are -* stored row by row in the returned PointSets, i.e. if the cell size -* for the grid is (dx,dy), the first point is (xmin,ymin), followed -* by (xmin+dx,ymin), (xmin+2*dx,ymin), up to (xmin+(dim-1)*dx,ymin), -* followed by the next row (xmin,ymin+dy), (xmin+dx,ymin+dy), etc. - -* Parameters: -* this -* The Plot. -* frm -* A pointer to the Current Frame in the Plot. If this is supplied -* NULL, then a pointer is found within this function if required (i.e. -* if "norm" is non-zero). -* map -* The Mapping from graphics to physical coordinates, extracted from -* the Plot. -* disk -* If non-zero, the corners of the grid are omitted form the -* returned PointSets, resulting in a grid that is more disk like than -* rectangular. -* dim -* The number of samples along each edge of the grid. -* xlo -* The lower bound on the first axis of the region to be covered -* by the grid. -* xhi -* The upper bound on the first axis of the region to be covered -* by the grid. -* ylo -* The lower bound on the second axis of the region to be covered -* by the grid. -* yhi -* The upper bound on the second axis of the region to be covered -* by the grid. -* nphy -* The number of axes in the physical cooridinate system. -* pset1 -* A pointer to a location at which to store a pointer to the -* PointSet holding the graphics coordinates. -* pset2 -* A pointer to a location at which to store a pointer to the -* PointSet holding the physical coordinates. -* norm -* If non-zero the physical cooridnates are normalised using the -* Plot's astNorm method. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the physical coordinate data stored in the PointSet -* "pset2". - -* Notes: -* - The returned PointSets should be annulled when no longer needed, -* using astAnnul. -* - NULL pointers are returned if an error has already occurred, or -* if this function should fail for any reason. -*/ - -/* Local Variables: */ - double **ptr1; /* Pointers to graphics axis values */ - double **ptr2; /* Pointers to physical axis values */ - int size; /* No. of points in the grid */ - -/* Initialise the returned pointers. */ - *pset1 = NULL; - *pset2 = NULL; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Create two PointSets. We assume for the moment that they cover the - full grid, including corners. */ - size = dim*dim; - *pset1 = astPointSet( size, 2, "", status ); - *pset2 = astPointSet( size, nphy, "", status ); - -/* Get pointers to the data arrays for the two PointSets. */ - ptr1 = astGetPoints( *pset1 ); - ptr2 = astGetPoints( *pset2 ); - -/* Create a grid covering the supplied area. */ - size = GraphGrid( dim, disk, xlo, xhi, ylo, yhi, ptr1, status ); - -/* If the corners are being omitted, reduce the number of points in the - two PointSets. */ - if( disk ) { - astSetNpoint( *pset1, size ); - astSetNpoint( *pset2, size ); - } - -/* Transform these graphics positions to physical coordinates. */ - Trans( this, frm, map, *pset1, 1, *pset2, norm, method, class, status ); - -/* If an error has occurred, annul the two pointsets. */ - if( !astOK ){ - *pset1 = astAnnul( *pset1 ); - *pset2 = astAnnul( *pset2 ); - ptr2 = NULL; - } - -/* Return. */ - return ptr2; - -} - - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* Plot member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to Plot structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* If defined, ensure the grfcontext KeyMap contained within the Plot is - locked, unlocked or checked. */ - if( this->grfcontext ) { - if( !result ) result = astManageLock( this->grfcontext, mode, extra, fail ); - -/* Also lock or unlock the associated object handle. */ - if( mode == AST__LOCK ) { - if( !result ) astLock( this->grfcontextID, extra ); - - } else if( mode == AST__UNLOCK ) { - if( !result ) astUnlock( this->grfcontextID, 0 ); - - } - } - - return result; - -} -#endif - -static void Map1( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map1 - -* Purpose: -* Find graphics coordinates at given distances along a curve -* parallel to a physical axis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map1( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances are converted into physical coordinates -* using the scalings described by various external variables, and then -* these physical coordinates are mapped into graphics coordinates. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the starting position supplied in external -* variable Map1_origin. A "dist" value of one corresponds to the -* finishing position which is a distance Map1_length away from -* Map1_origin, moving in the positive direction of the axis given -* by Map1_axis. "dist" values can be either linearly or -* logarithmically related to axis values (see Map1_log). -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist". -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map1_log = int (Read) -* If zero, then "dist" in learly related to axis value. Otherwise -* it is linearly related to log10(axis value). -* Map1_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map1_axis = int (Read) -* The zero-based index of the axis which the curve follows (i.e. -* the axis which changes value along the curve). -* Map1_statics = Map1Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map1. -* Map1_origin = const double * (Read) -* A pointer to an array holding the physical coordinate value on -* each axis at the start of the curve (i.e. at dist = 0.0). -* Map1_length = double (Read) -* The scale factor to convert "dist" values into increments -* along the physical axis given by Map1_axis. -* Map1_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map1_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates extracted from the Plot. -* Map1_frame = AstFrame * (Read) -* A pointer to the Current Frame in the Plot. -* Map1_norm = int (Read) -* A flag indicating if physical coordinate values which are not in -* the normal ranges of the corresponding axes should be considered -* bad. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ - -/* Local Constants: */ - Map1Statics *statics; /* Pointer to structure holding static data */ - double *p; /* Pointer to next value */ - double axval; /* Axis origin value */ - int i, j; /* Loop counts */ - -/* Convert the global "void *" pointer to a Map1Statics pointer */ - statics = (Map1Statics *) Map1_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->work1 ) statics->work1 = (double *) astFree( (void *) statics->work1 ); - if( statics->work2 ) statics->work2 = (double *) astFree( (void *) statics->work2 ); - Map1_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map1Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->ptr1 = NULL; - statics->pax = NULL; - statics->ptr2[ 0 ] = NULL; - statics->ptr2[ 1 ] = NULL; - statics->work1 = NULL; - statics->work2 = NULL; - statics->nl = 0; - Map1_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the physical coordinates corresponding to - the supplied offsets. First annul any existing PointSet. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, Map1_ncoord, "", status ); - statics->ptr1 = astGetPoints( statics->pset1 ); - -/* Create a PointSet to hold the corresponding graphics coordinates. - The supplied "x" and "y" arrays will be used to store the data - so we do not need to get pointers to the data using astGetPoints. First - annul any existing PointSet. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, 2, "", status ); - -/* Get work space to hold two positions. */ - statics->work1 = (double *) astRealloc( (void *) statics->work1, - sizeof(double)*(size_t)Map1_ncoord ); - statics->work2 = (double *) astRealloc( (void *) statics->work2, - sizeof(double)*(size_t)Map1_ncoord ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Store a pointer to the start of the memory which will be used to store - the physical data for the axis being drawn. */ - statics->pax = statics->ptr1[ Map1_axis ]; - -/* Fill the PointSet which is used to hold physical data with the physical - coordinates at the start of the curve. */ - for( i = 0; i < Map1_ncoord; i++ ){ - axval = Map1_origin[ i ]; - p = statics->ptr1[ i ]; - for( j = 0; j < n; j++ ) *(p++) = axval; - } - -/* Store the scale and offset to apply to the "dist" values. If Map1_log is - zero (linear axes) then applying these values gives axis value directly. - If Map1_log is non-zero (log axes) then applying these values gives - log10( axis value). */ - if( Map1_log ) { - statics->neg = ( Map1_origin[ Map1_axis ] < 0 ); - statics->axorig = log10( fabs( Map1_origin[ Map1_axis ] ) ); - statics->axscale = log10( fabs( Map1_origin[ Map1_axis ] + - Map1_length ) ) - statics->axorig; - } else { - statics->axorig = Map1_origin[ Map1_axis ]; - statics->axscale = Map1_length; - } - } - } - -/* Check the initialisation went OK (if done). */ - if( astOK ){ - -/* Loop round each offset along the curve, converting the normalised offset - in the range [0,1] to a physical coordinate and storing in PointSet 1. */ - p = statics->pax; - for( i = 0; i < n; i++){ - *(p++) = statics->axorig + statics->axscale*dist[ i ]; - } - if( Map1_log ) { - p = statics->pax; - for( i = 0; i < n; i++,p++ ){ - *p = statics->neg ? -pow( 10.0, *p ) : pow( 10.0, *p ); - } - } - -/* Store pointers to the results arrays in PointSet 2. */ - statics->ptr2[ 0 ] = x; - statics->ptr2[ 1 ] = y; - astSetPoints( statics->pset2, statics->ptr2 ); - -/* Map all the positions into graphics coordinates. */ - (void) Trans( Map1_plot, NULL, Map1_map, statics->pset1, 0, statics->pset2, 1, method, class, status ); - -/* If points not in their normal ranges are to be set bad... */ - if( Map1_norm ) { - -/* The following code simply normalizes the physical position, and if this - produces any change, the graphics positions are set bad. */ - for( i = 0; i < n; i++){ - for( j = 0; j < Map1_ncoord; j++) statics->work1[j] = statics->ptr1[j][i]; - astNorm( Map1_frame, statics->work1 ); - for( j = 0; j < Map1_ncoord; j++) { - if( !astEQUALS( statics->work1[j], statics->ptr1[j][i], 1.0E8 ) ) { - statics->ptr2[0][i] = AST__BAD; - statics->ptr2[1][i] = AST__BAD; - break; - } - } - } - } - } - -/* Return. */ - return; - -} - -static void Map2( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map2 - -* Purpose: -* Find which graphics coordinates have good physical coordinates -* at given distances along a straight line. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map2( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances refer to the distance along a straight line -* in the graphics coordinate system. The returned graphics coordinates -* correspond to the supplied distances, except that any position for -* which there are no defined physical coordinates is returned bad. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the graphics position supplied in external -* variables (Map2_x0, Map2_y0). A "dist" value of one corresponds to -* the graphics position which is offset from the start by the vector -* (Map2_deltax, Map2_deltay). -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist", -* except that any which have no corresponding physical coordinates -* are set to AST__BAD. -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist", -* except that any which have no corresponding physical coordinates -* are set to AST__BAD. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map2_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map2_x0 = double (Read) -* The graphics X coordinate at the start of the line (i.e. at dist -* = 0.0). -* Map2_y0 = double (Read) -* The graphics Y coordinate at the start of the line (i.e. at dist -* = 0.0). -* Map2_deltax = double (Read) -* The increment along the graphics X axis between the start and -* end of the line. -* Map2_deltay = double (Read) -* The increment along the graphics Y axis between the start and -* end of the line. -* Map2_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map2_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates, extracted from the Plot. -* Map2_statics = Map2Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map2. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ -/* Local Constants: */ - Map2Statics *statics; /* Pointer to structure holding static data */ - int i, j; /* Loop counts */ - double *p; /* Pointer to next physical value */ - double *px; /* Pointer to next x graphics value */ - double *py; /* Pointer to next y graphics value */ - -/* Convert the global "void *" pointer to a Map2Statics pointer */ - statics = (Map2Statics *) Map2_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - Map2_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map2Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->ptr2 = NULL; - statics->ptr1[ 0 ] = NULL; - statics->ptr1[ 1 ] = NULL; - statics->nl = 0; - Map2_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the graphics coordinates corresponding to - the supplied offsets. The supplied arrays will be used to hold the - data for this PointSet, and so astGetPoints is not called. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, 2, "", status ); - -/* Create a PointSet to hold the corresponding physical coordinates, and - get pointers to the associated axis values. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, Map2_ncoord, "", status ); - statics->ptr2 = astGetPoints( statics->pset2 ); - } - - -/* Check the initialisation went OK (if done). */ - if( astOK ){ - -/* Store pointers to the results arrays in PointSet 1. */ - statics->ptr1[ 0 ] = x; - statics->ptr1[ 1 ] = y; - astSetPoints( statics->pset1, statics->ptr1 ); - -/* Loop round each offset along the curve, converting the normalised offset - in the range [0,1] to graphics coordinate and storing in PointSet 1. */ - px = x; - py = y; - for( i = 0; i < n; i++){ - *(px++) = Map2_x0 + Map2_deltax*dist[ i ]; - *(py++) = Map2_y0 + Map2_deltay*dist[ i ]; - } - -/* Map all the positions into physical coordinates. */ - (void) Trans( Map2_plot, NULL, Map2_map, statics->pset1, 1, statics->pset2, 0, method, class, status ); - -/* Check the physical coordinates for bad values, setting the corresponding - graphics coordinates bad. */ - for( j = 0; j < Map2_ncoord; j++ ){ - p = statics->ptr2[ j ]; - px = x; - py = y; - - for( i = 0; i < n; i++){ - if( *(p++) == AST__BAD ){ - *(px++) = AST__BAD; - *(py++) = AST__BAD; - } else { - px++; - py++; - } - } - } - } - -/* Return. */ - return; - -} - -static void Map3( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map3 - -* Purpose: -* Find graphics coordinates at given distances along a geodesic curve -* between two physical coordinate positions. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map3( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances are converted into physical offsets along the -* geodesic curve joining the starting and finishing points given by -* externals Map3_origin and Map3_end. The physical coordinates at these -* offsets are found, and transformed into graphics coordinates. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the starting position supplied in external -* variable Map3_origin. A "dist" value of one corresponds to the -* finishing position given by Map3_end. -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist". -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map3_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map3_origin = const double * (Read) -* A pointer to an array holding the physical coordinate value on -* each axis at the start of the curve (i.e. at dist = 0.0). -* Map3_end = const double * (Read) -* A pointer to an array holding the physical coordinate value on -* each axis at the end of the curve (i.e. at dist = 1.0). -* Map3_scale = double (Read) -* The scale factor to convert "dist" values into physical offsets -* along the geodesic curve. -* Map3_statics = Map3Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map3. -* Map3_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map3_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates extracted from the Plot. -* Map3_frame = AstFrame * (Read) -* A pointer to the Current Frame in the Plot. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ - -/* Local Constants: */ - Map3Statics *statics; /* Pointer to structure holding static data */ - int i, j; /* Loop counts */ - -/* Convert the global "void *" pointer to a Map3Statics pointer */ - statics = (Map3Statics *) Map3_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->pos ) statics->pos = (double *) astFree( (void *) statics->pos ); - Map3_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map3Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->ptr1 = NULL; - statics->ptr2[ 0 ] = NULL; - statics->ptr2[ 1 ] = NULL; - statics->nc = 0; - statics->nl = 0; - statics->pos = NULL; - Map3_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the physical coordinates corresponding to - the supplied offsets. First annul any existing PointSet. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, Map3_ncoord, "", status ); - statics->ptr1 = astGetPoints( statics->pset1 ); - -/* Create a PointSet to hold the corresponding graphics coordinates. - The supplied "x" and "y" arrays will be used to store the data - so we do not need to get pointers to the data using astGetPoints. First - annul any existing PointSet. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, 2, "", status ); - - } - -/* If the number of physical axes is different to last time, allocate - memory to hold a single physical position. */ - if( statics->nc != Map3_ncoord ){ - statics->nc = Map3_ncoord; - statics->pos = (double *) astMalloc( sizeof(double)*(size_t)Map3_ncoord ); - } - -/* Check the initialisation went OK (if done). */ - if( astOK ){ - -/* Loop round each offset along the curve, converting the normalised offset - in the range [0,1] to a physical offset, and then into a physical - position, and store in PointSet 1. */ - for( i = 0; i < n; i++){ - astOffset( Map3_frame, Map3_origin, Map3_end, Map3_scale*dist[ i ], - statics->pos ); - - for( j = 0; j < Map3_ncoord; j++ ){ - statics->ptr1[ j ][ i ] = statics->pos[ j ]; - } - - } - -/* Store pointers to the results arrays in PointSet 2. */ - statics->ptr2[ 0 ] = x; - statics->ptr2[ 1 ] = y; - astSetPoints( statics->pset2, statics->ptr2 ); - -/* Map all the positions into graphics coordinates. */ - (void) Trans( Map3_plot, NULL, Map3_map, statics->pset1, 0, statics->pset2, 1, method, class, status ); - } - -/* Return. */ - return; - -} - -static void Map4( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map4 - -* Purpose: -* Find graphics coordinates at given distances along a user -* specified curve. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map4( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances are converted into physical coordinates using -* the Mapping Map4_umap. These physical coordinates are transformed into -* graphics coordinates. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the starting position supplied in external -* variable Map3_origin. A "dist" value of one corresponds to the -* finishing position given by Map3_end. -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist". -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map4_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map4_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map4_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates extracted from the Plot. -* Map4_statics = Map4Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map4. -* Map4_umap = AstMapping * (Read) -* A pointer to the mapping from distance along the curve to physical -* coordinates. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ - -/* Local Variables: */ - Map4Statics *statics; /* Pointer to structure holding static data */ - double *ptr1[ 1 ]; /* Pointer to distances data */ - double *ptr3[ 2 ]; /* Pointers to graphics coord data */ - -/* Convert the global "void *" pointer to a Map4Statics pointer */ - statics = (Map4Statics *) Map4_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->pset3 ) statics->pset3 = astAnnul( statics->pset3 ); - Map4_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map4Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->pset3 = NULL; - statics->nl = 0; - Map4_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the distances along the curve. First annul any - existing PointSet. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, 1, "", status ); - -/* Create a PointSet to hold the physical coordinates corresponding to - the supplied distances. First annul any existing PointSet. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, Map4_ncoord, "", status ); - -/* Create a PointSet to hold the corresponding graphics coordinates. - First annul any existing PointSet. */ - if( statics->pset3 ) statics->pset3 = astAnnul( statics->pset3 ); - statics->pset3 = astPointSet( n, 2, "", status ); - - } - -/* Check the initialisation went OK (if done). */ - if( astOK ){ - -/* Use Map4_umap to convert the supplied distances into physical coords - (i.e. coords in the current Frame of the Plot). */ - ptr1[ 0 ] = dist; - astSetPoints( statics->pset1, ptr1 ); - (void) astTransform( Map4_umap, statics->pset1, 1, statics->pset2 ); - -/* Store pointers to the results arrays in PointSet 2. */ - ptr3[ 0 ] = x; - ptr3[ 1 ] = y; - astSetPoints( statics->pset3, ptr3 ); - -/* Now transform these physical coords into graphical coords, - incorporating clipping. */ - (void) Trans( Map4_plot, NULL, Map4_map, statics->pset2, 0, statics->pset3, 1, method, class, status ); - } - -/* Return. */ - return; - -} - -static void Map5( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map5 - -* Purpose: -* Find graphics coordinates at given distances along the boundary of -* a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map5( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances are converted into physical coordinates -* using the Region specified by an external variable, and then -* these physical coordinates are mapped into graphics coordinates. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the starting position supplied in external -* variable Map1_origin. A "dist" value of one corresponds to the -* finishing position which is a distance Map1_length away from -* Map1_origin, moving in the positive direction of the axis given -* by Map1_axis. "dist" values can be either linearly or -* logarithmically related to axis values (see Map1_log). -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist". -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map1_log = int (Read) -* If zero, then "dist" in learly related to axis value. Otherwise -* it is linearly related to log10(axis value). -* Map1_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map1_axis = int (Read) -* The zero-based index of the axis which the curve follows (i.e. -* the axis which changes value along the curve). -* Map1_statics = Map1Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map1. -* Map1_origin = const double * (Read) -* A pointer to an array holding the physical coordinate value on -* each axis at the start of the curve (i.e. at dist = 0.0). -* Map1_length = double (Read) -* The scale factor to convert "dist" values into increments -* along the physical axis given by Map1_axis. -* Map1_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map1_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates extracted from the Plot. -* Map1_frame = AstFrame * (Read) -* A pointer to the Current Frame in the Plot. -* Map1_norm = int (Read) -* A flag indicating if physical coordinate values which are not in -* the normal ranges of the corresponding axes should be considered -* bad. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ - -/* Local Constants: */ - Map5Statics *statics; /* Pointer to structure holding static data */ - -/* Convert the global "void *" pointer to a Map5Statics pointer */ - statics = (Map5Statics *) Map5_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - Map5_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map3Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->ptr1 = NULL; - statics->ptr2[ 0 ] = NULL; - statics->ptr2[ 1 ] = NULL; - statics->nl = 0; - Map5_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the physical coordinates corresponding to - the supplied offsets. First annul any existing PointSet. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, Map5_ncoord, "", status ); - statics->ptr1 = astGetPoints( statics->pset1 ); - -/* Create a PointSet to hold the corresponding graphics coordinates. - The supplied "x" and "y" arrays will be used to store the data - so we do not need to get pointers to the data using astGetPoints. First - annul any existing PointSet. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, 2, "", status ); - } - -/* Get the physical coords at the required positions along the Region - border. */ - astRegTrace( Map5_region, n, dist, statics->ptr1 ); - -/* Store pointers to the results arrays in PointSet 2. */ - statics->ptr2[ 0 ] = x; - statics->ptr2[ 1 ] = y; - astSetPoints( statics->pset2, statics->ptr2 ); - -/* Map all the positions into graphics coordinates. */ - (void) Trans( Map5_plot, NULL, Map5_map, statics->pset1, 0, - statics->pset2, 1, method, class, status ); - -/* Return. */ - return; -} - -static void Mark( AstPlot *this, int nmark, int ncoord, int indim, - const double *in, int type, int *status ){ -/* -*++ -* Name: -c astMark -f AST_MARK - -* Purpose: -* Draw a set of markers for a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astMark( AstPlot *this, int nmark, int ncoord, int indim, -c const double *in, int type ) -f CALL AST_MARK( THIS, NMARK, NCOORD, INDIM, IN, TYPE, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a set of markers (symbols) at positions -f This routine draws a set of markers (symbols) at positions -* specified in the physical coordinate system of a Plot. The -* positions are transformed into graphical coordinates to -* determine where the markers should appear within the plotting -* area. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c nmark -f NMARK = INTEGER (Given) -* The number of markers to draw. This may be zero, in which -* case nothing will be drawn. -c ncoord -f NCOORD = INTEGER (Given) -* The number of coordinates being supplied for each mark -* (i.e. the number of axes in the current Frame of the Plot, as -* given by its Naxes attribute). -c indim -f INDIM = INTEGER (Given) -c The number of elements along the second dimension of the "in" -f The number of elements along the first dimension of the IN -* array (which contains the marker coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -c given should not be less than "nmark". -f given should not be less than NMARK. -c in -f IN( INDIM, NCOORD ) = DOUBLE PRECISION (Given) -c The address of the first element of a 2-dimensional array of -c shape "[ncoord][indim]" giving the -c physical coordinates of the points where markers are to be -c drawn. These should be stored such that the value of -c coordinate number "coord" for input mark number "mark" is -c found in element "in[coord][mark]". -f A 2-dimensional array giving the physical coordinates of the -f points where markers are to be drawn. These should be -f stored such that the value of coordinate number COORD for -f input mark number MARK is found in element IN(MARK,COORD). -c type -f TYPE = INTEGER (Given) -* A value specifying the type (e.g. shape) of marker to be -* drawn. The set of values which may be used (and the shapes -* that will result) is determined by the underlying graphics -* system. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Markers are not drawn at positions which have any coordinate -* equal to the value AST__BAD (or where the transformation into -* graphical coordinates yields coordinates containing the value -* AST__BAD). -c - If any marker position is clipped (see astClip), then the -f - If any marker position is clipped (see AST_CLIP), then the -* entire marker is not drawn. -* - An error results if the base Frame of the Plot is not 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *mapping; /* Pointer to graphics->physical mapping */ - AstPointSet *pset1; /* PointSet holding physical positions */ - AstPointSet *pset2; /* PointSet holding graphics positions */ - const char *class; /* Object class */ - const char *method; /* Current method */ - const double **ptr1; /* Pointer to physical positions */ - double **ptr2; /* Pointer to graphics positions */ - double *xpd; /* Pointer to next double precision x value */ - double *ypd; /* Pointer to next double precision y value */ - double xx; /* X axis value */ - double yy; /* Y axis value */ - float *x; /* Pointer to single precision x values */ - float *xpf; /* Pointer to next single precision x value */ - float *y; /* Pointer to single precision y values */ - float *ypf; /* Pointer to next single precision y value */ - int axis; /* Axis index */ - int clip; /* Clips marks at plot boundary? */ - int i; /* Loop count */ - int naxes; /* No. of axes in the base Frame */ - int nn; /* Number of good marker positions */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astMark"; - class = astClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Also validate the input array dimension argument. */ - if ( astOK && ( indim < nmark ) ) { - astError( AST__DIMIN, "%s(%s): The input array dimension value " - "(%d) is invalid.", status, method, class, indim ); - astError( AST__DIMIN, "This should not be less than the number of " - "markers being drawn (%d).", status, nmark ); - } - -/* Initialise the bounding box for primatives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__MARKS_ID, 1, GRF__MARK, method, class ); - -/* Create a PointSet to hold the supplied physical coordinates. */ - pset1 = astPointSet( nmark, ncoord, "", status ); - -/* Allocate memory to hold pointers to the first value on each axis. */ - ptr1 = (const double **) astMalloc( sizeof( const double * )* - (size_t)( ncoord )); - -/* Check the pointer can be used, then store pointers to the first value - on each axis. */ - if( astOK ){ - for( axis = 0; axis < ncoord; axis++ ){ - ptr1[ axis ] = in + axis*indim; - } - } - -/* Store these pointers in the PointSet. */ - astSetPoints( pset1, (double **) ptr1 ); - -/* Transform the supplied data from the current frame (i.e. physical - coordinates) to the base frame (i.e. graphics coordinates) using - the inverse Mapping defined by the Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - pset2 = Trans( this, NULL, mapping, pset1, 0, NULL, 0, method, class, status ); - mapping = astAnnul( mapping ); - -/* Get pointers to the graphics coordinates. */ - ptr2 = astGetPoints( pset2 ); - -/* Allocate memory to hold single precision versions of the graphics - coordinates. */ - x = (float *) astMalloc( sizeof( float )*(size_t) nmark ); - y = (float *) astMalloc( sizeof( float )*(size_t) nmark ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Store pointers to the next single and double precision x and y - values. */ - xpf = x; - ypf = y; - xpd = ptr2[ 0 ]; - ypd = ptr2[ 1 ]; - -/* Convert the double precision values to single precision, rejecting - any bad marker positions. If clipping is switched on, also clip any - markers with centres outside the plotting area. */ - clip = astGetClip( this ) & 2; - nn = 0; - for( i = 0; i < nmark; i++ ){ - if( *xpd != AST__BAD && *ypd != AST__BAD ){ - xx = *(xpd++); - yy = *(ypd++); - if( !clip || ( xx >= this->xlo && xx <= this->xhi && - yy >= this->ylo && yy <= this->yhi ) ) { - nn++; - *(xpf++) = (float) xx; - *(ypf++) = (float) yy; - } - } else { - xpd++; - ypd++; - } - } - -/* Draw the remaining markers. */ - GMark( this, nn, x, y, type, method, class, status ); - - } - -/* Free the memory used to store single precision graphics coordinates. */ - x = (float *) astFree( (void *) x ); - y = (float *) astFree( (void *) y ); - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Free the memory holding the pointers to the first value on each axis. */ - ptr1 = (const double **) astFree( (void *) ptr1 ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__MARKS_ID, 0, GRF__MARK, method, class ); - -/* Return */ - return; -} - -static void Mirror( AstPlot *this, int axis, int *status ){ -/* -*+ -* Name: -* astMirror - -* Purpose: -* Flip a graphics axis of a Plot. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* void astMirror( AstPlot *this, int axis ) - -* Class Membership: -* Plot method. - -* Description: -* This function referses the direction of a specified graphics axis -* in the Plot. - -* Parameters: -* this -* Pointer to a Plot. -* axis -* The zero-based axis of the axis to mirror. - -*- -*/ - -/* Check the global status. */ - if( !astOK ) return; - - if( axis == 0 ) { - this->xrev = ( this->xrev == 0 ); - - } else if( axis == 1 ){ - this->yrev = ( this->yrev == 0 ); - - } else { - astError( AST__INTER, "astMirror(%s): Illegal axis index (%d) " - "supplied (internal AST programming error).", status, - astGetClass( this ), axis ); - } -} - -static void Norm1( AstMapping *map, int axis, int nv, double *vals, - double refval, double width, int *status ){ -/* -* Name: -* Norm1 - -* Purpose: -* Use a Mapping to normalize an array of axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Norm1( AstMapping *map, int axis, int nv, double *vals, -* double refval, double width, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The normalization of a position in physical space has two parts; -* firstly, the Mapping may determine a form of normalization; -* secondly, the Frame may provide an additional normalizion by the -* astNorm method. This function implements normalization using a -* Mapping, by transforming the physical position into Graphics position, -* and then back into a physical position. For instance, if the Mapping -* represents a mapping of Cartesian graphics axes onto a 2D polar -* coordinate system, a physical theta value of 3.PI will be normalized by -* the Mapping into a theta value of 1.PI (probably, but it depends on -* the Mapping). In this case, the Mapping normalization may well be the -* only normalization available, since the 2D polar coord. system will -* probably use a simple Frame to represent the (radius,theta) system, -* and a simple Frame defines no normalization (i.e. the astNorm method -* returns the supplied position unchanged). -* -* Complications arise though because it is not possible to normalise -* a single axis value - you can only normalize a complete position. -* Therefore some value must be supplied for the other axis. We -* should use the LabelAt value, but we do not yet know what the LabelAt -* value will be. Instead, we try first using the supplied "refval" -* which should be close to the mode of the other aixs values. Usually -* the value used is not very important. However, for some complex -* projections (such as quad-cubes, TSC, etc) the choice can be more -* critical since some positions on the ksy correspond to undefined -* graphics positions (e.g the face edges in a TSC projection). -* Therefore, if the supplied refval results in any positions being -* undefined we refine the process by transforming the undefined -* positaons again using a different refval. We do this twice to bump -* up the likelihood of finding a suitable reference value. - -* Parameters: -* mapping -* The Mapping from Graphics Frame to the current Frame. -* axis -* The index of the axis for which values are supplied in "vals". -* nv -* The number of values supplied in "vals". -* vals -* Pointer to an array of axis values. On exit they are normalized. -* refval -* The preffered constant value to use for the other axis when -* normalizing the values in "vals". -* width -* The range of used values for the other axis. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* PointSet holding physical coords */ - AstPointSet *pset2; /* PointSet holding graphics coords */ - double **ptr1; /* Pointer to physical coords data */ - double *a; /* Pointer to next axis value */ - double *b; /* Pointer to next axis value */ - int i; /* Loop count */ - int itry; /* Loop count for re-try loop */ - int nbad; /* No. of bad values found after transformation */ - int *flags; /* Pointer to flags array */ - -/* Check the inherited global status. */ - if( !astOK ) return; - -/* Store the supplied positions in a PointSet. */ - pset1 = astPointSet( nv, 2, "", status ); - ptr1 = astGetPoints( pset1 ); - if( astOK ) { - a = ptr1[ axis ]; - b = ptr1[ 1 - axis ]; - for( i = 0; i < nv; i++){ - *(a++) = vals[ i ]; - *(b++) = refval; - } - } - -/* Transform the supplied positions into the Base Frame. */ - pset2 = astTransform( map, pset1, 0, NULL ); - -/* Transform the Base Frame positions back into the Current Frame. */ - (void) astTransform( map, pset2, 1, pset1 ); - -/* Allocate memory to hold a flag for each position which is non-zero if - we currently have a good axis value to return for the position. */ - flags = (int *) astMalloc( sizeof(int)* (size_t) nv ); - -/* If good, store these values back in the supplied array. If the - transformed values are bad, retain the original good values for the - moment in "vals", and also copy the good values back into pset1. So - at the end, pset1 will contain the original good values at any points - which produced bad values after the above transformation - the other - points in pset1 will be bad. */ - nbad = 0; - if( astOK ) { - a = ptr1[ axis ]; - for( i = 0; i < nv; i++, a++ ){ - if( *a != AST__BAD ) { - vals[ i ] = *a; - *a = AST__BAD; - flags[ i ] = 1; - } else if( vals[ i ] != AST__BAD ) { - nbad++; - *a = vals[ i ]; - flags[ i ] = 0; - } else { - flags[ i ] = 1; - } - } - } - -/* We now try normalising any remaining bad positions using different - values for the other axis. This may result in some or all of the - remaining points being normalised succesfully. */ - for( itry = 0; itry < 10; itry++ ) { - -/* If the above transformation produced any bad values, try again with a - different value on the other axis. */ - if( astOK && nbad > 0 ) { - b = ptr1[ 1 - axis ]; - for( i = 0; i < nv; i++){ - *(b++) = refval + 0.1*( itry + 1 )*width; - } - -/* Transform to graphics coords and back to world coords. */ - (void) astTransform( map, pset1, 0, pset2 ); - (void) astTransform( map, pset2, 1, pset1 ); - -/* Copy any good positions back into the returned vals array. Count - remaining bad positions. */ - a = ptr1[ axis ]; - nbad = 0; - for( i = 0; i < nv; i++, a++ ){ - if( *a != AST__BAD ) { - vals[ i ] = *a; - flags[ i ] = 1; - *a = AST__BAD; - } else if( !flags[ i ] ) { - nbad++; - *a = vals[ i ]; - } - } - } - -/* If the above transformation produced any bad values, try again with a - different value on the other axis. */ - if( astOK && nbad > 0 ) { - b = ptr1[ 1 - axis ]; - for( i = 0; i < nv; i++){ - *(b++) = refval - 0.1*( itry + 1 )*width; - } - -/* Transform to graphics coords and back to world coords. */ - (void) astTransform( map, pset1, 0, pset2 ); - (void) astTransform( map, pset2, 1, pset1 ); - -/* Copy any good positions back into the returned vals array. Count - remaining bad positions. */ - a = ptr1[ axis ]; - nbad = 0; - for( i = 0; i < nv; i++, a++ ){ - if( *a != AST__BAD ) { - vals[ i ] = *a; - flags[ i ] = 1; - *a = AST__BAD; - } else if( !flags[ i ] ) { - nbad++; - *a = vals[ i ]; - } - } - } - } - -/* Free resources. */ - flags = (int *) astFree( flags ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -} - -static void Opoly( AstPlot *this, int *status ){ -/* -* Name: -* Opoly - -* Purpose: -* Draws the current poly line. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Opoly( AstPlot *this, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws the current poly line, and empties the buffer. - -* Parameters: -* this -* Pointer to the Plot. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int ipoly; /* Index of new polyline */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Draw the poly-line if needed. */ - if( Poly_n > 0 ) { - -/* Extend the global arrays that hold pointers to the polylines already - drawn. */ - ipoly = Poly_npoly++; - astBeginPM; - Poly_xp = astGrow( Poly_xp, Poly_npoly, sizeof(float*) ); - Poly_yp = astGrow( Poly_yp, Poly_npoly, sizeof(float*) ); - Poly_np = astGrow( Poly_np, Poly_npoly, sizeof(int) ); - astEndPM; - - if( astOK ) { - -/* Add pointers to the new polyline to the end of the above extended - arrays. */ - Poly_xp[ ipoly ] = Poly_x; - Poly_yp[ ipoly ] = Poly_y; - Poly_np[ ipoly ] = Poly_n; - -/* Indicate that the current polyline is now empty. */ - Poly_x = NULL; - Poly_y = NULL; - Poly_n = 0; - } - } -} - -static int Overlap( AstPlot *this, int mode, int esc, const char *text, float x, - float y, const char *just, float upx, float upy, - float **work, const char *method, const char *class, int *status ){ -/* -* Name: -* Overlap - -* Purpose: -* See if a major tick value label would overlap any of the previously -* drawn labels. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Overlap( AstPlot *this, int mode, int esc, const char *text, float x, -* float y, const char *just, float upx, float upy, -* float **work, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The operation of this function is determined by the "mode" parameter. - -* A record is kept of the bounding boxes enclosing all the displayed -* labels. If the bounding box of the new label defined by the given -* parameter values would overlap any of the old bounding boxes, 0 is -* returned. Otherwise 1 is returned and the bounding box for the new -* label is added to the list of old bounding boxes. - -* This function also updates the external variables Box_lbnd and -* Box_ubnd which hold the lower and upper bounds of the area enclosing -* all used labels. - -* Parameters: -* this -* A pointer to the Plot. -* mode -* - If -1, find the bounding box of the supplied label, add it -* to the list of stored bounding box, and return 1 if it overlaps -* any previously stored bounding boxes. -* - If -2, leave the bounding boxes unchanged and return the -* number of bounding boxes currently stored. No other action is taken -* and all other arguments are ignored. -* - Otherwise, reset the number of stored bounding boxes to the -* value of mode, and return the new number of bounding boxes. No -* action is taken if mode is less than zero or greater than the current -* number of stored boxes. No other action is taken and all other -* arguments are ignored. -* esc -* Should escape sequences in the text be interpreted? -* text -* A pointer to the label text string. -* x -* The graphics X coordinate of the label's reference point. -* y -* The graphics Y coordinate of the label's reference point. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text. -* upy -* The y component of the up-vector for the text. -* work -* A pointer to a place at which to store a pointer to an array of -* floats holding the old bounding boxes. Memory to hold this array -* is allocated automatically within this function. The pointer to -* the array should be supplied as NULL on the first call to this -* function, and the array should be freed using astFree when no -* longer needed. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* See parameter "mode." - -* Notes: -* - Zero is returned if an error has occurred, or if this function -* should fail for any reason. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int nbox = 0; /* Number of boxes stored in "work" */ - int ret; /* Does the new label overlap a previous label? */ - int i; /* Box index */ - float *cx; /* Pointer to next corner's X value */ - float *cy; /* Pointer to next corner's Y value */ - float xbn[ 4 ]; /* X coords at corners of new label's bounding box */ - float ybn[ 4 ]; /* Y coords at corners of new label's bounding box */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Initialise the returned value to indicate no overlap has been found. */ - ret = 0; - -/* Get the number of bounding boxes in the supplied work array. */ - if( work && *work ) { - nbox = (*work)[ 0 ]; - } else { - nbox = 0; - } - -/* If required, return the number of bounding boxes currently stored. */ - if( mode == -2 ) return nbox; - -/* If required, reset the number of bounding boxes currently stored, and - return the new number. */ - if( mode >= 0 ) { - if( mode < nbox && work && *work ) { - nbox = mode; - (*work)[ 0 ] = nbox; - } - return nbox; - } - -/* If no work array has been supplied, allocate one now with room for - 10 boxes. Each box requires 8 floats, 2 for each of the 4 corners. The - X graphics coordinates at the 4 corners are stored in the first 4 floats, - and the corresponding Y graphics coordinates in the second group of 4 - floats. */ - if( work && !(*work) ) { - *work = (float *) astMalloc( 81*sizeof(float) ); - if( astOK ) { - nbox = 0; - (*work)[ 0 ] = 0; - } - } - -/* Check the global status. */ - if( !astOK ) return ret; - -/* Get the bounds of the box containing the new label. */ - DrawText( this, 0, esc, text, x, y, just, upx, upy, - xbn, ybn, NULL, method, class, status ); - -/* If the bounding box was obtained succesfully... */ - if( astOK ) { - -/* Check for an overlap between the box and each of the previous boxes. */ - cx = *work + 1; - cy = cx + 4; - for( i = 0; i < nbox; i++ ){ - - if( BoxCheck( xbn, ybn, cx, cy, status ) ) { - ret = 1; - break; - } - -/* Increment the pointers to the next box. */ - cx += 8; - cy += 8; - - } - -/* If no overlap was found, add the new box to the list. */ - if( !ret ){ - *work = (float *) astGrow( (void *) *work, 8*nbox + 9, sizeof(float) ); - cx = *work + 1 + 8*nbox; - cy = cx + 4; - for( i = 0; i < 4; i++ ){ - cx[ i ] = xbn[ i ]; - cy[ i ] = ybn[ i ]; - } - (*work)[ 0 ]++; - -/* Extend the bounds of the global bounding box held externally to include - the new box. */ - for( i = 0; i < 4; i++ ){ - Box_lbnd[ 0 ] = astMIN( xbn[ i ], Box_lbnd[ 0 ] ); - Box_ubnd[ 0 ] = astMAX( xbn[ i ], Box_ubnd[ 0 ] ); - Box_lbnd[ 1 ] = astMIN( ybn[ i ], Box_lbnd[ 1 ] ); - Box_ubnd[ 1 ] = astMAX( ybn[ i ], Box_ubnd[ 1 ] ); - } - } - } - -/* If an error has occur, return a value of 0. */ - if( !astOK ) ret = 0; - -/* Return the answer. */ - return ret; - -} - -static void PlotLabels( AstPlot *this, int esc, AstFrame *frame, int axis, - LabelList *list, char *fmt, int nlab, float **box, - const char *method, const char *class, int *status ) { -/* -* -* Name: -* PlotLabels - -* Purpose: -* Draws the numerical labels which have been selected for display. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void PlotLabels( AstPlot *this, int esc, AstFrame *frame, int axis, -* LabelList *list, char *fmt, int nlab, float **box, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function displays the numerical labels supplied in the -* structure pointed to by "list". Overlapping labels are omitted, -* and redundant leading fields are removed from adjacent labels. -* Nothing is plotted if the NumLab attribute for the axis is false. - -* Parameters: -* this -* A pointer to the Plot. -* esc -* Interpret escape sequences in labels? -* frame -* A pointer to the current Frame of the Plot. -* axis -* The axis index (0 or 1). -* list -* A pointer to the LabelList structure holding information about -* the selected numerical labels. -* fmt -* A pointer to a null terminated string holding the format -* specification used to create the labels. -* nlab -* The number of labels described by "list". -* box -* A pointer to a place at which to store a pointer to an array of -* floats holding the bounding boxes of displayed labels. Memory to -* hold this array is allocated automatically within this function. -* The pointer to the array should be supplied as NULL on the first -* call to this function, and the array should be freed using astFree -* when no longer needed. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - LabelList *ll; /* Pointer to next label structure */ - LabelList *llhi; /* Pointer to higher neighbouring label structure */ - LabelList *lllo; /* Pointer to lower neighbouring label structure */ - char *text; /* Pointer to label text */ - const char *latext; /* Axis label at previous label */ - const char *texthi; /* Pointer to text abbreviated with higher neighbour */ - const char *textlo; /* Pointer to text abbreviated with lower neighbour */ - float tolx; /* Min allowed X interval between labels */ - float toly; /* Min allowed Y interval between labels */ - float xbn[ 4 ]; /* X coords at corners of new label's bounding box */ - float ybn[ 4 ]; /* Y coords at corners of new label's bounding box */ - int abb; /* Abbreviate leading fields? */ - int dp; /* Number of decimal places */ - int found; /* Non-zero digit found? */ - int hilen; /* Length of texthi */ - int i; /* Label index */ - int j; /* Label index offset */ - int jgap; /* Gap in index between rejected labels */ - int lab0; /* Index of middle label */ - int lolen; /* Length of textlo */ - int mxdp; /* Maximum number of decimal places */ - int nbox; /* The number of boinding boxes supplied */ - int nexti; /* Index of next label to retain */ - int nleft; /* No. of labels left */ - int nz; /* Number of trailing zeros in this label */ - int nzmax; /* Max. number of trailing zeros */ - int odd; /* DO we have a strange axis? */ - int off; /* Offset from central label */ - int olap; /* Any overlap found? */ - int prio; /* Current priority */ - int root; /* Index of unabbreviated label */ - int root_found; /* Has the root label been decided on? */ - int rootoff; /* Distance from middle to root label */ - int split; /* Indicates whether to split labels into 2 lines */ - -/* Return without action if an error has occurred, or there are no labels to - draw. */ - if( !astOK || nlab == 0 || !list || !astGetNumLab( this, axis ) ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - rootoff = 0; - -/* Get the number of bounding boxes describing the labels already drawn - (this will be non-zero only if this is the second axis to be labelled). */ - nbox = Overlap( this, -2, 0, NULL, 0.0, 0.0, NULL, 0.0, 0.0, box, method, - class, status ); - -/* Ensure the labels are sorted into increasing index order. */ - qsort( (void *) list, (size_t) nlab, sizeof(LabelList), Compare_LL ); - -/* Complex curves can have multiple edge crossings very close together. - This means that the same label can sometimes be included more than once - in the supplied list at the same (x,y) position. Purge duplicate labels - by setting their priority to -1. Initialise the priority of the remaining - labels to zero. */ - tolx = 0.02*fabs( this->xhi - this->xlo ); - toly = 0.02*fabs( this->yhi - this->ylo ); - ll = list; - ll->priority = 0; - ll->saved_prio = 0; - - for( i = 1; i < nlab; i++ ) { - ll++; - ll->priority = 0; - ll->saved_prio = 0; - for( j = 0; j < i; j++ ){ - if( !strcmp( ll->text, list[ j ].text ) ) { - if( fabs( ll->x - list[ j ].x ) < tolx && - fabs( ll->y - list[ j ].y ) < toly ) { - ll->priority = -1; - ll->saved_prio = -1; - break; - } - } - } - } - -/* Find the maximum number of decimal places in any label. */ - mxdp = 0; - ll = list - 1; - for( i = 0; i < nlab; i++ ) { - ll++; - FindDPTZ( frame, axis, fmt, ll->text, &dp, &nz, status ); - if( dp > mxdp ) mxdp = dp; - } - -/* Indicate that we do not yet know whether SplitValue should split labels - into two lines or not. */ - split = 0; - -/* Find the highest priority label (the "root" label). This label is - never abbreviated to remove leading fields, and is never omitted due to - overlaps with other labels. To find this label, each label is assigned a - priority equal to the number of trailing zeros in the label text. If the - text has fewer than the maximum number of decimal places, pretend the text - is padded with trailing zeros to bring the number of decimal places up to - the maximum. The root label is the highest priority label, giving - preference to labels which occur in the middle of the index order. At the - same time, initialize the abbreviated text for each label to be equal to - the unabbreviated text. */ - lab0 = nlab/2; - nzmax = -1; - ll = list - 1; - root = -1; - root_found = 0; - for( i = 0; i < nlab; i++ ) { - ll++; - if( ll->priority > -1 ) { - text = ll->text; - -/* Find the number of decimal places and the number of trailing zeros in - this label. Note if a non-zero digit was found in the label. */ - found = FindDPTZ( frame, axis, fmt, text, &dp, &nz, status ); - -/* Add on some extra trailing zeros to make the number of decimal places - up to the maximum value. */ - nz += mxdp - dp; - -/* Store the priority for this label. */ - ll->priority = nz; - ll->saved_prio = nz; - -/* Note the highest priority of any label. */ - if( nz > nzmax ) nzmax = nz; - -/* We will use this label as the root label if: - - - We have not already found the root label - - AND - - - It does not overlap any labels drawn for a previous axis - - AND - - - We do not currently have a candidate root label, or - - The priority for this label is higher than the priority of the current - root label, or - - The priority for this label is equal to the priority of the current - root label and this label is closer to the centre of the axis, or - - The label value is zero. */ - - if( root == -1 || - nz > list[ root ].priority || - ( nz == list[ root ].priority && abs( i - lab0 ) < rootoff ) || - !found ) { - - if( !root_found ) { - - if( axis == 0 || !Overlap( this, -1, esc, - SplitValue( this, ll->text, - axis, &split, status ), - (float) ll->x, (float) ll->y, - ll->just, (float) ll->upx, - (float) ll->upy, box, method, - class, status ) ) { - root = i; - rootoff = abs( i - lab0 ); - -/* If the label value was zero, we will use label as the root label, - regardless of the priorities of later labels. */ - if( !found ) root_found = 1; - } - -/* Reset the list of bounding boxes to exclude any box added above. */ - Overlap( this, nbox, esc, NULL, 0.0, 0.0, NULL, 0.0, 0.0, box, - method, class, status ); - - } - } - } - -/* Initialise the abbreviated text to be the same as the full text. */ - ll->atext = ll->text; - } - -/* If all the labels overlapped labels on a previous axis, arbitrarily - use the label with non-genative priority that is closest to the middle - as the root label (this should never happen but is included to avoid - segmentation violations occurring in error conditions such as the - txExt function being buggy and cuasing spurious overlaps). */ - if( root == -1 ) { - for( off = 0; off < (nlab-1)/2; off++ ) { - root = nlab/2 + off; - if( list[ root ].priority >= 0 ) break; - root = nlab/2 - off; - if( list[ root ].priority >= 0 ) break; - } - if( root == -1 ) { - astError( AST__PLFMT, "%s(%s): Cannot produce labels for axis %d.", - status, method, class, axis + 1 ); - root = nlab/2; - } - } - -/* Assign a priority higher than any other priority to the root label. */ - list[ root ].priority = nzmax + 1; - list[ root ].saved_prio = nzmax + 1; - -/* See if leading fields are to be abbreviated */ - abb = astGetAbbrev( this, axis ); - -/* The following process may have removed some labels which define the - missing fields in neighbouring abbreviated fields, so that the user - would not be able to tell what value the abbvreviated leading fields - should have. We therefore loop back and perform the abbreviation - process again, omitting the removed labels this time. Continue doing - this until no further labels are removed. */ - jgap = 1; - olap = 1; - odd = 0; - while( olap && !odd ) { - -/* We now attempt to abbreviate the remaining labels (i.e. those which - have not been rejected on an earlier pass through this loop). Labels - are abbreviated in order of their priority. Higher priority labels are - abbreviated first (except that the root label, which has the highest - priority, is never abbreviated). Each label is abbreviated by comparing - it with the nearest label with a higher priority. */ - -/* Loop through all the priority values, starting with the highest - priority (excluding the root label so that the root label is never - abbreviated), and working downwards to finish with zero priority. */ - prio = nzmax + 1; - while( prio-- > 0 ) { - -/* Look for labels which have the current priority. */ - ll = list - 1; - for( i = 0; i < nlab; i++ ) { - ll++; - if( ll->priority == prio ) { - -/* Find the closest label to this one on the high index side which has a - higher priority. */ - llhi = NULL; - for( j = i + 1; j < nlab; j++ ) { - if( list[ j ].priority > prio ) { - llhi = list + j; - break; - } - } - -/* If no higher priority neighbour was found on the high index side, - use the nearest label with the current priority on the high index side. */ - if( !llhi ) { - for( j = i + 1; j < nlab; j++ ) { - if( list[ j ].priority == prio ) { - llhi = list + j; - break; - } - } - } - -/* Find the closest label to this one on the low index side which has a - higher priority. */ - lllo = NULL; - for( j = i - 1; j >= 0; j-- ) { - if( list[ j ].priority > prio ) { - lllo = list + j; - break; - } - } - -/* If no higher priority neighbour was found on the low index side, - use the nearest label with the current priority on the low index side. */ - if( !lllo ) { - for( j = i - 1; j >= 0; j-- ) { - if( list[ j ].priority == prio ) { - lllo = list + j; - break; - } - } - } - -/* If we are not abbreviating, use the full text as the abbreviated text.*/ - if( !abb ) { - ll->atext = ll->text; - -/* Otherwise, if only one of these two neighbouring labels was found, we - abbreviate the current label by comparing it with the one found - neighbouring label. If they are identical, we use the last field as - the abbreviated text. */ - } else if( !lllo ) { - ll->atext = astAbbrev( frame, axis, fmt, llhi->text, - ll->text ); - - } else if( !llhi ) { - ll->atext = astAbbrev( frame, axis, fmt, lllo->text, - ll->text ); - -/* If two neighbouring labels were found, we abbreviate the current label - by comparing it with both neighbouring labels, and choosing the shorter - abbreviation. */ - } else { - textlo = abb ? astAbbrev( frame, axis, fmt, lllo->text, - ll->text ) : ll->text; - texthi = abb ? astAbbrev( frame, axis, fmt, llhi->text, - ll->text ) : ll->text; - - lolen = strlen( textlo ); - hilen = strlen( texthi ); - if( lolen > 0 && lolen < hilen ) { - ll->atext = textlo; - } else { - ll->atext = texthi; - } - } - -/* If the two fields are identical, the abbreviated text returned by - astAbbrev will be a null string. In this case, find the start of the - last field in the formatted value (using astAbbrev again), and use - that as the abbreviated text. */ - if( !(ll->atext)[0] ) { - ll->atext = astAbbrev( frame, axis, fmt, NULL, ll->text ); - } - } - } - } - -/* Find the bounding box of the root label and add it to the list of bounding - boxes. */ - nleft = 1; - ll = list + root; - olap = Overlap( this, -1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, (float) ll->upx, - (float) ll->upy, box, method, class, status ); - -/* Now look for labels which would overlap. First, check labels above the root - label. Do not count overlaps where the two abbreviated labels have the same text. */ - ll = list + root; - latext = ll->atext; - for( i = root + 1; i < nlab; i++ ) { - ll++; - if( ll->priority >= 0 ) { - if( strcmp( ll->atext, latext ) ) { - if( Overlap( this, -1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, - (float) ll->upx, (float) ll->upy, box, method, - class, status ) ){ - olap++; - } else { - nleft++; - } - } - latext = ll->atext; - } - } - -/* Now check the labels below the root label. */ - ll = list + root; - latext = ll->atext; - for( i = root - 1; i >= 0; i-- ) { - ll--; - if( ll->priority >= 0 ) { - if( strcmp( ll->atext, latext ) ) { - if( Overlap( this, -1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, - (float) ll->upx, (float) ll->upy, box, method, - class, status ) ){ - olap++; - } else { - nleft++; - } - } - latext = ll->atext; - } - } - -/* If only one overlap was found, and this is the second axis, ignore it - since it is probably caused by the crossing of the two axes. */ - if( axis == 1 && olap == 1 ) olap = 0; - -/* If we are now only plotting every 3rd label, or if there are less than - 3 labels left, and there are still overlapping labels, then we must have - a very odd axis (such as logarithmically spaced ticks on a linearly mapped - axis). In this case, we will re-instate the orignal label priorities and - then leave this loop so that we attempt to plot all labels. Also retain - original priorities if the axis is mapped logarithmically onto the - screen. */ - if( olap && ( jgap == 3 || nleft < 3 || astGetLogPlot( this, axis ) ) ){ - jgap = 0; - odd = 1; - } else { - odd = 0; - } - -/* If any labels overlapped, re-instate the priority of all previously - excluded labels (using the copy of the label's real priority stored in - "saved_prio"), and then remove labels (by setting their priorities - negative) to increase the gap between labels, and try again. */ - if( olap ) { - jgap++; - - nexti = root + jgap; - for( i = root + 1; i < nlab; i++ ) { - if( i == nexti ) { - nexti += jgap; - list[ i ].priority = list[ i ].saved_prio; - } else { - list[ i ].priority = -1; - } - } - - nexti = root - jgap; - for( i = root - 1; i >= 0; i-- ) { - if( i == nexti ) { - nexti -= jgap; - list[ i ].priority = list[ i ].saved_prio; - } else { - list[ i ].priority = -1; - } - } - -/* Reset the abbreviated text to be the full text. */ - for( i = 0; i < nlab - 1; i++ ) list[ i ].atext = list[ i ].text; - - } - -/* Rest the list of bounding boxes to exclude the boxes added above. */ - Overlap( this, nbox, esc, NULL, 0.0, 0.0, NULL, 0.0, 0.0, box, method, - class, status ); - } - -/* We can now draw the abbreviated labels (ignoring rejected labels). */ - ll = list-1; - for( i = 0; i < nlab; i++ ) { - ll++; - if( ll->priority >= 0 ) { - -/* Check that this label does not overlap any labels drawn for previous - axes (we know from the above processing that it will not overlap any - other label on the current axis). */ - if( !Overlap( this, -1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, (float) ll->upx, - (float) ll->upy, box, method, class, status ) ) { - -/* Draw the abbreviated label text, and get the bounds of the box containing - the new label, splitting long formatted values (such as produced by - TimeFrames) into two lines. */ - DrawText( this, 1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, (float) ll->upx, - (float) ll->upy, xbn, ybn, NULL, method, class, status ); - } - } - } -} - -static void PolyCurve( AstPlot *this, int npoint, int ncoord, int indim, - const double *in, int *status ){ -/* -*++ -* Name: -c astPolyCurve -f AST_POLYCURVE - -* Purpose: -* Draw a series of connected geodesic curves. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astPolyCurve( AstPlot *this, int npoint, int ncoord, int indim, -c const double *in ) -f CALL AST_POLYCURVE( THIS, NPOINT, NCOORD, INDIM, IN, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function joins a series of points specified in the physical -c coordinate system of a Plot by drawing a sequence of geodesic -c curves. It is equivalent to making repeated use of the astCurve -c function (q.v.), except that astPolyCurve will generally be more -c efficient when drawing many geodesic curves end-to-end. A -c typical application of this might be in drawing contour lines. -f This routine joins a series of points specified in the physical -f coordinate system of a Plot by drawing a sequence of geodesic -f curves. It is equivalent to making repeated calls to the -f AST_CURVE routine (q.v.), except that AST_POLYCURVE will -f generally be more efficient when drawing many geodesic curves -f end-to-end. A typical application of this might be in drawing -f contour lines. -* -c As with astCurve, full account is taken of the Mapping between -c physical and graphical coordinate systems. This includes any -c discontinuities and clipping established using astClip. -f As with AST_CURVE, full account is taken of the Mapping between -f physical and graphical coordinate systems. This includes any -f discontinuities and clipping established using AST_CLIP. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c npoint -f NPOINT = INTEGER (Given) -* The number of points between which geodesic curves are to be drawn. -c ncoord -f NCOORD = INTEGER (Given) -* The number of coordinates being supplied for each point (i.e. -* the number of axes in the current Frame of the Plot, as given -* by its Naxes attribute). -c indim -f INDIM = INTEGER (Given) -c The number of elements along the second dimension of the "in" -f The number of elements along the first dimension of the IN -* array (which contains the input coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -c given should not be less than "npoint". -f given should not be less than NPOINT. -c in -f IN( INDIM, NCOORD ) = DOUBLE PRECISION (Given) -c The address of the first element in a 2-dimensional array of shape -c "[ncoord][indim]" giving the -c physical coordinates of the points which are to be joined in -c sequence by geodesic curves. These should be stored such that -c the value of coordinate number "coord" for point number -c "point" is found in element "in[coord][point]". -f A 2-dimensional array giving the physical coordinates of the -f points which are to be joined in sequence by geodesic -f curves. These should be stored such that the value of -f coordinate number COORD for input point number POINT is found -f in element IN(POINT,COORD). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - No curve is drawn on either side of any point which has any -* coordinate equal to the value AST__BAD. -* - An error results if the base Frame of the Plot is not -* 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *class; /* Object class */ - const char *method; /* Current method */ - const double **in_ptr; /* Pointer to array of data pointers */ - double *finish; /* Pointer to array holding segment end position */ - double *start; /* Pointer to array holding segment start position */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - int coord; /* Loop counter for coordinates */ - int i; /* Loop count */ - int naxes; /* No. of Frame axes */ - int ok; /* Are all start and end coords good? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astPolyCurve"; - class = astGetClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Initialise the bounding box for primatives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Check the current Frame of the Plot has ncoord axes. */ - naxes = astGetNout( this ); - if( naxes != ncoord && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the current " - "Frame of the supplied %s is invalid - this number should " - "be %d (possible programming error).", status, method, class, naxes, - class, ncoord ); - } - -/* Check the array dimension argument. */ - if ( astOK && ( indim < npoint ) ) { - astError( AST__DIMIN, "%s(%s): The array dimension value " - "(%d) is invalid.", status, method, class, indim ); - astError( AST__DIMIN, "This should not be less than the number of " - "points being drawn (%d).", status, npoint ); - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Allocate memory to hold the array of data pointers, the start position, - and the end position. */ - if ( astOK ) { - in_ptr = (const double **) astMalloc( sizeof( const double * ) * - (size_t) ncoord ); - start = (double *) astMalloc( sizeof( double ) * (size_t) ncoord ); - finish = (double *) astMalloc( sizeof( double ) * (size_t) ncoord ); - -/* Set up externals used to communicate with the Map3 function... - The number of axes in the physical coordinate system (i.e. the current - Frame). */ - Map3_ncoord = ncoord; - -/* A pointer to the Plot, the Current Frame, and and Mapping. */ - Map3_plot = this; - Map3_frame = astGetFrame( this, AST__CURRENT ); - Map3_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map3; - Crv_ink = 1; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_clip = astGetClip( this ) & 1; - -/* Set up a list of points spread evenly over each curve segment. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Initialise the data pointers to locate the coordinate data in - the "in" array. */ - if ( astOK ) { - for ( coord = 0; coord < ncoord; coord++ ) { - in_ptr[ coord ] = in + coord * indim; - } - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__CURVE_ID, 1, GRF__LINE, method, class ); - -/* Loop round each curve segment. */ - for( i = 1 ; i < npoint; i++ ) { - -/* Store the start position and check it for bad values. Increment the - pointers to the next position on each axis, so that they refer to the - finish point of the current curve segment. */ - ok = 1; - for( coord = 0; coord < ncoord; coord++ ) { - if( *( in_ptr[coord] ) == AST__BAD ){ - ok = 0; - } else { - start[ coord ] = *( in_ptr[coord] ); - } - ( in_ptr[coord] )++; - } - -/* Store the end position and check it for bad values. Do not increment - the axis pointers. This means that they will refer to the start position - of the next curve segment on the next pass through this loop. */ - for( coord = 0; coord < ncoord; coord++ ) { - if( *( in_ptr[coord] ) == AST__BAD ){ - ok = 0; - } else { - finish[ coord ] = *( in_ptr[coord] ); - } - } - -/* Pass on to the next curve segment if either the start or finish position - was bad. */ - if( ok ) { - -/* Set up the remaining externals used to communicate with the Map3 - function... */ - -/* The physical coordinates at the start of the curve. */ - Map3_origin = start; - -/* The physical coordinates at the end of the curve. */ - Map3_end = finish; - -/* The scale factor to convert "dist" values into physical offset values. */ - Map3_scale = astDistance( Map3_frame, start, finish ); - -/* Now set up the remaining external variables used by the Crv and CrvLine - function. */ - Crv_ux0 = AST__BAD; - Crv_out = 1; - Crv_xbrk = Curve_data.xbrk; - Crv_ybrk = Curve_data.ybrk; - Crv_vxbrk = Curve_data.vxbrk; - Crv_vybrk = Curve_data.vybrk; - -/* Map the evenly spread distances between "start" and "finish" into graphics - coordinates. */ - Map3( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map3 to draw the curve segment. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - Curve_data.length = Crv_len; - Curve_data.out = Crv_out; - Curve_data.nbrk = Crv_nbrk; - PurgeCdata( &Curve_data, status ); - } - } - -/* End the last poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map3. */ - Map3( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__CURVE_ID, 0, GRF__LINE, method, class ); - } - -/* Annul the Frame and Mapping. */ - Map3_frame = astAnnul( Map3_frame ); - Map3_map = astAnnul( Map3_map ); - -/* Free the memory used for the data pointers, and start and end positions. */ - in_ptr = (const double **) astFree( (void *) in_ptr ); - start = (double *) astFree( (void *) start ); - finish = (double *) astFree( (void *) finish ); - } -} - -static int PopGat( AstPlot *this, float *rise, const char *method, - const char *class, int *status ) { -/* -* Name: -* PopGat - -* Purpose: -* Pop current graphical attributes for text from a stack. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int PopGat( AstPlot *this, float *rise, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function restores the current graphical attributes for text -* from the values on a stack. Current attributes are left unchanged if -* the stack is empty. - -* Parameters: -* this -* Pointer to the Plot. -* rise -* Pointer to a location at which to return thhe height of the baseline -* above the normal baseline, expressed as a percentage of the normal -* character height. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Returns zero if the stack is empty, and 1 otherwise. - -*/ - -/* Local Variables: */ - AstGat *gat; - int result; - -/* Initialise */ - result = 0; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Check there is at least one AstGat structure on the stack. */ - if( this->ngat ) { - -/* Decrement the number of entries in the stack, and get a pointer to the - AstGat structure. Nullify the pointer on the stack. */ - gat = (this->gat)[ --(this->ngat) ]; - (this->gat)[ this->ngat ] = NULL; - -/* Restore the values in the AstGat structure */ - *rise = gat->rise; - GAttr( this, GRF__SIZE, gat->size, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, gat->width, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, gat->col, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, gat->font, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, gat->style, NULL, GRF__TEXT, method, class, status ); - -/* Free the AstGat structure. */ - gat = astFree( gat ); - -/* Indicate success.*/ - result = 1; - } - -/* Return the result. */ - return result; - -} - -static void PurgeCdata( AstPlotCurveData *cdata, int *status ){ -/* -* -* Name: -* AstPlotCurveData - -* Purpose: -* Remove any zero length sections from the description of a curve. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void PurgeCdata( AstPlotCurveData *cdata ) - -* Class Membership: -* Plot member function. - -* Description: -* This function removes any zero length sections from the supplied -* AstPlotCurveData struture, which describes a multi-section curve. - -* Parameters: -* cdata -* A pointer to the structure containing information about the -* breaks in a curve. - -*/ - -/* Local Variables: */ - int brk; /*Break index */ - int i; /*Break index */ - -/* Check the global error status. */ - if ( !astOK || !cdata ) return; - -/* Loop round all breaks. */ - brk = 0; - while( brk < cdata->nbrk ) { - -/* If this break and the next one are co-incident, remove both breaks. */ - if( cdata->xbrk[ brk ] == cdata->xbrk[ brk + 1 ] && - cdata->ybrk[ brk ] == cdata->ybrk[ brk + 1 ] ) { - -/* Shuffle down the higher elements of all the arrays in the curve data. */ - for( i = brk + 2; i < cdata->nbrk; i++ ){ - cdata->xbrk[ i - 2 ] = cdata->xbrk[ i ]; - cdata->ybrk[ i - 2 ] = cdata->ybrk[ i ]; - cdata->vxbrk[ i - 2 ] = cdata->vxbrk[ i ]; - cdata->vybrk[ i - 2 ] = cdata->vybrk[ i ]; - } - -/* Decrement the number of breaks in the curve data. */ - cdata->nbrk -= 2; - -/* If the section is not zero length, move on to the next pair of breaks. */ - } else { - brk += 2; - } - } -} - -static void PushGat( AstPlot *this, float rise, const char *method, - const char *class, int *status ) { -/* -* Name: -* PushGat - -* Purpose: -* Push current graphical attributes for text onto a stack. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void PushGat( AstPlot *this, float rise, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function stores the current graphical attributes for text -* on a stack. - -* Parameters: -* this -* Pointer to the Plot. -* rise -* The height of the baseline above the normal baseline, expressed -* as a percentage of the normal character height. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstGat *new_gat; - -/* Check inherited status */ - if( !astOK ) return; - -/* Allocate memory for a new AstGat structure to store the graphical - attributes. */ - new_gat = astMalloc( sizeof( AstGat ) ); - if( astOK ) { - -/* Store the height of the current baseline above the normal baseline, - expressed as a percentage of a normal character height. */ - new_gat->rise = rise; - -/* Store the current graphical attribute values. */ - GAttr( this, GRF__SIZE, AST__BAD, &(new_gat->size), GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, AST__BAD, &(new_gat->width), GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, AST__BAD, &(new_gat->font), GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, AST__BAD, &(new_gat->style), GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, AST__BAD, &(new_gat->col), GRF__TEXT, method, class, status ); - -/* Increment the number of AstGat structures on the stack.*/ - this->ngat++; - -/* Extend the array of AstGat pointers in the Plot structure so that there - is room for the new one. */ - this->gat = (AstGat **) astGrow( this->gat, this->ngat, sizeof( AstGat * ) ); - if( astOK ) { - -/* Store the new pointer. */ - (this->gat)[ this->ngat - 1 ] = new_gat; - - } - } -} - -static void RegionOutline( AstPlot *this, AstRegion *region, int *status ){ -/* -*++ -* Name: -c astRegionOutline -f AST_RegionOutline - -* Purpose: -* Draw the outline of an AST Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astRegionOutline( AstPlot *this, AstRegion *region ) -f CALL AST_REGIONOUTLINE( THIS, REGION, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -* This function draws an outline around the supplied AST Region object. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c region -f REGION = INTEGER (Given) -* Pointer to the Region. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ -/* Local Variables: */ - AstFrameSet *fs; - AstMapping *map; - const char *class; - const char *method; - int ibase; - int icurr; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astRegionOutline"; - class = astGetClass( this ); - -/* Save the base Frame index within the Plot, since astConvert will - change it. */ - ibase = astGetBase( this ); - -/* Get the FrameSet that converts from the current Frame of the Plot, to the - Frame represented by the Region. Check a conversion was found. */ - fs = astConvert( this, region, " " ); - -/* Re-instate the original base Frame. */ - astSetBase( this, ibase ); - -/* Report an error if the Region could not be mapped into the current - Frame of the Plot. */ - if( !fs ) { - if( astOK ) { - astError( AST__NOCNV, "%s(%s): Cannot find a mapping from the " - "%d-dimensional Plot coordinate system (%s) to the " - "%d-dimensional Region coordinate system (%s).", status, - method, class, astGetNout( this ), astGetTitle( this ), - astGetNout( region ), astGetTitle( region ) ); - } - -/* If a transformation from Plot to Region was found... */ - } else { - -/* Add the Region as a new Frame into the Plot, connecting it to the - current Frame using the FrameSet found above. It becomes the new current - Frame. First record the index of the original current Frame since - astAddFrame will modify the FrameSet to use a different current Frame. */ - icurr = astGetCurrent( this ); - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - astAddFrame( this, icurr, map, region ); - -/* Draw the outline of the Region (now the current Frame in the Plot). */ - astBorder( this ); - -/* Tidy up by removing the Region (i.e. the current Frame) from the Plot and - re-instating the original current Frame. */ - astRemoveFrame( this, AST__CURRENT ); - astSetCurrent( this, icurr ); - -/* Free resources. */ - map = astAnnul( map ); - fs = astAnnul( fs ); - } -} - -static void RemoveFrame( AstFrameSet *this_fset, int iframe, int *status ) { -/* -* Name: -* RemoveFrame - -* Purpose: -* Remove a Frame from a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "plot.h" -* void RemoveFrame( AstFrameSet *this_fset, int iframe, int *status ) - -* Class Membership: -* Plot member function (over-rides the astRemoveFrame public -* method inherited from the FrameSet class). - -* Description: -* This function removes a Frame from a Plot. All other Frames -* in the Plot have their indices re-numbered from one (if -* necessary), but are otherwise unchanged. -* -* If the index of the clipping Frame is changed, the index value -* stored in the Plot is updated. If the clipping Frame itself is -* removed, all clipping information is removed from the Plot. - -* Parameters: -* this_fset -* Pointer to the FrameSet component of the Plot. -* iframe -* The index within the Plot of the Frame to be removed. -* This value should lie in the range from 1 to the number of -* Frames in the Plot (as given by its Nframe attribute). -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to Plot structure */ - int ifrm; /* Validated frame index */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_fset; - -/* Validate the frame index. */ - ifrm = astValidateFrameIndex( this_fset, iframe, "astRemoveFrame" ); - -/* Invoke the parent astRemoveFrame method to remove the Frame. */ - (*parent_removeframe)( this_fset, iframe, status ); - -/* If the index of the removed Frame is smaller than the clipping Frame - index, then decrement the clipping Frame index so that the same Frame - will be used in future. */ - if( astOK ){ - if( ifrm < this->clip_frame ){ - (this->clip_frame)--; - -/* If the clipping fgrame itself has been removed, indicate that no - clipping should nbow be performed. */ - } else if( ifrm == this->clip_frame ){ - astClip( this, AST__NOFRAME, NULL, NULL ); - } - } -} - -static void RightVector( AstPlot *this, float *ux, float *uy, float *rx, - float *ry, const char *method, const char *class, int *status ){ -/* -* Name: -* RightVector - -* Purpose: -* Return a vector in the direction of the base line of normal text. - -* Synopsis: -* #include "plot.h" -* void RightVector( AstPlot *this, float *ux, float *uy, float *rx, -* float *ry, const char *method, const char *class, int *status ) - -* Description: -* This function returns a vector which points from left to right along -* the text baseline, taking account of any difference in the scales of -* the x and y axes. It also scales the supplied up vector so that it has -* a length equal to the height of normal text, and scales the returned -* right vector to have the same length (on the screen) as the up vector. - -* Parameters: -* this -* The plot. -* ux -* Pointer to a float holding the x component of the up-vector for the -* text, in graphics coords. Scaled on exit so that the up vector has -* length equal to the height of normal text. -* uy -* Pointer to a float holding the y component of the up-vector for the -* text, in graphics coords. Scaled on exit so that the up vector has -* length equal to the height of normal text. -* rx -* Pointer to a double in which will be put the x component of a -* vector parallel to the baseline of normal text. -* ry -* Pointer to a double in which will be put the y component of a -* vector parallel to the baseline of normal text. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Local Variables: */ - float alpha; /* Scale factor for X axis */ - float beta; /* Scale factor for Y axis */ - float chv; - float chh; - float l; /* Normalisation constant */ - float a; - float b; - float nl; /* Character height in standard coordinates */ - -/* Check inherited status */ - if( !astOK ) return; - -/* Find the scale factors for the two axes which scale graphics coordinates - into a "standard" coordinate system in which: 1) the axes have equal scale - in terms of (for instance) millimetres per unit distance, 2) X values - increase from left to right, 3) Y values increase from bottom to top. */ - GScales( this, &alpha, &beta, method, class, status ); - -/* Convert the up-vector into "standard" system in which the axes have - equal scales, and increase left-to-right, bottom-to-top. */ - *ux *= alpha; - *uy *= beta; - -/* Normalise this up-vector. */ - l = sqrt( (*ux)*(*ux) + (*uy)*(*uy) ); - if( l <= 0.0 ) { - *ux = 0.0; - *uy = 1.0; - } else { - *ux /= l; - *uy /= l; - } - -/* Find the height in "standard" coordinates of "normal" text draw with the - requested up-vector. */ - GQch( this, &chv, &chh, method, class, status ); - a = (*ux)/(chv*alpha); - b = (*uy)/(chh*beta); - nl = 1.0/sqrt( a*a + b*b ); - -/* Scale the up-vector so that is has length equal to the height of "normal" - text with the specified up-vector. */ - *ux *= nl; - *uy *= nl; - -/* Get the vector along the base-line of the text, by rotating the - up-vector by 90 degrees clockwise. */ - *rx = *uy; - *ry = -*ux; - -/* Convert both vectors back from standard coords to normal world coords */ - *ux /= alpha; - *uy /= beta; - *rx /= alpha; - *ry /= beta; - -} - -static void SaveTick( AstPlot *this, int axis, double gx, double gy, - int major, int *status ){ -/* -* Name: -* SaveTick - -* Purpose: -* Save info about a drawn tick in the Plot structure. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void SaveTick( AstPlot *this, int axis, double gx, double gy, -* int major, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function stores the start position and type of each drawn -* tick in the given Plot. - -* Parameters: -* this -* Pointer to the Plot. -* axis -* The zero-based axis index to which the tick refers. If a -* negative value is specified then all information about drawn ticks -* curently stored in the Plot is erased. -* gx -* The graphics X position at the start of the tick mark. -* gy -* The graphics Y position at the start of the tick mark. -* major -* Non-zero if the tick mark is a major tick. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int i; - int *count; - double *tickgx; - double *tickgy; - -/* Free the tick info in the supplied Plot if required. Do this before - checking the error status. */ - if( axis < 0 ) { - for( i = 0; i < 3; i++ ) { - this->majtickgx[ i ] = astFree( this->majtickgx[ i ] ); - this->majtickgy[ i ] = astFree( this->majtickgy[ i ] ); - this->mintickgx[ i ] = astFree( this->mintickgx[ i ] ); - this->mintickgy[ i ] = astFree( this->mintickgy[ i ] ); - this->mintickcount[ i ] = 0; - this->majtickcount[ i ] = 0; - } - return; - } - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get pointers to the arrays to use, and ensure the arrays are big - enough to hold the new tick. */ - if( major ) { - count = this->majtickcount + axis; - tickgx = this->majtickgx[ axis ]; - tickgy = this->majtickgy[ axis ]; - } else { - count = this->mintickcount + axis; - tickgx = this->mintickgx[ axis ]; - tickgy = this->mintickgy[ axis ]; - } - -/* Ensure the arrays are big enough to hold the new tick. */ - i = *count; - tickgx = astGrow( tickgx, i + 1, sizeof( double ) ); - tickgy = astGrow( tickgy, i + 1, sizeof( double ) ); - -/* If memory was allocated succesfully, store the new tick information in - the expanded arrays. */ - if( astOK ) { - tickgx[ i ] = gx; - tickgy[ i ] = gy; - *count = i + 1; - -/* Store the potentially updated array pointers. */ - if( major ) { - this->majtickgx[ axis ] = tickgx; - this->majtickgy[ axis ] = tickgy; - } else { - this->mintickgx[ axis ] = tickgx; - this->mintickgy[ axis ] = tickgy; - } - } -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Plot. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* Plot member function (over-rides the astSetAttrib protected -* method inherited from the FrameSet class). - -* Description: -* This function assigns an attribute value for a Plot, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Plot. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to the Plot structure */ - char label[21]; /* Graphics item label */ - const char *class; /* Pointer to class string */ - double dval; /* Double attribute value */ - int axis; /* Index for the axis */ - int edge; /* Index of edge within list */ - int id1; /* Plot object id */ - int id2; /* Plot object id */ - int id; /* Plot object id */ - int ival; /* Int attribute value */ - int len; /* Length of setting string */ - int nax; /* Number of graphics frame axes */ - int nc; /* Number of characters read by astSscanf */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Get the number of base Frame axis (2 for a Plot, 3 for a Plot3D). */ - nax = astGetNin( this ); - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* Tol. */ -/* ---- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "tol= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetTol( this, dval ); - -/* Grid. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "grid= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetGrid( this, ival ); - -/* TickAll. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "tickall= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetTickAll( this, ival ); - -/* ForceExterior */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "forceexterior= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetForceExterior( this, ival ); - -/* Invisible. */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "invisible= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetInvisible( this, ival ); - -/* Border. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "border= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetBorder( this, ival ); - -/* ClipOp. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "clipop= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetClipOp( this, ival ); - -/* Clip. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "clip= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetClip( this, ival ); - -/* Grf. */ -/* ---- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "grf= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetGrf( this, ival ); - -/* DrawTitle. */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "drawtitle= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetDrawTitle( this, ival ); - -/* DrawAxes. */ -/* --------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "drawaxes= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetDrawAxes( this, axis, ival ); - -/* DrawAxes(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "drawaxes(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetDrawAxes( this, axis - 1, ival ); - -/* Abbrev. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "abbrev= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetAbbrev( this, axis, ival ); - -/* Abbrev(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "abbrev(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetAbbrev( this, axis - 1, ival ); - -/* Escape. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "escape= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetEscape( this, ival ); - -/* Edge(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "edge(%d)= %n%*s %n", &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - edge = FullForm( "left right top bottom", setting + ival, setting, - "astSet", astGetClass( this ), status ); - if( edge == 0 ) { - astSetEdge( this, axis - 1, LEFT ); - } else if( edge == 1 ) { - astSetEdge( this, axis - 1, RIGHT ); - } else if( edge == 2 ) { - astSetEdge( this, axis - 1, TOP ); - } else if( edge == 3 ) { - astSetEdge( this, axis - 1, BOTTOM ); - } - -/* LabelAt (axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "labelat(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetLabelAt( this, axis - 1, dval ); - -/* Centre(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "centre(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetCentre( this, axis - 1, dval ); - -/* Gap. */ -/* ---- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "gap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetGap( this, axis, dval ); - -/* Gap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "gap(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetGap( this, axis - 1, dval ); - -/* LogGap. */ -/* ---- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "loggap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLogGap( this, axis, dval ); - -/* LogGap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "loggap(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetLogGap( this, axis - 1, dval ); - -/* NumLabGap. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "numlabgap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetNumLabGap( this, axis, dval ); - -/* NumLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "numlabgap(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetNumLabGap( this, axis - 1, dval ); - -/* TextLabGap. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "textlabgap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetTextLabGap( this, axis, dval ); - -/* TextLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "textlabgap(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetTextLabGap( this, axis - 1, dval ); - -/* LabelUp. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "labelup= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLabelUp( this, axis, ival ); - -/* LabelUp(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "labelup(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLabelUp( this, axis - 1, ival ); - -/* LogPlot. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "logplot= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLogPlot( this, axis, ival ); - -/* LogPlot(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "logplot(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLogPlot( this, axis - 1, ival ); - -/* LogTicks. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "logticks= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLogTicks( this, axis, ival ); - -/* LogTicks(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "logticks(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLogTicks( this, axis - 1, ival ); - -/* LogLabel. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "loglabel= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLogLabel( this, axis, ival ); - -/* LogLabel(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "loglabel(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLogLabel( this, axis - 1, ival ); - -/* NumLab. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "numlab= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetNumLab( this, axis, ival ); - -/* NumLab(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "numlab(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetNumLab( this, axis - 1, ival ); - -/* MinTick. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "mintick= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetMinTick( this, axis, ival ); - -/* MinTick(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "mintick(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetMinTick( this, axis - 1, ival ); - -/* TextLab. */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "textlab= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetTextLab( this, axis, ival ); - -/* TextLab(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "textlab(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetTextLab( this, axis - 1, ival ); - -/* LabelUnits. */ -/* --------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "labelunits= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLabelUnits( this, axis, ival ); - -/* LabelUnits(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "labelunits(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLabelUnits( this, axis - 1, ival ); - -/* Style. */ -/* ------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "style= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetStyle( this, id, ival ); - -/* Style(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "style(%20[^()])= %d %n", - label, &ival, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Style", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetStyle( this, id1, ival ); - if( nid > 1 ) astSetStyle( this, id2, ival ); - if( nid > 2 ) astSetStyle( this, id3, ival ); - -/* Font. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "font= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetFont( this, id, ival ); - -/* Font(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "font(%20[^()])= %d %n", - label, &ival, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Font", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetFont( this, id1, ival ); - if( nid > 1 ) astSetFont( this, id2, ival ); - if( nid > 2 ) astSetFont( this, id3, ival ); - -/* Colour. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "colour= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetColour( this, id, ival ); - -/* Colour(label). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "colour(%20[^()])= %d %n", - label, &ival, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Colour", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetColour( this, id1, ival ); - if( nid > 1 ) astSetColour( this, id2, ival ); - if( nid > 2 ) astSetColour( this, id3, ival ); - -/* Color. */ -/* ------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "color= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetColour( this, id, ival ); - -/* Color(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "color(%20[^()])= %d %n", - label, &ival, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Color", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetColour( this, id1, ival ); - if( nid > 1 ) astSetColour( this, id2, ival ); - if( nid > 2 ) astSetColour( this, id3, ival ); - -/* Width. */ -/* ------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "width= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetWidth( this, id, dval ); - -/* Width(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "width(%20[^()])= %lg %n", - label, &dval, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Width", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetWidth( this, id1, dval ); - if( nid > 1 ) astSetWidth( this, id2, dval ); - if( nid > 2 ) astSetWidth( this, id3, dval ); - -/* Size. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "size= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetSize( this, id, dval ); - -/* Size(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "size(%20[^()])= %lg %n", - label, &dval, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Size", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetSize( this, id1, dval ); - if( nid > 1 ) astSetSize( this, id2, dval ); - if( nid > 2 ) astSetSize( this, id3, dval ); - -/* TitleGap. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "titlegap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetTitleGap( this, dval ); - -/* MajTickLen. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "majticklen= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetMajTickLen( this, axis, dval ); - -/* MajTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "majticklen(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetMajTickLen( this, axis - 1, dval ); - -/* MinTickLen. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "minticklen= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetMinTickLen( this, axis, dval ); - -/* MinTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "minticklen(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetMinTickLen( this, axis - 1, dval ); - -/* Labelling. */ -/* -------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "labelling= %n%*s %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLabelling( this, FullForm( "exterior interior", - setting + ival, setting, - "astSet", astGetClass( this ), status ) - ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static void SetLogPlot( AstPlot *this, int axis, int ival, int *status ){ -/* -* -* Name: -* SetLogPlot - -* Purpose: -* Set a new value for a LogPlot attribute - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void SetLogPlot( AstPlot *this, int axis, int ival, int *status ) - -* Class Membership: -* Plot member function - -* Description: -* Assigns a new value to the LogPlot attribute of the specified axis, -* and also re-maps the base Frame of the Plot if necessary. - -* Parameters: -* this -* The Plot. -* axis -* Zero based axis index. -* ival -* The new value for the ogPlot attribute. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int oldval; /* Original attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the axis index. */ - if( axis < 0 || axis >= 2 ){ - astError( AST__AXIIN, "astSetLogPlot(%s): Index (%d) is invalid for " - "attribute LogPlot - it should be in the range 1 to 2.", status, - astGetClass( this ), axis + 1 ); - -/* If the axis index is OK, store the original attribute value. We use - astGetLogPlot to get the value rather than directly accessing - "this->logplot" in order to get the any default value in the case of - no value having been set. */ - } else { - oldval = astGetLogPlot( this, axis ); - -/* If the current attribute value will change, attempt to re-map the plot - axis. If the attempt succeeds, toggle the current attribute value. */ - if( ( ival != 0 ) != ( oldval != 0 ) ){ - if( ToggleLogLin( this, axis, oldval, "astSetLogPlot", status ) ){ - this->logplot[ axis ] = ( !oldval ); - } - -/* If the current attribute value will not change, just store the supplied - value (this is not redundant because it may cause a previously defaulted - value to become an explicitly set value ). */ - } else { - this->logplot[ axis ] = oldval; - } - } -} - -static void SetTickValues( AstPlot *this, int axis, int nmajor, double *major, - int nminor, double *minor, int *status ){ -/* -*+ -* Name: -* astSetTickValues - -* Purpose: -* Store the tick mark values to use for a given Plot axis. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* void astSetTickValues( AstPlot *this, int axis, int nmajor, -* double *major, int nminor, double *minor ) - -* Class Membership: -* Plot method. - -* Description: -* This function stores a set of tick mark values that should be used by -* subsequent calls to astGrid. - -* Parameters: -* this -* Pointer to a Plot. -* axis -* The zero-based index of the axis for which tick marks values -* have been supplied. -* nmajor -* The number of major tick mark values. If zero is supplied then -* the other parameters are ignored, and subsequent calls to -* astGrid will itself determine the tick values to be used. -* major -* Pointer to an array holding "nmajor" values for axis "axis" in -* the current Frame of the suppled Plot. Major tick marks will be -* drawn at these values. -* nminor -* The number of minor tick mark values. -* minor -* Pointer to an array holding "nminor" values for axis "axis" in -* the current Frame of the suppled Plot. Minor tick marks will be -* drawn at these values. - -*- -*/ - -/* Check the global status. */ - if( !astOK ) return; - -/* Report an error if the supplied axis value is incorrect. */ - if( axis < 0 || axis >= astGetNin( this ) ) { - astError( AST__INTER, "astSetTickValues(Plot): Supplied \"axis\" " - "value is %d - should in the range 0 to %d (internal AST " - "programming error).", status, axis, astGetNin( this ) - 1 ); - -/* Otherwise store or clear the values. */ - } else if( nmajor > 0 ){ - this->nmajtickval[ axis ] = nmajor; - this->majtickval[ axis ] = astStore( this->majtickval[ axis ], major, - sizeof( double )*nmajor ); - this->nmintickval[ axis ] = nminor; - this->mintickval[ axis ] = astStore( this->mintickval[ axis ], minor, - sizeof( double )*nminor ); - -/* Sort them into increasing order. */ - qsort( (void *) this->majtickval[ axis ], (size_t) nmajor, - sizeof(double), Compared ); - - qsort( (void *) this->mintickval[ axis ], (size_t) nminor, - sizeof(double), Compared ); - - } else { - this->nmajtickval[ axis ] = 0; - this->majtickval[ axis ] = astFree( this->majtickval[ axis ] ); - this->nmintickval[ axis ] = 0; - this->mintickval[ axis ] = astFree( this->mintickval[ axis ] ); - } -} - -const char *astStripEscapes_( const char *text, int *status ) { -/* -*++ -* Name: -c astStripEscapes -f AST_STRIPESCAPES - -* Purpose: -* Remove AST escape sequences from a string. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c const char *astStripEscapes( const char *text ) -f RESULT = AST_STRIPESCAPES( TEXT ) - -* Description: -* This function removes AST escape sequences from a supplied string, -* returning the resulting text as the function value. The behaviour -* of this function can be controlled by invoking the -c astEscapes function, -f AST_ESCAPES routine, -* which can be used to supress or enable the removal of escape -* sequences by this function. -* -* AST escape sequences are used by the Plot class to modify the -* appearance and position of sub-strings within a plotted text string. -* See the "Escape" attribute for further information. - -* Parameters: -c text -c Pointer to the string to be checked. -f TEXT -f The string to be checked. - -* Returned Value: -c astStripEscapes() -f AST_STRIPESCAPES = CHARACTER -c Pointer to the modified string. If no escape sequences were found -c in the supplied string, then a copy of the supplied pointer is -c returned. Otherwise, the pointer will point to a static buffer -c holding the modified text. This text will be over-written by -c subsequent invocations of this function. If the astEscapes function -f The modified string. If the AST_ESCAPES routine -* has been called indicating that escape sequences should not be -* stripped, then the supplied string is returned without change. - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - const char *a; - char *b; - int nc; - int ncc; - int type; - int value; - const char *result; - -/* Initialise */ - result= text; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check inherited status and supplied pointer. Also return if the - string contains no escape sequences or if stripping of escapes has - been supressed. */ - if( !astOK || astEscapes( -1 ) || !text || !HasEscapes( text, status ) ) return result; - -/* Initialise a pointer to the next character to be read from the - supplied string. */ - a = text; - -/* Initialise a pointer to the next character to be written to the - returned string. */ - b = stripescapes_buff; - -/* Note the available space left in the buffer. */ - ncc = AST__PLOT_STRIPESCAPES_BUFF_LEN; - -/* Loop until all the string has been read, or the buffer is full. */ - while( *a && ncc > 0 ){ - -/* If the remaining string starts with an escape sequence, increment the - read point by the length of the escape sequence, but leave the write - pointer where it is. */ - if( astFindEscape( a, &type, &value, &nc ) ) { - a += nc; - -/* If the remaining string does not start with an escape sequence, copy - the following text from the read position to the write position. */ - } else { - if( nc > ncc ) nc = ncc; - memcpy( b, a, sizeof( char )*nc ); - a += nc; - b += nc; - ncc -= nc; - } - } - -/* Terminate the returned string. */ - *b = 0; - -/* Return the result.*/ - return stripescapes_buff; -} - -static int swapEdges( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, int *status ) { -/* -* Name: -* swapEdges - -* Purpose: -* Determine if edges for text labels should be swapped. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int swapEdges( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* or not it is necessary to swap the Edges(0) and Edges(1) attributes -* in order to place textual labels on appropriate edges. This should -* only be used if the attributes have not explicitly been set, and if -* interior labelling is being used. The sides are determines by -* looking at the bounding box of tick marks on axis 0, in graphics -* coordinates. The returned value causes the label for axis 0 to be -* placed on the edge parallel to the longest side of this bounding box. -* The label for axis 1 is placed parallel to the shortest side of this -* bounding box. - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick marks on the axis. See function GridLines. -* cdata -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structure (one for each -* major tick value on the axis), holding information about breaks -* in the curves drawn to mark the major tick values. See function -* DrawGrid. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the edges should be swapped, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPlotCurveData *cdt; /* Pointer to the AstPlotCurveData for the next tick */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - float xmax; /* Max graphics X value */ - float xmin; /* Min graphics X value */ - float ymax; /* Max graphics Y value */ - float ymin; /* Min graphics Y value */ - int oldedge; /* The original edge for axis 0 */ - int result; /* Swap edges? */ - int tick; /* Tick index */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along axis 0. */ - info = grid[ 0 ]; - -/* Get a pointer to the structure containing information describing - the breaks in the curve which is parallel to axis 1 and passes - through the first major tick mark on axis 0. */ - cdt = cdata[ 0 ]; - -/* Initialise the graphiocs X and Y bounds of the area covered by the - axis. */ - xmax = -1.0E10; - xmin = 1.0E10; - ymax = -1.0E10; - ymin = 1.0E10; - -/* Loop round each of the major tick marks on axis 0. */ - for( tick = 0; cdt && info && tick < info->nmajor; tick++ ){ - -/* Update the max and min graphics X and Y coords covered by the axis. */ - if( cdt->nbrk > 0 ) { - xmax = astMAX( xmax, cdt->xbrk[0] ); - xmin = astMIN( xmin, cdt->xbrk[0] ); - ymax = astMAX( ymax, cdt->ybrk[0] ); - ymin = astMIN( ymin, cdt->ybrk[0] ); - } - -/* Get a pointer to the curve through the next major tick mark. */ - cdt++; - - } - -/* See which edge axis 0 would normally be labelled on. */ - oldedge = astGetEdge( this, 0 ); - -/* If the X range is larger than the Y range, the textual label should be - placed on the bottom edge. If required, indicate that the edges must - be swapped to achieve this. */ - if( xmax - xmin > ymax - ymin ) { - if( oldedge == 0 || oldedge == 2 ) result = 1; - -/* If the X range is smaller than the Y range, the textual label should be - placed on the left edge. If required, indicate that the edges must - be swapped to achieve this. */ - } else { - if( oldedge == 1 || oldedge == 3 ) result = 1; - } - - return result; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Plot. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Plot member function (over-rides the astTestAttrib protected -* method inherited from the FrameSet class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Plot's attributes. - -* Parameters: -* this -* Pointer to the Plot. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to the Plot structure */ - char label[21]; /* Graphics item label */ - int axis; /* Axis number */ - int len; /* Length of attrib string */ - int nax; /* Number of base Frame axes */ - int nc; /* No. characters read by astSscanf */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Get the number of base Frame axis (2 for a Plot, 3 for a Plot3D). */ - nax = astGetNin( this ); - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* Tol. */ -/* ---- */ - if ( !strcmp( attrib, "tol" ) ) { - result = astTestTol( this ); - -/* Edge(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "edge(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestEdge( this, axis - 1 ); - -/* Grid. */ -/* ----- */ - } else if ( !strcmp( attrib, "grid" ) ) { - result = astTestGrid( this ); - -/* TickAll. */ -/* -------- */ - } else if ( !strcmp( attrib, "tickall" ) ) { - result = astTestTickAll( this ); - -/* ForceExterior */ -/* ------------- */ - } else if ( !strcmp( attrib, "forceexterior" ) ) { - result = astTestForceExterior( this ); - -/* Invisible. */ -/* ---------- */ - } else if ( !strcmp( attrib, "invisible" ) ) { - result = astTestInvisible( this ); - -/* Border. */ -/* ------- */ - } else if ( !strcmp( attrib, "border" ) ) { - result = astTestBorder( this ); - -/* ClipOp. */ -/* ------- */ - } else if ( !strcmp( attrib, "clipop" ) ) { - result = astTestClipOp( this ); - -/* Clip. */ -/* ----- */ - } else if ( !strcmp( attrib, "clip" ) ) { - result = astTestClip( this ); - -/* Grf. */ -/* ---- */ - } else if ( !strcmp( attrib, "grf" ) ) { - result = astTestGrf( this ); - -/* DrawTitle. */ -/* ---------- */ - } else if ( !strcmp( attrib, "drawtitle" ) ) { - result = astTestDrawTitle( this ); - -/* DrawAxes. */ -/* --------- */ - } else if ( !strcmp( attrib, "drawaxes" ) ) { - result = astTestDrawAxes( this, 0 ); - -/* DrawAxes(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "drawaxes(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestDrawAxes( this, axis - 1 ); - -/* Abbrev. */ -/* --------- */ - } else if ( !strcmp( attrib, "abbrev" ) ) { - result = astTestAbbrev( this, 0 ); - -/* Abbrev(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "abbrev(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestAbbrev( this, axis - 1 ); - -/* Escape. */ -/* ------- */ - } else if ( !strcmp( attrib, "escape" ) ) { - result = astTestEscape( this ); - -/* Gap. */ -/* ---- */ - } else if ( !strcmp( attrib, "gap" ) ) { - result = astTestGap( this, 0 ); - -/* Gap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "gap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestGap( this, axis - 1 ); - -/* LabelAt(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelat(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLabelAt( this, axis - 1 ); - -/* LogGap. */ -/* ---- */ - } else if ( !strcmp( attrib, "loggap" ) ) { - result = astTestLogGap( this, 0 ); - -/* LogGap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loggap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLogGap( this, axis - 1 ); - -/* NumLabGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "numlabgap" ) ) { - result = astTestNumLabGap( this, 0 ); - -/* NumLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestNumLabGap( this, axis - 1 ); - -/* TextLabGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "textlabgap" ) ) { - result = astTestTextLabGap( this, 0 ); - -/* TextLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestTextLabGap( this, axis - 1 ); - -/* LabelUp. */ -/* -------- */ - } else if ( !strcmp( attrib, "labelup" ) ) { - result = astTestLabelUp( this, 0 ); - -/* LabelUp(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelup(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLabelUp( this, axis - 1 ); - -/* LogPlot. */ -/* -------- */ - } else if ( !strcmp( attrib, "logplot" ) ) { - result = astTestLogPlot( this, 0 ); - -/* LogPlot(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logplot(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLogPlot( this, axis - 1 ); - -/* LogTicks. */ -/* -------- */ - } else if ( !strcmp( attrib, "logticks" ) ) { - result = astTestLogTicks( this, 0 ); - -/* LogTicks(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logticks(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLogTicks( this, axis - 1 ); - -/* LogLabel. */ -/* -------- */ - } else if ( !strcmp( attrib, "loglabel" ) ) { - result = astTestLogLabel( this, 0 ); - -/* LogLabel(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loglabel(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLogLabel( this, axis - 1 ); - -/* NumLab. */ -/* -------- */ - } else if ( !strcmp( attrib, "numlab" ) ) { - result = astTestNumLab( this, 0 ); - -/* NumLab(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestNumLab( this, axis - 1 ); - -/* MinTick. */ -/* -------- */ - } else if ( !strcmp( attrib, "mintick" ) ) { - result = astTestMinTick( this, 0 ); - -/* MinTick(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "mintick(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestMinTick( this, axis - 1 ); - -/* TextLab. */ -/* ---------- */ - } else if ( !strcmp( attrib, "textlab" ) ) { - result = astTestTextLab( this, 0 ); - -/* TextLab(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestTextLab( this, axis - 1 ); - -/* LabelUnits. */ -/* --------- */ - } else if ( !strcmp( attrib, "labelunits" ) ) { - result = astTestLabelUnits( this, 0 ); - -/* LabelUnits(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelunits(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLabelUnits( this, axis - 1 ); - -/* Style. */ -/* ------ */ - } else if ( !strcmp( attrib, "style" ) ) { - result = TestUseStyle( this, AST__BORDER_ID, status ); - -/* Style(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "style(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseStyle( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Font. */ -/* ----- */ - } else if ( !strcmp( attrib, "font" ) ) { - result = TestUseFont( this, AST__TEXTLABS_ID, status ); - -/* Font(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "font(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseFont( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Colour. */ -/* ------- */ - } else if ( !strcmp( attrib, "colour" ) ) { - result = TestUseColour( this, AST__TEXTLABS_ID, status ); - -/* Color. */ -/* ------- */ - } else if ( !strcmp( attrib, "color" ) ) { - result = TestUseColour( this, AST__TEXTLABS_ID, status ); - -/* Colour(label). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "colour(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseColour( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Color(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "color(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseColour( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Width. */ -/* ------ */ - } else if ( !strcmp( attrib, "width" ) ) { - result = TestUseWidth( this, AST__BORDER_ID, status ); - -/* Width(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "width(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseWidth( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Size. */ -/* ----- */ - } else if ( !strcmp( attrib, "size" ) ) { - result = TestUseSize( this, AST__TEXTLABS_ID, status ); - -/* Size(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "size(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseSize( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* TitleGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "titlegap" ) ) { - result = astTestTitleGap( this ); - -/* MajTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "majticklen" ) ) { - result = astTestMajTickLen( this, 0 ); - -/* MajTickLen(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "majticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestMajTickLen( this, axis - 1 ); - -/* MinTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "minticklen" ) ) { - result = astTestMinTickLen( this, 0 ); - -/* MinTickLen(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "minticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestMinTickLen( this, axis - 1 ); - -/* Labelling. */ -/* -------- */ - } else if ( !strcmp( attrib, "labelling" ) ) { - result = astTestLabelling( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static void Text( AstPlot *this, const char *text, const double pos[], - const float up[], const char *just, int *status ){ -/* -*++ -* Name: -c astText -f AST_TEXT - -* Purpose: -* Draw a text string for a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astText( AstPlot *this, const char *text, const double pos[], -c const float up[], const char *just ) -f CALL AST_TEXT( THIS, TEXT, POS, UP, JUST, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -* This function draws a string of text at a position specified in -* the physical coordinate system of a Plot. The physical position -* is transformed into graphical coordinates to determine where the -* text should appear within the plotting area. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c text -f TEXT = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing the -f A character string containing the -* text to be drawn. Trailing white space is ignored. -c pos -f POS( * ) = DOUBLE PRECISION (Given) -* An array, with one element for each axis of the Plot, giving -* the physical coordinates of the point where the reference -* position of the text string is to be placed. -c up -f UP( * ) = REAL (Given) -* An array holding the components of a vector in the "up" -* direction of the text (in graphical coordinates). For -c example, to get horizontal text, the vector {0.0f,1.0f} should -f example, to get horizontal text, the vector [0.0,1.0] should -* be supplied. For a basic Plot, 2 values should be supplied. For -* a Plot3D, 3 values should be supplied, and the actual up vector -* used is the projection of the supplied up vector onto the text plane -* specified by the current value of the Plot3D's Norm attribute. -c just -f JUST = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string identifying the -f A character string identifying the -* reference point for the text being drawn. The first character in -* this string identifies the reference position in the "up" direction -* and may be "B" (baseline), "C" (centre), "T" (top) or "M" (bottom). -* The second character identifies the side-to-side reference position -* and may be "L" (left), "C" (centre) or "R" (right ). The string is -* case-insensitive, and only the first two characters are significant. -* -* For example, a value of "BL" means that the left end of the -* baseline of the original (un-rotated) text is to be drawn at the -c position given by "pos". -f position given by POS. - -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The Plot3D class currently does not interpret graphical escape -* sequences contained within text displayed using this method. -* - Text is not drawn at positions which have any coordinate equal -* to the value AST__BAD (or where the transformation into -* graphical coordinates yields coordinates containing the value -* AST__BAD). -c - If the plotting position is clipped (see astClip), then no -f - If the plotting position is clipped (see AST_CLIP), then no -* text is drawn. -* - An error results if the base Frame of the Plot is not -* 2-dimensional or (for a Plot3D) 3-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *mapping; /* Pointer to graphics->physical mapping */ - AstPointSet *pset1; /* PointSet holding physical positions */ - AstPointSet *pset2; /* PointSet holding graphics positions */ - const char *class; /* Object class */ - const char *method; /* Current method */ - const double **ptr1; /* Pointer to physical positions */ - char ljust[3]; /* Upper case copy of "just" */ - char *ltext; /* Local copy of "text" excluding trailing spaces */ - double **ptr2; /* Pointer to graphics positions */ - float xbn[ 4 ]; /* X coords of text bounding box. */ - float ybn[ 4 ]; /* Y coord of text bounding box. */ - int axis; /* Axis index */ - int escs; /* Original astEscapes value */ - int naxes; /* No. of axes in the base Frame */ - int ncoord; /* No. of axes in the current Frame */ - int ulen; /* Length of "text" excluding trailing spaces */ - -/* Check the global error status. */ - if ( !astOK || !text ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astText"; - class = astClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Ensure AST functions included graphical escape sequences in any - returned text strings. */ - escs = astEscapes( 1 ); - -/* Initialise the bounding box for primatives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__TEXT_ID, 1, GRF__TEXT, method, class ); - -/* Get the number of coordinates in the physical coordinate frame. */ - ncoord = astGetNout( this ); - -/* Create a PointSet to hold the supplied physical coordinates. */ - pset1 = astPointSet( 1, ncoord, "", status ); - -/* Allocate memory to hold pointers to the first value on each axis. */ - ptr1 = (const double **) astMalloc( sizeof( const double * )* - (size_t)( ncoord )); - -/* Check the pointer can be used, then store pointers to the first value - on each axis. */ - if( astOK ){ - for( axis = 0; axis < ncoord; axis++ ){ - ptr1[ axis ] = pos + axis; - } - } - -/* Store these pointers in the PointSet. */ - astSetPoints( pset1, (double **) ptr1 ); - -/* Transform the supplied data from the current frame (i.e. physical - coordinates) to the base frame (i.e. graphics coordinates) using - the inverse Mapping defined by the Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - pset2 = Trans( this, NULL, mapping, pset1, 0, NULL, 0, method, class, status ); - mapping = astAnnul( mapping ); - -/* Get pointers to the graphics coordinates. */ - ptr2 = astGetPoints( pset2 ); - -/* Take a copy of the string excluding any trailing white space. */ - ulen = ChrLen( text, status ); - ltext = (char *) astStore( NULL, (void *) text, ulen + 1 ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Terminate the local copy of the text string. */ - ltext[ ulen ] = 0; - -/* Produce an upper-case copy of the first two characters in "just". */ - ljust[0] = (char) toupper( (int) just[0] ); - ljust[1] = (char) toupper( (int) just[1] ); - ljust[2] = 0; - -/* Convert the double precision values to single precision, checking for - bad positions. */ - if( ptr2[0][0] != AST__BAD && ptr2[1][0] != AST__BAD ){ - -/* Draw the text string. */ - DrawText( this, 1, astGetEscape( this ), ltext, (float) ptr2[0][0], - (float) ptr2[1][0], ljust, up[ 0 ], up[ 1 ], xbn, ybn, - NULL, method, class, status ); - } - -/* Free the local copy of the string. */ - ltext = (char *) astFree( (void *) ltext ); - - } - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Free the memory holding the pointers to the first value on each axis. */ - ptr1 = (const double **) astFree( (void *) ptr1 ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__TEXT_ID, 0, GRF__TEXT, method, class ); - -/* Restore the original value of the flag which says whether graphical - escape sequences should be incldued in any returned text strings. */ - astEscapes( escs ); - -/* Return */ - return; -} - -static void TextLabels( AstPlot *this, int edgeticks, int dounits[2], - const char *method, const char *class, int *status ){ -/* -* -* Name: -* TextLabels - -* Purpose: -* Draw textual labels round a grid. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void TextLabels( AstPlot *this, int edgeticks, int dounits[2], -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function displays a textual label for each physical axis, and a -* title. The text strings are obtained from the Label and Title -* attributes of the current Frame in the Plot. - -* Parameters: -* this -* A pointer to the Plot. -* edgeticks -* If tick marks and numerical labels were drawn around the edges -* of the plotting area, this should be supplied as 1. Otherwise it -* should be supplied as zero. -* dounits -* Flags indicating if the axis Units string should be included in -* the edge labels. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char *new_text; /* Pointer to complete text string (inc. units) */ - char *just; /* Pointer to axis label justification string */ - const char *text; /* Pointer to text string to be displayed */ - const char *units; /* Pointer to text string describing the units */ - double mindim; /* Minimum dimension of plotting area */ - double xrange; /* Width of plotting area */ - double yrange; /* Height of plotting area */ - float txtgap; /* Gap between bounding box and text string */ - float upx; /* X component of text up-vector */ - float upy; /* Y component of text up-vector */ - float xbn[ 4 ]; /* X coords at corners of new label's bounding box */ - float ybn[ 4 ]; /* Y coords at corners of new label's bounding box */ - float xref; /* Graphics X coord. at text ref. position */ - float yref; /* Graphics Y coord. at text ref. position */ - float xlo, xhi, ylo, yhi;/* The original bounding box (excluding labels) */ - int axis; /* Axis index */ - int draw; /* Should label be drawn? */ - int edge; /* Edge to be labelled */ - int esc; /* Interpret escape sequences? */ - int gelid; /* ID for next graphical element to be drawn */ - int tlen; /* No. of characetsr in label */ - int ulen; /* No. of characetsr in units */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Get the minimum dimension of the plotting area. */ - xrange = this->xhi - this->xlo; - yrange = this->yhi - this->ylo; - mindim = astMIN( xrange, yrange ); - -/* Take a copy of the bounding box which encloses all other parts of the - annotated grid. If nothing has been plotted, use an area 20 % smaller - than the plotting area. */ - if( Box_lbnd[ 0 ] != FLT_MAX ) { - xlo = Box_lbnd[ 0 ]; - xhi = Box_ubnd[ 0 ]; - ylo = Box_lbnd[ 1 ]; - yhi = Box_ubnd[ 1 ]; - } else { - xlo = this->xlo + 0.2*xrange; - xhi = this->xhi - 0.2*xrange; - ylo = this->ylo + 0.2*yrange; - yhi = this->yhi - 0.2*yrange; - } - -/* See if escape sequences are to be interpreted within the labels. */ - esc = astGetEscape( this ); - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__TEXTLAB1_ID; - -/* Now write a label for each physical axis. */ - for( axis = 0; axis < 2 && astOK; axis++ ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__TEXT, method, class ); - -/* See if the label is to be drawn. If an explicit value has not been set - for the TextLab attribute, the default is to draw the label if tick - marks were draw round the edge of the plotting area, and not to - otherwise. */ - if( astTestTextLab( this, axis ) ){ - draw = astGetTextLab( this, axis ); - } else { - draw = edgeticks; - } - -/* If so get the label. */ - if( draw ){ - text = astGetLabel( this, axis ); - tlen = ChrLen( text, status ); - -/* If required, get the units string and concatenate it with the label (inside - parenthesise). Ignore trailing spaces. */ - if( dounits[ axis ] ){ - units = astGetUnit( this, axis ); - if( units && units[0] ){ - ulen = ChrLen( units, status ); - new_text = astMalloc( tlen + ulen + 4 ); - if( new_text ) memcpy( new_text, text, tlen ); - - text = new_text + tlen; - - memcpy( (void *) text, " (", 2 ); - text += 2; - - memcpy( (char *) text, units, ulen ); - text += ulen; - - memcpy( (char *) text, ")", 1 ); - text += 1; - - ( (char *) text )[0] = 0; - - text = new_text; - - } else { - new_text = astStore( NULL, (void *) text, tlen + 1 ); - new_text[ tlen ] = 0; - text = new_text; - units = NULL; - } - - } else { - new_text = astStore( NULL, (void *) text, tlen + 1 ); - new_text[ tlen ] = 0; - text = new_text; - units = NULL; - } - -/* Get the gap between the edge of the bounding box and the closest edge - of the text string. */ - txtgap = (float)( mindim*astGetTextLabGap( this, axis ) ); - -/* Get the edge to be labelled. Edge 0 is the left hand edge. Edge 1 is the - top edge. Edge 2 is the right-hand edge. Edge 3 is the bottom edge. */ - edge = astGetEdge( this, axis ) % 4; - if( edge < 0 ) edge = -edge; - -/* If the label is to be put on the left hand edge... */ - if( edge == 0 ){ - -/* Set the up vector so that the text is written from bottom to top. */ - upx = -1.0; - upy = 0.0; - -/* Justify the bottom of the whole bounding box (not just the text - base-line). */ - just = "MC"; - -/* Set the x reference position just outside the box enclosing all the - graphics drawn so far. The reference point refers to the centre of the - text string in both directions ("CC" justification). Take account of - whether or not the x axis is reversed. Do not allow the text to be - written outside the whole plotting surface. */ - if( this->xrev ){ - xref = xhi + txtgap; - } else { - xref = xlo - txtgap; - } - -/* The Y reference position is at the mid point vertically. */ - yref = 0.5*( astMIN( yhi, this->yhi ) + - astMAX( ylo, this->ylo ) ); - -/* Do the same for the top edge. */ - } else if( edge == 1 ){ - upx = 0.0; - upy = 1.0; - just = "MC"; - if( this->yrev ){ - yref = ylo - txtgap; - } else { - yref = yhi + txtgap; - } - xref = 0.5*( astMIN( xhi, this->xhi ) + - astMAX( xlo, this->xlo ) ); - -/* Do the same for the right-hand edge. */ - } else if( edge == 2 ){ - upx = 1.0; - upy = 0.0; - just = "MC"; - if( this->xrev ){ - xref = xlo - txtgap; - } else { - xref = xhi + txtgap; - } - yref = 0.5*( astMIN( yhi, this->yhi ) + - astMAX( ylo, this->ylo ) ); - -/* Do the same for the bottom edge. */ - } else { - upx = 0.0; - upy = 1.0; - just = "TC"; - if( this->yrev ){ - yref = yhi + txtgap; - } else { - yref = ylo - txtgap; - } - xref = 0.5*( astMIN( xhi, this->xhi ) + - astMAX( xlo, this->xlo ) ); - } - -/* Display the label. */ - DrawText( this, 1, esc, text, xref, yref, just, - upx, upy, xbn, ybn, NULL, method, class, status ); - -/* Release the memory allocated to store the axis label;. */ - new_text = (char *) astFree( (void *) new_text ); - text = NULL; - - } - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__TEXT, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__TEXTLAB2_ID; - - } - -/* See if the title is to be drawn. */ - if( astOK && astGetDrawTitle( this ) ){ - -/* If so get the title. */ - text = astGetTitle( this ); - -/* Create a copy from which trailing spaces have been removed. */ - tlen = ChrLen( text, status ); - new_text = (char *) astStore( NULL, (void *) text, tlen + 1 ); - new_text[ tlen ] = 0; - text = new_text; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__TITLE_ID, 1, GRF__TEXT, method, class ); - -/* Take a copy of the bounding box which encloses all other parts of the - annotated grid (this may have been extended by the above code). If - nothing has been plotted, use an area 20 % smaller than the plotting - area. */ - if( Box_lbnd[ 0 ] != FLT_MAX ) { - xlo = Box_lbnd[ 0 ]; - xhi = Box_ubnd[ 0 ]; - ylo = Box_lbnd[ 1 ]; - yhi = Box_ubnd[ 1 ]; - } else { - xlo = this->xlo + 0.2*xrange; - xhi = this->xhi - 0.2*xrange; - ylo = this->ylo + 0.2*yrange; - yhi = this->yhi - 0.2*yrange; - } - -/* Get the graphics coordinates of the bottom centre point of the title. - The X centre is put at the mid point of the used x axis range - (restricted to the range of the plotting area). */ - xref = 0.5*( astMIN( xhi, this->xhi ) + - astMAX( xlo, this->xlo ) ); - -/* The Y centre is put a "TitleGap" distance outside the box containing - the everything else. */ - if( this->yrev ){ - yref = ylo - (float)( mindim*astGetTitleGap( this ) ); - } else { - yref = yhi + (float)( mindim*astGetTitleGap( this ) ); - } - -/* Display the title. Justify the bottom of the whole bounding box (not - just the text base-line). */ - DrawText( this, 1, esc, text, xref, yref, "MC", 0.0F, 1.0F, - xbn, ybn, NULL, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__TITLE_ID, 0, GRF__TEXT, method, class ); - -/* Release the memory allocated to store the title. */ - new_text = (char *) astFree( (void *) new_text ); - text = NULL; - } - -/* Include the labels in the bounding box held in global variables - Box_lbnd/ubnd. */ - if( Box_lbnd[ 0 ] != FLT_MAX ) { - Box_lbnd[ 0 ] = astMIN( Box_lbnd[ 0 ], Boxp_lbnd[ 0 ] ); - Box_ubnd[ 0 ] = astMAX( Box_ubnd[ 0 ], Boxp_ubnd[ 0 ] ); - Box_lbnd[ 1 ] = astMIN( Box_lbnd[ 1 ], Boxp_lbnd[ 1 ] ); - Box_ubnd[ 1 ] = astMAX( Box_ubnd[ 1 ], Boxp_ubnd[ 1 ] ); - } else { - Box_lbnd[ 0 ] = Boxp_lbnd[ 0 ]; - Box_ubnd[ 0 ] = Boxp_ubnd[ 0 ]; - Box_lbnd[ 1 ] = Boxp_lbnd[ 1 ]; - Box_ubnd[ 1 ] = Boxp_ubnd[ 1 ]; - } - -/* Return. */ - return; - -} - -static void UpdateConcat( float *xbn, float *ybn, float ux, float uy, - float rx, float ry, float *x, float *y, - float x0, float y0, float *alpha_lo, - float *alpha_hi, float *beta_lo, float *beta_hi, - int *status ){ - -/* -* Name: -* UpdateConcat - -* Purpose: -* Update the concatenation point for a text string in preparation for -* appending another string. - -* Synopsis: -* #include "plot.h" -* void UpdateConcat( float *xbn, float *ybn, float ux, float uy, -* float rx, float ry, float *x, float *y, -* float x0, float y0, float *alpha_lo, float *alpha_hi, -* float *beta_lo, float *beta_hi, int *status ) - -* Description: -* This function modifies the supplied concatenation point (x,y) by moving -* it to the right along the baseline of the text by an amount equal -* to the width of the supplied sub-string bounding box. It also updates -* the supplied total bounding box so that it includes the supplied -* sub-string bounding box. - -* Parameters: -* xbn -* Pointer to an array holding the x coord at the four corners of -* the sub-string bounding box. -* ybn -* Pointer to an array holding the y coord at the four corners of -* the sub-string bounding box. -* ux -* The x component of the up-vector for the text, in graphics coords. -* The length of this vector should be equal to the height of normal -* text drawn with this up-vector. -* uy -* The y component of the up-vector for the text. See "ux". -* rx -* The x component of the right-vector for the text. The length of this -* vector should be equal to the height of normal text drawn with the -* supplied up-vector. -* ry -* The y component of the right-vector for the text. see "rx". -* x -* Pointer to a float holding the x coord of the concatenation point -* of the text just drawn. This is changed on exit so that the next -* string will be appended to the end of the text just drawn. -* y -* Pointer to a float holding the y coord of the concatenation point -* of the text just drawn. This is changed on exit so that the next -* string will be appended to the end of the text just drawn. -* x0 -* The X coord at the left end of the baseline of the total string. -* y0 -* The Y coord at the left end of the baseline of the total string. -* alpha_lo -* Pointer to a double holding a value which gives the position of the -* bottom edge of the total bounding box. The value is such that -* (x0,y0) + alpha_lo*(ux,uy) is a point on the bottom edge of the -* total bounding box. The returned value is updated so that the -* total bounding box includes the supplied sub-string bounding box. -* alpha_hi -* Pointer to a double holding a value which gives the position of the -* top edge of the total bounding box. The value is such that -* (x0,y0) + alpha_hi*(ux,uy) is a point on the top edge of the -* total bounding box. The returned value is updated so that the -* total bounding box includes the supplied sub-string bounding box. -* beta_lo -* Pointer to a double holding a value which gives the position of the -* left edge of the total bounding box. The value is such that -* (x0,y0) + beta_lo*(rx,ry) is a point on the left edge of the -* total bounding box. The returned value is updated so that the -* total bounding box includes the supplied sub-string bounding box. -* beta_hi -* Pointer to a double holding a value which gives the position of the -* right edge of the total bounding box. The value is such that -* (x0,y0) + beta_hi*(rx,ry) is a point on the right edge of the -* total bounding box. The returned value is updated so that the -* total bounding box includes the supplied sub-string bounding box. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - float ahi; - float alo; - float alpha; - float beta; - float bhi; - float blo; - float denom; - float dx; - float dy; - float xc; - float yc; - int ic; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check the supplied up and right vectors are not parallel. */ - denom = ux*ry - uy*rx; - if( denom != 0.0 ) { - -/* Get the coords at the centre of the sub-string bounding box. */ - xc = ( xbn[ 0 ] + xbn[ 1 ] + xbn[ 2 ] + xbn[ 3 ] )/4.0; - yc = ( ybn[ 0 ] + ybn[ 1 ] + ybn[ 2 ] + ybn[ 3 ] )/4.0; - -/* For each of the 4 corners of the sub-string bounding box, we consider the - vector from the centre of the bounding box to the corner. We want to express - this vector, vx, as a sum of a vector in the up direction and a vector - in the right direction: - - vx = alpha*ux + beta+rx - vy = alpha*uy + beta+ry - - where alpha and beta are constants which are different for each - corner vector. We also want to find the minimum and maximum alpha and - beta covered by the box. First initialise the limits. */ - alo = 0.0; - ahi = 0.0; - blo = 0.0; - bhi = 0.0; - -/* Now find alpha and beta for each of the four corners. */ - for( ic = 0; ic < 4; ic++ ) { - dx = xbn[ ic ] - xc; - dy = ybn[ ic ] - yc; - alpha = ( dx*ry - dy*rx ) /denom; - beta = ( dy*ux - dx*uy ) /denom; - -/* Extend the bounds in alpha and beta. */ - if( alpha < alo ) alo = alpha; - if( alpha > ahi ) ahi = alpha; - if( beta < blo ) blo = beta; - if( beta > bhi ) bhi = beta; - -/* The bottom left corner has negative values for both alpha and beta. - Commence the process of updating the concatenation point by subtracting - off the coordinates at the bottom left corner. For zero height bounding - boxes (such as may be produced if the text is completely blank), the - "alpha" value should be zero, but may be slightly non-zero due to - rounding errors. Allow for this (assuming non-blank text will always - produce a boundiong box that is at least 1.0E-4 of the up vector in - height). We do the same for bounding box width (although zero width - boxes will probably not occur). */ - if( alpha < 1.0E-4 ) { - if( beta < 1.0E-4 ) { - *x -= xbn[ ic ]; - *y -= ybn[ ic ]; - -/* The bottom right corner has negative alpha and positive beta. Complete - the process of updating the concatenation point by adding on the - coordinates at the bottom right corner. */ - } else if( beta > -1.0E-4 ) { - *x += xbn[ ic ]; - *y += ybn[ ic ]; - } - } - } - -/* Also express the vector from (x0,y0) to (xc,yc) as a sum of a vector - in the up direction and a vector in the right direction: - - xc - x0 = alpha*ux + beta*rx - yc - y0 = alpha*uy + beta*ry - - Find alpha and beta. */ - - dx = xc - x0; - dy = yc - y0; - alpha = ( dx*ry - dy*rx ) /denom; - beta = ( dy*ux - dx*uy ) /denom; - -/* We can now express the vector from (x0,y0) to each of the 4 corners as - a sum of alpha*up and beta*right. Form the bounds of the sub-string in - terms of up-vectors and right vectors from (x0,y0) instead of from the - centre of the box. */ - alo += alpha; - ahi += alpha; - blo += beta; - bhi += beta; - -/* Extend the supplied alpha and beta bounding box to include these limits. */ - if( alo < *alpha_lo ) *alpha_lo = alo; - if( ahi > *alpha_hi ) *alpha_hi = ahi; - if( blo < *beta_lo ) *beta_lo = blo; - if( bhi > *beta_hi ) *beta_hi = bhi; - } -} - -static void Ticker( AstPlot *this, int edge, int axis, double value, - double *gap, double tklen, int majtick, int save, - EdgeCrossingsStatics **pstatics, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* Ticker - -* Purpose: -* Draw edge tick marks for a given axis value. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Ticker( AstPlot *this, int edge, int axis, double value, -* double *gap, double tklen, int majtick, int save, -* EdgeCrossingsStatics **pstatics, const char *method, -* const char *class, int *status ){ - -* Class Membership: -* Plot member function. - -* Description: -* This function draws tick marks at all occurences of a given -* physical axis value on a given edge of the plotting area. - -* Parameters: -* this -* A pointer to the Plot. -* edge -* The edge of the plotting area to be ticked. Edge 0 is the left hand -* edge. Edge 1 is the top edge. Edge 2 is the right-hand edge. Edge 3 -* is the bottom edge. -* axis -* The index of the axis to which "value" refers. The tick mark extends -* parallel to this axis. -* value -* The physical axis value at which to place the tick mark. -* gap -* Pointer to array of two values holding the gap between major -* tick marks on the two axes. -* tklen -* The length of the tick, in graphics units. -* majtick -* Non-zero if the tick mark being drawn is a major tick, and zero -* if it is a minor tick. -* save -* If non-zero, the tick mark position will be saved in the Plot structure. -* pstatics -* Address of a pointer to a structure holding values for variables -* which were statically defined within this function prior to the -* thread-safe version of AST. If the pointer is supplied as NULL, -* then a new structure is allocated and initialised. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double *cross; /* Pointer to crossings information */ - double *vx; /* Pointer to next X vector component value */ - double *vy; /* Pointer to next Y vector component value */ - double *x; /* Pointer to next X value */ - double *y; /* Pointer to next Y value */ - double xe; /* X at tick end */ - double ye; /* Y at tick end */ - int j; /* Crossing index */ - int ncross; /* No. of crossings of tick value and edge */ - -/* Check the global status. */ - if( !astOK ) return; - -/* See where the current major tick value crosses the edge. */ - ncross = EdgeCrossings( this, edge, axis, value, gap, &cross, pstatics, - method, class, status ); - -/* Do nothing if the supplied axis value does not occur on the specified - edge of the plotting area. */ - if( ncross ){ - -/* Draw major tick marks at the crossings. */ - x = cross; - y = cross + 1; - vx = cross + 2; - vy = cross + 3; - -/* Draw a tick mark at each occurence of the axis value on the specified - edge. */ - for( j = 0; j < ncross; j++ ){ - -/* Check the tick mark position and directionm are defined. */ - if( *vx != AST__BAD && *vy != AST__BAD && - *x != AST__BAD && *y != AST__BAD ){ - -/* Ensure the tick mark will point into the plotting area, no matter which - edge it is on. First ensure the direction vector refers to a system in - which X increases to the left and Y increases upwards. */ - if( this->xrev ) *vx = -*vx; - if( this->yrev ) *vy = -*vy; - -/* If necessary reverse the vector so that it points into the plotting - area. How to do this depends on which edge is being ticked. */ - if( ( edge == 0 && *vx < 0.0 ) || /* left-hand edge */ - ( edge == 1 && *vy > 0.0 ) || /* Top edge */ - ( edge == 2 && *vx > 0.0 ) || /* Right-hand edge */ - ( edge == 3 && *vy < 0.0 ) ){ /* Bottom edge */ - - *vx = -*vx; - *vy = -*vy; - } - -/* Now ensure the direction vector refers to a the native graphics system - taking account of any reversal of axes. */ - if( this->xrev ) *vx = -*vx; - if( this->yrev ) *vy = -*vy; - -/* Do not draw the tick if the start of the tick is outside the bounds of - the axis it is labelling. */ - if( ( ( edge == 1 || edge == 3 ) && - *x < this->xhi && *x > this->xlo ) || - ( ( edge == 0 || edge == 2 ) && - *y < this->yhi && *y > this->ylo ) ) { - -/* Store the x and y graphics coords of the far end of the tick mark */ - xe = *x + tklen*(*vx); - ye = *y + tklen*(*vy); - -/* Ensure the far end of the tick mark is within the bounds of the axis - it is labelling. If not, redice the length of the tick mark until it is.*/ - if( edge == 1 || edge == 3 ) { /* Top or bottom edge */ - if( xe > this->xhi ) { - ye = *y + tklen*(*vy)*( this->xhi - *x )/(xe - *x ); - xe = this->xhi; - } else if( xe < this->xlo ) { - ye = *y + tklen*(*vy)*( this->xlo - *x )/(xe - *x ); - xe = this->xlo; - } - - } else { /* Left or right edge */ - if( ye > this->yhi ) { - xe = *x + tklen*(*vx)*( this->yhi - *y )/(ye - *y ); - ye = this->yhi; - } else if( ye < this->ylo ) { - xe = *x + tklen*(*vx)*( this->ylo - *y )/(ye - *y ); - ye = this->ylo; - } - } - -/* Draw the tick mark as a straight line of the specified length. */ - if( save ) SaveTick( this, axis, *x, *y, majtick, status ); - if( *x != xe || *y != ye ) { - Bpoly( this, (float) *x, (float) *y, status ); - Apoly( this, (float) xe, (float) ye, status ); - Opoly( this, status ); - } - } - -/* Move on to the next crossing. */ - x += 4; - y += 4; - vx += 4; - vy += 4; - } - } - -/* Free the memory holding the crossings. */ - if( cross ) cross = (double *) astFree( (void *) cross ); - - } - -/* Return. */ - return; - -} - -static TickInfo *TickMarks( AstPlot *this, int axis, double *cen, double *gap, - int *inval, GetTicksStatics **pstatics, - const char *method, const char *class, int *status ){ -/* -* Name: -* TickMarks - -* Purpose: -* Obtain a list of tick mark values and labels for a single axis in a 2-D -* physical coordinate Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* TickInfo *TickMarks( AstPlot *this, int axis, double *cen, double *gap, -* int *inval, GetTicksStatics **pstatics, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* A set of tick marks values and corresponding formatted labels are -* found for an axis which result in all adjacent labels being different, -* but using the minimum number of digits of precision in the formatting. -* This algorithm is over-ridden if the caller has set an explicit Format -* string for the axis. The gap between tick marks can be specified by -* the caller or a default value may be found automatically. - -* Parameters: -* this -* The Plot. -* axis -* The zero-based index of the axis to use. -* cen -* Pointer to the supplied axis value at which to put a single -* central tick. Other ticks will be placed evenly on either side of -* this tick. If AST__BAD is provided, a value will be used which -* would put a tick at an axis value of zero. The used value is -* returned. -* gap -* The supplied values for the gaps between ticks on the axis. If -* this is AST__BAD a suitable default value will be used and -* returned in place of the AST__BAD value. -* inval -* A pointer to a location at which to return a flag indicating if -* any invalid physical coordinates were encountered while deciding on -* the tick values. -* pstatics -* Address of a pointer to a structure holding static data values -* used within the GetTicks function. A NULL pointer should be supplied -* on the first invocation (dynamic memory will then be allocated to -* hold ths structure). The memory is freed when a NULL value for -* "this" is supplied. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a TickInfo structure holding information about the tick -* marks (no. of major and minor ticks, the major tick mark values and -* labels). This structure should be freed, together with its contents, -* using astFree when it is no longer needed. - -* Notes: -* - The returned labels are NOT abbreviated to remove identical -* leading fields. -* - This function allocates some static resources on its first -* invocation, which should be released when no longer needed, or when -* a different Plot is supplied, by calling this function with a NULL -* pointer for parameter "this". All other parameters (except axis) are -* ignored. -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - An error is reported if the region containing valid physical -* coordinates is too small to use. -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned. -*/ - -/* Local Constants: */ -#define MAXFLD 10 - -/* Local Variables: */ - AstAxis *ax; /* Pointer to the axis. */ - AstFrame *frame; /* Pointer to the current Frame in the Plot */ - TickInfo *ret; /* Pointer to the returned structure. */ - char **labels; /* Pointer to list of formatted labels */ - char **newlabels; /* Pointer to new list of shortened formatted labels */ - char **oldlabels; /* Pointer to old list of formatted labels */ - char *fields[ MAXFLD ]; /* Pointers to starts of fields in a label */ - char *old_format; /* Original Format string */ - char *used_fmt; /* Copy of format string actually used */ - const char *a; /* Pointer to next character to consider */ - const char *fmt; /* Format string actually used */ - double *ticks; /* Pointer to major tick mark values */ - double *minticks; /* Pointer to minor tick mark values */ - double cen0; /* Supplied value of cen */ - double junk; /* Unused value */ - double refval; /* Value for other axis to use when normalizing */ - double used_gap; /* The gap size actually used */ - int bot_digits; /* Digits value which makes labels as short as possible */ - int digits; /* New Digits value */ - int digset; /* Did the format string fix the no. of digits to use? */ - int fmtset; /* Was a format set? */ - int i; /* Tick index. */ - int nc[ MAXFLD ]; /* Lengths of fields in a label */ - int nf; /* Number of fields in a label */ - int nmajor; /* No. of major tick marks */ - int nminor; /* No. of minor tick marks */ - int ok; /* Are all adjacent labels different? */ - int reset_fmt; /* Re-instate the original state of the Format attribute? */ - - -/* If a NULL pointer has been supplied for "this", release the resources - allocated within GetTicks, and return. */ - if( !this ){ - (void) GetTicks( NULL, axis, NULL, &ticks, &nmajor, &minticks, &nminor, - 0, inval, &refval, pstatics, method, class, status ); - return NULL; - } - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Initialise the returned pointer. */ - ret = NULL; - -/* Store the supplied value of cen. */ - cen0 = cen ? *cen : AST__BAD ; - -/* Get a pointer to the current Frame from the Plot. */ - frame = astGetFrame( this, AST__CURRENT ); - -/* Initialise a flag to indicate that all adjacent labels are different. */ - ok = 0; - -/* Initialise the pointer to the list of formatted tick mark values to - indicate that no memory has yet been obtained. */ - labels = NULL; - -/* Initialise the pointer to a copy of the used format string to indicate - that no memory has yet been obtained. */ - used_fmt = NULL; - -/* Get a pointer to the axis. */ - ax = astGetAxis( frame, axis ); - -/* See if a value has been set for the axis Format. */ - fmtset = astTestFormat( frame, axis ); - -/* Get an initial set of tick mark values. This also establishes defaults for - LogTicks and LogLabel attributes, and so must be done before the - following block which uses the LogLabel attribute. */ - used_gap = GetTicks( this, axis, cen, &ticks, &nmajor, &minticks, &nminor, - fmtset, inval, &refval, pstatics, method, class, status ); - -/* See if exponential labels using superscript powers are required. */ - old_format = NULL; - reset_fmt = 0; - if( astGetLogLabel( this, axis ) && astGetEscape( this ) && - GCap( this, GRF__SCALES, 1, status ) ) { - -/* Save a copy of the Frame's Format value, if set. It will be - re-instated at the end of this function. */ - if( fmtset ) { - fmt = astGetFormat( frame, axis ); - old_format = astStore( NULL, (void *) fmt, strlen(fmt) + 1 ); - } - -/* Temporarily use a format of "%&g" to get "10**x" style axis labels, - with super-scripted "x". */ - astSetFormat( frame, axis, "%&g" ); - -/* Not all subclasses of Frame support this format specifier, so format a - test value, and see if it has two fields, the first of which is "10". - If not, we cannot use log labels so re-instate the original format. */ - nf = astFields( frame, axis, "%&g", astFormat( frame, axis, 1.0E4 ), - MAXFLD, fields, nc, &junk ); - if( nf != 2 || nc[ 0 ] != 2 || strncmp( fields[ 0 ], "10", 2 ) ) { - if( old_format ) { - astSetFormat( frame, axis, old_format ); - old_format = astFree( old_format); - } else { - astClearFormat( frame, axis ); - } - -/* If the "%&g" format is usable, note that we should reset the Format - back to its original state before leaving this function. */ - } else { - reset_fmt = 1; - } - } - -/* If a value has been set for the axis Format, see if the format string - contains a wildcard precision specifier ".*". If so, we are free to - vary the number of digits used in the label in order to produce - distinct labels. If no value has been set for the axis Format, we are - also free to vary the number of digits. */ - digset = 0; - if( fmtset ) { - fmt = astGetFormat( frame, axis ); - if( fmt ) { - digset = 1; - a = fmt; - while( (a = strchr( a, '.' )) ){ - if( *(++a) == '*' ) { - digset = 0; - break; - } - } - } - } - -/* If the axis precision has been specified, either through the Format string - or Digits value, or the Frame Digits value, we should use it so that the - user's attempts to get a specific result are not foiled. */ - if( digset || astTestAxisDigits( ax ) || astTestDigits( frame ) ){ - -/* Reserve memory to hold pointers to the formatted labels. */ - labels = (char **) astMalloc( sizeof(char *)*(size_t)nmajor ); - -/* Format the labels. We do not check that all adjacent labels are distinct - in order not to foil the users choice of format. That is, "ok" is set - non-zero by the call to CheckLabels, even if some identical adjacent - labels are found. */ - ok = CheckLabels( this, frame, axis, ticks, nmajor, 1, labels, refval, status ); - -/* Note the format used. */ - fmt = astGetFormat( frame, axis ); - if( fmt ) used_fmt = (char *) astStore( used_fmt, (void *) fmt, strlen( fmt ) + 1 ); - -/* If no precision has been specified for the axis, we need to find a - Digits value which gives different labels, but without using any more - digits than necessary. */ - } else if( astOK ){ - -/* Reserve memory to hold pointers to an initial set of labels formatted - with the default digits value. */ - labels = (char **) astMalloc( sizeof(char *)*(size_t)nmajor ); - -/* Produce these default labels. */ - CheckLabels( this, frame, axis, ticks, nmajor, 1, labels, refval, status ); - -/* The first task is to decide what the smallest usable number of digits - is. Starting at the default number of digits used above to produce the - default labels, we reduce the number of digits until one or more of the - formatted labels *increases* in length. This can happen for instance if - printf decides to include an exponent in the label. The *absolute* - minimum value 1. Set this first. */ - bot_digits = 1; - oldlabels = labels; - for( digits = astGetDigits( frame ) - 1; digits > 0; digits-- ){ - astSetAxisDigits( ax, digits ); - -/* CheckLabels2 formats the labels with the decreased number of digits, - and compares them with the old labels in "labels". If any of the new labels - are longer than the corresponding old labels, then a null pointer is - returned. Otherwise, a pointer is returned to the new set of labels. */ - newlabels = CheckLabels2( this, frame, axis, ticks, nmajor, - oldlabels, refval, status ); - -/* Free the old labels unless they are the orignal labels (which are - needed below). */ - if( oldlabels != labels ) { - for( i = 0; i < nmajor; i++ ){ - if( oldlabels[ i ] ) oldlabels[ i ] = (char *) astFree( (void *) oldlabels[ i ] ); - } - oldlabels = (char **) astFree( (void *) oldlabels ); - } - -/* If any of the labels got longer as a result of reducing the digits - value, then use the previous number of digits as the lowest possible - number of digits. Break out of the loop. */ - if( !newlabels ) { - bot_digits = digits + 1; - break; - } - -/* If none of the labels got longer, we arrive here. Use the shorter labels - for the next pass round this loop. */ - oldlabels = newlabels; - } - -/* Free any remaining labels. */ - if( oldlabels && oldlabels != labels ) { - for( i = 0; i < nmajor; i++ ){ - if( oldlabels[ i ] ) oldlabels[ i ] = (char *) astFree( (void *) oldlabels[ i ] ); - } - oldlabels = (char **) astFree( (void *) oldlabels ); - } - -/* Now loop round increasing the number of digits in the formatted labels - from the lowest usable value found above until all adjacent labels are - different. An arbitrary upper limit of 1000 is used for Digits to stop it - looping for ever. */ - for( digits = bot_digits; digits < 1000; digits++ ){ - -/* Store the new Digits value. */ - astSetAxisDigits( ax, digits ); - -/* Free memory used to hold the current set of labels. A new set will be - created by the following call to CheckLabels. */ - if( labels ) { - for( i = 0; i < nmajor; i++ ) labels[ i ] = astFree( labels[ i ] ); - } - -/* Break out of the loop if a Digits value has been found which results - in all adjacent labels being different. Note the format used (we know - the Format attribute is currently unset, but the default Format string - reflects the current value of the Digits attribute). */ - if( CheckLabels( this, frame, axis, ticks, nmajor, 0, labels, refval, status ) ) { - ok = 1; - fmt = astGetFormat( frame, axis ); - used_fmt = (char *) astStore( NULL, (void *) fmt, strlen( fmt ) + 1 ); - break; - } - } - -/* Clear the Digits value. */ - astClearAxisDigits( ax ); - } - -/* Annul the pointer to the Axis. */ - ax = astAnnul( ax ); - -/* Re-instate the original format specifier if required. */ - if( reset_fmt ) { - if( old_format ) { - astSetFormat( frame, axis, old_format ); - old_format = astFree( old_format); - } else { - astClearFormat( frame, axis ); - } - } - -/* If suitable labels were found... */ - if( ok && astOK ) { - -/* Store the used gap size. */ - *gap = used_gap; - -/* If the caller has specified the number of minor tick marks to use, - use the specified value rather than the value found above. */ - if( astTestMinTick( this, axis ) ){ - nminor = astGetMinTick( this, axis ); - } - -/* Allocate memory for the returned structure. */ - ret = (TickInfo *) astMalloc( sizeof( TickInfo ) ); - -/* If the pointer can be used, store the information. */ - if( astOK ){ - ret->nmajor = nmajor; - ret->nminor = nminor; - ret->ticks = ticks; - ret->minticks = minticks; - ret->labels = labels; - ret->fmt = used_fmt; - used_fmt = NULL; - ret->start = NULL; - ret->length = NULL; - ret->nsect = 0; - ret->gap = used_gap; - } - -/* If no suitable labels were found report an error. */ - } else if( astOK ){ - if( fmtset ){ - astError( AST__PLFMT, "%s(%s): No numerical labels can be produced " - "for axis %d using the supplied %s format string '%s'.", status, - method, class, axis + 1, astGetClass( frame ), - astGetFormat( frame, axis ) ); - } else { - astError( AST__PLFMT, "%s(%s): No suitable format can be found to " - "produce numerical labels for axis %d of a %s.", status, - method, class, axis + 1, astGetClass( frame ) ); - } - } - -/* Release any remaining resources. */ - frame = astAnnul( frame ); - if( used_fmt ) used_fmt = astFree( used_fmt ); - -/* If an error has occurred, release the returned information. */ - if( !astOK ){ - ticks = (double *) astFree( (void *) ticks ); - minticks = (double *) astFree( (void *) minticks ); - if( labels ){ - for( i = 0; i < nmajor; i++ ) { - labels[ i ] = (char *) astFree( (void *) labels[ i ] ); - } - labels = (char **) astFree( (void *) labels ); - if( ret ) (void ) astFree( (void *) ret->fmt ); - } - ret = (TickInfo *) astFree( (void *) ret ); - } - -/* Return the structure. */ - return ret; - -/* Undefine local constants. */ -#undef MAXFLD - -} - -static int TraceBorder( AstPlot *this, AstMapping *map, double xlo, double xhi, - double ylo, double yhi, int dim, double tol, - int edges[ 4 ], const char *method, const char *class, - int *status ) { -/* -* Name: -* TraceBorder - -* Purpose: -* Trace the boundary between good and bad physical coordinates through a -* fine grid. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TraceBorder( AstPlot *this, AstMapping *map, double xlo, double xhi, -* double ylo, double yhi, int dim, double tol, -* int edges[ 4 ], const char *method, const char *class, -* int *status ) { - -* Class Membership: -* Plot member function. - -* Description: -* A rectangular grid of points in graphics coords is created covering -* the region specified by (xlo,xhi,ylo,yhi), using "dim" points along -* each axis. This grid of points is converted into physical (WCS) -* coords, and a flag is associatred with each point saying whether -* the WCS coords are good or bad. The cells in this grid are then -* scanned from bottom left to top right in raster fashion (each cell -* has a grid point at each of its 4 corners). If a cell has a mix of -* bad and good corners, the good/bad boundary must pass through it. -* If the grid is sufficiently fine (as defined by "tol") then this -* function draws a single straight line through each cell as an -* approximation to the good bad boundary. This line joins the centres -* of the two cells edges through which the boundary passes (as -* indicated by the fact that one end of the edge has good WCS coords -* and the other end has bad WCS coords). If the grid is not -* sufficiently fine to meet the "tol" requirement, then this function -* is invoked recursively to draw the curve through each cell through -* which the boundary passes. - -* Parameters: -* this -* The plot. -* map -* The Graphics->WCS mapping. -* xlo -* The lower bounds on the graphics X axis of the rectangle being -* considered. -* xhi -* The upper bounds on the graphics X axis of the rectangle being -* considered. -* ylo -* The lower bounds on the graphics Y axis of the rectangle being -* considered. -* yhi -* The upper bounds on the graphics Y axis of the rectangle being -* considered. -* dim -* The number of points along one edge of the fine grid. -* tol -* The plotting tolerance. Once each cell is smaller than this -* distance (in graphics coords), the cell is drawn. Otherwise, -* this function is invoked recursively to draw the cell using a -* finer grid. -* edges -* A pointer to an array of 4 int, in which will be returned -* flags indicating if the good/bad boundary intersects any of the -* edges of the grid. These flags are stored in the order left, -* top, right, bottom. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPointSet *pset1; - AstPointSet *pset2; - double **ptr2; - double *px1; - double *px2; - double *py1; - double *py2; - double cxhi; - double cxlo; - double cyhi; - double cylo; - double dx; - double dy; - float xc; - float yc; - int *bndry; - int *drawn; - int bad1; - int bad2; - int bad3; - int bad4; - int icell; - int icol; - int irow; - int lastcell; - int ncell; - int recurse; - int result; - int sedges[ 4 ]; - int totcells; - -/* Initialise returned edge flags */ - edges[ 0 ] = 0; - edges[ 1 ] = 0; - edges[ 2 ] = 0; - edges[ 3 ] = 0; - -/* Initialise the returned flag to indicate that no bad regions were - found. */ - result = 0; - -/* Check the global status. */ - if ( !astOK ) return result; - -/* Create a grid of graphics and WCS coords covering the specified region - of graphics coords. "ptr2" is used to access the WCS coords at each - point in the grid. */ - ptr2 = MakeGrid( this, NULL, map, 0, dim, xlo, xhi, ylo, yhi, - 2, &pset1, &pset2, 0, method, class, status ); - -/* The number of cells along each axis of the grid is one less than the - number of points. Also get the number of cells in the whole grid. */ - ncell = dim - 1; - totcells = ncell*ncell; - -/* Store the dimensions of each cell in graphics coords. */ - dx = ( xhi - xlo )/ncell; - dy = ( yhi - ylo )/ncell; - -/* Set a flag indicating if the cell size is larger than the required - plotting tolerance. If so, we will call this function recursively to - draw the curve using a finer grid. */ - recurse = ( dx > tol || dy > tol ); - -/* If we have not yet reached the plotting tolerance, allocate work arrays - with one element for each cell in the grid. */ - if( recurse ) { - bndry = astMalloc( sizeof( int )*totcells ); - drawn = astMalloc( sizeof( int )*totcells ); - } else { - bndry = NULL; - drawn = NULL; - } - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* If required, initialise work arrays to hold zero. */ - if( recurse ) { - -/* Initialise "boundary passes through cell" flags to zero. */ - memset( bndry, 0, sizeof( int )*totcells ); - -/* Initialise "cell has been drawn" flags to zero. */ - memset( drawn, 0, sizeof( int )*totcells ); - } - -/* Store the Y graphics coords at the bottom and top of the first row. */ - cylo = ylo; - cyhi = ylo + dy; - -/* Store pointers to the physical coords at the bottom left corner of the - first cell in the first row. */ - px1 = ptr2[ 0 ]; - py1 = ptr2[ 1 ]; - -/* Store pointers to the physical coords at the top left corner of the - first cell in the first row. */ - px2 = px1 + dim; - py2 = py1 + dim; - -/* Store the index of the last cell in a row or column. */ - lastcell = ncell - 1; - -/* Initialise index of next cell. */ - icell = 0; - -/* Loop round every row of cells in this grid. */ - for( irow = 0; irow < ncell; irow++ ) { - -/* See if the physical coords are bad at the bottom left corner of the - first cell in this row. At the same time, increment the pointers so - they refer to the bottom right corner of the first cell in this row. */ - bad1 = ( *px1 == AST__BAD || *py1 == AST__BAD ); - -/* Increment the pointers. Do not do it in the above "if" statement since - the or (!!) means that the second expression may never be evaluated. */ - px1++; - py1++; - -/* See if the physical coords are bad at the top left corner of the - first cell in this row. At the same time, increment the pointers so - they refer to the top right corner of the first cell in this row. */ - bad2 = ( *px2 == AST__BAD || *py2 == AST__BAD ); - px2++; - py2++; - -/* Loop round every cell in the current row of cells. */ - for( icol = 0; icol < ncell; icol++, icell++ ) { - -/* See if the physical coords are bad at the bottom right corner of the - current cell in this row. At the same time, increment the pointers so - they refer to the bottom right corner of the next cell in this row. */ - bad3 = ( *px1 == AST__BAD || *py1 == AST__BAD ); - px1++; - py1++; - -/* See if the physical coords are bad at the top right corner of the - current cell in this row. At the same time, increment the pointers so - they refer to the top right corner of the next cell in this row. */ - bad4 = ( *px2 == AST__BAD || *py2 == AST__BAD ); - px2++; - py2++; - -/* Set the returned flag non-zero if any invalidpositions are found. */ - if( bad1 || bad2 || bad3 || bad4 ) result = 1; - -/* If there are a mixture of good and bad corners, the good/bad boundary - must pass through the current cell. */ - if( bad2 != bad1 || bad3 != bad1 || bad4 != bad1 ) { - -/* If we have not yet reached the required plotting tolerance, set a flag - to indicate that the boundary should be plotted through this cell - using a recirsive call to this function. */ - if( recurse ) { - bndry[ icell ] = 1; - -/* If we have reached the required plotting tolerance, draw the boundary - as a straight line between the centres of the edges through which the - boundary enteres and leaves the current cell. */ - } else { - -/* Get the upper and lower graphics X bounds of the current cell. */ - cxlo = xlo + icol*dx; - cxhi = cxlo + dx; - -/* If an edge of the current cell has good coords at one end but bad - coords at the other, the boundary is assumed to pass through the edge - at its centre. Normally, we expect only two cell edges to have this - property (i.e the boundary enters the cell through one edge and leaves - through the other). However, sometimes all four edges may have this - property. In this case, two sections of the boundary must pass through - the cell, and there is no way of knowing which edges connect together - (short of further recursion), and we arbitrarily decide to join opposite - edges. */ - if( bad1 == bad4 && bad2 == bad3 ) { - -/* Draw a horizontal line through the cell centre */ - yc = 0.5*( cylo + cyhi ); - Bpoly( this, (float) cxlo, yc, status ); - Apoly( this, (float) cxhi, yc, status ); - -/* Draw a vertical line through the cell centre */ - xc = 0.5*( cxlo + cxhi ); - Bpoly( this, xc, (float) cylo, status ); - Apoly( this, xc, (float) cyhi, status ); - -/* If the boundary passes through the left hand edge, it must also have - passed through the right edge of the previous cell in the row (unless - this is the first cell in the row), so we do not need to begin a new - polyline (we can just extend the existing polyline). */ - } else if( bad1 != bad2 ) { - -/* If this is the first cell in the row, begin a new polyline. */ - yc = 0.5*( cylo + cyhi ); - if( icol == 0 ) Bpoly( this, (float) cxlo, yc, status ); - -/* and through the top edge, draw a line between the centres of the left - and top edges. */ - if( bad2 != bad4 ) { - xc = 0.5*( cxlo + cxhi ); - Apoly( this, xc, (float) cyhi, status ); - -/* or through the right edge, draw a line between the centres of the left - and right edges. */ - } else if( bad3 != bad4 ) { - Apoly( this, (float) cxhi, yc, status ); - -/* Otherwise, draw a line between the centres of the left and bottom edges. */ - } else { - xc = 0.5*( cxlo + cxhi ); - Apoly( this, xc, (float) cylo, status ); - } - -/* If the boundary passes through the top edge (we do not need to check - the left edge because that was done above)... */ - } else if( bad4 != bad2 ) { - -/* and through the right edge, draw a line between the centres of the top - and right edges. */ - if( bad3 != bad4 ) { - xc = 0.5*( cxlo + cxhi ); - yc = 0.5*( cylo + cyhi ); - Bpoly( this, xc, (float) cyhi, status ); - Apoly( this, (float) cxhi, yc, status ); - -/* Otherwise, draw a line between the centres of the top and bottom edges. */ - } else { - xc = 0.5*( cxlo + cxhi ); - Bpoly( this, xc, (float) cyhi, status ); - Apoly( this, xc, (float) cylo, status ); - } - -/* If the boundary passes through the right edge it must also pass - throught the bottom edge since all other combinations will have been - trapped above. */ - } else { - xc = 0.5*( cxlo + cxhi ); - yc = 0.5*( cylo + cyhi ); - Bpoly( this, xc, (float) cylo, status ); - Apoly( this, (float) cxhi, yc, status ); - } - -/* If the current cell is on the edge of the grid, set flags in the - returned "edges" array to indicate that the boundary passes out of - the grid on the appropriate edge. */ - if( icol == 0 ) { - if( bad1 != bad2 ) edges[ 0 ] = 1; /* Left edge */ - } else if( icol == lastcell ) { - if( bad3 != bad4 ) edges[ 2 ] = 1; /* Right edge */ - } - - if( irow == 0 ) { - if( bad1 != bad3 ) edges[ 3 ] = 1; /* Bottom edge */ - } else if( irow == lastcell ) { - if( bad2 != bad4 ) edges[ 1 ] = 1; /* Top edge */ - } - } - } - -/* The flags for the right hand corners of the current cell can be - re-used as the flags for the left hand corners of the next cell. */ - bad1 = bad3; - bad2 = bad4; - } - -/* Store the Y graphics coords at the bottom and top of the next row. */ - cylo = cyhi; - cyhi = cylo + dy; - } - -/* If we have not yet reached the required plotting tolerance, call this - function recursively to draw the boundary through the cells identified - above. On each pass through this loop, we may discover more boundary - cells in the grid, in addition to those found above. Continue looping - until no further boundary cells are found. */ - while( recurse ) { - -/* Assume that the current pass though this loop will result in all boundary - cells being draw, in which case we can then leave the loop. */ - recurse = 0; - -/* Store the Y graphics coords at the bottom and top of the first row. */ - cylo = ylo; - cyhi = ylo + dy; - -/* Initialise the cell index */ - icell = 0; - -/* Loop round every row of cells in this grid. */ - for( irow = 0; irow < ncell; irow++ ) { - -/* Loop round every cell in the current row of cells. */ - for( icol = 0; icol < ncell; icol++, icell++ ) { - -/* If the good/bad boundary passes through the current cell we need to - draw it unless it has already been drawn. */ - if( bndry[ icell ] && ! drawn[ icell ] ){ - -/* Get the upper and lower graphics X bounds of the current cell. */ - cxlo = xlo + icol*dx; - cxhi = cxlo + dx; - -/* Call this function recursively to draw the boundary through the current - cell, setting the returned flag non-zero if any bad positions are found. */ - if( TraceBorder( this, map, cxlo, cxhi, cylo, cyhi, 3, tol, - sedges, method, class, status ) ) result = 1; - -/* The boundary may have passed out of the current cell and then back - into the cell on the same edge (i.e. a small loop that pokes out into - a neighbouring cell). Such neighbouring cells may not have been - identified by the earlier section of this function, so we now ensure - that any such cells are flagged as boundary cells. */ - -/* If the boundary passed out of the left edge of the cell... */ - if( sedges[ 0 ] ) { - -/* If the current cell is at the left edge of the grid, indicate that the - boundary passes out of the left edge of the grid. */ - if( icol == 0 ) { - edges[ 0 ] = 1; /* Left edge */ - -/* Otherwise, if the left hand neighbour of the current cell is not - flagged as a boundary cell, flag it now and indicate that another pass - though the loop is needed to draw the extra cell. */ - } else if( ! bndry[ icell - 1 ] ) { - bndry[ icell - 1 ] = 1; - recurse = 1; - } - } - -/* If the boundary passed out of the top edge of the cell... */ - if( sedges[ 1 ] ) { - -/* If the current cell is at the top edge of the grid, indicate that the - boundary passes out of the top edge of the grid. */ - if( irow == lastcell ) { - edges[ 1 ] = 1; /* Top edge */ - -/* Otherwise, ensure that the upper neighbour of the current cell is - flagged as a boundary cell. */ - } else { - bndry[ icell + ncell ] = 1; - } - } - -/* If the boundary passed out of the right edge of the cell... */ - if( sedges[ 2 ] ) { - -/* If the current cell is at the right edge of the grid, indicate that the - boundary passes out of the right edge of the grid. */ - if( icol == lastcell ) { - edges[ 2 ] = 1; /* Right edge */ - -/* Otherwise, ensure that the right hand neighbour of the current cell is - flagged as a boundary cell. */ - } else { - bndry[ icell + 1 ] = 1; - } - } - -/* If the boundary passed out of the bottom edge of the cell... */ - if( sedges[ 3 ] ) { - -/* If the current cell is at the bottom edge of the grid, indicate that the - boundary passes out of the bottom edge of the grid. */ - if( irow == 0 ) { - edges[ 3 ] = 1; /* Bottom edge */ - -/* Otherwise, if the lower neighbour of the current cell is not flagged - as a boundary cell, flag it now and indicate that another pass though - the loop is needed to draw the extra cell. */ - } else if( ! bndry[ icell - ncell ] ) { - bndry[ icell - ncell ] = 1; - recurse = 1; - } - } - -/* Indicate this cell has been drawn. */ - drawn[ icell ] = 1; - } - } - -/* Store the Y graphics coords at the bottom and top of the next row. */ - cylo += dy; - cyhi = cylo + dy; - } - } - } - -/* Free resources */ - bndry = astFree( bndry ); - drawn = astFree( drawn ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Trans( AstPlot *this, AstFrame *frm, AstMapping *mapping, - AstPointSet *in, int forward, AstPointSet *out, - int norm, const char *method, const char *class, int *status ) { -/* -* Name: -* Trans - -* Purpose: -* Use a Mapping to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPointSet *Trans( AstPlot *this, AstFrame *frm, AstMapping *mapping, -* AstPointSet *in, int forward, AstPointSet *out, -* int norm, const char *method, const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* This performs the same task as the protected method astTransform -* but uses the astTransform method for the supplied Mapping instead -* the parent method for the Plot. This allows the Mapping to be -* extracted from the Plot using astGetMapping once, rather than every -* time a mapping is performed. - -* Parameters: -* this -* Pointer to the Plot (only used to access clipping attributes and -* other methods). -* frm -* Pointer to the Current Frame in the Plot. If this is NULL, then -* a pointer for the Current Frame is found within this function if -* required (i.e. if "forward" and "norm" are both non-zero). -* mapping -* Pointer to the Mapping extracted from the Plot. If this is NULL, then -* a pointer for the base->current Mapping is found within this function. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate -* transformation should be applied while a zero value requests the -* inverse transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* norm -* The normalisation of returned physical coordinates is only done -* if "norm" is non-zero. Otherwise they are left as returned by -* astTransform. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - Clipping is only performed as set up using the astClip method. -* In particular, the clipping specified by the arguments to the astPlot -* constructor function is NOT performed. This is done in order to improve -* the efficiency of the curve drawing method astGridLine. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the Plot being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstFrame *cfr; /* Pointer to the Current Frame */ - AstFrame *fr; /* Pointer to the clipping Frame */ - AstMapping *map; /* Pointer to output->clip mapping */ - AstPointSet *clip; /* Positions in clipping Frame */ - AstPointSet *result; /* Positions in output Frame */ - double **ptr_clip; /* Pointer to clipping Frame data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *work; /* Pointer to array holding an o/p position */ - double axval; /* Axis value in clipping frame */ - double lbnd; /* Lower bound on current clipping axis */ - double ubnd; /* Upper bound on current clipping axis */ - int axin; /* Is the axis value within the allowed range? */ - int clip_norm; /* Normalise the clipping positions? */ - int clip_or; /* Combine axes using a logical OR? */ - int clipit; /* Should the current point be clipped? */ - int i; /* Point index */ - int iframe; /* Validated index for clipping Frame */ - int j; /* Axis index */ - int naxes; /* Number of axes in clipping Frame */ - int ncoord_out; /* Number of coordinates per output point */ - int npoint; /* Number of points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Ensure we have a Mapping */ - if( !mapping ) mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent FrameSet class. */ - result = astTransform( mapping, in, forward, out ); - -/* Get the dimensions of the returned data, and an array of pointers to - the axis values. */ - ncoord_out = astGetNcoord( result ); - npoint = astGetNpoint( result ); - ptr_out = astGetPoints( result ); - -/* If we have done a forward mapping, we now normalise the returned physical - positions if required using the astNorm method for the supplied object. */ - if( forward && norm ){ - -/* If no Frame was supplied, get a pointer to the Current Frame. Otherwise, - use the supplied pointer. */ - if( !frm ) { - cfr = astGetFrame( this, AST__CURRENT ); - } else { - cfr = frm; - } - -/* Get work space to hold a single positions. */ - work = (double *) astMalloc( sizeof(double)*(size_t)ncoord_out ); - -/* Check the work space and axis pointers can be used. */ - if( astOK ){ - -/* Now loop through every position, copying the axis values to the work array, - normalising them using astNorm, and copying them back to the returned - PointSet. */ - for( i = 0; i < npoint; i++ ){ - for( j = 0; j < ncoord_out; j++ ) work[ j ] = ptr_out[ j ][ i ]; - astNorm( cfr, work ); - for( j = 0; j < ncoord_out; j++ ) ptr_out[ j ][ i ] = work[ j ]; - } - } - -/* Free the work space. */ - work = (double *) astFree( (void *) work ); - -/* Annul the pointer to the Current Frame if it was obtained in this - function. */ - if( !frm ) cfr = astAnnul( cfr ); - - } - -/* Clipping is only performed if the bounds of a clipping region are - available for both axes. */ - if( this->clip_lbnd && this->clip_ubnd ){ - -/* Validate and translate the index of the clipping Frame. */ - iframe = astValidateFrameIndex( this, this->clip_frame, method ); - -/* Obtain a pointer to the clipping Frame and determine how many axes it - has. */ - fr = astGetFrame( this, iframe ); - naxes = astGetNaxes( fr ); - -/* Report an error if the number of bounds does not equal the number of - axes in the clipping Frame. */ - if( astOK && naxes != this->clip_axes ){ - astError( AST__CLPAX, "%s%s): The supplied %s specifies clipping " - "in %d dimensions, but the clipping Frame ('%s') has " - "%d axes.", status, method, class, class, this->clip_axes, - astGetTitle( fr ), naxes ); - } - -/* Set a flag indicating if the coordinates in the clipping frame need to - be normalised. */ - clip_norm = 1; - -/* We now obtain a pointer to a PointSet holding the corresponding - coordinates in the clipping frame. If the clipping frame is the - base frame, then take a clone of the PointSet holding base frame - coordinates. */ - if( iframe == astGetBase( this ) ){ - if( forward ){ - clip = astClone( in ); - } else { - clip = astClone( result ); - } - -/* If the clipping frame is the current frame, then take a clone of the - PointSet holding current coordinates. Note, if the returned physical - coordinates have already been normalised, we don't need to normalise - the clipping coordinates. */ - } else if( iframe == astGetCurrent( this ) ){ - if( forward ){ - clip = astClone( result ); - if( norm ) clip_norm = 0; - } else { - clip = astClone( in ); - } - -/* If the clipping Frame is neither the base nor the current Frame, we need - to map the returned normalised points into the clipping Frame. */ - } else { - if( forward ){ - map = astGetMapping( this, AST__CURRENT, iframe ); - } else { - map = astGetMapping( this, AST__BASE, iframe ); - } - clip = astTransform( map, result, 1, NULL ); - map = astAnnul( map ); - } - -/* Get a pointer to the coordinate data in the clipping Frame. */ - ptr_clip = astGetPoints( clip ); - -/* If necessary, normalise the coordinates in the clipping frame. */ - if( clip_norm ){ - -/* Get work space to hold a single position. */ - work = (double *) astMalloc( sizeof(double)*(size_t)naxes ); - -/* Check the work space and axis pointers can be used. */ - if( astOK ){ - -/* Now loop through every position, copying the axis values to the work array, - normalising them using astNorm, and copying them back to the clipping - PointSet. */ - for( i = 0; i < npoint; i++ ){ - for( j = 0; j < naxes; j++ ) work[ j ] = ptr_clip[ j ][ i ]; - astNorm( fr, work ); - for( j = 0; j < naxes; j++ ) ptr_clip[ j ][ i ] = work[ j ]; - } - } - -/* Free the work space. */ - work = (double *) astFree( (void *) work ); - - } - -/* If all has gone ok, we will now clip the returned points. */ - if( astOK ){ - -/* Get the logical operation to be used to determine if a point is to be - clipped. A zero value means that a logical AND is to be performed - between the axes (i.e. all axes must be within the supplied bounds for a - point to be retained). A non-zero value means that a logical OR is to be - performed between the axes (i.e. only a single axis need be within the - supplied bounds for a point to be retained). */ - clip_or = astGetClipOp( this ); - -/* Do each point in turn. */ - for( j = 0; j < npoint; j++ ){ - -/* If all axes must fall within the supplied range to avoid the point being - clipped (i.e. if clip_or is 0), then assume initially that the point - is not to be clipped. This will be toggled as soon as the first - out-of-bounds point is found. If, on the other hand, the point is - only clipped if all axis values are out-of-bounds, then assume - initially that the point is to be clipped. This will be toggled as - soon as the first axis value is found which is not out-of-bounds. */ - clipit = clip_or; - -/* Check each axis value for the current point. */ - for( i = 0; i < naxes; i++ ){ - axval = ptr_clip[ i ][ j ]; - -/* Chekc that it is not bad. */ - if( axval != AST__BAD ){ - -/* Store the bounds of the clipping volume on this axis. */ - lbnd = this->clip_lbnd[ i ]; - ubnd = this->clip_ubnd[ i ]; - -/* Set a flag indicating if the axis value is within the specified range. - If the supplied bounds are reversed, they specify the range to exclude, - otherwise they specify the range to include. */ - if( lbnd <= ubnd ){ - axin = ( axval >= lbnd && axval <= ubnd ); - } else { - axin = ( axval < ubnd || axval > lbnd ); - } - -/* If the point is within the range and only one such point is - required to avoid the point being clipped, indicate that the point - should not be clipped, and leave the loop. */ - if( axin && clip_or ){ - clipit = 0; - break; - -/* If the point is not within the range and we only one such point is - required to cause the point to be clipped, indicate that the point - should be clipped, and leave the loop. */ - } else if( !axin && !clip_or ){ - clipit = 1; - break; - } - -/* Clip the point if any axis value is bad in the clipping Frame. */ - } else { - clipit = 1; - break; - } - - } - -/* If the point is to be clipped, set all returned axis values bad. */ - if( clipit ) { - for( i = 0; i < naxes; i++ ) ptr_out[ i ][ j ] = AST__BAD; - } - - } - - } - -/* Annul the PointSet holding clipping Frame positions. */ - if( clip ) clip = astAnnul( clip ); - -/* Annul the clipping Frame pointer. */ - fr = astAnnul( fr ); - - } - -/* If an error has occurred, annul the result. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; - -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Use a Plot to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out ) - -* Class Membership: -* Plot member function (over-rides the astTransform protected -* method inherited from the FrameSet class). - -* Description: -* This function takes a Plot and a set of points encapsulated in a -* PointSet and transforms the points from graphics coordinates to -* physical coordinates (in the forward direction). If the returned -* positions are physical coordinates (i.e. if a forward mapping is -* performed) they are normalised using the astNorm method of the supplied -* Plot. The returned axis values are set to AST__BAD for any positions -* which are outside the clipping volume set up by the astClip method. - -* Parameters: -* this -* Pointer to the Plot. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate -* transformation should be applied while a zero value requests the -* inverse transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - Clipping is only performed as set up using the astClip method. -* In particular, the clipping specified by the arguments to the astPlot -* constructor function is NOT performed. This is done in order to improve -* the efficiency of the curve drawing method astGridLine. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the Plot being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstMapping *map; /* Pointer to the mapping */ - AstPointSet *result; /* Positions in output Frame */ - AstPlot *plot; /* The Plot */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the Plot. */ - plot = (AstPlot *) this; - -/* Get the Mapping from the base to the current Frame. */ - map = astGetMapping( plot, AST__BASE, AST__CURRENT ); - -/* Do the transformation. */ - result = Trans( plot, NULL, map, in, forward, out, 1, "astTransform", - astGetClass( this ), status ); - -/* Annul the mapping. */ - map = astAnnul( map ); - -/* If an error has occurred, annul the result. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; - -} - -static double Typical( int n, double *value, double lolim, double hilim, - double *width, int *status ) { -/* -* Name: -* Typical - -* Purpose: -* Return a typical value within the supplied array of values. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double Typical( int n, double *value, double lolim, double hilim, -* double *width, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function locates the approximate mode of the supplied values, -* and returns one of the supplied values which is close to the modal -* value. Values outside an indicated range are ignored. - -* Parameters: -* n -* The number of data values. -* value -* A pointer to an array of "n" values. -* lolim -* Values less than lolim are ignored. Supply as -DBL_MAX if there -* is no lower limit. -* hilim -* Values greater than hilim are ignored. Supply as DBL_MAX if there -* is no upper limit. -* width -* Pointer to a double in which to return the width (i,e, data range) -* of the non-empty histogram cells. This is an estimate of the -* range of used values in the supplied array. NULL may be supplied. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A typical value from the supplied array. AST__BAD is returned only -* if an error has occurred, or if all the supplied values are AST__BAD -* or outside the specified range. - -*/ - -/* Local Variables: */ - double *a; /* Pointer to next value */ - double cnt; /* Modified count */ - double delta; /* Bin size */ - double maxval; /* Maximum supplied value */ - double mean; /* Mean supplied value */ - double minval; /* Minimum supplied value */ - double result; /* The returned value. */ - double w0; /* Rate of increase of weight with dist from edge */ - double w1; /* Weight for left edge */ - double w2; /* Weight for right edge */ - double w; /* Weight for this bin */ - int *hist; /* Pointer to first cell of histogram array */ - int i; /* Loop count */ - int ibin; /* Bin index */ - int maxcnt; /* Maximum no. of values in any bin */ - int modify; /* Modify the effect of the edge bins? */ - int nbin; /* No. of bins in histogram */ - int nc; /* Total number of points in histogram */ - int ngood; /* No. of good values supplied */ - int nonemp; /* No. of non-empty bins in hstogram */ - -/* Initialise. */ - result = AST__BAD; - if( width ) *width = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - ibin = 0; - -/* Find the minimum and maximum value in the supplied array, which are - also within the supplied limits. Also store the first good value - encountered in "result". */ - minval = DBL_MAX; - maxval = -DBL_MAX; - a = value; - ngood = 0; - for( i = 0; i < n; i++, a++ ) { - if( *a != AST__BAD ) { - if( *a >= lolim && *a <= hilim ) { - if( *a < minval ) minval = *a; - if( *a > maxval ) maxval = *a; - if( ngood == 0 ) result = *a; - ngood++; - } - } - } - -/* Initialise the returned width to the total data range. */ - if( width && maxval != -DBL_MAX ) *width = maxval - minval; - -/* If less than 3 points were found, we will return the first. Otherwise, if - 3 or more good values were found, find a typical value. */ - if( ngood > 2 ) { - -/* We will form a histogram of the supplied values in order to find the - mode. The number of bins in this histogram is chosen so that there - is an average of 2 points per bin. Find the number of bins. */ - nbin = ( ngood + 1 )/2; - -/* Find the bin size. If zero (i.e. if all values are equal), return the - first good value established above. */ - delta = ( maxval - minval )/ nbin; - if( delta > 0.0 ) { - -/* Allocat ememory for the histogram. */ - hist = astMalloc( sizeof(int)*(size_t)nbin ); - if( hist ) { - -/* Initialise the histogram. */ - for( i = 0; i < nbin; i++ ) hist[ i ] = 0; - -/* Form the histogram. Form the mean data value at the same time. */ - mean = 0.0; - a = value; - nc = 0; - for( i = 0; i < n; i++, a++ ){ - if( *a != AST__BAD ) { - if( *a >= lolim && *a <= hilim ) { - mean += *a; - ibin = (int) ( ( *a - minval )/ delta ); - if( ibin == nbin ) ibin--; - hist[ ibin ]++; - nc++; - } - } - } - - mean /= ngood; - -/* We tend to prefer not to use reference values which are very close the - the limits since they can give problems with regard to normalization - (rounding errors can knock them over the edge), so we modify the counts - in each bin of the histogram to reduce the impact of bins near the edge. - However, we do not do this if the number of bins is very small or if - all the counts are in the edge bins. */ - modify = ( nbin > 4 && - ( hist[ 0 ] + hist[ nbin - 1 ] < 0.98*ngood ) ); - -/* Find the bin with the highest modified count. If there is more than one bin - with the highest modified count, choose the one which is closest to the - mean data value found above. Also count the number of non-empty bins. */ - nonemp = 0; - maxcnt = 0; - w0 = nbin/2; - for( i = 0; i < nbin; i++ ) { - - cnt = hist[ i ]; - if( cnt ) nonemp++; - - if( modify ) { - w1 = i*w0; - w2 = ( nbin - 1 - i )*w0; - w = ( w1 < w2 ) ? w1 :w2; - if( w < 1.0 ) cnt *= w; - } - - if( cnt > maxcnt ) { - maxcnt = cnt; - ibin = i; - - } else if( cnt == maxcnt ) { - if( fabs( minval + ( i - 0.5 )*delta - mean ) < - fabs( minval + ( ibin - 0.5 )*delta - mean ) ) { - maxcnt = cnt; - ibin = i; - } - } - } - -/* Free the histogram memory. */ - hist = astFree( hist ); - -/* If required, return the width of the non-empty bins. */ - if( width ) *width = nonemp*delta; - -/* Call this function recursively to refine the value, restricting - attention to those data values which are within the range of the bin - found above. */ - if( maxcnt < nc && ibin*delta > 1000.0*DBL_EPSILON*fabs(maxval) ) { - minval += ibin*delta; - maxval = minval + delta; - result = Typical( n, value, minval, maxval, NULL, status ); - } - } - } - } - -/* Return the result. */ - return result; -} - -static int GetUseColour( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseColour - -* Purpose: -* Get the Colour value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GetUseColour( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Colour value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the colour -* for the first set specific value is returned. For example, if the -* Colour for AST__AXES_ID is requested, then the colour for AST__AXIS1_ID -* will be returned if set, and otherwise the colour for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AST__AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Colour value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOCOLOUR; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first - set genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestColour( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestColour( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestColour( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetColour( this, id ); - -} - -static int GetUseFont( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseFont - -* Purpose: -* Get the Font value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GetUseFont( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Font value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the Font -* for the first set specific value is returned. For example, if the -* Font for AST__AXES_ID is requested, then the Font for AST__AXIS1_ID -* will be returned if set, and otherwise the Font for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AST__AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Font value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOFONT; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first set - genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestFont( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestFont( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestFont( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetFont( this, id ); - -} - -static double GetUseSize( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseSize - -* Purpose: -* Get the Size value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double GetUseSize( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Size value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the Size -* for the first set specific value is returned. For example, if the -* Size for AST__AXES_ID is requested, then the Size for AST__AXIS1_ID -* will be returned if set, and otherwise the Size for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Size value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOSIZE; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first set - genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestSize( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestSize( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestSize( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetSize( this, id ); - -} - -static int GetUseStyle( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseStyle - -* Purpose: -* Get the Style value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GetUseStyle( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Style value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the style -* for the first set specific value is returned. For example, if the -* Style for AST__AXES_ID is requested, then the style for AST__AXIS1_ID -* will be returned if set, and otherwise the style for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AST__AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Style value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOSTYLE; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first set - genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestStyle( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestStyle( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestStyle( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetStyle( this, id ); - -} - -static double GetUseWidth( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseWidth - -* Purpose: -* Get the Width value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double GetUseWidth( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Width value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the Width -* for the first set specific value is returned. For example, if the -* Width for AST__AXES_ID is requested, then the Width for AST__AXIS1_ID -* will be returned if set, and otherwise the Width for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AST__AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Width value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOWIDTH; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first set - genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestWidth( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestWidth( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestWidth( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetWidth( this, id ); - -} - -static int TestUseColour( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseColour - -* Purpose: -* Test the Colour value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseColour( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Colour value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Colour value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestColour( this, id1 ); - if( nid > 1 ) ret = ret && astTestColour( this, id2 ); - if( nid > 2 ) ret = ret && astTestColour( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int TestUseFont( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseFont - -* Purpose: -* Test the Font value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseFont( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Font value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Font value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestFont( this, id1 ); - if( nid > 1 ) ret = ret && astTestFont( this, id2 ); - if( nid > 2 ) ret = ret && astTestFont( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int TestUseSize( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseSize - -* Purpose: -* Test the Size value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseSize( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Size value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Size value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestSize( this, id1 ); - if( nid > 1 ) ret = ret && astTestSize( this, id2 ); - if( nid > 2 ) ret = ret && astTestSize( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int TestUseStyle( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseStyle - -* Purpose: -* Test the Style value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseStyle( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Style value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Style value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestStyle( this, id1 ); - if( nid > 1 ) ret = ret && astTestStyle( this, id2 ); - if( nid > 2 ) ret = ret && astTestStyle( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int TestUseWidth( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseWidth - -* Purpose: -* Test the Width value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseWidth( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Width value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Width value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestWidth( this, id1 ); - if( nid > 1 ) ret = ret && astTestWidth( this, id2 ); - if( nid > 2 ) ret = ret && astTestWidth( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int ToggleLogLin( AstPlot *this, int axis, int islog, - const char *method, int *status ){ -/* -* -* Name: -* ToggleLogLin - -* Purpose: -* Toggle the nature of the Plot axis mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int ToggleLogLin( AstPlot *this, int axis, int islog, -* const char *method, int *status ) - -* Class Membership: -* Plot member function - -* Description: -* Each axis in the graphics Frame of a Plot can be mapped linearly or -* logarithmically onto the corresponding axis in the base Frame of -* the FrameSet supplied whtn the Plot was constructed. This function -* toggles the nature of the specified axis; if it is currently -* logarithmic it becomes linear, and if it is linear it becomes -* logarithmic. -* -* If the Frame canot be re-maped (for instance because the visible -* part of the axis includes the value zero), then zero is returned -* but no error is reported. - -* Parameters: -* this -* The Plot. -* axis -* Zero based axis index. -* islog -* Is the axis currently logarithmic? If so, this function remaps -* it so that it is linear (and vice-versa). -* method -* Pointer to a null-terminated string holding the name of the calling -* method (only used within error mesages). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the attempt to re-map the graphics Frame was succesful, -* zero otherwise. - -*/ - -/* Local Variables: */ - AstCmpMap *remap1; /* 1D Mapping to re-map the graphics Frame */ - AstCmpMap *remap2; /* 2D Mapping to re-map the graphics Frame */ - AstMathMap *logmap; /* 1D Logarithmic axis Mapping */ - AstUnitMap *unitmap; /* 1D Unit mapping */ - AstWinMap *linmap; /* 1D Linear axis Mapping */ - char fwdexp[ 25 + 2*AST__DBL_DIG ]; /* Forward log mapping expression */ - char invexp[ 28 + 2*AST__DBL_DIG ]; /* Inverse log mapping expression */ - const char *fwd[1]; /* Pointer to pass to MathMap constructor */ - const char *inv[1]; /* Pointer to pass to MathMap constructor */ - double a; /* Constant for log expression */ - double b1; /* Original base Frame axis value at first edge */ - double b2; /* Original base Frame axis value at second edge */ - double b; /* Constant for log expression */ - double c; /* Constant for log expression */ - double g1; /* Graphics axis value at first edge */ - double g2; /* Graphics axis value at second edge */ - int result; /* Returned value */ - -/* Inotialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the corresponding axis limits in the graphics coordinate system - and the original base Frame coordinate system. */ - if( axis == 0 ) { - if( this->xrev ) { - g1 = this->xhi; - g2 = this->xlo; - } else { - g1 = this->xlo; - g2 = this->xhi; - } - b1 = this->bbox[ 0 ]; - b2 = this->bbox[ 2 ]; - - } else { - if( this->yrev ) { - g1 = this->yhi; - g2 = this->ylo; - } else { - g1 = this->ylo; - g2 = this->yhi; - } - b1 = this->bbox[ 1 ]; - b2 = this->bbox[ 3 ]; - } - -/* Check the limits are usable (e.g. the base Frame values will be bad - if this Plot was restored from a dump of a Plot created before the - LogPlot attributes were added). */ - if( b1 != AST__BAD && b2 != AST__BAD && g1 != g2 && b1 != b2 && - b1*b2 > 0.0 ) { - -/* Form the 1D Mapping which maps the specified axis linearly onto the plotting - surface. The forward transformation goes from graphics to base Frame. */ - linmap = astWinMap( 1, &g1, &g2, &b1, &b2, "", status ); - -/* Form the 1D Mapping which maps the specified axis logarithmically onto the - plotting surface. The forward transformation goes from graphics to base - Frame. */ - c = log10( b1/b2 ); - a = ( g1 - g2 )/c; - - if( b1 > 0.0 ) { - b = ( g2*log10( b1 ) - g1*log10( b2 ) )/c; - (void) sprintf( invexp, "g=%.*g*log10(b)+%.*g", AST__DBL_DIG, a, AST__DBL_DIG, b ); - (void) sprintf( fwdexp, "b=pow(10,(g-%.*g)/%.*g)", AST__DBL_DIG, b, AST__DBL_DIG, a ); - - } else { - b = ( g2*log10( -b1 ) - g1*log10( -b2 ) )/c; - (void) sprintf( invexp, "g=%.*g*log10(-b)+%.*g", AST__DBL_DIG, a, AST__DBL_DIG, b ); - (void) sprintf( fwdexp, "b=-pow(10,(g-%.*g)/%.*g)", AST__DBL_DIG, b, AST__DBL_DIG, a ); - } - - fwd[ 0 ] = (const char *) fwdexp; - inv[ 0 ] = (const char *) invexp; - logmap = astMathMap( 1, 1, 1, fwd, 1, inv, "SimpFI=1,SimpIF=1", status ); - -/* If the axis was previously logarithmic, get the Mapping with which to remap - the graphics Frame so that it becomes linearly related to the base Frame - in the FrameSet supplied when the Plot was constructed. */ - if( islog ) { - astInvert( linmap ); - remap1 = astCmpMap( logmap, linmap, 1, "", status ); - -/* If the axis was previously linear, store the new value and get the Mapping - with which to remap the graphics Frame so that it becomes logarithmically - related to the base Frame in the FrameSet supplied when the Plot was - constructed. */ - } else { - astInvert( logmap ); - remap1 = astCmpMap( linmap, logmap, 1, "", status ); - } - -/* Add a 1D UnitMap to map the unaltered mapping. */ - unitmap = astUnitMap( 1, "", status ); - if( axis == 0 ) { - remap2 = astCmpMap( remap1, unitmap, 0, "", status ); - } else { - remap2 = astCmpMap( unitmap, remap1, 0, "", status ); - } - -/* Remap the base (graphics) Frame in the Plot. */ - astRemapFrame( this, AST__BASE, remap2 ); - -/* Free resources. */ - remap1 = astAnnul( remap1 ); - remap2 = astAnnul( remap2 ); - logmap = astAnnul( logmap ); - linmap = astAnnul( linmap ); - unitmap = astAnnul( unitmap ); - -/* Indicate success. */ - if( astOK ) result = 1; - - } - -/* Return the result. */ - return result; -} - -static int Ustrcmp( const char *a, const char *b, int *status ){ -/* -* Name: -* Ustrncmp - -* Purpose: -* A case blind version of strcmp. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Ustrcmp( const char *a, const char *b ) - -* Class Membership: -* Plot member function. - -* Description: -* Returns 0 if there are no differences between the two strings, and 1 -* otherwise. Comparisons are case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference between -* the two strings, whereas "strcmp" does. -* - This function attempts to execute even if an error has occurred. - -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int ret; /* Returned value */ - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Loop round each character. */ - while( 1 ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - - } - - } - -/* Return the result. */ - return ret; - -} - -static int Ustrncmp( const char *a, const char *b, size_t n, int *status ){ -/* -* Name: -* Ustrncmp - -* Purpose: -* A case blind version of strncmp. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Ustrncmp( const char *a, const char *b, size_t n ) - -* Class Membership: -* Plot member function. - -* Description: -* Returns 0 if there are no differences between the first "n" -* characters of the two strings, and 1 otherwise. Comparisons are -* case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. -* n -* The maximum number of characters to compare. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference -* between the two strings, whereas "strncmp" does. -* - This function attempts to execute even if an error has -* occurred. - -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int i; /* Character index */ - int ret; /* Returned value */ - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Compare up to "n" characters. */ - for( i = 0; i < (int) n; i++ ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - - } - - } - -/* Return the result. */ - return ret; - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Plot objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Plot objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to Plot */ - int i; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) obj; - -/* Free the clipping bounds arrays. */ - this->clip_lbnd = (double *) astFree( (void *) this->clip_lbnd ); - this->clip_ubnd = (double *) astFree( (void *) this->clip_ubnd ); - -/* Free the Grf function stack */ - this->grfstack = (AstGrfPtrs *) astFree( (void *) this->grfstack ); - -/* Free the graphics attribute stack. */ - for( i = this->ngat - 1; i >= 0; i-- ) { - this->gat[ i ] = astFree( this->gat[ i ] ); - } - -/* Free the graphics context pointer. */ - if( this->grfcontext ) { - this->grfcontext = astAnnul( this->grfcontext ); - this->grfcontextID = astAnnulId( this->grfcontextID ); - } - -/* Free the information about the tick marks to draw. */ - for( i = 0; i < 3; i++ ) { - this->majtickval[ i ] = astFree( this->majtickval[ i ] ); - this->mintickval[ i ] = astFree( this->mintickval[ i ] ); - this->nmajtickval[ i ] = 0; - this->nmintickval[ i ] = 0; - } - -/* Free the information about the drawn tick marks. */ - SaveTick( this, -1, 0.0, 0.0, 0, status ); -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Plot objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Plot objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstPlot *in; /* Pointer to input Plot */ - AstPlot *out; /* Pointer to output Plot */ - int axis; /* Zero based axis index */ - int n; /* Number of ticks saved */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Plots. */ - in = (AstPlot *) objin; - out = (AstPlot *) objout; - -/* For safety, first clear any references to the input memory from - the output Plot. */ - out->clip_lbnd = NULL; - out->clip_ubnd = NULL; - out->gat = NULL; - out->ngat = 0; - - for( axis = 0; axis < 3; axis++ ) { - out->majtickgx[ axis ] = NULL; - out->majtickgy[ axis ] = NULL; - out->majtickcount[ axis ] = 0; - out->mintickgx[ axis ] = NULL; - out->mintickgy[ axis ] = NULL; - out->mintickcount[ axis ] = 0; - out->majtickval[ axis ] = NULL; - out->nmajtickval[ axis ] = 0; - out->mintickval[ axis ] = NULL; - out->nmintickval[ axis ] = 0; - } - -/* Copy the clipping bounds arrays. */ - out->clip_lbnd = (double *) astStore( NULL, (void *) in->clip_lbnd, - sizeof(double)*(size_t)(in->clip_axes) ); - out->clip_ubnd = (double *) astStore( NULL, (void *) in->clip_ubnd, - sizeof(double)*(size_t)(in->clip_axes) ); - -/* Copy the Grf function stack */ - out->grfstack = (AstGrfPtrs *) astStore( NULL, (void *) in->grfstack, - sizeof(AstGrfPtrs)*(size_t)(in->grfnstack )); - -/* Copy the information about drawn tick marks. */ - for( axis = 0; axis < 3; axis++ ) { - n = in->majtickcount[ axis ]; - out->majtickgx[ axis ] = (double *) astStore( NULL, in->majtickgx[ axis ], - n*sizeof( double ) ); - out->majtickgy[ axis ] = (double *) astStore( NULL, in->majtickgy[ axis ], - n*sizeof( double ) ); - out->majtickcount[ axis ] = n; - - n = in->mintickcount[ axis ]; - out->mintickgx[ axis ] = (double *) astStore( NULL, in->mintickgx[ axis ], - n*sizeof( double ) ); - out->mintickgy[ axis ] = (double *) astStore( NULL, in->mintickgy[ axis ], - n*sizeof( double ) ); - out->mintickcount[ axis ] = n; - - n = in->nmajtickval[ axis ]; - out->majtickval[ axis ] = (double *) astStore( NULL, in->majtickval[ axis ], - n*sizeof( double ) ); - out->nmajtickval[ axis ] = n; - - n = in->nmintickval[ axis ]; - out->mintickval[ axis ] = (double *) astStore( NULL, in->mintickval[ axis ], - n*sizeof( double ) ); - out->nmintickval[ axis ] = n; - } - -/* If an error occurred, free any allocated memory. */ - if ( !astOK ) { - out->clip_lbnd = (double *) astFree( out->clip_lbnd ); - out->clip_ubnd = (double *) astFree( out->clip_ubnd ); - out->grfstack = (AstGrfPtrs *) astFree( out->grfstack ); - SaveTick( out, -1, 0.0, 0.0, 0, status ); - } -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Plot objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Plot class to an output Channel. - -* Parameters: -* this -* Pointer to the Plot whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstPlot *this; /* Pointer to the Plot structure */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char *comment; /* Pointer to comment string */ - double dval; /* Double precision value */ - int ax; /* Axis to which element refers */ - int axis; /* Zero based axis index */ - int id; /* Zero based graphical object id */ - int ival; /* Integer value */ - int itick; /* Tick mark index */ - int nax; /* Number of base Frame axes */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Get the number of graphics (base) frame axes - 2 for a Plot, 3 for a - Plot3D. */ - nax = astGetNin( this ); - -/* Write out values representing the instance variables for the - Plot class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Tol. */ -/* ---- */ - set = TestTol( this, status ); - dval = set ? GetTol( this, status ) : astGetTol( this ); - astWriteDouble( channel, "Tol", set, 0, dval, "Plotting tolerance" ); - -/* Grid. */ -/* ----- */ - set = TestGrid( this, status ); - ival = set ? GetGrid( this, status ) : astGetGrid( this ); - astWriteInt( channel, "Grid", set, 0, ival, "Is a grid required?" ); - -/* TickAll. */ -/* -------- */ - set = TestTickAll( this, status ); - ival = set ? GetTickAll( this, status ) : astGetTickAll( this ); - astWriteInt( channel, "TckAll", set, 1, ival, "Put ticks on all edges?" ); - -/* ForceExterior. */ -/* -------------- */ - set = TestForceExterior( this, status ); - ival = set ? GetForceExterior( this, status ) : astGetForceExterior( this ); - astWriteInt( channel, "FrcExt", set, 1, ival, "Force exterior labelling?" ); - -/* Invisible. */ -/* ---------- */ - set = TestInvisible( this, status ); - ival = set ? GetInvisible( this, status ) : astGetInvisible( this ); - astWriteInt( channel, "Invsbl", set, 1, ival, "Use invisible ink?" ); - -/* Border. */ -/* ------- */ - set = TestBorder( this, status ); - ival = set ? GetBorder( this, status ) : astGetBorder( this ); - astWriteInt( channel, "Border", set, 0, ival, "Draw a border round the grid?" ); - -/* ClipOp. */ -/* ------- */ - set = TestClipOp( this, status ); - ival = set ? GetClipOp( this, status ) : astGetClipOp( this ); - astWriteInt( channel, "ClpOp", set, 0, ival, "Clip using logical OR?" ); - -/* Clip. */ -/* ----- */ - set = TestClip( this, status ); - ival = set ? GetClip( this, status ) : astGetClip( this ); - astWriteInt( channel, "Clip", set, 0, ival, - ((ival == 0)?"Do not clip at plot edges": - ((ival == 1)?"Clip curves at plot edges": - ((ival == 2)?"Clip markers at plot edges": - "Clip markers and curves at plot edges")))); - -/* DrawTitle. */ -/* --------- */ - set = TestDrawTitle( this, status ); - ival = set ? GetDrawTitle( this, status ) : astGetDrawTitle( this ); - astWriteInt( channel, "DrwTtl", set, 1, ival, "Add a title to the grid?" ); - -/* DrawAxesUnits(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestDrawAxes( this, axis, status ); - ival = set ? GetDrawAxes( this, axis, status ) : astGetDrawAxes( this, axis ); - (void) sprintf( buff, "DrwAxs%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "Draw axis through ticks?" ); - } - -/* Abbrev(axis). */ -/* ------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestAbbrev( this, axis, status ); - ival = set ? GetAbbrev( this, axis, status ) : astGetAbbrev( this, axis ); - (void) sprintf( buff, "Abbrv%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "Abbreviate numerical axis labels?" ); - } - -/* Escape. */ -/* ------- */ - set = TestEscape( this, status ); - ival = set ? GetEscape( this, status ) : astGetEscape( this ); - astWriteInt( channel, "Escape", set, 1, ival, "Interpret escape sequences?" ); - -/* LabelAt(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLabelAt( this, axis, status ); - dval = set ? GetLabelAt( this, axis, status ) : astGetLabelAt( this, axis ); - if( dval != AST__BAD ){ - (void) sprintf( buff, "LblAt%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Put numerical labels at" ); - } - } - -/* Centre(axis). */ -/* ------------ */ - for( axis = 0; axis < nax; axis++ ){ - set = TestCentre( this, axis, status ); - dval = set ? GetCentre( this, axis, status ) : astGetCentre( this, axis ); - if( dval != AST__BAD ){ - (void) sprintf( buff, "Cen%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Tick mark origin" ); - } - } - -/* Gap(axis). */ -/* ---------- */ -/* Discovering the default value requires a lot of calculation. Only - write out this attribute if an explicit value has been set. */ - for( axis = 0; axis < nax; axis++ ){ - if( astTestGap( this, axis ) ) { - dval = astGetGap( this, axis ); - if( dval != AST__BAD ){ - (void) sprintf( buff, "Gap%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Difference between ticks" ); - } - } - } - -/* LogGap(axis). */ -/* ------------- */ -/* Discovering the default value requires a lot of calculation. Only - write out this attribute if an explicit value has been set. */ - for( axis = 0; axis < nax; axis++ ){ - if( astTestLogGap( this, axis ) ) { - dval = astGetLogGap( this, axis ); - if( dval != AST__BAD ){ - (void) sprintf( buff, "LgGap%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Ratio between ticks" ); - } - } - } - -/* NumLabGap(axis). */ -/* ---------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestNumLabGap( this, axis, status ); - dval = set ? GetNumLabGap( this, axis, status ) : astGetNumLabGap( this, axis ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "NmGap%d", axis + 1 ); - astWriteDouble( channel, buff, set, 1, dval, "Spacing of numerical labels" ); - } - } - -/* TextLabGap(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestTextLabGap( this, axis, status ); - dval = set ? GetTextLabGap( this, axis, status ) : astGetTextLabGap( this, axis ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "TxGap%d", axis + 1 ); - astWriteDouble( channel, buff, set, 1, dval, "Spacing of descriptive labels" ); - } - } - -/* LabelUp(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLabelUp( this, axis, status ); - ival = set ? GetLabelUp( this, axis, status ) : astGetLabelUp( this, axis ); - (void) sprintf( buff, "LblUp%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Draw numerical labels upright?" ); - } - -/* LogPlot(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLogPlot( this, axis, status ); - ival = set ? GetLogPlot( this, axis, status ) : astGetLogPlot( this, axis ); - (void) sprintf( buff, "LgPlt%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Map plot axis logarithmically?" ); - } - -/* LogTicks(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLogTicks( this, axis, status ); - ival = set ? GetLogTicks( this, axis, status ) : astGetLogTicks( this, axis ); - (void) sprintf( buff, "LgTck%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Space ticks logarithmically?" ); - } - -/* LogLabel(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLogLabel( this, axis, status ); - ival = set ? GetLogLabel( this, axis, status ) : astGetLogLabel( this, axis ); - (void) sprintf( buff, "LgLbl%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Scientific notation for labels?" ); - } - -/* NumLab(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestNumLab( this, axis, status ); - ival = set ? GetNumLab( this, axis, status ) : astGetNumLab( this, axis ); - (void) sprintf( buff, "NmLbl%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Draw numerical labels?" ); - } - -/* MinTick(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestMinTick( this, axis, status ); - ival = set ? GetMinTick( this, axis, status ) : astGetMinTick( this, axis ); - (void) sprintf( buff, "MnTks%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "No. of sub-divisions " - "between major tick marks" ); - } - -/* TextLab(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestTextLab( this, axis, status ); - ival = set ? GetTextLab( this, axis, status ) : astGetTextLab( this, axis ); - (void) sprintf( buff, "TxLbl%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "Draw textual label?" ); - } - -/* LabelUnits(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLabelUnits( this, axis, status ); - ival = set ? GetLabelUnits( this, axis, status ) : astGetLabelUnits( this, axis ); - (void) sprintf( buff, "LbUnt%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "Add units to axis label?" ); - } - -/* Style(object). */ -/* -------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestStyle( this, id, status ); - ival = set ? GetStyle( this, id, status ) : astGetStyle( this, id ); - (void) sprintf( buff, "Style%d", id + 1 ); - comment = GrfItem( id, " line style", &ax, status ); - if( ax < nax ) astWriteInt( channel, buff, set, 0, ival, comment ); - comment = (char *) astFree( (void *) comment ); - } - -/* Font(object). */ -/* ------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestFont( this, id, status ); - ival = set ? GetFont( this, id, status ) : astGetFont( this, id ); - (void) sprintf( buff, "Font%d", id + 1 ); - comment = GrfItem( id, " character font", &ax, status ); - if( ax < nax ) astWriteInt( channel, buff, set, 0, ival, comment ); - comment = (char *) astFree( (void *) comment ); - } - -/* Colour(object). */ -/* --------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestColour( this, id, status ); - ival = set ? GetColour( this, id, status ) : astGetColour( this, id ); - (void) sprintf( buff, "Col%d", id + 1 ); - comment = GrfItem( id, " colour index", &ax, status ); - if( ax < nax ) astWriteInt( channel, buff, set, 0, ival, comment ); - comment = (char *) astFree( (void *) comment ); - } - -/* Width(object). */ -/* -------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestWidth( this, id, status ); - dval = set ? GetWidth( this, id, status ) : astGetWidth( this, id ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "Width%d", id + 1 ); - comment = GrfItem( id, " line width", &ax, status ); - if( ax < nax ) astWriteDouble( channel, buff, set, 0, dval, comment ); - comment = (char *) astFree( (void *) comment ); - } - } - -/* Size(object). */ -/* ------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestSize( this, id, status ); - dval = set ? GetSize( this, id, status ) : astGetSize( this, id ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "Size%d", id + 1 ); - comment = GrfItem( id, " character size", &ax, status ); - if( ax < nax ) astWriteDouble( channel, buff, set, 0, dval, comment ); - comment = (char *) astFree( (void *) comment ); - } - } - -/* TitleGap. */ -/* --------- */ - set = TestTitleGap( this, status ); - dval = set ? GetTitleGap( this, status ) : astGetTitleGap( this ); - if( dval != AST__BAD ) astWriteDouble( channel, "TtlGap", set, 1, dval, - "Gap between title and edge" ); - -/* MajTickLen(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestMajTickLen( this, axis, status ); - dval = set ? GetMajTickLen( this, axis, status ) : astGetMajTickLen( this, axis ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "MjTkLn%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Major tick length" ); - } - } - -/* MinTickLen(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestMinTickLen( this, axis, status ); - dval = set ? GetMinTickLen( this, axis, status ) : astGetMinTickLen( this, axis ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "MnTkLn%d", axis + 1 ); - astWriteDouble( channel, buff, set, 1, dval, "Minor tick length" ); - } - } - -/* Labelling. */ -/* ---------- */ - set = TestLabelling( this, status ); - ival = set ? GetLabelling( this, status ) : astGetLabelling( this ); - comment = "Labelling scheme"; - astWriteString( channel, "Lbling", set, 0, xlbling[ival], comment ); - -/* Edge(axis). */ -/* ----------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestEdge( this, axis, status ); - ival = set ? GetEdge( this, axis, status ) : astGetEdge( this, axis ); - (void) sprintf( buff, "Edge%d", axis + 1 ); - comment = "Edge used to label an axis"; - astWriteString( channel, buff, set, 0, xedge[ival], comment ); - } - -/* Now do instance variables which are not attributes. */ -/* =================================================== */ - -/* Only write out clipping information if set. */ - if( this->clip_lbnd && this->clip_ubnd ){ - -/* The lower bounds of the clipping volume. */ - for( axis = 0; axis < this->clip_axes; axis++ ){ - (void) sprintf( buff, "ClpLb%d", axis + 1 ); - if( this->clip_lbnd && (this->clip_lbnd)[ axis ] != AST__BAD ){ - astWriteDouble( channel, buff, 1, 0, (this->clip_lbnd)[ axis ], - "Lower bound of clipping region" ); - } - } - -/* The upper bounds of the clipping volume. */ - for( axis = 0; axis < this->clip_axes; axis++ ){ - (void) sprintf( buff, "ClpUb%d", axis + 1 ); - if( this->clip_ubnd && (this->clip_ubnd)[ axis ] != AST__BAD ){ - astWriteDouble( channel, buff, 1, 0, (this->clip_ubnd)[ axis ], - "Upper bound of clipping region" ); - } - } - -/* The number of bounds supplied for the clipping volume. */ - astWriteInt( channel, "ClpAxs", 1, 0, this->clip_axes, - "No. of bounds for clipping region" ); - -/* The index of the clipping Frame within the Plot. */ - astWriteInt( channel, "ClpFrm", 1, 0, this->clip_frame, - "Index of clipping Frame" ); - } - -/* The bounds of the plotting area in graphics coords. */ - astWriteDouble( channel, "Xlo", 1, 1, this->xlo, - "Lower X bound of plotting area" ); - astWriteDouble( channel, "Ylo", 1, 1, this->ylo, - "Lower Y bound of plotting area" ); - astWriteDouble( channel, "Xhi", 1, 1, this->xhi, - "Upper X bound of plotting area" ); - astWriteDouble( channel, "Yhi", 1, 1, this->yhi, - "Upper Y bound of plotting area" ); - -/* Axis reversal flags. */ - astWriteInt( channel, "Xrev", 1, 0, this->xrev, "X axis reversed?" ); - astWriteInt( channel, "Yrev", 1, 0, this->yrev, "Y axis reversed?" ); - -/* The bounds of the plotting area in the base Frame of the FrameSet - supplied when the Plot was constructed. */ - astWriteDouble( channel, "Xb1", 1, 1, this->bbox[ 0 ], - "Lower X bound of supplied base Frame" ); - astWriteDouble( channel, "Yb1", 1, 1, this->bbox[ 1 ], - "Lower Y bound of supplied base Frame" ); - astWriteDouble( channel, "Xb2", 1, 1, this->bbox[ 2 ], - "Upper X bound of supplied base Frame" ); - astWriteDouble( channel, "Yb2", 1, 1, this->bbox[ 3 ], - "Upper Y bound of supplied base Frame" ); - -/* User-specified tick values */ - for( axis = 0; axis < 3; axis++ ) { - - if( this->nmajtickval[ axis ] > 0 ) { - sprintf( buff, "NMjTk%d", axis + 1 ); - astWriteInt( channel, buff, 1, 1, this->nmajtickval[ axis ], "" ); - - for( itick = 0; itick < this->nmajtickval[ axis ]; itick++ ) { - sprintf( buff, "MjTk%d_%d", axis + 1, itick + 1 ); - astWriteDouble( channel, buff, 1, 1, - this->majtickval[ axis ][ itick ], "" ); - } - } - - if( this->nmintickval[ axis ] > 0 ) { - sprintf( buff, "NMnTk%d", axis + 1 ); - astWriteInt( channel, buff, 1, 1, this->nmintickval[ axis ], "" ); - - for( itick = 0; itick < this->nmintickval[ axis ]; itick++ ) { - sprintf( buff, "MnTk%d_%d", axis + 1, itick + 1 ); - astWriteDouble( channel, buff, 1, 1, - this->mintickval[ axis ][ itick ], "" ); - } - } - } - -/* Return. */ - return; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPlot and astCheckPlot functions using - the macros defined for this purpose in the "object.h" header - file. */ -astMAKE_ISA(Plot,FrameSet) -astMAKE_CHECK(Plot) - -AstPlot *astPlot_( void *frame_void, const float *graphbox, - const double *basebox, const char *options, int *status, ...) { -/* -*+ -* Name: -* astPlot - -* Purpose: -* Create a Plot. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* AstPlot *astPlot( AstFrame *frame, const float *graphbox, -* const double *basebox, const char *options, ..., int *status ) - -* Class Membership: -* Plot constructor. - -* Description: -* This function creates a new Plot and optionally initialises -* its attributes. -* -* The supplied Frame (or the base frame if a FrameSet was supplied) is -* assumed to be related to the graphics world coordinate system by a -* simple shift and scale along each axis. The mapping between graphics -* world coordinates and this Frame is specified by supplying the -* coordinates in both systems at the bottom left and top right corners -* of a box on the graphics device. By default, no graphics will be -* produced outside the supplied box, but this default behaviour can be -* changed by setting explicit values for the various clipping attributes. - -* Parameters: -* frame -* A pointer to a Frame or FrameSet to be annotated. If a NULL pointer -* is supplied, then a default 2-D Frame will be created to which labels, -* etc, can be attached by setting the relevant Frame attributes. -* graphbox -* A pointer to an array of 4 values giving the graphics world -* coordinates of the bottom left and top right corners of a box on -* the graphics output device. The first pair of values should be the -* coordinates of the bottom left corner of the box and the second -* pair of values should be the coordinates of the top right corner. -* The horizontal axis should be given first in each pair. -* basebox -* A pointer to an array of 4 values giving the coordinates in the -* supplied Frame, or base frame of the supplied FrameSet, at the -* bottom left and top right corners of the box specified by parameter -* graphbox. These should be supplied in the same order as for -* parameter "graphbox". -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new Plot. The syntax used is the same as -* for the astSet method and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of arguments may follow it in order to -* supply values to be substituted for these specifiers. The -* rules for supplying these are identical to those for the -* astSet method (and for the C "printf" function). - -* Returned Value: -* A pointer to the new Plot. - -* Notes: -* - The base Frame of the created Plot corresponds to the graphics world -* coordinate system, and should not, in general, be changed. -* - The current Frame of the created Plot corresponds to the Frame -* given by parameter "frame". If a FrameSet was supplied then its -* current Frame becomes the current Frame of the created Plot. -* - If the supplied Frame, or base Frame if a FrameSet was supplied, -* has more than 2 axes, then the sub-Frame defined by the first 2 axes -* is used. -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic Plot constructor which -* is available via the protected interface to the Plot class. -* A public interface is provided by the astPlotId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "frame" parameter is of type (void *) and is converted and -* validated within the function itself. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPlot *new; /* Pointer to new Plot */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - new = NULL; - -/* Obtain and validate a pointer to any supplied Frame structure. */ - if( frame_void ){ - frame = astCheckFrame( frame_void ); - } else { - frame = NULL; - } - -/* Check the pointer can be used. */ - if ( astOK ) { - -/* Initialise the Plot, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPlot( NULL, sizeof( AstPlot ), !class_init, - &class_vtab, "Plot", frame, graphbox, - basebox ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - Plot's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new Plot. */ - return new; -} - -AstPlot *astInitPlot_( void *mem, size_t size, int init, AstPlotVtab *vtab, - const char *name, AstFrame *frame, const float *graphbox, - const double *basebox, int *status ) { -/* -*+ -* Name: -* astInitPlot - -* Purpose: -* Initialise a Plot. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* AstPlot *astInitPlot( void *mem, size_t size, int init, -* AstPlotVtab *vtab, const char *name, -* AstFrame *frame, const float *graphbox, -* const double *basebox ) - -* Class Membership: -* Plot initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Plot object. It allocates memory (if necessary) to accommodate -* the Plot plus any additional data associated with the derived class. -* It then initialises a Plot structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Plot at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Plot is to be created. This -* must be of sufficient size to accommodate the Plot data -* (sizeof(Plot)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Plot (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Plot -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Plot's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Plot. If NULL, the vtab associated with this class -* (Plot) will be used. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* A pointer to the Frame or Frameset to be annotated. -* graphbox -* A pointer to an array of 4 values giving the graphics coordinates -* of the bottom left and top right corners of a box on the graphics -* output device. The first pair of values should be the graphics -* coordinates of the bottom left corner of the box and the second -* pair of values are the graphics coordinates of the top right corner. -* The horizontal axis should be given first in each pair. -* basebox -* A pointer to an array of 4 values giving the coordinates in the -* supplied Frame or base Frame of the supplied FrameSet at the bottom -* left and top right corners of the box specified by parameter graphbox. -* These should be supplied in the same order as for parameter "graphbox". - -* Returned Value: -* A pointer to the new Plot. - -* Notes: -* - If the supplied Frame, or base Frame if a FrameSet was supplied, -* has more than 2 axes, then the sub-Frame defined by the first 2 axes -* is used. -* - The current Frame of the supplied FrameSet need not be 2-dimensional. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *baseframe; /* Pointer to base frame */ - AstFrame *graphicsframe; /* Pointer to graphics frame */ - AstFrameSet *fset0; /* The n-D FrameSet to be annotated */ - AstFrameSet *fset; /* The 2-D FrameSet to be annotated */ - AstPlot *new; /* Pointer to new Plot */ - AstWinMap *map; /* Mapping for converting bbox -> gbox */ - char *mess; /* Pointer to a descriptive message */ - double gbox[ 4 ]; /* Double precision version of "graphbox" */ - int axis; /* Axis index, 0 or 1 */ - int bi; /* Index of base frame */ - int ci; /* Index of current frame */ - int i; /* Loop count */ - int id; /* Plot object id */ - int naxes; /* No. of axes in frame */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(frame); - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - fset = NULL; - mess = NULL; - -/* If no vtab was supplied, use the vtab for this class (Plot). */ - if( !vtab ) { - vtab = &class_vtab; - if ( !class_init ) { - astInitPlotVtab( vtab, "Plot" ); - class_init = 1; - } - -/* If necessary, initialise the virtual function table. */ - } else if ( init ) { - astInitPlotVtab( vtab, name ); - } - -/* Initialise. */ - new = NULL; - baseframe = NULL; - -/* First of all we need to ensure that we have a FrameSet and a base - Frame on which to base the new Plot. If a NULL Frame pointer was - supplied, create a default 2-D Frame, and then create a FrameSet - containing just this default Frame. Also store a pointer to a - message which can be used to describe the object within error - messages. */ - if( !frame ){ - baseframe = astFrame( 2, "", status ); - fset = astFrameSet( baseframe, "", status ); - mess = "default 2-d Frame"; - -/* If an object was supplied, report an error if it is not a Frame or - an object derived from a Frame (such as a FrameSet). */ - } else if( !astIsAFrame( frame ) ){ - if( astOK ){ - astError( AST__BDOBJ, "astInitPlot(%s): Supplied Object (class '%s') " - "is not a Frame.", status, name, astGetClass( frame ) ); - } - -/* If the supplied object is a Plot or an object derived from a Plot (a Plot - is a sort of Frame and so will pass the above test), extract a - FrameSet from the Plot, and clear the Domain attribute for any existing - Frames which have Domain GRAPHICS. */ - } else if( astIsAPlot( frame ) ){ - fset0 = astFrameSet( frame, "", status ); - fset = astCopy( fset0 ); - fset0 = astAnnul( fset0 ); - - for( i = 0; i < astGetNframe( fset ); i++ ) { - graphicsframe = astGetFrame( fset, i ); - if( !strcmp( astGetDomain( graphicsframe ), "GRAPHICS" ) ) { - astClearDomain( graphicsframe ); - } - graphicsframe = astAnnul( graphicsframe ); - } - - baseframe = astGetFrame( fset, astGetBase( fset ) ); - mess = "base Frame of the supplied Plot"; - -/* If the object is not a FrameSet, create a FrameSet holding the - supplied Frame. If the Frame is not 2D, an extra 2D Frame is - included in the FrameSet derived from axes 1 and 2 of the supplied - Frame. This new Frame becomes the base Frame. */ - } else if( !astIsAFrameSet( frame ) ){ - fset0 = astFrameSet( frame, "", status ); - mess = "supplied Frame"; - fset = Fset2D( fset0, AST__BASE, status ); - fset0 = astAnnul( fset0 ); - baseframe = astGetFrame( fset, astGetBase( fset ) ); - -/* If a FrameSet was supplied, ensure it has a 2D base Frame. - If the supplied FrameSet is not 2D, then a new base Frame is - inserted into it which is derived from axes 1 and 2 of the - original base Frame. */ - } else { - fset = Fset2D( (AstFrameSet *) frame, AST__BASE, status ); - baseframe = astGetFrame( fset, astGetBase( fset ) ); - mess = "base Frame of the supplied FrameSet"; - } - -/* Check that there are 2 axes in the base frame of the FrameSet. */ - naxes = astGetNaxes( baseframe ); - if ( naxes != 2 && astOK ) { - astError( AST__NAXIN, "astInitPlot(%s): Number of axes (%d) in the %s " - "is invalid - this number should be 2.", status, name, naxes, mess ); - } - -/* Check that neither dimension of the graphbox is zero. */ - if( ( graphbox[ 2 ] == graphbox[ 0 ] || - graphbox[ 3 ] == graphbox[ 1 ] ) && astOK ){ - astError( AST__BADBX, "astInitPlot(%s): The plotting area has zero size " - "in the graphics world coordinate system.", status, name ); - } - -/* Check that neither dimension of the graphbox is bad. */ - if( astISBAD(graphbox[0]) || astISBAD(graphbox[1]) || - astISBAD(graphbox[2]) || astISBAD(graphbox[3]) ) { - astError( AST__BADBX, "astInitPlot(%s): The plotting area has undefined limits " - "in the graphics world coordinate system.", status, name ); - } - -/* Check that neither dimension of the basebox is zero. */ - if( astISBAD(basebox[2]) || astISBAD(basebox[0]) ) { - astError( AST__BADBX, "astInitPlot(%s): The limits of the horizontal " - "axis of the %s are undefined or bad.", status, name, name ); - } else if( astISBAD(basebox[3]) || astISBAD(basebox[1]) ) { - astError( AST__BADBX, "astInitPlot(%s): The limits of the vertical " - "axis of the %s are undefined or bad.", status, name, name ); - } - -/* Create a Frame which describes the graphics world coordinate system. */ - graphicsframe = astFrame( 2, - "Domain=GRAPHICS,Title=Graphical Coordinates", status ); - -/* Initialise a FrameSet structure (the parent class) as the first - component within the Plot structure, allocating memory if necessary. - The new FrameSet is initialised to hold the graphics Frame created - above. */ - new = (AstPlot *) astInitFrameSet( mem, size, 0, (AstFrameSetVtab *) vtab, - name, graphicsframe ); - - if ( astOK ) { - -/* Initialise the Plot data. */ -/* ----------------------------- */ - -/* Get a double precision version of "graphbox". */ - gbox[ 0 ] = (double) graphbox[ 0 ]; - gbox[ 1 ] = (double) graphbox[ 1 ]; - gbox[ 2 ] = (double) graphbox[ 2 ]; - gbox[ 3 ] = (double) graphbox[ 3 ]; - -/* Store the bounds in graphics coordinates of the clipping box, ensuring - that the low bound is lower than the high bound. Set flags to indicate - if the supplied bounds has to be reversed to do this (some graphics - system have the Y axis increasing from the top of the screen to the - bottom). */ - if( graphbox[ 0 ] <= graphbox[ 2 ] ){ - new->xlo = gbox[ 0 ]; - new->xhi = gbox[ 2 ]; - new->xrev = 0; - } else { - new->xhi = gbox[ 0 ]; - new->xlo = gbox[ 2 ]; - new->xrev = 1; - astSetDirection( graphicsframe, 0, 0 ); - } - if( graphbox[ 1 ] <= graphbox[ 3 ] ){ - new->ylo = gbox[ 1 ]; - new->yhi = gbox[ 3 ]; - new->yrev = 0; - } else { - new->yhi = gbox[ 1 ]; - new->ylo = gbox[ 3 ]; - new->yrev = 1; - astSetDirection( graphicsframe, 1, 0 ); - } - -/* Store the bounds of the Plot within the base Frame of the supplied - FrameSet. */ - new->bbox[ 0 ] = basebox[ 0 ]; - new->bbox[ 1 ] = basebox[ 1 ]; - new->bbox[ 2 ] = basebox[ 2 ]; - new->bbox[ 3 ] = basebox[ 3 ]; - -/* We initially assume that the base Frame of the supplied FrameSet is - mapped lineary onto the graphics frame. This may be changed later by - assigning values to the LogPlot attributes. Create a WinMap which - maps the base box (within the base Frame of the supplied FrameSet) - onto the graphics box. */ - map = astWinMap( 2, gbox, gbox + 2, basebox, basebox + 2, "", status ); - -/* Get the index of the current (physical) and base (pixel) Frames in - the supplied FrameSet. */ - bi = astGetBase( fset ); - ci = astGetCurrent( fset ); - -/* Temporarily set the current Frame to be the pixel frame. */ - astSetCurrent( fset, bi ); - -/* Add the supplied FrameSet into the Plot (i.e. FrameSet) created - earlier. This leaves the graphics frame with index 1 in the - returned Plot. We use the linear mapping initially. */ - astAddFrame( (AstFrameSet *) new, 1, map, fset ); - map = astAnnul( map ); - -/* Set the current Frame in the Plot to be the physical coordinate Frame - (with index incremented by one because the graphics Frame has been added). */ - astSetCurrent( (AstFrameSet *) new, ci + 1 ); - -/* Re-establish the original current Frame in the supplied FrameSet. */ - astSetCurrent( fset, ci ); - -/* Store a value of -1.0 for Tol to indicate that no value has yet been - set. This will cause a default value of 0.001 to be used. */ - new->tol = -1.0; - -/* Set up default clipping information which gives no clipping. */ - new->clip_frame = AST__NOFRAME; - new->clip_lbnd = NULL; - new->clip_ubnd = NULL; - new->clip_axes = 0; - -/* Is a grid covering the plotting area required? Store a value of -1 - to indicate that no value has yet been set. This will cause a default - value of 0 (no) to be used. */ - new->grid = -1; - -/* Are tick marks to be placed on both edges in a pair of opposite edges? - Store a value of -1 to indicate that no value has yet been set. This will - cause a default value of 1 (yes) to be used. */ - new->tickall = -1; - -/* Graphics context identifier */ - new->grfcontext = NULL; - new->grfcontextID = NULL; - -/* Shoudl ast Grid draw a boundary round the regions of valid coordinates? - Store a value of -1 to indicate that no value has yet been set. This will - cause a default value of 1 (yes) to be used. */ - new->border = -1; - -/* Should graphics be drawn invisible? Store a value of -1 to indicate that - no value has yet been set. This will cause a default value of 0 (no) to - be used. */ - new->invisible = -1; - -/* By default clip markers but not curves at the boundary of the plotting - area. This was the only behaviour available prior to the introduction of - the Clip attribute, and is chosen as the default to maintain backwards - compatibility. */ - new->clip = -1; - -/* Is clipping to be done using a logical OR operation between the axes? - Store a value of -1 to indicate that no value has yet been set. This will - cause a default value of 0 (no, i.e. a logical AND) to be used. */ - new->clipop = -1; - -/* Is the graphics interface registered using astGrfSet to be used? - Store a value of -1 to indicate that no value has yet been set. This will - cause a default value of 0 (no, i.e. use the graphics interface - selected at link-time) to be used. */ - new->grf = -1; - -/* Wrapper functions to call the drawing routines. These are the - default wrappers which call GRF routines written in C. Alternative - wrappers are defined in fplot.c for use with GRF routines written in - F77. */ - new->GAttr = CGAttrWrapper; - new->GBBuf = CGBBufWrapper; - new->GEBuf = CGEBufWrapper; - new->GFlush = CGFlushWrapper; - new->GLine = CGLineWrapper; - new->GMark = CGMarkWrapper; - new->GText = CGTextWrapper; - new->GCap = CGCapWrapper; - new->GTxExt = CGTxExtWrapper; - new->GScales = CGScalesWrapper; - new->GQch = CGQchWrapper; - - for( i = 0; i < AST__NGRFFUN; i++ ) new->grffun[i] = NULL; - new->grfstack = NULL; - new->grfnstack = 0; - -/* Is a title to be added to an annotated grid? Store a value of -1 to - indicate that no value has yet been set. This will cause a default value - of 1 (yes) to be used. */ - new->drawtitle = -1; - -/* Are escape sequences within text strings to be interpreted? If not, - they are printed literally. Store a value of -1 when not set. - This will cause a default value of 1 (yes) to be used. */ - new->escape = -1; - -/* A boolean attribute indicating where numerical labels are to be - placed; zero implies round the edges of the plotting area; non-zero - implies within the plotting area. The unset value of -9999 yields a - default of zero. */ - new->labelling = -9999; - -/* Graphics attributes. Default behaviour is to use the current values. */ - for( id = 0; id < AST__NPID; id++ ){ - new->style[ id ] = -1; - new->font[ id ] = -1; - new->colour[ id ] = -1; - new->width[ id ] = AST__BAD; - new->size[ id ] = AST__BAD; - } - -/* The space between the top edge and the grid title as a fraction of the - minimum dimension of the plotting area. Store AST__BAD to indicate that no - value has been set. This will cause a default of 0.05 to be used. */ - new->titlegap = AST__BAD; - -/* Initialise the protected Ink attribute so that visible ink is used. */ - new->ink = -1; - -/* A stack of AstGat pointers used to store the graphical attributes for - text within strings which include graphical escape sequences. */ - new->gat = NULL; - new->ngat = 0; - -/* Now set the attribute values for each axis. The arrays stored in the - Plot struture allow for 3 graphics axes (e.g. as used by a Plot3D) so - we initialise 3 axes here even though the Plot class only uses 2. */ - for( axis = 0; axis < 3; axis++ ) { - -/* Are curves to be drawn through the tick marks even if no grid is - produced? Store a value of -1 to indicate that no value has yet been - set. This will cause a default value of 1 (yes) to be used. */ - new->drawaxes[ axis ] = -1; - -/* Are adjacent numerical axis labels to be abbreviated by removing matching - leading fields? Store a value of -1 to indicate that no value has yet been - set. This will cause a default value of 1 (yes) to be used. */ - new->abbrev[ axis ] = -1; - -/* The length of the major tick marks as a fraction of the minimum - dimension of the plotting area. Store AST__BAD to indicate that no - value has been set. This will cause a default of 0.015 to be used. */ - new->majticklen[ axis ] = AST__BAD; - -/* The length of the minor tick marks as a fraction of the minimum - dimension of the plotting area. Store AST__BAD to indicate that no - value has been set. This will cause a default of 0.007 to be used. */ - new->minticklen[ axis ] = AST__BAD; - -/* Are numeric labels to be drawn upright? Store a value of -1 to indicate - that no value has yet been set. This will cause a default value of 0 (no) - to be used. */ - new->labelup[ axis ] = -1; - -/* The space between an axis and its numeric labels as a fraction of the - minimum dimension of the plotting area. Store AST__BAD to indicate that no - value has been set. This will cause a default of 0.01 to be used. */ - new->numlabgap[ axis ] = AST__BAD; - new->textlabgap[ axis ] = AST__BAD; - -/* The edges on which to put labels for axes 1 and 2. Store values of -1 - to indicate that no values have been set. This will cause default values - to be used. */ - new->edge[ axis ] = -1; - -/* The placement of labels within the plotting area will be done - automatically by default. */ - new->labelat[ axis ] = AST__BAD; - -/* The central tick is placed automatically by default. */ - new->centre[ axis ] = AST__BAD; - -/* The gap between tick marks and the number of minor tick marks will be - found automatically by default. */ - new->gap[ axis ] = AST__BAD; - new->loggap[ axis ] = AST__BAD; - new->mintick[ axis ] = -1; - -/* Both axes will be labelled by default. */ - new->numlab[ axis ] = -1; - new->textlab[ axis ] = -1; - new->labelunits[ axis ] = -1; - -/* Log/lin attributes. Default value is to use linear axes. */ - new->logplot[ axis ] = -1; - new->logticks[ axis ] = -1; - new->loglabel[ axis ] = -1; - -/* Initialise the components used to store the values actually used - for attributes which have dynamic defaults. */ - new->ulglb[ axis ] = new->loglabel[ axis ]; - new->ulgtk[ axis ] = new->logticks[ axis ]; - new->uloggap[ axis ] = new->loggap[ axis ]; - new->ugap[ axis ] = new->gap[ axis ]; - new->ucentre[ axis ] = new->centre[ axis ]; - new->uedge[ axis ] = new->edge[ axis ]; - new->ulblat[ axis ] = new->labelat[ axis ]; - new->ulbunit[ axis ] = new->labelunits[ axis ]; - new->umintk[ axis ] = new->mintick[ axis ]; - new->utxtlb[ axis ] = new->textlab[ axis ]; - new->umjtkln[ axis ] = new->majticklen[ axis ]; - -/* Initialise the arrays used to hold information describing the tick - marks that have been drawn for the axis. */ - new->majtickgx[ axis ] = NULL; - new->majtickgy[ axis ] = NULL; - new->majtickcount[ axis ] = 0; - new->mintickgx[ axis ] = NULL; - new->mintickgy[ axis ] = NULL; - new->mintickcount[ axis ] = 0; - new->nmajtickval[ axis ] = 0; - new->majtickval[ axis ] = NULL; - new->nmintickval[ axis ] = 0; - new->mintickval[ axis ] = NULL; - } - - new->ugrid = new->grid; - new->ulbling = new->labelling; - new->uborder = new->border; - - } - -/* Annul the frame. */ - graphicsframe = astAnnul( graphicsframe ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - -/* Annul the pointer to the base Frame and FrameSet. */ - baseframe = astAnnul( baseframe ); - fset = astAnnul( fset ); - -/* Return a pointer to the new object. */ - return new; -} - -AstPlot *astLoadPlot_( void *mem, size_t size, - AstPlotVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPlot - -* Purpose: -* Load a Plot. - -* Type: -* Protected function. - -* Synopsis: -* #include "Plot.h" -* AstPlot *astLoadPlot( void *mem, size_t size, -* AstPlotVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* Plot loader. - -* Description: -* This function is provided to load a new Plot using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Plot structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Plot at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the Plot is to be -* loaded. This must be of sufficient size to accommodate the -* Plot data (sizeof(Plot)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Plot (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Plot structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPlot) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Plot. If this is NULL, a pointer -* to the (static) virtual function table for the Plot class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Plot" is used instead. - -* Returned Value: -* A pointer to the new Plot. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPlot *new; /* Pointer to the new Plot */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char *text; /* Textual version of integer value */ - int axis; /* Zero based axis index */ - int id; /* Zero based graphical object id */ - int i; /* Loop count */ - int itick; /* Tick mark index */ - int nax; /* Number of base Frame axes */ - int ntick; /* Total number of ticks */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Plot. In this case the - Plot belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPlot ); - vtab = &class_vtab; - name = "Plot"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPlotVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Plot. */ - new = astLoadFrameSet( mem, size, (AstFrameSetVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Get the number of graphics (base) frame axes - 2 for a Plot, 3 for a - Plot3D. */ - nax = astGetNin( new ); - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Plot" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Tol. */ -/* ---- */ - new->tol = astReadDouble( channel, "tol", -1.0 ); - if ( TestTol( new, status ) ) SetTol( new, new->tol, status ); - -/* Grid. */ -/* ----- */ - new->grid = astReadInt( channel, "grid", -1 ); - if ( TestGrid( new, status ) ) SetGrid( new, new->grid, status ); - -/* TickAll. */ -/* -------- */ - new->tickall = astReadInt( channel, "tckall", -1 ); - if ( TestTickAll( new, status ) ) SetTickAll( new, new->tickall, status ); - -/* ForceExterior. */ -/* -------- */ - new->forceexterior = astReadInt( channel, "frcext", -1 ); - if ( TestForceExterior( new, status ) ) SetForceExterior( new, new->forceexterior, status ); - -/* Invisible. */ -/* ---------- */ - new->invisible = astReadInt( channel, "invsbl", -1 ); - if ( TestInvisible( new, status ) ) SetInvisible( new, new->invisible, status ); - -/* Border. */ -/* -------- */ - new->border = astReadInt( channel, "border", -1 ); - if ( TestBorder( new, status ) ) SetBorder( new, new->border, status ); - -/* ClipOp. */ -/* ------- */ - new->clipop = astReadInt( channel, "clpop", -1 ); - if ( TestClipOp( new, status ) ) SetClipOp( new, new->clipop, status ); - -/* Clip. */ -/* ----- */ - new->clip = astReadInt( channel, "clip", -1 ); - if ( TestClip( new, status ) ) SetClip( new, new->clip, status ); - -/* DrawTitle. */ -/* --------- */ - new->drawtitle = astReadInt( channel, "drwttl", -1 ); - if ( TestDrawTitle( new, status ) ) SetDrawTitle( new, new->drawtitle, status ); - -/* LabelUp(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lblup%d", axis + 1 ); - new->labelup[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLabelUp( new, axis, status ) ) SetLabelUp( new, axis, - new->labelup[ axis ], status ); - } - -/* LogPlot(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lgplt%d", axis + 1 ); - new->logplot[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLogPlot( new, axis, status ) ) SetLogPlot( new, axis, - new->logplot[ axis ], status ); - } - -/* LogTicks(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lgtck%d", axis + 1 ); - new->logticks[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLogTicks( new, axis, status ) ) SetLogTicks( new, axis, - new->logticks[ axis ], status ); - } - -/* LogLabel(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lglbl%d", axis + 1 ); - new->loglabel[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLogLabel( new, axis, status ) ) SetLogLabel( new, axis, - new->loglabel[ axis ], status ); - } - -/* DrawAxes. */ -/* --------- */ - new->drawaxes[ 0 ] = astReadInt( channel, "drwaxs", -1 ); - - if( new->drawaxes[ 0 ] != -1 ) { - new->drawaxes[ 1 ] = new->drawaxes[ 0 ]; - if ( TestDrawAxes( new, 0, status ) ) SetDrawAxes( new, 0, new->drawaxes[ 0 ], status ); - if ( TestDrawAxes( new, 1, status ) ) SetDrawAxes( new, 1, new->drawaxes[ 1 ], status ); - - } else { - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "drwaxs%d", axis + 1 ); - new->drawaxes[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestDrawAxes( new, axis, status ) ) SetDrawAxes( new, axis, - new->drawaxes[ axis ], status ); - } - } - -/* Abbrev. */ -/* ------- */ - new->abbrev[ 0 ] = astReadInt( channel, "abbrv", -1 ); - - if( new->abbrev[ 0 ] != -1 ) { - new->abbrev[ 1 ] = new->abbrev[ 0 ]; - if ( TestAbbrev( new, 0, status ) ) SetAbbrev( new, 0, new->abbrev[ 0 ], status ); - if ( TestAbbrev( new, 1, status ) ) SetAbbrev( new, 1, new->abbrev[ 1 ], status ); - - } else { - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "abbrv%d", axis + 1 ); - new->abbrev[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestAbbrev( new, axis, status ) ) SetAbbrev( new, axis, - new->abbrev[ axis ], status ); - } - } - - -/* Escape. */ -/* ------- */ - new->escape = astReadInt( channel, "escape", -1 ); - if ( TestEscape( new, status ) ) SetEscape( new, new->escape, status ); - -/* LabelAt(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lblat%d", axis + 1 ); - new->labelat[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestLabelAt( new, axis, status ) ) SetLabelAt( new, axis, - new->labelat[ axis ], status ); - } - -/* Centre(axis). */ -/* ------------ */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "cen%d", axis + 1 ); - new->centre[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestCentre( new, axis, status ) ) SetCentre( new, axis, - new->centre[ axis ], status ); - } - -/* Gap(axis). */ -/* ---------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "gap%d", axis + 1 ); - new->gap[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestGap( new, axis, status ) ) SetGap( new, axis, new->gap[ axis ], status ); - } - -/* LogGap(axis). */ -/* ------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lggap%d", axis + 1 ); - new->loggap[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestLogGap( new, axis, status ) ) SetLogGap( new, axis, new->loggap[ axis ], status ); - } - -/* NumLabGap(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "nmgap%d", axis + 1 ); - new->numlabgap[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestNumLabGap( new, axis, status ) ) SetNumLabGap( new, axis, - new->numlabgap[ axis ], status ); - } - -/* TextLabGap(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "txgap%d", axis + 1 ); - new->textlabgap[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestTextLabGap( new, axis, status ) ) SetTextLabGap( new, axis, - new->textlabgap[ axis ], status ); - } - -/* NumLab(axis). */ -/* ---------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "nmlbl%d", axis + 1 ); - new->numlab[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestNumLab( new, axis, status ) ) SetNumLab( new, axis, - new->numlab[ axis ], status ); - } - -/* MinTick(axis). */ -/* --------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "mntks%d", axis + 1 ); - new->mintick[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestMinTick( new, axis, status ) ) SetMinTick( new, axis, - new->mintick[ axis ], status ); - } - -/* TextLab(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "txlbl%d", axis + 1 ); - new->textlab[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestTextLab( new, axis, status ) ) SetTextLab( new, axis, - new->textlab[ axis ], status ); - } - -/* LabelUnits(axis). */ -/* --------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lbunt%d", axis + 1 ); - new->labelunits[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLabelUnits( new, axis, status ) ) SetLabelUnits( new, axis, - new->labelunits[ axis ], status ); - } - -/* Style(object). */ -/* ------------ */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "style%d", id + 1 ); - new->style[ id ] = astReadInt( channel, buff, -1 ); - if ( TestStyle( new, id, status ) ) SetStyle( new, id, new->style[ id ], status ); - } - -/* Font(object). */ -/* ----------- */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "font%d", id + 1 ); - new->font[ id ] = astReadInt( channel, buff, -1 ); - if ( TestFont( new, id, status ) ) SetFont( new, id, new->font[ id ], status ); - } - -/* Colour(object). */ -/* --------------- */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "col%d", id + 1 ); - new->colour[ id ] = astReadInt( channel, buff, -1 ); - if ( TestColour( new, id, status ) ) SetColour( new, id, new->colour[ id ], status ); - } - -/* Width(object). */ -/* ------------ */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "width%d", id + 1 ); - new->width[ id ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestWidth( new, id, status ) ) SetWidth( new, id, new->width[ id ], status ); - } - -/* Size(object). */ -/* ----------- */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "size%d", id + 1 ); - new->size[ id ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestSize( new, id, status ) ) SetSize( new, id, new->size[ id ], status ); - } - -/* TitleGap. */ -/* --------- */ - new->titlegap = astReadDouble( channel, "ttlgap", AST__BAD ); - if ( TestTitleGap( new, status ) ) SetTitleGap( new, new->titlegap, status ); - -/* MajTickLen. */ -/* ----------- */ -/* Retained in order to read old Plots - new Plots use MajTickLen(axis). */ - new->majticklen[ 0 ] = astReadDouble( channel, "mjtkln", AST__BAD ); - if( new->majticklen[ 0 ] != AST__BAD ) { - new->majticklen[ 1 ] = new->majticklen[ 0 ]; - if ( TestMajTickLen( new, 0, status ) ) SetMajTickLen( new, 0, new->majticklen[ 0 ], status ); - if ( TestMajTickLen( new, 1, status ) ) SetMajTickLen( new, 1, new->majticklen[ 1 ], status ); - -/* MajTickLen(axis). */ -/* ----------------- */ - } else { - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "mjtkln%d", axis + 1 ); - new->majticklen[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestMajTickLen( new, axis, status ) ) SetMajTickLen( new, axis, - new->majticklen[ axis ], status ); - } - } - -/* MinTickLen. */ -/* ----------- */ -/* Retained in order to read old Plots - new Plots use MinTickLen(axis). */ - new->minticklen[ 0 ] = astReadDouble( channel, "mntkln", AST__BAD ); - if( new->minticklen[ 0 ] != AST__BAD ) { - new->minticklen[ 1 ] = new->minticklen[ 0 ]; - if ( TestMinTickLen( new, 0, status ) ) SetMinTickLen( new, 0, new->minticklen[ 0 ], status ); - if ( TestMinTickLen( new, 1, status ) ) SetMinTickLen( new, 1, new->minticklen[ 1 ], status ); - -/* MinTickLen(axis). */ -/* ----------------- */ - } else { - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "mntkln%d", axis + 1 ); - new->minticklen[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestMinTickLen( new, axis, status ) ) SetMinTickLen( new, axis, - new->minticklen[ axis ], status ); - } - } - -/* Labelling. */ -/* ---------- */ - text = astReadString( channel, "lbling", " " ); - if( astOK && strcmp( text, " " ) ) { - new->labelling = FindString( 2, xlbling, text, - "the Plot component 'Lbling'", - "astRead", astGetClass( channel ), status ); - } else { - new->labelling = -9999; - } - if ( TestLabelling( new, status ) ) SetLabelling( new, new->labelling, status ); - text = astFree( text ); - -/* Edge(axis). */ -/* ----------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "edge%d", axis + 1 ); - text = astReadString( channel, buff, " " ); - if( astOK && strcmp( text, " " ) ) { - new->edge[ axis ] = FindString( 4, xedge, text, - "the Plot component 'Edge'", - "astRead", astGetClass( channel ), status ); - } else { - new->edge[ axis ] = -1; - } - if ( TestEdge( new, axis, status ) ) SetEdge( new, axis, - new->edge[ axis ], status ); - text = astFree( text ); - } - -/* Now do instance variables which are not attributes. */ -/* =================================================== */ - -/* We have no graphics context. */ - new->grfcontext = NULL; - new->grfcontextID = NULL; - -/* Initialise the protected Ink attribute so that visible ink is used. */ - new->ink = -1; - -/* The number of bounds supplied for the clipping volume. */ - new->clip_axes = astReadInt( channel, "clpaxs", 0 ); - if ( new->clip_axes < 0 ) new->clip_axes = 0; - -/* The index of the clipping Frame within the Plot. */ - new->clip_frame = astReadInt( channel, "clpfrm", AST__NOFRAME ); - -/* If necessary, allocate memory to hold the bounds of the clipping volume. */ - if( new->clip_axes > 0 ){ - new->clip_lbnd = astMalloc( sizeof( double ) * (size_t) new->clip_axes ); - new->clip_ubnd = astMalloc( sizeof( double ) * (size_t) new->clip_axes ); - -/* If an error occurs, ensure that all allocated memory is freed. */ - if ( !astOK ) { - new->clip_lbnd = (double *) astFree( (void *) new->clip_lbnd ); - new->clip_ubnd = (double *) astFree( (void *) new->clip_ubnd ); - -/* Otherwise, store the bounds. Use extreme defaults if no values are - available. */ - } else { - for( axis = 0; axis < new->clip_axes; axis++ ){ - (void) sprintf( buff, "clplb%d", axis + 1 ); - new->clip_lbnd[ axis ] = astReadDouble( channel, buff, -DBL_MAX ); - - (void) sprintf( buff, "clpub%d", axis + 1 ); - new->clip_ubnd[ axis ] = astReadDouble( channel, buff, DBL_MAX ); - } - } - -/* If there are no clipping axes, store NULL pointers for the bounds - arrays. */ - } else { - new->clip_lbnd = NULL; - new->clip_ubnd = NULL; - } - -/* The bounds of the plotting area in graphics coords. */ - new->xlo = astReadDouble( channel, "xlo", 0.0 ); - new->xhi = astReadDouble( channel, "xhi", 1.0 ); - new->ylo = astReadDouble( channel, "ylo", 0.0 ); - new->yhi = astReadDouble( channel, "yhi", 1.0 ); - -/* Axis reversal flags. */ - new->xrev = astReadInt( channel, "xrev", 0 ); - new->yrev = astReadInt( channel, "yrev", 0 ); - -/* The bounds of the plotting area in the base Frame of the FrameSet - supplied when the Plot was constructed. */ - new->bbox[ 0 ] = astReadDouble( channel, "xb1", AST__BAD ); - new->bbox[ 1 ] = astReadDouble( channel, "yb1", AST__BAD ); - new->bbox[ 2 ] = astReadDouble( channel, "xb2", AST__BAD ); - new->bbox[ 3 ] = astReadDouble( channel, "yb2", AST__BAD ); - -/* Grf. */ - new->grf = -1; - new->GAttr = CGAttrWrapper; - new->GBBuf = CGBBufWrapper; - new->GEBuf = CGEBufWrapper; - new->GFlush = CGFlushWrapper; - new->GLine = CGLineWrapper; - new->GMark = CGMarkWrapper; - new->GText = CGTextWrapper; - new->GCap = CGCapWrapper; - new->GTxExt = CGTxExtWrapper; - new->GScales = CGScalesWrapper; - new->GQch = CGQchWrapper; - for( i = 0; i < AST__NGRFFUN; i++ ) new->grffun[i] = NULL; - new->grfstack = NULL; - new->grfnstack = 0; - -/* A stack of AstGat pointers used to store the graphical attributes for - text within strings which include graphical escape sequences. */ - new->gat = NULL; - new->ngat = 0; - -/* Arrays holding user-specified major and minot tick mark values. */ - for( axis = 0; axis < 3; axis++ ) { - sprintf( buff, "nmjtk%d", axis + 1 ); - ntick = astReadInt( channel, buff, 0 ); - new->nmajtickval[ axis ] = ntick; - new->majtickval[ axis ] = astMalloc( ntick*sizeof( double ) ); - - for( itick = 0; itick < ntick; itick++ ) { - sprintf( buff, "mjtk%d_%d", axis + 1, itick + 1 ); - new->majtickval[ axis ][ itick ] = astReadDouble( channel, buff, - AST__BAD ); - } - - sprintf( buff, "nmntk%d", axis + 1 ); - ntick = astReadInt( channel, buff, 0 ); - new->nmintickval[ axis ] = ntick; - new->mintickval[ axis ] = astMalloc( ntick*sizeof( double ) ); - - for( itick = 0; itick < ntick; itick++ ) { - sprintf( buff, "mntk%d_%d", axis + 1, itick + 1 ); - new->mintickval[ axis ][ itick ] = astReadDouble( channel, buff, - AST__BAD ); - } - - } - -/* Initialise the arrays used to hold information describing the tick - marks that have already been drawn for each axis. */ - for( axis = 0; axis < 3; axis++ ) { - new->majtickgx[ axis ] = NULL; - new->majtickgy[ axis ] = NULL; - new->majtickcount[ axis ] = 0; - new->mintickgx[ axis ] = NULL; - new->mintickgy[ axis ] = NULL; - new->mintickcount[ axis ] = 0; - } - -/* If an error occurred, clean up by deleting the new Plot. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Plot pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astBBuf_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,BBuf))(this, status ); -} - -int astBorder_( AstPlot *this, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,Plot,Border))(this, status ); -} - -void astBoundingBox_( AstPlot *this, float lbnd[2], float ubnd[2], int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,BoundingBox))(this,lbnd,ubnd, status ); -} - -void astClip_( AstPlot *this, int iframe, const double lbnd[], -const double ubnd[], int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,Clip))(this,iframe,lbnd,ubnd, status ); -} - -void astGrid_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,Grid))(this, status ); -} - -int astCvBrk_( AstPlot *this, int ibrk, double *brk, double *vbrk, - double *len, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,Plot,CvBrk))(this,ibrk,brk,vbrk,len, status ); -} - -void astEBuf_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,EBuf))(this, status ); -} - -void astMirror_( AstPlot *this, int axis, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,Mirror))(this,axis, status ); -} - -AstPointSet *astGetDrawnTicks_( AstPlot *this, int axis, int major, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,Plot,GetDrawnTicks))(this,axis,major, status ); -} - -void astSetTickValues_( AstPlot *this, int axis, int nmajor, double *major, - int nminor, double *minor, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,SetTickValues))(this,axis,nmajor,major,nminor,minor, status ); -} - -void astCopyPlotDefaults_( AstPlot *this, int axis, AstPlot *dplot, - int daxis, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,CopyPlotDefaults))(this,axis,dplot,daxis, status ); -} - -int astGetLabelUnits_( AstPlot *this, int axis, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,Plot,GetLabelUnits))(this,axis, status ); -} - -void astMark_( AstPlot *this, int nmark, int ncoord, int indim, - const double *in, int type, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Plot,Mark))( this, nmark, ncoord, indim, in, type, status ); -} - -void astText_( AstPlot *this, const char *text, const double pos[], - const float up[], const char *just, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Plot,Text))( this, text, pos, up, just, status ); -} - -void astGridLine_( AstPlot *this, int axis, const double start[], double length, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GridLine))(this,axis,start,length, status ); -} - -void astCurve_( AstPlot *this, const double start[], const double finish[], int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,Curve))(this,start,finish, status ); -} - -void astGenCurve_( AstPlot *this, AstMapping *map, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GenCurve))(this,map, status ); -} - -void astPolyCurve_( AstPlot *this, int npoint, int ncoord, int dim, - const double *in, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,PolyCurve))(this,npoint,ncoord,dim,in, status ); -} - -void astRegionOutline_( AstPlot *this, AstRegion *region, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,RegionOutline))(this,region,status); -} - -void astGrfSet_( AstPlot *this, const char *name, AstGrfFun fun, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GrfSet))(this,name,fun, status ); -} - -void astGrfPush_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GrfPush))(this, status ); -} - -void astGrfPop_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GrfPop))(this, status ); -} - -void astGrfWrapper_( AstPlot *this, const char *name, AstGrfWrap wrapper, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GrfWrapper))(this,name,wrapper, status ); -} - -void astSetLogPlot_( AstPlot *this, int axis, int value, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Plot,SetLogPlot))( this, axis, value, status ); -} - -void astClearLogPlot_( AstPlot *this, int axis, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Plot,ClearLogPlot))( this, axis, status ); -} - -AstKeyMap *astGetGrfContext_( AstPlot *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Plot,GetGrfContext))( this, status ); -} - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstPlot *astPlotId_( void *frame_void, const float graphbox[4], - const double basebox[4], const char *options, ... ) { -/* -*++ -* Name: -c astPlot -f AST_PLOT - -* Purpose: -* Create a Plot. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c AstPlot *astPlot( AstFrame *frame, const float graphbox[ 4 ], -c const double basebox[ 4 ], const char *options, ... ) -f RESULT = AST_PLOT( FRAME, GRAPHBOX, BASEBOX, OPTIONS, STATUS ) - -* Class Membership: -* Plot constructor. - -* Description: -* This function creates a new Plot and optionally initialises its -* attributes. -* -* A Plot is a specialised form of FrameSet, in which the base -* Frame describes a "graphical" coordinate system and is -* associated with a rectangular plotting area in the underlying -* graphics system. This plotting area is where graphical output -* appears. It is defined when the Plot is created. -* -* The current Frame of a Plot describes a "physical" coordinate -* system, which is the coordinate system in which plotting -* operations are specified. The results of each plotting operation -* are automatically transformed into graphical coordinates so as -* to appear in the plotting area (subject to any clipping which -* may be in effect). -* -* Because the Mapping between physical and graphical coordinates -* may often be non-linear, or even discontinuous, most plotting -* does not result in simple straight lines. The basic plotting -* element is therefore not a straight line, but a geodesic curve -c (see astCurve). A Plot also provides facilities for drawing -c markers or symbols (astMark), text (astText) and grid lines -c (astGridLine). It is also possible to draw curvilinear axes with -c optional coordinate grids (astGrid). -f (see AST_CURVE). A Plot also provides facilities for drawing -f markers or symbols (AST_MARK), text (AST_TEXT) and grid lines -f (AST_GRIDLINE). It is also possible to draw curvilinear axes -f with optional coordinate grids (AST_GRID). -* A range of Plot attributes is available to allow precise control -* over the appearance of graphical output produced by these -c functions. -f routines. -* -* You may select different physical coordinate systems in which to -* plot (including the native graphical coordinate system itself) -* by selecting different Frames as the current Frame of a Plot, -* using its Current attribute. You may also set up clipping (see -c astClip) to limit the extent of any plotting you perform, and -f AST_CLIP) to limit the extent of any plotting you perform, and -* this may be done in any of the coordinate systems associated -* with the Plot, not necessarily the one you are plotting in. -* -* Like any FrameSet, a Plot may also be used as a Frame. In this -* case, it behaves like its current Frame, which describes the -* physical coordinate system. -* -* When used as a Mapping, a Plot describes the inter-relation -* between graphical coordinates (its base Frame) and physical -* coordinates (its current Frame). It differs from a normal -* FrameSet, however, in that an attempt to transform points which -* lie in clipped areas of the Plot will result in bad coordinate -* values (AST__BAD). - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* Pointer to a Frame describing the physical coordinate system -* in which to plot. A pointer to a FrameSet may also be given, -* in which case its current Frame will be used to define the -* physical coordinate system and its base Frame will be mapped -* on to graphical coordinates (see below). -* -* If a null Object pointer (AST__NULL) is given, a default -* 2-dimensional Frame will be used to describe the physical -* coordinate system. Labels, etc. may then be attached to this -* by setting the appropriate Frame attributes -* (e.g. Label(axis)) for the Plot. -c graphbox -f GRAPHBOX( 4 ) = REAL (Given) -* An array giving the position and extent of the plotting area -* (on the plotting surface of the underlying graphics system) -* in which graphical output is to appear. This must be -* specified using graphical coordinates appropriate to the -* underlying graphics system. -* -* The first pair of values should give the coordinates of the -* bottom left corner of the plotting area and the second pair -* should give the coordinates of the top right corner. The -* coordinate on the horizontal axis should be given first in -* each pair. Note that the order in which these points are -* given is important because it defines up, down, left and -* right for subsequent graphical operations. -c basebox -f BASEBOX( 4 ) = DOUBLE PRECISION (Given) -* An array giving the coordinates of two points in the supplied -* Frame (or in the base Frame if a FrameSet was supplied) which -* correspond to the bottom left and top right corners of the -* plotting area, as specified above. This range of coordinates -* will be mapped linearly on to the plotting area. The -* coordinates should be given in the same order as above. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Plot. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Plot. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPlot() -f AST_PLOT -* A pointer to the new Plot. - -* Notes: -* - The base Frame of the returned Plot will be a new Frame which -* is created by this function to represent the coordinate system -* of the underlying graphics system (graphical coordinates). It is -* given a Frame index of 1 within the Plot. The choice of base -* Frame (Base attribute) should not, in general, be changed once a -* Plot has been created (although you could use this as a way of -* moving the plotting area around on the plotting surface). -c - If a Frame is supplied (via the "frame" pointer), then it -f - If a Frame is supplied (via the FRAME pointer), then it -* becomes the current Frame of the new Plot and is given a Frame -* index of 2. -c - If a FrameSet is supplied (via the "frame" pointer), then -f - If a FrameSet is supplied (via the FRAME pointer), then -* all the Frames within this FrameSet become part of the new Plot -* (where their Frame indices are increased by 1), with the -* FrameSet's current Frame becoming the current Frame of the Plot. -* - If a null Object pointer (AST__NULL) is supplied (via the -c "frame" pointer), then the returned Plot will contain two -f FRAME pointer), then the returned Plot will contain two -* Frames, both created by this function. The base Frame will -* describe graphics coordinates (as above) and the current Frame -* will be a basic Frame with no attributes set (this will -* therefore give default values for such things as the Plot Title -* and the Label on each axis). Physical coordinates will be mapped -* linearly on to graphical coordinates. -* - An error will result if the Frame supplied (or the base Frame -* if a FrameSet was supplied) is not 2-dimensional. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astPlot constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astPlot_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "frame" parameter is of type -* (void *) and is converted from an ID value to a pointer and -* validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astPlot_ directly, so it must be a -* re-implementation of it in all respects, except for the -* conversions between IDs and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPlot *new; /* Pointer to new Plot */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get apointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - new = NULL; - -/* Obtain a Frame pointer from any ID supplied and validate the - pointer to ensure it identifies a valid Frame. */ - if( frame_void ){ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - } else { - frame = NULL; - } - -/* Check the pointer can be used. */ - if ( astOK ) { - -/* Initialise the Plot, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPlot( NULL, sizeof( AstPlot ), !class_init, - &class_vtab, "Plot", frame, graphbox, - basebox ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - Plot's attributes. */ - - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new Plot. */ - return astMakeId( new ); - -} - - - - diff --git a/ast/plot.f b/ast/plot.f deleted file mode 100644 index 27e83b4..0000000 --- a/ast/plot.f +++ /dev/null @@ -1,71 +0,0 @@ - CHARACTER * ( * ) FUNCTION AST_STRIPESCAPES( THIS, ATTRIB ) -*+ -* Name: -* AST_STRIPESCAPES - -* Purpose: -* Wrap up the C AST_STRIPESCAPES_A function. - -* Language: -* Fortran 77 - -* Invocation: -* RESULT = AST_STRIPESCAPES( THIS, ATTRIB ) - -* Description: -* This function is a wrap-up of the C ast_stripescapes_a function. It -* will rarely need to be used, but is provided for use on platforms -* where the normal mechanism for returning character strings as -* function results from C to Fortran (as defined in the f77.h -* include file) doesn't work. -* -* If this problem is encountered, the C macro NO_CHAR_FUNCTION -* should be defined (in CFLAGS) during C compilation. This will -* cause the function ast_stripescapes_a to be built (instead of -* ast_stripescapes) and this returns its the result via an additional -* initial argument. This Fortran function is then used simply to -* transfer the argument value to the function result. - -* Arguments: -* As for the C version of the Fortran-callable function ast_stripescapes. - -* Returned Value: -* AST_STRIPESCAPES = CHARACTER * ( * ) -* The character return value required. - -* Notes: -* - The length of the returned result is limited to 300 characters -* by a local buffer. This length can be increased if necessary. - -* Authors: -* DSB: David S Berry (JAC) -* {enter_new_authors_here} - -* History: -* 10-JUL-2006 (DSB): -* Original version. -* {enter_changes_here} - -* Bugs: -* {note_any_bugs_here} - -*- - -* Type Definitions: - IMPLICIT NONE ! No implicit typing - -* Arguments Given: - INTEGER THIS - CHARACTER * ( * ) ATTRIB - -* Local Variables: - CHARACTER * ( 300 ) BUFF ! Local buffer for result -*. - -* Invoke the C function (with the additional argument). - CALL AST_STRIPESCAPES_A( BUFF, THIS, ATTRIB ) - -* Return the argument value as the function result. - AST_STRIPESCAPES = BUFF - - END diff --git a/ast/plot.h b/ast/plot.h deleted file mode 100644 index 6f702ab..0000000 --- a/ast/plot.h +++ /dev/null @@ -1,1417 +0,0 @@ -#if !defined( PLOT_INCLUDED ) /* Include this file only once */ -#define PLOT_INCLUDED -/* -*+ -* Name: -* plot.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Plot class. - -* Invocation: -* #include "plot.h" - -* Description: -* This include file defines the interface to the Plot class and -* provides the type definitions, function prototypes and macros, etc. -* needed to use this class. -* -* The Plot class provides facilities for producing graphical information -* describing positions within coordinate systems. These include the -* creation of annotated coordinate axes, the plotting of markers at given -* physical positions, etc. - -* Inheritance: -* The Plot class inherits from the FrameSet class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 18-SEP-1996 (DSB): -* Original version. -* 28-OCT-1998 (DSB): -* Added method astPolyCurve. -* 12-OCT-1999 (DSB): -* Allow tick marks to be specified separately for both axes. -* 9-JAN-2001 (DSB): -* Change argument "in" for astMark and astPolyCurve from type -* "const double (*)[]" to "const double *". -* 13-JUN-2001 (DSB): -* Added methods astGenCurve, astGrfSet, astGrfPop, astGrfPush and -* attribute Grf. -* 8-JAN-2003 (DSB): -* Added protected astInitPlotVtab method. -* 13-JAN-2004 (DSB): -* Added bbox, logticks and logplot to the AstPlot structure. Added -* LogPlot and LogTicks accessor methods. -* 19-JAN-2004 (DSB): -* Added loggap and loglabel to the AstPlot structure. Added -* LogGap and LogLabel accessor methods. -* 21-MAR-2005 (DSB): -* - Added the Clip attribute. -* 24-OCT-2006 (DSB): -* - Remove duplicated documentation from prologue. -* - Add ForceExterior attribute. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "frameset.h" /* Parent FrameSet class */ -#include "keymap.h" -#include "region.h" - -#if defined(astCLASS) /* Protected */ -#include "grf.h" -#endif - -/* C header files. */ -/* --------------- */ -#include - -/* Macros. */ -/* ======= */ - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif -#define AST__NPID 20 /* No. of different genuine plot object id's */ - -#define AST__GATTR 0 /* Identifiers for GRF functions */ -#define AST__GFLUSH 1 /* Note, if any items are added or changed here, */ -#define AST__GLINE 2 /* make sure that the astGrfFunID function is */ -#define AST__GMARK 3 /* updated in plot.c */ -#define AST__GTEXT 4 -#define AST__GTXEXT 5 -#define AST__GSCALES 6 -#define AST__GQCH 7 -#define AST__GCAP 8 -#define AST__GBBUF 9 -#define AST__GEBUF 10 - -#define AST__NGRFFUN 11 /* No. of Grf functions used by Plot */ - -#if defined(astCLASS) /* Protected */ -#define AST__MXBRK 100 /* Max. no. of breaks in a drawn curve */ - -/* Identifiers for the graphical elements of an annotated coord grid. - "Pseudo-elements" (i.e. values used to indicate a group of other - genuine elements) should come at the end of the list. The number of - genuine elements should be stored in AST__NPID. */ -#define AST__BORDER_ID 0 /* Id for astBorder curves */ -#define AST__CURVE_ID 1 /* Id for astCurve, astGenCurve or astPolyCurve curves */ -#define AST__TITLE_ID 2 /* Id for textual title */ -#define AST__MARKS_ID 3 /* Id for marks drawn by astMark */ -#define AST__TEXT_ID 4 /* Id for text strings drawn by astText */ -#define AST__AXIS1_ID 5 /* Id for axis 1 through interior tick marks */ -#define AST__AXIS2_ID 6 /* Id for axis 2 through interior tick marks */ -#define AST__AXIS3_ID 7 /* Id for axis 2 through interior tick marks */ -#define AST__NUMLAB1_ID 8 /* Id for numerical labels */ -#define AST__NUMLAB2_ID 9 /* Id for numerical labels */ -#define AST__NUMLAB3_ID 10 /* Id for numerical labels */ -#define AST__TEXTLAB1_ID 11 /* Id for textual axis labels */ -#define AST__TEXTLAB2_ID 12 /* Id for textual axis labels */ -#define AST__TEXTLAB3_ID 13 /* Id for textual axis labels */ -#define AST__TICKS1_ID 14 /* Id for major and minor tick marks */ -#define AST__TICKS2_ID 15 /* Id for major and minor tick marks */ -#define AST__TICKS3_ID 16 /* Id for major and minor tick marks */ -#define AST__GRIDLINE1_ID 17 /* Id for axis 1 astGridLine AST__curves */ -#define AST__GRIDLINE2_ID 18 /* Id for axis 2 astGridLine AST__curves */ -#define AST__GRIDLINE3_ID 19 /* Id for axis 2 astGridLine AST__curves */ -#define AST__AXES_ID 20 /* Id for axes through interior tick marks */ -#define AST__NUMLABS_ID 21 /* Id for numerical labels */ -#define AST__TEXTLABS_ID 22 /* Id for textual axis labels */ -#define AST__GRIDLINE_ID 23 /* Id for astGridLine AST__curves */ -#define AST__TICKS_ID 24 /* Id for major and minor tick marks */ - -/* Define constants used to size global arrays in this module. */ -#define AST__PLOT_CRV_MXBRK 1000 /* Max. no. of breaks allowed in a plotted curve */ -#define AST__PLOT_STRIPESCAPES_BUFF_LEN 50 /* Length of string returned by astStripEscapes */ - -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions */ -/* ================ */ - -/* Pre-declare the AstPlot structure so that it can be used within the - GRF function typedefs. */ -struct AstPlot; - -/* Interfaces for GRF functions */ -/* ---------------------------- */ -/* A general interface into which actual Grf functions should be cast - before being passed as an argument to astGrfSet. */ -typedef void (* AstGrfFun)( void ); - -/* Interfaces for specific Grf funstions implemented in C (other languages - may have different interfaces). */ -typedef int (* AstGAttrFun)( AstKeyMap *, int, double, double *, int ); -typedef int (* AstGFlushFun)( AstKeyMap * ); -typedef int (* AstGBBufFun)( AstKeyMap * ); -typedef int (* AstGEBufFun)( AstKeyMap * ); -typedef int (* AstGLineFun)( AstKeyMap *, int, const float *, const float * ); -typedef int (* AstGMarkFun)( AstKeyMap *, int, const float *, const float *, int ); -typedef int (* AstGTextFun)( AstKeyMap *, const char *, float, float, const char *, float, float ); -typedef int (* AstGCapFun)( AstKeyMap *, int, int ); -typedef int (* AstGTxExtFun)( AstKeyMap *, const char *, float, float, const char *, float, float, float *, float * ); -typedef int (* AstGScalesFun)( AstKeyMap *, float *, float * ); -typedef int (* AstGQchFun)( AstKeyMap *, float *, float * ); - -/* A general interface into which Grf Wrapper functions should be cast - before being passed as an argument to astGrfWrapper. */ -typedef void (* AstGrfWrap)( void ); - -/* Interfaces for the wrapper functions which wrap specific Grf funstions. */ -typedef int (* AstGAttrWrap)( struct AstPlot *, int, double, double *, int, int * ); -typedef int (* AstGBBufWrap)( struct AstPlot *, int * ); -typedef int (* AstGEBufWrap)( struct AstPlot *, int * ); -typedef int (* AstGFlushWrap)( struct AstPlot *, int * ); -typedef int (* AstGLineWrap)( struct AstPlot *, int, const float *, const float *, int * ); -typedef int (* AstGMarkWrap)( struct AstPlot *, int, const float *, const float *, int, int * ); -typedef int (* AstGTextWrap)( struct AstPlot *, const char *, float, float, const char *, float, float, int * ); -typedef int (* AstGCapWrap)( struct AstPlot *, int, int, int * ); -typedef int (* AstGTxExtWrap)( struct AstPlot *, const char *, float, float, const char *, float, float, float *, float *, int * ); -typedef int (* AstGScalesWrap)( struct AstPlot *, float *, float *, int * ); -typedef int (* AstGQchWrap)( struct AstPlot *, float *, float *, int * ); - -/* A structure in which a collection of Grf function pointers can be - stored. */ -typedef struct AstGrfPtrs { - AstGrfFun grffun[AST__NGRFFUN]; - AstGAttrWrap GAttr; - AstGBBufWrap GBBuf; - AstGEBufWrap GEBuf; - AstGFlushWrap GFlush; - AstGLineWrap GLine; - AstGMarkWrap GMark; - AstGTextWrap GText; - AstGCapWrap GCap; - AstGTxExtWrap GTxExt; - AstGScalesWrap GScales; - AstGQchWrap GQch; -} AstGrfPtrs; - -/* Structure holding current graphical attribute values for text. */ -typedef struct AstGat { - float rise; - double size; - double width; - double col; - double font; - double style; -} AstGat; - -/* Plot structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstPlot { - -/* Attributes inherited from the parent class. */ - AstFrameSet parent; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *clip_lbnd; - double *clip_ubnd; - double centre[ 3 ]; - double gap[ 3 ]; - double loggap[ 3 ]; - double labelat[ 3 ]; - double majticklen[ 3 ]; - double minticklen[ 3 ]; - double numlabgap[ 3 ]; - double size[ AST__NPID ]; - double textlabgap[ 3 ]; - double titlegap; - double tol; - double ucentre[ 3 ]; - double ugap[ 3 ]; - double uloggap[ 3 ]; - double ulblat[ 3 ]; - double umjtkln[ 3 ]; - double width[ AST__NPID ]; - double *majtickgx[ 3 ]; - double *majtickgy[ 3 ]; - double *mintickgx[ 3 ]; - double *mintickgy[ 3 ]; - int majtickcount[ 3 ]; - int mintickcount[ 3 ]; - int nmajtickval[ 3 ]; - double *majtickval[ 3 ]; - int nmintickval[ 3 ]; - double *mintickval[ 3 ]; - double xhi; - double xlo; - double yhi; - double ylo; - double bbox[ 4 ]; - int border; - int clip_axes; - int clip_frame; - int clip; - int clipop; - int colour[ AST__NPID ]; - int drawaxes[ 3 ]; - int abbrev[ 3 ]; - int escape; - int drawtitle; - int edge[ 3 ]; - int font[ AST__NPID ]; - int grf; - int grid; - int invisible; - int labelling; - int labelunits[ 3 ]; - int labelup[ 3 ]; - int mintick[ 3 ]; - int numlab[ 3 ]; - int style[ AST__NPID ]; - int textlab[ 3 ]; - int tickall; - int forceexterior; - int uborder; - int uedge[ 3 ]; - int ugrid; - int ulbling; - int ulbunit[ 3 ]; - int ulgtk[ 3 ]; - int ulglb[ 3 ]; - int umintk[ 3 ]; - int utxtlb[ 3 ]; - int xrev; - int yrev; - int ink; - int logplot[ 3 ]; - int logticks[ 3 ]; - int loglabel[ 3 ]; - AstGrfFun grffun[AST__NGRFFUN]; - AstGAttrWrap GAttr; - AstGBBufWrap GBBuf; - AstGEBufWrap GEBuf; - AstGFlushWrap GFlush; - AstGLineWrap GLine; - AstGMarkWrap GMark; - AstGTextWrap GText; - AstGCapWrap GCap; - AstGTxExtWrap GTxExt; - AstGScalesWrap GScales; - AstGQchWrap GQch; - AstGrfPtrs *grfstack; - int grfnstack; - AstGat **gat; - int ngat; - AstKeyMap *grfcontext; - AstKeyMap *grfcontextID; - float hmarkx; - float hmarky; - -} AstPlot; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ - -typedef struct AstPlotVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstFrameSetVtab FrameSet_vtab;/* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstKeyMap *(* GetGrfContext)( AstPlot *, int * ); - AstPointSet *(* GetDrawnTicks)( AstPlot *, int, int, int * ); - int (* Border)( AstPlot *, int * ); - int (* CvBrk)( AstPlot *, int, double *, double *, double *, int * ); - void (* BBuf)( AstPlot *, int * ); - void (* BoundingBox)( AstPlot *, float[2], float[2], int * ); - void (* Clip)( AstPlot *, int, const double [], const double [], int * ); - void (* CopyPlotDefaults)( AstPlot *, int, AstPlot *, int, int * ); - void (* Curve)( AstPlot *, const double [], const double [], int * ); - void (* DrawExtraTicks)( AstPlot *, int, AstPointSet *, int * ); - void (* EBuf)( AstPlot *, int * ); - void (* GenCurve)( AstPlot *, AstMapping *, int * ); - void (* GrfPop)( AstPlot *, int * ); - void (* GrfPush)( AstPlot *, int * ); - void (* GrfSet)( AstPlot *, const char *, AstGrfFun, int * ); - void (* GrfWrapper)( AstPlot *, const char *, AstGrfWrap, int * ); - void (* Grid)( AstPlot *, int * ); - void (* GridLine)( AstPlot *, int, const double [], double, int * ); - void (* Mark)( AstPlot *, int, int, int, const double *, int, int * ); - void (* Mirror)( AstPlot *, int, int * ); - void (* PolyCurve)( AstPlot *, int, int, int, const double *, int * ); - void (* RegionOutline)( AstPlot *, AstRegion *, int * ); - void (* SetTickValues)( AstPlot *, int, int, double *, int, double *, int * ); - void (* Text)( AstPlot *, const char *, const double [], const float [], const char *, int * ); - - double (* GetTol)( AstPlot *, int * ); - int (* TestTol)( AstPlot *, int * ); - void (* SetTol)( AstPlot *, double, int * ); - void (* ClearTol)( AstPlot *, int * ); - - int (* GetGrid)( AstPlot *, int * ); - int (* TestGrid)( AstPlot *, int * ); - void (* SetGrid)( AstPlot *, int, int * ); - void (* ClearGrid)( AstPlot *, int * ); - - int (* GetTickAll)( AstPlot *, int * ); - int (* TestTickAll)( AstPlot *, int * ); - void (* SetTickAll)( AstPlot *, int, int * ); - void (* ClearTickAll)( AstPlot *, int * ); - - int (* GetForceExterior)( AstPlot *, int * ); - int (* TestForceExterior)( AstPlot *, int * ); - void (* SetForceExterior)( AstPlot *, int, int * ); - void (* ClearForceExterior)( AstPlot *, int * ); - - int (* GetInvisible)( AstPlot *, int * ); - int (* TestInvisible)( AstPlot *, int * ); - void (* SetInvisible)( AstPlot *, int, int * ); - void (* ClearInvisible)( AstPlot *, int * ); - - int (* GetBorder)( AstPlot *, int * ); - int (* TestBorder)( AstPlot *, int * ); - void (* SetBorder)( AstPlot *, int, int * ); - void (* ClearBorder)( AstPlot *, int * ); - - int (* GetClipOp)( AstPlot *, int * ); - int (* TestClipOp)( AstPlot *, int * ); - void (* SetClipOp)( AstPlot *, int, int * ); - void (* ClearClipOp)( AstPlot *, int * ); - - int (* GetClip)( AstPlot *, int * ); - int (* TestClip)( AstPlot *, int * ); - void (* SetClip)( AstPlot *, int, int * ); - void (* ClearClip)( AstPlot *, int * ); - - int (* GetGrf)( AstPlot *, int * ); - int (* TestGrf)( AstPlot *, int * ); - void (* SetGrf)( AstPlot *, int, int * ); - void (* ClearGrf)( AstPlot *, int * ); - - int (* GetDrawTitle)( AstPlot *, int * ); - int (* TestDrawTitle)( AstPlot *, int * ); - void (* SetDrawTitle)( AstPlot *, int, int * ); - void (* ClearDrawTitle)( AstPlot *, int * ); - - int (* GetLabelUp)( AstPlot *, int, int * ); - int (* TestLabelUp)( AstPlot *, int, int * ); - void (* SetLabelUp)( AstPlot *, int, int, int * ); - void (* ClearLabelUp)( AstPlot *, int, int * ); - - int (* GetLogPlot)( AstPlot *, int, int * ); - int (* TestLogPlot)( AstPlot *, int, int * ); - void (* SetLogPlot)( AstPlot *, int, int, int * ); - void (* ClearLogPlot)( AstPlot *, int, int * ); - - int (* GetLogTicks)( AstPlot *, int, int * ); - int (* TestLogTicks)( AstPlot *, int, int * ); - void (* SetLogTicks)( AstPlot *, int, int, int * ); - void (* ClearLogTicks)( AstPlot *, int, int * ); - - int (* GetLogLabel)( AstPlot *, int, int * ); - int (* TestLogLabel)( AstPlot *, int, int * ); - void (* SetLogLabel)( AstPlot *, int, int, int * ); - void (* ClearLogLabel)( AstPlot *, int, int * ); - - int (* GetDrawAxes)( AstPlot *, int, int * ); - int (* TestDrawAxes)( AstPlot *, int, int * ); - void (* SetDrawAxes)( AstPlot *, int, int, int * ); - void (* ClearDrawAxes)( AstPlot *, int, int * ); - - int (* GetAbbrev)( AstPlot *, int, int * ); - int (* TestAbbrev)( AstPlot *, int, int * ); - void (* SetAbbrev)( AstPlot *, int, int, int * ); - void (* ClearAbbrev)( AstPlot *, int, int * ); - - int (* GetEscape)( AstPlot *, int * ); - int (* TestEscape)( AstPlot *, int * ); - void (* SetEscape)( AstPlot *, int, int * ); - void (* ClearEscape)( AstPlot *, int * ); - - int (* GetLabelling)( AstPlot *, int * ); - int (* TestLabelling)( AstPlot *, int * ); - void (* SetLabelling)( AstPlot *, int, int * ); - void (* ClearLabelling)( AstPlot *, int * ); - - double (* GetMajTickLen)( AstPlot *, int, int * ); - int (* TestMajTickLen)( AstPlot *, int, int * ); - void (* SetMajTickLen)( AstPlot *, int, double, int * ); - void (* ClearMajTickLen)( AstPlot *, int, int * ); - - double (* GetMinTickLen)( AstPlot *, int, int * ); - int (* TestMinTickLen)( AstPlot *, int, int * ); - void (* SetMinTickLen)( AstPlot *, int, double, int * ); - void (* ClearMinTickLen)( AstPlot *, int, int * ); - - double (* GetNumLabGap)( AstPlot *, int, int * ); - int (* TestNumLabGap)( AstPlot *, int, int * ); - void (* SetNumLabGap)( AstPlot *, int, double, int * ); - void (* ClearNumLabGap)( AstPlot *, int, int * ); - - double (* GetTextLabGap)( AstPlot *, int, int * ); - int (* TestTextLabGap)( AstPlot *, int, int * ); - void (* SetTextLabGap)( AstPlot *, int, double, int * ); - void (* ClearTextLabGap)( AstPlot *, int, int * ); - - double (* GetTitleGap)( AstPlot *, int * ); - int (* TestTitleGap)( AstPlot *, int * ); - void (* SetTitleGap)( AstPlot *, double, int * ); - void (* ClearTitleGap)( AstPlot *, int * ); - - double (* GetLabelAt)( AstPlot *, int, int * ); - int (* TestLabelAt)( AstPlot *, int, int * ); - void (* SetLabelAt)( AstPlot *, int, double, int * ); - void (* ClearLabelAt)( AstPlot *, int, int * ); - - double (* GetGap)( AstPlot *, int, int * ); - int (* TestGap)( AstPlot *, int, int * ); - void (* SetGap)( AstPlot *, int, double, int * ); - void (* ClearGap)( AstPlot *, int, int * ); - - double (* GetLogGap)( AstPlot *, int, int * ); - int (* TestLogGap)( AstPlot *, int, int * ); - void (* SetLogGap)( AstPlot *, int, double, int * ); - void (* ClearLogGap)( AstPlot *, int, int * ); - - double (* GetCentre)( AstPlot *, int, int * ); - int (* TestCentre)( AstPlot *, int, int * ); - void (* SetCentre)( AstPlot *, int, double, int * ); - void (* ClearCentre)( AstPlot *, int, int * ); - - int (* GetEdge)( AstPlot *, int, int * ); - int (* TestEdge)( AstPlot *, int, int * ); - void (* SetEdge)( AstPlot *, int, int, int * ); - void (* ClearEdge)( AstPlot *, int, int * ); - - int (* GetNumLab)( AstPlot *, int, int * ); - int (* TestNumLab)( AstPlot *, int, int * ); - void (* SetNumLab)( AstPlot *, int, int, int * ); - void (* ClearNumLab)( AstPlot *, int, int * ); - - int (* GetMinTick)( AstPlot *, int, int * ); - int (* TestMinTick)( AstPlot *, int, int * ); - void (* SetMinTick)( AstPlot *, int, int, int * ); - void (* ClearMinTick)( AstPlot *, int, int * ); - - int (* GetTextLab)( AstPlot *, int, int * ); - int (* TestTextLab)( AstPlot *, int, int * ); - void (* SetTextLab)( AstPlot *, int, int, int * ); - void (* ClearTextLab)( AstPlot *, int, int * ); - - int (* GetLabelUnits)( AstPlot *, int, int * ); - int (* TestLabelUnits)( AstPlot *, int, int * ); - void (* SetLabelUnits)( AstPlot *, int, int, int * ); - void (* ClearLabelUnits)( AstPlot *, int, int * ); - - int (* GetStyle)( AstPlot *, int, int * ); - int (* TestStyle)( AstPlot *, int, int * ); - void (* SetStyle)( AstPlot *, int, int, int * ); - void (* ClearStyle)( AstPlot *, int, int * ); - - int (* GetFont)( AstPlot *, int, int * ); - int (* TestFont)( AstPlot *, int, int * ); - void (* SetFont)( AstPlot *, int, int, int * ); - void (* ClearFont)( AstPlot *, int, int * ); - - int (* GetColour)( AstPlot *, int, int * ); - int (* TestColour)( AstPlot *, int, int * ); - void (* SetColour)( AstPlot *, int, int, int * ); - void (* ClearColour)( AstPlot *, int, int * ); - - double (* GetWidth)( AstPlot *, int, int * ); - int (* TestWidth)( AstPlot *, int, int * ); - void (* SetWidth)( AstPlot *, int, double, int * ); - void (* ClearWidth)( AstPlot *, int, int * ); - - double (* GetSize)( AstPlot *, int, int * ); - int (* TestSize)( AstPlot *, int, int * ); - void (* SetSize)( AstPlot *, int, double, int * ); - void (* ClearSize)( AstPlot *, int, int * ); - - int (* GetInk)( AstPlot *, int * ); - int (* TestInk)( AstPlot *, int * ); - void (* SetInk)( AstPlot *, int, int * ); - void (* ClearInk)( AstPlot *, int * ); - -} AstPlotVtab; - -/* Structure holding information about curves drawn by astGridLine and - astCurve. */ -typedef struct AstPlotCurveData{ - int out; /* Was the curve completely outside the clipping area? */ - int nbrk; /* The number of breaks in the curve. */ - float xbrk[ AST__PLOT_CRV_MXBRK ]; /* Graphics X coordinate at each break. */ - float ybrk[ AST__PLOT_CRV_MXBRK ]; /* Graphics Y coordinate at each break. */ - float vxbrk[ AST__PLOT_CRV_MXBRK ]; /* X comp. of unit tangent vector */ - float vybrk[ AST__PLOT_CRV_MXBRK ]; /* Y comp. of unit tangent vector */ - float length; /* Drawn length of the curve in graphics coordinates */ -} AstPlotCurveData; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstPlotGlobals { - AstPlotVtab Class_Vtab; - int Class_Init; - double GrfAttrs_attrs_t[ GRF__NATTR ]; - int GrfAttrs_nesting_t; - double Crv_limit_t; - double Crv_scerr_t; - double Crv_tol_t; - double Crv_ux0_t; - double Crv_uy0_t; - double Crv_vxl_t; - double Crv_vyl_t; - double Crv_xhi_t; - double Crv_xl_t; - double Crv_xlo_t; - double Crv_yhi_t; - double Crv_yl_t; - double Crv_ylo_t; - float *Crv_vxbrk_t; - float *Crv_vybrk_t; - float *Crv_xbrk_t; - float *Crv_ybrk_t; - float Crv_len_t; - int Crv_ink_t; - int Crv_nbrk_t; - int Crv_nent_t; - int Crv_out_t; - int Crv_clip_t; - void (*Crv_map_t)( int, double *, double *, double *, const char *, const char *, int *, struct AstGlobals * ); - void *Crv_mapstatics_t; - float Box_lbnd_t[ 2 ]; - float Box_ubnd_t[ 2 ]; - float Boxp_lbnd_t[ 2 ]; - float Boxp_ubnd_t[ 2 ]; - int Boxp_freeze_t; - float *Poly_x_t; - float *Poly_y_t; - int Poly_n_t; - float **Poly_xp_t; - float **Poly_yp_t; - int *Poly_np_t; - int Poly_npoly_t; - int Map1_ncoord_t; - AstPlot *Map1_plot_t; - AstMapping *Map1_map_t; - AstFrame *Map1_frame_t; - const double *Map1_origin_t; - double Map1_length_t; - int Map1_axis_t; - void *Map1_statics_t; - int Map1_norm_t; - int Map1_log_t; - int Map2_ncoord_t; - AstPlot *Map2_plot_t; - AstMapping *Map2_map_t; - double Map2_x0_t; - double Map2_y0_t; - double Map2_deltax_t; - double Map2_deltay_t; - void *Map2_statics_t; - int Map3_ncoord_t; - AstPlot *Map3_plot_t; - AstMapping *Map3_map_t; - AstFrame *Map3_frame_t; - const double *Map3_origin_t; - const double *Map3_end_t; - double Map3_scale_t; - void *Map3_statics_t; - int Map4_ncoord_t; - AstPlot *Map4_plot_t; - AstMapping *Map4_map_t; - AstMapping *Map4_umap_t; - void *Map4_statics_t; - int Map5_ncoord_t; - AstPlot *Map5_plot_t; - AstMapping *Map5_map_t; - AstRegion *Map5_region_t; - void *Map5_statics_t; - AstPlotCurveData Curve_data_t; - char GetAttrib_Buff[ 200 ]; - char SplitValue_Buff[ 200 ]; - char StripEscapes_Buff[ AST__PLOT_STRIPESCAPES_BUFF_LEN + 1 ]; - double Grf_chv_t; - double Grf_chh_t; - float Grf_alpha_t; - float Grf_beta_t; -} AstPlotGlobals; - -#endif -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Plot) /* Check class membership */ -astPROTO_ISA(Plot) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstPlot *astPlot_( void *, const float *, const double *, const char *, int *, ...); -#else -AstPlot *astPlotId_( void *, const float [], const double [], const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstPlot *astInitPlot_( void *, size_t, int, AstPlotVtab *, - const char *, AstFrame *, const float *, const double *, int * ); - -/* Vtab initialiser. */ -void astInitPlotVtab_( AstPlotVtab *, const char *, int * ); - -/* Loader. */ -AstPlot *astLoadPlot_( void *, size_t, AstPlotVtab *, - const char *, AstChannel *channel, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitPlotGlobals_( AstPlotGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - AstKeyMap *astGetGrfContext_( AstPlot *, int * ); - AstKeyMap *astGrfConID_( AstPlot *, int * ); - const char *astStripEscapes_( const char *, int * ); - int astBorder_( AstPlot *, int * ); - int astFindEscape_( const char *, int *, int *, int *, int * ); - void astBBuf_( AstPlot *, int * ); - void astBoundingBox_( AstPlot *, float[2], float[2], int * ); - void astClip_( AstPlot *, int, const double [], const double [], int * ); - void astCurve_( AstPlot *, const double [], const double [], int * ); - void astEBuf_( AstPlot *, int * ); - void astGenCurve_( AstPlot *, AstMapping *, int * ); - void astGrfPop_( AstPlot *, int * ); - void astGrfPush_( AstPlot *, int * ); - void astGrfSet_( AstPlot *, const char *, AstGrfFun, int * ); - void astGridLine_( AstPlot *, int, const double [], double, int * ); - void astGrid_( AstPlot *, int * ); - void astMark_( AstPlot *, int, int, int, const double *, int, int * ); - void astPolyCurve_( AstPlot *, int, int, int, const double *, int * ); - void astRegionOutline_( AstPlot *, AstRegion *, int * ); - void astText_( AstPlot *, const char *, const double [], const float [], const char *, int * ); - - void astGrfWrapper_( AstPlot *, const char *, AstGrfWrap, int * ); - int astGrfFunID_( const char *, const char *, const char *, int * ); - -#if defined(astCLASS) /* Protected */ - int astCvBrk_( AstPlot *, int, double *, double *, double *, int * ); - void astCopyPlotDefaults_( AstPlot *, int, AstPlot *, int, int * ); - void astMirror_( AstPlot *, int, int * ); - AstPointSet *astGetDrawnTicks_( AstPlot *, int, int, int * ); - void astSetTickValues_( AstPlot *, int, int, double *, int, double *, int * ); - void astDrawExtraTicks_( AstPlot *, int, AstPointSet *, int * ); - void astGrfAttrs_( AstPlot *, int, int, int, const char *, const char *, int * ); - - double astGetTol_( AstPlot *, int * ); - int astTestTol_( AstPlot *, int * ); - void astSetTol_( AstPlot *, double, int * ); - void astClearTol_( AstPlot *, int * ); - - int astGetGrid_( AstPlot *, int * ); - int astTestGrid_( AstPlot *, int * ); - void astSetGrid_( AstPlot *, int, int * ); - void astClearGrid_( AstPlot *, int * ); - - int astGetTickAll_( AstPlot *, int * ); - int astTestTickAll_( AstPlot *, int * ); - void astSetTickAll_( AstPlot *, int, int * ); - void astClearTickAll_( AstPlot *, int * ); - - int astGetForceExterior_( AstPlot *, int * ); - int astTestForceExterior_( AstPlot *, int * ); - void astSetForceExterior_( AstPlot *, int, int * ); - void astClearForceExterior_( AstPlot *, int * ); - - int astGetInvisible_( AstPlot *, int * ); - int astTestInvisible_( AstPlot *, int * ); - void astSetInvisible_( AstPlot *, int, int * ); - void astClearInvisible_( AstPlot *, int * ); - - int astGetBorder_( AstPlot *, int * ); - int astTestBorder_( AstPlot *, int * ); - void astSetBorder_( AstPlot *, int, int * ); - void astClearBorder_( AstPlot *, int * ); - - int astGetClip_( AstPlot *, int * ); - int astTestClip_( AstPlot *, int * ); - void astSetClip_( AstPlot *, int, int * ); - void astClearClip_( AstPlot *, int * ); - - int astGetClipOp_( AstPlot *, int * ); - int astTestClipOp_( AstPlot *, int * ); - void astSetClipOp_( AstPlot *, int, int * ); - void astClearClipOp_( AstPlot *, int * ); - - int astGetGrf_( AstPlot *, int * ); - int astTestGrf_( AstPlot *, int * ); - void astSetGrf_( AstPlot *, int, int * ); - void astClearGrf_( AstPlot *, int * ); - - int astGetDrawTitle_( AstPlot *, int * ); - int astTestDrawTitle_( AstPlot *, int * ); - void astSetDrawTitle_( AstPlot *, int, int * ); - void astClearDrawTitle_( AstPlot *, int * ); - - int astGetLabelUp_( AstPlot *, int, int * ); - int astTestLabelUp_( AstPlot *, int, int * ); - void astSetLabelUp_( AstPlot *, int, int, int * ); - void astClearLabelUp_( AstPlot *, int, int * ); - - int astGetLogPlot_( AstPlot *, int, int * ); - int astTestLogPlot_( AstPlot *, int, int * ); - void astSetLogPlot_( AstPlot *, int, int, int * ); - void astClearLogPlot_( AstPlot *, int, int * ); - - int astGetLogTicks_( AstPlot *, int, int * ); - int astTestLogTicks_( AstPlot *, int, int * ); - void astSetLogTicks_( AstPlot *, int, int, int * ); - void astClearLogTicks_( AstPlot *, int, int * ); - - int astGetLogLabel_( AstPlot *, int, int * ); - int astTestLogLabel_( AstPlot *, int, int * ); - void astSetLogLabel_( AstPlot *, int, int, int * ); - void astClearLogLabel_( AstPlot *, int, int * ); - - int astGetDrawAxes_( AstPlot *, int, int * ); - int astTestDrawAxes_( AstPlot *, int, int * ); - void astSetDrawAxes_( AstPlot *, int, int, int * ); - void astClearDrawAxes_( AstPlot *, int, int * ); - - int astGetAbbrev_( AstPlot *, int, int * ); - int astTestAbbrev_( AstPlot *, int, int * ); - void astSetAbbrev_( AstPlot *, int, int, int * ); - void astClearAbbrev_( AstPlot *, int, int * ); - - int astGetEscape_( AstPlot *, int * ); - int astTestEscape_( AstPlot *, int * ); - void astSetEscape_( AstPlot *, int, int * ); - void astClearEscape_( AstPlot *, int * ); - - double astGetLabelAt_( AstPlot *, int, int * ); - int astTestLabelAt_( AstPlot *, int, int * ); - void astSetLabelAt_( AstPlot *, int, double, int * ); - void astClearLabelAt_( AstPlot *, int, int * ); - - double astGetGap_( AstPlot *, int, int * ); - int astTestGap_( AstPlot *, int, int * ); - void astSetGap_( AstPlot *, int, double, int * ); - void astClearGap_( AstPlot *, int, int * ); - - double astGetLogGap_( AstPlot *, int, int * ); - int astTestLogGap_( AstPlot *, int, int * ); - void astSetLogGap_( AstPlot *, int, double, int * ); - void astClearLogGap_( AstPlot *, int, int * ); - - double astGetCentre_( AstPlot *, int, int * ); - int astTestCentre_( AstPlot *, int, int * ); - void astSetCentre_( AstPlot *, int, double, int * ); - void astClearCentre_( AstPlot *, int, int * ); - - int astGetLabelling_( AstPlot *, int * ); - int astTestLabelling_( AstPlot *, int * ); - void astSetLabelling_( AstPlot *, int, int * ); - void astClearLabelling_( AstPlot *, int * ); - - double astGetMajTickLen_( AstPlot *, int, int * ); - int astTestMajTickLen_( AstPlot *, int, int * ); - void astSetMajTickLen_( AstPlot *, int, double, int * ); - void astClearMajTickLen_( AstPlot *, int, int * ); - - double astGetMinTickLen_( AstPlot *, int, int * ); - int astTestMinTickLen_( AstPlot *, int, int * ); - void astSetMinTickLen_( AstPlot *, int, double, int * ); - void astClearMinTickLen_( AstPlot *, int, int * ); - - double astGetNumLabGap_( AstPlot *, int, int * ); - int astTestNumLabGap_( AstPlot *, int, int * ); - void astSetNumLabGap_( AstPlot *, int, double, int * ); - void astClearNumLabGap_( AstPlot *, int, int * ); - - double astGetTextLabGap_( AstPlot *, int, int * ); - int astTestTextLabGap_( AstPlot *, int, int * ); - void astSetTextLabGap_( AstPlot *, int, double, int * ); - void astClearTextLabGap_( AstPlot *, int, int * ); - - double astGetTitleGap_( AstPlot *, int * ); - int astTestTitleGap_( AstPlot *, int * ); - void astSetTitleGap_( AstPlot *, double, int * ); - void astClearTitleGap_( AstPlot *, int * ); - - int astGetEdge_( AstPlot *, int, int * ); - int astTestEdge_( AstPlot *, int, int * ); - void astSetEdge_( AstPlot *, int, int, int * ); - void astClearEdge_( AstPlot *, int, int * ); - - int astGetMinTick_( AstPlot *, int, int * ); - int astTestMinTick_( AstPlot *, int, int * ); - void astSetMinTick_( AstPlot *, int, int, int * ); - void astClearMinTick_( AstPlot *, int, int * ); - - int astGetNumLab_( AstPlot *, int, int * ); - int astTestNumLab_( AstPlot *, int, int * ); - void astSetNumLab_( AstPlot *, int, int, int * ); - void astClearNumLab_( AstPlot *, int, int * ); - - int astGetTextLab_( AstPlot *, int, int * ); - int astTestTextLab_( AstPlot *, int, int * ); - void astSetTextLab_( AstPlot *, int, int, int * ); - void astClearTextLab_( AstPlot *, int, int * ); - - int astGetLabelUnits_( AstPlot *, int, int * ); - int astTestLabelUnits_( AstPlot *, int, int * ); - void astSetLabelUnits_( AstPlot *, int, int, int * ); - void astClearLabelUnits_( AstPlot *, int, int * ); - - int astGetStyle_( AstPlot *, int, int * ); - int astTestStyle_( AstPlot *, int, int * ); - void astSetStyle_( AstPlot *, int, int, int * ); - void astClearStyle_( AstPlot *, int, int * ); - - int astGetFont_( AstPlot *, int, int * ); - int astTestFont_( AstPlot *, int, int * ); - void astSetFont_( AstPlot *, int, int, int * ); - void astClearFont_( AstPlot *, int, int * ); - - int astGetColour_( AstPlot *, int, int * ); - int astTestColour_( AstPlot *, int, int * ); - void astSetColour_( AstPlot *, int, int, int * ); - void astClearColour_( AstPlot *, int, int * ); - - double astGetWidth_( AstPlot *, int, int * ); - int astTestWidth_( AstPlot *, int, int * ); - void astSetWidth_( AstPlot *, int, double, int * ); - void astClearWidth_( AstPlot *, int, int * ); - - double astGetSize_( AstPlot *, int, int * ); - int astTestSize_( AstPlot *, int, int * ); - void astSetSize_( AstPlot *, int, double, int * ); - void astClearSize_( AstPlot *, int, int * ); - - int astGetInk_( AstPlot *, int * ); - int astTestInk_( AstPlot *, int * ); - void astSetInk_( AstPlot *, int, int * ); - void astClearInk_( AstPlot *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class to make - them easier to invoke (e.g. to avoid type mis-matches when passing pointers - to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them to - validate their own arguments. We must use a cast when passing object - pointers (so that they can accept objects from derived classes). */ - -/* Check class membership. */ -#define astCheckPlot(this) astINVOKE_CHECK(Plot,this,0) -#define astVerifyPlot(this) astINVOKE_CHECK(Plot,this,1) - -/* Test class membership. */ -#define astIsAPlot(this) astINVOKE_ISA(Plot,this) - -#if defined(astCLASS) /* Protected */ -#define astPlot astINVOKE(F,astPlot_) -#else -#define astPlot astINVOKE(F,astPlotId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitPlot(mem,size,init,vtab,name,frame,graph,base) \ -astINVOKE(O,astInitPlot_(mem,size,init,vtab,name,frame,graph,base,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitPlotVtab(vtab,name) astINVOKE(V,astInitPlotVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadPlot(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadPlot_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to member functions. */ -/* ------------------------------- */ -/* Here we make use of astCheckPlot (et al.) to validate Plot - pointers before use. This provides a contextual error report if a - pointer to the wrong sort of object is supplied. */ - - -#define astGetGrfContext(this) \ -astINVOKE(O,astGetGrfContext_(astCheckPlot(this),STATUS_PTR)) - -#define astBorder(this) \ -astINVOKE(V,astBorder_(astCheckPlot(this),STATUS_PTR)) - -#define astBoundingBox(this,lbnd,ubnd) \ -astINVOKE(V,astBoundingBox_(astCheckPlot(this),lbnd,ubnd,STATUS_PTR)) - -#define astClip(this,iframe,lbnd,ubnd) \ -astINVOKE(V,astClip_(astCheckPlot(this),iframe,lbnd,ubnd,STATUS_PTR)) - -#define astMark(this,nmark,ncoord,indim,in,type) \ -astINVOKE(V,astMark_(astCheckPlot(this),nmark,ncoord,indim,in,type,STATUS_PTR)) - -#define astText(this,text,pos,up,just) \ -astINVOKE(V,astText_(astCheckPlot(this),text,pos,up,just,STATUS_PTR)) - -#define astGrid(this) \ -astINVOKE(V,astGrid_(astCheckPlot(this),STATUS_PTR)) - -#define astGridLine(this,axis,start,length) \ -astINVOKE(V,astGridLine_(astCheckPlot(this),axis,start,length,STATUS_PTR)) - -#define astCurve(this,start,finish) \ -astINVOKE(V,astCurve_(astCheckPlot(this),start,finish,STATUS_PTR)) - -#define astGenCurve(this,map) \ -astINVOKE(V,astGenCurve_(astCheckPlot(this),astCheckMapping(map),STATUS_PTR)) - -#define astPolyCurve(this,npoint,ncoord,dim,in) \ -astINVOKE(V,astPolyCurve_(astCheckPlot(this),npoint,ncoord,dim,in,STATUS_PTR)) - -#define astRegionOutline(this,region) \ -astINVOKE(V,astRegionOutline_(astCheckPlot(this),astCheckRegion(region),STATUS_PTR)) - -#define astGrfSet(this,name,fun) \ -astINVOKE(V,astGrfSet_(astCheckPlot(this),name,fun,STATUS_PTR)) - -#define astGrfPush(this) \ -astINVOKE(V,astGrfPush_(astCheckPlot(this),STATUS_PTR)) - -#define astGrfPop(this) \ -astINVOKE(V,astGrfPop_(astCheckPlot(this),STATUS_PTR)) - -#define astBBuf(this) \ -astINVOKE(V,astBBuf_(astCheckPlot(this),STATUS_PTR)) - -#define astEBuf(this) \ -astINVOKE(V,astEBuf_(astCheckPlot(this),STATUS_PTR)) - - -#define astGrfFunID(name,method,class) astGrfFunID_(name,method,class,STATUS_PTR) -#define astFindEscape(text,type,value,nc) astFindEscape_(text,type,value,nc,STATUS_PTR) -#define astStripEscapes(text) astStripEscapes_(text,STATUS_PTR) -#define astGrfConID(this) astGrfConID_(this,STATUS_PTR) - -#define astGrfWrapper(this,name,wrapper) \ -astINVOKE(V,astGrfWrapper_(astCheckPlot(this),name,wrapper,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ - -#define astGrfAttrs(this,id,set,prim,method,class) \ -astGrfAttrs_(astCheckPlot(this),id,set,prim,method,class,STATUS_PTR) - -#define astCvBrk(this,ibrk,brk,vbrk,len) \ -astINVOKE(V,astCvBrk_(astCheckPlot(this),ibrk,brk,vbrk,len,STATUS_PTR)) - -#define astCopyPlotDefaults(this,axis,dplot,daxis) \ -astINVOKE(V,astCopyPlotDefaults_(astCheckPlot(this),axis,astCheckPlot(dplot),daxis,STATUS_PTR)) - -#define astMirror(this,axis) \ -astINVOKE(V,astMirror_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astGetDrawnTicks(this,axis,major) \ -astINVOKE(O,astGetDrawnTicks_(astCheckPlot(this),axis,major,STATUS_PTR)) - -#define astSetTickValues(this,axis,nmajor,major,nminor,minor) \ -astINVOKE(V,astSetTickValues_(astCheckPlot(this),axis,nmajor,major,nminor,minor,STATUS_PTR)) - -#define astDrawExtraTicks(this,axis,pset) \ -astINVOKE(V,astDrawExtraTicks_(astCheckPlot(this),axis,astCheckPointSet(pset),STATUS_PTR)) - -#define astClearTol(this) \ -astINVOKE(V,astClearTol_(astCheckPlot(this),STATUS_PTR)) -#define astGetTol(this) \ -astINVOKE(V,astGetTol_(astCheckPlot(this),STATUS_PTR)) -#define astSetTol(this,tol) \ -astINVOKE(V,astSetTol_(astCheckPlot(this),tol,STATUS_PTR)) -#define astTestTol(this) \ -astINVOKE(V,astTestTol_(astCheckPlot(this),STATUS_PTR)) - -#define astClearGrid(this) \ -astINVOKE(V,astClearGrid_(astCheckPlot(this),STATUS_PTR)) -#define astGetGrid(this) \ -astINVOKE(V,astGetGrid_(astCheckPlot(this),STATUS_PTR)) -#define astSetGrid(this,grid) \ -astINVOKE(V,astSetGrid_(astCheckPlot(this),grid,STATUS_PTR)) -#define astTestGrid(this) \ -astINVOKE(V,astTestGrid_(astCheckPlot(this),STATUS_PTR)) - -#define astClearInk(this) \ -astINVOKE(V,astClearInk_(astCheckPlot(this),STATUS_PTR)) -#define astGetInk(this) \ -astINVOKE(V,astGetInk_(astCheckPlot(this),STATUS_PTR)) -#define astSetInk(this,ink) \ -astINVOKE(V,astSetInk_(astCheckPlot(this),ink,STATUS_PTR)) -#define astTestInk(this) \ -astINVOKE(V,astTestInk_(astCheckPlot(this),STATUS_PTR)) - -#define astClearTickAll(this) \ -astINVOKE(V,astClearTickAll_(astCheckPlot(this),STATUS_PTR)) -#define astGetTickAll(this) \ -astINVOKE(V,astGetTickAll_(astCheckPlot(this),STATUS_PTR)) -#define astSetTickAll(this,tickall) \ -astINVOKE(V,astSetTickAll_(astCheckPlot(this),tickall,STATUS_PTR)) -#define astTestTickAll(this) \ -astINVOKE(V,astTestTickAll_(astCheckPlot(this),STATUS_PTR)) - -#define astClearForceExterior(this) \ -astINVOKE(V,astClearForceExterior_(astCheckPlot(this),STATUS_PTR)) -#define astGetForceExterior(this) \ -astINVOKE(V,astGetForceExterior_(astCheckPlot(this),STATUS_PTR)) -#define astSetForceExterior(this,frcext) \ -astINVOKE(V,astSetForceExterior_(astCheckPlot(this),frcext,STATUS_PTR)) -#define astTestForceExterior(this) \ -astINVOKE(V,astTestForceExterior_(astCheckPlot(this),STATUS_PTR)) - -#define astClearBorder(this) \ -astINVOKE(V,astClearBorder_(astCheckPlot(this),STATUS_PTR)) -#define astGetBorder(this) \ -astINVOKE(V,astGetBorder_(astCheckPlot(this),STATUS_PTR)) -#define astSetBorder(this,border) \ -astINVOKE(V,astSetBorder_(astCheckPlot(this),border,STATUS_PTR)) -#define astTestBorder(this) \ -astINVOKE(V,astTestBorder_(astCheckPlot(this),STATUS_PTR)) - -#define astClearClip(this) \ -astINVOKE(V,astClearClip_(astCheckPlot(this),STATUS_PTR)) -#define astGetClip(this) \ -astINVOKE(V,astGetClip_(astCheckPlot(this),STATUS_PTR)) -#define astSetClip(this,clip) \ -astINVOKE(V,astSetClip_(astCheckPlot(this),clip,STATUS_PTR)) -#define astTestClip(this) \ -astINVOKE(V,astTestClip_(astCheckPlot(this),STATUS_PTR)) - -#define astClearClipOp(this) \ -astINVOKE(V,astClearClipOp_(astCheckPlot(this),STATUS_PTR)) -#define astGetClipOp(this) \ -astINVOKE(V,astGetClipOp_(astCheckPlot(this),STATUS_PTR)) -#define astSetClipOp(this,clipop) \ -astINVOKE(V,astSetClipOp_(astCheckPlot(this),clipop,STATUS_PTR)) -#define astTestClipOp(this) \ -astINVOKE(V,astTestClipOp_(astCheckPlot(this),STATUS_PTR)) - -#define astClearInvisible(this) \ -astINVOKE(V,astClearInvisible_(astCheckPlot(this),STATUS_PTR)) -#define astGetInvisible(this) \ -astINVOKE(V,astGetInvisible_(astCheckPlot(this),STATUS_PTR)) -#define astSetInvisible(this,invisible) \ -astINVOKE(V,astSetInvisible_(astCheckPlot(this),invisible,STATUS_PTR)) -#define astTestInvisible(this) \ -astINVOKE(V,astTestInvisible_(astCheckPlot(this),STATUS_PTR)) - -#define astClearGrf(this) \ -astINVOKE(V,astClearGrf_(astCheckPlot(this),STATUS_PTR)) -#define astGetGrf(this) \ -astINVOKE(V,astGetGrf_(astCheckPlot(this),STATUS_PTR)) -#define astSetGrf(this,grf) \ -astINVOKE(V,astSetGrf_(astCheckPlot(this),grf,STATUS_PTR)) -#define astTestGrf(this) \ -astINVOKE(V,astTestGrf_(astCheckPlot(this),STATUS_PTR)) - -#define astClearDrawTitle(this) \ -astINVOKE(V,astClearDrawTitle_(astCheckPlot(this),STATUS_PTR)) -#define astGetDrawTitle(this) \ -astINVOKE(V,astGetDrawTitle_(astCheckPlot(this),STATUS_PTR)) -#define astSetDrawTitle(this,drawtitle) \ -astINVOKE(V,astSetDrawTitle_(astCheckPlot(this),drawtitle,STATUS_PTR)) -#define astTestDrawTitle(this) \ -astINVOKE(V,astTestDrawTitle_(astCheckPlot(this),STATUS_PTR)) - -#define astClearDrawAxes(this,axis) \ -astINVOKE(V,astClearDrawAxes_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetDrawAxes(this,axis) \ -astINVOKE(V,astGetDrawAxes_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetDrawAxes(this,axis,drawaxes) \ -astINVOKE(V,astSetDrawAxes_(astCheckPlot(this),axis,drawaxes,STATUS_PTR)) -#define astTestDrawAxes(this,axis) \ -astINVOKE(V,astTestDrawAxes_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearAbbrev(this,axis) \ -astINVOKE(V,astClearAbbrev_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetAbbrev(this,axis) \ -astINVOKE(V,astGetAbbrev_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetAbbrev(this,axis,abbrev) \ -astINVOKE(V,astSetAbbrev_(astCheckPlot(this),axis,abbrev,STATUS_PTR)) -#define astTestAbbrev(this,axis) \ -astINVOKE(V,astTestAbbrev_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearEscape(this) \ -astINVOKE(V,astClearEscape_(astCheckPlot(this),STATUS_PTR)) -#define astGetEscape(this) \ -astINVOKE(V,astGetEscape_(astCheckPlot(this),STATUS_PTR)) -#define astSetEscape(this,escape) \ -astINVOKE(V,astSetEscape_(astCheckPlot(this),escape,STATUS_PTR)) -#define astTestEscape(this) \ -astINVOKE(V,astTestEscape_(astCheckPlot(this),STATUS_PTR)) - -#define astClearLabelAt(this,axis) \ -astINVOKE(V,astClearLabelAt_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetLabelAt(this,axis) \ -astINVOKE(V,astGetLabelAt_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetLabelAt(this,axis,labelat) \ -astINVOKE(V,astSetLabelAt_(astCheckPlot(this),axis,labelat,STATUS_PTR)) -#define astTestLabelAt(this,axis) \ -astINVOKE(V,astTestLabelAt_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearGap(this,axis) \ -astINVOKE(V,astClearGap_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetGap(this,axis) \ -astINVOKE(V,astGetGap_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetGap(this,axis,gap) \ -astINVOKE(V,astSetGap_(astCheckPlot(this),axis,gap,STATUS_PTR)) -#define astTestGap(this,axis) \ -astINVOKE(V,astTestGap_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearLogGap(this,axis) \ -astINVOKE(V,astClearLogGap_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetLogGap(this,axis) \ -astINVOKE(V,astGetLogGap_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetLogGap(this,axis,gap) \ -astINVOKE(V,astSetLogGap_(astCheckPlot(this),axis,gap,STATUS_PTR)) -#define astTestLogGap(this,axis) \ -astINVOKE(V,astTestLogGap_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearCentre(this,axis) \ -astINVOKE(V,astClearCentre_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetCentre(this,axis) \ -astINVOKE(V,astGetCentre_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetCentre(this,axis,centre) \ -astINVOKE(V,astSetCentre_(astCheckPlot(this),axis,centre,STATUS_PTR)) -#define astTestCentre(this,axis) \ -astINVOKE(V,astTestCentre_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearMajTickLen(this,axis) \ -astINVOKE(V,astClearMajTickLen_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetMajTickLen(this,axis) \ -astINVOKE(V,astGetMajTickLen_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetMajTickLen(this,axis,majticklen) \ -astINVOKE(V,astSetMajTickLen_(astCheckPlot(this),axis,majticklen,STATUS_PTR)) -#define astTestMajTickLen(this,axis) \ -astINVOKE(V,astTestMajTickLen_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearMinTickLen(this,axis) \ -astINVOKE(V,astClearMinTickLen_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetMinTickLen(this,axis) \ -astINVOKE(V,astGetMinTickLen_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetMinTickLen(this,axis,minticklen) \ -astINVOKE(V,astSetMinTickLen_(astCheckPlot(this),axis,minticklen,STATUS_PTR)) -#define astTestMinTickLen(this,axis) \ -astINVOKE(V,astTestMinTickLen_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearNumLabGap(this,axis) \ -astINVOKE(V,astClearNumLabGap_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetNumLabGap(this,axis) \ -astINVOKE(V,astGetNumLabGap_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetNumLabGap(this,axis,numlabgap) \ -astINVOKE(V,astSetNumLabGap_(astCheckPlot(this),axis,numlabgap,STATUS_PTR)) -#define astTestNumLabGap(this,axis) \ -astINVOKE(V,astTestNumLabGap_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearTextLabGap(this,axis) \ -astINVOKE(V,astClearTextLabGap_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetTextLabGap(this,axis) \ -astINVOKE(V,astGetTextLabGap_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetTextLabGap(this,axis,textlabgap) \ -astINVOKE(V,astSetTextLabGap_(astCheckPlot(this),axis,textlabgap,STATUS_PTR)) -#define astTestTextLabGap(this,axis) \ -astINVOKE(V,astTestTextLabGap_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearTitleGap(this) \ -astINVOKE(V,astClearTitleGap_(astCheckPlot(this),STATUS_PTR)) -#define astGetTitleGap(this) \ -astINVOKE(V,astGetTitleGap_(astCheckPlot(this),STATUS_PTR)) -#define astSetTitleGap(this,titlegap) \ -astINVOKE(V,astSetTitleGap_(astCheckPlot(this),titlegap,STATUS_PTR)) -#define astTestTitleGap(this) \ -astINVOKE(V,astTestTitleGap_(astCheckPlot(this),STATUS_PTR)) - -#define astClearLabelling(this) \ -astINVOKE(V,astClearLabelling_(astCheckPlot(this),STATUS_PTR)) -#define astGetLabelling(this) \ -astINVOKE(V,astGetLabelling_(astCheckPlot(this),STATUS_PTR)) -#define astSetLabelling(this,labelling) \ -astINVOKE(V,astSetLabelling_(astCheckPlot(this),labelling,STATUS_PTR)) -#define astTestLabelling(this) \ -astINVOKE(V,astTestLabelling_(astCheckPlot(this),STATUS_PTR)) - -#define astClearEdge(this,axis) \ -astINVOKE(V,astClearEdge_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetEdge(this,axis) \ -astINVOKE(V,astGetEdge_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetEdge(this,axis,edge) \ -astINVOKE(V,astSetEdge_(astCheckPlot(this),axis,edge,STATUS_PTR)) -#define astTestEdge(this,axis) \ -astINVOKE(V,astTestEdge_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearMinTick(this,axis) \ -astINVOKE(V,astClearMinTick_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetMinTick(this,axis) \ -astINVOKE(V,astGetMinTick_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetMinTick(this,axis,mintick) \ -astINVOKE(V,astSetMinTick_(astCheckPlot(this),axis,mintick,STATUS_PTR)) -#define astTestMinTick(this,axis) \ -astINVOKE(V,astTestMinTick_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearNumLab(this,axis) \ -astINVOKE(V,astClearNumLab_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetNumLab(this,axis) \ -astINVOKE(V,astGetNumLab_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetNumLab(this,axis,numlab) \ -astINVOKE(V,astSetNumLab_(astCheckPlot(this),axis,numlab,STATUS_PTR)) -#define astTestNumLab(this,axis) \ -astINVOKE(V,astTestNumLab_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearLabelUp(this,axis) \ -astINVOKE(V,astClearLabelUp_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetLabelUp(this,axis) \ -astINVOKE(V,astGetLabelUp_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetLabelUp(this,axis,labelup) \ -astINVOKE(V,astSetLabelUp_(astCheckPlot(this),axis,labelup,STATUS_PTR)) -#define astTestLabelUp(this,axis) \ -astINVOKE(V,astTestLabelUp_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearLogPlot(this,axis) \ -astINVOKE(V,astClearLogPlot_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetLogPlot(this,axis) \ -astINVOKE(V,astGetLogPlot_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetLogPlot(this,axis,logplot) \ -astINVOKE(V,astSetLogPlot_(astCheckPlot(this),axis,logplot,STATUS_PTR)) -#define astTestLogPlot(this,axis) \ -astINVOKE(V,astTestLogPlot_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearLogTicks(this,axis) \ -astINVOKE(V,astClearLogTicks_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetLogTicks(this,axis) \ -astINVOKE(V,astGetLogTicks_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetLogTicks(this,axis,logticks) \ -astINVOKE(V,astSetLogTicks_(astCheckPlot(this),axis,logticks,STATUS_PTR)) -#define astTestLogTicks(this,axis) \ -astINVOKE(V,astTestLogTicks_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearLogLabel(this,axis) \ -astINVOKE(V,astClearLogLabel_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetLogLabel(this,axis) \ -astINVOKE(V,astGetLogLabel_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetLogLabel(this,axis,loglabel) \ -astINVOKE(V,astSetLogLabel_(astCheckPlot(this),axis,loglabel,STATUS_PTR)) -#define astTestLogLabel(this,axis) \ -astINVOKE(V,astTestLogLabel_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearTextLab(this,axis) \ -astINVOKE(V,astClearTextLab_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetTextLab(this,axis) \ -astINVOKE(V,astGetTextLab_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetTextLab(this,axis,textlab) \ -astINVOKE(V,astSetTextLab_(astCheckPlot(this),axis,textlab,STATUS_PTR)) -#define astTestTextLab(this,axis) \ -astINVOKE(V,astTestTextLab_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearLabelUnits(this,axis) \ -astINVOKE(V,astClearLabelUnits_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetLabelUnits(this,axis) \ -astINVOKE(V,astGetLabelUnits_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetLabelUnits(this,axis,labelunits) \ -astINVOKE(V,astSetLabelUnits_(astCheckPlot(this),axis,labelunits,STATUS_PTR)) -#define astTestLabelUnits(this,axis) \ -astINVOKE(V,astTestLabelUnits_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearStyle(this,axis) \ -astINVOKE(V,astClearStyle_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetStyle(this,axis) \ -astINVOKE(V,astGetStyle_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetStyle(this,axis,style) \ -astINVOKE(V,astSetStyle_(astCheckPlot(this),axis,style,STATUS_PTR)) -#define astTestStyle(this,axis) \ -astINVOKE(V,astTestStyle_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearFont(this,axis) \ -astINVOKE(V,astClearFont_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetFont(this,axis) \ -astINVOKE(V,astGetFont_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetFont(this,axis,font) \ -astINVOKE(V,astSetFont_(astCheckPlot(this),axis,font,STATUS_PTR)) -#define astTestFont(this,axis) \ -astINVOKE(V,astTestFont_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearColour(this,axis) \ -astINVOKE(V,astClearColour_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetColour(this,axis) \ -astINVOKE(V,astGetColour_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetColour(this,axis,colour) \ -astINVOKE(V,astSetColour_(astCheckPlot(this),axis,colour,STATUS_PTR)) -#define astTestColour(this,axis) \ -astINVOKE(V,astTestColour_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearWidth(this,axis) \ -astINVOKE(V,astClearWidth_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetWidth(this,axis) \ -astINVOKE(V,astGetWidth_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetWidth(this,axis,width) \ -astINVOKE(V,astSetWidth_(astCheckPlot(this),axis,width,STATUS_PTR)) -#define astTestWidth(this,axis) \ -astINVOKE(V,astTestWidth_(astCheckPlot(this),axis,STATUS_PTR)) - -#define astClearSize(this,axis) \ -astINVOKE(V,astClearSize_(astCheckPlot(this),axis,STATUS_PTR)) -#define astGetSize(this,axis) \ -astINVOKE(V,astGetSize_(astCheckPlot(this),axis,STATUS_PTR)) -#define astSetSize(this,axis,size) \ -astINVOKE(V,astSetSize_(astCheckPlot(this),axis,size,STATUS_PTR)) -#define astTestSize(this,axis) \ -astINVOKE(V,astTestSize_(astCheckPlot(this),axis,STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/plot3d.c b/ast/plot3d.c deleted file mode 100644 index 1bed16c..0000000 --- a/ast/plot3d.c +++ /dev/null @@ -1,8587 +0,0 @@ -/* -*class++ -* Name: -* Plot3D - -* Purpose: -* Provide facilities for 3D graphical output. - -* Constructor Function: -c astPlot3D -f AST_PLOT3D - -* Description: -* A Plot3D is a specialised form of Plot that provides facilities -* for producing 3D graphical output, including fully annotated 3D -* coordinate grids. The base Frame in a Plot3D describes a 3-dimensional -* "graphical" coordinate system. The axes of this coordinate system are -* assumed to be right-handed (that is, if X appears horizontally to the -* right and Y vertically upwards, then Z is out of the screen towards -* the viewer), and are assumed to be equally scaled (that is, the same -* units are used to measure positions on each of the 3 axes). The upper -* and lower bounds of a volume within this graphical coordinate system -* is specified when the Plot3D is created, and all subsequent graphics -* are "drawn" in this volume. -* -* The Plot3D class does not itself include any ability to draw on a -* graphics device. Instead it calls upon function in an externally -* supplied module (the "grf3d" module) to do the required drawing. -* A module should be written that implements the functions of the -* grf3d interface using the facilities of a specific graphics system -* This module should then be linked into the application so that the -* Plot3D class can use its functions (see the description of the -* ast_link commands for details of how to do this). The grf3d interface -* defines a few simple functions for drawing primitives such as straight -* lines, markers and character strings. These functions all accept -* positions in the 3D graphics coordinate system (the base Frame of the -* Plot3D), and so the grf3d module must also manage the projection of -* these 3D coordinates onto the 2D viewing surface, including the choice -* of "eye"/"camera" position, direction of viewing, etc. The AST -* library includes a sample implementation of the grf3d interface -* based on the PGPLOT graphics system (see file grf3d_pgplot.c). This -* implementation also serves to document the grf3d interface itself and -* should be consulted for details before writing a new implementation. -* -* The current Frame of a Plot3D describes a "physical" 3-dimensional -* coordinate system, which is the coordinate system in which plotting -* operations are specified when invoking the methods of the Plot3D -* class. The results of each plotting operation are automatically -* transformed into 3D graphical coordinates before being plotted -* using the facilities of the grf3d module linked into the application. -* Note, at least one of the three axes of the current Frame must be -* independent of the other two current Frame axes. -* -* You may select different physical coordinate systems in which to -* plot (including the native graphical coordinate system itself) -* by selecting different Frames as the current Frame of a Plot3D, -* using its Current attribute. -* -* Like any FrameSet, a Plot3D may also be used as a Frame. In this -* case, it behaves like its current Frame, which describes the -* physical coordinate system. -* -* When used as a Mapping, a Plot3D describes the inter-relation -* between 3D graphical coordinates (its base Frame) and 3D physical -* coordinates (its current Frame). -* -* Although the Plot3D class inherits from the Plot class, several of -* the facilities of the Plot class are not available in the Plot3D -* class, and an error will be reported if any attempt is made to use -* them. Specifically, the Plot3D class does not support clipping -* using the -* astClip function. -f AST_CLIP routine. -* Nor does it support the specification of graphics primitive functions -* at run-time using the -c astGrfSet, astGrfPop, astGrfPush and astGetGrfContext functions. -f AST_GRFSET, AST_GRFPOP, AST_GRFPUSH, and AST_GETGRFCONTEXT routines. - -* Inheritance: -* The Plot3D class inherits from the Plot class. - -* Attributes: -* In addition to those attributes common to all Plots, every -* Plot3D also has the following attributes: -* -* - Norm: Normal vector defining the 2D plane used for text and markers -* - RootCorner: Specifies which edges of the 3D box should be annotated. -* -* Some attributes of the Plot class refer to specific physical -* coordinate axes (e.g. Gap, LabelUp, DrawAxes, etc). For a basic -* Plot, the axis index must be 1 or 2, but for a Plot3D the axis index -* can be 1, 2 or 3. -* -* Certain Plot attributes are ignored by the Plot3D class (e.g. Edge, -* DrawTitle, TitleGap, etc). Consult the Plot attribute documentation -* for details. All other Plot attributes can be set for a specific -* plane of the 3-d plot by appending one of the strings "_XY", "_XZ" -* or "_YZ" to the end of the Plot attribute name. For instance, -* "Grid_YZ" refers to the "Grid" attribute for the plane spanning -* the second (Y) and third (Z) axes of the 3-d plot. - - -* Functions: -c The Plot3D class does not define any new functions beyond those -f The Plot3D class does not define any new routines beyond those -* which are applicable to all Plots. Note, however, that the -* following methods inherited from the Plot class cannot be used with -* a Plot3D and will report an error if called: -c - astBoundingBox, astClip, astCurve, astGenCurve, -c astGetGrfContext, astGrfPop, astGrfPush, astGrfSet, astGridLine, -c astPolyCurve. -f - AST_BOUNDINGBOX, AST_CLIP, AST_CURVE, AST_GENCURVE, -f AST_GETGRFCONTEXT, AST_GRFPOP, AST_GRFPUSH, AST_GRFSET, -f AST_GRIDLINE, AST_POLYCURVE. - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 6-JUN-2007 (DSB): -* Original version. -* 6-SEP-2007 (DSB): -* Re-code the astGrid function. -* 12-NOV-2007 (DSB): -* Clear up compiler warnings. -* 4-MAY-2012 (DSB): -* Avoid segvio in Grid if no ticks are drawn. -* 21-MAY-2012 (DSB): -* In astLoadPlot3D, do not call SetRootCorner as it requires an -* active graphics system to be present which may not yet have been -* established. Also establish the grf routines to be used. -* 5-OCT-2015 (DSB): -* Allow Plot attributes to be set for specific planes. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Plot3D - -/* Integers identifying the 3 plotting surfaces */ -#define XY 1 -#define XZ 2 -#define YZ 3 - -/* Integers identifying the 8 corners of the graphics cube. */ -#define LLL 0 -#define ULL 1 -#define LUL 2 -#define UUL 3 -#define LLU 4 -#define ULU 5 -#define LUU 6 -#define UUU 7 - -/* Identify the 4 edges of a Plot */ -#define LEFT 0 -#define TOP 1 -#define RIGHT 2 -#define BOTTOM 3 - -/* A macros that returns a pointer to the Plot that spans a given plane. */ -#define GET_PLOT(plane) ( \ - ( plane == XY ) ? this->plotxy : ( \ - ( plane == XZ ) ? this->plotxz : ( \ - ( plane == YZ ) ? this->plotyz : NULL ) ) ) - - -/* -* -* Name: -* MAKE_CLEAR3 - -* Purpose: -* Implement a method to clear a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_CLEAR3(attr,component,assign,nval) - -* Class Membership: -* Defined by the Plot3D class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstPlot *this, int axis ) -* -* and an external interface function of the form: -* -* void astClear_( AstPlot *this, int axis ) -* -* which implement a method for clearing a single value in a specified -* multi-valued attribute for an axis of a Plot3D. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. LabelAt in "astClearLabelAt"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR3(attr,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstPlot3D *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astClear" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Assign the "clear" value. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attr##_( AstPlot3D *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,Plot3D,Clear##attr))( this, axis, status ); \ -} - - -/* -* -* Name: -* MAKE_GET3 - -* Purpose: -* Implement a method to get a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_GET3(attr,type,bad_value,assign,nval) - -* Class Membership: -* Defined by the Plot3D class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( AstPlot3D *this, int axis ) -* -* and an external interface function of the form: -* -* astGet_( AstPlot3D *this, int axis ) -* -* which implement a method for getting a single value from a specified -* multi-valued attribute for an axis of a Plot3D. - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. This can -* use the string "axis" to represent the zero-based value index. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET3(attr,type,bad_value,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attr( AstPlot3D *this, int axis, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Initialise */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astGet" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -type astGet##attr##_( AstPlot3D *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,Plot3D,Get##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_SET3 - -* Purpose: -* Implement a method to set a single value in a multi-valued attribute -* for a Plot3D. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_SET3(attr,type,component,assign,nval) - -* Class Membership: -* Defined by the Plot3D class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstPlot3D *this, int axis, value ) -* -* and an external interface function of the form: -* -* void astSet_( AstPlot3D *this, int axis, value ) -* -* which implement a method for setting a single value in a specified -* multi-valued attribute for a Plot3D. - -* Parameters: -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. LabelAt in "astSetLabelAt"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot3D's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET3(attr,type,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstPlot3D *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astSet" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Store the new value in the structure component. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attr##_( AstPlot3D *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,Plot3D,Set##attr))( this, axis, value, status ); \ -} - -/* -* -* Name: -* MAKE_TEST3 - -* Purpose: -* Implement a method to test if a single value has been set in a -* multi-valued attribute for a class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_TEST3(attr,assign,nval) - -* Class Membership: -* Defined by the Plot3D class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static int Test( AstPlot3D *this, int axis ) -* -* and an external interface function of the form: -* -* int astTest_( AstPlot3D *this, int axis ) -* -* which implement a method for testing if a single value in a specified -* multi-valued attribute has been set for a class. - -* Parameters: -* attr -* The name of the attribute to be tested, as it appears in the function -* name (e.g. LabelAt in "astTestLabelAt"). -* assign -* An expression that evaluates to 0 or 1, to be used as the returned -* value. This can use the string "axis" to represent the zero-based -* index of the value within the attribute. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_TEST3(attr,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static int Test##attr( AstPlot3D *this, int axis, int *status ) { \ - int result; /* Value to return */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astTest" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -int astTest##attr##_( AstPlot3D *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,Plot3D,Test##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_CLEAR2 - -* Purpose: -* Implement a method to clear an element-specific attribute inherited -* from the Plot class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_CLEAR2(attr) - -* Class Membership: -* Defined by the Plot3d class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstPlot *this, int element ) -* -* which implements a method for clearing one of the element-specific -* attributes (e.g. Size, Colour, Width, etc) inherited from the -* parent Plot class. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. LabelAt in "astClearSize"). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR2(attr) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstPlot *this_plot, int element, int *status ) { \ -\ -/* Local Variables: */ \ - AstPlot3D *this; \ - int axis3d; \ - int elem2d1; \ - int elem2d2; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Clear the attribute value in the parent Plot structure. */ \ - (*parent_clear##attr)( this_plot, element, status ); \ -\ -/* If OK, clear the attribute in the encapsulated Plots. */ \ - if( astOK ) { \ - this = (AstPlot3D *) this_plot; \ -\ -/* Get the zero-based index of the 3D axis to which the supplied element \ - refers. Use an index of -1 to indicate that the element does not \ - relate to a specific axis. Also get the corresponding elements to use \ - with the two Plots that share the specified 3D axis. */ \ - axis3d = Element2D( this, element, &elem2d1, &elem2d2, status ); \ -\ -/* If the element is not axis-specific, clear the attribute value in all \ - three plots. */ \ - if( axis3d == -1 ) { \ - astClear##attr( this->plotxy, element ); \ - astClear##attr( this->plotxz, element ); \ - astClear##attr( this->plotyz, element ); \ -\ -/* Otherwise, clear the attribute in the two plots that share the \ - specified 3D axis. */ \ - } else { \ - astClear##attr( GET_PLOT(this->axis_plot1[ axis3d ]), elem2d1 ); \ - astClear##attr( GET_PLOT(this->axis_plot2[ axis3d ]), elem2d2 ); \ - } \ - } \ -} - -/* -* -* Name: -* MAKE_SET2 - -* Purpose: -* Implement a method to set an element-specific attribute inherited -* from the Plot class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_SET2(attr,type) - -* Class Membership: -* Defined by the Plot3d class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstPlot *this, int element, type value ) -* -* which implements a method for setting one of the element-specific -* attributes (e.g. Size, Colour, Width, etc) inherited from the -* parent Plot class. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. LabelAt in "astClearSize"). -* type -* The attribute data type. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_SET2(attr,type) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstPlot *this_plot, int element, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstPlot3D *this; \ - int axis3d; \ - int elem2d1; \ - int elem2d2; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Set the attribute value in the parent Plot structure. */ \ - (*parent_set##attr)( this_plot, element, value, status ); \ -\ -/* If OK, set the attribute in the encapsulated Plots. */ \ - if( astOK ) { \ - this = (AstPlot3D *) this_plot; \ -\ -/* Get the zero-based index of the 3D axis to which the supplied element \ - refers. Use an index of -1 to indicate that the element does not \ - relate to a specific axis. Also get the corresponding elements to use \ - with the two Plots that share the specified 3D axis. */ \ - axis3d = Element2D( this, element, &elem2d1, &elem2d2, status ); \ -\ -/* If the element is not axis-specific, clear the attribute value in all \ - three plots. */ \ - if( axis3d == -1 ) { \ - astSet##attr( this->plotxy, element, value ); \ - astSet##attr( this->plotxz, element, value ); \ - astSet##attr( this->plotyz, element, value ); \ -\ -/* Otherwise, clear the attribute in the two plots that share the \ - specified 3D axis. */ \ - } else { \ - astSet##attr( GET_PLOT(this->axis_plot1[ axis3d ]), elem2d1, value ); \ - astSet##attr( GET_PLOT(this->axis_plot2[ axis3d ]), elem2d2, value ); \ - } \ - } \ -} - - -/* -* -* Name: -* MAKE_CLEAR1 - -* Purpose: -* Implement a method to clear an attribute inherited from the Plot class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_CLEAR1(attr) - -* Class Membership: -* Defined by the Plot3d class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstPlot *this ) -* -* which implements a method for clearing a Plot3D attribute inherited -* from the parent Plot class. It clears the attribute in all three -* plots encapsulated within the Plot3D. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. LabelAt in "astClearLabelAt"). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR1(attr) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstPlot *this_plot, int *status ) { \ -\ -/* Local Variables: */ \ - AstPlot3D *this; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Clear the attribute value in the parent Plot structure. */ \ - (*parent_clear##attr)( this_plot, status ); \ -\ -/* If OK, clear the attribute in all three of the encapsulated Plots. */ \ - if( astOK ) { \ - this = (AstPlot3D *) this_plot; \ - astClear##attr( this->plotxy ); \ - astClear##attr( this->plotxz ); \ - astClear##attr( this->plotyz ); \ - } \ -} - -/* -* -* Name: -* MAKE_SET1 - -* Purpose: -* Implement a method to set an attribute inherited from the Plot class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_SET1(attr,type) - -* Class Membership: -* Defined by the Plot3d class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstPlot *this, type value ) -* -* which implements a method for setting a Plot3D attribute inherited -* from the parent Plot class. It sets the attribute in all three -* plots encapsulated within the Plot3D. - -* Parameters: -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. LabelAt in "astSetLabelAt"). -* type -* The C data type for the attribute value. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_SET1(attr,type) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstPlot *this_plot, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstPlot3D *this; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Set the attribute value in the parent Plot structure. */ \ - (*parent_set##attr)( this_plot, value, status ); \ -\ -/* If OK, set the attribute in all three of the encapsulated Plots. */ \ - if( astOK ) { \ - this = (AstPlot3D *) this_plot; \ - astSet##attr( this->plotxy, value ); \ - astSet##attr( this->plotxz, value ); \ - astSet##attr( this->plotyz, value ); \ - } \ -} - -/* -* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a method to clear an attribute inherited from the Plot class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_CLEAR(attr,whichplots) - -* Class Membership: -* Defined by the Plot3d class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstPlot *this, int axis ) -* -* which implements a method for clearing an axis specific Plot3D -* attribute inherited from the parent Plot class. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. LabelAt in "astClearLabelAt"). -* whichplots -* A value indicating which Plots should be affected. A negative value -* means "all threee plots", a value of zero means "just the two plots -* that touch at the specified axis in 3D space", a positive value -* means "just the Plot that is used to label th 3D axis." - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attr,whichplots) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstPlot *this_plot, int axis, int *status ) { \ -\ -/* Local Variables: */ \ - AstPlot *plot; \ - AstPlot3D *this; \ - int axis2d; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Clear the attribute value in the parent Plot structure. This will \ - validate the axis index. */ \ - (*parent_clear##attr)( this_plot, axis, status ); \ -\ -/* If OK, clear the attribute for the relevant axis, or axes, of the Plots \ - encapsulated inside the Plot3D. First get a pointer to the Plot3D \ - structure. */ \ - if( astOK ) { \ - this = (AstPlot3D *) this_plot; \ -\ -/* If requested clear the attribute in all three Plots. */ \ - if( whichplots < 0 ) { \ - astClear##attr( this->plotxy, axis ); \ - astClear##attr( this->plotxz, axis ); \ - astClear##attr( this->plotyz, axis ); \ -\ -/* Each axis in 3D graphics space is described by two of the encapsulated \ - Plots, but only one of these two Plots is used to generate labels for \ - the axis. Now deal with cases where we are clearing the attribute \ - value in both of the two Plots that describe the axis. */ \ - } else if ( whichplots == 0 ) { \ - if( axis == 0 ) { \ - astClear##attr( this->plotxy, 0 ); \ - astClear##attr( this->plotxz, 0 ); \ -\ - } else if( axis == 1 ) { \ - astClear##attr( this->plotxy, 1 ); \ - astClear##attr( this->plotyz, 0 ); \ -\ - } else { \ - astClear##attr( this->plotxz, 1 ); \ - astClear##attr( this->plotyz, 1 ); \ - } \ -\ -/* Now deal with cases where we are clearing the attribute value only in \ - the Plot that is used to label the axis. */ \ - } else { \ - plot = AxisPlot( this, axis, &axis2d, status ); \ - astClear##attr( plot, axis2d ); \ - } \ - } \ -} - - -/* -* -* Name: -* MAKE_GET - -* Purpose: -* Implement a method to get the value of an attribute inherited from the -* Plot class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot.h" -* MAKE_GET(attr,type,bad_value) - -* Class Membership: -* Defined by the Plot3D class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( AstPlot *this, int axis ) -* -* which implements a method for getting a value for an axis specific -* attribute for a Plot3D. - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET(attr,type,bad_value) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attr( AstPlot *this_plot, int axis, int *status ) { \ -\ -/* Local Variables: */ \ - AstPlot *plot; \ - AstPlot3D *this; \ - int axis2d; \ - type result; \ -\ -/* Initialise */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* See if the attribute value is set in the parent Plot structure. If so, \ - use the parent get method to get its value. */ \ - if( astTest##attr( this_plot, axis ) ) { \ - result = (*parent_get##attr)( this_plot, axis, status ); \ -\ -/* If the attribute value is not set in the parent Plot structure, get \ - the default value from the Plot that is used to label the 3D axis. The \ - parent test method called above will have reported an error if the axis \ - index is invalid, so check astOK here. */ \ - } else if( astOK ) { \ - this = (AstPlot3D *) this_plot; \ - plot = AxisPlot( this, axis, &axis2d, status ); \ - result = astGet##attr( plot, axis2d ); \ - } \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* -* Name: -* MAKE_SET - -* Purpose: -* Implement a method to set a value for an attribute inherited from the -* Plot class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot3d.h" -* MAKE_SET(attr,type,whichplots) - -* Class Membership: -* Defined by the Plot3d class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstPlot *this, int axis, value ) -* -* which implements a method for setting a value for an axis specific -* attribute inherited from the parent Plot class. - -* Parameters: -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. LabelAt in "astSetLabelAt"). -* type -* The C type of the attribute. -* whichplots -* A value indicating which Plots should be affected. A negative value -* means "all threee plots", a value of zero means "just the two plots -* that touch at the specified axis in 3D space", a positive value -* means "just the Plot that is used to label the 3D axis." - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET(attr,type,whichplots) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstPlot *this_plot, int axis, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstPlot3D *this; \ - AstPlot *plot; \ - int axis2d; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Set the supplied value in the parent Plot class. This will validate \ - the axis index. */ \ - (*parent_set##attr)( this_plot, axis, value, status ); \ -\ -/* If this went OK, also set the value for the appropriate axis of the \ - appropriate encapsulated Plot(s). First get a pointer to the Plot3D \ - structure. */ \ - if( astOK ) { \ - this = (AstPlot3D *) this_plot; \ -\ -/* If requested set the attribute in all three Plots. */ \ - if( whichplots < 0 ) { \ - astSet##attr( this->plotxy, axis, value ); \ - astSet##attr( this->plotxz, axis, value ); \ - astSet##attr( this->plotyz, axis, value ); \ -\ -/* Each axis in 3D graphics space is described by two of the encapsulated \ - Plots, but only one of these two Plots is used to generate labels for \ - the axis. First deal with cases where we are setting the attribute \ - value in both of the two Plots that describe the axis. */ \ - } else if( whichplots == 0 ) { \ - if( axis == 0 ) { \ - astSet##attr( this->plotxy, 0, value ); \ - astSet##attr( this->plotxz, 0, value ); \ -\ - } else if( axis == 1 ) { \ - astSet##attr( this->plotxy, 1, value ); \ - astSet##attr( this->plotyz, 0, value ); \ -\ - } else { \ - astSet##attr( this->plotxz, 1, value ); \ - astSet##attr( this->plotyz, 1, value ); \ - } \ -\ -/* Now deal with cases where we are setting the attribute value only in \ - the Plot that is used to label the axis. */ \ - } else { \ - plot = AxisPlot( this, axis, &axis2d, status ); \ - astSet##attr( plot, axis2d, value ); \ - } \ - } \ -} - - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "cmpframe.h" /* Compound Frames */ -#include "cmpmap.h" /* Compound Mappings */ -#include "unitmap.h" /* Unit mappings */ -#include "permmap.h" /* Axis permutations */ -#include "winmap.h" /* Scale and shift mappings */ -#include "frame.h" /* Coordinate systems */ -#include "frameset.h" /* Inter-related coordinate systems */ -#include "keymap.h" /* Hash array */ -#include "plot.h" /* Interface definition for parent class */ -#include "plot3d.h" /* Interface definition for this class */ -#include "grf3d.h" /* The grf3D interface */ -#include "pointset.h" /* Sets of points */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are used or extended by this - class. */ -static AstObject *(* parent_cast)( AstObject *, AstObject *, int * ); -static void (* parent_removeframe)( AstFrameSet *, int, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); -static int (* parent_equal)( AstObject *, AstObject *, int * ); -static void (* parent_vset)( AstObject *, const char *, char **, va_list, int * ); -static void (* parent_clear)( AstObject *, const char *, int * ); -static void (* parent_clearcurrent)( AstFrameSet *, int * ); -static void (* parent_setcurrent)( AstFrameSet *, int, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -/* A FrameSet pointer that is used when calling astCast. */ -static AstFrameSet *dummy_frameset = NULL; - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Plot3D) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Plot3D,Class_Init) -#define class_vtab astGLOBAL(Plot3D,Class_Vtab) -#define getattrib_buff astGLOBAL(Plot3D,GetAttrib_Buff) - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -static pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX3 pthread_mutex_lock( &mutex3 ); -#define UNLOCK_MUTEX3 pthread_mutex_unlock( &mutex3 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPlot3DVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#define LOCK_MUTEX3 -#define UNLOCK_MUTEX3 - -#endif - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstFrameSet *Fset3D( AstFrameSet *, int, int * ); -static AstKeyMap *GetGrfContext( AstPlot *, int * ); -static AstObject *Cast( AstObject *, AstObject *, int * ); -static AstPlot *AxisPlot( AstPlot3D *, int, int *, int * ); -static AstPointSet *ExtendTicks( AstPlot *, AstPointSet *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *RootCornerString( int, int * ); -static int Attr3D( AstKeyMap *, int, double, double *, int, int * ); -static int Border( AstPlot *, int * ); -static int Element2D( AstPlot3D *, int, int *, int *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetObjSize( AstObject *, int * ); -static int Plot3DAttr( AstKeyMap *, int, double, double *, int ); -static int Plot3DCap( AstKeyMap *, int, int ); -static int Plot3DFlush( AstKeyMap * ); -static int Plot3DLine( AstKeyMap *, int, const float *, const float * ); -static int Plot3DMark( AstKeyMap *, int, const float *, const float *, int ); -static int Plot3DQch( AstKeyMap *, float *, float * ); -static int Plot3DScales( AstKeyMap *, float *, float * ); -static int Plot3DText( AstKeyMap *, const char *, float, float, const char *, float, float ); -static int Plot3DTxExt( AstKeyMap *, const char *, float, float, const char *, float, float, float *, float * ); -static int RootCornerInt( const char *, int * ); -static void BoundingBox( AstPlot *, float[2], float[2], int * ); -static void ChangeRootCorner( AstPlot3D *, int, int, int * ); -static void Clear( AstObject *, const char *, int * ); -static void ClearCurrent( AstFrameSet *, int * ); -static void Clip( AstPlot *, int, const double [], const double [], int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void CreatePlots( AstPlot3D *, AstFrameSet *, const float *, const double *, int * ); -static void Curve( AstPlot *, const double [], const double [], int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void GenCurve( AstPlot *, AstMapping *, int * ); -static void GrfPop( AstPlot *, int * ); -static void GrfPush( AstPlot *, int * ); -static void GrfSet( AstPlot *, const char *, AstGrfFun, int * ); -static void Grid( AstPlot *, int * ); -static void GridLine( AstPlot *, int, const double [], double, int * ); -static void Mark( AstPlot *, int, int, int, const double *, int, int * ); -static void PolyCurve( AstPlot *, int, int, int, const double *, int * ); -static void RemoveFrame( AstFrameSet *, int, int * ); -static void Set3DGrf( AstPlot3D *, AstPlot *, int, int * ); -static void SetCurrent( AstFrameSet *, int, int * ); -static void SetPlotAttr( AstPlot *, int, int[ 2 ], int * ); -static void SetTickValues( AstPlot *, int, int, double *, int, double *, int * ); -static void SplitFrameSet( AstFrameSet *, AstFrameSet **, int[2], int[2], AstFrameSet **, int[2], int[2], AstFrameSet **, int[2], int[2], int *, int * ); -static void StoreAxisInfo( AstPlot3D *, int[2], int[2], int[2], int[2], int[2], int[2], int * ); -static void Text( AstPlot *, const char *, const double [], const float [2], const char *, int * ); -static void UpdatePlots( AstPlot3D *, int * ); -static void VSet( AstObject *, const char *, char **, va_list, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Declare private member functions that access Plot3D attributes. - --------------------------------------------------------------*/ - -/* Axis independent... */ - -#define DECLARE_PLOT3D_ACCESSORS(attr,type) \ - static type Get##attr(AstPlot3D *,int *); \ - static void Set##attr(AstPlot3D *,type,int *); \ - static void Clear##attr(AstPlot3D *,int *); \ - static int Test##attr(AstPlot3D *,int *); - -DECLARE_PLOT3D_ACCESSORS(RootCorner,int) - -#undef DECLARE_PLOT3D_ACCESSORS - - -/* Axis specific... */ - -#define DECLARE_PLOT3D_ACCESSORS(attr,type) \ - static type Get##attr(AstPlot3D *,int,int *); \ - static void Set##attr(AstPlot3D *,int,type,int *); \ - static void Clear##attr(AstPlot3D *,int,int *); \ - static int Test##attr(AstPlot3D *,int,int *); - -DECLARE_PLOT3D_ACCESSORS(Norm,double) - -#undef DECLARE_PLOT3D_ACCESSORS - - -/* Declare private member functions that access axis-specific attributes - inherited from the Plot class. Also declare pointers to hold the parent - function pointers. - ----------------------------------------------------------------------*/ - -#define DECLARE_PLOT_ACCESSORS(attr,type) \ - static type Get##attr(AstPlot *,int,int *); \ - static void Set##attr(AstPlot *,int,type,int *); \ - static void Clear##attr(AstPlot *,int,int *); \ - static type (*parent_get##attr)(AstPlot *,int,int *); \ - static void (*parent_set##attr)(AstPlot *,int,type,int *); \ - static void (*parent_clear##attr)(AstPlot *,int,int *); - -DECLARE_PLOT_ACCESSORS(MinTick,int) -DECLARE_PLOT_ACCESSORS(Abbrev,int) -DECLARE_PLOT_ACCESSORS(Gap,double) -DECLARE_PLOT_ACCESSORS(LogGap,double) -DECLARE_PLOT_ACCESSORS(LogPlot,int) -DECLARE_PLOT_ACCESSORS(LogTicks,int) -DECLARE_PLOT_ACCESSORS(LogLabel,int) -DECLARE_PLOT_ACCESSORS(LabelUp,int) -DECLARE_PLOT_ACCESSORS(DrawAxes,int) -DECLARE_PLOT_ACCESSORS(LabelUnits,int) -DECLARE_PLOT_ACCESSORS(MinTickLen,double) -DECLARE_PLOT_ACCESSORS(MajTickLen,double) -DECLARE_PLOT_ACCESSORS(NumLab,int) -DECLARE_PLOT_ACCESSORS(NumLabGap,double) -DECLARE_PLOT_ACCESSORS(TextLab,int) -DECLARE_PLOT_ACCESSORS(TextLabGap,double) - -#undef DECLARE_PLOT_ACCESSORS - - -/* Declare private member functions that access element-specific attributes - inherited from the Plot class. Also declare pointers to hold the parent - function pointers. - ----------------------------------------------------------------------*/ - -#define DECLARE_PLOT_ACCESSORS(attr,type) \ - static void Set##attr(AstPlot *,int,type,int *); \ - static void Clear##attr(AstPlot *,int,int *); \ - static void (*parent_set##attr)(AstPlot *,int,type,int *); \ - static void (*parent_clear##attr)(AstPlot *,int,int *); - -DECLARE_PLOT_ACCESSORS(Style,int) -DECLARE_PLOT_ACCESSORS(Font,int) -DECLARE_PLOT_ACCESSORS(Colour,int) -DECLARE_PLOT_ACCESSORS(Width,double) -DECLARE_PLOT_ACCESSORS(Size,double) - -#undef DECLARE_PLOT_ACCESSORS - - -/* Declare private member functions that access attributes inherited from - the Plot class that do not need to override the Get method. This - includes attributes that are not axis-specific or that do not have - dynamic defaults. Also declare pointers to hold the parent function - pointers. - ----------------------------------------------------------------------*/ -#define DECLARE_PLOT_ACCESSORS(attr,type) \ - static void Set##attr(AstPlot *,type,int *); \ - static void Clear##attr(AstPlot *,int *); \ - static void (*parent_set##attr)(AstPlot *,type,int *); \ - static void (*parent_clear##attr)(AstPlot *,int *); - -DECLARE_PLOT_ACCESSORS(Ink,int) -DECLARE_PLOT_ACCESSORS(Tol,double) -DECLARE_PLOT_ACCESSORS(Invisible,int) -DECLARE_PLOT_ACCESSORS(TickAll,int) -DECLARE_PLOT_ACCESSORS(ForceExterior,int) -DECLARE_PLOT_ACCESSORS(Border,int) -DECLARE_PLOT_ACCESSORS(Clip,int) -DECLARE_PLOT_ACCESSORS(ClipOp,int) -DECLARE_PLOT_ACCESSORS(Escape,int) -DECLARE_PLOT_ACCESSORS(Grid,int) -DECLARE_PLOT_ACCESSORS(Labelling,int) - -#undef DECLARE_PLOT_ACCESSORS - - - -/* Member functions. */ -/* ================= */ - -static int Attr3D( AstKeyMap *grfconID, int attr, double value, - double *old_value, int prim, int *status ){ -/* -* Name: -* Attr3D - -* Purpose: -* Get or set the value of a 3D grf attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* Attr3D( AstKeyMap *grfconID, int attr, double value, double *old_value, -* int prim, int *status ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function gets or sets the current value of a specified graphics -* attribute in the parent Plot structure of a Plot3D. It forwards the -* call to the grf3D module being used by this Plot3D. It should be -* registered with the parent Plot using astGrfSet. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. -* attr -* An integer value identifying the required attribute. This should -* be one of the symbolic values defined in grf.h. -* value -* A new value to store for the attribute. If this is AST__BAD -* no value is stored. -* old_value -* A pointer to a double in which to return the attribute value. -* If this is NULL, no value is returned. -* prim -* The sort of graphics primitive to be drawn with the new attribute. -* Identified by one of the values defined in grf.h. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* An integer value of 0 is returned if an error occurs, and 1 otherwise. - -*/ - -/* Local Variables: */ - int result; - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Use the function in the external Grf3D module, selected at link-time - using ast_link options. */ - result = astG3DAttr( attr, value, old_value, prim ); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Return the result. */ - return result; -} - -static AstPlot *AxisPlot( AstPlot3D *this, int axis3d, int *axis2d, int *status ){ -/* -* Name: -* AxisPlot - -* Purpose: -* Find the Plot used to label a 3D axis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* AstPlot *AxisPlot( AstPlot3D *this, int axis3d, int *axis2d, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns a pointer to the encapsulated 2D Plot that -* is used to label the given 3D axis. It also returns the index -* of the labelled axis within the 2D Plot. - -* Parameters: -* this -* Pointer to a Plot3D. -* axis3d -* A zero-based axis index within the Plot3D. -* axis2d -* Pointer to an int in which to put the index of the labelled axis -* within the returned 2D Plot. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Plot used to label the 3D axis. Do not annul this -* pointer. - -*- -*/ - -/* Local Variables: */ - AstPlot *plot; - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Return the required information form the Plot3D structure. */ - plot = GET_PLOT( this->axis_plot1[ axis3d ] ); - if( ! plot ) { - astError( AST__INTER, "AxisPlot(Plot3D): Illegal value %d " - "for axis3d (internal AST programming error).", status, - this->axis_plot1[ axis3d ] ); - } - - *axis2d = this->axis_index1[ axis3d ]; - - return plot; -} - -static int Border( AstPlot *this_plot, int *status ){ -/* -* Name: -* Border - -* Purpose: -* Draw a border around valid regions of a Plot. - -* Type: -* Private member function. - -* Synopsis: -* #include "plot3d.h" -* int Border( AstPlot *this, int *status ) - -* Class Membership: -* Plot method (overrides the astBorder method inherited from the -* Plot class) - -* Description: -* This function draws a (line) border around regions of the -* plotting area of a Plot which correspond to valid, unclipped -* physical coordinates. For example, when plotting using an -* all-sky map projection, this function could be used to draw the -* boundary of the celestial sphere when it is projected on to the -* plotting surface. -* -* If the entire plotting area contains valid, unclipped physical -* coordinates, then the boundary will just be a rectangular box -* around the edges of the plotting area. - -* Parameters: -* this -* Pointer to the Plot. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the plotting area is completely filled by -* valid, unclipped physical coordinates (so that only a -* rectangular box was drawn around the edge). Otherwise, one is -* returned. - -* Notes: -* - The Plot3D implementation of this method, invokes the astBorder -* method on each of the three encapsulated Plots, and returns the -* logical OR of the three returned flags. -* - A value of zero will be returned if this function is invoked -* with the AST error status set, or if it should fail for any -* reason. -* - An error results if either the current Frame or the base Frame -* of the Plot is not 2-dimensional, or (for a Plot3D) 3-dimensional. -* - An error also results if the transformation between the base -* and current Frames of the Plot is not defined (i.e. the Plot's -* TranForward attribute is zero). -*/ - -/* Local Variables: */ - AstPlot3D *this; - const char *class; - const char *method; - float x1; - float y1; - float z1; - float x[ 2 ]; - float y[ 2 ]; - float z[ 2 ]; - int flag1; - int flag2; - int flag3; - int naxes; - int ok; - int result; - int root_corner; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_plot; - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astBorder"; - class = astGetClass( this ); - -/* Check the base Frame of the Plot is 3-D. */ - naxes = astGetNin( this ); - if( naxes != 3 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 3.", status, method, class, naxes, class ); - } - -/* Check the current Frame of the Plot is 3-D. */ - naxes = astGetNout( this ); - if( naxes != 3 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the current " - "Frame of the supplied %s is invalid - this number should " - "be 3.", status, method, class, naxes, class ); - } - -/* Invoke the astBorder method on each of the three encapsulated Plots. */ - flag1 = astBorder( this->plotxy ); - flag2 = astBorder( this->plotxz ); - flag3 = astBorder( this->plotyz ); - -/* If no bad values were encountered in any of the Plots, draw lines - along the remaining plot edges. */ - result = ( flag1 || flag2 || flag3 ); - if( !result ) { - -/* The three remaining edges to be drawn all meet at the corner - diagonally opposite the root corner. Get the root corner. */ - root_corner = astGetRootCorner( this ); - -/* The (x0,y0,z0) position is the graphics coords at the corner - diagonally opposite the root corner. The x1, y1 and z1 values - are the graphics x, y and z values at the ends of the three - lines that remain to be drawn. */ - if( root_corner & 1 ) { - x[ 0 ] = this->gbox[ 0 ]; - x1 = this->gbox[ 3 ]; - } else { - x[ 0 ] = this->gbox[ 3 ]; - x1 = this->gbox[ 0 ]; - } - - if( root_corner & 2 ) { - y[ 0 ] = this->gbox[ 1 ]; - y1 = this->gbox[ 4 ]; - } else { - y[ 0 ] = this->gbox[ 4 ]; - y1 = this->gbox[ 1 ]; - } - - if( root_corner & 4 ) { - z[ 0 ] = this->gbox[ 2 ]; - z1 = this->gbox[ 5 ]; - } else { - z[ 0 ] = this->gbox[ 5 ]; - z1 = this->gbox[ 2 ]; - } - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__BORDER_ID, 1, GRF__LINE, method, class ); - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Draw the remaining line parallel to the X axis. */ - x[ 1 ] = x1; - y[ 1 ] = y[ 0 ]; - z[ 1 ] = z[ 0 ]; - ok = astG3DLine( 2, x, y, z ); - -/* Draw the remaining line parallel to the Y axis. */ - x[ 1 ] = x[ 0 ]; - y[ 1 ] = y1; - z[ 1 ] = z[ 0 ]; - ok = ok && astG3DLine( 2, x, y, z ); - -/* Draw the remaining line parallel to the X axis. */ - x[ 1 ] = x[ 0 ]; - y[ 1 ] = y[ 0 ]; - z[ 1 ] = z1; - ok = ok && astG3DLine( 2, x, y, z ); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__BORDER_ID, 0, GRF__LINE, method, class ); - -/* Report an error if anything went wrong in the grf3d module. */ - if( !ok && astOK ) { - astError( AST__GRFER, "%s(%s): Graphics error in astG3DLine. ", status, - method, class ); - } - } - -/* Return zero if an error has occurrred. */ - if( !astOK ) result = 0; - -/* Return a flag indicating if any bad values were encountered in any of - the Plots. */ - return result; -} - -static AstObject *Cast( AstObject *this_object, AstObject *obj, int *status ) { -/* -* Name: -* Cast - -* Purpose: -* Cast an Object into an instance of a sub-class. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* AstObject *Cast( AstObject *this, AstObject *obj, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the protected astCast -* method inherited from the Frame class). - -* Description: -* This function returns a deep copy of an ancestral component of the -* supplied object. The required class of the ancestral component is -* specified by another object. Specifically, if "this" and "new" are -* of the same class, a copy of "this" is returned. If "this" is an -* instance of a subclass of "obj", then a copy of the component -* of "this" that matches the class of "obj" is returned. Otherwise, -* a NULL pointer is returned without error. - -* Parameters: -* this -* Pointer to the Object to be cast. -* obj -* Pointer to an Object that defines the class of the returned Object. -* The returned Object will be of the same class as "obj". - -* Returned Value: -* A pointer to the new Object. NULL if "this" is not a sub-class of -* "obj", or if an error occurs. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables; */ - AstObject *new; - astDECLARE_GLOBALS - int generation_gap; - -/* Initialise */ - new = NULL; - -/* Check inherited status */ - if( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* See how many steps up the class inheritance ladder it is from "obj" - to this class (Plot3D). A positive value is returned if Plot3D - is a sub-class of "obj". A negative value is returned if "obj" is - a sub-class of Plot3D. Zero is returned if "obj" is a Plot3D. - AST__COUSIN is returned if "obj" is not on the same line of descent - as Plot3D. */ - generation_gap = astClassCompare( (AstObjectVtab *) &class_vtab, - astVTAB( obj ) ); - -/* If "obj" is a Plot3D or a sub-class of Plot3D, we can cast by - truncating the vtab for "this" so that it matches the vtab of "obJ", - and then taking a deep copy of "this". */ - if( generation_gap <= 0 && generation_gap != AST__COUSIN ) { - new = astCastCopy( this_object, obj ); - -/* If "obj" is a Plot (the parent class), we cast by returning a deep - copy of the Plot covering the XY face. */ - } else if( generation_gap == 1 ) { - new = astCopy( ( (AstPlot3D *) this_object)->plotxy ); - -/* If "obj" is a FrameSet or higher, we attempt to use the implementation - inherited from the parent class to cast the FrameSet component into the - class indicated by "obj". */ - } else { - new = (*parent_cast)( this_object, obj, status ); - } - -/* Return the new pointer. */ - return new; -} - -static void ChangeRootCorner( AstPlot3D *this, int old, int new, int *status ){ -/* -* Name: -* ChangeRootCorner - -* Purpose: -* Use a new RootCorner value. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void ChangeRootCorner( AstPlot3D *this, int old, int new, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function sets the attributes of the encapsulated Plots so that -* labels appear on the edges of the 3D graphics cube that join at the -* specified new root corner. It also reverses the graphics axes in -* the encapsulated Plots as required in order to ensure that the Plots -* look "normal" when viewed from the outside of the 3D graphics cube. -* This happens if a the Plot used to label a specific axis moves from -* one face the the 3D graphics cube to the opposite face. - -* Parameters: -* this -* Pointer to a Plot3D. -* old -* The old RootCorner value. -* new -* The new RootCorner value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Each RootCorner value is in the range 0 to 7 and is a 3 bit -* bit-mask. Bit 0 describes the 3D graphics X axis, bit 1 describes -* the graphics Y axis and bit 2 describes the graphics Z axis. If a -* bit is set it means that the corner is at the upper bound on the -* corresponding axis. If a bit is unset it means that the corner is -* at the lower bound on the corresponding axis. - -*- -*/ - -/* Local Variables: */ - AstKeyMap *grfcon; - AstPlot *plot; - AstPlot *plots[ 24 ]; - int edges[ 24 ]; - int axes[ 24 ]; - int axis2d; - int edge; - int i; - int np; - int xeqy; - int xeqz; - -/* Check the global status. */ - if( !astOK ) return; - -/* If the corner has moved on the 3D X axis (from upper X bound to lower X - bound or vice-versa), mirror the axis of the encapsulated Plot that is - perpendicular to the 3D X axis. This means that the Plot can be thought - of as being viewed from the outside of the 3D graphics cube. Also, - update the constant X axis value at which the YZ plane is drawn. */ - if( ( old & 1 ) != ( new & 1 ) ) astMirror( this->plotyz, 0 ); - grfcon = (AstKeyMap *) astGetGrfContext( this->plotyz ); - astMapPut0D( grfcon, "Gcon", this->gbox[ ( new & 1 ) ? 3 : 0 ], "Constant X value" ); - astMapPut0I( grfcon, "RootCorner", new, "Labelled corner" ); - grfcon= astAnnul( grfcon ); - -/* Likewise mirror the other two axes if required. */ - if( ( old & 2 ) != ( new & 2 ) ) astMirror( this->plotxz, 0 ); - grfcon = (AstKeyMap *) astGetGrfContext( this->plotxz ); - astMapPut0D( grfcon, "Gcon", this->gbox[ ( new & 2 ) ? 4 : 1 ], "Constant Y value" ); - astMapPut0I( grfcon, "RootCorner", new, "Labelled corner" ); - grfcon= astAnnul( grfcon ); - - if( ( old & 4 ) != ( new & 4 ) ) astMirror( this->plotxy, 0 ); - grfcon = (AstKeyMap *) astGetGrfContext( this->plotxy ); - astMapPut0D( grfcon, "Gcon", this->gbox[ ( new & 4 ) ? 5 : 2 ], "Constant Z value" ); - astMapPut0I( grfcon, "RootCorner", new, "Labelled corner" ); - grfcon= astAnnul( grfcon ); - -/* Set a flag saying whether the limits are equal at the new corner for - the X and Y axes. */ - xeqy = ( ( ( new & 1 ) > 0 ) == ( ( new & 2 ) > 0 ) ); - -/* Set a flag saying whether the limits are equal at the new corner for - the X and Z axes. */ - xeqz = ( ( ( new & 1 ) > 0 ) == ( ( new & 4 ) > 0 ) ); - -/* Ensure all Edge attributes are clear. This means that the public - attribute accessors routines used below will return dynamic defaults for - the Edge attributes. */ - astClearEdge( this->plotxy, 0 ); - astClearEdge( this->plotxy, 1 ); - astClearEdge( this->plotxz, 0 ); - astClearEdge( this->plotxz, 1 ); - astClearEdge( this->plotyz, 0 ); - astClearEdge( this->plotyz, 1 ); - -/* So far we have recorded no edges changes. */ - np = 0; - -/* We now adjust the Edge attributes in the Plot used to annotate the 3D - X axis in order to get the X axis labels on the correct edge of the 3D - graphics cube. Get the Plot used to produce X axis labels (this will - be either this->plotxy or this->plotxz). */ - plot = AxisPlot( this, 0, &axis2d, status ); - -/* See what edge of the Plot is used to annotate the first of the two WCS - axis described by the 2D Plot. If the Edge(1) attribute has not been - assigned a value, then a dynamic default will be used by the Plot class. - We want to know what this dynamic default is, so we first cleared the - attribute above. Now we set the attribute value explicitly to the dynamic - default returned by astGetC. Note, we use astGetC rather than astGetEdge - because the dynamic default is not calculated when calling astGetEdge. */ - astSetC( plot, "Edge(1)", astGetC( plot, "Edge(1)" )); - edge = astGetEdge( plot, 0 ); - astClearEdge( plot, 0 ); - -/* If the 3D X axis is labelled using the Plot that spans the XY plane... */ - if( plot == this->plotxy ) { - -/* ... and if the new root corner is at the upper limit on the Y axis... */ - if( new & 2 ) { - -/* If the first WCS axis is currently labelled on either the top or bottom - edge, ensure it is labelled on the upper Y (top) edge. */ - if( edge == 3 || edge == 1 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = TOP; - -/* Otherwise ensure that the second WCS axis is labelled on the upper Y (top) - edge. */ - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = TOP; - } - -/* If the new root corner is at the lower limit on the Y axis... */ - } else { - -/* If the first WCS axis is currently labelled on either the top or bottom - edge, ensure it is labelled on the lower Y (bottom) edge. */ - if( edge == 3 || edge == 1 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = BOTTOM; - -/* Otherwise ensure that the second WCS axis is labelled on the lower Y - (bottom) edge. */ - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = BOTTOM; - } - } - -/* If the 3D X axis is labelled using the Plot that spans the XZ plane... */ - } else { - -/* ... and if the new root corner is at the upper limit on the Z axis... */ - if( new & 4 ) { - -/* If the first WCS axis is currently labelled on either the top or bottom - edge, ensure it is labelled on the upper Z (top) edge. */ - if( edge == 3 || edge == 1 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = TOP; - -/* Otherwise ensure that the second WCS axis is labelled on the upper Y (top) - edge. */ - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = TOP; - } - -/* If the new root corner is at the lower limit on the Z axis... */ - } else { - -/* If the first WCS axis is currently labelled on either the top or bottom - edge, ensure it is labelled on the lower Z (bottom) edge. */ - if( edge == 3 || edge == 1 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = BOTTOM; - -/* Otherwise ensure that the second WCS axis is labelled on the lower Z - (bottom) edge. */ - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = BOTTOM; - } - } - } - -/* We now adjust the Edge attributes in the Plot used to annotate the 3D - Y axis in order to get the Y axis labels on the correct edge of the 3D - graphics cube. Get the Plot used to produce Y axis labels. */ - plot = AxisPlot( this, 1, &axis2d, status ); - -/* See what edge of the Plot is used to annotate the first of the two WCS - axis described by the Plot. */ - astSetC( plot, "Edge(1)", astGetC( plot, "Edge(1)" )); - edge = astGetEdge( plot, 0 ); - astClearEdge( plot, 0 ); - -/* If the 3D Y axis is labelled using the Plot that spans the XY plane... */ - if( plot == this->plotxy ) { - -/* ... and if the new root corner is at the same limit on the X and Z axes, - put Y labels on the right side of the Plot. */ - if( xeqz ) { - if( edge == 0 || edge == 2 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = RIGHT; - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = RIGHT; - } - -/* If the new root corner is at a different limit on the X and Z axes, - put Y labels on the left side of the Plot. */ - } else { - if( edge == 0 || edge == 2 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = LEFT; - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = LEFT; - } - } - -/* If the 3D Y axis is labelled using the Plot that spans the YZ plane... */ - } else { - -/* ... and if the new root corner is at the upper Z limit, put Y labels on - the top of the Plot. */ - if( new & 4 ) { - if( edge == 1 || edge == 3 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = TOP; - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = TOP; - } - -/* If the new root corner is at the lower Z limit, put Y labels on the - bottom of the Plot. */ - } else { - if( edge == 1 || edge == 3 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = BOTTOM; - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = BOTTOM; - } - } - } - -/* We now adjust the Edge attributes in the Plot used to annotate the 3D - Z axis in order to get the Z axis labels on the correct edge of the 3D - graphics cube. Get the Plot used to produce Z axis labels. */ - plot = AxisPlot( this, 2, &axis2d, status ); - -/* See what edge of the Plot is used to annotate the first of the two WCS - axis described by the Plot. */ - astSetC( plot, "Edge(1)", astGetC( plot, "Edge(1)" )); - edge = astGetEdge( plot, 0 ); - astClearEdge( plot, 0 ); - -/* If the 3D Z axis is labelled using the Plot that spans the XZ plane... */ - if( plot == this->plotxz ) { - -/* ... and if the new root corner is at the same limit on the X and Y axes, - put Z labels on the left side of the Plot. */ - if( xeqy ) { - if( edge == 0 || edge == 2 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = LEFT; - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = LEFT; - } - -/* If the new root corner is at a different limit on the X and Y axes, - put Y labels on the right side of the Plot. */ - } else { - if( edge == 0 || edge == 2 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = RIGHT; - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = RIGHT; - } - } - -/* If the 3D Z axis is labelled using the Plot that spans the YZ plane... */ - } else { - -/* ... and if the new root corner is at the same limit on the X and Y axes, - put Z labels on the right side of the Plot. */ - if( xeqz ) { - if( edge == 0 || edge == 2 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = RIGHT; - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = RIGHT; - } - -/* If the new root corner is at a different limit on the X and Y axes, - put Y labels on the left side of the Plot. */ - } else { - if( edge == 0 || edge == 2 ) { - plots[ np ] = plot; - axes[ np ] = 0; - edges[ np++ ] = LEFT; - } else { - plots[ np ] = plot; - axes[ np ] = 1; - edges[ np++ ] = LEFT; - } - } - } - -/* Apply the set of edge changes determined above. */ - for( i = 0; i < np; i++ ) { - astSetEdge( plots[ i ], axes[ i ], edges[ i ] ); - } - -/* Ensure that the 2 Plot axes that are not being used have suitable values - for their attributes. That is, no labels are drawn, and the ticked - edges are the one that meet at the new RootCorner. */ - - if( !astTestEdge( this->plotxy, 0 ) ) { - astSetEdge( this->plotxy, 0, ( new & 2 ) ? TOP : BOTTOM ); - } - - if( !astTestEdge( this->plotxy, 1 ) ) { - astSetEdge( this->plotxy, 1, xeqz ? RIGHT: LEFT ); - } - - if( !astTestEdge( this->plotxz, 0 ) ) { - astSetEdge( this->plotxz, 0, ( new & 4 ) ? TOP : BOTTOM ); - } - - if( !astTestEdge( this->plotxz, 1 ) ) { - astSetEdge( this->plotxz, 1, xeqy ? LEFT : RIGHT ); - } - - if( !astTestEdge( this->plotyz, 0 ) ) { - astSetEdge( this->plotyz, 0, ( new & 4 ) ? TOP : BOTTOM ); - } - - if( !astTestEdge( this->plotyz, 1 ) ) { - astSetEdge( this->plotyz, 1, xeqy ? RIGHT : LEFT ); - } - - -} - -static void Clear( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* Clear - -* Purpose: -* Clear attribute values for a Plot3D. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void Clear( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the public astClear method -* inherited from the Object class). - -* Description: -* This function clears the values of a specified set of attributes -* for a Plot3D. Clearing an attribute cancels any value that has -* previously been explicitly set for it, so that the standard -* default attribute value will subsequently be used instead. This -* also causes the astTest function to return the value zero for -* the attribute, indicating that no value has been set. - -* Parameters: -* this -* Pointer to the Plot3D. -* attrib -* Pointer to a null-terminated character string containing a -* comma-separated list of the names of the attributes to be -* cleared. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function preserves the integrity of the Plot3D (if -* possible) by appropriately modifying the three encapsulated Plots. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent astClear method to clear the Plot3D's attribute values. */ - (*parent_clear)( this_object, attrib, status ); - -/* Update the three 2D Plots stored in the Plot3D structure so that they - reflect this modified FrameSet. */ - UpdatePlots( (AstPlot3D *) this_object, status ); - -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Plot3D. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void ClearAttrib( AstObject *this, const char *attrib ) - -* Class Membership: -* Plot3D member function (over-rides the astClearAttrib protected -* method inherited from the Plot class). - -* Description: -* This function clears the value of a specified attribute for a -* Plot3D, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Plot3D. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -*/ - -/* Local Variables: */ - AstPlot3D *this; /* Pointer to the Plot3D structure */ - AstPlot *plot; /* Pointer to specific Plot */ - char attname[50]; /* Plot attribute base name */ - char patt[50]; /* Plot attribute full name */ - char spec[10]; /* Plane specification */ - int axis; /* Axis index */ - int len; /* Length of attrib string */ - int nc; /* Number of characters read */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Norm. */ -/* ----------- */ - if ( !strcmp( attrib, "norm" ) ) { - astClearNorm( this, 0 ); - astClearNorm( this, 1 ); - astClearNorm( this, 2 ); - -/* Norm(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "norm(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearNorm( this, axis - 1 ); - -/* RootCorner. */ -/* ----------- */ - } else if ( !strcmp( attrib, "rootcorner" ) ) { - astClearRootCorner( this ); - -/* ..._XY etc */ -/* ---------- */ - } else if ( nc = 0, - ( 2 == astSscanf( attrib, "%[a-z]_%[xyz]%n", attname, spec, - &nc ) ) ) { - - if( !strcmp( spec, "xy" ) || !strcmp( spec, "yx" ) ) { - plot = this->plotxy; - } else if( !strcmp( spec, "xz" ) || !strcmp( spec, "zx" ) ) { - plot = this->plotyz; - } else if( !strcmp( spec, "yz" ) || !strcmp( spec, "zy" ) ) { - plot = this->plotxz; - } else { - plot = NULL; - } - - if( plot ) { - sprintf( patt, "%s%s", attname, attrib + nc ); - astClearAttrib( plot, patt ); - - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearCurrent( AstFrameSet *this_frameset, int *status ) { -/* -* Name: -* ClearCurrent - -* Purpose: -* Clear the value of the Current attribute for a Plot3D. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int astClearCurrent( AstFrameSet *this ) - -* Class Membership: -* Plot3D member function (over-rides the public astClearCurrent method -* inherited from the FrameSet class). - -* Description: -* This function clears the value of the Current attribute for a -* Plot3D. This attribute is an index that identifies the current -* Frame for the Plot3D. - -* Parameters: -* this -* Pointer to the Plot3D. -*/ - -/* Invoke the parent astClearCurrent method. */ - (*parent_clearcurrent)( this_frameset, status ); - -/* Update the three 2D Plots stored in the Plot3D structure so that they - reflect this modified FrameSet. */ - UpdatePlots( (AstPlot3D *) this_frameset, status ); -} - -static void ClearRootCorner( AstPlot3D *this, int *status ){ -/* -*+ -* Name: -* astClearRootCorner - -* Purpose: -* Clear the RootCorner attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot3d.h" -* void astClearRootCorner( AstPlot3D *this ) - -* Class Membership: -* Plot method. - -* Description: -* This function clears the RootCorner attribute. - -* Parameters: -* this -* Pointer to a Plot3D. - -*- -*/ - -/* Local Variables: */ - int old; - int new; - -/* Check the global status. */ - if( !astOK ) return; - -/* Get the current rootcorner value. */ - old = astGetRootCorner( this ); - -/* Clear the RootCorner attribute. */ - this->rootcorner = -1; - -/* Get the new (default) rootcorner value. */ - new = astGetRootCorner( this ); - -/* If the root corner has changed, mirror any axes of the encapsulated Plots - that need mirroring (this is done to ensure that Plots look right when - viewed from the outside of the graphics cube), and modify the Edge - attributes in the encapsulated Plots to ensure the labels appear on the - requested edges of the 3D graphics cube. . */ - if( old != new ) ChangeRootCorner( this, old, new, status ); -} - -static void CreatePlots( AstPlot3D *this, AstFrameSet *fset, const float *gbox, - const double *bbox, int *status ) { -/* -* Name: -* CreatePlots - -* Purpose: -* Create three 2D plots and store in the Plot3D. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void CreatePlots( AstPlot3D *this, AstFrameSet *fset, const float *gbox, - const double *bbox, int *status ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function splits the supplied FrameSet up into 3 independent 2D -* FrameSets, each describing a 2D plane in the supplied 3D FrameSet. -* It then uses these 2D FrameSets to create three Plots, one for each -* plane in the graphics plotting space, and stores them in the Plot3D. -* -* Each of the three Plots is notionally pasted onto one face of the -* 3D graphics cube (the RootCorner attribute is used to determine which -* of the two parallel faces a particular Plot is pasted onto). The -* Plot is pasted in such a way that, when viewed from the outside of -* the graphics cube, the first graphics axis increases left to right -* and the second increases bottom to top (this assumes that "up" is -* parallel to the 3D Z axis). -* -* Initially, the Plots are created assuming the default RootCorner -* value ("LLL"). They will be changed later if the value of the -* RootCorner attribute is changed. - -* Parameters: -* this -* Pointer to the Plot3D. -* fset -* Pointer to the FrameSet. -* gbox -* A pointer to an array of 6 values giving the graphics coordinates -* of the bottom left and top right corners of a box on the graphics -* output device. The first triple of values should be the graphics -* coordinates of the bottom left corner of the box and the second -* triple of values are the graphics coordinates of the top right corner. -* bbox -* A pointer to an array of 6 values giving the coordinates in the -* supplied Frame or base Frame of the supplied FrameSet at the bottom -* left and top right corners of the box specified by parameter gbox. -* These should be supplied in the same order as for parameter "gbox". -* status -* Pointer to the inherited status variable. - -* Notes: -* - Each returned plot has 3 Frames: Frame 1 is the base (GRAPHICS) -* Frame; Frame 2 is spanned by 2 of the 3 axes in the base Frame of -* the supplied FrameSet; Frame 3 is the current Frame and is spanned -* by 2 of the 3 axes in the current Frame of the supplied FrameSet. -* Any future changes to this function that alter this structure should -* reflected in equivalent changes to function UpdatePlots. - -*/ - -/* Local Variables: */ - AstFrameSet *fsetxy; - AstFrameSet *fsetxz; - AstFrameSet *fsetyz; - double basebox2d[ 4 ]; - float graphbox2d[ 4 ]; - int baseplane; - int labelxy[ 2 ]; - int labelxz[ 2 ]; - int labelyz[ 2 ]; - int wcsxy[ 2 ]; - int wcsxz[ 2 ]; - int wcsyz[ 2 ]; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Split the supplied FrameSet up into 3 FrameSets, each with a 2D base - and current Frame. Each of these FrameSets describes one plane of - the 3D cube. One of them will be spanned by two axes picked from the - supplied 3D FrameSet. The other two FrameSets will each include a copy - of the remaining 3rd axis from the supplied FrameSet, plus an extra - dummy axis. These dummy axes will never be labelled. */ - SplitFrameSet( fset, &fsetxy, labelxy, wcsxy, &fsetxz, labelxz, wcsxz, - &fsetyz, labelyz, wcsyz, &baseplane, status ); - -/* If OK, annul any existing 2D plots. */ - if( astOK ) { - if( this->plotxy ) this->plotxy = astAnnul( this->plotxy ); - if( this->plotxz ) this->plotxz = astAnnul( this->plotxz ); - if( this->plotyz ) this->plotyz = astAnnul( this->plotyz ); - -/* Create three Plots; one for each 2D plane in the graphics plotting - space. Set the attributes of these plots so that the required axes are - labelled and other axes are left blank. The "graphbox2d" and "basebox2d" - values used to create each Plot define the sense, as well as the extent, - of each axis. The first pair of values in each give the lower left corner - of the Plot and the second pair give the top right corner. We want each - Plot to have X increasing left to right and Y increasing bottom to - top when viewed from the outside of the cube. We assume an initial - RootCorner value of "LLL" (that is, the Plots are pasted onto the cube - faces that meet at the lower limit on every axis). */ - graphbox2d[ 0 ] = gbox[ 3 ]; - graphbox2d[ 1 ] = gbox[ 1 ]; - graphbox2d[ 2 ] = gbox[ 0 ]; - graphbox2d[ 3 ] = gbox[ 4 ]; - - basebox2d[ 0 ] = bbox[ 3 ]; - basebox2d[ 1 ] = bbox[ 1 ]; - basebox2d[ 2 ] = bbox[ 0 ]; - basebox2d[ 3 ] = bbox[ 4 ]; - - if( this->plotxy ) this->plotxy = astAnnul( this->plotxy ); - this->plotxy = astPlot( fsetxy, graphbox2d, basebox2d, "", status ); - SetPlotAttr( this->plotxy, XY, labelxy, status ); - - graphbox2d[ 0 ] = gbox[ 0 ]; - graphbox2d[ 1 ] = gbox[ 2 ]; - graphbox2d[ 2 ] = gbox[ 3 ]; - graphbox2d[ 3 ] = gbox[ 5 ]; - - basebox2d[ 0 ] = bbox[ 0 ]; - basebox2d[ 1 ] = bbox[ 2 ]; - basebox2d[ 2 ] = bbox[ 3 ]; - basebox2d[ 3 ] = bbox[ 5 ]; - - this->plotxz = astPlot( fsetxz, graphbox2d, basebox2d, "", status ); - SetPlotAttr( this->plotxz, XZ, labelxz, status ); - - graphbox2d[ 0 ] = gbox[ 4 ]; - graphbox2d[ 1 ] = gbox[ 2 ]; - graphbox2d[ 2 ] = gbox[ 1 ]; - graphbox2d[ 3 ] = gbox[ 5 ]; - - basebox2d[ 0 ] = bbox[ 4 ]; - basebox2d[ 1 ] = bbox[ 2 ]; - basebox2d[ 2 ] = bbox[ 1 ]; - basebox2d[ 3 ] = bbox[ 5 ]; - - this->plotyz = astPlot( fsetyz, graphbox2d, basebox2d, "", status ); - SetPlotAttr( this->plotyz, YZ, labelyz, status ); - -/* Store information that allows each 3D WCS axis to be associatedf with - a pair of Plots. Also store the WCS axis within each Plot that - corresponds to the 3D WCS axis. */ - StoreAxisInfo( this, labelxy, wcsxy, labelxz, wcsxz, labelyz, wcsyz, status ); - -/* Store the Plot that spans two connected 3D axes. */ - this->baseplot = baseplane; - -/* Free resources */ - fsetxy = astAnnul( fsetxy ); - fsetxz = astAnnul( fsetxz ); - fsetyz = astAnnul( fsetyz ); - - } -} - -static int Element2D( AstPlot3D *this, int element, int *elem2d1, - int *elem2d2, int *status ){ -/* -* Name: -* Element2D - -* Purpose: -* Convert a 3D graphics element identifier to a corresponding pair of -* 2D identifiers. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Element2D( AstPlot3D *this, int element, int *elem2d1, -* int *elem2d2, int *status ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function takes an integer identifier for an element of a 3D -* annotated grid (e.g. ticks, axis 1 labels, border, etc), and returns -* a element identifers that can be used with the encapsualted 2D Plots. - -* Parameters: -* this -* Pointer to the Plot2D structure. -* element -* The 3D element identifier to convert. -* elem2d1 -* Pointer to an int in which to return the 2D element identifier -* to use with the first of the two Plots that span the axis to -* which the 3D element identifier refers. Returned holding 0 if -* the given 3D element identifier is not axis specific. -* elem2d2 -* Pointer to an int in which to return the 2D element identifier -* to use with the second of the two Plots that span the axis to -* which the 3D element identifier refers. Returned holding 0 if -* the given 3D element identifier is not axis specific. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The zero-based index of the 3D axis to which the given element -* identifier refers, or -1 if the element identifier is not axis -* specific. - -*/ - -/* Local Variables: */ - int axis3d; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get the zero-based index of the 3D axis to which the supplied element - refers. Use an index of -1 to indicate that the element does not - relate to a specific axis. Also get the corresponding element to use - with the two Plots that share the speified 3D axis. */ - -/* Define a macro used to set the 2d element identifiers for a given 3d - element identifier. */ - -#define SET_ELEM2D(id1,id2) \ - *elem2d1 = this->axis_index1[ axis3d ] ? id2 : id1; \ - *elem2d2 = this->axis_index2[ axis3d ] ? id2 : id1; - - if( element == AST__BORDER_ID ){ - axis3d = -1; - - } else if( element == AST__CURVE_ID ){ - axis3d = -1; - - } else if( element == AST__TITLE_ID ){ - axis3d = -1; - - } else if( element == AST__MARKS_ID ){ - axis3d = -1; - - } else if( element == AST__TEXT_ID ){ - axis3d = -1; - - } else if( element == AST__AXIS1_ID ){ - axis3d = 0; - SET_ELEM2D(AST__AXIS1_ID,AST__AXIS2_ID) - - } else if( element == AST__AXIS2_ID ){ - axis3d = 1; - SET_ELEM2D(AST__AXIS1_ID,AST__AXIS2_ID) - - } else if( element == AST__AXIS3_ID ){ - axis3d = 2; - SET_ELEM2D(AST__AXIS1_ID,AST__AXIS2_ID) - - } else if( element == AST__NUMLAB1_ID ){ - axis3d = 0; - SET_ELEM2D(AST__NUMLAB1_ID,AST__NUMLAB2_ID) - - } else if( element == AST__NUMLAB2_ID ){ - axis3d = 1; - SET_ELEM2D(AST__NUMLAB1_ID,AST__NUMLAB2_ID) - - } else if( element == AST__NUMLAB3_ID ){ - axis3d = 2; - SET_ELEM2D(AST__NUMLAB1_ID,AST__NUMLAB2_ID) - - } else if( element == AST__TEXTLAB1_ID ){ - axis3d = 0; - SET_ELEM2D(AST__TEXTLAB1_ID,AST__TEXTLAB2_ID) - - } else if( element == AST__TEXTLAB2_ID ){ - axis3d = 1; - SET_ELEM2D(AST__TEXTLAB1_ID,AST__TEXTLAB2_ID) - - } else if( element == AST__TEXTLAB3_ID ){ - axis3d = 2; - SET_ELEM2D(AST__TEXTLAB1_ID,AST__TEXTLAB2_ID) - - } else if( element == AST__TICKS1_ID ){ - axis3d = 0; - SET_ELEM2D(AST__TICKS1_ID,AST__TICKS2_ID) - - } else if( element == AST__TICKS2_ID ){ - axis3d = 1; - SET_ELEM2D(AST__TICKS1_ID,AST__TICKS2_ID) - - } else if( element == AST__TICKS3_ID ){ - axis3d = 2; - SET_ELEM2D(AST__TICKS1_ID,AST__TICKS2_ID) - - } else if( element == AST__GRIDLINE1_ID ){ - axis3d = 0; - SET_ELEM2D(AST__GRIDLINE1_ID,AST__GRIDLINE2_ID) - - } else if( element == AST__GRIDLINE2_ID ){ - axis3d = 1; - SET_ELEM2D(AST__GRIDLINE1_ID,AST__GRIDLINE2_ID) - - } else if( element == AST__GRIDLINE3_ID ){ - axis3d = 2; - SET_ELEM2D(AST__GRIDLINE1_ID,AST__GRIDLINE2_ID) - - } else { - axis3d = 0; - astError( AST__INTER, "Element2D(Plot3D): The MAKE_CLEAR2 macro " - "does not yet support element index %d (internal " - "AST programming error).", status, element ); - } - -#undef SET_ELEM2D - - return axis3d; - -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two Plot3Ds are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the astEqual protected -* method inherited from the Plot Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two Plot3Ds are equivalent. - -* Parameters: -* this -* Pointer to the first Plot3D. -* that -* Pointer to the second Plot3D. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the Plot3Ds are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPlot3D *that; /* Pointer to the second Plot3D structure */ - AstPlot3D *this; /* Pointer to the first Plot3D structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the Equal method inherited from the parent Plot class. This checks - that the Plots are both of the same class (amongst other things). */ - if( (*parent_equal)( this_object, that_object, status ) ) { - -/* Obtain pointers to the two Plot3D structures. */ - this = (AstPlot3D *) this_object; - that = (AstPlot3D *) that_object; - -/* Check the encapsulated Plots for equality. */ - result = ( astEqual( this->plotxz, that->plotxz ) && - astEqual( this->plotyz, that->plotyz ) && - astEqual( this->plotxy, that->plotxy ) ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static AstPointSet *ExtendTicks( AstPlot *plot, AstPointSet *ticks, int *status ){ -/* -* Name: -* ExtendTicks - -* Purpose: -* Add an extra tick to the start and end of a list of tick marks. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* AstPointSet *ExtendTicks( AstPlot *plot, AstPointSet *ticks, int *status ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function takes a list of tick marks drawn using the supplied -* Plot, and adds in an extra tick mark at the start and end of the -* supplied list of ticks, returning the expanded list in a new -* PointSet. The extra points are guaranteed to fall outside the area -* enclosed within the supplied Plot. - -* Parameters: -* plot -* The Plot that was used to generate the list of tick marks. -* ticks -* A PointSet holding the 2D graphics coordinates (within the base -* Frame of the supplied Plot) at which each tick mark starts. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a new PointSet that has 2 more entries than the -* supplied PointSet. The first point is a new tick mark, then comes -* all the ticks mark positions supplied in "ticks", and finally there -* is another new tick mark. - -*/ - -/* Local Variables: */ - AstPointSet *result; - double **ptr_in; - double **ptr_out; - double *a_in; - double *a_out; - double *b_in; - double *b_out; - double *p; - double delta; - double hi; - double lo; - double range[ 2 ]; - double v; - int axis; - int i; - int increasing; - int np; - -/* Check inherited status */ - if( !astOK || !ticks ) return NULL; - -/* Get the number of tick marsk in the supplied PointSet and get pointers - to the 3D Graphics values contained in the PointSet. */ - np = astGetNpoint( ticks ); - ptr_in = astGetPoints( ticks ); - -/* Create the returned PointSet with room for an extra pair of ticks. Get - pointers to its data arrays */ - result = astPointSet( np + 2, 2, "", status ); - ptr_out = astGetPoints( result ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Find the index of the 2D graphics axis (0 or 1) that varies along the - set of tick marks. We do this by finding the max and min value - supplied for each axis, and then choosing the axis that has the highest - range. */ - for( axis = 0; axis < 2; axis++ ) { - hi = -DBL_MAX; - lo = DBL_MAX; - p = ptr_in[ axis ]; - - for( i = 0; i < np; i++, p++ ) { - v = *p; - if( v != AST__BAD ) { - if( v > hi ) hi = v; - if( v < lo ) lo = v; - } - } - - if( lo != DBL_MAX ) { - range[ axis ] = hi - lo; - } else { - astError( AST__INTER, "ExtendTicks{Plot3D): no good ticks on " - "axis %d (internal AST prgramming error).", status, axis ); - } - } - - -/* Get the index of the axis with the largest range (the other range - should be zero). */ - axis = ( range[ 0 ] > range[ 1 ] ) ? 0 : 1; - -/* Copy the input graphics positions to the output PointSet, and add an - extra position at the beginning and end of the output PointSet. */ - if( axis == 0 ) { - lo = plot->xlo; - hi = plot->xhi; - a_in = ptr_in[ 0 ]; - b_in = ptr_in[ 1 ]; - a_out = ptr_out[ 0 ]; - b_out = ptr_out[ 1 ]; - - } else { - lo = plot->ylo; - hi = plot->yhi; - a_in = ptr_in[ 1 ]; - b_in = ptr_in[ 0 ]; - a_out = ptr_out[ 1 ]; - b_out = ptr_out[ 0 ]; - } - - delta = 0.2*( hi - lo ); - - if( a_in[ 0 ] < a_in[ 1 ] ) { - increasing = 1; - *(a_out++) = lo - delta; - } else { - increasing = 0; - *(a_out++) = hi + delta; - } - - *(b_out++) = *b_in; - for( i = 0; i < np; i++ ) { - *(a_out++) = *(a_in++); - *(b_out++) = *(b_in++); - } - *(b_out++) = b_in[ -1 ]; - - - if( increasing ) { - *(a_out++) = hi + delta; - } else { - *(a_out++) = lo - delta; - } - } - -/* Return the extended PointSet. */ - return result; -} - -static AstFrameSet *Fset3D( AstFrameSet *fset, int ifrm, int *status ) { -/* -* Name: -* Fset3D - -* Purpose: -* Create a FrameSet with no more than 3 dimensions for a given Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* AstFrameSet *Fset3D( AstFrameSet *fset, int ifrm, int *status ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function checks a specified Frame in the supplied FrameSet. -* If the Frame has more than 3 dimensions, a new Frame is added to -* the FrameSet containing just the first three axes of the specified -* Frame. A PermMap is used to connect this Frame to the specified -* Frame, which supplied bad values for any missing axes. If the -* specified Frame is the base Frame in the supplied FrameSet, then the -* new Frame becomes the base Frame in the returned FrameSet. Like-wise, -* if the specified Frame is the current Frame, then the new Frame -* will be the current Frame in the returned FrameSet. -* -* If the specified Frame does not have more than 3 axes, then a clone -* of the FrameSet pointer is returned, otherwise the returned pointer -* points to a copy of the supplied FrameSet with the new 3-D Frame -* added. - -* Parameters: -* fset -* Pointer to the FrameSet. -* ifrm -* The index of the Frame to check. This should be AST__BASE or -* AST_CURRENT. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a FrameSet in which the Frame with index given by ifrm -* has no more than 3 axes. -*/ - -/* Local Variables: */ - AstFrame *frm; - AstFrame *newfrm; - AstFrameSet *ret; - AstPermMap *map; - double zero; - int *inperm; - int axes[3]; - int i; - int ic; - int nax; - -/* Check the inherited status. */ - if( !astOK ) return NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - map = NULL; - -/* Get a pointer to the requested Frame in the supplied FrameSet. */ - frm = astGetFrame( fset, ifrm ); - -/* See how many dimensions the specified Frame of the supplied FrameSet - has. */ - nax = astGetNaxes( frm ); - -/* If it is more than 3-dimensionbal, create a 3D Frame by picking - axes 1, 2 and 3 from the original Frame. */ - if( nax > 3 ) { - axes[ 0 ] = 0; - axes[ 1 ] = 1; - axes[ 2 ] = 2; - newfrm = astPickAxes( frm, 3, axes, NULL ); - -/* Create a PermMap to describe the mapping between the two Frames. - Use zero as the value for unknown axes (the optional mapping which - can be returned by astPickAxes uses AST__BAD for unknown axes). */ - inperm = (int *) astMalloc( sizeof(int)*(size_t) nax ); - if( astOK ){ - inperm[ 0 ] = 0; - inperm[ 1 ] = 1; - inperm[ 2 ] = 2; - for( i = 3; i < nax; i++ ) inperm[ i ] = -1; - zero = 0.0; - map = astPermMap( nax, inperm, 3, axes, &zero, "", status ); - inperm = (int *) astFree( (void *) inperm ); - } - -/* Get a copy of the supplied FrameSet. */ - ret = astCopy( fset ); - -/* Add the new Frame to the FrameSet (it becomes the current Frame). */ - ic = astGetCurrent( ret ); - astAddFrame( ret, ifrm, map, newfrm ); - newfrm = astAnnul( newfrm ); - -/* If the new Frame was derived from the base frame, set the new base - Frame, and re-instate the original current Frame */ - if( ifrm == AST__BASE ){ - astSetBase( ret, astGetCurrent( ret ) ); - astSetCurrent( ret, ic ); - } - -/* If the specified Frame in the supplied FrameSet is 3-dimensional, just - return a clone of it. */ - } else { - ret = astClone( fset ); - } - -/* Annul the pointer to the original Frame. */ - frm = astAnnul( frm ); - - return ret; - -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Plot3D. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the protected astGetAttrib -* method inherited from the FrameSet class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Plot3D, formatted as a character string. - -* Parameters: -* this -* Pointer to the Plot3D. -* attrib -* Pointer to a null terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Plot3D, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Plot3D. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstPlot *plot; /* Pointer to specific Plot */ - AstPlot3D *this; /* Pointer to the Plot3D structure */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char attname[50]; /* Plot attribute base name */ - char patt[50]; /* Plot attribute full name */ - char spec[10]; /* Plane specification */ - const char *result; /* Pointer value to return */ - double dval; /* Floating point attribute value */ - int axis; /* Axis index */ - int ival; /* Int attribute value */ - int len; /* Length of attrib string */ - int nc; /* Number of character read */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* Norm(axis). */ -/* ----------- */ - if ( nc = 0, - ( 1 == astSscanf( attrib, "norm(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetNorm( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* RootCorner. */ -/* ----------- */ - } else if ( !strcmp( attrib, "rootcorner" ) ) { - ival = astGetRootCorner( this ); - result = RootCornerString( ival, status ); - if( !result && astOK ) { - astError( AST__INTER, "astGetAttrib(Plot3D): Illegal value %d " - "for RootCorner attribute (internal AST programming " - "error).", status, ival ); - } - -/* ..._XY etc */ -/* ---------- */ - } else if ( nc = 0, - ( 2 == astSscanf( attrib, "%[a-z]_%[xyz]%n", attname, spec, - &nc ) ) ) { - - if( !strcmp( spec, "xy" ) || !strcmp( spec, "yx" ) ) { - plot = this->plotxy; - } else if( !strcmp( spec, "xz" ) || !strcmp( spec, "zx" ) ) { - plot = this->plotyz; - } else if( !strcmp( spec, "yz" ) || !strcmp( spec, "zy" ) ) { - plot = this->plotxz; - } else { - plot = NULL; - } - - if( plot ) { - sprintf( patt, "%s%s", attname, attrib + nc ); - result = astGetAttrib( plot, patt ); - - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied Plot3D, -* in bytes. - -* Parameters: -* this -* Pointer to the Plot3D. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPlot3D *this; /* Pointer to Plot3D structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the Plot3D structure. */ - this = (AstPlot3D *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astGetObjSize( this->plotxy ); - result += astGetObjSize( this->plotxz ); - result += astGetObjSize( this->plotyz ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void Grid( AstPlot *this_plot, int *status ) { -/* -* Name: -* Grid - -* Purpose: -* Draw a set of labelled coordinate axes. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void Grid( AstPlot *this, int *status ) - -* Class Membership: -* Plot member function (over-rides the astGrid method inherited from -* the Plot class). - -* Description: -* This function draws a complete annotated set of 3-dimensional -* coordinate axes for a Plot3D with (optionally) a coordinate grid -* superimposed. - -* Parameters: -* this -* Pointer to the Plot3D. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPlot *baseplot; - AstPlot *plot; - AstPlot3D *this; - AstPointSet *majticks; - AstPointSet *minticks; - AstPointSet *tmp; - AstPointSet *wcsmajticks; - AstPointSet *wcsminticks; - const char *edge; - double **ptrmin; - double **ptrmaj; - double gcon; - int base_wax2d; - int itick; - int new_gaxis; - int new_plot; - int new_wax2d; - int nmaj; - int nmin; - int perm[ 2 ]; - int rootcorner; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_plot; - -/* Invoke the astGrid method on the 2D base Plot. Both WCS axes in this - Plot are inherited from the 3D FrameSet that was supplied when the Plot3D - was constructed, and will be labelled. The other two Plots encapsulated - in the Plot3D only inherit a single axis from the original 3D FrameSet - (a dummy axis is used for the second WCS axis in these Plots). */ - baseplot = GET_PLOT( this->baseplot ); - astGrid( baseplot ); - -/* We next use astGrid to draw a grid on the 2D plane that shares the first - base plot graphics axis. Get the identifier for this Plot and the 2D - graphics axis index within the Plot that corresponds to the first base - plot graphics axis. Also get the constant value on the 3rd graphics - axis over the base plot */ - rootcorner = astGetRootCorner( this ); - if( this->baseplot == XY ) { - new_plot = XZ; - new_gaxis = 0; - gcon = this->gbox[ ( rootcorner & 4 ) ? 5 : 2 ]; - - } else if( this->baseplot == XZ ) { - new_plot = XY; - new_gaxis = 0; - gcon = this->gbox[ ( rootcorner & 2 ) ? 4 : 1 ]; - - } else { - new_plot = XY; - new_gaxis = 1; - gcon = this->gbox[ ( rootcorner & 1 ) ? 3 : 0 ]; - } - -/* Get a pointer to the Plot upon which astGrid is about to be invoked. */ - plot = GET_PLOT( new_plot ); - -/* Find which 2D WCS axis was labelled on graphics axis 0 (the bottom or - top edge) of the base plot. */ - if( ( edge = astGetC( baseplot, "Edge(1)" ) ) ) { - base_wax2d = ( !strcmp( edge, "bottom" ) || !strcmp( edge, "top" ) ) ? 0 : 1; - } else { - base_wax2d = 0; - } - -/* Get the 2D graphics coords within the base Plot at which the tick - marks were drawn for this 2D WCS axis. Extend the PointSets holding - the major tick values to include an extra tick above and below the - ticks drawn by astGrid. These extra ticks are placed outside the - bounds of the plot. This ensures that the curves on the other axis - extend the full width of the plot. */ - tmp = astGetDrawnTicks( baseplot, base_wax2d, 1 ); - if( tmp ) { - majticks = ExtendTicks( baseplot, tmp, status ); - nmaj = astGetNpoint( majticks ); - ptrmaj = astGetPoints( majticks ); - tmp = astAnnul( tmp ); - } else { - majticks = NULL; - nmaj = 0; - ptrmaj = NULL; - } - - minticks = astGetDrawnTicks( baseplot, base_wax2d, 0 ); - if( minticks ) { - nmin = astGetNpoint( minticks ); - ptrmin = astGetPoints( minticks ); - } else { - nmin = 0; - ptrmin = NULL; - } - -/* All the tick marks will have a constant value for the 2D graphics axis - that is not being ticked (axis 1 at the moment). Change this constant - value to be the value appropriate to the new Plot. */ - if( ptrmaj && ptrmin ) { - for( itick = 0; itick < nmaj; itick++ ) ptrmaj[ 1 ][ itick ] = gcon; - for( itick = 0; itick < nmin; itick++ ) ptrmin[ 1 ][ itick ] = gcon; - } - -/* If required, permute the axes in the tick mark positions. */ - if( new_gaxis != 0 ) { - perm[ 0 ] = 1; - perm[ 1 ] = 0; - if( majticks ) astPermPoints( majticks, 1, perm ); - if( minticks ) astPermPoints( minticks, 1, perm ); - } - -/* Transform the tick mark positions from 2D graphics coords to 2D WCS - coords. */ - wcsmajticks = majticks ? astTransform( plot, majticks, 1, NULL ) : NULL; - wcsminticks = minticks ? astTransform( plot, minticks, 1, NULL ) : NULL; - -/* Find the index of the 2D WCS axis that will be labelled on the bottom - or top edge (i.e. 2D graphics axis zero) of the new Plot. */ - if( ( edge = astGetC( plot, "Edge(1)" ) ) ) { - new_wax2d = ( !strcmp( edge, "bottom" ) || !strcmp( edge, "top" ) ) ? 0 : 1; - } else { - new_wax2d = 0; - } - -/* Use the other WCS axis if we are ticking the left or right edge (i.e. - 2D graphics axis one) of the new Plot. This gives us the index of the - 2D WCS axis for which tick values are to be stored in the Plot. */ - if( new_gaxis == 1 ) new_wax2d = 1 - new_wax2d; - -/* Store the tick mark values to be used on this WCS axis. */ - ptrmaj = wcsmajticks ? astGetPoints( wcsmajticks ) : NULL; - ptrmin = wcsminticks ? astGetPoints( wcsminticks ) : NULL; - if( ptrmaj && ptrmin ) { - astSetTickValues( plot, new_wax2d, nmaj, ptrmaj[ new_gaxis ], - nmin, ptrmin[ new_gaxis ] ); - } - -/* Invoke the astGrid method on this plot. */ - astGrid( plot ); - -/* Clear the stored tick values in the plot. */ - astSetTickValues( plot, new_wax2d, 0, NULL, 0, NULL ); - -/* Free resources */ - if( wcsmajticks ) wcsmajticks = astAnnul( wcsmajticks ); - if( wcsminticks ) wcsminticks = astAnnul( wcsminticks ); - if( majticks ) majticks = astAnnul( majticks ); - if( minticks ) minticks = astAnnul( minticks ); - -/* We next use astGrid to draw a grid on the 2D plane that shares the - second base plot graphics axis. Get the identifier for this Plot and the - 2D graphics axis index within the Plot that corresponds to the first - base plot graphics axis. */ - if( this->baseplot == XY ) { - new_plot = YZ; - new_gaxis = 0; - - } else if( this->baseplot == XZ ) { - new_plot = YZ; - new_gaxis = 1; - - } else { - new_plot = XZ; - new_gaxis = 1; - } - -/* Get a pointer to the Plot upon which astGrid is about to be invoked. */ - plot = GET_PLOT( new_plot ); - -/* Find which 2D WCS axis was labelled on graphics axis 1 (the left or - right edge) of the base plot. */ - base_wax2d = 1 - base_wax2d; - -/* Get the 2D graphics coords within the base Plot at which the tick - marks were drawn for this 2D WCS axis. Extend the PointSets holding - the major tick values to include an extra tick above and below the - ticks drawn by astGrid. These extra ticks are placed outside the - bounds of the plot. This ensures that the curves on the other axis - extend the full width of the plot. */ - tmp = astGetDrawnTicks( baseplot, base_wax2d, 1 ); - if( tmp ) { - majticks = ExtendTicks( baseplot, tmp, status ); - nmaj = astGetNpoint( majticks ); - ptrmaj = astGetPoints( majticks ); - tmp = astAnnul( tmp ); - } else { - majticks = NULL; - nmaj = 0; - ptrmaj = NULL; - } - - minticks = astGetDrawnTicks( baseplot, base_wax2d, 0 ); - if( minticks ) { - nmin = astGetNpoint( minticks ); - ptrmin = astGetPoints( minticks ); - } else { - nmin = 0; - ptrmin = NULL; - } - -/* All the tick marks will have a constant value for the 2D graphics axis - that is not being ticked (axis 0 at the moment). Change this constant - value to be the value appropriate to the new Plot. */ - if( ptrmaj && ptrmin ) { - for( itick = 0; itick < nmaj; itick++ ) ptrmaj[ 0 ][ itick ] = gcon; - for( itick = 0; itick < nmin; itick++ ) ptrmin[ 0 ][ itick ] = gcon; - } - -/* If required, permute the axes in the tick mark positions. */ - if( new_gaxis != 1 ) { - perm[ 0 ] = 1; - perm[ 1 ] = 0; - if( majticks ) astPermPoints( majticks, 1, perm ); - if( minticks ) astPermPoints( minticks, 1, perm ); - } - -/* Transform the tick mark positions from 2D graphics coords to 2D WCS - coords. */ - wcsmajticks = majticks ? astTransform( plot, majticks, 1, NULL ) : NULL; - wcsminticks = minticks ? astTransform( plot, minticks, 1, NULL ) : NULL; - -/* Find the index of the 2D WCS axis that will be labelled on the bottom - or top edge (i.e. 2D graphics axis zero) of the new Plot. */ - if( ( edge = astGetC( plot, "Edge(1)" ) ) ) { - new_wax2d = ( !strcmp( edge, "bottom" ) || !strcmp( edge, "top" ) ) ? 0 : 1; - } else { - new_wax2d = 0; - } - -/* Use the other WCS axis if we are ticking the left or right edge (i.e. - 2D graphics axis one) of the new Plot. This gives us the index of the - 2D WCS axis for which tick values are to be stored in the Plot. */ - if( new_gaxis == 1 ) new_wax2d = 1 - new_wax2d; - -/* Store the tick mark values to be used on this WCS axis. */ - ptrmaj = wcsmajticks ? astGetPoints( wcsmajticks ) : NULL; - ptrmin = wcsminticks ? astGetPoints( wcsminticks ) : NULL; - if( ptrmaj && ptrmin ) { - astSetTickValues( plot, new_wax2d, nmaj, ptrmaj[ new_gaxis ], - nmin, ptrmin[ new_gaxis ] ); - } - -/* Invoke the astGrid method on this plot. */ - astGrid( plot ); - -/* Clear the stored tick values in the plot. */ - astSetTickValues( plot, new_wax2d, 0, NULL, 0, NULL ); - -/* Free resources */ - if( wcsmajticks ) wcsmajticks = astAnnul( wcsmajticks ); - if( wcsminticks ) wcsminticks = astAnnul( wcsminticks ); - if( majticks ) majticks = astAnnul( majticks ); - if( minticks ) minticks = astAnnul( minticks ); - -} - -void astInitPlot3DVtab_( AstPlot3DVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitPlot3DVtab - -* Purpose: -* Initialise a virtual function table for a Plot3D. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot3d.h" -* void astInitPlot3DVtab( AstPlot3DVtab *vtab, const char *name ) - -* Class Membership: -* Plot3D vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Plot3D class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *dummy_frame; /* The Frame to put in dummy_frameset */ - AstPlotVtab *plot; /* Pointer to Plot component of Vtab */ - AstFrameSetVtab *fset; /* Pointer to FrameSet component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitPlotVtab( (AstPlotVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAPlot3D) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstPlotVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -#define SET_PLOT3D_ACCESSORS(attr) \ - vtab->Set##attr = Set##attr; \ - vtab->Get##attr = Get##attr; \ - vtab->Test##attr = Test##attr; \ - vtab->Clear##attr = Clear##attr; - -SET_PLOT3D_ACCESSORS(RootCorner) -SET_PLOT3D_ACCESSORS(Norm) - -#undef SET_PLOT3D_ACCESSORS - - - - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - fset = (AstFrameSetVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - plot = (AstPlotVtab *) vtab; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_equal = object->Equal; - object->Equal = Equal; - - parent_vset = object->VSet; - object->VSet = VSet; - - parent_cast = object->Cast; - object->Cast = Cast; - - parent_clear = object->Clear; - object->Clear = Clear; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_clearcurrent = fset->ClearCurrent; - fset->ClearCurrent = ClearCurrent; - - parent_setcurrent = fset->SetCurrent; - fset->SetCurrent = SetCurrent; - - parent_removeframe = fset->RemoveFrame; - fset->RemoveFrame = RemoveFrame; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - -/* Define a macro to override attribute accessors inherited from the - parent Plot class. First do axis specific attributes. */ - -#define SET_PLOT_ACCESSORS(attr) \ - parent_get##attr = plot->Get##attr; \ - plot->Get##attr = Get##attr; \ - parent_set##attr = plot->Set##attr; \ - plot->Set##attr = Set##attr; \ - parent_clear##attr = plot->Clear##attr; \ - plot->Clear##attr = Clear##attr; - -/* Use the above macro to override all the inherited attribute accessors. */ -SET_PLOT_ACCESSORS(MinTick) -SET_PLOT_ACCESSORS(Abbrev) -SET_PLOT_ACCESSORS(Gap) -SET_PLOT_ACCESSORS(LogGap) -SET_PLOT_ACCESSORS(LogPlot) -SET_PLOT_ACCESSORS(LogTicks) -SET_PLOT_ACCESSORS(LogLabel) -SET_PLOT_ACCESSORS(LabelUp) -SET_PLOT_ACCESSORS(DrawAxes) -SET_PLOT_ACCESSORS(LabelUnits) -SET_PLOT_ACCESSORS(MinTickLen) -SET_PLOT_ACCESSORS(MajTickLen) -SET_PLOT_ACCESSORS(NumLab) -SET_PLOT_ACCESSORS(NumLabGap) -SET_PLOT_ACCESSORS(TextLab) -SET_PLOT_ACCESSORS(TextLabGap) - -#undef SET_PLOT_ACCESSORS - - -/* Now do attributes that are not axis specific. */ - -#define SET_PLOT_ACCESSORS(attr) \ - parent_set##attr = plot->Set##attr; \ - plot->Set##attr = Set##attr; \ - parent_clear##attr = plot->Clear##attr; \ - plot->Clear##attr = Clear##attr; - -SET_PLOT_ACCESSORS(Ink) -SET_PLOT_ACCESSORS(Tol) -SET_PLOT_ACCESSORS(Invisible) -SET_PLOT_ACCESSORS(TickAll) -SET_PLOT_ACCESSORS(ForceExterior) -SET_PLOT_ACCESSORS(Border) -SET_PLOT_ACCESSORS(Clip) -SET_PLOT_ACCESSORS(ClipOp) -SET_PLOT_ACCESSORS(Escape) -SET_PLOT_ACCESSORS(Grid) -SET_PLOT_ACCESSORS(Labelling) -SET_PLOT_ACCESSORS(Style) -SET_PLOT_ACCESSORS(Font) -SET_PLOT_ACCESSORS(Colour) -SET_PLOT_ACCESSORS(Width) -SET_PLOT_ACCESSORS(Size) - -#undef SET_PLOT_ACCESSORS - - -/* Store replacement pointers for methods which will be over-ridden by new - member functions implemented here. */ - plot->Grid = Grid; - plot->Text = Text; - plot->SetTickValues = SetTickValues; - plot->PolyCurve = PolyCurve; - plot->Border = Border; - plot->BoundingBox = BoundingBox; - plot->GetGrfContext = GetGrfContext; - plot->GrfPop = GrfPop; - plot->GrfPush = GrfPush; - plot->GrfSet = GrfSet; - plot->GridLine = GridLine; - plot->Mark = Mark; - plot->Curve = Curve; - plot->GenCurve = GenCurve; - plot->Clip = Clip; - mapping->Transform = Transform; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "Plot3D", "Provide facilities for 3D graphical output" ); - -/* Create a FrameSet that can be used when calling astCast to indicate - the class to which we want to cast. */ - LOCK_MUTEX3 - if( !dummy_frameset ) { - dummy_frame = astFrame( 1, " ", status ); - dummy_frameset = astFrameSet( dummy_frame, " ", status ); - dummy_frame = astAnnul( dummy_frame ); - } - UNLOCK_MUTEX3 - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* CmpMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstPlot3D *this; /* Pointer to Plot3D structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the Plot3D structure. */ - this = (AstPlot3D *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->plotxy, mode, extra, fail ); - if( !result ) result = astManageLock( this->plotxz, mode, extra, fail ); - if( !result ) result = astManageLock( this->plotyz, mode, extra, fail ); - - return result; - -} -#endif - -static void Mark( AstPlot *this_plot, int nmark, int ncoord, int indim, - const double *in, int type, int *status ){ -/* -* Name: -* Mark - -* Purpose: -* Draw a set of markers for a Plot3D. - -* Type: -* Private member function. - -* Synopsis: -* #include "plot3d.h" -* void Mark( AstPlot *this, int nmark, int ncoord, int indim, -* const double *in, int type, int *status ) - -* Class Membership: -* Plot3d member function (overrides the astMark method inherited form -* the parent Plot class). - -* Description: -* This function draws a set of markers (symbols) at positions -* specified in the physical coordinate system of a Plot3D. The -* positions are transformed into graphical coordinates to -* determine where the markers should appear within the plotting -* area. -* -* They are drawn on a 2D plane that has a normal vector given by the -* current value of the Plot3D's "Norm" attribute. - -* Parameters: -* this -* Pointer to the Plot3D. -* nmark -* The number of markers to draw. This may be zero, in which -* case nothing will be drawn. -* ncoord -* The number of coordinates being supplied for each mark -* (i.e. the number of axes in the current Frame of the Plot, as -* given by its Naxes attribute). -* indim -* The number of elements along the second dimension of the "in" -* array (which contains the marker coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -* given should not be less than "nmark". -* in -* The address of the first element of a 2-dimensional array of -* shape "[ncoord][indim]" giving the -* physical coordinates of the points where markers are to be -* drawn. These should be stored such that the value of -* coordinate number "coord" for input mark number "mark" is -* found in element "in[coord][mark]". -* type -* A value specifying the type (e.g. shape) of marker to be -* drawn. The set of values which may be used (and the shapes -* that will result) is determined by the underlying graphics -* system. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Markers are not drawn at positions which have any coordinate -* equal to the value AST__BAD (or where the transformation into -* graphical coordinates yields coordinates containing the value -* AST__BAD). -* - An error results if the base Frame of the Plot is not 3-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*/ - -/* Local Variables: */ - AstMapping *mapping; /* Pointer to graphics->physical mapping */ - AstPlot3D *this; /* Pointer to the Plot3D structure */ - AstPointSet *pset1; /* PointSet holding physical positions */ - AstPointSet *pset2; /* PointSet holding graphics positions */ - const char *class; /* Object class */ - const char *method; /* Current method */ - const double **ptr1; /* Pointer to physical positions */ - double **ptr2; /* Pointer to graphics positions */ - double *xpd; /* Pointer to next double precision x value */ - double *ypd; /* Pointer to next double precision y value */ - double *zpd; /* Pointer to next double precision z value */ - float *x; /* Pointer to single precision x values */ - float *xpf; /* Pointer to next single precision x value */ - float *y; /* Pointer to single precision y values */ - float *ypf; /* Pointer to next single precision y value */ - float *z; /* Pointer to single precision z values */ - float *zpf; /* Pointer to next single precision z value */ - float norm[ 3 ]; /* Single precision normal vector */ - int axis; /* Axis index */ - int i; /* Loop count */ - int naxes; /* No. of axes in the base Frame */ - int nn; /* Number of good marker positions */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_plot; - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astMark"; - class = astClass( this ); - -/* Check the base Frame of the Plot is 3-D. */ - naxes = astGetNin( this ); - if( naxes != 3 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 3.", status, method, class, naxes, class ); - } - -/* Also validate the input array dimension argument. */ - if ( astOK && ( indim < nmark ) ) { - astError( AST__DIMIN, "%s(%s): The input array dimension value " - "(%d) is invalid.", status, method, class, indim ); - astError( AST__DIMIN, "This should not be less than the number of " - "markers being drawn (%d).", status, nmark ); - } - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__MARKS_ID, 1, GRF__MARK, method, class ); - -/* Create a PointSet to hold the supplied physical coordinates. */ - pset1 = astPointSet( nmark, ncoord, "", status ); - -/* Allocate memory to hold pointers to the first value on each axis. */ - ptr1 = (const double **) astMalloc( sizeof( const double * )* - (size_t)( ncoord )); - -/* Check the pointer can be used, then store pointers to the first value - on each axis. */ - if( astOK ){ - for( axis = 0; axis < ncoord; axis++ ){ - ptr1[ axis ] = in + axis*indim; - } - } - -/* Store these pointers in the PointSet. */ - astSetPoints( pset1, (double **) ptr1 ); - -/* Transform the supplied data from the current frame (i.e. physical - coordinates) to the base frame (i.e. graphics coordinates) using - the inverse Mapping defined by the Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - pset2 = astTransform( mapping, pset1, 0, NULL ); - mapping = astAnnul( mapping ); - -/* Get pointers to the graphics coordinates. */ - ptr2 = astGetPoints( pset2 ); - -/* Allocate memory to hold single precision versions of the graphics - coordinates. */ - x = (float *) astMalloc( sizeof( float )*(size_t) nmark ); - y = (float *) astMalloc( sizeof( float )*(size_t) nmark ); - z = (float *) astMalloc( sizeof( float )*(size_t) nmark ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Store pointers to the next single and double precision x, y and z - values. */ - xpf = x; - ypf = y; - zpf = z; - xpd = ptr2[ 0 ]; - ypd = ptr2[ 1 ]; - zpd = ptr2[ 2 ]; - -/* Convert the double precision values to single precision, rejecting - any bad marker positions. */ - nn = 0; - for( i = 0; i < nmark; i++ ){ - if( *xpd != AST__BAD && *ypd != AST__BAD && *zpd != AST__BAD ){ - nn++; - *(xpf++) = (float) *(xpd++); - *(ypf++) = (float) *(ypd++); - *(zpf++) = (float) *(zpd++); - } else { - xpd++; - ypd++; - zpd++; - } - } - -/* If the nornmal vector has non-zero length, draw the remaining markers. */ - norm[ 0 ] = (float) astGetNorm( this, 0 ); - norm[ 1 ] = (float) astGetNorm( this, 1 ); - norm[ 2 ] = (float) astGetNorm( this, 2 ); - - if( norm[ 0 ] != 0.0 || norm[ 1 ] != 0.0 || norm[ 2 ] != 0.0 ){ - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - - if( !astG3DMark( nn, x, y, z, type, norm ) ) { - astError( AST__GRFER, "%s(%s): Graphics error in astG3DMark. ", status, - method, class ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - - } else if( astOK ) { - astError( AST__ATTIN, "%s(%s): The vector specified by the Norm " - "attribute has zero length.", status, method, class ); - } - } - -/* Free the memory used to store single precision graphics coordinates. */ - x = (float *) astFree( (void *) x ); - y = (float *) astFree( (void *) y ); - z = (float *) astFree( (void *) z ); - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Free the memory holding the pointers to the first value on each axis. */ - ptr1 = (const double **) astFree( (void *) ptr1 ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__MARKS_ID, 0, GRF__MARK, method, class ); - -/* Return */ - return; -} - -static int Plot3DAttr( AstKeyMap *grfconID, int attr, double value, - double *old_value, int prim ){ -/* -* Name: -* Plot3DAttr - -* Purpose: -* Get or set the value of a 3D grf attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Plot3DAttr( AstKeyMap *grfconID, int attr, double value, -* double *old_value, int prim ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function is called by one of the three encapsulated 2D Plots to -* get or set the current value of a specified graphics attribute. It -* forwards the call to the grf3D module being used by this Plot3D. It -* should be registered with each of the 2D Plots using astGrfSet. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. This is used to identify which of -* the three Plots is calling this function. -* attr -* An integer value identifying the required attribute. This should -* be one of the symbolic values defined in grf.h. -* value -* A new value to store for the attribute. If this is AST__BAD -* no value is stored. -* old_value -* A pointer to a double in which to return the attribute value. -* If this is NULL, no value is returned. -* prim -* The sort of graphics primitive to be drawn with the new attribute. -* Identified by one of the values defined in grf.h. - -* Returned Value: -* An integer value of 0 is returned if an error occurs, and 1 otherwise. - -*/ - -/* Local Variables: */ - int result; - int *status; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Use the function in the external Grf3D module, selected at link-time - using ast_link options. Note, attribute values are the same for each - of the three Plot. */ - result = astG3DAttr( attr, value, old_value, prim ); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Return the result. */ - return result; -} - -static int Plot3DCap( AstKeyMap *grfconID, int cap, int value ){ -/* -* Name: -* Plot3DCap - -* Purpose: -* Determine if the 3D grf module has a given capability. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Plot3DCap( AstKeyMap *grfconID, int cap, int value ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function is called by one of the three encapsulated 2D Plots to -* determine if a given graphics capability is available. It forwards -* the call to the grf3D module being used by this Plot3D. It should be -* registered with each of the 2D Plots using astGrfSet. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. This is -* used to identify which of the three Plots is calling this function. -* cap -* The capability being inquired about. This will be one of the -* following constants defined in grf.h: GRF__SCALES, GRF__MJUST, -* GRF__ESC, -* value -* The use of this parameter depends on the value of "cap" as -* described in the documentation for the astGrfSet function in the -* Plot class. - -* Returned Value: -* The value returned by the function depends on the value of "cap" -* as described in the astGrfSet documentation. Zero is returned if -* the supplied capability is not recognised. - -*/ - -/* Local Variables: */ - int result; - int *status; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* The astGScales function is implemented by code within the Plot3D class - (not within the grf3D module). The Plot3D class assumes all axes are - equally scaled. */ - if( cap == GRF__SCALES ) { - result = 1; - -/* All grf3D modules are assumed to support "M" justification. */ - } else if( cap == GRF__MJUST ) { - result = 1; - -/* Forward all other capability requests to the grf3D module. */ - } else { - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - - result = astG3DCap( cap, value ); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - } - -/* Return the result. */ - return result; -} - -static int Plot3DFlush( AstKeyMap *grfconID ){ -/* -* Name: -* Plot3DFlush - -* Purpose: -* Flush any buffered graphical output. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Plot3DFlush( AstKeyMap *grfconID ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function is called by one of the three encapsulated 2D Plots to -* ensure that the display device is up-to-date by flushing any pending -* graphics to the output device. It forwards the call to the grf3D module -* being used by this Plot3D. It should be registered with each of the -* 2D Plots using astGrfSet. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. This is -* used to identify which of the three Plots is calling this function. - -* Returned Value: -* An integer value of 0 is returned if an error occurs, and 1 otherwise. - -*/ - -/* Local Variables: */ - int result; - int *status; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Use the function in the external Grf3D module, selected at link-time - using ast_link options. */ - result = astG3DFlush(); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Return the result. */ - return result; -} - -static int Plot3DLine( AstKeyMap *grfconID, int n, const float *x, const float *y ){ -/* -* Name: -* Plot3DLine - -* Purpose: -* Draw a polyline on a 2D surface. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Plot3DLine( AstKeyMap *grfconID, int n, const float *x, -* const float *y ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function is called by one of the three encapsulated 2D Plots to -* draw a polyline. It forwards the call to the grf3D module being used -* by this Plot3D. It should be registered with each of the 2D Plots -* using astGrfSet. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. This is -* used to identify which of the three Plots is calling this function. -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. - -* Returned Value: -* An integer value of 0 is returned if an error occurs, and 1 otherwise. - -*/ - -/* Local Variables: */ - AstKeyMap *grfcon; - double gcon; - float *work; - float *x3d = NULL; - float *y3d = NULL; - float *z3d = NULL; - int i; - int plane; - int result = 0; - int *status; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a genuine pointer from the supplied grfcon identifier. */ - grfcon = astMakePointer( grfconID ); - -/* Report an error if no grfcon object was supplied. */ - if( !grfcon ) { - astError( AST__INTER, "astG3DLine(Plot3D): No grfcon Object supplied " - "(internal AST programming error)." , status); - -/* If a grfcon Object was supplied, get the graphics box array out of it. */ - } else if( !astMapGet0D( grfcon, "Gcon", &gcon ) ) { - astError( AST__INTER, "astG3DLine(Plot3D): No \"Gcon\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - -/* Also get the plane index out of it. */ - } else if( !astMapGet0I( grfcon, "Plane", &plane ) ) { - astError( AST__INTER, "astG3DLine(Plot3D): No \"Plane\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - } - -/* Allocate memory to hold the "n" values for the missing coordinate. */ - work = astMalloc( sizeof( float )*(size_t) n ); - if( work ) { - -/* Set up pointers to the x, y and z arrays in the 3D graphics system. - Fill the missing array with suitable values (the constant value of - the third axis on the plane being drawn). */ - if( plane == XY ) { - x3d = (float *) x; - y3d = (float *) y; - z3d = work; - - for( i = 0; i < n; i++ ) z3d[ i ] = gcon; - - } else if( plane == XZ ) { - x3d = (float *) x; - y3d = work; - z3d = (float *) y; - for( i = 0; i < n; i++ ) y3d[ i ] = gcon; - - } else if( plane == YZ ) { - x3d = work; - y3d = (float *) x; - z3d = (float *) y; - for( i = 0; i < n; i++ ) x3d[ i ] = gcon; - - } else { - astError( AST__INTER, "astG3DLine(Plot3D): Illegal plane " - "identifier %d supplied (internal AST programming " - "error).", status, plane ); - } - -/* If ok, draw the lines in the 3D graphics coordinate space. */ - if( x3d ) { - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Draw the line */ - result = astG3DLine( n, x3d, y3d, z3d ); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - } - } - -/* Free resources. */ - work = astFree( work ); - -/* Return the result. */ - return result; -} - -static int Plot3DMark( AstKeyMap *grfconID, int n, const float *x, - const float *y, int type ){ -/* -* Name: -* Plot3DMark - -* Purpose: -* Draw a set of markers. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Plot3DMark( AstKeyMap *grfconID, int n, const float *x, -* const float *y, int type ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function is called by one of the three encapsulated 2D Plots to -* draw a set of markers. It forwards the call to the grf3D module being -* used by this Plot3D. It should be registered with each of the 2D Plots -* using astGrfSet. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. This is -* used to identify which of the three Plots is calling this function. -* n -* The number of markers to draw. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* type -* An integer which can be used to indicate the type of marker symbol -* required. - -* Returned Value: -* An integer value of 0 is returned if an error occurs, and 1 otherwise. - -*/ - -/* Local Variables: */ - AstKeyMap *grfcon; - double gcon; - float *work; - float *x3d = NULL; - float *y3d = NULL; - float *z3d = NULL; - float norm[ 3 ]; - int i; - int plane; - int rc; - int result = 0; - int *status; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a genuine pointer from the supplied grfcon identifier. */ - grfcon = astMakePointer( grfconID ); - -/* Report an error if no grfcon object was supplied. */ - if( !grfcon ) { - astError( AST__INTER, "astG3DMark(Plot3D): No grfcon Object supplied " - "(internal AST programming error)." , status); - -/* If a grfcon Object was supplied, get the graphics box array out of it. */ - } else if( !astMapGet0D( grfcon, "Gcon", &gcon ) ) { - astError( AST__INTER, "astG3DMark(Plot3D): No \"Gcon\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - -/* If a grfcon Object was supplied, get the RootCorner value out of it. */ - } else if( !astMapGet0I( grfcon, "RootCorner", &rc ) ) { - astError( AST__INTER, "astG3DLine(Plot3D): No \"RootCornern\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - -/* Also get the plane index out of it. */ - } else if( !astMapGet0I( grfcon, "Plane", &plane ) ) { - astError( AST__INTER, "astG3DMark(Plot3D): No \"Plane\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - } - -/* Allocate memory to hold the "n" values for the missing coordinate. */ - work = astMalloc( sizeof( float )*(size_t) n ); - if( work ) { - -/* Set up pointers to the x, y and z arrays in the 3D graphics system. - Fill the missing array with suitable values (the constant value of - the third axis on the plane being drawn). Set the normal vector for - the markers so that they are drawn in the plane described by the Plot.*/ - if( plane == XY ) { - x3d = (float *) x; - y3d = (float *) y; - z3d = work; - for( i = 0; i < n; i++ ) z3d[ i ] = gcon; - norm[ 0 ] = 0; - norm[ 1 ] = 0; - norm[ 2 ] = ( rc & 4 ) ? 1 : -1; - - } else if( plane == XZ ) { - x3d = (float *) x; - y3d = work; - z3d = (float *) y; - for( i = 0; i < n; i++ ) y3d[ i ] = gcon; - norm[ 0 ] = 0; - norm[ 1 ] = ( rc & 2 ) ? 1 : -1; - norm[ 2 ] = 0; - - } else if( plane == YZ ) { - x3d = work; - y3d = (float *) x; - z3d = (float *) y; - for( i = 0; i < n; i++ ) x3d[ i ] = gcon; - norm[ 0 ] = ( rc & 1 ) ? 1 : -1; - norm[ 1 ] = 0; - norm[ 2 ] = 0; - - } else { - astError( AST__INTER, "astG3DMark(Plot3D): Illegal plane " - "identifier %d supplied (internal AST programming " - "error).", status, plane ); - } - -/* If ok, draw the markers in the 3D graphics coordinate space. */ - if( x3d ) { - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Draw the markers */ - result = astG3DMark( n, x3d, y3d, z3d, type, norm ); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - } - } - -/* Free resources. */ - work = astFree( work ); - -/* Return the result. */ - return result; -} - -static int Plot3DQch( AstKeyMap *grfconID, float *chv, float *chh ){ -/* -* Name: -* Plot3DQch - -* Purpose: -* Get the current text size. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Plot3DQch( AstKeyMap *grfconID, float *chv, float *chh ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function is called by one of the three encapsulated 2D Plots to -* get the current text size. It forwards the call to the grf3D module -* being used by this Plot3D. It should be registered with each of the -* 2D Plots using astGrfSet. -* -* The grf3D module assumes that the 3D graphics axes are equally -* scaled and therefore the text height does not depend on the text -* orientation. Therefore, "chv" and "chh" are returned holding the -* same value. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. This is -* used to identify which of the three Plots is calling this function. -* chv -* A pointer to the float which is to receive the height of -* characters drawn with a vertical baseline in the 2D Plot. This -* will be an increment in the 2D X axis. -* chh -* A pointer to the float which is to receive the height of -* characters drawn with a horizontal baseline in the 2D Plot. This -* will be an increment in the 2D Y axis. - -* Returned Value: -* An integer value of 0 is returned if an error occurs, and 1 otherwise. - -*/ - -/* Local Variables: */ - int result; - float ch; - int *status; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Use the function in the external Grf3D module, selected at link-time - using ast_link options. Note, text height is the same for each - of the three Plot. */ - result = astG3DQch( &ch ); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Store the value in both the returned values. */ - *chv = ch; - *chh = ch; - -/* Return the error flag. */ - return result; -} - -static int Plot3DScales( AstKeyMap *grfconID, float *alpha, float *beta ){ -/* -* Name: -* Plot3DScales - -* Purpose: -* Get the 2D axis scales. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Plot3DScales( AstKeyMap *grfconID, float *alpha, float *beta ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function is called by one of the three encapsulated 2D Plots to -* get the relative scales of the 2D axes. Since the grf3D module -* assumes that all graphics axes are equally scaled, it just returns 1.0 -* for alpha and beta. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. This is -* used to identify which of the three Plots is calling this function. -* alpha -* A pointer to the float which is to receive the scale for the X -* axis -* beta -* A pointer to the float which is to receive the scale for the Y -* axis - -* Returned Value: -* An integer value of 0 is returned if an error occurs, and 1 otherwise. - -*/ - - *alpha = 1.0; - *beta = 1.0; - return 1; -} - -static int Plot3DText( AstKeyMap *grfconID, const char *text, float x, float y, - const char *just, float upx, float upy ){ -/* -* Name: -* Plot3DText - -* Purpose: -* Draw a text string. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Plot3DText( AstKeyMap *grfconID, const char *text, float x, float y, -* const char *just, float upx, float upy ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function is called by one of the three encapsulated 2D Plots to -* draw a text string. It forwards the call to the grf3D module being -* used by this Plot3D. It should be registered with each of the 2D Plots -* using astGrfSet. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. This is -* used to identify which of the three Plots is calling this function. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. -* upx -* The x component of the up-vector for the text. -* upy -* The y component of the up-vector for the text. - -* Returned Value: -* An integer value of 0 is returned if an error occurs, and 1 otherwise. - -*/ - -/* Local Variables: */ - AstKeyMap *grfcon; - double gcon; - float norm[ 3 ]; - float ref[ 3 ]; - float up[ 3 ]; - int plane; - int rc; - int result = 0; - int *status; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a genuine pointer from the supplied grfcon identifier. */ - grfcon = astMakePointer( grfconID ); - -/* Report an error if no grfcon object was supplied. */ - if( !grfcon ) { - astError( AST__INTER, "astG3DText(Plot3D): No grfcon Object supplied " - "(internal AST programming error)." , status); - -/* If a grfcon Object was supplied, get the graphics box array out of it. */ - } else if( !astMapGet0D( grfcon, "Gcon", &gcon ) ) { - astError( AST__INTER, "astG3DText(Plot3D): No \"Gcon\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - -/* If a grfcon Object was supplied, get the RootCorner value out of it. */ - } else if( !astMapGet0I( grfcon, "RootCorner", &rc ) ) { - astError( AST__INTER, "astG3DLine(Plot3D): No \"RootCornern\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - -/* Also get the plane index out of it. */ - } else if( !astMapGet0I( grfcon, "Plane", &plane ) ) { - astError( AST__INTER, "astG3DText(Plot3D): No \"Plane\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - -/* If OK, draw the text. */ - } else { - -/* Set up the reference, up and normal vectors so that the text appears - on the required plane. */ - if( plane == XY ) { - ref[ 0 ] = x; - ref[ 1 ] = y; - ref[ 2 ] = gcon; - norm[ 0 ] = 0; - norm[ 1 ] = 0; - norm[ 2 ] = ( rc & 4 ) ? 1 : -1; - up[ 0 ] = upx; - up[ 1 ] = upy; - up[ 2 ] = 0; - - } else if( plane == XZ ) { - ref[ 0 ] = x; - ref[ 1 ] = gcon; - ref[ 2 ] = y; - norm[ 0 ] = 0; - norm[ 1 ] = ( rc & 2 ) ? 1 : -1; - norm[ 2 ] = 0; - up[ 0 ] = upx; - up[ 1 ] = 0; - up[ 2 ] = upy; - - } else if( plane == YZ ) { - ref[ 0 ] = gcon; - ref[ 1 ] = x; - ref[ 2 ] = y; - norm[ 0 ] = ( rc & 1 ) ? 1 : -1; - norm[ 1 ] = 0; - norm[ 2 ] = 0; - up[ 0 ] = 0; - up[ 1 ] = upx; - up[ 2 ] = upy; - - } else { - astError( AST__INTER, "astG3DText(Plot3D): Illegal plane " - "identifier %d supplied (internal AST programming " - "error).", status, plane ); - } - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If ok, draw the markers in the 3D graphics coordinate space. */ - if( astOK ) result = astG3DText( text, ref, just, up, norm ); - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - } - -/* Return the result. */ - return result; -} - -static int Plot3DTxExt( AstKeyMap *grfconID, const char *text, float x, float y, - const char *just, float upx, float upy, float *xb, - float *yb ){ -/* -* Name: -* Plot3DTxExt - -* Purpose: -* Determine the plotted extent of a text string. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int Plot3DTxExt( AstKeyMap *grfconID, const char *text, float x, -* float y, const char *just, float upx, float upy, -* float *xb, float *yb ) - -* Class Membership: -* Plot3D member function. - -* Description: -* This function is called by one of the three encapsulated 2D Plots to -* determine the extent a string would have if plotted using Plot3DText. -* It forwards the call to the grf3D module being used by this Plot3D. It -* should be registered with each of the 2D Plots using astGrfSet. - -* Parameters: -* grfconID -* The Plot's GrfContext KeyMap. This is -* used to identify which of the three Plots is calling this function. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. -* upx -* The x component of the up-vector for the text. -* upy -* The y component of the up-vector for the text. -* xb -* An array of 4 elements in which to return the x coordinate of -* each corner of the bounding box. -* yb -* An array of 4 elements in which to return the y coordinate of -* each corner of the bounding box. - -* Returned Value: -* An integer value of 0 is returned if an error occurs, and 1 otherwise. - -*/ - -/* Local Variables: */ - AstKeyMap *grfcon; - double gcon; - float *xb3d = NULL; - float *yb3d = NULL; - float *zb3d = NULL; - float bl[ 3 ]; - float norm[ 3 ]; - float ref[ 3 ]; - float unused[ 4 ]; - float up[ 3 ]; - int plane; - int rc; - int result = 0; - int *status; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a genuine pointer from the supplied grfcon identifier. */ - grfcon = astMakePointer( grfconID ); - -/* Report an error if no grfcon object was supplied. */ - if( !grfcon ) { - astError( AST__INTER, "astG3DTxExt(Plot3D): No grfcon Object supplied " - "(internal AST programming error)." , status); - -/* If a grfcon Object was supplied, get the graphics box array out of it. */ - } else if( !astMapGet0D( grfcon, "Gcon", &gcon ) ) { - astError( AST__INTER, "astG3DTxExt(Plot3D): No \"Gcon\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - -/* If a grfcon Object was supplied, get the RootCorner value out of it. */ - } else if( !astMapGet0I( grfcon, "RootCorner", &rc ) ) { - astError( AST__INTER, "astG3DLine(Plot3D): No \"RootCornern\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - -/* Also get the plane index out of it. */ - } else if( !astMapGet0I( grfcon, "Plane", &plane ) ) { - astError( AST__INTER, "astG3DTxExt(Plot3D): No \"Plane\" key found " - "in the supplied grfcon Object (internal AST programming " - "error)." , status); - -/* If OK, get the extent of the text. */ - } else { - -/* Set up the reference, up and normal vectors so that the text appears - on the required plane. */ - if( plane == XY ) { - ref[ 0 ] = x; - ref[ 1 ] = y; - ref[ 2 ] = gcon; - norm[ 0 ] = 0; - norm[ 1 ] = 0; - norm[ 2 ] = ( rc & 4 ) ? 1 : -1; - up[ 0 ] = upx; - up[ 1 ] = upy; - up[ 2 ] = 0; - xb3d = xb; - yb3d = yb; - zb3d = unused; - - } else if( plane == XZ ) { - ref[ 0 ] = x; - ref[ 1 ] = gcon; - ref[ 2 ] = y; - norm[ 0 ] = 0; - norm[ 1 ] = ( rc & 2 ) ? 1 : -1; - norm[ 2 ] = 0; - up[ 0 ] = upx; - up[ 1 ] = 0; - up[ 2 ] = upy; - xb3d = xb; - yb3d = unused; - zb3d = yb; - - } else if( plane == YZ ) { - ref[ 0 ] = gcon; - ref[ 1 ] = x; - ref[ 2 ] = y; - norm[ 0 ] = ( rc & 1 ) ? 1 : -1; - norm[ 1 ] = 0; - norm[ 2 ] = 0; - up[ 0 ] = 0; - up[ 1 ] = upx; - up[ 2 ] = upy; - xb3d = unused; - yb3d = xb; - zb3d = yb; - - } else { - astError( AST__INTER, "astG3DTxExt(Plot3D): Illegal plane " - "identifier %d supplied (internal AST programming " - "error).", status, plane ); - } - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If ok, get the extent of the text. */ - if( astOK ) result = astG3DTxExt( text, ref, just, up, norm, xb3d, yb3d, - zb3d, bl ); -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - } - -/* Return the result. */ - return result; -} - -static void PolyCurve( AstPlot *this, int npoint, int ncoord, int indim, - const double *in, int *status ){ -/* -* Name: -* PolyCurve - -* Purpose: -* Draw a series of connected geodesic curves. - -* Type: -* Private member function. - -* Synopsis: -* #include "plot3d.h" -* void PolyCurve( AstPlot *this, int npoint, int ncoord, int indim, -* const double *in, int *status ) - -* Class Membership: -* Plot method (overrides the astPolyCurve method inherited form the -* Plot class) - -* Description: -* This function joins a series of points specified in the physical -* coordinate system of a Plot by drawing a sequence of geodesic -* curves. It is equivalent to making repeated use of the astCurve -* function (q.v.), except that astPolyCurve will generally be more -* efficient when drawing many geodesic curves end-to-end. A -* typical application of this might be in drawing contour lines. -* -* As with astCurve, full account is taken of the Mapping between -* physical and graphical coordinate systems. This includes any -* discontinuities and clipping established using astClip. - -* Parameters: -* this -* Pointer to the Plot. -* npoint -* The number of points between which geodesic curves are to be drawn. -* ncoord -* The number of coordinates being supplied for each point (i.e. -* the number of axes in the current Frame of the Plot, as given -* by its Naxes attribute). -* indim -* The number of elements along the second dimension of the "in" -* array (which contains the input coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -* given should not be less than "npoint". -* in -* The address of the first element in a 2-dimensional array of shape -* "[ncoord][indim]" giving the -* physical coordinates of the points which are to be joined in -* sequence by geodesic curves. These should be stored such that -* the value of coordinate number "coord" for point number -* "point" is found in element "in[coord][point]". -* status -* Pointer to the inherited status variable. - -* Notes: -* - No curve is drawn on either side of any point which has any -* coordinate equal to the value AST__BAD. -* - An error results if the base Frame of the Plot is not -* 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - - astError( AST__INTER, "astPolyCurve(%s): The astPolyCurve " - "method cannot be used with a %s (programming error).", status, - astGetClass( this ), astGetClass( this ) ); -} - -static void RemoveFrame( AstFrameSet *this_fset, int iframe, int *status ) { -/* -* Name: -* RemoveFrame - -* Purpose: -* Remove a Frame from a Plot3D. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "plot.h" -* void RemoveFrame( AstFrameSet *this_fset, int iframe, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the astRemoveFrame public -* method inherited from the Plot class). - -* Description: -* This function removes a Frame from a Plot3D. All other Frames -* in the Plot3D have their indices re-numbered from one (if -* necessary), but are otherwise unchanged. -* -* If the index of the original base Frame is changed, the index value -* stored in the Plot3D is updated. If the base Frame itself is -* removed, an error is reported. - -* Parameters: -* this_fset -* Pointer to the FrameSet component of the Plot3D. -* iframe -* The index within the Plot3D of the Frame to be removed. -* This value should lie in the range from 1 to the number of -* Frames in the Plot3D (as given by its Nframe attribute). -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPlot3D *this; /* Pointer to Plot3D structure */ - int ifrm; /* Validated frame index */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_fset; - -/* Validate the frame index. This translated AST__BASE and AST__CURRENT - into actual Frame indices. */ - ifrm = astValidateFrameIndex( this_fset, iframe, "astRemoveFrame" ); - -/* Report an error if an attempt is made to delete the Frame that defines - the mapping onto the screen (the original base Frame in the FrameSet - supplied when the Plot3D was constructed). */ - if( ifrm == this->pix_frame ){ - astError( AST__PXFRRM, "astRemoveFrame(%s): Cannot delete Frame " - "number %d from the supplied %s since it is the Frame " - "that defines the mapping onto the graphics plane.", status, - astGetClass( this ), iframe, astGetClass( this ) ); - -/* Otherwise, invoke the parent astRemoveFrame method to remove the Frame. */ - } else { - (*parent_removeframe)( this_fset, iframe, status ); - -/* If the index of the removed Frame is smaller than the original base Frame - index, then decrement the original base Frame index so that the same Frame - will be used in future. */ - if( astOK ){ - if( ifrm < this->pix_frame ) (this->pix_frame)--; - } - } -} - -static int RootCornerInt( const char *rootcorner, int *status ){ -/* -* Name: -* RootCornerInt - -* Purpose: -* Convert a RootCorner string to an integer. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int RootCornerInt( const char *rootcorner, int *status ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function converts a RootCorner string to an integer. - -* Parameters: -* rootcorner -* The string value to convert. Should be 3 characters long -* and contain nothing but "U" or "L" (upper or lower case). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The integer value that is is the protected equivalent of the -* supplied string. A negative value is returned if an error has -* already occurred, of the supplied string is not legal. - -*/ - -/* Local Variables: */ - int result; - -/* Initialise */ - result = -1; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Compare thr supplied value with every legal value. */ - if( astChrMatch( rootcorner, "LLL" ) ) { - result = LLL; - - } else if( astChrMatch( rootcorner, "ULL" ) ) { - result = ULL; - - } else if( astChrMatch( rootcorner, "LUL" ) ) { - result = LUL; - - } else if( astChrMatch( rootcorner, "UUL" ) ) { - result = UUL; - - } else if( astChrMatch( rootcorner, "LLU" ) ) { - result = LLU; - - } else if( astChrMatch( rootcorner, "ULU" ) ) { - result = ULU; - - } else if( astChrMatch( rootcorner, "LUU" ) ) { - result = LUU; - - } else if( astChrMatch( rootcorner, "UUU" ) ) { - result = UUU; - - } - -/* Return the result. */ - return result; -} - -static const char *RootCornerString( int rootcorner, int *status ){ -/* -* Name: -* RootCornerString - -* Purpose: -* Convert a RootCorner integer to a string. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* const char *RootCornerString( int rootcorner, int *status ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function converts a RootCorner integer to a string. - -* Parameters: -* rootcorner -* The integer value to convert. Should be in the range 0 to 7. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a static string that is the public equivalent of the -* supplied integer. A NULL pointer is returned if an error has -* already occurred, of the supplied integer is not legal. - -*/ - -/* Local Variables: */ - char *result; - -/* Initialise */ - result = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Compare thr supplied value with every legal value. */ - if( rootcorner == LLL ) { - result = "LLL"; - - } else if( rootcorner == ULL ) { - result = "ULL"; - - } else if( rootcorner == LUL ) { - result = "LUL"; - - } else if( rootcorner == UUL ) { - result = "UUL"; - - } else if( rootcorner == LLU ) { - result = "LLU"; - - } else if( rootcorner == ULU ) { - result = "ULU"; - - } else if( rootcorner == LUU ) { - result = "LUU"; - - } else if( rootcorner == UUU ) { - result = "UUU"; - - } - -/* Return the result. */ - return result; -} - -static void Set3DGrf( AstPlot3D *this, AstPlot *plot, int plane, int *status ){ -/* -* Name: -* Set3DGrf - -* Purpose: -* Associate GRF functions with a Plot. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void Set3DGrf( AstPlot3D *this, AstPlot *plot, int plane, int *status ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function registers grf functions defined in this class with -* the supplied Plot, so that, whenever the Plot draws anything, the -* plotting request is caught by this class and converted into an -* appropriate grf3D call. - -* Parameters: -* this -* Pointer to the Plot3D. -* plot -* Pointer to the Plot. -* plane -* An integer identifier for the plane within 3D GRAPHICS -* coordinates upon which the supplied Plot should draw. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstKeyMap *grfcon; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Register the plotting functions defined in this class, so that the - plot will call these functions to do its 2D plotting. */ - astGrfSet( plot, "Attr", (AstGrfFun) Plot3DAttr ); - astGrfSet( plot, "Cap", (AstGrfFun) Plot3DCap ); - astGrfSet( plot, "Flush", (AstGrfFun) Plot3DFlush ); - astGrfSet( plot, "Line", (AstGrfFun) Plot3DLine ); - astGrfSet( plot, "Mark", (AstGrfFun) Plot3DMark ); - astGrfSet( plot, "Qch", (AstGrfFun) Plot3DQch ); - astGrfSet( plot, "Scales", (AstGrfFun) Plot3DScales ); - astGrfSet( plot, "Text", (AstGrfFun) Plot3DText ); - astGrfSet( plot, "TxExt", (AstGrfFun) Plot3DTxExt ); - -/* Ensure that the Plot uses the grf interface registered using - astGrfSet. */ - astSetGrf( plot, 1 ); - -/* When the above functions are called, they need to know which plane - they are drawing on. So we put this information into the GrfContext - KeyMap stored in the Plot. This KeyMap will be passed to the above - drawing functions when they are called from within the Plot class. */ - grfcon = astGetGrfContext( plot ); - astMapPut0I( grfcon, "Plane", plane, "The 2D plane being drawn on" ); - if( plane == XY ) { - astMapPut0D( grfcon, "Gcon", this->gbox[2], "Constant Z value" ); - } else if( plane == XZ ) { - astMapPut0D( grfcon, "Gcon", this->gbox[1], "Constant Y value" ); - } else { - astMapPut0D( grfcon, "Gcon", this->gbox[0], "Constant X value" ); - } - astMapPut0I( grfcon, "RootCorner", astGetRootCorner(this), "The labelled corner" ); - grfcon = astAnnul( grfcon ); -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Plot3D. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the astSetAttrib protected -* method inherited from the Plot class). - -* Description: -* This function assigns an attribute value for a Plot3D, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Plot3D. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPlot *plot; /* Pointer to specific Plot */ - AstPlot3D *this; /* Pointer to the Plot3D structure */ - char pat[30]; /* Regular expression pattern */ - char spec[10]; /* Plane specification */ - const char *null = ""; /* Pointer to null string */ - const char *psetting; /* Pointer to plot-specific attrib setting */ - double dval; /* Floating point attribute value */ - int axis; /* Axis index */ - int ival; /* Int attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* Norm(axis). */ -/* ----------- */ - if ( nc = 0, - ( 2 == astSscanf( setting, "norm(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetNorm( this, axis - 1, dval ); - -/* RootCorner. */ -/* ----------- */ - } else if( nc = 0, - ( 0 == astSscanf( setting, "rootcorner=%n%*[^\n]%n", &ival, &nc ) ) - && ( nc >= len ) ) { - ival = RootCornerInt( setting + ival, status ); - if( astOK && ival < 0 ) { - astError( AST__ATTIN, "astSetAttrib(Plot3D): Unusable value \"%s\" " - "given for attribute RootCorner.", status, setting + ival ); - } else { - astSetRootCorner( this, ival ); - } - -/* ..._XY etc */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "%*[a-z]_%[xyz]%n", spec, &nc ) ) ) { - - if( !strcmp( spec, "xy" ) || !strcmp( spec, "yx" ) ) { - plot = this->plotxy; - } else if( !strcmp( spec, "xz" ) || !strcmp( spec, "zx" ) ) { - plot = this->plotyz; - } else if( !strcmp( spec, "yz" ) || !strcmp( spec, "zy" ) ) { - plot = this->plotxz; - } else { - plot = NULL; - } - - if( plot ) { - sprintf( pat, ".*(_%s).*", spec ); - psetting = astChrSub( setting, pat, &null, 1 ); - astSetAttrib( plot, psetting ); - psetting = astFree( (void *) psetting ); - - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static void SetCurrent( AstFrameSet *this_frameset, int iframe, int *status ) { -/* -* Name: -* SetCurrent - -* Purpose: -* Set a value for the Current attribute of a Plot3D. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int astSetCurrent( AstFrameSet *this, int iframe, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the public astSetCurrent method -* inherited from the FrameSet class). - -* Description: -* This function sets a value for the Current attribute of a -* Plot3D. This attribute is an index that identifies the current -* Frame for the Plot3D. - -* Parameters: -* this -* Pointer to the Plot3D. -* iframe -* Value to be set for the Current attribute. -* status -* Pointer to the inherited status variable. -*/ - -/* Invoke the parent astSetCurrent method. */ - (*parent_setcurrent)( this_frameset, iframe, status ); - -/* Update the three 2D Plots stored in the Plot3D structure so that they - reflect this modified FrameSet. */ - UpdatePlots( (AstPlot3D *) this_frameset, status ); -} - -static void SetPlotAttr( AstPlot *plot, int plane, int label[ 2 ], int *status ){ -/* -* Name: -* SetPlotAttr - -* Purpose: -* Set the attributes ofr one of the encapsulated Plots. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void SetPlotAttr( AstPlot *plot, int plane, int label[ 2 ], int *status ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function sets the attributes of one of the encapsulated Plots. - -* Parameters: -* plot -* Pointer to the Plot to modify. -* plane -* The 3D plane spanned by the 2D plot. -* label -* Array indicating if each WCS axis should be labelled or not. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int axis; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Ensure that the Plot uses the grf interface registered using - astGrfSet. */ - astSetGrf( plot, 1 ); - -/* Ensure that no title is drawn. */ - astSetDrawTitle( plot, 0 ); - -/* For each axis, ensure that no axis labels or ticks are produced unless - the axis is indicated as a labelled axis in the supplied array. */ - for( axis = 0; axis < 2; axis++ ) { - if( !label[ axis ] ) { - astSetLabelUnits( plot, axis, 0 ); - astSetNumLab( plot, axis, 0 ); - astSetTextLab( plot, axis, 0 ); - } - } -} - -static void SetRootCorner( AstPlot3D *this, int rootcorner, int *status ){ -/* -*+ -* Name: -* astSetRootCorner - -* Purpose: -* Set a new value for the RootCorner attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot3d.h" -* void astSetRootCorner( AstPlot3D *this, int rootcorner ) - -* Class Membership: -* Plot method. - -* Description: -* This function sets a new value for the RootCorner attribute. - -* Parameters: -* this -* Pointer to a Plot3D. -* rootcorner -* The new RootCorner value. - -*- -*/ - -/* Check the global status. */ - if( !astOK ) return; - -/* Report an error if the new value is out of bounds. */ - if( rootcorner < 0 || rootcorner > 7 ){ - astError( AST__ATTIN, "astSetRootCorner(Plot3D): Invalid value %d " - "supplied for RootCorner attribute", status,rootcorner); - -/* If the new corner is OK, mirror any axes of the encapsulated Plots - that need mirroring (this is done to ensure that Plots look right when - viewed from the outside of the graphics cube), and modify the Edge - attributes in the encapsulated Plots to ensure the labels appear on the - requested edges of the 3D graphics cube. . */ - } else { - ChangeRootCorner( this, astGetRootCorner(this), rootcorner, status ); - -/* Store the new value. */ - this->rootcorner = rootcorner; - } -} - -static void SetTickValues( AstPlot *this, int axis, int nmajor, double *major, - int nminor, double *minor, int *status ){ -/* -* Name: -* SetTickValues - -* Purpose: -* Store the tick mark values to use for a given Plot axis. - -* Type: -* Private member function. - -* Synopsis: -* #include "plot3d.h" -* void SetTickValues( AstPlot *this, int axis, int nmajor, -* double *major, int nminor, double *minor, int *status ) - -* Class Membership: -* Plot method (overrides the astSetTickValues method inherited form -* the Plot class) - -* Description: -* This function stores a set of tick mark values that should be used by -* subsequent calls to astGrid. - -* Parameters: -* this -* Pointer to a Plot. -* axis -* The zero-based index of the axis for which tick marks values -* have been supplied. -* nmajor -* The number of major tick mark values. If zero is supplied then -* the other parameters are ignored, and subsequent calls to -* astGrid will itself determine the tick values to be used. -* major -* Pointer to an array holding "nmajor" values for axis "axis" in -* the current Frame of the suppled Plot. Major tick marks will be -* drawn at these values. -* nminor -* The number of minor tick mark values. -* minor -* Pointer to an array holding "nminor" values for axis "axis" in -* the current Frame of the suppled Plot. Minor tick marks will be -* drawn at these values. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global status. */ - if( !astOK ) return; - - astError( AST__INTER, "astSetTickValues(%s): The astSetTickValues " - "method cannot be used with a %s (programming error).", status, - astGetClass( this ), astGetClass( this ) ); -} - -static void SplitFrameSet( AstFrameSet *fset, - AstFrameSet **fsetxy, int labelxy[2], int wcsxy[2], - AstFrameSet **fsetxz, int labelxz[2], int wcsxz[2], - AstFrameSet **fsetyz, int labelyz[2], int wcsyz[2], - int *baseplane, int *status ){ -/* -* Name: -* SplitFrameSet - -* Purpose: -* Split a 3D FrameSet into three 2D FrameSets. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void SplitFrameSet( AstFrameSet *fset, -* AstFrameSet **fsetxy, int labelxy[2], int wcsxy[2], -* AstFrameSet **fsetxz, int labelxz[2], int wcsxz[2], -* AstFrameSet **fsetyz, int labelyz[2], int wcsyz[2], -* int *baseplane, int *status ) - -* Class Membership: -* Plot3D member function - -* Description: -* This function returns 3 FrameSets, each of which has 2-dimensional -* base and current Frames. Each of the 2D base Frames span a single -* plane in the 3D base Frame of the supplied FrameSet. Likewise, each -* of the 2D current Frames span a single plane in the 3D current Frame -* of the supplied FrameSet. An error is reported if there is no -* one-to-one association between the three planes in the supplied -* current Frame and the 3 planes in the supplied base Frame. - -* Parameters: -* fset -* Pointer to a FrameSet that has a 3D base Frame and a 3D current -* Frame. -* fsetxy -* Pointer to a location at which to return a pointer to a new FrameSet -* that has a 2D base Frame and a 2D current. The base Frame spans -* axes 1 and 2 of the 3D base Frame in "fset". -* labelxy -* Returned holding flags indicating if the two axes of the current -* Frame in *fsetxy should be labelled or not. -* wcsxy -* Returned holding the zero based axis index within the current Frame -* of the supplied FrameSet that corresponds to each of the two -* current Frame axes in the "fsetxy" FrameSet. -* fsetxz -* Pointer to a location at which to return a pointer to a new FrameSet -* that has a 2D base Frame and a 2D current. The base Frame spans -* axes 1 and 3 of the 3D base Frame in "fset". -* labelxz -* Returned holding flags indicating if the two axes of the current -* Frame in *fsetxz should be labelled or not. -* wcsxz -* Returned holding the zero based axis index within the current Frame -* of the supplied FrameSet that corresponds to each of the two -* current Frame axes in the "fsetxz" FrameSet. -* fsetyz -* Pointer to a location at which to return a pointer to a new FrameSet -* that has a 2D base Frame and a 2D current. The base Frame spans -* axes 2 and 3 of the 3D base Frame in "fset". -* labelyz -* Returned holding flags indicating if the two axes of the current -* Frame in *fsetyz should be labelled or not. -* wcsyz -* Returned holding the zero based axis index within the current Frame -* of the supplied FrameSet that corresponds to each of the two -* current Frame axes in the "fsetxy" FrameSet. -* baseplane -* Index of the plane that is spanned by two connected 3D axes. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Null pointers will be returned for the three new FrameSets if this -* function is invoked with the global status set, or if it should fail -* for any reason. -* - Each returned FrameSet has 2 Frames: Frame 1 is the base Frame -* and is spanned by 2 of the 3 axes in the base Frame of the supplied -* FrameSet; Frame 2 is the current Frame and is spanned by 2 of the 3 -* axes in the current Frame of the supplied FrameSet. Any future changes -* to this function that alter this structure should reflected in -* equivalent changes to functions CreatePlots and UpdatePlots. -*/ - -/* Local Variables: */ - AstFrame *bfrm2d; - AstFrame *bfrm; - AstFrame *cfrm1d; - AstFrame *cfrm2d; - AstFrame *cfrm; - AstFrame *dummy; - AstFrameSet *fset1; - AstFrameSet *fset2; - AstFrameSet *fset3; - AstMapping *map1d; - AstMapping *map2d; - AstMapping *map; - AstMapping *smap; - AstUnitMap *unit1d; - int *axout; - int *other_axout; - int axin2[ 2 ]; - int axin[ 2 ]; - int i; - int label1[ 2 ]; - int label2[ 2 ]; - int label3[ 2 ]; - int other_axin; - int wcsax1[ 2 ]; - int wcsax2[ 2 ]; - int wcsax3[ 2 ]; - -/* Initialise. */ - *fsetxy = NULL; - *fsetxz = NULL; - *fsetyz = NULL; - *baseplane = 0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the simplified base -> current Mapping form the supplied FrameSet. - Also get the base and current Frames themselves. */ - map = astGetMapping( fset, AST__BASE, AST__CURRENT ); - smap = astSimplify( map ); - map = astAnnul( map ); - cfrm = astGetFrame( fset, AST__CURRENT ); - bfrm = astGetFrame( fset, AST__BASE ); - -/* Create a 1D UnitMap. */ - unit1d = astUnitMap( 1, "", status ); - -/* First try to identify a pair of base Frame axes that map onto a pair - of current Frame axes. This will be the case for instance if the 3D - FrameSet describes a spectral cube in which two of the axes are spanned - by a SkyFrame. We try all three possible pairs of axes in turn until a - pair is found succesfully. */ - for( i = 0; i < 3 && ! *fsetxy; i++ ) { - axin[ 0 ] = ( i < 2 ) ? 0 : 1; - axin[ 1 ] = ( i == 0 ) ? 1 : 2; - -/* Try to get a Mapping that connects the inputs given by axin to a - distinct subset of outputs. */ - axout = astMapSplit( smap, 2, axin, &map2d ); - -/* If succesful, check that the 2 inputs correspond to exactly 2 outputs. */ - if( map2d ){ - if( astGetNout( map2d ) == 2 ) { - -/* Get the index of the other input axis (the one not included in the pair). */ - other_axin = 3 - axin[ 0 ] - axin[ 1 ]; - -/* Try to get a Mapping that connects this remaining input to a distinct - subset of outputs. */ - other_axout = astMapSplit( smap, 1, &other_axin, &map1d ); - -/* If succesful, check that the 1 input correspond to exactly 1 output. */ - if( map1d ){ - if( astGetNout( map1d ) == 1 ) { - -/* Pick the two axes from the 3D base and current Frames that correspond to - the paired axes found above. */ - bfrm2d = astPickAxes( bfrm, 2, axin, NULL ); - cfrm2d = astPickAxes( cfrm, 2, axout, NULL ); - -/* Pick the axis from the 3D current Frame that correspond to - the other axis. */ - cfrm1d = astPickAxes( cfrm, 1, other_axout, NULL ); - -/* Construct a FrameSet using these 2D Frames and Mapping. */ - fset1 = astFrameSet( bfrm2d, "", status ); - astAddFrame( fset1, AST__BASE, map2d, cfrm2d ); - - bfrm2d = astAnnul( bfrm2d ); - cfrm2d = astAnnul( cfrm2d ); - map2d = astAnnul( map2d ); - -/* Indicate that both axes in the current Frame of this FrameSet should - be labelled. */ - label1[ 0 ] = 1; - label1[ 1 ] = 1; - -/* Store the index of the axis within the supplied current Frame that - corresponds to each axis in the current Frame of the FrameSet created - above. */ - wcsax1[ 0 ] = axout[ 0 ]; - wcsax1[ 1 ] = axout[ 1 ]; - -/* Pick the two axes from the 3D base Frame that correspond to the first of - the paired axes, and the unpaired axis. Order them so that we get the - 2 axes in the order xy, xz or yz. Also, store the index of the axis - within the supplied current Frame that corresponds to each axis in - the current Frame of the FrameSet created below. */ - if( i < 2 ) { - axin2[ 0 ] = axin[ 0 ]; - axin2[ 1 ] = other_axin; - wcsax2[ 0 ] = axout[ 0 ]; - wcsax2[ 1 ] = other_axout[ 0 ]; - } else { - axin2[ 0 ] = other_axin; - axin2[ 1 ] = axin[ 0 ]; - wcsax2[ 0 ] = other_axout[ 0 ]; - wcsax2[ 1 ] = axout[ 0 ]; - } - bfrm2d = astPickAxes( bfrm, 2, axin2, NULL ); - -/* The corresponding current Frame in the new FrameSet will be a compound - 2D Frame holding the other current Frame axis and a copy of the input - base Frame axis. Combine them so that we get the 2 axes in the order - xy, xz or yz. */ - dummy = astPickAxes( bfrm, 1, axin, NULL ); - if( i < 2 ) { - cfrm2d = (AstFrame *) astCmpFrame( dummy, cfrm1d, "", status ); - } else { - cfrm2d = (AstFrame *) astCmpFrame( cfrm1d, dummy, "", status ); - } - dummy = astAnnul( dummy ); - -/* The Mapping that joins this 2D base Frame to the 2D current Frame uses - the above 1D mapping for the other axis, and a UnitMap for the copied - base Frame axis. */ - if( i < 2 ) { - map2d = (AstMapping *) astCmpMap( unit1d, map1d, 0, "", status ); - } else { - map2d = (AstMapping *) astCmpMap( map1d, unit1d, 0, "", status ); - } - -/* Construct a FrameSet using these 2D Frames and Mapping. */ - fset2 = astFrameSet( bfrm2d, "", status ); - astAddFrame( fset2, AST__BASE, map2d, cfrm2d ); - - bfrm2d = astAnnul( bfrm2d ); - cfrm2d = astAnnul( cfrm2d ); - map2d = astAnnul( map2d ); - -/* Indicate that only one of the axes in the current Frame of this FrameSet - should be labelled. */ - if( i < 2 ) { - label2[ 0 ] = 0; - label2[ 1 ] = 1; - } else { - label2[ 0 ] = 1; - label2[ 1 ] = 0; - } - -/* Pick the two axes from the 3D base Frame that correspond to the second - of the paired axes, and the unpaired axis. Order them so that we get the - 2 axes in the order xy, xz or yz. Also, store the index of the axis - within the supplied current Frame that corresponds to each axis in - the current Frame of the FrameSet created below. */ - if( i == 0 ) { - axin2[ 0 ] = axin[ 1 ]; - axin2[ 1 ] = other_axin; - wcsax3[ 0 ] = axout[ 1 ]; - wcsax3[ 1 ] = other_axout[ 0 ]; - } else { - axin2[ 0 ] = other_axin; - axin2[ 1 ] = axin[ 1 ]; - wcsax3[ 0 ] = other_axout[ 0 ]; - wcsax3[ 1 ] = axout[ 1 ]; - } - bfrm2d = astPickAxes( bfrm, 2, axin2, NULL ); - -/* The corresponding current Frame in the new FrameSet will be a compound - 2D Frame holding the other current Frame axis and a copy of the input - base Frame axis. Combine them so that we get the 2 axes in the order - xy, xz or yz. */ - dummy = astPickAxes( bfrm, 1, axin + 1, NULL ); - if( i == 0 ) { - cfrm2d = (AstFrame *) astCmpFrame( dummy, cfrm1d, "", status ); - } else { - cfrm2d = (AstFrame *) astCmpFrame( cfrm1d, dummy, "", status ); - } - dummy = astAnnul( dummy ); - -/* The Mapping that joins this 2D base Frame to the 2D current Frame uses - the above 1D mapping for the other axis, and a UnitMap for the copied - base Frame axis. */ - if( i == 0 ) { - map2d = (AstMapping *) astCmpMap( unit1d, map1d, 0, "", status ); - } else { - map2d = (AstMapping *) astCmpMap( map1d, unit1d, 0, "", status ); - } - -/* Construct a FrameSet using these 2D Frames and Mapping. */ - fset3 = astFrameSet( bfrm2d, "", status ); - astAddFrame( fset3, AST__BASE, map2d, cfrm2d ); - - bfrm2d = astAnnul( bfrm2d ); - cfrm2d = astAnnul( cfrm2d ); - map2d = astAnnul( map2d ); - -/* Indicate that neither axis in the current Frame of this FrameSet - should be labelled. */ - label3[ 0 ] = 0; - label3[ 1 ] = 0; - -/* Store each FrameSet in the correct returned pointer. */ - if( i == 0 ) { - *baseplane = XY; - *fsetxy = fset1; - *fsetxz = fset2; - *fsetyz = fset3; - - labelxy[ 0 ] = label1[ 0 ]; - labelxy[ 1 ] = label1[ 1 ]; - labelxz[ 0 ] = label2[ 0 ]; - labelxz[ 1 ] = label2[ 1 ]; - labelyz[ 0 ] = label3[ 0 ]; - labelyz[ 1 ] = label3[ 1 ]; - - wcsxy[ 0 ] = wcsax1[ 0 ]; - wcsxy[ 1 ] = wcsax1[ 1 ]; - wcsxz[ 0 ] = wcsax2[ 0 ]; - wcsxz[ 1 ] = wcsax2[ 1 ]; - wcsyz[ 0 ] = wcsax3[ 0 ]; - wcsyz[ 1 ] = wcsax3[ 1 ]; - - } else if( i == 1 ) { - *baseplane = XZ; - *fsetxy = fset2; - *fsetxz = fset1; - *fsetyz = fset3; - - labelxy[ 0 ] = label2[ 0 ]; - labelxy[ 1 ] = label2[ 1 ]; - labelxz[ 0 ] = label1[ 0 ]; - labelxz[ 1 ] = label1[ 1 ]; - labelyz[ 0 ] = label3[ 0 ]; - labelyz[ 1 ] = label3[ 1 ]; - - wcsxy[ 0 ] = wcsax2[ 0 ]; - wcsxy[ 1 ] = wcsax2[ 1 ]; - wcsxz[ 0 ] = wcsax1[ 0 ]; - wcsxz[ 1 ] = wcsax1[ 1 ]; - wcsyz[ 0 ] = wcsax3[ 0 ]; - wcsyz[ 1 ] = wcsax3[ 1 ]; - - } else { - *baseplane = YZ; - *fsetxy = fset2; - *fsetxz = fset3; - *fsetyz = fset1; - - labelxy[ 0 ] = label2[ 0 ]; - labelxy[ 1 ] = label2[ 1 ]; - labelxz[ 0 ] = label3[ 0 ]; - labelxz[ 1 ] = label3[ 1 ]; - labelyz[ 0 ] = label1[ 0 ]; - labelyz[ 1 ] = label1[ 1 ]; - - wcsxy[ 0 ] = wcsax2[ 0 ]; - wcsxy[ 1 ] = wcsax2[ 1 ]; - wcsxz[ 0 ] = wcsax3[ 0 ]; - wcsxz[ 1 ] = wcsax3[ 1 ]; - wcsyz[ 0 ] = wcsax1[ 0 ]; - wcsyz[ 1 ] = wcsax1[ 1 ]; - - } - -/* Free resources */ - cfrm1d = astAnnul( cfrm1d ); - } - -/* Free resources */ - map1d = astAnnul( map1d ); - other_axout = astFree( other_axout ); - } - } - -/* Free resources */ - if( map2d ) map2d = astAnnul( map2d ); - axout = astFree( axout ); - -/* Leave the loop if we now have the required FrameSets, or an error has - occurred. */ - if( *fsetxy || !astOK ) break; - - } - } - -/* Free resources */ - cfrm = astAnnul( cfrm ); - bfrm = astAnnul( bfrm ); - smap = astAnnul( smap ); - unit1d = astAnnul( unit1d ); - -/* Return null pointers if an error has occurred. */ - if( !astOK ) { - *fsetxy = astAnnul( *fsetxy ); - *fsetxz = astAnnul( *fsetxz ); - *fsetyz = astAnnul( *fsetyz ); - -/* Report an error if the supplied FrameSet could not be split into 3 - independent 2D planes. */ - } if( ! *fsetxy ) { - astError( AST__3DFSET, "astInitPlot3D(Plot3D): Supplied %s contains " - "no independent axes.", status, astGetClass( fset ) ); - } -} - -static void StoreAxisInfo( AstPlot3D *this, int labelxy[2], int wcsxy[2], - int labelxz[2], int wcsxz[2], int labelyz[2], - int wcsyz[2], int *status ) { -/* -* Name: -* StoreAxisInfo - -* Purpose: -* Store information connecting 3D axis with associuated 2D Plot axes. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void StoreAxisInfo( AstPlot3D *this, int labelxy[2], int wcsxy[2], -* int labelxz[2], int wcsxz[2], int labelyz[2], -* int wcsyz[2], int *status ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function stores information inside the Plot3D that allows each -* 3D axis to be associated with the 2 Plots that share the 3D axis, -* and with the axis index within each of these two Plots. - -* Parameters: -* this -* Pointer to the Plot3D. -* labelxy -* Flags indicating if the two axes of the current Frame in the XY -* Plot should be labelled or not. -* wcsxy -* The zero based axis index within the 3D current Frame that -* corresponds to each of the two current Frame axes in the XY Plot. -* A value of -1 should be used for 2D axes that do not correspond -* to any 3D axis. -* labelxz -* Flags indicating if the two axes of the current Frame in the XZ -* Plot should be labelled or not. -* wcsxz -* The zero based axis index within the 3D current Frame that -* corresponds to each of the two current Frame axes in the XZ Plot. -* A value of -1 should be used for 2D axes that do not correspond -* to any 3D axis. -* labelyz -* Flags indicating if the two axes of the current Frame in the YZ -* Plot should be labelled or not. -* wcsyz -* The zero based axis index within the 3D current Frame that -* corresponds to each of the two current Frame axes in the YZ Plot. -* A value of -1 should be used for 2D axes that do not correspond -* to any 3D axis. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int axis2d; - int axis3d; - int gotfirst; - int gotsecond; - int temp; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Store information that allows each 3D WCS axis to be associated with - a pair of Plots. Also store the WCS axis within each Plot that - corresponds to the 3D WCS axis. Do each 3D WCS axis in turn. */ - for( axis3d = 0; axis3d < 3; axis3d++ ) { - -/* Indicate we have not yet found either of the two Plots that share the - current 3D axis. */ - gotfirst = 0; - gotsecond = 0; - -/* Check each of the 2 axes in the plot spanning the XY face of the 3D - graphics cube. Break early if we have found both Plots for the current - 3D WCS axis. */ - for( axis2d = 0; axis2d < 2 && !gotsecond; axis2d++ ) { - -/* See if this 2D axis corresponds to the required 3D axis. If so, store - the Plot identifier and the 2D axis index. */ - if( wcsxy[ axis2d ] == axis3d ) { - if( gotfirst ) { - this->axis_plot2[ axis3d ] = XY; - this->axis_index2[ axis3d ] = axis2d; - gotsecond = 1; - } else { - this->axis_plot1[ axis3d ] = XY; - this->axis_index1[ axis3d ] = axis2d; - gotfirst = 1; - } - } - } - -/* Check the plot spanning the XZ face in the same way. */ - for( axis2d = 0; axis2d < 2 && !gotsecond; axis2d++ ) { - if( wcsxz[ axis2d ] == axis3d ) { - if( gotfirst ) { - this->axis_plot2[ axis3d ] = XZ; - this->axis_index2[ axis3d ] = axis2d; - gotsecond = 1; - } else { - this->axis_plot1[ axis3d ] = XZ; - this->axis_index1[ axis3d ] = axis2d; - gotfirst = 1; - } - } - } - -/* Check the plot spanning the YZ face in the same way. */ - for( axis2d = 0; axis2d < 2 && !gotsecond; axis2d++ ) { - if( wcsyz[ axis2d ] == axis3d ) { - if( gotfirst ) { - this->axis_plot2[ axis3d ] = YZ; - this->axis_index2[ axis3d ] = axis2d; - gotsecond = 1; - } else { - this->axis_plot1[ axis3d ] = YZ; - this->axis_index1[ axis3d ] = axis2d; - gotfirst = 1; - } - } - } - } - -/* Ensure that the first Plot within each pair is the one that is used to - generate labels for the 3D axis. */ - for( axis2d = 0; axis2d < 2; axis2d++ ) { - if( labelxy[ axis2d ] ) { - axis3d = wcsxy[ axis2d ]; - if( this->axis_plot1[ axis3d ] != XY ){ - temp = this->axis_plot1[ axis3d ]; - this->axis_plot1[ axis3d ] = this->axis_plot2[ axis3d ]; - this->axis_plot2[ axis3d ] = temp; - - temp = this->axis_index1[ axis3d ]; - this->axis_index1[ axis3d ] = this->axis_index2[ axis3d ]; - this->axis_index1[ axis3d ] = temp; - } - } - } - - for( axis2d = 0; axis2d < 2; axis2d++ ) { - if( labelxz[ axis2d ] ) { - axis3d = wcsxz[ axis2d ]; - if( this->axis_plot1[ axis3d ] != XZ ){ - temp = this->axis_plot1[ axis3d ]; - this->axis_plot1[ axis3d ] = this->axis_plot2[ axis3d ]; - this->axis_plot2[ axis3d ] = temp; - - temp = this->axis_index1[ axis3d ]; - this->axis_index1[ axis3d ] = this->axis_index2[ axis3d ]; - this->axis_index1[ axis3d ] = temp; - } - } - } - - for( axis2d = 0; axis2d < 2; axis2d++ ) { - if( labelyz[ axis2d ] ) { - axis3d = wcsyz[ axis2d ]; - if( this->axis_plot1[ axis3d ] != YZ ){ - temp = this->axis_plot1[ axis3d ]; - this->axis_plot1[ axis3d ] = this->axis_plot2[ axis3d ]; - this->axis_plot2[ axis3d ] = temp; - - temp = this->axis_index1[ axis3d ]; - this->axis_index1[ axis3d ] = this->axis_index2[ axis3d ]; - this->axis_index1[ axis3d ] = temp; - } - } - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Plot3D. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the astTestAttrib protected -* method inherited from the Plot class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Plot3D's attributes. - -* Parameters: -* this -* Pointer to the Plot3D. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPlot *plot; /* Pointer to specific Plot */ - AstPlot3D *this; /* Pointer to the Plot3D structure */ - char attname[50]; /* Plot attribute base name */ - char patt[50]; /* Plot attribute full name */ - char spec[10]; /* Plane specification */ - int axis; /* Axis index */ - int len; /* Length of attrib string */ - int nc; /* Number of character read */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* Norm. */ -/* ----- */ - if ( !strcmp( attrib, "norm" ) ) { - result = astTestNorm( this, 0 ) || - astTestNorm( this, 1 ) || - astTestNorm( this, 2 ); - -/* Norm(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "norm(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestNorm( this, axis - 1 ); - -/* RootCorner. */ -/* ----------- */ - } else if ( !strcmp( attrib, "rootcorner" ) ) { - result = astTestRootCorner( this ); - - -/* ..._XY etc */ -/* ---------- */ - } else if ( nc = 0, - ( 2 == astSscanf( attrib, "%[a-z]_%[xyz]%n", attname, spec, - &nc ) ) ) { - - if( !strcmp( spec, "xy" ) || !strcmp( spec, "yx" ) ) { - plot = this->plotxy; - } else if( !strcmp( spec, "xz" ) || !strcmp( spec, "zx" ) ) { - plot = this->plotyz; - } else if( !strcmp( spec, "yz" ) || !strcmp( spec, "zy" ) ) { - plot = this->plotxz; - } else { - plot = NULL; - } - - if( plot ) { - sprintf( patt, "%s%s", attname, attrib + nc ); - result = astTestAttrib( plot, patt ); - - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static void Text( AstPlot *this_plot, const char *text, const double pos[], - const float up[], const char *just, int *status ){ -/* -* Name: -* Text - -* Purpose: -* Draw a text string for a Plot3D. - -* Type: -* Private member function. - -* Synopsis: -* #include "plot3d.h" -* void Text( AstPlot *this, const char *text, const double pos[], -* const float up[], const char *just, int *status ) - -* Class Membership: -* Plot3D method (overrides the Text method inherited form the Plot -* class). - -* Description: -* This function draws a string of text at a position specified in -* the physical coordinate system of a Plot3D. The physical position -* is transformed into graphical coordinates to determine where the -* text should appear within the plotting area. -* -* The text is drawn on a 2D plane that has a normal vector given by the -* current value of the Plot3D's "Norm" attribute. - -* Parameters: -* this -* Pointer to the Plot3D. -* text -* Pointer to a null-terminated character string containing the -* text to be drawn. Trailing white space is ignored. -* pos -* An array, with one element for each axis of the Plot3D, giving -* the physical coordinates of the point where the reference -* position of the text string is to be placed. -* up -* An array holding the components of a vector in the "up" -* direction of the text (in graphical coordinates). For -* example, to get horizontal text, the vector {0.0f,1.0f} should -* be supplied. "Up" is taken to be the projection of the positive -* Z axis onto the plane specified by the current value of the -* just -* Pointer to a null-terminated character string identifying the -* reference point for the text being drawn. The first character in -* this string identifies the reference position in the "up" direction -* and may be "B" (baseline), "C" (centre), "T" (top) or "M" (bottom). -* The second character identifies the side-to-side reference position -* and may be "L" (left), "C" (centre) or "R" (right ). The string is -* case-insensitive, and only the first two characters are significant. -* -* For example, a value of "BL" means that the left end of the -* baseline of the original (un-rotated) text is to be drawn at the -* position given by "pos". -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMapping *mapping; /* Pointer to graphics->physical mapping */ - AstPlot3D *this; /* Pointer to the Plot3D structure */ - AstPointSet *pset1; /* PointSet holding physical positions */ - AstPointSet *pset2; /* PointSet holding graphics positions */ - char *ltext; /* Local copy of "text" excluding trailing spaces */ - char ljust[3]; /* Upper case copy of "just" */ - const char *class; /* Object class */ - const char *method; /* Current method */ - const double **ptr1; /* Pointer to physical positions */ - double **ptr2; /* Pointer to graphics positions */ - float norm[ 3 ]; /* Single precision normal vector */ - float ref[ 3 ]; /* Single precision ref position */ - int axis; /* Axis index */ - int escs; /* Original astEscapes value */ - int naxes; /* No. of axes in the base Frame */ - int ncoord; /* No. of axes in the current Frame */ - int ulen; /* Length of "text" excluding trailing spaces */ - -/* Check the global error status. */ - if ( !astOK || !text ) return; - -/* Store a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_plot; - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astText"; - class = astClass( this ); - -/* Check the base Frame of the Plot is 3-D. */ - naxes = astGetNin( this ); - if( naxes != 3 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 3.", status, method, class, naxes, class ); - } - -/* Ensure AST functions do not included graphical escape sequences in any - returned text strings. This is because the Plot3D implementation of - this method cannot currently handle graphical escape sequences. */ - escs = astEscapes( 0 ); - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__TEXT_ID, 1, GRF__TEXT, method, class ); - -/* Get the number of coordinates in the physical coordinate frame. */ - ncoord = astGetNout( this ); - -/* Create a PointSet to hold the supplied physical coordinates. */ - pset1 = astPointSet( 1, ncoord, "", status ); - -/* Allocate memory to hold pointers to the first value on each axis. */ - ptr1 = (const double **) astMalloc( sizeof( const double * )* - (size_t)( ncoord )); - -/* Check the pointer can be used, then store pointers to the first value - on each axis. */ - if( astOK ){ - for( axis = 0; axis < ncoord; axis++ ){ - ptr1[ axis ] = pos + axis; - } - } - -/* Store these pointers in the PointSet. */ - astSetPoints( pset1, (double **) ptr1 ); - -/* Transform the supplied data from the current frame (i.e. physical - coordinates) to the base frame (i.e. graphics coordinates) using - the inverse Mapping defined by the Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - pset2 = astTransform( mapping, pset1, 0, NULL ); - mapping = astAnnul( mapping ); - -/* Get pointers to the graphics coordinates. */ - ptr2 = astGetPoints( pset2 ); - -/* Take a copy of the string excluding any trailing white space. */ - ulen = astChrLen( text ); - ltext = (char *) astStore( NULL, (void *) text, ulen + 1 ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Terminate the local copy of the text string. */ - ltext[ ulen ] = 0; - -/* Produce an upper-case copy of the first two characters in "just". */ - ljust[0] = (char) toupper( (int) just[0] ); - ljust[1] = (char) toupper( (int) just[1] ); - ljust[2] = 0; - -/* Convert the double precision values to single precision, checking for - bad positions. */ - if( ptr2[0][0] != AST__BAD && ptr2[1][0] != AST__BAD && - ptr2[2][0] != AST__BAD ){ - ref[ 0 ] = (float) ptr2[0][0]; - ref[ 1 ] = (float) ptr2[1][0]; - ref[ 2 ] = (float) ptr2[2][0]; - -/* If the nornmal vector has non-zero length, draw the text. */ - norm[ 0 ] = (float) astGetNorm( this, 0 ); - norm[ 1 ] = (float) astGetNorm( this, 1 ); - norm[ 2 ] = (float) astGetNorm( this, 2 ); - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - - if( norm[ 0 ] != 0.0 || norm[ 1 ] != 0.0 || norm[ 2 ] != 0.0 ){ - if( !astG3DText( ltext, ref, ljust, (float *) up, norm ) ) { - astError( AST__GRFER, "%s(%s): Graphics error in astG3DText. ", status, - method, class ); - } - } else if( astOK ) { - astError( AST__ATTIN, "%s(%s): The vector specified by the Norm " - "attribute has zero length.", status, method, class ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - } - -/* Free the local copy of the string. */ - ltext = (char *) astFree( (void *) ltext ); - - } - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Free the memory holding the pointers to the first value on each axis. */ - ptr1 = (const double **) astFree( (void *) ptr1 ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__TEXT_ID, 0, GRF__TEXT, method, class ); - -/* Restore the original value of the flag which says whether graphical - escape sequences should be incldued in any returned text strings. */ - astEscapes( escs ); - -/* Return */ - return; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Use a Plot to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the astTransform protected -* method inherited from the Plot class). - -* Description: -* This function takes a Plot3D and a set of points encapsulated in a -* PointSet and transforms the points from graphics coordinates to -* physical coordinates (in the forward direction). No clipping or -* normalisation is applied. - -* Parameters: -* this -* Pointer to the Plot3D. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate -* transformation should be applied while a zero value requests the -* inverse transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the Plot being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstMapping *map; /* Pointer to the mapping */ - AstPointSet *result; /* Positions in output Frame */ - AstPlot3D *this; /* The Plot3D */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the Plot3D. */ - this = (AstPlot3D *) this_mapping; - -/* Get the Mapping from the base to the current Frame. */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Do the transformation. */ - result = astTransform( map, in, forward, out ); - -/* Annul the mapping. */ - map = astAnnul( map ); - -/* If an error has occurred, annul the result. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; - -} - -static void UpdatePlots( AstPlot3D *this, int *status ) { -/* -* Name: -* UpdatePlots - -* Purpose: -* Update the three 2D plots stored in the Plot3D. - -* Type: -* Private function. - -* Synopsis: -* #include "plot3d.h" -* void UpdatePlots( AstPlot3D *this ) - -* Class Membership: -* Plot3D method. - -* Description: -* This function splits the parent FrameSet up into 3 independent 2D -* FrameSets, each describing a 2D plane in the supplied 3D FrameSet. -* It then uses these 2D FrameSets to update the three Plots in the -* Plot3D, by removing the existing current Frame and adding in the -* new current Frame with the associated Mapping. - -* Parameters: -* this -* Pointer to the Plot3D. - -* Notes: -* - Each of the 3 plots has 3 Frames: Frame 1 is the base (GRAPHICS) -* Frame; Frame 2 is spanned by 2 of the 3 axes in the base Frame of -* the supplied FrameSet; Frame 3 is the current Frame and is spanned -* by 2 of the 3 axes in the current Frame of the supplied FrameSet. -* Any future changes to this function that alter this structure should -* reflected in equivalewnt changes to function CreatePlots. -*/ - -/* Local Variables: */ - AstFrame *frm; - AstFrameSet *fsetxy; - AstFrameSet *fsetxz; - AstFrameSet *fsetyz; - AstFrameSet *fset; - AstMapping *map; - int baseplane; - int labelxy[ 2 ]; - int labelxz[ 2 ]; - int labelyz[ 2 ]; - int wcsxy[ 2 ]; - int wcsxz[ 2 ]; - int wcsyz[ 2 ]; - int rootcorner; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Return without action if the Plot3D does not contain the three 2D - Plots. This may be the case for instance if this function is called - before the Plot3D is fully constructed. */ - if( this->plotxy && this->plotxz && this->plotyz ){ - -/* We need a FrameSet that is equivalent to the one that was used to - construct the Plot3D (i.e. a FrameSet that does not have the GRAPHICS - Frame that was added by the Plot3D constructor). So take a copy of the - parent FrameSet, remove the GRAPHICS Frame (Frame 1) and set the base - Frame to be the Frame that was the base Frame when the Plot3D was - constructed. */ - fset = (AstFrameSet *) astCast( this, dummy_frameset ); - astSetBase( fset, this->pix_frame ); - astRemoveFrame( fset, 1 ); - -/* Split the supplied FrameSet up into 3 FrameSets, each with a 2D base - and current Frame. Each of these FrameSets describes one plane of - the 3D cube. */ - SplitFrameSet( fset, &fsetxy, labelxy, wcsxy, &fsetxz, labelxz, wcsxz, - &fsetyz, labelyz, wcsyz, &baseplane, status ); - -/* First do the XY Plot. Extract the current Frame and base->current - Mapping from the new FrameSet. It is assumed that he base Frame in the - new FrameSet is equivalent to Frame 2 in the existing Plot. This - assumption is based on the way the CreatePlots and SplitFrameSet - functions work, and should be reviewed if either of these functions - is changed. */ - frm = astGetFrame( fsetxy, 2 ); - map = astGetMapping( fsetxy, 1, 2 ); - -/* Add the new Frame into the existing Plot using the Mapping to connect - it to Frame 2 in the Plot. It becomes the current Frame in the Plot. */ - astAddFrame( this->plotxy, 2, map, frm ); - -/* Delete the original current Frame in the Plot since it is not needed - any more. */ - astRemoveFrame( this->plotxy, 3 ); - -/* Set the Plot attributes. */ - SetPlotAttr( this->plotxy, XY, labelxy, status ); - -/* Free resources */ - fsetxy = astAnnul( fsetxy ); - map = astAnnul( map ); - frm = astAnnul( frm ); - -/* Do the same for the XZ plot. */ - frm = astGetFrame( fsetxz, 2 ); - map = astGetMapping( fsetxz, 1, 2 ); - astAddFrame( this->plotxz, 2, map, frm ); - astRemoveFrame( this->plotxz, 3 ); - SetPlotAttr( this->plotxz, XZ, labelxz, status ); - fsetxz = astAnnul( fsetxz ); - map = astAnnul( map ); - frm = astAnnul( frm ); - -/* Do the same for the YZ plot. */ - frm = astGetFrame( fsetyz, 2 ); - map = astGetMapping( fsetyz, 1, 2 ); - astAddFrame( this->plotyz, 2, map, frm ); - astRemoveFrame( this->plotyz, 3 ); - SetPlotAttr( this->plotyz, YZ, labelyz, status ); - fsetyz = astAnnul( fsetyz ); - map = astAnnul( map ); - frm = astAnnul( frm ); - -/* Store information that allows each 3D WCS axis to be associatedf with - a pair of Plots. Also store the WCS axis within each Plot that - corresponds to the 3D WCS axis. */ - StoreAxisInfo( this, labelxy, wcsxy, labelxz, wcsxz, labelyz, wcsyz, status ); - -/* Set up the Edges attributes in the encapsulated Plots to produce labels - on the required edges of the 3D graphics cube. */ - rootcorner = astGetRootCorner( this ); - ChangeRootCorner( this, rootcorner, rootcorner, status ); - -/* Store the plane spanned by two connected 3D axes. */ - this->baseplot = baseplane; - -/* Free remaining resources */ - fset = astAnnul( fset ); - } -} - -static void VSet( AstObject *this_object, const char *settings, - char **text, va_list args, int *status ) { -/* -* Name: -* VSet - -* Purpose: -* Set values for a Plot3D's attributes. - -* Type: -* Private function. - -* Synopsis: -* #include "frameset.h" -* void VSet( AstObject *this, const char *settings, char **text, -* va_list args, int *status ) - -* Class Membership: -* Plot3D member function (over-rides the protected astVSet -* method inherited from the Object class). - -* Description: -* This function assigns a set of attribute values for a Plot3D, -* the attributes and their values being specified by means of a -* string containing a comma-separated list of the form: -* -* "attribute1 = value1, attribute2 = value2, ... " -* -* Here, "attribute" specifies an attribute name and the value to -* the right of each "=" sign should be a suitable textual -* representation of the value to be assigned to that attribute. This -* will be interpreted according to the attribute's data type. -* -* The string supplied may also contain "printf"-style format -* specifiers identified by a "%" sign in the usual way. If -* present, these will be substituted by values supplied as -* optional arguments (as a va_list variable argument list), using -* the normal "printf" rules, before the string is used. - -* Parameters: -* this -* Pointer to the Plot3D. -* settings -* Pointer to a null-terminated string containing a -* comma-separated list of attribute settings. -* text -* Pointer to a location at which to return a pointer to dynamic -* memory holding a copy of the expanded setting string. This memory -* should be freed using astFree when no longer needed. If a NULL -* pointer is supplied, no string is created. -* args -* The variable argument list which contains values to be -* substituted for any "printf"-style format specifiers that -* appear in the "settings" string. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function preserves the integrity of the Plot3D (if -* possible) by appropriately modifying the three encapsulated Plots. -*/ - -/* Invoke the parent astVSet method to set the Plot3D's attribute values. */ - (*parent_vset)( this_object, settings, text, args, status ); - -/* Update the three 2D Plots stored in the Plot3D structure so that they - reflect this modified FrameSet. */ - UpdatePlots( (AstPlot3D *) this_object, status ); -} - -/* Functions which access Plot3D class attributes. */ -/* ----------------------------------------------- */ - -/* RootCorner. */ -/* ----------- */ -/* -*att++ -* Name: -* RootCorner - -* Purpose: -* Specifies which edges of the 3D box should be annotated. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* which edges of the cube enclosing the 3D graphics space are used -* for displaying numerical and descriptive axis labels. The attribute -* value identifies one of the eight corners of the cube within -* which graphics are being drawn (i.e. the cube specified by the -c "graphbox" parameter when astPlot3D -f GRAPHBOX argument when AST_PLOT3D -* was called tp create the Plot3D). Axis labels and tick marks will -* be placed on the three cube edges that meet at the given corner. -* -* The attribute value should consist of three character, each of -* which must be either "U" or "L". The first character in the string -* specifies the position of the corner on the first graphics axis. -* If the character is "U" then the corner is at the upper bound on the -* first graphics axis. If it is "L", then the corner is at the lower -* bound on the first axis. Likewise, the second and third characters -* in the string specify the location of the corner on the second and -* third graphics axes. -* -* For instance, corner "LLL" is the corner that is at the lower bound -* on all three graphics axes, and corner "ULU" is at the upper bound -* on axes 1 and 3 but at the lower bound on axis 2. -* -* The default value is "LLL". - -* Applicability: -* Plot3D -* All Plot3Ds have this attribute. - -*att-- -*/ - -/* Internally, the RootCorner is represented as an integer bit mask, with - bit zero for the X axis, bit 1 for the Y axis and bit 2 for the Z axis. - A bit is set if the corner is at the upper bound on the axis and unset - if it is at the lower bound. A value of -1 indicates that the attribue - has not been assigned a value. */ -astMAKE_GET(Plot3D,RootCorner,int,0,( this->rootcorner == -1 ? 0 : this->rootcorner)) -astMAKE_TEST(Plot3D,RootCorner,( this->rootcorner != -1 )) - - -/* Norm(axis). */ -/* ----------- */ -/* -*att++ -* Name: -* Norm(axis) - -* Purpose: -* Specifies the plane upon which a Plot3D draws text and markers. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of text and markers drawn -* by a Plot3D. It specifies the orientation of the plane upon which -* text and markers will be drawn by all subsequent invocations of the -c astText and astMark functions. -f AST_TEXT and AST_MARK functions. -* -* When setting or getting the Norm attribute, the attribute name must -* be qualified by an axis index in the range 1 to 3. The 3 elements of -* the Norm attribute are together interpreted as a vector in 3D graphics -* coordinates that is normal to the plane upon which text and marks -* should be drawn. When testing or clearing the attribute, the axis -* index is optional. If no index is supplied, then clearing the Norm -* attribute will clear all three elements, and testing the Norm attribute -* will return a non-zero value if any of the three elements are set. -* -* The default value is 1.0 for each of the 3 elements. The length of -* the vector is insignificant, but an error will be reported when -* attempting to draw text or markers if the vector has zero length. - -* Applicability: -* Plot -* All Plot3Ds have this attribute. - -*att-- -*/ -MAKE_CLEAR3(Norm,norm,AST__BAD,3) -MAKE_SET3(Norm,double,norm,value,3) -MAKE_TEST3(Norm,( this->norm[axis] != AST__BAD ),3) -MAKE_GET3(Norm,double,AST__BAD,(this->norm[axis]!=AST__BAD?this->norm[axis]:1.0),3) - - - -/* Functions which access Plot class attributes. */ -/* --------------------------------------------- */ - -/* First do axis specific attributes. */ - -#define MAKE_ALL(attr,type,badval,whichplots) \ - MAKE_CLEAR(attr,whichplots) \ - MAKE_SET(attr,type,whichplots) \ - MAKE_GET(attr,type,badval ) - -MAKE_ALL(MinTick,int,0,0) -MAKE_ALL(Abbrev,int,0,1) -MAKE_ALL(Gap,double,AST__BAD,1) -MAKE_ALL(LogGap,double,AST__BAD,1) -MAKE_ALL(LogPlot,int,0,0) -MAKE_ALL(LogTicks,int,0,0) -MAKE_ALL(LogLabel,int,0,1) -MAKE_ALL(LabelUp,int,0,1) -MAKE_ALL(DrawAxes,int,0,0) -MAKE_ALL(LabelUnits,int,0,1) -MAKE_ALL(MinTickLen,double,0.0,0) -MAKE_ALL(MajTickLen,double,0.0,0) -MAKE_ALL(NumLab,int,0,1) -MAKE_ALL(NumLabGap,double,AST__BAD,1) -MAKE_ALL(TextLab,int,0,1) -MAKE_ALL(TextLabGap,double,AST__BAD,1) - -#undef MAKE_ALL - - -/* Now do attributes that are not axis specific. */ - -#define MAKE_ALL(attr,type) \ - MAKE_CLEAR1(attr) \ - MAKE_SET1(attr,type) - -MAKE_ALL(Ink,int) -MAKE_ALL(Tol,double) -MAKE_ALL(Invisible,int) -MAKE_ALL(TickAll,int) -MAKE_ALL(ForceExterior,int) -MAKE_ALL(Border,int) -MAKE_ALL(Clip,int) -MAKE_ALL(ClipOp,int) -MAKE_ALL(Escape,int) -MAKE_ALL(Grid,int) -MAKE_ALL(Labelling,int) - -#undef MAKE_ALL - - - -/* First do element-specific attributes. */ - -#define MAKE_ALL(attr,type) \ - MAKE_CLEAR2(attr) \ - MAKE_SET2(attr,type) - -MAKE_ALL(Style,int) -MAKE_ALL(Font,int) -MAKE_ALL(Colour,int) -MAKE_ALL(Width,double) -MAKE_ALL(Size,double) - -#undef MAKE_ALL - - - - - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Plot3D objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Plot3D objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstPlot3D *in; /* Pointer to input Plot3D */ - AstPlot3D *out; /* Pointer to output Plot3D */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Plot3Ds. */ - in = (AstPlot3D *) objin; - out = (AstPlot3D *) objout; - -/* Nullify the pointers stored in the output object since these will - currently be pointing at the input data (since the output is a simple - byte-for-byte copy of the input). Otherwise, the input data could be - freed by accidient if the output object is deleted due to an error - occuring in this function. */ - out->plotxy = NULL; - out->plotxz = NULL; - out->plotyz = NULL; - -/* Copy the encapsulated Plots */ - if( in->plotxy ) out->plotxy = astCopy( in->plotxy ); - if( in->plotxz ) out->plotxz = astCopy( in->plotxz ); - if( in->plotyz ) out->plotyz = astCopy( in->plotyz ); - -/* If an error has occurred, free the output resources. */ - if( !astOK ) Delete( (AstObject *) out, status ); - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Plot3D objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Plot3D objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstPlot3D *this; - -/* Release the memory referred to in the Plot3D structure. */ - this = (AstPlot3D *) obj; - if( this ) { - this->plotxy = astDelete( this->plotxy ); - this->plotxz = astDelete( this->plotxz ); - this->plotyz = astDelete( this->plotyz ); - } -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Plot3D objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Plot3D class to an output Channel. - -* Parameters: -* this -* Pointer to the Plot3D whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstPlot3D *this; - double dval; - char key[ KEY_LEN + 1 ]; - int axis; - int helpful; - int ival; - int set; - const char *text; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot3D structure. */ - this = (AstPlot3D *) this_object; - -/* Write out values representing the instance variables for the - Plot3D class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - - -/* Norm. */ -/* ----- */ - for ( axis = 0; axis < 3; axis++ ) { - dval = astGetNorm( this, axis ); - helpful = ( dval != -DBL_MAX ); - (void) sprintf( key, "Norm%d", axis + 1 ); - astWriteDouble( channel, key, 0, helpful, dval, "Text plane normal vector"); - } - -/* RootCorner. */ -/* ----------- */ - set = TestRootCorner( this, status ); - ival = set ? GetRootCorner( this, status ) : astGetRootCorner( this ); - text = RootCornerString( ival, status ); - if( text ) { - astWriteString( channel, "RootCn", set, 1, text, "Corner where labelled axes meet" ); - } else if( astOK ) { - astError( AST__INTER, "astDump(Plot3D): Illegal value %d found for " - "RootCorner attribute (interbal AST programming error).", status, - ival ); - } - -/* Labelled axes */ - astWriteInt( channel, "AxPlX1", 1, 1, this->axis_plot1[0], - "Plot used to label the 3D X axis" ); - astWriteInt( channel, "AxPlY1", 1, 1, this->axis_plot1[1], - "Plot used to label the 3D Y axis" ); - astWriteInt( channel, "AxPlZ1", 1, 1, this->axis_plot1[2], - "Plot used to label the 3D Z axis" ); - astWriteInt( channel, "AxInX1", 1, 1, this->axis_index1[0], - "Plot axis index used to label the 3D X axis" ); - astWriteInt( channel, "AxInY1", 1, 1, this->axis_index1[1], - "Plot axis index used to label the 3D Y axis" ); - astWriteInt( channel, "AxInZ1", 1, 1, this->axis_index1[2], - "Plot axis index used to label the 3D Z axis" ); - -/* Unlabelled axes */ - astWriteInt( channel, "AxPlX2", 1, 1, this->axis_plot2[0], - "Other Plot touching the 3D X axis" ); - astWriteInt( channel, "AxPlY2", 1, 1, this->axis_plot2[1], - "Other Plot touching the 3D Y axis" ); - astWriteInt( channel, "AxPlZ2", 1, 1, this->axis_plot2[2], - "Other Plot touching the 3D Z axis" ); - astWriteInt( channel, "AxInX2", 1, 1, this->axis_index2[0], - "Other Plot axis index touching the 3D X axis" ); - astWriteInt( channel, "AxInY2", 1, 1, this->axis_index2[1], - "Other Plot axis index touching the 3D Y axis" ); - astWriteInt( channel, "AxInZ2", 1, 1, this->axis_index2[2], - "Other Plot axis index touching the 3D Z axis" ); - -/* The Plot that spans the two connected axes. */ - astWriteInt( channel, "BasePl", 1, 1, this->baseplot, - "Plot spanning two connected 3D axes" ); - -/* XY Plot */ - astWriteObject( channel, "PlotXY", 1, 1, this->plotxy, - "Plot describing the XY plane" ); - -/* XZ Plot */ - astWriteObject( channel, "PlotXZ", 1, 1, this->plotxz, - "Plot describing the XZ plane" ); - -/* YZ Plot */ - astWriteObject( channel, "PlotYZ", 1, 1, this->plotyz, - "Plot describing the YZ plane" ); - -/* The index within the Plot3D FrameSet, of the original base Frame in - the FrameSet supplied when the Plot3D was constructed. */ - astWriteInt( channel, "PixFrm", 1, 0, this->pix_frame, - "Index of original base Frame" ); - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPlot3D and astCheckPlot3D functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Plot3D,Plot) -astMAKE_CHECK(Plot3D) - - -AstPlot3D *astPlot3D_( void *frame_void, const float *graphbox, - const double *basebox, const char *options, int *status, ...) { -/* -*+ -* Name: -* astPlot3D - -* Purpose: -* Create a Plot3D. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot3d.h" -* AstPlot3D *astPlot3D( AstFrame *frame, const float *graphbox, -* const double *basebox, const char *options, ..., int *status ) - -* Class Membership: -* Plot3D constructor. - -* Description: -* This function creates a new Plot3D and optionally initialises its -* attributes. -* -* The supplied Frame (or the base frame if a FrameSet was supplied) is -* assumed to be related to the graphics world coordinate system by a -* simple shift and scale along each axis. The mapping between graphics -* world coordinates and this Frame is specified by supplying the -* coordinates in both systems at the lower bounds and upper bounds corners -* of a box on the graphics device. By default, no graphics will be -* produced outside the supplied box, but this default behaviour can be -* changed by setting explicit values for the various clipping attributes. - -* Parameters: -* frame -* A pointer to a Frame or FrameSet to be annotated. If a NULL pointer -* is supplied, then a default 3-D Frame will be created to which labels, -* etc, can be attached by setting the relevant Frame attributes. -* graphbox -* A pointer to an array of 6 values giving the graphics world -* coordinates of the lower bounds and upper bound corners of a box on -* the graphics output device. The first triple of values should be the -* coordinates of the lower bounds corner of the box and the second -* triple of values should be the coordinates of the upper bounds corner. -* basebox -* A pointer to an array of 6 values giving the coordinates in the -* supplied Frame, or base frame of the supplied FrameSet, at the -* lower bounds corner and upper bounds corners of the box specified -* by parameter graphbox. These should be supplied in the same order as -* for parameter "graphbox". -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new Plot3D. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new Plot3D. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic Plot3D constructor which -* is available via the protected interface to the Plot3D class. -* A public interface is provided by the astPlot3DId_ function. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPlot3D *new; /* Pointer to new Plot3D */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - new = NULL; - -/* Obtain and validate a pointer to any supplied Frame structure. */ - if( frame_void ){ - frame = astCheckFrame( frame_void ); - } else { - frame = NULL; - } - -/* Check the pointer can be used. */ - if ( astOK ) { - -/* Initialise the Plot3D, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPlot3D( NULL, sizeof( AstPlot3D ), !class_init, - &class_vtab, "Plot3D", frame, graphbox, - basebox ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - Plot's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new Plot. */ - return new; -} - -AstPlot3D *astInitPlot3D_( void *mem, size_t size, int init, - AstPlot3DVtab *vtab, const char *name, - AstFrame *frame, const float *graphbox, - const double *basebox, int *status ) { -/* -*+ -* Name: -* astInitPlot3D - -* Purpose: -* Initialise a Plot3D. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot3d.h" -* AstPlot3D *astInitPlot3D( void *mem, size_t size, int init, -* AstPlotVtab *vtab, const char *name, -* AstFrame *frame, const float *graphbox, -* const double *basebox ) - -* Class Membership: -* Plot3D initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new Plot3D object. It allocates memory (if -* necessary) to accommodate the Plot3D plus any additional data -* associated with the derived class. It then initialises a -* Plot3D structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual function -* table for a Plot3D at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Plot3D is to be -* created. This must be of sufficient size to accommodate the -* Plot3D data (sizeof(Plot3D)) plus any data used by -* the derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Plot3D (plus derived -* class data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also stored -* in the Plot3D structure, so a valid value must be supplied -* even if not required for allocating memory. -* init -* A logical flag indicating if the Plot3D's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Plot3D. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object belongs -* (it is this pointer value that will subsequently be returned by -* the astGetClass method). -* fset -* A pointer to the Frame or Frameset to be annotated. -* graphbox -* A pointer to an array of 6 values giving the graphics coordinates -* of the bottom left and top right corners of a box on the graphics -* output device. The first triple of values should be the graphics -* coordinates of the bottom left corner of the box and the second -* triple of values are the graphics coordinates of the top right corner. -* basebox -* A pointer to an array of 6 values giving the coordinates in the -* supplied Frame or base Frame of the supplied FrameSet at the bottom -* left and top right corners of the box specified by parameter graphbox. -* These should be supplied in the same order as for parameter "graphbox". - -* Returned Value: -* A pointer to the new Plot3D. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstFrame *baseframe = NULL; /* Pointer to base frame */ - AstFrame *graphicsframe = NULL; /* Pointer to graphics frame */ - AstFrameSet *fset0 = NULL; /* The n-D FrameSet to be annotated */ - AstFrameSet *fset = NULL; /* The 2-D FrameSet to be annotated */ - AstMapping *map = NULL; /* Mapping for converting bbox -> gbox */ - AstPlot3D *new = NULL; /* Pointer to new Plot3D */ - char *mess = NULL; /* Pointer to a descriptive message */ - double djunkbox[ 4 ] = { 0.0, 0.0, 1.0, 1.0 }; /* Dummy 2D basebox */ - float fjunkbox[ 4 ] = { 0.0, 0.0, 1.0, 1.0 }; /* Dummy 2D graphbox */ - int bi; /* Index of base frame */ - int ci; /* Index of current frame */ - int i; /* Loop count */ - int ii; /* Loop count */ - int naxes; /* No. of axes in frame */ - int nfrm; /* Number of Frames in frameset */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitPlot3DVtab( vtab, name ); - -/* First of all we need to ensure that we have a FrameSet and a base - Frame on which to base the new Plot3D. If a NULL Frame pointer was - supplied, create a default 3-D Frame, and then create a FrameSet - containing just this default Frame. Also store a pointer to a - message which can be used to describe the object within error - messages. */ - if( !frame ){ - baseframe = astFrame( 3, "", status ); - fset = astFrameSet( baseframe, "", status ); - mess = "default 3-d Frame"; - -/* If an object was supplied, report an error if it is not a Frame or - an object derived from a Frame (such as a FrameSet). */ - } else if( !astIsAFrame( frame ) ){ - if( astOK ){ - astError( AST__BDOBJ, "astInitPlot3D(%s): Supplied Object (class '%s') " - "is not a Frame.", status, name, astGetClass( frame ) ); - } - -/* If the supplied object is a Plot3D or an object derived from a Plot3D - (a Plot3D is a sort of Frame and so will pass the above test), extract a - FrameSet from the Plot3D, and clear the Domain attribute for any existing - Frames which have Domain GRAPHICS. */ - } else if( astIsAPlot3D( frame ) ){ - fset0 = astFrameSet( frame, "", status ); - fset = astCopy( fset0 ); - fset0 = astAnnul( fset0 ); - - for( i = 0; i < astGetNframe( fset ); i++ ) { - graphicsframe = astGetFrame( fset, i ); - if( !strcmp( astGetDomain( graphicsframe ), "GRAPHICS" ) ) { - astClearDomain( graphicsframe ); - } - graphicsframe = astAnnul( graphicsframe ); - } - - baseframe = astGetFrame( fset, astGetBase( fset ) ); - mess = "base Frame of the supplied Plot3D"; - -/* If the object is not a FrameSet, create a FrameSet holding the - supplied Frame. If the Frame is not 3D, an extra 3D Frame is - included in the FrameSet derived from axes 1, 2 and 3 of the supplied - Frame. This new Frame becomes the base Frame. */ - } else if( !astIsAFrameSet( frame ) ){ - fset0 = astFrameSet( frame, "", status ); - mess = "supplied Frame"; - fset = Fset3D( fset0, AST__BASE, status ); - fset0 = astAnnul( fset0 ); - baseframe = astGetFrame( fset, astGetBase( fset ) ); - -/* If a FrameSet was supplied, ensure it has a 3D base Frame. - If the supplied FrameSet is not 3D, then a new base Frame is - inserted into it which is derived from axes 1, 2 and 3 of the - original base Frame. */ - } else { - fset = Fset3D( (AstFrameSet *) frame, AST__BASE, status ); - baseframe = astGetFrame( fset, astGetBase( fset ) ); - mess = "base Frame of the supplied FrameSet"; - } - -/* Check that there are 3 axes in the base frame of the FrameSet. */ - naxes = astGetNaxes( baseframe ); - if ( naxes != 3 && astOK ) { - astError( AST__NAXIN, "astInitPlot3D(%s): Number of axes (%d) in the %s " - "is invalid - this number should be 3.", status, name, naxes, mess ); - } - -/* Check that no dimension of the graphbox is bad. */ - if( astISBAD(graphbox[0]) || astISBAD(graphbox[1]) || - astISBAD(graphbox[2]) || astISBAD(graphbox[3]) || - astISBAD(graphbox[4]) || astISBAD(graphbox[5]) ) { - astError( AST__BADBX, "astInitPlot3D(%s): The plotting volume has undefined limits " - "in the graphics world coordinate system.", status, name ); - } - -/* Check that no dimension of the graphbox is zero. */ - if( ( graphbox[ 3 ] == graphbox[ 0 ] || - graphbox[ 4 ] == graphbox[ 1 ] || - graphbox[ 5 ] == graphbox[ 2 ] ) && astOK ){ - astError( AST__BADBX, "astInitPlot3D(%s): The plotting volume has zero size " - "in the graphics world coordinate system.", status, name ); - } - -/* Check that no dimension of the basebox is bad. */ - if( astISBAD(basebox[0]) || astISBAD(basebox[1]) || - astISBAD(basebox[2]) || astISBAD(basebox[3]) || - astISBAD(basebox[4]) || astISBAD(basebox[5]) ) { - astError( AST__BADBX, "astInitPlot3D(%s): The limits of " - "the %s are undefined or bad.", status, name, name ); - } - -/* Create a Frame which describes the graphics world coordinate system. */ - graphicsframe = astFrame( 3, "Domain=GRAPHICS,Title=Graphical Coordinates", status ); - -/* Initialise a 2D Plot structure (the parent class) as the first component - within the Plot3D structure, allocating memory if necessary. We supply - dummy arguments since we will not be using the parent Plot class to - draw anything. We supply a NULL vtab pointer so that methods defined by - the Plot class will be used during the construction of the Plot3D. Once - the Plot3D is fully constructed, we will use astSetVtab to establish - the correct vtab. */ - new = (AstPlot3D *) astInitPlot( mem, size, 0, NULL, name, NULL, fjunkbox, - djunkbox ); - if ( astOK ) { - -/* Initialise the Plot3D data. */ -/* ----------------------------- */ - -/* Remove all Frames from the parent FrameSet except for the base (2D graphics) - Frame (we leave this last Frame since an error is reported if the last - Frame is removed from a FrameSet). We do this by repeatedly removing the - first Frame, causing all remaining Frames to have their index reduced by 1. - When the base Frame arrives at index 1, we skip it and start removing the - second frame instead. */ - nfrm = astGetNframe( new ); - i = 1; - for( ii = 0; ii < nfrm; ii++ ) { - if( i > 1 || astGetBase( new ) != 1 ) { - astRemoveFrame( new, i ); - } else { - i = 2; - } - } - -/* Add in the 3D graphics Frame, using a PermMap to connect it to the - 2D graphics Frame. */ - map = (AstMapping *) astPermMap( 2, NULL, 3, NULL, NULL, "", status ); - astAddFrame( new, 1, map, graphicsframe ); - map = astAnnul( map ); - -/* And remove the 2D GRAPHICS Frame, leaving just the 3D GRAPHICS Frame - in the FrameSet, with index 1. */ - astRemoveFrame( new, 1 ); - -/* Get the index of the current (physical) and base (pixel) Frames in - the supplied FrameSet. */ - bi = astGetBase( fset ); - ci = astGetCurrent( fset ); - -/* Temporarily set the current Frame to be the pixel frame. */ - astSetCurrent( fset, bi ); - -/* Get a double precision version of "graphbox", and store it in the - Plot3D structure. */ - new->gbox[ 0 ] = (double) graphbox[ 0 ]; - new->gbox[ 1 ] = (double) graphbox[ 1 ]; - new->gbox[ 2 ] = (double) graphbox[ 2 ]; - new->gbox[ 3 ] = (double) graphbox[ 3 ]; - new->gbox[ 4 ] = (double) graphbox[ 4 ]; - new->gbox[ 5 ] = (double) graphbox[ 5 ]; - -/* The base Frame of the supplied FrameSet is mapped linearly onto the - graphics frame. Create a WinMap that maps the base box (within the - base Frame of the supplied FrameSet) onto the graphics box. */ - map = (AstMapping *) astWinMap( 3, new->gbox, new->gbox + 3, basebox, - basebox + 3, "", status ); - -/* Add the supplied FrameSet into the Plot3D (i.e. FrameSet) created - earlier. This leaves the graphics frame with index 1 in the - returned Plot3D. */ - astAddFrame( (AstFrameSet *) new, 1, map, fset ); - map = astAnnul( map ); - -/* Set the current Frame in the Plot to be the physical coordinate Frame - (with index incremented by one because the graphics Frame has been added). */ - astSetCurrent( (AstFrameSet *) new, ci + 1 ); - -/* Note the index of the original base Frame in the Plot3D FrameSet */ - new->pix_frame = bi + 1; - -/* Re-establish the original current Frame in the supplied FrameSet. */ - astSetCurrent( fset, ci ); - -/* Initialise the Plot pointers. */ - new->plotxy = NULL; - new->plotxz = NULL; - new->plotyz = NULL; - -/* Initialise other attributes */ - new->rootcorner = -1; - -/* Initialise the normal vector to the plane used by astText and astMark. */ - new->norm[ 0 ] = AST__BAD; - new->norm[ 1 ] = AST__BAD; - new->norm[ 2 ] = AST__BAD; - -/* Create three 2D Plots to describe the three planes in the cube. */ - CreatePlots( new, fset, graphbox, basebox, status ); - -/* Ensure that attempts to use the graphics interface of the parent - Plot structure get forwarded to the relevant 3D routines defined in - this class. */ - astGrfSet( new, "Attr", (AstGrfFun) Attr3D ); - astSetGrf( new, 1 ); - -/* Change the virtual function table stored in the new Plot3D, from the Plot - vtab (established when astINitPlot was called above), to the supplied - vtab. */ - if( vtab ) astSetVtab( new, vtab ); - -/* Ensure that these Plots use the grf functions defined by this class - (Plot3D). This means that whenever a Plot draws anything, it will use - the appropriate grf function defined in this class to do the drawing. - The grf functions defined in this class, convert the grf call into a - grf3D call apprpriate the plane spanned by the Plot. */ - Set3DGrf( new, new->plotxy, XY, status ); - Set3DGrf( new, new->plotxz, XZ, status ); - Set3DGrf( new, new->plotyz, YZ, status ); - -/* Set up the Edges attributes in the encapsulated Plots so that labels - appear on the requited edges. Initially, the root corner is "LLL" - (i.e. the lower bound on every axis). */ - ChangeRootCorner( new, 0, 0, status ); - } - -/* Annul the frame. */ - graphicsframe = astAnnul( graphicsframe ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - -/* Annul the pointer to the base Frame and FrameSet. */ - baseframe = astAnnul( baseframe ); - fset = astAnnul( fset ); - -/* Return a pointer to the new object. */ - return new; -} - - -AstPlot3D *astLoadPlot3D_( void *mem, size_t size, AstPlot3DVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPlot3D - -* Purpose: -* Load a Plot3D. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot3d.h" -* AstPlot3D *astLoadPlot3D( void *mem, size_t size, -* AstPlot3DVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* Plot3D loader. - -* Description: -* This function is provided to load a new Plot3D using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Plot3D structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the Plot3D is to be -* loaded. This must be of sufficient size to accommodate the -* Plot3D data (sizeof(Plot3D)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Plot3D (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Plot3D structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPlot3D) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Plot3D. If this is NULL, a pointer -* to the (static) virtual function table for the Plot3D class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Plot3D" is used instead. - -* Returned Value: -* A pointer to the new Plot3D. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - astDECLARE_GLOBALS - AstPlot3D *new; - char key[ KEY_LEN + 1 ]; - char *text; - int axis; - int i; - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Plot3D. In this case the - Plot3D belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPlot3D ); - vtab = &class_vtab; - name = "Plot3D"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPlot3DVtab( vtab, name ); - class_init = 1; - } - } - -/* Allocate memory to hold the new Object. We allocate it now rather than - waiting for astInitObject to allocate it so that we can pass a NULL - vtab pointer to the Plot loader, thus causing the Plot loader to use the - function implementations provided by the Plot class rather than those - provided by the class being instantiated. */ - if( !mem ) mem = astMalloc( size ); - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Plot3D. Pass a NULL vtab pointer so that the "new" object - will be loaded using Plot methods rather than than Plot3D methods. - This is important because the implementations provided by the Plot3D - class for the Plot attribute accessors require the existence of the - encapsulated Plots held within the Plot3D, but these have not yet been - created. */ - new = astLoadPlot( mem, size, NULL, name, channel ); - if ( astOK ) { - -/* Now modify the new object to use the supplied vtab. */ - astSetVtab( new, vtab ); - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Plot3D" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Norm. */ -/* ----- */ - for( axis = 0; axis < 3; axis++ ) { - (void) sprintf( key, "norm%d", axis + 1 ); - new->norm[ axis ] = astReadDouble( channel, key, AST__BAD ); - if( TestNorm( new, axis, status ) ) SetNorm( new, axis, new->norm[ axis ], status ); - } - -/* RootCorner. */ -/* ----------- */ - text = astReadString( channel, "rootcn", " " ); - if( astOK && strcmp( text, " " ) ) { - new->rootcorner = RootCornerInt( text, status ); - if( new->rootcorner < 0 && astOK ) { - astError( AST__INTER, "astRead(Plot3D): Corrupt Plot3D contains " - "invalid RootCorner attribute value (%s).", status, text ); - } - } else { - new->rootcorner = -1; - } - text = astFree( text ); - -/* Labelled axes */ - new->axis_plot1[0] = astReadInt( channel, "axplx1", -1 ); - new->axis_plot1[1] = astReadInt( channel, "axply1", -1 ); - new->axis_plot1[2] = astReadInt( channel, "axplz1", -1 ); - - new->axis_index1[0] = astReadInt( channel, "axinx1", -1 ); - new->axis_index1[1] = astReadInt( channel, "axiny1", -1 ); - new->axis_index1[2] = astReadInt( channel, "axinz1", -1 ); - -/* Unlabelled axes */ - new->axis_plot2[0] = astReadInt( channel, "axplx2", -1 ); - new->axis_plot2[1] = astReadInt( channel, "axply2", -1 ); - new->axis_plot2[2] = astReadInt( channel, "axplz2", -1 ); - - new->axis_index2[0] = astReadInt( channel, "axinx2", -1 ); - new->axis_index2[1] = astReadInt( channel, "axiny2", -1 ); - new->axis_index2[2] = astReadInt( channel, "axinz2", -1 ); - -/* Plot that spans two connected 3D axes. */ - new->baseplot = astReadInt( channel, "basepl", -1 ); - -/* XY Plot */ - new->plotxy = astReadObject( channel, "plotxy", NULL ); - -/* XZ Plot */ - new->plotxz = astReadObject( channel, "plotxz", NULL ); - -/* YZ Plot */ - new->plotyz = astReadObject( channel, "plotyz", NULL ); - -/* The index within the Plot3D FrameSet, of the original base Frame in - the FrameSet supplied when the Plot3D was constructed. */ - new->pix_frame = astReadInt( channel, "pixfrm", AST__NOFRAME ); - -/* Ensure that these Plots use the grf functions defined by this class - (Plot3D). This means that whener a Plot draws anything, it will use - the appropriate grf function defined in this class to do the drawing. - The grf functions defined in this class, convert the grf call into a - grf3D call apprpriate the plane spanned by the Plot. */ - Set3DGrf( new, new->plotxy, XY, status ); - Set3DGrf( new, new->plotxz, XZ, status ); - Set3DGrf( new, new->plotyz, YZ, status ); - -/* For attributes of the parent Plot class will have been loaded - each attribute that has a set value in the parent Plot structure, - re-set the value so that it gets copied to the copy the to the - encapsulated Plots. First do axis specific attributes. */ - -#define COPY_ATTR(attr,nval) \ - for( i = 0; i < nval; i++ ) { \ - if( astTest##attr(new,i) ) astSet##attr(new,i,astGet##attr(new,i)); \ - } - - COPY_ATTR(MinTick,3) - COPY_ATTR(Abbrev,3) - COPY_ATTR(Gap,3) - COPY_ATTR(LogGap,3) - COPY_ATTR(LogPlot,3) - COPY_ATTR(LogTicks,3) - COPY_ATTR(LogLabel,3) - COPY_ATTR(LabelUp,3) - COPY_ATTR(DrawAxes,3) - COPY_ATTR(LabelUnits,3) - COPY_ATTR(MinTickLen,3) - COPY_ATTR(MajTickLen,3) - COPY_ATTR(NumLab,3) - COPY_ATTR(NumLabGap,3) - COPY_ATTR(TextLab,3) - COPY_ATTR(TextLabGap,3) - - COPY_ATTR(Style,AST__NPID) - COPY_ATTR(Font,AST__NPID) - COPY_ATTR(Colour,AST__NPID) - COPY_ATTR(Width,AST__NPID) - COPY_ATTR(Size,AST__NPID) - -#undef COPY_ATTR - -/* Now do attributes that are not axis specific. */ - -#define COPY_ATTR(attr) \ - if( astTest##attr(new) ) astSet##attr(new,astGet##attr(new)); - - COPY_ATTR(Ink) - COPY_ATTR(Tol) - COPY_ATTR(Invisible) - COPY_ATTR(TickAll) - COPY_ATTR(ForceExterior) - COPY_ATTR(Border) - COPY_ATTR(Clip) - COPY_ATTR(ClipOp) - COPY_ATTR(Escape) - COPY_ATTR(Grid) - COPY_ATTR(Labelling) - -#undef COPY_ATTR - -/* If an error occurred, clean up by deleting the new Plot3D. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Plot3D pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astClearRootCorner_( AstPlot3D *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Plot3D,ClearRootCorner))( this, status ); -} - -void astSetRootCorner_( AstPlot3D *this, int value, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Plot3D,SetRootCorner))( this, value, status ); -} - - - - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstPlot3D *astPlot3DId_( void *frame_void, const float graphbox[6], - const double basebox[6], const char *, ... ); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstPlot3D *astPlot3DId_( void *frame_void, const float graphbox[6], - const double basebox[6], const char *options, ... ) { -/* -*++ -* Name: -c astPlot3D -f AST_PLOT3D - -* Purpose: -* Create a Plot3D. - -* Type: -* Public function. - -* Synopsis: -c #include "plot3d.h" -c AstPlot3D *astPlot3D( AstFrame *frame, const float graphbox[ 6 ], -c const double basebox[ 6 ], const char *options, ... ) -f RESULT = AST_PLOT3D( FRAME, GRAPHBOX, BASEBOX, OPTIONS, STATUS ) - -* Class Membership: -* Plot3D constructor. - -* Description: -* This function creates a new Plot3D and optionally initialises -* its attributes. -* -* A Plot3D is a specialised form of Plot that provides facilities -* for producing 3D graphical output. - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* Pointer to a Frame describing the physical coordinate system -* in which to plot. A pointer to a FrameSet may also be given, -* in which case its current Frame will be used to define the -* physical coordinate system and its base Frame will be mapped -* on to graphical coordinates (see below). -* -* If a null Object pointer (AST__NULL) is given, a default -* 3-dimensional Frame will be used to describe the physical -* coordinate system. Labels, etc. may then be attached to this -* by setting the appropriate Frame attributes -* (e.g. Label(axis)) for the Plot. -c graphbox -f GRAPHBOX( 6 ) = REAL (Given) -* An array giving the position and extent of the plotting volume -* (within the plotting space of the underlying graphics system) -* in which graphical output is to appear. This must be -* specified using graphical coordinates appropriate to the -* underlying graphics system. -* -* The first triple of values should give the coordinates of the -* bottom left corner of the plotting volume and the second triple -* should give the coordinates of the top right corner. The -* coordinate on the horizontal axis should be given first in -* each pair. Note that the order in which these points are -* given is important because it defines up, down, left and -* right for subsequent graphical operations. -c basebox -f BASEBOX( 6 ) = DOUBLE PRECISION (Given) -* An array giving the coordinates of two points in the supplied -* Frame (or in the base Frame if a FrameSet was supplied) which -* correspond to the bottom left and top right corners of the -* plotting volume, as specified above. This range of coordinates -* will be mapped linearly on to the plotting area. The -* coordinates should be given in the same order as above. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Plot3D. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Plot3D. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPlot3D() -f AST_PLOT3D = INTEGER -* A pointer to the new Plot3D. - -* Notes: -* - The base Frame of the returned Plot3D will be a new Frame which -* is created by this function to represent the coordinate system -* of the underlying graphics system (graphical coordinates). It is -* given a Frame index of 1 within the Plot3D. The choice of base -* Frame (Base attribute) should not, in general, be changed once a -* Plot3D has been created (although you could use this as a way of -* moving the plotting area around on the plotting surface). -c - If a Frame is supplied (via the "frame" pointer), then it -f - If a Frame is supplied (via the FRAME pointer), then it -* becomes the current Frame of the new Plot3D and is given a Frame -* index of 2. -c - If a FrameSet is supplied (via the "frame" pointer), then -f - If a FrameSet is supplied (via the FRAME pointer), then -* all the Frames within this FrameSet become part of the new Plot3D -* (where their Frame indices are increased by 1), with the -* FrameSet's current Frame becoming the current Frame of the Plot3D. -* - At least one of the three axes of the current Frame must be -* independent of the other two current Frame axes. -* - If a null Object pointer (AST__NULL) is supplied (via the -c "frame" pointer), then the returned Plot3D will contain two -f FRAME pointer), then the returned Plot3D will contain two -* Frames, both created by this function. The base Frame will -* describe graphics coordinates (as above) and the current Frame -* will be a basic Frame with no attributes set (this will -* therefore give default values for such things as the Plot3D Title -* and the Label on each axis). Physical coordinates will be mapped -* linearly on to graphical coordinates. -* - An error will result if the Frame supplied (or the base Frame -* if a FrameSet was supplied) is not 3-dimensional. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astPlot3D constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astPlot3D_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "frame" parameter is of type -* (void *) and is converted from an ID value to a pointer and -* validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astPlot3D_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPlot3D *new; /* Pointer to new Plot3D */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - new = NULL; - -/* Obtain a Frame pointer from any ID supplied and validate the - pointer to ensure it identifies a valid Frame. */ - if( frame_void ){ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - } else { - frame = NULL; - } - -/* Check the pointer can be used. */ - if ( astOK ) { - -/* Initialise the Plot3D, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPlot3D( NULL, sizeof( AstPlot3D ), !class_init, - &class_vtab, "Plot3D", frame, graphbox, - basebox ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - Plot3D's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new Plot3D. */ - return astMakeId( new ); - -} - - - -/* Macros that define method to override the methods of the Plot class - that are not currently implemented by this class. They just report an - error if called. */ - -#define METHOD1(name) \ -static void name(ARGLIST,int *status){ \ - if( !astOK ) return; \ - astError( AST__INTER, "ast##name(%s): The ast##name " \ - "method cannot be used with a %s (programming error).", status, \ - astGetClass( this ), astGetClass( this ) ); \ -} - -#define METHOD2(name,rettype,retval) \ -static rettype name(ARGLIST,int *status){ \ - if( !astOK ) return retval; \ - astError( AST__INTER, "ast##name(%s): The ast##name " \ - "method cannot be used with a %s (programming error).", status, \ - astGetClass( this ), astGetClass( this ) ); \ - return retval; \ -} - - -#define ARGLIST AstPlot *this -METHOD2(GetGrfContext,AstKeyMap *,NULL) -#undef ARGLIST - -#define ARGLIST AstPlot *this -METHOD1(GrfPop) -#undef ARGLIST - -#define ARGLIST AstPlot *this -METHOD1(GrfPush) -#undef ARGLIST - -#define ARGLIST AstPlot *this, const char *name, AstGrfFun fun -METHOD1(GrfSet) -#undef ARGLIST - -#define ARGLIST AstPlot *this, int axis, const double start[], double length -METHOD1(GridLine) -#undef ARGLIST - -#define ARGLIST AstPlot *this, float lbnd[2], float ubnd[2] -METHOD1(BoundingBox) -#undef ARGLIST - -#define ARGLIST AstPlot *this, int iframe, const double lbnd[], const double ubnd[] -METHOD1(Clip) -#undef ARGLIST - -#define ARGLIST AstPlot *this, const double start[], const double finish[] -METHOD1(Curve) -#undef ARGLIST - -#define ARGLIST AstPlot *this, AstMapping *map -METHOD1(GenCurve) -#undef ARGLIST - - - - - - - - diff --git a/ast/plot3d.h b/ast/plot3d.h deleted file mode 100644 index 4826b44..0000000 --- a/ast/plot3d.h +++ /dev/null @@ -1,258 +0,0 @@ -#if !defined( PLOT3D_INCLUDED ) /* Include this file only once */ -#define PLOT3D_INCLUDED -/* -*+ -* Name: -* plot3d.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Plot3D class. - -* Invocation: -* #include "plot3d.h" - -* Description: -* This include file defines the interface to the Plot3D class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 6-JUN-2007 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "plot.h" /* Parent Plot class */ - -/* Macros. */ -/* ======= */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - - -#if defined(astCLASS) /* Protected */ - -#endif - -/* Type Definitions. */ -/* ================= */ - -/* Plot3D structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstPlot3D { - -/* Attributes inherited from the parent class. */ - AstPlot plot; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstPlot *plotxy; /* Plot describing the XY plane */ - AstPlot *plotxz; /* Plot describing the XZ plane */ - AstPlot *plotyz; /* Plot describing the YZ plane */ - double gbox[6]; /* Graphics box */ - int pix_frame; /* Index of original base Frame */ - int rootcorner; /* Corner at junction of the annotated axes */ - int baseplot; /* The Plot that is used to label 2 3D axes */ - int axis_plot1[3]; /* The Plot used to label each 3D axis */ - int axis_index1[3]; /* The axis index within the axis_plot1 Plot */ - int axis_plot2[3]; /* The other Plot touching each 3D axis */ - int axis_index2[3]; /* The axis index within the axis_plot2 Plot */ - double norm[3]; /* Normal vector for text plane */ -} AstPlot3D; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all objects in the - class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstPlot3DVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstPlotVtab plot_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - - int (* GetRootCorner)( AstPlot3D *, int * ); - int (* TestRootCorner)( AstPlot3D *, int * ); - void (* SetRootCorner)( AstPlot3D *, int, int * ); - void (* ClearRootCorner)( AstPlot3D *, int * ); - - double (* GetNorm)( AstPlot3D *, int, int * ); - int (* TestNorm)( AstPlot3D *, int, int * ); - void (* SetNorm)( AstPlot3D *, int, double, int * ); - void (* ClearNorm)( AstPlot3D *, int, int * ); - -} AstPlot3DVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstPlot3DGlobals { - AstPlot3DVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 101 ]; -} AstPlot3DGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Plot3D) /* Check class membership */ -astPROTO_ISA(Plot3D) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -AstPlot3D *astPlot3D_( void *, const float *, const double *, const char *, int *, ...); -#else -AstPlot3D *astPlot3DId_( void *, const float [], const double [], const char *, ... ); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstPlot3D *astInitPlot3D_( void *, size_t, int, AstPlot3DVtab *, - const char *, AstFrame *, const float *, - const double *, int * ); - -/* Vtab initialiser. */ -void astInitPlot3DVtab_( AstPlot3DVtab *, const char *, int * ); - -/* Loader. */ -AstPlot3D *astLoadPlot3D_( void *, size_t, - AstPlot3DVtab *, - const char *, AstChannel *channel, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitPlot3DGlobals_( AstPlot3DGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -#if defined(astCLASS) /* Protected */ - - int astGetRootCorner_( AstPlot3D *, int * ); - int astTestRootCorner_( AstPlot3D *, int * ); - void astSetRootCorner_( AstPlot3D *, int, int * ); - void astClearRootCorner_( AstPlot3D *, int * ); - - double astGetNorm_( AstPlot3D *, int, int * ); - int astTestNorm_( AstPlot3D *, int, int * ); - void astSetNorm_( AstPlot3D *, int, double, int * ); - void astClearNorm_( AstPlot3D *, int, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckPlot3D(this) astINVOKE_CHECK(Plot3D,this,0) -#define astVerifyPlot3D(this) astINVOKE_CHECK(Plot3D,this,1) - -/* Test class membership. */ -#define astIsAPlot3D(this) astINVOKE_ISA(Plot3D,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -#define astPlot3D astINVOKE(F,astPlot3D_) -#else -#define astPlot3D astINVOKE(F,astPlot3DId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitPlot3D(mem,size,init,vtab,name,frame,graph,base) \ -astINVOKE(O,astInitPlot3D_(mem,size,init,vtab,name,frame,graph,base,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitPlot3DVtab(vtab,name) astINVOKE(V,astInitPlot3DVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadPlot3D(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadPlot3D_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) - -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ - -/* Interfaces to protected member functions. */ -/* ----------------------------------------- */ -/* Here we make use of astCheckPlot3D to validate Plot3D pointers - before use. This provides a contextual error report if a pointer to - the wrong sort of object is supplied. */ - -#if defined(astCLASS) /* Protected */ - -#define astGetRootCorner(this) astINVOKE(V,astGetRootCorner_(astCheckPlot3D(this),STATUS_PTR)) -#define astTestRootCorner(this) astINVOKE(V,astTestRootCorner_(astCheckPlot3D(this),STATUS_PTR)) -#define astClearRootCorner(this) astINVOKE(V,astClearRootCorner_(astCheckPlot3D(this),STATUS_PTR)) -#define astSetRootCorner(this,value) astINVOKE(V,astSetRootCorner_(astCheckPlot3D(this),value,STATUS_PTR)) - -#define astGetNorm(this,axis) astINVOKE(V,astGetNorm_(astCheckPlot3D(this),axis,STATUS_PTR)) -#define astTestNorm(this,axis) astINVOKE(V,astTestNorm_(astCheckPlot3D(this),axis,STATUS_PTR)) -#define astClearNorm(this,axis) astINVOKE(V,astClearNorm_(astCheckPlot3D(this),axis,STATUS_PTR)) -#define astSetNorm(this,axis,value) astINVOKE(V,astSetNorm_(astCheckPlot3D(this),axis,value,STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/pointlist.c b/ast/pointlist.c deleted file mode 100644 index 61117c2..0000000 --- a/ast/pointlist.c +++ /dev/null @@ -1,3407 +0,0 @@ -/* -*class++ -* Name: -* PointList - -* Purpose: -* A collection of points in a Frame. - -* Constructor Function: -c astPointList -f AST_POINTLIST - -* Description: -* The PointList class implements a Region which represents a collection -* of points in a Frame. - -* Inheritance: -* The PointList class inherits from the Region class. - -* Attributes: -* In addition to those attributes common to all Regions, every -* PointList also has the following attributes: -* -* - ListSize: The number of positions stored in the PointList - - -* Functions: -c The PointList class does not define any new functions beyond those -f The PointList class does not define any new routines beyond those -* which are applicable to all Regions. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-MAR-2004 (DSB): -* Original version. -* 20-JAN-2009 (DSB): -* Over-ride astRegBasePick. -* 21-JAN-2009 (DSB): -* - Add methods astGetEnclosure, astSetEnclosure and astPoints, and -* attribute ListSize. -* - Override astGetObjSize and astEqual. -* 26-JAN-2009 (DSB): -* Change protected constructor to accept a PointSet rather than an -* array of doubles. -* 6-FEB-2009 (DSB): -* Over-ride astMapMerge. -* 9-FEB-2009 (DSB): -* Move methods astGetEnclosure and astSetEnclosure to Region class. -* 8-JUL-2009 (DSB): -* In Transform, use "ptr2", not "ptr", if we are creating a mask. -*class-- - -* Implementation Deficiencies: -* - Use of simple arrays to hold lists of points is probably not -* efficient for large numbers of points. For instance, use of k-tree -* structures instead of arrays could result in a much more efficient -* implementation of the Transform function. Maybe the PointSet class -* should be extended to provide a k-tree representation as well as a -* simple array. - -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS PointList - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "region.h" /* Coordinate regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "pointlist.h" /* Interface definition for this class */ -#include "mapping.h" /* Position mappings */ -#include "unitmap.h" /* Unit Mapping */ -#include "frame.h" /* Coordinate systems */ -#include "cmpframe.h" /* Compound Frames */ -#include "cmpmap.h" /* Compound Mappings */ -#include "prism.h" /* Extruded Regions */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstMapping *(* parent_simplify)( AstMapping *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(PointList) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(PointList,Class_Init) -#define class_vtab astGLOBAL(PointList,Class_Vtab) -#define getattrib_buff astGLOBAL(PointList,GetAttrib_Buff) - - -#include - - -#else - -static char getattrib_buff[ 101 ]; - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPointListVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstPointList *astPointListId_( void *, int, int, int, const double *, void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -static int MaskLD( AstRegion *, AstMapping *, int, int, const int[], const int ubnd[], long double [], long double, int * ); -#endif -static int MaskB( AstRegion *, AstMapping *, int, int, const int[], const int[], signed char[], signed char, int * ); -static int MaskD( AstRegion *, AstMapping *, int, int, const int[], const int[], double[], double, int * ); -static int MaskF( AstRegion *, AstMapping *, int, int, const int[], const int[], float[], float, int * ); -static int MaskI( AstRegion *, AstMapping *, int, int, const int[], const int[], int[], int, int * ); -static int MaskL( AstRegion *, AstMapping *, int, int, const int[], const int[], long int[], long int, int * ); -static int MaskS( AstRegion *, AstMapping *, int, int, const int[], const int[], short int[], short int, int * ); -static int MaskUB( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned char[], unsigned char, int * ); -static int MaskUI( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned int[], unsigned int, int * ); -static int MaskUL( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned long int[], unsigned long int, int * ); -static int MaskUS( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned short int[], unsigned short int, int * ); - -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *RegBasePick( AstRegion *, int, const int *, int * ); -static int GetClosed( AstRegion *, int * ); -static int GetListSize( AstPointList *, int * ); -static int GetObjSize( AstObject *, int * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void PointListPoints( AstPointList *, AstPointSet **, int *); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void RegBaseBox( AstRegion *, double *, double *, int * ); -static AstRegion *MergePointList( AstPointList *, AstRegion *, int, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - - -/* Member functions. */ -/* ================= */ - -static void ClearAttrib( AstObject *this_object, const char *attrib, - int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a PointList. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PointList member function (over-rides the astClearAttrib -* protected method inherited from the Object class). - -* Description: -* This function clears the value of a specified attribute for a -* PointList, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the PointList. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPointList *this; /* Pointer to the PointList structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PointList structure. */ - this = (AstPointList *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Test if the name matches any of the read-only attributes of this - class. If it does, then report an error. */ - if ( !strcmp( attrib, "listsize" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, - int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a PointList. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PointList member function (over-rides the protected astGetAttrib -* method inherited from the Region class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a PointList, formatted as a character string. - -* Parameters: -* this -* Pointer to the PointList. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the PointList, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the PointList. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPointList *this; /* Pointer to the PointList structure */ - const char *result; /* Pointer value to return */ - int ival; /* Integer attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the PointList structure. */ - this = (AstPointList *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an - appropriate format. Set "result" to point at the result string. */ - -/* ListSize. */ -/* -------- */ - if ( !strcmp( attrib, "listsize" ) ) { - ival = astGetListSize( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static int GetClosed( AstRegion *this, int *status ) { -/* -* Name: -* GetClosed - -* Purpose: -* Get the value of the CLosed attribute for a PointList. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* int GetClosed( AstRegion *this, int *status ) - -* Class Membership: -* PointList member function (over-rides the astGetClosed method -* inherited from the Region class). - -* Description: -* This function returns the value of the Closed attribute for a -* PointList. Since points have zero volume they consist entirely of -* boundary. Therefore the Region is always considered to be closed -* unless it has been negated, in which case it is always assumed to -* be open. - -* Parameters: -* this -* Pointer to the PointList. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to use for the Closed attribute. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* The value to be used for the Closed attribute is always the opposite - of the Negated attribute. */ - return ( astGetNegated( this ) == 0 ); -} - -static int GetListSize( AstPointList *this, int *status ) { -/* -*+ -* Name: -* astGetListSize - -* Purpose: -* Determine how many points there are in a PointList. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointlist.h" -* int astGetListSize( AstPointList *this ) - -* Class Membership: -* PointList method. - -* Description: -* This function returns the number of points stored in a Point|List. - -* Parameters: -* this -* Pointer to the PointList. - -* Returned Value: -* The number of points in the PointList. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the number of points by querying the PointSet that holds the - points. */ - return astGetNpoint( ((AstRegion *) this)->points ); -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* PointList member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied PointList, -* in bytes. - -* Parameters: -* this -* Pointer to the PointList. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPointList *this; /* Pointer to PointList structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the PointList structure. */ - this = (AstPointList *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astGetObjSize( this->lbnd ); - result += astGetObjSize( this->ubnd ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -void astInitPointListVtab_( AstPointListVtab *vtab, const char *name, - int *status ) { -/* -*+ -* Name: -* astInitPointListVtab - -* Purpose: -* Initialise a virtual function table for a PointList. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointlist.h" -* void astInitPointListVtab( AstPointListVtab *vtab, const char *name ) - -* Class Membership: -* PointList vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the PointList class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAPointList) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->GetListSize = GetListSize; - vtab->PointListPoints = PointListPoints; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - mapping->MapMerge = MapMerge; - - region->RegBaseMesh = RegBaseMesh; - region->RegBaseBox = RegBaseBox; - region->RegBasePick = RegBasePick; - region->RegPins = RegPins; - region->GetClosed = GetClosed; - region->MaskB = MaskB; - region->MaskD = MaskD; - region->MaskF = MaskF; - region->MaskI = MaskI; - region->MaskL = MaskL; - region->MaskS = MaskS; - region->MaskUB = MaskUB; - region->MaskUI = MaskUI; - region->MaskUL = MaskUL; - region->MaskUS = MaskUS; -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - region->MaskLD = MaskLD; -#endif - -/* Declare the class dump function. There is no copy constructor or - destructor. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "PointList", "Collection of points" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -/* -* Name: -* Mask - -* Purpose: -* Mask a region of a data grid. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* int Mask( AstRegion *this, AstMapping *map, int inside, int ndim, -* const int lbnd[], const int ubnd[], in[], -* val ) - -* Class Membership: -* PointList function method (replaces the astMask methods -* inherited from the parent Region class). - -* Description: -* This is a set of functions for masking out regions within gridded data -* (e.g. an image). The functions modifies a given data grid by -* assigning a specified value to all samples which are inside (or outside -* if "inside" is zero) the specified Region. -* -* You should use a masking function which matches the numerical -* type of the data you are processing by replacing in -* the generic function name astMask by an appropriate 1- or -* 2-character type code. For example, if you are masking data -* with type "float", you should use the function astMaskF (see -* the "Data Type Codes" section below for the codes appropriate to -* other numerical types). - -* Parameters: -* this -* Pointer to a Region. -* map -* Pointer to a Mapping. The forward transformation should map -* positions in the coordinate system of the supplied Region -* into pixel coordinates as defined by the "lbnd" and "ubnd" -* parameters. A NULL pointer can be supplied if the coordinate -* system of the supplied Region corresponds to pixel coordinates. -* This is equivalent to supplying a UnitMap. -* -* The number of inputs for this Mapping (as given by its Nin attribute) -* should match the number of axes in the supplied Region (as given -* by the Naxes attribute of the Region). The number of outputs for the -* Mapping (as given by its Nout attribute) should match the number of -* grid dimensions given by the value of "ndim" below. -* inside -* A boolean value which indicates which pixel are to be masked. If -* a non-zero value is supplied, then all grid pixels which are inside -* the supplied Region are assigned the value given by "val", -* and all other pixels are left unchanged. If zero is supplied, then -* all grid pixels which are not inside the supplied Region are -* assigned the value given by "val", and all other pixels are left -* unchanged. Note, the Negated attribute of the Region is used to -* determine which pixel are inside the Region and which are outside. -* So the inside of a Region which has not been negated is the same as -* the outside of the corresponding negated Region. -* ndim -* The number of dimensions in the input grid. This should be at -* least one. -* lbnd -* Pointer to an array of integers, with "ndim" elements, -* containing the coordinates of the centre of the first pixel -* in the input grid along each dimension. -* ubnd -* Pointer to an array of integers, with "ndim" elements, -* containing the coordinates of the centre of the last pixel in -* the input grid along each dimension. -* -* Note that "lbnd" and "ubnd" together define the shape -* and size of the input grid, its extent along a particular -* (j'th) dimension being ubnd[j]-lbnd[j]+1 (assuming the -* index "j" to be zero-based). They also define -* the input grid's coordinate system, each pixel having unit -* extent along each dimension with integral coordinate values -* at its centre. -* in -* Pointer to an array, with one element for each pixel in the -* input grid, containing the data to be masked. The -* numerical type of this array should match the 1- or -* 2-character type code appended to the function name (e.g. if -* you are using astMaskF, the type of each array element -* should be "float"). -* -* The storage order of data within this array should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -* (i.e. Fortran array indexing is used). -* -* On exit, the samples specified by "inside" are set to the value -* of "val". All other samples are left unchanged. -* val -* This argument should have the same type as the elements of -* the "in" array. It specifies the value used to flag the -* masked data (see "inside"). - -* Returned Value: -* The number of pixels to which a value of "badval" has been assigned. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. - -* Data Type Codes: -* To select the appropriate masking function, you should -* replace in the generic function name astMask with a -* 1- or 2-character data type code, so as to match the numerical -* type of the data you are processing, as follows: -* - D: double -* - F: float -* - L: long int -* - UL: unsigned long int -* - I: int -* - UI: unsigned int -* - S: short int -* - US: unsigned short int -* - B: byte (signed char) -* - UB: unsigned byte (unsigned char) -* -* For example, astMaskD would be used to process "double" -* data, while astMaskS would be used to process "short int" -* data, etc. -*/ -/* Define a macro to implement the function for a specific data - type. */ -#define MAKE_MASK(X,Xtype) \ -static int Mask##X( AstRegion *this, AstMapping *map, int inside, int ndim, \ - const int lbnd[], const int ubnd[], \ - Xtype in[], Xtype val, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *grid_frame; /* Pointer to Frame describing grid coords */ \ - AstPointSet *pset1; /* Pointer to base Frame positions */ \ - AstPointSet *pset2; /* Pointer to current Frame positions */ \ - AstRegion *used_region; /* Pointer to Region to be used by astResample */ \ - Xtype *temp; /* Pointer to temp storage for retained points */ \ - double **ptr2; /* Pointer to pset2 data values */ \ - int *iv; /* Pointer to index array */ \ - int i; /* Point index */ \ - int idim; /* Loop counter for coordinate dimensions */ \ - int ii; /* Vectorised point index */ \ - int j; /* Axis index */ \ - int nax; /* Number of Region axes */ \ - int negated; /* Has Region been negated? */ \ - int nin; /* Number of Mapping input coordinates */ \ - int nout; /* Number of Mapping output coordinates */ \ - int npnt; /* Number of points in PointList */ \ - int result; /* Result value to return */ \ - int vlen; /* Length of vectorised array */ \ -\ -/* Initialise. */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Obtain value for the Naxes attribute of the Region. */ \ - nax = astGetNaxes( this ); \ -\ -/* If supplied, obtain values for the Nin and Nout attributes of the Mapping. */ \ - if( map ) { \ - nin = astGetNin( map ); \ - nout = astGetNout( map ); \ -\ -/* If OK, check that the number of mapping inputs matches the \ - number of axes in the Region. Report an error if necessary. */ \ - if ( astOK && ( nax != nin ) ) { \ - astError( AST__NGDIN, "astMask"#X"(%s): Bad number of mapping " \ - "inputs (%d).", status, astGetClass( this ), nin ); \ - astError( AST__NGDIN, "The %s given requires %d coordinate value%s " \ - "to specify a position.", status, \ - astGetClass( this ), nax, ( nax == 1 ) ? "" : "s" ); \ - } \ -\ -/* If OK, check that the number of mapping outputs matches the \ - number of grid dimensions. Report an error if necessary. */ \ - if ( astOK && ( ndim != nout ) ) { \ - astError( AST__NGDIN, "astMask"#X"(%s): Bad number of mapping " \ - "outputs (%d).", status, astGetClass( this ), nout ); \ - astError( AST__NGDIN, "The pixel grid requires %d coordinate value%s " \ - "to specify a position.", status, \ - ndim, ( ndim == 1 ) ? "" : "s" ); \ - } \ -\ -/* Create a new Region by mapping the supplied Region with the supplied \ - Mapping.*/ \ - grid_frame = astFrame( ndim, "Domain=grid", status ); \ - used_region = astMapRegion( this, map, grid_frame ); \ - grid_frame = astAnnul( grid_frame ); \ -\ -/* If no Mapping was supplied check that the number of grid dimensions \ - matches the number of axes in the Region.*/ \ - } else if ( astOK && ( ( ndim != nax ) || ( ndim < 1 ) ) ) { \ - used_region = NULL; \ - astError( AST__NGDIN, "astMask"#X"(%s): Bad number of input grid " \ - "dimensions (%d).", status, astGetClass( this ), ndim ); \ - if ( ndim != nax ) { \ - astError( AST__NGDIN, "The %s given requires %d coordinate value%s " \ - "to specify an input position.", status, \ - astGetClass( this ), nax, ( nax == 1 ) ? "" : "s" ); \ - } \ -\ -/* If no Mapping was supplied and the parameters look OK, clone the \ - supplied Region pointer for use later on. */ \ - } else { \ - used_region = astClone( this ); \ - } \ -\ -/* Check that the lower and upper bounds of the input grid are \ - consistent. Report an error if any pair is not. */ \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim; idim++ ) { \ - if ( lbnd[ idim ] > ubnd[ idim ] ) { \ - astError( AST__GBDIN, "astMask"#X"(%s): Lower bound of " \ - "input grid (%d) exceeds corresponding upper bound " \ - "(%d).", status, astGetClass( this ), \ - lbnd[ idim ], ubnd[ idim ] ); \ - astError( AST__GBDIN, "Error in input dimension %d.", status, \ - idim + 1 ); \ - break; \ - } \ - } \ - } \ -\ -/* Get the PointSet in the base Frame of the Region's FrameSet, and \ - transform to the current (GRID) Frame. */ \ - pset1 = used_region->points; \ - pset2 = astRegTransform( used_region, pset1, 1, NULL, NULL ); \ - ptr2 =astGetPoints( pset2 ); \ -\ -/* Allocate memory to hold the corresponding vector indices. */ \ - npnt = astGetNpoint( pset2 ); \ - iv = astMalloc( sizeof(int)*(size_t) npnt ); \ - if( astOK ) { \ -\ -/* Convert the transformed GRID positions into integer indices into the \ - vectorised data array. Also form the total size of the data array. */ \ - vlen = 0; \ - for( i = 0; i < npnt; i++ ) { \ - vlen = 1; \ - ii = 0; \ - for( j = 0; j < ndim; j++ ) { \ - ii += vlen*( (int)( ptr2[ j ][ i ] + 0.5 ) - lbnd[ j ] ); \ - vlen *= ubnd[ i ] - lbnd[ i ] + 1; \ - } \ - iv[ i ] = ii; \ - } \ -\ -/* See if the Region is negated. */ \ - negated = astGetNegated( used_region ); \ -\ -/* If necessary, set the transformed pixel coords to the supplied value. */ \ - if( ( inside && !negated ) || ( !inside && negated ) ) { \ - for( i = 0; i < npnt; i++ ) in[ iv[ i ] ] = val; \ - result = npnt; \ -\ -/* If necessary, set all except the transformed pixel coords to the supplied \ - value. */ \ - } else { \ - temp = astMalloc( sizeof( Xtype )*(size_t)npnt ); \ - if( astOK ) { \ - for( i = 0; i < npnt; i++ ) temp[ i ] = in[ iv[ i ] ]; \ - for( i = 0; i < vlen; i++ ) in[ i ] = val; \ - for( i = 0; i < npnt; i++ ) in[ iv[ i ] ] = temp[ i ]; \ - result = vlen - npnt; \ - } \ - temp = astFree( temp ); \ - } \ - } \ -\ -/* Free resources */ \ - iv = astFree( iv ); \ - pset2 = astAnnul( pset2 ); \ - used_region = astAnnul( used_region ); \ -\ -/* If an error occurred, clear the returned result. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_MASK(LD,long double) -#endif -MAKE_MASK(D,double) -MAKE_MASK(F,float) -MAKE_MASK(L,long int) -MAKE_MASK(UL,unsigned long int) -MAKE_MASK(I,int) -MAKE_MASK(UI,unsigned int) -MAKE_MASK(S,short int) -MAKE_MASK(US,unsigned short int) -MAKE_MASK(B,signed char) -MAKE_MASK(UB,unsigned char) - -/* Undefine the macro. */ -#undef MAKE_MASK - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a PointList. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* PointList method (over-rides the protected astMapMerge method -* inherited from the Region class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated PointList in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated PointList with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated PointList which is to be merged with -* its neighbours. This should be a cloned copy of the PointList -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* PointList it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated PointList resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstPointList *oldint; /* Pointer to supplied PointList */ - AstMapping *map; /* Pointer to adjacent Mapping */ - AstMapping *new; /* Simplified or merged Region */ - int i1; /* Index of first Mapping merged */ - int i; /* Loop counter */ - int result; /* Result value to return */ - -/* Initialise. */ - result = -1; - i1 = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the PointList. */ - oldint = (AstPointList *) this; - -/* First of all, see if the PointList can be replaced by a simpler Region, - without reference to the neighbouring Regions in the list. */ -/* =====================================================================*/ - -/* Try to simplify the PointList. If the pointer value has changed, we assume - some simplification took place. */ - new = astSimplify( oldint ); - if( new != (AstMapping *) oldint ) { - -/* Annul the PointList pointer in the list and replace it with the new Region - pointer, and indicate that the forward transformation of the returned - Region should be used (not really needed but keeps things clean). */ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = new; - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - -/* If the PointList itself could not be simplified, see if it can be merged - with the Regions on either side of it in the list. We can only merge - in parallel. */ -/* =====================================================================*/ - } else if( ! series ){ - new = astAnnul( new ); - -/* Attempt to merge the PointList with its lower neighbour (if any). */ - if( where > 0 ) { - i1 = where - 1; - map = ( *map_list )[ where - 1 ]; - if( astIsARegion( map ) ) { - new = (AstMapping *) MergePointList( oldint, (AstRegion *) map, - 0, status ); - } - } - -/* If this did not produced a merged Region, attempt to merge the PointList - with its upper neighbour (if any). */ - if( !new && where < *nmap - 1 ) { - i1 = where; - map = ( *map_list )[ where + 1 ]; - if( astIsARegion( map ) ) { - new = (AstMapping *) MergePointList( oldint, (AstRegion *) map, - 1, status ); - } - } - -/* If succesfull... */ - if( new ){ - -/* Annul the first of the two Mappings, and replace it with the merged - Region. Also clear the invert flag. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - ( *map_list )[ i1 ] = new; - ( *invert_list )[ i1 ] = 0; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ i1 + 1 ] ); - for ( i = i1 + 2; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = i1; - } - - } else { - new = astAnnul( new ); - } - -/* Return the result. */ - return result; -} - -static AstRegion *MergePointList( AstPointList *this, AstRegion *reg, - int plsfirst, int *status ) { -/* -* Name: -* MergePointList - -* Purpose: -* Attempt to merge a PointList with another Region to form a Region of -* higher dimensionality. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* AstRegion *MergePointList( AstPointList *this, AstRegion *reg, -* int plsfirst, int *status ) - -* Class Membership: -* PointList member function. - -* Description: -* This function attempts to combine the supplied Regions together -* into a Region of higher dimensionality. - -* Parameters: -* this -* Pointer to a PointList. -* reg -* Pointer to another Region. -* plsfirst -* If non-zero, then the PointList axes are put first in the new Region. -* Otherwise, the other Region's axes are put first. -* status -* Pointer to the inherited status value. - -* Returned Value: -* A pointer to a new region, or NULL if the supplied Regions could -* not be merged. -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* Pointer to base Frame for "result" */ - AstFrame *cfrm; /* Pointer to current Frame for "result" */ - AstFrame *frm_reg; /* Pointer to Frame from "reg" */ - AstFrame *frm_this; /* Pointer to Frame from "this" */ - AstMapping *bcmap; /* Base->current Mapping for "result" */ - AstMapping *map_reg; /* Base->current Mapping from "reg" */ - AstMapping *map_this; /* Base->current Mapping from "this" */ - AstMapping *sbunc; /* Simplified uncertainty */ - AstPointSet *pset_new; /* PointSet for new PointList */ - AstPointSet *pset_reg; /* PointSet from reg */ - AstPointSet *pset_this; /* PointSet from this */ - AstRegion *bunc; /* Base Frame uncertainty Region */ - AstRegion *new; /* Pointer to new PointList in base Frame */ - AstRegion *result; /* Pointer to returned PointList in current Frame */ - AstRegion *unc_reg; /* Current Frame uncertainty Region from "reg" */ - AstRegion *unc_this; /* Current Frame uncertainty Region from "this" */ - double **ptr_new; /* PointSet data pointers for new PointList */ - double **ptr_reg; /* PointSet data pointers for reg */ - double **ptr_this; /* PointSet data pointers for this */ - double fac_reg; /* Ratio of used to default MeshSize for "reg" */ - double fac_this; /* Ratio of used to default MeshSize for "this" */ - int i; /* Axis index */ - int msz_reg; /* Original MeshSize for "reg" */ - int msz_reg_set; /* Was MeshSize originally set for "reg"? */ - int msz_this; /* Original MeshSize for "this" */ - int msz_this_set; /* Was MeshSize originally set for "this"? */ - int nax; /* Number of axes in "result" */ - int nax_reg; /* Number of axes in "reg" */ - int nax_this; /* Number of axes in "this" */ - int neg_reg; /* Negated attribute value for other supplied Region */ - int neg_this; /* Negated attribute value for supplied PointList */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get the Closed attributes of the two Regions. They must be the same in - each Region if we are to merge the Regions. In addition, in order to - merge, either both Regions must have a defined uncertainty, or neither - Region must have a defined Uncertainty. */ - if( astGetClosed( this ) == astGetClosed( reg ) && - astTestUnc( this ) == astTestUnc( reg ) ) { - -/* Get the Nagated attributes of the two Regions. */ - neg_this = astGetNegated( this ); - neg_reg = astGetNegated( reg ); - -/* We only check for merging with another PointList (other classes such - as Box and Interval check for merging of PointLists with other classes). - The result will be an PointList. Both Regions must have the same value - for the Negated flag, and can contain only a single point. */ - if( astIsAPointList( reg ) && neg_this == neg_reg && - astGetListSize( this ) == 1 && - astGetListSize( (AstPointList *) reg ) == 1 ) { - -/* Get the number of axes in the two supplied Regions. */ - nax_reg = astGetNaxes( reg ); - nax_this = astGetNaxes( this ); - -/* Get the number of axes the combination will have. */ - nax = nax_reg + nax_this; - -/* Get the base Frames from the two Region FrameSets, and combine them - into a single CmpFrame that will be used to create the new Region. */ - frm_this = astGetFrame( ((AstRegion *) this)->frameset, AST__BASE ); - frm_reg = astGetFrame( reg->frameset, AST__BASE ); - - if( plsfirst ) { - bfrm = (AstFrame *) astCmpFrame( frm_this, frm_reg, "", status ); - } else { - bfrm = (AstFrame *) astCmpFrame( frm_reg, frm_this, "", status ); - } - - frm_this = astAnnul( frm_this ); - frm_reg = astAnnul( frm_reg ); - -/* Get pointers to the coordinate data in the two PointLists */ - pset_this = ((AstRegion *) this)->points; - ptr_this = astGetPoints( pset_this ); - pset_reg = reg->points; - ptr_reg = astGetPoints( pset_reg ); - -/* Create a PointSet to hold the points for the returned PointList. */ - pset_new = astPointSet( 1, nax, "", status ); - -/* Get pointers to its data. */ - ptr_new = astGetPoints( pset_new ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Copy the point positions fon the selected axes into the arrays allocated - above, in the requested order. */ - if( plsfirst ) { - for( i = 0; i < nax_this; i++ ) { - ptr_new[ i ][ 0 ] = ptr_this[ i ][ 0 ]; - } - for( ; i < nax; i++ ) { - ptr_new[ i ][ 0 ] = ptr_reg[ i - nax_this ][ 0 ]; - } - - } else { - for( i = 0; i < nax_reg; i++ ) { - ptr_new[ i ][ 0 ] = ptr_reg[ i ][ 0 ]; - } - for( ; i < nax; i++ ) { - ptr_new[ i ][ 0 ] = ptr_this[ i - nax_reg ][ 0 ]; - } - } - -/* Create the new PointList. */ - new = (AstRegion *) astPointList( bfrm, pset_new, NULL, "", - status ); - -/* Propagate remaining attributes of the supplied Region to it. */ - astRegOverlay( new, this, 1 ); - -/* Ensure the Negated flag is set correctly in the returned PointList. */ - if( neg_this ) { - astSetNegated( new, neg_this ); - } else { - astClearNegated( new ); - } - -/* If both the supplied Regions have uncertainty, assign the new Region an - uncertainty. */ - if( astTestUnc( this ) && astTestUnc( reg ) ) { - -/* Get the uncertainties from the two supplied Regions. */ - unc_this = astGetUncFrm( this, AST__BASE ); - unc_reg = astGetUncFrm( reg, AST__BASE ); - -/* Combine them into a single Region (a Prism), in the correct order. */ - if( plsfirst ) { - bunc = (AstRegion *) astPrism( unc_this, unc_reg, "", status ); - } else { - bunc = (AstRegion *) astPrism( unc_reg, unc_this, "", status ); - } - -/* Attempt to simplify the Prism. */ - sbunc = astSimplify( bunc ); - -/* Use the simplified Prism as the uncertainty for the returned Region. */ - astSetUnc( new, sbunc ); - -/* Free resources. */ - sbunc = astAnnul( sbunc ); - bunc = astAnnul( bunc ); - unc_reg = astAnnul( unc_reg ); - unc_this = astAnnul( unc_this ); - } - -/* Get the current Frames from the two Region FrameSets, and combine them - into a single CmpFrame. */ - frm_this = astGetFrame( ((AstRegion *) this)->frameset, AST__CURRENT ); - frm_reg = astGetFrame( reg->frameset, AST__CURRENT ); - - if( plsfirst ) { - cfrm = (AstFrame *) astCmpFrame( frm_this, frm_reg, "", status ); - } else { - cfrm = (AstFrame *) astCmpFrame( frm_reg, frm_this, "", status ); - } - -/* Get the base -> current Mappings from the two Region FrameSets, and - combine them into a single parallel CmpMap that connects bfrm and cfrm. */ - map_this = astGetMapping( ((AstRegion *) this)->frameset, AST__BASE, - AST__CURRENT ); - map_reg = astGetMapping( reg->frameset, AST__BASE, AST__CURRENT ); - - if( plsfirst ) { - bcmap = (AstMapping *) astCmpMap( map_this, map_reg, 0, "", - status ); - } else { - bcmap = (AstMapping *) astCmpMap( map_reg, map_this, 0, "", - status ); - } - -/* Map the new Region into the new current Frame. */ - result = astMapRegion( new, bcmap, cfrm ); - -/* The filling factor in the returned is the product of the filling - factors for the two supplied Regions. */ - if( astTestFillFactor( reg ) || astTestFillFactor( this ) ) { - astSetFillFactor( result, astGetFillFactor( reg )* - astGetFillFactor( this ) ); - } - -/* If the MeshSize value is set in either supplied Region, set a value - for the returned Region which scales the default value by the - product of the scaling factors for the two supplied Regions. First see - if either MeshSize value is set. */ - msz_this_set = astTestMeshSize( this ); - msz_reg_set = astTestMeshSize( reg ); - if( msz_this_set || msz_reg_set ) { - -/* If so, get the two MeshSize values (one of which may be a default - value), and then clear them so that the default value will be returned - in future. */ - msz_this = astGetMeshSize( this ); - msz_reg = astGetMeshSize( reg ); - astClearMeshSize( this ); - astClearMeshSize( reg ); - -/* Get the ratio of the used MeshSize to the default MeshSize for both - Regions. */ - fac_this = (double)msz_this/(double)astGetMeshSize( this ); - fac_reg = (double)msz_reg/(double)astGetMeshSize( reg ); - -/* The MeshSize of the returned Returned is the default value scaled by - the product of the two ratios found above. */ - astSetMeshSize( result, fac_this*fac_reg*astGetMeshSize( result ) ); - -/* Re-instate the original MeshSize values for the supplied Regions (if - set) */ - if( msz_this_set ) astSetMeshSize( this, msz_this ); - if( msz_reg_set ) astSetMeshSize( reg, msz_reg ); - } - -/* Free remaining resources */ - frm_this = astAnnul( frm_this ); - frm_reg = astAnnul( frm_reg ); - map_this = astAnnul( map_this ); - map_reg = astAnnul( map_reg ); - bcmap = astAnnul( bcmap ); - cfrm = astAnnul( cfrm ); - new = astAnnul( new ); - } - bfrm = astAnnul( bfrm ); - pset_new = astAnnul( pset_new ); - - } - } - -/* If an error has occurred, annul the returned pointer. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -void PointListPoints( AstPointList *this, AstPointSet **pset, int *status) { -/* -*+ -* Name: -* astPointListPoints - -* Purpose: -* Return the defining points of a PointList. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointlist.h" -* astPointListPoints( AstPointList *this, AstPointSet **pset ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns the axis values at the points defining the -* supplied PointList. - -* Parameters: -* this -* Pointer to the PointList. -* pset -* Address of a location at which to return a pointer to a PointSet -* holding the points in the PointList, in the base Frame of the -* encapsulated FrameSet. The returned Pointer should be annulled -* when no longer needed. - -*- -*/ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Return a clone of the PointSet holding the points defining the PointList. */ - *pset = astClone( ((AstRegion *) this)->points ); - -} - -static void RegBaseBox( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* void astRegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* PointList member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to encapsulated Frame */ - AstPointList *this; /* Pointer to PointList structure */ - AstPointSet *pset; /* Pointer to PointSet defining the Region */ - double **ptr; /* Pointer to PointSet data */ - double *p; /* Pointer to next axis value */ - double *lb; /* Pointer to lower limit array */ - double *ub; /* Pointer to upper limit array */ - double d; /* Axis offset from refernce value */ - double p0; /* Reference axis value */ - int ic; /* Axis index */ - int ip; /* Point index */ - int nb; /* Number of bytes to be copied */ - int nc; /* No. of axes in base Frame */ - int np; /* No. of points in PointSet */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the PointList structure. */ - this = (AstPointList *) this_region; - -/* Calculate the number of bytes in each array. */ - nb = sizeof( double )*(size_t) astGetNaxes( this ); - -/* If the base Frame bounding box has not yet been found, find it now and - store it in the PointList structure. */ - if( !this->lbnd || !this->ubnd ) { - -/* Allocate memory to store the bounding box in the PointList structure. */ - lb = astMalloc( nb ); - ub = astMalloc( nb ); - -/* Get the axis values for the PointSet which defines the location and - extent of the region in the base Frame of the encapsulated FrameSet. */ - pset = this_region->points; - ptr = astGetPoints( pset ); - nc = astGetNcoord( pset ); - np = astGetNpoint( pset ); - -/* Get a pointer to the base Frame in the encaposulated FrameSet. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Find the bounds on each axis in turn. */ - for( ic = 0; ic < nc; ic++ ) { - -/* We first find the max and min axis offsets from the first point. We - used astAxDistance to cater for the possbility that the Frame may be a - SkyFrame and thus have circular redundancy. */ - p = ptr[ ic ] + 1; - p0 = p[ -1 ]; - lb[ ic ] = 0.0; - ub[ ic ] = 0.0; - for( ip = 1; ip < np; ip++, p++ ) { - d = astAxDistance( frm, ic + 1, p0, *p ); - if( d < lb[ ic ] ) lb[ ic ] = d; - if( d > ub[ ic ] ) ub[ ic ] = d; - } - -/* Now convert these offsets to actual axis values. */ - lb[ ic ] = astAxOffset( frm, ic + 1, p0, lb[ ic ] ); - ub[ ic ] = astAxOffset( frm, ic + 1, p0, ub[ ic ] ); - - } - } - -/* Free resources */ - frm = astAnnul( frm ); - -/* Store the pointers in the PointList structure. */ - if( astOK ) { - this->lbnd = lb; - this->ubnd = ub; - } else { - this->lbnd = astFree( this->lbnd ); - this->ubnd = astFree( this->ubnd ); - } - } - -/* If the bounding box has been found succesfully, copy it into the supplied - arrays. */ - if( astOK ) { - memcpy( lbnd, this->lbnd, nb ); - memcpy( ubnd, this->ubnd, nb ); - } - -} - -static AstPointSet *RegBaseMesh( AstRegion *this, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Return a PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* AstPointSet *astRegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* PointList member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. The axis values in this PointSet will have -* associated accuracies derived from the accuracies which were -* supplied when the Region was created. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - -/* Local Variables: */ - AstPointSet *result; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* If the Region structure contains a pointer to a PointSet holding - a previously created mesh, return it. */ - if( this->basemesh ) { - result = astClone( this->basemesh ); - -/* Otherwise, create a new mesh. */ - } else { - -/* It is just a copy of the encapsulated PointSet. */ - result = astCopy( this->points ); - -/* Same the returned pointer in the Region structure so that it does not - need to be created again next time this function is called. */ - if( astOK && result ) this->basemesh = astClone( result ); - } - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static AstRegion *RegBasePick( AstRegion *this_region, int naxes, - const int *axes, int *status ){ -/* -* Name: -* RegBasePick - -* Purpose: -* Return a Region formed by picking selected base Frame axes from the -* supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* AstRegion *RegBasePick( AstRegion *this, int naxes, const int *axes, -* int *status ) - -* Class Membership: -* PointList member function (over-rides the astRegBasePick protected -* method inherited from the Region class). - -* Description: -* This function attempts to return a Region that is spanned by selected -* axes from the base Frame of the encapsulated FrameSet of the supplied -* Region. This may or may not be possible, depending on the class of -* Region. If it is not possible a NULL pointer is returned. - -* Parameters: -* this -* Pointer to the Region. -* naxes -* The number of base Frame axes to select. -* axes -* An array holding the zero-based indices of the base Frame axes -* that are to be selected. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Region, or NULL if no region can be formed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* The base Frame in the supplied Region */ - AstFrame *frm; /* The base Frame in the returned Region */ - AstPointSet *pset; /* Holds axis values defining the supplied Region */ - AstPointSet *pset_new; /* Holds axis values defining the returned Region */ - AstRegion *bunc; /* The uncertainty in the supplied Region */ - AstRegion *result; /* Returned Region */ - AstRegion *unc; /* The uncertainty in the returned Region */ - double **ptr; /* Holds axis values defining the supplied Region */ - double **ptr_new; /* Holds axis values defining the returned Region */ - double *p; /* Pointer to next input axis value */ - double *q; /* Pointer to next output axis value */ - int i; /* Index of axis within returned Region */ - int j; /* Point index */ - int npnt; /* Number of points in PointList */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the base Frame of the encapsulated FrameSet. */ - bfrm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Create a Frame by picking the selected axes from the base Frame of the - encapsulated FrameSet. */ - frm = astPickAxes( bfrm, naxes, axes, NULL ); - -/* Get the uncertainty Region (if any) within the base Frame of the supplied - Region, and select the required axes from it. If the resulting Object - is not a Region, annul it so that the returned Region will have no - uncertainty. */ - if( astTestUnc( this_region ) ) { - bunc = astGetUncFrm( this_region, AST__BASE ); - unc = astPickAxes( bunc, naxes, axes, NULL ); - bunc = astAnnul( bunc ); - - if( ! astIsARegion( unc ) ) unc = astAnnul( unc ); - - } else { - unc = NULL; - } - -/* Get pointers to the coordinate data in the parent Region structure. */ - pset = this_region->points; - ptr = astGetPoints( pset ); - npnt = astGetNpoint( pset ); - -/* Create a PointSet to hold the points for the returned PointList. */ - pset_new = astPointSet( npnt, naxes, "", status ); - -/* Get pointers to its data. */ - ptr_new = astGetPoints( pset_new ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Copy the point positions on the selected axes into the arrays allocated - above. */ - for( i = 0; i < naxes; i++ ) { - p = ptr[ axes[ i ] ]; - q = ptr_new[ i ]; - for( j = 0; j < npnt; j++ ) *(q++) = *(p++); - } - -/* Create the new PointList. */ - result = (AstRegion *) astPointList( frm, pset_new, unc, "", status ); - } - -/* Free resources */ - frm = astAnnul( frm ); - bfrm = astAnnul( bfrm ); - if( unc ) unc = astAnnul( unc ); - pset_new = astAnnul( pset_new ); - -/* Return a NULL pointer if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int RegPins( AstRegion *this_region, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -* Name: -* RegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given PointList. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask, int *status ) - -* Class Membership: -* PointList member function (over-rides the astRegPins protected -* method inherited from the Region class). - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given PointList. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied PointList "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the PointList. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "this". -* Each element in the returned array is set to 1 if the -* corresponding position in "this" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*/ - -/* Local variables: */ - AstPointList *pl; /* Pointer to PointList holding supplied points */ - AstPointList *this; /* Pointer to the PointList structure. */ - AstPointSet *pset2; /* Supplied points masked by this PointList */ - AstPointSet *pset3; /* This PointList masked by supplied points */ - double **ptr2; /* Pointer to axis values in "pset2" */ - double **ptr3; /* Pointer to axis values in "pset3" */ - double **ptr; /* Pointer to axis values in "this" */ - double *p; /* Pointer to next axis value to read */ - int ic; /* Axis index */ - int icurr; /* Index of original current Frame in "this" */ - int ip; /* Point index */ - int nc; /* No. of axes in Box base frame */ - int neg_old; /* Original Negated flag for "this" */ - int np; /* No. of supplied points */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - if( mask ) *mask = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the Box structure. */ - this = (AstPointList *) this_region; - -/* Temporarily ensure that the current Frame in "this" is the same as the - base Frame. We need to do this since the supplied points are in the - base Frame of "this", but the astTransform method below assumes - that it is transforming points in the current Frame of the Region. */ - icurr = astGetCurrent( this_region->frameset ); - astSetCurrent( this_region->frameset, AST__BASE ); - -/* Get pointer to the supplied axis values, the number of points and the - number of axis values per point. */ - ptr = astGetPoints( pset ); - np = astGetNpoint( pset ); - nc = astGetNcoord( pset ); - -/* All the supplied points should be within the supplied PointsList region - (given that "within" implies some tolerance). Transform the positions - using this PointList and check if any of the resulting points fell - outside this PointList. We need to ensure that the PointList is not - negated first. */ - neg_old = astGetNegated( this ); - astSetNegated( this, 0 ); - pset2 = astTransform( this, pset, 1, NULL ); - ptr2 = astGetPoints( pset2 ); - -/* Check pointers can be used. */ - if( astOK ) { - -/* Check there are no bad points (i.e. check that none of the points are - outside the supplied PointList). The algorithm used to do this depends - on whether we need to create an output mask. */ - result = 1; - if( mask ) { - -/* Create the returned mask array. */ - *mask = astMalloc( np ); - if( astOK ) { - -/* Initialise the mask elements on the basis of the first axis values */ - result = 1; - p = ptr2[ 0 ]; - for( ip = 0; ip < np; ip++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ ip ] = 0; - } else { - (*mask)[ ip ] = 1; - } - } - -/* Now check for bad values on other axes. */ - for( ic = 1; ic < nc; ic++ ) { - p = ptr2[ ic ]; - for( ip = 0; ip < np; ip++ ) { - if( *(p++) == AST__BAD ) { - result = 0; - (*mask)[ ip ] = 0; - } - } - } - } - -/* If no output mask is to be made, we can break out of the check as soon - as the first bad value is found. */ - } else { - for( ic = 0; ic < nc && result; ic++ ){ - p = ptr2[ ic ]; - for( ip = 0; ip < np; ip++,p++ ){ - if( *p == AST__BAD ) { - result = 0; - break; - } - } - } - } - -/* If this check was passed, we perform a similar check in the opposite - direction: we create a new PointList from the supplied list of points, - and then we transform the points associated with the supplied PointList - using the new PointList. This checks that all the points in the - supplied PointList are close to the supplied points. Create the new - PointList holding the supplied points. */ - if( result ) { - pl = astPointList( unc, pset, unc, "", status ); - -/* Transform the points in "this" PointList using the new PointList as a - Mapping. */ - pset3 = astTransform( pl, this_region->points, 1, NULL ); - ptr3 = astGetPoints( pset3 ); - -/* Check pointers can be used. */ - if( astOK ) { - for( ic = 0; ic < nc && result; ic++ ){ - p = ptr3[ ic ]; - for( ip = 0; ip < np; ip++,p++ ){ - if( *p == AST__BAD ) { - result = 0; - break; - } - } - } - } - -/* Free resources. */ - pl = astAnnul( pl ); - pset3 = astAnnul( pset3 ); - - } - } - - pset2 = astAnnul( pset2 ); - -/* Re-instate the original current Frame in "this". */ - astSetCurrent( this_region->frameset, icurr ); - -/* Re-instate the original Negated flag for "this". */ - astSetNegated( this, neg_old ); - -/* If an error has occurred, return zero. */ - if( !astOK ) { - result = 0; - if( mask ) *mask = astAnnul( *mask ); - } - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, - int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a PointList. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* PointList member function (over-rides the astSetAttrib protected -* method inherited from the Object class). - -* Description: -* This function assigns an attribute value for a PointList, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the PointList. -* setting -* Pointer to a null-terminated string specifying the new -* attribute value. -*/ - -/* Local Variables: */ - AstPointList *this; /* Pointer to the PointList structure */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PointList structure. */ - this = (AstPointList *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* Use this macro to report an error if a read-only attribute has been - specified. */ - if ( MATCH( "listsize" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", - status, setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mapping represented by a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* PointList method (over-rides the astSimplify method inherited -* from the Region class). - -* Description: -* This function invokes the parent Region Simplify method, and then -* performs any further region-specific simplification. -* -* If the Mapping from base to current Frame is not a UnitMap, this -* will include attempting to fit a new Region to the boundary defined -* in the current Frame. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the simplified Region. A cloned pointer to the -* supplied Region will be returned if no simplication could be -* performed. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to encapsulated Frame */ - AstMapping *map; /* Pointer to frameset Mapping */ - AstMapping *result; /* Result pointer to return */ - AstPointList *new2; /* Pointer to simplified Region */ - AstPointSet *pset1; /* Original base Frame positions */ - AstPointSet *pset2; /* Current Frame Frame positions */ - AstRegion *new; /* Pointer to simplified Region */ - AstRegion *this; /* Pointer to original Region structure */ - AstRegion *unc; /* Pointer to new uncertainty Region */ - double **ptr2; /* Pointer to current Frame points */ - int simpler; /* Has some simplication taken place? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_mapping; - -/* Invoke the parent Simplify method inherited from the Region class. This - will simplify the encapsulated FrameSet and uncertainty Region. */ - new = (AstRegion *) (*parent_simplify)( this_mapping, status ); - -/* Note if any simplification took place. This is assumed to be the case - if the pointer returned by the above call is different to the supplied - pointer. */ - simpler = ( new != this ); - -/* Get the Mapping from base to current Frame. We can modify the PointList so - that a UnitMap can be used. This is good because it means that the - serialised PointList is simpler since the Dump function only needs to - record one Frame instead of the whole FrameSet. */ - map = astGetMapping( new->frameset, AST__BASE, AST__CURRENT ); - if( !astIsAUnitMap( map ) ){ - -/* Get a pointer to the current Region Frame */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - -/* Get the PointSet which holds the base Frame positions defining this - PointList. */ - pset1 = this->points; - -/* Transform the PointSet using this Mapping. */ - pset2 = astTransform( map, pset1, 1, NULL ); - ptr2 = astGetPoints( pset2 ); - -/* Get the Region describing the positional uncertainty within the - supplied PointList, in its current Frame. */ - unc = astGetUncFrm( new, AST__CURRENT ); - -/* Create a new PointList, and use it in place of the original. */ - new2 = astPointList( fr, pset2, unc, "", status ); - (void) astAnnul( new ); - new = (AstRegion *) new2; - simpler = 1; - -/* Free resources. */ - fr = astAnnul( fr ); - pset2 = astAnnul( pset2 ); - unc = astAnnul( unc ); - } - -/* Free resources. */ - map = astAnnul( map ); - -/* If any simplification could be performed, copy Region attributes from - the supplied Region to the returned Region, and return a pointer to it. - If the supplied Region had no uncertainty, ensure the returned Region - has no uncertainty. Otherwise, return a clone of the supplied pointer. */ - if( simpler ){ - astRegOverlay( new, this, 1 ); - result = (AstMapping *) new; - - } else { - new = astAnnul( new ); - result = astClone( this ); - } - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, - int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a PointList. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PointList member function (over-rides the astTestAttrib protected -* method inherited from the Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate -* whether a value has been set for one of a PointList's attributes. - -* Parameters: -* this -* Pointer to the PointList. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPointList *this; /* Pointer to the PointList structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the PointList structure. */ - this = (AstPointList *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* Test if the name matches any of the read-only attributes of this - class. If it does, then return zero. */ - if ( !strcmp( attrib, "listsize" ) ){ - result = 0; - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a PointList to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "pointlist.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* PointList member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a PointList and a set of points encapsulated in a -* PointSet and transforms the points by setting axis values to -* AST__BAD for all points which are outside the region covered by the -* PointList. PointList inside the region are copied unchanged from input -* to output. - -* Parameters: -* this -* Pointer to the PointList. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - The forward and inverse transformations are identical for a -* Region. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of axes in the Frame represented by the PointList. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *in_base; /* Pointer to PointSet holding base Frame positions*/ - AstPointSet *ps1; /* Pointer to accumulation PointSet */ - AstPointSet *ps2; /* Pointer to accumulation PointSet */ - AstPointSet *ps3; /* Pointer for swapping PointSet pointers */ - AstPointSet *pset_base; /* PointList positions in "unc" base Frame */ - AstPointSet *pset_reg; /* Pointer to Region PointSet */ - AstPointSet *result; /* Pointer to output PointSet */ - AstRegion *this; /* Pointer to the Region structure */ - AstRegion *unc; /* Pointer to uncertainty Region */ - double **ptr1; /* Pointer to mask pointer array */ - double **ptr_base; /* Pointer to axis values for "pset_base" */ - double **ptr_out; /* Pointer to output coordinate data */ - double *cen_orig; /* Pointer to array holding original centre coords */ - double *mask; /* Pointer to mask axis values */ - int coord; /* Zero-based index for coordinates */ - int ncoord_base; /* No. of coordinates per base Frame point */ - int ncoord_out; /* No. of coordinates per output point */ - int npoint; /* No. of supplied input test points */ - int nrp; /* No. of points in Region PointSet */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Avoid -Wall compiler warnings. */ - ps1 = NULL; - ps2 = NULL; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_mapping; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, - containing a copy of the input PointSet. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* First use the encapsulated FrameSet to transform the supplied positions - from the current Frame in the encapsulated FrameSet (the Frame - represented by the Region), to the base Frame (the Frame in which the - Region is defined). */ - in_base = astRegTransform( this, in, 0, NULL, NULL ); - -/* The PointSet pointer returned above may be a clone of the "in" - pointer. If so take a copy of the PointSet so we can change it safely. */ - if( in_base == in ) { - ps3 = astCopy( in_base ); - (void) astAnnul( in_base ); - in_base = ps3; - ps3 = NULL; - } - -/* Determine the numbers of points and coordinates per point from the base - Frame PointSet and obtain pointers for accessing the base Frame and output - coordinate values. */ - npoint = astGetNpoint( in_base ); - ncoord_base = astGetNcoord( in_base ); - ncoord_out = astGetNcoord( result ); - ptr_out = astGetPoints( result ); - -/* Get the axis values for the PointSet which defines the location and - extent of the region in the base Frame, and check them. */ - pset_reg = this->points; - nrp = astGetNpoint( pset_reg ); - if( astGetNcoord( pset_reg ) != ncoord_base && astOK ) { - astError( AST__INTER, "astTransform(PointList): Illegal number of " - "coords (%d) in the Region - should be %d " - "(internal AST programming error).", status, astGetNcoord( pset_reg ), - ncoord_base ); - } - -/* Get the base Frame uncertainty Region. Temporarily set its negated flag. */ - unc = astGetUncFrm( this, AST__BASE ); - astSetNegated( unc, 1 ); - -/* Transform the PointList PointSet into the base Frame of the uncertainty - Region, and get pointers to the corresponding axis value. */ - pset_base = astRegTransform( unc, pset_reg, 0, NULL, NULL ); - ptr_base = astGetPoints( pset_base ); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - -/* Save the original base Frame centre coords of the uncertainty Region. */ - cen_orig = astRegCentre( unc, NULL, NULL, 0, AST__BASE ); - -/* We use the PointSet created above as the initial input to astTransform - below. Also indicate we currently have no output PointSet. This will - cause a new PointSet to be created on the first pass through the loop - below. */ - ps1 = astClone( in_base ); - ps2 = NULL; - -/* Loop round all the points in the PointList. */ - for ( point = 0; point < nrp; point++ ) { - -/* Centre the uncertainty Region at this PointList position. Note, the - base Frame of the PointList should be the same as the current Frame - of the uncertainty Region. */ - astRegCentre( unc, NULL, ptr_base, point, AST__BASE ); - -/* Use the uncertainty Region to transform the supplied PointSet. This - will set supplied points bad if they are within the uncertainty Region - (since the uncertainty Region has been negated above). */ - ps2 = astTransform( unc, ps1, 0, ps2 ); - -/* Use the output PointSet created above as the input for the next - position. This causes bad points to be accumulated in the output - PointSet. */ - ps3 = ps2; - ps2 = ps1; - ps1 = ps3; - - } - -/* Re-instate the original centre coords of the uncertainty Region. */ - astRegCentre( unc, cen_orig, NULL, 0, AST__BASE ); - cen_orig = astFree( cen_orig ); - -/* The ps1 PointSet will now be a copy of the supplied PointSet but with - positions set to bad if they are inside any of the re-centred uncertainty - Regions. If this PointList has been negated, this is what we want so - we just transfer this bad position mask to the result PointSet. If this - PointList has not been negated we need to invert the bad position - mask. Get a pointer to the first axis of the resulting PointSet. */ - ptr1 = astGetPoints( ps1 ); - if( astOK ) { - mask = ptr1[ 0 ]; - -/* Apply the mask to the returned PointSet, inverted if necessary. */ - if( astGetNegated( this ) ) { - for ( point = 0; point < npoint; point++, mask++ ) { - if( *mask == AST__BAD ) { - for( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - - } else { - for ( point = 0; point < npoint; point++, mask++ ) { - if( *mask != AST__BAD ) { - for( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - } - } - } - -/* Clear the negated flag for the uncertainty Region. */ - astClearNegated( unc ); - -/* Free resources */ - in_base = astAnnul( in_base ); - pset_base = astAnnul( pset_base ); - unc = astAnnul( unc ); - if( ps2 ) ps2 = astAnnul( ps2 ); - if( ps1 ) ps1 = astAnnul( ps1 ); - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* ListSize - -* Purpose: -* Number of points in a PointList. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This is a read-only attribute giving the number of points in a -* PointList. This value is determined when the PointList is created. - -* Applicability: -* PointList -* All PointLists have this attribute. -*att-- -*/ - - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for PointList objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for PointList objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstPointList *in; /* Pointer to input PointList */ - AstPointList *out; /* Pointer to output PointList */ - int nb; /* Number of bytes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output PointLists. */ - in = (AstPointList *) objin; - out = (AstPointList *) objout; - -/* For safety, first clear any references to the input memory from - the output PointList. */ - out->lbnd = NULL; - out->ubnd = NULL; - -/* Copy dynamic memory contents */ - if( in->lbnd && in->ubnd ) { - nb = sizeof( double )*astGetNaxes( in ); - out->lbnd = astStore( NULL, in->lbnd, nb ); - out->ubnd = astStore( NULL, in->ubnd, nb ); - } -} - - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for PointList objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for PointList objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstPointList *this; /* Pointer to PointList */ - -/* Obtain a pointer to the PointList structure. */ - this = (AstPointList *) obj; - -/* Annul all resources. */ - this->lbnd = astFree( this->lbnd ); - this->ubnd = astFree( this->ubnd ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for PointList objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the PointList class to an output Channel. - -* Parameters: -* this -* Pointer to the PointList whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPointList *this; /* Pointer to the PointList structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PointList structure. */ - this = (AstPointList *) this_object; - -/* Write out values representing the instance variables for the - PointList class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPointList and astCheckPointList functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(PointList,Region) -astMAKE_CHECK(PointList) - -AstPointList *astPointList_( void *frame_void, AstPointSet *points, - AstRegion *unc, const char *options, - int *status, ...) { -/* -*+ -* Name: -* astPointList - -* Purpose: -* Create a PointList. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointlist.h" -* AstPointList *astPointList( AstFrame *frame, AstPointSet *points, -* AstRegion *unc, const char *options, -* int *status, ...) { - -* Class Membership: -* PointList constructor. - -* Description: -* This function implements the protected interface to the astPointList -* constructor function, returning a true C pointer. The parameter list -* differs from the public constructor, in that the positions are -* defined by a PointSet rather than an array of doubles. - -* Parameters: -* frame -* A pointer to the Frame in which the region is defined. A deep -* copy is taken of the supplied Frame. This means that any -* subsequent changes made to the Frame using the supplied pointer -* will have no effect the Region. -* points -* A PointSet holding the physical coordinates of the points. -* unc -* An optional pointer to an existing Region which specifies the -* uncertainties associated with each point in the PointList being -* created. The uncertainty at any point in the PointList is found by -* shifting the supplied "uncertainty" Region so that it is centred at -* the point being considered. The area covered by the shifted -* uncertainty Region then represents the uncertainty in the position. -* The uncertainty is assumed to be the same for all points. -* -* If supplied, the uncertainty Region must be of a class for which -* all instances are centro-symetric (e.g. Box, Circle, Ellipse, etc.) -* or be a Prism containing centro-symetric component Regions. A deep -* copy of the supplied Region will be taken, so subsequent changes to -* the uncertainty Region using the supplied pointer will have no -* effect on the created Box. Alternatively, a NULL Object pointer -* may be supplied, in which case a default uncertainty is used -* equivalent to a box 1.0E-6 of the size of the bounding box of the -* PointList being created. -* -* The uncertainty Region has two uses: 1) when the astOverlap -* function compares two Regions for equality the uncertainty Region -* is used to determine the tolerance on the comparison, and 2) -* when a Region is mapped into a different coordinate system and -* subsequently simplified (using astSimplify), the uncertainties are -* used to determine if the transformed boundary can be accurately -* represented by a specific shape of Region. -* options -* Pointer to a null-terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new PointList. The syntax used is identical to -* that for the astSet function and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* status -* Pointer to the inherited status value. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of additional arguments may follow it in -* order to supply values to be substituted for these -* specifiers. The rules for supplying these are identical to -* those for the astSet function (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new PointList. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPointList *new; /* Pointer to new PointList */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the supplied Frame structure. */ - frame = astCheckFrame( frame_void ); - -/* Initialise the PointList, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPointList( NULL, sizeof( AstPointList ), !class_init, - &class_vtab, "PointList", frame, points, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new PointList's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new PointList. */ - return new; -} - -AstPointList *astPointListId_( void *frame_void, int npnt, int ncoord, int dim, - const double *points, void *unc_void, - const char *options, ... ) { -/* -*++ -* Name: -c astPointList -f AST_POINTLIST - -* Purpose: -* Create a PointList. - -* Type: -* Public function. - -* Synopsis: -c #include "pointlist.h" -c AstPointList *astPointList( AstFrame *frame, int npnt, int ncoord, int dim, -c const double *points, AstRegion *unc, -c const char *options, ... ) -f RESULT = AST_POINTLIST( FRAME, NPNT, COORD, DIM, POINTS, UNC, OPTIONS, STATUS ) - -* Class Membership: -* PointList constructor. - -* Description: -* This function creates a new PointList object and optionally initialises -* its attributes. -* -* A PointList object is a specialised type of Region which represents a -* collection of points in a coordinate Frame. - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* A pointer to the Frame in which the region is defined. A deep -* copy is taken of the supplied Frame. This means that any -* subsequent changes made to the Frame using the supplied pointer -* will have no effect the Region. -c npnt -f NPNT = INTEGER (Given) -* The number of points in the Region. -c ncoord -f NCOORD = INTEGER (Given) -* The number of coordinates being supplied for each point. This -* must equal the number of axes in the supplied Frame, given by -* its Naxes attribute. -c dim -f DIM = INTEGER (Given) -c The number of elements along the second dimension of the "points" -f The number of elements along the first dimension of the POINTS -* array (which contains the point coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -c given should not be less than "npnt". -f given should not be less than NPNT. -c points -f POINTS( DIM, NCOORD ) = DOUBLE PRECISION (Given) -c The address of the first element of a 2-dimensional array of -c shape "[ncoord][dim]" giving the physical coordinates of the -c points. These should be stored such that the value of coordinate -c number "coord" for point number "pnt" is found in element -c "in[coord][pnt]". -f A 2-dimensional array giving the physical coordinates of the -f points. These should be stored such that the value of coordinate -f number COORD for point number PNT is found in element IN(PNT,COORD). -c unc -f UNC = INTEGER (Given) -* An optional pointer to an existing Region which specifies the uncertainties -* associated with each point in the PointList being created. The -* uncertainty at any point in the PointList is found by shifting the -* supplied "uncertainty" Region so that it is centred at the point -* being considered. The area covered by the shifted uncertainty Region -* then represents the uncertainty in the position. The uncertainty is -* assumed to be the same for all points. -* -* If supplied, the uncertainty Region must be of a class for which -* all instances are centro-symetric (e.g. Box, Circle, Ellipse, etc.) -* or be a Prism containing centro-symetric component Regions. A deep -* copy of the supplied Region will be taken, so subsequent changes to -* the uncertainty Region using the supplied pointer will have no -* effect on the created Box. Alternatively, -f a null Object pointer (AST__NULL) -c a NULL Object pointer -* may be supplied, in which case a default uncertainty is used -* equivalent to a box 1.0E-6 of the size of the bounding box of the -* PointList being created. -* -* The uncertainty Region has two uses: 1) when the -c astOverlap -f AST_OVERLAP -* function compares two Regions for equality the uncertainty -* Region is used to determine the tolerance on the comparison, and 2) -* when a Region is mapped into a different coordinate system and -* subsequently simplified (using -c astSimplify), -f AST_SIMPLIFY), -* the uncertainties are used to determine if the transformed boundary -* can be accurately represented by a specific shape of Region. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new PointList. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new PointList. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPointList() -f AST_POINTLIST = INTEGER -* A pointer to the new PointList. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPointList *new; /* Pointer to new PointList */ - AstPointSet *pset; /* Pointer to PointSet holding points */ - AstRegion *unc; /* Pointer to Region structure */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const double *q; /* Pointer to next supplied axis value */ - double **ptr; /* Pointer to data in pset */ - double *p; /* Pointer to next PointSet axis value */ - int *status; /* Pointer to inherited status value */ - int i; /* Axis index */ - int j; /* Point index */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Frame pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Frame. */ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - -/* Create a PointSet and store the supplied points in it. */ - pset = astPointSet( npnt, ncoord , "", status ); - ptr = astGetPoints( pset ); - if( astOK ) { - for( i = 0; i < ncoord; i++ ) { - p = ptr[ i ]; - q = points + i*dim; - for( j = 0; j < npnt; j++ ) *(p++) = *(q++); - } - } - -/* Obtain a Region pointer from the supplied "unc" ID and validate the - pointer to ensure it identifies a valid Region . */ - unc = unc_void ? astCheckRegion( astMakePointer( unc_void ) ) : NULL; - -/* Initialise the PointList, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPointList( NULL, sizeof( AstPointList ), !class_init, - &class_vtab, "PointList", frame, pset, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new PointList's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Free resources. */ - pset = astAnnul( pset ); - -/* Return an ID value for the new PointList. */ - return astMakeId( new ); -} - -AstPointList *astInitPointList_( void *mem, size_t size, int init, - AstPointListVtab *vtab, const char *name, - AstFrame *frame, AstPointSet *points, - AstRegion *unc, int *status ) { -/* -*+ -* Name: -* astInitPointList - -* Purpose: -* Initialise a PointList. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointlist.h" -* AstPointList *astInitPointList( void *mem, size_t size, int init, -* AstPointListVtab *vtab, const char *name, -* AstFrame *frame, AstPointSet *points, -* AstRegion *unc, int *status ) - -* Class Membership: -* PointList initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new PointList object. It allocates memory (if necessary) to accommodate -* the PointList plus any additional data associated with the derived class. -* It then initialises a PointList structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a PointList at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the PointList is to be initialised. -* This must be of sufficient size to accommodate the PointList data -* (sizeof(PointList)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the PointList (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the PointList -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the PointList's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new PointList. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* A pointer to the Frame in which the region is defined. -* points -* A PointSet containing the Points for the PointList. -* unc -* A pointer to a Region which specifies the uncertainty in the -* supplied positions (all points in the new PointList being -* initialised are assumed to have the same uncertainty). A NULL -* pointer can be supplied, in which case default uncertainties equal -* to 1.0E-6 of the dimensions of the new PointList's bounding box are -* used. If an uncertainty Region is supplied, it must be either a Box, -* a Circle or an Ellipse, and its encapsulated Frame must be related -* to the Frame supplied for parameter "frame" (i.e. astConvert -* should be able to find a Mapping between them). Two positions -* the "frame" Frame are considered to be co-incident if their -* uncertainty Regions overlap. The centre of the supplied -* uncertainty Region is immaterial since it will be re-centred on the -* point being tested before use. A deep copy is taken of the supplied -* Region. - -* Returned Value: -* A pointer to the new PointList. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstPointList *new; /* Pointer to new PointList */ - int ncoord; /* No. of axes in PointSet */ - int nin; /* No. of axes in Frame */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitPointListVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check the number of axis values per position is correct. */ - nin = astGetNaxes( frame ); - ncoord = astGetNcoord( points ); - if( nin != ncoord ) { - astError( AST__NCPIN, "astInitPointList(): Bad number of coordinate " - "values (%d).", status, ncoord ); - astError( AST__NCPIN, "The %s given requires %d coordinate value(s) for " - "each input point.", status, astGetClass( frame ), nin ); - } - -/* Initialise a Region structure (the parent class) as the first component - within the PointList structure, allocating memory if necessary. */ - if( astOK ) { - new = (AstPointList *) astInitRegion( mem, size, 0, (AstRegionVtab *) vtab, - name, frame, points, unc ); - if ( astOK ) { - -/* Initialise the PointList data. */ -/* ------------------------------ */ - new->lbnd = NULL; - new->ubnd = NULL; - -/* If an error occurred, clean up by deleting the new PointList. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new PointList. */ - return new; -} - -AstPointList *astLoadPointList_( void *mem, size_t size, AstPointListVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPointList - -* Purpose: -* Load a PointList. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointlist.h" -* AstPointList *astLoadPointList( void *mem, size_t size, AstPointListVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* PointList loader. - -* Description: -* This function is provided to load a new PointList using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* PointList structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a PointList at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the PointList is to be -* loaded. This must be of sufficient size to accommodate the -* PointList data (sizeof(PointList)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the PointList (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the PointList structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPointList) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new PointList. If this is NULL, a pointer -* to the (static) virtual function table for the PointList class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "PointList" is used instead. - -* Returned Value: -* A pointer to the new PointList. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPointList *new; /* Pointer to the new PointList */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this PointList. In this case the - PointList belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPointList ); - vtab = &class_vtab; - name = "PointList"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPointListVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built PointList. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "PointList" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* If an error occurred, clean up by deleting the new PointList. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new PointList pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -int astGetListSize_( AstPointList *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,PointList,GetListSize))( this, status ); -} -void astPointListPoints_( AstPointList *this, AstPointSet **pset, int *status) { - if ( !astOK ) return; - (**astMEMBER(this,PointList,PointListPoints))( this, pset, status ); - return; -} - diff --git a/ast/pointlist.h b/ast/pointlist.h deleted file mode 100644 index a2e35b7..0000000 --- a/ast/pointlist.h +++ /dev/null @@ -1,239 +0,0 @@ -#if !defined( POINTLIST_INCLUDED ) /* Include this file only once */ -#define POINTLIST_INCLUDED -/* -*+ -* Name: -* pointlist.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the PointList class. - -* Invocation: -* #include "pointlist.h" - -* Description: -* This include file defines the interface to the PointList class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The PointList class implements a Region which represents a collection -* of points in a Frame. - -* Inheritance: -* The PointList class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 23-AUG-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "region.h" /* Coordinate regions (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* PointList structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstPointList { - -/* Attributes inherited from the parent class. */ - AstRegion region; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *lbnd; /* Lower axis limits of bounding box */ - double *ubnd; /* Upper axis limits of bounding box */ -} AstPointList; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstPointListVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - int (* GetListSize)( AstPointList *, int * ); - void (* PointListPoints)( AstPointList *, AstPointSet **, int * ); -} AstPointListVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstPointListGlobals { - AstPointListVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 101 ]; -} AstPointListGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitPointListGlobals_( AstPointListGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(PointList) /* Check class membership */ -astPROTO_ISA(PointList) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstPointList *astPointList_( void *, AstPointSet *, AstRegion *, const char *, int *, ...); -#else -AstPointList *astPointListId_( void *, int, int, int, const double *, AstRegion *, const char *, ... )__attribute__((format(printf,7,8))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstPointList *astInitPointList_( void *, size_t, int, AstPointListVtab *, - const char *, AstFrame *, AstPointSet *, - AstRegion *, int * ); - -/* Vtab initialiser. */ -void astInitPointListVtab_( AstPointListVtab *, const char *, int * ); - -/* Loader. */ -AstPointList *astLoadPointList_( void *, size_t, AstPointListVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -int astGetListSize_( AstPointList *, int * ); -void astPointListPoints_( AstPointList *, AstPointSet **, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckPointList(this) astINVOKE_CHECK(PointList,this,0) -#define astVerifyPointList(this) astINVOKE_CHECK(PointList,this,1) - -/* Test class membership. */ -#define astIsAPointList(this) astINVOKE_ISA(PointList,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astPointList astINVOKE(F,astPointList_) -#else -#define astPointList astINVOKE(F,astPointListId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitPointList(mem,size,init,vtab,name,frame,points,unc) \ -astINVOKE(O,astInitPointList_(mem,size,init,vtab,name,frame,points,unc,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitPointListVtab(vtab,name) astINVOKE(V,astInitPointListVtab_(vtab,name,STATUS_PTR)) - -/* Loader. */ -#define astLoadPointList(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadPointList_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckPointList to validate PointList pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astGetListSize(this) \ -astINVOKE(V,astGetListSize_(astCheckPointList(this),STATUS_PTR)) -#define astPointListPoints(this,pset) \ -astINVOKE(V,astPointListPoints_(astCheckPointList(this),pset,STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/pointset.c b/ast/pointset.c deleted file mode 100644 index cdbdef6..0000000 --- a/ast/pointset.c +++ /dev/null @@ -1,3285 +0,0 @@ -/* -* Name: -* pointset.c - -* Purpose: -* Implement the PointSet class. - -* Description: -* This file implements the PointSet class. For a description of -* the class and its interface, see the .h file of the same name. - -* Inheritance: -* The PointSet class inherits from the Object class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 1-FEB-1996 (RFWS): -* Original version. -* 27-SEP-1996 (RFWS): -* Added external interface and I/O facilities. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitPointSetVtab -* method. -* 9-SEP-2004 (DSB): -* Added astPermPoints. -* 5-OCT-2004 (DSB): -* Bug fix in astLoadPointSet - npoint was used as size for new array -* of pointers (changed to ncoord). -* 19-OCT-2004 (DSB): -* Added astSetNpoint. -* 2-NOV-2004 (DSB): -* - Do not write out AST__BAD axis values in the Dump function. -* - Override astEqual method. -* - Add protected PointAccuracy attribute. -* 7-JAN-2005 (DSB): -* Added astAppendPoints. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 22-FEB-2006 (DSB): -* Avoid allocating memory for "acc" unless needed. -* 1-MAY-2009 (DSB): -* Added astBndPoints. -* 16-JUN-2011 (DSB): -* Added astReplaceNan. -* 2-OCT-2012 (DSB): -* Check for Infs as well as NaNs. -* 24-MAY-2016 (DSB): -* Added astShowPoints. -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS PointSet - -/* Values that control the behaviour of the astReplaceNaN method. */ -#define IGNORE_NANS 0 -#define REPLACE_NANS 1 -#define REPORT_NANS 2 - -/* -* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a method to clear a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "pointset.h" -* MAKE_CLEAR(attr,component,assign) - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstPointSet *this, int axis ) -* -* and an external interface function of the form: -* -* void astClear_( AstPointSet *this, int axis ) -* -* which implement a method for clearing a single value in a specified -* multi-valued attribute for an axis of a PointSet. The "axis" value -* must be in the range 0 to (ncoord-1). - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. PointAccuracy in "astClearPointAccuracy"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attr,component,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstPointSet *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= this->ncoord ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astClear" #attr, astGetClass( this ), \ - axis + 1, this->ncoord ); \ -\ -/* Assign the "clear" value. */ \ - } else if( this->component ){ \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attr##_( AstPointSet *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,PointSet,Clear##attr))( this, axis, status ); \ -} - - -/* -* -* Name: -* MAKE_GET - -* Purpose: -* Implement a method to get a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "pointset.h" -* MAKE_GET(attr,type,bad_value,assign) - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( AstPointSet *this, int axis ) -* -* and an external interface function of the form: -* -* astGet_( AstPointSet *this, int axis ) -* -* which implement a method for getting a single value from a specified -* multi-valued attribute for an axis of a PointSet. The "axis" value -* must be in the range 0 to (ncoord-1). - - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. PointAccuracy in "astGetPointAccuracy"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. This can -* use the string "axis" to represent the zero-based value index. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET(attr,type,bad_value,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attr( AstPointSet *this, int axis, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Initialise */ \ - result = bad_value; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= this->ncoord ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astGet" #attr, astGetClass( this ), \ - axis + 1, this->ncoord ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -type astGet##attr##_( AstPointSet *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,PointSet,Get##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_SET - -* Purpose: -* Implement a method to set a single value in a multi-valued attribute -* for a PointSet. - -* Type: -* Private macro. - -* Synopsis: -* #include "pointset.h" -* MAKE_SET(attr,type,component,assign,null) - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstPointSet *this, int axis, value ) -* -* and an external interface function of the form: -* -* void astSet_( AstPointSet *this, int axis, value ) -* -* which implement a method for setting a single value in a specified -* multi-valued attribute for a PointSet. The "axis" value must be in -* the range 0 to (ncoord-1). - -* Parameters: -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. PointAccuracy in "astSetPointAccuracy"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. -* null -* The value to initialise newly created array elements to. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET(attr,type,component,assign,null) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstPointSet *this, int axis, type value, int *status ) { \ - int i; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= this->ncoord ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astSet" #attr, astGetClass( this ), \ - axis + 1, this->ncoord ); \ -\ -/* Store the new value in the structure component. */ \ - } else { \ - if( !this->component ){ \ - this->component = astMalloc( this->ncoord*sizeof( type ) ); \ - for( i = 0; i < this->ncoord; i++ ) { \ - this->component[ i ] = null; \ - } \ - } \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attr##_( AstPointSet *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,PointSet,Set##attr))( this, axis, value, status ); \ -} - -/* -* -* Name: -* MAKE_TEST - -* Purpose: -* Implement a method to test if a single value has been set in a -* multi-valued attribute for a class. - -* Type: -* Private macro. - -* Synopsis: -* #include "pointset.h" -* MAKE_TEST(attr,assign) - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static int Test( AstPointSet *this, int axis ) -* -* and an external interface function of the form: -* -* int astTest_( AstPointSet *this, int axis ) -* -* which implement a method for testing if a single value in a specified -* multi-valued attribute has been set for a class. The "axis" value -* must be in the range 0 to (ncoord-1). - -* Parameters: -* attr -* The name of the attribute to be tested, as it appears in the function -* name (e.g. PointAccuracy in "astTestPointAccuracy"). -* assign -* An expression that evaluates to 0 or 1, to be used as the returned -* value. This can use the string "axis" to represent the zero-based -* index of the value within the attribute. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_TEST(attr,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static int Test##attr( AstPointSet *this, int axis, int *status ) { \ - int result; /* Value to return */ \ -\ - result= 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= this->ncoord ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astTest" #attr, astGetClass( this ), \ - axis + 1, this->ncoord ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -int astTest##attr##_( AstPointSet *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,PointSet,Test##attr))( this, axis, status ); \ -} - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* This static variable is used to hold an IEEE 754 quiet double precision - Nan value. */ -static double ast_nan; - -/* This static variable is used to hold an IEEE 754 quiet single precision - Nan value. */ -static float ast_nanf; - -/* Enable or disable the astReplaceNan method. */ -static int replace_nan = -1; - -/* Pointers to parent class methods which are extended by this class. */ -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static int (* parent_equal)( AstObject *, AstObject *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(PointSet) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(PointSet,Class_Init) -#define class_vtab astGLOBAL(PointSet,Class_Vtab) -#define getattrib_buff astGLOBAL(PointSet,GetAttrib_Buff) - -static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX1 pthread_mutex_lock( &mutex1 ); -#define UNLOCK_MUTEX1 pthread_mutex_unlock( &mutex1 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPointSetVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX1 -#define UNLOCK_MUTEX1 - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstPointSet *astPointSetId_( int, int, const char *, int *, ...); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static const char *GetAttrib( AstObject *, const char *, int * ); -static double **GetPoints( AstPointSet *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetNcoord( const AstPointSet *, int * ); -static int GetNpoint( const AstPointSet *, int * ); -static int GetObjSize( AstObject *, int * ); -static int ReplaceNaN( AstPointSet *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static AstPointSet *AppendPoints( AstPointSet *, AstPointSet *, int * ); -static void BndPoints( AstPointSet *, double *, double *, int * ); -static void CheckPerm( AstPointSet *, const int *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void PermPoints( AstPointSet *, int, const int[], int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetNpoint( AstPointSet *, int, int * ); -static void SetPoints( AstPointSet *, double **, int * ); -static void SetSubPoints( AstPointSet *, int, int, AstPointSet *, int * ); -static void ShowPoints( AstPointSet *, int * ); - -static double GetPointAccuracy( AstPointSet *, int, int * ); -static int TestPointAccuracy( AstPointSet *, int, int * ); -static void ClearPointAccuracy( AstPointSet *, int, int * ); -static void SetPointAccuracy( AstPointSet *, int, double, int * ); - -/* Member functions. */ -/* ================= */ -static AstPointSet *AppendPoints( AstPointSet *this, AstPointSet *that, int *status ) { -/* -*+ -* Name: -* astAppendPoints - -* Purpose: -* Append one PointSet to another. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* AstPointSet *astAppendPoints( AstPointSet *this, AstPointSet *that ) - -* Class Membership: -* PointSet method. - -* Description: -* This function creates a new PointSet containing all the points in -* "this" followed by all the points in "that". - -* Parameters: -* this -* Pointer to the first PointSet. -* that -* Pointer to the second PointSet. - -* Returned Value: -* Pointer to the new PointSet. - -* Notes: -* - Axis accuracies are copied from "this". -* - The Ncoord attribute of the two PointSets must match. -* - NULL will be returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstPointSet *result; - double **ptr; - double **ptr1; - double **ptr2; - int ic; - int n1; - int n2; - int ncoord; - size_t nb2; - size_t nb1; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check the two PointSets have the same Ncoord value. */ - ncoord = astGetNcoord( this ); - if( ncoord != astGetNcoord( that ) ) { - astError( AST__NPTIN, "astAppendPoints(%s): Number of coordinates " - "per point differ in the two supplied PointSets.", status, - astGetClass( this ) ); - -/* Calculate the new size for the PointSet. */ - } else { - n1 = astGetNpoint( this ); - n2 = astGetNpoint( that ); - -/* Create the new PointSet and get pointers to its data. */ - result = astPointSet( n1 + n2, ncoord, "", status ); - ptr1 = astGetPoints( this ); - ptr2 = astGetPoints( that ); - ptr = astGetPoints( result ); - if( astOK ) { - -/* Copy the axis values for each coordinate in turn. */ - nb1 = sizeof( double )*(size_t) n1; - nb2 = sizeof( double )*(size_t) n2; - for( ic = 0; ic < ncoord; ic++ ) { - memcpy( ptr[ ic ], ptr1[ ic ], nb1 ); - memcpy( ptr[ ic ] + n1, ptr2[ ic ], nb2 ); - } - -/* Copy any axis accuracies from "this". */ - result->acc = this->acc ? - astStore( NULL, this->acc, sizeof( double )*(size_t) ncoord ) - : NULL; - } - } - -/* Annul the result if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void BndPoints( AstPointSet *this, double *lbnd, double *ubnd, int *status ) { -/* -*+ -* Name: -* astBndPoints - -* Purpose: -* Find the axis bounds of the points in a PointSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* void astBndPoints( AstPointSet *this, double *lbnd, double *ubnd ) - -* Class Membership: -* PointSet method. - -* Description: -* This function returns the lower and upper limits of the axis values -* of the points in a PointSet. - -* Parameters: -* this -* Pointer to the first PointSet. -* lbnd -* Pointer to an array in which to return the lowest value for -* each coordinate. The length of the array should equal the number -* returned by astGetNcoord. -* ubnd -* Pointer to an array in which to return the highest value for -* each coordinate. The length of the array should equal the number -* returned by astGetNcoord. - -*- -*/ - -/* Local Variables: */ - double **ptr; - double *p; - double lb; - double ub; - int ic; - int ip; - int nc; - int np; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get pointers to the PointSet data, the number of axes adn the number - of points. */ - ptr = astGetPoints( this ); - nc = astGetNcoord( this ); - np = astGetNpoint( this ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Loop round each axis. */ - for( ic = 0; ic < nc; ic++ ) { - -/* Initialise the bounds for this axis. */ - lb = AST__BAD; - ub = AST__BAD; - -/* Search for the first good point. Use it to initialise the bounds and - break out of the loop. */ - p = ptr[ ic ]; - for( ip = 0; ip < np; ip++,p++ ) { - if( *p != AST__BAD ) { - lb = ub = *p; - break; - } - } - -/* Search through the remaining points. Update the bounds if the axis - value is good. */ - for( ; ip < np; ip++,p++ ) { - if( *p != AST__BAD ) { - if( *p < lb ) { - lb = *p; - } else if( *p > ub ) { - ub = *p; - } - } - } - -/* Store the returned bounds. */ - lbnd[ ic ] = lb; - ubnd[ ic ] = ub; - } - } -} - -static void CheckPerm( AstPointSet *this, const int *perm, const char *method, int *status ) { -/* -*+ -* Name: -* astCheckPerm - -* Purpose: -* Check that an array contains a valid permutation. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* void astCheckPerm( AstPointSet *this, const int *perm, const char *method ) - -* Class Membership: -* PointSet method. - -* Description: -* This function checks the validity of a permutation array that -* will be used to permute the order of a PointSet's axes. If the -* permutation specified by the array is not valid, an error is -* reported and the global error status is set. Otherwise, the -* function returns without further action. - -* Parameters: -* this -* Pointer to the PointSet. -* perm -* Pointer to an array of integers with the same number of -* elements as there are axes in the PointSet. For each axis, the -* corresponding integer gives the (zero based) axis index to be -* used to identify the axis values for that axis (using the -* un-permuted axis numbering). To be valid, the integers in -* this array should therefore all lie in the range zero to -* (ncoord-1) inclusive, where "ncoord" is the number of PointSet -* axes, and each value should occur exactly once. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate a permutation array. This method name is used -* solely for constructing error messages. - -* Notes: -* - Error messages issued by this function refer to the external -* (public) numbering system used for axes (which is one-based), -* whereas zero-based axis indices are used internally. -*- -*/ - -/* Local Variables: */ - int *there; /* Pointer to temporary array */ - int coord; /* Loop counter for axes */ - int ncoord; /* Number of PointSet axes */ - int valid; /* Permutation array is valid? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise. */ - valid = 1; - -/* Obtain the number of PointSet axes and allocate a temporary array of - integers with the same number of elements. */ - ncoord = astGetNcoord( this ); - there = astMalloc( sizeof( int ) * (size_t) ncoord ); - if ( astOK ) { - -/* Initialise the temporary array to zero. */ - for ( coord = 0; coord < ncoord; coord++ ) there[ coord ] = 0; - -/* Scan the permutation array, checking that each permuted axis index it - contains is within the correct range. Note an error and quit checking - if an invalid value is found. */ - for ( coord = 0; coord < ncoord; coord++ ) { - if ( ( perm[ coord ] < 0 ) || ( perm[ coord ] >= ncoord ) ) { - valid = 0; - break; - -/* Use the temporary array to count how many times each valid axis index - occurs. */ - } else { - there[ perm[ coord ] ]++; - } - } - -/* If all the axis indices were within range, check to ensure that each value - occurred only once. */ - if ( valid ) { - for ( coord = 0; coord < ncoord; coord++ ) { - -/* Note an error and quit checking if any value did not occur exactly once. */ - if ( there[ coord ] != 1 ) { - valid = 0; - break; - } - } - } - } - -/* Free the temporary array. */ - there = astFree( there ); - -/* If an invalid permutation was detected and no other error has - occurred, then report an error (note we convert to one-based axis - numbering in the error message). */ - if ( !valid && astOK ) { - astError( AST__PRMIN, "%s(%s): Invalid coordinate permutation array.", status, - method, astGetClass( this ) ); - astError( AST__PRMIN, "Each coordinate index should lie in the range 1 to %d " - "and should occur only once.", status, ncoord ); - } -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a PointSet. - -* Type: -* Private function. - -* Synopsis: -* #include "pointset.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PointSet member function (over-rides the astClearAttrib -* protected method inherited from the Object class). - -* Description: -* This function clears the value of a specified attribute for a -* PointSet, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the PointSet. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPointSet *this; /* Pointer to the PointSet structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PointSet structure. */ - this = (AstPointSet *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Test if the name matches any of the read-only attributes of this - class. If it does, then report an error. */ - if ( !strcmp( attrib, "ncoord" ) || - !strcmp( attrib, "npoint" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two PointSets are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "pointset.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* PointSet member function (over-rides the astEqual protected -* method inherited from the Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two PointSets are equivalent. - -* Parameters: -* this -* Pointer to the first PointSet. -* that -* Pointer to the second PointSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the PointSets are equivalent, zero otherwise. - -* Notes: -* - The two PointSets are considered equivalent if they have the same -* number of points, the same number of axis values per point, and the -* same axis values to within the absolute tolerance specified by the -* Accuracy attribute of the two PointSets. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local constants: */ -#define SMALL sqrt(DBL_MIN) - -/* Local Variables: */ - AstPointSet *that; /* Pointer to the second PointSet structure */ - AstPointSet *this; /* Pointer to the first PointSet structure */ - double **ptr_that; /* Pointer to axis values in second PointSet */ - double **ptr_this; /* Pointer to axis values in first PointSet */ - double *p_that; /* Pointer to next axis value in second PointSet */ - double *p_this; /* Pointer to next axis value in first PointSet */ - double acc1; /* Absolute accuracy for 1st PointSet axis value */ - double acc2; /* Absolute accuracy for 2nd PointSet axis value */ - double acc; /* Combined absolute accuracy */ - double acc_that; /* PointAccuracy attribute for 2nd PointSet */ - double acc_this; /* PointAccuracy attribute for 1st PointSet */ - int ic; /* Axis index */ - int ip; /* Point index */ - int nc; /* No. of axis values per point */ - int np; /* No. of points in each PointSet */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the Equal method inherited from the parent Object class. This checks - that the Objects are both of the same class (amongst other things). */ - if( (*parent_equal)( this_object, that_object, status ) ) { - -/* Obtain pointers to the two PointSet structures. */ - this = (AstPointSet *) this_object; - that = (AstPointSet *) that_object; - -/* Check the number of points and the number of axis values per point are - equal in the two PointSets. */ - np = astGetNpoint( this ); - nc = astGetNcoord( this ); - if( np == astGetNpoint( that ) && nc == astGetNcoord( that ) ) { - -/* Get pointers to the axis values.*/ - ptr_this = astGetPoints( this ); - ptr_that = astGetPoints( that ); - if( astOK ) { - -/* Assume the PointSets are equal until proven otherwise. */ - result = 1; - -/* Loop round each axis, until we find a difference. */ - for( ic = 0; ic < nc && result; ic++ ) { - -/* Get pointers to the next value for this axis. */ - p_this = ptr_this[ ic ]; - p_that = ptr_that[ ic ]; - -/* Get the absolute accuracies for this axis. The default value for this - attribute is AST__BAD. */ - acc_this = astGetPointAccuracy( this, ic ); - acc_that = astGetPointAccuracy( that, ic ); - -/* If both accuracies are available, combine them in quadrature. */ - if( acc_this != AST__BAD && acc_that != AST__BAD ) { - acc = sqrt( acc_this*acc_this + acc_that*acc_that ); - -/* Loop round all points on this axis */ - for( ip = 0; ip < np; ip++, p_this++, p_that++ ){ - -/* If either value is bad we do not need to compare values. */ - if( *p_this == AST__BAD || *p_that == AST__BAD ) { - -/* If one value is bad and one is good, they differ, so break. If both - values are bad they are equal so we continue. */ - if( *p_this != AST__BAD || *p_that != AST__BAD ) { - result = 0; - break; - } - -/* Otherwise (if both axis values are good), compare axis values, and break if - they differ by more than the absolute accuracy. */ - } else if( fabs( *p_this - *p_that ) > acc ) { - result = 0; - break; - } - } - -/* If either accuracy is unavailable, we use a default relative accuracy. */ - } else { - -/* Loop round all points on this axis */ - for( ip = 0; ip < np; ip++, p_this++, p_that++ ){ - -/* If either value is bad we do not need to compare values. */ - if( *p_this == AST__BAD || *p_that == AST__BAD ) { - -/* If one value is bad and one is good, they differ, so break. If both - values are bad they are equal so we continue. */ - if( *p_this != AST__BAD || *p_that != AST__BAD ) { - result = 0; - break; - } - -/* Otherwise (if both axis values are good), find the absolute error for - both values. */ - } else { - - if( acc_this == AST__BAD ) { - acc1 = fabs(*p_this)*DBL_EPSILON; - if( acc1 < SMALL ) acc1 = SMALL; - acc1 *= 1.0E3; - } else { - acc1 = acc_this; - } - - if( acc_that == AST__BAD ) { - acc2 = fabs(*p_that)*DBL_EPSILON; - if( acc2 < SMALL ) acc2 = SMALL; - acc2 *= 1.0E3; - } else { - acc2 = acc_that; - } - -/* Combine them in quadrature. */ - acc = sqrt( acc1*acc1 + acc2*acc2 ); - -/* Compare axis values, and break if they differ by more than the - absolute accuracy. */ - if( fabs( *p_this - *p_that ) > acc ) { - result = 0; - break; - } - } - } - } - } - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -#undef SMALL -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a PointSet. - -* Type: -* Private function. - -* Synopsis: -* #include "pointset.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PointSet member function (over-rides the protected astGetAttrib -* method inherited from the Object class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a PointSet, formatted as a character string. - -* Parameters: -* this -* Pointer to the PointSet. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the PointSet, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the PointSet. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPointSet *this; /* Pointer to the PointSet structure */ - const char *result; /* Pointer value to return */ - int ncoord; /* Ncoord attribute value */ - int npoint; /* Npoint attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the PointSet structure. */ - this = (AstPointSet *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* Ncoord. */ -/* ------- */ - if ( !strcmp( attrib, "ncoord" ) ) { - ncoord = astGetNcoord( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ncoord ); - result = getattrib_buff; - } - -/* Npoint. */ -/* ------- */ - } else if ( !strcmp( attrib, "npoint" ) ) { - npoint = astGetNpoint( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", npoint ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "pointset.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* PointSet member function (over-rides the astGetObjSize protected -* method inherited from the Object class). - -* Description: -* This function returns the in-memory size of the supplied PointSet, -* in bytes. - -* Parameters: -* this -* Pointer to the Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPointSet *this; /* Pointer to PointSet structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the PointSet structure. */ - this = (AstPointSet *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astTSizeOf( this->ptr ); - result += astTSizeOf( this->values ); - result += astTSizeOf( this->acc ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetNcoord( const AstPointSet *this, int *status ) { -/* -*+ -* Name: -* astGetNcoord - -* Purpose: -* Get the number of coordinate values per point from a PointSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* int astGetNcoord( const AstPointSet *this ) - -* Class Membership: -* PointSet method. - -* Description: -* This function returns the number of coordinate values per point (1 or -* more) for a PointSet. - -* Parameters: -* this -* Pointer to the PointSet. - -* Returned Value: -* The number of coordinate values per point. - -* Notes: -* - A value of zero is returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the number of coordinate values. */ - return this->ncoord; -} - -static int GetNpoint( const AstPointSet *this, int *status ) { -/* -*+ -* Name: -* astGetNpoint - -* Purpose: -* Get the number of points in a PointSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* int astGetNpoint( const AstPointSet *this ) - -* Class Membership: -* PointSet method. - -* Description: -* This function returns the number of points (1 or more) in a PointSet. - -* Parameters: -* this -* Pointer to the PointSet. - -* Returned Value: -* The number of points. - -* Notes: -* - A value of zero is returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Return the number of points. */ - return this->npoint; -} - -static double **GetPoints( AstPointSet *this, int *status ) { -/* -*+ -* Name: -* astGetPoints - -* Purpose: -* Get a pointer for the coordinate values associated with a PointSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* double **astGetPoints( AstPointSet *this ) - -* Class Membership: -* PointSet method. - -* Description: -* This function returns a pointer which grants access to the coordinate -* values associated with a PointSet. If the PointSet has previously had -* coordinate values associated with it, this pointer will identify these -* values. Otherwise, it will point at a newly-allocated region of memory -* (associated with the PointSet) in which new coordinate values may be -* stored. - -* Parameters: -* this -* Pointer to the PointSet. - -* Returned Value: -* A pointer to an array of type double* with ncoord elements (where ncoord -* is the number of coordinate values per point). Each element of this array -* points at an array of double, of size npoint (where npoint is the number -* of points in the PointSet), containing the values of that coordinate for -* each point in the set. Hence, the value of the i'th coordinate for the -* j'th point (where i and j are counted from zero) is given by ptr[i][j] -* where ptr is the returned pointer value. - -* Notes: -* - The returned pointer points at an array of pointers allocated -* internally within the PointSet. The values in this array may be changed -* by the caller, who is reponsible for ensuring that they continue to -* point at valid arrays of coordinate values. -* - No attempt should be made to de-allocate memory allocated by a -* PointSet to store coordinate values or pointers to them. This memory -* will be freed when the PointSet is deleted. -* - No count is kept of the number of pointers issued for the PointSet -* coordinate values. The caller must keep track of these. -* - A NULL pointer is returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - int i; /* Loop counter for coordinates */ - int nval; /* Number of values to be stored */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* If the PointSet has an existing array of pointers (which point at coordinate - values), we will simply return a pointer to it. Otherwise, we must allocate - space to hold new coordinate values. */ - if( !this->ptr ) { - -/* Determine the number of coordinate values to be stored and allocate memory - to hold them, storing the pointer to this values array in the PointSet - structure. */ - nval = this->npoint * this->ncoord; - this->values = (double *) astMalloc( sizeof( double ) * (size_t) nval ); - -#ifdef DEBUG - for( i = 0; i < nval; i++ ) this->values[ i ] = 0.0; -#endif - -/* If OK, also allocate memory for the array of pointers into this values - array, storing a pointer to this pointer array in the PointSet structure. */ - if ( astOK ) { - this->ptr = (double **) astMalloc( sizeof( double * ) - * (size_t) this->ncoord ); - -/* If OK, initialise the pointer array to point into the values array. */ - if ( astOK ) { - for ( i = 0; i < this->ncoord; i++ ) { - this->ptr[ i ] = this->values + ( i * this->npoint ); - } - -/* If we failed to allocate the pointer array, then free the values array. */ - } else { - this->values = (double *) astFree( (void *) this->values ); - } - } - -#ifdef DEBUG - } else { - -/* Check for bad values */ - if( this->values ) { - int i, j; - for( i = 0; astOK && i < this->ncoord; i++ ) { - for( j = 0; j < this->npoint; j++ ) { - if( !finite( (this->ptr)[ i ][ j ] ) ) { - astError( AST__INTER, "astGetPoints(PointSet): Non-finite " - "axis value returned.", status); - break; - } - } - } - } - -#endif - } - -/* Return the required pointer. */ - return this->ptr; -} - -void astInitPointSetVtab_( AstPointSetVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitPointSetVtab - -* Purpose: -* Initialise a virtual function table for a PointSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointset.h" -* void astInitPointSetVtab( AstPointSetVtab *vtab, const char *name ) - -* Class Membership: -* PointSet vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the PointSet class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *envvar; /* Pointer to environment variable value */ - size_t i; /* Index of next byte in NaN value */ - unsigned char *p; /* Pointer to next byte in NaN value */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitObjectVtab( (AstObjectVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAPointSet) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstObjectVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->AppendPoints = AppendPoints; - vtab->BndPoints = BndPoints; - vtab->GetNcoord = GetNcoord; - vtab->GetNpoint = GetNpoint; - vtab->GetPoints = GetPoints; - vtab->PermPoints = PermPoints; - vtab->ReplaceNaN = ReplaceNaN; - vtab->SetPoints = SetPoints; - vtab->SetNpoint = SetNpoint; - vtab->SetSubPoints = SetSubPoints; - vtab->ShowPoints = ShowPoints; - - vtab->GetPointAccuracy = GetPointAccuracy; - vtab->SetPointAccuracy = SetPointAccuracy; - vtab->TestPointAccuracy = TestPointAccuracy; - vtab->ClearPointAccuracy = ClearPointAccuracy; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - parent_equal = object->Equal; - object->Equal = Equal; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "PointSet", "Container for a set of points" ); - -/* Calculate single and double precision NaN values and store in static - module variables. Setting all bits to 1 produces a quiet NaN. */ - LOCK_MUTEX1 - p = (unsigned char *) &ast_nan; - for( i = 0; i < sizeof( ast_nan ); i++ ) *(p++) = 255; - p = (unsigned char *) &ast_nanf; - for( i = 0; i < sizeof( ast_nanf ); i++ ) *(p++) = 255; - -/* See what action the astReplaceNaN method should perform. This - is determined by the value of the AST_REPLACE_NAN environment - variable. Not set = do not check for NaNs, "1" = replace NaNs with - AST__BAD silently, anything else = report an error if any NaNs are - encountered. */ - if( replace_nan == -1 ) { - envvar = getenv( "AST_REPLACE_NAN" ); - if( !envvar ) { - replace_nan = IGNORE_NANS; - } else if( !strcmp( envvar, "1" ) ) { - replace_nan = REPLACE_NANS; - } else { - replace_nan = REPORT_NANS; - } - } - UNLOCK_MUTEX1 - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -double astCheckNaN_( double value ) { -/* -*+ -* Name: -* astCheckNaN - -* Purpose: -* Substitute a NaN for a supplied value if the supplied value is -* AST__NAN. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointset.h" -* double astCheckNaN( double value ) - -* Class Membership: -* PointSet method. - -* Description: -* If the supplied double is AST__NAN then this function returns an -* IEEE double precision NaN value. Otherwise it returns the supplied -* value. - -* Parameters: -* valuethis -* The value to check. - -* Returned Value: -* The suppleid value, or NaN. - -* Notes: -* - This function does not check the inherited status. - -*- -*/ - return ( value == AST__NAN ) ? ast_nan : value; -} - -float astCheckNaNF_( float value ) { -/* -*+ -* Name: -* astCheckNaNF - -* Purpose: -* Substitute a NaN for a supplied value if the supplied value is -* AST__NANF. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointset.h" -* float astCheckNaNF( float value ) - -* Class Membership: -* PointSet method. - -* Description: -* If the supplied float is AST__NANF then this function returns an -* IEEE single precision NaN value. Otherwise it returns the supplied -* value. - -* Parameters: -* valuethis -* The value to check. - -* Returned Value: -* The suppleid value, or NaN. - -* Notes: -* - This function does not check the inherited status. - -*- -*/ - return ( value == AST__NANF ) ? ast_nanf : value; -} - -static void PermPoints( AstPointSet *this, int forward, const int perm[], int *status ) { -/* -*+ -* Name: -* astPermPoints - -* Purpose: -* Permute the order of a PointSet's axes. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* void astPermPoints( AstPointSet *this, int forward, const int perm[] ) - -* Class Membership: -* PointSet method. - -* Description: -* This function permutes the order in which a PointSet's axes occur. - -* Parameters: -* this -* Pointer to the PointSet. -* forward -* The direction in which the permutation is to be applied. This -* controls the use of the "perm" arrays. If a non-zero value is -* given, then the indices into the "perm" array correspond to the -* indices of the coordinates in the returned PointSet, and the -* values stored in the "perm" array correspond to the indices of -* the coordinates in the supplied PointSet. If a zero value is -* given, then the indices into the "perm" array correspond to the -* indices of the coordinates in the supplied PointSet, and the -* values stored in the "perm" array correspond to the indices of -* the coordinates in the returnedPointSet. -* perm -* An array of int (with one element for each axis of the PointSet) -* which lists the axes in their new order. How this array is use -* depends on the value supplied for "forward". - -* Notes: -* - Only genuine permutations of the axis order are permitted, so -* each axis must be referenced exactly once in the "perm" array. -* - If more than one axis permutation is applied to a PointSet, the -* effects are cumulative. -*- -*/ - -/* Local Variables: */ - double **old; /* Pointer to copy of old pointer array */ - int coord; /* Loop counter for axes */ - int ncoord; /* Number of axes */ - -/* Check the global error status. Return without action if no data is - associated with the PointSet. */ - if ( !astOK || !this->ptr ) return; - -/* Validate the permutation array, to check that it describes a genuine - permutation. */ - CheckPerm( this, perm, "astPermPoints", status ); - -/* Obtain the number of PointSet axes. */ - ncoord = astGetNcoord( this ); - -/* Allocate memory and use it to store a copy of the old pointers array for - the PointSet. */ - old = astStore( NULL, this->ptr, sizeof( double * ) * (size_t) ncoord ); - -/* Apply the new axis permutation cumulatively to the old one and store the - result in the PointSet. */ - if ( astOK ) { - if( forward ) { - for ( coord = 0; coord < ncoord; coord++ ) { - this->ptr[ coord ] = old[ perm[ coord ] ]; - } - } else { - for ( coord = 0; coord < ncoord; coord++ ) { - this->ptr[ perm[ coord ] ] = old[ coord ]; - } - } - } - -/* Free the temporary copy of the old array. */ - old = astFree( old ); -} - -static int ReplaceNaN( AstPointSet *this, int *status ) { -/* -*+ -* Name: -* astReplaceNaN - -* Purpose: -* Check for NaNs in a PointSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* int astReplaceNaNs( AstPointSet *this ) - -* Class Membership: -* PointSet method. - -* Description: -* The behaviour of this method is determined by the AST_REPLACE_NAN -* environment variable. If AST_REPLACE_NAN is undefined, then the -* method returns without action. If AST_REPLACE_NAN is "1", then the -* method examines the supplied PointSet and replaces any NaN values -* with AST__BAD. If AST_REPLACE_NAN has any other value, any NaNs in -* the supplied PointSet are still replaced, but in addition an error -* is reported. - -* Parameters: -* this -* Pointer to the PointSet. - -* Returned Value: -* Non-zero if any NaN values were found in the PointSet. If AST_REPLACE_NAN -* is undefined, then zero is always returned. - -* Notes: -* The value of the AST_REPLACE_NAN environment variable is obtained -* only once, when the PointSet virtual function table is first -* created. This value is saved for all subsequent invocations of this -* method. - -*- -*/ - -/* Local Variables: */ - double **ptr; - double *p0; - double *p; - int ic; - int nc; - int np; - int result; - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Unless the AST_REPALCE_NAN environment variable is undefined, check - for NaNs in the supplied PointSet, replacing any with AST__BAD. */ - if( replace_nan != IGNORE_NANS ) { - ptr = astGetPoints( this ); - if( ptr ) { - nc = astGetNcoord( this ); - np = astGetNpoint( this ); - for( ic = 0; ic < nc; ic++ ) { - p = ptr[ ic ]; - p0 = p + np; - for( ; p < p0; p++ ) { - if( !astISFINITE(*p) ) { - result = 1; - *p = AST__BAD; - } - } - } - -/* If any NaNs were found, and AST_REPLACE_NAN is not set to "1", report - an error. */ - if( result && replace_nan == REPORT_NANS ) { - astError( AST__ISNAN, "astReplaceNan(%s): One or more NaN values " - "were encountered within an AST PointSet.", status, - astGetClass( this ) ); - } - } - } - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a PointSet. - -* Type: -* Private function. - -* Synopsis: -* #include "pointset.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* PointSet member function (over-rides the astSetAttrib protected -* method inherited from the Object class). - -* Description: -* This function assigns an attribute value for a PointSet, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the PointSet. -* setting -* Pointer to a null-terminated string specifying the new -* attribute value. -*/ - -/* Local Variables: */ - AstPointSet *this; /* Pointer to the PointSet structure */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PointSet structure. */ - this = (AstPointSet *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* Use this macro to report an error if a read-only attribute has been - specified. */ - if ( MATCH( "ncoord" ) || - MATCH( "npoint" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static void SetNpoint( AstPointSet *this, int npoint, int *status ) { -/* -*+ -* Name: -* astSetNpoint - -* Purpose: -* Reduce the number of points in a PointSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* void astSetNpoint( AstPointSet *this, int npoint ) - -* Class Membership: -* PointSet method. - -* Description: -* This function reduces the number of points stored in a PointSet. -* Points with indices beyond the new size will be discarded. - -* Parameters: -* this -* Pointer to the PointSet. -* npoint -* The new value for the number of points in the PointSet. Must be -* less than or equal to the original size of the PointSet, and -* greater than zero. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check the new size is valid. */ - if( npoint < 1 || npoint > this->npoint ) { - astError( AST__NPTIN, "astSetNpoint(%s): Number of points (%d) is " - "not valid.", status, astGetClass( this ), npoint ); - astError( AST__NPTIN, "Should be in the range 1 to %d.", status, this->npoint ); - -/* Store the new size. */ - } else { - this->npoint = npoint; - } -} - -static void SetPoints( AstPointSet *this, double **ptr, int *status ) { -/* -*+ -* Name: -* astSetPoints - -* Purpose: -* Associate coordinate values with a PointSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* void astSetPoints( AstPointSet *this, double **ptr ) - -* Class Membership: -* PointSet method. - -* Description: -* This function associates coordinate values with a PointSet by storing an -* array of pointers to the values within the PointSet object. A pointer to -* this pointer array will later be returned when astGetPoints is used to -* locate the coordinate values. If values are already associated with the -* PointSet, the array of pointers to them is over-written by the new values -* (any internally allocated memory holding the actual coordinate values -* first being freed). - -* Parameters: -* this -* Pointer to the PointSet. -* ptr -* Pointer to an array of type double* with ncoord elements (where ncoord -* is the number of coordinate values per point in the PointSet). Each -* element of this array should point at an array of double with npoint -* elements (where npoint is the number of points in the PointSet), -* containing the values of that coordinate for each point in the set. -* Hence, the value of the i'th coordinate for the j'th point (where i -* and j are counted from zero) should be given by ptr[i][j]. - -* Returned Value: -* void - -* Notes: -* - It is the caller's responsibility to ensure that the pointer supplied -* points at a valid array of pointers that point at arrays of coordinate -* values. This is only superficially validated by this function, which then -* simply stores a copy of the supplied array of pointers for later use. -* The caller must also manage any allocation (and freeing) of memory for -* these coordinate values. -* - This functon makes a copy of the array of pointers supplied, but does -* not copy the coordinate values they point at. If a PointSet containing a -* copy of the coordinate values is required, internal memory should be -* allocated within the PointSet by calling astGetPoints before storing any -* pointer, and then copying the values into this memory. Alternatively, -* using astCopy to produce a deep copy of a PointSet will also copy the -* coordinate values. -* - A NULL pointer may be supplied as the "ptr" argument, in which case -* any previously stored array of pointers will be cancelled (and internal -* memory freed if necessary) and subsequent use of astGetPoints will then -* cause memory to be allocated internally by the PointSet to hold new -* values. -*- -*/ - -/* Local Variables: */ - int i; /* Loop counter for coordinates */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If the pointer supplied is not NULL, inspect each pointer in the array it - points at to check that none of these are NULL. This validates (to some - extent) the caller's data structure. Report an error and quit checking if a - NULL pointer is found. */ - if ( ptr ) { - for ( i = 0; i < this->ncoord; i++ ) { - if ( !ptr[ i ] ) { - astError( AST__PDSIN, "astSetPoints(%s): Invalid NULL pointer in " - "element %d of array of pointers to coordinate values.", status, - astGetClass( this ), i ); - break; - } - } - } - -/* Do not carry on if the data structure is obviously invalid. */ - if ( astOK ) { - -/* Free any memory previously allocated to store coordinate values. */ - this->values = (double *) astFree( (void *) this->values ); - -/* If a new array of pointers has been provided, (re)allocate memory and store - a copy of the array in it, saving a pointer to this copy in the PointSet - structure. */ - if ( ptr ) { - this->ptr = (double **) astStore( (void *) this->ptr, - (const void *) ptr, - sizeof( double * ) - * (size_t) this->ncoord ); - -/* If no pointer array was provided, free the previous one (if any). */ - } else { - this->ptr = (double **) astFree( (void *) this->ptr ); - } - } -} - -static void SetSubPoints( AstPointSet *point1, int point, int coord, - AstPointSet *point2, int *status ) { -/* -*+ -* Name: -* astSetSubPoints - -* Purpose: -* Associate a subset of one PointSet with another PointSet. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* void astSetSubPoints( AstPointSet *point1, int point, int coord, -* AstPointSet *point2 ) - -* Class Membership: -* PointSet method. - -* Description: -* This function selects a subset of the coordinate values associated with -* one PointSet and associates them with another PointSet. The second -* PointSet may then be used to access the subset. Any previous coordinate -* value association with the second PointSet is replaced. - -* Parameters: -* point1 -* Pointer to the first PointSet, from which a subset is to be selected. -* point -* The index of the first point (counting from zero) which is to appear -* in the subset (the number of points is determined by the size of the -* second PointSet). -* coord -* The index of the first coordinate (counting from zero) which is to -* appear in the subset (the number of coordinates is determined by the -* size of the second PointSet). -* point2 -* Second PointSet, with which the subset of coordinate values is to be -* associated. - -* Returned Value: -* void - -* Notes: -* - The range of points and coordinates selected must lie entirely within -* the first PointSet. -* - This function does not make a copy of the coordinate values, but -* merely stores pointers to the required subset of values associated with -* the first PointSet. If a PointSet containing a copy of the subset's -* coordinate values is required, then astCopy should be used to make a -* deep copy from the second PointSet. -* - If the first PointSet does not yet have coordinate values associated -* with it, then space will be allocated within it to hold values (so that -* the second PointSet has somewhere to point at). -*- -*/ - -/* Local Variables: */ - double ** ptr2; /* Pointer to new pointer array */ - double **ptr1; /* Pointer to original pointer array */ - int i; /* Loop counter for coordinates */ - int ncoord1; /* Number of coordinates in first PointSet */ - int ncoord2; /* Number of coordinates in second PointSet */ - int npoint1; /* Number of points in first PointSet */ - int npoint2; /* Number of points in second PointSet */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain the sizes of both PointSets. */ - npoint1 = astGetNpoint( point1 ); - npoint2 = astGetNpoint( point2 ); - ncoord1 = astGetNcoord( point1 ); - ncoord2 = astGetNcoord( point2 ); - -/* Check if the range of points required lies within the first PointSet and - report an error if it does not. */ - if ( astOK ) { - if ( ( point < 0 ) || ( point + npoint2 > npoint1 ) ) { - astError( AST__PTRNG, "astSetSubPoints(%s): Range of points in " - "output %s (%d to %d) lies outside the input %s extent " - "(0 to %d).", status, - astGetClass( point1 ), astGetClass( point2 ), point, - point + npoint2, astGetClass( point1 ), npoint1 ); - -/* Similarly check that the range of coordinates is valid. */ - } else if ( ( coord < 0 ) || ( coord + ncoord2 > ncoord1 ) ) { - astError( AST__CORNG, "astSetSubPoints(%s): Range of coordinates in " - "output %s (%d to %d) lies outside the input %s extent " - "(0 to %d).", status, - astGetClass( point1 ), astGetClass( point2 ), coord, - coord + ncoord2, astGetClass( point1 ), ncoord1 ); - -/* Obtain a pointer for the coordinate values associated with the first - PointSet (this will cause internal memory to be allocated if it is not - yet associated with coordinate values). */ - } else { - ptr1 = astGetPoints( point1 ); - -/* Allocate a temporary array to hold new pointer values. */ - ptr2 = (double **) astMalloc( sizeof( double * ) * (size_t) ncoord2 ); - -/* Initialise this pointer array to point at the required subset of coordinate - values. */ - if ( astOK ) { - for ( i = 0; i < ncoord2; i++ ) { - ptr2[ i ] = ptr1[ i + coord ] + point; - } - -/* Associate the second PointSet with this new pointer array. This will free - any internally allocated memory and replace any existing coordinate value - association. */ - astSetPoints( point2, ptr2 ); - } - -/* Free the temporary pointer arry. */ - ptr2 = (double **) astFree( (void * ) ptr2 ); - } - } -} - -static void ShowPoints( AstPointSet *this, int *status ) { -/* -*+ -* Name: -* astShowPoints - -* Purpose: -* Display the contents of a PointSet on standard output as a table -* in TOPCAT ASCII format. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "pointset.h" -* void astShowPoints( AstPointSet *this ) - -* Class Membership: -* PointSet method. - -* Description: -* This function displays the contents of the supplied PointSet on -* standard output as a table in TOPCAT "ascii" format. The first row -* is a comment that defines the column (axis) names as AXIS1, AXIS2, -* etc. Each subsequent row contains the axis values for one point. -* Bad axis values are represented by the string "null". - -* Parameters: -* this -* Pointer to the first PointSet. -*- -*/ - -/* Local Variables: */ - double **ptr; - double *p; - int ic; - int ip; - int nc; - int np; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get pointers to the PointSet data, the number of axes and the number - of points. */ - ptr = astGetPoints( this ); - nc = astGetNcoord( this ); - np = astGetNpoint( this ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Display the header. */ - printf("# "); - for( ic = 0; ic < nc; ic++ ) { - printf("Axis%d ", ic + 1 ); - } - printf("\n"); - -/* Display each row. */ - for( ip = 0; ip < np; ip++,p++ ) { - for( ic = 0; ic < nc; ic++ ) { - if( ptr[ic][ip] != AST__BAD ) { - printf("%.*g ", AST__DBL_DIG, ptr[ic][ip] ); - } else { - printf("%*s ", -AST__DBL_DIG, "null"); - } - } - printf("\n"); - } - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a PointSet. - -* Type: -* Private function. - -* Synopsis: -* #include "pointset.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PointSet member function (over-rides the astTestAttrib protected -* method inherited from the Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate -* whether a value has been set for one of a PointSet's attributes. - -* Parameters: -* this -* Pointer to the PointSet. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check the attribute name and test the appropriate attribute. */ - -/* Test if the name matches any of the read-only attributes of this - class. If it does, then return zero. */ - if ( !strcmp( attrib, "ncoord" ) || - !strcmp( attrib, "npoint" ) ) { - result = 0; - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ - -/* -*att+ -* Name: -* PointAccuracy - -* Purpose: -* The absolute accuracies for all points in the PointSet. - -* Type: -* Protected attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute holds the absolute accuracy for each axis in the -* PointSet. It has a separate value for each axis. It is used when -* comparing two PointSets using the protected astEqual method inherited -* from the Object class. The default value for each axis is AST__BAD -* which causes the a default accuracy of each axis value to be calculated -* as 1.0E8*min( abs(axis value)*DBL_EPSILON, DBL_MIN ). - -* Applicability: -* PointSet -* All PointSets have this attribute. -*att- -*/ -MAKE_CLEAR(PointAccuracy,acc,AST__BAD) -MAKE_GET(PointAccuracy,double,AST__BAD,this->acc?this->acc[axis]:AST__BAD) -MAKE_SET(PointAccuracy,double,acc,((value!=AST__BAD)?fabs(value):AST__BAD),AST__BAD) -MAKE_TEST(PointAccuracy,(this->acc?this->acc[axis]!=AST__BAD:0)) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for PointSet objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for PointSet objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the coordinate -* values (if any) associated with the input PointSet. -*/ - -/* Local Variables: */ - AstPointSet *in; /* Pointer to input PointSet */ - AstPointSet *out; /* Pointer to output PointSet */ - int i; /* Loop counter for coordinates */ - int nval; /* Number of values to store */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output PointSets. */ - in = (AstPointSet *) objin; - out = (AstPointSet *) objout; - -/* For safety, first clear any references to the input coordinate values from - the output PointSet. */ - out->ptr = NULL; - out->values = NULL; - out->acc = NULL; - -/* Copy axis accuracies. */ - if( in->acc ){ - out->acc = astStore( NULL, in->acc, sizeof( double )*(size_t) in->ncoord ); - } - -/* If the input PointSet is associated with coordinate values, we must - allocate memory in the output PointSet to hold a copy of them. */ - if ( in->ptr ) { - -/* Determine the number of coordinate values to be stored and allocate memory - to hold them, storing a pointer to this memory in the output PointSet. */ - nval = in->npoint * in->ncoord; - out->values = (double *) astMalloc( sizeof( double ) * (size_t) nval ); - -/* If OK, also allocate memory for the array of pointers into this values - array, storing a pointer to this pointer array in the output PointSet. */ - if ( astOK ) { - out->ptr = (double **) astMalloc( sizeof( double * ) - * (size_t) in->ncoord ); - -/* If OK, initialise the new pointer array. */ - if ( astOK ) { - for ( i = 0; i < in->ncoord; i++ ) { - out->ptr[ i ] = out->values + ( i * in->npoint ); - } - -/* If we failed to allocate the pointer array, then free the values array. */ - } else { - out->values = (double *) astFree( (void *) out->values ); - } - } - -/* Copy the values for each coordinate from the input to the output. Use a - memory copy to avoid floating point errors if the data are - un-initialised. */ - if ( astOK ) { - for ( i = 0; i < in->ncoord; i++ ) { - (void) memcpy( (void *) out->ptr[ i ], - (const void *) in->ptr[ i ], - sizeof( double ) * (size_t) in->npoint ); - } - } - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for PointSet objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for PointSet objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstPointSet *this; /* Pointer to PointSet */ - -/* Obtain a pointer to the PointSet structure. */ - this = (AstPointSet *) obj; - -/* Free memory holding axis accuracies. */ - this->acc = astFree( this->acc ); - -/* Free any pointer array and associated coordinate values array, */ - this->ptr = (double **) astFree( (void *) this->ptr ); - this->values = (double *) astFree( (void *) this->values ); - -/* Clear the remaining PointSet variables. */ - this->npoint = 0; - this->ncoord = 0; -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for PointSet objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the PointSet class to an output Channel. - -* Parameters: -* this -* Pointer to the PointSet whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. - -* Notes: -* - It is not recommended that PointSets containing large numbers -* of points be written out, as the coordinate data will be -* formatted as text and this will not be very efficient. -*/ - -/* Local Constants: */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstPointSet *this; /* Pointer to the PointSet structure */ - char key[ KEY_LEN + 1 ]; /* Buffer for keywords */ - int coord; /* Loop counter for coordinates */ - int i; /* Counter for coordinate values */ - int ival; /* Integer value */ - int makeComment; /* Include a comment? */ - int point; /* Loop counter for points */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PointSet structure. */ - this = (AstPointSet *) this_object; - -/* Write out values representing the instance variables for the - PointSet class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Npoint. */ -/* ------- */ - astWriteInt( channel, "Npoint", 1, 1, this->npoint, - "Number of points" ); - -/* Ncoord. */ -/* ------- */ - astWriteInt( channel, "Ncoord", 1, 1, this->ncoord, - "Number of coordinates per point" ); - -/* Axis Acuracies. */ -/* --------------- */ - for ( coord = 0; coord < this->ncoord; coord++ ) { - if( astTestPointAccuracy( this, coord ) ) { - (void) sprintf( key, "Acc%d", coord + 1 ); - astWriteDouble( channel, key, 1, 1, astGetPointAccuracy( this, coord ), - (coord == 0 ) ? "Axis accuracies..." : "" ); - } - } - -/* Coordinate data. */ -/* ---------------- */ -/* Write an "Empty" value to indicate whether or not the PointSet - contains data. */ - ival = ( this->ptr == NULL ); - set = ( ival != 0 ); - astWriteInt( channel, "Empty", set, 0, ival, - ival ? "PointSet is empty" : - "PointSet contains data" ); - -/* If it contains data, create a suitable keyword for each coordinate - value in turn. */ - if ( this->ptr ) { - makeComment = 1; - i = 0; - for ( point = 0; point < this->npoint; point++ ) { - for ( coord = 0; coord < this->ncoord; coord++ ) { - i++; - (void) sprintf( key, "X%d", i ); - -/* Write the value out if good. Only supply a comment for the first good value. */ - if( this->ptr[ coord ][ point ] != AST__BAD ) { - astWriteDouble( channel, key, 1, 1, this->ptr[ coord ][ point ], - ( makeComment ) ? "Coordinate values..." : "" ); - makeComment = 0; - } - } - } - } - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPointSet and astCheckPointSet functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(PointSet,Object) -astMAKE_CHECK(PointSet) - -AstPointSet *astPointSet_( int npoint, int ncoord, const char *options, int *status, ...) { -/* -*+ -* Name: -* astPointSet - -* Purpose: -* Create a PointSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointset.h" -* AstPointSet *astPointSet( int npoint, int ncoord, -* const char *options, ..., int *status ) - -* Class Membership: -* PointSet constructor. - -* Description: -* This function creates a new PointSet and optionally initialises its -* attributes. - -* Parameters: -* npoint -* The number of points to be stored in the PointSet (must be at -* least 1). -* ncoord -* The number of coordinate values associated with each point -* (must be at least 1). -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new PointSet. The syntax used is the same as -* for the astSet method and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of arguments may follow it in order to -* supply values to be substituted for these specifiers. The -* rules for supplying these are identical to those for the -* astSet method (and for the C "printf" function). - -* Returned Value: -* A pointer to the new PointSet. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPointSet *new; /* Pointer to new PointSet */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the PointSet, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPointSet( NULL, sizeof( AstPointSet ), !class_init, - &class_vtab, "PointSet", npoint, ncoord ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - PointSet's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new PointSet. */ - return new; -} - -AstPointSet *astPointSetId_( int npoint, int ncoord, - const char *options, int *status, ...) { -/* -* Name: -* astPointSetId_ - -* Purpose: -* Create a PointSet. - -* Type: -* Private function. - -* Synopsis: -* #include "pointset.h" -* AstPointSet *astPointSetId_( int npoint, int ncoord, -* const char *options, ... ) - -* Class Membership: -* PointSet constructor. - -* Description: -* This function implements the external (public) interface to the -* astPointSet constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astPointSet_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* -* The variable argument list also prevents this function from -* invoking astPointSet_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. - -* Parameters: -* As for astPointSet_. - -* Returned Value: -* The ID value associated with the new PointSet. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPointSet *new; /* Pointer to new PointSet */ - va_list args; /* Variable argument list */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise the PointSet, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPointSet( NULL, sizeof( AstPointSet ), !class_init, - &class_vtab, "PointSet", npoint, ncoord ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - PointSet's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new PointSet. */ - return astMakeId( new ); -} - -AstPointSet *astInitPointSet_( void *mem, size_t size, int init, - AstPointSetVtab *vtab, const char *name, - int npoint, int ncoord, int *status ) { -/* -*+ -* Name: -* astInitPointSet - -* Purpose: -* Initialise a PointSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointset.h" -* AstPointSet *astInitPointSet( void *mem, size_t size, int init, -* AstPointSetVtab *vtab, const char *name, -* int npoint, int ncoord ) - -* Class Membership: -* PointSet initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new PointSet object. It allocates memory (if necessary) to accommodate -* the PointSet plus any additional data associated with the derived class. -* It then initialises a PointSet structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a PointSet at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the PointSet is to be created. This -* must be of sufficient size to accommodate the PointSet data -* (sizeof(PointSet)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the PointSet (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the PointSet -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the PointSet's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new PointSet. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* npoint -* The number of points in the PointSet (must be at least 1). -* ncoord -* The number of coordinate values associated with each point (must be -* at least 1). - -* Returned Value: -* A pointer to the new PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstPointSet *new; /* Pointer to new PointSet */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitPointSetVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check the initialisation values for validity, reporting an error if - necessary. */ - if ( npoint < 1 ) { - astError( AST__NPTIN, "astInitPointSet(%s): Number of points (%d) is " - "not valid.", status, name, npoint ); - } else if ( ncoord < 1 ) { - astError( AST__NCOIN, "astInitPointSet(%s): Number of coordinates per " - "point (%d) is not valid.", status, name, ncoord ); - } - -/* Initialise an Object structure (the parent class) as the first component - within the PointSet structure, allocating memory if necessary. */ - new = (AstPointSet *) astInitObject( mem, size, 0, - (AstObjectVtab *) vtab, name ); - - if ( astOK ) { - -/* Initialise the PointSet data. */ -/* ----------------------------- */ -/* Store the number of points and number of coordinate values per point. */ - new->npoint = npoint; - new->ncoord = ncoord; - -/* Initialise pointers to the pointer array and associated coordinate - values array. */ - new->ptr = NULL; - new->values = NULL; - new->acc = NULL; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstPointSet *astLoadPointSet_( void *mem, size_t size, - AstPointSetVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPointSet - -* Purpose: -* Load a PointSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "pointset.h" -* AstPointSet *astLoadPointSet( void *mem, size_t size, -* AstPointSetVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* PointSet loader. - -* Description: -* This function is provided to load a new PointSet using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* PointSet structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the PointSet is to be -* loaded. This must be of sufficient size to accommodate the -* PointSet data (sizeof(PointSet)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the PointSet (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the PointSet structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPointSet) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new PointSet. If this is NULL, a pointer -* to the (static) virtual function table for the PointSet class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "PointSet" is used instead. - -* Returned Value: -* A pointer to the new PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstPointSet *new; /* Pointer to the new PointSet */ - char key[ KEY_LEN + 1 ]; /* Buffer for keywords */ - double acc; /* Accuracy value */ - int coord; /* Loop counter for coordinates */ - int empty; /* PointSet empty? */ - int i; /* Counter for coordinate values */ - int point; /* Loop counter for points */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this PointSet. In this case the - PointSet belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPointSet ); - vtab = &class_vtab; - name = "PointSet"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPointSetVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built PointSet. */ - new = astLoadObject( mem, size, (AstObjectVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Initialise the PointSet's data pointers. */ - new->ptr = NULL; - new->values = NULL; - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "PointSet" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Npoint. */ -/* ------- */ - new->npoint = astReadInt( channel, "npoint", 1 ); - if ( new->npoint < 1 ) new->npoint = 1; - -/* Ncoord. */ -/* ------- */ - new->ncoord = astReadInt( channel, "ncoord", 1 ); - if ( new->ncoord < 1 ) new->ncoord = 1; - -/* Axis Acuracies. */ -/* --------------- */ - new->acc = NULL; - for ( coord = 0; coord < new->ncoord; coord++ ) { - (void) sprintf( key, "acc%d", coord + 1 ); - acc = astReadDouble( channel, key, AST__BAD ); - if( !new->acc && acc != AST__BAD ) { - new->acc = astMalloc( sizeof( double )*(size_t) new->ncoord ); - if( new->acc ) { - for( i = 0; i < coord - 1; i++ ) new->acc[ i ] = AST__BAD; - } - } - if( new->acc ) new->acc[ coord ] = acc; - } - -/* Coordinate data. */ -/* ---------------- */ -/* Read a value for the "Empty" keyword to see whether the PointSet - contains data. */ - empty = astReadInt( channel, "empty", 0 ); - -/* If it does, allocate memory to hold the coordinate data and - pointers. */ - if ( astOK && !empty ) { - new->ptr = astMalloc( sizeof( double * ) * (size_t) new->ncoord ); - new->values = astMalloc( sizeof( double ) * - (size_t) ( new->npoint * new->ncoord ) ); - if ( astOK ) { - -/* Initialise the array of pointers into the main data array. */ - for ( coord = 0; coord < new->ncoord; coord++ ) { - new->ptr[ coord ] = new->values + ( coord * new->npoint ); - } - -/* Create a keyword for each coordinate value to be read. */ - i = 0; - for ( point = 0; point < new->npoint; point++ ) { - for ( coord = 0; coord < new->ncoord; coord++ ) { - i++; - (void) sprintf( key, "x%d", i ); - -/* Read and assign the values. */ - new->ptr[ coord ][ point ] = - astReadDouble( channel, key, AST__BAD ); - } - } - } - -/* If an error occurred, clean up by freeing the memory allocated - above, thus emptying the PointSet. */ - if ( !astOK ) { - new->ptr = astFree( new->ptr ); - new->values = astFree( new->values ); - } - } - -/* If an error occurred, clean up by deleting the new PointSet. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new PointSet pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -int astGetNpoint_( const AstPointSet *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,PointSet,GetNpoint))( this, status ); -} -int astGetNcoord_( const AstPointSet *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,PointSet,GetNcoord))( this, status ); -} -double **astGetPoints_( AstPointSet *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,PointSet,GetPoints))( this, status ); -} -void astPermPoints_( AstPointSet *this, int forward, const int perm[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,PointSet,PermPoints))( this, forward, perm, status ); -} -void astSetPoints_( AstPointSet *this, double **ptr, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,PointSet,SetPoints))( this, ptr, status ); -} -void astSetNpoint_( AstPointSet *this, int npoint, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,PointSet,SetNpoint))( this, npoint, status ); -} -void astSetSubPoints_( AstPointSet *point1, int point, int coord, - AstPointSet *point2, int *status ) { - if ( !astOK ) return; - (**astMEMBER(point1,PointSet,SetSubPoints))( point1, point, coord, point2, status ); -} -AstPointSet *astAppendPoints_( AstPointSet *this, AstPointSet *that, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,PointSet,AppendPoints))( this, that, status ); -} -void astBndPoints_( AstPointSet *this, double *lbnd, double *ubnd, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,PointSet,BndPoints))( this, lbnd, ubnd, status ); -} - -int astReplaceNaN_( AstPointSet *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,PointSet,ReplaceNaN))( this, status ); -} -void astShowPoints_( AstPointSet *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,PointSet,ShowPoints))( this, status ); -} - - - - - diff --git a/ast/pointset.h b/ast/pointset.h deleted file mode 100644 index 422a077..0000000 --- a/ast/pointset.h +++ /dev/null @@ -1,711 +0,0 @@ -#if !defined( POINTSET_INCLUDED ) /* Include this file only once */ -#define POINTSET_INCLUDED -/* -*+ -* Name: -* pointset.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the PointSet class. - -* Invocation: -* #include "pointset.h" - -* Description: -* This include file defines the interface to the PointSet class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. -* -* The PointSet class encapsulates sets of coordinate values -* representing points in an N-dimensional space, to which -* coordinate transformations may be applied. It also provides -* memory allocation facilities for coordinate values. - -* Inheritance: -* The PointSet class inherits from the Object class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* Ncoord (integer) -* A read-only attribute that gives the number of coordinates -* for each point in a PointSet (i.e. the number of dimensions -* of the space in which the points reside). This value is -* determined when the PointSet is created. -* Npoint (integer) -* A read-only attribute that gives the number of points that -* can be stored in the PointSet. This value is determined when -* the PointSet is created. -* PointAccuracy (floating point) -* This stores the absolute accuracies for each axis in the PointSet. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* ClearAttrib -* Clear an attribute value for a PointSet. -* GetAttrib -* Get an attribute value for a PointSet. -* SetAttrib -* Set an attribute value for a PointSet. -* TestAttrib -* Test if an attribute value has been set for a PointSet. - -* New Methods Defined: -* Public: -* astAppendPoints -* Append one PointSet to another. -* astBndPoints -* Find the axis bounds of the points in a PointSet. -* astGetPoints -* Get a pointer to the coordinate values associated with a PointSet. -* astPermPoints -* Permute coordinates within a PointSet. -* astSetPoints -* Associate coordinate values with a PointSet. -* astSetNpoint -* Reduce the size of a PointSet. -* astSetSubPoints -* Associate one PointSet with a subset of another. -* -* Protected: -* astGetNpoint -* Get the number of points in a PointSet. -* astGetNcoord -* Get the number of coordinate values per point from a PointSet. -* astGetPointAccuracy -* Get the curent value of the PointAcuracy attribute for an axis. -* astSetPointAccuracy -* Set a new value for the PointAcuracy attribute for an axis. -* astTestPointAccuracy -* Test the value of the PointAcuracy attribute for an axis. -* astClearPointAccuracy -* Clear the value of the PointAcuracy attribute for an axis. - -* Other Class Functions: -* Public: -* astIsAPointSet -* Test class membership. -* astPointSet -* Create a PointSet. -* -* Protected: -* astCheckPointSet -* Validate class membership. -* astInitPointSet -* Initialise a PointSet. -* astInitPointSetVtab -* Initialise the virtual function table for the PointSet class. -* astLoadPointSet -* Load a PointSet. - -* Macros: -* Public: -* AST__BAD -* Bad value flag for coordinate data. -* -* Protected: -* astISBAD -* Check if a value is AST__BAD or NaN. -* astISGOOD -* Check if a value is not AST__BAD or NaN. -* astISNAN -* Check if a value is NaN. - -* Type Definitions: -* Public: -* AstPointSet -* PointSet object type. -* -* Protected: -* AstPointSetVtab -* PointSet virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 30-JAN-1996 (RFWS): -* Original version. -* 27-SEP-1996 (RFWS): -* Added external interface and I/O facilities. -* 8-JAN-2003 (DSB): -* Added protected astInitPointSetVtab method. -* 2-NOV-2004 (DSB): -* Added PointAccuracy attribute. -*- -*/ - -/* Include files. */ -/* ============== */ - -/* Configuration results. */ -/* ---------------------- */ -#if HAVE_CONFIG_H -#include -#endif - -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ - -/* C header files. */ -/* --------------- */ -#include -#if defined(astCLASS) /* Protected */ -#include -#include - -#if !HAVE_DECL_ISNAN -# if HAVE_ISNAN - /* Seems that math.h does not include a prototype for isnan etc */ - int isnan( double ); -# else - /* isnan is not available prior to C99 so define - alternative macros Note multiple evaluations of "x" in these - macros!!! */ -# define isnan(x) ((x) != (x)) -# endif -#endif - -#if !HAVE_DECL_ISFINITE -# if HAVE_ISFINITE - /* Seems that math.h does not include a prototype for isfinite */ - int isfinite( double ); -# else - /* isfinite is not available prior to C99 so define - alternative macros. Note multiple evaluations of "x" in these - macros!!! */ -# define isfinite(x) (!isnan(x) && ((x) != (1.0/0.0)) && ((x) != (-1.0/0.0))) -# endif -#endif -#endif - -/* Macros. */ -/* ======= */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* -*+ -* Name: -* AST__BAD - -* Type: -* Public macro. - -* Purpose: -* Bad value flag for coordinate data. - -* Synopsis: -* #include "pointset.h" -* const double AST__BAD - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to a const double value that is used to flag -* coordinate values that are "bad" (i.e. undefined or -* meaningless). Classes that implement coordinate transformations -* should test coordinate values against this value, and -* appropriately propagate bad values to their output. -*- -*/ - -/* Define AST__BAD to be the most negative (normalised) double - value. */ - -#define AST__BAD (-(DBL_MAX)) - -/* -*+ -* Name: -* AST__NAN - -* Type: -* Public macro. - -* Purpose: -* A value representing the double precision IEEE NaN value. - -* Synopsis: -* #include "pointset.h" -* const double AST__NAN - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to a const double value that is used to indicate -* that a IEEE NaN value should be used. Note, AST__NAN itself is a finite -* double precision floating point value a little below the maximum -* allowed value for a double. This value can be used as flag to -* indicate that the corresponding IEEE NaN value should be used in its -* place. - -*- -*/ -#define AST__NAN (-(0.95*DBL_MAX)) - -/* -*+ -* Name: -* AST__NANF - -* Type: -* Public macro. - -* Purpose: -* A value representing the single precision IEEE NaN value. - -* Synopsis: -* #include "pointset.h" -* const double AST__NANF - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to a const float value that is used to indicate -* that a IEEE NaN value should be used. Note, AST__NANF itself is a finite -* single precision floating point value a little below the maximum -* allowed value for a float. This value can be used as flag to -* indicate that the corresponding IEEE NaN value should be used in its -* place. - -*- -*/ -#define AST__NANF ((float)-(0.95*FLT_MAX)) - -#if defined(astCLASS) /* Protected */ - -/* -*+ -* Name: -* astISNAN - -* Type: -* Protected macro. - -* Purpose: -* Test if a double is NaN. - -* Synopsis: -* #include "pointset.h" -* astISNAN(value) - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to a integer valued expression which is zero -* if and only if the supplied value equals NaN ("Not a Number"). - -* Parameters: -* value -* The value to be tested. This should be a double. - -* Examples: -* if( astISNAN(x) ) x = AST__BAD; -* If "x" is NaN replace it with AST__BAD. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -* - On some system it is possible that the supplied macro argument -* "x" may be evaluated multiple times. Therefore the evaluation of "x" -* should have no side effects. -*- -*/ - -#define astISNAN(value) isnan(value) - -/* -*+ -* Name: -* astISFINITE - -* Type: -* Protected macro. - -* Purpose: -* Test if a double is neither NaN nor Inf. - -* Synopsis: -* #include "pointset.h" -* astISFINITE(value) - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to a integer valued expression which is zero -* if and only if the supplied value equals NaN ("Not a Number") or Inf. - -* Parameters: -* value -* The value to be tested. This should be a double. - -* Examples: -* if( !astISFINITE(x) ) x = AST__BAD; -* If "x" is NaN or Inf replace it with AST__BAD. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -* - On some system it is possible that the supplied macro argument -* "x" may be evaluated multiple times. Therefore the evaluation of "x" -* should have no side effects. -*- -*/ - -#define astISFINITE(value) isfinite(value) - -/* -*+ -* Name: -* astISGOOD - -* Type: -* Protected macro. - -* Purpose: -* Test if a double is neither AST__BAD, NaN or Inf. - -* Synopsis: -* #include "pointset.h" -* astISGOOD(value) - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to a integer valued expression which is zero -* if and only if the supplied value equals AST__BAD or is NaN ("Not a -* Number") or "Inf". - -* Parameters: -* value -* The value to be tested. This should be a double. - -* Examples: -* if( astISGOOD(x) ) y = x; -* Checks that "x" is usable before assigning it to y. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -* - On some system it is possible that the supplied macro argument -* "x" may be evaluated multiple times. Therefore the evaluation of "x" -* should have no side effects. -*- -*/ - -#define astISGOOD(value) ( (value) != AST__BAD && astISFINITE(value) ) - - -/* -*+ -* Name: -* astISBAD - -* Type: -* Protected macro. - -* Purpose: -* Test if a double is either AST__BAD, NaN, or Inf. - -* Synopsis: -* #include "pointset.h" -* astISBAD(value) - -* Class Membership: -* Defined by the PointSet class. - -* Description: -* This macro expands to a integer valued expression which is non-zero -* if and only if the supplied value equals AST__BAD or is NaN ("Not a -* Number"), or is Inf. - -* Parameters: -* value -* The value to be tested. This should be a double. - -* Examples: -* if( astISBAD(x) ) astError( ... ); -* Reports an error if "x" is bad. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -* - On some system it is possible that the supplied macro argument -* "x" may be evaluated multiple times. Therefore the evaluation of "x" -* should have no side effects. -*- -*/ - -#define astISBAD(value) ( (value) == AST__BAD || !astISFINITE(value)) - -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* PointSet structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstPointSet { - -/* Attributes inherited from the parent class. */ - AstObject object; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double **ptr; /* Pointer to array of pointers to values */ - double *values; /* Pointer to array of coordinate values */ - int ncoord; /* Number of coordinate values per point */ - int npoint; /* Number of points */ - double *acc; /* Axis accuracies */ -} AstPointSet; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstPointSetVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstObjectVtab object_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstPointSet *(* AppendPoints)( AstPointSet *, AstPointSet *, int * ); - double **(* GetPoints)( AstPointSet *, int * ); - int (* GetNcoord)( const AstPointSet *, int * ); - int (* GetNpoint)( const AstPointSet *, int * ); - void (* BndPoints)( AstPointSet *, double *, double *, int * ); - void (* PermPoints)( AstPointSet *, int, const int[], int * ); - void (* SetNpoint)( AstPointSet *, int, int * ); - void (* SetPoints)( AstPointSet *, double **, int * ); - void (* SetSubPoints)( AstPointSet *, int, int, AstPointSet *, int * ); - void (* ShowPoints)( AstPointSet *, int * ); - int (* ReplaceNaN)( AstPointSet *, int * ); - - double (* GetPointAccuracy)( AstPointSet *, int, int * ); - int (* TestPointAccuracy)( AstPointSet *, int, int * ); - void (* ClearPointAccuracy)( AstPointSet *, int, int * ); - void (* SetPointAccuracy)( AstPointSet *, int, double, int * ); - -} AstPointSetVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstPointSetGlobals { - AstPointSetVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 101 ]; -} AstPointSetGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(PointSet) /* Check class membership */ -astPROTO_ISA(PointSet) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstPointSet *astPointSet_( int, int, const char *, int *, ...); -#else -AstPointSet *astPointSetId_( int, int, const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstPointSet *astInitPointSet_( void *, size_t, int, AstPointSetVtab *, - const char *, int, int, int * ); - -/* Vtab initialiser. */ -void astInitPointSetVtab_( AstPointSetVtab *, const char *, int * ); - -/* Loader. */ -AstPointSet *astLoadPointSet_( void *, size_t, AstPointSetVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitPointSetGlobals_( AstPointSetGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -double **astGetPoints_( AstPointSet *, int * ); -void astPermPoints_( AstPointSet *, int, const int[], int * ); -void astSetPoints_( AstPointSet *, double **, int * ); -void astSetNpoint_( AstPointSet *, int, int * ); -void astSetSubPoints_( AstPointSet *, int, int, AstPointSet *, int * ); -AstPointSet *astAppendPoints_( AstPointSet *, AstPointSet *, int * ); -void astBndPoints_( AstPointSet *, double *, double *, int * ); -int astReplaceNaN_( AstPointSet *, int * ); -void astShowPoints_( AstPointSet *, int * ); - -# if defined(astCLASS) /* Protected */ -int astGetNcoord_( const AstPointSet *, int * ); -int astGetNpoint_( const AstPointSet *, int * ); - -double astGetPointAccuracy_( AstPointSet *, int, int * ); -int astTestPointAccuracy_( AstPointSet *, int, int * ); -void astClearPointAccuracy_( AstPointSet *, int, int * ); -void astSetPointAccuracy_( AstPointSet *, int, double, int * ); - -double astCheckNaN_( double ); -float astCheckNaNF_( float ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckPointSet(this) astINVOKE_CHECK(PointSet,this,0) -#define astVerifyPointSet(this) astINVOKE_CHECK(PointSet,this,1) - -/* Test class membership. */ -#define astIsAPointSet(this) astINVOKE_ISA(PointSet,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astPointSet astINVOKE(F,astPointSet_) -#else -#define astPointSet astINVOKE(F,astPointSetId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitPointSet(mem,size,init,vtab,name,npoint,ncoord) \ -astINVOKE(O,astInitPointSet_(mem,size,init,vtab,name,npoint,ncoord,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitPointSetVtab(vtab,name) astINVOKE(V,astInitPointSetVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadPointSet(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadPointSet_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckPointSet to validate PointSet pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astGetPoints(this) \ -astINVOKE(V,astGetPoints_(astCheckPointSet(this),STATUS_PTR)) -#define astPermPoints(this,forward,perm) \ -astINVOKE(V,astPermPoints_(astCheckPointSet(this),forward,perm,STATUS_PTR)) -#define astSetPoints(this,ptr) \ -astINVOKE(V,astSetPoints_(astCheckPointSet(this),ptr,STATUS_PTR)) -#define astSetNpoint(this,np) \ -astINVOKE(V,astSetNpoint_(astCheckPointSet(this),np,STATUS_PTR)) -#define astSetSubPoints(point1,point,coord,point2) \ -astINVOKE(V,astSetSubPoints_(astCheckPointSet(point1),point,coord,astCheckPointSet(point2),STATUS_PTR)) -#define astAppendPoints(this,that) \ -astINVOKE(O,astAppendPoints_(astCheckPointSet(this),astCheckPointSet(that),STATUS_PTR)) -#define astBndPoints(this,lbnd,ubnd) \ -astINVOKE(V,astBndPoints_(astCheckPointSet(this),lbnd,ubnd,STATUS_PTR)) -#define astReplaceNaN(this) \ -astINVOKE(V,astReplaceNaN_(astCheckPointSet(this),STATUS_PTR)) -#define astShowPoints(this) \ -astINVOKE(V,astShowPoints_(astCheckPointSet(this),STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astGetNpoint(this) \ -astINVOKE(V,astGetNpoint_(astCheckPointSet(this),STATUS_PTR)) -#define astGetNcoord(this) \ -astINVOKE(V,astGetNcoord_(astCheckPointSet(this),STATUS_PTR)) - -#define astClearPointAccuracy(this,axis) \ -astINVOKE(V,astClearPointAccuracy_(astCheckPointSet(this),axis,STATUS_PTR)) -#define astGetPointAccuracy(this,axis) \ -astINVOKE(V,astGetPointAccuracy_(astCheckPointSet(this),axis,STATUS_PTR)) -#define astSetPointAccuracy(this,axis,value) \ -astINVOKE(V,astSetPointAccuracy_(astCheckPointSet(this),axis,value,STATUS_PTR)) -#define astTestPointAccuracy(this,axis) \ -astINVOKE(V,astTestPointAccuracy_(astCheckPointSet(this),axis,STATUS_PTR)) - -#define astCheckNaNF(value) astCheckNaNF_(value) -#define astCheckNaN(value) astCheckNaN_(value) - - -#endif -#endif - - - - - diff --git a/ast/polygon.c b/ast/polygon.c deleted file mode 100644 index 1dfae39..0000000 --- a/ast/polygon.c +++ /dev/null @@ -1,7087 +0,0 @@ -/* -*class++ -* Name: -* Polygon - -* Purpose: -* A polygonal region within a 2-dimensional Frame. - -* Constructor Function: -c astPolygon -f AST_POLYGON - -* Description: -* The Polygon class implements a polygonal area, defined by a -* collection of vertices, within a 2-dimensional Frame. The vertices -* are connected together by geodesic curves within the encapsulated Frame. -* For instance, if the encapsulated Frame is a simple Frame then the -* geodesics will be straight lines, but if the Frame is a SkyFrame then -* the geodesics will be great circles. Note, the vertices must be -* supplied in an order such that the inside of the polygon is to the -* left of the boundary as the vertices are traversed. Supplying them -* in the reverse order will effectively negate the polygon. -* -* Within a SkyFrame, neighbouring vertices are always joined using the -* shortest path. Thus if an edge of 180 degrees or more in length is -* required, it should be split into section each of which is less -* than 180 degrees. The closed path joining all the vertices in order -* will divide the celestial sphere into two disjoint regions. The -* inside of the polygon is the region which is circled in an -* anti-clockwise manner (when viewed from the inside of the celestial -* sphere) when moving through the list of vertices in the order in -* which they were supplied when the Polygon was created (i.e. the -* inside is to the left of the boundary when moving through the -* vertices in the order supplied). - -* Inheritance: -* The Polygon class inherits from the Region class. - -* Attributes: -* In addition to those attributes common to all Regions, every -* Polygon also has the following attributes: -* - SimpVertices: Simplify by transforming the vertices? - -* Functions: -c In addition to those functions applicable to all Regions, the -c following functions may also be applied to all Polygons: -f In addition to those routines applicable to all Regions, the -f following routines may also be applied to all Polygons: -* -c - astDownsize: Reduce the number of vertices in a Polygon. -f - AST_DOWNSIZE: Reduce the number of vertices in a Polygon. -c - astConvex: Create a Polygon giving the convex hull of a pixel array -f - AST_CONVEX: Create a Polygon giving the convex hull of a pixel array -c - astOutline: Create a Polygon outlining values in a pixel array -f - AST_OUTLINE: Create a Polygon outlining values in a pixel array - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 26-OCT-2004 (DSB): -* Original version. -* 28-MAY-2009 (DSB): -* Added astDownsize. -* 29-MAY-2009 (DSB): -* Added astOutline. -* 30-JUN-2009 (DSB): -* Override astGetBounded. -* 4-NOV-2013 (DSB): -* Modify RegPins so that it can handle uncertainty regions that straddle -* a discontinuity. Previously, such uncertainty Regions could have a huge -* bounding box resulting in matching region being far too big. -* 6-DEC-2013 (DSB): -* Reverse the order of the vertices when the Polygon is created, -* if necessary, to ensure that the unnegated Polygon is bounded. -* The parent Region class assumes that unnegated regions are -* bounded. -* 6-JAN-2014 (DSB): -* Free edges when clearing the cache, not when establishing a new -* cache, as the number of edges may have changed. -* 10-JAN-2014 (DSB): -* - Remove unused parameter description in prologue of for astOutline -* 24-FEB-2014 (DSB): -* Added astConvex. -* 25-FEB-2014 (DSB): -* Added attribute SimpVertices. -* 7-SEP-2015 (DSB): -* Shrink outline polygons by a small fraction of a pixel, in order -* to avoid placing vertices exactly on pixel edges. This is because -* rounding errors in subsequent code may push the vertices into -* neighbouring pixels, which may have bad WCS coords (e.g. -* vertices on the boundary of a polar cusp in an HPX map). -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Polygon - -/* Define a macro for testing if a pixel value satisfies the requirements - specified by and . Compiler optimisation should remove - all the "if" testing from this expression. */ -#define ISVALID(V,OperI,Value) ( \ - ( OperI == AST__LT ) ? ( (V) < Value ) : ( \ - ( OperI == AST__LE ) ? ( (V) <= Value ) : ( \ - ( OperI == AST__EQ ) ? ( (V) == Value ) : ( \ - ( OperI == AST__GE ) ? ( (V) >= Value ) : ( \ - ( OperI == AST__NE ) ? ( (V) != Value ) : ( \ - (V) > Value \ - ) \ - ) \ - ) \ - ) \ - ) \ -) - -/* Macros specifying whether a point is inside, outside or on the - boundary of the polygon. */ -#define UNKNOWN 0 -#define IN 1 -#define OUT 2 -#define ON 3 - -/* Size of pertubation (in pixels) used to avoid placing vertices exactly - on a pixel edge. */ -#define DELTA 0.01 - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "region.h" /* Coordinate regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "box.h" /* Box Regions */ -#include "wcsmap.h" /* Definitons of AST__DPI etc */ -#include "polygon.h" /* Interface definition for this class */ -#include "mapping.h" /* Position mappings */ -#include "unitmap.h" /* Unit Mapping */ -#include "pal.h" /* SLALIB library interface */ -#include "frame.h" /* Coordinate system description */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Type definitions. */ -/* ================= */ - -/* A structure that holds information about an edge of the new Polygon - being created by astDownsize. The edge is a line betweeen two of the - vertices of the original Polygon. */ -typedef struct Segment { - int i1; /* Index of starting vertex within old Polygon */ - int i2; /* Index of ending vertex within old Polygon */ - double error; /* Max geodesic distance from any old vertex to the line */ - int imax; /* Index of the old vertex at which max error is reached */ - struct Segment *next;/* Pointer to next Segment in a double link list */ - struct Segment *prev;/* Pointer to previous Segment in a double link list */ -} Segment; - - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstMapping *(* parent_simplify)( AstMapping *, int * ); -static void (* parent_setregfs)( AstRegion *, AstFrame *, int * ); -static void (* parent_resetcache)( AstRegion *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Polygon) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Polygon,Class_Init) -#define class_vtab astGLOBAL(Polygon,Class_Vtab) -#define getattrib_buff astGLOBAL(Polygon,GetAttrib_Buff) - - -#include - - -#else - -static char getattrib_buff[ 51 ]; - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPolygonVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstPolygon *astPolygonId_( void *, int, int, const double *, void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ - -/* Define a macro that expands to a single prototype for function - FindInsidePoint for a given data type and operation. */ -#define FINDINSIDEPOINT_PROTO0(X,Xtype,Oper) \ -static void FindInsidePoint##Oper##X( Xtype, const Xtype *, const int[2], const int[2], int *, int *, int *, int * ); - -/* Define a macro that expands to a set of prototypes for all operations - for function FindInsidePoint for a given data type. */ -#define FINDINSIDEPOINT_PROTO(X,Xtype) \ -FINDINSIDEPOINT_PROTO0(X,Xtype,LT) \ -FINDINSIDEPOINT_PROTO0(X,Xtype,LE) \ -FINDINSIDEPOINT_PROTO0(X,Xtype,EQ) \ -FINDINSIDEPOINT_PROTO0(X,Xtype,GE) \ -FINDINSIDEPOINT_PROTO0(X,Xtype,GT) \ -FINDINSIDEPOINT_PROTO0(X,Xtype,NE) - -/* Use the above macros to define all FindInsidePoint prototypes for all - data types and operations. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -FINDINSIDEPOINT_PROTO(LD,long double) -#endif -FINDINSIDEPOINT_PROTO(D,double) -FINDINSIDEPOINT_PROTO(L,long int) -FINDINSIDEPOINT_PROTO(UL,unsigned long int) -FINDINSIDEPOINT_PROTO(I,int) -FINDINSIDEPOINT_PROTO(UI,unsigned int) -FINDINSIDEPOINT_PROTO(S,short int) -FINDINSIDEPOINT_PROTO(US,unsigned short int) -FINDINSIDEPOINT_PROTO(B,signed char) -FINDINSIDEPOINT_PROTO(UB,unsigned char) -FINDINSIDEPOINT_PROTO(F,float) - -/* Define a macro that expands to a single prototype for function - TraceEdge for a given data type and operation. */ -#define TRACEEDGE_PROTO0(X,Xtype,Oper) \ -static AstPointSet *TraceEdge##Oper##X( Xtype, const Xtype *, const int[2], const int[2], int, int, int, int, int, int * ); - -/* Define a macro that expands to a set of prototypes for all operations - for function TraceEdge for a given data type. */ -#define TRACEEDGE_PROTO(X,Xtype) \ -TRACEEDGE_PROTO0(X,Xtype,LT) \ -TRACEEDGE_PROTO0(X,Xtype,LE) \ -TRACEEDGE_PROTO0(X,Xtype,EQ) \ -TRACEEDGE_PROTO0(X,Xtype,GE) \ -TRACEEDGE_PROTO0(X,Xtype,GT) \ -TRACEEDGE_PROTO0(X,Xtype,NE) - -/* Use the above macros to define all TraceEdge prototypes for all - data types and operations. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -TRACEEDGE_PROTO(LD,long double) -#endif -TRACEEDGE_PROTO(D,double) -TRACEEDGE_PROTO(L,long int) -TRACEEDGE_PROTO(UL,unsigned long int) -TRACEEDGE_PROTO(I,int) -TRACEEDGE_PROTO(UI,unsigned int) -TRACEEDGE_PROTO(S,short int) -TRACEEDGE_PROTO(US,unsigned short int) -TRACEEDGE_PROTO(B,signed char) -TRACEEDGE_PROTO(UB,unsigned char) -TRACEEDGE_PROTO(F,float) - -/* Define a macro that expands to a single prototype for function - PartHull for a given data type and operation. */ -#define PARTHULL_PROTO0(X,Xtype,Oper) \ -static void PartHull##Oper##X( Xtype, const Xtype[], int, int, int, int, int, int, int, const int[2], double **, double **, int *, int * ); - -/* Define a macro that expands to a set of prototypes for all operations - for function PartHull for a given data type. */ -#define PARTHULL_PROTO(X,Xtype) \ -PARTHULL_PROTO0(X,Xtype,LT) \ -PARTHULL_PROTO0(X,Xtype,LE) \ -PARTHULL_PROTO0(X,Xtype,EQ) \ -PARTHULL_PROTO0(X,Xtype,GE) \ -PARTHULL_PROTO0(X,Xtype,GT) \ -PARTHULL_PROTO0(X,Xtype,NE) - -/* Use the above macros to define all PartHull prototypes for all - data types and operations. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -PARTHULL_PROTO(LD,long double) -#endif -PARTHULL_PROTO(D,double) -PARTHULL_PROTO(L,long int) -PARTHULL_PROTO(UL,unsigned long int) -PARTHULL_PROTO(I,int) -PARTHULL_PROTO(UI,unsigned int) -PARTHULL_PROTO(S,short int) -PARTHULL_PROTO(US,unsigned short int) -PARTHULL_PROTO(B,signed char) -PARTHULL_PROTO(UB,unsigned char) -PARTHULL_PROTO(F,float) - -/* Define a macro that expands to a single prototype for function - ConvexHull for a given data type and operation. */ -#define CONVEXHULL_PROTO0(X,Xtype,Oper) \ -static AstPointSet *ConvexHull##Oper##X( Xtype, const Xtype[], const int[2], int, int, int, int * ); - -/* Define a macro that expands to a set of prototypes for all operations - for function ConvexHull for a given data type. */ -#define CONVEXHULL_PROTO(X,Xtype) \ -CONVEXHULL_PROTO0(X,Xtype,LT) \ -CONVEXHULL_PROTO0(X,Xtype,LE) \ -CONVEXHULL_PROTO0(X,Xtype,EQ) \ -CONVEXHULL_PROTO0(X,Xtype,GE) \ -CONVEXHULL_PROTO0(X,Xtype,GT) \ -CONVEXHULL_PROTO0(X,Xtype,NE) - -/* Use the above macros to define all ConvexHull prototypes for all - data types and operations. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -CONVEXHULL_PROTO(LD,long double) -#endif -CONVEXHULL_PROTO(D,double) -CONVEXHULL_PROTO(L,long int) -CONVEXHULL_PROTO(UL,unsigned long int) -CONVEXHULL_PROTO(I,int) -CONVEXHULL_PROTO(UI,unsigned int) -CONVEXHULL_PROTO(S,short int) -CONVEXHULL_PROTO(US,unsigned short int) -CONVEXHULL_PROTO(B,signed char) -CONVEXHULL_PROTO(UB,unsigned char) -CONVEXHULL_PROTO(F,float) - -/* Define a macro that expands to a single prototype for function - FindBoxEdge for a given data type and operation. */ -#define FINDBOXEDGE_PROTO0(X,Xtype,Oper) \ -static void FindBoxEdge##Oper##X( Xtype, const Xtype[], int, int, int, int, int *, int *, int *, int * ); - -/* Define a macro that expands to a set of prototypes for all operations - for function FindBoxEdge for a given data type. */ -#define FINDBOXEDGE_PROTO(X,Xtype) \ -FINDBOXEDGE_PROTO0(X,Xtype,LT) \ -FINDBOXEDGE_PROTO0(X,Xtype,LE) \ -FINDBOXEDGE_PROTO0(X,Xtype,EQ) \ -FINDBOXEDGE_PROTO0(X,Xtype,GE) \ -FINDBOXEDGE_PROTO0(X,Xtype,GT) \ -FINDBOXEDGE_PROTO0(X,Xtype,NE) - -/* Use the above macros to define all FindBoxEdge prototypes for all - data types and operations. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -FINDBOXEDGE_PROTO(LD,long double) -#endif -FINDBOXEDGE_PROTO(D,double) -FINDBOXEDGE_PROTO(L,long int) -FINDBOXEDGE_PROTO(UL,unsigned long int) -FINDBOXEDGE_PROTO(I,int) -FINDBOXEDGE_PROTO(UI,unsigned int) -FINDBOXEDGE_PROTO(S,short int) -FINDBOXEDGE_PROTO(US,unsigned short int) -FINDBOXEDGE_PROTO(B,signed char) -FINDBOXEDGE_PROTO(UB,unsigned char) -FINDBOXEDGE_PROTO(F,float) - - - - - - - - - -/* Non-generic function prototypes. */ -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *DownsizePoly( AstPointSet *, double, int, AstFrame *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstPolygon *Downsize( AstPolygon *, double, int, int * ); -static Segment *AddToChain( Segment *, Segment *, int * ); -static Segment *NewSegment( Segment *, int, int, int, int * ); -static Segment *RemoveFromChain( Segment *, Segment *, int * ); -static double Polywidth( AstFrame *, AstLineDef **, int, int, double[ 2 ], int * ); -static int GetBounded( AstRegion *, int * ); -static int IntCmp( const void *, const void * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static int RegTrace( AstRegion *, int, double *, double **, int * ); -static void Cache( AstPolygon *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void EnsureInside( AstPolygon *, int * ); -static void FindMax( Segment *, AstFrame *, double *, double *, int, int, int * ); -static void RegBaseBox( AstRegion *this, double *, double *, int * ); -static void ResetCache( AstRegion *this, int * ); -static void SetPointSet( AstPolygon *, AstPointSet *, int * ); -static void SetRegFS( AstRegion *, AstFrame *, int * ); -static void SmoothPoly( AstPointSet *, int, double, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); - -static int GetSimpVertices( AstPolygon *, int * ); -static int TestSimpVertices( AstPolygon *, int * ); -static void ClearSimpVertices( AstPolygon *, int * ); -static void SetSimpVertices( AstPolygon *, int, int * ); - - -/* Member functions. */ -/* ================= */ -static Segment *AddToChain( Segment *head, Segment *seg, int *status ){ -/* -* Name: -* AddToChain - -* Purpose: -* Add a Segment into the linked list of Segments, maintaining the -* required order in the list. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* Segment *AddToChain( Segment *head, Segment *seg, int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* The linked list of Segments maintained by astDownsize is searched -* from the high error end (the head), until a Segment is foound which -* has a lower error than the supplied segment. The supplied Segment -* is then inserted into the list at that point. - -* Parameters: -* head -* The Segment structure at the head of the list (i.e. the segment -* with maximum error). -* seg -* The Segment to be added into the list. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the link head (which will have changed if "seg" has a -* higher error than the original head). - -*/ - -/* Local Variables: */ - Segment *tseg; - -/* Check the global error status. */ - if ( !astOK ) return head; - -/* If the list is empty, return the supplied segment as the new list - head. */ - if( !head ) { - head = seg; - -/* If the supplied segment has a higher error than the original head, - insert the new segment in front of the original head. */ - } else if( seg->error > head->error ){ - seg->next = head; - head->prev = seg; - head = seg; - -/* Otherwise, move down the list from the head until a segment is found - which has a lower error than the supplied Segment. Then insert the - supplied segment into the list in front of it. */ - } else { - tseg = head; - seg->next = NULL; - - while( tseg->next ) { - if( seg->error > tseg->next->error ) { - seg->next = tseg->next; - seg->prev = tseg; - tseg->next->prev = seg; - tseg->next = seg; - break; - } - tseg = tseg->next; - } - - if( !seg->next ) { - tseg->next = seg; - seg->prev = tseg; - } - } - -/* Return the new head. */ - return head; -} - -static void Cache( AstPolygon *this, int *status ){ -/* -* Name: -* Cache - -* Purpose: -* Calculate intermediate values and cache them in the Polygon structure. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void Cache( AstPolygon *this, int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* This function uses the PointSet stored in the parent Region to calculate -* some intermediate values which are useful in other methods. These -* values are stored within the Polygon structure. - -* Parameters: -* this -* Pointer to the Polygon. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to base Frame in Polygon */ - double **ptr; /* Pointer to data in the encapsulated PointSet */ - double end[ 2 ]; /* Start position for edge */ - double maxwid; /* Maximum polygon width found so far */ - double polcen[ 2 ]; /* Polygon centre perpendicular to current edge */ - double polwid; /* Polygon width perpendicular to current edge */ - double start[ 2 ]; /* Start position for edge */ - int i; /* Axis index */ - int nv; /* Number of vertices in Polygon */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do nothing if the cached information is up to date. */ - if( this->stale ) { - -/* Get a pointer to the base Frame. */ - frm = astGetFrame( ((AstRegion *) this)->frameset, AST__BASE ); - -/* Get the number of vertices. */ - nv = astGetNpoint( ((AstRegion *) this)->points ); - -/* Get pointers to the coordinate data in the parent Region structure. */ - ptr = astGetPoints( ((AstRegion *) this)->points ); - -/* Free any existing edge information in the Polygon structure. */ - if( this->edges ) { - for( i = 0; i < nv; i++ ) { - this->edges[ i ] = astFree( this->edges[ i ] ); - } - -/* Allocate memory to store new edge information if necessary. */ - } else { - this->edges = astMalloc( sizeof( AstLineDef *)*(size_t) nv ); - this->startsat = astMalloc( sizeof( double )*(size_t) nv ); - } - -/* Check pointers can be used safely. */ - if( this->edges ) { - -/* Create and store a description of each edge. Also form the total - distance round the polygon, and the distance from the first vertex - at which each edge starts. */ - this->totlen = 0.0; - start[ 0 ] = ptr[ 0 ][ nv - 1 ]; - start[ 1 ] = ptr[ 1 ][ nv - 1 ]; - - for( i = 0; i < nv; i++ ) { - end[ 0 ] = ptr[ 0 ][ i ]; - end[ 1 ] = ptr[ 1 ][ i ]; - this->edges[ i ] = astLineDef( frm, start, end ); - start[ 0 ] = end[ 0 ]; - start[ 1 ] = end[ 1 ]; - - this->startsat[ i ] = this->totlen; - this->totlen += this->edges[ i ]->length; - } - -/* We now look for a point that is inside the polygon. We want a point - that is well within the polygon, since points that are only just inside - the polygon can give numerical problems. Loop round each edge with - non-zero length. */ - maxwid = -1.0; - for( i = 0; i < nv; i++ ) { - if( this->edges[ i ]->length > 0.0 ) { - -/* We define another line perpendicular to the current edge, passing - through the mid point of the edge, extending towards the inside of the - polygon. The following function returns the distance we can travel - along this line before we hit any of the other polygon edges. It also - puts the position corresponding to half that distance into "polcen". */ - polwid = Polywidth( frm, this->edges, i, nv, polcen, status ); - -/* If the width of the polygon perpendicular to the current edge is - greater than the width perpdeicular to any other edge, record the - width and also store the current polygon centre. */ - if( polwid > maxwid && polwid != AST__BAD ) { - maxwid = polwid; - (this->in)[ 0 ] = polcen[ 0 ]; - (this->in)[ 1 ] = polcen[ 1 ]; - } - } - } - -/* If no width was found it probably means that the polygon vertices were - given in clockwise order, resulting in the above process probing the - infinite extent outside the polygonal hole. In this case any point - outside the hole will do, so we use the current contents of the - "polcen" array. Set a flag indicating if the vertices are stored in - anti-clockwise order. */ - if( maxwid < 0.0 ) { - (this->in)[ 0 ] = polcen[ 0 ]; - (this->in)[ 1 ] = polcen[ 1 ]; - this->acw = 0; - } else { - this->acw = 1; - } - } - -/* Free resources */ - frm = astAnnul( frm ); - -/* Indicate cached information is up to date. */ - this->stale = 0; - } -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Polygon member function (over-rides the astClearAttrib protected -* method inherited from the Region class). - -* Description: -* This function clears the value of a specified attribute for a -* Polygon, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Polygon. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPolygon *this; /* Pointer to the Polygon structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Polygon structure. */ - this = (AstPolygon *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* SimpVertices. */ -/* ------------- */ - if ( !strcmp( attrib, "simpvertices" ) ) { - astClearSimpVertices( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -/* -*++ -* Name: -c astConvex -f AST_CONVEX - -* Purpose: -* Create a new Polygon representing the convex hull of a 2D data grid. - -* Type: -* Public function. - -* Synopsis: -c #include "polygon.h" -c AstPolygon *astConvex( value, int oper, const array[], -c const int lbnd[2], const int ubnd[2], int starpix ) -f RESULT = AST_CONVEX( VALUE, OPER, ARRAY, LBND, UBND, STARPIX, STATUS ) - -* Class Membership: -* Polygon method. - -* Description: -* This is a set of functions that create the shortest Polygon that -* encloses all pixels with a specified value within a gridded -* 2-dimensional data array (e.g. an image). -* -* A basic 2-dimensional Frame is used to represent the pixel coordinate -* system in the returned Polygon. The Domain attribute is set to -* "PIXEL", the Title attribute is set to "Pixel coordinates", and the -* Unit attribute for each axis is set to "pixel". All other -* attributes are left unset. The nature of the pixel coordinate system -* is determined by parameter -c "starpix". -f STARPIX. -* -* You should use a function which matches the numerical type of the -* data you are processing by replacing in the generic function -* name -c astConvex -f AST_CONVEX -c by an appropriate 1- or 2-character type code. For example, if you -* are procesing data with type -c "float", you should use the function astConvexF -f REAL, you should use the function AST_CONVEXR -* (see the "Data Type Codes" section below for the codes appropriate to -* other numerical types). - -* Parameters: -c value -f VALUE = (Given) -* A data value that specifies the pixels to be included within the -* convex hull. -c oper -f OPER = INTEGER (Given) -* Indicates how the -c "value" -f VALUE -* parameter is used to select the required pixels. It can -* have any of the following values: -c - AST__LT: include pixels with value less than "value". -c - AST__LE: include pixels with value less than or equal to "value". -c - AST__EQ: include pixels with value equal to "value". -c - AST__NE: include pixels with value not equal to "value". -c - AST__GE: include pixels with value greater than or equal to "value". -c - AST__GT: include pixels with value greater than "value". -f - AST__LT: include pixels with value less than VALUE. -f - AST__LE: include pixels with value less than or equal to VALUE. -f - AST__EQ: include pixels with value equal to VALUE. -f - AST__NE: include pixels with value not equal to VALUE. -f - AST__GE: include pixels with value greater than or equal to VALUE. -f - AST__GT: include pixels with value greater than VALUE. -c array -f ARRAY( * ) = (Given) -c Pointer to a -f A -* 2-dimensional array containing the data to be processed. The -* numerical type of this array should match the 1- or -* 2-character type code appended to the function name (e.g. if -c you are using astConvexF, the type of each array element -c should be "float"). -f you are using AST_CONVEXR, the type of each array element -f should be REAL). -* -* The storage order of data within this array should be such -* that the index of the first grid dimension varies most -* rapidly and that of the second dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -c lbnd -f LBND( 2 ) = INTEGER (Given) -c Pointer to an array of two integers -f An array -* containing the coordinates of the centre of the first pixel -* in the input grid along each dimension. -c ubnd -f UBND( 2) = INTEGER (Given) -c Pointer to an array of two integers -f An array -* containing the coordinates of the centre of the last pixel in -* the input grid along each dimension. -* -c Note that "lbnd" and "ubnd" together define the shape -f Note that LBND and UBND together define the shape -* and size of the input grid, its extent along a particular -c (j'th) dimension being ubnd[j]-lbnd[j]+1 (assuming the -c index "j" to be zero-based). They also define -f (J'th) dimension being UBND(J)-LBND(J)+1. They also define -* the input grid's coordinate system, each pixel having unit -* extent along each dimension with integral coordinate values -* at its centre or upper corner, as selected by parameter -c "starpix". -f STARPIX. -c starpix -f STARPIX = LOGICAL (Given) -* A flag indicating the nature of the pixel coordinate system used -* to describe the vertex positions in the returned Polygon. If -c non-zero, -f .TRUE., -* the standard Starlink definition of pixel coordinate is used in -* which a pixel with integer index I spans a range of pixel coordinate -* from (I-1) to I (i.e. pixel corners have integral pixel coordinates). -c If zero, -f If .FALSE., -* the definition of pixel coordinate used by other AST functions -c such as astResample, astMask, -f such as AST_RESAMPLE, AST_MASK, -* etc., is used. In this definition, a pixel with integer index I -* spans a range of pixel coordinate from (I-0.5) to (I+0.5) (i.e. -* pixel centres have integral pixel coordinates). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astConvex() -f AST_CONVEX = INTEGER -* A pointer to the required Polygon. -c NULL -f AST__NULL -* is returned without error if the array contains no pixels that -* satisfy the criterion specified by -c "value" and "oper". -f VALUE and OPER. - -* Notes: -c - NULL -f - AST__NULL -* will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. - -* Data Type Codes: -* To select the appropriate masking function, you should -c replace in the generic function name astConvex with a -f replace in the generic function name AST_CONVEX with a -* 1- or 2-character data type code, so as to match the numerical -* type of the data you are processing, as follows: -c - D: double -c - F: float -c - L: long int -c - UL: unsigned long int -c - I: int -c - UI: unsigned int -c - S: short int -c - US: unsigned short int -c - B: byte (signed char) -c - UB: unsigned byte (unsigned char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - UI: INTEGER (treated as unsigned) -f - S: INTEGER*2 (short integer) -f - US: INTEGER*2 (short integer, treated as unsigned) -f - B: BYTE (treated as signed) -f - UB: BYTE (treated as unsigned) -* -c For example, astConvexD would be used to process "double" -c data, while astConvexS would be used to process "short int" -c data, etc. -f For example, AST_CONVEXD would be used to process DOUBLE -f PRECISION data, while AST_CONVEXS would be used to process -f short integer data (stored in an INTEGER*2 array), etc. -f -f For compatibility with other Starlink facilities, the codes W -f and UW are provided as synonyms for S and US respectively (but -f only in the Fortran interface to AST). - -*-- -*/ -/* Define a macro to implement the function for a specific data - type. Note, this function cannot be a virtual function since the - argument list does not include a Polygon, and so no virtual function - table is available. */ -#define MAKE_CONVEX(X,Xtype) \ -AstPolygon *astConvex##X##_( Xtype value, int oper, const Xtype array[], \ - const int lbnd[2], const int ubnd[2], \ - int starpix, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *frm; /* Frame in which to define the Polygon */ \ - AstPointSet *candidate; /* Candidate polygon vertices */ \ - AstPolygon *result; /* Result value to return */ \ - int xdim; /* Number of pixels per row */ \ - int ydim; /* Number of rows */ \ - static double junk[ 6 ] = {0.0, 0.0, 1.0, 1.0, 0.0, 1.0 }; /* Junk poly */ \ -\ -/* Initialise. */ \ - result = NULL; \ - candidate = NULL; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Get the array dimensions. */ \ - xdim = ubnd[ 0 ] - lbnd[ 0 ] + 1; \ - ydim = ubnd[ 1 ] - lbnd[ 1 ] + 1; \ -\ -/* Get the basic concvex hull. */ \ - if( oper == AST__LT ) { \ - candidate = ConvexHullLT##X( value, array, lbnd, starpix, xdim, ydim, status ); \ -\ - } else if( oper == AST__LE ) { \ - candidate = ConvexHullLE##X( value, array, lbnd, starpix, xdim, ydim, status ); \ -\ - } else if( oper == AST__EQ ) { \ - candidate = ConvexHullEQ##X( value, array, lbnd, starpix, xdim, ydim, status ); \ -\ - } else if( oper == AST__NE ) { \ - candidate = ConvexHullNE##X( value, array, lbnd, starpix, xdim, ydim, status ); \ -\ - } else if( oper == AST__GE ) { \ - candidate = ConvexHullGE##X( value, array, lbnd, starpix, xdim, ydim, status ); \ -\ - } else if( oper == AST__GT ) { \ - candidate = ConvexHullGT##X( value, array, lbnd, starpix, xdim, ydim, status ); \ -\ - } else if( astOK ){ \ - astError( AST__OPRIN, "astConvex"#X": Invalid operation code " \ - "(%d) supplied (programming error).", status, oper ); \ - } \ -\ -/* Check some good selected values were found. */ \ - if( candidate ) { \ -\ -/* Create a default Polygon with 3 junk vertices. */ \ - frm = astFrame( 2, "Domain=PIXEL,Unit(1)=pixel,Unit(2)=pixel," \ - "Title=Pixel coordinates", status ); \ - result = astPolygon( frm, 3, 3, junk, NULL, " ", status ); \ -\ -/* Change the PointSet within the Polygon to the one created above. */ \ - SetPointSet( result, candidate, status ); \ -\ -/* Free resources. */ \ - frm = astAnnul( frm ); \ - candidate = astAnnul( candidate ); \ - } \ -\ -/* If an error occurred, clear the returned result. */ \ - if ( !astOK ) result = astAnnul( result ); \ -\ -/* Return the result. */ \ - return result; \ -} - - -/* Expand the above macro to generate a function for each required - data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_CONVEX(LD,long double) -#endif -MAKE_CONVEX(D,double) -MAKE_CONVEX(L,long int) -MAKE_CONVEX(UL,unsigned long int) -MAKE_CONVEX(I,int) -MAKE_CONVEX(UI,unsigned int) -MAKE_CONVEX(S,short int) -MAKE_CONVEX(US,unsigned short int) -MAKE_CONVEX(B,signed char) -MAKE_CONVEX(UB,unsigned char) -MAKE_CONVEX(F,float) - -/* Undefine the macros. */ -#undef MAKE_CONVEX - -/* -* Name: -* ConvexHull - -* Purpose: -* Find the convex hull enclosing selected pixels in a 2D array. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* AstPointSet *ConvexHull( value, const array[], -* const int lbnd[2], int starpix, -* int xdim, int ydim, int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* This function uses an algorithm similar to "Andrew's Monotone Chain -* Algorithm" to create a list of vertices describing the convex hull -* enclosing the selected pixels in the supplied array. The vertices -* are returned in a PointSet. - -* Parameters: -* value -* A data value that specifies the pixels to be selected. -* array -* Pointer to a 2-dimensional array containing the data to be -* processed. The numerical type of this array should match the 1- -* or 2-character type code appended to the function name. -* lbnd -* The lower pixel index bounds of the array. -* starpix -* If non-zero, the usual Starlink definition of pixel coordinate -* is used (integral values at pixel corners). Otherwise, the -* system used by other AST functions such as astResample is used -* (integral values at pixel centres). -* xdim -* The number of pixels along each row of the array. -* ydim -* The number of rows in the array. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A PointSet holding the vertices of the convex hull, or NULL if an -* error occurs. - -* Notes: -* - The following code has been designed with a view to it being -* multi-threaded at some point. - -*/ - -/* Define a macro to implement the function for a specific data - type and operation. */ -#define MAKE_CONVEXHULL(X,Xtype,Oper,OperI) \ -static AstPointSet *ConvexHull##Oper##X( Xtype value, const Xtype array[], \ - const int lbnd[2], int starpix, \ - int xdim, int ydim, int *status ) { \ -\ -/* Local Variables: */ \ - AstPointSet *result; \ - double **ptr; \ - double *xv1; \ - double *xv2; \ - double *xv3; \ - double *xv4; \ - double *xvert; \ - double *yv1; \ - double *yv2; \ - double *yv3; \ - double *yv4; \ - double *yvert; \ - int nv1; \ - int nv2; \ - int nv3; \ - int nv4; \ - int nv; \ - int xhi; \ - int xhiymax; \ - int xhiymin; \ - int xlo; \ - int xloymax; \ - int xloymin; \ - int yhi; \ - int yhixmax; \ - int yhixmin; \ - int ylo; \ - int yloxmax; \ - int yloxmin; \ -\ -/* Initialise */ \ - result = NULL; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Find the lowest Y value at any selected pixel, and find the max and \ - min X value of the selected pixels at that lowest Y value. */ \ - FindBoxEdge##Oper##X( value, array, xdim, ydim, 1, 1, &ylo, &yloxmax, \ - &yloxmin, status ); \ -\ -/* Skip if there are no selected values in the array. */ \ - if( ylo > 0 ) { \ -\ -/* Find the highest Y value at any selected pixel, and find the max and \ - min X value of the selected pixels at that highest Y value. */ \ - FindBoxEdge##Oper##X( value, array, xdim, ydim, 1, 0, &yhi, &yhixmax, \ - &yhixmin, status ); \ -\ -/* Find the lowest X value at any selected pixel, and find the max and \ - min Y value of the selected pixels at that lowest X value. */ \ - FindBoxEdge##Oper##X( value, array, xdim, ydim, 0, 1, &xlo, &xloymax, \ - &xloymin, status ); \ -\ -/* Find the highest X value at any selected pixel, and find the max and \ - min Y value of the selected pixels at that highest X value. */ \ - FindBoxEdge##Oper##X( value, array, xdim, ydim, 0, 0, &xhi, &xhiymax, \ - &xhiymin, status ); \ -\ -/* Create a list of vertices for the bottom right corner of the bounding \ - box of the selected pixels. */ \ - PartHull##Oper##X( value, array, xdim, ydim, yloxmax, ylo, xhi, xhiymin, \ - starpix, lbnd, &xv1, &yv1, &nv1, status ); \ -\ -/* Create a list of vertices for the top right corner of the bounding \ - box of the selected pixels. */ \ - PartHull##Oper##X( value, array, xdim, ydim, xhi, xhiymax, yhixmax, yhi, \ - starpix, lbnd, &xv2, &yv2, &nv2, status ); \ -\ -/* Create a list of vertices for the top left corner of the bounding \ - box of the selected pixels. */ \ - PartHull##Oper##X( value, array, xdim, ydim, yhixmin, yhi, xlo, xloymax, \ - starpix, lbnd, &xv3, &yv3, &nv3, status ); \ -\ -/* Create a list of vertices for the bottom left corner of the bounding \ - box of the selected pixels. */ \ - PartHull##Oper##X( value, array, xdim, ydim, xlo, xloymin, yloxmin, ylo, \ - starpix, lbnd, &xv4, &yv4, &nv4, status ); \ -\ -/* Concatenate the four vertex lists and store them in the returned \ - PointSet. */ \ - nv = nv1 + nv2 + nv3 + nv4; \ - result = astPointSet( nv, 2, " ", status ); \ - ptr = astGetPoints( result ); \ - if( astOK ) { \ - xvert = ptr[ 0 ]; \ - yvert = ptr[ 1 ]; \ -\ - memcpy( xvert, xv1, nv1*sizeof( double ) ); \ - memcpy( yvert, yv1, nv1*sizeof( double ) ); \ - xvert += nv1; \ - yvert += nv1; \ -\ - memcpy( xvert, xv2, nv2*sizeof( double ) ); \ - memcpy( yvert, yv2, nv2*sizeof( double ) ); \ - xvert += nv2; \ - yvert += nv2; \ -\ - memcpy( xvert, xv3, nv3*sizeof( double ) ); \ - memcpy( yvert, yv3, nv3*sizeof( double ) ); \ - xvert += nv3; \ - yvert += nv3; \ -\ - memcpy( xvert, xv4, nv4*sizeof( double ) ); \ - memcpy( yvert, yv4, nv4*sizeof( double ) ); \ - } \ -\ -/* Free resources. */ \ - xv1 = astFree( xv1 ); \ - xv2 = astFree( xv2 ); \ - xv3 = astFree( xv3 ); \ - xv4 = astFree( xv4 ); \ - yv1 = astFree( yv1 ); \ - yv2 = astFree( yv2 ); \ - yv3 = astFree( yv3 ); \ - yv4 = astFree( yv4 ); \ - } \ -\ -/* Free the returned PointSet if an error occurred. */ \ - if( result && !astOK ) result = astAnnul( result ); \ -\ -/* Return the result. */ \ - return result; \ -} - -/* Define a macro that uses the above macro to to create implementations - of ConvexHull for all operations. */ -#define MAKEALL_CONVEXHULL(X,Xtype) \ -MAKE_CONVEXHULL(X,Xtype,LT,AST__LT) \ -MAKE_CONVEXHULL(X,Xtype,LE,AST__LE) \ -MAKE_CONVEXHULL(X,Xtype,EQ,AST__EQ) \ -MAKE_CONVEXHULL(X,Xtype,NE,AST__NE) \ -MAKE_CONVEXHULL(X,Xtype,GE,AST__GE) \ -MAKE_CONVEXHULL(X,Xtype,GT,AST__GT) - -/* Expand the above macro to generate a function for each required - data type and operation. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKEALL_CONVEXHULL(LD,long double) -#endif -MAKEALL_CONVEXHULL(D,double) -MAKEALL_CONVEXHULL(L,long int) -MAKEALL_CONVEXHULL(UL,unsigned long int) -MAKEALL_CONVEXHULL(I,int) -MAKEALL_CONVEXHULL(UI,unsigned int) -MAKEALL_CONVEXHULL(S,short int) -MAKEALL_CONVEXHULL(US,unsigned short int) -MAKEALL_CONVEXHULL(B,signed char) -MAKEALL_CONVEXHULL(UB,unsigned char) -MAKEALL_CONVEXHULL(F,float) - -/* Undefine the macros. */ -#undef MAKE_CONVEXHULL -#undef MAKEALL_CONVEXHULL - -static AstPolygon *Downsize( AstPolygon *this, double maxerr, int maxvert, - int *status ) { -/* -*++ -* Name: -c astDownsize -f AST_DOWNSIZE - -* Purpose: -* Reduce the number of vertices in a Polygon. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "polygon.h" -c AstPolygon *astDownsize( AstPolygon *this, double maxerr, int maxvert ) -f RESULT = AST_DOWNSIZE( THIS, MAXERR, MAXVERT, STATUS ) - -* Class Membership: -* Polygon method. - -* Description: -* This function returns a pointer to a new Polygon that contains a -* subset of the vertices in the supplied Polygon. The subset is -* chosen so that the returned Polygon is a good approximation to -* the supplied Polygon, within the limits specified by the supplied -* parameter values. That is, the density of points in the returned -* Polygon is greater at points where the curvature of the boundary of -* the supplied Polygon is greater. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Polygon. -c maxerr -f MAXERR = DOUBLE PRECISION (Given) -* The maximum allowed discrepancy between the supplied and -* returned Polygons, expressed as a geodesic distance within the -* Polygon's coordinate frame. If this is zero or less, the -* returned Polygon will have the number of vertices specified by -c maxvert. -f MAXVERT. -c maxvert -f MAXVERT = INTEGER (Given) -* The maximum allowed number of vertices in the returned Polygon. -* If this is less than 3, the number of vertices in the returned -* Polygon will be the minimum needed to achieve the maximum -* discrepancy specified by -c maxerr. -f MAXERR. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astDownsize() -f AST_DOWNSIZE = INTEGER -* Pointer to the new Polygon. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstFrame *frm; /* Base Frame from the Polygon */ - AstPointSet *pset; /* PointSet holding vertices of downsized polygon */ - AstPolygon *result; /* Returned pointer to new Polygon */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the base Frame of the Polygon. */ - frm = astGetFrame( ((AstRegion *) this)->frameset, AST__BASE ); - -/* Create a PointSet holding the vertices of the downsized polygon. */ - pset = DownsizePoly( ((AstRegion *) this)->points, maxerr, maxvert, - frm, status ); - -/* Take a deep copy of the supplied Polygon. */ - result = astCopy( this ); - -/* Change the PointSet within the result Polygon to the one created above. */ \ - SetPointSet( result, pset, status ); \ - -/* Free resources. */ - frm = astAnnul( frm ); - pset = astAnnul( pset ); - -/* If an error occurred, annul the returned Polygon. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *DownsizePoly( AstPointSet *pset, double maxerr, - int maxvert, AstFrame *frm, int *status ) { -/* -* Name: -* DownsizePoly - -* Purpose: -* Reduce the number of vertices in a Polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* AstPointSet *DownsizePoly( AstPointSet *pset, double maxerr, int maxvert, -* AstFrame *frm, int *status ) - -* Class Membership: -* Polygon member function. - -* Description: -* This function returns a pointer to a new PointSet that contains a -* subset of the vertices in the supplied PointSet. The subset is -* chosen so that the returned polygon is a good approximation to -* the supplied polygon, within the limits specified by the supplied -* parameter values. That is, the density of points in the returned -* polygon is greater at points where the curvature of the boundary of -* the supplied polygon is greater. - -* Parameters: -* pset -* Pointer to the PointSet holding the polygon vertices. -* maxerr -* The maximum allowed discrepancy between the supplied and -* returned Polygons, expressed as a geodesic distance within the -* Polygon's coordinate frame. If this is zero or less, the -* returned Polygon will have the number of vertices specified by -* maxvert. -* maxvert -* The maximum allowed number of vertices in the returned Polygon. -* If this is less than 3, the number of vertices in the returned -* Polygon will be the minimum needed to achieve the maximum -* discrepancy specified by -* maxerr. -* frm -* Pointer to the Frame in which the polygon is defined. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new PointSet. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Returned pointer to new PointSet */ - Segment *head; /* Pointer to new polygon edge with highest error */ - Segment *seg1; /* Pointer to new polygon edge */ - Segment *seg2; /* Pointer to new polygon edge */ - Segment *seg3; /* Pointer to new polygon edge */ - double **ptr; /* Pointer to arrays of axis values */ - double *x; /* Pointer to array of X values for old Polygon */ - double *xnew; /* Pointer to array of X values for new Polygon */ - double *y; /* Pointer to array of Y values for old Polygon */ - double *ynew; /* Pointer to array of Y values for new Polygon */ - double x1; /* Lowest X value at any vertex */ - double x2; /* Highest X value at any vertex */ - double y1; /* Lowest Y value at any vertex */ - double y2; /* Highest Y value at any vertex */ - int *newpoly; /* Holds indices of retained input vertices */ - int i1; /* Index of first vertex added to output polygon */ - int i1x; /* Index of vertex with lowest X */ - int i1y; /* Index of vertex with lowest Y */ - int i2; /* Index of second vertex added to output polygon */ - int i2x; /* Index of vertex with highest X */ - int i2y; /* Index of vertex with highest Y */ - int i3; /* Index of third vertex added to output polygon */ - int iadd; /* Normalised vertex index */ - int iat; /* Index at which to store new vertex index */ - int newlen; /* Number of vertices currently in new Polygon */ - int nv; /* Number of vertices in old Polygon */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the number of vertices in the supplied polygon. */ - nv = astGetNpoint( pset ); - -/* If the maximum error allowed is zero, and the maximum number of - vertices is equal to or greater than the number in the supplied - polygon, just return a deep copy of the supplied PointSet. */ - if( maxerr <= 0.0 && ( maxvert < 3 || maxvert >= nv ) ) { - result = astCopy( pset ); - -/* Otherwise... */ - } else { - -/* Get pointers to the X and Y arrays holding the vertex coordinates in - the supplied polygon. */ - ptr = astGetPoints( pset ); - x = ptr[ 0 ]; - y = ptr[ 1 ]; - -/* Allocate memory for an array to hold the original indices of the vertices - to be used to create the returned Polygon. This array is expanded as - needed. */ - newpoly = astMalloc( 10*sizeof( int ) ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* We first need to decide on three widely spaced vertices which form a - reasonable triangular approximation to the whole polygon. First find - the vertices with the highest and lowest Y values, and the highest and - lowest X values. */ - x1 = DBL_MAX; - x2 = -DBL_MAX; - y1 = DBL_MAX; - y2 = -DBL_MAX; - - i1y = i1x = 0; - i2y = i2x = nv/2; - - for( i3 = 0; i3 < nv; i3++ ) { - if( y[ i3 ] < y1 ) { - y1 = y[ i3 ]; - i1y = i3; - } else if( y[ i3 ] > y2 ) { - y2 = y[ i3 ]; - i2y = i3; - } - - if( x[ i3 ] < x1 ) { - x1 = x[ i3 ]; - i1x = i3; - } else if( x[ i3 ] > x2 ) { - x2 = x[ i3 ]; - i2x = i3; - } - } - -/* Use the axis which spans the greater range. */ - if( y2 - y1 > x2 - x1 ) { - i1 = i1y; - i2 = i2y; - } else { - i1 = i1x; - i2 = i2x; - } - -/* The index with vertex i1 is definitely going to be one of our three - vertices. We are going to use the line from i1 to i2 to choose the two - other vertices to use. Create a structure describing the segment of the - Polygon from the lowest value on the selected axis (X or Y) to the - highest value. As always, the polygons is traversed in an anti-clockwise - direction. */ - seg1 = NewSegment( NULL, i1, i2, nv, status ); - -/* Find the vertex within this segment which is furthest away from the - line on the right hand side (as moving from vertex i1 to vertex i2). */ - FindMax( seg1, frm, x, y, nv, 0, status ); - -/* Likewise, create a structure describing the remained of the Polygon - (i.e. the segment from the highest value on the selected axis to the - lowest value). Then find the vertex within this segment which is - furthest away from the line on the right hand side. */ - seg2 = NewSegment( NULL, i2, i1, nv, status ); - FindMax( seg2, frm, x, y, nv, 0, status ); - -/* Select the segment for which the found vertex is furthest from the - line. */ - if( seg2->error > seg1->error ) { - -/* If the second segment, we will use the vertex that is farthest from - the line as one of our threee vertices. To ensure that movement from - vertex i1 to i2 to i3 is anti-clockwise, we must use this new vertex - as vertex i3, not i2. */ - i3 = seg2->imax; - -/* Create a description of the polygon segment from vertex i1 to i3, and - find the vertex which is furthest to the right of the line joining the - two vertices. We use this as the middle vertex (i2). */ - seg1 = NewSegment( seg1, i1, i3, nv, status ); - FindMax( seg1, frm, x, y, nv, 0, status ); - i2 = seg1->imax; - -/* Do the same if we are choosing the other segment, ordering the - vertices to retain anti-clockwise movement from i1 to i2 to i3. */ - } else { - i2 = seg1->imax; - seg1 = NewSegment( seg1, i2, i1, nv, status ); - FindMax( seg1, frm, x, y, nv, 0, status ); - i3 = seg1->imax; - } - -/* Ensure the vertex indices are in the first cycle. */ - if( i2 >= nv ) i2 -= nv; - if( i3 >= nv ) i3 -= nv; - -/* Create Segment structures to describe each of these three edges. */ - seg1 = NewSegment( seg1, i1, i2, nv, status ); - seg2 = NewSegment( seg2, i2, i3, nv, status ); - seg3 = NewSegment( NULL, i3, i1, nv, status ); - -/* Record these 3 vertices in an array holding the original indices of - the vertices to be used to create the returned Polygon. */ - newpoly[ 0 ] = i1; - newpoly[ 1 ] = i2; - newpoly[ 2 ] = i3; - -/* Indicate the new polygon currently has 3 vertices. */ - newlen = 3; - -/* Search the old vertices between the start and end of segment 3, looking - for the vertex which lies furthest from the line of segment 3. The - residual between this point and the line is stored in the Segment - structure, as is the index of the vertex at which this maximum residual - occurred. */ - FindMax( seg3, frm, x, y, nv, 1, status ); - -/* The "head" variable points to the head of a double linked list of - Segment structures. This list is ordered by residual, so that the - Segment with the maximum residual is at the head, and the Segment - with the minimum residual is at the tail. Initially "seg3" is at the - head. */ - head = seg3; - -/* Search the old vertices between the start and end of segment 1, looking - for the vertex which lies furthest from the line of segment 1. The - residual between this point and the line is stored in the Segment - structure, as is the index of the vertex at which this maximum residual - occurred. */ - FindMax( seg1, frm, x, y, nv, 1, status ); - -/* Insert segment 1 into the linked list of Segments, at a position that - maintains the ordering of the segments by error. Thus the head of the - list will still have the max error. */ - head = AddToChain( head, seg1, status ); - -/* Do the same for segment 2. */ - FindMax( seg2, frm, x, y, nv, 1, status ); - head = AddToChain( head, seg2, status ); - -/* If the maximum allowed number of vertices in the output Polygon is - less than 3, allow any number of vertices up to the number in the - input Polygon (termination will then be determined just by "maxerr"). */ - if( maxvert < 3 ) maxvert = nv; - -/* Loop round adding an extra vertex to the returned Polygon until the - maximum residual between the new and old polygons is no more than - "maxerr". Abort early if the specified maximum number of vertices is - reached. */ - while( head->error > maxerr && newlen < maxvert ) { - -/* The segment at the head of the list has the max error (that is, it is - the segment that departs most from the supplied Polygon). To make the - new polygon a better fit to the old polygon, we add the vertex that is - furthest away from this segment to the new polygon. Remember that a - polygon is cyclic so if the vertex has an index that is greater than the - number of vertices in the old polygon, reduce the index by the number - of vertices in the old polygon. */ - iadd = head->imax; - if( iadd >= nv ) iadd -= nv; - iat = newlen++; - newpoly = astGrow( newpoly, newlen, sizeof( int ) ); - if( !astOK ) break; - newpoly[ iat ] = iadd; - -/* We now split the segment that had the highest error into two segments. - The split occurs at the vertex that had the highest error. */ - seg1 = NewSegment( NULL, head->imax, head->i2, nv, status ); - seg2 = head; - seg2->i2 = head->imax; - -/* We do not know where these two new segments should be in the ordered - linked list, so remove them from the list. */ - head = RemoveFromChain( head, seg1, status ); - head = RemoveFromChain( head, seg2, status ); - -/* Find the vertex that deviates most from the first of these two new - segments, and then add the segment into the list of vertices, using - the maximum deviation to determine the position of the segment within - the list. */ - FindMax( seg1, frm, x, y, nv, 1, status ); - head = AddToChain( head, seg1, status ); - -/* Do the same for the second new segment. */ - FindMax( seg2, frm, x, y, nv, 1, status ); - head = AddToChain( head, seg2, status ); - } - -/* Now we have reached the required accuracy, free resources. */ - while( head ) { - seg1 = head; - head = head->next; - seg1 = astFree( seg1 ); - } - -/* If no vertices have been left out, return a deep copy of the supplied - PointSet. */ - if( newlen == nv ) { - result = astCopy( pset ); - -/* Otherwise, sort the indices of the vertices to be retained so that they - are in the same order as they were in the supplied Polygon. */ - } else if( astOK ){ - qsort( newpoly, newlen, sizeof( int ), IntCmp ); - -/* Create a new PointSet and get pointers to its axis values. */ - result = astPointSet( newlen, 2, " ", status ); - ptr = astGetPoints( result ); - xnew = ptr[ 0 ]; - ynew = ptr[ 1 ]; - -/* Copy the axis values for the retained vertices from the old to the new - PointSet. */ - if( astOK ) { - for( iat = 0; iat < newlen; iat++ ) { - *(xnew++) = x[ newpoly[ iat ] ]; - *(ynew++) = y[ newpoly[ iat ] ]; - } - } - } - } - -/* Free resources. */ - newpoly = astFree( newpoly ); - } - -/* If an error occurred, annul the returned PointSet. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void EnsureInside( AstPolygon *this, int *status ){ -/* -* Name: -* EnsureInside - -* Purpose: -* Ensure the unnegated Polygon represents the inside of the polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void EnsureInside( AstPolygon *this, int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* Reversing the order of the vertices of a Polygon is like negating -* the Polygon. But the parent Region class assumes that an unnegated -* region bounded by closed curves (e.g. boxes, circles, ellipses, etc) -* is bounded. So we need to have a way to ensure that a Polygon also -* follows this convention. So this function reverses the order of the -* vertices in the Polygon, if necessary, to ensure that the unnegated -* Polygon is bounded. - -* Parameters: -* this -* The Polygon. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstRegion *this_region; - double **ptr; - double *p; - double *q; - double tmp; - int bounded; - int i; - int j; - int jmid; - int negated; - int np; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Is the unnegated Polygon unbounded? If so, we need to reverse the - vertices. */ - bounded = astGetBounded( this ); - negated = astGetNegated( this ); - if( ( bounded && negated ) || ( !bounded && !negated ) ) { - this_region = (AstRegion *) this; - -/* Get a pointer to the arrays holding the coordinates at the Polygon - vertices. */ - ptr = astGetPoints( this_region->points ); - -/* Get the number of vertices. */ - np = astGetNpoint( this_region->points ); - -/* Store the index of the last vertex to swap. For odd "np" the central - vertex does not need to be swapped. */ - jmid = np/2; - -/* Loop round the two axes spanned by the Polygon. */ - for( i = 0; i < 2; i++ ) { - -/* Get pointers to the first pair of axis values to be swapped - i.e. the - first and last axis values. */ - p = ptr[ i ]; - q = p + np - 1; - -/* Loop round all pairs of axis values. */ - for( j = 0; j < jmid; j++ ) { - -/* Swap the pair. */ - tmp = *p; - *(p++) = *q; - *(q--) = tmp; - } - } - -/* Invert the value of the "Negated" attribute to cancel out the effect - of the above vertex reversal. */ - astNegate( this ); - -/* Indicate the cached information in the Polygon structure is stale. */ - this->stale = 1; - } -} - -/* -* Name: -* FindBoxEdge - -* Purpose: -* Find an edge of the bounding box containing the selected pixels. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void FindBoxEdge( value, const array[], -* int xdim, int ydim, int axis, int low, -* int *val, int *valmax, int *valmin, -* int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* This function search for an edge of the bounding box containing the -* selected pixels in the supplied array. - -* Parameters: -* value -* A data value that specifies the pixels to be selected. -* array -* Pointer to a 2-dimensional array containing the data to be -* processed. The numerical type of this array should match the 1- -* or 2-character type code appended to the function name. -* xdim -* The number of pixels along each row of the array. -* ydim -* The number of rows in the array. -* axis -* The index (0 or 1) of the pixel axis perpendicular to the edge of the -* bounding box being found. -* low -* If non-zero, the lower edge of the bounding box on the axis -* specified by "axis" is found and returned. Otherwise, the higher -* edge of the bounding box on the axis specified by "axis" is -* found and returned. -* val -* Address of an int in which to return the value on axis "axis" of -* the higher or lower (as specified by "low") edge of the bounding -* box. -* valmax -* Address of an int in which to return the highest value on axis -* "1-axis" of the selected pixels on the returned edge. -* valmin -* Address of an int in which to return the lowest value on axis -* "1-axis" of the selected pixels on the returned edge. -* status -* Pointer to the inherited status variable. - -* Notes; -* - Zero is returned for "*val" if no good values are found, or if -* an error occurs. - -*/ - -/* Define a macro to implement the function for a specific data - type and operation. */ -#define MAKE_FINDBOXEDGE(X,Xtype,Oper,OperI) \ -static void FindBoxEdge##Oper##X( Xtype value, const Xtype array[], int xdim, \ - int ydim, int axis, int low, int *val, \ - int *valmax, int *valmin, int *status ) { \ -\ -/* Local Variables: */ \ - int astep; \ - int bstep; \ - int a0; \ - int a1; \ - int b0; \ - int b1; \ - int inc; \ - int a; \ - int b; \ - const Xtype *pc; \ -\ -/* Initialise. */ \ - *val = 0; \ - *valmin = 0; \ - *valmax = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* If we are finding an edge that is parallel to the X axis... */ \ - if( axis ) { \ -\ -/* Get the vector step between adjacent pixels on the selected axis, and \ - on the other axis. */ \ - astep = xdim; \ - bstep = 1; \ -\ -/* Get the first and last value to check on the selected axis, and the \ - increment between checks. */ \ - if( low ) { \ - a0 = 1; \ - a1 = ydim; \ - inc = 1; \ - } else { \ - a0 = ydim; \ - a1 = 1; \ - inc = -1; \ - } \ -\ -/* The first and last value to check on the other axis. */ \ - b0 = 1; \ - b1 = xdim; \ -\ -/* Do the same if we are finding an edge that is parallel to the Y axis. */ \ - } else { \ - astep = 1; \ - bstep = xdim; \ -\ - if( low ) { \ - a0 = 1; \ - a1 = xdim; \ - inc = 1; \ - } else { \ - a0 = xdim; \ - a1 = 1; \ - inc = -1; \ - } \ -\ - b0 = 1; \ - b1 = ydim; \ - } \ -\ -/* Loop round the axis values. */ \ - a = a0; \ - while( 1 ) { \ -\ -/* Get a pointer to the first value to be checked at this axis value. */ \ - pc = array + (a - 1)*astep + (b0 - 1)*bstep; \ -\ -/* Scan the other axis to find the first and last selected pixel. */ \ - for( b = b0; b <= b1; b++ ) { \ - if( ISVALID(*pc,OperI,value) ) { \ - if( *valmin == 0 ) *valmin = b; \ - *valmax = b; \ - } \ - pc += bstep; \ - } \ -\ -/* If any selected pixels were found, store the axis value and exit. */ \ - if( *valmax ) { \ - *val = a; \ - break; \ - } \ -\ -/* Move on to the next axis value. */ \ - if( a != a1 ) { \ - a += inc; \ - } else { \ - break; \ - } \ -\ - } \ -} - -/* Define a macro that uses the above macro to to create implementations - of FindBoxEdge for all operations. */ -#define MAKEALL_FINDBOXEDGE(X,Xtype) \ -MAKE_FINDBOXEDGE(X,Xtype,LT,AST__LT) \ -MAKE_FINDBOXEDGE(X,Xtype,LE,AST__LE) \ -MAKE_FINDBOXEDGE(X,Xtype,EQ,AST__EQ) \ -MAKE_FINDBOXEDGE(X,Xtype,NE,AST__NE) \ -MAKE_FINDBOXEDGE(X,Xtype,GE,AST__GE) \ -MAKE_FINDBOXEDGE(X,Xtype,GT,AST__GT) - -/* Expand the above macro to generate a function for each required - data type and operation. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKEALL_FINDBOXEDGE(LD,long double) -#endif -MAKEALL_FINDBOXEDGE(D,double) -MAKEALL_FINDBOXEDGE(L,long int) -MAKEALL_FINDBOXEDGE(UL,unsigned long int) -MAKEALL_FINDBOXEDGE(I,int) -MAKEALL_FINDBOXEDGE(UI,unsigned int) -MAKEALL_FINDBOXEDGE(S,short int) -MAKEALL_FINDBOXEDGE(US,unsigned short int) -MAKEALL_FINDBOXEDGE(B,signed char) -MAKEALL_FINDBOXEDGE(UB,unsigned char) -MAKEALL_FINDBOXEDGE(F,float) - -/* Undefine the macros. */ -#undef MAKE_FINDBOXEDGE -#undef MAKEALL_FINDBOXEDGE - -/* -* Name: -* FindInsidePoint - -* Purpose: -* Find a point that is inside the required outline. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void FindInsidePoint( value, const array[], -* const int lbnd[ 2 ], const int ubnd[ 2 ], -* int *inx, int *iny, int *iv, -* int *status ); - -* Class Membership: -* Polygon member function - -* Description: -* The central pixel in the array is checked to see if its value meets -* the requirements implied by and "value". If so, its pixel -* indices and vector index are returned> if not, a spiral search is -* made until such a pixel value is found. - -* Parameters: -* value -* The data value defining valid pixels. -* array -* The data array. -* lbnd -* The lower pixel index bounds of the array. -* ubnd -* The upper pixel index bounds of the array. -* inx -* Pointer to an int in which to return the X pixel index of the -* first point that meets the requirements implied by and -* "value". -* iny -* Pointer to an int in which to return the Y pixel index of the -* first point that meets the requirements implied by and -* "value". -* iv -* Pointer to an int in which to return the vector index of the -* first point that meets the requirements implied by and -* "value". -* status -* Pointer to the inherited status variable. - -* Notes: -* - must be one of LT, LE, EQ, NE, GE, GT. - - -*/ - -/* Define a macro to implement the function for a specific data - type and operation. */ -#define MAKE_FINDINSIDEPOINT(X,Xtype,Oper,OperI) \ -static void FindInsidePoint##Oper##X( Xtype value, const Xtype array[], \ - const int lbnd[ 2 ], const int ubnd[ 2 ], \ - int *inx, int *iny, int *iv, \ - int *status ){ \ -\ -/* Local Variables: */ \ - const Xtype *pv; /* Pointer to next data value to test */ \ - const char *text; /* Pointer to text describing oper */ \ - int cy; /* Central row index */ \ - int iskin; /* Index of spiral layer being searched */ \ - int nskin; /* Number of spiral layers to search */ \ - int nx; /* Pixel per row */ \ - int tmp; /* Temporary storage */ \ - int xhi; /* High X pixel index bound of current skin */ \ - int xlo; /* Low X pixel index bound of current skin */ \ - int yhi; /* High X pixel index bound of current skin */ \ - int ylo; /* Low X pixel index bound of current skin */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Find number of pixels in one row of the array. */ \ - nx = ( ubnd[ 0 ] - lbnd[ 0 ] + 1 ); \ -\ -/* Find the pixel indices of the central pixel */ \ - *inx = ( ubnd[ 0 ] + lbnd[ 0 ] )/2; \ - *iny = ( ubnd[ 1 ] + lbnd[ 1 ] )/2; \ -\ -/* Initialise the vector index and pointer to refer to the central pixel. */ \ - *iv = ( *inx - lbnd[ 0 ] ) + nx*( *iny - lbnd[ 1 ] ) ; \ - pv = array + (*iv); \ -\ -/* Test the pixel value, returning if it is valid. This \ - relies on the compiler optimisation to remove the "if" statements \ - for all but the operation appropriate to the function being defined. */ \ - if( OperI == AST__LT ) { \ - if( *pv < value ) return; \ -\ - } else if( OperI == AST__LE ) { \ - if( *pv <= value ) return; \ -\ - } else if( OperI == AST__EQ ) { \ - if( *pv == value ) return; \ -\ - } else if( OperI == AST__NE ) { \ - if( *pv != value ) return; \ -\ - } else if( OperI == AST__GE ) { \ - if( *pv >= value ) return; \ -\ - } else { \ - if( *pv > value ) return; \ - } \ -\ -/* The central pixel is invalid if we arrive here. So we need to do a \ - spiral search out from the centre looking for a valid pixel. Record \ - the central row index (this is the row at which we jump to the next \ - outer skin when doing the spiral search below). */ \ - cy = *iny; \ -\ -/* Find how many skins can be searched as part of the spiral search \ - before the edge of the array is encountered. */ \ - nskin = ubnd[ 0 ] - *inx; \ - tmp = *inx - lbnd[ 0 ]; \ - if( tmp < nskin ) nskin = tmp; \ - tmp = ubnd[ 1 ] - *iny; \ - if( tmp < nskin ) nskin = tmp; \ - tmp = *iny - lbnd[ 1 ]; \ - if( tmp < nskin ) nskin = tmp; \ -\ -/* Initialise the skin box bounds to be just the central pixel. */ \ - xlo = xhi = *inx; \ - ylo = yhi = *iny; \ -\ -/* Loop round each skin looking for a valid test pixel. */ \ - for( iskin = 0; iskin < nskin; iskin++ ) { \ -\ -/* Increment the upper and lower bounds of the box forming the next \ - skin. */ \ - xhi++; \ - xlo--; \ - yhi++; \ - ylo--; \ -\ -/* Initialise things for the first pixel in the new skin by moving one \ - pixel to the right. */ \ - pv++; \ - (*iv)++; \ - (*inx)++; \ -\ -/* Move up the right hand edge of the box corresponding to the current \ - skin. We start at the middle of the right hand edge. */ \ - for( *iny = cy; *iny <= yhi; (*iny)++ ) { \ -\ -/* Test the pixel value, returning if it is valid. This relies on the \ - compiler optimisation to remove the "if" statements for all but the \ - operation appropriate to the function being defined. */ \ - if( OperI == AST__LT ) { \ - if( *pv < value ) return; \ -\ - } else if( OperI == AST__LE ) { \ - if( *pv <= value ) return; \ -\ - } else if( OperI == AST__EQ ) { \ - if( *pv == value ) return; \ -\ - } else if( OperI == AST__NE ) { \ - if( *pv != value ) return; \ -\ - } else if( OperI == AST__GE ) { \ - if( *pv >= value ) return; \ -\ - } else { \ - if( *pv > value ) return; \ - } \ -\ -/* Move up a pixel. */ \ - pv += nx; \ - *iv += nx; \ - } \ -\ -/* Move down a pixel so that *iny == yhi. */ \ - pv -= nx; \ - *iv -= nx; \ - (*iny)--; \ -\ -/* Move left along the top edge of the box corresponding to the current \ - skin. */ \ - for( *inx = xhi; *inx >= xlo; (*inx)-- ) { \ -\ -/* Test the pixel value, returning if it is valid. */ \ - if( OperI == AST__LT ) { \ - if( *pv < value ) return; \ -\ - } else if( OperI == AST__LE ) { \ - if( *pv <= value ) return; \ -\ - } else if( OperI == AST__EQ ) { \ - if( *pv == value ) return; \ -\ - } else if( OperI == AST__NE ) { \ - if( *pv != value ) return; \ -\ - } else if( OperI == AST__GE ) { \ - if( *pv >= value ) return; \ -\ - } else { \ - if( *pv > value ) return; \ - } \ -\ -/* Move left a pixel. */ \ - pv--; \ - (*iv)--; \ - } \ -\ -/* Move right a pixel so that *inx == xlo. */ \ - pv++; \ - (*iv)++; \ - (*inx)++; \ -\ -/* Move down along the left hand edge of the box corresponding to the current \ - skin. */ \ - for( *iny = yhi; *iny >= ylo; (*iny)-- ) { \ -\ -/* Test the pixel value, returning if it is valid. */ \ - if( OperI == AST__LT ) { \ - if( *pv < value ) return; \ -\ - } else if( OperI == AST__LE ) { \ - if( *pv <= value ) return; \ -\ - } else if( OperI == AST__EQ ) { \ - if( *pv == value ) return; \ -\ - } else if( OperI == AST__NE ) { \ - if( *pv != value ) return; \ -\ - } else if( OperI == AST__GE ) { \ - if( *pv >= value ) return; \ -\ - } else { \ - if( *pv > value ) return; \ - } \ -\ -/* Move down a pixel. */ \ - pv -= nx; \ - *iv -= nx; \ - } \ -\ -/* Move up a pixel so that *iny == ylo. */ \ - pv += nx; \ - *iv += nx; \ - (*iny)++; \ -\ -/* Move right along the bottom edge of the box corresponding to the current \ - skin. */ \ - for( *inx = xlo; *inx <= xhi; (*inx)++ ) { \ -\ -/* Test the pixel value, returning if it is valid. */ \ - if( OperI == AST__LT ) { \ - if( *pv < value ) return; \ -\ - } else if( OperI == AST__LE ) { \ - if( *pv <= value ) return; \ -\ - } else if( OperI == AST__EQ ) { \ - if( *pv == value ) return; \ -\ - } else if( OperI == AST__NE ) { \ - if( *pv != value ) return; \ -\ - } else if( OperI == AST__GE ) { \ - if( *pv >= value ) return; \ -\ - } else { \ - if( *pv > value ) return; \ - } \ -\ -/* Move right a pixel. */ \ - pv++; \ - (*iv)++; \ - } \ -\ -/* Move left a pixel so that *inx == xhi. */ \ - pv--; \ - (*iv)--; \ - (*inx)--; \ -\ -/* Move up the right hand edge of the box correspionding to the current \ - skin. We stop just below the middle of the right hand edge. */ \ - for( *iny = ylo; *iny < cy; (*iny)++ ) { \ -\ -/* Test the pixel value, returning if it is valid. This relies on the \ - compiler optimisation to remove the "if" statements for all but the \ - operation appropriate to the function being defined. */ \ - if( OperI == AST__LT ) { \ - if( *pv < value ) return; \ -\ - } else if( OperI == AST__LE ) { \ - if( *pv <= value ) return; \ -\ - } else if( OperI == AST__EQ ) { \ - if( *pv == value ) return; \ -\ - } else if( OperI == AST__NE ) { \ - if( *pv != value ) return; \ -\ - } else if( OperI == AST__GE ) { \ - if( *pv >= value ) return; \ -\ - } else { \ - if( *pv > value ) return; \ - } \ -\ -/* Move up a pixel. */ \ - pv += nx; \ - *iv += nx; \ - } \ - } \ -\ -/* Report an error if no inside pooint could be found. */ \ - if( OperI == AST__LT ) { \ - text = "less than"; \ - } else if( OperI == AST__LE ) { \ - text = "less than or equal to"; \ - } else if( OperI == AST__EQ ) { \ - text = "equal to"; \ - } else if( OperI == AST__NE ) { \ - text = "not equal to"; \ - } else if( OperI == AST__GE ) { \ - text = "greater than or equal to"; \ - } else { \ - text = "greater than"; \ - } \ - astError( AST__NONIN, "astOutline"#X": Could not find a pixel value %s " \ - "%g in the supplied array.", status, text, (double) value ); \ -} - -/* Define a macro that uses the above macro to to create implementations - of FindInsidePoint for all operations. */ -#define MAKEALL_FINDINSIDEPOINT(X,Xtype) \ -MAKE_FINDINSIDEPOINT(X,Xtype,LT,AST__LT) \ -MAKE_FINDINSIDEPOINT(X,Xtype,LE,AST__LE) \ -MAKE_FINDINSIDEPOINT(X,Xtype,EQ,AST__EQ) \ -MAKE_FINDINSIDEPOINT(X,Xtype,GE,AST__GE) \ -MAKE_FINDINSIDEPOINT(X,Xtype,GT,AST__GT) \ -MAKE_FINDINSIDEPOINT(X,Xtype,NE,AST__NE) - -/* Expand the above macro to generate a function for each required - data type and operation. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKEALL_FINDINSIDEPOINT(LD,long double) -#endif -MAKEALL_FINDINSIDEPOINT(D,double) -MAKEALL_FINDINSIDEPOINT(L,long int) -MAKEALL_FINDINSIDEPOINT(UL,unsigned long int) -MAKEALL_FINDINSIDEPOINT(I,int) -MAKEALL_FINDINSIDEPOINT(UI,unsigned int) -MAKEALL_FINDINSIDEPOINT(S,short int) -MAKEALL_FINDINSIDEPOINT(US,unsigned short int) -MAKEALL_FINDINSIDEPOINT(B,signed char) -MAKEALL_FINDINSIDEPOINT(UB,unsigned char) -MAKEALL_FINDINSIDEPOINT(F,float) - -/* Undefine the macros. */ -#undef MAKE_FINDINSIDEPOINT -#undef MAKEALL_FINDINSIDEPOINT - -static void FindMax( Segment *seg, AstFrame *frm, double *x, double *y, - int nv, int abs, int *status ){ -/* -* Name: -* FindMax - -* Purpose: -* Find the maximum discrepancy between a given line segment and the -* Polygon being downsized. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void FindMax( Segment *seg, AstFrame *frm, double *x, double *y, -* int nv, int abs, int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* The supplied Segment structure describes a range of vertices in -* the polygon being downsized. This function checks each of these -* vertices to find the one that lies furthest from the line joining the -* first and last vertices in the segment. The maximum error, and the -* vertex index at which this maximum error is found, is stored in the -* Segment structure. - -* Parameters: -* seg -* The structure describing the range of vertices to check. It -* corresponds to a candidate edge in the downsized polygon. -* frm -* The Frame in which the positions are defined. -* x -* Pointer to the X axis values in the original Polygon. -* y -* Pointer to the Y axis values in the original Polygon. -* nv -* Total number of vertics in the old Polygon.. -* abs -* If non-zero, then the stored maximum is the position with -* maximum absolute error. Otherwise, the stored maximum is the -* position with maximum positive error (positive errors are to the -* right when travelling from start to end of the segment). -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* PointSet holding vertex positions */ - AstPointSet *pset2; /* PointSet holding offset par/perp components */ - double **ptr1; /* Pointers to "pset1" data arrays */ - double **ptr2; /* Pointers to "pset2" data arrays */ - double *px; /* Pointer to next X value */ - double *py; /* Pointer to next Y value */ - double ax; /* X value at start */ - double ay; /* Y value at start */ - double ba; /* Distance between a and b */ - double bax; /* X increment from a to b */ - double bay; /* Y increment from a to b */ - double cax; /* X increment from a to c */ - double cay; /* Y increment from a to c */ - double end[ 2 ]; /* Position of starting vertex */ - double error; /* Error value for current vertex */ - double start[ 2 ]; /* Position of starting vertex */ - int i1; /* Starting index (always in first cycle) */ - int i2; /* Ending index converted to first cycle */ - int i2b; /* Upper vertex limit in first cycle */ - int i; /* Loop count */ - int n; /* Number of vertices to check */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Stuff needed for handling cyclic redundancy of vertex indices. */ - i1 = seg->i1; - i2 = seg->i2; - n = i2 - i1 - 1; - i2b = i2; - if( i2 >= nv ) { - i2 -= nv; - i2b = nv; - } - -/* If the segment has no intermediate vertices, set the segment error to - zero and return. */ - if( n < 1 ) { - seg->error = 0.0; - seg->imax = i1; - -/* For speed, we use simple plane geometry if the Polygon is defined in a - simple Frame. */ - } else if( !strcmp( astGetClass( frm ), "Frame" ) ) { - -/* Point "a" is the vertex that marks the start of the segment. Point "b" - is the vertex that marks the end of the segment. */ - ax = x[ i1 ]; - ay = y[ i1 ]; - bax = x[ i2 ] - ax; - bay = y[ i2 ] - ay; - ba = sqrt( bax*bax + bay*bay ); - -/* Initialise the largest error found so far. */ - seg->error = -1.0; - -/* Check the vertices from the start (plus one) up to the end (minus one) - or the last vertex (which ever comes first). */ - for( i = i1 + 1; i < i2b; i++ ) { - -/* Position "c" is the vertex being tested. Find the squared distance from - "c" to the line joining "a" and "b". */ - cax = x[ i ] - ax; - cay = y[ i ] - ay; - error = ( bay*cax - cay*bax )/ba; - if( abs ) error = fabs( error ); - -/* If this is the largest value found so far, record it. Note the error - here is a squared distance. */ - if( error > seg->error ) { - seg->error = error; - seg->imax = i; - } - } - -/* If the end vertex is in the next cycle, check the remaining vertex - posI would have thought a telentitions in the same way. */ - if( i2b != i2 ) { - - for( i = 0; i < i2; i++ ) { - - cax = x[ i ] - ax; - cay = y[ i ] - ay; - error = ( bay*cax - cay*bax )/ba; - if( abs ) error = fabs( error ); - - if( error > seg->error ) { - seg->error = error; - seg->imax = i + i2b; - } - - } - } - -/* If the polygon is not defined in a simple Frame, we use the overloaded - Frame methods to do the geometry. */ - } else { - -/* Create a PointSet to hold the positions of the vertices to test. We do - not need to test the start or end vertex. */ - pset1 = astPointSet( n, 2, " ", status ); - ptr1 = astGetPoints( pset1 ); - if( astOK ) { - -/* Copy the vertex axis values form the start (plus one) up to the end - (minus one) vertex or the last vertex (which ever comes first). */ - px = ptr1[ 0 ]; - py = ptr1[ 1 ]; - - for( i = i1 + 1; i < i2b; i++ ){ - *(px++) = x[ i ]; - *(py++) = y[ i ]; - } - -/* If the end vertex is in the next cycle, copy the remaining vertex - positions into the PointSet. */ - if( i2b != i2 ) { - for( i = 0; i < i2; i++ ) { - *(px++) = x[ i ]; - *(py++) = y[ i ]; - } - } - -/* Record the start and end vertex positions. */ - start[ 0 ] = x[ i1 ]; - start[ 1 ] = y[ i1 ]; - end[ 0 ] = x[ i2 ]; - end[ 1 ] = y[ i2 ]; - -/* Resolve the vector from the start to each vertex into two components, - parallel and perpendicular to the start->end vector. */ - pset2 = astResolvePoints( frm, start, end, pset1, NULL ); - ptr2 = astGetPoints( pset2 ); - if( astOK ) { - -/* Find the vertex with largest perpendicular component. */ - seg->error = -1.0; - py = ptr2[ 1 ]; - for( i = 1; i <= n; i++ ) { - - error = *(py++); - if( abs ) error = fabs( error ); - - if( error > seg->error ) { - seg->error = error; - seg->imax = i + i1; - } - - } - } - -/* Free resources. */ - pset2 = astAnnul( pset2 ); - } - pset1 = astAnnul( pset1 ); - } -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Polygon member function (over-rides the protected astGetAttrib -* method inherited from the Region class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Polygon, formatted as a character string. - -* Parameters: -* this -* Pointer to the Polygon. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Polygon, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Polygon. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPolygon *this; /* Pointer to the Polygon structure */ - const char *result; /* Pointer value to return */ - int ival; /* Integer attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Polygon structure. */ - this = (AstPolygon *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* SimpVertices. */ -/* ------------- */ - if ( !strcmp( attrib, "simpvertices" ) ) { - ival = astGetSimpVertices( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; - -} - -static int GetBounded( AstRegion *this, int *status ) { -/* -* Name: -* GetBounded - -* Purpose: -* Is the Region bounded? - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* int GetBounded( AstRegion *this, int *status ) - -* Class Membership: -* Polygon method (over-rides the astGetBounded method inherited from -* the Region class). - -* Description: -* This function returns a flag indicating if the Region is bounded. -* The implementation provided by the base Region class is suitable -* for Region sub-classes representing the inside of a single closed -* curve (e.g. Circle, Interval, Box, etc). Other sub-classes (such as -* CmpRegion, PointList, etc ) may need to provide their own -* implementations. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Region is bounded. Zero otherwise. - -*/ - -/* Local Variables: */ - int neg; /* Has the Polygon been negated? */ - int result; /* Returned result */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Ensure cached information is available. */ - Cache( (AstPolygon *) this, status ); - -/* See if the Polygon has been negated. */ - neg = astGetNegated( this ); - -/* If the polygon vertices are stored in anti-clockwise order, then the - polygon is bounded if it has not been negated. */ - if( ( (AstPolygon *) this)->acw ) { - result = (! neg ); - -/* If the polygon vertices are stored in clockwise order, then the - polygon is bounded if it has been negated. */ - } else { - result = neg; - } - -/* Return the result. */ - return result; -} - -void astInitPolygonVtab_( AstPolygonVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitPolygonVtab - -* Purpose: -* Initialise a virtual function table for a Polygon. - -* Type: -* Protected function. - -* Synopsis: -* #include "polygon.h" -* void astInitPolygonVtab( AstPolygonVtab *vtab, const char *name ) - -* Class Membership: -* Polygon vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Polygon class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAPolygon) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->Downsize = Downsize; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - - parent_setregfs = region->SetRegFS; - region->SetRegFS = SetRegFS; - - parent_resetcache = region->ResetCache; - region->ResetCache = ResetCache; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - region->RegPins = RegPins; - region->RegBaseMesh = RegBaseMesh; - region->RegBaseBox = RegBaseBox; - region->RegTrace = RegTrace; - region->GetBounded = GetBounded; - - vtab->ClearSimpVertices = ClearSimpVertices; - vtab->GetSimpVertices = GetSimpVertices; - vtab->SetSimpVertices = SetSimpVertices; - vtab->TestSimpVertices = TestSimpVertices; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDump( vtab, Dump, "Polygon", "Polygonal region" ); - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int IntCmp( const void *a, const void *b ){ -/* -* Name: -* IntCmp - -* Purpose: -* An integer comparison function for the "qsort" function. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* int IntCmp( const void *a, const void *b ) - -* Class Membership: -* Polygon member function - -* Description: -* See the docs for "qsort". - -* Parameters: -* a -* Pointer to the first int -* b -* Pointer to the second int - -* Returnd Value: -* Positive, negative or zero, depending on whether a is larger than, -* equal to, or less than b. - -*/ - - return *((int*)a) - *((int*)b); -} - -static Segment *NewSegment( Segment *seg, int i1, int i2, int nvert, - int *status ){ -/* -* Name: -* NewSegment - -* Purpose: -* Initialise a structure describing a segment of the new Polygon -* created by astDownsize. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* Segment *NewSegment( Segment *seg, int i1, int i2, int nvert, -* int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* This function initialises the contents of a structure describing -* the specified range of vertices within a Polygon. The cyclic nature -* of vertex indices is taken into account. -* -* If no structure is supplied, memory is allocated to hold a new -* structure. - -* Parameters: -* seg -* Pointer to a structure to initialise, or NULL if a new structure -* is to be allocated. -* i1 -* The index of a vertex within the old Polygon (supplied to -* astDownsize) that marks the start of the new line segment in -* the downsized polygon. -* i2 -* The index of a vertex within the old Polygon (supplied to -* astDownsize) that marks the end of the new line segment in -* the downsized polygon. -* nvert -* Total number of vertics in the old Polygon.. -* status -* Pointer to the inherited status variable. - -* Returnd Value: -* Pointer to the initialised Segment structure. It should be freed using -* astFree when no longer needed. - -*/ - -/* Local Variables: */ - Segment *result; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure to be initialised, allocating memory - for a new structure if none was supplied. */ - result = seg ? seg : astMalloc( sizeof( Segment ) ); - -/* Check the pointer can be used safely. */ - if( result ) { - -/* If the supplied ending index is less than the starting index, the - ending index must have gone all the way round the polygon and started - round again. Increase the ending index by the number of vertices to - put it in the same cycle as the starting index. */ - if( i2 < i1 ) i2 += nvert; - -/* If the supplied starting index is within the first cycle (i.e. zero -> - nvert-1 ), use the indices as they are (which may mean that the ending - index is greater than nvert, but this is handled correctly by other - functions). */ - if( i1 < nvert ) { - result->i1 = i1; - result->i2 = i2; - -/* If the supplied starting index is within the second cycle (i.e. nvert - or greater) the ending index will be even greater, so we can reduce - both by "nvert" to put them both in the first cycle. The goal is that - the starting index should always be in the first cycle, but the ending - index may possibly be in the second cycle. */ - } else { - result->i1 = i1 - nvert; - result->i2 = i2 - nvert; - } - -/* Nullify the links to other Segments */ - result->next = NULL; - result->prev = NULL; - } - -/* Return the pointer to the new Segment structure. */ - return result; -} - -/* -*++ -* Name: -c astOutline -f AST_OUTLINE - -* Purpose: -* Create a new Polygon outling values in a 2D data grid. - -* Type: -* Public function. - -* Synopsis: -c #include "polygon.h" -c AstPolygon *astOutline( value, int oper, const array[], -c const int lbnd[2], const int ubnd[2], double maxerr, -c int maxvert, const int inside[2], int starpix ) -f RESULT = AST_OUTLINE( VALUE, OPER, ARRAY, LBND, UBND, MAXERR, -f MAXVERT, INSIDE, STARPIX, STATUS ) - -* Class Membership: -* Polygon method. - -* Description: -* This is a set of functions that create a Polygon enclosing a single -* contiguous set of pixels that have a specified value within a gridded -* 2-dimensional data array (e.g. an image). -* -* A basic 2-dimensional Frame is used to represent the pixel coordinate -* system in the returned Polygon. The Domain attribute is set to -* "PIXEL", the Title attribute is set to "Pixel coordinates", and the -* Unit attribute for each axis is set to "pixel". All other -* attributes are left unset. The nature of the pixel coordinate system -* is determined by parameter -c "starpix". -f STARPIX. -* -* The -c "maxerr" and "maxvert" -f MAXERR and MAXVERT -* parameters can be used to control how accurately the returned -* Polygon represents the required region in the data array. The -* number of vertices in the returned Polygon will be the minimum -* needed to achieve the required accuracy. -* -* You should use a function which matches the numerical type of the -* data you are processing by replacing in the generic function -* name -c astOutline -f AST_OUTLINE -c by an appropriate 1- or 2-character type code. For example, if you -* are procesing data with type -c "float", you should use the function astOutlineF -f REAL, you should use the function AST_OUTLINER -* (see the "Data Type Codes" section below for the codes appropriate to -* other numerical types). - -* Parameters: -c value -f VALUE = (Given) -* A data value that specifies the pixels to be outlined. -c oper -f OPER = INTEGER (Given) -* Indicates how the -c "value" -f VALUE -* parameter is used to select the outlined pixels. It can -* have any of the following values: -c - AST__LT: outline pixels with value less than "value". -c - AST__LE: outline pixels with value less than or equal to "value". -c - AST__EQ: outline pixels with value equal to "value". -c - AST__NE: outline pixels with value not equal to "value". -c - AST__GE: outline pixels with value greater than or equal to "value". -c - AST__GT: outline pixels with value greater than "value". -f - AST__LT: outline pixels with value less than VALUE. -f - AST__LE: outline pixels with value less than or equal to VALUE. -f - AST__EQ: outline pixels with value equal to VALUE. -f - AST__NE: outline pixels with value not equal to VALUE. -f - AST__GE: outline pixels with value greater than or equal to VALUE. -f - AST__GT: outline pixels with value greater than VALUE. -c array -f ARRAY( * ) = (Given) -c Pointer to a -f A -* 2-dimensional array containing the data to be processed. The -* numerical type of this array should match the 1- or -* 2-character type code appended to the function name (e.g. if -c you are using astOutlineF, the type of each array element -c should be "float"). -f you are using AST_OUTLINER, the type of each array element -f should be REAL). -* -* The storage order of data within this array should be such -* that the index of the first grid dimension varies most -* rapidly and that of the second dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -c lbnd -f LBND( 2 ) = INTEGER (Given) -c Pointer to an array of two integers -f An array -* containing the pixel index of the first pixel in the input grid -* along each dimension. -c ubnd -f UBND( 2) = INTEGER (Given) -c Pointer to an array of two integers -f An array -* containing the pixel index of the last pixel in the input grid -* along each dimension. -* -c Note that "lbnd" and "ubnd" together define the shape -f Note that LBND and UBND together define the shape -* and size of the input pixel grid, its extent along a particular -c (j'th) dimension being ubnd[j]-lbnd[j]+1 pixels. -f (J'th) dimension being UBND(J)-LBND(J)+1 pixels. -* For FITS images, -c the lbnd values will be 1 and the ubnd -f the LBND values will be 1 and the UBND -* values will be equal to the NAXISi header values. Other -* data systems, such as the Starlink NDF system, allow an -c arbitrary pixel origin to be used (i.e. lbnd -f arbitrary pixel origin to be used (i.e. LBND -* is not necessarily 1). -* -* These bounds also define the input grid's floating point coordinate -* system, each pixel having unit extent along each dimension with -* integral coordinate values at its centre or upper corner, as selected -* by parameter -c "starpix". -f STARPIX. -c maxerr -f MAXERR = DOUBLE PRECISION (Given) -* Together with -c "maxvert", -f MAXVERT, -* this determines how accurately the returned Polygon represents -* the required region of the data array. It gives the target -* discrepancy between the returned Polygon and the accurate outline -* in the data array, expressed as a number of pixels. Insignificant -* vertices are removed from the accurate outline, one by one, until -* the number of vertices remaining in the returned Polygon equals -c "maxvert", -f MAXVERT, -* or the largest discrepancy between the accurate outline and the -* returned Polygon is greater than -c "maxerr". If "maxerr" -f MAXERR. If MAXERR -* is zero or less, its value is ignored and the returned Polygon will -* have the number of vertices specified by -c "maxvert". -f MAXVERT. -c maxvert -f MAXVERT = INTEGER (Given) -* Together with -c "maxerr", -f MAXERR, -* this determines how accurately the returned Polygon represents -* the required region of the data array. It gives the maximum -* allowed number of vertices in the returned Polygon. Insignificant -* vertices are removed from the accurate outline, one by one, until -* the number of vertices remaining in the returned Polygon equals -c "maxvert", -f MAXVERT, -* or the largest discrepancy between the accurate outline and the -* returned Polygon is greater than -c "maxerr". If "maxvert" -f MAXERR. If MAXVERT -* is less than 3, its value is ignored and the number of vertices in -* the returned Polygon will be the minimum needed to ensure that the -* discrepancy between the accurate outline and the returned -* Polygon is less than -c "maxerr". -f MAXERR. -c inside -f INSIDE( 2 ) = INTEGER (Given) -c Pointer to an array of two integers -f An array -* containing the pixel indices of a pixel known to be inside the -* required region. This is needed because the supplied data -* array may contain several disjoint areas of pixels that satisfy -* the criterion specified by -c "value" and "oper". -f VALUE and OPER. -* In such cases, the area described by the returned Polygon will -* be the one that contains the pixel specified by -c "inside". -f INSIDE. -* If the specified pixel is outside the bounds given by -c "lbnd" and "ubnd", -f LBND and UBND, -* or has a value that does not meet the criterion specified by -c "value" and "oper", -f VALUE and OPER, -* then this function will search for a suitable pixel. The search -* starts at the central pixel and proceeds in a spiral manner until -* a pixel is found that meets the specified crierion. -c starpix -f STARPIX = LOGICAL (Given) -* A flag indicating the nature of the pixel coordinate system used -* to describe the vertex positions in the returned Polygon. If -c non-zero, -f .TRUE., -* the standard Starlink definition of pixel coordinate is used in -* which a pixel with integer index I spans a range of pixel coordinate -* from (I-1) to I (i.e. pixel corners have integral pixel coordinates). -c If zero, -f If .FALSE., -* the definition of pixel coordinate used by other AST functions -c such as astResample, astMask, -f such as AST_RESAMPLE, AST_MASK, -* etc., is used. In this definition, a pixel with integer index I -* spans a range of pixel coordinate from (I-0.5) to (I+0.5) (i.e. -* pixel centres have integral pixel coordinates). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astOutline() -f AST_OUTLINE = INTEGER -* A pointer to the required Polygon. - -* Notes: -* - This function proceeds by first finding a very accurate polygon, -* and then removing insignificant vertices from this fine polygon -* using -c astDownsize. -f AST_DOWNSIZE. -* - The returned Polygon is the outer boundary of the contiguous set -* of pixels that includes ths specified "inside" point, and satisfy -* the specified value requirement. This set of pixels may potentially -* include "holes" where the pixel values fail to meet the specified -* value requirement. Such holes will be ignored by this function. -c - NULL -f - AST__NULL -* will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. - -* Data Type Codes: -* To select the appropriate masking function, you should -c replace in the generic function name astOutline with a -f replace in the generic function name AST_OUTLINE with a -* 1- or 2-character data type code, so as to match the numerical -* type of the data you are processing, as follows: -c - D: double -c - F: float -c - L: long int -c - UL: unsigned long int -c - I: int -c - UI: unsigned int -c - S: short int -c - US: unsigned short int -c - B: byte (signed char) -c - UB: unsigned byte (unsigned char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - UI: INTEGER (treated as unsigned) -f - S: INTEGER*2 (short integer) -f - US: INTEGER*2 (short integer, treated as unsigned) -f - B: BYTE (treated as signed) -f - UB: BYTE (treated as unsigned) -* -c For example, astOutlineD would be used to process "double" -c data, while astOutlineS would be used to process "short int" -c data, etc. -f For example, AST_OUTLINED would be used to process DOUBLE -f PRECISION data, while AST_OUTLINES would be used to process -f short integer data (stored in an INTEGER*2 array), etc. -f -f For compatibility with other Starlink facilities, the codes W -f and UW are provided as synonyms for S and US respectively (but -f only in the Fortran interface to AST). - -*-- -*/ -/* Define a macro to implement the function for a specific data - type. Note, this function cannot be a virtual function since the - argument list does not include a Polygon, and so no virtual function - table is available. */ -#define MAKE_OUTLINE(X,Xtype) \ -AstPolygon *astOutline##X##_( Xtype value, int oper, const Xtype array[], \ - const int lbnd[2], const int ubnd[2], double maxerr, \ - int maxvert, const int inside[2], int starpix, \ - int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *frm; /* Frame in which to define the Polygon */ \ - AstPointSet *candidate; /* Candidate polygon vertices */ \ - AstPointSet *pset; /* PointSet holding downsized polygon vertices */ \ - AstPolygon *result; /* Result value to return */ \ - const Xtype *pv; /* Pointer to next test point */ \ - Xtype v; /* Value of current pixel */ \ - double **ptr; /* Pointers to PointSet arrays */ \ - int boxsize; /* Half width of smoothign box in vertices */ \ - int inx; /* X index of inside point */ \ - int iny; /* Y index of inside point */ \ - int iv; /* Vector index of next test pixel */ \ - int ixv; /* X pixel index of next test point */ \ - int nv0; /* Number of vertices in accurate outline */ \ - int nx; /* Length of array x axis */ \ - int smooth; /* Do we need to smooth the polygon? */ \ - int stop_at_invalid; /* Indicates when to stop rightwards search */ \ - int tmp; /* Alternative boxsize */ \ - int valid; /* Does current pixel meet requirements? */ \ - static double junk[ 6 ] = {0.0, 0.0, 1.0, 1.0, 0.0, 1.0 }; /* Junk poly */ \ -\ -/* Initialise. */ \ - result = NULL; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Avoid compiler warnings. */ \ - iv = 0; \ -\ -/* If we are going to be smoothing the polygon before downsizing it, we \ - need to ensure that the full polygon is retained within TraceEdge. if \ - this is not the case, TraceEdge can remove all vertices from straight \ - lines, except for the vertices that mark the beinning and end of the \ - straight line. */ \ - smooth = ( maxerr > 0.0 || maxvert > 2 ); \ -\ -/* Store the X dimension of the array. */ \ - nx = ubnd[ 0 ] - lbnd[ 0 ] + 1; \ -\ -/* See if a valid inside point was supplied. It must be inside the bounds \ - of the array, and must have a pixel value that meets the specified \ - requirement. */ \ - inx = inside[ 0 ]; \ - iny = inside[ 1 ]; \ - valid = ( inx >= lbnd[ 0 ] && inx <= ubnd[ 0 ] && \ - iny >= lbnd[ 1 ] && iny <= ubnd[ 1 ] ); \ -\ - if( valid ) { \ - iv = ( inx - lbnd[ 0 ] ) + (iny - lbnd[ 1 ] )*nx; \ - v = array[ iv ]; \ -\ - if( oper == AST__LT ) { \ - valid = ( v < value ); \ -\ - } else if( oper == AST__LE ) { \ - valid = ( v <= value ); \ -\ - } else if( oper == AST__EQ ) { \ - valid = ( v == value ); \ -\ - } else if( oper == AST__NE ) { \ - valid = ( v != value ); \ -\ - } else if( oper == AST__GE ) { \ - valid = ( v >= value ); \ -\ - } else if( oper == AST__GT ) { \ - valid = ( v > value ); \ -\ - } else if( astOK ){ \ - astError( AST__OPRIN, "astOutline"#X": Invalid operation code " \ - "(%d) supplied (programming error).", status, oper ); \ - } \ - } \ -\ -/* If no valid inside point was supplied, find one now. */ \ - if( !valid ) { \ -\ - if( oper == AST__LT ) { \ - FindInsidePointLT##X( value, array, lbnd, ubnd, &inx, &iny, &iv, status ); \ -\ - } else if( oper == AST__LE ) { \ - FindInsidePointLE##X( value, array, lbnd, ubnd, &inx, &iny, &iv, status ); \ -\ - } else if( oper == AST__EQ ) { \ - FindInsidePointEQ##X( value, array, lbnd, ubnd, &inx, &iny, &iv, status ); \ -\ - } else if( oper == AST__NE ) { \ - FindInsidePointNE##X( value, array, lbnd, ubnd, &inx, &iny, &iv, status ); \ -\ - } else if( oper == AST__GE ) { \ - FindInsidePointGE##X( value, array, lbnd, ubnd, &inx, &iny, &iv, status ); \ -\ - } else if( oper == AST__GT ) { \ - FindInsidePointGT##X( value, array, lbnd, ubnd, &inx, &iny, &iv, status ); \ -\ - } else if( astOK ){ \ - astError( AST__OPRIN, "astOutline"#X": Invalid operation code " \ - "(%d) supplied (programming error).", status, oper ); \ - } \ - } \ -\ -/* We now need to find a point on the boundary of the region containing \ - the inside point. Starting at the inside point, move to the right \ - through the array until a pixel is found which fails to meet the value \ - requirement or the edge of the array is reached. */ \ -\ - candidate = NULL; \ - pv = array + iv; \ - ixv = inx; \ - stop_at_invalid = 1; \ -\ - while( ++ixv <= ubnd[ 0 ] ) { \ -\ -/* Get the next pixel value. */ \ - v = *(++pv); \ -\ -/* See if it meets the value requirement. */ \ - if( oper == AST__LT ) { \ - valid = ( v < value ); \ -\ - } else if( oper == AST__LE ) { \ - valid = ( v <= value ); \ -\ - } else if( oper == AST__EQ ) { \ - valid = ( v == value ); \ -\ - } else if( oper == AST__NE ) { \ - valid = ( v != value ); \ -\ - } else if( oper == AST__GE ) { \ - valid = ( v >= value ); \ -\ - } else if( oper == AST__GT ) { \ - valid = ( v > value ); \ -\ - } else if( astOK ){ \ - astError( AST__OPRIN, "astOutline"#X": Invalid operation code " \ - "(%d) supplied (programming error).", status, oper ); \ - break; \ - } \ -\ -/* If we are currently looking for the next invalid pixel, and this pixel \ - is invalid... */ \ - if( stop_at_invalid ) { \ - if( ! valid ) { \ -\ -/* The current pixel may be on the required polygon, or it may be on the \ - edge of a hole contained within the region being outlined. We would \ - like to jump over such holes so that we can continue to look for the \ - real edge of the region being outlined. In order to determine if we \ - have reached a hole, we trace the edge that passes through the current \ - pixel, forming a candidate polygon in the process. In the process, We \ - see if the inside point falls within this candidate polygon. If it does \ - then the polygon is accepted as the required polygon. Otherwise, it is \ - rejected as a mere hole, and we continue moving away from the inside \ - point, looking for a new edge. */ \ - if( oper == AST__LT ) { \ - candidate = TraceEdgeLT##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__LE ) { \ - candidate = TraceEdgeLE##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__EQ ) { \ - candidate = TraceEdgeEQ##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__NE ) { \ - candidate = TraceEdgeNE##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__GE ) { \ - candidate = TraceEdgeGE##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__GT ) { \ - candidate = TraceEdgeGT##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( astOK ){ \ - astError( AST__OPRIN, "astOutline"#X": Invalid operation code " \ - "(%d) supplied (programming error).", status, oper ); \ - } \ -\ -/* If the candidate polygon is the required polygon, break out of the \ - loop. Otherwise, indicate that we want to continue moving right, \ - across the hole, until we reach the far side of the hole (i.e. find \ - the next valid pixel). */ \ - if( candidate ) { \ - break; \ - } else { \ - stop_at_invalid = 0; \ - } \ - } \ -\ -/* If we are currently looking for the next valid pixel, and the current \ - pixel is valid... */ \ - } else if( valid ) { \ -\ -/* We have reached the far side of a hole. Continue moving right, looking \ - now for the next invalid pixel (which may be on the required polygon). */ \ - stop_at_invalid = 1; \ - } \ - } \ -\ -/* If we have not yet found the required polygon, we must have reached \ - the right hand edge of the array. So we now follow the edge of the \ - array round until we meet the boundary of the required region. */ \ - if( !candidate ) { \ - if( oper == AST__LT ) { \ - candidate = TraceEdgeLT##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__LE ) { \ - candidate = TraceEdgeLE##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__EQ ) { \ - candidate = TraceEdgeEQ##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__NE ) { \ - candidate = TraceEdgeNE##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__GE ) { \ - candidate = TraceEdgeGE##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( oper == AST__GT ) { \ - candidate = TraceEdgeGT##X( value, array, lbnd, ubnd, iv - 1, \ - ixv - 1, iny, starpix, smooth, status ); \ -\ - } else if( astOK ){ \ - astError( AST__OPRIN, "astOutline"#X": Invalid operation code " \ - "(%d) supplied (programming error).", status, oper ); \ - } \ - } \ -\ -/* If required smooth the full resolution polygon before downsizing it. */ \ - if( smooth ) { \ -\ -/* Initially, set the boxsize to be equal to the required accouracy. */ \ - if( maxerr > 0 ) { \ - boxsize = (int) maxerr; \ - } else { \ - boxsize = INT_MAX; \ - } \ -\ -/* Determine a second box size equal to the average number of vertices in \ - the accurate outline, per vertex in the returned Polygon. */ \ - nv0 = astGetNpoint( candidate ); \ - if( maxvert > 2 ) { \ - tmp = nv0/(2*maxvert); \ - } else { \ - tmp = INT_MAX; \ - } \ -\ -/* Use the minimum of the two box sizes. */ \ - if( tmp < boxsize ) boxsize = tmp; \ -\ -/* Ensure the box is sufficiently small to allow at least 10 full boxes \ - (=20 half boxes) around the polygon. */ \ - tmp = nv0/20; \ - if( tmp < boxsize ) boxsize = tmp; \ - if( boxsize == 0 ) boxsize = 1; \ -\ -/* Smooth the polygon. */ \ - SmoothPoly( candidate, boxsize, 1.0, status ); \ - } \ -\ -/* Reduce the number of vertices in the outline. */ \ - frm = astFrame( 2, "Domain=PIXEL,Unit(1)=pixel,Unit(2)=pixel," \ - "Title=Pixel coordinates", status ); \ - pset = DownsizePoly( candidate, maxerr, maxvert, frm, status ); \ -\ -/* Create a default Polygon with 3 junk vertices. */ \ - result = astPolygon( frm, 3, 3, junk, NULL, " ", status ); \ -\ -/* Change the PointSet within the Polygon to the one created above. */ \ - SetPointSet( result, pset, status ); \ -\ -/* Free resources. Note, we need to free the arrays within the candidate \ - PointSet explicitly, since they were not created as part of the \ - construction of the PointSet (see TraceEdge). */ \ - pset = astAnnul( pset ); \ - frm = astAnnul( frm ); \ - ptr = astGetPoints( candidate ); \ - if( astOK ) { \ - astFree( ptr[ 0 ] ); \ - astFree( ptr[ 1 ] ); \ - } \ - candidate = astAnnul( candidate ); \ -\ -/* If an error occurred, clear the returned result. */ \ - if ( !astOK ) result = astAnnul( result ); \ -\ -/* Return the result. */ \ - return result; \ -} - - -/* Expand the above macro to generate a function for each required - data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_OUTLINE(LD,long double) -#endif -MAKE_OUTLINE(D,double) -MAKE_OUTLINE(L,long int) -MAKE_OUTLINE(UL,unsigned long int) -MAKE_OUTLINE(I,int) -MAKE_OUTLINE(UI,unsigned int) -MAKE_OUTLINE(S,short int) -MAKE_OUTLINE(US,unsigned short int) -MAKE_OUTLINE(B,signed char) -MAKE_OUTLINE(UB,unsigned char) -MAKE_OUTLINE(F,float) - -/* Undefine the macros. */ -#undef MAKE_OUTLINE - -/* -* Name: -* PartHull - -* Purpose: -* Find the convex hull enclosing selected pixels in one corner of a 2D array. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void PartHull( value, const array[], int xdim, -* int ydim, int xs, int ys, int xe, int ye, -* int starpix, const int lbnd[2], double **xvert, -* double **yvert, int *nvert, int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* This function uses an algorithm similar to "Andrew's Monotone Chain -* Algorithm" to create a list of vertices describing one corner of the -* convex hull enclosing the selected pixels in the supplied array. -* The corner is defined to be the area of the array to the right of -* the line from (xs,ys) to (xe,ye). - -* Parameters: -* value -* A data value that specifies the pixels to be selected. -* array -* Pointer to a 2-dimensional array containing the data to be -* processed. The numerical type of this array should match the 1- -* or 2-character type code appended to the function name. -* xdim -* The number of pixels along each row of the array. -* ydim -* The number of rows in the array. -* xs -* The X GRID index of the first pixel on the line to be checked. -* ys -* The Y GRID index of the first pixel on the line to be checked. -* xe -* The X GRID index of the last pixel on the line to be checked. -* ye -* The Y GRID index of the last pixel on the line to be checked. -* starpix -* If non-zero, the usual Starlink definition of pixel coordinate -* is used (integral values at pixel corners). Otherwise, the -* system used by other AST functions such as astResample is used -* (integral values at pixel centres). -* lbnd -* The lower pixel index bounds of the array. -* xvert -* Address of a pointer in which to return a pointer to the list -* of GRID x values on the hull. -* yvert -* Address of a pointer in which to return a pointer to the list -* of GRID y values on the hull. -* nvert -* Address of a pointer in which to return the number of points in -* the returned xvert and yvert arrays. -* status -* Pointer to the inherited status variable. - -*/ - -/* Define a macro to implement the function for a specific data - type and operation. */ -#define MAKE_PARTHULL(X,Xtype,Oper,OperI) \ -static void PartHull##Oper##X( Xtype value, const Xtype array[], int xdim, \ - int ydim, int xs, int ys, int xe, int ye, \ - int starpix, const int lbnd[2], \ - double **xvert, double **yvert, int *nvert, \ - int *status ) { \ -\ -/* Local Variables: */ \ - const Xtype *pc; \ - double *pxy; \ - double dx2; \ - double dx1; \ - double dy1; \ - double dy2; \ - double off; \ - double xdelta; \ - int ivert; \ - int ix; \ - int iy; \ - int x0; \ - int x1; \ - int xl; \ - int xlim; \ - int xr; \ - int yinc; \ -\ -/* Initialise */ \ - *yvert = NULL; \ - *xvert = NULL; \ - *nvert = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* If the line has zero length. just return a single vertex. */ \ - if( xs == xe && ys == ye ) { \ - *xvert = astMalloc( sizeof( double ) ); \ - *yvert = astMalloc( sizeof( double ) ); \ - if( astOK ) { \ - if( starpix ) { \ - (*xvert)[ 0 ] = xs + lbnd[ 0 ] - 1.5; \ - (*yvert)[ 0 ] = ys + lbnd[ 1 ] - 1.5; \ - } else { \ - (*xvert)[ 0 ] = xs + lbnd[ 0 ] - 1.0; \ - (*yvert)[ 0 ] = ys + lbnd[ 1 ] - 1.0; \ - } \ - *nvert = 1; \ - } \ - return; \ - } \ -\ -/* Otherwise check the line is sloping. */ \ - if( xs == xe ) { \ - astError( AST__INTER, "astOutline(Polygon): Bounding box " \ - "has zero width (internal AST programming error).", \ - status ); \ - return; \ - } else if( ys == ye ) { \ - astError( AST__INTER, "astOutline(Polygon): Bounding box " \ - "has zero height (internal AST programming error).", \ - status ); \ - return; \ - } \ -\ -/* Calculate the difference in length between adjacent rows of the area \ - to be tested. */ \ - xdelta = ((double)( xe - xs ))/((double)( ye - ys )); \ -\ -/* The left and right X limits */ \ - if( xe > xs ) { \ - xl = xs; \ - xr = xe; \ - } else { \ - xl = xe; \ - xr = xs; \ - } \ -\ -/* Get the increment in row number as we move from the start to the end \ - of the line. */ \ - yinc = ( ye > ys ) ? 1 : -1; \ -\ -/* Loop round all rows that cross the region to be tested, from start to \ - end of the supplied line. */ \ - iy = ys; \ - while( astOK ) { \ -\ -/* Get the GRID X coord where the line crosses this row. */ \ - xlim = (int)( 0.5 + xs + xdelta*( iy - ys ) ); \ -\ -/* Get the index of the first and last columns to be tested on this row. */ \ - if( yinc < 0 ) { \ - x0 = xl; \ - x1 = xlim; \ - } else { \ - x0 = xlim; \ - x1 = xr; \ - } \ -\ -/* Get a pointer to the first pixel to be tested at this row. */ \ - pc = array + ( iy - 1 )*xdim + x0 - 1; \ -\ -/* Loop round all columns to be tested in this row. */ \ - for( ix = x0; ix <= x1 && astOK; ix++,pc++ ) { \ -\ -/* Ignore pixels that are not selected. */ \ - if( ISVALID(*pc,OperI,value) ) { \ -\ -/* If this is the very first pixel, initialise the hull to contain just \ - the first pixel. */ \ - if( *nvert == 0 ){ \ - *xvert = astMalloc( 200*sizeof( double ) ); \ - *yvert = astMalloc( 200*sizeof( double ) ); \ - if( astOK ) { \ - (*xvert)[ 0 ] = ix; \ - (*yvert)[ 0 ] = iy; \ - *nvert = 1; \ - } else { \ - break; \ - } \ -\ -/* Otherwise.... */ \ - } else { \ -\ -/* Loop until the hull has been corrected to include the current pixel. */ \ - while( 1 ) { \ -\ -/* If the hull currently contains only one pixel, add the current pixel to \ - the end of the hull. */ \ - if( *nvert == 1 ){ \ - (*xvert)[ 1 ] = ix; \ - (*yvert)[ 1 ] = iy; \ - *nvert = 2; \ - break; \ -\ -/* Otherwise... */ \ - } else { \ -\ -/* Extend the line from the last-but-one pixel on the hull to the last \ - pixel on the hull, and see if the current pixel is to the left of \ - this line. If it is, it too is on the hull and so push it onto the end \ - of the list of vertices. */ \ - dx1 = (*xvert)[ *nvert - 1 ] - (*xvert)[ *nvert - 2 ]; \ - dy1 = (*yvert)[ *nvert - 1 ] - (*yvert)[ *nvert - 2 ]; \ - dx2 = ix - (*xvert)[ *nvert - 2 ]; \ - dy2 = iy - (*yvert)[ *nvert - 2 ]; \ -\ - if( dx1*dy2 > dx2*dy1 ) { \ - ivert = (*nvert)++; \ - *xvert = astGrow( *xvert, *nvert, sizeof( double ) ); \ - *yvert = astGrow( *yvert, *nvert, sizeof( double ) ); \ - if( astOK ) { \ - (*xvert)[ ivert ] = ix; \ - (*yvert)[ ivert ] = iy; \ - } \ -\ -/* Leave the loop now that the new point is on the hull. */ \ - break; \ -\ -/* If the new point is to the left of the line, then the last point \ - previously thought to be on hull is in fact not on the hull, so remove \ - it. We then loop again to compare the new pixel with modified hull. */ \ - } else { \ - (*nvert)--; \ - } \ - } \ - } \ - } \ - } \ - } \ -\ - if( iy == ye ) { \ - break; \ - } else { \ - iy += yinc; \ - } \ -\ - } \ -\ -/* Convert GRID coords to PIXEL coords. */ \ - if( astOK ) { \ - pxy = *xvert; \ - off = starpix ? lbnd[ 0 ] - 1.5 : lbnd[ 0 ] - 1.0; \ - for( ivert = 0; ivert < *nvert; ivert++ ) *(pxy++) += off; \ -\ - pxy = *yvert; \ - off = starpix ? lbnd[ 1 ] - 1.5 : lbnd[ 1 ] - 1.0; \ - for( ivert = 0; ivert < *nvert; ivert++ ) *(pxy++) += off; \ -\ -/* Free lists if an error has occurred. */ \ - } else { \ - *xvert = astFree( *xvert ); \ - *yvert = astFree( *yvert ); \ - *nvert = 0; \ - } \ -} - -/* Define a macro that uses the above macro to to create implementations - of PartHull for all operations. */ -#define MAKEALL_PARTHULL(X,Xtype) \ -MAKE_PARTHULL(X,Xtype,LT,AST__LT) \ -MAKE_PARTHULL(X,Xtype,LE,AST__LE) \ -MAKE_PARTHULL(X,Xtype,EQ,AST__EQ) \ -MAKE_PARTHULL(X,Xtype,NE,AST__NE) \ -MAKE_PARTHULL(X,Xtype,GE,AST__GE) \ -MAKE_PARTHULL(X,Xtype,GT,AST__GT) - -/* Expand the above macro to generate a function for each required - data type and operation. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKEALL_PARTHULL(LD,long double) -#endif -MAKEALL_PARTHULL(D,double) -MAKEALL_PARTHULL(L,long int) -MAKEALL_PARTHULL(UL,unsigned long int) -MAKEALL_PARTHULL(I,int) -MAKEALL_PARTHULL(UI,unsigned int) -MAKEALL_PARTHULL(S,short int) -MAKEALL_PARTHULL(US,unsigned short int) -MAKEALL_PARTHULL(B,signed char) -MAKEALL_PARTHULL(UB,unsigned char) -MAKEALL_PARTHULL(F,float) - -/* Undefine the macros. */ -#undef MAKE_PARTHULL -#undef MAKEALL_PARTHULL - -static double Polywidth( AstFrame *frm, AstLineDef **edges, int i, int nv, - double cen[ 2 ], int *status ){ -/* -* Name: -* Polywidth - -* Purpose: -* Find the width of a polygon perpendicular to a given edge. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* double Polywidth( AstFrame *frm, AstLineDef **edges, int i, int nv, -* double cen[ 2 ], int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* This function defines a line perpendicular to a given polygon edge, -* passing through the mid point of the edge, extending towards the -* inside of the polygon. It returns the distance that can be travelled -* along this line before any of the other polygon edges are hit (the -* "width" of the polygon perpendicular to the given edge). It also -* puts the position corresponding to half that distance into "cen". - -* Parameters: -* frm -* The Frame in which the lines are defined. -* edges -* Array of "nv" pointers to AstLineDef structures, each defining an -* edge of the polygon. -* i -* The index of the edge that is to define the polygon width. -* nv -* Total number of edges. -* cen -* An array into which are put the coords of the point half way -* along the polygon width line. -* status -* Pointer to the inherited status variable. - -* Returnd Value: -* The width of the polygon perpendicular to the given edge, or -* AST__BAD if the width cannot be determined (usually because the -* vertices been supplied in a clockwise direction, effectively -* negating the Polygon). - -*/ - -/* Local Variables: */ - AstLineDef *line; - double *cross; - double d; - double end[ 2 ]; - double l1; - double l2; - double result; - double start[ 2 ]; - int j; - -/* Check the global error status. */ - result = AST__BAD; - if ( !astOK ) return result; - -/* Create a Line description for a line perpendicular to the specified - edge, passing through the mid point of the edge, and extending towards - the inside of the polygon. First move away from the start along the - line to the mid point. This gives the start of the new line. */ - l1 = 0.5*( edges[ i ]->length ); - astLineOffset( frm, edges[ i ], l1, 0.0, start ); - -/* We now move away from this position at right angles to the line. We - start off by moving 5 times the length of the specified edge. For - some Frames (e.g. SkyFrames) this may result in a position that is - much too close (i.e. if it goes all the way round the great circle - and comes back to the beginning). Therefore, we check that the end - point is the requested distance from the start point, and if not, we - halve the length of the line and try again. */ - l2 = 10.0*l1; - while( 1 ) { - astLineOffset( frm, edges[ i ], l1, l2, end ); - d = astDistance( frm, start, end ); - if( d != AST__BAD && fabs( d - l2 ) < 1.0E-6*l2 ) break; - l2 *= 0.5; - } - -/* Create a description of the required line. */ - line = astLineDef( frm, start, end ); - -/* Loop round every edge, except for the supplied edge. */ - for( j = 0; j < nv; j++ ) { - if( j != i ) { - -/* Find the position at which the line created above crosses the current - edge. Skip to the next edge if the line does not intersect the edge - within the length of the edge. */ - if( astLineCrossing( frm, line, edges[ j ], &cross ) ) { - -/* Find the distance between the crossing point and the line start. */ - d = astDistance( frm, start, cross ); - -/* If this is less than the smallest found so far, record it. */ - if( d != AST__BAD && ( d < result || result == AST__BAD ) ) { - result = d; - } - } - -/* Free resources */ - cross = astFree( cross ); - } - } - line = astFree( line ); - -/* If a width was found, return the point half way across the polygon. */ - if( result != AST__BAD ) { - astOffset( frm, start, end, 0.5*result, cen ); - -/* The usual reason for not finding a width is if the polygon vertices - are supplied in clockwise order, effectively negating the polygon, and - resulting in the "inside" of the polygon being the infinite region - outside a polygonal hole. In this case, the end point of the line - perpendicular to the initial edge can be returned as a representative - "inside" point. */ - } else { - cen[ 0 ] = end[ 0 ]; - cen[ 1 ] = end[ 1 ]; - } - -/* Return the width. */ - return result; - -} - -static void RegBaseBox( AstRegion *this_region, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* Polygon member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to encapsulated Frame */ - AstPointSet *pset; /* Pointer to PointSet defining the Region */ - AstPolygon *this; /* Pointer to Polygon structure */ - AstRegion *reg; /* Base Frame equivalent of supplied Polygon */ - double **ptr; /* Pointer to PointSet data */ - double *x; /* Pointer to next X axis value */ - double *y; /* Pointer to next Y axis value */ - double dist; /* Offset along an axis */ - double x0; /* The first X axis value */ - double y0; /* The first Y axis value */ - int ip; /* Point index */ - int np; /* No. of points in PointSet */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Polygon structure. */ - this = (AstPolygon *) this_region; - -/* If the base Frame bounding box has already been found, return the - values stored in the Polygon structure. */ - if( this->lbnd[ 0 ] != AST__BAD ) { - lbnd[ 0 ] = this->lbnd[ 0 ]; - lbnd[ 1 ] = this->lbnd[ 1 ]; - ubnd[ 0 ] = this->ubnd[ 0 ]; - ubnd[ 1 ] = this->ubnd[ 1 ]; - -/* If the base Frame bounding box has not yet been found, find it now and - store it in the Polygon structure. */ - } else { - -/* Get the axis values for the PointSet which defines the location and - extent of the region in the base Frame of the encapsulated FrameSet. */ - pset = this_region->points; - ptr = astGetPoints( pset ); - np = astGetNpoint( pset ); - -/* Get a pointer to the base Frame in the frameset encapsulated by the - parent Region structure. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Find the upper and lower bounds of the box enclosing all the vertices. - The box is expressed in terms of axis offsets from the first vertex, in - order to avoid problems with boxes that cross RA=0 or RA=12h */ - lbnd[ 0 ] = 0.0; - lbnd[ 1 ] = 0.0; - ubnd[ 0 ] = 0.0; - ubnd[ 1 ] = 0.0; - - x = ptr[ 0 ]; - y = ptr[ 1 ]; - - x0 = *x; - y0 = *y; - - for( ip = 0; ip < np; ip++, x++, y++ ) { - - dist = astAxDistance( frm, 1, x0, *x ); - if( dist < lbnd[ 0 ] ) { - lbnd[ 0 ] = dist; - } else if( dist > ubnd[ 0 ] ) { - ubnd[ 0 ] = dist; - } - - dist = astAxDistance( frm, 2, y0, *y ); - if( dist < lbnd[ 1 ] ) { - lbnd[ 1 ] = dist; - } else if( dist > ubnd[ 1 ] ) { - ubnd[ 1 ] = dist; - } - - } - -/* Convert the box bounds to absolute values, rather than values relative - to the first vertex. */ - lbnd[ 0 ] += x0; - lbnd[ 1 ] += y0; - ubnd[ 0 ] += x0; - ubnd[ 1 ] += y0; - -/* The astNormBox requires a Mapping which can be used to test points in - this base Frame. Create a copy of the Polygon and then set its - FrameSet so that the current Frame in the copy is the same as the base - Frame in the original. */ - reg = astCopy( this ); - astSetRegFS( reg, frm ); - astSetNegated( reg, 0 ); - -/* Normalise this box. */ - astNormBox( frm, lbnd, ubnd, reg ); - -/* Free resources */ - reg = astAnnul( reg ); - frm = astAnnul( frm ); - -/* Store it in the olygon structure for future use. */ - this->lbnd[ 0 ] = lbnd[ 0 ]; - this->lbnd[ 1 ] = lbnd[ 1 ]; - this->ubnd[ 0 ] = ubnd[ 0 ]; - this->ubnd[ 1 ] = ubnd[ 1 ]; - - } -} - -static AstPointSet *RegBaseMesh( AstRegion *this_region, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Return a PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* AstPointSet *astRegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* Polygon member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. Annul the pointer using astAnnul when it -* is no longer needed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - -/* Local Variables: */ - AstFrame *frm; /* Base Frame in encapsulated FrameSet */ - AstPointSet *result; /* Returned pointer */ - AstPolygon *this; /* The Polygon structure */ - double **rptr; /* Pointers to returned mesh data */ - double **vptr; /* Pointers to vertex data */ - double *lens; /* Pointer to work space holding edge lengths */ - double d; /* Length of this edge */ - double delta; /* Angular separation of points */ - double end[ 2 ]; /* End position */ - double mp; /* No. of mesh points per unit distance */ - double p[ 2 ]; /* Position in 2D Frame */ - double start[ 2 ]; /* Start position */ - double total; /* Total length of polygon */ - int ip; /* Point index */ - int iv; /* Vertex index */ - int n; /* No. of points on this edge */ - int next; /* Index of next point in returned PointSet */ - int np; /* No. of points in returned PointSet */ - int nv; /* No. of polygon vertices */ - -/* Initialise */ - result= NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the Region structure contains a pointer to a PointSet holding - a previously created mesh, return it. */ - if( this_region->basemesh ) { - result = astClone( this_region->basemesh ); - -/* Otherwise, create a new mesh. */ - } else { - -/* Get a pointer to the Polygon structure. */ - this = (AstPolygon *) this_region; - -/* Get a pointer to the base Frame in the encapsulated FrameSet. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* Get the number of vertices and pointers to the vertex axis values. */ - nv = astGetNpoint( this_region->points ); - vptr = astGetPoints( this_region->points ); - -/* Allocate memory to hold the geodesic length of each edge. */ - lens = astMalloc( sizeof( double )*(size_t) nv ); - - if( astOK ) { - -/* Find the total geodesic distance around the boundary. */ - total = 0.0; - - start[ 0 ] = vptr[ 0 ][ 0 ]; - start[ 1 ] = vptr[ 1 ][ 0 ]; - - for( iv = 1; iv < nv; iv++ ) { - end[ 0 ] = vptr[ 0 ][ iv ]; - end[ 1 ] = vptr[ 1 ][ iv ]; - - d = astDistance( frm, start, end ); - if( d != AST__BAD ) total += fabs( d ); - lens[ iv ] = d; - start[ 0 ] = end[ 0 ]; - start[ 1 ] = end[ 1 ]; - } - - end[ 0 ] = vptr[ 0 ][ 0 ]; - end[ 1 ] = vptr[ 1 ][ 0 ]; - - d = astDistance( frm, start, end ); - if( d != AST__BAD ) total += fabs( d ); - lens[ 0 ] = d; - -/* Find the number of mesh points per unit geodesic distance. */ - if( total > 0.0 ){ - mp = astGetMeshSize( this )/total; - -/* Find the total number of mesh points required. */ - np = 0; - for( iv = 0; iv < nv; iv++ ) { - if( lens[ iv ] != AST__BAD ) np += 1 + (int)( lens[ iv ]*mp ); - } - -/* Create a suitable PointSet to hold the returned positions. */ - result = astPointSet( np, 2, "", status ); - rptr = astGetPoints( result ); - if( astOK ) { - -/* Initialise the index of the next point to be added to the returned - PointSet. */ - next = 0; - -/* Loop round each good edge of the polygon. The edge ends at vertex "iv". */ - start[ 0 ] = vptr[ 0 ][ 0 ]; - start[ 1 ] = vptr[ 1 ][ 0 ]; - - for( iv = 1; iv < nv; iv++ ) { - end[ 0 ] = vptr[ 0 ][ iv ]; - end[ 1 ] = vptr[ 1 ][ iv ]; - if( lens[ iv ] != AST__BAD ) { - -/* Add the position of the starting vertex to the returned mesh. */ - rptr[ 0 ][ next ] = start[ 0 ]; - rptr[ 1 ][ next ] = start[ 1 ]; - next++; - -/* Find the number of points on this edge, and the geodesic distance - between them. */ - n = 1 + (int) ( lens[ iv ]*mp ); - -/* If more than one point, find the distance between points. */ - if( n > 1 ) { - delta = lens[ iv ]/n; - -/* Loop round the extra points. */ - for( ip = 1; ip < n; ip++ ) { - -/* Find the position of the next mesh point. */ - astOffset( frm, start, end, delta*ip, p ); - -/* Add it to the mesh. */ - rptr[ 0 ][ next ] = p[ 0 ]; - rptr[ 1 ][ next ] = p[ 1 ]; - next++; - - } - } - } - -/* The end of this edge becomes the start of the next. */ - start[ 0 ] = end[ 0 ]; - start[ 1 ] = end[ 1 ]; - } - -/* Now do the edge which ends at the first vertex. */ - end[ 0 ] = vptr[ 0 ][ 0 ]; - end[ 1 ] = vptr[ 1 ][ 0 ]; - if( lens[ 0 ] != AST__BAD ) { - rptr[ 0 ][ next ] = start[ 0 ]; - rptr[ 1 ][ next ] = start[ 1 ]; - next++; - - n = 1 + (int)( lens[ 0 ]*mp ); - if( n > 1 ) { - delta = lens[ 0 ]/n; - for( ip = 1; ip < n; ip++ ) { - astOffset( frm, start, end, delta*ip, p ); - rptr[ 0 ][ next ] = p[ 0 ]; - rptr[ 1 ][ next ] = p[ 1 ]; - next++; - } - } - } - -/* Check the PointSet size was correct. */ - if( next != np && astOK ) { - astError( AST__INTER, "astRegBaseMesh(%s): Error in the " - "allocated PointSet size (%d) - should have " - "been %d (internal AST programming error).", status, - astGetClass( this ), np, next ); - } - -/* Save the returned pointer in the Region structure so that it does not - need to be created again next time this function is called. */ - if( astOK ) this_region->basemesh = astClone( result ); - - } - - } else if( astOK ) { - astError( AST__BADIN, "astRegBaseMesh(%s): The boundary of " - "the supplied %s has an undefined length.", status, - astGetClass( this ), astGetClass( this ) ); - } - - } - -/* Free resources. */ - frm = astAnnul( frm ); - lens = astFree( lens ); - } - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static int RegPins( AstRegion *this_region, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -* Name: -* RegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given Polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask, int *status ) - -* Class Membership: -* Polygon member function (over-rides the astRegPins protected -* method inherited from the Region class). - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given Polygon. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied Polygon "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the Polygon. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "pset". -* Each element in the returned array is set to 1 if the -* corresponding position in "pset" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*/ - -/* Local variables: */ - AstFrame *frm; /* Base Frame in supplied Polygon */ - AstPointSet *pset1; /* Pointer to copy of supplied PointSet */ - AstPointSet *pset2; /* Pointer to PointSet holding resolved components */ - AstPolygon *this; /* Pointer to the Polygon structure. */ - AstRegion *tunc; /* Uncertainity Region from "this" */ - double **ptr1; /* Pointer to axis values in "pset1" */ - double **ptr2; /* Pointer to axis values in "pset2" */ - double **vptr; /* Pointer to axis values at vertices */ - double *safe; /* An interior point in "this" */ - double edge_len; /* Length of current edge */ - double end[2]; /* Position of end of current edge */ - double l1; /* Length of bounding box diagonal */ - double l2; /* Length of bounding box diagonal */ - double lbnd_tunc[2]; /* Lower bounds of "this" uncertainty Region */ - double lbnd_unc[2]; /* Lower bounds of supplied uncertainty Region */ - double par; /* Parallel component */ - double parmax; /* Max acceptable parallel component */ - double prp; /* Perpendicular component */ - double start[2]; /* Position of start of current edge */ - double ubnd_tunc[2]; /* Upper bounds of "this" uncertainty Region */ - double ubnd_unc[2]; /* Upper bounds of supplied uncertainty Region */ - double wid; /* Width of acceptable margin around polygon */ - int *m; /* Pointer to next mask value */ - int i; /* Edge index */ - int ip; /* Point index */ - int np; /* No. of supplied points */ - int nv; /* No. of vertices */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - if( mask ) *mask = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the Polygon structure. */ - this = (AstPolygon *) this_region; - -/* Check the supplied PointSet has 2 axis values per point. */ - if( astGetNcoord( pset ) != 2 && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axis " - "values per point (%d) in the supplied PointSet - should be " - "2 (internal AST programming error).", status, astGetClass( this ), - astGetNcoord( pset ) ); - } - -/* Get the number of axes in the uncertainty Region and check it is also 2. */ - if( unc && astGetNaxes( unc ) != 2 && astOK ) { - astError( AST__INTER, "astRegPins(%s): Illegal number of axes (%d) " - "in the supplied uncertainty Region - should be 2 " - "(internal AST programming error).", status, astGetClass( this ), - astGetNaxes( unc ) ); - } - -/* Get pointers to the axis values at the polygon vertices. */ - vptr = astGetPoints( this_region->points ); - -/* Get the number of vertices. */ - nv = astGetNpoint( this_region->points ); - -/* Take a copy of the supplied PointSet and get pointers to its axis - values,and its size */ - pset1 = astCopy( pset ); - ptr1 = astGetPoints( pset1 ); - np = astGetNpoint( pset1 ); - -/* Create a PointSet to hold the resolved components and get pointers to its - axis data. */ - pset2 = astPointSet( np, 2, "", status ); - ptr2 = astGetPoints( pset2 ); - -/* Create a mask array if required. */ - if( mask ) *mask = astMalloc( sizeof(int)*(size_t) np ); - -/* Get the centre of the region in the base Frame. We use this as a "safe" - interior point within the region. */ - safe = astRegCentre( this, NULL, NULL, 0, AST__BASE ); - -/* We now find the maximum distance on each axis that a point can be from the - boundary of the Polygon for it still to be considered to be on the boundary. - First get the Region which defines the uncertainty within the Polygon - being checked (in its base Frame), re-centre it on the interior point - found above (to avoid problems if the uncertainty region straddles a - discontinuity), and get its bounding box. The current Frame of the - uncertainty Region is the same as the base Frame of the Polygon. */ - tunc = astGetUncFrm( this, AST__BASE ); - if( safe ) astRegCentre( tunc, safe, NULL, 0, AST__CURRENT ); - astGetRegionBounds( tunc, lbnd_tunc, ubnd_tunc ); - -/* Find the geodesic length within the base Frame of "this" of the diagonal of - the bounding box. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - l1 = astDistance( frm, lbnd_tunc, ubnd_tunc ); - -/* Also get the Region which defines the uncertainty of the supplied - points and get its bounding box. First re-centre the uncertainty at the - interior position to avoid problems from uncertainties that straddle a - discontinuity. */ - if( unc ) { - if( safe ) astRegCentre( unc, safe, NULL, 0, AST__CURRENT ); - astGetRegionBounds( unc, lbnd_unc, ubnd_unc ); - -/* Find the geodesic length of the diagonal of this bounding box. */ - l2 = astDistance( frm, lbnd_unc, ubnd_unc ); - -/* Assume zero uncertainty if no "unc" Region was supplied. */ - } else { - l2 = 0.0; - } - -/* The required border width is half of the total diagonal of the two bounding - boxes. */ - if( astOK ) { - wid = 0.5*( l1 + l2 ); - -/* Loop round each edge of the polygon. Edge "i" starts at vertex "i-1" - and ends at vertex "i". Edge zero starts at vertex "nv-1" and ends at - vertex zero. */ - start[ 0 ] = vptr[ 0 ][ nv - 1 ]; - start[ 1 ] = vptr[ 1 ][ nv - 1 ]; - for( i = 0; i < nv; i++ ) { - end[ 0 ] = vptr[ 0 ][ i ]; - end[ 1 ] = vptr[ 1 ][ i ]; - -/* Find the length of this edge. */ - edge_len = astDistance( frm, start, end ); - -/* Resolve all the supplied mesh points into components parallel and - perpendicular to this edge. */ - (void) astResolvePoints( frm, start, end, pset1, pset2 ); - -/* A point is effectively on this edge if the parallel component is - greater than (-wid) and less than (edge_len+wid) AND the perpendicular - component has an absolute value less than wid. Identify such positions - and set them bad in pset1. */ - parmax = edge_len + wid; - for( ip = 0; ip < np; ip++ ) { - par = ptr2[ 0 ][ ip ]; - prp = ptr2[ 1 ][ ip ]; - - if( par != AST__BAD && prp != AST__BAD ) { - if( par > -wid && par < parmax && prp > -wid && prp < wid ) { - ptr1[ 0 ][ ip ] = AST__BAD; - ptr1[ 1 ][ ip ] = AST__BAD; - } - } - } - -/* The end of the current edge becomes the start of the next. */ - start[ 0 ] = end[ 0 ]; - start[ 1 ] = end[ 1 ]; - } - -/* See if any good points are left in pset1. If so, it means that those - points were not on any edge of hte Polygon. We use two alogorithms - here depending on whether we are creating a mask array, since we can - abort the check upon finding the first good point if we are not - producing a mask. */ - result = 1; - if( mask ) { - m = *mask; - for( ip = 0; ip < np; ip++, m++ ) { - if( ptr1[ 0 ][ ip ] != AST__BAD && - ptr1[ 1 ][ ip ] != AST__BAD ) { - *m = 0; - result = 0; - } else { - *m = 1; - } - } - } else { - for( ip = 0; ip < np; ip++ ) { - if( ptr1[ 0 ][ ip ] != AST__BAD && - ptr1[ 1 ][ ip ] != AST__BAD ) { - result = 0; - break; - } - } - } - } - -/* Free resources. */ - tunc = astAnnul( tunc ); - frm = astAnnul( frm ); - safe = astFree( safe ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* If an error has occurred, return zero. */ - if( !astOK ) { - result = 0; - if( mask ) *mask = astAnnul( *mask ); - } - -/* Return the result. */ - return result; -} - -static int RegTrace( AstRegion *this_region, int n, double *dist, double **ptr, - int *status ){ -/* -*+ -* Name: -* RegTrace - -* Purpose: -* Return requested positions on the boundary of a 2D Region. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* int astTraceRegion( AstRegion *this, int n, double *dist, double **ptr ); - -* Class Membership: -* Polygon member function (overrides the astTraceRegion method -* inherited from the parent Region class). - -* Description: -* This function returns positions on the boundary of the supplied -* Region, if possible. The required positions are indicated by a -* supplied list of scalar parameter values in the range zero to one. -* Zero corresponds to some arbitrary starting point on the boundary, -* and one corresponds to the end (which for a closed region will be -* the same place as the start). - -* Parameters: -* this -* Pointer to the Region. -* n -* The number of positions to return. If this is zero, the function -* returns without action (but the returned function value still -* indicates if the method is supported or not). -* dist -* Pointer to an array of "n" scalar parameter values in the range -* 0 to 1.0. -* ptr -* A pointer to an array of pointers. The number of elements in -* this array should equal tthe number of axes in the Frame spanned -* by the Region. Each element of the array should be a pointer to -* an array of "n" doubles, in which to return the "n" values for -* the corresponding axis. The contents of the arrays are unchanged -* if the supplied Region belongs to a class that does not -* implement this method. - -* Returned Value: -* Non-zero if the astTraceRegion method is implemented by the class -* of Region supplied, and zero if not. - -*- -*/ - -/* Local Variables; */ - AstFrame *frm; - AstMapping *map; - AstPointSet *bpset; - AstPointSet *cpset; - AstPolygon *this; - double **bptr; - double d; - double p[ 2 ]; - int i; - int j0; - int j; - int ncur; - int nv; - int monotonic; - -/* Check inherited status, and the number of points to return, returning - a non-zero value to indicate that this class supports the astRegTrace - method. */ - if( ! astOK || n == 0 ) return 1; - -/* Get a pointer to the Polygon structure. */ - this = (AstPolygon *) this_region; - -/* Ensure cached information is available. */ - Cache( this, status ); - -/* Get a pointer to the base Frame in the encapsulated FrameSet. */ - frm = astGetFrame( this_region->frameset, AST__BASE ); - -/* We first determine the required positions in the base Frame of the - Region, and then transform them into the current Frame. Get the - base->current Mapping, and the number of current Frame axes. */ - map = astGetMapping( this_region->frameset, AST__BASE, AST__CURRENT ); - -/* If it's a UnitMap we do not need to do the transformation, so put the - base Frame positions directly into the supplied arrays. */ - if( astIsAUnitMap( map ) ) { - bpset = NULL; - bptr = ptr; - ncur = 2; - -/* Otherwise, create a PointSet to hold the base Frame positions (known - to be 2D since this is an polygon). */ - } else { - bpset = astPointSet( n, 2, " ", status ); - bptr = astGetPoints( bpset ); - ncur = astGetNout( map ); - } - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Get the number of vertices. */ - nv = astGetNpoint( this_region->points ); - -/* If we have a reasonable number of pointsand there are a reasonable - number of vertices, we can be quicker if we know if the parameteric - distances are monotonic increasing. Find out now. */ - if( n > 5 && nv > 5 ) { - - monotonic = 1; - for( i = 1; i < n; i++ ) { - if( dist[ i ] < dist[ i - 1 ] ) { - monotonic = 0; - break; - } - } - - } else { - monotonic = 0; - } - -/* Loop round each point. */ - j0 = 1; - for( i = 0; i < n; i++ ) { - -/* Get the required round the polygon, starting from vertex zero. */ - d = dist[ i ]*this->totlen; - -/* Loop round each vertex until we find one which is beyond the required - point. If the supplied distances are monotonic increasing, we can - start the checks at the same vertex that was used for the previous - since we know there will never be a backward step. */ - for( j = j0; j < nv; j++ ) { - if( this->startsat[ j ] > d ) break; - } - -/* If the distances are monotonic increasing, record the vertex that we - have reached so far. */ - if( monotonic ) j0 = j; - -/* Find the distance to travel beyond the previous vertex. */ - d -= this->startsat[ j - 1 ]; - -/* Find the position, that is the required distance from the previous - vertex towards the next vertex. */ - astLineOffset( frm, this->edges[ j - 1 ], d, 0.0, p ); - -/* Store the resulting axis values. */ - bptr[ 0 ][ i ] = p[ 0 ]; - bptr[ 1 ][ i ] = p[ 1 ]; - } - } - -/* If required, transform the base frame positions into the current - Frame, storing them in the supplied array. Then free resources. */ - if( bpset ) { - cpset = astPointSet( n, ncur, " ", status ); - astSetPoints( cpset, ptr ); - - (void) astTransform( map, bpset, 1, cpset ); - - cpset = astAnnul( cpset ); - bpset = astAnnul( bpset ); - } - -/* Free remaining resources. */ - map = astAnnul( map ); - frm = astAnnul( frm ); - -/* Return a non-zero value to indicate that this class supports the - astRegTrace method. */ - return 1; -} - -static Segment *RemoveFromChain( Segment *head, Segment *seg, int *status ){ -/* -* Name: -* RemoveFromChain - -* Purpose: -* Remove a Segment from the link list maintained by astDownsize. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* Segment *RemoveFromChain( Segment *head, Segment *seg, int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* The supplied Segment is removed form the list, and the gap is -* closed up. - -* Parameters: -* head -* The Segment structure at the head of the list. -* seg -* The Segment to be removed from the list. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the link head (which will have changed if "seg" was the -* original head). - -*/ - -/* Check the global error status. */ - if ( !astOK ) return head; - -/* If the Segment was the original head, make the next segment the new - head. */ - if( head == seg ) head = seg->next; - -/* Close up the links between the Segments on either side of the segment - being removed. */ - if( seg->prev ) seg->prev->next = seg->next; - if( seg->next ) seg->next->prev = seg->prev; - -/* Nullify the links in the segment being removed. */ - seg->next = NULL; - seg->prev = NULL; - -/* Return the new head. */ - return head; -} - -static void ResetCache( AstRegion *this_region, int *status ){ -/* -* Name: -* ResetCache - -* Purpose: -* Clear cached information within the supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void ResetCache( AstRegion *this, int *status ) - -* Class Membership: -* Region member function (overrides the astResetCache method -* inherited from the parent Region class). - -* Description: -* This function clears cached information from the supplied Region -* structure. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPolygon *this; - int i; - int nv; - -/* Get a pointer to the Polygon structure. */ - this = (AstPolygon *) this_region; - -/* If a Polygon was supplied, indicate cached information needs to be - recalculated. */ - if( this ) { - this->stale = 1; - this->lbnd[ 0 ] = AST__BAD; - -/* Free any edge structures (number of vertices may be about to change so - this cannot be left until the next call to "Cache()". */ - if( this->edges ) { - nv = astGetNpoint( this_region->points ); - for( i = 0; i < nv; i++ ) { - this->edges[ i ] = astFree( this->edges[ i ] ); - } - this->edges = astFree( this->edges ); - } - -/* Clear the cache of the parent class. */ - (*parent_resetcache)( this_region, status ); - } -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* Polygon member function (extends the astSetAttrib method inherited from -* the Region class). - -* Description: -* This function assigns an attribute value for a Polygon, the attribute -* and its value being specified by means of a string of the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in lower -* case with no white space present. The value to the right of the "=" -* should be a suitable textual representation of the value to be assigned -* and this will be interpreted according to the attribute's data type. -* White space surrounding the value is only significant for string -* attributes. - -* Parameters: -* this -* Pointer to the Polygon. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void -*/ - -/* Local Vaiables: */ - AstPolygon *this; /* Pointer to the Polygon structure */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Polygon structure. */ - this = (AstPolygon *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* SimpVertices. */ -/* ------------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "simpvertices= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetSimpVertices( this, ival ); - -/* Pass any unrecognised setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetPointSet( AstPolygon *this, AstPointSet *pset, int *status ){ -/* -* Name: -* SetPointSet - -* Purpose: -* Store a new set of vertices in an existing Polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void SetPointSet( AstPolygon *this, AstPointSet *pset, int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* The PointSet in the supplied Polygon is annulled, and replaced by a -* clone of the supplied PointSet pointer. - -* Parameters: -* this -* Pointer to the Polygon to be changed. -* pset -* The PointSet containing the new vertex information. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Indicate the cached information in the polygon will need to be - re-calculated when needed. */ - astResetCache( this ); - -/* Annul the pointer to the PointSet already in the supplied Polygon. */ - (void) astAnnul( ((AstRegion *) this)->points ); - -/* Store a clone of the supplied new PointSet pointer. */ - ((AstRegion *) this)->points = astClone( pset ); - -} - -static void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) { -/* -* Name: -* SetRegFS - -* Purpose: -* Stores a new FrameSet in a Region - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) - -* Class Membership: -* Polygon method (over-rides the astSetRegFS method inherited from -* the Region class). - -* Description: -* This function creates a new FrameSet and stores it in the supplied -* Region. The new FrameSet contains two copies of the supplied -* Frame, connected by a UnitMap. - -* Parameters: -* this -* Pointer to the Region. -* frm -* The Frame to use. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Indicate cached information eeds re-calculating. */ - astResetCache( this_region ); - -/* Invoke the parent method to store the FrameSet in the parent Region - structure. */ - (* parent_setregfs)( this_region, frm, status ); - -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mapping represented by a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* Polygon method (over-rides the astSimplify method inherited -* from the Region class). - -* Description: -* This function invokes the parent Region Simplify method, and then -* performs any further region-specific simplification. -* -* If the Mapping from base to current Frame is not a UnitMap, this -* will include attempting to fit a new Region to the boundary defined -* in the current Frame. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the simplified Region. A cloned pointer to the -* supplied Region will be returned if no simplication could be -* performed. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Current Frame */ - AstMapping *map; /* Base -> current Mapping */ - AstMapping *result; /* Result pointer to return */ - AstPointSet *mesh; /* Mesh of current Frame positions */ - AstPointSet *ps2; /* Polygon PointSet in current Frame */ - AstPolygon *newpol; /* New Polygon */ - AstRegion *new; /* Pointer to simplified Region */ - AstRegion *this; /* Pointer to supplied Region structure */ - AstRegion *unc; /* Pointer to uncertainty Region */ - double **ptr2; /* Pointer axis values in "ps2" */ - double *mem; /* Pointer to array holding new vertex coords */ - double *p; /* Pointer to next vertex coords */ - double *q; /* Pointer to next vertex coords */ - int iv; /* Vertex index */ - int nv; /* Number of vertices in polygon */ - int ok; /* Are the new polygon vertices good? */ - int simpler; /* Has some simplication taken place? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the supplied Region structure. */ - this = (AstRegion *) this_mapping; - -/* Invoke the parent Simplify method inherited from the Region class. This - will simplify the encapsulated FrameSet and uncertainty Region. */ - new = (AstRegion *) (*parent_simplify)( this_mapping, status ); - -/* Note if any simplification took place. This is assumed to be the case - if the pointer returned by the above call is different to the supplied - pointer. */ - simpler = ( new != this ); - -/* We attempt to simplify the Polygon by re-defining it within its current - Frame. Transforming the Polygon from its base to its current Frame may - result in the region no having the same edges. If required, we test this - by transforming a set of bounds on the Polygon boundary. This can only - be done if the current Frame is 2-dimensional. Also, there is only any - point in doing it if the Mapping from base to current Frame in the - Polygon is not a UnitMap. */ - map = astGetMapping( new->frameset, AST__BASE, AST__CURRENT ); - if( !astIsAUnitMap( map ) && astGetNout( map ) == 2 ) { - -/* Get a pointer to the Frame represented by the Polgon. */ - frm = astGetFrame( new->frameset, AST__CURRENT ); - -/* Get the Region describing the positional uncertainty in this Frame. */ - unc = astGetUncFrm( new, AST__CURRENT ); - -/* Get the positions of the vertices within this Frame. */ - ps2 = astRegTransform( this, this->points, 1, NULL, NULL ); - ptr2 = astGetPoints( ps2 ); - -/* Get the number of vertices. */ - nv = astGetNpoint( ps2 ); - -/* Re-organise the vertex axis values into the form required by the - Polygon constructor function. */ - mem = astMalloc( sizeof( double)*(size_t)( 2*nv ) ); - if( astOK ) { - ok = 1; - p = mem; - q = ptr2[ 0 ]; - for( iv = 0; iv < nv; iv++ ) { - if( ( *(p++) = *(q++) ) == AST__BAD ) ok = 0; - } - q = ptr2[ 1 ]; - for( iv = 0; iv < nv; iv++ ) *(p++) = *(q++); - -/* Create a new Polygon using these transformed vertices. */ - if( ok ) { - newpol = astPolygon( frm, nv, nv, mem, unc, "", status ); - -/* If the SimpVertices attribute is zero, we now check that the - transformation has not bent the edges of the polygon significantly. - If it has, we annul the new Polygon. */ - if( !astGetSimpVertices( this ) ) { - -/* Get a mesh of points covering the Polygon in this Frame. */ - mesh = astRegMesh( new ); - -/* See if all points within the mesh created from the original Polygon fall - on the boundary of the new Polygon, to within the uncertainty of the - Region. If not, annul the new Polgon. */ - if( !astRegPins( newpol, mesh, NULL, NULL ) ) { - newpol = astAnnul( newpol ); - } - -/* Free the mesh. */ - mesh = astAnnul( mesh ); - } - -/* If we still have a new polygon, use the new Polygon in place of the - original Region. */ - if( newpol ) { - (void) astAnnul( new ); - new = (AstRegion *) newpol; - simpler = 1; - } - } - } - -/* Free other resources. */ - frm = astAnnul( frm ); - unc = astAnnul( unc ); - ps2 = astAnnul( ps2 ); - mem = astFree( mem ); - } - map = astAnnul( map ); - -/* If any simplification could be performed, copy Region attributes from - the supplied Region to the returned Region, and return a pointer to it. - If the supplied Region had no uncertainty, ensure the returned Region - has no uncertainty. Otherwise, return a clone of the supplied pointer. */ - if( simpler ){ - astRegOverlay( new, this, 1 ); - result = (AstMapping *) new; - - } else { - new = astAnnul( new ); - result = astClone( this ); - } - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void SmoothPoly( AstPointSet *pset, int boxsize, double strength, - int *status ) { -/* -* Name: -* SmoothPoly - -* Purpose: -* Smoooth a polygon assuming plane geometry. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void SmoothPoly( AstPointSet *pset, int boxsize, double strength, -* int *status ) - -* Class Membership: -* Polygon member function - -* Description: -* This function smooths a polygon, without changing the number of -* vertices. It assumes plane geometry, so should not be used to -* smooth polygons defined within a SkyFrame or CmpFrame. -* -* Each vertex is replaced by a new vertex determined as follows: the -* mean X and Y axis value of the vertices in a section of the polygon -* centred on the vertex being replaced are found (the length of the -* section is given by parameter "boxsize"). The new vertex position -* is then the weighted mean of this mean (X,Y) position and the old -* vertex position. The weight for the mean (X,Y) position is given -* by parameter "strength", and the weight for the old vertex -* position is (1.0 - strength) - -* Parameters: -* pset -* A PointSet holding the polygon vertices. -* boxsize -* Half width of the box filter, given as a number of vertices. -* strength -* The weight to use for the mean (X,Y) position when finding each -* new vertex position. Should be in the range 0.0 to 1.0. A value -* of zero results in no change being made to the polygon. A value -* of 1.0 results in the returned polygon being fully smoothed. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double **ptr; - double *newx; - double *newy; - double *nx; - double *ny; - double *oldx; - double *oldy; - double *ox; - double *oy; - double *px; - double *py; - double *qx; - double *qy; - double a; - double b; - double sx; - double sy; - int half_width; - int i; - int nv; - int top; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the number of vertices. */ - nv = astGetNpoint( pset ); - -/* Get pointers to arrays holding the supplied vertex positions. */ - ptr = astGetPoints( pset ); - oldx = ptr[ 0 ]; - oldy = ptr[ 1 ]; - -/* Allocate arrays to hold the returned vertex positions. */ - newx = astMalloc( nv*sizeof( double ) ); - newy = astMalloc( nv*sizeof( double ) ); - -/* Check these pointers can be used safely. */ - if( astOK ) { - -/* Get weighting factors for the fully smoothed and unsmoothed positions. */ - a = strength; - b = 1.0 - a; - -/* Ensure the box size is sufficiently small for there to be room for - two boxes along the polygon. */ - half_width = nv/4 - 1; - if( boxsize < half_width ) half_width = boxsize; - if( half_width < 1 ) half_width = 1; - -/* Modify the weight for the fully smoothed position to include the - normalisation factor needed to account for the box width. */ - a /= 2*half_width + 1; - -/* Find the sum of the x and y coordinates within a box centred on the - first vertex. This includes vertices from the end of the polygon. */ - px = oldx + 1; - qx = oldx + nv; - sx = (oldx)[ 0 ]; - - py = oldy + 1; - qy = oldy + nv; - sy = (oldy)[ 0 ]; - - for( i = 0; i < half_width; i++ ) { - sx += *(px++) + *(--qx); - sy += *(py++) + *(--qy); - } - -/* Replacing vertices within the first half box will include vertices at - both ends of the polygon. Set up the pointers accordingly, and then - find replacements for each vertex in the first half box.*/ - ox = oldx; - oy = oldy; - nx = newx; - ny = newy; - for( i = 0; i < half_width; i++ ) { - -/* Form the new vertex (x,y) values as the weighted mean of the mean - (x,y) values in the box, and the old (x,y) values. */ - *(nx++) = a*sx + b*( *(ox++) ); - *(ny++) = a*sy + b*( *(oy++) ); - -/* Add in the next vertex X and Y axis values to the running sums, and - remove the position that has now passed out of the box. */ - sx += *(px++) - *(qx++); - sy += *(py++) - *(qy++); - } - -/* Adjust the pointer for the rest of the polygon, up to one half box away - from the end. In this section, the smoothing box does not touch either - end of the polygon. */ - top = nv - half_width - 1; - qx = oldx; - qy = oldy; - for( ; i < top; i++ ){ - -/* Form the new vertex (x,y) values as the weighted mean of the mean - (x,y) values in the box, and the old (x,y) values. */ - *(nx++) = a*sx + b*( *(ox++) ); - *(ny++) = a*sy + b*( *(oy++) ); - -/* Add in the next vertex X and Y axis values to the running sums, and - remove the position that has now passed out of the box. */ - sx += *(px++) - *(qx++); - sy += *(py++) - *(qy++); - } - -/* Now do the last half box (which includes vertices from the start of - the polygon). */ - top = nv; - px = oldx; - py = oldy; - for( ; i < top; i++ ){ - *(nx++) = a*sx + b*( *(ox++) ); - *(ny++) = a*sy + b*( *(oy++) ); - sx += *(px++) - *(qx++); - sy += *(py++) - *(qy++); - } - -/* Replace the data points in the PointSet. */ - ptr[ 0 ] = newx; - ptr[ 1 ] = newy; - oldx = astFree( oldx ); - oldy = astFree( oldy ); - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Polygon member function (over-rides the astTestAttrib protected -* method inherited from the Region class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Polygon's attributes. - -* Parameters: -* this -* Pointer to the Polygon. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPolygon *this; /* Pointer to the Polygon structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Polygon structure. */ - this = (AstPolygon *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* SimpVertices. */ -/* ------------- */ - if ( !strcmp( attrib, "simpvertices" ) ) { - result = astTestSimpVertices( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -/* -* Name: -* TraceEdge - -* Purpose: -* Find a point that is inside the required outline. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* void TraceEdge( value, const array[], -* const int lbnd[ 2 ], const int ubnd[ 2 ], -* int iv0, int ix0, int iy0, int starpix, -* int full, int *status ); - -* Class Membership: -* Polygon member function - -* Description: -* This function forms a polygon enclosing the region of the data -* array specified by and "value". If this polygon contains -* the point "(inx,iny)", then a PointSet is returned holding the -* pixel coordinates of the Polygon vertices. If the polygon -* does not contain "(inx,iny)", a NULL pointer is returned. -* -* Each vertex in the polygon corresponds to a corner of a pixel in -* the data array. - -* Parameters: -* value -* The data value defining valid pixels. -* array -* The data array. -* lbnd -* The lower pixel index bounds of the array. -* ubnd -* The upper pixel index bounds of the array. -* iv0 -* The vector index of a pixel inside the region such that the -* pixel to the right is NOT inside the region. This defines the -* start of the polygon. -* ix0 -* The X pixel index of the pixel specified by "iv0". -* inx -* The X pixel index of a point which must be inside the polygon -* for the polygon to be acceptable. -* iny -* The Y pixel index of a point which must be inside the polygon -* for the polygon to be acceptable. -* starpix -* If non-zero, the usual Starlink definition of pixel coordinate -* is used (integral values at pixel corners). Otherwise, the -* system used by other AST functions such as astResample is used -* (integral values at pixel centres). -* full -* If non-zero, the full polygon is stored. If zero, vertices in the -* middle of straight sections of the Polygon are omitted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a PointSet holding the vertices of the polygon, or -* NULL if the polygon did not contain "(inx,iny)". - -* Notes: -* - must be one of LT, LE, EQ, GE, GT, NE. - - -*/ - -/* Define a macro to implement the function for a specific data - type and operation. */ -#define MAKE_TRACEEDGE(X,Xtype,Oper,OperI) \ -static AstPointSet *TraceEdge##Oper##X( Xtype value, const Xtype array[], \ - const int lbnd[ 2 ], const int ubnd[ 2 ], \ - int iv0, int ix0, int iy0, \ - int starpix, int full, \ - int *status ){ \ -\ -/* Local Variables: */ \ - AstPointSet *result; /* Pointer to text describing oper */ \ - const Xtype *pa; /* Pointer to current valid pixel value */ \ - const Xtype *pb; /* Pointer to neigbouring valid pixel value */ \ - const Xtype *pc; /* Pointer to neigbouring valid pixel value */ \ - double *ptr[ 2 ]; /* PointSet data pointers */ \ - double *xvert; /* Pointer to array holding vertex X axis values */ \ - double *yvert; /* Pointer to array holding vertex Y axis values */ \ - double dx; /* Pertubation in X (pixels) to avoid the pixel edge */ \ - double dy; /* Pertubation in Y (pixels) to avoid the pixel edge */ \ - double xx; /* Pixel X coord at corner */ \ - double yy; /* Pixel Y coord at corner */ \ - int at; /* The pixel corner to draw to */ \ - int done; /* Have we arrived back at the start of the polygon? */ \ - int ii; /* Index of new vertex */ \ - int ix; /* X pixel index of current valid pixel */ \ - int iy; /* Y pixel index of current valid pixel */ \ - int nright; /* Overall number of right hand turns along polygon */ \ - int nvert; /* Number of vertices */ \ - int nx; /* Pixels per row */ \ -\ -/* Initialise */ \ - result = NULL; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -\ -/* Initialise pointers to arrays holding the X and Y pixel coordinates at \ - the vertices of the polygon. */ \ - xvert = NULL; \ - yvert = NULL; \ - nvert = 0; \ -\ -/* Find number of pixels in one row of the array. */ \ - nx = ( ubnd[ 0 ] - lbnd[ 0 ] + 1 ); \ -\ -/* The four corners of a pixel are numbered as follows: 0=bottom left, \ - 1=top left, 2=top right, 3=bottom right. The following algorithm moves \ - along pixel edges, from corner to corner, using the above numbering \ - scheme to identify the corners. We start the polygon by moving from the \ - bottom right to the top right corner of pixel "(ix0,iy0)". */ \ - ix = ix0; \ - iy = iy0; \ - at = 2; \ -\ -/* Store a pointer to the first good pixel value. */ \ - pa = array + ( ix - lbnd[ 0 ] ) + nx*( iy - lbnd[ 1 ] ) ; \ -\ -/* We count the number of times the polygon turns to the right compared \ - to the left. Initialise it to zero. */ \ - nright = 0; \ -\ -/* Loop round tracing out the polygon until we arrive back at the \ - beginning. The Polygon class requires that the inside of the polygon \ - is to the left as we move round the polygon in an anti-clockwise \ - direction. So at each corner, we attempt to move to the next \ - anti-clockwise good pixel corner. */ \ - done = 0; \ - while( !done ) { \ -\ -/* If we have arrived at the bottom left corner of the good pixel, we must \ - have come from the top left corner since all movements around a pixel \ - must be anti-clockwise. */ \ - if( at == 0 ) { \ -\ -/* Note the pixel coordinates at the bottom left corner of the current \ - pixel. */ \ - if( starpix ) { \ - xx = ix - 1.0; \ - yy = iy - 1.0; \ - } else { \ - xx = ix - 0.5; \ - yy = iy - 0.5; \ - } \ -\ -/* Get a pointer to lower left pixel value */ \ - pb = pa - nx - 1; \ -\ -/* Get a pointer to lower mid pixel value. */ \ - pc = pb + 1; \ -\ -/* If the lower left pixel is within the array and meets the validity \ - requirements, move to the left along its top edge. */ \ - if( iy > lbnd[ 1 ] && ix > lbnd[ 0 ] && ISVALID(*pb,OperI,value) ) { \ - nright++; \ - pa = pb; \ - at = 1; \ - ix--; \ - iy--; \ - dx = DELTA; \ - dy = -DELTA; \ -\ -/* Otherwise, if lower mid pixel is good, move down its left edge. */ \ - } else if( iy > lbnd[ 1 ] && ISVALID(*pc,OperI,value) ) { \ - pa = pc; \ - at = 0; \ - iy--; \ - dx = DELTA; \ - dy = 0.0; \ -\ -/* Otherwise, move to the right along the bottom edge of the current pixel. */ \ - } else { \ - nright--; \ - at = 3; \ - dx = DELTA; \ - dy = DELTA; \ - } \ -\ -/* If the polygon bends at this point, or if we will be smoothing the \ - polygon, append the pixel coordinates at this pixel corner to the \ - polygon. */ \ - if( full || pa != pc ) ADD( xx, yy ); \ -\ -/* If we have arrived at the top left corner of the good pixel, we must \ - have come from the top right corner. */ \ - } else if( at == 1 ) { \ -\ -/* Note the pixel coordinates at the top left corner of the current \ - pixel. */ \ - if( starpix ) { \ - xx = ix - 1.0; \ - yy = iy; \ - } else { \ - xx = ix - 0.5; \ - yy = iy + 0.5; \ - } \ -\ -/* Get a pointer to upper left pixel value */ \ - pb = pa + nx - 1; \ -\ -/* Get a pointer to mid left pixel value. */ \ - pc = pa - 1; \ -\ -/* If upper left pixel is good, move up its left edge. */ \ - if( iy < ubnd[ 1 ] && ix > lbnd[ 0 ] && ISVALID(*pb,OperI,value) ) { \ - nright++; \ - pa = pb; \ - at = 2; \ - ix--; \ - iy++; \ - dx = -DELTA; \ - dy = -DELTA; \ -\ -/* Otherwise, if left mid pixel is good, move left along its top edge. */ \ - } else if( ix > lbnd[ 0 ] && ISVALID(*pc,OperI,value) ) { \ - pa = pc; \ - at = 1; \ - ix--; \ - dx = 0.0; \ - dy = -DELTA; \ -\ -/* Otherwise, move down the left edge of the current pixel. */ \ - } else { \ - nright--; \ - at = 0; \ - dx = DELTA; \ - dy = -DELTA; \ - } \ -\ -/* If the polygon bends at this point, or if we will be smoothing the \ - polygon, append the pixel coordinates at this pixel corner to the \ - polygon. */ \ - if( full || pa != pc ) ADD( xx, yy ); \ -\ -/* If we have arrived at the top right corner of the good pixel, we must \ - have come from the bottom right corner. */ \ - } else if( at == 2 ) { \ -\ -/* Note the pixel coordinates at the top right corner of the current \ - pixel. */ \ - if( starpix ) { \ - xx = ix; \ - yy = iy; \ - } else { \ - xx = ix + 0.5; \ - yy = iy + 0.5; \ - } \ -\ -/* Pointer to upper right pixel value */ \ - pb = pa + nx + 1; \ -\ -/* Pointer to top mid pixel value. */ \ - pc = pa + nx; \ -\ -/* If upper right pixel is good, move right along its bottom edge. */ \ - if( iy < ubnd[ 1 ] && ix < ubnd[ 0 ] && ISVALID(*pb,OperI,value) ){ \ - nright++; \ - pa = pb; \ - at = 3; \ - ix++; \ - iy++; \ - dx = -DELTA; \ - dy = DELTA; \ -\ -/* Otherwise, if upper mid pixel is good, move up its right edge. */ \ - } else if( iy < ubnd[ 1 ] && ISVALID(*pc,OperI,value) ) { \ - pa = pc; \ - at = 2; \ - iy++; \ - dx = -DELTA; \ - dy = 0.0; \ -\ -/* Otherwise, move left along the top edge of the current pixel. */ \ - } else { \ - nright--; \ - at = 1; \ - dx = -DELTA; \ - dy = -DELTA; \ - } \ -\ -/* If the polygon bends at this point, or if we will be smoothing the \ - polygon, append the pixel coordinates at this pixel corner to the \ - polygon. */ \ - if( full || pa != pc ) ADD( xx, yy ); \ -\ -/* Arrived at bottom right corner of good pixel from lower left. */ \ - } else { \ -\ -/* Note the pixel coordinates at the bottom right corner of the current \ - pixel. */ \ - if( starpix ) { \ - xx = ix; \ - yy = iy - 1.0; \ - } else { \ - xx = ix + 0.5; \ - yy = iy - 0.5; \ - } \ -\ -/* Pointer to lower right pixel value */ \ - pb = pa - ( nx - 1 ); \ -\ -/* Pointer to mid right pixel value. */ \ - pc = pa + 1; \ -\ -/* If lower right pixel is good, move down its left edge. */ \ - if( iy > lbnd[ 1 ] && ix < ubnd[ 0 ] && ISVALID(*pb,OperI,value) ) { \ - nright++; \ - pa = pb; \ - at = 0; \ - ix++; \ - iy--; \ - dx = DELTA; \ - dy = DELTA; \ -\ -/* Otherwise, if right mid pixel is good, move right along its lower edge. */ \ - } else if( ix < ubnd[ 0 ] && ISVALID(*pc,OperI,value) ) { \ - pa = pc; \ - at = 3; \ - ix++; \ - dx = 0.0; \ - dy = DELTA; \ -\ -/* Otherwise, move up the right edge of the current pixel. */ \ - } else { \ - nright--; \ - at = 2; \ - dx = -DELTA; \ - dy = DELTA; \ - } \ -\ -/* If the polygon bends at this point, or if we will be smoothing the \ - polygon, append the pixel coordinates at this pixel corner to the \ - polygon. */ \ - if( full || pa != pc ) ADD( xx, yy ); \ - } \ -\ -/* If we have arrived back at the start, break out of the loop. */ \ - if( ix == ix0 && iy == iy0 && at == 2 ) done = 1; \ - } \ -\ -/* If we have circled round to the right, the polygon will not enclosed \ - the specified position, so free resources and return a NULL pointer. */ \ - if( nright > 0 ) { \ - xvert = astFree( xvert ); \ - yvert = astFree( yvert ); \ -\ -/* If we have circled round to the left, the polygon will enclose \ - the specified position, so create and return a PointSet. */ \ - } else { \ - result = astPointSet( nvert, 2, " ", status ); \ - ptr[ 0 ] = xvert; \ - ptr[ 1 ] = yvert; \ - astSetPoints( result, ptr ); \ - } \ -\ -/* Annul the returned PointSet if anythign went wrong. */ \ - if( !astOK && result ) result = astAnnul( result ); \ -\ -/* Return the PointSet pointer. */ \ - return result; \ -} - -/* Define a macro to add a vertex position to dynamically allocated - arrays of X and Y positions. We offset the supplied position by - a small fraction of a pixel towards the centre of hte polygon to - avoid placing vertices exactly on the edge, which may cause problems - later for pixels that are on the edge of an area of bad pixel. */ -#define ADD(X,Y) {\ - ii = nvert++; \ - xvert = (double *) astGrow( xvert, nvert, sizeof( double ) ); \ - yvert = (double *) astGrow( yvert, nvert, sizeof( double ) ); \ - if( astOK ) { \ - xvert[ ii ] = (X+dx); \ - yvert[ ii ] = (Y+dy); \ - } \ -} - -/* Define a macro that uses the above macro to to create implementations - of TraceEdge for all operations. */ -#define MAKEALL_TRACEEDGE(X,Xtype) \ -MAKE_TRACEEDGE(X,Xtype,LT,AST__LT) \ -MAKE_TRACEEDGE(X,Xtype,LE,AST__LE) \ -MAKE_TRACEEDGE(X,Xtype,EQ,AST__EQ) \ -MAKE_TRACEEDGE(X,Xtype,NE,AST__NE) \ -MAKE_TRACEEDGE(X,Xtype,GE,AST__GE) \ -MAKE_TRACEEDGE(X,Xtype,GT,AST__GT) - -/* Expand the above macro to generate a function for each required - data type and operation. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKEALL_TRACEEDGE(LD,long double) -#endif -MAKEALL_TRACEEDGE(D,double) -MAKEALL_TRACEEDGE(L,long int) -MAKEALL_TRACEEDGE(UL,unsigned long int) -MAKEALL_TRACEEDGE(I,int) -MAKEALL_TRACEEDGE(UI,unsigned int) -MAKEALL_TRACEEDGE(S,short int) -MAKEALL_TRACEEDGE(US,unsigned short int) -MAKEALL_TRACEEDGE(B,signed char) -MAKEALL_TRACEEDGE(UB,unsigned char) -MAKEALL_TRACEEDGE(F,float) - -/* Undefine the macros. */ -#undef MAKE_TRACEEDGE -#undef MAKEALL_TRACEEDGE - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a Polygon to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* Polygon member function (over-rides the astTransform protected -* method inherited from the Region class). - -* Description: -* This function takes a Polygon and a set of points encapsulated in a -* PointSet and transforms the points by setting axis values to -* AST__BAD for all points which are outside the region. Points inside -* the region are copied unchanged from input to output. - -* Parameters: -* this -* Pointer to the Polygon. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - The forward and inverse transformations are identical for a -* Region. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of axes in the Frame represented by the Polygon. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to base Frame in FrameSet */ - AstLineDef *a; /* Line from inside point to test point */ - AstLineDef *b; /* Polygon edge */ - AstPointSet *in_base; /* PointSet holding base Frame input positions*/ - AstPointSet *result; /* Pointer to output PointSet */ - AstPolygon *this; /* Pointer to Polygon */ - double **ptr_in; /* Pointer to input base Frame coordinate data */ - double **ptr_out; /* Pointer to output current Frame coordinate data */ - double *px; /* Pointer to array of first axis values */ - double *py; /* Pointer to array of second axis values */ - double p[ 2 ]; /* Current test position */ - int closed; /* Is the boundary part of the Region? */ - int i; /* Edge index */ - int icoord; /* Coordinate index */ - int in_region; /* Is the point inside the Region? */ - int ncoord_out; /* No. of current Frame axes */ - int ncross; /* Number of crossings */ - int neg; /* Has the Region been negated? */ - int npoint; /* No. of input points */ - int nv; /* No. of vertices */ - int point; /* Loop counter for input points */ - int pos; /* Is test position in, on, or outside boundary? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the Polygon structure. */ - this = (AstPolygon *) this_mapping; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, - containing a copy of the input PointSet. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* Get the number of points to be transformed. */ - npoint = astGetNpoint( result ); - -/* Get a pointer to the output axis values. */ - ptr_out = astGetPoints( result ); - -/* Find the number of axes in the current Frame. This need not be 2 (the - number of axes in the *base* Frame must be 2 however). */ - ncoord_out = astGetNcoord( result ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* First use the encapsulated FrameSet to transform the supplied positions - from the current Frame in the encapsulated FrameSet (the Frame - represented by the Region), to the base Frame (the Frame in which the - Region is defined). This call also returns a pointer to the base Frame - of the encapsulated FrameSet. Note, the returned pointer may be a - clone of the "in" pointer, and so we must be carefull not to modify the - contents of the returned PointSet. */ - in_base = astRegTransform( this, in, 0, NULL, &frm ); - ptr_in = astGetPoints( in_base ); - -/* Get the number of vertices in the polygon. */ - nv = astGetNpoint( ((AstRegion *) this)->points ); - -/* See if the boundary is part of the Region. */ - closed = astGetClosed( this ); - -/* See if the Region has been negated. */ - neg = astGetNegated( this ); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - px = ptr_in[ 0 ]; - py = ptr_in[ 1 ]; - -/* Loop round each supplied point in the base Frame of the polygon. */ - for ( point = 0; point < npoint; point++, px++, py++ ) { - -/* If the input point is bad, indicate that bad output values should be - returned. */ - if( *px == AST__BAD || *py == AST__BAD ) { - in_region = 0; - -/* Otherwise, we first determine if the point is inside, outside, or on, - the Polygon boundary. Initialially it is unknown. */ - } else { - -/* Ensure cached information is available.*/ - Cache( this, status ); - -/* Create a definition of the line from a point which is inside the - polygon to the supplied point. This is a structure which includes - cached intermediate information which can be used to speed up - subsequent calculations. */ - p[ 0 ] = *px; - p[ 1 ] = *py; - a = astLineDef( frm, this->in, p ); - -/* We now determine the number of times this line crosses the polygon - boundary. Initialise the number of crossings to zero. */ - ncross = 0; - pos = UNKNOWN; - -/* Loop rouind all edges of the polygon. */ - for( i = 0; i < nv; i++ ) { - b = this->edges[ i ]; - -/* If this point is on the current edge, then we need do no more checks - since we know it is either inside or outside the polygon (depending on - whether the polygon is closed or not). */ - if( astLineContains( frm, b, 0, p ) ) { - pos = ON; - break; - -/* Otherwise, see if the two lines cross within their extent. If so, - increment the number of crossings. */ - } else if( astLineCrossing( frm, b, a, NULL ) ) { - ncross++; - } - } - -/* Free resources */ - a = astFree( a ); - -/* If the position is not on the boundary, it is inside the boundary if - the number of crossings is even, and outside otherwise. */ - if( pos == UNKNOWN ) pos = ( ncross % 2 == 0 )? IN : OUT; - -/* Whether the point is in the Region depends on whether the point is - inside the polygon boundary, whether the Polygon has been negated, and - whether the polygon is closed. */ - if( neg ) { - if( pos == IN ) { - in_region = 0; - } else if( pos == OUT ) { - in_region = 1; - } else if( closed ) { - in_region = 1; - } else { - in_region = 0; - } - - } else { - if( pos == IN ) { - in_region = 1; - } else if( pos == OUT ) { - in_region = 0; - } else if( closed ) { - in_region = 1; - } else { - in_region = 0; - } - } - } - -/* If the point is not inside the Region, store bad output values. */ - if( !in_region ) { - for ( icoord = 0; icoord < ncoord_out; icoord++ ) { - ptr_out[ icoord ][ point ] = AST__BAD; - } - } - } - } - -/* Free resources */ - in_base = astAnnul( in_base ); - frm = astAnnul( frm ); - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* SimpVertices - -* Purpose: -* Simplify a Polygon by transforming its vertices? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the behaviour of the -c astSimplify -f AST_SIMPLIFY -* method when applied to a Polygon. The simplified Polygon is created -* by transforming the vertices from the Frame in which the Polygon -* was originally defined into the Frame currently represented by the -* Polygon. If SimpVertices is non-zero (the default) then this -* simplified Polygon is returned without further checks. If SimpVertices -* is zero, a check is made that the edges of the new Polygon do not -* depart significantly from the edges of the original Polygon (as -* determined by the uncertainty associated with the Polygon). This -* could occur, for instance, if the Mapping frrm the original to the -* current Frame is highly non-linear. If this check fails, the -* original unsimplified Polygon is returned without change. - -* Applicability: -* Polygon -* All Polygons have this attribute. - -*att-- -*/ -astMAKE_CLEAR(Polygon,SimpVertices,simp_vertices,-INT_MAX) -astMAKE_GET(Polygon,SimpVertices,int,0,( ( this->simp_vertices != -INT_MAX ) ? - this->simp_vertices : 1 )) -astMAKE_SET(Polygon,SimpVertices,int,simp_vertices,( value != 0 )) -astMAKE_TEST(Polygon,SimpVertices,( this->simp_vertices != -INT_MAX )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Polygon objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Polygon objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstPolygon *out; /* Pointer to output Polygon */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the output Polygon. */ - out = (AstPolygon *) objout; - -/* For safety, first clear any references to the input memory from - the output Polygon. */ - out->edges = NULL; - out->startsat = NULL; - -/* Indicate cached information needs nre-calculating. */ - astResetCache( (AstPolygon *) out ); -} - - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Polygon objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Polygon objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstPointSet *ps; /* Pointer to PointSet inside Region */ - AstPolygon *this; /* Pointer to Polygon */ - int i; /* Index of vertex */ - int istat; /* Original AST error status */ - int nv; /* Number of vertices */ - int rep; /* Original error reporting state */ - -/* Obtain a pointer to the Polygon structure. */ - this = (AstPolygon *) obj; - -/* Annul all resources. */ - ps = ((AstRegion *) this)->points; - if( this->edges && ps ) { - -/* Ensure we get a value for "nv" even if an error has occurred. */ - istat = astStatus; - astClearStatus; - rep = astReporting( 0 ); - - nv = astGetNpoint( ps ); - - astSetStatus( istat ); - astReporting( rep ); - -/* Free the structures holding the edge information. */ - for( i = 0; i < nv; i++ ) { - this->edges[ i ] = astFree( this->edges[ i ] ); - } - this->edges = astFree( this->edges ); - this->startsat = astFree( this->startsat ); - - } -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Polygon objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Polygon class to an output Channel. - -* Parameters: -* this -* Pointer to the Polygon whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPolygon *this; /* Pointer to the Polygon structure */ - int ival; /* Integer attribute value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Polygon structure. */ - this = (AstPolygon *) this_object; - -/* Write out values representing the instance variables for the - Polygon class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* SimpVertices. */ -/* ------------ */ -/* Write out the forward-inverse simplification flag. */ - set = TestSimpVertices( this, status ); - ival = set ? GetSimpVertices( this, status ) : astGetSimpVertices( this ); - astWriteInt( channel, "SimpVT", set, 0, ival, "Simplify by transforming vertices?" ); - -/* A flag indicating the convention used for determining the interior of - the polygon. A zero value indicates that the old AST system is in - use (inside to the left when moving anti-clockwise round the vertices - as viewed from the outside of the celestial sphere). A non-zero value - indicates the STC system is in use (inside to the left when moving - anti-clockwise round the vertices as viewed from the inside of the - celestial sphere). AST currently uses the STC system. */ - astWriteInt( channel, "Order", 1, 0, 1, "Polygon uses STC vertex order convention" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPolygon and astCheckPolygon functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Polygon,Region) -astMAKE_CHECK(Polygon) - -AstPolygon *astPolygon_( void *frame_void, int npnt, int dim, - const double *points, AstRegion *unc, - const char *options, int *status, ...) { -/* -*++ -* Name: -c astPolygon -f AST_POLYGON - -* Purpose: -* Create a Polygon. - -* Type: -* Public function. - -* Synopsis: -c #include "polygon.h" -c AstPolygon *astPolygon( AstFrame *frame, int npnt, int dim, -c const double *points, AstRegion *unc, -c const char *options, ... ) -f RESULT = AST_POLYGON( FRAME, NPNT, DIM, POINTS, UNC, OPTIONS, STATUS ) - -* Class Membership: -* Polygon constructor. - -* Description: -* This function creates a new Polygon object and optionally initialises -* its attributes. -* -* The Polygon class implements a polygonal area, defined by a -* collection of vertices, within a 2-dimensional Frame. The vertices -* are connected together by geodesic curves within the encapsulated Frame. -* For instance, if the encapsulated Frame is a simple Frame then the -* geodesics will be straight lines, but if the Frame is a SkyFrame then -* the geodesics will be great circles. Note, the vertices must be -* supplied in an order such that the inside of the polygon is to the -* left of the boundary as the vertices are traversed. Supplying them -* in the reverse order will effectively negate the polygon. -* -* Within a SkyFrame, neighbouring vertices are always joined using the -* shortest path. Thus if an edge of 180 degrees or more in length is -* required, it should be split into section each of which is less -* than 180 degrees. The closed path joining all the vertices in order -* will divide the celestial sphere into two disjoint regions. The -* inside of the polygon is the region which is circled in an -* anti-clockwise manner (when viewed from the inside of the celestial -* sphere) when moving through the list of vertices in the order in -* which they were supplied when the Polygon was created (i.e. the -* inside is to the left of the boundary when moving through the -* vertices in the order supplied). - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* A pointer to the Frame in which the region is defined. It must -* have exactly 2 axes. A deep copy is taken of the supplied Frame. -* This means that any subsequent changes made to the Frame using the -* supplied pointer will have no effect the Region. -c npnt -f NPNT = INTEGER (Given) -* The number of points in the Region. -c dim -f DIM = INTEGER (Given) -c The number of elements along the second dimension of the "points" -f The number of elements along the first dimension of the POINTS -* array (which contains the point coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -c given should not be less than "npnt". -f given should not be less than NPNT. -c points -f POINTS( DIM, 2 ) = DOUBLE PRECISION (Given) -c The address of the first element of a 2-dimensional array of -c shape "[2][dim]" giving the physical coordinates of the vertices. -c These should be stored such that the value of coordinate -c number "coord" for point number "pnt" is found in element -c "in[coord][pnt]". -f A 2-dimensional array giving the physical coordinates of the -f vertices. These should be stored such that the value of coordinate -f number COORD for point number PNT is found in element IN(PNT,COORD). -c unc -f UNC = INTEGER (Given) -* An optional pointer to an existing Region which specifies the -* uncertainties associated with the boundary of the Polygon being created. -* The uncertainty in any point on the boundary of the Polygon is found by -* shifting the supplied "uncertainty" Region so that it is centred at -* the boundary point being considered. The area covered by the -* shifted uncertainty Region then represents the uncertainty in the -* boundary position. The uncertainty is assumed to be the same for -* all points. -* -* If supplied, the uncertainty Region must be of a class for which -* all instances are centro-symetric (e.g. Box, Circle, Ellipse, etc.) -* or be a Prism containing centro-symetric component Regions. A deep -* copy of the supplied Region will be taken, so subsequent changes to -* the uncertainty Region using the supplied pointer will have no -* effect on the created Polygon. Alternatively, -f a null Object pointer (AST__NULL) -c a NULL Object pointer -* may be supplied, in which case a default uncertainty is used -* equivalent to a box 1.0E-6 of the size of the Polygon being created. -* -* The uncertainty Region has two uses: 1) when the -c astOverlap -f AST_OVERLAP -* function compares two Regions for equality the uncertainty -* Region is used to determine the tolerance on the comparison, and 2) -* when a Region is mapped into a different coordinate system and -* subsequently simplified (using -c astSimplify), -f AST_SIMPLIFY), -* the uncertainties are used to determine if the transformed boundary -* can be accurately represented by a specific shape of Region. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Polygon. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Polygon. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPolygon() -f AST_POLYGON = INTEGER -* A pointer to the new Polygon. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPolygon *new; /* Pointer to new Polygon */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the supplied Frame structure. */ - frame = astCheckFrame( frame_void ); - -/* Initialise the Polygon, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPolygon( NULL, sizeof( AstPolygon ), !class_init, - &class_vtab, "Polygon", frame, npnt, - dim, points, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Polygon's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Polygon. */ - return new; -} - -AstPolygon *astPolygonId_( void *frame_void, int npnt, int dim, - const double *points, void *unc_void, - const char *options, ... ) { -/* -* Name: -* astPolygonId_ - -* Purpose: -* Create a Polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "polygon.h" -* AstPolygon *astPolygonId_( void *frame_void, int npnt, -* int dim, const double *points, void *unc_void, -* const char *options, ... ) - -* Class Membership: -* Polygon constructor. - -* Description: -* This function implements the external (public) interface to the -* astPolygon constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astPolygon_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astPolygon_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astPolygon_. - -* Returned Value: -* The ID value associated with the new Polygon. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPolygon *new; /* Pointer to new Polygon */ - AstRegion *unc; /* Pointer to Region structure */ - va_list args; /* Variable argument list */ - - int *status; /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Frame pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Frame. */ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - -/* Obtain a Region pointer from the supplied "unc" ID and validate the - pointer to ensure it identifies a valid Region . */ - unc = unc_void ? astCheckRegion( astMakePointer( unc_void ) ) : NULL; - -/* Initialise the Polygon, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPolygon( NULL, sizeof( AstPolygon ), !class_init, - &class_vtab, "Polygon", frame, npnt, dim, - points, unc ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Polygon's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Polygon. */ - return astMakeId( new ); -} - - -AstPolygon *astInitPolygon_( void *mem, size_t size, int init, AstPolygonVtab *vtab, - const char *name, AstFrame *frame, int npnt, - int dim, const double *points, AstRegion *unc, int *status ) { -/* -*+ -* Name: -* astInitPolygon - -* Purpose: -* Initialise a Polygon. - -* Type: -* Protected function. - -* Synopsis: -* #include "polygon.h" -* AstPolygon *astInitPolygon( void *mem, size_t size, int init, AstPolygonVtab *vtab, -* const char *name, AstFrame *frame, int npnt, -* int dim, const double *points, AstRegion *unc ) - -* Class Membership: -* Polygon initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Polygon object. It allocates memory (if necessary) to accommodate -* the Polygon plus any additional data associated with the derived class. -* It then initialises a Polygon structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Polygon at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Polygon is to be initialised. -* This must be of sufficient size to accommodate the Polygon data -* (sizeof(Polygon)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Polygon (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Polygon -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Polygon's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Polygon. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* A pointer to the Frame in which the region is defined. -* npnt -* The number of points in the Region. -* dim -* The number of elements along the second dimension of the "points" -* array (which contains the point coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -* given should not be less than "npnt". -* points -* The address of the first element of a 2-dimensional array of -* shape "[2][dim]" giving the physical coordinates of the -* points. These should be stored such that the value of coordinate -* number "coord" for point number "pnt" is found in element -* "in[coord][pnt]". -* unc -* A pointer to a Region which specifies the uncertainty in the -* supplied positions (all points in the new Polygon being -* initialised are assumed to have the same uncertainty). A NULL -* pointer can be supplied, in which case default uncertainties equal -* to 1.0E-6 of the dimensions of the new Polygon's bounding box are -* used. If an uncertainty Region is supplied, it must be either a Box, -* a Circle or an Ellipse, and its encapsulated Frame must be related -* to the Frame supplied for parameter "frame" (i.e. astConvert -* should be able to find a Mapping between them). Two positions -* the "frame" Frame are considered to be co-incident if their -* uncertainty Regions overlap. The centre of the supplied -* uncertainty Region is immaterial since it will be re-centred on the -* point being tested before use. A deep copy is taken of the supplied -* Region. - -* Returned Value: -* A pointer to the new Polygon. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstPolygon *new; /* Pointer to new Polygon */ - AstPointSet *pset; /* Pointer to PointSet holding points */ - const double *q; /* Pointer to next supplied axis value */ - double **ptr; /* Pointer to data in pset */ - double *p; /* Pointer to next PointSet axis value */ - int i; /* Axis index */ - int j; /* Point index */ - int nin; /* No. of axes */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitPolygonVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check the number of axis values per position is correct. */ - nin = astGetNaxes( frame ); - if( nin != 2 ) { - astError( AST__BADIN, "astInitPolygon(%s): The supplied %s has %d " - "axes - polygons must have exactly 2 axes.", status, name, - astGetClass( frame ), nin ); - -/* If so create a PointSet and store the supplied points in it. Check - none are bad. */ - } else { - pset = astPointSet( npnt, 2, "", status ); - ptr = astGetPoints( pset ); - for( i = 0; i < 2 && astOK; i++ ) { - p = ptr[ i ]; - q = points + i*dim; - for( j = 0; j < npnt; j++ ) { - if( (*(p++) = *(q++)) == AST__BAD ) { - astError( AST__BADIN, "astInitPolygon(%s): One or more " - "bad axis values supplied for the vertex " - "number %d.", status, name, j + 1 ); - break; - } - } - } - -/* Initialise a Region structure (the parent class) as the first component - within the Polygon structure, allocating memory if necessary. */ - new = (AstPolygon *) astInitRegion( mem, size, 0, (AstRegionVtab *) vtab, - name, frame, pset, unc ); - if ( astOK ) { - -/* Initialise the Polygon data. */ -/* ------------------------------ */ - new->lbnd[ 0 ] = AST__BAD; - new->ubnd[ 0 ] = AST__BAD; - new->lbnd[ 1 ] = AST__BAD; - new->ubnd[ 1 ] = AST__BAD; - new->simp_vertices = -INT_MAX; - new->edges = NULL; - new->startsat = NULL; - new->totlen = 0.0; - new->acw = 1; - new->stale = 1; - -/* Ensure the vertices are stored such that the unnegated Polygon - represents the inside of the polygon. */ - EnsureInside( new, status ); - -/* If an error occurred, clean up by deleting the new Polygon. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Free resources. */ - pset = astAnnul( pset ); - - } - -/* Return a pointer to the new Polygon. */ - return new; -} - -AstPolygon *astLoadPolygon_( void *mem, size_t size, AstPolygonVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPolygon - -* Purpose: -* Load a Polygon. - -* Type: -* Protected function. - -* Synopsis: -* #include "polygon.h" -* AstPolygon *astLoadPolygon( void *mem, size_t size, AstPolygonVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* Polygon loader. - -* Description: -* This function is provided to load a new Polygon using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Polygon structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Polygon at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the Polygon is to be -* loaded. This must be of sufficient size to accommodate the -* Polygon data (sizeof(Polygon)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Polygon (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Polygon structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPolygon) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Polygon. If this is NULL, a pointer -* to the (static) virtual function table for the Polygon class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Polygon" is used instead. - -* Returned Value: -* A pointer to the new Polygon. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPolygon *new; /* Pointer to the new Polygon */ - int order; /* Is the new (STC) order convention used? */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Polygon. In this case the - Polygon belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPolygon ); - vtab = &class_vtab; - name = "Polygon"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPolygonVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Polygon. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Polygon" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - - new->simp_vertices = astReadInt( channel, "simpvt", -INT_MAX ); - if ( TestSimpVertices( new, status ) ) SetSimpVertices( new, new->simp_vertices, status ); - -/* A flag indicating what order the vertices are stored in. See the Dump - function. */ - order = astReadInt( channel, "order", 0 ); - -/* Initialise other class properties. */ - new->lbnd[ 0 ] = AST__BAD; - new->ubnd[ 0 ] = AST__BAD; - new->lbnd[ 1 ] = AST__BAD; - new->ubnd[ 1 ] = AST__BAD; - new->edges = NULL; - new->startsat = NULL; - new->totlen = 0.0; - new->acw = 1; - new->stale = 1; - -/* If the order in which the vertices were written used the old AST - convention, negate the Polygon so that it is consistent with the - current conevtion (based on STC). */ - if( ! order ) astNegate( new ); - -/* Ensure the vertices are stored such that the unnegated Polygon - represents the inside of the polygon. */ - EnsureInside( new, status ); - -/* If an error occurred, clean up by deleting the new Polygon. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Polygon pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - -AstPolygon *astDownsize_( AstPolygon *this, double maxerr, int maxvert, - int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Polygon,Downsize))( this, maxerr, maxvert, status ); -} - - diff --git a/ast/polygon.h b/ast/polygon.h deleted file mode 100644 index 2cd46b6..0000000 --- a/ast/polygon.h +++ /dev/null @@ -1,353 +0,0 @@ -#if !defined( POLYGON_INCLUDED ) /* Include this file only once */ -#define POLYGON_INCLUDED -/* -*+ -* Name: -* polygon.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Polygon class. - -* Invocation: -* #include "polygon.h" - -* Description: -* This include file defines the interface to the Polygon class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The Polygon class implements a Region which represents a collection -* of points in a Frame. - -* Inheritance: -* The Polygon class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 26-OCT-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "frame.h" /* Coordinate systems */ -#include "region.h" /* Coordinate regions (parent class) */ -#include "timeframe.h" /* For AST__LT definition */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Flags used to indicate how astOutline should define the pixel - region to be outlined. We omit AST__LT here since it is defined in - timeframe.h (with value 11). */ -#define AST__LE 2 -#define AST__EQ 3 -#define AST__GE 4 -#define AST__GT 5 -#define AST__NE 6 - -/* Type Definitions. */ -/* ================= */ -/* Polygon structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstPolygon { - -/* Attributes inherited from the parent class. */ - AstRegion region; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double in[2]; /* A point which is inside the polygon */ - double lbnd[2]; /* Lower axis limits of bounding box */ - double ubnd[2]; /* Upper axis limits of bounding box */ - AstLineDef **edges; /* Cached description of edges */ - double *startsat; /* Perimeter distance to each vertex */ - double totlen; /* Total perimeter distance round polygon */ - int acw; /* Are vertices stored in anti-clockwise order? */ - int stale; /* Is cached information stale? */ - int simp_vertices; /* Simplify by transforming vertices? */ -} AstPolygon; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstPolygonVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstPolygon *(* Downsize)( AstPolygon *, double, int, int * ); - - int (* GetSimpVertices)( AstPolygon *, int * ); - int (* TestSimpVertices)( AstPolygon *, int * ); - void (* ClearSimpVertices)( AstPolygon *, int * ); - void (* SetSimpVertices)( AstPolygon *, int, int * ); - -} AstPolygonVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstPolygonGlobals { - AstPolygonVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 51 ]; -} AstPolygonGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitPolygonGlobals_( AstPolygonGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Polygon) /* Check class membership */ -astPROTO_ISA(Polygon) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstPolygon *astPolygon_( void *, int, int, const double *, AstRegion *, const char *, int *, ...); -#else -AstPolygon *astPolygonId_( void *, int, int, const double *, AstRegion *, const char *, ... )__attribute__((format(printf,6,7))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstPolygon *astInitPolygon_( void *, size_t, int, AstPolygonVtab *, const char *, AstFrame *, int, int, const double *, AstRegion *, int * ); - -/* Vtab initialiser. */ -void astInitPolygonVtab_( AstPolygonVtab *, const char *, int * ); - -/* Loader. */ -AstPolygon *astLoadPolygon_( void *, size_t, AstPolygonVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -AstPolygon *astDownsize_( AstPolygon *, double, int, int * ); - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -AstPolygon *astOutlineLD_( long double, int, const long double[], const int[2], const int[2], double, int, const int[2], int, int * ); -#endif -AstPolygon *astOutlineB_( signed char, int, const signed char[], const int[2], const int[2], double, int, const int[2], int, int * ); -AstPolygon *astOutlineD_( double, int, const double[], const int[2], const int[2], double, int, const int[2], int, int * ); -AstPolygon *astOutlineF_( float, int, const float[], const int[2], const int[2], double, int, const int[2], int, int * ); -AstPolygon *astOutlineI_( int, int, const int[], const int[2], const int[2], double, int, const int[2], int, int * ); -AstPolygon *astOutlineL_( long int, int, const long int[], const int[2], const int[2], double, int, const int[2], int, int * ); -AstPolygon *astOutlineS_( short int, int, const short int[], const int[2], const int[2], double, int, const int[2], int, int * ); -AstPolygon *astOutlineUB_( unsigned char, int, const unsigned char[], const int[2], const int[2], double, int, const int[2], int, int * ); -AstPolygon *astOutlineUI_( unsigned int, int, const unsigned int[], const int[2], const int[2], double, int, const int[2], int, int * ); -AstPolygon *astOutlineUL_( unsigned long int, int, const unsigned long int[], const int[2], const int[2], double, int, const int[2], int, int * ); -AstPolygon *astOutlineUS_( unsigned short int, int, const unsigned short int[], const int[2], const int[2], double, int, const int[2], int, int * ); - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -AstPolygon *astConvexLD_( long double, int, const long double[], const int[2], const int[2], int, int * ); -#endif -AstPolygon *astConvexB_( signed char, int, const signed char[], const int[2], const int[2], int, int * ); -AstPolygon *astConvexD_( double, int, const double[], const int[2], const int[2], int, int * ); -AstPolygon *astConvexF_( float, int, const float[], const int[2], const int[2], int, int * ); -AstPolygon *astConvexI_( int, int, const int[], const int[2], const int[2], int, int * ); -AstPolygon *astConvexL_( long int, int, const long int[], const int[2], const int[2], int, int * ); -AstPolygon *astConvexS_( short int, int, const short int[], const int[2], const int[2], int, int * ); -AstPolygon *astConvexUB_( unsigned char, int, const unsigned char[], const int[2], const int[2], int, int * ); -AstPolygon *astConvexUI_( unsigned int, int, const unsigned int[], const int[2], const int[2], int, int * ); -AstPolygon *astConvexUL_( unsigned long int, int, const unsigned long int[], const int[2], const int[2], int, int * ); -AstPolygon *astConvexUS_( unsigned short int, int, const unsigned short int[], const int[2], const int[2], int, int * ); - -# if defined(astCLASS) /* Protected */ -int astGetSimpVertices_( AstPolygon *, int * ); -int astTestSimpVertices_( AstPolygon *, int * ); -void astClearSimpVertices_( AstPolygon *, int * ); -void astSetSimpVertices_( AstPolygon *, int, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckPolygon(this) astINVOKE_CHECK(Polygon,this,0) -#define astVerifyPolygon(this) astINVOKE_CHECK(Polygon,this,1) - -/* Test class membership. */ -#define astIsAPolygon(this) astINVOKE_ISA(Polygon,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astPolygon astINVOKE(F,astPolygon_) -#else -#define astPolygon astINVOKE(F,astPolygonId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitPolygon(mem,size,init,vtab,name,frame,npnt,indim,points,unc) \ -astINVOKE(O,astInitPolygon_(mem,size,init,vtab,name,frame,npnt,indim,points,unc,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitPolygonVtab(vtab,name) astINVOKE(V,astInitPolygonVtab_(vtab,name,STATUS_PTR)) - -/* Loader. */ -#define astLoadPolygon(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadPolygon_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckPolygon to validate Polygon pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astDownsize(this,maxerr,maxvert) \ -astINVOKE(O,astDownsize_(astCheckPolygon(this),maxerr,maxvert,STATUS_PTR)) - - - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#define astOutlineLD(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineLD_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#endif - -#define astOutlineB(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineB_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#define astOutlineD(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineD_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#define astOutlineF(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineF_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#define astOutlineI(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineI_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#define astOutlineL(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineL_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#define astOutlineS(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineS_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#define astOutlineUB(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineUB_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#define astOutlineUI(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineUI_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#define astOutlineUL(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineUL_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) -#define astOutlineUS(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix) \ -astINVOKE(O,astOutlineUS_(value,oper,array,lbnd,ubnd,maxerr,maxvert,inside,starpix,STATUS_PTR)) - - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#define astConvexLD(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O,astConvexLD_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#endif - -#define astConvexB(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexB_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#define astConvexD(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexD_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#define astConvexF(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexF_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#define astConvexI(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexI_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#define astConvexL(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexL_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#define astConvexS(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexS_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#define astConvexUB(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexUB_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#define astConvexUI(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexUI_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#define astConvexUL(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexUL_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) -#define astConvexUS(value,oper,array,lbnd,ubnd,starpix) \ -astINVOKE(O, astConvexUS_(value,oper,array,lbnd,ubnd,starpix,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astClearSimpVertices(this) \ -astINVOKE(V,astClearSimpVertices_(astCheckPolygon(this),STATUS_PTR)) -#define astGetSimpVertices(this) \ -astINVOKE(V,astGetSimpVertices_(astCheckPolygon(this),STATUS_PTR)) -#define astSetSimpVertices(this,value) \ -astINVOKE(V,astSetSimpVertices_(astCheckPolygon(this),value,STATUS_PTR)) -#define astTestSimpVertices(this) \ -astINVOKE(V,astTestSimpVertices_(astCheckPolygon(this),STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/polymap.c b/ast/polymap.c deleted file mode 100644 index 498000f..0000000 --- a/ast/polymap.c +++ /dev/null @@ -1,6107 +0,0 @@ -/* -*class++ -* Name: -* PolyMap - -* Purpose: -* Map coordinates using polynomial functions. - -* Constructor Function: -c astPolyMap -f AST_POLYMAP - -* Description: -* A PolyMap is a form of Mapping which performs a general polynomial -* transformation. Each output coordinate is a polynomial function of -* all the input coordinates. The coefficients are specified separately -* for each output coordinate. The forward and inverse transformations -* are defined independantly by separate sets of coefficients. If no -* inverse transformation is supplied, the default behaviour is to use -* an iterative method to evaluate the inverse based only on the forward -* transformation (see attribute IterInverse). - -* Inheritance: -* The PolyMap class inherits from the Mapping class. - -* Attributes: -* In addition to those attributes common to all Mappings, every -* PolyMap also has the following attributes: -* -* - IterInverse: Provide an iterative inverse transformation? -* - NiterInverse: Maximum number of iterations for iterative inverse -* - TolInverse: Target relative error for iterative inverse - -* Functions: -c In addition to those functions applicable to all Objects, the -c following functions may also be applied to all Mappings: -f In addition to those routines applicable to all Objects, the -f following routines may also be applied to all Mappings: -* -c - astPolyCoeffs: Retrieve the coefficients of a PolyMap transformation -c - astPolyTran: Fit a PolyMap inverse or forward transformation -f - AST_POLYCOEFFS: Retrieve the coefficients of a PolyMap transformation -f - AST_POLYTRAN: Fit a PolyMap inverse or forward transformation - -* Copyright: -* Copyright (C) 2017 East Asian Observatory. -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2011 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 27-SEP-2003 (DSB): -* Original version. -* 13-APR-2005 (DSB): -* Changed the keys used by the Dump/astLoadPolyMap functions. They -* used to exceed 8 characters and consequently caused problems for -* FitsChans. -* 20-MAY-2005 (DSB): -* Correct the indexing of keywords produced in the Dump function. -* 20-APR-2006 (DSB): -* Guard against undefined transformations in Copy. -* 10-MAY-2006 (DSB): -* Override astEqual. -* 4-JUL-2008 (DSB): -* Fixed loop indexing problems in Equal function. -* 27-MAY-2011 (DSB): -* Added public method astPolyTran. -* 18-JUL-2011 (DSB): -* - Added attributes IterInverse, NiterInverse and TolInverse. -* - Do not report an error if astPolyTran fails to fit an inverse. -* 15-OCT-2011 (DSB): -* Improve argument checking and error reporting in PolyTran -* 8-MAY-2014 (DSB): -* Move to using CMinPack for minimisations. -* 11-NOV-2016 (DSB): -* - Fix bug in MapMerge that could cause a seg fault. It did not -* check that the PolyMap had a defined transformation before accessing -* the transformation's coefficient array. -* - Fix similar bugs in Equal that could cause seg faults. -* 15-MAR-2017 (DSB): -* - Change the GetTranForward and GetTranInverse functions so that they -* take into account the state of the Invert attribute. -* - Improve docs for the IterInverse attribute to explain that the -* inverse transformation replaced is always the original inverse -* transformation, as defined by the arguments supplied to the PolyMap -* constructor, regardless of the state of the Invert attribute. -* 17-MAR-2017 (DSB): -* - Add the astPolyCoeffs method. -* 30-MAR-2017 (DSB): -* Modify the astPolyTran method so that it can be used by the -* ChebyMap class to determine new transformations implemented as -* Chebyshev polynomials. -* 27-JUN-2017 (DSB): -* In SamplePoly1D/2D ensure the final sample on each axis does not -* go above the supplied upper bound. This can happen due to rounding -* error. This is important for ChebyMaps since points outside the -* bounds are set bad when transformed using a ChebyMap, causing NaNs -* to be generated in lmder1 (cminpack minimisation function). -* 3-JUL-2017 (DSB): -* Within FitPoly1D and FitPoly2D, use an initial guess that represents -* a unit mapping between normalised input and output values, rather -* than unnormalised PolyMap values. This is in case the PolyMap being -* fitted includes a change of scale (e.g. the PolyMap input is in "mm" -* but the output is in "rads" and includes some large scaling factor -* to do the conversion). -* 9-JAN-2018 (DSB): -* Correct Transform to take account of AST__BAD coeffs correctly. -* Previously bad coeffs could generate NaN output values. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS PolyMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "cmpmap.h" /* Compound mappings */ -#include "polymap.h" /* Interface definition for this class */ -#include "unitmap.h" /* Unit mappings */ -#include "cminpack/cminpack.h" /* Levenberg - Marquardt minimization */ -#include "pal.h" /* SLALIB function definitions */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(PolyMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(PolyMap,Class_Init) -#define class_vtab astGLOBAL(PolyMap,Class_Vtab) -#define getattrib_buff astGLOBAL(LutMap,GetAttrib_Buff) - -#include - - -#else - -static char getattrib_buff[ 101 ]; - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPolyMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - - - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstPolyMap *astPolyMapId_( int, int, int, const double[], int, const double[], const char *, ... ); - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstPolyMap **GetJacobian( AstPolyMap *, int * ); -static AstPolyMap *PolyTran( AstPolyMap *, int, double, double, int, const double *, const double *, int * ); -static double **SamplePoly1D( AstPolyMap *, int, double **, double, double, int, int *, double[2], int * ); -static double **SamplePoly2D( AstPolyMap *, int, double **, const double *, const double *, int, int *, double[4], int * ); -static double *FitPoly1D( AstPolyMap *, int, int, double, int, double **, double[2], int *, double *, int * ); -static double *FitPoly2D( AstPolyMap *, int, int, double, int, double **, double[4], int *, double *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetObjSize( AstObject *, int * ); -static int GetTranForward( AstMapping *, int * ); -static int GetTranInverse( AstMapping *, int * ); -static int MPFunc1D( void *, int, int, const double *, double *, double *, int, int ); -static int MPFunc2D( void *, int, int, const double *, double *, double *, int, int ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int ReplaceTransformation( AstPolyMap *, int, double, double, int, const double *, const double *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *obj, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void FreeArrays( AstPolyMap *, int, int * ); -static void IterInverse( AstPolyMap *, AstPointSet *, AstPointSet *, int * ); -static void LMFunc1D( const double *, double *, int, int, void * ); -static void LMFunc2D( const double *, double *, int, int, void * ); -static void LMJacob1D( const double *, double *, int, int, void * ); -static void LMJacob2D( const double *, double *, int, int, void * ); -static void PolyPowers( AstPolyMap *, double **, int, const int *, double **, int, int, int * ); -static void StoreArrays( AstPolyMap *, int, int, const double *, int * ); -static void PolyCoeffs( AstPolyMap *, int, int, double *, int *, int * ); -static void FitPoly1DInit( AstPolyMap *, int, double **, AstMinPackData *, double *, int *); -static void FitPoly2DInit( AstPolyMap *, int, double **, AstMinPackData *, double *, int *); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static int GetIterInverse( AstPolyMap *, int * ); -static int TestIterInverse( AstPolyMap *, int * ); -static void ClearIterInverse( AstPolyMap *, int * ); -static void SetIterInverse( AstPolyMap *, int, int * ); - -static int GetNiterInverse( AstPolyMap *, int * ); -static int TestNiterInverse( AstPolyMap *, int * ); -static void ClearNiterInverse( AstPolyMap *, int * ); -static void SetNiterInverse( AstPolyMap *, int, int * ); - -static double GetTolInverse( AstPolyMap *, int * ); -static int TestTolInverse( AstPolyMap *, int * ); -static void ClearTolInverse( AstPolyMap *, int * ); -static void SetTolInverse( AstPolyMap *, double, int * ); - - -/* Member functions. */ -/* ================= */ - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a PolyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PolyMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* PolyMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the PolyMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPolyMap *this; /* Pointer to the PolyMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PolyMap structure. */ - this = (AstPolyMap *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* IterInverse. */ -/* ------------ */ - if ( !strcmp( attrib, "iterinverse" ) ) { - astClearIterInverse( this ); - -/* NiterInverse. */ -/* ------------- */ - } else if ( !strcmp( attrib, "niterinverse" ) ) { - astClearNiterInverse( this ); - -/* TolInverse. */ -/* ----------- */ - } else if ( !strcmp( attrib, "tolinverse" ) ) { - astClearTolInverse( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two PolyMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* PolyMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two PolyMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a PolyMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the PolyMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPolyMap *that; - AstPolyMap *this; - int i, j, k; - int nin; - int nout; - int result; - int tmp; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two PolyMap structures. */ - this = (AstPolyMap *) this_object; - that = (AstPolyMap *) that_object; - -/* Check the second object is a PolyMap. We know the first is a - PolyMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAPolyMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two PolyMaps differ, it may still be possible - for them to be equivalent. First compare the PolyMaps if their Invert - flags are the same. In this case all the attributes of the two PolyMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - -/* Assume they are the same until we find a difference. */ - result = 1; - -/* The "_f" and "_i" suffixes in the PolyMap structure array names refer - to the forward and inverse transformations of the original uninverted - PolyMap. So we need to ensure the "nout" and "nin" values also refer - to the uninverted values. So if the PolyMaps are inverted, swap nout - and nin. */ - if( astGetInvert( this ) ) { - tmp = nin; - nin = nout; - nout = tmp; - } - -/* Check properties of the forward transformation. */ - if( this->ncoeff_f && that->ncoeff_f ) { - for( i = 0; i < nout && result; i++ ) { - if( this->ncoeff_f[ i ] != that->ncoeff_f[ i ] ){ - result = 0; - } - } - } else if( this->ncoeff_f || that->ncoeff_f ) { - result = 0; - } - - if( this->mxpow_f && that->mxpow_f ) { - for( i = 0; i < nout && result; i++ ) { - if( this->mxpow_f[ i ] != that->mxpow_f[ i ] ){ - result = 0; - } - } - } else if( this->mxpow_f || that->mxpow_f ) { - result = 0; - } - - if( this->coeff_f && that->coeff_f ) { - for( i = 0; i < nout && result; i++ ) { - for( j = 0; j < this->ncoeff_f[ i ] && result; j++ ) { - if( !astEQUAL( this->coeff_f[ i ][ j ], - that->coeff_f[ i ][ j ] ) ) { - result = 0; - } - } - } - } else if( this->coeff_f || that->coeff_f ) { - result = 0; - } - - if( this->power_f && that->power_f ) { - for( i = 0; i < nout && result; i++ ) { - for( j = 0; j < this->ncoeff_f[ i ] && result; j++ ) { - for( k = 0; k < nin && result; k++ ) { - if( this->power_f[ i ][ j ][ k ] != - that->power_f[ i ][ j ][ k ] ) { - result = 0; - } - } - } - } - } else if( this->power_f || that->power_f ) { - result = 0; - } - -/* Check properties of the inverse transformation. */ - if( this->ncoeff_i && that->ncoeff_i ) { - for( i = 0; i < nout && result; i++ ) { - if( this->ncoeff_i[ i ] != that->ncoeff_i[ i ] ){ - result = 0; - } - } - } else if( this->ncoeff_i || that->ncoeff_i ) { - result = 0; - } - - if( this->mxpow_i && that->mxpow_i ) { - for( i = 0; i < nout && result; i++ ) { - if( this->mxpow_i[ i ] != that->mxpow_i[ i ] ){ - result = 0; - } - } - } else if( this->mxpow_i || that->mxpow_i ) { - result = 0; - } - - if( this->coeff_f && that->coeff_f ) { - for( i = 0; i < nout && result; i++ ) { - for( j = 0; j < this->ncoeff_f[ i ] && result; j++ ) { - if( !astEQUAL( this->coeff_f[ i ][ j ], - that->coeff_f[ i ][ j ] ) ) { - result = 0; - } - } - } - } else if( this->coeff_f || that->coeff_f ) { - result = 0; - } - - if( this->power_f && that->power_f ) { - for( i = 0; i < nout && result; i++ ) { - for( j = 0; j < this->ncoeff_f[ i ] && result; j++ ) { - for( k = 0; k < nin && result; k++ ) { - if( this->power_f[ i ][ j ][ k ] != - that->power_f[ i ][ j ][ k ] ) { - result = 0; - } - } - } - } - } else if( this->power_f || that->power_f ) { - result = 0; - } - -/* If the Invert flags for the two PolyMaps differ, the attributes of the two - PolyMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a PolyMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static double *FitPoly1D( AstPolyMap *this, int forward, int nsamp, double acc, - int order, double **table, double scales[2], int *ncoeff, - double *racc, int *status ){ -/* -* Name: -* FitPoly1D - -* Purpose: -* Fit a (1-in,1-out) polynomial to a supplied set of data. - -* Type: -* Private function. - -* Synopsis: -* double *FitPoly1D( AstPolyMap *this, int forward, int nsamp, double acc, -* int order, double **table, double scales[2], int *ncoeff, -* double *racc, int *status ) - -* Description: -* This function fits a least squares 1D polynomial curve to the -* positions in a supplied table, and returns the coefficients of a -* PolyMap to describe the fit. For the purposes of this function, -* the input to the fit is refered to as x1 and the output as y1. So -* the returned coefficients describe a PolyMap with forward -* transformation: -* -* y1 = P1( x1 ) - -* Parameters: -* this -* Pointer to the PolyMap. -* forward -* Non-zero if the forward transformation of "this" is being -* replaced. Zero if the inverse transformation of "this" is being -* replaced. -* nsamp -* The number of (x1,y1) positions in the supplied table. -* acc -* The required accuracy, expressed as a geodesic distance within -* the polynomials output space (not the normalised tabular space). -* order -* The maximum power (plus one) of x1 within P1. So for instance, a -* value of 3 refers to a quadratic polynomial. -* table -* Pointer to an array of 2 pointers. Each of these pointers points -* to an array of "nsamp" doubles, being the normalised and sampled -* values for x1 and y1 in that order. -* scales -* Array holding the scaling factors used to produced the normalised -* values in the two columns of the table. Multiplying the normalised -* table values by the scale factor produces input or output axis -* values for the returned PolyMap -* ncoeff -* Pointer to an int in which to return the number of coefficients -* described by the returned array. -* racc -* Pointer to a double in which to return the achieved accuracy -* (which may be greater than "acc"). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to an array of doubles defining the polynomial in the -* form required by the PolyMap contructor. The number of coefficients -* is returned via "ncoeff". If the polynomial could not be found, -* then NULL is returned. The returned pointer should be freed using -* astFree when no longer needed. - -*/ - -/* Local Variables: */ - AstMinPackData data; - double *coeffs; - double *pc; - double *pr; - double *pxp1; - double *result; - double *work1; - double *work2; - double *work4; - double f1; - double f2; - double maxterm; - double term; - double tv; - int *work3; - int info; - int k; - int ncof; - int w1; - -/* Initialise returned value */ - result = NULL; - *ncoeff = 0; - *racc = 10*acc; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Number of coefficients per poly. */ - ncof = order; - -/* Initialise the elements of the structure. */ - data.order = order; - data.nsamp = nsamp; - data.init_jac = 1; - data.xp1 = astMalloc( nsamp*order*sizeof( double ) ); - data.xp2 = NULL; - data.y[ 0 ] = table[ 1 ]; - data.y[ 1 ] = NULL; - -/* Work space to hold coefficients. */ - coeffs = astMalloc( ncof*sizeof( double ) ); - -/* Other work space. */ - work1 = astMalloc( nsamp*sizeof( double ) ); - work2 = astMalloc( ncof*nsamp*sizeof( double ) ); - work3 = astMalloc( ncof*sizeof( int ) ); - work4 = astMalloc( (5*ncof+nsamp)*sizeof( double ) ); - if( astOK ) { - -/* Find all the required powers of x1 and store them in the "xp1" - component of the data structure. The required initialisation is done - differently for different subclasses of PolyMap, so we need to wrap - it up in a virtual function. */ - astFitPoly1DInit( this, forward, table, &data, scales ); - -/* The initial guess at the coefficient values represents a unit - transformation in (normalised) tabulated (x,y) values. Using normalised - values means that we are, effectively, including a guess at the linear - scaling factor between input and output of the PolyMap (e.g. the PolyMap - may have inputs in mm and outputs in radians). */ - for( k = 0; k < ncof; k++ ) coeffs[ k ] = 0.0; - coeffs[ 1 ] = 1.0; - -/* Find the best coefficients */ - info = lmder1( MPFunc1D, &data, nsamp, ncof, coeffs, work1, work2, nsamp, - sqrt(DBL_EPSILON), work3, work4, (5*ncof+nsamp) ); - if( info == 0 ) astError( AST__MNPCK, "astPolyMap(PolyTran): Minpack error " - "detected (possible programming error).", status ); - -/* Return the achieved accuracy. The "work1" array holds the normalised Y - residuals at each tabulated point. */ - pr = work1; - tv = 0.0; - for( k = 0; k < nsamp; k++,pr++ ) tv += (*pr)*(*pr); - *racc = scales[ 1 ]*sqrt( tv/nsamp ); - -/* The best fitting polynomial coefficient found above relate to the - polynomial between the scaled positions stored in "table". These - scaled positions are related to PolyMap input/output axis values via - the scale factors supplied in "scales". Find the initial factor for the - current output. */ - f1 = scales[ 1 ]; - f2 = 1.0; - -/* Look at each coefficient. */ - pc = coeffs; - for( w1 = 0; w1 < order; w1++,pc++ ) { - -/* Get a pointer to the powers of X1 appropriate for the current coefficient, - at the first sample. */ - pxp1 = data.xp1 + w1; - -/* We find the contribution which this coefficient makes to the total - polynomial value. Find the maximum contribution made at any sample - points. */ - maxterm = 0.0; - for( k = 0; k < nsamp; k++ ) { - -/* Get the absolute value of the polynomial term that uses the current - coefficient. */ - term = fabs( ( *pc )*( *pxp1 ) ); - -/* Update the maximum term found at any sample. */ - if( term > maxterm ) maxterm = term; - -/* Increment the pointers to refer to the next sample. */ - pxp1 += order; - } - -/* If the maximum contribution made by this term is less than the - required accuracy, set the coefficient value to zero. */ - if( maxterm*f1 < acc ) { - *pc = 0.0; - -/* Scale the best fitting polynomial coefficient found above to take - account of the fact that the tabulated input and output positions in - "table" were are not actual PolyMap input and output axis values, but - are scaled by the factors stored in "scales". */ - } else { - *pc *= f1/f2; - } - - f2 *= scales[ 0 ]; - } - -/* Convert the array of coefficients into PolyMap form. */ - result = astMalloc( ncof*3*sizeof( double ) ); - - *ncoeff = 0; - pr = result; - pc = coeffs; - for( w1 = 0; w1 < order; w1++,pc++ ) { - if( *pc != 0.0 ) { - *(pr++) = *pc; - *(pr++) = 1; - *(pr++) = w1; - (*ncoeff)++; - } - } - -/* Truncate the returned array. */ - result = astRealloc( result, (*ncoeff)*3*sizeof( double ) ); - } - -/* Free resources. */ - coeffs = astFree( coeffs ); - data.xp1 = astFree( data.xp1 ); - work1 = astFree( work1 ); - work2 = astFree( work2 ); - work3 = astFree( work3 ); - work4 = astFree( work4 ); - -/* Return the coefficient array. */ - return result; - -} - -static void FitPoly1DInit( AstPolyMap *this, int forward, double **table, - AstMinPackData *data, double *scales, int *status ){ -/* -*+ -* Name: -* astFitPoly1DInit - -* Purpose: -* Perform initialisation needed for FitPoly1D - -* Type: -* Protected function. - -* Synopsis: -* #include "polymap.h" -* void astFitPoly1DInit( AstPolyMap *this, int forward, double **table, -* AstMinPackData *data, double *scales, -* int *status ) - -* Class Membership: -* PolyMap virtual function. - -* Description: -* This function performs initialisation needed for FitPoly1D. - -* Parameters: -* this -* Pointer to the PolyMap. -* forward -* Non-zero if the forward transformation of "this" is being -* replaced. Zero if the inverse transformation of "this" is being -* replaced. -* table -* Pointer to an array of 2 pointers. Each of these pointers points -* to an array of "nsamp" doubles, being the scaled and sampled values -* for x1 and y1 in that order. -* data -* Pointer to a structure holding information to pass the the -* service function invoked by the minimisation function. -* scales -* Array holding the scaling factors for the two columns of the table. -* Multiplying the table values by the scale factor produces PolyMap -* input or output axis values. -*- -*/ - -/* Local Variables; */ - double *px1; - double *pxp1; - double tv; - double x1; - int k; - int w1; - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get pointers to the supplied x1 values. */ - px1 = table[ 0 ]; - -/* Get pointers to the location for the next power of x1. */ - pxp1 = data->xp1; - -/* Loop round all samples. */ - for( k = 0; k < data->nsamp; k++ ) { - -/* Get the current x1 value. */ - x1 = *(px1++); - -/* Find all the required powers of x1 and store them in the "xp1" - component of the data structure. */ - tv = 1.0; - for( w1 = 0; w1 < data->order; w1++ ) { - *(pxp1++) = tv; - tv *= x1; - } - } -} - -static double *FitPoly2D( AstPolyMap *this, int forward, int nsamp, double acc, - int order, double **table, double scales[4], - int *ncoeff, double *racc, int *status ){ -/* -* Name: -* FitPoly2D - -* Purpose: -* Fit a (2-in,2-out) polynomial to a supplied set of data. - -* Type: -* Private function. - -* Synopsis: -* double *FitPoly2D( AstPolyMap *this, int forward, int nsamp, double acc, -* int order, double **table, double scales[4], -* int *ncoeff, double *racc, int *status ) - -* Description: -* This function fits a pair of least squares 2D polynomial surfaces -* to the positions in a supplied table, and returns the coefficients -* of a PolyMap to describe the fit. For the purposes of this function, -* the inputs to the fit is refered to as (x1,x2) and the output as -* (y1,y2). So the returned coefficients describe a PolyMap with forward -* transformations: -* -* y1 = P1( x1, x2 ) -* y2 = P2( x1, x2 ) -* -* P1 and P2 have the same maximum power on each input (specified by -* the "order" parameter). - -* Parameters: -* this -* Pointer to the PolyMap. -* forward -* Non-zero if the forward transformation of "this" is being -* replaced. Zero if the inverse transformation of "this" is being -* replaced. -* nsamp -* The number of (x1,x2,y1,y2) positions in the supplied table. -* acc -* The required accuracy, expressed as a geodesic distance within -* the polynomials output space (not the normalised tabular space). -* order -* The maximum power (plus one) of x1 or x2 within P1 and P2. So for -* instance, a value of 3 refers to a quadratic polynomial. Note, cross -* terms with total powers greater than or equal to "order" are not -* included in the fit. So the maximum number of terms in the fitted -* polynomial is order*(order+1)/2. -* table -* Pointer to an array of 4 pointers. Each of these pointers points -* to an array of "nsamp" doubles, being the normalised and sampled -* values for x1, x2, y1 or y2 in that order. -* scales -* Array holding the scaling factors used to produced the normalised -* values in the four columns of the table. Multiplying the normalised -* table values by the scale factor produces input or output axis -* values for the returned PolyMap -* ncoeff -* Pointer to an ant in which to return the number of coefficients -* described by the returned array. -* racc -* Pointer to a double in which to return the achieved accuracy -* (which may be greater than "acc"). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to an array of doubles defining the polynomial in the -* form required by the PolyMap contructor. The number of coefficients -* is returned via "ncoeff". If the polynomial could not be found with -* sufficient accuracy , then NULL is returned. The returned pointer -* should be freed using astFree when no longer needed. - -*/ - -/* Local Variables: */ - AstMinPackData data; - double *coeffs; - double *pc; - double *pr; - double *pxp1; - double *pxp2; - double *result; - double *work1; - double *work2; - double *work4; - double f1; - double f20; - double f2; - double f3; - double facc; - double maxterm; - double term; - double tv; - int *work3; - int info; - int iout; - int k; - int ncof; - int w12; - int w1; - int w2; - -/* Initialise returned value */ - result = NULL; - *ncoeff = 0; - *racc = 10*acc; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Number of coefficients per poly. */ - ncof = order*( order + 1 )/2; - -/* Initialise the elements of the structure. */ - data.order = order; - data.nsamp = nsamp; - data.init_jac = 1; - data.xp1 = astMalloc( nsamp*order*sizeof( double ) ); - data.xp2 = astMalloc( nsamp*order*sizeof( double ) ); - data.y[ 0 ] = table[ 2 ]; - data.y[ 1 ] = table[ 3 ]; - -/* Work space to hold coefficients. */ - coeffs = astMalloc( 2*ncof*sizeof( double ) ); - -/* Other work space. */ - work1 = astMalloc( 2*nsamp*sizeof( double ) ); - work2 = astMalloc( 4*ncof*nsamp*sizeof( double ) ); - work3 = astMalloc( 2*ncof*sizeof( int ) ); - work4 = astMalloc( 2*(5*ncof+nsamp)*sizeof( double ) ); - if( astOK ) { - -/* Find all the required powers of x1 and x2 and store them in the "xp1" - and "xp2" components of the data structure. The required initialisation - is done differently for different subclasses of PolyMap, so we need to - wrap it up in a virtual function. */ - astFitPoly2DInit( this, forward, table, &data, scales ); - -/* The initial guess at the coefficient values represents a unit - transformation in (normalised) tabulated (x,y) values. Using normalised - values means that we are, effectively, including a guess at the linear - scaling factor between input and output of the PolyMap (e.g. the PolyMap - may have inputs in mm and outputs in radians). */ - for( k = 0; k < 2*ncof; k++ ) coeffs[ k ] = 0.0; - coeffs[ 1 ] = 1.0; - coeffs[ 5 ] = 1.0; - -/* Find the best coefficients */ - info = lmder1( MPFunc2D, &data, 2*nsamp, 2*ncof, coeffs, work1, work2, - 2*nsamp, sqrt(DBL_EPSILON), work3, work4, 2*(5*ncof+nsamp) ); - if( info == 0 ) astError( AST__MNPCK, "astPolyMap(PolyTran): Minpack error " - "detected (possible programming error).", status ); - -/* Return the achieved accuracy. */ - pr = work1; - tv = 0.0; - for( k = 0; k < 2*nsamp; k++,pr++ ) tv += (*pr)*(*pr); - facc = 1.0/(scales[2]*scales[2]) + 1.0/(scales[3]*scales[3]); - *racc = sqrt( tv/(2*nsamp*facc) ); - -/* Pointer to the first coefficient. */ - pc = coeffs; - -/* Look at coefficients for each output in turn. */ - for( iout = 0; iout < 2 && astOK; iout++ ) { - -/* The best fitting polynomial coefficient found above relate to the - polynomial between the scaled positions stored in "table". These - scaled positions are related to PolyMap input/output axis values via - the scale factors supplied in "scales". Find the initial factor for the - current output. */ - f1 = scales[ 2 + iout ]; - -/* Look at each coefficient for the current output. */ - f20 = 1.0; - for( w12 = 0; w12 < order; w12++ ) { - f3 = 1.0; - f2 = f20; - for( w2 = 0; w2 <= w12; w2++,pc++ ) { - w1 = w12 - w2; - -/* Get pointers to the powers of X1 and X2 appropriate for the current - coefficient, at the first sample. */ - pxp1 = data.xp1 + w1; - pxp2 = data.xp2 + w2; - -/* We find the contribution which this coefficient makes to the total - polynomial value. Find the maximum contribution made at any sample - points. */ - maxterm = 0.0; - for( k = 0; k < nsamp; k++ ) { - -/* Get the absolute value of the polynomial term that uses the current - coefficient. */ - term = fabs( ( *pc )*( *pxp1 )*( *pxp2 ) ); - -/* Update the maximum term found at any sample. */ - if( term > maxterm ) maxterm = term; - -/* Increment the pointers to refer to the next sample. */ - pxp1 += order; - pxp2 += order; - } - -/* If the maximum contribution made by this term is less than the - required accuracy, set the coefficient value to zero. */ - if( maxterm*f1 < acc ) { - *pc = 0.0; - -/* Scale the best fitting polynomial coefficient found above to take - account of the fact that the tabulated input and output positions in - "table" were are not actual PolyMap input and output axis values, but - are scaled by the factors stored in "scales". */ - } else { - *pc *= f1/( f2*f3 ); - } - - f2 /= scales[ 0 ]; - f3 *= scales[ 1 ]; - } - - f20 *= scales[ 0 ]; - } - } - -/* Convert the array of coefficients into PolyMap form. */ - result = astMalloc( 2*ncof*4*sizeof( double ) ); - - *ncoeff = 0; - pr = result; - pc = coeffs; - for( iout = 0; iout < 2 && astOK; iout++ ) { - for( w12 = 0; w12 < order; w12++ ) { - for( w2 = 0; w2 <= w12; w2++,pc++ ) { - w1 = w12 - w2; - if( *pc != 0.0 ) { - *(pr++) = *pc; - *(pr++) = iout + 1; - *(pr++) = w1; - *(pr++) = w2; - (*ncoeff)++; - } - } - } - } - -/* Truncate the returned array. */ - result = astRealloc( result, (*ncoeff)*4*sizeof( double ) ); - } - -/* Free resources. */ - coeffs = astFree( coeffs ); - data.xp1 = astFree( data.xp1 ); - data.xp2 = astFree( data.xp2 ); - work1 = astFree( work1 ); - work2 = astFree( work2 ); - work3 = astFree( work3 ); - work4 = astFree( work4 ); - -/* Return the coefficient array. */ - return result; - -} - -static void FitPoly2DInit( AstPolyMap *this, int forward, double **table, - AstMinPackData *data, double *scales, int *status ){ -/* -*+ -* Name: -* astFitPoly2DInit - -* Purpose: -* Perform initialisation needed for FitPoly2D - -* Type: -* Protected function. - -* Synopsis: -* #include "polymap.h" -* void astFitPoly2DInit( AstPolyMap *this, int forward, double **table, -* AstMinPackData *data, double *scales, -* int *status ) - -* Class Membership: -* PolyMap virtual function. - -* Description: -* This function performs initialisation needed for FitPoly2D. - -* Parameters: -* this -* Pointer to the PolyMap. -* forward -* Non-zero if the forward transformation of "this" is being -* replaced. Zero if the inverse transformation of "this" is being -* replaced. -* table -* Pointer to an array of 4 pointers. Each of these pointers points -* to an array of "nsamp" doubles, being the scaled and sampled values -* for x1, x2, y1 or y2 in that order. -* data -* Pointer to a structure holding information to pass the the -* service function invoked by the minimisation function. -* scales -* Array holding the scaling factors for the four columns of the table. -* Multiplying the table values by the scale factor produces PolyMap -* input or output axis values. -*- -*/ - -/* Local Variables; */ - double *px1; - double *px2; - double *pxp1; - double *pxp2; - double tv; - double x1; - double x2; - int k; - int w1; - int w2; - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get pointers to the supplied x1 and x2 values. */ - px1 = table[ 0 ]; - px2 = table[ 1 ]; - -/* Get pointers to the location for the next power of x1 and x2. */ - pxp1 = data->xp1; - pxp2 = data->xp2; - -/* Loop round all samples. */ - for( k = 0; k < data->nsamp; k++ ) { - -/* Get the current x1 and x2 values. */ - x1 = *(px1++); - x2 = *(px2++); - -/* Find all the required powers of x1 and store them in the "xp1" - component of the data structure. */ - tv = 1.0; - for( w1 = 0; w1 < data->order; w1++ ) { - *(pxp1++) = tv; - tv *= x1; - } - -/* Find all the required powers of x2 and store them in the "xp2" - comonent of the data structure. */ - tv = 1.0; - for( w2 = 0; w2 < data->order; w2++ ) { - *(pxp2++) = tv; - tv *= x2; - } - } -} - -static void FreeArrays( AstPolyMap *this, int forward, int *status ) { -/* -* Name: -* FreeArrays - -* Purpose: -* Free the dynamic arrays contained within a PolyMap - -* Type: -* Private function. - -* Synopsis: -* void FreeArrays( AstPolyMap *this, int forward, int *status ) - -* Description: -* This function frees all the dynamic arrays allocated as part of a -* PolyMap. - -* Parameters: -* this -* Pointer to the PolyMap. -* forward -* If non-zero, the arrays for the forward transformation are freed. -* Otherwise, the arrays for the inverse transformation are freed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - int nin; /* Number of inputs */ - int nout; /* Number of outputs */ - int i; /* Loop count */ - int j; /* Loop count */ - -/* Get the number of inputs and outputs of the uninverted Mapping. */ - nin = ( (AstMapping *) this )->nin; - nout = ( (AstMapping *) this )->nout; - -/* Free the dynamic arrays for the forward transformation. */ - if( forward ) { - - if( this->coeff_f ) { - for( i = 0; i < nout; i++ ) { - this->coeff_f[ i ] = astFree( this->coeff_f[ i ] ); - } - this->coeff_f = astFree( this->coeff_f ); - } - - if( this->power_f ) { - for( i = 0; i < nout; i++ ) { - if( this->ncoeff_f && this->power_f[ i ] ) { - for( j = 0; j < this->ncoeff_f[ i ]; j++ ) { - this->power_f[ i ][ j ] = astFree( this->power_f[ i ][ j ] ); - } - } - this->power_f[ i ] = astFree( this->power_f[ i ] ); - } - this->power_f = astFree( this->power_f ); - } - - this->ncoeff_f = astFree( this->ncoeff_f ); - this->mxpow_f = astFree( this->mxpow_f ); - -/* Free the dynamic arrays for the inverse transformation. */ - } else { - - if( this->coeff_i ) { - for( i = 0; i < nin; i++ ) { - this->coeff_i[ i ] = astFree( this->coeff_i[ i ] ); - } - this->coeff_i = astFree( this->coeff_i ); - } - - if(this->power_i ) { - for( i = 0; i < nin; i++ ) { - if( this->ncoeff_i && this->power_i[ i ] ) { - for( j = 0; j < this->ncoeff_i[ i ]; j++ ) { - this->power_i[ i ][ j ] = astFree( this->power_i[ i ][ j ] ); - } - } - this->power_i[ i ] = astFree( this->power_i[ i ] ); - } - this->power_i = astFree( this->power_i ); - } - - this->ncoeff_i = astFree( this->ncoeff_i ); - this->mxpow_i = astFree( this->mxpow_i ); - } -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a PolyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PolyMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a PolyMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the PolyMap. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the PolyMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the PolyMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPolyMap *this; /* Pointer to the PolyMap structure */ - const char *result; /* Pointer value to return */ - double dval; /* Floating point attribute value */ - int ival; /* Integer attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the PolyMap structure. */ - this = (AstPolyMap *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* IterInverse. */ -/* ------------ */ - if ( !strcmp( attrib, "iterinverse" ) ) { - ival = astGetIterInverse( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* NiterInverse. */ -/* ------------- */ - } else if ( !strcmp( attrib, "niterinverse" ) ) { - ival = astGetNiterInverse( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TolInverse. */ -/* ----------- */ - } else if ( !strcmp( attrib, "tolinverse" ) ) { - dval = astGetTolInverse( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; - -} - -static AstPolyMap **GetJacobian( AstPolyMap *this, int *status ){ -/* -* Name: -* GetJacobian - -* Purpose: -* Get a description of a Jacobian matrix for the fwd transformation -* of a PolyMap. - -* Type: -* Private function. - -* Synopsis: -* AstPolyMap **GetJacobian( AstPolyMap *this, int *status ) - -* Description: -* This function returns a set of PolyMaps which define the Jacobian -* matrix of the forward transformation of the supplied PolyMap. -* -* The Jacobian matrix has "nout" rows and "nin" columns, where "nin" -* and "nout" are the number of inputs and outputs of the supplied PolyMap. -* Row "i", column "j" of the matrix holds the rate of change of the -* i'th PolyMap output with respect to the j'th PolyMap input. -* -* Since the values in the Jacobian matrix vary across the input space -* of the PolyMap, the matrix is returned in the form of a set of new -* PolyMaps which generate the elements of the Jacobian for any given -* position in the input space. The "nout" values in a single column of -* the Jacobian matrix are generated by the "nout" outputs from a single -* new PolyMap. The whole matrix is described by "nin" PolyMaps. -* -* The returned PolyMaps are cached in the supplied PolyMap object in -* order to speed up subsequent calls to this function. - -* Parameters: -* this -* The PolyMap for which the Jacbian is required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to an array of "nin" PolyMap pointers, where "nin" is the number -* of inputs for the sipplied PolyMap. The returned array should not be changed -* in any way, and the PolyMaps should not be freed (they will be freed when -* the supplied PolyMap is deleted). - -*/ - -/* Local Variables: */ - double *coeffs; - double *pc; - int icof; - int icol; - int iin; - int irow; - int ncof; - int ncof_row; - int ncof_total; - int nin; - int nout; - int power; - -/* Check inherited status */ - if( !astOK ) return NULL; - -/* Ensure there is a Jacobian stored in the PolyMap. */ - if( !this->jacobian ) { - -/* Get the number of inputs and outputs. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - -/* Allocate memory to hold pointers to the PolyMaps used to describe the - Jacobian matrix. */ - this->jacobian = astCalloc( nin, sizeof(AstPolyMap *) ); - -/* Find the total number of coefficients used to describe the supplied - PolyMap (forward transformation) and allocate work space to hold the - coefficients for a single new PolyMap forward transformation. */ - ncof = 0; - for( irow = 0; irow < nout; irow++ ) { - ncof += this->ncoeff_f[ irow ]; - } - coeffs = astMalloc( ncof*( 2 + nin )*sizeof( double ) ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* The Jacobian matrix has "nout" rows and "nin" columns. The "nout" values - in a single column of the Jacobian matrix corresponds to the "nout" outputs - from a single PolyMap. The whole matrix is described by "nin" PolyMaps. - Loop over each column of the Matrix, creating the corresponding PolyMap - for each. */ - for( icol = 0; icol < nin; icol++ ) { - -/* Initialise the total number of coefficients used to describe the - element of the PolyMap. */ - ncof_total = 0; - -/* Loop over each row of the Jacobian matrix (i.e. each PolyMap output). */ - pc = coeffs; - for( irow = 0; irow < nout; irow++ ) { - -/* Loop over each coefficient used in the polynomial that generates the - current PolyMap output. */ - ncof_row = this->ncoeff_f[ irow ]; - for( icof = 0; icof < ncof_row; icof++ ) { - -/* Get the power of input "icol" associated with the current coefficient. */ - power = (int)( this->power_f[ irow ][ icof ][ icol ] + 0.5 ); - -/* We can skip the coefficient if the power is zero. */ - if( power > 0 ) { - ncof_total++; - -/* Store the coefficient value, modified so that it describes a - polynomial that has been differentiated with respect to input "icol". */ - *(pc++) = this->coeff_f[ irow ][ icof ]*power; - -/* Store the output PolyMap to which the coeff relates. */ - *(pc++) = irow + 1; - -/* Store the powers of the inputs associated with the coeff. These are - the same as the original powers, except that the power of "icol" - (the input with respect to which the output has been differentiated) - is reduced by one. */ - for( iin = 0; iin < nin; iin++ ) { - if( iin != icol ) { - *(pc++) = this->power_f[ irow ][ icof ][ iin ]; - } else { - *(pc++) = this->power_f[ irow ][ icof ][ iin ] - 1; - } - } - } - } - } - -/* Create the PolyMap and store a pointer to it in the jacobian array in - the supplied PolyMap. */ - (this->jacobian)[ icol ] = astPolyMap( nin, nout, ncof_total, coeffs, - 0, NULL, " ", status ); - } - } - -/* Free resources */ - coeffs = astFree( coeffs ); - } - -/* Return the Jacobian. */ - return this->jacobian; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* PolyMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied PolyMap, -* in bytes. - -* Parameters: -* this -* Pointer to the PolyMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPolyMap *this; - int ic; - int nc; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the PolyMap structure. */ - this = (AstPolyMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - if( this->jacobian ) { - nc = astGetNin( this ); - for( ic = 0; ic < nc; ic++ ) { - result += astGetObjSize( (this->jacobian)[ ic ] ); - } - result += sizeof( AstPolyMap * )*nc; - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetTranForward( AstMapping *this, int *status ) { -/* -* -* Name: -* GetTranForward - -* Purpose: -* Determine if a PolyMap defines a forward coordinate transformation. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int GetTranForward( AstMapping *this, int *status ) - -* Class Membership: -* PolyMap member function (over-rides the astGetTranForward method -* inherited from the Mapping class). - -* Description: -* This function returns a value indicating if the PolyMap is able -* to perform a forward coordinate transformation. - -* Parameters: -* this -* Pointer to the PolyMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the forward coordinate transformation is not defined, or 1 if it -* is. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPolyMap *map; /* Pointer to PolyMap to be queried */ - int result; /* The returned value */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the PolyMap. */ - map = (AstPolyMap *) this; - -/* First deal with cases where the PolyMap has not been inverted. */ - if( ! astGetInvert( this ) ) { - -/* The PolyMap has a defined forward transformation if one or more - coefficients values were supplied for the original forward - transformation. It is not possible to replace the original forward - transformation with an iterative algorithm. */ - result = map->ncoeff_f ? 1 : 0; - -/* Now deal with cases where the PolyMap has been inverted. */ - } else { - -/* The PolyMap has a defined forward transformation if one or more - coefficients values were supplied for the original inverse - transformation, or if the original inverse transformation is being - approximated using an iterative algorithm. */ - result = ( map->ncoeff_i || astGetIterInverse( map ) ) ? 1 : 0; - } - -/* Return the result. */ - return result; -} - -static int GetTranInverse( AstMapping *this, int *status ) { -/* -* -* Name: -* GetTranInverse - -* Purpose: -* Determine if a PolyMap defines an inverse coordinate transformation. - -* Type: -* Private function. - -* Synopsis: -* #include "matrixmap.h" -* int GetTranInverse( AstMapping *this, int *status ) - -* Class Membership: -* PolyMap member function (over-rides the astGetTranInverse method -* inherited from the Mapping class). - -* Description: -* This function returns a value indicating if the PolyMap is able -* to perform an inverse coordinate transformation. - -* Parameters: -* this -* Pointer to the PolyMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the inverse coordinate transformation is not defined, or 1 if it -* is. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPolyMap *map; /* Pointer to PolyMap to be queried */ - int result; /* The returned value */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the PolyMap. */ - map = (AstPolyMap *) this; - -/* First deal with cases where the PolyMap has not been inverted. */ - if( ! astGetInvert( this ) ) { - -/* The PolyMap has a defined inverse transformation if one or more - coefficients values were supplied for the original inverse - transformation, or if the original inverse transformation is being - approximated using an iterative algorithm. */ - result = ( map->ncoeff_i || astGetIterInverse( map ) ) ? 1 : 0; - -/* Now deal with cases where the PolyMap has been inverted. */ - } else { - -/* The PolyMap has a defined inverse transformation if one or more - coefficients values were supplied for the original forward - transformation. It is not possible to replace the original forward - transformation with an iterative algorithm. */ - result = map->ncoeff_f ? 1 : 0; - } - -/* Return the result. */ - return result; -} - -void astInitPolyMapVtab_( AstPolyMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitPolyMapVtab - -* Purpose: -* Initialise a virtual function table for a PolyMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "polymap.h" -* void astInitPolyMapVtab( AstPolyMapVtab *vtab, const char *name ) - -* Class Membership: -* PolyMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the PolyMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAPolyMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->PolyPowers = PolyPowers; - vtab->FitPoly1DInit = FitPoly1DInit; - vtab->FitPoly2DInit = FitPoly2DInit; - vtab->PolyTran = PolyTran; - vtab->PolyCoeffs = PolyCoeffs; - - vtab->ClearIterInverse = ClearIterInverse; - vtab->GetIterInverse = GetIterInverse; - vtab->SetIterInverse = SetIterInverse; - vtab->TestIterInverse = TestIterInverse; - - vtab->ClearNiterInverse = ClearNiterInverse; - vtab->GetNiterInverse = GetNiterInverse; - vtab->SetNiterInverse = SetNiterInverse; - vtab->TestNiterInverse = TestNiterInverse; - - vtab->ClearTolInverse = ClearTolInverse; - vtab->GetTolInverse = GetTolInverse; - vtab->SetTolInverse = SetTolInverse; - vtab->TestTolInverse = TestTolInverse; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - mapping->GetTranForward = GetTranForward; - mapping->GetTranInverse = GetTranInverse; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the destructor and copy constructor. */ - astSetDelete( (AstObjectVtab *) vtab, Delete ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - -/* Declare the class dump function. */ - astSetDump( vtab, Dump, "PolyMap", "Polynomial transformation" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void IterInverse( AstPolyMap *this, AstPointSet *out, AstPointSet *result, - int *status ){ -/* -* Name: -* IterInverse - -* Purpose: -* Use an iterative method to evaluate the inverse transformation of a -* PolyMap at a set of output positions. - -* Type: -* Private function. - -* Synopsis: -* void IterInverse( AstPolyMap *this, AstPointSet *out, AstPointSet *result, -* int *status ) - -* Description: -* This function transforms a set of PolyMap output positions using -* the inverse transformation of the PolyMap, to generate the corresponding -* input positions. An iterative Newton-Raphson method is used which -* only required the forward transformation of the PolyMap to be deifned. - -* Parameters: -* this -* The PolyMap. -* out -* A PointSet holding the PolyMap output positions that are to be -* transformed using the inverse transformation. -* result -* A PointSet into which the generated PolyMap input positions are to be -* stored. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPointSet *work; - AstPointSet **ps_jac; - AstPolyMap **jacob; - double *vec; - double *pb; - double **ptr_work; - double ***ptr_jac; - double *mat; - double **ptr_out; - double **ptr_in; - double *pa; - double det; - double maxerr; - double vlensq; - double xlensq; - double xx; - int *flags; - int *iw; - int fwd; - int icol; - int icoord; - int ipoint; - int irow; - int iter; - int maxiter; - int nconv; - int ncoord; - int npoint; - int sing; - -/* Check inherited status */ - if( !astOK ) return; - -/* Check the PolyMap has equal numbers of inputs and outputs. */ - ncoord = astGetNin( this ); - if( ncoord != astGetNout( this ) ) { - astError( AST__INTER, "astTransform(%s): Supplied %s has unequal numbers" - " of inputs and outputs and therefore an iterative inverse " - "cannot be used (internal AST Programming errpr).", status, - astGetClass(this), astGetClass(this) ); - } - -/* Get information about the Jacobian matrix for the forward polynomial - transformation. This matrix is a ncoord X ncoord matrix, in which - element (row=I,col=J) is the rate of change of output coord I with - respect to input coord J, of the supplied PolyMap's forward transformation. - The numerical values of the matrix vary depending on where it is - evaluated within the input space of the PolyMap. For this reason, the - "jacob" variable holds a vector of "ncoord" PolyMaps. The outputs of - each of these PolyMaps corresponds to a single column in the Jacobian - matrix. */ - jacob = GetJacobian( this, status ); - -/* Get the number of points to be transformed. */ - npoint = astGetNpoint( out ); - -/* Get another PointSet to hold intermediate results. */ - work = astPointSet( npoint, ncoord, " ", status ); - -/* See if the PolyMap has been inverted. */ - fwd = !astGetInvert( this ); - -/* Get pointers to the data arrays for all PointSets. Note, here "in" and - "out" refer to inputs and outputs of the PolyMap (i.e. the forward - transformation). These are respectively *outputs* and *inputs* of the - inverse transformation. */ - ptr_in = astGetPoints( result ); /* Returned input positions */ - ptr_out = astGetPoints( out ); /* Supplied output positions */ - ptr_work = astGetPoints( work ); /* Work space */ - -/* Allocate an array of PointSets to hold the elements of the Jacobian - matrix. */ - ptr_jac = astMalloc( sizeof( double ** )*ncoord ); - ps_jac = astCalloc( ncoord, sizeof( AstPointSet * ) ); - if( astOK ) { - for( icoord = 0; icoord < ncoord; icoord++ ) { - ps_jac[ icoord ] = astPointSet( npoint, ncoord, " ", status ); - ptr_jac[ icoord ] = astGetPoints( ps_jac[ icoord ] ); - } - } - -/* Allocate an array to hold flags indicating if each position has - converged. Initialise it to hold zero at every element. */ - flags = astCalloc( npoint, sizeof( int ) ); - -/* Allocate memory to hold the Jacobian matrix at a single point. */ - mat = astMalloc( sizeof( double )*ncoord*ncoord ); - -/* Allocate memory to hold the offset vector. */ - vec = astMalloc( sizeof( double )*ncoord ); - -/* Allocate memory to hold work space for palDmat. */ - iw = astMalloc( sizeof( int )*ncoord ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Store the initial guess at the required input positions. We assume initially - that the inverse transformation is a unit mapping, and so we just copy - the supplied outputs positions to the results PointSet holding the - corresponding input positions. */ - for( icoord = 0; icoord < ncoord; icoord++ ) { - memcpy( ptr_in[ icoord ], ptr_out[ icoord ], sizeof( double )*npoint ); - } - -/* Get the maximum number of iterations to perform. */ - maxiter = astGetNiterInverse( this ); - -/* Get the target relative error for the returned input axis values, and - square it. */ - maxerr = astGetTolInverse( this ); - maxerr *= maxerr; - -/* Initialise the number of positions which have reached the required - accuracy. */ - nconv = 0; - -/* Loop round doing iterations of a Newton-Raphson algorithm, until - all points have achieved the required relative error, or the - maximum number of iterations have been performed. */ - for( iter = 0; iter < maxiter && nconv < npoint && astOK; iter++ ) { - -/* Use the forward transformation of the supplied PolyMap to transform - the current guesses at the required input positions into the - corresponding output positions. Store the results in the "work" - PointSet. */ - (void) astTransform( this, result, fwd, work ); - -/* Modify the work PointSet so that it holds the offsets from the output - positions produced by the current input position guesses, and the - required output positions. */ - for( icoord = 0; icoord < ncoord; icoord++ ) { - pa = ptr_out[ icoord ]; - pb = ptr_work[ icoord ]; - for( ipoint = 0; ipoint< npoint; ipoint++,pa++,pb++ ) { - if( *pa != AST__BAD && *pb != AST__BAD ){ - *pb = *pa - *pb; - } else { - *pb = AST__BAD; - } - } - } - -/* Evaluate the elements of the Jacobian matrix at the current input - position guesses. */ - for( icoord = 0; icoord < ncoord; icoord++ ) { - (void) astTransform( jacob[ icoord ], result, 1, ps_jac[ icoord ] ); - } - -/* For each position, we now invert the matrix equation - - Dy = Jacobian.Dx - - to find a guess at the vector (dx) holding the offsets from the - current input positions guesses to their required values. Loop over all - points. */ - for( ipoint = 0; ipoint < npoint; ipoint++ ) { - -/* Do not change positions that have already converged. */ - if( !flags[ ipoint ] ) { - -/* Get the numerical values for the elements of the Jacobian matrix at - the current point. */ - pa = mat; - for( irow = 0; irow < ncoord; irow++ ) { - for( icol = 0; icol < ncoord; icol++ ) { - *(pa++) = ptr_jac[ icol ][ irow ][ ipoint ]; - } - -/* Store the offset from the current output position to the required - output position. */ - vec[ irow ] = ptr_work[ irow ][ ipoint ]; - } - -/* Find the corresponding offset from the current input position to the required - input position. */ - palDmat( ncoord, mat, vec, &det, &sing, iw ); - -/* If the matrix was singular, the input position cannot be evaluated so - store a bad value for it and indicate it has converged. */ - if( sing ) { - for( icoord = 0; icoord < ncoord; icoord++ ) { - ptr_in[ icoord ][ ipoint ] = AST__BAD; - } - flags[ ipoint ] = 1; - nconv++; - -/* Otherwise, update the input position guess. */ - } else { - vlensq = 0.0; - xlensq = 0.0; - pa = vec; - for( icoord = 0; icoord < ncoord; icoord++,pa++ ) { - xx = ptr_in[ icoord ][ ipoint ] + (*pa); - ptr_in[ icoord ][ ipoint ] = xx; - xlensq += xx*xx; - vlensq += (*pa)*(*pa); - } - -/* Check for convergence. */ - if( vlensq < maxerr*xlensq ) { - flags[ ipoint ] = 1; - nconv++; - } - } - } - } - } - } - -/* Free resources. */ - vec = astFree( vec ); - iw = astFree( iw ); - mat = astFree( mat ); - flags = astFree( flags ); - work = astAnnul( work ); - - if( ps_jac ) { - for( icoord = 0; icoord < ncoord; icoord++ ) { - ps_jac[ icoord ] = astAnnul( ps_jac[ icoord ] ); - } - ps_jac = astFree( ps_jac ); - } - - ptr_jac = astFree( ptr_jac ); - -} - -static void LMFunc1D( const double *p, double *hx, int m, int n, void *adata ){ -/* -* Name: -* LMFunc1D - -* Purpose: -* Evaluate a test 1D polynomal. - -* Type: -* Private function. - -* Synopsis: -* void LMFunc1D( const double *p, double *hx, int m, int n, void *adata ) - -* Description: -* This function finds the residuals implied by a supplied set of -* candidate polynomial coefficients. Each residual is a candidate -* polynomial evaluated at one of the sample points, minus the -* supplied target value for the polynomial at that test point. -* -* The minimisation process minimises the sum of the squared residuals. - -* Parameters: -* p -* An array of "m" coefficients for the candidate polynomial. The -* coefficients are ordered C0, C1, C2, etc. -* hx -* An array in which to return the "n" residuals. The residual at -* sample "k" is returned in element (k). -* m -* The length of the "p" array. This should be equal to order. -* n -* The length of the "hx" array. This should be equal to nsamp. -* adata -* Pointer to a structure holding the sample positions and values, -* and other information. - -*/ - -/* Local Variables: */ - AstMinPackData *data; - double *px1; - double *py; - const double *vp; - double *vr; - double res; - int k; - int w1; - -/* Get a pointer to the data structure. */ - data = (AstMinPackData *) adata; - -/* Initialise a pointer to the current returned residual value. */ - vr = hx; - -/* Initialise a pointer to the sampled Y values for the polynomial output. */ - py = data->y[ 0 ]; - -/* Initialise a pointer to the powers of the input X values at the curent - (i.e. first) sample. */ - px1 = data->xp1; - -/* Loop over the index of the sample to which this residual refers. */ - for( k = 0; k < data->nsamp; k++ ) { - -/* Initialise a pointer to the first coefficient (the constant term) for the - polynomial output coordinate. */ - vp = p; - -/* Initialise this residual to hold the sampled Y value. Increment the - pointer to the next sampled value for the current polynomial output. */ - res = -( *(py++) ); - -/* Loop over the coefficients. */ - for( w1 = 0; w1 < data->order; w1++ ) { - -/* Increment the residual by the value of the current term Cw1*(x1^w1). - Increment the pointer to the next coefficient (C). Also increment the - pointer to the next higher power of X1. */ - res += ( *(vp++) )*( *(px1++) ); - } - -/* Store the complete residual in the returned array, and increment the - pointer to the next residual. */ - *(vr++) = res; - } -} - -static void LMFunc2D( const double *p, double *hx, int m, int n, void *adata ){ -/* -* Name: -* LMFunc2D - -* Purpose: -* Evaluate a test 2D polynomal. - -* Type: -* Private function. - -* Synopsis: -* void LMFunc2D( const double *p, double *hx, int m, int n, void *adata ) - -* Description: -* This function finds the residuals implied by a supplied set of -* candidate polynomial coefficients. Each residual is a candidate -* polynomial (either P1 or P2) evaluated at one of the sample points -* (x1,x2), minus the supplied target value for the polynomial at that -* test point. -* -* The minimisation process minimises the sum of the squared residuals. - -* Parameters: -* p -* An array of "m" coefficients for the candidate polynomial. All the -* coefficients for polynomial P1 come first, followed by those for P2. -* Within each each polynomial, the coefficients are order C00, C10, -* C01, C20, C11, C02, C30, C21, C12, C03, etc. So the coefficient -* of (x1^j*x2^k) (=Cjk) for polynomial Pi is stored in element -* [k + (j + k)*(j + k + 1)/2 + i*order*(order+1)/2] of the "p" array. -* hx -* An array in which to return the "n" residuals. The residual at -* sample "k" for polynomial "i" is returned in element (k + nsamp*i). -* m -* The length of the "p" array. This should be equal to order*(order+1). -* n -* The length of the "hx" array. This should be equal to 2*nsamp. -* adata -* Pointer to a structure holding the sample positions and values, -* and other information. - -*/ - -/* Local Variables: */ - AstMinPackData *data; - const double *vp0; - const double *vp; - double *py; - double *px1; - double *px10; - double *px20; - double *vr; - double res; - double *px2; - int iout; - int k; - int w12; - int w2; - -/* Get a pointer to the data structure. */ - data = (AstMinPackData *) adata; - -/* Initialise a pointer to the current returned residual value. */ - vr = hx; - -/* Initialise a pointer to the first coefficient (the constant term) for the - current (i.e. first) polynomial output coordinate. */ - vp0 = p; - -/* Loop over each polynomial output coordinate. */ - for( iout = 0; iout < 2; iout++ ) { - -/* Initialise a pointer to the sampled Y values for the first polynomial - output. */ - py = data->y[ iout ]; - -/* Initialise pointers to the powers of the input X values at the curent - (i.e. first) sample. */ - px10 = data->xp1; - px20 = data->xp2; - -/* Loop over the index of the sample to which this residual refers. */ - for( k = 0; k < data->nsamp; k++ ) { - -/* Reset the pointer to the first coefficient (the constant term) - for the current polynomial output coordinate. */ - vp = vp0; - -/* Initialise this residual to hold the sampled Y value. Increment the - pointer to the next sampled value for the current polynomial output. */ - res = -( *(py++) ); - -/* The w12 value is the sum of the powers of X1 and X2. So w12=0 - corresponds to the constant term in the polynomial, and (e.g.) w12=6 - corresponds to all the terms for which the sum of the powerss (w1+w2) - is 6. Loop over all possible w12 values. */ - for( w12 = 0; w12 < data->order; w12++ ) { - -/* The next coeff refers to (x1^w12)*(x2^0). Get pointers to the values - holding x1^w12 and x2^0. */ - px1 = px10++; - px2 = px20; - -/* Loop over powers of x2. The corresponding power of x1 is "w12-w2", but - is not explicitly needed here. So x1 moves down from w12 to zero, as - w2 moves up from zero to w12. */ - for( w2 = 0; w2 <= w12; w2++ ) { - -/* Increment the residual by the value of the current term Cw1w2*(x1^w1)*(x2^w2). - Increment the pointer tio the next coefficient (C). Also decrement the - pointer to the next lower power of X1, and increment the pointer to the next - higher power of X2. */ - res += ( *(vp++) )*( *(px1--) )*( *(px2++) ); - } - } - -/* Move on to the x2 powers for the next sample. Don't need to do this - for x1 since px10 is incremented within the above loop. */ - px20 += data->order; - -/* Store the complete residual in the returned array, and increment the - pointer to the next residual. */ - *(vr++) = res; - } - -/* Get a pointer to the first coefficient (the constant term) for the - next polynomial output coordinate. */ - vp0 += data->order*( 1 + data->order )/2; - } -} - -static void LMJacob1D( const double *p, double *jac, int m, int n, void *adata ){ -/* -* Name: -* LMJacob1D - -* Purpose: -* Evaluate the Jacobian matrix of a test 1D polynomal. - -* Type: -* Private function. - -* Synopsis: -* void LMJacob1D( const double *p, double *jac, int m, int n, void *adata ) - -* Description: -* This function finds the Jacobian matrix that describes the rate of -* change of every residual with respect to every polynomial coefficient. -* Each residual is a candidate polynomial evaluated at one of the sample -* points minus the supplied target value for the polynomial at that test -* point. -* -* For a polynomial the Jacobian matrix is constant (i.e. does not -* depend on the values of the polynomial coefficients). So we only -* evaluate it on the first call. - -* Parameters: -* p -* An array of "m" coefficients for the candidate polynomial. -* jac -* An array in which to return the "m*n" elements of the Jacobian -* matrix. The rate of change of residual "r" with respect to -* coefficient "c" is returned in element "r + c*n". The residual -* at sample "k" of polynomial Pi has an "r" index of (k + nsamp*i). -* The coefficient of (x1^j) for polynomial Pi has a "c" index -* of j. -* m -* The length of the "p" array. This should be equal to order. -* n -* The number of residuals. This should be equal to nsamp. -* adata -* Pointer to a structure holding the sample positions and values, -* and other information. - -*/ - -/* Local Variables: */ - AstMinPackData *data; - int k; - int w1; - -/* Get a pointer to the data structure. */ - data = (AstMinPackData *) adata; - -/* The Jacobian of the residuals with respect to the polynomial - coefficients is constant (i.e. does not depend on the values of the - polynomial coefficients). So we only need to calculate it once. If - this is the first call, calculate the Jacobian and return it in "jac". - otherwise, just return immediately retaining the supplied "jac" values - (which will be the values returned by the previous call to this - function). */ - if( data->init_jac ) { - data->init_jac = 0; - -/* Loop over all residuals. */ - for( k = 0; k < n; k++ ) { - -/* Loop over all parameters (i.e. polynomial coefficients). */ - for( w1 = 0; w1 < m; w1++ ) { - -/* Store the Jacobian. */ - jac[ k + w1*n ] = (data->xp1)[ w1 + k*data->order ]; - } - } - } -} - -static void LMJacob2D( const double *p, double *jac, int m, int n, void *adata ){ -/* -* Name: -* LMJacob2D - -* Purpose: -* Evaluate the Jacobian matrix of a test 2D polynomal. - -* Type: -* Private function. - -* Synopsis: -* void LMJacob2D( const double *p, double *jac, int m, int n, void *adata ) - -* Description: -* This function finds the Jacobian matrix that describes the rate of -* change of every residual with respect to every polynomial coefficient. -* Each residual is a candidate polynomial (either P1 or P2) evaluated -* at one of the sample points (x1,x2), minus the supplied target value -* for the polynomial at that test point. -* -* For a polynomial the Jacobian matrix is constant (i.e. does not -* depend on the values of the polynomial coefficients). So we only -* evaluate it on the first call. - -* Parameters: -* p -* An array of "m" coefficients for the candidate polynomial. All the -* coefficients for polynomial P1 come first, followed by those for P2. -* Within each each polynomial, the coefficients are order C00, C10, -* C01, C20, C11, C02, C30, C21, C12, C03, etc. So the coefficient -* of (x1^j*x2^k) (=Cjk) for polynomial Pi is stored in element -* [k + (j + k)*(j + k + 1)/2 + i*order*(order+1)/2] of the "p" array. -* jac -* An array in which to return the "m*n" elements of the Jacobian -* matrix. The rate of change of residual "r" with respect to -* coefficient "c" is returned in element "r + c*n". The residual -* at sample "k" of polynomial Pi has an "r" index of (k + nsamp*i). -* The coefficient of (x1^j*x2^k) for polynomial Pi has a "c" index -* of [k + (j + k)*(j + k + 1)/2 + i*order*(order+1)/2]. -* m -* The length of the "p" array. This should be equal to order*(order+1). -* n -* The number of residuals. This should be equal to 2*nsamp. -* adata -* Pointer to a structure holdin gthe sample positions and values, -* and other information. - -*/ - -/* Local Variables: */ - AstMinPackData *data; - int iout; - int k; - int ncof; - int vp; - int vr; - int w1; - int w12; - int w2; - -/* Get a pointer to the data structure. */ - data = (AstMinPackData *) adata; - -/* The Jacobian of the residuals with respect to the polynomial - coefficients is constant (i.e. does not depend on the values of the - polynomial coefficients). So we only need to calculate it once. If - this is the first call, calculate the Jacobian and return it in "jac". - otherwise, just return immediately retaining the supplied "jac" values - (which will be the values returned by the previous call to this - function). */ - if( data->init_jac ) { - data->init_jac = 0; - -/* Store the number of coefficients in one polynomial. */ - ncof = data->order*( 1 + data->order )/2; - -/* Loop over all residuals. */ - for( vr = 0; vr < n; vr++ ) { - -/* Calculate the polynomial output index, and sample index, that creates - the current residual. */ - iout = vr/data->nsamp; - k = vr - iout*data->nsamp; - -/* Loop over all parameters (i.e. polynomial coefficients). */ - for( vp = 0; vp < m; vp++ ) { - -/* If this coefficient is not used in the creation of the current - polynomial output value, then the Jacobian value is zero. */ - if( vp/ncof != iout ) { - jac[ vr + vp*n ] = 0.0; - -/* Otherwise, get the powers of the two polynomial inputs, to which - the current coefficient relates. */ - } else { - w12 = ( -1.0 + sqrt( 1.0 + 8.0*(vp - iout*ncof) ) )/2.0; - w2 = vp - iout*ncof - w12*( w12 + 1 )/2; - w1 = w12 - w2; - -/* Store the Jacobian. */ - jac[ vr + vp*n ] = (data->xp1)[ w1 + k*data->order ]* - (data->xp2)[ w2 + k*data->order ]; - } - } - } - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* PolyMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstPolyMap *this; - int ic; - int result; - int nc; - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointer to the PolyMap structure. */ - this = (AstPolyMap *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( this->jacobian ) { - nc = astGetNin( this ); - for( ic = 0; ic < nc && result; ic++ ) { - result = astManageLock( (this->jacobian)[ ic ], mode, - extra, fail ); - } - } - - return result; - -} -#endif - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a PolyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* PolyMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated PolyMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated PolyMap with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated PolyMap which is to be merged with -* its neighbours. This should be a cloned copy of the PolyMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* PolyMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated PolyMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstPolyMap *pmap0; /* Nominated PolyMap */ - AstPolyMap *pmap1; /* Neighbouring PolyMap */ - int i; /* Index of neighbour */ - int nin; /* Number of input coordinates for nominated PolyMap */ - int nout; /* Number of output coordinates for nominated PolyMap */ - int ok; /* Are PolyMaps equivalent? */ - int oldinv0; /* Original Invert value in pmap0 */ - int oldinv1; /* Original Invert value in pmap1 */ - int result; /* Result value to return */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Save a pointer to the nominated PolyMap. */ - pmap0 = (AstPolyMap *) ( *map_list )[ where ]; - -/* The only simplification which can currently be performed is to merge a PolyMap - with its own inverse. This can only be done in series. Obviously, - there are potentially other simplications which could be performed, but - time does not currently allow these to be coded. */ - if( series ) { - -/* Temporarily set the Invert flag of the nominated PolyMap to the - required value, first saving the original value so that it can be - re-instated later. */ - oldinv0 = astGetInvert( pmap0 ); - astSetInvert( pmap0, ( *invert_list )[ where ] ); - -/* Get the number of inputs and outputs to the nominated PolyMap. */ - nin = astGetNin( pmap0 ); - nout = astGetNout( pmap0 ); - -/* Check each neighbour. */ - for( i = where - 1; i <= where + 1; i += 2 ) { - -/* Continue with the next pass if the neighbour does not exist. */ - if( i < 0 || i >= *nmap ) continue; - -/* Continue with the next pass if this neighbour is not a PermMap. */ - if( ! astIsAPolyMap( ( *map_list )[ i ] ) ) continue; - -/* Get a pointer to it. */ - pmap1 = (AstPolyMap *) ( *map_list )[ i ]; - -/* Check it is used in the opposite direction to the nominated PolyMap. */ - if( ( *invert_list )[ i ] == ( *invert_list )[ where ] ) continue; - -/* We use the astEqual method to check that the two PolyMaps are equal. - But at the moment they may not be equal because they may have - different Invert flags. Therefore, temporarily set the invert flag - of the neighbour so that it is the same as the nominated PolyMap, - first saving the original value so that it can be re-instated later. - Note, we have already checked that the two PolyMaps are used in opposite - directions within the CmpMap. */ - oldinv1 = astGetInvert( pmap1 ); - astSetInvert( pmap1, ( *invert_list )[ where ] ); - -/* Use astEqual to check that the coefficients etc are equal in the two - PolyMaps. */ - ok = astEqual( pmap0, pmap1 ); - -/* Re-instate the original value of the Invert flag in the neighbour. */ - astSetInvert( pmap1, oldinv1 ); - -/* Pass on to the next neighbour if the current neighbour differs from - the nominated PolyMap. */ - if( !ok ) continue; - -/* If we get this far, then the nominated PolyMap and the current - neighbour cancel each other out, so replace each by a UnitMap. */ - pmap0 = astAnnul( pmap0 ); - pmap1 = astAnnul( pmap1 ); - if( i < where ) { - ( *map_list )[ where ] = (AstMapping *) astUnitMap( nout, "", status ); - ( *map_list )[ i ] = (AstMapping *) astUnitMap( nout, "", status ); - ( *invert_list )[ where ] = 0; - ( *invert_list )[ i ] = 0; - result = i; - } else { - ( *map_list )[ where ] = (AstMapping *) astUnitMap( nin, "", status ); - ( *map_list )[ i ] = (AstMapping *) astUnitMap( nin, "", status ); - ( *invert_list )[ where ] = 0; - ( *invert_list )[ i ] = 0; - result = where; - } - -/* Leave the loop. */ - break; - } - -/* If the nominated PolyMap was not replaced by a UnitMap, then - re-instate its original value for the Invert flag. */ - if( pmap0 ) astSetInvert( pmap0, oldinv0 ); - } - -/* Return the result. */ - return result; -} - -static int MPFunc1D( void *p, int m, int n, const double *x, double *fvec, - double *fjac, int ldfjac, int iflag ) { -/* -* Name: -* MPFunc1D - -* Purpose: -* Evaluate a test 1D polynomal or its Jacobian. - -* Type: -* Private function. - -* Synopsis: -* int MPFunc1D( void *p, int m, int n, const double *x, double *fvec, -* double *fjac, int ldfjac, int iflag ) - -* Description: -* This function finds the residuals or Jacobian implied by a supplied -* set of candidate polynomial coefficients. Each residual is a candidate -* polynomial evaluated at one of the sample points, minus the -* supplied target value for the polynomial at that test point. -* -* The minimisation process minimises the sum of the squared residuals. - -* Parameters: -* p -* A pointer to data needed to evaluate the required residuals or -* Jacobians. -* m -* The number of residuals. -* n -* The number of coefficients. -* x -* An array of "n" coefficients for the candidate polynomial. -* fvec -* An array in which to return the "m" residuals. -* fjac -* An array in which to return the "mxn" Jacobian values. -* ldflac -* Unused (should always be equal to "m"). -* iflag -* If 1 calculate the residuals, otherwise calculate the Jacobians. - -*/ - -/* If required, calculate the function values at X, and return this - vector in fvec. Do not alter fjac. */ - if( iflag == 1 ) { - LMFunc1D( x, fvec, n, m, p ); - -/* Otherwise, calculate the Jacobian values at X, and return this - matrix in fjac. Do not alter fvec. */ - } else { - LMJacob1D( x, fjac, n, m, p ); - } - - return 0; -} - -static int MPFunc2D( void *p, int m, int n, const double *x, double *fvec, - double *fjac, int ldfjac, int iflag ) { -/* -* Name: -* MPFunc1D - -* Purpose: -* Evaluate a test 2D polynomal or its Jacobian. - -* Type: -* Private function. - -* Synopsis: -* int MPFunc2D( void *p, int m, int n, const double *x, double *fvec, -* double *fjac, int ldfjac, int iflag ) - -* Description: -* This function finds the residuals or Jacobian implied by a supplied -* set of candidate polynomial coefficients. Each residual is a candidate -* polynomial evaluated at one of the sample points, minus the -* supplied target value for the polynomial at that test point. -* -* The minimisation process minimises the sum of the squared residuals. - -* Parameters: -* p -* A pointer to data needed to evaluate the required residuals or -* Jacobians. -* m -* The number of residuals. -* n -* The number of coefficients. -* x -* An array of "n" coefficients for the candidate polynomial. -* fvec -* An array in which to return the "m" residuals. -* fjac -* An array in which to return the "mxn" Jacobian values. -* ldflac -* Unused (should always be equal to "m"). -* iflag -* If 1 calculate the residuals, otherwise calculate the Jacobians. - -*/ - -/* If required, calculate the function values at X, and return this - vector in fvec. Do not alter fjac. */ - if( iflag == 1 ) { - LMFunc2D( x, fvec, n, m, p ); - -/* Otherwise, calculate the Jacobian values at X, and return this - matrix in fjac. Do not alter fvec. */ - } else { - LMJacob2D( x, fjac, n, m, p ); - - } - - return 0; -} - -static void PolyCoeffs( AstPolyMap *this, int forward, int nel, double *coeffs, - int *ncoeff, int *status ){ -/* -*++ -* Name: -c astPolyCoeffs -f AST_POLYCOEFFS - -* Purpose: -* Retrieve the coefficient values used by a PolyMap. - -* Type: -* Public function. - -* Synopsis: -c #include "polymap.h" -c void astPolyCoeffs( AstPolyMap *this, int forward, int nel, double *coeffs, -c int *ncoeff ) -f CALL AST_POLYCOEFFS( THIS, FORWARD, NEL, COEFFS, NCOEFF, STATUS ) - -* Class Membership: -* PolyMap method. - -* Description: -* This function returns the coefficient values used by either the -* forward or inverse transformation of a PolyMap, in the same form -* that they are supplied to the PolyMap constructor. -* -* Usually, you should call this method first with -c "nel" -f NEL -* set to zero to determine the number of coefficients used by the -* PolyMap. This allows you to allocate an array of the correct size to -* hold all coefficient data. You should then call this method a -* second time to get the coefficient data. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the original Mapping. -c forward -f FORWARD = LOGICAL (Given) -c If non-zero, -f If .TRUE., -* the coefficients of the forward PolyMap transformation are -* returned. Otherwise the inverse transformation coefficients are -* returned. -c nel -f NEL = INTEGER (Given) -* The length of the supplied -c "coeffs" -f COEFFS -* array. It should be at least "ncoeff*( nin + 2 )" if -c "foward" is non-zero, -f FORWARD is .TRUE., -* and "ncoeff*( nout + 2 )" otherwise, where "ncoeff" is the -* number of coefficients to be returned. If a value of zero -* is supplied, no coefficient values are returned, but the -* number of coefficients used by the transformation is still -* returned in -c "ncoeff". -f NCOEFF. -c coeffs -f COEFFS( NEL ) = DOUBLE PRECISION (Returned) -* An array in which to return the coefficients used by the -* requested transformation of the PolyMap. Ignored if -c "nel" is zero. -f NEL is zero. -* The coefficient data is returned in the form in which it is -* supplied to the PolyMap constructor. That is, each group of -* "2 + nin" or "2 + nout" adjacent elements describe a single -* coefficient of the forward or inverse transformation. See the -* PolyMap constructor documentation for further details. -* -* If the supplied array is too short to hold all the coefficients, -* trailing coefficients are excluded. If the supplied array is -* longer than needed to hold all the coefficients, trailing -* elements are filled with zeros. -c ncoeff -f NCOEFF = INTEGER (Returned) -* The number of coefficients used by the requested transformation. -* A value of zero is returned if the transformation does not -* have any defining polynomials. A value is returned for this argument -* even if -c "nel" is zero. -f NEL is zero. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - double **coeff; - int ***power; - int *nco; - int *pp; - int iax; - int icoeff; - int iel; - int ipoly; - int nax; - int npoly; - -/* Initialise */ - *ncoeff = 0; - -/* Check the inherited status. */ - if ( !astOK ) return; - -/* Fill any supplied array with zeros. */ - if( nel ) memset( coeffs, 0, nel*sizeof( *coeffs ) ); - -/* Get the values to use, taking account of whether the PolyMap has been - inverted or not. */ - if( forward != astGetInvert( this ) ){ - nco = this->ncoeff_f; - power = this->power_f; - coeff = this->coeff_f; - npoly = astGetNout( this ); - nax = astGetNin( this ); - } else { - nco = this->ncoeff_i; - power = this->power_i; - coeff = this->coeff_i; - npoly = astGetNin( this ); - nax = astGetNout( this ); - } - -/* Notheg to do if there are no coeffs. */ - if( nco && power && coeff ) { - -/* Initialise index of next value to store in returned array. */ - iel = 0; - -/* Loop round each 1D polynomial. */ - for( ipoly = 0; ipoly < npoly; ipoly++ ){ - -/* Loop round coefficients. */ - for( icoeff = 0; icoeff < nco[ ipoly ]; icoeff++ ) { - -/* Store the coefficient value in the next element of the returned array, - if the array is not already full. Increment the pointer to the next - element. */ - if( iel < nel ) coeffs[ iel++ ] = coeff[ipoly][icoeff]; - -/* Next store the integer index of the PolyMap input or output which uses - the coefficient within its defining polynomial (the first axis has - index 1). */ - if( iel < nel ) coeffs[ iel++ ] = ipoly + 1; - -/* The remaining elements of the group give the integer powers to use - with each input or output coordinate value. */ - pp = power[ipoly][icoeff]; - for( iax = 0; iax < nax; iax++,pp++ ) { - if( iel < nel ) coeffs[ iel++ ] = *pp; - } - } - -/* Increment the total number of coefficients used by the transformation. */ - *ncoeff += nco[ ipoly ]; - } - } -} - -static void PolyPowers( AstPolyMap *this, double **work, int ncoord, - const int *mxpow, double **ptr, int point, - int fwd, int *status ){ -/* -*+ -* Name: -* astPolyPowers - -* Purpose: -* Find the required powers of the input axis values. - -* Type: -* Protected function. - -* Synopsis: -* #include "polymap.h" -* void astPolyPowers( AstPolyMap *this, double **work, int ncoord, -* const int *mxpow, double **ptr, int point, -* int fwd ) - -* Class Membership: -* PolyMap virtual function. - -* Description: -* This function is used by astTransform to calculate the powers of -* the axis values for a single input position. In the case of -* sub-classes, the powers may not be simply powers of the supplied -* axis values but may be more complex quantities such as a Chebyshev -* polynomial of the required degree evaluated at the input axis values. - -* Parameters: -* this -* Pointer to the PolyMap. -* work -* An array of "ncoord" pointers, each pointing to an array of -* length "max(2,mxpow)". The required values are placed in this -* array on exit. -* ncoord -* The number of axes. -* mxpow -* Pointer to an array holding the maximum power required of each -* axis value. Should have "ncoord" elements. -* ptr -* An array of "ncoord" pointers, each pointing to an array holding -* the axis values. Each of these arrays of axis values must have -* at least "point+1" elements. -* point -* The zero based index of the point within "ptr" that holds the -* axis values to be exponentiated. -* fwd -* Do the supplied coefficients define the foward transformation of -* the PolyMap? -*- -*/ - -/* Local Variables; */ - double *pwork; - double x; - int coord; - int ip; - -/* Check the local error status. */ - if ( !astOK ) return; - -/* For the base PolyMap class, this method simply raises each input axis - value to the required power. Loop over all input axes. */ - for( coord = 0; coord < ncoord; coord++ ) { - -/* Get a pointer to the array in which the powers of the current axis - value are to be returned. */ - pwork = work[ coord ]; - -/* Anything to the power zero is 1.0. */ - pwork[ 0 ] = 1.0; - -/* Get the input axis value. If it is bad, store bad values for all - remaining powers. */ - x = ptr[ coord ][ point ]; - if( x == AST__BAD ) { - for( ip = 1; ip <= mxpow[ coord ]; ip++ ) pwork[ ip ] = AST__BAD; - -/* Otherwise, form and store the required powers of the input axis value. */ - } else { - for( ip = 1; ip <= mxpow[ coord ]; ip++ ) { - pwork[ ip ] = pwork[ ip - 1 ]*x; - } - } - } -} - -static AstPolyMap *PolyTran( AstPolyMap *this, int forward, double acc, - double maxacc, int maxorder, const double *lbnd, - const double *ubnd, int *status ){ -/* -*++ -* Name: -c astPolyTran -f AST_POLYTRAN - -* Purpose: -* Fit a PolyMap inverse or forward transformation. - -* Type: -* Public function. - -* Synopsis: -c #include "polymap.h" -c AstPolyMap *astPolyTran( AstPolyMap *this, int forward, double acc, -c double maxacc, int maxorder, const double *lbnd, -c const double *ubnd ) -f RESULT = AST_POLYTRAN( THIS, FORWARD, ACC, MAXACC, MAXORDER, LBND, -f UBND, STATUS ) - -* Class Membership: -* PolyMap method. - -* Description: -* This function creates a new PolyMap which is a copy of the supplied -* PolyMap, in which a specified transformation (forward or inverse) -* has been replaced by a new polynomial transformation. The -* coefficients of the new transformation are estimated by sampling -* the other transformation and performing a least squares polynomial -* fit in the opposite direction to the sampled positions and values. -* -* This method can only be used on (1-input,1-output) or (2-input,2-output) -* PolyMaps. -* -* The transformation to create is specified by the -c "forward" parameter. -f FORWARD parameter. -* In what follows "X" refers to the inputs of the PolyMap, and "Y" to -* the outputs of the PolyMap. The forward transformation transforms -* input values (X) into output values (Y), and the inverse transformation -* transforms output values (Y) into input values (X). Within a PolyMap, -* each transformation is represented by an independent set of -* polynomials, P_f or P_i: Y=P_f(X) for the forward transformation and -* X=P_i(Y) for the inverse transformation. -* -c The "forward" -f The FORWARD -* parameter specifies the transformation to be replaced. If it is -c non-zero, -f is .TRUE., -* a new forward transformation is created -* by first finding the input values (X) using the inverse transformation -* (which must be available) at a regular grid of points (Y) covering a -* rectangular region of the PolyMap's output space. The coefficients of -* the required forward polynomial, Y=P_f(X), are chosen in order to -* minimise the sum of the squared residuals between the sampled values -* of Y and P_f(X). -* -c If "forward" is zero (probably the most likely case), -f If FORWARD is .FALSE. (probably the most likely case), -* a new inverse transformation is created by -* first finding the output values (Y) using the forward transformation -* (which must be available) at a regular grid of points (X) covering a -* rectangular region of the PolyMap's input space. The coefficients of -* the required inverse polynomial, X=P_i(Y), are chosen in order to -* minimise the sum of the squared residuals between the sampled values -* of X and P_i(Y). -* -* This fitting process is performed repeatedly with increasing -* polynomial orders (starting with linear) until the target -* accuracy is achieved, or a specified maximum order is reached. If -* the target accuracy cannot be achieved even with this maximum-order -* polynomial, the best fitting maximum-order polynomial is returned so -* long as its accuracy is better than -c "maxacc". -f MAXACC. -* If it is not, a NULL pointer is returned but no error is reported. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the original Mapping. -c forward -f FORWARD = LOGICAL (Given) -c If non-zero, -f If .TRUE., -* the forward PolyMap transformation is replaced. Otherwise the -* inverse transformation is replaced. -c acc -f ACC = DOUBLE (Given) -* The target accuracy, expressed as a geodesic distance within -* the PolyMap's input space (if -c "forward" is zero) or output space (if "forward" is non-zero). -f FORWARD is .FALSE.) or output space (if FORWARD is .TRUE.). -c maxacc -f MAXACC = DOUBLE (Given) -* The maximum allowed accuracy for an acceptable polynomial, -* expressed as a geodesic distance within the PolyMap's input -* space (if -c "forward" is zero) or output space (if "forward" is non-zero). -f FORWARD is .FALSE.) or output space (if FORWARD is .TRUE.). -c maxorder -f MAXORDER = INTEGER (Given) -* The maximum allowed polynomial order. This is one more than the -* maximum power of either input axis. So for instance, a value of -* 3 refers to a quadratic polynomial. Note, cross terms with total -* powers greater than or equal to -c maxorder -f MAXORDER -* are not inlcuded in the fit. So the maximum number of terms in -* each of the fitted polynomials is -c maxorder*(maxorder+1)/2. -f MAXORDER*(MAXORDER+1)/2. -c lbnd -f LBND( * ) = DOUBLE PRECISION (Given) -c Pointer to an -f An -* array holding the lower bounds of a rectangular region within -* the PolyMap's input space (if -c "forward" is zero) or output space (if "forward" is non-zero). -f FORWARD is .FALSE.) or output space (if FORWARD is .TRUE.). -* The new polynomial will be evaluated over this rectangle. The -* length of this array should equal the value of the PolyMap's Nin -* or Nout attribute, depending on -c "forward". -f FORWARD. -c ubnd -f UBND( * ) = DOUBLE PRECISION (Given) -c Pointer to an -f An -* array holding the upper bounds of a rectangular region within -* the PolyMap's input space (if -c "forward" is zero) or output space (if "forward" is non-zero). -f FORWARD is .FALSE.) or output space (if FORWARD is .TRUE.). -* The new polynomial will be evaluated over this rectangle. The -* length of this array should equal the value of the PolyMap's Nin -* or Nout attribute, depending on -c "forward". -f FORWARD. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPolyTran() -f AST_POLYTRAN = INTEGER -* A pointer to the new PolyMap. -c A NULL pointer -f AST__NULL -* will be returned if the fit fails to achieve the accuracy -* specified by -c "maxacc", -f MAXACC, -* but no error will be reported. - -* Applicability: -* PolyMap -* All PolyMaps have this method. -* ChebyMap -c The ChebyMap implementation of this method allows -c NULL pointers to be supplied for "lbnd" and/or "ubnd", -c in which case the corresponding bounds supplied when the ChebyMap -c was created are used. -* The returned PolyMap will be a ChebyMap, and the new transformation -* will be defined as a weighted sum of Chebyshev functions of the -* first kind. - -* Notes: -* - This function can only be used on 1D or 2D PolyMaps which have -* the same number of inputs and outputs. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstPolyMap *result; - int ok; - -/* Initialise. */ - result = NULL; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Take a copy of the supplied PolyMap. */ - result = astCopy( this ); - -/* Replace the required transformation. */ - ok = ReplaceTransformation( result, forward, acc, maxacc, maxorder, lbnd, - ubnd, status ); - -/* If an error occurred, or the fit was not good enough, annul the returned - PolyMap. */ - if ( !ok || !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int ReplaceTransformation( AstPolyMap *this, int forward, double acc, - double maxacc, int maxorder, const double *lbnd, - const double *ubnd, int *status ){ -/* -* Name: -* ReplaceTransformation - -* Purpose: -* Create a new inverse or forward transformation for a PolyMap. - -* Type: -* Private function. - -* Synopsis: -* int ReplaceTransformation( AstPolyMap *this, int forward, double acc, -* double maxacc, int maxorder, const double *lbnd, -* const double *ubnd, int *status ) - -* Description: -* This function creates a new forward or inverse transformation for -* the supplied PolyMap (replacing any existing transformation), by -* sampling the other transformation and performing a least squares -* polynomial fit to the sample positions and values. -* -* The transformation to create is specified by the "forward" parameter. -* In what follows "X" refers to the inputs of the PolyMap, and "Y" to -* the outputs of the PolyMap. The forward transformation transforms -* input values (X) into output values (Y), and the inverse transformation -* transforms output values (Y) into input values (X). Within a PolyMap, -* each transformation is represented by an independent set of -* polynomials: Y=P_f(X) for the forward transformation and X=P_i(Y) -* for the inverse transformation. -* -* If "forward" is zero then a new inverse transformation is created by -* first finding the output values (Y) using the forward transformation -* (which must be available) at a regular grid of points (X) covering a -* rectangular region of the PolyMap's input space. The coefficients of -* the required inverse polynomial, X=P_i(Y), are chosen in order to -* minimise the sum of the squared residuals between the sampled values -* of X and P_i(Y). -* -* If "forward" is non-zero then a new forward transformation is created -* by first finding the input values (X) using the inverse transformation -* (which must be available) at a regular grid of points (Y) covering a -* rectangular region of the PolyMap's output space. The coefficients of -* the required forward polynomial, Y=P_f(X), are chosen in order to -* minimise the sum of the squared residuals between the sampled values -* of Y and P_f(X). -* -* This fitting process is performed repeatedly with increasing -* polynomial orders (starting with linear) until the target -* accuracy is achieved, or a specified maximum order is reached. If -* the target accuracy cannot be achieved even with this maximum-order -* polynomial, the best fitting maximum-order polynomial is returned so -* long as its accuracy is better than "maxacc". - -* Parameters: -* this -* The PolyMap. -* forward -* If non-zero, then the forward PolyMap transformation is -* replaced. Otherwise the inverse transformation is replaced. -* acc -* The target accuracy, expressed as a geodesic distance within -* the PolyMap's input space (if "forward" is zero) or output -* space (if "forward" is non-zero). -* maxacc -* The maximum allowed accuracy for an acceptable polynomial, -* expressed as a geodesic distance within the PolyMap's input -* space (if "forward" is zero) or output space (if "forward" is -* non-zero). -* maxorder -* The maximum allowed polynomial order. This is one more than the -* maximum power of either input axis. So for instance, a value of -* 3 refers to a quadratic polynomial. Note, cross terms with total -* powers greater than or equal to maxorder are not inlcuded in the -* fit. So the maximum number of terms in each of the fitted polynomials -* is maxorder*(maxorder+1)/2. -* lbnd -* An array holding the lower bounds of a rectangular region within -* the PolyMap's input space (if "forward" is zero) or output -* space (if "forward" is non-zero). The new polynomial will be -* evaluated over this rectangle. -* ubnd -* An array holding the upper bounds of a rectangular region within -* the PolyMap's input space (if "forward" is zero) or output -* space (if "forward" is non-zero). The new polynomial will be -* evaluated over this rectangle. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Non-zero if a fit was performed succesfully, to at least the -* maximum allowed accuracy. Zero if the fit failed, or an error -* occurred. - -* Notes: -* - No error is reported if the fit fails to achieve the required -* maximum accuracy. -* - An error is reported if the transformation that is not being -* replaced is not defined. -* - An error is reported if the PolyMap does not have equal numbers -* of inputs and outputs. -* - An error is reported if the PolyMap has more than 2 inputs or outputs. - -*/ - -/* Local Variables: */ - double **table; - double *cofs; - double racc; - double scales[ 4 ]; - int ndim; - int ncof; - int nsamp; - int order; - int result; - -/* Check inherited status */ - if( !astOK ) return 0; - -/* Check the PolyMap can be used. */ - ndim = astGetNin( this ); - if( astGetNout( this ) != ndim && astOK ) { - astError( AST__BADNI, "astPolyTran(%s): Supplied %s has " - "different number of inputs (%d) and outputs (%d).", - status, astGetClass( this ), astGetClass( this ), ndim, - astGetNout( this ) ); - - } else if( ndim > 2 && astOK ) { - astError( AST__BADNI, "astPolyTran(%s): Supplied %s has " - "too many inputs and outputs (%d) - must be 1 or 2.", - status, astGetClass( this ), astGetClass( this ), ndim ); - } - - if( forward != astGetInvert( this ) ){ - if( ! this->ncoeff_i && astOK ) { - astError( AST__NODEF, "astPolyTran(%s): Supplied %s has " - "no inverse transformation.", status, astGetClass( this ), - astGetClass( this ) ); - } - } else { - if( ! this->ncoeff_f && astOK ) { - astError( AST__NODEF, "astPolyTran(%s): Supplied %s has " - "no forward transformation.", status, astGetClass( this ), - astGetClass( this ) ); - } - } - -/* Check the bounds can be used. */ - if( !lbnd || !ubnd ) { - astError( AST__NODEF, "astPolyTran(%s): No upper and/or lower bounds " - "supplied.", status, astGetClass( this ) ); - } else if( lbnd[ 0 ] >= ubnd[ 0 ] && astOK ) { - astError( AST__NODEF, "astPolyTran(%s): Supplied upper " - "bound for the first axis (%g) is less than or equal to the " - "supplied lower bound (%g).", status, astGetClass( this ), - lbnd[ 0 ], ubnd[ 0 ] ); - } else if( ndim == 2 && lbnd[ 1 ] >= ubnd[ 1 ] && astOK ) { - astError( AST__NODEF, "astPolyTran(%s): Supplied upper " - "bound for the second axis (%g) is less than or equal to the " - "supplied lower bound (%g).", status, astGetClass( this ), - lbnd[ 1 ], ubnd[ 1 ] ); - } - -/* Initialise pointer to work space. */ - table = NULL; - -/* Loop over increasing polynomial orders until the required accuracy is - achieved, up to the specified maximum order. The "order" value is one more - than the maximum power in the polynomial (so a quadratic has "order" 3). */ - if( maxorder < 2 ) maxorder = 2; - for( order = 2; order <= maxorder; order++ ) { - -/* First do 2D PolyMaps. */ - if( ndim == 2 ) { - -/* Sample the requested polynomial transformation at a grid of points. This - grid covers the user-supplied region, using 2*order points on each - axis. */ - table = SamplePoly2D( this, !forward, table, lbnd, ubnd, 2*order, - &nsamp, scales, status ); - -/* Fit the polynomial. Always fit a linear polynomial ("order" 2) to any - dummy second axis. If successfull, replace the PolyMap transformation - and break out of the order loop. */ - cofs = FitPoly2D( this, forward, nsamp, acc, order, table, scales, - &ncof, &racc, status ); - -/* Now do 1D PolyMaps. */ - } else { - table = SamplePoly1D( this, !forward, table, lbnd[ 0 ], ubnd[ 0 ], - 2*order, &nsamp, scales, status ); - cofs = FitPoly1D( this, forward, nsamp, acc, order, table, scales, - &ncof, &racc, status ); - } - -/* If the fit was succesful, replace the PolyMap transformation and break - out of the order loop. */ - if( cofs && ( racc < acc || ( racc < maxacc && order == maxorder ) ) ) { - StoreArrays( this, forward, ncof, cofs, status ); - break; - } else { - cofs = astFree( cofs ); - } - } - -/* If no fit was produced, return zero. */ - result = cofs ? 1 : 0; - -/* Free resources. */ - cofs = astFree( cofs ); - table = astFreeDouble( table ); - -/* Return the result. */ - return result; -} - -static double **SamplePoly1D( AstPolyMap *this, int forward, double **table, - double lbnd, double ubnd, int npoint, int *nsamp, - double scales[2], int *status ){ -/* -* Name: -* SamplePoly1D - -* Purpose: -* Create a table of input and output positions for a 1D PolyMap. - -* Type: -* Private function. - -* Synopsis: -* double **SamplePoly1D( AstPolyMap *this, int forward, double **table, -* double lbnd, double ubnd, int npoint, int *nsamp, -* double scales[2], int *status ) - -* Description: -* This function creates a table containing samples of the requested -* polynomial transformation at a grid of input points. This grid covers -* the user-supplied region, using "npoint" points. - -* Parameters: -* this -* The PolyMap. -* forward -* If non-zero, then the forward PolyMap transformation is sampled. -* Otherwise the inverse transformation is sampled. -* table -* Pointer to a previous table created by this function, which is -* to be re-used, or NULL. -* lbnd -* The lower bounds of the region within the PolyMap's 1D input space -* (if "forward" is non-zero) or output space (if "forward" is zero). -* The new polynomial will be evaluated over this region. -* ubnd -* The upper bounds of the region within the PolyMap's 1D input space -* (if "forward" is non-zero) or output space (if "forward" is zero). -* The new polynomial will be evaluated over this region. -* npoint -* The number of points to use. -* nsamp -* Address of an int in which to return the total number of samples -* in the returned table. -* scales -* Array in which to return the scaling factors for the two columns -* of the returned table. Multiplying the returned table values by -* the scale factor produces PolyMap input or output axis values. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to an array of 2 pointers. Each of these pointers points -* to an array of "nsamp" doubles, being the sampled values for y1 -* and x1 in that order. Here x1 is the input value for the sampled -* transformation (these are spaced on the regular grid specified -* by lbnd, ubnd and npoint), and y1 is the output position produced -* by the sampled transformation. The returned values are scaled so -* that each column has an RMS value of 1.0. The scaling factors that -* convert scaled values into original values are returned in "scales". -* The returned pointer should be freed using astFreeDouble when no -* longer needed. - -*/ - -/* Local Variables: */ - AstPointSet *ps1; - AstPointSet *ps2; - double **result; - double *p0; - double *p1; - double *ptr1[ 1 ]; - double *ptr2[ 1 ]; - double delta0; - double rms; - double sum; - double val0; - int i; - int icol; - -/* Initialise returned value */ - result = table; - *nsamp = 0; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Ensure we have a table of the correct size. */ - *nsamp = npoint; - if( !result ) result = astCalloc( 2, sizeof( double * ) ); - if( result ) { - for( i = 0; i < 2; i++ ) { - result[ i ] = astRealloc( result[ i ] , (*nsamp)*sizeof( double ) ); - } - } - -/* Work out the step sizes for the grid. */ - delta0 = ( ubnd - lbnd )/( npoint - 1 ); - -/* Create a PointSet to hold the grid of input positions. Use column 1 - of the table to hold the PointSet values. */ - ps1 = astPointSet( *nsamp, 1, " ", status ); - ptr1[ 0 ] = result[ 1 ]; - astSetPoints( ps1, ptr1 ); - -/* Create a PointSet to hold the grid of output positions. Use column 0 - of the table to hold the PointSet values. */ - ps2 = astPointSet( *nsamp, 1, " ", status ); - ptr2[ 0 ] = result[ 0 ]; - astSetPoints( ps2, ptr2 ); - if( astOK ) { - -/* Calculate the grid of input positions and store in the PointSet and - therefore also in the returned table. Rounding error may cause the - final point to be just over the upper bound, so we leave the final - point out of the loop and set it explicitly to the upper bound - afterwards. */ - val0 = lbnd; - p0 = ptr1[ 0 ]; - for( i = 0; i < npoint-1; i++ ) { - *(p0++) = val0; - val0 += delta0; - } - *p0 = ubnd; - -/* Transform the input grid to get the output grid. */ - (void) astTransform( this, ps1, forward, ps2 ); - -/* Scale each column in turn. */ - for( icol = 0; icol < 2; icol++ ) { - -/* Find the RMS of the values in the column. */ - sum = 0.0; - p0 = result[ icol ]; - p1 = p0 + (*nsamp); - for( ; p0 < p1; p0++ ) sum += ( *p0 )*( *p0 ); - rms = sqrt( sum/(*nsamp) ); - -/* Divide the table values by the RMS. */ - p0 = result[ icol ]; - p1 = p0 + (*nsamp); - for( ; p0 < p1; p0++ ) *p0 /= rms; - -/* Return the RMS as the scale factor. */ - scales[ icol ] = rms; - } - } - -/* Free resources */ - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - -/* If an error occurred, free the returned array. */ - if( !astOK ) result = astFreeDouble( result ); - -/* Return a pointer to the table. */ - return result; -} - -static double **SamplePoly2D( AstPolyMap *this, int forward, double **table, - const double *lbnd, const double *ubnd, int npoint, - int *nsamp, double scales[4], int *status ){ -/* -* Name: -* SamplePoly2D - -* Purpose: -* Create a table of input and output positions for a 2D PolyMap. - -* Type: -* Private function. - -* Synopsis: -* double **SamplePoly2D( AstPolyMap *this, int forward, double **table, -* const double *lbnd, const double *ubnd, int npoint, -* int *nsamp, double scales[4], int *status ) - -* Description: -* This function creates a table containing samples of the requested -* polynomial transformation at a grid of input points. This grid covers -* the user-supplied region, using "npoint" points on each axis. - -* Parameters: -* this -* The PolyMap. -* forward -* If non-zero, then the forward PolyMap transformation is sampled. -* Otherwise the inverse transformation is sampled. -* table -* Pointer to a previous table created by this function, which is -* to be re-used, or NULL. -* lbnd -* An array holding the lower bounds of a rectangular region within -* the PolyMap's input space (if "forward" is non-zero) or output -* space (if "forward" is zero). The new polynomial will be -* evaluated over this rectangle. -* ubnd -* An array holding the upper bounds of a rectangular region within -* the PolyMap's input space (if "forward" is non-zero) or output -* space (if "forward" is zero). The new polynomial will be -* evaluated over this rectangle. -* npoint -* The number of points along each edge of the grid. -* nsamp -* Address of an int in which to return the total number of samples -* in the returned table. -* scales -* Array in which to return the scaling factors for the four -* columns of the returned table. Multiplying the returned table -* values by the scale factor produces PolyMap input or output axis -* values. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to an array of 4 pointers. Each of these pointers points -* to an array of "nsamp" doubles, being the sampled values for y1, -* y2, x1 or x2 in that order. Here (x1,x2) are the input values -* for the sampled transformation (these are spaced on the regular -* grid specified by lbnd, ubnd and npoint), and (y1,y2) are the -* output positions produced by the sampled transformation. The -* returned values are scaled so that each column has an RMS value -* of 1.0. The scaling factors that convert scaled values into -* original values are returned in "scales". The returned pointer -* should be freed using astFreeDouble when no longer needed. - -*/ - -/* Local Variables: */ - AstPointSet *ps1; - AstPointSet *ps2; - double **result; - double *p0; - double *p1; - double *ptr1[ 2 ]; - double *ptr2[ 2 ]; - double delta1; - double delta0; - double rms; - double sum; - double val0; - double val1; - int i; - int icol; - int j; - -/* Initialise returned value */ - result = table; - *nsamp = 0; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Ensure we have a table of the correct size. */ - *nsamp = npoint*npoint; - if( !result ) result = astCalloc( 4, sizeof( double * ) ); - if( result ) { - for( i = 0; i < 4; i++ ) { - result[ i ] = astRealloc( result[ i ] , (*nsamp)*sizeof( double ) ); - } - } - -/* Work out the step sizes for the grid. */ - delta0 = ( ubnd[ 0 ] - lbnd[ 0 ] )/( npoint - 1 ); - delta1 = ( ubnd[ 1 ] - lbnd[ 1 ] )/( npoint - 1 ); - -/* Create a PointSet to hold the grid of input positions. Use columns 2 - and 3 of the table to hold the PointSet values. */ - ps1 = astPointSet( *nsamp, 2, " ", status ); - ptr1[ 0 ] = result[ 2 ]; - ptr1[ 1 ] = result[ 3 ]; - astSetPoints( ps1, ptr1 ); - -/* Create a PointSet to hold the grid of output positions. Use columns 0 - and 1 of the table to hold the PointSet values. */ - ps2 = astPointSet( *nsamp, 2, " ", status ); - ptr2[ 0 ] = result[ 0 ]; - ptr2[ 1 ] = result[ 1 ]; - astSetPoints( ps2, ptr2 ); - if( astOK ) { - -/* Calculate the grid of input positions and store in the PointSet and - therefore also in the returned table. Rounding error may cause the - final point on each axis to be just over the upper bound, so we leave - the final point out of the loop and set it explicitly to the upper bound - afterwards. */ - val0 = lbnd[ 0 ]; - p0 = ptr1[ 0 ]; - p1 = ptr1[ 1 ]; - for( i = 0; i < npoint - 1; i++ ) { - val1 = lbnd[ 1 ]; - for( j = 0; j < npoint-1; j++ ) { - *(p0++) = val0; - *(p1++) = val1; - val1 += delta1; - } - *(p0++) = val0; - *(p1++) = ubnd[ 1 ]; - val0 += delta0; - } - - - val1 = lbnd[ 1 ]; - for( j = 0; j < npoint-1; j++ ) { - *(p0++) = ubnd[ 0 ]; - *(p1++) = val1; - val1 += delta1; - } - *(p0++) = ubnd[ 0 ]; - *(p1++) = ubnd[ 1 ]; - - -/* Transform the input grid to get the output grid. */ - (void) astTransform( this, ps1, forward, ps2 ); - -/* Scale each pair of columns in turn. Use the same scale factor for - each axis in order to ensure an isotropic metric. */ - for( icol = 0; icol < 4; icol += 2 ) { - -/* Find the RMS of the values in the two columns. */ - sum = 0.0; - p0 = result[ icol ]; - p1 = p0 + (*nsamp); - for( ; p0 < p1; p0++ ) sum += ( *p0 )*( *p0 ); - - p0 = result[ icol + 1 ]; - p1 = p0 + (*nsamp); - for( ; p0 < p1; p0++ ) sum += ( *p0 )*( *p0 ); - - rms = sqrt( sum/(2*(*nsamp)) ); - -/* Divide the table values by the RMS. */ - p0 = result[ icol ]; - p1 = p0 + (*nsamp); - for( ; p0 < p1; p0++ ) *p0 /= rms; - - p0 = result[ icol + 1 ]; - p1 = p0 + (*nsamp); - for( ; p0 < p1; p0++ ) *p0 /= rms; - -/* Return the RMS as the scale factor. */ - scales[ icol ] = rms; - scales[ icol + 1 ] = rms; - } - } - -/* Free resources */ - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - -/* If an error occurred, free the returned array. */ - if( !astOK ) result = astFreeDouble( result ); - -/* Return a pointer to the table. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a PolyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* PolyMap member function (over-rides the astSetAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function assigns an attribute value for a PolyMap, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the PolyMap. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstPolyMap *this; /* Pointer to the PolyMap structure */ - double dval; /* Floating point attribute value */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PolyMap structure. */ - this = (AstPolyMap *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* IterInverse. */ -/* ------------ */ - if ( nc = 0, - ( 1 == astSscanf( setting, "iterinverse= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetIterInverse( this, ival ); - -/* NiterInverse. */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "niterinverse= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetNiterInverse( this, ival ); - -/* TolInverse. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "tolinverse= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetTolInverse( this, dval ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void StoreArrays( AstPolyMap *this, int forward, int ncoeff, - const double *coeff, int *status ){ -/* -* Name: -* StoreArrays - -* Purpose: -* Store the dynamic arrays for a single transformation within a PolyMap - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* void StoreArrays( AstPolyMap *this, int forward, int ncoeff, -* const double *coeff, int *status ) - -* Class Membership: -* PolyMap initialiser. - -* Description: -* This function sets up the arrays within a PolyMap structure that -* describes either the forward or inverse transformation. - -* Parameters: -* this -* The PolyMap. -* forward -* If non-zero, replace the forward transformation. Otherwise, -* replace the inverse transformation. -* ncoeff -* The number of non-zero coefficients necessary to define the -* specified transformation of the PolyMap. If zero is supplied, the -* transformation will be undefined. -* coeff -* An array containing "ncof*( 2 + nin )" elements. Each group -* of "2 + nin" adjacent elements describe a single coefficient of -* the transformation. Within each such group, the first -* element is the coefficient value; the next element is the -* integer index of the PolyMap output which uses the coefficient -* within its defining polynomial (the first output has index 1); -* the remaining elements of the group give the integer powers to -* use with each input coordinate value (powers must not be -* negative). -* status -* Pointer to inherited status. -*/ - -/* Local Variables: */ - const double *group; /* Pointer to start of next coeff. description */ - int *pows; /* Pointer to powers for current coeff. */ - int gsize; /* Length of each coeff. description */ - int i; /* Loop count */ - int ico; /* Index of next coeff. for current input or output */ - int iin; /* Input index extracted from coeff. description */ - int iout; /* Output index extracted from coeff. description */ - int j; /* Loop count */ - int nin; /* Number of inputs */ - int nout; /* Number of outputs */ - int pow; /* Power extracted from coeff. description */ - -/* Check the global status. */ - if ( !astOK ) return; - -/* Get the number of inputs and outputs. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - -/* First Free any existing arrays. */ - FreeArrays( this, forward, status ); - -/* Now initialise the forward transformation, if required. */ - if( forward && ncoeff > 0 ) { - -/* Create the arrays decribing the forward transformation. */ - this->ncoeff_f = astMalloc( sizeof( int )*(size_t) nout ); - this->mxpow_f = astMalloc( sizeof( int )*(size_t) nin ); - this->power_f = astMalloc( sizeof( int ** )*(size_t) nout ); - this->coeff_f = astMalloc( sizeof( double * )*(size_t) nout ); - if( astOK ) { - -/* Initialise the count of coefficients for each output coordinate to zero. */ - for( i = 0; i < nout; i++ ) this->ncoeff_f[ i ] = 0; - -/* Initialise max power for each input coordinate to zero. */ - for( j = 0; j < nin; j++ ) this->mxpow_f[ j ] = 0; - -/* Scan through the supplied forward coefficient array, counting the - number of coefficients which relate to each output. Also find the - highest power used for each input axis. Report errors if any unusable - values are found in the supplied array. */ - group = coeff; - gsize = 2 + nin; - for( i = 0; i < ncoeff && astOK; i++, group += gsize ) { - - iout = floor( group[ 1 ] + 0.5 ); - if( iout < 1 || iout > nout ) { - astError( AST__BADCI, "astInitPolyMap(%s): Forward " - "coefficient %d referred to an illegal output " - "coordinate %d.", status, astGetClass( this ), i + 1, - iout ); - astError( AST__BADCI, "This number should be in the " - "range 1 to %d.", status, nout ); - break; - } - - this->ncoeff_f[ iout - 1 ]++; - - for( j = 0; j < nin; j++ ) { - pow = floor( group[ 2 + j ] + 0.5 ); - if( pow < 0 ) { - astError( AST__BADPW, "astInitPolyMap(%s): Forward " - "coefficient %d has a negative power (%d) " - "for input coordinate %d.", status, - astGetClass( this ), i + 1, pow, j + 1 ); - astError( AST__BADPW, "All powers should be zero or " - "positive." , status); - break; - } - if( pow > this->mxpow_f[ j ] ) this->mxpow_f[ j ] = pow; - } - } - -/* Allocate the arrays to store the input powers associated with each - coefficient, and the coefficient values. Reset the coefficient count - for each axis to zero afterwards so that we can use the array as an index - to the next vacant slot withint he following loop. */ - for( i = 0; i < nout; i++ ) { - this->power_f[ i ] = astMalloc( sizeof( int * )* - (size_t) this->ncoeff_f[ i ] ); - this->coeff_f[ i ] = astMalloc( sizeof( double )* - (size_t) this->ncoeff_f[ i ] ); - this->ncoeff_f[ i ] = 0; - } - - if( astOK ) { - -/* Extract the coefficient values and powers form the supplied array and - store them in the arrays created above. */ - group = coeff; - for( i = 0; i < ncoeff && astOK; i++, group += gsize ) { - iout = floor( group[ 1 ] + 0.5 ) - 1; - ico = ( this->ncoeff_f[ iout ] )++; - this->coeff_f[ iout ][ ico ] = group[ 0 ]; - - pows = astMalloc( sizeof( int )*(size_t) nin ); - this->power_f[ iout ][ ico ] = pows; - if( astOK ) { - for( j = 0; j < nin; j++ ) { - pows[ j ] = floor( group[ 2 + j ] + 0.5 ); - } - } - } - } - } - } - -/* Now initialise the inverse transformation, if required. */ - if( !forward && ncoeff > 0 ) { - -/* Create the arrays decribing the inverse transformation. */ - this->ncoeff_i = astMalloc( sizeof( int )*(size_t) nin ); - this->mxpow_i = astMalloc( sizeof( int )*(size_t) nout ); - this->power_i = astMalloc( sizeof( int ** )*(size_t) nin ); - this->coeff_i = astMalloc( sizeof( double * )*(size_t) nin ); - if( astOK ) { - -/* Initialise the count of coefficients for each input coordinate to zero. */ - for( i = 0; i < nin; i++ ) this->ncoeff_i[ i ] = 0; - -/* Initialise max power for each output coordinate to zero. */ - for( j = 0; j < nout; j++ ) this->mxpow_i[ j ] = 0; - -/* Scan through the supplied inverse coefficient array, counting the - number of coefficients which relate to each input. Also find the - highest power used for each output axis. Report errors if any unusable - values are found in the supplied array. */ - group = coeff; - - gsize = 2 + nout; - for( i = 0; i < ncoeff && astOK; i++, group += gsize ) { - - iin = floor( group[ 1 ] + 0.5 ); - if( iin < 1 || iin > nin ) { - astError( AST__BADCI, "astInitPolyMap(%s): Inverse " - "coefficient %d referred to an illegal input " - "coordinate %d.", status, astGetClass( this ), - i + 1, iin ); - astError( AST__BADCI, "This number should be in the " - "range 1 to %d.", status, nin ); - break; - } - - this->ncoeff_i[ iin - 1 ]++; - - for( j = 0; j < nout; j++ ) { - pow = floor( group[ 2 + j ] + 0.5 ); - if( pow < 0 ) { - astError( AST__BADPW, "astInitPolyMap(%s): Inverse " - "coefficient %d has a negative power (%d) " - "for output coordinate %d.", status, - astGetClass( this ), i + 1, pow, j + 1 ); - astError( AST__BADPW, "All powers should be zero or " - "positive." , status); - break; - } - if( pow > this->mxpow_i[ j ] ) this->mxpow_i[ j ] = pow; - } - } - -/* Allocate the arrays to store the output powers associated with each - coefficient, and the coefficient values. Reset the coefficient count - for each axis to zero afterwards so that we can use the array as an index - to the next vacant slot within the following loop. */ - for( i = 0; i < nin; i++ ) { - this->power_i[ i ] = astMalloc( sizeof( int * )* - (size_t) this->ncoeff_i[ i ] ); - this->coeff_i[ i ] = astMalloc( sizeof( double )* - (size_t) this->ncoeff_i[ i ] ); - this->ncoeff_i[ i ] = 0; - } - - if( astOK ) { - -/* Extract the coefficient values and powers form the supplied array and - store them in the arrays created above. */ - group = coeff; - for( i = 0; i < ncoeff && astOK; i++, group += gsize ) { - iin = floor( group[ 1 ] + 0.5 ) - 1; - ico = ( this->ncoeff_i[ iin ] )++; - this->coeff_i[ iin ][ ico ] = group[ 0 ]; - - pows = astMalloc( sizeof( int )*(size_t) nout ); - this->power_i[ iin ][ ico ] = pows; - if( astOK ) { - for( j = 0; j < nout; j++ ) { - pows[ j ] = floor( group[ 2 + j ] + 0.5 ); - } - } - } - } - } - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a PolyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* PolyMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a PolyMap's attributes. - -* Parameters: -* this -* Pointer to the PolyMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPolyMap *this; /* Pointer to the PolyMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the PolyMap structure. */ - this = (AstPolyMap *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* IterInverse. */ -/* ------------ */ - if ( !strcmp( attrib, "iterinverse" ) ) { - result = astTestIterInverse( this ); - -/* NiterInverse. */ -/* ------------- */ - } else if ( !strcmp( attrib, "niterinverse" ) ) { - result = astTestNiterInverse( this ); - -/* TolInverse. */ -/* ----------- */ - } else if ( !strcmp( attrib, "tolinverse" ) ) { - result = astTestTolInverse( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a PolyMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* PolyMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a PolyMap and a set of points encapsulated in a -* PointSet and transforms the points. - -* Parameters: -* this -* Pointer to the PolyMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of columns in the PolyMap being applied. -* - The number of coordinate values per point in the output PointSet will -* equal the number of rows in the PolyMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstPolyMap *map; /* Pointer to PolyMap to be applied */ - double **coeff; /* Pointer to coefficient value arrays */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double **work; /* Pointer to exponentiated axis values */ - double *outcof; /* Pointer to next coefficient value */ - double outval; /* Output axis value */ - double term; /* Term to be added to output value */ - double xp; /* Exponentiated input axis value */ - int ***power; /* Pointer to coefficient power arrays */ - int **outpow; /* Pointer to next set of axis powers */ - int *mxpow; /* Pointer to max used power for each input */ - int *ncoeff; /* Pointer to no. of coefficients */ - int in_coord; /* Index of output coordinate */ - int ico; /* Coefficient index */ - int nc; /* No. of coefficients in polynomial */ - int ncoord_in; /* Number of coordinates per input point */ - int ncoord_out; /* Number of coordinates per output point */ - int npoint; /* Number of points */ - int out_coord; /* Index of output coordinate */ - int point; /* Loop counter for points */ - int pow; /* Next axis power */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the PolyMap. */ - map = (AstPolyMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* Determine whether to apply the original forward or inverse mapping, - according to the direction specified and whether the mapping has been - inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* If we are using the original inverse transformatiom, and the IterInverse - attribute is non-zero, use an iterative inverse algorithm rather than any - inverse transformation defined within the PolyMap. */ - if( !forward && astGetIterInverse(map) ) { - IterInverse( map, in, result, status ); - -/* Otherwise, determine the numbers of points and coordinates per point from - the input and output PointSets and obtain pointers for accessing the input - and output coordinate values. */ - } else { - ncoord_in = astGetNcoord( in ); - ncoord_out = astGetNcoord( result ); - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Get a pointer to the arrays holding the required coefficient - values and powers, according to the direction of mapping required. */ - if ( forward ) { - ncoeff = map->ncoeff_f; - coeff = map->coeff_f; - power = map->power_f; - mxpow = map->mxpow_f; - } else { - ncoeff = map->ncoeff_i; - coeff = map->coeff_i; - power = map->power_i; - mxpow = map->mxpow_i; - } - -/* Allocate memory to hold the required powers of the input axis values. */ - work = astMalloc( sizeof( double * )*(size_t) ncoord_in ); - for( in_coord = 0; in_coord < ncoord_in; in_coord++ ) { - work[ in_coord ] = astMalloc( sizeof( double )* - (size_t) ( astMAX( 2, mxpow[in_coord]+1 ) ) ); - } - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - -/* Loop to apply the polynomial to each point in turn.*/ - for ( point = 0; point < npoint; point++ ) { - -/* Find the required powers of the input axis values and store them - in the work array. Note, using a virtual method here slows the PolyMap - Transform function down by about 5%, compared to doing the equivalent - calculations in-line. But we need some way to allow the ChebyMap class - to over-ride the calculation of the powers, so we must do something - like this. If the 5% slow-down is too much, it can be reduced down to - about 2% by replacing the invocation of the astPolyPowers_ interface - function with a direct call to the implementation function itself. - This involves replacing the astPolyPowers call below with this: - - (**astMEMBER(this,PolyMap,PolyPowers))( (AstPolyMap *) this, work, ncoord_in, - mxpow, ptr_in, point, forward, status ); - - The above could be wrapped up in an alternative implementation of the - astPolyPowers macro, so that it looks the same as the existing code. - In fact, this scheme could be more widely used to speed up invocation - of virtual functions within AST. The disadvantage is that the interface - functions for some virtual methods includes some extra processing, - over and above simply invoking the implementation function. - - Of course the other way to get rid of the 5% slow down, is to - revert to using in-line code below, and then replicate this entire - function in the ChebyMap class, making suitable changes to use - Chebyshev functions in place of simple powers. But that is bad - structuring... */ - astPolyPowers( this, work, ncoord_in, mxpow, ptr_in, point, - forward ); - -/* Loop round each output. */ - for( out_coord = 0; out_coord < ncoord_out; out_coord++ ) { - -/* Initialise the output value. */ - outval = 0.0; - -/* Get pointers to the coefficients and powers for this output. */ - outcof = coeff[ out_coord ]; - outpow = power[ out_coord ]; - -/* Loop round all polynomial coefficients.*/ - nc = ncoeff[ out_coord ]; - for ( ico = 0; ico < nc && outval != AST__BAD; - ico++, outcof++, outpow++ ) { - -/* Initialise the current term to be equal to the value of the coefficient. - If it is bad, store a bad output value. */ - term = *outcof; - if( term == AST__BAD ) { - outval = AST__BAD; - -/* Otherwise, loop round all inputs */ - } else { - for( in_coord = 0; in_coord < ncoord_in; in_coord++ ) { - -/* Get the power of the current input axis value used by the current - coefficient. If it is zero, pass on. */ - pow = (*outpow)[ in_coord ]; - if( pow > 0 ) { - -/* Get the axis value raised to the appropriate power. */ - xp = work[ in_coord ][ pow ]; - -/* If bad, set the output value bad and break. */ - if( xp == AST__BAD ) { - outval = AST__BAD; - break; - -/* Otherwise multiply the current term by the exponentiated axis value. */ - } else { - term *= xp; - } - } - } - } - -/* Increment the output value by the current term of the polynomial. */ - if( outval != AST__BAD ) outval += term; - - } - -/* Store the output value. */ - ptr_out[ out_coord ][ point ] = outval; - - } - } - } - -/* Free resources. */ - for( in_coord = 0; in_coord < ncoord_in; in_coord++ ) { - work[ in_coord ] = astFree( work[ in_coord ] ); - } - work = astFree( work ); - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* IterInverse - -* Purpose: -* Provide an iterative inverse transformation? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute indicates whether the inverse transformation of -* the PolyMap should be implemented via an iterative Newton-Raphson -* approximation that uses the forward transformation to transform -* candidate input positions until an output position is found which -* is close to the required output position. By default, an iterative -* inverse is provided if, and only if, no inverse polynomial was supplied -* when the PolyMap was constructed. -* -* The NiterInverse and TolInverse attributes provide parameters that -* control the behaviour of the inverse approximation method. -* -* The iterative inverse returns AST__BAD axis values at positions -* for which the inverse transformation is undefined. For instance, -* if the forward transformation is y = x*x, the iterative inverse -* will return x = AST__BAD at y = -1. If the inverse transformation -* is multiply defined, the position returned by the iterative inverse -* will be the position of the solution that is closest to the -* supplied position. For instance, using the above example, y = x*x, -* the iterative inverse will return x = +2 at y = 4, because x = +2 -* is the closest solution to 4 (the other solution is x = -2). - -* Applicability: -* PolyMap -* All PolyMaps have this attribute. -* ChebyMap -* The ChebyMap class does not currently provide an option for an -* iterative inverse, and so the IterInverse value is always zero. -* Setting or clearing the IterInverse attribute of a ChebyMap has -* no effect. - -* Notes: -* - The transformation replaced by the iterative algorithm is the -* transformation from the original PolyMap output space to the -* original PolyMap input space (i.e. the input and output spaces as -* defined by the arguments of the PolyMap constructor). This is still -* the case even if the PolyMap has subsequently been inverted. In -* other words if a PolyMap is created and then inverted, setting -* the IterInverse to a non-zero value will replace the forward -* transformation of the inverted PolyMap (i.e. the inverse -* transformation of the original PolyMap). It is not possible to -* replace the other transformation (i.e. from the original PolyMap -* input space to the original PolyMap output space) with an iterative -* algorithm. -* - If a PolyMap that has an iterative inverse transformation is -* subsequently inverted, the inverted PolyMap will have an iterative -* forward transformation. -* - An iterative inverse can only be used if the PolyMap has equal -* numbers of inputs and outputs, as given by the Nin and Nout -* attributes. An error will be reported if IterInverse is set non-zero -* for a PolyMap that does not meet this requirement. - -*att-- -*/ -astMAKE_CLEAR(PolyMap,IterInverse,iterinverse,-INT_MAX) -astMAKE_GET(PolyMap,IterInverse,int,0,( ( this->iterinverse == -INT_MAX ) ? - (this->ncoeff_i == 0) : this->iterinverse )) -astMAKE_SET(PolyMap,IterInverse,int,iterinverse, - (((astGetNin(this)==astGetNout(this))||!value)?((value?1:0)):(astError(AST__ATTIN,"astSetIterInverse(%s):" - "Cannot use an iterative inverse because the %s has unequal numbers of " - "inputs and outputs.", status, astGetClass(this),astGetClass(this)),this->iterinverse))) -astMAKE_TEST(PolyMap,IterInverse,( this->iterinverse != -INT_MAX )) - -/* NiterInverse. */ -/* --------- */ -/* -*att++ -* Name: -* NiterInverse - -* Purpose: -* Maximum number of iterations for the iterative inverse transformation. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute controls the iterative inverse transformation -* used if the IterInverse attribute is non-zero. -* -* Its value gives the maximum number of iterations of the -* Newton-Raphson algorithm to be used for each transformed position. -* The default value is 4. See also attribute TolInverse. - -* Applicability: -* PolyMap -* All PolyMaps have this attribute. - -*att-- -*/ -astMAKE_CLEAR(PolyMap,NiterInverse,niterinverse,-INT_MAX) -astMAKE_GET(PolyMap,NiterInverse,int,0,( this->niterinverse == -INT_MAX ? 4 : this->niterinverse)) -astMAKE_SET(PolyMap,NiterInverse,int,niterinverse,value) -astMAKE_TEST(PolyMap,NiterInverse,( this->niterinverse != -INT_MAX )) - -/* TolInverse. */ -/* ----------- */ -/* -*att++ -* Name: -* TolInverse - -* Purpose: -* Target relative error for the iterative inverse transformation. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the iterative inverse transformation -* used if the IterInverse attribute is non-zero. -* -* Its value gives the target relative error in the axis values of -* each transformed position. Further iterations will be performed -* until the target relative error is reached, or the maximum number -* of iterations given by attribute NiterInverse is reached. - -* The default value is 1.0E-6. - -* Applicability: -* PolyMap -* All PolyMaps have this attribute. -*att-- -*/ -astMAKE_CLEAR(PolyMap,TolInverse,tolinverse,AST__BAD) -astMAKE_GET(PolyMap,TolInverse,double,0.0,( this->tolinverse == AST__BAD ? 1.0E-6 : this->tolinverse)) -astMAKE_SET(PolyMap,TolInverse,double,tolinverse,value) -astMAKE_TEST(PolyMap,TolInverse,( this->tolinverse != AST__BAD )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for PolyMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for PolyMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the -* coefficients associated with the input PolyMap. -*/ - - -/* Local Variables: */ - AstPolyMap *in; /* Pointer to input PolyMap */ - AstPolyMap *out; /* Pointer to output PolyMap */ - int nin; /* No. of input coordinates */ - int nout; /* No. of output coordinates */ - int i; /* Loop count */ - int j; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output PolyMaps. */ - in = (AstPolyMap *) objin; - out = (AstPolyMap *) objout; - -/* Nullify the pointers stored in the output object since these will - currently be pointing at the input data (since the output is a simple - byte-for-byte copy of the input). Otherwise, the input data could be - freed by accidient if the output object is deleted due to an error - occuring in this function. */ - out->ncoeff_f = NULL; - out->power_f = NULL; - out->coeff_f = NULL; - out->mxpow_f = NULL; - - out->ncoeff_i = NULL; - out->power_i = NULL; - out->coeff_i = NULL; - out->mxpow_i = NULL; - - out->jacobian = NULL; - -/* Get the number of inputs and outputs of the uninverted Mapping. */ - nin = ( (AstMapping *) in )->nin; - nout = ( (AstMapping *) in )->nout; - -/* Copy the number of coefficients associated with each output of the forward - transformation. */ - if( in->ncoeff_f ) { - out->ncoeff_f = (int *) astStore( NULL, (void *) in->ncoeff_f, - sizeof( int )*(size_t) nout ); - -/* Copy the maximum power of each input axis value used by the forward - transformation. */ - out->mxpow_f = (int *) astStore( NULL, (void *) in->mxpow_f, - sizeof( int )*(size_t) nin ); - -/* Copy the coefficient values used by the forward transformation. */ - if( in->coeff_f ) { - out->coeff_f = astMalloc( sizeof( double * )*(size_t) nout ); - if( astOK ) { - for( i = 0; i < nout; i++ ) { - out->coeff_f[ i ] = (double *) astStore( NULL, (void *) in->coeff_f[ i ], - sizeof( double )*(size_t) in->ncoeff_f[ i ] ); - } - } - } - -/* Copy the input axis powers associated with each coefficient of the forward - transformation. */ - if( in->power_f ) { - out->power_f = astMalloc( sizeof( int ** )*(size_t) nout ); - if( astOK ) { - for( i = 0; i < nout; i++ ) { - out->power_f[ i ] = astMalloc( sizeof( int * )*(size_t) in->ncoeff_f[ i ] ); - if( astOK ) { - for( j = 0; j < in->ncoeff_f[ i ]; j++ ) { - out->power_f[ i ][ j ] = (int *) astStore( NULL, (void *) in->power_f[ i ][ j ], - sizeof( int )*(size_t) nin ); - } - } - } - } - } - } - -/* Do the same for the inverse transformation. */ - if( in->ncoeff_i ) { - out->ncoeff_i = (int *) astStore( NULL, (void *) in->ncoeff_i, - sizeof( int )*(size_t) nin ); - - out->mxpow_i = (int *) astStore( NULL, (void *) in->mxpow_i, - sizeof( int )*(size_t) nout ); - - if( in->coeff_i ) { - out->coeff_i = astMalloc( sizeof( double * )*(size_t) nin ); - if( astOK ) { - for( i = 0; i < nin; i++ ) { - out->coeff_i[ i ] = (double *) astStore( NULL, (void *) in->coeff_i[ i ], - sizeof( double )*(size_t) in->ncoeff_i[ i ] ); - } - } - } - - if( in->power_i ) { - out->power_i = astMalloc( sizeof( int ** )*(size_t) nin ); - if( astOK ) { - for( i = 0; i < nin; i++ ) { - out->power_i[ i ] = astMalloc( sizeof( int * )*(size_t) in->ncoeff_i[ i ] ); - if( astOK ) { - for( j = 0; j < in->ncoeff_i[ i ]; j++ ) { - out->power_i[ i ][ j ] = (int *) astStore( NULL, (void *) in->power_i[ i ][ j ], - sizeof( int )*(size_t) nout ); - } - } - } - } - } - } - -/* If an error has occurred, free al the resources allocated above. */ - if( !astOK ) { - FreeArrays( out, 1, status ); - FreeArrays( out, 0, status ); - } - - return; - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for PolyMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for PolyMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstPolyMap *this; - int nc; - int ic; - int lstat; - int error; - -/* Obtain a pointer to the PolyMap structure. */ - this = (AstPolyMap *) obj; - -/* Free the arrays. */ - FreeArrays( this, 1, status ); - FreeArrays( this, 0, status ); - -/* Free the resources used to store the Jacobian of the forward - transformation. */ - if( this->jacobian ) { - -/* Get the number of PolyMap inputs. We need to clear any error status - first since astGetNin returns zero if an error has occurred. The - Jacobian will only be non-NULL if the number of inputs and outputs - are equal. */ - error = !astOK; - if( error ) { - lstat = astStatus; - astClearStatus; - } - nc = astGetNin( this ); - if( error ) astSetStatus( lstat ); - - for( ic = 0; ic < nc; ic++ ) { - (this->jacobian)[ ic ] = astAnnul( (this->jacobian)[ ic ] ); - } - this->jacobian = astFree( this->jacobian ); - } -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for PolyMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the PolyMap class to an output Channel. - -* Parameters: -* this -* Pointer to the PolyMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstPolyMap *this; /* Pointer to the PolyMap structure */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char comm[ 100 ]; /* Buffer for comment string */ - double dval; /* Floating point attribute value */ - int i; /* Loop index */ - int iv; /* Vectorised keyword index */ - int ival; /* Integer value */ - int j; /* Loop index */ - int k; /* Loop index */ - int nin; /* No. of input coords */ - int nout; /* No. of output coords */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the PolyMap structure. */ - this = (AstPolyMap *) this_object; - -/* Find the number of inputs and outputs of the uninverted Mapping. */ - nin = ( (AstMapping *) this )->nin; - nout = ( (AstMapping *) this )->nout; - -/* Write out values representing the instance variables for the - PolyMap class. */ - -/* First do the forward transformation arrays. Check they are used. */ - if( this->ncoeff_f ) { - -/* Store the maximum power of each input axis value used by the forward - transformation. */ - for( i = 0; i < nin; i++ ){ - (void) sprintf( buff, "MPF%d", i + 1 ); - (void) sprintf( comm, "Max. power of input %d in any forward polynomial", i + 1 ); - astWriteInt( channel, buff, 1, 1, (this->mxpow_f)[ i ], comm ); - } - -/* Store the number of coefficients associated with each output of the forward - transformation. */ - for( i = 0; i < nout; i++ ){ - (void) sprintf( buff, "NCF%d", i + 1 ); - (void) sprintf( comm, "No. of coeff.s for forward polynomial %d", i + 1 ); - astWriteInt( channel, buff, 1, 1, (this->ncoeff_f)[ i ], comm ); - } - -/* Store the coefficient values used by the forward transformation. */ - iv = 1; - for( i = 0; i < nout; i++ ){ - for( j = 0; j < this->ncoeff_f[ i ]; j++, iv++ ){ - if( (this->coeff_f)[ i ][ j ] != AST__BAD ) { - (void) sprintf( buff, "CF%d", iv ); - (void) sprintf( comm, "Coeff %d of forward polynomial %d", j + 1, i + 1 ); - astWriteDouble( channel, buff, 1, 1, (this->coeff_f)[ i ][ j ], comm ); - } - } - } - -/* Store the input axis powers associated with each coefficient of the forward - transformation. */ - iv = 1; - for( i = 0; i < nout; i++ ){ - for( j = 0; j < this->ncoeff_f[ i ]; j++ ){ - for( k = 0; k < nin; k++, iv++ ){ - if( (this->power_f)[ i ][ j ][ k ] > 0 ) { - (void) sprintf( buff, "PF%d", iv ); - (void) sprintf( comm, "Power of i/p %d for coeff %d of fwd poly %d", k + 1, j + 1, i + 1 ); - astWriteDouble( channel, buff, 1, 1, (this->power_f)[ i ][ j ][ k ], comm ); - } - } - } - } - } - -/* Now do the inverse transformation arrays. Check they are used. */ - if( this->ncoeff_i ) { - -/* Store the maximum power of each output axis value used by the inverse - transformation. */ - for( i = 0; i < nout; i++ ){ - (void) sprintf( buff, "MPI%d", i + 1 ); - (void) sprintf( comm, "Max. power of output %d in any inverse polynomial", i + 1 ); - astWriteInt( channel, buff, 1, 1, (this->mxpow_i)[ i ], comm ); - } - -/* Store the number of coefficients associated with each input of the inverse - transformation. */ - for( i = 0; i < nin; i++ ){ - (void) sprintf( buff, "NCI%d", i + 1 ); - (void) sprintf( comm, "No. of coeff.s for inverse polynomial %d", i + 1 ); - astWriteInt( channel, buff, 1, 1, (this->ncoeff_i)[ i ], comm ); - } - -/* Store the coefficient values used by the inverse transformation. */ - iv = 1; - for( i = 0; i < nin; i++ ){ - for( j = 0; j < this->ncoeff_i[ i ]; j++, iv++ ){ - if( (this->coeff_i)[ i ][ j ] != AST__BAD ) { - (void) sprintf( buff, "CI%d", iv ); - (void) sprintf( comm, "Coeff %d of inverse polynomial %d", j + 1, i + 1 ); - astWriteDouble( channel, buff, 1, 1, (this->coeff_i)[ i ][ j ], comm ); - } - } - } - -/* Store the output axis powers associated with each coefficient of the inverse - transformation. */ - iv = 1; - for( i = 0; i < nin; i++ ){ - for( j = 0; j < this->ncoeff_i[ i ]; j++ ){ - for( k = 0; k < nout; k++, iv++ ){ - if( (this->power_i)[ i ][ j ][ k ] > 0 ) { - (void) sprintf( buff, "PI%d", iv ); - (void) sprintf( comm, "Power of o/p %d for coeff %d of inv poly %d", k + 1, j + 1, i + 1 ); - astWriteDouble( channel, buff, 1, 1, (this->power_i)[ i ][ j ][ k ], comm ); - } - } - } - } - } - -/* Use an iterative inverse? */ - set = TestIterInverse( this, status ); - ival = set ? GetIterInverse( this, status ) : astGetIterInverse( this ); - astWriteInt( channel, "IterInv", set, 0, ival, ival ? "Use an iterative inverse" : "Do not use an iterative inverse" ); - -/* Max number of iterations for iterative inverse. */ - set = TestNiterInverse( this, status ); - ival = set ? GetNiterInverse( this, status ) : astGetNiterInverse( this ); - astWriteInt( channel, "NiterInv", set, 0, ival, "Max number of iterations for iterative inverse" ); - -/* Target relative error for iterative inverse. */ - set = TestTolInverse( this, status ); - dval = set ? GetTolInverse( this, status ) : astGetTolInverse( this ); - astWriteDouble( channel, "TolInv", set, 0, dval, "Target relative error for iterative inverse" ); - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPolyMap and astCheckPolyMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(PolyMap,Mapping) -astMAKE_CHECK(PolyMap) - -AstPolyMap *astPolyMap_( int nin, int nout, int ncoeff_f, const double coeff_f[], - int ncoeff_i, const double coeff_i[], const char *options, int *status, ...){ -/* -*++ -* Name: -c astPolyMap -f AST_POLYMAP - -* Purpose: -* Create a PolyMap. - -* Type: -* Public function. - -* Synopsis: -c #include "polymap.h" -c AstPolyMap *astPolyMap( int nin, int nout, int ncoeff_f, const double coeff_f[], -c int ncoeff_i, const double coeff_i[], -c const char *options, ... ) -f RESULT = AST_POLYMAP( NIN, NOUT, NCOEFF_F, COEFF_F, NCOEFF_I, COEFF_I, -f OPTIONS, STATUS ) - -* Class Membership: -* PolyMap constructor. - -* Description: -* This function creates a new PolyMap and optionally initialises -* its attributes. -* -* A PolyMap is a form of Mapping which performs a general polynomial -* transformation. Each output coordinate is a polynomial function of -* all the input coordinates. The coefficients are specified separately -* for each output coordinate. The forward and inverse transformations -* are defined independantly by separate sets of coefficients. If no -* inverse transformation is supplied, the default behaviour is to use -* an iterative method to evaluate the inverse based only on the forward -* transformation (see attribute IterInverse). - -* Parameters: -c nin -f NIN = INTEGER (Given) -* The number of input coordinates. -c nout -f NOUT = INTEGER (Given) -* The number of output coordinates. -c ncoeff_f -f NCOEFF_F = INTEGER (Given) -* The number of non-zero coefficients necessary to define the -* forward transformation of the PolyMap. If zero is supplied, the -* forward transformation will be undefined. -c coeff_f -f COEFF_F( * ) = DOUBLE PRECISION (Given) -* An array containing -c "ncoeff_f*( 2 + nin )" elements. Each group of "2 + nin" -f "NCOEFF_F*( 2 + NIN )" elements. Each group of "2 + NIN" -* adjacent elements describe a single coefficient of the forward -* transformation. Within each such group, the first element is the -* coefficient value; the next element is the integer index of the -* PolyMap output which uses the coefficient within its defining -* polynomial (the first output has index 1); the remaining elements -* of the group give the integer powers to use with each input -* coordinate value (powers must not be negative, and floating -* point values are rounded to the nearest integer). -c If "ncoeff_f" is zero, a NULL pointer may be supplied for "coeff_f". -* -* For instance, if the PolyMap has 3 inputs and 2 outputs, each group -* consisting of 5 elements, A groups such as "(1.2, 2.0, 1.0, 3.0, 0.0)" -* describes a coefficient with value 1.2 which is used within the -* definition of output 2. The output value is incremented by the -* product of the coefficient value, the value of input coordinate -* 1 raised to the power 1, and the value of input coordinate 2 raised -* to the power 3. Input coordinate 3 is not used since its power is -* specified as zero. As another example, the group "(-1.0, 1.0, -* 0.0, 0.0, 0.0 )" describes adds a constant value -1.0 onto -* output 1 (it is a constant value since the power for every input -* axis is given as zero). -* -c Each final output coordinate value is the sum of the "ncoeff_f" terms -c described by the "ncoeff_f" groups within the supplied array. -f Each final output coordinate value is the sum of the "NCOEFF_F" terms -f described by the "NCOEFF_F" groups within the supplied array. -c ncoeff_i -f NCOEFF_I = INTEGER (Given) -* The number of non-zero coefficients necessary to define the -* inverse transformation of the PolyMap. If zero is supplied, the -* default behaviour is to use an iterative method to evaluate the -* inverse based only on the forward transformation (see attribute -* IterInverse). -c coeff_i -f COEFF_I( * ) = DOUBLE PRECISION (Given) -* An array containing -c "ncoeff_i*( 2 + nout )" elements. Each group of "2 + nout" -f "NCOEFF_I*( 2 + NOUT )" elements. Each group of "2 + NOUT" -* adjacent elements describe a single coefficient of the inverse -c transformation, using the same schame as "coeff_f", -f transformation, using the same schame as "COEFF_F", -* except that "inputs" and "outputs" are transposed. -c If "ncoeff_i" is zero, a NULL pointer may be supplied for "coeff_i". -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new PolyMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new PolyMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPolyMap() -f AST_POLYMAP = INTEGER -* A pointer to the new PolyMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPolyMap *new; /* Pointer to new PolyMap */ - va_list args; /* Variable argument list */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise the PolyMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPolyMap( NULL, sizeof( AstPolyMap ), !class_init, - &class_vtab, "PolyMap", nin, nout, - ncoeff_f, coeff_f, ncoeff_i, coeff_i ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new PolyMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new PolyMap. */ - return new; -} - -AstPolyMap *astPolyMapId_( int nin, int nout, int ncoeff_f, const double coeff_f[], - int ncoeff_i, const double coeff_i[], const char *options, ... ){ -/* -* Name: -* astPolyMapId_ - -* Purpose: -* Create a PolyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "polymap.h" -* AstPolyMap *astPolyMap( int nin, int nout, int ncoeff_f, const double coeff_f[], -* int ncoeff_i, const double coeff_i[], -* const char *options, ... ) - -* Class Membership: -* PolyMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astPolyMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astPolyMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astPolyMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astPolyMap_. - -* Returned Value: -* The ID value associated with the new PolyMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPolyMap *new; /* Pointer to new PolyMap */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the PolyMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPolyMap( NULL, sizeof( AstPolyMap ), !class_init, - &class_vtab, "PolyMap", nin, nout, - ncoeff_f, coeff_f, ncoeff_i, coeff_i ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new PolyMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new PolyMap. */ - return astMakeId( new ); -} - -AstPolyMap *astInitPolyMap_( void *mem, size_t size, int init, - AstPolyMapVtab *vtab, const char *name, - int nin, int nout, int ncoeff_f, const double coeff_f[], - int ncoeff_i, const double coeff_i[], int *status ){ -/* -*+ -* Name: -* astInitPolyMap - -* Purpose: -* Initialise a PolyMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "polymap.h" -* AstPolyMap *astInitPolyMap( void *mem, size_t size, int init, -* AstPolyMapVtab *vtab, const char *name, -* int nin, int nout, int ncoeff_f, -* const double coeff_f[], int ncoeff_i, -* const double coeff_i[] ) - -* Class Membership: -* PolyMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new PolyMap object. It allocates memory (if necessary) to accommodate -* the PolyMap plus any additional data associated with the derived class. -* It then initialises a PolyMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a PolyMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the PolyMap is to be initialised. -* This must be of sufficient size to accommodate the PolyMap data -* (sizeof(PolyMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the PolyMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the PolyMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the PolyMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new PolyMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* nin -* The number of input coordinate values per point. This is the -* same as the number of columns in the matrix. -* nout -* The number of output coordinate values per point. This is the -* same as the number of rows in the matrix. -* ncoeff_f -* The number of non-zero coefficients necessary to define the -* forward transformation of the PolyMap. If zero is supplied, the -* forward transformation will be undefined. -* coeff_f -* An array containing "ncoeff_f*( 2 + nin )" elements. Each group -* of "2 + nin" adjacent elements describe a single coefficient of -* the forward transformation. Within each such group, the first -* element is the coefficient value; the next element is the -* integer index of the PolyMap output which uses the coefficient -* within its defining polynomial (the first output has index 1); -* the remaining elements of the group give the integer powers to -* use with each input coordinate value (powers must not be -* negative) -* -* For instance, if the PolyMap has 3 inputs and 2 outputs, each group -* consisting of 5 elements, A groups such as "(1.2, 2.0, 1.0, 3.0, 0.0)" -* describes a coefficient with value 1.2 which is used within the -* definition of output 2. The output value is incremented by the -* product of the coefficient value, the value of input coordinate -* 1 raised to the power 1, and the value of input coordinate 2 raised -* to the power 3. Input coordinate 3 is not used since its power is -* specified as zero. As another example, the group "(-1.0, 1.0, -* 0.0, 0.0, 0.0 )" describes adds a constant value -1.0 onto -* output 1 (it is a constant value since the power for every input -* axis is given as zero). -* -* Each final output coordinate value is the sum of the "ncoeff_f" terms -* described by the "ncoeff_f" groups within the supplied array. -* ncoeff_i -* The number of non-zero coefficients necessary to define the -* inverse transformation of the PolyMap. If zero is supplied, the -* inverse transformation will be undefined. -* coeff_i -* An array containing -* "ncoeff_i*( 2 + nout )" elements. Each group of "2 + nout" -* adjacent elements describe a single coefficient of the inverse -* transformation, using the same schame as "coeff_f", except that -* "inputs" and "outputs" are transposed. - -* Returned Value: -* A pointer to the new PolyMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstPolyMap *new; /* Pointer to new PolyMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitPolyMapVtab( vtab, name ); - -/* Initialise a Mapping structure (the parent class) as the first component - within the PolyMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstPolyMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, nout, 1, 1 ); - if ( astOK ) { - -/* Initialise the PolyMap data. */ -/* ---------------------------- */ - -/* First initialise the pointers in case of errors. */ - new->ncoeff_f = NULL; - new->power_f = NULL; - new->coeff_f = NULL; - new->mxpow_f = NULL; - - new->ncoeff_i = NULL; - new->power_i = NULL; - new->coeff_i = NULL; - new->mxpow_i = NULL; - -/* Store the forward transformation. */ - StoreArrays( new, 1, ncoeff_f, coeff_f, status ); - -/* Store the inverse transformation. */ - StoreArrays( new, 0, ncoeff_i, coeff_i, status ); - -/* Other class attributes. */ - new->iterinverse = -INT_MAX; - new->niterinverse = -INT_MAX; - new->tolinverse = AST__BAD; - new->jacobian = NULL; - -/* If an error occurred, clean up by deleting the new PolyMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new PolyMap. */ - return new; -} - -AstPolyMap *astLoadPolyMap_( void *mem, size_t size, - AstPolyMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPolyMap - -* Purpose: -* Load a PolyMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "polymap.h" -* AstPolyMap *astLoadPolyMap( void *mem, size_t size, -* AstPolyMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* PolyMap loader. - -* Description: -* This function is provided to load a new PolyMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* PolyMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a PolyMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the PolyMap is to be -* loaded. This must be of sufficient size to accommodate the -* PolyMap data (sizeof(PolyMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the PolyMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the PolyMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPolyMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new PolyMap. If this is NULL, a pointer -* to the (static) virtual function table for the PolyMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "PolyMap" is used instead. - -* Returned Value: -* A pointer to the new PolyMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -/* Local Variables: */ - AstPolyMap *new; /* Pointer to the new PolyMap */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int i; /* Loop index */ - int iv; /* Vectorised keyword index */ - int j; /* Loop index */ - int k; /* Loop index */ - int nin; /* No. of input coords */ - int nout; /* No. of output coords */ - int undef; /* Is the transformation undefined? */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this PolyMap. In this case the - PolyMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPolyMap ); - vtab = &class_vtab; - name = "PolyMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPolyMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built PolyMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Get the number of inputs and outputs for the uninverted Mapping. */ - nin = ( (AstMapping *) new )->nin; - nout = ( (AstMapping *) new )->nout; - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "PolyMap" ); - -/* Allocate memory to hold the forward arrays. */ - new->ncoeff_f = astMalloc( sizeof( int )*(size_t) nout ); - new->mxpow_f = astMalloc( sizeof( int )*(size_t) nin ); - new->power_f = astMalloc( sizeof( int ** )*(size_t) nout ); - new->coeff_f = astMalloc( sizeof( double * )*(size_t) nout ); - if( astOK ) { - -/* Assume the forward transformation is defined. */ - undef = 0; - -/* Get the maximum power of each input axis value used by the forward - transformation. Set a flag "undef" if no values relating to the - forward transformation are found (this indicates that the forward - transformation is not defined). */ - for( i = 0; i < nin && !undef; i++ ){ - (void) sprintf( buff, "mpf%d", i + 1 ); - (new->mxpow_f)[ i ] = astReadInt( channel, buff, INT_MAX ); - if( (new->mxpow_f)[ i ] == INT_MAX ) undef = 1; - } - -/* Get the number of coefficients associated with each output of the forward - transformation. */ - for( i = 0; i < nout && !undef; i++ ){ - (void) sprintf( buff, "ncf%d", i + 1 ); - (new->ncoeff_f)[ i ] = astReadInt( channel, buff, INT_MAX ); - if( (new->ncoeff_f)[ i ] == INT_MAX ) undef = 1; - } - -/* Get the coefficient values used by the forward transformation. This - uses new style vectorised key names if available. Otherwise it uses - old style indexed names (which were superceded by vectorised names - because they are shorter and so work better with FitsChans). */ - iv = 0; - for( i = 0; i < nout && !undef; i++ ){ - - (new->coeff_f)[ i ] = astMalloc( sizeof( double )* - (size_t) new->ncoeff_f[ i ] ); - if( astOK ) { - for( j = 0; j < new->ncoeff_f[ i ]; j++ ){ - (void) sprintf( buff, "cf%d", ++iv ); - (new->coeff_f)[ i ][ j ] = astReadDouble( channel, buff, AST__BAD ); - if( (new->coeff_f)[ i ][ j ] == AST__BAD ) { - (void) sprintf( buff, "cf%d_%d", i + 1, j + 1 ); - (new->coeff_f)[ i ][ j ] = astReadDouble( channel, buff, AST__BAD ); - } - } - } - } - -/* Get the input axis powers associated with each coefficient of the forward - transformation. */ - iv = 0; - for( i = 0; i < nout && !undef; i++ ){ - (new->power_f)[ i ] = astMalloc( sizeof( int * )* - (size_t) new->ncoeff_f[ i ] ); - if( astOK ) { - for( j = 0; j < new->ncoeff_f[ i ]; j++ ){ - (new->power_f)[ i ][ j ] = astMalloc( sizeof( int )* (size_t) nin ); - if( astOK ) { - for( k = 0; k < nin; k++ ){ - (void) sprintf( buff, "pf%d", ++iv ); - (new->power_f)[ i ][ j ][ k ] = astReadInt( channel, buff, 0 ); - if( (new->power_f)[ i ][ j ][ k ] == 0 ) { - (void) sprintf( buff, "pf%d_%d_%d", i + 1, j + 1, k + 1 ); - (new->power_f)[ i ][ j ][ k ] = astReadInt( channel, buff, 0 ); - } - } - } - } - } - } - -/* Free the arrays if the forward transformation is undefined. */ - if( undef ) { - new->ncoeff_f = astFree( new->ncoeff_f ); - new->mxpow_f = astFree( new->mxpow_f ); - new->power_f = astFree( new->power_f ); - new->coeff_f = astFree( new->coeff_f ); - } - } - -/* Allocate memory to hold the inverse arrays. */ - new->ncoeff_i = astMalloc( sizeof( int )*(size_t) nin ); - new->mxpow_i = astMalloc( sizeof( int )*(size_t) nout ); - new->power_i = astMalloc( sizeof( int ** )*(size_t) nin ); - new->coeff_i = astMalloc( sizeof( double * )*(size_t) nin ); - if( astOK ) { - -/* Assume the inverse transformation is defined. */ - undef = 0; - -/* Get the maximum power of each output axis value used by the inverse - transformation. Set a flag "undef" if no values relating to the - inverse transformation are found (this indicates that the inverse - transformation is not defined). */ - for( i = 0; i < nout && !undef; i++ ){ - (void) sprintf( buff, "mpi%d", i + 1 ); - (new->mxpow_i)[ i ] = astReadInt( channel, buff, INT_MAX ); - if( (new->mxpow_i)[ i ] == INT_MAX ) undef = 1; - } - -/* Get the number of coefficients associated with each input of the inverse - transformation. */ - for( i = 0; i < nin && !undef; i++ ){ - (void) sprintf( buff, "nci%d", i + 1 ); - (new->ncoeff_i)[ i ] = astReadInt( channel, buff, INT_MAX ); - if( (new->ncoeff_i)[ i ] == INT_MAX ) undef = 1; - } - -/* Get the coefficient values used by the inverse transformation. */ - iv = 0; - for( i = 0; i < nin && !undef; i++ ){ - - (new->coeff_i)[ i ] = astMalloc( sizeof( double )* - (size_t) new->ncoeff_i[ i ] ); - if( astOK ) { - for( j = 0; j < new->ncoeff_i[ i ]; j++ ){ - (void) sprintf( buff, "ci%d", ++iv ); - (new->coeff_i)[ i ][ j ] = astReadDouble( channel, buff, AST__BAD ); - if( (new->coeff_i)[ i ][ j ] == AST__BAD ) { - (void) sprintf( buff, "ci%d_%d", i + 1, j + 1 ); - (new->coeff_i)[ i ][ j ] = astReadDouble( channel, buff, AST__BAD ); - } - } - } - } - -/* Get the output axis powers associated with each coefficient of the inverse - transformation. */ - iv = 0; - for( i = 0; i < nin && !undef; i++ ){ - (new->power_i)[ i ] = astMalloc( sizeof( int * )* - (size_t) new->ncoeff_i[ i ] ); - if( astOK ) { - for( j = 0; j < new->ncoeff_i[ i ]; j++ ){ - (new->power_i)[ i ][ j ] = astMalloc( sizeof( int )* (size_t) nout ); - if( astOK ) { - for( k = 0; k < nout; k++ ){ - (void) sprintf( buff, "pi%d", ++iv ); - (new->power_i)[ i ][ j ][ k ] = astReadInt( channel, buff, 0 ); - if( (new->power_i)[ i ][ j ][ k ] == 0 ) { - (void) sprintf( buff, "pi%d_%d_%d", i + 1, j + 1, k + 1 ); - (new->power_i)[ i ][ j ][ k ] = astReadInt( channel, buff, 0 ); - } - } - } - } - } - } - -/* Free the arrays if the inverse transformation is undefined. */ - if( undef ) { - new->ncoeff_i = astFree( new->ncoeff_i ); - new->mxpow_i = astFree( new->mxpow_i ); - new->power_i = astFree( new->power_i ); - new->coeff_i = astFree( new->coeff_i ); - } - } - -/* Whether to use an iterative inverse transformation. */ - new->iterinverse = astReadInt( channel, "iterinv", -INT_MAX ); - if ( TestIterInverse( new, status ) ) SetIterInverse( new, new->iterinverse, status ); - -/* Max number of iterations for iterative inverse transformation. */ - new->niterinverse = astReadInt( channel, "niterinv", -INT_MAX ); - if ( TestNiterInverse( new, status ) ) SetNiterInverse( new, new->niterinverse, status ); - -/* Target relative error for iterative inverse transformation. */ - new->tolinverse = astReadDouble( channel, "tolinv", AST__BAD ); - if ( TestTolInverse( new, status ) ) SetTolInverse( new, new->tolinverse, status ); - -/* The Jacobian of the PolyMap's forward transformation has not yet been - found. */ - new->jacobian = NULL; - -/* If an error occurred, clean up by deleting the new PolyMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new PolyMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astPolyPowers_( AstPolyMap *this, double **work, int ncoord, - const int *mxpow, double **ptr, int point, int fwd, - int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,PolyMap,PolyPowers))( this, work, ncoord, mxpow, ptr, - point, fwd, status ); -} - -AstPolyMap *astPolyTran_( AstPolyMap *this, int forward, double acc, - double maxacc, int maxorder, const double *lbnd, - const double *ubnd, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,PolyMap,PolyTran))( this, forward, acc, - maxacc, maxorder, lbnd, - ubnd, status ); -} - -void astPolyCoeffs_( AstPolyMap *this, int forward, int nel, double *array, - int *ncoeff, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,PolyMap,PolyCoeffs))( this, forward, nel, - array, ncoeff, status ); -} - -void astFitPoly1DInit_( AstPolyMap *this, int forward, double **table, - AstMinPackData *data, double *scales, - int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,PolyMap,FitPoly1DInit))( this, forward, table, data, scales, - status ); -} - - -void astFitPoly2DInit_( AstPolyMap *this, int forward, double **table, - AstMinPackData *data, double *scales, - int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,PolyMap,FitPoly2DInit))( this, forward, table, data, scales, - status ); -} - - - - diff --git a/ast/polymap.h b/ast/polymap.h deleted file mode 100644 index bdfb319..0000000 --- a/ast/polymap.h +++ /dev/null @@ -1,386 +0,0 @@ -#if !defined( POLYMAP_INCLUDED ) /* Include this file only once */ -#define POLYMAP_INCLUDED -/* -*+ -* Name: -* polymap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the PolyMap class. - -* Invocation: -* #include "polymap.h" - -* Description: -* This include file defines the interface to the PolyMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* A PolyMap is a form of Mapping which performs a general polynomial -* transformation. Each output coordinate is a polynomial function of -* all the input coordinates. The coefficients are specified separately -* for each output coordinate. The forward and inverse transformations -* are defined independantly by separate sets of coefficients. - -* Inheritance: -* The PolyMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astTransform -* Apply a PolyMap to transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsAPolyMap -* Test class membership. -* astPolyMap -* Create a PolyMap. -* -* Protected: -* astCheckPolyMap -* Validate class membership. -* astInitPolyMap -* Initialise a PolyMap. -* astInitPolyMapVtab -* Initialise the virtual function table for the PolyMap class. -* astLoadPolyMap -* Load a PolyMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstPolyMap -* PolyMap object type. -* -* Protected: -* AstPolyMapVtab -* PolyMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 28-SEP-2003 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* PolyMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstPolyMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int *ncoeff_f; /* No. of coeffs for each forward polynomial */ - int *mxpow_f; /* Max power of each i/p axis for each forward polynomial */ - int ***power_f; /* Pointer to i/p powers for all forward coefficients */ - double **coeff_f; /* Pointer to values of all forward coefficients */ - int *ncoeff_i; /* No. of coeffs for each inverse polynomial */ - int *mxpow_i; /* Max power of each i/p axis for each inverse polynomial */ - int ***power_i; /* Pointer to i/p powers for all inverse coefficients */ - double **coeff_i; /* Pointer to values of all inverse coefficients */ - int iterinverse; /* Use an iterative inverse? */ - int niterinverse; /* Max number of iterations for iterative inverse */ - double tolinverse; /* Target relative error for iterative inverse */ - struct AstPolyMap **jacobian;/* PolyMaps defining Jacobian of forward transformation */ -} AstPolyMap; - -/* Virtual function table. */ -/* ----------------------- */ -#if defined(astCLASS) /* Protected */ - -/* Structure used to pass data to the Levenberg - Marquardt non-linear - minimization algorithm. */ -typedef struct AstMinPackData { - int order; /* Max power of X1 or X2, plus one. */ - int nsamp; /* No. of polynomial samples to fit */ - int init_jac; /* Has the constant Jacobian been found yet? */ - double *xp1; /* Pointer to powers of X1 (1st poly i/p) at all samples */ - double *xp2; /* Pointer to powers of X2 (2nd poly i/p) at all samples */ - double *y[ 2 ]; /* Pointers to Y1 and Y2 values at all samples */ -} AstMinPackData; - - -/* This structure contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -typedef struct AstPolyMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstPolyMap *(* PolyTran)( AstPolyMap *, int, double, double, int, const double *, const double *, int * ); - void (* PolyPowers)( AstPolyMap *, double **, int, const int *, double **, int, int, int * ); - void (* PolyCoeffs)( AstPolyMap *, int, int, double *, int *, int *); - void (* FitPoly1DInit)( AstPolyMap *, int, double **, AstMinPackData *, double *, int *); - void (* FitPoly2DInit)( AstPolyMap *, int, double **, AstMinPackData *, double *, int *); - - int (*GetIterInverse)( AstPolyMap *, int * ); - int (* TestIterInverse)( AstPolyMap *, int * ); - void (* ClearIterInverse)( AstPolyMap *, int * ); - void (* SetIterInverse)( AstPolyMap *, int, int * ); - - int (*GetNiterInverse)( AstPolyMap *, int * ); - int (* TestNiterInverse)( AstPolyMap *, int * ); - void (* ClearNiterInverse)( AstPolyMap *, int * ); - void (* SetNiterInverse)( AstPolyMap *, int, int * ); - - double (*GetTolInverse)( AstPolyMap *, int * ); - int (* TestTolInverse)( AstPolyMap *, int * ); - void (* ClearTolInverse)( AstPolyMap *, int * ); - void (* SetTolInverse)( AstPolyMap *, double, int * ); - -} AstPolyMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstPolyMapGlobals { - AstPolyMapVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ AST__GETATTRIB_BUFF_LEN + 1 ]; -} AstPolyMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitPolyMapGlobals_( AstPolyMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(PolyMap) /* Check class membership */ -astPROTO_ISA(PolyMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstPolyMap *astPolyMap_( int, int, int, const double[], int, const double[], const char *, int *, ...); -#else -AstPolyMap *astPolyMapId_( int, int, int, const double[], int, const double[], const char *, ... )__attribute__((format(printf,7,8))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstPolyMap *astInitPolyMap_( void *, size_t, int, AstPolyMapVtab *, const char *, int, int, int, const double[], int, const double[], int * ); - -/* Vtab initialiser. */ -void astInitPolyMapVtab_( AstPolyMapVtab *, const char *, int * ); - -/* Loader. */ -AstPolyMap *astLoadPolyMap_( void *, size_t, AstPolyMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -AstPolyMap *astPolyTran_( AstPolyMap *, int, double, double, int, const double *, const double *, int * ); -void astPolyCoeffs_( AstPolyMap *, int, int, double *, int *, int *); - -# if defined(astCLASS) /* Protected */ - void astPolyPowers_( AstPolyMap *, double **, int, const int *, double **, int, int, int * ); - void astFitPoly1DInit_( AstPolyMap *, int, double **, AstMinPackData *, double *, int *); - void astFitPoly2DInit_( AstPolyMap *, int, double **, AstMinPackData *, double *, int *); - - int astGetIterInverse_( AstPolyMap *, int * ); - int astTestIterInverse_( AstPolyMap *, int * ); - void astClearIterInverse_( AstPolyMap *, int * ); - void astSetIterInverse_( AstPolyMap *, int, int * ); - - int astGetNiterInverse_( AstPolyMap *, int * ); - int astTestNiterInverse_( AstPolyMap *, int * ); - void astClearNiterInverse_( AstPolyMap *, int * ); - void astSetNiterInverse_( AstPolyMap *, int, int * ); - - double astGetTolInverse_( AstPolyMap *, int * ); - int astTestTolInverse_( AstPolyMap *, int * ); - void astClearTolInverse_( AstPolyMap *, int * ); - void astSetTolInverse_( AstPolyMap *, double, int * ); -#endif - - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckPolyMap(this) astINVOKE_CHECK(PolyMap,this,0) -#define astVerifyPolyMap(this) astINVOKE_CHECK(PolyMap,this,1) - -/* Test class membership. */ -#define astIsAPolyMap(this) astINVOKE_ISA(PolyMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astPolyMap astINVOKE(F,astPolyMap_) -#else -#define astPolyMap astINVOKE(F,astPolyMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitPolyMap(mem,size,init,vtab,name,nin,nout,ncoeff_f,coeff_f,ncoeff_i,coeff_i) \ -astINVOKE(O,astInitPolyMap_(mem,size,init,vtab,name,nin,nout,ncoeff_f,coeff_f,ncoeff_i,coeff_i,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitPolyMapVtab(vtab,name) astINVOKE(V,astInitPolyMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadPolyMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadPolyMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckPolyMap to validate PolyMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astPolyTran(this,forward,acc,maxacc,maxorder,lbnd,ubnd) \ -astINVOKE(O,astPolyTran_(astCheckPolyMap(this),forward,acc,maxacc,maxorder,lbnd,ubnd,STATUS_PTR)) - -#define astPolyCoeffs(this,forward,nel,coeffs,ncoeff) \ -astINVOKE(V,astPolyCoeffs_(astCheckPolyMap(this),forward,nel,coeffs,ncoeff,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ - -#define astPolyPowers(this,work,ncoord,mxpow,ptr,offset,fwd) \ - astINVOKE(V,astPolyPowers_(astCheckPolyMap(this),work,ncoord,mxpow,ptr,point,fwd,STATUS_PTR)) -#define astFitPoly1DInit(this,forward,table,data,scales) \ - astINVOKE(V,astFitPoly1DInit_(astCheckPolyMap(this),forward,table,data,scales,STATUS_PTR)) -#define astFitPoly2DInit(this,forward,table,data,scales) \ - astINVOKE(V,astFitPoly2DInit_(astCheckPolyMap(this),forward,table,data,scales,STATUS_PTR)) -#define astClearIterInverse(this) \ - astINVOKE(V,astClearIterInverse_(astCheckPolyMap(this),STATUS_PTR)) -#define astGetIterInverse(this) \ - astINVOKE(V,astGetIterInverse_(astCheckPolyMap(this),STATUS_PTR)) -#define astSetIterInverse(this,value) \ - astINVOKE(V,astSetIterInverse_(astCheckPolyMap(this),value,STATUS_PTR)) -#define astTestIterInverse(this) \ - astINVOKE(V,astTestIterInverse_(astCheckPolyMap(this),STATUS_PTR)) - -#define astClearNiterInverse(this) \ - astINVOKE(V,astClearNiterInverse_(astCheckPolyMap(this),STATUS_PTR)) -#define astGetNiterInverse(this) \ - astINVOKE(V,astGetNiterInverse_(astCheckPolyMap(this),STATUS_PTR)) -#define astSetNiterInverse(this,value) \ - astINVOKE(V,astSetNiterInverse_(astCheckPolyMap(this),value,STATUS_PTR)) -#define astTestNiterInverse(this) \ - astINVOKE(V,astTestNiterInverse_(astCheckPolyMap(this),STATUS_PTR)) - -#define astClearTolInverse(this) \ - astINVOKE(V,astClearTolInverse_(astCheckPolyMap(this),STATUS_PTR)) -#define astGetTolInverse(this) \ - astINVOKE(V,astGetTolInverse_(astCheckPolyMap(this),STATUS_PTR)) -#define astSetTolInverse(this,value) \ - astINVOKE(V,astSetTolInverse_(astCheckPolyMap(this),value,STATUS_PTR)) -#define astTestTolInverse(this) \ - astINVOKE(V,astTestTolInverse_(astCheckPolyMap(this),STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/prepare_all b/ast/prepare_all deleted file mode 100755 index cda505d..0000000 --- a/ast/prepare_all +++ /dev/null @@ -1,41 +0,0 @@ - -chmod +x ./getnewversion -./getnewversion - -AST_VERSION="`cat ./version.number`" -export AST_VERSION - -echo "AST_VERSION $AST_VERSION" - -PATH="$PWD:$PATH" -export PATH - -AST_DEV=$PWD -export AST_DEV - -AST_REF=$PWD -export AST_REF - -PKG="ast" -export PKG - -PKG_REF=$PWD -export PKG_REF - -PKG_DIR=$PWD -export PKG_DIR - -PROJECTDIR=$PWD -export PROJECTDIR - -MAKEFILE="$PWD/grp-ref.make" -export MAKEFILE - -EXPORT="$HOME" -export EXPORT - -( - builddocs - buildhyperdocs - rmk release -) 2>&1 | tee ~/ast_release.log diff --git a/ast/prepare_docs b/ast/prepare_docs deleted file mode 100755 index 8fc0358..0000000 --- a/ast/prepare_docs +++ /dev/null @@ -1,16 +0,0 @@ - -AST_DEV=$PWD -export AST_DEV - -AST_REF=$PWD -export AST_REF - -chmod +x ./getnewversion -./getnewversion -AST_VERSION="`cat ./version.number`" -echo "AST_VERSION $AST_VERSION" -export AST_VERSION - -( - builddocs -) 2>&1 | tee ~/ast_release.log diff --git a/ast/prepare_hyperdocs b/ast/prepare_hyperdocs deleted file mode 100755 index 3d6e1e4..0000000 --- a/ast/prepare_hyperdocs +++ /dev/null @@ -1,37 +0,0 @@ - -chmod +x ./getnewversion -./getnewversion -AST_VERSION="`cat ./version.number`" -echo "AST_VERSION $AST_VERSION" -export AST_VERSION - -PATH="$PWD:$PATH" -export PATH - -AST_DEV=$PWD -export AST_DEV - -AST_REF=$PWD -export AST_REF - -PKG="ast" -export PKG - -PKG_REF=$PWD -export PKG_REF - -PKG_DIR=$PWD -export PKG_DIR - -PROJECTDIR=$PWD -export PROJECTDIR - -MAKEFILE="$PWD/grp-ref.make" -export MAKEFILE - -EXPORT="$HOME" -export EXPORT - -( - buildhyperdocs -) 2>&1 | tee ~/ast_release.log diff --git a/ast/prepare_release b/ast/prepare_release deleted file mode 100755 index 84b8dff..0000000 --- a/ast/prepare_release +++ /dev/null @@ -1,39 +0,0 @@ - -chmod +x ./getnewversion -./getnewversion - -AST_VERSION="`cat ./version.number`" -export AST_VERSION - -echo "AST_VERSION $AST_VERSION" - -PATH="$PWD:$PATH" -export PATH - -AST_DEV=$PWD -export AST_DEV - -AST_REF=$PWD -export AST_REF - -PKG="ast" -export PKG - -PKG_REF=$PWD -export PKG_REF - -PKG_DIR=$PWD -export PKG_DIR - -PROJECTDIR=$PWD -export PROJECTDIR - -MAKEFILE="$PWD/grp-ref.make" -export MAKEFILE - -EXPORT="$HOME" -export EXPORT - -( - rmk release -) 2>&1 | tee ~/ast_release.log diff --git a/ast/prism.c b/ast/prism.c deleted file mode 100644 index f4e26c9..0000000 --- a/ast/prism.c +++ /dev/null @@ -1,4448 +0,0 @@ -/* -*class++ -* Name: -* Prism - -* Purpose: -* An extrusion of a region into higher dimensions. - -* Constructor Function: -c astPrism -f AST_PRISM - -* Description: -* A Prism is a Region which represents an extrusion of an existing Region -* into one or more orthogonal dimensions (specified by another Region). -* If the Region to be extruded has N axes, and the Region defining the -* extrusion has M axes, then the resulting Prism will have (M+N) axes. -* A point is inside the Prism if the first N axis values correspond to -* a point inside the Region being extruded, and the remaining M axis -* values correspond to a point inside the Region defining the extrusion. -* -* As an example, a cylinder can be represented by extruding an existing -* Circle, using an Interval to define the extrusion. Ih this case, the -* Interval would have a single axis and would specify the upper and -* lower limits of the cylinder along its length. - -* Inheritance: -* The Prism class inherits from the Region class. - -* Attributes: -* The Prism class does not define any new attributes beyond those -* which are applicable to all Regions. - -* Functions: -c The Prism class does not define any new functions beyond those -f The Prism class does not define any new routines beyond those -* which are applicable to all Regions. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 17-DEC-2004 (DSB): -* Original version. -* 11-MAY-2005 (DSB): -* Overlap modified to allow testing of overlap between prisms and -* intervals. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 9-OCT-2007 (DSB): -* Guard against all axes being extrusion axes in EquivPrism. -* 20-JAN-2009 (DSB): -* Over-ride astRegBasePick. -* 22-JAN-2009 (DSB): -* - Allow any class of Region to be used to define the extrusion axes. -* - Over-ride the astMapList method. -* 19-MAR-2009 (DSB): -* Over-ride the astDecompose method. -* 14-AUG-2014 (DSB): -* Over-ride the astGetRegionBounds method. -* 9-SEP-2014 (DSB): -* Record the pointer to the Prism implementation of RegBaseMesh -* within the class virtual function table. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Prism - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "region.h" /* Regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "prism.h" /* Interface definition for this class */ -#include "cmpmap.h" /* Compound Mappings */ -#include "cmpframe.h" /* Compound Frames */ -#include "unitmap.h" /* Unit Mappings */ -#include "interval.h" /* Axis intervals */ -#include "pointlist.h" /* Points within Frames */ -#include "permmap.h" /* Axis permutations */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstMapping *(* parent_simplify)( AstMapping *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *(* parent_getdefunc)( AstRegion *, int * ); -static double (*parent_getfillfactor)( AstRegion *, int * ); -static int (* parent_equal)( AstObject *, AstObject *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); -static int (* parent_maplist)( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int (* parent_overlapx)( AstRegion *, AstRegion *, int * ); -static void (* parent_clearclosed)( AstRegion *, int * ); -static void (* parent_clearmeshsize)( AstRegion *, int * ); -static void (* parent_setclosed)( AstRegion *, int, int * ); -static void (* parent_setmeshsize)( AstRegion *, int, int * ); -static void (* parent_setregfs)( AstRegion *, AstFrame *, int * ); -static void (*parent_getregionbounds)( AstRegion *, double *, double *, int * ); -static void (*parent_regclearattrib)( AstRegion *, const char *, char **, int * ); -static void (*parent_regsetattrib)( AstRegion *, const char *, char **, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Prism) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Prism,Class_Init) -#define class_vtab astGLOBAL(Prism,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPrismVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstPrism *astPrismId_( void *, void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *GetDefUnc( AstRegion *, int * ); -static AstRegion *RegBasePick( AstRegion *this, int, const int *, int * ); -static double *RegCentre( AstRegion *this, double *, double **, int, int, int * ); -static double GetFillFactor( AstRegion *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetBounded( AstRegion *, int * ); -static int GetObjSize( AstObject *, int * ); -static int MapList( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int Overlap( AstRegion *, AstRegion *, int * ); -static int OverlapX( AstRegion *, AstRegion *, int * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static void ClearClosed( AstRegion *, int * ); -static void ClearMeshSize( AstRegion *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Decompose( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void GetRegions( AstPrism *, AstRegion **, AstRegion **, int *, int * ); -static void GetRegionBounds( AstRegion *, double *, double *, int * ); -static void RegBaseBox( AstRegion *, double *, double *, int * ); -static void RegClearAttrib( AstRegion *, const char *, char **, int * ); -static void RegSetAttrib( AstRegion *, const char *, char **, int * ); -static void SetClosed( AstRegion *, int, int * ); -static void SetMeshSize( AstRegion *, int, int * ); -static void SetRegFS( AstRegion *, AstFrame *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Member functions. */ -/* ================= */ -AstRegion *astConvertToPrism_( AstRegion *this, int *status ) { -/* -*+ -* Name: -* astConvertToPrism - -* Purpose: -* Convert a supplied Region into a Prism if possible. - -* Type: -* Protected function. - -* Synopsis: -* #include "prism.h" -* AstRegion *astConvertToPrism( AstRegion *this, int *status ) - -* Description: -* This function attempts to split the supplied Region into two -* regions defined within separate coordinate system. If this is -* possible, and if either one of the two resulting Regions can be -* simplified, then the two simplified Regions are joined into a Prism -* equivalent to the supplied Region. The Prism is then simplified and -* returned. -* -* If the supplied Region cannot be split into two components, or if -* neither of the two components can eb simplified, then a clone of the -* supplied Region pointer is returned. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the equivalent simplified Prism, or a clone of the -* supplied Region pointer. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*- -*/ - -/* Local Variables: */ - AstFrame *frm; /* Current Frame in supplied Region */ - AstFrame *pickfrm1; /* Frame formed by picking current subset of axes */ - AstFrame *pickfrm2; /* Frame formed by picking all other axes */ - AstMapping *junk; /* Unused Mapping pointer */ - AstMapping *map; /* Base -> current Mapping */ - AstPrism *prism; /* Prism combining all axes */ - AstPrism *newprism; /* Prism combining all axes, in original Frame */ - AstRegion *result; /* Result pointer to return */ - AstRegion *sp1; /* Simplified region spanning selected axes */ - AstRegion *sp2; /* Simplified region spanning unselected axes */ - AstUnitMap *um; /* A UnitMap */ - int *ax; /* Pointer to array of selecte axis indices */ - int *perm; /* Axis permutation array */ - int axis; /* Axis index */ - int bitmask; /* Integer with set bits for selected axes */ - int i; /* Loop index */ - int mask; /* Integer with a set bit at current axis */ - int nax; /* Number of selected axes */ - int nin; /* No. of base Frame axes (Mapping inputs) */ - int nout; /* No. of current Frame axes (Mapping outputs) */ - int topmask; /* Integer that selects all axes */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the Mapping from base to current Frame. */ - map = astGetMapping( this->frameset, AST__BASE, AST__CURRENT ); - -/* Get the number of inputs and outputs for the Mapping. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - -/* Allocate memory to hold the indices of the current Frame axes in the - current subset */ - ax = astMalloc( sizeof( int )* nout ); - if( ax ) { - -/* We need to scan through all possible subsets of the current Frame - axes, looking for a subset that results in the Region being split. - We use the binary pattern of bits in "bitmask" to indicate if the - corresponding axes should be included in the subset of axes. - Loop round all possible combinations, until a combination is found - that results in a Prism being formed. */ - topmask = pow( 2, nout ); - for( bitmask = 1; bitmask < topmask && !result; bitmask++ ) { - -/* Store the indices of the axes forming the current subset. */ - nax = 0; - mask = 1; - for( axis = 0; axis < nout; axis++ ) { - if( bitmask & mask ) ax[ nax++ ] = axis; - mask <<= 1; - } - -/* See if the current subset of current Frame axes can be split off from - the Region. If it can, the Frame pointer returned by astPickAxes will identify - a Region. */ - pickfrm1 = astPickAxes( this, nax, ax, &junk ); - junk = astAnnul( junk ); - if( astIsARegion( pickfrm1 ) ) { - -/* Check that the remaining (unselected) axes can also be picked into a - new Region. */ - nax = 0; - mask = 1; - for( axis = 0; axis < nout; axis++ ) { - if( ( bitmask & mask ) == 0 ) ax[ nax++ ] = axis; - mask <<= 1; - } - - pickfrm2 = astPickAxes( this, nax, ax, &junk ); - junk = astAnnul( junk ); - if( astIsARegion( pickfrm2 ) ) { - -/* See if either of these picked Regions can be simplified. */ - sp1 = astSimplify( pickfrm1 ); - sp2 = astSimplify( pickfrm2 ); - if( (AstFrame *) sp1 != pickfrm1 || - (AstFrame *) sp2 != pickfrm2 ) { - -/* If so form a Prism containing the simplified Regions. */ - prism = astPrism( sp1, sp2, " ", status ); - -/* Permute the axes of the Prism so that they are in the same order as - in the Box. */ - perm = astMalloc( sizeof( int )*nout ); - if( perm ) { - - for( i = 0; i < nout; i++ ) perm[ i ] = -1; - - for( i = 0; i < nax; i++ ) { - perm[ ax[ i ] ] = i + ( nout - nax ); - } - - nax = 0; - for( i = 0; i < nout; i++ ) { - if( perm[ i ] == -1 ) perm[ i ] = nax++; - } - - astPermAxes( prism, perm ); - perm = astFree( perm ); - } - -/* Put the original current Frame back in (in place of the CmpFrame - containined in the Prism). */ - frm = astGetFrame( this->frameset, AST__CURRENT ); - um = astUnitMap( nout, " ", status ); - newprism = astMapRegion( prism, um, frm ); - um = astAnnul( um ); - frm = astAnnul( frm ); - -/* Attempt to simplify the Prism. */ - result = astSimplify( newprism ); - -/* Free resources */ - prism = astAnnul( prism ); - newprism = astAnnul( newprism ); - } - - sp1 = astAnnul( sp1 ); - sp2 = astAnnul( sp2 ); - } - pickfrm2 = astAnnul( pickfrm2 ); - } - - pickfrm1 = astAnnul( pickfrm1 ); - } - - ax = astFree( ax ); - } - - map = astAnnul( map ); - -/* If no Prism could be made, return a clone of the supplied Region - pointer. */ - if( !result ) result = astClone( this ); - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static void Decompose( AstMapping *this_mapping, AstMapping **map1, - AstMapping **map2, int *series, int *invert1, - int *invert2, int *status ) { -/* -* -* Name: -* Decompose - -* Purpose: -* Decompose a Prism into two component Regions. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void Decompose( AstMapping *this, AstMapping **map1, -* AstMapping **map2, int *series, -* int *invert1, int *invert2, int *status ) - -* Class Membership: -* Prism member function (over-rides the protected astDecompose -* method inherited from the Mapping class). - -* Description: -* This function returns pointers to two Mappings which, when applied -* either in series or parallel, are equivalent to the supplied Mapping. -* -* Since the Frame class inherits from the Mapping class, Frames can -* be considered as special types of Mappings and so this method can -* be used to decompose either CmpMaps, CmpFrames, CmpRegions or Prisms. - -* Parameters: -* this -* Pointer to the Mapping. -* map1 -* Address of a location to receive a pointer to first component -* Mapping. -* map2 -* Address of a location to receive a pointer to second component -* Mapping. -* series -* Address of a location to receive a value indicating if the -* component Mappings are applied in series or parallel. A non-zero -* value means that the supplied Mapping is equivalent to applying map1 -* followed by map2 in series. A zero value means that the supplied -* Mapping is equivalent to applying map1 to the lower numbered axes -* and map2 to the higher numbered axes, in parallel. -* invert1 -* The value of the Invert attribute to be used with map1. -* invert2 -* The value of the Invert attribute to be used with map2. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Any changes made to the component rames using the returned -* pointers will be reflected in the supplied CmpFrame. - -*- -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to Prism structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the CmpMap structure. */ - this = (AstPrism *) this_mapping; - -/* The components Frames of a Prism are considered to be parallel - Mappings. */ - if( series ) *series = 0; - -/* The Frames are returned in their original order whether or not the - Prism has been inverted. */ - if( map1 ) *map1 = astClone( this->region1 ); - if( map2 ) *map2 = astClone( this->region2 ); - -/* The invert flags dont mean anything for a Region, but we return them - anyway. If the Prism has been inverted, return inverted Invert flags. */ - if( astGetInvert( this ) ) { - if( invert1 ) *invert1 = astGetInvert( this->region1 ) ? 0 : 1; - if( invert2 ) *invert2 = astGetInvert( this->region2 ) ? 0 : 1; - -/* If the Prism has not been inverted, return the current Invert flags. */ - } else { - if( invert1 ) *invert1 = astGetInvert( this->region1 ); - if( invert2 ) *invert2 = astGetInvert( this->region2 ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two Objects are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* int Equal( AstObject *this_object, AstObject *that_object, int *status ) - -* Class Membership: -* Prism member function (over-rides the astEqual protected -* method inherited from the Region class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two Prisms are equivalent. - -* Parameters: -* this -* Pointer to the first Prism. -* that -* Pointer to the second Prism. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the Prisms are equivalent, zero otherwise. - -* Notes: -* - The Prisms are equivalent if their component Regions are -* equivalent and if they have the same boolean operation, negation -* and closed flags. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPrism *that; - AstPrism *this; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the Equal method inherited from the parent Region class. This checks - that the Objects are both of the same class, and have the same Negated - and Closed flags (amongst other things). */ - if( (*parent_equal)( this_object, that_object, status ) ) { - -/* Obtain pointers to the two Prism structures. */ - this = (AstPrism *) this_object; - that = (AstPrism *) that_object; - -/* Test their first component Regions for equality. */ - if( astEqual( this->region1, that->region1 ) ) { - -/* Test their second component Regions for equality. */ - if( astEqual( this->region2, that->region2 ) ) result = 1; - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -/* -* Name: -* MAKE_SET - -* Purpose: -* Define a function to set an attribute value for a Prism. - -* Type: -* Private macro. - -* Synopsis: -* #include "prism.h" -* MAKE_SET(attribute,lattribute,type) - -* Class Membership: -* Defined by the Prism class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Set( AstRegion *this, value ) -* -* that sets the value of a specified Region attribute in the parent -* Region structure and also in the component Regions. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* lattribute -* Name of the attribute, all in lower case. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_SET(attribute,lattribute,type) \ -static void Set##attribute( AstRegion *this_region, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstPrism *this; /* Pointer to the Prism structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Use the parent method to set the value in the parent Region structure. */ \ - (*parent_set##lattribute)( this_region, value, status ); \ -\ -/* Also set the value in the two component Regions. */ \ - this = (AstPrism *) this_region; \ - astSet##attribute( this->region1, value ); \ - astSet##attribute( this->region2, value ); \ -} - -/* Use the above macro to create accessors for the MeshSize and Closed - attributes. */ -MAKE_SET(MeshSize,meshsize,int) -MAKE_SET(Closed,closed,int) - -/* Undefine the macro. */ -#undef MAKE_SET - -/* -* Name: -* MAKE_CLEAR - -* Purpose: -* Define a function to clear an attribute value for a Prism. - -* Type: -* Private macro. - -* Synopsis: -* #include "prism.h" -* MAKE_CLEAR(attribute,lattribute) - -* Class Membership: -* Defined by the Prism class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Clear( AstRegion *this ) -* -* that sets the value of a specified Region attribute in the parent -* Region structure and also in the component Regions. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* lattribute -* Name of the attribute, all in lower case. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attribute,lattribute) \ -static void Clear##attribute( AstRegion *this_region, int *status ) { \ -\ -/* Local Variables: */ \ - AstPrism *this; /* Pointer to the Prism structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Use the parent method to clear the value in the parent Region structure. */ \ - (*parent_clear##lattribute)( this_region, status ); \ -\ -/* Also clear the value in the two component Regions. */ \ - this = (AstPrism *) this_region; \ - astClear##attribute( this->region1 ); \ - astClear##attribute( this->region2 ); \ -} - -/* Use the above macro to create accessors for the MeshSize and Closed - attributes. */ -MAKE_CLEAR(MeshSize,meshsize) -MAKE_CLEAR(Closed,closed) - -/* Undefine the macro. */ -#undef MAKE_CLEAR - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* Prism member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied Prism, -* in bytes. - -* Parameters: -* this -* Pointer to the Prism. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to Prism structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the Prism structure. */ - this = (AstPrism *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astGetObjSize( this->region1 ); - result += astGetObjSize( this->region2 ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetBounded( AstRegion *this_region, int *status ) { -/* -* Name: -* GetBounded - -* Purpose: -* Is the Region bounded? - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* int GetBounded( AstRegion *this, int *status ) - -* Class Membership: -* Prism method (over-rides the astGetBounded method inherited from -* the Region class). - -* Description: -* This function returns a flag indicating if the Region is bounded. -* The implementation provided by the base Region class is suitable -* for Region sub-classes representing the inside of a single closed -* curve (e.g. Circle, Ellipse, Box, etc). Other sub-classes (such as -* Prism, PointList, etc ) may need to provide their own -* implementations. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Region is bounded. Zero otherwise. - -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to Prism structure */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - int neg; /* Negated flag to use with the Prism */ - int reg1b; /* Is the first component Region bounded?*/ - int reg2b; /* Is the second component Region bounded?*/ - int result; /* Returned result */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Prism structure. */ - this = (AstPrism *) this_region; - -/* Get the component Regions, and the Negated value for the Prism. The - returned Regions represent a region within the base Frame of the FrameSet - encapsulated by the parent Region structure. */ - GetRegions( this, ®1, ®2, &neg, status ); - -/* If the Prism has been inverted, temporarily invert the components. */ - if( neg ) { - astNegate( reg1 ); - astNegate( reg2 ); - } - -/* See if either of the component Regions is bounded. */ - reg1b = astGetBounded( reg1 ); - reg2b = astGetBounded( reg2 ); - -/* If the Prism has been inverted, re-invert the components to bring them - back to their original states. */ - if( neg ) { - astNegate( reg1 ); - astNegate( reg2 ); - } - -/* The Prism is bounded only if both of the component Regions are bounded. */ - result = ( reg1b && reg2b ); - -/* Free resources. */ - reg1 = astAnnul( reg1 ); - reg2 = astAnnul( reg2 ); - -/* Return zero if an error occurred. */ - if( !astOK ) result = 0; - -/* Return the required pointer. */ - return result; -} - -static double GetFillFactor( AstRegion *this_region, int *status ) { -/* -* Name: -* GetFillFactor - -* Purpose: -* Obtain the value of the FillFactor attribute for a Prism. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* double GetFillFactor( AstRegion *this, int *status ) - -* Class Membership: -* Prism member function (over-rides the astGetFillFactor method inherited -* from the Region class). - -* Description: -* This function returns the value of the FillFactor attribute for a -* Prism. A suitable default value is returned if no value has -* previously been set. - -* Parameters: -* this -* Pointer to the Prism. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The FillFactor value to use. - -*/ - -/* Local Variables: */ - AstPrism *this; - double f1; - double f2; - double result; - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Initialise. */ - result = AST__BAD; - -/* Obtain a pointer to the Prism structure. */ - this = (AstPrism *) this_region; - -/* See if a FillFactor value has been set. If so, use the parent - astGetFillFactor method to obtain it. */ - if ( astTestFillFactor( this ) ) { - result = (*parent_getfillfactor)( this_region, status ); - -/* Otherwise, we will generate a default value equal to the product of - the FillFactor values of the two component Regions. */ - } else { - f1 = astGetFillFactor( this->region1 ); - f2 = astGetFillFactor( this->region2 ); - if( f1 != AST__BAD && f2 != AST__BAD ) result = f1*f2; - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static void GetRegionBounds( AstRegion *this_region, double *lbnd, - double *ubnd, int *status ){ -/* -* -* Name: -* GetRegionBounds - -* Purpose: -* Returns the bounding box of Prism. - -* Type: -* Private function. - -* Synopsis: -* #include "cmpregion.h" -* void GetRegionBounds( AstRegion *this_region, double *lbnd, -* double *ubnd, int *status ) - -* Class Membership: -* Prism member function (over-rides the protected astGetRegionBounds -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower limits of a box which just -* encompasses the supplied Prism. The limits are returned as axis -* values within the Frame represented by the Prism. The value of the -* Negated attribute is ignored (i.e. it is assumed that the Prism has -* not been negated). - -* Parameters: -* this -* Pointer to the Prism. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Prism. It should have at least as many elements as -* there are axes in the Prism. If an axis has no lower limit, the -* returned value will be the largest possible negative value. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Prism. It should have at least as many elements as -* there are axes in the Prism. If an axis has no upper limit, the -* returned value will be the largest possible positive value. - -* Notes: -* - The value of the Negated attribute is ignored (i.e. it is assumed that -* the Prism has not been negated). -* - If an axis has no extent on an axis then the lower limit will be -* returned larger than the upper limit. Note, this is different to an -* axis which has a constant value (in which case both lower and upper -* limit will be returned set to the constant value). -* - If the bounds on an axis cannot be determined, AST__BAD is returned for -* both upper and lower bounds -* - The implementation of this method for Prisms attempts to split the Prism -* into two separate Regions spanning indepenent sets of axes, and then uses -* the astGetRegionBouinds method to get the bounds on these two Regions. Care -* has to be taken because the Prism may have been remapped into a different -* Frame since it was created. - -*- -*/ - -/* Local Variables: */ - AstFrame *cfrm1; /* Frame spanning current axes for 1st component Region */ - AstFrame *cfrm2; /* Frame spanning current axes for 2nd component Region */ - AstFrame *cfrm; /* Current Frame for total Prism */ - AstMapping *map1; /* Base->Current Mapping for axes of 1st component Region */ - AstMapping *map2; /* Base->Current Mapping for axes of 2nd component Region */ - AstMapping *map; /* Case->Current mapping for total Prism */ - AstPrism *this; /* Pointer to Prism structure */ - AstRegion *reg1; /* 1st component Region Mapping into Prism's Frame */ - AstRegion *reg2; /* 2nd component Region Mapping into Prism's Frame */ - int *baxes; /* Indicies of Base Frame axes to be picked */ - int *caxes; /* Indicies of Current Frame axes to be picked */ - int iax; /* Axis index */ - int nax1; /* Number of axes in first component Region */ - int nax1_out; /* Number of current Frame axes in first component Region */ - int nax2; /* Number of axes in second component Region */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Prism structure. */ - this = (AstPrism *) this_region; - -/* Initialise */ - cfrm1 = NULL; - cfrm2 = NULL; - map1 = NULL; - map2 = NULL; - nax1_out = 0; - -/* The number of base-frame axes spanned by the two component Regions. */ - nax1 = astGetNaxes( this->region1 ); - nax2 = astGetNaxes( this->region2 ); - -/* Work space to hold the base frame indices for a single component - FrameSet. */ - baxes = astMalloc( ( nax1 + nax2 )*sizeof( int ) ); - if( astOK ) { - -/* Get the Mapping from Base to Current Frame from the Prism's FrameSet, - and get a pointer to the current Frame. */ - map = astGetMapping( this_region->frameset, AST__BASE, AST__CURRENT ); - cfrm = astGetFrame( this_region->frameset, AST__CURRENT ); - -/* Attempt to split the FrameSet encapsulated within the Prism into two - - one containing the axes spanned by the first component Region and - another containing the axes spanned by the second component Region. - First store the zero-based indices of the base Frame axes - corresponding to the first component Region. */ - for( iax = 0; iax < nax1; iax++ ) baxes[ iax ] = iax; - -/* Attempt to split these inputs from the total Mapping, thus creating a - Mapping that converts just the axes spanned by the first component - Region. */ - caxes = astMapSplit( map, nax1, baxes, &map1 ); - -/* If the Mapping could be split, get a Frame spanning the current Frame - axes corresponding to the first component Region. */ - if( caxes ) { - nax1_out = astGetNout( map1 ); - cfrm1 = astPickAxes( cfrm, nax1_out, caxes, NULL ); - caxes = astFree( caxes ); - } - -/* Do the same thing for the second component Region. */ - for( iax = 0; iax < nax2; iax++ ) baxes[ iax ] = iax + nax1; - caxes = astMapSplit( map, nax2, baxes, &map2 ); - if( caxes ) { - cfrm2 = astPickAxes( cfrm, astGetNout( map2 ), caxes, NULL ); - caxes = astFree( caxes ); - } - -/* Free resources. */ - cfrm = astAnnul( cfrm ); - map = astAnnul( map ); - } - baxes = astFree( baxes ); - -/* If the Prism mapping could not be split, use the parent GetRegionBounds - method. */ - if( !map1 || !map2 ) { - (*parent_getregionbounds)( this_region, lbnd, ubnd, status ); - -/* Otherwise, we get the bounds of the two component Regions separately. */ - } else { - -/* Remap the first component Region using the FrameSet created above. */ - reg1 = astMapRegion( this->region1, map1, cfrm1 ); - -/* Get the bounds of this Region, storing the results at the start of the - returned lbnd/ubnd arrays. */ - astGetRegionBounds( reg1, lbnd, ubnd ); - reg1 = astAnnul( reg1 ); - -/* Do the same thing for the second component Region, storing the results - at the end of the returned lbnd/ubnd arrays. */ - reg2 = astMapRegion( this->region2, map2, cfrm2 ); - astGetRegionBounds( reg2, lbnd + nax1_out, ubnd + nax1_out ); - reg2 = astAnnul( reg2 ); - -/* What about the possibility that the axes of the Prism have been - permuted? */ - - } - -/* Free resources. */ - if( map1 ) map1 = astAnnul( map1 ); - if( map2 ) map2 = astAnnul( map2 ); - if( cfrm1 ) cfrm1 = astAnnul( cfrm1 ); - if( cfrm2 ) cfrm2 = astAnnul( cfrm2 ); - -} - -static void GetRegions( AstPrism *this, AstRegion **reg1, AstRegion **reg2, - int *neg, int *status ) { -/* -* -* Name: -* GetRegions - -* Purpose: -* Get the component Regions of a Prism. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void GetRegions( AstPrism *this, AstRegion **reg1, AstRegion **reg2, -* int *neg, int *status ) - -* Class Membership: -* Prism member function - -* Description: -* This function returns pointers to the two Regions in a Prism, together -* with the Negated flag for the Prism. -* -* The current Frames in both the returned component Regions will be -* equivalent to componets of the base Frame in the FrameSet encapsulated -* by the parent Region structure. - -* Parameters: -* this -* Pointer to the Prism. -* reg1 -* Address of a location to receive a pointer to first component -* Region. This is the region which is to be extruded. -* reg2 -* Address of a location to receive a pointer to second component -* Region. This will be an Interval defining the axes along which -* the first Region is to be extruded. -* neg -* Pointer to an int in which to return the value of the Negated -* attribute of the Prism. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The returned pointers should be annuled using astAnnul when no -* longer needed. -* - The Frames represented by the returned Regions (that is, the -* current Frames in their encapsulated FrameSets) are equivalent to the -* base Frame in the FrameSet encapsulated within the parent Region. -* - Any changes made to the component Regions using the returned -* pointers will be reflected in the supplied Prism. - -*- -*/ - -/* Initialise */ - if( reg1 ) *reg1 = NULL; - if( reg2 ) *reg2 = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the required values.*/ - *reg1 = astClone( this->region1 ); - *reg2 = astClone( this->region2 ); - *neg = astGetNegated( (AstRegion *) this ); -} - -static AstRegion *GetDefUnc( AstRegion *this_region, int *status ) { -/* -* Name: -* GetDefUnc - -* Purpose: -* Obtain a pointer to the default uncertainty Region for a given Region. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* AstRegion *GetDefUnc( AstRegion *this ) - -* Class Membership: -* Prism method (over-rides the astGetDefUnc method inherited from -* the Region class). - -* This function returns a pointer to a Region which represents the -* default uncertainty associated with a position on the boundary of the -* given Region. The returned Region refers to the base Frame within the -* FrameSet encapsulated by the supplied Region. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* A pointer to the Region. This should be annulled (using astAnnul) -* when no longer needed. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to Prism structure */ - AstRegion *bunc1; /* Uncertainty Region for 1st component */ - AstRegion *bunc2; /* Uncertainty Region for 2nd component */ - AstRegion *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Prism structure. */ - this = (AstPrism *) this_region; - -/* Construct a default uncertainty Region from the uncertainty Regions - in the two component Regions. The current Frames in the component - Regions are equivalent to the base Frame in the parent Region structure. - So we may need to map the component uncertainty into the current Region of - the parent if required later on. */ - bunc1 = astGetUncFrm( this->region1, AST__CURRENT ); - bunc2 = astGetUncFrm( this->region2, AST__CURRENT ); - -/* Combine them into a Prism. */ - result = (AstRegion *) astPrism( bunc1, bunc2, "", status ); - -/* Free resources. */ - bunc1 = astAnnul( bunc1 ); - bunc2 = astAnnul( bunc2 ); - -/* Return NULL if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the required pointer. */ - return result; -} - -void astInitPrismVtab_( AstPrismVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitPrismVtab - -* Purpose: -* Initialise a virtual function table for a Prism. - -* Type: -* Protected function. - -* Synopsis: -* #include "prism.h" -* void astInitPrismVtab( AstPrismVtab *vtab, const char *name ) - -* Class Membership: -* Prism vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Prism class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAPrism) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -/* None. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - frame = (AstFrameVtab *) vtab; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - - parent_maplist = mapping->MapList; - mapping->MapList = MapList; - - parent_getdefunc = region->GetDefUnc; - region->GetDefUnc = GetDefUnc; - - parent_setregfs = region->SetRegFS; - region->SetRegFS = SetRegFS; - - parent_equal = object->Equal; - object->Equal = Equal; - - parent_clearclosed = region->ClearClosed; - region->ClearClosed = ClearClosed; - - parent_clearmeshsize = region->ClearMeshSize; - region->ClearMeshSize = ClearMeshSize; - - parent_setclosed = region->SetClosed; - region->SetClosed = SetClosed; - - parent_setmeshsize = region->SetMeshSize; - region->SetMeshSize = SetMeshSize; - - parent_getfillfactor = region->GetFillFactor; - region->GetFillFactor = GetFillFactor; - - parent_overlapx = region->OverlapX; - region->OverlapX = OverlapX; - - parent_regsetattrib = region->RegSetAttrib; - region->RegSetAttrib = RegSetAttrib; - - parent_regclearattrib = region->RegClearAttrib; - region->RegClearAttrib = RegClearAttrib; - - parent_getregionbounds = region->GetRegionBounds; - region->GetRegionBounds = GetRegionBounds; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - mapping->Decompose = Decompose; - region->RegBaseBox = RegBaseBox; - region->RegBaseMesh = RegBaseMesh; - region->RegPins = RegPins; - region->GetBounded = GetBounded; - region->RegCentre = RegCentre; - region->Overlap = Overlap; - region->RegBasePick = RegBasePick; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "Prism", "Region extrusion into higher dimensions" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* CmpMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to Prism structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the Prism structure. */ - this = (AstPrism *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->region1, mode, extra, fail ); - if( !result ) result = astManageLock( this->region2, mode, extra, fail ); - - return result; - -} -#endif - -static int MapList( AstMapping *this_mapping, int series, int invert, - int *nmap, AstMapping ***map_list, int **invert_list, - int *status ) { -/* -* Name: -* MapList - -* Purpose: -* Decompose a Prism into a sequence of simpler Regions. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapList( AstMapping *this, int series, int invert, int *nmap, -* AstMapping ***map_list, int **invert_list ) - -* Class Membership: -* Prism member function (over-rides the protected astMapList -* method inherited from the Region class). - -* Description: -* This function decomposes a Prism into a sequence of simpler -* Regions which may be applied in parallel to achieve the same -* effect. The Prism is decomposed as far as possible, but it is -* not guaranteed that this will necessarily yield any more than -* one Region, which may actually be the original Prism supplied. - -* Parameters: -* this -* Pointer to the Prism to be decomposed (the Prism is not -* actually modified by this function). -* series -* Prisms always apply their component Regions in parallel, so this -* value should always be zero. This function will return without -* action if it is non-zero. -* invert -* Inverting a Region has no effect on the properties of the Region -* and so this parameter is ignored. -* nmap -* The address of an int which holds a count of the number of -* individual Regions in the decomposition. On entry, this -* should count the number of Regions already in the -* "*map_list" array (below). On exit, it is updated to include -* any new Regions appended by this function. -* map_list -* Address of a pointer to an array of Region pointers. On -* entry, this array pointer should either be NULL (if no -* Regions have yet been obtained) or should point at a -* dynamically allocated array containing Region pointers -* ("*nmap" in number) which have been obtained from a previous -* invocation of this function. -* -* On exit, the dynamic array will be enlarged to contain any -* new Region pointers that result from the decomposition -* requested. These pointers will be appended to any previously -* present, and the array pointer will be updated as necessary -* to refer to the enlarged array (any space released by the -* original array will be freed automatically). -* -* The new Region pointers returned will identify a sequence of -* Regions which, when applied (in parallel) in order, will be -* equivalent to the original Prism. -* -* All the Region pointers returned by this function should be -* annulled by the caller, using astAnnul, when no longer -* required. The dynamic array holding these pointers should -* also be freed, using astFree. -* invert_list -* Address of a pointer to an array of int. On entry, this array -* pointer should either be NULL (if no Regions have yet been -* obtained) or should point at a dynamically allocated array -* containing Invert attribute values ("*nmap" in number) which -* have been obtained from a previous invocation of this -* function. -* -* On exit, the dynamic array will be enlarged to contain any -* new Invert attribute values that result from the -* decomposition requested. These values will be appended to any -* previously present, and the array pointer will be updated as -* necessary to refer to the enlarged array (any space released -* by the original array will be freed automatically). -* -* The new Invert values returned will always be zero since a -* Region is unaffected by its Invert setting. -* -* The dynamic array holding these values should be freed by the -* caller, using astFree, when no longer required. - -* Returned Value: -* Zero is always returned. - -* Notes: -* - It is unspecified to what extent the original Prism and the -* individual (decomposed) Regions are -* inter-dependent. Consequently, the individual Regions cannot be -* modified without risking modification of the original Prism. -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then the *nmap value, the -* list of Region pointers and the list of Invert values will all -* be returned unchanged. -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to Prism structure */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the Prism structure. */ - this = (AstPrism *) this_mapping; - -/* When considered as a CmpMap, a Prism always combines its component - Mappings (Regions) in parallel. So check that a parallel decomposition - was requested. */ - if ( ! series ) { - -/* Concatenate the Mapping lists obtained from each component Region. */ - (void) astMapList( (AstMapping *) this->region1, 0, 0, nmap, map_list, - invert_list ); - (void) astMapList( (AstMapping *) this->region2, 0, 0, nmap, map_list, - invert_list ); - -/* If the Prism does not combine its components in the way required - by the decomposition (series or parallel), then we cannot decompose - it. In this case it must be appended to the Mapping list as a - single entity. We can use the parent class method to do this. */ - } else { - (void) ( *parent_maplist )( this_mapping, series, invert, nmap, - map_list, invert_list, status ); - } - - return 0; -} - -static int Overlap( AstRegion *this, AstRegion *that, int *status ){ -/* -* Name: -* Overlap - -* Purpose: -* Test if two regions overlap each other. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* int Overlap( AstRegion *this, AstRegion *that, int *status ) - -* Class Membership: -* Prism member function (over-rides the astOverlap method inherited -* from the Region class). - -* Description: -* This function returns an integer value indicating if the two -* supplied Regions overlap. The two Regions are converted to a commnon -* coordinate system before performing the check. If this conversion is -* not possible (for instance because the two Regions represent areas in -* different domains), then the check cannot be performed and a zero value -* is returned to indicate this. - -* Parameters: -* this -* Pointer to the first Region. -* that -* Pointer to the second Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* astOverlap() -* A value indicating if there is any overlap between the two Regions. -* Possible values are: -* -* 0 - The check could not be performed because the second Region -* could not be mapped into the coordinate system of the first -* Region. -* -* 1 - There is no overlap between the two Regions. -* -* 2 - The first Region is completely inside the second Region. -* -* 3 - The second Region is completely inside the first Region. -* -* 4 - There is partial overlap between the two Regions. -* -* 5 - The Regions are identical. -* -* 6 - The second Region is the negation of the first Region. - -* Notes: -* - The returned values 5 and 6 do not check the value of the Closed -* attribute in the two Regions. -* - A value of zero will be returned if this function is invoked with the -* AST error status set, or if it should fail for any reason. - -*/ - -/* Local Variables: */ - AstFrame *bfrm; - AstFrame *efrm; - AstFrameSet *fs; - AstMapping *bmap; - AstMapping *emap; - AstMapping *map1; - AstMapping *map2; - AstMapping *map; - AstMapping *smap; - AstRegion *that_base2; - AstRegion *that_base; - AstRegion *that_ext2; - AstRegion *that_ext; - AstRegion *this_reg1; - AstRegion *this_reg2; - int *inax; - int *outax; - int i; - int nbase; - int next; - int rbase; - int result; - int rext; - int that_neg; - int this_neg; - -/* A table indicating how to combine together the overlap state of the - extrusion Regions with the overlap state of the other (base) Region. - The first index represents the value returned by the astOverlap method - when used to determine the overlap of the base Regions in the two - supplied Prisms. The second index represents the value returned by the - astOverlap method when used to determine the overlap of the extrusion - Regions in the two supplied Prisms. The integer values stored in the - array represent the astOverlap value describing the overlap of the two - Prisms. */ - static int rtable[ 7 ][ 7 ] = { { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 1, 1, 1, 1, 1, 1 }, - { 0, 1, 2, 4, 4, 2, 1 }, - { 0, 1, 4, 3, 4, 3, 1 }, - { 0, 1, 4, 4, 4, 4, 1 }, - { 0, 1, 2, 3, 4, 5, 1 }, - { 0, 1, 1, 1, 1, 1, 6 } }; - -/* Initialise */ - result = 0; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Get pointers to the base and extrusion Regions within "this", and also - the nagated flag. */ - GetRegions( (AstPrism *) this, &this_reg1, &this_reg2, &this_neg, status ); - -/* Get the number of axes in the base and extrusion Regions of "this". */ - nbase = astGetNaxes( this_reg1 ); - next = astGetNaxes( this_reg2 ); - -/* Get a FrameSet which goes from the Frame represented by "this" to the - Frame represented by "that". Check that the conection is defined. */ - fs = astConvert( this, that, "" ); - if( fs ) { - -/* Get the forward Mapping from the above FrameSet. */ - map2 = astGetMapping( fs, AST__BASE, AST__CURRENT ); - -/* Get a pointer to the Mapping from base to current Frame in "this". */ - map1 = astGetMapping( this->frameset, AST__BASE, AST__CURRENT ); - -/* Combine these Mappings to get the Mapping from the base Frame of "this" - to the current Frame of "that". */ - map = (AstMapping *) astCmpMap( map1, map2, 1, "", status ); - -/* Simplify this Mapping. */ - smap = astSimplify( map ); - -/* See if the extrusion axes in "this" correspond to a unique set of axes - in the current Frame of "that". */ - inax = astMalloc( sizeof(int)*(size_t)next ); - for( i = 0; i < next; i++ ) inax[ i ] = nbase + i; - outax = astMapSplit( smap, next, inax, &emap ); - -/* If they do, attempt to create a Region by picking the axes from "that" - that correspond to the extrusion axes in "this". */ - if( emap && astGetNout( emap ) == next ) { - that_ext = (AstRegion *) astPickAxes( that, next, outax, NULL ); - -/* If the picked axes formed a Region, see if the base axes can also be - picked in the same way. */ - if( astIsARegion( that_ext ) ) { - outax = astFree( outax ); - inax = astGrow( inax, (size_t)nbase, sizeof( int ) ); - for( i = 0; i < nbase; i++ ) inax[ i ] = i; - outax = astMapSplit( smap, nbase, inax, &bmap ); - if( bmap && astGetNout( bmap ) == nbase ) { - that_base = (AstRegion *) astPickAxes( that, nbase, outax, NULL ); - if( astIsARegion( that_base ) ) { - -/* Map the two Regions picked from "that" into the Frames of the two - sub-regions within "this". */ - astInvert( emap ); - efrm = astGetFrame( this_reg2->frameset, AST__CURRENT ); - that_ext2 = astMapRegion( that_ext, emap, efrm ); - - astInvert( bmap ); - bfrm = astGetFrame( this_reg1->frameset, AST__CURRENT ); - that_base2 = astMapRegion( that_base, bmap, bfrm ); - -/* We can test separately for overlap of the two extrusion Regions, and for - overlap of the two base Regions, and then combine the returned flags to - represent overlap of the whole Prism. */ - rbase = astOverlap( this_reg1, that_base2 ); - rext = astOverlap( this_reg2, that_ext2 ); - result = rtable[ rbase ][ rext ]; - -/* The values in the rtable array assume that neither of the supplied - Prisms have been negated. Modify the value obtained from rtable to - take account of negation of either or both of the supplied Prisms. */ - that_neg = astGetNegated( that ); - if( this_neg ) { - if( that_neg ) { - if( result == 1 ) { - result = 4; - } else if( result == 2 ) { - result = 3; - } else if( result == 3 ) { - result = 2; - } - } else { - if( result == 1 ) { - result = 3; - } else if( result == 2 ) { - result = 4; - } else if( result == 3 ) { - result = 1; - } else if( result == 5 ) { - result = 6; - } else if( result == 6 ) { - result = 5; - } - } - } else if( that_neg ){ - if( result == 1 ) { - result = 2; - } else if( result == 2 ) { - result = 1; - } else if( result == 3 ) { - result = 4; - } else if( result == 5 ) { - result = 6; - } else if( result == 6 ) { - result = 5; - } - } - -/* Free resources */ - efrm = astAnnul( efrm ); - that_ext2 = astAnnul( that_ext2 ); - bfrm = astAnnul( bfrm ); - that_base2 = astAnnul( that_base2 ); - } - that_base = astAnnul( that_base ); - bmap = astAnnul( bmap ); - } - } - emap = astAnnul( emap ); - that_ext = astAnnul( that_ext ); - } - outax = astFree( outax ); - inax = astFree( inax ); - smap = astAnnul( smap ); - map = astAnnul( map ); - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - fs = astAnnul( fs ); - } - this_reg1 = astAnnul( this_reg1 ); - this_reg2 = astAnnul( this_reg2 ); - -/* If overlap could not be determined using the above implementation, try - using the implementation inherited from the parent Region class. Use - OverlapX rather than Overlap since a) it is OverlapX that does the work, - and b) calling Overlap could end us in an infinite loop. */ - if( !result ) result = (*parent_overlapx)( this, that, status ); - -/* If not OK, return zero. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int OverlapX( AstRegion *that, AstRegion *this, int *status ){ -/* -* Name: -* OverlapX - -* Purpose: -* Test if two regions overlap each other. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* int OverlapX( AstRegion *that, AstRegion *this ) - -* Class Membership: -* Prism member function (over-rides the astOverlapX method inherited -* from the Region class). - -* Description: -* This function performs the processing for the public astOverlap -* method and has exactly the same interface except that the order -* of the two arguments is swapped. This is a trick to allow -* the astOverlap method to be over-ridden by derived classes on -* the basis of the class of either of its two arguments. -* -* See the astOverlap method for details of the interface. -*/ - -/* Local Variables; */ - int result; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* We know that "that" is a Prism, so call the private Overlap method, - and then modify the returned value to take account of the fact that the - two Regions are swapped. */ - result = Overlap( that, this, status ); - - if( result == 2 ){ - result = 3; - } else if( result == 3 ){ - result = 2; - } - - return result; -} - - -static void RegBaseBox( AstRegion *this_region, double *lbnd, double *ubnd, - int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, -* int *status ) - -* Class Membership: -* Prism member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to Prism structure */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - int nax; /* Number of axes in Frame */ - int neg; /* Negated flag for Prism */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Prism structure */ - this = (AstPrism *) this_region; - -/* Get pointers to the component Regions. */ - GetRegions( this, ®1, ®2, &neg, status ); - -/* The base Frame of the parent Region structure is equivalent to a - CmpFrame containing the current Frames of the component Regions. - Get the no. of axes in the first component Frame. */ - nax = astGetNaxes( reg1 ); - -/* Get the bounding boxes of the component Regions in these Frame, - storing the values in the supplied arrays. */ - astGetRegionBounds( reg1, lbnd, ubnd ); - astGetRegionBounds( reg2, lbnd + nax, ubnd + nax ); - -/* Free resources.*/ - reg1 = astAnnul( reg1 ); - reg2 = astAnnul( reg2 ); -} - -static AstPointSet *RegBaseMesh( AstRegion *this_region, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Return a PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* AstPointSet *RegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* Prism member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. Annul the pointer using astAnnul when it -* is no longer needed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - - -/* Local Variables: */ - AstPointSet *grid1; /* PointSet holding grid for region1 */ - AstPointSet *grid2; /* PointSet holding grid for region2 */ - AstPointSet *mesh1; /* PointSet holding mesh for region1 */ - AstPointSet *mesh2; /* PointSet holding mesh for region2 */ - AstPointSet *result; /* Returned pointer */ - AstPrism *this; /* The Prism structure */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - double **pg1; /* Pointer to grid1 arrays */ - double **pg2; /* Pointer to grid2 arrays */ - double **pm1; /* Pointer to mesh1 arrays */ - double **pm2; /* Pointer to mesh2 arrays */ - double **ptr; /* Pointer to returned mesh arrays */ - int gsz1; /* Preferred grid size for region1 */ - int gsz2; /* Preferred grid size for region2 */ - int hasMesh1; /* Does 1st component Region have a mesh? */ - int hasMesh2; /* Does 2nd component Region have a mesh? */ - int i; /* Index of next mesh position */ - int ii; /* Index of next results position */ - int j; /* Index of next grid position */ - int jc; /* Axis index */ - int msz1; /* Preferred mesh size for region1 */ - int msz2; /* Preferred mesh size for region2 */ - int msz; /* Original MeshSize */ - int mszp; /* MeshSize value for Prism */ - int nax1; /* Number of axes in region1 */ - int nax2; /* Number of axes in region2 */ - int nax; /* Number of axes in Prism */ - -/* Initialise */ - result= NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Prism structure. */ - this = (AstPrism *) this_region; - -/* If the Region structure contains a pointer to a PointSet holding - a previously created mesh, return it. */ - if( this_region->basemesh ) { - result = astClone( this_region->basemesh ); - -/* Otherwise, create a new mesh. */ - } else { - -/* Get pointers to the component regions. */ - reg1 = this->region1; - reg2 = this->region2; - -/* A mesh can only be produced for a Region if it is bounded when either - negated or un-negated. See if meshes can be produced for the component - Regions. */ - hasMesh1 = astGetBounded( reg1 ); - if( !hasMesh1 ){ - astNegate( reg1 ); - hasMesh1 = astGetBounded( reg1 ); - astNegate( reg1 ); - } - - hasMesh2 = astGetBounded( reg2 ); - if( !hasMesh2 ){ - astNegate( reg2 ); - hasMesh2 = astGetBounded( reg2 ); - astNegate( reg2 ); - } - -/* If either Region does not have a mesh we cannot produce a mesh for the - Prism. */ - if( !hasMesh1 || !hasMesh2 ) { - if( astOK ) astError( AST__INTER, "astRegBaseMesh(%s): No mesh " - "can be produced for the %s bacause one of its component " - "Regions is unbounded.", status, astGetClass( this ), astGetClass( this ) ); - -/* Otherwise we can create a mesh for the Prism. */ - } else { - -/* Determine the grid sizes and mesh sizes to use for the two components. - This aims to produce a total number of points in the returned Prism - mesh roughly equal to the MeshSize attribute of the Prism. It also - aims to divide the mesh points equally between the end faces of the - prism, and the side walls. We remember that the grid used to represent - any 1-D region always has a size of 2, regardless of the setting of - MeshSize. */ - mszp = astGetMeshSize( this ); - msz1 = ( astGetNaxes( reg1 ) == 1 ) ? 2 : sqrt( 0.5*mszp ); - gsz2 = 0.5*mszp/msz1; - msz2 = ( astGetNaxes( reg2 ) == 1 ) ? 2 : sqrt( 0.5*mszp ); - gsz1 = 0.5*mszp/msz2; - -/* First, get a boundary mesh for the second component Region defining the - prism extrusion. For instance, if the Region is 1-dimensional, this mesh - will consist of the two values on the Region axis: the lower and upper - bounds of the Region. */ - msz = astTestMeshSize( reg2 ) ? astGetMeshSize( reg2 ) : -1; - astSetMeshSize( reg2, msz2 ); - mesh2 = astRegMesh( reg2 ); - -/* Also get a grid of points spread throughout the extent (i.e. not - merely on the boundary) of the second Region. */ - astSetMeshSize( reg2, gsz2 ); - grid2 = astRegGrid( reg2 ); - -/* Re-instate the original MeshSize for the second Region. */ - if( msz == -1 ) { - astClearMeshSize( reg2 ); - } else { - astSetMeshSize( reg2, msz ); - } - -/* Similarly, get a boundary mesh and a volume grid for the first Region. */ - msz = astTestMeshSize( reg1 ) ? astGetMeshSize( reg1 ) : -1; - astSetMeshSize( reg1, msz1 ); - mesh1 = astRegMesh( reg1 ); - - astSetMeshSize( reg1, gsz1 ); - grid1 = astRegGrid( reg1 ); - - if( msz == -1 ) { - astClearMeshSize( reg1 ); - } else { - astSetMeshSize( reg1, msz ); - } - -/* Note the number of axes in the two component Regions. */ - nax1 = astGetNcoord( mesh1 ); - nax2 = astGetNcoord( mesh2 ); - -/* The above mesh and grid sizes are only approximate. Find the values - actually used. */ - msz1 = astGetNpoint( mesh1 ); - gsz1 = astGetNpoint( grid1 ); - msz2 = astGetNpoint( mesh2 ); - gsz2 = astGetNpoint( grid2 ); - -/* Create the returned PointSet. */ - msz = gsz1*msz2 + msz1*gsz2; - nax= astGetNaxes( this ); - result = astPointSet( msz, nax, "", status ); - -/* Get pointers to the data in all 5 PointSets. */ - ptr = astGetPoints( result ); - pm1 = astGetPoints( mesh1 ); - pg1 = astGetPoints( grid1 ); - pm2 = astGetPoints( mesh2 ); - pg2 = astGetPoints( grid2 ); - -/* Check pointers can be de-referenced safely. */ - if( astOK ) { - -/* Initialise the index of the next point to be written to the results - array. */ - ii = 0; - -/* First, replicate the volume grid covering the first region at every - point in the boundary mesh covering the second Region. */ - for( i = 0; i < msz2; i++ ) { - for( j = 0; j < gsz1; j++, ii++ ) { - for( jc = 0; jc < nax1; jc++ ) { - ptr[ jc ][ ii ] = pg1[ jc ][ j ]; - } - for( ; jc < nax; jc++ ) { - ptr[ jc ][ ii ] = pm2[ jc - nax1 ][ i ]; - } - } - } - -/* Now, replicate the volume grid covering the second region at every - point in the boundary mesh covering the first Region. */ - for( i = 0; i < msz1; i++ ) { - for( j = 0; j < gsz2; j++, ii++ ) { - for( jc = 0; jc < nax1; jc++ ) { - ptr[ jc ][ ii ] = pm1[ jc ][ i ]; - } - for( ; jc < nax; jc++ ) { - ptr[ jc ][ ii ] = pg2[ jc -nax1 ][ j ]; - } - } - } - } - -/* Free resources. */ - mesh1 = astAnnul( mesh1 ); - mesh2 = astAnnul( mesh2 ); - grid1 = astAnnul( grid1 ); - grid2 = astAnnul( grid2 ); - } - -/* Save the returned pointer in the Region structure so that it does not - need to be created again next time this function is called. */ - if( astOK && result ) this_region->basemesh = astClone( result ); - } - -/* Annul the result if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static AstRegion *RegBasePick( AstRegion *this_region, int naxes, - const int *axes, int *status ){ -/* -* Name: -* RegBasePick - -* Purpose: -* Return a Region formed by picking selected base Frame axes from the -* supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* AstRegion *RegBasePick( AstRegion *this, int naxes, const int *axes, -* int *status ) - -* Class Membership: -* Prism member function (over-rides the astRegBasePick protected -* method inherited from the Region class). - -* Description: -* This function attempts to return a Region that is spanned by selected -* axes from the base Frame of the encapsulated FrameSet of the supplied -* Region. This may or may not be possible, depending on the class of -* Region. If it is not possible a NULL pointer is returned. - -* Parameters: -* this -* Pointer to the Region. -* naxes -* The number of base Frame axes to select. -* axes -* An array holding the zero-based indices of the base Frame axes -* that are to be selected. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Region, or NULL if no region can be formed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *frm1; /* Axes picked from the 1st encapsulated Region */ - AstFrame *frm2; /* Axes picked from the 2nd encapsulated Region */ - AstPrism *this; /* Pointer to Prism structure */ - AstRegion *result; /* Returned Region */ - int *axes1; /* Axes to pick from 1st input encapsulated Region */ - int *axes2; /* Axes to pick from 2nd input encapsulated Region */ - int i; /* Output axis index */ - int j; /* Input axis index */ - int nax1; /* No. of axes in 1st input encapsulated Region */ - int nax2; /* No. of axes in 2nd input encapsulated Region */ - int naxes1; /* No. of axes in 1st output encapsulated Region */ - int naxes2; /* No. of axes in 2nd output encapsulated Region */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Prism information. */ - this = (AstPrism *) this_region; - -/* Get the number of axes in each of the two encapsulated Regions. */ - nax1 = astGetNaxes( this->region1 ); - nax2 = astGetNaxes( this->region2 ); - -/* Allocate memory to hold the indices of the axes selected from each of - the two encapsulated Regions. */ - axes1 = astMalloc( sizeof( *axes1 )*nax1 ); - axes2 = astMalloc( sizeof( *axes2 )*nax2 ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Initialise the counters that count the number of axes selected from - each of the two encapsulated Regions. */ - naxes1 = 0; - naxes2 = 0; - -/* For each of the axes to be selected from the prism... */ - for( i = 0; i < naxes; i++ ) { - j = axes[ i ]; - -/* ... if the current selected axis is part of the first encapsulated - Region, add its index into the array that holds the axes to be selected - from the first encapsulated region. Increment the number of axes - selected from the first encapsulated region. */ - if( j < nax1 ) { - axes1[ naxes1++ ] = j; - -/* If the current selected axis is part of the second encapsulated Region, - add its index into the array that holds the axes to be selected from - the second encapsulated region. Note, the index is converted from a - Prism axis index to a sub-region axis index by subtracting "nax1". - Also increment the number of axes selected from the second encapsulated - region. */ - } else { - axes2[ naxes2++ ] = j - nax1; - } - } - -/* Pick any required axes from the first sub-region. If the result of the - selection is not a Region, we cannot pick the required axes, so annul - the object holding the selected axes. */ - if( naxes1 ) { - frm1 = astPickAxes( this->region1, naxes1, axes1, NULL ); - if( frm1 && !astIsARegion( frm1 ) ) frm1 = astAnnul( frm1 ); - } else { - frm1 = NULL; - } - -/* Pick any required axes from the second sub-region. If the result of the - selection is not a Region, we cannot pick the required axes, so annul - the object holding the selected axes. */ - if( naxes2 ) { - frm2 = astPickAxes( this->region2, naxes2, axes2, NULL ); - if( frm2 && !astIsARegion( frm2 ) ) frm2 = astAnnul( frm2 ); - } else { - frm2 = NULL; - } - -/* If we are selecting axes only from the first sub-region, and the above - selection was succesful, just return a clone of the Region holding the - axes selected from the first sub-region. */ - if( naxes1 > 0 && naxes2 == 0 && frm1 ) { - result = astClone( frm1 ); - -/* If we are selecting axes only from the second sub-region, and the above - selection was succesful, just return a clone of the Region holding the - axes selected from the second sub-region. */ - } else if( naxes1 == 0 && naxes2 > 0 && frm2 ) { - result = astClone( frm2 ); - -/* If we are selecting axes from both sub-regions, and both the above - selections were succesful, joing them together into a Prism. */ - } else if( naxes1 > 0 && naxes2 > 0 && frm1 && frm2 ) { - result = (AstRegion *) astPrism( (AstRegion *) frm1, - (AstRegion *) frm2, - "", status ); - } - -/* Free resources */ - if( frm1 ) frm1 = astAnnul( frm1 ); - if( frm2 ) frm2 = astAnnul( frm2 ); - } - - axes1 = astFree( axes1 ); - axes2 = astFree( axes2 ); - -/* Return a NULL pointer if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static double *RegCentre( AstRegion *this_region, double *cen, double **ptr, - int index, int ifrm, int *status ){ -/* -* Name: -* RegCentre - -* Purpose: -* Re-centre a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* double *RegCentre( AstRegion *this, double *cen, double **ptr, -* int index, int ifrm, int *status ) - -* Class Membership: -* Prism member function (over-rides the astRegCentre protected -* method inherited from the Region class). - -* Description: -* This function shifts the centre of the supplied Region to a -* specified position, or returns the current centre of the Region. - -* Parameters: -* this -* Pointer to the Region. -* cen -* Pointer to an array of axis values, giving the new centre. -* Supply a NULL value for this in order to use "ptr" and "index" to -* specify the new centre. -* ptr -* Pointer to an array of points, one for each axis in the Region. -* Each pointer locates an array of axis values. This is the format -* returned by the PointSet method astGetPoints. Only used if "cen" -* is NULL. -* index -* The index of the point within the arrays identified by "ptr" at -* which is stored the coords for the new centre position. Only used -* if "cen" is NULL. -* ifrm -* Should be AST__BASE or AST__CURRENT. Indicates whether the centre -* position is supplied and returned in the base or current Frame of -* the FrameSet encapsulated within "this". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If both "cen" and "ptr" are NULL then a pointer to a newly -* allocated dynamic array is returned which contains the centre -* coords of the Region. This array should be freed using astFree when -* no longer needed. If either of "ptr" or "cen" is not NULL, then a -* NULL pointer is returned. - -* Notes: -* - Some Region sub-classes do not have a centre. Such classes will report -* an AST__INTER error code if this method is called with either "ptr" or -* "cen" not NULL. If "ptr" and "cen" are both NULL, then no error is -* reported if this method is invoked on a Region of an unsuitable class, -* but NULL is always returned. -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to Prism structure */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - double *bc; /* Base Frame centre position */ - double *cen1; /* Centre of first component Region */ - double *cen2; /* Centre of second component Region */ - double *result; /* Returned pointer */ - double *tmp; /* Temporary array pointer */ - double *total; /* Pointer to total base Frame centre array */ - int i; /* Coordinate index */ - int nax1; /* Number of axes in first component Region */ - int nax2; /* Number of axes in second component Region */ - int ncb; /* Number of base frame coordinate values per point */ - int ncc; /* Number of current frame coordinate values per point */ - int neg; /* Prism negated flag */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Prism structure. */ - this = (AstPrism *) this_region; - -/* Get the component Regions, and the Negated flag for the Prism. */ - GetRegions( this, ®1, ®2, &neg, status ); - -/* Get the number of current Frame axes in each component Region. The sum - of these will equal the number of base Frame axes in the parent Region - structure. */ - nax1 = astGetNaxes( reg1 ); - nax2 = astGetNaxes( reg2 ); - ncb = nax1 + nax2; - -/* If we are getting (not setting) the current centre... */ - if( !ptr && !cen ) { - -/* Get the centre from the two component Regions in their current Frames. */ - cen1 = astRegCentre( reg1, NULL, NULL, 0, AST__CURRENT ); - cen2 = astRegCentre( reg2, NULL, NULL, 0, AST__CURRENT ); - -/* If both component regions are re-centerable, join the two centre - arrays together into a single array. */ - if( cen1 && cen2 ) { - total = astMalloc( sizeof(double)*(size_t)ncb ); - if( total ) { - for( i = 0; i < nax1; i++ ) total[ i ] = cen1[ i ]; - for( i = 0; i < nax2; i++ ) total[ i + nax1 ] = cen2[ i ]; - -/* The current Frames of the component Regions correspond to the base - Frame of the parent Region structure. If the original centre is - required in the current Frame, transform it using the base->current - Mapping from the parent Region structure. */ - if( ifrm == AST__CURRENT ) { - result = astRegTranPoint( this_region, total, 1, 1 ); - total = astFree( total ); - } else { - result = total; - } - } - } - -/* Free the individual centre arrays. */ - cen1 = astFree( cen1 ); - cen2 = astFree( cen2 ); - -/* If we are setting a new centre... */ - } else { - -/* If the new centre is supplied in the current Frame of the parent - Region structure, transform it into the base Frame (i.e. the Frames - represented by the component Regions). */ - if( ifrm == AST__CURRENT ) { - if( cen ) { - bc = astRegTranPoint( this_region, cen, 1, 0 ); - } else { - ncc = astGetNaxes( this_region ); - tmp = astMalloc( sizeof( double)*(size_t)ncc ); - if( astOK ) { - for( i = 0; i < ncc; i++ ) tmp[ i ] = ptr[ i ][ index ]; - } - bc = astRegTranPoint( this_region, tmp, 1, 0 ); - tmp = astFree( tmp ); - } - - } else { - if( cen ) { - bc = cen; - } else { - bc = astMalloc( sizeof( double)*(size_t)ncb ); - if( astOK ) { - for( i = 0; i < ncb; i++ ) bc[ i ] = ptr[ i ][ index ]; - } - } - } - -/* Set the centre in the two component Regions in their current Frames. */ - astRegCentre( reg1, bc, NULL, 0, AST__CURRENT ); - astRegCentre( reg2, bc + nax1, NULL, 0, AST__CURRENT ); - -/* Free resources. */ - if( bc != cen ) bc = astFree( bc ); - } - - reg1 = astAnnul( reg1 ); - reg2 = astAnnul( reg2 ); - -/* Return the result. */ - return result; -} - -static int RegPins( AstRegion *this_region, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -* Name: -* RegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given Prism. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask, int *status ) - -* Class Membership: -* Prism member function (over-rides the astRegPins protected -* method inherited from the Region class). - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given Prism. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied Prism "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the Prism. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "pset". -* Each element in the returned array is set to 1 if the -* corresponding position in "pset" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*/ - -/* Local variables: */ - AstPointSet *ps1; /* Points projected into 1st component Region */ - AstPointSet *ps1b; /* "ps1" in base Frame of 1st component Region */ - AstPointSet *ps1b2; /* "ps1b" transformed using 1st Region */ - AstPointSet *ps2b2; /* "ps2b" transformed using 2nd Region */ - AstPointSet *ps2; /* Points projected into 2nd component Region */ - AstPointSet *ps2b; /* "ps2" in base Frame of 2nd component Region */ - AstPrism *this; /* Pointer to the Prism structure. */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - AstRegion *unc1; /* Base Frame uncertainty in 1st component Region */ - AstRegion *unc2; /* Base Frame uncertainty in 2nd component Region */ - double **ptr1b2; /* Pointer to axis values in "ps1b2" */ - double **ptr2b2; /* Pointer to axis values in "ps2b2" */ - int *mask1; /* Mask for first component boundary */ - int *mask2; /* Mask for second component boundary */ - int cl1; /* Original Closed flag for reg1 */ - int cl2; /* Original Closed flag for reg2 */ - int i; /* Point index */ - int j; /* Axis index */ - int nax1; /* Number of axes in first component Region */ - int nax2; /* Number of axes in second component Region */ - int np; /* Number of points in supplied PointSet */ - int on; /* Is this point on the Prism boundary? */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - if( mask ) *mask = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get a pointer to the Prism structure. */ - this = (AstPrism *) this_region; - -/* Get pointers to the two component Regions. */ - reg1 = this->region1; - reg2 = this->region2; - -/* Temporarily ensure the components are closed. */ - cl1 = astTestClosed( reg1 ) ? astGetClosed( reg1 ) : INT_MAX; - cl2 = astTestClosed( reg2 ) ? astGetClosed( reg2 ) : INT_MAX; - astSetClosed( reg1, cl1 ); - astSetClosed( reg2, cl2 ); - -/* A point in the coordinate system represented by the Prism is on the - boundary of the Prism if: - 1) it is on the boundary of one of the coomponent Regions AND - 2) it is on or within the boundary of the other component Region. - - First look for points on the boundary of the first component Region. - Create a PointSet holding just the axes from the supplied PointSet - which relate to the first component Region. */ - np = astGetNpoint( pset ); - nax1 = astGetNaxes( reg1 ); - ps1 = astPointSet( np, nax1, "", status ); - astSetSubPoints( pset, 0, 0, ps1 ); - -/* Get a mask which indicates if each supplied point is on or off the - boundary of the first component Region. astRegPins expects its "pset" - argument to contain positions in the base Frame of the Region, so - we must first transform the supplied points into the base Frame of - "reg1". We must also get the uncertainty in the base Frame of the - component Region. */ - ps1b = astRegTransform( reg1, ps1, 0, NULL, NULL ); - unc1 = astGetUncFrm( reg1, AST__BASE ); - astRegPins( reg1, ps1b, unc1, &mask1 ); - -/* Also determine which of the points are on or in the boundary by using - "reg1" as a Mapping to transform the supplied points. */ - ps1b2 = astTransform( reg1, ps1b, 1, NULL ); - -/* Do the same for the second component Region */ - nax2 = astGetNaxes( reg2 ); - ps2 = astPointSet( np, nax2, "", status ); - astSetSubPoints( pset, 0, nax1, ps2 ); - ps2b = astRegTransform( reg2, ps2, 0, NULL, NULL ); - unc2 = astGetUncFrm( reg2, AST__BASE ); - astRegPins( reg2, ps2b, unc2, &mask2 ); - ps2b2 = astTransform( reg2, ps2b, 1, NULL ); - -/* Get pointers to the data in all the relevant PointSets. */ - ptr1b2 = astGetPoints( ps1b2 ); - ptr2b2 = astGetPoints( ps2b2 ); - -/* Check pointers can be dereferenced safely. */ - if( astOK ) { - -/* Assume all points are on the boundary of the Prism. */ - result = 1; - -/* Check each point. */ - for( i = 0; i < np; i++ ) { - -/* Assume this point is on the boundary of the Prism. */ - on = 1; - -/* If this point is on the boundary of both component Regions, it is on - the boundary of the Prism. If it is on the boundary of the first - component Region but not on the boundary of the second, then it is - still on the boundary of the Prism if it is within the volume - reporesented by the second. */ - if( mask1[ i ] ) { - if( !mask2[ i ] ) { - for( j = 0; j < nax2; j++ ) { - if( ptr2b2[ j ][ i ] == AST__BAD ) { - on = 0; - break; - } - } - } - -/* If this point is on the boundary of the second component Region but - not the first, it is on the boundary of the Prism if it is within the - volume reporesented by the first. */ - } else { - if( mask2[ i ] ) { - for( j = 0; j < nax1; j++ ) { - if( ptr1b2[ j ][ i ] == AST__BAD ) { - on = 0; - break; - } - } - -/* If this point is on the boundary of neither component Region, it is not - on the boundary of the Prism. */ - } else { - on = 0; - } - } - -/* Use "mask1" to return the Prism's mask. Clear the returned flag if - this point is not on the boundary of the Prism. */ - mask1[ i ] = on; - if( !on ) result = 0; - } - } - -/* Re-instate the original values of the Closed attribute for the - component Regions. */ - if( cl1 == INT_MAX ) { - astClearClosed( reg1 ); - } else { - astSetClosed( reg1, cl1 ); - } - if( cl2 == INT_MAX ) { - astClearClosed( reg2 ); - } else { - astSetClosed( reg2, cl2 ); - } - -/* Return "mask1" as the Prism's mask if required. Otherwise free it. */ - if( mask ) { - *mask = mask1; - } else { - mask1 = astFree( mask1 ); - } - -/* Free other resources */ - mask2 = astFree( mask2 ); - ps1 = astAnnul( ps1 ); - ps1b = astAnnul( ps1b ); - ps1b2 = astAnnul( ps1b2 ); - ps2 = astAnnul( ps2 ); - unc1 = astAnnul( unc1 ); - ps2b = astAnnul( ps2b ); - ps2b2 = astAnnul( ps2b2 ); - unc2 = astAnnul( unc2 ); - -/* If an error has occurred, return zero. */ - if( !astOK ) { - result = 0; - if( mask ) *mask = astAnnul( *mask ); - } - -/* Return the result. */ - return result; -} - -static void RegClearAttrib( AstRegion *this_region, const char *attrib, - char **base_attrib, int *status ) { -/* -* Name: -* RegClearAttrib - -* Purpose: -* Clear an attribute value for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* void RegClearAttrib( AstRegion *this, const char *attrib, -* char **base_attrib, int *status ) - -* Class Membership: -* Prism member function (over-rides the astRegClearAttrib method -* inherited from the Region class). - -* Description: -* This function clears the value of a named attribute in both the base -* and current Frame in the FrameSet encapsulated within a Region, without -* remapping either Frame. -* -* No error is reported if the attribute is not recognised by the base -* Frame. - -* Parameters: -* this -* Pointer to the Region. -* attrib -* Pointer to a null terminated string holding the attribute name. -* NOTE, IT SHOULD BE ENTIRELY LOWER CASE. -* base_attrib -* Address of a location at which to return a pointer to the null -* terminated string holding the attribute name which was cleared in -* the base Frame of the encapsulated FrameSet. This may differ from -* the supplied attribute if the supplied attribute contains an axis -* index and the current->base Mapping in the FrameSet produces an -* axis permutation. The returned pointer should be freed using -* astFree when no longer needed. A NULL pointer may be supplied in -* which case no pointer is returned. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPrism *this; - AstRegion *creg; - char *batt; - char buf1[ 100 ]; - char buf2[ 255 ]; - int axis; - int len; - int nax1; - int nc; - int rep; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Prism structure. */ - this = (AstPrism *) this_region; - -/* Use the RegClearAttrib method inherited from the parent class to clear the - attribute in the current and base Frames in the FrameSet encapsulated by - the parent Region structure. */ - (*parent_regclearattrib)( this_region, attrib, &batt, status ); - -/* We now propagate the setting down to the component Regions. The current - Frames in the component Regions together form a CmpFrame which is - equivalent to the base Frame in the parent FrameSet. Switch off error - reporting whilst we apply the setting to the component Regions. */ - rep = astReporting( 0 ); - -/* If the setting which was applied to the base Frame of the parent FrameSet - is qualified by an axis index, modify the axis index to refer to component - Region which defines the axis. First parse the base Frame attribute setting - to locate any axis index. */ - len = strlen( batt ); - if( nc = 0, ( 2 == astSscanf( batt, "%[^(](%d) %n", buf1, &axis, - &nc ) ) && ( nc >= len ) ) { - -/* If found, convert the axis index from one-based to zero-based. */ - axis--; - -/* Get a pointer to the component Region containing the specified axis, and - create a new setting with the same attribute name but with the axis index - appropriate to the component Region which defines the axis. */ - nax1 = astGetNaxes( this->region1 ); - if( axis < nax1 ) { - creg = this->region1; - } else { - creg = this->region2; - axis -= nax1; - } - sprintf( buf2, "%s(%d)", buf1, axis + 1 ); - -/* Apply the setting to the relevant component Region. */ - astRegClearAttrib( creg, buf2, NULL ); - -/* If the setting is not qualified by an axis index, apply it to both - component Regions. */ - } else { - astRegClearAttrib( this->region1, batt, NULL ); - astRegClearAttrib( this->region2, batt, NULL ); - } - -/* Annul the error if the attribute was not recognised by the component - Regions. Then switch error reporting back on. */ - if( astStatus == AST__BADAT ) astClearStatus; - astReporting( rep ); - -/* If required, return the base Frame setting string. Otherwise free it. */ - if( base_attrib ) { - *base_attrib = batt; - } else { - batt = astFree( batt ); - } - -} - -static void RegSetAttrib( AstRegion *this_region, const char *setting, - char **base_setting, int *status ) { -/* -* Name: -* RegSetAttrib - -* Purpose: -* Set an attribute value for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* void RegSetAttrib( AstRegion *this, const char *setting, -* char **base_setting, int *status ) - -* Class Membership: -* Prism method (over-rides the astRegSetAttrib method inherited from -* the Region class). - -* Description: -* This function assigns an attribute value to both the base and -* current Frame in the FrameSet encapsulated within a Region, without -* remapping either Frame. -* -* No error is reported if the attribute is not recognised by the base -* Frame. - -* Parameters: -* this -* Pointer to the Region. -* setting -* Pointer to a null terminated attribute setting string. NOTE, IT -* SHOULD BE ENTIRELY LOWER CASE. The supplied string will be -* interpreted using the public interpretation implemented by -* astSetAttrib. This can be different to the interpretation of the -* protected accessor functions. For instance, the public -* interpretation of an unqualified floating point value for the -* Epoch attribute is to interpet the value as a gregorian year, -* but the protected interpretation is to interpret the value as an -* MJD. -* base_setting -* Address of a location at which to return a pointer to the null -* terminated attribute setting string which was applied to the -* base Frame of the encapsulated FrameSet. This may differ from -* the supplied setting if the supplied setting contains an axis -* index and the current->base Mapping in the FrameSet produces an -* axis permutation. The returned pointer should be freed using -* astFree when no longer needed. A NULL pointer may be supplied in -* which case no pointer is returned. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPrism *this; - AstRegion *creg; - char *bset; - char buf1[ 100 ]; - char buf2[ 255 ]; - int axis; - int len; - int nax1; - int nc; - int rep; - int value; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Prism structure. */ - this = (AstPrism *) this_region; - -/* Use the RegSetAttrib method inherited from the parent class to apply the - setting to the current and base Frames in the FrameSet encapsulated by the - parent Region structure. */ - (*parent_regsetattrib)( this_region, setting, &bset, status ); - -/* We now propagate the setting down to the component Regions. The current - Frames in the component Regions together form a CmpFrame which is - equivalent to the base Frame in the parent FrameSet. Switch off error - reporting whilst we apply the setting to the component Regions. */ - rep = astReporting( 0 ); - -/* If the setting which was applied to the base Frame of the parent FrameSet - is qualified by an axis index, modify the axis index to refer to component - Region which defines the axis. First parse the base Frame attribute setting - to locate any axis index. */ - len = strlen( bset ); - if( nc = 0, ( 2 == astSscanf( bset, "%[^(](%d)= %n%*s %n", buf1, &axis, - &value, &nc ) ) && ( nc >= len ) ) { - -/* If found, convert the axis index from one-based to zero-based. */ - axis--; - -/* Get a pointer to the component Region containing the specified axis, and - create a new setting with the same attribute name but with the axis index - appropriate to the component Region which defines the axis. */ - nax1 = astGetNaxes( this->region1 ); - if( axis < nax1 ) { - creg = this->region1; - } else { - creg = this->region2; - axis -= nax1; - } - sprintf( buf2, "%s(%d)=%s", buf1, axis + 1, bset + value ); - -/* Apply the setting to the relevant component Region. */ - astRegSetAttrib( creg, buf2, NULL ); - -/* If the setting is not qualified by an axis index, apply it to both - component Regions. */ - } else { - astRegSetAttrib( this->region1, bset, NULL ); - astRegSetAttrib( this->region2, bset, NULL ); - } - -/* Annul the error if the attribute was not recognised by the component - Regions. Then switch error reporting back on. */ - if( astStatus == AST__BADAT ) astClearStatus; - astReporting( rep ); - -/* If required, return the base Frame setting string. Otherwise free it. */ - if( base_setting ) { - *base_setting = bset; - } else { - bset = astFree( bset ); - } - -} - -static void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) { -/* -* Name: -* SetRegFS - -* Purpose: -* Stores a new FrameSet in a Region - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) - -* Class Membership: -* Prism method (over-rides the astSetRegFS method inherited from -* the Region class). - -* Description: -* This function creates a new FrameSet and stores it in the supplied -* Region. The new FrameSet contains two copies of the supplied -* Frame, connected by a UnitMap. - -* Parameters: -* this -* Pointer to the Region. -* frm -* The Frame to use. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *cfrm; /* Frame containing required axes */ - AstRegion *creg; /* Pointer to component Region structure */ - int *axes; /* Pointer to array of axis indices */ - int i; /* Loop count */ - int nax1; /* No.of axes in 1st component Frame */ - int nax2; /* No.of axes in 2nd component Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent method to store the FrameSet in the parent Region - structure. */ - (* parent_setregfs)( this_region, frm, status ); - -/* If either component Region has a dummy FrameSet use this method - recursively to give them a FrameSet containing the corresponding axes - from the supplied Frame. */ - creg = ((AstPrism *) this_region )->region1; - if( creg ) { - nax1 = astGetNaxes( creg ); - if( !astGetRegionFS( creg ) ) { - axes = astMalloc( sizeof( int )*(size_t) nax1 ); - if( astOK ) for( i = 0; i < nax1; i++ ) axes[ i ] = i; - cfrm = astPickAxes( frm, nax1, axes, NULL ); - astSetRegFS( creg, cfrm ); - axes = astFree( axes ); - cfrm = astAnnul( cfrm ); - } - - } else { - nax1 = 0; - } - - creg = ((AstPrism *) this_region )->region2; - if( creg && !astGetRegionFS( creg ) ) { - nax2 = astGetNaxes( creg ); - axes = astMalloc( sizeof( int )*(size_t) nax2 ); - if( astOK ) for( i = 0; i < nax2; i++ ) axes[ i ] = nax1 + i; - cfrm = astPickAxes( frm, nax2, axes, NULL ); - astSetRegFS( creg, cfrm ); - axes = astFree( axes ); - cfrm = astAnnul( cfrm ); - } - -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* Prism method (over-rides the astSimplify method inherited from -* the Region class). - -* Description: -* This function simplifies a Prism to eliminate redundant -* computational steps, or to merge separate steps which can be -* performed more efficiently in a single operation. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A new pointer to the (possibly simplified) Region. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. - -* Deficiencies: -* - Currently, this function does not attempt to map the component -* Regions into the current Frame of the parent Region structure. - -*/ - -/* Local Variables: */ - AstFrame *cfrm; /* Current Frame */ - AstFrame *newfrm1; /* Current Frame axes for reg1 */ - AstFrame *newfrm2; /* Current Frame axes for reg2 */ - AstFrameSet *fs; /* Parent FrameSet */ - AstMapping *bcmap; /* Base->current Mapping */ - AstMapping *nmap1; /* Reg1->current Mapping */ - AstMapping *map1; /* First component Region from a CmpMap */ - AstMapping *map2; /* Second component Region from a CmpMap */ - int series; /* Apply component Mappings in series? */ - int invert1; /* Use inverted first component Mapping? */ - int invert2; /* Use inverted second component Mapping? */ - AstMapping *nmap2; /* Reg2->current Mapping */ - AstMapping *result; /* Result pointer to return */ - AstCmpMap *cmpmap; /* Result pointer to return */ - AstMapping *smap; /* Simplified CmpMap */ - AstRegion *new2; /* New simplified Region */ - AstRegion *new; /* New Region */ - AstRegion *newreg1; /* Reg1 mapped into current Frame */ - AstRegion *newreg2; /* Reg2 mapped into current Frame */ - AstRegion *reg1; /* First component Region */ - AstRegion *reg2; /* Second component Region */ - AstRegion *reg; /* This Region */ - AstRegion *snewreg1; /* Simplified newreg1 */ - AstRegion *snewreg2; /* Simplified newreg2 */ - AstRegion *unc; /* Uncertainty Region from supplied Prism */ - int *axin; /* Indices of Mapping inputs to use */ - int *axout1; /* Indices of cfrm axes corresponding to reg1 */ - int *axout2; /* Indices of cfrm axes corresponding to reg2 */ - int *perm; /* Axis permutation array */ - int i; /* Loop count */ - int nax1; /* Number of axes in first component Region */ - int nax2; /* Number of axes in second component Region */ - int naxt; /* Total number of axes in current Frame */ - int naxout1; /* Number of current axes for reg1 */ - int naxout2; /* Number of current axes for reg2 */ - int neg; /* Negated flag for supplied Prism */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Region structure */ - reg = (AstRegion *) this_mapping; - -/* Get the component Regions, and the Negated flag for the Prism. */ - GetRegions( (AstPrism *) this_mapping, ®1, ®2, &neg, status ); - -/* The above Regions describe areas within the base Frame of the FrameSet - encapsulated by the parent Region structure. Get the current Frame in - this FrameSet and the base->current Mapping. */ - fs = reg->frameset; - cfrm = astGetFrame( fs, AST__CURRENT ); - bcmap = astGetMapping( fs, AST__BASE, AST__CURRENT ); - -/* Combine the two Regions into a parallel CmpMap (this uses the fact - that a Region is a type of Mapping). Then simplify the CmpMap. This - will result in the astMapMerge methods defined by sub-classes of - Regions being used to merge adjacent regions. */ - cmpmap = astCmpMap( reg1, reg2, 0, "", status ); - smap = astSimplify( cmpmap ); - cmpmap = astAnnul( cmpmap ); - -/* Initially, assume we cannot form a new Region from the simplified - CmpMap. */ - new = NULL; - -/* If the result is a region, use it. */ - if( astIsARegion( smap ) ) { - new = astClone( smap ); - -/* If the result is a parallel CmpMap, get its two components and check - they are Regions. If so, and if they are not the same as the original - two component Regions, form a new Prism from them. */ - } else if( astIsACmpMap( smap ) ) { - astDecompose( smap, &map1, &map2, &series, &invert1, &invert2 ); - if( ! series && astIsARegion( map1 ) && astIsARegion( map2 ) ) { - if( (AstRegion *) map1 != reg1 || (AstRegion *) map2 != reg2 ) { - new = (AstRegion *) astPrism( (AstRegion *) map1, - (AstRegion *) map2, "", status ); - } - } - -/* Free resources */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - } - - smap = astAnnul( smap ); - -/* If the above produced a simplified Region, map it into the current Frame - of "this" and simplify it. */ - if( new ) { - new2 = astMapRegion( new, bcmap, cfrm ); - (void) astAnnul( new ); - new = astSimplify( new2 ); - new2 = astAnnul( new2 ); - -/* If the above did not produced a result, try a different approach. */ - } else { - -/* Get the number of axes in each component Region. */ - nax1 = astGetNaxes( reg1 ); - nax2 = astGetNaxes( reg2 ); - -/* Use astMapSplit to see if the axes of the first component Region correspond - to a distinct set of axes within the current Frame. If this is the case, - then a Mapping is returned by astMapSplit which maps the axes of the first - component Region into the corresponding current Frame axes. Also returned - is a list of the axes within the current Frame which correspnd to the - axes of the first component Region. */ - nmap1 = NULL; - axout1 = NULL; - axin = astMalloc( sizeof( int )*(size_t)nax1 ); - if( astOK ) { - for( i = 0; i < nax1; i++ ) axin[ i ] = i; - axout1 = astMapSplit( bcmap, nax1, axin, &nmap1 ); - axin = astFree( axin ); - } - -/* Do the same for the second component. */ - nmap2 = NULL; - axout2 = NULL; - axin = astMalloc( sizeof( int )*(size_t)nax2 ); - if( astOK ) { - for( i = 0; i < nax2; i++ ) axin[ i ] = i + nax1; - axout2 = astMapSplit( bcmap, nax2, axin, &nmap2 ); - axin = astFree( axin ); - } - -/* Assume for the moment that the component Regions cannot be simplified. - In this case we will use a clone of the supplied Prism. */ - new = astClone( this_mapping ); - -/* Determine the number of outputs from these Mappings. */ - if( nmap1 ){ - naxout1 = astGetNout( nmap1 ); - } else { - naxout1 = 0; - } - if( nmap2 ){ - naxout2 = astGetNout( nmap2 ); - } else { - naxout2 = 0; - } - -/* Determine the number of axes in the current Frame of the Prism. */ - naxt = astGetNout( bcmap ); - -/* If the second component does not contribute any axes to the total - Prism, we can ignore it. */ - if( naxout1 == naxt && naxout2 == 0 ) { - newfrm1 = astPickAxes( cfrm, naxout1, axout1, NULL ); - newreg1 = astMapRegion( reg1, nmap1, newfrm1 ); - (void) astAnnul( new ); - new = astSimplify( newreg1 ); - if( neg ) astNegate( new ); - perm = astMalloc( sizeof( int )*(size_t) ( naxout1 ) ); - if( astOK ) { - for( i = 0; i < naxout1; i++ ) perm[ i ] = axout1[ i ]; - astPermAxes( new, perm ); - perm = astFree( perm ); - } - newfrm1 = astAnnul( newfrm1 ); - newreg1 = astAnnul( newreg1 ); - -/* If the first component does not contribute any axes to the total - Prism, we can ignore it. */ - } else if( naxout1 == 0 && naxout2 == naxt ) { - newfrm2 = astPickAxes( cfrm, naxout2, axout2, NULL ); - newreg2 = astMapRegion( reg2, nmap2, newfrm2 ); - (void) astAnnul( new ); - new = astSimplify( newreg2 ); - if( neg ) astNegate( new ); - perm = astMalloc( sizeof( int )*(size_t) ( naxout2 ) ); - if( astOK ) { - for( i = 0; i < naxout2; i++ ) perm[ i ] = axout2[ i ]; - astPermAxes( new, perm ); - perm = astFree( perm ); - } - newfrm2 = astAnnul( newfrm2 ); - newreg2 = astAnnul( newreg2 ); - -/* If both component Regions correspond to a distinct subspace within the - current Frame, then we can try to express each component Region within - the current Frame. */ - } else if( nmap1 && nmap2 ) { - -/* Create a Frame representing the subspace of the current Frame which - corresponds to the axes of the first component Region. */ - newfrm1 = astPickAxes( cfrm, naxout1, axout1, NULL ); - -/* Remap the first component Region so that it represents an area in this - subspace. */ - newreg1 = astMapRegion( reg1, nmap1, newfrm1 ); - -/* Attempt to simplify the remapped Region. */ - snewreg1 = astSimplify( newreg1 ); - -/* Do the same for the second component Region. */ - naxout2 = astGetNout( nmap2 ); - newfrm2 = astPickAxes( cfrm, naxout2, axout2, NULL ); - newreg2 = astMapRegion( reg2, nmap2, newfrm2 ); - snewreg2 = astSimplify( newreg2 ); - -/* If either component Region was simplified, create a new Prism from the - simplified Regions. */ - if( snewreg1 != newreg1 || snewreg2 != newreg2 ) { - (void) astAnnul( new ); - new = (AstRegion *) astPrism( snewreg1, snewreg2, "", status ); - -/* Ensure the new Prism has the same Negated attribute as the original. */ - if( neg ) astNegate( new ); - -/* Ensure that the new Prism has the same axis order as the original - current Frame. */ - perm = astMalloc( sizeof( int )*(size_t) ( naxout1 + naxout2 ) ); - if( astOK ) { - for( i = 0; i < naxout1; i++ ) perm[ i ] = axout1[ i ]; - for( ; i < naxout1 + naxout2; i++ ) perm[ i ] = axout2[ i - naxout1 ]; - astPermAxes( new, perm ); - perm = astFree( perm ); - } - } - -/* Free resources. */ - newfrm1 = astAnnul( newfrm1 ); - newfrm2 = astAnnul( newfrm2 ); - newreg1 = astAnnul( newreg1 ); - newreg2 = astAnnul( newreg2 ); - snewreg1 = astAnnul( snewreg1 ); - snewreg2 = astAnnul( snewreg2 ); - } - -/* Free resources. */ - if( axout1 ) axout1 = astFree( axout1 ); - if( axout2 ) axout2 = astFree( axout2 ); - if( nmap1 ) nmap1 = astAnnul( nmap1 ); - if( nmap2 ) nmap2 = astAnnul( nmap2 ); - } - -/* If we have created a new Region, ensure any user-supplied uncertainty - that has been stored explicitly with the supplied Prism is passed on - to the new Region. */ - if( new ) { - if( astTestUnc( reg ) ) { - unc = astGetUnc( reg, 0 ); - astSetUnc( new, unc ); - } - -/* Now invoke the parent Simplify method inherited from the Region class. - This will simplify the encapsulated FrameSet and uncertainty Region. */ - result = (*parent_simplify)( (AstMapping *) new, status ); - new = astAnnul( new ); - } - -/* Free resources. */ - reg1 = astAnnul( reg1 ); - reg2 = astAnnul( reg2 ); - cfrm = astAnnul( cfrm ); - bcmap = astAnnul( bcmap ); - -/* If any simplification could be performed, copy Region attributes from - the supplied Region to the returned Region, and return a pointer to it. */ - if( result != this_mapping ) astRegOverlay( result, (AstRegion *) this_mapping, 0 ); - -/* If an error occurred, annul the returned Mapping. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a Prism to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "prism.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* Prism member function (over-rides the astTransform method inherited -* from the Region class). - -* Description: -* This function takes a Prism and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required Region. -* This implies applying each of the Prism's component Regions in turn, -* either in series or in parallel. - -* Parameters: -* this -* Pointer to the Prism. -* in -* Pointer to the PointSet associated with the input coordinate values. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the Prism being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstCmpMap *map; /* CmpMap containing component Regions */ - AstPointSet *psb; /* Pointer to base Frame PointSet */ - AstPointSet *pset_tmp; /* Pointer to PointSet holding base Frame positions*/ - AstPointSet *result; /* Pointer to output PointSet */ - AstPrism *this; /* Pointer to the Prism structure */ - AstRegion *reg1; /* Pointer to first component Region */ - AstRegion *reg2; /* Pointer to second component Region */ - double **ptr_out; /* Pointer to output coordinate data */ - double **ptrb; /* Pointer to base Frame axis values */ - int coord; /* Zero-based index for coordinates */ - int good; /* Is the point inside the Prism? */ - int ncoord_out; /* No. of coordinates per output point */ - int ncoord_tmp; /* No. of coordinates per base Frame point */ - int neg; /* Has Prism been negated? */ - int npoint; /* No. of points */ - int point; /* Loop counter for points */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a Pointer to the Prism structure */ - this = (AstPrism *) this_mapping; - -/* Get the component Regions, and the Negated value for the Prism. */ - GetRegions( this, ®1, ®2, &neg, status ); - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, containing - a copy of the input PointSet. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* First use the encapsulated FrameSet in the parent Region structure to - transform the supplied positions from the current Frame in the - encapsulated FrameSet (the Frame represented by the Prism), to the - base Frame (the Frame in which the component Regions are defined). Note, - the returned pointer may be a clone of the "in" pointer, and so we - must be carefull not to modify the contents of the returned PointSet. */ - pset_tmp = astRegTransform( this, in, 0, NULL, NULL ); - -/* Form a parallel CmpMap from the two component Regions. */ - map = astCmpMap( reg1, reg2, 0, "", status ); - -/* Apply the Mapping to the PointSet containing positions in the base Frame - of the parent Region structure (which is the same as the combination of - the current Frames of the component Regions). */ - psb = astTransform( map, pset_tmp, 1, NULL ); - -/* Annul the Mapping pointer. */ - map = astAnnul( map ); - -/* Determine the numbers of points and coordinates per point for these base - Frame PointSets and obtain pointers for accessing the base Frame and output - coordinate values. */ - npoint = astGetNpoint( pset_tmp ); - ncoord_tmp = astGetNcoord( pset_tmp ); - ptrb = astGetPoints( psb ); - ncoord_out = astGetNcoord( result ); - ptr_out = astGetPoints( result ); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - for ( point = 0; point < npoint; point++ ) { - good = 1; - - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - if( ptrb[ coord ][ point ] == AST__BAD ){ - good = 0; - break; - } - } - - if( good == neg ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - } - -/* Free resources. */ - reg1 = astAnnul( reg1 ); - reg2 = astAnnul( reg2 ); - psb = astAnnul( psb ); - pset_tmp = astAnnul( pset_tmp ); - -/* If an error occurred, clean up by deleting the output PointSet (if - allocated by this function) and setting a NULL result pointer. */ - if ( !astOK ) { - if ( !out ) result = astDelete( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Prism objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Prism objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Regions within the Prism. -*/ - -/* Local Variables: */ - AstPrism *in; /* Pointer to input Prism */ - AstPrism *out; /* Pointer to output Prism */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Prisms. */ - in = (AstPrism *) objin; - out = (AstPrism *) objout; - -/* For safety, start by clearing any references to the input component - Regions from the output Prism. */ - out->region1 = NULL; - out->region2 = NULL; - -/* Make copies of these Regions and store pointers to them in the output - Prism structure. */ - out->region1 = astCopy( in->region1 ); - out->region2 = astCopy( in->region2 ); -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Prism objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Prism objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to Prism */ - -/* Obtain a pointer to the Prism structure. */ - this = (AstPrism *) obj; - -/* Annul the pointers to the component Regions. */ - this->region1 = astAnnul( this->region1 ); - this->region2 = astAnnul( this->region2 ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Prism objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Prism class to an output Channel. - -* Parameters: -* this -* Pointer to the Prism whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPrism *this; /* Pointer to the Prism structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Prism structure. */ - this = (AstPrism *) this_object; - -/* Write out values representing the instance variables for the Prism - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* First Region. */ -/* -------------- */ - astWriteObject( channel, "RegionA", 1, 1, this->region1, - "First component Region" ); - -/* Second Region. */ -/* --------------- */ - astWriteObject( channel, "RegionB", 1, 1, this->region2, - "Second component Region" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPrism and astCheckPrism functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Prism,Region) -astMAKE_CHECK(Prism) - -AstPrism *astPrism_( void *region1_void, void *region2_void, - const char *options, int *status, ...) { -/* -*+ -* Name: -* astPrism - -* Purpose: -* Create a Prism. - -* Type: -* Protected function. - -* Synopsis: -* #include "prism.h" -* AstPrism *astPrism( AstRegion *region1, AstRegion *region2, -* const char *options, ..., int *status ) - -* Class Membership: -* Prism constructor. - -* Description: -* This function creates a new Prism and optionally initialises its -* attributes. - -* Parameters: -* region1 -* Pointer to the Region to be extruded. -* region2 -* Pointer to the Region defining the extent of the extrusion. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new Prism. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new Prism. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic Prism constructor which is -* available via the protected interface to the Prism class. A -* public interface is provided by the astPrismId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "region1" and "region2" parameters are of type (void *) and are -* converted and validated within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPrism *new; /* Pointer to new Prism */ - AstRegion *region1; /* Pointer to first Region structure */ - AstRegion *region2; /* Pointer to second Region structure */ - va_list args; /* Variable argument list */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain and validate pointers to the Region structures provided. */ - region1 = astCheckRegion( region1_void ); - region2 = astCheckRegion( region2_void ); - if ( astOK ) { - -/* Initialise the Prism, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPrism( NULL, sizeof( AstPrism ), !class_init, - &class_vtab, "Prism", region1, region2 ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new Prism's - attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new Prism. */ - return new; -} - -AstPrism *astPrismId_( void *region1_void, void *region2_void, - const char *options, ... ) { -/* -*++ -* Name: -c astPrism -f AST_PRISM - -* Purpose: -* Create a Prism. - -* Type: -* Public function. - -* Synopsis: -c #include "prism.h" -c AstPrism *astPrism( AstRegion *region1, AstRegion *region2, -c const char *options, ... ) -f RESULT = AST_PRISM( REGION1, REGION2, OPTIONS, STATUS ) - -* Class Membership: -* Prism constructor. - -* Description: -* This function creates a new Prism and optionally initialises -* its attributes. -* -* A Prism is a Region which represents an extrusion of an existing Region -* into one or more orthogonal dimensions (specified by another Region). -* If the Region to be extruded has N axes, and the Region defining the -* extrusion has M axes, then the resulting Prism will have (M+N) axes. -* A point is inside the Prism if the first N axis values correspond to -* a point inside the Region being extruded, and the remaining M axis -* values correspond to a point inside the Region defining the extrusion. -* -* As an example, a cylinder can be represented by extruding an existing -* Circle, using an Interval to define the extrusion. Ih this case, the -* Interval would have a single axis and would specify the upper and -* lower limits of the cylinder along its length. - -* Parameters: -c region1 -f REGION1 = INTEGER (Given) -* Pointer to the Region to be extruded. -c region2 -f REGION2 = INTEGER (Given) -* Pointer to the Region defining the extent of the extrusion. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Prism. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Prism. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPrism() -f AST_PRISM = INTEGER -* A pointer to the new Prism. - -* Notes: -* - Deep copies are taken of the supplied Regions. This means that -* any subsequent changes made to the component Regions using the -* supplied pointers will have no effect on the Prism. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astPrism constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astPrism_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "region1" and "region2" parameters -* are of type (void *) and are converted from an ID value to a -* pointer and validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astPrism_ directly, so it must be a re-implementation -* of it in all respects, except for the conversions between IDs -* and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPrism *new; /* Pointer to new Prism */ - AstRegion *region1; /* Pointer to first Region structure */ - AstRegion *region2; /* Pointer to second Region structure */ - int *status; /* Pointer to inherited status value */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain the Region pointers from the ID's supplied and validate the - pointers to ensure they identify valid Regions. */ - region1 = astVerifyRegion( astMakePointer( region1_void ) ); - region2 = astVerifyRegion( astMakePointer( region2_void ) ); - if ( astOK ) { - -/* Initialise the Prism, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPrism( NULL, sizeof( AstPrism ), !class_init, - &class_vtab, "Prism", region1, region2 ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new Prism's - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new Prism. */ - return astMakeId( new ); -} - -AstPrism *astInitPrism_( void *mem, size_t size, int init, AstPrismVtab *vtab, - const char *name, AstRegion *region1, - AstRegion *region2, int *status ) { -/* -*+ -* Name: -* astInitPrism - -* Purpose: -* Initialise a Prism. - -* Type: -* Protected function. - -* Synopsis: -* #include "prism.h" -* AstPrism *astInitPrism_( void *mem, size_t size, int init, -* AstPrismVtab *vtab, const char *name, -* AstRegion *region1, AstRegion *region2 ) - -* Class Membership: -* Prism initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Prism object. It allocates memory (if necessary) to -* accommodate the Prism plus any additional data associated with the -* derived class. It then initialises a Prism structure at the start -* of this memory. If the "init" flag is set, it also initialises the -* contents of a virtual function table for a Prism at the start of -* the memory passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Prism is to be initialised. -* This must be of sufficient size to accommodate the Prism data -* (sizeof(Prism)) plus any data used by the derived class. If a -* value of NULL is given, this function will allocate the memory itself -* using the "size" parameter to determine its size. -* size -* The amount of memory used by the Prism (plus derived class -* data). This will be used to allocate memory if a value of NULL is -* given for the "mem" parameter. This value is also stored in the -* Prism structure, so a valid value must be supplied even if not -* required for allocating memory. -* init -* A logical flag indicating if the Prism's virtual function table -* is to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Prism. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* region1 -* Pointer to the first Region. -* region2 -* Pointer to the second Region. - -* Returned Value: -* A pointer to the new Prism. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstPrism *new; /* Pointer to new Prism */ - AstFrame *frm1; /* Frame encapsulated by 1st Region */ - AstFrame *frm2; /* Frame encapsulated by 2nd Region */ - AstFrame *frm; /* CmpFrame formed from frm1 and frm2 */ - AstMapping *map; /* Mapping between two supplied Regions */ - AstRegion *reg1; /* Copy of first supplied Region */ - AstRegion *reg2; /* Copy of second supplied Region */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitPrismVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - reg2 = NULL; - -/* Take a copy of the two supplied Regions. */ - reg1 = astCopy( region1 ); - reg2 = astCopy( region2 ); - -/* Form a CmpFrame representing the combined Frame of these two Regions. */ - frm1 = astRegFrame( reg1 ); - frm2 = astRegFrame( reg2 ); - frm = (AstFrame *) astCmpFrame( frm1, frm2, "", status ); - -/* Initialise a Region structure (the parent class) as the first component - within the Prism structure, allocating memory if necessary. A NULL - PointSet is suppled as the two component Regions will perform the function - of defining the Region shape. The base Frame of the FrameSet in the - parent Region structure will be the CmpFrame formed from the two component - Regions. */ - if ( astOK ) { - new = (AstPrism *) astInitRegion( mem, size, 0, (AstRegionVtab *) vtab, - name, frm, NULL, NULL ); - -/* Initialise the Prism data. */ -/* --------------------------- */ -/* Store pointers to the component Regions. */ - new->region1 = reg1; - new->region2 = reg2; - -/* If the base->current Mapping in the FrameSet within a component Region - is a UnitMap, then the FrameSet does not need to be included in the - Dump of the new Prism. Set the RegionFS attribute of the component - Region to zero to flag this. */ - map = astGetMapping( reg1->frameset, AST__BASE, AST__CURRENT ); - if( astIsAUnitMap( map ) ) astSetRegionFS( reg1, 0 ); - map = astAnnul( map ); - - map = astGetMapping( reg2->frameset, AST__BASE, AST__CURRENT ); - if( astIsAUnitMap( map ) ) astSetRegionFS( reg2, 0 ); - map = astAnnul( map ); - -/* If an error occurred, clean up by annulling the Region pointers and - deleting the new object. */ - if ( !astOK ) { - new->region1 = astAnnul( new->region1 ); - new->region2 = astAnnul( new->region2 ); - new = astDelete( new ); - } - } - -/* Free resources */ - frm = astAnnul( frm ); - frm1 = astAnnul( frm1 ); - frm2 = astAnnul( frm2 ); - -/* Return a pointer to the new object. */ - return new; -} - -AstPrism *astLoadPrism_( void *mem, size_t size, AstPrismVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPrism - -* Purpose: -* Load a Prism. - -* Type: -* Protected function. - -* Synopsis: -* #include "prism.h" -* AstPrism *astLoadPrism( void *mem, size_t size, AstPrismVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* Prism loader. - -* Description: -* This function is provided to load a new Prism using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Prism structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Prism at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the Prism is to be -* loaded. This must be of sufficient size to accommodate the -* Prism data (sizeof(Prism)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Prism (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Prism structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPrism) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Prism. If this is NULL, a pointer to -* the (static) virtual function table for the Prism class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Prism" is used instead. - -* Returned Value: -* A pointer to the new Prism. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *cfrm; /* Frame containing required axes */ - AstFrame *f1; /* Base Frame in parent Region */ - AstPrism *new; /* Pointer to the new Prism */ - AstRegion *creg; /* Pointer to component Region */ - int *axes; /* Pointer to array of axis indices */ - int i; /* Loop count */ - int nax1; /* No.of axes in 1st component Frame */ - int nax2; /* No.of axes in 2nd component Frame */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Prism. In this case the - Prism belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPrism ); - vtab = &class_vtab; - name = "Prism"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPrismVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Prism. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Prism" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* First Region. */ -/* -------------- */ - new->region1 = astReadObject( channel, "regiona", NULL ); - -/* Second Region. */ -/* --------------- */ - new->region2 = astReadObject( channel, "regionb", NULL ); - -/* Either component Region may currently contain a dummy FrameSet rather than - the correct FrameSet (see the Dump function for this class). In this case, - the correct FrameSet will have copies of selected axes from the base Frame - of the new Prism as both its current and base Frames, and these are - connected by a UnitMap (this is equivalent to a FrameSet containing a - single Frame). However if the new Prism being loaded has itself got a dummy - FrameSet, then we do not do this since we do not yet know what the correct - FrameSet is. In this case we wait until the parent Region invokes the - astSetRegFS method on the new Prism. */ - if( !astRegDummyFS( new ) ) { - f1 = astGetFrame( ((AstRegion *) new)->frameset, AST__BASE ); - - creg = new->region1; - nax1 = astGetNaxes( creg ); - if( astRegDummyFS( creg ) ) { - axes = astMalloc( sizeof( int )*(size_t) nax1 ); - if( astOK ) for( i = 0; i < nax1; i++ ) axes[ i ] = i; - cfrm = astPickAxes( f1, nax1, axes, NULL ); - astSetRegFS( creg, cfrm ); - axes = astFree( axes ); - cfrm = astAnnul( cfrm ); - } - - creg = new->region2; - if( astRegDummyFS( creg ) ) { - nax2 = astGetNaxes( creg ); - axes = astMalloc( sizeof( int )*(size_t) nax2 ); - if( astOK ) for( i = 0; i < nax2; i++ ) axes[ i ] = nax1 + i; - cfrm = astPickAxes( f1, nax2, axes, NULL ); - astSetRegFS( creg, cfrm ); - axes = astFree( axes ); - cfrm = astAnnul( cfrm ); - } - - f1 = astAnnul( f1 ); - } - -/* If an error occurred, clean up by deleting the new Prism. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Prism pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -/* None. */ - - - diff --git a/ast/prism.h b/ast/prism.h deleted file mode 100644 index ab14c77..0000000 --- a/ast/prism.h +++ /dev/null @@ -1,238 +0,0 @@ -#if !defined( PRISM_INCLUDED ) /* Include this file only once */ -#define PRISM_INCLUDED -/* -*+ -* Name: -* prism.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Prism class. - -* Invocation: -* #include "prism.h" - -* Description: -* This include file defines the interface to the Prism class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The Prism class implement a Region which represents an extrusion of -* another Region into higher dimensions. For instance, a Prism can be -* used to represent a cylinder, which is an extrusion of a circle into a -* 3rd dimension. - -* Inheritance: -* The Prism class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 17-DEC-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "region.h" /* Coordinate regions (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros. */ -/* ------- */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* Prism structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -typedef struct AstPrism { - -/* Attributes inherited from the parent class. */ - AstRegion region; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstRegion *region1; /* First component Region */ - AstRegion *region2; /* Second component Region */ - -} AstPrism; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstPrismVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -} AstPrismVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstPrismGlobals { - AstPrismVtab Class_Vtab; - int Class_Init; -} AstPrismGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitPrismGlobals_( AstPrismGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Prism) /* Check class membership */ -astPROTO_ISA(Prism) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstPrism *astPrism_( void *, void *, const char *, int *, ...); -#else -AstPrism *astPrismId_( void *, void *, const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstPrism *astInitPrism_( void *, size_t, int, AstPrismVtab *, - const char *, AstRegion *, AstRegion *, int * ); - -/* Vtab initialiser. */ -void astInitPrismVtab_( AstPrismVtab *, const char *, int * ); - -/* Loader. */ -AstPrism *astLoadPrism_( void *, size_t, AstPrismVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -AstRegion *astConvertToPrism_( AstRegion *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckPrism(this) astINVOKE_CHECK(Prism,this,0) -#define astVerifyPrism(this) astINVOKE_CHECK(Prism,this,1) - -/* Test class membership. */ -#define astIsAPrism(this) astINVOKE_ISA(Prism,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astPrism astINVOKE(F,astPrism_) -#else -#define astPrism astINVOKE(F,astPrismId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitPrism(mem,size,init,vtab,name,reg1,reg2) \ -astINVOKE(O,astInitPrism_(mem,size,init,vtab,name,reg1,reg2,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitPrismVtab(vtab,name) astINVOKE(V,astInitPrismVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadPrism(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadPrism_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckPrism to validate Prism pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astConvertToPrism(this) astConvertToPrism_(this,STATUS_PTR) -#endif -#endif - - - - - diff --git a/ast/proj.c b/ast/proj.c deleted file mode 100644 index 8b92c21..0000000 --- a/ast/proj.c +++ /dev/null @@ -1,4840 +0,0 @@ -/*============================================================================ -* -* WCSLIB - an implementation of the FITS WCS proposal. -* Copyright (C) 1995-2002, Mark Calabretta -* -* This library is free software; you can redistribute it and/or modify it -* under the terms of the GNU Library General Public License as published -* by the Free Software Foundation; either version 2 of the License, or (at -* your option) any later version. -* -* This library is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library -* General Public License for more details. -* -* You should have received a copy of the GNU Library General Public License -* along with this library; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street,Fifth Floor, Boston, MA 02110-1301, USA -* -* Correspondence concerning WCSLIB may be directed to: -* Internet email: mcalabre@atnf.csiro.au -* Postal address: Dr. Mark Calabretta, -* Australia Telescope National Facility, -* P.O. Box 76, -* Epping, NSW, 2121, -* AUSTRALIA -* -* -*============================================================================= -* -* This version of proj.c is based on the version in wcslib-2.9, but has -* been modified in the following ways by the Starlink project (e-mail: -* ussc@star.rl.ac.uk): -* - The copysign macro is now always defined within this file -* instead of only being defined if the COPYSIGN macro has previously -* been defined. -* - Sine values which are slightly larger than 1.0 are now treated -* as 1.0 in function astCYPrev. -* - The maximum number of projection parameters has been changed from -* 10 to 100. -* - The maximum number of projection parameters is given by the -* WCSLIB_MXPAR macro (defined in proj.h) instead of being hard-wired. -* - The names of all functions and structures have been chanegd to avoid -* clashes with wcslib. This involves adding "Ast" or "ast" at the -* front and changing the capitalisation. -* - Include string.h (for strcpy and strcmp prototypes). -* - Include stdlib.h (for abs prototype). -* - Comment out declarations of npcode and pcodes variables (they -* are not needed by AST) in order to avoid clash with similar names -* in other modules imported as part of other software systems (e.g. -* SkyCat). -* - astZPNfwd: Loop from prj->n to zero, not from MAXPAR to zero. -* - astZPNfwd: Only return "2" if prj->n is larger than 2. -* - Lots of variables are initialised to null values in order to -* avoid "use of uninitialised variable" messages from compilers which -* are not clever enough to work out that the uninitialised variable is -* not in fact ever used. -* - Use dynamic rather than static memory for the parameter arrays in -* the AstPrjPrm structure.Override astGetObjSize. This is to -* reduce the in-memory size of a WcsMap. -* - HPX and XPH projections included from a more recent version of WCSLIB, -* and modified to use scalar instead of vector positions -* - The expressions for xc in astHPXrev and phic in astHPXfwd have -* been conditioned differently to the WCSLIB code in order to improve -* accuracy of the floor function for arguments very slightly below an -* integer value. - -*============================================================================= -* -* C implementation of the spherical map projections recognized by the FITS -* "World Coordinate System" (WCS) convention. -* -* Summary of routines -* ------------------- -* Each projection is implemented via separate functions for the forward, -* *fwd(), and reverse, *rev(), transformation. -* -* Initialization routines, *set(), compute intermediate values from the -* projection parameters but need not be called explicitly - see the -* explanation of prj.flag below. -* -* astPRJset astPRJfwd astPRJrev Driver routines (see below). -* -* astAZPset astAZPfwd astAZPrev AZP: zenithal/azimuthal perspective -* astSZPset astSZPfwd astSZPrev SZP: slant zenithal perspective -* astTANset astTANfwd astTANrev TAN: gnomonic -* astSTGset astSTGfwd astSTGrev STG: stereographic -* astSINset astSINfwd astSINrev SIN: orthographic/synthesis -* astARCset astARCfwd astARCrev ARC: zenithal/azimuthal equidistant -* astZPNset astZPNfwd astZPNrev ZPN: zenithal/azimuthal polynomial -* astZEAset astZEAfwd astZEArev ZEA: zenithal/azimuthal equal area -* astAIRset astAIRfwd astAIRrev AIR: Airy -* astCYPset astCYPfwd astCYPrev CYP: cylindrical perspective -* astCEAset astCEAfwd astCEArev CEA: cylindrical equal area -* astCARset astCARfwd astCARrev CAR: Cartesian -* astMERset astMERfwd astMERrev MER: Mercator -* astSFLset astSFLfwd astSFLrev SFL: Sanson-Flamsteed -* astPARset astPARfwd astPARrev PAR: parabolic -* astMOLset astMOLfwd astMOLrev MOL: Mollweide -* astAITset astAITfwd astAITrev AIT: Hammer-Aitoff -* astCOPset astCOPfwd astCOPrev COP: conic perspective -* astCOEset astCOEfwd astCOErev COE: conic equal area -* astCODset astCODfwd astCODrev COD: conic equidistant -* astCOOset astCOOfwd astCOOrev COO: conic orthomorphic -* astBONset astBONfwd astBONrev BON: Bonne -* astPCOset astPCOfwd astPCOrev PCO: polyconic -* astTSCset astTSCfwd astTSCrev TSC: tangential spherical cube -* astCSCset astCSCfwd astCSCrev CSC: COBE quadrilateralized spherical cube -* astQSCset astQSCfwd astQSCrev QSC: quadrilateralized spherical cube -* astHPXset astHPXfwd astHPXrev HPX: HEALPix projection -* astXPHset astXPHfwd astXPHrev XPH: HEALPix polar, aka "butterfly" -* -* -* Driver routines; astPRJset(), astPRJfwd() & astPRJrev() -* ---------------------------------------------- -* A set of driver routines are available for use as a generic interface to -* the specific projection routines. The interfaces to astPRJfwd() and astPRJrev() -* are the same as those of the forward and reverse transformation routines -* for the specific projections (see below). -* -* The interface to astPRJset() differs slightly from that of the initialization -* routines for the specific projections and unlike them it must be invoked -* explicitly to use astPRJfwd() and astPRJrev(). -* -* Given: -* pcode[4] const char -* WCS projection code. -* -* Given and/or returned: -* prj AstPrjPrm* Projection parameters (see below). -* -* Function return value: -* int Error status -* 0: Success. -* -* -* Initialization routine; *set() -* ------------------------------ -* Initializes members of a AstPrjPrm data structure which hold intermediate -* values. Note that this routine need not be called directly; it will be -* invoked by astPRJfwd() and astPRJrev() if the "flag" structure member is -* anything other than a predefined magic value. -* -* Given and/or returned: -* prj AstPrjPrm* Projection parameters (see below). -* -* Function return value: -* int Error status -* 0: Success. -* 1: Invalid projection parameters. -* -* Forward transformation; *fwd() -* ----------------------------- -* Compute (x,y) coordinates in the plane of projection from native spherical -* coordinates (phi,theta). -* -* Given: -* phi, const double -* theta Longitude and latitude of the projected point in -* native spherical coordinates, in degrees. -* -* Given and returned: -* prj AstPrjPrm* Projection parameters (see below). -* -* Returned: -* x,y double* Projected coordinates. -* -* Function return value: -* int Error status -* 0: Success. -* 1: Invalid projection parameters. -* 2: Invalid value of (phi,theta). -* -* Reverse transformation; *rev() -* ----------------------------- -* Compute native spherical coordinates (phi,theta) from (x,y) coordinates in -* the plane of projection. -* -* Given: -* x,y const double -* Projected coordinates. -* -* Given and returned: -* prj AstPrjPrm* Projection parameters (see below). -* -* Returned: -* phi, double* Longitude and latitude of the projected point in -* theta native spherical coordinates, in degrees. -* -* Function return value: -* int Error status -* 0: Success. -* 1: Invalid projection parameters. -* 2: Invalid value of (x,y). -* 1: Invalid projection parameters. -* -* Projection parameters -* --------------------- -* The AstPrjPrm struct consists of the following: -* -* int flag -* This flag must be set to zero whenever any of p[] or r0 are set -* or changed. This signals the initialization routine to recompute -* intermediaries. flag may also be set to -1 to disable strict bounds -* checking for the AZP, SZP, TAN, SIN, ZPN, and COP projections. -* -* double r0 -* r0; The radius of the generating sphere for the projection, a linear -* scaling parameter. If this is zero, it will be reset to the default -* value of 180/pi (the value for FITS WCS). -* -* double p[] -* Contains the projection parameters associated with the -* longitude axis. -* -* The remaining members of the AstPrjPrm struct are maintained by the -* initialization routines and should not be modified. This is done for the -* sake of efficiency and to allow an arbitrary number of contexts to be -* maintained simultaneously. -* -* char code[4] -* Three-letter projection code. -* -* double phi0, theta0 -* Native longitude and latitude of the reference point, in degrees. -* -* double w[10] -* int n -* Intermediate values derived from the projection parameters. -* -* int (*astPRJfwd)() -* int (*astPRJrev)() -* Pointers to the forward and reverse projection routines. -* -* Usage of the p[] array as it applies to each projection is described in -* the prologue to each trio of projection routines. -* -* Argument checking -* ----------------- -* Forward routines: -* -* The values of phi and theta (the native longitude and latitude) -* normally lie in the range [-180,180] for phi, and [-90,90] for theta. -* However, all forward projections will accept any value of phi and will -* not normalize it. -* -* The forward projection routines do not explicitly check that theta lies -* within the range [-90,90]. They do check for any value of theta which -* produces an invalid argument to the projection equations (e.g. leading -* to division by zero). The forward routines for AZP, SZP, TAN, SIN, -* ZPN, and COP also return error 2 if (phi,theta) corresponds to the -* overlapped (far) side of the projection but also return the -* corresponding value of (x,y). This strict bounds checking may be -* relaxed by setting prj->flag to -1 (rather than 0) when these -* projections are initialized. -* -* Reverse routines: -* -* Error checking on the projected coordinates (x,y) is limited to that -* required to ascertain whether a solution exists. Where a solution does -* exist no check is made that the value of phi and theta obtained lie -* within the ranges [-180,180] for phi, and [-90,90] for theta. -* -* Accuracy -* -------- -* Closure to a precision of at least 1E-10 degree of longitude and latitude -* has been verified for typical projection parameters on the 1 degree grid -* of native longitude and latitude (to within 5 degrees of any latitude -* where the projection may diverge). -* -* Author: Mark Calabretta, Australia Telescope National Facility -* $Id$ -*===========================================================================*/ - -/* Set the name of the module we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. NB, this module is not a proper AST - class, but it defines this macro sanyway in order to get the protected - symbols defined in memory.h */ - -#include -#include -#include -#include "wcsmath.h" -#include "wcstrig.h" -#include "memory.h" -#include "proj.h" - -/* Following variables are not needed in AST and are commented out to - avoid name clashes with other software systems (e.g. SkyCat) which - defines them. - -int npcode = 28; -char pcodes[28][4] = - {"AZP", "SZP", "TAN", "STG", "SIN", "ARC", "ZPN", "ZEA", "AIR", "CYP", - "CEA", "CAR", "MER", "COP", "COE", "COD", "COO", "SFL", "PAR", "MOL", - "AIT", "BON", "PCO", "TSC", "CSC", "QSC", "HPX", "XPH"}; -*/ - -const int WCS__AZP = 101; -const int WCS__SZP = 102; -const int WCS__TAN = 103; -const int WCS__STG = 104; -const int WCS__SIN = 105; -const int WCS__ARC = 106; -const int WCS__ZPN = 107; -const int WCS__ZEA = 108; -const int WCS__AIR = 109; -const int WCS__CYP = 201; -const int WCS__CEA = 202; -const int WCS__CAR = 203; -const int WCS__MER = 204; -const int WCS__SFL = 301; -const int WCS__PAR = 302; -const int WCS__MOL = 303; -const int WCS__AIT = 401; -const int WCS__COP = 501; -const int WCS__COE = 502; -const int WCS__COD = 503; -const int WCS__COO = 504; -const int WCS__BON = 601; -const int WCS__PCO = 602; -const int WCS__TSC = 701; -const int WCS__CSC = 702; -const int WCS__QSC = 703; -const int WCS__HPX = 801; -const int WCS__XPH = 802; - -/* Map error number to error message for each function. */ -const char *astPRJset_errmsg[] = { - 0, - "Invalid projection parameters"}; - -const char *astPRJfwd_errmsg[] = { - 0, - "Invalid projection parameters", - "Invalid value of (phi,theta)"}; - -const char *astPRJrev_errmsg[] = { - 0, - "Invalid projection parameters", - "Invalid value of (x,y)"}; - - -#define copysign(X, Y) ((Y) < 0.0 ? -fabs(X) : fabs(X)) -#define icopysign(X, Y) ((Y) < 0.0 ? -abs(X) : abs(X)) - - - -/*==========================================================================*/ - -int astPRJset(pcode, prj) - -const char pcode[4]; -struct AstPrjPrm *prj; - -{ - /* Set pointers to the forward and reverse projection routines. */ - if (strcmp(pcode, "AZP") == 0) { - astAZPset(prj); - } else if (strcmp(pcode, "SZP") == 0) { - astSZPset(prj); - } else if (strcmp(pcode, "TAN") == 0) { - astTANset(prj); - } else if (strcmp(pcode, "STG") == 0) { - astSTGset(prj); - } else if (strcmp(pcode, "SIN") == 0) { - astSINset(prj); - } else if (strcmp(pcode, "ARC") == 0) { - astARCset(prj); - } else if (strcmp(pcode, "ZPN") == 0) { - astZPNset(prj); - } else if (strcmp(pcode, "ZEA") == 0) { - astZEAset(prj); - } else if (strcmp(pcode, "AIR") == 0) { - astAIRset(prj); - } else if (strcmp(pcode, "CYP") == 0) { - astCYPset(prj); - } else if (strcmp(pcode, "CEA") == 0) { - astCEAset(prj); - } else if (strcmp(pcode, "CAR") == 0) { - astCARset(prj); - } else if (strcmp(pcode, "MER") == 0) { - astMERset(prj); - } else if (strcmp(pcode, "SFL") == 0) { - astSFLset(prj); - } else if (strcmp(pcode, "PAR") == 0) { - astPARset(prj); - } else if (strcmp(pcode, "MOL") == 0) { - astMOLset(prj); - } else if (strcmp(pcode, "AIT") == 0) { - astAITset(prj); - } else if (strcmp(pcode, "COP") == 0) { - astCOPset(prj); - } else if (strcmp(pcode, "COE") == 0) { - astCOEset(prj); - } else if (strcmp(pcode, "COD") == 0) { - astCODset(prj); - } else if (strcmp(pcode, "COO") == 0) { - astCOOset(prj); - } else if (strcmp(pcode, "BON") == 0) { - astBONset(prj); - } else if (strcmp(pcode, "PCO") == 0) { - astPCOset(prj); - } else if (strcmp(pcode, "TSC") == 0) { - astTSCset(prj); - } else if (strcmp(pcode, "CSC") == 0) { - astCSCset(prj); - } else if (strcmp(pcode, "QSC") == 0) { - astQSCset(prj); - } else if (strcmp(pcode, "HPX") == 0) { - astHPXset(prj); - } else if (strcmp(pcode, "XPH") == 0) { - astXPHset(prj); - } else { - /* Unrecognized projection code. */ - return 1; - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astPRJfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - return prj->astPRJfwd(phi, theta, prj, x, y); -} - -/*--------------------------------------------------------------------------*/ - -int astPRJrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - return prj->astPRJrev(x, y, prj, phi, theta); -} - -/*============================================================================ -* AZP: zenithal/azimuthal perspective projection. -* -* Given: -* prj->p[1] Distance parameter, mu in units of r0. -* prj->p[2] Tilt angle, gamma in degrees. -* -* Given and/or returned: -* prj->flag AZP, or -AZP if prj->flag is given < 0. -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "AZP" -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->w[0] r0*(mu+1) -* prj->w[1] tan(gamma) -* prj->w[2] sec(gamma) -* prj->w[3] cos(gamma) -* prj->w[4] sin(gamma) -* prj->w[5] asin(-1/mu) for |mu| >= 1, -90 otherwise -* prj->w[6] mu*cos(gamma) -* prj->w[7] 1 if |mu*cos(gamma)| < 1, 0 otherwise -* prj->astPRJfwd Pointer to astAZPfwd(). -* prj->astPRJrev Pointer to astAZPrev(). -*===========================================================================*/ - -int astAZPset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "AZP"); - prj->flag = icopysign(WCS__AZP, prj->flag); - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - prj->w[0] = prj->r0*(prj->p[1] + 1.0); - if (prj->w[0] == 0.0) { - return 1; - } - - prj->w[3] = astCosd(prj->p[2]); - if (prj->w[3] == 0.0) { - return 1; - } - - prj->w[2] = 1.0/prj->w[3]; - prj->w[4] = astSind(prj->p[2]); - prj->w[1] = prj->w[4] / prj->w[3]; - - if (fabs(prj->p[1]) > 1.0) { - prj->w[5] = astASind(-1.0/prj->p[1]); - } else { - prj->w[5] = -90.0; - } - - prj->w[6] = prj->p[1] * prj->w[3]; - prj->w[7] = (fabs(prj->w[6]) < 1.0) ? 1.0 : 0.0; - - prj->astPRJfwd = astAZPfwd; - prj->astPRJrev = astAZPrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astAZPfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double a, b, cphi, cthe, r, s, t; - - if (abs(prj->flag) != WCS__AZP) { - if (astAZPset(prj)) return 1; - } - - cphi = astCosd(phi); - cthe = astCosd(theta); - - s = prj->w[1]*cphi; - t = (prj->p[1] + astSind(theta)) + cthe*s; - if (t == 0.0) { - return 2; - } - - r = prj->w[0]*cthe/t; - *x = r*astSind(phi); - *y = -r*cphi*prj->w[2]; - - /* Bounds checking. */ - if (prj->flag > 0) { - /* Overlap. */ - if (theta < prj->w[5]) { - return 2; - } - - /* Divergence. */ - if (prj->w[7] > 0.0) { - t = prj->p[1] / sqrt(1.0 + s*s); - - if (fabs(t) <= 1.0) { - s = astATand(-s); - t = astASind(t); - a = s - t; - b = s + t + 180.0; - - if (a > 90.0) a -= 360.0; - if (b > 90.0) b -= 360.0; - - if (theta < ((a > b) ? a : b)) { - return 2; - } - } - } - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astAZPrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double a, b, r, s, t, ycosg; - const double tol = 1.0e-13; - - if (abs(prj->flag) != WCS__AZP) { - if (astAZPset(prj)) return 1; - } - - ycosg = y*prj->w[3]; - - r = sqrt(x*x + ycosg*ycosg); - if (r == 0.0) { - *phi = 0.0; - *theta = 90.0; - } else { - *phi = astATan2d(x, -ycosg); - - s = r / (prj->w[0] + y*prj->w[4]); - t = s*prj->p[1]/sqrt(s*s + 1.0); - - s = astATan2d(1.0, s); - - if (fabs(t) > 1.0) { - t = copysign(90.0,t); - if (fabs(t) > 1.0+tol) { - return 2; - } - } else { - t = astASind(t); - } - - a = s - t; - b = s + t + 180.0; - - if (a > 90.0) a -= 360.0; - if (b > 90.0) b -= 360.0; - - *theta = (a > b) ? a : b; - } - - return 0; -} - -/*============================================================================ -* SZP: slant zenithal perspective projection. -* -* Given: -* prj->p[1] Distance of the point of projection from the centre of the -* generating sphere, mu in units of r0. -* prj->p[2] Native longitude, phi_c, and ... -* prj->p[3] Native latitude, theta_c, on the planewards side of the -* intersection of the line through the point of projection -* and the centre of the generating sphere, phi_c in degrees. -* -* Given and/or returned: -* prj->flag SZP, or -SZP if prj->flag is given < 0. -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "SZP" -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->w[0] 1/r0 -* prj->w[1] xp = -mu*cos(theta_c)*sin(phi_c) -* prj->w[2] yp = mu*cos(theta_c)*cos(phi_c) -* prj->w[3] zp = mu*sin(theta_c) + 1 -* prj->w[4] r0*xp -* prj->w[5] r0*yp -* prj->w[6] r0*zp -* prj->w[7] (zp - 1)^2 -* prj->w[8] asin(1-zp) if |1 - zp| < 1, -90 otherwise -* prj->astPRJfwd Pointer to astSZPfwd(). -* prj->astPRJrev Pointer to astSZPrev(). -*===========================================================================*/ - -int astSZPset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "SZP"); - prj->flag = icopysign(WCS__SZP, prj->flag); - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - prj->w[0] = 1.0/prj->r0; - - prj->w[3] = prj->p[1] * astSind(prj->p[3]) + 1.0; - if (prj->w[3] == 0.0) { - return 1; - } - - prj->w[1] = -prj->p[1] * astCosd(prj->p[3]) * astSind(prj->p[2]); - prj->w[2] = prj->p[1] * astCosd(prj->p[3]) * astCosd(prj->p[2]); - prj->w[4] = prj->r0 * prj->w[1]; - prj->w[5] = prj->r0 * prj->w[2]; - prj->w[6] = prj->r0 * prj->w[3]; - prj->w[7] = (prj->w[3] - 1.0) * prj->w[3] - 1.0; - - if (fabs(prj->w[3] - 1.0) < 1.0) { - prj->w[8] = astASind(1.0 - prj->w[3]); - } else { - prj->w[8] = -90.0; - } - - prj->astPRJfwd = astSZPfwd; - prj->astPRJrev = astSZPrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astSZPfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double a, b, cphi, cthe, s, sphi, t; - - if (abs(prj->flag) != WCS__SZP) { - if (astSZPset(prj)) return 1; - } - - cphi = astCosd(phi); - sphi = astSind(phi); - cthe = astCosd(theta); - s = 1.0 - astSind(theta); - - t = prj->w[3] - s; - if (t == 0.0) { - return 2; - } - - *x = (prj->w[6]*cthe*sphi - prj->w[4]*s)/t; - *y = -(prj->w[6]*cthe*cphi + prj->w[5]*s)/t; - - /* Bounds checking. */ - if (prj->flag > 0) { - /* Divergence. */ - if (theta < prj->w[8]) { - return 2; - } - - /* Overlap. */ - if (fabs(prj->p[1]) > 1.0) { - s = prj->w[1]*sphi - prj->w[2]*cphi; - t = 1.0/sqrt(prj->w[7] + s*s); - - if (fabs(t) <= 1.0) { - s = astATan2d(s, prj->w[3] - 1.0); - t = astASind(t); - a = s - t; - b = s + t + 180.0; - - if (a > 90.0) a -= 360.0; - if (b > 90.0) b -= 360.0; - - if (theta < ((a > b) ? a : b)) { - return 2; - } - } - } - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astSZPrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double a, b, c, d, r2, sth1, sth2, sthe, sxy, t, x1, xp, y1, yp, z; - const double tol = 1.0e-13; - - if (abs(prj->flag) != WCS__SZP) { - if (astSZPset(prj)) return 1; - } - - xp = x*prj->w[0]; - yp = y*prj->w[0]; - r2 = xp*xp + yp*yp; - - x1 = (xp - prj->w[1])/prj->w[3]; - y1 = (yp - prj->w[2])/prj->w[3]; - sxy = xp*x1 + yp*y1; - - if (r2 < 1.0e-10) { - /* Use small angle formula. */ - z = r2/2.0; - *theta = 90.0 - R2D*sqrt(r2/(1.0 + sxy)); - - } else { - t = x1*x1 + y1*y1; - a = t + 1.0; - b = sxy - t; - c = r2 - sxy - sxy + t - 1.0; - d = b*b - a*c; - - /* Check for a solution. */ - if (d < 0.0) { - return 2; - } - d = sqrt(d); - - /* Choose solution closest to pole. */ - sth1 = (-b + d)/a; - sth2 = (-b - d)/a; - sthe = (sth1 > sth2) ? sth1 : sth2; - if (sthe > 1.0) { - if (sthe-1.0 < tol) { - sthe = 1.0; - } else { - sthe = (sth1 < sth2) ? sth1 : sth2; - } - } - - if (sthe < -1.0) { - if (sthe+1.0 > -tol) { - sthe = -1.0; - } - } - - if (sthe > 1.0 || sthe < -1.0) { - return 2; - } - - *theta = astASind(sthe); - - z = 1.0 - sthe; - } - - *phi = astATan2d(xp - x1*z, -(yp - y1*z)); - - return 0; -} - -/*============================================================================ -* TAN: gnomonic projection. -* -* Given and/or returned: -* prj->flag TAN, or -TAN if prj->flag is given < 0. -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "TAN" -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->astPRJfwd Pointer to astTANfwd(). -* prj->astPRJrev Pointer to astTANrev(). -*===========================================================================*/ - -int astTANset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "TAN"); - prj->flag = icopysign(WCS__TAN, prj->flag); - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - prj->astPRJfwd = astTANfwd; - prj->astPRJrev = astTANrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astTANfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double r, s; - - if (abs(prj->flag) != WCS__TAN) { - if(astTANset(prj)) return 1; - } - - s = astSind(theta); - if (s == 0.0) { - return 2; - } - - r = prj->r0*astCosd(theta)/s; - *x = r*astSind(phi); - *y = -r*astCosd(phi); - - if (prj->flag > 0 && s < 0.0) { - return 2; - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astTANrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double r; - - if (abs(prj->flag) != WCS__TAN) { - if (astTANset(prj)) return 1; - } - - r = sqrt(x*x + y*y); - if (r == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(x, -y); - } - *theta = astATan2d(prj->r0, r); - - return 0; -} - -/*============================================================================ -* STG: stereographic projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "STG" -* prj->flag STG -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->w[0] 2*r0 -* prj->w[1] 1/(2*r0) -* prj->astPRJfwd Pointer to astSTGfwd(). -* prj->astPRJrev Pointer to astSTGrev(). -*===========================================================================*/ - -int astSTGset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "STG"); - prj->flag = WCS__STG; - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 360.0/PI; - prj->w[1] = PI/360.0; - } else { - prj->w[0] = 2.0*prj->r0; - prj->w[1] = 1.0/prj->w[0]; - } - - prj->astPRJfwd = astSTGfwd; - prj->astPRJrev = astSTGrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astSTGfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double r, s; - - if (prj->flag != WCS__STG) { - if (astSTGset(prj)) return 1; - } - - s = 1.0 + astSind(theta); - if (s == 0.0) { - return 2; - } - - r = prj->w[0]*astCosd(theta)/s; - *x = r*astSind(phi); - *y = -r*astCosd(phi); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astSTGrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double r; - - if (prj->flag != WCS__STG) { - if (astSTGset(prj)) return 1; - } - - r = sqrt(x*x + y*y); - if (r == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(x, -y); - } - *theta = 90.0 - 2.0*astATand(r*prj->w[1]); - - return 0; -} - -/*============================================================================ -* SIN: orthographic/synthesis projection. -* -* Given: -* prj->p[1:2] Obliqueness parameters, xi and eta. -* -* Given and/or returned: -* prj->flag SIN, or -SIN if prj->flag is given < 0. -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "SIN" -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->w[0] 1/r0 -* prj->w[1] xi**2 + eta**2 -* prj->w[2] xi**2 + eta**2 + 1 -* prj->w[3] xi**2 + eta**2 - 1 -* prj->astPRJfwd Pointer to astSINfwd(). -* prj->astPRJrev Pointer to astSINrev(). -*===========================================================================*/ - -int astSINset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "SIN"); - prj->flag = icopysign(WCS__SIN, prj->flag); - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - prj->w[0] = 1.0/prj->r0; - prj->w[1] = prj->p[1]*prj->p[1] + prj->p[2]*prj->p[2]; - prj->w[2] = prj->w[1] + 1.0; - prj->w[3] = prj->w[1] - 1.0; - - prj->astPRJfwd = astSINfwd; - prj->astPRJrev = astSINrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astSINfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double cphi, cthe, sphi, t, z; - - if (abs(prj->flag) != WCS__SIN) { - if (astSINset(prj)) return 1; - } - - t = (90.0 - fabs(theta))*D2R; - if (t < 1.0e-5) { - if (theta > 0.0) { - z = t*t/2.0; - } else { - z = 2.0 - t*t/2.0; - } - cthe = t; - } else { - z = 1.0 - astSind(theta); - cthe = astCosd(theta); - } - - cphi = astCosd(phi); - sphi = astSind(phi); - *x = prj->r0*(cthe*sphi + prj->p[1]*z); - *y = -prj->r0*(cthe*cphi - prj->p[2]*z); - - /* Validate this solution. */ - if (prj->flag > 0) { - if (prj->w[1] == 0.0) { - /* Orthographic projection. */ - if (theta < 0.0) { - return 2; - } - } else { - /* "Synthesis" projection. */ - t = -astATand(prj->p[1]*sphi - prj->p[2]*cphi); - if (theta < t) { - return 2; - } - } - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astSINrev (x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - const double tol = 1.0e-13; - double a, b, c, d, r2, sth1, sth2, sthe, sxy, x0, x1, xp, y0, y1, yp, z; - - if (abs(prj->flag) != WCS__SIN) { - if (astSINset(prj)) return 1; - } - - /* Compute intermediaries. */ - x0 = x*prj->w[0]; - y0 = y*prj->w[0]; - r2 = x0*x0 + y0*y0; - - if (prj->w[1] == 0.0) { - /* Orthographic projection. */ - if (r2 != 0.0) { - *phi = astATan2d(x0, -y0); - } else { - *phi = 0.0; - } - - if (r2 < 0.5) { - *theta = astACosd(sqrt(r2)); - } else if (r2 <= 1.0) { - *theta = astASind(sqrt(1.0 - r2)); - } else { - return 2; - } - - } else { - /* "Synthesis" projection. */ - x1 = prj->p[1]; - y1 = prj->p[2]; - sxy = x0*x1 + y0*y1; - - if (r2 < 1.0e-10) { - /* Use small angle formula. */ - z = r2/2.0; - *theta = 90.0 - R2D*sqrt(r2/(1.0 + sxy)); - - } else { - a = prj->w[2]; - b = sxy - prj->w[1]; - c = r2 - sxy - sxy + prj->w[3]; - d = b*b - a*c; - - /* Check for a solution. */ - if (d < 0.0) { - return 2; - } - d = sqrt(d); - - /* Choose solution closest to pole. */ - sth1 = (-b + d)/a; - sth2 = (-b - d)/a; - sthe = (sth1 > sth2) ? sth1 : sth2; - if (sthe > 1.0) { - if (sthe-1.0 < tol) { - sthe = 1.0; - } else { - sthe = (sth1 < sth2) ? sth1 : sth2; - } - } - - if (sthe < -1.0) { - if (sthe+1.0 > -tol) { - sthe = -1.0; - } - } - - if (sthe > 1.0 || sthe < -1.0) { - return 2; - } - - *theta = astASind(sthe); - z = 1.0 - sthe; - } - - xp = -y0 + prj->p[2]*z; - yp = x0 - prj->p[1]*z; - if (xp == 0.0 && yp == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(yp,xp); - } - } - - return 0; -} - -/*============================================================================ -* ARC: zenithal/azimuthal equidistant projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "ARC" -* prj->flag ARC -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->w[0] r0*(pi/180) -* prj->w[1] (180/pi)/r0 -* prj->astPRJfwd Pointer to astARCfwd(). -* prj->astPRJrev Pointer to astARCrev(). -*===========================================================================*/ - -int astARCset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "ARC"); - prj->flag = WCS__ARC; - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 1.0; - prj->w[1] = 1.0; - } else { - prj->w[0] = prj->r0*D2R; - prj->w[1] = 1.0/prj->w[0]; - } - - prj->astPRJfwd = astARCfwd; - prj->astPRJrev = astARCrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astARCfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double r; - - if (prj->flag != WCS__ARC) { - if (astARCset(prj)) return 1; - } - - r = prj->w[0]*(90.0 - theta); - *x = r*astSind(phi); - *y = -r*astCosd(phi); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astARCrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double r; - - if (prj->flag != WCS__ARC) { - if (astARCset(prj)) return 1; - } - - r = sqrt(x*x + y*y); - if (r == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(x, -y); - } - *theta = 90.0 - r*prj->w[1]; - - return 0; -} - -/*============================================================================ -* ZPN: zenithal/azimuthal polynomial projection. -* -* Given: -* prj->p[0:WCSLIB_MXPAR-1] Polynomial coefficients. -* -* Given and/or returned: -* prj->flag ZPN, or -ZPN if prj->flag is given < 0. -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "ZPN" -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->n Degree of the polynomial, N. -* prj->w[0] Co-latitude of the first point of inflection (N > 2). -* prj->w[1] Radius of the first point of inflection (N > 2). -* prj->astPRJfwd Pointer to astZPNfwd(). -* prj->astPRJrev Pointer to astZPNrev(). -*===========================================================================*/ - -int astZPNset(prj) - -struct AstPrjPrm *prj; - -{ - int i, j, k, plen; - double d, d1, d2, r, zd, zd1, zd2; - const double tol = 1.0e-13; - - strcpy(prj->code, "ZPN"); - prj->flag = icopysign(WCS__ZPN, prj->flag); - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - /* Find the highest non-zero coefficient. */ - plen = astSizeOf( prj->p )/sizeof( double ); - for (k = plen-1; k >= 0 && prj->p[k] == 0.0; k--); - if (k < 0) return 1; - - prj->n = k; - - if (k >= 3) { - /* Find the point of inflection closest to the pole. */ - zd1 = 0.0; - d1 = prj->p[1]; - if (d1 <= 0.0) { - return 1; - } - - /* Find the point where the derivative first goes negative. */ - for (i = 0; i < 180; i++) { - zd2 = i*D2R; - d2 = 0.0; - for (j = k; j > 0; j--) { - d2 = d2*zd2 + j*prj->p[j]; - } - - if (d2 <= 0.0) break; - zd1 = zd2; - d1 = d2; - } - - if (i == 180) { - /* No negative derivative -> no point of inflection. */ - zd = PI; - } else { - /* Find where the derivative is zero. */ - for (i = 1; i <= 10; i++) { - zd = zd1 - d1*(zd2-zd1)/(d2-d1); - - d = 0.0; - for (j = k; j > 0; j--) { - d = d*zd + j*prj->p[j]; - } - - if (fabs(d) < tol) break; - - if (d < 0.0) { - zd2 = zd; - d2 = d; - } else { - zd1 = zd; - d1 = d; - } - } - } - - r = 0.0; - for (j = k; j >= 0; j--) { - r = r*zd + prj->p[j]; - } - prj->w[0] = zd; - prj->w[1] = r; - } - - prj->astPRJfwd = astZPNfwd; - prj->astPRJrev = astZPNrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astZPNfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - int j; - double r, s; - - if (abs(prj->flag) != WCS__ZPN) { - if (astZPNset(prj)) return 1; - } - - s = (90.0 - theta)*D2R; - - r = 0.0; - for (j = prj->n; j >= 0; j--) { - r = r*s + prj->p[j]; - } - r = prj->r0*r; - - *x = r*astSind(phi); - *y = -r*astCosd(phi); - - if (prj->flag > 0 && s > prj->w[0] && prj->n > 2 ) { - return 2; - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astZPNrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - int i, j, k; - double a, b, c, d, lambda, r, r1, r2, rt, zd, zd1, zd2; - const double tol = 1.0e-13; - - if (abs(prj->flag) != WCS__ZPN) { - if (astZPNset(prj)) return 1; - } - - k = prj->n; - - r = sqrt(x*x + y*y)/prj->r0; - - if (k < 1) { - /* Constant - no solution. */ - return 1; - } else if (k == 1) { - /* Linear. */ - zd = (r - prj->p[0])/prj->p[1]; - } else if (k == 2) { - /* Quadratic. */ - a = prj->p[2]; - b = prj->p[1]; - c = prj->p[0] - r; - - d = b*b - 4.0*a*c; - if (d < 0.0) { - return 2; - } - d = sqrt(d); - - /* Choose solution closest to pole. */ - zd1 = (-b + d)/(2.0*a); - zd2 = (-b - d)/(2.0*a); - zd = (zd1zd2) ? zd1 : zd2; - if (zd < 0.0) { - if (zd < -tol) { - return 2; - } - zd = 0.0; - } else if (zd > PI) { - if (zd > PI+tol) { - return 2; - } - zd = PI; - } - } else { - /* Higher order - solve iteratively. */ - zd1 = 0.0; - r1 = prj->p[0]; - zd2 = prj->w[0]; - r2 = prj->w[1]; - - if (r < r1) { - if (r < r1-tol) { - return 2; - } - zd = zd1; - } else if (r > r2) { - if (r > r2+tol) { - return 2; - } - zd = zd2; - } else { - /* Disect the interval. */ - for (j = 0; j < 100; j++) { - lambda = (r2 - r)/(r2 - r1); - if (lambda < 0.1) { - lambda = 0.1; - } else if (lambda > 0.9) { - lambda = 0.9; - } - - zd = zd2 - lambda*(zd2 - zd1); - - rt = 0.0; - for (i = k; i >= 0; i--) { - rt = (rt * zd) + prj->p[i]; - } - - if (rt < r) { - if (r-rt < tol) break; - r1 = rt; - zd1 = zd; - } else { - if (rt-r < tol) break; - r2 = rt; - zd2 = zd; - } - - if (fabs(zd2-zd1) < tol) break; - } - } - } - - if (r == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(x, -y); - } - *theta = 90.0 - zd*R2D; - - return 0; -} - -/*============================================================================ -* ZEA: zenithal/azimuthal equal area projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "ZEA" -* prj->flag ZEA -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->w[0] 2*r0 -* prj->w[1] 1/(2*r0) -* prj->astPRJfwd Pointer to astZEAfwd(). -* prj->astPRJrev Pointer to astZEArev(). -*===========================================================================*/ - -int astZEAset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "ZEA"); - prj->flag = WCS__ZEA; - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 360.0/PI; - prj->w[1] = PI/360.0; - } else { - prj->w[0] = 2.0*prj->r0; - prj->w[1] = 1.0/prj->w[0]; - } - - prj->astPRJfwd = astZEAfwd; - prj->astPRJrev = astZEArev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astZEAfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double r; - - if (prj->flag != WCS__ZEA) { - if (astZEAset(prj)) return 1; - } - - r = prj->w[0]*astSind((90.0 - theta)/2.0); - *x = r*astSind(phi); - *y = -r*astCosd(phi); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astZEArev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double r, s; - const double tol = 1.0e-12; - - if (prj->flag != WCS__ZEA) { - if (astZEAset(prj)) return 1; - } - - r = sqrt(x*x + y*y); - if (r == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(x, -y); - } - - s = r*prj->w[1]; - if (fabs(s) > 1.0) { - if (fabs(r - prj->w[0]) < tol) { - *theta = -90.0; - } else { - return 2; - } - } else { - *theta = 90.0 - 2.0*astASind(s); - } - - return 0; -} - -/*============================================================================ -* AIR: Airy's projection. -* -* Given: -* prj->p[1] Latitude theta_b within which the error is minimized, in -* degrees. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "AIR" -* prj->flag AIR -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->w[0] 2*r0 -* prj->w[1] ln(cos(xi_b))/tan(xi_b)**2, where xi_b = (90-theta_b)/2 -* prj->w[2] 1/2 - prj->w[1] -* prj->w[3] 2*r0*prj->w[2] -* prj->w[4] tol, cutoff for using small angle approximation, in -* radians. -* prj->w[5] prj->w[2]*tol -* prj->w[6] (180/pi)/prj->w[2] -* prj->astPRJfwd Pointer to astAIRfwd(). -* prj->astPRJrev Pointer to astAIRrev(). -*===========================================================================*/ - -int astAIRset(prj) - -struct AstPrjPrm *prj; - -{ - const double tol = 1.0e-4; - double cxi; - - strcpy(prj->code, "AIR"); - prj->flag = WCS__AIR; - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - prj->w[0] = 2.0*prj->r0; - if (prj->p[1] == 90.0) { - prj->w[1] = -0.5; - prj->w[2] = 1.0; - } else if (prj->p[1] > -90.0) { - cxi = astCosd((90.0 - prj->p[1])/2.0); - prj->w[1] = log(cxi)*(cxi*cxi)/(1.0-cxi*cxi); - prj->w[2] = 0.5 - prj->w[1]; - } else { - return 1; - } - - prj->w[3] = prj->w[0] * prj->w[2]; - prj->w[4] = tol; - prj->w[5] = prj->w[2]*tol; - prj->w[6] = R2D/prj->w[2]; - - prj->astPRJfwd = astAIRfwd; - prj->astPRJrev = astAIRrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astAIRfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double cxi, r, txi, xi; - - if (prj->flag != WCS__AIR) { - if (astAIRset(prj)) return 1; - } - - if (theta == 90.0) { - r = 0.0; - } else if (theta > -90.0) { - xi = D2R*(90.0 - theta)/2.0; - if (xi < prj->w[4]) { - r = xi*prj->w[3]; - } else { - cxi = astCosd((90.0 - theta)/2.0); - txi = sqrt(1.0-cxi*cxi)/cxi; - r = -prj->w[0]*(log(cxi)/txi + prj->w[1]*txi); - } - } else { - return 2; - } - - *x = r*astSind(phi); - *y = -r*astCosd(phi); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astAIRrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - int j; - double cxi, lambda, r, r1, r2, rt, txi, x1, x2, xi; - const double tol = 1.0e-12; - - if (prj->flag != WCS__AIR) { - if (astAIRset(prj)) return 1; - } - - r = sqrt(x*x + y*y)/prj->w[0]; - - if (r == 0.0) { - xi = 0.0; - } else if (r < prj->w[5]) { - xi = r*prj->w[6]; - } else { - /* Find a solution interval. */ - x1 = 1.0; - r1 = 0.0; - for (j = 0; j < 30; j++) { - x2 = x1/2.0; - txi = sqrt(1.0-x2*x2)/x2; - r2 = -(log(x2)/txi + prj->w[1]*txi); - - if (r2 >= r) break; - x1 = x2; - r1 = r2; - } - if (j == 30) return 2; - - for (j = 0; j < 100; j++) { - /* Weighted division of the interval. */ - lambda = (r2-r)/(r2-r1); - if (lambda < 0.1) { - lambda = 0.1; - } else if (lambda > 0.9) { - lambda = 0.9; - } - cxi = x2 - lambda*(x2-x1); - - txi = sqrt(1.0-cxi*cxi)/cxi; - rt = -(log(cxi)/txi + prj->w[1]*txi); - - if (rt < r) { - if (r-rt < tol) break; - r1 = rt; - x1 = cxi; - } else { - if (rt-r < tol) break; - r2 = rt; - x2 = cxi; - } - } - if (j == 100) return 2; - - xi = astACosd(cxi); - } - - if (r == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(x, -y); - } - *theta = 90.0 - 2.0*xi; - - return 0; -} - -/*============================================================================ -* CYP: cylindrical perspective projection. -* -* Given: -* prj->p[1] Distance of point of projection from the centre of the -* generating sphere, mu, in units of r0. -* prj->p[2] Radius of the cylinder of projection, lambda, in units of -* r0. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "CYP" -* prj->flag CYP -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*lambda*(pi/180) -* prj->w[1] (180/pi)/(r0*lambda) -* prj->w[2] r0*(mu + lambda) -* prj->w[3] 1/(r0*(mu + lambda)) -* prj->astPRJfwd Pointer to astCYPfwd(). -* prj->astPRJrev Pointer to astCYPrev(). -*===========================================================================*/ - -int astCYPset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "CYP"); - prj->flag = WCS__CYP; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - - prj->w[0] = prj->p[2]; - if (prj->w[0] == 0.0) { - return 1; - } - - prj->w[1] = 1.0/prj->w[0]; - - prj->w[2] = R2D*(prj->p[1] + prj->p[2]); - if (prj->w[2] == 0.0) { - return 1; - } - - prj->w[3] = 1.0/prj->w[2]; - } else { - prj->w[0] = prj->r0*prj->p[2]*D2R; - if (prj->w[0] == 0.0) { - return 1; - } - - prj->w[1] = 1.0/prj->w[0]; - - prj->w[2] = prj->r0*(prj->p[1] + prj->p[2]); - if (prj->w[2] == 0.0) { - return 1; - } - - prj->w[3] = 1.0/prj->w[2]; - } - - prj->astPRJfwd = astCYPfwd; - prj->astPRJrev = astCYPrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCYPfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double s; - - if (prj->flag != WCS__CYP) { - if (astCYPset(prj)) return 1; - } - - s = prj->p[1] + astCosd(theta); - if (s == 0.0) { - return 2; - } - - *x = prj->w[0]*phi; - *y = prj->w[2]*astSind(theta)/s; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCYPrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double eta; - double a; - const double tol = 1.0e-13; - - if (prj->flag != WCS__CYP) { - if (astCYPset(prj)) return 1; - } - - *phi = x*prj->w[1]; - eta = y*prj->w[3]; - - a = eta*prj->p[1]/sqrt(eta*eta+1.0); - if( fabs( a ) < 1.0 ) { - *theta = astATan2d(eta,1.0) + astASind( a ); - - } else if( fabs( a ) < 1.0 + tol ) { - if( a > 0.0 ){ - *theta = astATan2d(eta,1.0) + 90.0; - } else { - *theta = astATan2d(eta,1.0) - 90.0; - } - - } else { - return 2; - } - - return 0; -} - -/*============================================================================ -* CEA: cylindrical equal area projection. -* -* Given: -* prj->p[1] Square of the cosine of the latitude at which the -* projection is conformal, lambda. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "CEA" -* prj->flag CEA -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*(pi/180) -* prj->w[1] (180/pi)/r0 -* prj->w[2] r0/lambda -* prj->w[3] lambda/r0 -* prj->astPRJfwd Pointer to astCEAfwd(). -* prj->astPRJrev Pointer to astCEArev(). -*===========================================================================*/ - -int astCEAset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "CEA"); - prj->flag = WCS__CEA; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 1.0; - prj->w[1] = 1.0; - if (prj->p[1] <= 0.0 || prj->p[1] > 1.0) { - return 1; - } - prj->w[2] = prj->r0/prj->p[1]; - prj->w[3] = prj->p[1]/prj->r0; - } else { - prj->w[0] = prj->r0*D2R; - prj->w[1] = R2D/prj->r0; - if (prj->p[1] <= 0.0 || prj->p[1] > 1.0) { - return 1; - } - prj->w[2] = prj->r0/prj->p[1]; - prj->w[3] = prj->p[1]/prj->r0; - } - - prj->astPRJfwd = astCEAfwd; - prj->astPRJrev = astCEArev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCEAfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - if (prj->flag != WCS__CEA) { - if (astCEAset(prj)) return 1; - } - - *x = prj->w[0]*phi; - *y = prj->w[2]*astSind(theta); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCEArev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double s; - const double tol = 1.0e-13; - - if (prj->flag != WCS__CEA) { - if (astCEAset(prj)) return 1; - } - - s = y*prj->w[3]; - if (fabs(s) > 1.0) { - if (fabs(s) > 1.0+tol) { - return 2; - } - s = copysign(1.0,s); - } - - *phi = x*prj->w[1]; - *theta = astASind(s); - - return 0; -} - -/*============================================================================ -* CAR: Cartesian projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "CAR" -* prj->flag CAR -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*(pi/180) -* prj->w[1] (180/pi)/r0 -* prj->astPRJfwd Pointer to astCARfwd(). -* prj->astPRJrev Pointer to astCARrev(). -*===========================================================================*/ - -int astCARset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "CAR"); - prj->flag = WCS__CAR; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 1.0; - prj->w[1] = 1.0; - } else { - prj->w[0] = prj->r0*D2R; - prj->w[1] = 1.0/prj->w[0]; - } - - prj->astPRJfwd = astCARfwd; - prj->astPRJrev = astCARrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCARfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - if (prj->flag != WCS__CAR) { - if (astCARset(prj)) return 1; - } - - *x = prj->w[0]*phi; - *y = prj->w[0]*theta; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCARrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - if (prj->flag != WCS__CAR) { - if (astCARset(prj)) return 1; - } - - *phi = prj->w[1]*x; - *theta = prj->w[1]*y; - - return 0; -} - -/*============================================================================ -* MER: Mercator's projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "MER" -* prj->flag MER -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*(pi/180) -* prj->w[1] (180/pi)/r0 -* prj->astPRJfwd Pointer to astMERfwd(). -* prj->astPRJrev Pointer to astMERrev(). -*===========================================================================*/ - -int astMERset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "MER"); - prj->flag = WCS__MER; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 1.0; - prj->w[1] = 1.0; - } else { - prj->w[0] = prj->r0*D2R; - prj->w[1] = 1.0/prj->w[0]; - } - - prj->astPRJfwd = astMERfwd; - prj->astPRJrev = astMERrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astMERfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - if (prj->flag != WCS__MER) { - if (astMERset(prj)) return 1; - } - - if (theta <= -90.0 || theta >= 90.0) { - return 2; - } - - *x = prj->w[0]*phi; - *y = prj->r0*log(astTand((90.0+theta)/2.0)); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astMERrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - if (prj->flag != WCS__MER) { - if (astMERset(prj)) return 1; - } - - *phi = x*prj->w[1]; - *theta = 2.0*astATand(exp(y/prj->r0)) - 90.0; - - return 0; -} - -/*============================================================================ -* SFL: Sanson-Flamsteed ("global sinusoid") projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "SFL" -* prj->flag SFL -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*(pi/180) -* prj->w[1] (180/pi)/r0 -* prj->astPRJfwd Pointer to astSFLfwd(). -* prj->astPRJrev Pointer to astSFLrev(). -*===========================================================================*/ - -int astSFLset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "SFL"); - prj->flag = WCS__SFL; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 1.0; - prj->w[1] = 1.0; - } else { - prj->w[0] = prj->r0*D2R; - prj->w[1] = 1.0/prj->w[0]; - } - - prj->astPRJfwd = astSFLfwd; - prj->astPRJrev = astSFLrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astSFLfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - if (prj->flag != WCS__SFL) { - if (astSFLset(prj)) return 1; - } - - *x = prj->w[0]*phi*astCosd(theta); - *y = prj->w[0]*theta; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astSFLrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double w; - - if (prj->flag != WCS__SFL) { - if (astSFLset(prj)) return 1; - } - - w = cos(y/prj->r0); - if (w == 0.0) { - *phi = 0.0; - } else { - *phi = x*prj->w[1]/cos(y/prj->r0); - } - *theta = y*prj->w[1]; - - return 0; -} - -/*============================================================================ -* PAR: parabolic projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "PAR" -* prj->flag PAR -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*(pi/180) -* prj->w[1] (180/pi)/r0 -* prj->w[2] pi*r0 -* prj->w[3] 1/(pi*r0) -* prj->astPRJfwd Pointer to astPARfwd(). -* prj->astPRJrev Pointer to astPARrev(). -*===========================================================================*/ - -int astPARset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "PAR"); - prj->flag = WCS__PAR; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 1.0; - prj->w[1] = 1.0; - prj->w[2] = 180.0; - prj->w[3] = 1.0/prj->w[2]; - } else { - prj->w[0] = prj->r0*D2R; - prj->w[1] = 1.0/prj->w[0]; - prj->w[2] = PI*prj->r0; - prj->w[3] = 1.0/prj->w[2]; - } - - prj->astPRJfwd = astPARfwd; - prj->astPRJrev = astPARrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astPARfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double s; - - if (prj->flag != WCS__PAR) { - if (astPARset(prj)) return 1; - } - - s = astSind(theta/3.0); - *x = prj->w[0]*phi*(1.0 - 4.0*s*s); - *y = prj->w[2]*s; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astPARrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double s, t; - - if (prj->flag != WCS__PAR) { - if (astPARset(prj)) return 1; - } - - s = y*prj->w[3]; - if (s > 1.0 || s < -1.0) { - return 2; - } - - t = 1.0 - 4.0*s*s; - if (t == 0.0) { - if (x == 0.0) { - *phi = 0.0; - } else { - return 2; - } - } else { - *phi = prj->w[1]*x/t; - } - - *theta = 3.0*astASind(s); - - return 0; -} - -/*============================================================================ -* MOL: Mollweide's projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "MOL" -* prj->flag MOL -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] sqrt(2)*r0 -* prj->w[1] sqrt(2)*r0/90 -* prj->w[2] 1/(sqrt(2)*r0) -* prj->w[3] 90/r0 -* prj->astPRJfwd Pointer to astMOLfwd(). -* prj->astPRJrev Pointer to astMOLrev(). -*===========================================================================*/ - -int astMOLset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "MOL"); - prj->flag = WCS__MOL; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - prj->w[0] = SQRT2*prj->r0; - prj->w[1] = prj->w[0]/90.0; - prj->w[2] = 1.0/prj->w[0]; - prj->w[3] = 90.0/prj->r0; - prj->w[4] = 2.0/PI; - - prj->astPRJfwd = astMOLfwd; - prj->astPRJrev = astMOLrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astMOLfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - int j; - double gamma, resid, u, v, v0, v1; - const double tol = 1.0e-13; - - if (prj->flag != WCS__MOL) { - if (astMOLset(prj)) return 1; - } - - if (fabs(theta) == 90.0) { - *x = 0.0; - *y = copysign(prj->w[0],theta); - } else if (theta == 0.0) { - *x = prj->w[1]*phi; - *y = 0.0; - } else { - u = PI*astSind(theta); - v0 = -PI; - v1 = PI; - v = u; - for (j = 0; j < 100; j++) { - resid = (v - u) + sin(v); - if (resid < 0.0) { - if (resid > -tol) break; - v0 = v; - } else { - if (resid < tol) break; - v1 = v; - } - v = (v0 + v1)/2.0; - } - - gamma = v/2.0; - *x = prj->w[1]*phi*cos(gamma); - *y = prj->w[0]*sin(gamma); - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astMOLrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double s, y0, z; - const double tol = 1.0e-12; - - if (prj->flag != WCS__MOL) { - if (astMOLset(prj)) return 1; - } - - y0 = y/prj->r0; - s = 2.0 - y0*y0; - if (s <= tol) { - if (s < -tol) { - return 2; - } - s = 0.0; - - if (fabs(x) > tol) { - return 2; - } - *phi = 0.0; - } else { - s = sqrt(s); - *phi = prj->w[3]*x/s; - } - - z = y*prj->w[2]; - if (fabs(z) > 1.0) { - if (fabs(z) > 1.0+tol) { - return 2; - } - z = copysign(1.0,z) + y0*s/PI; - } else { - z = asin(z)*prj->w[4] + y0*s/PI; - } - - if (fabs(z) > 1.0) { - if (fabs(z) > 1.0+tol) { - return 2; - } - z = copysign(1.0,z); - } - - *theta = astASind(z); - - return 0; -} - -/*============================================================================ -* AIT: Hammer-Aitoff projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "AIT" -* prj->flag AIT -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] 2*r0**2 -* prj->w[1] 1/(2*r0)**2 -* prj->w[2] 1/(4*r0)**2 -* prj->w[3] 1/(2*r0) -* prj->astPRJfwd Pointer to astAITfwd(). -* prj->astPRJrev Pointer to astAITrev(). -*===========================================================================*/ - -int astAITset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "AIT"); - prj->flag = WCS__AIT; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - prj->w[0] = 2.0*prj->r0*prj->r0; - prj->w[1] = 1.0/(2.0*prj->w[0]); - prj->w[2] = prj->w[1]/4.0; - prj->w[3] = 1.0/(2.0*prj->r0); - - prj->astPRJfwd = astAITfwd; - prj->astPRJrev = astAITrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astAITfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double cthe, w; - - if (prj->flag != WCS__AIT) { - if (astAITset(prj)) return 1; - } - - cthe = astCosd(theta); - w = sqrt(prj->w[0]/(1.0 + cthe*astCosd(phi/2.0))); - *x = 2.0*w*cthe*astSind(phi/2.0); - *y = w*astSind(theta); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astAITrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double s, u, xp, yp, z; - const double tol = 1.0e-13; - - if (prj->flag != WCS__AIT) { - if (astAITset(prj)) return 1; - } - - u = 1.0 - x*x*prj->w[2] - y*y*prj->w[1]; - if (u < 0.0) { - if (u < -tol) { - return 2; - } - - u = 0.0; - } - - z = sqrt(u); - s = z*y/prj->r0; - if (fabs(s) > 1.0) { - if (fabs(s) > 1.0+tol) { - return 2; - } - s = copysign(1.0,s); - } - - xp = 2.0*z*z - 1.0; - yp = z*x*prj->w[3]; - if (xp == 0.0 && yp == 0.0) { - *phi = 0.0; - } else { - *phi = 2.0*astATan2d(yp, xp); - } - *theta = astASind(s); - - return 0; -} - -/*============================================================================ -* COP: conic perspective projection. -* -* Given: -* prj->p[1] sigma = (theta2+theta1)/2 -* prj->p[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the -* latitudes of the standard parallels, in degrees. -* -* Given and/or returned: -* prj->flag COP, or -COP if prj->flag is given < 0. -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "COP" -* prj->phi0 0.0 -* prj->theta0 sigma -* prj->w[0] C = sin(sigma) -* prj->w[1] 1/C -* prj->w[2] Y0 = r0*cos(delta)*cot(sigma) -* prj->w[3] r0*cos(delta) -* prj->w[4] 1/(r0*cos(delta) -* prj->w[5] cot(sigma) -* prj->astPRJfwd Pointer to astCOPfwd(). -* prj->astPRJrev Pointer to astCOPrev(). -*===========================================================================*/ - -int astCOPset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "COP"); - prj->flag = icopysign(WCS__COP, prj->flag); - prj->phi0 = 0.0; - prj->theta0 = prj->p[1]; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - prj->w[0] = astSind(prj->p[1]); - if (prj->w[0] == 0.0) { - return 1; - } - - prj->w[1] = 1.0/prj->w[0]; - - prj->w[3] = prj->r0*astCosd(prj->p[2]); - if (prj->w[3] == 0.0) { - return 1; - } - - prj->w[4] = 1.0/prj->w[3]; - prj->w[5] = 1.0/astTand(prj->p[1]); - - prj->w[2] = prj->w[3]*prj->w[5]; - - prj->astPRJfwd = astCOPfwd; - prj->astPRJrev = astCOPrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCOPfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double a, r, s, t; - - if (abs(prj->flag) != WCS__COP) { - if (astCOPset(prj)) return 1; - } - - t = theta - prj->p[1]; - s = astCosd(t); - if (s == 0.0) { - return 2; - } - - a = prj->w[0]*phi; - r = prj->w[2] - prj->w[3]*astSind(t)/s; - - *x = r*astSind(a); - *y = prj->w[2] - r*astCosd(a); - - if (prj->flag > 0 && r*prj->w[0] < 0.0) { - return 2; - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCOPrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double a, dy, r; - - if (abs(prj->flag) != WCS__COP) { - if (astCOPset(prj)) return 1; - } - - dy = prj->w[2] - y; - r = sqrt(x*x + dy*dy); - if (prj->p[1] < 0.0) r = -r; - - if (r == 0.0) { - a = 0.0; - } else { - a = astATan2d(x/r, dy/r); - } - - *phi = a*prj->w[1]; - *theta = prj->p[1] + astATand(prj->w[5] - r*prj->w[4]); - - return 0; -} - -/*============================================================================ -* COE: conic equal area projection. -* -* Given: -* prj->p[1] sigma = (theta2+theta1)/2 -* prj->p[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the -* latitudes of the standard parallels, in degrees. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "COE" -* prj->flag COE -* prj->phi0 0.0 -* prj->theta0 sigma -* prj->w[0] C = (sin(theta1) + sin(theta2))/2 -* prj->w[1] 1/C -* prj->w[2] Y0 = chi*sqrt(psi - 2C*astSind(sigma)) -* prj->w[3] chi = r0/C -* prj->w[4] psi = 1 + sin(theta1)*sin(theta2) -* prj->w[5] 2C -* prj->w[6] (1 + sin(theta1)*sin(theta2))*(r0/C)**2 -* prj->w[7] C/(2*r0**2) -* prj->w[8] chi*sqrt(psi + 2C) -* prj->astPRJfwd Pointer to astCOEfwd(). -* prj->astPRJrev Pointer to astCOErev(). -*===========================================================================*/ - -int astCOEset(prj) - -struct AstPrjPrm *prj; - -{ - double theta1, theta2; - - strcpy(prj->code, "COE"); - prj->flag = WCS__COE; - prj->phi0 = 0.0; - prj->theta0 = prj->p[1]; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - theta1 = prj->p[1] - prj->p[2]; - theta2 = prj->p[1] + prj->p[2]; - - prj->w[0] = (astSind(theta1) + astSind(theta2))/2.0; - if (prj->w[0] == 0.0) { - return 1; - } - - prj->w[1] = 1.0/prj->w[0]; - - prj->w[3] = prj->r0/prj->w[0]; - prj->w[4] = 1.0 + astSind(theta1)*astSind(theta2); - prj->w[5] = 2.0*prj->w[0]; - prj->w[6] = prj->w[3]*prj->w[3]*prj->w[4]; - prj->w[7] = 1.0/(2.0*prj->r0*prj->w[3]); - prj->w[8] = prj->w[3]*sqrt(prj->w[4] + prj->w[5]); - - prj->w[2] = prj->w[3]*sqrt(prj->w[4] - prj->w[5]*astSind(prj->p[1])); - - prj->astPRJfwd = astCOEfwd; - prj->astPRJrev = astCOErev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCOEfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double a, r; - - if (prj->flag != WCS__COE) { - if (astCOEset(prj)) return 1; - } - - a = phi*prj->w[0]; - if (theta == -90.0) { - r = prj->w[8]; - } else { - r = prj->w[3]*sqrt(prj->w[4] - prj->w[5]*astSind(theta)); - } - - *x = r*astSind(a); - *y = prj->w[2] - r*astCosd(a); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCOErev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double a, dy, r, w; - const double tol = 1.0e-12; - - if (prj->flag != WCS__COE) { - if (astCOEset(prj)) return 1; - } - - dy = prj->w[2] - y; - r = sqrt(x*x + dy*dy); - if (prj->p[1] < 0.0) r = -r; - - if (r == 0.0) { - a = 0.0; - } else { - a = astATan2d(x/r, dy/r); - } - - *phi = a*prj->w[1]; - if (fabs(r - prj->w[8]) < tol) { - *theta = -90.0; - } else { - w = (prj->w[6] - r*r)*prj->w[7]; - if (fabs(w) > 1.0) { - if (fabs(w-1.0) < tol) { - *theta = 90.0; - } else if (fabs(w+1.0) < tol) { - *theta = -90.0; - } else { - return 2; - } - } else { - *theta = astASind(w); - } - } - - return 0; -} - -/*============================================================================ -* COD: conic equidistant projection. -* -* Given: -* prj->p[1] sigma = (theta2+theta1)/2 -* prj->p[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the -* latitudes of the standard parallels, in degrees. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "COD" -* prj->flag COD -* prj->phi0 0.0 -* prj->theta0 sigma -* prj->w[0] C = r0*sin(sigma)*sin(delta)/delta -* prj->w[1] 1/C -* prj->w[2] Y0 = delta*cot(delta)*cot(sigma) -* prj->w[3] Y0 + sigma -* prj->astPRJfwd Pointer to astCODfwd(). -* prj->astPRJrev Pointer to astCODrev(). -*===========================================================================*/ - -int astCODset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "COD"); - prj->flag = WCS__COD; - prj->phi0 = 0.0; - prj->theta0 = prj->p[1]; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - if (prj->p[2] == 0.0) { - prj->w[0] = prj->r0*astSind(prj->p[1])*D2R; - } else { - prj->w[0] = prj->r0*astSind(prj->p[1])*astSind(prj->p[2])/prj->p[2]; - } - - if (prj->w[0] == 0.0) { - return 1; - } - - prj->w[1] = 1.0/prj->w[0]; - prj->w[2] = prj->r0*astCosd(prj->p[2])*astCosd(prj->p[1])/prj->w[0]; - prj->w[3] = prj->w[2] + prj->p[1]; - - prj->astPRJfwd = astCODfwd; - prj->astPRJrev = astCODrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCODfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double a, r; - - if (prj->flag != WCS__COD) { - if (astCODset(prj)) return 1; - } - - a = prj->w[0]*phi; - r = prj->w[3] - theta; - - *x = r*astSind(a); - *y = prj->w[2] - r*astCosd(a); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCODrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double a, dy, r; - - if (prj->flag != WCS__COD) { - if (astCODset(prj)) return 1; - } - - dy = prj->w[2] - y; - r = sqrt(x*x + dy*dy); - if (prj->p[1] < 0.0) r = -r; - - if (r == 0.0) { - a = 0.0; - } else { - a = astATan2d(x/r, dy/r); - } - - *phi = a*prj->w[1]; - *theta = prj->w[3] - r; - - return 0; -} - -/*============================================================================ -* COO: conic orthomorphic projection. -* -* Given: -* prj->p[1] sigma = (theta2+theta1)/2 -* prj->p[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the -* latitudes of the standard parallels, in degrees. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "COO" -* prj->flag COO -* prj->phi0 0.0 -* prj->theta0 sigma -* prj->w[0] C = ln(cos(theta2)/cos(theta1))/ln(tan(tau2)/tan(tau1)) -* where tau1 = (90 - theta1)/2 -* tau2 = (90 - theta2)/2 -* prj->w[1] 1/C -* prj->w[2] Y0 = psi*tan((90-sigma)/2)**C -* prj->w[3] psi = (r0*cos(theta1)/C)/tan(tau1)**C -* prj->w[4] 1/psi -* prj->astPRJfwd Pointer to astCOOfwd(). -* prj->astPRJrev Pointer to astCOOrev(). -*===========================================================================*/ - -int astCOOset(prj) - -struct AstPrjPrm *prj; - -{ - double cos1, cos2, tan1, tan2, theta1, theta2; - - strcpy(prj->code, "COO"); - prj->flag = WCS__COO; - prj->phi0 = 0.0; - prj->theta0 = prj->p[1]; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - theta1 = prj->p[1] - prj->p[2]; - theta2 = prj->p[1] + prj->p[2]; - - tan1 = astTand((90.0 - theta1)/2.0); - cos1 = astCosd(theta1); - - if (theta1 == theta2) { - prj->w[0] = astSind(theta1); - } else { - tan2 = astTand((90.0 - theta2)/2.0); - cos2 = astCosd(theta2); - prj->w[0] = log(cos2/cos1)/log(tan2/tan1); - } - if (prj->w[0] == 0.0) { - return 1; - } - - prj->w[1] = 1.0/prj->w[0]; - - prj->w[3] = prj->r0*(cos1/prj->w[0])/pow(tan1,prj->w[0]); - if (prj->w[3] == 0.0) { - return 1; - } - prj->w[2] = prj->w[3]*pow(astTand((90.0 - prj->p[1])/2.0),prj->w[0]); - prj->w[4] = 1.0/prj->w[3]; - - prj->astPRJfwd = astCOOfwd; - prj->astPRJrev = astCOOrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCOOfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double a, r; - - if (prj->flag != WCS__COO) { - if (astCOOset(prj)) return 1; - } - - a = prj->w[0]*phi; - if (theta == -90.0) { - if (prj->w[0] < 0.0) { - r = 0.0; - } else { - return 2; - } - } else { - r = prj->w[3]*pow(astTand((90.0 - theta)/2.0),prj->w[0]); - } - - *x = r*astSind(a); - *y = prj->w[2] - r*astCosd(a); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCOOrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double a, dy, r; - - if (prj->flag != WCS__COO) { - if (astCOOset(prj)) return 1; - } - - dy = prj->w[2] - y; - r = sqrt(x*x + dy*dy); - if (prj->p[1] < 0.0) r = -r; - - if (r == 0.0) { - a = 0.0; - } else { - a = astATan2d(x/r, dy/r); - } - - *phi = a*prj->w[1]; - if (r == 0.0) { - if (prj->w[0] < 0.0) { - *theta = -90.0; - } else { - return 2; - } - } else { - *theta = 90.0 - 2.0*astATand(pow(r*prj->w[4],prj->w[1])); - } - - return 0; -} - -/*============================================================================ -* BON: Bonne's projection. -* -* Given: -* prj->p[1] Bonne conformal latitude, theta1, in degrees. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "BON" -* prj->flag BON -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[1] r0*pi/180 -* prj->w[2] Y0 = r0*(cot(theta1) + theta1*pi/180) -* prj->astPRJfwd Pointer to astBONfwd(). -* prj->astPRJrev Pointer to astBONrev(). -*===========================================================================*/ - -int astBONset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "BON"); - prj->flag = WCS__BON; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[1] = 1.0; - prj->w[2] = prj->r0*astCosd(prj->p[1])/astSind(prj->p[1]) + prj->p[1]; - } else { - prj->w[1] = prj->r0*D2R; - prj->w[2] = prj->r0*(astCosd(prj->p[1])/astSind(prj->p[1]) + prj->p[1]*D2R); - } - - prj->astPRJfwd = astBONfwd; - prj->astPRJrev = astBONrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astBONfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double a, r; - - if (prj->p[1] == 0.0) { - /* Sanson-Flamsteed. */ - return astSFLfwd(phi, theta, prj, x, y); - } - - if (prj->flag != WCS__BON) { - if (astBONset(prj)) return 1; - } - - r = prj->w[2] - theta*prj->w[1]; - a = prj->r0*phi*astCosd(theta)/r; - - *x = r*astSind(a); - *y = prj->w[2] - r*astCosd(a); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astBONrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double a, cthe, dy, r; - - if (prj->p[1] == 0.0) { - /* Sanson-Flamsteed. */ - return astSFLrev(x, y, prj, phi, theta); - } - - if (prj->flag != WCS__BON) { - if (astBONset(prj)) return 1; - } - - dy = prj->w[2] - y; - r = sqrt(x*x + dy*dy); - if (prj->p[1] < 0.0) r = -r; - - if (r == 0.0) { - a = 0.0; - } else { - a = astATan2d(x/r, dy/r); - } - - *theta = (prj->w[2] - r)/prj->w[1]; - cthe = astCosd(*theta); - if (cthe == 0.0) { - *phi = 0.0; - } else { - *phi = a*(r/prj->r0)/cthe; - } - - return 0; -} - -/*============================================================================ -* PCO: polyconic projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "PCO" -* prj->flag PCO -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*(pi/180) -* prj->w[1] 1/r0 -* prj->w[2] 2*r0 -* prj->astPRJfwd Pointer to astPCOfwd(). -* prj->astPRJrev Pointer to astPCOrev(). -*===========================================================================*/ - -int astPCOset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "PCO"); - prj->flag = WCS__PCO; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 1.0; - prj->w[1] = 1.0; - prj->w[2] = 360.0/PI; - } else { - prj->w[0] = prj->r0*D2R; - prj->w[1] = 1.0/prj->w[0]; - prj->w[2] = 2.0*prj->r0; - } - - prj->astPRJfwd = astPCOfwd; - prj->astPRJrev = astPCOrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astPCOfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double a, cthe, cotthe, sthe; - - if (prj->flag != WCS__PCO) { - if (astPCOset(prj)) return 1; - } - - cthe = astCosd(theta); - sthe = astSind(theta); - a = phi*sthe; - - if (sthe == 0.0) { - *x = prj->w[0]*phi; - *y = 0.0; - } else { - cotthe = cthe/sthe; - *x = prj->r0*cotthe*astSind(a); - *y = prj->r0*(cotthe*(1.0 - astCosd(a)) + theta*D2R); - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astPCOrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - int j; - double f, fneg, fpos, lambda, tanthe, theneg, thepos, w, xp, xx, ymthe, yp; - const double tol = 1.0e-12; - - if (prj->flag != WCS__PCO) { - if (astPCOset(prj)) return 1; - } - - w = fabs(y*prj->w[1]); - if (w < tol) { - *phi = x*prj->w[1]; - *theta = 0.0; - } else if (fabs(w-90.0) < tol) { - *phi = 0.0; - *theta = copysign(90.0,y); - } else { - /* Iterative solution using weighted division of the interval. */ - if (y > 0.0) { - thepos = 90.0; - } else { - thepos = -90.0; - } - theneg = 0.0; - - xx = x*x; - ymthe = y - prj->w[0]*thepos; - fpos = xx + ymthe*ymthe; - fneg = -999.0; - - for (j = 0; j < 64; j++) { - if (fneg < -100.0) { - /* Equal division of the interval. */ - *theta = (thepos+theneg)/2.0; - } else { - /* Weighted division of the interval. */ - lambda = fpos/(fpos-fneg); - if (lambda < 0.1) { - lambda = 0.1; - } else if (lambda > 0.9) { - lambda = 0.9; - } - *theta = thepos - lambda*(thepos-theneg); - } - - /* Compute the residue. */ - ymthe = y - prj->w[0]*(*theta); - tanthe = astTand(*theta); - f = xx + ymthe*(ymthe - prj->w[2]/tanthe); - - /* Check for convergence. */ - if (fabs(f) < tol) break; - if (fabs(thepos-theneg) < tol) break; - - /* Redefine the interval. */ - if (f > 0.0) { - thepos = *theta; - fpos = f; - } else { - theneg = *theta; - fneg = f; - } - } - - xp = prj->r0 - ymthe*tanthe; - yp = x*tanthe; - if (xp == 0.0 && yp == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(yp, xp)/astSind(*theta); - } - } - - return 0; -} - -/*============================================================================ -* TSC: tangential spherical cube projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "TSC" -* prj->flag TSC -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*(pi/4) -* prj->w[1] (4/pi)/r0 -* prj->astPRJfwd Pointer to astTSCfwd(). -* prj->astPRJrev Pointer to astTSCrev(). -*===========================================================================*/ - -int astTSCset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "TSC"); - prj->flag = WCS__TSC; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 45.0; - prj->w[1] = 1.0/45.0; - } else { - prj->w[0] = prj->r0*PI/4.0; - prj->w[1] = 1.0/prj->w[0]; - } - - prj->astPRJfwd = astTSCfwd; - prj->astPRJrev = astTSCrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astTSCfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - int face; - double cthe, l, m, n, rho, x0, xf, y0, yf; - const double tol = 1.0e-12; - - x0 = 0.0; - xf = 0.0; - y0 = 0.0; - yf = 0.0; - - if (prj->flag != WCS__TSC) { - if (astTSCset(prj)) return 1; - } - - cthe = astCosd(theta); - l = cthe*astCosd(phi); - m = cthe*astSind(phi); - n = astSind(theta); - - face = 0; - rho = n; - if (l > rho) { - face = 1; - rho = l; - } - if (m > rho) { - face = 2; - rho = m; - } - if (-l > rho) { - face = 3; - rho = -l; - } - if (-m > rho) { - face = 4; - rho = -m; - } - if (-n > rho) { - face = 5; - rho = -n; - } - - if (face == 0) { - xf = m/rho; - yf = -l/rho; - x0 = 0.0; - y0 = 2.0; - } else if (face == 1) { - xf = m/rho; - yf = n/rho; - x0 = 0.0; - y0 = 0.0; - } else if (face == 2) { - xf = -l/rho; - yf = n/rho; - x0 = 2.0; - y0 = 0.0; - } else if (face == 3) { - xf = -m/rho; - yf = n/rho; - x0 = 4.0; - y0 = 0.0; - } else if (face == 4) { - xf = l/rho; - yf = n/rho; - x0 = 6.0; - y0 = 0.0; - } else if (face == 5) { - xf = m/rho; - yf = l/rho; - x0 = 0.0; - y0 = -2.0; - } - - if (fabs(xf) > 1.0) { - if (fabs(xf) > 1.0+tol) { - return 2; - } - xf = copysign(1.0,xf); - } - if (fabs(yf) > 1.0) { - if (fabs(yf) > 1.0+tol) { - return 2; - } - yf = copysign(1.0,yf); - } - - *x = prj->w[0]*(xf + x0); - *y = prj->w[0]*(yf + y0); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astTSCrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double l, m, n, xf, yf; - - if (prj->flag != WCS__TSC) { - if (astTSCset(prj)) return 1; - } - - xf = x*prj->w[1]; - yf = y*prj->w[1]; - - /* Check bounds. */ - if (fabs(xf) <= 1.0) { - if (fabs(yf) > 3.0) return 2; - } else { - if (fabs(xf) > 7.0) return 2; - if (fabs(yf) > 1.0) return 2; - } - - /* Map negative faces to the other side. */ - if (xf < -1.0) xf += 8.0; - - /* Determine the face. */ - if (xf > 5.0) { - /* face = 4 */ - xf = xf - 6.0; - m = -1.0/sqrt(1.0 + xf*xf + yf*yf); - l = -m*xf; - n = -m*yf; - } else if (xf > 3.0) { - /* face = 3 */ - xf = xf - 4.0; - l = -1.0/sqrt(1.0 + xf*xf + yf*yf); - m = l*xf; - n = -l*yf; - } else if (xf > 1.0) { - /* face = 2 */ - xf = xf - 2.0; - m = 1.0/sqrt(1.0 + xf*xf + yf*yf); - l = -m*xf; - n = m*yf; - } else if (yf > 1.0) { - /* face = 0 */ - yf = yf - 2.0; - n = 1.0/sqrt(1.0 + xf*xf + yf*yf); - l = -n*yf; - m = n*xf; - } else if (yf < -1.0) { - /* face = 5 */ - yf = yf + 2.0; - n = -1.0/sqrt(1.0 + xf*xf + yf*yf); - l = -n*yf; - m = -n*xf; - } else { - /* face = 1 */ - l = 1.0/sqrt(1.0 + xf*xf + yf*yf); - m = l*xf; - n = l*yf; - } - - if (l == 0.0 && m == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(m, l); - } - *theta = astASind(n); - - return 0; -} - -/*============================================================================ -* CSC: COBE quadrilateralized spherical cube projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "CSC" -* prj->flag CSC -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*(pi/4) -* prj->w[1] (4/pi)/r0 -* prj->astPRJfwd Pointer to astCSCfwd(). -* prj->astPRJrev Pointer to astCSCrev(). -*===========================================================================*/ - -int astCSCset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "CSC"); - prj->flag = WCS__CSC; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 45.0; - prj->w[1] = 1.0/45.0; - } else { - prj->w[0] = prj->r0*PI/4.0; - prj->w[1] = 1.0/prj->w[0]; - } - - prj->astPRJfwd = astCSCfwd; - prj->astPRJrev = astCSCrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCSCfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - int face; - float cthe, eta, l, m, n, rho, xi; - const float tol = 1.0e-7; - - float a, a2, a2b2, a4, ab, b, b2, b4, ca2, cb2, x0, xf, y0, yf; - const float gstar = 1.37484847732; - const float mm = 0.004869491981; - const float gamma = -0.13161671474; - const float omega1 = -0.159596235474; - const float d0 = 0.0759196200467; - const float d1 = -0.0217762490699; - const float c00 = 0.141189631152; - const float c10 = 0.0809701286525; - const float c01 = -0.281528535557; - const float c11 = 0.15384112876; - const float c20 = -0.178251207466; - const float c02 = 0.106959469314; - - eta = 0.0; - xi = 0.0; - x0 = 0.0; - y0 = 0.0; - - if (prj->flag != WCS__CSC) { - if (astCSCset(prj)) return 1; - } - - cthe = astCosd(theta); - l = cthe*astCosd(phi); - m = cthe*astSind(phi); - n = astSind(theta); - - face = 0; - rho = n; - if (l > rho) { - face = 1; - rho = l; - } - if (m > rho) { - face = 2; - rho = m; - } - if (-l > rho) { - face = 3; - rho = -l; - } - if (-m > rho) { - face = 4; - rho = -m; - } - if (-n > rho) { - face = 5; - rho = -n; - } - - if (face == 0) { - xi = m; - eta = -l; - x0 = 0.0; - y0 = 2.0; - } else if (face == 1) { - xi = m; - eta = n; - x0 = 0.0; - y0 = 0.0; - } else if (face == 2) { - xi = -l; - eta = n; - x0 = 2.0; - y0 = 0.0; - } else if (face == 3) { - xi = -m; - eta = n; - x0 = 4.0; - y0 = 0.0; - } else if (face == 4) { - xi = l; - eta = n; - x0 = 6.0; - y0 = 0.0; - } else if (face == 5) { - xi = m; - eta = l; - x0 = 0.0; - y0 = -2.0; - } - - a = xi/rho; - b = eta/rho; - - a2 = a*a; - b2 = b*b; - ca2 = 1.0 - a2; - cb2 = 1.0 - b2; - - /* Avoid floating underflows. */ - ab = fabs(a*b); - a4 = (a2 > 1.0e-16) ? a2*a2 : 0.0; - b4 = (b2 > 1.0e-16) ? b2*b2 : 0.0; - a2b2 = (ab > 1.0e-16) ? a2*b2 : 0.0; - - xf = a*(a2 + ca2*(gstar + b2*(gamma*ca2 + mm*a2 + - cb2*(c00 + c10*a2 + c01*b2 + c11*a2b2 + c20*a4 + c02*b4)) + - a2*(omega1 - ca2*(d0 + d1*a2)))); - yf = b*(b2 + cb2*(gstar + a2*(gamma*cb2 + mm*b2 + - ca2*(c00 + c10*b2 + c01*a2 + c11*a2b2 + c20*b4 + c02*a4)) + - b2*(omega1 - cb2*(d0 + d1*b2)))); - - if (fabs(xf) > 1.0) { - if (fabs(xf) > 1.0+tol) { - return 2; - } - xf = copysign(1.0,xf); - } - if (fabs(yf) > 1.0) { - if (fabs(yf) > 1.0+tol) { - return 2; - } - yf = copysign(1.0,yf); - } - - *x = prj->w[0]*(x0 + xf); - *y = prj->w[0]*(y0 + yf); - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astCSCrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - int face; - float l, m, n; - - float a, b, xf, xx, yf, yy, z0, z1, z2, z3, z4, z5, z6; - const float p00 = -0.27292696; - const float p10 = -0.07629969; - const float p20 = -0.22797056; - const float p30 = 0.54852384; - const float p40 = -0.62930065; - const float p50 = 0.25795794; - const float p60 = 0.02584375; - const float p01 = -0.02819452; - const float p11 = -0.01471565; - const float p21 = 0.48051509; - const float p31 = -1.74114454; - const float p41 = 1.71547508; - const float p51 = -0.53022337; - const float p02 = 0.27058160; - const float p12 = -0.56800938; - const float p22 = 0.30803317; - const float p32 = 0.98938102; - const float p42 = -0.83180469; - const float p03 = -0.60441560; - const float p13 = 1.50880086; - const float p23 = -0.93678576; - const float p33 = 0.08693841; - const float p04 = 0.93412077; - const float p14 = -1.41601920; - const float p24 = 0.33887446; - const float p05 = -0.63915306; - const float p15 = 0.52032238; - const float p06 = 0.14381585; - - l = 0.0; - m = 0.0; - n = 0.0; - - if (prj->flag != WCS__CSC) { - if (astCSCset(prj)) return 1; - } - - xf = x*prj->w[1]; - yf = y*prj->w[1]; - - /* Check bounds. */ - if (fabs(xf) <= 1.0) { - if (fabs(yf) > 3.0) return 2; - } else { - if (fabs(xf) > 7.0) return 2; - if (fabs(yf) > 1.0) return 2; - } - - /* Map negative faces to the other side. */ - if (xf < -1.0) xf += 8.0; - - /* Determine the face. */ - if (xf > 5.0) { - face = 4; - xf = xf - 6.0; - } else if (xf > 3.0) { - face = 3; - xf = xf - 4.0; - } else if (xf > 1.0) { - face = 2; - xf = xf - 2.0; - } else if (yf > 1.0) { - face = 0; - yf = yf - 2.0; - } else if (yf < -1.0) { - face = 5; - yf = yf + 2.0; - } else { - face = 1; - } - - xx = xf*xf; - yy = yf*yf; - - z0 = p00 + xx*(p10 + xx*(p20 + xx*(p30 + xx*(p40 + xx*(p50 + xx*(p60)))))); - z1 = p01 + xx*(p11 + xx*(p21 + xx*(p31 + xx*(p41 + xx*(p51))))); - z2 = p02 + xx*(p12 + xx*(p22 + xx*(p32 + xx*(p42)))); - z3 = p03 + xx*(p13 + xx*(p23 + xx*(p33))); - z4 = p04 + xx*(p14 + xx*(p24)); - z5 = p05 + xx*(p15); - z6 = p06; - - a = z0 + yy*(z1 + yy*(z2 + yy*(z3 + yy*(z4 + yy*(z5 + yy*z6))))); - a = xf + xf*(1.0 - xx)*a; - - z0 = p00 + yy*(p10 + yy*(p20 + yy*(p30 + yy*(p40 + yy*(p50 + yy*(p60)))))); - z1 = p01 + yy*(p11 + yy*(p21 + yy*(p31 + yy*(p41 + yy*(p51))))); - z2 = p02 + yy*(p12 + yy*(p22 + yy*(p32 + yy*(p42)))); - z3 = p03 + yy*(p13 + yy*(p23 + yy*(p33))); - z4 = p04 + yy*(p14 + yy*(p24)); - z5 = p05 + yy*(p15); - z6 = p06; - - b = z0 + xx*(z1 + xx*(z2 + xx*(z3 + xx*(z4 + xx*(z5 + xx*z6))))); - b = yf + yf*(1.0 - yy)*b; - - if (face == 0) { - n = 1.0/sqrt(a*a + b*b + 1.0); - l = -b*n; - m = a*n; - } else if (face == 1) { - l = 1.0/sqrt(a*a + b*b + 1.0); - m = a*l; - n = b*l; - } else if (face == 2) { - m = 1.0/sqrt(a*a + b*b + 1.0); - l = -a*m; - n = b*m; - } else if (face == 3) { - l = -1.0/sqrt(a*a + b*b + 1.0); - m = a*l; - n = -b*l; - } else if (face == 4) { - m = -1.0/sqrt(a*a + b*b + 1.0); - l = -a*m; - n = -b*m; - } else if (face == 5) { - n = -1.0/sqrt(a*a + b*b + 1.0); - l = -b*n; - m = -a*n; - } - - if (l == 0.0 && m == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(m, l); - } - *theta = astASind(n); - - return 0; -} - -/*============================================================================ -* QSC: quadrilaterilized spherical cube projection. -* -* Given and/or returned: -* prj->r0 r0; reset to 180/pi if 0. -* -* Returned: -* prj->code "QSC" -* prj->flag QSC -* prj->phi0 0.0 -* prj->theta0 0.0 -* prj->w[0] r0*(pi/4) -* prj->w[1] (4/pi)/r0 -* prj->astPRJfwd Pointer to astQSCfwd(). -* prj->astPRJrev Pointer to astQSCrev(). -*===========================================================================*/ - -int astQSCset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "QSC"); - prj->flag = WCS__QSC; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 45.0; - prj->w[1] = 1.0/45.0; - } else { - prj->w[0] = prj->r0*PI/4.0; - prj->w[1] = 1.0/prj->w[0]; - } - - prj->astPRJfwd = astQSCfwd; - prj->astPRJrev = astQSCrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astQSCfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - int face; - double cthe, eta, l, m, n, omega, p, rho, rhu, t, tau, x0, xf, xi, y0, yf; - const double tol = 1.0e-12; - - eta = 0.0; - x0 = 0.0; - xf = 0.0; - xi = 0.0; - y0 = 0.0; - yf = 0.0; - - if (prj->flag != WCS__QSC) { - if (astQSCset(prj)) return 1; - } - - if (fabs(theta) == 90.0) { - *x = 0.0; - *y = copysign(2.0*prj->w[0],theta); - return 0; - } - - cthe = astCosd(theta); - l = cthe*astCosd(phi); - m = cthe*astSind(phi); - n = astSind(theta); - - face = 0; - rho = n; - if (l > rho) { - face = 1; - rho = l; - } - if (m > rho) { - face = 2; - rho = m; - } - if (-l > rho) { - face = 3; - rho = -l; - } - if (-m > rho) { - face = 4; - rho = -m; - } - if (-n > rho) { - face = 5; - rho = -n; - } - - rhu = 1.0 - rho; - - if (face == 0) { - xi = m; - eta = -l; - if (rhu < 1.0e-8) { - /* Small angle formula. */ - t = (90.0 - theta)*D2R; - rhu = t*t/2.0; - } - x0 = 0.0; - y0 = 2.0; - } else if (face == 1) { - xi = m; - eta = n; - if (rhu < 1.0e-8) { - /* Small angle formula. */ - t = theta*D2R; - p = fmod(phi,360.0); - if (p < -180.0) p += 360.0; - if (p > 180.0) p -= 360.0; - p *= D2R; - rhu = (p*p + t*t)/2.0; - } - x0 = 0.0; - y0 = 0.0; - } else if (face == 2) { - xi = -l; - eta = n; - if (rhu < 1.0e-8) { - /* Small angle formula. */ - t = theta*D2R; - p = fmod(phi,360.0); - if (p < -180.0) p += 360.0; - p = (90.0 - p)*D2R; - rhu = (p*p + t*t)/2.0; - } - x0 = 2.0; - y0 = 0.0; - } else if (face == 3) { - xi = -m; - eta = n; - if (rhu < 1.0e-8) { - /* Small angle formula. */ - t = theta*D2R; - p = fmod(phi,360.0); - if (p < 0.0) p += 360.0; - p = (180.0 - p)*D2R; - rhu = (p*p + t*t)/2.0; - } - x0 = 4.0; - y0 = 0.0; - } else if (face == 4) { - xi = l; - eta = n; - if (rhu < 1.0e-8) { - /* Small angle formula. */ - t = theta*D2R; - p = fmod(phi,360.0); - if (p > 180.0) p -= 360.0; - p *= (90.0 + p)*D2R; - rhu = (p*p + t*t)/2.0; - } - x0 = 6; - y0 = 0.0; - } else if (face == 5) { - xi = m; - eta = l; - if (rhu < 1.0e-8) { - /* Small angle formula. */ - t = (90.0 + theta)*D2R; - rhu = t*t/2.0; - } - x0 = 0.0; - y0 = -2; - } - - if (xi == 0.0 && eta == 0.0) { - xf = 0.0; - yf = 0.0; - } else if (-xi >= fabs(eta)) { - omega = eta/xi; - tau = 1.0 + omega*omega; - xf = -sqrt(rhu/(1.0-1.0/sqrt(1.0+tau))); - yf = (xf/15.0)*(astATand(omega) - astASind(omega/sqrt(tau+tau))); - } else if (xi >= fabs(eta)) { - omega = eta/xi; - tau = 1.0 + omega*omega; - xf = sqrt(rhu/(1.0-1.0/sqrt(1.0+tau))); - yf = (xf/15.0)*(astATand(omega) - astASind(omega/sqrt(tau+tau))); - } else if (-eta > fabs(xi)) { - omega = xi/eta; - tau = 1.0 + omega*omega; - yf = -sqrt(rhu/(1.0-1.0/sqrt(1.0+tau))); - xf = (yf/15.0)*(astATand(omega) - astASind(omega/sqrt(tau+tau))); - } else if (eta > fabs(xi)) { - omega = xi/eta; - tau = 1.0 + omega*omega; - yf = sqrt(rhu/(1.0-1.0/sqrt(1.0+tau))); - xf = (yf/15.0)*(astATand(omega) - astASind(omega/sqrt(tau+tau))); - } - - if (fabs(xf) > 1.0) { - if (fabs(xf) > 1.0+tol) { - return 2; - } - xf = copysign(1.0,xf); - } - if (fabs(yf) > 1.0) { - if (fabs(yf) > 1.0+tol) { - return 2; - } - yf = copysign(1.0,yf); - } - - *x = prj->w[0]*(xf + x0); - *y = prj->w[0]*(yf + y0); - - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astQSCrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - int direct, face; - double l, m, n, omega, rho, rhu, tau, xf, yf, w; - const double tol = 1.0e-12; - - l = 0.0; - m = 0.0; - n = 0.0; - - if (prj->flag != WCS__QSC) { - if (astQSCset(prj)) return 1; - } - - xf = x*prj->w[1]; - yf = y*prj->w[1]; - - /* Check bounds. */ - if (fabs(xf) <= 1.0) { - if (fabs(yf) > 3.0) return 2; - } else { - if (fabs(xf) > 7.0) return 2; - if (fabs(yf) > 1.0) return 2; - } - - /* Map negative faces to the other side. */ - if (xf < -1.0) xf += 8.0; - - /* Determine the face. */ - if (xf > 5.0) { - face = 4; - xf = xf - 6.0; - } else if (xf > 3.0) { - face = 3; - xf = xf - 4.0; - } else if (xf > 1.0) { - face = 2; - xf = xf - 2.0; - } else if (yf > 1.0) { - face = 0; - yf = yf - 2.0; - } else if (yf < -1.0) { - face = 5; - yf = yf + 2.0; - } else { - face = 1; - } - - direct = (fabs(xf) > fabs(yf)); - if (direct) { - if (xf == 0.0) { - omega = 0.0; - tau = 1.0; - rho = 1.0; - rhu = 0.0; - } else { - w = 15.0*yf/xf; - omega = astSind(w)/(astCosd(w) - SQRT2INV); - tau = 1.0 + omega*omega; - rhu = xf*xf*(1.0 - 1.0/sqrt(1.0 + tau)); - rho = 1.0 - rhu; - } - } else { - if (yf == 0.0) { - omega = 0.0; - tau = 1.0; - rho = 1.0; - rhu = 0.0; - } else { - w = 15.0*xf/yf; - omega = astSind(w)/(astCosd(w) - SQRT2INV); - tau = 1.0 + omega*omega; - rhu = yf*yf*(1.0 - 1.0/sqrt(1.0 + tau)); - rho = 1.0 - rhu; - } - } - - if (rho < -1.0) { - if (rho < -1.0-tol) { - return 2; - } - - rho = -1.0; - rhu = 2.0; - w = 0.0; - } else { - w = sqrt(rhu*(2.0-rhu)/tau); - } - - if (face == 0) { - n = rho; - if (direct) { - m = w; - if (xf < 0.0) m = -m; - l = -m*omega; - } else { - l = w; - if (yf > 0.0) l = -l; - m = -l*omega; - } - } else if (face == 1) { - l = rho; - if (direct) { - m = w; - if (xf < 0.0) m = -m; - n = m*omega; - } else { - n = w; - if (yf < 0.0) n = -n; - m = n*omega; - } - } else if (face == 2) { - m = rho; - if (direct) { - l = w; - if (xf > 0.0) l = -l; - n = -l*omega; - } else { - n = w; - if (yf < 0.0) n = -n; - l = -n*omega; - } - } else if (face == 3) { - l = -rho; - if (direct) { - m = w; - if (xf > 0.0) m = -m; - n = -m*omega; - } else { - n = w; - if (yf < 0.0) n = -n; - m = -n*omega; - } - } else if (face == 4) { - m = -rho; - if (direct) { - l = w; - if (xf < 0.0) l = -l; - n = l*omega; - } else { - n = w; - if (yf < 0.0) n = -n; - l = n*omega; - } - } else if (face == 5) { - n = -rho; - if (direct) { - m = w; - if (xf < 0.0) m = -m; - l = m*omega; - } else { - l = w; - if (yf < 0.0) l = -l; - m = l*omega; - } - } - - if (l == 0.0 && m == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(m, l); - } - *theta = astASind(n); - - return 0; -} - -/*============================================================================ -* HPX: HEALPix projection. -* -* Given: -* prj->p[1] H - the number of facets in longitude. -* prj->p[2] K - the number of facets in latitude -* -* Given and/or returned: -* prj->r0 Reset to 180/pi if 0. -* prj->phi0 Reset to 0.0 -* prj->theta0 Reset to 0.0 -* -* Returned: -* prj->flag HPX -* prj->code "HPX" -* prj->n True if K is odd. -* prj->w[0] r0*(pi/180) -* prj->w[1] (180/pi)/r0 -* prj->w[2] (K-1)/K -* prj->w[3] 90*K/H -* prj->w[4] (K+1)/2 -* prj->w[5] 90*(K-1)/H -* prj->w[6] 180/H -* prj->w[7] H/360 -* prj->w[8] (90*K/H)*r0*(pi/180) -* prj->w[9] (180/H)*r0*(pi/180) -* prj->astPRJfwd Pointer to astHPXfwd(). -* prj->astPRJrev Pointer to astHPXrev(). - - -*===========================================================================*/ - -int astHPXset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "HPX"); - prj->flag = WCS__HPX; - prj->phi0 = 0.0; - prj->theta0 = 0.0; - - prj->n = ((int)prj->p[2])%2; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 1.0; - prj->w[1] = 1.0; - } else { - prj->w[0] = prj->r0*D2R; - prj->w[1] = R2D/prj->r0; - } - - prj->w[2] = (prj->p[2] - 1.0) / prj->p[2]; - prj->w[3] = 90.0 * prj->p[2] / prj->p[1]; - prj->w[4] = (prj->p[2] + 1.0) / 2.0; - prj->w[5] = 90.0 * (prj->p[2] - 1.0) / prj->p[1]; - prj->w[6] = 180.0 / prj->p[1]; - prj->w[7] = prj->p[1] / 360.0; - prj->w[8] = prj->w[3] * prj->w[0]; - prj->w[9] = prj->w[6] * prj->w[0]; - - prj->astPRJfwd = astHPXfwd; - prj->astPRJrev = astHPXrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astHPXfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double abssin, sigma, sinthe, phic; - int hodd; - - if( prj->flag != WCS__HPX ) { - if( astHPXset( prj ) ) return 1; - } - - sinthe = astSind( theta ); - abssin = fabs( sinthe ); - -/* Equatorial zone */ - if( abssin <= prj->w[2] ) { - *x = prj->w[0] * phi; - *y = prj->w[8] * sinthe; - -/* Polar zone */ - } else { - -/* DSB - The expression for phic is conditioned differently to the - WCSLIB code in order to improve accuracy of the floor function for - arguments very slightly below an integer value. */ - hodd = ((int)prj->p[1]) % 2; - if( !prj->n && theta <= 0.0 ) hodd = 1 - hodd; - if( hodd ) { - phic = -180.0 + (2.0*floor( prj->w[7] * phi + 1/2 ) + prj->p[1] ) * prj->w[6]; - } else { - phic = -180.0 + (2.0*floor( prj->w[7] * phi ) + prj->p[1] + 1 ) * prj->w[6]; - } - - sigma = sqrt( prj->p[2]*( 1.0 - abssin )); - - *x = prj->w[0] *( phic + ( phi - phic )*sigma ); - - *y = prj->w[9] * ( prj->w[4] - sigma ); - if( theta < 0 ) *y = -*y; - - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astHPXrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double absy, sigma, t, yr, xc; - int hodd; - - if (prj->flag != WCS__HPX) { - if (astHPXset(prj)) return 1; - } - - yr = prj->w[1]*y; - absy = fabs( yr ); - -/* Equatorial zone */ - if( absy <= prj->w[5] ) { - *phi = prj->w[1] * x; - t = yr/prj->w[3]; - if( t < -1.0 || t > 1.0 ) { - return 2; - } else { - *theta = astASind( t ); - } - -/* Polar zone */ - } else if( absy <= 90 ){ - - -/* DSB - The expression for xc is conditioned differently to the - WCSLIB code in order to improve accuracy of the floor function for - arguments very slightly below an integer value. */ - hodd = ((int)prj->p[1]) % 2; - if( !prj->n && yr <= 0.0 ) hodd = 1 - hodd; - if( hodd ) { - xc = -180.0 + (2.0*floor( prj->w[7] * x + 1/2 ) + prj->p[1] ) * prj->w[6]; - } else { - xc = -180.0 + (2.0*floor( prj->w[7] * x ) + prj->p[1] + 1 ) * prj->w[6]; - } - - sigma = prj->w[4] - absy / prj->w[6]; - - if( sigma == 0.0 ) { - return 2; - } else { - - t = ( x - xc )/sigma; - if( fabs( t ) <= prj->w[6] ) { - *phi = prj->w[1] *( xc + t ); - } else { - return 2; - } - } - - t = 1.0 - sigma*sigma/prj->p[2]; - if( t < -1.0 || t > 1.0 ) { - return 2; - } else { - *theta = astASind( t ); - if( y < 0 ) *theta = -*theta; - } - - } else { - return 2; - } - - return 0; -} - -/*============================================================================ -* XPH: HEALPix polar, aka "butterfly" projection. -* -* Given and/or returned: -* prj->r0 Reset to 180/pi if 0. -* prj->phi0 Reset to 0.0 if undefined. -* prj->theta0 Reset to 0.0 if undefined. -* -* Returned: -* prj->flag XPH -* prj->code "XPH" -* prj->w[0] r0*(pi/180)/sqrt(2) -* prj->w[1] (180/pi)/r0/sqrt(2) -* prj->w[2] 2/3 -* prj->w[3] tol (= 1e-4) -* prj->w[4] sqrt(2/3)*(180/pi) -* prj->w[5] 90 - tol*sqrt(2/3)*(180/pi) -* prj->w[6] sqrt(3/2)*(pi/180) -* prj->astPRJfwd Pointer to astXPHfwd(). -* prj->astPRJrev Pointer to astXPHrev(). -*===========================================================================*/ - -int astXPHset(prj) - -struct AstPrjPrm *prj; - -{ - strcpy(prj->code, "XPH"); - prj->flag = WCS__XPH; - - if (prj->r0 == 0.0) { - prj->r0 = R2D; - prj->w[0] = 1.0; - prj->w[1] = 1.0; - } else { - prj->w[0] = prj->r0*D2R; - prj->w[1] = R2D/prj->r0; - } - - prj->w[0] /= sqrt(2.0); - prj->w[1] /= sqrt(2.0); - prj->w[2] = 2.0/3.0; - prj->w[3] = 1e-4; - prj->w[4] = sqrt(prj->w[2])*R2D; - prj->w[5] = 90.0 - prj->w[3]*prj->w[4]; - prj->w[6] = sqrt(1.5)*D2R; - - prj->astPRJfwd = astXPHfwd; - prj->astPRJrev = astXPHrev; - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astXPHfwd(phi, theta, prj, x, y) - -const double phi, theta; -struct AstPrjPrm *prj; -double *x, *y; - -{ - double abssin, chi, eta, psi, sigma, sinthe, xi; - - if (prj->flag != WCS__XPH) { - if (astXPHset(prj)) return 1; - } - - /* Do phi dependence. */ - chi = phi; - if (180.0 <= fabs(chi)) { - chi = fmod(chi, 360.0); - if (chi < -180.0) { - chi += 360.0; - } else if (180.0 <= chi) { - chi -= 360.0; - } - } - - /* phi is also recomputed from chi to avoid rounding problems. */ - chi += 180.0; - psi = fmod(chi, 90.0); - - /* y is used to hold phi (rounded). */ - *x = psi; - *y = chi - 180.0; - - /* Do theta dependence. */ - sinthe = astSind(theta); - abssin = fabs(sinthe); - - if (abssin <= prj->w[2]) { - /* Equatorial regime. */ - xi = *x; - eta = 67.5 * sinthe; - - } else { - /* Polar regime. */ - if (theta < prj->w[5]) { - sigma = sqrt(3.0*(1.0 - abssin)); - } else { - sigma = (90.0 - theta)*prj->w[6]; - } - - xi = 45.0 + (*x - 45.0)*sigma; - eta = 45.0 * (2.0 - sigma); - if (theta < 0.0) eta = -eta; - } - - xi -= 45.0; - eta -= 90.0; - - /* Recall that y holds phi. */ - if (*y < -90.0) { - *x = prj->w[0]*(-xi + eta); - *y = prj->w[0]*(-xi - eta); - - } else if (*y < 0.0) { - *x = prj->w[0]*(+xi + eta); - *y = prj->w[0]*(-xi + eta); - - } else if (*y < 90.0) { - *x = prj->w[0]*( xi - eta); - *y = prj->w[0]*( xi + eta); - - } else { - *x = prj->w[0]*(-xi - eta); - *y = prj->w[0]*( xi - eta); - } - - return 0; - -} - -/*--------------------------------------------------------------------------*/ - -int astXPHrev(x, y, prj, phi, theta) - -const double x, y; -struct AstPrjPrm *prj; -double *phi, *theta; - -{ - double abseta, eta, eta1, sigma, xi, xi1, xr, yr; - const double tol = 1.0e-12; - - if (prj->flag != WCS__XPH) { - if (astXPHset(prj)) return 1; - } - - - xr = x*prj->w[1]; - yr = y*prj->w[1]; - if (xr <= 0.0 && 0.0 < yr) { - xi1 = -xr - yr; - eta1 = xr - yr; - *phi = -180.0; - } else if (xr < 0.0 && yr <= 0.0) { - xi1 = xr - yr; - eta1 = xr + yr; - *phi = -90.0; - } else if (0.0 <= xr && yr < 0.0) { - xi1 = xr + yr; - eta1 = -xr + yr; - *phi = 0.0; - } else { - xi1 = -xr + yr; - eta1 = -xr - yr; - *phi = 90.0; - } - - xi = xi1 + 45.0; - eta = eta1 + 90.0; - abseta = fabs(eta); - - if (abseta <= 90.0) { - if (abseta <= 45.0) { - /* Equatorial regime. */ - *phi += xi; - *theta = astASind(eta/67.5); - - /* Bounds checking. */ - if (45.0+tol < fabs(xi1)) return 2; - - } else { - /* Polar regime. */ - sigma = (90.0 - abseta) / 45.0; - - /* Ensure an exact result for points on the boundary. */ - if (xr == 0.0) { - if (yr <= 0.0) { - *phi = 0.0; - } else { - *phi = 180.0; - } - } else if (yr == 0.0) { - if (xr < 0.0) { - *phi = -90.0; - } else { - *phi = 90.0; - } - } else { - *phi += 45.0 + xi1/sigma; - } - - if (sigma < prj->w[3]) { - *theta = 90.0 - sigma*prj->w[4]; - } else { - *theta = astASind(1.0 - sigma*sigma/3.0); - } - if (eta < 0.0) *theta = -(*theta); - - /* Bounds checking. */ - if (eta < -45.0 && eta+90.0+tol < fabs(xi1)) return 2; - } - - } else { - /* Beyond latitude range. */ - *phi = 0.0; - *theta = 0.0; - return 2; - } - - return 0; -} - - diff --git a/ast/proj.h b/ast/proj.h deleted file mode 100644 index 61e4746..0000000 --- a/ast/proj.h +++ /dev/null @@ -1,181 +0,0 @@ -/*============================================================================= -* -* WCSLIB - an implementation of the FITS WCS proposal. -* Copyright (C) 1995-2002, Mark Calabretta -* -* This library is free software; you can redistribute it and/or modify it -* under the terms of the GNU Library General Public License as published -* by the Free Software Foundation; either version 2 of the License, or (at -* your option) any later version. -* -* This library is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library -* General Public License for more details. -* -* You should have received a copy of the GNU Library General Public License -* along with this library; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street,Fifth Floor, Boston, MA 02110-1301, USA -* -* Correspondence concerning WCSLIB may be directed to: -* Internet email: mcalabre@atnf.csiro.au -* Postal address: Dr. Mark Calabretta, -* Australia Telescope National Facility, -* P.O. Box 76, -* Epping, NSW, 2121, -* AUSTRALIA -* -* Author: Mark Calabretta, Australia Telescope National Facility -* $Id$ -*============================================================================= -* -* This version of proj.h is based on the version in wcslib-2.9, but has -* been modified in the following ways by the Starlink project (e-mail: -* ussc@star.rl.ac.uk): -* - Support for non-ANSI C prototypes removed -* - Changed the name of the WCSLIB_PROJ macro to WCSLIB_PROJ_INCLUDED -* - Changed names of all functions and structures to avoid name -* clashes with wcslib. -* - Change the maximum number of projection parameters to 100. -* - Added definition of macro WCSLIB_MXPAR, and use it to define -* size of projection parameter array within AstPrjPrm structure. -* - Added component "p2" to the AstPrjPrm structure to hold projection -* parameters associated with the longitude axis (for use within -* the tpn.c file which holds an implementation of the old "TAN with -* correction terms" projection). -* - Added prototypes for TPN projection functions (defined in file -* tpn.c). -* - Added prototypes for HPX projection functions. -* - Added prototypes for XPH projection functions. -*===========================================================================*/ - -#ifndef WCSLIB_PROJ_INCLUDED -#define WCSLIB_PROJ_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - -#define WCSLIB_MXPAR 100 - -extern int npcode; -extern char pcodes[26][4]; - -struct AstPrjPrm { - char code[4]; - int flag; - double phi0, theta0; - double r0; - double *p; - double *p2; - double w[20]; - int n; - int (*astPRJfwd)(const double, const double, - struct AstPrjPrm *, - double *, double *); - int (*astPRJrev)(const double, const double, - struct AstPrjPrm *, - double *, double *); -}; - - int astPRJset(const char [], struct AstPrjPrm *); - int astPRJfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astPRJrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astAZPset(struct AstPrjPrm *); - int astAZPfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astAZPrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astSZPset(struct AstPrjPrm *); - int astSZPfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astSZPrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astTANset(struct AstPrjPrm *); - int astTANfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astTANrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astSTGset(struct AstPrjPrm *); - int astSTGfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astSTGrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astSINset(struct AstPrjPrm *); - int astSINfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astSINrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astARCset(struct AstPrjPrm *); - int astARCfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astARCrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astZPNset(struct AstPrjPrm *); - int astZPNfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astZPNrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astZEAset(struct AstPrjPrm *); - int astZEAfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astZEArev(const double, const double, struct AstPrjPrm *, double *, double *); - int astAIRset(struct AstPrjPrm *); - int astAIRfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astAIRrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astCYPset(struct AstPrjPrm *); - int astCYPfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astCYPrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astCEAset(struct AstPrjPrm *); - int astCEAfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astCEArev(const double, const double, struct AstPrjPrm *, double *, double *); - int astCARset(struct AstPrjPrm *); - int astCARfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astCARrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astMERset(struct AstPrjPrm *); - int astMERfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astMERrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astSFLset(struct AstPrjPrm *); - int astSFLfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astSFLrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astPARset(struct AstPrjPrm *); - int astPARfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astPARrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astMOLset(struct AstPrjPrm *); - int astMOLfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astMOLrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astAITset(struct AstPrjPrm *); - int astAITfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astAITrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astCOPset(struct AstPrjPrm *); - int astCOPfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astCOPrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astCOEset(struct AstPrjPrm *); - int astCOEfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astCOErev(const double, const double, struct AstPrjPrm *, double *, double *); - int astCODset(struct AstPrjPrm *); - int astCODfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astCODrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astCOOset(struct AstPrjPrm *); - int astCOOfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astCOOrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astBONset(struct AstPrjPrm *); - int astBONfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astBONrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astPCOset(struct AstPrjPrm *); - int astPCOfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astPCOrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astTSCset(struct AstPrjPrm *); - int astTSCfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astTSCrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astCSCset(struct AstPrjPrm *); - int astCSCfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astCSCrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astQSCset(struct AstPrjPrm *); - int astQSCfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astQSCrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astHPXset(struct AstPrjPrm *); - int astHPXfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astHPXrev(const double, const double, struct AstPrjPrm *, double *, double *); - int astXPHset(struct AstPrjPrm *); - int astXPHfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astXPHrev(const double, const double, struct AstPrjPrm *, double *, double *); - - int astTPNset(struct AstPrjPrm *); - int astTPNfwd(const double, const double, struct AstPrjPrm *, double *, double *); - int astTPNrev(const double, const double, struct AstPrjPrm *, double *, double *); - -extern const char *astPRJset_errmsg[]; -extern const char *astPRJfwd_errmsg[]; -extern const char *astPRJrev_errmsg[]; - -#ifdef __cplusplus -}; -#endif - -#endif /* WCSLIB_PROJ_INCLUDED */ diff --git a/ast/ratemap.c b/ast/ratemap.c deleted file mode 100644 index 1e343a6..0000000 --- a/ast/ratemap.c +++ /dev/null @@ -1,2011 +0,0 @@ -/* -*class++ -* Name: -* RateMap - -* Purpose: -* Mapping which represents differentiation. - -* Constructor Function: -c astRateMap -f AST_RATEMAP - -* Description: -* A RateMap is a Mapping which represents a single element of the -* Jacobian matrix of another Mapping. The Mapping for which the -* Jacobian is required is specified when the new RateMap is created, -* and is referred to as the "encapsulated Mapping" below. -* -* The number of inputs to a RateMap is the same as the number of inputs -* to its encapsulated Mapping. The number of outputs from a RateMap -* is always one. This one output equals the rate of change of a -* specified output of the encapsulated Mapping with respect to a -* specified input of the encapsulated Mapping (the input and output -* to use are specified when the RateMap is created). -* -* A RateMap which has not been inverted does not define an inverse -* transformation. If a RateMap has been inverted then it will define -* an inverse transformation but not a forward transformation. - -* Inheritance: -* The RateMap class inherits from the Mapping class. - -* Attributes: -* The RateMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c The RateMap class does not define any new functions beyond those -f The RateMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 10-FEB-2004 (DSB): -* Original version. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 10-MAY-2006 (DSB): -* Override astEqual. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS RateMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "ratemap.h" /* Interface definition for this class */ -#include "unitmap.h" /* Unit Mappings */ -#include "frame.h" /* Frames */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int *(* parent_mapsplit)( AstMapping *, int, const int *, AstMapping **, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(RateMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(RateMap,Class_Init) -#define class_vtab astGLOBAL(RateMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstRateMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstRateMap *astRateMapId_( void *, int, int, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *RemoveRegions( AstMapping *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetObjSize( AstObject *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two RateMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "ratemap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* RateMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two RateMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a RateMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the RateMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstRateMap *that; - AstRateMap *this; - int nin; - int nout; - int result; - int that_inv; - int this_inv; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two RateMap structures. */ - this = (AstRateMap *) this_object; - that = (AstRateMap *) that_object; - -/* Check the second object is a RateMap. We know the first is a - RateMap since we have arrived at this implementation of the virtual - function. */ - if( astIsARateMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two RateMaps differ, it may still be possible - for them to be equivalent. First compare the RateMaps if their Invert - flags are the same. In this case all the attributes of the two RateMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - -/* Temporarily re-instate the original Invert flag values. */ - this_inv = astGetInvert( this->map ); - that_inv = astGetInvert( that->map ); - astSetInvert( this->map, this->invert ); - astSetInvert( that->map, that->invert ); - - if( astEqual( this->map, that->map ) && - this->iin == that->iin && - this->iout == that->iout ){ - result = 1; - } - -/* Restore the original Invert flag values. */ - astSetInvert( this->map, this_inv ); - astSetInvert( that->map, that_inv ); - -/* If the Invert flags for the two RateMaps differ, the attributes of the two - RateMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a RateMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "ratemap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* RateMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied RateMap, -* in bytes. - -* Parameters: -* this -* Pointer to the RateMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstRateMap *this; /* Pointer to RateMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the RateMap structure. */ - this = (AstRateMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astGetObjSize( this->map ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -void astInitRateMapVtab_( AstRateMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitRateMapVtab - -* Purpose: -* Initialise a virtual function table for a RateMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "ratemap.h" -* void astInitRateMapVtab( AstRateMapVtab *vtab, const char *name ) - -* Class Membership: -* RateMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the RateMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsARateMap) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -/* None. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - mapping->RemoveRegions = RemoveRegions; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_mapsplit = mapping->MapSplit; - mapping->MapSplit = MapSplit; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "RateMap", "Differential Mapping" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* RateMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstRateMap *this; /* Pointer to RateMap structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the RateMap structure. */ - this = (AstRateMap *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->map, mode, extra, fail ); - - return result; - -} -#endif - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a RateMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* RateMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated RateMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated RateMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated RateMap which is to be merged with -* its neighbours. This should be a cloned copy of the RateMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* RateMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated RateMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *emap1; - AstMapping *emap2; - AstMapping *emap; - AstMapping *smap; - AstRateMap *map; - AstRateMap *rmap1; - AstRateMap *rmap2; - int cancel; - int map_inv; - int nax; - int old_inv2; - int old_inv; - int old_winv; - int result; - -/* Initialise. */ - result = -1; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Initialisation to avoid compiler warnings. */ - nax = 0; - -/* Get a pointer to this RateMap. */ - map = (AstRateMap *) this; - -/* Temporarily set its Invert flag to the requested value. */ - map_inv = astGetInvert( map ); - astSetInvert( map, ( *invert_list )[ where ] ); - -/* Get the encapsulated Mapping, and temporarily set its Invert attribute - back to the value it had when the RateMap was created, saving the current - Invert value so that it can be re-instated later. */ - emap = map->map; - old_inv = astGetInvert( emap ); - astSetInvert( emap, map->invert ); - -/* First try to simplify the RateMap by simplifying its encapsulated - Mapping. */ - smap = astSimplify( emap ); - -/* If any simplification took place, create a new RateMap with the - simplified mapping. */ - if( smap != emap ) { - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) astRateMap( smap, map->iout, map->iin, "", status ); - result = where; - -/* The only other simplication which can be performed is to cancel a RateMap - with its own inverse in series. */ - } else if( series ) { - -/* Indicate we have nothing to cancel with as yet. */ - cancel = -1; - -/* First consider the lower neighbour. */ - if( where > 0 && astIsARateMap( ( *map_list )[ where - 1 ] ) ) { - -/* Check the Invert flags are opposite */ - if( ( *invert_list )[ where ] != ( *invert_list )[ where - 1 ] ) { - rmap1 = map; - rmap2 = (AstRateMap *) ( *map_list )[ where - 1 ]; - -/* Check the input and output indices are equal. */ - if( rmap1->iin == rmap2->iin && - rmap1->iout == rmap2->iout ) { - -/* Check the encapsulated Mappings are equal. */ - emap1 = emap; - emap2 = rmap2->map; - old_winv = astGetInvert( rmap2 ); - astSetInvert( rmap2, ( *invert_list )[ where - 1 ] ); - old_inv2 = astGetInvert( emap2 ); - astSetInvert( emap2, rmap2->invert ); - - if( astEqual( emap1, emap2 ) ) cancel = where - 1; - - astSetInvert( emap2, old_inv2 ); - astSetInvert( rmap2, old_winv ); - - nax = astGetNout( rmap1 ); - } - } - } - -/* Likewise consider the upper neighbour. */ - if( cancel == -1 && where + 1 < *nmap && - astIsARateMap( ( *map_list )[ where + 1 ] ) ) { - - if( ( *invert_list )[ where ] != ( *invert_list )[ where + 1 ] ) { - rmap1 = map; - rmap2 = (AstRateMap *) ( *map_list )[ where + 1 ]; - if( rmap1->iin == rmap2->iin && - rmap1->iout == rmap2->iout ) { - emap1 = emap; - emap2 = rmap2->map; - old_winv = astGetInvert( rmap2 ); - astSetInvert( rmap2, ( *invert_list )[ where + 1 ] ); - old_inv2 = astGetInvert( emap2 ); - astSetInvert( emap2, rmap2->invert ); - - if( astEqual( emap1, emap2 ) ) cancel = where + 1; - - astSetInvert( emap2, old_inv2 ); - astSetInvert( rmap2, old_winv ); - - nax = astGetNin( rmap1 ); - } - } - } - -/* If we can cancel with a neightbour, do so. */ - if( cancel != -1 ) { - (void) astAnnul( ( *map_list )[ where ] ); - (void) astAnnul( ( *map_list )[ cancel ] ); - ( *map_list )[ where ] = (AstMapping *) astUnitMap( nax, "", status ); - ( *invert_list )[ where ] = 0; - ( *map_list )[ cancel ] = (AstMapping *) astUnitMap( nax, "", status ); - ( *invert_list )[ cancel ] = 0; - result = ( cancel < where ) ? cancel : where; - } - } - -/* Free resources. */ - smap = astAnnul( smap ); - -/* Reset the original Invert attribute for the encapsulated Mapping. */ - astSetInvert( emap, old_inv ); - -/* Reset the original Invert attribute for the specified RateMap */ - astSetInvert( map, map_inv ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* RateMap. - -* Type: -* Private function. - -* Synopsis: -* #include "ratemap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* RateMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing RateMap. This is only possible if the specified inputs -* correspond to some subset of the RateMap outputs. That is, there -* must exist a subset of the RateMap outputs for which each output -* depends only on the selected RateMap inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied RateMap, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the RateMap to be split (the RateMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied RateMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied RateMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied RateMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstMapping *emap; /* Pointer to Mapping encapsulated by RateMap */ - AstMapping *remap; /* Split Mapping encapsulated by RateMap */ - AstRateMap *this; /* Pointer to RateMap structure */ - int *eres; /* Outputs used by split Mapping */ - int *result; /* Array holding returned output inedx */ - int ax1; /* New index of output being differentiated */ - int ax2; /* New index of output being varied */ - int i; /* Loop count */ - int nout; /* No. of outputs in the split Mapping */ - int old_inv; /* Original Invert flag for emap */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the parent astMapSplit method to see if it can do the job. */ - result = (*parent_mapsplit)( this_map, nin, in, map, status ); - -/* If not, we provide a special implementation here. Note we cannot - produce the Mapping if the RaterMap has been inverted. */ - if( !result && !astGetInvert( this_map ) ) { - -/* Get a pointer to the RateMap structure. */ - this = (AstRateMap *) this_map; - -/* Temporarily reset the Invert attribute of the encapsulated Mapping - back to the value it had when the RateMap was created. */ - emap = this->map; - old_inv = astGetInvert( emap ); - astSetInvert( emap, this->invert ); - -/* Attempt to split the encapsulated Mapping */ - eres = astMapSplit( emap, nin, in, &remap ); - -/* We can only continue if this was succesful. */ - if( eres ) { - -/* Check that the input which the RateMap varies is one of the selected - inputs. */ - ax2 = -1; - for( i = 0; i < nin; i++ ) { - if( in[ i ] == this->iin ) { - ax2 = i; - break; - } - } - -/* Check that the output which the RateMap differentiates is one of the - outputs of the "remap" Mapping. */ - ax1 = -1; - nout = astGetNout( remap ); - for( i = 0; i < nout; i++ ) { - if( eres[ i ] == this->iout ) { - ax1 = i; - break; - } - } - -/* If possible create the required Mapping and returned array. */ - if( ax1 != -1 && ax2 != -1 ) { - *map = (AstMapping *) astRateMap( remap, ax1, ax2, "", status ); - result = astMalloc( sizeof( int ) ); - if( astOK ) *result= 0; - } - -/* Free resources */ - eres = astFree( eres ); - remap = astAnnul( remap ); - } - -/* Re-instate the original Invert flag in the Mapping encapsulated by the - supplied RateMap. */ - astSetInvert( emap, old_inv ); - } - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static AstMapping *RemoveRegions( AstMapping *this_mapping, int *status ) { -/* -* Name: -* RemoveRegions - -* Purpose: -* Remove any Regions from a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "ratemap.h" -* AstMapping *RemoveRegions( AstMapping *this, int *status ) - -* Class Membership: -* RateMap method (over-rides the astRemoveRegions method inherited -* from the Mapping class). - -* Description: -* This function searches the supplied Mapping (which may be a -* compound Mapping such as a CmpMap) for any component Mappings -* that are instances of the AST Region class. It then creates a new -* Mapping from which all Regions have been removed. If a Region -* cannot simply be removed (for instance, if it is a component of a -* parallel CmpMap), then it is replaced with an equivalent UnitMap -* in the returned Mapping. -* -* The implementation provided by the RateMap class invokes the -* astRemoveRegions method on the encapsulated Mapping, and returns a -* new RateMap containing the resulting Mapping. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the modified mapping. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstMapping *newmap; /* New component Mapping */ - AstMapping *result; /* Result pointer to return */ - AstRateMap *new; /* Pointer to new RateMap */ - AstRateMap *this; /* Pointer to RateMap structure */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the RateMap. */ - this = (AstRateMap *) this_mapping; - -/* Invoke the astRemoveRegions method on the component Mapping. */ - newmap = astRemoveRegions( this->map ); - -/* If the Mapping was not modified, just return a clone of the supplied - pointer. */ - if( this->map == newmap ) { - result = astClone( this ); - -/* Otherwise, we need to create a new RateMap to return. */ - } else { - -/* If the new Mapping is a Frame (as will be the case if the original - Mapping was a Region), use a UnitMap instead. */ - if( astIsAFrame( newmap ) ) { - (void) astAnnul( newmap ); - newmap = (AstMapping *) astUnitMap( astGetNin( this ), " ", status ); - } - -/* Take a deep copy of the supplied RateMap and then modify the Mapping - so that we retain any extra information in the supplied RateMap. */ - new = astCopy( this ); - (void) astAnnul( new->map ); - new->map = astClone( newmap ); - result = (AstMapping *) new; - } - -/* Free resources. */ - newmap = astAnnul( newmap ); - -/* Annul the returned Mapping if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a RateMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "ratemap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* RateMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a RateMap and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required Mapping. -* This implies applying each of the RateMap's component Mappings in turn, -* either in series or in parallel. - -* Parameters: -* this -* Pointer to the RateMap. -* in -* Pointer to the PointSet associated with the input coordinate values. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the RateMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstMapping *emap; - AstPointSet *result; - AstRateMap *map; - double **ptr2; - double **ptr; - double *pout; - double *work; - int ic; - int iin; - int iout; - int ipoint; - int ncoord; - int npoint; - int old_inv; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the RateMap. */ - map = (AstRateMap *) this; - -/* Apply the parent Mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We now extend the parent astTransform method by applying the component - Mappings of the RateMap to generate the output coordinate values. */ - -/* Determine whether to apply the forward or inverse Mapping, according to the - direction specified and whether the Mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* The RateMap class does not have an inverse transformation. */ - if( !forward ) { - astError( AST__INTER, "astTransform(%s): The %s class does not have " - "an inverse transformation (AST internal programming error).", status, - astGetClass( this ), astGetClass( this ) ); - -/* Otherwise use the astRate method on the encapsulated Maping to - determine the required rate of change at each supplied input point. */ - } else { - -/* Temporarily reset the Invert attribute of the encapsulated Mapping - back to the value it had when the RateMap was created. */ - emap = map->map; - old_inv = astGetInvert( emap ); - astSetInvert( emap, map->invert ); - -/* Note the indices of the input and output to use. */ - iin = map->iin; - iout = map->iout; - -/* Get pointers to the axis values in the supplied PointSet. */ - ptr = astGetPoints( in ); - ncoord = astGetNcoord( in ); - npoint = astGetNpoint( in ); - -/* Work space to hold an input position. */ - work = astMalloc( sizeof( double )*(size_t) ncoord ); - -/* Get a pointer to the axis values in the results PointSet. */ - ptr2 = astGetPoints( result ); - pout = ptr2[ 0 ]; - if( astOK ) { - -/* Loop round each point in the supplied PointSet. */ - for( ipoint = 0; ipoint < npoint; ipoint++ ) { - -/* Copy this point into the work array. */ - for( ic = 0; ic < ncoord; ic++ ) work[ ic ] = ptr[ ic ][ ipoint ]; - -/* Find the rate of change of the specified output of the encapsulated - Mapping with respect to the specified input. */ - *(pout++) = astRate( emap, work, iout, iin ); - } - } - -/* Re-instate the original Invert flag. */ - astSetInvert( emap, old_inv ); - -/* Free resources */ - work = astFree( work ); - - } - -/* If an error occurred, clean up by deleting the output PointSet (if - allocated by this function) and setting a NULL result pointer. */ - if ( !astOK ) { - if ( !out ) result = astDelete( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for RateMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for RateMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Mappings within the RateMap. -*/ - -/* Local Variables: */ - AstRateMap *in; /* Pointer to input RateMap */ - AstRateMap *out; /* Pointer to output RateMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output RateMaps. */ - in = (AstRateMap *) objin; - out = (AstRateMap *) objout; - -/* For safety, start by clearing any references to the input component - Mappings from the output RateMap. */ - out->map = NULL; - -/* Make copies of these Mappings and store pointers to them in the output - RateMap structure. */ - out->map = astCopy( in->map ); -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for RateMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for RateMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstRateMap *this; /* Pointer to RateMap */ - -/* Obtain a pointer to the RateMap structure. */ - this = (AstRateMap *) obj; - -/* Annul the pointers to the component Mappings. */ - this->map = astAnnul( this->map ); - -/* Clear the remaining RateMap variables. */ - this->invert = 0; - this->iin = 0; - this->iout = 0; -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for RateMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the RateMap class to an output Channel. - -* Parameters: -* this -* Pointer to the RateMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstRateMap *this; /* Pointer to the RateMap structure */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the RateMap structure. */ - this = (AstRateMap *) this_object; - -/* Write out values representing the instance variables for the RateMap - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Input axis. */ -/* ------------ */ - ival = this->iin; - set = ( ival != 0 ); - astWriteInt( channel, "IIn", set, 0, ival, "Index of Mapping input" ); - -/* Output axis. */ -/* ------------ */ - ival = this->iout; - set = ( ival != 0 ); - astWriteInt( channel, "IOut", set, 0, ival, "Index of Mapping output" ); - -/* Invert flag. */ -/* ------------ */ - ival = this->invert; - set = ( ival != 0 ); - astWriteInt( channel, "Inv", set, 0, ival, - ival ? "Mapping used in inverse direction" : - "Mapping used in forward direction" ); - -/* Mapping. */ -/* -------- */ - astWriteObject( channel, "Map", 1, 1, this->map, - "Mapping to be differentiated" ); - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsARateMap and astCheckRateMap functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(RateMap,Mapping) -astMAKE_CHECK(RateMap) - -AstRateMap *astRateMap_( void *map_void, int ax1, int ax2, const char *options, int *status, ...) { -/* -*+ -* Name: -* astRateMap - -* Purpose: -* Create a RateMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "ratemap.h" -* AstRateMap *astRateMap( AstMapping *map, int ax1, int ax2, const char *options, int *status, ... ) - -* Class Membership: -* RateMap constructor. - -* Description: -* This function creates a new RateMap and optionally initialises its -* attributes. - -* Parameters: -* map -* Pointer to the Mapping to differentiate. -* ax1 -* zero-based index of the "map" output which is to be differentiated. -* ax2 -* Zero-based index of the "map" input which is to be varied. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new RateMap. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new RateMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic RateMap constructor which is -* available via the protected interface to the RateMap class. A -* public interface is provided by the astRateMapId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "map" parameter is of type (void *) and is converted and validated -* within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstRateMap *new; /* Pointer to new RateMap */ - AstMapping *map; /* Pointer to Mapping structure */ - va_list args; /* Variable argument list */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain and validate pointers to the Mapping structures provided. */ - map = astCheckMapping( map_void ); - if ( astOK ) { - -/* Initialise the RateMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitRateMap( NULL, sizeof( AstRateMap ), !class_init, &class_vtab, - "RateMap", map, ax1, ax2 ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new RateMap's - attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new RateMap. */ - return new; -} - -AstRateMap *astRateMapId_( void *map_void, int ax1, int ax2, - const char *options, ... ) { -/* -*++ -* Name: -c astRateMap -f AST_RATEMAP - -* Purpose: -* Create a RateMap. - -* Type: -* Public function. - -* Synopsis: -c #include "ratemap.h" -c AstRateMap *astRateMap( AstMapping *map, int ax1, int ax2, -c const char *options, ... ) -f RESULT = AST_RATEMAP( MAP, AX1, AX2, OPTIONS, STATUS ) - -* Class Membership: -* RateMap constructor. - -* Description: -* This function creates a new RateMap and optionally initialises -* its attributes. -* -* A RateMap is a Mapping which represents a single element of the -* Jacobian matrix of another Mapping. The Mapping for which the -* Jacobian is required is specified when the new RateMap is created, -* and is referred to as the "encapsulated Mapping" below. -* -* The number of inputs to a RateMap is the same as the number of inputs -* to its encapsulated Mapping. The number of outputs from a RateMap -* is always one. This one output equals the rate of change of a -* specified output of the encapsulated Mapping with respect to a -* specified input of the encapsulated Mapping (the input and output -* to use are specified when the RateMap is created). -* -* A RateMap which has not been inverted does not define an inverse -* transformation. If a RateMap has been inverted then it will define -* an inverse transformation but not a forward transformation. - -* Parameters: -c map -f MAP = INTEGER (Given) -* Pointer to the encapsulated Mapping. -c ax1 -f AX1 = INTEGER (Given) -* Index of the output from the encapsulated Mapping for which the -* rate of change is required. This corresponds to the delta -* quantity forming the numerator of the required element of the -* Jacobian matrix. The first axis has index 1. -c ax2 -f AX2 = INTEGER (Given) -* Index of the input to the encapsulated Mapping which is to be -* varied. This corresponds to the delta quantity forming the -* denominator of the required element of the Jacobian matrix. -* The first axis has index 1. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new RateMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new RateMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astRateMap() -f AST_RATEMAP = INTEGER -* A pointer to the new RateMap. - -* Notes: -* - The forward transformation of the encapsulated Mapping must be -* defined. -c - Note that the component Mappings supplied are not copied by -c astRateMap (the new RateMap simply retains a reference to -c them). They may continue to be used for other purposes, but -c should not be deleted. If a RateMap containing a copy of its -c component Mappings is required, then a copy of the RateMap should -c be made using astCopy. -f - Note that the component Mappings supplied are not copied by -f AST_RATEMAP (the new RateMap simply retains a reference to -f them). They may continue to be used for other purposes, but -f should not be deleted. If a RateMap containing a copy of its -f component Mappings is required, then a copy of the RateMap should -f be made using AST_COPY. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astRateMap constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astRateMap_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "map" parameter is of type -* (void *) and is converted from an ID value to a pointer and -* validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astRateMap_ directly, so it must be a re-implementation -* of it in all respects, except for the conversions between IDs -* and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstRateMap *new; /* Pointer to new RateMap */ - AstMapping *map; /* Pointer to Mapping structure */ - va_list args; /* Variable argument list */ - -/* Pointer to inherited status value */ - int *status; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain the Mapping pointer from the ID supplied and validate the - pointer to ensure it identifies a valid Mapping. */ - map = astVerifyMapping( astMakePointer( map_void ) ); - if ( astOK ) { - -/* Initialise the RateMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitRateMap( NULL, sizeof( AstRateMap ), !class_init, &class_vtab, - "RateMap", map, ax1 - 1, ax2 - 1 ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new RateMap's - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new RateMap. */ - return astMakeId( new ); -} - -AstRateMap *astInitRateMap_( void *mem, size_t size, int init, - AstRateMapVtab *vtab, const char *name, - AstMapping *map, int ax1, int ax2, int *status ) { -/* -*+ -* Name: -* astInitRateMap - -* Purpose: -* Initialise a RateMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "ratemap.h" -* AstRateMap *astInitRateMap( void *mem, size_t size, int init, -* AstRateMapVtab *vtab, const char *name, -* AstMapping *map, int ax1, int ax2 ) - -* Class Membership: -* RateMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new RateMap object. It allocates memory (if necessary) to -* accommodate the RateMap plus any additional data associated with the -* derived class. It then initialises a RateMap structure at the start -* of this memory. If the "init" flag is set, it also initialises the -* contents of a virtual function table for a RateMap at the start of -* the memory passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the RateMap is to be initialised. -* This must be of sufficient size to accommodate the RateMap data -* (sizeof(RateMap)) plus any data used by the derived class. If a -* value of NULL is given, this function will allocate the memory itself -* using the "size" parameter to determine its size. -* size -* The amount of memory used by the RateMap (plus derived class -* data). This will be used to allocate memory if a value of NULL is -* given for the "mem" parameter. This value is also stored in the -* RateMap structure, so a valid value must be supplied even if not -* required for allocating memory. -* init -* A logical flag indicating if the RateMap's virtual function table -* is to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new RateMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* map -* Pointer to the Mapping. -* ax1 -* Zero-based index of output axis. -* ax2 -* Zero-based index of input axis. - -* Returned Value: -* A pointer to the new RateMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstRateMap *new; /* Pointer to new RateMap */ - int nin; /* No. input coordinates for RateMap */ - int nout; /* No. output coordinates for RateMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitRateMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Report an error if "map" has no forward transformation. */ - if( !astGetTranForward( map ) && astOK ) { - astError( AST__INTRD, "astInitRateMap(%s): The supplied Mapping " - "is not able to transform coordinates in the forward direction.", status, - name ); - } - -/* Check that the input and output axis indices are valid. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - if( ( ax1 < 0 || ax1 >= nout ) && astOK ) { - astError( AST__INNCO, "astInitRateMap(%s): The output axis %d is out " - "of range - it should be in the range 1 to %d.", status, name, - ax1 + 1, nout ); - } - if( ( ax2 < 0 || ax2 >= nin ) && astOK ) { - astError( AST__INNCO, "astInitRateMap(%s): The input axis %d is out " - "of range - it should be in the range 1 to %d.", status, name, - ax2 + 1, nin ); - } - -/* Initialise a Mapping structure (the parent class) as the first component - within the RateMap structure, allocating memory if necessary. Specify - the number of input and output coordinates and in which directions the - Mapping should be defined. */ - if ( astOK ) { - new = (AstRateMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, 1, 1, 0 ); - - if ( astOK ) { - -/* Initialise the RateMap data. */ -/* --------------------------- */ -/* Store a pointer to the encapsulated Mapping. */ - new->map = astClone( map ); - -/* Save the initial values of the inversion flag for this Mapping. */ - new->invert = astGetInvert( map ); - -/* Save the input and output axis indices. */ - new->iout = ax1; - new->iin = ax2; - -/* If an error occurred, clean up by annulling the Mapping pointers and - deleting the new object. */ - if ( !astOK ) { - new->map = astAnnul( new->map ); - new = astDelete( new ); - } - } - } - -/* Return a pointer to the new object. */ - return new; -} - -AstRateMap *astLoadRateMap_( void *mem, size_t size, - AstRateMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadRateMap - -* Purpose: -* Load a RateMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "ratemap.h" -* AstRateMap *astLoadRateMap( void *mem, size_t size, -* AstRateMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* RateMap loader. - -* Description: -* This function is provided to load a new RateMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* RateMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a RateMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the RateMap is to be -* loaded. This must be of sufficient size to accommodate the -* RateMap data (sizeof(RateMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the RateMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the RateMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstRateMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new RateMap. If this is NULL, a pointer to -* the (static) virtual function table for the RateMap class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "RateMap" is used instead. - -* Returned Value: -* A pointer to the new RateMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstRateMap *new; /* Pointer to the new RateMap */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this RateMap. In this case the - RateMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstRateMap ); - vtab = &class_vtab; - name = "RateMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitRateMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built RateMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "RateMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Invert flag. */ -/* ------------ */ - new->invert = astReadInt( channel, "inv", 0 ); - new->invert = ( new->invert != 0 ); - -/* Input and output axes. */ -/* ---------------------- */ - new->iin = astReadInt( channel, "iin", 0 ); - new->iout = astReadInt( channel, "iout", 0 ); - -/* Mapping. */ -/* -------- */ - new->map = astReadObject( channel, "map", NULL ); - -/* If an error occurred, clean up by deleting the new RateMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new RateMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -/* None. */ - - - - diff --git a/ast/ratemap.h b/ast/ratemap.h deleted file mode 100644 index b26bbd6..0000000 --- a/ast/ratemap.h +++ /dev/null @@ -1,276 +0,0 @@ -#if !defined( RATEMAP_INCLUDED ) /* Include this file only once */ -#define RATEMAP_INCLUDED -/* -*+ -* Name: -* ratemap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the RateMap class. - -* Invocation: -* #include "ratemap.h" - -* Description: -* This include file defines the interface to the RateMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. - -* Inheritance: -* The RateMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astMapMerge -* Merge a RateMap within a sequence of Mappings. -* astTransform -* Transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsARateMap -* Test class membership. -* astRateMap -* Create a RateMap. -* -* Protected: -* astCheckRateMap -* Validate class membership. -* astInitRateMap -* Initialise a RateMap. -* astInitRateMapVtab -* Initialise the virtual function table for the RateMap class. -* astLoadRateMap -* Load a RateMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstRateMap -* RateMap object type. -* -* Protected: -* AstRateMapVtab -* RateMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 7-DEC-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* RateMap structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstRateMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstMapping *map; /* Pointer to the Mapping */ - int invert; /* Inversion flag for Mapping */ - int iin; /* Index of Mapping input to vary */ - int iout; /* Index of Mapping output to measure */ -} AstRateMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstRateMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -/* None. */ -} AstRateMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstRateMapGlobals { - AstRateMapVtab Class_Vtab; - int Class_Init; -} AstRateMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitRateMapGlobals_( AstRateMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(RateMap) /* Check class membership */ -astPROTO_ISA(RateMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstRateMap *astRateMap_( void *, int, int, const char *, int *, ...); -#else -AstRateMap *astRateMapId_( void *, int, int, const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstRateMap *astInitRateMap_( void *, size_t, int, AstRateMapVtab *, - const char *, AstMapping *, int, int, int * ); - -/* Vtab initialiser. */ -void astInitRateMapVtab_( AstRateMapVtab *, const char *, int * ); - -/* Loader. */ -AstRateMap *astLoadRateMap_( void *, size_t, AstRateMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -/* None. */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckRateMap(this) astINVOKE_CHECK(RateMap,this,0) -#define astVerifyRateMap(this) astINVOKE_CHECK(RateMap,this,1) - -/* Test class membership. */ -#define astIsARateMap(this) astINVOKE_ISA(RateMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astRateMap astINVOKE(F,astRateMap_) -#else -#define astRateMap astINVOKE(F,astRateMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitRateMap(mem,size,init,vtab,name,map,iin,iout) \ -astINVOKE(O,astInitRateMap_(mem,size,init,vtab,name,astCheckMapping(map),iin,iout,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitRateMapVtab(vtab,name) astINVOKE(V,astInitRateMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadRateMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadRateMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckRateMap to validate RateMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -/* None. */ -#endif - - - - - diff --git a/ast/region.c b/ast/region.c deleted file mode 100644 index 5148917..0000000 --- a/ast/region.c +++ /dev/null @@ -1,13502 +0,0 @@ -/* -*class++ -* Name: -* Region - -* Purpose: -* Represents a region within a coordinate system. - -* Constructor Function: -* None. - -* Description: -* This class provides the basic facilities for describing a region within -* a specified coordinate system. However, the Region class does not -* have a constructor function of its own, as it is simply a container -* class for a family of specialised sub-classes such as Circle, Box, etc, -* which implement Regions with particular shapes. -* -* All sub-classes of Region require a Frame to be supplied when the Region -* is created. This Frame describes the coordinate system in which the -* Region is defined, and is referred to as the "encapsulated Frame" below. -* Constructors will also typically required one or more positions to be -* supplied which define the location and extent of the region. These -* positions must be supplied within the encapsulated Frame. -* -* The Region class inherits from the Frame class, and so a Region can be -* supplied where-ever a Frame is expected. In these cases, supplying a -* Region is equivalent to supplying a reference to its encapsulated Frame. -* Thus all the methods of the Frame class can be used on the Region class. -* For instance, the -c astFormat function -f AST_FORMAT routine -* may be used on a Region to format an axis value. -* -* In addition, since Frame inherits from Mapping, a Region is also a sort -* of Mapping. Transforming positions by supplying a Region to one of the -c astTran functions -f AST_TRAN routines -* is the way to determine if a given position is inside or outside the -* Region. When used as a Mapping, most classes of Frame are equivalent to -* a UnitMap. However, the Region class modifies this behaviour so that a -* Region acts like a UnitMap only for input positions which are within the -* area represented by the Region. Input positions which are outside the -* area produce bad output values (i.e. the output values are equal to -* AST__BAD). This behaviour is the same for both the forward and the -* inverse transformation. In this sense the "inverse transformation" -* is not a true inverse of the forward transformation, since applying -* the forward transformation to a point outside the Region, and then -* applying the inverse transformation results, in a set of AST__BAD axis -* values rather than the original axis values. If required, the -c astRemoveRegions -f AST_REMOVEREGIONS -* function can be used to remove the "masking" effect of any Regions -* contained within a compound Mapping or FrameSet. It does this by -* replacing each Region with a UnitMap or equivalent Frame (depending -* on the context in which the Region is used). -* -* If the coordinate system represented by the Region is changed (by -* changing the values of one or more of the attribute which the Region -* inherits from its encapsulated Frame), the area represented by -* the Region is mapped into the new coordinate system. For instance, let's -* say a Circle (a subclass of Region) is created, a SkyFrame being -* supplied to the constructor so that the Circle describes a circular -* area on the sky in FK4 equatorial coordinates. Since Region inherits -* from Frame, the Circle will have a System attribute and this attribute -* will be set to "FK4". If the System attribute of the Region is then -* changed from FK4 to FK5, the circular area represented by the Region -* will automatically be mapped from the FK4 system into the FK5 system. -* In general, changing the coordinate system in this way may result in the -* region changing shape - for instance, a circle may change into an -* ellipse if the transformation from the old to the new coordinate system -* is linear but with different scales on each axis. Thus the specific -* class of a Region cannot be used as a guarantee of the shape in any -* particular coordinate system. If the -c astSimplify function -f AST_SIMPLIFY routine -* is used on a Region, it will endeavour to return a new Region of -* a sub-class which accurately describes the shape in the current -* coordinate system of the Region (but this may not always be possible). -* -* It is possible to negate an existing Region so that it represents all -* areas of the encapsulated Frame except for the area specified when -* the Region was created. - -* Inheritance: -* The Region class inherits from the Frame class. - -* Attributes: -* In addition to those attributes common to all Frames, every -* Region also has the following attributes: -* -* - Adaptive: Should the area adapt to changes in the coordinate system? -* - Negated: Has the original region been negated? -* - Closed: Should the boundary be considered to be inside the region? -* - MeshSize: Number of points used to create a mesh covering the Region -* - FillFactor: Fraction of the Region which is of interest -* - Bounded: Is the Region bounded? -* -* Every Region also inherits any further attributes that belong -* to the encapsulated Frame, regardless of that Frame's class. (For -* example, the Equinox attribute, defined by the SkyFrame class, is -* inherited by any Region which represents a SkyFrame.) - -* Functions: -c In addition to those functions applicable to all Frames, the -c following functions may also be applied to all Regions: -f In addition to those routines applicable to all Frames, the -f following routines may also be applied to all Regions: -* -c - astGetRegionBounds: Get the bounds of a Region -f - AST_GETREGIONBOUNDS: Get the bounds of a Region -c - astGetRegionFrame: Get a copy of the Frame represent by a Region -f - AST_GETREGIONFRAME: Get a copy of the Frame represent by a Region -c - astGetRegionFrameSet: Get a copy of the Frameset encapsulated by a Region -f - AST_GETREGIONFRAMESET: Get a copy of the Frameset encapsulated by a Region -c - astGetRegionMesh: Get a mesh of points covering a Region -f - AST_GETREGIONMESH: Get a mesh of points covering a Region -c - astGetRegionPoints: Get the positions that define a Region -f - AST_GETREGIONPOINTS: Get the positions that define a Region -c - astGetUnc: Obtain uncertainty information from a Region -f - AST_GETUNC: Obtain uncertainty information from a Region -c - astMapRegion: Transform a Region into a new coordinate system -f - AST_MAPREGION: Transform a Region into a new coordinate system -c - astNegate: Toggle the value of the Negated attribute -f - AST_NEGATE: Toggle the value of the Negated attribute -c - astOverlap: Determines the nature of the overlap between two Regions -f - AST_OVERLAP: Determines the nature of the overlap between two Regions -c - astMask: Mask a region of a data grid -f - AST_MASK: Mask a region of a data grid -c - astSetUnc: Associate a new uncertainty with a Region -f - AST_SETUNC: Associate a new uncertainty with a Region -c - astShowMesh: Display a mesh of points on the surface of a Region -f - AST_SHOWMESH: Display a mesh of points on the surface of a Region - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (STARLINK) - -* History: -* 3-DEC-2003 (DSB): -* Original version. -* 12-MAY-2005 (DSB): -* Override astNormBox method. -* 12-AUG-2005 (DSB): -* Override ObsLat and ObsLon accessor methods. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 2-MAR-2006 (DSB): -* Changed AST_LONG_DOUBLE to HAVE_LONG_DOUBLE. -* 14-MAR-2006 (DSB): -* Added astGetRefFS. -* 28-MAY-2007 (DSB): -* - Added protected function astBndMesh. -* 14-JAN-2009 (DSB): -* Override the astIntersect method. -* 20-JAN-2009 (DSB): -* Change astPickAxes so that it returns a Region rather than a -* Frame if possible. This included adding method astRegBasePick. -* 9-FEB-2009 (DSB): -* Move PointList methods astGetEnclosure and astSetEnclosure to -* Region. -* 18-FEB-2009 (DSB): -* Remove methods astGetEnclosure and astSetEnclosure. -* 15-JUN-2009 (DSB): -* Modify MapRegion to use FrameSets properly. -* 18-JUN-2009 (DSB): -* Override ObsAlt accessor methods. -* 7-SEP-2009 (DSB): -* Fix astMask to avoid reading variance values from the data array. -* 8-SEP-2009 (DSB): -* Fix bugs in astOverlap that could result in wrong results if -* either region is unbounded. -* 4-JAN-2010 (DSB): -* Fix bug in GetRegionBounds (it was assumed implicitly that the base -* Frame had the same number of axes as the current Frame). -* 18-MAR-2011 (DSB): -* Added astGetRegionMesh public method. -* 22-MAR-2011 (DSB): -* Improve uniformity of points produced by astRegBaseGrid method. -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -* 17-MAY-2011 (DSB): -* In RegBaseGrid, accept the final try even if it is not within 5% -* of the required meshsize. -* 27-APR-2012 (DSB): -* Store a negated copy of itself with each Region. Changing the Negated -* attribute of a Region causes the cached information to be reset, and -* re-calculating it can be an expensive operation. So instead of changing -* "Negatated" in "this", access the negated copy of "this" using the -* new protected method astGetNegation. -* 7-JUN-2012 (DSB): -* Added protected astRegSplit method to split a Region into disjoint -* component regions. -* 15-JUN-2012 (DSB): -* Guard against division by zero in RegBase Grid if "ipr" is zero. -* 7-NOV-2013 (DSB): -* Added method astGetRegionFrameSet. -* 3-FEB-2014 (DSB): -* Fix bug masking regions that have no overlap with the supplied array. -* 17-APR-2015 (DSB): -* Added Centre. -* 26-OCT-2016 (DSB): -* - Override the astAxNorm method. -* - Use astAxNorm to fix a bug in astGetRegionBounds for cases where -* the Region cross a longitude=0 singularity. -* 11-NOV-2016 (DSB): -* When loading a Region, use the dimensionality of the base Frame -* of the FrameSet (rather than the current Frame as it used to be) -* to define the number of axes required in the PointSet. -* 1-DEC-2016 (DSB): -* Changed MapRegion to remove any unnecessary base frame axes in -* the returned Region. -*class-- - -* Implementation Notes: -* - All sub-classes must over-ride the following abstract methods declared -* in this class: astRegBaseBox, astRegBaseMesh, astRegPins, astRegCentre. -* They must also extend the astTransform method. In addition they should -* usually extend astSimplify. - -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Region - -/* Value for Ident attribute of of an encapsulated FrameSet which - indicates that it is a dummy FrameSet (see astRegDummy). */ -#define DUMMY_FS "ASTREGION-DUMMY" - -/* -* Name: -* MAKE_CLEAR - -* Purpose: -* Define a function to clear an attribute value for a Region. - -* Type: -* Private macro. - -* Synopsis: -* #include "region.h" -* MAKE_CLEAR(attribute) - -* Class Membership: -* Defined by the Region class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Clear( AstFrame *this ) -* -* that clears the value of a specified attribute for the encapsulated -* FrameSet within a Region (this). This function is intended to over-ride -* the astClear method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attribute) \ -static void Clear##attribute( AstFrame *this_frame, int *status ) { \ -\ -/* Local Variables: */ \ - AstRegion *this; /* Pointer to the Region structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the Region structure. */ \ - this = (AstRegion *) this_frame; \ -\ -/* Obtain a pointer to the encapsulated FrameSet and invoke its \ - astClear method. The protected astClear##attribute method is not used \ - because we want the current Frame of the FrameSet tp be re-mapped if \ - necessary. */ \ - astClear( this->frameset, #attribute ); \ -} - -/* -* Name: -* MAKE_CLEAR_AXIS - -* Purpose: -* Define a function to clear an attribute value for a Region axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "region.h" -* MAKE_CLEAR_AXIS(attribute) - -* Class Membership: -* Defined by the Region class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Clear( AstFrame *this, int axis ) -* -* that clears the value of a specified attribute for an axis of -* the encapsulated FrameSet within a Region (this). This function is -* intended to over-ride the astClear method inherited -* from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR_AXIS(attribute) \ -static void Clear##attribute( AstFrame *this_frame, int axis, int *status ) { \ -\ -/* Local Variables: */ \ - AstRegion *this; /* Pointer to the Region structure */ \ - char buf[100]; /* Buffer for attribute name */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the Region structure. */ \ - this = (AstRegion *) this_frame; \ -\ -/* Validate the axis index supplied. */ \ - (void) astValidateAxis( this, axis, 1, "astClear" #attribute ); \ -\ -/* We use the public astSetx method rather than the protected \ - astSet#attribute method so that the current Frame in the encapsulated \ - FrameSet will be re-mapped if necessary. Construct the attribute name. */ \ - sprintf( buf, "%s(%d)", #attribute, axis + 1 ); \ -\ -/* Obtain a pointer to the Region's encapsulated FrameSet and invoke its \ - astClear method. The protected astClear#attribute method is notused \ - since we want the current Frame of the encapsulated FrameSet to be \ - remapped if required. */ \ - astClear( this->frameset, buf ); \ -} - -/* -* Name: -* MAKE_GET - -* Purpose: -* Define a function to get an attribute value for a Region. - -* Type: -* Private macro. - -* Synopsis: -* #include "region.h" -* MAKE_GET(attribute,type) - -* Class Membership: -* Defined by the Region class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static Get( AstFrame *this ) -* -* that gets the value of a specified attribute for the encapsulated -* FrameSet of a Region (this). This function is intended to over-ride -* the astGet method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_GET(attribute,type) \ -static type Get##attribute( AstFrame *this_frame, int *status ) { \ -\ -/* Local Variables: */ \ - AstRegion *this; /* Pointer to the Region structure */ \ - type result; /* Value to return */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (type) 0; \ -\ -/* Obtain a pointer to the Region structure. */ \ - this = (AstRegion *) this_frame; \ -\ -/* Obtain a pointer to the encapsulated FrameSet and invoke its \ - astGet method. */ \ - result = astGet##attribute( this->frameset ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = (type) 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* Name: -* MAKE_GET_AXIS - -* Purpose: -* Define a function to get an attribute value for a Region axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "region.h" -* MAKE_GET_AXIS(attribute,type) - -* Class Membership: -* Defined by the Region class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static Get( AstFrame *this, int axis ) -* -* that gets the value of a specified attribute for an axis of the -* encapsulated FrameSet within a Region (this). This function is intended -* to over-ride the astGet method inherited from the Frame -* class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_GET_AXIS(attribute,type) \ -static type Get##attribute( AstFrame *this_frame, int axis, int *status ) { \ -\ -/* Local Variables: */ \ - AstRegion *this; /* Pointer to the Region structure */ \ - type result; /* Value to return */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (type) 0; \ -\ -/* Obtain a pointer to the Region structure. */ \ - this = (AstRegion *) this_frame; \ -\ -/* Validate the axis index supplied. */ \ - (void) astValidateAxis( this, axis, 1, "astGet" #attribute ); \ -\ -/* Obtain a pointer to the Region's encapsulated FrameSet and invoke its \ - astGet method. */ \ - result = astGet##attribute( this->frameset, axis ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = (type) 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* Name: -* MAKE_SET_SYSTEM - -* Purpose: -* Define a function to set a System attribute value for a Region. - -* Type: -* Private macro. - -* Synopsis: -* #include "region.h" -* MAKE_SET_SYSTEM(attribute) - -* Class Membership: -* Defined by the Region class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Set( AstFrame *this, AstSystemType value ) -* -* that sets the value of a specified attribute for the encapsulated -* FrameSet of a Region (this). This function is intended to over-ride the -* astSet method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -*/ - -/* Define the macro. */ -#define MAKE_SET_SYSTEM(attribute) \ -static void Set##attribute( AstFrame *this_frame, AstSystemType value, int *status ) { \ -\ -/* Local Variables: */ \ - AstRegion *this; /* Pointer to the Region structure */ \ - const char *text; /* Pointer to system string */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the Region structure. */ \ - this = (AstRegion *) this_frame; \ -\ -/* Convert the supplied value to a string using the astSystemString - method of the current Frame in the encapsulated FrameSet. */ \ - text = astSystemString( this->frameset, value ); \ -\ -/* Set the value by invoking the public astSetC method on the encapusulated \ - FrameSet. This ensures that the current Frame of the encapsulated \ - FrameSet is re-mapped if necessary. */ \ - astSetC( this->frameset, #attribute, text ); \ -} - -/* -* Name: -* MAKE_SET - -* Purpose: -* Define a function to set an attribute value for a Region. - -* Type: -* Private macro. - -* Synopsis: -* #include "region.h" -* MAKE_SET(attribute,type,x) - -* Class Membership: -* Defined by the Region class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Set( AstFrame *this, value ) -* -* that sets the value of a specified attribute for the encapsulated -* FrameSet of a Region (this). This function is intended to over-ride the -* astSet method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -* x -* The single character code for the astSetx function for the given C -* type. -*/ - -/* Define the macro. */ -#define MAKE_SET(attribute,type,x) \ -static void Set##attribute( AstFrame *this_frame, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstRegion *this; /* Pointer to the Region structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the Region structure. */ \ - this = (AstRegion *) this_frame; \ -\ -/* Set the value by invoking the public astSetx method on the encapusulated \ - FrameSet. This ensures that the current Frame of the encapsulated \ - FrameSet is re-mapped if necessary. */ \ - astSet##x( this->frameset, #attribute, value ); \ -} - -/* -* Name: -* MAKE_SET_AXIS - -* Purpose: -* Define a function to set an attribute value for a Region axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "region.h" -* MAKE_SET_AXIS(attribute,type,x) - -* Class Membership: -* Defined by the Region class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Set( AstFrame *this, int axis, value ) -* -* that sets the value of a specified attribute for an axis of the -* encapsulated FrameSet within a Region (this). This function is intended -* to over-ride the astSet method inherited from the Frame -* class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -* x -* The single character code for the astSetx function for the given C -* type. -*/ - -/* Define the macro. */ -#define MAKE_SET_AXIS(attribute,type,x) \ -static void Set##attribute( AstFrame *this_frame, int axis, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstRegion *this; /* Pointer to the Region structure */ \ - char buf[100]; /* Buffer for attribute name */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Obtain a pointer to the Region structure. */ \ - this = (AstRegion *) this_frame; \ -\ -/* Validate the axis index supplied. */ \ - (void) astValidateAxis( this, axis, 1, "astSet" #attribute ); \ -\ -/* We use the public astSetx method rather than the protected \ - astSet#attribute method so that the current Frame in the encapsulated \ - FrameSet will be re-mapped if necessary. Construct the attribute name. */ \ - sprintf( buf, "%s(%d)", #attribute, axis + 1 ); \ -\ -/* Obtain a pointer to the Region's encapsulated FrameSet and invoke its \ - astSet method. */ \ - astSet##x( this->frameset, buf, value ); \ -} - -/* -* Name: -* MAKE_TEST - -* Purpose: -* Define a function to test if an attribute value is set for a Region. - -* Type: -* Private macro. - -* Synopsis: -* #include "region.h" -* MAKE_TEST(attribute) - -* Class Membership: -* Defined by the Region class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static int Test( AstFrame *this ) -* -* that returns a boolean result (0 or 1) to indicate if the value -* of a specified attribute for the encapsulated FrameSet within a -* Region (this) is set. This function is intended to over-ride the -* astTest method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -*/ - -/* Define the macro. */ -#define MAKE_TEST(attribute) \ -static int Test##attribute( AstFrame *this_frame, int *status ) { \ -\ -/* Local Variables: */ \ - AstRegion *this; /* Pointer to Region structure */ \ - int result; /* Result to return */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Obtain a pointer to the Region structure. */ \ - this = (AstRegion *) this_frame; \ -\ -/* Obtain a pointer to the Region's encapsulated FrameSet and invoke its \ - astTest method. */ \ - result = astTest##attribute( this->frameset ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* Name: -* MAKE_TEST_AXIS - -* Purpose: -* Define a function to test if an attribute value is set for a Region -* axis. - -* Type: -* Private macro. - -* Synopsis: -* #include "region.h" -* MAKE_TEST_AXIS(attribute) - -* Class Membership: -* Defined by the Region class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static int Test( AstFrame *this, int axis ) -* -* that returns a boolean result (0 or 1) to indicate if the value -* of a specified attribute for an axis of the encapsulated FrameSet -* within a Region (this) is set. This function is intended to over-ride -* the astTest method inherited from the Frame class. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -*/ - -/* Define the macro. */ -#define MAKE_TEST_AXIS(attribute) \ -static int Test##attribute( AstFrame *this_frame, int axis, int *status ) { \ -\ -/* Local Variables: */ \ - AstRegion *this; /* Pointer to the Region structure */ \ - int result; /* Value to return */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Obtain a pointer to the Region structure. */ \ - this = (AstRegion *) this_frame; \ -\ -/* Validate the axis index supplied. */ \ - (void) astValidateAxis( this, axis, 1, "astTest" #attribute ); \ -\ -/* Obtain a pointer to the Region's encapsulated FrameSet and invoke its \ - astTest method. */ \ - result = astTest##attribute( this->frameset, axis ); \ -\ -/* If an error occurred, clear the result value. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "mapping.h" /* Coordinate Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "permmap.h" /* Coordinate permutation Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "frame.h" /* Parent Frame class */ -#include "frameset.h" /* Interconnected coordinate systems */ -#include "region.h" /* Interface definition for this class */ -#include "circle.h" /* Circular regions */ -#include "box.h" /* Box regions */ -#include "cmpregion.h" /* Compound regions */ -#include "ellipse.h" /* Elliptical regions */ -#include "pointset.h" /* Sets of points */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static int (* parent_getusedefs)( AstObject *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Region) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Region,Class_Init) -#define class_vtab astGLOBAL(Region,Class_Vtab) -#define getattrib_buff astGLOBAL(Region,GetAttrib_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstRegionVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -static int MaskLD( AstRegion *, AstMapping *, int, int, const int[], const int ubnd[], long double [], long double, int * ); -#endif -static int MaskB( AstRegion *, AstMapping *, int, int, const int[], const int[], signed char[], signed char, int * ); -static int MaskD( AstRegion *, AstMapping *, int, int, const int[], const int[], double[], double, int * ); -static int MaskF( AstRegion *, AstMapping *, int, int, const int[], const int[], float[], float, int * ); -static int MaskI( AstRegion *, AstMapping *, int, int, const int[], const int[], int[], int, int * ); -static int MaskL( AstRegion *, AstMapping *, int, int, const int[], const int[], long int[], long int, int * ); -static int MaskS( AstRegion *, AstMapping *, int, int, const int[], const int[], short int[], short int, int * ); -static int MaskUB( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned char[], unsigned char, int * ); -static int MaskUI( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned int[], unsigned int, int * ); -static int MaskUL( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned long int[], unsigned long int, int * ); -static int MaskUS( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned short int[], unsigned short int, int * ); - -static AstAxis *GetAxis( AstFrame *, int, int * ); -static AstFrame *GetRegionFrame( AstRegion *, int * ); -static AstFrameSet *GetRegionFrameSet( AstRegion *, int * ); -static AstFrame *PickAxes( AstFrame *, int, const int[], AstMapping **, int * ); -static AstFrame *RegFrame( AstRegion *, int * ); -static AstFrameSet *Conv( AstFrameSet *, AstFrameSet *, int * ); -static AstFrameSet *Convert( AstFrame *, AstFrame *, const char *, int * ); -static AstFrameSet *ConvertX( AstFrame *, AstFrame *, const char *, int * ); -static AstFrameSet *FindFrame( AstFrame *, AstFrame *, const char *, int * ); -static AstFrameSet *GetRegFS( AstRegion *, int * ); -static AstLineDef *LineDef( AstFrame *, const double[2], const double[2], int * ); -static AstMapping *RegMapping( AstRegion *, int * ); -static AstMapping *RemoveRegions( AstMapping *, int * ); -static AstMapping *Simplify( AstMapping *, int * ); -static AstObject *Cast( AstObject *, AstObject *, int * ); -static AstPointSet *BTransform( AstRegion *, AstPointSet *, int, AstPointSet *, int * ); -static AstPointSet *BndBaseMesh( AstRegion *, double *, double *, int * ); -static AstPointSet *BndMesh( AstRegion *, double *, double *, int * ); -static AstPointSet *GetSubMesh( int *, AstPointSet *, int * ); -static AstPointSet *RegBaseGrid( AstRegion *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *RegGrid( AstRegion *, int * ); -static AstPointSet *RegMesh( AstRegion *, int * ); -static AstPointSet *RegTransform( AstRegion *, AstPointSet *, int, AstPointSet *, AstFrame **, int * ); -static AstPointSet *ResolvePoints( AstFrame *, const double [], const double [], AstPointSet *, AstPointSet *, int * ); -static AstRegion *MapRegion( AstRegion *, AstMapping *, AstFrame *, int * ); -static AstRegion *RegBasePick( AstRegion *, int, const int *, int * ); -static AstRegion **RegSplit( AstRegion *, int *, int * ); -static AstSystemType SystemCode( AstFrame *, const char *, int * ); -static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * ); -static const char *Abbrev( AstFrame *, int, const char *, const char *, const char *, int * ); -static const char *Format( AstFrame *, int, double, int * ); -static const char *SystemString( AstFrame *, AstSystemType, int * ); -static const int *GetPerm( AstFrame *, int * ); -static double *RegCentre( AstRegion *, double *, double **, int, int, int * ); -static double Angle( AstFrame *, const double[], const double[], const double[], int * ); -static double AxAngle( AstFrame *, const double[], const double[], int, int * ); -static double AxDistance( AstFrame *, int, double, double, int * ); -static double AxOffset( AstFrame *, int, double, double, int * ); -static double Distance( AstFrame *, const double[], const double[], int * ); -static double Centre( AstFrame *, int, double, double, int * ); -static double Gap( AstFrame *, int, double, int *, int * ); -static double Offset2( AstFrame *, const double[2], double, double, double[2], int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetNaxes( AstFrame *, int * ); -static int GetObjSize( AstObject *, int * ); -static int GetUseDefs( AstObject *, int * ); -static int IsUnitFrame( AstFrame *, int * ); -static int LineContains( AstFrame *, AstLineDef *, int, double *, int * ); -static int LineCrossing( AstFrame *, AstLineDef *, AstLineDef *, double **, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int Overlap( AstRegion *, AstRegion *, int * ); -static int OverlapX( AstRegion *, AstRegion *, int * ); -static int RegDummyFS( AstRegion *, int * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int RegTrace( AstRegion *, int, double *, double **, int * ); -static int Unformat( AstFrame *, int, const char *, double *, int * ); -static int ValidateAxis( AstFrame *, int, int, const char *, int * ); -static void AxNorm( AstFrame *, int, int, int, double *, int * ); -static void CheckPerm( AstFrame *, const int *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void GetRegionBounds( AstRegion *, double *, double *, int * ); -static void GetRegionBounds2( AstRegion *, double *, double *, int * ); -static void GetRegionMesh( AstRegion *, int, int, int, int *, double *, int * ); -static void GetRegionPoints( AstRegion *, int, int, int *, double *, int * ); -static void Intersect( AstFrame *, const double[2], const double[2], const double[2], const double[2], double[2], int * ); -static void LineOffset( AstFrame *, AstLineDef *, double, double, double[2], int * ); -static void MatchAxes( AstFrame *, AstFrame *, int *, int * ); -static void MatchAxesX( AstFrame *, AstFrame *, int *, int * ); -static void Negate( AstRegion *, int * ); -static void Norm( AstFrame *, double[], int * ); -static void NormBox( AstFrame *, double[], double[], AstMapping *, int * ); -static void Offset( AstFrame *, const double[], const double[], double, double[], int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void PermAxes( AstFrame *, const int[], int * ); -static void RegBaseBox( AstRegion *, double *, double *, int * ); -static void RegBaseBox2( AstRegion *, double *, double *, int * ); -static void RegClearAttrib( AstRegion *, const char *, char **, int * ); -static void RegOverlay( AstRegion *, AstRegion *, int, int * ); -static void RegSetAttrib( AstRegion *, const char *, char **, int * ); -static void ReportPoints( AstMapping *, int, AstPointSet *, AstPointSet *, int * ); -static void ResetCache( AstRegion *, int * ); -static void Resolve( AstFrame *, const double [], const double [], const double [], double [], double *, double *, int * ); -static void SetAxis( AstFrame *, int, AstAxis *, int * ); -static void SetRegFS( AstRegion *, AstFrame *, int * ); -static void ShowMesh( AstRegion *, int, const char *, int * ); -static void ValidateAxisSelection( AstFrame *, int, const int *, const char *, int * ); -static AstRegion *GetNegation( AstRegion *, int * ); - -static int GetBounded( AstRegion *, int * ); -static AstRegion *GetDefUnc( AstRegion *, int * ); - -static AstRegion *GetUncFrm( AstRegion *, int, int * ); -static AstRegion *GetUnc( AstRegion *, int, int * ); -static int TestUnc( AstRegion *, int * ); -static void ClearUnc( AstRegion *, int * ); -static void SetUnc( AstRegion *, AstRegion *, int * ); - -static const char *GetDomain( AstFrame *, int * ); -static int TestDomain( AstFrame *, int * ); -static void ClearDomain( AstFrame *, int * ); -static void SetDomain( AstFrame *, const char *, int * ); - -static const char *GetFormat( AstFrame *, int, int * ); -static int TestFormat( AstFrame *, int, int * ); -static void ClearFormat( AstFrame *, int, int * ); -static void SetFormat( AstFrame *, int, const char *, int * ); - -static const char *GetLabel( AstFrame *, int, int * ); -static int TestLabel( AstFrame *, int, int * ); -static void ClearLabel( AstFrame *, int, int * ); -static void SetLabel( AstFrame *, int, const char *, int * ); - -static const char *GetSymbol( AstFrame *, int, int * ); -static int TestSymbol( AstFrame *, int, int * ); -static void ClearSymbol( AstFrame *, int, int * ); -static void SetSymbol( AstFrame *, int, const char *, int * ); - -static const char *GetTitle( AstFrame *, int * ); -static void SetTitle( AstFrame *, const char *, int * ); -static void ClearTitle( AstFrame *, int * ); -static int TestTitle( AstFrame *, int * ); - -static const char *GetUnit( AstFrame *, int, int * ); -static int TestUnit( AstFrame *, int, int * ); -static void ClearUnit( AstFrame *, int, int * ); -static void SetUnit( AstFrame *, int, const char *, int * ); - -static int GetDigits( AstFrame *, int * ); -static int TestDigits( AstFrame *, int * ); -static void ClearDigits( AstFrame *, int * ); -static void SetDigits( AstFrame *, int, int * ); - -static int GetDirection( AstFrame *, int, int * ); -static int TestDirection( AstFrame *, int, int * ); -static void ClearDirection( AstFrame *, int, int * ); -static void SetDirection( AstFrame *, int, int, int * ); - -static int GetActiveUnit( AstFrame *, int * ); -static int TestActiveUnit( AstFrame *, int * ); -static void SetActiveUnit( AstFrame *, int, int * ); - -static int GetMatchEnd( AstFrame *, int * ); -static int TestMatchEnd( AstFrame *, int * ); -static void ClearMatchEnd( AstFrame *, int * ); -static void SetMatchEnd( AstFrame *, int, int * ); - -static int GetMaxAxes( AstFrame *, int * ); -static int TestMaxAxes( AstFrame *, int * ); -static void ClearMaxAxes( AstFrame *, int * ); -static void SetMaxAxes( AstFrame *, int, int * ); - -static int GetMinAxes( AstFrame *, int * ); -static int TestMinAxes( AstFrame *, int * ); -static void ClearMinAxes( AstFrame *, int * ); -static void SetMinAxes( AstFrame *, int, int * ); - -static int GetPermute( AstFrame *, int * ); -static int TestPermute( AstFrame *, int * ); -static void ClearPermute( AstFrame *, int * ); -static void SetPermute( AstFrame *, int, int * ); - -static int GetPreserveAxes( AstFrame *, int * ); -static int TestPreserveAxes( AstFrame *, int * ); -static void ClearPreserveAxes( AstFrame *, int * ); -static void SetPreserveAxes( AstFrame *, int, int * ); - -static double GetBottom( AstFrame *, int, int * ); -static int TestBottom( AstFrame *, int, int * ); -static void ClearBottom( AstFrame *, int, int * ); -static void SetBottom( AstFrame *, int, double, int * ); - -static double GetTop( AstFrame *, int, int * ); -static int TestTop( AstFrame *, int, int * ); -static void ClearTop( AstFrame *, int, int * ); -static void SetTop( AstFrame *, int, double, int * ); - -static double GetEpoch( AstFrame *, int * ); -static int TestEpoch( AstFrame *, int * ); -static void ClearEpoch( AstFrame *, int * ); -static void SetEpoch( AstFrame *, double, int * ); - -static double GetObsAlt( AstFrame *, int * ); -static int TestObsAlt( AstFrame *, int * ); -static void ClearObsAlt( AstFrame *, int * ); -static void SetObsAlt( AstFrame *, double, int * ); - -static double GetObsLat( AstFrame *, int * ); -static int TestObsLat( AstFrame *, int * ); -static void ClearObsLat( AstFrame *, int * ); -static void SetObsLat( AstFrame *, double, int * ); - -static double GetObsLon( AstFrame *, int * ); -static int TestObsLon( AstFrame *, int * ); -static void ClearObsLon( AstFrame *, int * ); -static void SetObsLon( AstFrame *, double, int * ); - -static AstSystemType GetSystem( AstFrame *, int * ); -static int TestSystem( AstFrame *, int * ); -static void ClearSystem( AstFrame *, int * ); -static void SetSystem( AstFrame *, AstSystemType, int * ); - -static AstSystemType GetAlignSystem( AstFrame *, int * ); -static int TestAlignSystem( AstFrame *, int * ); -static void ClearAlignSystem( AstFrame *, int * ); -static void SetAlignSystem( AstFrame *, AstSystemType, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static int GetNegated( AstRegion *, int * ); -static int TestNegated( AstRegion *, int * ); -static void ClearNegated( AstRegion *, int * ); -static void SetNegated( AstRegion *, int, int * ); - -static int GetClosed( AstRegion *, int * ); -static int TestClosed( AstRegion *, int * ); -static void ClearClosed( AstRegion *, int * ); -static void SetClosed( AstRegion *, int, int * ); - -static int GetMeshSize( AstRegion *, int * ); -static int TestMeshSize( AstRegion *, int * ); -static void ClearMeshSize( AstRegion *, int * ); -static void SetMeshSize( AstRegion *, int, int * ); - -static double GetFillFactor( AstRegion *, int * ); -static int TestFillFactor( AstRegion *, int * ); -static void ClearFillFactor( AstRegion *, int * ); -static void SetFillFactor( AstRegion *, double, int * ); - -static int GetRegionFS( AstRegion *, int * ); -static int TestRegionFS( AstRegion *, int * ); -static void ClearRegionFS( AstRegion *, int * ); -static void SetRegionFS( AstRegion *, int, int * ); - -static int GetAdaptive( AstRegion *, int * ); -static int TestAdaptive( AstRegion *, int * ); -static void ClearAdaptive( AstRegion *, int * ); -static void SetAdaptive( AstRegion *, int, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Member functions. */ -/* ================= */ - -static const char *Abbrev( AstFrame *this_frame, int axis, const char *fmt, - const char *str1, const char *str2, int *status ) { -/* -* Name: -* Abbrev - -* Purpose: -* Abbreviate a formatted Region axis value by skipping leading fields. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* const char *Abbrev( AstFrame *this, int axis, const char *fmt, -* const char *str1, const char *str2, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astAbbrev -* method inherited from the Frame class). - -* Description: -* This function compares two Region axis values that have been -* formatted (using astFormat) and determines if they have any -* redundant leading fields (i.e. leading fields in common which -* can be suppressed when tabulating the values or plotting them on -* the axis of a graph). - -* Parameters: -* this -* Pointer to the Region -* axis -* The number of the Region axis for which the values have -* been formatted (axis numbering starts at zero for the first -* axis). -* fmt -* Pointer to a constant null-terminated string containing the -* format specification used to format the two values. -* str1 -* Pointer to a constant null-terminated string containing the -* first formatted value. -* str1 -* Pointer to a constant null-terminated string containing the -* second formatted value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer into the "str2" string which locates the first -* character in the first field that differs between the two -* formatted values. -* -* If the two values have no leading fields in common, the returned -* value will point at the start of string "str2". If the two -* values are equal, it will point at the terminating null at the -* end of this string. - -* Notes: -* - This function assumes that the format specification used was -* the same when both values were formatted and that they both -* apply to the same Region axis. -* - A pointer to the start of "str2" will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return str2; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astAbbrev" ); - -/* Obtain a pointer to the Region's current Frame and invoke this - Frame's astAbbrev method to perform the processing. Annul the Frame - pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astAbbrev( fr, axis, fmt, str1, str2 ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = str2; - -/* Return the result. */ - return result; -} - -static double Angle( AstFrame *this_frame, const double a[], - const double b[], const double c[], int *status ) { -/* -* Name: -* Angle - -* Purpose: -* Calculate the angle subtended by two points at a third point. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* double Angle( AstFrame *this, const double a[], const double b[], -* const double c[], int *status ) - -* Class Membership: -* Region member function (over-rides the protected astAngle -* method inherited from the Frame class). - -* Description: -* This function finds the angle at point B between the line joining points -* A and B, and the line joining points C and B. These lines will in fact be -* geodesic curves appropriate to the Frame in use. For instance, in -* SkyFrame, they will be great circles. - -* Parameters: -* this -* Pointer to the Frame. -* a -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the first point. -* b -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the second point. -* c -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the third point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* astAngle -* The angle in radians, from the line AB to the line CB. If the -* Frame is 2-dimensional, it will be in the range $\pm \pi$, -* and positive rotation is in the same sense as rotation from -* the positive direction of axis 2 to the positive direction of -* axis 1. If the Frame has more than 2 axes, a positive value will -* always be returned in the range zero to $\pi$. - -* Notes: -* - A value of AST__BAD will also be returned if points A and B are -* co-incident, or if points B and C are co-incident. -* - A value of AST__BAD will also be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke this - Frame's astAngle method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astAngle( fr, a, b, c ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static double AxAngle( AstFrame *this_frame, const double a[], const double b[], int axis, int *status ) { -/* -* Name: -* AxAngle - -* Purpose: -* Returns the angle from an axis, to a line through two points. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* double AxAngle( AstFrame *this, const double a[], const double b[], int axis, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astAxAngle -* method inherited from the Frame class). - -* Description: -* This function finds the angle, as seen from point A, between the positive -* direction of a specified axis, and the geodesic curve joining point -* A to point B. - -* Parameters: -* this -* Pointer to the Frame. -* a -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the first point. -* b -* An array of double, with one element for each Frame axis -* (Naxes attribute) containing the coordinates of the second point. -* axis -* The number of the Frame axis from which the angle is to be -* measured (one-based) -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The angle in radians, from the positive direction of the -* specified axis, to the line AB. If the Frame is 2-dimensional, -* it will be in the range $\pm \pi$, and positive rotation is in -* the same sense as rotation from the positive direction of axis 2 -* to the positive direction of axis 1. If the Frame has more than 2 -* axes, a positive value will always be returned in the range zero -* to $\pi$. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value, or if the require -* position angle is undefined. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxAngle" ); - -/* Obtain a pointer to the Region's encapsulated Frame and invoke the - astAxAngle method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astAxAngle( fr, a, b, axis ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static double AxDistance( AstFrame *this_frame, int axis, double v1, double v2, int *status ) { -/* -* Name: -* AxDistance - -* Purpose: -* Find the distance between two axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* double AxDistance( AstFrame *this, int axis, double v1, double v2, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astAxDistance -* method inherited from the Frame class). - -* Description: -* This function returns a signed value representing the axis increment -* from axis value v1 to axis value v2. -* -* For a simple Frame, this is a trivial operation returning the -* difference between the two axis values. But for other derived classes -* of Frame (such as a SkyFrame) this is not the case. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The index of the axis to which the supplied values refer. The -* first axis has index 1. -* v1 -* The first axis value. -* v2 -* The second axis value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The distance between the two axis values. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input vaues has this value. -* - A "bad" value will also be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxDistance" ); - -/* Obtain a pointer to the Region's encapsulated Frame and invoke the - astAxDistance method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astAxDistance( fr, axis, v1, v2 ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static void AxNorm( AstFrame *this_frame, int axis, int oper, int nval, - double *values, int *status ){ -/* -* Name: -* AxNorm - -* Purpose: -* Normalise an array of axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void AxNorm( AstFrame *this, int axis, int oper, int nval, -* double *values, int *status ) - -* Class Membership: -* FrameSet member function (over-rides the protected astAxNorm -* method inherited from the Frame class). - -* Description: -* This function modifies a supplied array of axis values so that -* they are normalised in the manner indicated by parameter "oper". -* -* No normalisation is possible for a simple Frame and so the supplied -* values are returned unchanged. However, this may not be the case for -* specialised sub-classes of Frame. For instance, a SkyFrame has a -* discontinuity at zero longitude and so a longitude value can be -* expressed in the range [-Pi,+PI] or the range [0,2*PI]. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The index of the axis to which the supplied values refer. The -* first axis has index 1. -* oper -* Indicates the type of normalisation to be applied. If zero is -* supplied, the normalisation will be the same as that performed by -* function astNorm. If 1 is supplied, the normalisation will be -* chosen automatically so that the resulting list has the smallest -* range. -* nval -* The number of points in the values array. -* values -* On entry, the axis values to be normalised. Modified on exit to -* hold the normalised values. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxNorm" ); - -/* Obtain a pointer to the Region's encapsulated Frame and invoke - the astAxNorm method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astAxNorm( fr, axis, oper, nval, values ); - fr = astAnnul( fr ); -} - -static double AxOffset( AstFrame *this_frame, int axis, double v1, double dist, int *status ) { -/* -* Name: -* AxOffset - -* Purpose: -* Add an increment onto a supplied axis value. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* double AxOffset( AstFrame *this, int axis, double v1, double dist, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astAxOffset -* method inherited from the Frame class). - -* Description: -* This function returns an axis value formed by adding a signed axis -* increment onto a supplied axis value. -* -* For a simple Frame, this is a trivial operation returning the -* sum of the two supplied values. But for other derived classes -* of Frame (such as a SkyFrame) this is not the case. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The index of the axis to which the supplied values refer. The -* first axis has index 1. -* v1 -* The original axis value. -* dist -* The axis increment to add to the original axis value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The incremented axis value. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input vaues has this value. -* - A "bad" value will also be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis - 1, 1, "astAxOffset" ); - -/* Obtain a pointer to the Region's encapsulated Frame and invoke the - astAxOffset method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astAxOffset( fr, axis, v1, dist ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static AstPointSet *BndBaseMesh( AstRegion *this, double *lbnd, double *ubnd, int *status ){ -/* -*+ -* Name: -* astBndBaseMesh - -* Purpose: -* Return a PointSet containing points spread around part of the boundary -* of a Region, in the base Frame. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstPointSet *astBndBaseMesh( AstRegion *this, double *lbnd, double *ubnd ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a PointSet containing a set of points on the -* boundary of the intersection between the supplied Region and the -* supplied (current Frame) box. The mesh points refer to the base -* Frame. If the boundary of the supplied Region does not intersect the -* supplied box, then a PointSet containing a single bad point is -* returned. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array holding the lower limits of the axis values -* within the required box. Defined in the current Frame of the Region. -* ubnd -* Pointer to an array holding the upper limits of the axis values -* within the required box. Defined in the current Frame of the Region. - -* Returned Value: -* Pointer to the PointSet holding the base Frame mesh. The axis values -* in this PointSet will have associated accuracies derived from the -* uncertainties which were supplied when the Region was created. -* -* If the Region does not intersect the supplied box, the returned -* PointSet will contain a single point with a value of AST__BAD on -* every axis. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstBox *box; - AstCmpRegion *cmpreg; - AstPointSet *result; - double **ptr; - int ic; - int nc; - -/* Check the local error status. */ - if ( !astOK ) return NULL; - -/* Form a Box describing the required box. */ - box = astBox( this, 1, lbnd, ubnd, NULL, "", status ); - -/* Check there is partial overlap between the Regions.*/ - if( astOverlap( this, box ) > 3 ) { - -/* Form a CmpRegion representing the intersection between the supplied - Region and the above box. */ - cmpreg = astCmpRegion( this, box, AST__AND, "", status ); - -/* Get the boundary mesh. */ - result = astRegBaseMesh( cmpreg ); - -/* Free resources. */ - cmpreg = astAnnul( cmpreg ); - -/* If the boundary of the supplied Region does not intersect the box, - return a PointSet containing a single bad position. */ - } else { - nc = astGetNin( this->frameset ); - result = astPointSet( 1, nc, "", status ); - ptr = astGetPoints( result ); - if( ptr ) { - for( ic = 0; ic < nc; ic++ ) ptr[ ic ][ 0 ] = AST__BAD; - } - } - -/* Free resources. */ - box = astAnnul( box ); - -/* Return NULL if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the required pointer. */ - return result; -} - -static AstPointSet *BndMesh( AstRegion *this, double *lbnd, double *ubnd, int *status ){ -/* -*+ -* Name: -* astBndMesh - -* Purpose: -* Return a PointSet containing points spread around part of the boundary -* of a Region, in the current Frame. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstPointSet *astBndMesh( AstRegion *this, double *lbnd, double *ubnd ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a PointSet containing a set of points on the -* boundary of the intersection between the supplied Region and the -* supplied box. The points refer to the current Frame of the -* encapsulated FrameSet. If the boundary of the supplied Region does -* not intersect the supplied box, then a PointSet containing a single -* bad point is returned. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array holding the lower limits of the axis values -* within the required box. Defined in the current Frame of the Region. -* ubnd -* Pointer to an array holding the upper limits of the axis values -* within the required box. Defined in the current base Frame of the -* Region. - -* Returned Value: -* Pointer to the PointSet. The axis values in this PointSet will have -* associated accuracies derived from the uncertainties which were -* supplied when the Region was created. -* -* If the Region does not intersect the supplied box, the returned -* PointSet will contain a single point with a value of AST__BAD on -* every axis. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstMapping *map; - AstPointSet *ps1; - AstPointSet *result; - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get the current->base Mapping from the Region. */ - map = astGetMapping( this->frameset, AST__CURRENT, AST__BASE ); - -/* Use astBndBaseMesh to get a mesh of base Frame points within this base - Frame bounding box. */ - ps1 = astBndBaseMesh( this, lbnd, ubnd ); - -/* Transform it into the current Frame. */ - if( ps1 ) result = astTransform( map, ps1, 0, NULL ); - -/* Free resources. */ - map = astAnnul( map ); - ps1 = astAnnul( ps1 ); - -/* Return NULL if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the required pointer. */ - return result; -} - -static AstPointSet *BTransform( AstRegion *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -*+ -* Name: -* astBTransform - -* Purpose: -* Use a Region to transform a set of points in the base Frame. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "circle.h" -* AstPointSet *astBTransform( AstRegion *this, AstPointSet *in, - int forward, AstPointSet *out ) - -* Class Membership: -* Region member function - -* Description: -* This function takes a Region and a set of points within the base -* Frame of the Region, and transforms the points by setting axis values -* to AST__BAD for all points which are outside the region. Points inside -* the region are copied unchanged from input to output. - -* Parameters: -* this -* Pointer to the Region. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - This is identical to the astTransform method for a Region except -* that the supplied and returned points refer to the base Frame of -* the Region, rather than the current Frame. -*- -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - int old; /* Origial value of "nomap" flag */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Save the current value of the "nomap" flag for this Region,and then - set it. Doing this tells the astRegMapping function (called by - astRegTransform) to assume a unit map connects base and current Frame. */ - old = this->nomap; - this->nomap = 1; - -/* Invoke the usual astTransform method. The above setting of the "nomap" - flag will cause the astTransform method to treat the base Frame as the - current Frame. */ - result = astTransform( this, in, forward, out ); - -/* Reset the "nomap" flag. */ - this->nomap = old; - -/* Return a pointer to the output PointSet. */ - return result; -} - -static AstObject *Cast( AstObject *this_object, AstObject *obj, int *status ) { -/* -* Name: -* Cast - -* Purpose: -* Cast an Object into an instance of a sub-class. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstObject *Cast( AstObject *this, AstObject *obj, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astCast -* method inherited from the Frame class). - -* Description: -* This function returns a deep copy of an ancestral component of the -* supplied object. The required class of the ancestral component is -* specified by another object. Specifically, if "this" and "new" are -* of the same class, a copy of "this" is returned. If "this" is an -* instance of a subclass of "obj", then a copy of the component -* of "this" that matches the class of "obj" is returned. Otherwise, -* a NULL pointer is returned without error. - -* Parameters: -* this -* Pointer to the Object to be cast. -* obj -* Pointer to an Object that defines the class of the returned Object. -* The returned Object will be of the same class as "obj". - -* Returned Value: -* A pointer to the new Object. NULL if "this" is not a sub-class of -* "obj", or if an error occurs. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables; */ - AstFrame *cfrm; - AstObject *new; - astDECLARE_GLOBALS - int generation_gap; - -/* Initialise */ - new = NULL; - -/* Check inherited status */ - if( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* See how many steps up the class inheritance ladder it is from "obj" - to this class (Region). A positive value is returned if Region is - a sub-class of "obj". A negative value is returned if "obj" is a - sub-class of Region. Zero is returned if "obj" is a Region. - AST__COUSIN is returned if "obj" is not on the same line of descent - as Region. */ - generation_gap = astClassCompare( (AstObjectVtab *) &class_vtab, - astVTAB( obj ) ); - -/* If "obj" is a Region or a sub-class of Region, we can cast by - truncating the vtab for "this" so that it matches the vtab of "obJ", - and then taking a deep copy of "this". */ - if( generation_gap <= 0 && generation_gap != AST__COUSIN ) { - new = astCastCopy( this_object, obj ); - -/* If "obj" is not a Region or a sub-class of Region (e.g. a Frame or - some sub-class of Frame), we attempt to cast the current Frame of the - encapsulated FrameSet into the class indicated by "obj". */ - } else { - cfrm = astGetFrame( ((AstRegion *) this_object)->frameset, AST__CURRENT ); - new = astCast( cfrm, obj ); - cfrm = astAnnul( cfrm ); - } - -/* Return the new pointer. */ - return new; -} - -static double Centre( AstFrame *this_frame, int axis, double value, double gap, int *status ) { -/* -* Name: -* Centre - -* Purpose: -* Find a "nice" central value for tabulating Frame axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* double Centre( AstFrame *this_frame, int axis, double value, -* double gap, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astCentre method -* inherited from the Frame class). - -* Description: -* This function returns an axis value which produces a nice formatted -* value suitable for a major tick mark on a plot axis, close to the -* supplied axis value. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which a central value -* is to be found. -* value -* An arbitrary axis value in the section that is being plotted. -* gap -* The gap size. - -* Returned Value: -* The nice central axis value. - -* Notes: -* - A value of zero is returned if the supplied gap size is zero. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astCentre" ); - -/* Obtain a pointer to the Region's current Frame and invoke this - Frame's astCentre method to obtain the required value. Annul the - Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astCentre( fr, axis, value, gap ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static void CheckPerm( AstFrame *this_frame, const int *perm, const char *method, int *status ) { -/* -* Name: -* CheckPerm - -* Purpose: -* Check that an array contains a valid permutation. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void CheckPerm( AstFrame *this, const int *perm, const char *method, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astCheckPerm -* method inherited from the Frame class). - -* Description: -* This function checks the validity of a permutation array that -* will be used to permute the order of a Frame's axes. If the -* permutation specified by the array is not valid, an error is -* reported and the global error status is set. Otherwise, the -* function returns without further action. - -* Parameters: -* this -* Pointer to the Frame. -* perm -* Pointer to an array of integers with the same number of -* elements as there are axes in the Frame. For each axis, the -* corresponding integer gives the (zero based) axis index to be -* used to identify the information for that axis (using the -* un-permuted axis numbering). To be valid, the integers in -* this array should therefore all lie in the range zero to -* (naxes-1) inclusive, where "naxes" is the number of Frame -* axes, and each value should occur exactly once. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate a permutation array. This method name is used -* solely for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Error messages issued by this function refer to the external -* (public) numbering system used for axes (which is one-based), -* whereas zero-based axis indices are used internally. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke this - Frame's astCheckPerm method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astCheckPerm( fr, perm, method ); - fr = astAnnul( fr ); - -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Region member function (over-rides the astClearAttrib protected -* method inherited from the Frame class). - -* Description: -* This function clears the value of a specified attribute for a -* Region, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Region. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* We first handle attributes that apply to the Region as a whole - (rather than to the encapsulated FrameSet). */ - -/* Negated */ -/* ------- */ - if ( !strcmp( attrib, "negated" ) ) { - astClearNegated( this ); - -/* Closed */ -/* ------ */ - } else if ( !strcmp( attrib, "closed" ) ) { - astClearClosed( this ); - -/* FillFactor */ -/* ---------- */ - } else if ( !strcmp( attrib, "fillfactor" ) ) { - astClearFillFactor( this ); - -/* MeshSize */ -/* -------- */ - } else if ( !strcmp( attrib, "meshsize" ) ) { - astClearMeshSize( this ); - -/* Adaptive */ -/* -------- */ - } else if ( !strcmp( attrib, "adaptive" ) ) { - astClearAdaptive( this ); - - -/* We now check for atttributes of superclasses which apply to the Region - as a whole. We do not want to pass these on to the encapsulated FrameSet. */ - -/* ID. */ -/* --- */ - } else if ( !strcmp( attrib, "id" ) ) { - astClearID( this ); - -/* Ident. */ -/* ------ */ - } else if ( !strcmp( attrib, "ident" ) ) { - astClearIdent( this ); - -/* Invert. */ -/* ------- */ - } else if ( !strcmp( attrib, "invert" ) ) { - astClearInvert( this ); - -/* Report. */ -/* ------- */ - } else if ( !strcmp( attrib, "report" ) ) { - astClearReport( this ); - - -/* If the name was not recognised, test if it matches any of the - read-only attributes of this class (including those of all superclasses). - If it does, then report an error. */ - } else if ( !strcmp( attrib, "class" ) || - !strcmp( attrib, "nin" ) || - !strcmp( attrib, "nobject" ) || - !strcmp( attrib, "nout" ) || - !strcmp( attrib, "bounded" ) || - !strcmp( attrib, "refcount" ) || - !strcmp( attrib, "tranforward" ) || - !strcmp( attrib, "traninverse" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Pass unrecognised attributes on to the Region's encapsulated FrameSet for - further interpretation. Do not pass on FrameSet attributes since we - pretend to the outside world that the encapsulated FrameSet is actually a - Frame. */ - } else if ( strcmp( attrib, "base" ) && - strcmp( attrib, "current" ) && - strcmp( attrib, "nframe" ) ) { - -/* If the Region is to adapt to coordinate system chanmges, use the public - astClear method so that the current Frame in the encapsulated FrameSet will - be re-mapped if the attribute changes require it. */ - if( astGetAdaptive( this ) ) { - astClear( this->frameset, attrib ); - -/* If the Region is not to adapt to coordinate system chanmges, use the - astRegSetAttrib method which assigns the attribute setting to both - current and base Frames in the FrameSet without causing any remapping to - be performed. */ - } else { - astRegClearAttrib( this, attrib, NULL ); - } - } -} - -static AstFrameSet *Conv( AstFrameSet *from, AstFrameSet *to, int *status ){ -/* -* Name: -* Conv - -* Purpose: -* Find Mapping between Frames - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstFrameSet *Conv( AstFrameSet *from, AstFrameSet *to, int *status ); - -* Class Membership: -* Region member function - -* Description: -* This function provides a convenient interface for astConvert. -* It is like astConvert except it does not alter the base Frames of -* the supplied FrameSets and does not require a Domain list. - -* Parameters: -* from -* Pointer to the source FrameSet. -* to -* Pointer to the source FrameSet. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The conversion FrameSet (see astConvert). - -*/ - -/* Local Variables: */ - AstFrameSet *result; /* FrameSet to return */ - int from_base; /* Index of original base Frame in "from" */ - int to_base; /* Index of original base Frame in "to" */ - -/* Check the global error status. */ - if( !astOK ) return NULL; - -/* Note the indices of the base Frames in the FrameSets. */ - to_base = astGetBase( to ); - from_base = astGetBase( from ); - -/* Invoke astConvert. */ - result = astConvert( from, to, "" ); - -/* Re-instate original base Frames. */ - astSetBase( to, to_base ); - astSetBase( from, from_base ); - -/* Return the result. */ - return result; -} - -static AstFrameSet *Convert( AstFrame *from, AstFrame *to, - const char *domainlist, int *status ) { -/* -* Name: -* Convert - -* Purpose: -* Determine how to convert between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstFrameSet *Convert( AstFrame *from, AstFrame *to, -* const char *domainlist, int *status ) - -* Class Membership: -* Region member function (over-rides the public astConvert -* method inherited fromm the Frame class). - -* Description: -* This function compares two Regions and determines whether it -* is possible to convert between the coordinate systems which -* their current Frames represent. If conversion is possible, it -* returns a FrameSet which describes the conversion and which may -* be used (as a Mapping) to transform coordinate values in either -* direction. - -* Parameters: -* from -* Pointer to a Region whose current Frame represents the -* "source" coordinate system. Note that the Base attribute of -* the Region may be modified by this function. -* to -* Pointer to a Region whose current Frame represents the -* "destination" coordinate system. Note that the Base -* attribute of the Region may be modified by this function. -* domainlist -* Pointer to a null-terminated character string containing a -* comma-separated list of Frame domains. This may be used to -* define a priority order for the different intermediate -* coordinate systems that might be used to perform the -* conversion. -* -* The function will first try to obtain a conversion by making -* use only of intermediate Frames whose Domain attribute -* matches the first domain in this list. If this fails, the -* second domain in the list will be used, and so on, until -* conversion is achieved. A blank domain (e.g. two consecutive -* commas) indicates that all Frames should be considered, -* regardless of their Domain attributes. The list is -* case-insensitive and all white space is ignored. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If the requested coordinate conversion is possible, the -* function returns a pointer to a FrameSet which describes the -* conversion. Otherwise, a null Object pointer (AST__NULL) is -* returned without error. -* -* If a FrameSet is returned, it will contain two Frames. Frame -* number 1 (its base Frame) will describe the source coordinate -* system, corresponding to the "from" parameter. Frame number 2 -* (its current Frame) will describe the destination coordinate -* system, corresponding to the "to" parameter. The Mapping -* which inter-relates these Frames will perform the required -* conversion between the two coordinate systems. - -* Notes: -* - The returned FrameSet will not contain any Regions. If one or -* more of the supplied Frames are in fact Regions, the corresponding -* Frames in any returned FrameSet will described the encapsulated -* Frame, without any region information. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrameSet *result; /* Returned FrameSet */ - -/* Check the inherited status. */ - if ( !astOK ) return NULL; - -/* If the "from" pointer is a Region, get a pointer to the current Frame of - the encapsulated FrameSet and use it instead of the supplied pointer. */ - if( astIsARegion( from ) ) { - from = astGetFrame( ((AstRegion *) from)->frameset, AST__CURRENT ); - } else { - from = astClone( from ); - } - -/* If the "to" pointer is a Region, get a pointer to the current Frame of - the encapsulated FrameSet and use it instead of the supplied pointer. */ - if( astIsARegion( to ) ) { - to = astGetFrame( ((AstRegion *) to)->frameset, AST__CURRENT ); - } else { - to = astClone( to ); - } - -/* Now invoke astConvert on the above Frames. */ - result = astConvert( from, to, domainlist ); - -/* Annul the pointers used above. */ - from = astAnnul( from ); - to = astAnnul( to ); - -/* Return the result */ - return result; -} - -static AstFrameSet *ConvertX( AstFrame *to, AstFrame *from, - const char *domainlist, int *status ) { -/* -* Name: -* ConvertX - -* Purpose: -* Determine how to convert between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstFrameSet *astConvertX( AstFrame *to, AstFrame *from, -* const char *domainlist ) - -* Class Membership: -* Region member function (over-rides the protected astConvertX -* method inherited from the Frame class). - -* Description: -* This function performs the processing for the public astConvert -* method and has exactly the same interface except that the order -* of the first two arguments is swapped. This is a trick to allow -* the astConvert method to be over-ridden by derived classes on -* the basis of the class of either of its first two arguments. -* -* See the astConvert method for details of the interface. -*- -*/ - -/* Local Variables: */ - AstFrameSet *result; /* Returned FrameSet */ - -/* Check the inherited status. */ - if ( !astOK ) return NULL; - -/* If the "to" pointer is a Region, get a pointer to the current Frame of - the encapsulated FrameSet and use it instead of the supplied pointer. */ - if( astIsARegion( to ) ) { - to = astGetFrame( ((AstRegion *) to)->frameset, AST__CURRENT ); - } else { - to = astClone( to ); - } - -/* If the "from" pointer is a Region, get a pointer to the current Frame of - the encapsulated FrameSet and use it instead of the supplied pointer. */ - if( astIsARegion( from ) ) { - from = astGetFrame( ((AstRegion *) from)->frameset, AST__CURRENT ); - } else { - from = astClone( from ); - } - -/* Now invoke astConvertX on the above Frames. */ - result = astConvertX( to, from, domainlist ); - -/* Annul the pointers used above. */ - from = astAnnul( from ); - to = astAnnul( to ); - -/* Return the result */ - return result; -} - -static double Distance( AstFrame *this_frame, const double point1[], - const double point2[], int *status ) { -/* -* Name: -* Distance - -* Purpose: -* Calculate the distance between two points. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* double Distance( AstFrame *this, const double point1[], -* const double point2[], int *status ) - -* Class Membership: -* Region member function (over-rides the protected astDistance -* method inherited from the Frame class). - -* Description: -* This function finds the distance between two points whose -* Region coordinates are given. The distance calculated is that -* along the geodesic curve that joins the two points. - -* Parameters: -* this -* Pointer to the Region. -* point1 -* An array of double, with one element for each Region axis -* containing the coordinates of the first point. -* point2 -* An array of double, with one element for each Region axis -* containing the coordinates of the second point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The distance between the two points. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input coordinates has this value. -* - A "bad" value will also be returned if this function is -* invoked with the AST error status set or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's current Frame and invoke this - Frame's astDistance method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astDistance( fr, point1, point2 ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two Objects are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int Equal( AstObject *this_object, AstObject *that_object, int *status ) - -* Class Membership: -* Region member function (over-rides the astEqual protected -* method inherited from the Frame class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two Regions are equivalent. - -* Parameters: -* this -* Pointer to the first Region. -* that -* Pointer to the second Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the Regions are equivalent, zero otherwise. - -* Notes: -* - The Regions are equivalent if they are of the same class, have -* equal PointSets, have equal base Frames, have equal current Frames, -* and if the Mapping between base Frames is a UnitMap. In addition, the -* Negated attribute must have the same value in both Regions, as must -* the Closed attribute. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *bf1; - AstFrame *bf2; - AstFrame *cf1; - AstFrame *cf2; - AstMapping *m1; - AstMapping *m2; - AstRegion *that; - AstRegion *this; - const char *class1; - const char *class2; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check that the two objects have the same class. */ - class1 = astGetClass( this_object ); - class2 = astGetClass( that_object ); - if( astOK && !strcmp( class1, class2 ) ) { - -/* Obtain pointers to the two Region structures. */ - this = (AstRegion *) this_object; - that = (AstRegion *) that_object; - -/* Test their PointSets for equality. */ - if( astEqual( this->points, that->points ) ){ - -/* Test their base Frames for equality. */ - bf1 = astGetFrame( this->frameset, AST__BASE ); - bf2 = astGetFrame( that->frameset, AST__BASE ); - if( astEqual( bf1, bf2 ) ){ - -/* Test their current Frames for equality. */ - cf1 = astGetFrame( this->frameset, AST__CURRENT ); - cf2 = astGetFrame( that->frameset, AST__CURRENT ); - if( astEqual( cf1, cf2 ) ){ - -/* Get the two Mappings and check that they are equal */ - m1 = astGetMapping( this->frameset, AST__BASE, AST__CURRENT ); - m2 = astGetMapping( that->frameset, AST__BASE, AST__CURRENT ); - if( astEqual( m1, m2 ) ) { - -/* Test the Negated and Closed flags are equal */ - if( astGetNegated( this ) == astGetNegated( that ) && - astGetClosed( this ) == astGetClosed( that ) ) { - result = 1; - } - } - -/* Free resources. */ - m1 = astAnnul( m1 ); - m2 = astAnnul( m2 ); - } - - cf1 = astAnnul( cf1 ); - cf2 = astAnnul( cf2 ); - } - - bf1 = astAnnul( bf1 ); - bf2 = astAnnul( bf2 ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void ClearUnc( AstRegion *this, int *status ){ -/* -*+ -* Name: -* astClearUnc - -* Purpose: -* Erase any uncertainty information in a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astClearUnc( AstRegion *this ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function erases all uncertainty information, whether default -* or not, from a Region. - -* Parameters: -* this -* Pointer to the Region. - -*- -*/ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Annul any user-supplied uncertainty. Also indicate that cached - information may now be out of date. */ - if( this->unc ) { - this->unc = astAnnul( this->unc ); - astResetCache( this ); - } - -/* Annul any default uncertainty. */ - if( this->defunc ) this->defunc = astAnnul( this->defunc ); - -} - -static AstFrameSet *FindFrame( AstFrame *target_frame, AstFrame *template, - const char *domainlist, int *status ) { -/* -* Name: -* FindFrame - -* Purpose: -* Find a coordinate system with specified characteristics. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstFrameSet *FindFrame( AstFrame *target, AstFrame *template, -* const char *domainlist, int *status ) - -* Class Membership: -* Region member function (over-rides the astFindFrame method -* inherited from the Frame class). - -* Description: -* This function uses a "template" Frame to search a Region to -* identify a coordinate system which has a specified set of -* characteristics. If a suitable coordinate system can be found, -* the function returns a pointer to a FrameSet which describes the -* required coordinate system and how to convert coordinates to and -* from it. - -* Parameters: -* target -* Pointer to the target Region. -* template -* Pointer to the template Frame, which should be an instance of -* the type of Frame you wish to find. -* domainlist -* Pointer to a null-terminated character string containing a -* comma-separated list of Frame domains. This may be used to -* establish a priority order for the different types of -* coordinate system that might be found. -* -* The function will first try to find a suitable coordinate -* system whose Domain attribute equals the first domain in this -* list. If this fails, the second domain in the list will be -* used, and so on, until a result is obtained. A blank domain -* (e.g. two consecutive commas) indicates that any coordinate -* system is acceptable (subject to the template) regardless of -* its domain. -* -* This list is case-insensitive and all white space is ignored. -* If you do not wish to restrict the domain in this way, you -* should supply an empty string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If the search is successful, the function returns a pointer to a -* FrameSet which contains the Frame found and a description of how -* to convert to (and from) the coordinate system it -* represents. Otherwise, a null Object pointer (AST__NULL) is -* returned without error. -* -* If a FrameSet is returned, it will contain two Frames. Frame -* number 1 (its base Frame) represents the target coordinate -* system and will be the same as the target. Frame number 2 (its -* current Frame) will be a Frame representing the coordinate system -* which the function found. The Mapping which inter-relates these two -* Frames will describe how to convert between their respective coordinate -* systems. Note, the Frames in this FrameSet will not be Regions - -* that is, they will be simple Frames or other derived classes. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - AstFrameSet *result; /* Pointer to result FrameSet */ - AstFrame *fr; /* Pointer to encapsulated Frame */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the astFindFrame method on the current Frame of the - encapsulated FrameSet within the target Region. */ - fr = astGetFrame( ((AstRegion *) target_frame)->frameset, AST__CURRENT ); - result = astFindFrame( fr, template, domainlist ); - fr = astAnnul( fr ); - -/* Return the result. */ - return result; -} - -static const char *Format( AstFrame *this_frame, int axis, double value, int *status ) { -/* -* Name: -* Format - -* Purpose: -* Format a coordinate value for a Region axis. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* const char *Format( AstFrame *this, int axis, double value, int *status ) - -* Class Membership: -* Region member function (over-rides the astFormat method -* inherited from the Frame class). - -* Description: -* This function returns a pointer to a string containing the -* formatted (character) version of a coordinate value for a -* Region axis. The formatting applied is that specified by a -* previous invocation of the astSetFormat method. A suitable -* default format is applied if necessary. - -* Parameters: -* this -* Pointer to the Region. -* axis -* The number of the axis (zero-based) for which formatting is -* to be performed. -* value -* The coordinate value to be formatted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a null-terminated string containing the formatted -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Region object, or at static memory. The contents of -* the string may be over-written or the pointer may become invalid -* following a further invocation of the same function or deletion -* of the Region. A copy of the string should therefore be made -* if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astFormat" ); - -/* Obtain a pointer to the Region's current Frame and invoke the - astFormat method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astFormat( fr, axis, value ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static double Gap( AstFrame *this_frame, int axis, double gap, int *ntick, int *status ) { -/* -* Name: -* Gap - -* Purpose: -* Find a "nice" gap for tabulating Region axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* double Gap( AstFrame *this, int axis, double gap, int *ntick, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astGap method -* inherited from the Frame class). - -* Description: -* This function returns a gap size which produces a nicely spaced -* series of formatted values for a Region axis, the returned gap -* size being as close as possible to the supplied target gap -* size. It also returns a convenient number of divisions into -* which the gap can be divided. - -* Parameters: -* this -* Pointer to the Region. -* axis -* The number of the axis (zero-based) for which a gap is to be found. -* gap -* The target gap size. -* ntick -* Address of an int in which to return a convenient number of -* divisions into which the gap can be divided. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The nice gap size. - -* Notes: -* - A value of zero is returned if the target gap size is zero. -* - A negative gap size is returned if the supplied gap size is negative. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - double result; /* Gap value to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astGap" ); - -/* Obtain a pointer to the Region's current Frame and invoke this - Frame's astGap method to obtain the required gap value. Annul the - Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astGap( fr, axis, gap, ntick ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* Region member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied Region, -* in bytes. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstRegion *this; /* Pointer to Region structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the Region structure. */ - this = (AstRegion *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astGetObjSize( this->frameset ); - result += astGetObjSize( this->points ); - result += astGetObjSize( this->basemesh ); - result += astGetObjSize( this->basegrid ); - result += astGetObjSize( this->unc ); - result += astGetObjSize( this->negation ); - result += astGetObjSize( this->defunc ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astGetAttrib -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Region, formatted as a character string. - -* Parameters: -* this -* Pointer to the Region. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Region, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Region. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstRegion *this; /* Pointer to the Region structure */ - const char *result; /* Pointer value to return */ - double dval; /* Floating point attribute value */ - int ival; /* Integer attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* We first handle attributes that apply to the Region as a whole - (rather than to the encapsulated FrameSet). */ - -/* Negated */ -/* ------- */ - if ( !strcmp( attrib, "negated" ) ) { - ival = astGetNegated( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Closed */ -/* ------ */ - } else if ( !strcmp( attrib, "closed" ) ) { - ival = astGetClosed( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Adaptive */ -/* -------- */ - } else if ( !strcmp( attrib, "adaptive" ) ) { - ival = astGetAdaptive( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* FillFactor */ -/* ---------- */ - } else if ( !strcmp( attrib, "fillfactor" ) ) { - dval = astGetFillFactor( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* MeshSize */ -/* -------- */ - } else if ( !strcmp( attrib, "meshsize" ) ) { - ival = astGetMeshSize( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Bounded */ -/* ------- */ - } else if ( !strcmp( attrib, "bounded" ) ) { - ival = astGetBounded( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Now get the values of attributes inherited from parent classes. We do - this to avoid the request being passed on to the encapsulated FrameSet - below. */ - -/* Class. */ -/* ------ */ - } else if ( !strcmp( attrib, "class" ) ) { - result = astGetClass( this ); - -/* ID. */ -/* --- */ - } else if ( !strcmp( attrib, "id" ) ) { - result = astGetID( this ); - -/* Ident. */ -/* ------ */ - } else if ( !strcmp( attrib, "ident" ) ) { - result = astGetIdent( this ); - -/* Invert. */ -/* ------- */ - } else if ( !strcmp( attrib, "invert" ) ) { - ival = astGetInvert( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Nin. */ -/* ---- */ - } else if ( !strcmp( attrib, "nin" ) ) { - ival = astGetNin( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Nobject. */ -/* -------- */ - } else if ( !strcmp( attrib, "nobject" ) ) { - ival = astGetNobject( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Nout. */ -/* ----- */ - } else if ( !strcmp( attrib, "nout" ) ) { - ival = astGetNout( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* RefCount. */ -/* --------- */ - } else if ( !strcmp( attrib, "refcount" ) ) { - ival = astGetRefCount( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Report. */ -/* ------- */ - } else if ( !strcmp( attrib, "report" ) ) { - ival = astGetReport( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TranForward. */ -/* ------------ */ - } else if ( !strcmp( attrib, "tranforward" ) ) { - ival = astGetTranForward( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TranInverse. */ -/* ------------ */ - } else if ( !strcmp( attrib, "traninverse" ) ) { - ival = astGetTranInverse( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Pass unrecognised attributes on to the Region's encapsulated FrameSet for - further interpretation. Do not pass on FrameSet attributes since we - pretend to the outside world that the encapsulated FrameSet is actually a - Frame. */ - } else if ( strcmp( attrib, "base" ) && - strcmp( attrib, "current" ) && - strcmp( attrib, "nframe" ) ) { - result = astGetAttrib( this->frameset, attrib ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static int GetBounded( AstRegion *this, int *status ) { -/* -*+ -* Name: -* astGetBounded - -* Purpose: -* Is the Region bounded? - -* Type: -* Protected function. - -* Synopsis: -* int astGetBounded( AstRegion *this ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a flag indicating if the Region is bounded. -* The implementation provided by the base Region class is suitable -* for Region sub-classes representing the inside of a single closed -* curve (e.g. Circle, Ellipse, Box, etc). Other sub-classes (such as -* CmpRegion, PointList, etc ) may need to provide their own -* implementations. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* Non-zero if the Region is bounded. Zero otherwise. - -*- -*/ - -/* For Regions which are defined by one or more closed curves such as Circles, - Boxes, etc, the Region is bounded so long as it has not been negated. - Classes for which this is not true should over-ride this implementation. */ - return !astGetNegated( this ); -} - -static AstAxis *GetAxis( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetAxis - -* Purpose: -* Obtain a pointer to a specified Axis from a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstAxis *GetAxis( AstFrame *this, int axis, int *status ) - -* Class Membership: -* Region member function (over-rides the astGetAxis method -* inherited from the Frame class). - -* Description: -* This function returns a pointer to the Axis object associated -* with one of the axes of the current Frame of a Region. This -* object describes the quantity which is represented along that -* axis. - -* Parameters: -* this -* Pointer to the Region. -* axis -* The number of the axis (zero-based) for which an Axis pointer -* is required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the requested Axis object. - -* Notes: -* - The reference count of the requested Axis object will be -* incremented by one to reflect the additional pointer returned by -* this function. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstAxis *result; /* Pointer to Axis */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astGetAxis" ); - -/* Obtain a pointer to the Region's encapsulated FrameSet and invoke - this FrameSet's astGetAxis method to obtain the required Axis - pointer. */ - result = astGetAxis( this->frameset, axis ); - -/* If an error occurred, annul the result. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstRegion *GetDefUnc( AstRegion *this, int *status ) { -/* -*+ -* Name: -* astGetDefUnc - -* Purpose: -* Obtain a pointer to the default uncertainty Region for a given Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstRegion *astGetDefUnc( AstRegion *this ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a pointer to a Region which represents the -* default uncertainty associated with a position on the boundary of the -* given Region. The returned Region refers to the base Frame within the -* FrameSet encapsulated by the supplied Region. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* A pointer to the Region. This should be annulled (using astAnnul) -* when no longer needed. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* Base Frame of supplied Region */ - AstRegion *result; /* Returned pointer */ - double *lbnd; /* Ptr. to array holding axis lower bounds */ - double *ubnd; /* Ptr. to array holding axis upper bounds */ - double c; /* Central axis value */ - double hw; /* Half width of uncertainty interval */ - int i; /* Axis index */ - int nax; /* Number of base Frame axes */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the base Frame in the supplied Region. */ - bfrm = astGetFrame( this->frameset, AST__BASE ); - -/* Get the number of base Frame axes. */ - nax = astGetNaxes( bfrm ); - -/* Get the base frame bounding box of the supplied Region. The astRegBaseBox - assumes the supplied Region has not been inverted. But if the Region - contains other Regions (e.g. a Prism or CmpRegion, etc) then this - assumption needs to be propagated to the component Regions, which - astRegBaseBox does not do. For this reason we use astRegBaseBox2 - instead. */ - lbnd = astMalloc( sizeof( double)*(size_t) nax ); - ubnd = astMalloc( sizeof( double)*(size_t) nax ); - astRegBaseBox2( this, lbnd, ubnd ); - -/* Create a Box covering 1.0E-6 of this bounding box, centred on the - centre of the box. */ - if( astOK ) { - for( i = 0; i < nax; i++ ) { - if( ubnd[ i ] != DBL_MAX && lbnd[ i ] != -DBL_MAX ) { - hw = fabs( 0.5E-6*( ubnd[ i ] - lbnd[ i ] ) ); - c = 0.5*( ubnd[ i ] + lbnd[ i ] ); - if( hw == 0.0 ) hw = c*0.5E-6; - ubnd[ i ] = c + hw; - lbnd[ i ] = c - hw; - } else { - ubnd[ i ] = 0.0; - lbnd[ i ] = 0.0; - } - } - result = (AstRegion *) astBox( bfrm, 1, lbnd, ubnd, NULL, "", status ); - } - -/* Free resources. */ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - bfrm = astAnnul( bfrm ); - -/* Return NULL if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the required pointer. */ - return result; -} - -static AstRegion *GetNegation( AstRegion *this, int *status ) { -/* -*+ -* Name: -* astGetNegation - -* Purpose: -* Obtain a pointer to a negated copy of the supplied Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstRegion *GetNegation( AstRegion *this, int *status ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a pointer to a Region which is a negated -* copy of "this". The copy is cached in the Region structure for -* future use. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* A pointer to the Region. This should be annulled (using astAnnul) -* when no longer needed. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* If the Region struture does not contain a pointer to a negated copy of - itself, create one now. */ - if( ! this->negation ) { - this->negation = astCopy( this ); - astNegate( this->negation ); - } - -/* Return a clone of the negation pointer. */ - return astClone( this->negation ); -} - -static AstFrameSet *GetRegFS( AstRegion *this, int *status ) { -/* -*+ -* Name: -* astGetRegFS - -* Purpose: -* Obtain a pointer to the FrameSet encapsulated within a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstFrameSet *astGetRegFS( AstRegion *this ) - -* Class Membership: -* Region virtual function - -* Description: -* This function returns a pointer to the FrameSet encapsulated by the -* Region. This is a clone, not a deep copy, of the pointer stored -* in the Region. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* A pointer to the FrameSet. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Return the required pointer. */ - return astClone( this->frameset ); -} - -static AstPointSet *GetSubMesh( int *mask, AstPointSet *in, int *status ) { -/* -* Name: -* GetSubMesh - -* Purpose: -* Extract a selection of points from a PointSet. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstPointSet *GetSubMesh( int *mask, AstPointSet *in, int *status ) - -* Class Membership: -* Region member function - -* Description: -* This function creates a new PointSet holding points selected from a -* supplied PointSet. An integer mask is supplied to indicate which -* points should be selected. - -* Parameters: -* mask -* Pointer to a mask array, Its size should be equal to the number -* of points in the supplied PointSet. Each corresponding point will -* be copied if the mask value is zero. -* in -* Pointer to the PointSet holding the input positions. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - double **ptr_in; /* Pointers to input axis values */ - double **ptr_out; /* Pointers to output axis values */ - double *pin; /* Pointer to next input axis value */ - double *pout; /* Pointer to next output axis value */ - int *m; /* Pointer to next mask element */ - int ic; /* Axis index */ - int ip; /* Point index */ - int nc; /* Number of axes in both PointSets */ - int npin; /* Number of points in input PointSet */ - int npout; /* Number of points in output PointSet */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the length of the mask. */ - npin = astGetNpoint( in ); - -/* Count the number of zeros in the mask. */ - npout = 0; - m = mask; - for( ip = 0; ip < npin; ip++ ) { - if( *(m++) == 0 ) npout++; - } - -/* Create the output PointSet and get pointers to its data arrays. */ - nc = astGetNcoord( in ); - result = astPointSet( npout, nc, "", status ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Check pointers can be dereferenced safely. */ - if( astOK ) { - -/* Copy the required axis values from the input to the output. */ - for( ic = 0; ic < nc; ic++ ) { - pin = ptr_in[ ic ]; - pout = ptr_out[ ic ]; - m = mask; - for( ip = 0; ip < npin; ip++, pin++, m++ ) { - if( *m == 0 ) *(pout++) = *pin; - } - } - } - -/* Return a pointer to the output PointSet. */ - return result; - -} - -static AstRegion *GetUnc( AstRegion *this, int def, int *status ){ -/* -*++ -* Name: -c astGetUnc -f AST_GETUNC - -* Purpose: -* Obtain uncertainty information from a Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c AstRegion *astGetUnc( AstRegion *this, int def ) -f RESULT = AST_GETUNC( THIS, DEF, STATUS ) - -* Class Membership: -* Region method. - -* Description: -* This function returns a Region which represents the uncertainty -* associated with positions within the supplied Region. See -c astSetUnc -f AST_SETUNC -* for more information about Region uncertainties and their use. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -c def -f DEF = LOGICAL (Given) -* Controls what is returned if no uncertainty information has been -* associated explicitly with the supplied Region. If -c a non-zero value -f .TRUE. -* is supplied, then the default uncertainty Region used internally -* within AST is returned (see "Applicability" below). If -c zero is supplied, then NULL -f .FALSE. is supplied, then AST__NULL -* will be returned (without error). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetUnc() -f AST_GETUNC = INTEGER -* A pointer to a Region describing the uncertainty in the supplied -* Region. - -* Applicability: -* CmpRegion -* The default uncertainty for a CmpRegion is taken from one of the -* two component Regions. If the first component Region has a -* non-default uncertainty, then it is used as the default uncertainty -* for the parent CmpRegion. Otherwise, if the second component Region -* has a non-default uncertainty, then it is used as the default -* uncertainty for the parent CmpRegion. If neither of the -* component Regions has non-default uncertainty, then the default -* uncertainty for the CmpRegion is 1.0E-6 of the bounding box of -* the CmpRegion. -* Prism -* The default uncertainty for a Prism is formed by combining the -* uncertainties from the two component Regions. If a component -* Region does not have a non-default uncertainty, then its default -* uncertainty will be used to form the default uncertainty of the -* parent Prism. -* Region -* For other classes of Region, the default uncertainty is 1.0E-6 -* of the bounding box of the Region. If the bounding box has zero -* width on any axis, then the uncertainty will be 1.0E-6 of the -* axis value. - -* Notes: -* - If uncertainty information is associated with a Region, and the -* coordinate system described by the Region is subsequently changed -* (e.g. by changing the value of its System attribute, or using the -c astMapRegion -f AST_MAPREGION -* function), then the uncertainty information returned by this function -* will be modified so that it refers to the coordinate system currently -* described by the supplied Region. -f - A null Object pointer (AST__NULL) will be returned if this -f function is invoked with STATUS set to an error value, or if it -c - A null Object pointer (NULL) will be returned if this -c function is invoked with the AST error status set, or if it -* should fail for any reason. - -*-- -*/ - -/* Local Variables: */ - AstRegion *result; /* Pointer to returned uncertainty Region */ - AstRegion *unc; /* Pointer to original uncertainty Region */ - -/* Initialise */ - result = NULL; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Check that we have an uncertainty Region to return (either assigned or - default). */ - if( def || astTestUnc( this ) ) { - -/* Obtain the uncertainty Region and take a copy so that we can modify it - without affecting the supplied Region. */ - unc = astGetUncFrm( this, AST__CURRENT ); - result = astCopy( unc ); - unc = astAnnul( unc ); - -/* In its current context, the uncertainty region is known to refer to - the Frame of the supplied Region and so its RegionFS attribute will be - set to zero, indicating that the uncertainty FrameSet need not be - dumped. However, outside of AST this information cannot be implied, so - clear the RegionFS attribute so that the returned pointer will include - Frame information if it is dumped to a Channel. */ - astClearRegionFS( result ); - - } - -/* Return the result. */ - return result; - -} - -static AstRegion *GetUncFrm( AstRegion *this, int ifrm, int *status ) { -/* -*+ -* Name: -* astGetUncFrm - -* Purpose: -* Obtain a pointer to the uncertainty Region for a given Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstRegion *astGetUncFrm( AstRegion *this, int ifrm ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a pointer to a Region which represents the -* uncertainty associated with a position on the boundary of the given -* Region. The returned Region can refer to the either the base or -* the current Frame within the FrameSet encapsulated by the supplied -* Region as specified by the "ifrm" parameter. If the returned Region is -* re-centred at some point on the boundary of the supplied Region, then -* the re-centred Region will represent the region in which the true -* boundary position could be. - -* Parameters: -* this -* Pointer to the Region. -* ifrm -* The index of a Frame within the FrameSet encapsulated by "this". -* The returned Region will refer to the requested Frame. It should -* be either AST__CURRENT or AST__BASE. - -* Returned Value: -* A pointer to the Region. This should be annulled (using astAnnul) -* when no longer needed. - -* Notes: -* - A default uncertainty Region will be created if the supplied Region -* does not have an uncertainty Region. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstFrame *frm; /* Current Frame from supplied Region */ - AstMapping *map; /* Supplied to uncertainty Mapping */ - AstRegion *result; /* Returned pointer */ - AstRegion *unc; /* Base frame uncertainty Region to use */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the Region has an explicitly assigned base-frame uncertainty Region, - use it. */ - if( this->unc ) { - unc = this->unc; - -/* If not, use the default base-frame uncertainty Region, creating it if - necessary. */ - } else { - if( !this->defunc ) this->defunc = astGetDefUnc( this ); - unc = this->defunc; - } - -/* If the uncertainty Region is the base Frame is required, just return a - clone of the uncertainty Region pointer. The Frame represented by an - uncertainty Region will always (barring bugs!) be the base Frame of - its parent Region. */ - if( ifrm == AST__BASE ) { - result = astClone( unc ); - -/* If the uncertainty Region is the current Frame is required... */ - } else { - -/* Get a Mapping from the Frame represented by the uncertainty Region - (the Region base Frame) to the Region current Frame. */ - map = astGetMapping( this->frameset, AST__BASE, AST__CURRENT ); - -/* If this is a UnitMap, the uncertainty Region is already in the correct - Frame, so just return the stored pointer. */ - if( astIsAUnitMap( map ) ) { - result = astClone( unc ); - -/* Otherwise, use this Mapping to map the uncertainty Region into the current - Frame. */ - } else { - frm = astGetFrame( this->frameset, AST__CURRENT ); - result = astMapRegion( unc, map, frm ); - -/* Free resources. */ - frm = astAnnul( frm ); - } - - map = astAnnul( map ); - } - -/* Return NULL if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the required pointer. */ - return result; -} - -static int GetUseDefs( AstObject *this_object, int *status ) { -/* -* Name: -* GetUseDefs - -* Purpose: -* Get the value of the UseDefs attribute for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int GetUseDefs( AstObject *this_object, int *status ) { - -* Class Membership: -* Region member function (over-rides the protected astGetUseDefs -* method inherited from the Frame class). - -* Description: -* This function returns the value of the UseDefs attribute for a -* Region. supplying a suitable default. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - The USeDefs value. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - int result; /* Value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_object; - -/* If the UseDefs value for the Region has been set explicitly, use the - Get method inherited from the parent Frame class to get its value. */ - if( astTestUseDefs( this ) ) { - result = (*parent_getusedefs)( this_object, status ); - -/* Otherwise, supply a default value equal to the UseDefs value of the - encapsulated Frame. */ - } else { - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astGetUseDefs( fr ); - fr = astAnnul( fr ); - } - -/* Return the result. */ - return result; -} - -static int TestUnc( AstRegion *this, int *status ) { -/* -*+ -* Name: -* astTestUnc - -* Purpose: -* Does the Region contain non-default uncertainty information? - -* Type: -* Protected function. - -* Synopsis: -* int astTestUnc( AstRegion *this ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a flag indicating if the uncertainty Region in -* the supplied Region was supplied explicit (i.e. is not a default -* uncertainty Region). - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* Non-zero if the uncertainty Region was supplied explicitly. -* Zero otherwise. - -* Notes: -* - Classes of Region that encapsulate two or more other Regions -* inherit their default uncertainty from the encapsulated Regions. -* Non-default uncertainty in the component Regions does not imply -* that the parent Region has non-default uncertainty. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - - return ( this->unc != NULL ); -} - -static AstFrame *RegFrame( AstRegion *this, int *status ) { -/* -*+ -* Name: -* astRegFrame - -* Purpose: -* Obtain a pointer to the current Frame for a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstFrame *astRegFrame( AstRegion *this ) - -* Class Membership: -* Region virtual function - -* Description: -* This function returns a pointer to the current Frame in the encapsulated -* FrameSet. This is a clone, not a deep copy, of the pointer stored -* in the FrameSet. For a deep copy, use astGetRegionFrame. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* A pointer to the Frame. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Return the required pointer. */ - return astGetFrame( this->frameset, AST__CURRENT ); -} - -static AstMapping *RegMapping( AstRegion *this, int *status ) { -/* -*+ -* Name: -* astRegMapping - -* Purpose: -* Obtain a pointer to the simplified base->current Mapping for a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstMapping *astRegMapping( AstRegion *this ) - -* Class Membership: -* Region member function - -* Description: -* This function returns a pointer to the Mapping from the base to the -* current Frame int he encapsulated FrameSet. The returned Mapping is -* simplified before being returned. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* A pointer to the Mapping. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstMapping *map; /* Unsimplified Mapping */ - AstMapping *result; /* Simplified Mapping */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the "nomap" flag is set in the Region structure, re return a - UnitMap. */ - if( this->nomap ) { - result = (AstMapping *) astUnitMap( astGetNin( this->frameset ), "", status ); - -/* Otherwise use the Mapping from the Region's FrameSet. */ - } else { - -/* Get the Mapping */ - map = astGetMapping( this->frameset, AST__BASE, AST__CURRENT ); - -/* Simplify it. */ - result = astSimplify( map ); - -/* Annul the pointer to the unsimplified Mapping */ - map = astAnnul( map ); - } - -/* Return the required pointer. */ - return result; -} - -static int GetNaxes( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetNaxes - -* Purpose: -* Determine how many axes a Region has. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int GetNaxes( AstFrame *this, int *status ) - -* Class Membership: -* Region member function (over-rides the astGetNaxes method -* inherited from the Frame class). - -* Description: -* This function returns the number of axes for a Region. This is equal -* to the number of axes in its current Frame. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of Region axes (zero or more). - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's current Frame. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - -/* Obtain the number of axes in this Frame. */ - result = astGetNaxes( fr ); - -/* Annul the current Frame pointer. */ - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static const int *GetPerm( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetPerm - -* Purpose: -* Access the axis permutation array for the current Frame of a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* const int *GetPerm( AstFrame *this, int *status ) - -* Class Membership: -* Region member function (over-rides the astGetPerm protected -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the axis permutation array -* for the current Frame of a Region. This array constitutes a -* lookup-table that converts between an axis number supplied -* externally and the corresponding index in the Frame's internal -* axis arrays. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the current Frame's axis permutation array (a -* constant array of int). Each element of this contains the -* (zero-based) internal axis index to be used in place of the -* external index which is used to address the permutation -* array. If the current Frame has zero axes, this pointer will be -* NULL. - -* Notes: -* - The pointer returned by this function gives direct access to -* data internal to the Frame object. It remains valid only so long -* as the Frame exists. The permutation array contents may be -* modified by other functions which operate on the Frame and this -* may render the returned pointer invalid. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to Region structure */ - const int *result; /* Result pointer value */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's current Frame and then obtain a - pointer to its axis permutation array. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astGetPerm( fr ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static AstFrame *GetRegionFrame( AstRegion *this, int *status ) { -/* -*++ -* Name: -c astGetRegionFrame -f AST_GETREGIONFRAME - -* Purpose: -* Obtain a pointer to the encapsulated Frame within a Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c AstFrame *astGetRegionFrame( AstRegion *this ) -f RESULT = AST_GETREGIONFRAME( THIS, STATUS ) - -* Class Membership: -* Region method. - -* Description: -* This function returns a pointer to the Frame represented by a -* Region. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetRegionFrame() -f AST_GETREGIONFRAME = INTEGER -* A pointer to a deep copy of the Frame represented by the Region. -* Using this pointer to modify the Frame will have no effect on -* the Region. To modify the Region, use the Region pointer directly. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstFrame *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the current Frame of the encapsulated FrameSet. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - -/* Take a deep copy of it, and then annul the original pointer. */ - result = astCopy( fr ); - fr = astAnnul( fr ); - -/* If not OK, annul the returned pointer. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstFrameSet *GetRegionFrameSet( AstRegion *this, int *status ) { -/* -*++ -* Name: -c astGetRegionFrameSet -f AST_GETREGIONFRAMESET - -* Purpose: -* Obtain a pointer to the encapsulated FrameSet within a Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c AstFrame *astGetRegionFrameSet( AstRegion *this ) -f RESULT = AST_GETREGIONFRAMESET( THIS, STATUS ) - -* Class Membership: -* Region method. - -* Description: -* This function returns a pointer to the FrameSet encapsulated by a -* Region. The base Frame is the Frame in which the box was originally -* defined, and the current Frame is the Frame into which the Region -* is currently mapped (i.e. it will be the same as the Frame returned -c by astGetRegionFrame). -f by AST_GETREGIONFRAME). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetRegionFrameSet() -f AST_GETREGIONFRAMESET = INTEGER -* A pointer to a deep copy of the FrameSet represented by the Region. -* Using this pointer to modify the FrameSet will have no effect on -* the Region. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Return a deep copy of the encapsulated FrameSet. */ - return astCopy( this->frameset ); -} - -void astInitRegionVtab_( AstRegionVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitRegionVtab - -* Purpose: -* Initialise a virtual function table for a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astInitRegionVtab( AstRegionVtab *vtab, const char *name ) - -* Class Membership: -* Region vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Region class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameVtab( (AstFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsARegion) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ - -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->ClearNegated = ClearNegated; - vtab->GetNegated = GetNegated; - vtab->SetNegated = SetNegated; - vtab->TestNegated = TestNegated; - - vtab->ClearRegionFS = ClearRegionFS; - vtab->GetRegionFS = GetRegionFS; - vtab->SetRegionFS = SetRegionFS; - vtab->TestRegionFS = TestRegionFS; - - vtab->ClearClosed = ClearClosed; - vtab->GetClosed = GetClosed; - vtab->SetClosed = SetClosed; - vtab->TestClosed = TestClosed; - - vtab->ClearMeshSize = ClearMeshSize; - vtab->GetMeshSize = GetMeshSize; - vtab->SetMeshSize = SetMeshSize; - vtab->TestMeshSize = TestMeshSize; - - vtab->ClearAdaptive = ClearAdaptive; - vtab->GetAdaptive = GetAdaptive; - vtab->SetAdaptive = SetAdaptive; - vtab->TestAdaptive = TestAdaptive; - - vtab->ClearFillFactor = ClearFillFactor; - vtab->GetFillFactor = GetFillFactor; - vtab->SetFillFactor = SetFillFactor; - vtab->TestFillFactor = TestFillFactor; - - vtab->ResetCache = ResetCache; - vtab->RegTrace = RegTrace; - vtab->GetBounded = GetBounded; - vtab->TestUnc = TestUnc; - vtab->ClearUnc = ClearUnc; - vtab->GetRegionFrame = GetRegionFrame; - vtab->GetRegionFrameSet = GetRegionFrameSet; - vtab->MapRegion = MapRegion; - vtab->Overlap = Overlap; - vtab->OverlapX = OverlapX; - vtab->Negate = Negate; - vtab->BndMesh = BndMesh; - vtab->BndBaseMesh = BndBaseMesh; - vtab->RegBaseGrid = RegBaseGrid; - vtab->RegBaseMesh = RegBaseMesh; - vtab->RegSplit = RegSplit; - vtab->RegBaseBox = RegBaseBox; - vtab->RegBaseBox2 = RegBaseBox2; - vtab->RegBasePick = RegBasePick; - vtab->RegCentre = RegCentre; - vtab->RegGrid = RegGrid; - vtab->RegMesh = RegMesh; - vtab->RegClearAttrib = RegClearAttrib; - vtab->RegSetAttrib = RegSetAttrib; - vtab->GetDefUnc = GetDefUnc; - vtab->GetNegation = GetNegation; - vtab->GetUncFrm = GetUncFrm; - vtab->SetUnc = SetUnc; - vtab->GetUnc = GetUnc; - vtab->ShowMesh = ShowMesh; - vtab->GetRegionBounds = GetRegionBounds; - vtab->GetRegionBounds2 = GetRegionBounds2; - vtab->GetRegionMesh = GetRegionMesh; - vtab->GetRegionPoints = GetRegionPoints; - vtab->RegOverlay = RegOverlay; - vtab->RegFrame = RegFrame; - vtab->RegDummyFS = RegDummyFS; - vtab->RegMapping = RegMapping; - vtab->RegPins = RegPins; - vtab->RegTransform = RegTransform; - vtab->BTransform = BTransform; - vtab->GetRegFS = GetRegFS; - vtab->SetRegFS = SetRegFS; - vtab->MaskB = MaskB; - vtab->MaskD = MaskD; - vtab->MaskF = MaskF; - vtab->MaskI = MaskI; - vtab->MaskL = MaskL; - vtab->MaskS = MaskS; - vtab->MaskUB = MaskUB; - vtab->MaskUI = MaskUI; - vtab->MaskUL = MaskUL; - vtab->MaskUS = MaskUS; -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - vtab->MaskLD = MaskLD; -#endif - -/* Save the inherited pointers to methods that will be extended, and store - replacement pointers for methods which will be over-ridden by new member - functions implemented here. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - frame = (AstFrameVtab *) vtab; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_getusedefs = object->GetUseDefs; - object->GetUseDefs = GetUseDefs; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - object->Cast = Cast; - object->Equal = Equal; - object->ClearAttrib = ClearAttrib; - object->GetAttrib = GetAttrib; - object->SetAttrib = SetAttrib; - object->TestAttrib = TestAttrib; - - mapping->ReportPoints = ReportPoints; - mapping->RemoveRegions = RemoveRegions; - mapping->Simplify = Simplify; - - frame->Abbrev = Abbrev; - frame->Angle = Angle; - frame->AxAngle = AxAngle; - frame->AxDistance = AxDistance; - frame->AxNorm = AxNorm; - frame->AxOffset = AxOffset; - frame->CheckPerm = CheckPerm; - frame->ClearDigits = ClearDigits; - frame->ClearDirection = ClearDirection; - frame->ClearDomain = ClearDomain; - frame->ClearFormat = ClearFormat; - frame->ClearLabel = ClearLabel; - frame->ClearMatchEnd = ClearMatchEnd; - frame->ClearMaxAxes = ClearMaxAxes; - frame->ClearMinAxes = ClearMinAxes; - frame->ClearPermute = ClearPermute; - frame->ClearPreserveAxes = ClearPreserveAxes; - frame->ClearSymbol = ClearSymbol; - frame->ClearTitle = ClearTitle; - frame->ClearUnit = ClearUnit; - frame->Convert = Convert; - frame->ConvertX = ConvertX; - frame->Distance = Distance; - frame->FindFrame = FindFrame; - frame->Format = Format; - frame->Centre = Centre; - frame->Gap = Gap; - frame->GetAxis = GetAxis; - frame->GetDigits = GetDigits; - frame->GetDirection = GetDirection; - frame->GetDomain = GetDomain; - frame->GetFormat = GetFormat; - frame->GetLabel = GetLabel; - frame->GetMatchEnd = GetMatchEnd; - frame->GetMaxAxes = GetMaxAxes; - frame->GetMinAxes = GetMinAxes; - frame->GetNaxes = GetNaxes; - frame->GetPerm = GetPerm; - frame->GetPermute = GetPermute; - frame->GetPreserveAxes = GetPreserveAxes; - frame->GetSymbol = GetSymbol; - frame->GetTitle = GetTitle; - frame->GetUnit = GetUnit; - frame->Intersect = Intersect; - frame->IsUnitFrame = IsUnitFrame; - frame->Match = Match; - frame->Norm = Norm; - frame->NormBox = NormBox; - frame->Offset = Offset; - frame->Offset2 = Offset2; - frame->Overlay = Overlay; - frame->PermAxes = PermAxes; - frame->PickAxes = PickAxes; - frame->Resolve = Resolve; - frame->ResolvePoints = ResolvePoints; - frame->SetAxis = SetAxis; - frame->SetDigits = SetDigits; - frame->SetDirection = SetDirection; - frame->SetDomain = SetDomain; - frame->SetFormat = SetFormat; - frame->SetLabel = SetLabel; - frame->SetMatchEnd = SetMatchEnd; - frame->SetMaxAxes = SetMaxAxes; - frame->SetMinAxes = SetMinAxes; - frame->SetPermute = SetPermute; - frame->SetPreserveAxes = SetPreserveAxes; - frame->SetSymbol = SetSymbol; - frame->SetTitle = SetTitle; - frame->SetUnit = SetUnit; - frame->SubFrame = SubFrame; - frame->SystemCode = SystemCode; - frame->SystemString = SystemString; - frame->TestDigits = TestDigits; - frame->TestDirection = TestDirection; - frame->TestDomain = TestDomain; - frame->TestFormat = TestFormat; - frame->TestLabel = TestLabel; - frame->TestMatchEnd = TestMatchEnd; - frame->TestMaxAxes = TestMaxAxes; - frame->TestMinAxes = TestMinAxes; - frame->TestPermute = TestPermute; - frame->TestPreserveAxes = TestPreserveAxes; - frame->TestSymbol = TestSymbol; - frame->TestTitle = TestTitle; - frame->TestUnit = TestUnit; - frame->Unformat = Unformat; - frame->ValidateAxis = ValidateAxis; - frame->ValidateAxisSelection = ValidateAxisSelection; - frame->ValidateSystem = ValidateSystem; - frame->LineDef = LineDef; - frame->LineContains = LineContains; - frame->LineCrossing = LineCrossing; - frame->LineOffset = LineOffset; - frame->MatchAxes = MatchAxes; - frame->MatchAxesX = MatchAxesX; - - frame->GetActiveUnit = GetActiveUnit; - frame->SetActiveUnit = SetActiveUnit; - frame->TestActiveUnit = TestActiveUnit; - - frame->GetTop = GetTop; - frame->SetTop = SetTop; - frame->TestTop = TestTop; - frame->ClearTop = ClearTop; - - frame->GetBottom = GetBottom; - frame->SetBottom = SetBottom; - frame->TestBottom = TestBottom; - frame->ClearBottom = ClearBottom; - - frame->GetEpoch = GetEpoch; - frame->SetEpoch = SetEpoch; - frame->TestEpoch = TestEpoch; - frame->ClearEpoch = ClearEpoch; - - frame->ClearObsAlt = ClearObsAlt; - frame->TestObsAlt = TestObsAlt; - frame->GetObsAlt = GetObsAlt; - frame->SetObsAlt = SetObsAlt; - - frame->ClearObsLat = ClearObsLat; - frame->TestObsLat = TestObsLat; - frame->GetObsLat = GetObsLat; - frame->SetObsLat = SetObsLat; - - frame->ClearObsLon = ClearObsLon; - frame->TestObsLon = TestObsLon; - frame->GetObsLon = GetObsLon; - frame->SetObsLon = SetObsLon; - - frame->GetSystem = GetSystem; - frame->SetSystem = SetSystem; - frame->TestSystem = TestSystem; - frame->ClearSystem = ClearSystem; - - frame->GetAlignSystem = GetAlignSystem; - frame->SetAlignSystem = SetAlignSystem; - frame->TestAlignSystem = TestAlignSystem; - frame->ClearAlignSystem = ClearAlignSystem; - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "Region", - "An area within a coordinate system" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void Intersect( AstFrame *this_frame, const double a1[2], - const double a2[2], const double b1[2], - const double b2[2], double cross[2], - int *status ) { -/* -* Name: -* Intersect - -* Purpose: -* Find the point of intersection between two geodesic curves. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void Intersect( AstFrame *this_frame, const double a1[2], -* const double a2[2], const double b1[2], -* const double b2[2], double cross[2], -* int *status ) - -* Class Membership: -* Region member function (over-rides the astIntersect method -* inherited from the Frame class). - -* Description: -* This function finds the coordinate values at the point of -* intersection between two geodesic curves. Each curve is specified -* by two points on the curve. - -* Parameters: -* this -* Pointer to the SkyFrame. -* a1 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a point on the first -* geodesic curve. -* a2 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a second point on the -* first geodesic curve. -* b1 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a point on the second -* geodesic curve. -* b2 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a second point on -* the second geodesic curve. -* cross -* An array of double, with one element for each Frame axis -* in which the coordinates of the required intersection -* point will be returned. These will be AST__BAD if the curves do -* not intersect. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -* - For SkyFrames each curve will be a great circle, and in general -* each pair of curves will intersect at two diametrically opposite -* points on the sky. The returned position is the one which is -* closest to point "a1". -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke the - astIntersect method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astIntersect( fr, a1, a2, b1, b2, cross ); - fr = astAnnul( fr ); -} - -static int IsUnitFrame( AstFrame *this, int *status ){ -/* -* Name: -* IsUnitFrame - -* Purpose: -* Is this Frame equivalent to a UnitMap? - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int IsUnitFrame( AstFrame *this, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astIsUnitFrame -* method inherited from the Frame class). - -* Description: -* This function returns a flag indicating if the supplied Frame is -* equivalent to a UnitMap when treated as a Mapping (note, the Frame -* class inherits from Mapping and therefore every Frame is also a Mapping). - -* Parameters: -* this -* Pointer to the Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the supplied Frame is equivalent to -* a UnitMap when treated as a Mapping. - -*- -*/ - -/* Check the global error status. */ - if( !astOK ) return 0; - -/* The Region class is never equivalent to a UnitMap. */ - return 0; -} - -static int LineContains( AstFrame *this_frame, AstLineDef *l, int def, double *point, int *status ) { -/* -* Name: -* LineContains - -* Purpose: -* Determine if a line contains a point. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int LineContains( AstFrame *this, AstLineDef *l, int def, double *point, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astLineContains -* method inherited from the Frame class). - -* Description: -* This function determines if the supplied point is on the supplied -* line within the supplied Frame. The start point of the line is -* considered to be within the line, but the end point is not. The tests -* are that the point of closest approach of the line to the point should -* be between the start and end, and that the distance from the point to -* the point of closest aproach should be less than 1.0E-7 of the length -* of the line. - -* Parameters: -* this -* Pointer to the Frame. -* l -* Pointer to the structure defining the line. -* def -* Should be set non-zero if the "point" array was created by a -* call to astLineCrossing (in which case it may contain extra -* information following the axis values),and zero otherwise. -* point -* Point to an array containing the axis values of the point to be -* tested, possibly followed by extra cached information (see "def"). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the line contains the point. - -* Notes: -* - The pointer supplied for "l" should have been created using the -* astLineDef method. These structures contained cached information about -* the lines which improve the efficiency of this method when many -* repeated calls are made. An error will be reported if the structure -* does not refer to the Frame specified by "this". -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - int result; /* Returned value */ - -/* Initialise */ - result =0; - -/* Obtain a pointer to the Region's current Frame and then invoke the - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( ((AstRegion *) this_frame)->frameset, AST__CURRENT ); - result = astLineContains( fr, l, def, point ); - fr = astAnnul( fr ); - -/* Return the result. */ - return result; -} - -static int LineCrossing( AstFrame *this_frame, AstLineDef *l1, AstLineDef *l2, - double **cross, int *status ) { -/* -* Name: -* LineCrossing - -* Purpose: -* Determine if two lines cross. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int LineCrossing( AstFrame *this, AstLineDef *l1, AstLineDef *l2, -* double **cross, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astLineCrossing -* method inherited from the Frame class). - -* Description: -* This function determines if the two suplied line segments cross, -* and if so returns the axis values at the point where they cross. -* A flag is also returned indicating if the crossing point occurs -* within the length of both line segments, or outside one or both of -* the line segments. - -* Parameters: -* this -* Pointer to the Frame. -* l1 -* Pointer to the structure defining the first line. -* l2 -* Pointer to the structure defining the second line. -* cross -* Pointer to a location at which to put a pointer to a dynamically -* alocated array containing the axis values at the crossing. If -* NULL is supplied no such array is returned. Otherwise, the returned -* array should be freed using astFree when no longer needed. If the -* lines are parallel (i.e. do not cross) then AST__BAD is returned for -* all axis values. Note usable axis values are returned even if the -* lines cross outside the segment defined by the start and end points -* of the lines. The order of axes in the returned array will take -* account of the current axis permutation array if appropriate. Note, -* sub-classes such as SkyFrame may append extra values to the end -* of the basic frame axis values. A NULL pointer is returned if an -* error occurs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the lines cross at a point which is -* within the [start,end) segment of both lines. If the crossing point -* is outside this segment on either line, or if the lines are parallel, -* zero is returned. Note, the start point is considered to be inside -* the length of the segment, but the end point is outside. - -* Notes: -* - The pointers supplied for "l1" and "l2" should have been created -* using the astLineDef method. These structures contained cached -* information about the lines which improve the efficiency of this method -* when many repeated calls are made. An error will be reported if -* either structure does not refer to the Frame specified by "this". -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - int result; /* Returned value */ - -/* Initialise */ - result =0; - -/* Obtain a pointer to the Region's current Frame and then invoke the - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( ((AstRegion *) this_frame)->frameset, AST__CURRENT ); - result = astLineCrossing( fr, l1, l2, cross ); - fr = astAnnul( fr ); - -/* Return the result. */ - return result; -} - -static AstLineDef *LineDef( AstFrame *this_frame, const double start[2], - const double end[2], int *status ) { -/* -* Name: -* LineDef - -* Purpose: -* Creates a structure describing a line segment in a 2D Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstLineDef *LineDef( AstFrame *this, const double start[2], -* const double end[2], int *status ) - -* Class Membership: -* Region member function (over-rides the protected astLineDef -* method inherited from the Frame class). - -* Description: -* This function creates a structure containing information describing a -* given line segment within the supplied 2D Frame. This may include -* information which allows other methods such as astLineCrossing to -* function more efficiently. Thus the returned structure acts as a -* cache to store intermediate values used by these other methods. - -* Parameters: -* this -* Pointer to the Frame. Must have 2 axes. -* start -* An array of 2 doubles marking the start of the line segment. -* end -* An array of 2 doubles marking the end of the line segment. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the memory structure containing the description of the -* line. This structure should be freed using astFree when no longer -* needed. A NULL pointer is returned (without error) if any of the -* supplied axis values are AST__BAD. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstLineDef *result; /* Returned value */ - -/* Initialise */ - result = NULL; - -/* Obtain a pointer to the Region's current Frame and then invoke the - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( ((AstRegion *) this_frame)->frameset, AST__CURRENT ); - result = astLineDef( fr, start, end ); - fr = astAnnul( fr ); - -/* Return the result. */ - return result; -} - -static void LineOffset( AstFrame *this_frame, AstLineDef *line, double par, - double prp, double point[2], int *status ){ -/* -* Name: -* LineOffset - -* Purpose: -* Find a position close to a line. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void LineOffset( AstFrame *this, AstLineDef *line, double par, -* double prp, double point[2], int *status ) - -* Class Membership: -* Region member function (over-rides the protected astLineOffset -* method inherited from the Frame class). - -* Description: -* This function returns a position formed by moving a given distance along -* the supplied line, and then a given distance away from the supplied line. - -* Parameters: -* this -* Pointer to the Frame. -* line -* Pointer to the structure defining the line. -* par -* The distance to move along the line from the start towards the end. -* prp -* The distance to move at right angles to the line. Positive -* values result in movement to the left of the line, as seen from -* the observer, when moving from start towards the end. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The pointer supplied for "line" should have been created using the -* astLineDef method. This structure contains cached information about the -* line which improves the efficiency of this method when many repeated -* calls are made. An error will be reported if the structure does not -* refer to the Frame specified by "this". -*/ - - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - -/* Obtain a pointer to the Region's current Frame and then invoke the - method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( ((AstRegion *) this_frame)->frameset, AST__CURRENT ); - astLineOffset( fr, line, par, prp, point ); - fr = astAnnul( fr ); -} - - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* Region member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstRegion *this; /* Pointer to Region structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the Region structure. */ - this = (AstRegion *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->frameset, mode, extra, fail ); - if( !result ) result = astManageLock( this->points, mode, extra, fail ); - if( !result ) result = astManageLock( this->unc, mode, extra, fail ); - if( !result ) result = astManageLock( this->negation, mode, extra, fail ); - if( !result ) result = astManageLock( this->defunc, mode, extra, fail ); - if( !result ) result = astManageLock( this->basemesh, mode, extra, fail ); - if( !result ) result = astManageLock( this->basegrid, mode, extra, fail ); - - return result; - -} -#endif - -static AstRegion *MapRegion( AstRegion *this, AstMapping *map0, - AstFrame *frame0, int *status ) { -/* -*+ -* Name: -* astMapRegion - -* Purpose: -* Transform a Region into a new Frame using a given Mapping. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "region.h" -* AstRegion *astMapRegion( AstRegion *this, AstMapping *map, -* AstFrame *frame ) - -* Class Membership: -* Region method. - -* Description: -* This function returns a pointer to a new Region which corresponds to -* supplied Region in some other specified coordinate system. A -* Mapping is supplied which transforms positions between the old and new -* coordinate systems. The new Region may not be of the same class as -* the original region. - -* Parameters: -* this -* Pointer to the Region. -* map -* Pointer to a Mapping which transforms positions from the -* coordinate system represented by the supplied Region to the -* coordinate system specified by "frame". The supplied Mapping should -* define both forward and inverse transformations, and these -* transformations should form a genuine inverse pair. That is, -* transforming a position using the forward transformation and then -* using the inverse transformation should produce the original input -* position. Some Mapping classes (such as PermMap, MathMap, SphMap) -* can result in Mappings for which this is not true. -* frame -* Pointer to a Frame describing the coordinate system in which -* the new Region is required. - -* Returned Value: -* astMapRegion() -* A pointer to a new Region. This Region will represent the area -* within the coordinate system specified by "frame" which corresponds -* to the supplied Region. - -* Notes: -* - This is the protected implementation of this function - it does -* not simplify the returned Region. The public implementation is -* astMapRegionID, which simplifies the returned Region. -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstFrame *frame; - AstFrameSet *fs; - AstMapping *tmap; - AstMapping *usemap; - AstMapping *map; - AstPointSet *ps1; - AstPointSet *pst; - AstPointSet *ps2; - AstRegion *usethis; - AstRegion *result; - double **ptr1; - double **ptr2; - int *axflags; - int *inax; - int *keep; - int *outax; - int i; - int icurr; - int j; - int nax1; - int nkept; - int nnew; - int nold; - int np; - int ntotal; - int ok; - -/* Initialise returned value. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise local variables */ - axflags = NULL; - -/* If a FrameSet was supplied for the Mapping, use the base->current - Mapping */ - if( astIsAFrameSet( map0 ) ) { - map = astGetMapping( (AstFrameSet *) map0, AST__BASE, AST__CURRENT ); - } else { - map = astClone( map0 ); - } - -/* If a FrameSet was supplied for the Frame, use the current Frame. */ - if( astIsAFrameSet( frame0 ) ) { - frame = astGetFrame( (AstFrameSet *) frame0, AST__CURRENT ); - } else { - frame = astClone( frame0 ); - } - -/* First check the Mapping is suitable. It must defined both a forward - and an inverse Mapping. */ - if( !astGetTranInverse( map ) ) { - astError( AST__NODEF, "astMapRegion(%s): The supplied %s does not " - "define an inverse transformation.", status, astGetClass( this ), - astGetClass( map ) ); - } else if( !astGetTranForward( map ) ) { - astError( AST__NODEF, "astMapRegion(%s): The supplied %s does not " - "define a forward transformation.", status, astGetClass( this ), - astGetClass( map ) ); - } - - -/* Get the number of axes in the supplied Region. */ - nold = astGetNaxes( this ); - -/* Get the number of axes in the returned Region. */ - nnew = astGetNaxes( frame ); - -/* The forward transformation must not introduce any bad axis values. We - can only perform this test reliably if the supplied Region has no bad - axis values. */ - ps1 = this->points; - if( ps1 ) { - nax1 = astGetNcoord( ps1 ); - np = astGetNpoint( ps1 ); - ptr1 = astGetPoints( ps1 ); - if( ptr1 ) { - -/* Check the axis values defining the Region are good. */ - ok = 1; - for( i = 0; i < nax1 && ok; i++ ){ - for( j = 0; j < np; j++ ) { - if( ptr1[ i ][ j ] == AST__BAD ){ - ok = 0; - break; - } - } - } - if( ok ) { - -/* Transform the points defining the supplied Region into the current Frame - of the Region. */ - pst = astRegTransform( this, ps1, 1, NULL, NULL ); - -/* The use the supplied Mapping to transfom them into the new Frame. */ - ps2 = astTransform( map, pst, 1, NULL ); - -/* Test if any of these axis values are bad. */ - ptr2 = astGetPoints( ps2 ); - if( ptr2 ) { - for( i = 0; i < nnew && ok; i++ ){ - for( j = 0; j < np; j++ ) { - if( ptr2[ i ][ j ] == AST__BAD ){ - ok = 0; - break; - } - } - } - if( !ok ) { - astError( AST__NODEF, "astMapRegion(%s): The region which " - "results from using the supplied %s to transform " - "the supplied %s is undefined.", status, astGetClass( this ), - astGetClass( map ), astGetClass( this ) ); - -/* If all axis values are good, use the inverse transformation of the - supplied Mapping to transform them back to the Frame of the supplied - Region. */ - } else { - pst = astAnnul( pst ); - pst = astTransform( map, ps2, 0, NULL ); - -/* Get a flag for each input of the supplied Mapping (i.e. each axis of - the supplied Region) which is non-zero if the inverse transformation - of the Mapping has produced any good axis values. */ - ptr1 = astGetPoints( pst ); - axflags = astCalloc( nold, sizeof(int) ); - if( astOK ) { - for( i = 0; i < nold; i++ ){ - for( j = 0; j < np; j++ ) { - if( ptr1[ i ][ j ] != AST__BAD ){ - axflags[ i ] = 1; - break; - } - } - } - } - } - } - ps2 = astAnnul( ps2 ); - pst = astAnnul( pst ); - } - } - } - -/* Assume we will be using the supplied Region (this) and Mapping (map). */ - usethis = astClone( this ); - usemap = astClone( map ); - -/* If the new Frame for the Region has fewer axes than the old Frame, see - if we can discard some base-frame axes. We only do this if the inverse - transformation would otherwise supply bad values for the unused axes. - Using bad axis values is not a good idea as some operations cannot be - performed if any bad values are supplied. Also having more axes than - needed is bad as it results in fewer mesh points per axis. */ - if( nnew < nold ) { - -/* First invert the Mapping since astMapSplit only allows selection of - inputs, and we want to select outputs. */ - astInvert( map ); - -/* Create an array holding the indices of the required inputs. */ - inax = astMalloc( nnew*sizeof(int) ); - if( astOK ) for( i = 0; i < nnew; i++ ) inax[i] = i; - -/* Attempt to split the mapping to extract a new mapping that omits any - unnecessary outputs (i.e. outputs that are indepenent of the selected - inputs). Check the Mapping was split successfully. */ - outax = astMapSplit( map, nnew, inax, &tmap ); - if( outax ) { - -/* Get the number of old axes that have been retained in the Mapping. */ - nkept = astGetNout( tmap ); - -/* Now we need to ensure that any unused axes for which the Mapping - creates non-bad values are retained (such values are significant - since they may determine whether the new Region is null or not). - We only need to do this if any of the outputs that were split off - above have been found to generate good values, as indicated by the - "axflags" array. Count the number of extra axes that need to be kept, - over and above those that are kept by the Mapping returned by - astMapSplit above. */ - ntotal = 0; - keep = NULL; - if( axflags ) { - keep = astMalloc( nold*sizeof(int) ); - if( astOK ) { - -/* Loop round each axis in the supplied Region. */ - for( i = 0; i < nold; i++ ) { - -/* Search the "outax" array to see if this axis was retained by astMapSplit. - If it was, append its index to the total list of axes to keep. */ - ok = 0; - for( j = 0; j < nkept; j++ ) { - if( outax[ j ] == i ) { - keep[ ntotal++ ] = i; - ok = 1; - break; - } - } - -/* If the axis was not retained by astMapSplit, but generates good axis - values, also append its index to the total list of axes to keep. */ - if( !ok && axflags[ i ] ) { - keep[ ntotal++ ] = i; - } - } - } - } - -/* If there are no extra axes to keep, then the Mapping returned by - astMapSplit above can be used as it is. */ - if( ntotal == nkept ) { - -/* The values in the "outax" array will hold the zero-based indices of - the original old axes that are retained by the new Mapping. We need to - create a copy of the supplied Region that includes only these axes. */ - usethis = astAnnul( usethis ); - usethis = astPickAxes( this, nkept, outax, NULL ); - -/* Use the temportary Mapping returned by astMapSplit in place of the - supplied Mapping (remember to invert to undo the inversion performed - above). */ - usemap = astAnnul( usemap ); - usemap = astClone( tmap ); - astInvert( usemap ); - -/* Free temporary resources. */ - tmap = astAnnul( tmap ); - outax = astFree( outax ); - -/* If we need to retain some extra axes because they generate good values - (even though they are independent of the new Frame axes)... */ - } else if( ntotal > nkept ){ - -/* We know the old Frame axes that we want to keep, so use astMapSplit - in the opposite direction - i.e. use it on the Mapping form old to - new. */ - astInvert( map ); - - tmap = astAnnul( tmap ); - outax = astFree( outax ); - - outax = astMapSplit( map, ntotal, keep, &tmap ); - if( outax ) { - - usethis = astAnnul( usethis ); - usethis = astPickAxes( this, ntotal, keep, NULL ); - - usemap = astAnnul( usemap ); - usemap = astClone( tmap ); - - tmap = astAnnul( tmap ); - outax = astFree( outax ); - - } - - astInvert( map ); - } - keep = astFree( keep ); - } - inax = astFree( inax ); - -/* Invert the Mapping again to bring it back to its original state. */ - astInvert( map ); - } - -/* Take a deep copy of the supplied Region. */ - result = astCopy( usethis ); - -/* Get a pointer to the encapsulated FrameSet. */ - if( astOK ) { - fs = result->frameset; - -/* Add in the new Frame and Mapping. First note the index of the original - current Frame. */ - icurr = astGetCurrent( fs ); - astAddFrame( fs, AST__CURRENT, usemap, frame ); - -/* Remove the original current Frame. */ - astRemoveFrame( fs, icurr ); - -/* The base and current Frames of the resulting FrameSet are now (in - general) different and so the Region should include its FrameSet in any - Dump. */ - astSetRegionFS( result, 1 ); - } - -/* Since the Mapping has been changed, any cached information calculated - on the basis of the Mapping properties may no longer be up to date. */ - astResetCache( result ); - -/* Free resources */ - usemap = astAnnul( usemap ); - usethis = astAnnul( usethis ); - map = astAnnul( map ); - frame = astAnnul( frame ); - axflags = astFree( axflags ); - -/* If not OK, annul the returned pointer. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -/* -*++ -* Name: -c astMask -f AST_MASK - -* Purpose: -* Mask a region of a data grid. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c int astMask( AstRegion *this, AstMapping *map, int inside, int ndim, -c const int lbnd[], const int ubnd[], in[], -c val ) -f RESULT = AST_MASK( THIS, MAP, INSIDE, NDIM, LBND, UBND, IN, VAL, -f STATUS ) - -* Class Membership: -* Mapping method. - -* Description: -* This is a set of functions for masking out regions within gridded data -* (e.g. an image). The functions modifies a given data grid by -* assigning a specified value to all samples which are inside (or outside -c if "inside" is zero) -f if INSIDE is .FALSE.) -* the specified Region. -* -* You should use a masking function which matches the numerical -* type of the data you are processing by replacing in -c the generic function name astMask by an appropriate 1- or -f the generic function name AST_MASK by an appropriate 1- or -* 2-character type code. For example, if you are masking data -c with type "float", you should use the function astMaskF (see -f with type REAL, you should use the function AST_MASKR (see -* the "Data Type Codes" section below for the codes appropriate to -* other numerical types). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to a Region. -c map -f MAP = INTEGER (Given) -* Pointer to a Mapping. The forward transformation should map -* positions in the coordinate system of the supplied Region -* into pixel coordinates as defined by the -c "lbnd" and "ubnd" parameters. A NULL pointer -f LBND and UBND arguments. A value of AST__NULL -* can be supplied if the coordinate system of the supplied Region -* corresponds to pixel coordinates. This is equivalent to -* supplying a UnitMap. -* -* The number of inputs for this Mapping (as given by its Nin attribute) -* should match the number of axes in the supplied Region (as given -* by the Naxes attribute of the Region). -* The number of outputs for the Mapping (as given by its Nout attribute) -* should match the number of -c grid dimensions given by the value of "ndim" -f grid dimensions given by the value of NDIM -* below. -c inside -f INSIDE = INTEGER (Given) -* A boolean value which indicates which pixel are to be masked. If -c a non-zero value -f .TRUE. -* is supplied, then all grid pixels with centres inside the supplied -* Region are assigned the value given by -c "val", -f VAL, -* and all other pixels are left unchanged. If -c zero -f .FALSE. -* is supplied, then all grid pixels with centres not inside the supplied -* Region are assigned the value given by -c "val", -f VAL, -* and all other pixels are left unchanged. Note, the Negated -* attribute of the Region is used to determine which pixel are -* inside the Region and which are outside. So the inside of a Region -* which has not been negated is the same as the outside of the -* corresponding negated Region. -* -* For types of Region such as PointList which have zero volume, -* pixel centres will rarely fall exactly within the Region. For -* this reason, the inclusion criterion is changed for zero-volume -* Regions so that pixels are included (or excluded) if any part of -* the Region passes through the pixel. For a PointList, this means -* that pixels are included (or excluded) if they contain at least -* one of the points listed in the PointList. -c ndim -f NDIM = INTEGER (Given) -* The number of dimensions in the input grid. This should be at -* least one. -c lbnd -f LBND( NDIM ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim" elements, -f An array -* containing the coordinates of the centre of the first pixel -* in the input grid along each dimension. -c ubnd -f UBND( NDIM ) = INTEGER (Given) -c Pointer to an array of integers, with "ndim" elements, -f An array -* containing the coordinates of the centre of the last pixel in -* the input grid along each dimension. -* -c Note that "lbnd" and "ubnd" together define the shape -f Note that LBND and UBND together define the shape -* and size of the input grid, its extent along a particular -c (j'th) dimension being ubnd[j]-lbnd[j]+1 (assuming the -c index "j" to be zero-based). They also define -f (J'th) dimension being UBND(J)-LBND(J)+1. They also define -* the input grid's coordinate system, each pixel having unit -* extent along each dimension with integral coordinate values -* at its centre. -c in -f IN( * ) = (Given and Returned) -c Pointer to an array, with one element for each pixel in the -f An array, with one element for each pixel in the -* input grid, containing the data to be masked. The -* numerical type of this array should match the 1- or -* 2-character type code appended to the function name (e.g. if -c you are using astMaskF, the type of each array element -c should be "float"). -f you are using AST_MASKR, the type of each array element -f should be REAL). -* -* The storage order of data within this array should be such -* that the index of the first grid dimension varies most -* rapidly and that of the final dimension least rapidly -c (i.e. Fortran array indexing is used). -f (i.e. normal Fortran array storage order). -* -* On exit, the samples specified by -c "inside" are set to the value of "val". -f INSIDE are set to the value of VAL. -* All other samples are left unchanged. -c val -f VAL = (Given) -* This argument should have the same type as the elements of -c the "in" array. It specifies the value used to flag the -f the IN array. It specifies the value used to flag the -* masked data (see -c "inside"). -f INSIDE). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMask() -f AST_MASK = INTEGER -* The number of pixels to which a value of -c "badval" -f BADVAL -* has been assigned. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -* - An error will be reported if the overlap of the Region and -* the array cannot be determined. - -* Data Type Codes: -* To select the appropriate masking function, you should -c replace in the generic function name astMask with a -f replace in the generic function name AST_MASK with a -* 1- or 2-character data type code, so as to match the numerical -* type of the data you are processing, as follows: -c - D: double -c - F: float -c - L: long int -c - UL: unsigned long int -c - I: int -c - UI: unsigned int -c - S: short int -c - US: unsigned short int -c - B: byte (signed char) -c - UB: unsigned byte (unsigned char) -f - D: DOUBLE PRECISION -f - R: REAL -f - I: INTEGER -f - UI: INTEGER (treated as unsigned) -f - S: INTEGER*2 (short integer) -f - US: INTEGER*2 (short integer, treated as unsigned) -f - B: BYTE (treated as signed) -f - UB: BYTE (treated as unsigned) -* -c For example, astMaskD would be used to process "double" -c data, while astMaskS would be used to process "short int" -c data, etc. -f For example, AST_MASKD would be used to process DOUBLE -f PRECISION data, while AST_MASKS would be used to process -f short integer data (stored in an INTEGER*2 array), etc. -f -f For compatibility with other Starlink facilities, the codes W -f and UW are provided as synonyms for S and US respectively (but -f only in the Fortran interface to AST). - -*-- -*/ -/* Define a macro to implement the function for a specific data - type. */ -#define MAKE_MASK(X,Xtype) \ -static int Mask##X( AstRegion *this, AstMapping *map, int inside, int ndim, \ - const int lbnd[], const int ubnd[], \ - Xtype in[], Xtype val, int *status ) { \ -\ -/* Local Variables: */ \ - AstFrame *grid_frame; /* Pointer to Frame describing grid coords */ \ - AstRegion *used_region; /* Pointer to Region to be used by astResample */ \ - Xtype *c; /* Pointer to next array element */ \ - Xtype *d; /* Pointer to next array element */ \ - Xtype *out; /* Pointer to the array used for resample output */ \ - Xtype *tmp_out; /* Pointer to temporary output array */ \ - double *lbndgd; /* Pointer to array holding lower grid bounds */ \ - double *ubndgd; /* Pointer to array holding upper grid bounds */ \ - int *lbndg; /* Pointer to array holding lower grid bounds */ \ - int *ubndg; /* Pointer to array holding upper grid bounds */ \ - int idim; /* Loop counter for coordinate dimensions */ \ - int ipix; /* Loop counter for pixel index */ \ - int nax; /* Number of Region axes */ \ - int nin; /* Number of Mapping input coordinates */ \ - int nout; /* Number of Mapping output coordinates */ \ - int npix; /* Number of pixels in supplied array */ \ - int npixg; /* Number of pixels in bounding box */ \ - int result; /* Result value to return */ \ -\ -/* Initialise. */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Obtain value for the Naxes attribute of the Region. */ \ - nax = astGetNaxes( this ); \ -\ -/* If supplied, obtain values for the Nin and Nout attributes of the Mapping. */ \ - if( map ) { \ - nin = astGetNin( map ); \ - nout = astGetNout( map ); \ -\ -/* If OK, check that the number of mapping inputs matches the \ - number of axes in the Region. Report an error if necessary. */ \ - if ( astOK && ( nax != nin ) ) { \ - astError( AST__NGDIN, "astMask"#X"(%s): Bad number of mapping " \ - "inputs (%d).", status, astGetClass( this ), nin ); \ - astError( AST__NGDIN, "The %s given requires %d coordinate value%s " \ - "to specify a position.", status, \ - astGetClass( this ), nax, ( nax == 1 ) ? "" : "s" ); \ - } \ -\ -/* If OK, check that the number of mapping outputs matches the \ - number of grid dimensions. Report an error if necessary. */ \ - if ( astOK && ( ndim != nout ) ) { \ - astError( AST__NGDIN, "astMask"#X"(%s): Bad number of mapping " \ - "outputs (%d).", status, astGetClass( this ), nout ); \ - astError( AST__NGDIN, "The pixel grid requires %d coordinate value%s " \ - "to specify a position.", status, \ - ndim, ( ndim == 1 ) ? "" : "s" ); \ - } \ -\ -/* Create a new Region by mapping the supplied Region with the supplied \ - Mapping. The resulting Region represents a region in grid coordinates. */ \ - grid_frame = astFrame( ndim, "Domain=grid", status ); \ - used_region = astMapRegion( this, map, grid_frame ); \ - grid_frame = astAnnul( grid_frame ); \ -\ -/* If no Mapping was supplied check that the number of grid dimensions \ - matches the number of axes in the Region.*/ \ - } else if ( astOK && ( ( ndim != nax ) || ( ndim < 1 ) ) ) { \ - used_region = NULL; \ - astError( AST__NGDIN, "astMask"#X"(%s): Bad number of input grid " \ - "dimensions (%d).", status, astGetClass( this ), ndim ); \ - if ( ndim != nax ) { \ - astError( AST__NGDIN, "The %s given requires %d coordinate value%s " \ - "to specify an input position.", status, \ - astGetClass( this ), nax, ( nax == 1 ) ? "" : "s" ); \ - } \ -\ -/* If no Mapping was supplied and the parameters look OK, clone the \ - supplied Region pointer for use later on. */ \ - } else { \ - used_region = astClone( this ); \ - } \ -\ -/* Check that the lower and upper bounds of the input grid are \ - consistent. Report an error if any pair is not. */ \ - if ( astOK ) { \ - for ( idim = 0; idim < ndim; idim++ ) { \ - if ( lbnd[ idim ] > ubnd[ idim ] ) { \ - astError( AST__GBDIN, "astMask"#X"(%s): Lower bound of " \ - "input grid (%d) exceeds corresponding upper bound " \ - "(%d).", status, astGetClass( this ), \ - lbnd[ idim ], ubnd[ idim ] ); \ - astError( AST__GBDIN, "Error in input dimension %d.", status, \ - idim + 1 ); \ - break; \ - } \ - } \ - } \ -\ -/* Allocate memory, and then get the bounding box of this new Region in its \ - current Frame (grid coordinates). This bounding box assumes the region \ - has not been negated. */ \ - lbndg = astMalloc( sizeof( int )*(size_t) ndim ); \ - ubndg = astMalloc( sizeof( int )*(size_t) ndim ); \ - lbndgd = astMalloc( sizeof( double )*(size_t) ndim ); \ - ubndgd = astMalloc( sizeof( double )*(size_t) ndim ); \ - if( astOK ) { \ - astGetRegionBounds( used_region, lbndgd, ubndgd ); \ -\ -/* We convert the floating point bounds to integer pixel bounds, and at \ - the same time expand the box by 2 pixels at each edge to ensure that \ - rounding errors etc do not cause any of the Region to fall outside (or \ - on) the box. Do not let the expanded box extend outside the supplied \ - array bounds. Also note the total number of pixels in the supplied \ - array, and in the bounding box. */ \ - npix = 1; \ - npixg = 1; \ - for ( idim = 0; idim < ndim; idim++ ) { \ - if( lbndgd[ idim ] != AST__BAD && ubndgd[ idim ] != AST__BAD ) { \ - lbndg[ idim ] = astMAX( lbnd[ idim ], (int)( lbndgd[ idim ] + 0.5 ) - 2 ); \ - ubndg[ idim ] = astMIN( ubnd[ idim ], (int)( ubndgd[ idim ] + 0.5 ) + 2 ); \ - } else { \ - lbndg[ idim ] = lbnd[ idim ]; \ - ubndg[ idim ] = ubnd[ idim ]; \ - } \ - npix *= ( ubnd[ idim ] - lbnd[ idim ] + 1 ); \ - if( npixg >= 0 ) npixg *= ( ubndg[ idim ] - lbndg[ idim ] + 1 ); \ - } \ -\ -/* If the bounding box is null, fill the mask with the supplied value if \ - we assigning the value to the outside of the region (do the opposite if \ - the Region has been negated). */ \ - if( npixg <= 0 && astOK ) { \ - if( ( inside != 0 ) == ( astGetNegated( used_region ) != 0 ) ) { \ - c = in; \ - for( ipix = 0; ipix < npix; ipix++ ) *(c++) = val; \ - result = npix; \ - } \ -\ -/* If the bounding box is null, return without action. */ \ - } else if( npixg > 0 && astOK ) { \ -\ -/* All points outside this box are either all inside, or all outside, the \ - Region. So we can speed up processing by setting all the points which are \ - outside the box to the supplied data value (if required). This is \ - faster than checking each point individually using the Transform method \ - of the Region. We do this by supplying an alternative output array to \ - the resampling function below, which has been pre-filled with "val" at \ - every pixel. */ \ - if( ( inside != 0 ) == ( astGetNegated( used_region ) != 0 ) ) { \ -\ -/* Allocate memory for the alternative output array, and fill it with \ - "val". */ \ - tmp_out = astMalloc( sizeof( Xtype )*(size_t) npix ); \ - if( tmp_out ) { \ - c = tmp_out; \ - for( ipix = 0; ipix < npix; ipix++ ) *(c++) = val; \ - result = npix - npixg; \ - } \ -\ -/* Indicate that we will use this temporary array rather than the \ - supplied array. */ \ - out = tmp_out; \ -\ -/* If the outside of the grid box is outside the region of interest it \ - will be unchanged in the resturned array. Therefore we can use the \ - supplied array as the output array below. */ \ - } else { \ - tmp_out = NULL; \ - out = in; \ - } \ -\ -/* Temporarily invert the Region if required. The Region Transform methods \ - leave interior points unchanged and assign AST__BAD to exterior points. \ - This is the opposite of what we want (which is to leave exterior \ - points unchanged and assign VAL to interior points), so we negate the \ - region if the inside is to be assigned the value VAL.*/ \ - if( inside ) astNegate( used_region ); \ -\ -/* Invoke astResample to mask just the region inside the bounding box found \ - above (specified by lbndg and ubndg), since all the points outside this \ - box will already contain their required value. */ \ - result += astResample##X( used_region, ndim, lbnd, ubnd, in, NULL, AST__NEAREST, \ - NULL, NULL, 0, 0.0, 100, val, ndim, \ - lbnd, ubnd, lbndg, ubndg, out, NULL ); \ -\ -/* Revert to the original setting of the Negated attribute. */ \ - if( inside ) astNegate( used_region ); \ -\ -/* If required, copy the output data from the temporary output array to \ - the supplied array, and then free the temporary output array. */ \ - if( tmp_out ) { \ - c = tmp_out; \ - d = in; \ - for( ipix = 0; ipix < npix; ipix++ ) *(d++) = *(c++); \ - tmp_out = astFree( tmp_out ); \ - }\ - }\ - } \ -\ -/* Free resources */ \ - ubndg = astFree( ubndg ); \ - lbndg = astFree( lbndg ); \ - ubndgd = astFree( ubndgd ); \ - lbndgd = astFree( lbndgd ); \ - used_region = astAnnul( used_region ); \ -\ -/* If an error occurred, clear the returned result. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_MASK(LD,long double) -#endif -MAKE_MASK(D,double) -MAKE_MASK(L,long int) -MAKE_MASK(UL,unsigned long int) -MAKE_MASK(I,int) -MAKE_MASK(UI,unsigned int) -MAKE_MASK(S,short int) -MAKE_MASK(US,unsigned short int) -MAKE_MASK(B,signed char) -MAKE_MASK(UB,unsigned char) -MAKE_MASK(F,float) - -/* Undefine the macro. */ -#undef MAKE_MASK - - - -static int Match( AstFrame *this_frame, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, - AstMapping **map, AstFrame **result, int *status ) { -/* -* Name: -* Match - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astMatch -* method inherited from the Frame class). - -* Description: -* This function matches the current Frame of a "template" Region -* to a "target" frame and determines whether it is possible to -* convert coordinates between them. If it is, a Mapping that -* performs the transformation is returned along with a new Frame -* that describes the coordinate system that results when this -* Mapping is applied to the current Frame of the target -* Region. In addition, information is returned to allow the axes -* in this "result" Frame to be associated with the corresponding -* axes in the target and template Frames from which they are -* derived. - -* Parameters: -* template -* Pointer to the template Region, whose current Frame -* describes the coordinate system (or set of possible -* coordinate systems) into which we wish to convert our -* coordinates. -* target -* Pointer to the target Frame. This describes the coordinate -* system in which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case. -* template_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the index of the axis in the -* template Region's current Frame from which it is -* derived. If it is not derived from any template Region -* axis, a value of -1 will be returned instead. -* target_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the index of the target Frame axis -* from which it is derived. If it is not derived from any -* target Frame axis, a value of -1 will be returned instead. -* map -* Address of a location where a pointer to a new Mapping will -* be returned if the requested coordinate conversion is -* possible. If returned, the forward transformation of this -* Mapping may be used to convert coordinates between the target -* Frame and the result Frame (see below) and the inverse -* transformation will convert in the opposite direction. -* result -* Address of a location where a pointer to a new Frame will be -* returned if the requested coordinate conversion is -* possible. If returned, this Frame describes the coordinate -* system that results from applying the returned Mapping -* (above) to the "target" coordinate system. In general, this -* Frame will combine attributes from (and will therefore be -* more specific than) both the target Frame and the current -* Frame of the template Region. In particular, when the -* template allows the possibility of transformaing to any one -* of a set of alternative coordinate systems, the "result" -* Frame will indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate -* conversion is possible. Otherwise zero is returned (this will -* not in itself result in an error condition). - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to Region's current Frame */ - int match; /* Result to be returned */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Invoke the parent astMatch method on the current Frame within the - encapsulated FrameSet within the Region. */ - fr = astGetFrame( ((AstRegion *) this_frame)->frameset, AST__CURRENT ); - match = astMatch( fr, target, matchsub, template_axes, target_axes, map, result ); - fr = astAnnul( fr ); - -/* Return the result. */ - return match; -} - -static void MatchAxes( AstFrame *frm1_frame, AstFrame *frm2, int *axes, - int *status ) { -/* -* Name: -* MatchAxes - -* Purpose: -* Find any corresponding axes in two Frames. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void MatchAxes( AstFrame *frm1, AstFrame *frm2, int *axes ) -* int *status ) - -* Class Membership: -* Region member function (over-rides the protected astMatchAxes -* method inherited from the Frame class). - -* Description: -* This function looks for corresponding axes within two supplied -* Frames. An array of integers is returned that contains an element -* for each axis in the second supplied Frame. An element in this array -* will be set to zero if the associated axis within the second Frame -* has no corresponding axis within the first Frame. Otherwise, it -* will be set to the index (a non-zero positive integer) of the -* corresponding axis within the first supplied Frame. - -* Parameters: -* frm1 -* Pointer to the first Frame. -* frm2 -* Pointer to the second Frame. -* axes -* Pointer to an -* integer array in which to return the indices of the axes (within -* the second Frame) that correspond to each axis within the first -* Frame. Axis indices start at 1. A value of zero will be stored -* in the returned array for each axis in the first Frame that has -* no corresponding axis in the second Frame. -* -* The number of elements in this array must be greater than or -* equal to the number of axes in the first Frame. -* status -* Pointer to inherited status value. - -* Notes: -* - Corresponding axes are identified by the fact that a Mapping -* can be found between them using astFindFrame or astConvert. Thus, -* "corresponding axes" are not necessarily identical. For instance, -* SkyFrame axes in two Frames will match even if they describe -* different celestial coordinate systems -*/ - -/* Local Variables: */ - AstFrame *frm1; /* Pointer to Region's current Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the astMatchAxesX method on frm2, passing it the current Frame - within the encapsulated FrameSet within the Region as "frm1". */ - frm1 = astGetFrame( ((AstRegion *) frm1_frame)->frameset, AST__CURRENT ); - astMatchAxesX( frm2, frm1, axes ); - frm1 = astAnnul( frm1 ); -} - -static void MatchAxesX( AstFrame *frm2_frame, AstFrame *frm1, int *axes, - int *status ) { -/* -* Name: -* MatchAxesX - -* Purpose: -* Find any corresponding axes in two Frames. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void MatchAxesX( AstFrame *frm2, AstFrame *frm1, int *axes ) -* int *status ) - -* Class Membership: -* Region member function (over-rides the protected astMatchAxesX -* method inherited from the Frame class). - -* This function looks for corresponding axes within two supplied -* Frames. An array of integers is returned that contains an element -* for each axis in the second supplied Frame. An element in this array -* will be set to zero if the associated axis within the second Frame -* has no corresponding axis within the first Frame. Otherwise, it -* will be set to the index (a non-zero positive integer) of the -* corresponding axis within the first supplied Frame. - -* Parameters: -* frm2 -* Pointer to the second Frame. -* frm1 -* Pointer to the first Frame. -* axes -* Pointer to an integer array in which to return the indices of -* the axes (within the first Frame) that correspond to each axis -* within the second Frame. Axis indices start at 1. A value of zero -* will be stored in the returned array for each axis in the second -* Frame that has no corresponding axis in the first Frame. -* -* The number of elements in this array must be greater than or -* equal to the number of axes in the second Frame. -* status -* Pointer to inherited status value. - -* Notes: -* - Corresponding axes are identified by the fact that a Mapping -* can be found between them using astFindFrame or astConvert. Thus, -* "corresponding axes" are not necessarily identical. For instance, -* SkyFrame axes in two Frames will match even if they describe -* different celestial coordinate systems -*/ - -/* Local Variables: */ - AstFrame *frm2; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the current Frame in the FrameSet. */ - frm2 = astGetFrame( ((AstRegion *) frm2_frame)->frameset, AST__CURRENT ); - -/* Invoke the astMatchAxesX on the current Frame. */ - astMatchAxesX( frm2, frm1, axes ); - -/* Free resources */ - frm2 = astAnnul( frm2 ); -} - -static void Negate( AstRegion *this, int *status ) { -/* -*++ -* Name: -c astNegate -f AST_NEGATE - -* Purpose: -* Negate the area represented by a Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c void astNegate( AstRegion *this ) -f CALL AST_NEGATE( THIS, STATUS ) - -* Class Membership: -* Region method. - -* Description: -* This function negates the area represented by a Region. That is, -* points which were previously inside the region will then be -* outside, and points which were outside will be inside. This is -* acomplished by toggling the state of the Negated attribute for -* the supplied region. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Toggle the Negated attribute. */ - astSetNegated( this, astGetNegated( this ) ? 0 : 1 ); - -} - -static void Norm( AstFrame *this_frame, double value[], int *status ) { -/* -* Name: -* Norm - -* Purpose: -* Normalise a set of Region coordinates. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void Norm( AstAxis *this, double value[], int *status ) - -* Class Membership: -* Region member function (over-rides the astNorm method -* inherited from the Frame class). - -* Description: -* This function converts a set of coordinate values for the -* current Frame of a Region, which might potentially be -* unsuitable for display to a user (for instance, may lie outside -* the expected range of values) into a set of acceptable -* alternative values suitable for display. -* -* Typically, for Frames whose axes represent cyclic values (such -* as angles or positions on the sky), this function wraps an -* arbitrary set of coordinates, so that they lie within the first -* cycle (say zero to 2*pi or -pi/2 to +pi/2). For Frames with -* ordinary linear axes, without constraints, this function will -* typically return the original coordinate values unchanged. - -* Parameters: -* this -* Pointer to the Region. -* value -* An array of double, with one element for each Region axis. -* This should contain the initial set of coordinate values, -* which will be modified in place. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to the current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's current Frame and invoke this - Frame's astNorm method to obtain the new values. Annul the Frame - pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astNorm( fr, value ); - fr = astAnnul( fr ); -} - -static void NormBox( AstFrame *this_frame, double lbnd[], double ubnd[], - AstMapping *reg, int *status ) { -/* -* Name: -* NormBox - -* Purpose: -* Extend a box to include effect of any singularities in the Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void astNormBox( AstFrame *this, double lbnd[], double ubnd[], -* AstMapping *reg, int *status ) - -* Class Membership: -* Region member function (over-rides the astNormBox method inherited -* from the Frame class). - -* Description: -* This function modifies a supplied box to include the effect of any -* singularities in the co-ordinate system represented by the Frame. -* For a normal Cartesian coordinate system, the box will be returned -* unchanged. Other classes of Frame may do other things. For instance, -* a SkyFrame will check to see if the box contains either the north -* or south pole and extend the box appropriately. - -* Parameters: -* this -* Pointer to the Frame. -* lbnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* lower axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* ubnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* upper axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* reg -* A Mapping which should be used to test if any singular points are -* inside or outside the box. The Mapping should leave an input -* position unchanged if the point is inside the box, and should -* set all bad if the point is outside the box. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to the current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's current Frame and invoke this - Frame's astNormBox method to obtain the new values. Annul the Frame - pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astNormBox( fr, lbnd, ubnd, reg ); - fr = astAnnul( fr ); -} - -static void Offset( AstFrame *this_frame, const double point1[], - const double point2[], double offset, double point3[], int *status ) { -/* -* Name: -* Offset - -* Purpose: -* Calculate an offset along a geodesic curve. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "region.h" -* void Offset( AstFrame *this, -* const double point1[], const double point2[], -* double offset, double point3[], int *status ) - -* Class Membership: -* Region member function (over-rides the protected astOffset -* method inherited from the Frame class). - -* Description: -* This function finds the Region coordinate values of a point -* which is offset a specified distance along the geodesic curve -* between two other points. - -* Parameters: -* this -* Pointer to the Region. -* point1 -* An array of double, with one element for each Region axis. -* This should contain the coordinates of the point marking the -* start of the geodesic curve. -* point2 -* An array of double, with one element for each Region axis -* This should contain the coordinates of the point marking the -* end of the geodesic curve. -* offset -* The required offset from the first point along the geodesic -* curve. If this is positive, it will be towards the second -* point. If it is negative, it will be in the opposite -* direction. This offset need not imply a position lying -* between the two points given, as the curve will be -* extrapolated if necessary. -* point3 -* An array of double, with one element for each Region axis -* in which the coordinates of the required point will be -* returned. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -* - "Bad" coordinate values will also be returned if the two -* points supplied are coincident (or otherwise fail to uniquely -* specify a geodesic curve) but the requested offset is non-zero. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's current Frame and invoke this - Frame's astOffset method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astOffset( fr, point1, point2, offset, point3 ); - fr = astAnnul( fr ); -} - -static double Offset2( AstFrame *this_frame, const double point1[2], - double angle, double offset, double point2[2], int *status ){ -/* -* Name: -* Offset2 - -* Purpose: -* Calculate an offset along a geodesic curve in a 2D Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* double Offset2( AstFrame *this, const double point1[2], double angle, -* double offset, double point2[2], int *status ); - -* Class Membership: -* Region member function (over-rides the protected astOffset2 -* method inherited from the Frame class). - -* Description: -* This function finds the Frame coordinate values of a point which -* is offset a specified distance along the geodesic curve at a -* given angle from a specified starting point. It can only be -* used with 2-dimensional Frames. -* -* For example, in a basic Frame, this offset will be along the -* straight line joining two points. For a more specialised Frame -* describing a sky coordinate system, however, it would be along -* the great circle passing through two sky positions. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This should contain the coordinates of the -* point marking the start of the geodesic curve. -* angle -* The angle (in radians) from the positive direction of the second -* axis, to the direction of the required position, as seen from -* the starting position. Positive rotation is in the sense of -* rotation from the positive direction of axis 2 to the positive -* direction of axis 1. -* offset -* The required offset from the first point along the geodesic -* curve. If this is positive, it will be in the direction of the -* given angle. If it is negative, it will be in the opposite -* direction. -* point2 -* An array of double, with one element for each Frame axis -* in which the coordinates of the required point will be returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The direction of the geodesic curve at the end point. That is, the -* angle (in radians) between the positive direction of the second -* axis and the continuation of the geodesic curve at the requested -* end point. Positive rotation is in the sense of rotation from -* the positive direction of axis 2 to the positive direction of axis 1. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - An error will be reported if the Frame is not 2-dimensional. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - double result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke the - astOffset2 method for this Frame. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astOffset2( fr, point1, angle, offset, point2 ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static int Overlap( AstRegion *this, AstRegion *that, int *status ){ -/* -*++ -* Name: -c astOverlap -f AST_OVERLAP - -* Purpose: -* Test if two regions overlap each other. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c int astOverlap( AstRegion *this, AstRegion *that ) -f RESULT = AST_OVERLAP( THIS, THAT, STATUS ) - -* Class Membership: -* Region method. - -* Description: -* This function returns an integer value indicating if the two -* supplied Regions overlap. The two Regions are converted to a commnon -* coordinate system before performing the check. If this conversion is -* not possible (for instance because the two Regions represent areas in -* different domains), then the check cannot be performed and a zero value -* is returned to indicate this. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the first Region. -c that -f THAT = INTEGER (Given) -* Pointer to the second Region. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astOverlap() -f AST_OVERLAP = INTEGER -* A value indicating if there is any overlap between the two Regions. -* Possible values are: -* -* 0 - The check could not be performed because the second Region -* could not be mapped into the coordinate system of the first -* Region. -* -* 1 - There is no overlap between the two Regions. -* -* 2 - The first Region is completely inside the second Region. -* -* 3 - The second Region is completely inside the first Region. -* -* 4 - There is partial overlap between the two Regions. -* -* 5 - The Regions are identical to within their uncertainties. -* -* 6 - The second Region is the exact negation of the first Region -* to within their uncertainties. - -* Notes: -* - The returned values 5 and 6 do not check the value of the Closed -* attribute in the two Regions. -* - A value of zero will be returned if this function is invoked with the -* AST error status set, or if it should fail for any reason. -*-- - -* Implementation Notes: -* This function is simply a wrap-up for the protected astOverlapX -* method which performs the required processing but swaps the order -* of the two arguments. This is a trick to allow the astOverlap method -* to be over-ridden by derived classes on the basis of the class of either -* of the two arguments. -*/ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Invoke the "astOverlapX" method with the two arguments swapped. */ - return astOverlapX( that, this ); -} - -static int OverlapX( AstRegion *that, AstRegion *this, int *status ){ -/* -*+ -* Name: -* astOverlapX - -* Purpose: -* Test if two regions overlap each other. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "region.h" -* int astOverlapX( AstRegion *that, AstRegion *this ) - -* Class Membership: -* Region method. - -* Description: -* This function performs the processing for the public astOverlap -* method and has exactly the same interface except that the order -* of the two arguments is swapped. This is a trick to allow -* the astOverlap method to be over-ridden by derived classes on -* the basis of the class of either of its two arguments. -* -* See the astOverlap method for details of the interface. -*- -*/ - -/* Local Variables: */ - AstFrame *bfrm_reg1; /* Pointer to base Frame in "reg1" Frame */ - AstFrame *frm_reg1; /* Pointer to current Frame in "reg1" Frame */ - AstFrameSet *fs0; /* FrameSet connecting Region Frames */ - AstFrameSet *fs; /* FrameSet connecting Region Frames */ - AstMapping *cmap; /* Mapping connecting Region Frames */ - AstMapping *map; /* Mapping form "reg2" current to "reg1" base */ - AstMapping *map_reg1; /* Pointer to current->base Mapping in "reg1" */ - AstPointSet *ps1; /* Mesh covering second Region */ - AstPointSet *ps3; /* Mesh covering first Region */ - AstPointSet *ps4; /* Mesh covering first Region */ - AstPointSet *ps2; /* Mesh covering second Region */ - AstPointSet *reg2_mesh; /* Mesh covering second Region */ - AstPointSet *reg1_mesh; /* Mesh covering first Region */ - AstPointSet *reg2_submesh; /* Second Region mesh minus boundary points */ - AstRegion *reg1; /* Region to use as the first Region */ - AstRegion *reg2; /* Region to use as the second Region */ - AstRegion *unc1; /* "unc" mapped into Frame of first Region */ - AstRegion *unc; /* Uncertainty in second Region */ - double **ptr1; /* Pointer to mesh axis values */ - double **ptr; /* Pointer to pointset data */ - double *p; /* Pointer to next axis value */ - int *mask; /* Mask identifying common boundary points */ - int allbad; /* Were all axis values bad? */ - int allgood; /* Were all axis values good? */ - int bnd1; /* Does reg1 have a finite boundary */ - int bnd2; /* Does reg2 have a finite boundary */ - int bnd_that; /* Does "that" have a finite boundary */ - int bnd_this; /* Does "this" have a finite boundary */ - int case1; /* First region inside second region? */ - int first; /* First pass? */ - int good; /* Any good axis values found? */ - int i; /* Mesh axis index */ - int iax; /* Axis index */ - int inv0; /* Original FrameSet Invert flag */ - int ip; /* Index of point */ - int j; /* Mesh point index */ - int nc; /* Number of axis values per point */ - int np; /* Number of points in mesh */ - int result; /* Value to return */ - int reg1_neg; /* Was "reg1" negated to make it bounded? */ - int reg2_neg; /* Was "reg2" negated to make it bounded? */ - int that_neg; /* Was "that" negated to make it bounded? */ - int this_neg; /* Was "this" negated to make it bounded? */ - int touch; /* Do the Regions touch? */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Return 5 if the two Regions are equal using the astEqual method. */ - if( astEqual( this, that ) ) { - return 5; - -/* Return 6 if the two Regions are equal using the Equal method after - temporarily negating the first. */ - } else { - astNegate( this ); - result = astEqual( this, that ); - astNegate( this ); - if( result ) return 6; - } - -/* Get a FrameSet which connects the Frame represented by the second Region - to the Frame represented by the first Region. Check that the conection is - defined. */ - fs0 = astConvert( that, this, "" ); - if( !fs0 ) return 0; - inv0 = astGetInvert( fs0 ); - -/* The rest of this function tests for overlap by representing one of the - Regions as a mesh of points along its boundary, and then checking to see - if any of the points in this mesh fall inside or outside the other Region. - This can only be done if the Region has a boundary of finite length (e.g. - Circles, Boxes, etc). Other Regions (e.g. some Intervals) do not have - finite boundaries and consequently report an error if an attempt is made - to represent them using a boundary mesh. We now therefore check to see if - either of the two Regions has a finite boundary length. This will be the - case if the region is bounded, or if it can be made bounded simply by - negating it. If a Region is unbounded regardless of the setting of its - Negated flag, then it does not have a finite boundary. We leave the - Negated attributes (temporaily) set to the values that cause the - Regions to be bounded. Set flags to indicate if the Regions have been - negated. */ - bnd_this = astGetBounded( this ); - if( !bnd_this ) { - astNegate( this ); - bnd_this = astGetBounded( this ); - if( ! bnd_this ) { - astNegate( this ); - this_neg = 0; - } else { - this_neg = 1; - } - } else { - this_neg = 0; - } - - bnd_that = astGetBounded( that ); - if( !bnd_that ) { - astNegate( that ); - bnd_that = astGetBounded( that ); - if( ! bnd_that ) { - astNegate( that ); - that_neg = 0; - } else { - that_neg = 1; - } - } else { - that_neg = 0; - } - -/* If neither Regions has a finite boundary, then we cannot currently - determine any overlap, so report an error. Given more time, it - is probably possible to think of some way of determining overlap - between two unbounded Regions, but it will probably not be a common - requirement and so is currently put off to a rainy day. */ - if( !bnd_this && !bnd_that && astOK ) { - astError( AST__INTER, "astOverlap(Region): Neither of the two " - "supplied Regions (classes %s and %s) has a finite " - "boundary.", status, astGetClass(this), astGetClass(that) ); - astError( AST__INTER, "The current implementation of astOverlap " - "cannot determine the overlap between two Regions " - "unless at least one of them has a finite boundary." , status); - } - -/* If only one of the two Regions has a finite boundary, we must use its - mesh first. Choose the finite boundary Region as the "second" region. - Also store a flag indicating if the first Region has a finite boundary. */ - if( bnd_that ) { - reg1 = this; - reg2 = that; - bnd1 = bnd_this; - bnd2 = bnd_that; - reg1_neg = this_neg; - reg2_neg = that_neg; - } else { - reg1 = that; - reg2 = this; - bnd1 = bnd_that; - bnd2 = bnd_this; - reg1_neg = that_neg; - reg2_neg = this_neg; - } - -/* We may need to try again with the above selections swapped. We only do - this once though. Set a flag to indicate that we are about to start the - first pass. */ - first = 1; -L1: - -/* Get a FrameSet which connects the Frame represented by the second Region - to the Frame represented by the first Region. Check that the conection is - defined. */ - fs = astClone( fs0 ); - astSetInvert( fs, (reg2 == that ) ? inv0 : 1 - inv0 ); - if( fs ) { - -/* Get a pointer to the Frame represented by the first Region. */ - frm_reg1 = astGetFrame( reg1->frameset, AST__CURRENT ); - -/* Get a pointer to the Mapping from current to base Frame in the first - Region. */ - map_reg1 = astGetMapping( reg1->frameset, AST__CURRENT, AST__BASE ); - -/* Get the Mapping from the current Frame of the second Region to the - current Frame of the first Region. */ - cmap = astGetMapping( fs, AST__BASE, AST__CURRENT ); - -/* Combine these Mappings to get the Mapping from current Frame of the - second region to the base Frame of the first Region. */ - map = (AstMapping *) astCmpMap( cmap, map_reg1, 1, "", status ); - -/* Get a mesh of points covering the second Region. These points are - within the current Frame of the second Region. */ - reg2_mesh = astRegMesh( reg2 ); - -/* Transform this mesh into the base Frame of the first Region. */ - ps1 = astTransform( map, reg2_mesh, 1, NULL ); - -/* Check there are some good points in the transformed pointset. */ - good = 0; - np = astGetNpoint( ps1 ); - nc = astGetNcoord( ps1 ); - ptr1 = astGetPoints( ps1 ); - if( ptr1 ) { - for( i = 0; i < nc && !good; i++ ) { - for( j = 0; j < np; j++ ) { - if( ptr1[ i ][ j ] != AST__BAD ) { - good = 1; - break; - } - } - } - } - -/* If the transformed mesh contains no good points, swap the regions and - try again. */ - if( !good ) { - fs = astAnnul( fs ); - frm_reg1 = astAnnul( frm_reg1 ); - map_reg1 = astAnnul( map_reg1 ); - cmap = astAnnul( cmap ); - map = astAnnul( map ); - reg2_mesh = astAnnul( reg2_mesh ); - ps1 = astAnnul( ps1 ); - - if( first ) { - first = 0; - - if( !bnd_that ) { - reg1 = this; - reg2 = that; - bnd1 = bnd_this; - bnd2 = bnd_that; - reg1_neg = this_neg; - reg2_neg = that_neg; - } else { - reg1 = that; - reg2 = this; - bnd1 = bnd_that; - bnd2 = bnd_this; - reg1_neg = that_neg; - reg2_neg = this_neg; - } - goto L1; - - } else { - return 0; - } - } - -/* Also transform the Region describing the positional uncertainty within - the second supplied Region into the base Frame of the first supplied - Region. */ - unc = astGetUncFrm( reg2, AST__CURRENT ); - bfrm_reg1 = astGetFrame( reg1->frameset, AST__BASE ); - unc1 = astMapRegion( unc, map, bfrm_reg1 ); - -/* See if all points within this transformed mesh fall on the boundary of - the first Region, to within the joint uncertainty of the two Regions. If - so the two Regions have equivalent boundaries. We can only do this is - the first region is bounded. */ - if( astRegPins( reg1, ps1, unc1, &mask ) && good ) { - -/* If the boundaries are equivalent, the Regions are either identical or - are mutually exclusive. To distinguish between these cases, we - looked at the Bounded attributes. If the Bounded attribute is the same - for both Regions then they are identical, otherwise they are mutually - exclusive. */ - result = ( ( !reg1_neg && bnd1 ) == ( !reg2_neg && bnd2 ) ) ? 5 : 6; - -/* If the boundaries of the two Regions are not equivalent. */ - } else { - -/* Create a new PointSet containing those points from the mesh which are - not on the boundary of the first Region. These points are identified by - the mask array created by the astRegPins method above. */ - reg2_submesh = GetSubMesh( mask, reg2_mesh, status ); - -/* Transform the points in the submesh of the second Region into the - current Frame of the first Region. */ - (void ) astAnnul( ps1 ); - ps1 = astTransform( cmap, reg2_submesh, 1, NULL ); - -/* Transform this submesh using the first Region as a Mapping. Any points - outside the first region will be set bad in the output PointSet. */ - ps2 = astTransform( (AstMapping *) reg1, ps1, 1, NULL ); - -/* Get the number of axes and points in this PointSet. */ - nc = astGetNcoord( ps2 ); - np = astGetNpoint( ps2 ); - -/* Note if there were any common points (i.e. points on the boundary of - both regions). */ - touch = ( astGetNpoint( reg2_mesh ) != np ); - -/* Get pointers to the axis data in this PointSet, and check they can be - used safely. */ - ptr = astGetPoints( ps2 ); - if( astOK ) { - -/* Loop round all points checking if the axis values are bad. We want a - flag saying if there are any good axis values and another flag saying if - there are any bad axis values. */ - allbad = 1; - allgood = 1; - for( iax = 0; iax < nc; iax++ ) { - p = ptr[ iax ]; - for( ip = 0; ip < np; ip++,p++ ) { - if( *p == AST__BAD ) { - allgood = 0; - if( !allbad ) break; - } else { - allbad = 0; - if( !allgood ) break; - } - } - } - -/* If the entire mesh of the (potentially negated) second Region was either - on the boundary of, or inside, the (potentially negated) first region, - determine the result depending on whether the regions have been - negated and whether they are bounded. Check for impossible states (or - maybe just errors in my logic). */ - if( allgood ) { - -/* Second region has a mesh so it must be bounded. */ - if( !bnd2 && astOK ) { - astError( AST__INTER, "astOverlap(%s): Inconsistent " - "state 1 (internal AST programming error).", - status, astGetClass( this ) ); - -/* If the first region has been made bounded by negating it... */ - } else if( reg1_neg ) { - if( bnd1 ) { - -/* If the second region has been made bounded by negating it, then the - unnegated first region is completely inside the unnegated second region. */ - if( reg2_neg ) { - result = 2; - -/* If the second region was bounded without negating it, then there is - no overlap between the unnegated first region and the second region. */ - } else { - result = 1; - } - -/* If the first region has been negated then it should not be unbounded. - This is ensured by the nature of the code that sets the "this_neg" and - "that_neg" flags above. */ - } else if( astOK ) { - astError( AST__INTER, "astOverlap(%s): Inconsistent " - "state 2 (internal AST programming error).", - status, astGetClass( this ) ); - } - -/* If the first region was bounded without negating it, but the second - region was made bounded by negating it, there is partial overlap. */ - } else if( reg2_neg ) { - result = 4; - -/* If the first region was bounded without negating it, but the second - region was also bounded without negating it, the second region is - completely inside the first region. */ - } else { - result = 3; - } - -/* If part of the mesh of the second Region was inside the first region, - and part was outside, then there is partial ocverlap. */ - } else if( !allbad ) { - result = 4; - -/* If no part of the mesh of the (possibly negated) second Region was inside - the (possibly negated) first region ... */ - } else { - -/* First deal with cases where the first region is unbounded. */ - if( !bnd1 ) { - if( reg1_neg && astOK ) { - astError( AST__INTER, "astOverlap(%s): Inconsistent " - "state 5 (internal AST programming error).", - status, astGetClass( this ) ); - } else if( reg2_neg ){ - result = 2; - } else { - result = 1; - } - -/* The second region has a mesh so it must be bounded. */ - } else if( !bnd2 && astOK ) { - astError( AST__INTER, "astOverlap(%s): Inconsistent " - "state 6 (internal AST programming error).", - status, astGetClass( this ) ); - -/* So now we know both (possibly negated) regions are bounded. */ - } else { - -/* We know that none of the reg2 mesh points are inside the bounded reg1. - But this still leaves two cases: 1) reg1 could be contained completely - within reg2, or 2) there is no overlap between reg2 and reg1. To - distinguish between these two cases we use reg2 to transform a point - on the boundary of reg1. First get a mesh on the boundary of reg1. */ - reg1_mesh = astRegMesh( reg1 ); - -/* Transform this mesh into the coordinate system of the second Region. */ - ps3 = astTransform( cmap, reg1_mesh, 0, NULL ); - -/* Transform the points in this mesh using the second Region as a Mapping. - Any points outside the second region will be set bad in the output - PointSet. */ - ps4 = astTransform( (AstMapping *) reg2, ps3, 1, NULL ); - -/* Get pointers to the axis data in this PointSet,and check they can be - used safely. */ - ptr = astGetPoints( ps4 ); - if( astOK ) { - -/* Test the firts point and set a flag indicating if we are in case 1 (if - not, we must be in case 2). */ - case1 = ( ptr[ 0 ][ 0 ] != AST__BAD ); - -/* Apply logic similar to the other cases to determine the result. */ - if( reg1_neg ) { - if( case1 == ( reg2_neg != 0 ) ) { - result = 3; - } else { - result = 4; - } - } else { - if( case1 == ( reg2_neg != 0 ) ) { - result = 1; - } else { - result = 2; - } - } - } - -/* Free resources. */ - reg1_mesh = astAnnul( reg1_mesh ); - ps3 = astAnnul( ps3 ); - ps4 = astAnnul( ps4 ); - } - } - } - -/* If there was no intersection or overlap, but the regions touch, then we - consider there to be an intersection if either region is closed. */ - if( touch && result == 1 ) { - if( astGetClosed( this) || astGetClosed( that ) ) result = 4; - } - -/* Free resources.*/ - reg2_submesh = astAnnul( reg2_submesh ); - ps2 = astAnnul( ps2 ); - } - -/* Free resources.*/ - fs = astAnnul( fs ); - bfrm_reg1 = astAnnul( bfrm_reg1 ); - frm_reg1 = astAnnul( frm_reg1 ); - map_reg1 = astAnnul( map_reg1 ); - cmap = astAnnul( cmap ); - map = astAnnul( map ); - ps1 = astAnnul( ps1 ); - reg2_mesh = astAnnul( reg2_mesh ); - unc = astAnnul( unc ); - unc1 = astAnnul( unc1 ); - if( mask) mask = astFree( mask ); - } - fs0 = astAnnul( fs0 ); - -/* The returned value should take account of whether "this" or "that" is - the first Region. If "this" was used as the first Region, then the - result value calculated above is already correct. If "that" was used as - the first Region, then we need to change the result to swap "this" and - "that". */ - if( reg1 == that ) { - if( result == 2 ) { - result = 3; - } else if( result == 3 ) { - result = 2; - } - } - -/* Re-instate the original Negated flags. */ - if( this_neg ) astNegate( this ); - if( that_neg ) astNegate( that ); - -/* If not OK, return zero. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static void Overlay( AstFrame *template_frame, const int *template_axes, - AstFrame *result, int *status ) { -/* -* Name: -* Overlay - -* Purpose: -* Overlay the attributes of a template Region on to another Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void Overlay( AstFrame *template, const int *template_axes, -* AstFrame *result, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astOverlay -* method inherited from the Frame class). - -* Description: -* This function overlays attributes from the current Frame of a -* Region on to another Frame, so as to over-ride selected -* attributes of that second Frame. Normally only those attributes -* which have been specifically set in the template will be -* transferred. This implements a form of defaulting, in which a -* Frame acquires attributes from the template, but retains its -* original attributes (as the default) if new values have not -* previously been explicitly set in the template. - -* Parameters: -* template -* Pointer to the template Region, for whose current Frame -* values should have been explicitly set for any attribute -* which is to be transferred. -* template_axes -* Pointer to an array of int, with one element for each axis of -* the "result" Frame (see below). For each axis in the result -* frame, the corresponding element of this array should contain -* the (zero-based) index of the axis in the current Frame of -* the template Region to which it corresponds. This array is -* used to establish from which template Frame axis any -* axis-dependent attributes should be obtained. -* -* If any axis in the result Frame is not associated with a -* template Frame axis, the corresponding element of this array -* should be set to -1. -* -* If a NULL pointer is supplied, the template and result axis -* indices are assumed to be identical. -* result -* Pointer to the Frame which is to receive the new attribute values. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the current Frame in the Region and invoke its - astOverlay method to overlay its attributes. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( ((AstRegion *) template_frame)->frameset, AST__CURRENT ); - astOverlay( fr, template_axes, result ); - fr = astAnnul( fr ); -} - -static void PermAxes( AstFrame *this_frame, const int perm[], int *status ) { -/* -* Name: -* PermAxes - -* Purpose: -* Permute the order of a Region's axes. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void PermAxes( AstFrame *this, const int perm[], int *status ) - -* Class Membership: -* Region member function (over-rides the astPermAxes method -* inherited from the Frame class). - -* Description: -* This function permutes the order in which the axes in the -* current Frame of a Region occur. - -* Parameters: -* this -* Pointer to the Region. -* perm -* An array of int (with one element for each axis of the -* Region's current Frame) which lists the axes in their new -* order. Each element of this array should be a (zero-based) -* axis index identifying the axes according to their old -* (un-permuted) order. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Only genuine permutations of the axis order are permitted, so -* each axis must be referenced exactly once in the "perm" array. -* - If more than one axis permutation is applied to the same Frame -* in a Region, the effects are cumulative. -*/ - -/* Local Variables: */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Invoke the astPermAxes method on the encapsulated FrameSet. */ - astPermAxes( this->frameset, perm ); - -} - -static AstFrame *PickAxes( AstFrame *this_frame, int naxes, const int axes[], - AstMapping **map, int *status ) { -/* -* Name: -* PickAxes - -* Purpose: -* Create a new Frame by picking axes from a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstFrame *PickAxes( AstFrame *this, int naxes, const int axes[], -* AstMapping **map, int *status ) - -* Class Membership: -* Region member function (over-rides the astPickAxes protected -* method inherited from the Frame class). - -* Description: -* This function creates a new Frame whose axes are copies of axes -* picked from the encapsulated Frame of an existing Region. Other -* Frame attributes are also copied from this existing Frame to the -* new Frame. Zero or more of the original axes may be picked in -* any order, but each can be used only once. Additional axes (with -* default characteristics) may be included in the new Frame if -* required. -* -* Optionally, a Mapping that converts between the original Frame's -* axes and those of the new Frame may also be returned. - -* Parameters: -* this -* Pointer to the Region. -* naxes -* The number of axes required in the new Frame. -* axes -* Pointer to an array of int with naxes elements. This should -* contain (zero based) axis indices specifying the axes which -* are to be included in the new Frame, in the order -* required. Each axis index may occur only once. -* -* If additional (default) axes are also to be included, the -* corresponding elements of this array should be set to -1. -* map -* Address of a location to receive a pointer to a new -* Mapping. This will be a PermMap (or a UnitMap as a special -* case) that describes the axis permutation that has taken -* place between the current Frame of the Region and the new -* Frame. The forward transformation will convert from the -* original Region's axes to the new one's, and vice versa. -* -* If this Mapping is not required, a NULL value may be supplied -* for this parameter. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new Frame. - -* Notes: -* - The class of object returned may differ from that of the -* original current Frame, depending on which axes are -* selected. For example, if a single axis is picked from a -* SkyFrame (which always has two axes), the resulting Frame cannot -* be a valid SkyFrame, so will revert to the parent class (Frame) -* instead. -* - The new Frame contains a deep copy of all the data selected -* from the original current Frame. Modifying the new Frame will -* therefore not affect the Region or the Frames it contains. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *cfrm; /* Current Frame from input Region */ - AstFrame *frame; /* Pointer to Frame to be returned */ - AstMapping *cbmap; /* Base->current Mapping from input Region */ - AstMapping *fsmap; /* Mapping from selected current to base axes */ - AstRegion *breg; /* Region spanning selected base Frame axes */ - AstRegion *creg; /* Region spanning selected current Frame axes */ - AstRegion *this; /* Pointer to Region structure */ - int *base_axes; /* Holds selected base frame axis indices */ - int def; /* Were any default axes requested? */ - int i; /* Axis index */ - int nbase; /* No. of selected base Frame axes */ - -/* Initialise the returned pointers. */ - if ( map ) *map = NULL; - frame = NULL; - -/* Check the global error status. */ - if ( !astOK ) return frame; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Check that a valid set of axes is being selected . */ - astValidateAxisSelection( this, naxes, axes, "astPickAxes" ); - -/* Pick the required axes from the current Frame of the encapsulated - FrameSet. */ - cfrm = astGetFrame( this->frameset, AST__CURRENT ); - frame = astPickAxes( cfrm, naxes, axes, map ); - -/* See if any default axes are to be included in the returned Frame. */ - def = 0; - for( i = 0; i < naxes; i++ ) { - if( axes[ i ] < 0 ) def = 1; - } - -/* Regions cannot yet include extra default axes in the returned Frame - so return a basic Frame if any default axes were requested. */ - if( ! def ) { - -/* We now see if the requested set of current Frame axes correspond to a - unique set of base Frame axes. If they do, we may be able to return a - Region spanning the selected axes rather than just a Frame. The check - is performed by attempting to split the current->base Mapping. */ - cbmap = astGetMapping( this->frameset, AST__CURRENT, AST__BASE ); - base_axes = astMapSplit( cbmap, naxes, axes, &fsmap ); - -/* Check the Mapping could be split. */ - if( base_axes ) { - -/* Store the number of base Frame axes that correspond to the requested - set of current Frame axes. */ - nbase = astGetNout( fsmap ); - -/* Attempt to create a new Region that spans the corresponding set of - base Frame axes. */ - breg = astRegBasePick( this, nbase, base_axes ); - if( breg ) { - -/* Use the split Mapping to map the base Frame region into the requested - Frame. We invert the "fsmap" first so that it maps the selected base - Frame axes into the selected current Frame axes. */ - astInvert( fsmap ); - creg = astMapRegion( breg, fsmap, frame ); - -/* Copy properties from the old Region to the new Region. */ - astRegOverlay( creg, this, 0 ); - -/* Return this new Region in place of the simple Frame found above. */ - (void) astAnnul( frame ); - frame = (AstFrame *) creg; - -/* Free resources */ - breg = astAnnul( breg ); - } - fsmap = astAnnul( fsmap ); - base_axes = astFree( base_axes ); - } - cbmap = astAnnul( cbmap ); - } - cfrm = astAnnul( cfrm ); - -/* If an error occurred, annul the Mapping pointer (if requested) and - the new Frame pointer. */ - if ( !astOK ) { - if ( map ) *map = astAnnul( *map ); - frame = astAnnul( frame ); - } - -/* Return the pointer to the new Frame. */ - return frame; -} - -static void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ){ -/* -*+ -* Name: -* astRegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astRegBaseBox( AstRegion *this, double *lbnd, double *ubnd ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. - -*- -*/ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* This abstract implementation simply reports an error. All sub-classes of - Region should over-ride this to return appropriate values. */ - astError( AST__INTER, "astRegBaseBox(%s): The %s class does not implement " - "the astRegBaseBox method inherited from the Region class " - "(internal AST programming error).", status, astGetClass( this ), - astGetClass( this ) ); -} - -static void RegBaseBox2( AstRegion *this, double *lbnd, double *ubnd, int *status ){ -/* -*+ -* Name: -* astRegBaseBox2 - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astRegBaseBox2( AstRegion *this, double *lbnd, double *ubnd ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function is similar to astRegBaseBox in that it returns the -* upper and lower axis bounds of a Region in the base Frame of the -* encapsulated FrameSet. But, in addition to assuming that the -* supplied Region has not been negated, it also assumes that any -* component Regions contained within the supplied Region have not been -* negated. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. - -*- -*/ - -/* This base class implementation simply calls astRegBaseBox. Sub-classes - which contain component Regions should override it. */ - astRegBaseBox( this, lbnd, ubnd ); - -} - -static AstPointSet *RegBaseGrid( AstRegion *this, int *status ){ -/* -*+ -* Name: -* astRegBaseGrid - -* Purpose: -* Return a PointSet containing points spread through the volume of a -* Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstPointSet *astRegBaseGrid( AstRegion *this ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a PointSet containing a set of points spread -* through the volume of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* Pointer to the PointSet. If the Region is unbounded, a NULL pointer -* will be returned. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstBox *box; - AstFrame *frmb; - AstPointSet *ps1; - AstPointSet *ps2; - AstPointSet *result; - double **ptr2; - double **ptr; - double *lbnd; - double *ubnd; - int good; - int ic; - int ip; - int ipr; - int meshsize; - int naxb; - int np; - int npnt2; - int ntry; - -/* Initialise */ - result= NULL; - -/* Check the local error status. */ - if ( !astOK ) return NULL; - -/* If the Region structure contains a pointer to a PointSet holding - positions spread over the volume of the Region in the base Frame, - return it. */ - if( this->basegrid ) { - result = astClone( this->basegrid ); - -/* Otherwise, check the Region is bounded. */ - } else if( astGetBounded( this ) ) { - -/* Get the original MeshSize attribute. */ - meshsize = astGetMeshSize( this ); - -/* Get the base Frame bounding box. */ - naxb = astGetNin( this->frameset ); - lbnd = astMalloc( sizeof( double )*(size_t)naxb ); - ubnd = astMalloc( sizeof( double )*(size_t)naxb ); - astRegBaseBox( this, lbnd, ubnd ); - -/* Create a Box covering this bounding box. */ - frmb = astGetFrame( this->frameset, AST__BASE ); - box = astBox( frmb, 1, lbnd, ubnd, NULL, "", status ); - -/* Loop until we have a grid of nearly the right size. Make at most three - attempts. */ - ipr = 0; - np = meshsize; - ntry = 0; - while( ntry++ < 3 ) { - -/* Copy the MeshSize attribute to the new Box since this will be used by - the invocation of astRegBaseGrid below. */ - astSetMeshSize( box, np ); - -/* Invoke the Box astRegGrid method. Note, the Box class overrides this - implementation of astRegBaseGrid and does not (must not) invoke this - implementation, in order to avoid an infinite loop. */ - ps1 = astRegBaseGrid( box ); - -/* Some of the base Frame points in the above bounding box will fall outside - the supplied Region. Use the Region as a Mapping to determine which they - are. Since the points are base Frame points, use astBTransform rather - than astTransform. */ - ps2 = astBTransform( this, ps1, 1, NULL ); - -/* We now create a PointSet which is a copy of "ps2" but with all the bad - points (i.e. the points in the bounding box grid which are not inside - the supplied Region) removed. Create a result PointSet which is the same - size as "ps2", then copy just the good points from "ps2" to the result - PointSet, keeping a record of the number of points copied. */ - ptr2 = astGetPoints( ps2 ); - npnt2 = astGetNpoint( ps2 ); - result = astPointSet( npnt2, naxb, "", status ); - ptr = astGetPoints( result ); - if( astOK ) { - -/* Initialise the index of the next point to be stored in "result". */ - ipr = 0; - -/* Loop round all points in "ps2" */ - for( ip = 0; ip < npnt2; ip++ ) { - -/* Copy each axis value for this point from "ps2" to "result". If a bad - axis value is encountered, flag that the point is bad and break out of - the axis loop. */ - good = 1; - for( ic = 0; ic < naxb; ic++ ) { - if( ptr2[ ic ][ ip ] == AST__BAD ) { - good = 0; - break; - } else { - ptr[ ic ][ ipr ] = ptr2[ ic ][ ip ]; - } - } - -/* If the current point has no bad axis values, increment the index of - the next point to be stored in "result". */ - if( good ) ipr++; - } - } - -/* Free resources */ - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - -/* Leave the loop if an error has occurred. */ - if( !astOK ) break; - -/* If the number of points in the grid is within 5% of the target value, - it is good enough, so break. */ - if( fabs( (double)( ipr - meshsize ) )/meshsize < 0.05 ) break; - -/* Otherwise, adjust the target size of the grid by the ratio by which it - is in error. Don't do this if we have reached the maximum number of - re-tries. */ - if( ntry < 3 ) { - if( ipr == 0 ) { - np *= 10; - } else { - np *= (double)meshsize/(double)ipr; - } - result = astAnnul( result ); - } - } - -/* Truncate the "result" PointSet to exclude any unused space at the end - of the axis values arrays. */ - if( astOK ) astSetNpoint( result, ipr ); - -/* Free resources */ - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - frmb = astAnnul( frmb ); - box = astAnnul( box ); - -/* Cache the new grid for future use. */ - if( astOK ) this->basegrid = astClone( result ); - } - -/* Annul the result if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result */ - return result; -} - -static AstRegion **RegSplit( AstRegion *this, int *nlist, int *status ){ -/* -*+ -* Name: -* astRegSplit - -* Purpose: -* Split a Region into a list of disjoint component Regions. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstRegion **astRegSplit( AstRegion *this, int *nlist ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function splits the supplied Region into a set of disjoint -* component Regions. If the Region cannot be split, then the returned -* array contains only one pointer - a clone of the supplied Region -* pointer. - -* Parameters: -* this -* Pointer to the Region. -* nlist -* Pointer to an int in which to return the number of elements in -* the returned array. - -* Returned Value: -* Pointer to dynamically alloctaed memory holding an array of Region -* pointers. The length of this array is given by the value returned -* in "*nlist". The pointers in the returned array should be annulled -* using astAnnul when no longer needed, and the memory used to hold -* the array should be freed using astFree. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*- -*/ - -/* Local Variables; */ - AstRegion **result; - -/* Initialise. */ - result = NULL; - *nlist = 0; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* The base class just returns an array containing a clone of the - supplied Region pointer. */ - result = astMalloc( sizeof( *result ) ); - if( astOK ) { - result[ 0 ] = astClone( this ); - *nlist = 1; - } - - if( !astOK ) { - result = astFree( result ); - *nlist = 0; - } - - return result; -} - -static AstPointSet *RegBaseMesh( AstRegion *this, int *status ){ -/* -*+ -* Name: -* astRegBaseMesh - -* Purpose: -* Return a PointSet containing points spread around the boundary of a -* Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstPointSet *astRegBaseMesh( AstRegion *this ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a PointSet containing a set of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* Pointer to the PointSet. The axis values in this PointSet will have -* associated accuracies derived from the uncertainties which were -* supplied when the Region was created. -* -* If the Region has no boundary (i.e. is equivalent to a NullRegion), the -* returned PointSet will contain a single point with a value of AST__BAD -* on every axis. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*- -*/ - -/* Check the local error status. */ - if ( !astOK ) return NULL; - -/* This abstract method must be over-ridden by each concrete sub-class. - Report an error if this null imlementation is called.*/ - astError( AST__INTER, "astRegBaseMesh(%s): The %s class does not implement " - "the astRegBaseMesh method inherited from the Region class " - "(internal AST programming error).", status, astGetClass( this ), - astGetClass( this ) ); - return NULL; -} - -static AstRegion *RegBasePick( AstRegion *this, int naxes, const int *axes, - int *status ){ -/* -*+ -* Name: -* astRegBasePick - -* Purpose: -* Return a Region formed by picking selected base Frame axes from the -* supplied Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstRegion *astRegBasePick( AstRegion *this, int naxes, const int *axes ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function attempts to return a Region that is spanned by selected -* axes from the base Frame of the encapsulated FrameSet of the supplied -* Region. This may or may not be possible, depending on the class of -* Region. If it is not possible a NULL pointer is returned. - -* Parameters: -* this -* Pointer to the Region. -* naxes -* The number of base Frame axes to select. -* axes -* An array holding the zero-based indices of the base Frame axes -* that are to be selected. - -* Returned Value: -* Pointer to the Region, or NULL if no region can be formed. - -* Notes: -* - This base implementation returns NULL unless all base Frame axes -* are selected (possibly in a permuted order). -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*- -*/ -/* Local Variables: */ - AstFrame *fr; /* Pointer to the Region's base Frame */ - AstRegion *result; /* The returned Region pointer */ - int found; /* Has the current axis index been found yet? */ - int i; /* Axis index */ - int j; /* Index into the "axes" array */ - int nax; /* No. of base Frame axes */ - int ok; /* Are we doing a genuine axis permutation? */ - int unit; /* Is the axis permutation a unit map? */ - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the base Frame int he encapsulated FrameSet. */ - fr = astGetFrame( this->frameset, AST__BASE ); - -/* See how many axes it has. We only proceed if we are selecting all axes - in the base Frame. */ - nax = astGetNaxes( fr ); - if( nax == naxes ) { - -/* We now check that the axes array is a genuine permutation of all axes. - This means that all axis indices must occur once, and only once, within - the "axes" array. Look for each axis index in turn. */ - unit = 1; - ok = 1; - for( i = 0; i < nax && ok; i++ ) { - -/* Check each element of the axes array to see if it holds the axis index - currently being looked for. */ - found = 0; - for( j = 0; j < nax; j++ ) { - -/* If so, if this axis index has already been found, break out of the - loop. */ - if( axes[ j ] == i ) { - if( found ) { - ok = 0; - break; - } - found = 1; - -/* Note if we do not have a unit map (i.e. each axis is permuted onto itself). */ - if( i != j ) unit = 0; - } - } - -/* If the axis index was not found, we do not have a genuine axis - permutation. */ - if( !found ) ok = 0; - } - -/* If we have a genuine axis permutation, create a Region which is a copy - of the supplied region and set it to represent its base Frame. */ - if( ok ) { - result = astCopy( this ); - astSetRegFS( result, fr ); - -/* If the axis selection is not equivalent to a unit mapping, we now - permute the axes. */ - if( !unit ) astPermAxes( result, axes ); - } - } - -/* Free resources. */ - fr = astAnnul( fr ); - -/* Returned the result. */ - return result; -} - -static double *RegCentre( AstRegion *this, double *cen, double **ptr, - int index, int ifrm, int *status ){ -/* -*+ -* Name: -* astRegCentre - -* Purpose: -* Re-centre a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* double *astRegCentre( AstRegion *this, double *cen, double **ptr, -* int index, int ifrm ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function shifts the centre of the supplied Region to a -* specified position, or returns the current centre of the Region. - -* Parameters: -* this -* Pointer to the Region. -* cen -* Pointer to an array of axis values, giving the new centre. -* Supply a NULL value for this in order to use "ptr" and "index" to -* specify the new centre. -* ptr -* Pointer to an array of pointers, one for each axis in the Region. -* Each pointer locates an array of axis values. This is the format -* returned by the PointSet method astGetPoints. Only used if "cen" -* is NULL. -* index -* The index of the point within the arrays identified by "ptr" at -* which is stored the coords for the new centre position. Only used -* if "cen" is NULL. -* ifrm -* Should be AST__BASE or AST__CURRENT. Indicates whether the centre -* position is supplied and returned in the base or current Frame of -* the FrameSet encapsulated within "this". - -* Returned Value: -* If both "cen" and "ptr" are NULL then a pointer to a newly -* allocated dynamic array is returned which contains the centre -* coords of the Region. This array should be freed using astFree when -* no longer needed. If either of "ptr" or "cen" is not NULL, then a -* NULL pointer is returned. - -* Notes: -* - Any bad (AST__BAD) centre axis values are ignored. That is, the -* centre value on such axes is left unchanged. -* - Some Region sub-classes do not have a centre. Such classes will report -* an AST__INTER error code if this method is called with either "ptr" or -* "cen" not NULL. If "ptr" and "cen" are both NULL, then no error is -* reported if this method is invoked on a Region of an unsuitable class, -* but NULL is always returned. - -*- -*/ - -/* Local Variables: */ - double *result; - -/* Initialise */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* This abstract method must be over-ridden by each concrete sub-class - which allows the centre to be shifted. Report an error if this null - imlementation is called to set a new centre. If it is called to - enquire the current centre, then return a NULL pointer. */ - if( ptr || cen ) astError( AST__INTER, "astRegCentre(%s): The %s " - "class does not implement the astRegCentre method " - "inherited from the Region class (internal AST " - "programming error).", status, astGetClass( this ), - astGetClass( this ) ); - - return NULL; -} - -static void RegClearAttrib( AstRegion *this, const char *aattrib, - char **base_attrib, int *status ) { -/* -*+ -* Name: -* astRegClearAttrib - -* Purpose: -* Clear an attribute value for a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astRegClearAttrib( AstRegion *this, const char *aattrib, -* char **base_attrib ) - -* Class Membership: -* Region virtual function - -* Description: -* This function clears the value of a named attribute in both the base -* and current Frame in the FrameSet encapsulated within a Region, without -* remapping either Frame. -* -* No error is reported if the attribute is not recognised by the base -* Frame. - -* Parameters: -* this -* Pointer to the Region. -* aattrib -* Pointer to a null terminated string holding the attribute name. -* base_attrib -* Address of a location at which to return a pointer to the null -* terminated string holding the attribute name which was cleared in -* the base Frame of the encapsulated FrameSet. This may differ from -* the supplied attribute if the supplied attribute contains an axis -* index and the current->base Mapping in the FrameSet produces an -* axis permutation. The returned pointer should be freed using -* astFree when no longer needed. A NULL pointer may be supplied in -* which case no pointer is returned. -*- -*/ - -/* Local Variables: */ - AstFrame *frm; - AstMapping *junkmap; - AstMapping *map; - AstRegion *unc; - char *attrib; - char *battrib; - char buf1[ 100 ]; - int *outs; - int axis; - int baxis; - int i; - int len; - int nc; - int rep; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Produce a lower case version of the attribute name string */ - nc = strlen( aattrib ); - attrib = astMalloc( nc + 1 ); - for( i = 0; i < nc; i++ ) attrib[ i ] = tolower( aattrib[ i ] ); - attrib[ nc ] = 0; - -/* Clear the attribute in the current Frame in the encapsulated FrameSet. - Use the protected astClearAttrib method which does not cause the Frame - to be remapped within the FrameSet. */ - frm = astGetFrame( this->frameset, AST__CURRENT ); - astClearAttrib( frm, attrib ); - frm = astAnnul( frm ); - -/* Indicate that we should use the supplied attribute name with the base Frame. */ - battrib = NULL; - -/* If the attribute name contains an axis number, we need to create a new - attribute name which refers to the corresponding base Frame axis - (since the base<->current Mapping may permute the axes). First parse the - supplied attribute name to locate any axis index. */ - len = strlen( attrib ); - if( nc = 0, ( 2 == astSscanf( attrib, "%[^(](%d) %n", buf1, &axis, - &nc ) ) && ( nc >= len ) ) { - -/* If found, convert the axis index from one-based to zero-based. */ - axis--; - -/* See if the specified current Frame axis is connected to one and only - one base Frame axis. If so, get the index of the base Frame axis. */ - map = astGetMapping( this->frameset, AST__CURRENT, AST__BASE ); - outs = astMapSplit( map, 1, &axis, &junkmap ); - if( junkmap && astGetNout( junkmap ) == 1 ) { - baxis = outs[ 0 ]; - -/* If the base Frame axis index is different to the current Frame axis - index, create a new attribute name string using the base Frame axis index. */ - if( baxis != axis ) { - battrib = astMalloc( strlen( attrib ) + 10 ); - if( battrib ) sprintf( battrib, "%s(%d)", buf1, baxis + 1 ); - } - -/* If there is no one base Frame axis which corresponds to the supplied - current Frame axis, report an error. */ - } else if( astOK ) { - astError( AST__INTER, "astRegClearAttrib(%s): Unable to clear " - "attribute \"%s\" in the base Frame of the %s", status, - astGetClass( this ), attrib, astGetClass( this ) ); - astError( AST__INTER, "There is no base Frame axis corresponding " - "to current Frame axis %d\n", status, axis + 1 ); - } - -/* Free resources */ - outs = astFree( outs ); - if( junkmap ) junkmap = astAnnul( junkmap ); - map = astAnnul( map ); - } - -/* Clear the appropriate attribute name in the base Frame. This time ensure - that any error caused by the attribute name is annulled. Also clear it in - any uncertainty Region (the current Frame of the uncertainty Region is - assumed to be equivalent to the base Frame of the parent Region). */ - frm = astGetFrame( this->frameset, AST__BASE ); - if( frm ) { - rep = astReporting( 0 ); - astClearAttrib( frm, battrib ? battrib : attrib ); - if( astTestUnc( this ) ) { - unc = astGetUncFrm( this, AST__BASE ); - astRegClearAttrib( unc, battrib ? battrib : attrib, NULL ); - unc = astAnnul( unc ); - } - if( astStatus == AST__BADAT ) astClearStatus; - astReporting( rep ); - } - frm = astAnnul( frm ); - -/* If required return the modified base Frame attribute name. Otherwise, - free it. */ - if( base_attrib ) { - if( battrib ) { - *base_attrib = battrib; - } else { - *base_attrib = astStore( NULL, attrib, strlen( attrib ) + 1 ); - } - } else { - battrib = astFree( battrib ); - } - -/* Since the base Frame has been changed, any cached information calculated - on the basis of the base Frame properties may no longer be up to date. */ - astResetCache( this ); - -/* Free resources. */ - attrib = astFree( attrib ); - -} - -static AstPointSet *RegGrid( AstRegion *this, int *status ){ -/* -*+ -* Name: -* astRegGrid - -* Purpose: -* Return a PointSet containing points spread through the volume of a -* Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstPointSet *astRegGrid( AstRegion *this ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a PointSet containing a mesh of points spread -* throughout the volume of the Region. The points refer to the current -* Frame of the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* Pointer to the PointSet. The axis values in this PointSet will have -* associated accuracies derived from the uncertainties which were -* supplied when the Region was created. Annul the pointer using -* astAnnul when it is no longer needed. - -* Notes: -* - It should not be assumed that the returned points are evenly -* spaced withint he volume. -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*- -*/ - -/* Local Variables; */ - AstMapping *map; /* Base -> current Frame Mapping */ - AstPointSet *result; /* Pointer to returned PointSet */ - -/* Initialise the returned pointer */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* If the Region structure does not contain a pointer to a PointSet holding - positions evenly spread over the volume of the Region in the base - Frame, create one now. Note, we cannot cache the grid in the current - Frame in this way since the current Frame grid depends on the proprties - of the current Frame (e.g. System) which can be changed at any time. */ - if( !this->basegrid ) this->basegrid = astRegBaseGrid( this ); - -/* Get the simplified base->current Mapping */ - map = astRegMapping( this ); - -/* If the Mapping is a UnitMap, just return a clone of the PointSet - pointer stored in the Region structure. */ - if( astIsAUnitMap( map ) ){ - result = astClone( this->basegrid ); - -/* Otherwise, create a new PointSet holding the above points transformed - into the current Frame. */ - } else { - result = astTransform( map, this->basegrid, 1, NULL ); - } - -/* Free resources.*/ - map = astAnnul( map ); - -/* If an error has occurred, annul the returned PointSet. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *RegMesh( AstRegion *this, int *status ){ -/* -*+ -* Name: -* astRegMesh - -* Purpose: -* Return a PointSet containing points spread over the boundary of a -* Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstPointSet *astRegMesh( AstRegion *this ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the current Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* Pointer to the PointSet. The axis values in this PointSet will have -* associated accuracies derived from the uncertainties which were -* supplied when the Region was created. Annul the pointer using -* astAnnul when it is no longer needed. - -* Notes: -* - It should not be assumed that the returned points are evenly -* spaced on the boundary. -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*- -*/ - -/* Local Variables; */ - AstMapping *map; /* Base -> current Frame Mapping */ - AstPointSet *bmesh; /* Base Frame mesh */ - AstPointSet *result; /* Pointer to returned PointSet */ - -/* Initialise the returned pointer */ - result = NULL; - -/* Check the local error status. */ - if ( !astOK ) return result; - -/* Get a pointer to a PointSet holding positions evenly spread over the - boundary of the Region in the base Frame. */ - bmesh = astRegBaseMesh( this ); - -/* Get the simplified base->current Mapping */ - map = astRegMapping( this ); - -/* If the Mapping is a UnitMap, just return a clone of the mesh PointSet - pointer. */ - if( astIsAUnitMap( map ) ){ - result = astClone( bmesh ); - -/* Otherwise, create a new PointSet holding the above points transformed - into the current Frame. */ - } else { - result = astTransform( map, bmesh, 1, NULL ); - } - -/* Free resources.*/ - bmesh = astAnnul( bmesh ); - map = astAnnul( map ); - -/* If an error has occurred, annul the returned PointSet. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int RegDummyFS( AstRegion *this, int *status ){ -/* -*+ -* Name: -* astRegDummyFS - -* Purpose: -* Check if a Region has a dummy FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* int astRegDummyFS( AstRegion *this ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a flag indicating if the supplied Region has -* a dummy FrameSet. -* -* The astDump method for a Region may choose not to include the -* Region's FrameSet in the dump, depending on the value of the -* RegionFS attribute and the nature of the FrameSet. If the FrameSet -* is omitted from the Dump, then special action has to be taken when -* the dump is subsequently read in and used to re-create the Region. -* On encounterting such a dump, the astLoadRegion function will create -* a dummy FrameSet and associate it with the reconstructed Region. -* The new Region should not be used however until this dummy FrameSet -* has been replaced by the correct FrameSet. Performing this replacement -* is the responsibility of the parent class (i.e. the class which choose -* to omit the FrameSet from the dump). These will usually be Region -* classes which encapsulate other Regions, such as CmpRegion, Prism, -* Stc, etc. -* -* This function can be used by astLoad... methods in sub-classes to -* determine if a newly loaded component Region has a dummy FrameSet. If -* so the astLoad function should either use the astSetRegFS method to -* store a new FrameSet in the component Region. If the parent Region -* itself has a dummy FrameSet (i.e. is a component Region contained -* within a higher level Region) then it cannot do this and should -* ignore the presence of the dummy FrameSet (it then becomes the -* responsibility of hte parent Region to load appropriate FrameSets -* into all its components). - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* Non-zero if the Region has a dummy FrameSet. - -*- -*/ - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* The Ident attribute of the FrameSet will be set to DUMMY_FS if the - FrameSet is a dummy. */ - return !strcmp( astGetIdent( this->frameset ), DUMMY_FS ); -} - -static int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -*+ -* Name: -* astRegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* int astRegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given Region. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied Region "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the Region. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "pset". -* Each element in the returned array is set to 1 if the -* corresponding position in "pset" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*- -*/ - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* This abstract implementation simply reports an error. All sub-classes of - Region should over-ride this to return appropriate values. */ - astError( AST__INTER, "astRegPins(%s): The %s class does not implement " - "the astRegPins method inherited from the Region class " - "(internal AST programming error).", status, astGetClass( this ), - astGetClass( this ) ); - return 0; -} - -static void GetRegionBounds( AstRegion *this, double *lbnd, double *ubnd, int *status ){ -/* -*++ -* Name: -c astGetRegionBounds -f AST_GETREGIONBOUNDS - -* Purpose: -* Returns the bounding box of Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c void astGetRegionBounds( AstRegion *this, double *lbnd, double *ubnd ) -f CALL AST_GETREGIONBOUNDS( THIS, LBND, UBND, STATUS ) - -* Class Membership: -* Region method. - -* Description: -c This function -f This routine -* returns the upper and lower limits of a box which just encompasses -* the supplied Region. The limits are returned as axis values within -* the Frame represented by the Region. The value of the Negated -* attribute is ignored (i.e. it is assumed that the Region has not -* been negated). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -c lbnd -f LBND() = DOUBLE PRECISION (Returned) -c Pointer to an -f An -* array in which to return the lower axis bounds covered by the Region. -* It should have at least as many elements as there are axes in the -* Region. If an axis has no lower limit, the returned value will -* be the largest possible negative value. -c ubnd -f UBND() = DOUBLE PRECISION (Returned) -c Pointer to an -f An -* array in which to return the upper axis bounds covered by the Region. -* It should have at least as many elements as there are axes in the -* Region. If an axis has no upper limit, the returned value will -* be the largest possible positive value. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The value of the Negated attribute is ignored (i.e. it is assumed that -* the Region has not been negated). -* - If an axis has no extent on an axis then the lower limit will be -* returned larger than the upper limit. Note, this is different to an -* axis which has a constant value (in which case both lower and upper -* limit will be returned set to the constant value). -* - If the bounds on an axis cannot be determined, AST__BAD is returned for -* both upper and lower bounds - -*-- -*/ - -/* Local Variables: */ - AstFrame *frm; /* Current Frame */ - AstMapping *smap; /* Simplified base -> current Mapping */ - AstPointSet *bmesh; /* PointSet holding base Frame mesh */ - AstPointSet *cmesh; /* PointSet holding current Frame mesh */ - double **bptr; /* Pointer to PointSet coord arrays */ - double **cptr; /* Pointer to PointSet coord arrays */ - double *blbnd; /* Lower bounds in base Frame */ - double *bubnd; /* Upper bounds in base Frame */ - double *p; /* Array of values for current axis */ - double width; /* Width of bounding box on i'th axis */ - int i; /* Axis count */ - int ip; /* Index of current corner */ - int j; /* Timer for low/high swaps */ - int jmax; /* Increment between low/high swaps */ - int lo; /* Assign low bound to next corner? */ - int nbase; /* Number of base Frame axes */ - int ncur; /* Number of current Frame axes */ - int npos; /* Number of box corners */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Get the simplified base to current Mapping. */ - smap = astRegMapping( this ); - -/* If the simplified Mapping is a UnitMap, just store the base box bounds - in the returned arrays */ - if( astIsAUnitMap( smap ) ) { - astRegBaseBox( this, lbnd, ubnd ); - -/* Otherwise, we get a mesh of points over the boundary of the Region within - the base Frame, transform them into the current Frame, and find their bounds. */ - } else { - -/* If the Region is bounded, we can get a genuine mesh of points on the - boundary of the Region. */ - if( astGetBounded( this ) ) { - bmesh = astRegBaseMesh( this ); - -/* If the Region is not bounded, no mesh can be created so we use the - corners of the base frame bounding box instead. */ - } else { - -/* Get workspace to hold the bounds of the region within the base Frame. */ - nbase = astGetNin( smap ); - blbnd = astMalloc( sizeof( double )*nbase ); - bubnd = astMalloc( sizeof( double )*nbase ); - -/* Get the base Frame bounding box. */ - astRegBaseBox( this, blbnd, bubnd ); - -/* Get the number of corners in the base Frame bounding box. */ - npos = pow( 2, nbase ); - -/* Create a PointSet to hold the positions at the corners in the base - frame box. */ - bmesh = astPointSet( npos, nbase, " ", status ); - bptr = astGetPoints( bmesh ); - if( bptr ) { - -/* Store the coordinates of the box corners in the PointSet. */ - jmax = 1; - for( i = 0; i < nbase; i++ ) { - p = bptr[ i ]; - - lo = 1; - j = 0; - for( ip = 0; ip < npos; ip++,j++ ) { - if( j == jmax ) { - lo = 1 - lo; - j = 0; - } - p[ ip ] = lo ? blbnd[ i ] : bubnd[ i ]; - } - - jmax *= 2; - } - } - -/* Release resources. */ - blbnd = astFree( blbnd ); - bubnd = astFree( bubnd ); - } - -/* Create a new PointSet holding the above points transformed into the - current Frame. */ - cmesh = astTransform( smap, bmesh, 1, NULL ); - -/* There is a possibility that these points may span a singularity in the - coordinate system such as the RA=0 line in a SkyFrame. So ensure the - axis values are normalised into the shortest possible range. */ - frm = astGetFrame( this->frameset, AST__CURRENT ); - ncur = astGetNaxes( frm ); - - cptr = astGetPoints( cmesh ); - npos = astGetNpoint( cmesh ); - for( i = 0; i < ncur; i++ ) { - astAxNorm( frm, i+1, 1, npos, cptr[i] ); - } - -/* Get the axis bounds of this PointSet. */ - astBndPoints( cmesh, lbnd, ubnd ); - -/* There is again a possibility that these bounds may span a singularity in - the coordinate system such as the RA=0 line in a SkyFrame. So for each - axis we ensure the width (i.e. "ubnd-lbnd" ) is correct. */ - for( i = 0; i < ncur; i++ ) { - width = astAxDistance( frm, i + 1, lbnd[ i ], ubnd[ i ] ); - if( width != AST__BAD ) { - ubnd[ i ] = lbnd[ i ] + width; - } else { - ubnd[ i ] = AST__BAD; - lbnd[ i ] = AST__BAD; - } - } - -/* Release resources. */ - frm = astAnnul( frm ); - bmesh = astAnnul( bmesh ); - cmesh = astAnnul( cmesh ); - } - smap = astAnnul( smap ); -} - -static void GetRegionBounds2( AstRegion *this, double *lbnd, double *ubnd, int *status ){ -/* -*+ -* Name: -* astGetRegionBounds - -* Purpose: -* Returns the bounding box of Region. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "region.h" -* void astGetRegionBounds2( AstRegion *this, double *lbnd, double *ubnd ) - -* Class Membership: -* Region method. - -* Description: -* This function is like astGetRegionBounds, in that it returns the upper -* and lower limits of a box which just encompasses the supplied Region, -* as axis values within the Frame represented by the Region. But, in -* addition to assuming that the supplied Region has not been negated, it -* also assumes that any component Regions contained within the supplied -* Region have not been negated. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region. It should have at least as many elements -* as there are axes in the Region. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region. It should have at least as many elements -* as there are axes in the Region. - -* Notes: -* - The value of the Negated attribute is ignored (i.e. it is assumed that -* the Region has not been negated). The Nagated attributes of any -* component Regions are also ignored. - -*- -*/ - -/* Local Variables: */ - AstMapping *smap; /* Simplified base -> current Mapping */ - double *lbndb; /* Pointer to lower bounds on base box */ - double *ubndb; /* Pointer to upper bounds on base box */ - int i; /* Axis count */ - int nbase; /* Number of base Frame axes */ - int ncur; /* Number of current Frame axes */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Find the number of axes in the base and current Frames of the - encapsulated FrameSet. */ - nbase = astGetNin( this->frameset ); - ncur = astGetNout( this->frameset ); - -/* Get the bounding box in the base Frame of the encapsulated FrameSet. */ - lbndb = astMalloc( sizeof( double )*(size_t) nbase ); - ubndb = astMalloc( sizeof( double )*(size_t) nbase ); - astRegBaseBox2( this, lbndb, ubndb ); - -/* Get the simplified base to current Mapping. */ - smap = astRegMapping( this ); - -/* Check pointers can be used safely. */ - if( smap ) { - -/* If the simplified Mapping is a UnitMap, just copy the base box bounds - to the returned arrays */ - if( astIsAUnitMap( smap ) ) { - for( i = 0; i < ncur; i++ ) { - lbnd[ i ] = lbndb[ i ]; - ubnd[ i ] = ubndb[ i ]; - } - -/* Otherwise, use astMapBox to find the corresponding current Frame - limits. */ - } else { - for( i = 0; i < ncur; i++ ) { - astMapBox( smap, lbndb, ubndb, 1, i, lbnd + i, ubnd + i, - NULL, NULL ); - } - } - } - -/* Release resources. */ - smap = astAnnul( smap ); - lbndb = astFree( lbndb ); - ubndb = astFree( ubndb ); -} - -static void GetRegionMesh( AstRegion *this, int surface, int maxpoint, - int maxcoord, int *npoint, double *points, - int *status ){ -/* -*++ -* Name: -c astGetRegionMesh -f AST_GETREGIONMESH - -* Purpose: -* Return a mesh of points covering the surface or volume of a Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c void astGetRegionMesh( AstRegion *this, int surface, int maxpoint, -c int maxcoord, int *npoint, double *points ) -f CALL AST_GETREGIONMESH( THIS, SURFACE, MAXPOINT, MAXCOORD, NPOINT, -f POINTS, STATUS ) - -* Class Membership: -* Region method. - -* Description: -c This function -f This routine -* returns the axis values at a mesh of points either covering the -* surface (i.e. boundary) of the supplied Region, or filling the -* interior (i.e. volume) of the Region. The number of points in -* the mesh is approximately equal to the MeshSize attribute. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -c surface -f SURFACE = LOGICAL (Given) -c If non-zero, -f If .TRUE., -* the returned points will cover the surface or the Region. -* Otherwise, they will fill the interior of the Region. -c maxpoint -f MAXPOINT = INTEGER (Given) -* If zero, the number of points in the mesh is returned in -c "*npoint", -f NPOINT, -* but no axis values are returned and all other parameters are ignored. -* If not zero, the supplied value should be the length of the -c second dimension of the "points" -f first dimension of the POINTS -* array. An error is reported if the number of points in the mesh -* exceeds this number. -c maxcoord -f MAXCOORD = INTEGER (Given) -* The length of the -c first dimension of the "points" array. -f second dimension of the POINTS array. -* An error is reported if the number of axes in the supplied Region -* exceeds this number. -c npoint -f NPOINT = INTEGER (Returned) -c A pointer to an integer in which to return the -f The -* number of points in the returned mesh. -c points -f POINTS( MAXPOINT, MAXCOORD ) = DOUBLE PRECISION (Returned) -c The address of the first element in a 2-dimensional array of -c shape "[maxcoord][maxpoint]", in which to return the coordinate -c values at the mesh positions. These are stored such that the -c value of coordinate number "coord" for point number "point" is -c found in element "points[coord][point]". -f An array in which to return the coordinates values at the mesh -f positions. These are stored such that the value of coordinate -f number COORD for point number POINT is found in element -f POINTS(POINT,COORD). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - An error is reported if the Region is unbounded. -* - If the coordinate system represented by the Region has been -* changed since it was first created, the returned axis values refer -* to the new (changed) coordinate system, rather than the original -* coordinate system. Note however that if the transformation from -* original to new coordinate system is non-linear, the shape within -* the new coordinate system may be distorted, and so may not match -* that implied by the name of the Region subclass (Circle, Box, etc). - -*-- -*/ - -/* Local Variables: */ - AstPointSet *pset; /* PointSet holding mesh/grid axis values */ - double **ptr; /* Pointer to mesh/grid axes values */ - double *p; /* Pointer to next input axis value */ - double *q; /* Pointer to next output axis value */ - int j; /* Axis index */ - int nc; /* No. of axes to copy */ - -/* Initialise */ - *npoint = 0; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Report an error if the Region is unbounded. */ - if( !astGetBounded( this ) ) { - if( astOK ) astError( AST__MBBNF, "astGetRegionMesh(%s): The supplied %s" - " is unbounded so no mesh can be created to cover " - "it.", status, astGetClass( this ), astGetClass( this ) ); - } else { - -/* Get the mesh or grid as required. If only the size of the mesh or grid - is required, get it in the base Frame as there is no need to spend the - extra time transforming it into the current Frame. */ - if( maxpoint == 0 ){ - if( surface ) { - pset = astRegBaseMesh( this ); - } else { - pset = astRegBaseGrid( this ); - } - } else { - if( surface ) { - pset = astRegMesh( this ); - } else { - pset = astRegGrid( this ); - } - } - -/* Return the number of points in the mesh or grid. */ - *npoint = astGetNpoint( pset ); - -/* Do nothing more unless a non-zero array size was supplied. */ - if( *npoint > 0 && maxpoint != 0 && astOK ) { - -/* Check the supplied array is large enough. */ - if( *npoint > maxpoint ) { - astError( AST__DIMIN, "astGetRegionMesh(%s): The supplied " - "array can hold up to %d points but the %s supplied " - "has %d points on its mesh (programming error).", - status, astGetClass( this ), maxpoint, astGetClass( this ), - *npoint ); - } - -/* Get the dimensionality of the PointSet, and get a pointer to the axis - values. */ - nc = astGetNcoord( pset ); - ptr = astGetPoints( pset ); - -/* Check pointers can be used safely. */ - if ( astOK ) { - -/* Check the supplied array has room for all the axes. */ - if( nc > maxcoord ) { - astError( AST__DIMIN, "astGetRegionMesh(%s): The supplied " - "array can hold up to %d axes but the %s supplied " - "has %d axes (programming error).", status, - astGetClass( this ), maxcoord, astGetClass( this ), nc ); - -/* If all is OK, copy the current Frame axis values into the supplied array. */ - } else { - -/* Loop round the axes to be copied. */ - for( j = 0; j < nc; j++ ) { - -/* Get points to the first element of the input and output arrays. */ - p = ptr[ j ]; - q = points + j*maxpoint; - -/* Copying the axis values. */ - (void) memcpy( q, p, sizeof( double )*( *npoint ) ); - } - } - } - } - -/* Free resources. */ - pset = astAnnul( pset ); - } -} - -static void GetRegionPoints( AstRegion *this, int maxpoint, int maxcoord, - int *npoint, double *points, int *status ){ -/* -*++ -* Name: -c astGetRegionPoints -f AST_GETREGIONPOINTS - -* Purpose: -* Returns the positions that define the given Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c void astGetRegionPoints( AstRegion *this, int maxpoint, int maxcoord, -c int *npoint, double *points ) -f CALL AST_GETREGIONPOINTS( THIS, MAXPOINT, MAXCOORD, NPOINT, POINTS, -f STATUS ) - -* Class Membership: -* Region method. - -* Description: -c This function -f This routine -* returns the axis values at the points that define the supplied -* Region. The particular meaning of these points will depend on the -* type of class supplied, as listed below under "Applicability:". - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -c maxpoint -f MAXPOINT = INTEGER (Given) -* If zero, the number of points needed to define the Region is -* returned in -c "*npoint", -f NPOINT, -* but no axis values are returned and all other parameters are ignored. -* If not zero, the supplied value should be the length of the -c second dimension of the "points" -f first dimension of the POINTS -* array. An error is reported if the number of points needed to define -* the Region exceeds this number. -c maxcoord -f MAXCOORD = INTEGER (Given) -* The length of the -c first dimension of the "points" array. -f second dimension of the POINTS array. -* An error is reported if the number of axes in the supplied Region -* exceeds this number. -c npoint -f NPOINT = INTEGER (Returned) -c A pointer to an integer in which to return the -f The -* number of points defining the Region. -c points -f POINTS( MAXPOINT, MAXCOORD ) = DOUBLE PRECISION (Returned) -c The address of the first element in a 2-dimensional array of -c shape "[maxcoord][maxpoint]", in which to return -c the coordinate values at the positions that define the Region. -c These are stored such that the value of coordinate number -c "coord" for point number "point" is found in element -c "points[coord][point]". -f An array in which to return the coordinates values at the -f positions that define the Region. These are stored such that the -f value of coordinate number COORD for point number POINT -f is found in element POINTS(POINT,COORD). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Region -* All Regions have this attribute. -* Box -* The first returned position is the Box centre, and the second is -* a Box corner. -* Circle -* The first returned position is the Circle centre, and the second is -* a point on the circumference. -* CmpRegion -* Returns a value of zero for -c "*npoint" -f NPOINT -* and leaves the supplied array contents unchanged. To find the -* points defining a CmpRegion, use this method on the component -* Regions, which can be accessed by invoking -c astDecompose -f AST_DECOMPOSE -* on the CmpRegion. -* Ellipse -* The first returned position is the Ellipse centre. The second is -* the end of one of the axes of the ellipse. The third is some -* other point on the circumference of the ellipse, distinct from -* the second point. -* Interval -* The first point corresponds to the lower bounds position, and -* the second point corresponds to the upper bounds position. These -* are reversed to indicate an extcluded interval rather than an -* included interval. See the Interval constructor for more -* information. -* NullRegion -* Returns a value of zero for -c "*npoint" -f NPOINT -* and leaves the supplied array contents unchanged. -* PointList -* The positions returned are those that were supplied when the -* PointList was constructed. -* Polygon -* The positions returned are the vertex positions that were supplied -* when the Polygon was constructed. -* Prism -* Returns a value of zero for -c "*npoint" -f NPOINT -* and leaves the supplied array contents unchanged. To find the -* points defining a Prism, use this method on the component -* Regions, which can be accessed by invoking -c astDecompose -f AST_DECOMPOSE -* on the CmpRegion. - -* Notes: -* - If the coordinate system represented by the Region has been -* changed since it was first created, the returned axis values refer -* to the new (changed) coordinate system, rather than the original -* coordinate system. Note however that if the transformation from -* original to new coordinate system is non-linear, the shape within -* the new coordinate system may be distorted, and so may not match -* that implied by the name of the Region subclass (Circle, Box, etc). - -*-- -*/ - -/* Local Variables: */ - AstPointSet *pset; /* PointSet holding PointList axis values */ - double **ptr; /* Pointer to axes values in the PointList */ - double *p; /* Pointer to next input axis value */ - double *q; /* Pointer to next output axis value */ - int j; /* Axis index */ - int nc; /* No. of axes to copy */ - -/* Initialise */ - *npoint = 0; - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Return the number of points used to define the Region, if any. */ - *npoint = this->points ? astGetNpoint( this->points ) : 0; - -/* Do nothing more unless a non-zero array size was supplied. */ - if( *npoint > 0 && maxpoint != 0 ) { - -/* Transform the base Frame axis values into the current Frame. */ - pset = astTransform( this->frameset, this->points, 1, NULL ); - -/* Get the dimensionality of this PointList, and get a pointer to the axis - values. */ - nc = astGetNcoord( pset ); - ptr = astGetPoints( pset ); - -/* Check pointers can be used safely. */ - if ( astOK ) { - -/* Check the supplied array has room for all the axis values. */ - if( nc > maxcoord ) { - astError( AST__DIMIN, "astGetRegionPoints(%s): The supplied " - "array can hold up to %d axes but the %s supplied " - "has %d axes (programming error).", status, - astGetClass( this ), maxcoord, astGetClass( this ), nc ); - - } else if( *npoint > maxpoint ) { - astError( AST__DIMIN, "astGetRegionPoints(%s): The supplied " - "array can hold up to %d points but the %s supplied " - "requires %d points to describe it (programming " - "error).", status, astGetClass( this ), maxpoint, - astGetClass( this ), *npoint ); - -/* If all is OK, copy the transformed axis values into the supplied array. */ - } else { - -/* Loop round the axes to be copied. */ - for( j = 0; j < nc; j++ ) { - -/* Get points to the first element of the input and output arrays. */ - p = ptr[ j ]; - q = points + j*maxpoint; - -/* Copying the axis values. */ - (void) memcpy( q, p, sizeof( double )*( *npoint ) ); - } - } - } - -/* Free resources. */ - pset = astAnnul( pset ); - - } -} - -static void RegOverlay( AstRegion *this, AstRegion *that, int unc, int *status ){ -/* -*+ -* Name: -* astRegOverlay - -* Purpose: -* Copy properties from one Region to another. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astRegOverlay( AstRegion *this, AstRegion *that, int unc ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function copies selected properties from "that" to "this". -* It is intended to be called by sub-classes which need to create a -* similar copy of an existing Region. For instance, subclass -* implementations of the Simplify method will usually use this -* function to ensure that the simplified Region loooks like the original -* Region. - -* Parameters: -* this -* Pointer to the new Region. -* that -* Pointer to the old Region. -* unc -* If non-zero, any uncertainty in "this" is cleared if "that" has -* no uncertainty. If zero, any uncertainty in "this" is left -* unchanged. -*- -*/ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Copy the required attribute values. */ - this->negated = that->negated; - this->closed = that->closed; - this->regionfs = that->regionfs; - this->adaptive = that->adaptive; - -/* Clear things that depend on the number of axes. */ - if( astGetNaxes( this ) == astGetNaxes( that ) ) { - if( astTestMeshSize( that ) ) astSetMeshSize( this, astGetMeshSize( that ) ); - if( astTestFillFactor( that ) ) astSetFillFactor( this, astGetFillFactor( that ) ); - } else { - astClearMeshSize( this ); - astClearFillFactor( this ); - } - -/* If required, clear uncertainty in "this" if "that" has no uncertainty. */ - if( unc && !astTestUnc( that ) ) astClearUnc( this ); - -} - -static void RegSetAttrib( AstRegion *this, const char *asetting, - char **base_setting, int *status ) { -/* -*+ -* Name: -* astRegSetAttrib - -* Purpose: -* Set an attribute value for a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astRegSetAttrib( AstRegion *this, const char *asetting, -* char **base_setting ) - -* Class Membership: -* Region virtual function - -* Description: -* This function assigns an attribute value to both the base and -* current Frame in the FrameSet encapsulated within a Region, without -* remapping either Frame. -* -* No error is reported if the attribute is not recognised by the base -* Frame. - -* Parameters: -* this -* Pointer to the Region. -* asetting -* Pointer to a null terminated attribute setting string. The supplied -* string will be interpreted using the public interpretation -* implemented by astSetAttrib. This can be different to the -* interpretation of the protected accessor functions. For instance, -* the public interpretation of an unqualified floating point value for -* the Epoch attribute is to interpet the value as a gregorian year, -* but the protected interpretation is to interpret the value as an -* MJD. -* base_setting -* Address of a location at which to return a pointer to the null -* terminated attribute setting string which was applied to the -* base Frame of the encapsulated FrameSet. This may differ from -* the supplied setting if the supplied setting contains an axis -* index and the current->base Mapping in the FrameSet produces an -* axis permutation. The returned pointer should be freed using -* astFree when no longer needed. A NULL pointer may be supplied in -* which case no pointer is returned. -*- -*/ - -/* Local Variables: */ - AstFrame *frm; - AstMapping *junkmap; - AstMapping *map; - AstRegion *unc; - char *setting; - char *bsetting; - char buf1[ 100 ]; - int *outs; - int axis; - int baxis; - int i; - int len; - int nc; - int rep; - int value; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Produce a lower case version of the setting string */ - nc = strlen( asetting ); - setting = astMalloc( nc + 1 ); - for( i = 0; i < nc; i++ ) setting[ i ] = tolower( asetting[ i ] ); - setting[ nc ] = 0; - -/* Apply the setting to the current Frame in the encapsulated FrameSet. - Use the protected astSetAttrib method which does not cause the Frame - to be remapped within the FrameSet. */ - frm = astGetFrame( this->frameset, AST__CURRENT ); - astSetAttrib( frm, setting ); - frm = astAnnul( frm ); - -/* Indicate that we should use the supplied setting with the base Frame. */ - bsetting = NULL; - -/* If the attribute name contains an axis number, we need to create a new - attribute setting which refers to the corresponding base Frame axis - (since the base<->current Mapping may permute the axes). First parse the - supplied attribute setting to locate any axis index. */ - len = strlen( setting ); - if( nc = 0, ( 2 == astSscanf( setting, "%[^(](%d)= %n%*s %n", buf1, &axis, - &value, &nc ) ) && ( nc >= len ) ) { - -/* If found, convert the axis index from one-based to zero-based. */ - axis--; - -/* See if the specified current Frame axis is connected to one and only - one base Frame axis. If so, get the index of the base Frame axis. */ - map = astGetMapping( this->frameset, AST__CURRENT, AST__BASE ); - outs = astMapSplit( map, 1, &axis, &junkmap ); - if( junkmap && astGetNout( junkmap ) == 1 ) { - baxis = outs[ 0 ]; - -/* If the base Frame axis index is different to the current Frame axis - index, create a new setting string using the base Frame axis index. */ - if( baxis != axis ) { - bsetting = astMalloc( strlen( setting ) + 10 ); - if( bsetting ) { - sprintf( bsetting, "%s(%d)=%s", buf1, baxis + 1, setting + value ); - } - } - -/* If there is no one base Frame axis which corresponds to the supplied - current Frame axis, report an error. */ - } else if( astOK ) { - astError( AST__INTER, "astRegSetAttrib(%s): Unable to apply " - "attribute setting \"%s\" to the base Frame in the %s", status, - astGetClass( this ), setting, astGetClass( this ) ); - astError( AST__INTER, "There is no base Frame axis corresponding " - "to current Frame axis %d\n", status, axis + 1 ); - } - -/* Free resources */ - outs = astFree( outs ); - if( junkmap ) junkmap = astAnnul( junkmap ); - map = astAnnul( map ); - } - -/* Apply the appropriate attribute setting to the base Frame. This time - ensure that any error caused by the attribute setting is annulled. - Also apply it to any uncertainty Region (the current Frame of the - uncertainty Region is assumed to be equivalent to the base Frame of the - parent Region). */ - frm = astGetFrame( this->frameset, AST__BASE ); - if( frm ) { - rep = astReporting( 0 ); - astSetAttrib( frm, bsetting ? bsetting : setting ); - if( astTestUnc( this ) ) { - unc = astGetUncFrm( this, AST__BASE ); - astRegSetAttrib( unc, bsetting ? bsetting : setting, NULL ); - unc = astAnnul( unc ); - } - if( astStatus == AST__BADAT ) astClearStatus; - astReporting( rep ); - } - frm = astAnnul( frm ); - -/* If required return the modified base Frame setting. Otherwise, free it. */ - if( base_setting ) { - if( bsetting ) { - *base_setting = bsetting; - } else { - *base_setting = astStore( NULL, setting, strlen( setting ) + 1 ); - } - } else { - bsetting = astFree( bsetting ); - } - -/* Since the base Frame has been changed, any cached information calculated - on the basis of the base Frame properties may no longer be up to date. */ - astResetCache( this ); - -/* Free resources. */ - setting = astFree( setting ); - -} - -static AstMapping *RemoveRegions( AstMapping *this_mapping, int *status ) { -/* -* Name: -* RemoveRegions - -* Purpose: -* Remove any Regions from a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstMapping *RemoveRegions( AstMapping *this, int *status ) - -* Class Membership: -* Region method (over-rides the astRemoveRegions method inherited -* from the Frame class). - -* Description: -* This function searches the supplied Mapping (which may be a -* compound Mapping such as a CmpMap) for any component Mappings -* that are instances of the AST Region class. It then creates a new -* Mapping from which all Regions have been removed. If a Region -* cannot simply be removed (for instance, if it is a component of a -* parallel CmpMap), then it is replaced with an equivalent UnitMap -* in the returned Mapping. -* -* The implementation provided by the Region class just returns the -* equivalent Frame. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the modified mapping. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* The Region class just returns a pointer to a deep copy of the Region's - equivalent Frame. */ - return astGetRegionFrame( (AstRegion *)this_mapping ); -} - -static void ReportPoints( AstMapping *this_mapping, int forward, - AstPointSet *in_points, AstPointSet *out_points, int *status ) { -/* -* Name: -* ReportPoints - -* Purpose: -* Report the effect of transforming a set of points using a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void ReportPoints( AstMapping *this, int forward, -* AstPointSet *in_points, AstPointSet *out_points, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astReportPoints -* method inherited from the Frame class). - -* Description: -* This function reports the coordinates of a set of points before -* and after being transformed by a Region, by writing them to -* standard output. - -* Parameters: -* this -* Pointer to the Region. -* forward -* A non-zero value indicates that the Region's forward -* coordinate transformation has been applied, while a zero -* value indicates the inverse transformation. -* in_points -* Pointer to a PointSet which is associated with the -* coordinates of a set of points before the Region was -* applied. -* out_points -* Pointer to a PointSet which is associated with the -* coordinates of the same set of points after the Region has -* been applied. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_mapping; - -/* Obtain a pointer to the Region's current Frame and invoke its - astReportPoints method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astReportPoints( (AstMapping *) fr, forward, in_points, out_points ); - fr = astAnnul( fr ); - -} - -static void ResetCache( AstRegion *this, int *status ){ -/* -*+ -* Name: -* astResetCache - -* Purpose: -* Clear cached information within the supplied Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astResetCache( AstRegion *this ) - -* Class Membership: -* Region virtual function - -* Description: -* This function clears cached information from the supplied Region -* structure. - -* Parameters: -* this -* Pointer to the Region. -*- -*/ - if( this ) { - if( this->basemesh ) this->basemesh = astAnnul( this->basemesh ); - if( this->basegrid ) this->basegrid = astAnnul( this->basegrid ); - if( this->negation ) this->negation = astAnnul( this->negation ); - } -} - - -static void Resolve( AstFrame *this_frame, const double point1[], - const double point2[], const double point3[], - double point4[], double *d1, double *d2, int *status ){ -/* -* Name: -* Resolve - -* Purpose: -* Resolve a vector into two orthogonal components - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void Resolve( AstFrame *this, const double point1[], -* const double point2[], const double point3[], -* double point4[], double *d1, double *d2, int *status ); - -* Class Membership: -* Region member function (over-rides the protected astResolve -* method inherited from the Frame class). - -* Description: -* This function resolves a vector into two perpendicular components. -* The vector from point 1 to point 2 is used as the basis vector. -* The vector from point 1 to point 3 is resolved into components -* parallel and perpendicular to this basis vector. The lengths of the -* two components are returned, together with the position of closest -* aproach of the basis vector to point 3. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vector to be resolved. -* point2 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -* point3 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the vector to be -* resolved. -* point4 -* An array of double, with one element for each Frame axis -* in which the coordinates of the point of closest approach of the -* basis vector to point 3 will be returned. -* d1 -* The address of a location at which to return the distance from -* point 1 to point 4 (that is, the length of the component parallel -* to the basis vector). Positive values are in the same sense as -* movement from point 1 to point 2. -* d2 -* The address of a location at which to return the distance from -* point 4 to point 3 (that is, the length of the component -* perpendicular to the basis vector). The value is always positive. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Each vector used in this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value, or if the required -* output values are undefined. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke this - Frame's astResolve method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astResolve( fr, point1, point2, point3, point4, d1, d2 ); - fr = astAnnul( fr ); - -} - -static AstPointSet *ResolvePoints( AstFrame *this_frame, const double point1[], - const double point2[], AstPointSet *in, - AstPointSet *out, int *status ) { -/* -* Name: -* ResolvePoints - -* Purpose: -* Resolve a set of vectors into orthogonal components - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstPointSet *ResolvePoints( AstFrame *this, const double point1[], -* const double point2[], AstPointSet *in, -* AstPointSet *out ) - -* Class Membership: -* Region member function (over-rides the astResolvePoints method -* inherited from the Frame class). - -* Description: -* This function takes a Frame and a set of vectors encapsulated -* in a PointSet, and resolves each one into two orthogonal components, -* returning these two components in another PointSet. -* -* This is exactly the same as the public astResolve method, except -* that this method allows many vectors to be processed in a single call, -* thus reducing the computational cost of overheads of many -* individual calls to astResolve. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vectors to be resolved. -* point2 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -* in -* Pointer to the PointSet holding the ends of the vectors to be -* resolved. -* out -* Pointer to a PointSet which will hold the length of the two -* resolved components. A NULL value may also be given, in which -* case a new PointSet will be created by this function. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. The first axis will -* hold the lengths of the vector components parallel to the basis vector. -* These values will be signed (positive values are in the same sense as -* movement from point 1 to point 2. The second axis will hold the lengths -* of the vector components perpendicular to the basis vector. These -* values will always be positive. - -* Notes: -* - The number of coordinate values per point in the input -* PointSet must match the number of axes in the supplied Frame. -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and 2 coordinate values per point. -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke this - Frame's astResolve method. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astResolvePoints( fr, point1, point2, in, out ); - fr = astAnnul( fr ); - -/* Return a pointer to the output PointSet. */ - return result; - -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* Region member function (extends the astSetAttrib method -* inherited from the Frame class). - -* Description: -* This function assigns an attribute value for a Region, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Region. -* setting -* Pointer to a null terminated string specifying the new -* attribute value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This protected method is intended to be invoked by the Object -* astSet method and makes additional attributes accessible to it. -*/ - -/* Local Variables: */ - AstRegion *this; /* Pointer to the Region structure */ - double dval; /* Floating point attribute value */ - int ival; /* Integer attribute value */ - int id; /* Offset of ID string */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* We first handle attributes that apply to the Region as a whole - (rather than to the encapsulated Frame). */ - -/* Negated */ -/* ------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "negated= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetNegated( this, ival ); - -/* Closed */ -/*------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "closed= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetClosed( this, ival ); - -/* FillFactor */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "fillfactor= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetFillFactor( this, dval ); - -/* MeshSize */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "meshsize= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetMeshSize( this, ival ); - -/* Adaptive */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "adaptive= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetAdaptive( this, ival ); - -/* Now do attributes inherited from parent classes. We do these here to - avoid the settings being passed on to the encapsulated FrameSet below. */ - -/* ID. */ -/* --- */ - } else if ( nc = 0, ( 0 == astSscanf( setting, "id=%n%*[^\n]%n", &id, &nc ) ) - && ( nc >= len ) ) { - astSetID( this, setting + id ); - -/* Ident. */ -/* ------ */ - } else if ( nc = 0, ( 0 == astSscanf( setting, "ident=%n%*[^\n]%n", &id, &nc ) ) - && ( nc >= len ) ) { - astSetIdent( this, setting + id ); - -/* Invert. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "invert= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetInvert( this, ival ); - -/* Report. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "report= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetReport( this, ival ); - -/* Define macros to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -#define AXISMATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "(%*d)=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* If the attribute was not recognised, use this macro to report an error - if a read-only attribute has been specified. */ - } else if ( MATCH( "class" ) || - MATCH( "nin" ) || - MATCH( "nobject" ) || - MATCH( "bounded" ) || - MATCH( "nout" ) || - MATCH( "refcount" ) || - MATCH( "tranforward" ) || - MATCH( "traninverse" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Pass unrecognised attributes on to the Region's encapsulated FrameSet for - further interpretation. Do not pass on FrameSet attributes since we - pretend to the outside world that the encapsulated FrameSet is actually a - Frame. */ - } else if ( !MATCH( "base" ) && - !MATCH( "current" ) && - !MATCH( "nframe" ) ) { - -/* If the Region is to adapt to coordinate system chanmges, use the public - astSet method so that the current Frame in the encapsulated FrameSet will - be re-mapped if the attribute changes require it. */ - if( astGetAdaptive( this ) ) { - astSet( this->frameset, setting, status ); - -/* If the Region is not to adapt to coordinate system chanmges, use the - astRegSetAttrib method which assigns the attribute setting to both - current and base Frames in the FrameSet without causing any remapping to - be performed. */ - } else { - astRegSetAttrib( this, setting, NULL ); - } - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static void SetAxis( AstFrame *this_frame, int axis, AstAxis *newaxis, int *status ) { -/* -* Name: -* SetAxis - -* Purpose: -* Set a new Axis for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void SetAxis( AstFrame *this, int axis, AstAxis *newaxis, int *status ) - -* Class Membership: -* Region member function (over-rides the astSetAxis method -* inherited from the Frame class). - -* Description: -* This function allows a new Axis object to be associated with one -* of the axes of the current Frame in a Region, replacing the -* previous one. Each Axis object contains a description of the -* quantity represented along one of the Frame's axes, so this -* function allows this description to be exchanged for another -* one. - -* Parameters: -* this -* Pointer to the Region. -* axis -* The index (zero-based) of the axis whose associated Axis -* object is to be replaced. -* newaxis -* Pointer to the new Axis object. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index supplied. */ - (void) astValidateAxis( this, axis, 1, "astSetAxis" ); - -/* Obtain a pointer to the Region's current Frame and invoke this - Frame's astSetAxis method to assign the new Axis object. Annul the - Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astSetAxis( fr, axis, newaxis ); - fr = astAnnul( fr ); -} - -static void SetRegFS( AstRegion *this, AstFrame *frm, int *status ) { -/* -*+ -* Name: -* astSetRegFS - -* Purpose: -* Stores a new FrameSet in a Region - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astSetRegFS( AstRegion *this, AstFrame *frm ) - -* Class Membership: -* Region virtual function. - -* Description: -* This function creates a new FrameSet and stores it in the supplied -* Region. The new FrameSet contains two copies of the supplied -* Frame, connected by a UnitMap. - -* Parameters: -* this -* Pointer to the Region. -* frm -* The Frame to use. -*- -*/ - -/* Local Variables: */ - AstFrame *f1; /* Copy of supplied Frame */ - AstFrame *f2; /* Copy of supplied Frame */ - AstFrameSet *fs; /* New FrameSet */ - AstRegion *unc; /* Uncertainty Region */ - AstUnitMap *um; /* UnitMap connecting base anc current Frames */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Take a copy of the supplied Frame. */ - f1 = astCopy( frm ); - -/* Create the new FrameSet. First take another copy of the supplied Frame - so that modifications using the supplied pointer will not affect the new - FrameSet. We create two copies (rather than 1) because the base and - current Frames must be independant objects - otherwise attribute changes - done to one will also appear in the other. Then construct the FrameSet - containing the two Frame copies connected by a UnitMap. */ - f2 = astCopy( f1 ); - fs = astFrameSet( f1, "", status ); - um = astUnitMap( astGetNaxes( f1 ), "", status ); - astAddFrame( fs, AST__BASE, um, f2 ); - um = astAnnul( um ); - f2 = astAnnul( f2 ); - -/* Annul any existing FrameSet */ - if( this->frameset ) (void) astAnnul( this->frameset ); - -/* Use the new FrameSet */ - this->frameset = fs; - -/* If any uncertainty Region has a zero value for its RegionFS attribute, - it will currently contain a dummy FrameSet rather than the correct - FrameSet. The correct FrameSet has copies of the base Frame of the new - Region as both its current and base Frames, and these are connected by - a UnitMap (this is equivalent to a FrameSet containing a single Frame). */ - if( astTestUnc( this ) ) { - unc = astGetUncFrm( this, AST__BASE ); - if( unc && !astGetRegionFS( unc ) ) astSetRegFS( unc, f1 ); - unc = astAnnul( unc ); - } - -/* Free remaining resourvces */ - f1 = astAnnul( f1 ); - -} - -static void SetUnc( AstRegion *this, AstRegion *unc, int *status ){ -/* -*++ -* Name: -c astSetUnc -f AST_SETUNC - -* Purpose: -* Store uncertainty information in a Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c void astSetUnc( AstRegion *this, AstRegion *unc ) -f CALL AST_SETUNC( THIS, UNC, STATUS ) - -* Class Membership: -* Region method. - -* Description: -* Each Region (of any class) can have an "uncertainty" which specifies -* the uncertainties associated with the boundary of the Region. This -* information is supplied in the form of a second Region. The uncertainty -* in any point on the boundary of a Region is found by shifting the -* associated "uncertainty" Region so that it is centred at the boundary -* point being considered. The area covered by the shifted uncertainty -* Region then represents the uncertainty in the boundary position. -* The uncertainty is assumed to be the same for all points. -* -* The uncertainty is usually specified when the Region is created, but -* this -c function -f routine -* allows it to be changed at any time. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region which is to be assigned a new uncertainty. -c unc -f UNC = INTEGER (Given) -* Pointer to the new uncertainty Region. This must be of a class for -* which all instances are centro-symetric (e.g. Box, Circle, Ellipse, -* etc.) or be a Prism containing centro-symetric component Regions. -* A deep copy of the supplied Region will be taken, so subsequent -* changes to the uncertainty Region using the supplied pointer will -* have no effect on the Region -c "this". -f THIS. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - AstFrame *frm; /* Current Frame from FrameSet */ - AstFrameSet *fs2; /* FrameSet from "unc" current Frame to "this" base Frame */ - AstFrameSet *fs; /* FrameSet in "this" supplied Region */ - AstMapping *map2; /* Base->current Mapping from FrameSet */ - AstMapping *map; /* Base->current Mapping from FrameSet */ - AstMapping *smap; /* Simplified base->current Mapping */ - double *cen0; /* Pointer to array holding original centre */ - double **ptr_reg; /* Pointer to axis values for Region's Pointset */ - int changed; /* Has the uncertainty been changed? */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Annul any existing uncertainty Region. */ - if( this->unc ) { - this->unc = astIsAObject( this->unc ) ? - astAnnul( this->unc ) : NULL; - changed = 1; - } else { - changed = 0; - } - -/* Check an uncertainty Region was supplied, and is of a usable class - (i.e. a class which can be re-centred). */ - cen0 = unc ? astRegCentre( unc, NULL, NULL, 0, 0 ) : NULL; - if( cen0 ) { - cen0 = astFree( cen0 ); - -/* Map it into the same Frame as that represented by the base Frame in - the supplied Region. */ - fs = this->frameset; - astInvert( fs ); - fs2 = Conv( unc->frameset, fs, status ); - astInvert( fs ); - - if( fs2 ) { - map = astGetMapping( fs2, AST__BASE, AST__CURRENT ); - frm = astGetFrame( fs2, AST__CURRENT ); - this->unc = astMapRegion( unc, map, frm ); - if( this->unc ) { - -/* Ensure the Region is bounded. We know that negating an unbounded - Region will make it bounded because we know that the Region consists of - Circles, Boxes and/or Ellipses, all of which have this property. */ - if( !astGetBounded( this->unc ) ) astNegate( this->unc ); - -/* If the base Frame in the uncertainty Region is the same as the base - Frame in the Region being dumped, then we do no need to include the - FrameSet in the dump of the uncertainty Region. Since the current - Frame in the uncertainty Region always corresponds to the base Frame of - its parent Region, we only need to check if the base->current Mapping - in the uncertainty Region's FrameSet is a UnitMap or not (after - simplification). If it is, set the RegionFS attribute of the uncertainty - Region to zero (i.e. false). This will cause the FrameSet to be omitted - from the Dump. */ - map2 = astGetMapping( this->unc->frameset, AST__BASE, AST__CURRENT ); - smap = astSimplify( map2 ); - if( astIsAUnitMap( smap ) ) astSetRegionFS( this->unc, 0 ); - -/* Re-centre the uncertainty Region at the first position in the PointSet - associated with the Region structure (if any). */ - if( this->points ) { - ptr_reg = astGetPoints( this->points ); - astRegCentre( this->unc, NULL, ptr_reg, 0, AST__CURRENT ); - } - -/* Set a flag indicating that the uncertainty in the Region has changed. */ - changed = 1; - -/* Free resources */ - map2 = astAnnul( map2 ); - smap = astAnnul( smap ); - } - frm = astAnnul( frm ); - fs2 = astAnnul( fs2 ); - map = astAnnul( map ); - -/* Report error if conversion between Frames is not possible. */ - } else if( astOK ) { - astError( AST__BADIN, "astSetUnc(%s): Bad %d dimensional " - "uncertainty Frame (%s %s) supplied.", status, astGetClass(this), - astGetNaxes(unc), astGetDomain(unc), astGetTitle(unc) ); - astError( AST__NCPIN, "Cannot convert it to the Frame of the " - "new %s.", status, astGetClass( this ) ); - } - -/* Report an error if it is not of a usable class. */ - } else if( unc && astOK ){ - astError( AST__BADIN, "astSetUnc(%s): Bad uncertainty shape " - "(%s) supplied.", status, astGetClass( this ), astGetClass(unc) ); - astError( AST__NCPIN, "The uncertainty Region must be an instance of " - "a centro-symetric subclass of Region (e.g. Box, Circle, " - "Ellipse, etc)." , status); - } - -/* If the uncertainty in the Region has changed, indicate that any cached - information in the Region is now out of date. */ - if( changed ) astResetCache( this ); - -} - -static void ShowMesh( AstRegion *this, int format, const char *ttl, int *status ){ -/* -*++ -* Name: -c astShowMesh -f AST_SHOWMESH - -* Purpose: -* Display a mesh of points covering the surface of a Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c void astShowMesh( AstRegion *this, int format, const char *ttl ) -f CALL AST_SHOWMESH( THIS, FORMAT, TTL, STATUS ) - -* Class Membership: -* Region method. - -* Description: -c This function -f This routine -* writes a table to standard output containing the axis values at a -* mesh of points covering the surface of the supplied Region. Each row -* of output contains a tab-separated list of axis values, one for -* each axis in the Frame encapsulated by the Region. The number of -* points in the mesh is determined by the MeshSize attribute. -* -* The table is preceded by a given title string, and followed by a -* single line containing the word "ENDMESH". - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -c format -f FORMAT = LOGICAL (Given) -* A boolean value indicating if the displayed axis values should -* be formatted according to the Format attribute associated with -* the Frame's axis. Otherwise, they are displayed as simple -* floating point values. -c ttl -f TTL = CHARACTER * ( * ) (Given) -* A title to display before displaying the first position. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - AstPointSet *ps; /* PointSet holding mesh */ - char *buffer = NULL; /* Buffer for line output text */ - char buf[ 40 ]; /* Buffer for floating poitn value */ - double **ptr; /* Pointers to the mesh data */ - int i; /* Axis index */ - int j; /* Position index */ - int nax; /* Number of axes */ - int nc; /* Number of characters in buffer */ - int np; /* Number of axis values per position */ - -/* Check the inherited status. */ - if( !astOK ) return; - -/* Get a PointSet holding the mesh */ - ps = astRegMesh( this ); - if( ps ) { - -/* Get the number of axis values per position, and the number of positions. */ - nax = astGetNcoord( ps ); - np = astGetNpoint( ps ); - -/* Get a pointer to the mesh data, and check it can be used. */ - ptr = astGetPoints( ps ); - if( ptr ) { - -/* Display the title. */ - if( ttl ) printf( "\n%s\n\n", ttl ); - -/* Loop round all positions. */ - for( j = 0; j < np; j++ ) { - -/* Reset the current buffer length to zero. */ - nc = 0; - -/* Loop round all axes */ - for( i = 0; i < nax; i++ ){ - -/* If the axis value is bad, append " in the end of the output buffer. */ - if( ptr[ i ][ j ] == AST__BAD ){ - buffer = astAppendString( buffer, &nc, "" ); - -/* Otherwise, if required, append the formatted value to the end of the - buffer. */ - } else if( format ){ - buffer = astAppendString( buffer, &nc, - astFormat( this, i, ptr[ i ][ j ] ) ); - -/* Otherwise, append the floating point value to the end of the buffer. */ - } else { - sprintf( buf, "%g", ptr[ i ][ j ] ); - buffer = astAppendString( buffer, &nc, buf ); - } -/* Add a separating tab to the end of the buffer. */ - buffer = astAppendString( buffer, &nc, "\t" ); - } - -/* Display the line buffer. */ - printf( "%s\n", buffer ); - } - } - -/* Print out a marker for th eend of the list. */ - printf( "ENDMESH\n\n" ); - -/* Release resources. */ - ps = astAnnul( ps ); - buffer = astFree( buffer ); - } -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify the Mapping represented by a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* Region method (over-rides the astSimplify method inherited -* from the Frame class). - -* Description: -* This function simplifies the encapsulated FrameSet and any -* uncertainty Region in the supplied Region. This is different to -* the Simplify method in the parent Frame class which always returns -* a UnitMap. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the simplified Region. A cloned pointer to the -* supplied Region will be returned if no simplication could be -* performed. - -* Notes: -* - This implementation just simplifies the encapsulated FrameSet -* and uncertainty Region. Sub-classes should usually provide their own -* implementation which invokes this implemetation, and then continues to -* check for further simplifications (such as fitting a new region to the -* current Frame). -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* Pointer to "this" baseFrame */ - AstFrameSet *fs; /* Pointer to encapsulated FrameSet */ - AstMapping *map; /* Base->current Mapping for "this" */ - AstMapping *result; /* Result pointer to return */ - AstPointSet *pset1; /* Base Frame centre position */ - AstPointSet *pset2; /* Current Frame centre position */ - AstRegion *new; /* Pointer to simplified Region */ - AstRegion *sunc; /* Simplified uncertainty Region */ - AstRegion *this; /* Pointer to original Region structure */ - AstRegion *unc; /* Original uncertainty Region */ - double **ptr1; /* Pointer to axis values in "pset1" */ - double *cen; /* Original centre of uncertainty Region */ - double *lbnd; /* Lower bounds of "this" bounding box */ - double *orig_cen; /* Original centre for uncertainty Region */ - double *s1_lbnd; /* Lower bounds of "unc" when centred at lbnd */ - double *s1_ubnd; /* Upper bounds of "unc" when centred at lbnd */ - double *s2_lbnd; /* Lower bounds of "unc" when centred at ubnd */ - double *s2_ubnd; /* Upper bounds of "unc" when centred at ubnd */ - double *ubnd; /* Upper bounds of "this" bounding box */ - double delta; /* Half width of test box */ - double w1; /* Width of "s1" bounding box */ - double w2; /* Width of "s2" bounding box */ - int ic; /* Axis index */ - int naxb; /* No. of base Frame axes in "this" */ - int nin; /* Number of base Frame axes in "this" */ - int nout; /* Number of current Frame axes in "this" */ - int ok; /* Can we use the simplified uncertainty? */ - int simpler; /* Has some simplication taken place? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_mapping; - -/* Take a deep copy of the supplied Region. This is so that the returned - pointer will have a diferent value to the supplied pointer if any - simplication takes place. */ - new = astCopy( this ); - -/* Simplify the encapsulated FrameSet, and note if any simplification took - place. */ - fs = astSimplify( new->frameset ); - simpler = ( fs != new->frameset ); - -/* If so, annull the existing FrameSet and use the simpler FrameSet. */ - if( simpler ) { - (void) astAnnul( new->frameset ); - new->frameset = astClone( fs ); - } - fs = astAnnul( fs ); - -/* If the Region has default uncertainty, we simplify the uncertainty - Region simply by deleting it. It will be regenerated when needed, - using the simplified Region. */ - if( new->defunc ) new->defunc = astAnnul( new->defunc ); - -/* If the Region's uncertainty was supplied explicitly, try simplifying - the unncertainty Region. */ - if( astTestUnc( new ) ){ - -/* Obtain the Region's uncertainty. */ - unc = astGetUncFrm( new, AST__BASE ); - -/* Get the base->current Mapping from "this". */ - map = astGetMapping( this->frameset, AST__BASE, AST__CURRENT ); - -/* If it has different numbers of inputs and outputs (e.g. a PermMap used - to take a slice through a Region), we need to ensure that the - uncertainty Region is centred on the slice. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - if( nin != nout ) { - -/* Get the current centre of the uncertainty Region in its current Frame - (the same as the base Frame of "this"). */ - cen = astRegCentre( unc, NULL, NULL, 0, AST__CURRENT ); - -/* Store it in a PointSet so it can be transformed. */ - pset1 = astPointSet( 1, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - if( astOK ) for( ic = 0; ic < nin; ic++ ) ptr1[ ic ][ 0 ] = cen[ ic ]; - -/* Transform into the curent Frame of "this", and then back into the base - Frame. */ - pset2 = astTransform( map, pset1, 1, NULL ); - (void) astTransform( map, pset2, 0, pset1 ); - -/* Re-centre the uncertainty Region at this position. */ - astRegCentre( unc, NULL, ptr1, 0, AST__CURRENT ); - -/* Free resources. */ - cen = astFree( cen ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - } - -/* Free resources. */ - map = astAnnul( map ); - -/* Try simplifying the uncertainty. Only proceed if the uncertainty can - be simplified. */ - sunc = astSimplify( unc ); - if( sunc != unc ) { - -/* If the uncertainty can be simplified it means that the base->current - Mapping in the uncertainty Region is sufficiently linear to allow the - uncertainty shape to retain its form when transformed from the base to - the current Frane. But this has only been tested at the current centre - position in the uncertainty Region. The uncertainty Region should - describe the whole of "this" Region, and so we need to check that the - simplified uncertainty does not change as we move it around within "this" - Region. To do this, we re-centre the uncertainty region at opposite - corners of a large test box, and then we find the bounding box of the - re-centred uncertainty Region. If this uncertainty bounding box changes - from corner to corner of the test box, then we do not simplify the - uncertainty Region. If "this" is bounded, we use the bounding box of - "this" as the test box. Otherwise we use a box 100 times the size of the - uncertainty Region. */ - -/* Note the original base Frame centre of the simplified uncertainty Region. */ - orig_cen = astRegCentre( sunc, NULL, NULL, 0, AST__BASE ); - -/* Allocate memory to hold the bounds of the test box. */ - naxb = astGetNin( this->frameset ); - lbnd = astMalloc( sizeof( double )*(size_t)naxb ); - ubnd = astMalloc( sizeof( double )*(size_t)naxb ); - -/* If possible, get the base Frame bounding box of "this" and use it as - the test box. */ - if( astGetBounded( this ) ) { - astRegBaseBox( this, lbnd, ubnd ); - -/* Otherwise, store the bounds of a box which is 100 times the size of - the uncertainty region, centred on the current centre of the uncertainty - region (we know all uncertainty regions are bounded). */ - } else { - astGetRegionBounds( sunc, lbnd, ubnd ); - for( ic = 0; ic < naxb; ic++ ) { - delta = 0.5*fabs( ubnd[ ic ] - lbnd[ ic ] ); - lbnd[ ic ] = orig_cen[ ic ] - delta; - ubnd[ ic ] = orig_cen[ ic ] + delta; - } - } - -/* Re-centre it at the lower bounds of the test box. This is in the base Frame - of "this" which is the same as the current Frame of "sunc". */ - astRegCentre( sunc, lbnd, NULL, 0, AST__CURRENT ); - -/* Get the bounding box of the re-centred uncertainty Region, within its - current Frame, which is the same as the base Frame of "this". */ - s1_lbnd = astMalloc( sizeof( double )*(size_t)naxb ); - s1_ubnd = astMalloc( sizeof( double )*(size_t)naxb ); - astGetRegionBounds( sunc, s1_lbnd, s1_ubnd ); - -/* Now re-centre the uncertainty Region at the upper bounds of the test - box. */ - astRegCentre( sunc, ubnd, NULL, 0, AST__CURRENT ); - -/* Get the bounding box of the re-centred uncertainty Region. */ - s2_lbnd = astMalloc( sizeof( double )*(size_t)naxb ); - s2_ubnd = astMalloc( sizeof( double )*(size_t)naxb ); - astGetRegionBounds( sunc, s2_lbnd, s2_ubnd ); - -/* Get a pointer to the base Frame of "this". */ - bfrm = astGetFrame( this->frameset, AST__BASE ); - -/* The "ok" flag is initialised to indicate that the simplified uncertainty - Region should not be used. */ - ok = 0; - -/* Check pointers can be referenced safely */ - if( astOK ) { - -/* Now indicate that the simplified uncertainty Region should be used. */ - ok = 1; - -/* Loop round all axes of the base Frame of "this". */ - for( ic = 0; ic < naxb; ic++ ) { - -/* Get the width of the two bounding boxes on this axis. */ - w1 = s1_ubnd[ ic ] - s1_lbnd[ ic ]; - w2 = s2_ubnd[ ic ] - s2_lbnd[ ic ]; - -/* If these differ by more than 0.1% then we determine that the simplified - uncertainty Region varies in size across the bounding box of "this", and - so we do not use the simplified uncertainty Region. The figure of 0.1% - is arbitrary. */ - if( fabs( w1 - w2 ) > 0.005*( fabs( w1 ) + fabs( w2 ) ) ) { - ok = 0; - break; - } - } - } - -/* Reinstate the original base Frame centre of the simplified uncertainty Region. */ - astRegCentre( sunc, orig_cen, NULL, 0, AST__BASE ); - -/* Free resources. */ - orig_cen = astFree( orig_cen ); - lbnd = astFree( lbnd ); - ubnd = astFree( ubnd ); - s1_lbnd = astFree( s1_lbnd ); - s1_ubnd = astFree( s1_ubnd ); - s2_lbnd = astFree( s2_lbnd ); - s2_ubnd = astFree( s2_ubnd ); - bfrm = astAnnul( bfrm ); - -/* If we can use the simplified uncertainty Region, indicate that we have - performed some simplification, and store the new uncertainty Region. */ - if( ok ) { - simpler = 1; - astSetUnc( new, sunc ); - } - } - -/* Free resources */ - unc = astAnnul( unc ); - sunc = astAnnul( sunc ); - } - -/* If any simplification could be performed, return the new Region. - Otherwise, return a clone of the supplied pointer. */ - if( simpler ){ - result = (AstMapping *) new; - } else { - new = astAnnul( new ); - result = astClone( this ); - } - -/* If an error occurred, annul the returned pointer. */ - if ( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static int SubFrame( AstFrame *this_frame, AstFrame *template, - int result_naxes, - const int *target_axes, const int *template_axes, - AstMapping **map, AstFrame **result, int *status ) { -/* -* Name: -* SubFrame - -* Purpose: -* Select axes from a Region and convert to the new coordinate system. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int SubFrame( AstFrame *target, AstFrame *template, int result_naxes, -* const int *target_axes, const int *template_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astSubFrame -* method inherited from the Frame class). - -* Description: -* This function selects a requested sub-set (or super-set) of the -* axes from the current Frame of a "target" Region and creates a -* new Frame with copies of the selected axes assembled in the -* requested order. It then optionally overlays the attributes of a -* "template" Frame on to the result. It returns both the resulting -* Frame and a Mapping that describes how to convert between the -* coordinate systems described by the current Frame of the target -* Region and the result Frame. If necessary, this Mapping takes -* account of any differences in the Frames' attributes due to the -* influence of the template. - -* Parameters: -* target -* Pointer to the target Region, from whose current Frame the -* axes are to be selected. -* template -* Pointer to the template Frame, from which new attributes for -* the result Frame are to be obtained. Optionally, this may be -* NULL, in which case no overlaying of template attributes will -* be performed. -* result_naxes -* Number of axes to be selected from the target Region. This -* number may be greater than or less than the number of axes in -* the Region's current Frame (or equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving -* a list of the (zero-based) axis indices of the axes to be -* selected from the current Frame of the target Region. The -* order in which these are given determines the order in which -* the axes appear in the result Frame. If any of the values in -* this array is set to -1, the corresponding result axis will -* not be derived from the target Region, but will be assigned -* default attributes instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This -* should contain a list of the template axes (given as -* zero-based axis indices) with which the axes of the result -* Frame are to be associated. This array determines which axes -* are used when overlaying axis-dependent attributes of the -* template on to the result. If any element of this array is -* set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not -* used and a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned -* Mapping. The forward transformation of this Mapping will -* describe how to convert coordinates from the coordinate -* system described by the current Frame of the target Region -* to that described by the result Frame. The inverse -* transformation will convert in the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is -* possible between the current Frame of the target Region and -* the result Frame. Otherwise zero is returned and *map and -* *result are returned as NULL (but this will not in itself result -* in an error condition). In general, coordinate conversion should -* always be possible if no template Frame is supplied but may not -* always be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to Region's current Frame */ - int match; /* Result to be returned */ - -/* Initialise. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Invoke the parent astSubFrame method on the Frame represented by the - region. */ - fr = astGetFrame( ((AstRegion *) this_frame)->frameset, AST__CURRENT ); - match = astSubFrame( fr, template, result_naxes, target_axes, template_axes, - map, result ); - fr = astAnnul( fr ); - -/* Return the result. */ - return match; -} - -static AstSystemType SystemCode( AstFrame *this_frame, const char *system, int *status ) { -/* -* Name: -* SystemCode - -* Purpose: -* Convert a string into a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astSystemCode -* method inherited from the Frame class). - -* Description: -* This function converts a string used for the external description of -* a coordinate system into a Frame coordinate system type code (System -* attribute value). It is the inverse of the astSystemString function. - -* Parameters: -* this -* Pointer to the Frame. -* system -* Pointer to a constant null-terminated string containing the -* external description of the coordinate system. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System type code. - -* Notes: -* - A value of AST__BADSYSTEM is returned if the coordinate system -* description was not recognised. This does not produce an error. -* - A value of AST__BADSYSTEM is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Result value to return */ - AstFrame *fr; /* Pointer to FrameSet's current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke the - astSystemCode method for this Frame. Annul the Frame pointer afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astSystemCode( fr, system ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BADSYSTEM; - -/* Return the result. */ - return result; -} - -static const char *SystemString( AstFrame *this_frame, AstSystemType system, int *status ) { -/* -* Name: -* SystemString - -* Purpose: -* Convert a coordinate system type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* const char *SystemString( AstFrame *this, AstSystemType system, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astSystemString -* method inherited from the Frame class). - -* Description: -* This function converts a Frame coordinate system type code -* (System attribute value) into a string suitable for use as an -* external representation of the coordinate system type. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to FrameSet's current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke the - astSystemString method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astSystemString( fr, system ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = NULL; - -/* Return the result pointer. */ - return result; - -} - -static int RegTrace( AstRegion *this, int n, double *dist, double **ptr, int *status ){ -/* -*+ -* Name: -* astRegTrace - -* Purpose: -* Return requested positions on the boundary of a 2D Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* int astRegTrace( AstRegion *this, int n, double *dist, double **ptr ); - -* Class Membership: -* Region virtual function - -* Description: -* This function returns positions on the boundary of the supplied -* Region, if possible. The required positions are indicated by a -* supplied list of scalar parameter values in the range zero to one. -* Zero corresponds to some arbitrary starting point on the boundary, -* and one corresponds to the end (which for a closed region will be -* the same place as the start). - -* Parameters: -* this -* Pointer to the Region. -* n -* The number of positions to return. If this is zero, the function -* returns without action (but the returned function value still -* indicates if the method is supported or not). -* dist -* Pointer to an array of "n" scalar parameter values in the range -* 0 to 1.0. -* ptr -* A pointer to an array of pointers. The number of elements in -* this array should equal tthe number of axes in the Frame spanned -* by the Region. Each element of the array should be a pointer to -* an array of "n" doubles, in which to return the "n" values for -* the corresponding axis. The contents of the arrays are unchanged -* if the supplied Region belongs to a class that does not -* implement this method. - -* Returned Value: -* Non-zero if the astRegTrace method is implemented by the class -* of Region supplied, and zero if not. - -*- -*/ - -/* Concrete sub-classes of Region must over-ride this method. */ - return 0; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Region member function (over-rides the astTestAttrib protected -* method inherited from the Frame class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Region's attributes. - -* Parameters: -* this -* Pointer to the Region. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstRegion *this; /* Pointer to the Region structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* We first handle attributes that apply to the Region as a whole - (rather than to the encapsulated FrameSet). */ - -/* Negated. */ -/* -------- */ - if ( !strcmp( attrib, "negated" ) ) { - result = astTestNegated( this ); - -/* Closed. */ -/* ------- */ - } else if ( !strcmp( attrib, "closed" ) ) { - result = astTestClosed( this ); - -/* FillFactor */ -/* ---------- */ - } else if ( !strcmp( attrib, "fillfactor" ) ) { - result = astTestFillFactor( this ); - -/* MeshSize */ -/* -------- */ - } else if ( !strcmp( attrib, "meshsize" ) ) { - result = astTestMeshSize( this ); - -/* Adaptive */ -/* -------- */ - } else if ( !strcmp( attrib, "adaptive" ) ) { - result = astTestAdaptive( this ); - -/* Now do attributes inherited from parent classes. This is so that the - attribute test will not be passed on to the encpasulated FrameSet below. */ - -/* ID. */ -/* --- */ - } else if ( !strcmp( attrib, "id" ) ) { - result = astTestID( this ); - -/* Ident. */ -/* ------ */ - } else if ( !strcmp( attrib, "ident" ) ) { - result = astTestIdent( this ); - -/* Invert. */ -/* ------- */ - } else if ( !strcmp( attrib, "invert" ) ) { - result = astTestInvert( this ); - -/* Report. */ -/* ------- */ - } else if ( !strcmp( attrib, "report" ) ) { - result = astTestReport( this ); - -/* If the name is not recognised, test if it matches any of the - read-only attributes of this class. If it does, then return - zero. */ - } else if ( !strcmp( attrib, "class" ) || - !strcmp( attrib, "nin" ) || - !strcmp( attrib, "nobject" ) || - !strcmp( attrib, "bounded" ) || - !strcmp( attrib, "nout" ) || - !strcmp( attrib, "refcount" ) || - !strcmp( attrib, "tranforward" ) || - !strcmp( attrib, "traninverse" ) ) { - result = 0; - -/* Pass unrecognised attributes on to the Region's encapsulated FrameSet for - further interpretation. Do not pass on FrameSet attributes since we - pretend to the outside world that the encapsulated FrameSet is actually a - Frame. */ - } else if ( strcmp( attrib, "base" ) && - strcmp( attrib, "current" ) && - strcmp( attrib, "nframe" ) ) { - result = astTestAttrib( this->frameset, attrib ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -double *astRegTranPoint_( AstRegion *this, double *in, int np, int forward, int *status ){ -/* -*+ -* Name: -* astRegTranPoint - -* Purpose: -* Transform points between the base and current Frames in a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* double *astRegTranPoint( AstRegion *this, double *in, int np, int forward ) - -* Class Membership: -* Region member function - -* Description: -* This function transforms one or more points between the base and -* current Frames of the FrameSet encapsulated by the supplied Region. - -* Parameters: -* this -* The Region pointer. -* in -* Pointer to a 1-d array holding the axis values to be transformed. -* If "forward" is non-zero, the number of axis values supplied for -* each position should equal the number of axes in the base Frame -* of the FrameSet encapsulated by "this". If "forward" is zero, the -* number of axis values supplied for each position should equal the -* number of axes in the current Frame of the FrameSet encapsulated by -* "this". All the axis values for a position should be in adjacent -* elements of the array. -* np -* The number of points supplied in "in". -* forward -* If non-zero, the supplied points are assumed to refer to the base -* Frame of the encapsulated FrameSet, and they are transformed to the -* current Frame. If zero, the supplied points are assumed to refer to -* the current Frame of the encapsulated FrameSet, and they are -* transformed to the base Frame. - -* Returned Value: -* Pointer to a new dynamically allocated array holding the -* transformed axis values. If "forward" is non-zero, the number of axis -* values for each position will be equal the number of axes in the -* current Frame of the FrameSet encapsulated by "this". If "forward" is -* zero, the number of axis values for each position will be equal to the -* number of axes in the base Frame of the FrameSet encapsulated by "this". -* All the axis values for a position will be in adjacent elements of the -* array. The array should be freed using astFree when no longer needed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - AstMapping *map; - AstPointSet *pset_in; - AstPointSet *pset_out; - double **ptr_in; - double **ptr_out; - double *p; - double *result; - int ic; - int ip; - int naxin; - int naxout; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the required Mapping. */ - if( forward ) { - map = astGetMapping( this->frameset, AST__BASE, AST__CURRENT ); - } else { - map = astGetMapping( this->frameset, AST__CURRENT, AST__BASE ); - } - -/* Get the number of axis values per input and per output point. */ - naxin = astGetNin( map ); - naxout = astGetNout( map ); - -/* Create a pointSet holding the supplied axis values. */ - pset_in = astPointSet( np, naxin, "", status ); - -/* Get pointers to the memory used to store axis values within this - PointSet. */ - ptr_in = astGetPoints( pset_in ); - -/* Allocate the output array. */ - result = astMalloc( sizeof( double )*(size_t)( naxout*np ) ); - -/* Check the pointers can be used. */ - if( astOK ) { - -/* Store the supplied axis values in the PointSet memory. */ - p = in; - for( ip = 0; ip < np; ip++ ) { - for( ic = 0; ic < naxin; ic++ ) ptr_in[ ic ][ ip ] = *(p++); - } - -/* Transform the PointSet. */ - pset_out = astTransform( map, pset_in, 1, NULL ); - -/* Get a pointer to the memory in the transformed PointSet. */ - ptr_out = astGetPoints( pset_out ); - - if( pset_out && astStatus == AST__INTER ) { - p = in; - for( ip = 0; ip < np; ip++ ) { - for( ic = 0; ic < naxin; ic++ ) printf("%.*g\n", AST__DBL_DIG, *(p++) ); - } - } - - if( astOK ) { - -/* Store the resulting axis values in the output array. */ - p = result; - for( ip = 0; ip < np; ip++ ) { - for( ic = 0; ic < naxout; ic++ ) *(p++) = ptr_out[ ic ][ ip ]; - } - } - -/* Free resources. */ - pset_out = astAnnul( pset_out ); - } - pset_in = astAnnul( pset_in ); - map = astAnnul( map ); - -/* Return NULL if anything went wrong. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result.*/ - return result; -} - -static AstPointSet *RegTransform( AstRegion *this, AstPointSet *in, - int forward, AstPointSet *out, AstFrame **frm, int *status ) { -/* -*+ -* Name: -* astRegTransform - -* Purpose: -* Transform a set of points using the encapsulated FrameSet. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstPointSet *astRegTransform( AstRegion *this, AstPointSet *in, -* int forward, AstPointSet *out, -* AstFrameSet **frm ) - -* Class Membership: -* Region virtual function - -* Description: -* This function takes a Region and a set of points encapsulated -* in a PointSet, and applies either the forward or inverse -* coordinate transformation represented by the encapsulated FrameSet. -* It also returned a pointer to either the current or base Frame in -* the FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* in -* Pointer to the PointSet holding the input coordinate data. If -* NULL then the "points" PointSet within the supplied Region -* ("this") is used. -* forward -* A non-zero value indicates that the forward coordinate transformation -* (from base to current) should be applied, while a zero value requests -* the inverse transformation (from current to base). -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* frm -* Location at which to return a pointer to a Frame. If "forward" -* is non-zero, the current Frame in the encapsulated FrameSet will -* be returned. Otherwise, the base Frame is returned. The returned -* pointer should be annulled when no longer needed. May be NULL if -* no pointer is needed. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. If "out" is NULL, -* the returned pointer will be a clone of "in" if the Mapping is a -* UnitMap. If "out" is not NULL, then the supplied "out" PointSet will -* be used and returned. - -* Notes: -* - An error will result if the Region supplied does not define -* the requested coordinate transformation (either forward or -* inverse). -* - The number of coordinate values per point in the input -* PointSet must match the number of input coordinates for the -* Region being applied (or number of output coordinates if the -* inverse transformation is requested). This will be equal to the -* number of axes in the Region's base Frame (or the current -* Frame for the inverse transformation). -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and coordinate values per point to -* accommodate the result (e.g. the number of Region output -* coordinates, or number of input coordinates if the inverse -* transformation is requested). Any excess space will be ignored. -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstMapping *smap; /* Pointer to simplified Mapping */ - AstPointSet *result; /* Pointer value to return */ - -/* Initialise */ - if( frm ) *frm = NULL; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* If no input PointSet was provided, use the PointSet in the Region. */ - if( !in ) { - if( this->points ) { - in = this->points; - } else { - astError( AST__INTER, "astRegTransform(%s): No PointSet supplied " - "and the supplied %s has no PointSet (internal AST " - "programming error)", status, astGetClass( this ),astGetClass( this ) ); - } - } - -/* Get the simplified Mapping from base to current Frame. */ - smap = astRegMapping( this ); - -/* If it is a UnitMap, return a clone of the input PointSet unless an - explicit output PointSet has been supplied. */ - if( astIsAUnitMap( smap ) && !out ) { - result = astClone( in ); - -/* Otherwise use the Mapping to transform the supplied positions. */ - } else { - result = astTransform( smap, in, forward, out ); - } - -/* Return a pointer to the appropriate Frame. */ - if( frm ) *frm = astGetFrame( this->frameset, forward ? AST__CURRENT : AST__BASE ); - -/* Release resources. */ - smap = astAnnul( smap ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static int Unformat( AstFrame *this_frame, int axis, const char *string, - double *value, int *status ) { -/* -* Name: -* Unformat - -* Purpose: -* Read a formatted coordinate value for a Region axis. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int Unformat( AstFrame *this, int axis, const char *string, -* double *value, int *status ) - -* Class Membership: -* Region member function (over-rides the public astUnformat -* method inherited from the Frame class). - -* Description: -* This function reads a formatted coordinate value for a Region -* axis (supplied as a string) and returns the equivalent numerical -* value as a double. It also returns the number of characters read -* from the string. - -* Parameters: -* this -* Pointer to the Region. -* axis -* The number of the Region axis for which the coordinate -* value is to be read (axis numbering starts at zero for the -* first axis). -* string -* Pointer to a constant null-terminated string containing the -* formatted coordinate value. -* value -* Pointer to a double in which the coordinate value read will be -* returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of characters read from the string to obtain the -* coordinate value. - -* Notes: -* - Any white space at the beginning of the string will be -* skipped, as also will any trailing white space following the -* coordinate value read. The function's return value will reflect -* this. -* - A function value of zero (and no coordinate value) will be -* returned, without error, if the string supplied does not contain -* a suitably formatted value. -* - The string "" is recognised as a special case and will -* generate the value AST__BAD, without error. The test for this -* string is case-insensitive and permits embedded white space. -* - A function result of zero will be returned and no coordinate -* value will be returned via the "value" pointer if this function -* is invoked with the global error status set, or if it should -* fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - double coord; /* Coordinate value read */ - int nc; /* Number of characters read */ - -/* Initialise. */ - nc = 0; - -/* Check the global error status. */ - if ( !astOK ) return nc; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astUnformat" ); - -/* Obtain a pointer to the Region's current Frame and invoke the - astUnformat method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - nc = astUnformat( fr, axis, string, &coord ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the number of characters read. */ - if ( !astOK ) { - nc = 0; - -/* Otherwise, if characters were read, return the coordinate value. */ - } else if ( nc ) { - *value = coord; - } - -/* Return the number of characters read. */ - return nc; -} - -static int ValidateAxis( AstFrame *this_frame, int axis, int fwd, - const char *method, int *status ) { -/* -* Name: -* ValidateAxis - -* Purpose: -* Validate and permute a Region's axis index. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int ValidateAxis( AstFrame *this, int axis, int fwd, const char *method, -* int *status ) - -* Class Membership: -* Region member function (over-rides the protected -* astValidateAxis method inherited from the Frame class). - -* Description: -* This function checks the validity of an index (zero-based) which -* is to be used to address one of the coordinate axes of the -* current Frame in a Region. If the index is valid, it is -* permuted using the axis permutation array associated with the -* Region's current Frame and the (zero-based) permuted axis -* index is returned. This gives the index the axis had when the -* Frame was first created. If the axis index supplied is not -* valid, an error is reported and the global error status is set. - -* Parameters: -* this -* Pointer to the Region. -* axis -* The axis index (zero-based) to be checked. To be valid, it -* must lie between zero and (naxes-1) inclusive, where "naxes" -* is the number of coordinate axes associated with the -* Region's current Frame. -* fwd -* If non-zero, the suppplied axis index is assumed to be an -* "external" axis index, and the corresponding "internal" axis index -* is returned as the function value. Otherwise, the suppplied axis -* index is assumed to be an "internal" axis index, and the -* corresponding "external" axis index is returned as the function -* value. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The permuted axis index - either "internal" or "external" as -* specified by "fwd". - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - int naxes; /* Number of Region axes */ - int result; /* Permuted axis index */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_frame; - -/* Determine the number of Region axes. */ - naxes = astGetNaxes( this ); - if ( astOK ) { - -/* If the Region has no axes, report an error (convert to 1-based - axis numbering for the benefit of the public interface). */ - if ( naxes == 0 ) { - astError( AST__AXIIN, "%s(%s): Invalid attempt to use an axis index " - "(%d) for a %s which has no axes.", status, method, - astGetClass( this ), axis + 1, astGetClass( this ) ); - -/* Otherwise, check the axis index for validity and report an error if - it is not valid (again, convert to 1-based axis numbering). */ - } else if ( ( axis < 0 ) || ( axis >= naxes ) ) { - astError( AST__AXIIN, "%s(%s): Axis index (%d) invalid - it should " - "be in the range 1 to %d.", status, method, astGetClass( this ), - axis + 1, naxes ); - -/* If the axis index was valid, obtain a pointer to the Region's - current Frame and invoke this Frame's astValidateAxis method to - obtain the permuted axis index. Annul the Frame pointer - afterwards. */ - } else { - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astValidateAxis( fr, axis, fwd, "astValidateAxis" ); - fr = astAnnul( fr ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static void ValidateAxisSelection( AstFrame *this_frame, int naxes, - const int *axes, const char *method, int *status ) { -/* -* Name: -* ValidateAxisSelection - -* Purpose: -* Check that a set of axes selected from a Frame is valid. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void ValidateAxisSelection( AstFrame *this, int naxes, -* const int *axes, const char *method, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astValidateAxisSelection -* method inherited from the Frame class). - -* Description: -* This function checks the validity of an array of (zero-based) -* axis indices that specify a set of axes to be selected from a -* Frame. To be valid, no axis should be selected more than -* once. In assessing this, any axis indices that do not refer to -* valid Frame axes (e.g. are set to -1) are ignored. -* -* If the axis selection is valid, this function returns without further -* action. Otherwise, an error is reported and the global error status is -* set. - -* Parameters: -* this -* Pointer to the Frame. -* naxes -* The number of axes to be selected (may be zero). -* axes -* Pointer to an array of int with naxes elements that contains the -* (zero based) axis indices to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis selection. This method name is used -* solely for constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke this - Frame's astValidateAxisSelection method. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - astValidateAxisSelection( fr, naxes, axes, method ); - fr = astAnnul( fr ); - -} - -static int ValidateSystem( AstFrame *this_frame, AstSystemType system, const char *method, int *status ) { -/* -* Name: -* ValidateSystem - -* Purpose: -* Validate a value for a Frame's System attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* int ValidateSystem( AstFrame *this, AstSystemType system, -* const char *method, int *status ) - -* Class Membership: -* Region member function (over-rides the protected astValidateSystem -* method inherited from the Frame class). - -* Description: -* This function checks the validity of the supplied system value. -* If the value is valid, it is returned unchanged. Otherwise, an -* error is reported and a value of AST__BADSYSTEM is returned. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The system value to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The validated system value. - -* Notes: -* - A value of AST_BADSYSTEM will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstSystemType result; /* Validated system value */ - AstFrame *fr; /* Pointer to FrameSet's current Frame */ - AstRegion *this; /* Pointer to the Region structure */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the FrameSet structure. */ - this = (AstRegion *) this_frame; - -/* Obtain a pointer to the Region's encapsulated Frame and invoke the - astValidateSystem method for this Frame. Annul the Frame pointer - afterwards. */ - fr = astGetFrame( this->frameset, AST__CURRENT ); - result = astValidateSystem( this, system, method ); - fr = astAnnul( fr ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BADSYSTEM; - -/* Return the result. */ - return result; -} - -/* Region Attributes. */ -/* -------------------- */ - -/* -*att++ -* Name: -* Adaptive - -* Purpose: -* Should the area adapt to changes in the coordinate system? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* The coordinate system represented by a Region may be changed by -* assigning new values to attributes such as System, Unit, etc. -* For instance, a Region representing an area on the sky in ICRS -* coordinates may have its System attribute changed so that it -* represents (say) Galactic coordinates instead of ICRS. This -* attribute controls what happens when the coordinate system -* represented by a Region is changed in this way. -* -* If Adaptive is non-zero (the default), then area represented by the -* Region adapts to the new coordinate system. That is, the numerical -* values which define the area represented by the Region are changed -* by mapping them from the old coordinate system into the new coordinate -* system. Thus the Region continues to represent the same physical -* area. -* -* If Adaptive is zero, then area represented by the Region does not adapt -* to the new coordinate system. That is, the numerical values which -* define the area represented by the Region are left unchanged. Thus -* the physical area represented by the Region will usually change. -* -* As an example, consider a Region describe a range of wavelength from -* 2000 Angstrom to 4000 Angstrom. If the Unit attribute for the Region -* is changed from Angstrom to "nm" (nanometre), what happens depends -* on the setting of Adaptive. If Adaptive is non-zero, the Mapping -* from the old to the new coordinate system is found. In this case it -* is a simple scaling by a factor of 0.1 (since 1 Angstrom is 0.1 nm). -* This Mapping is then used to modify the numerical values within the -* Region, changing 2000 to 200 and 4000 to 400. Thus the modified -* region represents 200 nm to 400 nm, the same physical space as -* the original 2000 Angstrom to 4000 Angstrom. However, if Adaptive -* had been zero, then the numerical values would not have been changed, -* resulting in the final Region representing 2000 nm to 4000 nm. -* -* Setting Adaptive to zero can be necessary if you want correct -* inaccurate attribute settings in an existing Region. For instance, -* when creating a Region you may not know what Epoch value to use, so -* you would leave Epoch unset resulting in some default value being used. -* If at some later point in the application, the correct Epoch value -* is determined, you could assign the correct value to the Epoch -* attribute. However, you would first need to set Adaptive temporarily -* to zero, because otherwise the area represented by the Region would -* be Mapped from the spurious default Epoch to the new correct Epoch, -* which is not what is required. - -* Applicability: -* Region -* All Regions have this attribute. -*att-- -*/ - -/* This is a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of 1. */ -astMAKE_CLEAR(Region,Adaptive,adaptive,-INT_MAX) -astMAKE_GET(Region,Adaptive,int,1,( ( this->adaptive == -INT_MAX ) ? - 1 : this->adaptive )) -astMAKE_SET(Region,Adaptive,int,adaptive,( value != 0 )) -astMAKE_TEST(Region,Adaptive,( this->adaptive != -INT_MAX )) - -/* -*att++ -* Name: -* Negated - -* Purpose: -* Region negation flag. - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls whether a Region represents the "inside" or -* the "outside" of the area which was supplied when the Region was -* created. If the attribute value is zero (the default), the Region -* represents the inside of the original area. However, if it is non-zero, -* it represents the outside of the original area. The value of this -* attribute may be toggled using the -c astNegate function. -f AST_NEGATE routine. - -* Note, whether the boundary is considered to be inside the Region or -* not is controlled by the Closed attribute. Changing the value of -* the Negated attribute does not change the value of the Closed attribute. -* Thus, if Region is closed, then the boundary of the Region will be -* inside the Region, whatever the setting of the Negated attribute. - -* Applicability: -* Region -* All Regions have this attribute. -*att-- -*/ - -/* This is a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of zero. */ -astMAKE_CLEAR(Region,Negated,negated,(astResetCache(this),-INT_MAX)) -astMAKE_GET(Region,Negated,int,0,( ( this->negated == -INT_MAX ) ? - 0 : this->negated )) -astMAKE_SET(Region,Negated,int,negated,(astResetCache(this),( value != 0 ))) -astMAKE_TEST(Region,Negated,( this->negated != -INT_MAX )) - -/* -*att++ -* Name: -* Bounded - -* Purpose: -* Is the Region bounded? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean), read-only. - -* Description: -* This is a read-only attribute indicating if the Region is bounded. -* A Region is bounded if it is contained entirely within some -* finite-size bounding box. - -* Applicability: -* Region -* All Regions have this attribute. -*att-- -*/ - -/* -*att+ -* Name: -* RegionFS - -* Purpose: -* Should Region FrameSet be dumped? - -* Type: -* Protected attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute indicates whether the FrameSet encapsulated by the -* Region should be included in the dump produced by the Dump function. -* -* If set to a non-zero value (the default), the FrameSet in the Region -* will always be included in the dump as usual. If set to zero, the -* FrameSet will only be included in the dump if the Mapping from base -* to current Frame is not a UnitMap. If the base->current Mapping is -* a UnitMap, the FrameSet is omitted from the dump. If the dump is -* subsequently used to re-create the Region, the new Region will have a -* default FrameSet containing a single default Frame with the appropriate -* number of axes. -* -* This facility is indended to reduce the size of textual dumps of -* Regions in situations where the Frame to which the Region refers can -* be implied by the context in which the Region is used. This is -* often the case when a Region is encapsulated within another Region. -* In such cases the current Frame of the encapsulated Region will -* usually be equivalent to the base Frame of the parent Region -* structure, and so can be re-instated (by calling the astSetRegFS -* method) even if the FrameSet is omitted from the dump of the -* encapsulated Region. Note if the base->current Mapping in the FrameSet -* in the encapsulated Region is not a UnitMap, then we should always -* dump the FrameSet regardless of the setting of RegionFS. This is because -* the parent Region structure will not know how to convert the PointSet -* stored in the encapsulated Region into its own base Frame if the -* FrameSet is not available. - -* Applicability: -* Region -* All Regions have this attribute. -*att- -*/ - -/* This is a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of one. */ -astMAKE_CLEAR(Region,RegionFS,regionfs,-INT_MAX) -astMAKE_TEST(Region,RegionFS,( this->regionfs != -INT_MAX )) -astMAKE_SET(Region,RegionFS,int,regionfs,( value != 0 )) -astMAKE_GET(Region,RegionFS,int,1,( ( this->regionfs == -INT_MAX ) ? - 1 : this->regionfs )) - -/* -*att++ -* Name: -* FillFactor - -* Purpose: -* Fraction of the Region which is of interest. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute indicates the fraction of the Region which is of -* interest. AST does not use this attribute internally for any purpose. -* Typically, it could be used to indicate the fraction of the Region for -* which data is available. -* -* The supplied value must be in the range 0.0 to 1.0, and the default -* value is 1.0 (except as noted below). - -* Applicability: -* Region -* All Regions have this attribute. -* CmpRegion -* The default FillFactor for a CmpRegion is the FillFactor of its -* first component Region. -* Prism -* The default FillFactor for a Prism is the product of the -* FillFactors of its two component Regions. -* Stc -* The default FillFactor for an Stc is the FillFactor of its -* encapsulated Region. -*att-- -*/ - -astMAKE_CLEAR(Region,FillFactor,fillfactor,AST__BAD) -astMAKE_GET(Region,FillFactor,double,1.0,( ( this->fillfactor == AST__BAD ) ? - 1.0 : this->fillfactor )) -astMAKE_TEST(Region,FillFactor,( this->fillfactor != AST__BAD )) -astMAKE_SET(Region,FillFactor,double,fillfactor,((value<0.0||value>1.0)?( - astError(AST__ATSER,"astSetFillFactor(%s): Invalid value (%g) supplied " - "for attribute FillFactor.", status,astGetClass(this),value), - astError(AST__ATSER,"FillFactor values should be in the range 0.0 to 1.0", status), - this->fillfactor):value)) - -/* -*att++ -* Name: -* MeshSize - -* Purpose: -* Number of points used to represent the boundary of a Region. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute controls how many points are used when creating a -* mesh of points covering the boundary or volume of a Region. Such a -* mesh is returned by the -c astGetRegionMesh -f AST_GETREGIONMESH -* method. The boundary mesh is also used when testing for overlap -* between two Regions: each point in the bomdary mesh of the first -* Region is checked to see if it is inside or outside the second Region. -* Thus, the reliability of the overlap check depends on the value assigned -* to this attribute. If the value used is very low, it is possible for -* overlaps to go unnoticed. High values produce more reliable results, but -* can result in the overlap test being very slow. The default value is 200 -* for two dimensional Regions and 2000 for three or more dimensional -* Regions (this attribute is not used for 1-dimensional regions since the -* boundary of a simple 1-d Region can only ever have two points). A -* value of five is used if the supplied value is less than five. - -* Applicability: -* Region -* All Regions have this attribute. -* CmpRegion -* The default MeshSize for a CmpRegion is the MeshSize of its -* first component Region. -* Stc -* The default MeshSize for an Stc is the MeshSize of its -* encapsulated Region. -*att-- -*/ -/* If the value of MeshSize is set or cleared, annul the PointSet used to - cache a mesh of base Frame boundary points. This will force a new - PointSet to be created next time it is needed. See function RegMesh. */ -astMAKE_CLEAR(Region,MeshSize,meshsize,(astResetCache(this),-INT_MAX)) -astMAKE_SET(Region,MeshSize,int,meshsize,(astResetCache(this),( value > 5 ? value : 5 ))) -astMAKE_TEST(Region,MeshSize,( this->meshsize != -INT_MAX )) -astMAKE_GET(Region,MeshSize,int,0,( ( this->meshsize == -INT_MAX)?((astGetNaxes(this)==1)?2:((astGetNaxes(this)==2)?200:2000)): this->meshsize )) - -/* -*att++ -* Name: -* Closed - -* Purpose: -* Should the boundary be considered to be inside the region? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls whether points on the boundary of a Region -* are considered to be inside or outside the region. If the attribute -* value is non-zero (the default), points on the boundary are considered -* to be inside the region (that is, the Region is "closed"). However, -* if the attribute value is zero, points on the bounary are considered -* to be outside the region. - -* Applicability: -* Region -* All Regions have this attribute. -* PointList -* The value of the Closed attribute is ignored by PointList regions. -* If the PointList region has not been negated, then it is always -* assumed to be closed. If the PointList region has been negated, then -* it is always assumed to be open. This is required since points -* have zero volume and therefore consist entirely of boundary. -* CmpRegion -* The default Closed value for a CmpRegion is the Closed value of its -* first component Region. -* Stc -* The default Closed value for an Stc is the Closed value of its -* encapsulated Region. -*att-- -*/ -/* This is a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of 1. */ -astMAKE_CLEAR(Region,Closed,closed,(astResetCache(this),-INT_MAX)) -astMAKE_GET(Region,Closed,int,1,( ( this->closed == -INT_MAX ) ? - 1 : this->closed )) -astMAKE_SET(Region,Closed,int,closed,(astResetCache(this),( value != 0 ))) -astMAKE_TEST(Region,Closed,( this->closed != -INT_MAX )) - -/* Access to attributes of the encapsulated Frame. */ -/* ----------------------------------------------- */ -/* Use the macros defined at the start of this file to implement - private member functions that give access to the attributes of the - encapsulated Frame of a Region and its axes. These functions over-ride - the attribute access methods inherited from the Frame class. */ - -/* Clear, Get, Set and Test axis-independent Frame attributes. */ -MAKE_CLEAR(Digits) -MAKE_CLEAR(Domain) -MAKE_CLEAR(MatchEnd) -MAKE_CLEAR(MaxAxes) -MAKE_CLEAR(MinAxes) -MAKE_CLEAR(Permute) -MAKE_CLEAR(PreserveAxes) -MAKE_CLEAR(Title) - -MAKE_GET(Digits,int) -MAKE_GET(Domain,const char *) -MAKE_GET(MatchEnd,int) -MAKE_GET(MaxAxes,int) -MAKE_GET(MinAxes,int) -MAKE_GET(Permute,int) -MAKE_GET(PreserveAxes,int) -MAKE_GET(Title,const char *) -MAKE_SET(Digits,int,I) -MAKE_SET(Domain,const char *,C) -MAKE_SET(MatchEnd,int,I) -MAKE_SET(MaxAxes,int,I) -MAKE_SET(MinAxes,int,I) -MAKE_SET(Permute,int,I) -MAKE_SET(PreserveAxes,int,I) -MAKE_SET(Title,const char *,C) -MAKE_TEST(Digits) -MAKE_TEST(Domain) -MAKE_TEST(MatchEnd) -MAKE_TEST(MaxAxes) -MAKE_TEST(MinAxes) -MAKE_TEST(Permute) -MAKE_TEST(PreserveAxes) -MAKE_TEST(Title) - -MAKE_GET(ActiveUnit,int) -MAKE_SET(ActiveUnit,int,I) -MAKE_TEST(ActiveUnit) - -MAKE_GET(System,AstSystemType) -MAKE_SET_SYSTEM(System) -MAKE_TEST(System) -MAKE_CLEAR(System) - -MAKE_GET(AlignSystem,AstSystemType) -MAKE_SET_SYSTEM(AlignSystem) -MAKE_TEST(AlignSystem) -MAKE_CLEAR(AlignSystem) - -MAKE_GET(Epoch,double) -MAKE_SET(Epoch,double,D) -MAKE_TEST(Epoch) -MAKE_CLEAR(Epoch) - -MAKE_GET(ObsLon,double) -MAKE_SET(ObsLon,double,D) -MAKE_TEST(ObsLon) -MAKE_CLEAR(ObsLon) - -MAKE_GET(ObsLat,double) -MAKE_SET(ObsLat,double,D) -MAKE_TEST(ObsLat) -MAKE_CLEAR(ObsLat) - -MAKE_GET(ObsAlt,double) -MAKE_SET(ObsAlt,double,D) -MAKE_TEST(ObsAlt) -MAKE_CLEAR(ObsAlt) - -/* Clear, Get, Set and Test axis-dependent Frame attributes. */ -MAKE_CLEAR_AXIS(Direction) -MAKE_CLEAR_AXIS(Format) -MAKE_CLEAR_AXIS(Label) -MAKE_CLEAR_AXIS(Symbol) -MAKE_CLEAR_AXIS(Unit) -MAKE_GET_AXIS(Direction,int) -MAKE_GET_AXIS(Format,const char *) -MAKE_GET_AXIS(Label,const char *) -MAKE_GET_AXIS(Symbol,const char *) -MAKE_GET_AXIS(Unit,const char *) -MAKE_SET_AXIS(Direction,int,I) -MAKE_SET_AXIS(Format,const char *,C) -MAKE_SET_AXIS(Label,const char *,C) -MAKE_SET_AXIS(Symbol,const char *,C) -MAKE_SET_AXIS(Unit,const char *,C) -MAKE_TEST_AXIS(Direction) -MAKE_TEST_AXIS(Format) -MAKE_TEST_AXIS(Label) -MAKE_TEST_AXIS(Symbol) -MAKE_TEST_AXIS(Unit) - -MAKE_GET_AXIS(Bottom,double) -MAKE_SET_AXIS(Bottom,double,D) -MAKE_TEST_AXIS(Bottom) -MAKE_CLEAR_AXIS(Bottom) - -MAKE_GET_AXIS(Top,double) -MAKE_SET_AXIS(Top,double,D) -MAKE_TEST_AXIS(Top) -MAKE_CLEAR_AXIS(Top) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Region objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Region objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstRegion *in; /* Pointer to input Region */ - AstRegion *out; /* Pointer to output Region */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Regions. */ - in = (AstRegion *) objin; - out = (AstRegion *) objout; - -/* For safety, first clear any references to the input memory from - the output Region. */ - out->basemesh = NULL; - out->basegrid = NULL; - out->frameset = NULL; - out->points = NULL; - out->unc = NULL; - out->negation = NULL; - out->defunc = NULL; - -/* Now copy each of the above structures. */ - out->frameset = astCopy( in->frameset ); - if( in->points ) out->points = astCopy( in->points ); - if( in->basemesh ) out->basemesh = astCopy( in->basemesh ); - if( in->basegrid ) out->basegrid = astCopy( in->basegrid ); - if( in->unc ) out->unc = astCopy( in->unc ); - if( in->negation ) out->negation = astCopy( in->negation ); - if( in->defunc ) out->defunc = astCopy( in->defunc ); -} - - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Region objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Region objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstRegion *this; /* Pointer to Region */ - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) obj; - -/* Annul all resources. */ - this->frameset = astAnnul( this->frameset ); - if( this->points ) this->points = astAnnul( this->points ); - if( this->basemesh ) this->basemesh = astAnnul( this->basemesh ); - if( this->basegrid ) this->basegrid = astAnnul( this->basegrid ); - if( this->unc ) this->unc = astAnnul( this->unc ); - if( this->negation ) this->negation = astAnnul( this->negation ); - if( this->defunc ) this->defunc = astAnnul( this->defunc ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Region objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Region class to an output Channel. - -* Parameters: -* this -* Pointer to the Region whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define KEY_LEN 50 /* Maximum length of a keyword */ -#define COM_LEN 50 /* Maximum length of a comment */ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to the current Frame */ - AstMapping *smap; /* Base->current Mapping */ - AstRegion *this; /* Pointer to the Region structure */ - AstRegion *unc; /* Pointer to the uncertainty Region */ - double dval; /* Floating point attribute value */ - int ival; /* Integer attribute value */ - int set; /* Attribute value set? */ - int unit; /* Base->current is unitmap? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Region structure. */ - this = (AstRegion *) this_object; - -/* Write out values representing the instance variables for the - Region class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Negated. */ -/* -------- */ - set = TestNegated( this, status ); - ival = set ? GetNegated( this, status ) : astGetNegated( this ); - astWriteInt( channel, "Negate", (ival != 0), 0, ival, - ival ? "Region negated" : "Region not negated" ); - -/* FillFactor */ -/* ---------- */ - set = TestFillFactor( this, status ); - dval = set ? GetFillFactor( this, status ) : astGetFillFactor( this ); - astWriteDouble( channel, "Fill", set, 0, dval,"Region fill factor" ); - -/* MeshSize. */ -/* --------- */ - set = TestMeshSize( this, status ); - ival = set ? GetMeshSize( this, status ) : astGetMeshSize( this ); - astWriteInt( channel, "MeshSz", set, 0, ival, - "No. of points used to represent boundary" ); - -/* Closed. */ -/* ------- */ - set = TestClosed( this, status ); - ival = set ? GetClosed( this, status ) : astGetClosed( this ); - astWriteInt( channel, "Closed", set, 0, ival, - ival ? "Boundary is inside" : "Boundary is outside" ); - -/* Adaptive */ -/* -------- */ - set = TestAdaptive( this, status ); - ival = set ? GetAdaptive( this, status ) : astGetAdaptive( this ); - astWriteInt( channel, "Adapt", (ival != 0), 0, ival, - ival ? "Region adapts to coord sys changes" : "Region does not adapt to coord sys changes" ); - -/* FrameSet */ -/* -------- */ - -/* If the vertices are the same in both base and current Frames (i.e. - if the Frames are connected by a UnitMap), then just dump the current - Frame (unless the RegionFS attribute is zero, in which case the - current Frame can be determined from the higher level context of the - Region and so does not need to be dumped- e.g. if the Region is contained - within another Region the parent Region will define the current Frame). - Otherwise, dump the whole FrameSet. */ - ival = astGetRegionFS( this ); - smap = astRegMapping( this ); - if( ( unit = astIsAUnitMap( smap ) ) ){ - set = 0; - if( ival ) { - fr = astGetFrame( this->frameset, AST__CURRENT ); - astWriteObject( channel, "Frm", 1, 1, fr, "Coordinate system" ); - fr = astAnnul( fr ); - } - } else { - set = ( ival == 0 ); - astWriteObject( channel, "FrmSet", 1, 1, this->frameset, - "Original & current coordinate systems" ); - } - -/* Annul the Mapping pointers */ - smap = astAnnul( smap ); - -/* RegionFS */ -/* -------- */ - astWriteInt( channel, "RegFS", set, 0, ival, - ival ? "Include Frame in dump" : "Do not include Frame in dump" ); - -/* Points */ -/* ------ */ - if( this->points ) { - astWriteObject( channel, "Points", 1, 1, this->points, - "Points defining the shape" ); - -/* If the FrameSet was not included in the dump, then the loader will use - the PointSet to determine the number of axes in the frame spanned by - the Region. If there is no PointSet, then we must explicitly include - an item giving the number of axes.*/ - } else { - astWriteInt( channel, "RegAxes", 1, 1, astGetNaxes( this ), - "Number of axes spanned by the Region" ); - } - -/* Uncertainty */ -/* ----------- */ -/* Only dump the uncertinaty Region if required. */ - if( astTestUnc( this ) ) { - unc = astGetUncFrm( this, AST__BASE ); - astWriteObject( channel, "Unc", 1, 1, unc, - "Region defining positional uncertainties." ); - unc = astAnnul( unc ); - } - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsARegion and astCheckRegion functions using - the macros defined for this purpose in the "object.h" header - file. */ -astMAKE_ISA(Region,Frame) -astMAKE_CHECK(Region) - -AstRegion *astInitRegion_( void *mem, size_t size, int init, - AstRegionVtab *vtab, const char *name, - AstFrame *frame, AstPointSet *pset, - AstRegion *unc, int *status ){ -/* -*+ -* Name: -* astInitRegion - -* Purpose: -* Initialise a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstRegion *astInitRegion( void *mem, size_t size, int init, -* AstRegionVtab *vtab, const char *name, -* AstFrame *frame, AstpointSet *pset, -* AstRegion *unc ) - -* Class Membership: -* Region initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new Region object. It allocates memory (if -* necessary) to accommodate the Region plus any additional data -* associated with the derived class. It then initialises a -* Region structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual -* function table for a Region at the start of the memory passed -* via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Region is to be -* created. This must be of sufficient size to accommodate the -* Region data (sizeof(Region)) plus any data used by the -* derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Region (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Region structure, so a valid value must be -* supplied even if not required for allocating memory. -* init -* A logical flag indicating if the Region's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Region. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* frame -* Pointer to the encapsulated Frame. A deep copy of this Frame is -* taken. This means that subsequent changes to the supplied Frame -* will have no effect on the new Region. -* pset -* A PointSet holding the points which define the Region. These -* positions should refer to the given Frame. May be NULL. -* unc -* A pointer to a Region which specifies the uncertainty in the -* supplied positions (all points on the boundary of the new Region -* being initialised are assumed to have the same uncertainty). A NULL -* pointer can be supplied, in which case default uncertainties equal to -* 1.0E-6 of the dimensions of the new Region's bounding box are used. -* If an uncertainty Region is supplied, it must be of a class for -* which all instances are centro-symetric (e.g. Box, Circle, Ellipse, -* etc.) or be a Prism containing centro-symetric component Regions. -* Its encapsulated Frame must be related to the Frame supplied for -* parameter "frame" (i.e. astConvert should be able to find a Mapping -* between them). Two positions in the "frame" Frame are considered to be -* co-incident if their uncertainty Regions overlap. The centre of the -* supplied uncertainty Region is immaterial since it will be re-centred -* on the point being tested before use. A deep copy is taken of the -* supplied Region. - -* Returned Value: -* A pointer to the new Region. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstFrame *f0; /* Frame to use */ - AstRegion *new; /* Pointer to new Region */ - int nax; /* No. of axes in supplied Frame */ - int ncoord; /* Coords per point */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if( init ) astInitRegionVtab( vtab, name ); - -/* Note the number of axes in the supplied Frame. */ - nax = astGetNaxes( frame ); - -/* Check the pointset if supplied. */ - if( pset ) { - -/* Note the number of axes per point in the supplied PointSet */ - ncoord = astGetNcoord( pset ); - -/* If OK, check that the number of coordinates per point matches the number - of axes in the Frame. Report an error if these numbers do not match. */ - if ( astOK && ( ncoord != nax ) ) { - astError( AST__NCPIN, "astInitRegion(%s): Bad number of coordinate " - "values per point (%d).", status, name, ncoord ); - astError( AST__NCPIN, "The %s given requires %d coordinate value(s) " - "for each point.", status, astGetClass( frame ), nax ); - } - } - -/* Initialise a Frame structure (the parent class) as the first - component within the Region structure, allocating memory if - necessary. Give this Frame zero axes as the Frame information will be - specified by the encapsulated FrameSet. */ - new = (AstRegion *) astInitFrame( mem, size, 0, (AstFrameVtab *) vtab, - name, 0 ); - if ( astOK ) { - -/* Initialise the Region data. */ -/* ----------------------------- */ - new->frameset = NULL; - new->points = NULL; - new->unc = NULL; - new->meshsize = -INT_MAX; - new->adaptive = -INT_MAX; - new->basemesh = NULL; - new->basegrid = NULL; - new->negated = -INT_MAX; - new->closed = -INT_MAX; - new->regionfs = -INT_MAX; - new->fillfactor = AST__BAD; - new->defunc = NULL; - new->nomap = 0; - new->negation = NULL; - -/* If the supplied Frame is a Region, gets its encapsulated Frame. If a - FrameSet was supplied, use its current Frame, otherwise use the - supplied Frame. */ - if( astIsARegion( frame ) ) { - f0 = astGetFrame( ((AstRegion *) frame)->frameset, AST__CURRENT ); - - } else if( astIsAFrameSet( frame ) ) { - f0 = astGetFrame( (AstFrameSet *) frame, AST__CURRENT ); - - } else { - f0 = astClone( frame ); - } - -/* Store a clone of the supplied PointSet pointer. */ - new->points = pset ? astClone( pset ) : NULL; - - -#ifdef DEBUG - if( pset ) { - double **ptr; - double lim; - int ii,jj, np; - ptr = astGetPoints( pset ); - np = astGetNpoint( pset ); - lim = sqrt( DBL_MAX ); - for( ii = 0; astOK && ii < ncoord; ii++ ) { - for( jj = 0; jj < np; jj++ ) { - if( fabs( ptr[ ii ][ jj ] ) > lim ) { - if( !strcmp( name, "Interval" ) ) { - if( ptr[ ii ][ jj ] != AST__BAD && - ptr[ ii ][ jj ] != DBL_MAX && - ptr[ ii ][ jj ] != -DBL_MAX ) { - astError( AST__INTER, "astInitRegion(%s): suspicious " - "axis value (%g) supplied.", status, name, ptr[ ii ][ jj ] ); - break; - } - } else { - astError( AST__INTER, "astInitRegion(%s): suspicious " - "axis value (%g) supplied.", status, name, - ptr[ ii ][ jj ] ); - break; - } - } - } - } - } -#endif - -/* Form a FrameSet consisting of two copies of the supplied Frame connected - together by a UnitMap, and store in the Region structure. We use the - private SetRegFS rather than the protected astSetRegFS because this - initialiser may be being called from a subclass which over-rides - astSetRegFS. If this were the case, then the implementation of - astSetRegFS provided by the subclass may access information within the - subclass structure which has not yet been initialised. */ - SetRegFS( new, f0, status ); - f0 = astAnnul( f0 ); - -/* Store any uncertainty Region. Use the private SetUnc rather than - astSetUnc to avoid subclass implementations using subclass data which - has not yet been initialised. */ - SetUnc( new, unc, status ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstRegion *astLoadRegion_( void *mem, size_t size, - AstRegionVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadRegion - -* Purpose: -* Load a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* AstRegion *astLoadRegion( void *mem, size_t size, -* AstRegionVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* Region loader. - -* Description: -* This function is provided to load a new Region using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Region structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the Region is to be -* loaded. This must be of sufficient size to accommodate the -* Region data (sizeof(Region)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Region (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Region structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstRegion) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Region. If this is NULL, a pointer -* to the (static) virtual function table for the Region class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Region" is used instead. - -* Returned Value: -* A pointer to the new Region. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstFrame *f1; /* Base Frame for encapsulated FrameSet */ - AstRegion *new; /* Pointer to the new Region */ - int nax; /* No. of axes in Frame, or FrameSet base Frame */ - int naxpt; /* No. of axes in per point */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Region. In this case the - Region belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstRegion ); - vtab = &class_vtab; - name = "Region"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitRegionVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Region. */ - new = astLoadFrame( mem, size, (AstFrameVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Region" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Negated */ -/* ------- */ - new->negated = astReadInt( channel, "negate", -INT_MAX ); - if ( TestNegated( new, status ) ) SetNegated( new, new->negated, status ); - -/* FillFactor */ -/* ---------- */ - new->fillfactor = astReadDouble( channel, "fill", AST__BAD ); - if ( TestFillFactor( new, status ) ) SetFillFactor( new, new->fillfactor, status ); - -/* MeshSize */ -/* -------- */ - new->meshsize = astReadInt( channel, "meshsz", -INT_MAX ); - if ( TestMeshSize( new, status ) ) SetMeshSize( new, new->meshsize, status ); - -/* Closed */ -/* ------ */ - new->closed = astReadInt( channel, "closed", -INT_MAX ); - if ( TestClosed( new, status ) ) SetClosed( new, new->closed, status ); - -/* Adaptive */ -/* -------- */ - new->adaptive = astReadInt( channel, "adapt", -INT_MAX ); - if ( TestAdaptive( new, status ) ) SetAdaptive( new, new->adaptive, status ); - -/* Points */ -/* ------ */ - new->points = astReadObject( channel, "points", NULL ); - -/* If some points were found, ensure that they are in a PointSet and get - the number of axis values per point. */ - if( new->points ){ - if( astIsAPointSet( new->points) ) { - naxpt = astGetNcoord( new->points ); - } else { - naxpt = 0; - astError( AST__REGIN, "astLoadRegion(%s): Corrupt %s specifies points " - "using a %s (should be a PointSet).", status, astGetClass( new ), - astGetClass( new ), astGetClass( new->points ) ); - } - -/* If no PointSet was loaded, attempt to determine the number of axes - spanned by the Region by reading the RegAxes value. */ - } else { - naxpt = astReadInt( channel, "regaxes", 0 ); - } - -/* Uncertainty */ -/* ----------- */ - new->unc = astReadObject( channel, "unc", NULL ); - new->defunc = NULL; - -/* FrameSet */ -/* -------- */ -/* First see if the dump contains a single Frame. If so, create a - FrameSet from it and a copy of itself, using a UnitMap to connect the - two. */ - new->nomap = 0; - new->frameset = NULL; - f1 = astReadObject( channel, "frm", NULL ); - if( f1 ) { - new->regionfs = 1; - nax = astGetNaxes( f1 ); - astSetRegFS( new, f1 ); - f1 = astAnnul( f1 ); - -/* If no Frame was found in the dump, look for a FrameSet. Get the number - of axes spanning its base Frame ("Nin"). */ - } else { - new->frameset = astReadObject( channel, "frmset", NULL ); - if( new->frameset ) { - nax = astGetNin( new->frameset ); - -/* If a FrameSet was found, the value of the RegionFS attribute is still - unknown and so we must read it from an attribute as normal. */ - new->regionfs = astReadInt( channel, "regfs", 1 ); - if ( TestRegionFS( new, status ) ) SetRegionFS( new, new->regionfs, status ); - - } else { - nax = 0; - } - } - -/* If neither a Frame nor a FrameSet was found, create a default FrameSet - and set the RegionFS attribute false, to indicate that the FrameSet - should not be used. */ - if( !new->frameset ){ - nax = naxpt ? naxpt : 1; - f1 = astFrame( nax, "", status ); - new->frameset = astFrameSet( f1, "", status ); - astSetIdent( new->frameset, DUMMY_FS ); - f1 = astAnnul( f1 ); - new->regionfs = 0; - } - -/* Report an error if the number of axis values per point in the pointset is - incorrect. */ - if ( astOK && new->points && ( naxpt != nax ) ) { - astError( AST__REGIN, "astLoadRegion(%s): Corrupt %s contains " - " incorrect number of coordinate values per point (%d).", status, - astGetClass( new ), astGetClass( new ), naxpt ); - astError( AST__REGIN, "The %s requires %d coordinate value(s) " - "for each point.", status, astGetClass( new ), nax ); - } - -/* Initialise other fields which are used as caches for values derived - from the attributes set above. */ - new->basemesh = NULL; - new->basegrid = NULL; - -/* If an error occurred, clean up by deleting the new Region. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Region pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astRegClearAttrib_( AstRegion *this, const char *attrib, char **base_attrib, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Region,RegClearAttrib))( this, attrib, base_attrib, status ); -} -void astRegSetAttrib_( AstRegion *this, const char *setting, char **base_setting, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Region,RegSetAttrib))( this, setting, base_setting, status ); -} -void astNegate_( AstRegion *this, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,Negate))( this, status ); -} -AstFrame *astGetRegionFrame_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,GetRegionFrame))( this, status ); -} -AstFrameSet *astGetRegionFrameSet_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,GetRegionFrameSet))( this, status ); -} -AstRegion *astMapRegion_( AstRegion *this, AstMapping *map, AstFrame *frame, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,MapRegion))( this, map, frame, status ); -} -int astOverlap_( AstRegion *this, AstRegion *that, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Region,Overlap))( this, that, status ); -} -int astOverlapX_( AstRegion *that, AstRegion *this, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(that,Region,OverlapX))( that, this, status ); -} -AstFrame *astRegFrame_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegFrame))( this, status ); -} -AstRegion *astRegBasePick_( AstRegion *this, int naxes, const int *axes, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegBasePick))( this, naxes, axes, status ); -} -AstPointSet *astBTransform_( AstRegion *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,BTransform))( this, in, forward, out, status ); -} -AstPointSet *astRegTransform_( AstRegion *this, AstPointSet *in, - int forward, AstPointSet *out, - AstFrame **frm, int *status ) { - if( frm ) *frm = NULL; - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegTransform))( this, in, forward, out, frm, status ); -} -int astRegPins_( AstRegion *this, AstPointSet *pset, AstRegion *unc, int **mask, int *status ){ - if( mask ) *mask = NULL; - if ( !astOK ) return 0; - return (**astMEMBER(this,Region,RegPins))( this, pset, unc, mask, status ); -} -AstMapping *astRegMapping_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegMapping))( this, status ); -} -int astRegDummyFS_( AstRegion *this, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Region,RegDummyFS))( this, status ); -} -int astGetBounded_( AstRegion *this, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Region,GetBounded))( this, status ); -} -int astTestUnc_( AstRegion *this, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Region,TestUnc))( this, status ); -} -void astClearUnc_( AstRegion *this, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,ClearUnc))( this, status ); -} -void astRegBaseBox_( AstRegion *this, double *lbnd, double *ubnd, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,RegBaseBox))( this, lbnd, ubnd, status ); -} -void astRegBaseBox2_( AstRegion *this, double *lbnd, double *ubnd, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,RegBaseBox2))( this, lbnd, ubnd, status ); -} -void astResetCache_( AstRegion *this, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,ResetCache))( this, status ); -} -int astRegTrace_( AstRegion *this, int n, double *dist, double **ptr, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Region,RegTrace))( this, n, dist, ptr, status ); -} -void astGetRegionBounds_( AstRegion *this, double *lbnd, double *ubnd, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,GetRegionBounds))( this, lbnd, ubnd, status ); -} -void astGetRegionMesh_( AstRegion *this, int surface, int maxpoint, - int maxcoord, int *npoint, double *points, - int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,GetRegionMesh))( this, surface, maxpoint, maxcoord, - npoint, points, status ); -} -void astGetRegionPoints_( AstRegion *this, int maxpoint, int maxcoord, - int *npoint, double *points, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,GetRegionPoints))( this, maxpoint, maxcoord, - npoint, points, status ); -} -void astShowMesh_( AstRegion *this, int format, const char *ttl, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,ShowMesh))( this, format,ttl, status ); -} -void astGetRegionBounds2_( AstRegion *this, double *lbnd, double *ubnd, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,GetRegionBounds2))( this, lbnd, ubnd, status ); -} -void astRegOverlay_( AstRegion *this, AstRegion *that, int unc, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,RegOverlay))( this, that, unc, status ); -} -AstPointSet *astRegGrid_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegGrid))( this, status ); -} -AstPointSet *astRegMesh_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegMesh))( this, status ); -} -double *astRegCentre_( AstRegion *this, double *cen, double **ptr, int index, - int ifrm, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegCentre))( this, cen, ptr, index, ifrm, status ); -} -AstRegion *astGetNegation_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,GetNegation))( this, status ); -} -AstRegion *astGetUncFrm_( AstRegion *this, int ifrm, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,GetUncFrm))( this, ifrm, status ); -} -AstRegion *astGetDefUnc_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,GetDefUnc))( this, status ); -} -AstRegion *astGetUnc_( AstRegion *this, int def, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,GetUnc))( this, def, status ); -} -void astSetUnc_( AstRegion *this, AstRegion *unc, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,SetUnc))( this, unc, status ); -} -AstFrameSet *astGetRegFS_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,GetRegFS))( this, status ); -} -void astSetRegFS_( AstRegion *this, AstFrame *frm, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Region,SetRegFS))( this, frm, status ); -} -AstPointSet *astRegBaseMesh_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegBaseMesh))( this, status ); -} -AstRegion **astRegSplit_( AstRegion *this, int *nlist, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegSplit))( this, nlist, status ); -} -AstPointSet *astRegBaseGrid_( AstRegion *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,RegBaseGrid))( this, status ); -} -AstPointSet *astBndBaseMesh_( AstRegion *this, double *lbnd, double *ubnd, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,BndBaseMesh))( this, lbnd, ubnd, status ); -} -AstPointSet *astBndMesh_( AstRegion *this, double *lbnd, double *ubnd, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Region,BndMesh))( this, lbnd, ubnd, status ); -} - -#define MAKE_MASK_(X,Xtype) \ -int astMask##X##_( AstRegion *this, AstMapping *map, int inside, int ndim, \ - const int lbnd[], const int ubnd[], Xtype in[], \ - Xtype val, int *status ) { \ - if ( !astOK ) return 0; \ - return (**astMEMBER(this,Region,Mask##X))( this, map, inside, ndim, lbnd, \ - ubnd, in, val, status ); \ -} -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -MAKE_MASK_(LD,long double) -#endif -MAKE_MASK_(D,double) -MAKE_MASK_(F,float) -MAKE_MASK_(L,long int) -MAKE_MASK_(UL,unsigned long int) -MAKE_MASK_(I,int) -MAKE_MASK_(UI,unsigned int) -MAKE_MASK_(S,short int) -MAKE_MASK_(US,unsigned short int) -MAKE_MASK_(B,signed char) -MAKE_MASK_(UB,unsigned char) -#undef MAKE_MASK_ - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ - -/* Special interface function implementations. */ -/* ------------------------------------------- */ - - -AstRegion *astMapRegionId_( AstRegion *this, AstMapping *map, AstFrame *frame, int *status ) { -/* -*++ -* Name: -c astMapRegion -f AST_MAPREGION - -* Purpose: -* Transform a Region into a new Frame using a given Mapping. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "region.h" -c AstRegion *astMapRegion( AstRegion *this, AstMapping *map, -c AstFrame *frame ) -f RESULT = AST_MAPREGION( THIS, MAP, FRAME, STATUS ) - -* Class Membership: -* Region method. - -* Description: -* This function returns a pointer to a new Region which corresponds to -* supplied Region described by some other specified coordinate system. A -* Mapping is supplied which transforms positions between the old and new -* coordinate systems. The new Region may not be of the same class as -* the original region. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Region. -c map -f MAP = INTEGER (Given) -* Pointer to a Mapping which transforms positions from the -* coordinate system represented by the supplied Region to the -* coordinate system specified by -c "frame". -f FRAME. -* The supplied Mapping should define both forward and inverse -* transformations, and these transformations should form a genuine -* inverse pair. That is, transforming a position using the forward -* transformation and then using the inverse transformation should -* produce the original input position. Some Mapping classes (such -* as PermMap, MathMap, SphMap) can result in Mappings for which this -* is not true. -c frame -f FRAME = INTEGER (Given) -* Pointer to a Frame describing the coordinate system in which -* the new Region is required. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astMapRegion() -f AST_MAPREGION = INTEGER -* A pointer to a new Region. This Region will represent the area -* within the coordinate system specified by -c "frame" -f FRAME -* which corresponds to the supplied Region. - -* Notes: -* - The uncertainty associated with the supplied Region is modified -* using the supplied Mapping. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - The only difference between this public interface and the protected -* astMapRegion interface is that this implementation additionally -* simplifies the returned Region. The protected implementation does -* not do this since doing so can lead to infinite recursion because -* it is sometimes necessary for Simplify to call astMapRegion. - -*/ - -/* Local Variables: */ - AstRegion *new; /* Pointer to new Region */ - AstRegion *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the protected astMapRegion function. */ - new = astMapRegion( this, map, frame ); - -/* Simplify the resulting Region. */ - result = astSimplify( new ); - -/* Free resources. */ - new = astAnnul( new ); - -/* If not OK, annul the returned pointer. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - - - - - - - - - - - - diff --git a/ast/region.h b/ast/region.h deleted file mode 100644 index b6ffd4e..0000000 --- a/ast/region.h +++ /dev/null @@ -1,515 +0,0 @@ -#if !defined( REGION_INCLUDED ) /* Include this file only once */ -#define REGION_INCLUDED -/* -*+ -* Name: -* region.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Region class. - -* Invocation: -* #include "region.h" - -* Description: -* This include file defines the interface to the Region class and -* provides the type definitions, function prototypes and macros, etc. -* needed to use this class. - -* Inheritance: -* The Region class inherits from the Frame class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 5-DEC-2003 (DSB): -* Original version. -* 2-MAR-2006 (DSB): -* Changed AST_LONG_DOUBLE to HAVE_LONG_DOUBLE. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "frame.h" /* Parent Frame class */ - -/* Macros. */ -/* ======= */ - -/* Type Definitions. */ -/* ================= */ -/* Region structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -typedef struct AstRegion { - -/* Attributes inherited from the parent class. */ - AstFrame parent; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstFrameSet *frameset; /* FrameSet holding original and current Frames */ - AstPointSet *points; /* Points defining region location and extent */ - struct AstRegion *unc; /* Region specifying position uncertainties */ - double fillfactor; /* Fill factor (0.0->1.0) */ - int regionfs; /* Include FrameSet in dump? */ - int negated; /* Has the Region been negated? */ - int closed; /* Is the boundary part of the Region? */ - int meshsize; /* No. of points on boundary mesh */ - struct AstRegion *defunc; /* Default uncertainty Region */ - AstPointSet *basemesh; /* Base frame mesh covering the boundary */ - AstPointSet *basegrid; /* Base frame grid covering the boundary */ - int adaptive; /* Does the Region adapt to coord sys changes? */ - int nomap; /* Ignore the Region's FrameSet? */ - struct AstRegion *negation;/* Negated copy of "this" */ -} AstRegion; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all objects in the - class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstRegionVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstFrameVtab frame_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - int (* Overlap)( AstRegion *, AstRegion *, int * ); - int (* OverlapX)( AstRegion *, AstRegion *, int * ); - AstRegion *(* MapRegion)( AstRegion *, AstMapping *, AstFrame *, int * ); - AstFrame *(* GetRegionFrame)( AstRegion *, int * ); - AstFrameSet *(* GetRegionFrameSet)( AstRegion *, int * ); - AstFrame *(* RegFrame)( AstRegion *, int * ); - AstFrameSet *(* GetRegFS)( AstRegion *, int * ); - AstPointSet *(* RegTransform)( AstRegion *, AstPointSet *, int, AstPointSet *, AstFrame **, int * ); - AstPointSet *(* BTransform)( AstRegion *, AstPointSet *, int, AstPointSet *, int * ); - void (* Negate)( AstRegion *, int * ); - void (* RegBaseBox)( AstRegion *, double *, double *, int * ); - void (* RegBaseBox2)( AstRegion *, double *, double *, int * ); - void (* RegSetAttrib)( AstRegion *, const char *, char **, int * ); - void (* RegClearAttrib)( AstRegion *, const char *, char **, int * ); - void (* GetRegionBounds)( AstRegion *, double *, double *, int * ); - void (* ShowMesh)( AstRegion *, int, const char *, int * ); - void (* GetRegionBounds2)( AstRegion *, double *, double *, int * ); - void (* ClearUnc)( AstRegion *, int * ); - void (* RegOverlay)( AstRegion *, AstRegion *, int, int * ); - void (* GetRegionMesh)( AstRegion *, int, int, int, int *, double *, int * ); - void (* GetRegionPoints)( AstRegion *, int, int, int *, double *, int * ); - int (* GetBounded)( AstRegion *, int * ); - int (* TestUnc)( AstRegion *, int * ); - int (* RegDummyFS)( AstRegion *, int * ); - int (* RegPins)( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); - AstMapping *(* RegMapping)( AstRegion *, int * ); - AstPointSet *(* RegMesh)( AstRegion *, int * ); - AstPointSet *(* RegGrid)( AstRegion *, int * ); - AstPointSet *(* RegBaseMesh)( AstRegion *, int * ); - AstPointSet *(* RegBaseGrid)( AstRegion *, int * ); - AstRegion **(* RegSplit)( AstRegion *, int *, int * ); - AstPointSet *(* BndBaseMesh)( AstRegion *, double *, double *, int * ); - AstPointSet *(* BndMesh)( AstRegion *, double *, double *, int * ); - AstRegion *(* GetNegation)( AstRegion *, int * ); - AstRegion *(* GetUncFrm)( AstRegion *, int, int * ); - AstRegion *(* GetUnc)( AstRegion *, int, int * ); - AstRegion *(* GetDefUnc)( AstRegion *, int * ); - AstRegion *(* RegBasePick)( AstRegion *this, int, const int *, int * ); - void (* ResetCache)( AstRegion *, int * ); - int (* RegTrace)( AstRegion *, int, double *, double **, int * ); - void (* SetUnc)( AstRegion *, AstRegion *, int * ); - void (* SetRegFS)( AstRegion *, AstFrame *, int * ); - double *(* RegCentre)( AstRegion *, double *, double **, int, int, int * ); - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ - int (* MaskLD)( AstRegion *, AstMapping *, int, int, const int[], const int ubnd[], long double [], long double, int * ); -#endif - int (* MaskB)( AstRegion *, AstMapping *, int, int, const int[], const int[], signed char[], signed char, int * ); - int (* MaskD)( AstRegion *, AstMapping *, int, int, const int[], const int[], double[], double, int * ); - int (* MaskF)( AstRegion *, AstMapping *, int, int, const int[], const int[], float[], float, int * ); - int (* MaskI)( AstRegion *, AstMapping *, int, int, const int[], const int[], int[], int, int * ); - int (* MaskL)( AstRegion *, AstMapping *, int, int, const int[], const int[], long int[], long int, int * ); - int (* MaskS)( AstRegion *, AstMapping *, int, int, const int[], const int[], short int[], short int, int * ); - int (* MaskUB)( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned char[], unsigned char, int * ); - int (* MaskUI)( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned int[], unsigned int, int * ); - int (* MaskUL)( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned long int[], unsigned long int, int * ); - int (* MaskUS)( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned short int[], unsigned short int, int * ); - - int (* GetNegated)( AstRegion *, int * ); - int (* TestNegated)( AstRegion *, int * ); - void (* ClearNegated)( AstRegion *, int * ); - void (* SetNegated)( AstRegion *, int, int * ); - - int (* GetRegionFS)( AstRegion *, int * ); - int (* TestRegionFS)( AstRegion *, int * ); - void (* ClearRegionFS)( AstRegion *, int * ); - void (* SetRegionFS)( AstRegion *, int, int * ); - - int (* GetClosed)( AstRegion *, int * ); - int (* TestClosed)( AstRegion *, int * ); - void (* ClearClosed)( AstRegion *, int * ); - void (* SetClosed)( AstRegion *, int, int * ); - - int (* GetMeshSize)( AstRegion *, int * ); - int (* TestMeshSize)( AstRegion *, int * ); - void (* ClearMeshSize)( AstRegion *, int * ); - void (* SetMeshSize)( AstRegion *, int, int * ); - - double (* GetFillFactor)( AstRegion *, int * ); - int (* TestFillFactor)( AstRegion *, int * ); - void (* ClearFillFactor)( AstRegion *, int * ); - void (* SetFillFactor)( AstRegion *, double, int * ); - - int (* GetAdaptive)( AstRegion *, int * ); - int (* TestAdaptive)( AstRegion *, int * ); - void (* ClearAdaptive)( AstRegion *, int * ); - void (* SetAdaptive)( AstRegion *, int, int * ); - -} AstRegionVtab; -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstRegionGlobals { - AstRegionVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 101 ]; -} AstRegionGlobals; - -#endif -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Region) /* Check class membership */ -astPROTO_ISA(Region) /* Test class membership */ - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstRegion *astInitRegion_( void *, size_t, int, AstRegionVtab *, const char *, - AstFrame *, AstPointSet *, AstRegion *, int * ); - -/* Vtab initialiser. */ -void astInitRegionVtab_( AstRegionVtab *, const char *, int * ); - -/* Loader. */ -AstRegion *astLoadRegion_( void *, size_t, AstRegionVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitRegionGlobals_( AstRegionGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -AstFrame *astGetRegionFrame_( AstRegion *, int * ); -AstFrameSet *astGetRegionFrameSet_( AstRegion *, int * ); -int astOverlap_( AstRegion *, AstRegion *, int * ); -void astNegate_( AstRegion *, int * ); - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -int astMaskLD_( AstRegion *, AstMapping *, int, int, const int[], const int[], long double [], long double, int * ); -#endif -int astMaskB_( AstRegion *, AstMapping *, int, int, const int[], const int[], signed char[], signed char, int * ); -int astMaskD_( AstRegion *, AstMapping *, int, int, const int[], const int[], double[], double, int * ); -int astMaskF_( AstRegion *, AstMapping *, int, int, const int[], const int[], float[], float, int * ); -int astMaskI_( AstRegion *, AstMapping *, int, int, const int[], const int[], int[], int, int * ); -int astMaskL_( AstRegion *, AstMapping *, int, int, const int[], const int[], long int[], long int, int * ); -int astMaskS_( AstRegion *, AstMapping *, int, int, const int[], const int[], short int[], short int, int * ); -int astMaskUB_( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned char[], unsigned char, int * ); -int astMaskUI_( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned int[], unsigned int, int * ); -int astMaskUL_( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned long int[], unsigned long int, int * ); -int astMaskUS_( AstRegion *, AstMapping *, int, int, const int[], const int[], unsigned short int[], unsigned short int, int * ); -void astSetUnc_( AstRegion *, AstRegion *, int * ); -AstRegion *astGetNegation_( AstRegion *, int * ); -AstRegion *astGetUnc_( AstRegion *, int, int * ); -void astGetRegionBounds_( AstRegion *, double *, double *, int * ); -void astShowMesh_( AstRegion *, int, const char *, int * ); -void astGetRegionMesh_( AstRegion *, int, int, int, int *, double *, int * ); -void astGetRegionPoints_( AstRegion *, int, int, int *, double *, int * ); - -#if defined(astCLASS) /* Protected */ -void astGetRegionBounds2_( AstRegion *, double *, double *, int * ); -AstRegion *astMapRegion_( AstRegion *, AstMapping *, AstFrame *, int * ); -AstFrame *astRegFrame_( AstRegion *, int * ); -AstPointSet *astRegTransform_( AstRegion *, AstPointSet *, int, AstPointSet *, AstFrame **, int * ); -AstPointSet *astBTransform_( AstRegion *, AstPointSet *, int, AstPointSet *, int * ); -void astRegBaseBox_( AstRegion *, double *, double *, int * ); -void astRegBaseBox2_( AstRegion *, double *, double *, int * ); -void astRegSetAttrib_( AstRegion *, const char *, char **, int * ); -void astRegClearAttrib_( AstRegion *, const char *, char **, int * ); -void astClearUnc_( AstRegion *, int * ); -void astRegOverlay_( AstRegion *, AstRegion *, int, int * ); -int astGetBounded_( AstRegion *, int * ); -int astTestUnc_( AstRegion *, int * ); -int astRegDummyFS_( AstRegion *, int * ); -int astRegPins_( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -AstMapping *astRegMapping_( AstRegion *, int * ); -AstPointSet *astRegMesh_( AstRegion *, int * ); -AstPointSet *astRegGrid_( AstRegion *, int * ); -AstPointSet *astRegBaseMesh_( AstRegion *, int * ); -AstPointSet *astRegBaseGrid_( AstRegion *, int * ); -AstPointSet *astBndBaseMesh_( AstRegion *, double *, double *, int * ); -AstRegion **astRegSplit_( AstRegion *, int *, int * ); -AstPointSet *astBndMesh_( AstRegion *, double *, double *, int * ); -AstRegion *astGetUncFrm_( AstRegion *, int, int * ); -AstRegion *astGetDefUnc_( AstRegion *, int * ); -AstRegion *astRegBasePick_( AstRegion *this, int, const int *, int * ); -int astOverlapX_( AstRegion *, AstRegion *, int * ); -AstFrameSet *astGetRegFS_( AstRegion *, int * ); -void astSetRegFS_( AstRegion *, AstFrame *, int * ); -double *astRegCentre_( AstRegion *, double *, double **, int, int, int * ); -double *astRegTranPoint_( AstRegion *, double *, int, int, int * ); -void astResetCache_( AstRegion *, int * ); -int astRegTrace_( AstRegion *, int, double *, double **, int * ); - -int astGetNegated_( AstRegion *, int * ); -int astTestNegated_( AstRegion *, int * ); -void astClearNegated_( AstRegion *, int * ); -void astSetNegated_( AstRegion *, int, int * ); - -int astGetRegionFS_( AstRegion *, int * ); -int astTestRegionFS_( AstRegion *, int * ); -void astClearRegionFS_( AstRegion *, int * ); -void astSetRegionFS_( AstRegion *, int, int * ); - -int astGetMeshSize_( AstRegion *, int * ); -int astTestMeshSize_( AstRegion *, int * ); -void astClearMeshSize_( AstRegion *, int * ); -void astSetMeshSize_( AstRegion *, int, int * ); - -int astGetClosed_( AstRegion *, int * ); -int astTestClosed_( AstRegion *, int * ); -void astClearClosed_( AstRegion *, int * ); -void astSetClosed_( AstRegion *, int, int * ); - -double astGetFillFactor_( AstRegion *, int * ); -int astTestFillFactor_( AstRegion *, int * ); -void astClearFillFactor_( AstRegion *, int * ); -void astSetFillFactor_( AstRegion *, double, int * ); - -int astGetAdaptive_( AstRegion *, int * ); -int astTestAdaptive_( AstRegion *, int * ); -void astClearAdaptive_( AstRegion *, int * ); -void astSetAdaptive_( AstRegion *, int, int * ); - -#else /* Public only */ -AstRegion *astMapRegionId_( AstRegion *, AstMapping *, AstFrame *, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class to make - them easier to invoke (e.g. to avoid type mis-matches when passing pointers - to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them to - validate their own arguments. We must use a cast when passing object - pointers (so that they can accept objects from derived classes). */ - -/* Check class membership. */ -#define astCheckRegion(this) astINVOKE_CHECK(Region,this,0) -#define astVerifyRegion(this) astINVOKE_CHECK(Region,this,1) - -/* Test class membership. */ -#define astIsARegion(this) astINVOKE_ISA(Region,this) - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitRegion(mem,size,init,vtab,name,frame,pset,acc)\ -astINVOKE(O,astInitRegion_(mem,size,init,vtab,name,astCheckFrame(frame),pset,acc,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitRegionVtab(vtab,name) astINVOKE(V,astInitRegionVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadRegion(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadRegion_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckRegion to validate Region pointers before - use. This provides a contextual error report if a pointer to the wrong sort - of object is supplied. */ -#define astGetRegionFrame(this) \ -astINVOKE(O,astGetRegionFrame_(astCheckRegion(this),STATUS_PTR)) -#define astGetRegionFrameSet(this) \ -astINVOKE(O,astGetRegionFrameSet_(astCheckRegion(this),STATUS_PTR)) -#define astNegate(this) \ -astINVOKE(V,astNegate_(astCheckRegion(this),STATUS_PTR)) -#define astOverlap(this,that) \ -astINVOKE(V,astOverlap_(astCheckRegion(this),astCheckRegion(that),STATUS_PTR)) - -#if HAVE_LONG_DOUBLE /* Not normally implemented */ -#define astMaskLD(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskLD_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#endif - -#define astMaskB(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskB_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astMaskD(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskD_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astMaskF(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskF_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astMaskI(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskI_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astMaskL(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskL_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astMaskS(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskS_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astMaskUB(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskUB_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astMaskUI(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskUI_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astMaskUL(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskUL_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astMaskUS(this,map,inside,ndim,lbnd,ubnd,in,val) \ -astINVOKE(V,astMaskUS_(astCheckRegion(this),(map?astCheckMapping(map):NULL),inside,ndim,lbnd,ubnd,in,val,STATUS_PTR)) -#define astSetUnc(this,unc) astINVOKE(V,astSetUnc_(astCheckRegion(this),unc?astCheckRegion(unc):NULL,STATUS_PTR)) -#define astGetUnc(this,def) astINVOKE(O,astGetUnc_(astCheckRegion(this),def,STATUS_PTR)) -#define astGetRegionBounds(this,lbnd,ubnd) astINVOKE(V,astGetRegionBounds_(astCheckRegion(this),lbnd,ubnd,STATUS_PTR)) -#define astShowMesh(this,format,ttl) astINVOKE(V,astShowMesh_(astCheckRegion(this),format,ttl,STATUS_PTR)) -#define astGetRegionMesh(this,surface,maxpoint,maxcoord,npoint,points) \ -astINVOKE(V,astGetRegionMesh_(astCheckRegion(this),surface,maxpoint,maxcoord,npoint,points,STATUS_PTR)) -#define astGetRegionPoints(this,maxpoint,maxcoord,npoint,points) \ -astINVOKE(V,astGetRegionPoints_(astCheckRegion(this),maxpoint,maxcoord,npoint,points,STATUS_PTR)) - -/* Interfaces to protected member functions. */ -/* ----------------------------------------- */ -#if defined(astCLASS) /* Protected */ - -#define astGetNegation(this) astINVOKE(O,astGetNegation_(astCheckRegion(this),STATUS_PTR)) -#define astGetRegionBounds2(this,lbnd,ubnd) astINVOKE(V,astGetRegionBounds2_(astCheckRegion(this),lbnd,ubnd,STATUS_PTR)) -#define astClearUnc(this) astINVOKE(V,astClearUnc_(astCheckRegion(this),STATUS_PTR)) -#define astGetBounded(this) astINVOKE(V,astGetBounded_(astCheckRegion(this),STATUS_PTR)) -#define astGetUncFrm(this,ifrm) astINVOKE(O,astGetUncFrm_(astCheckRegion(this),ifrm,STATUS_PTR)) -#define astGetDefUnc(this) astINVOKE(O,astGetDefUnc_(astCheckRegion(this),STATUS_PTR)) -#define astMapRegion(this,map,frame) astINVOKE(O,astMapRegion_(astCheckRegion(this),astCheckMapping(map),astCheckFrame(frame),STATUS_PTR)) -#define astOverlapX(that,this) astINVOKE(V,astOverlapX_(astCheckRegion(that),astCheckRegion(this),STATUS_PTR)) -#define astRegBaseBox(this,lbnd,ubnd) astINVOKE(V,astRegBaseBox_(astCheckRegion(this),lbnd,ubnd,STATUS_PTR)) -#define astRegBaseBox2(this,lbnd,ubnd) astINVOKE(V,astRegBaseBox2_(astCheckRegion(this),lbnd,ubnd,STATUS_PTR)) -#define astRegSetAttrib(this,setting,bset) astINVOKE(V,astRegSetAttrib_(astCheckRegion(this),setting,bset,STATUS_PTR)) -#define astRegClearAttrib(this,setting,batt) astINVOKE(V,astRegClearAttrib_(astCheckRegion(this),setting,batt,STATUS_PTR)) -#define astRegBaseMesh(this) astINVOKE(O,astRegBaseMesh_(astCheckRegion(this),STATUS_PTR)) -#define astRegBasePick(this,naxes,axes) astINVOKE(O,astRegBasePick_(astCheckRegion(this),naxes,axes,STATUS_PTR)) -#define astRegBaseGrid(this) astINVOKE(O,astRegBaseGrid_(astCheckRegion(this),STATUS_PTR)) -#define astRegSplit(this,nlist) astINVOKE(V,astRegSplit_(astCheckRegion(this),nlist,STATUS_PTR)) -#define astBndBaseMesh(this,lbnd,ubnd) astINVOKE(O,astBndBaseMesh_(astCheckRegion(this),lbnd,ubnd,STATUS_PTR)) -#define astBndMesh(this,lbnd,ubnd) astINVOKE(O,astBndMesh_(astCheckRegion(this),lbnd,ubnd,STATUS_PTR)) -#define astRegCentre(this,cen,ptr,index,ifrm) astINVOKE(V,astRegCentre_(astCheckRegion(this),cen,ptr,index,ifrm,STATUS_PTR)) -#define astRegFrame(this) astINVOKE(O,astRegFrame_(astCheckRegion(this),STATUS_PTR)) -#define astRegGrid(this) astINVOKE(O,astRegGrid_(astCheckRegion(this),STATUS_PTR)) -#define astRegMesh(this) astINVOKE(O,astRegMesh_(astCheckRegion(this),STATUS_PTR)) -#define astRegOverlay(this,that,unc) astINVOKE(V,astRegOverlay_(astCheckRegion(this),astCheckRegion(that),unc,STATUS_PTR)) -#define astRegDummyFS(this) astINVOKE(V,astRegDummyFS_(astCheckRegion(this),STATUS_PTR)) -#define astRegMapping(this) astINVOKE(O,astRegMapping_(astCheckRegion(this),STATUS_PTR)) -#define astRegPins(this,pset,unc,mask) astINVOKE(V,astRegPins_(astCheckRegion(this),astCheckPointSet(pset),unc?astCheckRegion(unc):unc,mask,STATUS_PTR)) -#define astRegTranPoint(this,in,np,forward) astRegTranPoint_(this,in,np,forward,STATUS_PTR) -#define astGetRegFS(this) astINVOKE(O,astGetRegFS_(astCheckRegion(this),STATUS_PTR)) -#define astSetRegFS(this,frm) astINVOKE(V,astSetRegFS_(astCheckRegion(this),astCheckFrame(frm),STATUS_PTR)) -#define astTestUnc(this) astINVOKE(V,astTestUnc_(astCheckRegion(this),STATUS_PTR)) -#define astResetCache(this) astINVOKE(V,astResetCache_(astCheckRegion(this),STATUS_PTR)) -#define astRegTrace(this,n,dist,ptr) astINVOKE(V,astRegTrace_(astCheckRegion(this),n,dist,ptr,STATUS_PTR)) - -/* Since a NULL PointSet pointer is acceptable for "out", we must omit the - argument checking in that case. (But unfortunately, "out" then gets - evaluated twice - this is unlikely to matter, but is there a better way?) */ - -#define astRegTransform(this,in,forward,out,frm) \ -astINVOKE(O,astRegTransform_(astCheckRegion(this),in?astCheckPointSet(in):NULL,forward,(out)?astCheckPointSet(out):NULL,frm,STATUS_PTR)) - -#define astBTransform(this,in,forward,out) \ -astINVOKE(O,astBTransform_(astCheckRegion(this),in?astCheckPointSet(in):NULL,forward,(out)?astCheckPointSet(out):NULL,STATUS_PTR)) - -#define astClearNegated(this) astINVOKE(V,astClearNegated_(astCheckRegion(this),STATUS_PTR)) -#define astGetNegated(this) astINVOKE(V,astGetNegated_(astCheckRegion(this),STATUS_PTR)) -#define astSetNegated(this,negated) astINVOKE(V,astSetNegated_(astCheckRegion(this),negated,STATUS_PTR)) -#define astTestNegated(this) astINVOKE(V,astTestNegated_(astCheckRegion(this),STATUS_PTR)) - -#define astClearAdaptive(this) astINVOKE(V,astClearAdaptive_(astCheckRegion(this),STATUS_PTR)) -#define astGetAdaptive(this) astINVOKE(V,astGetAdaptive_(astCheckRegion(this),STATUS_PTR)) -#define astSetAdaptive(this,adaptive) astINVOKE(V,astSetAdaptive_(astCheckRegion(this),adaptive,STATUS_PTR)) -#define astTestAdaptive(this) astINVOKE(V,astTestAdaptive_(astCheckRegion(this),STATUS_PTR)) - -#define astClearRegionFS(this) astINVOKE(V,astClearRegionFS_(astCheckRegion(this),STATUS_PTR)) -#define astGetRegionFS(this) astINVOKE(V,astGetRegionFS_(astCheckRegion(this),STATUS_PTR)) -#define astSetRegionFS(this,fs) astINVOKE(V,astSetRegionFS_(astCheckRegion(this),fs,STATUS_PTR)) -#define astTestRegionFS(this) astINVOKE(V,astTestRegionFS_(astCheckRegion(this),STATUS_PTR)) - -#define astClearMeshSize(this) astINVOKE(V,astClearMeshSize_(astCheckRegion(this),STATUS_PTR)) -#define astGetMeshSize(this) astINVOKE(V,astGetMeshSize_(astCheckRegion(this),STATUS_PTR)) -#define astSetMeshSize(this,meshsize) astINVOKE(V,astSetMeshSize_(astCheckRegion(this),meshsize,STATUS_PTR)) -#define astTestMeshSize(this) astINVOKE(V,astTestMeshSize_(astCheckRegion(this),STATUS_PTR)) - -#define astClearClosed(this) astINVOKE(V,astClearClosed_(astCheckRegion(this),STATUS_PTR)) -#define astGetClosed(this) astINVOKE(V,astGetClosed_(astCheckRegion(this),STATUS_PTR)) -#define astSetClosed(this,closed) astINVOKE(V,astSetClosed_(astCheckRegion(this),closed,STATUS_PTR)) -#define astTestClosed(this) astINVOKE(V,astTestClosed_(astCheckRegion(this),STATUS_PTR)) - -#define astClearFillFactor(this) astINVOKE(V,astClearFillFactor_(astCheckRegion(this),STATUS_PTR)) -#define astGetFillFactor(this) astINVOKE(V,astGetFillFactor_(astCheckRegion(this),STATUS_PTR)) -#define astSetFillFactor(this,ff) astINVOKE(V,astSetFillFactor_(astCheckRegion(this),ff,STATUS_PTR)) -#define astTestFillFactor(this) astINVOKE(V,astTestFillFactor_(astCheckRegion(this),STATUS_PTR)) - -#else /* Public only */ -#define astMapRegion(this,map,frame) astINVOKE(O,astMapRegionId_(astCheckRegion(this),astCheckMapping(map),astCheckFrame(frame),STATUS_PTR)) -#endif - -#endif - - - - - diff --git a/ast/selectfc b/ast/selectfc deleted file mode 100755 index abf0dc7..0000000 --- a/ast/selectfc +++ /dev/null @@ -1,29 +0,0 @@ -#! /usr/bin/env perl - - $key = "c"; - $select = 1; - -# Read switches. - while ( $_ = $ARGV[0], /^-/ ) { - shift; - last if /^--$/; - if ( /^-f/ ) { $key = "f" }; - } - -# Read input lines. - line: while (<>) { - -# Detect start of prologue and initialise prologue text. - if ( /^[fc]\+ *$/ ) { - $select = 0; - if ( /^$key\+ *$/o ) { $select = 1; } - next line; - } - -# Detect end of prologue. - if ( /^[fc]- *$/ ) { $select = 1; next line } - -# Process the prologue contents. - if ( $select ) { print; } - - } diff --git a/ast/selectormap.c b/ast/selectormap.c deleted file mode 100644 index 87a6f45..0000000 --- a/ast/selectormap.c +++ /dev/null @@ -1,1838 +0,0 @@ -/* -*class++ -* Name: -* SelectorMap - -* Purpose: -* A Mapping that locates positions within one of a set of alternate -* Regions. - -* Constructor Function: -c astSelectorMap -f AST_SELECTORMAP - -* Description: -* A SelectorMap is a Mapping that identifies which Region contains -* a given input position. -* -* A SelectorMap encapsulates a number of Regions that all have the same -* number of axes and represent the same coordinate Frame. The number of -* inputs (Nin attribute) of the SelectorMap equals the number of axes -* spanned by one of the encapsulated Region. All SelectorMaps have only -* a single output. SelectorMaps do not define an inverse transformation. -* -* For each input position, the forward transformation of a SelectorMap -* searches through the encapsulated Regions (in the order supplied when -* the SelectorMap was created) until a Region is found which contains -* the input position. The index associated with this Region is -* returned as the SelectorMap output value (the index value is the -* position of the Region within the list of Regions supplied when the -* SelectorMap was created, starting at 1 for the first Region). If an -* input position is not contained within any Region, a value of zero is -* returned by the forward transformation. -* -* If a compound Mapping contains a SelectorMap in series with its own -* inverse, the combination of the two adjacent SelectorMaps will be -* replaced by a UnitMap when the compound Mapping is simplified using -c astSimplify. -f AST_SIMPLIFY. -* -* In practice, SelectorMaps are often used in conjunction with SwitchMaps. - -* Inheritance: -* The SelectorMap class inherits from the Mapping class. - -* Attributes: -* The SelectorMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c The SelectorMap class does not define any new functions beyond those -f The SelectorMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 15-MAR-2006 (DSB): -* Original version. -* 18-MAY-2006 (DSB): -* - Change logic for detecting interior points in function Transform. -* - Added BADVAL to contructor argument list. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS SelectorMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ -#include "unitmap.h" /* Unit Mappings */ -#include "channel.h" /* I/O channels */ -#include "selectormap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(SelectorMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SelectorMap,Class_Init) -#define class_vtab astGLOBAL(SelectorMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSelectorMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSelectorMap *astSelectorMapId_( int, void **, double, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetObjSize( AstObject *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two SelectorMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "selectormap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* SelectorMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two SelectorMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a SelectorMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the SelectorMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSelectorMap *that; - AstSelectorMap *this; - int i; - int nin; - int nreg; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two SelectorMap structures. */ - this = (AstSelectorMap *) this_object; - that = (AstSelectorMap *) that_object; - -/* Check the second object is a SelectorMap. We know the first is a - SelectorMap since we have arrived at this implementation of the virtual - function. */ - if( astIsASelectorMap( that ) ) { - -/* Check they have the same number of inputs. */ - nin = astGetNin( this ); - if( astGetNin( that ) == nin ) { - -/* Check they contain the same number of Regions, and have the same badval. */ - nreg = this->nreg; - if( that->nreg == nreg || - astEQUAL( that->badval, this->badval) ) { - -/* Loop over the Regions, breaking as soon as two unequal Regions are - found. */ - result = 1; - for( i = 0; i < nreg; i++ ) { - if( !astEqual( this->reg[ i ], that->reg[ i ] ) ) { - result = 0; - break; - } - } - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "selectormap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* SelectorMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied SelectorMap, -* in bytes. - -* Parameters: -* this -* Pointer to the SelectorMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSelectorMap *this; - int i; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the SelectorMap structure. */ - this = (AstSelectorMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - for( i = 0; i < this->nreg; i++ ) { - result += astGetObjSize( this->reg[ i ] ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -void astInitSelectorMapVtab_( AstSelectorMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSelectorMapVtab - -* Purpose: -* Initialise a virtual function table for a SelectorMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "selectormap.h" -* void astInitSelectorMapVtab( AstSelectorMapVtab *vtab, const char *name ) - -* Class Membership: -* SelectorMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SelectorMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASelectorMap) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -/* None. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "SelectorMap", "Region identification Mapping" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* SelectorMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstSelectorMap *this; /* Pointer to SelectorMap structure */ - int i; /* Loop count */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the SelectorMap structure. */ - this = (AstSelectorMap *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - for( i = 0; i < this->nreg; i++ ) { - if( !result ) result = astManageLock( this->reg[ i ], mode, extra, fail ); - } - - return result; - -} -#endif - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a SelectorMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* SelectorMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated SelectorMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated SelectorMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated SelectorMap which is to be merged with -* its neighbours. This should be a cloned copy of the SelectorMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* SelectorMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated SelectorMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *new; - AstRegion **sreg; - AstSelectorMap *map; - AstSelectorMap *slneb; - int equal; - int i; - int ilo; - int nreg; - int result; - int simp; - -/* Initialise.*/ - result = -1; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Get a pointer to this SelectorMap, and note the number of Regions. */ - map = (AstSelectorMap *) this; - nreg = map->nreg; - -/* Attempt to simplify the SelectorMap on its own. */ -/* ============================================= */ - -/* Try to simplify each of the encapsulated Regions, noting if any - simplification takes place. */ - simp = 0; - sreg = astMalloc( sizeof( AstRegion * )*nreg ); - if( astOK ) { - for( i = 0; i < nreg; i++ ) { - sreg[ i ] = astSimplify( map->reg[ i ] ); - simp = simp || ( sreg[ i ] != map->reg[ i ] ); - } - -/* If any simplification took place, construct a new SelectorMap from these - simplified Mappings. */ - if( simp ) { - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) astSelectorMap( nreg, - (void **) sreg, - map->badval, "", status ); - result = where; - } - -/* Release resources. */ - if( sreg ) { - for( i = 0; i < nreg; i++ ) sreg[ i ] = astAnnul( sreg[ i ] ); - sreg = astFree( sreg ); - } - } - -/* If possible, merge the SelectorMap with a neighbouring SelectorMap. */ -/* =============================================================== */ -/* Only do this if no change was made above, and we are combining the - Mappings in series. */ - if( result == -1 && series ) { - -/* Is the higher neighbour a SelectorMap? If so get a pointer to it, and - note the index of the lower of the two adjacent SelectorMaps. */ - if( where < ( *nmap - 1 ) && - astIsASelectorMap( ( *map_list )[ where + 1 ] ) ){ - slneb = (AstSelectorMap *) ( *map_list )[ where + 1 ]; - ilo = where; - -/* If not, is the lower neighbour a SelectorMap? If so get a pointer to it, and - note the index of the lower of the two adjacent SelectorMaps. */ - } else if( where > 0 && - astIsASelectorMap( ( *map_list )[ where - 1 ] ) ){ - slneb = (AstSelectorMap *) ( *map_list )[ where - 1 ]; - ilo = where - 1; - - } else { - slneb = NULL; - } - -/* If a neighbouring SelectorMap was found, we can replace the pair by a - UnitMap if the two SelectorMaps are equal but have opposite values for - their Invert flags. Temporarily invert the neighbour, then compare - the two SelectorMaps for equality, then re-invert the neighbour. */ - if( slneb ) { - astInvert( slneb ); - equal = astEqual( map, slneb ); - astInvert( slneb ); - -/* If the two SelectorMaps are equal but opposite, annul the first of the two - Mappings, and replace it with a UnitMap. Also set the invert flag. */ - if( equal ) { - new = (AstMapping *) astUnitMap( astGetNin( ( *map_list )[ ilo ] ), "", status ); - (void) astAnnul( ( *map_list )[ ilo ] ); - ( *map_list )[ ilo ] = new; - ( *invert_list )[ ilo ] = 0; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ ilo + 1 ] ); - for ( i = ilo + 2; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = where; - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a SelectorMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "selectormap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* SelectorMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a SelectorMap and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required Mapping. -* This implies applying each of the SelectorMap's component Mappings in turn, -* either in series or in parallel. - -* Parameters: -* this -* Pointer to the SelectorMap. -* in -* Pointer to the PointSet associated with the input coordinate values. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the SelectorMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *ps1; - AstPointSet *ps2; - AstPointSet *result; - AstPointSet *tps; - AstRegion *reg; - AstSelectorMap *map; - double **ptr_out; - double **ptr1; - double **ptr2; - double **tptr; - double *p2; - double *pout; - double badval; - int bad; - int closed; - int icoord; - int ipoint; - int ireg; - int ncoord; - int npoint; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the SelectorMap. */ - map = (AstSelectorMap *) this; - -/* Apply the parent Mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We now extend the parent astTransform method by applying the component - Mappings of the SelectorMap to generate the output coordinate values. */ - -/* Check we are implementing the original forward transformation (the - inverse transformation is not defined). */ - if( forward != astGetInvert( this ) ) { - -/* Get the number of input axes and the number of points. */ - ncoord = astGetNcoord( in ); - npoint = astGetNpoint( in ); - -/* Create two temporary PointSets to hold copies of the input points. */ - ps1 = astCopy( in ); - ptr1 = astGetPoints( ps1 ); - ps2 = astPointSet( npoint, ncoord, "", status ); - ptr2 = astGetPoints( ps2 ); - -/* Get a pointer to the output data */ - ptr_out = astGetPoints( result ); - if( astOK ) { - -/* Initialise the output array to hold -1 at any points that have - bad input axis values, and zero at all other points. */ - pout = ptr_out[ 0 ]; - for( ipoint = 0; ipoint < npoint; ipoint++ ) { - bad = 0; - for( icoord = 0; icoord < ncoord; icoord++ ) { - if( ptr1[ icoord ][ ipoint ] == AST__BAD ) { - bad = 1; - break; - } - } - *(pout++) = bad ? -1 : 0; - } - -/* Loop round all Regions. */ - for( ireg = 1; ireg <= map->nreg; ireg++ ) { - reg = map->reg[ ireg - 1 ]; - -/* Temporarily Negate the Region. */ - astNegate( reg ); - closed = astGetClosed( reg ); - astSetClosed( reg, !closed ); - -/* Transform the remaining input positions. Good input positions which - are within the Region will be bad in the output. */ - ps2 = astTransform( reg, ps1, 1, ps2 ); - -/* Loop round all positions. */ - p2 = ptr2[ 0 ]; - pout = ptr_out[ 0 ]; - for( ipoint = 0; ipoint < npoint; ipoint++, p2++, pout++ ) { - -/* Any position that has not already been assigned to a Region and is bad - in the output PointSet must be contained within the current Region, so - assign the (one-based) index of the current Region to the output element. */ - if( *pout == 0 && *p2 == AST__BAD ) *pout = ireg; - } - -/* Negate the Region to get it back to its original state. */ - astSetClosed( reg, closed ); - astNegate( reg ); - -/* Swap the input and output PointSets. */ - tps = ps1; - ps1 = ps2; - ps2 = tps; - tptr = ptr1; - ptr1 = ptr2; - ptr2 = tptr; - } - -/* Replace -1 values in the output (that indicate that the input position - had at least one bad axis value) with the "badval".*/ - badval = map->badval; - pout = ptr_out[ 0 ]; - for( ipoint = 0; ipoint < npoint; ipoint++, pout++ ) { - if( *pout == -1 ) *pout = badval; - } - } - -/* Free resources. */ - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - } - -/* If an error occurred, clean up by deleting the output PointSet (if - allocated by this function) and setting a NULL result pointer. */ - if ( !astOK ) { - if ( !out ) result = astDelete( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for SelectorMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for SelectorMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the -* Regions within the SelectorMap. -*/ - -/* Local Variables: */ - AstSelectorMap *in; /* Pointer to input SelectorMap */ - AstSelectorMap *out; /* Pointer to output SelectorMap */ - int i; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output SelectorMaps. */ - in = (AstSelectorMap *) objin; - out = (AstSelectorMap *) objout; - -/* For safety, start by clearing any references to the input Regions. */ - out->reg = NULL; - out->nreg = 0; - -/* Make copies of the Regions, and store pointers to them in the output - SelectorMap structure. */ - out->reg = astMalloc( sizeof( AstRegion * )*( in->nreg ) ); - if( astOK ) { - for( i = 0; i < in->nreg; i++ ) { - out->reg[ i ] = astCopy( in->reg[ i ] ); - } - out->nreg = in->nreg; - } - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for SelectorMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for SelectorMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstSelectorMap *this; /* Pointer to SelectorMap */ - int i; - -/* Obtain a pointer to the SelectorMap structure. */ - this = (AstSelectorMap *) obj; - -/* Free dynamically allocated resources. */ - for( i = 0; i < this->nreg; i++ ) { - this->reg[ i ] = astAnnul( this->reg[ i ] ); - } - this->reg = astFree( this->reg ); - -/* Clear the remaining SelectorMap variables. */ - this->nreg = 0; -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SelectorMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the SelectorMap class to an output Channel. - -* Parameters: -* this -* Pointer to the SelectorMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSelectorMap *this; - int i; - char buf[ 20 ]; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SelectorMap structure. */ - this = (AstSelectorMap *) this_object; - -/* Write out values representing the instance variables for the SelectorMap - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Loop to dump each Region. */ -/* ------------------------- */ -/* The coordinate Frame of the Regions is defined by the first Region. - The Frame information is omitted from the second and subsequent - Regions by setting the protected RegionFS attribute to zero. */ - for( i = 0; i < this->nreg; i++ ) { - sprintf( buf, "Reg%d", i + 1 ); - if( i > 0 ) astSetRegionFS( this->reg[ i ], 0 ); - astWriteObject( channel, buf, 1, 1, this->reg[ i ], - "Region of input space" ); - if( i > 0 ) astClearRegionFS( this->reg[ i ] ); - } - -/* BadVal. */ -/* ------- */ - if( this->badval != AST__BAD ) { - astWriteDouble( channel, "BadVal", 1, 1, this->badval, - "Output value for bad input positions" ); - } - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASelectorMap and astCheckSelectorMap functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SelectorMap,Mapping) -astMAKE_CHECK(SelectorMap) - -AstSelectorMap *astSelectorMap_( int nreg, void **regs_void, double badval, - const char *options, int *status, ...) { -/* -*+ -* Name: -* astSelectorMap - -* Purpose: -* Create a SelectorMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "selectormap.h" -* AstSelectorMap *astSelectorMap( int nreg, AstRegion **regs, -* double badval, const char *options, ... ) - -* Class Membership: -* SelectorMap constructor. - -* Description: -* This function creates a new SelectorMap and optionally initialises its -* attributes. - -* Parameters: -* nreg -* The number of Regions supplied. -* regs -* An array of pointers to the Regions. Deep copies of these -* Regions are taken. -* badval -* The value to be returned by the forward transformation of the -* SelectorMap for any input positions that have a bad (AST__BAD) -* value on any axis. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new SelectorMap. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new SelectorMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic SelectorMap constructor which is -* available via the protected interface to the SelectorMap class. A -* public interface is provided by the astSelectorMapId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "map1" and "map2" parameters are of type (void *) and are -* converted and validated within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSelectorMap *new; /* Pointer to new SelectorMap */ - AstRegion **regs; /* Array of Region pointers */ - int i; /* Region index */ - va_list args; /* Variable argument list */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Report an error if no Regions have been supplied. */ - if( nreg <= 0 ) astError( AST__BDPAR, "astSelectorMap(SelectorMap): " - "Bad number of Regions (%d) specified.", status, nreg ); - -/* Otherwise create an array to hold the Region pointers. */ - regs = astMalloc( sizeof( AstRegion * )*nreg ); - -/* Obtain and validate pointers to the Region structures provided. */ - if( astOK ) { - for( i = 0; i < nreg; i++ ) { - regs[ i ] = astCheckRegion( regs_void[ i ] ); - } - } - - if ( astOK ) { - -/* Initialise the SelectorMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSelectorMap( NULL, sizeof( AstSelectorMap ), !class_init, &class_vtab, - "SelectorMap", nreg, regs, badval ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new SelectorMap's - attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Free memory used to hold the Regions pointers. */ - regs = astFree( regs ); - -/* Return a pointer to the new SelectorMap. */ - return new; -} - -AstSelectorMap *astSelectorMapId_( int nreg, void **regs_void, double badval, - const char *options, ... ) { -/* -*++ -* Name: -c astSelectorMap -f AST_SELECTORMAP - -* Purpose: -* Create a SelectorMap. - -* Type: -* Public function. - -* Synopsis: -c #include "selectormap.h" -c AstSelectorMap *astSelectorMap( int nreg, AstRegion *regs[], -c double badval, const char *options, ... ) -f RESULT = AST_SELECTORMAP( NREG, REGS, BADVAL, OPTIONS, STATUS ) - -* Class Membership: -* SelectorMap constructor. - -* Description: -* This function creates a new SelectorMap and optionally initialises -* its attributes. -* -* A SelectorMap is a Mapping that identifies which Region contains -* a given input position. -* -* A SelectorMap encapsulates a number of Regions that all have the same -* number of axes and represent the same coordinate Frame. The number of -* inputs (Nin attribute) of the SelectorMap equals the number of axes -* spanned by one of the encapsulated Region. All SelectorMaps have only -* a single output. SelectorMaps do not define an inverse transformation. -* -* For each input position, the forward transformation of a SelectorMap -* searches through the encapsulated Regions (in the order supplied when -* the SelectorMap was created) until a Region is found which contains -* the input position. The index associated with this Region is -* returned as the SelectorMap output value (the index value is the -* position of the Region within the list of Regions supplied when the -* SelectorMap was created, starting at 1 for the first Region). If an -* input position is not contained within any Region, a value of zero is -* returned by the forward transformation. -* -* If a compound Mapping contains a SelectorMap in series with its own -* inverse, the combination of the two adjacent SelectorMaps will be -* replaced by a UnitMap when the compound Mapping is simplified using -c astSimplify. -f AST_SIMPLIFY. -* -* In practice, SelectorMaps are often used in conjunction with SwitchMaps. - -* Parameters: -c nreg -f NREG = INTEGER (Given) -* The number of supplied Regions. -c regs -f REGS( NREG ) = INTEGER (Given) -* An array of pointers to the Regions. All the supplied Regions must -* relate to the same coordinate Frame. The number of axes in this -* coordinate Frame defines the number of inputs for the SelectorMap. -c badval -f BADVAL = DOUBLE PRECISION (Given) -* The value to be returned by the forward transformation of the -* SelectorMap for any input positions that have a bad (AST__BAD) -* value on any axis. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new SelectorMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new SelectorMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSelectorMap() -f AST_SELECTORMAP = INTEGER -* A pointer to the new SelectorMap. - -* Notes: -* - Deep copies are taken of the supplied Regions. This means that -* any subsequent changes made to the component Regions using the -* supplied pointers will have no effect on the SelectorMap. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astSelectorMap constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astSelectorMap_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "map1" and "map2" parameters -* are of type (void *) and are converted from an ID value to a -* pointer and validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astSelectorMap_ directly, so it must be a re-implementation -* of it in all respects, except for the conversions between IDs -* and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSelectorMap *new; /* Pointer to new SelectorMap */ - AstRegion **regs; /* Array of Region pointers */ - int i; /* Region index */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Report an error if no Regions have been supplied. */ - if( nreg <= 0 ) astError( AST__BDPAR, "astSelectorMap(SelectorMap): " - "Bad number of Regions (%d) specified.", status, nreg ); - -/* Create an array to hold the Region pointers. */ - regs = astMalloc( sizeof( AstRegion * )*nreg ); - -/* Obtain and validate pointers to the Region structures provided. */ - if( astOK ) { - for( i = 0; i < nreg; i++ ) { - regs[ i ] = astVerifyRegion( astMakePointer(regs_void[ i ]) ); - } - } - - if ( astOK ) { - -/* Initialise the SelectorMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSelectorMap( NULL, sizeof( AstSelectorMap ), !class_init, - &class_vtab, "SelectorMap", nreg, regs, - badval ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new SelectorMap's - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Free memory used to hold the Regions pointers. */ - regs = astFree( regs ); - -/* Return an ID value for the new SelectorMap. */ - return astMakeId( new ); -} - -AstSelectorMap *astInitSelectorMap_( void *mem, size_t size, int init, - AstSelectorMapVtab *vtab, const char *name, - int nreg, AstRegion **regs, double badval, int *status ) { -/* -*+ -* Name: -* astInitSelectorMap - -* Purpose: -* Initialise a SelectorMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "selectormap.h" -* AstSelectorMap *astInitSelectorMap( void *mem, size_t size, int init, -* AstSelectorMapVtab *vtab, const char *name, -* int nreg, AstRegion **regs, double badval ) - -* Class Membership: -* SelectorMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new SelectorMap object. It allocates memory (if necessary) to -* accommodate the SelectorMap plus any additional data associated with the -* derived class. It then initialises a SelectorMap structure at the start -* of this memory. If the "init" flag is set, it also initialises the -* contents of a virtual function table for a SelectorMap at the start of -* the memory passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SelectorMap is to be initialised. -* This must be of sufficient size to accommodate the SelectorMap data -* (sizeof(SelectorMap)) plus any data used by the derived class. If a -* value of NULL is given, this function will allocate the memory itself -* using the "size" parameter to determine its size. -* size -* The amount of memory used by the SelectorMap (plus derived class -* data). This will be used to allocate memory if a value of NULL is -* given for the "mem" parameter. This value is also stored in the -* SelectorMap structure, so a valid value must be supplied even if not -* required for allocating memory. -* init -* A logical flag indicating if the SelectorMap's virtual function table -* is to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new SelectorMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* nreg -* The number of Regions supplied. -* regs -* An array holdiong pointers to the Regions. Deep copies are taken -* of these Regions. -* badval -* The value to be returned by the forward transformation of the -* SelectorMap for any input positions that have a bad (AST__BAD) -* value on any axis. - -* Returned Value: -* A pointer to the new SelectorMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstFrame *f0; /* Frame from first Region */ - AstFrame *f1; /* Frame from current Region */ - AstSelectorMap *new; /* Pointer to new SelectorMap */ - int equal; /* Are Frames equal? */ - int i; /* Loop count */ - int nin; /* No. input coordinates for SelectorMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSelectorMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check that all Regions refer to the same Frame. */ - f0 = astRegFrame( regs[ 0 ] ); - for( i = 1; i < nreg; i++ ) { - f1 = astRegFrame( regs[ i ] ); - equal = astEqual( f1, f0 ); - f1 = astAnnul( f1 ); - - if( !equal ) { - if( astOK ) { - astError( AST__BADNI, "astInitSelectorMap(%s): Region " - "number %d does not refer to the same coordinate " - "Frame as the first Region.", status, name, i + 1 ); - } - } - } - - nin = astGetNin( regs[ 0 ] ); - f0 = astAnnul( f0 ); - -/* Initialise a Mapping structure (the parent class) as the first component - within the SelectorMap structure, allocating memory if necessary. Specify - the number of input and output coordinates and in which directions the - Mapping should be defined. */ - if ( astOK ) { - new = (AstSelectorMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, 1, 1, 0 ); - if ( astOK ) { - -/* Initialise the SelectorMap data. */ -/* -------------------------------- */ - -/* Create an array for the Region pointers. */ - new->reg = astMalloc( sizeof( AstRegion * )*nreg ); - -/* Store pointers to deep copies of the Regions. */ - if( astOK ) { - new->nreg = nreg; - for( i = 0; i < nreg; i++ ) { - new->reg[ i ] = astCopy( regs[ i ] ); - } - } else { - new->nreg = 0; - } - -/* Store other items */ - new->badval = badval; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new object. */ - return new; -} - -AstSelectorMap *astLoadSelectorMap_( void *mem, size_t size, - AstSelectorMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSelectorMap - -* Purpose: -* Load a SelectorMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "selectormap.h" -* AstSelectorMap *astLoadSelectorMap( void *mem, size_t size, -* AstSelectorMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* SelectorMap loader. - -* Description: -* This function is provided to load a new SelectorMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* SelectorMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a SelectorMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the SelectorMap is to be -* loaded. This must be of sufficient size to accommodate the -* SelectorMap data (sizeof(SelectorMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SelectorMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SelectorMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstSelectorMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SelectorMap. If this is NULL, a pointer to -* the (static) virtual function table for the SelectorMap class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "SelectorMap" is used instead. - -* Returned Value: -* A pointer to the new SelectorMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSelectorMap *new; - AstFrameSet *fs; - AstRegion *reg; - int i; - char buf[ 20 ]; - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SelectorMap. In this case the - SelectorMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSelectorMap ); - vtab = &class_vtab; - name = "SelectorMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSelectorMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built SelectorMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "SelectorMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - - -/* Loop to load each Region. */ -/* ------------------------- */ - new->reg = NULL; - i = 0; - fs = NULL; - while( astOK ) { - sprintf( buf, "reg%d", i + 1 ); - reg = astReadObject( channel, buf, NULL ); - if( reg ) { - new->reg = astGrow( new->reg, i + 1, sizeof( AstRegion *) ); - if( astOK ) { - new->reg[ i ] = reg; - -/* All but the first Region may have a dummy FrameSet rather than the - correct FrameSet. The correct FrameSet will be a copy of the FrameSet - from the first Region. */ - if( i == 0 ) { - fs = astGetRegFS( reg ); - } else if( astRegDummyFS( reg ) ){ - astSetRegFS( reg, fs ); - } - - i++; - } - } else { - break; - } - } - - fs = astAnnul( fs ); - -/* Number of Regions. */ - new->nreg = i; - - -/* BadVal. */ -/* ------- */ - new->badval = astReadDouble( channel, "badval", AST__BAD ); - -/* If an error occurred, clean up by deleting the new SelectorMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new SelectorMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -/* None. */ - - - - diff --git a/ast/selectormap.h b/ast/selectormap.h deleted file mode 100644 index 36d83a5..0000000 --- a/ast/selectormap.h +++ /dev/null @@ -1,277 +0,0 @@ -#if !defined( SELECTORMAP_INCLUDED ) /* Include this file only once */ -#define SELECTORMAP_INCLUDED -/* -*+ -* Name: -* selectormap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the SelectorMap class. - -* Invocation: -* #include "selectormap.h" - -* Description: -* This include file defines the interface to the SelectorMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. - -* Inheritance: -* The SelectorMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astMapMerge -* Merge a SelectorMap within a sequence of Mappings. -* astTransform -* Transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsASelectorMap -* Test class membership. -* astSelectorMap -* Create a SelectorMap. -* -* Protected: -* astCheckSelectorMap -* Validate class membership. -* astInitSelectorMap -* Initialise a SelectorMap. -* astInitSelectorMapVtab -* Initialise the virtual function table for the SelectorMap class. -* astLoadSelectorMap -* Load a SelectorMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstSelectorMap -* SelectorMap object type. -* -* Protected: -* AstSelectorMapVtab -* SelectorMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 13-MAR-2006 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ -#include "region.h" /* Coordinate Regions (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* SelectorMap structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstSelectorMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int nreg; /* The number of Regions in the SelectorMap */ - AstRegion **reg; /* Array of Region pointers */ - double badval; /* Output value for positions with bad axis values */ - -} AstSelectorMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstSelectorMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -/* None. */ -} AstSelectorMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstSelectorMapGlobals { - AstSelectorMapVtab Class_Vtab; - int Class_Init; -} AstSelectorMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitSelectorMapGlobals_( AstSelectorMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(SelectorMap) /* Check class membership */ -astPROTO_ISA(SelectorMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstSelectorMap *astSelectorMap_( int, void **, double, const char *, int *, ...); -#else -AstSelectorMap *astSelectorMapId_( int, void **, double, const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstSelectorMap *astInitSelectorMap_( void *, size_t, int, AstSelectorMapVtab *, - const char *, int, AstRegion **, double, int * ); - -/* Vtab initialiser. */ -void astInitSelectorMapVtab_( AstSelectorMapVtab *, const char *, int * ); - -/* Loader. */ -AstSelectorMap *astLoadSelectorMap_( void *, size_t, AstSelectorMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -/* None. */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckSelectorMap(this) astINVOKE_CHECK(SelectorMap,this,0) -#define astVerifySelectorMap(this) astINVOKE_CHECK(SelectorMap,this,1) - -/* Test class membership. */ -#define astIsASelectorMap(this) astINVOKE_ISA(SelectorMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astSelectorMap astINVOKE(F,astSelectorMap_) -#else -#define astSelectorMap astINVOKE(F,astSelectorMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitSelectorMap(mem,size,init,vtab,name,nreg,regs,badval) \ -astINVOKE(O,astInitSelectorMap_(mem,size,init,vtab,name,nreg,regs,badval,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitSelectorMapVtab(vtab,name) astINVOKE(V,astInitSelectorMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadSelectorMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadSelectorMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckSelectorMap to validate SelectorMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -/* None. */ -#endif - - - - - diff --git a/ast/series.pdf b/ast/series.pdf deleted file mode 100644 index 71d8624..0000000 Binary files a/ast/series.pdf and /dev/null differ diff --git a/ast/shiftmap.c b/ast/shiftmap.c deleted file mode 100644 index eed6e1d..0000000 --- a/ast/shiftmap.c +++ /dev/null @@ -1,1617 +0,0 @@ -/* -*class++ -* Name: -* ShiftMap - -* Purpose: -* Add a constant value to each coordinate. - -* Constructor Function: -c astShiftMap -f AST_SHIFTMAP - -* Description: -* A ShiftMap is a linear Mapping which shifts each axis by a -* specified constant value. - -* Inheritance: -* The ShiftMap class inherits from the Mapping class. - -* Attributes: -* The ShiftMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c The ShiftMap class does not define any new functions beyond those -f The ShiftMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David Berry (Starlink) - -* History: -* 15-AUG-2003 (DSB): -* Original version. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 10-MAY-2006 (DSB): -* Override astEqual. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS ShiftMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "matrixmap.h" /* Linear mappings */ -#include "unitmap.h" /* Unit mappings */ -#include "zoommap.h" /* Zoom mappings */ -#include "permmap.h" /* Axis permutations */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "winmap.h" /* Window mappings */ -#include "shiftmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(ShiftMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(ShiftMap,Class_Init) -#define class_vtab astGLOBAL(ShiftMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstShiftMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstShiftMap *astShiftMapId_( int, const double [], const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ - -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int GetObjSize( AstObject *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetIsLinear( AstMapping *, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); - -/* Member functions. */ -/* ================= */ - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two ShiftMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "shiftmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* ShiftMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two ShiftMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a ShiftMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the ShiftMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstShiftMap *that; - AstShiftMap *this; - int i; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two ShiftMap structures. */ - this = (AstShiftMap *) this_object; - that = (AstShiftMap *) that_object; - -/* Check the second object is a ShiftMap. We know the first is a - ShiftMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAShiftMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two ShiftMaps differ, it may still be possible - for them to be equivalent. First compare the ShiftMaps if their Invert - flags are the same. In this case all the attributes of the two ShiftMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - result = 1; - for( i = 0; i < nin; i++ ) { - if( !astEQUAL( this->shift[ i ], that->shift[ i ] ) ) { - result = 0; - break; - } - } - -/* If the Invert flags for the two ShiftMaps differ, the attributes of the two - ShiftMaps must be inversely related to each other. */ - } else { - - result = 1; - for( i = 0; i < nin; i++ ) { - if( !astEQUAL( this->shift[ i ], -(that->shift[ i ] ) ) ) { - result = 0; - break; - } - } - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetIsLinear( AstMapping *this_mapping, int *status ){ -/* -* Name: -* GetIsLinear - -* Purpose: -* Return the value of the IsLinear attribute for a ShiftMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GetIsLinear( AstMapping *this, int *status ) - -* Class Membership: -* ShiftMap member function (over-rides the protected astGetIsLinear -* method inherited from the Mapping class). - -* Description: -* This function returns the value of the IsLinear attribute for a -* Frame, which is always one. - -* Parameters: -* this -* Pointer to the ShiftMap. -* status -* Pointer to the inherited status variable. -*/ - return 1; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "shiftmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* ShiftMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied ShiftMap, -* in bytes. - -* Parameters: -* this -* Pointer to the ShiftMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstShiftMap *this; /* Pointer to ShiftMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the ShiftMap structure. */ - this = (AstShiftMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astTSizeOf( this->shift ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -void astInitShiftMapVtab_( AstShiftMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitShiftMapVtab - -* Purpose: -* Initialise a virtual function table for a ShiftMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "shiftmap.h" -* void astInitShiftMapVtab( AstShiftMapVtab *vtab, const char *name ) - -* Class Membership: -* ShiftMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the ShiftMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAShiftMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - mapping->Rate = Rate; - mapping->MapSplit = MapSplit; - mapping->GetIsLinear = GetIsLinear; - -/* Declare the class dump, copy and delete functions.*/ - astSetDump( vtab, Dump, "ShiftMap", "Shift each coordinate axis" ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - astSetDelete( (AstObjectVtab *) vtab, Delete ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a ShiftMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* ShiftMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated ShiftMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated ShiftMap with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated ShiftMap which is to be merged with -* its neighbours. This should be a cloned copy of the ShiftMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* ShiftMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated ShiftMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstWinMap *w1; /* Pointer to replacement Mapping */ - AstShiftMap *sm; /* Pointer to this ShiftMap */ - double *aa; /* Pointer to shift terms for new WinMap */ - double *bb; /* Pointer to scale terms for new WinMap */ - int i; /* Axis count */ - int nin; /* Number of axes */ - int result; /* Returned value */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* A ShiftMap is equivalent to a WinMap with unit scaling. The policy on - simplifying a ShiftMap is to convert it to the equivalent WinMap and let - the WinMap class do the simplifying. Create the returned WinMap, initially - with undefined corners. */ - nin = astGetNin( this ); - w1 = astWinMap( nin, NULL, NULL, NULL, NULL, "", status ); - -/* If succesful, store the scale and shift terms in the WinMap. The scale - terms are unity. */ - if( astOK ){ - sm = (AstShiftMap *) this; - - bb = w1->b; - aa = w1->a; - for( i = 0; i < nin; i++ ) { - *(bb++) = 1.0; - *(aa++) = ( *invert_list )[ where ] ? -(sm->shift)[ i ] : (sm->shift)[ i ]; - } - -/* Replace the supplied ShiftMap with the new WinMap and reset the invert - flag. */ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) w1; - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - } - -/* Return the result. */ - return result; -} - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* ShiftMap. - -* Type: -* Private function. - -* Synopsis: -* #include "shiftmap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* ShiftMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing ShiftMap. This is only possible if the specified inputs -* correspond to some subset of the ShiftMap outputs. That is, there -* must exist a subset of the ShiftMap outputs for which each output -* depends only on the selected ShiftMap inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied ShiftMap, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the ShiftMap to be split (the ShiftMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied ShiftMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied ShiftMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied ShiftMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstShiftMap *newsm; /* Pointer to returned ShiftMap */ - AstShiftMap *this; /* Pointer to ShiftMap structure */ - int *result; /* Pointer to returned array */ - int i; /* Loop count */ - int iin; /* Mapping input index */ - int mnin; /* No. of Mapping inputs */ - int ok; /* Are input indices OK? */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the ShiftMap structure. */ - this = (AstShiftMap *) this_map; - -/* Allocate memory for the returned array and create a ShiftMap with the - required number of axes and initially unsorted shifts. */ - result = astMalloc( sizeof( int )*(size_t) nin ); - newsm = astShiftMap( nin, this->shift, "", status ); - *map = (AstMapping *) newsm; - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Store the required shifts in the new ShiftMap. At the same time check - that each axis is valid. */ - mnin = astGetNin( this ); - ok = 1; - for( i = 0; i < nin; i++ ) { - iin = in[ i ]; - if( iin >= 0 && iin < mnin ) { - (newsm->shift)[ i ] = (this->shift)[ iin ]; - result[ i ] = iin; - } else { - ok = 0; - break; - } - } - -/* If the "in" array contained any invalid values, free the returned - resources. */ - if( !ok ) { - result = astFree( result ); - *map = astAnnul( *map ); - -/* If the indices are good, invert the returned ShiftMap if the supplied - ShiftMap is inverted. */ - } else { - if( astGetInvert( this ) ) astInvert( *map ); - } - } - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "shiftmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* ShiftMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -*/ - - return ( ax1 == ax2 ) ? 1.0 : 0.0; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a ShiftMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "shiftmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* ShiftMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a ShiftMap and a set of points encapsulated in a -* PointSet and transforms the points so as to map them into the -* required window. - -* Parameters: -* this -* Pointer to the ShiftMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the ShiftMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstShiftMap *map; /* Pointer to ShiftMap to be applied */ - const char *class; /* Object class */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *axin; /* Pointer to next input axis value */ - double *axout; /* Pointer to next output axis value */ - double a; /* Shift for current axis */ - int coord; /* Loop counter for coordinates */ - int ncoord; /* Number of coordinates per point */ - int npoint; /* Number of points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the ShiftMap. */ - map = (AstShiftMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - ncoord = astGetNcoord( in ); - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse mapping, according to the - direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Report an error if the ShiftMap does not contain any shifts. */ - if( !map->shift && astOK ){ - class = astGetClass( this ); - astError( AST__BADSM, "astTransform(%s): The supplied %s does not " - "contain any shift information.", status, class, class ); - } - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if( astOK ){ - -/* Apply the mapping to each axis. */ - for( coord = 0; coord < ncoord; coord++ ){ - -/* Store pointers to the first input and output values on this axis. */ - axin = ptr_in[ coord ]; - axout = ptr_out[ coord ]; - -/* Get the value to add to each axis value. */ - a = (map->shift)[ coord ]; - -/* If the shift is bad store bad output values. */ - if( a == AST__BAD ){ - for( point = 0; point < npoint; point++ ) *(axout++) = AST__BAD; - -/* Otherwise, shift this axis, taking account of whether the mapping is - inverted or not. */ - } else { - if( !forward ) a = -a; - - for( point = 0; point < npoint; point++ ){ - if( *axin != AST__BAD ){ - *(axout++) = (*axin) + a; - } else { - *(axout++) = AST__BAD; - } - axin++; - } - } - } - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for ShiftMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for ShiftMap objects. - -* Parameters: -* objin -* Pointer to the ShiftMap to be copied. -* objout -* Pointer to the ShiftMap being constructed. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstShiftMap *out; /* Pointer to output ShiftMap */ - AstShiftMap *in; /* Pointer to input ShiftMap */ - int ncoord; /* No. of axes for the mapping */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the input and output ShiftMaps. */ - in= (AstShiftMap *) objin; - out = (AstShiftMap *) objout; - -/* Get the number of coordinates mapped by the ShiftMap. */ - ncoord = astGetNin( in ); - -/* Allocate memory holding copies of the shifts defining the mapping. */ - out->shift = (double *) astStore( NULL, (void *) in->shift, - sizeof(double)*(size_t)ncoord ); - -/* If an error occurred, free any allocated memory. */ - if ( !astOK ) { - out->shift = (double *) astFree( (void *) out->shift ); - } - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for ShiftMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for ShiftMap objects. - -* Parameters: -* obj -* Pointer to the ShiftMap to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This destructor does nothing and exists only to maintain a -* one-to-one correspondence between destructors and copy -* constructors. -*/ - -/* Local Variables: */ - AstShiftMap *this; /* Pointer to ShiftMap */ - -/* Obtain a pointer to the ShiftMap structure. */ - this = (AstShiftMap *) obj; - -/* Free the memory holding the shifts. */ - this->shift = (double *) astFree( (void *) this->shift ); - -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for ShiftMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the ShiftMap class to an output Channel. - -* Parameters: -* this -* Pointer to the ShiftMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define COMMENT_LEN 50 /* Maximum length of a comment string */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstShiftMap *this; /* Pointer to the ShiftMap structure */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment string */ - int axis; /* Axis index */ - int ncoord; /* No. of axes for mapping */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the ShiftMap structure. */ - this = (AstShiftMap *) this_object; - -/* Get the number of coordinates to be mapped. */ - ncoord = astGetNin( this ); - -/* Write out values representing the instance variables for the - ShiftMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* The shifts. */ - for( axis = 0; axis < ncoord; axis++ ){ - (void) sprintf( buff, "Sft%d", axis + 1 ); - (void) sprintf( comment, "Shift for axis %d", axis + 1 ); - astWriteDouble( channel, buff, (this->shift)[ axis ] != 0.0, 0, - (this->shift)[ axis ], comment ); - } - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAShiftMap and astCheckShiftMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(ShiftMap,Mapping) -astMAKE_CHECK(ShiftMap) - -AstShiftMap *astShiftMap_( int ncoord, const double shift[], const char *options, int *status, ...) { -/* -*++ -* Name: -c astShiftMap -f AST_SHIFTMAP - -* Purpose: -* Create a ShiftMap. - -* Type: -* Public function. - -* Synopsis: -c #include "shiftmap.h" -c AstShiftMap *astShiftMap( int ncoord, const double shift[], -c const char *options, ... ) -f RESULT = AST_SHIFTMAP( NCOORD, SHIFT, OPTIONS, STATUS ) - -* Class Membership: -* ShiftMap constructor. - -* Description: -* This function creates a new ShiftMap and optionally initialises its -* attributes. -* -* A ShiftMap is a linear Mapping which shifts each axis by a -* specified constant value. - -* Parameters: -c ncoord -f NCOORD = INTEGER (Given) -* The number of coordinate values for each point to be -* transformed (i.e. the number of dimensions of the space in -* which the points will reside). The same number is applicable -* to both input and output points. -c shift -f SHIFT( NCOORD ) = DOUBLE PRECISION (Given) -* An array containing the values to be added on to the input -* coordinates in order to create the output coordinates. A separate -* value should be supplied for each coordinate. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new ShiftMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new ShiftMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astShiftMap() -f AST_SHIFTMAP = INTEGER -* A pointer to the new ShiftMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstShiftMap *new; /* Pointer to new ShiftMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the ShiftMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitShiftMap( NULL, sizeof( AstShiftMap ), !class_init, &class_vtab, - "ShiftMap", ncoord, shift ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new ShiftMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new ShiftMap. */ - return new; -} - -AstShiftMap *astShiftMapId_( int ncoord, const double shift[], - const char *options, ... ) { -/* -* Name: -* astShiftMapId_ - -* Purpose: -* Create a ShiftMap. - -* Type: -* Private function. - -* Synopsis: -* #include "shiftmap.h" -* AstShiftMap *astShiftMapId_( int ncoord, const double shift[], -* const char *options, ... ) - -* Class Membership: -* ShiftMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astShiftMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astShiftMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astShiftMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astShiftMap_. - -* Returned Value: -* The ID value associated with the new ShiftMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstShiftMap *new; /* Pointer to new ShiftMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the ShiftMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitShiftMap( NULL, sizeof( AstShiftMap ), !class_init, &class_vtab, - "ShiftMap", ncoord, shift ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new ShiftMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new ShiftMap. */ - return astMakeId( new ); -} - -AstShiftMap *astInitShiftMap_( void *mem, size_t size, int init, - AstShiftMapVtab *vtab, const char *name, - int ncoord, const double *shift, int *status ) { -/* -*+ -* Name: -* astInitShiftMap - -* Purpose: -* Initialise a ShiftMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "shiftmap.h" -* AstShiftMap *astInitShiftMap( void *mem, size_t size, int init, -* AstShiftMapVtab *vtab, const char *name, -* int ncoord, const double *shift ) - -* Class Membership: -* ShiftMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new ShiftMap object. It allocates memory (if necessary) to accommodate -* the ShiftMap plus any additional data associated with the derived class. -* It then initialises a ShiftMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a ShiftMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the ShiftMap is to be initialised. -* This must be of sufficient size to accommodate the ShiftMap data -* (sizeof(ShiftMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the ShiftMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the ShiftMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the ShiftMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new ShiftMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* ncoord -* The number of coordinate values per point. -* shift -* Pointer to an array of shifts, one for each coordinate. - -* Returned Value: -* A pointer to the new ShiftMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstShiftMap *new; /* Pointer to new ShiftMap */ - int axis; /* Axis index */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitShiftMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a Mapping structure (the parent class) as the first component - within the ShiftMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstShiftMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - ncoord, ncoord, 1, 1 ); - - if ( astOK ) { - -/* Initialise the ShiftMap data. */ -/* ---------------------------- */ -/* Allocate memory to hold the shift for each axis. */ - new->shift = (double *) astMalloc( sizeof(double)*(size_t)ncoord ); - -/* Check the pointers can be used */ - if( astOK ){ - -/* Store the shift and scale for each axis. */ - for( axis = 0; axis < ncoord; axis++ ){ - (new->shift)[ axis ] = shift ? shift[ axis ] : AST__BAD; - } - - } - -/* If an error occurred, clean up by deleting the new ShiftMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new ShiftMap. */ - return new; -} - -AstShiftMap *astLoadShiftMap_( void *mem, size_t size, - AstShiftMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadShiftMap - -* Purpose: -* Load a ShiftMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "shiftmap.h" -* AstShiftMap *astLoadShiftMap( void *mem, size_t size, -* AstShiftMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* ShiftMap loader. - -* Description: -* This function is provided to load a new ShiftMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* ShiftMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a ShiftMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the ShiftMap is to be -* loaded. This must be of sufficient size to accommodate the -* ShiftMap data (sizeof(ShiftMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the ShiftMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the ShiftMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstShiftMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new ShiftMap. If this is NULL, a pointer -* to the (static) virtual function table for the ShiftMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "ShiftMap" is used instead. - -* Returned Value: -* A pointer to the new ShiftMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants. */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstShiftMap *new; /* Pointer to the new ShiftMap */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int axis; /* Axis index */ - int ncoord; /* The number of coordinate axes */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this ShiftMap. In this case the - ShiftMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstShiftMap ); - vtab = &class_vtab; - name = "ShiftMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitShiftMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built ShiftMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Get the number of axis for the mapping. */ - ncoord = astGetNin( (AstMapping *) new ); - -/* Allocate memory to hold the shifts. */ - new->shift = (double *) astMalloc( sizeof(double)*(size_t)ncoord ); - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "ShiftMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* The shifts. */ - for( axis = 0; axis < ncoord; axis++ ){ - (void) sprintf( buff, "sft%d", axis + 1 ); - (new->shift)[ axis ] = astReadDouble( channel, buff, 0.0 ); - } - } - -/* If an error occurred, clean up by deleting the new ShiftMap. */ - if ( !astOK ) new = astDelete( new ); - -/* Return the new ShiftMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - diff --git a/ast/shiftmap.h b/ast/shiftmap.h deleted file mode 100644 index a9b1346..0000000 --- a/ast/shiftmap.h +++ /dev/null @@ -1,290 +0,0 @@ -#if !defined( SHIFTMAP_INCLUDED ) /* Include this file only once */ -#define SHIFTMAP_INCLUDED -/* -*+ -* Name: -* shiftmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the ShiftMap class. - -* Invocation: -* #include "shiftmap.h" - -* Description: -* This include file defines the interface to the ShiftMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The ShiftMap class implements Mappings which shift each coordinate -* by a fixed amount. - -* Inheritance: -* The ShiftMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* ClearAttrib -* Clear an attribute value for a ShiftMap. -* GetAttrib -* Get an attribute value for a ShiftMap. -* SetAttrib -* Set an attribute value for a ShiftMap. -* TestAttrib -* Test if an attribute value has been set for a ShiftMap. -* astMapMerge -* Simplify a sequence of Mappings containing a ShiftMap. -* astTransform -* Apply a ShiftMap to transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsAShiftMap -* Test class membership. -* astShiftMap -* Create a ShiftMap. -* -* Protected: -* astCheckShiftMap -* Validate class membership. -* astInitShiftMap -* Initialise a ShiftMap. -* astInitShiftMapVtab -* Initialise the virtual function table for the ShiftMap class. -* astLoadShiftMap -* Load a ShiftMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstShiftMap -* ShiftMap object type. -* -* Protected: -* AstShiftMapVtab -* ShiftMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 14-AUG-2003 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* ShiftMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstShiftMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *shift; /* Pointer to array of shifts */ - -} AstShiftMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstShiftMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - -} AstShiftMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstShiftMapGlobals { - AstShiftMapVtab Class_Vtab; - int Class_Init; -} AstShiftMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitShiftMapGlobals_( AstShiftMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(ShiftMap) /* Check class membership */ -astPROTO_ISA(ShiftMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstShiftMap *astShiftMap_( int, const double [], const char *, int *, ...); -#else -AstShiftMap *astShiftMapId_( int, const double [], const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstShiftMap *astInitShiftMap_( void *, size_t, int, AstShiftMapVtab *, - const char *, int, const double *, int * ); - -/* Vtab initialiser. */ -void astInitShiftMapVtab_( AstShiftMapVtab *, const char *, int * ); - -/* Loader. */ -AstShiftMap *astLoadShiftMap_( void *, size_t, AstShiftMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckShiftMap(this) astINVOKE_CHECK(ShiftMap,this,0) -#define astVerifyShiftMap(this) astINVOKE_CHECK(ShiftMap,this,1) - -/* Test class membership. */ -#define astIsAShiftMap(this) astINVOKE_ISA(ShiftMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astShiftMap astINVOKE(F,astShiftMap_) -#else -#define astShiftMap astINVOKE(F,astShiftMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define \ -astInitShiftMap(mem,size,init,vtab,name,ncoord,shift) \ -astINVOKE(O,astInitShiftMap_(mem,size,init,vtab,name,ncoord,shift,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitShiftMapVtab(vtab,name) astINVOKE(V,astInitShiftMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadShiftMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadShiftMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckShiftMap to validate ShiftMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#endif - -#endif - - - - - diff --git a/ast/simpexamp.pdf b/ast/simpexamp.pdf deleted file mode 100644 index b65f58e..0000000 Binary files a/ast/simpexamp.pdf and /dev/null differ diff --git a/ast/skyaxis.c b/ast/skyaxis.c deleted file mode 100644 index fd6d6f6..0000000 --- a/ast/skyaxis.c +++ /dev/null @@ -1,5150 +0,0 @@ -/* -*class++ -* Name: -* SkyAxis - -* Purpose: -* Store celestial axis information. - -* Constructor Function: -* None. - -* Description: -* The SkyAxis class is used to store information associated with a -* particular axis of a SkyFrame. It is used internally by the AST -* library and has no constructor function. You should encounter it -c only within textual output (e.g. from astWrite). -f only within textual output (e.g. from AST_WRITE). - -* Inheritance: -* The SkyAxis class inherits from the Axis class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2008 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: B.S. Berry (Starlink) - -* History: -* 1-MAR-1996 (RFWS): -* Original version. -* 19-APR-1996 (RFWS): -* Tidied up, etc. -* 8-MAY-1996 (RFWS): -* Remove leading minus sign from formatted HMS string if all -* fields are zero. -* 9-MAY-1996 (RFWS): -* Fixed bug in rounding of fractional parts of HMS strings and -* improved algorithm to cope gracefully with requests for -* excessive numbers of decimal places. -* 13-MAY-1996 (RFWS): -* Over-ride the astGetAxisDirection method so that a SkyAxis -* with the AsTime attribute set is displayed in reverse by -* default. -* 17-MAY-1996 (RFWS): -* Change AxisNorm to return a bad coordinate value if a bad -* value is given. -* 11-SEP-1996 (RFWS): -* Added AxisGap and DHmsGap (written by DSB). -* 26-FEB-1998 (RFWS): -* Over-ride the astAxisUnformat method. -* 6-MAR-1998 (RFWS): -* Add formatting options to omit degrees/hours field and change -* all affected functions. -* 10-AUG-2000 (DSB): -* Fixed bug in DHmsFormat which could cause (for instance) a formatted -* galactic longitude value of zero to be formated as "-0.-0". -* 29-AUG-2001 (DSB): -* Added AxisDistance and AxisOffset. -* 10-OCT-2002 (DSB): -* Over-ride the astGetAxisTop and astGetAxisBottom methods so that a -* SkyAxis with the IsLatitude attribute set is legal between plus -* and minus 90 degrees. -* 8-JAN-2003 (DSB): -* - Changed private InitVtab method to protected astInitSkyAxisVtab -* method. -* - Modify DHmsGap to avoid decimal gap "4" which produces things -* like "0.0 0.4 0.8 1.2 1.6 2.0" ("4" replaced by "5"). -* 24-JAN-2004 (DSB): -* o Added AxisFields. -* o Added 'g' format character which produces graphical separators. -* o Modified AxisAbbrev to use AxisFields so that delimiters which -* include digits can be recognised. -* 13-SEP-20904 (DSB): -* Modify AxisFields to correct usage of the "p" pointer in the -* case that the first and only field begins with a minus sign. -* 15-SEP-2004 (DSB): -* Modified ParseDHmsFormat so that the number of decimal places -* is specified by Digits if the given format string include a ".*" -* precision (e.g. "dms.*"). -* 18-MAR-2005 (DSB): -* Invoke methods inherited from parent Axis class if the format -* string starts with a '%' character. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 30-JUN-2006 (DSB): -* Guard against a null "str1" value in AxisAbbrev. -* 7-AUG-2007 (DSB): -* Added CentreZero attribute. -* 1-FEB-2008 (DSB): -* Modified AxisUnformat to allow the final numerical field to include -* an exponent. -* 13-OCT-2011 (DSB): -* Use tuning parameters to store graphical delimiters. -* 27-APR-2015 (DSB): -* Added InternalUNit attribute.. -* 26-OCT-2016 (DSB): -* Override astAxisNormValues. -* 7-NOV-2016 (DSB): -* Ensure astAxisNormValues ignores bad axis values. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to the header - files that define class interfaces that they should make "protected" - symbols available. */ -#define astCLASS SkyAxis - -/* Header files. */ -/* ============= */ -#include "ast_err.h" /* Error code definitions */ - -/* Interface definitions. */ -/* ---------------------- */ -#include "pal.h" /* SLALIB interface */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "pointset.h" /* Sets of points (for AST__BAD) */ -#include "axis.h" /* Axis (parent) class interface */ -#include "skyaxis.h" /* Interface definition for this class */ -#include "globals.h" /* Thread-safe global data access */ -#include "wcsmap.h" /* For constants */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static const char *(* parent_getaxislabel)( AstAxis *, int * ); -static const char *(* parent_getaxissymbol)( AstAxis *, int * ); -static const char *(* parent_getaxisunit)( AstAxis *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static int (*parent_getaxisdirection)( AstAxis *this, int * ); -static void (* parent_axisoverlay)( AstAxis *, AstAxis *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static double (*parent_getaxisbottom)( AstAxis *this, int * ); -static double (*parent_getaxistop)( AstAxis *this, int * ); -static const char *(* parent_axisformat)( AstAxis *, double, int * ); -static double (*parent_axisgap)( AstAxis *, double, int *, int * ); -static int (*parent_axisunformat)( AstAxis *, const char *, double *, int * ); -static int (*parent_axisfields)( AstAxis *, const char *, const char *, int, char **, int *, double *, int * ); - -/* Factors for converting between hours, degrees and radians. */ -static double hr2rad; -static double deg2rad; -static double pi; -static double piby2; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->DHmsFormat_Buff[ 0 ] = 0; \ - globals->DHmsUnit_Buff[ 0 ] = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->GetAxisFormat_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(SkyAxis) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SkyAxis,Class_Init) -#define class_vtab astGLOBAL(SkyAxis,Class_Vtab) -#define dhmsformat_buff astGLOBAL(SkyAxis,DHmsFormat_Buff) -#define dhmsunit_buff astGLOBAL(SkyAxis,DHmsUnit_Buff) -#define getattrib_buff astGLOBAL(SkyAxis,GetAttrib_Buff) -#define getaxisformat_buff astGLOBAL(SkyAxis,GetAxisFormat_Buff) - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char dhmsformat_buff[ AST__SKYAXIS_DHMSFORMAT_BUFF_LEN + 1 ]; -static char dhmsunit_buff[ AST__SKYAXIS_DHMSUNIT_BUFF_LEN + 1 ]; -static char getattrib_buff[ AST__SKYAXIS_GETATTRIB_BUFF_LEN + 1 ]; -static char getaxisformat_buff[ AST__SKYAXIS_GETAXISFORMAT_BUFF_LEN + 1 ]; - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSkyAxisVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#endif - - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSkyAxis *astSkyAxisId_( const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static const char *AxisAbbrev( AstAxis *, const char *, const char *, const char *, int * ); -static const char *AxisFormat( AstAxis *, double, int * ); -static int GetObjSize( AstObject *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetAxisFormat( AstAxis *, int * ); -static const char *GetAxisInternalUnit( AstAxis *, int * ); -static const char *GetAxisLabel( AstAxis *, int * ); -static const char *GetAxisSymbol( AstAxis *, int * ); -static const char *GetAxisUnit( AstAxis *, int * ); -static const char *DHmsFormat( const char *, int, double, int * ); -static const char *DHmsUnit( const char *, int, int, int * ); -static double AxisGap( AstAxis *, double, int *, int * ); -static double AxisDistance( AstAxis *, double, double, int * ); -static double AxisOffset( AstAxis *, double, double, int * ); -static double DHmsGap( const char *, int, double, int *, int * ); -static double GetAxisTop( AstAxis *, int * ); -static double GetAxisBottom( AstAxis *, int * ); -static int AxisIn( AstAxis *, double, double, double, int, int * ); -static int AxisFields( AstAxis *, const char *, const char *, int, char **, int *, double *, int * ); -static int AxisUnformat( AstAxis *, const char *, double *, int * ); -static int GetAxisAsTime( AstSkyAxis *, int * ); -static int GetAxisDirection( AstAxis *, int * ); -static int GetAxisIsLatitude( AstSkyAxis *, int * ); -static int GetAxisCentreZero( AstSkyAxis *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestAxisAsTime( AstSkyAxis *, int * ); -static int TestAxisFormat( AstAxis *, int * ); -static int TestAxisInternalUnit( AstAxis *, int * ); -static int TestAxisIsLatitude( AstSkyAxis *, int * ); -static int TestAxisCentreZero( AstSkyAxis *, int * ); -static void AxisNorm( AstAxis *, double *, int * ); -static void AxisNormValues( AstAxis *, int, int, double *, int * ); -static void AxisOverlay( AstAxis *, AstAxis *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearAxisAsTime( AstSkyAxis *, int * ); -static void ClearAxisFormat( AstAxis *, int * ); -static void ClearAxisIsLatitude( AstSkyAxis *, int * ); -static void ClearAxisCentreZero( AstSkyAxis *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void ParseDHmsFormat( const char *, int, char *, int *, int *, int *, int *, int *, int *, int *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetAxisAsTime( AstSkyAxis *, int, int * ); -static void SetAxisFormat( AstAxis *, const char *, int * ); -static void SetAxisIsLatitude( AstSkyAxis *, int, int * ); -static void SetAxisCentreZero( AstSkyAxis *, int, int * ); - -/* Member functions. */ -/* ================= */ -static const char *AxisAbbrev( AstAxis *this_axis, const char *fmt, - const char *str1, const char *str2, int *status ) { -/* -* Name: -* AxisAbbrev - -* Purpose: -* Abbreviate a formatted SkyAxis value by skipping leading fields. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* const char *AxisAbbrev( AstAxis *this, const char *fmt, -* const char *str1, const char *str2 ) - -* Class Membership: -* SkyAxis member function (over-rides the protected astAxisAbbrev -* method inherited from the Axis class). - -* Description: -* This function compares two SkyAxis values that have been -* formatted with the supplied format specifier (using astAxisFormat) -* and determines if they have any redundant leading fields (i.e. -* leading fields in common which can be suppressed when tabulating -* the values or plotting them on the axis of a graph). - -* Parameters: -* this -* Pointer to the SkyAxis. -* fmt -* Pointer to a constant null-terminated string containing the -* format specifier used to format the two values. -* str1 -* Pointer to a constant null-terminated string containing the -* first formatted value. If this is null, the returned pointer -* points to the start of the final field in str2. -* str2 -* Pointer to a constant null-terminated string containing the -* second formatted value. - -* Returned Value: -* A pointer into the "str2" string which locates the first -* character in the first field that differs between the two -* formatted values. -* -* If the two values have no leading fields in common, the returned -* value will point at the start of string "str2". If the two -* values are equal, it will point at the terminating null at the -* end of this string. - -* Notes: -* - A pointer to the start of "str2" will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -*/ - -/* Local Variables: */ - char *fld1[ 3 ]; /* Pointers to start of each field in str1 */ - char *fld2[ 3 ]; /* Pointers to start of each field in str2 */ - const char *result; /* Result pointer to return */ - int i; /* Loop counter for string fields */ - int nf1; /* Number of fields found in str1 */ - int nf2; /* Number of fields found in str2 */ - int nc1[ 3 ]; /* Length of each field in str1 */ - int nc2[ 3 ]; /* Length of each field in str2 */ - -/* Initialise. */ - result = str2; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Find the fields within the "str2" string. */ - nf2 = astAxisFields( this_axis, fmt, str2, 3, fld2, nc2, NULL ); - -/* If "str1" was not supplied, return a pointer to the final field in - "str2". */ - if( !str1 ) { - result = fld2[ nf2 - 1 ]; - -/* Otherwise, find the fields within the "str1" string. */ - } else { - nf1 = astAxisFields( this_axis, fmt, str1, 3, fld1, nc1, NULL ); - -/* Loop to inspect corresponding fields from each string. */ - for ( i = 0; i < nf1 && i < nf2; i++ ) { - -/* If the fields are different, break out of the loop. */ - if ( nc1[ i ] != nc2[ i ] || - strncmp( fld1[ i ], fld2[ i ], nc1[ i ] ) ) { - break; - -/* Otherwise, move the returned poitner on to point to the start of the - next field in str2. If we are already at the last field in str2, - return a pointer to the terminating null. */ - } else { - if ( i + 1 < nf2 ) { - result = fld2[ i + 1 ]; - } else { - result = strchr( str2, '\0' ); - } - } - } - } - -/* Return the result. */ - return result; -} - -static double AxisDistance( AstAxis *this_axis, double v1, double v2, int *status ) { -/* -* Name: -* AxisDistance - -* Purpose: -* Find the distance between two axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* AxisDistance( AstAxis *this, double v1, double v2 ) - -* Class Membership: -* SkyAxis member function (over-rides the protected astAxisDistance -* method inherited from the Axis class). - -* Description: -* This function returns a signed value representing the axis increment -* from axis value v1 to axis value v2. -* -* For a SkyAxis, the angular difference between the two supplied axis -* values is normalized into the range +PI to -PI. - -* Parameters: -* this -* Pointer to the SkyAxis. -* v1 -* The first axis value -* v2 -* The second axis value - -* Returned Value: -* The axis increment from v1 to v2. - -* Notes: -* - A value of AST__BAD is returned if either axis value is AST__BAD. -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - double result; /* Returned gap size */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check both axis values are OK, and form the returned increment, - normalizing it into the range +PI to -PI. */ - if( v1 != AST__BAD && v2 != AST__BAD ) result = palDrange( v2 - v1 ); - -/* Return the result. */ - return result; -} - -static int AxisFields( AstAxis *this_axis, const char *fmt, const char *str, - int maxfld, char **fields, int *nc, double *val, int *status ) { -/* -* Name: -* AxisFields - -* Purpose: -* Identify numerical fields within a formatted SkyAxis value. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* int AxisFields( AstAxis *this_axis, const char *fmt, const char *str, -* int maxfld, char **fields, int *nc, double *val ) - -* Class Membership: -* SkyAxis member function (over-rides the protected astAxisFields -* method inherited from the Axis class). - -* Description: -* This function identifies the numerical fields within a SkyAxis value -* that have been formatted using astAxisFormat. It assumes that the -* value was formatted using the supplied format string. It also -* returns the equivalent floating point value in radians. - -* Parameters: -* this -* Pointer to the SkyAxis. -* fmt -* Pointer to a constant null-terminated string containing the -* format used when creating "str". -* str -* Pointer to a constant null-terminated string containing the -* formatted value. -* maxfld -* The maximum number of fields to identify within "str". -* fields -* A pointer to an array of at least "maxfld" character pointers. -* Each element is returned holding a pointer to the start of the -* corresponding field in "str" (in the order in which they occur -* within "str"), or NULL if no corresponding field can be found. -* nc -* A pointer to an array of at least "maxfld" integers. Each -* element is returned holding the number of characters in the -* corresponding field, or zero if no corresponding field can be -* found. -* val -* Pointer to a location at which to store the radians value -* equivalent to the returned field values. If this is NULL, -* it is ignored. - -* Returned Value: -* The number of fields succesfully identified and returned. - -* Notes: -* - Leading and trailing spaces are ignored. -* - If the formatted value is not consistent with the supplied format -* string, then a value of zero will be returned, "fields" will be -* returned holding NULLs, "nc" will be returned holding zeros, and -* "val" is returned holding VAL__BAD. -* - Fields are counted from the start of the formatted string. If the -* string contains more than "maxfld" fields, then trailing fields are -* ignored. -* - If this function is invoked with the global error status set, or -* if it should fail for any reason, then a value of zero will be returned -* as the function value, and "fields", "nc" and "val" will be returned -* holding their supplied values - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char sep; /* Field separator character */ - char tbuf[50]; /* Buffer for terminator string */ - char *p; /* Pointer to next character */ - char *t; /* Pointer to start of terminator string */ - char *term; /* Pointer to terminator string */ - double dval; /* Value read from string */ - double value; /* Equivalent radians value */ - int as_time; /* Format the value as a time? */ - int dh; /* Hours field required? */ - int ifld; /* Field index */ - int lead_zero; /* Add leading zeros? */ - int min; /* Minutes field required? */ - int ndp; /* Number of decimal places */ - int ok; /* Value and format consistent? */ - int plus; /* Add leading plus sign? */ - int result; /* Result fields count to return */ - int sec; /* Seconds field required? */ - int sign; /* The sign of the radians value */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_axis); - -/* If the format string starts with a "%" call the method inherited from - the parent Axis class. */ - if( fmt[ 0 ] == '%' ) { - return (*parent_axisfields)( this_axis, fmt, str, maxfld, fields, nc, - val, status ); - } - -/* Initialise. */ - result = 0; - for( ifld = 0; ifld < maxfld; ifld++ ) { - fields[ ifld ] = NULL; - nc[ ifld ] = 0; - } - if( val ) *val = AST__BAD; - -/* Parse the format specifier. */ - ParseDHmsFormat( fmt, astGetAxisDigits( this_axis ), &sep, &plus, &lead_zero, - &as_time, &dh, &min, &sec, &ndp, status ); - -/* Only proceed if the format was parsed succesfully, and the supplied arrays - are not of zero size. */ - if( astOK && maxfld > 0 ) { - -/* Indicate that we have not yet found any inconsistency between the - formatted value and the forat string. */ - ok = 1; - -/* Variable "p" points to the next character to be read from the - formatted string. Initialise it to point to the first non-space - character. */ - p = (char *) str; - while( *p == ' ' ) p++; - -/* Note the start of the first field. */ - fields[ 0 ] = p; - -/* If the first non-blank character is a + or - sign, skip it and note - the sign of the final value. */ - sign = 1; - if( *p == '-' ) { - sign = -1; - p++; - } else if( *p == '+' ) { - p++; - } - -/* Initialise the equivalent radian value. */ - value = 0.0; - -/* If the format string specifies a degrees or hours field, it should be - the first field. */ - if( dh ) { - -/* If the format indicates that fields are separated by characters, or if - there is a minutes or seconds field, then the first field should end with - the appropriate separator. In these cases locate the terminator,and - store the length of the first field. */ - if( sep == 'l' || sep == 'g' || min || sec ) { - - if( sep == 'l' ) { - term = as_time ? "h" : "d"; - - } else if( sep == 'g' ) { - astTuneC( as_time ? "hrdel":"dgdel", NULL, tbuf, - sizeof( tbuf ) ); - term = tbuf; - - } else { - tbuf[ 0 ] = sep; - tbuf[ 1 ] = '\0'; - term = tbuf; - } - - t = strstr( p, term ); - if( t ) { - nc[ 0 ] = t - fields[ 0 ]; - } else { - ok = 0; - } - -/* Move on to the first character following the terminator. */ - p = t + strlen( term ); - -/* In all other cases, the first field is the only field and is not - terminated. Note its length (ignoring trailing spaces). Move the - pointer on by the length of the field, remembering that any leading - minus sign has already been skipped. */ - } else { - nc[ 0 ] = astChrLen( fields[ 0 ] ); - p += nc[ result ]; - if( sign == -1 ) p--; - } - -/* Read a numerical value from the first field. */ - if( astSscanf( fields[ 0 ], "%lg", &dval ) ) { - value = fabs( dval ); - } else { - ok = 0; - } - -/* Increment then number of returned fields if OK */ - if( ok ) result++; - - } - -/* If the format string specifies a minutes field, it should be the next - field. */ - if( min && ok ) { - -/* Note the start of the next field. */ - fields[ result ] = p; - -/* If the format indicates that fields are separated by characters, or if - there is a seconds field, then this field should end with the appropriate - separator. In these cases locate the terminator,and store the length of - this field. */ - if( sep == 'l' || sep == 'g' || sec ) { - if( sep == 'l' ) { - term = "m"; - - } else if( sep == 'g' ) { - astTuneC( as_time ? "mndel":"amdel", NULL, tbuf, - sizeof( tbuf ) ); - term = tbuf; - - } else { - tbuf[ 0 ] = sep; - tbuf[ 1 ] = '\0'; - term = tbuf; - } - - t = strstr( p, term ); - if( t ) { - nc[ result ] = t - fields[ result ]; - } else { - ok = 0; - } - -/* Move on to the first character following the terminator. */ - p = t + strlen( term ); - -/* In all other cases, this field is not terminated. Note its length - (ignoring trailing spaces). */ - } else { - nc[ result ] = astChrLen( fields[ result ] ); - p += nc[ result ]; - } - -/* Read a numerical value from this field. */ - if( astSscanf( fields[ result ], "%lg", &dval ) ) { - value += dval/60.0; - } else { - ok = 0; - } - -/* Increment then number of returned fields if OK */ - if( ok ) result++; - - } - -/* If the format string specifies a seconds field, it should be the next - field. */ - if( sec && ok ) { - -/* Note the start of the next field. */ - fields[ result ] = p; - -/* If the format indicates that fields are separated by characters, then this - field should end with the appropriate separator. In this case locate the - terminator,and store the length of this field. */ - if( sep == 'l' || sep == 'g' ) { - if( sep == 'l' ) { - term = "s"; - } else { - astTuneC( as_time ? "scdel":"asdel", NULL, tbuf, - sizeof( tbuf ) ); - term = tbuf; - } - - t = strstr( p, term ); - if( t ) { - nc[ result ] = t - fields[ result ]; - } else { - ok = 0; - } - -/* Move on to the first character following the terminator. */ - p = t + strlen( term ); - -/* In all other cases, this field is not terminated. Note its length - (ignoring trailing spaces). */ - } else { - nc[ result ] = astChrLen( fields[ result ] ); - p += nc[ result ]; - } - -/* Read a numerical value from this field. */ - if( astSscanf( fields[ result ], "%lg", &dval ) ) { - value += dval/3600.0; - } else { - ok = 0; - } - -/* Increment then number of returned fields if OK */ - if( ok ) result++; - - } - -/* Check that nothing is left.*/ - if( astChrLen( p ) > 0 ) ok = 0; - -/* If OK, convert the axis value to radians. */ - if( ok ) { - if( val ) { - *val = sign*value*( as_time ? hr2rad : deg2rad ); - } - -/* Otherwise, return zero. */ - } else { - result = 0; - for( ifld = 0; ifld < maxfld; ifld++ ) { - fields[ ifld ] = NULL; - nc[ ifld ] = 0; - } - } - } - -/* Return the result. */ - return result; -} - -static const char *AxisFormat( AstAxis *this_axis, double value, int *status ) { -/* -* Name: -* AxisFormat - -* Purpose: -* Format a coordinate value for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* const char *AxisFormat( AstAxis *this, double value, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astAxisFormat method inherited -* from the Axis class). - -* Description: -* This function returns a pointer to a string containing the formatted -* (character) version of a coordinate value for a SkyAxis. The formatting -* applied is that specified by a previous invocation of the -* astSetAxisFormat method. A suitable default format is applied if -* necessary. - -* Parameters: -* this -* Pointer to the SkyAxis. -* value -* The coordinate value to be formatted (in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a null-terminated string containing the formatted value. - -* Notes: -* - The returned string pointer may point at memory allocated within -* the SkyAxis object, or at static memory. The contents of the string may -* be over-written or the pointer may become invalid following a further -* invocation of the same function or deletion of the SkyAxis. A copy of the -* string should therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - const char *fmt; /* Pointer to format specifier */ - const char *result; /* Pointer to result string */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise. */ - result = NULL; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Obtain a pointer to the format specifier to be used. Note we use a private - member function to obtain this (not a method) in case derived classes have - extended the syntax of this string. */ - fmt = GetAxisFormat( this_axis, status ); - -/* If the format string starts with a percent, use the AxisFormat method - inherited from the parent Axis class. Otherwise, format using the - syntax of this class. */ - if ( astOK ) { - if( fmt[ 0 ] == '%' ) { - result = (*parent_axisformat)( this_axis, value, status ); - } else { - result = DHmsFormat( fmt, astGetAxisDigits( this ), value, status ); - } - } - -/* Return the result. */ - return result; -} - -static double AxisGap( AstAxis *this_axis, double gap, int *ntick, int *status ) { -/* -* Name: -* AxisGap - -* Purpose: -* Find a "nice" gap for tabulating SkyAxis values. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* double AxisGap( AstAxis *this, double gap, int *ntick, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the protected astAxisGap -* method inherited from the Axis class). - -* Description: -* This function returns a gap size in radians which produces a -* nicely spaced series of formatted SkyAxis values, the returned -* gap size being as close as possible to the supplied target gap -* size. It also returns a convenient number of divisions into -* which the gap can be divided. - -* Parameters: -* this -* Pointer to the SkyAxis. -* gap -* The target gap size. -* ntick -* Address of an int in which to return a convenient number of -* divisions into which the gap can be divided. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The nice gap size. - -* Notes: -* - The returned gap size is influenced by the format string -* specified for the SkyAxis by a previous invocation of the -* astSetAxisFormat method. A suitable default format is used if -* necessary. -* - A value of zero is returned if the supplied gap size is zero. -* - A negative gap size is returned if the supplied gap size is negative. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - const char *fmt; /* Pointer to Format string */ - double result; /* Returned gap size */ - -/* Initialise. */ - result = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Obtain a pointer to the format string to be used. Note we use a - private member function to obtain this (not a method) in case - derived classes have extended the syntax of this string. */ - fmt = GetAxisFormat( this_axis, status ); - -/* Obtain the closest "nice" gap size. */ - if ( astOK ) result = DHmsGap( fmt, astGetAxisDigits( this ), gap, ntick, status ); - -/* If the format string starts with a percent, use the AxisGap method - inherited from the parent Axis class. Otherwise, use the method - provided by this class. */ - if ( astOK ) { - if( fmt[ 0 ] == '%' ) { - result = (*parent_axisgap)( this_axis, gap, ntick, status ); - } else { - result = DHmsGap( fmt, astGetAxisDigits( this ), gap, ntick, status ); - } - } - -/* Return the result. */ - return result; -} - -static int AxisIn( AstAxis *this, double lo, double hi, double val, int closed, int *status ){ -/* -* Name: -* AxisIn - -* Purpose: -* Test if an axis value lies within a given interval. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "skyaxis.h" -* int AxisIn( AstAxis *this, double lo, double hi, double val, int closed, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astAxisIn method inherited -* from the Axis class). - -* Description: -* This function returns non-zero if a given axis values lies within a -* given axis interval. -* -* The SkyAxis implementation of this method treats the supplied -* numerical values as non-cyclic (e.g. lo=10, hi = 350 implies that -* val = 180 is inside and zero is outside: lo = 10, hi = 400 would imply -* that all angles are inside: lo = -10, hi = 10 would imply that 180 is -* outside and zero is inside). But when testing a supplied value, adding -* or subtracting multiples of 2.PI from the supplied value will make no -* difference to whether the point is inside or outside). - -* Parameters: -* this -* Pointer to the Axis. -* lo -* The lower axis limit of the interval. -* hi -* The upper axis limit of the interval. -* val -* The axis value to be tested. -* closed -* If non-zero, then the lo and hi axis values are themselves -* considered to be within the interval. Otherwise they are outside. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the test value is inside the interval. - -*/ - -/* For speed, omit the astOK check since no pointers are being used. */ - -/* Deal with closed intervals. */ - if( closed ) { - -/* If the supplied value is greater than the upper limit, subtract 2.PI until - it is not. */ - while( val > hi ) val -= 2*pi; - -/* If the value is now less than the lower limit, add 2.PI until it is not. */ - while( val < lo ) val += 2*pi; - -/* The axis value is in the range if its numerical value is less than or - equal to the end value. */ - return ( val <= hi ); - -/* Now deal with open intervals. */ - } else { - -/* If the supplied value is greater than or equal to the upper limit, subtract - 2.PI until it is not. */ - while( val >= hi ) val -= 2*pi; - -/* If the value is now less than or equal to the lower limit, add 2.PI until - it is not. */ - while( val <= lo ) val += 2*pi; - -/* The axis value is in the range if its numerical value is less than the - end value. */ - return ( val < hi ); - } -} - -static void AxisNorm( AstAxis *this_axis, double *value, int *status ) { -/* -* Name: -* AxisNorm - -* Purpose: -* Normalise a SkyAxis coordinate value. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "skyaxis.h" -* void AxisNorm( AstAxis *this, double *value, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astAxisNorm method inherited -* from the Axis class). - -* Description: -* This function converts a SkyAxis coordinate value which might -* potentially be unsuitable for display to a user (for instance, -* may lie outside the expected range of values) into an acceptable -* alternative value suitable for display. -* -* For a SkyAxis that is a longitude axis, values are wrapped into -* the range zero to 2*pi, while for a latitude axis, they are -* wrapped into the range -pi to +pi. The astAxisCentreZero method -* is used to determine which algorithm to apply. - -* Parameters: -* this -* Pointer to the SkyAxis. -* value -* Pointer to the coordinate value to be normalised, which will -* be modified in place. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - int centrezero; /* SkyAxis range centred on zero? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* If the coordinate value is bad, then return it unchanged. Otherwise, - determine if the SkyAxis range is centred on zero or PI. */ - if ( *value != AST__BAD ) { - centrezero = astGetAxisCentreZero( this ); - -/* Wrap the value into the appropriate range. */ - if ( astOK ) *value = centrezero ? palDrange( *value ) : - palDranrm( *value ); - } -} - -static void AxisNormValues( AstAxis *this_axis, int oper, int nval, - double *values, int *status ){ -/* -* Name: -* astAxisNormValues - -* Purpose: -* Normalise an array of axis coordinate values. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "skyaxis.h" -* void astAxisNormValues( AstAxis *this, int oper, int nval, -* double *values ) - -* Class Membership: -* SkyAxis member function (over-rides the astAxisNormValues method -* inherited from the Axis class). - -* Description: -* This function modifies a supplied array of axis values so that -* they are normalised in the manner indicated by parameter "oper". -* -* For a SkyAxis, if "oper" is 0, longitude values are returned in -* the range [0,2*PI]. If "oper" is 1, longitude values are returned -* in either the range [0,2*PI] or [-PI,PI]. The choice is made so -* that the resulting list has the smallest range. Latitude values -* are always returned in the range [-PI,PI]. - -* Parameters: -* this -* Pointer to the Axis. -* oper -* Indicates the type of normalisation to be applied. If zero is -* supplied, the normalisation will be the same as that performed by -* function astAxisNorm. If 1 is supplied, the normalisation will be -* chosen automatically so that the resulting list has the smallest -* range. -* nval -* The number of points in the values array. -* values -* On entry, the axis values to be normalised. Modified on exit to -* hold the normalised values. - -* Notes: -* - Bad axis values, and axis values outside the range -1E6 to +1E6 -* radians (such as DBL_MAX and DBL_MIN) are returned unchanged. - -*/ - -/* Local macros */ -#define VAL_OK(v) ((v)!=AST__BAD&&fabs(v)<1.0E6) - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - double *pv; /* Pointer to next axis value */ - double hi; /* Max axis value after normalisation */ - double lo; /* Min axis value after normalisation */ - double mn1; /* Min value in range [-pi,0] */ - double mn2; /* Min value in range [0,pi] */ - double mn3; /* Min value in range [pi,2pi] */ - double mx1; /* Max value in range [-pi,0] */ - double mx2; /* Max value in range [0,pi] */ - double mx3; /* Max value in range [pi,2pi] */ - double range1; /* Range after normalising to [0,2*pi] */ - double range2; /* Range after normalising to [-pi,pi] */ - double twopi; /* Two PI */ - int centrezero; /* SkyAxis range centred on zero? */ - int i; /* Index of next axis value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Oper 0 - always normalise according to the value of the CentreZero - attribute (i.e. mimic AxisNorm). */ - if( oper == 0 ) { - -/* Determine if the SkyAxis range is centred on zero or PI. */ - centrezero = astGetAxisCentreZero( this ); - -/* Loop over axis values. */ - pv = values; - for( i = 0; i < nval; i++,pv++ ) { - -/* If the coordinate value is bad, or unusually large, then return it - unchanged. Otherwise, wrap the value into the appropriate range. */ - if( VAL_OK(*pv) ) *pv = centrezero ? palDrange( *pv ) : - palDranrm( *pv ); - } - -/* Oper 1 - choose a range that leaves most values unchanged. */ - } else if( oper == 1 ) { - -/* Normalise latitude axes into [-PI,+PI]. */ - if( astGetAxisIsLatitude( this ) ) { - pv = values; - for( i = 0; i < nval; i++,pv++ ) { - if( VAL_OK(*pv) ) *pv = palDrange( *pv ); - } - -/* Now deal with longitude axes. */ - } else { - -/* First ensure all values are in the range [-PI,2*PI] and find the max - and min value in each of the three ranges [-PI,0], [0,PI], [PI, 2PI]. */ - twopi = 2*AST__DPI; - mx1 = -DBL_MAX; - mn1 = DBL_MAX; - mx2 = -DBL_MAX; - mn2 = DBL_MAX; - mx3 = -DBL_MAX; - mn3 = DBL_MAX; - - pv = values; - for( i = 0; i < nval; i++,pv++ ) { - if( VAL_OK(*pv) ) { - while( *pv > twopi ) *pv -= twopi; - while( *pv < -AST__DPIBY2 ) *pv += twopi; - - if( *pv > AST__DPI ) { - mx3 = astMAX( mx3, *pv ); - mn3 = astMIN( mn3, *pv ); - } else if( *pv > 0 ) { - mx2 = astMAX( mx2, *pv ); - mn2 = astMIN( mn2, *pv ); - } else { - mx1 = astMAX( mx1, *pv ); - mn1 = astMIN( mn1, *pv ); - } - } - } - -/* What would the range be if we normalised into [0,2.PI] ? */ - if( mx1 != -DBL_MAX ) { - hi = astMAX( mx2, astMAX( mx1 + twopi, mx3) ); - lo = astMIN( mn2, astMIN( mn1 + twopi, mn3) ); - } else { - hi = astMAX( mx2, mx3 ); - lo = astMIN( mn2, mn3 ); - } - range1 = hi - lo; - -/* What would the range be if we normalised into [-PI,PI] ? */ - if( mn3 != -DBL_MAX ) { - hi = astMAX( mx2, astMAX( mx3 - twopi, mx1) ); - lo = astMIN( mn2, astMIN( mn3 - twopi, mn1) ); - } else { - hi = astMAX( mx2, mx1 ); - lo = astMIN( mn2, mn1 ); - } - range2 = hi - lo; - -/* If [-PI,PI] produces the smaller range, normalise into [-PI,PI]. */ - if( range2 < range1 ) { - pv = values; - for( i = 0; i < nval; i++,pv++ ) { - if( VAL_OK(*pv) ) *pv = palDrange( *pv ); - } - -/* Otherwise, normalise all into the range [0,2PI]. */ - } else { - pv = values; - for( i = 0; i < nval; i++,pv++ ) { - if( VAL_OK(*pv) ) *pv = palDranrm( *pv ); - } - } - } - -/* Report an error if the supplied operation is invalid. */ - } else if( astOK ) { - astError( AST__INTER, "astAxisNormValues: Invalid oper value %d " - "supplied (internal AST programming error).", status, oper ); - } - -#undef VAL_OK -} - -static double AxisOffset( AstAxis *this_axis, double v1, double dist, int *status ) { -/* -* -* Name: -* AxisOffset - -* Purpose: -* Add an increment onto a supplied axis value. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* AxisOffset( AstSkyAxis *this, double v1, double dist ) - -* Class Membership: -* SkyAxis member function (over-rides the protected astAxisOffset -* method inherited from the Axis class). - -* Description: -* This function returns an axis value formed by adding a signed axis -* increment onto a supplied axis value. -* -* For a SkyFrame, the result is normalized into the correct angular -* range (+PI to -PI for latitude axes, and 0 to 2*PI for longitude axes). - -* Parameters: -* this -* Pointer to the SkyAxis. -* v1 -* The supplied axis value -* dist -* The axis increment - -* Returned Value: -* The axis value which is the specified increment away from v1. - -* Notes: -* - A value of AST__BAD is returned if either axis value is AST__BAD. -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - double result; /* Returned gap size */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check both axis values are OK, and form the returned axis value. */ - if( v1 != AST__BAD && dist != AST__BAD ) { - result = v1 + dist; - AxisNorm( this_axis, &result, status ); - } - -/* Return the result. */ - return result; -} - -static void AxisOverlay( AstAxis *template_axis, AstAxis *result, int *status ) { -/* -* Name: -* AxisOverlay - -* Purpose: -* Overlay the attributes of a template SkyAxis on to another Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* void AxisOverlay( AstAxis *template, AstAxis *result, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astAxisOverlay method inherited -* from the Axis class). - -* Description: -* This function overlays attributes of a SkyAxis (the "template") on to -* another Axis, so as to over-ride selected attributes of that second -* Axis. Normally only those attributes which have been specifically set -* in the template will be transferred. This implements a form of -* defaulting, in which an Axis acquires attributes from the template, but -* retains its original attributes (as the default) if new values have not -* previously been explicitly set in the template. - -* Parameters: -* template -* Pointer to the template SkyAxis, for which values should have been -* explicitly set for any attribute which is to be transferred. -* result -* Pointer to the Axis which is to receive the new attribute values. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void -*/ - -/* Local Variables: */ - AstSkyAxis *template; /* Pointer to the SkyAxis structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the template SkyAxis structure. */ - template = (AstSkyAxis *) template_axis; - -/* Invoke the parent astAstOverlay method to overlay inherited attributes. */ - (*parent_axisoverlay)( template_axis, result, status ); - -/* Test if the "result" Axis is a SkyAxis (if not, it cannot acquire any - further attributes, so there is nothing more to do). */ - if ( astIsASkyAxis( result ) && astOK ) { - -/* Overlay the Format attribute if it is set in the template. Note that we - use private member functions (not methods) to access the Format value, since - derived classes may extend the syntax of this string and we should not - overlay a string whose syntax cannot be interpreted by the result Axis. */ - if ( TestAxisFormat( template_axis, status ) ) { - SetAxisFormat( result, GetAxisFormat( template_axis, status ), status ); - } - -/* Overlay the AsTime attribute in the same way, but this time using methods - to access it. */ - if ( astTestAxisAsTime( template ) ) { - astSetAxisAsTime( result, astGetAxisAsTime( template ) ); - } - -/* Also overlay the IsLatitude attribute. */ - if ( astTestAxisIsLatitude( template ) ) { - astSetAxisIsLatitude( result, astGetAxisIsLatitude( template ) ); - } - -/* Also overlay the CentreZero attribute. */ - if ( astTestAxisCentreZero( template ) ) { - astSetAxisCentreZero( result, astGetAxisCentreZero( template ) ); - } - } -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astClearAttrib protected -* method inherited from the Axis class). - -* Description: -* This function clears the value of a specified attribute for a -* SkyAxis, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the SkyAxis. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - -/* AsTime. */ -/* ------- */ - if ( !strcmp( attrib, "astime" ) ) { - astClearAxisAsTime( this ); - -/* IsLatitude. */ -/* ----------- */ - } else if ( !strcmp( attrib, "islatitude" ) ) { - astClearAxisIsLatitude( this ); - -/* CentreZero. */ -/* ----------- */ - } else if ( !strcmp( attrib, "centrezero" ) ) { - astClearAxisCentreZero( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearAxisFormat( AstAxis *this_axis, int *status ) { -/* -* Name: -* ClearAxisFormat - -* Purpose: -* Clear the Format attribute for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* void ClearAxisFormat( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astClearAxisFormat method -* inherited from the Axis class). - -* Description: -* This function clears the Format attribute of a SkyAxis, as if no value -* had ever been set for it. - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Free any memory allocated to hold the Format string and reset the string - pointer to NULL. */ - this->skyformat = astFree( this->skyformat ); -} - -static const char *DHmsFormat( const char *fmt, int digs, double value, int *status ) { -/* -* Name: -* DHmsFormat - -* Purpose: -* Format a value representing degrees/hours, minutes and seconds. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* const char *DHmsFormat( const char *fmt, int digs, double value, int *status ) - -* Class Membership: -* SkyAxis member function. - -* Description: -* This function formats a value representing an angle in radians -* into a text string giving degrees/hours, minutes and seconds -* according to a format specifier supplied. See the "Format -* Specifier" section for details of the formats available. - -* Parameters: -* fmt -* Pointer to a null terminated string containing the format -* specifier. -* digs -* The default number of digits of precision to use. This is used -* if the given format specifier indicates the number of decimal -* places to use with the string ".*". In this case, the number of -* decimal places produced will be chosen so that the total number -* of digits of precision is equal to "digs". -* double -* The value to be formatted (in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null terminated character string containing the -* formatted value. - -* Format Specifier: -* The format specifier supplied via the "fmt" parameter should -* contain zero or more of the following characters to specify the -* format required. These characters may occur in any order, but -* the following is recommended for clarity: -* -* '+' -* Indicates that a plus sign should be prefixed to positive -* values. By default, no plus sign is used. -* 'z' -* Indicates that leading zeros should be prefixed to the value -* so that the first field is always of constant width, as would -* be required in a fixed-width table. (Leading zeros are always -* prefixed to any fields that follow.) By default, no leading -* zeros are added. -* 'i' -* Use the standard ISO field separator (a colon) between -* fields. This is the default behaviour. -* 'b' -* Use a blank to separate fields. -* 'l' -* Use a letter ('d'/'h', 'm' or 's' as appropriate) to separate -* and identify fields. -* 'g' -* As 'l', but escape sequences are included in the returned -* character string which cause the separators ('h', 'd', 'm', etc) -* to be drawn as small super-scripts when plotted by the astText -* or astGrid. -* 'd' -* Express the value as an angle and include a degrees -* field. Expressing the value as an angle is also the default -* behaviour if neither 'h' nor 't' is given, and expressing it -* in degrees is the default if neither 'm' nor 's' is given. -* 'h' -* Express the value as a time instead of an angle (where 24 -* hours correspond to 360 degrees) and include an hours -* field. Expressing times in hours is the default if 't' is -* given without either 'm' or 's'. -* 'm' -* Include a minutes field. By default this is not included. -* 's' -* Include a seconds field. By default this is not -* included. This request is ignored if 'd' or 'h' is given, -* unless a minutes field is also included. -* 't' -* Express the value as a time instead of an angle (where 24 -* hours correspond to 360 degrees). This option is ignored if -* either 'd' or 'h' is given and is intended for use in cases -* where the value is to be expressed purely in minutes and/or -* seconds of time (no hours field). If 't' is given without -* 'd', 'h', 'm' or 's' being present, then it is equivalent to -* 'h'. -* '.' -* Indicates that decimal places are to be given for the final -* field in the formatted string (whichever field this is). The -* '.' should be followed immediately by a zero or positive integer -* which gives the number of decimal places required. The '.' may -* also be followed by asterisk (i.e. '.*') which causes the number -* of decimal places to be chosen so that the total number of digits -* is equal to the value of Digits. -* -* Format specifiers are not case sensitive. If several characters -* make conflicting requests (e.g. if both 'i' and 'l' appear in a -* format specifier), then the character occurring last takes -* precedence, except that 'd' and 'h' always override 't'. - -* Notes: -* - The result string may be stored in static memory. Its contents -* may be over-written or the returned pointer may become invalid -* following a further invocation of this function. A copy of the -* string should therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. - -* Acknowledgements: -* - This function is a close approximation to a Fortran 77 routine -* written by Clive Davenhall which implements the system of format -* specifiers for angles described in his document on the CAT -* catalogue access library (Starlink User Note 181). Some minor -* improvements have been made to ensure better behaviour when -* results are rounded to a specified number of decimal places. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char *term; /* Pointer to terminator string */ - char sep; /* Field separator character */ - char tbuf[50]; /* Buffer for terminator string */ - const char *result; /* Pointer to result string */ - double absvalue; /* Absolute value in radians */ - double fract; /* Fractional part of final field */ - double idh; /* Integer number of degrees/hours */ - double ifract; /* Fractional part expressed as an integer */ - double imin; /* Integer number of minutes */ - double isec; /* Integer number of seconds */ - double shift; /* Factor for rounding fractional part */ - double test; /* Test value to determine rounding */ - int as_time; /* Format the value as a time? */ - int dh; /* Degrees/hours field required? */ - int lead_zero; /* Add leading zeros? */ - int min; /* Minutes field required? */ - int ndp; /* Number of decimal places */ - int plus; /* Add leading plus sign? */ - int pos; /* Position to add next character */ - int positive; /* Value is positive (or zero)? */ - int sec; /* Seconds field required? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - result = NULL; - -/* Check if a bad coordinate value has been given and return an - appropriate string. */ - if ( value == AST__BAD ) { - result = ""; - -/* Otherwise... */ - } else { - -/* Parse the format specifier. */ - ParseDHmsFormat( fmt, digs, &sep, &plus, &lead_zero, - &as_time, &dh, &min, &sec, &ndp, status ); - -/* Break the value into fields. */ -/* ---------------------------- */ -/* Restrict the number of decimal places requested, if necessary, so - that under the worst case the buffer for the result string is not - likely to overflow. */ - if ( astOK ) { - if ( ( ndp + 11 ) > AST__SKYAXIS_DHMSFORMAT_BUFF_LEN ) ndp = AST__SKYAXIS_DHMSFORMAT_BUFF_LEN - 11; - -/* Some operating systems have a "minus zero" value (for instance - "-1.2*0" would give "-0"). This value is numerically equivalent to - zero, but is formated as "-0" instead of "0". The leading minus sign - confuses the following code, and so ensure now that all zero values - are the usual "+0". */ - if ( value == 0.0 ) value = 0.0; - -/* Determine if the value to be formatted is positive and obtain its - absolute value in radians. */ - positive = ( value >= 0.0 ); - absvalue = positive ? value : -value; - -/* Convert this to an absolute number of degrees or hours, as - required. */ - fract = absvalue / ( as_time ? hr2rad : deg2rad ); - -/* If a degrees/hours field is required, extract the whole number of - degrees/hours and the remaining fractional part of a - degree/hour. */ - idh = 0.0; - if ( dh ) fract = modf( fract, &idh ); - -/* If a minutes field is required, convert the value remaining to - minutes and extract the whole number of minutes and the remaining - fractional part of a minute. */ - imin = 0.0; - if ( min ) fract = modf( fract * 60.0, &imin ); - -/* If a seconds field is required, convert the value remaining to - seconds (allowing for the absence of a minutes field if necessary) - and extract the whole number of seconds and the remaining - fractional part of a second. */ - isec = 0.0; - if ( sec ) { - if ( !min ) fract *= 60.0; - fract = modf( fract * 60.0, &isec ); - } - -/* Round to the required number of decimal places. */ -/* ----------------------------------------------- */ -/* We must now round the fractional part (of whichever field) to the - required number of decimal places. Calculate the power of 10 that - brings the least significant digit into the units column. Scale the - fractional part by this factor and truncate to an integer (but - stored as a double to prevent possible integer overflow if the - number of decimal places is excessive). */ - shift = pow( 10.0, (double) ndp ); - ifract = floor( fract * shift ); - -/* Next we must determine if truncation was adequate, or whether we - should round upwards instead. This process is more subtle than it - seems because if a value with a 5 as the final digit is converted - to radians and then back again, it may no longer end in 5 (because - it cannot be represented exactly in radians) and so may round - either up or down. If we want to recover the original (textual) - value, we must compare the value we are formatting not with a test - value whose last digit is 5, but with the closest number to this - that can be represented exactly in radians. - - To do this, we add 0.5 to our truncated value, divide by the scale - factor (to get the truncated fractional part, but now with a - trailing digit 5 appended) and then combine this fractional part - with the value of all the other fields. Finally, we convert this - test value back into radians. */ - test = ( 0.5 + ifract ) / shift; - if ( sec ) test = ( isec + test ) / 60.0; - if ( min ) { - test = ( imin + test ) / 60.0; - } else if ( sec ) { - test /= 60.0; - } - if ( dh ) test += idh; - test *= ( as_time ? hr2rad : deg2rad ); - -/* We now compare the absolute value we are formatting with this test - value. If it is not smaller than it, we should have rounded up - instead of truncating the final digit of the fractional part, so - increment the integer representation of the truncated fractional - part by 1.0 to compensate. */ - if ( absvalue >= test ) ifract += 1.0; - -/* Divide by the scale factor to obtain the correctly rounded - fractional part. Then check if this fractional part is 1.0. If so, - rounding has caused it to overflow into the units column of the - final field, so clear the fractional part. */ - fract = ( ifract / shift ); - if ( fract >= 1.0 ) { - ifract = 0.0; - -/* If a seconds field is present, propagate the overflow up through - each field in turn, but omitting fields which are not required. Be - careful about possible rounding errors when comparing integer - values stored as double. */ - if ( sec ) { - isec += 1.0; - if ( ( floor( isec + 0.5 ) > 59.5 ) && min ) { - isec = 0.0; - imin += 1.0; - if ( ( floor( imin + 0.5 ) > 59.5 ) && dh ) { - imin = 0.0; - idh += 1.0; - } - } - -/* Omit the seconds field if it is not present. */ - } else if ( min ) { - imin += 1.0; - if ( ( floor( imin + 0.5 ) > 59.5 ) && dh ) { - imin = 0.0; - idh += 1.0; - } - -/* If only the degree/hour field is present, simply increment it. */ - } else { - idh += 1.0; - } - } - -/* Construct the result string. */ -/* ---------------------------- */ -/* We now have the value of each field and the information about how - they are to be formatted, so we can combine them into the required - string. */ - -/* If each field is either not required or equal to zero, disregard - any sign. */ - if ( !positive && ( !dh || floor( idh + 0.5 ) < 0.5 ) && - ( !min || floor( imin + 0.5 ) < 0.5 ) && - ( !sec || floor( isec + 0.5 ) < 0.5 ) && - ( floor( ifract + 0.5 ) < 0.5 ) ) { - positive = 1; - } - -/* Use "pos" to identify where the next character should be - added. Insert a leading '+' or '-' sign if required. */ - pos = 0; - if ( !positive ) { - dhmsformat_buff[ pos++ ] = '-'; - } else if ( plus ) { - dhmsformat_buff[ pos++ ] = '+'; - } - -/* Use "sprintf" to format the degrees/hours field, if required. Set - the minimum field width according to whether padding with leading - zeros is required and whether the value represents hours (2 digits) - or degrees (3 digits). */ - if ( dh ) { - pos += sprintf( dhmsformat_buff + pos, "%0*.0f", - lead_zero ? ( as_time ? 2 : 3 ) : 1, idh ); - -/* If letters are being used as field separators, and there are more - fields to follow, append "d" or "h" as necessary. */ - if ( min || sec ) { - if ( sep == 'l' ) { - dhmsformat_buff[ pos++ ] = ( as_time ? 'h' : 'd' ); - } else if( sep == 'g' ) { - astTuneC( as_time ? "hrdel":"dgdel", NULL, tbuf, - sizeof( tbuf ) ); - term = tbuf; - pos += sprintf( dhmsformat_buff + pos, "%s", term ); - } - } - } - -/* If a minutes field is required, first add an appropriate non-letter - field separator if needed. */ - if ( min ) { - if ( ( sep != 'l' && sep != 'g' ) && dh ) dhmsformat_buff[ pos++ ] = sep; - -/* Then format the minutes field with a leading zero to make it two - digits if necessary. */ - pos += sprintf( dhmsformat_buff + pos, "%0*.0f", ( dh || lead_zero ) ? 2 : 1, - imin ); - -/* If letters are being used as field separators, and there is another - field to follow, append the separator. */ - if ( sec ) { - if ( sep == 'l' ) { - dhmsformat_buff[ pos++ ] = 'm'; - } else if( sep == 'g' ) { - astTuneC( as_time ? "mndel":"amdel", NULL, tbuf, - sizeof( tbuf ) ); - term = tbuf; - pos += sprintf( dhmsformat_buff + pos, "%s", term ); - } - } - } - -/* Similarly, if a seconds field is required, first add an appropriate - non-letter field separator if needed. */ - if ( sec ) { - if ( ( sep != 'l' && sep != 'g' ) && ( dh || min ) ) dhmsformat_buff[ pos++ ] = sep; - -/* Then format the seconds field with a leading zero to make it two - digits if necessary. */ - pos += sprintf( dhmsformat_buff + pos, "%0*.0f", - ( dh || min || lead_zero ) ? 2 : 1, isec ); - } - -/* If decimal places are needed, add a decimal point followed by the - integer representation of the correctly rounded fractional part, - padded with leading zeros if necessary. */ - if ( ndp > 0 ) { - dhmsformat_buff[ pos++ ] = '.'; - pos += sprintf( dhmsformat_buff + pos, "%0*.0f", ndp, ifract ); - } - -/* If letters are being used as separators, append the appropriate one - to the final field. */ - if ( sep == 'l' ) { - dhmsformat_buff[ pos++ ] = ( sec ? 's' : ( min ? 'm' : - ( as_time ? 'h' : 'd' ) ) ); - } else if ( sep == 'g' ) { - astTuneC( as_time ? ( sec ? "scdel" : ( min ? "mndel" : "hrdel" ) ) : - ( sec ? "asdel" : ( min ? "amdel" : "dgdel" ) ), - NULL, tbuf, sizeof( tbuf ) ); - term = tbuf; - pos += sprintf( dhmsformat_buff + pos, "%s", term ); - } - -/* Terminate the result string and return a pointer to it. */ - dhmsformat_buff[ pos ] = '\0'; - result = dhmsformat_buff; - } - } - -/* Return the result. */ - return result; -} - -static double DHmsGap( const char *fmt, int digs, double gap, int *ntick, int *status ) { -/* -* Name: -* DHmsGap - -* Purpose: -* Find a "nice" gap for formatted SkyAxis values. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* double DHmsGap( const char *fmt, int digs, double gap, int *ntick, int *status ) - -* Class Membership: -* SkyAxis member function. - -* Description: -* This function returns a gap size in radians which produces a -* nicely spaced series of formatted SkyAxis values, the returned -* gap size being as close as possible to the supplied target gap -* size. It also returns a convenient number of divisions into -* which the gap can be divided. - -* Parameters: -* fmt -* Pointer to a constant null-terminated string containing the -* format specifier which will be used to format the SkyAxis -* values. -* digs -* The default number of digits of precision to use. This is used -* if the given format specifier indicates the number of decimal -* places to use with the string ".*". In this case, the number of -* decimal places produced will be chosen so that the total number -* of digits of precision is equal to "digs". -* gap -* The target gap size. -* ntick -* Address of an int in which to return a convenient number of -* divisions into which the gap can be divided. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The nice gap size. - -* Notes: -* - A value of zero is returned if the target gap size is zero. -* - A negative gap size is returned if the supplied gap size is -* negative. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Constants: */ -#define BUFF_LEN 50 /* Length of character buffer */ - -/* Local Variables: */ - char buff[ BUFF_LEN + 1 ]; /* Buffer for formatted scaled "nice" value */ - char sep; /* Field separator character */ - const double *table; /* Pointer to nice gap table */ - const int *nticks; /* Pointer to number of subdivisions table */ - double field_value[ 3 ]; /* Formatted field values in radians */ - double scale; /* Power of ten scaling factor */ - double scaled_table_value; /* Scaled "nice" value to test against */ - int as_time; /* Format the value as a time? */ - int decimal; /* Use nice decimal gap value? */ - int dh; /* Degrees/hours field required? */ - int field; /* ID of most significant formatted field */ - int i; /* Look-up-table index */ - int iter; /* Iteration count */ - int lead_zero; /* Add leading zeros? */ - int min; /* Minutes field required? */ - int ndp; /* Number of decimal places */ - int plus; /* Add leading plus sign? */ - int positive; /* Value is positive (or zero)? */ - int sec; /* Seconds field required? */ - -/* Local Data: */ -/* ----------- */ -/* Table of nice decimal gaps. */ - const double dec_table[] = { 1.0, 2.0, 5.0, 5.0, 10.0, -1.0 }; - const int dec_nticks[] = { 5, 4, 5, 5, 5 }; - -/* Table of nice degrees gaps. */ - const double deg_table[] = - { 1.0, 2.0, 5.0, 10.0, 30.0, 45.0, 60.0, 90.0, 180.0, 360.0, -1.0 }; - const int deg_nticks[] = - { 4, 4, 5, 5, 6, 3, 6, 3, 3, 4 }; - -/* Table of nice hours gaps. */ - const double hr_table[] = { 1.0, 2.0, 3.0, 6.0, 12.0, 24.0, -1.0 }; - const int hr_nticks[] = { 4, 4, 6, 6, 4, 4 }; - -/* Table of nice minutes or seconds gaps. */ - const double minsec_table[] = { 1.0, 2.0, 5.0, 10.0, 30.0, 60.0, -1.0 }; - const int minsec_nticks[] = { 4, 4, 5, 5, 6, 4 }; - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Check that the supplied gap size is not zero. */ - if ( gap != 0.0 ) { - -/* Parse the format specifier. */ - ParseDHmsFormat( fmt, digs, &sep, &plus, &lead_zero, &as_time, &dh, &min, - &sec, &ndp, status ); - -/* If OK, calculate the value of each formatted field in radians. */ - if ( astOK ) { - field_value[ 0 ] = ( as_time ? hr2rad : deg2rad ); - field_value[ 1 ] = field_value[ 0 ] / 60.0; - field_value[ 2 ] = field_value[ 0 ] / 3600.0; - -/* Determine if the suggested gap size is positive and obtain its - absolute value. */ - positive = ( gap >= 0.0 ); - if ( !positive ) gap = -gap; - -/* Perform two iterations to determine the optimum gap value. This is - because the method of choosing the gap value depends on the initial - value. If a nice decimal gap is chosen on the first iteration, - this may round the suggested gap value downwards, making it - preferable to choose the gap value using a different method on the - second iteration. */ - for ( iter = 0; iter < 2; iter++ ) { - -/* Decide which is the most significant field that the suggested gap - value will occupy when formatted. Also decide whether to use a - special "nice" gap value specific to that field, or simply to use a - generic nice decimal gap value. Perform all tests on the gap size - in radians, so as to avoid any rounding problems from conversion - into degrees/hours, minutes or seconds. */ - decimal = 0; - -/* Suggested values exceeding one degree/hour. */ -/* ------------------------------------------- */ - if ( gap > field_value[ 0 ] ) { - -/* If a degree/hour field is present, use a special gap value, unless - the suggested value exceeds the normal range of this field (in - which case use a decimal gap). */ - if ( dh ) { - field = 1; - decimal = ( gap > ( field_value[ 0 ] * - ( as_time ? 24.0 : 360.0 ) ) ); - -/* If the most significant field is not degrees/hours, then its normal - range will be exceeded, so use a decimal gap. */ - } else if ( min ) { - field = 2; - decimal = 1; - } else { - field = 3; - decimal = 1; - } - -/* Suggested values exceeding one minute. */ -/* -------------------------------------- */ - } else if ( gap > field_value[ 1 ] ) { - -/* If a minutes field is present, the suggested value will lie within - its normal range, so use a special gap value. */ - if ( min ) { - field = 2; - -/* Otherwise, if the most significant field is seconds, its normal - range will be exceeded, so use a decimal gap value. */ - } else if ( sec ) { - field = 3; - decimal = 1; - -/* If only a degrees/hours field is present, then only digits after - the decimal point can be affected, so use a decimal gap value. */ - } else { - field = 1; - decimal = 1; - } - -/* Suggested values exceeding one second. */ -/* -------------------------------------- */ - } else if ( gap > field_value[ 2 ] ) { - -/* If a seconds field is present, the suggested value will lie within - its normal range, so use a special gap value. */ - if ( sec ) { - field = 3; - -/* If the least significant field is degrees/hours or minutes, then - only digits after the decimal point can be affected, so use a - decimal gap value. */ - } else if ( min ) { - field = 2; - decimal = 1; - } else { - field = 1; - decimal = 1; - } - -/* Suggested values less than one second. */ -/* -------------------------------------- */ - } else { - -/* Only digits after the decimal point can be affected, so decide - which is the least significant field present and use a decimal - gap. */ - if ( sec ) { - field = 3; - } else if ( min ) { - field = 2; - } else { - field = 1; - } - decimal = 1; - } - -/* If a decimal gap value is required, select the appropriate table of - gap values and numbers of subdivisions. */ - if ( decimal ) { - table = dec_table; - nticks = dec_nticks; - -/* Find a power of ten divisor which scales the suggested value (when - formatted) into the range 1.0 to 10.0. */ - scale = pow( 10.0, - floor( log10( gap / field_value[ field - 1 ] ) ) ); - -/* Look the scaled value up in the table, comparing values in radians - to avoid rounding problems due to conversion to/from - degrees/radians, etc. */ - for ( i = 0; table[ i + 1 ] > 0.0; i++ ) { - -/* We must be careful about rounding errors here. If, for example, we - read in a value of 0.15 as the suggested gap value, the scaled - "nice" value we would be comparing it with would be 0.1 times the - values in the nice values table. The relevant value in this table - is 1.5 (i.e. 0.5 * ( 1.0 + 2.0 ) ), so we would compute 0.1 * 1.5 - as the test value. However, this is probably not equal (to machine - precision) to the number that results when a formatted value of - 0.15 is read, because 0.1 isn't exactly representable. Since it is - the formatted appearance of the numbers which matters, we want a - new scaled nice table containing the numbers that result from - reading the formatted values 0.1, 0.2, etc. To achieve this effect, - we format the scaled table value using the default floating point - precision (which rounds to a relatively small number of decimal - digits) and then read the value back again. */ - (void ) sprintf( buff, "%g", scale * - 0.5 * ( table[ i ] + table[ i + 1 ] ) ); - (void) astSscanf( buff, "%lf", &scaled_table_value ); - -/* Now test the suggested gap value against the scaled table value. */ - if ( gap < ( field_value[ field - 1 ] * - scaled_table_value ) ) break; - } - -/* Return the nice gap value and the number of subdivisions. */ - gap = scale * field_value[ field - 1 ] * table[ i ]; - if ( ntick ) *ntick = nticks[ i ]; - -/* If a special gap value appropriate to the field is required, then - select the table of gap values and numbers of subdivisions - according to which field we are considering and whether it contains - degrees or hours. */ - } else { - if ( field == 1 ) { - if ( as_time ) { - table = hr_table; - nticks = hr_nticks; - } else { - table = deg_table; - nticks = deg_nticks; - } - } else { - table = minsec_table; - nticks = minsec_nticks; - } - -/* Search the table for a suitable gap. We do not need to format and - unformat the test value here (as we did above) because the table - values are being used literally and not being scaled. */ - for ( i = 0; table[ i + 1 ] > 0.0; i++ ) { - if ( gap < ( field_value[ field - 1 ] * - 0.5 * ( table[ i ] + table[ i + 1 ] ) ) ) break; - } - -/* Return the nice gap value and the number of subdivisions. */ - gap = field_value[ field - 1 ] * table[ i ]; - if ( ntick ) *ntick = nticks[ i ]; - } - } - -/* After iterations are complete, restore the original sign. */ - if ( !positive ) gap = -gap; - } - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) gap = 0.0; - -/* Return the result. */ - return gap; - -/* Undefine macros local to this function */ -#undef BUFF_LEN -} - -static const char *DHmsUnit( const char *fmt, int digs, int output, int *status ) { -/* -* Name: -* DHmsUnit - -* Purpose: -* Generate a unit string to describe a formatted angle or time. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* const char *DHmsUnit( const char *fmt, int digs, int output, int *status ) - -* Class Membership: -* SkyAxis member function. - -* Description: -* This function generates a string that may be used to describe -* either (a) the units of an angle or time that has been formatted -* for output using the DHmsFormat function, or (b) a suitable -* format to be used for an angle or time that is to be supplied as -* an input coordinate value. - -* Parameters: -* fmt -* Pointer to a null terminated string containing the format -* specifier used to format coordinate values. For details of -* the syntax of this string, see the DHmsFormat function. -* digs -* The default number of digits of precision to use. This is used -* if the given format specifier indicates the number of decimal -* places to use with the string ".*". In this case, the number of -* decimal places produced will be chosen so that the total number -* of digits of precision is equal to "digs". -* output -* If non-zero, the returned string will be in a form suitable -* for describing the units/format of output produced using -* DHmsFormat. -* -* If zero, the returned string will be in a form suitable for -* describing a suggested input format, which will subsequently -* be read using AxisUnformat. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null terminated string containing the unit description. - -* Notes: -* - The result string may be stored in static memory. Its contents -* may be over-written or the returned pointer may become invalid -* following a further invocation of this function. A copy of the -* string should therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char dpchar; /* Character to indicate decimal places */ - char sep; /* Field separator character */ - const char *result; /* Pointer to result string */ - const int maxdp = 6; /* Maximum number of decimal places to show */ - int as_time; /* Value formatted as a time? */ - int dh; /* Degrees/hours field required? */ - int dp; /* Loop counter for decimal places */ - int lead_zero; /* Add leading zeros? */ - int min; /* Minutes field required? */ - int ndp; /* Number of decimal places */ - int plus; /* Leading plus sign required? */ - int pos; /* Position to add next character */ - int sec; /* Seconds field required? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Parse the format specifier. */ - ParseDHmsFormat( fmt, digs, &sep, &plus, &lead_zero, &as_time, &dh, &min, - &sec, &ndp, status ); - -/* If the units string is required to describe formatted output and - the field separators are letters (e.g. giving "01h23m45s" or - "012d34m56s"), then the units will already be clear so return a - pointer to an empty units string. */ - if ( astOK ) { - if ( output && ( sep == 'l' || sep == 'g' ) ) { - result = ""; - -/* Otherwise, if the units string is required to describe formatted - output and there is only one field present, then select an - appropriate string. */ - } else if ( output && dh && !min && !sec ) { - result = as_time ? "hours" : "degrees"; - - } else if ( output && !dh && min && !sec ) { - result = as_time ? "minutes of time" : "arcminutes"; - - } else if ( output && !dh && !min && sec ) { - result = as_time ? "seconds of time" : "arcseconds"; - -/* If there is more than one field present, or we want to describe how - to supply formatted input, then we will generate a units string of - the general form "ddd:mm:ss.sss" or "hh:mm:ss.s" or - similar. Initialise the output character count and the character to - be used to represent decimal places. */ - } else { - pos = 0; - dpchar = 'd'; - -/* Decide which field separator to use (use a space if letters were - requested since it is easier to input). */ - if ( sep == 'l' || sep == 'g' ) sep = ' '; - -/* Start with the "ddd" or "hh" field, if required, and update the - decimal places character appropriately. */ - if ( dh ) { - pos += sprintf( dhmsunit_buff, "%s", as_time ? "hh" : "ddd" ); - dpchar = as_time ? 'h' : 'd'; - } - -/* If a minutes field is present, add a separator if necessary and - "mm" and update the decimal places character. */ - if ( min ) { - if ( dh ) dhmsunit_buff[ pos++ ] = sep; - dhmsunit_buff[ pos++ ] = 'm'; - dhmsunit_buff[ pos++ ] = 'm'; - dpchar = 'm'; - } - -/* Repeat this process for the seconds field, if present. */ - if ( sec ) { - if ( dh || min ) dhmsunit_buff[ pos++ ] = sep; - dhmsunit_buff[ pos++ ] = 's'; - dhmsunit_buff[ pos++ ] = 's'; - dpchar = 's'; - } - -/* If decimal places are present, add a decimal point and then loop to - add further instances of the decimal places character to represent - the digits that follow. */ - if ( ndp > 0 ) { - dhmsunit_buff[ pos++ ] = '.'; - for ( dp = 0; dp < ndp; dp++ ) { - if ( dp < maxdp ) { - dhmsunit_buff[ pos++ ] = dpchar; - -/* After showing the maximum number of decimal places, simply add an - ellipsis and quit (otherwise the result gets boring to look at). */ - } else { - dhmsunit_buff[ pos - 1 ] = '.'; - dhmsunit_buff[ pos - 2 ] = '.'; - dhmsunit_buff[ pos - 3 ] = '.'; - break; - } - } - } - -/* Terminate the result string and return a pointer to it. */ - dhmsunit_buff[ pos ] = '\0'; - result = dhmsunit_buff; - } - } - -/* Return the result. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied SkyAxis, -* in bytes. - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to SkyAxis structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the SkyAxis structure. */ - this = (AstSkyAxis *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astTSizeOf( this->skyformat ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the protected astGetAttrib -* method inherited from the Axis class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a SkyAxis, formatted as a character string. - -* Parameters: -* this -* Pointer to the SkyAxis. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the SkyAxis, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the SkyAxis. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - const char *result; /* Pointer value to return */ - int as_time; /* AsTime attribute value */ - int centrezero; /* CentreZero attribute value */ - int is_latitude; /* IsLatitude attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* AsTime. */ -/* ------- */ - if ( !strcmp( attrib, "astime" ) ) { - as_time = astGetAxisAsTime( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", as_time ); - result = getattrib_buff; - } - -/* IsLatitude. */ -/* ----------- */ - } else if ( !strcmp( attrib, "islatitude" ) ) { - is_latitude = astGetAxisIsLatitude( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", is_latitude ); - result = getattrib_buff; - } - -/* CentreZero. */ -/* ----------- */ - } else if ( !strcmp( attrib, "centrezero" ) ) { - centrezero= astGetAxisCentreZero( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", centrezero ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static double GetAxisBottom( AstAxis *this_axis, int *status ) { -/* -* Name: -* GetAxisBottom - -* Purpose: -* Obtain the value of the Bottom attribute for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* double GetAxisBottom( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astGetAxisBottom method -* inherited from the Axis class). - -* Description: -* This function returns a value for the Bottom attribute of a SkyAxis. -* This attribute indicates the lowest legal value for the axis. - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The atribute value. A suitable default value is supplied if necessary. - -* Notes: -* - A value of -DBL_MAX will be returned if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables. */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - double result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return -DBL_MAX; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Check if a value has been set for the Bottom attribute. If so, obtain - this value. */ - if ( astTestAxisBottom( this ) ) { - result = (*parent_getaxisbottom)( this_axis, status ); - -/* Otherwise, supply a default of -pi/2 for latitude axes, and -DBL_MAX - for longitude axes. */ - } else { - result = astGetAxisIsLatitude( this ) ? -piby2 : -DBL_MAX; - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -DBL_MAX; - -/* Return the result. */ - return result; -} - -static const char *GetAxisInternalUnit( AstAxis *this, int *status ){ -/* -* Name: -* GetAxisInternalUnit - -* Purpose: -* Return the unit string for unformatted Axis values - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* const char *GetAxisInternalUnit( AstAxis *this ) - -* Class Membership: -* SkyAxis member function (over-rides the astGetAxisInternalUnit method -* inherited from the Axis class). - -* Description: -* This function returns the axis InternalUnit attribute. For sky -* axes, the InternalUnit is always "rad" (radians). - -* Parameters: -* this -* Pointer to the Axis. - -* Returned Value: -* - Pointer to a null-terminated string containing the internal -* unit string. - -* Notes: -* - The returned pointer points to a static memory buffer. The -* contents of this buffer will be over-written on each invocation of -* this function. A copy of the returned string should therefore be -* taken if it will be needed later. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - return "rad"; -} - -static double GetAxisTop( AstAxis *this_axis, int *status ) { -/* -* Name: -* GetAxisTop - -* Purpose: -* Obtain the value of the Top attribute for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* double GetAxisTop( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astGetAxisTop method -* inherited from the Axis class). - -* Description: -* This function returns a value for the Top attribute of a SkyAxis. -* This attribute indicates the highest legal value for the axis. - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The atribute value. A suitable default value is supplied if necessary. - -* Notes: -* - A value of DBL_MAX will be returned if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables. */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - double result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return DBL_MAX; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Check if a value has been set for the Top attribute. If so, obtain - this value. */ - if ( astTestAxisTop( this ) ) { - result = (*parent_getaxistop)( this_axis, status ); - -/* Otherwise, supply a default of pi/2 for latitude axes, and DBL_MAX - for longitude axes. */ - } else { - result = astGetAxisIsLatitude( this ) ? piby2 : DBL_MAX; - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = DBL_MAX; - -/* Return the result. */ - return result; -} - -static int GetAxisDirection( AstAxis *this_axis, int *status ) { -/* -* Name: -* GetAxisDirection - -* Purpose: -* Obtain the value of the Direction attribute for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* int GetAxisDirection( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astGetAxisDirection method -* inherited from the Axis class). - -* Description: -* This function returns a value for the Direction attribute of a SkyAxis. -* This attribute indicates in which direction the SkyAxis's values should -* increase when represented on a graph (1 for the conventional direction, -* 0 for reverse direction). - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero or one, according to the attribute setting. A suitable default -* value is supplied if necessary. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables. */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Check if a value has been set for the Direction attribute. If so, obtain - this value. */ - if ( astTestAxisDirection( this ) ) { - result = (*parent_getaxisdirection)( this_axis, status ); - -/* Otherwise, supply a default of 1 unless the SkyAxis values are being - formatted as times (instead of angles) by default. */ - } else { - result = !astGetAxisAsTime( this ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static const char *GetAxisFormat( AstAxis *this_axis, int *status ) { -/* -* Name: -* GetAxisFormat - -* Purpose: -* Obtain a pointer to the Format attribute for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* const char *GetAxisFormat( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astGetAxisFormat method inherited -* from the Axis class). - -* Description: -* This function returns a pointer to the Format attribute associated with -* a SkyAxis and provides a suitable default if necessary. This string -* attribute contains the format specifier that will be interpreted by the -* astAxisFormat method when formatting a value for the SkyAxis. The default -* Format may depend on other attribute settings, in particular on the -* Digits and AsTime attributes. - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Format string (null terminated). - -* Notes: -* - The pointer returned may point at memory allocated within the SkyAxis -* object, or at static memory. The contents of the string may be -* over-written or the pointer may become invalid following a further -* invocation of the same function, deletion of the SkyAxis, or assignment -* of a new Format value. A copy of the string should therefore be made if -* necessary. -* - This function will return a NULL pointer if it is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - const char *result; /* Pointer to result string */ - int as_time; /* Format SkyAxis values as times? */ - int digits; /* Number of digits of precision */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_axis); - -/* Initialise. */ - result = NULL; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Obtain a pointer to the Format string stored in the SkyAxis structure. Note - we do not use a method to obtain this, because we want a string with a - syntax appropriate to this class, and derived classes may have extended the - syntax. */ - result = this->skyformat; - -/* If no Format string has been set, we must generate a default one. Determine - how many digits of precision are to be used by default and whether the - SkyAxis values are to be formatted as times (instead of angles). */ - if ( !result ) { - digits = astGetAxisDigits( this ); - as_time = astGetAxisAsTime( this ); - if ( astOK ) { - -/* If formatting values as times, use the number of digits to select an - appropriate Format string and obtain a pointer to it. */ - if ( as_time ) { - if ( digits <= 2 ) { - result = "h"; - } else if ( digits == 3 ) { - result = "hm"; - } else if ( digits == 4 ) { - result = "hm"; - } else if ( digits == 5 ) { - result = "hms"; - } else if ( digits == 6 ) { - result = "hms"; - -/* Construct the Format string in a buffer if necessary. */ - } else { - (void) sprintf( getaxisformat_buff, "hms.%d", digits - 6 ); - result = getaxisformat_buff; - } - -/* Similarly, select a Format for expressing an angle if necessary. */ - } else { - if ( digits <= 3 ) { - result = "d"; - } else if ( digits == 4 ) { - result = "dm"; - } else if ( digits == 5 ) { - result = "dm"; - } else if ( digits == 6 ) { - result = "dms"; - } else if ( digits == 7 ) { - result = "dms"; - } else { - (void) sprintf( getaxisformat_buff, "dms.%d", digits - 7 ); - result = getaxisformat_buff; - } - } - } - } - -/* Return the result. */ - return result; -} - -static const char *GetAxisLabel( AstAxis *this_axis, int *status ) { -/* -* Name: -* GetAxisLabel - -* Purpose: -* Obtain a pointer to the Label attribute for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* const char *GetAxisLabel( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astGetAxisLabel method inherited -* from the Axis class). - -* Description: -* This function returns a pointer to the Label attribute associated with -* a SkyAxis and provides a suitable default if necessary. This string -* attribute specifies the label to be attached to the SkyAxis when it is -* represented in (e.g.) a graph. It is intended purely for interpretation -* by human readers and not by software. - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Label string (null terminated). - -* Notes: -* - The pointer returned may point at memory allocated within the SkyAxis -* object, or at static memory. The contents of the string may be -* over-written or the pointer may become invalid following a further -* invocation of the same function, deletion of the SkyAxis, or assignment -* of a new Label value. A copy of the string should therefore be made if -* necessary. -* - This function will return a NULL pointer if it is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - const char *result; /* Pointer value to be returned */ - int as_time; /* SkyAxis values formatted as times? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise. */ - result = NULL; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Test if the Label attribute is set. If so, use the parent astGetAxisLabel - method to get a pointer to it. */ - if ( astTestAxisLabel( this ) ) { - result = (*parent_getaxislabel)( this_axis, status ); - -/* Otherwise, return a pointer to a suitable default string, using the result - of the astGetAxisAsTime method to determine whether a string describing - time or angle is more appropriate. */ - } else { - as_time = astGetAxisAsTime( this ); - if ( !astTestAxisIsLatitude( this ) ) { - result = as_time ? "Angle on sky expressed as time" : - "Angle on sky"; - } else if ( astGetAxisIsLatitude( this ) ) { - result = as_time ? "Sky latitude expressed as time" : - "Sky latitude"; - } else { - result = as_time ? "Sky longitude expressed as time" : - "Sky longitude"; - } - } - -/* If an error occurred, clear the result pointer. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static const char *GetAxisSymbol( AstAxis *this_axis, int *status ) { -/* -* Name: -* GetAxisSymbol - -* Purpose: -* Obtain a pointer to the Symbol attribute for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* const char *GetAxisSymbol( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astGetAxisSymbol method inherited -* from the Axis class). - -* Description: -* This function returns a pointer to the Symbol attribute associated with -* a SkyAxis and provides a suitable default if necessary. This string -* attribute specifies the symbol to be used to represent coordinate values -* for the SkyAxis in "short form", such as in algebraic expressions where a -* full description would be inappropriate. - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Symbol string (null terminated). - -* Notes: -* - The pointer returned may point at memory allocated within the SkyAxis -* object, or at static memory. The contents of the string may be -* over-written or the pointer may become invalid following a further -* invocation of the same function, deletion of the SkyAxis, or assignment -* of a new Symbol value. A copy of the string should therefore be made if -* necessary. -* - This function will return a NULL pointer if it is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise. */ - result = NULL; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Test if the Symbol attribute is set. If so, use the parent astGetAxisSymbol - method to get a pointer to it. */ - if ( astTestAxisSymbol( this ) ) { - result = (*parent_getaxissymbol)( this_axis, status ); - -/* If a value has been set for the IsLatitude attribute, use it to decide - whether to use "delta" (for latitude) or "alpha" (for longitude). */ - } else if ( astTestAxisIsLatitude( this ) ) { - result = astGetAxisIsLatitude( this ) ? "delta" : "alpha"; - -/* Otherwise, use the AsTime attribute to decide whether the SkyAxis is - likely to be a longitude or latitude axis (the former usually having values - formatted as times). */ - } else { - result = astGetAxisAsTime( this ) ? "alpha" : "delta"; - } - -/* If an error occurred, clear the result pointer. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static const char *GetAxisUnit( AstAxis *this_axis, int *status ) { -/* -* Name: -* GetAxisUnit - -* Purpose: -* Obtain a pointer to the Unit attribute for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* const char *GetAxisUnit( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astGetAxisUnit method inherited -* from the Axis class). - -* Description: -* This function returns a pointer to the Unit attribute associated with -* a SkyAxis and provides a suitable default if necessary. This string -* attribute describes the unit used to represent formatted coordinate -* values on the SkyAxis. - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Unit string (null terminated). - -* Notes: -* - The pointer returned may point at memory allocated within the SkyAxis -* object, or at static memory. The contents of the string may be -* over-written or the pointer may become invalid following a further -* invocation of the same function, deletion of the SkyAxis, or assignment -* of a new Unit value. A copy of the string should therefore be made if -* necessary. -* - This function will return a NULL pointer if it is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - const char *fmt; /* Pointer to format specifier */ - const char *result; /* Pointer to result string */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise */ - result = NULL; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Test if the Unit attribute is set. If so, invoke the parent astGetAxisUnit - method to obtain a pointer to it. */ - if ( astTestAxisUnit( this ) ) { - result = (*parent_getaxisunit)( this_axis, status ); - -/* If we must provide a default, obtain a pointer to the format specifier used - to format SkyAxis values. Use a private member function (not a method) to - access this, in case derived classes have extended the syntax of this - string. */ - } else { - fmt = GetAxisFormat( this_axis, status ); - -/* If the format string starts with a percent, use "rad" as the default units - string. Otherwise, use the format specifier to generate a matching - default Unit string and obtain a pointer to it. */ - if ( astOK ) { - if( fmt[ 0 ] == '%' ) { - result = "rad"; - } else { - result = DHmsUnit( fmt, astGetAxisDigits( this_axis ), 1, status ); - } - } - } - -/* Return the result. */ - return result; -} - -void astInitSkyAxisVtab_( AstSkyAxisVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSkyAxisVtab - -* Purpose: -* Initialise a virtual function table for a SkyAxis. - -* Type: -* Protected function. - -* Synopsis: -* #include "skyaxis.h" -* void astInitSkyAxisVtab( AstSkyAxisVtab *vtab, const char *name ) - -* Class Membership: -* SkyAxis vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SkyAxis class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstAxisVtab *axis; /* Pointer to Axis component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - int stat; /* SLALIB status */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitAxisVtab( (AstAxisVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASkyAxis) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstAxisVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->ClearAxisAsTime = ClearAxisAsTime; - vtab->ClearAxisIsLatitude = ClearAxisIsLatitude; - vtab->ClearAxisCentreZero = ClearAxisCentreZero; - vtab->GetAxisAsTime = GetAxisAsTime; - vtab->GetAxisIsLatitude = GetAxisIsLatitude; - vtab->GetAxisCentreZero = GetAxisCentreZero; - vtab->SetAxisAsTime = SetAxisAsTime; - vtab->SetAxisIsLatitude = SetAxisIsLatitude; - vtab->SetAxisCentreZero = SetAxisCentreZero; - vtab->TestAxisAsTime = TestAxisAsTime; - vtab->TestAxisIsLatitude = TestAxisIsLatitude; - vtab->TestAxisCentreZero = TestAxisCentreZero; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - axis = (AstAxisVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_axisoverlay = axis->AxisOverlay; - axis->AxisOverlay = AxisOverlay; - parent_getaxisdirection = axis->GetAxisDirection; - axis->GetAxisDirection = GetAxisDirection; - parent_getaxislabel = axis->GetAxisLabel; - axis->GetAxisLabel = GetAxisLabel; - parent_getaxissymbol = axis->GetAxisSymbol; - axis->GetAxisSymbol = GetAxisSymbol; - parent_getaxisunit = axis->GetAxisUnit; - axis->GetAxisUnit = GetAxisUnit; - - parent_getaxistop = axis->GetAxisTop; - axis->GetAxisTop = GetAxisTop; - - parent_getaxisbottom = axis->GetAxisBottom; - axis->GetAxisBottom = GetAxisBottom; - - parent_axisformat = axis->AxisFormat; - axis->AxisFormat = AxisFormat; - - parent_axisunformat = axis->AxisUnformat; - axis->AxisUnformat = AxisUnformat; - - parent_axisgap = axis->AxisGap; - axis->AxisGap = AxisGap; - - parent_axisfields = axis->AxisFields; - axis->AxisFields = AxisFields; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - axis->AxisAbbrev = AxisAbbrev; - axis->AxisIn = AxisIn; - axis->AxisDistance = AxisDistance; - axis->AxisOffset = AxisOffset; - axis->AxisNorm = AxisNorm; - axis->AxisNormValues = AxisNormValues; - axis->ClearAxisFormat = ClearAxisFormat; - axis->GetAxisFormat = GetAxisFormat; - axis->SetAxisFormat = SetAxisFormat; - axis->TestAxisFormat = TestAxisFormat; - axis->GetAxisInternalUnit = GetAxisInternalUnit; - axis->TestAxisInternalUnit = TestAxisInternalUnit; - -/* Declare the destructor, copy constructor and dump function. */ - astSetDelete( vtab, Delete ); - astSetCopy( vtab, Copy ); - astSetDump( vtab, Dump, "SkyAxis", "Celestial coordinate axis" ); - -/* Initialize constants for converting between hours, degrees and radians. */ - LOCK_MUTEX2 - palDtf2r( 1, 0, 0.0, &hr2rad, &stat ); - palDaf2r( 1, 0, 0.0, °2rad, &stat ); - palDaf2r( 180, 0, 0.0, &pi, &stat ); - piby2 = 0.5*pi; - UNLOCK_MUTEX2 - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void ParseDHmsFormat( const char *fmt, int digs, char *sep, int *plus, - int *lead_zero, int *as_time, int *dh, int *min, - int *sec, int *ndp, int *status ) { -/* -* Name: -* ParseDHmsFormat - -* Purpose: -* Parse a format specifier for degrees/hours, minutes and seconds. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* void ParseDHmsFormat( const char *fmt, int digs, char *sep, int *plus, -* int *lead_zero, int *as_time, int *dh, int *min, -* int *sec, int *ndp, int *status ) - -* Class Membership: -* SkyAxis member function. - -* Description: -* This function parses a SkyAxis format specifier which describes -* how to convert an angle in radians into a text string with -* separate fields for degrees/hours, minutes and seconds. - -* Parameters: -* fmt -* Pointer to a null terminated string containing the format -* specifier. For details of the syntax of this string, see the -* DHmsFormat function. -* digs -* The default number of digits of precision to use. This is used -* if the given format specifier indicates the number of decimal -* places to use with the string ".*". In this case, the returned -* value for "ndp" will be set to produce the number of digits of -* precision given by "digs". -* sep -* Pointer to a location in which a single character will be -* returned to indicate which separator should be used to -* separate the fields. The returned value will be one of ' ' -* (use a blank as the separator), ':' (use a colon as the -* separator) or 'l' (use one of the letters "hdms" as -* appropriate) or 'g' (use one of the letters "hdms" but -* include suitable escape sequences to allow the Plot class to draw -* the letter as a small super-script). -* plus -* Pointer to an int in which a boolean value will be returned -* to indicate if a plus sign should be prefixed to positive -* values. -* lead_zero -* Pointer to an int in which a boolean value will be returned -* to indicate if leading zeros should be prefixed to the value -* so that the first field is always of constant (maximum) -* width, as would be required in a fixed-width table. Leading -* zeros are always prefixed to any fields that follow. -* as_time -* Pointer to an int in which a boolean value will be returned -* to indicate whether the value is to be formatted as a time -* (e.g. in hours) rather than as an angle (in degrees). -* dh -* Pointer to an int in which a boolean value will be returned -* to indicate whether a degrees or hours field is required. -* min -* Pointer to an int in which a boolean value will be returned -* to indicate whether a minutes field is required. -* sec -* Pointer to an int in which a boolean value will be returned -* to indicate whether a seconds field is required. -* ndp -* Pointer to an int in which to return the number of digits -* required following the decimal point in the final field. A -* value of zero indicates that the decimal point should be -* omitted. See parameter "digs". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Acknowledgements: -* - This function is a close approximation to a Fortran 77 routine -* written by Clive Davenhall which implements the system of format -* specifiers for angles described in his document on the CAT -* catalogue access library (Starlink User Note 181). It supports -* the same format specifiers. -*/ - -/* Local Variables: */ - int decpos; /* Offset of decimal point */ - int i; /* Loop counter for format characters */ - int ndpval; /* Number of decimal places required */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise. */ - *as_time = -1; - *lead_zero = 0; - *dh = 0; - *min = 0; - *ndp = 0; - *plus = 0; - *sec = 0; - *sep = ':'; - decpos = -1; - -/* Loop to inspect and classify each character. */ - for ( i = 0; fmt[ i ]; i++ ) { - switch ( fmt[ i ] ) { - -/* Note if a '+' sign is needed. */ - case '+': - *plus = 1; - break; - -/* Note if leading zeros are needed. */ - case 'Z': case 'z': - *lead_zero = 1; - break; - -/* Set the required separator. Note we only use graphical separators if - astEscapes indicates that escape sequences are currently being used. */ - case 'I': case 'i': - *sep = ':'; - break; - case 'B': case 'b': - *sep = ' '; - break; - case 'L': case 'l': - *sep = 'l'; - break; - case 'G': case 'g': - *sep = astEscapes( -1 ) ? 'g' : 'l'; - break; - -/* Note if the value is to be formatted as a time (but not if a - degrees or hours field has already been specified). */ - case 'T': case 't': - if ( *as_time == -1 ) *as_time = 1; - break; - -/* Note if a degrees or hours field is required (and hence whether the - value is to be formatted as a time or an angle). */ - case 'H': case 'h': - *dh = 1; - *as_time = 1; - break; - case 'D': case 'd': - *dh = 1; - *as_time = 0; - break; - -/* Note if a minutes field is required. */ - case 'M': case 'm': - *min = 1; - break; - -/* Note if a seconds field is required. */ - case 'S': case 's': - *sec = 1; - break; - -/* Note if decimal places are required. */ - case '.': - decpos = i; - } - } - -/* Format the value as an angle by default. */ - if ( *as_time == -1 ) *as_time = 0; - -/* Use degrees (or hours) as the default field. */ - if ( !*min && !*sec ) *dh = 1; - -/* Omit the seconds field if the degrees/hours field is present but - the minutes field is not. */ - if ( *dh && !*min ) *sec = 0; - -/* Determine the default number of decimal places following the final field. - This is the number which will be used if the format specifier does not - indicate how many decimal places should be produced. It is shosen to - produce the requested total number of digits of precision. */ - -/* If decimal places are required, attempt to read the integer value - following the decimal point which specifies how many. If successful, - and a valid (positive or zero) result was obtained, note its value. If - an asterisk follows the decimal point, use a value determined by the - supplied "digs" value. */ - if ( ( decpos >= 0 ) && ( decpos < ( i - 1 ) ) ) { - - if ( astSscanf( fmt + decpos + 1, "%d", &ndpval ) == 1 ) { - if ( ndpval >= 0 ) *ndp = ndpval; - - } else if ( fmt[ decpos + 1 ] == '*' ) { - *ndp = digs; - if( *as_time ) { - *ndp = ( digs > 2 ) ? digs : 2; - if( *dh ) *ndp -= 2; - } else { - *ndp = ( digs > 3 ) ? digs : 3; - if( *dh ) *ndp -= 3; - } - if( *min ) *ndp -= 2; - if( *sec ) *ndp -= 2; - if( *ndp < 0 ) *ndp = 0; - } - } -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astSetAttrib method -* inherited from the Axis class). - -* Description: -* This function assigns an attribute value for a SkyAxis, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the SkyAxis. -* setting -* Pointer to a null terminated string specifying the new -* attribute value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - int as_time; /* Format values as times? */ - int centrezero; /* SkyAxis range centred on zero? */ - int is_latitude; /* SkyAxis is a latitude axis? */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* AsTime. */ -/* ------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "astime= %d %n", &as_time, &nc ) ) - && ( nc >= len ) ) { - astSetAxisAsTime( this, as_time ); - -/* IsLatitude. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "islatitude= %d %n", &is_latitude, &nc ) ) - && ( nc >= len ) ) { - astSetAxisIsLatitude( this, is_latitude ); - -/* CentreZero. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "centrezero= %d %n", ¢rezero, &nc ) ) - && ( nc >= len ) ) { - astSetAxisCentreZero( this, centrezero ); - -/* Pass any unrecognised attribute setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetAxisFormat( AstAxis *this_axis, const char *format, int *status ) { -/* -* Name: -* SetAxisFormat - -* Purpose: -* Set a value for the Format attribute of a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* void SetAxisFormat( AstAxis *this, const char *format ) - -* Class Membership: -* SkyAxis member function (over-rides the astSetAxisFormat method inherited -* from the Axis class). - -* Description: -* This function sets a new value for the Format attribute of a SkyAxis. - -* Parameters: -* this -* Pointer to the SkyAxis. -* format -* Pointer to a null terminated string containing the new Format value. - -* Returned Value: -* void - -* Notes: -* - For details of the syntax of the Format string, see the DHmsFormat -* function. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* Store a pointer to a copy of the Format string in the SkyAxis structure. */ - this->skyformat = astStore( this->skyformat, format, - strlen( format ) + (size_t) 1 ); -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astTestAttrib protected -* method inherited from the Axis class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate -* whether a value has been set for one of a SkyAxis' attributes. - -* Parameters: -* this -* Pointer to the SkyAxis. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - -/* AsTime. */ -/* ------- */ - if ( !strcmp( attrib, "astime" ) ) { - result = astTestAxisAsTime( this ); - -/* IsLatitude. */ -/* ----------- */ - } else if ( !strcmp( attrib, "islatitude" ) ) { - result = astTestAxisIsLatitude( this ); - -/* CentreZero. */ -/* ----------- */ - } else if ( !strcmp( attrib, "centrezero" ) ) { - result = astTestAxisCentreZero( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static int TestAxisFormat( AstAxis *this_axis, int *status ) { -/* -* Name: -* TestAxisFormat - -* Purpose: -* Test if a value has been set for the Format attribute of a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* int TestAxisFormat( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astTestAxisFormat method -* inherited from the Axis class). - -* Description: -* This function returns 0 or 1 to indicate whether a value has been set -* for the Format attribute of a SkyAxis. - -* Parameters: -* this -* Pointer to the SkyAxis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if no Format value has been set, otherwise one. - -* Notes: -* - This function will return a value of zero if it is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_axis; - -/* The Format string has been set if the pointer to it is not NULL. */ - result = ( this->skyformat != NULL ); - -/* Return the result. */ - return result; -} - -static int TestAxisInternalUnit( AstAxis *this, int *status ){ -/* -* Name: -* TestAxisInternalUnit - -* Purpose: -* Test if a InternalUnit attribute value is set for an Axis. - -* Type: -* Private function. - -* Synopsis: -* #include "axis.h" -* int TestAxisInternalUnit( AstAxis *this, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astTestAxisInternalUnit -* protected method inherited from the Axis class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate -* whether a value has been set for the InternalUnit string. - -* Parameters: -* this -* Pointer to the Axis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Tell the world that we know what value to use for InternalUnit (i.e. - "rad"). */ - return 1; -} - -static int AxisUnformat( AstAxis *this_axis, const char *string, - double *value, int *status ) { -/* -* Name: -* AxisUnformat - -* Purpose: -* Read a formatted coordinate value for a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* int AxisUnformat( AstAxis *axis, const char *string, double *value, int *status ) - -* Class Membership: -* SkyAxis member function (over-rides the astAxisUnformat method -* inherited from the Axis class). - -* Description: -* This function reads a formatted coordinate value for a SkyAxis -* (supplied as a string) and returns the equivalent numerical -* value as a double. It also returns the number of characters read -* from the string. - -* Parameters: -* this -* Pointer to the SkyAxis. -* string -* Pointer to a constant null-terminated string containing the -* formatted coordinate value. -* value -* Pointer to a double in which the coordinate value read will be -* returned (in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of characters read from the string to obtain the -* coordinate value. - -* Notes: -* - Any white space at the beginning of the string will be -* skipped, as also will any trailing white space following the -* coordinate value read. The function's return value will reflect -* this. -* - A function value of zero (and no coordinate value) will be -* returned, without error, if the string supplied does not contain -* a suitably formatted value. -* - The string "" is recognised as a special case and will -* generate the value AST__BAD, without error. The test for this -* string is case-insensitive and permits embedded white space. -* - A function result of zero will be returned and no coordinate -* value will be returned via the "value" pointer if this function -* is invoked with the global error status set, or if it should -* fail for any reason. -*- -*/ - -/* Local Constants: */ -#define FMT_LEN 50 /* Length of format buffer */ - -/* Local Variables: */ - char fmtbuf[ FMT_LEN + 1 ]; /* Buffer for C format specification */ - char fmtsep; /* Format field separator character */ - char last_sep; /* Previous separator character */ - char sep; /* Separator character */ - char sep_used; /* Separator character being used */ - char sign[ 2 ]; /* Sign character as string */ - const char *field_start[ 3 ]; /* Pointer to start of each field */ - const char *fmt; /* Pointer to SkyAxis Format string */ - const char *s; /* Pointer to current reading position */ - const char *string_start; /* Pointer to first significant character */ - double field[ 3 ]; /* Field values */ - double testval; /* Value to test for invalid fields */ - int angle_or_time; /* Value known to be angle or time? */ - int as_time; /* Value is a time (else an angle)? */ - int decimal; /* Decimal point in field? */ - int dh; /* Hours field required? */ - int digs; /* Default no. of digits of precision */ - int exponent; /* Exponent at end of field? */ - int field_id[ 3 ]; /* Field identification (0 = don't know) */ - int final; /* Final field read? */ - int good_sep; /* Separator character valid? */ - int i; /* Loop counter for characters */ - int ifield; /* Loop counter for fields */ - int lead_zero; /* Add leading zeros? */ - int len; /* Significant length of string */ - int m; /* Number of characters read by astSscanf */ - int match; /* Character pattern matches? */ - int min; /* Minutes field required? */ - int n; /* Number of characters read by astSscanf */ - int nc; /* Total no. characters read */ - int nchar; /* Number of characters in erroneous value */ - int ndp; /* Number of decimal places */ - int next_id; /* Next field ID to use (0 = don't know) */ - int nfield; /* Number of fields read */ - int nread; /* No. characters read for current field */ - int plus; /* Add leading plus sign? */ - int positive; /* Value is positive? */ - int sec; /* Seconds field required? */ - int sep_angle_or_time; /* Separator indicates angle or time? */ - int sep_field_id; /* Field ID from separator (0 = don't know) */ - int sep_index; /* Index of separator character in table */ - int sep_len; /* Length of separator plus trailing space */ - int suffix_sep; /* Field has a suffix separator? */ - -/* Local Data: */ - const char *sep_list = /* List of separator characters recognised */ - " :hHdDmM'sS\""; - - const int angle_or_time_list[] = /* Whether separator indicates angle or - time (1 or 2). Zero => don't know. */ - { 0, 0, 2, 2, 1, 1, 0, 0, 1, 0, 0, 1 }; - - const int field_id_list[] = /* Whether separator identifies previous field - (1, 2, or 3). Zero => doesn't identify. */ - { 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3 }; - - const double fieldvalue[ 3 ] = /* Nominal field values (degrees/hours) */ - { 1.0, 1.0 / 60.0, 1.0 / 3600.0 }; - -/* Initialise. */ - nc = 0; - -/* Check the global error status. */ - if ( !astOK ) return nc; - -/* Obtain the SkyAxis Format string. If its starts with a "%" sign, use - the parent AxisUnformat method inherited from the Axis class. Use - a private method to obtain the Format string, in case the syntax has been - over-ridden by a derived class. */ - fmt = GetAxisFormat( this_axis, status ); - if( fmt && fmt[0] == '%' ) { - nc = (*parent_axisunformat)( this_axis, string, value, status ); - -/* Otherwise, parse it to determine the default choice of input format. */ - } else if( astOK ){ - digs = astGetAxisDigits( this_axis ); - ParseDHmsFormat( fmt, digs, &fmtsep, &plus, &lead_zero, &as_time, &dh, - &min, &sec, &ndp, status ); - -/* Initialise a pointer into the string and advance it to the first - non-white space character. Save a copy of this pointer. */ - s = string; - while ( isspace( (int) *s ) ) s++; - string_start = s; - -/* Read sign information. */ -/* ---------------------- */ -/* Attempt to read an optional sign character ("+" or "-"), possibly - surrounded by white space. Set a flag to indicate if the returned - value should be positive or not. Increment the string pointer to - the next significant character. */ - positive = 1; - n = 0; - if ( 1 == astSscanf( s, " %1[+-] %n", sign, &n ) ) { - positive = ( *sign == '+' ); - s += n; - } - -/* Loop to read field information. */ -/* ------------------------------- */ -/* Initialise, then loop to read the values of up to three fields and - to identify the separators that accompany them. */ - angle_or_time = 0; - last_sep = '\0'; - next_id = 0; - nfield = 0; - sep_used = '\0'; - suffix_sep = 0; - sep_len = 0; - for ( ifield = 0; ifield < 3; ifield++ ) { - -/* Set the default field value. */ - field[ ifield ] = 0.0; - -/* If a prefix separator was identified for the second and subsequent - fields (when the previous field was being read), then step over the - prefix, including any following white space. */ - if ( ifield && !suffix_sep ) s += sep_len; - -/* Note where in the input string the field's numerical value - starts. */ - field_start[ ifield ] = s; - -/* Each field must consist of a string of digits, possibly surrounded - by white space, except that an optional decimal point may also be - present (in which case it indicates the final field). Since we want - to exclude signs, etc. from these fields, we must first identify a - valid sequence of digits, before attempting to read them as a number. - Start by assuming that we will find a decimal point but not an - exponent. */ - decimal = 1; - exponent = 0; - -/* Match a field and obtain its value. */ -/* ----------------------------------- */ -/* Look for a character sequence like "12.345", or similar, setting a - flag to identify a match. */ - n = 0; - match = ( 0 == astSscanf( s, "%*[0123456789].%*[0123456789]%n", &n ) ) - && n; - -/* If that failed, then look for a sequence like "12.", or similar. */ - if ( !match ) { - n = 0; - match = ( 0 == astSscanf( s, "%*[0123456789].%n", &n ) ) && n; - } - -/* If that also failed, then look for a sequence like ".12", or similar. */ - if ( !match ) { - n = 0; - match = ( 0 == astSscanf( s, ".%*[0123456789]%n", &n ) ) && n; - } - -/* If that also failed, then look for a sequence containing digits only. */ - if ( !match ) { - n = 0; - match = ( 0 == astSscanf( s, "%*[0123456789]%n", &n ) ) && n; - -/* Note we have not found a decimal point. */ - decimal = 0; - } - -/* Now look for numbers that end with an exponent. First check that the - string starts with a sequence of digits with or without a decimal point. */ - if( match ) { - -/* See if the numbers are followed by an exponent with an explicit sign - character. If so, increment the number of characters in the numerical - string prefix. */ - m = 0; - if( ( 0 == astSscanf( s + n, "%*1[Ee]%*1[+-]%*[0123456789]%n", &m ) ) - && m ) { - n += m; - exponent = 1; - -/* If the above check failed, see if the numbers are followed by an exponent - without an explicit sign character. If so, increment the number of - characters in the numerical string prefix. */ - } else { - m = 0; - if( ( 0 == astSscanf( s + n, "%*1[Ee]%*[0123456789]%n", &m ) ) - && m ) { - n += m; - exponent = 1; - } - } - } - -/* If we identified a suitable sequence of characters above, we will - now read them as a number. To prevent any subsequent characters - being included as part of this number, the field width must be - restricted to the length of the sequence we found. Write a format - specification to read a double with this field width, followed by - optional white space, and to return the total number of characters - read. */ - nread = 0; - if ( match ) { - (void) sprintf( fmtbuf, "%%%dlf %%n", n ); - -/* Use this format specification to read the field value. If - successful, increment the string pointer to the next significant - character. */ - if ( 1 == astSscanf( s, fmtbuf, field + ifield, &nread ) ) s += nread; - } - -/* Note the total number of characters read up to the end of the - numerical value in this field (including any following white - space). */ - nc = s - string; - -/* Identify the following separator. */ -/* --------------------------------- */ -/* We will now attempt to identify the field separator (if any) which - follows the field we have just read. By default, we behave as if - the separator is a space. Note we have actually found a space (at - least) if extra white space characters were read as part of the - field value above. */ - sep = ' '; - good_sep = ( nread > n ); - -/* Look for one of the recognised separator characters. If one is - found, save a copy of it and note we appear (so far) to have a - valid separator. */ - sep_len = 0; - if ( *s && strchr( sep_list, *s ) ) { - sep = *s; - good_sep = 1; - -/* Set "sep_len" to the number of characters associated with the - separator. This includes any following white space. */ - while ( isspace( (int) s[ ++sep_len ] ) ); - } - -/* Identify the separator character by looking it up in the separator - list (this just uses a space if no valid separator has been - found). */ - sep_index = strchr( sep_list, sep ) - sep_list; - -/* Determine if the separator can be used to identify the field which - preceded it and if it allows us to determine whether an angle or a - time is being read. Both of these properties are specified in data - tables (with zero indicating that the separator didn't supply any - information). */ - sep_field_id = field_id_list[ sep_index ]; - sep_angle_or_time = angle_or_time_list[ sep_index ]; - -/* Validate the separator. */ -/* ----------------------- */ -/* Now perform further checks that the separator is valid - (i.e. conforms to the required syntax). If it appears to identify - the previous field (i.e. is a "suffix" separator like "m" or "s"), - then it is valid only if its field ID is no less than the ID value - that would be used next, based on previous fields (if any), and no - less than the current field number. This ensures that fields occur - in the correct order without duplication. */ - if ( good_sep ) { - if ( sep_field_id ) { - good_sep = ( sep_field_id >= next_id ) && - ( sep_field_id > ifield ); - -/* Otherwise (i.e. we appear to have a "prefix" separator like ":" or - " "), it is valid if it is the first one used, or if it matches the - previous one used. Keep a note of the first such separator used for - checking subsequent ones. */ - } else { - good_sep = !sep_used || ( sep == sep_used ); - if ( !sep_used ) sep_used = sep; - } - } - -/* If the separator seems OK and we don't yet know whether we are reading - an angle or a time, then use whatever information the separator - provides about this. */ - if ( good_sep ) { - if ( !angle_or_time ) { - angle_or_time = sep_angle_or_time; - -/* If we already know whether we are reading an angle or a time and - the current separator also contains information about this, then - check that these sources of information are compatible. This - prevents inconsistent use of angle/time field separators. */ - } else { - good_sep = !sep_angle_or_time || - ( sep_angle_or_time == angle_or_time ); - } - } - -/* Update the count of characters read for this field and note if we - have identified a valid suffix separator. */ - if ( good_sep ) nread += sep_len; - suffix_sep = good_sep && sep_field_id; - -/* Identify which field was read. */ -/* ------------------------------ */ -/* If we have a valid suffix separator, store the field ID. Also make - a note of the ID to use for the next field. */ - if ( suffix_sep ) { - field_id[ ifield ] = sep_field_id; - next_id = sep_field_id + 1; - -/* Step over the separator (plus any following white space) and update - the total number of characters read (prefix separators are not - accounted for until we start to read the next field). */ - s += sep_len; - nc = s - string;; - -/* If the separator does not identify the current field, then assign a - field ID based on the previous field (if any). Update the ID to use - for the next field, if known. */ - } else { - field_id[ ifield ] = next_id; - if ( next_id ) next_id++; - } - -/* Count fields and exit when done. */ -/* -------------------------------- */ -/* If no characters have been read for the current field, then - disregard the field if: (a) it is the first one (i.e. there is - nothing to read), or (b) it follows a white space separator - (because trailing space does not delimit an extra field). In either - case, we have now read all the fields. Otherwise, increment the - count of fields read. */ - final = 0; - if ( !nread && ( !ifield || isspace( (int) last_sep ) ) ) { - final = 1; - } else { - nfield++; - } - -/* We have also read all the fields if: (a) the last one contained a - decimal point, or (b) the last one ended with an exponent, or (c) - the next character is not a valid field separator, or (d) we have - read the seconds field so the next field ID would exceed 3. */ - final = final || decimal || exponent || !good_sep || ( next_id > 3 ); - -/* Quit reading if we have read the final field. Otherwise, save the - separator character and attempt to read the next field. */ - if ( final ) break; - last_sep = sep; - } - -/* Complete the identification of fields. */ -/* -------------------------------------- */ -/* Although we have propagated field IDs from earlier ones to later - ones in the loop above, we have still not done the reverse. This - means there there may still be some leading fields which have not - been positively identified (i.e. still have a field ID of zero). In - fact, all the fields we have read might still be unidentified at - this point. */ - -/* Calculate the field ID that would apply to the final field we have - read in the absence of any other information. This depends on the - number of leading fields that are expected to be missing. */ - next_id = nfield + ( dh ? 0 : ( min ? 1 : 2 ) ); - if ( next_id > 3 ) next_id = 3; - -/* Loop through the fields in reverse order, propagating any positive - identifications backwards towards the first field. If no fields - have been positively identified, then they are simply numbered - consecutively based on the value calculated above. */ - for ( ifield = nfield - 1; ifield >= 0; ifield-- ) { - if ( field_id[ ifield ] ) { - next_id = field_id[ ifield ] - 1; - } else { - field_id[ ifield ] = next_id--; - } - } - -/* Handle inability to read any value. */ -/* ----------------------------------- */ -/* If no fields were read, then check to see if we are trying to read - the string "" (or similar) possibly surrounded by, or - containing, white space. If so, return the coordinate value - AST__BAD. */ - if ( !nfield ) { - if ( n = 0, - ( 0 == astSscanf( string, " < %*1[Bb] %*1[Aa] %*1[Dd] > %n", &n ) - && n ) ) { - *value = AST__BAD; - nc = n; - -/* If the string still cannot be read, then return a function value of - zero. */ - } else { - nc = 0; - } - -/* Finally determine angle or time. */ -/* -------------------------------- */ -/* If one or more fields have been read, check if we know whether to - interpret the value as an angle or a time (if not, we continue to - use the default choice obtained from the SkyAxis Format string). */ - } else { - if ( angle_or_time ) as_time = ( angle_or_time == 2 ); - -/* Validate field values. */ -/* ---------------------- */ -/* If OK, check all fields except the first one for a valid value (we - allow the first field to be unconstrained, so that angles and times - outside the conventional ranges can be represented). We only need - to test for values over 60.0, since negative values can't be - read. */ - if ( astOK ) { - for ( ifield = 1; ifield < nfield; ifield++ ) { - if ( field[ ifield ] >= 60.0 ) { - -/* If a suspect field is found, we must now re-read it. This is - because values like "59.9999..." are valid, even if they round up - to 60, whereas "60" isn't. To distinguish these cases, we read the - digits that occur before the decimal point (if any). Determine how - many such digits there are. */ - n = 0; - if ( ( 0 == astSscanf( field_start[ ifield ], - "%*[0123456789]%n", &n ) ) && n ) { - -/* If there are none (this shouldn't happen), the field is - valid. Otherwise, construct a format specification to read these - digits as a floating point number. */ - (void) sprintf( fmtbuf, "%%%dlf", n ); - -/* Read the digits and compare the result with 60.0. Report an error - and quit if necessary, limiting the string length in the error - message to include just the significant characters in the value - read. */ - if ( ( 1 == astSscanf( field_start[ ifield ], fmtbuf, - &testval ) ) - && ( testval >= 60.0 ) ) { - nchar = nc - ( string_start - string ); - for ( i = len = 0; i < nchar; i++ ) { - if ( !isspace( (int) string_start[ i ] ) ) { - len = i + 1; - } - } - astError( AST__UNFER, "Invalid %s%s value in sky " - "coordinate \"%.*s\".", status, as_time ? "" : "arc", - ( field_id[ ifield ] == 2 ) ? "minutes" : - "seconds", - len, string_start ); - break; - } - } - } - } - } - -/* Calculate final result. */ -/* ----------------------- */ -/* If OK, calculate the result by summing the field values and converting - to radians. */ - if ( astOK ) { - *value = 0.0; - for ( ifield = 0; ifield < nfield; ifield++ ) { - *value += field[ ifield ] * - fieldvalue[ field_id[ ifield ] - 1 ] * - ( as_time ? hr2rad : deg2rad ); - } - -/* Change sign if necessary. */ - if ( !positive ) *value = - *value; - } - } - } - -/* If an error occurred, set the number of characters read to zero. */ - if ( !astOK ) nc = 0; - -/* Return the number of characters read. */ - return nc; - -/* Undefine macros local to this function. */ -#undef FMT_LEN -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with the - SkyAxis class using the macros defined for this purpose in the "object.h" - file. For a description of each attribute, see the class interface (in the - associated .h file). */ - -/* AsTime. */ -/* ------- */ -/* The value is constrained to be -INT_MAX, 0 or 1, with -INT_MAX for - "undefined". The default value is 0 unless the "IsLatitude" - attribute has been explicitly set to 0, in which case "AsTime" - defaults to 1. */ -astMAKE_CLEAR(SkyAxis,AxisAsTime,as_time,-INT_MAX) -astMAKE_GET(SkyAxis,AxisAsTime,int,0,( ( this->as_time != -INT_MAX ) ? - this->as_time : - ( astTestAxisIsLatitude( this ) && - !astGetAxisIsLatitude( this ) ) )) -astMAKE_SET(SkyAxis,AxisAsTime,int,as_time,( value != 0 )) -astMAKE_TEST(SkyAxis,AxisAsTime,( this->as_time != -INT_MAX )) - -/* IsLatitude. */ -/* ----------- */ -/* The value is constrained to be -INT_MAX, 0 or 1, with -INT_MAX for - "undefined". The default value is 0. */ -astMAKE_CLEAR(SkyAxis,AxisIsLatitude,is_latitude,-INT_MAX) -astMAKE_GET(SkyAxis,AxisIsLatitude,int,0,( this->is_latitude != -INT_MAX ? - this->is_latitude : 0 )) -astMAKE_SET(SkyAxis,AxisIsLatitude,int,is_latitude,( value != 0 )) -astMAKE_TEST(SkyAxis,AxisIsLatitude,( this->is_latitude != -INT_MAX )) - -/* CentreZero. */ -/* ----------- */ -/* The value is constrained to be -INT_MAX, 0 or 1, with -INT_MAX for - "undefined". The default value is equal to the value of IsLatitude. */ -astMAKE_CLEAR(SkyAxis,AxisCentreZero,centrezero,-INT_MAX) -astMAKE_GET(SkyAxis,AxisCentreZero,int,0,( this->centrezero != -INT_MAX ? - this->centrezero : astGetAxisIsLatitude( this ) )) -astMAKE_SET(SkyAxis,AxisCentreZero,int,centrezero,( value != 0 )) -astMAKE_TEST(SkyAxis,AxisCentreZero,( this->centrezero != -INT_MAX )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for SkyAxis objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for SkyAxis objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstSkyAxis *in; /* Pointer to input SkyAxis */ - AstSkyAxis *out; /* Pointer to output SkyAxis */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output SkyAxis structures. */ - in = (AstSkyAxis *) objin; - out = (AstSkyAxis *) objout; - -/* For safety, first clear any references to the input memory from - the output SkyAxis. */ - out->skyformat = NULL; - -/* Make copies of the allocated strings. */ - if ( in->skyformat ) out->skyformat = astStore( NULL, in->skyformat, - strlen( in->skyformat ) + (size_t) 1 ); - -/* If an error occurred, clean up by freeing all memory allocated above. */ - if ( !astOK ) { - out->skyformat = astFree( out->skyformat ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for SkyAxis objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for SkyAxis objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) obj; - -/* Free all allocated memory. */ - this->skyformat = astFree( this->skyformat ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SkyAxis objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the SkyAxis class to an output Channel. - -* Parameters: -* this -* Pointer to the SkyAxis whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstAxis *this_axis; /* Pointer to Axis structure */ - AstSkyAxis *this; /* Pointer to the SkyAxis structure */ - const char *sval; /* Pointer to string value */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyAxis structure. */ - this = (AstSkyAxis *) this_object; - -/* Write out values representing the instance variables for the - SkyAxis class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Format. */ -/* ------- */ -/* We must write out the Format value stored locally as it over-rides - that provided by the Axis class. */ - this_axis = (AstAxis *) this; - set = TestAxisFormat( this_axis, status ); - sval = set ? GetAxisFormat( this_axis, status ) : astGetAxisFormat( this ); - astWriteString( channel, "Format", set, 0, sval, "Format specifier" ); - -/* IsLatitude. */ -/* ----------- */ - set = TestAxisIsLatitude( this, status ); - ival = set ? GetAxisIsLatitude( this, status ) : astGetAxisIsLatitude( this ); - astWriteInt( channel, "IsLat", set, 0, ival, - ival ? "Latitude axis (not longitude)" : - "Longitude axis (not latitude)" ); - -/* CentreZero. */ -/* ----------- */ - set = TestAxisCentreZero( this, status ); - ival = set ? GetAxisCentreZero( this, status ) : astGetAxisCentreZero( this ); - astWriteInt( channel, "CnZer", set, 0, ival, - ival ? "Display axis values in range -PI -> +PI" : - "Display axis values in range 0 -> 2.PI" ); - -/* AsTime. */ -/* ------- */ - set = TestAxisAsTime( this, status ); - ival = set ? GetAxisAsTime( this, status ) : astGetAxisAsTime( this ); - astWriteInt( channel, "AsTime", set, 0, ival, - ival ? "Display values as times (not angles)" : - "Display values as angles (not times)" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASkyAxis and astCheckSkyAxis functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SkyAxis,Axis) -astMAKE_CHECK(SkyAxis) - -AstSkyAxis *astSkyAxis_( const char *options, int *status, ...) { -/* -*+ -* Name: -* astSkyAxis - -* Purpose: -* Create a SkyAxis. - -* Type: -* Public function. - -* Synopsis: -* #include "skyaxis.h" -* AstSkyAxis *astSkyAxis( const char *options, int *status, ... ) - -* Class Membership: -* SkyAxis constructor. - -* Description: -* This function creates a new SkyAxis and optionally initialises its -* attributes. - -* Parameters: -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new SkyAxis. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new SkyAxis. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSkyAxis *new; /* Pointer to new SkyAxis */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the SkyAxis, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSkyAxis( NULL, sizeof( AstSkyAxis ), !class_init, &class_vtab, - "SkyAxis" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new SkyAxis' - attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new SkyAxis. */ - return new; -} - -AstSkyAxis *astSkyAxisId_( const char *options, ... ) { -/* -* Name: -* astSkyAxisId_ - -* Purpose: -* Create a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyaxis.h" -* AstSkyAxis *astSkyAxisId_( const char *options, ... ) - -* Class Membership: -* SkyAxis constructor. - -* Description: -* This function implements the external (public) interface to the -* astSkyAxis constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astSkyAxis_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astSkyAxis_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astSkyAxis_. - -* Returned Value: -* The ID value associated with the new SkyAxis. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSkyAxis *new; /* Pointer to new SkyAxis */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the SkyAxis, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSkyAxis( NULL, sizeof( AstSkyAxis ), !class_init, &class_vtab, - "SkyAxis" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new SkyAxis' - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new SkyAxis. */ - return astMakeId( new ); -} - -AstSkyAxis *astInitSkyAxis_( void *mem, size_t size, int init, - AstSkyAxisVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSkyAxis - -* Purpose: -* Initialise a SkyAxis. - -* Type: -* Protected function. - -* Synopsis: -* #include "skyaxis.h" -* AstSkyAxis *astInitSkyAxis( void *mem, size_t size, int init, -* AstSkyAxisVtab *vtab, const char *name ) - -* Class Membership: -* SkyAxis initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new SkyAxis object. It allocates memory (if necessary) to accommodate -* the SkyAxis plus any additional data associated with the derived class. -* It then initialises a SkyAxis structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a SkyAxis at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SkyAxis is to be created. This -* must be of sufficient size to accommodate the SkyAxis data -* (sizeof(SkyAxis)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the SkyAxis (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the SkyAxis -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the SkyAxis's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new SkyAxis. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astClass -* method). - -* Returned Value: -* A pointer to the new SkyAxis. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstSkyAxis *new; /* Pointer to the new SkyAxis */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSkyAxisVtab( vtab, name ); - -/* Initialise an Axis structure (the parent class) as the first component - within the SkyAxis structure, allocating memory if necessary. */ - new = (AstSkyAxis *) astInitAxis( mem, size, 0, (AstAxisVtab *) vtab, - name ); - - if ( astOK ) { - -/* Initialise the SkyAxis data. */ -/* ---------------------------- */ -/* Initialise all attributes to their "undefined" values. */ - new->as_time = -INT_MAX; - new->is_latitude = -INT_MAX; - new->centrezero = -INT_MAX; - new->skyformat = NULL; - -/* If an error occurred, clean up by deleting the new SkyAxis. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new SkyAxis. */ - return new; -} - -AstSkyAxis *astLoadSkyAxis_( void *mem, size_t size, - AstSkyAxisVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSkyAxis - -* Purpose: -* Load a SkyAxis. - -* Type: -* Protected function. - -* Synopsis: -* #include "skyaxis.h" -* AstSkyAxis *astLoadSkyAxis( void *mem, size_t size, -* AstSkyAxisVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* SkyAxis loader. - -* Description: -* This function is provided to load a new SkyAxis using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* SkyAxis structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a SkyAxis at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the SkyAxis is to be -* loaded. This must be of sufficient size to accommodate the -* SkyAxis data (sizeof(SkyAxis)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SkyAxis (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SkyAxis structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstSkyAxis) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SkyAxis. If this is NULL, a pointer -* to the (static) virtual function table for the SkyAxis class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "SkyAxis" is used instead. - -* Returned Value: -* A pointer to the new SkyAxis. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSkyAxis *new; /* Pointer to the new SkyAxis */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SkyAxis. In this case the - SkyAxis belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSkyAxis ); - vtab = &class_vtab; - name = "SkyAxis"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSkyAxisVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built SkyAxis. */ - new = astLoadAxis( mem, size, (AstAxisVtab *) vtab, name, channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "SkyAxis" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Format. */ -/* ------- */ -/* Note that string values do not require any additional processing. */ - new->skyformat = astReadString( channel, "format", NULL ); - -/* IsLatitude. */ -/* ----------- */ - new->is_latitude = astReadInt( channel, "islat", -INT_MAX ); - if ( TestAxisIsLatitude( new, status ) ) { - SetAxisIsLatitude( new, new->is_latitude, status ); - } - -/* CentreZero. */ -/* ----------- */ - new->centrezero = astReadInt( channel, "cnzer", -INT_MAX ); - if ( TestAxisCentreZero( new, status ) ) { - SetAxisCentreZero( new, new->centrezero, status ); - } - -/* AsTime. */ -/* ------- */ - new->as_time = astReadInt( channel, "astime", -INT_MAX ); - if ( TestAxisAsTime( new, status ) ) SetAxisAsTime( new, new->as_time, status ); - -/* If an error occurred, clean up by deleting the new SkyAxis. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new SkyAxis pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -/* (No more to define at present.) */ - - - - - diff --git a/ast/skyaxis.h b/ast/skyaxis.h deleted file mode 100644 index 5c2f7ac..0000000 --- a/ast/skyaxis.h +++ /dev/null @@ -1,428 +0,0 @@ -#if !defined( SKYAXIS_INCLUDED ) /* Include this file only once */ -#define SKYAXIS_INCLUDED -/* -*+ -* Name: -* skyaxis.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the SkyAxis class. - -* Invocation: -* #include "skyaxis.h" - -* Description: -* This include file defines the interface to the SkyAxis class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The SkyAxis class extends the Axis class to represent angles on -* the sky measured in radians. It provides alternative formatting -* facilities for representing these coordinate values either as -* angles (in degrees) or as time (in hours) using sexagesimal -* notation. It also provides alternative defaults for certain -* attributes and adds new attributes and methods of its own which -* are needed to manipulate angular coordinates on the sky. - -* Inheritance: -* The SkyAxis class inherits from the Axis class. - -* Attributes Over-Ridden: -* Format (string) -* The SkyAxis class defines a new syntax for this string. -* Label (string) -* The SkyAxis class defines new default values. These may -* depend on other attribute settings. -* Symbol (string) -* The SkyAxis class defines new default values. These may -* depend on other attribute settings. -* Unit (string) -* The SkyAxis class defines new default values. These may -* depend on other attribute settings. - -* New Attributes Defined: -* AsTime (integer) -* A boolean value which indicates whether SkyAxis coordinate -* values should be formatted for display as times (instead of -* angles). It is used to determine the default format to use if -* no explicit value has been set for the Format attribute. -* CentreZero (integer) -* A boolean value which indicates whether a SkyAxis value should -* be normalised into the range [-PI,+PI] or [0,2.PI] when astNorm -* is used. -* IsLatitude (integer) -* A boolean value which indicates whether a SkyAxis is a -* latitude axis (as opposed to a longitude axis). It is used to -* determine default axis labels and symbols. It also determines the -* default value for the "AsTime" attribute (since longitudes on -* the sky are usually expressed as times). - -* Methods Over-Ridden: -* Public: -* astAxisFormat -* Format a coordinate value for a SkyAxis. -* astAxisNorm -* Normalise a SkyAxis coordinate value. -* astAxisUnformat -* Read a formatted coordinate value for a SkyAxis. - -* Protected: -* astAxisAbbrev -* Abbreviate a formatted SkyAxis value by skipping leading fields. -* astAxisDistance -* Find the distance between two SkyAxis values. -* astAxisGap -* Find a "nice" gap for tabulating SkyAxis values. -* astClearAxisFormat -* Clear the Format attribute for a SkyAxis. -* astGetAxisDirection -* Obtain the value of the Direction attribute for a SkyAxis. -* astGetAxisFormat -* Obtain a pointer to the Format attribute for a SkyAxis. -* astGetAxisLabel -* Obtain a pointer to the Label attribute for a SkyAxis. -* astGetAxisSymbol -* Obtain a pointer to the Symbol attribute for a SkyAxis. -* astGetAxisUnit -* Obtain a pointer to the Unit attribute for a SkyAxis. -* astSetAxisFormat -* Set a value for the Format attribute of a SkyAxis. -* astTestAxisFormat -* Test if a value has been set for the Format attribute of a SkyAxis. -* astAxisOffset -* Add an increment onto a supplied SkyAxis value. -* astAxisOverlay -* Overlay the attributes of a template SkyAxis on to another Axis. -* astSetAttrib -* Set an attribute value for a SkyAxis. - -* New Methods Defined: -* Public: -* None. - -* Protected: -* astClearAxisAsTime -* Clear the AsTime attribute for a SkyAxis. -* astClearAxisCentreZero -* Clear the CentreZero attribute for a SkyAxis. -* astClearAxisIsLatitude -* Clear the IsLatitude attribute for a SkyAxis. -* astGetAxisAsTime -* Obtain the value of the AsTime attribute for a SkyAxis. -* astGetAxisIsLatitude -* Obtain the value of the IsLatitude attribute for a SkyAxis. -* astGetAxisCentreZero -* Obtain the value of the CentreZero attribute for a SkyAxis. -* astSetAxisAsTime -* Set a value for the AsTime attribute of a SkyAxis. -* astSetAxisIsLatitude -* Set a value for the IsLatitude attribute of a SkyAxis. -* astSetAxisCentreZero -* Set a value for the CentreZero attribute of a SkyAxis. -* astTestAxisAsTime -* Test if a value has been set for the AsTime attribute of a SkyAxis. -* astTestAxisIsLatitude -* Test if a value has been set for the IsLatitude attribute of a -* SkyAxis. -* astTestAxisCentreZero -* Test if a value has been set for the CentreZero attribute of a -* SkyAxis. - -* Other Class Functions: -* Public: -* astIsASkyAxis -* Test class membership. -* astSkyAxis -* Create an SkyAxis. - -* Protected: -* astCheckSkyAxis -* Validate class membership. -* astInitSkyAxis -* Initialise an SkyAxis. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstSkyAxis -* SkyAxis object type. - -* Protected: -* AstSkyAxisVtab -* SkyAxis virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 29-MAR-1996 (RFWS): -* Original version. -* 25-APR-1996 (RFWS): -* Made all attribute access functions protected. -* 13-MAY-1996 (RFWS): -* Documented over-riding of the astGetAxisDirection method. -* 26-FEB-1998 (RFWS): -* Over-ride the astAxisUnformat method. -* 8-JAN-2003 (DSB): -* Added protected astInitSkyAxisVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "axis.h" /* Coordinate axes (parent class) */ - -/* Macros */ -/* ====== */ - -/* Define constants used to size global arrays in this module. */ -/* Define numerical constants for use in thie module. */ -#define AST__SKYAXIS_GETAXISFORMAT_BUFF_LEN 50 -#define AST__SKYAXIS_DHMSFORMAT_BUFF_LEN 70 -#define AST__SKYAXIS_DHMSUNIT_BUFF_LEN 17 -#define AST__SKYAXIS_GETATTRIB_BUFF_LEN 50 - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - - -/* Type Definitions. */ -/* ================= */ -/* SkyAxis structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstSkyAxis { - -/* Attributes inherited from the parent class. */ - AstAxis axis; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - char *skyformat; /* Pointer to sky format string */ - int as_time; /* Format angles as time (hours)? */ - int is_latitude; /* SkyAxis is a latitude axis? */ - int centrezero; /* Normalised range is zero-centred? */ -} AstSkyAxis; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstSkyAxisVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstAxisVtab axis_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - int (* GetAxisAsTime)( AstSkyAxis *, int * ); - int (* GetAxisIsLatitude)( AstSkyAxis *, int * ); - int (* GetAxisCentreZero)( AstSkyAxis *, int * ); - int (* TestAxisAsTime)( AstSkyAxis *, int * ); - int (* TestAxisIsLatitude)( AstSkyAxis *, int * ); - int (* TestAxisCentreZero)( AstSkyAxis *, int * ); - void (* ClearAxisAsTime)( AstSkyAxis *, int * ); - void (* ClearAxisIsLatitude)( AstSkyAxis *, int * ); - void (* ClearAxisCentreZero)( AstSkyAxis *, int * ); - void (* SetAxisAsTime)( AstSkyAxis *, int, int * ); - void (* SetAxisIsLatitude)( AstSkyAxis *, int, int * ); - void (* SetAxisCentreZero)( AstSkyAxis *, int, int * ); -} AstSkyAxisVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstSkyAxisGlobals { - AstSkyAxisVtab Class_Vtab; - int Class_Init; - char DHmsFormat_Buff[ AST__SKYAXIS_DHMSFORMAT_BUFF_LEN + 1 ]; - char DHmsUnit_Buff[ AST__SKYAXIS_DHMSUNIT_BUFF_LEN + 1 ]; - char GetAttrib_Buff[ AST__SKYAXIS_GETATTRIB_BUFF_LEN + 1 ]; - char GetAxisFormat_Buff[ AST__SKYAXIS_GETAXISFORMAT_BUFF_LEN + 1 ]; - char *GhDelim; - char *GmDelim; - char *GsDelim; - char *GdDelim; - char *GamDelim; - char *GasDelim; -} AstSkyAxisGlobals; - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(SkyAxis) /* Check class membership */ -astPROTO_ISA(SkyAxis) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstSkyAxis *astSkyAxis_( const char *, int *, ...); -#else -AstSkyAxis *astSkyAxisId_( const char *, ... )__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstSkyAxis *astInitSkyAxis_( void *, size_t, int, AstSkyAxisVtab *, - const char *, int * ); - -/* Vtab initialiser. */ -void astInitSkyAxisVtab_( AstSkyAxisVtab *, const char *, int * ); - -/* Loader. */ -AstSkyAxis *astLoadSkyAxis_( void *, size_t, AstSkyAxisVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitSkyAxisGlobals_( AstSkyAxisGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -#if defined(astCLASS) /* Protected */ -int astGetAxisAsTime_( AstSkyAxis *, int * ); -int astGetAxisIsLatitude_( AstSkyAxis *, int * ); -int astGetAxisCentreZero_( AstSkyAxis *, int * ); -int astTestAxisAsTime_( AstSkyAxis *, int * ); -int astTestAxisIsLatitude_( AstSkyAxis *, int * ); -int astTestAxisCentreZero_( AstSkyAxis *, int * ); -void astClearAxisAsTime_( AstSkyAxis *, int * ); -void astClearAxisIsLatitude_( AstSkyAxis *, int * ); -void astClearAxisCentreZero_( AstSkyAxis *, int * ); -void astSetAxisAsTime_( AstSkyAxis *, int, int * ); -void astSetAxisIsLatitude_( AstSkyAxis *, int, int * ); -void astSetAxisCentreZero_( AstSkyAxis *, int, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckSkyAxis(this) astINVOKE_CHECK(SkyAxis,this,0) -#define astVerifySkyAxis(this) astINVOKE_CHECK(SkyAxis,this,1) - -/* Test class membership. */ -#define astIsASkyAxis(this) astINVOKE_ISA(SkyAxis,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astSkyAxis astINVOKE(F,astSkyAxis_) -#else -#define astSkyAxis astINVOKE(F,astSkyAxisId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitSkyAxis(mem,size,init,vtab,name) \ -astINVOKE(O,astInitSkyAxis_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitSkyAxisVtab(vtab,name) astINVOKE(V,astInitSkyAxisVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadSkyAxis(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadSkyAxis_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ - -/* Here we make use of astCheckSkyAxis to validate SkyAxis pointers - before use. This provides a contextual error report if a pointer to - the wrong sort of object is supplied. */ -#if defined(astCLASS) /* Protected */ - -#define astClearAxisAsTime(this) \ -astINVOKE(V,astClearAxisAsTime_(astCheckSkyAxis(this),STATUS_PTR)) -#define astClearAxisIsLatitude(this) \ -astINVOKE(V,astClearAxisIsLatitude_(astCheckSkyAxis(this),STATUS_PTR)) -#define astGetAxisAsTime(this) \ -astINVOKE(V,astGetAxisAsTime_(astCheckSkyAxis(this),STATUS_PTR)) -#define astGetAxisIsLatitude(this) \ -astINVOKE(V,astGetAxisIsLatitude_(astCheckSkyAxis(this),STATUS_PTR)) -#define astSetAxisAsTime(this,value) \ -astINVOKE(V,astSetAxisAsTime_(astCheckSkyAxis(this),value,STATUS_PTR)) -#define astSetAxisIsLatitude(this,value) \ -astINVOKE(V,astSetAxisIsLatitude_(astCheckSkyAxis(this),value,STATUS_PTR)) -#define astTestAxisAsTime(this) \ -astINVOKE(V,astTestAxisAsTime_(astCheckSkyAxis(this),STATUS_PTR)) -#define astTestAxisIsLatitude(this) \ -astINVOKE(V,astTestAxisIsLatitude_(astCheckSkyAxis(this),STATUS_PTR)) - -#define astClearAxisCentreZero(this) \ -astINVOKE(V,astClearAxisCentreZero_(astCheckSkyAxis(this),STATUS_PTR)) -#define astGetAxisCentreZero(this) \ -astINVOKE(V,astGetAxisCentreZero_(astCheckSkyAxis(this),STATUS_PTR)) -#define astSetAxisCentreZero(this,value) \ -astINVOKE(V,astSetAxisCentreZero_(astCheckSkyAxis(this),value,STATUS_PTR)) -#define astTestAxisCentreZero(this) \ -astINVOKE(V,astTestAxisCentreZero_(astCheckSkyAxis(this),STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/skyframe.c b/ast/skyframe.c deleted file mode 100644 index 1c20839..0000000 --- a/ast/skyframe.c +++ /dev/null @@ -1,12592 +0,0 @@ -/* -*class++ -* Name: -* SkyFrame - -* Purpose: -* Celestial coordinate system description. - -* Constructor Function: -c astSkyFrame -f AST_SKYFRAME - -* Description: -* A SkyFrame is a specialised form of Frame which describes -* celestial longitude/latitude coordinate systems. The particular -* celestial coordinate system to be represented is specified by -* setting the SkyFrame's System attribute (currently, the default -* is ICRS) qualified, as necessary, by a mean Equinox value and/or -* an Epoch. -* -* For each of the supported celestial coordinate systems, a SkyFrame -* can apply an optional shift of origin to create a coordinate system -* representing offsets within the celestial coordinate system from some -* specified reference point. This offset coordinate system can also be -* rotated to define new longitude and latitude axes. See attributes -* SkyRef, SkyRefIs, SkyRefP and AlignOffset. -* -* All the coordinate values used by a SkyFrame are in -* radians. These may be formatted in more conventional ways for -c display by using astFormat. -f display by using AST_FORMAT. -* For a SkyFrame, the Unit attribute describes the formatted value of -* a SkyFrame axis, and may for instance be "h:m:s", indicating that a -* formatted axis value contains colon-separated fields for hours, minutes -* and seconds. On the other hand, the InternalUnit attribute for a -* SkyFrame is always set to "rad" (i.e. radians), indicating that the -* unformatted (i.e. floating point) axis values used by application code -* are always in units of radians - -* Inheritance: -* The SkyFrame class inherits from the Frame class. - -* Attributes: -* In addition to those attributes common to all Frames, every -* SkyFrame also has the following attributes: -* -* - AlignOffset: Align SkyFrames using the offset coordinate system? -* - AsTime(axis): Format celestial coordinates as times? -* - Equinox: Epoch of the mean equinox -* - IsLatAxis: Is the specified axis the latitude axis? -* - IsLonAxis: Is the specified axis the longitude axis? -* - LatAxis: Index of the latitude axis -* - LonAxis: Index of the longitude axis -* - NegLon: Display longitude values in the range [-pi,pi]? -* - Projection: Sky projection description. -* - SkyRef: Position defining location of the offset coordinate system -* - SkyRefIs: Selects the nature of the offset coordinate system -* - SkyRefP: Position defining orientation of the offset coordinate system -* - SkyTol: Smallest significant shift in sky coordinates - -* Functions: -* In addition to those -c functions -f routines -* applicable to all Frames, the following -c functions -f routines -* may also be applied to all SkyFrames: -* -c - astSkyOffsetMap: Obtain a Mapping from absolute to offset coordinates -f - AST_SKYOFFSETMAP: Obtain a Mapping from absolute to offset coordinates - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) -* BEC: Brad Cavanagh (JAC, Hawaii) - -* History: -* 4-MAR-1996 (RFWS): -* Original version. -* 17-MAY-1996 (RFWS): -* Tidied up, etc. -* 31-JUL-1996 (RFWS): -* Added support for attributes and a public interface. -* 11-SEP-1996 (RFWS): -* Added Gap (written by DSB). -* 24-SEP-1996 (RFWS): -* Added I/O facilities. -* 27-FEB-1997 (RFWS): -* Improved the public prologues. -* 27-MAY-1997 (RFWS): -* Modified to use a new public interface to the SlaMap class -* and to use the astSimplify method to remove redundant -* conversions. -* 16-JUN-1997 (RFWS): -* Fixed bug in axis associations returned by astMatch if axes -* were swapped. -* 16-JUL-1997 (RFWS): -* Added Projection attribute. -* 14-NOV-1997 (RFWS): -* Corrected the omission of axis permutations from astNorm. -* 21-JAN-1998 (RFWS): -* Ensure that Title and Domain values appropriate to a SkyFrame -* are preserved if a Frame result is generated by SubFrame. -* 26-FEB-1998 (RFWS): -* Over-ride the astUnformat method. -* 3-APR-2001 (DSB): -* Added "Unknown" option for the System attribute. Added read-only -* attributes LatAxis and LonAxis. -* 21-JUN-2001 (DSB): -* Added astAngle and astOffset2. -* 4-SEP-2001 (DSB): -* Added NegLon attribute, and astResolve method. -* 9-SEP-2001 (DSB): -* Added astBear method. -* 21-SEP-2001 (DSB): -* Removed astBear method. -* 10-OCT-2002 (DSB): -* Moved definitions of macros for SkyFrame system values from -* this file into skyframe.h. -* 24-OCT-2002 (DSB): -* Modified MakeSkyMapping so that any two SkyFrames with system=unknown -* are assumed to be related by a UnitMap. previously, they were -* considered to be unrelated, resulting in no ability to convert from -* one to the other. This could result for instance in astConvert -* being unable to find a maping from a SkyFrame to itself. -* 15-NOV-2002 (DSB): -* Moved System and Epoch attributes to the Frame class. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitSkyFrameVtab -* method. -* 11-JUN-2003 (DSB): -* Added ICRS option for System attribute, and made it the default -* in place of FK5. -* 27-SEP-2003 (DSB): -* Added HELIOECLIPTIC option for System attribute. -* 19-APR-2004 (DSB): -* Added SkyRef, SkyRefIs, SkyRefP and AlignOffset attributes. -* 8-SEP-2004 (DSB): -* Added astResolvePoints method. -* 2-DEC-2004 (DSB): -* Added System "J2000" -* 27-JAN-2005 (DSB): -* Fix memory leaks in astLoadSkyFrame_ and Match. -* 7-APR-2005 (DSB): -* Allow SkyRefIs to be set to "Ignored". -* 12-MAY-2005 (DSB): -* Override astNormBox method. -* 15-AUG-2005 (DSB): -* Added AZEL system. -* 13-SEP-2005 (DSB): -* Override astClearSystem so that SkyRef/SkyRefPcan be converted -* from the original System to the default System. -* 19-SEP-2005 (DSB): -* Changed default for SkyRefIs from ORIGIN to IGNORED. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 22-FEB-2006 (DSB): -* Store the Local Apparent Sidereal Time in the SkyFrame structure -* in order to avoid expensive re-computations. -* 22-AUG-2006 (DSB): -* Ensure the cached Local Apparent Siderial Time is initialised -* when initialising or loading a SkyFrame. -* 22-SEP-2006 (DSB): -* Report an error in SetSystem if it is not possible to convert -* from old to new systems. -* 3-OCT-2006 (DSB): -* Added Equation of Equinoxes to the SkyFrame structure. -* 6-OCT-2006 (DSB): -* - Guard against annulling null pointers in subFrame. -* - Add Dut1 attribute -* - Use linear approximation for LAST over short periods (less -* than 0.001 of a day) -* - Remove Equation of Equinoxes from the SkyFrame structure. -* 10-OCT-2006 (DSB): -* Use "AlOff" instead of "AlignOffset" as the external channel name -* for the AlignOffset attribute. The longer form exceeded the -* limit that can be used by the Channel class. -* 14-OCT-2006 (DSB): -* - Move Dut1 attribute to the Frame class. -* - Use the TimeFrame class to do the TDB->LAST conversions. -* 17-JAN-2007 (DSB): -* - Use a UnitMap to align offset coordinate systems in two -* SkyFrames, regardless of other attribute values. -* - Only align in offset coordinates if both target and template -* have a non-zero value for AlignOffset. -* 23-JAN-2007 (DSB): -* Modified so that a SkyFrame can be used as a template to find a -* SkyFrame contained within a CmpFrame. This involves changes in -* Match and the removal of the local versions of SetMaxAxes and -* SetMinAxes. -* 4-JUL-2007 (DSB): -* Modified GetLast to use the correct solar to sidereal conversion -* factor. As a consequence the largest acceptable epoch gap before -* the LAST needs to be recalculated has been increased. -* 11-JUL-2007 (DSB): -* Override astSetEpoch and astClearEpoch by implementations which -* update the LAST value stored in the SkyFrame. -* 7-AUG-2007 (DSB): -* - Set a value for the CentreZero attribute when extracting a -* SkyAxis from a SkyFrame in function SubFrame. -* - In SubFrame, clear extended attributes such as System after -* all axis attributes have been "fixated. -* 30-AUG-2007 (DSB): -* Override astSetDut1 and astClearDut1 by implementations which -* update the LAST value stored in the SkyFrame. -* 31-AUG-2007 (DSB): -* - Cache the magnitude of the diurnal aberration vector in the -* SkyFrame structure for use when correcting for diurnal aberration. -* - Modify the azel conversions to include correction for diurnal -* aberration. -* - Override astClearObsLat and astSetObsLat by implementations which -* reset the magnitude of the diurnal aberration vector. -* 3-SEP-2007 (DSB): -* In SubFrame, since AlignSystem is extended by the SkyFrame class -* it needs to be cleared before invoking the parent SubFrame -* method in cases where the result Frame is not a SkyFrame. -* 2-OCT-2007 (DSB): -* In Overlay, clear AlignSystem as well as System before calling -* the parent overlay method. -* 10-OCT-2007 (DSB): -* In MakeSkyMapping, correct the usage of variables "system" and -* "align_sys" when aligning in AZEL. -* 18-OCT-2007 (DSB): -* Compare target and template AlignSystem values in Match, rather -* than comparing target and result AlignSystem values in MakeSkyMapping -* (since result is basically a copy of target). -* 27-NOV-2007 (DSB): -* - Modify SetSystem to ensure that SkyRef and SkyRefP position are -* always transformed as absolute values, rather than as offset -* values. -* - Modify SubMatch so that a value of zero is assumed for -* AlignOffset when restoring thre integrity of a FrameSet. -* 15-DEC-2008 (DSB): -* Improve calculation of approximate Local Apparent Sidereal time -* by finding and using the ratio of solar to sidereal time -* independently for each approximation period. -* 14-JAN-2009 (DSB): -* Override the astIntersect method. -* 21-JAN-2009 (DSB): -* Fix mis-use of results buffers for GetFormat and GetAttrib. -* 16-JUN-2009 (DSB): -* All sky coordinate systems currently supported by SkyFrame are -* left handed. So fix GetDirection method to return zero for all -* longitude axes and 1 for all latitude axes. -* 18-JUN-2009 (DSB): -* Incorporate the new ObsAlt attribute. -* 23-SEP-2009 (DSB): -* Allow some rounding error when checking for changes in SetObsLon -* and SetDut1. This reduces the number of times the expensive -* calculation of LAST is performed. -* 24-SEP-2009 (DSB); -* Create a static cache of LAST values stored in the class virtual -* function table. These are used in preference to calculating a new -* value from scratch. -* 25-SEP-2009 (DSB); -* Do not calculate LAST until it is needed. -* 12-OCT-2009 (DSB); -* - Handle 2.PI->0 discontinuity in cached LAST values. -* 12-OCT-2009 (BEC); -* - Fix bug in caching LAST value. -* 31-OCT-2009 (DSB); -* Correct SetCachedLAST to handle cases where the epoch to be -* stored is smaller than any epoch already in the table. -* 24-NOV-2009 (DSB): -* - In CalcLast, only use end values form the table of stored -* LAST values if the corresponding epochs are within 0.001 of -* a second of the required epoch (this tolerance used to be -* 0.1 seconds). -* - Do not clear the cached LAST value in SetEpoch and ClearEpoch. -* 8-MAR-2010 (DSB): -* Add astSkyOffsetMap method. -* 7-APR-2010 (DSB): -* Add IsLatAxis and IsLonAxis attributes. -* 11-MAY-2010 (DSB): -* In SetSystem, clear SkyRefP as well as SkyRef. -* 22-MAR-2011 (DSB): -* Override astFrameGrid method. -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -* 23-MAY-2011 (DSB): -* Truncate returned PointSet in function FrameGrid to exclude unused points. -* 24-MAY-2011 (DSB): -* When clearing or setting the System attribute, clear SkyRef rather -* than reporting an error if the Mapping from the old System to the -* new System is unknown. -* 30-NOV-2011 (DSB): -* When aligning two SkyFrames in the system specified by AlignSystem, -* do not assume inappropriate default equinox values for systems -* that are not referred to the equinox specified by the Equinox attribute. -* 26-APR-2012 (DSB): -* - Correct Dump function so that any axis permutation is taken into -* account when dumping SkyFrame attributes that have a separate value -* for each axis (e.g. SkyRef and SkyRefP). -* - Take axis permutation into account when setting a new value -* for attributes that have a separate value for each axis (e.g. -* SkyRef and SkyRefP). -* - Remove the code that overrides ClearEpoch and SetEpoch (these -* overrides have not been needed since the changes made on -* 24/11/2009). -* 27-APR-2012 (DSB): -* - Correct astLoadSkyFrame function so that any axis permutation is -* taken into account when loading SkyFrame attributes that have a -* separate value for each axis. -* 25-JUL-2013 (DSB): -* Use a single table of cached LAST values for all threads, rather -* than a separate table for each thread. The problem with a table per -* thread is that if you have N threads, each table contains only -* one N'th of the total number of cached values, resulting in -* poorer accuracy, and small variations in interpolated LAST value -* depending on the way the cached values are distributed amongst the -* N threads. -* 6-AST-2013 (DSB): -* Fix the use of the read-write lock that is used to serialise -* access to the table of cached LAST values. This bug could -* cause occasional problems where an AST pointer would became -* invalid for no apparent reason. -* 21-FEB-2014 (DSB): -* Rounding errors in the SkyLineDef constructor could result in the line -* between coincident points being given a non-zero length. -* 6-JUL-2015 (DSB): -* Added SkyTol attribute. -* 3-FEB-2017 (GSB): -* Override astSetDtai and astClearDtai. -* 6-APR-2017 (GSB): -* Added dtai to AstSkyLastTable. -* 10-APR-2017 (GSB): -* Added macro to test floating point equality and used it for Dtai. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS SkyFrame - -/* Define the first and last acceptable System values. */ -#define FIRST_SYSTEM AST__FK4 -#define LAST_SYSTEM AST__AZEL - -/* Speed of light (AU per day) (from SLA_AOPPA) */ -#define C 173.14463331 - -/* Ratio between solar and sidereal time (from SLA_AOPPA) */ -#define SOLSID 1.00273790935 - -/* Define values for the different values of the SkyRefIs attribute. */ -#define POLE_STRING "Pole" -#define ORIGIN_STRING "Origin" -#define IGNORED_STRING "Ignored" - -/* Define other numerical constants for use in this module. */ -#define GETATTRIB_BUFF_LEN 200 -#define GETFORMAT_BUFF_LEN 50 -#define GETLABEL_BUFF_LEN 40 -#define GETSYMBOL_BUFF_LEN 20 -#define GETTITLE_BUFF_LEN 200 - -/* A macro which returns a flag indicating if the supplied system is - references to the equinox specified by the Equinox attribute. */ -#define EQREF(system) \ -((system==AST__FK4||system==AST__FK4_NO_E||system==AST__FK5||system==AST__ECLIPTIC)?1:0) - -/* Check for floating point equality (within the given tolerance), taking - bad values into account. */ -#define EQUAL(aa,bb,tol) (((aa)==AST__BAD)?(((bb)==AST__BAD)?1:0):(((bb)==AST__BAD)?0:(fabs((aa)-(bb))<=(tol)))) - -/* -* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a method to clear a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "skyframe.h" -* MAKE_CLEAR(attr,component,assign,nval) - -* Class Membership: -* Defined by the SkyFrame class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstSkyFrame *this, int axis ) -* -* and an external interface function of the form: -* -* void astClear_( AstSkyFrame *this, int axis ) -* -* which implement a method for clearing a single value in a specified -* multi-valued attribute for an axis of a SkyFrame. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. Label in "astClearLabelAt"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attr,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstSkyFrame *this, int axis, int *status ) { \ -\ - int axis_p; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate and permute the axis index. */ \ - axis_p = astValidateAxis( this, axis, 1, "astClear" #attr ); \ -\ -/* Assign the "clear" value. */ \ - if( astOK ) { \ - this->component[ axis_p ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attr##_( AstSkyFrame *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,SkyFrame,Clear##attr))( this, axis, status ); \ -} - - -/* -* -* Name: -* MAKE_GET - -* Purpose: -* Implement a method to get a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "skyframe.h" -* MAKE_GET(attr,type,bad_value,assign,nval) - -* Class Membership: -* Defined by the SkyFrame class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( AstSkyFrame *this, int axis ) -* -* and an external interface function of the form: -* -* astGet_( AstSkyFrame *this, int axis ) -* -* which implement a method for getting a single value from a specified -* multi-valued attribute for an axis of a SkyFrame. - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. This can -* use the string "axis" to represent the zero-based value index. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET(attr,type,bad_value,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attr( AstSkyFrame *this, int axis, int *status ) { \ - int axis_p; /* Permuted axis index */ \ - type result; /* Result to be returned */ \ -\ -/* Initialise */\ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate and permute the axis index. */ \ - axis_p = astValidateAxis( this, axis, 1, "astGet" #attr ); \ -\ -/* Assign the result value. */ \ - if( astOK ) { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -type astGet##attr##_( AstSkyFrame *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,SkyFrame,Get##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_SET - -* Purpose: -* Implement a method to set a single value in a multi-valued attribute -* for a SkyFrame. - -* Type: -* Private macro. - -* Synopsis: -* #include "skyframe.h" -* MAKE_SET(attr,type,component,assign,nval) - -* Class Membership: -* Defined by the SkyFrame class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstSkyFrame *this, int axis, value ) -* -* and an external interface function of the form: -* -* void astSet_( AstSkyFrame *this, int axis, value ) -* -* which implement a method for setting a single value in a specified -* multi-valued attribute for a SkyFrame. - -* Parameters: -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. Label in "astSetLabelAt"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET(attr,type,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstSkyFrame *this, int axis, type value, int *status ) { \ -\ - int axis_p; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate and permute the axis index. */ \ - axis_p = astValidateAxis( this, axis, 1, "astSet" #attr ); \ -\ -/* Store the new value in the structure component. */ \ - if( astOK ) { \ - this->component[ axis_p ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attr##_( AstSkyFrame *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,SkyFrame,Set##attr))( this, axis, value, status ); \ -} - -/* -* -* Name: -* MAKE_TEST - -* Purpose: -* Implement a method to test if a single value has been set in a -* multi-valued attribute for a class. - -* Type: -* Private macro. - -* Synopsis: -* #include "skyframe.h" -* MAKE_TEST(attr,assign,nval) - -* Class Membership: -* Defined by the SkyFrame class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static int Test( AstSkyFrame *this, int axis ) -* -* and an external interface function of the form: -* -* int astTest_( AstSkyFrame *this, int axis ) -* -* which implement a method for testing if a single value in a specified -* multi-valued attribute has been set for a class. - -* Parameters: -* attr -* The name of the attribute to be tested, as it appears in the function -* name (e.g. Label in "astTestLabelAt"). -* assign -* An expression that evaluates to 0 or 1, to be used as the returned -* value. This can use the string "axis" to represent the zero-based -* index of the value within the attribute. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_TEST(attr,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static int Test##attr( AstSkyFrame *this, int axis, int *status ) { \ - int result; /* Value to return */ \ - int axis_p; /* Permuted axis index */ \ -\ -/* Initialise */ \ - result =0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate and permute the axis index. */ \ - axis_p = astValidateAxis( this, axis, 1, "astTest" #attr ); \ -\ -/* Assign the result value. */ \ - if( astOK ) { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -int astTest##attr##_( AstSkyFrame *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,SkyFrame,Test##attr))( this, axis, status ); \ -} - - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points (for AST__BAD) */ -#include "unitmap.h" /* Unit Mappings */ -#include "permmap.h" /* Coordinate permutations */ -#include "cmpmap.h" /* Compound Mappings */ -#include "slamap.h" /* SLALIB sky coordinate Mappings */ -#include "timemap.h" /* Time conversions */ -#include "skyaxis.h" /* Sky axes */ -#include "frame.h" /* Parent Frame class */ -#include "matrixmap.h" /* Matrix multiplication */ -#include "sphmap.h" /* Cartesian<->Spherical transformations */ -#include "skyframe.h" /* Interface definition for this class */ -#include "pal.h" /* SLALIB library interface */ -#include "wcsmap.h" /* Factors of PI */ -#include "timeframe.h" /* Time system transformations */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Type Definitions. */ -/* ================= */ - -/* Cached Line structure. */ -/* ---------------------- */ -/* This structure contains information describing a line segment within a - SkyFrame. It differs from the AstLineDef defined in frame.h because - positions are represented by 3D (x,y,z) cartesian coords rather than - 2D (long,lat) coords. */ - -typedef struct SkyLineDef { - AstFrame *frame; /* Pointer to Frame in which the line is defined */ - double length; /* Line length */ - int infinite; /* Disregard the start and end of the line? */ - double start[3]; /* Unit vector defining start of line */ - double end[3]; /* Unit vector defining end of line */ - double dir[3]; /* Unit vector defining line direction */ - double q[3]; /* Unit vector perpendicular to line */ - double start_2d[2]; - double end_2d[2]; -} SkyLineDef; - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are used or extended by this - class. */ -static AstSystemType (* parent_getalignsystem)( AstFrame *, int * ); -static AstSystemType (* parent_getsystem)( AstFrame *, int * ); -static const char *(* parent_format)( AstFrame *, int, double, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static const char *(* parent_getdomain)( AstFrame *, int * ); -static const char *(* parent_getformat)( AstFrame *, int, int * ); -static const char *(* parent_getlabel)( AstFrame *, int, int * ); -static const char *(* parent_getsymbol)( AstFrame *, int, int * ); -static const char *(* parent_gettitle)( AstFrame *, int * ); -static const char *(* parent_getunit)( AstFrame *, int, int * ); -static double (* parent_gap)( AstFrame *, int, double, int *, int * ); -static double (* parent_getbottom)( AstFrame *, int, int * ); -static double (* parent_getepoch)( AstFrame *, int * ); -static double (* parent_gettop)( AstFrame *, int, int * ); -static int (* parent_getdirection)( AstFrame *, int, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); -static int (* parent_match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int (* parent_subframe)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static int (* parent_testformat)( AstFrame *, int, int * ); -static int (* parent_unformat)( AstFrame *, int, const char *, double *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_cleardtai)( AstFrame *, int * ); -static void (* parent_cleardut1)( AstFrame *, int * ); -static void (* parent_clearformat)( AstFrame *, int, int * ); -static void (* parent_clearobsalt)( AstFrame *, int * ); -static void (* parent_clearobslat)( AstFrame *, int * ); -static void (* parent_clearobslon)( AstFrame *, int * ); -static void (* parent_clearsystem)( AstFrame *, int * ); -static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_setdtai)( AstFrame *, double, int * ); -static void (* parent_setdut1)( AstFrame *, double, int * ); -static void (* parent_setformat)( AstFrame *, int, const char *, int * ); -static void (* parent_setobsalt)( AstFrame *, double, int * ); -static void (* parent_setobslat)( AstFrame *, double, int * ); -static void (* parent_setobslon)( AstFrame *, double, int * ); -static void (* parent_setsystem)( AstFrame *, AstSystemType, int * ); - -/* Factors for converting between hours, degrees and radians. */ -static double hr2rad; -static double deg2rad; -static double pi; -static double piby2; - -/* Table of cached Local Apparent Sidereal Time values and corresponding - epochs. */ -static int nlast_tables = 0; -static AstSkyLastTable **last_tables = NULL; - - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->GetFormat_Buff[ 0 ] = 0; \ - globals->GetLabel_Buff[ 0 ] = 0; \ - globals->GetSymbol_Buff[ 0 ] = 0; \ - globals->GetTitle_Buff[ 0 ] = 0; \ - globals->GetTitle_Buff2[ 0 ] = 0; \ - globals->TDBFrame = NULL; \ - globals->LASTFrame = NULL; \ - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(SkyFrame) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SkyFrame,Class_Init) -#define class_vtab astGLOBAL(SkyFrame,Class_Vtab) -#define getattrib_buff astGLOBAL(SkyFrame,GetAttrib_Buff) -#define getformat_buff astGLOBAL(SkyFrame,GetFormat_Buff) -#define getlabel_buff astGLOBAL(SkyFrame,GetLabel_Buff) -#define getsymbol_buff astGLOBAL(SkyFrame,GetSymbol_Buff) -#define gettitle_buff astGLOBAL(SkyFrame,GetTitle_Buff) -#define gettitle_buff2 astGLOBAL(SkyFrame,GetTitle_Buff2) -#define tdbframe astGLOBAL(SkyFrame,TDBFrame) -#define lastframe astGLOBAL(SkyFrame,LASTFrame) - - - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -/* A read-write lock used to protect the table of cached LAST values so - that multiple threads can read simultaneously so long as no threads are - writing to the table. */ -static pthread_rwlock_t rwlock1=PTHREAD_RWLOCK_INITIALIZER; -#define LOCK_WLOCK1 pthread_rwlock_wrlock( &rwlock1 ); -#define LOCK_RLOCK1 pthread_rwlock_rdlock( &rwlock1 ); -#define UNLOCK_RWLOCK1 pthread_rwlock_unlock( &rwlock1 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ GETATTRIB_BUFF_LEN + 1 ]; - -/* Buffer returned by GetFormat. */ -static char getformat_buff[ GETFORMAT_BUFF_LEN + 1 ]; - -/* Default GetLabel string buffer */ -static char getlabel_buff[ GETLABEL_BUFF_LEN + 1 ]; - -/* Default GetSymbol buffer */ -static char getsymbol_buff[ GETSYMBOL_BUFF_LEN + 1 ]; - -/* Default Title string buffer */ -static char gettitle_buff[ AST__SKYFRAME_GETTITLE_BUFF_LEN + 1 ]; -static char gettitle_buff2[ AST__SKYFRAME_GETTITLE_BUFF_LEN + 1 ]; - -/* TimeFrames for doing TDB<->LAST conversions. */ -static AstTimeFrame *tdbframe = NULL; -static AstTimeFrame *lastframe = NULL; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSkyFrameVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#define LOCK_WLOCK1 -#define LOCK_RLOCK1 -#define UNLOCK_RWLOCK1 - -#endif - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstLineDef *LineDef( AstFrame *, const double[2], const double[2], int * ); -static AstMapping *SkyOffsetMap( AstSkyFrame *, int * ); -static AstPointSet *FrameGrid( AstFrame *, int, const double *, const double *, int * ); -static AstPointSet *ResolvePoints( AstFrame *, const double [], const double [], AstPointSet *, AstPointSet *, int * ); -static AstSystemType GetAlignSystem( AstFrame *, int * ); -static AstSystemType GetSystem( AstFrame *, int * ); -static AstSystemType SystemCode( AstFrame *, const char *, int * ); -static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * ); -static const char *Format( AstFrame *, int, double, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetDomain( AstFrame *, int * ); -static const char *GetFormat( AstFrame *, int, int * ); -static const char *GetLabel( AstFrame *, int, int * ); -static const char *GetProjection( AstSkyFrame *, int * ); -static const char *GetSymbol( AstFrame *, int, int * ); -static const char *GetTitle( AstFrame *, int * ); -static const char *GetUnit( AstFrame *, int, int * ); -static const char *SystemString( AstFrame *, AstSystemType, int * ); -static double Angle( AstFrame *, const double[], const double[], const double[], int * ); -static double CalcLAST( AstSkyFrame *, double, double, double, double, double, double, int * ); -static double Distance( AstFrame *, const double[], const double[], int * ); -static double Gap( AstFrame *, int, double, int *, int * ); -static double GetBottom( AstFrame *, int, int * ); -static double GetCachedLAST( AstSkyFrame *, double, double, double, double, double, double, int * ); -static double GetEpoch( AstFrame *, int * ); -static double GetEquinox( AstSkyFrame *, int * ); -static void SetCachedLAST( AstSkyFrame *, double, double, double, double, double, double, double, int * ); -static void SetLast( AstSkyFrame *, int * ); -static double GetTop( AstFrame *, int, int * ); -static double Offset2( AstFrame *, const double[2], double, double, double[2], int * ); -static double GetDiurab( AstSkyFrame *, int * ); -static double GetLAST( AstSkyFrame *, int * ); -static int GetActiveUnit( AstFrame *, int * ); -static int GetAsTime( AstSkyFrame *, int, int * ); -static int GetDirection( AstFrame *, int, int * ); -static int GetIsLatAxis( AstSkyFrame *, int, int * ); -static int GetIsLonAxis( AstSkyFrame *, int, int * ); -static int GetLatAxis( AstSkyFrame *, int * ); -static int GetLonAxis( AstSkyFrame *, int * ); -static int GetNegLon( AstSkyFrame *, int * ); -static int GetObjSize( AstObject *, int * ); -static int IsEquatorial( AstSystemType, int * ); -static int LineContains( AstFrame *, AstLineDef *, int, double *, int * ); -static int LineCrossing( AstFrame *, AstLineDef *, AstLineDef *, double **, int * ); -static int LineIncludes( SkyLineDef *, double[3], int * ); -static int MakeSkyMapping( AstSkyFrame *, AstSkyFrame *, AstSystemType, AstMapping **, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int TestActiveUnit( AstFrame *, int * ); -static int TestAsTime( AstSkyFrame *, int, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int TestEquinox( AstSkyFrame *, int * ); -static int TestNegLon( AstSkyFrame *, int * ); -static int TestProjection( AstSkyFrame *, int * ); -static int TestSlaUnit( AstSkyFrame *, AstSkyFrame *, AstSlaMap *, int * ); -static int Unformat( AstFrame *, int, const char *, double *, int * ); -static void ClearAsTime( AstSkyFrame *, int, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void ClearDtai( AstFrame *, int * ); -static void ClearDut1( AstFrame *, int * ); -static void ClearEquinox( AstSkyFrame *, int * ); -static void ClearNegLon( AstSkyFrame *, int * ); -static void ClearObsAlt( AstFrame *, int * ); -static void ClearObsLat( AstFrame *, int * ); -static void ClearObsLon( AstFrame *, int * ); -static void ClearProjection( AstSkyFrame *, int * ); -static void ClearSystem( AstFrame *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void Intersect( AstFrame *, const double[2], const double[2], const double[2], const double[2], double[2], int * ); -static void LineOffset( AstFrame *, AstLineDef *, double, double, double[2], int * ); -static void MatchAxesX( AstFrame *, AstFrame *, int *, int * ); -static void Norm( AstFrame *, double[], int * ); -static void NormBox( AstFrame *, double[], double[], AstMapping *, int * ); -static void Offset( AstFrame *, const double[], const double[], double, double[], int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void Resolve( AstFrame *, const double [], const double [], const double [], double [], double *, double *, int * ); -static void SetAsTime( AstSkyFrame *, int, int, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SetDtai( AstFrame *, double, int * ); -static void SetDut1( AstFrame *, double, int * ); -static void SetEquinox( AstSkyFrame *, double, int * ); -static void SetNegLon( AstSkyFrame *, int, int * ); -static void SetObsAlt( AstFrame *, double, int * ); -static void SetObsLat( AstFrame *, double, int * ); -static void SetObsLon( AstFrame *, double, int * ); -static void SetProjection( AstSkyFrame *, const char *, int * ); -static void SetSystem( AstFrame *, AstSystemType, int * ); -static void Shapp( double, double *, double *, double, double *, int * ); -static void Shcal( double, double, double, double *, double *, int * ); -static void VerifyMSMAttrs( AstSkyFrame *, AstSkyFrame *, int, const char *, const char *, int * ); - -static double GetSkyRef( AstSkyFrame *, int, int * ); -static int TestSkyRef( AstSkyFrame *, int, int * ); -static void SetSkyRef( AstSkyFrame *, int, double, int * ); -static void ClearSkyRef( AstSkyFrame *, int, int * ); - -static double GetSkyRefP( AstSkyFrame *, int, int * ); -static int TestSkyRefP( AstSkyFrame *, int, int * ); -static void SetSkyRefP( AstSkyFrame *, int, double, int * ); -static void ClearSkyRefP( AstSkyFrame *, int, int * ); - -static int GetSkyRefIs( AstSkyFrame *, int * ); -static int TestSkyRefIs( AstSkyFrame *, int * ); -static void SetSkyRefIs( AstSkyFrame *, int, int * ); -static void ClearSkyRefIs( AstSkyFrame *, int * ); - -static int GetAlignOffset( AstSkyFrame *, int * ); -static int TestAlignOffset( AstSkyFrame *, int * ); -static void SetAlignOffset( AstSkyFrame *, int, int * ); -static void ClearAlignOffset( AstSkyFrame *, int * ); - -static double GetSkyTol( AstSkyFrame *, int * ); -static int TestSkyTol( AstSkyFrame *, int * ); -static void SetSkyTol( AstSkyFrame *, double, int * ); -static void ClearSkyTol( AstSkyFrame *, int * ); - -/* Member functions. */ -/* ================= */ -static double Angle( AstFrame *this_frame, const double a[], - const double b[], const double c[], int *status ) { -/* -* Name: -* Angle - -* Purpose: -* Calculate the angle subtended by two points at a third point. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double Angle( AstFrame *this_frame, const double a[], -* const double b[], const double c[], int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astAngle method -* inherited from the Frame class). - -* Description: -* This function finds the angle at point B between the line -* joining points A and B, and the line joining points C -* and B. These lines will in fact be geodesic curves (great circles). - -* Parameters: -* this -* Pointer to the SkyFrame. -* a -* An array of double, with one element for each SkyFrame axis, -* containing the coordinates of the first point. -* b -* An array of double, with one element for each SkyFrame axis, -* containing the coordinates of the second point. -* c -* An array of double, with one element for each SkyFrame axis, -* containing the coordinates of the third point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The angle in radians, from the line AB to the line CB, in -* the range $\pm \pi$ with positive rotation is in the same sense -* as rotation from axis 2 to axis 1. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input coordinates has this value. -* - A "bad" value will also be returned if points A and B are -* co-incident, or if points B and C are co-incident. -* - A "bad" value will also be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - const int *perm; /* Axis permutation array */ - double aa[ 2 ]; /* Permuted a coordinates */ - double anga; /* Angle from north to the line BA */ - double angc; /* Angle from north to the line BC */ - double bb[ 2 ]; /* Permuted b coordinates */ - double cc[ 2 ]; /* Permuted c coordinates */ - double result; /* Value to return */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( astOK ) { - -/* Check that all supplied coordinates are OK. */ - if ( ( a[ 0 ] != AST__BAD ) && ( a[ 1 ] != AST__BAD ) && - ( b[ 0 ] != AST__BAD ) && ( b[ 1 ] != AST__BAD ) && - ( c[ 0 ] != AST__BAD ) && ( c[ 1 ] != AST__BAD ) ) { - -/* Apply the axis permutation array to obtain the coordinates of the - three points in the required (longitude,latitude) order. */ - aa[ perm[ 0 ] ] = a[ 0 ]; - aa[ perm[ 1 ] ] = a[ 1 ]; - bb[ perm[ 0 ] ] = b[ 0 ]; - bb[ perm[ 1 ] ] = b[ 1 ]; - cc[ perm[ 0 ] ] = c[ 0 ]; - cc[ perm[ 1 ] ] = c[ 1 ]; - -/* Check that A and B are not co-incident. */ - if( aa[ 0 ] != bb[ 0 ] || aa[ 1 ] != bb[ 1 ] ) { - -/* Check that C and B are not co-incident. */ - if( cc[ 0 ] != bb[ 0 ] || cc[ 1 ] != bb[ 1 ] ) { - -/* Find the angle from north to the line BA. */ - anga = palDbear( bb[ 0 ], bb[ 1 ], aa[ 0 ], aa[ 1 ] ); - -/* Find the angle from north to the line BC. */ - angc = palDbear( bb[ 0 ], bb[ 1 ], cc[ 0 ], cc[ 1 ] ); - -/* Find the difference. */ - result = angc - anga; - -/* This value is the angle from north, but we want the angle from axis 2. - If the axes have been swapped so that axis 2 is actually the longitude - axis, then we need to correct this result. */ - if( perm[ 0 ] != 0 ) result = piby2 - result; - -/* Fold the result into the range +/- PI. */ - result = palDrange( result ); - } - } - } - } - -/* Return the result. */ - return result; -} - -static double CalcLAST( AstSkyFrame *this, double epoch, double obslon, - double obslat, double obsalt, double dut1, double dtai, - int *status ) { -/* -* Name: -* CalcLAST - -* Purpose: -* Calculate the Local Appearent Sidereal Time for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double CalcLAST( AstSkyFrame *this, double epoch, double obslon, -* double obslat, double obsalt, double dut1, double dtai, -* int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function calculates and returns the Local Apparent Sidereal Time -* at the given epoch, etc. - -* Parameters: -* this -* Pointer to the SkyFrame. -* epoch -* The epoch (MJD). -* obslon -* Observatory geodetic longitude (radians) -* obslat -* Observatory geodetic latitude (radians) -* obsalt -* Observatory geodetic altitude (metres) -* dut1 -* The UT1-UTC correction, in seconds. -* dtai -* The TAI-UTC correction, in seconds. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Local Apparent Sidereal Time, in radians. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstFrameSet *fs; /* Mapping from TDB offset to LAST offset */ - double epoch0; /* Supplied epoch value */ - double result; /* Returned LAST value */ - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* See if the required LAST value can be determined from the cached LAST - values in the SkyFrame virtual function table. */ - result = GetCachedLAST( this, epoch, obslon, obslat, obsalt, dut1, dtai, - status ); - -/* If not, we do an exact calculation from scratch. */ - if( result == AST__BAD ) { - -/* If not yet done, create two TimeFrames. Note, this is done here - rather than in astInitSkyFrameVtab in order to avoid infinite vtab - initialisation loops (caused by the TimeFrame class containing a - static SkyFrame). */ - if( ! tdbframe ) { - astBeginPM; - tdbframe = astTimeFrame( "system=mjd,timescale=tdb", status ); - lastframe = astTimeFrame( "system=mjd,timescale=last", status ); - astEndPM; - } - -/* For better accuracy, use this integer part of the epoch as the origin of - the two TimeFrames. */ - astSetTimeOrigin( tdbframe, (int) epoch ); - astSetTimeOrigin( lastframe, (int) epoch ); - -/* Convert the absolute Epoch value to an offset from the above origin. */ - epoch0 = epoch; - epoch -= (int) epoch; - -/* Store the observers position in the two TimeFrames. */ - astSetObsLon( tdbframe, obslon ); - astSetObsLon( lastframe, obslon ); - - astSetObsLat( tdbframe, obslat ); - astSetObsLat( lastframe, obslat ); - - astSetObsAlt( tdbframe, obsalt ); - astSetObsAlt( lastframe, obsalt ); - -/* Store the DUT1 value. */ - astSetDut1( tdbframe, dut1 ); - astSetDut1( lastframe, dut1 ); - -/* Store the DTAI value. */ - if ( dtai == AST__BAD ) { - astClearDtai( tdbframe ); - astClearDtai( lastframe ); - } - else { - astSetDtai( tdbframe, dtai ); - astSetDtai( lastframe, dtai ); - } - -/* Get the conversion from tdb mjd offset to last mjd offset. */ - fs = astConvert( tdbframe, lastframe, "" ); - -/* Use it to transform the SkyFrame Epoch from TDB offset to LAST offset. */ - astTran1( fs, 1, &epoch, 1, &epoch ); - fs = astAnnul( fs ); - -/* Convert the LAST offset from days to radians. */ - result = ( epoch - (int) epoch )*2*AST__DPI; - -/* Cache the new LAST value in the SkyFrame virtual function table. */ - SetCachedLAST( this, result, epoch0, obslon, obslat, obsalt, dut1, dtai, - status ); - } - -/* Return the required LAST value. */ - return result; -} - -static void ClearAsTime( AstSkyFrame *this, int axis, int *status ) { -/* -* Name: -* ClearAsTime - -* Purpose: -* Clear the value of the AsTime attribute for a SkyFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void ClearAsTime( AstSkyFrame *this, int axis, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function clears any value that has been set for the AsTime -* attribute for a specified axis of a SkyFrame. This attribute indicates -* whether axis values should be formatted as times (as opposed to angles) -* by default. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Index of the axis for which the value is to be cleared (zero based). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astClearAsTime" ); - -/* Obtain a pointer to the Axis object. */ - ax = astGetAxis( this, axis ); - -/* If the Axis is a SkyAxis, clear the AsTime attribute (if it is not a - SkyAxis, it will not have this attribute anyway). */ - if ( astIsASkyAxis( ax ) ) astClearAxisAsTime( ax ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astClearAttrib protected -* method inherited from the Frame class). - -* Description: -* This function clears the value of a specified attribute for a -* SkyFrame, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the SkyFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - int axis; /* SkyFrame axis number */ - int len; /* Length of attrib string */ - int nc; /* No. characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* AsTime(axis). */ -/* ------------- */ - if ( nc = 0, - ( 1 == astSscanf( attrib, "astime(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearAsTime( this, axis - 1 ); - -/* Equinox. */ -/* -------- */ - } else if ( !strcmp( attrib, "equinox" ) ) { - astClearEquinox( this ); - -/* NegLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "neglon" ) ) { - astClearNegLon( this ); - -/* Projection. */ -/* ----------- */ - } else if ( !strcmp( attrib, "projection" ) ) { - astClearProjection( this ); - -/* SkyRef. */ -/* ------- */ - } else if ( !strcmp( attrib, "skyref" ) ) { - astClearSkyRef( this, 0 ); - astClearSkyRef( this, 1 ); - -/* SkyTol. */ -/* ------- */ - } else if ( !strcmp( attrib, "skytol" ) ) { - astClearSkyTol( this ); - -/* SkyRef(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "skyref(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearSkyRef( this, axis - 1 ); - -/* SkyRefP. */ -/* -------- */ - } else if ( !strcmp( attrib, "skyrefp" ) ) { - astClearSkyRefP( this, 0 ); - astClearSkyRefP( this, 1 ); - -/* SkyRefP(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "skyrefp(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearSkyRefP( this, axis - 1 ); - -/* SkyRefIs. */ -/* --------- */ - } else if ( !strcmp( attrib, "skyrefis" ) ) { - astClearSkyRefIs( this ); - -/* AlignOffset. */ -/* ------------ */ - } else if ( !strcmp( attrib, "alignoffset" ) ) { - astClearAlignOffset( this ); - -/* If the name was not recognised, test if it matches any of the - read-only attributes of this class. If it does, then report an - error. */ - } else if ( !strncmp( attrib, "islataxis", 9 ) || - !strncmp( attrib, "islonaxis", 9 ) || - !strcmp( attrib, "lataxis" ) || - !strcmp( attrib, "lonaxis" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearDtai( AstFrame *this, int *status ) { -/* -* Name: -* ClearDtai - -* Purpose: -* Clear the value of the Dtai attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void ClearDtai( AstFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astClearDtai method -* inherited from the Frame class). - -* Description: -* This function clears the Dtai value and updates the LAST value -* stored in the SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Note the original value */ - orig = astGetDtai( this ); - -/* Invoke the parent method to clear the Frame Dtai */ - (*parent_cleardtai)( this, status ); - -/* If the DTAI value has changed significantly, indicate that the LAST value - will need to be re-calculated when it is next needed. */ - if( ! EQUAL( orig, astGetDtai( this ), 1.0E-6 ) ) { - ( (AstSkyFrame *) this )->last = AST__BAD; - ( (AstSkyFrame *) this )->eplast = AST__BAD; - ( (AstSkyFrame *) this )->klast = AST__BAD; - } -} - -static void ClearDut1( AstFrame *this, int *status ) { -/* -* Name: -* ClearDut1 - -* Purpose: -* Clear the value of the Dut1 attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void ClearDut1( AstFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astClearDut1 method -* inherited from the Frame class). - -* Description: -* This function clears the Dut1 value and updates the LAST value -* stored in the SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Note the original value */ - orig = astGetDut1( this ); - -/* Invoke the parent method to clear the Frame Dut1 */ - (*parent_cleardut1)( this, status ); - -/* If the DUT1 value has changed significantly, indicate that the LAST value - will need to be re-calculated when it is next needed. */ - if( fabs( orig - astGetDut1( this ) ) > 1.0E-6 ) { - ( (AstSkyFrame *) this )->last = AST__BAD; - ( (AstSkyFrame *) this )->eplast = AST__BAD; - ( (AstSkyFrame *) this )->klast = AST__BAD; - } -} - -static void ClearObsAlt( AstFrame *this, int *status ) { -/* -* Name: -* ClearObsAlt - -* Purpose: -* Clear the value of the ObsAlt attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void ClearObsAlt( AstFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astClearObsAlt method -* inherited from the Frame class). - -* Description: -* This function clears the ObsAlt value. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Note the original value */ - orig = astGetObsAlt( this ); - -/* Invoke the parent method to clear the Frame ObsAlt. */ - (*parent_clearobsalt)( this, status ); - -/* If the altitude has changed significantly, indicate that the LAST value - and magnitude of the diurnal aberration vector will need to be - re-calculated when next needed. */ - if( fabs( orig - astGetObsAlt( this ) ) > 0.001 ) { - ( (AstSkyFrame *) this )->last = AST__BAD; - ( (AstSkyFrame *) this )->eplast = AST__BAD; - ( (AstSkyFrame *) this )->klast = AST__BAD; - ( (AstSkyFrame *) this )->diurab = AST__BAD; - } -} - -static void ClearObsLat( AstFrame *this, int *status ) { -/* -* Name: -* ClearObsLat - -* Purpose: -* Clear the value of the ObsLat attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void ClearObsLat( AstFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astClearObsLat method -* inherited from the Frame class). - -* Description: -* This function clears the ObsLat value. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Note the original value */ - orig = astGetObsLat( this ); - -/* Invoke the parent method to clear the Frame ObsLat. */ - (*parent_clearobslat)( this, status ); - -/* If the altitude has changed significantly, indicate that the LAST value - and magnitude of the diurnal aberration vector will need to be - re-calculated when next needed. */ - if( fabs( orig - astGetObsLat( this ) ) > 1.0E-8 ) { - ( (AstSkyFrame *) this )->last = AST__BAD; - ( (AstSkyFrame *) this )->eplast = AST__BAD; - ( (AstSkyFrame *) this )->klast = AST__BAD; - ( (AstSkyFrame *) this )->diurab = AST__BAD; - } -} - -static void ClearObsLon( AstFrame *this, int *status ) { -/* -* Name: -* ClearObsLon - -* Purpose: -* Clear the value of the ObsLon attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void ClearObsLon( AstFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astClearObsLon method -* inherited from the Frame class). - -* Description: -* This function clears the ObsLon value. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Note the original value */ - orig = astGetObsLon( this ); - -/* Invoke the parent method to clear the Frame ObsLon. */ - (*parent_clearobslon)( this, status ); - -/* If the longitude has changed significantly, indicate that the LAST value - will need to be re-calculated when it is next needed. */ - if( fabs( orig - astGetObsLon( this ) ) > 1.0E-8 ) { - ( (AstSkyFrame *) this )->last = AST__BAD; - ( (AstSkyFrame *) this )->eplast = AST__BAD; - ( (AstSkyFrame *) this )->klast = AST__BAD; - } -} - -static void ClearSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearSystem - -* Purpose: -* Clear the System attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void ClearSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astClearSystem protected -* method inherited from the Frame class). - -* Description: -* This function clears the System attribute for a SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrameSet *fs; /* FrameSet to be used as the Mapping */ - AstSkyFrame *sfrm; /* Copy of original SkyFrame */ - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - double xin[ 2 ]; /* Axis 0 values */ - double yin[ 2 ]; /* Axis 1 values */ - double xout[ 2 ]; /* Axis 0 values */ - double yout[ 2 ]; /* Axis 1 values */ - int skyref_set; /* Is either SkyRef attribute set? */ - int skyrefp_set; /* Is either SkyRefP attribute set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* See if either the SkyRef or SkyRefP attribute is set. */ - skyref_set = astTestSkyRef( this, 0 ) || astTestSkyRef( this, 1 ); - skyrefp_set = astTestSkyRefP( this, 0 ) || astTestSkyRefP( this, 1 ); - -/* If so, we will need to transform their values into the new coordinate - system. Save a copy of the SkyFrame with its original System value. */ - sfrm = ( skyref_set || skyrefp_set )?astCopy( this ):NULL; - -/* Use the parent method to clear the System value. */ - (*parent_clearsystem)( this_frame, status ); - -/* Now modify the SkyRef and SkyRefP attributes if necessary. */ - if( sfrm ) { - -/* Save the SkyRef and SkyRefP values. */ - xin[ 0 ] = astGetSkyRef( sfrm, 0 ); - xin[ 1 ] = astGetSkyRefP( sfrm, 0 ); - yin[ 0 ] = astGetSkyRef( sfrm, 1 ); - yin[ 1 ] = astGetSkyRefP( sfrm, 1 ); - -/* Clear the SkyRef values to avoid infinite recursion in the following - call to astConvert. */ - if( skyref_set ) { - astClearSkyRef( sfrm, 0 ); - astClearSkyRef( sfrm, 1 ); - astClearSkyRef( this, 0 ); - astClearSkyRef( this, 1 ); - } - -/* Get the Mapping from the original System to the default System. Invoking - astConvert will recursively invoke ClearSystem again. This is why we need - to be careful to ensure that SkyRef is cleared above - doing so ensure - we do not end up with infinite recursion. */ - fs = astConvert( sfrm, this, "" ); - -/* Check the Mapping was found. */ - if( fs ) { - -/* Use the Mapping to find the SkyRef and SkyRefP positions in the default - coordinate system. */ - astTran2( fs, 2, xin, yin, 1, xout, yout ); - -/* Store the values as required. */ - if( skyref_set ) { - astSetSkyRef( this, 0, xout[ 0 ] ); - astSetSkyRef( this, 1, yout[ 0 ] ); - } - - if( skyrefp_set ) { - astSetSkyRefP( this, 0, xout[ 1 ] ); - astSetSkyRefP( this, 1, yout[ 1 ] ); - } - -/* Free resources. */ - fs = astAnnul( fs ); - -/* If the Mapping is not defined, we cannot convert the SkyRef or SkyRefP - positions in the new Frame so clear them. */ - } else { - if( skyref_set ) { - astClearSkyRef( this, 0 ); - astClearSkyRef( this, 1 ); - } - if( skyrefp_set ) { - astClearSkyRefP( this, 0 ); - astClearSkyRefP( this, 1 ); - } - } - -/* Free resources. */ - sfrm = astAnnul( sfrm ); - } -} - -static double Distance( AstFrame *this_frame, - const double point1[], const double point2[], int *status ) { -/* -* Name: -* Distance - -* Purpose: -* Calculate the distance between two points. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double Distance( AstFrame *this, -* const double point1[], const double point2[], int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astDistance method -* inherited from the Frame class). - -* Description: -* This function finds the distance between two points whose -* SkyFrame coordinates are given. The distance calculated is that -* along the geodesic curve (i.e. great circle) that joins the two -* points. - -* Parameters: -* this -* Pointer to the SkyFrame. -* point1 -* An array of double, with one element for each SkyFrame axis, -* containing the coordinates of the first point. -* point2 -* An array of double, with one element for each SkyFrame axis, -* containing the coordinates of the second point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The distance between the two points, in radians. - -* Notes: -* - This function will return a "bad" result value (AST__BAD) if -* any of the input coordinates has this value. -* - A "bad" value will also be returned if this function is -* invoked with the AST error status set or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - const int *perm; /* Axis permutation array */ - double p1[ 2 ]; /* Permuted point1 coordinates */ - double p2[ 2 ]; /* Permuted point2 coordinates */ - double result; /* Value to return */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( astOK ) { - -/* Check that all supplied coordinates are OK. */ - if ( ( point1[ 0 ] != AST__BAD ) && ( point1[ 1 ] != AST__BAD ) && - ( point2[ 0 ] != AST__BAD ) && ( point2[ 1 ] != AST__BAD ) ) { - -/* Apply the axis permutation array to obtain the coordinates of the - two points in the required (longitude,latitude) order. */ - p1[ perm[ 0 ] ] = point1[ 0 ]; - p1[ perm[ 1 ] ] = point1[ 1 ]; - p2[ perm[ 0 ] ] = point2[ 0 ]; - p2[ perm[ 1 ] ] = point2[ 1 ]; - -/* Calculate the great circle distance between the points in radians. */ - result = palDsep( p1[ 0 ], p1[ 1 ], p2[ 0 ], p2[ 1 ] ); - } - } - -/* Return the result. */ - return result; -} - -static const char *Format( AstFrame *this_frame, int axis, double value, int *status ) { -/* -* Name: -* Format - -* Purpose: -* Format a coordinate value for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* const char *Format( AstFrame *this, int axis, double value, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astFormat method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to a string containing the formatted -* (character) version of a coordinate value for a SkyFrame axis. The -* formatting applied is that specified by a previous invocation of the -* astSetFormat method. A suitable default format is applied if necessary, -* and this may depend on which sky coordinate system the SkyFrame -* describes. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* The number of the axis (zero-based) for which formatting is to be -* performed. -* value -* The coordinate value to be formatted, in radians. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a null-terminated string containing the formatted value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const char *result; /* Pointer value to return */ - int format_set; /* Format attribute set? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astFormat" ); - -/* Determine if a Format value has been set for the axis and set a temporary - value if it has not. Use the GetFormat member function for this class - together with member functions inherited from the parent class (rather than - using the object's methods directly) because if any of these methods have - been over-ridden by a derived class the Format string syntax may no longer - be compatible with this class. */ - format_set = (*parent_testformat)( this_frame, axis, status ); - if ( !format_set ) { - (*parent_setformat)( this_frame, axis, GetFormat( this_frame, axis, status ), status ); - } - -/* Use the Format member function inherited from the parent class to format the - value and return a pointer to the resulting string. */ - result = (*parent_format)( this_frame, axis, value, status ); - -/* If necessary, clear any temporary Format value that was set above. */ - if ( !format_set ) (*parent_clearformat)( this_frame, axis, status ); - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static AstPointSet *FrameGrid( AstFrame *this_object, int size, const double *lbnd, - const double *ubnd, int *status ){ -/* -* Name: -* FrameGrid - -* Purpose: -* Return a grid of points covering a rectangular area of a Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* AstPointSet *FrameGrid( AstFrame *this_frame, int size, -* const double *lbnd, const double *ubnd, -* int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astFrameGrid -* method inherited from the Frame class). - -* Description: -* This function returns a PointSet containing positions spread -* approximately evenly throughtout a specified rectangular area of -* the Frame. - -* Parameters: -* this -* Pointer to the Frame. -* size -* The preferred number of points in the returned PointSet. The -* actual number of points in the returned PointSet may be -* different, but an attempt is made to stick reasonably closely to -* the supplied value. -* lbnd -* Pointer to an array holding the lower bound of the rectangular -* area on each Frame axis. The array should have one element for -* each Frame axis. -* ubnd -* Pointer to an array holding the upper bound of the rectangular -* area on each Frame axis. The array should have one element for -* each Frame axis. - -* Returned Value: -* A pointer to a new PointSet holding the grid of points. - -* Notes: -* - A NULL pointer is returned if an error occurs. -*/ - -/* Local Variables: */ - AstPointSet *result; - AstSkyFrame *this; - double **ptr; - double box_area; - double cl; - double dlon; - double hilat; - double hilon; - double inclon; - double lat_size; - double lat; - double lon; - double lolon; - double lon_size; - double lolat; - double totlen; - int ilat; - int ilon; - int imer; - int ip; - int ipar; - int ipmax; - int nmer; - int npar; - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_object; - -/* Get the zero-based indices of the longitude and latitude axes. */ - ilon = astGetLonAxis( this ); - ilat = 1 - ilon; - -/* The latitude bounds may not be the right way round so check for it. */ - if( lbnd[ ilat ] <= ubnd[ ilat ] ) { - lolat = lbnd[ ilat ]; - hilat = ubnd[ ilat ]; - } else { - lolat = ubnd[ ilat ]; - hilat = lbnd[ ilat ]; - } - -/* Check all bounds are good. Also check the size is positive. */ - lolon = lbnd[ ilon ]; - hilon = ubnd[ ilon ]; - if( size > 0 && lolat != AST__BAD && hilat != AST__BAD && - lolon != AST__BAD && hilon != AST__BAD ) { - -/* Ensure the longitude bounds are in the range 0-2PI. */ - lolon = palDranrm( lolon ); - hilon = palDranrm( hilon ); - -/* If the upper longitude limit is less than the lower limit, add 2.PI */ - if( hilon <= lolon && - ubnd[ ilon ] != lbnd[ ilon ] ) hilon += 2*AST__DPI; - -/* Get the total area of the box in steradians. */ - dlon = hilon - lolon; - box_area = fabs( dlon*( sin( hilat ) - sin( lolat ) ) ); - -/* Get the nominal size of a square grid cell, in radians. */ - lat_size = sqrt( box_area/size ); - -/* How many parallels should we use to cover the box? Ensure we use at - least two. These parallels pass through the centre of the grid cells. */ - npar = (int)( 0.5 + ( hilat - lolat )/lat_size ); - if( npar < 2 ) npar = 2; - -/* Find the actual sample size implied by this number of parallels. */ - lat_size = ( hilat - lolat )/npar; - -/* Find the total arc length of the parallels. */ - totlen = 0.0; - lat = lolat + 0.5*lat_size; - for( ipar = 0; ipar < npar; ipar++ ) { - totlen += dlon*cos( lat ); - lat += lat_size; - } - -/* If we space "size" samples evenly over this total arc-length, what is - the arc-distance between samples? */ - lon_size = totlen/size; - -/* Create a PointSet in which to store the grid. Make it bigger than - necessary in order to leave room for extra samples caused by integer - truncation. */ - ipmax = 2*size; - result = astPointSet( ipmax, 2, " ", status ); - ptr = astGetPoints( result ); - if( astOK ) { - -/* Loop over all the parallels. */ - ip = 0; - lat = lolat + 0.5*lat_size; - for( ipar = 0; ipar < npar; ipar++ ) { - -/* Get the longitude increment between samples on this parallel. */ - cl = cos( lat ); - inclon = ( cl != 0.0 ) ? lon_size/cl : 0.0; - -/* Get the number of longitude samples for this parallel. Reduce it if - it would extend beyond the end of the PointSet. */ - nmer = dlon/inclon; - if( ip + nmer >= ipmax ) nmer = ipmax - ip; - -/* Adjust the longitude increment to take up any slack caused by the - above integer division. */ - inclon = dlon/nmer; - -/* Produce the samples for the current parallel. */ - lon = lolon + 0.5*inclon; - for( imer = 0; imer < nmer; imer++ ) { - ptr[ ilon ][ ip ] = lon; - ptr[ ilat ][ ip ] = lat; - - lon += inclon; - ip++; - } - -/* Get the latitude on the next parallel. */ - lat += lat_size; - } - -/* Truncate the PointSet to exclude unused elements at the end. */ - astSetNpoint( result, ip ); - } - -/* Report error if supplied values were bad. */ - } else if( astOK ) { - if( size < 1 ) { - astError( AST__ATTIN, "astFrameGrid(%s): The supplied grid " - "size (%d) is invalid (programming error).", - status, astGetClass( this ), size ); - } else { - astError( AST__ATTIN, "astFrameGrid(%s): One of more of the " - "supplied bounds is AST__BAD (programming error).", - status, astGetClass( this ) ); - } - } - -/* Annul the returned PointSet if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the PointSet holding the grid. */ - return result; -} - -static double Gap( AstFrame *this_frame, int axis, double gap, int *ntick, int *status ) { -/* -* Name: -* Gap - -* Purpose: -* Find a "nice" gap for tabulating SkyFrame axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double Gap( AstFrame *this, int axis, double gap, int *ntick, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astGap method -* inherited from the Frame class). - -* Description: -* This function returns a gap size which produces a nicely spaced -* series of formatted values for a SkyFrame axis, the returned gap -* size being as close as possible to the supplied target gap -* size. It also returns a convenient number of divisions into -* which the gap can be divided. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* The number of the axis (zero-based) for which a gap is to be found. -* gap -* The target gap size. -* ntick -* Address of an int in which to return a convenient number of -* divisions into which the gap can be divided. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The nice gap size. - -* Notes: -* - A value of zero is returned if the target gap size is zero. -* - A negative gap size is returned if the supplied gap size is negative. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - double result; /* Gap value to return */ - int format_set; /* Format attribute set? */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astGap" ); - -/* Determine if a Format value has been set for the axis and set a - temporary value if it has not. Use the GetFormat member function - for this class together with member functions inherited from the - parent class (rather than using the object's methods directly) - because if any of these methods have been over-ridden by a derived - class the Format string syntax may no longer be compatible with - this class. */ - format_set = (*parent_testformat)( this_frame, axis, status ); - if ( !format_set ) { - (*parent_setformat)( this_frame, axis, GetFormat( this_frame, axis, status ), status ); - } - -/* Use the Gap member function inherited from the parent class to find - the gap size. */ - result = (*parent_gap)( this_frame, axis, gap, ntick, status ); - -/* If necessary, clear any temporary Format value that was set above. */ - if ( !format_set ) (*parent_clearformat)( this_frame, axis, status ); - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied SkyFrame, -* in bytes. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the SkyFrame structure. */ - this = (AstSkyFrame *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astTSizeOf( this->projection ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetActiveUnit - -* Purpose: -* Obtain the value of the ActiveUnit flag for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int GetActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function returns the value of the ActiveUnit flag for a -* SkyFrame, which is always 0. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to use for the ActiveUnit flag (0). - -*/ - return 0; -} - -static int GetAsTime( AstSkyFrame *this, int axis, int *status ) { -/* -* Name: -* GetAsTime - -* Purpose: -* Obtain the value of the AsTime attribute for a SkyFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int GetAsTime( AstSkyFrame *this, int axis, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function returns the boolean value of the AsTime attribute for a -* specified axis of a SkyFrame. This value indicates whether axis values -* should be formatted as times (as opposed to angles) by default. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Index of the axis for which information is required (zero based). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero or one, according to the setting of the AsTime attribute (if no -* value has previously been set, a suitable default is returned). - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - int axis_p; /* Permuted axis index */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise. */ - result = 0; - -/* Validate and permute the axis index. */ - axis_p = astValidateAxis( this, axis, 1, "astGetAsTime" ); - -/* Obtain a pointer to the required Axis object. */ - ax = astGetAxis( this, axis ); - -/* Determine if the AsTime attribute has been set for the axis (this can only - be the case if the object is a SkyAxis). If the attribute is set, obtain its - value. */ - if ( astIsASkyAxis( ax ) && astTestAxisAsTime( ax ) ) { - result = astGetAxisAsTime( ax ); - -/* Otherwise, check which (permuted) axis is involved. Only the first - (longitude) axis may be displayed as a time by default. */ - } else if ( axis_p == 0 ) { - -/* Test for those coordinate systems which normally have their longitude axes - displayed as times (basically, those that involve the Earth's equator) and - set the returned value appropriately. */ - result = IsEquatorial( astGetSystem( this ), status ); - } - -/* Annul the Axis object pointer. */ - ax = astAnnul( ax ); - -/* Return the result. */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astGetAttrib -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a SkyFrame, formatted as a character string. - -* Parameters: -* this -* Pointer to the SkyFrame. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - The returned string pointer may point at memory allocated -* within the SkyFrame, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the SkyFrame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const char *cval; /* Pointer to character attribute value */ - const char *result; /* Pointer value to return */ - double dval; /* Floating point attribute value */ - double equinox; /* Equinox attribute value (as MJD) */ - int as_time; /* AsTime attribute value */ - int axis; /* SkyFrame axis number */ - int ival; /* Integer attribute value */ - int len; /* Length of attrib string */ - int nc; /* No. characters read by astSscanf */ - int neglon; /* Display long. values as [-pi,pi]? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* AsTime(axis). */ -/* ------------- */ - if ( nc = 0, - ( 1 == astSscanf( attrib, "astime(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - as_time = astGetAsTime( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", as_time ); - result = getattrib_buff; - } - -/* Equinox. */ -/* -------- */ - } else if ( !strcmp( attrib, "equinox" ) ) { - equinox = astGetEquinox( this ); - if ( astOK ) { - -/* Format the Equinox as decimal years. Use a Besselian epoch if it - will be less than 1984.0, otherwise use a Julian epoch. */ - result = astFmtDecimalYr( ( equinox < palEpj2d( 1984.0 ) ) ? - palEpb( equinox ) : palEpj( equinox ), - AST__DBL_DIG ); - } - -/* IsLatAxis(axis) */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "islataxis(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = astGetIsLatAxis( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* IsLonAxis(axis) */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "islonaxis(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = astGetIsLonAxis( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LatAxis */ -/* -------- */ - } else if ( !strcmp( attrib, "lataxis" ) ) { - axis = astGetLatAxis( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", axis + 1 ); - result = getattrib_buff; - } - -/* LonAxis */ -/* -------- */ - } else if ( !strcmp( attrib, "lonaxis" ) ) { - axis = astGetLonAxis( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", axis + 1 ); - result = getattrib_buff; - } - -/* NegLon */ -/* ------ */ - } else if ( !strcmp( attrib, "neglon" ) ) { - neglon = astGetNegLon( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", neglon ); - result = getattrib_buff; - } - -/* SkyTol */ -/* ------ */ - } else if ( !strcmp( attrib, "skytol" ) ) { - dval = astGetSkyTol( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Projection. */ -/* ----------- */ - } else if ( !strcmp( attrib, "projection" ) ) { - result = astGetProjection( this ); - -/* SkyRef. */ -/* ------- */ - } else if ( !strcmp( attrib, "skyref" ) ) { - cval = astFormat( this, 0, astGetSkyRef( this, 0 ) ); - if ( astOK ) { - nc = sprintf( getattrib_buff, "%s, ", cval ); - cval = astFormat( this, 1, astGetSkyRef( this, 1 ) ); - if ( astOK ) { - (void) sprintf( getattrib_buff + nc, "%s", cval ); - result = getattrib_buff; - } - } - -/* SkyRef(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "skyref(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetSkyRef( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* SkyRefP. */ -/* -------- */ - } else if ( !strcmp( attrib, "skyrefp" ) ) { - cval = astFormat( this, 0, astGetSkyRefP( this, 0 ) ); - if ( astOK ) { - nc = sprintf( getattrib_buff, "%s, ", cval ); - cval = astFormat( this, 1, astGetSkyRefP( this, 1 ) ); - if ( astOK ) { - (void) sprintf( getattrib_buff + nc, "%s", cval ); - result = getattrib_buff; - } - } - -/* SkyRefP(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "skyrefp(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetSkyRefP( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* SkyRefIs. */ -/* --------- */ - } else if ( !strcmp( attrib, "skyrefis" ) ) { - ival = astGetSkyRefIs( this ); - if ( astOK ) { - if( ival == AST__POLE_REF ){ - result = POLE_STRING; - } else if( ival == AST__IGNORED_REF ){ - result = IGNORED_STRING; - } else { - result = ORIGIN_STRING; - } - } - -/* AlignOffset */ -/* ----------- */ - } else if ( !strcmp( attrib, "alignoffset" ) ) { - ival = astGetAlignOffset( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static int GetDirection( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetDirection - -* Purpose: -* Obtain the value of the Direction attribute for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int GetDirection( AstFrame *this_frame, int axis, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetDirection method inherited -* from the Frame class). - -* Description: -* This function returns the value of the Direction attribute for a -* specified axis of a SkyFrame. A suitable default value is returned if no -* Direction value has previously been set. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero or one, depending on the Direction attribute value. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - int axis_p; /* Permuted axis index */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise. */ - result = 0; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Validate and permute the axis index. */ - axis_p = astValidateAxis( this, axis, 1, "astGetDirection" ); - -/* Check if a value has been set for the axis Direction attribute. If so, - obtain its value. */ - if ( astTestDirection( this, axis ) ) { - result = (*parent_getdirection)( this_frame, axis, status ); - -/* Otherwise, we will generate a default Direction value. Currently all - systems supported by SkyFrame are left handed, so all longitude axes - are reversed and all latitude axes are not reversed. */ - } else if( axis_p == 0 ) { - result = 0; - } else { - result = 1; - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static double GetBottom( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetBottom - -* Purpose: -* Obtain the value of the Bottom attribute for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double GetBottom( AstFrame *this_frame, int axis, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetBottom method inherited -* from the Frame class). - -* Description: -* This function returns the value of the Bottom attribute for a -* specified axis of a SkyFrame. A suitable default value is returned if no -* value has previously been set. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Bottom value to use. - -* Notes: -* - A value of -DBL_MAX will be returned if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - int axis_p; /* Permuted axis index */ - double result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return -DBL_MAX; - -/* Initialise. */ - result = -DBL_MAX; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Validate and permute the axis index. */ - axis_p = astValidateAxis( this, axis, 1, "astGetBottom" ); - -/* Check if a value has been set for the axis Bottom attribute. If so, - obtain its value. */ - if ( astTestBottom( this, axis ) ) { - result = (*parent_getbottom)( this_frame, axis, status ); - -/* Otherwise, we will return a default Bottom value appropriate to the - SkyFrame class. */ - } else { - -/* If it is a latitude axis return -pi/2. */ - if( axis_p == 1 ) { - result = -piby2; - -/* If it is a longitude value return -DBL_MAX (i.e. no lower limit). */ - } else { - result = -DBL_MAX; - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -DBL_MAX; - -/* Return the result. */ - return result; -} - -static double GetCachedLAST( AstSkyFrame *this, double epoch, double obslon, - double obslat, double obsalt, double dut1, - double dtai, int *status ) { -/* -* Name: -* GetCachedLAST - -* Purpose: -* Attempt to get a LAST value from the cache in the SkyFrame vtab. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double GetCachedLAST( AstSkyFrame *this, double epoch, double obslon, -* double obslat, double obsalt, double dut1, -* double dtai, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function searches the static cache of LAST values held in the -* SkyFrame virtual function table for a value that corresponds to the -* supplied parameter values. If one is found, it is returned. -* Otherwise AST__BAD is found. - -* Parameters: -* this -* Pointer to the SkyFrame. -* epoch -* The epoch (MJD). -* obslon -* Observatory geodetic longitude (radians) -* obslat -* Observatory geodetic latitude (radians) -* obsalt -* Observatory geodetic altitude (metres) -* dut1 -* The UT1-UTC correction, in seconds. -* dtai -* The TAI-UTC correction, in seconds. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Local Apparent Sidereal Time, in radians. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - AstSkyLastTable *table; - double *ep; - double *lp; - double dep; - double result; - int ihi; - int ilo; - int itable; - int itest; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Wait until the table is not being written to by any thread. This also - prevents a thread from writing to the table whilst we are reading it. */ - LOCK_RLOCK1 - -/* Loop round every LAST table held in the vtab. Each table refers to a - different observatory position and/or DUT1 and/or DTAI value. */ - for( itable = 0; itable < nlast_tables; itable++ ) { - table = last_tables[ itable ]; - -/* See if the table refers to the given position, dut1 and dtai value, allowing - some small tolerance. */ - if( fabs( table->obslat - obslat ) < 2.0E-7 && - fabs( table->obslon - obslon ) < 2.0E-7 && - fabs( table->obsalt - obsalt ) < 1.0 && - fabs( table->dut1 - dut1 ) < 1.0E-5 && - EQUAL( table->dtai, dtai, 1.0E-5 ) ) { - -/* Get pointers to the array of epoch and corresponding LAST values in - the table. */ - ep = table->epoch; - lp = table->last; - -/* The values in the epoch array are monotonic increasing. Do a binary chop - within the table's epoch array to find the earliest entry that has a - value equal to or greater than the supplied epoch value. */ - ilo = 0; - ihi = table->nentry - 1; - while( ihi > ilo ) { - itest = ( ilo + ihi )/2; - if( ep[ itest ] >= epoch ) { - ihi = itest; - } else { - ilo = itest + 1; - } - } - -/* Get the difference between the epoch at the entry selected above and - the requested epoch. */ - dep = ep[ ilo ] - epoch; - -/* If the entry selected above is the first entry in the table, it can - only be used if it is within 0.001 second of the requested epoch. */ - if( ilo == 0 ) { - if( fabs( dep ) < 0.001/86400.0 ) { - result = lp[ 0 ]; - } - -/* If the list of epoch values contained no value that was greater than - the supplied epoch value, then we can use the last entry if - it is no more than 0.001 second away from the requested epoch. */ - } else if( dep <= 0.0 ) { - if( fabs( dep ) < 0.001/86400.0 ) { - result = lp[ ilo ]; - } - - -/* Otherwise, see if the entry selected above is sufficiently close to - its lower neighbour (i.e. closer than 0.4 days) to allow a reasonably - accurate LAST value to be determined by interpolation. */ - } else if( ep[ ilo ] - ep[ ilo - 1 ] < 0.4 ) { - ep += ilo - 1; - lp += ilo - 1; - result = *lp + ( epoch - *ep )*( lp[ 1 ] - *lp )/( ep[ 1 ] - *ep ); - -/* If the neighbouring point is too far away for interpolation to be - reliable, then we can only use the point if it is within 0.001 seconds of - the requested epoch. */ - } else if( fabs( dep ) < 0.001/86400.0 ) { - result = lp[ ilo ]; - } - -/* If we have found the right table, we do not need to look at any other - tables, so leave the table loop. */ - break; - } - } - -/* Indicate that threads may now write to the table. */ - UNLOCK_RWLOCK1 - -/* Ensure the returned value is within the range 0 - 2.PI. */ - if( result != AST__BAD ) { - while( result > 2*AST__DPI ) result -= 2*AST__DPI; - while( result < 0.0 ) result += 2*AST__DPI; - } - -/* Return the required LAST value. */ - return result; -} - -static double GetEpoch( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetEpoch - -* Purpose: -* Obtain the value of the Epoch attribute for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double GetEpoch( AstFrame *this_frame, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetEpoch method inherited -* from the Frame class). - -* Description: -* This function returns the value of the Epoch attribute for a -* SkyFrame. A suitable default value is returned if no value has -* previously been set. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Epoch value to use. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - AstSystemType system; /* System attribute */ - double result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* Initialise. */ - result = AST__BAD; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Check if a value has been set for the Epoch attribute. If so, obtain its - value. */ - if ( astTestEpoch( this ) ) { - result = (*parent_getepoch)( this_frame, status ); - -/* Otherwise, we will return a default Epoch value appropriate to the - SkyFrame class. */ - } else { - -/* Provide a default value of B1950.0 or J2000.0 depending on the System - setting. */ - system = astGetSystem( this ); - if( system == AST__FK4 || system == AST__FK4_NO_E ) { - result = palEpb2d( 1950.0 ); - } else { - result = palEpj2d( 2000.0 ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static double GetTop( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetTop - -* Purpose: -* Obtain the value of the Top attribute for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double GetTop( AstFrame *this_frame, int axis, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetTop method inherited -* from the Frame class). - -* Description: -* This function returns the value of the Top attribute for a -* specified axis of a SkyFrame. A suitable default value is returned if no -* value has previously been set. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Top value to use. - -* Notes: -* - A value of DBL_MAX will be returned if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - int axis_p; /* Permuted axis index */ - double result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return DBL_MAX; - -/* Initialise. */ - result = DBL_MAX; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Validate and permute the axis index. */ - axis_p = astValidateAxis( this, axis, 1, "astGetTop" ); - -/* Check if a value has been set for the axis Top attribute. If so, - obtain its value. */ - if ( astTestTop( this, axis ) ) { - result = (*parent_gettop)( this_frame, axis, status ); - -/* Otherwise, we will return a default Top value appropriate to the - SkyFrame class. */ - } else { - -/* If this is a latitude axis return pi/2. */ - if( axis_p == 1 ) { - result = piby2; - -/* If it is a longitude value return DBL_MAX (i.e. no upper limit). */ - } else { - result = DBL_MAX; - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = DBL_MAX; - -/* Return the result. */ - return result; -} - -static const char *GetDomain( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetDomain - -* Purpose: -* Obtain a pointer to the Domain attribute string for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* const char *GetDomain( AstFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetDomain protected -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the Domain attribute string -* for a SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a constant null-terminated string containing the -* Domain value. - -* Notes: -* - The returned pointer or the string it refers to may become -* invalid following further invocation of this function or -* modification of the SkyFrame. -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* If a Domain attribute string has been set, invoke the parent method - to obtain a pointer to it. */ - if ( astTestDomain( this ) ) { - result = (*parent_getdomain)( this_frame, status ); - -/* Otherwise, provide a pointer to a suitable default string. */ - } else { - result = "SKY"; - } - -/* Return the result. */ - return result; -} - -static const char *GetFormat( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetFormat - -* Purpose: -* Access the Format string for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* const char *GetFormat( AstFrame *this, int axis ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetFormat method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Format string for a specified axis -* of a SkyFrame. A pointer to a suitable default string is returned if no -* Format value has previously been set. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. - -* Returned Value: -* Pointer to a null-terminated character string containing the requested -* information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstAxis *ax; /* Pointer to Axis object */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const char *result; /* Pointer value to return */ - int as_time; /* Value of AsTime attribute */ - int as_time_set; /* AsTime attribute set? */ - int axis_p; /* Permuted axis index */ - int digits; /* Number of digits of precision */ - int is_latitude; /* Value of IsLatitude attribute */ - int is_latitude_set; /* IsLatitude attribute set? */ - int parent; /* Use parent method? */ - int skyaxis; /* Is the Axis a SkyAxis? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_frame); - -/* Initialise. */ - result = NULL; - as_time_set = 0; - is_latitude = 0; - is_latitude_set = 0; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Validate and permute the axis index. */ - axis_p = astValidateAxis( this, axis, 1, "astGetFormat" ); - -/* Obtain a pointer to the Axis structure. */ - ax = astGetAxis( this, axis ); - -/* Decide whether the parent astGetFormat method is able to provide the format - string we require. We must use the parent method if the Axis is not a - SkyAxis, because the syntax of the Format string would become unsuitable - for use with the Axis astFormat method if it was over-ridden here. We also - use the parent method to return a Format pointer if an explicit Format - string has already been set. */ - skyaxis = astIsASkyAxis( ax ); - parent = ( !skyaxis || (*parent_testformat)( this_frame, axis, status ) ); - -/* If neither of the above conditions apply, we may still be able to use the - parent method if the Axis (actually a SkyAxis) is required to behave as a - normal RA or DEC axis, as this is the standard behaviour provided by the - SkyAxis class. Examine the SkyFrame's System attribute to determine if its - axes should behave in this way. */ - if ( !parent ) parent = IsEquatorial( astGetSystem( this ), status ); - -/* If using the parent method and dealing with a SkyAxis, determine the - settings of any attributes that may affect the Format string. */ - if ( astOK ) { - if ( parent ) { - if ( skyaxis ) { - as_time_set = astTestAsTime( this, axis ); - is_latitude_set = astTestAxisIsLatitude( ax ); - is_latitude = astGetAxisIsLatitude( ax ); - -/* If no AsTime value is set for the axis, set a temporary value as determined - by the astGetAsTime method, which supplies suitable defaults for the axes of - a SkyFrame. */ - if ( !as_time_set ) { - astSetAsTime( this, axis, astGetAsTime( this, axis ) ); - } - -/* Temporarly over-ride the SkyAxis IsLatitude attribute, regardless of its - setting, as the second axis of a SkyFrame is always the latitude axis. */ - astSetAxisIsLatitude( ax, axis_p == 1 ); - } - -/* Invoke the parent method to obtain a pointer to the Format string. */ - result = (*parent_getformat)( this_frame, axis, status ); - -/* Now restore the attributes that were temporarily over-ridden above to their - previous states. */ - if ( skyaxis ) { - if ( !as_time_set ) astClearAsTime( this, axis ); - if ( !is_latitude_set ) { - astClearAxisIsLatitude( ax ); - } else { - astSetAxisIsLatitude( ax, is_latitude ); - } - } - -/* If the parent method is unsuitable, we must construct a new Format string - here. This affects only those coordinate systems whose axes do not behave - like standard RA/DEC axes (e.g. typically ecliptic, galactic and - supergalactic coordinates). For these, we format values as decimal degrees - (or decimal hours if the AsTime attribute is set). Obtain the AsTime - value. */ - } else { - as_time = astGetAsTime( this, axis ); - -/* Determine how many digits of precision to use. This is obtained from the - SkyAxis Digits attribute (if set), otherwise from the Digits attribute of - the enclosing SkyFrame. */ - if ( astTestAxisDigits( ax ) ) { - digits = astGetAxisDigits( ax ); - } else { - digits = astGetDigits( this ); - } - -/* If a time format is required, generate a Format string using decimal - hours. */ - if ( astOK ) { - if ( as_time ) { - if ( digits <= 2 ) { - result = "h"; - } else { - (void) sprintf( getformat_buff, "h.%d", digits - 2 ); - result = getformat_buff; - } - -/* Otherwise use decimal degrees. */ - } else { - if ( digits <= 3 ) { - result = "d"; - } else { - (void) sprintf( getformat_buff, "d.%d", digits - 3 ); - result = getformat_buff; - } - } - } - } - } - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static const char *GetLabel( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetLabel - -* Purpose: -* Access the Label string for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* const char *GetLabel( AstFrame *this, int axis, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetLabel method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Label string for a specified axis -* of a SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstSystemType system; /* Code identifying type of sky coordinates */ - const char *result; /* Pointer to label string */ - int axis_p; /* Permuted axis index */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate and permute the axis index. */ - axis_p = astValidateAxis( this, axis, 1, "astGetLabel" ); - -/* Check if a value has been set for the required axis label string. If so, - invoke the parent astGetLabel method to obtain a pointer to it. */ - if ( astTestLabel( this, axis ) ) { - result = (*parent_getlabel)( this, axis, status ); - -/* Otherwise, identify the sky coordinate system described by the SkyFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default label string. */ - if ( astOK ) { - -/* Equatorial coordinate systems. */ - if ( IsEquatorial( system, status ) ) { - result = ( axis_p == 0 ) ? "Right ascension" : - "Declination"; - -/* Ecliptic coordinates. */ - } else if ( system == AST__ECLIPTIC ) { - result = ( axis_p == 0 ) ? "Ecliptic longitude" : - "Ecliptic latitude"; - -/* Helio-ecliptic coordinates. */ - } else if ( system == AST__HELIOECLIPTIC ) { - result = ( axis_p == 0 ) ? "Helio-ecliptic longitude" : - "Helio-ecliptic latitude"; - -/* AzEl coordinates. */ - } else if ( system == AST__AZEL ) { - result = ( axis_p == 0 ) ? "Azimuth" : - "Elevation"; - -/* Galactic coordinates. */ - } else if ( system == AST__GALACTIC ) { - result = ( axis_p == 0 ) ? "Galactic longitude" : - "Galactic latitude"; - -/* Supergalactic coordinates. */ - } else if ( system == AST__SUPERGALACTIC ) { - result = ( axis_p == 0 ) ? "Supergalactic longitude" : - "Supergalactic latitude"; - -/* Unknown spherical coordinates. */ - } else if ( system == AST__UNKNOWN ) { - result = ( axis_p == 0 ) ? "Longitude" : - "Latitude"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "astGetLabel(%s): Corrupt %s contains " - "invalid sky coordinate system identification code " - "(%d).", status, astGetClass( this ), astGetClass( this ), - (int) system ); - } - -/* If the SkyRef attribute has a set value, append " offset" to the label. */ - if( astGetSkyRefIs( this ) != AST__IGNORED_REF && - ( astTestSkyRef( this, 0 ) || astTestSkyRef( this, 1 ) ) ) { - sprintf( getlabel_buff, "%s offset", result ); - result = getlabel_buff; - } - } - } - -/* Return the result. */ - return result; -} - -static double GetDiurab( AstSkyFrame *this, int *status ) { -/* -* Name: -* GetDiurab - -* Purpose: -* Return the magnitude of the diurnal aberration vector. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double GetDiurab( AstSkyFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function - -* Description: -* This function returns the magnitude of the diurnal aberration -* vector. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The magnitude of the diurnal aberration vector. - -*/ - -/* Local Variables: */ - double uau; - double vau; - -/* Check the global error status. */ - if ( !astOK ) return AST__BAD; - -/* If the magnitude of the diurnal aberration vector has not yet been - found, find it now, and cache it in the SkyFrame structure. The cached - value will be reset to AST__BAD if the ObsLat attribute value is - changed. This code is transliterated from SLA_AOPPA. */ - if( this->diurab == AST__BAD ) { - palGeoc( astGetObsLat( this ), astGetObsAlt( this ), &uau, &vau ); - this->diurab = 2*AST__DPI*uau*SOLSID/C; - } - -/* Return the result, */ - return this->diurab; -} - -static double GetLAST( AstSkyFrame *this, int *status ) { -/* -* Name: -* GetLAST - -* Purpose: -* Return the Local Apparent Sidereal Time for the SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double GetLAST( AstSkyFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function - -* Description: -* This function returns the Local Apparent Sidereal Time (LAST) -* at the moment intime given by the Epoch attribute of the SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The LAST value. - -*/ - -/* Local Variables: */ - double dlast; /* Change in LAST */ - double epoch; /* Epoch (TDB MJD) */ - double last1; /* LAST at end of current interval */ - double result; /* Result value to return */ - double delta_epoch; /* Change in Epoch */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* The "last" component of the SkyFrame structure holds the accurate - LAST at the moment in time given by the "eplast" (a TDB MJD) component - of the SkyFrame structure. If the current value of the SkyFrame's - Epoch attribute is not much different to "eplast" (within 0.4 of a day), - then the returned LAST value is the "last" value plus the difference - between Epoch and "eplast", converted from solar to sidereal time, - then converted to radians. This approximation seems to be good to less - than a tenth of an arcsecond. If this approximation cannot be used, - invoke SetLast to recalculate the accurate LAST and update the "eplast" - and "last" values. */ - if( this->eplast != AST__BAD ) { - epoch = astGetEpoch( this ); - delta_epoch = epoch - this->eplast; - -/* Return the current LAST value if the epoch has not changed. */ - if( delta_epoch == 0.0 ) { - result = this->last; - -/* If the previous full calculation of LAST was less than 0.4 days ago, - use a linear approximation to LAST. */ - } else if( fabs( delta_epoch ) < 0.4 ) { - -/* If we do not know the ratio of sidereal to solar time at the current - epoch, calculate it now. This involves a full calculation of LAST at - the end of the current linear approximation period. */ - if( this->klast == AST__BAD ) { - last1 = CalcLAST( this, this->eplast + 0.4, astGetObsLon( this ), - astGetObsLat( this ), astGetObsAlt( this ), - astGetDut1( this ), astGetDtai( this ), status ); - -/* Ensure the change in LAST is positive so that we get a positive ratio. */ - dlast = last1 - this->last; - if( dlast < 0.0 ) dlast += 2*AST__DPI; - this->klast = 2*AST__DPI*0.4/dlast; - } - -/* Now use the ratio of solar to sidereal time to calculate the linear - approximation to LAST. */ - result = this->last + 2*AST__DPI*delta_epoch/this->klast; - -/* If the last accurate calculation of LAST was more than 0.4 days ago, - do a full accurate calculation. */ - } else { - SetLast( this, status ); - result = this->last; - } - -/* If we have not yet done an accurate calculation of LAST, do one now. */ - } else { - SetLast( this, status ); - result = this->last; - } - -/* Return the result, */ - return result; -} - -static int GetIsLatAxis( AstSkyFrame *this, int axis, int *status ) { -/* -* Name: -* GetIsLatAxis - -* Purpose: -* Test an axis to see if it is a latitude axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int GetIsLatAxis( AstSkyFrame *this, int axis, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function tests if a SkyFrame axis is a celestial latitude axis. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Zero based axis index. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the supplied axis is a celestial latitude axis, and zero -* otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get the index of the latitude axis and compare to the supplied axis - index. */ - result = ( axis == astGetLatAxis( this ) ); - -/* Return the result. */ - return astOK ? result : 0; - -} - -static int GetIsLonAxis( AstSkyFrame *this, int axis, int *status ) { -/* -* Name: -* GetIsLonAxis - -* Purpose: -* Test an axis to see if it is a longitude axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int GetIsLonAxis( AstSkyFrame *this, int axis, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function tests if a SkyFrame axis is a celestial longitude axis. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Zero based axis index. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the supplied axis is a celestial longitude axis, and zero -* otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get the index of the longitude axis and compare to the supplied axis - index. */ - result = ( axis == astGetLonAxis( this ) ); - -/* Return the result. */ - return astOK ? result : 0; - -} - -static int GetLatAxis( AstSkyFrame *this, int *status ) { -/* -* Name: -* GetLatAxis - -* Purpose: -* Obtain the index of the latitude axis of a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int GetLatAxis( AstSkyFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function returns the zero-based index of the latitude axis of -* a SkyFrame, taking into account any current axis permutation. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The zero based axis index (0 or 1) of the latitude axis. - -* Notes: -* - A value of one will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - int result; /* Result to be returned */ - const int *perm; /* Axis permutation array */ - -/* Check the global error status. */ - if ( !astOK ) return 1; - -/* Initialise. */ - result = 1; - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( astOK ) { - -/* Identify the latitude axis. */ - if( perm[ 0 ] == 1 ) { - result = 0; - } else { - result = 1; - } - - } - -/* Return the result. */ - return result; - -} - -static int GetLonAxis( AstSkyFrame *this, int *status ) { -/* -* Name: -* GetLonAxis - -* Purpose: -* Obtain the index of the longitude axis of a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int GetLonAxis( AstSkyFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function returns the zero-based index of the longitude axis of -* a SkyFrame, taking into account any current axis permutation. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The zero based axis index (0 or 1) of the longitude axis. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - int result; /* Result to be returned */ - const int *perm; /* Axis permutation array */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise. */ - result = 0; - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( astOK ) { - -/* Identify the longitude axis. */ - if( perm[ 0 ] == 0 ) { - result = 0; - } else { - result = 1; - } - - } - -/* Return the result. */ - return result; - -} - -static double GetSkyRefP( AstSkyFrame *this, int axis, int *status ) { -/* -* Name: -* GetSkyRefP - -* Purpose: -* Obtain the value of the SkyRefP attribute for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double GetSkyRefP( AstSkyFrame *this, int axis, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function returns the value of the SkyRefP attribute for a -* SkyFrame axis, providing suitable defaults. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The SkyRefP value to be used. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - double result; /* Returned value */ - int axis_p; /* Permuted axis index */ - -/* Initialise. */ - result = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate and permute the axis index. */ - axis_p = astValidateAxis( this, axis, 1, "astGetSkyRefP" ); - -/* Check if a value has been set for the required axis. If so, return it. */ - if( this->skyrefp[ axis_p ] != AST__BAD ) { - result = this->skyrefp[ axis_p ]; - -/* Otherwise, return the default value */ - } else { - -/* The default longitude value is always zero. */ - if( axis_p == 0 ) { - result= 0.0; - -/* The default latitude value depends on SkyRef. The usual default is the - north pole. The exception to this is if the SkyRef attribute identifies - either the north or the south pole, in which case the origin is used as - the default. Allow some tolerance. */ - } else if( fabs( cos( this->skyref[ 1 ] ) ) > 1.0E-10 ) { - result = pi/2; - - } else { - result = 0.0; - } - } - -/* Return the result. */ - return result; -} - -static const char *GetSymbol( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetSymbol - -* Purpose: -* Obtain a pointer to the Symbol string for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* const char *GetSymbol( AstFrame *this, int axis, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetSymbol method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Symbol string for a specified axis -* of a SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstSystemType system; /* Code identifying type of sky coordinates */ - const char *result; /* Pointer to symbol string */ - int axis_p; /* Permuted axis index */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate and permute the axis index. */ - axis_p = astValidateAxis( this, axis, 1, "astGetSymbol" ); - -/* Check if a value has been set for the required axis symbol string. If so, - invoke the parent astGetSymbol method to obtain a pointer to it. */ - if ( astTestSymbol( this, axis ) ) { - result = (*parent_getsymbol)( this, axis, status ); - -/* Otherwise, identify the sky coordinate system described by the SkyFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default Symbol string. */ - if ( astOK ) { - -/* Equatorial coordinate systems. */ - if ( IsEquatorial( system, status ) ) { - result = ( axis_p == 0 ) ? "RA" : "Dec"; - -/* Ecliptic coordinates. */ - } else if ( system == AST__ECLIPTIC ) { - result = ( axis_p == 0 ) ? "Lambda" : "Beta"; - -/* Helio-ecliptic coordinates. */ - } else if ( system == AST__HELIOECLIPTIC ) { - result = ( axis_p == 0 ) ? "Lambda" : "Beta"; - -/* AzEl coordinates. */ - } else if ( system == AST__AZEL ) { - result = ( axis_p == 0 ) ? "Az" : "El"; - -/* Galactic coordinates. */ - } else if ( system == AST__GALACTIC ) { - result = ( axis_p == 0 ) ? "l" : "b"; - -/* Supergalactic coordinates. */ - } else if ( system == AST__SUPERGALACTIC ) { - result = ( axis_p == 0 ) ? "SGL" : "SGB"; - -/* Unknown spherical coordinates. */ - } else if ( system == AST__UNKNOWN ) { - result = ( axis_p == 0 ) ? "Lon" : "Lat"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "astGetSymbol(%s): Corrupt %s contains " - "invalid sky coordinate system identification code " - "(%d).", status, astGetClass( this ), astGetClass( this ), - (int) system ); - } - -/* If the SkyRef attribute had a set value, prepend "D" (for "delta") to the - Symbol. */ - if( astGetSkyRefIs( this ) != AST__IGNORED_REF && - ( astTestSkyRef( this, 0 ) || astTestSkyRef( this, 1 ) ) ) { - sprintf( getsymbol_buff, "D%s", result ); - result = getsymbol_buff; - } - } - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetAlignSystem - -* Purpose: -* Obtain the AlignSystem attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetAlignSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the AlignSystem attribute for a SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The AlignSystem value. - -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* If a AlignSystem attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestAlignSystem( this ) ) { - result = (*parent_getalignsystem)( this_frame, status ); - -/* Otherwise, provide a suitable default. */ - } else { - result = AST__ICRS; - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetSystem - -* Purpose: -* Obtain the System attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* AstSystemType GetSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the System attribute for a SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System value. - -* Notes: -* - AST__BADSYSTEM is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* If a System attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestSystem( this ) ) { - result = (*parent_getsystem)( this_frame, status ); - -/* Otherwise, provide a suitable default. */ - } else { - result = AST__ICRS; - } - -/* Return the result. */ - return result; -} - -static const char *GetTitle( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetTitle - -* Purpose: -* Obtain a pointer to the Title string for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* const char *GetTitle( AstFrame *this_frame, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetTitle method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Title string for a SkyFrame. -* A pointer to a suitable default string is returned if no Title value has -* previously been set. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null-terminated character string containing the requested -* information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - AstSystemType system; /* Code identifying type of sky coordinates */ - const char *extra; /* Pointer to extra information */ - const char *p; /* Character pointer */ - const char *projection; /* Pointer to sky projection description */ - const char *result; /* Pointer to result string */ - const char *word; /* Pointer to critical word */ - double epoch; /* Value of Epoch attribute */ - double equinox; /* Value of Equinox attribute */ - int lextra; /* Length of extra information */ - int offset; /* Using offset coordinate system? */ - int pos; /* Buffer position to enter text */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_frame); - -/* Initialise. */ - result = NULL; - pos = 0; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* See if a Title string has been set. If so, use the parent astGetTitle - method to obtain a pointer to it. */ - if ( astTestTitle( this ) ) { - result = (*parent_gettitle)( this_frame, status ); - -/* Otherwise, we will generate a default Title string. Obtain the values of the - SkyFrame's attributes that determine what this string will be. */ - } else { - epoch = astGetEpoch( this ); - equinox = astGetEquinox( this ); - projection = astGetProjection( this ); - system = astGetSystem( this ); - -/* See if an offset coordinate system is being used.*/ - offset = ( astTestSkyRef( this, 0 ) || astTestSkyRef( this, 1 ) ) - && ( astGetSkyRefIs( this ) != AST__IGNORED_REF ); - -/* Use this to determine if the word "coordinates" or "offsets" should be - used.*/ - word = offset ? "offsets" : "coordinates"; - -/* Classify the coordinate system type and create an appropriate Title - string. (Note that when invoking the astFmtDecimalYr function we must - use a separate sprintf on each occasion so as not to over-write its - internal buffer before the result string has been used.) */ - if ( astOK ) { - result = gettitle_buff; - switch ( system ) { - -/* FK4 equatorial coordinates. */ -/* --------------------------- */ -/* Display the Equinox and Epoch values. */ - case AST__FK4: - pos = sprintf( gettitle_buff, "FK4 equatorial %s", word ); - if( astTestEquinox( this ) || astGetUseDefs( this ) ) { - pos += sprintf( gettitle_buff + pos, "; mean equinox B%s", - astFmtDecimalYr( palEpb( equinox ), 9 ) ); - } - if( astTestEpoch( this ) || astGetUseDefs( this ) ) { - pos += sprintf( gettitle_buff + pos, - "; epoch B%s", astFmtDecimalYr( palEpb( epoch ), 9 ) ); - } - break; - -/* FK4 coordinates with no E-terms of aberration. */ -/* ---------------------------------------------- */ -/* Display the Equinox and Epoch values. */ - case AST__FK4_NO_E: - pos = sprintf( gettitle_buff, "FK4 equatorial %s; no E-terms", word ); - if( astTestEquinox( this ) || astGetUseDefs( this ) ) { - pos += sprintf( gettitle_buff + pos, "; mean equinox B%s", - astFmtDecimalYr( palEpb( equinox ), 9 ) ); - } - if( astTestEpoch( this ) || astGetUseDefs( this ) ) { - pos += sprintf( gettitle_buff + pos, - "; epoch B%s", astFmtDecimalYr( palEpb( epoch ), 9 ) ); - } - break; - -/* FK5 equatorial coordinates. */ -/* --------------------------- */ -/* Display only the Equinox value. */ - case AST__FK5: - pos = sprintf( gettitle_buff, "FK5 equatorial %s", word ); - if( astTestEquinox( this ) || astGetUseDefs( this ) ) { - pos += sprintf( gettitle_buff + pos, "; mean equinox J%s", - astFmtDecimalYr( palEpj( equinox ), 9 ) ); - } - break; - -/* J2000 equatorial coordinates. */ -/* ----------------------------- */ -/* Based on the dynamically determined mean equator and equinox of J2000, - rather than on a model such as FK4 or FK5 */ - case AST__J2000: - pos = sprintf( gettitle_buff, "J2000 equatorial %s", word ); - break; - -/* ICRS coordinates. */ -/* ----------------- */ -/* ICRS is only like RA/Dec by co-incidence, it is not really an - equatorial system by definition. */ - case AST__ICRS: - pos = sprintf( gettitle_buff, "ICRS %s", word ); - break; - -/* AzEl coordinates. */ -/* ----------------- */ - case AST__AZEL: - pos = sprintf( gettitle_buff, "Horizon (Azimuth/Elevation) %s", word ); - break; - -/* Geocentric apparent equatorial coordinates. */ -/* ------------------------------------------ */ -/* Display only the Epoch value. */ - case AST__GAPPT: - pos = sprintf( gettitle_buff, - "Geocentric apparent equatorial %s; " - "; epoch J%s", word, astFmtDecimalYr( palEpj( epoch ), 9 ) ); - break; - -/* Ecliptic coordinates. */ -/* --------------------- */ -/* Display only the Equinox value. */ - case AST__ECLIPTIC: - pos = sprintf( gettitle_buff, "Ecliptic %s", word ); - if( astTestEquinox( this ) || astGetUseDefs( this ) ) { - pos += sprintf( gettitle_buff + pos, "; mean equinox J%s", - astFmtDecimalYr( palEpj( equinox ), 9 ) ); - } - break; - -/* Helio-ecliptic coordinates. */ -/* --------------------------- */ -/* Display only the Epoch value (equinox is fixed). */ - case AST__HELIOECLIPTIC: - pos = sprintf( gettitle_buff, "Helio-ecliptic %s; mean equinox J2000", word ); - if( astTestEpoch( this ) || astGetUseDefs( this ) ) { - pos += sprintf( gettitle_buff + pos, "; epoch J%s", - astFmtDecimalYr( palEpj( epoch ), 9 ) ); - } - break; - -/* Galactic coordinates. */ -/* --------------------- */ -/* Do not display an Equinox or Epoch value. */ - case AST__GALACTIC: - pos = sprintf( gettitle_buff, "IAU (1958) galactic %s", word ); - break; - -/* Supergalactic coordinates. */ -/* -------------------------- */ -/* Do not display an Equinox or Epoch value. */ - case AST__SUPERGALACTIC: - pos = sprintf( gettitle_buff, - "De Vaucouleurs supergalactic %s", word ); - break; - -/* Unknown coordinates. */ -/* -------------------------- */ - case AST__UNKNOWN: - pos = sprintf( gettitle_buff, - "Spherical %s", word ); - break; - -/* Report an error if the coordinate system was not recognised. */ - default: - astError( AST__SCSIN, "astGetTitle(%s): Corrupt %s contains " - "invalid sky coordinate system identification code " - "(%d).", status, astGetClass( this ), astGetClass( this ), - (int) system ); - break; - } - -/* If OK, we add either a description of the sky projection, or (if used) - a description of the origin or pole of the offset coordinate system. - We include only one of these two strings in order to keep the length - of the title down to a reasonable value.*/ - if ( astOK ) { - -/* If the SkyRef attribute has set values, create a description of the offset - coordinate system. */ - if( offset ){ - word = ( astGetSkyRefIs( this ) == AST__POLE_REF )?"pole":"origin"; - lextra = sprintf( gettitle_buff2, "%s at %s ", word, - astFormat( this, 0, astGetSkyRef( this, 0 ) ) ); - lextra += sprintf( gettitle_buff2 + lextra, "%s", - astFormat( this, 1, astGetSkyRef( this, 1 ) ) ); - extra = gettitle_buff2; - -/* Otherwise, get the sky projection description. */ - } else { - extra = projection; - -/* Determine the length of the extra information, after removing trailing - white space. */ - for ( lextra = (int) strlen( extra ); lextra > 0; lextra-- ) { - if ( !isspace( extra[ lextra - 1 ] ) ) break; - } - } - -/* If non-blank extra information is available, append it to the title string, - checking that the end of the buffer is not over-run. */ - if ( lextra ) { - p = "; "; - while ( ( pos < AST__SKYFRAME_GETTITLE_BUFF_LEN ) && *p ) gettitle_buff[ pos++ ] = *p++; - p = extra; - while ( ( pos < AST__SKYFRAME_GETTITLE_BUFF_LEN ) && - ( p < ( extra + lextra ) ) ) gettitle_buff[ pos++ ] = *p++; - if( extra == projection ) { - p = " projection"; - while ( ( pos < AST__SKYFRAME_GETTITLE_BUFF_LEN ) && *p ) gettitle_buff[ pos++ ] = *p++; - } - gettitle_buff[ pos ] = '\0'; - } - } - } - } - -/* If an error occurred, clear the returned pointer value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static const char *GetUnit( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetUnit - -* Purpose: -* Obtain a pointer to the Unit string for a SkyFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* const char *GetUnit( AstFrame *this_frame, int axis ) - -* Class Membership: -* SkyFrame member function (over-rides the astGetUnit method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Unit string for a specified axis -* of a SkyFrame. If the Unit attribute has not been set for the axis, a -* pointer to a suitable default string is returned instead. This string may -* depend on the value of the Format attribute for the axis and, in turn, on -* the type of sky coordinate system that the SkyFrame describes. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* The number of the axis (zero-based) for which information is required. - -* Returned Value: -* A pointer to a null-terminated string containing the Unit value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const char *result; /* Pointer value to return */ - int format_set; /* Format attribute set? */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astGetUnit" ); - -/* The Unit value may depend on the value of the Format attribute, so - determine if a Format value has been set for the axis and set a - temporary value if it has not. Use the GetFormat member function - for this class together with member functions inherited from the - parent class (rather than using the object's methods directly) - because if any of these methods have been over-ridden by a derived - class the Format string syntax may no longer be compatible with - this class. */ - format_set = (*parent_testformat)( this_frame, axis, status ); - if ( !format_set ) { - (*parent_setformat)( this_frame, axis, GetFormat( this_frame, axis, status ), status ); - } - -/* Use the parent GetUnit method to return a pointer to the required Unit - string. */ - result = (*parent_getunit)( this_frame, axis, status ); - -/* If necessary, clear any temporary Format value that was set above. */ - if ( !format_set ) (*parent_clearformat)( this_frame, axis, status ); - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -void astInitSkyFrameVtab_( AstSkyFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSkyFrameVtab - -* Purpose: -* Initialise a virtual function table for a SkyFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "skyframe.h" -* void astInitSkyFrameVtab( AstSkyFrameVtab *vtab, const char *name ) - -* Class Membership: -* SkyFrame vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SkyFrame class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - int stat; /* SLALIB status */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameVtab( (AstFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASkyFrame) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->ClearAsTime = ClearAsTime; - vtab->ClearEquinox = ClearEquinox; - vtab->ClearNegLon = ClearNegLon; - vtab->ClearProjection = ClearProjection; - vtab->GetAsTime = GetAsTime; - vtab->GetEquinox = GetEquinox; - vtab->GetNegLon = GetNegLon; - vtab->GetIsLatAxis = GetIsLatAxis; - vtab->GetIsLonAxis = GetIsLonAxis; - vtab->GetLatAxis = GetLatAxis; - vtab->GetLonAxis = GetLonAxis; - vtab->GetProjection = GetProjection; - vtab->SetAsTime = SetAsTime; - vtab->SetEquinox = SetEquinox; - vtab->SetNegLon = SetNegLon; - vtab->SetProjection = SetProjection; - vtab->SkyOffsetMap = SkyOffsetMap; - vtab->TestAsTime = TestAsTime; - vtab->TestEquinox = TestEquinox; - vtab->TestNegLon = TestNegLon; - vtab->TestProjection = TestProjection; - - vtab->TestSkyTol = TestSkyTol; - vtab->SetSkyTol = SetSkyTol; - vtab->GetSkyTol = GetSkyTol; - vtab->ClearSkyTol = ClearSkyTol; - - vtab->TestSkyRef = TestSkyRef; - vtab->SetSkyRef = SetSkyRef; - vtab->GetSkyRef = GetSkyRef; - vtab->ClearSkyRef = ClearSkyRef; - - vtab->TestSkyRefP = TestSkyRefP; - vtab->SetSkyRefP = SetSkyRefP; - vtab->GetSkyRefP = GetSkyRefP; - vtab->ClearSkyRefP = ClearSkyRefP; - - vtab->TestSkyRefIs = TestSkyRefIs; - vtab->SetSkyRefIs = SetSkyRefIs; - vtab->GetSkyRefIs = GetSkyRefIs; - vtab->ClearSkyRefIs = ClearSkyRefIs; - - vtab->TestAlignOffset = TestAlignOffset; - vtab->SetAlignOffset = SetAlignOffset; - vtab->GetAlignOffset = GetAlignOffset; - vtab->ClearAlignOffset = ClearAlignOffset; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - frame = (AstFrameVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_gettop = frame->GetTop; - frame->GetTop = GetTop; - - parent_setobsalt = frame->SetObsAlt; - frame->SetObsAlt = SetObsAlt; - - parent_setobslat = frame->SetObsLat; - frame->SetObsLat = SetObsLat; - - parent_setobslon = frame->SetObsLon; - frame->SetObsLon = SetObsLon; - - parent_clearobslon = frame->ClearObsLon; - frame->ClearObsLon = ClearObsLon; - - parent_clearobsalt = frame->ClearObsAlt; - frame->ClearObsAlt = ClearObsAlt; - - parent_clearobslat = frame->ClearObsLat; - frame->ClearObsLat = ClearObsLat; - - parent_getbottom = frame->GetBottom; - frame->GetBottom = GetBottom; - - parent_getepoch = frame->GetEpoch; - frame->GetEpoch = GetEpoch; - - parent_format = frame->Format; - frame->Format = Format; - parent_gap = frame->Gap; - frame->Gap = Gap; - parent_getdirection = frame->GetDirection; - frame->GetDirection = GetDirection; - parent_getdomain = frame->GetDomain; - frame->GetDomain = GetDomain; - parent_getsystem = frame->GetSystem; - frame->GetSystem = GetSystem; - parent_setsystem = frame->SetSystem; - frame->SetSystem = SetSystem; - parent_clearsystem = frame->ClearSystem; - frame->ClearSystem = ClearSystem; - parent_getalignsystem = frame->GetAlignSystem; - frame->GetAlignSystem = GetAlignSystem; - parent_getformat = frame->GetFormat; - frame->GetFormat = GetFormat; - parent_getlabel = frame->GetLabel; - frame->GetLabel = GetLabel; - parent_getsymbol = frame->GetSymbol; - frame->GetSymbol = GetSymbol; - parent_gettitle = frame->GetTitle; - frame->GetTitle = GetTitle; - parent_getunit = frame->GetUnit; - frame->GetUnit = GetUnit; - parent_match = frame->Match; - frame->Match = Match; - parent_overlay = frame->Overlay; - frame->Overlay = Overlay; - parent_subframe = frame->SubFrame; - frame->SubFrame = SubFrame; - parent_unformat = frame->Unformat; - frame->Unformat = Unformat; - - parent_setdtai = frame->SetDtai; - frame->SetDtai = SetDtai; - parent_setdut1 = frame->SetDut1; - frame->SetDut1 = SetDut1; - - parent_cleardtai = frame->ClearDtai; - frame->ClearDtai = ClearDtai; - parent_cleardut1 = frame->ClearDut1; - frame->ClearDut1 = ClearDut1; - -/* Store replacement pointers for methods which will be over-ridden by new - member functions implemented here. */ - frame->Angle = Angle; - frame->Distance = Distance; - frame->FrameGrid = FrameGrid; - frame->Intersect = Intersect; - frame->Norm = Norm; - frame->NormBox = NormBox; - frame->Resolve = Resolve; - frame->ResolvePoints = ResolvePoints; - frame->Offset = Offset; - frame->Offset2 = Offset2; - frame->ValidateSystem = ValidateSystem; - frame->SystemString = SystemString; - frame->SystemCode = SystemCode; - frame->LineDef = LineDef; - frame->LineContains = LineContains; - frame->LineCrossing = LineCrossing; - frame->LineOffset = LineOffset; - frame->GetActiveUnit = GetActiveUnit; - frame->TestActiveUnit = TestActiveUnit; - frame->MatchAxesX = MatchAxesX; - -/* Store pointers to inherited methods that will be invoked explicitly - by this class. */ - parent_clearformat = frame->ClearFormat; - parent_setformat = frame->SetFormat; - parent_testformat = frame->TestFormat; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "SkyFrame", - "Description of celestial coordinate system" ); - -/* Initialize constants for converting between hours, degrees and - radians, etc.. */ - LOCK_MUTEX2 - palDtf2r( 1, 0, 0.0, &hr2rad, &stat ); - palDaf2r( 1, 0, 0.0, °2rad, &stat ); - palDaf2r( 180, 0, 0.0, &pi, &stat ); - piby2 = 0.5*pi; - UNLOCK_MUTEX2 - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void Intersect( AstFrame *this_frame, const double a1[2], - const double a2[2], const double b1[2], - const double b2[2], double cross[2], - int *status ) { -/* -* Name: -* Intersect - -* Purpose: -* Find the point of intersection between two geodesic curves. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void Intersect( AstFrame *this_frame, const double a1[2], -* const double a2[2], const double b1[2], -* const double b2[2], double cross[2], -* int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astIntersect method -* inherited from the Frame class). - -* Description: -* This function finds the coordinate values at the point of -* intersection between two geodesic curves. Each curve is specified -* by two points on the curve. - -* Parameters: -* this -* Pointer to the SkyFrame. -* a1 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a point on the first -* geodesic curve. -* a2 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a second point on the -* first geodesic curve. -* b1 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a point on the second -* geodesic curve. -* b2 -* An array of double, with one element for each Frame axis. -* This should contain the coordinates of a second point on -* the second geodesic curve. -* cross -* An array of double, with one element for each Frame axis -* in which the coordinates of the required intersection -* point will be returned. These will be AST__BAD if the curves do -* not intersect. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -* - For SkyFrames each curve will be a great circle, and in general -* each pair of curves will intersect at two diametrically opposite -* points on the sky. The returned position is the one which is -* closest to point "a1". -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const int *perm; /* Pointer to axis permutation array */ - double aa1[ 2 ]; /* Permuted coordinates for a1 */ - double aa2[ 2 ]; /* Permuted coordinates for a2 */ - double bb1[ 2 ]; /* Permuted coordinates for b1 */ - double bb2[ 2 ]; /* Permuted coordinates for b2 */ - double cc[ 2 ]; /* Permuted coords at intersection */ - double d1; /* Cos(distance from a1 to vp) */ - double d2; /* Cos(distance from a1 to -vp) */ - double na[ 3 ]; /* Normal to the a1/a2 great circle */ - double nb[ 3 ]; /* Normal to the b1/b2 great circle */ - double va1[ 3 ]; /* Vector pointing at a1 */ - double va2[ 3 ]; /* Vector pointing at a2 */ - double vb1[ 3 ]; /* Vector pointing at b1 */ - double vb2[ 3 ]; /* Vector pointing at b2 */ - double vmod; /* Length of "vp" */ - double vp[ 3 ]; /* Vector pointing at the intersection */ - double vpn[ 3 ]; /* Normalised vp */ - int iaxis; /* Axis index */ - -/* Initialise. */ - cross[ 0 ] = AST__BAD; - cross[ 1 ] = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Check that all supplied values are OK. */ - if ( ( a1[ 0 ] != AST__BAD ) && ( a1[ 1 ] != AST__BAD ) && - ( a2[ 0 ] != AST__BAD ) && ( a2[ 1 ] != AST__BAD ) && - ( b1[ 0 ] != AST__BAD ) && ( b1[ 1 ] != AST__BAD ) && - ( b2[ 0 ] != AST__BAD ) && ( b2[ 1 ] != AST__BAD ) ) { - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( astOK ) { - -/* Apply the axis permutation array to obtain the coordinates of - the points in the required (longitude,latitude) order. */ - for( iaxis = 0; iaxis < 2; iaxis++ ) { - aa1[ perm[ iaxis ] ] = a1[ iaxis ]; - aa2[ perm[ iaxis ] ] = a2[ iaxis ]; - bb1[ perm[ iaxis ] ] = b1[ iaxis ]; - bb2[ perm[ iaxis ] ] = b2[ iaxis ]; - } - -/* Convert each (lon,lat) pair into a unit length 3-vector. */ - palDcs2c( aa1[ 0 ], aa1[ 1 ], va1 ); - palDcs2c( aa2[ 0 ], aa2[ 1 ], va2 ); - palDcs2c( bb1[ 0 ], bb1[ 1 ], vb1 ); - palDcs2c( bb2[ 0 ], bb2[ 1 ], vb2 ); - -/* Find the normal vectors to the two great cicles. */ - palDvxv( va1, va2, na ); - palDvxv( vb1, vb2, nb ); - -/* The cross product of the two normal vectors points to one of the - two diametrically opposite intersections. */ - palDvxv( na, nb, vp ); - -/* Normalise the "vp" vector, also obtaining its original modulus. */ - palDvn( vp, vpn, &vmod ); - if( vmod != 0.0 ) { - -/* We want the intersection which is closest to "a1". The dot product - gives the cos(distance) between two positions. So find the dot - product between "a1" and "vpn", and then between "a1" and the point - diametrically opposite "vpn". */ - d1 = palDvdv( vpn, va1 ); - vpn[ 0 ] = -vpn[ 0 ]; - vpn[ 1 ] = -vpn[ 1 ]; - vpn[ 2 ] = -vpn[ 2 ]; - d2 = palDvdv( vpn, va1 ); - -/* Revert to "vpn" if it is closer to "a1". */ - if( d1 > d2 ) { - vpn[ 0 ] = -vpn[ 0 ]; - vpn[ 1 ] = -vpn[ 1 ]; - vpn[ 2 ] = -vpn[ 2 ]; - } - -/* Convert the vector back into a (lon,lat) pair, and put the longitude - into the range 0 to 2.pi. */ - palDcc2s( vpn, cc, cc + 1 ); - *cc = palDranrm( *cc ); - -/* Permute the result coordinates to undo the effect of the SkyFrame - axis permutation array. */ - cross[ 0 ] = cc[ perm[ 0 ] ]; - cross[ 1 ] = cc[ perm[ 1 ] ]; - } - } - } -} - -static int IsEquatorial( AstSystemType system, int *status ) { -/* -* Name: -* IsEquatorial - -* Purpose: -* Test for an equatorial sky coordinate system. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int IsEquatorial( AstSystemType system, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function returns a boolean value to indicate if a sky coordinate -* system is equatorial. - -* Parameters: -* system -* Code to identify the sky coordinate system. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the sky coordinate system is equatorial, otherwise zero. - -* Notes: -* - A value of zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - int result; /* Result value to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Determine if the sky coordinate system is an equatorial one. Note, - ICRS is not equatorial by definition, but is included here because it - is normally treated as an equatorial system in terms of the axis - labels, formats, etc. */ - result = ( ( system == AST__FK4 ) || - ( system == AST__FK4_NO_E ) || - ( system == AST__ICRS ) || - ( system == AST__FK5 ) || - ( system == AST__J2000 ) || - ( system == AST__GAPPT ) ); - -/* Return the result. */ - return result; -} - -static int LineContains( AstFrame *this, AstLineDef *l, int def, double *point, int *status ) { -/* -* Name: -* LineContains - -* Purpose: -* Determine if a line contains a point. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int LineContains( AstFrame *this, AstLineDef *l, int def, double *point, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astLineContains -* method inherited from the Frame class). - -* Description: -* This function determines if the supplied point is on the supplied -* line within the supplied Frame. The start point of the line is -* considered to be within the line, but the end point is not. The tests -* are that the point of closest approach of the line to the point should -* be between the start and end, and that the distance from the point to -* the point of closest aproach should be less than 1.0E-7 of the length -* of the line. - -* Parameters: -* this -* Pointer to the Frame. -* l -* Pointer to the structure defining the line. -* def -* Should be set non-zero if the "point" array was created by a -* call to astLineCrossing (in which case it may contain extra -* information following the axis values),and zero otherwise. -* point -* Point to an array containing the axis values of the point to be -* tested, possibly followed by extra cached information (see "def"). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the line contains the point. - -* Notes: -* - The pointer supplied for "l" should have been created using the -* astLineDef method. These structures contained cached information about -* the lines which improve the efficiency of this method when many -* repeated calls are made. An error will be reported if the structure -* does not refer to the Frame specified by "this". -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - SkyLineDef *sl; /* SkyLine information */ - const int *perm; /* Pointer to axis permutation array */ - double *b; /* Pointer to Cartesian coords array */ - double bb[3]; /* Buffer for Cartesian coords */ - double p1[2]; /* Buffer for Spherical coords */ - double t1, t2; - int result; /* Returned value */ - -/* Initialise */ - result =0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check that the line refers to the supplied Frame. */ - if( l->frame != this ) { - astError( AST__INTER, "astLineContains(%s): The supplied line does " - "not relate to the supplied %s (AST internal programming " - "error).", status, astGetClass( this ), astGetClass( this ) ); - -/* Check the axis values are good */ - } else if( point[ 0 ] != AST__BAD && point[ 1 ] != AST__BAD ){ - -/* Get a pointer to an array holding the corresponding Cartesian coords. */ - if( def ) { - b = point + 2; - - } else { - perm = astGetPerm( this ); - if ( perm ) { - p1[ perm[ 0 ] ] = point[ 0 ]; - p1[ perm[ 1 ] ] = point[ 1 ]; - palDcs2c( p1[ 0 ], p1[ 1 ], bb ); - b = bb; - } else { - b = NULL; - } - } - -/* Recast the supplied AstLineDef into a SkyLineDef to get the different - structure (we know from the above check on the Frame that it is safe to - do this). */ - sl = (SkyLineDef *) l; - -/* Check that the point of closest approach of the line to the point is - within the limits of the line. */ - if( LineIncludes( sl, b, status ) ){ - -/* Check that the point is 90 degrees away from the pole of the great - circle containing the line. */ - t1 = palDvdv( sl->q, b ); - t2 = 1.0E-7*sl->length; - if( t2 < 1.0E-10 ) t2 = 1.0E-10; - if( fabs( t1 ) <= t2 ) result = 1; - } - } - -/* Return the result. */ - return result; -} - -static int LineCrossing( AstFrame *this, AstLineDef *l1, AstLineDef *l2, - double **cross, int *status ) { -/* -* Name: -* LineCrossing - -* Purpose: -* Determine if two lines cross. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int LineCrossing( AstFrame *this, AstLineDef *l1, AstLineDef *l2, -* double **cross, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astLineCrossing -* method inherited from the Frame class). - -* Description: -* This function determines if the two suplied line segments cross, -* and if so returns the axis values at the point where they cross. -* A flag is also returned indicating if the crossing point occurs -* within the length of both line segments, or outside one or both of -* the line segments. - -* Parameters: -* this -* Pointer to the Frame. -* l1 -* Pointer to the structure defining the first line. -* l2 -* Pointer to the structure defining the second line. -* cross -* Pointer to a location at which to put a pointer to a dynamically -* alocated array containing the axis values at the crossing. If -* NULL is supplied no such array is returned. Otherwise, the returned -* array should be freed using astFree when no longer needed. If the -* lines are parallel (i.e. do not cross) then AST__BAD is returned for -* all axis values. Note usable axis values are returned even if the -* lines cross outside the segment defined by the start and end points -* of the lines. The order of axes in the returned array will take -* account of the current axis permutation array if appropriate. Note, -* sub-classes such as SkyFrame may append extra values to the end -* of the basic frame axis values. A NULL pointer is returned if an -* error occurs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the lines cross at a point which is -* within the [start,end) segment of both lines. If the crossing point -* is outside this segment on either line, or if the lines are parallel, -* zero is returned. Note, the start point is considered to be inside -* the length of the segment, but the end point is outside. - -* Notes: -* - The pointers supplied for "l1" and "l2" should have been created -* using the astLineDef method. These structures contained cached -* information about the lines which improve the efficiency of this method -* when many repeated calls are made. An error will be reported if -* either structure does not refer to the Frame specified by "this". -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - SkyLineDef *sl1; /* SkyLine information for line 1 */ - SkyLineDef *sl2; /* SkyLine information for line 2 */ - const int *perm; /* Pointer to axis permutation array */ - double *crossing; /* Pointer to returned array */ - double *b; /* Pointer to Cartesian coords */ - double len; /* Vector length */ - double p[ 2 ]; /* Temporary (lon,lat) pair */ - double temp[ 3 ]; /* Temporary vector */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - if( cross ) *cross = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Allocate returned array (2 elements for the lon and lat values, plus 3 - for the corresponding (x,y,z) coords). */ - crossing = astMalloc( sizeof(double)*5 ); - -/* Check that both lines refer to the supplied Frame. */ - if( l1->frame != this ) { - astError( AST__INTER, "astLineCrossing(%s): First supplied line does " - "not relate to the supplied %s (AST internal programming " - "error).", status, astGetClass( this ), astGetClass( this ) ); - - } else if( l2->frame != this ) { - astError( AST__INTER, "astLineCrossing(%s): Second supplied line does " - "not relate to the supplied %s (AST internal programming " - "error).", status, astGetClass( this ), astGetClass( this ) ); - -/* Recast the supplied AstLineDefs into a SkyLineDefs to get the different - structure (we know from the above check on the Frame that it is safe to - do this). */ - } else if( crossing ){ - sl1 = (SkyLineDef *) l1; - sl2 = (SkyLineDef *) l2; - -/* Point of intersection of the two great circles is perpendicular to the - pole vectors of both great circles. Put the Cartesian coords in elements - 2 to 4 of the returned array. */ - palDvxv( sl1->q, sl2->q, temp ); - b = crossing + 2; - palDvn( temp, b, &len ); - -/* See if this point is within the length of both arcs. If so return it. */ - if( LineIncludes( sl2, b, status ) && LineIncludes( sl1, b, status ) ) { - result = 1; - -/* If not, see if the negated b vector is within the length of both arcs. - If so return it. Otherwise, we return zero. */ - } else { - b[ 0 ] *= -1.0; - b[ 1 ] *= -1.0; - b[ 2 ] *= -1.0; - if( LineIncludes( sl2, b, status ) && LineIncludes( sl1, b, status ) ) result = 1; - } - -/* Store the spherical coords in elements 0 and 1 of the returned array. */ - palDcc2s( b, p, p + 1 ); - -/* Permute the spherical axis value into the order used by the SkyFrame. */ - perm = astGetPerm( this ); - if( perm ){ - crossing[ 0 ] = p[ perm[ 0 ] ]; - crossing[ 1 ] = p[ perm[ 1 ] ]; - } - } - -/* If an error occurred, return 0. */ - if( !astOK ) { - result = 0; - crossing = astFree( crossing ); - } - -/* Return the array */ - if( cross ) { - *cross = crossing; - } else { - crossing = astFree( crossing ); - } - -/* Return the result. */ - return result; -} - -static AstLineDef *LineDef( AstFrame *this, const double start[2], - const double end[2], int *status ) { -/* -* Name: -* LineDef - -* Purpose: -* Creates a structure describing a line segment in a 2D Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* AstLineDef *LineDef( AstFrame *this, const double start[2], -* const double end[2], int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astLineDef -* method inherited from the Frame class). - -* Description: -* This function creates a structure containing information describing a -* given line segment within the supplied 2D Frame. This may include -* information which allows other methods such as astLineCrossing to -* function more efficiently. Thus the returned structure acts as a -* cache to store intermediate values used by these other methods. - -* Parameters: -* this -* Pointer to the Frame. Must have 2 axes. -* start -* An array of 2 doubles marking the start of the line segment. -* end -* An array of 2 doubles marking the end of the line segment. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the memory structure containing the description of the -* line. This structure should be freed using astFree when no longer -* needed. A NULL pointer is returned (without error) if any of the -* supplied axis values are AST__BAD. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - SkyLineDef *result; /* Returned value */ - const int *perm; /* Axis permutation array */ - double le; /* Length of end vector */ - double len; /* Permuted point1 coordinates */ - double ls; /* Length of start vector */ - double p1[ 2 ]; /* Permuted point1 coordinates */ - double p2[ 2 ]; /* Permuted point2 coordinates */ - double temp[3]; /* Cartesian coords at offset position */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Check the axis values are good */ - if( start[ 0 ] != AST__BAD && start[ 1 ] != AST__BAD && - end[ 0 ] != AST__BAD && end[ 1 ] != AST__BAD ) { - -/* Allocate memory for the returned structure. */ - result = astMalloc( sizeof( SkyLineDef ) ); - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( perm ) { - -/* Apply the axis permutation array to obtain the coordinates of the two - input points in the required (longitude,latitude) order. */ - p1[ perm[ 0 ] ] = start[ 0 ]; - p1[ perm[ 1 ] ] = start[ 1 ]; - p2[ perm[ 0 ] ] = end[ 0 ]; - p2[ perm[ 1 ] ] = end[ 1 ]; - -/* Convert each point into a 3-vector of unit length and store in the - returned structure. */ - palDcs2c( p1[ 0 ], p1[ 1 ], result->start ); - palDcs2c( p2[ 0 ], p2[ 1 ], result->end ); - -/* Calculate the great circle distance between the points in radians and - store in the result structure. Correct for rounding errors in palDcs2c - that can result in the vectors not having exactly unit length. */ - result->length = palDvdv( result->start, result->end ); - ls = result->start[0]*result->start[0] + - result->start[1]*result->start[1] + - result->start[2]*result->start[2]; - le = result->end[0]*result->end[0] + - result->end[1]*result->end[1] + - result->end[2]*result->end[2]; - result->length = acos( result->length/sqrt( ls*le ) ); - -/* Find a unit vector representing the pole of the system in which the - equator is given by the great circle. This is such that going the - short way from the start to the end, the pole is to the left of the - line as seen by the observer (i.e. from the centre of the sphere). - If the line has zero length, or 180 degrees length, the pole is - undefined, so we use an arbitrary value. */ - if( result->length == 0.0 || result->length > pi - 5.0E-11 ) { - palDcs2c( p1[ 0 ] + 0.01, p1[ 1 ] + 0.01, temp ); - palDvxv( temp, result->start, result->dir ); - } else { - palDvxv( result->end, result->start, result->dir ); - } - palDvn( result->dir, result->q, &len ); - -/* Also store a point which is 90 degrees along the great circle from the - start. */ - palDvxv( result->start, result->q, result->dir ); - -/* Store a pointer to the defining SkyFrame. */ - result->frame = this; - -/* Indicate that the line is considered to be terminated at the start and - end points. */ - result->infinite = 0; - -/* Normalise the spherical start and end positions stored in the returned - structure. */ - result->start_2d[ 0 ] = start[ 0 ]; - result->start_2d[ 1 ] = start[ 1 ]; - result->end_2d[ 0 ] = end[ 0 ]; - result->end_2d[ 1 ] = end[ 1 ]; - - astNorm( this, result->start_2d ); - astNorm( this, result->end_2d ); - } - } - -/* Free the returned pointer if an error occurred. */ - if( !astOK ) result = astFree( result ); - -/* Return a pointer to the output structure. */ - return (AstLineDef *) result; -} - -static int LineIncludes( SkyLineDef *l, double point[3], int *status ) { -/* -* Name: -* LineIncludes - -* Purpose: -* Determine if a line includes a point which is known to be in the -* great circle. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int LineIncludes( SkyLineDef *l, double point[3], int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astLineIncludes -* method inherited from the Frame class). - -* Description: -* The supplied point is assumed to be a point on the great circle of -* which the supplied line is a segment. This function returns true if -* "point" is within the bounds of the segment (the end point of the -* line is assumed * not to be part of the segment). - -* Parameters: -* l -* Pointer to the structure defining the line. -* point -* An array holding the Cartesian coords of the point to be tested. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the line includes the point. - -* Notes: -* - Zero will be returned if this function is invoked with the global -* error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - double t1, t2, t3; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* If the line is of infite length, it is assumed to include the supplied - point. */ - if( l->infinite ) return 1; - -/* Otherwise, get the unsigned distance of the point from the start of the - line in the range 0 - 180 degs. Check it is less than the line length. - Then check that the point is not more than 90 degs away from the quarter - point. */ - t1 = palDvdv( l->start, point ); - t2 = acos( t1 ); - t3 = palDvdv( l->dir, point ); - return ( ((l->length > 0) ? t2 < l->length : t2 == 0.0 ) && t3 >= -1.0E-8 ); -} - -static void LineOffset( AstFrame *this, AstLineDef *line, double par, - double prp, double point[2], int *status ){ -/* -* Name: -* LineOffset - -* Purpose: -* Find a position close to a line. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void LineOffset( AstFrame *this, AstLineDef *line, double par, -* double prp, double point[2], int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astLineOffset -* method inherited from the Frame class). - -* Description: -* This function returns a position formed by moving a given distance along -* the supplied line, and then a given distance away from the supplied line. - -* Parameters: -* this -* Pointer to the Frame. -* line -* Pointer to the structure defining the line. -* par -* The distance to move along the line from the start towards the end. -* prp -* The distance to move at right angles to the line. Positive -* values result in movement to the left of the line, as seen from -* the observer, when moving from start towards the end. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The pointer supplied for "line" should have been created using the -* astLineDef method. This structure contains cached information about the -* line which improves the efficiency of this method when many repeated -* calls are made. An error will be reported if the structure does not -* refer to the Frame specified by "this". -*- -*/ - -/* Local Variables; */ - SkyLineDef *sl; - const int *perm; - double c; - double nx; - double ny; - double nz; - double p[2]; - double s; - double v[3]; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check that the line refers to the supplied Frame. */ - if( line->frame != this ) { - astError( AST__INTER, "astLineOffset(%s): The supplied line does " - "not relate to the supplied %s (AST internal programming " - "error).", status, astGetClass( this ), astGetClass( this ) ); - -/* This implementation uses spherical geometry. */ - } else { - -/* Get a pointer to the SkyLineDef structure. */ - sl = (SkyLineDef *) line; - -/* Move a distance par from start to end. */ - c = cos( par ); - s = sin( par ); - nx = c * sl->start[ 0 ] + s * sl->dir[ 0 ]; - ny = c * sl->start[ 1 ] + s * sl->dir[ 1 ]; - nz = c * sl->start[ 2 ] + s * sl->dir[ 2 ]; - -/* Move a distance prp from this point towards the pole point. */ - if( prp != 0.0 ) { - c = cos( prp ); - s = sin( prp ); - v[ 0 ] = c * nx + s * sl->q[ 0 ]; - v[ 1 ] = c * ny + s * sl->q[ 1 ]; - v[ 2 ] = c * nz + s * sl->q[ 2 ]; - } else { - v[ 0 ] = nx; - v[ 1 ] = ny; - v[ 2 ] = nz; - } - -/* Convert to lon/lat */ - palDcc2s( v, p, p + 1 ); - -/* Permute the spherical axis value into the order used by the SkyFrame. */ - perm = astGetPerm( this ); - if( perm ){ - point[ 0 ] = p[ perm[ 0 ] ]; - point[ 1 ] = p[ perm[ 1 ] ]; - } - } -} - -static int MakeSkyMapping( AstSkyFrame *target, AstSkyFrame *result, - AstSystemType align_sys, AstMapping **map, int *status ) { -/* -* Name: -* MakeSkyMapping - -* Purpose: -* Generate a Mapping between two SkyFrames. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int MakeSkyMapping( AstSkyFrame *target, AstSkyFrame *result, -* AstSystemType align_sys, AstMapping **map, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function takes two SkyFrames and generates a Mapping that -* converts between them, taking account of differences in their -* coordinate systems, equinox value, epoch, etc. (but not allowing -* for any axis permutations). - -* Parameters: -* target -* Pointer to the first SkyFrame. -* result -* Pointer to the second SkyFrame. -* align_sys -* The system in which to align the two SkyFrames. -* map -* Pointer to a location which is to receive a pointer to the -* returned Mapping. The forward transformation of this Mapping -* will convert from "target" coordinates to "result" -* coordinates, and the inverse transformation will convert in -* the opposite direction (all coordinate values in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Mapping could be generated, or zero if the two -* SkyFrames are sufficiently un-related that no meaningful Mapping -* can be produced. - -* Notes: -* A value of zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Constants: */ -#define MAX_ARGS 4 /* Max arguments for an SlaMap conversion */ - -/* Local Variables: */ - AstMapping *omap; /* Mapping from coorinates to offsets */ - AstMapping *tmap2; /* Temporary Mapping */ - AstMapping *tmap; /* Temporary Mapping */ - AstSlaMap *slamap; /* Pointer to SlaMap */ - AstSystemType result_system; /* Code to identify result coordinate system */ - AstSystemType system; /* Code to identify coordinate system */ - AstSystemType target_system; /* Code to identify target coordinate system */ - double args[ MAX_ARGS ]; /* Conversion argument array */ - double epoch; /* Epoch as Modified Julian Date */ - double epoch_B; /* Besselian epoch as decimal years */ - double epoch_J; /* Julian epoch as decimal years */ - double equinox; /* Equinox as Modified Julian Date */ - double equinox_B; /* Besselian equinox as decimal years */ - double equinox_J; /* Julian equinox as decimal years */ - double diurab; /* Magnitude of diurnal aberration vector */ - double last; /* Local Apparent Sidereal Time */ - double lat; /* Observers latitude */ - double result_epoch; /* Result frame Epoch */ - double result_equinox; /* Result frame Epoch */ - double target_epoch; /* Target frame Epoch */ - double target_equinox; /* Target frame Epoch */ - int isunit; /* Is the SlaMap effectively a unit mapping? */ - int match; /* Mapping can be generated? */ - int step1; /* Convert target to FK5 J2000? */ - int step2; /* Convert FK5 J2000 to align sys? */ - int step3; /* Convert align sys to FK5 J2000? */ - int step4; /* Convert FK5 J2000 to result? */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise the returned values. */ - match = 1; - *map = NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - epoch_B = 0.0; - epoch_J = 0.0; - equinox_B = 0.0; - equinox_J = 0.0; - -/* Get the two epoch values. */ - result_epoch = astGetEpoch( result ); - target_epoch = astGetEpoch( target ); - -/* Get the two equinox values. */ - result_equinox = astGetEquinox( result ); - target_equinox = astGetEquinox( target ); - -/* Get the two system values. */ - result_system = astGetSystem( result ); - target_system = astGetSystem( target ); - -/* If either system is not references to the equinox given by the Equinox - attribute, then use the equinox of the other system rather than - adopting the arbitrary default of J2000. */ - if( !EQREF(result_system) ) result_equinox = target_equinox; - if( !EQREF(target_system) ) target_equinox = result_equinox; - -/* If both systems are unknown, assume they are the same. Return a UnitMap. - We need to do this, otherwise a simple change of Title (for instance) - will result in a FrameSet whose current Frame has System=AST__UNKNOWN - loosing its integrity. */ - if( target_system == AST__UNKNOWN && result_system == AST__UNKNOWN ) { - *map = (AstMapping *) astUnitMap( 2, "", status ); - return 1; - } - -/* The total Mapping is divided into two parts in series; the first part - converts from the target SkyFrame to the alignment system, using the - Epoch and Equinox of the target Frame, the second part converts from - the alignment system to the result SkyFrame, using the Epoch and Equinox - of the result Frame. Each of these parts has an arbitrary input and an - output system, and therefore could be implemented using a collection - of NxN conversions. To reduce the complexity, each part is implement - by converting from the input system to FK5 J2000, and then from FK5 - J2000 to the output system. This scheme required only N conversions - rather than NxN. Thus overall the total Mapping is made up of 4 steps - in series. Some of these steps may be ommitted if they are effectively - a UnitMap. Determine which steps need to be included. Assume all need - to be done to begin with. */ - step1 = 1; - step2 = 1; - step3 = 1; - step4 = 1; - -/* If the target system is the same as the alignment system, neither of the - first 2 steps need be done. */ - if( target_system == align_sys ) { - step1 = 0; - step2 = 0; - } - -/* If the result system is the same as the alignment system, neither of the - last 2 steps need be done. */ - if( result_system == align_sys ) { - step3 = 0; - step4 = 0; - } - -/* If the two epochs are the same, or if the alignment system is FK5 J2000, - steps 2 and 3 are not needed. */ - if( step2 && step3 ) { - if( align_sys == AST__FK5 || result_epoch == target_epoch ) { - step2 = 0; - step3 = 0; - } - } - -/* None are needed if the target and result SkyFrames have the same - System, Epoch and Equinox. */ - if( result_system == target_system && - result_epoch == target_epoch && - result_equinox == target_equinox ) { - step1 = 0; - step2 = 0; - step3 = 0; - step4 = 0; - } - -/* Create an initial (null) SlaMap. */ - slamap = astSlaMap( 0, "", status ); - -/* Define local macros as shorthand for adding sky coordinate - conversions to this SlaMap. Each macro simply stores details of - the additional arguments in the "args" array and then calls - astSlaAdd. The macros differ in the number of additional argument - values. */ - #define TRANSFORM_0(cvt) \ - astSlaAdd( slamap, cvt, 0, NULL ); - - #define TRANSFORM_1(cvt,arg0) \ - args[ 0 ] = arg0; \ - astSlaAdd( slamap, cvt, 1, args ); - - #define TRANSFORM_2(cvt,arg0,arg1) \ - args[ 0 ] = arg0; \ - args[ 1 ] = arg1; \ - astSlaAdd( slamap, cvt, 2, args ); - - #define TRANSFORM_3(cvt,arg0,arg1,arg2) \ - args[ 0 ] = arg0; \ - args[ 1 ] = arg1; \ - args[ 2 ] = arg2; \ - astSlaAdd( slamap, cvt, 3, args ); - - #define TRANSFORM_4(cvt,arg0,arg1,arg2,arg3) \ - args[ 0 ] = arg0; \ - args[ 1 ] = arg1; \ - args[ 2 ] = arg2; \ - args[ 3 ] = arg3; \ - astSlaAdd( slamap, cvt, 4, args ); - -/* Convert _to_ FK5 J2000.0 coordinates. */ -/* ===================================== */ -/* The overall conversion is formulated in four phases. In this first - phase, we convert from the target coordinate system to intermediate sky - coordinates expressed using the FK5 system, mean equinox J2000.0. */ - -/* Obtain the sky coordinate system, equinox, epoch, etc, of the target - SkyFrame. */ - system = target_system; - equinox = target_equinox; - epoch = target_epoch; - last = GetLAST( target, status ); - diurab = GetDiurab( target, status ); - lat = astGetObsLat( target ); - if( astOK && step1 ) { - -/* Convert the equinox and epoch values (stored as Modified Julian - Dates) into the equivalent Besselian and Julian epochs (as decimal - years). */ - equinox_B = palEpb( equinox ); - equinox_J = palEpj( equinox ); - epoch_B = palEpb( epoch ); - epoch_J = palEpj( epoch ); - -/* Formulate the conversion... */ - -/* From FK4. */ -/* --------- */ -/* If necessary, apply the old-style FK4 precession model to bring the - equinox to B1950.0, with rigorous handling of the E-terms of - aberration. Then convert directly to FK5 J2000.0 coordinates. */ - if ( system == AST__FK4 ) { - VerifyMSMAttrs( target, result, 1, "Equinox Epoch", "astMatch", status ); - if ( equinox_B != 1950.0 ) { - TRANSFORM_1( "SUBET", equinox_B ) - TRANSFORM_2( "PREBN", equinox_B, 1950.0 ) - TRANSFORM_1( "ADDET", 1950.0 ) - } - TRANSFORM_1( "FK45Z", epoch_B ) - -/* From FK4 with no E-terms. */ -/* ------------------------- */ -/* This is the same as above, except that we do not need to subtract - the E-terms initially as they are already absent. */ - } else if ( system == AST__FK4_NO_E ) { - VerifyMSMAttrs( target, result, 1, "Equinox Epoch", "astMatch", status ); - if ( equinox_B != 1950.0 ) { - TRANSFORM_2( "PREBN", equinox_B, 1950.0 ) - } - TRANSFORM_1( "ADDET", 1950.0 ) - TRANSFORM_1( "FK45Z", epoch_B ) - -/* From FK5. */ -/* --------- */ -/* We simply need to apply a precession correction for the change of - equinox. Omit even this if the equinox is already J2000.0. */ - } else if ( system == AST__FK5 ) { - VerifyMSMAttrs( target, result, 1, "Equinox", "astMatch", status ); - if ( equinox_J != 2000.0 ) { - TRANSFORM_2( "PREC", equinox_J, 2000.0 ); - } - -/* From J2000. */ -/* ----------- */ -/* Convert from J2000 to ICRS, then from ICRS to FK5. */ - } else if ( system == AST__J2000 ) { - VerifyMSMAttrs( target, result, 1, "Epoch", "astMatch", status ); - TRANSFORM_0( "J2000H" ) - TRANSFORM_1( "HFK5Z", epoch_J ); - -/* From geocentric apparent. */ -/* ------------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( system == AST__GAPPT ) { - VerifyMSMAttrs( target, result, 1, "Epoch", "astMatch", status ); - TRANSFORM_2( "AMP", epoch, 2000.0 ) - -/* From ecliptic coordinates. */ -/* -------------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( system == AST__ECLIPTIC ) { - VerifyMSMAttrs( target, result, 1, "Equinox", "astMatch", status ); - TRANSFORM_1( "ECLEQ", equinox ) - -/* From helio-ecliptic coordinates. */ -/* -------------------------------- */ - } else if ( system == AST__HELIOECLIPTIC ) { - VerifyMSMAttrs( target, result, 1, "Epoch", "astMatch", status ); - TRANSFORM_1( "HEEQ", epoch ) - -/* From galactic coordinates. */ -/* -------------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( system == AST__GALACTIC ) { - TRANSFORM_0( "GALEQ" ) - -/* From ICRS. */ -/* ---------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( system == AST__ICRS ) { - VerifyMSMAttrs( target, result, 1, "Epoch", "astMatch", status ); - TRANSFORM_1( "HFK5Z", epoch_J ); - -/* From supergalactic coordinates. */ -/* ------------------------------- */ -/* Convert to galactic coordinates and then to FK5 J2000.0 - equatorial. */ - } else if ( system == AST__SUPERGALACTIC ) { - TRANSFORM_0( "SUPGAL" ) - TRANSFORM_0( "GALEQ" ) - -/* From AzEl. */ -/* ---------- */ -/* Rotate from horizon to equator (H2E), shift hour angle into RA (H2R), - go from geocentric apparent to FK5 J2000. */ - } else if ( system == AST__AZEL ) { - VerifyMSMAttrs( target, result, 1, "ObsLon ObsLat Epoch", "astMatch", status ); - TRANSFORM_2( "H2E", lat, diurab ) - TRANSFORM_1( "H2R", last ) - TRANSFORM_2( "AMP", epoch, 2000.0 ) - -/* From unknown coordinates. */ -/* ------------------------- */ -/* No conversion is possible. */ - } else if ( system == AST__UNKNOWN ) { - match = 0; - } - } - -/* Convert _from_ FK5 J2000.0 coordinates _to_ the alignment system. */ -/* ============================================================ */ -/* In this second phase, we convert to the system given by the align_sys - argument (if required), still using the properties of the target Frame. */ - if ( astOK && match && step2 ) { - -/* Align in FK4. */ -/* --------------- */ -/* Convert directly from FK5 J2000.0 to FK4 B1950.0 coordinates at the - appropriate epoch. Then, if necessary, apply the old-style FK4 - precession model to bring the equinox to that required, with - rigorous handling of the E-terms of aberration. */ - if ( align_sys == AST__FK4 ) { - VerifyMSMAttrs( target, result, 1, "Equinox Epoch", "astMatch", status ); - TRANSFORM_1( "FK54Z", epoch_B ) - if ( equinox_B != 1950.0 ) { - TRANSFORM_1( "SUBET", 1950.0 ) - TRANSFORM_2( "PREBN", 1950.0, equinox_B ) - TRANSFORM_1( "ADDET", equinox_B ) - } - -/* Align in FK4 with no E-terms. */ -/* ------------------------------- */ -/* This is the same as above, except that we do not need to add the - E-terms at the end. */ - } else if ( align_sys == AST__FK4_NO_E ) { - VerifyMSMAttrs( target, result, 1, "Equinox Epoch", "astMatch", status ); - TRANSFORM_1( "FK54Z", epoch_B ) - TRANSFORM_1( "SUBET", 1950.0 ) - if ( equinox_B != 1950.0 ) { - TRANSFORM_2( "PREBN", 1950.0, equinox_B ) - } - -/* Align in FK5. */ -/* ------------- */ -/* We simply need to apply a precession correction for the change of - equinox. Omit even this if the required equinox is J2000.0. */ - } else if ( align_sys == AST__FK5 ) { - VerifyMSMAttrs( target, result, 1, "Equinox", "astMatch", status ); - if ( equinox_J != 2000.0 ) { - TRANSFORM_2( "PREC", 2000.0, equinox_J ) - } - -/* Align in J2000. */ -/* --------------- */ -/* Mov from FK5 to ICRS, and from ICRS to J2000. */ - } else if ( align_sys == AST__J2000 ) { - VerifyMSMAttrs( target, result, 1, "Epoch", "astMatch", status ); - TRANSFORM_1( "FK5HZ", epoch_J ) - TRANSFORM_0( "HJ2000" ) - -/* Align in geocentric apparent. */ -/* ------------------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( align_sys == AST__GAPPT ) { - VerifyMSMAttrs( target, result, 1, "Epoch", "astMatch", status ); - TRANSFORM_2( "MAP", 2000.0, epoch ) - -/* Align in ecliptic coordinates. */ -/* -------------------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( align_sys == AST__ECLIPTIC ) { - VerifyMSMAttrs( target, result, 1, "Equinox", "astMatch", status ); - TRANSFORM_1( "EQECL", equinox ) - -/* Align in helio-ecliptic coordinates. */ -/* ------------------------------------ */ - } else if ( align_sys == AST__HELIOECLIPTIC ) { - VerifyMSMAttrs( target, result, 1, "Epoch", "astMatch", status ); - TRANSFORM_1( "EQHE", epoch ) - -/* Align in galactic coordinates. */ -/* -------------------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( align_sys == AST__GALACTIC ) { - TRANSFORM_0( "EQGAL" ) - -/* Align in ICRS. */ -/* -------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( align_sys == AST__ICRS ) { - VerifyMSMAttrs( target, result, 1, "Epoch", "astMatch", status ); - TRANSFORM_1( "FK5HZ", epoch_J ) - -/* Align in supergalactic coordinates. */ -/* ------------------------------------- */ -/* Convert to galactic coordinates and then to supergalactic. */ - } else if ( align_sys == AST__SUPERGALACTIC ) { - TRANSFORM_0( "EQGAL" ) - TRANSFORM_0( "GALSUP" ) - -/* Align in AzEl coordinates. */ -/* -------------------------- */ -/* Go from FK5 J2000 to geocentric apparent (MAP), shift RA into hour angle - (R2H), rotate from equator to horizon (E2H). */ - } else if ( align_sys == AST__AZEL ) { - VerifyMSMAttrs( target, result, 1, "ObsLon ObsLat Epoch", "astMatch", status ); - TRANSFORM_2( "MAP", 2000.0, epoch ) - TRANSFORM_1( "R2H", last ) - TRANSFORM_2( "E2H", lat, diurab ) - -/* Align in unknown coordinates. */ -/* ------------------------------- */ -/* No conversion is possible. */ - } else if ( align_sys == AST__UNKNOWN ) { - match = 0; - } - } - -/* Convert _from_ the alignment system _to_ FK5 J2000.0 coordinates */ -/* =========================================================== */ -/* In this third phase, we convert from the alignment system (if required) - to the intermediate FK5 J2000 system, using the properties of the - result SkyFrame. */ - -/* Obtain the sky coordinate system, equinox, epoch, etc, of the result - SkyFrame. */ - system = result_system; - equinox = result_equinox; - epoch = result_epoch; - diurab = GetDiurab( result, status ); - last = GetLAST( result, status ); - lat = astGetObsLat( result ); - -/* Convert the equinox and epoch values (stored as Modified Julian - Dates) into the equivalent Besselian and Julian epochs (as decimal - years). */ - if( astOK ) { - equinox_B = palEpb( equinox ); - equinox_J = palEpj( equinox ); - epoch_B = palEpb( epoch ); - epoch_J = palEpj( epoch ); - } - -/* Check we need to do the conversion. */ - if ( astOK && match && step3 ) { - -/* Formulate the conversion... */ - -/* From FK4. */ -/* --------- */ -/* If necessary, apply the old-style FK4 precession model to bring the - equinox to B1950.0, with rigorous handling of the E-terms of - aberration. Then convert directly to FK5 J2000.0 coordinates. */ - if ( align_sys == AST__FK4 ) { - VerifyMSMAttrs( target, result, 3, "Equinox Epoch", "astMatch", status ); - if ( equinox_B != 1950.0 ) { - TRANSFORM_1( "SUBET", equinox_B ) - TRANSFORM_2( "PREBN", equinox_B, 1950.0 ) - TRANSFORM_1( "ADDET", 1950.0 ) - } - TRANSFORM_1( "FK45Z", epoch_B ) - -/* From FK4 with no E-terms. */ -/* ------------------------- */ -/* This is the same as above, except that we do not need to subtract - the E-terms initially as they are already absent. */ - } else if ( align_sys == AST__FK4_NO_E ) { - VerifyMSMAttrs( target, result, 3, "Equinox Epoch", "astMatch", status ); - if ( equinox_B != 1950.0 ) { - TRANSFORM_2( "PREBN", equinox_B, 1950.0 ) - } - TRANSFORM_1( "ADDET", 1950.0 ) - TRANSFORM_1( "FK45Z", epoch_B ) - -/* From FK5. */ -/* --------- */ -/* We simply need to apply a precession correction for the change of - equinox. Omit even this if the equinox is already J2000.0. */ - } else if ( align_sys == AST__FK5 ) { - VerifyMSMAttrs( target, result, 3, "Equinox", "astMatch", status ); - if ( equinox_J != 2000.0 ) { - TRANSFORM_2( "PREC", equinox_J, 2000.0 ); - } - -/* From geocentric apparent. */ -/* ------------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( align_sys == AST__GAPPT ) { - VerifyMSMAttrs( target, result, 3, "Epoch", "astMatch", status ); - TRANSFORM_2( "AMP", epoch, 2000.0 ) - -/* From ecliptic coordinates. */ -/* -------------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( align_sys == AST__ECLIPTIC ) { - VerifyMSMAttrs( target, result, 3, "Equinox", "astMatch", status ); - TRANSFORM_1( "ECLEQ", equinox ) - -/* From helio-ecliptic coordinates. */ -/* -------------------------------- */ - } else if ( align_sys == AST__HELIOECLIPTIC ) { - VerifyMSMAttrs( target, result, 3, "Epoch", "astMatch", status ); - TRANSFORM_1( "HEEQ", epoch ) - -/* From galactic coordinates. */ -/* -------------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( align_sys == AST__GALACTIC ) { - TRANSFORM_0( "GALEQ" ) - -/* From ICRS. */ -/* ---------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( align_sys == AST__ICRS ) { - VerifyMSMAttrs( target, result, 3, "Epoch", "astMatch", status ); - TRANSFORM_1( "HFK5Z", epoch_J ) - -/* From J2000. */ -/* ----------- */ -/* From J2000 to ICRS, and from ICRS to FK5. */ - } else if ( align_sys == AST__J2000 ) { - VerifyMSMAttrs( target, result, 3, "Epoch", "astMatch", status ); - TRANSFORM_0( "J2000H" ) - TRANSFORM_1( "HFK5Z", epoch_J ) - -/* From supergalactic coordinates. */ -/* ------------------------------- */ -/* Convert to galactic coordinates and then to FK5 J2000.0 - equatorial. */ - } else if ( align_sys == AST__SUPERGALACTIC ) { - TRANSFORM_0( "SUPGAL" ) - TRANSFORM_0( "GALEQ" ) - -/* From AzEl. */ -/* ---------- */ -/* Rotate from horizon to equator (H2E), shift hour angle into RA (H2R), - go from geocentric apparent to FK5 J2000. */ - } else if ( align_sys == AST__AZEL ) { - VerifyMSMAttrs( target, result, 3, "ObsLon ObsLat Epoch", "astMatch", status ); - TRANSFORM_2( "H2E", lat, diurab ) - TRANSFORM_1( "H2R", last ) - TRANSFORM_2( "AMP", epoch, 2000.0 ) - -/* From unknown coordinates. */ -/* ------------------------------- */ -/* No conversion is possible. */ - } else if ( align_sys == AST__UNKNOWN ) { - match = 0; - } - } - -/* Convert _from_ FK5 J2000.0 coordinates. */ -/* ======================================= */ -/* In this fourth and final phase, we convert to the result coordinate - system from the intermediate FK5 J2000 sky coordinates generated above. */ - if ( astOK && match && step4 ) { - -/* To FK4. */ -/* ------- */ -/* Convert directly from FK5 J2000.0 to FK4 B1950.0 coordinates at the - appropriate epoch. Then, if necessary, apply the old-style FK4 - precession model to bring the equinox to that required, with - rigorous handling of the E-terms of aberration. */ - if ( system == AST__FK4 ) { - VerifyMSMAttrs( target, result, 3, "Equinox Epoch", "astMatch", status ); - TRANSFORM_1( "FK54Z", epoch_B ) - if ( equinox_B != 1950.0 ) { - TRANSFORM_1( "SUBET", 1950.0 ) - TRANSFORM_2( "PREBN", 1950.0, equinox_B ) - TRANSFORM_1( "ADDET", equinox_B ) - } - -/* To FK4 with no E-terms. */ -/* ----------------------- */ -/* This is the same as above, except that we do not need to add the - E-terms at the end. */ - } else if ( system == AST__FK4_NO_E ) { - VerifyMSMAttrs( target, result, 3, "Equinox Epoch", "astMatch", status ); - TRANSFORM_1( "FK54Z", epoch_B ) - TRANSFORM_1( "SUBET", 1950.0 ) - if ( equinox_B != 1950.0 ) { - TRANSFORM_2( "PREBN", 1950.0, equinox_B ) - } - -/* To FK5. */ -/* ------- */ -/* We simply need to apply a precession correction for the change of - equinox. Omit even this if the required equinox is J2000.0. */ - } else if ( system == AST__FK5 ) { - VerifyMSMAttrs( target, result, 3, "Equinox", "astMatch", status ); - if ( equinox_J != 2000.0 ) { - TRANSFORM_2( "PREC", 2000.0, equinox_J ) - } - -/* To geocentric apparent. */ -/* ----------------------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( system == AST__GAPPT ) { - VerifyMSMAttrs( target, result, 3, "Epoch", "astMatch", status ); - TRANSFORM_2( "MAP", 2000.0, epoch ) - -/* To ecliptic coordinates. */ -/* ------------------------ */ -/* This conversion is supported directly by SLALIB. */ - } else if ( system == AST__ECLIPTIC ) { - VerifyMSMAttrs( target, result, 3, "Equinox", "astMatch", status ); - TRANSFORM_1( "EQECL", equinox ) - -/* To helio-ecliptic coordinates. */ -/* ------------------------------ */ - } else if ( system == AST__HELIOECLIPTIC ) { - VerifyMSMAttrs( target, result, 3, "Epoch", "astMatch", status ); - TRANSFORM_1( "EQHE", epoch ) - -/* To galactic coordinates. */ -/* ------------------------ */ -/* This conversion is supported directly by SLALIB. */ - } else if ( system == AST__GALACTIC ) { - TRANSFORM_0( "EQGAL" ) - -/* To ICRS. */ -/* -------- */ -/* This conversion is supported directly by SLALIB. */ - } else if ( system == AST__ICRS ) { - VerifyMSMAttrs( target, result, 3, "Epoch", "astMatch", status ); - TRANSFORM_1( "FK5HZ", epoch_J ) - -/* To J2000. */ -/* --------- */ -/* From FK5 to ICRS, then from ICRS to J2000. */ - } else if ( system == AST__J2000 ) { - VerifyMSMAttrs( target, result, 3, "Epoch", "astMatch", status ); - TRANSFORM_1( "FK5HZ", epoch_J ) - TRANSFORM_0( "HJ2000" ) - -/* To supergalactic coordinates. */ -/* ----------------------------- */ -/* Convert to galactic coordinates and then to supergalactic. */ - } else if ( system == AST__SUPERGALACTIC ) { - TRANSFORM_0( "EQGAL" ) - TRANSFORM_0( "GALSUP" ) - -/* To AzEl */ -/* ------- */ -/* Go from FK5 J2000 to geocentric apparent (MAP), shift RA into hour angle - (R2H), rotate from equator to horizon (E2H). */ - } else if ( system == AST__AZEL ) { - VerifyMSMAttrs( target, result, 3, "ObsLon ObsLat Epoch", "astMatch", status ); - TRANSFORM_2( "MAP", 2000.0, epoch ) - TRANSFORM_1( "R2H", last ) - TRANSFORM_2( "E2H", lat, diurab ) - -/* To unknown coordinates. */ -/* ----------------------------- */ -/* No conversion is possible. */ - } else if ( system == AST__UNKNOWN ) { - match = 0; - } - } - -/* See of the slamap created above is effectively a unit mapping to - within the tolerance of the more accurate SkyFrame (target or result). */ - isunit = TestSlaUnit( target, result, slamap, status ); - -/* Now need to take account of the possibility that the input or output - SkyFrame may represent an offset system rather than a coordinate system. - Form the Mapping from the target coordinate system to the associated - offset system. A UnitMap is returned if the target does not use an - offset system. */ - omap = SkyOffsetMap( target, status ); - -/* Invert it to get the Mapping from the actual used system (whther - offsets or coordinates) to the coordinate system. */ - astInvert( omap ); - -/* Combine it with the slamap created earlier, so that its coordinate - outputs feed the inputs of the slamap. We only do this if the slamap - is not effectively a unit mapping. Annul redundant pointers afterwards. */ - if( ! isunit ) { - tmap = (AstMapping *) astCmpMap( omap, slamap, 1, "", status ); - } else { - tmap = astClone( omap ); - } - omap = astAnnul( omap ); - slamap =astAnnul( slamap ); - -/* Now form the Mapping from the result coordinate system to the associated - offset system. A UnitMap is returned if the result does not use an - offset system. */ - omap = SkyOffsetMap( result, status ); - -/* Combine it with the above CmpMap, so that the CmpMap outputs feed the - new Mapping inputs. Annul redundant pointers afterwards. */ - tmap2 = (AstMapping *) astCmpMap( tmap, omap, 1, "", status ); - omap =astAnnul( omap ); - tmap =astAnnul( tmap ); - -/* Simplify the Mapping produced above (this eliminates any redundant - conversions) and annul the original pointer. */ - *map = astSimplify( tmap2 ); - tmap2 = astAnnul( tmap2 ); - -/* If an error occurred, annul the returned Mapping and clear the - returned values. */ - if ( !astOK ) { - *map = astAnnul( *map ); - match = -1; - } - -/* Return the result. */ - return match; - -/* Undefine macros local to this function. */ -#undef MAX_ARGS -#undef TRANSFORM_0 -#undef TRANSFORM_1 -#undef TRANSFORM_2 -#undef TRANSFORM_3 -} - -static int Match( AstFrame *template_frame, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* Match - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astMatch method -* inherited from the Frame class). - -* Description: -* This function matches a "template" SkyFrame to a "target" Frame and -* determines whether it is possible to convert coordinates between them. -* If it is, a mapping that performs the transformation is returned along -* with a new Frame that describes the coordinate system that results when -* this mapping is applied to the "target" coordinate system. In addition, -* information is returned to allow the axes in this "result" Frame to be -* associated with the corresponding axes in the "target" and "template" -* Frames from which they are derived. - -* Parameters: -* template -* Pointer to the template SkyFrame. This describes the coordinate system -* (or set of possible coordinate systems) into which we wish to convert -* our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate system in -* which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case. -* template_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the template SkyFrame axis from which -* it is derived. If it is not derived from any template SkyFrame axis, -* a value of -1 will be returned instead. -* target_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the target Frame axis from which it -* is derived. If it is not derived from any target Frame axis, a value -* of -1 will be returned instead. -* map -* Address of a location where a pointer to a new Mapping will be -* returned if the requested coordinate conversion is possible. If -* returned, the forward transformation of this Mapping may be used to -* convert coordinates between the "target" Frame and the "result" -* Frame (see below) and the inverse transformation will convert in the -* opposite direction. -* result -* Address of a location where a pointer to a new Frame will be returned -* if the requested coordinate conversion is possible. If returned, this -* Frame describes the coordinate system that results from applying the -* returned Mapping (above) to the "target" coordinate system. In -* general, this Frame will combine attributes from (and will therefore -* be more specific than) both the target and the template Frames. In -* particular, when the template allows the possibility of transformaing -* to any one of a set of alternative coordinate systems, the "result" -* Frame will indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate conversion is -* possible. Otherwise zero is returned (this will not in itself result in -* an error condition). - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* This implementation addresses the matching of a SkyFrame class object to -* any other class of Frame. A SkyFrame will match any class of SkyFrame -* (i.e. possibly from a derived class) but will not match a less -* specialised class of Frame. -*/ - -/* Local Variables: */ - AstFrame *frame0; /* Pointer to Frame underlying axis 0 */ - AstFrame *frame1; /* Pointer to Frame underlying axis 1 */ - AstSkyFrame *template; /* Pointer to template SkyFrame structure */ - int iaxis; /* Axis index */ - int iaxis0; /* Axis index underlying axis 0 */ - int iaxis1; /* Axis index underlying axis 1 */ - int match; /* Coordinate conversion possible? */ - int swap1; /* Template axes swapped? */ - int swap2; /* Target axes swapped? */ - int swap; /* Additional axis swap needed? */ - int target_axis0; /* Index of 1st SkyFrame axis in the target */ - int target_axis1; /* Index of 2nd SkyFrame axis in the target */ - int target_naxes; /* Number of target axes */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - swap = 0; - target_axis0 = -1; - target_axis1 = -1; - -/* Obtain a pointer to the template SkyFrame structure. */ - template = (AstSkyFrame *) template_frame; - -/* Obtain the number of axes in the target Frame. */ - target_naxes = astGetNaxes( target ); - -/* The first criterion for a match is that the template matches as a - Frame class object. This ensures that the number of axes (2) and - domain, etc. of the target Frame are suitable. Invoke the parent - "astMatch" method to verify this. */ - match = (*parent_match)( template_frame, target, matchsub, - template_axes, target_axes, map, result, status ); - -/* If a match was found, annul the returned objects, which are not - needed, but keep the memory allocated for the axis association - arrays, which we will re-use. */ - if ( astOK && match ) { - *map = astAnnul( *map ); - *result = astAnnul( *result ); - } - -/* If OK so far, obtain pointers to the primary Frames which underlie - all target axes. Stop when a SkyFrame axis is found. */ - if ( match && astOK ) { - - match = 0; - for( iaxis = 0; iaxis < target_naxes; iaxis++ ) { - astPrimaryFrame( target, iaxis, &frame0, &iaxis0 ); - if( astIsASkyFrame( frame0 ) ) { - target_axis0 = iaxis; - match = 1; - break; - } else { - frame0 = astAnnul( frame0 ); - } - } - -/* Check at least one SkyFrame axis was found it the target. */ - if( match ) { - -/* If so, search the remaining target axes for another axis that is - derived from the same SkyFrame. */ - match = 0; - for( iaxis++ ; iaxis < target_naxes; iaxis++ ) { - astPrimaryFrame( target, iaxis, &frame1, &iaxis1 ); - if( frame1 == frame0 ) { - target_axis1 = iaxis; - frame1 = astAnnul( frame1 ); - match = 1; - break; - } else { - frame1 = astAnnul( frame1 ); - } - } - -/* Annul the remaining Frame pointer used in the above tests. */ - frame0 = astAnnul( frame0 ); - } - -/* If this test is passed, we can now test that the underlying axis indices - are 0 and 1, in either order. This then ensures that we have a - single SkyFrame (not a compound Frame) with both axes present. */ - if ( match && astOK ) { - match = ( ( ( iaxis0 == 0 ) && ( iaxis1 == 1 ) ) || - ( ( iaxis1 == 0 ) && ( iaxis0 == 1 ) ) ); - } - - } - -/* If a possible match has been detected, we must now decide how the - order of the axes in the result Frame relates to the order of axes - in the target Frame. There are two factors involved. The first - depends on whether the axis permutation array for the template - SkyFrame (whose method we are executing) causes an axis - reversal. Determine this by permuting axis index zero. */ - if ( astOK && match ) { - swap1 = ( astValidateAxis( template, 0, 1, "astMatch" ) != 0 ); - -/* The second factor depends on whether the axes of the underlying - primary SkyFrame are reversed when seen in the target Frame. */ - swap2 = ( iaxis0 != 0 ); - -/* Combine these to determine if an additional axis swap will be - needed. */ - swap = ( swap1 != swap2 ); - -/* Now check to see if this additional swap is permitted by the - template's Permute attribute. */ - match = ( !swap || astGetPermute( template ) ); - } - -/* If the Frames still match, we next set up the axis association - arrays. */ - if ( astOK && match ) { - -/* If the target axis order is to be preserved, then the target axis - association involves no permutation but the template axis - association may involve an axis swap. */ - if ( astGetPreserveAxes( template ) ) { - (*template_axes)[ 0 ] = swap; - (*template_axes)[ 1 ] = !swap; - (*target_axes)[ 0 ] = target_axis0; - (*target_axes)[ 1 ] = target_axis1; - -/* Otherwise, any swap applies to the target axis association - instead. */ - } else { - (*template_axes)[ 0 ] = 0; - (*template_axes)[ 1 ] = 1; - (*target_axes)[ 0 ] = swap ? target_axis1 : target_axis0; - (*target_axes)[ 1 ] = swap ? target_axis0 : target_axis1; - } - -/* Use the target's "astSubFrame" method to create a new Frame (the - result Frame) with copies of the target axes in the required - order. This process also overlays the template attributes on to the - target Frame and returns a Mapping between the target and result - Frames which effects the required coordinate conversion. */ - match = astSubFrame( target, template, 2, *target_axes, *template_axes, - map, result ); - } - -/* If an error occurred, or conversion to the result Frame's - coordinate system was not possible, then free all memory, annul the - returned objects, and reset the returned value. */ - if ( !astOK || !match ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static void MatchAxesX( AstFrame *frm2_frame, AstFrame *frm1, int *axes, - int *status ) { -/* -* Name: -* MatchAxesX - -* Purpose: -* Find any corresponding axes in two Frames. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void MatchAxesX( AstFrame *frm2, AstFrame *frm1, int *axes ) -* int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astMatchAxesX -* method inherited from the Frame class). - -* This function looks for corresponding axes within two supplied -* Frames. An array of integers is returned that contains an element -* for each axis in the second supplied Frame. An element in this array -* will be set to zero if the associated axis within the second Frame -* has no corresponding axis within the first Frame. Otherwise, it -* will be set to the index (a non-zero positive integer) of the -* corresponding axis within the first supplied Frame. - -* Parameters: -* frm2 -* Pointer to the second Frame. -* frm1 -* Pointer to the first Frame. -* axes -* Pointer to an integer array in which to return the indices of -* the axes (within the first Frame) that correspond to each axis -* within the second Frame. Axis indices start at 1. A value of zero -* will be stored in the returned array for each axis in the second -* Frame that has no corresponding axis in the first Frame. -* -* The number of elements in this array must be greater than or -* equal to the number of axes in the second Frame. -* status -* Pointer to inherited status value. - -* Notes: -* - Corresponding axes are identified by the fact that a Mapping -* can be found between them using astFindFrame or astConvert. Thus, -* "corresponding axes" are not necessarily identical. For instance, -* SkyFrame axes in two Frames will match even if they describe -* different celestial coordinate systems -*/ - -/* Local Variables: */ - AstFrame *resfrm; - AstMapping *resmap; - AstSkyFrame *frm2; - int *frm2_axes; - int *frm1_axes; - int max_axes; - int min_axes; - int preserve_axes; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the SkyFrame. */ - frm2 = (AstSkyFrame *) frm2_frame; - -/* Temporarily ensure that the PreserveAxes attribute is non-zero in - the first supplied Frame. This means thte result Frame returned by - astMatch below will have the axis count and order of the target Frame - (i.e. "pfrm"). */ - if( astTestPreserveAxes( frm1 ) ) { - preserve_axes = astGetPreserveAxes( frm1 ) ? 1 : 0; - } else { - preserve_axes = -1; - } - astSetPreserveAxes( frm1, 1 ); - -/* Temporarily ensure that the MaxAxes and MinAxes attributes in the - first supplied Frame are set so the Frame can be used as a template - in astMatch for matching any number of axes. */ - if( astTestMaxAxes( frm1 ) ) { - max_axes = astGetMaxAxes( frm1 ); - } else { - max_axes = -1; - } - astSetMaxAxes( frm1, 10000 ); - - if( astTestMinAxes( frm1 ) ) { - min_axes = astGetMinAxes( frm1 ); - } else { - min_axes = -1; - } - astSetMinAxes( frm1, 1 ); - -/* Attempt to find a sub-frame within the first supplied Frame that - corresponds to the supplied SkyFrame. */ - if( astMatch( frm1, frm2, 1, &frm1_axes, &frm2_axes, &resmap, &resfrm ) ) { - -/* If successfull, Store the one-based index within "frm1" of the - corresponding axes. */ - axes[ 0 ] = frm1_axes[ 0 ] + 1; - axes[ 1 ] = frm1_axes[ 1 ] + 1; - -/* Free resources */ - frm1_axes = astFree( frm1_axes ); - frm2_axes = astFree( frm2_axes ); - resmap = astAnnul( resmap ); - resfrm = astAnnul( resfrm ); - -/* If no corresponding SkyFrame was found store zeros in the returned array. */ - } else { - axes[ 0 ] = 0; - axes[ 1 ] = 0; - } - -/* Re-instate the original attribute values in the first supplied Frame. */ - if( preserve_axes == -1 ) { - astClearPreserveAxes( frm1 ); - } else { - astSetPreserveAxes( frm1, preserve_axes ); - } - - if( max_axes == -1 ) { - astClearMaxAxes( frm1 ); - } else { - astSetMaxAxes( frm1, max_axes ); - } - - if( min_axes == -1 ) { - astClearMinAxes( frm1 ); - } else { - astSetMinAxes( frm1, min_axes ); - } -} - -static void Norm( AstFrame *this_frame, double value[], int *status ) { -/* -* Name: -* Norm - -* Purpose: -* Normalise a set of SkyFrame coordinates. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void Norm( AstAxis *this, double value[], int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astNorm method inherited -* from the Frame class). - -* Description: -* This function converts a set of SkyFrame coordinate values, -* which might potentially be unsuitable for display to a user (for -* instance, may lie outside the expected range of values) into a -* set of acceptable alternative values suitable for display. -* -* This is done by wrapping coordinates so that the latitude lies -* in the range (-pi/2.0) <= latitude <= (pi/2.0). If the NegLon -* attribute is zero (the default), then the wrapped longitude value -* lies in the range 0.0 <= longitude < (2.0*pi). Otherwise, it lies -* in the range -pi <= longitude < pi. - -* Parameters: -* this -* Pointer to the SkyFrame. -* value -* An array of double, with one element for each SkyFrame axis. -* This should contain the initial set of coordinate values, -* which will be modified in place. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const int *perm; /* Axis permutation array */ - double sky_lat; /* Sky latitude value */ - double sky_long; /* Sky longitude value */ - double v[ 2 ]; /* Permuted value coordinates */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( astOK ) { - -/* Obtain the sky longitude and latitude values, allowing for any axis - permutation. */ - v[ perm[ 0 ] ] = value[ 0 ]; - v[ perm[ 1 ] ] = value[ 1 ]; - sky_long = v[ 0 ]; - sky_lat = v[ 1 ]; - -/* Test if both values are OK (i.e. not "bad"). */ - if ( ( sky_long != AST__BAD ) && ( sky_lat != AST__BAD ) ) { - -/* Fold the longitude value into the range 0 to 2*pi and the latitude into - the range -pi to +pi. */ - sky_long = palDranrm( sky_long ); - sky_lat = palDrange( sky_lat ); - -/* If the latitude now exceeds pi/2, shift the longitude by pi in whichever - direction will keep it in the range 0 to 2*pi. */ - if ( sky_lat > ( pi / 2.0 ) ) { - sky_long += ( sky_long < pi ) ? pi : -pi; - -/* Reflect the latitude value through the pole, so it lies in the range 0 to - pi/2. */ - sky_lat = pi - sky_lat; - -/* If the latitude is less than -pi/2, shift the longitude in the same way - as above. */ - } else if ( sky_lat < -( pi / 2.0 ) ) { - sky_long += ( sky_long < pi ) ? pi : -pi; - -/* But reflect the latitude through the other pole, so it lies in the range - -pi/2 to 0. */ - sky_lat = -pi - sky_lat; - } - -/* If only the longitude value is valid, wrap it into the range 0 to 2*pi. */ - } else if ( sky_long != AST__BAD ) { - sky_long = palDranrm( sky_long ); - -/* If only the latitude value is valid, wrap it into the range -pi to +pi. */ - } else if ( sky_lat != AST__BAD ) { - sky_lat = palDrange( sky_lat ); - -/* Then refect through one of the poles (as above), if necessary, to move it - into the range -pi/2 to +pi/2. */ - if ( sky_lat > ( pi / 2.0 ) ) { - sky_lat = pi - sky_lat; - } else if ( sky_lat < -( pi / 2.0 ) ) { - sky_lat = -pi - sky_lat; - } - } - -/* Convert 2*pi longitude into zero. Allow for a small error. */ - if ( fabs( sky_long - ( 2.0 * pi ) ) <= - ( 2.0 * pi ) * ( DBL_EPSILON * (double) FLT_RADIX ) ) sky_long = 0.0; - -/* If the NegLon attribute is set, and the longitude value is good, - convert it into the range -pi to +pi. */ - if( sky_long != AST__BAD && astGetNegLon( this ) ) { - sky_long = palDrange( sky_long ); - } - -/* Return the new values, allowing for any axis permutation. */ - v[ 0 ] = sky_long; - v[ 1 ] = sky_lat; - value[ 0 ] = v[ perm[ 0 ] ]; - value[ 1 ] = v[ perm[ 1 ] ]; - } -} - -static void NormBox( AstFrame *this_frame, double lbnd[], double ubnd[], - AstMapping *reg, int *status ) { -/* -* Name: -* NormBox - -* Purpose: -* Extend a box to include effect of any singularities in the Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void astNormBox( AstFrame *this, double lbnd[], double ubnd[], -* AstMapping *reg, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astNormBox method inherited -* from the Frame class). - -* Description: -* This function modifies a supplied box to include the effect of any -* singularities in the co-ordinate system represented by the Frame. -* For a normal Cartesian coordinate system, the box will be returned -* unchanged. Other classes of Frame may do other things. For instance, -* a SkyFrame will check to see if the box contains either the north -* or south pole and extend the box appropriately. - -* Parameters: -* this -* Pointer to the Frame. -* lbnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* lower axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* ubnd -* An array of double, with one element for each Frame axis -* (Naxes attribute). Initially, this should contain a set of -* upper axis bounds for the box. They will be modified on exit -* to include the effect of any singularities within the box. -* reg -* A Mapping which should be used to test if any singular points are -* inside or outside the box. The Mapping should leave an input -* position unchanged if the point is inside the box, and should -* set all bad if the point is outside the box. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const int *perm; /* Axis permutation array */ - double lb[ 2 ]; /* Permuted lower bounds */ - double t; /* Temporary storage */ - double t2; /* Temporary storage */ - double ub[ 2 ]; /* Permuted upper bounds */ - double x[2]; /* 1st axis values at poles */ - double xo[2]; /* Tested 1st axis values at poles */ - double y[2]; /* 2nd axis values at poles */ - double yo[2]; /* Tested 2nd axis values at poles */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if( perm ) { - -/* Obtain the sky longitude and latitude limits, allowing for any axis - permutation. */ - lb[ perm[ 0 ] ] = lbnd[ 0 ]; - lb[ perm[ 1 ] ] = lbnd[ 1 ]; - ub[ perm[ 0 ] ] = ubnd[ 0 ]; - ub[ perm[ 1 ] ] = ubnd[ 1 ]; - -/* Use the supplied Mapping to test if box includes either pole. */ - if( perm[ 0 ] == 0 ) { - x[ 0 ] = 0.0; - y[ 0 ] = AST__DPIBY2; - x[ 1 ] = 0.0; - y[ 1 ] = -AST__DPIBY2; - } else { - x[ 0 ] = AST__DPIBY2; - y[ 0 ] = 0.0; - x[ 1 ] = -AST__DPIBY2; - y[ 1 ] = 0.0; - } - astTran2( reg, 2, x, y, 1, xo, yo ); - -/* If the box includes the north pole... */ - if( xo[ 0 ] != AST__BAD ) { - -/* Find the lowest latitude after normalisation. */ - if( ub[ 1 ] != AST__BAD && lb[ 1 ] != AST__BAD ){ - t = palDrange( ub[ 1 ] ); - t2 = palDrange( lb[ 1 ] ); - if( t2 < t ) t = t2; - } else { - t = AST__BAD; - } - -/* Set the lower returned limit to this value and the upper returned limit - to +90 degs */ - lb[ 1 ] = t; - ub[ 1 ] = AST__DPIBY2; - -/* Set the longitude range to 0 to 2PI */ - lb[ 0 ] = 0; - ub[ 0 ] = 2*AST__DPI; - - } - -/* If the box includes the south pole... */ - if( xo[ 1 ] != AST__BAD ) { - -/* Find the highest latitude after normalisation. */ - if( ub[ 1 ] != AST__BAD && lb[ 1 ] != AST__BAD ){ - t = palDrange( ub[ 1 ] ); - t2 = palDrange( lb[ 1 ] ); - if( t2 > t ) t = t2; - } else { - t = AST__BAD; - } - -/* Set the upper returned limit to this value and the lower returned limit - to -90 degs */ - lb[ 1 ] = -AST__DPIBY2; - ub[ 1 ] = t; - -/* Set the longitude range to 0 to 2PI */ - lb[ 0 ] = 0; - ub[ 0 ] = 2*AST__DPI; - } - -/* Return the modified limits. */ - lbnd[ 0 ] = lb[ perm[ 0 ] ]; - lbnd[ 1 ] = lb[ perm[ 1 ] ]; - ubnd[ 0 ] = ub[ perm[ 0 ] ]; - ubnd[ 1 ] = ub[ perm[ 1 ] ]; - } -} - -static void Offset( AstFrame *this_frame, const double point1[], - const double point2[], double offset, double point3[], int *status ) { -/* -* Name: -* Offset - -* Purpose: -* Calculate an offset along a geodesic curve. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void Offset( AstFrame *this, -* const double point1[], const double point2[], -* double offset, double point3[], int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astOffset method -* inherited from the Frame class). - -* Description: -* This function finds the SkyFrame coordinate values of a point -* which is offset a specified distance along the geodesic curve -* (i.e. great circle) between two other points. - -* Parameters: -* this -* Pointer to the SkyFrame. -* point1 -* An array of double, with one element for each SkyFrame axis. -* This should contain the coordinates of the point marking the -* start of the geodesic curve. -* point2 -* An array of double, with one element for each SkyFrame axis. -* This should contain the coordinates of the point marking the -* end of the geodesic curve. -* offset -* The required offset from the first point along the geodesic -* curve, in radians. If this is positive, it will be towards -* the second point. If it is negative, it will be in the -* opposite direction. This offset need not imply a position -* lying between the two points given, as the curve will be -* extrapolated if necessary. -* point3 -* An array of double, with one element for each SkyFrame axis -* in which the coordinates of the required point will be -* returned. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -* - "Bad" coordinate values will also be returned if the two -* points supplied are coincident (or otherwise fail to uniquely -* specify a geodesic curve) but the requested offset is non-zero. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const int *perm; /* Pointer to axis permutation array */ - double mrot[ 3 ][ 3 ]; /* Rotation matrix */ - double p1[ 2 ]; /* Permuted coordinates for point1 */ - double p2[ 2 ]; /* Permuted coordinates for point2 */ - double p3[ 2 ]; /* Permuted coordinates for point3 */ - double scale; /* Scale factor */ - double v1[ 3 ]; /* 3-vector for p1 */ - double v2[ 3 ]; /* 3-vector for p2 */ - double v3[ 3 ]; /* 3-vector for p3 */ - double vmod; /* Modulus of vector */ - double vrot[ 3 ]; /* Vector along rotation axis */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( astOK ) { - -/* Check that all supplied coordinates are OK. If not, generate "bad" - output coordinates. */ - if ( ( point1[ 0 ] == AST__BAD ) || ( point1[ 1 ] == AST__BAD ) || - ( point2[ 0 ] == AST__BAD ) || ( point2[ 1 ] == AST__BAD ) ) { - point3[ 0 ] = AST__BAD; - point3[ 1 ] = AST__BAD; - -/* Otherwise, apply the axis permutation array to obtain the - coordinates of the two input points in the required - (longitude,latitude) order. */ - } else { - p1[ perm[ 0 ] ] = point1[ 0 ]; - p1[ perm[ 1 ] ] = point1[ 1 ]; - p2[ perm[ 0 ] ] = point2[ 0 ]; - p2[ perm[ 1 ] ] = point2[ 1 ]; - -/* Convert each point into a 3-vector of unit length. */ - palDcs2c( p1[ 0 ], p1[ 1 ], v1 ); - palDcs2c( p2[ 0 ], p2[ 1 ], v2 ); - -/* Find the cross product between these two vectors (the vector order - is reversed here to compensate for the sense of rotation introduced - by palDav2m and palDmxv below). */ - palDvxv( v2, v1, v3 ); - -/* Normalise the cross product vector, also obtaining its original - modulus. */ - palDvn( v3, vrot, &vmod ); - -/* If the original modulus was zero, the input points are either - coincident or diametrically opposite, so do not uniquely define a - great circle. In either case, we can only generate output - coordinates if the offset required is an exact multiple of pi. If - it is, generate the 3-vector that results from rotating the first - input point through this angle. */ - if ( vmod == 0.0 ) { - if ( sin( offset ) == 0.0 ) { - scale = cos( offset ); - v3[ 0 ] = v1[ 0 ] * scale; - v3[ 1 ] = v1[ 1 ] * scale; - v3[ 2 ] = v1[ 2 ] * scale; - -/* Convert the 3-vector back into spherical cooordinates and then - constrain the longitude result to lie in the range 0 to 2*pi - (palDcc2s doesn't do this itself). */ - palDcc2s( v3, &p3[ 0 ], &p3[ 1 ] ); - p3[ 0 ] = palDranrm( p3[ 0 ] ); - -/* If the offset was not a multiple of pi, generate "bad" output - coordinates. */ - } else { - p3[ 0 ] = AST__BAD; - p3[ 1 ] = AST__BAD; - } - -/* If the two input points define a great circle, scale the normalised - cross product vector to make its length equal to the required - offset (angle) between the first input point and the result. */ - } else { - vrot[ 0 ] *= offset; - vrot[ 1 ] *= offset; - vrot[ 2 ] *= offset; - -/* Generate the rotation matrix that implements this rotation and use - it to rotate the first input point (3-vector) to give the required - result (3-vector). */ - palDav2m( vrot, mrot ); - palDmxv( mrot, v1, v3 ); - -/* Convert the 3-vector back into spherical cooordinates and then - constrain the longitude result to lie in the range 0 to 2*pi. */ - palDcc2s( v3, &p3[ 0 ], &p3[ 1 ] ); - p3[ 0 ] = palDranrm( p3[ 0 ] ); - } - -/* Permute the result coordinates to undo the effect of the SkyFrame - axis permutation array. */ - point3[ 0 ] = p3[ perm[ 0 ] ]; - point3[ 1 ] = p3[ perm[ 1 ] ]; - } - } -} - -static AstMapping *SkyOffsetMap( AstSkyFrame *this, int *status ){ -/* -*++ -* Name: -c astSkyOffsetMap -f AST_SKYOFFSETMAP - -* Purpose: -* Returns a Mapping which goes from absolute coordinates to offset -* coordinates. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "skyframe.h" -c AstMapping *astSkyOffsetMap( AstSkyFrame *this ) -f RESULT = AST_SKYOFFSETMAP( THIS, STATUS ) - -* Class Membership: -* SkyFrame method. - -* Description: -* This function returns a Mapping in which the forward transformation -* transforms a position in the coordinate system given by the System -* attribute of the supplied SkyFrame, into the offset coordinate system -* specified by the SkyRef, SkyRefP and SkyRefIs attributes of the -* supplied SkyFrame. -* -* A UnitMap is returned if the SkyFrame does not define an offset -* coordinate system. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the SkyFrame. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSkyOffsetMap() -f AST_SKYOFFSETMAP = INTEGER -* Pointer to the returned Mapping. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstCmpMap *map3; /* Partial Mapping. */ - AstMapping *result; /* The returned Mapping. */ - AstMatrixMap *map1; /* Spherical rotation in 3D cartesian space */ - AstSphMap *map2; /* 3D Cartesian to 2D spherical Mapping */ - double *vx; /* Pointer to x unit vector. */ - double *vy; /* Pointer to y unit vector. */ - double *vz; /* Pointer to z unit vector. */ - double mat[ 9 ]; /* Spherical rotation matrix */ - double vmod; /* Length of vector (+ve) */ - double vp[ 3 ]; /* Unit vector representin SkyRefP position. */ - int lataxis; /* Index of the latitude axis */ - int lonaxis; /* Index of the longitude axis */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Return a UnitMap if the offset coordinate system is not defined. */ - if( astGetSkyRefIs( this ) == AST__IGNORED_REF || - ( !astTestSkyRef( this, 0 ) && !astTestSkyRef( this, 1 ) ) ) { - result = (AstMapping *) astUnitMap( 2, "", status ); - -/* Otherwise... */ - } else { - -/* Get the longitude and latitude at the reference point and at a point - on the primary meridian. */ - lataxis = astGetLatAxis( this ); - lonaxis = 1 - lataxis; - -/* Initialise pointers to the rows of the 3x3 matrix. Each row will be - used to store a unit vector. */ - vx = mat; - vy = mat + 3; - vz = mat + 6; - -/* The following trig converts between (longitude,latitude) and (x,y,z) - on a unit sphere, in which (0,0) is at (1,0,0), (0,pi/2) is (0,0,1) - and (pi/2,0) is at (0,1,0). */ - -/* First deal with cases where the SkyRef attribute holds the standard - coords at the origin of the offset coordinate system. */ - if( astGetSkyRefIs( this ) == AST__ORIGIN_REF ) { - -/* Convert each point into a 3-vector of unit length. The SkyRef position - defines the X axis in the offset coord system. */ - palDcs2c( astGetSkyRef( this, lonaxis ), astGetSkyRef( this, lataxis ), vx ); - palDcs2c( astGetSkyRefP( this, lonaxis ), astGetSkyRefP( this, lataxis ), vp ); - -/* The Y axis is perpendicular to both the X axis and the skyrefp - position. That is, it is parallel to the cross product of the 2 above - vectors.*/ - palDvxv( vp, vx, vy ); - -/* Normalize the y vector. */ - palDvn( vy, vy, &vmod ); - -/* Report an error if the modulus of the vector is zero.*/ - if( vmod == 0.0 ) { - astError( AST__BADOC, "astConvert(%s): The position specified by the SkyRefP " - "attribute is either coincident, with or opposite to, the " - "position specified by the SkyRef attribute.", status, astGetClass( this ) ); - -/* If OK, form the Z axis as the cross product of the x and y axes. */ - } else { - palDvxv( vx, vy, vz ); - - } - -/* Now deal with cases where the SkyRef attribute holds the standard - coords at the north pole of the offset coordinate system. */ - } else { - -/* Convert each point into a 3-vector of unit length. The SkyRef position - defines the Z axis in the offset coord system. */ - palDcs2c( astGetSkyRef( this, lonaxis ), astGetSkyRef( this, lataxis ), vz ); - palDcs2c( astGetSkyRefP( this, lonaxis ), astGetSkyRefP( this, lataxis ), vp ); - -/* The Y axis is perpendicular to both the Z axis and the skyrefp - position. That is, it is parallel to the cross product of the 2 above - vectors.*/ - palDvxv( vz, vp, vy ); - -/* Normalize the y vector. */ - palDvn( vy, vy, &vmod ); - -/* Report an error if the modulus of the vector is zero.*/ - if( vmod == 0.0 ) { - astError( AST__BADOC, "astConvert(%s): The position specified by the SkyRefP " - "attribute is either coincident, with or opposite to, the " - "position specified by the SkyRef attribute.", status, astGetClass( this ) ); - -/* If OK, form the X axis as the cross product of the y and z axes. */ - } else { - palDvxv( vy, vz, vx ); - } - } - -/* Create a MatrixMap which implements the above spherical rotation. Each - row in this matrix represents one of the unit axis vectors found above. */ - map1 = astMatrixMap( 3, 3, 0, mat, "", status ); - -/* Create a 3D cartesian to 2D spherical Mapping. */ - map2 = astSphMap( "UnitRadius=1", status ); - -/* Form a series CmpMap which converts from 2D (long,lat) in the base - System to 2D (long,lat) in the offset coordinate system. */ - map3 = astCmpMap( map1, map2, 1, "", status ); - astInvert( map2 ); - result = (AstMapping *) astCmpMap( map2, map3, 1, "", status ); - -/* Free resources. */ - map1 = astAnnul( map1 ); - map2 = astAnnul( map2 ); - map3 = astAnnul( map3 ); - } - -/* Annul the returned Mapping if anything has gone wrong. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; - -} - -static double Offset2( AstFrame *this_frame, const double point1[2], - double angle, double offset, double point2[2], int *status ) { -/* -* Name: -* Offset2 - -* Purpose: -* Calculate an offset along a geodesic curve at a given bearing. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* double Offset2( AstFrame *this_frame, const double point1[2], -* double angle, double offset, double point2[2], int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astOffset2 method -* inherited from the Frame class). - -* Description: -* This function finds the SkyFrame coordinate values of a point -* which is offset a specified distance along the geodesic curve -* (i.e. great circle) at a given angle from a given starting point. - -* Parameters: -* this -* Pointer to the SkyFrame. -* point1 -* An array of double, with one element for each SkyFrame axis. -* This should contain the coordinates of the point marking the -* start of the geodesic curve. -* angle -* The angle (in radians) from the positive direction of the second -* axis, to the direction of the required position, as seen from -* the starting position. Positive rotation is in the sense of -* rotation from the positive direction of axis 2 to the positive -* direction of axis 1. -* offset -* The required offset from the first point along the geodesic -* curve, in radians. If this is positive, it will be towards -* the given angle. If it is negative, it will be in the -* opposite direction. -* point2 -* An array of double, with one element for each SkyFrame axis -* in which the coordinates of the required point will be -* returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The direction of the geodesic curve at the end point. That is, the -* angle (in radians) between the positive direction of the second -* axis and the continuation of the geodesic curve at the requested -* end point. Positive rotation is in the sense of rotation from -* the positive direction of axis 2 to the positive direction of axis -* 1. - -* Notes: -* - The geodesic curve used by this function is the path of -* shortest distance between two points, as defined by the -* astDistance function. -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const int *perm; /* Pointer to axis permutation array */ - double p1[ 2 ]; /* Permuted coordinates for point1 */ - double p2[ 2 ]; /* Permuted coordinates for point2 */ - double result; /* The returned answer */ - double cosoff; /* Cosine of offset */ - double cosa1; /* Cosine of longitude at start */ - double cosb1; /* Cosine of latitude at start */ - double pa; /* A position angle measured from north */ - double q1[ 3 ]; /* Vector PI/2 away from R4 in meridian of R4 */ - double q2[ 3 ]; /* Vector PI/2 away from R4 on equator */ - double q3[ 3 ]; /* Vector PI/2 away from R4 on great circle */ - double r0[ 3 ]; /* Reference position vector */ - double r3[ 3 ]; /* Vector PI/2 away from R0 on great circle */ - double sinoff; /* Sine of offset */ - double sina1; /* Sine of longitude at start */ - double sinb1; /* Sine of latitude at start */ - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( astOK ) { - -/* Check that all supplied values are OK. If not, generate "bad" - output coordinates. */ - if ( ( point1[ 0 ] == AST__BAD ) || ( point1[ 1 ] == AST__BAD ) || - ( angle == AST__BAD ) || ( offset == AST__BAD ) ) { - point2[ 0 ] = AST__BAD; - point2[ 1 ] = AST__BAD; - -/* Otherwise, apply the axis permutation array to obtain the - coordinates of the starting point in the required (longitude,latitude) - order. */ - } else { - p1[ perm[ 0 ] ] = point1[ 0 ]; - p1[ perm[ 1 ] ] = point1[ 1 ]; - -/* If the axes are permuted, convert the supplied angle into a position - angle. */ - pa = ( perm[ 0 ] == 0 )? angle: piby2 - angle; - -/* Use Shcal to calculate the required vectors R0 (representing - the reference point) and R3 (representing the point which is 90 - degrees away from the reference point, along the required great - circle). The XY plane defines zero latitude, Z is in the direction - of increasing latitude, X is towards zero longitude, and Y is - towards longitude 90 degrees. */ - Shcal( p1[ 0 ], p1[ 1 ], pa, r0, r3, status ); - -/* Use Shapp to use R0 and R3 to calculate the new position. */ - Shapp( offset, r0, r3, p1[ 0 ], p2, status ); - -/* Normalize the result. */ - astNorm( this, p2 ); - -/* Create the vector Q1 representing the point in the meridian of the - required point which has latitude 90 degrees greater than the - required point. */ - sina1 = sin( p2[ 0 ] ); - cosa1 = cos( p2[ 0 ] ); - sinb1 = sin( p2[ 1 ] ); - cosb1 = cos( p2[ 1 ] ); - - q1[ 0 ] = -sinb1*cosa1; - q1[ 1 ] = -sinb1*sina1; - q1[ 2 ] = cosb1; - -/* Create the vector Q2 representing the point on the equator (i.e. a - latitude of zero), which has a longitude 90 degrees to the west of - the required point. */ - q2[ 0 ] = -sina1; - q2[ 1 ] = cosa1; - q2[ 2 ] = 0.0; - -/* Create the vector Q3 representing the point which is 90 degrees away - from the required point, along the required great circle. */ - cosoff = cos( offset ); - sinoff = sin( offset ); - - q3[ 0 ] = -sinoff*r0[ 0 ] + cosoff*r3[ 0 ]; - q3[ 1 ] = -sinoff*r0[ 1 ] + cosoff*r3[ 1 ]; - q3[ 2 ] = -sinoff*r0[ 2 ] + cosoff*r3[ 2 ]; - -/* Calculate the position angle of the great circle at the required - point. */ - pa = atan2( palDvdv( q3, q2 ), palDvdv( q3, q1 ) ); - -/* Convert this from a pa into the required angle. */ - result = ( perm[ 0 ] == 0 )? pa: piby2 - pa; - -/* Ensure that the end angle is in the range 0 to 2*pi. */ - result = palDranrm( result ); - -/* Permute the result coordinates to undo the effect of the SkyFrame - axis permutation array. */ - point2[ 0 ] = p2[ perm[ 0 ] ]; - point2[ 1 ] = p2[ perm[ 1 ] ]; - } - } - -/* Return the result. */ - return result; - -} - -static void Overlay( AstFrame *template, const int *template_axes, - AstFrame *result, int *status ) { -/* -* Name: -* Overlay - -* Purpose: -* Overlay the attributes of a template SkyFrame on to another Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void Overlay( AstFrame *template, const int *template_axes, -* AstFrame *result, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astOverlay method -* inherited from the Frame class). - -* Description: -* This function overlays attributes of a SkyFrame (the "template") on to -* another Frame, so as to over-ride selected attributes of that second -* Frame. Normally only those attributes which have been specifically set -* in the template will be transferred. This implements a form of -* defaulting, in which a Frame acquires attributes from the template, but -* retains its original attributes (as the default) if new values have not -* previously been explicitly set in the template. -* -* Note that if the result Frame is a SkyFrame and a change of sky -* coordinate system occurs as a result of overlaying its System -* attribute, then some of its original attribute values may no -* longer be appropriate (e.g. the Title, or attributes describing -* its axes). In this case, these will be cleared before overlaying -* any new values. - -* Parameters: -* template -* Pointer to the template SkyFrame, for which values should have been -* explicitly set for any attribute which is to be transferred. -* template_axes -* Pointer to an array of int, with one element for each axis of the -* "result" Frame (see below). For each axis in the result frame, the -* corresponding element of this array should contain the (zero-based) -* index of the template axis to which it corresponds. This array is used -* to establish from which template axis any axis-dependent attributes -* should be obtained. -* -* If any axis in the result Frame is not associated with a template -* axis, the corresponding element of this array should be set to -1. -* -* If a NULL pointer is supplied, the template and result axis -* indices are assumed to be identical. -* result -* Pointer to the Frame which is to receive the new attribute values. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - In general, if the result Frame is not from the same class as the -* template SkyFrame, or from a class derived from it, then attributes may -* exist in the template SkyFrame which do not exist in the result Frame. In -* this case, these attributes will not be transferred. -*/ - - -/* Local Variables: */ - AstSystemType new_alignsystem;/* Code identifying new alignment coords */ - AstSystemType new_system; /* Code identifying new sky cordinates */ - AstSystemType old_system; /* Code identifying old sky coordinates */ - int axis; /* Loop counter for result SkyFrame axes */ - int skyref_changed; /* Has the SkyRef attribute changed? */ - int reset_system; /* Was the template System value cleared? */ - int skyframe; /* Result Frame is a SkyFrame? */ - int tax0; /* Template axis for result axis 0 */ - int tax1; /* Template axis for result axis 1 */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Indicate that we do not need to reset the System attribute of the - template. */ - reset_system = 0; - new_system = AST__UNKNOWN; - -/* If the result Frame is a SkyFrame, we must test to see if overlaying its - System attribute will change the type of sky coordinate system it - describes. Determine the value of this attribute for the result and template - SkyFrames. We also need to do this if either SkyRef attribute would - change. */ - skyframe = astIsASkyFrame( result ); - if ( skyframe ) { - old_system = astGetSystem( result ); - new_system = astGetSystem( template ); - skyref_changed = ( astGetSkyRef( result, 0 ) != - astGetSkyRef( template, 0 ) ) || - ( astGetSkyRef( result, 1 ) != - astGetSkyRef( template, 1 ) ); - -/* If the coordinate system will change, any value already set for the result - SkyFrame's Title will no longer be appropriate, so clear it. */ - if ( new_system != old_system || skyref_changed ) { - astClearTitle( result ); - -/* Test if the old and new sky coordinate systems are similar enough to make - use of the same axis attribute values (e.g. if they are both equatorial - systems, then they can both use the same axis labels, etc.,so long as - the SKyRefIs value has not changed). */ - if ( IsEquatorial( new_system, status ) != IsEquatorial( old_system, status ) || - skyref_changed ) { - -/* If necessary, clear inappropriate values for all those axis attributes - whose access functions are over-ridden by this class (these access functions - will then provide suitable defaults appropriate to the new coordinate system - instead). */ - for ( axis = 0; axis < 2; axis++ ) { - astClearAsTime( result, axis ); - astClearDirection( result, axis ); - astClearFormat( result, axis ); - astClearLabel( result, axis ); - astClearSymbol( result, axis ); - astClearUnit( result, axis ); - } - } - } - -/* If the result Frame is not a SkyFrame, we must temporarily clear the - System and AlignSystem values since the values used by this class are only - appropriate to this class. */ - } else { - if( astTestSystem( template ) ) { - new_system = astGetSystem( template ); - astClearSystem( template ); - new_alignsystem = astGetAlignSystem( template ); - astClearAlignSystem( template ); - reset_system = 1; - } - } - -/* Invoke the parent class astOverlay method to transfer attributes inherited - from the parent class. */ - (*parent_overlay)( template, template_axes, result, status ); - -/* Reset the System and AlignSystem values if necessary */ - if( reset_system ) { - astSetSystem( template, new_system ); - astSetAlignSystem( template, new_alignsystem ); - } - -/* Check if the result Frame is a SkyFrame or from a class derived from - SkyFrame. If not, we cannot transfer SkyFrame attributes to it as it is - insufficiently specialised. In this case simply omit these attributes. */ - if ( skyframe && astOK ) { - -/* Define a macro that tests whether an attribute is set in the template and, - if so, transfers its value to the result. */ -#define OVERLAY(attr) \ - if ( astTest##attr( template ) ) { \ - astSet##attr( result, astGet##attr( template ) ); \ - } - -/* Store template axis indices */ - if( template_axes ) { - tax0 = template_axes[ 0 ]; - tax1 = template_axes[ 1 ]; - } else { - tax0 = 0; - tax1 = 1; - } - -/* Define a similar macro that does the same for SkyFrame specific axis - attributes. */ -#define OVERLAY2(attr) \ - if( astTest##attr( template, tax0 ) ) { \ - astSet##attr( result, 0, astGet##attr( template, tax0 ) ); \ - } \ - if( astTest##attr( template, tax1 ) ) { \ - astSet##attr( result, 1, astGet##attr( template, tax1 ) ); \ - } - -/* Use the macro to transfer each SkyFrame attribute in turn. */ - OVERLAY(Equinox); - OVERLAY(Projection); - OVERLAY(NegLon); - OVERLAY(SkyTol); - OVERLAY(AlignOffset); - OVERLAY(SkyRefIs); - OVERLAY2(SkyRef); - OVERLAY2(SkyRefP); - } - -/* Undefine macros local to this function. */ -#undef OVERLAY -#undef OVERLAY2 -} - -static void Resolve( AstFrame *this_frame, const double point1[], - const double point2[], const double point3[], - double point4[], double *d1, double *d2, int *status ){ -/* -* Name: -* Resolve - -* Purpose: -* Resolve a vector into two orthogonal components - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void Resolve( AstFrame *this, const double point1[], -* const double point2[], const double point3[], -* double point4[], double *d1, double *d2, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astResolve method -* inherited from the Frame class). - -* Description: -* This function resolves a vector into two perpendicular components. -* The vector from point 1 to point 2 is used as the basis vector. -* The vector from point 1 to point 3 is resolved into components -* parallel and perpendicular to this basis vector. The lengths of the -* two components are returned, together with the position of closest -* aproach of the basis vector to point 3. -* -* Each vector is a geodesic curve. For a SkyFrame, these are great -* circles on the celestial sphere. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vector to be resolved. -* point2 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -* point3 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the vector to be -* resolved. -* point4 -* An array of double, with one element for each Frame axis -* in which the coordinates of the point of closest approach of the -* basis vector to point 3 will be returned. -* d1 -* The address of a location at which to return the distance from -* point 1 to point 4 (that is, the length of the component parallel -* to the basis vector). Positive values are in the same sense as -* movement from point 1 to point 2. -* d2 -* The address of a location at which to return the distance from -* point 4 to point 3 (that is, the length of the component -* perpendicular to the basis vector). The returned value is always -* positive. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function will return "bad" coordinate values (AST__BAD) -* if any of the input coordinates has this value, or if the required -* output values are undefined. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - const int *perm; /* Pointer to axis permutation array */ - double n1[ 3 ]; /* Unit normal to grt crcl thru p1 and p2 */ - double n2[ 3 ]; /* Unit normal to grt crcl thru p3 and p4 */ - double p1[ 2 ]; /* Permuted coordinates for point1 */ - double p2[ 2 ]; /* Permuted coordinates for point2 */ - double p3[ 2 ]; /* Permuted coordinates for point3 */ - double p4[ 2 ]; /* Permuted coordinates for point4 */ - double v1[ 3 ]; /* 3-vector for p1 */ - double v2[ 3 ]; /* 3-vector for p2 */ - double v3[ 3 ]; /* 3-vector for p3 */ - double v4[ 3 ]; /* 3-vector for p4 */ - double v5[ 3 ]; /* 3-vector 90 degs away from p1 */ - double vmod; /* Modulus of vector */ - double vtemp[ 3 ]; /* Temporary vector workspace */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Store initial bad output values. */ - point4[ 0 ] = AST__BAD; - point4[ 1 ] = AST__BAD; - *d1 = AST__BAD; - *d2 = AST__BAD; - -/* Check that all supplied values are OK. */ - if ( ( point1[ 0 ] != AST__BAD ) && ( point1[ 1 ] != AST__BAD ) && - ( point2[ 0 ] != AST__BAD ) && ( point2[ 1 ] != AST__BAD ) && - ( point3[ 0 ] != AST__BAD ) && ( point3[ 1 ] != AST__BAD ) ) { - -/* If so, obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - if ( astOK ) { - -/* Apply the axis permutation array to obtain the coordinates of the - three supplied point in the required (longitude,latitude) order. */ - p1[ perm[ 0 ] ] = point1[ 0 ]; - p1[ perm[ 1 ] ] = point1[ 1 ]; - p2[ perm[ 0 ] ] = point2[ 0 ]; - p2[ perm[ 1 ] ] = point2[ 1 ]; - p3[ perm[ 0 ] ] = point3[ 0 ]; - p3[ perm[ 1 ] ] = point3[ 1 ]; - -/* Convert each point into a 3-vector of unit length. */ - palDcs2c( p1[ 0 ], p1[ 1 ], v1 ); - palDcs2c( p2[ 0 ], p2[ 1 ], v2 ); - palDcs2c( p3[ 0 ], p3[ 1 ], v3 ); - -/* Find the cross product between the first two vectors, and normalize is. - This is the unit normal to the great circle plane defining parallel - distance. */ - palDvxv( v2, v1, vtemp ); - palDvn( vtemp, n1, &vmod ); - -/* Return with bad values if the normal is undefined (i.e. if the first two - vectors are identical or diametrically opposite). */ - if( vmod > 0.0 ) { - -/* Now take the cross product of the normal vector and v1. This gives a - point, v5, on the great circle which is 90 degrees away from v1, in the - direction of v2. */ - palDvxv( v1, n1, v5 ); - -/* Find the cross product of the outlying point (point 3), and the vector - n1 found above, and normalize it. This is the unit normal to the great - circle plane defining perpendicular distance. */ - palDvxv( v3, n1, vtemp ); - palDvn( vtemp, n2, &vmod ); - -/* Return with bad values if the normal is undefined (i.e. if the - outlying point is normal to the great circle defining the basis - vector). */ - if( vmod > 0.0 ) { - -/* The point of closest approach, point 4, is the point which is normal - to both normal vectors (i.e. the intersection of the two great circles). - This is the cross product of n1 and n2. No need to normalize this time - since both n1 and n2 are unit vectors, and so v4 will already be a - unit vector. */ - palDvxv( n1, n2, v4 ); - -/* The dot product of v4 and v1 is the cos of the parallel distance, - d1, whilst the dot product of v4 and v5 is the sin of the parallel - distance. Use these to get the parallel distance with the correct - sign, in the range -PI to +PI. */ - *d1 = atan2( palDvdv( v4, v5 ), palDvdv( v4, v1 ) ); - -/* The dot product of v4 and v3 is the cos of the perpendicular distance, - d2, whilst the dot product of n1 and v3 is the sin of the perpendicular - distance. Use these to get the perpendicular distance. */ - *d2 = fabs( atan2( palDvdv( v3, n1 ), palDvdv( v3, v4 ) ) ); - -/* Convert the 3-vector representing the intersection of the two planes - back into spherical cooordinates and then constrain the longitude result - to lie in the range 0 to 2*pi. */ - palDcc2s( v4, &p4[ 0 ], &p4[ 1 ] ); - p4[ 0 ] = palDranrm( p4[ 0 ] ); - -/* Permute the result coordinates to undo the effect of the SkyFrame - axis permutation array. */ - point4[ 0 ] = p4[ perm[ 0 ] ]; - point4[ 1 ] = p4[ perm[ 1 ] ]; - } - } - } - } - - return; - -} - -static AstPointSet *ResolvePoints( AstFrame *this_frame, const double point1[], - const double point2[], AstPointSet *in, - AstPointSet *out, int *status ) { -/* -* Name: -* ResolvePoints - -* Purpose: -* Resolve a set of vectors into orthogonal components - -* Type: -* Private function. - -* Synopsis: -* #include "frame.h" -* AstPointSet *astResolvePoints( AstFrame *this, const double point1[], -* const double point2[], AstPointSet *in, -* AstPointSet *out ) - -* Class Membership: -* SkyFrame member function (over-rides the astResolvePoints method -* inherited from the Frame class). - -* Description: -* This function takes a Frame and a set of vectors encapsulated -* in a PointSet, and resolves each one into two orthogonal components, -* returning these two components in another PointSet. -* -* This is exactly the same as the public astResolve method, except -* that this method allows many vectors to be processed in a single call, -* thus reducing the computational cost of overheads of many -* individual calls to astResolve. - -* Parameters: -* this -* Pointer to the Frame. -* point1 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the start of the basis vector, -* and of the vectors to be resolved. -* point2 -* An array of double, with one element for each Frame axis -* (Naxes attribute). This marks the end of the basis vector. -* in -* Pointer to the PointSet holding the ends of the vectors to be -* resolved. -* out -* Pointer to a PointSet which will hold the length of the two -* resolved components. A NULL value may also be given, in which -* case a new PointSet will be created by this function. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. The first axis will -* hold the lengths of the vector components parallel to the basis vector. -* These values will be signed (positive values are in the same sense as -* movement from point 1 to point 2. The second axis will hold the lengths -* of the vector components perpendicular to the basis vector. These -* values will be signed only if the Frame is 2-dimensional, in which -* case a positive value indicates that rotation from the basis vector -* to the tested vector is in the same sense as rotation from the first -* to the second axis of the Frame. - -* Notes: -* - The number of coordinate values per point in the input -* PointSet must match the number of axes in the supplied Frame. -* - If an output PointSet is supplied, it must have space for -* sufficient number of points and 2 coordinate values per point. -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -* - We assume spherical geometry throughout this function. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - const int *perm; /* Pointer to axis permutation array */ - double **ptr_in; /* Pointers to input axis values */ - double **ptr_out; /* Pointers to returned axis values */ - double *d1; /* Pointer to next parallel component value */ - double *d2; /* Pointer to next perpendicular component value */ - double *point3x; /* Pointer to next first axis value */ - double *point3y; /* Pointer to next second axis value */ - double n1[ 3 ]; /* Unit normal to grt crcl thru p1 and p2 */ - double n2[ 3 ]; /* Unit normal to grt crcl thru p3 and p4 */ - double p1[ 2 ]; /* Permuted coordinates for point1 */ - double p2[ 2 ]; /* Permuted coordinates for point2 */ - double p3[ 2 ]; /* Permuted coordinates for point3 */ - double sign; /* Sign for perpendicular distances */ - double v1[ 3 ]; /* 3-vector for p1 */ - double v2[ 3 ]; /* 3-vector for p2 */ - double v3[ 3 ]; /* 3-vector for p3 */ - double v4[ 3 ]; /* 3-vector for p4 */ - double v5[ 3 ]; /* 3-vector 90 degs away from p1 */ - double vmod; /* Modulus of vector */ - double vtemp[ 3 ]; /* Temporary vector workspace */ - int ipoint; /* Index of next point */ - int ncoord_in; /* Number of input PointSet coordinates */ - int ncoord_out; /* Number of coordinates in output PointSet */ - int npoint; /* Number of points to transform */ - int npoint_out; /* Number of points in output PointSet */ - int ok; /* OK to proceed? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Obtain the number of input vectors to resolve and the number of coordinate - values per vector. */ - npoint = astGetNpoint( in ); - ncoord_in = astGetNcoord( in ); - -/* If OK, check that the number of input coordinates matches the number - required by the Frame. Report an error if these numbers do not match. */ - if ( astOK && ( ncoord_in != 2 ) ) { - astError( AST__NCPIN, "astResolvePoints(%s): Bad number of coordinate " - "values (%d) in input %s.", status, astGetClass( this ), ncoord_in, - astGetClass( in ) ); - astError( AST__NCPIN, "The %s given requires 2 coordinate values for " - "each input point.", status, astGetClass( this ) ); - } - -/* If still OK, and a non-NULL pointer has been given for the output PointSet, - then obtain the number of points and number of coordinates per point for - this PointSet. */ - if ( astOK && out ) { - npoint_out = astGetNpoint( out ); - ncoord_out = astGetNcoord( out ); - -/* Check that the dimensions of this PointSet are adequate to accommodate the - output coordinate values and report an error if they are not. */ - if ( astOK ) { - if ( npoint_out < npoint ) { - astError( AST__NOPTS, "astResolvePoints(%s): Too few points (%d) in " - "output %s.", status, astGetClass( this ), npoint_out, - astGetClass( out ) ); - astError( AST__NOPTS, "The %s needs space to hold %d transformed " - "point(s).", status, astGetClass( this ), npoint ); - } else if ( ncoord_out < 2 ) { - astError( AST__NOCTS, "astResolvePoints(%s): Too few coordinate " - "values per point (%d) in output %s.", status, - astGetClass( this ), ncoord_out, astGetClass( out ) ); - astError( AST__NOCTS, "The %s supplied needs space to store 2 " - "coordinate value(s) per transformed point.", status, - astGetClass( this ) ); - } - } - } - -/* If all the validation stages are passed successfully, and a NULL output - pointer was given, then create a new PointSet to encapsulate the output - coordinate data. */ - if ( astOK ) { - if ( !out ) { - result = astPointSet( npoint, 2, "", status ); - -/* Otherwise, use the PointSet supplied. */ - } else { - result = out; - } - } - -/* Get pointers to the input and output axis values */ - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Obtain a pointer to the SkyFrame's axis permutation array. */ - perm = astGetPerm( this ); - -/* If the axes have been swapped we need to swap the sign of the returned - perpendicular distances. */ - sign = ( perm[ 0 ] == 0 ) ? -1.0 : 1.0; - -/* Check pointers can be used safely */ - if( astOK ) { - -/* Apply the axis permutation array to obtain the coordinates of the - two supplied points in the required (longitude,latitude) order. */ - p1[ perm[ 0 ] ] = point1[ 0 ]; - p1[ perm[ 1 ] ] = point1[ 1 ]; - p2[ perm[ 0 ] ] = point2[ 0 ]; - p2[ perm[ 1 ] ] = point2[ 1 ]; - -/* Convert these points into 3-vectors of unit length. */ - palDcs2c( p1[ 0 ], p1[ 1 ], v1 ); - palDcs2c( p2[ 0 ], p2[ 1 ], v2 ); - -/* Find the cross product between the vectors, and normalize it. This is the - unit normal to the great circle plane defining parallel distance. */ - palDvxv( v2, v1, vtemp ); - palDvn( vtemp, n1, &vmod ); - -/* Return with bad values if the normal is undefined (i.e. if the first two - vectors are identical or diametrically opposite). */ - ok = 0; - if( vmod > 0.0 ) { - ok = 1; - -/* Now take the cross product of the normal vector and v1. This gives a - point, v5, on the great circle which is 90 degrees away from v1, in the - direction of v2. */ - palDvxv( v1, n1, v5 ); - } - -/* Store pointers to the first two axis arrays in the returned PointSet. */ - d1 = ptr_out[ 0 ]; - d2 = ptr_out[ 1 ]; - -/* Store pointers to the axis values in the supplied PointSet. */ - point3x = ptr_in[ 0 ]; - point3y = ptr_in[ 1 ]; - -/* Check supplied values can be used */ - if( ok ) { - -/* Loop round each supplied vector. */ - for( ipoint = 0; ipoint < npoint; ipoint++, d1++, d2++, - point3x++, point3y++ ) { - -/* Store bad output values if either input axis value is bad. */ - if( *point3x == AST__BAD || *point3y == AST__BAD ){ - *d1 = AST__BAD; - *d2 = AST__BAD; - -/* If both are good... */ - } else { - -/* Apply the axis permutation array to obtain the coordinates in the - required (longitude,latitude) order. */ - p3[ perm[ 0 ] ] = *point3x; - p3[ perm[ 1 ] ] = *point3y; - -/* Convert into a 3-vector of unit length. */ - palDcs2c( p3[ 0 ], p3[ 1 ], v3 ); - -/* Find the cross product of the outlying point (point 3), and the vector - n1 found above, and normalize it. This is the unit normal to the great - circle plane defining perpendicular distance. */ - palDvxv( v3, n1, vtemp ); - palDvn( vtemp, n2, &vmod ); - -/* Return with bad values if the normal is undefined (i.e. if the - outlying point is normal to the great circle defining the basis - vector). */ - if( vmod <= 0.0 ) { - *d1 = AST__BAD; - *d2 = AST__BAD; - } else { - -/* The point of closest approach, point 4, is the point which is normal - to both normal vectors (i.e. the intersection of the two great circles). - This is the cross product of n1 and n2. No need to normalize this time - since both n1 and n2 are unit vectors, and so v4 will already be a - unit vector. */ - palDvxv( n1, n2, v4 ); - -/* The dot product of v4 and v1 is the cos of the parallel distance, - d1, whilst the dot product of v4 and v5 is the sin of the parallel - distance. Use these to get the parallel distance with the correct - sign, in the range -PI to +PI. */ - *d1 = atan2( palDvdv( v4, v5 ), palDvdv( v4, v1 ) ); - -/* The dot product of v4 and v3 is the cos of the perpendicular distance, - d2, whilst the dot product of n1 and v3 is the sin of the perpendicular - distance. Use these to get the perpendicular distance. */ - *d2 = sign*atan2( palDvdv( v3, n1 ), palDvdv( v3, v4 ) ); - } - } - } - -/* If supplied values cannot be used, fill the returned PointSet with bad - values */ - } else { - for( ipoint = 0; ipoint < npoint; ipoint++, d1++, d2++ ) { - *d1 = AST__BAD; - *d2 = AST__BAD; - } - } - } - -/* Annul the returned PointSet if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; -} - -static void SetAsTime( AstSkyFrame *this, int axis, int value, int *status ) { -/* -* Name: -* SetAsTime - -* Purpose: -* Set a value for the AsTime attribute for a SkyFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetAsTime( AstSkyFrame *this, int axis, int value, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function sets the boolean value of the AsTime attribute for a -* specified axis of a SkyFrame. This value indicates whether axis values -* should be formatted as times (as opposed to angles) by default. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Index of the axis for which a value is to be set (zero based). -* value -* The boolean value to be set. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to Axis object */ - AstSkyAxis *new_ax; /* Pointer to new SkyAxis object */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astSetAsTime" ); - -/* Obtain a pointer to the Axis object. */ - ax = astGetAxis( this, axis ); - -/* Check if the Axis object is a SkyAxis. If not, we will replace it with - one. */ - if ( !astIsASkyAxis( ax ) ) { - -/* Create a new SkyAxis and overlay the attributes of the original Axis. */ - new_ax = astSkyAxis( "", status ); - astAxisOverlay( ax, new_ax ); - -/* Modify the SkyFrame to use the new Skyaxis and annul the original Axis - pointer. Retain a pointer to the new SkyAxis. */ - astSetAxis( this, axis, new_ax ); - ax = astAnnul( ax ); - ax = (AstAxis *) new_ax; - } - -/* Set a value for the Axis AsTime attribute. */ - astSetAxisAsTime( ax, value ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* SkyFrame member function (extends the astSetAttrib method inherited from -* the Mapping class). - -* Description: -* This function assigns an attribute value for a SkyFrame, the attribute -* and its value being specified by means of a string of the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in lower -* case with no white space present. The value to the right of the "=" -* should be a suitable textual representation of the value to be assigned -* and this will be interpreted according to the attribute's data type. -* White space surrounding the value is only significant for string -* attributes. - -* Parameters: -* this -* Pointer to the SkyFrame. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Attributes: -* As well as those attributes inherited from the parent class, this -* function also accepts values for the following additional attributes: -* -* Equinox (double, read as a string) - -* Notes: -* This protected method is intended to be invoked by the Object astSet -* method and makes additional attributes accessible to it. -*/ - -/* Local Vaiables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - double dval; /* Floating point attribute value */ - double dval1; /* Floating point attribute value */ - double dval2; /* Floating point attribute value */ - double mjd; /* Modified Julian Date */ - int astime; /* Value of AsTime attribute */ - int axis; /* Axis index */ - int equinox; /* Offset of Equinox attribute value */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - int neglon; /* Display -ve longitudes? */ - int ok; /* Can string be used? */ - int offset; /* Offset of start of attribute value */ - int projection; /* Offset of projection attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* AsTime(axis). */ -/* ------------- */ - if ( nc = 0, - ( 2 == astSscanf( setting, "astime(%d)= %d %n", &axis, &astime, &nc ) ) - && ( nc >= len ) ) { - astSetAsTime( this, axis - 1, astime ); - -/* Equinox. */ -/* -------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "equinox=%n%*[^\n]%n", - &equinox, &nc ) ) && ( nc >= len ) ) { - -/* Convert the Equinox value to a Modified Julian Date before use. */ - mjd = astReadDateTime( setting + equinox ); - if ( astOK ) { - astSetEquinox( this, mjd ); - -/* Report contextual information if the conversion failed. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid equinox value " - "\"%s\" given for sky coordinate system.", status, - astGetClass( this ), setting + equinox ); - } - -/* NegLon. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "neglon= %d %n", &neglon, &nc ) ) - && ( nc >= len ) ) { - astSetNegLon( this, neglon ); - -/* SkyTol. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "skytol= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetSkyTol( this, dval ); - -/* Projection. */ -/* ----------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "projection=%n%*[^\n]%n", - &projection, &nc ) ) - && ( nc >= len ) ) { - astSetProjection( this, setting + projection ); - -/* SkyRef. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "skyref=%n%*[^\n]%n", - &offset, &nc ) ) - && ( nc >= len ) ) { - ok = 0; - nc = astUnformat( this, 0, setting + offset, &dval1 ); - if( setting[ offset + nc ] == ',' ) { - nc++; - nc += astUnformat( this, 1, setting + offset + nc, &dval2 ); - if( nc == strlen( setting + offset ) ) { - astSetSkyRef( this, 0, dval1 ); - astSetSkyRef( this, 1, dval2 ); - ok = 1; - } - } - - if( !ok && astOK ) { - astError( AST__BADOC, "astSetAttrib(%s): Invalid axis values string " - "\"%.*s\" given for SkyRef attribute.", status, astGetClass( this ), - (int) astChrLen( setting + offset ), setting + offset ); - } - -/* SkyRef(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "skyref(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetSkyRef( this, axis - 1, dval ); - -/* SkyRefIs. */ -/* --------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "skyrefis=%n%*[^\n]%n", - &offset, &nc ) ) - && ( nc >= len ) ) { - - if( astChrMatch( setting + offset, POLE_STRING ) ) { - astSetSkyRefIs( this, AST__POLE_REF ); - - } else if( astChrMatch( setting + offset, ORIGIN_STRING ) ) { - astSetSkyRefIs( this, AST__ORIGIN_REF ); - - } else if( astChrMatch( setting + offset, IGNORED_STRING ) ) { - astSetSkyRefIs( this, AST__IGNORED_REF ); - - } else if( astOK ) { - astError( AST__OPT, "astSet(%s): option '%s' is unknown in '%s'.", status, - astGetClass( this ), setting+offset, setting ); - } - -/* SkyRefP. */ -/* -------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "skyrefp=%n%*[^\n]%n", - &offset, &nc ) ) - && ( nc >= len ) ) { - - ok = 0; - nc = astUnformat( this, 0, setting + offset, &dval1 ); - if( setting[ offset + nc ] == ',' ) { - nc++; - nc += astUnformat( this, 1, setting + offset + nc, &dval2 ); - if( nc == strlen( setting + offset ) ) { - astSetSkyRefP( this, 0, dval1 ); - astSetSkyRefP( this, 1, dval2 ); - ok = 1; - } - } - - if( !ok && astOK ) { - astError( AST__BADOC, "astSetAttrib(%s): Invalid axis values string " - "\"%.*s\" given for SkyRefP attribute.", status, astGetClass( this ), - (int) astChrLen( setting + offset ), setting + offset ); - } - - -/* SkyRefP(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "skyrefp(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetSkyRefP( this, axis - 1, dval ); - -/* AlignOffset. */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "alignoffset= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetAlignOffset( this, ival ); - -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* If the attribute was not recognised, use this macro to report an error - if a read-only attribute has been specified. */ - } else if ( !strncmp( setting, "islataxis", 9 ) || - !strncmp( setting, "islonaxis", 9 ) || - MATCH( "lataxis" ) || - MATCH( "lonaxis" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Pass any unrecognised setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetCachedLAST( AstSkyFrame *this, double last, double epoch, - double obslon, double obslat, double obsalt, - double dut1, double dtai, int *status ) { -/* -* Name: -* SetCachedLAST - -* Purpose: -* Store a LAST value in the cache in the SkyFrame vtab. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetCachedLAST( AstSkyFrame *this, double last, double epoch, -* double obslon, double obslat, double obsalt, -* double dut1, double dtai, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function stores the supplied LAST value in a cache in the -* SkyFrame virtual function table for later use by GetCachedLAST. - -* Parameters: -* this -* Pointer to the SkyFrame. -* last -* The Local Apparent Sidereal Time (radians). -* epoch -* The epoch (MJD). -* obslon -* Observatory geodetic longitude (radians) -* obslat -* Observatory geodetic latitude (radians) -* obsalt -* Observatory geodetic altitude (metres) -* dut1 -* The UT1-UTC correction, in seconds. -* dtai -* The TAI-UTC correction, in seconds. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - AstSkyLastTable *table; - double *ep; - double *lp; - double lp_ref; - int i; - int itable; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise */ - table = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Ensure no threads are allowed to read the table whilst we are writing - to it. */ - LOCK_WLOCK1 - -/* Loop round every LAST table held in the vtab. Each table refers to a - different observatory position and/or DUT1 and/or DTAI value. */ - for( itable = 0; itable < nlast_tables; itable++ ) { - table = last_tables[ itable ]; - -/* See if the table refers to the given position, dut1 and dtai value, allowing - some small tolerance. If it does, leave the loop. */ - if( fabs( table->obslat - obslat ) < 2.0E-7 && - fabs( table->obslon - obslon ) < 2.0E-7 && - fabs( table->obsalt - obsalt ) < 1.0 && - fabs( table->dut1 - dut1 ) < 1.0E-5 && - EQUAL( table->dtai, dtai, 1.0E-5 ) ) break; - -/* Ensure "table" ends up NULL if no suitable table is found. */ - table = NULL; - } - -/* If no table was found, create one now, and add it into the vtab cache. */ - if( !table ) { - - astBeginPM; - table = astMalloc( sizeof( AstSkyLastTable ) ); - itable = nlast_tables++; - last_tables = astGrow( last_tables, nlast_tables, - sizeof( AstSkyLastTable * ) ); - astEndPM; - - if( astOK ) { - last_tables[ itable ] = table; - table->obslat = obslat; - table->obslon = obslon; - table->obsalt = obsalt; - table->dut1 = dut1; - table->dtai = dtai; - table->nentry = 1; - - astBeginPM; - table->epoch = astMalloc( sizeof( double ) ); - table->last = astMalloc( sizeof( double ) ); - astEndPM; - - if( astOK ) { - table->epoch[ 0 ] = epoch; - table->last[ 0 ] = last; - } - } - - -/* If we have a table, add the new point into it. */ - } else { - -/* Extend the epoch and last arrays. */ - astBeginPM; - table->epoch = astGrow( table->epoch, ++(table->nentry), sizeof( double ) ); - table->last = astGrow( table->last, table->nentry, sizeof( double ) ); - astEndPM; - -/* Check memory allocation was successful. */ - if( astOK ) { - -/* Get pointers to the last original elements in the arrays of epoch and - corresponding LAST values in the table. */ - ep = table->epoch + table->nentry - 2; - lp = table->last + table->nentry - 2; - -/* Starting from the end of the arrays, shuffle all entries up one - element until an element is found which is less than the supplied epoch - value. This maintains the epoch array in monotonic increasing order. */ - for( i = table->nentry - 2; i >= 0; i--,ep--,lp-- ) { - if( *ep <= epoch ) break; - ep[ 1 ] = *ep; - lp[ 1 ] = *lp; - } - -/* Store the new epoch and LAST value. Add or subtract 2.PI as needed - from the new LAST value to ensure it is continuous with an adjacent - LAST value. This is needed for interpolation between the two values - to be meaningful. */ - ep[ 1 ] = epoch; - -/* For most cases, compare with the previous LAST value. If the new epoch - value is smaller than any epoch already in the table, there will be no - previous LAST value. So compare with the next value instead. */ - if( i >= 0 ) { - lp_ref = lp[ 0 ]; - } else { - lp_ref = lp[ 2 ]; - } - - if( last > lp_ref + AST__DPI ) { - lp[ 1 ] = last - 2*AST__DPI; - - } else if( last < lp_ref - AST__DPI ) { - lp[ 1 ] = last + 2*AST__DPI; - - } else { - lp[ 1 ] = last; - } - } - } - -/* Indicate other threads are now allowed to read the table. */ - UNLOCK_RWLOCK1 - -} - -static void SetDtai( AstFrame *this_frame, double val, int *status ) { -/* -* Name: -* SetDtai - -* Purpose: -* Set the value of the Dtai attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetDtai( AstFrame *this, double val, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astSetDtai method -* inherited from the Frame class). - -* Description: -* This function clears the Dtai value and updates the LAST value -* stored in the SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* val -* New Dtai value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstSkyFrame *this; - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Note the original Dtai value. */ - orig = astGetDtai( this ); - -/* Invoke the parent method to set the Frame Dtai value. */ - (*parent_setdtai)( this_frame, val, status ); - -/* If the DTAI value has changed significantly, indicate that the LAST value - will need to be re-calculated when it is next needed. */ - if( ! EQUAL( orig, val, 1.0E-6 ) ) { - this->last = AST__BAD; - this->eplast = AST__BAD; - this->klast = AST__BAD; - } -} - -static void SetDut1( AstFrame *this_frame, double val, int *status ) { -/* -* Name: -* SetDut1 - -* Purpose: -* Set the value of the Dut1 attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetDut1( AstFrame *this, double val, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astSetDut1 method -* inherited from the Frame class). - -* Description: -* This function clears the Dut1 value and updates the LAST value -* stored in the SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* val -* New Dut1 value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstSkyFrame *this; - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Note the original Dut1 value. */ - orig = astGetDut1( this ); - -/* Invoke the parent method to set the Frame Dut1 value. */ - (*parent_setdut1)( this_frame, val, status ); - -/* If the DUT1 value has changed significantly, indicate that the LAST value - will need to be re-calculated when it is next needed. */ - if( fabs( orig - val ) > 1.0E-6 ) { - this->last = AST__BAD; - this->eplast = AST__BAD; - this->klast = AST__BAD; - } -} - -static void SetLast( AstSkyFrame *this, int *status ) { -/* -* Name: -* SetLast - -* Purpose: -* Set the Local Appearent Sidereal Time for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetLast( AstSkyFrame *this, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function sets the Local Apparent Sidereal Time at the epoch -* and geographical longitude given by the current values of the Epoch -* and ObsLon attributes associated with the supplied SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - double epoch; /* Epoch as a TDB MJD */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the SkyFrame Epoch as a TDB MJD. */ - epoch = astGetEpoch( this ); - -/* Calculate the LAST value (in rads) and store in the SkyFrame structure. */ - this->last = CalcLAST( this, epoch, astGetObsLon( this ), - astGetObsLat( this ), astGetObsAlt( this ), - astGetDut1( this ), astGetDtai( this ), status ); - -/* Save the TDB MJD to which this LAST corresponds. */ - this->eplast = epoch; - -/* The ratio between solar and sidereal time is a slowly varying function - of epoch. The GetLAST function returns a fast approximation to LAST - by using the ratio between solar and sidereal time. Indicate that - GetLAST should re-calculate the ratio by setting the ratio value bad. */ - this->klast = AST__BAD; -} - -static void SetObsAlt( AstFrame *this, double val, int *status ) { -/* -* Name: -* SetObsAlt - -* Purpose: -* Set the value of the ObsAlt attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetObsAlt( AstFrame *this, double val, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astSetObsAlt method -* inherited from the Frame class). - -* Description: -* This function sets the ObsAlt value. - -* Parameters: -* this -* Pointer to the SkyFrame. -* val -* New ObsAlt value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Note the original ObsAlt value. */ - orig = astGetObsAlt( this ); - -/* Invoke the parent method to set the Frame ObsAlt. */ - (*parent_setobsalt)( this, val, status ); - -/* If the altitude has changed significantly, indicate that the LAST value - and magnitude of the diurnal aberration vector will need to be - re-calculated when next needed. */ - if( fabs( orig - val ) > 0.001 ) { - ( (AstSkyFrame *) this )->last = AST__BAD; - ( (AstSkyFrame *) this )->eplast = AST__BAD; - ( (AstSkyFrame *) this )->klast = AST__BAD; - ( (AstSkyFrame *) this )->diurab = AST__BAD; - } -} - -static void SetObsLat( AstFrame *this, double val, int *status ) { -/* -* Name: -* SetObsLat - -* Purpose: -* Set the value of the ObsLat attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetObsLat( AstFrame *this, double val, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astSetObsLat method -* inherited from the Frame class). - -* Description: -* This function sets the ObsLat value. - -* Parameters: -* this -* Pointer to the SkyFrame. -* val -* New ObsLat value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Note the original ObsLat value. */ - orig = astGetObsLat( this ); - -/* Invoke the parent method to set the Frame ObsLat. */ - (*parent_setobslat)( this, val, status ); - -/* If the altitude has changed significantly, indicate that the LAST value - and magnitude of the diurnal aberration vector will need to be - re-calculated when next needed. */ - if( fabs( orig - val ) > 1.0E-8 ) { - ( (AstSkyFrame *) this )->last = AST__BAD; - ( (AstSkyFrame *) this )->eplast = AST__BAD; - ( (AstSkyFrame *) this )->klast = AST__BAD; - ( (AstSkyFrame *) this )->diurab = AST__BAD; - } -} - -static void SetObsLon( AstFrame *this, double val, int *status ) { -/* -* Name: -* SetObsLon - -* Purpose: -* Set the value of the ObsLon attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetObsLon( AstFrame *this, double val, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astSetObsLon method -* inherited from the Frame class). - -* Description: -* This function sets the ObsLon value. - -* Parameters: -* this -* Pointer to the SkyFrame. -* val -* New ObsLon value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double orig; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Note the original ObsLon value. */ - orig = astGetObsLon( this ); - -/* Invoke the parent method to set the Frame ObsLon. */ - (*parent_setobslon)( this, val, status ); - -/* If the longitude has changed significantly, indicate that the LAST value - will need to be re-calculated when it is next needed. */ - if( fabs( orig - val ) > 1.0E-8 ) { - ( (AstSkyFrame *) this )->last = AST__BAD; - ( (AstSkyFrame *) this )->eplast = AST__BAD; - ( (AstSkyFrame *) this )->klast = AST__BAD; - } -} - -static void SetSystem( AstFrame *this_frame, AstSystemType system, int *status ) { -/* -* Name: -* SetSystem - -* Purpose: -* Set the System attribute for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void SetSystem( AstFrame *this_frame, AstSystemType system, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astSetSystem protected -* method inherited from the Frame class). - -* Description: -* This function assigns a new value to the System attribute for a SkyFrame. - -* Parameters: -* this -* Pointer to the SkyFrame. -* system -* The new System value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrameSet *fs; /* FrameSet to be used as the Mapping */ - AstSkyFrame *sfrm; /* Copy of original SkyFrame */ - AstSkyFrame *this; /* Pointer to SkyFrame structure */ - double xin[ 2 ]; /* Axis 0 values */ - double xout[ 2 ]; /* Axis 0 values */ - double yin[ 2 ]; /* Axis 1 values */ - double yout[ 2 ]; /* Axis 1 values */ - int aloff; /* The AlignOffset attribute value */ - int aloff_set; /* Is the AlignOffset attribute set? */ - int skyref_set; /* Is either SkyRef attribute set? */ - int skyrefis; /* The SkyRefIs attribute value */ - int skyrefis_set; /* Is the SkyRefIs attribute set? */ - int skyrefp_set; /* Is either SkyRefP attribute set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* See if either the SkyRef or SkyRefP attribute is set. */ - skyref_set = astTestSkyRef( this, 0 ) || astTestSkyRef( this, 1 ); - skyrefp_set = astTestSkyRefP( this, 0 ) || astTestSkyRefP( this, 1 ); - -/* If so, we will need to transform their values into the new coordinate - system. Save a copy of the SkyFrame with its original System value. */ - sfrm = ( skyref_set || skyrefp_set )?astCopy( this ):NULL; - -/* Use the parent method to set the new System value. */ - (*parent_setsystem)( this_frame, system, status ); - -/* Now modify the SkyRef and SkyRefP attributes if necessary. */ - if( sfrm ) { - -/* Save the AlignOffset, SkyRefIs, SkyRef and SkyRefP values. */ - aloff_set = astTestAlignOffset( sfrm ); - aloff = astGetAlignOffset( sfrm ); - skyrefis_set = astTestSkyRefIs( sfrm ); - skyrefis = astGetSkyRefIs( sfrm ); - - xin[ 0 ] = astGetSkyRef( sfrm, 0 ); - xin[ 1 ] = astGetSkyRefP( sfrm, 0 ); - yin[ 0 ] = astGetSkyRef( sfrm, 1 ); - yin[ 1 ] = astGetSkyRefP( sfrm, 1 ); - -/* Clear the SkyRef and SkyRefP values to avoid infinite recursion in the - following call to astConvert. */ - if( skyref_set ) { - astClearSkyRef( sfrm, 0 ); - astClearSkyRef( sfrm, 1 ); - astClearSkyRef( this, 0 ); - astClearSkyRef( this, 1 ); - } - - if( skyrefp_set ) { - astClearSkyRefP( sfrm, 0 ); - astClearSkyRefP( sfrm, 1 ); - astClearSkyRefP( this, 0 ); - astClearSkyRefP( this, 1 ); - } - -/* Also set AlignOffset and SkyRefIs so that the following call to - astConvert does not align in offset coords. */ - astSetAlignOffset( sfrm, 0 ); - astSetSkyRefIs( sfrm, AST__IGNORED_REF ); - -/* Get the Mapping from the original System to the new System. Invoking - astConvert will recursively invoke SetSystem again. This is why we need - to be careful to ensure that SkyRef and SKyRefP are cleared above - doing - so ensure we do not end up with infinite recursion. */ - fs = astConvert( sfrm, this, "" ); - -/* If the conversion is not possible, clear the SkyRef and SkyRefP - values. */ - if( !fs ) { - if( skyref_set ) { - astClearSkyRef( this, 0 ); - astClearSkyRef( this, 1 ); - } - if( skyrefp_set ) { - astClearSkyRefP( this, 0 ); - astClearSkyRefP( this, 1 ); - } - -/* Use the Mapping to find the SkyRef and SkyRefP positions in the new - coordinate system. */ - } else { - astTran2( fs, 2, xin, yin, 1, xout, yout ); - -/* Store the values as required. */ - if( skyref_set ) { - astSetSkyRef( this, 0, xout[ 0 ] ); - astSetSkyRef( this, 1, yout[ 0 ] ); - } - - if( skyrefp_set ) { - astSetSkyRefP( this, 0, xout[ 1 ] ); - astSetSkyRefP( this, 1, yout[ 1 ] ); - } - -/* Restore the original SkyRefIs and AlignOffset values. */ - if( aloff_set ) { - astSetAlignOffset( this, aloff ); - } else { - astClearAlignOffset( this ); - } - - if( skyrefis_set ) { - astSetSkyRefIs( this, skyrefis ); - } else { - astClearSkyRefIs( this ); - } - -/* Free resources. */ - fs = astAnnul( fs ); - } - sfrm = astAnnul( sfrm ); - } -} - -static void Shapp( double dist, double *r0, double *r3, double a0, - double *p4, int *status ){ -/* -* Name: -* Shapp - -* Purpose: -* Use the vectors calculated by Shcal to find a sky position -* which is offset along a given position angle. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void Shapp( double dist, double *r0, double *r3, double a0, -* double *p4, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function uses the vectors R0 and R3 calculated previously by -* Shcal to find the sky position which is offset away from the -* "reference" position (see function Offset2) by a given arc -* distance, along a given great circle. -* -* No checks are made for AST__BAD values. - -* Parameters: -* dist -* The arc distance to move away from the reference position -* in the given direction, in radians. -* r0 -* Pointer to an array holding the 3-vector representing the reference -* position. -* r3 -* Pointer to an array holding the 3-vector representing the -* point which is 90 degrees away from the reference point, along -* the required great circle. -* a0 -* The sky longitude of the reference position, in radians. -* p4 -* Pointer to an array of 2 doubles in which to put the sky longitude -* and latitude of the required point, in radians. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double cosdst; /* Cosine of DIST */ - double r4[ 3 ]; /* Required position vector */ - double sindst; /* Sine of DIST */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store commonly used values. */ - sindst = sin( dist ); - cosdst = cos( dist ); - -/* The vector R4 representing the required point is produced as a - linear sum of R0 and R3. */ - r4[ 0 ] = cosdst*r0[ 0 ] + sindst*r3[ 0 ]; - r4[ 1 ] = cosdst*r0[ 1 ] + sindst*r3[ 1 ]; - r4[ 2 ] = cosdst*r0[ 2 ] + sindst*r3[ 2 ]; - -/* Create the longitude of the required point. If this point is at - a pole it is assigned the same longitude as the reference point. */ - if( r4[ 0 ] != 0.0 || r4[ 1 ] != 0.0 ) { - p4[ 0 ] = atan2( r4[ 1 ], r4[ 0 ] ); - } else { - p4[ 0 ] = a0; - } - -/* Create the latitude of the required point. */ - if( r4[ 2 ] > 1.0 ) { - r4[ 2 ] = 1.0; - } else if( r4[ 2 ] < -1.0 ) { - r4[ 2 ] = -1.0; - } - p4[ 1 ] = asin( r4[ 2 ] ); - -} - -static void Shcal( double a0, double b0, double angle, double *r0, - double *r3, int *status ) { -/* -* Name: -* Shcal - -* Purpose: -* Calculate vectors required by Offset2. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void Shcal( double a0, double b0, double angle, double *r0, -* double *r3, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function calculates the 3-vector R0, representing the given -* sky position (A0,B0), and the 3-vector R3, representing the sky -* position which is 90 degrees away from R0, along a great circle -* passing through R0 at a position angle given by ANGLE. Each -* 3-vector holds Cartesian (X,Y,Z) values with origin at the centre -* of the celestial sphere. The XY plane is the "equator", the Z -* axis is in the direction of the "north pole", X is towards zero -* longitude (A=0), and Y is towards longitude 90 degrees. -* -* No checks are made for AST__BAD input values. - -* Parameters: -* a0 -* The sky longitude of the given position, in radians. -* b0 -* The sky latitude of the given position, in radians. -* angle -* The position angle of a great circle passing through the given -* position. That is, the angle from north to the required -* direction, in radians. Positive angles are in the sense of -* rotation from north to east. -* r0 -* A pointer to an array to receive 3-vector R0. See above. -* r3 -* A pointer to an array to receive 3-vector R3. See above. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double cosa0; /* Cosine of A0 */ - double cosb0; /* Cosine of B0 */ - double cospa; /* Cosine of ANGLE */ - double r1[ 3 ]; /* Vector PI/2 away from R0 in meridian of R0 */ - double r2[ 3 ]; /* Vector PI/2 away from R0 on equator */ - double sinpa; /* Sine of ANGLE */ - double sina0; /* Sine of A0 */ - double sinb0; /* Sine of B0 */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store commonly used values. */ - sina0 = sin( a0 ); - cosa0 = cos( a0 ); - sinb0 = sin( b0 ); - cosb0 = cos( b0 ); - sinpa = sin( angle ); - cospa = cos( angle ); - -/* Create the vector R0 representing the given point. The XY plane - defines zero latitude, Z is in the direction of increasing latitude, - X is towards zero longitude, and Y is towards longitude 90 degrees. */ - r0[ 0 ] = cosb0*cosa0; - r0[ 1 ] = cosb0*sina0; - r0[ 2 ] = sinb0; - -/* Create the vector R1 representing the point in the meridian of the - given point which has latitude 90 degrees greater than the - given point. */ - r1[ 0 ] = -sinb0*cosa0; - r1[ 1 ] = -sinb0*sina0; - r1[ 2 ] = cosb0; - -/* Create the vector R2 representing the point on the equator (i.e. a - latitude of zero), which has a longitude 90 degrees to the west of - the given point. */ - r2[ 0 ] = -sina0; - r2[ 1 ] = cosa0; - r2[ 2 ] = 0.0; - -/* Create the vector R3 representing the point which is 90 degrees away - from the given point, along the required great circle. */ - r3[ 0 ] = cospa*r1[ 0 ] + sinpa*r2[ 0 ]; - r3[ 1 ] = cospa*r1[ 1 ] + sinpa*r2[ 1 ]; - r3[ 2 ] = cospa*r1[ 2 ] + sinpa*r2[ 2 ]; - -/* Return */ - return; -} - -static int SubFrame( AstFrame *target_frame, AstFrame *template, - int result_naxes, const int *target_axes, - const int *template_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* SubFrame - -* Purpose: -* Select axes from a SkyFrame and convert to the new coordinate system. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int SubFrame( AstFrame *target, AstFrame *template, -* int result_naxes, const int *target_axes, -* const int *template_axes, AstMapping **map, -* AstFrame **result, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the protected astSubFrame method -* inherited from the Frame class). - -* Description: -* This function selects a requested sub-set (or super-set) of the axes from -* a "target" SkyFrame and creates a new Frame with copies of the selected -* axes assembled in the requested order. It then optionally overlays the -* attributes of a "template" Frame on to the result. It returns both the -* resulting Frame and a Mapping that describes how to convert between the -* coordinate systems described by the target and result Frames. If -* necessary, this Mapping takes account of any differences in the Frames' -* attributes due to the influence of the template. - -* Parameters: -* target -* Pointer to the target SkyFrame, from which axes are to be selected. -* template -* Pointer to the template Frame, from which new attributes for the -* result Frame are to be obtained. Optionally, this may be NULL, in -* which case no overlaying of template attributes will be performed. -* result_naxes -* Number of axes to be selected from the target Frame. This number may -* be greater than or less than the number of axes in this Frame (or -* equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving a list -* of the (zero-based) axis indices of the axes to be selected from the -* target SkyFrame. The order in which these are given determines the -* order in which the axes appear in the result Frame. If any of the -* values in this array is set to -1, the corresponding result axis will -* not be derived from the target Frame, but will be assigned default -* attributes instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This should -* contain a list of the template axes (given as zero-based axis indices) -* with which the axes of the result Frame are to be associated. This -* array determines which axes are used when overlaying axis-dependent -* attributes of the template on to the result. If any element of this -* array is set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not used and -* a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned Mapping. -* The forward transformation of this Mapping will describe how to -* convert coordinates from the coordinate system described by the target -* SkyFrame to that described by the result Frame. The inverse -* transformation will convert in the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is possible -* between the target and the result Frame. Otherwise zero is returned and -* *map and *result are returned as NULL (but this will not in itself -* result in an error condition). In general, coordinate conversion should -* always be possible if no template Frame is supplied but may not always -* be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* - This implementation addresses the selection of axes from a SkyFrame -* object. This results in another object of the same class only if both -* axes of the SkyFrame are selected, once each. Otherwise, the result is a -* Frame class object which inherits the SkyFrame's axis information (if -* appropriate) but none of the other properties of a SkyFrame. -* - In the event that a SkyFrame results, the returned Mapping will take -* proper account of the relationship between the target and result sky -* coordinate systems. -* - In the event that a Frame class object results, the returned Mapping -* will only represent a selection/permutation of axes. - -* Implementation Deficiencies: -* - Any axis selection is currently permitted. Probably this should be -* restricted so that each axis can only be selected once. The -* astValidateAxisSelection method will do this but currently there are bugs -* in the CmpFrame class that cause axis selections which will not pass this -* test. Install the validation when these are fixed. -*/ - -/* Local Variables: */ - AstAxis *ax; /* Pointer to result Frame Axis object */ - AstMapping *tmpmap; /* Temporary Mapping pointer */ - AstPermMap *permmap; /* Pointer to PermMap */ - AstSkyFrame *target; /* Pointer to the SkyFrame structure */ - AstSkyFrame *temp; /* Pointer to copy of target SkyFrame */ - AstSystemType align_sys; /* System in which to align the SkyFrames */ - int match; /* Coordinate conversion is possible? */ - int perm[ 2 ]; /* Permutation array for axis swap */ - int result_swap; /* Swap result SkyFrame coordinates? */ - int set_usedefs; /* Set the returned UseDefs attribute zero?*/ - int target_axis; /* Target SkyFrame axis index */ - int target_swap; /* Swap target SkyFrame coordinates? */ - -/* Initialise the returned values. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the target SkyFrame structure. */ - target = (AstSkyFrame *) target_frame; - -/* Result is a SkyFrame. */ -/* --------------------- */ -/* Check if the result Frame is to have two axes obtained by selecting - both of the target SkyFrame axes, in either order. If so, the - result will also be a SkyFrame. */ - if ( ( result_naxes == 2 ) && - ( ( ( target_axes[ 0 ] == 0 ) && ( target_axes[ 1 ] == 1 ) ) || - ( ( target_axes[ 0 ] == 1 ) && ( target_axes[ 1 ] == 0 ) ) ) ) { - -/* If a template has not been supplied, or is the same object as the - target, we are simply extracting axes from the supplied SkyFrame. In - this case we temporarily force the UseDefs attribute to 1 so that (for - instance) the astPickAxes method can function correctly. E.g. if you - have a SkyFrame with no set Epoch and UseDefs set zero, and you try to - swap the axes, the attempt would fail because MakeSkyMapping would be - unable to determine the Mapping from original to swapped SkyFrame, - because of the lack of an Epoch value. */ - set_usedefs = 0; - if( !template || template == target_frame ) { - if( !astGetUseDefs( target ) ) { - astClearUseDefs( target ); - set_usedefs = 1; - } - } - -/* Form the result from a copy of the target and then permute its axes - into the order required. */ - *result = astCopy( target ); - astPermAxes( *result, target_axes ); - -/* If required, overlay the template attributes on to the result SkyFrame. - Also get the system in which to align the two SkyFrames. This is the - value of the AlignSystem attribute from the template (if there is a - template). */ - if ( template ) { - astOverlay( template, template_axes, *result ); - align_sys = astGetAlignSystem( template ); - - } else { - align_sys = astGetAlignSystem( target ); - } - -/* See whether alignment occurs in offset coordinates or absolute - coordinates. If the current call to this function is part of the - process of restoring a FrameSet's integrity following changes to - the FrameSet's current Frame, then we ignore the setting of the - AlignOffset attributes and use 0. This ensures that when the System - attribute (for instance) is changed via a FrameSet pointer, the - Mappings within the FrameSet are modified to produce offsets in the - new System. If we are not currently restoring a FrameSet's integrity, - then we align in offsets if the template is a SkyFrame and both template - and target want alignment to occur in the offset coordinate system. In - this case we use a UnitMap to connect them. */ - if( ( astGetFrameFlags( target_frame ) & AST__INTFLAG ) == 0 ) { - if( astGetAlignOffset( target ) && - astGetSkyRefIs( target ) != AST__IGNORED_REF && - template && astIsASkyFrame( template ) ){ - if( astGetAlignOffset( (AstSkyFrame *) template ) && - astGetSkyRefIs( (AstSkyFrame *) template ) != AST__IGNORED_REF ) { - match = 1; - *map = (AstMapping *) astUnitMap( 2, "", status ); - } - } - } - -/* Otherwise, generate a Mapping that takes account of changes in the sky - coordinate system (equinox, epoch, etc.) between the target SkyFrame and - the result SkyFrame. If this Mapping can be generated, set "match" to - indicate that coordinate conversion is possible. */ - if( ! *map ) { - match = ( MakeSkyMapping( target, (AstSkyFrame *) *result, - align_sys, map, status ) != 0 ); - } - -/* If required, re-instate the original zero value of UseDefs. */ - if( set_usedefs ) { - astSetUseDefs( target, 0 ); - astSetUseDefs( *result, 0 ); - } - -/* If a Mapping has been obtained, it will expect coordinate values to be - supplied in (longitude,latitude) pairs. Test whether we need to swap the - order of the target SkyFrame coordinates to conform with this. */ - if ( astOK && match ) { - target_swap = ( astValidateAxis( target, 0, 1, "astSubFrame" ) != 0 ); - -/* Coordinates will also be delivered in (longitude,latitude) pairs, so check - to see whether the result SkyFrame coordinate order should be swapped. */ - result_swap = ( target_swap != ( target_axes[ 0 ] != 0 ) ); - -/* If either set of coordinates needs swapping, create a PermMap that - will swap a pair of coordinates. */ - permmap = NULL; - if ( target_swap || result_swap ) { - perm[ 0 ] = 1; - perm[ 1 ] = 0; - permmap = astPermMap( 2, perm, 2, perm, NULL, "", status ); - } - -/* If necessary, prefix this PermMap to the main Mapping. */ - if ( target_swap ) { - tmpmap = (AstMapping *) astCmpMap( permmap, *map, 1, "", status ); - *map = astAnnul( *map ); - *map = tmpmap; - } - -/* Also, if necessary, append it to the main Mapping. */ - if ( result_swap ) { - tmpmap = (AstMapping *) astCmpMap( *map, permmap, 1, "", status ); - *map = astAnnul( *map ); - *map = tmpmap; - } - -/* Annul the pointer to the PermMap (if created). */ - if ( permmap ) permmap = astAnnul( permmap ); - } - -/* Result is not a SkyFrame. */ -/* ------------------------- */ -/* In this case, we select axes as if the target were from the Frame - class. However, since the resulting data will then be separated - from their enclosing SkyFrame, default attribute values may differ - if the methods for obtaining them were over-ridden by the SkyFrame - class. To overcome this, we ensure that these values are explicitly - set for the result Frame (rather than relying on their - defaults). */ - } else { - -/* Make a temporary copy of the target SkyFrame. We will explicitly - set the attribute values in this copy so as not to modify the - original. */ - temp = astCopy( target ); - -/* Define a macro to test if an attribute is set. If not, set it - explicitly to its default value. */ -#define SET(attribute) \ - if ( !astTest##attribute( temp ) ) { \ - astSet##attribute( temp, astGet##attribute( temp ) ); \ - } - -/* Set attribute values which apply to the Frame as a whole and which - we want to retain, but whose defaults are over-ridden by the - SkyFrame class. */ - SET(Domain) - SET(Title) - -/* Now loop to set explicit attribute values for each axis. */ - for ( target_axis = 0; target_axis < 2; target_axis++ ) { - -/* Define a macro to test if an axis attribute is set. If not, set it - explicitly to its default value. */ -#define SET_AXIS(attribute) \ - if ( !astTest##attribute( temp, target_axis ) ) { \ - astSet##attribute( temp, target_axis, \ - astGet##attribute( temp, target_axis ) ); \ - } - -/* Use this macro to set explicit values for all the axis attributes - for which the SkyFrame class over-rides the default value. */ - SET_AXIS(AsTime) - SET_AXIS(Format) - SET_AXIS(Label) - SET_AXIS(Symbol) - SET_AXIS(Unit) - -/* Now handle axis attributes for which there are no SkyFrame access - methods. For these we require a pointer to the temporary - SkyFrame's Axis object. */ - ax = astGetAxis( temp, target_axis ); - -/* Set an explicit value for the IsLatitude and CentreZero attributes. */ - if( astValidateAxis( temp, target_axis, 1, "astSubFrame" ) == 1 ) { - astSetAxisIsLatitude( ax, 1 ); - astSetAxisCentreZero( ax, 1 ); - - } else { - astSetAxisIsLatitude( ax, 0 ); - astSetAxisCentreZero( ax, astGetNegLon( temp ) ); - } - -/* Annul the Axis object pointer. */ - ax = astAnnul( ax ); - } - -/* Clear attributes which have an extended range of values allowed by - this class. */ - astClearSystem( temp ); - astClearAlignSystem( temp ); - -/* Invoke the astSubFrame method inherited from the Frame class to - produce the result Frame by selecting the required set of axes and - overlaying the template Frame's attributes. */ - match = (*parent_subframe)( (AstFrame *) temp, template, - result_naxes, target_axes, template_axes, - map, result, status ); - -/* Delete the temporary copy of the target SkyFrame. */ - temp = astDelete( temp ); - } - -/* Ensure the returned Frame does not have active units. */ - astSetActiveUnit( *result, 0 ); - -/* If an error occurred or no match was found, annul the returned - objects and reset the returned result. */ - if ( !astOK || !match ) { - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; - -/* Undefine macros local to this function. */ -#undef SET -#undef SET_AXIS -} - -static AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) { -/* -* Name: -* SystemCode - -* Purpose: -* Convert a string into a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astSystemCode method -* inherited from the Frame class). - -* Description: -* This function converts a string used for the external -* description of a sky coordinate system into a SkyFrame -* coordinate system type code (System attribute value). It is the -* inverse of the astSystemString function. - -* Parameters: -* this -* The Frame. -* system -* Pointer to a constant null-terminated string containing the -* external description of the sky coordinate system. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System type code. - -* Notes: -* - A value of AST__BADSYSTEM is returned if the sky coordinate -* system description was not recognised. This does not produce an -* error. -* - A value of AST__BADSYSTEM is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" string against each possibility and assign the - result. */ - if ( astChrMatch( "FK4", system ) ) { - result = AST__FK4; - - } else if ( astChrMatch( "FK4_NO_E", system ) || - astChrMatch( "FK4-NO-E", system ) ) { - result = AST__FK4_NO_E; - - } else if ( astChrMatch( "FK5", system ) || - astChrMatch( "Equatorial", system ) ) { - result = AST__FK5; - - } else if ( astChrMatch( "J2000", system ) ) { - result = AST__J2000; - - } else if ( astChrMatch( "ICRS", system ) ) { - result = AST__ICRS; - - } else if ( astChrMatch( "AZEL", system ) ) { - result = AST__AZEL; - - } else if ( astChrMatch( "GAPPT", system ) || - astChrMatch( "GEOCENTRIC", system ) || - astChrMatch( "APPARENT", system ) ) { - result = AST__GAPPT; - - } else if ( astChrMatch( "ECLIPTIC", system ) ) { - result = AST__ECLIPTIC; - - } else if ( astChrMatch( "HELIOECLIPTIC", system ) ) { - result = AST__HELIOECLIPTIC; - - } else if ( astChrMatch( "GALACTIC", system ) ) { - result = AST__GALACTIC; - - } else if ( astChrMatch( "SUPERGALACTIC", system ) ) { - result = AST__SUPERGALACTIC; - - } else if ( astChrMatch( "UNKNOWN", system ) ) { - result = AST__UNKNOWN; - } - -/* Return the result. */ - return result; -} - -static const char *SystemString( AstFrame *this, AstSystemType system, int *status ) { -/* -* Name: -* SystemString - -* Purpose: -* Convert a coordinate system type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* const char *SystemString( AstFrame *this, AstSystemType system, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astSystemString method -* inherited from the Frame class). - -* Description: -* This function converts a SkyFrame coordinate system type code -* (System attribute value) into a string suitable for use as an -* external representation of the coordinate system type. - -* Parameters: -* this -* The Frame. -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the sky coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. (Where possible, return the same string as would be - used in the FITS WCS representation of the coordinate system). */ - switch ( system ) { - case AST__FK4: - result = "FK4"; - break; - - case AST__FK4_NO_E: - result = "FK4-NO-E"; - break; - - case AST__FK5: - result = "FK5"; - break; - - case AST__J2000: - result = "J2000"; - break; - - case AST__ICRS: - result = "ICRS"; - break; - - case AST__GAPPT: - result = "GAPPT"; - break; - - case AST__AZEL: - result = "AZEL"; - break; - - case AST__ECLIPTIC: - result = "ECLIPTIC"; - break; - - case AST__HELIOECLIPTIC: - result = "HELIOECLIPTIC"; - break; - - case AST__GALACTIC: - result = "GALACTIC"; - break; - - case AST__SUPERGALACTIC: - result = "SUPERGALACTIC"; - break; - - case AST__UNKNOWN: - result = "Unknown"; - break; - } - -/* Return the result pointer. */ - return result; -} - -static int TestActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* TestActiveUnit - -* Purpose: -* Test the ActiveUnit flag for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int TestActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astTestActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function test the value of the ActiveUnit flag for a SkyFrame, -* which is always "unset". - -* Parameters: -* this -* Pointer to the SkyFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The result of the test (0). - -*/ - return 0; -} - -static int TestAsTime( AstSkyFrame *this, int axis, int *status ) { -/* -* Name: -* TestAsTime - -* Purpose: -* Determine if a value has been set for a SkyFrame's AsTime attribute. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int TestAsTime( AstSkyFrame *this, int axis, int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function returns a boolean value to indicate if a value has -* previously been set for the AsTime attribute for a specified axis of a -* SkyFrame. This attribute indicates whether axis values should be -* formatted as times (as opposed to angles) by default. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* Index of the axis for which information is required (zero based). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero or one, according to whether the AsTime attribute has been set. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables. */ - AstAxis *ax; /* Pointer to Axis object */ - int result; /* Result to be returned */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astTestAsTime" ); - -/* Obtain a pointer to the Axis object. */ - ax = astGetAxis( this, axis ); - -/* Determine if the AsTime attribute has been set for it (it cannot have been - set unless the object is a SkyAxis). */ - result = ( astIsASkyAxis( ax ) && astTestAxisAsTime( ax ) ); - -/* Annul the Axis pointer. */ - ax = astAnnul( ax ); - -/* Return the result. */ - return result; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astTestAttrib protected -* method inherited from the Frame class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a SkyFrame's attributes. - -* Parameters: -* this -* Pointer to the SkyFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - int axis; /* SkyFrame axis number */ - int len; /* Length of attrib string */ - int nc; /* No. characters read by astSscanf */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* AsTime(axis). */ -/* ------------- */ - if ( nc = 0, - ( 1 == astSscanf( attrib, "astime(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestAsTime( this, axis - 1 ); - -/* Equinox. */ -/* -------- */ - } else if ( !strcmp( attrib, "equinox" ) ) { - result = astTestEquinox( this ); - -/* NegLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "neglon" ) ) { - result = astTestNegLon( this ); - -/* SkyTol. */ -/* ------- */ - } else if ( !strcmp( attrib, "skytol" ) ) { - result = astTestSkyTol( this ); - -/* Projection. */ -/* ----------- */ - } else if ( !strcmp( attrib, "projection" ) ) { - result = astTestProjection( this ); - -/* SkyRefIs. */ -/* --------- */ - } else if ( !strcmp( attrib, "skyrefis" ) ) { - result = astTestSkyRefIs( this ); - -/* SkyRef. */ -/* ------- */ - } else if ( !strcmp( attrib, "skyref" ) ) { - result = astTestSkyRef( this, 0 ) || astTestSkyRef( this, 1 ); - -/* SkyRef(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "skyref(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestSkyRef( this, axis - 1 ); - -/* SkyRefP. */ -/* -------- */ - } else if ( !strcmp( attrib, "skyrefp" ) ) { - result = astTestSkyRefP( this, 0 ) || astTestSkyRefP( this, 1 ); - -/* SkyRefP(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "skyrefp(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestSkyRefP( this, axis - 1 ); - -/* AlignOffset */ -/* ----------- */ - } else if ( !strcmp( attrib, "alignoffset" ) ) { - result = astTestAlignOffset( this ); - -/* If the name is not recognised, test if it matches any of the - read-only attributes of this class. If it does, then return - zero. */ - } else if ( !strncmp( attrib, "islataxis", 9 ) || - !strncmp( attrib, "islonaxis", 9 ) || - !strcmp( attrib, "lataxis" ) || - !strcmp( attrib, "lonaxis" ) ) { - result = 0; - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static int TestSlaUnit( AstSkyFrame *sf1, AstSkyFrame *sf2, AstSlaMap *slamap, - int *status ){ -/* -* Name: -* Unformat - -* Purpose: -* See if a slamap is effectively a unit mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int TestSlaUnit( AstSkyFrame *sf1, AstSkyFrame *sf2, AstSlaMap *slamap, -* int *status ) - -* Class Membership: -* SkyFrame member function. - -* Description: -* This function tests a SlaMap to see if it is effectively a unit -* transformatuon to within a tolerance given by the smaller tolerance -* of the two supplied SkyFrames. - -* Parameters: -* sf1 -* Pointer to the first SkyFrame. -* sf2 -* Pointer to the second SkyFrame (may be NULL) -* slamap -* Pointer to the SlaMap to test. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the SlaMap is effectively a unit mapping, and zero -* otherwise. - -*/ - -/* Number of test points. */ -#define NTEST 14 - -/* Local Variables: */ - double maxshift; /* Max. shift produced by slamap (rads) */ - double olat[NTEST]; /* Transformed latitudes */ - double olon[NTEST]; /* Transformed longitudes */ - double shift; /* Shift produced by slamap (rads) */ - double tol2; /* Second tolerance (in radians) */ - double tol; /* Used tolerance (in radians) */ - int i; /* Loop count */ - int result; /* Returned flag */ - -/* A grid of lon/lat points covering the sphere. */ - double lat[ NTEST ] = { 0.0, 0.0, 0.0, 0.0, - 0.8, 0.8, 0.8, 0.8, - -0.8, -0.8, -0.8, -0.8, - 1.570796, -1.570796 }; - double lon[ NTEST ] = { 0.0, 1.57, 3.14, 4.71, - 0.8, 2.37, 3.94, 5.51, - 0.8, 2.37, 3.94, 5.51, - 0.0, 0.0 }; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the SlaMap is empty (i.e. has no conversions in it), then is it a - UnitMap. So save time by not transforming the test values. */ - if( astSlaIsEmpty( slamap ) ) { - result = 1; - -/* Otherwise, get the smaller of the tolerances associated with the - supplied SkyFrames, in radians. */ - } else { - tol = astGetSkyTol( sf1 ); - if( sf2 ) { - tol2 = astGetSkyTol( sf2 ); - if( tol2 < tol ) tol = tol2; - } - -/* If the tolerance is zero, there is no need to do the test. */ - if( tol > 0.0 ) { - -/* Transform the test point using the SlaMap. */ - astTran2( slamap, NTEST, lon, lat, 1, olon, olat ); - -/* Find the maximum shift produced by the SlaMap at any of the test - positions. Again, to avoid the slow-down produced by checking for - axis permutation, use palDsep rather than astDistance. */ - maxshift = 0.0; - for( i = 0; i < NTEST; i++ ) { - shift = palDsep( lon[ i ], lat[ i ], olon[ i ], olat[ i ] ); - if( shift > maxshift ) maxshift = shift; - } - -/* Convert the max shift to arc-seconds and do the check. */ - result = ( maxshift*AST__DR2D*3600 < tol ); - } - } - - return result; -} - -static int Unformat( AstFrame *this_frame, int axis, const char *string, - double *value, int *status ) { -/* -* Name: -* Unformat - -* Purpose: -* Read a formatted coordinate value for a SkyFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* int Unformat( AstFrame *this, int axis, const char *string, -* double *value, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the public astUnformat -* method inherited from the Frame class). - -* Description: -* This function reads a formatted coordinate value for a SkyFrame -* axis (supplied as a string) and returns the equivalent numerical -* value as a double. It also returns the number of characters read -* from the string. - -* Parameters: -* this -* Pointer to the SkyFrame. -* axis -* The number of the SkyFrame axis for which the coordinate -* value is to be read (axis numbering starts at zero for the -* first axis). -* string -* Pointer to a constant null-terminated string containing the -* formatted coordinate value. -* value -* Pointer to a double in which the coordinate value read will -* be returned (in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of characters read from the string to obtain the -* coordinate value. - -* Notes: -* - Any white space at the beginning of the string will be -* skipped, as also will any trailing white space following the -* coordinate value read. The function's return value will reflect -* this. -* - A function value of zero (and no coordinate value) will be -* returned, without error, if the string supplied does not contain -* a suitably formatted value. -* - The string "" is recognised as a special case and will -* generate the value AST__BAD, without error. The test for this -* string is case-insensitive and permits embedded white space. -* - A function result of zero will be returned and no coordinate -* value will be returned via the "value" pointer if this function -* is invoked with the global error status set, or if it should -* fail for any reason. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - double coord; /* Coordinate value read */ - int format_set; /* Format attribute set? */ - int nc; /* Number of characters read */ - -/* Initialise. */ - nc = 0; - -/* Check the global error status. */ - if ( !astOK ) return nc; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astUnformat" ); - -/* Determine if a Format value has been set for the axis and set a - temporary value if it has not. Use the GetFormat member function - for this class together with member functions inherited from the - parent class (rather than using the object's methods directly) - because if any of these methods have been over-ridden by a derived - class the Format string syntax may no longer be compatible with - this class. */ - format_set = (*parent_testformat)( this_frame, axis, status ); - if ( !format_set ) { - (*parent_setformat)( this_frame, axis, GetFormat( this_frame, axis, status ), status ); - } - -/* Use the Unformat member function inherited from the parent class to - read the coordinate value. */ - nc = (*parent_unformat)( this_frame, axis, string, &coord, status ); - -/* If necessary, clear any temporary Format value that was set above. */ - if ( !format_set ) (*parent_clearformat)( this_frame, axis, status ); - -/* If an error occurred, clear the number of characters read. */ - if ( !astOK ) { - nc = 0; - -/* Otherwise, if characters were read, return the coordinate value. */ - } else if ( nc ) { - *value = coord; - } - -/* Return the number of characters read. */ - return nc; -} - -static int ValidateSystem( AstFrame *this, AstSystemType system, const char *method, int *status ) { -/* -* -* Name: -* ValidateSystem - -* Purpose: -* Validate a value for a Frame's System attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int ValidateSystem( AstFrame *this, AstSystemType system, -* const char *method, int *status ) - -* Class Membership: -* SkyFrame member function (over-rides the astValidateSystem method -* inherited from the Frame class). - -* Description: -* This function checks the validity of the supplied system value. -* If the value is valid, it is returned unchanged. Otherwise, an -* error is reported and a value of AST__BADSYSTEM is returned. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The system value to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The validated system value. - -* Notes: -* - A value of AST__BADSYSTEM will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Validated system value */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the value is out of bounds, report an error. */ - if ( system < FIRST_SYSTEM || system > LAST_SYSTEM ) { - astError( AST__AXIIN, "%s(%s): Bad value (%d) given for the System " - "or AlignSystem attribute of a %s.", status, method, - astGetClass( this ), (int) system, astGetClass( this ) ); - -/* Otherwise, return the supplied value. */ - } else { - result = system; - } - -/* Return the result. */ - return result; -} - -static void VerifyMSMAttrs( AstSkyFrame *target, AstSkyFrame *result, - int which, const char *attrs, const char *method, int *status ) { -/* -* Name: -* VerifyMSMAttrs - -* Purpose: -* Verify that usable attribute values are available. - -* Type: -* Private function. - -* Synopsis: -* #include "skyframe.h" -* void VerifyMSMAttrs( AstSkyFrame *target, AstSkyFrame *result, -* int which, const char *attrs, const char *method, int *status ) - -* Class Membership: -* SkyFrame member function - -* Description: -* This function tests each attribute listed in "attrs". It returns -* without action if 1) an explicit value has been set for each attribute -* in the SkyFrame indicated by "which" or 2) the UseDefs attribute of the -* "which" SkyFrame is non-zero. -* -* If UseDefs is zero (indicating that default values should not be -* used for attributes), and any of the named attributes does not have -* an explicitly set value, then an error is reported. -* -* The displayed error message assumes that tjis function was called -* as part of the process of producing a Mapping from "target" to "result". - -* Parameters: -* target -* Pointer to the target SkyFrame. -* result -* Pointer to the result SkyFrame. -* which -* If 2, both the target and result SkyFrames are checked for the -* supplied attributes. If less than 2, only the target SkyFrame is -* checked. If greater than 2, only the result SkyFrame is checked. -* attrs -* A string holding a space separated list of attribute names. -* method -* A string holding the name of the calling method for use in error -* messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - const char *a; - const char *p; - const char *desc; - int len; - int set1; - int set2; - int state; - int usedef1; - int usedef2; - -/* Check inherited status */ - if( !astOK ) return; - -/* Get the UseDefs attributes of the two SkyFrames. */ - usedef1 = astGetUseDefs( target ); - usedef2 = astGetUseDefs( result ); - -/* If both SkyFrames have a non-zero value for its UseDefs attribute, then - all attributes are assumed to have usable values, since the defaults - will be used if no explicit value has been set. So we only need to do - any checks if UseDefs is zero for either SkyFrame. */ - if( !usedef1 || !usedef2 ) { - -/* Stop compiler warnings about uninitialised variables */ - a = NULL; - desc = NULL; - len = 0; - set1 = 0; - set2 = 0; - -/* Loop round the "attrs" string identifying the start and length of each - non-blank word in the string. */ - state = 0; - p = attrs; - while( 1 ) { - if( state == 0 ) { - if( !isspace( *p ) ) { - a = p; - len = 1; - state = 1; - } - } else { - if( isspace( *p ) || !*p ) { - -/* The end of a word has just been reached. Compare it to each known - attribute value. Get a flag indicating if the attribute has a set - value, and a string describing the attribute.*/ - if( len > 0 ) { - - if( !strncmp( "Equinox", a, len ) ) { - set1 = astTestEquinox( target ); - set2 = astTestEquinox( result ); - desc = "reference equinox"; - - } else if( !strncmp( "Dtai", a, len ) ) { - set1 = astTestDtai( target ); - set2 = astTestDtai( result ); - desc = "TAI-UTC correction"; - - } else if( !strncmp( "Dut1", a, len ) ) { - set1 = astTestDut1( target ); - set2 = astTestDut1( result ); - desc = "UT1-UTC correction"; - - } else if( !strncmp( "Epoch", a, len ) ) { - set1 = astTestEpoch( target ); - set2 = astTestEpoch( result ); - desc = "epoch of observation"; - - } else if( !strncmp( "ObsLon", a, len ) ) { - set1 = astTestObsLon( target ); - set2 = astTestObsLon( result ); - desc = "longitude of observer"; - - } else if( !strncmp( "ObsLat", a, len ) ) { - set1 = astTestObsLat( target ); - set2 = astTestObsLat( result ); - desc = "latitude of observer"; - - } else if( !strncmp( "ObsAlt", a, len ) ) { - set1 = astTestObsAlt( target ); - set2 = astTestObsAlt( result ); - desc = "altitude of observer"; - - } else { - astError( AST__INTER, "VerifyMSMAttrs(SkyFrame): " - "Unknown attribute name \"%.*s\" supplied (AST " - "internal programming error).", status, len, a ); - } - -/* If the attribute is not set in the target but should be, report an - error. */ - if( !usedef1 && !set1 && which < 3 ) { - astClearTitle( target ); - astClearTitle( result ); - astError( AST__NOVAL, "%s(%s): Cannot convert " - "celestial coordinates from %s to %s.", status, - method, astGetClass( target ), - astGetC( target, "Title" ), - astGetC( result, "Title" ) ); - astError( AST__NOVAL, "No value has been set for " - "the \"%.*s\" attribute (%s) in the input %s.", status, - len, a, desc, astGetClass( target ) ); - break; - } - -/* If the attribute is not set in the result but should be, report an - error. */ - if( !usedef2 && !set2 && which > 1 ) { - astClearTitle( target ); - astClearTitle( result ); - astError( AST__NOVAL, "%s(%s): Cannot convert " - "celestial coordinates from %s to %s.", status, - method, astGetClass( result ), - astGetC( target, "Title" ), - astGetC( result, "Title" ) ); - astError( AST__NOVAL, "No value has been set for " - "the \"%.*s\" attribute (%s) in the output %s.", status, - len, a, desc, astGetClass( result ) ); - break; - } - -/* Continue the word search algorithm. */ - } - len = 0; - state = 0; - } else { - len++; - } - } - if( !*(p++) ) break; - } - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* -*att++ -* Name: -* AlignOffset - -* Purpose: -* Align SkyFrames using the offset coordinate system? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which controls how a SkyFrame -* behaves when it is used (by -c astFindFrame or astConvert) as a template to match another (target) -f AST_FINDFRAME or AST_CONVERT) as a template to match another (target) -* SkyFrame. It determines the coordinate system in which the two -* SkyFrames are aligned if a match occurs. -* -* If the template and target SkyFrames both have defined offset coordinate -* systems (i.e. the SkyRefIs attribute is set to either "Origin" or " -* Pole"), and they both have a non-zero value for AlignOffset, then -* alignment occurs within the offset coordinate systems (that is, a -* UnitMap will always be used to align the two SkyFrames). If either -* the template or target SkyFrame has zero (the default value) for -* AlignOffset, or if either SkyFrame has SkyRefIs set to "Ignored", then -* alignment occurring within the coordinate system specified by the -* AlignSystem attribute. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. -*att-- -*/ -astMAKE_CLEAR(SkyFrame,AlignOffset,alignoffset,-INT_MAX) -astMAKE_GET(SkyFrame,AlignOffset,int,0,( ( this->alignoffset != -INT_MAX ) ? - this->alignoffset : 0 )) -astMAKE_SET(SkyFrame,AlignOffset,int,alignoffset,( value != 0 )) -astMAKE_TEST(SkyFrame,AlignOffset,( this->alignoffset != -INT_MAX )) - -/* -*att++ -* Name: -* AsTime(axis) - -* Purpose: -* Format celestal coordinates as times? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute specifies the default style of formatting to be -c used (e.g. by astFormat) for the celestial coordinate values -f used (e.g. by AST_FORMAT) for the celestial coordinate values -* described by a SkyFrame. It takes a separate boolean value for -* each SkyFrame axis so that, for instance, the setting -* "AsTime(2)=0" specifies the default formatting style for -* celestial latitude values. -* -* If the AsTime attribute for a SkyFrame axis is zero, then -* coordinates on that axis will be formatted as angles by default -* (using degrees, minutes and seconds), otherwise they will be -* formatted as times (using hours, minutes and seconds). -* -* The default value of AsTime is chosen according to the sky -* coordinate system being represented, as determined by the -* SkyFrame's System attribute. This ensures, for example, that -* right ascension values will be formatted as times by default, -* following normal conventions. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. - -* Notes: -* - The AsTime attribute operates by changing the default value of -* the corresponding Format(axis) attribute. This, in turn, may -* also affect the value of the Unit(axis) attribute. -* - Only the default style of formatting is affected by the AsTime -* value. If an explicit Format(axis) value is set, it will -* over-ride any effect from the AsTime attribute. -*att-- -*/ - -/* -*att++ -* Name: -* Equinox - -* Purpose: -* Epoch of the mean equinox. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute is used to qualify those celestial coordinate -* systems described by a SkyFrame which are notionally based on -* the ecliptic (the plane of the Earth's orbit around the Sun) -* and/or the Earth's equator. -* -* Both of these planes are in motion and their positions are -* difficult to specify precisely. In practice, therefore, a model -* ecliptic and/or equator are used instead. These, together with -* the point on the sky that defines the coordinate origin (the -* intersection of the two planes termed the "mean equinox") move -* with time according to some model which removes the more rapid -* fluctuations. The SkyFrame class supports both the FK4 and -* FK5 models. -* -* The position of a fixed source expressed in any of these -* coordinate systems will appear to change with time due to -* movement of the coordinate system itself (rather than motion of -* the source). Such coordinate systems must therefore be -* qualified by a moment in time (the "epoch of the mean equinox" -* or "equinox" for short) which allows the position of the model -* coordinate system on the sky to be determined. This is the role -* of the Equinox attribute. -* -* The Equinox attribute is stored as a Modified Julian Date, but -* when setting or getting its value you may use the same formats -* as for the Epoch attribute (q.v.). -* -* The default Equinox value is B1950.0 (Besselian) for the old -* FK4-based coordinate systems (see the System attribute) and -* J2000.0 (Julian) for all others. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. - -* Notes: -* - Care must be taken to distinguish the Equinox value, which -* relates to the definition of a time-dependent coordinate system -* (based on solar system reference planes which are in motion), -* from the superficially similar Epoch value. The latter is used -* to qualify coordinate systems where the positions of sources -* change with time (or appear to do so) for a variety of other -* reasons, such as aberration of light caused by the observer's -* motion, etc. -* - See the description of the System attribute for details of -* which qualifying attributes apply to each celestial coordinate -* system. -*att-- -*/ -/* Clear the Equinox value by setting it to AST__BAD. */ -astMAKE_CLEAR(SkyFrame,Equinox,equinox,AST__BAD) - -/* Provide a default value of B1950.0 or J2000.0 depending on the System - setting. */ -astMAKE_GET(SkyFrame,Equinox,double,AST__BAD,( - ( this->equinox != AST__BAD ) ? this->equinox : - ( ( ( astGetSystem( this ) == AST__FK4 ) || - ( astGetSystem( this ) == AST__FK4_NO_E ) ) ? - palEpb2d( 1950.0 ) : palEpj2d( 2000.0 ) ) )) - -/* Allow any Equinox value to be set, unless the System is Helio-ecliptic - (in which case clear the value so that J2000 is used). */ -astMAKE_SET(SkyFrame,Equinox,double,equinox,((astGetSystem(this)!=AST__HELIOECLIPTIC)?value:AST__BAD)) - -/* An Equinox value is set if it is not equal to AST__BAD. */ -astMAKE_TEST(SkyFrame,Equinox,( this->equinox != AST__BAD )) - - -/* -*att++ -* Name: -* IsLatAxis(axis) - -* Purpose: -* Is the specified celestial axis a latitude axis? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean), read-only. - -* Description: -* This is a read-only boolean attribute that indicates the nature of -* the specified axis. The attribute has a non-zero value if the -* specified axis is a celestial latitude axis (Declination, Galactic -* latitude, etc), and is zero otherwise. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. - -* Notes: -* - When specifying this attribute by name, it should be -* subscripted with the number of the SkyFrame axis to be tested. -*att-- -*/ - -/* -*att++ -* Name: -* IsLonAxis(axis) - -* Purpose: -* Is the specified celestial axis a longitude axis? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean), read-only. - -* Description: -* This is a read-only boolean attribute that indicates the nature of -* the specified axis. The attribute has a non-zero value if the -* specified axis is a celestial longitude axis (Right Ascension, Galactic -* longitude, etc), and is zero otherwise. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. - -* Notes: -* - When specifying this attribute by name, it should be -* subscripted with the number of the SkyFrame axis to be tested. -*att-- -*/ - -/* -*att++ -* Name: -* LatAxis - -* Purpose: -* Index of the latitude axis. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This read-only attribute gives the index (1 or 2) of the latitude -* axis within the SkyFrame (taking into account any current axis -* permutations). - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. - -*att-- -*/ - -/* -*att++ -* Name: -* LonAxis - -* Purpose: -* Index of the longitude axis. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This read-only attribute gives the index (1 or 2) of the longitude -* axis within the SkyFrame (taking into account any current axis -* permutations). - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. - -*att-- -*/ - -/* -*att++ -* Name: -* NegLon - -* Purpose: -* Display negative longitude values? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which controls how longitude values -c are normalized for display by astNorm. -f are normalized for display by AST_NORM. -* -* If the NegLon attribute is zero, then normalized -* longitude values will be in the range zero to 2.pi. If NegLon is -* non-zero, then normalized longitude values will be in the range -pi -* to pi. -* -* The default value depends on the current value of the SkyRefIs -* attribute, If SkyRefIs has a value of "Origin", then the default for -* NegLon is one, otherwise the default is zero. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. -*att-- -*/ -/* Clear the NegLon value by setting it to -INT_MAX. */ -astMAKE_CLEAR(SkyFrame,NegLon,neglon,-INT_MAX) - -/* Supply a default of 0 for absolute coords and 1 for offset coords if - no NegLon value has been set. */ -astMAKE_GET(SkyFrame,NegLon,int,0,( ( this->neglon != -INT_MAX ) ? -this->neglon : (( astGetSkyRefIs( this ) == AST__ORIGIN_REF )? 1 : 0))) - -/* Set a NegLon value of 1 if any non-zero value is supplied. */ -astMAKE_SET(SkyFrame,NegLon,int,neglon,( value != 0 )) - -/* The NegLon value is set if it is not -INT_MAX. */ -astMAKE_TEST(SkyFrame,NegLon,( this->neglon != -INT_MAX )) - -/* -*att++ -* Name: -* SkyTol - -* Purpose: -* The smallest significant shift in sky coordinates. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute indicates the accuracy of the axis values that will -* be represented by the SkyFrame. If the arc-distance between two -* positions within the SkyFrame is smaller than the value of SkyTol, -* then the two positions will (for the puposes indicated below) be -* considered to be co-incident. -* -* This value is used only when constructing the Mapping between -* two different SkyFrames (for instance, when calling -c astConvert or astFindFrame). -f AST_CONVERT or AST_FINDFRAME). -* If the transformation between the two SkyFrames causes positions to -* shift by less than SkyTol arc-seconds, then the transformation is -* replaced by a UnitMap. This could in certain circumatances allow -* major simplifications to be made to the transformation between -* any pixel grids associated with the two SkyFrames (for instance, if -* each SkyFrame is part of the WCS FrameSet associated with an image). -* -* A common case is when two SkyFrames use the FK5 system, but have -* slightly different Epoch values. If the AlignSystem attribute has -* its default value of "ICRS", then the transformation between the -* two SkyFrames will include a very small rotation (FK5 rotates with -* respect to ICRS as a rate of about 0.0005 arc-seconds per year). In -* most circumstances such a small rotation is insignificant. Setting -* SkyTol to some suitably small non-zero value will cause this -* rotation to be ignored, allowing much simpler transformations to -* be used. -* -* The test to determine the shift introduced by transforming between -* the two SkyFrames is performed by transforming a set of 14 position -* spread evenly over the whole sky. The largest shift produced at any -* of these 14 positions is compared to the value of SkyTol. -* -* The SkyTol value is in units of arc-seconds, and the default value -* is 0.001. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. -*att-- -*/ -astMAKE_CLEAR(SkyFrame,SkyTol,skytol,AST__BAD) -astMAKE_GET(SkyFrame,SkyTol,double,0.001,((this->skytol!=AST__BAD)?this->skytol:0.001)) -astMAKE_SET(SkyFrame,SkyTol,double,skytol,fabs(value)) -astMAKE_TEST(SkyFrame,SkyTol,(this->skytol!=AST__BAD)) - -/* -*att++ -* Name: -* Projection - -* Purpose: -* Sky projection description. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute provides a place to store a description of the -* type of sky projection used when a SkyFrame is attached to a -* 2-dimensional object, such as an image or plotting surface. For -* example, typical values might be "orthographic", "Hammer-Aitoff" -* or "cylindrical equal area". -* -* The Projection value is purely descriptive and does not affect -* the celestial coordinate system represented by the SkyFrame in -* any way. If it is set to a non-blank string, the description -* provided may be used when forming the default value for the -* SkyFrame's Title attribute (so that typically it will appear in -* graphical output, for instance). The default value is an empty -* string. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. -*att-- -*/ -/* Clear the Projection value by freeing the allocated memory and - assigning a NULL pointer. */ -astMAKE_CLEAR(SkyFrame,Projection,projection,astFree( this->projection )) - -/* If the Projection value is not set, return a pointer to an empty - string. */ -astMAKE_GET(SkyFrame,Projection,const char *,NULL,( this->projection ? - this->projection : "" )) - -/* Set a Projection value by freeing any previously allocated memory, - allocating new memory, storing the string and saving the pointer to - the copy. */ -astMAKE_SET(SkyFrame,Projection,const char *,projection,astStore( - this->projection, value, strlen( value ) + (size_t) 1 )) - -/* The Projection value is set if the pointer to it is not NULL. */ -astMAKE_TEST(SkyFrame,Projection,( this->projection != NULL )) - -/* -*att++ -* Name: -* SkyRefIs - -* Purpose: -* Selects the nature of the offset coordinate system. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls how the values supplied for the SkyRef and -* SkyRefP attributes are used. These three attributes together allow -* a SkyFrame to represent offsets relative to some specified origin -* or pole within the coordinate system specified by the System attribute, -* rather than absolute axis values. SkyRefIs can take one of the -* case-insensitive values "Origin", "Pole" or "Ignored". -* -* If SkyRefIs is set to "Origin", then the coordinate system -* represented by the SkyFrame is modified to put the origin of longitude -* and latitude at the position specified by the SkyRef attribute. -* -* If SkyRefIs is set to "Pole", then the coordinate system represented -* by the SkyFrame is modified to put the north pole at the position -* specified by the SkyRef attribute. -* -* If SkyRefIs is set to "Ignored" (the default), then any value set for the -* SkyRef attribute is ignored, and the SkyFrame represents the coordinate -* system specified by the System attribute directly without any rotation. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. - -*att-- -*/ -astMAKE_CLEAR(SkyFrame,SkyRefIs,skyrefis,AST__BAD_REF) -astMAKE_SET(SkyFrame,SkyRefIs,int,skyrefis,value) -astMAKE_TEST(SkyFrame,SkyRefIs,( this->skyrefis != AST__BAD_REF )) -astMAKE_GET(SkyFrame,SkyRefIs,int,AST__IGNORED_REF,(this->skyrefis == AST__BAD_REF ? AST__IGNORED_REF : this->skyrefis)) - -/* -*att++ -* Name: -* SkyRef(axis) - -* Purpose: -* Position defining the offset coordinate system. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute allows a SkyFrame to represent offsets, rather than -* absolute axis values, within the coordinate system specified by the -* System attribute. If supplied, SkyRef should be set to hold the -* longitude and latitude of a point within the coordinate system -* specified by the System attribute. The coordinate system represented -* by the SkyFrame will then be rotated in order to put the specified -* position at either the pole or the origin of the new coordinate system -* (as indicated by the SkyRefIs attribute). The orientation of the -* modified coordinate system is then controlled using the SkyRefP -* attribute. -* -* If an integer axis index is included in the attribute name (e.g. -* "SkyRef(1)") then the attribute value should be supplied as a single -* floating point axis value, in radians, when setting a value for the -* attribute, and will be returned in the same form when getting the value -* of the attribute. In this case the integer axis index should be "1" -* or "2" (the values to use for longitude and latitude axes are -* given by the LonAxis and LatAxis attributes). -* -* If no axis index is included in the attribute name (e.g. "SkyRef") then -* the attribute value should be supplied as a character string -* containing two formatted axis values (an axis 1 value followed by a -* comma, followed by an axis 2 value). The same form -* will be used when getting the value of the attribute. -* -* The default values for SkyRef are zero longitude and zero latitude. - -* Aligning SkyFrames with Offset Coordinate Systems: -* The offset coordinate system within a SkyFrame should normally be -* considered as a superficial "re-badging" of the axes of the coordinate -* system specified by the System attribute - it merely provides an -* alternative numerical "label" for each position in the System coordinate -* system. The SkyFrame retains full knowledge of the celestial coordinate -* system on which the offset coordinate system is based (given by the -* System attribute). For instance, the SkyFrame retains knowledge of the -* way that one celestial coordinate system may "drift" with respect to -* another over time. Normally, if you attempt to align two SkyFrames (e.g. -f using the AST_CONVERT or AST_FINDFRAME routine), -c using the astConvert or astFindFrame routine), -* the effect of any offset coordinate system defined in either SkyFrame -* will be removed, resulting in alignment being performed in the -* celestial coordinate system given by the AlignSystem attribute. -* However, by setting the AlignOffset attribute to a non-zero value, it -* is possible to change this behaviour so that the effect of the offset -* coordinate system is not removed when aligning two SkyFrames. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. - -* Notes: -* - If the System attribute of the SkyFrame is changed, any position -* given for SkyRef is transformed into the new System. -* - If a value has been assigned to SkyRef attribute, then -* the default values for certain attributes are changed as follows: -* the default axis Labels for the SkyFrame are modified by appending -* " offset" to the end, the default axis Symbols for the SkyFrame are -* modified by prepending the character "D" to the start, and the -* default title is modified by replacing the projection information by the -* origin information. - -*att-- -*/ -MAKE_CLEAR(SkyRef,skyref,AST__BAD,2) -MAKE_SET(SkyRef,double,skyref,value,2) -MAKE_TEST(SkyRef,( this->skyref[axis_p] != AST__BAD ),2) -MAKE_GET(SkyRef,double,0.0,((this->skyref[axis_p]!=AST__BAD)?this->skyref[axis_p]:0.0),2) - -/* -*att++ -* Name: -* SkyRefP(axis) - -* Purpose: -* Position on primary meridian of offset coordinate system. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute is used to control the orientation of the offset -* coordinate system defined by attributes SkyRef and SkyRefIs. If used, -* it should be set to hold the longitude and latitude of a point within -* the coordinate system specified by the System attribute. The offset -* coordinate system represented by the SkyFrame will then be rotated in -* order to put the position supplied for SkyRefP on the zero longitude -* meridian. This rotation is about an axis from the centre of the -* celestial sphere to the point specified by the SkyRef attribute. -* The default value for SkyRefP is usually the north pole (that is, a -* latitude of +90 degrees in the coordinate system specified by the System -* attribute). The exception to this is if the SkyRef attribute is -* itself set to either the north or south pole. In these cases the -* default for SkyRefP is the origin (that is, a (0,0) in the coordinate -* system specified by the System attribute). -* -* If an integer axis index is included in the attribute name (e.g. -* "SkyRefP(1)") then the attribute value should be supplied as a single -* floating point axis value, in radians, when setting a value for the -* attribute, and will be returned in the same form when getting the value -* of the attribute. In this case the integer axis index should be "1" -* or "2" (the values to use for longitude and latitude axes are -* given by the LonAxis and LatAxis attributes). -* -* If no axis index is included in the attribute name (e.g. "SkyRefP") then -* the attribute value should be supplied as a character string -* containing two formatted axis values (an axis 1 value followed by a -* comma, followed by an axis 2 value). The same form -* will be used when getting the value of the attribute. - -* Applicability: -* SkyFrame -* All SkyFrames have this attribute. - -* Notes: -* - If the position given by the SkyRef attribute defines the origin -* of the offset coordinate system (that is, if the SkyRefIs attribute -* is set to "origin"), then there will in general be two orientations -* which will put the supplied SkyRefP position on the zero longitude -* meridian. The orientation which is actually used is the one which -* gives the SkyRefP position a positive latitude in the offset coordinate -* system (the other possible orientation would give the SkyRefP position -* a negative latitude). -* - An error will be reported if an attempt is made to use a -* SkyRefP value which is co-incident with SkyRef or with the point -* diametrically opposite to SkyRef on the celestial sphere. The -* reporting of this error is deferred until the SkyRef and SkyRefP -* attribute values are used within a calculation. -* - If the System attribute of the SkyFrame is changed, any position -* given for SkyRefP is transformed into the new System. - -*att-- -*/ -MAKE_CLEAR(SkyRefP,skyrefp,AST__BAD,2) -MAKE_SET(SkyRefP,double,skyrefp,value,2) -MAKE_TEST(SkyRefP,( this->skyrefp[axis_p] != AST__BAD ),2) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for SkyFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for SkyFrame objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstSkyFrame *in; /* Pointer to input SkyFrame */ - AstSkyFrame *out; /* Pointer to output SkyFrame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output SkyFrames. */ - in = (AstSkyFrame *) objin; - out = (AstSkyFrame *) objout; - -/* For safety, first clear any references to the input memory from - the output SkyFrame. */ - out->projection = NULL; - -/* If necessary, allocate memory in the output SkyFrame and store a - copy of the input Projection string. */ - if ( in->projection ) out->projection = astStore( NULL, in->projection, - strlen( in->projection ) + (size_t) 1 ); - -/* If an error occurred, free any allocated memory. */ - if ( !astOK ) { - out->projection = astFree( out->projection ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for SkyFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for SkyFrame objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to SkyFrame */ - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) obj; - -/* Free the memory used for the Projection string if necessary. */ - this->projection = astFree( this->projection ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SkyFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the SkyFrame class to an output Channel. - -* Parameters: -* this -* Pointer to the SkyFrame whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSkyFrame *this; /* Pointer to the SkyFrame structure */ - AstSystemType system; /* System attribute value */ - char buf[ 100 ]; /* Comment buffer */ - char key[ 10 ]; /* Buffer for keywords */ - const char *sval; /* Pointer to string value */ - const int *perm; /* Pointer to axis permutation array */ - double dval; /* Double value */ - int bessyr; /* Use a Besselian year value ?*/ - int helpful; /* Helpful to display un-set value? */ - int invperm[ 2 ]; /* Inverse permutation array */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - int axis; /* External (i.e. permuted) zero-based axis index */ - int axis_p; /* Internal zero-based axis index */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SkyFrame structure. */ - this = (AstSkyFrame *) this_object; - -/* Get a pointer to the SkyFrame's axis permutation array (using a method, - to allow for any over-ride by a derived class). */ - perm = astGetPerm( this ); - -/* Generate an inverse axis permutation array from the forward permutation - values. This will be used to determine which axis should be enquired - about (using possibly over-ridden methods) to obtain data to - correspond with a particular internal value (i.e. instance variable) - relating to an axis. This step is needed so that the effect of any - axis permutation can be un-done before values are written out, as - output values are written by this function in un-permuted order. */ - for ( axis = 0; axis < 2; axis++ ) invperm[ perm[ axis ] ] = axis; - -/* Write out values representing the instance variables for the - SkyFrame class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Projection. */ -/* ----------- */ - set = TestProjection( this, status ); - sval = set ? GetProjection( this, status ) : astGetProjection( this ); - astWriteString( channel, "Proj", set, 0, sval, - "Description of sky projection" ); - -/* NegLon. */ -/* ------- */ - set = TestNegLon( this, status ); - ival = set ? GetNegLon( this, status ) : astGetNegLon( this ); - astWriteInt( channel, "NegLon", set, 0, ival, - ival ? "Display negative longitude values" : - "Display positive longitude values" ); - -/* SkyTol. */ -/* ------- */ - set = TestSkyTol( this, status ); - dval = set ? GetSkyTol( this, status ) : astGetSkyTol( this ); - astWriteDouble( channel, "SkyTol", set, 1, dval, - "Smallest significant separation [arc-sec]"); - -/* Equinox. */ -/* -------- */ - set = TestEquinox( this, status ); - dval = set ? GetEquinox( this, status ) : astGetEquinox( this ); - -/* Decide whether the Equinox value is relevant to the current - coordinate system. */ - system = astGetSystem( this ); - helpful = ( ( system == AST__FK4 ) || - ( system == AST__FK4_NO_E ) || - ( system == AST__FK5 ) || - ( system == AST__ECLIPTIC ) ); - -/* Convert MJD to Besselian or Julian years, depending on the value. */ - bessyr = ( dval < palEpj2d( 1984.0 ) ); - dval = bessyr ? palEpb( dval ) : palEpj( dval ); - astWriteDouble( channel, "Eqnox", set, helpful, dval, - bessyr ? "Besselian epoch of mean equinox" : - "Julian epoch of mean equinox" ); - -/* SkyRefIs. */ -/* --------- */ - set = TestSkyRefIs( this, status ); - ival = set ? GetSkyRefIs( this, status ) : astGetSkyRefIs( this ); - if( ival == AST__POLE_REF ) { - astWriteString( channel, "SRefIs", set, 0, POLE_STRING, - "Rotated to put pole at ref. pos." ); - - } else if( ival == AST__IGNORED_REF ) { - astWriteString( channel, "SRefIs", set, 0, IGNORED_STRING, - "Not rotated (ref. pos. is ignored)" ); - - } else { - astWriteString( channel, "SRefIs", set, 0, ORIGIN_STRING, - "Rotated to put origin at ref. pos." ); - } - -/* SkyRef. */ -/* ------- */ -/* The inverse axis permutation array is used to obtain the axis index - to use when accessing the SkyRef attribute. This reverses the effect - of the SkyFrame's axis permutation array and yields a value appropriate - to the axis with internal index "axis". */ - for ( axis_p = 0; axis_p < 2; axis_p++ ) { - axis = invperm[ axis_p ]; - - set = TestSkyRef( this, axis, status ); - dval = set ? GetSkyRef( this, axis, status ) : astGetSkyRef( this, axis ); - sprintf( buf, "Ref. pos. %s %s", astGetSymbol( this, axis ), - astFormat( this, axis, dval ) ); - sprintf( key, "SRef%d", axis_p + 1 ); - astWriteDouble( channel, key, set, 0, dval, buf ); - } - -/* SkyRefP. */ -/* -------- */ - for ( axis_p = 0; axis_p < 2; axis_p++ ) { - axis = invperm[ axis_p ]; - - set = TestSkyRefP( this, axis, status ); - dval = set ? GetSkyRefP( this, axis, status ) : astGetSkyRefP( this, axis ); - sprintf( buf, "Ref. north %s %s", astGetSymbol( this, axis ), - astFormat( this, axis, dval ) ); - sprintf( key, "SRefP%d", axis_p + 1 ); - astWriteDouble( channel, key, set, 0, dval, buf ); - } - -/* AlignOffset. */ -/* ------------ */ - set = TestAlignOffset( this, status ); - ival = set ? GetAlignOffset( this, status ) : astGetAlignOffset( this ); - astWriteInt( channel, "AlOff", set, 0, ival, - ival ? "Align in offset coords" : - "Align in system coords" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASkyFrame and astCheckSkyFrame functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SkyFrame,Frame) -astMAKE_CHECK(SkyFrame) - -AstSkyFrame *astSkyFrame_( const char *options, int *status, ...) { -/* -*+ -* Name: -* astSkyFrame - -* Purpose: -* Create a SkyFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "skyframe.h" -* AstSkyFrame *astSkyFrame( const char *options, int *status, ... ) - -* Class Membership: -* SkyFrame constructor. - -* Description: -* This function creates a new SkyFrame and optionally initialises its -* attributes. - -* Parameters: -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new SkyFrame. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new SkyFrame. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic SkyFrame constructor which -* is available via the protected interface to the SkyFrame class. -* A public interface is provided by the astSkyFrameId_ function. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSkyFrame *new; /* Pointer to new SkyFrame */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SkyFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSkyFrame( NULL, sizeof( AstSkyFrame ), !class_init, &class_vtab, - "SkyFrame" ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SkyFrame's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new SkyFrame. */ - return new; -} - -AstSkyFrame *astInitSkyFrame_( void *mem, size_t size, int init, - AstSkyFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSkyFrame - -* Purpose: -* Initialise a SkyFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "skyframe.h" -* AstSkyFrame *astInitSkyFrame( void *mem, size_t size, int init, -* AstFrameVtab *vtab, const char *name ) - -* Class Membership: -* SkyFrame initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new SkyFrame object. It allocates memory (if necessary) to accommodate -* the SkyFrame plus any additional data associated with the derived class. -* It then initialises a SkyFrame structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a SkyFrame at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SkyFrame is to be created. This -* must be of sufficient size to accommodate the SkyFrame data -* (sizeof(SkyFrame)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the SkyFrame (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the SkyFrame -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the SkyFrame's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new SkyFrame. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). - -* Returned Value: -* A pointer to the new SkyFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstSkyAxis *ax; /* Pointer to SkyAxis object */ - AstSkyFrame *new; /* Pointer to the new SkyFrame */ - int axis; /* Loop counter for axes */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSkyFrameVtab( vtab, name ); - -/* Initialise a Frame structure (the parent class) as the first component - within the SkyFrame structure, allocating memory if necessary. */ - new = (AstSkyFrame *) astInitFrame( mem, size, 0, - (AstFrameVtab *) vtab, name, 2 ); - - if ( astOK ) { - -/* Initialise the SkyFrame data. */ -/* ----------------------------- */ -/* Initialise all attributes to their "undefined" values. */ - new->equinox = AST__BAD; - new->projection = NULL; - new->neglon = -INT_MAX; - new->skytol = AST__BAD; - new->alignoffset = -INT_MAX; - new->skyrefis = AST__BAD_REF; - new->skyref[ 0 ] = AST__BAD; - new->skyref[ 1 ] = AST__BAD; - new->skyrefp[ 0 ] = AST__BAD; - new->skyrefp[ 1 ] = AST__BAD; - new->last = AST__BAD; - new->eplast = AST__BAD; - new->klast = AST__BAD; - new->diurab = AST__BAD; - -/* Loop to replace the Axis object associated with each SkyFrame axis with - a SkyAxis object instead. */ - for ( axis = 0; axis < 2; axis++ ) { - -/* Create the new SkyAxis, assign it to the required SkyFrame axis and then - annul the SkyAxis pointer. */ - ax = astSkyAxis( "", status ); - astSetAxis( new, axis, ax ); - ax = astAnnul( ax ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstSkyFrame *astLoadSkyFrame_( void *mem, size_t size, - AstSkyFrameVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSkyFrame - -* Purpose: -* Load a SkyFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "skyframe.h" -* AstSkyFrame *astLoadSkyFrame( void *mem, size_t size, -* AstSkyFrameVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* SkyFrame loader. - -* Description: -* This function is provided to load a new SkyFrame using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* SkyFrame structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the SkyFrame is to be -* loaded. This must be of sufficient size to accommodate the -* SkyFrame data (sizeof(SkyFrame)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SkyFrame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SkyFrame structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstSkyFrame) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SkyFrame. If this is NULL, a pointer -* to the (static) virtual function table for the SkyFrame class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "SkyFrame" is used instead. - -* Returned Value: -* A pointer to the new SkyFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstSkyFrame *new; /* Pointer to the new SkyFrame */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char *sval; /* Pointer to string value */ - const int *perm; /* Pointer to axis permutation array */ - double dval; /* Floating point attribute value */ - int axis; /* External axis index */ - int invperm[ 2 ]; /* Inverse permutation array */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SkyFrame. In this case the - SkyFrame belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSkyFrame ); - vtab = &class_vtab; - name = "SkyFrame"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSkyFrameVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built SkyFrame. */ - new = astLoadFrame( mem, size, (AstFrameVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Get a pointer to the SkyFrame's axis permutation array (using a method, - to allow for any over-ride by a derived class). */ - perm = astGetPerm( new ); - -/* Generate an inverse axis permutation array from the forward permutation - values. This will be used to determine which axis should be enquired - about (using possibly over-ridden methods) to obtain data to - correspond with a particular internal value (i.e. instance variable) - relating to an axis. This step is needed so that the effect of any - axis permutation can be un-done before values are written out, as - output values are written by this function in un-permuted order. */ - for( axis = 0; axis < 2; axis++ ) invperm[ perm[ axis ] ] = axis; - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "SkyFrame" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* The attributes defining the offset coordinate system must be loaded - before the System attrivbute, since SetSystem uses them. */ - -/* AlignOffset */ -/* ----------- */ - new->alignoffset = astReadInt( channel, "aloff", -INT_MAX ); - if ( TestAlignOffset( new, status ) ) SetAlignOffset( new, new->alignoffset, status ); - -/* SkyRefIs. */ -/* --------- */ - sval = astReadString( channel, "srefis", " " ); - if( sval ){ - new->skyrefis = AST__BAD_REF; - if( astChrMatch( sval, POLE_STRING ) ) { - new->skyrefis = AST__POLE_REF; - } else if( astChrMatch( sval, ORIGIN_STRING ) ) { - new->skyrefis = AST__ORIGIN_REF; - } else if( astChrMatch( sval, IGNORED_STRING ) ) { - new->skyrefis = AST__IGNORED_REF; - } else if( !astChrMatch( sval, " " ) && astOK ){ - astError( AST__INTER, "astRead(SkyFrame): Corrupt SkyFrame contains " - "invalid SkyRefIs attribute value (%s).", status, sval ); - } - if( TestSkyRefIs( new, status ) ) SetSkyRefIs( new, new->skyrefis, status ); - sval = astFree( sval ); - } - -/* SkyRef. */ -/* ------- */ - new->skyref[ 0 ] = astReadDouble( channel, "sref1", AST__BAD ); - axis = invperm[ 0 ]; - if ( TestSkyRef( new, axis, status ) ) SetSkyRef( new, axis, new->skyref[ 0 ], status ); - - new->skyref[ 1 ] = astReadDouble( channel, "sref2", AST__BAD ); - axis = invperm[ 1 ]; - if ( TestSkyRef( new, axis, status ) ) SetSkyRef( new, axis, new->skyref[ 1 ], status ); - -/* SkyRefP. */ -/* -------- */ - new->skyrefp[ 0 ] = astReadDouble( channel, "srefp1", AST__BAD ); - axis = invperm[ 0 ]; - if ( TestSkyRefP( new, axis, status ) ) SetSkyRefP( new, axis, new->skyrefp[ 0 ], status ); - - new->skyrefp[ 1 ] = astReadDouble( channel, "srefp2", AST__BAD ); - axis = invperm[ 1 ]; - if ( TestSkyRefP( new, axis, status ) ) SetSkyRefP( new, axis, new->skyrefp[ 1 ], status ); - -/* System. */ -/* ------- */ -/* The System attribute is now part of the Frame class, but this code is - retained to allow this version of AST to read SkyFrames dumped by - previous versions. */ - -/* Check a value has not already been assigned to the Frames System - attribute. */ - if( !astTestSystem( new ) ){ - -/* Read the external representation as a string. */ - sval = astReadString( channel, "system", NULL ); - -/* If a value was read, use the SetAttrib method to validate and store the - new value in the correct place, then free the string. */ - if ( sval ) { - astSet( new, "System=%s", status, sval); - sval = astFree( sval ); - } - } - -/* Epoch. */ -/* ------ */ -/* The Epoch attribute is now part of the Frame class, but this code is - retained to allow this version of AST to read SkyFrames dumped by - previous versions. */ - -/* Check a value has not already been assigned to the Frames Epoch - attribute. */ - if( !astTestEpoch( new ) ){ - -/* Get the value. */ - dval = astReadDouble( channel, "epoch", AST__BAD ); - -/* If a value was read, use the SetAttrib method to validate and store the - new value in the correct place. */ - if( dval != AST__BAD ) { - if( dval < 1984.0 ) { - astSet( new, "Epoch=B%.*g", status, AST__DBL_DIG, dval); - } else { - astSet( new, "Epoch=J%.*g", status, AST__DBL_DIG, dval); - } - } - } - -/* Projection. */ -/* ----------- */ - new->projection = astReadString( channel, "proj", NULL ); - -/* Equinox. */ -/* -------- */ -/* Interpret this as Besselian or Julian depending on its value. */ - new->equinox = astReadDouble( channel, "eqnox", AST__BAD ); - if ( TestEquinox( new, status ) ) { - SetEquinox( new, ( new->equinox < 1984.0 ) ? palEpb2d( new->equinox ) : - palEpj2d( new->equinox ), status ); - } - -/* NegLon. */ -/* ------- */ - new->neglon = astReadInt( channel, "neglon", -INT_MAX ); - if ( TestNegLon( new, status ) ) SetNegLon( new, new->neglon, status ); - -/* SkyTol. */ -/* ------- */ - new->skytol = astReadDouble( channel, "skytol", AST__BAD ); - if ( TestSkyTol( new, status ) ) SetSkyTol( new, new->skytol, status ); - -/* Other values */ -/* ------------ */ - new->last = AST__BAD; - new->eplast = AST__BAD; - new->klast = AST__BAD; - new->diurab = AST__BAD; - -/* If an error occurred, clean up by deleting the new SkyFrame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new SkyFrame pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -void astClearAsTime_( AstSkyFrame *this, int axis, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,SkyFrame,ClearAsTime))( this, axis, status ); -} -int astGetAsTime_( AstSkyFrame *this, int axis, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,SkyFrame,GetAsTime))( this, axis, status ); -} -void astSetAsTime_( AstSkyFrame *this, int axis, int value, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,SkyFrame,SetAsTime))( this, axis, value, status ); -} -int astTestAsTime_( AstSkyFrame *this, int axis, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,SkyFrame,TestAsTime))( this, axis, status ); -} -int astGetIsLatAxis_( AstSkyFrame *this, int axis, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,SkyFrame,GetIsLatAxis))( this, axis, status ); -} -int astGetIsLonAxis_( AstSkyFrame *this, int axis, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,SkyFrame,GetIsLonAxis))( this, axis, status ); -} -int astGetLatAxis_( AstSkyFrame *this, int *status ) { - if ( !astOK ) return 1; - return (**astMEMBER(this,SkyFrame,GetLatAxis))( this, status ); -} -int astGetLonAxis_( AstSkyFrame *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,SkyFrame,GetLonAxis))( this, status ); -} -double astGetSkyRefP_( AstSkyFrame *this, int axis, int *status ) { - if ( !astOK ) return 0.0; - return (**astMEMBER(this,SkyFrame,GetSkyRefP))( this, axis, status ); -} -AstMapping *astSkyOffsetMap_( AstSkyFrame *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,SkyFrame,SkyOffsetMap))( this, status ); -} - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSkyFrame *astSkyFrameId_( const char *, ... ); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstSkyFrame *astSkyFrameId_( const char *options, ... ) { -/* -*++ -* Name: -c astSkyFrame -f AST_SKYFRAME - -* Purpose: -* Create a SkyFrame. - -* Type: -* Public function. - -* Synopsis: -c #include "skyframe.h" -c AstSkyFrame *astSkyFrame( const char *options, ... ) -f RESULT = AST_SKYFRAME( OPTIONS, STATUS ) - -* Class Membership: -* SkyFrame constructor. - -* Description: -* This function creates a new SkyFrame and optionally initialises -* its attributes. -* -* A SkyFrame is a specialised form of Frame which describes -* celestial longitude/latitude coordinate systems. The particular -* celestial coordinate system to be represented is specified by -* setting the SkyFrame's System attribute (currently, the default -* is ICRS) qualified, as necessary, by a mean Equinox value and/or -* an Epoch. -* -* For each of the supported celestial coordinate systems, a SkyFrame -* can apply an optional shift of origin to create a coordinate system -* representing offsets within the celestial coordinate system from some -* specified point. This offset coordinate system can also be rotated to -* define new longitude and latitude axes. See attributes SkyRef, SkyRefIs -* and SkyRefP -* -* All the coordinate values used by a SkyFrame are in -* radians. These may be formatted in more conventional ways for -c display by using astFormat. -f display by using AST_FORMAT. - -* Parameters: -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new SkyFrame. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new SkyFrame. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSkyFrame() -f AST_SKYFRAME = INTEGER -* A pointer to the new SkyFrame. - -* Examples: -c frame = astSkyFrame( "" ); -c Creates a SkyFrame to describe the default ICRS celestial -c coordinate system. -c frame = astSkyFrame( "System = FK5, Equinox = J2005, Digits = 10" ); -c Creates a SkyFrame to describe the FK5 celestial -c coordinate system, with a mean Equinox of J2005.0. -c Because especially accurate coordinates will be used, -c additional precision (10 digits) has been requested. This will -c be used when coordinate values are formatted for display. -c frame = astSkyFrame( "System = FK4, Equinox = 1955-sep-2" ); -c Creates a SkyFrame to describe the old FK4 celestial -c coordinate system. A default Epoch value (B1950.0) is used, -c but the mean Equinox value is given explicitly as "1955-sep-2". -c frame = astSkyFrame( "System = GAPPT, Epoch = %s", date ); -c Creates a SkyFrame to describe the Geocentric Apparent -c celestial coordinate system. The Epoch value, which specifies -c the date of observation, is obtained from a date/time string -c supplied via the string pointer "date". -f FRAME = AST_SKYFRAME( ' ', STATUS ) -f Creates a SkyFrame to describe the default ICRS celestial -f coordinate system. -f FRAME = AST_SKYFRAME( 'System = FK5, Equinox = J2005, Digits = 10', STATUS ) -f Creates a SkyFrame to describe the FK5 celestial -f coordinate system, with a mean Equinox of J2005.0. -f Because especially accurate coordinates will be used, -f additional precision (10 digits) has been requested. This will -f be used when coordinate values are formatted for display. -f FRAME = AST_SKYFRAME( 'System = FK4, Equinox = 1955-SEP-2', STATUS ) -f Creates a SkyFrame to describe the old FK4 celestial -f coordinate system. A default Epoch value (B1950.0) is used, -f but the mean Equinox value is given explicitly as "1955-SEP-2". -f FRAME = AST_SKYFRAME( 'System = GAPPT, Epoch = ' // DATE, STATUS ) -f Creates a SkyFrame to describe the Geocentric Apparent -f celestial coordinate system. The Epoch value, which specifies -f the date of observation, is obtained from a date/time string -f contained in the character variable DATE. - -* Notes: -* - Currently, the default celestial coordinate system is -* ICRS. However, this default may change in future as new -* astrometric standards evolve. The intention is to track the most -* modern appropriate standard. For this reason, you should use the -* default only if this is what you intend (and can tolerate any -* associated slight change in behaviour with future versions of -* this function). If you intend to use the ICRS system -* indefinitely, then you should specify it explicitly using an -c "options" value of "System=ICRS". -f OPTIONS value of "System=ICRS". -* - Whichever celestial coordinate system is represented, it will -* have two axes. The first of these will be the longitude axis -* and the second will be the latitude axis. This order can be -c changed using astPermAxes if required. -f changed using AST_PERMAXES if required. -* - When conversion between two SkyFrames is requested (as when -c supplying SkyFrames to astConvert), -f supplying SkyFrames AST_CONVERT), -* account will be taken of the nature of the celestial coordinate -* systems they represent, together with any qualifying mean Equinox or -* Epoch values, etc. The AlignSystem attribute will also be taken into -* account. The results will therefore fully reflect the -* relationship between positions on the sky measured in the two -* systems. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astSkyFrame constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astSkyFrame_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - The variable argument list also prevents this function from -* invoking astSkyFrame_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSkyFrame *new; /* Pointer to new SkyFrame */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SkyFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSkyFrame( NULL, sizeof( AstSkyFrame ), !class_init, &class_vtab, - "SkyFrame" ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SkyFrame's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new SkyFrame. */ - return astMakeId( new ); -} - - - - - - - diff --git a/ast/skyframe.h b/ast/skyframe.h deleted file mode 100644 index 1f63451..0000000 --- a/ast/skyframe.h +++ /dev/null @@ -1,508 +0,0 @@ -#if !defined( SKYFRAME_INCLUDED ) /* Include this file only once */ -#define SKYFRAME_INCLUDED -/* -*+ -* Name: -* skyframe.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the SkyFrame class. - -* Invocation: -* #include "skyframe.h" - -* Description: -* This include file defines the interface to the SkyFrame class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. - -* Inheritance: -* The SkyFrame class inherits from the Frame class. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstSkyFrame -* SkyFrame object type. - -* Protected: -* AstSkyFrameVtab -* SkyFrame virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 4-MAR-1996 (RFWS): -* Original version. -* 24-MAY-1996 (RFWS): -* Tidied up, etc. -* 24-SEP-1996 (RFWS): -* Added I/O facilities. -* 16-JUL-1997 (RFWS): -* Added Projection attribute. -* 26-FEB-1998 (RFWS): -* Over-ride the astUnformat method. -* 3-APR-2001 (DSB): -* Added "Unknown" option for the System attribute. Added read-only -* attributes LatAxis and LonAxis. -* 10-OCT-2002 (DSB): -* Moved definitions of macros for SkyFrame system values into -* this file from skyframe.c. -* 15-NOV-2002 (DSB): -* Move the System attribute from this class to the parent (Frame) -* class. -* 8-JAN-2003 (DSB): -* Added protected astInitSkyFrameVtab method. -* 19-APR-2004 (DSB): -* Added SkyRef, SkyRefIs, SkyRefP and AlignOffset attributes. -* Simplified prologue. -* 2-DEC-2004 (DSB): -* Added System "J2000" -* 22-FEB-2006 (DSB): -* Added Local Apparent Sidereal Time to the SkyFrame structure. -* 3-OCT-2006 (DSB): -* Added Equation of Equinoxes to the SkyFrame structure. -* 6-OCT-2006 (DSB): -* Removed Equation of Equinoxes from the SkyFrame structure. -* Added dut1 to the SkyFrame structure. -* Added Dut1 accessor methods. -* 14-OCT-2006 (DSB): -* Moved dut1 to the Frame class. -* 6-APR-2017 (GSB): -* Added dtai to AstSkyLastTable. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "frame.h" /* Parent Frame class */ - -/* Macros. */ -/* ======= */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -#if defined(astCLASS) /* Protected */ - -/* Define values for the different values of the SkyRefIs attribute. */ -#define AST__BAD_REF 0 -#define AST__POLE_REF 1 -#define AST__ORIGIN_REF 2 -#define AST__IGNORED_REF 3 - -/* Values used to represent different System attribute values. */ -#define AST__FK4 1 -#define AST__FK4_NO_E 2 -#define AST__FK5 3 -#define AST__GAPPT 4 -#define AST__ECLIPTIC 5 -#define AST__GALACTIC 6 -#define AST__SUPERGALACTIC 7 -#define AST__ICRS 8 -#define AST__HELIOECLIPTIC 9 -#define AST__J2000 10 -#define AST__UNKNOWN 11 -#define AST__AZEL 12 - -/* Define constants used to size global arrays in this module. */ -/* Define other numerical constants for use in this module. */ -#define AST__SKYFRAME_GETATTRIB_BUFF_LEN 200 -#define AST__SKYFRAME_GETFORMAT_BUFF_LEN 50 -#define AST__SKYFRAME_GETLABEL_BUFF_LEN 40 -#define AST__SKYFRAME_GETSYMBOL_BUFF_LEN 20 -#define AST__SKYFRAME_GETTITLE_BUFF_LEN 200 - -#endif - -/* Type Definitions. */ -/* ================= */ - -/* Cached LAST look-up table. */ -/* -------------------------- */ -/* Holds a list of epoch values and the corresponding Local Apparent - Sidereal Time values. Also holds the observatory position, DUT1 and DTAI - value used when calculating the LAST values. */ -typedef struct AstSkyLastTable { - double obslat; /* ObsLat at which LAST values were calculated */ - double obslon; /* ObsLon at which LAST values were calculated */ - double obsalt; /* ObsAlt at which LAST values were calculated */ - double dut1; /* Dut1 values at which LAST values were calculated */ - double dtai; /* Dtai values at which LAST values were calculated */ - int nentry; /* Number of entries in the epoch and last arrays */ - double *epoch; /* Array of epoch values */ - double *last; /* Array of LAST values */ -} AstSkyLastTable; - -/* SkyFrame structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstSkyFrame { - -/* Attributes inherited from the parent class. */ - AstFrame frame; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - char *projection; /* Description of sky projection */ - double equinox; /* Modified Julian Date of mean equinox */ - int neglon; /* Display negative longitude values? */ - double skytol; /* Smallest significant distance */ - int alignoffset; /* Align SkyFrame in offset coords? */ - int skyrefis; /* Nature of offset coord system */ - double skyref[ 2 ]; /* Origin or pole of offset coord system */ - double skyrefp[ 2 ]; /* Point on primary meridian of offset coord system */ - double last; /* Local Apparent Sidereal Time */ - double eplast; /* Epoch used to calculate "last" */ - double klast; /* Ratio of solar to sidereal time */ - double diurab; /* Magnitude of diurnal aberration vector */ -} AstSkyFrame; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all objects in the - class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstSkyFrameVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstFrameVtab frame_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstMapping *(* SkyOffsetMap)( AstSkyFrame *, int * ); - const char *(* GetProjection)( AstSkyFrame *, int * ); - double (* GetEquinox)( AstSkyFrame *, int * ); - int (* GetNegLon)( AstSkyFrame *, int * ); - int (* GetAsTime)( AstSkyFrame *, int, int * ); - int (* GetIsLatAxis)( AstSkyFrame *, int, int * ); - int (* GetIsLonAxis)( AstSkyFrame *, int, int * ); - int (* GetLatAxis)( AstSkyFrame *, int * ); - int (* GetLonAxis)( AstSkyFrame *, int * ); - int (* TestAsTime)( AstSkyFrame *, int, int * ); - int (* TestEquinox)( AstSkyFrame *, int * ); - int (* TestNegLon)( AstSkyFrame *, int * ); - int (* TestProjection)( AstSkyFrame *, int * ); - void (* ClearAsTime)( AstSkyFrame *, int, int * ); - void (* ClearEquinox)( AstSkyFrame *, int * ); - void (* ClearNegLon)( AstSkyFrame *, int * ); - void (* ClearProjection)( AstSkyFrame *, int * ); - void (* SetAsTime)( AstSkyFrame *, int, int, int * ); - void (* SetEquinox)( AstSkyFrame *, double, int * ); - void (* SetNegLon)( AstSkyFrame *, int, int * ); - void (* SetProjection)( AstSkyFrame *, const char *, int * ); - - int (* GetSkyRefIs)( AstSkyFrame *, int * ); - int (* TestSkyRefIs)( AstSkyFrame *, int * ); - void (* ClearSkyRefIs)( AstSkyFrame *, int * ); - void (* SetSkyRefIs)( AstSkyFrame *, int, int * ); - - double (* GetSkyTol)( AstSkyFrame *, int * ); - int (* TestSkyTol)( AstSkyFrame *, int * ); - void (* ClearSkyTol)( AstSkyFrame *, int * ); - void (* SetSkyTol)( AstSkyFrame *, double, int * ); - - double (* GetSkyRef)( AstSkyFrame *, int, int * ); - int (* TestSkyRef)( AstSkyFrame *, int, int * ); - void (* ClearSkyRef)( AstSkyFrame *, int, int * ); - void (* SetSkyRef)( AstSkyFrame *, int, double, int * ); - - double (* GetSkyRefP)( AstSkyFrame *, int, int * ); - int (* TestSkyRefP)( AstSkyFrame *, int, int * ); - void (* ClearSkyRefP)( AstSkyFrame *, int, int * ); - void (* SetSkyRefP)( AstSkyFrame *, int, double, int * ); - - int (* GetAlignOffset)( AstSkyFrame *, int * ); - int (* TestAlignOffset)( AstSkyFrame *, int * ); - void (* ClearAlignOffset)( AstSkyFrame *, int * ); - void (* SetAlignOffset)( AstSkyFrame *, int, int * ); - -} AstSkyFrameVtab; - -#if defined(THREAD_SAFE) - -/* The AstSkyFrameGlobals structure makes a forward reference to the - AstTimeFrame structure which is not defined here (since the - timeframe.h file includes skyframe.h). Hence make a preliminary - definition available now. */ -struct AstTimeFrame; - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstSkyFrameGlobals { - AstSkyFrameVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ AST__SKYFRAME_GETATTRIB_BUFF_LEN + 1 ]; - char GetFormat_Buff[ AST__SKYFRAME_GETFORMAT_BUFF_LEN + 1 ]; - char GetLabel_Buff[ AST__SKYFRAME_GETLABEL_BUFF_LEN + 1 ]; - char GetSymbol_Buff[ AST__SKYFRAME_GETSYMBOL_BUFF_LEN + 1 ]; - char GetTitle_Buff[ AST__SKYFRAME_GETTITLE_BUFF_LEN + 1 ]; - char GetTitle_Buff2[ AST__SKYFRAME_GETTITLE_BUFF_LEN + 1 ]; - struct AstTimeFrame *TDBFrame; - struct AstTimeFrame *LASTFrame; -} AstSkyFrameGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(SkyFrame) /* Check class membership */ -astPROTO_ISA(SkyFrame) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -AstSkyFrame *astSkyFrame_( const char *, int *, ...); -#else -AstSkyFrame *astSkyFrameId_( const char *, ... )__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstSkyFrame *astInitSkyFrame_( void *, size_t, int, AstSkyFrameVtab *, - const char *, int * ); - -/* Vtab initialiser. */ -void astInitSkyFrameVtab_( AstSkyFrameVtab *, const char *, int * ); - -/* Loader. */ -AstSkyFrame *astLoadSkyFrame_( void *, size_t, AstSkyFrameVtab *, - const char *, AstChannel *channel, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitSkyFrameGlobals_( AstSkyFrameGlobals * ); -#endif -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -AstMapping *astSkyOffsetMap_( AstSkyFrame *, int * ); - -#if defined(astCLASS) /* Protected */ -const char *astGetProjection_( AstSkyFrame *, int * ); -double astGetEquinox_( AstSkyFrame *, int * ); -int astGetNegLon_( AstSkyFrame *, int * ); -int astGetAsTime_( AstSkyFrame *, int, int * ); -int astGetIsLatAxis_( AstSkyFrame *, int, int * ); -int astGetIsLonAxis_( AstSkyFrame *, int, int * ); -int astGetLatAxis_( AstSkyFrame *, int * ); -int astGetLonAxis_( AstSkyFrame *, int * ); -int astTestAsTime_( AstSkyFrame *, int, int * ); -int astTestEquinox_( AstSkyFrame *, int * ); -int astTestNegLon_( AstSkyFrame *, int * ); -int astTestProjection_( AstSkyFrame *, int * ); -void astClearAsTime_( AstSkyFrame *, int, int * ); -void astClearEquinox_( AstSkyFrame *, int * ); -void astClearNegLon_( AstSkyFrame *, int * ); -void astClearProjection_( AstSkyFrame *, int * ); -void astSetAsTime_( AstSkyFrame *, int, int, int * ); -void astSetEquinox_( AstSkyFrame *, double, int * ); -void astSetNegLon_( AstSkyFrame *, int, int * ); -void astSetProjection_( AstSkyFrame *, const char *, int * ); - -int astGetAlignOffset_( AstSkyFrame *, int * ); -int astTestAlignOffset_( AstSkyFrame *, int * ); -void astClearAlignOffset_( AstSkyFrame *, int * ); -void astSetAlignOffset_( AstSkyFrame *, int, int * ); - -int astGetSkyRefIs_( AstSkyFrame *, int * ); -int astTestSkyRefIs_( AstSkyFrame *, int * ); -void astClearSkyRefIs_( AstSkyFrame *, int * ); -void astSetSkyRefIs_( AstSkyFrame *, int, int * ); - -double astGetSkyRef_( AstSkyFrame *, int, int * ); -int astTestSkyRef_( AstSkyFrame *, int, int * ); -void astClearSkyRef_( AstSkyFrame *, int, int * ); -void astSetSkyRef_( AstSkyFrame *, int, double, int * ); - -double astGetSkyRefP_( AstSkyFrame *, int, int * ); -int astTestSkyRefP_( AstSkyFrame *, int, int * ); -void astClearSkyRefP_( AstSkyFrame *, int, int * ); -void astSetSkyRefP_( AstSkyFrame *, int, double, int * ); - -double astGetSkyTol_( AstSkyFrame *, int * ); -int astTestSkyTol_( AstSkyFrame *, int * ); -void astClearSkyTol_( AstSkyFrame *, int * ); -void astSetSkyTol_( AstSkyFrame *, double, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckSkyFrame(this) astINVOKE_CHECK(SkyFrame,this,0) -#define astVerifySkyFrame(this) astINVOKE_CHECK(SkyFrame,this,1) - -/* Test class membership. */ -#define astIsASkyFrame(this) astINVOKE_ISA(SkyFrame,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -#define astSkyFrame astINVOKE(F,astSkyFrame_) -#else -#define astSkyFrame astINVOKE(F,astSkyFrameId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitSkyFrame(mem,size,init,vtab,name) \ -astINVOKE(O,astInitSkyFrame_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitSkyFrameVtab(vtab,name) astINVOKE(V,astInitSkyFrameVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadSkyFrame(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadSkyFrame_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) - -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ - -#define astSkyOffsetMap(this) \ -astINVOKE(O,astSkyOffsetMap_(astCheckSkyFrame(this),STATUS_PTR)) - -/* Interfaces to protected member functions. */ -/* ----------------------------------------- */ -/* Here we make use of astCheckSkyFrame to validate SkyFrame pointers - before use. This provides a contextual error report if a pointer to - the wrong sort of object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astClearAsTime(this,axis) \ -astINVOKE(V,astClearAsTime_(astCheckSkyFrame(this),axis,STATUS_PTR)) -#define astClearEquinox(this) \ -astINVOKE(V,astClearEquinox_(astCheckSkyFrame(this),STATUS_PTR)) -#define astClearNegLon(this) \ -astINVOKE(V,astClearNegLon_(astCheckSkyFrame(this),STATUS_PTR)) -#define astClearProjection(this) \ -astINVOKE(V,astClearProjection_(astCheckSkyFrame(this),STATUS_PTR)) -#define astGetAsTime(this,axis) \ -astINVOKE(V,astGetAsTime_(astCheckSkyFrame(this),axis,STATUS_PTR)) -#define astGetEquinox(this) \ -astINVOKE(V,astGetEquinox_(astCheckSkyFrame(this),STATUS_PTR)) -#define astGetNegLon(this) \ -astINVOKE(V,astGetNegLon_(astCheckSkyFrame(this),STATUS_PTR)) -#define astGetIsLatAxis(this,axis) \ -astINVOKE(V,astGetIsLatAxis_(astCheckSkyFrame(this),axis,STATUS_PTR)) -#define astGetIsLonAxis(this,axis) \ -astINVOKE(V,astGetIsLonAxis_(astCheckSkyFrame(this),axis,STATUS_PTR)) -#define astGetLatAxis(this) \ -astINVOKE(V,astGetLatAxis_(astCheckSkyFrame(this),STATUS_PTR)) -#define astGetLonAxis(this) \ -astINVOKE(V,astGetLonAxis_(astCheckSkyFrame(this),STATUS_PTR)) -#define astGetProjection(this) \ -astINVOKE(V,astGetProjection_(astCheckSkyFrame(this),STATUS_PTR)) -#define astSetAsTime(this,axis,value) \ -astINVOKE(V,astSetAsTime_(astCheckSkyFrame(this),axis,value,STATUS_PTR)) -#define astSetEquinox(this,value) \ -astINVOKE(V,astSetEquinox_(astCheckSkyFrame(this),value,STATUS_PTR)) -#define astSetNegLon(this,value) \ -astINVOKE(V,astSetNegLon_(astCheckSkyFrame(this),value,STATUS_PTR)) -#define astSetProjection(this,value) \ -astINVOKE(V,astSetProjection_(astCheckSkyFrame(this),value,STATUS_PTR)) -#define astTestAsTime(this,axis) \ -astINVOKE(V,astTestAsTime_(astCheckSkyFrame(this),axis,STATUS_PTR)) -#define astTestEquinox(this) \ -astINVOKE(V,astTestEquinox_(astCheckSkyFrame(this),STATUS_PTR)) -#define astTestNegLon(this) \ -astINVOKE(V,astTestNegLon_(astCheckSkyFrame(this),STATUS_PTR)) -#define astTestProjection(this) \ -astINVOKE(V,astTestProjection_(astCheckSkyFrame(this),STATUS_PTR)) - -#define astClearAlignOffset(this) astINVOKE(V,astClearAlignOffset_(astCheckSkyFrame(this),STATUS_PTR)) -#define astGetAlignOffset(this) astINVOKE(V,astGetAlignOffset_(astCheckSkyFrame(this),STATUS_PTR)) -#define astSetAlignOffset(this,value) astINVOKE(V,astSetAlignOffset_(astCheckSkyFrame(this),value,STATUS_PTR)) -#define astTestAlignOffset(this) astINVOKE(V,astTestAlignOffset_(astCheckSkyFrame(this),STATUS_PTR)) - -#define astClearSkyRefIs(this) astINVOKE(V,astClearSkyRefIs_(astCheckSkyFrame(this),STATUS_PTR)) -#define astGetSkyRefIs(this) astINVOKE(V,astGetSkyRefIs_(astCheckSkyFrame(this),STATUS_PTR)) -#define astSetSkyRefIs(this,value) astINVOKE(V,astSetSkyRefIs_(astCheckSkyFrame(this),value,STATUS_PTR)) -#define astTestSkyRefIs(this) astINVOKE(V,astTestSkyRefIs_(astCheckSkyFrame(this),STATUS_PTR)) - -#define astClearSkyRef(this,axis) astINVOKE(V,astClearSkyRef_(astCheckSkyFrame(this),axis,STATUS_PTR)) -#define astGetSkyRef(this,axis) astINVOKE(V,astGetSkyRef_(astCheckSkyFrame(this),axis,STATUS_PTR)) -#define astSetSkyRef(this,axis,value) astINVOKE(V,astSetSkyRef_(astCheckSkyFrame(this),axis,value,STATUS_PTR)) -#define astTestSkyRef(this,axis) astINVOKE(V,astTestSkyRef_(astCheckSkyFrame(this),axis,STATUS_PTR)) - -#define astClearSkyRefP(this,axis) astINVOKE(V,astClearSkyRefP_(astCheckSkyFrame(this),axis,STATUS_PTR)) -#define astGetSkyRefP(this,axis) astINVOKE(V,astGetSkyRefP_(astCheckSkyFrame(this),axis,STATUS_PTR)) -#define astSetSkyRefP(this,axis,value) astINVOKE(V,astSetSkyRefP_(astCheckSkyFrame(this),axis,value,STATUS_PTR)) -#define astTestSkyRefP(this,axis) astINVOKE(V,astTestSkyRefP_(astCheckSkyFrame(this),axis,STATUS_PTR)) - -#define astClearSkyTol(this) astINVOKE(V,astClearSkyTol_(astCheckSkyFrame(this),STATUS_PTR)) -#define astGetSkyTol(this) astINVOKE(V,astGetSkyTol_(astCheckSkyFrame(this),STATUS_PTR)) -#define astSetSkyTol(this,value) astINVOKE(V,astSetSkyTol_(astCheckSkyFrame(this),value,STATUS_PTR)) -#define astTestSkyTol(this) astINVOKE(V,astTestSkyTol_(astCheckSkyFrame(this),STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/slamap.c b/ast/slamap.c deleted file mode 100644 index 345bbf0..0000000 --- a/ast/slamap.c +++ /dev/null @@ -1,5027 +0,0 @@ -/* -*class++ -* Name: -* SlaMap - -* Purpose: -* Sequence of celestial coordinate conversions. - -* Constructor Function: -c astSlaMap (also see astSlaAdd) -f AST_SLAMAP (also see AST_SLAADD) - -* Description: -* An SlaMap is a specialised form of Mapping which can be used to -* represent a sequence of conversions between standard celestial -* (longitude, latitude) coordinate systems. -* -* When an SlaMap is first created, it simply performs a unit -c (null) Mapping on a pair of coordinates. Using the astSlaAdd -f (null) Mapping on a pair of coordinates. Using the AST_SLAADD -c function, a series of coordinate conversion steps may then be -f routine, a series of coordinate conversion steps may then be -* added, selected from those provided by the SLALIB Positional -* Astronomy Library (Starlink User Note SUN/67). This allows -* multi-step conversions between a variety of celestial coordinate -* systems to be assembled out of the building blocks provided by -* SLALIB. -* -* For details of the individual coordinate conversions available, -c see the description of the astSlaAdd function. -f see the description of the AST_SLAADD routine. - -* Inheritance: -* The SlaMap class inherits from the Mapping class. - -* Attributes: -* The SlaMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c In addition to those functions applicable to all Mappings, the -c following function may also be applied to all SlaMaps: -f In addition to those routines applicable to all Mappings, the -f following routine may also be applied to all SlaMaps: -* -c - astSlaAdd: Add a celestial coordinate conversion to an SlaMap -f - AST_SLAADD: Add a celestial coordinate conversion to an SlaMap - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2013 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 25-APR-1996 (RFWS): -* Original version. -* 28-MAY-1996 (RFWS): -* Fixed bug in argument order to palMappa for AST__SLA_AMP case. -* 26-SEP-1996 (RFWS): -* Added external interface and I/O facilities. -* 23-MAY-1997 (RFWS): -* Over-ride the astMapMerge method. -* 28-MAY-1997 (RFWS): -* Use strings to specify conversions for the public interface -* and convert to macros (from an enumerated type) for the -* internal representation. Tidy the public prologues. -* 8-JAN-2003 (DSB): -* - Changed private InitVtab method to protected astInitSlaMapVtab -* method. -* - Included STP conversion functions. -* 11-JUN-2003 (DSB): -* - Added HFK5Z and FK5HZ conversion functions. -* 28-SEP-2003 (DSB): -* - Added HEEQ and EQHE conversion functions. -* 2-DEC-2004 (DSB): -* - Added J2000H and HJ2000 conversion functions. -* 15-AUG-2005 (DSB): -* - Added H2E and E2H conversion functions. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 22-FEB-2006 (DSB): -* Cache results returned by palMappa in order to increase speed. -* 10-MAY-2006 (DSB): -* Override astEqual. -* 31-AUG-2007 (DSB): -* - Modify H2E and E2H conversion functions so that they convert to -* and from apparent (HA,Dec) rather than topocentric (HA,Dec) (i.e. -* include a correction for diurnal aberration). This requires an -* extra conversion argument holding the magnitude of the diurnal -* aberration vector. -* - Correct bug in the simplification of adjacent AMP and MAP -* conversions. -* 15-NOV-2013 (DSB): -* Fix bug in merging of adjacent AMP and MAP conversions (MapMerge -* did not take account of the fact that the arguments for these -* two conversions are stored in swapped order). -* 6-JUL-2015 (DSB): -* Added method astSlaIsEmpty. -* 30-NOV-2016 (DSB): -* Added a "narg" argumeent to astSlaAdd. - -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS SlaMap - -/* Codes to identify SLALIB sky coordinate conversions. */ -#define AST__SLA_NULL 0 /* Null value */ -#define AST__SLA_ADDET 1 /* Add E-terms of aberration */ -#define AST__SLA_SUBET 2 /* Subtract E-terms of aberration */ -#define AST__SLA_PREBN 3 /* Bessel-Newcomb (FK4) precession */ -#define AST__SLA_PREC 4 /* Apply IAU 1975 (FK5) precession model */ -#define AST__SLA_FK45Z 5 /* FK4 to FK5, no proper motion or parallax */ -#define AST__SLA_FK54Z 6 /* FK5 to FK4, no proper motion or parallax */ -#define AST__SLA_AMP 7 /* Geocentric apparent to mean place */ -#define AST__SLA_MAP 8 /* Mean place to geocentric apparent */ -#define AST__SLA_ECLEQ 9 /* Ecliptic to J2000.0 equatorial */ -#define AST__SLA_EQECL 10 /* Equatorial J2000.0 to ecliptic */ -#define AST__SLA_GALEQ 11 /* Galactic to J2000.0 equatorial */ -#define AST__SLA_EQGAL 12 /* J2000.0 equatorial to galactic */ -#define AST__SLA_GALSUP 13 /* Galactic to supergalactic */ -#define AST__SLA_SUPGAL 14 /* Supergalactic to galactic */ -#define AST__HPCEQ 15 /* Helioprojective-Cartesian to J2000.0 equatorial */ -#define AST__EQHPC 16 /* J2000.0 equatorial to Helioprojective-Cartesian */ -#define AST__HPREQ 17 /* Helioprojective-Radial to J2000.0 equatorial */ -#define AST__EQHPR 18 /* J2000.0 equatorial to Helioprojective-Radial */ -#define AST__SLA_HFK5Z 19 /* ICRS to FK5 J2000.0, no pm or parallax */ -#define AST__SLA_FK5HZ 20 /* FK5 J2000.0 to ICRS, no pm or parallax */ -#define AST__HEEQ 21 /* Helio-ecliptic to equatorial */ -#define AST__EQHE 22 /* Equatorial to helio-ecliptic */ -#define AST__J2000H 23 /* Dynamical J2000 to ICRS */ -#define AST__HJ2000 24 /* ICRS to dynamical J2000 */ -#define AST__SLA_DH2E 25 /* Horizon to equatorial coordinates */ -#define AST__SLA_DE2H 26 /* Equatorial coordinates to horizon */ -#define AST__R2H 27 /* RA to hour angle */ -#define AST__H2R 28 /* Hour to RA angle */ - -/* Maximum number of arguments required by an SLALIB conversion. */ -#define MAX_SLA_ARGS 4 - -/* The alphabet (used for generating keywords for arguments). */ -#define ALPHABET "abcdefghijklmnopqrstuvwxyz" - -/* Angle conversion (PI is from the SLALIB slamac.h file) */ -#define PI 3.1415926535897932384626433832795028841971693993751 -#define PIBY2 (PI/2.0) -#define D2R (PI/180.0) -#define R2D (180.0/PI) -#define AS2R (PI/648000.0) - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "pal.h" /* SLALIB interface */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ -#include "wcsmap.h" /* Required for AST__DPI */ -#include "unitmap.h" /* Unit (null) Mappings */ -#include "slamap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); - - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->Eq_Cache = AST__BAD; \ - globals->Ep_Cache = AST__BAD; \ - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(SlaMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SlaMap,Class_Init) -#define class_vtab astGLOBAL(SlaMap,Class_Vtab) -#define eq_cache astGLOBAL(SlaMap,Eq_Cache) -#define ep_cache astGLOBAL(SlaMap,Ep_Cache) -#define amprms_cache astGLOBAL(SlaMap,Amprms_Cache) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* A cache used to store the most recent results from palMappa in order - to avoid continuously recalculating the same values. */ -static double eq_cache = AST__BAD; -static double ep_cache = AST__BAD; -static double amprms_cache[ 21 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSlaMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSlaMap *astSlaMapId_( int, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *CvtString( int, const char **, int *, const char *[ MAX_SLA_ARGS ], int * ); -static int CvtCode( const char *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int SlaIsEmpty( AstSlaMap *, int * ); -static void AddSlaCvt( AstSlaMap *, int, int, const double *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void De2h( double, double, double, double, double *, double *, int * ); -static void Dh2e( double, double, double, double, double *, double *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void Earth( double, double[3], int * ); -static void SlaAdd( AstSlaMap *, const char *, int, const double[], int * ); -static void SolarPole( double, double[3], int * ); -static void Hpcc( double, double[3], double[3][3], double[3], int * ); -static void Hprc( double, double[3], double[3][3], double[3], int * ); -static void Hgc( double, double[3][3], double[3], int * ); -static void Haec( double, double[3][3], double[3], int * ); -static void Haqc( double, double[3][3], double[3], int * ); -static void Gsec( double, double[3][3], double[3], int * ); -static void STPConv( double, int, int, int, double[3], double *[3], int, double[3], double *[3], int * ); -static void J2000H( int, int, double *, double *, int * ); - -static int GetObjSize( AstObject *, int * ); - -/* Member functions. */ -/* ================= */ - -static void De2h( double ha, double dec, double phi, double diurab, - double *az, double *el, int *status ){ - -/* Not quite like slaDe2h since it converts from apparent (ha,dec) to - topocentric (az,el). This includes a correction for diurnal - aberration. The magnitude of the diurnal aberration vector should be - supplied in parameter "diurab". The extra code is taken from the - Fortran routine SLA_AOPQK. */ - -/* Local Variables: */ - double a; - double cd; - double ch; - double cp; - double f; - double r; - double sd; - double sh; - double sp; - double x; - double xhd; - double xhdt; - double y; - double yhd; - double yhdt; - double z; - double zhd; - double zhdt; - -/* Check inherited status */ - if( !astOK ) return; - -/* Pre-compute common values */ - sh = sin( ha ); - ch = cos( ha ); - sd = sin( dec ); - cd = cos( dec ); - sp = sin( phi ); - cp = cos( phi ); - -/* Components of cartesian (-ha,dec) vector. */ - xhd = ch*cd; - yhd = -sh*cd; - zhd = sd; - -/* Modify the above vector to apply diurnal aberration. */ - f = ( 1.0 - diurab*yhd ); - xhdt = f*xhd; - yhdt = f*( yhd + diurab ); - zhdt = f*zhd; - -/* Convert to cartesian (az,el). */ - x = -xhdt*sp + zhdt*cp; - y = yhdt; - z = xhdt*cp + zhdt*sp; - -/* Convert to spherical (az,el). */ - r = sqrt( x*x + y*y ); - if( r == 0.0 ) { - a = 0.0; - } else { - a = atan2( y, x ); - } - - while( a < 0.0 ) a += 2*AST__DPI; - - *az = a; - *el = atan2( z, r ); -} - -static void Dh2e( double az, double el, double phi, double diurab, double *ha, - double *dec, int *status ){ - -/* Not quite like slaDh2e since it converts from topocentric (az,el) to - apparent (ha,dec). This includes a correction for diurnal aberration. - The magnitude of the diurnal aberration vector should be supplied in - parameter "diurab". The extra code is taken from the Fortran routine - SLA_OAPQK. */ - -/* Local Variables: */ - double ca; - double ce; - double cp; - double f; - double r; - double sa; - double se; - double sp; - double x; - double xmhda; - double y; - double ymhda; - double z; - double zmhda; - -/* Check inherited status */ - if( !astOK ) return; - -/* Pre-compute common values. */ - sa = sin( az ); - ca = cos( az ); - se = sin( el ); - ce = cos( el ); - sp = sin( phi ); - cp = cos( phi ); - -/* Cartesian (az,el) to Cartesian (ha,dec) - note, +ha, not -ha. */ - xmhda = -ca*ce*sp + se*cp; - ymhda = -sa*ce; - zmhda = ca*ce*cp + se*sp; - -/* Correct this vector for diurnal aberration. Since the above - expressions produce +ha rather than -ha, we do not negate "diurab" - before using it. Compare this to SLA_AOPQK. */ - f = ( 1 - diurab*ymhda ); - x = f*xmhda; - y = f*( ymhda + diurab ); - z = f*zmhda; - -/* Cartesian (ha,dec) to spherical (ha,dec). */ - r = sqrt( x*x + y*y ); - if( r == 0.0 ) { - *ha = 0.0; - } else { - *ha = atan2( y, x ); - } - *dec = atan2( z, r ); -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two SlaMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "slamap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* SlaMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two SlaMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a SlaMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the SlaMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSlaMap *that; - AstSlaMap *this; - const char *argdesc[ MAX_SLA_ARGS ]; - const char *comment; - int i, j; - int nargs; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two SlaMap structures. */ - this = (AstSlaMap *) this_object; - that = (AstSlaMap *) that_object; - -/* Check the second object is a SlaMap. We know the first is a - SlaMap since we have arrived at this implementation of the virtual - function. */ - if( astIsASlaMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two SlaMaps differ, it may still be possible - for them to be equivalent. First compare the SlaMaps if their Invert - flags are the same. In this case all the attributes of the two SlaMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - if( this->ncvt == that->ncvt ) { - result = 1; - for( i = 0; i < this->ncvt && result; i++ ) { - if( this->cvttype[ i ] != that->cvttype[ i ] ) { - result = 0; - } else { - CvtString( this->cvttype[ i ], &comment, &nargs, - argdesc, status ); - for( j = 0; j < nargs; j++ ) { - if( !astEQUAL( this->cvtargs[ i ][ j ], - that->cvtargs[ i ][ j ] ) ){ - result = 0; - break; - } - } - } - } - } - -/* If the Invert flags for the two SlaMaps differ, the attributes of the two - SlaMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a SlaMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "slamap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* SlaMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied SlaMap, -* in bytes. - -* Parameters: -* this -* Pointer to the SlaMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSlaMap *this; /* Pointer to SlaMap structure */ - int result; /* Result value to return */ - int cvt; /* Loop counter for coordinate conversions */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the SlaMap structure. */ - this = (AstSlaMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - for ( cvt = 0; cvt < this->ncvt; cvt++ ) { - result += astTSizeOf( this->cvtargs[ cvt ] ); - result += astTSizeOf( this->cvtextra[ cvt ] ); - } - - result += astTSizeOf( this->cvtargs ); - result += astTSizeOf( this->cvtextra ); - result += astTSizeOf( this->cvttype ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void AddSlaCvt( AstSlaMap *this, int cvttype, int narg, - const double *args, int *status ) { -/* -* Name: -* AddSlaCvt - -* Purpose: -* Add a coordinate conversion step to an SlaMap. - -* Type: -* Private function. - -* Synopsis: -* #include "slamap.h" -* void AddSlaCvt( AstSlaMap *this, int cvttype, int narg, -* const double *args ) - -* Class Membership: -* SlaMap member function. - -* Description: -* This function allows one of the sky coordinate conversions -* supported by SLALIB to be appended to an SlaMap. When an SlaMap -* is first created (using astSlaMap), it simply performs a unit -* mapping. By using AddSlaCvt repeatedly, a series of sky -* coordinate conversions may then be specified which the SlaMap -* will subsequently perform in sequence. This allows a complex -* coordinate conversion to be assembled out of the basic building -* blocks provided by SLALIB. The SlaMap will also perform the -* inverse coordinate conversion (applying the individual -* conversion steps in reverse) if required. - -* Parameters: -* this -* Pointer to the SlaMap. -* cvttype -* A code to identify which sky coordinate conversion is to be -* appended. See the "SLALIB Coordinate Conversions" section -* for details of those available. -* narg -* The number of argument values supplied in "args". -* args -* Pointer to an array of double containing the argument values -* required to fully specify the required coordinate -* conversion. The number of arguments depends on the conversion -* (see the "SLALIB Coordinate Conversions" section for -* details). This value is ignored and may be NULL if no -* arguments are required. - -* Returned Value: -* void. - -* SLALIB Coordinate Conversions: -* The following values may be supplied for the "cvttype" parameter -* in order to specify the sky coordinate conversion to be -* performed. In each case the value is named after the SLALIB -* routine that performs the conversion, and the relevant SLALIB -* documentation should be consulted for full details. -* -* The argument(s) required to fully specify each conversion are -* indicated in parentheses after each value. Values for these -* should be given in the array pointed at by "args". The argument -* names given match the corresponding SLALIB function arguments -* (in the Fortran 77 documentation - SUN/67) and their values -* should be given using the same units, time scale, calendar, -* etc. as in SLALIB. -* -* AST__SLA_ADDET( EQ ) -* Add E-terms of aberration. -* AST__SLA_SUBET( EQ ) -* Subtract E-terms of aberration. -* AST__SLA_PREBN( BEP0, BEP1 ) -* Apply Bessel-Newcomb pre-IAU 1976 (FK4) precession model. -* AST__SLA_PREC( EP0, EP1 ) -* Apply IAU 1975 (FK5) precession model. -* AST__SLA_FK45Z( BEPOCH ) -* Convert FK4 to FK5 (no proper motion or parallax). -* AST__SLA_FK54Z( BEPOCH ) -* Convert FK5 to FK4 (no proper motion or parallax). -* AST__SLA_AMP( DATE, EQ ) -* Convert geocentric apparent to mean place. -* AST__SLA_MAP( EQ, DATE ) -* Convert mean place to geocentric apparent. -* AST__SLA_ECLEQ( DATE ) -* Convert ecliptic coordinates to J2000.0 equatorial. -* AST__SLA_EQECL( DATE ) -* Convert equatorial J2000.0 to ecliptic coordinates. -* AST__SLA_GALEQ( ) -* Convert galactic coordinates to J2000.0 equatorial. -* AST__SLA_EQGAL( ) -* Convert J2000.0 equatorial to galactic coordinates. -* AST__SLA_HFK5Z( JEPOCH ) -* Convert ICRS coordinates to J2000.0 equatorial (no proper -* motion or parallax). -* AST__SLA_FK5HZ( JEPOCH ) -* Convert J2000.0 equatorial to ICRS coordinates (no proper -* motion or parallax). -* AST__SLA_GALSUP( ) -* Convert galactic to supergalactic coordinates. -* AST__SLA_SUPGAL( ) -* Convert supergalactic coordinates to galactic. -* AST__HPCEQ( DATE, OBSX, OBSY, OBSZ ) -* Convert Helioprojective-Cartesian coordinates to J2000.0 -* equatorial. This is not a native SLALIB conversion, but is -* implemented by functions within this module. The DATE argument -* is the MJD defining the HPC coordinate system. The OBSX, OBSY -* and OBSZ arguments are the AST__HAEC coordinates of the observer. -* AST__EQHPC( DATE, OBSX, OBSY, OBSZ ) -* Convert J2000.0 equatorial coordinates to Helioprojective-Cartesian. -* AST__HPREQ( DATE, OBSX, OBSY, OBSZ ) -* Convert Helioprojective-Radial coordinates to J2000.0 equatorial. -* AST__EQHPR( DATE, OBSX, OBSY, OBSZ ) -* Convert J2000.0 equatorial coordinates to Helioprojective-Radial. -* AST__HEEQ( DATE ) -* Convert helio-ecliptic to ecliptic coordinates. -* AST__EQHE( DATE ) -* Convert ecliptic to helio-ecliptic coordinates. -* AST__J2000H( ) -* Convert dynamical J2000 to ICRS. -* AST__HJ2000( ) -* Convert ICRS to dynamical J2000. -* AST__SLA_DH2E( LAT, DIURAB ) -* Convert horizon to equatorial coordinates -* AST__SLA_DE2H( LAT, DIURAB ) -* Convert equatorial to horizon coordinates -* AST__R2H( LAST ) -* Convert RA to Hour Angle. -* AST__H2R( LAST ) -* Convert Hour Angle to RA. - -* Notes: -* - The specified conversion is appended only if the SlaMap's -* Invert attribute is zero. If it is non-zero, this function -* effectively prefixes the inverse of the conversion specified -* instead. -* - Sky coordinate values are in radians (as for SLALIB) and all -* conversions are performed using double arithmetic. -*/ - -/* Local Variables: */ - const char *argdesc[ MAX_SLA_ARGS ]; /* Pointers to argument descriptions */ - const char *comment; /* Pointer to comment string */ - const char *cvt_string; /* Pointer to conversion type string */ - int nargs; /* Number of arguments */ - int ncvt; /* Number of coordinate conversions */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the coordinate conversion type and obtain the number of - required arguments. */ - cvt_string = CvtString( cvttype, &comment, &nargs, argdesc, status ); - -/* If the sky coordinate conversion type was not valid, then report an - error. */ - if ( astOK && !cvt_string ) { - astError( AST__SLAIN, "AddSlaCvt(%s): Invalid SLALIB sky coordinate " - "conversion type (%d).", status, astGetClass( this ), - (int) cvttype ); - } - -/* If the number of supplied arguments is incorrect, then report an error. */ - if ( astOK && nargs != narg ) { - astError( AST__TIMIN, "AddSlaCvt(%s): Invalid no. of arguments for SLALIB " - "coordinate conversion type %d - %d supplied, %d required.", - status, astGetClass( this ), (int) cvttype, narg, nargs ); - } - -/* Note the number of coordinate conversions already stored in the SlaMap. */ - if ( astOK ) { - ncvt = this->ncvt; - -/* Extend the array of conversion types and the array of pointers to - their argument lists to accommodate the new one. */ - this->cvttype = (int *) astGrow( this->cvttype, ncvt + 1, - sizeof( int ) ); - this->cvtargs = (double **) astGrow( this->cvtargs, ncvt + 1, - sizeof( double * ) ); - this->cvtextra = (double **) astGrow( this->cvtextra, ncvt + 1, - sizeof( double * ) ); - -/* If OK, allocate memory and store a copy of the argument list, - putting a pointer to the copy into the SlaMap. */ - if ( astOK ) { - this->cvtargs[ ncvt ] = astStore( NULL, args, - sizeof( double ) * (size_t) nargs ); - this->cvtextra[ ncvt ] = NULL; - } - -/* Store the conversion type and increment the conversion count. */ - if ( astOK ) { - this->cvttype[ ncvt ] = cvttype; - this->ncvt++; - } - } -} - -static int CvtCode( const char *cvt_string, int *status ) { -/* -* Name: -* CvtCode - -* Purpose: -* Convert a conversion type from a string representation to a code value. - -* Type: -* Private function. - -* Synopsis: -* #include "slamap.h" -* int CvtCode( const char *cvt_string, int *status ) - -* Class Membership: -* SlaMap member function. - -* Description: -* This function accepts a string used to repersent one of the -* SLALIB sky coordinate conversions and converts it into a code -* value for internal use. - -* Parameters: -* cvt_string -* Pointer to a constant null-terminated string representing a -* sky coordinate conversion. This is case sensitive and should -* contain no unnecessary white space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The equivalent conversion code. If the string was not -* recognised, the code AST__SLA_NULL is returned, without error. - -* Notes: -* - A value of AST__SLA_NULL will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - int result; /* Result value to return */ - -/* Initialise. */ - result = AST__SLA_NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Test the string against each recognised value in turn and assign - the result. */ - if ( astChrMatch( cvt_string, "ADDET" ) ) { - result = AST__SLA_ADDET; - - } else if ( astChrMatch( cvt_string, "SUBET" ) ) { - result = AST__SLA_SUBET; - - } else if ( astChrMatch( cvt_string, "PREBN" ) ) { - result = AST__SLA_PREBN; - - } else if ( astChrMatch( cvt_string, "PREC" ) ) { - result = AST__SLA_PREC; - - } else if ( astChrMatch( cvt_string, "FK45Z" ) ) { - result = AST__SLA_FK45Z; - - } else if ( astChrMatch( cvt_string, "FK54Z" ) ) { - result = AST__SLA_FK54Z; - - } else if ( astChrMatch( cvt_string, "AMP" ) ) { - result = AST__SLA_AMP; - - } else if ( astChrMatch( cvt_string, "MAP" ) ) { - result = AST__SLA_MAP; - - } else if ( astChrMatch( cvt_string, "ECLEQ" ) ) { - result = AST__SLA_ECLEQ; - - } else if ( astChrMatch( cvt_string, "EQECL" ) ) { - result = AST__SLA_EQECL; - - } else if ( astChrMatch( cvt_string, "GALEQ" ) ) { - result = AST__SLA_GALEQ; - - } else if ( astChrMatch( cvt_string, "EQGAL" ) ) { - result = AST__SLA_EQGAL; - - } else if ( astChrMatch( cvt_string, "FK5HZ" ) ) { - result = AST__SLA_FK5HZ; - - } else if ( astChrMatch( cvt_string, "HFK5Z" ) ) { - result = AST__SLA_HFK5Z; - - } else if ( astChrMatch( cvt_string, "GALSUP" ) ) { - result = AST__SLA_GALSUP; - - } else if ( astChrMatch( cvt_string, "SUPGAL" ) ) { - result = AST__SLA_SUPGAL; - - } else if ( astChrMatch( cvt_string, "HPCEQ" ) ) { - result = AST__HPCEQ; - - } else if ( astChrMatch( cvt_string, "EQHPC" ) ) { - result = AST__EQHPC; - - } else if ( astChrMatch( cvt_string, "HPREQ" ) ) { - result = AST__HPREQ; - - } else if ( astChrMatch( cvt_string, "EQHPR" ) ) { - result = AST__EQHPR; - - } else if ( astChrMatch( cvt_string, "HEEQ" ) ) { - result = AST__HEEQ; - - } else if ( astChrMatch( cvt_string, "EQHE" ) ) { - result = AST__EQHE; - - } else if ( astChrMatch( cvt_string, "J2000H" ) ) { - result = AST__J2000H; - - } else if ( astChrMatch( cvt_string, "HJ2000" ) ) { - result = AST__HJ2000; - - } else if ( astChrMatch( cvt_string, "H2E" ) ) { - result = AST__SLA_DH2E; - - } else if ( astChrMatch( cvt_string, "E2H" ) ) { - result = AST__SLA_DE2H; - - } else if ( astChrMatch( cvt_string, "R2H" ) ) { - result = AST__R2H; - - } else if ( astChrMatch( cvt_string, "H2R" ) ) { - result = AST__H2R; - - } - -/* Return the result. */ - return result; -} - -static const char *CvtString( int cvt_code, const char **comment, - int *nargs, const char *arg[ MAX_SLA_ARGS ], int *status ) { -/* -* Name: -* CvtString - -* Purpose: -* Convert a conversion type from a code value to a string representation. - -* Type: -* Private function. - -* Synopsis: -* #include "slamap.h" -* const char *CvtString( int cvt_code, const char **comment, -* int *nargs, const char *arg[ MAX_SLA_ARGS ], int *status ) - -* Class Membership: -* SlaMap member function. - -* Description: -* This function accepts a code value used to represent one of the -* SLALIB sky coordinate conversions and converts it into an -* equivalent string representation. It also returns a descriptive -* comment and information about the arguments required in order to -* perform the conversion. - -* Parameters: -* cvt_code -* The conversion code. -* comment -* Address of a location to return a pointer to a constant -* null-terminated string containing a description of the -* conversion. -* nargs -* Address of an int in which to return the number of arguments -* required in order to perform the conversion (may be zero). -* arg -* An array in which to return a pointer to a constant -* null-terminated string for each argument (above) containing a -* description of what each argument represents. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string representation of -* the conversion code value supplied. If the code supplied is not -* valid, a NULL pointer will be returned, without error. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Result pointer to return */ - -/* Initialise the returned values. */ - *comment = NULL; - *nargs = 0; - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Test for each valid code value in turn and assign the appropriate - return values. */ - switch ( cvt_code ) { - - case AST__SLA_ADDET: - result = "ADDET"; - *comment = "Add E-terms of aberration"; - *nargs = 1; - arg[ 0 ] = "Besselian epoch of mean equinox (FK4)"; - break; - - case AST__SLA_SUBET: - result = "SUBET"; - *comment = "Subtract E-terms of aberration"; - *nargs = 1; - arg[ 0 ] = "Besselian epoch of mean equinox (FK4)"; - break; - - case AST__SLA_PREBN: - result = "PREBN"; - *comment = "Apply Bessel-Newcomb (FK4) precession"; - *nargs = 2; - arg[ 0 ] = "From Besselian epoch"; - arg[ 1 ] = "To Besselian epoch"; - break; - - case AST__SLA_PREC: - result = "PREC"; - *comment = "Apply IAU 1975 (FK5) precession"; - *nargs = 2; - arg[ 0 ] = "From Julian epoch"; - arg[ 1 ] = "To Julian epoch"; - break; - - case AST__SLA_FK45Z: - result = "FK45Z"; - *comment = "FK4 to FK5 J2000.0 (no PM or parallax)"; - arg[ 0 ] = "Besselian epoch of FK4 coordinates"; - *nargs = 1; - break; - - case AST__SLA_FK54Z: - result = "FK54Z"; - *comment = "FK5 J2000.0 to FK4 (no PM or parallax)"; - *nargs = 1; - arg[ 0 ] = "Besselian epoch of FK4 system"; - break; - - case AST__SLA_AMP: - result = "AMP"; - *comment = "Geocentric apparent to mean place (FK5)"; - *nargs = 2; - arg[ 0 ] = "TDB of apparent place (as MJD)"; - arg[ 1 ] = "Julian epoch of mean equinox (FK5)"; - break; - - case AST__SLA_MAP: - result = "MAP"; - *comment = "Mean place (FK5) to geocentric apparent"; - *nargs = 2; - arg[ 0 ] = "Julian epoch of mean equinox (FK5)"; - arg[ 1 ] = "TDB of apparent place (as MJD)"; - break; - - case AST__SLA_ECLEQ: - result = "ECLEQ"; - *comment = "Ecliptic (IAU 1980) to J2000.0 equatorial (FK5)"; - *nargs = 1; - arg[ 0 ] = "TDB of mean ecliptic (as MJD)"; - break; - - case AST__SLA_EQECL: - result = "EQECL"; - *comment = "Equatorial J2000.0 (FK5) to ecliptic (IAU 1980)"; - *nargs = 1; - arg[ 0 ] = "TDB of mean ecliptic (as MJD)"; - break; - - case AST__SLA_GALEQ: - result = "GALEQ"; - *comment = "Galactic (IAU 1958) to J2000.0 equatorial (FK5)"; - *nargs = 0; - break; - - case AST__SLA_EQGAL: - result = "EQGAL"; - *comment = "J2000.0 equatorial (FK5) to galactic (IAU 1958)"; - *nargs = 0; - break; - - case AST__SLA_FK5HZ: - result = "FK5HZ"; - *comment = "J2000.0 FK5 to ICRS (no PM or parallax)"; - arg[ 0 ] = "Julian epoch of FK5 coordinates"; - *nargs = 1; - break; - - case AST__SLA_HFK5Z: - result = "HFK5Z"; - *comment = "ICRS to J2000.0 FK5 (no PM or parallax)"; - arg[ 0 ] = "Julian epoch of FK5 coordinates"; - *nargs = 1; - break; - - case AST__SLA_GALSUP: - result = "GALSUP"; - *comment = "Galactic (IAU 1958) to supergalactic"; - *nargs = 0; - break; - - case AST__SLA_SUPGAL: - result = "SUPGAL"; - *comment = "Supergalactic to galactic (IAU 1958)"; - *nargs = 0; - break; - - case AST__HPCEQ: - result = "HPCEQ"; - *comment = "Helioprojective-Cartesian to J2000.0 equatorial (FK5)"; - *nargs = 4; - arg[ 0 ] = "Modified Julian Date of observation"; - arg[ 1 ] = "Heliocentric-Aries-Ecliptic X value at observer"; - arg[ 2 ] = "Heliocentric-Aries-Ecliptic Y value at observer"; - arg[ 3 ] = "Heliocentric-Aries-Ecliptic Z value at observer"; - break; - - case AST__EQHPC: - result = "EQHPC"; - *comment = "J2000.0 equatorial (FK5) to Helioprojective-Cartesian"; - *nargs = 4; - arg[ 0 ] = "Modified Julian Date of observation"; - arg[ 1 ] = "Heliocentric-Aries-Ecliptic X value at observer"; - arg[ 2 ] = "Heliocentric-Aries-Ecliptic Y value at observer"; - arg[ 3 ] = "Heliocentric-Aries-Ecliptic Z value at observer"; - break; - - case AST__HPREQ: - result = "HPREQ"; - *comment = "Helioprojective-Radial to J2000.0 equatorial (FK5)"; - *nargs = 4; - arg[ 0 ] = "Modified Julian Date of observation"; - arg[ 1 ] = "Heliocentric-Aries-Ecliptic X value at observer"; - arg[ 2 ] = "Heliocentric-Aries-Ecliptic Y value at observer"; - arg[ 3 ] = "Heliocentric-Aries-Ecliptic Z value at observer"; - break; - - case AST__EQHPR: - result = "EQHPR"; - *comment = "J2000.0 equatorial (FK5) to Helioprojective-Radial"; - *nargs = 4; - arg[ 0 ] = "Modified Julian Date of observation"; - arg[ 1 ] = "Heliocentric-Aries-Ecliptic X value at observer"; - arg[ 2 ] = "Heliocentric-Aries-Ecliptic Y value at observer"; - arg[ 3 ] = "Heliocentric-Aries-Ecliptic Z value at observer"; - break; - - case AST__HEEQ: - result = "HEEQ"; - *comment = "Helio-ecliptic to equatorial"; - *nargs = 1; - arg[ 0 ] = "Modified Julian Date of observation"; - break; - - case AST__EQHE: - result = "EQHE"; - *comment = "Equatorial to helio-ecliptic"; - *nargs = 1; - arg[ 0 ] = "Modified Julian Date of observation"; - break; - - case AST__J2000H: - result = "J2000H"; - *comment = "J2000 equatorial (dynamical) to ICRS"; - *nargs = 0; - break; - - case AST__HJ2000: - result = "HJ2000"; - *comment = "ICRS to J2000 equatorial (dynamical)"; - *nargs = 0; - break; - - case AST__SLA_DH2E: - result = "H2E"; - *comment = "Horizon to equatorial"; - *nargs = 2; - arg[ 0 ] = "Geodetic latitude of observer"; - arg[ 1 ] = "Magnitude of diurnal aberration vector"; - break; - - case AST__SLA_DE2H: - result = "E2H"; - *comment = "Equatorial to horizon"; - *nargs = 2; - arg[ 0 ] = "Geodetic latitude of observer"; - arg[ 1 ] = "Magnitude of diurnal aberration vector"; - break; - - case AST__R2H: - result = "R2H"; - *comment = "RA to Hour Angle"; - *nargs = 1; - arg[ 0 ] = "Local apparent sidereal time (radians)"; - break; - - case AST__H2R: - result = "H2R"; - *comment = "Hour Angle to RA"; - *nargs = 1; - arg[ 0 ] = "Local apparent sidereal time (radians)"; - break; - - } - -/* Return the result. */ - return result; -} - -static void Earth( double mjd, double earth[3], int *status ) { -/* -*+ -* Name: -* Earth - -* Purpose: -* Returns the AST__HAEC position of the earth at the specified time. - -* Type: -* Private member function. - -* Synopsis: -* #include "slamap.h" -* void Earth( double mjd, double earth[3], int *status ) - -* Class Membership: -* SlaMap method. - -* Description: -* This function returns the AST__HAEC position of the earth at the -* specified time. See astSTPConv for a description of the AST__HAEC -* coordinate systems. - -* Parameters: -* mjd -* Modified Julian date. -* earth -* The AST__HAEC position of the earth at the given date. -*- -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - double dpb[3]; /* Earth position (barycentric) */ - double dph[3]; /* Earth position (heliocentric) */ - double dvb[3]; /* Earth velocity (barycentric) */ - double dvh[3]; /* Earth velocity (heliocentric, AST__HAQC) */ - double ecmat[3][3];/* Equatorial to ecliptic matrix */ - int i; /* Loop count */ - -/* Initialize. */ - for( i = 0; i < 3; i++ ) earth[ i ] = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the position of the earth at the given date in the AST__HAQC coord - system (dph). */ - palEvp( mjd, 2000.0, dvb, dpb, dvh, dph ); - -/* Now rotate the earths position vector into AST__HAEC coords. */ - palEcmat( palEpj2d( 2000.0 ), ecmat ); - palDmxv( ecmat, dph, earth ); - -/* Convert from AU to metres. */ - earth[0] *= AST__AU; - earth[1] *= AST__AU; - earth[2] *= AST__AU; - -} - -static void Hgc( double mjd, double mat[3][3], double offset[3], int *status ) { -/* -*+ -* Name: -* Hgc - -* Purpose: -* Returns matrix and offset for converting AST__HGC positions to AST__HAEC. - -* Type: -* Private member function. - -* Synopsis: -* #include "slamap.h" -* void Hgc( double mjd, double mat[3][3], double offset[3], int *status ) - -* Class Membership: -* SlaMap method. - -* Description: -* This function returns a 3x3 matrix which rotates direction vectors -* given in the AST__HGC system to the AST__HAEC system at the -* specified date. It also returns the position of the origin of the -* AST__HGC system as an AST__HAEC position. See astSTPConv for a -* description of these coordinate systems. - -* Parameters: -* mjd -* Modified Julian date defining the coordinate systems. -* mat -* Matrix which rotates from AST__HGC to AST__HAEC. -* offset -* The origin of the AST__HGC system within the AST__HAEC system. -*- -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - double earth[3]; /* Earth position (heliocentric, AST__HAEC) */ - double len; /* Vector length */ - double xhg[3]; /* Unix X vector of AST__HGC system in AST__HAEC */ - double yhg[3]; /* Unix Y vector of AST__HGC system in AST__HAEC */ - double ytemp[3]; /* Un-normalized Y vector */ - double zhg[3]; /* Unix Z vector of AST__HGC system in AST__HAEC */ - int i; /* Loop count */ - int j; /* Loop count */ - -/* Initialize. */ - for( i = 0; i < 3; i++ ) { - for( j = 0; j < 3; j++ ) { - mat[i][j] = (i==j)?1.0:0.0; - } - offset[ i ] = 0.0; - } - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a unit vector parallel to the solar north pole at the given date. - This vector is expressed in AST__HAEC coords. This is the Z axis of the - AST__HGC system. */ - SolarPole( mjd, zhg, status ); - -/* Get the position of the earth at the given date in the AST__HAEC coord - system. */ - Earth( mjd, earth, status ); - -/* The HG Y axis is perpendicular to both the polar axis and the - sun-earth line. Obtain a Y vector by taking the cross product of the - two vectors, and then normalize it into a unit vector. */ - palDvxv( zhg, earth, ytemp ); - palDvn( ytemp, yhg, &len ); - -/* The HG X axis is perpendicular to both Z and Y, */ - palDvxv( yhg, zhg, xhg ); - -/* The HG X, Y and Z unit vectors form the columns of the required matrix. - The origins of the two systems are co-incident, so return the zero offset - vector initialised earlier. */ - for( i = 0; i < 3; i++ ) { - mat[ i ][ 0 ] = xhg[ i ]; - mat[ i ][ 1 ] = yhg[ i ]; - mat[ i ][ 2 ] = zhg[ i ]; - } - -} - -static void Gsec( double mjd, double mat[3][3], double offset[3], int *status ) { -/* -*+ -* Name: -* Gsec - -* Purpose: -* Returns matrix and offset for converting AST__GSEC positions to AST__HAEC. - -* Type: -* Private member function. - -* Synopsis: -* #include "slamap.h" -* void Gsec( double mjd, double mat[3][3], double offset[3], int *status ) - -* Class Membership: -* SlaMap method. - -* Description: -* This function returns a 3x3 matrix which rotates direction vectors -* given in the AST__GSEC system to the AST__HAEC system at the -* specified date. It also returns the position of the origin of the -* AST__GSEC system as an AST__HAEC position. See astSTPConv for a -* description of these coordinate systems. - -* Parameters: -* mjd -* Modified Julian date defining the coordinate systems. -* mat -* Matrix which rotates from AST__GSEC to AST__HAEC. -* offset -* The origin of the AST__GSEC system within the AST__HAEC system. -*- -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - double earth[3]; /* Earth position (heliocentric, AST__HAEC) */ - double pole[3]; /* Solar pole (AST__HAEC) */ - double len; /* Vector length */ - double xgs[3]; /* Unix X vector of AST__GSEC system in AST__HAEC */ - double ygs[3]; /* Unix Y vector of AST__GSEC system in AST__HAEC */ - double ytemp[3]; /* Un-normalized Y vector */ - double zgs[3]; /* Unix Z vector of AST__GSEC system in AST__HAEC */ - int i; /* Loop count */ - int j; /* Loop count */ - -/* Initialize. */ - for( i = 0; i < 3; i++ ) { - for( j = 0; j < 3; j++ ) { - mat[i][j] = (i==j)?1.0:0.0; - } - offset[ i ] = 0.0; - } - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the position of the earth at the given date in the AST__HAEC coord - system. */ - Earth( mjd, earth, status ); - -/* We need to find unit vectors parallel to the GSEC (X,Y,Z) axes, expressed - in terms of the AST__HAEC (X,Y,Z) axes. The GSEC X axis starts at the - earth and passes through the centre of the sun. This is just the - normalized opposite of the earth's position vector. */ - palDvn( earth, xgs, &len ); - xgs[0] *= -1.0; - xgs[1] *= -1.0; - xgs[2] *= -1.0; - -/* The GSEC Y axis is perpendicular to both the X axis and the ecliptic north - pole vector. So find the ecliptic north pole vector in AST__HAEC coords. */ - pole[ 0 ] = 0.0; - pole[ 1 ] = 0.0; - pole[ 2 ] = 1.0; - -/* Find the GSEC Y axis by taking the vector product of the X axis and - the ecliptic north pole vector, and then normalize it into a unit - vector. */ - palDvxv( pole, xgs, ytemp ); - palDvn( ytemp, ygs, &len ); - -/* The GSEC Z axis is perpendicular to both X and Y axis, and forms a - right-handed system. The resulting vector will be of unit length - since the x and y vectors are both of unit length, and are - perpendicular to each other. It therefore does not need to be - normalized.*/ - palDvxv( xgs, ygs, zgs ); - -/* The GSEC X, Y and Z unit vectors form the columns of the required matrix. */ - for( i = 0; i < 3; i++ ) { - mat[ i ][ 0 ] = xgs[ i ]; - mat[ i ][ 1 ] = ygs[ i ]; - mat[ i ][ 2 ] = zgs[ i ]; - offset[i] = earth[ i ]; - } - -} - -static void Haec( double mjd, double mat[3][3], double offset[3], int *status ) { -/* -*+ -* Name: -* Haec - -* Purpose: -* Returns matrix and offset for converting AST__HAEC positions to AST__HAEC. - -* Type: -* Private member function. - -* Synopsis: -* #include "slamap.h" -* void Haec( double mjd, double mat[3][3], double offset[3], int *status ) - -* Class Membership: -* SlaMap method. - -* Description: -* This function returns a 3x3 matrix which rotates direction vectors -* given in the AST__HAEC system to the AST__HAEC system at the -* specified date. It also returns the position of the origin of the -* AST__HAEC system as an AST__HAEC position. See astSTPConv for a -* description of these coordinate systems. - -* Parameters: -* mjd -* Modified Julian date defining the coordinate systems. -* mat -* Matrix which rotates from AST__HAEC to AST__HAEC. -* offset -* The origin of the AST__HAEC system within the AST__HAEC system. -*- -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int i; /* Loop count */ - int j; /* Loop count */ - -/* Return an identity matrix and a zero offset vector. */ - for( i = 0; i < 3; i++ ) { - for( j = 0; j < 3; j++ ) { - mat[i][j] = (i==j)?1.0:0.0; - } - offset[ i ] = 0.0; - } - -} - -static void Haqc( double mjd, double mat[3][3], double offset[3], int *status ) { -/* -*+ -* Name: -* Haqc - -* Purpose: -* Returns matrix and offset for converting AST__HAQC positions to AST__HAEC. - -* Type: -* Private member function. - -* Synopsis: -* #include "slamap.h" -* void Haqc( double mjd, double mat[3][3], double offset[3], int *status ) - -* Class Membership: -* SlaMap method. - -* Description: -* This function returns a 3x3 matrix which rotates direction vectors -* given in the AST__HAQC system to the AST__HAEC system at the -* specified date. It also returns the position of the origin of the -* AST__HAQC system as an AST__HAEC position. See astSTPConv for a -* description of these coordinate systems. - -* Parameters: -* mjd -* Modified Julian date defining the coordinate systems. -* mat -* Matrix which rotates from AST__HAQC to AST__HAEC. -* offset -* The origin of the AST__HAQC system within the AST__HAEC system. -*- -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int i; /* Loop count */ - int j; /* Loop count */ - -/* Initialise an identity matrix and a zero offset vector. */ - for( i = 0; i < 3; i++ ) { - for( j = 0; j < 3; j++ ) { - mat[i][j] = (i==j)?1.0:0.0; - } - offset[ i ] = 0.0; - } - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Return the required matrix. */ - palEcmat( palEpj2d( 2000.0 ), mat ); - return; -} - -static void Hpcc( double mjd, double obs[3], double mat[3][3], double offset[3], int *status ) { -/* -*+ -* Name: -* Hpcc - -* Purpose: -* Returns matrix and offset for converting AST__HPCC positions to -* AST__HAEC. - -* Type: -* Private member function. - -* Synopsis: -* #include "slamap.h" -* void Hpcc( double mjd, double obs[3], double mat[3][3], double offset[3], int *status ) - -* Class Membership: -* SlaMap method. - -* Description: -* This function returns a 3x3 matrix which rotates direction vectors -* given in the AST__HPCC system to the AST__HAEC system at the -* specified date. It also returns the position of the origin of the -* AST__HPCC system as an AST__HAEC position. See astSTPConv for a -* description of these coordinate systems. - -* Parameters: -* mjd -* Modified Julian date defining the coordinate systems. -* obs -* The observers position, in AST__HAEC, or NULL if the observer is -* at the centre of the earth. -* mat -* Matrix which rotates from AST__HPCC to AST__HAEC. -* offset -* The origin of the AST__HPCC system within the AST__HAEC system. -*- -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - double earth[3]; /* Earth position (heliocentric, AST__HAEC) */ - double pole[3]; /* Solar pole vector (AST__HAEC) */ - double len; /* Vector length */ - double xhpc[3]; /* Unix X vector of AST__HPCC system in AST__HAEC */ - double yhpc[3]; /* Unix Y vector of AST__HPCC system in AST__HAEC */ - double ytemp[3]; /* Un-normalized Y vector */ - double zhpc[3]; /* Unix Z vector of AST__HPCC system in AST__HAEC */ - int i; /* Loop count */ - int j; /* Loop count */ - -/* Initialize. */ - for( i = 0; i < 3; i++ ) { - for( j = 0; j < 3; j++ ) { - mat[i][j] = (i==j)?1.0:0.0; - } - offset[i] = 0.0; - } - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If no observers position was supplied, use the position of the earth - at the specified date in AST__HAEC coords. */ - if( !obs ) { - Earth( mjd, earth, status ); - obs = earth; - } - -/* We need to find unit vectors parallel to the HPCC (X,Y,Z) axes, expressed - in terms of the AST__HAEC (X,Y,Z) axes. The HPCC X axis starts at the - observer and passes through the centre of the sun. This is just the - normalized opposite of the supplied observer's position vector. */ - palDvn( obs, xhpc, &len ); - xhpc[0] *= -1.0; - xhpc[1] *= -1.0; - xhpc[2] *= -1.0; - -/* The HPC Y axis is perpendicular to both the X axis and the solar north - pole vector. So find the solar north pole vector in AST__HAEC coords. */ - SolarPole( mjd, pole, status ); - -/* Find the HPC Y axis by taking the vector product of the X axis and - the solar north pole vector, and then normalize it into a unit vector. - Note, HPC (X,Y,Z) axes form a left-handed system! */ - palDvxv( xhpc, pole, ytemp ); - palDvn( ytemp, yhpc, &len ); - -/* The HPC Z axis is perpendicular to both X and Y axis, and forms a - left-handed system. The resulting vector will be of unit length - since the x and y vectors are both of unit length, and are - perpendicular to each other. It therefore does not need to be - normalized.*/ - palDvxv( yhpc, xhpc, zhpc ); - -/* The HPC X, Y and Z unit vectors form the columns of the required matrix. */ - for( i = 0; i < 3; i++ ) { - mat[ i ][ 0 ] = xhpc[ i ]; - mat[ i ][ 1 ] = yhpc[ i ]; - mat[ i ][ 2 ] = zhpc[ i ]; - offset[i] = obs[ i ]; - } - -} - -static void Hprc( double mjd, double obs[3], double mat[3][3], double offset[3], int *status ) { -/* -*+ -* Name: -* Hprc - -* Purpose: -* Returns matrix and offset for converting AST__HPRC positions to -* AST__HAEC. - -* Type: -* Private member function. - -* Synopsis: -* #include "slamap.h" -* void Hprc( double mjd, double obs[3], double mat[3][3], double offset[3], int *status ) - -* Class Membership: -* SlaMap method. - -* Description: -* This function returns a 3x3 matrix which rotates direction vectors -* given in the AST__HPRC system to the AST__HAEC system at the -* specified date. It also returns the position of the origin of the -* AST__HPRC system as an AST__HAEC position. See astSTPConv for a -* description of these coordinate systems. - -* Parameters: -* mjd -* Modified Julian date defining the coordinate systems. -* obs -* The observers position, in AST__HAEC, or NULL if the observer is -* at the centre of the earth. -* mat -* Matrix which rotates from AST__HPRC to AST__HAEC. -* offset -* The origin of the AST__HPRC system within the AST__HAEC system. -*- -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - double pole[3]; /* Solar pole (AST__HAEC) */ - double earth[3]; /* Earth position (heliocentric, AST__HAEC) */ - double len; /* Vector length */ - double xhpr[3]; /* Unix X vector of AST__HPRC system in AST__HAEC */ - double yhpr[3]; /* Unix Y vector of AST__HPRC system in AST__HAEC */ - double ytemp[3]; /* Un-normalized Y vector */ - double zhpr[3]; /* Unix Z vector of AST__HPRC system in AST__HAEC */ - int i; /* Loop count */ - int j; /* Loop count */ - -/* Initialize. */ - for( i = 0; i < 3; i++ ) { - for( j = 0; j < 3; j++ ) { - mat[i][j] = (i==j)?1.0:0.0; - } - offset[i] = 0.0; - } - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If no observers position was supplied, use the position of the earth - at the specified date in AST__HAEC coords. */ - if( !obs ) { - Earth( mjd, earth, status ); - obs = earth; - } - -/* We need to find unit vectors parallel to the HPRC (X,Y,Z) axes, expressed - in terms of the AST__HAEC (X,Y,Z) axes. The HPRC Z axis starts at the - observer and passes through the centre of the sun. This is just the - normalized opposite of the supplied observer's position vector. */ - palDvn( obs, zhpr, &len ); - zhpr[0] *= -1.0; - zhpr[1] *= -1.0; - zhpr[2] *= -1.0; - -/* The HPR Y axis is perpendicular to both the Z axis and the solar north - pole vector. So find the solar north pole vector in AST__HAEC coords. */ - SolarPole( mjd, pole, status ); - -/* Find the HPR Y axis by taking the vector product of the Z axis and - the solar north pole vector, and then normalize it into a unit vector. - Note, HPR (X,Y,Z) axes form a left-handed system! */ - palDvxv( pole, zhpr, ytemp ); - palDvn( ytemp, yhpr, &len ); - -/* The HPRC X axis is perpendicular to both Y and Z axis, and forms a - left-handed system. The resulting vector will be of unit length - since the y and z vectors are both of unit length, and are - perpendicular to each other. It therefore does not need to be - normalized.*/ - palDvxv( zhpr, yhpr, xhpr ); - -/* The HPRC X, Y and Z unit vectors form the columns of the required matrix. */ - for( i = 0; i < 3; i++ ) { - mat[ i ][ 0 ] = xhpr[ i ]; - mat[ i ][ 1 ] = yhpr[ i ]; - mat[ i ][ 2 ] = zhpr[ i ]; - offset[ i ] = obs[ i ]; - } -} - -static void J2000H( int forward, int npoint, double *alpha, double *delta, int *status ){ -/* -* Name: -* J2000H - -* Purpose: -* Convert dynamical J2000 equatorial coords to ICRS. - -* Type: -* Private member function. - -* Synopsis: -* #include "slamap.h" -* void J2000H( int forward, int npoint, double *alpha, double *delta, int *status ) - -* Class Membership: -* SlaMap method. - -* Description: -* This function converts the supplied dynamical J2000 equatorial coords -* to ICRS (or vice-versa). - -* Parameters: -* forward -* Do forward transformation? -* npoint -* Number of points to transform. -* alpha -* Pointer to longitude values. -* delta -* Pointer to latitude values. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - int i; /* Loop count */ - double rmat[3][3]; /* J2000 -> ICRS rotation matrix */ - double v1[3]; /* J2000 vector */ - double v2[3]; /* ICRS vector */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the J2000 to ICRS rotation matrix (supplied by P.T. Wallace) */ - palDeuler( "XYZ", -0.0068192*AS2R, 0.0166172*AS2R, 0.0146000*AS2R, - rmat ); - -/* Loop round all points. */ - for( i = 0; i < npoint; i++ ) { - -/* Convert from (alpha,delta) to 3-vector */ - palDcs2c( alpha[ i ], delta[ i ], v1 ); - -/* Rotate the 3-vector */ - if( forward ) { - palDmxv( rmat, v1, v2 ); - } else { - palDimxv( rmat, v1, v2 ); - } - -/* Convert from 3-vector to (alpha,delta) */ - palDcc2s( v2, alpha + i, delta + i ); - } -} - -void astSTPConv1_( double mjd, int in_sys, double in_obs[3], double in[3], - int out_sys, double out_obs[3], double out[3], int *status ){ -/* -*+ -* Name: -* astSTPConv1 - -* Purpose: -* Converts a 3D solar system position between specified STP coordinate -* systems. - -* Type: -* Protected function. - -* Synopsis: -* #include "slamap.h" -* void astSTPConv1( double mjd, int in_sys, double in_obs[3], -* double in[3], int out_sys, double out_obs[3], -* double out[3] ) - -* Class Membership: -* Frame method. - -* Description: -* This function converts a single 3D solar-system position from the -* specified input coordinate system to the specified output coordinate -* system. See astSTPConv for a list of supported coordinate systems. - -* Parameters: -* mjd -* The Modified Julian Date to which the coordinate systems refer. -* in_sys -* The coordinate system in which the input positions are supplied. -* in_obs -* The position of the observer in AST__HAEC coordinates. This is only -* needed if the input system is an observer-centric system. If this -* is not the case, a NULL pointer can be supplied. A NULL pointer -* can also be supplied to indicate that he observer is at the centre of -* the earth at the specified date. -* in -* A 3-element array holding the input position. -* out_sys -* The coordinate system in which the input positions are supplied. -* out_obs -* The position of the observer in AST__HAEC coordinates. This is only -* needed if the output system is an observer-centric system. If this -* is not the case, a NULL pointer can be supplied. A NULL pointer -* can also be supplied to indicate that he observer is at the centre of -* the earth at the specified date. -* out -* A 3-element array holding the output position. - -* Notes: -* - The "in" and "out" arrays may safely point to the same memory. -* - Output longitude values are always in the range 0 - 2.PI. - -*- -*/ - -/* Local Variables: */ - double *ins[ 3 ]; /* The input position */ - double *outs[ 3 ]; /* The output position */ - -/* Store pointers to the supplied arrays suitable for passing to STPConv. */ - ins[ 0 ] = in; - ins[ 1 ] = in + 1; - ins[ 2 ] = in + 2; - outs[ 0 ] = out; - outs[ 1 ] = out + 1; - outs[ 2 ] = out + 2; - -/* Convert the position. */ - STPConv( mjd, 0, 1, in_sys, in_obs, ins, out_sys, out_obs, outs, status ); - -} - -void astSTPConv_( double mjd, int n, int in_sys, double in_obs[3], - double *in[3], int out_sys, double out_obs[3], - double *out[3], int *status ){ -/* -*+ -* Name: -* astSTPConv - -* Purpose: -* Converts a set of 3D solar system positions between specified STP -* coordinate systems. - -* Type: -* Protected function. - -* Synopsis: -* #include "slamap.h" -* void astSTPConv( double mjd, int n, int in_sys, double in_obs[3], -* double *in[3], int out_sys, double out_obs[3], -* double *out[3] ) - -* Class Membership: -* Frame method. - -* Description: -* This function converts a set of 3D solar-system positions from -* the specified input coordinate system to the specified output -* coordinate system. - -* Parameters: -* mjd -* The Modified Julian Date to which the coordinate systems refer. -* in_sys -* The coordinate system in which the input positions are supplied -* (see below). -* in_obs -* The position of the observer in AST__HAEC coordinates. This is only -* needed if the input system is an observer-centric system. If this -* is not the case, a NULL pointer can be supplied. A NULL pointer -* can also be supplied to indicate that he observer is at the centre of -* the earth at the specified date. -* in -* A 3-element array holding the input positions. Each of the 3 -* elements should point to an array of "n" axis values. For spherical -* input systems, in[3] can be supplied as NULL, in which case a -* constant value of 1 AU will be used. -* out_sys -* The coordinate system in which the input positions are supplied -* (see below). -* out_obs -* The position of the observer in AST__HAEC coordinates. This is only -* needed if the output system is an observer-centric system. If this -* is not the case, a NULL pointer can be supplied. A NULL pointer -* can also be supplied to indicate that he observer is at the centre of -* the earth at the specified date. -* out -* A 3-element array holding the output positions. Each of the 3 -* elements should point to an array of "n" axis values. If in[3] is -* NULL, no values will be assigned to out[3]. - -* Notes: -* - The "in" and "out" arrays may safely point to the same memory. -* - Output longitude values are always in the range 0 - 2.PI. - -* Supported Coordinate Systems: -* Coordinate systems are either spherical or Cartesian, and are right -* handed (unless otherwise indicated). Spherical systems use axis 0 for -* longitude, axis 1 for latitude, and axis 2 for radius. Cartesian systems -* use 3 mutually perpendicular axes; X is axis 0 and points towards the -* intersection of the equator and the zero longitude meridian of the -* corresponding spherical system, Y is axis 1 and points towards longitude -* of +90 degrees, Z is axis 2 and points twowards the north pole. All -* angles are in radians and all distances are in metres. The following -* systems are supported: -* -* - AST__HAE: Heliocentric-aries-ecliptic spherical coordinates. Centred -* at the centre of the sun. The north pole points towards the J2000 -* ecliptic north pole, and meridian of zero longitude includes the -* J2000 equinox. -* -* - AST__HAEC: Heliocentric-aries-ecliptic cartesian coordinates. Origin -* at the centre of the sun. The Z axis points towards the J2000 ecliptic -* north pole, and the X axis points towards the J2000 equinox. -* -* - AST__HAQ: Heliocentric-aries-equatorial spherical coordinates. Centred -* at the centre of the sun. The north pole points towards the FK5 J2000 -* equatorial north pole, and meridian of zero longitude includes the -* FK5 J2000 equinox. -* -* - AST__HAQC: Heliocentric-aries-equatorial cartesian coordinates. Origin -* at the centre of the sun. The Z axis points towards the FK5 J2000 -* equatorial north pole, and the X axis points towards the FK5 J2000 -* equinox. -* -* - AST__HG: Heliographic spherical coordinates. Centred at the centre of -* the sun. North pole points towards the solar north pole at the given -* date. The meridian of zero longitude includes the sun-earth line at -* the given date. -* -* - AST__HGC: Heliographic cartesian coordinates. Origin at the centre of -* the sun. The Z axis points towards the solar north pole at the given -* date. The X axis is in the plane spanned by the Z axis, and the -* sun-earth line at the given date. -* -* - AST__HPC: Helioprojective-cartesian spherical coordinates. A -* left-handed system (that is, longitude increases westwards), centred -* at the specified observer position. The intersection of the -* zero-longitude meridian and the equator coincides with the centre of -* the sun as seen from the observers position. The zero longitude -* meridian includes the solar north pole at the specified date. -* -* - AST__HPCC: Helioprojective-cartesian cartesian coordinates. A -* left-handed system with origin at the specified observer position. The -* X axis points towards the centre of the sun as seen from the observers -* position. The X-Z plane includes the solar north pole at the specified -* date. -* -* - AST__HPR: Helioprojective-radial spherical coordinates. A left-handed -* system (that is, longitude increases westwards), centred at the -* specified observer position. The north pole points towards the centre -* of the sun as seen from the observers position. The zero longitude -* meridian includes the solar north pole at the specified date. -* -* - AST__HPRC: Helioprojective-radial cartesian coordinates. A left-handed -* system with origin at the specified observer position. The Z axis points -* towards the centre of the sun as seen from the observers position. The -* X-Z plane includes the solar north pole at the specified date. -* -* - AST__GSE: Geocentric-solar-ecliptic spherical coordinates. Centred at -* the centre of the earth at the given date. The north pole points towards -* the J2000 ecliptic north pole, and the meridian of zero longitude -* includes the Sun. -* -* - AST__GSEC: Geocentric-solar-ecliptic cartesian coordinates. Origin at -* the centre of the earth at the given date. The X axis points towards the -* centre of sun, and the X-Z plane contains the J2000 ecliptic north -* pole. Since the earth may not be exactly in the mean ecliptic of -* J2000, the Z axis will not in general correspond exactly to the -* ecliptic north pole. -*- -*/ - STPConv( mjd, 0, n, in_sys, in_obs, in, out_sys, out_obs, out, status ); -} - -static void STPConv( double mjd, int ignore_origins, int n, int in_sys, - double in_obs[3], double *in[3], int out_sys, - double out_obs[3], double *out[3], int *status ){ -/* -* Name: -* STPConv - -* Purpose: -* Convert a set of 3D solar system positions between specified STP -* coordinate systems. - -* Type: -* Private member function. - -* Synopsis: -* #include "slamap.h" -* void STPConv( double mjd, int ignore_origins, int n, int in_sys, -* double in_obs[3], double *in[3], int out_sys, -* double out_obs[3], double *out[3], int *status ){ - -* Class Membership: -* Frame method. - -* Description: -* This function converts a set of 3D solar-system positions from -* the specified input coordinate system to the specified output -* coordinate system. See astSTPConv for a list of the available -* coordinate systems. - -* Parameters: -* mjd -* The Modified Julian Date to which the coordinate systems refer. -* ignore_origins -* If non-zero, then the coordinate system definitions are modified so -* that all cartesian systems have the origin at the centre of the -* Sun. If zero, the correct origins are used for each individual -* system. -* n -* The number of positions to transform. -* in_sys -* The coordinate system in which the input positions are supplied -* in_obs -* The position of the observer in AST__HAEC coordinates. This is only -* needed if the input system is an observer-centric system. If this -* is not the case, a NULL pointer can be supplied. A NULL pointer -* can also be supplied to indicate that he observer is at the centre of -* the earth at the specified date. -* in -* A 3-element array holding the input positions. Each of the 3 -* elements should point to an array of "n" axis values. For spherical -* input systems, in[3] can be supplied as NULL, in which case a -* constant value of 1 AU will be used. -* out_sys -* The coordinate system in which the input positions are supplied -* (see "Supported Coordinate Systems" below). -* out_obs -* The position of the observer in AST__HAEC coordinates. This is only -* needed if the output system is an observer-centric system. If this -* is not the case, a NULL pointer can be supplied. A NULL pointer -* can also be supplied to indicate that he observer is at the centre of -* the earth at the specified date. -* out -* A 3-element array holding the input positions. Each of the 3 -* elements should point to an array of "n" axis values. For spherical -* output coordinates, out[2] may be NULL, in which case the output -* radius values are thrown away. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Output longitude values are always in the range 0 - 2.PI. -* - The "in" and "out" arrays may safely point to the same memory. -* - The contents of the output array is left unchanged if an error -* has already occurred. -*/ - -/* Local Variables: */ - double *out2; /* Pointer to output third axis values */ - double *px; /* Pointer to next X axis value */ - double *py; /* Pointer to next Y axis value */ - double *pz; /* Pointer to next Z axis value */ - double lat; /* Latitude value */ - double lng; /* Longitude value */ - double mat1[3][3]; /* Input->HAEC rotation matrix */ - double mat2[3][3]; /* Output->HAEC rotation matrix */ - double mat3[3][3]; /* HAEC->output rotation matrix */ - double mat4[3][3]; /* Input->output rotation matrix */ - double off1[3]; /* Origin of input system in HAEC coords */ - double off2[3]; /* Origin of output system in HAEC coords */ - double off3[3]; /* HAEC vector from output origin to input origin */ - double off4[3]; /* Position of input origin within output system */ - double p[3]; /* Current position */ - double q[3]; /* New position */ - double radius; /* Radius value */ - int cur_sys; /* Current system for output values */ - int i; /* Loop count */ - int j; /* Loop count */ - int inCsys; /* Input cartesian system */ - int outCsys; /* Output cartesian system */ - size_t nbyte; /* Amount of memory to copy */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If out[2] was supplied as null, allocate memory to hold third axis - values. Otherwise, use the supplied array. */ - nbyte = n*sizeof( double ); - if( !out[2] ) { - out2 = (double *) astMalloc( nbyte ); - } else { - out2 = out[2]; - } - -/* Copy the input data to the output data and note that the output values - are currently in the same system as the input values. */ - memcpy ( out[ 0 ], in[ 0 ], nbyte ); - memcpy ( out[ 1 ], in[ 1 ], nbyte ); - if( in[2] ) { - memcpy ( out2, in[ 2 ], nbyte ); - } else { - for( i = 0; i < n; i++ ) out2[ i ] = AST__AU; - } - cur_sys = in_sys; - -/* Skip the next bit if the output values are now in the required system. */ - if( cur_sys != out_sys ) { - -/* If the current system is spherical note the corresponding cartesian - system. If the current system is cartesian, use it. */ - if( cur_sys == AST__HG ){ - inCsys = AST__HGC; - } else if( cur_sys == AST__HAQ ){ - inCsys = AST__HAQC; - } else if( cur_sys == AST__HAE ){ - inCsys = AST__HAEC; - } else if( cur_sys == AST__GSE ){ - inCsys = AST__GSEC; - } else if( cur_sys == AST__HPC ){ - inCsys = AST__HPCC; - } else if( cur_sys == AST__HPR ){ - inCsys = AST__HPRC; - } else { - inCsys = cur_sys; - } - -/* Convert input spherical positions into the corresponding cartesian system, - putting the results in the "out" arrays. Modify the input system - accordingly. */ - if( cur_sys != inCsys ) { - px = out[ 0 ]; - py = out[ 1 ]; - pz = out2; - for( i = 0; i < n; i++ ) { - p[ 0 ] = *px; - p[ 1 ] = *py; - p[ 2 ] = *pz; - if( p[ 0 ] != AST__BAD && - p[ 1 ] != AST__BAD && - p[ 2 ] != AST__BAD ) { - palDcs2c( p[ 0 ], p[ 1 ], q ); - *(px++) = q[ 0 ]*p[ 2 ]; - *(py++) = q[ 1 ]*p[ 2 ]; - *(pz++) = q[ 2 ]*p[ 2 ]; - } else { - *(px++) = AST__BAD; - *(py++) = AST__BAD; - *(pz++) = AST__BAD; - } - } - - cur_sys = inCsys; - - } - } - -/* Skip the next bit if the output values are now in the required system. */ - if( cur_sys != out_sys ) { - -/* If the required output system is spherical, note the corresponding - cartesian system. If the required output system is cartesian, use it.*/ - if( out_sys == AST__HG ){ - outCsys = AST__HGC; - } else if( out_sys == AST__HAQ ){ - outCsys = AST__HAQC; - } else if( out_sys == AST__HAE ){ - outCsys = AST__HAEC; - } else if( out_sys == AST__GSE ){ - outCsys = AST__GSEC; - } else if( out_sys == AST__HPC ){ - outCsys = AST__HPCC; - } else if( out_sys == AST__HPR ){ - outCsys = AST__HPRC; - } else { - outCsys = out_sys; - } - -/* Skip the next bit if the output values are already in the required - output cartesian system. */ - if( cur_sys != outCsys ) { - -/* Obtain an offset vector and a rotation matrix which moves positions from - the current (Cartesian) system to the AST__HAEC system. The offset vector - returned by these functions is the AST__HAEC coordinates of the origin of - the current system. The matrix rotates direction vectors from the current - system to the AST__HAEC system. */ - if( cur_sys == AST__HGC ) { - Hgc( mjd, mat1, off1, status ); - - } else if( cur_sys == AST__HAEC ) { - Haec( mjd, mat1, off1, status ); - - } else if( cur_sys == AST__HAQC ) { - Haqc( mjd, mat1, off1, status ); - - } else if( cur_sys == AST__GSEC ) { - Gsec( mjd, mat1, off1, status ); - - } else if( cur_sys == AST__HPCC ) { - Hpcc( mjd, in_obs, mat1, off1, status ); - - } else if( cur_sys == AST__HPRC ) { - Hprc( mjd, in_obs, mat1, off1, status ); - - } else { - astError( AST__INTER, "astSTPConv(SlaMap): Unsupported input " - "cartesian coordinate system type %d (internal AST " - "programming error).", status, cur_sys ); - } - -/* Obtain an offset vector and a rotation matrix which moves positions from - the required output Cartesian system to the AST__HAEC system. */ - if( outCsys == AST__HGC ) { - Hgc( mjd, mat2, off2, status ); - - } else if( outCsys == AST__HAEC ) { - Haec( mjd, mat2, off2, status ); - - } else if( outCsys == AST__HAQC ) { - Haqc( mjd, mat2, off2, status ); - - } else if( outCsys == AST__GSEC ) { - Gsec( mjd, mat2, off2, status ); - - } else if( outCsys == AST__HPCC ) { - Hpcc( mjd, out_obs, mat2, off2, status ); - - } else if( outCsys == AST__HPRC ) { - Hprc( mjd, out_obs, mat2, off2, status ); - - } else { - astError( AST__INTER, "astSTPConv(SlaMap): Unsupported output " - "cartesian coordinate system type %d (internal AST " - "programming error).", status, outCsys ); - } - -/* Invert the second matrix to get the matrix which rotates AST__HAEC coords - to the output cartesian system. This an be done simply by transposing it - since all the matrices are 3D rotations. */ - for( i = 0; i < 3; i++ ) { - for( j = 0; j < 3; j++ ) mat3[ i ][ j ] = mat2[ j ][ i ]; - -/* Find the offset in AST__HAEC coords from the origin of the output - cartesian system to the origin of the current system. */ - off3[ i ] = off1[ i ] - off2[ i ]; - } - -/* Unless the origins are being ignored, use the above matrix to rotate the - above AST__HAEC offset into the output cartesian system. If origins are - being ignored, use an offset of zero. */ - if( ignore_origins ) { - off4[ 0 ] = 0.0; - off4[ 1 ] = 0.0; - off4[ 2 ] = 0.0; - } else { - palDmxv( mat3, off3, off4 ); - } - -/* Concatentate the two matrices to get the matrix which rotates from the - current system to the output cartesian system. */ - palDmxm( mat3, mat1, mat4 ); - -/* Use the matrix and offset to convert current positions to output - cartesian positions. */ - px = out[ 0 ]; - py = out[ 1 ]; - pz = out2; - - for( i = 0; i < n; i++ ) { - p[ 0 ] = *px; - p[ 1 ] = *py; - p[ 2 ] = *pz; - - if( p[ 0 ] != AST__BAD && - p[ 1 ] != AST__BAD && - p[ 2 ] != AST__BAD ) { - palDmxv( mat4, p, q ); - *(px++) = q[ 0 ] + off4[ 0 ]; - *(py++) = q[ 1 ] + off4[ 1 ]; - *(pz++) = q[ 2 ] + off4[ 2 ]; - } else { - *(px++) = AST__BAD; - *(py++) = AST__BAD; - *(pz++) = AST__BAD; - } - } - -/* Indicate that the output values are now in the required output - cartesian system. */ - cur_sys = outCsys; - - } - } - -/* Skip the next bit if the output values are now in the required system. */ - if( cur_sys != out_sys ) { - -/* The only reason why the output values may not be in the required output - system is because the output system is spherical. Convert output Cartesian - positions to output spherical positions. */ - px = out[ 0 ]; - py = out[ 1 ]; - pz = out2; - for( i = 0; i < n; i++ ) { - p[ 0 ] = *px; - p[ 1 ] = *py; - p[ 2 ] = *pz; - if( p[ 0 ] != AST__BAD && - p[ 1 ] != AST__BAD && - p[ 2 ] != AST__BAD ) { - palDvn( p, q, &radius ); - palDcc2s( q, &lng, &lat ); - *(px++) = palDranrm( lng ); - *(py++) = lat; - *(pz++) = radius; - } else { - *(px++) = AST__BAD; - *(py++) = AST__BAD; - *(pz++) = AST__BAD; - } - } - } - -/* If out[2] was supplied as null, free the memory used to hold third axis - values. */ - if( !out[2] ) out2 = (double *) astFree( (void *) out2 ); -} - -void astInitSlaMapVtab_( AstSlaMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSlaMapVtab - -* Purpose: -* Initialise a virtual function table for a SlaMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "slamap.h" -* void astInitSlaMapVtab( AstSlaMapVtab *vtab, const char *name ) - -* Class Membership: -* SlaMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SlaMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASlaMap) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->SlaAdd = SlaAdd; - vtab->SlaIsEmpty = SlaIsEmpty; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "SlaMap", - "Conversion between sky coordinate systems" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing an SlaMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* SlaMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated SlaMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated SlaMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated SlaMap which is to be merged with -* its neighbours. This should be a cloned copy of the SlaMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* SlaMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated SlaMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *new; /* Pointer to replacement Mapping */ - AstSlaMap *slamap; /* Pointer to SlaMap */ - const char *argdesc[ MAX_SLA_ARGS ]; /* Argument descriptions (junk) */ - const char *class; /* Pointer to Mapping class string */ - const char *comment; /* Pointer to comment string (junk) */ - double (*cvtargs)[ MAX_SLA_ARGS ]; /* Pointer to argument arrays */ - int *cvttype; /* Pointer to transformation type codes */ - int *narg; /* Pointer to argument count */ - int done; /* Finished (no further simplification)? */ - int iarg; /* Loop counter for arguments */ - int icvt1; /* Loop initial value */ - int icvt2; /* Loop final value */ - int icvt; /* Loop counter for transformation steps */ - int ikeep; /* Index to store step being kept */ - int imap1; /* Index of first SlaMap to merge */ - int imap2; /* Index of last SlaMap to merge */ - int imap; /* Loop counter for Mappings */ - int inc; /* Increment for transformation step loop */ - int invert; /* SlaMap applied in inverse direction? */ - int istep; /* Loop counter for transformation steps */ - int keep; /* Keep transformation step? */ - int ngone; /* Number of Mappings eliminated */ - int nstep0; /* Original number of transformation steps */ - int nstep; /* Total number of transformation steps */ - int result; /* Result value to return */ - int simpler; /* Simplification possible? */ - int unit; /* Replacement Mapping is a UnitMap? */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* SlaMaps can only be merged if they are in series (or if there is - only one Mapping present, in which case it makes no difference), so - do nothing if they are not. */ - if ( series || ( *nmap == 1 ) ) { - -/* Initialise the number of transformation steps to be merged to equal - the number in the nominated SlaMap. */ - nstep = ( (AstSlaMap *) ( *map_list )[ where ] )->ncvt; - -/* Search adjacent lower-numbered Mappings until one is found which is - not an SlaMap. Accumulate the number of transformation steps - involved in any SlaMaps found. */ - imap1 = where; - while ( ( imap1 - 1 >= 0 ) && astOK ) { - class = astGetClass( ( *map_list )[ imap1 - 1 ] ); - if ( !astOK || strcmp( class, "SlaMap" ) ) break; - nstep += ( (AstSlaMap *) ( *map_list )[ imap1 - 1 ] )->ncvt; - imap1--; - } - -/* Similarly search adjacent higher-numbered Mappings. */ - imap2 = where; - while ( ( imap2 + 1 < *nmap ) && astOK ) { - class = astGetClass( ( *map_list )[ imap2 + 1 ] ); - if ( !astOK || strcmp( class, "SlaMap" ) ) break; - nstep += ( (AstSlaMap *) ( *map_list )[ imap2 + 1 ] )->ncvt; - imap2++; - } - -/* Remember the initial number of transformation steps. */ - nstep0 = nstep; - -/* Allocate memory for accumulating a list of all the transformation - steps involved in all the SlaMaps found. */ - cvttype = astMalloc( sizeof( int ) * (size_t) nstep ); - cvtargs = astMalloc( sizeof( double[ MAX_SLA_ARGS ] ) * (size_t) nstep ); - narg = astMalloc( sizeof( int ) * (size_t) nstep ); - -/* Loop to obtain the transformation data for each SlaMap being merged. */ - nstep = 0; - for ( imap = imap1; astOK && ( imap <= imap2 ); imap++ ) { - -/* Obtain a pointer to the SlaMap and note if it is being applied in - its inverse direction. */ - slamap = (AstSlaMap *) ( *map_list )[ imap ]; - invert = ( *invert_list )[ imap ]; - -/* Set up loop limits and an increment to scan the transformation - steps in each SlaMap in either the forward or reverse direction, as - dictated by the associated "invert" value. */ - icvt1 = invert ? slamap->ncvt - 1 : 0; - icvt2 = invert ? -1 : slamap->ncvt; - inc = invert ? -1 : 1; - -/* Loop through each transformation step in the SlaMap. */ - for ( icvt = icvt1; icvt != icvt2; icvt += inc ) { - -/* For simplicity, free any extra information stored with the conversion - step (it will be recreated as and when necessary). */ - slamap->cvtextra[ icvt ] = astFree( slamap->cvtextra[ icvt ] ); - -/* Store the transformation type code and use "CvtString" to determine - the associated number of arguments. Then store these arguments. */ - cvttype[ nstep ] = slamap->cvttype[ icvt ]; - (void) CvtString( cvttype[ nstep ], &comment, narg + nstep, - argdesc, status ); - if ( !astOK ) break; - for ( iarg = 0; iarg < narg[ nstep ]; iarg++ ) { - cvtargs[ nstep ][ iarg ] = slamap->cvtargs[ icvt ][ iarg ]; - } - -/* If the SlaMap is inverted, we must not only accumulate its - transformation steps in reverse, but also apply them in - reverse. For some steps this means swapping arguments, for some it - means changing the transformation type code to a complementary - value, and for others it means both. Define macros to perform each - of these changes. */ - -/* Macro to swap the values of two nominated arguments if the - transformation type code matches "code". */ -#define SWAP_ARGS( code, arg1, arg2 ) \ - if ( cvttype[ nstep ] == code ) { \ - double tmp = cvtargs[ nstep ][ arg1 ]; \ - cvtargs[ nstep ][ arg1 ] = cvtargs[ nstep ][ arg2 ]; \ - cvtargs[ nstep ][ arg2 ] = tmp; \ - } - -/* Macro to exchange a transformation type code for its inverse (and - vice versa). */ -#define SWAP_CODES( code1, code2 ) \ - if ( cvttype[ nstep ] == code1 ) { \ - cvttype[ nstep ] = code2; \ - } else if ( cvttype[ nstep ] == code2 ) { \ - cvttype[ nstep ] = code1; \ - } - -/* Use these macros to apply the changes where needed. */ - if ( invert ) { - -/* E-terms of aberration. */ -/* ---------------------- */ -/* Exchange addition and subtraction of E-terms. */ - SWAP_CODES( AST__SLA_ADDET, AST__SLA_SUBET ) - -/* Bessel-Newcomb pre-IAU 1976 (FK4) precession model. */ -/* --------------------------------------------------- */ -/* Exchange the starting and ending Besselian epochs. */ - SWAP_ARGS( AST__SLA_PREBN, 0, 1 ) - -/* IAU 1975 (FK5) precession model. */ -/* -------------------------------- */ -/* Exchange the starting and ending epochs. */ - SWAP_ARGS( AST__SLA_PREC, 0, 1 ) - -/* FK4 to FK5 (no proper motion or parallax). */ -/* ------------------------------------------ */ -/* Exchange FK5 to FK4 conversion for its inverse, and vice versa. */ - SWAP_CODES( AST__SLA_FK54Z, AST__SLA_FK45Z ) - -/* Geocentric apparent to mean place. */ -/* ---------------------------------- */ -/* Exchange the transformation code for its inverse and also exchange - the order of the date and equinox arguments. */ - SWAP_CODES( AST__SLA_AMP, AST__SLA_MAP ) - SWAP_ARGS( AST__SLA_AMP, 0, 1 ) - SWAP_ARGS( AST__SLA_MAP, 0, 1 ) - -/* Ecliptic coordinates to FK5 J2000.0 equatorial. */ -/* ------------------------------------------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__SLA_ECLEQ, AST__SLA_EQECL ) - -/* Horizon to equatorial. */ -/* ---------------------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__SLA_DH2E, AST__SLA_DE2H ) - -/* Galactic coordinates to FK5 J2000.0 equatorial. */ -/* ------------------------------------------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__SLA_GALEQ, AST__SLA_EQGAL ) - -/* ICRS coordinates to FK5 J2000.0 equatorial. */ -/* ------------------------------------------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__SLA_HFK5Z, AST__SLA_FK5HZ ) - -/* Galactic to supergalactic coordinates. */ -/* -------------------------------------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__SLA_GALSUP, AST__SLA_SUPGAL ) - -/* FK5 J2000 equatorial coordinates to Helioprojective-Cartesian. */ -/* -------------------------------------------------------------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__EQHPC, AST__HPCEQ ) - -/* FK5 J2000 equatorial coordinates to Helioprojective-Radial. */ -/* ----------------------------------------------------------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__EQHPR, AST__HPREQ ) - -/* FK5 J2000 equatorial coordinates to Helio-ecliptic. */ -/* --------------------------------------------------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__EQHE, AST__HEEQ ) - -/* Dynamical J2000.0 to ICRS. */ -/* -------------------------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__J2000H, AST__HJ2000 ) - -/* HA to RA */ -/* -------- */ -/* Exchange the transformation code for its inverse. */ - SWAP_CODES( AST__H2R, AST__R2H ) - - } - -/* Undefine the local macros. */ -#undef SWAP_ARGS -#undef SWAP_CODES - -/* Count the transformation steps. */ - nstep++; - } - } - -/* Loop to simplify the sequence of transformation steps until no - further improvement is possible. */ - done = 0; - while ( astOK && !done ) { - -/* Examine each remaining transformation step in turn. */ - ikeep = -1; - for ( istep = 0; istep < nstep; istep++ ) { - -/* Initially assume we will retain the current step. */ - keep = 1; - -/* Eliminate redundant precession corrections. */ -/* ------------------------------------------- */ -/* First check if this is a redundant precession transformation - (i.e. the starting and ending epochs are the same). If so, then - note that it should not be kept. */ - if ( ( ( cvttype[ istep ] == AST__SLA_PREBN ) || - ( cvttype[ istep ] == AST__SLA_PREC ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], cvtargs[ istep ][ 1 ] ) ) { - keep = 0; - -/* The remaining simplifications act to combine adjacent - transformation steps, so only apply them while there are at least 2 - steps left. */ - } else if ( istep < ( nstep - 1 ) ) { - -/* Define a macro to test if two adjacent transformation type codes - have specified values. */ -#define PAIR_CVT( code1, code2 ) \ - ( ( cvttype[ istep ] == code1 ) && \ - ( cvttype[ istep + 1 ] == code2 ) ) - -/* Combine adjacent precession corrections. */ -/* ---------------------------------------- */ -/* If two precession corrections are adjacent, and have an equinox - value in common, then they may be combined into a single correction - by eliminating the common equinox. */ - if ( ( PAIR_CVT( AST__SLA_PREBN, AST__SLA_PREBN ) || - PAIR_CVT( AST__SLA_PREC, AST__SLA_PREC ) ) && - astEQUAL( cvtargs[ istep ][ 1 ], cvtargs[ istep + 1 ][ 0 ] ) ) { - -/* Retain the second correction, changing its first argument, and - eliminate the first correction. */ - cvtargs[ istep + 1 ][ 0 ] = cvtargs[ istep ][ 0 ]; - istep++; - -/* Eliminate redundant E-term handling. */ -/* ------------------------------------ */ -/* Check if adjacent steps implement a matching pair of corrections - for the E-terms of aberration with the same argument value. If so, - they will cancel, so eliminate them both. */ - } else if ( ( PAIR_CVT( AST__SLA_SUBET, AST__SLA_ADDET ) || - PAIR_CVT( AST__SLA_ADDET, AST__SLA_SUBET ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - -/* Eliminate redundant FK4/FK5 conversions. */ -/* ---------------------------------------- */ -/* Similarly, check for a matching pair of FK4/FK5 conversions with - the same argument value and eliminate them both if possible. */ - } else if ( ( PAIR_CVT( AST__SLA_FK45Z, AST__SLA_FK54Z ) || - PAIR_CVT( AST__SLA_FK54Z, AST__SLA_FK45Z ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - -/* Eliminate redundant ICRS/FK5 conversions. */ -/* ----------------------------------------- */ -/* Similarly, check for a matching pair of ICRS/FK5 conversions with - the same argument value and eliminate them both if possible. */ - } else if ( ( PAIR_CVT( AST__SLA_HFK5Z, AST__SLA_FK5HZ ) || - PAIR_CVT( AST__SLA_FK5HZ, AST__SLA_HFK5Z ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - -/* Eliminate redundant geocentric apparent conversions. */ -/* ---------------------------------------------------- */ -/* As above, check for a matching pair of conversions with matching - argument values (note the argument order reverses for the two - directions) and eliminate them if possible. */ - } else if ( ( PAIR_CVT( AST__SLA_AMP, AST__SLA_MAP ) || - PAIR_CVT( AST__SLA_MAP, AST__SLA_AMP ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 1 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - -/* Eliminate redundant ecliptic coordinate conversions. */ -/* ---------------------------------------------------- */ -/* This is handled in the same way as the FK4/FK5 case. */ - } else if ( ( PAIR_CVT( AST__SLA_ECLEQ, AST__SLA_EQECL ) || - PAIR_CVT( AST__SLA_EQECL, AST__SLA_ECLEQ ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - -/* Eliminate redundant AzEl coordinate conversions. */ -/* ------------------------------------------------ */ - } else if ( ( PAIR_CVT( AST__SLA_DH2E, AST__SLA_DE2H ) || - PAIR_CVT( AST__SLA_DE2H, AST__SLA_DH2E ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 1 ] ) ) { - istep++; - keep = 0; - -/* Eliminate redundant galactic coordinate conversions. */ -/* ---------------------------------------------------- */ -/* This is handled as above, except that there are no arguments to - check. */ - } else if ( PAIR_CVT( AST__SLA_GALEQ, AST__SLA_EQGAL ) || - PAIR_CVT( AST__SLA_EQGAL, AST__SLA_GALEQ ) ) { - istep++; - keep = 0; - -/* Eliminate redundant supergalactic coordinate conversions. */ -/* --------------------------------------------------------- */ -/* This is handled as above. */ - } else if ( PAIR_CVT( AST__SLA_GALSUP, AST__SLA_SUPGAL ) || - PAIR_CVT( AST__SLA_SUPGAL, AST__SLA_GALSUP ) ) { - istep++; - keep = 0; - -/* Eliminate redundant helioprojective-Cartesian coordinate conversions. */ -/* --------------------------------------------------------------------- */ - } else if ( ( PAIR_CVT( AST__HPCEQ, AST__EQHPC ) || - PAIR_CVT( AST__EQHPC, AST__HPCEQ ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 1 ] ) && - astEQUAL( cvtargs[ istep ][ 2 ], - cvtargs[ istep + 1 ][ 2 ] ) && - astEQUAL( cvtargs[ istep ][ 3 ], - cvtargs[ istep + 1 ][ 3 ] ) ) { - istep++; - keep = 0; - -/* Eliminate redundant helioprojective-Radial coordinate conversions. */ -/* --------------------------------------------------------------------- */ - } else if ( ( PAIR_CVT( AST__HPREQ, AST__EQHPR ) || - PAIR_CVT( AST__EQHPR, AST__HPREQ ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 1 ] ) && - astEQUAL( cvtargs[ istep ][ 2 ], - cvtargs[ istep + 1 ][ 2 ] ) && - astEQUAL( cvtargs[ istep ][ 3 ], - cvtargs[ istep + 1 ][ 3 ] ) ) { - istep++; - keep = 0; - -/* Eliminate redundant helio-ecliptic coordinate conversions. */ -/* ---------------------------------------------------------- */ - } else if ( ( PAIR_CVT( AST__EQHE, AST__HEEQ ) || - PAIR_CVT( AST__HEEQ, AST__EQHE ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - -/* Eliminate redundant dynamical J2000 coordinate conversions. */ -/* ----------------------------------------------------------- */ - } else if ( PAIR_CVT( AST__J2000H, AST__HJ2000 ) || - PAIR_CVT( AST__HJ2000, AST__J2000H ) ) { - istep++; - keep = 0; - -/* Eliminate redundant Hour Angle conversions. */ -/* ------------------------------------------- */ - } else if ( ( PAIR_CVT( AST__R2H, AST__H2R ) || - PAIR_CVT( AST__H2R, AST__R2H ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - - } - -/* Undefine the local macro. */ -#undef PAIR_CVT - } - -/* If the current transformation (possibly modified above) is being - kept, then increment the index that identifies its new location in - the list of transformation steps. */ - if ( keep ) { - ikeep++; - -/* If the new location is different to its current location, copy the - transformation data into the new location. */ - if ( ikeep != istep ) { - cvttype[ ikeep ] = cvttype[ istep ]; - for ( iarg = 0; iarg < narg[ istep ]; iarg++ ) { - cvtargs[ ikeep ][ iarg ] = cvtargs[ istep ][ iarg ]; - } - narg[ ikeep ] = narg[ istep ]; - } - } - } - -/* Note if no simplification was achieved on this iteration (i.e. the - number of transformation steps was not reduced). This is the signal - to quit. */ - done = ( ( ikeep + 1 ) >= nstep ); - -/* Note how many transformation steps now remain. */ - nstep = ikeep + 1; - } - -/* Determine how many Mappings can be eliminated by condensing all - those considered above into a single Mapping. */ - if ( astOK ) { - ngone = imap2 - imap1; - -/* Determine if the replacement Mapping can be a UnitMap (a null - Mapping). This will only be the case if all the transformation - steps were eliminated above. */ - unit = ( nstep == 0 ); - -/* Determine if simplification is possible. This will be the case if - (a) Mappings were eliminated ("ngone" is non-zero), or (b) the - number of transformation steps was reduced, or (c) the SlaMap(s) - can be replaced by a UnitMap, or (d) if there was initially only - one SlaMap present, its invert flag was set (this flag will always - be cleared in the replacement Mapping). */ - simpler = ngone || ( nstep < nstep0 ) || unit || - ( *invert_list )[ where ]; - -/* Do nothing more unless simplification is possible. */ - if ( simpler ) { - -/* If the replacement Mapping is a UnitMap, then create it. */ - if ( unit ) { - new = (AstMapping *) - astUnitMap( astGetNin( ( *map_list )[ where ] ), "", status ); - -/* Otherwise, create a replacement SlaMap and add each of the - remaining transformation steps to it. */ - } else { - new = (AstMapping *) astSlaMap( 0, "", status ); - for ( istep = 0; istep < nstep; istep++ ) { - AddSlaCvt( (AstSlaMap *) new, cvttype[ istep ], - narg[ istep ], cvtargs[ istep ], status ); - } - } - -/* Annul the pointers to the Mappings being eliminated. */ - if ( astOK ) { - for ( imap = imap1; imap <= imap2; imap++ ) { - ( *map_list )[ imap ] = astAnnul( ( *map_list )[ imap ] ); - } - -/* Insert the pointer and invert value for the new Mapping. */ - ( *map_list )[ imap1 ] = new; - ( *invert_list )[ imap1 ] = 0; - -/* Move any subsequent Mapping information down to close the gap. */ - for ( imap = imap2 + 1; imap < *nmap; imap++ ) { - ( *map_list )[ imap - ngone ] = ( *map_list )[ imap ]; - ( *invert_list )[ imap - ngone ] = ( *invert_list )[ imap ]; - } - -/* Blank out any information remaining at the end of the arrays. */ - for ( imap = ( *nmap - ngone ); imap < *nmap; imap++ ) { - ( *map_list )[ imap ] = NULL; - ( *invert_list )[ imap ] = 0; - } - -/* Decrement the Mapping count and return the index of the first - Mapping which was eliminated. */ - ( *nmap ) -= ngone; - result = imap1; - -/* If an error occurred, annul the new Mapping pointer. */ - } else { - new = astAnnul( new ); - } - } - } - -/* Free the memory used for the transformation steps. */ - cvttype = astFree( cvttype ); - cvtargs = astFree( cvtargs ); - narg = astFree( narg ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static void SlaAdd( AstSlaMap *this, const char *cvt, int narg, - const double args[], int *status ) { -/* -*++ -* Name: -c astSlaAdd -f AST_SLAADD - -* Purpose: -* Add a celestial coordinate conversion to an SlaMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "slamap.h" -c void astSlaAdd( AstSlaMap *this, const char *cvt, int narg, -c const double args[] ) -f CALL AST_SLAADD( THIS, CVT, NARG, ARGS, STATUS ) - -* Class Membership: -* SlaMap method. - -* Description: -c This function adds one of the standard celestial coordinate -f This routine adds one of the standard celestial coordinate -* system conversions provided by the SLALIB Positional Astronomy -* Library (Starlink User Note SUN/67) to an existing SlaMap. -* -c When an SlaMap is first created (using astSlaMap), it simply -f When an SlaMap is first created (using AST_SLAMAP), it simply -c performs a unit (null) Mapping. By using astSlaAdd (repeatedly -f performs a unit (null) Mapping. By using AST_SLAADD (repeatedly -* if necessary), one or more coordinate conversion steps may then -* be added, which the SlaMap will perform in sequence. This allows -* multi-step conversions between a variety of celestial coordinate -* systems to be assembled out of the building blocks provided by -* SLALIB. -* -* Normally, if an SlaMap's Invert attribute is zero (the default), -* then its forward transformation is performed by carrying out -* each of the individual coordinate conversions specified by -c astSlaAdd in the order given (i.e. with the most recently added -f AST_SLAADD in the order given (i.e. with the most recently added -* conversion applied last). -* -* This order is reversed if the SlaMap's Invert attribute is -* non-zero (or if the inverse transformation is requested by any -* other means) and each individual coordinate conversion is also -* replaced by its own inverse. This process inverts the overall -* effect of the SlaMap. In this case, the first conversion to be -* applied would be the inverse of the one most recently added. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the SlaMap. -c cvt -f CVT = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string which identifies the -f A character string which identifies the -* celestial coordinate conversion to be added to the -* SlaMap. See the "SLALIB Conversions" section for details of -* those available. -c narg -f NARG = INTEGER (Given) -* The number of argument values supplied in the -c "args" array. -f ARGS array. -c args -f ARGS( * ) = DOUBLE PRECISION (Given) -* An array containing argument values for the celestial -* coordinate conversion. The number of arguments required, and -* hence the number of array elements used, depends on the -* conversion specified (see the "SLALIB Conversions" -* section). This array is ignored -c and a NULL pointer may be supplied -* if no arguments are needed. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - All coordinate values processed by an SlaMap are in -* radians. The first coordinate is the celestial longitude and the -* second coordinate is the celestial latitude. -* - When assembling a multi-stage conversion, it can sometimes be -* difficult to determine the most economical conversion path. For -* example, converting to the standard FK5 coordinate system as an -* intermediate stage is often sensible in formulating the problem, -* but may introduce unnecessary extra conversion steps. A solution -* to this is to include all the steps which are (logically) -c necessary, but then to use astSimplify to simplify the resulting -f necessary, but then to use AST_SIMPLIFY to simplify the resulting -* SlaMap. The simplification process will eliminate any steps -* which turn out not to be needed. -c - This function does not check to ensure that the sequence of -f - This routine does not check to ensure that the sequence of -* coordinate conversions added to an SlaMap is physically -* meaningful. - -* SLALIB Conversions: -* The following strings (which are case-insensitive) may be supplied -c via the "cvt" parameter to indicate which celestial coordinate -f via the CVT argument to indicate which celestial coordinate -* conversion is to be added to the SlaMap. Each string is derived -* from the name of the SLALIB routine that performs the -* conversion and the relevant documentation (SUN/67) should be -* consulted for details. Where arguments are needed by -* the conversion, they are listed in parentheses. Values for -c these arguments should be given, via the "args" array, in the -f these arguments should be given, via the ARGS array, in the -* order indicated. The argument names match the corresponding -* SLALIB routine arguments and their values should be given using -* exactly the same units, time scale, calendar, etc. as described -* in SUN/67: -* -* - "ADDET" (EQ): Add E-terms of aberration. -* - "SUBET" (EQ): Subtract E-terms of aberration. -* - "PREBN" (BEP0,BEP1): Apply Bessel-Newcomb pre-IAU 1976 (FK4) -* precession model. -* - "PREC" (EP0,EP1): Apply IAU 1975 (FK5) precession model. -* - "FK45Z" (BEPOCH): Convert FK4 to FK5 (no proper motion or parallax). -* - "FK54Z" (BEPOCH): Convert FK5 to FK4 (no proper motion or parallax). -* - "AMP" (DATE,EQ): Convert geocentric apparent to mean place. -* - "MAP" (EQ,DATE): Convert mean place to geocentric apparent. -* - "ECLEQ" (DATE): Convert ecliptic coordinates to FK5 J2000.0 equatorial. -* - "EQECL" (DATE): Convert equatorial FK5 J2000.0 to ecliptic coordinates. -* - "GALEQ": Convert galactic coordinates to FK5 J2000.0 equatorial. -* - "EQGAL": Convert FK5 J2000.0 equatorial to galactic coordinates. -* - "HFK5Z" (JEPOCH): Convert ICRS coordinates to FK5 J2000.0 equatorial. -* - "FK5HZ" (JEPOCH): Convert FK5 J2000.0 equatorial coordinates to ICRS. -* - "GALSUP": Convert galactic to supergalactic coordinates. -* - "SUPGAL": Convert supergalactic coordinates to galactic. -* - "J2000H": Convert dynamical J2000.0 to ICRS. -* - "HJ2000": Convert ICRS to dynamical J2000.0. -* - "R2H" (LAST): Convert RA to Hour Angle. -* - "H2R" (LAST): Convert Hour Angle to RA. -* -* For example, to use the "ADDET" conversion, which takes a single -* argument EQ, you should consult the documentation for the SLALIB -* routine SLA_ADDET. This describes the conversion in detail and -* shows that EQ is the Besselian epoch of the mean equator and -* equinox. -c This value should then be supplied to astSlaAdd in args[0]. -f This value should then be supplied to AST_SLAADD in ARGS(1). -* -* In addition the following strings may be supplied for more complex -* conversions which do not correspond to any one single SLALIB routine -* (DIURAB is the magnitude of the diurnal aberration vector in units -* of "day/(2.PI)", DATE is the Modified Julian Date of the observation, -* and (OBSX,OBSY,OBZ) are the Heliocentric-Aries-Ecliptic cartesian -* coordinates, in metres, of the observer): -* -* - "HPCEQ" (DATE,OBSX,OBSY,OBSZ): Convert Helioprojective-Cartesian coordinates to J2000.0 equatorial. -* - "EQHPC" (DATE,OBSX,OBSY,OBSZ): Convert J2000.0 equatorial coordinates to Helioprojective-Cartesian. -* - "HPREQ" (DATE,OBSX,OBSY,OBSZ): Convert Helioprojective-Radial coordinates to J2000.0 equatorial. -* - "EQHPR" (DATE,OBSX,OBSY,OBSZ): Convert J2000.0 equatorial coordinates to Helioprojective-Radial. -* - "HEEQ" (DATE): Convert helio-ecliptic coordinates to J2000.0 equatorial. -* - "EQHE" (DATE): Convert J2000.0 equatorial coordinates to helio-ecliptic. -* - "H2E" (LAT,DIRUAB): Convert horizon coordinates to equatorial. -* - "E2H" (LAT,DIURAB): Convert equatorial coordinates to horizon. -* -* Note, the "H2E" and "E2H" conversions convert between topocentric -* horizon coordinates (azimuth,elevation), and apparent local equatorial -* coordinates (hour angle,declination). Thus, the effects of diurnal -* aberration are taken into account in the conversions but the effects -* of atmospheric refraction are not. - -*-- -*/ - -/* Local Variables: */ - int cvttype; /* Conversion type code */ - -/* Check the inherited status. */ - if ( !astOK ) return; - -/* Validate the type string supplied and obtain the equivalent - conversion type code. */ - cvttype = CvtCode( cvt, status ); - -/* If the string was not recognised, then report an error. */ - if ( astOK && ( cvttype == AST__SLA_NULL ) ) { - astError( AST__SLAIN, - "astSlaAdd(%s): Invalid SLALIB sky coordinate conversion " - "type \"%s\".", status, astGetClass( this ), cvt ); - } - -/* Add the new conversion to the SlaMap. */ - AddSlaCvt( this, cvttype, narg, args, status ); -} - -static int SlaIsEmpty( AstSlaMap *this, int *status ){ -/* -*+ -* Name: -* astSlaIsEmpty - -* Purpose: -* Indicates if a SlaMap is empty (i.e. has no conversions). - -* Type: -* Protected function. - -* Synopsis: -* #include "slamap.h" -* result = astSlaIsEmpty( AstSlaMap *this ) - -* Class Membership: -* SlaMap method. - -* Description: -* This function returns a flag indicating if the SlaMap is empty -* (i.e. has not yet had any conversions added to it using astSlaAdd). - -* Parameters: -* this -* The SlaMap. -*- -*/ - if( !astOK ) return 1; - return ( this->ncvt == 0 ); -} - - -static void SolarPole( double mjd, double pole[3], int *status ) { -/* -* Name: -* SolarPole - -* Purpose: -* Returns a unit vector along the solar north pole at the given date. - -* Type: -* Private function. - -* Synopsis: -* #include "slamap.h" -* void SolarPole( double mjd, double pole[3], int *status ) - -* Class Membership: -* SlaMap member function. - -* Description: -* This function returns a unit vector along the solar north pole at -* the given date, in the AST__HAEC coordinate system. - -* Parameters: -* mjd -* The date at which the solar north pole vector is required. -* pole -* An array holding the (X,Y,Z) components of the vector, in the -* AST__HAEC system. -* status -* Pointer to the inherited status variable. - -* Notes: -* - AST__BAD will be returned for all components of the vector if this -* function is invoked with the global error status set, or if it should -* fail for any reason. -*/ - -/* Local Variables: */ - double omega; - double sproj; - double inc; - double t1; - -/* Initialize. */ - pole[0] = AST__BAD; - pole[1] = AST__BAD; - pole[2] = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* First, we find the ecliptic longitude of the ascending node of the solar - equator on the ecliptic at the required date. This is based on the - equation in the "Explanatory Supplement to the Astronomical Alamanac", - section "Physical Ephemeris of the Sun": - - Omega = 75.76 + 0.01397*T degrees - - Note, the text at the start of the chapter says that "T" is measured in - centuries since J2000, but the equivalent expression in Table 15.4 is - only consistent with the above equation if "T" is measured in days since - J2000. We assume T is in days. The text does not explicitly say so, - but we assume that this longitude value (Omega) is with respect to the - mean equinox of J2000.0. */ - omega = 75.76 + 0.01397*( palEpj(mjd) - 2000.0 ); - -/* Convert this to the ecliptic longitude of the projection of the sun's - north pole onto the ecliptic, in radians. */ - sproj = ( omega - 90.0 )*D2R; - -/* Obtain a unit vector parallel to the sun's north pole, in terms of - the required ecliptic (X,Y,Z) axes, in which X points towards ecliptic - longitude/latitude ( 0, 0 ), Y axis points towards ecliptic - longitude/latitude ( 90, 0 ) degrees, and Z axis points towards the - ecliptic north pole. The inclination of the solar axis to the ecliptic - axis (7.25 degrees) is taken from the "Explanatory Supplement" section - "The Physical Ephemeris of the Sun". */ - inc = 7.25*D2R; - t1 = sin( inc ); - pole[ 0 ]= t1*cos( sproj ); - pole[ 1 ] = t1*sin( sproj ); - pole[ 2 ] = cos( inc ); - -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply an SlaMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "slamap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* SlaMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes an SlaMap and a set of points encapsulated -* in a PointSet and transforms the points so as to perform the -* sequence of SLALIB sky coordinate conversions specified by -* previous invocations of astSlaAdd. - -* Parameters: -* this -* Pointer to the SlaMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the SlaMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPointSet *result; /* Pointer to output PointSet */ - AstSlaMap *map; /* Pointer to SlaMap to be applied */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *alpha; /* Pointer to longitude array */ - double *args; /* Pointer to argument list for conversion */ - double *extra; /* Pointer to intermediate values */ - double *delta; /* Pointer to latitude array */ - double *p[3]; /* Pointers to arrays to be transformed */ - double *obs; /* Pointer to array holding observers position */ - int cvt; /* Loop counter for conversions */ - int ct; /* Conversion type */ - int end; /* Termination index for conversion loop */ - int inc; /* Increment for conversion loop */ - int npoint; /* Number of points */ - int point; /* Loop counter for points */ - int start; /* Starting index for conversion loop */ - int sys; /* STP coordinate system code */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Obtain a pointer to the SlaMap. */ - map = (AstSlaMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - coordinate conversions needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse transformation, according - to the direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( this ) ) forward = !forward; - -/* Transform the coordinate values. */ -/* -------------------------------- */ -/* Use "alpha" and "delta" as synonyms for the arrays of longitude and latitude - coordinate values stored in the output PointSet. */ - if ( astOK ) { - alpha = ptr_out[ 0 ]; - delta = ptr_out[ 1 ]; - -/* Initialise the output coordinate values by copying the input ones. */ - (void) memcpy( alpha, ptr_in[ 0 ], sizeof( double ) * (size_t) npoint ); - (void) memcpy( delta, ptr_in[ 1 ], sizeof( double ) * (size_t) npoint ); - -/* We will loop to apply each SLALIB sky coordinate conversion in turn to the - (alpha,delta) arrays. However, if the inverse transformation was requested, - we must loop through these transformations in reverse order, so set up - appropriate limits and an increment to control this loop. */ - start = forward ? 0 : map->ncvt - 1; - end = forward ? map->ncvt : -1; - inc = forward ? 1 : -1; - -/* Loop through the coordinate conversions in the required order and obtain a - pointer to the argument list for the current conversion. */ - for ( cvt = start; cvt != end; cvt += inc ) { - args = map->cvtargs[ cvt ]; - extra = map->cvtextra[ cvt ]; - -/* Define a local macro as a shorthand to apply the code given as "function" - (the macro argument) to each element of the (alpha,delta) arrays in turn. - Before applying this conversion function, each element is first checked for - "bad" coordinates (indicated by the value AST__BAD) and appropriate "bad" - result values are assigned if necessary. */ -#define TRAN_ARRAY(function) \ - for ( point = 0; point < npoint; point++ ) { \ - if ( ( alpha[ point ] == AST__BAD ) || \ - ( delta[ point ] == AST__BAD ) ) { \ - alpha[ point ] = AST__BAD; \ - delta[ point ] = AST__BAD; \ - } else { \ - function \ - } \ - } - -/* Classify the SLALIB sky coordinate conversion to be applied. */ - ct = map->cvttype[ cvt ]; - switch ( ct ) { - -/* Add E-terms of aberration. */ -/* -------------------------- */ -/* Add or subtract (for the inverse) the E-terms from each coordinate pair - in turn, returning the results to the same arrays. */ - case AST__SLA_ADDET: - if ( forward ) { - TRAN_ARRAY(palAddet( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point );) - } else { - TRAN_ARRAY(palSubet( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point );) - } - break; - -/* Subtract E-terms of aberration. */ -/* ------------------------------- */ -/* This is the same as above, but with the forward and inverse cases - transposed. */ - case AST__SLA_SUBET: - if ( forward ) { - TRAN_ARRAY(palSubet( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point );) - } else { - TRAN_ARRAY(palAddet( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point );) - } - break; - -/* Apply Bessel-Newcomb pre-IAU 1976 (FK4) precession model. */ -/* --------------------------------------------------------- */ -/* Since we are transforming a sequence of points, first set up the required - precession matrix, swapping the argument order to get the inverse matrix - if required. */ - case AST__SLA_PREBN: - { - double epoch1 = forward ? args[ 0 ] : args[ 1 ]; - double epoch2 = forward ? args[ 1 ] : args[ 0 ]; - double precess_matrix[ 3 ][ 3 ]; - double vec1[ 3 ]; - double vec2[ 3 ]; - palPrebn( epoch1, epoch2, precess_matrix ); - -/* For each point in the (alpha,delta) arrays, convert to Cartesian - coordinates, apply the precession matrix, convert back to polar coordinates - and then constrain the longitude result to lie in the range 0 to 2*pi - (palDcc2s doesn't do this itself). */ - TRAN_ARRAY(palDcs2c( alpha[ point ], delta[ point ], vec1 ); - palDmxv( precess_matrix, vec1, vec2 ); - palDcc2s( vec2, alpha + point, delta + point ); - alpha[ point ] = palDranrm( alpha[ point ] );) - } - break; - -/* Apply IAU 1975 (FK5) precession model. */ -/* -------------------------------------- */ -/* This is handled in the same way as above, but using the appropriate FK5 - precession matrix. */ - case AST__SLA_PREC: - { - double epoch1 = forward ? args[ 0 ] : args[ 1 ]; - double epoch2 = forward ? args[ 1 ] : args[ 0 ]; - double precess_matrix[ 3 ][ 3 ]; - double vec1[ 3 ]; - double vec2[ 3 ]; - palPrec( epoch1, epoch2, precess_matrix ); - TRAN_ARRAY(palDcs2c( alpha[ point ], delta[ point ], vec1 ); - palDmxv( precess_matrix, vec1, vec2 ); - palDcc2s( vec2, alpha + point, delta + point ); - alpha[ point ] = palDranrm( alpha[ point ] );) - } - break; - -/* Convert FK4 to FK5 (no proper motion or parallax). */ -/* -------------------------------------------------- */ -/* Apply the conversion to each point. */ - case AST__SLA_FK45Z: - if ( forward ) { - TRAN_ARRAY(palFk45z( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point );) - -/* The inverse transformation is also straightforward, except that we need a - couple of dummy variables as function arguments. */ - } else { - double dr1950; - double dd1950; - TRAN_ARRAY(palFk54z( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point, - &dr1950, &dd1950 );) - } - break; - -/* Convert FK5 to FK4 (no proper motion or parallax). */ -/* -------------------------------------------------- */ -/* This is the same as above, but with the forward and inverse cases - transposed. */ - case AST__SLA_FK54Z: - if ( forward ) { - double dr1950; - double dd1950; - TRAN_ARRAY(palFk54z( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point, - &dr1950, &dd1950 );) - } else { - TRAN_ARRAY(palFk45z( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point );) - } - break; - -/* Convert geocentric apparent to mean place. */ -/* ------------------------------------------ */ -/* Since we are transforming a sequence of points, first set up the required - parameter array. Than apply this to each point in turn. */ - case AST__SLA_AMP: - { - - if( !extra ) { - - if( args[ 1 ] != eq_cache || - args[ 0 ] != ep_cache ) { - eq_cache = args[ 1 ]; - ep_cache = args[ 0 ]; - palMappa( eq_cache, ep_cache, amprms_cache ); - } - - extra = astStore( NULL, amprms_cache, - sizeof( double )*21 ); - map->cvtextra[ cvt ] = extra; - } - - if ( forward ) { - TRAN_ARRAY(palAmpqk( alpha[ point ], delta[ point ], - extra, - alpha + point, delta + point );) - -/* The inverse uses the same parameter array but converts from mean place - to geocentric apparent. */ - } else { - TRAN_ARRAY(palMapqkz( alpha[ point ], delta[ point ], - extra, - alpha + point, delta + point );) - } - } - break; - -/* Convert mean place to geocentric apparent. */ -/* ------------------------------------------ */ -/* This is the same as above, but with the forward and inverse cases - transposed. */ - case AST__SLA_MAP: - { - if( !extra ) { - - if( args[ 0 ] != eq_cache || - args[ 1 ] != ep_cache ) { - eq_cache = args[ 0 ]; - ep_cache = args[ 1 ]; - palMappa( eq_cache, ep_cache, amprms_cache ); - } - - extra = astStore( NULL, amprms_cache, - sizeof( double )*21 ); - map->cvtextra[ cvt ] = extra; - } - - if ( forward ) { - TRAN_ARRAY(palMapqkz( alpha[ point ], delta[ point ], - extra, - alpha + point, delta + point );) - } else { - TRAN_ARRAY(palAmpqk( alpha[ point ], delta[ point ], - extra, - alpha + point, delta + point );) - } - } - break; - -/* Convert ecliptic coordinates to J2000.0 equatorial. */ -/* --------------------------------------------------- */ -/* Since we are transforming a sequence of points, first set up the required - conversion matrix (the conversion is a rotation). */ - case AST__SLA_ECLEQ: - { - double convert_matrix[ 3 ][ 3 ]; - double precess_matrix[ 3 ][ 3 ]; - double rotate_matrix[ 3 ][ 3 ]; - double vec1[ 3 ]; - double vec2[ 3 ]; - -/* Obtain the matrix that precesses equatorial coordinates from J2000.0 to the - required date. Also obtain the rotation matrix that converts from - equatorial to ecliptic coordinates. */ - palPrec( 2000.0, palEpj( args[ 0 ] ), precess_matrix ); - palEcmat( args[ 0 ], rotate_matrix ); - -/* Multiply these matrices to give the overall matrix that converts from - equatorial J2000.0 coordinates to ecliptic coordinates for the required - date. */ - palDmxm( rotate_matrix, precess_matrix, convert_matrix ); - -/* Apply the conversion by transforming from polar to Cartesian coordinates, - multiplying by the inverse conversion matrix and converting back to polar - coordinates. Then constrain the longitude result to lie in the range - 0 to 2*pi (palDcc2s doesn't do this itself). */ - if ( forward ) { - TRAN_ARRAY(palDcs2c( alpha[ point ], delta[ point ], - vec1 ); - palDimxv( convert_matrix, vec1, vec2 ); - palDcc2s( vec2, alpha + point, delta + point ); - alpha[ point ] = palDranrm ( alpha[ point ] );) - -/* The inverse conversion is the same except that we multiply by the forward - conversion matrix (palDmxv instead of palDimxv). */ - } else { - TRAN_ARRAY(palDcs2c( alpha[ point ], delta[ point ], - vec1 ); - palDmxv( convert_matrix, vec1, vec2 ); - palDcc2s( vec2, alpha + point, delta + point ); - alpha[ point ] = palDranrm ( alpha[ point ] );) - } - } - break; - -/* Convert equatorial J2000.0 to ecliptic coordinates. */ -/* --------------------------------------------------- */ -/* This is the same as above, but with the forward and inverse cases - transposed. */ - case AST__SLA_EQECL: - { - double convert_matrix[ 3 ][ 3 ]; - double precess_matrix[ 3 ][ 3 ]; - double rotate_matrix[ 3 ][ 3 ]; - double vec1[ 3 ]; - double vec2[ 3 ]; - -/* Create the conversion matrix. */ - palPrec( 2000.0, palEpj( args[ 0 ] ), precess_matrix ); - palEcmat( args[ 0 ], rotate_matrix ); - palDmxm( rotate_matrix, precess_matrix, convert_matrix ); - -/* Apply it. */ - if ( forward ) { - TRAN_ARRAY(palDcs2c( alpha[ point ], delta[ point ], - vec1 ); - palDmxv( convert_matrix, vec1, vec2 ); - palDcc2s( vec2, alpha + point, delta + point ); - alpha[ point ] = palDranrm ( alpha[ point ] );) - } else { - TRAN_ARRAY(palDcs2c( alpha[ point ], delta[ point ], - vec1 ); - palDimxv( convert_matrix, vec1, vec2 ); - palDcc2s( vec2, alpha + point, delta + point ); - alpha[ point ] = palDranrm ( alpha[ point ] );) - } - } - break; - -/* Convert ICRS to J2000.0 equatorial. */ -/* ----------------------------------- */ -/* Apply the conversion to each point. */ - case AST__SLA_HFK5Z: - if ( forward ) { - double dr5; - double dd5; - TRAN_ARRAY(palHfk5z( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point, - &dr5, &dd5 );) - -/* The inverse simply uses the inverse SLALIB function. */ - } else { - TRAN_ARRAY(palFk5hz( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point );) - } - break; - -/* Convert J2000.0 to ICRS equatorial. */ -/* ----------------------------------- */ -/* This is the same as above, but with the forward and inverse cases - transposed. */ - case AST__SLA_FK5HZ: - if ( forward ) { - TRAN_ARRAY(palFk5hz( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point );) - -/* The inverse simply uses the inverse SLALIB function. */ - } else { - double dr5; - double dd5; - TRAN_ARRAY(palHfk5z( alpha[ point ], delta[ point ], - args[ 0 ], - alpha + point, delta + point, - &dr5, &dd5 );) - } - break; - -/* Convert horizon to equatorial. */ -/* ------------------------------ */ -/* Apply the conversion to each point. */ - case AST__SLA_DH2E: - if ( forward ) { - TRAN_ARRAY(Dh2e( alpha[ point ], delta[ point ], - args[ 0 ], args[ 1 ], - alpha + point, delta + point, status );) - -/* The inverse simply uses the inverse SLALIB function. */ - } else { - TRAN_ARRAY(De2h( alpha[ point ], delta[ point ], - args[ 0 ], args[ 1 ], - alpha + point, delta + point, status );) - } - break; - -/* Convert equatorial to horizon. */ -/* ------------------------------ */ -/* This is the same as above, but with the forward and inverse cases - transposed. */ - case AST__SLA_DE2H: - if ( forward ) { - TRAN_ARRAY(De2h( alpha[ point ], delta[ point ], - args[ 0 ], args[ 1 ], - alpha + point, delta + point, status );) - -/* The inverse simply uses the inverse SLALIB function. */ - } else { - TRAN_ARRAY(Dh2e( alpha[ point ], delta[ point ], - args[ 0 ], args[ 1 ], - alpha + point, delta + point, status );) - } - break; - -/* Convert galactic coordinates to J2000.0 equatorial. */ -/* --------------------------------------------------- */ -/* Apply the conversion to each point. */ - case AST__SLA_GALEQ: - if ( forward ) { - TRAN_ARRAY(palGaleq( alpha[ point ], delta[ point ], - alpha + point, delta + point );) - -/* The inverse simply uses the inverse SLALIB function. */ - } else { - TRAN_ARRAY(palEqgal( alpha[ point ], delta[ point ], - alpha + point, delta + point );) - } - break; - -/* Convert J2000.0 equatorial to galactic coordinates. */ -/* --------------------------------------------------- */ -/* This is the same as above, but with the forward and inverse cases - transposed. */ - case AST__SLA_EQGAL: - if ( forward ) { - TRAN_ARRAY(palEqgal( alpha[ point ], delta[ point ], - alpha + point, delta + point );) - } else { - TRAN_ARRAY(palGaleq( alpha[ point ], delta[ point ], - alpha + point, delta + point );) - } - break; - -/* Convert galactic to supergalactic coordinates. */ -/* ---------------------------------------------- */ -/* Apply the conversion to each point. */ - case AST__SLA_GALSUP: - if ( forward ) { - TRAN_ARRAY(palGalsup( alpha[ point ], delta[ point ], - alpha + point, delta + point );) - -/* The inverse simply uses the inverse SLALIB function. */ - } else { - TRAN_ARRAY(palSupgal( alpha[ point ], delta[ point ], - alpha + point, delta + point );) - } - break; - -/* Convert supergalactic coordinates to galactic. */ -/* ---------------------------------------------- */ -/* This is the same as above, but with the forward and inverse cases - transposed. */ - case AST__SLA_SUPGAL: - if ( forward ) { - TRAN_ARRAY(palSupgal( alpha[ point ], delta[ point ], - alpha + point, delta + point );) - } else { - TRAN_ARRAY(palGalsup( alpha[ point ], delta[ point ], - alpha + point, delta + point );) - } - break; - -/* If the conversion type was not recognised, then report an error - (this should not happen unless validation in astSlaAdd has failed - to detect a bad value previously). */ - default: - astError( AST__SLAIN, "astTransform(%s): Corrupt %s contains " - "invalid SLALIB sky coordinate conversion code (%d).", status, - astGetClass( this ), astGetClass( this ), - (int) ct ); - break; - -/* Convert any STP coordinates to J2000 equatorial. */ -/* ------------------------------------------------ */ - case AST__HPCEQ: - case AST__HPREQ: - case AST__HEEQ: - { - -/* Get the code for the appropriate 3D STP coordinate system to use. - Also, get a point to the observer position, if needed. */ - if( ct == AST__HPCEQ ) { - sys = AST__HPC; - obs = args + 1; - - } else if( ct == AST__HPREQ ) { - sys = AST__HPR; - obs = args + 1; - - } else { - sys = AST__GSE; - obs = NULL; - - } - -/* Store the 3D positions to be transformed. The supplied arrays are used - for the longitude and latitude values. No radius values are supplied. - (a value of 1AU will be used in the transformation). */ - p[0] = alpha; - p[1] = delta; - p[2] = NULL; - -/* Convert the supplied positions to (or from) AST__HEQ, ignoring the - distinction between the origin of the input and output systems (which - is appropriate since we are considering points at an infinite distance - from the observer). */ - if( forward ) { - STPConv( args[ 0 ], 1, npoint, sys, obs, p, - AST__HAQ, NULL, p, status ); - } else { - STPConv( args[ 0 ], 1, npoint, AST__HAQ, NULL, p, - sys, obs, p, status ); - } - } - break; - - -/* Convert J2000 equatorial to any STP coordinates. */ -/* ------------------------------------------------ */ -/* Same as above, but with forward and inverse cases transposed. */ - case AST__EQHPC: - case AST__EQHPR: - case AST__EQHE: - { - -/* Get the code for the appropriate 3D STP coordinate system to use. - Also, get a point to the observer position, if needed. */ - if( ct == AST__EQHPC ) { - sys = AST__HPC; - obs = args + 1; - - } else if( ct == AST__EQHPR ) { - sys = AST__HPR; - obs = args + 1; - - } else { - sys = AST__GSE; - obs = NULL; - - } - -/* Store the 3D positions to be transformed. The supplied arrays are used - for the longitude and latitude values. No radius values are supplied. - (a value of 1AU will be used in the transformation). */ - p[0] = alpha; - p[1] = delta; - p[2] = NULL; - -/* Convert the supplied positions from (or to) AST__HEQ, ignoring the - distinction between the origin of the input and output systems (which - is appropriate since we are considering points at an infinite distance - from the observer). */ - if( forward ) { - STPConv( args[ 0 ], 1, npoint, AST__HAQ, NULL, p, - sys, obs, p, status ); - } else { - STPConv( args[ 0 ], 1, npoint, sys, obs, p, - AST__HAQ, NULL, p, status ); - } - } - break; - -/* Convert dynamical J2000.0 to ICRS. */ -/* ---------------------------------- */ -/* Apply the conversion to each point. */ - case AST__J2000H: - J2000H( forward, npoint, alpha, delta, status ); - break; - -/* Convert ICRS to dynamical J2000.0 */ -/* ---------------------------------- */ - case AST__HJ2000: - J2000H( !(forward), npoint, alpha, delta, status ); - break; - -/* Convert HA to RA, or RA to HA */ -/* ----------------------------- */ -/* The forward and inverse transformations are the same. */ - case AST__H2R: - case AST__R2H: - TRAN_ARRAY( alpha[ point ] = args[ 0 ] - alpha[ point ]; ) - break; - - } - } - } - -/* If an error has occurred and a new PointSet may have been created, then - clean up by annulling it. In any case, ensure that a NULL result is - returned.*/ - if ( !astOK ) { - if ( !out ) result = astAnnul( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; - -/* Undefine macros local to this function. */ -#undef TRAN_ARRAY -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for SlaMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for SlaMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstSlaMap *in; /* Pointer to input SlaMap */ - AstSlaMap *out; /* Pointer to output SlaMap */ - int cvt; /* Loop counter for coordinate conversions */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output SlaMap structures. */ - in = (AstSlaMap *) objin; - out = (AstSlaMap *) objout; - -/* For safety, first clear any references to the input memory from the output - SlaMap. */ - out->cvtargs = NULL; - out->cvtextra = NULL; - out->cvttype = NULL; - -/* Allocate memory for the output array of argument list pointers. */ - out->cvtargs = astMalloc( sizeof( double * ) * (size_t) in->ncvt ); - -/* Allocate memory for the output array of extra (intermediate) values. */ - out->cvtextra = astMalloc( sizeof( double * ) * (size_t) in->ncvt ); - -/* If necessary, allocate memory and make a copy of the input array of sky - coordinate conversion codes. */ - if ( in->cvttype ) out->cvttype = astStore( NULL, in->cvttype, - sizeof( int ) - * (size_t) in->ncvt ); - -/* If OK, loop through each conversion in the input SlaMap and make a copy of - its argument list, storing the new pointer in the output argument list - array. */ - if ( astOK ) { - for ( cvt = 0; cvt < in->ncvt; cvt++ ) { - out->cvtargs[ cvt ] = astStore( NULL, in->cvtargs[ cvt ], - astSizeOf( in->cvtargs[ cvt ] ) ); - out->cvtextra[ cvt ] = astStore( NULL, in->cvtextra[ cvt ], - astSizeOf( in->cvtextra[ cvt ] ) ); - } - -/* If an error occurred while copying the argument lists, loop through the - conversions again and clean up by ensuring that the new memory allocated for - each argument list is freed. */ - if ( !astOK ) { - for ( cvt = 0; cvt < in->ncvt; cvt++ ) { - out->cvtargs[ cvt ] = astFree( out->cvtargs[ cvt ] ); - } - } - } - -/* If an error occurred, free all other memory allocated above. */ - if ( !astOK ) { - out->cvtargs = astFree( out->cvtargs ); - out->cvtextra = astFree( out->cvtextra ); - out->cvttype = astFree( out->cvttype ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for SlaMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for SlaMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstSlaMap *this; /* Pointer to SlaMap */ - int cvt; /* Loop counter for coordinate conversions */ - -/* Obtain a pointer to the SlaMap structure. */ - this = (AstSlaMap *) obj; - -/* Loop to free the memory containing the argument list for each sky coordinate - conversion. */ - for ( cvt = 0; cvt < this->ncvt; cvt++ ) { - this->cvtargs[ cvt ] = astFree( this->cvtargs[ cvt ] ); - this->cvtextra[ cvt ] = astFree( this->cvtextra[ cvt ] ); - } - -/* Free the memory holding the array of conversion types and the array of - argument list pointers. */ - this->cvtargs = astFree( this->cvtargs ); - this->cvtextra = astFree( this->cvtextra ); - this->cvttype = astFree( this->cvttype ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SlaMap objects. - -* Type: -* Private function. - -* Synopsis: -* #include "slamap.h" -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the SlaMap class to an output Channel. - -* Parameters: -* this -* Pointer to the SlaMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstSlaMap *this; /* Pointer to the SlaMap structure */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - const char *argdesc[ MAX_SLA_ARGS ]; /* Pointers to argument descriptions */ - const char *comment; /* Pointer to comment string */ - const char *sval; /* Pointer to string value */ - int iarg; /* Loop counter for arguments */ - int icvt; /* Loop counter for conversion steps */ - int ival; /* Integer value */ - int nargs; /* Number of conversion arguments */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SlaMap structure. */ - this = (AstSlaMap *) this_object; - -/* Write out values representing the instance variables for the SlaMap - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Number of conversion steps. */ -/* --------------------------- */ -/* Regard this as "set" if it is non-zero. */ - ival = this->ncvt; - set = ( ival != 0 ); - astWriteInt( channel, "Nsla", set, 0, ival, "Number of conversion steps" ); - -/* Write out data for each conversion step... */ - for ( icvt = 0; icvt < this->ncvt; icvt++ ) { - -/* Conversion type. */ -/* ---------------- */ -/* Change each conversion type code into an equivalent string and - obtain associated descriptive information. If the conversion code - was not recognised, report an error and give up. */ - if ( astOK ) { - sval = CvtString( this->cvttype[ icvt ], &comment, &nargs, argdesc, status ); - if ( astOK && !sval ) { - astError( AST__SLAIN, - "astWrite(%s): Corrupt %s contains invalid SLALIB " - "sky coordinate conversion code (%d).", status, - astGetClass( channel ), astGetClass( this ), - (int) this->cvttype[ icvt ] ); - break; - } - -/* Create an appropriate keyword and write out the conversion code - information. */ - (void) sprintf( key, "Sla%d", icvt + 1 ); - astWriteString( channel, key, 1, 1, sval, comment ); - -/* Write out data for each conversion argument... */ - for ( iarg = 0; iarg < nargs; iarg++ ) { - -/* Arguments. */ -/* ---------- */ -/* Create an appropriate keyword and write out the argument value, - accompanied by the descriptive comment obtained above. */ - (void) sprintf( key, "Sla%d%c", icvt + 1, ALPHABET[ iarg ] ); - astWriteDouble( channel, key, 1, 1, this->cvtargs[ icvt ][ iarg ], - argdesc[ iarg ] ); - } - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - } - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASlaMap and astCheckSlaMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SlaMap,Mapping) -astMAKE_CHECK(SlaMap) - -AstSlaMap *astSlaMap_( int flags, const char *options, int *status, ...) { -/* -*++ -* Name: -c astSlaMap -f AST_SLAMAP - -* Purpose: -* Create an SlaMap. - -* Type: -* Public function. - -* Synopsis: -c #include "slamap.h" -c AstSlaMap *astSlaMap( int flags, const char *options, ... ) -f RESULT = AST_SLAMAP( FLAGS, OPTIONS, STATUS ) - -* Class Membership: -* SlaMap constructor. - -* Description: -* This function creates a new SlaMap and optionally initialises -* its attributes. -* -* An SlaMap is a specialised form of Mapping which can be used to -* represent a sequence of conversions between standard celestial -* (longitude, latitude) coordinate systems. -* -* When an SlaMap is first created, it simply performs a unit -c (null) Mapping on a pair of coordinates. Using the astSlaAdd -f (null) Mapping on a pair of coordinates. Using the AST_SLAADD -c function, a series of coordinate conversion steps may then be -f routine, a series of coordinate conversion steps may then be -* added, selected from those provided by the SLALIB Positional -* Astronomy Library (Starlink User Note SUN/67). This allows -* multi-step conversions between a variety of celestial coordinate -* systems to be assembled out of the building blocks provided by -* SLALIB. -* -* For details of the individual coordinate conversions available, -c see the description of the astSlaAdd function. -f see the description of the AST_SLAADD routine. - -* Parameters: -c flags -f FLAGS = INTEGER (Given) -c This parameter is reserved for future use and should currently -f This argument is reserved for future use and should currently -* always be set to zero. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new SlaMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new SlaMap. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSlaMap() -f AST_SLAMAP = INTEGER -* A pointer to the new SlaMap. - -* Notes: -* - The Nin and Nout attributes (number of input and output -* coordinates) for an SlaMap are both equal to 2. The first -* coordinate is the celestial longitude and the second coordinate -* is the celestial latitude. All coordinate values are in radians. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSlaMap *new; /* Pointer to the new SlaMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SlaMap, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSlaMap( NULL, sizeof( AstSlaMap ), !class_init, &class_vtab, - "SlaMap", flags ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SlaMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new SlaMap. */ - return new; -} - -AstSlaMap *astSlaMapId_( int flags, const char *options, ... ) { -/* -* Name: -* astSlaMapId_ - -* Purpose: -* Create an SlaMap. - -* Type: -* Private function. - -* Synopsis: -* #include "slamap.h" -* AstSlaMap *astSlaMapId_( int flags, const char *options, ... ) - -* Class Membership: -* SlaMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astSlaMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astSlaMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astSlaMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astSlaMap_. - -* Returned Value: -* The ID value associated with the new SlaMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSlaMap *new; /* Pointer to the new SlaMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SlaMap, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSlaMap( NULL, sizeof( AstSlaMap ), !class_init, &class_vtab, - "SlaMap", flags ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SlaMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new SlaMap. */ - return astMakeId( new ); -} - -AstSlaMap *astInitSlaMap_( void *mem, size_t size, int init, - AstSlaMapVtab *vtab, const char *name, - int flags, int *status ) { -/* -*+ -* Name: -* astInitSlaMap - -* Purpose: -* Initialise an SlaMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "slamap.h" -* AstSlaMap *astInitSlaMap( void *mem, size_t size, int init, -* AstSlaMapVtab *vtab, const char *name, -* int flags ) - -* Class Membership: -* SlaMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new SlaMap object. It allocates memory (if necessary) to accommodate -* the SlaMap plus any additional data associated with the derived class. -* It then initialises an SlaMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for an SlaMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SlaMap is to be initialised. -* This must be of sufficient size to accommodate the SlaMap data -* (sizeof(SlaMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the SlaMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the SlaMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the SlaMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new SlaMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astClass -* method). -* flags -* This parameter is reserved for future use. It is currently ignored. - -* Returned Value: -* A pointer to the new SlaMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstSlaMap *new; /* Pointer to the new SlaMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSlaMapVtab( vtab, name ); - -/* Initialise a Mapping structure (the parent class) as the first component - within the SlaMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstSlaMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - 2, 2, 1, 1 ); - - if ( astOK ) { - -/* Initialise the SlaMap data. */ -/* --------------------------- */ -/* The initial state is with no SLALIB conversions set, in which condition the - SlaMap simply implements a unit mapping. */ - new->ncvt = 0; - new->cvtargs = NULL; - new->cvtextra = NULL; - new->cvttype = NULL; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstSlaMap *astLoadSlaMap_( void *mem, size_t size, - AstSlaMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSlaMap - -* Purpose: -* Load a SlaMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "slamap.h" -* AstSlaMap *astLoadSlaMap( void *mem, size_t size, -* AstSlaMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* SlaMap loader. - -* Description: -* This function is provided to load a new SlaMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* SlaMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a SlaMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the SlaMap is to be -* loaded. This must be of sufficient size to accommodate the -* SlaMap data (sizeof(SlaMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SlaMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SlaMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstSlaMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SlaMap. If this is NULL, a pointer to -* the (static) virtual function table for the SlaMap class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "SlaMap" is used instead. - -* Returned Value: -* A pointer to the new SlaMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstSlaMap *new; /* Pointer to the new SlaMap */ - char *sval; /* Pointer to string value */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - const char *argdesc[ MAX_SLA_ARGS ]; /* Pointers to argument descriptions */ - const char *comment; /* Pointer to comment string */ - int iarg; /* Loop counter for arguments */ - int icvt; /* Loop counter for conversion steps */ - int nargs; /* Number of conversion arguments */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SlaMap. In this case the - SlaMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSlaMap ); - vtab = &class_vtab; - name = "SlaMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSlaMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built SlaMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "SlaMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Number of conversion steps. */ -/* --------------------------- */ -/* Read the number of conversion steps and allocate memory to hold - data for each step. */ - new->ncvt = astReadInt( channel, "nsla", 0 ); - if ( new->ncvt < 0 ) new->ncvt = 0; - new->cvttype = astMalloc( sizeof( int ) * (size_t) new->ncvt ); - new->cvtargs = astMalloc( sizeof( double * ) * (size_t) new->ncvt ); - new->cvtextra = astMalloc( sizeof( double * ) * (size_t) new->ncvt ); - -/* If an error occurred, ensure that all allocated memory is freed. */ - if ( !astOK ) { - new->cvttype = astFree( new->cvttype ); - new->cvtargs = astFree( new->cvtargs ); - new->cvtextra = astFree( new->cvtextra ); - -/* Otherwise, initialise the argument pointer array. */ - } else { - for ( icvt = 0; icvt < new->ncvt; icvt++ ) { - new->cvtargs[ icvt ] = NULL; - new->cvtextra[ icvt ] = NULL; - } - -/* Read in data for each conversion step... */ - for ( icvt = 0; icvt < new->ncvt; icvt++ ) { - -/* Conversion type. */ -/* ---------------- */ -/* Create an appropriate keyword and read the string representation of - the conversion type. */ - (void) sprintf( key, "sla%d", icvt + 1 ); - sval = astReadString( channel, key, NULL ); - -/* If no value was read, report an error. */ - if ( astOK ) { - if ( !sval ) { - astError( AST__BADIN, - "astRead(%s): An SLALIB sky coordinate conversion " - "type is missing from the input SlaMap data.", status, - astGetClass( channel ) ); - -/* Otherwise, convert the string representation into the required - conversion type code. */ - } else { - new->cvttype[ icvt ] = CvtCode( sval, status ); - -/* If the string was not recognised, report an error. */ - if ( new->cvttype[ icvt ] == AST__SLA_NULL ) { - astError( AST__BADIN, - "astRead(%s): Invalid SLALIB sky conversion " - "type \"%s\" in SlaMap data.", status, - astGetClass( channel ), sval ); - } - } - -/* Free the memory holding the string value. */ - sval = astFree( sval ); - } - -/* Obtain the number of arguments associated with the conversion and - allocate memory to hold them. */ - (void) CvtString( new->cvttype[ icvt ], &comment, &nargs, - argdesc, status ); - new->cvtargs[ icvt ] = astMalloc( sizeof( double ) * - (size_t) nargs ); - -/* Read in data for each argument... */ - if ( astOK ) { - for ( iarg = 0; iarg < nargs; iarg++ ) { - -/* Arguments. */ -/* ---------- */ -/* Create an appropriate keyword and read each argument value. */ - (void) sprintf( key, "sla%d%c", icvt + 1, ALPHABET[ iarg ] ); - new->cvtargs[ icvt ][ iarg ] = astReadDouble( channel, key, - AST__BAD ); - } - } - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - } - -/* If an error occurred, clean up by deleting the new SlaMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new SlaMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -void astSlaAdd_( AstSlaMap *this, const char *cvt, int narg, const double args[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,SlaMap,SlaAdd))( this, cvt, narg, args, status ); -} - -int astSlaIsEmpty_( AstSlaMap *this, int *status ) { - if ( !astOK ) return 1; - return (**astMEMBER(this,SlaMap,SlaIsEmpty))( this, status ); -} - diff --git a/ast/slamap.h b/ast/slamap.h deleted file mode 100644 index e7280b8..0000000 --- a/ast/slamap.h +++ /dev/null @@ -1,330 +0,0 @@ -#if !defined( SLAMAP_INCLUDED ) /* Include this file only once */ -#define SLAMAP_INCLUDED -/* -*+ -* Name: -* slamap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the SlaMap class. - -* Invocation: -* #include "slamap.h" - -* Description: -* This include file defines the interface to the SlaMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The SlaMap class encapsulates the conversions provided by the -* SLALIB library (SUN/67) for converting between different sky -* coordinate systems. Since, typically, a sequence of these -* SLALIB conversions is required, an SlaMap can be used to -* accumulate a series of conversions which it then applies in -* sequence. - -* Inheritance: -* The SlaMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* astTransform -* Use an SlaMap to transform a set of points. - -* Protected: -* astMapMerge -* Simplify a sequence of Mappings containing an SlaMap. - -* New Methods Defined: -* Public: -* astSlaAdd -* Add a coordinate conversion step to an SlaMap. - -* Private: -* None. - -* Other Class Functions: -* Public: -* astIsASlaMap -* Test class membership. -* astSlaMap -* Create an SlaMap. - -* Protected: -* astCheckSlaMap -* Validate class membership. -* astInitSlaMap -* Initialise an SlaMap. -* astLoadSlaMap -* Load an SlaMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstSlaMap -* SlaMap object type. - -* Protected: -* AstSlaMapVtab -* SlaMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 26-APR-1996 (RFWS): -* Original version. -* 26-SEP-1996 (RFWS): -* Added external interface and I/O facilities. -* 23-MAY-1997 (RFWS): -* Over-ride the astMapMerge method. -* 15-OCT-2002 (DSB): -* Added astSTPConv, astSTPConv1, and STP coordinate system macros. -* 8-JAN-2003 (DSB): -* Added protected astInitSlaMapVtab method. -* 22-FEB-2006 (DSB): -* Added cvtextra to the AstSlaMap structure. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - - -/* Macros */ -/* ====== */ -#if defined(astCLASS) /* Protected */ -#define AST__NOSTP -1 /* An invalid value for an STP coordinate system */ -#define AST__HAE 0 /* Heliocentric-aries-ecliptic spherical coordinates */ -#define AST__HAEC 1 /* Heliocentric-aries-ecliptic cartesian coordinates */ -#define AST__HAQ 2 /* Heliocentric-aries-equatorial spherical coordinates */ -#define AST__HAQC 3 /* Heliocentric-aries-equatorial cartesian coordinates */ -#define AST__HG 4 /* Heliographic spherical coordinates */ -#define AST__HGC 5 /* Heliographic cartesian coordinates */ -#define AST__HPC 6 /* Helioprojective-cartesian spherical coordinates */ -#define AST__HPCC 7 /* Helioprojective-cartesian cartesian coordinates */ -#define AST__HPR 8 /* Helioprojective-radial spherical coordinates */ -#define AST__HPRC 9 /* Helioprojective-radial cartesian coordinates */ -#define AST__GSE 10 /* Geocentric-solar-ecliptic spherical coordinates */ -#define AST__GSEC 11 /* Geocentric-solar-ecliptic cartesian coordinates */ -#endif - -/* One IAU astronomical unit, in metres. */ -#define AST__AU 1.49597870E11 - -/* One solar radius (top of photosphere?), in metres (from "The Explanatory - Supplement to the Astronomical Almanac"). */ -#define AST__SOLRAD 6.96E8 - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* SlaMap structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstSlaMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int *cvttype; /* Pointer to array of conversion types */ - double **cvtargs; /* Pointer to argument list pointer array */ - double **cvtextra; /* Pointer to intermediate values pointer array */ - int ncvt; /* Number of conversions to perform */ -} AstSlaMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstSlaMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* SlaAdd)( AstSlaMap *, const char *, int, const double[], int * ); - int (* SlaIsEmpty)( AstSlaMap *, int * ); -} AstSlaMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstSlaMapGlobals { - AstSlaMapVtab Class_Vtab; - int Class_Init; - double Eq_Cache; - double Ep_Cache; - double Amprms_Cache[ 21 ]; -} AstSlaMapGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(SlaMap) /* Check class membership */ -astPROTO_ISA(SlaMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstSlaMap *astSlaMap_( int, const char *, int *, ...); -#else -AstSlaMap *astSlaMapId_( int, const char *, ... )__attribute__((format(printf,2,3))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstSlaMap *astInitSlaMap_( void *, size_t, int, AstSlaMapVtab *, - const char *, int, int * ); - -/* Vtab initialiser. */ -void astInitSlaMapVtab_( AstSlaMapVtab *, const char *, int * ); - -/* Loader. */ -AstSlaMap *astLoadSlaMap_( void *, size_t, AstSlaMapVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitSlaMapGlobals_( AstSlaMapGlobals * ); -#endif - -/* Other functions. */ -void astSTPConv1_( double, int, double[3], double[3], int, double[3], double[3], int * ); -void astSTPConv_( double, int, int, double[3], double *[3], int, double[3], double *[3], int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -void astSlaAdd_( AstSlaMap *, const char *, int, const double[], int * ); -int astSlaIsEmpty_( AstSlaMap *, int * ); - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckSlaMap(this) astINVOKE_CHECK(SlaMap,this,0) -#define astVerifySlaMap(this) astINVOKE_CHECK(SlaMap,this,1) - -/* Test class membership. */ -#define astIsASlaMap(this) astINVOKE_ISA(SlaMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astSlaMap astINVOKE(F,astSlaMap_) -#else -#define astSlaMap astINVOKE(F,astSlaMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitSlaMap(mem,size,init,vtab,name,flags) \ -astINVOKE(O,astInitSlaMap_(mem,size,init,vtab,name,flags,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitSlaMapVtab(vtab,name) astINVOKE(V,astInitSlaMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadSlaMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadSlaMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckSlaMap to validate SlaMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -#define astSlaAdd(this,cvt,narg,args) \ -astINVOKE(V,astSlaAdd_(astCheckSlaMap(this),cvt,narg,args,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astSTPConv astSTPConv_ -#define astSTPConv1 astSTPConv1_ -#define astSlaIsEmpty(this) astINVOKE(V,astSlaIsEmpty_(astCheckSlaMap(this),STATUS_PTR)) -#endif - -#endif - - - - - diff --git a/ast/specfluxframe.c b/ast/specfluxframe.c deleted file mode 100644 index ea00d49..0000000 --- a/ast/specfluxframe.c +++ /dev/null @@ -1,2189 +0,0 @@ -/* -*class++ -* Name: -* SpecFluxFrame - -* Purpose: -* Compound spectrum/flux Frame. - -* Constructor Function: -c astSpecFluxFrame -f AST_SPECFLUXFRAME - -* Description: -* A SpecFluxFrame combines a SpecFrame and a FluxFrame into a single -* 2-dimensional compound Frame. Such a Frame can for instance be used -* to describe a Plot of a spectrum in which the first axis represents -* spectral position and the second axis represents flux. - -* Inheritance: -* The SpecFluxFrame class inherits from the CmpFrame class. - -* Attributes: -* The SpecFluxFrame class does not define any new attributes beyond -* those which are applicable to all CmpFrames. However, the attributes -* of the component Frames can be accessed as if they were attributes -* of the SpecFluxFrame. For instance, the SpecFluxFrame will recognise -* the "StdOfRest" attribute and forward access requests to the component -* SpecFrame. An axis index can optionally be appended to the end of any -* attribute name, in which case the request to access the attribute will -* be forwarded to the primary Frame defining the specified axis. - -* Functions: -c The SpecFluxFrame class does not define any new functions beyond those -f The SpecFluxFrame class does not define any new routines beyond those -* which are applicable to all CmpFrames. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 8-DEC-2004 (DSB): -* Original version. -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS SpecFluxFrame - -/* Define the first and last acceptable System values. */ -#define FIRST_SYSTEM AST__COMP -#define LAST_SYSTEM AST__COMP - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "mapping.h" /* Coordinate Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "permmap.h" /* Coordinate permutation Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "axis.h" /* Coordinate axes */ -#include "cmpframe.h" /* Parent CmpFrame class */ -#include "tranmap.h" /* Separated transformation Mappings */ -#include "mathmap.h" /* Algebraic Mappings */ -#include "ratemap.h" /* Differential Mappings */ -#include "specframe.h" /* SpecFrame class */ -#include "fluxframe.h" /* FluxFrame class */ -#include "specfluxframe.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int (* parent_subframe)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static const char *(* parent_gettitle)( AstFrame *, int * ); - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetTitle_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(SpecFluxFrame) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SpecFluxFrame,Class_Init) -#define class_vtab astGLOBAL(SpecFluxFrame,Class_Vtab) -#define gettitle_buff astGLOBAL(SpecFluxFrame,GetTitle_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char gettitle_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSpecFluxFrameVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSpecFluxFrame *astSpecFluxFrameId_( void *, void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstFluxFrame *GetFluxFrame( AstSpecFluxFrame *, int, int * ); -static AstMapping *MakeMap2( AstSpecFluxFrame *, int * ); -static AstMapping *MakeMap3( AstSpecFluxFrame *, AstSpecFluxFrame *, int * ); -static AstMapping *MakeMapF( AstFluxFrame *, AstSpecFrame *, AstFluxFrame *, AstSpecFrame *, int * ); -static AstMapping *MakeMapI( AstFluxFrame *, AstSpecFrame *, AstFluxFrame *, AstSpecFrame *, int * ); -static AstSpecFrame *GetSpecFrame( AstSpecFluxFrame *, int, int * ); -static const char *GetTitle( AstFrame *, int * ); -static int MakeSFMapping( AstSpecFluxFrame *, AstSpecFluxFrame *, AstMapping **, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static void Dump( AstObject *, AstChannel *, int * ); - -/* Member functions. */ -/* ================= */ - -static AstFluxFrame *GetFluxFrame( AstSpecFluxFrame *this, int std, int *status ){ -/* -* Name: -* GetFluxFrame - -* Purpose: -* Return a pointer to the FluxFrame in a FluxSpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* AstFluxFrame *GetFluxFrame( AstSpecFluxFrame *this, int std, int *status ) - -* Class Membership: -* SpecFluxFrame member function. - -* Description: -* Returns a pointer to the FluxFrame in a SpecFluxFrame. - -* Parameters: -* this -* Pointer to the SpecFluxFrame. -* std -* If non zero, then the returned FluxFrame is a standardised copy of -* the FluxFrame in the supplied SpecFluxFrame, in which the System has -* been set explicitly (rather than potentially being defaulted), and -* the Units have been cleared to use default units appropriate to -* the flux System. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the FluxFrame. Should be freed using astAnnul when no -* longer needed. - -* Notes: -* NULL is returned if this function is invoked with the global error -* status set or if it should fail for any reason. -*/ - -/* Local Variables; */ - AstFluxFrame *ff; - AstFluxFrame *ret; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* The FluxFrame is always the second Frame in the parent CmpFrame. */ - ff = (AstFluxFrame *) ((AstCmpFrame *)this)->frame2; - -/* Produce a standardised copy of the FluxFrame if required, or clone the - above pointer otherwise. */ - if( std ) { - ret = astCopy( ff ); - astSetSystem( ret, astGetSystem( ff ) ); - astClearUnit( ret, 0 ); - } else { - ret = astClone( ff ); - } - -/* Annul the returned pointer if anything went wrong. */ - if( !astOK ) ret = astAnnul( ret ); - -/* Return the result. */ - return ret; -} - -static AstSpecFrame *GetSpecFrame( AstSpecFluxFrame *this, int std, int *status ){ -/* -* Name: -* GetSpecFrame - -* Purpose: -* Return a pointer to the SpecFrame in a FluxSpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* AstSpecFrame *GetSpecFrame( AstSpecFluxFrame *this, int std, int *status ) - -* Class Membership: -* SpecFluxFrame member function. - -* Description: -* Returns a pointer to the SpecFrame in a SpecFluxFrame. - -* Parameters: -* this -* Pointer to the SpecFluxFrame. -* std -* If non zero, then the returned SpecFrame is a standardised copy of -* the SpecFrame in the supplied SpecFluxFrame, in which the System -* and Units have been set explicitly to the values appropriate to the -* flux system in use in the FluxFrame in the supplied SpecFluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the FluxFrame. Should be freed using astAnnul when no -* longer needed. - -* Notes: -* NULL is returned if this function is invoked with the global error -* status set or if it should fail for any reason. -*/ - -/* Local Variables; */ - AstFluxFrame *ff; - AstSpecFrame *ret; - AstSpecFrame *sf; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the SpecFrame (the first Frame in the parent CmpFrame). */ - sf = (AstSpecFrame *) ((AstCmpFrame *)this)->frame1; - -/* If we want a standardised version of the SpecFrame... */ - if( std ) { - -/* The FluxFrame is always the second Frame in the parent CmpFrame. */ - ff = (AstFluxFrame *) ((AstCmpFrame *)this)->frame2; - -/* Produce a copy of the SpecFrame and set its System and Units - appropriate to the flux system (expressed in default units). */ - ret = astCopy( sf ); - astSetSystem( ret, astGetDensitySystem( ff ) ); - astSetUnit( ret, 0, astGetDensityUnit( ff ) ); - -/* If we are not standardising the SpecFrame, just return a clone of the - pointer in the parent CmpFrame. */ - } else { - ret = astClone( sf ); - } - -/* Annul the returned pointer if anything went wrong. */ - if( !astOK ) ret = astAnnul( ret ); - -/* Return the result. */ - return ret; -} - -static const char *GetTitle( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetTitle - -* Purpose: -* Obtain a pointer to the Title string for a SpecFluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* const char *GetTitle( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFluxFrame member function (over-rides the astGetTitle method -* inherited from the CmpFrame class). - -* Description: -* This function returns a pointer to the Title string for a SpecFluxFrame. -* A pointer to a suitable default string is returned if no Title value has -* previously been set. - -* Parameters: -* this -* Pointer to the SpecFluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null-terminated character string containing the requested -* information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - AstSpecFluxFrame *this; - AstSpecFrame *sf; - AstFluxFrame *ff; - const char *result; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_frame); - -/* Initialise. */ - result = NULL; - -/* Obtain a pointer to the SpecFluxFrame structure. */ - this = (AstSpecFluxFrame *) this_frame; - -/* See if a Title string has been set. If so, use the parent astGetTitle - method to obtain a pointer to it. */ - if ( astTestTitle( this ) ) { - result = (*parent_gettitle)( this_frame, status ); - -/* Otherwise, we will generate a default Title string. Obtain the values of the - SpecFrame's attributes that determine what this string will be. */ - } else { - ff = GetFluxFrame( this, 0, status ); - sf = GetSpecFrame( this, 0, status ); - - if( astOK ) { - sprintf( gettitle_buff, "%s versus %s", astGetLabel( ff, 0 ), - astGetLabel( sf, 0 ) ); - gettitle_buff[ 0 ] = toupper( gettitle_buff[ 0 ] ); - result = gettitle_buff; - } - - ff = astAnnul( ff ); - sf = astAnnul( sf ); - - } - -/* If an error occurred, clear the returned pointer value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -void astInitSpecFluxFrameVtab_( AstSpecFluxFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSpecFluxFrameVtab - -* Purpose: -* Initialise a virtual function table for a SpecFluxFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specfluxframe.h" -* void astInitSpecFluxFrameVtab( AstSpecFluxFrameVtab *vtab, const char *name ) - -* Class Membership: -* SpecFluxFrame vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SpecFluxFrame class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitCmpFrameVtab( (AstCmpFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASpecFluxFrame) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstCmpFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - frame = (AstFrameVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - - parent_match = frame->Match; - frame->Match = Match; - - parent_subframe = frame->SubFrame; - frame->SubFrame = SubFrame; - - parent_gettitle = frame->GetTitle; - frame->GetTitle = GetTitle; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetDump( vtab, Dump, "SpecFluxFrame", - "Compound spectral/flux coordinate system description" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static AstMapping *MakeMap2( AstSpecFluxFrame *this, int *status ){ -/* -* Name: -* MakeMap2 - -* Purpose: -* Generate the second Mapping required by MakeSFMapping - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* AstMapping *MakeMap2( AstSpecFluxFrame *this, int *status ) - -* Class Membership: -* SpecFluxFrame member function. - -* Description: -* The second Mapping used by MakeSFMapping contains three Mappings in -* parallel which converts v1 (flux value) and x1 (spectral position) into -* default units, and passes the third axis (a copy of flux value) -* unchanged. - -* Parameters: -* this -* Pointer to the SpecFluxFrame to use. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the required Mapping, or NULL if the Mapping cannot be -* created. The Mapping will have 3 inputs and 3 outputs. - -* Notes: -* NULL is returned if this function is invoked with the global error -* status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *f1; - AstFrame *f2; - AstFrameSet *fs; - AstMapping *ax1_map; - AstMapping *ax2_map; - AstMapping *ax3_map; - AstMapping *ret; - AstMapping *tmap; - -/* Initialise. */ - ret = NULL; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Input 0 is the supplied FluxFrame value and output 0 is the corresponding - value in the default units for the FluxFrame system. Take a copy of the - supplied FluxFrame, and fix its System value (which may be a default value - based on the Units string), and then clear the Units so that it represents - default units for the System. */ - f1 = (AstFrame *) GetFluxFrame( this, 0, status ); - f2 = (AstFrame *) GetFluxFrame( this, 1, status ); - -/* Now, if conversion was possible, get the Mapping from the supplied - FluxFrame to the default units FluxFrame. */ - fs = astConvert( f1, f2, "" ); - f1 = astAnnul( f1 ); - f2 = astAnnul( f2 ); - - if( fs ) { - ax1_map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - fs = astAnnul( fs ); - -/* Input 1 is the supplied SpecFrame value and output 1 is the corresponding - value in the spectral system used by the flux system (wavelength or - frequency). Take a copy of the supplied SpecFrame, and fix its System - value to wavelength or frequency (depending on the System value of the - FluxFrame), and set up units of Hz or Angstrom (these are the spectral - position units used within the default flux units for a FluxFrame). */ - f1 = (AstFrame *) GetSpecFrame( this, 0, status ); - f2 = (AstFrame *) GetSpecFrame( this, 1, status ); - -/* Now, if conversion was possible, get the Mapping from the supplied - SpecFrame to the required SpecFrame. */ - fs = astConvert( f1, f2, "" ); - f1 = astAnnul( f1 ); - f2 = astAnnul( f2 ); - - if( fs ) { - ax2_map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - fs = astAnnul( fs ); - -/* Create a UnitMap for the 3rd axis. */ - ax3_map = (AstMapping *) astUnitMap( 1, "", status ); - -/* Create a parallel CmpMap containing the three Mappings. */ - tmap = (AstMapping *) astCmpMap( ax1_map, ax2_map, 0, "", status ); - ret = (AstMapping *) astCmpMap( tmap, ax3_map, 0, "", status ); - -/* Free remaining resources. */ - tmap = astAnnul( tmap ); - ax2_map = astAnnul( ax2_map ); - ax3_map = astAnnul( ax3_map ); - - } - ax1_map = astAnnul( ax1_map ); - } - -/* If an error has occurred, return NULL. */ - if( !astOK ) ret = astAnnul( ret ); - -/* Return the result */ - return ret; -} - -static AstMapping *MakeMap3( AstSpecFluxFrame *target, AstSpecFluxFrame *result, int *status ){ -/* -* Name: -* MakeMap3 - -* Purpose: -* Generate the third Mapping required by MakeSFMapping - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* AstMapping *MakeMap3( AstSpecFluxFrame *target, AstSpecFluxFrame *result, int *status ) - -* Class Membership: -* SpecFluxFrame member function. - -* Description: -* The third Mapping used by MakeSFMapping converts input (v1,x1) in -* default units to output (v2,x2) in default units. The third axis (x1) -* in original units is converted to x2 in original units. - -* Parameters: -* target -* Pointer to the first SpecFluxFrame. -* result -* Pointer to the second SpecFluxFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the required Mapping, or NULL if the Mapping cannot be -* created. The Mapping will have 3 inputs and 3 outputs. - -* Notes: -* NULL is returned if this function is invoked with the global error -* status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstFluxFrame *ff2; - AstFluxFrame *ff1; - AstFrameSet *fs; - AstMapping *fmap; - AstMapping *imap; - AstMapping *mapa; - AstMapping *mapb; - AstMapping *ret; - AstSpecFrame *sf2; - AstSpecFrame *sf1; - -/* Initialise */ - ret = NULL; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* The first two inputs and outputs are related by a TranMap which - converts between standardised (v1,x1) and standardised (v2,x2). Get - pointers to the standardised SpecFrames and FluxFrames in the two - supplied SpecFluxFrames. */ - ff1 = GetFluxFrame( target, 1, status ); - sf1 = GetSpecFrame( target, 1, status ); - ff2 = GetFluxFrame( result, 1, status ); - sf2 = GetSpecFrame( result, 1, status ); - -/* Create the Mapping which defines the forward transformation of the - required TranMap. The forward transformation of this Mapping goes from - (v1,x1) to (v2,x2). */ - fmap = MakeMapF( ff1, sf1, ff2, sf2, status ); - -/* Create the Mapping which defines the inverse transformation of the - required TranMap. The inverse transformation of this Mapping goes from - (v2,x2) to (v1,x1). */ - imap = MakeMapI( ff1, sf1, ff2, sf2, status ); - -/* Combine these into a TranMap */ - if( fmap && imap ) { - mapa = (AstMapping *) astTranMap( fmap, imap, "", status ); - } else { - mapa = NULL; - } - -/* Free resources. */ - ff1 = astAnnul( ff1 ); - sf1 = astAnnul( sf1 ); - ff2 = astAnnul( ff2 ); - sf2 = astAnnul( sf2 ); - if( fmap ) fmap = astAnnul( fmap ); - if( imap ) imap = astAnnul( imap ); - -/* The third input and output are related by a Mapping which converts - between supplied (x1) and supplied (x2). Get pointers to the original - unmodified SpecFrames in the two supplied SpecFluxFrames. */ - sf1 = GetSpecFrame( target, 0, status ); - sf2 = GetSpecFrame( result, 0, status ); - -/* Find the Mapping from the first to the second. */ - fs = astConvert( sf1, sf2, "" ); - if( fs ) { - mapb = astGetMapping( fs, AST__BASE, AST__CURRENT ); - fs = astAnnul( fs ); - } else { - mapb = NULL; - } - -/* Free resources. */ - sf1 = astAnnul( sf1 ); - sf2 = astAnnul( sf2 ); - -/* Combine the two Mappings in parallel. */ - if( mapa && mapb ) ret = (AstMapping *) astCmpMap( mapa, mapb, 0, "", status ); - if( mapa ) mapa = astAnnul( mapa ); - if( mapb ) mapb = astAnnul( mapb ); - -/* If an error has occurred, return NULL. */ - if( !astOK ) ret = astAnnul( ret ); - -/* Return the result */ - return ret; -} - -static AstMapping *MakeMapF( AstFluxFrame *v1, AstSpecFrame *x1, - AstFluxFrame *v2, AstSpecFrame *x2, int *status ){ -/* -* Name: -* MakeMapF - -* Purpose: -* Generate the forward part of the third Mapping required by MakeSFMapping - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* AstMapping *MakeMapF( AstFluxFrame *v1, AstSpecFrame *x1, -* AstFluxFrame *v2, AstSpecFrame *x2, int *status ) - -* Class Membership: -* SpecFluxFrame member function. - -* Description: -* Theis creates a 2-input 2-output Mapping which transforms -* input (v1,x1) in default units to output (v2,x2) in default units. - -* Parameters: -* v1 -* Pointer to the standardised input FluxFrame. -* x1 -* Pointer to the standardised input SpecFrame. -* v2 -* Pointer to the standardised output FluxFrame. -* x2 -* Pointer to the standardised output SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the required Mapping, or NULL if the Mapping cannot be -* created. - -* Notes: -* NULL is returned if this function is invoked with the global error -* status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpMap *cmap1; - AstCmpMap *cmap2; - AstCmpMap *cmap3; - AstFrameSet *fs; - AstMapping *m; - AstMapping *ret; - AstMathMap *div; - AstPermMap *perm; - AstRateMap *rate; - AstUnitMap *unit; - const char *fwd[1]; - const char *inv[2]; - int inperm[ 2 ]; - int outperm[ 3 ]; - -/* Initialise */ - ret = NULL; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* First create the required component Mappings. - --------------------------------------------- */ - -/* A Mapping which maps input spectral position (x1) into output spectral - position (x2). */ - fs = astConvert( x1, x2, "" ); - if( fs ) { - m = astGetMapping( fs, AST__BASE, AST__CURRENT ); - -/* A 1-input 1-output Mapping in which the input is spectral position (x1) - and the output is the rate of change of output spectral position (x2) - with respect to input spectral position (x1). */ - rate = astRateMap( m, 0, 0, "", status ); - -/* A MathMap which is used to divide the flux value (v1) by the absolute rate - of change of x2 wrt x1 */ - fwd[ 0 ] = "out=in0/abs(in1)"; - inv[ 0 ] = "in0"; - inv[ 1 ] = "in1"; - div = astMathMap( 2, 1, 1, fwd, 2, inv, "", status ); - -/* A 1D UnitMap used to copy v1. */ - unit = astUnitMap( 1, "", status ); - -/* A PermMap which is used to produce an extra output copy of x1. */ - inperm[ 0 ] = 0; - inperm[ 1 ] = 2; - outperm[ 0 ] = 0; - outperm[ 1 ] = 1; - outperm[ 2 ] = 1; - perm = astPermMap( 2, inperm, 3, outperm, NULL, "", status ); - -/* Now combine these component Mappings together. - --------------------------------------------- */ - -/* First put the UnitMap and the RateMap in parallel. This produces a 2-in - 2-out Mapping in which the inputs are (v1,x1) and the outputs are - (v1,dx2/dx1). */ - cmap1 = astCmpMap( unit, rate, 0, "", status ); - -/* Now put this in series with the dividing MathMap. This results in a - 2-in, 1-out Mapping in which the inputs are v1 and x1 and the single - output is v2. */ - cmap2 = astCmpMap( cmap1, div, 1, "", status ); - -/* Now put this in parallel with the x1->x2 Mapping. This results in a - 3-in, 2-out Mapping in which the inputs are (v1,x1,x1) and the outputs - are (v2,x2). */ - cmap3 = astCmpMap( cmap2, m, 0, "", status ); - -/* Finally put this in series with the PermMap. This results in a 2-in, - 2-out Mapping in which the inputs are (v1,x1) and the outputs are - (v2,x2). */ - ret = (AstMapping *) astCmpMap( perm, cmap3, 1, "", status ); - -/* Free resources. */ - fs = astAnnul( fs ); - m = astAnnul( m ); - rate = astAnnul( rate ); - div= astAnnul( div ); - unit = astAnnul( unit ); - perm = astAnnul( perm ); - cmap1 = astAnnul( cmap1 ); - cmap2 = astAnnul( cmap2 ); - cmap3 = astAnnul( cmap3 ); - } - -/* If an error has occurred, return NULL. */ - if( !astOK ) ret = astAnnul( ret ); - -/* Return the result */ - return ret; -} - -static AstMapping *MakeMapI( AstFluxFrame *v1, AstSpecFrame *x1, - AstFluxFrame *v2, AstSpecFrame *x2, int *status ){ -/* -* Name: -* MakeMapI - -* Purpose: -* Generate the inverse part of the third Mapping required by MakeSFMapping - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* AstMapping *MakeMapI( AstFluxFrame *v1, AstSpecFrame *x1, -* AstFluxFrame *v2, AstSpecFrame *x2 ) - -* Class Membership: -* SpecFluxFrame member function. - -* Description: -* This creates a 2-input 2-output Mapping in which the inverse -* transformation transforms "outputs" representing (v2,x2) into -* "inputs" representing (v1,x1). - -* Parameters: -* v1 -* Pointer to the standardised input FluxFrame. -* x1 -* Pointer to the standardised input SpecFrame. -* v2 -* Pointer to the standardised output FluxFrame. -* x2 -* Pointer to the standardised output SpecFrame. - -* Returned Value: -* A pointer to the required Mapping, or NULL if the Mapping cannot be -* created. - -* Notes: -* NULL is returned if this function is invoked with the global error -* status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstCmpMap *cmap1; - AstCmpMap *cmap2; - AstCmpMap *cmap3; - AstCmpMap *cmap4; - AstCmpMap *cmap5; - AstFrameSet *fs; - AstMapping *m; - AstMapping *ret; - AstMathMap *mult; - AstPermMap *perm; - AstRateMap *rate; - AstUnitMap *unit; - const char *fwd[1]; - const char *inv[2]; - int inperm[ 2 ]; - int outperm[ 3 ]; - -/* Initialise */ - ret = NULL; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* We create a CmpMap in which the forward transformation foes from - (v2,x2) to (v1,x1) and we finally invert this Mapping to get the - required Mapping in which the *inverse* transformation goes from - (v2,x2) to (v1,x1). - - First create the required component Mappings. - --------------------------------------------- */ - -/* A Mapping which maps spectral position x1 into spectral position x2. */ - fs = astConvert( x1, x2, "" ); - if( fs ) { - m = astGetMapping( fs, AST__BASE, AST__CURRENT ); - -/* A 1-input 1-output Mapping in which the input is spectral position x1 - and the output is the rate of change of spectral position x2 with - respect to spectral position x1. */ - rate = astRateMap( m, 0, 0, "", status ); - -/* Now invert "m" so that its forward transformation goes from x2 to x1. - The RateMap created above retains a copy of the original Invert flag - for "m" and uses it in preference to the current value when transforming - points. */ - astInvert( m ); - -/* A MathMap which is used to multiple the flux value v2 by the - absolute rate of change of x2 wrt x1 */ - fwd[ 0 ] = "out=in0*abs(in1)"; - inv[ 0 ] = "in0"; - inv[ 1 ] = "in1"; - mult = astMathMap( 2, 1, 1, fwd, 2, inv, "", status ); - -/* A 1D UnitMap used to copy various values. */ - unit = astUnitMap( 1, "", status ); - -/* A PermMap which is used to produce an extra copy of x1. */ - inperm[ 0 ] = 0; - inperm[ 1 ] = 2; - outperm[ 0 ] = 0; - outperm[ 1 ] = 1; - outperm[ 2 ] = 1; - perm = astPermMap( 2, inperm, 3, outperm, NULL, "", status ); - -/* Now combine these component Mappings together. - --------------------------------------------- */ - -/* First put the UnitMap and the RateMap in parallel. This produces a 2-in - 2-out Mapping in which the inputs are (v2,x1) and the outputs are - (v2,dx2/dx1). */ - cmap1 = astCmpMap( unit, rate, 0, "", status ); - -/* Now put this in series with the multiplying MathMap. This results in a - 2-in, 1-out Mapping in which the inputs are (v2,x1) and the single - output is v1. */ - cmap2 = astCmpMap( cmap1, mult, 1, "", status ); - -/* Now put this in parallel with the UnitMap to get a 3-in, 2-out Mapping - in which the inputs are (v2,x1,x1) and the outputs are (v1,x1). */ - cmap3 = astCmpMap( cmap2, unit, 0, "", status ); - -/* Now put this in series with the PermMap to get a 2-in, 2-out Mapping - in which the inputs are (v2,x1) and the outputs are (v1,x1). */ - cmap4 = astCmpMap( perm, cmap3, 1, "", status ); - -/* Now put the UnitMap in parallel with the (x2->x1 Mapping to get a - 2-in, 2-out Mapping in which the inputs are (v2,x2) and the outputs are - (v2,x1). */ - cmap5 = astCmpMap( unit, m, 0, "", status ); - -/* Finally put this in series with "cmap4" to get a 2-in 2-out Mapping - from (v2,x2) to (v1,x1). */ - ret = (AstMapping *) astCmpMap( cmap5, cmap4, 1, "", status ); - -/* Invert this so that the inverse transformation goes from (v2,x2) to - (v1,x1). */ - astInvert( ret ); - -/* Free resources. */ - fs = astAnnul( fs ); - m = astAnnul( m ); - rate = astAnnul( rate ); - mult = astAnnul( mult ); - unit = astAnnul( unit ); - perm = astAnnul( perm ); - cmap1 = astAnnul( cmap1 ); - cmap2 = astAnnul( cmap2 ); - cmap3 = astAnnul( cmap3 ); - cmap4 = astAnnul( cmap4 ); - cmap5 = astAnnul( cmap5 ); - } - -/* If an error has occurred, return NULL. */ - if( !astOK ) ret = astAnnul( ret ); - -/* Return the result */ - return ret; -} - -static int MakeSFMapping( AstSpecFluxFrame *target, AstSpecFluxFrame *result, - AstMapping **map, int *status ){ -/* -* Name: -* MakeSFMapping - -* Purpose: -* Generate a Mapping between two SpecFluxFrames. - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* int MakeSFMapping( AstSpecFluxFrame *target, AstSpecFluxFrame *result, -* AstMapping **map, int *status ) - -* Class Membership: -* SpecFluxFrame member function. - -* Description: -* This function takes two SpecFluxFrames and generates a Mapping that -* converts between them, taking account of differences in their -* coordinate systems, systems, units, etc. (but not allowing for any -* axis permutations). - -* Parameters: -* target -* Pointer to the first SpecFluxFrame. -* result -* Pointer to the second SpecFluxFrame. -* map -* Pointer to a location which is to receive a pointer to the -* returned Mapping. The forward transformation of this Mapping -* will convert from "target" coordinates to "result" -* coordinates, and the inverse transformation will convert in -* the opposite direction (all coordinate values in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Mapping could be generated, or zero if the two -* SpecFluxFrames are sufficiently un-related that no meaningful Mapping -* can be produced. - -* Notes: -* A value of zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *map1; - AstMapping *map2; - AstMapping *map3; - AstMapping *map4; - AstMapping *map5; - AstMapping *tmap1; - AstMapping *tmap2; - AstMapping *tmap3; - AstMapping *tmap4; - int inperm[2]; - int match; - int outperm[3]; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise the returned values. */ - match = 0; - *map = NULL; - -/* Initialise other things. */ - map1 = NULL; - map2 = NULL; - map3 = NULL; - map4 = NULL; - map5 = NULL; - tmap1 = NULL; - tmap2 = NULL; - tmap3 = NULL; - tmap4 = NULL; - -/* At the top level, the required Mapping consists of five Mappings in - series. Inputs 0 and 1 of the total Mapping correspond to the SpecFrame - and FluxFrame in the target SpecFluxFrame. These are referred to as X1 - and V1. Outputs 0 and 1 of the total Mapping correspond to the SpecFrame - and FluxFrame in the result SpecFluxFrame. These are referred to as X2 - and V2. */ - -/* Map1 is a PermMap which copies v1 to its first output and x1 to its - second and third outputs. The inverse transformation copies v1 from - its first output and x1 from its third output. */ - inperm[ 0 ] = 2; - inperm[ 1 ] = 0; - outperm[ 0 ] = 1; - outperm[ 1 ] = 0; - outperm[ 2 ] = 0; - map1 = (AstMapping *) astPermMap( 2, inperm, 3, outperm, NULL, "", status ); - -/* Map2 contains three Mappings in parallel which converts v1 and x1 into - default units, and passes the third axis unchanged. */ - map2 = MakeMap2( target, status ); - -/* Map3 converts ( v1,x1) in default units to (v2,x2) in default units. - The third axis (x1) in original units is convert to x2 in original - units. */ - map3 = map2 ? MakeMap3( target, result, status ) : NULL; - -/* Map4 converts (v2,x2) in default units to (v2,x2) in original units - and passes the third axis unchanged. This is similar to Map2 but based - on the result ratherthan the target, and in the opposite direction. */ - if( map3 ) { - map4 = MakeMap2( result, status ); - if( map4 ) astInvert( map4 ); - } else { - map4 = NULL; - } - -/* Map5 is a PermMap which is the inverse of Map1. */ - map5 = map4 ? astCopy( map1 ) : NULL; - if( map5 ) astInvert( map5 ); - -/* Combine all 6 Mappings in series. */ - if( map5 ) { - tmap1 = (AstMapping *) astCmpMap( map1, map2, 1, "", status ); - tmap2 = (AstMapping *) astCmpMap( tmap1, map3, 1, "", status ); - tmap3 = (AstMapping *) astCmpMap( tmap2, map4, 1, "", status ); - tmap4 = (AstMapping *) astCmpMap( tmap3, map5, 1, "", status ); - -/* Return the simplified total Mapping. */ - *map = astSimplify( tmap4 ); - match = 1; - } - -/* Free resources. */ - if( map1 ) map1 = astAnnul( map1 ); - if( map2 ) map2 = astAnnul( map2 ); - if( map3 ) map3 = astAnnul( map3 ); - if( map4 ) map4 = astAnnul( map4 ); - if( map5 ) map5 = astAnnul( map5 ); - if( tmap1 ) tmap1 = astAnnul( tmap1 ); - if( tmap2 ) tmap2 = astAnnul( tmap2 ); - if( tmap3 ) tmap3 = astAnnul( tmap3 ); - if( tmap4 ) tmap4 = astAnnul( tmap4 ); - -/* If an error occurred, annul the returned Mapping and clear the - returned values. */ - if ( !astOK ) { - *map = astAnnul( *map ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static int Match( AstFrame *template_frame, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, - AstMapping **map, AstFrame **result, int *status ) { -/* -* Name: -* Match - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* SpecFluxFrame member function (over-rides the protected astMatch -* method inherited from the Frame class). - -* Description: -* This function matches a "template" SpecFluxFrame to a "target" Frame -* and determines whether it is possible to convert coordinates -* between them. If it is, a Mapping that performs the -* transformation is returned along with a new Frame that describes -* the coordinate system that results when this Mapping is applied -* to the "target" coordinate system. In addition, information is -* returned to allow the axes in this "result" Frame to be -* associated with the corresponding axes in the "target" Frame and -* "template" SpecFluxFrame from which they are derived. - -* Parameters: -* template -* Pointer to the template SpecFluxFrame. This describes the -* coordinate system (or set of possible coordinate systems) -* into which we wish to convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate -* system in which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case. -* template_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* template SpecFluxFrame axis from which it is derived. If it is not -* derived from any template axis, a value of -1 will be -* returned instead. -* target_axes -* Address of a location where a pointer to int will be returned -* if the requested coordinate conversion is possible. This -* pointer will point at a dynamically allocated array of -* integers with one element for each axis of the "result" Frame -* (see below). It must be freed by the caller (using astFree) -* when no longer required. -* -* For each axis in the result Frame, the corresponding element -* of this array will return the (zero-based) index of the -* target Frame axis from which it is derived. If it is not -* derived from any target axis, a value of -1 will be returned -* instead. -* map -* Address of a location where a pointer to a new Mapping will -* be returned if the requested coordinate conversion is -* possible. If returned, the forward transformation of this -* Mapping may be used to convert coordinates between the -* "target" Frame and the "result" Frame (see below) and the -* inverse transformation will convert in the opposite -* direction. -* result -* Address of a location where a pointer to a new Frame will be -* returned if the requested coordinate conversion is -* possible. If returned, this Frame describes the coordinate -* system that results from applying the returned Mapping -* (above) to the "target" coordinate system. In general, this -* Frame will combine attributes from (and will therefore be -* more specific than) both the target Frame and the template -* SpecFluxFrame. In particular, when the template allows the -* possibility of transformaing to any one of a set of -* alternative coordinate systems, the "result" Frame will -* indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate -* conversion is possible. Otherwise zero is returned (this will -* not in itself result in an error condition). - -* Notes: -* - By default, the "result" Frame will have its number of axes -* and axis order determined by the "template" SpecFluxFrame. However, -* if the PreserveAxes attribute of the template SpecFluxFrame is -* non-zero, then the axis count and axis order of the "target" -* Frame will be used instead. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstSpecFluxFrame *template; /* Pointer to template SpecFluxFrame structure */ - int match; /* Coordinate conversion possible? */ - int swap1; /* Template axes swapped? */ - int swap2; /* Target axes swapped? */ - int swap; /* Additional axis swap needed? */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the template SpecFluxFrame structure. */ - template = (AstSpecFluxFrame *) template_frame; - -/* If the target is not a SpecFluxFrame, use the results returned by the - parent Match method inherited from the CmpFrame class. */ - if( !astIsASpecFluxFrame( target ) ) { - match = (*parent_match)( template_frame, target, matchsub, template_axes, - target_axes, map, result, status ); - - -/* If the target is a SpecFluxFrame, see if we can convert between target - and template */ - } else { - -/* We must now decide how the order of the axes in the result Frame relates to - the order of axes in the target Frame. There are two factors involved. The - first depends on whether the axis permutation array for the template - SpecFluxFrame (whose method we are executing) causes an axis - reversal. Determine this by permuting axis index zero. */ - swap1 = ( astValidateAxis( template, 0, 1, "astMatch" ) != 0 ); - -/* The second factor depends on whether the axes of the target SpecFluxFrame - causes an axis reversal. Determine this by permuting axis index zero. */ - swap2 = ( astValidateAxis( target, 0, 1, "astMatch" ) != 0 ); - -/* Combine these to determine if an additional axis swap will be - needed. */ - swap = ( swap1 != swap2 ); - -/* Now check to see if this additional swap is permitted by the template's - Permute attribute. */ - match = ( !swap || astGetPermute( template ) ); - -/* Allocate the target and template axes arrays. */ - *template_axes = astMalloc( sizeof(int)*2 ); - *target_axes = astMalloc( sizeof(int)*2 ); - -/* If the Frames still match, we next set up the axis association - arrays. */ - if ( astOK && match ) { - -/* If the target axis order is to be preserved, then the target axis - association involves no permutation but the template axis - association may involve an axis swap. */ - if ( astGetPreserveAxes( template ) ) { - (*template_axes)[ 0 ] = swap; - (*template_axes)[ 1 ] = !swap; - (*target_axes)[ 0 ] = 0; - (*target_axes)[ 1 ] = 1; - -/* Otherwise, any swap applies to the target axis association - instead. */ - } else { - (*template_axes)[ 0 ] = 0; - (*template_axes)[ 1 ] = 1; - (*target_axes)[ 0 ] = swap; - (*target_axes)[ 1 ] = !swap; - } - -/* Use the target's "astSubFrame" method to create a new Frame (the - result Frame) with copies of the target axes in the required - order. This process also overlays the template attributes on to the - target Frame and returns a Mapping between the target and result - Frames which effects the required coordinate conversion. */ - match = astSubFrame( target, template, 2, *target_axes, *template_axes, - map, result ); - -/* If an error occurred, or conversion to the result Frame's - coordinate system was not possible, then free all memory, annul the - returned objects, and reset the returned value. */ - if ( !astOK || !match ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - } - } - -/* Return the result. */ - return match; -} - -static int SubFrame( AstFrame *target_frame, AstFrame *template, - int result_naxes, const int *target_axes, - const int *template_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* SubFrame - -* Purpose: -* Select axes from a SpecFluxFrame and convert to the new coordinate system. - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* int SubFrame( AstFrame *target, AstFrame *template, -* int result_naxes, const int *target_axes, -* const int *template_axes, AstMapping **map, -* AstFrame **result, int *status ) - -* Class Membership: -* SpecFluxFrame member function (over-rides the protected astSubFrame -* method inherited from the Frame class). - -* Description: -* This function selects a requested sub-set (or super-set) of the -* axes from a "target" SpecFluxFrame and creates a new Frame with -* copies of the selected axes assembled in the requested order. It -* then optionally overlays the attributes of a "template" Frame on -* to the result. It returns both the resulting Frame and a Mapping -* that describes how to convert between the coordinate systems -* described by the target and result Frames. If necessary, this -* Mapping takes account of any differences in the Frames' -* attributes due to the influence of the template. - -* Parameters: -* target -* Pointer to the target SpecFluxFrame, from which axes are to be selected. -* template -* Pointer to the template Frame, from which new attributes for -* the result Frame are to be obtained. Optionally, this may be -* NULL, in which case no overlaying of template attributes will -* be performed. -* result_naxes -* Number of axes to be selected from the target Frame. This -* number may be greater than or less than the number of axes in -* this Frame (or equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving -* a list of the (zero-based) axis indices of the axes to be -* selected from the target SpecFluxFrame. The order in which these -* are given determines the order in which the axes appear in -* the result Frame. If any of the values in this array is set -* to -1, the corresponding result axis will not be derived from -* the target Frame, but will be assigned default attributes -* instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This -* should contain a list of the template axes (given as -* zero-based axis indices) with which the axes of the result -* Frame are to be associated. This array determines which axes -* are used when overlaying axis-dependent attributes of the -* template on to the result. If any element of this array is -* set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not -* used and a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned -* Mapping. The forward transformation of this Mapping will -* describe how to convert coordinates from the coordinate -* system described by the target SpecFluxFrame to that described by -* the result Frame. The inverse transformation will convert in -* the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is -* possible between the target and the result Frame. Otherwise zero -* is returned and *map and *result are returned as NULL (but this -* will not in itself result in an error condition). In general, -* coordinate conversion should always be possible if no template -* Frame is supplied but may not always be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. - -* Implementation Deficiencies: -* - It is not clear that the method of handling "extra" axes is -* the best one, nor is the method of setting the "following" flag -* necessarily correct. However, it is also not obvious that this -* feature will ever be needed, so improvements have been left -* until the requirement is clearer. -*/ - -/* Local Variables: */ - AstMapping *tmpmap; /* Temporary Mapping pointer */ - AstPermMap *permmap; /* Pointer to PermMap */ - AstSpecFluxFrame *target; /* Pointer to target SpecFluxFrame structure */ - int match; /* Coordinate conversion is possible? */ - int perm[ 2 ]; /* Permutation array for axis swap */ - int result_swap; /* Swap result SpecFluxFrame coordinates? */ - int target_swap; /* Swap target SpecFluxFrame coordinates? */ - -/* Initialise the returned values. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* If the template is not a SpecFluxFrame we use the parent SubFrame - method inherited form the CmpFrame class. */ - if( !template || !astIsASpecFluxFrame( template ) || result_naxes != 2 ) { - match = (*parent_subframe)( target_frame, template, result_naxes, - target_axes, template_axes, map, result, status ); - -/* Otherwise... */ - } else { - -/* Obtain a pointer to the target SpecFluxFrame structure. */ - target = (AstSpecFluxFrame *) target_frame; - -/* Form the result from a copy of the target and then permute its axes - into the order required. */ - *result = astCopy( target ); - astPermAxes( *result, target_axes ); - -/* Overlay the template attributes on to the result SpecFrame. */ - astOverlay( template, template_axes, *result ); - -/* Generate a Mapping that takes account of changes in the coordinate - system (system, units, etc.) between the target SpecFluxFrame and the - result SpecFluxFrame. If this Mapping can be generated, set "match" to - indicate that coordinate conversion is possible. */ - match = MakeSFMapping( target, (AstSpecFluxFrame *) *result, map, status ); - -/* If a Mapping has been obtained, it will expect coordinate values to be - supplied in (flux,spec) pairs. Test whether we need to swap the - order of the target SpecFluxFrame coordinates to conform with this. */ - if ( astOK && match ) { - target_swap = ( astValidateAxis( target, 0, 1, "astSubFrame" ) != 0 ); - -/* Coordinates will also be delivered in (flux,spec) pairs, so check - to see whether the result SpecFluxFrame coordinate order should be - swapped. */ - result_swap = ( target_swap != ( target_axes[ 0 ] != 0 ) ); - -/* If either set of coordinates needs swapping, create a PermMap that - will swap a pair of coordinates. */ - permmap = NULL; - if ( target_swap || result_swap ) { - perm[ 0 ] = 1; - perm[ 1 ] = 0; - permmap = astPermMap( 2, perm, 2, perm, NULL, "", status ); - } - -/* If necessary, prefix this PermMap to the main Mapping. */ - if ( target_swap ) { - tmpmap = (AstMapping *) astCmpMap( permmap, *map, 1, "", status ); - *map = astAnnul( *map ); - *map = tmpmap; - } - -/* Also, if necessary, append it to the main Mapping. */ - if ( result_swap ) { - tmpmap = (AstMapping *) astCmpMap( *map, permmap, 1, "", status ); - *map = astAnnul( *map ); - *map = tmpmap; - } - -/* Annul the pointer to the PermMap (if created). */ - if ( permmap ) permmap = astAnnul( permmap ); - } - } - -/* If an error occurred, clean up by annulling the result pointers and - returning appropriate null values. */ - if ( !astOK ) { - *map = astAnnul( *map ); - *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - the axes of a SpecFluxFrame using the private macros defined for this - purpose at the start of this file. */ - -/* Copy constructor. */ -/* ----------------- */ - -/* Destructor. */ -/* ----------- */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SpecFluxFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the SpecFluxFrame class to an output Channel. - -* Parameters: -* this -* Pointer to the SpecFluxFrame whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSpecFluxFrame *this; /* Pointer to the SpecFluxFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFluxFrame structure. */ - this = (AstSpecFluxFrame *) this_object; - -/* Write out values representing the instance variables for the - SpecFluxFrame class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASpecFluxFrame and astCheckSpecFluxFrame functions using - the macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SpecFluxFrame,CmpFrame) -astMAKE_CHECK(SpecFluxFrame) - -AstSpecFluxFrame *astSpecFluxFrame_( void *frame1_void, void *frame2_void, - const char *options, int *status, ...) { -/* -*++ -* Name: -c astSpecFluxFrame -f AST_SPECFLUXFRAME - -* Purpose: -* Create a SpecFluxFrame. - -* Type: -* Public function. - -* Synopsis: -c #include "specfluxframe.h" -c AstSpecFluxFrame *astSpecFluxFrame( AstSpecFrame *frame1, AstFluxFrame *frame2, -c const char *options, ... ) -f RESULT = AST_SPECFLUXFRAME( FRAME1, FRAME2, OPTIONS, STATUS ) - -* Class Membership: -* SpecFluxFrame constructor. - -* Description: -* This function creates a new SpecFluxFrame and optionally initialises -* its attributes. -* -* A SpecFluxFrame combines a SpecFrame and a FluxFrame into a single -* 2-dimensional compound Frame. Such a Frame can for instance be used -* to describe a Plot of a spectrum in which the first axis represents -* spectral position and the second axis represents flux. - -* Parameters: -c frame1 -f FRAME1 = INTEGER (Given) -* Pointer to the SpecFrame. This will form the first axis in the -* new SpecFluxFrame. -c frame2 -f FRAME2 = INTEGER (Given) -* Pointer to the FluxFrame. This will form the second axis in the -* new SpecFluxFrame. The "SpecVal" attribute of this FluxFrame is -* not used by the SpecFluxFrame class and so may be set to AST__BAD -* when the FluxFrame is created. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new SpecFluxFrame. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new SpecFluxFrame. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSpecFluxFrame() -f AST_SPECFLUXFRAME = INTEGER -* A pointer to the new SpecFluxFrame. - -* Notes: -* - The supplied Frame pointers are stored directly, rather than -* being used to create deep copies of the supplied Frames. This means -* that any subsequent changes made to the Frames via the supplied -* pointers will result in equivalent changes being visible in the -* SpecFluxFrame. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- - -* Implementation Notes: -* - This function implements the basic SpecFluxFrame constructor which -* is available via the protected interface to the SpecFluxFrame class. -* A public interface is provided by the astSpecFluxFrameId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "frame1" and "frame2" parameters are of type (void *) and are -* converted and validated within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSpecFluxFrame *new; /* Pointer to new SpecFluxFrame */ - AstFluxFrame *frame2; /* Pointer to FluxFrame structure */ - AstSpecFrame *frame1; /* Pointer to SpecFrame structure */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - new = NULL; - if ( !astOK ) return new; - -/* Obtain and validate pointers to the Frame structures provided. */ - frame1 = astCheckSpecFrame( frame1_void ); - frame2 = astCheckFluxFrame( frame2_void ); - if ( astOK ) { - -/* Initialise the SpecFluxFrame, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSpecFluxFrame( NULL, sizeof( AstSpecFluxFrame ), !class_init, - &class_vtab, "SpecFluxFrame", frame1, frame2 ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - SpecFluxFrame's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new SpecFluxFrame. */ - return new; -} - -AstSpecFluxFrame *astSpecFluxFrameId_( void *frame1_void, void *frame2_void, - const char *options, ... ) { -/* -* Name: -* astSpecFluxFrameId_ - -* Purpose: -* Create a SpecFluxFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specfluxframe.h" -* AstSpecFluxFrame *astSpecFluxFrameId_( void *frame1_void, void *frame2_void, -* const char *options, ... ) - -* Class Membership: -* SpecFluxFrame constructor. - -* Description: -* This function implements the external (public) interface to the -* astSpecFluxFrame constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astSpecFluxFrame_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). For the same reason, the "frame1" and "frame2" -* parameters are of type (void *) and are converted and validated -* within the function itself. -* -* The variable argument list also prevents this function from -* invoking astSpecFluxFrame_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. - -* Parameters: -* As for astSpecFluxFrame_. - -* Returned Value: -* The ID value associated with the new SpecFluxFrame. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSpecFluxFrame *new; /* Pointer to new SpecFluxFrame */ - AstSpecFrame *frame1; /* Pointer to first Frame structure */ - AstFluxFrame *frame2; /* Pointer to second Frame structure */ - va_list args; /* Variable argument list */ - - int *status; /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - new = NULL; - if ( !astOK ) return new; - -/* Obtain the Frame pointers from the ID's supplied and validate the - pointers to ensure they identify valid Frames. */ - frame1 = astVerifySpecFrame( astMakePointer( frame1_void ) ); - frame2 = astVerifyFluxFrame( astMakePointer( frame2_void ) ); - if ( astOK ) { - -/* Initialise the SpecFluxFrame, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSpecFluxFrame( NULL, sizeof( AstSpecFluxFrame ), !class_init, - &class_vtab, "SpecFluxFrame", frame1, frame2 ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - SpecFluxFrame's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new SpecFluxFrame. */ - return astMakeId( new ); -} - -AstSpecFluxFrame *astInitSpecFluxFrame_( void *mem, size_t size, int init, - AstSpecFluxFrameVtab *vtab, const char *name, - AstSpecFrame *frame1, AstFluxFrame *frame2, int *status ) { -/* -*+ -* Name: -* astInitSpecFluxFrame - -* Purpose: -* Initialise a SpecFluxFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specfluxframe.h" -* AstSpecFluxFrame *astInitSpecFluxFrame( void *mem, size_t size, int init, -* AstSpecFluxFrameVtab *vtab, const char *name, -* AstSpecFrame *frame1, AstFluxFrame *frame2 ) - -* Class Membership: -* SpecFluxFrame initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new SpecFluxFrame object. It allocates memory (if -* necessary) to accommodate the SpecFluxFrame plus any additional data -* associated with the derived class. It then initialises a -* SpecFluxFrame structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual -* function table for a SpecFluxFrame at the start of the memory passed -* via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SpecFluxFrame is to be -* created. This must be of sufficient size to accommodate the -* SpecFluxFrame data (sizeof(SpecFluxFrame)) plus any data used by the -* derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SpecFluxFrame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SpecFluxFrame structure, so a valid value must be -* supplied even if not required for allocating memory. -* init -* A logical flag indicating if the SpecFluxFrame's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SpecFluxFrame. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the Object astClass function). -* frame1 -* Pointer to the SpecFrame -* frame2 -* Pointer to the FluxFrame - -* Returned Value: -* A pointer to the new SpecFluxFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstSpecFluxFrame *new; /* Pointer to new SpecFluxFrame */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSpecFluxFrameVtab( vtab, name ); - -/* Initialise a Frame structure (the parent class) as the first - component within the SpecFluxFrame structure, allocating memory if - necessary. Set the number of Frame axes to zero, since all axis - information is stored within the component Frames. */ - new = astInitCmpFrame( mem, size, 0, (AstCmpFrameVtab *) vtab, name, - frame1, frame2 ); - if ( astOK ) { - - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstSpecFluxFrame *astLoadSpecFluxFrame_( void *mem, size_t size, - AstSpecFluxFrameVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSpecFluxFrame - -* Purpose: -* Load a SpecFluxFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specfluxframe.h" -* AstSpecFluxFrame *astLoadSpecFluxFrame( void *mem, size_t size, -* AstSpecFluxFrameVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* SpecFluxFrame loader. - -* Description: -* This function is provided to load a new SpecFluxFrame using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* SpecFluxFrame structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the SpecFluxFrame is to be -* loaded. This must be of sufficient size to accommodate the -* SpecFluxFrame data (sizeof(SpecFluxFrame)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SpecFluxFrame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SpecFluxFrame structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstSpecFluxFrame) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SpecFluxFrame. If this is NULL, a pointer -* to the (static) virtual function table for the SpecFluxFrame class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "SpecFluxFrame" is used instead. - -* Returned Value: -* A pointer to the new SpecFluxFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstSpecFluxFrame *new; /* Pointer to the new SpecFluxFrame */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SpecFluxFrame. In this case the - SpecFluxFrame belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSpecFluxFrame ); - vtab = &class_vtab; - name = "SpecFluxFrame"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSpecFluxFrameVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built SpecFluxFrame. */ - new = astLoadCmpFrame( mem, size, (AstCmpFrameVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "SpecFluxFrame" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ -/* (none) */ - -/* If an error occurred, clean up by deleting the new SpecFluxFrame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new SpecFluxFrame pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - diff --git a/ast/specfluxframe.h b/ast/specfluxframe.h deleted file mode 100644 index ff8a5e1..0000000 --- a/ast/specfluxframe.h +++ /dev/null @@ -1,215 +0,0 @@ -#if !defined( SPECFLUXFRAME_INCLUDED ) /* Include this file only once */ -#define SPECFLUXFRAME_INCLUDED -/* -*+ -* Name: -* specfluxframe.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the SpecFluxFrame class. - -* Invocation: -* #include "specfluxframe.h" - -* Description: -* This include file defines the interface to the SpecFluxFrame class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. - -* Inheritance: -* The SpecFluxFrame class inherits from the Frame class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 8-DEC-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "cmpframe.h" /* Parent Frame class */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros. */ -/* ------- */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* SpecFluxFrame structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstSpecFluxFrame { - -/* Attributes inherited from the parent class. */ - AstCmpFrame cmpframe; /* Parent class structure */ - -} AstSpecFluxFrame; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstSpecFluxFrameVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstCmpFrameVtab frame_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - -} AstSpecFluxFrameVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstSpecFluxFrameGlobals { - AstSpecFluxFrameVtab Class_Vtab; - int Class_Init; - char GetTitle_Buff[ 201 ]; -} AstSpecFluxFrameGlobals; - -#endif -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(SpecFluxFrame) /* Check class membership */ -astPROTO_ISA(SpecFluxFrame) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstSpecFluxFrame *astSpecFluxFrame_( void *, void *, const char *, int *, ...); -#else -AstSpecFluxFrame *astSpecFluxFrameId_( void *, void *, const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstSpecFluxFrame *astInitSpecFluxFrame_( void *, size_t, int, AstSpecFluxFrameVtab *, - const char *, AstSpecFrame *, AstFluxFrame *, int * ); - -/* Vtab initialiser. */ -void astInitSpecFluxFrameVtab_( AstSpecFluxFrameVtab *, const char *, int * ); - -/* Loader. */ -AstSpecFluxFrame *astLoadSpecFluxFrame_( void *, size_t, AstSpecFluxFrameVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitSpecFluxFrameGlobals_( AstSpecFluxFrameGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckSpecFluxFrame(this) astINVOKE_CHECK(SpecFluxFrame,this,0) -#define astVerifySpecFluxFrame(this) astINVOKE_CHECK(SpecFluxFrame,this,1) - -/* Test class membership. */ -#define astIsASpecFluxFrame(this) astINVOKE_ISA(SpecFluxFrame,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astSpecFluxFrame astINVOKE(F,astSpecFluxFrame_) -#else -#define astSpecFluxFrame astINVOKE(F,astSpecFluxFrameId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitSpecFluxFrame(mem,size,init,vtab,name,frame1,frame2) \ -astINVOKE(O,astInitSpecFluxFrame_(mem,size,init,vtab,name,astCheckSpecFrame(frame1),astCheckFluxFrame(frame2),STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitSpecFluxFrameVtab(vtab,name) astINVOKE(V,astInitSpecFluxFrameVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadSpecFluxFrame(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadSpecFluxFrame_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckSpecFluxFrame to validate SpecFluxFrame pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#endif - - - - - diff --git a/ast/specframe.c b/ast/specframe.c deleted file mode 100644 index 482f1d8..0000000 --- a/ast/specframe.c +++ /dev/null @@ -1,7437 +0,0 @@ -/* -*class++ -* Name: -* SpecFrame - -* Purpose: -* Spectral coordinate system description. - -* Constructor Function: -c astSpecFrame -f AST_SPECFRAME - -* Description: -* A SpecFrame is a specialised form of one-dimensional Frame which -* represents various coordinate systems used to describe positions within -* an electro-magnetic spectrum. The particular coordinate system to be -* used is specified by setting the SpecFrame's System attribute (the -* default is wavelength) qualified, as necessary, by other attributes -* such as the rest frequency, the standard of rest, the epoch of -* observation, units, etc (see the description of the System attribute -* for details). -* -* By setting a value for thr SpecOrigin attribute, a SpecFrame can be made -* to represent offsets from a given spectral position, rather than absolute -* spectral values. - -* Inheritance: -* The SpecFrame class inherits from the Frame class. - -* Attributes: -* In addition to those attributes common to all Frames, every -* SpecFrame also has the following attributes: -* -* - AlignSpecOffset: Align SpecFrames using the offset coordinate system? -* - AlignStdOfRest: Standard of rest in which to align SpecFrames -* - RefDec: Declination of the source (FK5 J2000) -* - RefRA: Right ascension of the source (FK5 J2000) -* - RestFreq: Rest frequency -* - SourceSys: Source velocity spectral system -* - SourceVel: Source velocity -* - SourceVRF: Source velocity rest frame -* - SpecOrigin: The zero point for SpecFrame axis values -* - StdOfRest: Standard of rest -* -* Several of the Frame attributes inherited by the SpecFrame class -* refer to a specific axis of the Frame (for instance Unit(axis), -* Label(axis), etc). Since a SpecFrame is strictly one-dimensional, -* it allows these attributes to be specified without an axis index. -* So for instance, "Unit" is allowed in place of "Unit(1)". - -* Functions: -c In addition to those functions applicable to all Frames, the -c following functions may also be applied to all SpecFrames: -f In addition to those routines applicable to all Frames, the -f following routines may also be applied to all SpecFrames: -* -c - astSetRefPos: Set reference position in any celestial system -f - AST_SETREFPOS: Set reference position in any celestial system -c - astGetRefPos: Get reference position in any celestial system -f - AST_GETREFPOS: Get reference position in any celestial system - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 4-NOV-2002 (DSB): -* Original version. -* 2-FEB-2005 (DSB): -* - Avoid using astStore to allocate more storage than is supplied -* in the "data" pointer. This can cause access violations since -* astStore will then read beyond the end of the "data" area. -* 22-MAR-2005 (DSB): -* - Re-structure MakeSpecMapping in order to avoid unnecessary -* access to SpecFrame attributes which may not be set, and to -* check that all required attributes have been set if UseDefs is -* zero. -* 23-MAR-2005 (DSB): -* - Added missing rest frames to SorEqual. -* 12-AUG-2005 (DSB): -* - Remove GeoLon and GeoLat attributes. Use the new ObsLon and -* ObsLat attributes in the parent Frame class instead. Note, for -* backward compatibility the public attribute accessors and the -* astLoadSpecFrame functions still recogonise GeoLon and GeoLat, -* but use the ObsLat/ObsLon attributes internally. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 6-OCT-2006 (DSB): -* Guard against annulling null pointers in subFrame. -* 18-OCT-2006 (DSB): -* Added SpecOrigin and AlignSpecOffset attributes. -* 23-OCT-2006 (DSB): -* Fix memory leak caused by addition of SpecOrigin and AlignSpecOffset -* attributes. -* 15-NOV-2006 (DSB): -* Only write out SpecOrigin if it is not bad. -* 8-JAN-2006 (DSB): -* - SubFrame: Copy the SourceSystem and SourceStdOfRest attributes -* to the System and StdOfRest attributes of the "align_frm" -* SpecFrame before calling MakeSpecMapping. Previously, the -* values assigned to SourceSystem and SourceStdOfRest were -* ignored, and alignment was always performed in the templates System -* and StdOfRest. -* - MakeSpecMapping: Correct logic used to decide if steps 2 and 7 -* can be cancelled. -* - OriginSystem: Clear the AlignSpecOffset attributes before -* finding the Mapping between the old and new Systems. -* 16-JAN-2006 (DSB): -* Fix bug in Dump that caused SrcVRF not to be written out. -* 31-JAN-2007 (DSB): -* Modified so that a SpecFrame can be used as a template to find a -* SpecFrame contained within a CmpFrame. This involves changes in -* Match and the removal of the local versions of SetMaxAxes and -* SetMinAxes. -* 8-AUG-2007 (DSB): -* Changed Overlay to avoid the possibility of making permanent -* changes to the supplied template Frame. -* 3-SEP-2007 (DSB): -* In SubFrame, since AlignSystem is extended by the SpecFrame class -* it needs to be cleared before invoking the parent SubFrame -* method in cases where the result Frame is not a SkyFrame. -* 2-OCT-2007 (DSB): -* In Overlay, clear AlignSystem as well as System before calling -* the parent overlay method. -* 4-SEP-2009 (DSB): -* In MakeSpecMapping, in order to produce alignment that is not -* affected by the epoch or reference position, make the alignment -* frame adapt to the epoch and reference position of the target -* and result Frames. -* 14-SEP-2009 (DSB): -* In MakeSpecMapping, extend the 4-SEP-2009 fix to cover other -* attributes that define the available rest frames (e.g. -* SourceVRF, SourceVel, ObsLat, ObsLon, ObsAlt). -* 16-SEP-2009 (DSB): -* In MakeSpecMapping, retain the original alignment frame attribute -* values if we are restoring the integrity of a FrameSet. -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS SpecFrame - -/* Define the first and last acceptable System values. */ -#define FIRST_SYSTEM AST__FREQ -#define LAST_SYSTEM AST__VREL - -/* Define the first and last acceptable StdOfRest values. */ -#define FIRST_SOR AST__TPSOR -#define LAST_SOR AST__SCSOR - -/* The supported spectral coordinate systems fall into two groups; - "relative", and "absolute". The relative systems define each axis - value with respect to the rest frequency, whereas the absolute systems - have axis values which do not depend on the rest frequency. Define a - macro which returns one if the specified system is absolute, and zero - otherwise. */ -#define ABS_SYSTEM(sys) \ - ( ( sys == AST__ENERGY || \ - sys == AST__WAVENUM || \ - sys == AST__WAVELEN || \ - sys == AST__AIRWAVE || \ - sys == AST__FREQ ) ? 1 : 0 ) - -/* Define other numerical constants for use in this module. */ -#define GETATTRIB_BUFF_LEN 50 -#define GETLABEL_BUFF_LEN 200 -#define GETSYMBOL_BUFF_LEN 20 -#define GETTITLE_BUFF_LEN 200 - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "unit.h" /* Units management facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "specmap.h" /* Spectral coordinate Mappings */ -#include "frame.h" /* Parent Frame class */ -#include "skyframe.h" /* Celestial coordinate frames */ -#include "specframe.h" /* Interface definition for this class */ -#include "mapping.h" /* Coordinate Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "pal.h" /* SlaLib interface */ -#include "shiftmap.h" /* Change of origin */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are used or extended by this - class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstSystemType (* parent_getalignsystem)( AstFrame *, int * ); -static AstSystemType (* parent_getsystem)( AstFrame *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static const char *(* parent_getdomain)( AstFrame *, int * ); -static const char *(* parent_getlabel)( AstFrame *, int, int * ); -static const char *(* parent_getsymbol)( AstFrame *, int, int * ); -static const char *(* parent_gettitle)( AstFrame *, int * ); -static const char *(* parent_getunit)( AstFrame *, int, int * ); -static int (* parent_match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int (* parent_subframe)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_setunit)( AstFrame *, int, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_setsystem)( AstFrame *, AstSystemType, int * ); -static void (* parent_clearsystem)( AstFrame *, int * ); -static void (* parent_clearunit)( AstFrame *, int, int * ); - -/* Define a variable to hold a SkyFrame which will be used for formatting - and unformatting sky positions, etc. */ -static AstSkyFrame *skyframe; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->GetLabel_Buff[ 0 ] = 0; \ - globals->GetSymbol_Buff[ 0 ] = 0; \ - globals->GetTitle_Buff[ 0 ] = 0; \ - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(SpecFrame) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SpecFrame,Class_Init) -#define class_vtab astGLOBAL(SpecFrame,Class_Vtab) -#define getattrib_buff astGLOBAL(SpecFrame,GetAttrib_Buff) -#define getlabel_buff astGLOBAL(SpecFrame,GetLabel_Buff) -#define getsymbol_buff astGLOBAL(SpecFrame,GetSymbol_Buff) -#define gettitle_buff astGLOBAL(SpecFrame,GetTitle_Buff) - - - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ 51 ]; - -/* Default GetLabel string buffer */ -static char getlabel_buff[ 201 ]; - -/* Default GetSymbol buffer */ -static char getsymbol_buff[ 21 ]; - -/* Default Title string buffer */ -static char gettitle_buff[ 201 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSpecFrameVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#endif - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstStdOfRestType StdOfRestCode( const char *, int * ); -static int GetObjSize( AstObject *, int * ); -static AstSystemType GetAlignSystem( AstFrame *, int * ); -static AstSystemType SystemCode( AstFrame *, const char *, int * ); -static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * ); -static const char *DefUnit( AstSystemType, const char *, const char *, int * ); -static const char *GetDomain( AstFrame *, int * ); -static const char *GetLabel( AstFrame *, int, int * ); -static const char *GetSymbol( AstFrame *, int, int * ); -static const char *GetTitle( AstFrame *, int * ); -static const char *GetUnit( AstFrame *, int, int * ); -static const char *SpecMapUnit( AstSystemType, const char *, const char *, int * ); -static const char *StdOfRestString( AstStdOfRestType, int * ); -static const char *SystemLabel( AstSystemType, int * ); -static const char *SystemString( AstFrame *, AstSystemType, int * ); -static double ConvertSourceVel( AstSpecFrame *, AstStdOfRestType, AstSystemType, int * ); -static int EqualSor( AstSpecFrame *, AstSpecFrame *, int * ); -static int GetActiveUnit( AstFrame *, int * ); -static int MakeSpecMapping( AstSpecFrame *, AstSpecFrame *, AstSpecFrame *, int, AstMapping **, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int SorConvert( AstSpecFrame *, AstSpecFrame *, AstSpecMap *, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int TestActiveUnit( AstFrame *, int * ); -static void ClearUnit( AstFrame *, int, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void GetRefPos( AstSpecFrame *, AstSkyFrame *, double *, double *, int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void SetRefPos( AstSpecFrame *, AstSkyFrame *, double, double, int * ); -static void SetUnit( AstFrame *, int, const char *, int * ); -static void VerifyAttrs( AstSpecFrame *, const char *, const char *, const char *, int * ); -static double ToUnits( AstSpecFrame *, const char *, double, const char *, int * ); -static void OriginStdOfRest( AstSpecFrame *, AstStdOfRestType, const char *, int * ); -static void OriginSystem( AstSpecFrame *, AstSystemType, const char *, int * ); - -static AstSystemType GetSystem( AstFrame *, int * ); -static void SetSystem( AstFrame *, AstSystemType, int * ); -static void ClearSystem( AstFrame *, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static AstStdOfRestType GetAlignStdOfRest( AstSpecFrame *, int * ); -static int TestAlignStdOfRest( AstSpecFrame *, int * ); -static void ClearAlignStdOfRest( AstSpecFrame *, int * ); -static void SetAlignStdOfRest( AstSpecFrame *, AstStdOfRestType, int * ); - -static AstStdOfRestType GetStdOfRest( AstSpecFrame *, int * ); -static int TestStdOfRest( AstSpecFrame *, int * ); -static void ClearStdOfRest( AstSpecFrame *, int * ); -static void SetStdOfRest( AstSpecFrame *, AstStdOfRestType, int * ); - -static double GetRestFreq( AstSpecFrame *, int * ); -static int TestRestFreq( AstSpecFrame *, int * ); -static void ClearRestFreq( AstSpecFrame *, int * ); -static void SetRestFreq( AstSpecFrame *, double, int * ); - -static double GetSourceVel( AstSpecFrame *, int * ); -static int TestSourceVel( AstSpecFrame *, int * ); -static void ClearSourceVel( AstSpecFrame *, int * ); -static void SetSourceVel( AstSpecFrame *, double, int * ); - -static double GetRefRA( AstSpecFrame *, int * ); -static int TestRefRA( AstSpecFrame *, int * ); -static void ClearRefRA( AstSpecFrame *, int * ); -static void SetRefRA( AstSpecFrame *, double, int * ); - -static double GetRefDec( AstSpecFrame *, int * ); -static int TestRefDec( AstSpecFrame *, int * ); -static void ClearRefDec( AstSpecFrame *, int * ); -static void SetRefDec( AstSpecFrame *, double, int * ); - -static AstStdOfRestType GetSourceVRF( AstSpecFrame *, int * ); -static int TestSourceVRF( AstSpecFrame *, int * ); -static void ClearSourceVRF( AstSpecFrame *, int * ); -static void SetSourceVRF( AstSpecFrame *, AstStdOfRestType, int * ); - -static AstSystemType GetSourceSys( AstSpecFrame *, int * ); -static int TestSourceSys( AstSpecFrame *, int * ); -static void ClearSourceSys( AstSpecFrame *, int * ); -static void SetSourceSys( AstSpecFrame *, AstSystemType, int * ); - -static double GetSpecOrigin( AstSpecFrame *, int * ); -static int TestSpecOrigin( AstSpecFrame *, int * ); -static void ClearSpecOrigin( AstSpecFrame *, int * ); -static void SetSpecOrigin( AstSpecFrame *, double, int * ); -static double GetSpecOriginCur( AstSpecFrame *, int * ); - -static int GetAlignSpecOffset( AstSpecFrame *, int * ); -static int TestAlignSpecOffset( AstSpecFrame *, int * ); -static void SetAlignSpecOffset( AstSpecFrame *, int, int * ); -static void ClearAlignSpecOffset( AstSpecFrame *, int * ); - -/* Member functions. */ -/* ================= */ - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astClearAttrib protected -* method inherited from the Frame class). - -* Description: -* This function clears the value of a specified attribute for a -* SpecFrame, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the SpecFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - char *new_attrib; /* Pointer value to new attribute name */ - int len; /* Length of attrib string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* First look for axis attributes defined by the Frame class. Since a - SpecFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strcmp( attrib, "direction" ) || - !strcmp( attrib, "bottom" ) || - !strcmp( attrib, "top" ) || - !strcmp( attrib, "format" ) || - !strcmp( attrib, "label" ) || - !strcmp( attrib, "symbol" ) || - !strcmp( attrib, "unit" ) ) { - -/* Create a new attribute name from the original by appending the string - "(1)" and then use the parent ClearAttrib method. */ - new_attrib = astMalloc( len + 4 ); - if( new_attrib ) { - memcpy( new_attrib, attrib, len ); - memcpy( new_attrib + len, "(1)", 4 ); - (*parent_clearattrib)( this_object, new_attrib, status ); - new_attrib = astFree( new_attrib ); - } - -/* AlignStdOfRest. */ -/* --------------- */ - } else if ( !strcmp( attrib, "alignstdofrest" ) ) { - astClearAlignStdOfRest( this ); - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - SpecFrame had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "geolat" ) ) { - astClearAttrib( this, "obslat" ); - -/* GeoLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "geolon" ) ) { - astClearAttrib( this, "obslon" ); - -/* RefDec. */ -/* ---------- */ - } else if ( !strcmp( attrib, "refdec" ) ) { - astClearRefDec( this ); - -/* RefRA. */ -/* --------- */ - } else if ( !strcmp( attrib, "refra" ) ) { - astClearRefRA( this ); - -/* RestFreq. */ -/* --------- */ - } else if ( !strcmp( attrib, "restfreq" ) ) { - astClearRestFreq( this ); - -/* SourceVel. */ -/* ---------- */ - } else if ( !strcmp( attrib, "sourcevel" ) ) { - astClearSourceVel( this ); - -/* SpecOrigin. */ -/* ---------- */ - } else if ( !strcmp( attrib, "specorigin" ) ) { - astClearSpecOrigin( this ); - -/* AlignSpecOffset. */ -/* ---------------- */ - } else if ( !strcmp( attrib, "alignspecoffset" ) ) { - astClearAlignSpecOffset( this ); - -/* SourceVRF */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcevrf" ) ) { - astClearSourceVRF( this ); - -/* SourceSys */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcesys" ) ) { - astClearSourceSys( this ); - -/* StdOfRest. */ -/* ---------- */ - } else if ( !strcmp( attrib, "stdofrest" ) ) { - astClearStdOfRest( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearSystem - -* Purpose: -* Clear the System attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void ClearSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astClearSystem protected -* method inherited from the Frame class). - -* Description: -* This function clears the System attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstSystemType newsys; /* System after clearing */ - AstSystemType oldsys; /* System before clearing */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Save the original system */ - oldsys = astGetSystem( this_frame ); - -/* Use the parent ClearSystem method to clear the System value. */ - (*parent_clearsystem)( this_frame, status ); - -/* Get the default System. */ - newsys = astGetSystem( this_frame ); - -/* If the system has actually changed. */ - if( newsys != oldsys ) { - -/* Changing the System value will in general require the Units to change - as well. If the used has previously specified the units to be used with - the new system, then re-instate them (they are stored in the "usedunits" - array in the SpecFrame structure). Otherwise, clear the units so that - the default units will eb used with the new System. */ - if( (int) newsys < this->nuunits && this->usedunits && - this->usedunits[ (int) newsys ] ) { - astSetUnit( this, 0, this->usedunits[ (int) newsys ] ); - } else { - astClearUnit( this, 0 ); - } - -/* Also, clear all attributes which have system-specific defaults. */ - astClearLabel( this_frame, 0 ); - astClearSymbol( this_frame, 0 ); - astClearTitle( this_frame ); - -/* Modify the SpecOrigin value to use the new System */ - OriginSystem( this, oldsys, "astClearSystem", status ); - - } - -} - -static void ClearStdOfRest( AstSpecFrame *this, int *status ) { -/* -*+ -* Name: -* astClearStdOfRest - -* Purpose: -* Clear the StdOfRest attribute for a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* void astClearStdOfRest( AstSpecFrame *this ) - -* Class Membership: -* SpecFrame virtual function - -* Description: -* This function clears the StdOfRest attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Modify the SpecOrigin value stored in the SpecFrame structure to refer to the - default rest frame (heliocentric). */ - OriginStdOfRest( this, AST__HLSOR, "astClearStdOfRest", status ); - -/* Store a bad value for the standard of rest in the SpecFrame structure. */ - this->stdofrest = AST__BADSOR; -} - - -static void ClearUnit( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* ClearUnit - -* Purpose: -* Clear the value of the Unit string for a SpecFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void ClearUnit( AstFrame *this_frame, int axis ) - -* Class Membership: -* SpecFrame member function (over-rides the astClearUnit method inherited -* from the Frame class). - -* Description: -* This function clears the Unit string for a specified axis of a -* SpecFrame. It also clears the UsedUnit item in the SpecFrame -* structure corresponding to the current System. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* The number of the axis (zero-based). -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - int system; /* The SpecFrame's System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astClearUnit" ); - -/* Clear the UsedUnit item for the current System, if current set. */ - system = (int) astGetSystem( this ); - if( system < this->nuunits && this->usedunits ) { - this->usedunits[ system ] = astFree( this->usedunits[ system ] ); - } - -/* Use the parent method to clear the Unit attribute of the axis. */ - (*parent_clearunit)( this_frame, axis, status ); -} - -static double ConvertSourceVel( AstSpecFrame *this, AstStdOfRestType newsor, - AstSystemType newsys, int *status ) { -/* -* Name: -* ConvertSourceVel - -* Purpose: -* Convert the SourceVel value to a specified rest frame and spectral -* system. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* double ConvertSourceVel( AstSpecFrame *this, AstStdOfRestType newsor, -* AstSystemType newsys, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function convert the SourceVel value to a specified rest frame -* and spectral system, and returns the new value. - -* Parameters: -* this -* Pointer to the SpecFrame. -* newsor -* The rest frame in which the source velocity is required. -* newsys -* The spectral system (AST__VREL or AST__REDSHIFT) in which the -* source velocity is required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The converted source velocity (m/s), or redshift. - -* Notes: -* - This function returns zero if an error occurs. -*/ - -/* Local Variables: */ - AstSpecFrame *from; /* Pointer to a source SpecFrame */ - AstSpecFrame *to; /* Pointer to a destination SpecFrame */ - AstSpecMap *specmap; /* Pointer to a SpecMap */ - AstStdOfRestType sor; /* Standard of rest in which SourceVel is defined */ - AstSystemType sys; /* Spectral system in which SourceVel is defined */ - double ret; /* The returned value */ - double rf; /* Rest frequency (Hz) */ - double temp; /* Temporary storage */ - -/* Initialise */ - ret = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Get the value of the SourceVel attribute. This will be a velocity in m/s - (relativistic, radio or optical), or unitless redshift or beta factor, - depending on the current value of SourceSys. */ - ret = astGetSourceVel( this ); - -/* Check it can be used (depends on whether a value has been set and - whether the UseDefs attribute is zero). */ - VerifyAttrs( this, "convert source velocity to a new standard of rest", - "SourceVel", "astMatch", status ); - -/* Get the rest frame and spectral system to which value refers. */ - sor = astGetSourceVRF( this ); - sys = astGetSourceSys( this ); - -/* If necessary, convert to the requested rest frame and spectral system. */ - if( sor != newsor || sys != newsys ) { - -/* Verify that usable value is available for the RestFreq attribute. An - error is reported if not. */ - VerifyAttrs( this, "convert source velocity to a new standard of rest", - "RestFreq", "astMatch", status ); - -/* Take two copies of the supplied SpecFrame and set their StdOfRest - attributes to the required values. */ - from = astCopy( this ); - astSetStdOfRest( from, sor ); - - to = astCopy( this ); - astSetStdOfRest( to, newsor ); - -/* Initialise a new SpecMap to describe the conversion. The new SpecMap - initially represents a UnitMap. */ - specmap = astSpecMap( 1, 0, "", status ); - -/* Add a conversion from the spectral system in which the SourceVEl value - is stored, to relativistic velocity. */ - if( sys == AST__VRADIO ) { - astSpecAdd( specmap, "VRTOVL", 0, NULL ); - - } else if( sys == AST__VOPTICAL ) { - astSpecAdd( specmap, "VOTOVL", 0, NULL ); - - } else if( sys == AST__REDSHIFT ) { - astSpecAdd( specmap, "ZOTOVL", 0, NULL ); - - } else if( sys == AST__BETA ) { - astSpecAdd( specmap, "BTTOVL", 0, NULL ); - } - -/* Add a conversion from velocity to frequency since SorConvert converts - frequencies. */ - rf = astGetRestFreq( this ); - astSpecAdd( specmap, "VLTOFR", 1, &rf ); - -/* Now add a conversion from frequency in the SourveVRF standard of rest to - frequency in the required rest frame. */ - SorConvert( from, to, specmap, status ); - -/* Add a conversion from frequency back to velocity. Note, the value of the - rest frequency does not affect the overall conversion. */ - astSpecAdd( specmap, "FRTOVL", 1, &rf ); - -/* Add a conversion from relativistic velocity to the required spectral - system, if needed. */ - if( newsys == AST__VRADIO ) { - astSpecAdd( specmap, "VLTOVR", 0, NULL ); - - } else if( newsys == AST__VOPTICAL ) { - astSpecAdd( specmap, "VLTOVO",0, NULL ); - - } else if( newsys == AST__REDSHIFT ) { - astSpecAdd( specmap, "VLTOZO",0, NULL ); - - } else if( newsys == AST__BETA ) { - astSpecAdd( specmap, "VLTOBT",0, NULL ); - } - -/* Use the SpecMap to convert the source velocity in the SourceVRF - standard of rest and SourceSys spectral system to the required rest - frame and spectral system. */ - temp = ret; - astTran1( specmap, 1, &temp, 1, &ret ); - -/* Free resources */ - specmap = astAnnul( specmap ); - to = astAnnul( to ); - from = astAnnul( from ); - } - -/* Return zero if an error has occurred. */ - if( !astOK ) ret = 0.0; - -/* Return the answer. */ - return ret; - -} - -static const char *DefUnit( AstSystemType system, const char *method, - const char *class, int *status ){ -/* -* Name: -* DefUnit - -* Purpose: -* Return the default units for a spectral coordinate system type. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *DefUnit( AstSystemType system, const char *method, -* const char *class, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function returns a textual representation of the default -* units associated with the specified spectral coordinate system. - -* Parameters: -* system -* The spectral coordinate system. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* As tring describing the default units. This string follows the -* units syntax described in FITS WCS paper I "Representations of world -* coordinates in FITS" (Greisen & Calabretta). - -* Notes: -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Value to return */ - -/* Initialize */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get an identifier for the default units. */ - if( system == AST__FREQ ) { - result = "GHz"; - } else if( system == AST__ENERGY ) { - result = "J"; - } else if( system == AST__WAVENUM ) { - result = "1/m"; - } else if( system == AST__WAVELEN ) { - result = "Angstrom"; - } else if( system == AST__AIRWAVE ) { - result = "Angstrom"; - } else if( system == AST__VRADIO ) { - result = "km/s"; - } else if( system == AST__VOPTICAL ) { - result = "km/s"; - } else if( system == AST__REDSHIFT ) { - result = ""; - } else if( system == AST__BETA ) { - result = ""; - } else if( system == AST__VREL ) { - result = "km/s"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "%s(%s): Corrupt %s contains illegal System " - "identification code (%d).", status, method, class, class, - (int) system ); - } - -/* Return the result. */ - return result; -} - -static int EqualSor( AstSpecFrame *this, AstSpecFrame *that, int *status ) { -/* -* Name: -* EqualSor - -* Purpose: -* Do two SpecFrames use the same standard of rest? - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int EqualSor( AstSpecFrame *this, AstSpecFrame *that, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function returns non-zero if the two supplied SpecFrames use -* the same standard of rest. - -* Parameters: -* this -* Pointer to the first SpecFrame. -* that -* Pointer to the second SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the two SpecFrames use the same standard of rest. Zero -* otherwise. - -*/ - -/* Local Variables: */ - AstStdOfRestType sor; /* Standard of rest */ - int result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise. */ - result = 1; - -/* Compare StdOfRest attributes. */ - sor = astGetStdOfRest( this ); - if( astGetStdOfRest( that ) != sor ) { - result = 0; - -/* If the standards of rest are equal we need to check the the attributes - which specify the precise rest frame. */ - } else { - -/* The reference RA and Dec need to be equal */ - if( !astEQUAL( astGetRefRA( this ), astGetRefRA( that ) ) || - !astEQUAL( astGetRefDec( this ), astGetRefDec( that ) ) ) { - result = 0; - -/* For source rest frame, the source velocities, rest frames and systems must - be equal */ - } else if( sor == AST__SCSOR ){ - if( !astEQUAL( astGetSourceVel( this ), astGetSourceVel( that ) ) || - astGetSourceVRF( this ) != astGetSourceVRF( that ) || - astGetSourceSys( this ) != astGetSourceSys( that ) ) { - result = 0; - } - -/* For geocentric, barycentric and heliocentric rest frames, the epochs must - be the same */ - } else if( sor == AST__GESOR || sor == AST__BYSOR || sor == AST__HLSOR ){ - if( !astEQUAL( astGetEpoch( this ), astGetEpoch( that ) ) ) result = 0; - -/* For topocentric rest frame, the epoch and position of the observer must be - the same */ - } else if( sor == AST__TPSOR ){ - if( !astEQUAL( astGetEpoch( this ), astGetEpoch( that ) ) || - !astEQUAL( astGetObsAlt( this ), astGetObsAlt( that ) ) || - !astEQUAL( astGetObsLon( this ), astGetObsLon( that ) ) || - !astEQUAL( astGetObsLat( this ), astGetObsLat( that ) ) ) result = 0; - - } else if( sor != AST__LKSOR && sor != AST__LDSOR && - sor != AST__GLSOR && sor != AST__LGSOR && astOK ) { - astError( AST__INTER, "SorEqual(SpecFrame): Function SorEqual " - "does not yet support rest frame %d (AST internal " - "programming error)", status, sor ); - } - } - -/* Return the result */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied SpecFrame, -* in bytes. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - int result; /* Result value to return */ - int i; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - if( this->usedunits ) { - for( i = 0; i < this->nuunits; i++ ) { - result += astTSizeOf( this->usedunits[ i ] ); - } - result += astTSizeOf( this->usedunits ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetActiveUnit - -* Purpose: -* Obtain the value of the ActiveUnit flag for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int GetActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function returns the value of the ActiveUnit flag for a -* SpecFrame, which is always 1. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to use for the ActiveUnit flag (1). - -*/ - return 1; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the protected astGetAttrib -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a SpecFrame, formatted as a character string. - -* Parameters: -* this -* Pointer to the SpecFrame. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - The returned string pointer may point at memory allocated -* within the SpecFrame, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the SpecFrame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - AstStdOfRestType sor; /* Standard of rest */ - AstSystemType sys; /* Spectral system */ - char *new_attrib; /* Pointer value to new attribute name */ - const char *result; /* Pointer value to return */ - double dval; /* Attribute value */ - int ival; /* Attribute value */ - int len; /* Length of attrib string */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Create an FK5 J2000 SkyFrame which will be used for formatting and - unformatting sky positions, etc. */ - LOCK_MUTEX2 - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000", status ); - astEndPM; - } - UNLOCK_MUTEX2 - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* First look for axis attributes defined by the Frame class. Since a - SpecFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strcmp( attrib, "direction" ) || - !strcmp( attrib, "bottom" ) || - !strcmp( attrib, "top" ) || - !strcmp( attrib, "format" ) || - !strcmp( attrib, "label" ) || - !strcmp( attrib, "symbol" ) || - !strcmp( attrib, "unit" ) ) { - -/* Create a new attribute name from the original by appending the string - "(1)" and then use the parent GetAttrib method. */ - new_attrib = astMalloc( len + 4 ); - if( new_attrib ) { - memcpy( new_attrib, attrib, len ); - memcpy( new_attrib + len, "(1)", 4 ); - result = (*parent_getattrib)( this_object, new_attrib, status ); - new_attrib = astFree( new_attrib ); - } - -/* AlignStdOfRest. */ -/* --------------- */ -/* Obtain the AlignStdOfRest code and convert to a string. */ - } else if ( !strcmp( attrib, "alignstdofrest" ) ) { - sor = astGetAlignStdOfRest( this ); - if ( astOK ) { - result = StdOfRestString( sor, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid AlignStdOfRest " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) sor ); - } - } - -/* AlignSpecOffset */ -/* --------------- */ - } else if ( !strcmp( attrib, "alignspecoffset" ) ) { - ival = astGetAlignSpecOffset( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - SpecFrame had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "geolat" ) ) { - result = astGetAttrib( this, "obslat" ); - -/* GeoLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "geolon" ) ) { - result = astGetAttrib( this, "obslon" ); - -/* RefDec. */ -/* ------- */ -/* Convert to a string using the SkyFrame Format method. */ - } else if ( !strcmp( attrib, "refdec" ) ) { - dval = astGetRefDec( this ); - if ( astOK ) { - result = astFormat( skyframe, 1, dval ); - } - -/* RefRA. */ -/* ------ */ -/* Convert to a string using the SkyFrame Format method. */ - } else if ( !strcmp( attrib, "refra" ) ) { - dval = astGetRefRA( this ); - if ( astOK ) { - result = astFormat( skyframe, 0, dval ); - } - -/* RestFreq. */ -/* --------- */ - } else if ( !strcmp( attrib, "restfreq" ) ) { - dval = astGetRestFreq( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval*1.0E-9 ); - result = getattrib_buff; - } - -/* SourceVel */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcevel" ) ) { - dval = astGetSourceVel( this ); - if ( astOK ) { - -/* Convert from m/s to km/s if the SourceVel value is a velocity. . */ - if( astGetSourceSys( this ) == AST__VREL || - astGetSourceSys( this ) == AST__VRADIO || - astGetSourceSys( this ) == AST__VOPTICAL ) dval *= 1.0E-3; - -/* Format */ - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - - } - -/* SpecOrigin. */ -/* ----------- */ - } else if ( !strcmp( attrib, "specorigin" ) ) { - dval = GetSpecOriginCur( this, status ); - if( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - -/* SourceVRF */ -/* ----------*/ - } else if ( !strcmp( attrib, "sourcevrf" ) ) { - sor = astGetSourceVRF( this ); - if ( astOK ) { - result = StdOfRestString( sor, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid SourceVRF " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) sor ); - } - } - -/* SourceSys */ -/* ----------*/ - } else if ( !strcmp( attrib, "sourcesys" ) ) { - sys = astGetSourceSys( this ); - if ( astOK ) { - result = SystemString( (AstFrame *) this, sys, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid SourceSys " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) sys ); - } - } - -/* StdOfRest. */ -/* ---------- */ -/* Obtain the StdOfRest code and convert to a string. */ - } else if ( !strcmp( attrib, "stdofrest" ) ) { - sor = astGetStdOfRest( this ); - if ( astOK ) { - result = StdOfRestString( sor, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid StdOfRest " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) sor ); - } - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static const char *GetDomain( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetDomain - -* Purpose: -* Obtain a pointer to the Domain attribute string for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetDomain( AstFrame *this, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetDomain protected -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the Domain attribute string -* for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a constant null-terminated string containing the -* Domain value. - -* Notes: -* - The returned pointer or the string it refers to may become -* invalid following further invocation of this function or -* modification of the SpecFrame. -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* If a Domain attribute string has been set, invoke the parent method - to obtain a pointer to it. */ - if ( astTestDomain( this ) ) { - result = (*parent_getdomain)( this_frame, status ); - -/* Otherwise, provide a pointer to a suitable default string. */ - } else { - result = "SPECTRUM"; - } - -/* Return the result. */ - return result; -} - -static const char *GetLabel( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetLabel - -* Purpose: -* Access the Label string for a SpecFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetLabel( AstFrame *this, int axis, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetLabel method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Label string for a specified axis -* of a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstMapping *map; /* Mapping between units */ - AstSystemType system; /* Code identifying type of spectral coordinates */ - char *new_lab; /* Modified label string */ - const char *result; /* Pointer to label string */ - double orig; /* Spec origin */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetLabel" ); - -/* Check if a value has been set for the required axis label string. If so, - invoke the parent astGetLabel method to obtain a pointer to it. */ - if ( astTestLabel( this, axis ) ) { - result = (*parent_getlabel)( this, axis, status ); - -/* Otherwise, identify the spectral coordinate system described by the - SpecFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default label string. */ - if ( astOK ) { - result = strcpy( getlabel_buff, SystemLabel( system, status ) ); - getlabel_buff[ 0 ] = toupper( getlabel_buff[ 0 ] ); - -/* If a non-zero SpecOrigin has been specified, include the offset now. */ - orig = GetSpecOriginCur( (AstSpecFrame *) this, status ); - if( orig != 0.0 ) { - sprintf( getlabel_buff + strlen( getlabel_buff ), " offset from %s", - astFormat( this, 0, orig ) ); - } - -/* Modify this default to take account of the current value of the Unit - attribute, if set. */ - if( astTestUnit( this, axis ) ) { - -/* Find a Mapping from the default Units for the current System, to the - units indicated by the Unit attribute. This Mapping is used to modify - the existing default label appropriately. For instance, if the default - units is "Hz" and the actual units is "log(Hz)", then the default label - of "Frequency" is changed to "log( frequency )". */ - map = astUnitMapper( DefUnit( system, "astGetLabel", - astGetClass( this ), status ), - astGetUnit( this, axis ), result, - &new_lab ); - if( new_lab ) { - result = strcpy( getlabel_buff, new_lab ); - new_lab = astFree( new_lab ); - } - -/* Annul the unused Mapping. */ - if( map ) map = astAnnul( map ); - - } - } - } - -/* Return the result. */ - return result; -} - -static void GetRefPos( AstSpecFrame *this, AstSkyFrame *frm, double *lon, - double *lat, int *status ){ -/* -*++ -* Name: -c astGetRefPos -f AST_GETREFPOS - -* Purpose: -* Return the reference position in a specified celestial coordinate system. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "specframe.h" -c void astGetRefPos( AstSpecFrame *this, AstSkyFrame *frm, double *lon, -c double *lat ) -f CALL AST_GETREFPOS( THIS, FRM, LON, LAT, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* returns the reference position (specified by attributes RefRA and -* RefDec) converted to the celestial coordinate system represented by -* a supplied SkyFrame. The celestial longitude and latitude values -* are returned in radians. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the SpecFrame. -c frm -f FRM = INTEGER (Given) -* Pointer to the SkyFrame which defines the required celestial -* coordinate system. -c If NULL -f If AST__NULL -* is supplied, then the longitude and latitude values are returned -* as FK5 J2000 RA and Dec values. -c lon -f LON = DOUBLE PRECISION (Returned) -c A pointer to a double in which to store the -f The -* longitude of the reference point, in the coordinate system -* represented by the supplied SkyFrame (radians). -c lat -f LAT = DOUBLE PRECISION (Returned) -c A pointer to a double in which to store the -f The -* latitude of the reference point, in the coordinate system -* represented by the supplied SkyFrame (radians). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Values of AST__BAD will be returned if this function is -c invoked with the AST error status set, or if it should fail for -f invoked with STATUS set to an error value, or if it should fail for -* any reason. -*-- -*/ - -/* Local Variables: */ - AstFrameSet *fs; /* Conversion FrameSet */ - AstFrame *fb; /* Base Frame */ - AstFrame *fc; /* Current Frame */ - double xin[ 1 ]; /* Axis 1 values */ - double yin[ 1 ]; /* Axis 2 values */ - double xout[ 1 ]; /* Axis 1 values */ - double yout[ 1 ]; /* Axis 2 values */ - -/* Initialise. */ - if( lon ) *lon = AST__BAD; - if( lat ) *lat = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If no SkyFrame was supplied, just return the stored RefRA and RefDec - values. */ - if( !frm ) { - if( lon ) *lon = astGetRefRA( this ); - if( lat ) *lat = astGetRefDec( this ); - -/* Otherwise, convert the stored values to the requested system. */ - } else { - -/* Create an FK5 J2000 SkyFrame which will be used for formatting and - unformatting sky positions, etc. */ - LOCK_MUTEX2 - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000", status ); - astEndPM; - } - UNLOCK_MUTEX2 - -/* Find the Mapping from the SkyFrame which describes the internal format - in which the RefRA and RefDec attribute values are stored, to the - supplied Frame. */ - fs = astFindFrame( skyframe, frm, "" ); - -/* If alignment was possible, use the Mapping to transform the internal - RefRA and RefDec values. Check for axis permutatuion. */ - if( fs ) { - fb = astGetFrame( fs, AST__BASE ); - if( astGetLonAxis( fb ) == 0 ) { - xin[ 0 ] = astGetRefRA( this ); - yin[ 0 ] = astGetRefDec( this ); - } else { - yin[ 0 ] = astGetRefRA( this ); - xin[ 0 ] = astGetRefDec( this ); - } - astTran2( fs, 1, xin, yin, 1, xout, yout ); - -/* Store the returned values, checking to see if the axes of the supplied - SkyFrame have been permuted. */ - fc = astGetFrame( fs, AST__CURRENT ); - if( astGetLonAxis( fc ) == 0 ) { - if( lon ) *lon = xout[ 0 ]; - if( lat ) *lat = yout[ 0 ]; - } else { - if( lon ) *lon = yout[ 0 ]; - if( lat ) *lat = xout[ 0 ]; - } - -/* Annul object references. */ - fc = astAnnul( fc ); - fb = astAnnul( fb ); - fs = astAnnul( fs ); - } - } -} - -static const char *GetSymbol( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetSymbol - -* Purpose: -* Obtain a pointer to the Symbol string for a SpecFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetSymbol( AstFrame *this, int axis, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetSymbol method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Symbol string for a specified axis -* of a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstMapping *map; /* Mapping between units */ - AstSystemType system; /* Code identifying type of sky coordinates */ - char *new_sym; /* Modified symbol string */ - const char *result; /* Pointer to symbol string */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetSymbol" ); - -/* Check if a value has been set for the required axis symbol string. If so, - invoke the parent astGetSymbol method to obtain a pointer to it. */ - if ( astTestSymbol( this, axis ) ) { - result = (*parent_getsymbol)( this, axis, status ); - -/* Otherwise, identify the sky coordinate system described by the SpecFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default Symbol string. */ - if ( astOK ) { - - if( system == AST__FREQ ) { - result = "FREQ"; - } else if( system == AST__ENERGY ) { - result = "ENER"; - } else if( system == AST__WAVENUM ) { - result = "WAVN"; - } else if( system == AST__WAVELEN ) { - result = "WAVE"; - } else if( system == AST__AIRWAVE ) { - result = "AWAV"; - } else if( system == AST__VRADIO ) { - result = "VRAD"; - } else if( system == AST__VOPTICAL ) { - result = "VOPT"; - } else if( system == AST__REDSHIFT ) { - result = "ZOPT"; - } else if( system == AST__BETA ) { - result = "BETA"; - } else if( system == AST__VREL ) { - result = "VELO"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "astGetSymbol(%s): Corrupt %s contains " - "invalid System identification code (%d).", status, - astGetClass( this ), astGetClass( this ), (int) system ); - } - -/* Modify this default to take account of the current value of the Unit - attribute, if set. */ - if( astTestUnit( this, axis ) ) { - -/* Find a Mapping from the default Units for the current System, to the - units indicated by the Unit attribute. This Mapping is used to modify - the existing default symbol appropriately. For instance, if the default - units is "Hz" and the actual units is "log(Hz)", then the default symbol - of "nu" is changed to "log( nu )". */ - map = astUnitMapper( DefUnit( system, "astGetSymbol", - astGetClass( this ), status ), - astGetUnit( this, axis ), result, - &new_sym ); - if( new_sym ) { - result = strcpy( getsymbol_buff, new_sym ); - new_sym = astFree( new_sym ); - } - -/* Annul the unused Mapping. */ - if( map ) map = astAnnul( map ); - - } - } - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetAlignSystem - -* Purpose: -* Obtain the AlignSystem attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "Specframe.h" -* AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetAlignSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the AlignSystem attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The AlignSystem value. - -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* If a AlignSystem attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestAlignSystem( this ) ) { - result = (*parent_getalignsystem)( this_frame, status ); - -/* Otherwise, provide a suitable default. */ - } else { - result = AST__WAVELEN; - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetSystem - -* Purpose: -* Obtain the System attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* AstSystemType GetSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the System attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System value. - -* Notes: -* - AST__BADSYSTEM is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* If a System attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestSystem( this ) ) { - result = (*parent_getsystem)( this_frame, status ); - -/* Otherwise, provide a suitable default. */ - } else { - result = AST__WAVELEN; - } - -/* Return the result. */ - return result; -} - -static const char *GetTitle( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetTitle - -* Purpose: -* Obtain a pointer to the Title string for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetTitle( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetTitle method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Title string for a SpecFrame. -* A pointer to a suitable default string is returned if no Title value has -* previously been set. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null-terminated character string containing the requested -* information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstStdOfRestType sor; /* Code identifying standard of rest */ - AstSystemType system; /* Code identifying type of coordinates */ - const char *sor_string; /* Pointer to SOR description */ - const char *result; /* Pointer to result string */ - double rf; /* Rest frequency */ - int nc; /* No. of characters added */ - int pos; /* Buffer position to enter text */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_frame); - -/* Initialise. */ - result = NULL; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* See if a Title string has been set. If so, use the parent astGetTitle - method to obtain a pointer to it. */ - if ( astTestTitle( this ) ) { - result = (*parent_gettitle)( this_frame, status ); - -/* Otherwise, we will generate a default Title string. Obtain the values of the - SpecFrame's attributes that determine what this string will be. */ - } else { - system = astGetSystem( this ); - sor = astGetStdOfRest( this ); - sor_string = StdOfRestString( sor, status ); - rf = astGetRestFreq( this ); - -/* Classify the coordinate system type and create an appropriate Title - string. (Note that when invoking the astFmtDecimalYr function we must - use a separate sprintf on each occasion so as not to over-write its - internal buffer before the result string has been used.) */ - if ( astOK ) { - result = gettitle_buff; - -/* Begin with the system's default label. */ - pos = sprintf( gettitle_buff, "%s", SystemLabel( system, status ) ); - gettitle_buff[ 0 ] = toupper( gettitle_buff[ 0 ] ); - -/* Append the standard of rest in parentheses, if set. */ - if( astTestStdOfRest( this ) ) { - nc = sprintf( gettitle_buff+pos, " (%s)", sor_string ); - pos += nc; - } - -/* Append the rest frequency if relevant. */ - if( !ABS_SYSTEM(system) && ( astTestRestFreq( this ) || - astGetUseDefs( this ) ) ) { - pos += sprintf( gettitle_buff+pos, ", rest frequency = %g GHz", rf*1.0E-9 ); - } - } - } - -/* If an error occurred, clear the returned pointer value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static double GetSpecOriginCur( AstSpecFrame *this, int *status ) { -/* -* Name: -* GetSpecOriginCur - -* Purpose: -* Obtain the SpecOrigin attribute for a SpecFrame in current units. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double GetSpecOriginCur( AstSpecFrame *this, int *status ) - -* Class Membership: -* SpecFrame virtual function - -* Description: -* This function returns the SpecOrigin attribute for a SpecFrame, in -* the current units of the SpecFrame. The protected astGetSpecOrigin -* method can be used to obtain the time origin in the default units of -* the SpecFrame's System. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The SpecOrigin value, in the units, system and rest frame specified -* by the current values of the Unit, System and StdOfRest attributes -* within "this". - -* Notes: -* - AST__BAD is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *map; - const char *cur; - const char *def; - double result; - double defval; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the value in the default units */ - result = astGetSpecOrigin( this ); - -/* If SpecOrigin is non-zero and non-BAD we convert it to the current units.*/ - if( result != 0.0 && result != AST__BAD ) { - -/* Get the default units for the SpecFrame's System. */ - def = DefUnit( astGetSystem( this ), "astGetSpecOrigin", "SpecFrame", status ); - -/* Get the current units from the SpecFrame. */ - cur = astGetUnit( this, 0 ); - -/* If the units differ, get a Mapping from default to current units. */ - if( cur && def ){ - if( strcmp( cur, def ) ) { - map = astUnitMapper( def, cur, NULL, NULL ); - -/* Report an error if the units are incompatible. */ - if( !map ) { - astError( AST__BADUN, "%s(%s): The current units (%s) are not suitable " - "for a SpecFrame.", status, "astGetSpecOrigin", astGetClass( this ), - cur ); - -/* Otherwise, transform the stored origin value.*/ - } else { - defval = result; - astTran1( map, 1, &defval, 1, &result ); - map = astAnnul( map ); - } - } - } - } - -/* Return the result. */ - return result; -} - - -static const char *GetUnit( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetUnit - -* Purpose: -* Obtain a pointer to the Unit string for a SpecFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetUnit( AstFrame *this_frame, int axis ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetUnit method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Unit string for a specified axis -* of a SpecFrame. If the Unit attribute has not been set for the axis, a -* pointer to a suitable default string is returned instead. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* The number of the axis (zero-based) for which information is required. - -* Returned Value: -* A pointer to a null-terminated string containing the Unit value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - AstSystemType system; /* The SpecFrame's System value */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetUnit" ); - -/* If a value has been set for the Unit attribute, use the parent - GetUnit method to return a pointer to the required Unit string. */ - if( astTestUnit( this, axis ) ){ - result = (*parent_getunit)( this_frame, axis, status ); - -/* Otherwise, identify the spectral coordinate system described by the - SpecFrame. */ - } else { - system = astGetSystem( this ); - -/* Return a string describing the default units. */ - result = DefUnit( system, "astGetUnit", astGetClass( this ), status ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -void astInitSpecFrameVtab_( AstSpecFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSpecFrameVtab - -* Purpose: -* Initialise a virtual function table for a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* void astInitSpecFrameVtab( AstSpecFrameVtab *vtab, const char *name ) - -* Class Membership: -* SpecFrame vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SpecFrame class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameVtab( (AstFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASpecFrame) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->GetRefPos = GetRefPos; - vtab->SetRefPos = SetRefPos; - - vtab->ClearAlignStdOfRest = ClearAlignStdOfRest; - vtab->TestAlignStdOfRest = TestAlignStdOfRest; - vtab->GetAlignStdOfRest = GetAlignStdOfRest; - vtab->SetAlignStdOfRest = SetAlignStdOfRest; - - vtab->ClearSourceVRF = ClearSourceVRF; - vtab->TestSourceVRF = TestSourceVRF; - vtab->GetSourceVRF = GetSourceVRF; - vtab->SetSourceVRF = SetSourceVRF; - - vtab->ClearSourceSys = ClearSourceSys; - vtab->TestSourceSys = TestSourceSys; - vtab->GetSourceSys = GetSourceSys; - vtab->SetSourceSys = SetSourceSys; - - vtab->ClearRefDec = ClearRefDec; - vtab->TestRefDec = TestRefDec; - vtab->GetRefDec = GetRefDec; - vtab->SetRefDec = SetRefDec; - - vtab->ClearRefRA = ClearRefRA; - vtab->TestRefRA = TestRefRA; - vtab->GetRefRA = GetRefRA; - vtab->SetRefRA = SetRefRA; - - vtab->ClearRestFreq = ClearRestFreq; - vtab->TestRestFreq = TestRestFreq; - vtab->GetRestFreq = GetRestFreq; - vtab->SetRestFreq = SetRestFreq; - - vtab->ClearStdOfRest = ClearStdOfRest; - vtab->TestStdOfRest = TestStdOfRest; - vtab->GetStdOfRest = GetStdOfRest; - vtab->SetStdOfRest = SetStdOfRest; - - vtab->ClearSourceVel = ClearSourceVel; - vtab->TestSourceVel = TestSourceVel; - vtab->GetSourceVel = GetSourceVel; - vtab->SetSourceVel = SetSourceVel; - - vtab->ClearSpecOrigin = ClearSpecOrigin; - vtab->TestSpecOrigin = TestSpecOrigin; - vtab->GetSpecOrigin = GetSpecOrigin; - vtab->SetSpecOrigin = SetSpecOrigin; - - vtab->TestAlignSpecOffset = TestAlignSpecOffset; - vtab->SetAlignSpecOffset = SetAlignSpecOffset; - vtab->GetAlignSpecOffset = GetAlignSpecOffset; - vtab->ClearAlignSpecOffset = ClearAlignSpecOffset; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - frame = (AstFrameVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_getdomain = frame->GetDomain; - frame->GetDomain = GetDomain; - - parent_getsystem = frame->GetSystem; - frame->GetSystem = GetSystem; - parent_setsystem = frame->SetSystem; - frame->SetSystem = SetSystem; - parent_clearsystem = frame->ClearSystem; - frame->ClearSystem = ClearSystem; - - parent_getalignsystem = frame->GetAlignSystem; - frame->GetAlignSystem = GetAlignSystem; - - parent_getlabel = frame->GetLabel; - frame->GetLabel = GetLabel; - - parent_getsymbol = frame->GetSymbol; - frame->GetSymbol = GetSymbol; - - parent_gettitle = frame->GetTitle; - frame->GetTitle = GetTitle; - - parent_clearunit = frame->ClearUnit; - frame->ClearUnit = ClearUnit; - - parent_getunit = frame->GetUnit; - frame->GetUnit = GetUnit; - - parent_setunit = frame->SetUnit; - frame->SetUnit = SetUnit; - - parent_match = frame->Match; - frame->Match = Match; - - parent_overlay = frame->Overlay; - frame->Overlay = Overlay; - - parent_subframe = frame->SubFrame; - frame->SubFrame = SubFrame; - -/* Store replacement pointers for methods which will be over-ridden by new - member functions implemented here. */ - frame->GetActiveUnit = GetActiveUnit; - frame->TestActiveUnit = TestActiveUnit; - frame->ValidateSystem = ValidateSystem; - frame->SystemString = SystemString; - frame->SystemCode = SystemCode; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "SpecFrame", - "Description of spectral coordinate system" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MakeSpecMapping( AstSpecFrame *target, AstSpecFrame *result, - AstSpecFrame *align_frm, int report, - AstMapping **map, int *status ) { -/* -* Name: -* MakeSpecMapping - -* Purpose: -* Generate a Mapping between two SpecFrames. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int MakeSpecMapping( AstSpecFrame *target, AstSpecFrame *result, -* AstSpecFrame *align_frm, int report, -* AstMapping **map, int *status ) { - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function takes two SpecFrames and generates a Mapping that -* converts between them, taking account of differences in their -* coordinate systems, rest frequency, standard of rest, etc. -* -* In order to cut down the number of transformations to be considered, -* the scheme works by first converting from the target frame to an -* "alignment" Frame, using the attributes of the target to define the -* transformation. A transformation is then found from the alignment -* frame to the required result Frame, using the attributes of the -* result to define the transformation. The alignment Frame is -* described by the AlignSystem and AlignStdOfRest attributes of the -* "align_frm" SpecFrame. -* -* Thus, different forms of alignment can be obtained by suitable -* choice of the attributes of "align_frm". For instance, to compare the -* radio velocity dispersion of two lines at different rest frequencies, -* you would set "system=radio velocity" and (probably) "stdofrest=local -* group" in "align_frm". On the other hand if you wanted to re-calibrate -* an existing radio velocity Frame within a FrameSet to use a different -* rest frequency, you would make the SpecFrame the current Frame and then -* set the rest frequency attribute for the FrameSet. The "integrity -* checking" system in the FrameSet class would then get the Mapping -* between the original and the modified SpecFrames. In this case, the -* "alignment system" needs to be "frequency" since you want the original -* and modified SpecFrames to be aligned in frequency, not radio velocity. - -* Parameters: -* target -* Pointer to the first SpecFrame. -* result -* Pointer to the second SpecFrame. -* align_frm -* A SpecFrame defining the system and standard of rest in which to -* align the target and result SpecFrames. -* report -* Should errors be reported if no match is possible? These reports -* will describe why no match was possible. -* map -* Pointer to a location which is to receive a pointer to the -* returned Mapping. The forward transformation of this Mapping -* will convert from "target" coordinates to "result" -* coordinates, and the inverse transformation will convert in -* the opposite direction (all coordinate values in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Mapping could be generated, or zero if the two -* SpecFrames are sufficiently un-related that no meaningful Mapping -* can be produced (albeit an "unmeaningful" Mapping will be returned -* in this case, which will need to be annulled). - -* Notes: -* A value of zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Constants: */ -#define MAX_ARGS 1 /* Max arguments for an SpecMap conversion */ - -/* Local Variables: */ - AstMapping *map1; /* Intermediate Mapping */ - AstMapping *map2; /* Intermediate Mapping */ - AstMapping *umap1; /* First Units Mapping */ - AstMapping *umap2; /* Second Units Mapping */ - AstSpecMap *specmap; /* Pointer to SpecMap */ - AstShiftMap *sm; /* ShiftMap pointer */ - AstSpecFrame *align_target; /* Alignment Frame with target properties */ - AstSpecFrame *align_result; /* Alignment Frame with result properties */ - AstSystemType serr; /* Erroneous system */ - AstSystemType align_system; /* Code to identify alignment system */ - AstSystemType target_system; /* Code to identify target system */ - AstSystemType result_system; /* Code to identify result system */ - const char *uerr; /* Erroneous units */ - const char *ures; /* Results units */ - const char *utarg; /* Target units */ - const char *vmess; /* Text for use in error messages */ - double args[ MAX_ARGS ]; /* Conversion argument array */ - double target_rf; /* Target rest frequency (Hz) */ - double result_rf; /* Result rest frequency (Hz) */ - double target_origin; /* Target origin */ - double result_origin; /* Result origin */ - int match; /* Mapping can be generated? */ - int step2; /* Perform the 2nd step in the Mapping? */ - int step3; /* Perform the 3rd step in the Mapping? */ - int step4; /* Perform the 4th step in the Mapping? */ - int step5; /* Perform the 5th step in the Mapping? */ - int step6; /* Perform the 6th step in the Mapping? */ - int step7; /* Perform the 7th step in the Mapping? */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise the returned values. */ - match = 1; - *map = NULL; - -/* Create an initial (null) SpecMap. This is a 1D Mapping which converts - spectral axis values between different systems and standard of rest. - The axis units used by the SpecMap class match the default units used - by this class. Any discrepancy between units is taken into account at - the end of this function, once the total SpecMap has been created. */ - specmap = astSpecMap( 1, 0, "", status ); - -/* Define local macros as shorthand for adding spectral coordinate - conversions to this SpecMap. Each macro simply stores details of - the additional arguments in the "args" array and then calls - astSpecAdd. The macros differ in the number of additional argument - values. */ -#define TRANSFORM_0(cvt) \ - astSpecAdd( specmap, cvt, 0, NULL ); - -#define TRANSFORM_1(cvt,arg0) \ - args[ 0 ] = arg0; \ - astSpecAdd( specmap, cvt, 1, args ); - -/* Get all the necessary attributes from the result, target and alignment - Frames. */ - target_rf = astGetRestFreq( target ); - result_rf = astGetRestFreq( result ); - - target_system = astGetSystem( target ); - result_system = astGetSystem( result ); - align_system = astGetSystem( align_frm ); - -/* Define text for error messages.*/ - vmess = "convert between spectral systems"; - -/* Verify that values for the standard of rest have been set if required - (i.e if the UseDefs attribute of either SpecFrame is false). */ - VerifyAttrs( result, vmess, "StdOfRest", "astMatch", status ); - VerifyAttrs( target, vmess, "StdOfRest", "astMatch", status ); - -/* There are two different strategies for alignment. I'll use the Source - rest frame as an example, although the same argument applies to other - rest frames. In the first strategy, all "Source" rest frames are - considered equal. That is, if two SpecFrames respresent (for example) - frequencies in the source frame, then the SpecFrames are aligned using - a UnitMap even if the details of the two source rest frames differ. - This is usually what users want to see when (for instance) aligning - plots of two spectra which both represent source frequencies but where - the source frames details differ. In the second strategy, "Source" - rest frames are aligned using a SpecMap that takes into account any - differences in the properties of the source rest frames. This is what - should happen when changes are made to the properties of a SpecFrame - within a FrameSet. For instance, if the user changes the SourceVel - attribute of the current Frame (assumed here to be a SpecFrame) in a - FrameSet, then the process of restoring the integrity of the FrameSet - (see frameset.c for details of integrity restoration) should cause the - base->current Mapping in the FrameSet to be modified to reflect the - new SourceVel value. - - So if the current call to this function is part of the process of - restoring a FrameSet's integrity following changes to the FrameSet's - current Frame, then we want to retain the properties of the supplied - alignment Frame. So we use clones of the supplied alignment Frame. */ - if( astGetFrameFlags( target ) & AST__INTFLAG ) { - align_target = astClone( align_frm ); - align_result = astClone( align_frm ); - -/* Buf if we are not restoring the integrity of a FrameSet, we want - to ignore any differences in the properties that define the available - rest frames. So create copies of the alignment Frame in which the - properies defining the available rest frames are the same as in the - target and result Frames. */ - } else { - align_target = astCopy( align_frm ); - astSetEpoch( align_target, astGetEpoch( target ) ); - astSetRefRA( align_target, astGetRefRA( target ) ); - astSetRefDec( align_target, astGetRefDec( target ) ); - astSetSourceVRF( align_target, astGetSourceVRF( target ) ); - astSetSourceVel( align_target, astGetSourceVel( target ) ); - astSetObsLat( align_target, astGetObsLat( target ) ); - astSetObsLon( align_target, astGetObsLon( target ) ); - astSetObsAlt( align_target, astGetObsAlt( target ) ); - - align_result = astCopy( align_frm ); - astSetEpoch( align_result, astGetEpoch( result ) ); - astSetRefRA( align_result, astGetRefRA( result ) ); - astSetRefDec( align_result, astGetRefDec( result ) ); - astSetSourceVRF( align_result, astGetSourceVRF( result ) ); - astSetSourceVel( align_result, astGetSourceVel( result ) ); - astSetObsLat( align_result, astGetObsLat( result ) ); - astSetObsLon( align_result, astGetObsLon( result ) ); - astSetObsAlt( align_result, astGetObsAlt( result ) ); - } - -/* The supported spectral coordinate systems fall into two groups; - "relative", and "absolute". The relative systems define each axis - value with respect to the rest frequency, whereas the absolute systems - have axis values which do not depend on the rest frequency. In order - to convert an axis value from a system in one group to a system in the - other group, the rest frequency must be known. However, the rest - frequency is not necessary in order to convert axis values between two - systems belonging to the same group. Determine if the alignment system - is absolute or relative. If absolute, we ignore the system of the supplied - "align_frm" and align in frequency, since aligning in any absolute system - will automatically ensure that all the other absolute systems are aligned. - Similarly, aligning in any relative system will automatically ensure that - all the other relative systems are aligned. Doing this cuts down the - complexity of the conversion process since we do not need to check every - possible alignment system. */ - align_system = ( ABS_SYSTEM( align_system ) ) ? AST__FREQ : AST__VREL; - -/* The total Mapping is made up of the following steps in series: - - 0) Convert from an offset value to an absolute value (if SpecOrigin set) - 1) Convert target units to default units for the targets system - 2) Convert from target system in target SOR to frequency in target SOR - 3) Convert from freq in target SOR to freq in alignment SOR - 4) Convert from freq in alignment SOR to alignment system in alignment SOR - 5) Convert from alignment system in alignment SOR to freq in alignment SOR - 6) Convert from freq in alignment SOR to freq in result SOR - 7) Convert from freq in result SOR to result system in result SOR - 8) Convert default units for the result system to results unit - 9) Convert from an absolute value to an offset value (if SpecOrigin set) - - Steps 1,2,3,4 are performed using the attributes of the target (rest - frequency, reference farem, etc), whilst steps 5,6,7,8 are performed - using the attributes of the target (rest frequency, reference frame, - etc). It is necessary to go from target system to alignment system - via frequency because SOR conversion can only be performed in the - frequency domain. - - Some of these steps may not be necessary. Initially assume all steps - are necessary (we leave steps 0, 1, 8 and 9 out of this process and - implement them once all other steps have been done). */ - step2 = 1; - step3 = 1; - step4 = 1; - step5 = 1; - step6 = 1; - step7 = 1; - -/* Step 2 is not necessary if the target system is frequency. */ - if( target_system == AST__FREQ ) step2 = 0; - -/* Step 3 is not necessary if the alignment SOR is the same as the target - SOR. */ - if( EqualSor( target, align_target, status ) ) step3 = 0; - -/* Step 6 is not necessary if the alignment SOR is the same as the result - SOR. */ - if( EqualSor( result, align_result, status ) ) step6 = 0; - -/* Step 7 is not necessary if the result system is frequency. */ - if( result_system == AST__FREQ ) step7 = 0; - -/* Steps 4 and 5 are not necessary if the alignment system is frequency, - or if the target and result rest frequencies are equal. */ - if( align_system == AST__FREQ || result_rf == target_rf ) step4 = step5 = 0; - -/* Steps 3 and 6 are not necessary if steps 4 and 5 are not necessary, and - the target sor equals the result sor. */ - if( !step4 && !step5 && EqualSor( target, result, status ) ) step3 = step6 = 0; - -/* Steps 2 and 7 are not necessary if steps 3, 4, 5 and 6 are not necessary, - and the target sor equals the result sor, and the target and results - systems are equal (if the systems are relative they must also have equal - rest frequencies). */ - if( !step3 && !step4 && !step5 && !step6 && EqualSor( target, result, status ) && - target_system == result_system ) { - if( !ABS_SYSTEM( target_system ) && result_rf == target_rf ) step2 = step7 = 0; - } - - -/* Now we know which steps are needed, let's do them (we delay unit - conversion to the end)... */ - -/* Step 2: target system in target rest frame to frequency in target rest - frame. */ - if( step2 ) { - if( target_system != AST__FREQ ) { - -/* If the target system is absolute, we can convert directly to frequency. */ - if ( target_system == AST__ENERGY ) { - TRANSFORM_0( "ENTOFR" ) - - } else if ( target_system == AST__WAVENUM ) { - TRANSFORM_0( "WNTOFR" ) - - } else if ( target_system == AST__WAVELEN ) { - TRANSFORM_0( "WVTOFR" ) - - } else if ( target_system == AST__AIRWAVE ) { - TRANSFORM_0( "AWTOFR" ) - -/* If the target target_system is relative, we first need to convert to - apparent radial velocity, and then to frequency using the rest frequency. */ - } else { - - if ( target_system == AST__VRADIO ) { - TRANSFORM_0( "VRTOVL" ) - - } else if ( target_system == AST__VOPTICAL ) { - TRANSFORM_0( "VOTOVL" ) - - } else if ( target_system == AST__REDSHIFT ) { - TRANSFORM_0( "ZOTOVL" ) - - } else if ( target_system == AST__BETA ) { - TRANSFORM_0( "BTTOVL" ) - } - - VerifyAttrs( target, vmess, "RestFreq", "astMatch", status ); - TRANSFORM_1( "VLTOFR", target_rf ) - } - } - } - -/* Step 3: frequency in target rest frame to frequency in alignment rest - frame. */ - if( step3 ) match = SorConvert( target, align_target, specmap, status ); - -/* Step 4: frequency in alignment rest frame to alignment system in alignment - rest frame. The alignment will be either relativistic velocity or - frequency. */ - if( step4 ) { - if( align_system == AST__VREL ) { - VerifyAttrs( target, vmess, "RestFreq", "astMatch", status ); - TRANSFORM_1( "FRTOVL", target_rf ) - } - } - -/* Step 5: Alignment system in alignment rest frame to frequency in alignment - rest frame (from now on use the attributes of the result SpecFrame to - define the conversion parameters). */ - if( step5 ) { - if( align_system == AST__VREL ) { - VerifyAttrs( result, vmess, "RestFreq", "astMatch", status ); - TRANSFORM_1( "VLTOFR", result_rf ) - } - } - -/* Step 6: frequency in alignment rest frame to frequency in result rest - frame. */ - if( step6 ) match = SorConvert( align_result, result, specmap, status ); - -/* Step 7: frequency in result rest frame to result system in result rest - frame. */ - if( step7 ) { - if( result_system != AST__FREQ ) { - -/* If the results system is absolute, we can convert directly. */ - if ( result_system == AST__ENERGY ) { - TRANSFORM_0( "FRTOEN" ) - - } else if ( result_system == AST__WAVENUM ) { - TRANSFORM_0( "FRTOWN" ) - - } else if ( result_system == AST__WAVELEN ) { - TRANSFORM_0( "FRTOWV" ) - - } else if ( result_system == AST__AIRWAVE ) { - TRANSFORM_0( "FRTOAW" ) - -/* If the result system is relative, we first need to convert to apparent - radial velocity from frequency using the rest frequency. Report an error - if the rest frequency is undefined. */ - } else { - VerifyAttrs( result, vmess, "RestFreq", "astMatch", status ); - TRANSFORM_1( "FRTOVL", result_rf ) - -/* Now convert from apparent radial velocity to the required result system. */ - if ( result_system == AST__VRADIO ) { - TRANSFORM_0( "VLTOVR" ) - - } else if ( result_system == AST__VOPTICAL ) { - TRANSFORM_0( "VLTOVO" ) - - } else if ( result_system == AST__REDSHIFT ) { - TRANSFORM_0( "VLTOZO" ) - - } else if ( result_system == AST__BETA ) { - TRANSFORM_0( "VLTOBT" ) - } - } - } - } - -/* The SpecMap created above class assumes that the axis values supplied to - its Transform method are in units which correspond to the default units - for its class (the returned values also use these units). However, - the Unit attributes of the supplied Frames may have been set to some - non-default value, and so we need to add Mappings before and after the - SpecMap which convert to and from the default units. Find the Mapping - from the target Frame Units to the default Units for the target's system. */ - utarg = astGetUnit( target, 0 ); - umap1 = astUnitMapper( utarg, SpecMapUnit( target_system, "MakeSpecMap", - "SpecFrame", status ), NULL, NULL ); - -/* Find the Mapping from the default Units for the result's system to the - Units of the result Frame. */ - ures = astGetUnit( result, 0 ); - umap2 = astUnitMapper( SpecMapUnit( result_system, "MakeSpecMap", - "SpecFrame", status ), ures, NULL, NULL ); - -/* If both units Mappings were created OK, sandwich the SpecMap between - them. */ - if( umap1 && umap2 ) { - map1 = (AstMapping *) astCmpMap( umap1, specmap, 1, "", status ); - map2 = (AstMapping *) astCmpMap( map1, umap2, 1, "", status ); - map1 = astAnnul( map1 ); - -/* If the simplified SpecMap is a UnitMap, and the target and result - units are the same, we do not need to know the mapping between units. - Otherwise, report an error and indicate that we cannot convert between - the Frames. */ - } else { - map2 = astSimplify( specmap ); - if( !astIsAUnitMap( map2 ) || strcmp( ures, utarg ) ) { - match = 0; - if( astOK && report ) { - if( !umap1 ) { - uerr = utarg; - serr = astGetSystem( target ); - } else { - uerr = ures; - serr = astGetSystem( result ); - } - astError( AST__BADUN, "astMatch(SpecFrame): Inappropriate units (%s) " - "specified for a %s axis.", status, uerr, SystemLabel( serr, status ) ); - } - } - } - -/* Step 0: offset to absolute value in target system. Prepend the Maping created - above with a ShiftMap that does the required shift of origin. */ - target_origin = GetSpecOriginCur( target, status ); - if( target_origin != 0.0 ) { - sm = astShiftMap( 1, &target_origin, "", status ); - map1 = (AstMapping *) astCmpMap( sm, map2, 1, "", status ); - sm = astAnnul( sm ); - } else { - map1 = astClone( map2 ); - } - map2 = astAnnul( map2 ); - -/* Step 9: absolute value to offset in result system. If we are aligning in the - offset system, use the transformed target origin as the new zero point. - Otherwise use the origin from the result frame. First get the origin for the - result system. */ - if( astGetAlignSpecOffset( target ) && astGetAlignSpecOffset( result ) ) { - result_origin = 0.0; - astTran1( map1, 1, &result_origin, 1, &result_origin ); - } else { - result_origin = GetSpecOriginCur( result, status ); - } - -/* Now create the ShiftMap and apend it to the end of the Maping. */ - if( result_origin != 0.0 ) { - result_origin = -result_origin; - sm = astShiftMap( 1, &result_origin, "", status ); - map2 = (AstMapping *) astCmpMap( map1, sm, 1, "", status ); - sm = astAnnul( sm ); - } else { - map2 = astClone( map1 ); - } - map1 = astAnnul( map1 ); - -/* Return the simplified Mapping. */ - *map = astSimplify( map2 ); - -/* Annul remaining resources. */ - map2 = astAnnul( map2 ); - specmap = astAnnul( specmap ); - if( umap1 ) umap1 = astAnnul( umap1 ); - if( umap2 ) umap2 = astAnnul( umap2 ); - align_result = astAnnul( align_result ); - align_target = astAnnul( align_target ); - -/* If an error occurred, annul the returned Mapping and clear the returned - values. */ - if ( !astOK ) { - *map = astAnnul( *map ); - match = 0; - } - -/* Return the result. */ - return match; - -/* Undefine macros local to this function. */ -#undef MAX_ARGS -#undef TRANSFORM_0 -#undef TRANSFORM_1 -} - -static int Match( AstFrame *template_frame, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* Match - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the protected astMatch method -* inherited from the Frame class). - -* Description: -* This function matches a "template" SpecFrame to a "target" Frame and -* determines whether it is possible to convert coordinates between them. -* If it is, a mapping that performs the transformation is returned along -* with a new Frame that describes the coordinate system that results when -* this mapping is applied to the "target" coordinate system. In addition, -* information is returned to allow the axes in this "result" Frame to be -* associated with the corresponding axes in the "target" and "template" -* Frames from which they are derived. - -* Parameters: -* template -* Pointer to the template SpecFrame. This describes the coordinate -* system (or set of possible coordinate systems) into which we wish to -* convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate system in -* which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case. -* template_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the template SpecFrame axis from -* which it is derived. If it is not derived from any template -* SpecFrame axis, a value of -1 will be returned instead. -* target_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the target Frame axis from which it -* is derived. If it is not derived from any target Frame axis, a value -* of -1 will be returned instead. -* map -* Address of a location where a pointer to a new Mapping will be -* returned if the requested coordinate conversion is possible. If -* returned, the forward transformation of this Mapping may be used to -* convert coordinates between the "target" Frame and the "result" -* Frame (see below) and the inverse transformation will convert in the -* opposite direction. -* result -* Address of a location where a pointer to a new Frame will be returned -* if the requested coordinate conversion is possible. If returned, this -* Frame describes the coordinate system that results from applying the -* returned Mapping (above) to the "target" coordinate system. In -* general, this Frame will combine attributes from (and will therefore -* be more specific than) both the target and the template Frames. In -* particular, when the template allows the possibility of transformaing -* to any one of a set of alternative coordinate systems, the "result" -* Frame will indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate conversion is -* possible. Otherwise zero is returned (this will not in itself result in -* an error condition). - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* This implementation addresses the matching of a SpecFrame class -* object to any other class of Frame. A SpecFrame will match any class -* of SpecFrame (i.e. possibly from a derived class) but will not match -* a less specialised class of Frame. -*/ - -/* Local Variables: */ - AstFrame *frame0; /* Pointer to Frame underlying axis 0 */ - AstSpecFrame *template; /* Pointer to template SpecFrame structure */ - int iaxis0; /* Axis index underlying axis 0 */ - int iaxis; /* Axis index */ - int match; /* Coordinate conversion possible? */ - int target_axis0; /* Index of SpecFrame axis in the target */ - int target_naxes; /* Number of target axes */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the template SpecFrame structure. */ - template = (AstSpecFrame *) template_frame; - -/* Obtain the number of axes in the target Frame. */ - target_naxes = astGetNaxes( target ); - -/* The first criterion for a match is that the template matches as a - Frame class object. This ensures that the number of axes (1) and - domain, etc. of the target Frame are suitable. Invoke the parent - "astMatch" method to verify this. */ - match = (*parent_match)( template_frame, target, matchsub, - template_axes, target_axes, map, result, status ); - -/* If a match was found, annul the returned objects, which are not - needed, but keep the memory allocated for the axis association - arrays, which we will re-use. */ - if ( astOK && match ) { - *map = astAnnul( *map ); - *result = astAnnul( *result ); - } - -/* If OK so far, obtain pointers to the primary Frames which underlie - all target axes. Stop when a SpecFrame axis is found. */ - if ( match && astOK ) { - match = 0; - for( iaxis = 0; iaxis < target_naxes; iaxis++ ) { - astPrimaryFrame( target, iaxis, &frame0, &iaxis0 ); - if( astIsASpecFrame( frame0 ) ) { - frame0 = astAnnul( frame0 ); - target_axis0 = iaxis; - match = 1; - break; - } else { - frame0 = astAnnul( frame0 ); - } - } - - } - -/* Check at least one SpecFrame axis was found it the target. Store the - axis associataions. */ - if( match && astOK ) { - (*template_axes)[ 0 ] = 0; - (*target_axes)[ 0 ] = target_axis0; - -/* Use the target's "astSubFrame" method to create a new Frame (the - result Frame) with copies of the target axes in the required - order. This process also overlays the template attributes on to the - target Frame and returns a Mapping between the target and result - Frames which effects the required coordinate conversion. */ - match = astSubFrame( target, template, 1, *target_axes, *template_axes, - map, result ); - - } - -/* If an error occurred, or conversion to the result Frame's - coordinate system was not possible, then free all memory, annul the - returned objects, and reset the returned value. */ - if ( !astOK || !match ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - - -/* Return the result. */ - return match; -} - -static void OriginStdOfRest( AstSpecFrame *this, AstStdOfRestType newsor, - const char *method, int *status ){ -/* -* Name: -* OriginStdOfRest - -* Purpose: -* Convert the SpecOrigin in a SpecFrame to a new rest frame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void OriginStdOfRest( AstSpecFrame *this, AstStdOfRestType newsor, -* const char *method, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function converts the value of the SpecOrigin attribute stored -* within a supplied SpecFrame from the rest frame currently associated -* with the SpecFrame, to the new rest frame indicated by "newsor". - -* Parameters: -* this -* Point to the SpecFrame. On entry, the SpecOrigin value is -* assumed to refer to the re st frame given by the astGetStdOfRest -* method. On exit, the SpecOrigin value refers to the rest frame -* supplied in "newsor". The StdOfRest attribute of the SpecFrame -* should then be modified in order to keep things consistent. -* newsor -* The rest frame to which the SpecOrigin value stored within "this" -* should refer on exit. -* method -* Pointer to a string holding the name of the method to be -* included in any error messages. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Local Variables: */ - AstSpecFrame *sf; - AstFrameSet *fs; - double origin; - double neworigin; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do nothing if the SpecOrigin attribute has not been assigned a value. */ - if( astTestSpecOrigin( this ) ) { - -/* Do nothing if the rest frame will not change. */ - if( newsor != astGetStdOfRest( this ) ) { - -/* Save the original SpecOrigin value (in the current SpecFrame units) and then - clear it. */ - origin = GetSpecOriginCur( this, status ); - astClearSpecOrigin( this ); - -/* Take a copy of the SpecFrame and set the new StdOfRest. */ - sf = astCopy( this ); - astSetStdOfRest( sf, newsor ); - -/* Create a Mapping to perform the rest frame change, then use it to convert - the value to the new rest frame. */ - fs = astConvert( this, sf, "" ); - neworigin = AST__BAD; - if( fs ) { - astTran1( fs, 1, &origin, 1, &neworigin ); - fs = astAnnul( fs ); - } - -/* If succesful, convert from the current units to the default units, and store - in "this". */ - if( neworigin != AST__BAD ) { - astSetSpecOrigin( this, ToUnits( this, astGetUnit( this, 0 ), neworigin, - method, status ) ); - - } else if( astOK ) { - astError( AST__ATSER, "%s(%s): Cannot convert the SpecOrigin " - "value to a different rest frame.", status, method, - astGetClass( this ) ); - } - } - } -} - -static void OriginSystem( AstSpecFrame *this, AstSystemType oldsys, - const char *method, int *status ){ -/* -* Name: -* OriginSystem - -* Purpose: -* Convert the SpecOrigin in a SpecFrame to a new System. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void OriginSystem( AstSpecFrame *this, AstSystemType oldsys, -* const char *method, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function converts the value of the SpecOrigin attribute stored -* within a supplied SpecFrame from its original System, etc, to the -* System, etc, currently associated with the SpecFrame. - -* Parameters: -* this -* Point to the SpecFrame. On entry, the SpecOrigin value is -* assumed to refer to the System given by "oldsys", etc. On exit, the -* SpecOrigin value refers to the System returned by the astGetSystem -* method, etc. -* oldsys -* The System to which the SpecOrigin value stored within "this" -* refers on entry. -* method -* A string containing the method name for error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstSpecFrame *sf1; - AstSpecFrame *sf2; - AstFrameSet *fs; - double origin; - double neworigin; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do nothing if the SpecOrigin attribute has not been assigned a value. */ - if( astTestSpecOrigin( this ) ) { - -/* Do nothing if the System will not change. */ - if( oldsys != astGetSystem( this ) ) { - -/* Note the original SpecOrigin value, in the SpecFrame's default units. */ - origin = astGetSpecOrigin( this ); - -/* Take a copy of the original SpecFrame and ensure the Units, SpecOrigin and - AlignSpecOffset attributes are cleared. */ - sf1 = astCopy( this ); - astClearUnit( sf1, 0 ); - astClearSpecOrigin( sf1 ); - astClearAlignSpecOffset( sf1 ); - -/* Take another copy of the SpecFrame and set the old system. */ - sf2 = astCopy( sf1 ); - astSetSystem( sf2, oldsys ); - -/* Create a Mapping to perform the rest frame change, then use it to convert - the value to the current system. */ - fs = astConvert( sf2, sf1, "" ); - neworigin = AST__BAD; - if( fs ) { - astTran1( fs, 1, &origin, 1, &neworigin ); - fs = astAnnul( fs ); - } - -/* Free resources */ - sf1 = astAnnul( sf1 ); - sf2 = astAnnul( sf2 ); - -/* If succesful, store it in "this". */ - if( neworigin != AST__BAD ) { - astSetSpecOrigin( this, neworigin ); - - } else if( astOK ) { - astError( AST__ATSER, "%s(%s): Cannot convert the SpecOrigin " - "value to a different spectral system.", status, method, - astGetClass( this ) ); - } - } - } -} - - -static void Overlay( AstFrame *template, const int *template_axes, - AstFrame *result, int *status ) { -/* -* Name: -* Overlay - -* Purpose: -* Overlay the attributes of a template SpecFrame on to another Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void Overlay( AstFrame *template, const int *template_axes, -* AstFrame *result, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the protected astOverlay method -* inherited from the Frame class). - -* Description: -* This function overlays attributes of a SpecFrame (the "template") on to -* another Frame, so as to over-ride selected attributes of that second -* Frame. Normally only those attributes which have been specifically set -* in the template will be transferred. This implements a form of -* defaulting, in which a Frame acquires attributes from the template, but -* retains its original attributes (as the default) if new values have not -* previously been explicitly set in the template. -* -* Note that if the result Frame is a SpecFrame and a change of spectral -* coordinate system occurs as a result of overlaying its System -* attribute, then some of its original attribute values may no -* longer be appropriate (e.g. the Title, or attributes describing -* its axes). In this case, these will be cleared before overlaying -* any new values. - -* Parameters: -* template -* Pointer to the template SpecFrame, for which values should have been -* explicitly set for any attribute which is to be transferred. -* template_axes -* Pointer to an array of int, with one element for each axis of the -* "result" Frame (see below). For each axis in the result frame, the -* corresponding element of this array should contain the (zero-based) -* index of the template axis to which it corresponds. This array is used -* to establish from which template axis any axis-dependent attributes -* should be obtained. -* -* If any axis in the result Frame is not associated with a template -* axis, the corresponding element of this array should be set to -1. -* -* If a NULL pointer is supplied, the template and result axis -* indices are assumed to be identical. -* result -* Pointer to the Frame which is to receive the new attribute values. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - In general, if the result Frame is not from the same class as the -* template SpecFrame, or from a class derived from it, then attributes may -* exist in the template SpecFrame which do not exist in the result Frame. -* In this case, these attributes will not be transferred. -*/ - -/* Local Variables: */ - AstFrame *templt; /* Copy of supplied template Frame */ - AstSystemType new_system; /* Code identifying new cordinates */ - AstSystemType old_system; /* Code identifying old coordinates */ - const char *method; /* Pointer to method string */ - const char *new_class; /* Pointer to template class string */ - const char *old_class; /* Pointer to result class string */ - int specframe; /* Result Frame is a SpecFrame? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise strings used in error messages. */ - new_class = astGetClass( template ); - old_class = astGetClass( result ); - method = "astOverlay"; - -/* Get the old and new systems. */ - old_system = astGetSystem( result ); - new_system = astGetSystem( template ); - -/* It may be necessary to make temporary changes to the template Frame - below. In order to ensure that we make no permanent changes to the - supplied frame, we will, if necessary, take a deep copy of the - supplied Frame, storing a pointer to the copy in "templt". If it is - not necessary to make any changes to the template, we still want - "templt" to hold a usable pointer, so we initialise it now to hold a - clone of the supplied pointer. This pointer will be replaced by a - pointer to a deep copy (if required) below. */ - templt = astClone( template ); - -/* If the result Frame is a SpecFrame, we must test to see if overlaying its - System attribute will change the type of coordinate system it describes. - Determine the value of this attribute for the result and template - SpecFrames. */ - specframe = astIsASpecFrame( result ); - if( specframe ) { - -/* If the coordinate system will change, any value already set for the result - SpecFrame's Title will no longer be appropriate, so clear it. */ - if ( new_system != old_system ) { - astClearTitle( result ); - -/* If the systems have the same default units, we can retain the current - Unit value. */ - if( strcmp( DefUnit( new_system, method, new_class, status ), - DefUnit( old_system, method, old_class, status ) ) ) { - astClearUnit( result, 0 ); - } - -/* If necessary, clear inappropriate values for all those axis attributes - whose access functions are over-ridden by this class (these access functions - will then provide suitable defaults appropriate to the new coordinate system - instead). */ - astClearLabel( result, 0 ); - astClearSymbol( result, 0 ); - } - -/* If the result Frame is not a SpecFrame, we must temporarily clear the - System and AlignSystem values since the values used by this class - are only appropriate to this class. Use a deep copy to avoid the danger - of making any permanent changes to the suppied Frame. */ - } else { - if( astTestSystem( template ) ) { - templt = astAnnul( templt ); - templt = astCopy( template ); - astClearSystem( templt ); - astClearAlignSystem( templt ); - } - } - -/* Invoke the parent class astOverlay method to transfer attributes inherited - from the parent class. */ - (*parent_overlay)( templt, template_axes, result, status ); - -/* Check if the result Frame is a SpecFrame or from a class derived from - SpecFrame. If not, we cannot transfer SpecFrame attributes to it as it is - insufficiently specialised. In this case simply omit these attributes. */ - if ( specframe && astOK ) { - -/* Define macros that test whether an attribute is set in the template and, - if so, transfers its value to the result. */ -#define OVERLAY(attribute) \ - if ( astTest##attribute( template ) ) { \ - astSet##attribute( result, astGet##attribute( template ) ); \ - } - -/* Use the macro to transfer each SpecFrame attribute in turn. Note, - SourceVRF must be overlayed before SourceVel. Otherwise the stored value - for SourceVel would be changed from the default SourceVRF to the specified - SourceVRF when SourceVRF was overlayed. */ - OVERLAY(AlignStdOfRest) - OVERLAY(AlignSpecOffset); - OVERLAY(RefDec) - OVERLAY(RefRA) - OVERLAY(RestFreq) - OVERLAY(SourceSys) - OVERLAY(SourceVRF) - OVERLAY(SourceVel) - OVERLAY(StdOfRest) - OVERLAY(SpecOrigin) - } - -/* Free resources */ - templt = astAnnul( templt ); - -/* Undefine macros local to this function. */ -#undef OVERLAY -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* SpecFrame member function (extends the astSetAttrib method inherited from -* the Mapping class). - -* Description: -* This function assigns an attribute value for a SpecFrame, the attribute -* and its value being specified by means of a string of the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in lower -* case with no white space present. The value to the right of the "=" -* should be a suitable textual representation of the value to be assigned -* and this will be interpreted according to the attribute's data type. -* White space surrounding the value is only significant for string -* attributes. - -* Parameters: -* this -* Pointer to the SpecFrame. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This protected method is intended to be invoked by the Object astSet -* method and makes additional attributes accessible to it. -*/ - -/* Local Vaiables: */ - AstMapping *umap; /* Mapping between units */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - AstStdOfRestType sor; /* Standard of rest type code */ - AstSystemType sys; /* Spectral system type code */ - char *a; /* Pointer to next character */ - char *new_setting; /* Pointer value to new attribute setting */ - double dval; /* Double atribute value */ - double dtemp; /* Temporary double atribute value */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int ulen; /* Used length of setting string */ - int namelen; /* Length of attribute name in setting */ - int nc; /* Number of characters read by astSscanf */ - int off; /* Offset of attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Create an FK5 J2000 SkyFrame which will be used for formatting and - unformatting sky positions, etc. */ - LOCK_MUTEX2 - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000", status ); - astEndPM; - } - UNLOCK_MUTEX2 - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Obtain the used length of the setting string. */ - ulen = astChrLen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* First look for axis attributes defined by the Frame class. Since a - SpecFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strncmp( setting, "direction=", 10 ) || - !strncmp( setting, "bottom=", 7 ) || - !strncmp( setting, "top=", 4 ) || - !strncmp( setting, "format=", 7 ) || - !strncmp( setting, "label=", 6 ) || - !strncmp( setting, "symbol=", 7 ) || - !strncmp( setting, "unit=", 5 ) ) { - -/* Create a new setting string from the original by appending the string - "(1)" to the end of the attribute name and then use the parent SetAttrib - method. */ - new_setting = astMalloc( len + 4 ); - if( new_setting ) { - memcpy( new_setting, setting, len + 1 ); - a = strchr( new_setting, '=' ); - namelen = a - new_setting; - memcpy( a, "(1)", 4 ); - a += 3; - strcpy( a, setting + namelen ); - (*parent_setattrib)( this_object, new_setting, status ); - new_setting = astFree( new_setting ); - } - -/* AlignStdOfRest. */ -/* --------------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "alignstdofrest=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a StdOfRest code before use. */ - sor = StdOfRestCode( setting + off, status ); - if ( sor != AST__BADSOR ) { - astSetAlignStdOfRest( this, sor ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid standard of rest " - "description \"%s\".", status, astGetClass( this ), setting+off ); - } - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - SpecFrame had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "geolat=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - new_setting = astStore( NULL, setting, len + 1 ); - new_setting[ 0 ] = 'o'; - new_setting[ 1 ] = 'b'; - new_setting[ 2 ] = 's'; - astSetAttrib( this, new_setting ); - new_setting = astFree( new_setting ); - -/* GeoLon. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "geolon=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - new_setting = astStore( NULL, setting, len + 1 ); - new_setting[ 0 ] = 'o'; - new_setting[ 1 ] = 'b'; - new_setting[ 2 ] = 's'; - astSetAttrib( this, new_setting ); - new_setting = astFree( new_setting ); - -/* RefDec. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "refdec=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - -/* Convert the string to a radians value before use. */ - ival = astUnformat( skyframe, 1, setting + off, &dval ); - if ( ival == ulen - off ) { - astSetRefDec( this, dval ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid reference " - "declination \"%s\".", status, astGetClass( this ), setting + off ); - } - -/* RefRA. */ -/* ------ */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "refra=%n%*s %n", &off, &nc ) ) - && ( nc >= 6 ) ) { - -/* Convert the string to a radians value before use. */ - ival = astUnformat( skyframe, 0, setting + off, &dval ); - if ( ival == ulen - off ) { - astSetRefRA( this, dval ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid reference right " - "ascension \"%s\".", status, astGetClass( this ), setting + off ); - } - -/* AlignSpecOffset. */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "alignspecoffset= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetAlignSpecOffset( this, ival ); - -/* RestFreq. */ -/* --------- */ -/* Without any units indication - assume GHz. Convert to Hz for storage. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "restfreq= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetRestFreq( this, dval*1.0E9 ); - -/* With units indication. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "restfreq= %lg %n%*s %n", &dval, &off, &nc ) ) - && ( nc >= len ) ) { - dtemp = AST__BAD; - -/* Is there a Mapping from the supplied units to Hz? If so, use the - Mapping to convert the supplied value to Hz. */ - if( ( umap = astUnitMapper( setting + off, "Hz", NULL, NULL ) ) ) { - astTran1( umap, 1, &dval, 1, &dtemp ); - umap = astAnnul( umap ); - -/* Otherwise, if there is a Mapping from the supplied units to metre, - assume the supplied unit is a vacuum wavelength. */ - } else if( ( umap = astUnitMapper( setting + off, "m", NULL, NULL ) ) ) { - -/* Convert the supplied wavelength to metres. */ - astTran1( umap, 1, &dval, 1, &dtemp ); - umap = astAnnul( umap ); - -/* Convert the wavelength (m) to frequency (Hz). */ - if( dtemp != AST__BAD && dtemp != 0.0 ) { - dtemp = AST__C/dtemp; - } else if( astOK ) { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid rest wavelength " - "\"%g %s\" supplied.", status, astGetClass( this ), dval, setting + off ); - } - -/* Otherwise, if there is a Mapping from the supplied units to Joule, - assume the supplied unit is an energy. */ - } else if( ( umap = astUnitMapper( setting + off, "J", NULL, NULL ) ) ) { - -/* Convert the supplied energy to Joules. */ - astTran1( umap, 1, &dval, 1, &dtemp ); - umap = astAnnul( umap ); - -/* Convert the energy (J) to frequency (Hz). */ - if( dtemp != AST__BAD ) { - dtemp *= 1.0/AST__H; - } else if( astOK ) { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid rest energy " - "\"%g %s\" supplied.", status, astGetClass( this ), dval, setting + off ); - } - -/* Otherwise report an error. */ - } else if( astOK ) { - astError( AST__ATTIN, "astSetAttrib(%s): Rest frequency given in an " - "unsupported system of units \"%g %s\".", status, - astGetClass( this ), dval, setting + off ); - } - -/* Set the rest frequency. */ - astSetRestFreq( this, dtemp ); - -/* SourceVel. */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "sourcevel= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - -/* Convert from km/s to m/s if the SourceVel value is a velocity. */ - if( astGetSourceSys( this ) == AST__VREL || - astGetSourceSys( this ) == AST__VRADIO || - astGetSourceSys( this ) == AST__VOPTICAL ) dval *= 1.0E3; - -/* Store the value */ - astSetSourceVel( this, dval ); - -/* SourceVRF */ -/* --------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "sourcevrf=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a StdOfRest code before use. */ - sor = StdOfRestCode( setting + off, status ); - if ( sor != AST__BADSOR ) { - astSetSourceVRF( this, sor ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid standard of rest " - "description \"%s\".", status, astGetClass( this ), setting+off ); - } - -/* SourceSys */ -/* --------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "sourcesys=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a System code before use. */ - sys = SystemCode( (AstFrame *) this, setting + off, status ); - astSetSourceSys( this, sys ); - -/* StdOfRest. */ -/* ---------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "stdofrest=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a StdOfRest code before use. */ - sor = StdOfRestCode( setting + off, status ); - if ( sor != AST__BADSOR ) { - astSetStdOfRest( this, sor ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid standard of rest " - "description \"%s\".", status, astGetClass( this ), setting + off ); - } - -/* SpecOrigin */ -/* ---------- */ - -/* Floating-point without any units indication - assume the current Unit - value. Convert from current units to default units for current system. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "specorigin= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - - astSetSpecOrigin( this, ToUnits( this, astGetUnit( this, 0 ), dval, - "astSetSpecOrigin", status ) ); - -/* Floating-point with units. Convert the supplied value to the default units - for the SpecFrame's System. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "specorigin= %lg %n%*s %n", &dval, &off, &nc ) ) - && ( nc >= len ) ) { - astSetSpecOrigin( this, ToUnits( this, setting + off, dval, "astSetSpecOrigin", status ) ); - -/* Pass any unrecognised setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetRefPos( AstSpecFrame *this, AstSkyFrame *frm, double lon, - double lat, int *status ){ -/* -*++ -* Name: -c astSetRefPos -f AST_SETREFPOS - -* Purpose: -* Set the reference position in a specified celestial coordinate system. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "specframe.h" -c void astSetRefPos( AstSpecFrame *this, AstSkyFrame *frm, double lon, -c double lat ) -f CALL AST_SETREFPOS( THIS, FRM, LON, LAT, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* sets the reference position (see attributes RefRA and RefDec) using -* axis values (in radians) supplied within the celestial coordinate -* system represented by a supplied SkyFrame. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the SpecFrame. -c frm -f FRM = INTEGER (Given) -* Pointer to the SkyFrame which defines the celestial coordinate -* system in which the longitude and latitude values are supplied. -c If NULL -f If AST__NULL -* is supplied, then the supplied longitude and latitude values are -* assumed to be FK5 J2000 RA and Dec values. -c lon -f LON = DOUBLE PRECISION (Given) -* The longitude of the reference point, in the coordinate system -* represented by the supplied SkyFrame (radians). -c lat -f LAT = DOUBLE PRECISION (Given) -* The latitude of the reference point, in the coordinate system -* represented by the supplied SkyFrame (radians). -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - AstFrameSet *fs; /* Conversion FrameSet */ - AstFrame *fb; /* Base Frame */ - AstFrame *fc; /* Current Frame */ - double xin[ 1 ]; /* Axis 1 values */ - double yin[ 1 ]; /* Axis 2 values */ - double xout[ 1 ]; /* Axis 1 values */ - double yout[ 1 ]; /* Axis 2 values */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If no SkyFrame was supplied, just store the supplied RefRA and RefDec - values. */ - if( !frm ) { - astSetRefRA( this, lon ); - astSetRefDec( this, lat ); - -/* Otherwise, convert the supplied values from the requested system. */ - } else { - -/* Create an FK5 J2000 SkyFrame which will be used for formatting and - unformatting sky positions, etc. */ - LOCK_MUTEX2 - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000", status ); - astEndPM; - } - UNLOCK_MUTEX2 - -/* Find the Mapping from the supplied SkyFrame, to the SkyFrame which - describes the internal format in which the RefRA and RefDec attribute - values are stored. */ - fs = astFindFrame( frm, skyframe, "" ); - -/* If alignment was possible, use the Mapping to transform the supplied - axis values, checking to see if the axes of the supplied SkyFrame have - been permuted. */ - if( fs ) { - -/* Find the longitude axis in the Base Frame, and store the supplied - longitude and latitude values. */ - fb = astGetFrame( fs, AST__BASE ); - if( astGetLonAxis( fb ) == 0 ) { - xin[ 0 ] = lon; - yin[ 0 ] = lat; - } else { - xin[ 0 ] = lat; - yin[ 0 ] = lon; - } - astTran2( fs, 1, xin, yin, 1, xout, yout ); - -/* Store the corresponding RefRA and RefDec values. */ - fc = astGetFrame( fs, AST__CURRENT ); - if( astGetLonAxis( fc ) == 0 ) { - astSetRefRA( this, xout[ 0 ] ); - astSetRefDec( this, yout[ 0 ] ); - } else { - astSetRefRA( this, yout[ 0 ] ); - astSetRefDec( this, xout[ 0 ] ); - } - -/* Annul object references. */ - fc = astAnnul( fc ); - fb = astAnnul( fb ); - fs = astAnnul( fs ); - } - } -} - -static void SetStdOfRest( AstSpecFrame *this, AstStdOfRestType value, int *status ) { -/* -*+ -* Name: -* astSetStdOfRest - -* Purpose: -* Set the StdOfRest attribute for a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* void astSetStdOfRest( AstSpecFrame *this, AstStdOfRestType value ) - -* Class Membership: -* SpecFrame virtual function - -* Description: -* This function set a new value for the StdOfRest attribute for a -* SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* value -* The new value. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - - -/* Validate the StdOfRest value being set and report an error if necessary. */ - if( value < FIRST_SOR || value > LAST_SOR ) { - astError( AST__ATTIN, "%s(%s): Bad value (%d) given for StdOfRest attribute.", status, - "astSetStdOfRest", astGetClass( this ), (int) value ); - -/* Otherwise set the new StdOfRest */ - } else { - -/* Modify the SpecOrigin value stored in the SpecFrame structure to refer - to the new rest frame. */ - OriginStdOfRest( this, value, "astSetStdOfRest", status ); - -/* Store the new value for the rest frame in the SpecFrame structure. */ - this->stdofrest = value; - - } -} - -static void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status ) { -/* -* Name: -* SetSystem - -* Purpose: -* Set the System attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astSetSystem protected -* method inherited from the Frame class). - -* Description: -* This function sets the System attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* newsys -* The new System value to be stored. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstSystemType oldsys; /* Original System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Save the original System value */ - oldsys = astGetSystem( this_frame ); - -/* Use the parent SetSystem method to store the new System value. */ - (*parent_setsystem)( this_frame, newsys, status ); - -/* If the system has changed... */ - if( oldsys != newsys ) { - -/* Changing the System value will in general require the Units to change - as well. If the user has previously specified the units to be used with - the new system, then re-instate them (they are stored in the "usedunits" - array in the SpecFrame structure). Otherwise, clear the units so that - the default units will eb used with the new System. */ - if( (int) newsys < this->nuunits && this->usedunits && - this->usedunits[ (int) newsys ] ) { - astSetUnit( this, 0, this->usedunits[ (int) newsys ] ); - } else { - astClearUnit( this, 0 ); - } - -/* Modify the stored SpecOrigin. */ - OriginSystem( this, oldsys, "astSetSystem", status ); - -/* Also, clear all attributes which have system-specific defaults. */ - astClearLabel( this_frame, 0 ); - astClearSymbol( this_frame, 0 ); - astClearTitle( this_frame ); - } -} - -static void SetUnit( AstFrame *this_frame, int axis, const char *value, int *status ) { -/* -* Name: -* SetUnit - -* Purpose: -* Set a pointer to the Unit string for a SpecFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void SetUnit( AstFrame *this_frame, int axis, const char *value ) - -* Class Membership: -* SpecFrame member function (over-rides the astSetUnit method inherited -* from the Frame class). - -* Description: -* This function stores a pointer to the Unit string for a specified axis -* of a SpecFrame. It also stores the string in the "usedunits" array -* in the SpecFrame structure, in the element associated with the -* current System. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* The number of the axis (zero-based) for which information is required. -* unit -* The new string to store. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - int i; /* Loop counter */ - int system; /* The SpecFrame's System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astSetUnit" ); - -/* Store the supplied value as the UsedUnit for the current System. First - ensure the array is big enough. Free any previous value stored for the - current system. */ - system = (int) astGetSystem( this ); - if( system >= this->nuunits ) { - this->usedunits = astGrow( this->usedunits, system + 1, - sizeof(char *) ); - if( astOK ) { - for( i = this->nuunits; i < system + 1; i++ ) this->usedunits[ i ] = NULL; - this->nuunits = system + 1; - } - } - -/* Now store a copy of the value, if it is different to the stored string. */ - if( astOK && ( !this->usedunits[ system ] || - strcmp( this->usedunits[ system ], value ) ) ) { - this->usedunits[ system ] = astStore( this->usedunits[ system ], - value, strlen( value ) + 1 ); - } - -/* Now use the parent SetUnit method to store the value in the Axis - structure */ - (*parent_setunit)( this_frame, axis, value, status ); - -} - -static int SorConvert( AstSpecFrame *this, AstSpecFrame *that, - AstSpecMap *specmap, int *status ) { -/* -* Name: -* SorConvert - -* Purpose: -* Add a conversion to a SpecMap which transforms between two -* standards of rest. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int SorConvert( AstSpecFrame *this, AstSpecFrame *that, -* AstSpecMap *specmap, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function adds a conversion to a SpecMap which transforms -* frequencies from the standard of rest specified by "this" to -* the standard of rest specified by "that". Note the conversion is -* always between frequency in the two rest frames no matter what the -* System attributes of the two SpecFrames may be (which are ignored). - -* Parameters: -* this -* The SpecFrame which defines the input rest frame. -* that -* The SpecFrame which defines the output rest frame. -* specmap -* The SpecMap to which the conversion is to be added. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the conversion could not be performed. One is -* returned otherwise. - -*/ - -/* Local Constants: */ -#define MAX_ARGS 7 /* Max arguments for an SpecMap conversion */ - -/* Local Variables: */ - AstStdOfRestType from; /* Input standard of rest */ - AstStdOfRestType to; /* Output standard of rest */ - const char *vmess; /* Text for use in error messages */ - double args[ MAX_ARGS ]; /* Conversion argument array */ - double dec; /* DEC of source (radians, FK5 J2000) */ - double epoch; /* Epoch of observation (MJD) */ - double alt; /* Observers geodetic altitude (radians) */ - double lat; /* Observers geodetic latitude (radians) */ - double lon; /* Observers geodetic longitude (radians) */ - double ra; /* RA of source (radians, FK5 J2000) */ - int result; /* Returned value */ - -/* Initialise */ - result = 1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* No conversion is required if the rest frames are equal. */ - if( !EqualSor( this, that, status ) ) { - -/* Define local macros as shorthand for adding spectral coordinate - conversions to the SpecMap. Each macro simply stores details of - the additional arguments in the "args" array and then calls - astSpecAdd. The macros differ in the number of additional argument - values. */ -#define TRANSFORM_2(cvt,arg0,arg1) \ - args[ 0 ] = arg0; \ - args[ 1 ] = arg1; \ - astSpecAdd( specmap, cvt, 2, args ); - -#define TRANSFORM_3(cvt,arg0,arg1,arg2) \ - args[ 0 ] = arg0; \ - args[ 1 ] = arg1; \ - args[ 2 ] = arg2; \ - astSpecAdd( specmap, cvt, 3, args ); - -#define TRANSFORM_6(cvt,arg0,arg1,arg2,arg3,arg4,arg5) \ - args[ 0 ] = arg0; \ - args[ 1 ] = arg1; \ - args[ 2 ] = arg2; \ - args[ 3 ] = arg3; \ - args[ 4 ] = arg4; \ - args[ 5 ] = arg5; \ - astSpecAdd( specmap, cvt, 6, args ); - -/* A string for use in error messages. */ - vmess = "convert between different standards of rest"; - -/* Get the required values from "this". */ - from = astGetStdOfRest( this ); - ra = astGetRefRA( this ); - dec = astGetRefDec( this ); - lon = astGetObsLon( this ); - lat = astGetObsLat( this ); - alt = astGetObsAlt( this ); - epoch = astGetEpoch( this ); - -/* Verify that the reference RA and DEC can be used (they are needed by all - the conversions used below). */ - VerifyAttrs( this, vmess, "RefRA RefDec", "astMatch", status ); - -/* Convert from the "this" rest frame to heliographic. */ - if( from == AST__TPSOR ) { - VerifyAttrs( this, vmess, "ObsLon ObsLat ObsAlt Epoch", "astMatch", status ); - TRANSFORM_6( "TPF2HL", lon, lat, alt, epoch, ra, dec ) - - } else if( from == AST__GESOR ) { - VerifyAttrs( this, vmess, "Epoch", "astMatch", status ); - TRANSFORM_3( "GEF2HL", epoch, ra, dec ) - - } else if( from == AST__BYSOR ) { - VerifyAttrs( this, vmess, "Epoch", "astMatch", status ); - TRANSFORM_3( "BYF2HL", epoch, ra, dec ) - - } else if( from == AST__LKSOR ) { - TRANSFORM_2( "LKF2HL", ra, dec ) - - } else if( from == AST__LDSOR ) { - TRANSFORM_2( "LDF2HL", ra, dec ) - - } else if( from == AST__LGSOR ) { - TRANSFORM_2( "LGF2HL", ra, dec ) - - } else if( from == AST__GLSOR ) { - TRANSFORM_2( "GLF2HL", ra, dec ) - - } else if( from == AST__SCSOR ) { - TRANSFORM_3( "USF2HL", ConvertSourceVel( this, AST__HLSOR, AST__VREL, status ), - ra, dec ) - } - -/* Now go from heliocentric to the "to" frame. */ - to = astGetStdOfRest( that ); - ra = astGetRefRA( that ); - dec = astGetRefDec( that ); - lon = astGetObsLon( that ); - lat = astGetObsLat( that ); - alt = astGetObsAlt( that ); - epoch = astGetEpoch( that ); - VerifyAttrs( that, vmess, "RefRA RefDec", "astMatch", status ); - - if( to == AST__TPSOR ) { - VerifyAttrs( that, vmess, "ObsLon ObsLat ObsAlt Epoch", "astMatch", status ); - TRANSFORM_6( "HLF2TP", lon, lat, alt, epoch, ra, dec ) - - } else if( to == AST__GESOR ) { - VerifyAttrs( that, vmess, "Epoch", "astMatch", status ); - TRANSFORM_3( "HLF2GE", epoch, ra, dec ) - - } else if( to == AST__BYSOR ) { - VerifyAttrs( that, vmess, "Epoch", "astMatch", status ); - TRANSFORM_3( "HLF2BY", epoch, ra, dec ) - - } else if( to == AST__LKSOR ) { - TRANSFORM_2( "HLF2LK", ra, dec ) - - } else if( to == AST__LDSOR ) { - TRANSFORM_2( "HLF2LD", ra, dec ) - - } else if( to == AST__LGSOR ) { - TRANSFORM_2( "HLF2LG", ra, dec ) - - } else if( to == AST__GLSOR ) { - TRANSFORM_2( "HLF2GL", ra, dec ) - - } else if( to == AST__SCSOR ) { - TRANSFORM_3( "HLF2US", ConvertSourceVel( that, AST__HLSOR, AST__VREL, status ), - ra, dec ) - } - } - -/* Return the result. */ - return result; - -/* Undefine macros local to this function. */ -#undef MAX_ARGS -#undef TRANSFORM_2 -#undef TRANSFORM_3 -#undef TRANSFORM_6 -} - -static const char *SpecMapUnit( AstSystemType system, const char *method, - const char *class, int *status ){ -/* -* Name: -* SpecMapUnit - -* Purpose: -* Return the default units for a spectral coordinate system type used -* by the SpecMap class. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *SpecMapUnit( AstSystemType system, const char *method, -* const char *class, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function returns a textual representation of the -* units used by the SpecMap class for the specified spectral -* coordinate system. In general, the SpecMap class uses SI units -* (m/s, Hz, m, etc), but this class (SpecFrame) has default units -* more appropriate to astronomers (km/s, GHz, Angstroms, etc). - -* Parameters: -* system -* The spectral coordinate system. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A string describing the default units. This string follows the -* units syntax described in FITS WCS paper I "Representations of world -* coordinates in FITS" (Greisen & Calabretta). - -* Notes: -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Value to return */ - -/* Initialize */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get an identifier for the default units. */ - if( system == AST__FREQ ) { - result = "Hz"; - } else if( system == AST__ENERGY ) { - result = "J"; - } else if( system == AST__WAVENUM ) { - result = "1/m"; - } else if( system == AST__WAVELEN ) { - result = "m"; - } else if( system == AST__AIRWAVE ) { - result = "m"; - } else if( system == AST__VRADIO ) { - result = "m/s"; - } else if( system == AST__VOPTICAL ) { - result = "m/s"; - } else if( system == AST__REDSHIFT ) { - result = ""; - } else if( system == AST__BETA ) { - result = ""; - } else if( system == AST__VREL ) { - result = "m/s"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "%s(%s): Corrupt %s contains illegal System " - "identification code (%d).", status, method, class, class, - (int) system ); - } - -/* Return the result. */ - return result; -} - -static AstStdOfRestType StdOfRestCode( const char *sor, int *status ) { -/* -* Name: -* StdOfRestCode - -* Purpose: -* Convert a string into a standard of rest type code. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* AstStdOfRestType StdOfRestCode( const char *sor ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function converts a string used for the external description of -* a standard of rest into a SpecFrame standard of rest type code -* (StdOfRest attribute value). It is the inverse of the -* StdOfRestString function. - -* Parameters: -* sor -* Pointer to a constant null-terminated string containing the -* external description of the standard of rest. - -* Returned Value: -* The StdOfRest type code. - -* Notes: -* - A value of AST__BADSOR is returned if the standard of rest -* description was not recognised. This does not produce an error. -* - A value of AST__BADSOR is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstStdOfRestType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADSOR; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "sor" string against each possibility and assign the - result. */ - if ( astChrMatch( "TOPO", sor ) || astChrMatch( "TOPOCENT", sor ) || astChrMatch( "TOPOCENTRIC", sor ) ) { - result = AST__TPSOR; - - } else if ( astChrMatch( "GEO", sor ) || astChrMatch( "GEOCENTR", sor ) || astChrMatch( "GEOCENTRIC", sor ) ) { - result = AST__GESOR; - - } else if ( astChrMatch( "BARY", sor ) || astChrMatch( "BARYCENT", sor ) || astChrMatch( "BARYCENTRIC", sor ) ) { - result = AST__BYSOR; - - } else if ( astChrMatch( "HELIO", sor ) || astChrMatch( "HELIOCEN", sor ) || astChrMatch( "HELIOCENTRIC", sor ) ) { - result = AST__HLSOR; - - } else if ( astChrMatch( "LSRK", sor ) || astChrMatch( "LSR", sor ) ) { - result = AST__LKSOR; - - } else if ( astChrMatch( "LSRD", sor ) ) { - result = AST__LDSOR; - - } else if ( astChrMatch( "GAL", sor ) || astChrMatch( "GALACTOC", sor ) || astChrMatch( "GALACTIC", sor ) ) { - result = AST__GLSOR; - - } else if ( astChrMatch( "LG", sor ) || astChrMatch( "LOCALGRP", sor ) || - astChrMatch( "LOCAL_GROUP", sor ) || astChrMatch( "LOCAL-GROUP", sor ) ) { - result = AST__LGSOR; - - } else if ( astChrMatch( "SOURCE", sor ) || astChrMatch( "SRC", sor ) ) { - result = AST__SCSOR; - - } - -/* Return the result. */ - return result; -} - -static const char *StdOfRestString( AstStdOfRestType sor, int *status ) { -/* -* Name: -* StdOfRestString - -* Purpose: -* Convert a standard of rest type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *StdOfRestString( AstStdOfRestType sor, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function converts a SpecFrame standard of rest type code -* (StdOfRest attribute value) into a string suitable for use as an -* external representation of the standard of rest type. - -* Parameters: -* sor -* The standard of rest type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the standard of rest -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "sor" value against each possibility and convert to a - string pointer. (Where possible, return the same string as would be - used in the FITS WCS representation of the standard of rest). */ - switch ( sor ) { - - case AST__TPSOR: - result = "Topocentric"; - break; - - case AST__GESOR: - result = "Geocentric"; - break; - - case AST__BYSOR: - result = "Barycentric"; - break; - - case AST__HLSOR: - result = "Heliocentric"; - break; - - case AST__LDSOR: - result = "LSRD"; - break; - - case AST__LKSOR: - result = "LSRK"; - break; - - case AST__LGSOR: - result = "Local_group"; - break; - - case AST__GLSOR: - result = "Galactic"; - break; - - case AST__SCSOR: - result = "Source"; - break; - - } - -/* Return the result pointer. */ - return result; -} - -static int SubFrame( AstFrame *target_frame, AstFrame *template, - int result_naxes, const int *target_axes, - const int *template_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* SubFrame - -* Purpose: -* Select axes from a SpecFrame and convert to the new coordinate -* system. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int SubFrame( AstFrame *target, AstFrame *template, -* int result_naxes, const int *target_axes, -* const int *template_axes, AstMapping **map, -* AstFrame **result, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the protected astSubFrame -* method inherited from the Frame class). - -* Description: -* This function selects a requested sub-set (or super-set) of the axes -* from a "target" SpecFrame and creates a new Frame with copies of -* the selected axes assembled in the requested order. It then -* optionally overlays the attributes of a "template" Frame on to the -* result. It returns both the resulting Frame and a Mapping that -* describes how to convert between the coordinate systems described by -* the target and result Frames. If necessary, this Mapping takes -* account of any differences in the Frames' attributes due to the -* influence of the template. - -* Parameters: -* target -* Pointer to the target SpecFrame, from which axes are to be -* selected. -* template -* Pointer to the template Frame, from which new attributes for the -* result Frame are to be obtained. Optionally, this may be NULL, in -* which case no overlaying of template attributes will be performed. -* result_naxes -* Number of axes to be selected from the target Frame. This number may -* be greater than or less than the number of axes in this Frame (or -* equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving a list -* of the (zero-based) axis indices of the axes to be selected from the -* target SpecFrame. The order in which these are given determines -* the order in which the axes appear in the result Frame. If any of the -* values in this array is set to -1, the corresponding result axis will -* not be derived from the target Frame, but will be assigned default -* attributes instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This should -* contain a list of the template axes (given as zero-based axis indices) -* with which the axes of the result Frame are to be associated. This -* array determines which axes are used when overlaying axis-dependent -* attributes of the template on to the result. If any element of this -* array is set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not used and -* a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned Mapping. -* The forward transformation of this Mapping will describe how to -* convert coordinates from the coordinate system described by the target -* SpecFrame to that described by the result Frame. The inverse -* transformation will convert in the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is possible -* between the target and the result Frame. Otherwise zero is returned and -* *map and *result are returned as NULL (but this will not in itself -* result in an error condition). In general, coordinate conversion should -* always be possible if no template Frame is supplied but may not always -* be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* - This implementation addresses the selection of axes from a -* SpecFrame object. This results in another object of the same class -* only if the single SpecFrame axis is selected exactly once. -* Otherwise, the result is a Frame class object which inherits the -* SpecFrame's axis information (if appropriate) but none of the other -* properties of a SpecFrame. -* - In the event that a SpecFrame results, the returned Mapping will -* take proper account of the relationship between the target and result -* coordinate systems. -* - In the event that a Frame class object results, the returned Mapping -* will only represent a selection/permutation of axes. - -* Implementation Deficiencies: -* - Any axis selection is currently permitted. Probably this should be -* restricted so that each axis can only be selected once. The -* astValidateAxisSelection method will do this but currently there are bugs -* in the CmpFrame class that cause axis selections which will not pass this -* test. Install the validation when these are fixed. -*/ - -/* Local Variables: */ - AstSpecFrame *target; /* Pointer to the SpecFrame structure */ - AstSpecFrame *temp; /* Pointer to copy of target SpecFrame */ - AstSpecFrame *align_frm; /* Frame in which to align the SpecFrames */ - int match; /* Coordinate conversion is possible? */ - int report; /* Report errors if SpecFrames cannot be aligned? */ - -/* Initialise the returned values. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the target SpecFrame structure. */ - target = (AstSpecFrame *) target_frame; - -/* Result is a SpecFrame. */ -/* -------------------------- */ -/* Check if the result Frame is to have one axis obtained by selecting - the single target SpecFrame axis. If so, the result will also be - a SpecFrame. */ - if ( ( result_naxes == 1 ) && ( target_axes[ 0 ] == 0 ) ) { - -/* Form the result from a copy of the target. */ - *result = astCopy( target ); - -/* Initialise a flag to indicate that MakeSpecMapping should not report - errors if no Mapping can be created. */ - report = 0; - -/* If required, overlay the template attributes on to the result SpecFrame. - Also get the system and standard of rest in which to align the two - SpecFrames. These are the values from the template (if there is a - template). */ - if ( template ) { - astOverlay( template, template_axes, *result ); - if( astIsASpecFrame( template ) ) { - align_frm = astCopy( template ); - -/* Since we now know that both the template and target are SpecFrames, it - should usually be possible to convert betwen them. If conversion is - *not* possible (fpr instance if no rest frequency is availalbe, etc) - then the user will probably be interested in knowing the reason why - conversion is not possible. Therefore, indicate that MakeSpecMapping - should report errors if no Mapping can be created. */ - report = 1; - - } else { - align_frm = astCopy( target ); - } - -/* If no template was supplied, align in the System and StdOfRest of the - target. */ - } else { - VerifyAttrs( target, "convert between different spectral systems", - "StdOfRest", "astMatch", status ); - align_frm = astCopy( target ); - } - -/* The MakeSpecMapping function uses the System and StdOfRest attributes to - define the alignment frame. But the AlignSystem and AlignStdOfRest - attributes should be used for this purpose. Therefore, copy the values - of the AlignSystem and AlignStdOfRest attributes to the System and - StdOfRest attribute. */ - astSetSystem( align_frm, astGetAlignSystem( align_frm ) ); - astSetStdOfRest( align_frm, astGetAlignStdOfRest( align_frm ) ); - -/* Generate a Mapping that takes account of changes in the sky coordinate - system (equinox, epoch, etc.) between the target SpecFrame and the result - SpecFrame. If this Mapping can be generated, set "match" to indicate that - coordinate conversion is possible. If the template is a specframe, - report errors if a match is not possible. */ - match = ( MakeSpecMapping( target, (AstSpecFrame *) *result, - align_frm, report, map, status ) != 0 ); - -/* Free resources. */ - align_frm = astAnnul( align_frm ); - -/* Result is not a SpecFrame. */ -/* ------------------------------ */ -/* In this case, we select axes as if the target were from the Frame - class. However, since the resulting data will then be separated - from their enclosing SpecFrame, default attribute values may differ - if the methods for obtaining them were over-ridden by the SpecFrame - class. To overcome this, we ensure that these values are explicitly - set for the result Frame (rather than relying on their defaults). */ - } else { - -/* Make a temporary copy of the target SpecFrame. We will explicitly - set the attribute values in this copy so as not to modify the original. */ - temp = astCopy( target ); - -/* Define a macro to test if an attribute is set. If not, set it - explicitly to its default value. */ -#define SET(attribute) \ - if ( !astTest##attribute( temp ) ) { \ - astSet##attribute( temp, astGet##attribute( temp ) ); \ - } - -/* Set attribute values which apply to the Frame as a whole and which - we want to retain, but whose defaults are over-ridden by the - SpecFrame class. */ - SET(Domain) - SET(Title) - -/* Define a macro to test if an attribute is set for axis zero (the only - axis of a SpecFrame). If not, set it explicitly to its default value. */ -#define SET_AXIS(attribute) \ - if ( !astTest##attribute( temp, 0 ) ) { \ - astSet##attribute( temp, 0, \ - astGet##attribute( temp, 0 ) ); \ - } - -/* Use this macro to set explicit values for all the axis attributes - for which the SpecFrame class over-rides the default value. */ - SET_AXIS(Label) - SET_AXIS(Symbol) - SET_AXIS(Unit) - -/* Clear attributes which have an extended range of values allowed by - this class. */ - astClearSystem( temp ); - astClearAlignSystem( temp ); - -/* Invoke the astSubFrame method inherited from the Frame class to - produce the result Frame by selecting the required set of axes and - overlaying the template Frame's attributes. */ - match = (*parent_subframe)( (AstFrame *) temp, template, - result_naxes, target_axes, template_axes, - map, result, status ); - -/* Delete the temporary copy of the target SpecFrame. */ - temp = astDelete( temp ); - } - -/* If an error occurred or no match was found, annul the returned - objects and reset the returned result. */ - if ( !astOK || !match ) { - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; - -/* Undefine macros local to this function. */ -#undef SET -#undef SET_AXIS -} - -static AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) { -/* -* Name: -* SystemCode - -* Purpose: -* Convert a string into a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astSystemCode method -* inherited from the Frame class). - -* Description: -* This function converts a string used for the external -* description of a coordinate system into a SpecFrame -* coordinate system type code (System attribute value). It is the -* inverse of the astSystemString function. - -* Parameters: -* this -* The Frame. -* system -* Pointer to a constant null-terminated string containing the -* external description of the sky coordinate system. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System type code. - -* Notes: -* - A value of AST__BADSYSTEM is returned if the sky coordinate -* system description was not recognised. This does not produce an -* error. -* - A value of AST__BADSYSTEM is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" string against each possibility and assign the - result. */ - if ( astChrMatch( "FREQ", system ) ) { - result = AST__FREQ; - - } else if ( astChrMatch( "ENER", system ) || astChrMatch( "ENERGY", system ) ) { - result = AST__ENERGY; - - } else if ( astChrMatch( "WAVN", system ) || astChrMatch( "WAVENUM", system ) ) { - result = AST__WAVENUM; - - } else if ( astChrMatch( "WAVE", system ) || astChrMatch( "WAVELEN", system ) ) { - result = AST__WAVELEN; - - } else if ( astChrMatch( "AWAV", system ) || astChrMatch( "AIRWAVE", system ) ) { - result = AST__AIRWAVE; - - } else if ( astChrMatch( "VRAD", system ) || astChrMatch( "VRADIO", system ) ) { - result = AST__VRADIO; - - } else if ( astChrMatch( "VOPT", system ) || astChrMatch( "VOPTICAL", system ) ) { - result = AST__VOPTICAL; - - } else if ( astChrMatch( "ZOPT", system ) || astChrMatch( "REDSHIFT", system ) ) { - result = AST__REDSHIFT; - - } else if ( astChrMatch( "BETA", system ) ) { - result = AST__BETA; - - } else if ( astChrMatch( "VELO", system ) || astChrMatch( "VREL", system ) ) { - result = AST__VREL; - - } - -/* Return the result. */ - return result; -} - -static const char *SystemLabel( AstSystemType system, int *status ) { -/* -* Name: -* SystemLabel - -* Purpose: -* Return a label for a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *SystemLabel( AstSystemType system, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function converts a SpecFrame coordinate system type code -* (System attribute value) into a descriptive string for human readers. - -* Parameters: -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the sky coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. */ - switch ( system ) { - - case AST__FREQ: - result = "frequency"; - break; - - case AST__ENERGY: - result = "energy"; - break; - - case AST__WAVENUM: - result = "wave-number"; - break; - - case AST__WAVELEN: - result = "wavelength"; - break; - - case AST__AIRWAVE: - result = "wavelength in air"; - break; - - case AST__VRADIO: - result = "radio velocity"; - break; - - case AST__VOPTICAL: - result = "optical velocity"; - break; - - case AST__REDSHIFT: - result = "redshift"; - break; - - case AST__BETA: - result = "beta factor"; - break; - - case AST__VREL: - result = "apparent radial velocity"; - break; - } - -/* Return the result pointer. */ - return result; -} - -static const char *SystemString( AstFrame *this, AstSystemType system, int *status ) { -/* -* Name: -* SystemString - -* Purpose: -* Convert a coordinate system type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *SystemString( AstFrame *this, AstSystemType system, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astSystemString method -* inherited from the Frame class). - -* Description: -* This function converts a SpecFrame coordinate system type code -* (System attribute value) into a string suitable for use as an -* external representation of the coordinate system type. - -* Parameters: -* this -* The Frame. -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the sky coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. (Where possible, return the same string as would be - used in the FITS WCS representation of the coordinate system). */ - switch ( system ) { - - case AST__FREQ: - result = "FREQ"; - break; - - case AST__ENERGY: - result = "ENER"; - break; - - case AST__WAVENUM: - result = "WAVN"; - break; - - case AST__WAVELEN: - result = "WAVE"; - break; - - case AST__AIRWAVE: - result = "AWAV"; - break; - - case AST__VRADIO: - result = "VRAD"; - break; - - case AST__VOPTICAL: - result = "VOPT"; - break; - - case AST__REDSHIFT: - result = "ZOPT"; - break; - - case AST__BETA: - result = "BETA"; - break; - - case AST__VREL: - result = "VELO"; - break; - } - -/* Return the result pointer. */ - return result; -} - -static int TestActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* TestActiveUnit - -* Purpose: -* Test the ActiveUnit flag for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int TestActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astTestActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function test the value of the ActiveUnit flag for a SpecFrame, -* which is always "unset". - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The result of the test (0). - -*/ - return 0; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astTestAttrib protected -* method inherited from the Frame class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a SpecFrame's attributes. - -* Parameters: -* this -* Pointer to the SpecFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - char *new_attrib; /* Pointer value to new attribute name */ - int len; /* Length of attrib string */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* First look for axis attributes defined by the Frame class. Since a - SpecFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strcmp( attrib, "direction" ) || - !strcmp( attrib, "bottom" ) || - !strcmp( attrib, "top" ) || - !strcmp( attrib, "format" ) || - !strcmp( attrib, "label" ) || - !strcmp( attrib, "symbol" ) || - !strcmp( attrib, "unit" ) ) { - -/* Create a new attribute name from the original by appending the string - "(1)" and then use the parent TestAttrib method. */ - new_attrib = astMalloc( len + 4 ); - if( new_attrib ) { - memcpy( new_attrib, attrib, len ); - memcpy( new_attrib + len, "(1)", 4 ); - result = (*parent_testattrib)( this_object, new_attrib, status ); - new_attrib = astFree( new_attrib ); - } - -/* AlignStdOfRest. */ -/* --------------- */ - } else if ( !strcmp( attrib, "alignstdofrest" ) ) { - result = astTestAlignStdOfRest( this ); - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - SpecFrame had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "geolat" ) ) { - result = astTestAttrib( this, "obslat" ); - -/* GeoLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "geolon" ) ) { - result = astTestAttrib( this, "obslon" ); - -/* RefDec. */ -/* ------- */ - } else if ( !strcmp( attrib, "refdec" ) ) { - result = astTestRefDec( this ); - -/* RefRA. */ -/* ------ */ - } else if ( !strcmp( attrib, "refra" ) ) { - result = astTestRefRA( this ); - -/* RestFreq. */ -/* --------- */ - } else if ( !strcmp( attrib, "restfreq" ) ) { - result = astTestRestFreq( this ); - -/* SourceVel. */ -/* ---------- */ - } else if ( !strcmp( attrib, "sourcevel" ) ) { - result = astTestSourceVel( this ); - -/* SourceVRF */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcevrf" ) ) { - result = astTestSourceVRF( this ); - -/* SourceSys */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcesys" ) ) { - result = astTestSourceSys( this ); - -/* StdOfRest. */ -/* ---------- */ - } else if ( !strcmp( attrib, "stdofrest" ) ) { - result = astTestStdOfRest( this ); - -/* SpecOrigin. */ -/* --------- */ - } else if ( !strcmp( attrib, "specorigin" ) ) { - result = astTestSpecOrigin( this ); - -/* AlignSpecOffset */ -/* --------------- */ - } else if ( !strcmp( attrib, "alignspecoffset" ) ) { - result = astTestAlignSpecOffset( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static double ToUnits( AstSpecFrame *this, const char *oldunit, double oldval, - const char *method, int *status ){ -/* -* -* Name: -* ToUnits - -* Purpose: -* Convert a supplied spectral value to the default units of the supplied -* SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double ToUnits( AstSpecFrame *this, const char *oldunit, double oldval, -* const char *method, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function converts the supplied value from the supplied units to -* the default units associated with the supplied SpecFrame's System. - -* Parameters: -* this -* Pointer to the SpecFrame. -* oldunit -* The units in which "oldval" is supplied. -* oldval -* The value to be converted. -* method -* Pointer to a string holding the name of the method to be -* included in any error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The converted value. - -*/ - -/* Local Variables: */ - AstMapping *map; - const char *defunit; - double result; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get default units associated with the System attribute of the supplied - SpecFrame, and find a Mapping from the old units to the default. */ - defunit = DefUnit( astGetSystem( this ), method, "SpecFrame", status ); - map = astUnitMapper( oldunit, defunit, NULL, NULL ); - if( map ) { - -/* Use the Mapping to convert the supplied value. */ - astTran1( map, 1, &oldval, 1, &result ); - -/* Free resources. */ - map = astAnnul( map ); - -/* Report an error if no conversion is possible. */ - } else if( astOK ){ - astError( AST__BADUN, "%s(%s): Cannot convert the supplied attribute " - "value from units of %s to %s.", status, method, astGetClass( this ), - oldunit, defunit ); - } - -/* Return the result */ - return result; -} - - -static int ValidateSystem( AstFrame *this, AstSystemType system, const char *method, int *status ) { -/* -* -* Name: -* ValidateSystem - -* Purpose: -* Validate a value for a Frame's System attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "specframe.h" -* int ValidateSystem( AstFrame *this, AstSystemType system, -* const char *method, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astValidateSystem method -* inherited from the Frame class). - -* Description: -* This function checks the validity of the supplied system value. -* If the value is valid, it is returned unchanged. Otherwise, an -* error is reported and a value of AST__BADSYSTEM is returned. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The system value to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The validated system value. - -* Notes: -* - A value of AST__BADSYSTEM will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Validated system value */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the value is out of bounds, report an error. */ - if ( system < FIRST_SYSTEM || system > LAST_SYSTEM ) { - astError( AST__AXIIN, "%s(%s): Bad value (%d) given for the System " - "or AlignSystem attribute of a %s.", status, method, - astGetClass( this ), (int) system, astGetClass( this ) ); - -/* Otherwise, return the supplied value. */ - } else { - result = system; - } - -/* Return the result. */ - return result; -} - -static void VerifyAttrs( AstSpecFrame *this, const char *purp, - const char *attrs, const char *method, int *status ) { -/* -* Name: -* VerifyAttrs - -* Purpose: -* Verify that usable attribute values are available. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void VerifyAttrs( AstSpecFrame *this, const char *purp, -* const char *attrs, const char *method, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function tests each attribute listed in "attrs". It returns -* without action if 1) an explicit value has been set for each attribute -* or 2) the UseDefs attribute of the supplied SpecFrame is non-zero. -* -* If UseDefs is zero (indicating that default values should not be -* used for attributes), and any of the named attributes does not have -* an explicitly set value, then an error is reported. - -* Parameters: -* this -* Pointer to the SpecFrame. -* purp -* Pointer to a text string containing a message which will be -* included in any error report. This shouldindicate the purpose -* for which the attribute value is required. -* attrs -* A string holding a space separated list of attribute names. -* method -* A string holding the name of the calling method for use in error -* messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - const char *a; - const char *desc; - const char *p; - int len; - int set; - int state; - -/* Check inherited status */ - if( !astOK ) return; - -/* If the SpecFrame has a non-zero value for its UseDefs attribute, then - all attributes are assumed to have usable values, since the defaults - will be used if no explicit value has been set. So we only need to do - any checks if UseDefs is zero. */ - if( !astGetUseDefs( this ) ) { - -/* Stop compiler warnings about uninitialised variables */ - a = NULL; - desc = NULL; - len = 0; - set = 0; - -/* Loop round the "attrs" string identifying the start and length of each - non-blank word in the string. */ - state = 0; - p = attrs; - while( 1 ) { - if( state == 0 ) { - if( !isspace( *p ) ) { - a = p; - len = 1; - state = 1; - } - } else { - if( isspace( *p ) || !*p ) { - -/* The end of a word has just been reached. Compare it to each known - attribute value. Get a flag indicating if the attribute has a set - value, and a string describing the attribute.*/ - if( len > 0 ) { - - if( !strncmp( "ObsLat", a, len ) ) { - set = astTestObsLat( this ); - desc = "observer's latitude"; - - } else if( !strncmp( "ObsLon", a, len ) ) { - set = astTestObsLon( this ); - desc = "observer's longitude"; - - } else if( !strncmp( "ObsAlt", a, len ) ) { - set = astTestObsAlt( this ); - desc = "observer's altitude"; - - } else if( !strncmp( "RefRA", a, len ) ) { - set = astTestRefRA( this ); - desc = "source RA"; - - } else if( !strncmp( "RefDec", a, len ) ) { - set = astTestRefDec( this ); - desc = "source Dec"; - - } else if( !strncmp( "RestFreq", a, len ) ) { - set = astTestRestFreq( this ); - desc = "rest frequency"; - - } else if( !strncmp( "SourceVel", a, len ) ) { - set = astTestSourceVel( this ); - desc = "source velocity"; - - } else if( !strncmp( "StdOfRest", a, len ) ) { - set = astTestStdOfRest( this ); - desc = "spectral standard of rest"; - - } else if( !strncmp( "Epoch", a, len ) ) { - set = astTestEpoch( this ); - desc = "epoch of observation"; - - } else { - astError( AST__INTER, "VerifyAttrs(SpecFrame): " - "Unknown attribute name \"%.*s\" supplied (AST " - "internal programming error).", status, len, a ); - } - -/* If the attribute does not have a set value, report an error. */ - if( !set && astOK ) { - astError( AST__NOVAL, "%s(%s): Cannot %s.", status, method, - astGetClass( this ), purp ); - astError( AST__NOVAL, "No value has been set for " - "the AST \"%.*s\" attribute (%s).", status, len, a, - desc ); - } - -/* Continue the word search algorithm. */ - } - len = 0; - state = 0; - } else { - len++; - } - } - if( !*(p++) ) break; - } - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* -*att++ -* Name: -* AlignSpecOffset - -* Purpose: -* Align SpecFrames using the offset coordinate system? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which controls how a SpecFrame -* behaves when it is used (by -c astFindFrame or astConvert) as a template to match another (target) -f AST_FINDFRAME or AST_CONVERT) as a template to match another (target) -* SpecFrame. It determines whether alignment occurs between the offset -* values defined by the current value of the SpecOffset attribute, or -* between the corresponding absolute spectral values. -* -* The default value of zero results in the two SpecFrames being aligned -* so that a given absolute spectral value in one is mapped to the same -* absolute value in the other. A non-zero value results in the SpecFrames -* being aligned so that a given offset value in one is mapped to the same -* offset value in the other. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. -*att-- -*/ -astMAKE_CLEAR(SpecFrame,AlignSpecOffset,alignspecoffset,-INT_MAX) -astMAKE_GET(SpecFrame,AlignSpecOffset,int,0,( ( this->alignspecoffset != -INT_MAX ) ? - this->alignspecoffset : 0 )) -astMAKE_SET(SpecFrame,AlignSpecOffset,int,alignspecoffset,( value != 0 )) -astMAKE_TEST(SpecFrame,AlignSpecOffset,( this->alignspecoffset != -INT_MAX )) - - - -/* -*att++ -* Name: -* AlignStdOfRest - -* Purpose: -* Standard of rest to use when aligning SpecFrames. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls how a SpecFrame behaves when it is used (by -c astFindFrame or astConvert) as a template to match another (target) -f AST_FINDFRAME or AST_CONVERT) as a template to match another (target) -* SpecFrame. It identifies the standard of rest in which alignment is -* to occur. See the StdOfRest attribute for a desription of the values -* which may be assigned to this attribute. The default AlignStdOfRest -* value is "Helio" (heliographic). -* -c When astFindFrame or astConvert is used on two SpecFrames (potentially -f When AST_FindFrame or AST_CONVERT is used on two SpecFrames (potentially -* describing different spectral coordinate systems), it returns a Mapping -* which can be used to transform a position in one SpecFrame into the -* corresponding position in the other. The Mapping is made up of the -* following steps in the indicated order: -* -* - Map values from the system used by the target (wavelength, -* apparent radial velocity, etc) to the system specified by the -* AlignSystem attribute, using the target's rest frequency if necessary. -* -* - Map these values from the target's standard of rest to the standard of -* rest specified by the AlignStdOfRest attribute, using the Epoch, ObsLat, -* ObsLon, ObsAlt, RefDec and RefRA attributes of the target to define the -* two standards of rest. -* -* - Map these values from the standard of rest specified by the -* AlignStdOfRest attribute, to the template's standard of rest, using the -* Epoch, ObsLat, ObsLon, ObsAlt, RefDec and RefRA attributes of the -* template to define the two standards of rest. -* -* - Map these values from the system specified by the AlignSystem -* attribute, to the system used by the template, using the template's -* rest frequency if necessary. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The AlignStdOfRest value has a value of AST__BADSOR when not set yielding - a default of AST__HLSOR. */ -astMAKE_TEST(SpecFrame,AlignStdOfRest,( this->alignstdofrest != AST__BADSOR )) -astMAKE_CLEAR(SpecFrame,AlignStdOfRest,alignstdofrest,AST__BADSOR) -astMAKE_GET(SpecFrame,AlignStdOfRest,AstStdOfRestType,AST__BADSOR,( - ( this->alignstdofrest == AST__BADSOR ) ? AST__HLSOR : this->alignstdofrest ) ) - -/* Validate the AlignStdOfRest value being set and report an error if necessary. */ -astMAKE_SET(SpecFrame,AlignStdOfRest,AstStdOfRestType,alignstdofrest,( - ( ( value >= FIRST_SOR ) && ( value <= LAST_SOR ) ) ? - value : - ( astError( AST__ATTIN, "%s(%s): Bad value (%d) " - "given for AlignStdOfRest attribute.", status, - "astSetAlignStdOfRest", astGetClass( this ), (int) value ), - -/* Leave the value unchanged on error. */ - this->alignstdofrest ) ) ) - -/* -*att++ -* Name: -* RefDec - -* Purpose: -* The declination of the reference point - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies the FK5 J2000.0 declination of a reference -* point on the sky. See the description of attribute RefRA for details. -* The default RefDec is "0:0:0". - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The reference declination (FK5 J2000, radians). Clear the RefDec value by - setting it to AST__BAD, which results in a default value of zero. Any - value is acceptable. */ -astMAKE_CLEAR(SpecFrame,RefDec,refdec,AST__BAD) -astMAKE_GET(SpecFrame,RefDec,double,0.0,((this->refdec!=AST__BAD)?this->refdec:0.0)) -astMAKE_SET(SpecFrame,RefDec,double,refdec,value) -astMAKE_TEST(SpecFrame,RefDec,( this->refdec != AST__BAD )) - -/* -*att++ -* Name: -* RefRA - -* Purpose: -* The right ascension of the reference point - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute, together with the RefDec attribute, specifies the FK5 -* J2000.0 coordinates of a reference point on the sky. For 1-dimensional -* spectra, this should normally be the position of the source. For -* spectral data with spatial coverage (spectral cubes, etc), this should -* be close to centre of the spatial coverage. It is used to define the -* correction for Doppler shift to be applied when using the -c astFindFrame or astConvert -f AST_FINDFRAME or AST_CONVERT -* method to convert between different standards of rest. -* -* The SpecFrame class assumes this velocity correction is spatially -* invariant. If a single SpecFrame is used (for instance, as a -* component of a CmpFrame) to describe spectral values at different -* points on the sky, then it is assumes that the doppler shift at any -* spatial position is the same as at the reference position. The -* maximum velocity error introduced by this assumption is of the order -* of V*SIN(FOV), where FOV is the angular field of view, and V is the -* relative velocity of the two standards of rest. As an example, when -* correcting from the observers rest frame (i.e. the topocentric rest -* frame) to the kinematic local standard of rest the maximum value of V -* is about 20 km/s, so for 5 arc-minute field of view the maximum velocity -* error introduced by the correction will be about 0.03 km/s. As another -* example, the maximum error when correcting from the observers rest frame -* to the local group is about 5 km/s over a 1 degree field of view. -* -* The RefRA and RefDec attributes are stored internally in radians, but -* are converted to and from a string for access. The format "hh:mm:ss.ss" -* is used for RefRA, and "dd:mm:ss.s" is used for RefDec. The methods -c astSetRefPos and astGetRefPos may be used to access the values of -f AST_SETREFPOS and AST_GETREFPOS may be used to access the value of -* these attributes directly as unformatted values in radians. -* -* The default for RefRA is "0:0:0". - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The reference right ascension (FK5 J2000, radians). Clear the RefRA value - by setting it to AST__BAD, which gives a default value of 0.0. Any - value is acceptable. */ -astMAKE_CLEAR(SpecFrame,RefRA,refra,AST__BAD) -astMAKE_GET(SpecFrame,RefRA,double,0.0,((this->refra!=AST__BAD)?this->refra:0.0)) -astMAKE_SET(SpecFrame,RefRA,double,refra,value) -astMAKE_TEST(SpecFrame,RefRA,( this->refra != AST__BAD )) - - -/* -*att++ -* Name: -* RestFreq - -* Purpose: -* The rest frequency. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the frequency corresponding to zero -* velocity. It is used when converting between between velocity-based -* coordinate systems and and other coordinate systems (such as frequency, -* wavelength, energy, etc). The default value is 1.0E5 GHz. -* -* When setting a new value for this attribute, the new value can be -* supplied either directly as a frequency, or indirectly as a wavelength -* or energy, in which case the supplied value is converted to a frequency -* before being stored. The nature of the supplied value is indicated by -* appending text to the end of the numerical value indicating the units in -* which the value is supplied. If the units are not specified, then the -* supplied value is assumed to be a frequency in units of GHz. If the -* supplied unit is a unit of frequency, the supplied value is assumed to -* be a frequency in the given units. If the supplied unit is a unit of -* length, the supplied value is assumed to be a (vacuum) wavelength. If -* the supplied unit is a unit of energy, the supplied value is assumed to -* be an energy. For instance, the following strings all result in -* a rest frequency of around 1.4E14 Hz being used: "1.4E5", "1.4E14 Hz", -* "1.4E14 s**-1", "1.4E5 GHz", "2.14E-6 m", "21400 Angstrom", "9.28E-20 J", -* "9.28E-13 erg", "0.58 eV", etc. -* -* When getting the value of this attribute, the returned value is -* always a frequency in units of GHz. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The rest frequency (Hz). Clear the RestFreq value by setting it to AST__BAD, - which gives 1.0E14 as the default value. Any value is acceptable. */ -astMAKE_CLEAR(SpecFrame,RestFreq,restfreq,AST__BAD) -astMAKE_GET(SpecFrame,RestFreq,double,1.0E14,((this->restfreq!=AST__BAD)?this->restfreq:1.0E14)) -astMAKE_SET(SpecFrame,RestFreq,double,restfreq,value) -astMAKE_TEST(SpecFrame,RestFreq,( this->restfreq != AST__BAD )) - -/* -*att++ -* Name: -* SourceVel - -* Purpose: -* The source velocity. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute (together with SourceSys, SourceVRF, RefRA and RefDec) -* defines the "Source" standard of rest (see attribute StdOfRest). This is -* a rest frame which is moving towards the position given by RefRA and -* RefDec at a velocity given by SourceVel. A positive value means -* the source is moving away from the observer. When a new value is -* assigned to this attribute, the supplied value is assumed to refer -* to the spectral system specified by the SourceSys attribute. For -* instance, the SourceVel value may be supplied as a radio velocity, a -* redshift, a beta factor, etc. Similarly, when the current value of -* the SourceVel attribute is obtained, the returned value will refer -* to the spectral system specified by the SourceSys value. If the -* SourceSys value is changed, any value previously stored for the SourceVel -* attribute will be changed automatically from the old spectral system -* to the new spectral system. -* -* When setting a value for SourceVel, the value should be supplied in the -* rest frame specified by the SourceVRF attribute. Likewise, when getting -* the value of SourceVel, it will be returned in the rest frame specified -* by the SourceVRF attribute. -* -* The default SourceVel value is zero. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -* Notes: -* - It is important to set an appropriate value for SourceVRF and -* SourceSys before setting a value for SourceVel. If a new value is later -* set for SourceVRF or SourceSys, the value stored for SourceVel will -* simultaneously be changed to the new standard of rest or spectral -* system. - -*att-- -*/ -/* The source velocity (velocities are stored internally in m/s). Clear it - by setting it to AST__BAD, which returns a default value of zero. Any - value is acceptable. */ -astMAKE_CLEAR(SpecFrame,SourceVel,sourcevel,AST__BAD) -astMAKE_SET(SpecFrame,SourceVel,double,sourcevel,value) -astMAKE_TEST(SpecFrame,SourceVel,( this->sourcevel != AST__BAD )) -astMAKE_GET(SpecFrame,SourceVel,double,0.0,((this->sourcevel!=AST__BAD)?this->sourcevel:0.0)) - -/* -*att++ -* Name: -* SourceVRF - -* Purpose: -* Rest frame in which the source velocity is stored. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute identifies the rest frame in which the source -* velocity or redshift is stored (the source velocity or redshift is -* accessed using attribute SourceVel). When setting a new value for the -* SourceVel attribute, the source velocity or redshift should be supplied -* in the rest frame indicated by this attribute. Likewise, when getting -* the value of the SourceVel attribute, the velocity or redshift will be -* returned in this rest frame. -* -* If the value of SourceVRF is changed, the value stored for SourceVel -* will be converted from the old to the new rest frame. -* -* The values which can be supplied are the same as for the StdOfRest -* attribute (except that SourceVRF cannot be set to "Source"). The -* default value is "Helio". - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The SourceVRF value has a value of AST__BADSOR when not set yielding - a default of AST__HLSOR. */ -astMAKE_TEST(SpecFrame,SourceVRF,( this->sourcevrf != AST__BADSOR )) -astMAKE_GET(SpecFrame,SourceVRF,AstStdOfRestType,AST__BADSOR,( - ( this->sourcevrf == AST__BADSOR ) ? AST__HLSOR : this->sourcevrf ) ) - -/* When clearing SourceVRF, convert the SourceVel value to heliocentric - (but only if set)*/ -astMAKE_CLEAR(SpecFrame,SourceVRF,sourcevrf,((astTestSourceVel( this )? - (void)(astSetSourceVel( this, ConvertSourceVel( this, AST__HLSOR, - astGetSourceSys( this ), status ) ),NULL): - NULL),AST__BADSOR)) - -/* Validate the SourceVRF value being set and report an error if necessary. - If OK, convert the stored SourceVel value into the new rest frame (but -only if set)*/ -astMAKE_SET(SpecFrame,SourceVRF,AstStdOfRestType,sourcevrf,( - ( ( value >= FIRST_SOR ) && ( value <= LAST_SOR ) && value != AST__SCSOR ) ? - (astTestSourceVel( this )? - (void)(astSetSourceVel( this,ConvertSourceVel(this,value,astGetSourceSys( this ), status )),NULL): - NULL), value:( astError( AST__ATTIN, "%s(%s): Bad value (%d) " - "given for SourceVRF attribute.", status, - "astSetSourceVRF", astGetClass( this ), (int) value ), - -/* Leave the value unchanged on error. */ - this->sourcevrf ) ) ) - -/* -*att++ -* Name: -* SourceSys - -* Purpose: -* Spectral system in which the source velocity is stored. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute identifies the spectral system in which the -* SourceVel attribute value (the source velocity) is supplied and -* returned. It can be one of the following: -* -* - "VRAD" or "VRADIO": Radio velocity (km/s) -* - "VOPT" or "VOPTICAL": Optical velocity (km/s) -* - "ZOPT" or "REDSHIFT": Redshift (dimensionless) -* - "BETA": Beta factor (dimensionless) -* - "VELO" or "VREL": Apparent radial ("relativistic") velocity (km/s) -* -* When setting a new value for the SourceVel attribute, the source -* velocity should be supplied in the spectral system indicated -* by this attribute. Likewise, when getting the value of the SourceVel -* attribute, the velocity will be returned in this spectral system. -* -* If the value of SourceSys is changed, the value stored for SourceVel -* will be converted from the old to the new spectral systems. -* -* The default value is "VELO" (apparent radial velocity). - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The SourceSys value has a value of AST__BADSYS when not set yielding - a default of AST__VREL. */ -astMAKE_TEST(SpecFrame,SourceSys,( this->sourcesys != AST__BADSYSTEM )) -astMAKE_GET(SpecFrame,SourceSys,AstSystemType,AST__BADSYSTEM,( - ( this->sourcesys == AST__BADSYSTEM ) ? AST__VREL : this->sourcesys ) ) - -/* When clearing SourceSys, convert the SourceVel value to relativistic - velocity (but only if set) */ -astMAKE_CLEAR(SpecFrame,SourceSys,sourcesys,((astTestSourceVel( this )? -(void)(astSetSourceVel( this, ConvertSourceVel( this, astGetSourceVRF( this ), - AST__VREL, status ) ),NULL):NULL),AST__BADSYSTEM)) - -/* Validate the SourceSys value being set and report an error if necessary. - If OK, convert the stored SourceVel value into the new rest frame (but - only if set)*/ -astMAKE_SET(SpecFrame,SourceSys,AstSystemType,sourcesys,( - ( ( value == AST__VREL ) || ( value == AST__BETA ) || - ( value == AST__VRADIO ) || ( value == AST__REDSHIFT ) || - ( value == AST__VOPTICAL ) ) ? - (astTestSourceVel( this )? - (void)(astSetSourceVel( this, ConvertSourceVel( this, astGetSourceVRF( this ), - value, status )),NULL):NULL), - value: - ( astError( AST__ATTIN, "%s(%s): Bad value (%d) " - "given for SourceSys attribute.", status, - "astSetSourceSys", astGetClass( this ), (int) value ), - -/* Leave the value unchanged on error. */ - this->sourcesys ) ) ) - -/* -*att++ -* Name: -* StdOfRest - -* Purpose: -* Standard of rest. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute identifies the standard of rest to which the spectral -* axis values of a SpecFrame refer, and may take any of the values -* listed in the "Standards of Rest" section (below). -* -* The default StdOfRest value is "Helio". - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -* Standards of Rest: -* The SpecFrame class supports the following StdOfRest values (all are -* case-insensitive): -* -* - "Topocentric", "Topocent" or "Topo": The observers rest-frame (assumed -* to be on the surface of the earth). Spectra recorded in this standard of -* rest suffer a Doppler shift which varies over the course of a day -* because of the rotation of the observer around the axis of the earth. -* This standard of rest must be qualified using the ObsLat, ObsLon, -* ObsAlt, Epoch, RefRA and RefDec attributes. -* -* - "Geocentric", "Geocentr" or "Geo": The rest-frame of the earth centre. -* Spectra recorded in this standard of rest suffer a Doppler shift which -* varies over the course of a year because of the rotation of the earth -* around the Sun. This standard of rest must be qualified using the Epoch, -* RefRA and RefDec attributes. -* -* - "Barycentric", "Barycent" or "Bary": The rest-frame of the solar-system -* barycentre. Spectra recorded in this standard of rest suffer a Doppler -* shift which depends both on the velocity of the Sun through the Local -* Standard of Rest, and on the movement of the planets through the solar -* system. This standard of rest must be qualified using the Epoch, RefRA -* and RefDec attributes. -* -* - "Heliocentric", "Heliocen" or "Helio": The rest-frame of the Sun. -* Spectra recorded in this standard of rest suffer a Doppler shift which -* depends on the velocity of the Sun through the Local Standard of Rest. -* This standard of rest must be qualified using the RefRA and RefDec -* attributes. -* -* - "LSRK", "LSR": The rest-frame of the kinematical Local Standard of -* Rest. Spectra recorded in this standard of rest suffer a Doppler shift -* which depends on the velocity of the kinematical Local Standard of Rest -* through the galaxy. This standard of rest must be qualified using the -* RefRA and RefDec attributes. -* -* - "LSRD": The rest-frame of the dynamical Local Standard of Rest. Spectra -* recorded in this standard of rest suffer a Doppler shift which depends -* on the velocity of the dynamical Local Standard of Rest through the -* galaxy. This standard of rest must be qualified using the RefRA and -* RefDec attributes. -* -* - "Galactic", "Galactoc" or "Gal": The rest-frame of the galactic centre. -* Spectra recorded in this standard of rest suffer a Doppler shift which -* depends on the velocity of the galactic centre through the local group. -* This standard of rest must be qualified using the RefRA and RefDec -* attributes. -* -* - "Local_group", "Localgrp" or "LG": The rest-frame of the local group. -* This standard of rest must be qualified using the RefRA and RefDec -* attributes. -* -* - "Source", or "src": The rest-frame of the source. This standard of -* rest must be qualified using the RefRA, RefDec and SourceVel attributes. -* -* Where more than one alternative System value is shown above, the -* first of these will be returned when an enquiry is made. -*att-- -*/ -/* The StdOfRest value has a value of AST__BADSOR when not set yielding - a default of AST__HLSOR. */ -astMAKE_TEST(SpecFrame,StdOfRest,( this->stdofrest != AST__BADSOR )) -astMAKE_GET(SpecFrame,StdOfRest,AstStdOfRestType,AST__BADSOR,( - ( this->stdofrest == AST__BADSOR ) ? AST__HLSOR : this->stdofrest ) ) - -/* -*att++ -* Name: -* SpecOrigin - -* Purpose: -* The zero point for SpecFrame axis values - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This specifies the origin from which all spectral values are measured. -* The default value (zero) results in the SpecFrame describing -* absolute spectral values in the system given by the System attribute -* (e.g. frequency, velocity, etc). If a SpecFrame is to be used to -* describe offset from some origin, the SpecOrigin attribute -* should be set to hold the required origin value. The SpecOrigin value -* stored inside the SpecFrame structure is modified whenever SpecFrame -* attribute values are changed so that it refers to the original spectral -* position. -* -* When setting a new value for this attribute, the supplied value is assumed -* to be in the system, units and standard of rest described by the SpecFrame. -* Likewise, when getting the value of this attribute, the value is returned -* in the system, units and standard of rest described by the SpecFrame. If -* any of these attributes are changed, then any previously stored SpecOrigin -* value will also be changed so that refers to the new system, units or -* standard of rest. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The spec origin, stored internally in the default units associated - with the current System value. Clear the SpecOrigin value by setting it - to AST__BAD, which gives 0.0 as the default value. Any value is acceptable. */ -astMAKE_CLEAR(SpecFrame,SpecOrigin,specorigin,AST__BAD) -astMAKE_GET(SpecFrame,SpecOrigin,double,0.0,((this->specorigin!=AST__BAD)?this->specorigin:0.0)) -astMAKE_SET(SpecFrame,SpecOrigin,double,specorigin,value) -astMAKE_TEST(SpecFrame,SpecOrigin,( this->specorigin != AST__BAD )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for SpecFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for SpecFrame objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstSpecFrame *in; /* Pointer to input SpecFrame */ - AstSpecFrame *out; /* Pointer to output SpecFrame */ - char *usedunit; /* Pointer to an element of usedunits array */ - int i; /* Loop count */ - int nused; /* Size of "usedunits" array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output SpecFrames. */ - in = (AstSpecFrame *) objin; - out = (AstSpecFrame *) objout; - -/* Nullify the pointers stored in the output object since these will - currently be pointing at the input data (since the output is a simple - byte-for-byte copy of the input). Otherwise, the input data could be - freed by accidient if the output object is deleted due to an error - occuring in this function. */ - out->usedunits = NULL; - -/* Store the last used units in the output SpecMap. */ - if( in && in->usedunits ) { - nused = in->nuunits; - out->usedunits = astMalloc( nused*sizeof( char * ) ); - if( out->usedunits ) { - for( i = 0; i < nused; i++ ) { - usedunit = in->usedunits[ i ]; - if( usedunit ) { - out->usedunits[ i ] = astStore( NULL, usedunit, - strlen( usedunit ) + 1 ); - } else { - out->usedunits[ i ] = NULL; - } - } - } - } - -/* If an error has occurred, free the output resources. */ - if( !astOK ) Delete( (AstObject *) out, status ); - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for SpecFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for SpecFrame objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstSpecFrame *this; - int i; - -/* Release the memory referred to in the SpecFrame structure. */ - this = (AstSpecFrame *) obj; - if( this && this->usedunits ) { - for( i = 0; i < this->nuunits; i++ ) { - this->usedunits[ i ] = astFree( this->usedunits[ i ] ); - } - this->usedunits = astFree( this->usedunits ); - } -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SpecFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the SpecFrame class to an output Channel. - -* Parameters: -* this -* Pointer to the SpecFrame whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - AstStdOfRestType sor; /* StdOfRest attribute value */ - AstSystemType sys; /* Spectral system value */ - char buff[ 20 ]; /* Buffer for item name */ - char comm[ 50 ]; /* Buffer for comment */ - const char *sval; /* Pointer to string value */ - double dval; /* Double value */ - int i; /* Loop count */ - int ival; /* int value */ - int j; /* Loop count */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Write out values representing the instance variables for the - SpecFrame class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* StdOfRest. */ -/* ---------- */ - set = TestStdOfRest( this, status ); - sor = set ? GetStdOfRest( this, status ) : astGetStdOfRest( this ); - -/* If set, convert explicitly to a string for the external - representation. */ - sval = ""; - if ( set ) { - if ( astOK ) { - sval = StdOfRestString( sor, status ); - -/* Report an error if the StdOfRest value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid standard of rest " - "identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) sor ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "stdofrest" ); - } - -/* Write out the value. */ - astWriteString( channel, "SoR", set, 1, sval, "Standard of rest" ); - -/* AlignStdOfRest. */ -/* --------------- */ - set = TestAlignStdOfRest( this, status ); - sor = set ? GetAlignStdOfRest( this, status ) : astGetAlignStdOfRest( this ); - -/* If set, convert explicitly to a string for the external representation. */ - if ( set ) { - if ( astOK ) { - sval = StdOfRestString( sor, status ); - -/* Report an error if the StdOfRest value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid alignment standard " - "of rest identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) sor ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "alignstdofrest" ); - } - -/* Write out the value. */ - astWriteString( channel, "AlSoR", set, 0, sval, "Alignment standard of rest" ); - -/* RefRA. */ -/* ------ */ - set = TestRefRA( this, status ); - dval = set ? GetRefRA( this, status ) : astGetRefRA( this ); - astWriteDouble( channel, "RefRA", set, 0, dval, "Reference RA (rads, FK5 J2000)" ); - -/* RefDec. */ -/* ------- */ - set = TestRefDec( this, status ); - dval = set ? GetRefDec( this, status ) : astGetRefDec( this ); - astWriteDouble( channel, "RefDec", set, 0, dval, "Reference Dec (rads, FK5 J2000)" ); - -/* RestFreq. */ -/* --------- */ - set = TestRestFreq( this, status ); - dval = set ? GetRestFreq( this, status ) : astGetRestFreq( this ); - astWriteDouble( channel, "RstFrq", set, 0, dval, "Rest frequency (Hz)" ); - -/* SourceVel. */ -/* ---------- */ - set = TestSourceVel( this, status ); - dval = set ? GetSourceVel( this, status ) : astGetSourceVel( this ); - astWriteDouble( channel, "SrcVel", set, 0, dval, "Source velocity (m/s)" ); - -/* SourceVRF. */ -/* ---------- */ - set = TestSourceVRF( this, status ); - sor = set ? GetSourceVRF( this, status ) : astGetSourceVRF( this ); - -/* If set, convert explicitly to a string for the external representation. */ - if ( set ) { - if ( astOK ) { - sval = StdOfRestString( sor, status ); - -/* Report an error if the value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid source velocity " - "rest frame identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) sor ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "sourcevrf" ); - } - -/* Write out the value. */ - astWriteString( channel, "SrcVRF", set, 0, sval, "Source velocity rest frame" ); - -/* SourceSys. */ -/* ---------- */ - set = TestSourceSys( this, status ); - sys = set ? GetSourceSys( this, status ) : astGetSourceSys( this ); - -/* If set, convert explicitly to a string for the external representation. */ - if ( set ) { - if ( astOK ) { - sval = SystemString( (AstFrame *) this, sys, status ); - -/* Report an error if the value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid source velocity " - "spectral system identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) sys ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "sourcesys" ); - } - -/* Write out the value. */ - astWriteString( channel, "SrcSys", set, 0, sval, "Source velocity spectral system" ); - -/* AlignSpecOffset. */ -/* ---------------- */ - set = TestAlignSpecOffset( this, status ); - ival = set ? GetAlignSpecOffset( this, status ) : astGetAlignSpecOffset( this ); - astWriteInt( channel, "AlSpOf", set, 0, ival, - ival ? "Align in offset coords" : - "Align in system coords" ); - -/* UsedUnits */ -/* --------- */ - if( this->usedunits ) { - for( i = 0; i < this->nuunits; i++ ) { - if( this->usedunits[ i ] ) { - sprintf( buff, "U%s", astSystemString( this, (AstSystemType) i )); - for( j = 2; j < strlen( buff ); j++ ) buff[ j ] = tolower( buff[ j ] ); - sprintf( comm, "Preferred units for %s", SystemLabel( (AstSystemType) i, status ) ); - astWriteString( channel, buff, 1, 0, this->usedunits[ i ], comm ); - } - } - } - -/* SpecOrigin. */ -/* ----------- */ - set = TestSpecOrigin( this, status ); - dval = set ? GetSpecOrigin( this, status ) : astGetSpecOrigin( this ); - if( dval != AST__BAD ) { - astWriteDouble( channel, "SpOrg", set, 0, dval, "Spec offset" ); - } - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASpecFrame and astCheckSpecFrame functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SpecFrame,Frame) -astMAKE_CHECK(SpecFrame) - -AstSpecFrame *astSpecFrame_( const char *options, int *status, ...) { -/* -*+ -* Name: -* astSpecFrame - -* Purpose: -* Create a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* AstSpecFrame *astSpecFrame( const char *options, int *status, ... ) - -* Class Membership: -* SpecFrame constructor. - -* Description: -* This function creates a new SpecFrame and optionally initialises its -* attributes. - -* Parameters: -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new SpecFrame. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new SpecFrame. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic SpecFrame constructor which -* is available via the protected interface to the SpecFrame class. -* A public interface is provided by the astSpecFrameId_ function. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *um; /* Mapping from default to actual units */ - AstSpecFrame *new; /* Pointer to new SpecFrame */ - AstSystemType s; /* System */ - const char *u; /* Units string */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SpecFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSpecFrame( NULL, sizeof( AstSpecFrame ), !class_init, - &class_vtab, "SpecFrame" ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SpecFrame's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* Check the Units are appropriate for the System. */ - u = astGetUnit( new, 0 ); - s = astGetSystem( new ); - um = astUnitMapper( DefUnit( s, "astSpecFrame", "SpecFrame", status ), - u, NULL, NULL ); - if( um ) { - um = astAnnul( um ); - } else { - astError( AST__BADUN, "astSpecFrame: Inappropriate units (%s) " - "specified for a %s axis.", status, u, SystemLabel( s, status ) ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new SpecFrame. */ - return new; -} - -AstSpecFrame *astInitSpecFrame_( void *mem, size_t size, int init, - AstSpecFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSpecFrame - -* Purpose: -* Initialise a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* AstSpecFrame *astInitSpecFrame( void *mem, size_t size, int init, -* AstFrameVtab *vtab, const char *name ) - -* Class Membership: -* SpecFrame initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new SpecFrame object. It allocates memory (if -* necessary) to accommodate the SpecFrame plus any additional data -* associated with the derived class. It then initialises a -* SpecFrame structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual function -* table for a SpecFrame at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SpecFrame is to be -* created. This must be of sufficient size to accommodate the -* SpecFrame data (sizeof(SpecFrame)) plus any data used by -* the derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SpecFrame (plus derived -* class data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also stored -* in the SpecFrame structure, so a valid value must be supplied -* even if not required for allocating memory. -* init -* A logical flag indicating if the SpecFrame's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SpecFrame. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object belongs -* (it is this pointer value that will subsequently be returned by -* the astGetClass method). - -* Returned Value: -* A pointer to the new SpecFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstSpecFrame *new; /* Pointer to the new SpecFrame */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSpecFrameVtab( vtab, name ); - -/* Initialise a 1D Frame structure (the parent class) as the first component - within the SpecFrame structure, allocating memory if necessary. */ - new = (AstSpecFrame *) astInitFrame( mem, size, 0, - (AstFrameVtab *) vtab, name, 1 ); - - if ( astOK ) { - -/* Initialise the SpecFrame data. */ -/* ----------------------------- */ -/* Initialise all attributes to their "undefined" values. */ - new->alignstdofrest = AST__BADSOR; - new->refdec = AST__BAD; - new->refra = AST__BAD; - new->restfreq = AST__BAD; - new->sourcevel = AST__BAD; - new->sourcevrf = AST__BADSOR; - new->sourcesys = AST__BADSYSTEM; - new->stdofrest = AST__BADSOR; - new->nuunits = 0; - new->usedunits = NULL; - new->specorigin = AST__BAD; - new->alignspecoffset = -INT_MAX; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - - } - -/* Return a pointer to the new object. */ - return new; -} - -AstSpecFrame *astLoadSpecFrame_( void *mem, size_t size, - AstSpecFrameVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSpecFrame - -* Purpose: -* Load a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* AstSpecFrame *astLoadSpecFrame( void *mem, size_t size, -* AstSpecFrameVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* SpecFrame loader. - -* Description: -* This function is provided to load a new SpecFrame using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* SpecFrame structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the SpecFrame is to be -* loaded. This must be of sufficient size to accommodate the -* SpecFrame data (sizeof(SpecFrame)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SpecFrame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SpecFrame structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstSpecFrame) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SpecFrame. If this is NULL, a pointer -* to the (static) virtual function table for the SpecFrame class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "SpecFrame" is used instead. - -* Returned Value: -* A pointer to the new SpecFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSpecFrame *new; /* Pointer to the new SpecFrame */ - char buff[ 20 ]; /* Buffer for item name */ - char *sval; /* Pointer to string value */ - double obslat; /* Value for ObsLat attribute */ - double obslon; /* Get a pointer to the thread specific global data structure. */ - -/* Value for ObsLon attribute */ - int i; /* Loop count */ - int j; /* Loop count */ - int nc; /* String length */ - int sys; /* System value */ - - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SpecFrame. In this case the - SpecFrame belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSpecFrame ); - vtab = &class_vtab; - name = "SpecFrame"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSpecFrameVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built SpecFrame. */ - new = astLoadFrame( mem, size, (AstFrameVtab *) vtab, name, - channel ); - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "SpecFrame" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* StdOfRest. */ -/* ---------- */ -/* Set the default and read the external representation as a string. */ - new->stdofrest = AST__BADSOR; - sval = astReadString( channel, "sor", NULL ); - -/* If a value was read, convert from a string to a StdOfRest code. */ - if ( sval ) { - if ( astOK ) { - new->stdofrest = StdOfRestCode( sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->stdofrest == AST__BADSOR ) { - astError( AST__ATTIN, - "astRead(%s): Invalid standard of rest description " - "\"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* AlignStdOfRest. */ -/* --------------- */ -/* Set the default and read the external representation as a string. */ - new->alignstdofrest = AST__BADSOR; - sval = astReadString( channel, "alsor", NULL ); - -/* If a value was read, convert from a string to a StdOfRest code. */ - if ( sval ) { - if ( astOK ) { - new->alignstdofrest = StdOfRestCode( sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->alignstdofrest == AST__BADSOR ) { - astError( AST__ATTIN, - "astRead(%s): Invalid alignment standard of rest " - "description \"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in - which SpecFrame had a GeoLat attribute (now ObsLat is used instead). */ - if( !astTestObsLat( new ) ) { - obslat = astReadDouble( channel, "geolat", AST__BAD ); - if ( obslat != AST__BAD ) astSetObsLat( new, obslat ); - } - -/* GeoLon. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in - which SpecFrame had a GeoLon attribute (now ObsLon is used instead). */ - if( !astTestObsLon( new ) ) { - obslon = astReadDouble( channel, "geolon", AST__BAD ); - if ( obslon != AST__BAD ) astSetObsLon( new, obslon ); - } - -/* RefRA. */ -/* ------ */ - new->refra = astReadDouble( channel, "refra", AST__BAD ); - if ( TestRefRA( new, status ) ) SetRefRA( new, new->refra, status ); - -/* RefDec. */ -/* ------- */ - new->refdec = astReadDouble( channel, "refdec", AST__BAD ); - if ( TestRefDec( new, status ) ) SetRefDec( new, new->refdec, status ); - -/* RestFreq. */ -/* --------- */ - new->restfreq = astReadDouble( channel, "rstfrq", AST__BAD ); - if ( TestRestFreq( new, status ) ) SetRestFreq( new, new->restfreq, status ); - -/* AlignSpecOffset */ -/* --------------- */ - new->alignspecoffset = astReadInt( channel, "alspof", -INT_MAX ); - if ( TestAlignSpecOffset( new, status ) ) SetAlignSpecOffset( new, new->alignspecoffset, status ); - -/* SourceVel. */ -/* ---------- */ - new->sourcevel = astReadDouble( channel, "srcvel", AST__BAD ); - if ( TestSourceVel( new, status ) ) SetSourceVel( new, new->sourcevel, status ); - -/* SourceVRF */ -/* --------- */ -/* Set the default and read the external representation as a string. */ - new->sourcevrf = AST__BADSOR; - sval = astReadString( channel, "srcvrf", NULL ); - -/* If a value was read, convert from a string to a StdOfRest code. */ - if ( sval ) { - if ( astOK ) { - new->sourcevrf = StdOfRestCode( sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->sourcevrf == AST__BADSOR ) { - astError( AST__ATTIN, - "astRead(%s): Invalid source velocity rest frame " - "description \"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* SourceSys */ -/* --------- */ -/* Set the default and read the external representation as a string. */ - new->sourcesys = AST__BADSYSTEM; - sval = astReadString( channel, "srcsys", NULL ); - -/* If a value was read, convert from a string to a System code. */ - if ( sval ) { - if ( astOK ) { - new->sourcesys = SystemCode( (AstFrame *) new, sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->sourcesys == AST__BADSYSTEM ) { - astError( AST__ATTIN, - "astRead(%s): Invalid source velocity spectral system " - "description \"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* UsedUnits */ -/* --------- */ - new->nuunits = 0; - new->usedunits = NULL; - for( sys = FIRST_SYSTEM; sys <= LAST_SYSTEM; sys++ ) { - nc = sprintf( buff, "u%s", astSystemString( new, (AstSystemType) sys )); - for( j = 0; j < nc; j++ ) buff[ j ] = tolower( buff[ j ] ); - sval = astReadString( channel, buff, NULL ); - if( sval ) { - if( (int) sys >= new->nuunits ) { - new->usedunits = astGrow( new->usedunits, sys + 1, - sizeof(char *) ); - if( astOK ) { - for( i = new->nuunits; i < sys + 1; i++ ) new->usedunits[ i ] = NULL; - new->nuunits = sys + 1; - } - } else { - new->usedunits[ sys ] = astFree( new->usedunits[ sys ] ); - } - if( astOK ) { - new->usedunits[ sys ] = astStore( new->usedunits[ sys ], - sval, strlen( sval ) + 1 ); - } - sval = astFree( sval); - } - } - -/* SpecOrigin. */ -/* --------- */ - new->specorigin = astReadDouble( channel, "sporg", AST__BAD ); - if ( TestSpecOrigin( new, status ) ) SetSpecOrigin( new, new->specorigin, status ); - - -/* If an error occurred, clean up by deleting the new SpecFrame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new SpecFrame pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -void astGetRefPos_( AstSpecFrame *this, AstSkyFrame *frm, double *lon, - double *lat, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,SpecFrame,GetRefPos))(this,frm,lon,lat, status ); -} -void astSetRefPos_( AstSpecFrame *this, AstSkyFrame *frm, double lon, - double lat, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,SpecFrame,SetRefPos))(this,frm,lon,lat, status ); -} - -void astSetStdOfRest_( AstSpecFrame *this, AstStdOfRestType value, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,SpecFrame,SetStdOfRest))(this,value, status ); -} - -void astClearStdOfRest_( AstSpecFrame *this, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,SpecFrame,ClearStdOfRest))(this, status ); -} - - - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSpecFrame *astSpecFrameId_( const char *, ... ); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstSpecFrame *astSpecFrameId_( const char *options, ... ) { -/* -*++ -* Name: -c astSpecFrame -f AST_SPECFRAME - -* Purpose: -* Create a SpecFrame. - -* Type: -* Public function. - -* Synopsis: -c #include "specframe.h" -c AstSpecFrame *astSpecFrame( const char *options, ... ) -f RESULT = AST_SPECFRAME( OPTIONS, STATUS ) - -* Class Membership: -* SpecFrame constructor. - -* Description: -* This function creates a new SpecFrame and optionally initialises -* its attributes. -* -* A SpecFrame is a specialised form of one-dimensional Frame which -* represents various coordinate systems used to describe positions within -* an electro-magnetic spectrum. The particular coordinate system to be -* used is specified by setting the SpecFrame's System attribute (the -* default is wavelength) qualified, as necessary, by other attributes -* such as the rest frequency, the standard of rest, the epoch of -* observation, etc (see the description of the System attribute for -* details). -* -* By setting a value for thr SpecOrigin attribute, a SpecFrame can be made -* to represent offsets from a given spectral position, rather than absolute - -* Parameters: -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new SpecFrame. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new SpecFrame. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSpecFrame() -f AST_SPECFRAME = INTEGER -* A pointer to the new SpecFrame. - -* Examples: -c frame = astSpecFrame( "" ); -f FRAME = AST_SPECFRAME( ' ', STATUS ) -* Creates a SpecFrame to describe the default wavelength spectral -* coordinate system. The RestFreq attribute (rest frequency) is -* unspecified, so it will not be possible to align this SpecFrame -* with another SpecFrame on the basis of a velocity-based system. The -* standard of rest is also unspecified. This means that alignment -* will be possible with other SpecFrames, but no correction will be -* made for Doppler shift caused by change of rest frame during the -* alignment. -c frame = astSpecFrame( "System=VELO, RestFreq=1.0E15, StdOfRest=LSRK" ); -f FRAME = AST_SPECFRAME( 'System=VELO, RestFreq=1.0E15, StdOfRest=LSRK', STATUS ) -* Creates a SpecFrame describing a apparent radial velocity ("VELO") axis -* with rest frequency 1.0E15 Hz (about 3000 Angstroms), measured -* in the kinematic Local Standard of Rest ("LSRK"). Since the -* source position has not been specified (using attributes RefRA and -* RefDec), it will only be possible to align this SpecFrame with -* other SpecFrames which are also measured in the LSRK standard of -* rest. - -* Notes: -* - When conversion between two SpecFrames is requested (as when -c supplying SpecFrames to astConvert), -f supplying SpecFrames AST_CONVERT), -* account will be taken of the nature of the spectral coordinate systems -* they represent, together with any qualifying rest frequency, standard -* of rest, epoch values, etc. The AlignSystem and AlignStdOfRest -* attributes will also be taken into account. The results will therefore -* fully reflect the relationship between positions measured in the two -* systems. In addition, any difference in the Unit attributes of the two -* systems will also be taken into account. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astSpecFrame constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astSpecFrame_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - The variable argument list also prevents this function from -* invoking astSpecFrame_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *um; /* Mapping from default to actual units */ - AstSpecFrame *new; /* Pointer to new SpecFrame */ - AstSystemType s; /* System */ - const char *u; /* Units string */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - astGET_GLOBALS(NULL); /* Get a pointer to the thread specific global data structure. */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SpecFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSpecFrame( NULL, sizeof( AstSpecFrame ), !class_init, - &class_vtab, "SpecFrame" ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SpecFrame's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* Check the Units are appropriate for the System. */ - u = astGetUnit( new, 0 ); - s = astGetSystem( new ); - um = astUnitMapper( DefUnit( s, "astSpecFrame", "SpecFrame", status ), - u, NULL, NULL ); - if( um ) { - um = astAnnul( um ); - } else { - astError( AST__BADUN, "astSpecFrame: Inappropriate units (%s) " - "specified for a %s axis.", status, u, SystemLabel( s, status ) ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new SpecFrame. */ - return astMakeId( new ); -} - diff --git a/ast/specframe.h b/ast/specframe.h deleted file mode 100644 index 34d8eac..0000000 --- a/ast/specframe.h +++ /dev/null @@ -1,430 +0,0 @@ -#if !defined( SPECFRAME_INCLUDED ) /* Include this file only once */ -#define SPECFRAME_INCLUDED -/* -*+ -* Name: -* specframe.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the SpecFrame class. - -* Invocation: -* #include "specframe.h" - -* Description: -* This include file defines the interface to the SpecFrame class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 12-NOV-2002 (DSB): -* Original version. -* 18-OCT-2006 (DSB): -* Added SpecOrigin. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "frame.h" /* Parent Frame class */ -#include "skyframe.h" /* Celestial coordinate systems */ - -/* Macros. */ -/* ======= */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - - -#if defined(astCLASS) /* Protected */ - -/* Values used to represent different System attribute values. */ -#define AST__FREQ 1 -#define AST__ENERGY 2 -#define AST__WAVENUM 3 -#define AST__WAVELEN 4 -#define AST__AIRWAVE 5 -#define AST__VRADIO 6 -#define AST__VOPTICAL 7 -#define AST__REDSHIFT 8 -#define AST__BETA 9 -#define AST__VREL 10 - -/* Values used to represent different StdOfRest attribute values. */ -#define AST__BADSOR 0 -#define AST__TPSOR 1 -#define AST__GESOR 2 -#define AST__BYSOR 3 -#define AST__HLSOR 4 -#define AST__LDSOR 5 -#define AST__LKSOR 6 -#define AST__LGSOR 7 -#define AST__GLSOR 8 -#define AST__SCSOR 9 -#endif - -/* Type Definitions. */ -/* ================= */ - -/* Integer type used to store the spectral StdOfRest attribute. */ -typedef int AstStdOfRestType; - -/* SpecFrame structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstSpecFrame { - -/* Attributes inherited from the parent class. */ - AstFrame frame; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstStdOfRestType alignstdofrest;/* Code identifying alignment StdOfRest */ - AstStdOfRestType stdofrest; /* Standard of rest */ - double refdec; /* Dec (FK5 J2000) of source */ - double refra; /* RA (FK5 J2000) of source */ - double restfreq; /* Rest frequency (Hz)*/ - double sourcevel; /* Source velocity (heliocentric, m/s) */ - AstStdOfRestType sourcevrf; /* Code identifying source vel. StdOfRest */ - AstSystemType sourcesys; /* Code identifying source vel. system */ - int nuunits; /* Size of usedunits array */ - char **usedunits; /* Last used units for each system */ - double specorigin; /* Origin for sectral values */ - int alignspecoffset; /* Align SpecFrame in offset coords? */ -} AstSpecFrame; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all objects in the - class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstSpecFrameVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstFrameVtab frame_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* GetRefPos)( AstSpecFrame *, AstSkyFrame *, double *, double *, int * ); - void (* SetRefPos)( AstSpecFrame *, AstSkyFrame *, double, double, int * ); - - AstStdOfRestType (* GetStdOfRest)( AstSpecFrame *, int * ); - int (* TestStdOfRest)( AstSpecFrame *, int * ); - void (* ClearStdOfRest)( AstSpecFrame *, int * ); - void (* SetStdOfRest)( AstSpecFrame *, AstStdOfRestType, int * ); - - AstStdOfRestType (* GetAlignStdOfRest)( AstSpecFrame *, int * ); - int (* TestAlignStdOfRest)( AstSpecFrame *, int * ); - void (* ClearAlignStdOfRest)( AstSpecFrame *, int * ); - void (* SetAlignStdOfRest)( AstSpecFrame *, AstStdOfRestType, int * ); - - AstStdOfRestType (* GetSourceVRF)( AstSpecFrame *, int * ); - int (* TestSourceVRF)( AstSpecFrame *, int * ); - void (* ClearSourceVRF)( AstSpecFrame *, int * ); - void (* SetSourceVRF)( AstSpecFrame *, AstStdOfRestType, int * ); - - AstSystemType (* GetSourceSys)( AstSpecFrame *, int * ); - int (* TestSourceSys)( AstSpecFrame *, int * ); - void (* ClearSourceSys)( AstSpecFrame *, int * ); - void (* SetSourceSys)( AstSpecFrame *, AstSystemType, int * ); - - double (* GetRestFreq)( AstSpecFrame *, int * ); - int (* TestRestFreq)( AstSpecFrame *, int * ); - void (* ClearRestFreq)( AstSpecFrame *, int * ); - void (* SetRestFreq)( AstSpecFrame *, double, int * ); - - double (* GetRefRA)( AstSpecFrame *, int * ); - int (* TestRefRA)( AstSpecFrame *, int * ); - void (* ClearRefRA)( AstSpecFrame *, int * ); - void (* SetRefRA)( AstSpecFrame *, double, int * ); - - double (* GetRefDec)( AstSpecFrame *, int * ); - int (* TestRefDec)( AstSpecFrame *, int * ); - void (* ClearRefDec)( AstSpecFrame *, int * ); - void (* SetRefDec)( AstSpecFrame *, double, int * ); - - double (* GetSourceVel)( AstSpecFrame *, int * ); - int (* TestSourceVel)( AstSpecFrame *, int * ); - void (* ClearSourceVel)( AstSpecFrame *, int * ); - void (* SetSourceVel)( AstSpecFrame *, double, int * ); - - double (* GetSpecOrigin)( AstSpecFrame *, int * ); - int (* TestSpecOrigin)( AstSpecFrame *, int * ); - void (* ClearSpecOrigin)( AstSpecFrame *, int * ); - void (* SetSpecOrigin)( AstSpecFrame *, double, int * ); - - int (* GetAlignSpecOffset)( AstSpecFrame *, int * ); - int (* TestAlignSpecOffset)( AstSpecFrame *, int * ); - void (* ClearAlignSpecOffset)( AstSpecFrame *, int * ); - void (* SetAlignSpecOffset)( AstSpecFrame *, int, int * ); - - -} AstSpecFrameVtab; - - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstSpecFrameGlobals { - AstSpecFrameVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 51 ]; - char GetLabel_Buff[ 201 ]; - char GetSymbol_Buff[ 21 ]; - char GetTitle_Buff[ 201 ]; -} AstSpecFrameGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(SpecFrame) /* Check class membership */ -astPROTO_ISA(SpecFrame) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -AstSpecFrame *astSpecFrame_( const char *, int *, ...); -#else -AstSpecFrame *astSpecFrameId_( const char *, ... )__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstSpecFrame *astInitSpecFrame_( void *, size_t, int, - AstSpecFrameVtab *, - const char *, int * ); - -/* Vtab initialiser. */ -void astInitSpecFrameVtab_( AstSpecFrameVtab *, const char *, int * ); - -/* Loader. */ -AstSpecFrame *astLoadSpecFrame_( void *, size_t, - AstSpecFrameVtab *, - const char *, AstChannel *channel, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitSpecFrameGlobals_( AstSpecFrameGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -void astGetRefPos_( AstSpecFrame *, AstSkyFrame *, double *, double *, int * ); -void astSetRefPos_( AstSpecFrame *, AstSkyFrame *, double, double, int * ); - -#if defined(astCLASS) /* Protected */ - -AstStdOfRestType astGetStdOfRest_( AstSpecFrame *, int * ); -int astTestStdOfRest_( AstSpecFrame *, int * ); -void astClearStdOfRest_( AstSpecFrame *, int * ); -void astSetStdOfRest_( AstSpecFrame *, AstStdOfRestType, int * ); - -AstStdOfRestType astGetAlignStdOfRest_( AstSpecFrame *, int * ); -int astTestAlignStdOfRest_( AstSpecFrame *, int * ); -void astClearAlignStdOfRest_( AstSpecFrame *, int * ); -void astSetAlignStdOfRest_( AstSpecFrame *, AstStdOfRestType, int * ); - -AstStdOfRestType astGetSourceVRF_( AstSpecFrame *, int * ); -int astTestSourceVRF_( AstSpecFrame *, int * ); -void astClearSourceVRF_( AstSpecFrame *, int * ); -void astSetSourceVRF_( AstSpecFrame *, AstStdOfRestType, int * ); - -AstSystemType astGetSourceSys_( AstSpecFrame *, int * ); -int astTestSourceSys_( AstSpecFrame *, int * ); -void astClearSourceSys_( AstSpecFrame *, int * ); -void astSetSourceSys_( AstSpecFrame *, AstSystemType, int * ); - -double astGetRestFreq_( AstSpecFrame *, int * ); -int astTestRestFreq_( AstSpecFrame *, int * ); -void astClearRestFreq_( AstSpecFrame *, int * ); -void astSetRestFreq_( AstSpecFrame *, double, int * ); - -double astGetRefRA_( AstSpecFrame *, int * ); -int astTestRefRA_( AstSpecFrame *, int * ); -void astClearRefRA_( AstSpecFrame *, int * ); -void astSetRefRA_( AstSpecFrame *, double, int * ); - -double astGetRefDec_( AstSpecFrame *, int * ); -int astTestRefDec_( AstSpecFrame *, int * ); -void astClearRefDec_( AstSpecFrame *, int * ); -void astSetRefDec_( AstSpecFrame *, double, int * ); - -double astGetSourceVel_( AstSpecFrame *, int * ); -int astTestSourceVel_( AstSpecFrame *, int * ); -void astClearSourceVel_( AstSpecFrame *, int * ); -void astSetSourceVel_( AstSpecFrame *, double, int * ); - -double astGetSpecOrigin_( AstSpecFrame *, int * ); -int astTestSpecOrigin_( AstSpecFrame *, int * ); -void astClearSpecOrigin_( AstSpecFrame *, int * ); -void astSetSpecOrigin_( AstSpecFrame *, double, int * ); - -int astGetAlignSpecOffset_( AstSpecFrame *, int * ); -int astTestAlignSpecOffset_( AstSpecFrame *, int * ); -void astClearAlignSpecOffset_( AstSpecFrame *, int * ); -void astSetAlignSpecOffset_( AstSpecFrame *, int, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckSpecFrame(this) astINVOKE_CHECK(SpecFrame,this,0) -#define astVerifySpecFrame(this) astINVOKE_CHECK(SpecFrame,this,1) - -/* Test class membership. */ -#define astIsASpecFrame(this) astINVOKE_ISA(SpecFrame,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -#define astSpecFrame astINVOKE(F,astSpecFrame_) -#else -#define astSpecFrame astINVOKE(F,astSpecFrameId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitSpecFrame(mem,size,init,vtab,name) \ -astINVOKE(O,astInitSpecFrame_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitSpecFrameVtab(vtab,name) astINVOKE(V,astInitSpecFrameVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadSpecFrame(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadSpecFrame_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) - -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ - -/* None. */ - -/* Interfaces to protected member functions. */ -/* ----------------------------------------- */ -/* Here we make use of astCheckSpecFrame to validate SpecFrame pointers - before use. This provides a contextual error report if a pointer to - the wrong sort of object is supplied. */ - -#define astGetRefPos(this,frm,lon,lat) astINVOKE(V,astGetRefPos_(astCheckSpecFrame(this),(frm==NULL?NULL:astCheckSkyFrame(frm)),lon,lat,STATUS_PTR)) -#define astSetRefPos(this,frm,lon,lat) astINVOKE(V,astSetRefPos_(astCheckSpecFrame(this),(frm==NULL?NULL:astCheckSkyFrame(frm)),lon,lat,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ - -#define astGetStdOfRest(this) astINVOKE(V,astGetStdOfRest_(astCheckSpecFrame(this),STATUS_PTR)) -#define astTestStdOfRest(this) astINVOKE(V,astTestStdOfRest_(astCheckSpecFrame(this),STATUS_PTR)) -#define astClearStdOfRest(this) astINVOKE(V,astClearStdOfRest_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetStdOfRest(this,value) astINVOKE(V,astSetStdOfRest_(astCheckSpecFrame(this),value,STATUS_PTR)) - -#define astGetAlignStdOfRest(this) astINVOKE(V,astGetAlignStdOfRest_(astCheckSpecFrame(this),STATUS_PTR)) -#define astTestAlignStdOfRest(this) astINVOKE(V,astTestAlignStdOfRest_(astCheckSpecFrame(this),STATUS_PTR)) -#define astClearAlignStdOfRest(this) astINVOKE(V,astClearAlignStdOfRest_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetAlignStdOfRest(this,value) astINVOKE(V,astSetAlignStdOfRest_(astCheckSpecFrame(this),value,STATUS_PTR)) - -#define astGetSourceVRF(this) astINVOKE(V,astGetSourceVRF_(astCheckSpecFrame(this),STATUS_PTR)) -#define astTestSourceVRF(this) astINVOKE(V,astTestSourceVRF_(astCheckSpecFrame(this),STATUS_PTR)) -#define astClearSourceVRF(this) astINVOKE(V,astClearSourceVRF_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetSourceVRF(this,value) astINVOKE(V,astSetSourceVRF_(astCheckSpecFrame(this),value,STATUS_PTR)) - -#define astGetSourceSys(this) astINVOKE(V,astGetSourceSys_(astCheckSpecFrame(this),STATUS_PTR)) -#define astTestSourceSys(this) astINVOKE(V,astTestSourceSys_(astCheckSpecFrame(this),STATUS_PTR)) -#define astClearSourceSys(this) astINVOKE(V,astClearSourceSys_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetSourceSys(this,value) astINVOKE(V,astSetSourceSys_(astCheckSpecFrame(this),value,STATUS_PTR)) - -#define astGetRestFreq(this) astINVOKE(V,astGetRestFreq_(astCheckSpecFrame(this),STATUS_PTR)) -#define astTestRestFreq(this) astINVOKE(V,astTestRestFreq_(astCheckSpecFrame(this),STATUS_PTR)) -#define astClearRestFreq(this) astINVOKE(V,astClearRestFreq_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetRestFreq(this,value) astINVOKE(V,astSetRestFreq_(astCheckSpecFrame(this),value,STATUS_PTR)) - -#define astGetRefRA(this) astINVOKE(V,astGetRefRA_(astCheckSpecFrame(this),STATUS_PTR)) -#define astTestRefRA(this) astINVOKE(V,astTestRefRA_(astCheckSpecFrame(this),STATUS_PTR)) -#define astClearRefRA(this) astINVOKE(V,astClearRefRA_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetRefRA(this,value) astINVOKE(V,astSetRefRA_(astCheckSpecFrame(this),value,STATUS_PTR)) - -#define astGetRefDec(this) astINVOKE(V,astGetRefDec_(astCheckSpecFrame(this),STATUS_PTR)) -#define astTestRefDec(this) astINVOKE(V,astTestRefDec_(astCheckSpecFrame(this),STATUS_PTR)) -#define astClearRefDec(this) astINVOKE(V,astClearRefDec_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetRefDec(this,value) astINVOKE(V,astSetRefDec_(astCheckSpecFrame(this),value,STATUS_PTR)) - -#define astGetSourceVel(this) astINVOKE(V,astGetSourceVel_(astCheckSpecFrame(this),STATUS_PTR)) -#define astTestSourceVel(this) astINVOKE(V,astTestSourceVel_(astCheckSpecFrame(this),STATUS_PTR)) -#define astClearSourceVel(this) astINVOKE(V,astClearSourceVel_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetSourceVel(this,value) astINVOKE(V,astSetSourceVel_(astCheckSpecFrame(this),value,STATUS_PTR)) - -#define astGetSpecOrigin(this) astINVOKE(V,astGetSpecOrigin_(astCheckSpecFrame(this),STATUS_PTR)) -#define astTestSpecOrigin(this) astINVOKE(V,astTestSpecOrigin_(astCheckSpecFrame(this),STATUS_PTR)) -#define astClearSpecOrigin(this) astINVOKE(V,astClearSpecOrigin_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetSpecOrigin(this,value) astINVOKE(V,astSetSpecOrigin_(astCheckSpecFrame(this),value,STATUS_PTR)) - -#define astClearAlignSpecOffset(this) astINVOKE(V,astClearAlignSpecOffset_(astCheckSpecFrame(this),STATUS_PTR)) -#define astGetAlignSpecOffset(this) astINVOKE(V,astGetAlignSpecOffset_(astCheckSpecFrame(this),STATUS_PTR)) -#define astSetAlignSpecOffset(this,value) astINVOKE(V,astSetAlignSpecOffset_(astCheckSpecFrame(this),value,STATUS_PTR)) -#define astTestAlignSpecOffset(this) astINVOKE(V,astTestAlignSpecOffset_(astCheckSpecFrame(this),STATUS_PTR)) - - - -#endif -#endif - - - - - diff --git a/ast/specmap.c b/ast/specmap.c deleted file mode 100644 index 48ada4e..0000000 --- a/ast/specmap.c +++ /dev/null @@ -1,4696 +0,0 @@ -/* -*class++ -* Name: -* SpecMap - -* Purpose: -* Sequence of spectral coordinate conversions. - -* Constructor Function: -c astSpecMap (also see astSpecAdd) -f AST_SPECMAP (also see AST_SPECADD) - -* Description: -* A SpecMap is a specialised form of Mapping which can be used to -* represent a sequence of conversions between standard spectral -* coordinate systems. -* -* When an SpecMap is first created, it simply performs a unit -c (null) Mapping. Using the astSpecAdd -f (null) Mapping. Using the AST_SPECADD -c function, a series of coordinate conversion steps may then be -f routine, a series of coordinate conversion steps may then be -* added. This allows multi-step conversions between a variety of -* spectral coordinate systems to be assembled out of a set of building -* blocks. -* -* Conversions are available to transform between standards of rest. -* Such conversions need to know the source position as an RA and DEC. -* This information can be supplied in the form of parameters for -* the relevant conversions, in which case the SpecMap is 1-dimensional, -* simply transforming the spectral axis values. This means that the -* same source position will always be used by the SpecMap. However, this -* may not be appropriate for an accurate description of a 3-D spectral -* cube, where changes of spatial position can produce significant -* changes in the Doppler shift introduced when transforming between -* standards of rest. For this situation, a 3-dimensional SpecMap can -* be created in which axes 2 and 3 correspond to the source RA and DEC -* The SpecMap simply copies values for axes 2 and 3 from input to -* output), but modifies axis 1 values (the spectral axis) appropriately. -* -* For details of the individual coordinate conversions available, -c see the description of the astSpecAdd function. -f see the description of the AST_SPECADD routine. - -* Inheritance: -* The SpecMap class inherits from the Mapping class. - -* Attributes: -* The SpecMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c In addition to those functions applicable to all Mappings, the -c following function may also be applied to all SpecMaps: -f In addition to those routines applicable to all Mappings, the -f following routine may also be applied to all SpecMaps: -* -c - astSpecAdd: Add a spectral coordinate conversion to an SpecMap -f - AST_SPECADD: Add a spectral coordinate conversion to an SpecMap - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 6-NOV-2002 (DSB): -* Original version. -* 14-JUL-2003 (DSB): -* Added checks for NAN values produced by transformation functions. -* 17-SEP-2003 (DSB): -* - Improve FRTOAW accuracy by iterating. -* - Changed Refrac to use algorithm given in FITS-WCS paper 3 -* version dated 21/9/03. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 10-MAY-2006 (DSB): -* Override astEqual. -* 15-NOV-2006 (DSB): -* Guard against division by zero when converting freq to wave in -* SystemChange. -* 18-JUN-2009 (DSB): -* Add OBSALT argument to TPF2HL and HLF2TP conversions. -* Change GEOLON/LAT to OBSLON/LAT for consistency with other -* classes. -* 2-OCT-2012 (DSB): -* Check for Infs as well as NaNs. -* 1-DEC-2016 (DSB): -* Added a "narg" argumeent to astSpecAdd. - -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS SpecMap - -/* Codes to identify spectral coordinate conversions. */ -#define AST__SPEC_NULL 0 /* Null value */ -#define AST__FRTOVL 1 /* Frequency to relativistic velocity */ -#define AST__VLTOFR 2 /* Relativistic velocity to Frequency */ -#define AST__ENTOFR 3 /* Energy to frequency */ -#define AST__FRTOEN 4 /* Frequency to energy */ -#define AST__WNTOFR 5 /* Wave number to frequency */ -#define AST__FRTOWN 6 /* Frequency to wave number */ -#define AST__WVTOFR 7 /* Wavelength (vacuum) to frequency */ -#define AST__FRTOWV 8 /* Frequency to wavelength (vacuum) */ -#define AST__AWTOFR 9 /* Wavelength (air) to frequency */ -#define AST__FRTOAW 10 /* Frequency to wavelength (air) */ -#define AST__VRTOVL 11 /* Radio to relativistic velocity */ -#define AST__VLTOVR 12 /* Relativistic to radio velocity */ -#define AST__VOTOVL 13 /* Optical to relativistic velocity */ -#define AST__VLTOVO 14 /* Relativistic to optical velocity */ -#define AST__ZOTOVL 15 /* Redshift to relativistic velocity */ -#define AST__VLTOZO 16 /* Relativistic velocity to redshift */ -#define AST__BTTOVL 17 /* Beta factor to relativistic velocity */ -#define AST__VLTOBT 18 /* Relativistic velocity to beta factor */ -#define AST__USF2HL 19 /* User-defined to heliocentric frequency */ -#define AST__HLF2US 20 /* Heliocentric to user-defined frequency */ -#define AST__TPF2HL 21 /* Topocentric to heliocentric frequency */ -#define AST__HLF2TP 22 /* Heliocentric to topocentric frequency */ -#define AST__GEF2HL 23 /* Geocentric to heliocentric frequency */ -#define AST__HLF2GE 24 /* Heliocentric to geocentric frequency */ -#define AST__BYF2HL 25 /* Barycentric to heliocentric frequency */ -#define AST__HLF2BY 26 /* Heliocentric to barycentric frequency */ -#define AST__LKF2HL 27 /* LSRK to heliocentric frequency */ -#define AST__HLF2LK 28 /* Heliocentric to LSRK frequency */ -#define AST__LDF2HL 29 /* LSRD to heliocentric frequency */ -#define AST__HLF2LD 30 /* Heliocentric to LSRD frequency */ -#define AST__LGF2HL 31 /* Local group to heliocentric frequency */ -#define AST__HLF2LG 32 /* Heliocentric to local group frequency */ -#define AST__GLF2HL 33 /* Galactic to heliocentric frequency */ -#define AST__HLF2GL 34 /* Heliocentric to galactic frequency */ - -/* Maximum number of arguments required by a conversion. */ -#define MAX_ARGS 7 - -/* The alphabet (used for generating keywords for arguments). */ -#define ALPHABET "abcdefghijklmnopqrstuvwxyz" - -/* Angle conversion */ -#define PI 3.141592653589793238462643 -#define PIBY2 (PI/2.0) -#define D2R (PI/180.0) -#define R2D (180.0/PI) - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "pal.h" /* SLALIB interface */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ -#include "unitmap.h" /* Unit (null) Mappings */ -#include "specmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double (* parent_rate)( AstMapping *, double *, int, int, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(SpecMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SpecMap,Class_Init) -#define class_vtab astGLOBAL(SpecMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSpecMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* Structure to hold parameters and intermediate values describing a - reference frame */ -typedef struct FrameDef { - double obsalt; /* Observers geodetic altitude (m) */ - double obslat; /* Observers geodetic latitude (rads) */ - double obslon; /* Observers geodetic longitude (rads, +ve east) */ - double epoch; /* Julian epoch of observation */ - double refdec; /* RA of reference point (FK5 J2000) */ - double refra; /* DEC of reference point (FK5 J2000) */ - double veluser; /* Heliocentric velocity of user-defined system (m/s) */ - double last; /* Local apparent sideral time */ - double amprms[21]; /* Mean to apparent parameters */ - double vuser[3]; /* Used-defined velocity as a FK5 J2000 vector */ - double dvh[3]; /* Earth-sun velocity */ - double dvb[3]; /* Barycentre-sun velocity */ -} FrameDef; - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSpecMap *astSpecMapId_( int, int, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *CvtString( int, const char **, int *, int *, int *, int *, const char *[ MAX_ARGS ], int * ); -static double BaryVel( double, double, FrameDef *, int * ); -static double GalVel( double, double, FrameDef *, int * ); -static double GeoVel( double, double, FrameDef *, int * ); -static double LgVel( double, double, FrameDef *, int * ); -static double LsrdVel( double, double, FrameDef *, int * ); -static double LsrkVel( double, double, FrameDef *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static double Refrac( double, int * ); -static double Rverot( double, double, double, double, double, int * ); -static double TopoVel( double, double, FrameDef *, int * ); -static double UserVel( double, double, FrameDef *, int * ); -static int CvtCode( const char *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int FrameChange( int, int, double *, double *, double *, double *, int, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int SystemChange( int, int, double *, double *, int, int * ); -static void AddSpecCvt( AstSpecMap *, int, int, const double *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void SpecAdd( AstSpecMap *, const char *, int, const double[], int * ); - -static int GetObjSize( AstObject *, int * ); -/* Member functions. */ -/* ================= */ -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two SpecMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* SpecMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two SpecMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a SpecMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the SpecMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSpecMap *that; - AstSpecMap *this; - const char *argdesc[ MAX_ARGS ]; - const char *comment; - int argdec; - int argra; - int i, j; - int nargs; - int nin; - int nout; - int result; - int szargs; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two SpecMap structures. */ - this = (AstSpecMap *) this_object; - that = (AstSpecMap *) that_object; - -/* Check the second object is a SpecMap. We know the first is a - SpecMap since we have arrived at this implementation of the virtual - function. */ - if( astIsASpecMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two SpecMaps differ, it may still be possible - for them to be equivalent. First compare the SpecMaps if their Invert - flags are the same. In this case all the attributes of the two SpecMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - if( this->ncvt == that->ncvt ) { - result = 1; - for( i = 0; i < this->ncvt && result; i++ ) { - if( this->cvttype[ i ] != that->cvttype[ i ] ) { - result = 0; - } else { - CvtString( this->cvttype[ i ], &comment, &argra, - &argdec, &nargs, &szargs, argdesc, status ); - for( j = 0; j < nargs; j++ ) { - if( !astEQUAL( this->cvtargs[ i ][ j ], - that->cvtargs[ i ][ j ] ) ){ - result = 0; - break; - } - } - } - } - } - -/* If the Invert flags for the two SpecMaps differ, the attributes of the two - SpecMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a SpecMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* SpecMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied SpecMap, -* in bytes. - -* Parameters: -* this -* Pointer to the SpecMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSpecMap *this; /* Pointer to SpecMap structure */ - int result; /* Result value to return */ - int cvt; /* Loop counter for coordinate conversions */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the SpecMap structure. */ - this = (AstSpecMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - for ( cvt = 0; cvt < this->ncvt; cvt++ ) { - result += astTSizeOf( this->cvtargs[ cvt ] ); - } - - result += astTSizeOf( this->cvtargs ); - result += astTSizeOf( this->cvttype ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void AddSpecCvt( AstSpecMap *this, int cvttype, int narg, - const double *args, int *status ) { -/* -* Name: -* AddSpecCvt - -* Purpose: -* Add a coordinate conversion step to an SpecMap. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* void AddSpecCvt( AstSpecMap *this, int cvttype, int narg, -* const double *args ) - -* Class Membership: -* SpecMap member function. - -* Description: -* This function allows one of the supported spectral coordinate -* conversions to be appended to a SpecMap. When a SpecMap is first -* created (using astSpecMap), it simply performs a unit mapping. By -* using AddSpecCvt repeatedly, a series of coordinate conversions may -* then be specified which the SpecMap will subsequently perform in -* sequence. This allows a complex coordinate conversion to be -* assembled out of the basic building blocks. The SpecMap will also -* perform the inverse coordinate conversion (applying the individual -* conversion steps in reverse) if required. - -* Parameters: -* this -* Pointer to the SpecMap. -* cvttype -* A code to identify which spectral coordinate conversion is to be -* appended. See the "Coordinate Conversions" section for details -* of those available. -* narg -* The number of argument values supplied in "args". -* args -* Pointer to an array of double containing the argument values -* required to fully specify the required coordinate -* conversion. The number of arguments depends on the conversion -* (see the "Coordinate Conversions" section for details). This -* value is ignored and may be NULL if no arguments are required. - -* Returned Value: -* void. - -* Coordinate Conversions: -* The following values may be supplied for the "cvttype" parameter -* in order to specify the coordinate conversion to be performed. -* The argument(s) required to fully specify each conversion are -* indicated in parentheses after each value, and described at the end -* of the list. Values for these should be given in the array pointed -* at by "args". -* -* AST__FRTOVL( RF ) -* Convert frequency to relativistic velocity. -* AST__VLTOFR( RF ) -* Convert relativistic velocity to Frequency. -* AST__ENTOFR -* Convert energy to frequency. -* AST__FRTOEN -* Convert frequency to energy. -* AST__WNTOFR -* Convert wave number to frequency. -* AST__FRTOWN -* Convert frequency to wave number. -* AST__WVTOFR -* Convert wavelength (vacuum) to frequency. -* AST__FRTOWV -* Convert frequency to wavelength (vacuum). -* AST__AWTOFR -* Convert wavelength (air) to frequency. -* AST__FRTOAW -* Convert frequency to wavelength (air). -* AST__VRTOVL -* Convert radio to relativistic velocity. -* AST__VLTOVR -* Convert relativistic to radio velocity. -* AST__VOTOVL -* Convert optical to relativistic velocity. -* AST__VLTOVO -* Convert relativistic to optical velocity. -* AST__ZOTOVL -* Convert redshift to relativistic velocity. -* AST__VLTOZO -* Convert relativistic velocity to redshift. -* AST__BTTOVL -* Convert beta factor to relativistic velocity. -* AST__VLTOBT -* Convert relativistic velocity to beta factor. -* AST_USF2HL( VOFF, RA, DEC ) -* Convert frequency from a user-defined reference frame to -* heliocentric. -* AST__HLF2US( VOFF, RA, DEC ) -* Convert frequency from heliocentric reference frame to -* user-defined. -* AST__TPF2HL( OBSLON, OBSLAT, OBSALT, EPOCH, RA, DEC ) -* Convert from Topocentric to heliocentric frequency -* AST__HLF2TP( OBSLON, OBSLAT, OBSALT, EPOCH, RA, DEC ) -* Convert from Heliocentric to topocentric frequency. -* AST__GEF2HL( EPOCH, RA, DEC ) -* Convert from Geocentric to heliocentric frequency. -* AST__HLF2GE( EPOCH, RA, DEC ) -* Convert from Heliocentric to geocentric frequency. -* AST__BYF2HL( EPOCH, RA, DEC ) -* Convert from Barycentric to heliocentric frequency. -* AST__HLF2BY( EPOCH, RA, DEC ) -* Convert from Heliocentric to barycentric frequency. -* AST__LKF2HL( RA, DEC ) -* Convert from LSRK to heliocentric frequency. -* AST__HLF2LK( RA, DEC ) -* Convert from Heliocentric to LSRK frequency. -* AST__LDF2HL( RA, DEC ) -* Convert from LSRD to heliocentric frequency. -* AST__HLF2LD( RA, DEC ) -* Convert from Heliocentric to LSRD frequency. -* AST__LGF2HL( RA, DEC ) -* Convert from Local group to heliocentric frequency. -* AST__HLF2LG( RA, DEC ) -* Convert from Heliocentric to local group frequency. -* AST__GLF2HL( RA, DEC ) -* Convert from Galactic to heliocentric frequency. -* AST__HLF2GL( RA, DEC ) -* Convert from Heliocentric to galactic frequency. -* -* The units for the values processed by the above conversions are as -* follows: -* -* - all velocities: metres per second. -* - frequency: Hertz. -* - all wavelengths: metres. -* - energy: Joules. -* - wave number: cycles per metre. -* -* The arguments used in the above conversions are as follows: -* -* - RF: Rest frequency (Hz). -* - OBSALT: Geodetic altitude of observer (IAU 1975, metres). -* - OBSLAT: Geodetic latitude of observer (IAU 1975, radians). -* - OBSLON: Longitude of observer (radians, positive eastwards). -* - EPOCH: Epoch of observation (UT1 expressed as a Modified Julian Date). -* - RA: Right Ascension of source (radians, FK5 J2000). -* - DEC: Declination of source (radians, FK5 J2000). -* - VOFF: Velocity of the user-defined reference frame, towards the -* position given by RA and DEC, measured in the heliocentric -* reference frame. -* -* If the SpecMap is 3-dimensional, source positions are provided by the -* values supplied to inputs 2 and 3 of the SpecMap (which are simply -* copied to outputs 2 and 3). Note, usable values are still required -* for the RA and DEC arguments in order to define the "user-defined" -* reference frame used by USF2HL and HLF2US. However, AST__BAD can be -* supplied for RA and DEC if the user-defined reference frame is not -* required. - -* Notes: -* - The specified conversion is appended only if the SpecMap's -* Invert attribute is zero. If it is non-zero, this function -* effectively prefixes the inverse of the conversion specified -* instead. -*/ - -/* Local Variables: */ - const char *argdesc[ MAX_ARGS ]; /* Pointers to argument descriptions */ - const char *comment; /* Pointer to comment string */ - const char *cvt_string; /* Pointer to conversion type string */ - int argdec; /* Index of DEC argument */ - int argra; /* Index of RA argument */ - int i; /* Argument index */ - int nargs; /* Number of user-supplied arguments */ - int ncvt; /* Number of coordinate conversions */ - int szargs; /* Size of arguments array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the coordinate conversion type and obtain the number of - required user-supplied arguments, and the size of the array in which - to put the user-supplied arguments (the array meay leave room after - the user-supplied arguments for various useful pre-calculated values). */ - cvt_string = CvtString( cvttype, &comment, &argra, &argdec, &nargs, - &szargs, argdesc, status ); - -/* If the coordinate conversion type was not valid, then report an - error. */ - if ( astOK && !cvt_string ) { - astError( AST__SPCIN, "AddSpecCvt(%s): Invalid spectral coordinate " - "conversion type (%d).", status, astGetClass( this ), - (int) cvttype ); - } - -/* If the number of supplied arguments is incorrect, then report an error. */ - if ( astOK && nargs != narg ) { - astError( AST__TIMIN, "AddSpecCvt(%s): Invalid no. of arguments for spectral " - "coordinate conversion type %d - %d supplied, %d required.", - status, astGetClass( this ), (int) cvttype, narg, nargs ); - } - -/* Note the number of coordinate conversions already stored in the SpecMap. */ - if ( astOK ) { - ncvt = this->ncvt; - -/* Extend the array of conversion types and the array of pointers to - their argument lists to accommodate the new one. */ - this->cvttype = (int *) astGrow( this->cvttype, ncvt + 1, - sizeof( int ) ); - this->cvtargs = (double **) astGrow( this->cvtargs, ncvt + 1, - sizeof( double * ) ); - -/* If OK, allocate memory and store a copy of the argument list, - putting a pointer to the copy into the SpecMap. */ - if ( astOK ) { - this->cvtargs[ ncvt ] = astStore( NULL, args, - sizeof( double ) * (size_t) szargs ); - } - -/* Store the conversion type and increment the conversion count. Also put - AST__BAD in any elements of the argument array which are beyond the - end of the user-supplied arguments. These will be used to hold - intermediate values calculated on the basis of the user-supplied - arguments. */ - if ( astOK ) { - this->cvttype[ ncvt ] = cvttype; - this->ncvt++; - for( i = nargs; i < szargs; i++ ) this->cvtargs[ ncvt ][ i ] = AST__BAD; - } - } -} - -static double BaryVel( double ra, double dec, FrameDef *def, int *status ) { -/* -* Name: -* BaryVel - -* Purpose: -* Find the velocity of the earth-sun barycentre away from the source. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double BaryVel( double ra, double dec, FrameDef *def, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function finds the component of the velocity of the earth-sun -* barycentre away from a specified source position, at a given epoch, in -* the frame of rest of the centre of the Sun. - -* Parameters: -* ra -* The RA (rads, FK5 J2000) of the source. -* dec -* The Dec (rads, FK5 J2000) of the source. -* def -* Pointer to a FrameDef structure which holds the parameters which -* define the frame, together with cached intermediate results. -* status -* Pointer to the inherited status variable. - -* Returns: -* The component of the frame's velocity away from the position given by -* "ra" and "dec", in m/s, measured within the Heliographic frame of -* rest. Zero is returned if an error has already occurred. - -*/ - -/* Local Variables: */ - double dpb[ 3 ]; /* Barycentric earth position vector */ - double dph[ 3 ]; /* Heliocentric earth position vector */ - double dvh[ 3 ]; /* Heliocentric earth velocity vector */ - double v[ 3 ]; /* Source direction vector */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Get the Cartesian vector towards the source, in the Cartesian FK5 - J2000 system. */ - palDcs2c( ra, dec, v ); - -/* If not already done so, get the Earth/Sun velocity and position vectors in - the same system. Speed is returned in units of AU/s. Store in the supplied - frame definition structure. */ - if( def->dvb[ 0 ] == AST__BAD ) { - palEvp( def->epoch, 2000.0, def->dvb, dpb, dvh, dph ); - -/* Change the barycentric velocity of the earth into the heliocentric - velocity of the barycentre. */ - def->dvb[ 0 ] = dvh[ 0 ] - def->dvb[ 0 ]; - def->dvb[ 1 ] = dvh[ 1 ] - def->dvb[ 1 ]; - def->dvb[ 2 ] = dvh[ 2 ] - def->dvb[ 2 ]; - } - -/* Return the component away from the source, of the velocity of the - barycentre relative to the sun (in m/s). */ - return -palDvdv( v, def->dvb )*149.597870E9; - -} - -static int CvtCode( const char *cvt_string, int *status ) { -/* -* Name: -* CvtCode - -* Purpose: -* Convert a conversion type from a string representation to a code value. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* int CvtCode( const char *cvt_string, int *status ) - -* Class Membership: -* SpecMap member function. - -* Description: -* This function accepts a string used to repersent one of the -* SpecMap coordinate conversions and converts it into a code -* value for internal use. - -* Parameters: -* cvt_string -* Pointer to a constant null-terminated string representing a -* spectral coordinate conversion. This is case sensitive and should -* contain no unnecessary white space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The equivalent conversion code. If the string was not -* recognised, the code AST__SPEC_NULL is returned, without error. - -* Notes: -* - A value of AST__SPEC_NULL will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - int result; /* Result value to return */ - -/* Initialise. */ - result = AST__SPEC_NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Test the string against each recognised value in turn and assign - the result. */ - if ( astChrMatch( cvt_string, "FRTOVL" ) ) { - result = AST__FRTOVL; - - } else if ( astChrMatch( cvt_string, "VLTOFR" ) ) { - result = AST__VLTOFR; - - } else if ( astChrMatch( cvt_string, "VLTOFR" ) ) { - result = AST__VLTOFR; - - } else if ( astChrMatch( cvt_string, "ENTOFR" ) ) { - result = AST__ENTOFR; - - } else if ( astChrMatch( cvt_string, "FRTOEN" ) ) { - result = AST__FRTOEN; - - } else if ( astChrMatch( cvt_string, "WNTOFR" ) ) { - result = AST__WNTOFR; - - } else if ( astChrMatch( cvt_string, "FRTOWN" ) ) { - result = AST__FRTOWN; - - } else if ( astChrMatch( cvt_string, "WVTOFR" ) ) { - result = AST__WVTOFR; - - } else if ( astChrMatch( cvt_string, "FRTOWV" ) ) { - result = AST__FRTOWV; - - } else if ( astChrMatch( cvt_string, "AWTOFR" ) ) { - result = AST__AWTOFR; - - } else if ( astChrMatch( cvt_string, "FRTOAW" ) ) { - result = AST__FRTOAW; - - } else if ( astChrMatch( cvt_string, "VRTOVL" ) ) { - result = AST__VRTOVL; - - } else if ( astChrMatch( cvt_string, "VLTOVR" ) ) { - result = AST__VLTOVR; - - } else if ( astChrMatch( cvt_string, "VOTOVL" ) ) { - result = AST__VOTOVL; - - } else if ( astChrMatch( cvt_string, "VLTOVO" ) ) { - result = AST__VLTOVO; - - } else if ( astChrMatch( cvt_string, "ZOTOVL" ) ) { - result = AST__ZOTOVL; - - } else if ( astChrMatch( cvt_string, "VLTOZO" ) ) { - result = AST__VLTOZO; - - } else if ( astChrMatch( cvt_string, "BTTOVL" ) ) { - result = AST__BTTOVL; - - } else if ( astChrMatch( cvt_string, "VLTOBT" ) ) { - result = AST__VLTOBT; - - } else if ( astChrMatch( cvt_string, "USF2HL" ) ) { - result = AST__USF2HL; - - } else if ( astChrMatch( cvt_string, "HLF2US" ) ) { - result = AST__HLF2US; - - } else if ( astChrMatch( cvt_string, "TPF2HL" ) ) { - result = AST__TPF2HL; - - } else if ( astChrMatch( cvt_string, "HLF2TP" ) ) { - result = AST__HLF2TP; - - } else if ( astChrMatch( cvt_string, "GEF2HL" ) ) { - result = AST__GEF2HL; - - } else if ( astChrMatch( cvt_string, "HLF2GE" ) ) { - result = AST__HLF2GE; - - } else if ( astChrMatch( cvt_string, "BYF2HL" ) ) { - result = AST__BYF2HL; - - } else if ( astChrMatch( cvt_string, "HLF2BY" ) ) { - result = AST__HLF2BY; - - } else if ( astChrMatch( cvt_string, "LKF2HL" ) ) { - result = AST__LKF2HL; - - } else if ( astChrMatch( cvt_string, "HLF2LK" ) ) { - result = AST__HLF2LK; - - } else if ( astChrMatch( cvt_string, "LDF2HL" ) ) { - result = AST__LDF2HL; - - } else if ( astChrMatch( cvt_string, "HLF2LD" ) ) { - result = AST__HLF2LD; - - } else if ( astChrMatch( cvt_string, "LGF2HL" ) ) { - result = AST__LGF2HL; - - } else if ( astChrMatch( cvt_string, "HLF2LG" ) ) { - result = AST__HLF2LG; - - } else if ( astChrMatch( cvt_string, "GLF2HL" ) ) { - result = AST__GLF2HL; - - } else if ( astChrMatch( cvt_string, "HLF2GL" ) ) { - result = AST__HLF2GL; - - } - -/* Return the result. */ - return result; -} - -static const char *CvtString( int cvt_code, const char **comment, - int *argra, int *argdec, int *nargs, int *szargs, - const char *arg[ MAX_ARGS ], int *status ) { -/* -* Name: -* CvtString - -* Purpose: -* Convert a conversion type from a code value to a string representation. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* const char *CvtString( int cvt_code, const char **comment, -* int *argra, int *argdec, int *nargs, -* int *szargs, const char *arg[ MAX_ARGS ], int *status ) - -* Class Membership: -* SpecMap member function. - -* Description: -* This function accepts a code value used to represent one of the -* SpecMap coordinate conversions and converts it into an -* equivalent string representation. It also returns a descriptive -* comment and information about the arguments required in order to -* perform the conversion. - -* Parameters: -* cvt_code -* The conversion code. -* comment -* Address of a location to return a pointer to a constant -* null-terminated string containing a description of the -* conversion. -* argra -* Address of an int in which to return the index of the argument -* corresponding to the source RA. Returned equal to -1 if the -* conversion does not have a source RA argument. -* argdec -* Address of an int in which to return the index of the argument -* corresponding to the source DEC. Returned equal to -1 if the -* conversion does not have a source DEC argument. -* nargs -* Address of an int in which to return the number of arguments -* required from the user in order to perform the conversion (may -* be zero). -* szargs -* Address of an int in which to return the number of arguments -* associated with the conversion. This may be bigger than "nargs" -* if the conversion can pre-calculate useful values on the basis -* of the user-supplied values. Such precalculated values are -* stored after the last user-supplied argument. -* arg -* An array in which to return a pointer to a constant -* null-terminated string for each argument (above) containing a -* description of what each argument represents. This includes both -* user-supplied arguments and pre-calculated values. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string representation of -* the conversion code value supplied. If the code supplied is not -* valid, a NULL pointer will be returned, without error. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Result pointer to return */ - -/* Initialise the returned values. */ - *comment = NULL; - *nargs = 0; - *argra = -1; - *argdec = -1; - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Test for each valid code value in turn and assign the appropriate - return values. */ - switch ( cvt_code ) { - - case AST__FRTOVL: - *comment = "Convert frequency to rel. velocity"; - result = "FRTOVL"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "Rest frequency (Hz)"; - break; - - case AST__VLTOFR: - *comment = "Convert rel. velocity to frequency"; - result = "VLTOFR"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "Rest frequency (Hz)"; - break; - - case AST__ENTOFR: - *comment = "Convert energy to frequency"; - result = "ENTOFR"; - *nargs = 0; - *szargs = 0; - break; - - case AST__FRTOEN: - *comment = "Convert frequency to energy"; - result = "FRTOEN"; - *nargs = 0; - *szargs = 0; - break; - - case AST__WNTOFR: - *comment = "Convert wave number to frequency"; - result = "WNTOFR"; - *nargs = 0; - *szargs = 0; - break; - - case AST__FRTOWN: - *comment = "Convert frequency to wave number"; - result = "FRTOWN"; - *nargs = 0; - *szargs = 0; - break; - - case AST__WVTOFR: - *comment = "Convert wavelength (vacuum) to frequency"; - result = "WVTOFR"; - *nargs = 0; - *szargs = 0; - break; - - case AST__FRTOWV: - *comment = "Convert frequency to wavelength (vacuum)"; - result = "FRTOWV"; - *nargs = 0; - *szargs = 0; - break; - - case AST__AWTOFR: - *comment = "Convert wavelength (air) to frequency"; - result = "AWTOFR"; - *nargs = 0; - *szargs = 0; - break; - - case AST__FRTOAW: - *comment = "Convert frequency to wavelength (air)"; - result = "FRTOAW"; - *nargs = 0; - *szargs = 0; - break; - - case AST__VRTOVL: - *comment = "Convert radio to rel. velocity"; - result = "VRTOVL"; - *nargs = 0; - *szargs = 0; - break; - - case AST__VLTOVR: - *comment = "Convert relativistic to radio velocity"; - result = "VLTOVR"; - *nargs = 0; - *szargs = 0; - break; - - case AST__VOTOVL: - *comment = "Convert optical to rel. velocity"; - result = "VOTOVL"; - *nargs = 0; - *szargs = 0; - break; - - case AST__VLTOVO: - *comment = "Convert relativistic to optical velocity"; - result = "VLTOVO"; - *nargs = 0; - *szargs = 0; - break; - - case AST__ZOTOVL: - *comment = "Convert redshift to rel. velocity"; - result = "ZOTOVL"; - *nargs = 0; - *szargs = 0; - break; - - case AST__VLTOZO: - *comment = "Convert rel. velocity to redshift"; - result = "VLTOZO"; - *nargs = 0; - *szargs = 0; - break; - - case AST__BTTOVL: - *comment = "Convert beta factor to rel. velocity"; - result = "BTTOVL"; - *nargs = 0; - *szargs = 0; - break; - - case AST__VLTOBT: - *comment = "Convert rel. velocity to beta factor"; - result = "VLTOBT"; - *nargs = 0; - *szargs = 0; - break; - - case AST__USF2HL: - *comment = "Convert from user-defined to heliocentric frequency"; - result = "USF2HL"; - *argra = 1; - *argdec = 2; - *nargs = 3; - *szargs = 4; - arg[ 0 ] = "Velocity offset (m/s)"; - arg[ 1 ] = "RA of source (FK5 J2000, radians)"; - arg[ 2 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 3 ] = "Frequency correction factor"; - break; - - case AST__HLF2US: - *comment = "Convert from heliocentric to user-defined frequency"; - result = "HLF2US"; - *argra = 1; - *argdec = 2; - *nargs = 3; - *szargs = 4; - arg[ 0 ] = "Velocity offset (m/s)"; - arg[ 1 ] = "RA of source (FK5 J2000, radians)"; - arg[ 2 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 3 ] = "Frequency correction factor"; - break; - - case AST__TPF2HL: - *comment = "Convert from Topocentric to heliocentric frequency"; - result = "TPF2HL"; - *argra = 4; - *argdec = 5; - *nargs = 6; - *szargs = 7; - arg[ 0 ] = "Longitude (positive eastwards, radians)"; - arg[ 1 ] = "Latitude (geodetic, radians)"; - arg[ 2 ] = "Altitude (geodetic, metres)"; - arg[ 3 ] = "UT1 epoch of observaton (Modified Julian Date)"; - arg[ 4 ] = "RA of source (FK5 J2000, radians)"; - arg[ 5 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 6 ] = "Frequency correction factor"; - break; - - case AST__HLF2TP: - *comment = "Convert from Heliocentric to topocentric frequency"; - result = "HLF2TP"; - *argra = 4; - *argdec = 5; - *nargs = 6; - *szargs = 7; - arg[ 0 ] = "Longitude (positive eastwards, radians)"; - arg[ 1 ] = "Latitude (geodetic, radians)"; - arg[ 2 ] = "Altitude (geodetic, metres)"; - arg[ 3 ] = "UT1 epoch of observaton (Modified Julian Date)"; - arg[ 4 ] = "RA of source (FK5 J2000, radians)"; - arg[ 5 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 6 ] = "Frequency correction factor"; - break; - - case AST__GEF2HL: - *comment = "Convert from Geocentric to heliocentric frequency"; - result = "GEF2HL"; - *argra = 1; - *argdec = 2; - *nargs = 3; - *szargs = 4; - arg[ 0 ] = "UT1 epoch of observaton (Modified Julian Date)"; - arg[ 1 ] = "RA of source (FK5 J2000, radians)"; - arg[ 2 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 3 ] = "Frequency correction factor"; - break; - - case AST__HLF2GE: - *comment = "Convert from Heliocentric to geocentric frequency"; - result = "HLF2GE"; - *argra = 1; - *argdec = 2; - *nargs = 3; - *szargs = 4; - arg[ 0 ] = "UT1 epoch of observaton (Modified Julian Date)"; - arg[ 1 ] = "RA of source (FK5 J2000, radians)"; - arg[ 2 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 3 ] = "Frequency correction factor"; - break; - - case AST__BYF2HL: - *comment = "Convert from Barycentric to heliocentric frequency"; - result = "BYF2HL"; - *argra = 1; - *argdec = 2; - *nargs = 3; - *szargs = 4; - arg[ 0 ] = "UT1 epoch of observaton (Modified Julian Date)"; - arg[ 1 ] = "RA of source (FK5 J2000, radians)"; - arg[ 2 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 3 ] = "Frequency correction factor"; - break; - - case AST__HLF2BY: - *comment = "Convert from Heliocentric to barycentric frequency"; - result = "HLF2BY"; - *argra = 1; - *argdec = 2; - *nargs = 3; - *szargs = 4; - arg[ 0 ] = "UT1 epoch of observaton (Modified Julian Date)"; - arg[ 1 ] = "RA of source (FK5 J2000, radians)"; - arg[ 2 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 3 ] = "Frequency correction factor"; - break; - - case AST__LKF2HL: - *comment = "Convert from LSRK to heliocentric frequency"; - result = "LKF2HL"; - *argra = 0; - *argdec = 1; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "RA of source (FK5 J2000, radians)"; - arg[ 1 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 2 ] = "Frequency correction factor"; - break; - - case AST__HLF2LK: - *comment = "Convert from Heliocentric to LSRK frequency"; - result = "HLF2LK"; - *argra = 0; - *argdec = 1; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "RA of source (FK5 J2000, radians)"; - arg[ 1 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 2 ] = "Frequency correction factor"; - break; - - case AST__LDF2HL: - *comment = "Convert from LSRD to heliocentric frequency"; - result = "LDF2HL"; - *argra = 0; - *argdec = 1; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "RA of source (FK5 J2000, radians)"; - arg[ 1 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 2 ] = "Frequency correction factor"; - break; - - case AST__HLF2LD: - *comment = "Convert from Heliocentric to LSRD frequency"; - result = "HLF2LD"; - *argra = 0; - *argdec = 1; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "RA of source (FK5 J2000, radians)"; - arg[ 1 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 2 ] = "Frequency correction factor"; - break; - - case AST__LGF2HL: - *comment = "Convert from Local group to heliocentric frequency"; - result = "LGF2HL"; - *argra = 0; - *argdec = 1; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "RA of source (FK5 J2000, radians)"; - arg[ 1 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 2 ] = "Frequency correction factor"; - break; - - case AST__HLF2LG: - *comment = "Convert from Heliocentric to local group frequency"; - result = "HLF2LG"; - *argra = 0; - *argdec = 1; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "RA of source (FK5 J2000, radians)"; - arg[ 1 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 2 ] = "Frequency correction factor"; - break; - - case AST__GLF2HL: - *comment = "Convert from Galactic to heliocentric frequency"; - result = "GLF2HL"; - *argra = 0; - *argdec = 1; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "RA of source (FK5 J2000, radians)"; - arg[ 1 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 2 ] = "Frequency correction factor"; - break; - - case AST__HLF2GL: - *comment = "Convert from Heliocentric to galactic frequency"; - *argra = 0; - *argdec = 1; - result = "HLF2GL"; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "RA of source (FK5 J2000, radians)"; - arg[ 1 ] = "DEC of source (FK5 J2000, radians)"; - arg[ 2 ] = "Frequency correction factor"; - break; - - } - -/* Return the result. */ - return result; -} - -static int FrameChange( int cvt_code, int np, double *ra, double *dec, double *freq, - double *args, int forward, int *status ){ -/* -* Name: -* FrameChange - -* Purpose: -* Apply a doppler shift caused by a change of reference frame. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* int FrameChange( int cvt_code, int np, double *ra, double *dec, -* double *freq, double *args, int forward, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function modifies the supplied frequency values in order to -* apply a doppler shift caused by a change of the observers rest-frame. - -* Parameters: -* cvt_code -* A code indicating the conversion to be applied. If the code does -* not correspond to a change of rest-frame, then the supplied -* frequencies are left unchanged and zero is returned as the -* function value. -* np -* The number of frequency values to transform. -* ra -* Pointer to an array of "np" RA (J2000 FK5) values at which the -* "np" frequencies are observed. These are unchanged on exit. If a -* NULL pointer is supplied, then all frequencies are assumed to be -* observed at the single RA value given by "refra" -* dec -* Pointer to an array of "np" Dec (J2000 FK5) values at which the -* "np" frequencies are observed. These are unchanged on exit. If a -* NULL pointer is supplied, then all frequencies are assumed to be -* observed at the single Dec value given by "refdec" -* freq -* Pointer to an array of "np" frequency values, measured in the -* input rest-frame. These are modified on return to hold the -* corresponding values measured in the output rest-frame. -* args -* Pointer to an array holding the conversion arguments. The number -* of arguments expected depends on the particular conversion being -* used. -* forward -* Should the conversion be applied in the forward or inverse -* direction? Non-zero for forward, zero for inverse. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the supplied conversion code corresponds to a change of -* reference frame. Zoer otherwise (in which case the upplied values -* will not have been changed). - -* Notes: -* - The "args" array contains RA and DEC values which give the "source" -* position (FK5 J2000). If a NULL value is supplied for the "ra" -* parameter, then these args define the position of all the frequency -* values. In addition they also define the direction of motion of -* the "user-defined" rest-frame (see "veluser"). Thus they should still -* be supplied even if "ra" is NULL. - -*/ - -/* Local Variables: */ - FrameDef def; /* Structure holding frame parameters */ - double (* cvtFunc)( double, double, FrameDef *, int * ); /* Pointer to conversion function */ - double *fcorr; /* Pointer to frequency correction factor */ - double *pdec; /* Pointer to next Dec value */ - double *pf; /* Pointer to next frequency value */ - double *pra; /* Pointer to next RA value */ - double factor; /* Frequency correction factor */ - double s; /* Velocity correction (m/s) */ - int i; /* Loop index */ - int result; /* Returned value */ - int sign; /* Sign for velocity correction */ - -/* Check inherited status. */ - if( !astOK ) return 0; - -/* Initialise */ - cvtFunc = NULL; - fcorr = NULL; - sign = 0; - -/* Set the return value to indicate that the supplied conversion code - represents a change of rest-frame. */ - result = 1; - -/* Initialise a structure which stores parameters which define the - transformation. */ - def.obsalt = AST__BAD; - def.obslat = AST__BAD; - def.obslon = AST__BAD; - def.epoch = AST__BAD; - def.refdec = AST__BAD; - def.refra = AST__BAD; - def.veluser = AST__BAD; - def.last = AST__BAD; - def.amprms[ 0 ] = AST__BAD; - def.vuser[ 0 ] = AST__BAD; - def.dvh[ 0 ] = AST__BAD; - def.dvb[ 0 ] = AST__BAD; - -/* Test for each rest-frame code value in turn and assign the appropriate - values. */ - switch ( cvt_code ) { - - case AST__USF2HL: - cvtFunc = UserVel; - def.veluser = args[ 0 ]; - def.refra = args[ 1 ]; - def.refdec = args[ 2 ]; - fcorr = args + 3; - sign = -1; - break; - - case AST__HLF2US: - cvtFunc = UserVel; - def.veluser = args[ 0 ]; - def.refra = args[ 1 ]; - def.refdec = args[ 2 ]; - fcorr = args + 3; - sign = +1; - break; - - case AST__TPF2HL: - cvtFunc = TopoVel; - def.obslon = args[ 0 ]; - def.obslat = args[ 1 ]; - def.obsalt = args[ 2 ]; - def.epoch = args[ 3 ]; - def.refra = args[ 4 ]; - def.refdec = args[ 5 ]; - fcorr = args + 6; - sign = -1; - break; - - case AST__HLF2TP: - cvtFunc = TopoVel; - def.obslon = args[ 0 ]; - def.obslat = args[ 1 ]; - def.obsalt = args[ 2 ]; - def.epoch = args[ 3 ]; - def.refra = args[ 4 ]; - def.refdec = args[ 5 ]; - fcorr = args + 6; - sign = +1; - break; - - case AST__GEF2HL: - cvtFunc = GeoVel; - def.epoch = args[ 0 ]; - def.refra = args[ 1 ]; - def.refdec = args[ 2 ]; - fcorr = args + 3; - sign = -1; - break; - - case AST__HLF2GE: - cvtFunc = GeoVel; - def.epoch = args[ 0 ]; - def.refra = args[ 1 ]; - def.refdec = args[ 2 ]; - fcorr = args + 3; - sign = +1; - break; - - case AST__BYF2HL: - cvtFunc = BaryVel; - def.epoch = args[ 0 ]; - def.refra = args[ 1 ]; - def.refdec = args[ 2 ]; - fcorr = args + 3; - sign = -1; - break; - - case AST__HLF2BY: - cvtFunc = BaryVel; - def.epoch = args[ 0 ]; - def.refra = args[ 1 ]; - def.refdec = args[ 2 ]; - fcorr = args + 3; - sign = +1; - break; - - case AST__LKF2HL: - cvtFunc = LsrkVel; - def.refra = args[ 0 ]; - def.refdec = args[ 1 ]; - fcorr = args + 2; - sign = -1; - break; - - case AST__HLF2LK: - cvtFunc = LsrkVel; - def.refra = args[ 0 ]; - def.refdec = args[ 1 ]; - fcorr = args + 2; - sign = +1; - break; - - case AST__LDF2HL: - cvtFunc = LsrdVel; - def.refra = args[ 0 ]; - def.refdec = args[ 1 ]; - fcorr = args + 2; - sign = -1; - break; - - case AST__HLF2LD: - cvtFunc = LsrdVel; - def.refra = args[ 0 ]; - def.refdec = args[ 1 ]; - fcorr = args + 2; - sign = +1; - break; - - case AST__LGF2HL: - cvtFunc = LgVel; - def.refra = args[ 0 ]; - def.refdec = args[ 1 ]; - fcorr = args + 2; - sign = -1; - break; - - case AST__HLF2LG: - cvtFunc = LgVel; - def.refra = args[ 0 ]; - def.refdec = args[ 1 ]; - fcorr = args + 2; - sign = +1; - break; - - case AST__GLF2HL: - cvtFunc = GalVel; - def.refra = args[ 0 ]; - def.refdec = args[ 1 ]; - fcorr = args + 2; - sign = -1; - break; - - case AST__HLF2GL: - cvtFunc = GalVel; - def.refra = args[ 0 ]; - def.refdec = args[ 1 ]; - fcorr = args + 2; - sign = +1; - break; - -/* If the supplied code does not represent a change of rest-frame, clear - the returned flag. */ - default: - result = 0; - } - -/* Check we have a rest-frame code. */ - if( result ) { - -/* First deal with cases where we have a single source position (given by - refra and refdec). */ - if( !ra ) { - -/* If the frequency correction factor has not been found, find it now. */ - if( *fcorr == AST__BAD ) { - -/* Get the velocity correction. This is the component of the velocity of the - output system, away from the source, as measured in the input system. */ - s = sign*cvtFunc( def.refra, def.refdec, &def, status ); - -/* Find the factor by which to correct supplied frequencies. If the - velocity correction is positive, the output frequency wil be lower than - the input frequency. */ - if( s < AST__C && s > -AST__C ) { - *fcorr = sqrt( ( AST__C - s )/( AST__C + s ) ); - } - } - -/* Correct each supplied frequency. */ - if( *fcorr != AST__BAD && *fcorr != 0.0 ) { - factor = forward ? *fcorr : 1.0 / ( *fcorr ); - pf = freq; - for( i = 0; i < np; i++, pf++ ) { - if( *pf != AST__BAD ) *pf *= factor; - } - -/* Set returned values bad if the velocity correction is un-physical. */ - } else { - pf = freq; - for( i = 0; i < np; i++ ) *(pf++) = AST__BAD; - } - -/* Now deal with cases where each frequency value has its own source - position. */ - } else { - -/* Invert the sign if we are doing a inverse transformation. */ - if( !forward ) sign = -sign; - -/* Loop round each value. */ - pf = freq; - pra = ra; - pdec = dec; - for( i = 0; i < np; i++ ) { - -/* If the ra or dec is bad, store a bad frequency. */ - if( *pra == AST__BAD || *pdec == AST__BAD || *pf == AST__BAD ) { - *pf = AST__BAD; - -/* Otherwise, produce a corrected frequency. */ - } else { - -/* Get the velocity correction. */ - s = sign*cvtFunc( *pra, *pdec, &def, status ); - -/* Correct this frequency, if possible. Otherwise set bad. */ - if( s < AST__C && s > -AST__C ) { - *pf *= sqrt( ( AST__C - s )/( AST__C + s ) ); - } else { - *pf = AST__BAD; - } - } - -/* Move on to the next position. */ - pf++; - pra++; - pdec++; - } - } - } - -/* Return the result. */ - return result; -} - -static double GalVel( double ra, double dec, FrameDef *def, int *status ) { -/* -* Name: -* GalVel - -* Purpose: -* Find the velocity of the galactic centre away from the source. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double GalVel( double ra, double dec, FrameDef *def, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function finds the component of the velocity of the galactic -* centre away from a specified source position, in the frame of rest -* of the Sun. - -* Parameters: -* ra -* The RA (rads, FK5 J2000) of the source. -* dec -* The Dec (rads, FK5 J2000) of the source. -* def -* Pointer to a FrameDef structure which holds the parameters which -* define the frame, together with cached intermediate results. -* status -* Pointer to the inherited status variable. - -* Returns: -* The component of the frame's velocity away from the position given by -* "ra" and "dec", in m/s, measured within the Heliographic frame of -* rest. Zero is returned if an error has already occurred. - -*/ - -/* Local Variables: */ - double s1, s2; - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Get the component away from the source, of the velocity of the sun - relative to the dynamic LSR (in km/s). */ - s1 = (double) palRvlsrd( (float) ra, (float) dec ); - -/* Get the component away from the source, of the velocity of the - dynamic LSR relative to the galactic centre (in km/s). */ - s2 = (double) palRvgalc( (float) ra, (float) dec ); - -/* Return the total velocity of the galactic centre away from the source, - relative to the sun, in m/s. */ - return -1000.0*( s1 + s2 ); -} - -static double GeoVel( double ra, double dec, FrameDef *def, int *status ) { -/* -* Name: -* GeoVel - -* Purpose: -* Find the velocity of the earth away from the source. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double GeoVel( double ra, double dec, FrameDef *def, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function finds the component of the velocity of the earth away -* from a specified source position, at a given epoch, in the frame of -* rest of the Sun. - -* Parameters: -* ra -* The RA (rads, FK5 J2000) of the source. -* dec -* The Dec (rads, FK5 J2000) of the source. -* def -* Pointer to a FrameDef structure which holds the parameters which -* define the frame, together with cached intermediate results. -* status -* Pointer to the inherited status variable. - -* Returns: -* The component of the frame's velocity away from the position given by -* "ra" and "dec", in m/s, measured within the Heliographic frame of -* rest. Zero is returned if an error has already occurred. - -*/ - -/* Local Variables: */ - double dpb[ 3 ]; /* Barycentric earth position vector */ - double dph[ 3 ]; /* Heliocentric earth position vector */ - double dvb[ 3 ]; /* Barycentric earth velocity vector */ - double v[ 3 ]; /* Source direction vector */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Get the Cartesian vector towards the source, in the Cartesian FK5 - J2000 system. */ - palDcs2c( ra, dec, v ); - -/* If not already done so, get the Earth/Sun velocity and position vectors in - the same system. Speed is returned in units of AU/s. Store in the supplied - frame definition structure. */ - if( def->dvh[ 0 ] == AST__BAD ) palEvp( def->epoch, 2000.0, dvb, dpb, - def->dvh, dph ); - -/* Return the component away from the source, of the velocity of the earths - centre relative to the sun (in m/s). */ - return -palDvdv( v, def->dvh )*149.597870E9; -} - -void astInitSpecMapVtab_( AstSpecMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSpecMapVtab - -* Purpose: -* Initialise a virtual function table for a SpecMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "specmap.h" -* void astInitSpecMapVtab( AstSpecMapVtab *vtab, const char *name ) - -* Class Membership: -* SpecMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SpecMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASpecMap) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->SpecAdd = SpecAdd; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_rate = mapping->Rate; - mapping->Rate = Rate; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "SpecMap", - "Conversion between spectral coordinate systems" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static double LgVel( double ra, double dec, FrameDef *def, int *status ) { -/* -* Name: -* LgVel - -* Purpose: -* Find the velocity of the Local Group away from the source. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double LgVel( double ra, double dec, FrameDef *def, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function finds the component of the Local Group velocity away -* from a specified source position, in the frame of rest of the Sun. - -* Parameters: -* ra -* The RA (rads, FK5 J2000) of the source. -* dec -* The Dec (rads, FK5 J2000) of the source. -* def -* Pointer to a FrameDef structure which holds the parameters which -* define the frame, together with cached intermediate results. -* status -* Pointer to the inherited status variable. - -* Returns: -* The component of the frame's velocity away from the position given by -* "ra" and "dec", in m/s, measured within the Heliographic frame of -* rest. Zero is returned if an error has already occurred. - -*/ - -/* Return the component away from the source, of the velocity of the - local group relative to the sun (in m/s). */ - return -1000.0*palRvlg( (float) ra, (float) dec ); -} - -static double LsrdVel( double ra, double dec, FrameDef *def, int *status ) { -/* -* Name: -* LsrdVel - -* Purpose: -* Find the velocity of the Dynamical LSR away from the source. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double LsrdVel( double ra, double dec, FrameDef *def, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function finds the component of the velocity of the Dynamical -* LSR away from a specified source position, in the frame of rest of -* the Sun. - -* Parameters: -* ra -* The RA (rads, FK5 J2000) of the source. -* dec -* The Dec (rads, FK5 J2000) of the source. -* def -* Pointer to a FrameDef structure which holds the parameters which -* define the frame, together with cached intermediate results. -* status -* Pointer to the inherited status variable. - -* Returns: -* The component of the frame's velocity away from the position given by -* "ra" and "dec", in m/s, measured within the Heliographic frame of -* rest. Zero is returned if an error has already occurred. - -*/ -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Get the component away from the source, of the velocity of the sun - relative to the dynamical LSR (in m/s). This can also be thought of as the - velocity of the LSR towards the source relative to the sun. Return the - negated value (i.e. velocity of lsrd *away from* the source. */ - return -1000.0*palRvlsrd( (float) ra, (float) dec ); -} - -static double LsrkVel( double ra, double dec, FrameDef *def, int *status ) { -/* -* Name: -* LsrkVel - -* Purpose: -* Find the velocity of the Kinematic LSR away from the source. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double LsrkVel( double ra, double dec, FrameDef *def, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function finds the component of the velocity of the Kinematic -* LSR away from a specified source position, in the frame of rest of -* the Sun. - -* Parameters: -* ra -* The RA (rads, FK5 J2000) of the source. -* dec -* The Dec (rads, FK5 J2000) of the source. -* def -* Pointer to a FrameDef structure which holds the parameters which -* define the frame, together with cached intermediate results. -* status -* Pointer to the inherited status variable. - -* Returns: -* The component of the frame's velocity away from the position given by -* "ra" and "dec", in m/s, measured within the Heliographic frame of -* rest. Zero is returned if an error has already occurred. - -*/ -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Get the component away from the source, of the velocity of the sun - relative to the kinematic LSR (in m/s). This can also be thought of as the - velocity of the LSR towards the source relative to the sun. Return the - negated value (i.e. velocity of lsrk *away from* the source. */ - return -1000.0*palRvlsrk( (float) ra, (float) dec ); -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a SpecMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* SpecMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated SpecMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated SpecMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated SpecMap which is to be merged with -* its neighbours. This should be a cloned copy of the SpecMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* SpecMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated SpecMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *new; /* Pointer to replacement Mapping */ - AstSpecMap *specmap; /* Pointer to SpecMap */ - const char *argdesc[ MAX_ARGS ]; /* Argument descriptions (junk) */ - const char *class; /* Pointer to Mapping class string */ - const char *comment; /* Pointer to comment string (junk) */ - double (*cvtargs)[ MAX_ARGS ]; /* Pointer to argument arrays */ - double tmp; /* Temporary storage */ - int *cvttype; /* Pointer to transformation type codes */ - int *narg; /* Pointer to argument count */ - int *szarg; /* Pointer to argument array size */ - int argdec; /* Index of DEC argument */ - int argra; /* Index of RA argument */ - int done; /* Finished (no further simplification)? */ - int iarg; /* Loop counter for arguments */ - int icvt1; /* Loop initial value */ - int icvt2; /* Loop final value */ - int icvt; /* Loop counter for transformation steps */ - int ikeep; /* Index to store step being kept */ - int imap1; /* Index of first SpecMap to merge */ - int imap2; /* Index of last SpecMap to merge */ - int imap; /* Loop counter for Mappings */ - int inc; /* Increment for transformation step loop */ - int invert; /* SpecMap applied in inverse direction? */ - int istep; /* Loop counter for transformation steps */ - int keep; /* Keep transformation step? */ - int ngone; /* Number of Mappings eliminated */ - int nin; /* Numbr of axes for SpecMaps being merged */ - int nstep0; /* Original number of transformation steps */ - int nstep; /* Total number of transformation steps */ - int result; /* Result value to return */ - int simpler; /* Simplification possible? */ - int unit; /* Replacement Mapping is a UnitMap? */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* SpecMaps can only be merged if they are in series (or if there is - only one Mapping present, in which case it makes no difference), so - do nothing if they are not. */ - if ( series || ( *nmap == 1 ) ) { - -/* Save the number of inputs for the SpecMap. */ - nin = astGetNin( this ); - -/* Initialise the number of transformation steps to be merged to equal - the number in the nominated SpecMap. */ - nstep = ( (AstSpecMap *) ( *map_list )[ where ] )->ncvt; - -/* Search adjacent lower-numbered Mappings until one is found which is - not a SpecMap, or is a SpecMap with a different number of axes. Accumulate - the number of transformation steps involved in any SpecMaps found. */ - imap1 = where; - while ( ( imap1 - 1 >= 0 ) && astOK ) { - class = astGetClass( ( *map_list )[ imap1 - 1 ] ); - if ( !astOK || strcmp( class, "SpecMap" ) || - astGetNin( ( *map_list )[ imap1 - 1 ] ) != nin ) break; - nstep += ( (AstSpecMap *) ( *map_list )[ imap1 - 1 ] )->ncvt; - imap1--; - } - -/* Similarly search adjacent higher-numbered Mappings. */ - imap2 = where; - while ( ( imap2 + 1 < *nmap ) && astOK ) { - class = astGetClass( ( *map_list )[ imap2 + 1 ] ); - if ( !astOK || strcmp( class, "SpecMap" ) || - astGetNin( ( *map_list )[ imap2 + 1 ] ) != nin ) break; - nstep += ( (AstSpecMap *) ( *map_list )[ imap2 + 1 ] )->ncvt; - imap2++; - } - -/* Remember the initial number of transformation steps. */ - nstep0 = nstep; - -/* Allocate memory for accumulating a list of all the transformation - steps involved in all the SpecMaps found. */ - cvttype = astMalloc( sizeof( int ) * (size_t) nstep ); - cvtargs = astMalloc( sizeof( double[ MAX_ARGS ] ) * (size_t) nstep ); - szarg = astMalloc( sizeof( int ) * (size_t) nstep ); - narg = astMalloc( sizeof( int ) * (size_t) nstep ); - -/* Loop to obtain the transformation data for each SpecMap being merged. */ - nstep = 0; - for ( imap = imap1; astOK && ( imap <= imap2 ); imap++ ) { - -/* Obtain a pointer to the SpecMap and note if it is being applied in - its inverse direction. */ - specmap = (AstSpecMap *) ( *map_list )[ imap ]; - invert = ( *invert_list )[ imap ]; - -/* Set up loop limits and an increment to scan the transformation - steps in each SpecMap in either the forward or reverse direction, as - dictated by the associated "invert" value. */ - icvt1 = invert ? specmap->ncvt - 1 : 0; - icvt2 = invert ? -1 : specmap->ncvt; - inc = invert ? -1 : 1; - -/* Loop through each transformation step in the SpecMap. */ - for ( icvt = icvt1; icvt != icvt2; icvt += inc ) { - -/* Store the transformation type code and use "CvtString" to determine - the associated number of arguments. Then store these arguments. */ - cvttype[ nstep ] = specmap->cvttype[ icvt ]; - (void) CvtString( cvttype[ nstep ], &comment, &argra, &argdec, - narg + nstep, szarg + nstep, argdesc, status ); - if ( !astOK ) break; - for ( iarg = 0; iarg < szarg[ nstep ]; iarg++ ) { - cvtargs[ nstep ][ iarg ] = specmap->cvtargs[ icvt ][ iarg ]; - } - -/* If the SpecMap is inverted, we must not only accumulate its - transformation steps in reverse, but also apply them in - reverse. For some steps this means changing arguments, for some it - means changing the transformation type code to a complementary - value, and for others it means both. Define macros to perform each - of the required changes. */ - -/* Macro to exchange a transformation type code for its inverse (and - vice versa). */ -#define SWAP_CODES( code1, code2 ) \ - if ( cvttype[ nstep ] == code1 ) { \ - cvttype[ nstep ] = code2; \ - } else if ( cvttype[ nstep ] == code2 ) { \ - cvttype[ nstep ] = code1; \ - } - -/* Macro to exchange a transformation type code for its inverse (and - vice versa), and reciprocate a specified argument. */ -#define SWAP_CODES2( code1, code2, jarg ) \ - if ( cvttype[ nstep ] == code1 ) { \ - cvttype[ nstep ] = code2; \ - tmp = cvtargs[ nstep ][ jarg ]; \ - if( tmp != AST__BAD && tmp != 0.0 ) { \ - cvtargs[ nstep ][ jarg ] = 1.0/tmp; \ - } else { \ - cvtargs[ nstep ][ jarg ] = AST__BAD; \ - } \ - } else if ( cvttype[ nstep ] == code2 ) { \ - cvttype[ nstep ] = code1; \ - tmp = cvtargs[ nstep ][ jarg ]; \ - if( tmp != AST__BAD && tmp != 0.0 ) { \ - cvtargs[ nstep ][ jarg ] = 1.0/tmp; \ - } else { \ - cvtargs[ nstep ][ jarg ] = AST__BAD; \ - } \ - } - -/* Macro to exchange a transformation type code for its inverse (and - vice versa), and negate a specified argument. */ -#define SWAP_CODES3( code1, code2, jarg ) \ - if ( cvttype[ nstep ] == code1 ) { \ - cvttype[ nstep ] = code2; \ - tmp = cvtargs[ nstep ][ jarg ]; \ - if( tmp != AST__BAD ) { \ - cvtargs[ nstep ][ jarg ] = -tmp; \ - } \ - } else if ( cvttype[ nstep ] == code2 ) { \ - cvttype[ nstep ] = code1; \ - tmp = cvtargs[ nstep ][ jarg ]; \ - if( tmp != AST__BAD ) { \ - cvtargs[ nstep ][ jarg ] = -tmp; \ - } \ - } - -/* Use these macros to apply the changes where needed. */ - if ( invert ) { - -/* Exchange transformation codes for their inverses. */ - SWAP_CODES( AST__FRTOVL, AST__VLTOFR ) - SWAP_CODES( AST__ENTOFR, AST__FRTOEN ) - SWAP_CODES( AST__WNTOFR, AST__FRTOWN ) - SWAP_CODES( AST__WVTOFR, AST__FRTOWV ) - SWAP_CODES( AST__AWTOFR, AST__FRTOAW ) - SWAP_CODES( AST__VRTOVL, AST__VLTOVR ) - SWAP_CODES( AST__VOTOVL, AST__VLTOVO ) - SWAP_CODES( AST__ZOTOVL, AST__VLTOZO ) - SWAP_CODES( AST__BTTOVL, AST__VLTOBT ) - -/* Exchange transformation codes for their inverses, and reciprocate the - frequency correction factor. */ - SWAP_CODES2( AST__TPF2HL, AST__HLF2TP, 6 ) - SWAP_CODES2( AST__USF2HL, AST__HLF2US, 3 ) - SWAP_CODES2( AST__GEF2HL, AST__HLF2GE, 3 ) - SWAP_CODES2( AST__BYF2HL, AST__HLF2BY, 3 ) - SWAP_CODES2( AST__LKF2HL, AST__HLF2LK, 2 ) - SWAP_CODES2( AST__LDF2HL, AST__HLF2LD, 2 ) - SWAP_CODES2( AST__LGF2HL, AST__HLF2LG, 2 ) - SWAP_CODES2( AST__GLF2HL, AST__HLF2GL, 2 ) - - } - -/* Undefine the local macros. */ -#undef SWAP_CODES -#undef SWAP_CODES2 -#undef SWAP_CODES3 - -/* Count the transformation steps. */ - nstep++; - } - } - -/* Loop to simplify the sequence of transformation steps until no - further improvement is possible. */ - done = 0; - while ( astOK && !done ) { - -/* Examine each remaining transformation step in turn. */ - ikeep = -1; - for ( istep = 0; istep < nstep; istep++ ) { - -/* Initially assume we will retain the current step. */ - keep = 1; - -/* The only simplifications for the conversions currently in this class act - to combine adjacent transformation steps, so only apply them while there - are at least 2 steps left. */ - if ( istep < ( nstep - 1 ) ) { - -/* Define a macro to test if two adjacent transformation type codes - have specified values. */ -#define PAIR_CVT( code1, code2 ) \ - ( ( cvttype[ istep ] == code1 ) && \ - ( cvttype[ istep + 1 ] == code2 ) ) - -/* Define a macro to test if two adjacent transformation type codes - have specified values, either way round. */ -#define PAIR_CVT2( code1, code2 ) \ - ( ( PAIR_CVT( code1, code2 ) ) || \ - ( PAIR_CVT( code2, code1 ) ) ) - -/* If a correction is followed by its inverse, and the user-supplied argument - values are unchanged (we do not need to test values stored in the - argument array which were not supplied by the user), we can eliminate them. - First check for conversions which have no user-supplied arguments. */ - if ( PAIR_CVT2( AST__ENTOFR, AST__FRTOEN ) || - PAIR_CVT2( AST__WNTOFR, AST__FRTOWN ) || - PAIR_CVT2( AST__WVTOFR, AST__FRTOWV ) || - PAIR_CVT2( AST__AWTOFR, AST__FRTOAW ) || - PAIR_CVT2( AST__VRTOVL, AST__VLTOVR ) || - PAIR_CVT2( AST__VOTOVL, AST__VLTOVO ) || - PAIR_CVT2( AST__ZOTOVL, AST__VLTOZO ) || - PAIR_CVT2( AST__BTTOVL, AST__VLTOBT ) ) { - istep++; - keep = 0; - -/* Now check for conversions which have a single user-supplied argument. */ - } else if( PAIR_CVT2( AST__FRTOVL, AST__VLTOFR ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - -/* Now check for conversions which have two user-supplied arguments. */ - } else if( ( PAIR_CVT2( AST__LKF2HL, AST__HLF2LK ) || - PAIR_CVT2( AST__LDF2HL, AST__HLF2LD ) || - PAIR_CVT2( AST__LGF2HL, AST__HLF2LG ) || - PAIR_CVT2( AST__GLF2HL, AST__HLF2GL ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 1 ] ) ) { - istep++; - keep = 0; - -/* Now check for conversions which have three user-supplied arguments. */ - } else if( ( PAIR_CVT2( AST__GEF2HL, AST__HLF2GE ) || - PAIR_CVT2( AST__BYF2HL, AST__HLF2BY ) || - PAIR_CVT2( AST__USF2HL, AST__HLF2US ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 1 ] ) && - astEQUAL( cvtargs[ istep ][ 2 ], - cvtargs[ istep + 1 ][ 2 ] ) ) { - istep++; - keep = 0; - -/* Now check for conversions which have six user-supplied arguments (currently - no conversions have four or five user-supplied arguments). */ - } else if( ( PAIR_CVT2( AST__TPF2HL, AST__HLF2TP ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 1 ] ) && - astEQUAL( cvtargs[ istep ][ 2 ], - cvtargs[ istep + 1 ][ 2 ] ) && - astEQUAL( cvtargs[ istep ][ 3 ], - cvtargs[ istep + 1 ][ 3 ] ) && - astEQUAL( cvtargs[ istep ][ 4 ], - cvtargs[ istep + 1 ][ 4 ] ) && - astEQUAL( cvtargs[ istep ][ 5 ], - cvtargs[ istep + 1 ][ 5 ] ) ) { - istep++; - keep = 0; - - } - -/* Undefine the local macros. */ -#undef PAIR_CVT -#undef PAIR_CVT2 - } - -/* If the current transformation (possibly modified above) is being - kept, then increment the index that identifies its new location in - the list of transformation steps. */ - if ( keep ) { - ikeep++; - -/* If the new location is different to its current location, copy the - transformation data into the new location. */ - if ( ikeep != istep ) { - cvttype[ ikeep ] = cvttype[ istep ]; - for ( iarg = 0; iarg < szarg[ istep ]; iarg++ ) { - cvtargs[ ikeep ][ iarg ] = cvtargs[ istep ][ iarg ]; - } - szarg[ ikeep ] = szarg[ istep ]; - narg[ ikeep ] = narg[ istep ]; - } - } - } - -/* Note if no simplification was achieved on this iteration (i.e. the - number of transformation steps was not reduced). This is the signal - to quit. */ - done = ( ( ikeep + 1 ) >= nstep ); - -/* Note how many transformation steps now remain. */ - nstep = ikeep + 1; - } - -/* Determine how many Mappings can be eliminated by condensing all - those considered above into a single Mapping. */ - if ( astOK ) { - ngone = imap2 - imap1; - -/* Determine if the replacement Mapping can be a UnitMap (a null - Mapping). This will only be the case if all the transformation - steps were eliminated above. */ - unit = ( nstep == 0 ); - -/* Determine if simplification is possible. This will be the case if - (a) Mappings were eliminated ("ngone" is non-zero), or (b) the - number of transformation steps was reduced, or (c) the SpecMap(s) - can be replaced by a UnitMap, or (d) if there was initially only - one SpecMap present, its invert flag was set (this flag will always - be cleared in the replacement Mapping). */ - simpler = ngone || ( nstep < nstep0 ) || unit || - ( *invert_list )[ where ]; - -/* Do nothing more unless simplification is possible. */ - if ( simpler ) { - -/* If the replacement Mapping is a UnitMap, then create it. */ - if ( unit ) { - new = (AstMapping *) - astUnitMap( astGetNin( ( *map_list )[ where ] ), "", status ); - -/* Otherwise, create a replacement SpecMap and add each of the - remaining transformation steps to it. */ - } else { - new = (AstMapping *) astSpecMap( nin, 0, "", status ); - for ( istep = 0; istep < nstep; istep++ ) { - AddSpecCvt( (AstSpecMap *) new, cvttype[ istep ], - narg[ istep ], cvtargs[ istep ], status ); - } - } - -/* Annul the pointers to the Mappings being eliminated. */ - if ( astOK ) { - for ( imap = imap1; imap <= imap2; imap++ ) { - ( *map_list )[ imap ] = astAnnul( ( *map_list )[ imap ] ); - } - -/* Insert the pointer and invert value for the new Mapping. */ - ( *map_list )[ imap1 ] = new; - ( *invert_list )[ imap1 ] = 0; - -/* Move any subsequent Mapping information down to close the gap. */ - for ( imap = imap2 + 1; imap < *nmap; imap++ ) { - ( *map_list )[ imap - ngone ] = ( *map_list )[ imap ]; - ( *invert_list )[ imap - ngone ] = ( *invert_list )[ imap ]; - } - -/* Blank out any information remaining at the end of the arrays. */ - for ( imap = ( *nmap - ngone ); imap < *nmap; imap++ ) { - ( *map_list )[ imap ] = NULL; - ( *invert_list )[ imap ] = 0; - } - -/* Decrement the Mapping count and return the index of the first - Mapping which was eliminated. */ - ( *nmap ) -= ngone; - result = imap1; - -/* If an error occurred, annul the new Mapping pointer. */ - } else { - new = astAnnul( new ); - } - } - } - -/* Free the memory used for the transformation steps. */ - cvttype = astFree( cvttype ); - cvtargs = astFree( cvtargs ); - szarg = astFree( szarg ); - narg = astFree( narg ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* SpecMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -* Implementation Deficiencies: -* The initial version of this implementation only deals with -* frequency->wavelength conversions. This is because the slowness of -* the numerical differentiation implemented by the astRate method in -* the parent Mapping class is cripples conversion between SpecFluxFrames. -* Such conversions only rely on rate of change of wavelength with -* respect to frequency. This implementation should be extended when -* needed. - -*/ - -/* Local Variables: */ - AstSpecMap *map; - double result; - int cvt; - -/* Check inherited status */ - if( !astOK ) return AST__BAD; - -/* Get a pointer to the SpecMap structure. */ - map = (AstSpecMap *) this; - -/* Return 1.0 if the SpecMap has no conversions. */ - if( map->ncvt == 0 ) return 1.0; - -/* Store the type of the first conversion.*/ - cvt = map->cvttype[ 0 ]; - -/* If this is a 3D SpecMap or if it has more than one component, or if - that conversion is not between frequency and wavelength, use the - astRate method inherited form the parent Mapping class. */ - if( astGetNin( map ) != 1 || map->ncvt != 1 || - ( cvt != AST__WVTOFR && cvt != AST__FRTOWV ) ) { - result = (*parent_rate)( this, at, ax1, ax2, status ); - -/* Otherwise, evaluate the known analytical expressions for the rate of - change of frequency with respect to wavelength or wavelength with - respect to frequency. */ - } else { - result = ( *at != AST__BAD ) ? -AST__C/((*at)*(*at)) : AST__BAD; - } - -/* Return the result. */ - return result; -} - -static double Refrac( double wavelen, int *status ){ -/* -* Name: -* Refrac - -* Purpose: -* Returns the refractive index of dry air at a given wavelength. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double Refrac( double wavelen, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function returns the refractive index of dry air at standard -* temperature and pressure, at a given wavelength. The formula is -* taken from the paper "Representation of Spectral Coordinates in FITS" -* (Greisen et al). - -* Parameters: -* wavelen -* The wavelength, in metres. This should be the air wavelength, -* but supplying the vacuum wavelength will make no significant -* difference. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The refractive index. A value of 1.0 is returned if an error -* occurs, or has already occurred. - -*/ - -/* Local Variables: */ - double w2; /* Wavenumber squared */ - -/* Check the global error status. */ - if ( !astOK || wavelen == 0.0 ) return 1.0; - -/* Find the squared wave number in units of "(per um)**2". */ - w2 = 1.0E-12/( wavelen * wavelen ); - -/* Apply the rest of the algorithm as described in the FITS WCS - paper III. */ - return 1.0 + 1.0E-6*( 287.6155 + 1.62887*w2 + 0.01360*w2*w2 ); -} - -static double Rverot( double phi, double h, double ra, double da, - double st, int *status ) { -/* -* Name: -* Rverot - -* Purpose: -* Find the velocity component in a given direction due to Earth rotation. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double Rverot( double phi, double h, double ra, double da, -* double st, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function is like slaRverot, except that it takes account of the -* observers height (h), and does all calculations in double precision. - -* Parameters: -* phi -* The geodetic latitude of the observer (radians, IAU 1976). -* h -* The geodetic height above the reference spheroid of the observer -* (metres, IAU 1976). -* ra -* The geocentric apparent RA (rads) of the source. -* da -* The geocentric apparent Dec (rads) of the source. -* st -* The local apparent sidereal time (radians). -* status -* Pointer to the inherited status variable. - -* Returns: -* The component of the Earth rotation in direction [RA,DA] (km/s). -* The result is positive when the observer is receding from the -* given point on the sky. Zero is returned if an error has already -* occurred. - -*/ - -/* Local Variables: */ - double pv[ 6 ]; /* Observer position and velocity */ - double v[ 3 ]; /* Source direction vector */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Get the Cartesian coordinates of the unit vector pointing towards the - given sky position. */ - palDcs2c( ra, da, v ); - -/* Get velocity and position of the observer. */ - palPvobs( phi, h, st, pv ); - -/* Return the component of the observer's velocity away from the sky - position, and convert from AU/s to km/s. */ - return -palDvdv( v, pv + 3 )*149.597870E6; -} - -static void SpecAdd( AstSpecMap *this, const char *cvt, int narg, - const double args[], int *status ) { -/* -*++ -* Name: -c astSpecAdd -f AST_SPECADD - -* Purpose: -* Add a spectral coordinate conversion to a SpecMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "specmap.h" -c void astSpecAdd( AstSpecMap *this, const char *cvt, int narg, -c const double args[] ) -f CALL AST_SPECADD( THIS, CVT, NARG, ARGS, STATUS ) - -* Class Membership: -* SpecMap method. - -* Description: -c This function adds one of the standard spectral coordinate -f This routine adds one of the standard spectral coordinate -* system conversions listed below to an existing SpecMap. -* -c When a SpecMap is first created (using astSpecMap), it simply -f When a SpecMap is first created (using AST_SPECMAP), it simply -c performs a unit (null) Mapping. By using astSpecAdd (repeatedly -f performs a unit (null) Mapping. By using AST_SPECADD (repeatedly -* if necessary), one or more coordinate conversion steps may then -* be added, which the SpecMap will perform in sequence. This allows -* multi-step conversions between a variety of spectral coordinate -* systems to be assembled out of the building blocks provided by -* this class. -* -* Normally, if a SpecMap's Invert attribute is zero (the default), -* then its forward transformation is performed by carrying out -* each of the individual coordinate conversions specified by -c astSpecAdd in the order given (i.e. with the most recently added -f AST_SPECADD in the order given (i.e. with the most recently added -* conversion applied last). -* -* This order is reversed if the SpecMap's Invert attribute is -* non-zero (or if the inverse transformation is requested by any -* other means) and each individual coordinate conversion is also -* replaced by its own inverse. This process inverts the overall -* effect of the SpecMap. In this case, the first conversion to be -* applied would be the inverse of the one most recently added. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the SpecMap. -c cvt -f CVT = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string which identifies the -f A character string which identifies the -* spectral coordinate conversion to be added to the -* SpecMap. See the "Available Conversions" section for details of -* those available. -c narg -f NARG = INTEGER (Given) -* The number of argument values supplied in the -c "args" array. -f ARGS array. -c args -f ARGS( * ) = DOUBLE PRECISION (Given) -* An array containing argument values for the spectral -* coordinate conversion. The number of arguments required, and -* hence the number of array elements used, depends on the -* conversion specified (see the "Available Conversions" -* section). This array is ignored -c and a NULL pointer may be supplied -* if no arguments are needed. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - When assembling a multi-stage conversion, it can sometimes be -* difficult to determine the most economical conversion path. For -* example, when converting between reference frames, converting first -* to the heliographic reference frame as an intermediate stage is often -* sensible in formulating the problem, but may introduce unnecessary -* extra conversion steps. A solution to this is to include all the steps -* which are (logically) necessary, but then to use -c astSimplify to simplify the resulting -f AST_SIMPLIFY to simplify the resulting -* SpecMap. The simplification process will eliminate any steps -* which turn out not to be needed. -c - This function does not check to ensure that the sequence of -f - This routine does not check to ensure that the sequence of -* coordinate conversions added to a SpecMap is physically -* meaningful. - -* Available Conversions: -* The following strings (which are case-insensitive) may be supplied -c via the "cvt" parameter to indicate which spectral coordinate -f via the CVT argument to indicate which spectral coordinate -* conversion is to be added to the SpecMap. Where arguments are needed by -* the conversion, they are listed in parentheses. Values for -c these arguments should be given, via the "args" array, in the -f these arguments should be given, via the ARGS array, in the -* order indicated. Units and argument names are described at the end of -* the list of conversions. - -* - "FRTOVL" (RF): Convert frequency to relativistic velocity. -* - "VLTOFR" (RF): Convert relativistic velocity to Frequency. -* - "ENTOFR": Convert energy to frequency. -* - "FRTOEN": Convert frequency to energy. -* - "WNTOFR": Convert wave number to frequency. -* - "FRTOWN": Convert frequency to wave number. -* - "WVTOFR": Convert wavelength (vacuum) to frequency. -* - "FRTOWV": Convert frequency to wavelength (vacuum). -* - "AWTOFR": Convert wavelength (air) to frequency. -* - "FRTOAW": Convert frequency to wavelength (air). -* - "VRTOVL": Convert radio to relativistic velocity. -* - "VLTOVR": Convert relativistic to radio velocity. -* - "VOTOVL": Convert optical to relativistic velocity. -* - "VLTOVO": Convert relativistic to optical velocity. -* - "ZOTOVL": Convert redshift to relativistic velocity. -* - "VLTOZO": Convert relativistic velocity to redshift. -* - "BTTOVL": Convert beta factor to relativistic velocity. -* - "VLTOBT": Convert relativistic velocity to beta factor. -* - "USF2HL" (VOFF,RA,DEC): Convert frequency from a user-defined -* reference frame to heliocentric. -* - "HLF2US" (VOFF,RA,DEC): Convert frequency from heliocentric -* reference frame to user-defined. -* - "TPF2HL" (OBSLON,OBSLAT,OBSALT,EPOCH,RA,DEC): Convert frequency from -* topocentric reference frame to heliocentric. -* - "HLF2TP" (OBSLON,OBSLAT,OBSALT,EPOCH,RA,DEC): Convert frequency from -* heliocentric reference frame to topocentric. -* - "GEF2HL" (EPOCH,RA,DEC): Convert frequency from geocentric -* reference frame to heliocentric. -* - "HLF2GE" (EPOCH,RA,DEC): Convert frequency from -* heliocentric reference frame to geocentric. -* - "BYF2HL" (EPOCH,RA,DEC): Convert frequency from -* barycentric reference frame to heliocentric. -* - "HLF2BY" (EPOCH,RA,DEC): Convert frequency from -* heliocentric reference frame to barycentric. -* - "LKF2HL" (RA,DEC): Convert frequency from kinematic LSR -* reference frame to heliocentric. -* - "HLF2LK" (RA,DEC): Convert frequency from heliocentric -* reference frame to kinematic LSR. -* - "LDF2HL" (RA,DEC): Convert frequency from dynamical LSR -* reference frame to heliocentric. -* - "HLF2LD" (RA,DEC): Convert frequency from heliocentric -* reference frame to dynamical LSR. -* - "LGF2HL" (RA,DEC): Convert frequency from local group -* reference frame to heliocentric. -* - "HLF2LG" (RA,DEC): Convert frequency from heliocentric -* reference frame to local group. -* - "GLF2HL" (RA,DEC): Convert frequency from galactic -* reference frame to heliocentric. -* - "HLF2GL" (RA,DEC): Convert frequency from heliocentric -* reference frame to galactic. - -* The units for the values processed by the above conversions are as -* follows: -* -* - all velocities: metres per second (positive if the source receeds from -* the observer). -* - frequency: Hertz. -* - all wavelengths: metres. -* - energy: Joules. -* - wave number: cycles per metre. -* -* The arguments used in the above conversions are as follows: -* -* - RF: Rest frequency (Hz). -* - OBSALT: Geodetic altitude of observer (IAU 1975, metres). -* - OBSLAT: Geodetic latitude of observer (IAU 1975, radians). -* - OBSLON: Longitude of observer (radians - positive eastwards). -* - EPOCH: Epoch of observation (UT1 expressed as a Modified Julian Date). -* - RA: Right Ascension of source (radians, FK5 J2000). -* - DEC: Declination of source (radians, FK5 J2000). -* - VOFF: Velocity of the user-defined reference frame, towards the -* position given by RA and DEC, measured in the heliocentric -* reference frame. -* -* If the SpecMap is 3-dimensional, source positions are provided by the -* values supplied to inputs 2 and 3 of the SpecMap (which are simply -* copied to outputs 2 and 3). Note, usable values are still required -* for the RA and DEC arguments in order to define the "user-defined" -* reference frame used by USF2HL and HLF2US. However, AST__BAD can be -* supplied for RA and DEC if the user-defined reference frame is not -* required. -* -*-- -*/ - -/* Local Variables: */ - int cvttype; /* Conversion type code */ - -/* Check the inherited status. */ - if ( !astOK ) return; - -/* Validate the type string supplied and obtain the equivalent - conversion type code. */ - cvttype = CvtCode( cvt, status ); - -/* If the string was not recognised, then report an error. */ - if ( astOK && ( cvttype == AST__SPEC_NULL ) ) { - astError( AST__SPCIN, - "%s(%s): Invalid SpecMap spectral coordinate " - "conversion type \"%s\".", status, "astAddSpec", astGetClass( this ), cvt ); - } - -/* Add the new conversion to the SpecMap. */ - AddSpecCvt( this, cvttype, narg, args, status ); -} - -static int SystemChange( int cvt_code, int np, double *values, double *args, - int forward, int *status ){ -/* -* Name: -* SystemChange - -* Purpose: -* Change values between two spectral systems. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* int SystemChange( int cvt_code, int np, double *values, double *args, -* int forward, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function modifies the supplied values in order to change the -* spectral co-ordinate system (frequency, wavelength, etc) to which -* they refer. - -* Parameters: -* cvt_code -* A code indicating the conversion to be applied. If the code does -* not correspond to a change of system, then the supplied values -* are left unchanged and zero is returned as the function value. -* np -* The number of frequency values to transform. -* values -* Pointer to an array of "np" spectral values. These are modified on -* return to hold the corresponding values measured in the output -* system. -* args -* Pointer to an array holding the conversion arguments. The number -* of arguments expected depends on the particular conversion being -* used. -* forward -* Should the conversion be applied in the forward or inverse -* direction? Non-zero for forward, zero for inverse. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the supplied conversion code corresponds to a change of -* system. Zero otherwise (in which case the upplied values will not -* have been changed). - -*/ - -/* Local Variables: */ - double *pv; /* Pointer to next value */ - double d; /* Intermediate value */ - double f2; /* Squared frequency */ - double temp; /* Intermediate value */ - int i; /* Loop index */ - int iter; /* Iteration count */ - int result; /* Returned value */ - -/* Check inherited status. */ - if( !astOK ) return 0; - -/* Set the return value to indicate that the supplied conversion code - represents a change of system. */ - result = 1; - -/* Test for each code value in turn and assign the appropriate values. */ - switch ( cvt_code ) { - -/* Frequency to relativistic velocity. */ - case AST__FRTOVL: - if( forward ) { - if( args[ 0 ] != AST__BAD ) { - temp = args[ 0 ] * args[ 0 ]; - pv = values - 1; - for( i = 0; i < np; i++ ){ - pv++; - if( *pv != AST__BAD ) { - f2 = ( *pv ) * ( *pv ); - d = temp + f2; - if( d > 0.0 ) { - *pv = AST__C*( ( temp - f2 )/d ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } else { - *pv = AST__BAD; - } - } - } - } else { - pv = values; - for( i = 0; i < np; i++ ) *( pv++ ) = AST__BAD; - } - } else { - SystemChange( AST__VLTOFR, np, values, args, 1, status ); - } - break; - -/* Relativistic velocity to frequency. */ - case AST__VLTOFR: - if( forward ) { - if( args[ 0 ] != AST__BAD ) { - temp = args[ 0 ]; - pv = values - 1; - for( i = 0; i < np; i++ ){ - pv++; - if( *pv != AST__BAD ) { - d = AST__C + ( *pv ); - if( d != 0.0 ) { - d = ( AST__C - ( *pv ) )/d; - if( d >= 0.0 ) { - *pv = temp*sqrt( d ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } else { - *pv = AST__BAD; - } - } else { - *pv = AST__BAD; - } - } - } - } else { - pv = values; - for( i = 0; i < np; i++ ) *( pv++ ) = AST__BAD; - } - } else { - SystemChange( AST__FRTOVL, np, values, args, 1, status ); - } - break; - -/* Energy to frequency */ - case AST__ENTOFR: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - *pv /= AST__H; - } - } - } else { - SystemChange( AST__FRTOEN, np, values, args, 1, status ); - } - break; - -/* Frequency to energy */ - case AST__FRTOEN: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - *pv *= AST__H; - } - } - } else { - SystemChange( AST__ENTOFR, np, values, args, 1, status ); - } - break; - -/* Wave number to frequency */ - case AST__WNTOFR: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - *pv *= AST__C; - } - } - } else { - SystemChange( AST__FRTOWN, np, values, args, 1, status ); - } - break; - -/* Wave number to frequency */ - case AST__FRTOWN: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - *pv /= AST__C; - } - } - } else { - SystemChange( AST__WNTOFR, np, values, args, 1, status ); - } - break; - -/* Wavelength to frequency */ - case AST__WVTOFR: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD && *pv != 0.0 ) { - *pv = AST__C/( *pv ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } else { - *pv = AST__BAD; - } - } - } else { - SystemChange( AST__FRTOWV, np, values, args, 1, status ); - } - break; - -/* Frequency to wavelength. */ - case AST__FRTOWV: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD && *pv != 0.0 ) { - *pv = AST__C/( *pv ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } else { - *pv = AST__BAD; - } - } - } else { - SystemChange( AST__WVTOFR, np, values, args, 1, status ); - } - break; - -/* Wavelength in air to frequency. */ - case AST__AWTOFR: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD && *pv != 0.0 ) { - *pv = AST__C/( ( *pv )*Refrac( *pv, status ) ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } else { - *pv = AST__BAD; - } - } - } else { - SystemChange( AST__FRTOAW, np, values, args, 1, status ); - } - break; - -/* Frequency to wavelength in air. */ - case AST__FRTOAW: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD && *pv != 0.0 ) { - -/* Form the vacuum wavelength. */ - temp = AST__C/( *pv ); - -/* The refractive index function "Refrac" requires the wavelength in air - as its parameter. Initially assume that the wavelength in air is equal - to the vacuum wavelength to get he first estimate of the wavelength in - air. Then use this estimate to get a better refractive index in order to - form a better estimate of the air wavelength, etc. Iterate in this way a - few times. */ - *pv = temp; - for( iter = 0; iter < 3; iter++ ) { - *pv = temp/Refrac( *pv, status ); - if( !astISFINITE( *pv ) ) { - *pv = AST__BAD; - break; - } - } - - } else { - *pv = AST__BAD; - } - } - } else { - SystemChange( AST__AWTOFR, np, values, args, 1, status ); - } - break; - -/* Radio velocity to relativistic velocity */ - case AST__VRTOVL: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - temp = 1.0 - ( *pv )/AST__C; - temp *= temp; - *pv = AST__C*( 1.0 - temp )/( 1.0 + temp ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } - } - } else { - SystemChange( AST__VLTOVR, np, values, args, 1, status ); - } - break; - -/* Relativistic velocity to radio velocity. */ - case AST__VLTOVR: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - temp = AST__C + ( *pv ); - if( temp != 0.0 ) { - temp = (AST__C - *pv )/temp; - if( temp >= 0.0 ) { - *pv = AST__C*( 1.0 - sqrt( temp ) ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } else { - *pv = AST__BAD; - } - } else { - *pv = AST__BAD; - } - } - } - } else { - SystemChange( AST__VRTOVL, np, values, args, 1, status ); - } - break; - -/* Optical velocity to relativistic velocity */ - case AST__VOTOVL: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - temp = 1.0 + ( *pv )/AST__C; - temp *= temp; - *pv = AST__C*( temp - 1.0 )/( temp + 1.0 ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } - } - } else { - SystemChange( AST__VLTOVO, np, values, args, 1, status ); - } - break; - -/* Relativistic velocity to optical velocity. */ - case AST__VLTOVO: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - temp = AST__C - *pv; - if( temp != 0.0 ) { - temp = (AST__C + *pv )/temp; - if( temp >= 0.0 ) { - *pv = AST__C*( sqrt( temp ) - 1.0 ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } else { - *pv = AST__BAD; - } - } else { - *pv = AST__BAD; - } - } - } - } else { - SystemChange( AST__VOTOVL, np, values, args, 1, status ); - } - break; - -/* Redshift to relativistic velocity */ - case AST__ZOTOVL: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - temp = 1.0 + ( *pv ); - temp *= temp; - *pv = AST__C*( temp - 1.0 )/( temp + 1.0 ); - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } - } - } else { - SystemChange( AST__VLTOZO, np, values, args, 1, status ); - } - break; - -/* Relativistic velocity to redshift. */ - case AST__VLTOZO: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - temp = AST__C - *pv; - if( temp != 0.0 ) { - temp = (AST__C + *pv )/temp; - if( temp >= 0.0 ) { - *pv = sqrt( temp ) - 1.0; - if( !astISFINITE( *pv ) ) *pv = AST__BAD; - } else { - *pv = AST__BAD; - } - } else { - *pv = AST__BAD; - } - } - } - } else { - SystemChange( AST__ZOTOVL, np, values, args, 1, status ); - } - break; - -/* Beta factor to relativistic velocity */ - case AST__BTTOVL: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - *pv *= AST__C; - } - } - } else { - SystemChange( AST__VLTOBT, np, values, args, 1, status ); - } - break; - -/* Relativistic velocity to beta factor. */ - case AST__VLTOBT: - if( forward ) { - pv = values - 1; - for( i = 0; i < np; i++ ) { - pv++; - if( *pv != AST__BAD ) { - *pv /= AST__C; - } - } - } else { - SystemChange( AST__BTTOVL, np, values, args, 1, status ); - } - break; - -/* If the supplied code does not represent a change of system, clear - the returned flag. */ - default: - result = 0; - } - -/* Return the result. */ - return result; -} - -static double TopoVel( double ra, double dec, FrameDef *def, int *status ) { -/* -* Name: -* TopoVel - -* Purpose: -* Find the velocity of the observer away from the source. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double TopoVel( double ra, double dec, FrameDef *def, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function finds the component of the velocity of the observer away -* from a specified source position, at a given epoch, in the frame of -* rest of the Sun. - -* Parameters: -* ra -* The RA (rads, FK5 J2000) of the source. -* dec -* The Dec (rads, FK5 J2000) of the source. -* def -* Pointer to a FrameDef structure which holds the parameters which -* define the frame, together with cached intermediate results. -* status -* Pointer to the inherited status variable. - -* Returns: -* The component of the frame's velocity away from the position given by -* "ra" and "dec", in m/s, measured within the Heliographic frame of -* rest. Zero is returned if an error has already occurred. - -*/ - -/* Local Variables: */ - double deca; /* Apparent DEC */ - double raa; /* Apparent RA */ - double vobs; /* Velocity of observer relative to earth */ - double vearth; /* Velocity of earth realtive to sun */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* If not already done so, get the parameters defining the transformation - of mean ra and dec to apparent ra and dec, and store in the supplied frame - definition structure. */ - if( def->amprms[ 0 ] == AST__BAD ) palMappa( 2000.0, def->epoch, - def->amprms ); - -/* Convert the source position from mean ra and dec to apparent ra and dec. */ - palMapqkz( ra, dec, def->amprms, &raa, &deca ); - -/* If not already done so, get the local apparent siderial time (in radians) - and store in the supplied frame definition structure. */ - if( def->last == AST__BAD ) def->last = palGmst( def->epoch ) + - palEqeqx( def->epoch ) + - def->obslon; - -/* Get the component away from the source, of the velocity of the observer - relative to the centre of the earth (in m/s). */ - vobs = 1000.0*Rverot( def->obslat, def->obsalt, raa, deca, def->last, - status ); - -/* Get the component away from the source, of the velocity of the earth's - centre relative to the Sun, in m/s. */ - vearth = GeoVel( ra, dec, def, status ); - -/* Return the total velocity of the observer away from the source in the - frame of the sun. */ - return vobs + vearth; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a SpecMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* SpecMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a SpecMap and a set of points encapsulated -* in a PointSet and transforms the points so as to perform the -* sequence of spectral coordinate conversions specified by -* previous invocations of astSpecAdd. - -* Parameters: -* this -* Pointer to the SpecMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the SpecMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstSpecMap *map; /* Pointer to SpecMap to be applied */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *spec; /* Pointer to output spectral axis value array */ - double *alpha; /* Pointer to output RA axis value array */ - double *beta; /* Pointer to output DEC axis value array */ - int cvt; /* Loop counter for conversions */ - int end; /* Termination index for conversion loop */ - int inc; /* Increment for conversion loop */ - int map3d; /* Is the SpecMap 3-dimensional? */ - int ncoord_in; /* Number of coordinates per input point */ - int npoint; /* Number of points */ - int start; /* Starting index for conversion loop */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the SpecMap. */ - map = (AstSpecMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - coordinate conversions needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - ncoord_in = astGetNcoord( in ); - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse transformation, according - to the direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( this ) ) forward = !forward; - -/* Transform the coordinate values. */ -/* -------------------------------- */ -/* Use "spec" as a synonym for the array of spectral axis values stored in - the output PointSet. */ - if ( astOK ) { - spec = ptr_out[ 0 ]; - -/* If this is a 3D SpecMap use "alpha" as a synonym for the array of RA axis - values and "beta" as a synonym for the array of DEC axis values stored - in the output PointSet. */ - map3d = ( ncoord_in == 3 ); - if( map3d ) { - alpha = ptr_out[ 1 ]; - beta = ptr_out[ 2 ]; - } else { - alpha = NULL; - beta = NULL; - } - -/* Initialise the output coordinate values by copying the input ones. */ - (void) memcpy( spec, ptr_in[ 0 ], sizeof( double ) * (size_t) npoint ); - if( map3d ) { - (void) memcpy( alpha, ptr_in[ 1 ], sizeof( double ) * (size_t) npoint ); - (void) memcpy( beta, ptr_in[ 2 ], sizeof( double ) * (size_t) npoint ); - } - -/* We will loop to apply each spectral coordinate conversion in turn to the - (spec) array. However, if the inverse transformation was requested, - we must loop through these transformations in reverse order, so set up - appropriate limits and an increment to control this loop. */ - start = forward ? 0 : map->ncvt - 1; - end = forward ? map->ncvt : -1; - inc = forward ? 1 : -1; - -/* Loop through the coordinate conversions in the required order. */ - for ( cvt = start; cvt != end; cvt += inc ) { - -/* Process conversions which correspond to changes of reference frames. */ - if( !FrameChange( map->cvttype[ cvt ], npoint, alpha, beta, spec, - map->cvtargs[ cvt ], forward, status ) ) { - -/* If this conversion was not a change of reference frame, it must be a - change of system. */ - SystemChange( map->cvttype[ cvt ], npoint, spec, - map->cvtargs[ cvt ], forward, status ); - } - } - } - -/* If an error has occurred and a new PointSet may have been created, then - clean up by annulling it. In any case, ensure that a NULL result is - returned.*/ - if ( !astOK ) { - if ( !out ) result = astAnnul( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; - -} - -static double UserVel( double ra, double dec, FrameDef *def, int *status ) { -/* -* Name: -* UserVel - -* Purpose: -* Find the component of the velocity of the user-defined rest-frame -* away from the source. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* double UserVel( double ra, double dec, FrameDef *def, int *status ) - -* Class Membership: -* SpecMap method. - -* Description: -* This function finds the component of the velocity of the user-defined -* rest-frame away from a specified position. The magnitude and direction -* of the rest-frames velocity are defined within the supplied "def" -* structure. The user-defined rest-frame is typically used to represent -* the velocity of the source within the heliocentric rest-frame. - -* Parameters: -* ra -* The RA (rads, FK5 J2000) of the source. -* dec -* The Dec (rads, FK5 J2000) of the source. -* def -* Pointer to a FrameDef structure which holds the parameters which -* define the frame, together with cached intermediate results. -* status -* Pointer to the inherited status variable. - -* Returns: -* The component of the frame's velocity away from the position given by -* "ra" and "dec", in m/s, measured within the Heliographic frame of -* rest. Zero is returned if an error has already occurred. - -* Notes: -* - The direction of the user velocity is given by def->refra and -* def->refdec (an FK5 J2000 position). The maginitude of the velocity -* is given by def->veluser, in m/s, positive when the source is moving -* away from the observer towards def->refra, def->refdec, and given -* with respect to the heliocentric rest-frame. - -*/ - -/* Local Variables: */ - double vb[ 3 ]; /* Source position vector */ - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* If not already done so, express the user velocity in the form of a - J2000.0 x,y,z vector. */ - if( def->vuser[ 0 ] == AST__BAD ) { - def->vuser[ 0 ] = def->veluser*cos( def->refra )*cos( def->refdec ); - def->vuser[ 1 ] = def->veluser*sin( def->refra )*cos( def->refdec ); - def->vuser[ 2 ] = def->veluser*sin( def->refdec ); - } - -/* Convert given J2000 RA,Dec to x,y,z. */ - palDcs2c( ra, dec, vb ); - -/* Return the dot product with the user velocity. Invert it to get the - velocity towards the observer (the def->veluser value is supposed to be - positive if the source is moving away from the observer). */ - return -palDvdv( def->vuser, vb ); -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for SpecMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for SpecMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstSpecMap *in; /* Pointer to input SpecMap */ - AstSpecMap *out; /* Pointer to output SpecMap */ - int cvt; /* Loop counter for coordinate conversions */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output SpecMap structures. */ - in = (AstSpecMap *) objin; - out = (AstSpecMap *) objout; - -/* For safety, first clear any references to the input memory from the output - SpecMap. */ - out->cvtargs = NULL; - out->cvttype = NULL; - -/* Allocate memory for the output array of argument list pointers. */ - out->cvtargs = astMalloc( sizeof( double * ) * (size_t) in->ncvt ); - -/* If necessary, allocate memory and make a copy of the input array of - coordinate conversion codes. */ - if ( in->cvttype ) out->cvttype = astStore( NULL, in->cvttype, - sizeof( int ) - * (size_t) in->ncvt ); - -/* If OK, loop through each conversion in the input SpecMap and make a copy of - its argument list, storing the new pointer in the output argument list - array. */ - if ( astOK ) { - for ( cvt = 0; cvt < in->ncvt; cvt++ ) { - out->cvtargs[ cvt ] = astStore( NULL, in->cvtargs[ cvt ], - astSizeOf( in->cvtargs[ cvt ] ) ); - } - -/* If an error occurred while copying the argument lists, loop through the - conversions again and clean up by ensuring that the new memory allocated for - each argument list is freed. */ - if ( !astOK ) { - for ( cvt = 0; cvt < in->ncvt; cvt++ ) { - out->cvtargs[ cvt ] = astFree( out->cvtargs[ cvt ] ); - } - } - } - -/* If an error occurred, free all other memory allocated above. */ - if ( !astOK ) { - out->cvtargs = astFree( out->cvtargs ); - out->cvttype = astFree( out->cvttype ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for SpecMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for SpecMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstSpecMap *this; /* Pointer to SpecMap */ - int cvt; /* Loop counter for coordinate conversions */ - -/* Obtain a pointer to the SpecMap structure. */ - this = (AstSpecMap *) obj; - -/* Loop to free the memory containing the argument list for each coordinate - conversion. */ - for ( cvt = 0; cvt < this->ncvt; cvt++ ) { - this->cvtargs[ cvt ] = astFree( this->cvtargs[ cvt ] ); - } - -/* Free the memory holding the array of conversion types and the array of - argument list pointers. */ - this->cvtargs = astFree( this->cvtargs ); - this->cvttype = astFree( this->cvttype ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SpecMap objects. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the SpecMap class to an output Channel. - -* Parameters: -* this -* Pointer to the SpecMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstSpecMap *this; /* Pointer to the SpecMap structure */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - const char *argdesc[ MAX_ARGS ]; /* Pointers to argument descriptions */ - const char *comment; /* Pointer to comment string */ - const char *sval; /* Pointer to string value */ - int argdec; /* Index of DEC argument */ - int argra; /* Index of RA argument */ - int iarg; /* Loop counter for arguments */ - int icvt; /* Loop counter for conversion steps */ - int ival; /* Integer value */ - int nargs; /* Number of user-supplied arguments */ - int szargs; /* Number of stored arguments */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecMap structure. */ - this = (AstSpecMap *) this_object; - -/* Write out values representing the instance variables for the SpecMap - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Number of conversion steps. */ -/* --------------------------- */ -/* Regard this as "set" if it is non-zero. */ - ival = this->ncvt; - set = ( ival != 0 ); - astWriteInt( channel, "Nspec", set, 0, ival, "Number of conversion steps" ); - -/* Write out data for each conversion step... */ - for ( icvt = 0; icvt < this->ncvt; icvt++ ) { - -/* Conversion type. */ -/* ---------------- */ -/* Change each conversion type code into an equivalent string and - obtain associated descriptive information. If the conversion code - was not recognised, report an error and give up. */ - if ( astOK ) { - sval = CvtString( this->cvttype[ icvt ], &comment, &argra, &argdec, - &nargs, &szargs, argdesc, status ); - if ( astOK && !sval ) { - astError( AST__SPCIN, - "astWrite(%s): Corrupt %s contains invalid SpecMap " - "spectral coordinate conversion code (%d).", status, - astGetClass( channel ), astGetClass( this ), - (int) this->cvttype[ icvt ] ); - break; - } - -/* Create an appropriate keyword and write out the conversion code - information. */ - (void) sprintf( key, "Spec%d", icvt + 1 ); - astWriteString( channel, key, 1, 1, sval, comment ); - -/* Write out data for each conversion argument... */ - for ( iarg = 0; iarg < szargs; iarg++ ) { - -/* Arguments. */ -/* ---------- */ -/* Create an appropriate keyword and write out the argument value, - accompanied by the descriptive comment obtained above. */ - if( this->cvtargs[ icvt ][ iarg ] != AST__BAD ) { - (void) sprintf( key, "Spec%d%c", icvt + 1, ALPHABET[ iarg ] ); - astWriteDouble( channel, key, 1, 1, this->cvtargs[ icvt ][ iarg ], - argdesc[ iarg ] ); - } - } - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - } - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASpecMap and astCheckSpecMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SpecMap,Mapping) -astMAKE_CHECK(SpecMap) - -AstSpecMap *astSpecMap_( int nin, int flags, const char *options, int *status, ...) { -/* -*++ -* Name: -c astSpecMap -f AST_SPECMAP - -* Purpose: -* Create a SpecMap. - -* Type: -* Public function. - -* Synopsis: -c #include "specmap.h" -c AstSpecMap *astSpecMap( int nin, int flags, const char *options, ... ) -f RESULT = AST_SPECMAP( NIN, FLAGS, OPTIONS, STATUS ) - -* Class Membership: -* SpecMap constructor. - -* Description: -* This function creates a new SpecMap and optionally initialises -* its attributes. -* -* An SpecMap is a specialised form of Mapping which can be used to -* represent a sequence of conversions between standard spectral -* coordinate systems. This includes conversions between frequency, -* wavelength, and various forms of velocity, as well as conversions -* between different standards of rest. -* -* When a SpecMap is first created, it simply performs a unit -c (null) Mapping. Using the astSpecAdd function, -f (null) Mapping. Using the AST_SPECADD routine, -* a series of coordinate conversion steps may then be added, selected -* from the list of supported conversions. This allows multi-step -* conversions between a variety of spectral coordinate systems to -* be assembled out of the building blocks provided by this class. -* -* For details of the individual coordinate conversions available, -c see the description of the astSpecAdd function. -f see the description of the AST_SPECADD routine. -* -* Conversions are available to transform between standards of rest. -* Such conversions need to know the source position as an RA and DEC. -* This information can be supplied in the form of parameters for -* the relevant conversions, in which case the SpecMap is 1-dimensional, -* simply transforming the spectral axis values. This means that the -* same source position will always be used by the SpecMap. However, this -* may not be appropriate for an accurate description of a 3-D spectral -* cube, where changes of spatial position can produce significant -* changes in the Doppler shift introduced when transforming between -* standards of rest. For this situation, a 3-dimensional SpecMap can -* be created in which axes 2 and 3 correspond to the source RA and DEC -* The SpecMap simply copies values for axes 2 and 3 from input to -* output). - -* Parameters: -c nin -f NIN = INTEGER (Given) -* The number of inputs to the Mapping (this will also equal the -* number of outputs). This value must be either 1 or 3. In either -* case, the first input and output correspoindis the spectral axis. -* For a 3-axis SpecMap, the second and third axes give the RA and -* DEC (J2000 FK5) of the source. This positional information is -* used by conversions which transform between standards of rest, -* and replaces the "RA" and "DEC" arguments for the individual -* conversions listed in description of the "SpecAdd" -c function. -f routine. -c flags -f FLAGS = INTEGER (Given) -c This parameter is reserved for future use and should currently -f This argument is reserved for future use and should currently -* always be set to zero. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new SpecMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new SpecMap. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSpecMap() -f AST_SPECMAP = INTEGER -* A pointer to the new SpecMap. - -* Notes: -* - The nature and units of the coordinate values supplied for the -* first input (i.e. the spectral input) of a SpecMap must be appropriate -* to the first conversion step applied by the SpecMap. For instance, if -* the first conversion step is "FRTOVL" (frequency to relativistic -* velocity), then the coordinate values for the first input should -* be frequency in units of Hz. Similarly, the nature and units of the -* coordinate values returned by a SpecMap will be determined by the -* last conversion step applied by the SpecMap. For instance, if the -* last conversion step is "VLTOVO" (relativistic velocity to optical -* velocity), then the coordinate values for the first output will be optical -* velocity in units of metres per second. See the description of the -c astSpecAdd function for the units expected and returned by each -f AST_SPECADD routine for the units expected and returned by each -* conversion. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSpecMap *new; /* Pointer to the new SpecMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SpecMap, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSpecMap( NULL, sizeof( AstSpecMap ), !class_init, &class_vtab, - "SpecMap", nin, flags ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SpecMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new SpecMap. */ - return new; -} - -AstSpecMap *astSpecMapId_( int nin, int flags, const char *options, ... ) { -/* -* Name: -* astSpecMapId_ - -* Purpose: -* Create a SpecMap. - -* Type: -* Private function. - -* Synopsis: -* #include "specmap.h" -* AstSpecMap *astSpecMapId_( int nin, int flags, const char *options, ... ) - -* Class Membership: -* SpecMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astSpecMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astSpecMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astSpecMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astSpecMap_. - -* Returned Value: -* The ID value associated with the new SpecMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSpecMap *new; /* Pointer to the new SpecMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SpecMap, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSpecMap( NULL, sizeof( AstSpecMap ), !class_init, &class_vtab, - "SpecMap", nin, flags ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SpecMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new SpecMap. */ - return astMakeId( new ); -} - -AstSpecMap *astInitSpecMap_( void *mem, size_t size, int init, - AstSpecMapVtab *vtab, const char *name, - int nin, int flags, int *status ) { -/* -*+ -* Name: -* astInitSpecMap - -* Purpose: -* Initialise a SpecMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "specmap.h" -* AstSpecMap *astInitSpecMap( void *mem, size_t size, int init, -* AstSpecMapVtab *vtab, const char *name, -* int nin, int flags ) - -* Class Membership: -* SpecMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new SpecMap object. It allocates memory (if necessary) to accommodate -* the SpecMap plus any additional data associated with the derived class. -* It then initialises a SpecMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a SpecMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SpecMap is to be initialised. -* This must be of sufficient size to accommodate the SpecMap data -* (sizeof(SpecMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the SpecMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the SpecMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the SpecMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new SpecMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astClass -* method). -* nin -* The number of inputs and outputs for the SpecMap (either 1 or 3). -* flags -* This parameter is reserved for future use. It is currently ignored. - -* Returned Value: -* A pointer to the new SpecMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstSpecMap *new; /* Pointer to the new SpecMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Check nin is OK (1 or 3). */ - if( nin != 1 && nin != 3 ) { - astError( AST__BADNI, "astInitSpecMap(SpecMap): Supplied number of " - "SpecMap axes (%d) is illegal; it should be 1 or 2. ", status, - nin ); - } - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSpecMapVtab( vtab, name ); - -/* Initialise a 1D Mapping structure (the parent class) as the first component - within the SpecMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstSpecMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, nin, 1, 1 ); - - if ( astOK ) { - -/* Initialise the SpecMap data. */ -/* --------------------------- */ -/* The initial state is with no conversions set, in which condition the - SpecMap simply implements a unit mapping. */ - new->ncvt = 0; - new->cvtargs = NULL; - new->cvttype = NULL; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstSpecMap *astLoadSpecMap_( void *mem, size_t size, - AstSpecMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSpecMap - -* Purpose: -* Load a SpecMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "specmap.h" -* AstSpecMap *astLoadSpecMap( void *mem, size_t size, -* AstSpecMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* SpecMap loader. - -* Description: -* This function is provided to load a new SpecMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* SpecMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a SpecMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the SpecMap is to be -* loaded. This must be of sufficient size to accommodate the -* SpecMap data (sizeof(SpecMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SpecMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SpecMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstSpecMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SpecMap. If this is NULL, a pointer to -* the (static) virtual function table for the SpecMap class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "SpecMap" is used instead. - -* Returned Value: -* A pointer to the new SpecMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstSpecMap *new; /* Pointer to the new SpecMap */ - char *sval; /* Pointer to string value */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - const char *argdesc[ MAX_ARGS ]; /* Pointers to argument descriptions */ - const char *comment; /* Pointer to comment string */ - int argdec; /* Index of DEC argument */ - int argra; /* Index of RA argument */ - int iarg; /* Loop counter for arguments */ - int icvt; /* Loop counter for conversion steps */ - int nargs; /* Number of user-supplied arguments */ - int szargs; /* Number of stored arguments */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SpecMap. In this case the - SpecMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSpecMap ); - vtab = &class_vtab; - name = "SpecMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSpecMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built SpecMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "SpecMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Number of conversion steps. */ -/* --------------------------- */ -/* Read the number of conversion steps and allocate memory to hold - data for each step. */ - new->ncvt = astReadInt( channel, "nspec", 0 ); - if ( new->ncvt < 0 ) new->ncvt = 0; - new->cvttype = astMalloc( sizeof( int ) * (size_t) new->ncvt ); - new->cvtargs = astMalloc( sizeof( double * ) * (size_t) new->ncvt ); - -/* If an error occurred, ensure that all allocated memory is freed. */ - if ( !astOK ) { - new->cvttype = astFree( new->cvttype ); - new->cvtargs = astFree( new->cvtargs ); - -/* Otherwise, initialise the argument pointer array. */ - } else { - for ( icvt = 0; icvt < new->ncvt; icvt++ ) { - new->cvtargs[ icvt ] = NULL; - } - -/* Read in data for each conversion step... */ - for ( icvt = 0; icvt < new->ncvt; icvt++ ) { - -/* Conversion type. */ -/* ---------------- */ -/* Create an appropriate keyword and read the string representation of - the conversion type. */ - (void) sprintf( key, "spec%d", icvt + 1 ); - sval = astReadString( channel, key, NULL ); - -/* If no value was read, report an error. */ - if ( astOK ) { - if ( !sval ) { - astError( AST__BADIN, - "astRead(%s): A spectral coordinate conversion " - "type is missing from the input SpecMap data.", status, - astGetClass( channel ) ); - -/* Otherwise, convert the string representation into the required - conversion type code. */ - } else { - new->cvttype[ icvt ] = CvtCode( sval, status ); - -/* If the string was not recognised, report an error. */ - if ( new->cvttype[ icvt ] == AST__SPEC_NULL ) { - astError( AST__BADIN, - "astRead(%s): Invalid spectral conversion " - "type \"%s\" in SpecMap data.", status, - astGetClass( channel ), sval ); - } - } - -/* Free the memory holding the string value. */ - sval = astFree( sval ); - } - -/* Obtain the number of arguments associated with the conversion and - allocate memory to hold them. */ - (void) CvtString( new->cvttype[ icvt ], &comment, &argra, - &argdec, &nargs, &szargs, argdesc, status ); - new->cvtargs[ icvt ] = astMalloc( sizeof( double ) * - (size_t) szargs ); - -/* Read in data for each argument... */ - if ( astOK ) { - for ( iarg = 0; iarg < szargs; iarg++ ) { - -/* Arguments. */ -/* ---------- */ -/* Create an appropriate keyword and read each argument value. */ - (void) sprintf( key, "spec%d%c", icvt + 1, ALPHABET[ iarg ] ); - new->cvtargs[ icvt ][ iarg ] = astReadDouble( channel, key, - AST__BAD ); - } - } - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - } - -/* If an error occurred, clean up by deleting the new SpecMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new SpecMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -void astSpecAdd_( AstSpecMap *this, const char *cvt, int narg, - const double args[], int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,SpecMap,SpecAdd))( this, cvt, narg, args, status ); -} - - - - diff --git a/ast/specmap.h b/ast/specmap.h deleted file mode 100644 index d266ba1..0000000 --- a/ast/specmap.h +++ /dev/null @@ -1,282 +0,0 @@ -#if !defined( SPECMAP_INCLUDED ) /* Include this file only once */ -#define SPECMAP_INCLUDED -/* -*+ -* Name: -* specmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the SpecMap class. - -* Invocation: -* #include "specmap.h" - -* Description: -* This include file defines the interface to the SpecMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The SpecMap class encapsulates various ecptral coordinate -* conversions. Since, typically, a sequence of these conversions is -* required, a SpecMap can be used to accumulate a series of conversions -* which it then applies in sequence. - -* Inheritance: -* The SpecMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* astTransform -* Use an SpecMap to transform a set of points. - -* Protected: -* astMapMerge -* Simplify a sequence of Mappings containing an SpecMap. - -* New Methods Defined: -* Public: -* astSpecAdd -* Add a coordinate conversion step to an SpecMap. - -* Private: -* None. - -* Other Class Functions: -* Public: -* astIsASpecMap -* Test class membership. -* astSpecMap -* Create an SpecMap. - -* Protected: -* astCheckSpecMap -* Validate class membership. -* astInitSpecMap -* Initialise an SpecMap. -* astLoadSpecMap -* Load an SpecMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstSpecMap -* SpecMap object type. - -* Protected: -* AstSpecMapVtab -* SpecMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 8-NOV-2002 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ------ */ -/* Physical constants taken from Chapter 15 of the "Explanatory Supplement - to the Astronomical Ephemeris". */ -#define AST__C 2.99792458E8 /* Speed of light (metres per second) */ -#define AST__H 6.6260755E-34 /* Plank constant (Joule.seconds) */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* SpecMap structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstSpecMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int *cvttype; /* Pointer to array of conversion types */ - double **cvtargs; /* Pointer to argument list pointer array */ - int ncvt; /* Number of conversions to perform */ -} AstSpecMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstSpecMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* SpecAdd)( AstSpecMap *, const char *, int, const double[], int * ); -} AstSpecMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstSpecMapGlobals { - AstSpecMapVtab Class_Vtab; - int Class_Init; -} AstSpecMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitSpecMapGlobals_( AstSpecMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(SpecMap) /* Check class membership */ -astPROTO_ISA(SpecMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstSpecMap *astSpecMap_( int, int, const char *, int *, ...); -#else -AstSpecMap *astSpecMapId_( int, int, const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstSpecMap *astInitSpecMap_( void *, size_t, int, AstSpecMapVtab *, - const char *, int, int, int * ); - -/* Vtab initialiser. */ -void astInitSpecMapVtab_( AstSpecMapVtab *, const char *, int * ); - -/* Loader. */ -AstSpecMap *astLoadSpecMap_( void *, size_t, AstSpecMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -void astSpecAdd_( AstSpecMap *, const char *, int, const double[], int * ); - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckSpecMap(this) astINVOKE_CHECK(SpecMap,this,0) -#define astVerifySpecMap(this) astINVOKE_CHECK(SpecMap,this,1) - -/* Test class membership. */ -#define astIsASpecMap(this) astINVOKE_ISA(SpecMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astSpecMap astINVOKE(F,astSpecMap_) -#else -#define astSpecMap astINVOKE(F,astSpecMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitSpecMap(mem,size,init,vtab,name,nin,flags) \ -astINVOKE(O,astInitSpecMap_(mem,size,init,vtab,name,nin,flags,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitSpecMapVtab(vtab,name) astINVOKE(V,astInitSpecMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadSpecMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadSpecMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckSpecMap to validate SpecMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -#define astSpecAdd(this,cvt,narg,args) \ -astINVOKE(V,astSpecAdd_(astCheckSpecMap(this),cvt,narg,args,STATUS_PTR)) - -#endif - - - - - diff --git a/ast/sphmap.c b/ast/sphmap.c deleted file mode 100644 index bc4018c..0000000 --- a/ast/sphmap.c +++ /dev/null @@ -1,2061 +0,0 @@ -/* -*class++ -* Name: -* SphMap - -* Purpose: -* Map 3-d Cartesian to 2-d spherical coordinates - -* Constructor Function: -c astSphMap -f AST_SPHMAP - -* Description: -* A SphMap is a Mapping which transforms points from a -* 3-dimensional Cartesian coordinate system into a 2-dimensional -* spherical coordinate system (longitude and latitude on a unit -* sphere centred at the origin). It works by regarding the input -* coordinates as position vectors and finding their intersection -* with the sphere surface. The inverse transformation always -* produces points which are a unit distance from the origin -* (i.e. unit vectors). - -* Inheritance: -* The SphMap class inherits from the Mapping class. - -* Attributes: -* In addition to those attributes common to all Mappings, every -* SphMap also has the following attributes: -* -* - UnitRadius: SphMap input vectors lie on a unit sphere? -* - PolarLong: The longitude value to assign to either pole - -* Functions: -c The SphMap class does not define any new functions beyond those -f The SphMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 24-OCT-1996 (DSB): -* Original version. -* 5-MAR-1997 (RFWS): -* Tidied public prologues. -* 24-MAR-1998 (RFWS): -* Override the astMapMerge method. -* 4-SEP-1998 (DSB): -* Added UnitRadius attribute. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitSphMapVtab -* method. -* 11-JUN-2003 (DSB): -* Added PolarLong attribute. -* 10-MAY-2006 (DSB): -* Override astEqual. -* 5-NOV-2013 (DSB): -* Modify MapMerge so that it can spot and simplify an -* (inverted SphMap,MatrixMap,SphMap) sequence in which the -* MatrixMap just magnifies or reflects the radius vector. -* 25-MAR-2014 (DSB): -* Correct 5-NOV-2013 MapMerge change. -* 28-APR-2016 (DSB): -* Avoid modifying the attributes of the existing SphMap in -* MapMerge, since it may be in use in other contexts. Modify a -* copy instead. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS SphMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "unitmap.h" /* Unit (identity) Mappings */ -#include "sphmap.h" /* Interface definition for this class */ -#include "pal.h" /* SLA transformations */ -#include "wcsmap.h" /* For the AST__DPIBY2 (etc) constants */ -#include "matrixmap.h" /* Matrix mappings */ -#include "winmap.h" /* Shift and scale mappings */ -#include "zoommap.h" /* Scale mappings */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(SphMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SphMap,Class_Init) -#define class_vtab astGLOBAL(SphMap,Class_Vtab) -#define getattrib_buff astGLOBAL(SphMap,GetAttrib_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSphMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSphMap *astSphMapId_( const char *, ...); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static int GetUnitRadius( AstSphMap *, int * ); -static int TestUnitRadius( AstSphMap *, int * ); -static void ClearUnitRadius( AstSphMap *, int * ); -static void SetUnitRadius( AstSphMap *, int, int * ); - -static double GetPolarLong( AstSphMap *, int * ); -static int TestPolarLong( AstSphMap *, int * ); -static void ClearPolarLong( AstSphMap *, int * ); -static void SetPolarLong( AstSphMap *, double, int * ); - -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -/* Member functions. */ -/* ================= */ -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a SphMap. - -* Type: -* Private function. - -* Synopsis: -* #include "sphmap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status, int *status ) - -* Class Membership: -* SphMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* SphMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the SphMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSphMap *this; /* Pointer to the SphMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SphMap structure. */ - this = (AstSphMap *) this_object; - -/* UnitRadius */ -/* ---------- */ - if ( !strcmp( attrib, "unitradius" ) ) { - astClearUnitRadius( this ); - -/* PolarLong */ -/* --------- */ - } else if ( !strcmp( attrib, "polarlong" ) ) { - astClearPolarLong( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two SphMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "sphmap.h" -* int Equal( AstObject *this, AstObject *that, int *status, int *status ) - -* Class Membership: -* SphMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two SphMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a SphMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the SphMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSphMap *that; - AstSphMap *this; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two SphMap structures. */ - this = (AstSphMap *) this_object; - that = (AstSphMap *) that_object; - -/* Check the second object is a SphMap. We know the first is a - SphMap since we have arrived at this implementation of the virtual - function. */ - if( astIsASphMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two SphMaps differ, it may still be possible - for them to be equivalent. First compare the SphMaps if their Invert - flags are the same. In this case all the attributes of the two SphMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - - if( astEQUAL( this->polarlong, that->polarlong ) && - this->unitradius == that->unitradius ){ - result = 1; - } - -/* If the Invert flags for the two SphMaps differ, the attributes of the two - SphMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a SphMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a SphMap. - -* Type: -* Private function. - -* Synopsis: -* #include "sphmap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status, int *status ) - -* Class Membership: -* SphMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a SphMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the SphMap. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the SphMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the SphMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSphMap *this; /* Pointer to the SphMap structure */ - const char *result; /* Pointer value to return */ - double dval; /* Double precision attribute value */ - int ival; /* Int attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the SphMap structure. */ - this = (AstSphMap *) this_object; - -/* UnitRadius. */ -/* ----------- */ - if ( !strcmp( attrib, "unitradius" ) ) { - ival = astGetUnitRadius( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* PolarLong */ -/* --------- */ - } else if ( !strcmp( attrib, "polarlong" ) ) { - dval = astGetPolarLong( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -void astInitSphMapVtab_( AstSphMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSphMapVtab - -* Purpose: -* Initialise a virtual function table for a SphMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "sphmap.h" -* void astInitSphMapVtab( AstSphMapVtab *vtab, const char *name ) - -* Class Membership: -* SphMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SphMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASphMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->ClearUnitRadius = ClearUnitRadius; - vtab->SetUnitRadius = SetUnitRadius; - vtab->GetUnitRadius = GetUnitRadius; - vtab->TestUnitRadius = TestUnitRadius; - - vtab->ClearPolarLong = ClearPolarLong; - vtab->SetPolarLong = SetPolarLong; - vtab->GetPolarLong = GetPolarLong; - vtab->TestPolarLong = TestPolarLong; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the class dump, copy and delete functions.*/ - astSetDump( vtab, Dump, "SphMap", "Cartesian to Spherical mapping" ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - astSetDelete( (AstObjectVtab *) vtab, Delete ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a SphMap. - -* Type: -* Private function. - -* Synopsis: -* #include "sphmap.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status, int *status ) - -* Class Membership: -* SphMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated SphMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated SphMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated SphMap which is to be merged with -* its neighbours. This should be a cloned copy of the SphMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* SphMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated SphMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *new; /* Pointer to replacement Mapping */ - AstMatrixMap *mm; /* Pointer to MatrixMap */ - AstSphMap *sm; /* The new SphMap */ - AstWinMap *wm; /* The new WinMap */ - const char *class; /* Pointer to Mapping class string */ - double absval; /* Absolute value fo each diagonal element */ - double diag[ 3 ]; /* The diagonal matrix elements */ - double polarlong; /* Value of PolarLong attribute */ - int imap1; /* Index of first SphMap */ - int imap2; /* Index of second SphMap */ - int imap; /* Loop counter for Mappings */ - int result; /* Result value to return */ - int simpler; /* Mappings simplified? */ - -/* Initialise the returned result. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Further initialisation. */ - new = NULL; - simpler = 0; - -/* We will only handle the case of SphMaps in series and will consider - merging the nominated SphMap with the Mapping which follows - it. Check that there is such a Mapping. */ - if ( series && ( ( where + 1 ) < *nmap ) ) { - -/* Obtain the indices of the two potential SphMaps to be merged. */ - imap1 = where; - imap2 = where + 1; - -/* Obtain the Class string of the second Mapping and determine if it - is a SphMap. */ - class = astGetClass( ( *map_list )[ imap2 ] ); - if ( astOK && !strcmp( class, "SphMap" ) ) { - -/* Check if the first SphMap is applied in the inverse direction and - the second in the forward direction. This combination can be - simplified if the PolarLongitude attributes are equal.. */ - if( ( *invert_list )[ imap1 ] && !( *invert_list )[ imap2 ] ) { - simpler = astEQUAL( astGetPolarLong( ( *map_list )[ imap1 ] ), - astGetPolarLong( ( *map_list )[ imap2 ] ) ); - -/* If the first SphMap is applied in the forward direction and the second in - the inverse direction, the combination can only be simplified if the - input vectors to the first SphMap all have unit length (as indicated by - the UnitRadius attribute). */ - } else if( !( *invert_list )[ imap1 ] && ( *invert_list )[ imap2 ] ) { - simpler = astGetUnitRadius( ( *map_list )[ imap1 ] ); - } - } - -/* If the two SphMaps can be simplified, create a UnitMap to replace - them. */ - if ( simpler ) { - new = (AstMapping *) astUnitMap( 2, "", status ); - -/* Annul the pointers to the SphMaps. */ - if ( astOK ) { - ( *map_list )[ imap1 ] = astAnnul( ( *map_list )[ imap1 ] ); - ( *map_list )[ imap2 ] = astAnnul( ( *map_list )[ imap2 ] ); - -/* Insert the pointer to the replacement Mapping and initialise its - invert flag. */ - ( *map_list )[ imap1 ] = new; - ( *invert_list )[ imap1 ] = 0; - -/* Loop to close the resulting gap by moving subsequent elements down - in the arrays. */ - for ( imap = imap2 + 1; imap < *nmap; imap++ ) { - ( *map_list )[ imap - 1 ] = ( *map_list )[ imap ]; - ( *invert_list )[ imap - 1 ] = ( *invert_list )[ imap ]; - } - -/* Clear the vacated elements at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = imap1; - } - } - } - -/* Another possible simplification is if the nominated Mapping is an inverted - SphMap followed in series by a ZoomMap or diagonal MatrixMap that has - diagonal elements of equal magnitude, which is then followed by a - non-inverted SphMap. This is equivalent to a 3D rotation of a pair of - (longitude,latitude) angles. The MatrixMap/ZoomMap may magnify the - radius vector, but this will not alter the angles. Any difference in - signs amongst the diagonal elements will cause a reflection or reversal - of the corresponbding angles, which can be represented by a WinMap. We - do not need to consider the other possibility (that the nominated - SphMap is the *last* Mapping in such a sequence of three), since we - will already have discovered such a sequence on an earlier invocation - of this function. */ - if( series && !simpler && ( *invert_list )[ where ] && - where + 2 < *nmap ) { - -/* Check the third Mapping is a non-inverted SphMap. */ - class = astGetClass( ( *map_list )[ where + 2 ] ); - if( astOK && !strcmp( class, "SphMap" ) && - !( *invert_list )[ where + 2 ] ) { - -/* Check the second Mapping is a ZoomMap, or a diagonal MatrixMap that - has diagonal elements of equal magnitude. Since the Mapping is - sandwiched between the two SphMaps, we know it must have 3 inputs and - 3 outputs. Record the corresponding diagonal values. The state of the - Invert flag does not matter since it will only affect the degree to - which the radius vector is magnified - it will not change the signs of - any diagonal elements. */ - class = astGetClass( ( *map_list )[ where + 1 ] ); - if( astOK && !strcmp( class, "ZoomMap" ) ) { - diag[ 0 ] = astGetZoom( ( *map_list )[ where + 1 ] ); - if( diag[ 0 ] != 0.0 ) { - diag[ 1 ] = diag[ 0 ]; - diag[ 2 ] = diag[ 0 ]; - } else { - class = NULL; - } - - } else if( astOK && !strcmp( class, "MatrixMap" ) ) { - mm = (AstMatrixMap *) ( *map_list )[ where + 1 ]; - if( mm->form == 1 && mm->f_matrix ) { - diag[ 0 ] = mm->f_matrix[ 0 ]; - if( diag[ 0 ] != 0.0 ) { - diag[ 1 ] = mm->f_matrix[ 1 ]; - diag[ 2 ] = mm->f_matrix[ 2 ]; - - absval = fabs( diag[ 0 ] ); - if( !astEQUAL( fabs( diag[ 1 ] ), absval ) || - !astEQUAL( fabs( diag[ 2 ] ), absval ) ) { - class = NULL; - } - - } else { - class = NULL; - } - - } else { - class = NULL; - } - - } else { - class = NULL; - } - - } else { - class = NULL; - } - -/* We can only make changes if above conditions were met. */ - if( class ) { - -/* Create a WinMap that modifies the (longitude,latitude) values, initially - with undefined corners. */ - wm = astWinMap( 2, NULL, NULL, NULL, NULL, "", status ); - -/* Store appropriate scales and offsets in the WinMap. These just depend on - the signs of the matrix diagonal elements since we know the magnitudes of - these elements are all equal. */ - if( diag[ 0 ] < 0.0 ) { - if( diag[ 1 ] < 0.0 ) { - wm->a[ 0 ] = AST__DPI; - wm->b[ 0 ] = 1.0; - } else { - wm->a[ 0 ] = AST__DPI; - wm->b[ 0 ] = -1.0; - } - - } else { - if( diag[ 1 ] < 0.0 ) { - wm->a[ 0 ] = 0.0; - wm->b[ 0 ] = -1.0; - } else { - wm->a[ 0 ] = 0.0; - wm->b[ 0 ] = 1.0; - } - } - - if( diag[ 2 ] < 0.0 ) { - wm->a[ 1 ] = 0.0; - wm->b[ 1 ] = -1.0; - } else { - wm->a[ 1 ] = 0.0; - wm->b[ 1 ] = 1.0; - } - -/* We are aiming to replace the supplied (SphMap,MatrixMap,SphMap) - combination with (WinMap,SphMap,SphMap), leaving us with an inverted - and non-inverted SphMap side by side. This is on the understanding - that a subsequent call to this function will combine these two - adjacent SphMaps into a UnitMap. But this will only happen if the - adjacent SphMaps have equal values for their PolarLong attributes. The - change of (SphMap,MatrixMap) to (WinMap,SphMap) will change the value - of the PolarLong attribute in the first SphMap, so we need to work out - this changed value and check that it is the same as the PolarLong - value of the second SphMap. If they are different, there is no point - making any changes since the two SphMaps cannot be merged into a - UnitMap. So get the PolarLong value from the supplied first SphMap. */ - polarlong = astGetPolarLong( ( *map_list )[ where ] ); - -/* Modified the PolarLong value to take account of the change from - (SphMap,MatrixMap) to (WinMap,SphMap). */ - polarlong = wm->a[ 0 ] + wm->b[ 0 ]*polarlong; - -/* Check this is the same as the PolarLong value in the second SphMap. */ - if( astEQUAL( polarlong, astGetPolarLong( ( *map_list )[ where + 2 ] ) ) ) { - -/* All is good, so we can now change the supplied Mappings list. First - get a copy of the first SphMap and change its PolarLong value. We use - a copy since the original may be in use in other contexts that could be - badly affected by the change. */ - sm = astCopy( ( *map_list )[ where ] ); - astSetPolarLong( sm, polarlong ); - -/* Annul the SphMap and the MatrixMap or ZoomMap. */ - (void) astAnnul( ( *map_list )[ where ] ); - (void) astAnnul( ( *map_list )[ where + 1 ] ); - -/* Store the modified SphMap in the slot left vacant by the annulled - MatrixMap or ZoomMap. */ - ( *map_list )[ where + 1 ] = (AstMapping *) sm; - ( *invert_list )[ where + 1 ] = ( *invert_list )[ where ]; - -/* Store the new WinMap in the place of the SphMap. */ - ( *map_list )[ where ] = astClone( wm ); - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - } - -/* Free resources. */ - wm = astAnnul( wm ); - } - } - -/* If an error occurred, clear the returned result. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a SphMap. - -* Type: -* Private function. - -* Synopsis: -* #include "sphmap.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* SphMap member function (over-rides the astSetAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function assigns an attribute value for a SphMap, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the SphMap. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstSphMap *this; /* Pointer to the SphMap structure */ - double dval; /* Double precision attribute value */ - int len; /* Length of setting string */ - int ival; /* Int attribute value */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SphMap structure. */ - this = (AstSphMap *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* UnitRadius */ -/* ---------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "unitradius= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetUnitRadius( this, ival ); - -/* PolarLong */ -/* --------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "polarlong= %lf %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetPolarLong( this, dval ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a SphMap. - -* Type: -* Private function. - -* Synopsis: -* #include "sphmap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status, int *status ) - -* Class Membership: -* SphMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a SphMap's attributes. - -* Parameters: -* this -* Pointer to the SphMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSphMap *this; /* Pointer to the SphMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SphMap structure. */ - this = (AstSphMap *) this_object; - -/* UnitRadius */ -/* ---------- */ - if ( !strcmp( attrib, "unitradius" ) ) { - result = astTestUnitRadius( this ); - -/* PolarLong */ -/* --------- */ - } else if ( !strcmp( attrib, "polarlong" ) ) { - result = astTestPolarLong( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a SphMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "sphmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status, int *status ) - -* Class Membership: -* SphMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a SphMap and a set of points encapsulated in a -* PointSet and transforms the points from Cartesian coordinates to -* spherical coordinates. - -* Parameters: -* this -* Pointer to the SphMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the SphMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstSphMap *map; /* Pointer to SphMap to be applied */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - int npoint; /* Number of points */ - int point; /* Loop counter for points */ - double *p0; /* Pointer to x axis value */ - double *p1; /* Pointer to y axis value */ - double *p2; /* Pointer to z axis value */ - double *q0; /* Pointer to longitude value */ - double *q1; /* Pointer to latitude value */ - double mxerr; /* Largest value which is effectively zero */ - double polarlong; /* Longitude at either pole */ - double v[3]; /* Vector for a single point */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the SphMap. */ - map = (AstSphMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse mapping, according to the - direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if( astOK ){ - -/* First deal with forward mappings from Cartesian to Spherical. */ - if( forward ){ - -/* Get the longitude to return at either pole. */ - polarlong = astGetPolarLong( this ); - -/* Store pointers to the input Cartesian axes. */ - p0 = ptr_in[ 0 ]; - p1 = ptr_in[ 1 ]; - p2 = ptr_in[ 2 ]; - -/* Store pointers to the output Spherical axes. */ - q0 = ptr_out[ 0 ]; - q1 = ptr_out[ 1 ]; - -/* Apply the mapping to every point. */ - for( point = 0; point < npoint; point++ ){ - if( *p0 != AST__BAD && *p1 != AST__BAD && *p2 != AST__BAD ){ - v[0] = *p0; - v[1] = *p1; - v[2] = *p2; - -/* At either pole, return the longitude equal to PolarLong attribute. */ - mxerr = fabs( 1000.0*v[ 2 ] )*DBL_EPSILON; - if( fabs( v[ 0 ] ) < mxerr && fabs( v[ 1 ] ) < mxerr ) { - if( v[ 2 ] < 0.0 ) { - *(q0++) = polarlong; - *(q1++) = -AST__DPIBY2; - } else if( v[ 2 ] > 0.0 ) { - *(q0++) = polarlong; - *(q1++) = AST__DPIBY2; - } else { - *(q0++) = AST__BAD; - *(q1++) = AST__BAD; - } - -/* Otherwise use a SLALIB function to do the conversion (SLALIB always - returns zero at either pole which is why we make the above check). */ - } else { - palDcc2s( v, q0++, q1++ ); - } - - } else { - *(q0++) = AST__BAD; - *(q1++) = AST__BAD; - } - p0++; - p1++; - p2++; - } - -/* Now deal with inverse mappings from Spherical to Cartesian. */ - } else { - -/* Store pointers to the input Spherical axes. */ - q0 = ptr_in[ 0 ]; - q1 = ptr_in[ 1 ]; - -/* Store pointers to the output Cartesian axes. */ - p0 = ptr_out[ 0 ]; - p1 = ptr_out[ 1 ]; - p2 = ptr_out[ 2 ]; - -/* Apply the mapping to every point. */ - for( point = 0; point < npoint; point++ ){ - if( *q0 != AST__BAD && *q1 != AST__BAD ){ - palDcs2c( *q0, *q1, v ); - *(p0++) = v[ 0 ]; - *(p1++) = v[ 1 ]; - *(p2++) = v[ 2 ]; - } else { - *(p0++) = AST__BAD; - *(p1++) = AST__BAD; - *(p2++) = AST__BAD; - - } - q0++; - q1++; - } - - } - - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* UnitRadius */ -/* ---------- */ -/* -*att++ -* Name: -* UnitRadius - -* Purpose: -* SphMap input vectors lie on a unit sphere? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This is a boolean attribute which indicates whether the -* 3-dimensional vectors which are supplied as input to a SphMap -* are known to always have unit length, so that they lie on a unit -* sphere centred on the origin. -* -c If this condition is true (indicated by setting UnitRadius -c non-zero), it implies that a CmpMap which is composed of a -c SphMap applied in the forward direction followed by a similar -c SphMap applied in the inverse direction may be simplified -c (e.g. by astSimplify) to become a UnitMap. This is because the -c input and output vectors will both have unit length and will -c therefore have the same coordinate values. -f If this condition is true (indicated by setting UnitRadius -f non-zero), it implies that a CmpMap which is composed of a -f SphMap applied in the forward direction followed by a similar -f SphMap applied in the inverse direction may be simplified -f (e.g. by AST_SIMPLIFY) to become a UnitMap. This is because the -f input and output vectors will both have unit length and will -f therefore have the same coordinate values. -* -* If UnitRadius is zero (the default), then although the output -* vector produced by the CmpMap (above) will still have unit -* length, the input vector may not have. This will, in general, -* change the coordinate values, so it prevents the pair of SphMaps -* being simplified. - -* Notes: -* - This attribute is intended mainly for use when SphMaps are -* involved in a sequence of Mappings which project (e.g.) a -* dataset on to the celestial sphere. By regarding the celestial -* sphere as a unit sphere (and setting UnitRadius to be non-zero) -* it becomes possible to cancel the SphMaps present, along with -* associated sky projections, when two datasets are aligned using -* celestial coordinates. This often considerably improves -* performance. -* - Such a situations often arises when interpreting FITS data and -* is handled automatically by the FitsChan class. -* - The value of the UnitRadius attribute is used only to control -* the simplification of Mappings and has no effect on the value of -* the coordinates transformed by a SphMap. The lengths of the -* input 3-dimensional Cartesian vectors supplied are always -* ignored, even if UnitRadius is non-zero. -* - The value of this attribute may changed only if the SphMap -* has no more than one reference. That is, an error is reported if the -* SphMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* SphMap -* All SphMaps have this attribute. -*att-- -*/ -astMAKE_CLEAR1(SphMap,UnitRadius,unitradius,-1) -astMAKE_GET(SphMap,UnitRadius,int,0,(this->unitradius == -1 ? 0 : this->unitradius)) -astMAKE_SET1(SphMap,UnitRadius,int,unitradius,( value ? 1 : 0 )) -astMAKE_TEST(SphMap,UnitRadius,( this->unitradius != -1 )) - -/* PolarLong */ -/* --------- */ -/* -*att++ -* Name: -* PolarLong - -* Purpose: -* The longitude value to assign to either pole - -* Type: -* Public attribute. - -* Synopsis: -* Double precision. - -* Description: -* This attribute holds the longitude value, in radians, to be -* returned when a Cartesian position corresponding to either the north -* or south pole is transformed into spherical coordinates. The -* default value is zero. -* -* Note, the value of this attribute may changed only if the SphMap -* has no more than one reference. That is, an error is reported if the -* SphMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* SphMap -* All SphMaps have this attribute. -*att-- -*/ -astMAKE_CLEAR1(SphMap,PolarLong,polarlong,AST__BAD) -astMAKE_GET(SphMap,PolarLong,double,0.0,(this->polarlong == AST__BAD ? 0.0 : this->polarlong)) -astMAKE_SET1(SphMap,PolarLong,double,polarlong,value) -astMAKE_TEST(SphMap,PolarLong,( this->polarlong != AST__BAD )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for SphMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status, int *status, int *status ) - -* Description: -* This function implements the copy constructor for SphMap objects. - -* Parameters: -* objin -* Pointer to the SphMap to be copied. -* objout -* Pointer to the SphMap being constructed. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. - -*/ - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for SphMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status, int *status ) - -* Description: -* This function implements the destructor for SphMap objects. - -* Parameters: -* obj -* Pointer to the SphMap to be deleted. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This destructor does nothing and exists only to maintain a -* one-to-one correspondence between destructors and copy -* constructors. -*/ - - -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SphMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status, int *status, int *status, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the SphMap class to an output Channel. - -* Parameters: -* this -* Pointer to the SphMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSphMap *this; /* Pointer to the SphMap structure */ - double dval; /* Double precision attribute value */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SphMap structure. */ - this = (AstSphMap *) this_object; - -/* Write out values representing the instance variables for the - SphMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* UnitRadius. */ -/* ------- */ - set = TestUnitRadius( this, status ); - ival = set ? GetUnitRadius( this, status ) : astGetUnitRadius( this ); - if( ival ) { - astWriteInt( channel, "UntRd", set, 0, ival, "All input vectors have unit length" ); - } else { - astWriteInt( channel, "UntRd", set, 0, ival, "Input vectors do not all have unit length" ); - } - -/* PolarLong. */ -/* ---------- */ - set = TestPolarLong( this, status ); - dval = set ? GetPolarLong( this, status ) : astGetPolarLong( this ); - astWriteDouble( channel, "PlrLg", set, 1, dval, "Polar longitude (rad.s)" ); - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASphMap and astCheckSphMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SphMap,Mapping) -astMAKE_CHECK(SphMap) - -AstSphMap *astSphMap_( const char *options, int *status, ...) { -/* -*++ -* Name: -c astSphMap -f AST_SPHMAP - -* Purpose: -* Create a SphMap. - -* Type: -* Public function. - -* Synopsis: -c #include "sphmap.h" -c AstSphMap *astSphMap( const char *options, ... ) -f RESULT = AST_SPHMAP( OPTIONS, STATUS ) - -* Class Membership: -* SphMap constructor. - -* Description: -* This function creates a new SphMap and optionally initialises -* its attributes. -* -* A SphMap is a Mapping which transforms points from a -* 3-dimensional Cartesian coordinate system into a 2-dimensional -* spherical coordinate system (longitude and latitude on a unit -* sphere centred at the origin). It works by regarding the input -* coordinates as position vectors and finding their intersection -* with the sphere surface. The inverse transformation always -* produces points which are a unit distance from the origin -* (i.e. unit vectors). - -* Parameters: -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new SphMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new SphMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSphMap() -f AST_SPHMAP = INTEGER -* A pointer to the new SphMap. - -* Notes: -* - The spherical coordinates are longitude (positive -* anti-clockwise looking from the positive latitude pole) and -* latitude. The Cartesian coordinates are right-handed, with the x -* axis (axis 1) at zero longitude and latitude, and the z axis -* (axis 3) at the positive latitude pole. -* - At either pole, the longitude is set to the value of the -* PolarLong attribute. -* - If the Cartesian coordinates are all zero, then the longitude -* and latitude are set to the value AST__BAD. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSphMap *new; /* Pointer to new SphMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SphMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSphMap( NULL, sizeof( AstSphMap ), !class_init, &class_vtab, - "SphMap" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SphMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new SphMap. */ - return new; -} - -AstSphMap *astSphMapId_( const char *options, ...) { -/* -* Name: -* astSphMapId_ - -* Purpose: -* Create a SphMap. - -* Type: -* Private function. - -* Synopsis: -* #include "sphmap.h" -* AstSphMap *astSphMapId_( const char *options, ... ) - -* Class Membership: -* SphMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astSphMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astSphMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astSphMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astSphMap_. - -* Returned Value: -* The ID value associated with the new SphMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSphMap *new; /* Pointer to new SphMap */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SphMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSphMap( NULL, sizeof( AstSphMap ), !class_init, &class_vtab, - "SphMap" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new SphMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new SphMap. */ - return astMakeId( new ); -} - -AstSphMap *astInitSphMap_( void *mem, size_t size, int init, - AstSphMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSphMap - -* Purpose: -* Initialise a SphMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "sphmap.h" -* AstSphMap *astInitSphMap( void *mem, size_t size, int init, -* AstSphMapVtab *vtab, const char *name ) - -* Class Membership: -* SphMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new SphMap object. It allocates memory (if necessary) to accommodate -* the SphMap plus any additional data associated with the derived class. -* It then initialises a SphMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a SphMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SphMap is to be initialised. -* This must be of sufficient size to accommodate the SphMap data -* (sizeof(SphMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the SphMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the SphMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the SphMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new SphMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). - -* Returned Value: -* A pointer to the new SphMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstSphMap *new; /* Pointer to new SphMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSphMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a Mapping structure (the parent class) as the first component - within the SphMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstSphMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - 3, 2, 1, 1 ); - - if ( astOK ) { - -/* Initialise the SphMap data. */ -/* --------------------------- */ -/* Are all input vectors of unit length? Store a value of -1 to indicate that - no value has yet been set. This will cause a default value of 0 (no, i.e. - input vectors are not all of unit length) to be used. */ - new->unitradius = -1; - new->polarlong = AST__BAD; - - } - -/* Return a pointer to the new SphMap. */ - return new; -} - -AstSphMap *astLoadSphMap_( void *mem, size_t size, - AstSphMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSphMap - -* Purpose: -* Load a SphMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "sphmap.h" -* AstSphMap *astLoadSphMap( void *mem, size_t size, -* AstSphMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* SphMap loader. - -* Description: -* This function is provided to load a new SphMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* SphMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a SphMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the SphMap is to be -* loaded. This must be of sufficient size to accommodate the -* SphMap data (sizeof(SphMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SphMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SphMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstSphMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SphMap. If this is NULL, a pointer -* to the (static) virtual function table for the SphMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "SphMap" is used instead. - -* Returned Value: -* A pointer to the new SphMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSphMap *new; /* Pointer to the new SphMap */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SphMap. In this case the - SphMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSphMap ); - vtab = &class_vtab; - name = "SphMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSphMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built SphMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "SphMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* UnitRadius. */ -/* ----------- */ - new->unitradius = astReadInt( channel, "untrd", -1 ); - if ( TestUnitRadius( new, status ) ) SetUnitRadius( new, new->unitradius, status ); - -/* PolarLong. */ -/* ---------- */ - new->polarlong = astReadDouble( channel, "plrlg", AST__BAD ); - if ( TestPolarLong( new, status ) ) SetPolarLong( new, new->polarlong, status ); - - } - -/* If an error occurred, clean up by deleting the new SphMap. */ - if ( !astOK ) new = astDelete( new ); - -/* Return the new SphMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - diff --git a/ast/sphmap.h b/ast/sphmap.h deleted file mode 100644 index 905703b..0000000 --- a/ast/sphmap.h +++ /dev/null @@ -1,374 +0,0 @@ -#if !defined( SPHMAP_INCLUDED ) /* Include this file only once */ -#define SPHMAP_INCLUDED -/* -*+ -* Name: -* sphmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the SphMap class. - -* Invocation: -* #include "sphmap.h" - -* Description: -* This include file defines the interface to the SphMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The SphMap class implements Mappings which maps positions from -* 3-dimensional Cartesian coordinates into 2-dimensional spherical -* coordinates (i.e. longitude and latitude on a unit sphere). The -* inverse Mapping always produces vectors of unit length. -* -* The spherical coordinates are longitude (positive anti-clockwise -* looking from the positive latitude pole) and latitude. The -* Cartesian coordinates are right-handed, with the x-axis (axis 1) -* at zero longitude and latitude, and the z-axis (axis 3) at the -* positive latitude pole. -* -* At either pole, the longitude is set to the value of the PolarLong -* attribute. If the Cartesian coordinates are all zero, then the -* longitude and latitude values are set to AST__BAD. - -* Inheritance: -* The SphMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* PolarLong (double) -* This attribute holds the longitude value, in radians, to be -* returned when a Cartesian position corresponding to either the north -* or south pole is transformed into spherical coordinates. The -* default value is zero. -* UnitRadius (integer) -* This is a boolean attribute which indicates whether the -* 3-dimensional vectors which are supplied as input to a SphMap -* are known to always have unit length, so that they lie on a -* unit sphere centred on the origin. -* -* If this condition is true (indicated by setting UnitRadius -* non-zero), it implies that a CmpMap which is composed of a -* SphMap applied in the forward direction followed by a similar -* SphMap applied in the inverse direction may be simplified -* (e.g. by astSimplify) to become a UnitMap. This is because -* the input and output vectors will both have unit length and -* will therefore have the same coordinate values. -* -* If UnitRadius is zero (the default), then although the output -* vector produced by the CmpMap (above) will still have unit -* length, the input vector may not have. This will, in general, -* change the coordinate values, so it prevents the pair of -* SphMaps being simplified. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astClearAttrib -* Clear an attribute value for a SphMap. -* astGetAttrib -* Get an attribute value for a SphMap. -* astMapMerge -* Simplify a sequence of Mappings containing a SphMap. -* astSetAttrib -* Set an attribute value for a SphMap. -* astTestAttrib -* Test if an attribute value has been set for a SphMap. -* astTransform -* Apply a SphMap to transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* astClearUnitRadius -* Clear the UnitRadius attribute value for a SphMap. -* astGetUnitRadius -* Get the UnitRadius attribute value for a SphMap. -* astSetUnitRadius -* Set the UnitRadius attribute value for a SphMap. -* astTestUnitRadius -* Test if a UnitRadius attribute value has been set for a SphMap. -* astClearPolarLong -* Clear the PolarLong attribute value for a SphMap. -* astGetPolarLong -* Get the PolarLong attribute value for a SphMap. -* astSetPolarLong -* Set the PolarLong attribute value for a SphMap. -* astTestPolarLong -* Test if a PolarLong attribute value has been set for a SphMap. - -* Other Class Functions: -* Public: -* astIsASphMap -* Test class membership. -* astSphMap -* Create a SphMap. -* -* Protected: -* astCheckSphMap -* Validate class membership. -* astInitSphMap -* Initialise a SphMap. -* astInitSphMapVtab -* Initialise the virtual function table for the SphMap class. -* astLoadSphMap -* Load a SphMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstSphMap -* SphMap object type. -* -* Protected: -* AstSphMapVtab -* SphMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 25-OCT-1996 (DSB): -* Original version. -* 24-MAR-1998 (RFWS): -* Override the astMapMerge method. -* 4-SEP-1998 (DSB): -* Added UnitRadius attribute. -* 8-JAN-2003 (DSB): -* Added protected astInitSphMapVtab method. -* 11-JUN-2003 (DSB): -* Added PolarLong attribute. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* SphMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstSphMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double polarlong; /* Longitude to assign to either pole */ - int unitradius; /* Are input vectors always of unit length? */ -} AstSphMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstSphMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - int (* GetUnitRadius)( AstSphMap *, int * ); - int (* TestUnitRadius)( AstSphMap *, int * ); - void (* ClearUnitRadius)( AstSphMap *, int * ); - void (* SetUnitRadius)( AstSphMap *, int, int * ); - - double (* GetPolarLong)( AstSphMap *, int * ); - int (* TestPolarLong)( AstSphMap *, int * ); - void (* ClearPolarLong)( AstSphMap *, int * ); - void (* SetPolarLong)( AstSphMap *, double, int * ); -} AstSphMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstSphMapGlobals { - AstSphMapVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 51 ]; -} AstSphMapGlobals; -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(SphMap) /* Check class membership */ -astPROTO_ISA(SphMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstSphMap *astSphMap_( const char *, int *, ...); -#else -AstSphMap *astSphMapId_( const char *, ...)__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstSphMap *astInitSphMap_( void *, size_t, int, AstSphMapVtab *, - const char *, int * ); - -/* Vtab initialiser. */ -void astInitSphMapVtab_( AstSphMapVtab *, const char *, int * ); - -/* Loader. */ -AstSphMap *astLoadSphMap_( void *, size_t, AstSphMapVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitSphMapGlobals_( AstSphMapGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -int astGetUnitRadius_( AstSphMap *, int * ); -int astTestUnitRadius_( AstSphMap *, int * ); -void astClearUnitRadius_( AstSphMap *, int * ); -void astSetUnitRadius_( AstSphMap *, int, int * ); - -double astGetPolarLong_( AstSphMap *, int * ); -int astTestPolarLong_( AstSphMap *, int * ); -void astClearPolarLong_( AstSphMap *, int * ); -void astSetPolarLong_( AstSphMap *, double, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckSphMap(this) astINVOKE_CHECK(SphMap,this,0) -#define astVerifySphMap(this) astINVOKE_CHECK(SphMap,this,1) - -/* Test class membership. */ -#define astIsASphMap(this) astINVOKE_ISA(SphMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astSphMap astINVOKE(F,astSphMap_) -#else -#define astSphMap astINVOKE(F,astSphMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define \ -astInitSphMap(mem,size,init,vtab,name) \ -astINVOKE(O,astInitSphMap_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitSphMapVtab(vtab,name) astINVOKE(V,astInitSphMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadSphMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadSphMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckSphMap to validate SphMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astClearUnitRadius(this) astINVOKE(V,astClearUnitRadius_(astCheckSphMap(this),STATUS_PTR)) -#define astGetUnitRadius(this) astINVOKE(V,astGetUnitRadius_(astCheckSphMap(this),STATUS_PTR)) -#define astSetUnitRadius(this,value) astINVOKE(V,astSetUnitRadius_(astCheckSphMap(this),value,STATUS_PTR)) -#define astTestUnitRadius(this) astINVOKE(V,astTestUnitRadius_(astCheckSphMap(this),STATUS_PTR)) - -#define astClearPolarLong(this) astINVOKE(V,astClearPolarLong_(astCheckSphMap(this),STATUS_PTR)) -#define astGetPolarLong(this) astINVOKE(V,astGetPolarLong_(astCheckSphMap(this),STATUS_PTR)) -#define astSetPolarLong(this,value) astINVOKE(V,astSetPolarLong_(astCheckSphMap(this),value,STATUS_PTR)) -#define astTestPolarLong(this) astINVOKE(V,astTestPolarLong_(astCheckSphMap(this),STATUS_PTR)) -#endif - -#endif - - - - - diff --git a/ast/stc.c b/ast/stc.c deleted file mode 100644 index 08e4392..0000000 --- a/ast/stc.c +++ /dev/null @@ -1,3703 +0,0 @@ -/* -*class++ -* Name: -* Stc - -* Purpose: -* Represents an instance of the IVOA STC class. - -* Constructor Function: -c astStc -f AST_STC - -* Description: -* The Stc class is an implementation of the IVOA STC class which forms -* part of the IVOA Space-Time Coordinate Metadata system. See: -* -* http://hea-www.harvard.edu/~arots/nvometa/STC.html -* -* The Stc class does not have a constructor function of its own, as it -* is simply a container class for a family of specialised sub-classes -* including StcCatalogEntryLocation, StcResourceProfile, StcSearchLocation -* and StcObsDataLocation. - -* Inheritance: -* The Stc class inherits from the Region class. - -* Attributes: -* In addition to those attributes common to all Regions, every -* Stc also has the following attributes: -* -* - RegionClass: The class name of the encapsulated Region. - -* Functions: -c In addition to those functions applicable to all Regions, the -c following functions may also be applied to all Stc's: -f In addition to those routines applicable to all Regions, the -f following routines may also be applied to all Stc's: -* -c - astGetStcRegion: Get a pointer to the encapsulated Region -f - AST_GETSTCREGION: Get a pointer to the encapsulated Region -c - astGetStcCoord: Get information about an AstroCoords element -f - AST_GETSTCCOORD: Get information about an AstroCoords element -c - astGetStcNCoord: Returns the number of AstroCoords elements in an Stc -f - AST_GETSTCNCOORD: Returns the number of AstroCoords elements in an Stc - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2008 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 23-NOV-2004 (DSB): -* Original version. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 13-MAR-2009 (DSB): -* Over-ride astRegBasePick. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Stc - -/* The number of components in an AstroCoords element which are described - using a Region within a KeyMap. */ -#define NREG 5 - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "unitmap.h" /* Unit Mappings */ -#include "region.h" /* Regions (parent class) */ -#include "channel.h" /* I/O channels */ -#include "stc.h" /* Interface definition for this class */ -#include "keymap.h" /* Lists of value/key pairs */ -#include "pointlist.h" /* Individual points in a Frame */ -#include "ellipse.h" /* Ellipses within a Frame */ -#include "interval.h" /* Axis intervals within a Frame */ -#include "prism.h" /* Extrusions into higher dimensions */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstMapping *(* parent_simplify)( AstMapping *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *(* parent_getdefunc)( AstRegion *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_equal)( AstObject *, AstObject *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); -static int (* parent_getusedefs)( AstObject *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_setregfs)( AstRegion *, AstFrame *, int * ); -static void (*parent_regclearattrib)( AstRegion *, const char *, char **, int * ); -static void (*parent_regsetattrib)( AstRegion *, const char *, char **, int * ); - -static void (* parent_clearnegated)( AstRegion *, int * ); -static void (* parent_clearclosed)( AstRegion *, int * ); -static void (* parent_clearfillfactor)( AstRegion *, int * ); -static void (* parent_clearmeshsize)( AstRegion *, int * ); - -static void (* parent_setclosed)( AstRegion *, int, int * ); -static void (* parent_setfillfactor)( AstRegion *, double, int * ); -static void (* parent_setmeshsize)( AstRegion *, int, int * ); -static void (* parent_setnegated)( AstRegion *, int, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* The keys associated with each component of an AstroCoords element - within KeyMap */ -static const char *regkey[ NREG ] = { AST__STCERROR, - AST__STCRES, - AST__STCSIZE, - AST__STCPIXSZ, - AST__STCVALUE }; - -/* The comments associated with each component of an AstroCoords element - within KeyMap */ -static const char *regcom[ NREG ] = { "AstroCoords error region", - "AstroCoords resolution region", - "AstroCoords size region", - "AstroCoords pixel size region", - "AstroCoords value region" }; - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Stc) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Stc,Class_Init) -#define class_vtab astGLOBAL(Stc,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstStcVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstKeyMap *GetStcCoord( AstStc *, int, int * ); -static AstKeyMap *MakeAstroCoordsKeyMap( AstRegion *, AstKeyMap *, const char *, int * ); -static AstMapping *Simplify( AstMapping *, int * ); -static AstPointSet *RegBaseMesh( AstRegion *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstRegion *GetDefUnc( AstRegion *, int * ); -static AstRegion *GetStcRegion( AstStc *, int * ); -static AstRegion *RegBasePick( AstRegion *this, int, const int *, int * ); -static const char *GetRegionClass( AstStc *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetBounded( AstRegion *, int * ); -static int GetObjSize( AstObject *, int * ); -static int GetStcNCoord( AstStc *, int * ); -static int GetUseDefs( AstObject *, int * ); -static int Overlap( AstRegion *, AstRegion *, int * ); -static int OverlapX( AstRegion *, AstRegion *, int * ); -static int RegPins( AstRegion *, AstPointSet *, AstRegion *, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void GetRegion( AstStc *, AstRegion **, int *, int * ); -static void RegBaseBox( AstRegion *, double *, double *, int * ); -static void RegClearAttrib( AstRegion *, const char *, char **, int * ); -static void RegSetAttrib( AstRegion *, const char *, char **, int * ); -static void SetRegFS( AstRegion *, AstFrame *, int * ); - -static void ClearAttrib( AstObject *, const char *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); - -static void ClearClosed( AstRegion *, int * ); -static int GetClosed( AstRegion *, int * ); -static void SetClosed( AstRegion *, int, int * ); -static int TestClosed( AstRegion *, int * ); - -static void ClearMeshSize( AstRegion *, int * ); -static int GetMeshSize( AstRegion *, int * ); -static void SetMeshSize( AstRegion *, int, int * ); -static int TestMeshSize( AstRegion *, int * ); - -static void ClearFillFactor( AstRegion *, int * ); -static double GetFillFactor( AstRegion *, int * ); -static void SetFillFactor( AstRegion *, double, int * ); -static int TestFillFactor( AstRegion *, int * ); - -static void ClearNegated( AstRegion *, int * ); -static int GetNegated( AstRegion *, int * ); -static void SetNegated( AstRegion *, int, int * ); -static int TestNegated( AstRegion *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Stc. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Stc member function (over-rides the astClearAttrib protected -* method inherited from the Region class). - -* Description: -* This function clears the value of a specified attribute for a -* Stc, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Stc. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstStc *this; /* Pointer to the Stc structure */ - int len; /* Length of attrib string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Stc structure. */ - this = (AstStc *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* (none as yet) */ -/* ------------- */ - -/* Read-only attributes. */ -/* --------------------- */ -/* Test if the attribute name matches any of the read-only attributes - of this class. If it does, then report an error. */ - if ( !strcmp( attrib, "regionclass" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two Objects are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* int Equal( AstObject *this_object, AstObject *that_object, int *status ) - -* Class Membership: -* Stc member function (over-rides the astEqual protected -* method inherited from the Region class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two Stcs are equivalent. - -* Parameters: -* this -* Pointer to the first Stc. -* that -* Pointer to the second Stc. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the Stcs are equivalent, zero otherwise. - -* Notes: -* - The Stcs are equivalent if their encapsulated Region are -* equivalent, and if they have the same boolean operation, negation -* and closed flags. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstStc *that; - AstStc *this; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the Equal method inherited from the parent Region class. This checks - that the Objects are both of the same class, and have the same Negated - and Closed flags (amongst other things). */ - if( (*parent_equal)( this_object, that_object, status ) ) { - -/* Obtain pointers to the two Stc structures. */ - this = (AstStc *) this_object; - that = (AstStc *) that_object; - -/* Test their encapsulated Region for equality. */ - result = astEqual( this->region, that->region ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -/* -* Name: -* MAKE_SET - -* Purpose: -* Define a function to set an attribute value for a Stc. - -* Type: -* Private macro. - -* Synopsis: -* #include "stc.h" -* MAKE_SET(attribute,lattribute,type) - -* Class Membership: -* Defined by the Stc class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Set( AstRegion *this, value ) -* -* that sets the value of a specified Region attribute in the parent -* Region structure and also in the encapsulated Region. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* lattribute -* Name of the attribute, all in lower case. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_SET(attribute,lattribute,type) \ -static void Set##attribute( AstRegion *this_region, type value, int *status ) { \ -\ -/* Local Variables: */ \ - AstStc *this; /* Pointer to the Stc structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Use the parent method to set the value in the parent Region structure. */ \ - (*parent_set##lattribute)( this_region, value, status ); \ -\ -/* Also set the value in the encapsulated Region. */ \ - this = (AstStc *) this_region; \ - astSet##attribute( this->region, value ); \ -} - -/* Use the above macro to create accessors for the MeshSize, Closed and - FillFactor attributes. */ -MAKE_SET(FillFactor,fillfactor,double) -MAKE_SET(MeshSize,meshsize,int) -MAKE_SET(Closed,closed,int) -MAKE_SET(Negated,negated,int) - -/* Undefine the macro. */ -#undef MAKE_SET - -/* -* Name: -* MAKE_CLEAR - -* Purpose: -* Define a function to clear an attribute value for a Stc. - -* Type: -* Private macro. - -* Synopsis: -* #include "stc.h" -* MAKE_CLEAR(attribute,lattribute) - -* Class Membership: -* Defined by the Stc class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static void Clear( AstRegion *this ) -* -* that sets the value of a specified Region attribute in the parent -* Region structure and also in the encapsulated Region. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* lattribute -* Name of the attribute, all in lower case. -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attribute,lattribute) \ -static void Clear##attribute( AstRegion *this_region, int *status ) { \ -\ -/* Local Variables: */ \ - AstStc *this; /* Pointer to the Stc structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Use the parent method to clear the value in the parent Region structure. */ \ - (*parent_clear##lattribute)( this_region, status ); \ -\ -/* Also clear the value in the encapsulated Region. */ \ - this = (AstStc *) this_region; \ - astClear##attribute( this->region ); \ -} - -/* Use the above macro to create accessors for the MeshSize, Closed and - FillFactor attributes. */ -MAKE_CLEAR(FillFactor,fillfactor) -MAKE_CLEAR(MeshSize,meshsize) -MAKE_CLEAR(Closed,closed) -MAKE_CLEAR(Negated,negated) - -/* Undefine the macro. */ -#undef MAKE_CLEAR - - -/* -* Name: -* MAKE_GET - -* Purpose: -* Define a function to get an attribute value for a Stc. - -* Type: -* Private macro. - -* Synopsis: -* #include "stc.h" -* MAKE_GET(attribute,type,bad) - -* Class Membership: -* Defined by the Stc class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static Get( AstRegion *this ) -* -* that gets the value of a specified Region attribute from the encapsulated -* Region. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -* bad -* Value to return in caseof error. -*/ - -/* Define the macro. */ -#define MAKE_GET(attribute,type,bad) \ -static type Get##attribute( AstRegion *this_region, int *status ) { \ -\ -/* Local Variables: */ \ - AstStc *this; /* Pointer to the Stc structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad); \ -\ -/* Get the value from the encapsulated Region. */ \ - this = (AstStc *) this_region; \ - return astGet##attribute( this->region ); \ -} - -/* Use the above macro to create accessors for the MeshSize, Closed and - FillFactor attributes. */ -MAKE_GET(FillFactor,double,AST__BAD) -MAKE_GET(MeshSize,int,100) -MAKE_GET(Closed,int,1) -MAKE_GET(Negated,int,0) - -/* Undefine the macro. */ -#undef MAKE_GET - -/* -* Name: -* MAKE_TEST - -* Purpose: -* Define a function to test an attribute value for a Stc. - -* Type: -* Private macro. - -* Synopsis: -* #include "stc.h" -* MAKE_TEST(attribute) - -* Class Membership: -* Defined by the Stc class. - -* Description: -* This macro expands to an implementation of a private member function -* of the form: -* -* static int Test( AstRegion *this ) -* -* that test the value of a specified Region attribute from the encapsulated -* Region. - -* Parameters: -* attribute -* Name of the attribute, as it appears in the function name. -* type -* The C type of the attribute. -*/ - -/* Define the macro. */ -#define MAKE_TEST(attribute) \ -static int Test##attribute( AstRegion *this_region, int *status ) { \ -\ -/* Local Variables: */ \ - AstStc *this; /* Pointer to the Stc structure */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Test the value from the encapsulated Region. */ \ - this = (AstStc *) this_region; \ - return astTest##attribute( this->region ); \ -} - -/* Use the above macro to create accessors for the MeshSize, Closed and - FillFactor attributes. */ -MAKE_TEST(FillFactor) -MAKE_TEST(MeshSize) -MAKE_TEST(Closed) -MAKE_TEST(Negated) - -/* Undefine the macro. */ -#undef MAKE_TEST - - - - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* Stc member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied Stc, -* in bytes. - -* Parameters: -* this -* Pointer to the Stc. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstStc *this; /* Pointer to Stc structure */ - int result; /* Result value to return */ - int i; /* AstroCoords index */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the Stc structure. */ - this = (AstStc *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astGetObjSize( this->region ); - - if( this->coord ) { - for( i = 0; i < this->ncoord; i++ ) { - result += astGetObjSize( this->coord[ i ] ); - } - result += astTSizeOf( this->coord ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Stc. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Stc member function (over-rides the protected astGetAttrib -* method inherited from the Region class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Stc, formatted as a character string. - -* Parameters: -* this -* Pointer to the Stc. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Stc, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Stc. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstStc *this; /* Pointer to the Stc structure */ - const char *result; /* Pointer value to return */ - int len; /* Length of attrib string */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Stc structure. */ - this = (AstStc *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* RegionClass. */ -/* ------------ */ - if ( !strcmp( attrib, "regionclass" ) ) { - result = astGetClass( this->region ); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static int GetBounded( AstRegion *this_region, int *status ) { -/* -* Name: -* GetBounded - -* Purpose: -* Is the Region bounded? - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* int GetBounded( AstRegion *this, int *status ) - -* Class Membership: -* Stc method (over-rides the astGetBounded method inherited from -* the Region class). - -* Description: -* This function returns a flag indicating if the Region is bounded. -* The implementation provided by the base Region class is suitable -* for Region sub-classes representing the inside of a single closed -* curve (e.g. Circle, Ellipse, Box, etc). Other sub-classes (such as -* Stc, PointList, etc ) may need to provide their own implementations. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Region is bounded. Zero otherwise. - -*/ - -/* Local Variables: */ - AstStc *this; /* Pointer to Stc structure */ - AstRegion *reg; /* Pointer to the encapsulated Region */ - int neg; /* Negated flag to use */ - int neg_old; /* Original Negated flag */ - int result; /* Returned result */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Stc structure. */ - this = (AstStc *) this_region; - -/* Get the encapsulated Region, and the Negated value which should be used - with it. The returned values take account of whether the supplied Stc has - itself been Negated or not. The returned Region represent a region within - the base Frame of the FrameSet encapsulated by the parent Region - structure. */ - GetRegion( this, ®, &neg, status ); - -/* Temporarily set the Negated attribute to the required value.*/ - neg_old = astGetNegated( reg ); - astSetNegated( reg, neg ); - -/* See if the encapsulated Region is bounded. */ - result = astGetBounded( reg ); - -/* Re-instate the original value for the Negated attribute of the - encapsulated Region. */ - if( reg ) astSetNegated( reg, neg_old ); - -/* Free resources. */ - reg = astAnnul( reg ); - -/* Return zero if an error occurred. */ - if( !astOK ) result = 0; - -/* Return the required pointer. */ - return result; -} - -static AstRegion *GetDefUnc( AstRegion *this_region, int *status ) { -/* -* Name: -* GetDefUnc - -* Purpose: -* Obtain a pointer to the default uncertainty Region for a given Region. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* AstRegion *GetDefUnc( AstRegion *this ) - -* Class Membership: -* Stc method (over-rides the astGetDefUnc method inherited from -* the Region class). - -* This function returns a pointer to a Region which represents the -* default uncertainty associated with a position on the boundary of the -* given Region. The returned Region refers to the base Frame within the -* FrameSet encapsulated by the supplied Region. - -* Parameters: -* this -* Pointer to the Region. - -* Returned Value: -* A pointer to the Region. This should be annulled (using astAnnul) -* when no longer needed. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstStc *this; /* Pointer to the Stc structure */ - AstRegion *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Stc structure. */ - this = (AstStc *) this_region; - -/* If the encapsulated region has non-default uncertainty, use it as - the default uncertainty for the Cmpregion. Note, the current Frame of - an uncertainty Region is assumed to be the same as the base Frame in the - Stc. */ - if( astTestUnc( this->region ) ) { - result = astGetUncFrm( this->region, AST__CURRENT ); - -/* Otherwise, use the parent method to determine the default uncertainty. */ - } else { - result = (* parent_getdefunc)( this_region, status ); - } - -/* Return NULL if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the required pointer. */ - return result; -} - -static void GetRegion( AstStc *this, AstRegion **reg, int *neg, int *status ) { -/* -* -* Name: -* GetRegion - -* Purpose: -* Get the encapsulated Region of a Stc. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* void GetRegion( AstStc *this, AstRegion **reg, int *neg, int *status ) - -* Class Membership: -* Stc member function - -* Description: -* This function returns a pointer to a Region which is equivalent to -* the supplied Stc. If the Stc has been negated, then the returned -* "negated" flag will be set such that it represents the negated Stc. -* -* The current Frames in returned encapsulated Region will be equivalent -* to the base Frame in the FrameSet encapsulated by the parent Region -* structure. - -* Parameters: -* this -* Pointer to the Stc. -* reg -* Address of a location to receive a pointer to the encapsulated -* Region. The current Frame in this region will be equivalent to -* the base Frame in the FrameSet -* neg -* The value of the Negated attribute to be used with reg. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Any changes made to the encapsulated Region using the returned -* pointer will be reflected in the supplied Stc. - -*/ - -/* Initialise */ - if( reg ) *reg = NULL; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Return the component Region pointers. */ - if( reg ) *reg = astClone( this->region ); - -/* Initialise the other returned items. Note, the Stc initialiser stored a - deep copy of the supplied encapsulated Region, and so we do not - need to worry about attributes of the Region having been changed - after the creation of the Stc. This is different to the CmpMap - class which merely clones its supplied component pointers and so has - to save copies of the original Invert settings within the CmpMap - structure. */ - if( neg ) *neg = astGetNegated( this->region ); - -/* If the Stc has been inverted, we modify the boolean operator and - negation flags so that they reflect the inverted Stc. */ - if( astGetNegated( this ) && neg ) *neg = *neg ? 0 : 1; -} - -static const char *GetRegionClass( AstStc *this, int *status ){ -/* -*+ -* Name: -* astGetRegionClass - -* Purpose: -* Get the value of a RegionClass attribute for a Stc. - -* Type: -* Protected function. - -* Synopsis: -* #include "stc.h" -* const char *astGetRegionClass( AstStc *this ) - -* Class Membership: -* Stc virtual function - -* Description: -* This function returns a pointer to the value of the RegionClass -* attribute for a Stc. - -* Parameters: -* this -* Pointer to the Stc. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Stc, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Stc. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain and return the class of the encapsulated Region. */ - return astGetClass( ((AstStc *) this)->region ); -} - - -static AstKeyMap *GetStcCoord( AstStc *this, int icoord, int *status ){ -/* -*++ -* Name: -c astGetStcCoord -f AST_GETSTCCOORD - -* Purpose: -* Return information about an AstroCoords element stored in an Stc. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "specframe.h" -c AstKeyMap *astGetStcCoord( AstStc *this, int icoord ) -f RESULT = AST_GETSTCCOORD( THIS, ICOORD, STATUS ) - -* Class Membership: -* Stc method. - -* Description: -* When any sub-class of Stc is created, the constructor function -* allows one or more AstroCoords elements to be stored within the Stc. -* This function allows any one of these AstroCoords elements to be -* retrieved. The format of the returned information is the same as -* that used to pass the original information to the Stc constructor. -* That is, the information is returned in a KeyMap structure -* containing elements with one or more of the keys given by symbolic -* constants AST__STCNAME, AST__STCVALUE, AST__STCERROR, AST__STCRES, -* AST__STCSIZE and AST__STCPIXSZ. -* -* If the coordinate system represented by the Stc has been changed -* since it was created (for instance, by changing its System -* attribute), then the sizes and positions in the returned KeyMap -* will reflect the change in coordinate system. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Stc. -c icoord -f ICOORD = INTEGER (Given) -* The index of the AstroCoords element required. The first has index -* one. The number of AstroCoords elements in the Stc can be found using -c function astGetStcNcoord. -f function AST_GETSTCNCOORD. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetStcCoord() -f AST_GETSTCCOORD = INTEGER -* A pointer to a new KeyMap containing the required information. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - AstFrame *frm; - AstKeyMap *result; - AstMapping *map; - AstMapping *smap; - AstObject *obj; - AstRegion *reg; - AstRegion *rereg; - AstRegion *srereg; - int ikey; - int nc; - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate the supplied index. */ - nc = astGetStcNCoord( this ); - if( icoord < 1 || icoord > nc ) { - astError( AST__STCIND, "astGetStcCoord(%s): Supplied AstroCoords " - "index (%d) is invalid.", status, astGetClass( this ), icoord ); - - if( icoord < 1 ) { - astError( AST__STCIND, "The index of the first AstroCoord " - "element is one, not zero." , status); - } else if( nc == 0 ) { - astError( AST__STCIND, "There are no AstroCoords elements in " - "the supplied %s.", status, astGetClass( this ) ); - } else if( nc == 1 ) { - astError( AST__STCIND, "There is 1 AstroCoords element in " - "the supplied %s.", status, astGetClass( this ) ); - } else { - astError( AST__STCIND, "There are %d AstroCoords elements in " - "the supplied %s.", status, nc, astGetClass( this ) ); - } - -/* If the index is OK, initialise the returned KeyMap to be a copy of the - KeyMap holding information about the required AstroCoords element.*/ - } else { - result = astCopy( this->coord[ icoord - 1 ] ); - -/* The Regions stored within this KeyMap describe regions within the base - Frame of the parent Region structure. If the Mapping from base to current - Frame in the parent Region structure is not a UnitMap, we need to - change these to represent regions within the current Frame of the - parent Region structure. */ - map = astGetMapping( ((AstRegion *)this)->frameset, - AST__BASE, AST__CURRENT ); - smap = astSimplify( map ); - frm = astGetFrame( ((AstRegion *)this)->frameset, AST__CURRENT ); - -/* If the Frame represented by the Region has changed, erase the Names - element since they may no longer be correct. */ - if( !astIsAUnitMap( smap ) ) astMapRemove( result, AST__STCNAME ); - -/* Loop round keys for which a Region may be stored in the KeyMap. */ - for( ikey = 0; ikey < NREG; ikey++ ) { - -/* If the KeyMap contains a Region for this key, get a pointer to it. */ - if( astMapGet0A( result, regkey[ ikey ], &obj ) ){ - reg = (AstRegion *) obj; - -/* Sets its RegionFS attribute so that the encapsulated FrameSet will be - included in any dump of the Region. This is needed since the returned - Region pointer will have no parent Region from which the FrameSet can - be determined. */ - astSetRegionFS( reg, 1 ); - -/* If necessary, remap the Region into the current Frame, and simplify. */ - if( !astIsAUnitMap( smap ) ) { - rereg = astMapRegion( reg, smap, frm ); - srereg = astSimplify( rereg ); - rereg = astAnnul( rereg ); - } else { - srereg = astClone( reg ); - } - -/* Replace the Region in the KeyMap with the remapped Region. */ - astMapPut0A( result, regkey[ ikey ], srereg, NULL ); - -/* Free resources */ - reg = astAnnul( reg ); - srereg = astAnnul( srereg ); - } - } - - frm = astAnnul( frm ); - map = astAnnul( map ); - smap = astAnnul( smap ); - -/* Annul the returned KeyMap if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - } - -/* Return the pointer */ - return result; - -} - -static int GetStcNCoord( AstStc *this, int *status ){ -/* -*++ -* Name: -c astGetStcNCoord -f AST_GETSTCNCOORD - -* Purpose: -* Return the number of AstroCoords elements stored in an Stc. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "stc.h" -c int astGetStcNCoord( AstStc *this ) -f RESULT = AST_GETSTCNCOORD( THIS, STATUS ) - -* Class Membership: -* Stc method. - -* Description: -* This function returns the number of AstroCoords elements stored in -* an Stc. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Stc. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetStcNCoord() -f AST_GETSTCNCOORD = INTEGER -* The number of AstroCoords elements stored in the Stc. - -* Notes: -* - Zero will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Return the required value. */ - return astOK ? this->ncoord : 0; - -} - -static AstRegion *GetStcRegion( AstStc *this, int *status ) { -/* -*++ -* Name: -c astGetStcRegion -f AST_GETSTCREGION - -* Purpose: -* Obtain a copy of the encapsulated Region within a Stc. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "stc.h" -c AstRegion *astGetStcRegion( AstStc *this ) -f RESULT = AST_GETSTCREGION( THIS, STATUS ) - -* Class Membership: -* Region method. - -* Description: -* This function returns a pointer to a deep copy of the Region -* supplied when the Stc was created. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Stc. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetStcRegion() -f AST_GETSTCREGION = INTEGER -* A pointer to a deep copy of the Region encapsulated within the -* supplied Stc. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Return a pointer to a copy of the encapsulated Region. */ - return astCopy( this->region ); -} - -static int GetUseDefs( AstObject *this_object, int *status ) { -/* -* Name: -* GetUseDefs - -* Purpose: -* Get the value of the UseDefs attribute for a Stc. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* int GetUseDefs( AstObject *this_object, int *status ) { - -* Class Membership: -* Stc member function (over-rides the protected astGetUseDefs -* method inherited from the Region class). - -* Description: -* This function returns the value of the UseDefs attribute for a -* Stc, supplying a suitable default. - -* Parameters: -* this -* Pointer to the Stc. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - The USeDefs value. -*/ - -/* Local Variables: */ - AstStc *this; /* Pointer to the Stc structure */ - int result; /* Value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Stc structure. */ - this = (AstStc *) this_object; - -/* If the UseDefs value for the Stc has been set explicitly, use the - Get method inherited from the parent Region class to get its value. */ - if( astTestUseDefs( this ) ) { - result = (*parent_getusedefs)( this_object, status ); - -/* Otherwise, supply a default value equal to the UseDefs value of the - encapsulated Region. */ - } else { - result = astGetUseDefs( this->region ); - } - -/* Return the result. */ - return result; -} - -void astInitStcVtab_( AstStcVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitStcVtab - -* Purpose: -* Initialise a virtual function table for a Stc. - -* Type: -* Protected function. - -* Synopsis: -* #include "stc.h" -* void astInitStcVtab( AstStcVtab *vtab, const char *name ) - -* Class Membership: -* Stc vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Stc class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstRegionVtab *region; /* Pointer to Region component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitRegionVtab( (AstRegionVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAStc) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstRegionVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - - vtab->GetRegionClass = GetRegionClass; - vtab->GetStcRegion = GetStcRegion; - vtab->GetStcCoord = GetStcCoord; - vtab->GetStcNCoord = GetStcNCoord; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - region = (AstRegionVtab *) vtab; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_simplify = mapping->Simplify; - mapping->Simplify = Simplify; - - parent_setregfs = region->SetRegFS; - region->SetRegFS = SetRegFS; - - parent_equal = object->Equal; - object->Equal = Equal; - - parent_clearclosed = region->ClearClosed; - region->ClearClosed = ClearClosed; - - parent_setclosed = region->SetClosed; - region->SetClosed = SetClosed; - - region->TestClosed = TestClosed; - region->GetClosed = GetClosed; - - parent_regsetattrib = region->RegSetAttrib; - region->RegSetAttrib = RegSetAttrib; - - parent_regclearattrib = region->RegClearAttrib; - region->RegClearAttrib = RegClearAttrib; - - parent_clearnegated = region->ClearNegated; - region->ClearNegated = ClearNegated; - - parent_setnegated = region->SetNegated; - region->SetNegated = SetNegated; - - region->TestNegated = TestNegated; - region->GetNegated = GetNegated; - - parent_setmeshsize = region->SetMeshSize; - region->SetMeshSize = SetMeshSize; - - parent_clearmeshsize = region->ClearMeshSize; - region->ClearMeshSize = ClearMeshSize; - - region->TestMeshSize = TestMeshSize; - region->GetMeshSize = GetMeshSize; - - parent_setfillfactor = region->SetFillFactor; - region->SetFillFactor = SetFillFactor; - - parent_clearfillfactor = region->ClearFillFactor; - region->ClearFillFactor = ClearFillFactor; - - region->TestFillFactor = TestFillFactor; - region->GetFillFactor = GetFillFactor; - - parent_getusedefs = object->GetUseDefs; - object->GetUseDefs = GetUseDefs; - - parent_getdefunc = region->GetDefUnc; - region->GetDefUnc = GetDefUnc; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - region->Overlap = Overlap; - region->OverlapX = OverlapX; - region->RegBaseBox = RegBaseBox; - region->RegBaseMesh = RegBaseMesh; - region->RegBasePick = RegBasePick; - region->RegPins = RegPins; - region->GetBounded = GetBounded; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "Stc", "An IVOA Space-Time-Coords object" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static AstKeyMap *MakeAstroCoordsKeyMap( AstRegion *reg, AstKeyMap *coord, - const char *class, int *status ){ -/* -* Name: -* MakeAstroCoordsKeyMap - -* Purpose: -* Create a new KeyMap holding Regions describing a supplied -* AstroCoords element. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* AstKeyMap *MakeAstroCoordsKeyMap( AstRegion *reg, AstKeyMap *coord, -* const char *class, int *status ) - -* Class Membership: -* Stc member function - -* Description: -* This function returns a pointer to a new KeyMap containing elements -* which correspond to the components of an STC AstroCoords element. -* The element with key AST__STCNAME holds a vector of character -* strings containing the names associated with each of the axies. -* The other elements of the returned KeyMap such as AST__STCERROR, -* AST__STCRES, etc, hold pointers to Regions describing the error -* box, resolution, etc, in the Frame of the supplied Region "reg". - -* Parameters: -* reg -* Pointer to the Region in which the AstroCoords is defined. -* coordId -* An ID (not a pointer) to a KeyMap defining a single -* element, having elements with keys given by constants AST__STCNAME, -* AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. Any of these elements may be omitted, but no other -* elements should be included. If supplied, the AST__STCNAME element -* should be a vector of character string pointers holding the "Name" -* item for each axis. Any other supplied elements should be scalar -* elements, each holding a pointer to a Region describing the -* associated item of ancillary information (error, resolution, size, -* pixel size or value). These Regions should refer to the coordinate -* system represented by "region". -* class -* Pointer to a string holding the STC class name. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to the new KeyMap. - -* Notes: -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to current Frame */ - AstFrameSet *fs; /* Pointer to conversion FrameSet */ - AstKeyMap *result; /* Pointer value to return */ - AstMapping *map; /* Pointer to conversion Mapping */ - AstObject *obj; /* Pointer to Object stored in supplied KeyMap */ - AstRegion *areg; /* Pointer to remapped Region */ - AstRegion *sareg; /* Pointer to simplified remapped Region */ - const char *key; /* Current key */ - int j; /* Index of key within KeyMap */ - int naxes; /* Number of axes in region */ - int nkey; /* Number of keys in supplied KeyMap */ - int nv; /* Number of values in KeyMap element */ - int type; /* Data type of entry */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Confirm it is a genuine KeyMap pointer. */ - if( !astIsAKeyMap( coord ) && astOK ) { - astError( AST__STCKEY, "astInitStc(%s): Supplied pointer is for " - "a %s, not a KeyMap.", status, class, astGetClass( coord ) ); - } - -/* Initialise the new KeyMap to be a copy of the supplied KeyMap. */ - result = astCopy( coord ); - -/* Check the supplied KeyMap is usable. */ - naxes = astGetNaxes( reg ); - nkey = astMapSize( result ); - for( j = 0; j < nkey; j++ ) { - key = astMapKey( result, j ); - if( key ) { - nv = astMapLength( result, key ); - type = astMapType( result, key ); - -/* Check no unknown keys are present in the KeyMap. */ - if( strcmp( key, AST__STCNAME ) && - strcmp( key, AST__STCVALUE ) && - strcmp( key, AST__STCERROR ) && - strcmp( key, AST__STCRES ) && - strcmp( key, AST__STCSIZE ) && - strcmp( key, AST__STCPIXSZ ) ) { - astError( AST__STCKEY, "astInitStc(%s): Unknown key " - "\"%s\" supplied in an AstroCoords list.", status, - class, key ); - break; - -/* Check that the "Name" element is a vector of "naxes" strings. */ - } else if( !strcmp( key, AST__STCNAME ) ) { - if( nv != naxes ) { - astError( AST__STCKEY, "astInitStc(%s): %d \"%s\" " - "values supplied in an AstroCoords list, but " - "the Stc has %d axes. ", status, class, nv, key, - naxes ); - break; - - } else if( type != AST__STRINGTYPE ) { - astError( AST__STCKEY, "astInitStc(%s): The \"%s\" " - "values supplied in an AstroCoords list are " - "not character strings. ", status, class, key ); - break; - } - -/* Check that all other elements are scalar. */ - } else if( nv != 1 ) { - astError( AST__STCKEY, "astInitStc(%s): %d \"%s\" " - "values supplied in an AstroCoords list, but " - "only one is allowed. ", status, class, nv, key ); - break; - -/* Check that all other elements are AST Object pointers. */ - } else if( type != AST__OBJECTTYPE ) { - astError( AST__STCKEY, "astInitStc(%s): The \"%s\" " - "value supplied in an AstroCoords list is " - "not an AST Object pointer. ", status, class, key ); - break; - -/* Check that the Object pointers are not NULL. */ - } else { - astMapGet0A( result, key, &obj ); - if( astOK ) { - if( !obj ) { - astError( AST__STCKEY, "astInitStc(%s): The \"%s\" " - "value supplied in an AstroCoords list is " - "a NULL pointer. ", status, class, key ); - break; - -/* Check that the Object pointers are Region pointers. */ - } else if( !astIsARegion( obj ) ){ - astError( AST__STCKEY, "astInitStc(%s): The \"%s\" " - "value supplied in an AstroCoords list is " - "a %s, not a Region. ", status, class, key, - astGetClass(obj) ); - obj = astAnnul( obj ); - break; - -/* Check that the Region pointers can be converted to the coordinate - system represented by the supplied Region. */ - } else { - fs = astConvert( obj, reg, "" ); - if( !fs ) { - obj = astAnnul( obj ); - astError( AST__STCKEY, "astInitStc(%s): The \"%s\" " - "value supplied in an AstroCoords list " - "cannot be converted to the coordinate " - "system of its parent Stc object.", status, class, - key ); - break; - -/* If necessary, map the Region into the same frame as the supplied - Region, and replace the Region in the returned KeyMap with the - remapped Region. Also set the RegionFS attribute to indicate that the - FrameSet in the Region does not need to be dumped if it contains a - UnitMap. */ - } else { - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - if( !astIsAUnitMap( map ) ) { - frm = astGetFrame( fs, AST__CURRENT ); - areg = astMapRegion( (AstRegion *) obj, map, frm ); - sareg = astSimplify( areg ); - astSetRegionFS( sareg, 0 ); - astMapPut0A( result, key, sareg, NULL ); - areg = astAnnul( areg ); - sareg = astAnnul( sareg ); - frm = astAnnul( frm ); - } else { - astSetRegionFS( (AstRegion *) obj, 0 ); - } - map = astAnnul( map ); - fs = astAnnul( fs ); - - } - obj = astAnnul( obj ); - } - } - } - } - } - -/* Free the returned KeyMap if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result */ - return result; - -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* Stc member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstStc *this; /* Pointer to STC structure */ - int i; /* Loop count */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the STC structure. */ - this = (AstStc *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->region, mode, extra, fail ); - for( i = 0; i < this->ncoord; i++ ) { - if( !result ) result = astManageLock( this->coord[ i ], mode, - extra, fail ); - } - - return result; - -} -#endif - -static int Overlap( AstRegion *this, AstRegion *that, int *status ){ -/* -* Name: -* Overlap - -* Purpose: -* Test if two regions overlap each other. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* int Overlap( AstRegion *this, AstRegion *that, int *status ) - -* Class Membership: -* Stc member function (over-rides the astOverlap method inherited -* from the Region class). - -* Description: -* This function returns an integer value indicating if the two -* supplied Regions overlap. The two Regions are converted to a commnon -* coordinate system before performing the check. If this conversion is -* not possible (for instance because the two Regions represent areas in -* different domains), then the check cannot be performed and a zero value -* is returned to indicate this. - -* Parameters: -* this -* Pointer to the first Region. -* that -* Pointer to the second Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* astOverlap() -* A value indicating if there is any overlap between the two Regions. -* Possible values are: -* -* 0 - The check could not be performed because the second Region -* could not be mapped into the coordinate system of the first -* Region. -* -* 1 - There is no overlap between the two Regions. -* -* 2 - The first Region is completely inside the second Region. -* -* 3 - The second Region is completely inside the first Region. -* -* 4 - There is partial overlap between the two Regions. -* -* 5 - The Regions are identical. -* -* 6 - The second Region is the negation of the first Region. - -* Notes: -* - The returned values 5 and 6 do not check the value of the Closed -* attribute in the two Regions. -* - A value of zero will be returned if this function is invoked with the -* AST error status set, or if it should fail for any reason. - -*/ - -/* Check the inherited status. */ - if ( !astOK ) return 0; - -/* Invoke the "astOverlap" method on the encapsulated Region. */ - return astOverlap( ((AstStc *)this)->region, that ); -} - -static int OverlapX( AstRegion *that, AstRegion *this, int *status ){ -/* -* Name: -* OverlapX - -* Purpose: -* Test if two regions overlap each other. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* int OverlapX( AstRegion *that, AstRegion *this ) - -* Class Membership: -* Stc member function (over-rides the astOverlapX method inherited -* from the Region class). - -* Description: -* This function performs the processing for the public astOverlap -* method and has exactly the same interface except that the order -* of the two arguments is swapped. This is a trick to allow -* the astOverlap method to be over-ridden by derived classes on -* the basis of the class of either of its two arguments. -* -* See the astOverlap method for details of the interface. - -*/ - -/* Local Variables: */ - int result; - -/* Check the inherited status. */ - if ( !astOK ) return 0; - -/* Invoke the "astOverlapX" method on the encapsulated Region. */ - result = astOverlap( ((AstStc *)that)->region, this ); - -/* Swap the returned values 2 and 3 to take account of the swapping of - the regions.*/ - if( result == 2 ) { - result = 3; - } else if( result == 3 ) { - result = 2; - } - -/* Return the result. */ - return result; -} - -static void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ){ -/* -* Name: -* RegBaseBox - -* Purpose: -* Returns the bounding box of an un-negated Region in the base Frame of -* the encapsulated FrameSet. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* void RegBaseBox( AstRegion *this, double *lbnd, double *ubnd, int *status ) - -* Class Membership: -* Stc member function (over-rides the astRegBaseBox protected -* method inherited from the Region class). - -* Description: -* This function returns the upper and lower axis bounds of a Region in -* the base Frame of the encapsulated FrameSet, assuming the Region -* has not been negated. That is, the value of the Negated attribute -* is ignored. - -* Parameters: -* this -* Pointer to the Region. -* lbnd -* Pointer to an array in which to return the lower axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* ubnd -* Pointer to an array in which to return the upper axis bounds -* covered by the Region in the base Frame of the encapsulated -* FrameSet. It should have at least as many elements as there are -* axes in the base Frame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Invoke the method on the encapsulated Region. */ - astRegBaseBox( ((AstStc *)this)->region, lbnd, ubnd ); -} - -static AstPointSet *RegBaseMesh( AstRegion *this, int *status ){ -/* -* Name: -* RegBaseMesh - -* Purpose: -* Create a new PointSet containing a mesh of points on the boundary of a -* Region in its base Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* AstPointSet *astRegBaseMesh( AstRegion *this, int *status ) - -* Class Membership: -* Stc member function (over-rides the astRegBaseMesh protected -* method inherited from the Region class). - -* Description: -* This function creates a new PointSet containing a mesh of points on the -* boundary of the Region. The points refer to the base Frame of -* the encapsulated FrameSet. - -* Parameters: -* this -* Pointer to the Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the PointSet. Annul the pointer using astAnnul when it -* is no longer needed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. - -*/ - -/* Check the global error status. */ - if( !astOK ) return NULL; - -/* Invoke the astRegMesh method on the encapsulated Region. This returns - a mesh in the current Frame of the encapsulated Region which is the same - as the base Frame of the Stc Region. */ - return astRegMesh( ((AstStc *)this)->region ); -} - -static AstRegion *RegBasePick( AstRegion *this_region, int naxes, - const int *axes, int *status ){ -/* -* Name: -* RegBasePick - -* Purpose: -* Return a Region formed by picking selected base Frame axes from the -* supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* AstRegion *RegBasePick( AstRegion *this, int naxes, const int *axes, -* int *status ) - -* Class Membership: -* Stc member function (over-rides the astRegBasePick protected -* method inherited from the Region class). - -* Description: -* This function attempts to return a Region that is spanned by selected -* axes from the base Frame of the encapsulated FrameSet of the supplied -* Region. This may or may not be possible, depending on the class of -* Region. If it is not possible a NULL pointer is returned. - -* Parameters: -* this -* Pointer to the Region. -* naxes -* The number of base Frame axes to select. -* axes -* An array holding the zero-based indices of the base Frame axes -* that are to be selected. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the Region, or NULL if no region can be formed. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Invoke the astRegBaePick method on the encapsulated Region. */ - return astRegBasePick( ((AstStc *)this_region)->region, naxes, axes ); -} - -static void RegClearAttrib( AstRegion *this_region, const char *attrib, - char **base_attrib, int *status ) { -/* -* Name: -* RegClearAttrib - -* Purpose: -* Clear an attribute value for a Region. - -* Type: -* Protected function. - -* Synopsis: -* #include "stc.h" -* void RegClearAttrib( AstRegion *this, const char *attrib, -* char **base_attrib, int *status ) - -* Class Membership: -* Stc method (over-rides the astRegClearAttrib method inherited from -* the Region class). - -* Description: -* This function clears the value of an attribute in both the base and -* current Frame in the FrameSet encapsulated within a Region, without -* remapping either Frame. -* -* No error is reported if the attribute is not recognised by the base -* Frame. - -* Parameters: -* this -* Pointer to the Region. -* attrib -* Pointer to a null terminated string containing an attribute name. -* NOTE, IT SHOULD BE ENTIRELY LOWER CASE. -* base_attrib -* Address of a location at which to return a pointer to the null -* terminated string holding the name of the attribute which was -* cleared in the base Frame of the encapsulated FrameSet. This may -* differ from the supplied name if the supplied name contains an axis -* index and the current->base Mapping in the FrameSet produces an -* axis permutation. The returned pointer should be freed using -* astFree when no longer needed. A NULL pointer may be supplied in -* which case no pointer is returned. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstStc *this; - char *batt; - int rep; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Stc structure. */ - this = (AstStc *) this_region; - -/* Use the RegClearAttrib method inherited from the parent class to clear - the attribute in the current and base Frames in the FrameSet encapsulated - by the parent Region structure. */ - (*parent_regclearattrib)( this_region, attrib, &batt, status ); - -/* Now clear the base Frame attribute in the encapsulated Region (the current - Frame within the encapsulated Region is equivalent to the base Frame in the - parent Region structure). Annul any "attribute unknown" error that results - from attempting to do this. */ - if( astOK ) { - rep = astReporting( 0 ); - astRegClearAttrib( this->region, batt, NULL ); - if( astStatus == AST__BADAT ) astClearStatus; - astReporting( rep ); - } - -/* If required, return the base Frame attribute name, otherwise free it. */ - if( base_attrib ) { - *base_attrib = batt; - } else { - batt = astFree( batt ); - } -} - -static int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, - int **mask, int *status ){ -/* -* Name: -* RegPins - -* Purpose: -* Check if a set of points fall on the boundary of a given Stc. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* int RegPins( AstRegion *this, AstPointSet *pset, AstRegion *unc, -* int **mask, int *status ) - -* Class Membership: -* Stc member function (over-rides the astRegPins protected -* method inherited from the Region class). - -* Description: -* This function returns a flag indicating if the supplied set of -* points all fall on the boundary of the given Stc. -* -* Some tolerance is allowed, as specified by the uncertainty Region -* stored in the supplied Stc "this", and the supplied uncertainty -* Region "unc" which describes the uncertainty of the supplied points. - -* Parameters: -* this -* Pointer to the Stc. -* pset -* Pointer to the PointSet. The points are assumed to refer to the -* base Frame of the FrameSet encapsulated by "this". -* unc -* Pointer to a Region representing the uncertainties in the points -* given by "pset". The Region is assumed to represent the base Frame -* of the FrameSet encapsulated by "this". Zero uncertainity is assumed -* if NULL is supplied. -* mask -* Pointer to location at which to return a pointer to a newly -* allocated dynamic array of ints. The number of elements in this -* array is equal to the value of the Npoint attribute of "pset". -* Each element in the returned array is set to 1 if the -* corresponding position in "pset" is on the boundary of the Region -* and is set to zero otherwise. A NULL value may be supplied -* in which case no array is created. If created, the array should -* be freed using astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the points all fall on the boundary of the given -* Region, to within the tolerance specified. Zero otherwise. - -*/ - -/* Check the global error status. */ - if( !astOK ) return 0; - -/* Invoke the method on the encapsulated Region. */ - return astRegPins( ((AstStc *)this)->region, pset, unc, mask ); -} - -static void RegSetAttrib( AstRegion *this_region, const char *setting, - char **base_setting, int *status ) { -/* -* Name: -* RegSetAttrib - -* Purpose: -* Set an attribute value for a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* void RegSetAttrib( AstRegion *this, const char *setting, -* char **base_setting, int *status ) - -* Class Membership: -* Stc method (over-rides the astRegSetAttrib method inherited from -* the Region class). - -* Description: -* This function assigns an attribute value to both the base and -* current Frame in the FrameSet encapsulated within a Region, without -* remapping either Frame. -* -* No error is reported if the attribute is not recognised by the base -* Frame. - -* Parameters: -* this -* Pointer to the Region. -* setting -* Pointer to a null terminated attribute setting string. NOTE, IT -* SHOULD BE ENTIRELY LOWER CASE. The supplied string will be -* interpreted using the public interpretation implemented by -* astSetAttrib. This can be different to the interpretation of the -* protected accessor functions. For instance, the public -* interpretation of an unqualified floating point value for the -* Epoch attribute is to interpet the value as a gregorian year, -* but the protected interpretation is to interpret the value as an -* MJD. -* base_setting -* Address of a location at which to return a pointer to the null -* terminated attribute setting string which was applied to the -* base Frame of the encapsulated FrameSet. This may differ from -* the supplied setting if the supplied setting contains an axis -* index and the current->base Mapping in the FrameSet produces an -* axis permutation. The returned pointer should be freed using -* astFree when no longer needed. A NULL pointer may be supplied in -* which case no pointer is returned. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstKeyMap *keymap; - AstObject *obj; - AstRegion *reg; - AstStc *this; - char *bset; - int i; - int ikey; - int rep; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Stc structure. */ - this = (AstStc *) this_region; - -/* Use the RegSetAttrib method inherited from the parent class to apply the - setting to the current and base Frames in the FrameSet encapsulated by the - parent Region structure. */ - (*parent_regsetattrib)( this_region, setting, &bset, status ); - -/* Now apply the base Frame setting to the encapsulated Region (the current - Frame within the encapsulated Region is equivalent to the base Frame in the - parent Region structure). Annul any "attribute unknown" error that results - from attempting to do this. Also do any AstroCoords in the Stc. */ - if( astOK ) { - rep = astReporting( 0 ); - astRegSetAttrib( this->region, bset, NULL ); - if( astStatus == AST__BADAT ) astClearStatus; - -/* Loop round all AstroCoords elements. */ - for( i = 0; i < this->ncoord; i++ ) { - -/* Get a pointer to the KeyMap holding a description of the current - AstroCoords element. */ - keymap = this->coord[ i ]; - -/* Loop round all the elements of this KeyMap which may hold a Region - pointer. */ - for( ikey = 0; ikey < NREG; ikey++ ) { - -/* If the KeyMap contains a Region for this key, get a pointer to it. */ - if( astMapGet0A( keymap, regkey[ ikey ], &obj ) ){ - reg = (AstRegion *) obj; - -/* Modify it by applying the attribute setting. */ - astRegSetAttrib( reg, bset, NULL ); - if( astStatus == AST__BADAT ) astClearStatus; - -/* Annul the pointer. */ - reg = astAnnul( reg ); - } - } - } - - astReporting( rep ); - } - -/* If required, return the base Frame setting string, otherwise free it. */ - if( base_setting ) { - *base_setting = bset; - } else { - bset = astFree( bset ); - } -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Stc. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* Stc member function (over-rides the astSetAttrib method inherited -* from the Region class). - -* Description: -* This function assigns an attribute value for a Stc, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Stc. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -*/ - -/* Local Vaiables: */ - AstStc *this; /* Pointer to the Stc structure */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Stc structure. */ - this = (AstStc *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* (none as yet) */ - -/* Read-only attributes. */ -/* --------------------- */ -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* Use this macro to report an error if a read-only attribute has been - specified. */ - if ( MATCH( "regionclass" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) { -/* -* Name: -* SetRegFS - -* Purpose: -* Stores a new FrameSet in a Region - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* void SetRegFS( AstRegion *this_region, AstFrame *frm, int *status ) - -* Class Membership: -* Stc method (over-rides the astSetRegFS method inherited from -* the Region class). - -* Description: -* This function creates a new FrameSet and stores it in the supplied -* Region. The new FrameSet contains two copies of the supplied -* Frame, connected by a UnitMap. - -* Parameters: -* this -* Pointer to the Region. -* frm -* The Frame to use. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstRegion *creg; /* Pointer to encapsulated Region structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the parent method to store the FrameSet in the parent Region - structure. */ - (* parent_setregfs)( this_region, frm, status ); - -/* If the encapsulated Region has a dummy FrameSet use this method - recursively to give it the same FrameSet. */ - creg = ((AstStc *) this_region )->region; - if( creg && !astGetRegionFS( creg ) ) astSetRegFS( creg, frm ); - -} - -static AstMapping *Simplify( AstMapping *this_mapping, int *status ) { -/* -* Name: -* Simplify - -* Purpose: -* Simplify a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "region.h" -* AstMapping *Simplify( AstMapping *this, int *status ) - -* Class Membership: -* Stc method (over-rides the astSimplify method inherited from -* the Region class). - -* Description: -* This function simplifies a Stc to eliminate redundant -* computational steps, or to merge separate steps which can be -* performed more efficiently in a single operation. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A new pointer to the (possibly simplified) Region. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Current Frame */ - AstKeyMap *keymap; /* KeyMap holding stroCoords element */ - AstMapping *map; /* Base->current Mapping */ - AstObject *obj; /* Pointer to object retrieved from keymap */ - AstRegion *newreg; /* New encapsulated Region */ - AstRegion *reg; /* AstroCoords Region pointer */ - AstRegion *treg; /* Temporary Region pointer */ - AstStc *stc; /* Returned Stc Structure. */ - AstStc *temp; /* Temporary Stc pointer */ - int i; /* Index of current AstroCoords element */ - int ikey; /* Index of key to be tested */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Invoke the Simplify method of the parent Region class. This simplifies - the FrameSet and uncertainty Region in the parent Region structure. */ - stc = (AstStc *) (AstRegion *) (* parent_simplify)( this_mapping, status ); - -/* If the Stc is negated, we can perform a simplication by transferring - the negated state from the Stc itself to the encapsulated Region. */ - if( astGetNegated( stc ) ) { - -/* Ensure that modifying "stc" will not modify the supplied Stc, by - creating a copy of the supplied Stc, if this has not already been done. */ - if( stc == (AstStc *) this_mapping ) { - temp = (AstStc *) astCopy( stc ); - (void) astAnnul( stc ); - stc = temp; - } - -/* Modify "temp" by negating both the Stc structure and its encapsulated - Region. */ - astNegate( stc ); - astNegate( stc->region ); - - } - -/* Get the base->current Mapping from the parent Region structure, and - the current Frame. */ - map = astGetMapping( ((AstRegion *) stc)->frameset, AST__BASE, AST__CURRENT ); - frm = astGetFrame( ((AstRegion *) stc)->frameset, AST__CURRENT ); - -/* We may be able to perform some more simplication on the encapsulated - Region itself. If the above mapping is not a unit map, remap the - encapsulated Region into the current Frame of the parent Region structure - and simplify it. This transfers complication from the Mapping in the - parent Region structure to the encapsulated Region. */ - if( !astIsAUnitMap( map ) ) { - treg = astMapRegion( stc->region, map, frm ); - newreg = astSimplify( treg ); - treg = astAnnul( treg ); - -/* If the base->current Mapping in the parent Region structure is a unit - map, simplification of the whole Stc is possible if the encapsulated - Region (without any remapping) can be simplied. */ - } else { - newreg = astSimplify( stc->region ); - } - -/* If the encapsulated Region has been changed, store it in the returned - Stc. */ - if( newreg != stc->region ) { - -/* Ensure that modifying "stc" will not modify the supplied Stc, by - creating a copy of the supplied Stc, if this has not already been done. */ - if( stc == (AstStc *) this_mapping ) { - temp = (AstStc *) astCopy( stc ); - (void) astAnnul( stc ); - stc = temp; - } - -/* Store the new region in "stc", annulling the existing Region. */ - if( stc ) { - (void) astAnnul( stc->region ); - stc->region = astClone( newreg ); - } - -/* The encapsulated Region now represents an area in the current Frame - represented by the supplied Stc. Since the encapsulated Region is - defined as being in the base Frame of the FrameSet in the parent - Region structure, the parent FrameSet should just be a UnitMap. Modify - it appropriately (if it not already a UnitMap). */ - if( !astIsAUnitMap( map ) ) astSetRegFS( stc, frm ); - } - -/* Free resources */ - newreg = astAnnul( newreg ); - -/* Now we do a similar process on any Regions held within an AstroCoords - elements. Loop round all AstroCoords elements. */ - if( stc ) { - for( i = 0; i < stc->ncoord; i++ ) { - -/* Get a pointewr to the KeyMap holding a description of the current - AstroCoords element. */ - keymap = stc->coord[ i ]; - -/* Loop round all the elements of this KeyMap which may hold a Region - pointer. */ - for( ikey = 0; ikey < NREG; ikey++ ) { - -/* If the KeyMap contains a Region for this key, get a pointer to it. */ - if( astMapGet0A( keymap, regkey[ ikey ], &obj ) ){ - reg = (AstRegion *) obj; - -/* We have two tasks now, firstly to ensure that this AstroCoords Region - describes an area in the base Frame of the FrameSet in the parent - Region structure (which may have been changed by the earlier - simplications performed by this function), and secondly, to attempt to - simplify the Region. - - The Stc structure addressed by the "stc" pointer will have a current - Frame given by "frm". This will also be its base Frame, and the - base->current Mapping will consequently be a UnitMap. The Mapping from - the original base Frame to the new base Frame is given by "map". Unless - this is a UnitMap, we need to remap the Region.*/ - if( !astIsAUnitMap( map ) ) { - treg = astMapRegion( reg, map, frm ); - } else { - treg = astClone( reg ); - } - -/* Now attempt to simplify the Region.*/ - newreg = astSimplify( treg ); - -/* If the Region has been changed by either of these steps, we need to - store the modified Region back in the "stc" structure which is being - returned. But we need to be careful we do not modify the supplied Stc - structure. */ - if( newreg != reg ) { - - if( stc == (AstStc *) this_mapping ) { - temp = astCopy( stc ); - (void) astAnnul( stc ); - stc = temp; - keymap = temp->coord[ i ]; - } - - astMapPut0A( keymap, regkey[ ikey ], newreg, regcom[ ikey ] ); - - } - -/* Free resources */ - reg = astAnnul( reg ); - treg = astAnnul( treg ); - newreg = astAnnul( newreg ); - - } - } - } - } - -/* Free resources */ - map = astAnnul( map ); - frm = astAnnul( frm ); - -/* If an error occurred, annul the returned Mapping. */ - if ( !astOK ) stc = astAnnul( stc ); - -/* Return the result. */ - return (AstMapping *) stc; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Stc. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Stc member function (over-rides the astTestAttrib protected -* method inherited from the Region class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Stc's attributes. - -* Parameters: -* this -* Pointer to the Stc. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstStc *this; /* Pointer to the Stc structure */ - int len; /* Length of attrib string */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Stc structure. */ - this = (AstStc *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* Read-only attributes. */ -/* --------------------- */ -/* Test if the attribute name matches any of the read-only attributes - of this class. If it does, then return zero. */ - if ( !strcmp( attrib, "regionclass" ) ) { - result = 0; - -/* Not recognised. */ -/* --------------- */ -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a Stc to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "stc.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* Stc member function (over-rides the astTransform method inherited -* from the Region class). - -* Description: -* This function takes a Stc and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required Region. -* This implies applying each of the Stc's encapsulated Region in turn, -* either in series or in parallel. - -* Parameters: -* this -* Pointer to the Stc. -* in -* Pointer to the PointSet associated with the input coordinate values. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the Stc being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *ps; /* Pointer to PointSet */ - AstPointSet *pset_tmp; /* Pointer to PointSet holding base Frame positions*/ - AstPointSet *result; /* Pointer to output PointSet */ - AstRegion *reg; /* Pointer to encapsulated Region */ - AstStc *this; /* Pointer to the Stc structure */ - double **ptr; /* Pointer to axis values */ - double **ptr_out; /* Pointer to output coordinate data */ - int coord; /* Zero-based index for coordinates */ - int good; /* Is the point inside the Stc? */ - int ncoord_out; /* No. of coordinates per output point */ - int ncoord_tmp; /* No. of coordinates per base Frame point */ - int neg; /* Negated value for encapsulated Region */ - int neg_old; /* Original Negated flag */ - int npoint; /* No. of points */ - int point; /* Loop counter for points */ - int rep; /* Original error reporting status */ - int status_value; /* AST status value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a Pointer to the Stc structure */ - this = (AstStc *) this_mapping; - -/* Get the encapsulated Region, and the Negated value which should be used - with it. The returned values take account of whether the supplied Stc has - itself been Negated or not. The returned Region represent a region within - the base Frame of the FrameSet encapsulated by the parent Region - structure. */ - GetRegion( this, ®, &neg, status ); - -/* Temporarily set the Negated attribute to the required value.*/ - neg_old = astGetNegated( reg ); - astSetNegated( reg, neg ); - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Region class. This function validates - all arguments and generates an output PointSet if necessary, containing - a copy of the input PointSet. */ - result = (*parent_transform)( this_mapping, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* First use the encapsulated FrameSet in the parent Region structure to - transform the supplied positions from the current Frame in the - encapsulated FrameSet (the Frame represented by the Stc), to the - base Frame (the Frame in which the encapsulated Region are defined). Note, - the returned pointer may be a clone of the "in" pointer, and so we - must be carefull not to modify the contents of the returned PointSet. */ - pset_tmp = astRegTransform( this, in, 0, NULL, NULL ); - -/* Now transform this PointSet using the encapsulated Region. */ - ps = astTransform( reg, pset_tmp, 0, NULL ); - -/* Determine the numbers of points and coordinates per point for these base - Frame PointSets and obtain pointers for accessing the base Frame and output - coordinate values. */ - npoint = astGetNpoint( pset_tmp ); - ncoord_tmp = astGetNcoord( pset_tmp ); - ptr = astGetPoints( ps ); - ncoord_out = astGetNcoord( result ); - ptr_out = astGetPoints( result ); - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if ( astOK ) { - - for ( point = 0; point < npoint; point++ ) { - good = 0; - - for ( coord = 0; coord < ncoord_tmp; coord++ ) { - if( ptr[ coord ][ point ] != AST__BAD ) { - good = 1; - break; - } - } - - if( !good ) { - for ( coord = 0; coord < ncoord_out; coord++ ) { - ptr_out[ coord ][ point ] = AST__BAD; - } - } - } - } - -/* Re-instate the original value for the Negated attribute of the - encapsulated Region. Do this even if an error has occurred. */ - status_value = astStatus; - astClearStatus; - rep = astReporting( 0 ); - if( reg ) astSetNegated( reg, neg_old ); - astReporting( rep ); - astSetStatus( status_value ); - -/* Free resources. */ - reg = astAnnul( reg ); - ps = astAnnul( ps ); - pset_tmp = astAnnul( pset_tmp ); - -/* If an error occurred, clean up by deleting the output PointSet (if - allocated by this function) and setting a NULL result pointer. */ - if ( !astOK ) { - if ( !out ) result = astDelete( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - - -/* Stc Attributes: */ -/* =============== */ - -/* -*att++ -* Name: -* RegionClass - -* Purpose: -* The AST class name of the Region encapsulated within an Stc - -* Type: -* Public attribute. - -* Synopsis: -* String, read-only. - -* Description: -* This is a read-only attribute giving the AST class name of the -* Region encapsulated within an Stc (that is, the class of the Region -* which was supplied when the Stc was created). - -* Applicability: -* Stc -* All Stc objects this attribute. -*att-- -*/ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Stc objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Stc objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Regions within the Stc. -*/ - -/* Local Variables: */ - AstStc *in; /* Pointer to input Stc */ - AstStc *out; /* Pointer to output Stc */ - int i; /* AstroCoords index */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Stcs. */ - in = (AstStc *) objin; - out = (AstStc *) objout; - -/* For safety, start by clearing any references to the input component - Regions, etc, from the output Stc. */ - out->region = NULL; - out->coord = NULL; - out->ncoord = 0; - -/* Make a copy of the Region and store a pointer to it in the output Stc - structure. */ - out->region = astCopy( in->region ); - -/* Copy any memory holding AstroCoords values */ - if( in->coord && in->ncoord ) { - out->ncoord = in->ncoord; - out->coord = astMalloc( sizeof(AstKeyMap *) * (size_t)in->ncoord ); - if( out->coord ) { - for( i = 0; i < in->ncoord; i++ ) { - out->coord[ i ] = astCopy( in->coord[ i ] ); - } - } - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Stc objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Stc objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstStc *this; /* Pointer to Stc */ - int i; /* AstroCoords index */ - -/* Obtain a pointer to the Stc structure. */ - this = (AstStc *) obj; - -/* Annul the pointer to the encapsulated Region. */ - this->region = astAnnul( this->region ); - -/* Free any memory holding AstroCoords values */ - if( this->coord ) { - for( i = 0; i < this->ncoord; i++ ) { - this->coord[ i ] = astAnnul( this->coord[ i ] ); - } - this->coord = astFree( this->coord ); - } -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Stc objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Stc class to an output Channel. - -* Parameters: -* this -* Pointer to the Stc whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define COMMENT_LEN 150 /* Maximum length of a comment string */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstStc *this; /* Pointer to the Stc structure */ - char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment string */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int ico; /* Loop counter for KeyMaps */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Stc structure. */ - this = (AstStc *) this_object; - -/* Write out values representing the instance variables for the Stc - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Encapsulated Region. */ -/* -------------------- */ - astWriteObject( channel, "Region", 1, 1, this->region, - "STC Region" ); - -/* AstroCoords info */ -/* ---------------- */ - astWriteInt( channel, "Ncoord", ( this->ncoord != 0 ), 0, this->ncoord, - "Number of AstroCoords elements" ); - - for ( ico = 1; ico <= this->ncoord; ico++ ) { - (void) sprintf( key, "Coord%d", ico ); - (void) sprintf( comment, "AstroCoords number %d", ico ); - astWriteObject( channel, key, 1, 1, this->coord[ ico - 1 ], - comment ); - } - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAStc and astCheckStc functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Stc,Region) -astMAKE_CHECK(Stc) - -AstStc *astInitStc_( void *mem, size_t size, int init, AstStcVtab *vtab, - const char *name, AstRegion *region, int ncoords, - AstKeyMap **coords, int *status ) { -/* -*+ -* Name: -* astInitStc - -* Purpose: -* Initialise a Stc. - -* Type: -* Protected function. - -* Synopsis: -* #include "stc.h" -* AstStc *astInitStc( void *mem, size_t size, int init, AstStcVtab *vtab, -* const char *name, AstRegion *region, int ncoords, -* AstKeyMap **coords ) - -* Class Membership: -* Stc initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Stc object. It allocates memory (if necessary) to -* accommodate the Stc plus any additional data associated with the -* derived class. It then initialises a Stc structure at the start -* of this memory. If the "init" flag is set, it also initialises the -* contents of a virtual function table for a Stc at the start of -* the memory passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Stc is to be initialised. -* This must be of sufficient size to accommodate the Stc data -* (sizeof(Stc)) plus any data used by the derived class. If a -* value of NULL is given, this function will allocate the memory itself -* using the "size" parameter to determine its size. -* size -* The amount of memory used by the Stc (plus derived class -* data). This will be used to allocate memory if a value of NULL is -* given for the "mem" parameter. This value is also stored in the -* Stc structure, so a valid value must be supplied even if not -* required for allocating memory. -* init -* A logical flag indicating if the Stc's virtual function table -* is to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Stc. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* region -* Pointer to the Region represented by the Stc. -* ncoords -* Number of KeyMap pointers supplied in "coords". Can be zero. -* Ignored if "coords" is NULL. -* coords -* Pointer to an array of "ncoords" KeyMap pointers, or NULL if -* "ncoords" is zero. Each KeyMap defines defines a single -* element, and should have elements with keys given by constants -* AST__STCNAME, AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. Any of these elements may be omitted, but no other -* elements should be included. If supplied, the AST__STCNAME element -* should be a vector of character string pointers holding the "Name" -* item for each axis. Any other supplied elements should be scalar -* elements, each holding a pointer to a Region describing the -* associated item of ancillary information (error, resolution, size, -* pixel size or value). These Regions should describe a volume within -* the coordinate system represented by "region". - -* Returned Value: -* A pointer to the new Stc. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstMapping *frm; /* Current Frame in supplied Stc */ - AstMapping *map; /* Base -> Current Mapping in supplied Stc */ - AstRegion *reg; /* Copy of supplied Region */ - AstStc *new; /* Pointer to new Stc */ - int i; /* AstroCoords index */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitStcVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* If the supplied Region is an Stc, create a new Region by mapping the - encapsulated Region within the supplied Stc into the current Frame of the - Stc. */ - if( astIsAStc( region ) ) { - map = astGetMapping( region->frameset, AST__BASE, AST__CURRENT ); - frm = astGetFrame( region->frameset, AST__CURRENT ); - reg = astMapRegion( ((AstStc *) region)->region, map, frm ); - frm = astAnnul( frm ); - map = astAnnul( map ); - -/* Otherwise, just take a copy of the supplied Region. */ - } else { - reg = astCopy( region ); - } - -/* Initialise a Region structure (the parent class) as the first component - within the Stc structure, allocating memory if necessary. A NULL - PointSet is suppled as the encapsulated Region will perform the function - of defining the Region shape. The base Frame of the FrameSet in the - parent Region structure will be the same as the current Frames of the - FrameSets in the two encapsulated Region. */ - if ( astOK ) { - new = (AstStc *) astInitRegion( mem, size, 0, (AstRegionVtab *) vtab, - name, reg, NULL, NULL ); - -/* Initialise the Stc data. */ -/* --------------------------- */ -/* Store a pointer to the encapsulated Region. */ - new->region = astClone( reg ); - -/* No AstroCoords info as yet. */ - new->ncoord = 0; - new->coord = NULL; - -/* Transfer attributes from the encapsulated region to the parent region. */ - astRegOverlay( new, reg, 1 ); - if( astTestIdent( reg ) ) astSetIdent( new, astGetIdent( reg ) ); - -/* If the base->current Mapping in the FrameSet within the encapsulated Region - is a UnitMap, then the FrameSet does not need to be included in the - Dump of the new Stc. Set the RegionFS attribute of the encapsulated - Region to zero to flag this. Note, we do this after the previous class - to astRegOverlay because we do not want this zero value for RegionFS to - be copied into the new Stc object. */ - astSetRegionFS( reg, 0 ); - -/* For each supplied AstroCoords, create a new KeyMap holding Regions - representing the various elements of the AstroCoords, and store the - new KeyMap in the Stc structure. */ - if( coords && ncoords > 0 ) { - new->ncoord = ncoords; - new->coord = astMalloc( sizeof( AstKeyMap *)*(size_t) ncoords ); - if( new->coord ) { - for( i = 0; i < ncoords; i++ ) { - new->coord[ i ] = MakeAstroCoordsKeyMap( reg, coords[ i ], - name, status ); - } - } - } - -/* If an error occurred, clean up deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Free resources */ - reg = astAnnul( reg ); - -/* Return a pointer to the new object. */ - return new; -} - -AstStc *astLoadStc_( void *mem, size_t size, AstStcVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadStc - -* Purpose: -* Load a Stc. - -* Type: -* Protected function. - -* Synopsis: -* #include "stc.h" -* AstStc *astLoadStc( void *mem, size_t size, AstStcVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* Stc loader. - -* Description: -* This function is provided to load a new Stc using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Stc structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Stc at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the Stc is to be -* loaded. This must be of sufficient size to accommodate the -* Stc data (sizeof(Stc)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Stc (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Stc structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstStc) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Stc. If this is NULL, a pointer to -* the (static) virtual function table for the Stc class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Stc" is used instead. - -* Returned Value: -* A pointer to the new Stc. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstFrame *f1; /* Base Frame in parent Region */ - AstObject *obj; /* Pointer to Object retrieved from KeyMap */ - AstRegion *creg; /* Pointer to encapsulated Region */ - AstStc *new; /* Pointer to the new Stc */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int ico; /* Loop counter for AstroCoords */ - int ikey; /* Index of KeyMap */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Stc. In this case the - Stc belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstStc ); - vtab = &class_vtab; - name = "Stc"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitStcVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Stc. */ - new = astLoadRegion( mem, size, (AstRegionVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Stc" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Encapsulated Region. */ -/* -------------------- */ - new->region = astReadObject( channel, "region", NULL ); - -/* Get a pointer to the base Frame in the FrameSet encapsulated by the - parent Region structure. */ - f1 = astGetFrame( ((AstRegion *) new)->frameset, AST__BASE ); - -/* If the encapsulated Region has a dummy FrameSet rather than the correct - FrameSet, the correct FrameSet will have copies of the base Frame of the - new Stc as both its current and base Frames, connected by a UnitMap (this - is equivalent to a FrameSet containing a single Frame). However if the new - Stc being loaded has itself got a dummy FrameSet, then we do not do this - since we do not yet know what the correct FrameSet is. In this case we - wait until the parent Region invokes the astSetRegFS method on the new - Stc. */ - if( !astRegDummyFS( new ) ) { - creg = new->region; - if( astRegDummyFS( creg ) ) astSetRegFS( creg, f1 ); - } - -/* AstroCoords info */ -/* ---------------- */ -/* The number of AstroCoords described in the new Stc. */ - new->ncoord = astReadInt( channel, "ncoord", 0 ); - if( new->ncoord < 0 ) new->ncoord = 0; - -/* Read back each KeyMap describing these AstroCoords. */ - new->coord = astMalloc( sizeof( AstKeyMap *) * (size_t) new->ncoord ); - for( ico = 1; ico <= new->ncoord; ico++ ) { - (void) sprintf( key, "coord%d", ico ); - new->coord[ ico - 1 ] = astReadObject( channel, key, NULL ); - -/* Ensure the Regions within the KeyMap do not have dummy FrameSets. */ - if( new->coord[ ico - 1 ] && !astRegDummyFS( new ) ) { - for( ikey = 0; ikey < NREG; ikey++ ) { - if( astMapGet0A( new->coord[ ico - 1 ], regkey[ ikey ], &obj ) ){ - creg = (AstRegion *) obj; - if( astRegDummyFS( creg ) ) { - astSetRegFS( creg, f1 ); - astMapPut0A( new->coord[ ico - 1 ], regkey[ ikey ], creg, - regcom[ ikey ] ); - } - creg = astAnnul( creg ); - } - } - } - } - -/* Free resources */ - f1 = astAnnul( f1 ); - -/* If an error occurred, clean up by deleting the new Stc. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Stc pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -const char *astGetRegionClass_( AstStc *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Stc,GetRegionClass))( this, status ); -} - -AstRegion *astGetStcRegion_( AstStc *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Stc,GetStcRegion))( this, status ); -} - -AstKeyMap *astGetStcCoord_( AstStc *this, int icoord, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Stc,GetStcCoord))( this, icoord, status ); -} - -int astGetStcNCoord_( AstStc *this, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Stc,GetStcNCoord))( this, status ); -} - - - - - - - - - - - - - diff --git a/ast/stc.h b/ast/stc.h deleted file mode 100644 index 1fe0b1b..0000000 --- a/ast/stc.h +++ /dev/null @@ -1,240 +0,0 @@ -#if !defined( STC_INCLUDED ) /* Include this file only once */ -#define STC_INCLUDED -/* -*+ -* Name: -* stc.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Stc class. - -* Invocation: -* #include "stc.h" - -* Description: -* This include file defines the interface to the Stc class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The Stc class is an implementation of the IVOA STC class which forms -* part of the IVOA Space-Time Coordinate Metadata system. See: -* -* http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Inheritance: -* The Stc class inherits from the Region class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 23-NOV-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "region.h" /* Coordinate regions (parent class) */ -#include "keymap.h" /* Lists of value/key pairs */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros. */ -/* ======= */ - - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif -#define AST__STCNAME "Name" -#define AST__STCVALUE "Value" -#define AST__STCERROR "Error" -#define AST__STCRES "Resolution" -#define AST__STCSIZE "Size" -#define AST__STCPIXSZ "PixSize" - -/* Type Definitions. */ -/* ================= */ -/* Stc structure. */ -/* ------------------ */ - -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstStc { - -/* Attributes inherited from the parent class. */ - AstRegion parent_region; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstRegion *region; /* Encapsulated Region */ - AstKeyMap **coord; /* STC AstroCoords info */ - int ncoord; /* Number of AstroCoords in "coords" */ -} AstStc; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstStcVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstRegionVtab region_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - const char *(* GetRegionClass)( AstStc *, int * ); - AstRegion *(* GetStcRegion)( AstStc *, int * ); - AstKeyMap *(* GetStcCoord)( AstStc *, int, int * ); - int (* GetStcNCoord)( AstStc *, int * ); - -} AstStcVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstStcGlobals { - AstStcVtab Class_Vtab; - int Class_Init; -} AstStcGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitStcGlobals_( AstStcGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Stc) /* Check class membership */ -astPROTO_ISA(Stc) /* Test class membership */ - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstStc *astInitStc_( void *, size_t, int, AstStcVtab *, const char *, - AstRegion *, int, AstKeyMap **, int * ); - -/* Vtab initialiser. */ -void astInitStcVtab_( AstStcVtab *, const char *, int * ); - -/* Loader. */ -AstStc *astLoadStc_( void *, size_t, AstStcVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -AstRegion *astGetStcRegion_( AstStc *, int * ); -AstKeyMap *astGetStcCoord_( AstStc *, int, int * ); -int astGetStcNCoord_( AstStc *, int * ); - -# if defined(astCLASS) /* Protected */ -const char *astGetRegionClass_( AstStc *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckStc(this) astINVOKE_CHECK(Stc,this,0) -#define astVerifyStc(this) astINVOKE_CHECK(Stc,this,1) - -/* Test class membership. */ -#define astIsAStc(this) astINVOKE_ISA(Stc,this) - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitStc(mem,size,init,vtab,name,reg,ncoords,coords) \ -astINVOKE(O,astInitStc_(mem,size,init,vtab,name,reg,ncoords,coords,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitStcVtab(vtab,name) astINVOKE(V,astInitStcVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadStc(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadStc_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckStc to validate Stc pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astGetStcRegion(this) astINVOKE(O,astGetStcRegion_(astCheckStc(this),STATUS_PTR)) -#define astGetStcCoord(this,icoord) astINVOKE(O,astGetStcCoord_(astCheckStc(this),icoord,STATUS_PTR)) -#define astGetStcNCoord(this) astINVOKE(V,astGetStcNCoord_(astCheckStc(this),STATUS_PTR)) -#if defined(astCLASS) /* Protected */ -#define astGetRegionClass(this) astINVOKE(V,astGetRegionClass_(astCheckStc(this),STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/stccatalogentrylocation.c b/ast/stccatalogentrylocation.c deleted file mode 100644 index a1ea16f..0000000 --- a/ast/stccatalogentrylocation.c +++ /dev/null @@ -1,804 +0,0 @@ -/* -*class++ -* Name: -* StcCatalogEntryLocation - -* Purpose: -* Correspond to the IVOA STCCatalogEntryLocation class. - -* Constructor Function: -c astStcCatalogEntryLocation -f AST_STCCATALOGENTRYLOCATION - -* Description: -* The StcCatalogEntryLocation class is a sub-class of Stc used to describe -* the coverage of the datasets contained in some VO resource. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Inheritance: -* The StcCatalogEntryLocation class inherits from the Stc class. - -* Attributes: -* The StcCatalogEntryLocation class does not define any new attributes beyond -* those which are applicable to all Stcs. - -* Functions: -c The StcCatalogEntryLocation class does not define any new functions beyond those -f The StcCatalogEntryLocation class does not define any new routines beyond those -* which are applicable to all Stcs. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 26-NOV-2004 (DSB): -* Original version. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS StcCatalogEntryLocation - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "stc.h" /* Coordinate stcs (parent class) */ -#include "channel.h" /* I/O channels */ -#include "region.h" /* Regions within coordinate systems */ -#include "stccatalogentrylocation.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(StcCatalogEntryLocation) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(StcCatalogEntryLocation,Class_Init) -#define class_vtab astGLOBAL(StcCatalogEntryLocation,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstStcCatalogEntryLocationVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstStcCatalogEntryLocation *astStcCatalogEntryLocationId_( void *, int, AstKeyMap **, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static void Dump( AstObject *, AstChannel *, int * ); - -/* Member functions. */ -/* ================= */ - -void astInitStcCatalogEntryLocationVtab_( AstStcCatalogEntryLocationVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitStcCatalogEntryLocationVtab - -* Purpose: -* Initialise a virtual function table for a StcCatalogEntryLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "stccatalogentrylocation.h" -* void astInitStcCatalogEntryLocationVtab( AstStcCatalogEntryLocationVtab *vtab, const char *name ) - -* Class Membership: -* StcCatalogEntryLocation vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the StcCatalogEntryLocation class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstStcVtab *stc; /* Pointer to Stc component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitStcVtab( (AstStcVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAStcCatalogEntryLocation) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstStcVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - mapping = (AstMappingVtab *) vtab; - stc = (AstStcVtab *) vtab; - - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDump( vtab, Dump, "StcCatalogEntryLocation", "Resource coverage" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -/* None */ - -/* Destructor. */ -/* ----------- */ -/* None */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for StcCatalogEntryLocation objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the StcCatalogEntryLocation class to an output Channel. - -* Parameters: -* this -* Pointer to the StcCatalogEntryLocation whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstStcCatalogEntryLocation *this; /* Pointer to the StcCatalogEntryLocation structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the StcCatalogEntryLocation structure. */ - this = (AstStcCatalogEntryLocation *) this_object; - -/* Write out values representing the instance variables for the - StcCatalogEntryLocation class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* There are no values to write, so return without further action. */ -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAStcCatalogEntryLocation and astCheckStcCatalogEntryLocation functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(StcCatalogEntryLocation,Stc) -astMAKE_CHECK(StcCatalogEntryLocation) - - -AstStcCatalogEntryLocation *astStcCatalogEntryLocation_( void *region_void, int ncoords, - AstKeyMap **coords, const char *options, int *status, ...) { -/* -*++ -* Name: -c astStcCatalogEntryLocation -f AST_STCCATALOGENTRYLOCATION - -* Purpose: -* Create a StcCatalogEntryLocation. - -* Type: -* Public function. - -* Synopsis: -c #include "stccatalogentrylocation.h" -c AstStcCatalogEntryLocation *astStcCatalogEntryLocation( AstRegion *region, -c int ncoords, AstKeyMap *coords[], const char *options, ... ) -f RESULT = AST_STCCATALOGENTRYLOCATION( REGION, NCOORDS, COORDS, OPTIONS, STATUS ) - -* Class Membership: -* StcCatalogEntryLocation constructor. - -* Description: -* This function creates a new StcCatalogEntryLocation and optionally initialises its -* attributes. -* -* The StcCatalogEntryLocation class is a sub-class of Stc used to describe -* the coverage of the datasets contained in some VO resource. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Parameters: -c region -f REGION = INTEGER (Given) -* Pointer to the encapsulated Region. -c ncoords -f NCOORDS = INTEGER (Given) -c The length of the "coords" array. Supply zero if "coords" is NULL. -f The length of the COORDS array. Supply zero if COORDS should be -f ignored. -c coords -f COORDS( NCOORDS ) = INTEGER (Given) -c Pointer to an array holding "ncoords" AstKeyMap pointers (if "ncoords" -f An array holding NCOORDS AstKeyMap pointers (if NCOORDS -* is zero, the supplied value is ignored). Each supplied KeyMap -* describes the contents of a single STC element, and -* should have elements with keys given by constants AST__STCNAME, -* AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. Any of these elements may be omitted, but no other -* elements should be included. If supplied, the AST__STCNAME element -* should be a vector of character string pointers holding the "Name" -* item for each axis in the coordinate system represented by -c "region". -f REGION. -* Any other supplied elements should be scalar elements, each holding -* a pointer to a Region describing the associated item of ancillary -* information (error, resolution, size, pixel size or value). These -* Regions should describe a volume within the coordinate system -c represented by "region". -f represented by REGION. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new StcCatalogEntryLocation. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new StcCatalogEntryLocation. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astStcCatalogEntryLocation() -f AST_STCCATALOGENTRYLOCATION = INTEGER -* A pointer to the new StcCatalogEntryLocation. - -* Notes: -* - A deep copy is taken of the supplied Region. This means that -* any subsequent changes made to the encapsulated Region using the -* supplied pointer will have no effect on the Stc. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstRegion *region; /* Pointer to Region structure */ - AstStcCatalogEntryLocation *new; /* Pointer to new StcCatalogEntryLocation */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the Region structure provided. */ - region = astCheckRegion( region_void ); - -/* Initialise the StcCatalogEntryLocation, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitStcCatalogEntryLocation( NULL, sizeof( AstStcCatalogEntryLocation ), !class_init, - &class_vtab, "StcCatalogEntryLocation", region, - ncoords, coords ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new StcCatalogEntryLocation's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new StcCatalogEntryLocation. */ - return new; -} - -AstStcCatalogEntryLocation *astStcCatalogEntryLocationId_( void *region_void, int ncoords, - AstKeyMap **coords, const char *options, ... ) { -/* -* Name: -* astStcCatalogEntryLocationId_ - -* Purpose: -* Create a StcCatalogEntryLocation. - -* Type: -* Private function. - -* Synopsis: -* #include "stccatalogentrylocation.h" -* AstStcCatalogEntryLocation *astStcCatalogEntryLocationId( AstRegion *region, -* int ncoords, AstKeyMap *coords[], const char *options, ..., int *status ) - -* Class Membership: -* StcCatalogEntryLocation constructor. - -* Description: -* This function implements the external (public) interface to the -* astStcCatalogEntryLocation constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astStcCatalogEntryLocation_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astStcCatalogEntryLocation_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astStcCatalogEntryLocation_. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The ID value associated with the new StcCatalogEntryLocation. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstKeyMap **keymaps; /* Pointer to array of KeyMap pointers */ - AstRegion *region; /* Pointer to Region structure */ - AstStcCatalogEntryLocation *new;/* Pointer to new StcCatalogEntryLocation */ - int icoord; /* Keymap index */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Region pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Region. */ - region = astVerifyRegion( astMakePointer( region_void ) ); - -/* Obtain pointer from the supplied KeyMap ID's and validate the - pointers to ensure it identifies a valid KeyMap. */ - keymaps = astMalloc( sizeof( AstKeyMap * )*(size_t) ncoords ); - if( keymaps ) { - for( icoord = 0; icoord < ncoords; icoord++ ) { - keymaps[ icoord ] = astVerifyKeyMap( astMakePointer( coords[ icoord ] ) ); - } - } - -/* Initialise the StcCatalogEntryLocation, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitStcCatalogEntryLocation( NULL, sizeof( AstStcCatalogEntryLocation ), !class_init, - &class_vtab, "StcCatalogEntryLocation", region, - ncoords, keymaps ); - -/* Free resources. */ - keymaps = astFree( keymaps ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new StcCatalogEntryLocation's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new StcCatalogEntryLocation. */ - return astMakeId( new ); -} - -AstStcCatalogEntryLocation *astInitStcCatalogEntryLocation_( void *mem, size_t size, - int init, AstStcCatalogEntryLocationVtab *vtab, - const char *name, AstRegion *region, - int ncoords, AstKeyMap **coords, int *status ) { -/* -*+ -* Name: -* astInitStcCatalogEntryLocation - -* Purpose: -* Initialise a StcCatalogEntryLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "stccatalogentrylocation.h" -* AstStcCatalogEntryLocation *astInitStcCatalogEntryLocation_( void *mem, size_t size, -* int init, AstStcCatalogEntryLocationVtab *vtab, -* const char *name, AstRegion *region, -* int ncoords, AstKeyMap **coords ) - -* Class Membership: -* StcCatalogEntryLocation initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new StcCatalogEntryLocation object. It allocates memory (if necessary) to accommodate -* the StcCatalogEntryLocation plus any additional data associated with the derived class. -* It then initialises a StcCatalogEntryLocation structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a StcCatalogEntryLocation at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the StcCatalogEntryLocation is to be initialised. -* This must be of sufficient size to accommodate the StcCatalogEntryLocation data -* (sizeof(StcCatalogEntryLocation)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the StcCatalogEntryLocation (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the StcCatalogEntryLocation -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the StcCatalogEntryLocation's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new StcCatalogEntryLocation. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* region -* A pointer to the Region encapsulated by the StcCatalogEntryLocation. -* ncoords -* Number of KeyMap pointers supplied in "coords". Can be zero. -* Ignored if "coords" is NULL. -* coords -* Pointer to an array of "ncoords" KeyMap pointers, or NULL if -* "ncoords" is zero. Each KeyMap defines defines a single -* element, and should have elements with keys given by constants -* AST__STCNAME, AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. These elements hold values for the corresponding -* components of the STC AstroCoords element. Any of these elements may -* be omitted, but no other elements should be included. All supplied -* elements should be vector elements, with vector length less than or -* equal to the number of axes in the supplied Region. The data type of -* all elements should be "double", except for AST__STCNAME which should -* be "character string". If no value is available for a given axis, then -* AST__BAD (or NULL for the AST__STCNAME element) should be stored in -* the vector at the index corresponding to the axis (trailing axes -* can be omitted completely from the KeyMap). - -* Returned Value: -* A pointer to the new StcCatalogEntryLocation. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstStcCatalogEntryLocation *new; /* Pointer to new StcCatalogEntryLocation */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitStcCatalogEntryLocationVtab( vtab, name ); - -/* Initialise a Stc structure (the parent class) as the first component - within the StcCatalogEntryLocation structure, allocating memory if necessary. */ - new = (AstStcCatalogEntryLocation *) astInitStc( mem, size, 0, (AstStcVtab *) vtab, - name, region, ncoords, coords ); - -/* If an error occurred, clean up by deleting the new StcCatalogEntryLocation. */ - if ( !astOK ) new = astDelete( new ); - -/* Return a pointer to the new StcCatalogEntryLocation. */ - return new; -} - -AstStcCatalogEntryLocation *astLoadStcCatalogEntryLocation_( void *mem, size_t size, AstStcCatalogEntryLocationVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadStcCatalogEntryLocation - -* Purpose: -* Load a StcCatalogEntryLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "stccatalogentrylocation.h" -* AstStcCatalogEntryLocation *astLoadStcCatalogEntryLocation( void *mem, size_t size, AstStcCatalogEntryLocationVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* StcCatalogEntryLocation loader. - -* Description: -* This function is provided to load a new StcCatalogEntryLocation using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* StcCatalogEntryLocation structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a StcCatalogEntryLocation at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the StcCatalogEntryLocation is to be -* loaded. This must be of sufficient size to accommodate the -* StcCatalogEntryLocation data (sizeof(StcCatalogEntryLocation)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the StcCatalogEntryLocation (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the StcCatalogEntryLocation structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstStcCatalogEntryLocation) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new StcCatalogEntryLocation. If this is NULL, a pointer -* to the (static) virtual function table for the StcCatalogEntryLocation class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "StcCatalogEntryLocation" is used instead. - -* Returned Value: -* A pointer to the new StcCatalogEntryLocation. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstStcCatalogEntryLocation *new; /* Pointer to the new StcCatalogEntryLocation */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this StcCatalogEntryLocation. In this case the - StcCatalogEntryLocation belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstStcCatalogEntryLocation ); - vtab = &class_vtab; - name = "StcCatalogEntryLocation"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitStcCatalogEntryLocationVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built StcCatalogEntryLocation. */ - new = astLoadStc( mem, size, (AstStcVtab *) vtab, name, channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "StcCatalogEntryLocation" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* There are no values to read. */ -/* ---------------------------- */ - -/* If an error occurred, clean up by deleting the new StcCatalogEntryLocation. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new StcCatalogEntryLocation pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - - diff --git a/ast/stccatalogentrylocation.h b/ast/stccatalogentrylocation.h deleted file mode 100644 index f999e6a..0000000 --- a/ast/stccatalogentrylocation.h +++ /dev/null @@ -1,223 +0,0 @@ -#if !defined( STCCATALOGENTRYLOCATION_INCLUDED ) /* Include this file only once */ -#define STCCATALOGENTRYLOCATION_INCLUDED -/* -*+ -* Name: -* stccatalogentrylocation.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the StcCatalogEntryLocation class. - -* Invocation: -* #include "stccatalogentrylocation.h" - -* Description: -* This include file defines the interface to the StcCatalogEntryLocation class -* and provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The StcCatalogEntryLocation class is a sub-class of Stc used to describe -* the coverage of the datasets contained in some VO resource. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Inheritance: -* The StcCatalogEntryLocation class inherits from the Stc class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 26-NOV-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "stc.h" /* Coordinate stcs (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* StcCatalogEntryLocation structure. */ -/* ----------------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstStcCatalogEntryLocation { - -/* Attributes inherited from the parent class. */ - AstStc stc; /* Parent class structure */ - -} AstStcCatalogEntryLocation; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstStcCatalogEntryLocationVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstStcVtab stc_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -} AstStcCatalogEntryLocationVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstStcCatalogEntryLocationGlobals { - AstStcCatalogEntryLocationVtab Class_Vtab; - int Class_Init; -} AstStcCatalogEntryLocationGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitStcCatalogEntryLocationGlobals_( AstStcCatalogEntryLocationGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(StcCatalogEntryLocation) /* Check class membership */ -astPROTO_ISA(StcCatalogEntryLocation) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstStcCatalogEntryLocation *astStcCatalogEntryLocation_( void *, int, AstKeyMap **, const char *, int *, ...); -#else -AstStcCatalogEntryLocation *astStcCatalogEntryLocationId_( void *, int, AstKeyMap **, const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstStcCatalogEntryLocation *astInitStcCatalogEntryLocation_( void *, size_t, int, AstStcCatalogEntryLocationVtab *, const char *, AstRegion *, int, AstKeyMap **, int * ); - -/* Vtab initialiser. */ -void astInitStcCatalogEntryLocationVtab_( AstStcCatalogEntryLocationVtab *, const char *, int * ); - -/* Loader. */ -AstStcCatalogEntryLocation *astLoadStcCatalogEntryLocation_( void *, size_t, AstStcCatalogEntryLocationVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckStcCatalogEntryLocation(this) astINVOKE_CHECK(StcCatalogEntryLocation,this,0) -#define astVerifyStcCatalogEntryLocation(this) astINVOKE_CHECK(StcCatalogEntryLocation,this,1) - -/* Test class membership. */ -#define astIsAStcCatalogEntryLocation(this) astINVOKE_ISA(StcCatalogEntryLocation,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astStcCatalogEntryLocation astINVOKE(F,astStcCatalogEntryLocation_) -#else -#define astStcCatalogEntryLocation astINVOKE(F,astStcCatalogEntryLocationId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitStcCatalogEntryLocation(mem,size,init,vtab,name,region,ncoords,coords) \ -astINVOKE(O,astInitStcCatalogEntryLocation_(mem,size,init,vtab,name,region,ncoords,coords,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitStcCatalogEntryLocationVtab(vtab,name) astINVOKE(V,astInitStcCatalogEntryLocationVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadStcCatalogEntryLocation(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadStcCatalogEntryLocation_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckStcCatalogEntryLocation to validate StcCatalogEntryLocation pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#endif -#endif - - - - - diff --git a/ast/stcobsdatalocation.c b/ast/stcobsdatalocation.c deleted file mode 100644 index 777d29e..0000000 --- a/ast/stcobsdatalocation.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* -*class++ -* Name: -* StcObsDataLocation - -* Purpose: -* Correspond to the IVOA ObsDataLocation class. - -* Constructor Function: -c astStcObsDataLocation -f AST_STCOBSDATALOCATION - -* Description: -* The StcObsDataLocation class is a sub-class of Stc used to describe -* the coordinate space occupied by a particular observational dataset. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html -* -* An STC ObsDataLocation element specifies the extent of the -* observation within a specified coordinate system, and also specifies -* the observatory location within a second coordinate system. -* -* The AST StcObsDataLocation class inherits from Stc, and therefore -* an StcObsDataLocation can be used directly as an Stc. When used -* in this way, the StcObsDataLocation describes the location of the -* observation (not the observatory). -* -* Eventually, this class will have a method for returning an Stc -* describing the observatory location. However, AST currently does not -* include any classes of Frame for describing terrestrial or solar -* system positions. Therefore, the provision for returning observatory -* location as an Stc is not yet available. However, for terrestrial -* observations, the position of the observatory can still be recorded -* using the ObsLon and ObsLat attributes of the Frame encapsulated -* within the Stc representing the observation location (this assumes -* the observatory is located at sea level). - -* Inheritance: -* The StcObsDataLocation class inherits from the Stc class. - -* Attributes: -* The StcObsDataLocation class does not define any new attributes beyond -* those which are applicable to all Stcs. - -* Functions: -c The StcObsDataLocation class does not define any new functions beyond those -f The StcObsDataLocation class does not define any new routines beyond those -* which are applicable to all Stcs. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 25-APR-2005 (DSB): -* Original version. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS StcObsDataLocation - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "stc.h" /* Coordinate stcs (parent class) */ -#include "channel.h" /* I/O channels */ -#include "region.h" /* Regions within coordinate systems */ -#include "pointlist.h" /* Points within coordinate systems */ -#include "stcobsdatalocation.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); - - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(StcObsDataLocation) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(StcObsDataLocation,Class_Init) -#define class_vtab astGLOBAL(StcObsDataLocation,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstStcObsDataLocationVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstStcObsDataLocation *astStcObsDataLocationId_( void *, int, AstKeyMap **, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void StcSetObs( AstStcObsDataLocation *, AstPointList *, int * ); - -static int GetObjSize( AstObject *, int * ); -/* Member functions. */ -/* ================= */ -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "stcobsdatalocation.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* StcObsDataLocation member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied StcObsDataLocation, -* in bytes. - -* Parameters: -* this -* Pointer to the StcObsDataLocation. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstStcObsDataLocation *this; /* Pointer to StcObsDataLocation structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the StcObsDataLocation structure. */ - this = (AstStcObsDataLocation *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astGetObjSize( this->obs ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - - -void astInitStcObsDataLocationVtab_( AstStcObsDataLocationVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitStcObsDataLocationVtab - -* Purpose: -* Initialise a virtual function table for a StcObsDataLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcobsdatalocation.h" -* void astInitStcObsDataLocationVtab( AstStcObsDataLocationVtab *vtab, const char *name ) - -* Class Membership: -* StcObsDataLocation vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the StcObsDataLocation class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstStcVtab *stc; /* Pointer to Stc component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitStcVtab( (AstStcVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAStcObsDataLocation) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstStcVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - stc = (AstStcVtab *) vtab; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - vtab->StcSetObs = StcSetObs; - -/* Declare the copy constructor, destructor and class dump functions. */ - astSetDump( vtab, Dump, "StcObsDataLocation", "Observation coverage" ); - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static void StcSetObs( AstStcObsDataLocation *this, AstPointList *obs, int *status ) { -/* -*+ -* Name: -* astStcSetObs - -* Purpose: -* Set the observatory position within an StcObsDataLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "region.h" -* void astStcSetObs( AstStcObsDataLocation *this, AstPointList *obs ) - -* Class Membership: -* StcObsDataLocation virtual function - -* Description: -* This function stores a clone of the supplied PointList pointer -* within the supplied StcObsDataLocation, first annulling any -* pointer already stored in the StcObsDataLocation. - -* Parameters: -* this -* Pointer to the StcObsDataLocation. -* obs -* Pointer to a PointList defining the observatory position. NULL -* may be supplied in which case any existing observatory position -* is removed. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Free any existing obseravtory position PointList. */ - if( this->obs ) this->obs = astAnnul( this->obs ); - -/* Store any supplied pointer. */ - if( obs ) this->obs = astClone( obs ); - -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for StcObsDataLocation objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for StcObsDataLocation -* objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Regions within the StcObsDataLocation. -*/ - -/* Local Variables: */ - AstStcObsDataLocation *in; /* Pointer to input StcObsDataLocation */ - AstStcObsDataLocation *out; /* Pointer to output StcObsDataLocation */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output StcObsDataLocations. */ - in = (AstStcObsDataLocation *) objin; - out = (AstStcObsDataLocation *) objout; - -/* For safety, start by clearing any references to the input component - Regions, etc, from the output StcObsDataLocation. */ - out->obs = NULL; - -/* Make a copy of the Observatory location */ - if( in->obs ) out->obs = astCopy( in->obs ); - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for StcObsDataLocation objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for StcObsDataLocation objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstStcObsDataLocation *this; /* Pointer to StcObsDataLocation */ - -/* Obtain a pointer to the StcObsDataLocation structure. */ - this = (AstStcObsDataLocation *) obj; - -/* Annul the pointer to the observatory location Region. */ - if( this->obs ) this->obs = astAnnul( this->obs ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for StcObsDataLocation objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the StcObsDataLocation class to an output Channel. - -* Parameters: -* this -* Pointer to the StcObsDataLocation whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstStcObsDataLocation *this; /* Pointer to the StcObsDataLocation structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the StcObsDataLocation structure. */ - this = (AstStcObsDataLocation *) this_object; - -/* Write out values representing the instance variables for the - StcObsDataLocation class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Observatory position. */ -/* --------------------- */ - astWriteObject( channel, "ObsLoc", 1, 1, this->obs, "Observatory position" ); - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAStcObsDataLocation and astCheckStcObsDataLocation functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(StcObsDataLocation,Stc) -astMAKE_CHECK(StcObsDataLocation) - - -AstStcObsDataLocation *astStcObsDataLocation_( void *region_void, int ncoords, - AstKeyMap **coords, const char *options, int *status, ...) { -/* -*++ -* Name: -c astStcObsDataLocation -f AST_STCOBSDATALOCATION - -* Purpose: -* Create a StcObsDataLocation. - -* Type: -* Public function. - -* Synopsis: -c #include "stcobsdatalocation.h" -c AstStcObsDataLocation *astStcObsDataLocation( AstRegion *region, -c int ncoords, AstKeyMap *coords[], const char *options, ... ) -f RESULT = AST_STCOBSDATALOCATION( REGION, NCOORDS, COORDS, OPTIONS, STATUS ) - -* Class Membership: -* StcObsDataLocation constructor. - -* Description: -* This function creates a new StcObsDataLocation and optionally initialises its -* attributes. -* -* The StcObsDataLocation class is a sub-class of Stc used to describe -* the coverage of the datasets contained in some VO resource. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Parameters: -c region -f REGION = INTEGER (Given) -* Pointer to the encapsulated Region. -c ncoords -f NCOORDS = INTEGER (Given) -c The length of the "coords" array. Supply zero if "coords" is NULL. -f The length of the COORDS array. Supply zero if COORDS should be -f ignored. -c coords -f COORDS( NCOORDS ) = INTEGER (Given) -c Pointer to an array holding "ncoords" AstKeyMap pointers (if "ncoords" -f An array holding NCOORDS AstKeyMap pointers (if NCOORDS -* is zero, the supplied value is ignored). Each supplied KeyMap -* describes the contents of a single STC element, and -* should have elements with keys given by constants AST__STCNAME, -* AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. Any of these elements may be omitted, but no other -* elements should be included. If supplied, the AST__STCNAME element -* should be a vector of character string pointers holding the "Name" -* item for each axis in the coordinate system represented by -c "region". -f REGION. -* Any other supplied elements should be scalar elements, each holding -* a pointer to a Region describing the associated item of ancillary -* information (error, resolution, size, pixel size or value). These -* Regions should describe a volume within the coordinate system -c represented by "region". -f represented by REGION. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new StcObsDataLocation. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new StcObsDataLocation. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astStcObsDataLocation() -f AST_STCOBSDATALOCATION = INTEGER -* A pointer to the new StcObsDataLocation. - -* Notes: -* - A deep copy is taken of the supplied Region. This means that -* any subsequent changes made to the encapsulated Region using the -* supplied pointer will have no effect on the Stc. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstRegion *region; /* Pointer to Region structure */ - AstStcObsDataLocation *new; /* Pointer to new StcObsDataLocation */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the Region structure provided. */ - region = astCheckRegion( region_void ); - -/* Initialise the StcObsDataLocation, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitStcObsDataLocation( NULL, sizeof( AstStcObsDataLocation ), !class_init, - &class_vtab, "StcObsDataLocation", region, - ncoords, coords ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new StcObsDataLocation's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new StcObsDataLocation. */ - return new; -} - -AstStcObsDataLocation *astStcObsDataLocationId_( void *region_void, int ncoords, - AstKeyMap **coords, const char *options, ... ) { -/* -* Name: -* astStcObsDataLocationId_ - -* Purpose: -* Create a StcObsDataLocation. - -* Type: -* Private function. - -* Synopsis: -* #include "stcobsdatalocation.h" -* AstStcObsDataLocation *astStcObsDataLocationId( AstRegion *region, -* int ncoords, AstKeyMap *coords[], const char *options, ..., int *status ) - -* Class Membership: -* StcObsDataLocation constructor. - -* Description: -* This function implements the external (public) interface to the -* astStcObsDataLocation constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astStcObsDataLocation_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astStcObsDataLocation_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astStcObsDataLocation_. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The ID value associated with the new StcObsDataLocation. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstKeyMap **keymaps; /* Pointer to array of KeyMap pointers */ - AstRegion *region; /* Pointer to Region structure */ - AstStcObsDataLocation *new; /* Pointer to new StcObsDataLocation */ - int icoord; /* Keymap index */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Region pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Region. */ - region = astVerifyRegion( astMakePointer( region_void ) ); - -/* Obtain pointer from the supplied KeyMap ID's and validate the - pointers to ensure it identifies a valid KeyMap. */ - keymaps = astMalloc( sizeof( AstKeyMap * )*(size_t) ncoords ); - if( keymaps ) { - for( icoord = 0; icoord < ncoords; icoord++ ) { - keymaps[ icoord ] = astVerifyKeyMap( astMakePointer( coords[ icoord ] ) ); - } - } - -/* Initialise the StcObsDataLocation, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitStcObsDataLocation( NULL, sizeof( AstStcObsDataLocation ), !class_init, - &class_vtab, "StcObsDataLocation", region, - ncoords, keymaps ); - -/* Free resources. */ - keymaps = astFree( keymaps ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new StcObsDataLocation's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new StcObsDataLocation. */ - return astMakeId( new ); -} - -AstStcObsDataLocation *astInitStcObsDataLocation_( void *mem, size_t size, - int init, AstStcObsDataLocationVtab *vtab, - const char *name, AstRegion *region, - int ncoords, AstKeyMap **coords, int *status ) { -/* -*+ -* Name: -* astInitStcObsDataLocation - -* Purpose: -* Initialise a StcObsDataLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcobsdatalocation.h" -* AstStcObsDataLocation *astInitStcObsDataLocation_( void *mem, size_t size, -* int init, AstStcObsDataLocationVtab *vtab, -* const char *name, AstRegion *region, -* int ncoords, AstKeyMap **coords ) - -* Class Membership: -* StcObsDataLocation initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new StcObsDataLocation object. It allocates memory (if necessary) to accommodate -* the StcObsDataLocation plus any additional data associated with the derived class. -* It then initialises a StcObsDataLocation structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a StcObsDataLocation at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the StcObsDataLocation is to be initialised. -* This must be of sufficient size to accommodate the StcObsDataLocation data -* (sizeof(StcObsDataLocation)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the StcObsDataLocation (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the StcObsDataLocation -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the StcObsDataLocation's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new StcObsDataLocation. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* region -* A pointer to the Region encapsulated by the StcObsDataLocation. -* ncoords -* Number of KeyMap pointers supplied in "coords". Can be zero. -* Ignored if "coords" is NULL. -* coords -* Pointer to an array of "ncoords" KeyMap pointers, or NULL if -* "ncoords" is zero. Each KeyMap defines defines a single -* element, and should have elements with keys given by constants -* AST__STCNAME, AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. These elements hold values for the corresponding -* components of the STC AstroCoords element. Any of these elements may -* be omitted, but no other elements should be included. All supplied -* elements should be vector elements, with vector length less than or -* equal to the number of axes in the supplied Region. The data type of -* all elements should be "double", except for AST__STCNAME which should -* be "character string". If no value is available for a given axis, then -* AST__BAD (or NULL for the AST__STCNAME element) should be stored in -* the vector at the index corresponding to the axis (trailing axes -* can be omitted completely from the KeyMap). - -* Returned Value: -* A pointer to the new StcObsDataLocation. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstStcObsDataLocation *new; /* Pointer to new StcObsDataLocation */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitStcObsDataLocationVtab( vtab, name ); - -/* Initialise a Stc structure (the parent class) as the first component - within the StcObsDataLocation structure, allocating memory if necessary. */ - new = (AstStcObsDataLocation *) astInitStc( mem, size, 0, (AstStcVtab *) vtab, - name, region, ncoords, coords ); - -/* If succesful, initialise properties of the StcObsDataLocation. */ - if( new ) { - new->obs = NULL; - } - -/* If an error occurred, clean up by deleting the new StcObsDataLocation. */ - if ( !astOK ) new = astDelete( new ); - -/* Return a pointer to the new StcObsDataLocation. */ - return new; -} - -AstStcObsDataLocation *astLoadStcObsDataLocation_( void *mem, size_t size, AstStcObsDataLocationVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadStcObsDataLocation - -* Purpose: -* Load a StcObsDataLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcobsdatalocation.h" -* AstStcObsDataLocation *astLoadStcObsDataLocation( void *mem, size_t size, AstStcObsDataLocationVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* StcObsDataLocation loader. - -* Description: -* This function is provided to load a new StcObsDataLocation using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* StcObsDataLocation structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a StcObsDataLocation at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the StcObsDataLocation is to be -* loaded. This must be of sufficient size to accommodate the -* StcObsDataLocation data (sizeof(StcObsDataLocation)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the StcObsDataLocation (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the StcObsDataLocation structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstStcObsDataLocation) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new StcObsDataLocation. If this is NULL, a pointer -* to the (static) virtual function table for the StcObsDataLocation class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "StcObsDataLocation" is used instead. - -* Returned Value: -* A pointer to the new StcObsDataLocation. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstStcObsDataLocation *new; /* Pointer to the new StcObsDataLocation */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this StcObsDataLocation. In this case the - StcObsDataLocation belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstStcObsDataLocation ); - vtab = &class_vtab; - name = "StcObsDataLocation"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitStcObsDataLocationVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built StcObsDataLocation. */ - new = astLoadStc( mem, size, (AstStcVtab *) vtab, name, channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "StcObsDataLocation" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Observatory position. */ -/* --------------------- */ - new->obs = astReadObject( channel, "obsloc", NULL ); - -/* If an error occurred, clean up by deleting the new StcObsDataLocation. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new StcObsDataLocation pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astStcSetObs_( AstStcObsDataLocation *this, AstPointList *obs, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,StcObsDataLocation,StcSetObs))( this, obs, status ); -} - - - - diff --git a/ast/stcobsdatalocation.h b/ast/stcobsdatalocation.h deleted file mode 100644 index ad3b793..0000000 --- a/ast/stcobsdatalocation.h +++ /dev/null @@ -1,236 +0,0 @@ -#if !defined( STCOBSDATALOCATION_INCLUDED ) /* Include this file only once */ -#define STCOBSDATALOCATION_INCLUDED -/* -*+ -* Name: -* stcobsdatalocation.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the StcObsDataLocation class. - -* Invocation: -* #include "stcobsdatalocation.h" - -* Description: -* This include file defines the interface to the StcObsDataLocation class -* and provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The StcObsDataLocation class is a sub-class of Stc used to describe -* the an observation contained in some VO resource. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Inheritance: -* The StcObsDataLocation class inherits from the Stc class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 25-APR-2005 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "stc.h" /* Coordinate stcs (parent class) */ -#include "pointlist.h" /* Points within coordinate systems */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* StcObsDataLocation structure. */ -/* ----------------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstStcObsDataLocation { - -/* Attributes inherited from the parent class. */ - AstStc stc; /* Parent class structure */ - -/* Attributes specific to the StcObsDataLOcation class. */ - AstPointList *obs; /* Observatory position */ - -} AstStcObsDataLocation; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstStcObsDataLocationVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstStcVtab stc_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* StcSetObs)( AstStcObsDataLocation *, AstPointList *, int * ); - -} AstStcObsDataLocationVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstStcObsDataLocationGlobals { - AstStcObsDataLocationVtab Class_Vtab; - int Class_Init; -} AstStcObsDataLocationGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitStcObsDataLocationGlobals_( AstStcObsDataLocationGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(StcObsDataLocation) /* Check class membership */ -astPROTO_ISA(StcObsDataLocation) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstStcObsDataLocation *astStcObsDataLocation_( void *, int, AstKeyMap **, const char *, int *, ...); -#else -AstStcObsDataLocation *astStcObsDataLocationId_( void *, int, AstKeyMap **, const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstStcObsDataLocation *astInitStcObsDataLocation_( void *, size_t, int, AstStcObsDataLocationVtab *, const char *, AstRegion *, int, AstKeyMap **, int * ); - -/* Vtab initialiser. */ -void astInitStcObsDataLocationVtab_( AstStcObsDataLocationVtab *, const char *, int * ); - -/* Loader. */ -AstStcObsDataLocation *astLoadStcObsDataLocation_( void *, size_t, AstStcObsDataLocationVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - - -#if defined(astCLASS) /* Protected */ -void astStcSetObs_( AstStcObsDataLocation *, AstPointList *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckStcObsDataLocation(this) astINVOKE_CHECK(StcObsDataLocation,this,0) -#define astVerifyStcObsDataLocation(this) astINVOKE_CHECK(StcObsDataLocation,this,1) - -/* Test class membership. */ -#define astIsAStcObsDataLocation(this) astINVOKE_ISA(StcObsDataLocation,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astStcObsDataLocation astINVOKE(F,astStcObsDataLocation_) -#else -#define astStcObsDataLocation astINVOKE(F,astStcObsDataLocationId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitStcObsDataLocation(mem,size,init,vtab,name,region,ncoords,coords) \ -astINVOKE(O,astInitStcObsDataLocation_(mem,size,init,vtab,name,region,ncoords,coords,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitStcObsDataLocationVtab(vtab,name) astINVOKE(V,astInitStcObsDataLocationVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadStcObsDataLocation(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadStcObsDataLocation_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckStcObsDataLocation to validate StcObsDataLocation pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astStcSetObs(this,obs) \ -astINVOKE(V,astStcSetObs_(astCheckStcObsDataLocation(this),obs?astCheckPointList(obs):NULL,STATUS_PTR)) -#endif -#endif - - - - - diff --git a/ast/stcresourceprofile.c b/ast/stcresourceprofile.c deleted file mode 100644 index 4ae6cc0..0000000 --- a/ast/stcresourceprofile.c +++ /dev/null @@ -1,807 +0,0 @@ -/* -*class++ -* Name: -* StcResourceProfile - -* Purpose: -* Correspond to the IVOA STCResourceProfile class. - -* Constructor Function: -c astStcResourceProfile -f AST_STCRESOURCEPROFILE - -* Description: -* The StcResourceProfile class is a sub-class of Stc used to describe -* the coverage of the datasets contained in some VO resource. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Inheritance: -* The StcResourceProfile class inherits from the Stc class. - -* Attributes: -* The StcResourceProfile class does not define any new attributes beyond -* those which are applicable to all Stcs. - -* Functions: -c The StcResourceProfile class does not define any new functions beyond those -f The StcResourceProfile class does not define any new routines beyond those -* which are applicable to all Stcs. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 26-NOV-2004 (DSB): -* Original version. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS StcResourceProfile - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "stc.h" /* Coordinate stcs (parent class) */ -#include "channel.h" /* I/O channels */ -#include "region.h" /* Regions within coordinate systems */ -#include "stcresourceprofile.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(StcResourceProfile) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(StcResourceProfile,Class_Init) -#define class_vtab astGLOBAL(StcResourceProfile,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstStcResourceProfileVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstStcResourceProfile *astStcResourceProfileId_( void *, int, AstKeyMap **, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static void Dump( AstObject *, AstChannel *, int * ); - -/* Member functions. */ -/* ================= */ - -void astInitStcResourceProfileVtab_( AstStcResourceProfileVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitStcResourceProfileVtab - -* Purpose: -* Initialise a virtual function table for a StcResourceProfile. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcresourceprofile.h" -* void astInitStcResourceProfileVtab( AstStcResourceProfileVtab *vtab, const char *name ) - -* Class Membership: -* StcResourceProfile vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the StcResourceProfile class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstStcVtab *stc; /* Pointer to Stc component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitStcVtab( (AstStcVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAStcResourceProfile) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstStcVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - mapping = (AstMappingVtab *) vtab; - stc = (AstStcVtab *) vtab; - - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDump( vtab, Dump, "StcResourceProfile", "Resource coverage" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -/* None */ - -/* Destructor. */ -/* ----------- */ -/* None */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for StcResourceProfile objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the StcResourceProfile class to an output Channel. - -* Parameters: -* this -* Pointer to the StcResourceProfile whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstStcResourceProfile *this; /* Pointer to the StcResourceProfile structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the StcResourceProfile structure. */ - this = (AstStcResourceProfile *) this_object; - -/* Write out values representing the instance variables for the - StcResourceProfile class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* There are no values to write, so return without further action. */ -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAStcResourceProfile and astCheckStcResourceProfile functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(StcResourceProfile,Stc) -astMAKE_CHECK(StcResourceProfile) - - -AstStcResourceProfile *astStcResourceProfile_( void *region_void, int ncoords, - AstKeyMap **coords, const char *options, int *status, ...) { -/* -*++ -* Name: -c astStcResourceProfile -f AST_STCRESOURCEPROFILE - -* Purpose: -* Create a StcResourceProfile. - -* Type: -* Public function. - -* Synopsis: -c #include "stcresourceprofile.h" -c AstStcResourceProfile *astStcResourceProfile( AstRegion *region, -c int ncoords, AstKeyMap *coords[], const char *options, ... ) -f RESULT = AST_STCRESOURCEPROFILE( REGION, NCOORDS, COORDS, OPTIONS, STATUS ) - -* Class Membership: -* StcResourceProfile constructor. - -* Description: -* This function creates a new StcResourceProfile and optionally initialises its -* attributes. -* -* The StcResourceProfile class is a sub-class of Stc used to describe -* the coverage of the datasets contained in some VO resource. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Parameters: -c region -f REGION = INTEGER (Given) -* Pointer to the encapsulated Region. -c ncoords -f NCOORDS = INTEGER (Given) -c The length of the "coords" array. Supply zero if "coords" is NULL. -f The length of the COORDS array. Supply zero if COORDS should be -f ignored. -c coords -f COORDS( NCOORDS ) = INTEGER (Given) -c Pointer to an array holding "ncoords" AstKeyMap pointers (if "ncoords" -f An array holding NCOORDS AstKeyMap pointers (if NCOORDS -* is zero, the supplied value is ignored). Each supplied KeyMap -* describes the contents of a single STC element, and -* should have elements with keys given by constants AST__STCNAME, -* AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. Any of these elements may be omitted, but no other -* elements should be included. If supplied, the AST__STCNAME element -* should be a vector of character string pointers holding the "Name" -* item for each axis in the coordinate system represented by -c "region". -f REGION. -* Any other supplied elements should be scalar elements, each holding -* a pointer to a Region describing the associated item of ancillary -* information (error, resolution, size, pixel size or value). These -* Regions should describe a volume within the coordinate system -c represented by "region". -f represented by REGION. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new StcResourceProfile. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new StcResourceProfile. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astStcResourceProfile() -f AST_STCRESOURCEPROFILE = INTEGER -* A pointer to the new StcResourceProfile. - -* Notes: -* - A deep copy is taken of the supplied Region. This means that -* any subsequent changes made to the encapsulated Region using the -* supplied pointer will have no effect on the Stc. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstRegion *region; /* Pointer to Region structure */ - AstStcResourceProfile *new; /* Pointer to new StcResourceProfile */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the Region structure provided. */ - region = astCheckRegion( region_void ); - -/* Initialise the StcResourceProfile, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitStcResourceProfile( NULL, sizeof( AstStcResourceProfile ), !class_init, - &class_vtab, "StcResourceProfile", region, - ncoords, coords ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new StcResourceProfile's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new StcResourceProfile. */ - return new; -} - -AstStcResourceProfile *astStcResourceProfileId_( void *region_void, int ncoords, - AstKeyMap **coords, const char *options, ... ) { -/* -* Name: -* astStcResourceProfileId_ - -* Purpose: -* Create a StcResourceProfile. - -* Type: -* Private function. - -* Synopsis: -* #include "stcresourceprofile.h" -* AstStcResourceProfile *astStcResourceProfileId( AstRegion *region, -* int ncoords, AstKeyMap *coords[], const char *options, ... ) - -* Class Membership: -* StcResourceProfile constructor. - -* Description: -* This function implements the external (public) interface to the -* astStcResourceProfile constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astStcResourceProfile_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astStcResourceProfile_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astStcResourceProfile_. - -* Returned Value: -* The ID value associated with the new StcResourceProfile. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstKeyMap **keymaps; /* Pointer to array of KeyMap pointers */ - AstRegion *region; /* Pointer to Region structure */ - AstStcResourceProfile *new; /* Pointer to new StcResourceProfile */ - int icoord; /* Keymap index */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - astGET_GLOBALS(NULL); /* Get a pointer to the thread specific global data structure. */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Region pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Region. */ - region = astVerifyRegion( astMakePointer( region_void ) ); - -/* Obtain pointer from the supplied KeyMap ID's and validate the - pointers to ensure it identifies a valid KeyMap. */ - keymaps = astMalloc( sizeof( AstKeyMap * )*(size_t) ncoords ); - if( keymaps ) { - for( icoord = 0; icoord < ncoords; icoord++ ) { - keymaps[ icoord ] = astVerifyKeyMap( astMakePointer( coords[ icoord ] ) ); - } - } - -/* Initialise the StcResourceProfile, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitStcResourceProfile( NULL, sizeof( AstStcResourceProfile ), !class_init, - &class_vtab, "StcResourceProfile", region, - ncoords, keymaps ); - -/* Free resources. */ - keymaps = astFree( keymaps ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new StcResourceProfile's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new StcResourceProfile. */ - return astMakeId( new ); -} - -AstStcResourceProfile *astInitStcResourceProfile_( void *mem, size_t size, - int init, AstStcResourceProfileVtab *vtab, - const char *name, AstRegion *region, - int ncoords, AstKeyMap **coords, int *status ) { -/* -*+ -* Name: -* astInitStcResourceProfile - -* Purpose: -* Initialise a StcResourceProfile. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcresourceprofile.h" -* AstStcResourceProfile *astInitStcResourceProfile_( void *mem, size_t size, -* int init, AstStcResourceProfileVtab *vtab, -* const char *name, AstRegion *region, -* int ncoords, AstKeyMap **coords ) - -* Class Membership: -* StcResourceProfile initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new StcResourceProfile object. It allocates memory (if necessary) to accommodate -* the StcResourceProfile plus any additional data associated with the derived class. -* It then initialises a StcResourceProfile structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a StcResourceProfile at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the StcResourceProfile is to be initialised. -* This must be of sufficient size to accommodate the StcResourceProfile data -* (sizeof(StcResourceProfile)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the StcResourceProfile (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the StcResourceProfile -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the StcResourceProfile's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new StcResourceProfile. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* region -* A pointer to the Region encapsulated by the StcResourceProfile. -* ncoords -* Number of KeyMap pointers supplied in "coords". Can be zero. -* Ignored if "coords" is NULL. -* coords -* Pointer to an array of "ncoords" KeyMap pointers, or NULL if -* "ncoords" is zero. Each KeyMap defines defines a single -* element, and should have elements with keys given by constants -* AST__STCNAME, AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. These elements hold values for the corresponding -* components of the STC AstroCoords element. Any of these elements may -* be omitted, but no other elements should be included. All supplied -* elements should be vector elements, with vector length less than or -* equal to the number of axes in the supplied Region. The data type of -* all elements should be "double", except for AST__STCNAME which should -* be "character string". If no value is available for a given axis, then -* AST__BAD (or NULL for the AST__STCNAME element) should be stored in -* the vector at the index corresponding to the axis (trailing axes -* can be omitted completely from the KeyMap). - -* Returned Value: -* A pointer to the new StcResourceProfile. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstStcResourceProfile *new; /* Pointer to new StcResourceProfile */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitStcResourceProfileVtab( vtab, name ); - -/* Initialise a Stc structure (the parent class) as the first component - within the StcResourceProfile structure, allocating memory if necessary. */ - new = (AstStcResourceProfile *) astInitStc( mem, size, 0, (AstStcVtab *) vtab, - name, region, ncoords, coords ); - -/* If an error occurred, clean up by deleting the new StcResourceProfile. */ - if ( !astOK ) new = astDelete( new ); - -/* Return a pointer to the new StcResourceProfile. */ - return new; -} - -AstStcResourceProfile *astLoadStcResourceProfile_( void *mem, size_t size, AstStcResourceProfileVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadStcResourceProfile - -* Purpose: -* Load a StcResourceProfile. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcresourceprofile.h" -* AstStcResourceProfile *astLoadStcResourceProfile( void *mem, size_t size, AstStcResourceProfileVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* StcResourceProfile loader. - -* Description: -* This function is provided to load a new StcResourceProfile using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* StcResourceProfile structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a StcResourceProfile at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the StcResourceProfile is to be -* loaded. This must be of sufficient size to accommodate the -* StcResourceProfile data (sizeof(StcResourceProfile)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the StcResourceProfile (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the StcResourceProfile structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstStcResourceProfile) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new StcResourceProfile. If this is NULL, a pointer -* to the (static) virtual function table for the StcResourceProfile class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "StcResourceProfile" is used instead. - -* Returned Value: -* A pointer to the new StcResourceProfile. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstStcResourceProfile *new; /* Pointer to the new StcResourceProfile */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this StcResourceProfile. In this case the - StcResourceProfile belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstStcResourceProfile ); - vtab = &class_vtab; - name = "StcResourceProfile"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitStcResourceProfileVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built StcResourceProfile. */ - new = astLoadStc( mem, size, (AstStcVtab *) vtab, name, channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "StcResourceProfile" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* There are no values to read. */ -/* ---------------------------- */ - -/* If an error occurred, clean up by deleting the new StcResourceProfile. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new StcResourceProfile pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - - diff --git a/ast/stcresourceprofile.h b/ast/stcresourceprofile.h deleted file mode 100644 index 8157dbb..0000000 --- a/ast/stcresourceprofile.h +++ /dev/null @@ -1,223 +0,0 @@ -#if !defined( STCRESOURCEPROFILE_INCLUDED ) /* Include this file only once */ -#define STCRESOURCEPROFILE_INCLUDED -/* -*+ -* Name: -* stcresourceprofile.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the StcResourceProfile class. - -* Invocation: -* #include "stcresourceprofile.h" - -* Description: -* This include file defines the interface to the StcResourceProfile class -* and provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The StcResourceProfile class is a sub-class of Stc used to describe -* the coverage of the datasets contained in some VO resource. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Inheritance: -* The StcResourceProfile class inherits from the Stc class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 26-NOV-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "stc.h" /* Coordinate stcs (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* StcResourceProfile structure. */ -/* ----------------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstStcResourceProfile { - -/* Attributes inherited from the parent class. */ - AstStc stc; /* Parent class structure */ - -} AstStcResourceProfile; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstStcResourceProfileVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstStcVtab stc_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -} AstStcResourceProfileVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstStcResourceProfileGlobals { - AstStcResourceProfileVtab Class_Vtab; - int Class_Init; -} AstStcResourceProfileGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitStcResourceProfileGlobals_( AstStcResourceProfileGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(StcResourceProfile) /* Check class membership */ -astPROTO_ISA(StcResourceProfile) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstStcResourceProfile *astStcResourceProfile_( void *, int, AstKeyMap **, const char *, int *, ...); -#else -AstStcResourceProfile *astStcResourceProfileId_( void *, int, AstKeyMap **, const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstStcResourceProfile *astInitStcResourceProfile_( void *, size_t, int, AstStcResourceProfileVtab *, const char *, AstRegion *, int, AstKeyMap **, int * ); - -/* Vtab initialiser. */ -void astInitStcResourceProfileVtab_( AstStcResourceProfileVtab *, const char *, int * ); - -/* Loader. */ -AstStcResourceProfile *astLoadStcResourceProfile_( void *, size_t, AstStcResourceProfileVtab *, - const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckStcResourceProfile(this) astINVOKE_CHECK(StcResourceProfile,this,0) -#define astVerifyStcResourceProfile(this) astINVOKE_CHECK(StcResourceProfile,this,1) - -/* Test class membership. */ -#define astIsAStcResourceProfile(this) astINVOKE_ISA(StcResourceProfile,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astStcResourceProfile astINVOKE(F,astStcResourceProfile_) -#else -#define astStcResourceProfile astINVOKE(F,astStcResourceProfileId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitStcResourceProfile(mem,size,init,vtab,name,region,ncoords,coords) \ -astINVOKE(O,astInitStcResourceProfile_(mem,size,init,vtab,name,region,ncoords,coords,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitStcResourceProfileVtab(vtab,name) astINVOKE(V,astInitStcResourceProfileVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadStcResourceProfile(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadStcResourceProfile_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckStcResourceProfile to validate StcResourceProfile pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#endif -#endif - - - - - diff --git a/ast/stcs-ex1.txt b/ast/stcs-ex1.txt deleted file mode 100644 index f46fb6a..0000000 --- a/ast/stcs-ex1.txt +++ /dev/null @@ -1,13 +0,0 @@ -TimeInterval TT GEOCENTER -1996-01-01T00:00:00 1996-01-01T00:30:00 -Time MJD 50814.0 Error 1.2 -Resolution 0.8 PixSize 1024.0 -Circle ICRS GEOCENTER 179.0 -11.5 0.5 -Position 179.0 -11.5 Error 0.000889 -Resolution 0.001778 Size 0.000333 0.000278 -PixSize 0.000083 0.000083 -Spectral BARYCENTER 1420.4 unit MHz -Resolution 10.0 -RedshiftInterval BARYCENTER VELOCITY OPTICAL -200.0 2300.0 Redshift 300.0 -Resolution 0.7 PixSize 0.3 diff --git a/ast/stcschan-demo1.c b/ast/stcschan-demo1.c deleted file mode 100644 index 171e78c..0000000 --- a/ast/stcschan-demo1.c +++ /dev/null @@ -1,288 +0,0 @@ -/* Name: - stcschan-demo1.c - - Purpose: - A demonstration of the facilities provided by the AST library - for reading STC metadata encoded using the STC-S linear string - format. - - Description: - This program reads an STC-S description from a disk file, and - tests a given position to see if it is inside or outside the - AstroCoordsArea specified by the STC-S description. - - Usage: - % stcschan-demo1 ... - - : The path to the disk file containing the STC-S - description. - - ...: The axis values at the position to be tested. - If insufficient values are supplied, a message describing the - required values is displayed (label, units, etc). - - Example: - % stcschan-demo1 stcs-ex1.txt 1996-01-01T00:00:15 11:56:00 -11:30:00 \ - 1420.4 1000 - - To compile and link: - Assuming your starlink distribution is in "/star": - - % gcc -o stcschan-demo1 stcschan-demo1.c -L/star/lib \ - -I/star/include `ast_link` -*/ - -/* Include system headers. */ -#include -#include - -/* Include the AST library header. */ -#include "ast.h" - -/* Maximum number of axes in an STC-S AstroCoordSystem. */ -#define MAX_AXES 5 - -/* Maximum allowed length for a single line of text form the disk file. */ -#define MAX_LINE_LEN 500 - -/* Prototype for the function that reads text from the disk file. */ -const char *source( void ); - - -int main( int argc, char **argv ){ - -/* Local variables: */ - AstKeyMap *warnings; - AstObject *object; - AstRegion *region; - AstStcsChan *channel; - FILE *fd; - char attrib[ 9 ]; - char key[ 15 ]; - const char *message; - double inpos[ MAX_AXES ]; - double outpos[ MAX_AXES ]; - int axis; - int iwarn; - int naxis; - int nc; - int status; - -/* Initialised the returned system status to indicate success. */ - status = 0; - -/* Check a file was specified on the command line, and attempt to open it - for read access. */ - if( argc < 2 ) { - printf( "Usage: stcschan-demo1 ...\n" ); - status = 1; - } else { - fd = fopen( argv[ 1 ], "r" ); - if( !fd ) { - printf("Failed to open input file '%s'.\n", argv[ 1 ] ); - status = 1; - } - } - -/* If a disk file was opened successfully... */ - if( !status ) { - -/* Start an AST object context. This means we do not need to annull - each AST Object individually. Instead, all Objects created within - this context will be annulled automatically by the corresponding - invocation of astEnd. */ - astBegin; - -/* Create an StcsChan. This is the object that converts external STC-S - descriptions into corresponding AST Objects. Tell it to use the - "source" function for obtaining lines of text from the disk file. Also - tell it to store all warnings generated by the conversion for later - use. Other attributes of the StcsChan class retain their default - values. */ - channel = astStcsChan( source, NULL, "ReportLevel=3" ); - -/* Associate the descriptor for the input disk file with the StcsChan. - This makes it available to the "source" function. Since this - application is single threaded, we could instead have made "fd" a - global variable, but the ChannelData facility is used here to illustrate - how to pass data to a source or sink function safely in a multi-threaded - application. */ - astPutChannelData( channel, fd ); - -/* The default behaviour of the astRead function when used on an StcsChan is - to read and return the AstroCoordArea as an AST Region. This behaviour - can be changed by assigning appropriate values to the StcsChan attributes - "StcsArea", "StcsCoords" and "StcsProps". Options exist to return the - AstroCoords as an AST PointList, and/or to return the individual - property values read from the STC-S text in the form of an AST KeyMap - (a sort of hashmap). For now, just take the default action of reading the - AstroCoordsArea. */ - object = astRead( channel ); - -/* The astRead function is a generic function and so returns a generic - AstObject pointer. Check an Object was created successfully. */ - if( !object ) { - printf( "Failed to read an AST Object from file '%s'.\n", - argv[ 1 ] ); - status = 1; - -/* Now check that the object read is actually an AST Region, rather than - some other class of AST Object. */ - } else if( !astIsARegion( object ) ) { - printf( "Expected a Region but read a %s from file '%s'.\n", - astGetC( object, "Class" ), argv[ 1 ] ); - status = 1; - -/* We now now know we have a Region so it is safe to use the pointer - returned by astRead as a Region pointer. Do the cast now to avoid - repeated casting in future. */ - } else { - region = (AstRegion *) object; - -/* Get the number of axes in the AstroCoordSystem, and check it is not - larger than expected. */ - naxis = astGetI( region, "Naxes" ); - if( naxis > MAX_AXES ) { - printf( "The coordinate system read from file '%s' has " - "too many axes (%d). Up to %d axes are allowed.\n", - argv[ 1 ], naxis, MAX_AXES ); - status = 1; - -/* Now check that the correct number of axis values were supplied on the - command line. If not, issue a warning message and give details of the - label and units for each axis. Note, AST axis indices are one-based, - in the range 1 to "Naxes". */ - } else if( argc != 2 + naxis ) { - printf( "The coordinate system read from file '%s' has " - "%d axes, but %d axis values were supplied on the " - "command line. ", argv[ 1 ], naxis, argc - 2 ); - - printf( "Values are required for the following axes:\n"); - - for( axis = 1; axis <= naxis; axis++ ) { - sprintf( attrib, "Label(%d)", axis ); - printf( " Axis %d: %s ", axis, astGetC( region, attrib ) ); - sprintf( attrib, "Unit(%d)", axis ); - printf( "(%s)\n", astGetC( region, attrib ) ); - } - - status = 1; - -/* If the correct number of axis values was supplied on the command line, - convert the supplied strings into floating point axis values. Each - class of axis has its own formatting and unformatting rules that are - controlled by various attributes such as "Format" and "Digits". Values - for these attributes could be stored in the Region if different - unformatting conventions were preferred. */ - } else { - - for( axis = 1; axis <= naxis; axis++ ) { - - nc = astUnformat( region, axis, argv[ axis + 1 ], - inpos + axis - 1 ); - - if( nc != strlen( argv[ axis + 1 ] ) ) { - sprintf( attrib, "Label(%d)", axis ); - printf( "Failed to interpret '%s' as a value for axis " - "%d (%s).\n", argv[ axis + 1 ], axis, - astGetC( region, attrib ) ); - status = 1; - break; - } else { - printf("%g ", inpos[ axis - 1 ] ); - } - } - printf("\n"); - } - -/* If we have obtained a full set of floating point axis values, use the - Region as a Mapping to transform the supplied position. When a Region - is used as a Mapping, the transformation leaves all axis values - unchanged for interior positions, but assigns the magic value AST__BAD - to all axes for exterior positions. */ - if( !status ) { - astTranN( region, 1, naxis, 1, inpos, 1, naxis, 1, outpos ); - -/* Issue a message describing the position tested and indicating if it is - inside or outside the AstroCoordsArea. */ - printf( "\nThe position ( %s=%s", astGetC( region, "Symbol(1)" ), - argv[ 2 ] ); - - for( axis = 2; axis <= naxis; axis++ ) { - sprintf( attrib, "Symbol(%d)", axis ); - printf(", %s=%s", astGetC( region, attrib ), argv[ axis + 1 ] ); - } - - printf( " ) is " ); - - if( outpos[ 0 ] == AST__BAD ) { - printf( "OUTSIDE" ); - } else { - printf( "INSIDE" ); - } - - printf( " the region read from file '%s'.\n\n", argv[ 1 ] ); - - } - } - -/* We asked the StcsChan to record any warnings that were generated - whilst converting the STC-S description into a corresponding AST - Object (a Region in this case). We now see if any such warnings were - generated by the earlier call to astRead. */ - warnings = astWarnings( channel ); - -/* If any warnings were generated, and if no other error has occurred so - far, display the warnings. */ - if( warnings && !status && astOK ) { - printf( "\nThe following warnings were issued reading file " - "'%s':\n", argv[ 1 ] ); - -/* The warnings are stored in an AST KeyMap (a sort of hashmap). Each - warning message is associated with a key of the form "Warning_1", - "Warning_2", etc. Loop round successive keys, obtaining a value for - each key from the warnings KeyMap, and displaying it. */ - iwarn = 1; - while( astOK ) { - sprintf( key, "Warning_%d", iwarn++ ); - if( astMapGet0C( warnings, key, &message ) ) { - printf( "\n- %s\n", message ); - } else { - break; - } - } - } - -/* End the AST Object context. All Objects created since the - corresponding invocation of astbegin will be annulled automatically. */ - astEnd; - -/* Close the disk file. */ - (void) fclose( fd ); - } - -/* If an error occurred in the AST library, set the retiurns system - status non-zero. */ - if( !astOK ) status = 1; - return status; -} - - - - - - - -/* This is a function that reads a line of text from the disk file and - returns it to the AST library. It is called from within the astRead - function. */ -const char *source( void ){ - static char buffer[ MAX_LINE_LEN + 2 ]; - FILE *fd = astChannelData; - return fgets( buffer, MAX_LINE_LEN + 2, fd ); -} - - - - - diff --git a/ast/stcschan-demo2.c b/ast/stcschan-demo2.c deleted file mode 100644 index 1967e0b..0000000 --- a/ast/stcschan-demo2.c +++ /dev/null @@ -1,263 +0,0 @@ -/* Name: - stcschan-demo2.c - - Purpose: - A demonstration of the facilities provided by the AST library - for reading STC metadata encoded using the STC-S linear string - format. - - Description: - This program reads a set of FITS-WCS headers from a text file, and - writes an STC-S description of the region covered by the FITS - file to standard output. - - Notes: - - The simple approach used in this demonstration will report an - error if the FITS headers describe a WCS in which some pixels have - invalid WCS axis values (such as most all sky maps, for instance). - - Usage: - % stcschan-demo2 - - : The path to a text file containing a set of FITS-WCS - headers. - - Example: - % stcschan-demo2 m31.head - - To compile and link: - Assuming your starlink distribution is in "/star": - - % gcc -o stcschan-demo2 stcschan-demo2.c -L/star/lib \ - -I/star/include `ast_link` - -*/ - -/* Include system headers. */ -#include -#include - -/* Include the AST library header. */ -#include "ast.h" - -/* Maximum number of axes in an STC-S AstroCoordSystem. */ -#define MAX_AXES 5 - -/* Maximum allowed length for a single line of text from the disk file. */ -#define MAX_LINE_LEN 100 - -/* Prototype for the function that reads text from the disk file. */ -const char *source( void ); - - - -int main( int argc, char **argv ){ - -/* Local variables: */ - AstBox *pixbox; - AstFitsChan *fchan; - AstFrame *pixfrm; - AstFrame *wcsfrm; - AstFrameSet *frameset; - AstKeyMap *warnings; - AstMapping *pix2wcs; - AstObject *object; - AstRegion *wcsbox; - AstStcsChan *schan; - FILE *fd; - char key[ 15 ]; - char keyword[ 9 ]; - const char *message; - double p1[ MAX_AXES ]; - double p2[ MAX_AXES ]; - int axis; - int iwarn; - int naxis; - int status; - -/* Initialised the returned system status to indicate success. */ - status = 0; - -/* Check a file was specified on the command line, and attempt to open it - for read access. */ - if( argc < 2 ) { - printf( "Usage: stcschan-demo2 \n" ); - status = 1; - } else { - fd = fopen( argv[ 1 ], "r" ); - if( !fd ) { - printf("Failed to open input file '%s'.\n", argv[ 1 ] ); - status = 1; - } - } - -/* If a disk file was opened successfully... */ - if( !status ) { - -/* Start an AST object context. This means we do not need to annull - each AST Object individually. Instead, all Objects created within - this context will be annulled automatically by the corresponding - invocation of astEnd. */ - astBegin; - -/* Create a FitsChan. This is the object that converts external FITS - headers into corresponding AST Objects. Tell it to use the "source" - function for obtaining lines of text from the disk file. */ - fchan = astFitsChan( source, NULL, " " ); - -/* Associate the descriptor for the input disk file with the StcsChan. - This makes it available to the "source" function. Since this - application is single threaded, we could instead have made "fd" a - global variable, but the ChannelData facility is used here to illustrate - how to pass data to a source or sink function safely in a multi-threaded - application. */ - astPutChannelData( fchan, fd ); - -/* Attempt to read the FITS heades and convert them into an AST FrameSet. */ - object = astRead( fchan ); - -/* The astRead function is a generic function and so returns a generic - AstObject pointer. Check an Object was created successfully. */ - if( !object ) { - printf( "Failed to read an AST Object from file '%s'.\n", - argv[ 1 ] ); - status = 1; - -/* Now check that the object read is actually an AST FrameSet, rather than - some other class of AST Object. */ - } else if( !astIsAFrameSet( object ) ) { - printf( "Expected a FrameSet but read a %s from file '%s'.\n", - astGetC( object, "Class" ), argv[ 1 ] ); - status = 1; - -/* We now know we have a FrameSet so it is safe to use the pointer - returned by astRead as a FrameSet pointer. Do the cast now to avoid - repeated casting in future. */ - } else { - frameset = (AstFrameSet *) object; - -/* Get a pointer to the Frame that describes the attributes of the FITS - world coordinate system. This is the current Frame in the FrameSet - read from the FITS headers. */ - wcsfrm = astGetFrame( frameset, AST__CURRENT ); - -/* Get a pointer to the Frame that describes the attributes of the FITS - pixel coordinate system. This is the base Frame in the FrameSet - read from the FITS headers. */ - pixfrm = astGetFrame( frameset, AST__BASE ); - -/* Get the Mapping that transforms pixel positions into WCS positions. - The is the Mapping from base to current Frame in the FrameSet read - from the FITS headers. */ - pix2wcs = astGetMapping( frameset, AST__BASE, AST__CURRENT ); - -/* Get the number of axes in ther pixel Frame. */ - naxis = astGetI( pixfrm, "Naxes" ); - -/* For each pixel axis, form the name of the corresponding NAXISi - keyword. */ - for( axis = 0; axis < naxis; axis++ ) { - sprintf( keyword, "NAXIS%d", axis + 1 ); - -/* Store the pixel coordinate on the current axis at the lower left corner - of the first pixel. */ - p1[ axis ] = 0.5; - -/* Get the NAXISi value for the current axis from the FITS header, and - store it in array "p2". Report an error if NAXISi is not found. */ - if( !astGetFitsF( fchan, keyword, p2 + axis ) ){ - printf("Keyword '%s' not found in header\n", keyword ); - status = 1; - break; - -/* If it is found, modify "p2" so that it holds the pixel coordinate on - the current axis at the upper right corner of the last pixel. */ - } else { - p2[ axis ] += 0.5; - } - } - } - -/* If all has gone well, create an AST Region (a Box) describing the - rectangular region of pixel coordinates covered by the pixel array. */ - if( !status ) { - pixbox = astBox( pixfrm, 1, p1, p2, NULL, " " ); - -/* Map this box into the FITS world coordinate system. The Mapping is - specified by "pix2wcs", and the attributes of the resulting axes is - described by "wcsfrm". */ - wcsbox = astMapRegion( pixbox, pix2wcs, wcsfrm ); - -/* Create an StcsChan. This is the object that converts (either way) - between external STC-S descriptions and their corresponding AST Objects. - Tell it to use the "source" function for obtaining lines of text from - the disk file. Also tell it to store all warnings generated by the - conversion for later use. Other attributes of the StcsChan class retain - their default values. */ - schan = astStcsChan( NULL, NULL, "ReportLevel=3" ); - -/* Attempt to write out the Region describing the pixel array (in WCS) - as an STC-S description. Report an error if this fails. */ - if( ! astWrite( schan, wcsbox ) && astOK ) { - printf( "Failed to convert the Region into an STC-S " - "description.\n" ); - } - } - -/* We asked the StcsChan to record any warnings that were generated - whilst converting the AST Region into a corresponding STC-S description. - We now see if any such warnings were generated by the earlier call to - astWrite. */ - warnings = astWarnings( schan ); - -/* If any warnings were generated, and if no other error has occurred so - far, display the warnings. */ - if( warnings && !status && astOK ) { - printf( "\nThe following warnings were issued:\n" ); - -/* The warnings are stored in an AST KeyMap (a sort of hashmap). Each - warning message is associated with a key of the form "Warning_1", - "Warning_2", etc. Loop round successive keys, obtaining a value for - each key from the warnings KeyMap, and displaying it. */ - iwarn = 1; - while( astOK ) { - sprintf( key, "Warning_%d", iwarn++ ); - if( astMapGet0C( warnings, key, &message ) ) { - printf( "\n- %s\n", message ); - } else { - break; - } - } - } - -/* End the AST Object context. All Objects created since the - corresponding invocation of astbegin will be annulled automatically. */ - astEnd; - -/* Close the disk file. */ - (void) fclose( fd ); - } - -/* If an error occurred in the AST library, set the retiurns system - status non-zero. */ - if( !astOK ) status = 1; - return status; -} - - - - - -/* This is a function that reads a line of text from the disk file and - returns it to the AST library. It is called from within the astRead - function. */ -const char *source( void ){ - static char buffer[ MAX_LINE_LEN + 2 ]; - FILE *fd = astChannelData; - return fgets( buffer, MAX_LINE_LEN + 2, fd ); -} - - - - - diff --git a/ast/stcschan-demo3.c b/ast/stcschan-demo3.c deleted file mode 100644 index b7f4e6f..0000000 --- a/ast/stcschan-demo3.c +++ /dev/null @@ -1,435 +0,0 @@ -/* Name: - stcschan-demo3.c - - Purpose: - A demonstration of the facilities provided by the AST library - for reading STC metadata encoded using the STC-S linear string - format. - - Description: - This program reads an STC-S description from a text file, and also - reads a set of 2-D spatial FITS-WCS headers from another (text) file. - It then opens a specified graphics device, and displays an annotated - coordinate grid covering the region described by the FITS headers. - Finally, it draws the outline of the spatial extent of the STC-S - description over the top of the annotated coordinate grid. - - Usage: - % stcschan-demo3 - - : The path to a text file containing the STC-S - description. - - : The path to a text file containing a set of FITS-WCS - headers. - - : The name of an available PGPLOT graphics device. If not - supplied, the available device names will be listed and the program - will then exit. - - Example: - % stcschan-demo3 m31.stcs andromeda.head /xserve - - To compile and link: - Assuming your starlink distribution is in "/star": - - % gcc -o stcschan-demo3 stcschan-demo3.c -g -L/star/lib \ - -I/star/include `ast_link -pgplot` -lcpgplot - -*/ - -/* Include system headers. */ -#include -#include - -/* Include the PGPLOT header. */ -#include "cpgplot.h" - -/* Include the AST library header. */ -#include "ast.h" - -/* Maximum allowed length for a single line of text from the disk file. */ -#define MAX_LINE_LEN 100 - -/* Prototypes */ -const char *source( void ); -AstFrameSet *ReadFitsHeaders( const char *, int *, int * ); -AstRegion *ReadStcs( const char * ); - - -int main( int argc, char **argv ){ - -/* Local variables: */ - AstBox *pixbox; - AstFrame *pixfrm; - AstFrameSet *align_fs = NULL; - AstFrameSet *fset = NULL; - AstPlot *plot; - AstRegion *reg = NULL; - AstRegion *wcsbox = NULL; - AstRegion *wcsreg = NULL; - const char *dev; - double bbox[ 4 ]; - float gbox[ 4 ]; - int overlap_flag, status, naxis1, naxis2, ibase; - -/* Initialise the returned system status to indicate failure. */ - status = 1; - -/* Start an AST object context. This means we do not need to annull - each AST Object individually. Instead, all Objects created within - this context will be annulled automatically by the corresponding - invocation of astEnd. */ - astBegin; - -/* Check there are enough command line arguments. */ - if( argc < 3 ) { - printf( "Usage: stcschan-demo3 \n" ); - -/* If so, attempt to read the STC-S description, creating a corresponding - AST Region. If this is successful, attempt to read the FITS header file - and create an equivalent AST FrameSet. */ - } else { - reg = ReadStcs( argv[ 1 ] ); - if( reg ) fset = ReadFitsHeaders( argv[ 2 ], &naxis1, &naxis2 ); - } - -/* Check we obtained a Region and a FrameSet successfully. */ - if( reg && fset ){ - -/* Check that we can align the FITS WCS with the spatial axes in the - STC-S description. AST contains various built-in conversions between - standard celestial coordinate system. The necessary conversion will be - identified and used automatically if necessary to achieve alignment. - The returned object "align_fs" is a FrameSet that encapsulates the - the FITS WCS coordinate system, the STC-S spatial coordinate system and - the Mapping between them. A NULL pointer is returned if alignment is - not possible. Note, the astConvert method changes the base Frame in - any supplied FrameSet to indicate which coordinate frame was used for - alignment. So we first note the original base Frame index and then - re-instate it afterwards. */ - ibase = astGetI( fset, "Base" ); - align_fs = astConvert( reg, fset, " " ); - astSetI( fset, "Base", ibase ); - - if( !align_fs ) { - printf( "Could not align the FITS WCS with the spatial axes " - "in the STC-S\n" ); - -/* If alignment was possible, use the alignment FrameSet to create a new - Region representing the same region as the supplied STC-S, but - expressed in the coordinate system of the FITS WCS. The FrameSet class - inherits from both Frame and Mapping, and so the "align_fs" FrameSet can - be used both as the Mapping in this call, and as the Frame. When used - as a Mapping, a FrameSet represents the transformation between its base - and current Frame. When used as a Frame, a FrameSet represents its - current Frame. */ - } else { - wcsreg = astMapRegion( reg, align_fs, align_fs ); - -/* It would be nice to warn the user if the STC-S AstroCoordsArea does - not overlap the FITS grid. To do so we need a Region representing the - FITS grid. Create one now (an AST Box). First store the bounds of the - FITS grid, in pixel coordinates (i.e. a system in which the centre of - the bottom left pixel is at (1.0,1.0) ). */ - bbox[ 0 ] = 0.5; - bbox[ 1 ] = 0.5; - bbox[ 2 ] = (double) naxis1 + 0.5; - bbox[ 3 ] = (double) naxis2 + 0.5; - -/* Get a pointer to the Frame describing the FITS pixel coordinate system - (the base Frame in the FITS FrameSet). */ - pixfrm = astGetFrame( fset, AST__BASE ); - -/* Create a Box that encompasses the required range of axis values within - the pixel coordinate Frame. */ - pixbox = astBox( pixfrm, 1, bbox, bbox + 2, NULL, " " ); - -/* Create another Region that represents the same area, but in the FITS - WCS. */ - wcsbox = astMapRegion( pixbox, fset, fset ); - -/* If the previous step failed, it probably means the FITS header covers - the entire sky, resulting the corners of the pixel grid having invalid - sky positions. So cancel the error and omit the overlap test. */ - if( !wcsbox ) { - astClearStatus; - printf("\nContinuing, but omitting overlap test...\n\n"); - -/* Now see if the Region representing the FITS grid overlaps the region - read from the STC-S description.*/ - } else { - overlap_flag = astOverlap( wcsreg, wcsbox ); - - if( overlap_flag == 1 || overlap_flag == 6 ) { - printf( "\nThere is no overlap between the FITS grid and the " - "STC-S AstroCoordsArea\n\n" ); - - } else if( overlap_flag == 3 || overlap_flag == 5 ) { - printf( "\nThe FITS grid is completely contained within the " - "STC-S AstroCoordsArea\n\n" ); - } - - } - } - } - -/* Check we obtained a FITS-WCS to STC-S Mapping, and that no error has - occurred in AST. */ - if( wcsreg && astOK ){ - -/* Open PGPLOT using the specified device. Prompt the user for a device if - none was supplied on the command line. */ - if( argc < 4 ) { - dev = "?"; - } else { - dev = argv[ 3 ]; - } - if( cpgbeg( 0, dev, 1, 1 ) == 1 ) { - -/* Clear the screen. */ - cpgpage(); - -/* Ensure the graphics window has equal scales on both axes. */ - cpgwnad( 0.0f, 1.0f, 0.0f, 1.0f ); - -/* Find the extent of the graphics window, and store in an array suitable - for passing to the astPlot function. */ - cpgqwin( gbox, gbox + 2, gbox + 1, gbox + 3 ); - -/* Create an AST Plot. This is a special sort of FrameSet in which the - base Frame corresponds to graphics coordinates. All the coordinate - Frames and Mappings read from the FITS-WCS headers are added into the - Plot so that graphics can be drawn in any coordinate system. The extent - of the FITS array in pixel coordinates is mapped onto the extent of the - graphics device as returned above by cpgqwin. The AST library comes with - a driver module that provides primitive drawing functions by calling - appropriate PGFPLOT functions. It is simple to write driver modules - for other graphics systems such as Tcl/Tk, Java/Swing, etc. Set a few - graphics attributes to show the sort of thing that can be done. */ - plot = astPlot( fset, gbox, bbox, "Colour(border)=2,Colour(ticks)=2," - "Colour(axes)=2,Grid=1,Colour(grid)=3," - "Style(grid)=4" ); - -/* Draw a set of annotated coordinate axes labelling the FITS WCS axes. */ - astGrid( plot ); - -/* If there is any overlap (or if the overlap test could not be performed), - add the STC-S Region into the Plot. We use a UnitMap to connect it to - the current Frame (the FITS WCS frame). */ - if( 1 || overlap_flag == 2 || overlap_flag == 4 || !wcsbox ) { - astAddFrame( plot, AST__CURRENT, astUnitMap( 2, " " ), wcsreg ); - -/* Now draw the border round the STC-S Region. A Region is a sub-class of - Mapping and so can be used to transform positions. When a Region is used - as a Mapping, positions that are inside the Region are left unchanged - by the transformation, and positions that are outside the Region are - transformed into "bad" positions (i.e. every axis value has the nmagic - value AST__BAD indicating that the axis value is undefined). The - astBorder method is a generic function that will outline the areas - within the current coordinate Frame of the Plot that correspond to - valid (i.e. non-bad) positions. Set the colour and line thickness first - to emphasise the border. */ - astSet( plot, "Colour(border)=4,Width(border)=8" ); - (void) astBorder( plot ); - } - -/* Set the returned system status to indicate success. */ - status = 0; - -/* Close down PGPLOT. */ - cpgend(); - } - } - -/* End the AST Object context. All Objects created since the - corresponding invocation of astbegin will be annulled automatically. */ - astEnd; - -/* If an error occurred in the AST library, set the returned system - status non-zero. */ - if( !astOK ) status = 1; - return status; -} - - - - - - - -/* ------------------------------------------------------------------- - * This is a function that reads a line of text from the disk file and - * returns it to the AST library. It is called from within the astRead - * function. -*/ - -const char *source( void ){ - static char buffer[ MAX_LINE_LEN + 2 ]; - FILE *fd = astChannelData; - return fgets( buffer, MAX_LINE_LEN + 2, fd ); -} - - - -/* ------------------------------------------------------------------- - * This function reads a set of FITS-WCS headers from a given text file, - * and attempts to convert them into an AST FrameSet. If successful, a - * pointer to the FrameSet is returned. A NULL pointer is returned if - * anything goes wrong, or if the WCS is not 2-dimensional. The values of - * the NAXIS1 and NAXIS2 headers are returned in "*naxis1" and "*naxis2". -*/ - -AstFrameSet *ReadFitsHeaders( const char *file, int *naxis1, int *naxis2 ){ - AstFitsChan *chan; - AstFrameSet *result; - AstObject *object; - FILE *fd; - -/* Initialise the returned pointer to indicate that no FrameSet has yet - been read. */ - result = NULL; - -/* Attempt to open the FITS header file */ - fd = fopen( file, "r" ); - if( !fd ) { - printf("Failed to open FITS header file '%s'.\n", file ); - -/* If successful, create a FitsChan. This is the object that converts - external FITS headers into corresponding AST Objects. Tell it to use - the "source" function for obtaining lines of text from the disk file. */ - } else { - chan = astFitsChan( source, NULL, " " ); - -/* Associate the descriptor for the input disk file with the StcsChan. - This makes it available to the "source" function. Since this - application is single threaded, we could instead have made "fd" a - global variable, but the ChannelData facility is used here to illustrate - how to pass data to a source or sink function safely in a multi-threaded - application. */ - astPutChannelData( chan, fd ); - -/* Attempt to read the FITS heades and convert them into an AST FrameSet. */ - object = astRead( chan ); - -/* The astRead function is a generic function and so returns a generic - AstObject pointer. Check an Object was created successfully. */ - if( !object ) { - printf( "Failed to read an AST Object from FITS header file '%s'.\n", - file ); - -/* Now check that the object read is actually an AST FrameSet, rather than - some other class of AST Object. */ - } else if( !astIsAFrameSet( object ) ) { - printf( "Expected a FrameSet but read a %s from FITS header " - "file '%s'.\n", astGetC( object, "Class" ), file ); - -/* If the Object is a FrameSet, return the FrameSet pointer. */ - } else { - result = (AstFrameSet *) object; - -/* Check the WCS is 2-dimensional. If not, report an error and set the - returned pointer to NULL. The memory used to store the FrameSet will - be released when the current AST object context is ended (by calling - astEnd). */ - if( astGetI( result, "Naxes" ) != 2 ) { - printf( "The FITS WCS is not 2-dimensional.\n"); - result = NULL; - -/* If it is 2-dimensional, get the NAXIS1 and NAXIS2 keyword values. */ - } else { - - if( !astGetFitsI( chan, "NAXIS1", naxis1 ) ){ - printf("Keyword 'NAXIS1' not found in header\n" ); - result = NULL; - } - - if( !astGetFitsI( chan, "NAXIS2", naxis2 ) ){ - printf("Keyword 'NAXIS2' not found in header\n" ); - result = NULL; - } - - } - } - -/* Close the file. */ - fclose( fd ); - } - - return result; -} - - -/* ------------------------------------------------------------------- - * This function reads an STC-S description from a given text file, - * and attempts to convert them into an AST Region. If successful, a - * pointer to the Region is returned. A NULL pointer is returned if - * anything goes wrong. -*/ - -AstRegion *ReadStcs( const char *file ){ - AstStcsChan *chan; - AstRegion *result; - AstObject *object; - FILE *fd; - -/* Initialise the returned pointer to indicate that no Region has yet - been read. */ - result = NULL; - -/* Attempt to open the STC-S file */ - fd = fopen( file, "r" ); - if( !fd ) { - printf("Failed to open STC-S descrption file '%s'.\n", file ); - -/* If successful, create an StcsChan. This is the object that converts - external STC-S descriptions into corresponding AST Objects. Tell it to - use the "source" function for obtaining lines of text from the disk - file. */ - } else { - chan = astStcsChan( source, NULL, " " ); - -/* Associate the descriptor for the input disk file with the StcsChan. - This makes it available to the "source" function. Since this - application is single threaded, we could instead have made "fd" a - global variable, but the ChannelData facility is used here to illustrate - how to pass data to a source or sink function safely in a multi-threaded - application. */ - astPutChannelData( chan, fd ); - -/* The default behaviour of the astRead function when used on an StcsChan is - to read and return the AstroCoordArea as an AST Region. This behaviour - can be changed by assigning appropriate values to the StcsChan attributes - "StcsArea", "StcsCoords" and "StcsProps". Options exist to return the - AstroCoords as an AST PointList, and/or to return the individual - property values read from the STC-S text in the form of an AST KeyMap - (a sort of hashmap). For now, just take the default action of reading the - AstroCoordsArea. */ - object = astRead( chan ); - -/* The astRead function is a generic function and so returns a generic - AstObject pointer. Check an Object was created successfully. */ - if( !object ) { - printf( "Failed to read an AST Object from STC-S description " - "file '%s'.\n", file ); - -/* Now check that the object read is actually an AST Region, rather than - some other class of AST Object. */ - } else if( !astIsARegion( object ) ) { - printf( "Expected a Region but read a %s from STC-S description " - "file '%s'.\n", astGetC( object, "Class" ), file ); - -/* If the Object is a Region, return the Region pointer. */ - } else { - result = (AstRegion *) object; - } - -/* Close the file. */ - fclose( fd ); - } - - return result; -} - - - diff --git a/ast/stcschan-demo4.c b/ast/stcschan-demo4.c deleted file mode 100644 index e45035f..0000000 --- a/ast/stcschan-demo4.c +++ /dev/null @@ -1,262 +0,0 @@ -/* Name: - stcschan-demo4.c - - Purpose: - A demonstration of the facilities provided by the AST library - for reading STC metadata encoded using the STC-S linear string - format. - - Description: - This program reads two STC-S descriptions from two disk files, - and tests them for overlap. The two descriptions need not refer - to the same coordinate system. Built-in conversions within AST - will be used to align them if the coordinate systems differ. - - Usage: - % stcschan-demo4 - - : The path to the disk file containing the first STC-S - description. - - : The path to the disk file containing the second STC-S - description. - - Example: - % stcschan-demo4 stcs-ex1.txt stcs-ex2.txt - - To compile and link: - Assuming your starlink distribution is in "/star": - - % gcc -o stcschan-demo4 stcschan-demo4.c -L/star/lib \ - -I/star/include `ast_link` -*/ - -/* Include system headers. */ -#include -#include - -/* Include the AST library header. */ -#include "ast.h" - -/* Maximum number of axes in an STC-S AstroCoordSystem. */ -#define MAX_AXES 5 - -/* Maximum allowed length for a single line of text form the disk file. */ -#define MAX_LINE_LEN 500 - -/* Prototypes: */ -const char *source( void ); -AstRegion *ReadStcs( AstStcsChan *chan, const char *file, int *status ); - -int main( int argc, char **argv ){ - -/* Local variables: */ - AstRegion *region1; - AstRegion *region2; - AstStcsChan *channel; - int status; - -/* Initialised the returned system status to indicate success. */ - status = 0; - -/* Check two files were specified on the command line. */ - if( argc < 3 ) { - printf( "Usage: stcschan-demo4 \n" ); - status = 1; - } - -/* Start an AST object context. This means we do not need to annull - each AST Object individually. Instead, all Objects created within - this context will be annulled automatically by the corresponding - invocation of astEnd. */ - astBegin; - -/* Create an StcsChan. This is the object that converts between external - STC-S descriptions and the corresponding AST Objects. Tell it to use the - "source" function for obtaining lines of text from the disk file. Also - tell it to store all warnings generated by the conversion for later - use. Other attributes of the StcsChan class retain their default - values. */ - channel = astStcsChan( source, NULL, "ReportLevel=3" ); - -/* Attempt to read the STC-S description from the first file, and produce - a corresponding AST Region object. The conversion is performed by the - StcsChan created above. */ - region1 = ReadStcs( channel, argv[ 1 ], &status ); - -/* Now attempt to read the STC-S description from the second file, - producing a corresponding AST Region object. We re-use the StcsChan - created above. */ - region2 = ReadStcs( channel, argv[ 2 ], &status ); - -/* If we have two Regions, test them for overlap and tell the user the - result of the test. */ - if( region1 && region2 ) { - switch( astOverlap( region1, region2 ) ) { - - case 1: - printf( "\n There is no overlap between the two Regions.\n\n"); - break; - - case 2: - printf( "\n The first Region is completely inside the second Region.\n\n"); - break; - - case 3: - printf( "\n The second Region is completely inside the first Region.\n\n"); - break; - - case 4: - printf( "\n There is partial overlap between the two Regions.\n\n"); - break; - - case 5: - printf( "\n The Regions are identical to within their uncertainties.\n\n"); - break; - - case 6: - printf( "\n The second Region is the exact negation of the first " - "Region to within their uncertainties. \n\n"); - break; - - default: - if( astOK ) printf( "\n Unexpected value returned by astOverlap\n\n" ); - } - } - -/* End the AST Object context. All Objects created since the - corresponding invocation of astbegin will be annulled automatically. */ - astEnd; - -/* If an error occurred in the AST library, set the retiurns system - status non-zero. */ - if( !astOK ) status = 1; - return status; -} - - - - - - - -/* This is a function that reads a line of text from the disk file and - returns it to the AST library. It is called from within the astRead - function. */ -const char *source( void ){ - static char buffer[ MAX_LINE_LEN + 2 ]; - FILE *fd = astChannelData; - return fgets( buffer, MAX_LINE_LEN + 2, fd ); -} - - - - - -/* ------------------------------------------------------------------- - * This function reads an STC-S description from a given text file, - * and attempts to convert them into an AST Region. If successful, a - * pointer to the Region is returned. A NULL pointer is returned if - * anything goes wrong. -*/ - -AstRegion *ReadStcs( AstStcsChan *chan, const char *file, int *status ){ - AstKeyMap *warnings; - AstObject *object; - AstRegion *result; - FILE *fd; - char key[ 15 ]; - const char *message; - int iwarn; - -/* Initialise the returned pointer to indicate that no Region has yet - been read. */ - result = NULL; - -/* If an error has already occurred, return without action. */ - if( *status != 0 ) return result; - -/* Attempt to open the STC-S file */ - fd = fopen( file, "r" ); - if( !fd ) { - printf("Failed to open STC-S descrption file '%s'.\n", file ); - -/* If successful... */ - } else { - -/* Associate the descriptor for the input disk file with the StcsChan. - This makes it available to the "source" function. Since this - application is single threaded, we could instead have made "fd" a - global variable, but the ChannelData facility is used here to illustrate - how to pass data to a source or sink function safely in a multi-threaded - application. */ - astPutChannelData( chan, fd ); - -/* The default behaviour of the astRead function when used on an StcsChan is - to read and return the AstroCoordArea as an AST Region. This behaviour - can be changed by assigning appropriate values to the StcsChan attributes - "StcsArea", "StcsCoords" and "StcsProps". Options exist to return the - AstroCoords as an AST PointList, and/or to return the individual - property values read from the STC-S text in the form of an AST KeyMap - (a sort of hashmap). For now, just take the default action of reading the - AstroCoordsArea. */ - object = astRead( chan ); - -/* The astRead function is a generic function and so returns a generic - AstObject pointer. Check an Object was created successfully. */ - if( !object ) { - printf( "Failed to read an AST Object from STC-S description " - "file '%s'.\n", file ); - -/* Now check that the object read is actually an AST Region, rather than - some other class of AST Object. */ - } else if( !astIsARegion( object ) ) { - printf( "Expected a Region but read a %s from STC-S description " - "file '%s'.\n", astGetC( object, "Class" ), file ); - -/* If the Object is a Region, return the Region pointer. */ - } else { - result = (AstRegion *) object; - } - -/* Close the file. */ - fclose( fd ); - -/* If the StcsChan recorded any warnings that were generated whilst - converting the STC-S description into a corresponding AST Object, - we now display them. First test the ReportLevel attribute value to see - if warnings were recored. */ - if( astGetI( chan, "ReportLevel" ) > 0 ) { - -/* Any warnings recorded during the conversion performed by astRead above - are returned by the astWarnings method, in the form of an AST "KeyMap" - (a type of hash map ). */ - warnings = astWarnings( chan ); - -/* If any warnings were generated, and if no other error has occurred so - far, display the warnings. */ - if( warnings && !status && astOK ) { - printf( "\nThe following warnings were issued reading file " - "'%s':\n", file ); - -/* The warnings are stored in an AST KeyMap (a sort of hashmap). Each - warning message is associated with a key of the form "Warning_1", - "Warning_2", etc. Loop round successive keys, obtaining a value for - each key from the warnings KeyMap, and displaying it. */ - iwarn = 1; - while( astOK ) { - sprintf( key, "Warning_%d", iwarn++ ); - if( astMapGet0C( warnings, key, &message ) ) { - printf( "\n- %s\n", message ); - } else { - break; - } - } - } - } - } - - return result; -} - - diff --git a/ast/stcschan-demo5.c b/ast/stcschan-demo5.c deleted file mode 100644 index 787c9e6..0000000 --- a/ast/stcschan-demo5.c +++ /dev/null @@ -1,300 +0,0 @@ -/* Name: - stcschan-demo5.c - - Purpose: - A demonstration of the facilities provided by the AST library - for reading STC metadata encoded using the STC-S linear string - format. - - Description: - This program reads two STC-S descriptions from two disk files, and - writes a new STC-S description to standard output. The new STC-S - covers the same region as the first STC-S, but expressed in the - coordinate system of the second STC-S. - - Usage: - % stcschan-demo5 - - : The path to the disk file containing the first STC-S - description. - - : The path to the disk file containing the second STC-S - description. - - Example: - % stcschan-demo5 stcs-ex1.txt stcs-ex2.txt - - To compile and link: - Assuming your starlink distribution is in "/star": - - % gcc -o stcschan-demo5 stcschan-demo5.c -L/star/lib \ - -I/star/include `ast_link` -*/ - -/* Include system headers. */ -#include -#include - -/* Include the AST library header. */ -#include "ast.h" - -/* Maximum number of axes in an STC-S AstroCoordSystem. */ -#define MAX_AXES 5 - -/* Maximum allowed length for a single line of text form the disk file. */ -#define MAX_LINE_LEN 500 - -/* Prototypes: */ -const char *source( void ); -AstRegion *ReadStcs( AstStcsChan *chan, const char *file, int *status ); -void ReportWarnings( AstStcsChan *chan, const char *file, int *status ); - -int main( int argc, char **argv ){ - -/* Local variables: */ - AstFrameSet *fs; - AstFrame *frame; - AstMapping *map; - AstRegion *region1; - AstRegion *region2; - AstRegion *region3; - AstStcsChan *channel; - int status; - -/* Initialised the returned system status to indicate success. */ - status = 0; - -/* Check two files were specified on the command line. */ - if( argc < 3 ) { - printf( "Usage: stcschan-demo5 \n" ); - status = 1; - } - -/* Start an AST object context. This means we do not need to annull - each AST Object individually. Instead, all Objects created within - this context will be annulled automatically by the corresponding - invocation of astEnd. */ - astBegin; - -/* Create an StcsChan. This is the object that converts between external - STC-S descriptions and the corresponding AST Objects. Tell it to use the - "source" function for obtaining lines of text from the disk file. We - supply a NULL pointer for the "sink" function so that objects written out - through the channel will appear on standard output. Also tell it to - store all warnings generated by the conversion for later use. Other - attributes of the StcsChan class retain their default values. */ - channel = astStcsChan( source, NULL, "ReportLevel=3" ); - -/* Attempt to read the STC-S description from the first file, and produce - a corresponding AST Region object. The conversion is performed by the - StcsChan created above. */ - region1 = ReadStcs( channel, argv[ 1 ], &status ); - -/* Now attempt to read the STC-S description from the second file, - producing a corresponding AST Region object. We re-use the StcsChan - created above. */ - region2 = ReadStcs( channel, argv[ 2 ], &status ); - -/* If we have two Regions, get the mapping from the coordinate system of - the first Region to the coordinate system of the second Region. If - successful, this returns a FrameSet object that encapsulates both the - Mapping and the two coordinate Frames. */ - if( region1 && region2 ) { - fs = astConvert( region1, region2, "" ); - -/* Issue a warning if the conversion cannot be done. */ - if( ! fs ) { - printf( "Cannot determine the transformation from the first " - "coordinate system to the second coordinate system\n"); - status = 1; - -/* Otherwise, extract the Mapping from the FrameSet, and then extract the - Frame that describes the required coordinate system (it will be the - current Frame in the FrameSet). */ - } else { - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - frame = astGetFrame( fs, AST__CURRENT ); - -/* Create a new Region my mapping the first supplied Region using the - above Mapping. Also supply the above Frame to indicate the nature of - the axis values produced by the Mapping (the new Region will be - defined within this Frame). */ - region3 = astMapRegion( region1, map, frame ); - -/* Attempt to write out this new Region as an STC-S description. Report an - error if this fails. The channel writes text to standard output - because no "sink" function was supplied when it was created above. */ - if( ! astWrite( channel, region3 ) && astOK ) { - printf( "Failed to convert the new Region into an STC-S " - "description.\n" ); - -/* Report any warnings that were generated during the conversion to - STC-S. */ - } else { - ReportWarnings( channel, NULL, &status ); - } - } - } - -/* End the AST Object context. All Objects created since the - corresponding invocation of astbegin will be annulled automatically. */ - astEnd; - -/* If an error occurred in the AST library, set the retiurns system - status non-zero. */ - if( !astOK ) status = 1; - return status; -} - - - - - - - -/* This is a function that reads a line of text from the disk file and - returns it to the AST library. It is called from within the astRead - function. */ -const char *source( void ){ - static char buffer[ MAX_LINE_LEN + 2 ]; - FILE *fd = astChannelData; - return fgets( buffer, MAX_LINE_LEN + 2, fd ); -} - - - - - -/* ------------------------------------------------------------------- - * This function reads an STC-S description from a given text file, - * and attempts to convert them into an AST Region. If successful, a - * pointer to the Region is returned. A NULL pointer is returned if - * anything goes wrong. -*/ - -AstRegion *ReadStcs( AstStcsChan *chan, const char *file, int *status ){ - AstObject *object; - AstRegion *result; - FILE *fd; - -/* Initialise the returned pointer to indicate that no Region has yet - been read. */ - result = NULL; - -/* If an error has already occurred, return without action. */ - if( *status != 0 ) return result; - -/* Attempt to open the STC-S file */ - fd = fopen( file, "r" ); - if( !fd ) { - printf("Failed to open STC-S descrption file '%s'.\n", file ); - -/* If successful... */ - } else { - -/* Associate the descriptor for the input disk file with the StcsChan. - This makes it available to the "source" function. Since this - application is single threaded, we could instead have made "fd" a - global variable, but the ChannelData facility is used here to illustrate - how to pass data to a source or sink function safely in a multi-threaded - application. */ - astPutChannelData( chan, fd ); - -/* The default behaviour of the astRead function when used on an StcsChan is - to read and return the AstroCoordArea as an AST Region. This behaviour - can be changed by assigning appropriate values to the StcsChan attributes - "StcsArea", "StcsCoords" and "StcsProps". Options exist to return the - AstroCoords as an AST PointList, and/or to return the individual - property values read from the STC-S text in the form of an AST KeyMap - (a sort of hashmap). For now, just take the default action of reading the - AstroCoordsArea. */ - object = astRead( chan ); - -/* The astRead function is a generic function and so returns a generic - AstObject pointer. Check an Object was created successfully. */ - if( !object ) { - printf( "Failed to read an AST Object from STC-S description " - "file '%s'.\n", file ); - -/* Now check that the object read is actually an AST Region, rather than - some other class of AST Object. */ - } else if( !astIsARegion( object ) ) { - printf( "Expected a Region but read a %s from STC-S description " - "file '%s'.\n", astGetC( object, "Class" ), file ); - -/* If the Object is a Region, return the Region pointer. */ - } else { - result = (AstRegion *) object; - } - -/* Close the file. */ - fclose( fd ); - -/* If the StcsChan recorded any warnings that were generated whilst - converting the STC-S description into a corresponding AST Object, - we now display them. */ - ReportWarnings( chan, file, status ); - } - - return result; -} - -/* ------------------------------------------------------------------- - * This function extracts any warnings stored in the supplied Channel as - * a result of he previous read or write operation, and displays them on - * standard output. -*/ - -void ReportWarnings( AstStcsChan *chan, const char *file, int *status ){ - AstKeyMap *warnings; - char key[ 15 ]; - const char *message; - int iwarn; - -/* If an error has already occurred, return without action. */ - if( *status != 0 ) return; - -/* If the StcsChan records any warnings that are generated whilst - converting between STC-S descriptions and corresponding AST Objects, - display them. First test the ReportLevel attribute value to see - if warnings were recored. */ - if( astGetI( chan, "ReportLevel" ) > 0 ) { - -/* Any warnings recorded during the conversion performed by the previous - invocation of astRead or astWrite are returned by the astWarnings method, - in the form of an AST "KeyMap" (a type of hash map ). */ - warnings = astWarnings( chan ); - -/* If any warnings were generated, and if no other error has occurred so - far, display the warnings. */ - if( warnings && !status && astOK ) { - -/* Indicate the context to the user. Assume we were reading an STC-S - description if "file" was supplied, and writing an STC-S desciprion - otherwise. */ - if( file ) { - printf( "\nThe following warnings were issued reading file " - "'%s':\n", file ); - } else { - printf( "\nThe following warnings were issued converting an " - "AST Region into an STC-S description:\n" ); - } - -/* The warnings are stored in an AST KeyMap (a sort of hashmap). Each - warning message is associated with a key of the form "Warning_1", - "Warning_2", etc. Loop round successive keys, obtaining a value for - each key from the warnings KeyMap, and displaying it. */ - iwarn = 1; - while( astOK ) { - sprintf( key, "Warning_%d", iwarn++ ); - if( astMapGet0C( warnings, key, &message ) ) { - printf( "\n- %s\n", message ); - } else { - break; - } - } - } - } -} - - diff --git a/ast/stcschan.c b/ast/stcschan.c deleted file mode 100644 index 4b43524..0000000 --- a/ast/stcschan.c +++ /dev/null @@ -1,8732 +0,0 @@ -/* -*class++ -* Name: -* StcsChan - -* Purpose: -* I/O Channel using STC-S to represent Objects. - -* Constructor Function: -c astStcsChan -f AST_STCSCHAN - -* Description: -* A StcsChan is a specialised form of Channel which supports STC-S -* I/O operations. Writing an Object to an StcsChan (using -c astWrite) will, if the Object is suitable, generate an -f AST_WRITE) will, if the Object is suitable, generate an -* STC-S description of that Object, and reading from an StcsChan will -* create a new Object from its STC-S description. -* -* When an STC-S description is read using -c astRead, -f AST_READ, -* the returned AST Object may be 1) a PointList describing the STC -* AstroCoords (i.e. a single point of interest within the coordinate frame -* described by the STC-S description), or 2) a Region describing the STC -* AstrCoordsArea (i.e. an area or volume of interest within the coordinate -* frame described by the STC-S description), or 3) a KeyMap -* containing the uninterpreted property values read form the STC-S -* description, or 4) a KeyMap containing any combination of the first -* 3 options. The attributes StcsArea, StcsCoords and StcsProps -* control which of the above is returned by -c astRead. -f AST_READ. -* -* When an STC-S description is created from an AST Object using -c astWrite, -f AST_WRITE, -* the AST Object must be either a Region or a KeyMap. If it is a -* Region, it is assumed to define the AstroCoordsArea or (if the -* Region is a single point) the AstroCoords to write to the STC-S -* description. If the Object is a KeyMap, it may contain an entry -* with the key "AREA", holding a Region to be used to define the -* AstroCoordsArea. It may also contain an entry with the key "COORDS", -* holding a Region (a PointList) to be used to create the -* AstroCoords. It may also contain an entry with key "PROPS", holding -* a KeyMap that contains uninterpreted property values to be used as -* defaults for any STC-S properties that are not determined by the -* other supplied Regions. In addition, a KeyMap supplied to -c astWrite -f AST_WRITE -* may itself hold the default STC-S properties (rather than defaults -* being held in a secondary KeyMap, stored as the "PROPS" entry in the -* supplied KeyMap). -* -* The -c astRead and astWrite -f AST_READ and AST_WRITE -* functions work together so that any Object returned by -c astRead can immediately be re-written using astWrite. -f AST_READ can immediately be re-written using AST_WRITE. -* -* Normally, when you use an StcsChan, you should provide "source" -c and "sink" functions which connect it to an external data store -c by reading and writing the resulting text. These functions -f and "sink" routines which connect it to an external data store -f by reading and writing the resulting text. These routines -* should perform any conversions needed between external character -c encodings and the internal ASCII encoding. If no such functions -f encodings and the internal ASCII encoding. If no such routines -* are supplied, a Channel will read from standard input and write -* to standard output. -* -* Alternatively, an XmlChan can be told to read or write from -* specific text files using the SinkFile and SourceFile attributes, -* in which case no sink or source function need be supplied. -* -* Support for STC-S is currently based on the IVOA document "STC-S: -* Space-Time Coordinate (STC) Metadata Linear String Implementation", -* version 1.30 (dated 5th December 2007), available at -* http://www.ivoa.net/Documents/latest/STC-S.html. Note, this -* document is a recommednation only and does not constitute an accepted -* IVOA standard. -* -* The full text of version 1.30 is supported by the StcsChan class, -* with the following exceptions and provisos: -* -* - When reading an STC-S phrase, case is ignored except when reading -* units strings. -* - There is no support for multiple intervals specified within a -* TimeInterval, PositionInterval, SpectralInterval or RedshiftInterval. -* - If the ET timescale is specified, TT is used instead. -* - If the TEB timescale is specified, TDB is used instead. -* - The LOCAL timescale is not supported. -* - The AST TimeFrame and SkyFrame classes do not currently allow a -* reference position to be specified. Consequently, any -* specified within the Time or Space sub-phrase of an STC-S document -* is ignored. -* - The Convex identifier for the space sub-phrase is not supported. -* - The GEO_C and GEO_D space frames are not supported. -* - The UNITSPHERE and SPHER3 space flavours are not supported. -* - If any Error values are supplied in a space sub-phrase, then the -* number of values supplied should equal the number of spatial axes, -* and the values are assumed to specify an error box (i.e. error -* circles, ellipses, etc, are not supported). -* - The spectral and redshift sub-phrases do not support the -* following values: LOCAL_GROUP_CENTER, UNKNOWNRefPos, -* EMBARYCENTER, MOON, MERCURY, VENUS, MARS, JUPITER, SATURN, URANUS, -* NEPTUNE, PLUTO. -* - Error values are supported but error ranges are not. -* - Resolution, PixSize and Size values are ignored. -* - Space velocity sub-phrases are ignored. - -* Inheritance: -* The StcsChan class inherits from the Channel class. - -* Attributes: -* In addition to those attributes common to all Channels, every -* StcsChan also has the following attributes: -* -* - StcsArea: Return the CoordinateArea component after reading an STC-S? -* - StcsCoords: Return the Coordinates component after reading an STC-S? -* - StcsLength: Controls output buffer length -* - StcsProps: Return the STC-S properties after reading an STC-S? - -* Functions: -c The StcsChan class does not define any new functions beyond those -f The StcsChan class does not define any new routines beyond those -* which are applicable to all Channels. - -* Copyright: -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David Berry (Starlink) - -* History: -* 18-DEC-2008 (DSB): -* Original version. -* 22-MAY-2008 (DSB): -* Retain default Equinox values in SkyFrame when reading an STC-S. -* 30-OCT-2009 (DSB): -* Make case insensitive (except for units strings). -* 21-FEB-2014 (DSB): -* Split long properties up into words when writing out an STC-S -* description. -* 26-MAR-2015 (DSB): -* Guard against seg faults if an error has already occured. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS StcsChan - -/* Values identifying particular forms of CoordArea */ -#define NULL_ID 1 -#define TIME_INTERVAL_ID 2 -#define START_TIME_ID 3 -#define STOP_TIME_ID 4 -#define POSITION_INTERVAL_ID 5 -#define ALLSKY_ID 6 -#define CIRCLE_ID 7 -#define ELLIPSE_ID 8 -#define BOX_ID 9 -#define POLYGON_ID 10 -#define CONVEX_ID 11 -#define POSITION_ID 12 -#define TIME_ID 13 -#define SPECTRAL_INTERVAL_ID 14 -#define SPECTRAL_ID 15 -#define REDSHIFT_INTERVAL_ID 16 -#define REDSHIFT_ID 17 -#define VELOCITY_INTERVAL_ID 18 -#define UNION_ID 19 -#define INTERSECTION_ID 20 -#define DIFFERENCE_ID 21 -#define NOT_ID 22 -#define VELOCITY_ID 23 - -/* The number of words used to form an extract from an STC-S description - for use in an error message. */ -#define NEWORD 10 - -/* Max length of string returned by GetAttrib */ -#define GETATTRIB_BUFF_LEN 50 - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "frame.h" /* Generic cartesian coordinate systems */ -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "channel.h" /* Interface for parent class */ -#include "stcschan.h" /* Interface definition for this class */ -#include "loader.h" /* Interface to the global loader */ -#include "skyframe.h" /* Celestial coordinate systems */ -#include "timeframe.h" /* Time coordinate systems */ -#include "specframe.h" /* Spectral coordinate systems */ -#include "wcsmap.h" /* PI-related constants */ -#include "region.h" /* Abstract regions */ -#include "interval.h" /* Axis intervals */ -#include "unitmap.h" /* Unit mappings */ -#include "nullregion.h" /* Boundless regions */ -#include "cmpregion.h" /* Compound regions */ -#include "box.h" /* Box regions */ -#include "prism.h" /* Prism regions */ -#include "circle.h" /* Circle regions */ -#include "ellipse.h" /* Ellipse regions */ -#include "polygon.h" /* Polygon regions */ -#include "pointlist.h" /* Lists of points */ -#include "keymap.h" /* KeyMap interface */ - - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Module Types. */ -/* ============= */ -typedef struct WordContext { - char *line; - char *wnext; - char *e; - char f; - int done; - char *words[ NEWORD ]; - int next; - int close; - int open; -} WordContext; - -/* Module Variables. */ -/* ================= */ - -/* Pointers to parent class methods which are extended by this class. */ -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static int (* parent_getindent)( AstChannel *, int * ); - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(StcsChan) - -/* Define macros for accessing each item of thread specific global data. */ -#define getattrib_buff astGLOBAL(StcsChan,GetAttrib_Buff) -#define class_init astGLOBAL(StcsChan,Class_Init) -#define class_vtab astGLOBAL(StcsChan,Class_Vtab) - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstStcsChanVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ GETATTRIB_BUFF_LEN + 1 ]; - -#endif - - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstStcsChan *astStcsChanForId_( const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), const char *, int * ), - const char *, ... ); -AstStcsChan *astStcsChanId_( const char *(* source)( void ), - void (* sink)( const char * ), - const char *options, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstKeyMap *ReadProps( AstStcsChan *, int * ); -static AstObject *Read( AstChannel *, int * ); -static AstPointList *SinglePointList( AstFrame *, double *, AstRegion *, int *); -static AstRegion *MakeSpaceRegion( AstKeyMap *, AstFrame *, double, int * ); -static char *AddItem( AstStcsChan *, AstKeyMap *, const char *, const char *, char *, int *, int *, int, int * ); -static char *ContextFragment( WordContext *, char **, int * ); -static char *PutRegionProps( AstStcsChan *, AstKeyMap *, const char *, int, char *, int *, int *, int, int * ); -static char *SourceWrap( const char *(*)( void ), int * ); -static const char *GetNextWord( AstStcsChan *, WordContext *, int * ); -static const char *ReadSpaceArgs( AstStcsChan *, const char *, int, int, WordContext *, AstKeyMap *, int * ); -static double *BoxCorners( AstFrame *, const double[2], const double[2], int * ); -static int GetIndent( AstChannel *, int * ); -static int GetRegionProps( AstStcsChan *, AstRegion *, AstKeyMap *, int, int, double, int, int * ); -static int SpaceId( const char *, int * ); -static int Write( AstChannel *, AstObject *, int * ); -static int WriteRegion( AstStcsChan *, AstRegion *, AstKeyMap *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void FreeContext( WordContext *, int * ); -static void GetFmt( const char *, AstKeyMap *, int, int, char *, int * ); -static void MapPut0C( AstKeyMap *, const char *, const char *, const char *, int, int * ); -static void MapPut0D( AstKeyMap *, const char *, double, double, int, int * ); -static void SetUnc( AstRegion *, AstRegion *, AstFrame *, int, double, double *, int, int * ); -static void SinkWrap( void (*)( const char * ), const char *, int * ); -static void WriteProps( AstStcsChan *, AstKeyMap *, int * ); - -static int GetStcsArea( AstStcsChan *, int * ); -static int TestStcsArea( AstStcsChan *, int * ); -static void ClearStcsArea( AstStcsChan *, int * ); -static void SetStcsArea( AstStcsChan *, int, int * ); - -static int GetStcsCoords( AstStcsChan *, int * ); -static int TestStcsCoords( AstStcsChan *, int * ); -static void ClearStcsCoords( AstStcsChan *, int * ); -static void SetStcsCoords( AstStcsChan *, int, int * ); - -static int GetStcsProps( AstStcsChan *, int * ); -static int TestStcsProps( AstStcsChan *, int * ); -static void ClearStcsProps( AstStcsChan *, int * ); -static void SetStcsProps( AstStcsChan *, int, int * ); - -static void ClearAttrib( AstObject *, const char *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); - -static int TestStcsLength( AstStcsChan *, int * ); -static void ClearStcsLength( AstStcsChan *, int * ); -static void SetStcsLength( AstStcsChan *, int, int * ); -static int GetStcsLength( AstStcsChan *, int * ); - -/* Member functions. */ -/* ================= */ - -static char *AddItem( AstStcsChan *this, AstKeyMap *km, const char *key, - const char *prefix, char *line, int *nc, int *crem, - int linelen, int *status ){ -/* -* Name: -* AddItem - -* Purpose: -* Add an STC-S property item to a buffer. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* char *AddItem( AstStcsChan *this, AstKeyMap *km, const char *key, -* const char *prefix, char *line, int *nc, int *crem, -* int linelen, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function appends text describing a singlke STC-S property to -* a supplied text buffer, handling the splitting of text into lines. - -* Parameters: -* this -* The StcsChan. -* km -* Pointer to a KeyMap containing the STC-S properties. -* key -* The key name associated with the property to be checked. -* prefix -* if not NULL, this is a string that is to be written out before -* the property value. It should usually include a trailing space. -* line -* Pointer to the buffer to recieve the prefix and property value. -* nc -* Pointer to an int in which to store the number of characters in -* the buffer. Updated on exit. -* crem -* Pointer to an int in which to store the maximum number of -* characters before a new line. Ignored if linelen is zero. Updated -* on exit. -* linelen -* The maximum number of character per line, or zero if all text is -* to be included in a single line. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the buffer. This will usually be "line", but may be -* different to "line" if it was necessary to expand the memory to make -* room for the new property. - -*/ - -/* Local Variables: */ - char *result; /* Returned pointer */ - char **words; /* All words */ - const char *text; /* Property value */ - const char *word; /* Single word */ - int iw; /* Word index */ - int len; /* Length of new text */ - int nw; /* Number of words in property */ - -/* Initialise */ - result = line; - len = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the KeyMap contains the required property... */ - if( astMapGet0C( km, key, &text ) ) { - -/* Add any supplied prefix to the returned buffer. */ - if( prefix ) { - len = strlen( prefix ); - if( len > *crem && len < linelen ) { - astPutNextText( this, result ); - *nc = 0; - result = astAppendString( result, nc, " " ); - *crem = linelen - 3; - } - result = astAppendString( result, nc, prefix ); - *crem -= len; - } - -/* Split the property into words. */ - words = astChrSplit( text, &nw ); - -/* Append each word to the buffer. */ - for( iw = 0; iw < nw; iw++ ) { - word = words[ iw ]; - -/* If required, get the number of characters to be added to the buffer. */ - if( linelen ) { - len = strlen( word ); - -/* If there is insufficient room left, write out the text through the - Channel sink function, and start a new line with three spaces. Then - reset the number of character remaining in the line. */ - if( len > *crem && len < linelen ) { - astPutNextText( this, result ); - *nc = 0; - result = astAppendString( result, nc, " " ); - *crem = linelen - 3; - } - -/* Reduce crem to account for the text that is about to be added to the - line. */ - *crem -= len; - } - -/* Add the property value to the returned buffer. */ - result = astAppendString( result, nc, word ); - -/* Add a traling space to the returned buffer, if there is room. */ - if( !linelen || *crem > 0 ) { - result = astAppendString( result, nc, " " ); - (*crem)--; - } - } - -/* Free the words buffer. */ - if( words ) { - for( iw = 0; iw < nw; iw++ ) words[ iw ] = astFree( words[ iw ] ); - words = astFree( words ); - } - } - -/* Return the buffer pointer. */ - return result; -} - -static double *BoxCorners( AstFrame *frm, const double centre[2], - const double bsize[2], int *status ) { -/* -* Name: -* BoxCorners - -* Purpose: -* Determine the positions of the corners of an STC Box. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* double *BoxCorners( AstFrame *frm, const double centre[2], -* const double bsize[2], int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function returns a pointer to a dynamically allocated array -* holding the positions of the corners of the STC Box defined by the -* supplied "centre" and "bsize" arrays. - -* Parameters: -* frm -* Pointer to the Frame in which the Box is defined. Must be 2-D. -* centre -* Two element array holding the Frame co-ordinates at the centre -* of the Box. -* bsize -* Two element array holding the full width and height of the Box. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array holding the axis values -* at the four corners, in a form suitable for passing to the -* astPolygon constructor function. NULL is returned if an error has -* already occurred, of if this function fails for any reason. -*/ - -/* Local Variables: */ - double *result; /* Returned pointer. */ - double bh1[ 2 ]; /* A first point on the bottom horizontal edge */ - double bh2[ 2 ]; /* A second point on the bottom horizontal edge */ - double blc[ 2 ]; /* Position of bottom left corner */ - double brc[ 2 ]; /* Position of bottom right corner */ - double lv1[ 2 ]; /* A first point on the left vertical edge */ - double lv2[ 2 ]; /* A second point on the left vertical edge */ - double pa; /* Position angle of great circle/straight line */ - double rv1[ 2 ]; /* A first point on the right vertical edge */ - double rv2[ 2 ]; /* A second point on the right vertical edge */ - double th1[ 2 ]; /* A first point on the top horizontal edge */ - double th2[ 2 ]; /* A second point on the top horizontal edge */ - double tlc[ 2 ]; /* Position of top left corner */ - double trc[ 2 ]; /* Position of top right corner */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check the Frame is 2-dimensional. */ - if( astGetNaxes( frm ) != 2 ) { - astError( AST__BADIN, "astRead(StcsChan): Supplied space frame has " - "%d axes.", status, astGetNaxes( frm ) ); - astError( AST__BADIN, "astRead(StcsChan): Can only use STC Box regions " - "with 2-dimensional space frames.", status ); - } - -/* Offset away from the centre by half the Box width along a great circle - initially parallel to the positive first frame axis (i.e. position - angle +pi/2). The end position goes in "rv1" and the position angle of - the great circle (or straight line) at that point is returned as the - function value. NOTE, the use of the words "left" and "right" below is - vague because it depends on whether we are using a SkyFrame (which has - a reversed first axis) or a basic Frame. In general, the choice of "left" - and "right" below is appropriate for a basic Frame. */ - pa = astOffset2( frm, centre, AST__DPIBY2, bsize[ 0 ]/2, rv1 ); - -/* Turn by 90 degrees and offset away by half the box height. This is done - so that we have a second point (rv2) to define the great circle (or - straight line) that forms the first vertical edge of the Box (i.e. the - great circle or straight line through rv1 and rv2). Note, for spherical - Frames (i.e. SkyFrames) "rv2" is not necessarily a corner of the box. */ - (void) astOffset2( frm, rv1, pa + AST__DPIBY2, bsize[ 1 ]/2, rv2 ); - -/* In the same way, get two points on the second vertical Box edge. */ - pa = astOffset2( frm, centre, -AST__DPIBY2, bsize[ 0 ]/2, lv1 ); - (void) astOffset2( frm, lv1, pa + AST__DPIBY2, bsize[ 1 ]/2, lv2 ); - -/* In the same way, get two points on the top horizontal Box edge. */ - pa = astOffset2( frm, centre, 0.0, bsize[ 1 ]/2, th1 ); - (void) astOffset2( frm, th1, pa + AST__DPIBY2, bsize[ 0 ]/2, th2 ); - -/* In the same way, get two points on the bottom horizontal Box edge. */ - pa = astOffset2( frm, centre, AST__DPI, bsize[ 1 ]/2, bh1 ); - (void) astOffset2( frm, bh1, pa + AST__DPIBY2, bsize[ 0 ]/2, bh2 ); - -/* The first corner of the Box is at the intersection of the first - vertical and top horizontal edges. */ - astIntersect( frm, lv1, lv2, th1, th2, tlc ); - -/* The top right corner of the Box is at the intersection of the right - vertical and top horizontal edges. */ - astIntersect( frm, rv1, rv2, th1, th2, trc ); - -/* The bottom left corner of the Box is at the intersection of the left - vertical and bottom horizontal edges. */ - astIntersect( frm, lv1, lv2, bh1, bh2, blc ); - -/* The bottom right corner of the Box is at the intersection of the right - vertical and bottom horizontal edges. */ - astIntersect( frm, rv1, rv2, bh1, bh2, brc ); - -/* Gather the corners together into an array suitable for use with - astPolygon. Make sure the vertices are traversed in an ant-clockwise - sense whether in a SkyFrame or a basic Frame. */ - result = astMalloc( 8*sizeof( *result ) ); - if( result ) { - if( astIsASkyFrame( frm ) ) { - result[ 0 ] = tlc[ 0 ]; - result[ 1 ] = trc[ 0 ]; - result[ 2 ] = brc[ 0 ]; - result[ 3 ] = blc[ 0 ]; - result[ 4 ] = tlc[ 1 ]; - result[ 5 ] = trc[ 1 ]; - result[ 6 ] = brc[ 1 ]; - result[ 7 ] = blc[ 1 ]; - } else { - result[ 3 ] = tlc[ 0 ]; - result[ 2 ] = trc[ 0 ]; - result[ 1 ] = brc[ 0 ]; - result[ 0 ] = blc[ 0 ]; - result[ 7 ] = tlc[ 1 ]; - result[ 6 ] = trc[ 1 ]; - result[ 5 ] = brc[ 1 ]; - result[ 4 ] = blc[ 1 ]; - } - - } - -/* Return the pointer. */ - return result; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a StcsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* StcsChan member function (over-rides the astClearAttrib protected -* method inherited from the Channel class). - -* Description: -* This function clears the value of a specified attribute for a -* StcsChan, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the StcsChan. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstStcsChan *this; /* Pointer to the StcsChan structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the StcsChan structure. */ - this = (AstStcsChan *) this_object; - -/* Check the attribute name and clear the appropriate attribute. */ - - if ( !strcmp( attrib, "stcsarea" ) ) { - astClearStcsArea( this ); - - } else if ( !strcmp( attrib, "stcscoords" ) ) { - astClearStcsCoords( this ); - - } else if ( !strcmp( attrib, "stcsprop" ) ) { - astClearStcsProps( this ); - - } else if ( !strcmp( attrib, "stcslength" ) ) { - astClearStcsLength( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static char *ContextFragment( WordContext *con, char **buf, int *status ){ -/* -* Name: -* ContextFragment - -* Purpose: -* Returns a string holding a fragment of the document being read. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* char *ContextFragment( WordContext *con, char **buf, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function returns a pointer to a string that holds a fragment -* of the STC-S document currently being read. The fragment ends at -* the last word read by function GetNextWord, and starts a certain -* number of words earlier in the document, as specified by the NEWORD -* macro. - -* Parameters: -* con -* Pointer to the context structure, managed by GetNextWord. -* buf -* Address of a pointer to a dynamically allocated buffer. This -* pointer should be NULL on the first call to this function, and -* will be updated by this function. The pointer should be freed -* using astFree when no longer needed. -* status -* Address of the inherited status value. - -* Returned Value: -* A pointer to the buffer. -*/ - -/* Local Variables: */ - int i; /* Word count */ - int j; /* Word index */ - int nc; /* Text length */ - -/* Initialise the number of characters written to the buffer. */ - nc = 0; - -/* Get the index of the first word to add to the buffer. The "next" - component of the context structure holds the index at which the word - returned by the next call to GetNextWord will be stored. So at the - moment, this is the index of the oldest word in the cyclic list. */ - j = con->next; - -/* Loop round all non-NULL words in the cyclic list. */ - for( i = 0; i < NEWORD; i++ ) { - if( con->words[ j ] ) { - -/* Append this word to the buffer, extending the buffer size as - necessary. */ - *buf = astAppendString( *buf, &nc, con->words[ j ] ); - -/* Append a trailingh space. */ - *buf = astAppendString( *buf, &nc, " " ); - } - -/* Increment the index of the next word to use in the cyclic list. Wrap - back to zerp when the end of the list is reached. */ - if( ++j == NEWORD ) j = 0; - } - -/* Remove the final trailing space. */ - if( nc ) (*buf)[ nc - 1 ] = 0; - -/* Return a pointer to the supplied buffer. */ - return *buf; -} - -static void FreeContext( WordContext *con, int *status ){ -/* -* Name: -* FreeContext - -* Purpose: -* Free the resources used by a word-reading context structure. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* voidFreeContext( WordContext *con, int *status ); - -* Class Membership: -* StcsChan member function - -* Description: -* This function frees the resources used by the supplied WordContext -* structure. This structure is used by GetNextWord to keep track of -* which word to return next. -* -* This function frees the dynamic memory pointers stored within the -* WordContext structure, but does not free the memory holding the -* WordContext structure itself. - -* Parameters: -* con -* Pointer to a structure holding the context. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int i; /* Word index */ - -/* Check the supplied pointer. */ - if ( !con ) return; - -/* Free the resources. */ - con->line = astFree( con->line ); - - for( i = 0; i < NEWORD; i++ ) { - con->words[ i ] = astFree( con->words[ i ] ); - } - -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a StcsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* StcsChan member function (over-rides the protected astGetAttrib -* method inherited from the Channel class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a StcsChan, formatted as a character string. - -* Parameters: -* this -* Pointer to the StcsChan. -* attrib -* Pointer to a null terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the StcsChan, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the StcsChan. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstStcsChan *this; /* Pointer to the StcsChan structure */ - const char *result; /* Pointer value to return */ - int ival; /* Integer attribute value */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the StcsChan structure. */ - this = (AstStcsChan *) this_object; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* StcsArea. */ -/* --------- */ - if ( !strcmp( attrib, "stcsarea" ) ) { - ival = astGetStcsArea( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* StcsCoords. */ -/* ----------- */ - } else if ( !strcmp( attrib, "stcscoords" ) ) { - ival = astGetStcsCoords( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - - -/* StcsProps. */ -/* ---------- */ - } else if ( !strcmp( attrib, "stcsprops" ) ) { - ival = astGetStcsProps( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* StcsLength */ -/* --------- */ - } else if ( !strcmp( attrib, "stcslength" ) ) { - ival = astGetStcsLength( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; - -} - -static void GetFmt( const char *key, AstKeyMap *props, int i, int defdigs, - char *fmt, int *status ){ -/* -* Name: -* GetFmt - -* Purpose: -* Decide how many digits to use when formatting a numerical STC-S -* property value. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* void GetFmt( const char *key, AstKeyMap *props, int i, -* int defdigs, char *fmt, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function locates the named property in the supplied KeyMap. If -* it is found, a printf format specifier is generated that matches -* the value is determined and returned. Otherwise, a default format -* specified based on the supplied default number of digits is returned. - -* Parameters: -* key -* The key name associated with the property. -* km -* Pointer to a KeyMap containing the STC-S properties. -* i -* For vector values, this is the index of the vector element to be -* checked. Should be zero for scalar values. If "i" is greater -* than the number of values in the vector, then the number of digits -* in the first element is found and returned. -* defdigs -* The value to return if the KeyMap does not contain an entry with -* the supplied key. -* fmt -* Pointer to a string in which to return the format specifier. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - const char *dot; /* Pointer to decimal point */ - const char *p; /* Pointer to next character */ - const char *word; /* Property value */ - int after0; /* Digits after the decimal point in first word */ - int after; /* Digits after the decimal point in current word */ - int before0; /* Digits before the decimal point in first word */ - int before; /* Digits before the decimal point in current word */ - int exp0; /* Was an exponent found in first word? */ - int exp; /* Was an exponent found in current word? */ - int j; /* Index of current word */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise. */ - exp = 1; - before = defdigs; - after = 0; - exp0 = 0; - before0 = 0; - after0 = 0; - -/* If the KeyMap contains the required property... */ - if( astMapGet0C( props, key, &word ) ) { - -/* Skip over the words in the string. */ - p = word; - for( j = 0; j <= i; j++ ) { - -/* Find the next space or terminating null at the end of the current word. - Also count the number of digits before and after the decimal point and - see if the word includes an exponent. */ - exp = 0; - before = 0; - after = 0; - dot = NULL; - - while( *p != 0 && *p != ' ' ) { - if( ! exp ) { - if( isdigit( *p ) ) { - if( dot ) { - after++; - } else { - before++; - } - - } else if( *p == '.' ) { - dot = p; - - } else if( *p == 'e' || *p == 'E' ) { - exp = 1; - } - } - p++; - } - -/* Note the values for the first word. */ - if( j == 0 ) { - exp0 = exp; - before0 = before; - after0 = after; - } - -/* Find the following non-space marking the start of the next word, - or the terminating null. */ - while( *p != 0 && *p == ' ' ) p++; - -/* If we find the terminating null before we have found the i'th word, - break out of the loop using the first word instead of the i'th word. */ - if( *p == 0 ) { - exp = exp0; - before = before0; - after = after0; - break; - } - } - } - - if( exp ) { - sprintf( fmt, "%%.%dg", before + after ); - } else { - sprintf( fmt, "%%.%df", after ); - } -} - -static int GetIndent( AstChannel *this, int *status ) { -/* -* Name: -* GetIndent - -* Purpose: -* Get the value of the Indent attribute for a StcsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* int GetIndent( AstChannel *this, int *status ) - -* Class Membership: -* StcsChan member function (over-rides the protected astGetIndent -* method inherited from the Channel class). - -* Description: -* This function returns the value of the Indent attribute, supplying -* a default value appropriate to an StcsChan. - -* Parameters: -* this -* Pointer to the StcsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - The Indent value to use. - -*/ - -/* If the attribute is set, return its value. Otherwise return a value of - zero. */ - return astTestIndent( this ) ? (*parent_getindent)( this, status ) : 0; -} - -static const char *GetNextWord( AstStcsChan *this, WordContext *con, - int *status ){ -/* -* Name: -* GetNextWord - -* Purpose: -* Get a pointer to the next input word read from an STC-S source. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* const char *GetNextWord( AstStcsChan *this, WordContext *con, -* int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function returns a pointer to the next word of an STC-S -* description. - -* Parameters: -* this -* Pointer to the StcsChan, or NULL (to initialise "con"). -* con -* Pointer to a structure holding context. The structure should be -* initialised by calling this function with a NULL "this" pointer -* before making further use of this function. When finished, it -* should be released using FreeContext. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new word. NULL is returned if an error has already -* occurred, of if "this" is NULL. -*/ - -/* Local Variables: */ - const char *result; /* Returned pointer. */ - int i; /* Word index */ - size_t len; /* Word length */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If no StcChan was supplied, initialise the supplied WordContext. */ - if( !this ) { - con->e = NULL; - con->line = NULL; - con->done = 0; - con->next = 0; - con->wnext = NULL; - con->close = 0; - con->open = 0; - for( i = 0; i < NEWORD; i++ ) con->words[ i ] = NULL; - -/* Words that end with an opening parenthesis are treated as two words. If the - previous word ended in an opening parenthesis, it will have been removed by - the previous call to this function and the "con->open" flag set. In - this case, we just return a pointer to the second of the two words - a - single "(" character - and clear the "con->open" flag. */ - } else if( con->open && ! con->done ) { - con->open = 0; - result = "("; - -/* Likewise deal with words that end with a closing parenthesis. */ - } else if( con->close && ! con->done ) { - con->close = 0; - result = ")"; - -/* Words that begin with an opening parenthesis are treated as two words. If - the previous word was such an opening parenthesis, the rest of the word - will have been removed by the previous call to this function and the - "con->wnext" pointer set to the start of the remaining word. In - this case, re-instate the original character that was replaced by a - terminating null when the previous word was returned, return the - "con->wnext" pointer, and then clear the pointer. */ - } else if( con->wnext && ! con->done ) { - *(con->wnext) = con->f; - result = con->wnext; - con->wnext = NULL; - -/* Otherwise... */ - } else { - -/* If the previous invocation of this function converted a space - character into a null character, change it back again. */ - if( con->e ) *(con->e) = ' '; - -/* Get a pointer to the next non-white character in the current line of - input text. */ - result = con->e; - if( result ) { - while( *result && isspace( *result ) ) result++; - } - -/* If we have exhausted the current line, get the next line by invoking - the source function. We loop until we read a line that is not entirely - blank. */ - while( ( !result || ! *result ) && astOK ) { - -/* First free the memory holding the previous line. */ - if( con->line ) con->line = astFree( con->line ); - con->e = NULL; - -/* Get the next line of text from the source function. */ - con->line = astGetNextText( this ); - result = con->line; - -/* Break when we reach the end of the input text. */ - if( !result ) break; - -/* Get a pointer to the first non-white character in the new line. */ - while( *result && isspace( *result ) ) result++; - } - -/* Find the end of the word. */ - if( result && *result ) { - con->e = (char *) result + 1; - while( *(con->e) && !isspace( *(con->e) ) ) (con->e)++; - -/* If the word is already null-terminated, nullify the "e" pointer to - indicate this. Otherwise, change the white-space character into a - null. */ - if( *(con->e) ) { - *(con->e) = 0; - len = con->e - result; - } else { - con->e = NULL; - len = strlen( result ); - } - -/* Add the word into the cyclic list of words used to form a document - fragment to include in error and warning messages. */ - con->words[ con->next ] = astStore( con->words[ con->next ], - result, len + 1 ); - if( ++(con->next) == NEWORD ) con->next = 0; - -/* Deal with words that include an opening or closing parenthesis at - start or end. These words must have 2 or more characters. */ - if( len > 1 ) { - -/* If the word ends with an opening parenthesis, replace the parenthesis - with a null character and set a flag indicating that the next word - returned should consist of just an opening parenthesis. */ - if( result[ len - 1 ] == '(' ) { - ((char *) result)[ len - 1 ] = 0; - con->open = 1; - -/* If the word ends with a closing parenthesis, replace the parenthesis - with a null character and set a flag indicating that the next word - returned should consist of just a closing parenthesis. */ - } else if( result[ len - 1 ] == ')' ) { - ((char *) result)[ len - 1 ] = 0; - con->close = 1; - -/* If the word starts with an opening parenthesis, replace the parenthesis - with a null character and set a flag indicating that the next word - returned should consist of just a closing parenthesis. */ - } else if( result[ 0 ] == '(' ) { - con->wnext = ( (char *) result ) + 1; - con->f = *(con->wnext); - *(con->wnext) = 0; - } - } - -/* If we have run out of input words, but we have not yet finished - interpreting the previous word returned, return a null string, rather - than a null pointer in order to allow further interpretation of the - previous word. */ - } else if( ! con->done ) { - result = ""; - } - } - -/* Return the pointer to the next word. */ - return result; -} - -static int GetRegionProps( AstStcsChan *this, AstRegion *spreg, - AstKeyMap *spprops, int nspace, int defdigs, - double scale, int issky, int *status ) { -/* -* Name: -* GetRegionProps - -* Purpose: -* Create STC-S properties to describe a given Region and store in a -* KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* int GetRegionProps( AstStcsChan *this, AstRegion *spreg, -* AstKeyMap *spprops, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function creates a set of STC-S properties to describe the -* supplied spatial (2D) Region, and stores them in the supplied KeyMap. - -* Parameters: -* this -* The StcsChan being used. -* spreg -* The 2-D spatial Region to be described. -* spprops -* A KeyMap in which to store the created properties. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Returns the integer code for the spatial region, or NULL_ID if the -* properties could not be created for any reason. - -*/ - - -/* Local Variables: */ - AstKeyMap *new_props; /* KeyMap holding component Region properties */ - AstMapping *sreg; /* Simplified Region */ - AstRegion **reg_list; /* Array of component Regioon pointers */ - char *prop; /* Formatted property string */ - char buf[ 100 ]; /* Buffer for formatted values */ - char fmt[ 10 ]; /* Buffer for format specifier */ - double *p; /* Pointer to next axis value */ - double *points; /* Pointer to array of Region axis values */ - double a; /* Circle or ellipse radius */ - double angle; /* Ellipse position angle */ - double b; /* Ellipse radius */ - double centre[ 3 ]; /* Circle or ellipse centre */ - double lbnd[ 3 ]; /* Region lower bounds */ - double ubnd[ 3 ]; /* Region upper bounds */ - int i; /* Loop index */ - int j; /* Loop index */ - int nc; /* Number of characters in "prop" string */ - int np; /* Number of points defining the Region */ - int nreg; /* Number of component Regions */ - int ok; /* Can the Region be written out? */ - int oper; /* Code for CmpRegion boolean operator */ - int spaceid; /* Identifier for STC-S spatial region type */ - -/* Check inherited status */ - if( !astOK ) return NULL_ID; - -/* Initialise */ - spaceid = NULL_ID; - ok = 1; - prop = NULL; - -/* If the Region has been negated, temporarily negate the Region, and - write its properties into a new KeyMap by calling this function - recursively. Then store the new KeyMap in the supplied KeyMap. */ - if( astGetNegated( spreg ) ) { - spaceid = NOT_ID; - astNegate( spreg ); - new_props = astKeyMap( " ", status ); - - if( GetRegionProps( this, spreg, new_props, nspace, defdigs, - scale, issky, status ) == NULL_ID ) ok = 0; - - astMapPut0C( spprops, "ID", "Not", NULL ); - astMapPut0A( spprops, "REGION1", new_props, NULL ); - astMapPut0I( spprops, "NREG", 1, NULL ); - astNegate( spreg ); - -/* Store properties that are specific to AllSky sub-phrases (i.e. none)... */ - } else if( astIsANullRegion( spreg ) && astGetNegated( spreg ) ) { - spaceid = ALLSKY_ID; - astMapPut0C( spprops, "ID", "AllSky", NULL ); - -/* Store properties that are specific to Circle sub-phrases... */ - } else if( astIsACircle( spreg ) ) { - spaceid = CIRCLE_ID; - astMapPut0C( spprops, "ID", "Circle", NULL ); - -/* Get the geometric parameters of the Circle. */ - astCirclePars( spreg, centre, &a, NULL ); - -/* Create a string holding the formatted centre axis values, scaling - to the required units. Use the Frame's Digits attribute to specify - how many digits to use when formatting the axis values. */ - nc = 0; - for( i = 0; i < nspace; i++ ) { - if( centre[ i ] != AST__BAD ) { - GetFmt( "CENTRE", spprops, i, defdigs, fmt, status ); - (void) sprintf( buf, fmt, scale*centre[ i ] ); - prop = astAppendString( prop, &nc, buf ); - prop = astAppendString( prop, &nc, " " ); - - } else { - ok = 0; - astAddWarning( this, 1, "The supplied Circle contains " - "one or more bad centre axis values.", - "astWrite", status ); - break; - } - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - prop[ nc - 1 ] = 0; - astMapPut0C( spprops, "CENTRE", prop, NULL ); - -/* Scale, format and store the radius. */ - if( a != AST__BAD ) { - GetFmt( "RADIUS", spprops, 0, defdigs, fmt, status ); - (void) sprintf( buf, fmt, scale*a ); - astMapPut0C( spprops, "RADIUS", buf, NULL ); - } else { - ok = 0; - astAddWarning( this, 1, "The supplied Circle has an " - "undefined radius.", "astWrite", status ); - } - -/* Store properties that are specific to PositionInterval sub-phrases... */ - } else if( astIsAInterval( spreg ) || astIsABox( spreg ) ) { - spaceid = POSITION_INTERVAL_ID; - astMapPut0C( spprops, "ID", "PositionInterval", NULL ); - -/* Get the bounds of the Region. */ - astGetRegionBounds( spreg, lbnd, ubnd ); - -/* Create a string holding the formatted low limits, scaling to the - required units. Use the Frame's Digits attribute to specify how - many digits to use when formatting the axis values. */ - nc = 0; - for( i = 0; i < nspace; i++ ) { - if( lbnd[ i ] == AST__BAD || lbnd[ i ] == DBL_MAX || - lbnd[ i ] == -DBL_MAX ) { - astAddWarning( this, 1, "Spatial axis %d has an undefined " - "lower limit.", "astWrite", status, i + 1 ); - ok = 0; - break; - } else { - GetFmt( "LOLIMIT", spprops, i, defdigs, fmt, status ); - (void) sprintf( buf, fmt, scale*lbnd[ i ] ); - prop = astAppendString( prop, &nc, buf ); - prop = astAppendString( prop, &nc, " " ); - } - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - prop[ nc - 1 ] = 0; - astMapPut0C( spprops, "LOLIMIT", prop, NULL ); - -/* Do the same for the upper limits. */ - nc = 0; - for( i = 0; i < nspace; i++ ) { - if( ubnd[ i ] == AST__BAD || ubnd[ i ] == DBL_MAX || - ubnd[ i ] == -DBL_MAX ) { - astAddWarning( this, 1, "Spatial axis %d has an undefined " - "upper limit.", "astWrite", status, i + 1 ); - ok = 0; - break; - } else { - GetFmt( "HILIMIT", spprops, i, defdigs, fmt, status ); - (void) sprintf( buf, fmt, scale*ubnd[ i ] ); - prop = astAppendString( prop, &nc, buf ); - prop = astAppendString( prop, &nc, " " ); - } - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - prop[ nc - 1 ] = 0; - astMapPut0C( spprops, "HILIMIT", prop, NULL ); - -/* Store properties that are specific to Ellipse sub-phrases... */ - } else if( astIsAEllipse( spreg ) ) { - spaceid = ELLIPSE_ID; - astMapPut0C( spprops, "ID", "Ellipse", NULL ); - -/* Get the geometric parameters of the Ellipse. */ - astEllipsePars( spreg, centre, &a, &b, &angle, NULL, NULL ); - -/* Create a string holding the formatted centre axis values, scaling - to the required units. Use the Frame's Digits attribute to specify - how many digits to use when formatting the axis values. */ - nc = 0; - for( i = 0; i < nspace; i++ ) { - if( centre[ i ] != AST__BAD ) { - GetFmt( "CENTRE", spprops, i, defdigs, fmt, status ); - (void) sprintf( buf, fmt, scale*centre[ i ] ); - prop = astAppendString( prop, &nc, buf ); - prop = astAppendString( prop, &nc, " " ); - - } else { - ok = 0; - astAddWarning( this, 1, "The supplied Ellipse contains " - "one or more bad centre axis values.", - "astWrite", status ); - break; - } - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - prop[ nc - 1 ] = 0; - astMapPut0C( spprops, "CENTRE", prop, NULL ); - -/* Scale, format and store the two radii. */ - if( a != AST__BAD && b != AST__BAD && angle != AST__BAD ) { - GetFmt( "RADIUS1", spprops, 0, defdigs, fmt, status ); - (void) sprintf( buf, fmt, scale*a ); - astMapPut0C( spprops, "RADIUS1", buf, NULL ); - - GetFmt( "RADIUS2", spprops, 0, defdigs, fmt, status ); - (void) sprintf( buf, fmt, scale*b ); - astMapPut0C( spprops, "RADIUS2", buf, NULL ); - -/* Convert the angle to degrees in the direction required by STC-S, - format and store. */ - angle *= AST__DR2D; - if( !issky ) angle = 90 - angle; - while( angle < 0.0 ) angle += 360.0; - while( angle >= 360.0 ) angle -= 360.0; - - GetFmt( "POSANGLE", spprops, 0, defdigs, fmt, status ); - (void) sprintf( buf, fmt, angle ); - astMapPut0C( spprops, "POSANGLE", buf, NULL ); - - } else { - astAddWarning( this, 1, "The gemeotric parameters of the " - "supplied Ellipse are undefined.", - "astWrite", status ); - ok = 0; - } - -/* Store properties that are specific to Polygon sub-phrases... */ - } else if( astIsAPolygon( spreg ) ) { - spaceid = POLYGON_ID; - astMapPut0C( spprops, "ID", "Polygon", NULL ); - -/* Get an array holding the axis values at the polygon vertices. */ - astGetRegionPoints( spreg, 0, 0, &np, NULL ); - points = astMalloc( sizeof( double )*np*nspace ); - astGetRegionPoints( spreg, np, nspace, &np, points ); - -/* Create a string holding the formatted vertex axis values, scaling - to the required units. Use the Frame's Digits attribute to specify - how many digits to use when formatting the axis values. */ - GetFmt( "VERTICES", spprops, 0, defdigs, fmt, status ); - nc = 0; - for( j = 0; j < np; j++ ) { - p = points + j; - for( i = 0; i < nspace; i++ ) { - if( *p != AST__BAD ) { - (void) sprintf( buf, fmt, scale*(*p) ); - prop = astAppendString( prop, &nc, buf ); - prop = astAppendString( prop, &nc, " " ); - p += np; - } else { - astAddWarning( this, 1, "The supplied Polygon contains " - "one or more bad axis values.", "astWrite", - status ); - ok = 0; - break; - } - } - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - prop[ nc - 1 ] = 0; - astMapPut0C( spprops, "VERTICES", prop, NULL ); - -/* Free resources. */ - points = astFree( points ); - -/* Store properties that are specific to Position sub-phrases... */ - } else if( astIsAPointList( spreg ) ) { - spaceid = POSITION_ID; - astMapPut0C( spprops, "ID", "Position", NULL ); - -/* Check the PointList contains only a single point. */ - astGetRegionPoints( spreg, 0, 0, &np, NULL ); - if( np > 1 ) { - astAddWarning( this, 1, "The supplied PointList contains " - "more than one position.", "astWrite", status ); - ok = 0; - -/* If so, get the axis values at the point. */ - } else { - astGetRegionPoints( spreg, 1, nspace, &np, centre ); - -/* Create a string holding the formatted axis values, scaling to the - required units. Use the Frame's Digits attribute to specify how many - digits to use when formatting the axis values. */ - nc = 0; - for( i = 0; i < nspace; i++ ) { - if( centre[ i ] != AST__BAD ) { - GetFmt( "POSITION", spprops, i, defdigs, fmt, status ); - (void) sprintf( buf, fmt, scale*centre[ i ] ); - prop = astAppendString( prop, &nc, buf ); - prop = astAppendString( prop, &nc, " " ); - - } else { - astAddWarning( this, 1, "The supplied PointList contains " - "one or more bad axis values.", "astWrite", - status ); - ok = 0; - break; - } - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - prop[ nc - 1 ] = 0; - astMapPut0C( spprops, "POSITION", prop, NULL ); - } - -/* Store properties that are specific to compound Position sub-phrases... */ - } else { - -/* If the Region is not a CmpRegion (e.g. a Prism?) see if simplifying it - produces a CmpRegion. */ - if( !astIsACmpRegion( spreg ) ) { - sreg = astSimplify( spreg ); - } else { - sreg = astClone( spreg ); - } - -/* If we now have a CmpRegion, write its properties into a new KeyMap by - calling this function recursively. Then store the new KeyMap in the - supplied KeyMap. */ - if( astIsACmpRegion( sreg ) ) { - -/* Get the list of Regions that the CmpRegion combines together. This - also returns the boolean operator with which they are combined. */ - nreg = 0; - reg_list = NULL; - oper = astCmpRegionList( (AstCmpRegion *) sreg, &nreg, ®_list ); - -/* Store compound region type in the supplied KeyMap. */ - if( oper == AST__AND ) { - spaceid = INTERSECTION_ID; - astMapPut0C( spprops, "ID", "Intersection", NULL ); - } else if( oper == AST__OR ) { - spaceid = UNION_ID; - astMapPut0C( spprops, "ID", "Union", NULL ); - } else { - spaceid = DIFFERENCE_ID; - astMapPut0C( spprops, "ID", "Difference", NULL ); - } - -/* Loop round each of the combined Regions. */ - for( i = 0; i < nreg; i++ ) { - -/* Create a new KeyMap, and then call this function recursively to store - the properties of the i'th component Region in the new KeyMap. */ - if( ok ) { - new_props = astKeyMap( " ", status ); - if( GetRegionProps( this, reg_list[ i ], new_props, nspace, - defdigs, scale, issky, status ) - == NULL_ID ) ok = 0; - -/* Store the new KeyMap in the supplied KeyMap. */ - sprintf( buf, "REGION%d", i + 1 ); - astMapPut0A( spprops, buf, new_props, NULL ); - -/* Free resources. */ - new_props = astAnnul( new_props ); - } - reg_list[ i ] = astAnnul( reg_list[ i ] ); - } - reg_list = astFree( reg_list ); - astMapPut0I( spprops, "NREG", nreg, NULL ); - -/* All other classes of Region are unsupported. */ - } else { - astAddWarning( this, 1, "The supplied %s cannot be written " - "out since STC-S does not support %s regions.", - "astWrite", status, astGetClass( spreg ), - astGetClass( spreg ) ); - ok = 0; - } - -/* Free resources. */ - sreg = astAnnul( sreg ); - } - - if( prop ) prop = astFree( prop ); - -/* If an error has occurred, return NULL_ID. */ - if( !ok || !astOK ) spaceid = NULL_ID; - -/* Return the identifier for the STC-S spatial region type. */ - return spaceid; -} - -void astInitStcsChanVtab_( AstStcsChanVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitStcsChanVtab - -* Purpose: -* Initialise a virtual function table for an StcsChan. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcschan.h" -* void astInitStcsChanVtab( AstStcsChanVtab *vtab, const char *name ) - -* Class Membership: -* StcsChan vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the StcsChan class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstChannelVtab *channel; /* Pointer to Channel component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitChannelVtab( (AstChannelVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAStcsChan) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstChannelVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ - - vtab->ClearStcsArea = ClearStcsArea; - vtab->GetStcsArea = GetStcsArea; - vtab->SetStcsArea = SetStcsArea; - vtab->TestStcsArea = TestStcsArea; - - vtab->ClearStcsCoords = ClearStcsCoords; - vtab->GetStcsCoords = GetStcsCoords; - vtab->SetStcsCoords = SetStcsCoords; - vtab->TestStcsCoords = TestStcsCoords; - - vtab->ClearStcsProps = ClearStcsProps; - vtab->GetStcsProps = GetStcsProps; - vtab->SetStcsProps = SetStcsProps; - vtab->TestStcsProps = TestStcsProps; - - vtab->SetStcsLength = SetStcsLength; - vtab->ClearStcsLength = ClearStcsLength; - vtab->TestStcsLength = TestStcsLength; - vtab->GetStcsLength = GetStcsLength; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - channel = (AstChannelVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - channel->Write = Write; - channel->Read = Read; - - parent_getindent = channel->GetIndent; - channel->GetIndent = GetIndent; - -/* Declare the Dump function for this class. There is no destructor or - copy constructor. */ - astSetDump( vtab, Dump, "StcsChan", "STC-S I/O Channel" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static AstRegion *MakeSpaceRegion( AstKeyMap *props, AstFrame *frm, - double scale, int *status ){ -/* -* Name: -* MakeSpaceRegion - -* Purpose: -* Create a Region to describe the space coverage of the STC-S -* description being read. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* AstRegion *MakeSpaceRegion( AstKeyMap *props, AstFrame *frm, -* double scale, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function returns a pointer to a new Region that describes the -* spatial coverage of an STC-S description. - -* Parameters: -* props -* A KeyMap holding properties read from the STC-S space sub-phrase. -* frm -* The Frame in which the Region is to be defined. -* scale -* A factor that must be applied to the raw axis values read from the -* STC-S description in order to convert them into the units used by -* the supplied Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Region pointer. - -*/ - - -/* Local Variables: */ - AstKeyMap *reg_props; /* KeyMap holding argument properties */ - AstRegion *reg; /* Current argument Region */ - AstRegion *result; /* Returned Region */ - AstRegion *tmp; /* Temporary Region pointer */ - char key[ 20 ]; /* Key for argument region */ - const char *id; /* Sub-phrase identifier */ - double *p; /* Pointer to next axis value */ - double *temp; /* Pointer to array of reordered polygon vertex axis values */ - double *vertices; /* Pointer to array of polygon vertex axis values */ - double val1; /* Scalar value read from KeyMap */ - double val2; /* Scalar value read from KeyMap */ - double val3; /* Scalar value read from KeyMap */ - double vec1[ 10 ]; /* Vector read from KeyMap */ - double vec2[ 10 ]; /* Vector read from KeyMap */ - int iaxis; /* Axis index */ - int ireg; /* Index of argument regions */ - int ivert; /* Vertex index */ - int naxes; /* Number of spatial axes */ - int nreg; /* Number of argument regions */ - int nval; /* Number of values read from KeyMap */ - int nvert; /* Number of vertices */ - int spaceid; /* Integer identifier for spatial shape */ - int oper; /* Boolean operator code for CmpRegion */ - -/* Initialise */ - result = NULL; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Temporarily ensure that an error is reported if an attempt is made to - access a non-existent KeyMap entry. */ - astSetKeyError( props, 1 ); - -/* Get the space sub-phrase identifier from the properties KeyMap, and - find the corresponding integer identifier. */ - - astMapGet0C( props, "ID", &id ); - spaceid = SpaceId( id, status ); - -/* Get the number of axes in the Frame. */ - naxes = astGetNaxes( frm ); - -/* Create a suitable Region to enclose the space positions. This - includes scaling the supplied axis values to the units used by - the Frame. */ - if( spaceid == POSITION_INTERVAL_ID ) { - astMapGet1D( props, "DLOLIMIT", naxes, &nval, vec1 ); - astMapGet1D( props, "DHILIMIT", naxes, &nval, vec2 ); - - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vec1[ iaxis ] *= scale; - vec2[ iaxis ] *= scale; - } - - result = (AstRegion *) astBox( frm, 1, vec1, vec2, NULL, " ", status ); - - } else if( spaceid == ALLSKY_ID ) { - result = (AstRegion *) astNullRegion( frm, NULL, "Negated=1", status ); - - } else if( spaceid == CIRCLE_ID ) { - astMapGet1D( props, "DCENTRE", naxes, &nval, vec1 ); - astMapGet0D( props, "RADIUS", &val1 ); - for( iaxis = 0; iaxis < naxes; iaxis++ ) vec1[ iaxis ] *= scale; - val1 *= scale; - result = (AstRegion *) astCircle( frm, 1, vec1, &val1, NULL, " ", - status ); - - } else if( spaceid == ELLIPSE_ID ) { - astMapGet1D( props, "DCENTRE", naxes, &nval, vec1 ); - astMapGet0D( props, "RADIUS1", &val1 ); - astMapGet0D( props, "RADIUS2", &val2 ); - astMapGet0D( props, "POSANGLE", &val3 ); - for( iaxis = 0; iaxis < naxes; iaxis++ ) vec1[ iaxis ] *= scale; - vec2[ 0 ] = val1*scale; - vec2[ 1 ] = val2*scale; - if( !astIsASkyFrame( frm ) ) val3 = 90.0 - val3; - val3 *= AST__DD2R; - result = (AstRegion *) astEllipse( frm, 1, vec1, vec2, &val3, NULL, " ", - status ); - - } else if( spaceid == BOX_ID ) { - astMapGet1D( props, "DCENTRE", naxes, &nval, vec1 ); - astMapGet1D( props, "DBSIZE", naxes, &nval, vec2 ); - - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vec1[ iaxis ] *= scale; - vec2[ iaxis ] *= scale; - } - - vertices = BoxCorners( frm, vec1, vec2, status ); - result = (AstRegion *) astPolygon( frm, 4, 4, vertices, NULL, " ", - status ); - vertices = astFree( vertices ); - - } else if( spaceid == POLYGON_ID ) { - nval = astMapLength( props, "DVERTICES" ); - temp = astMalloc( sizeof( double )*nval ); - astMapGet1D( props, "DVERTICES", nval, &nval, temp ); - -/* An STC-S polygon description holds the vertex axis values in the wrong - order for the AstPolygon constructor. Therefore, transpose the temp - array (scale them at the same time). */ - vertices = astMalloc( sizeof( double )*nval ); - if( astOK ) { - nvert = nval/naxes; - p = temp; - for( ivert = 0; ivert < nvert; ivert++ ) { - for( iaxis = 0; iaxis < naxes; iaxis++,p++ ) { - vertices[ iaxis*nvert + ivert ] = *p*scale; - } - } - - result = (AstRegion *) astPolygon( frm, nvert, nvert, vertices, NULL, - " ", status ); - } - - vertices = astFree( vertices ); - temp = astFree( temp ); - - } else if( spaceid == POSITION_ID ) { - astMapGet1D( props, "DPOSITION", naxes, &nval, vec1 ); - for( iaxis = 0; iaxis < naxes; iaxis++ ) vec1[ iaxis ] *= scale; - result = (AstRegion *) SinglePointList( frm, vec1, NULL, status ); - - } else if( spaceid == CONVEX_ID ) { - astError( AST__INTER, "astRead(StcsChan): No support for Convex in " - "MakeSpaceRegion (internal AST programming error).", status ); - -/* All remaining valid space id values are compound - their arguments are held - within separate KeyMaps nested inside the supplied KeyMap. */ - } else if( spaceid != NULL_ID ) { - -/* The number of arguments is defined in the NREG entry. */ - astMapGet0I( props, "NREG", &nreg ); - -/* Get the CmpRegion operator code. */ - if( spaceid == UNION_ID ) { - oper = AST__OR; - } else if( spaceid == INTERSECTION_ID ) { - oper = AST__AND; - } else if( spaceid == DIFFERENCE_ID ) { - oper = AST__XOR; - } else { - oper = 0; /* To avoid compiler warnings */ - } - -/* Loop over all argument Regions. */ - for( ireg = 0; ireg < nreg; ireg++ ) { - -/* Get the KeyMap holding the STC-S properties of the current argument - region. */ - sprintf( key, "REGION%d", ireg + 1 ); - astMapGet0A( props, key, ®_props ); - -/* Construct an AST Region from this list of STC-S properties. */ - reg = MakeSpaceRegion( reg_props, frm, scale, status ); - -/* If we are creating a "Not" element, just negate the argument region - and return it. */ - if( spaceid == NOT_ID ) { - astNegate( reg ); - result = astClone( reg ); - -/* If we are creating a "Union", "Difference" or "Intersection" element, - combine the first two arguments into a CmpRegion, and then add in each - subsequent argument. */ - } else { - if( ireg == 0 ) { - result = astClone( reg ); - } else { - tmp = (AstRegion *) astCmpRegion( result, reg, oper, " ", - status ); - (void) astAnnul( result ); - result = tmp; - } - } - -/* Free resources */ - reg = astAnnul( reg ); - reg_props = astAnnul( reg_props ); - } - } - -/* Ensure that no error is reported if an attempt is made to access a - non-existent KeyMap entry. */ - astSetKeyError( props, 0 ); - -/* Return the Region. */ - return result; -} - -static void MapPut0C( AstKeyMap *km, const char *key, const char *value, - const char *def, int defs, int *status ){ -/* -* Name: -* MapPut0C - -* Purpose: -* Store a text STC-S property in the supplied keymap. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* void MapPut0C( AstKeyMap *km, const char *key, const char *value, -* const char *def, int defs, int *status ) - -* Class Membership: -* StcsChan member function. - -* Description: -* This function stors the supplied value in the given KeyMap, -* handling default values. - -* Parameters: -* km -* Pointer to the KeyMap in which to store the value. -* key -* Pointer to a string holding the property name associated with -* the value. -* value -* The property value. If this is NULL then the function -* returns without action. -* def -* The default property value. -* defs -* If zero, then the value is not stored in the KeyMap if the value -* is equal to the default value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Check the inherited status */ - if( !astOK ) return; - -/* If the value is NULL, ignore the entry. */ - if( value ) { - -/* If the value is equal to the default value, and we are NOT storing - default values, ensure the KeyMap has no entry for the given key. */ - if( astChrMatch( value, def ) && !defs ) { - astMapRemove( km, key ); - -/* Otherwise, store the value. */ - } else { - astMapPut0C( km, key, value, NULL ); - } - } -} - -static void MapPut0D( AstKeyMap *km, const char *key, double value, double def, - int defs, int *status ){ -/* -* Name: -* MapPut0D - -* Purpose: -* Store a floating point STC-S property in the supplied keymap. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* void MapPut0D( AstKeyMap *km, const char *key, double value, double def, -* int defs, int *status ) - -* Class Membership: -* StcsChan member function. - -* Description: -* This function stors the supplied value in the given KeyMap, -* handling default values. - -* Parameters: -* km -* Pointer to the KeyMap in which to store the value. -* key -* Pointer to a string holding the property name associated with -* the value. -* value -* The property value. If this is AST__BAD then the function -* returns without action. -* def -* The default property value. -* defs -* If zero, then the value is not stored in the KeyMap if the value -* is equal to the default value. -* status -* Pointer to the inherited status variable. - -*/ - -/* Check the inherited status */ - if( !astOK ) return; - -/* If the value is bad, ignore the entry. */ - if( value != AST__BAD ) { - -/* If the value is equal to the default value, and we are NOT storing - default values, ensure the KeyMap has no entry for the given key. */ - if( value == def && !defs ) { - astMapRemove( km, key ); - -/* Otherwise, store the value. */ - } else { - astMapPut0D( km, key, value, NULL ); - } - } -} - -static char *PutRegionProps( AstStcsChan *this, AstKeyMap *km, const char *id, - int indent, char *line, int *nc, int *crem, - int linelen, int *status ){ -/* -* Name: -* PutRegionProps - -* Purpose: -* Append STC-S space sub-phrase properties to the end of a string. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* char *PutRegionProps( AstStcsChan *this, AstKeyMap *km, const char *id, -* int indent, char *line, int *nc, int *crem, -* int linelen, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function converts the STC-S properties for the space sub-phrase -* supplied in a KeyMap into text, and appends them to the supplied -* line of text in the order required by STC-S. -* -* It is assumed that the sub-phrase identifier has already been put -* into the string. - -* Parameters: -* this -* The StcsChan. -* km -* Pointer to a KeyMap containing the STC-S properties. -* id -* Pointer to the sub-phrase identifier. -* indent -* If greater than or equal to zero, then it gives the number of -* spaces indentation to place before the first word (also indicates -* that a new-line should follow the last word of the argument). If -* negative, never use indentation. -* line -* Pointer to the buffer to receive the property values. -* nc -* Pointer to an int in which to store the number of characaters in -* the buffer. Updated on exit. -* crem -* Pointer to an int in which to store the maximum number of -* characters before a new line. Ignored if zero. Updated on exit. -* linelen -* The maximum number of character per line, or zero if all text is -* to be included in a single line. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the buffer. This will usually be "line", but may be -* different to "line" if it was necessary to expand the memory to make -* room for new properties. - -*/ - -/* Local Variables: */ - AstKeyMap *reg_props; - char *result; - char key[ 20 ]; - int i; - int ireg; - int nreg; - int spaceid; - -/* Initialise */ - result = line; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Temporarily ensure that an error is reported if an attempt is made to - access a non-existent KeyMap entry. */ - astSetKeyError( km, 1 ); - -/* Get the integer code for the space sub-phrase identifier. */ - spaceid = SpaceId( id, status ); - -/* Do each type of space sub-phrase. */ - if( spaceid == NULL_ID ) { - astError( AST__INTER, "astWrite(StcsChan): Illegal 'spaceid' value " - "in function PutRegionProps (internal AST programming " - "error).", status ); - - } else if( spaceid == POSITION_INTERVAL_ID ) { - result = AddItem( this, km, "LOLIMIT", NULL, result, nc, crem, linelen, status ); - result = AddItem( this, km, "HILIMIT", NULL, result, nc, crem, linelen, status ); - - } else if( spaceid == ALLSKY_ID ) { - - } else if( spaceid == CIRCLE_ID ) { - result = AddItem( this, km, "CENTRE", NULL, result, nc, crem, linelen, status ); - result = AddItem( this, km, "RADIUS", NULL, result, nc, crem, linelen, status ); - - } else if( spaceid == ELLIPSE_ID ) { - result = AddItem( this, km, "CENTRE", NULL, result, nc, crem, linelen, status ); - result = AddItem( this, km, "RADIUS1", NULL, result, nc, crem, linelen, status ); - result = AddItem( this, km, "RADIUS2", NULL, result, nc, crem, linelen, status ); - result = AddItem( this, km, "POSANGLE", NULL, result, nc, crem, linelen, status ); - - } else if( spaceid == BOX_ID ) { - result = AddItem( this, km, "CENTRE", NULL, result, nc, crem, linelen, status ); - result = AddItem( this, km, "BSIZE", NULL, result, nc, crem, linelen, status ); - - } else if( spaceid == POLYGON_ID ) { - result = AddItem( this, km, "VERTICES", NULL, result, nc, crem, linelen, status ); - - } else if( spaceid == CONVEX_ID ) { - astError( AST__INTER, "astWrite(StcsChan): No Convex support yet " - "(internal AST programming error).", status ); - - } else if( spaceid == POSITION_ID ) { - result = AddItem( this, km, "POSITION", NULL, result, nc, crem, linelen, status ); - -/* All remaining space id values are compound regions. */ - } else { - -/* Append an opening parenthesis. */ - result = astAppendString( result, nc, "( " ); - -/* If required, write out the text through the Channel sink function, - and start a new line. */ - if( indent >= 0 ) { - astPutNextText( this, result ); - *nc = 0; - *crem = linelen; - } - -/* Set the indentation for the next level down. */ - if( indent == 0 ) { - indent = 6; - } else if( indent > 0 ){ - indent += 3; - } - -/* Loop round all argument Regions. */ - astMapGet0I( km, "NREG", &nreg ); - for( ireg = 0; ireg < nreg; ireg++ ) { - sprintf( key, "REGION%d", ireg + 1 ); - astMapGet0A( km, key, ®_props ); - -/* Put any required indentation at the start of the line. */ - if( indent > 0 ) { - for( i = 0; i < indent; i++ ) { - result = astAppendString( result, nc, " " ); - } - *crem -= indent; - } - -/* Append the identifier for the next argument to the string. */ - result = AddItem( this, reg_props, "ID", NULL, result, nc, crem, - linelen, status ); - -/* Append the arguments to the string. */ - astMapGet0C( reg_props, "ID", &id ); - result = PutRegionProps( this, reg_props, id, indent, result, nc, - crem, linelen, status ); - -/* Write the text out to the sink function, and start a new line. */ - if( indent > 0 ) { - astPutNextText( this, result ); - *nc = 0; - *crem = linelen; - } - -/* Free resources. */ - reg_props = astAnnul( reg_props ); - } - -/* Decrease any indentation, and then append a closing parenthesis. */ - if( indent > 2 ) { - indent -= 3; - for( i = 0; i < indent; i++ ) { - result = astAppendString( result, nc, " " ); - } - } - result = astAppendString( result, nc, ") " ); - -/* If we are about to return fomr the top-level, start a new line. */ - if( indent > 0 && indent < 6 ) { - astPutNextText( this, result ); - *nc = 0; - for( i = 0; i < indent; i++ ) { - result = astAppendString( result, nc, " " ); - } - *crem = linelen - indent; - } - } - -/* Ensure that no error is reported if an attempt is made to access a - non-existent KeyMap entry. */ - astSetKeyError( km, 0 ); - -/* Return the buffer pointer. */ - return result; -} - -static AstObject *Read( AstChannel *this_channel, int *status ) { -/* -* Name: -* Read - -* Purpose: -* Read an Object from a Channel. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* AstObject *Read( AstChannel *this_channel, int *status ) - -* Class Membership: -* StcsChan member function (over-rides the astRead method -* inherited from the Channel class). - -* Description: -* This function reads an Object from an StcsChan. - -* Parameters: -* this -* Pointer to the StcsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new Object. -*/ - -/* Local Variables: */ - AstFrame *spacefrm; /* Pointer to SpaceFrame for space sub-phrase */ - AstFrameSet *fs; /* Temporary FrameSet */ - AstKeyMap *full_props; /* KeyMap holding all sub-phrase properties */ - AstKeyMap *props; /* KeyMap holding current sub-phrase properties */ - AstObject *new; /* Pointer to returned Object */ - AstObject *obj; /* Pointer to Object extracted from a KeyMap */ - AstPrism *tr; /* Temporary Region pointer */ - AstRegion *full_co; /* Region describing full coord position */ - AstRegion *full_enc; /* Region describing full enclosure */ - AstRegion *red_co; /* Region describing red-shift coord */ - AstRegion *red_enc; /* Region describing red-shift enclosure */ - AstRegion *space_co; /* Region describing space coord */ - AstRegion *space_enc; /* Region describing space enclosure */ - char **words; /* Array of pointers to individual words */ - int nword; /* Number of words returned */ - AstRegion *spec_co; /* Region describing spectral coord */ - AstRegion *spec_enc; /* Region describing spectral enclosure */ - AstRegion *time_co; /* Region describing time coord */ - AstRegion *time_enc; /* Region describing time enclosure */ - AstSpecFrame *redfrm; /* Pointer to SpecFrame for redshift sub-phrase */ - AstSpecFrame *specfrm; /* Pointer to SpecFrame for spectral sub-phrase */ - AstStcsChan *this; /* Pointer to the StcsChan structure */ - AstStdOfRestType sor; /* Standard of rest */ - AstSystemType sys; /* Frame System attribute value */ - AstTimeFrame *tf1; /* Temporary TimeFrame */ - AstTimeFrame *timefrm; /* Pointer to TimeFrame for time sub-phrase */ - AstTimeScaleType ts; /* TimeFrame TimeScale attribute value */ - WordContext con; /* Context for finding next source word */ - char *fbuf; /* Pointer to buffer holding document fragment */ - const char *new_ts; /* Time scale string */ - double epoch; /* Value to use for the Epoch attribue */ - double fill; /* Filling factor */ - double hilim; /* Axis upper limit */ - double lolim; /* Axis lower limit */ - double scale; /* Units scaling factor */ - int nval; /* No. of values read from KeyMap */ - double vals[ 10 ]; /* Values read from KeyMap */ - double start; /* Start time */ - double stop; /* Stop time */ - double time; /* Time value */ - double time_origin; /* Value to use as TimeFrame TimeOrigin*/ - double value; /* Axis value */ - int iaxis; /* Axis index */ - int is_skyframe; /* Is the space frame a SkyFrame? */ - int level; /* Warning reporting level */ - int naxes; /* No. of space Frame axes */ - int nwant; /* Number of objects to return */ - int use_co; /* Do we have a full coordinate position? */ - int use_enc; /* Do we have a full enclosure? */ - int want_co; /* Is the Coordinates component wanted? */ - int want_enc; /* Is the enclosure region wanted? */ - int want_props; /* Are the STC-S properties wanted? */ - const char *cval; /* Pointer to property value */ - const char *type; /* Type of redshift axis */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Obtain a pointer to the StcsChan structure. */ - this = (AstStcsChan *) this_channel; - -/* Initialise. */ - epoch = AST__BAD; - start = AST__BAD; - stop = AST__BAD; - time = AST__BAD; - time_co = NULL; - time_enc = NULL; - space_co = NULL; - space_enc = NULL; - spacefrm = NULL; - spec_co = NULL; - spec_enc = NULL; - red_co = NULL; - red_enc = NULL; - use_co = 1; - use_enc = 0; - scale = 1.0; - -/* Read the STC-S description from the external source, parse it, and - create a KeyMap containing the parsed property values. */ - full_props = ReadProps( this, status ); - -/* If the STC-S description contained a time sub-phrase, get the KeyMap - containing the proprties of the time sub-phrase, and then create AST - Regions describing the time coordinate value and its enclosing Region. */ - if( astMapGet0A( full_props, "TIME_PROPS", &obj ) ) { - props = (AstKeyMap *) obj; - -/* Create the default TimeFrame */ - timefrm = astTimeFrame( " ", status ); - -/* Get the TIMESCALE property from the KeyMap, and identify the corresponding - AST TimeScale. */ - ts = AST__BADTS; - new_ts = NULL; - level = 3; - - if( astMapGet0C( props, "TIMESCALE", &cval ) ) { - - if( astChrMatch( cval, "TT" ) ) { - ts = AST__TT; - - } else if( astChrMatch( cval, "TDT" ) ) { - ts = AST__TT; - new_ts = "TT"; - - } else if( astChrMatch( cval, "ET" ) ) { - ts = AST__TT; - new_ts = "TT"; - - } else if( astChrMatch( cval, "TAI" ) ) { - ts = AST__TAI; - - } else if( astChrMatch( cval, "IAT" ) ) { - ts = AST__TAI; - new_ts = "TAI"; - - } else if( astChrMatch( cval, "UTC" ) ) { - ts = AST__UTC; - - } else if( astChrMatch( cval, "TEB" ) ) { - ts = AST__TDB; - new_ts = "TDB"; - level = 1; - - } else if( astChrMatch( cval, "TDB" ) ) { - ts = AST__TDB; - - } else if( astChrMatch( cval, "TCG" ) ) { - ts = AST__TCG; - - } else if( astChrMatch( cval, "TCB" ) ) { - ts = AST__TCB; - - } else if( astChrMatch( cval, "LST" ) ) { - ts = AST__LMST; - - } else if( astChrMatch( cval, "nil" ) ) { - astAddWarning( this, 2, "Time scale defaulting to 'TAI'.", - "astRead", status ); - - } else if( astOK ){ - astError( AST__BADIN, "astRead(StcsChan): Unknown time scale '%s'.", - status, cval ); - } - - } else { - astAddWarning( this, 2, "Time scale defaulting to 'TAI'.", - "astRead", status ); - } - -/* Issue a warning if a different time-scale was substituted for the supplied - time-scale. */ - if( new_ts ) { - astAddWarning( this, level, "AST does not support the '%s' time " - "scale. The '%s' timescale is being used instead.", - "astRead", status, cval, new_ts ); - } - -/* If we got a time scale, set the TimeScale attribute in the TimeFrame - to the same value. */ - if( ts != AST__BADTS ) astSetTimeScale( timefrm, ts ); - -/* The AST TimeFrame class has no reference position, so allow any reference - position but issue a warning for anything other than "TOPOCENTER" and - "UNKNOWNRefPos". */ - if( !astMapGet0C( props, "REFPOS", &cval ) ) cval = "UNKNOWNRefPos"; - if( !astChrMatch( cval, "TOPOCENTER" ) ) { - astAddWarning( this, 1, "AST only supports topocentric time frames, " - "so 'TOPOCENTER' will be used in place of '%s'.", - "astRead", status, cval ); - } - -/* Get the times describes by the time sub-phrase as MJD values. */ - astMapGet0D( props, "MJDSTART", &start ); - astMapGet0D( props, "MJDTIME", &time ); - astMapGet0D( props, "MJDSTOP", &stop ); - -/* Get the earliest time represented by the time sub-phrase. We use this - as the TimeOrigin for the TimeFrame, and also as the Epoch for all - frames. */ - time_origin = start; - if( time_origin == AST__BAD ) time_origin = time; - if( time_origin == AST__BAD ) time_origin = stop; - epoch = time_origin; - -/* Store the TimeOrigin value in the TimeFrame, modifying the time values - accordingly. */ - if( time_origin != AST__BAD ) { - astSetTimeOrigin( timefrm, time_origin ); - if( start != AST__BAD ) start -= time_origin; - if( stop != AST__BAD ) stop -= time_origin; - if( time != AST__BAD ) time -= time_origin; - } - -/* Convert the epoch to TDB. */ - if( epoch != AST__BAD && ts != AST__TDB ) { - tf1 = astCopy( timefrm ); - astSetTimeScale( tf1, AST__TDB ); - fs = astConvert( timefrm, tf1, "" ); - astTran1( fs, 1, &epoch, 1, &epoch ); - fs = astAnnul( fs ); - tf1 = astAnnul( tf1 ); - } - -/* Store the epoch value in the TimeFrame. */ - if( epoch != AST__BAD ) astSetEpoch( timefrm, epoch ); - -/* Create a suitable Region to describe the enclosure for the time coords */ - if( start != AST__BAD || stop != AST__BAD ) { - time_enc = (AstRegion *) astInterval( timefrm, &start, &stop, - NULL, "", status ); - use_enc = 1; - } - -/* Create a suitable Region to describe the time coords contained within - the above enclosure. */ - if( time != AST__BAD ) { - time_co = (AstRegion *) SinglePointList( (AstFrame *) timefrm, - &time, NULL, status); - } else { - use_co = 0; - } - -/* If no enclosure Region was created for the time sub-phrase, use a - copy of any coordinate region. This is because each sub-phrase needs - to have an enclosure of some sort if they are to be combined in parallel - into an enclose for the whole CmpFrame. */ - if( ! time_enc && time_co ) time_enc = astCopy( time_co ); - -/* Set the filling factor. */ - if( time_enc && astMapGet0D( props, "FILLFACTOR", &fill ) ) { - astSetFillFactor( time_enc, fill ); - } - -/* Get the units in which the time error values are given, and get the - scaling factor that converts them into days. */ - if( astMapGet0C( props, "UNIT", &cval ) ) { - if( !strcmp( cval, "s" ) ) { - scale = 1.0/86400.0; - - } else if( !strcmp( cval, "d" ) ) { - scale = 1.0; - - } else if( !strcmp( cval, "a" ) ) { - scale = 365.25; - - } else if( !strcmp( cval, "yr" ) ) { - scale = 365.25; - - } else if( !strcmp( cval, "cy" ) ) { - scale = 36525.0; - - } else if( astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Unsupported " - "units (%s) for the time axis within an " - "STC-S description.", status, cval ); - } - - } else { - scale = 1.0/86400.0; - } - -/* Associate an uncertainty with the two Regions. */ - if( astMapGet1D( props, "DERROR", 2, &nval, vals ) ) { - if( nval > 1 ) { - astAddWarning( this, 1, "An STC-S time sub-phrase contains an " - "Error range. AST does not support error ranges " - "so the mid value will be used as the error.", - "astRead", status ); - vals[ 0 ] = 0.5*( vals[ 0 ] + vals[ 1 ] ); - } - - SetUnc( time_enc, time_co, (AstFrame *) timefrm, 0, scale, vals, 1, - status ); - } - -/* Free resources */ - props = astAnnul( props ); - timefrm = astAnnul( timefrm ); - } - -/* If the STC-S description contained a space sub-phrase, get the KeyMap - containing the proprties of the space sub-phrase, and then create AST - Regions describing the spatial position and its enclosing Region. */ - if( astMapGet0A( full_props, "SPACE_PROPS", &obj ) ) { - props = (AstKeyMap *) obj; - -/* The class of Frame (SkyFrame or basic Frame) is determined by the - "FLAVOR". */ - is_skyframe = 0; - if( astMapGet0C( props, "FLAVOUR", &cval ) ) { - - if( astChrMatch( cval, "SPHER2" ) ) { - spacefrm = (AstFrame *) astSkyFrame( "", status ); - is_skyframe = 1; - - } else if( astChrMatch( cval, "CART1" ) ) { - spacefrm = astFrame( 1, "", status ); - - } else if( astChrMatch( cval, "CART2" ) ) { - spacefrm = astFrame( 2, "", status ); - - } else if( astChrMatch( cval, "CART3" ) ) { - spacefrm = astFrame( 3, "", status ); - - } else { - astError( AST__BADIN, "astRead(StcsChan): Unsupported " - "space 'Flavor' (%s) found in STC-S description.", - status, cval ); - } - - } else { - spacefrm = (AstFrame *) astSkyFrame( "", status ); - is_skyframe = 1; - } - -/* Consider each supported space frame. Report an error for frames - not supported by AST. */ - if( astMapGet0C( props, "FRAME", &cval ) ) { - if( astChrMatch( cval, "ICRS" ) ) { - sys = AST__ICRS; - - } else if( astChrMatch( cval, "FK5" ) ) { - sys = AST__FK5; - - } else if( astChrMatch( cval, "FK4" ) ) { - sys = AST__FK4; - - } else if( astChrMatch( cval, "J2000" ) ) { - sys = AST__FK5; - - } else if( astChrMatch( cval, "B1950" ) ) { - sys = AST__FK4; - - } else if( astChrMatch( cval, "ECLIPTIC" ) ) { - sys = AST__ECLIPTIC; - - } else if( astChrMatch( cval, "GALACTIC" ) ) { - sys = AST__GALACTIC; - - } else if( astChrMatch( cval, "GALACTIC_II" ) ) { - sys = AST__GALACTIC; - - } else if( astChrMatch( cval, "SUPER_GALACTIC" ) ) { - sys = AST__SUPERGALACTIC; - - } else if( astChrMatch( cval, "UNKNOWNFrame" ) ) { - sys = AST__UNKNOWN; - - } else { - sys = AST__UNKNOWN; - astAddWarning( this, 1, "'UNKNOWNFrame' being used in place of " - "unsupported frame '%s' in an STC-S description.", - "astRead", status, cval ); - } - - } else { - cval = "UNKNOWNFrame"; - sys = AST__UNKNOWN; - astAddWarning( this, 1, "Space frame defaulting to 'UNKNOWNFrame' " - "in an STC-S description.", "astRead", status ); - } - -/* We can set the System (only needed for SkyFrames). */ - if( is_skyframe ) { - astSetSystem( spacefrm, sys ); - -/* If we have a basic Frame, set the Domain equal to the STC-S frame value. */ - } else { - astSetDomain( spacefrm, cval ); - } - -/* Set the epoch of the space frame. */ - if( epoch != AST__BAD ) astSetEpoch( spacefrm, epoch ); - -/* The AST Frame and SkyFrame class has no reference position, so for - SkyFrames we consider "TOPOCENTER" and "UNKNOWN" acceptable and all - other unsupported. For other Frames we allow any reference position. */ - if( !astMapGet0C( props, "REFPOS", &cval ) ) cval = "UNKNOWNRefPos"; - if( is_skyframe && !astChrMatch( cval, "TOPOCENTER" ) ) { - astAddWarning( this, 1, "AST only supports topocentric sky frames, " - "so 'TOPOCENTER' will be used in place of '%s'.", - "astRead", status, cval ); - } - -/* Get the number of spatial axes. */ - naxes = astGetNaxes( spacefrm ); - -/* Get the units strings. */ - if( !astMapGet0C( props, "UNIT", &cval ) ) { - if( is_skyframe ) { - cval = "deg"; - } else { - cval = "m"; - } - } - -/* In AST, SkyFrames always use radians, so set up a scaling factor to - convert supplied axis values into radians. */ - if( is_skyframe ) { - - if( !strcmp( cval, "deg" ) || !strcmp( cval, "deg deg" ) ) { - scale = AST__DD2R; - - } else if( !strcmp( cval, "arcmin" ) || !strcmp( cval, "arcmin arcmin" ) ) { - scale = AST__DD2R/60.0; - - } else if( !strcmp( cval, "arcsec" ) || !strcmp( cval, "arcsec arcsec" ) ) { - scale = AST__DD2R/3600.0; - - } else if( astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Unsupported " - "units (%s) for a spherical co-ordinate system " - "within an STC-S description: '%s'.", status, - cval, ContextFragment( &con, &fbuf, status ) ); - } - -/* Basic Frames can use any of the allowed units, so use a scale factor of - 1.0. Also set the active unit flag in the space frame to enable intelligent - units conversion by astConvert etc. */ - } else { - scale = 1.0; - astSetActiveUnit( spacefrm, 1 ); - -/* Basic Frames can have different units on different axes. So split the - units property up into separate words. */ - words = astChrSplit( cval, &nword ); - -/* Set values for the Unit attributes of the Frame. Replicate the last - supplied unit string for any extra axes. */ - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - if( iaxis < nword ) { - astSetUnit( spacefrm, iaxis, words[ iaxis ] ); - } else { - astSetUnit( spacefrm, iaxis, words[ nword - 1 ] ); - } - } - -/* Free resources. */ - for( iaxis = 0; iaxis < nword; iaxis++ ) { - words[ iaxis ] = astFree( words[ iaxis ] ); - } - words = astFree( words ); - } - -/* Create a suitable Region to enclose the space positions. This - includes scaling the supplied axis values to the units used by - the Frame. */ - space_enc = MakeSpaceRegion( props, spacefrm, scale, status ); - if( space_enc ) use_enc = 1; - -/* Create a suitable Region to describe the space coords contained within - the above enclosure. If any sub-phrase has no coordinate value, then - we cannot produce a PointList describing the complete coordinate set. */ - if( astMapGet1D( props, "DPOSITION", naxes, &nval, vals ) ) { - for( iaxis = 0; iaxis < nval; iaxis++ ) vals[ iaxis ] *= scale; - space_co = (AstRegion *) SinglePointList( spacefrm, vals, NULL, - status); - } else { - use_co = 0; - } - -/* If no enclosure Region was created for the space sub-phrase, use a - copy of any coordinate region. This is because each sub-phrase needs - to have an enclosure of some sort if they are to be combined in parallel - into an enclose for the whole CmpFrame. */ - if( ! space_enc && space_co ) space_enc = astCopy( space_co ); - -/* Set the filling factor. */ - if( space_enc && astMapGet0D( props, "FILLFACTOR", &fill ) ) { - astSetFillFactor( space_enc, fill ); - } - -/* Associate an uncertainty with the two Regions. */ - if( astMapGet1D( props, "DERROR", 2*naxes, &nval, vals ) ) { - if( nval > naxes ) { - astAddWarning( this, 1, "An STC-S space sub-phrase contains an " - "Error range. AST does not support error ranges " - "so the mid value will be used as the error.", - "astRead", status ); - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vals[ iaxis ] = 0.5*( vals[ iaxis ] + vals[ iaxis + naxes ] ); - } - -/* If insufficient error values have been supplied, replicate the last - one. */ - } else { - for( iaxis = nval; iaxis < naxes; iaxis++ ) { - vals[ iaxis ] = vals[ nval - 1 ]; - } - } - -/* Set the uncertainty in the two space regions. */ - SetUnc( space_enc, space_co, (AstFrame *) spacefrm, is_skyframe, - scale, vals, naxes, status ); - } - -/* Free resources */ - props = astAnnul( props ); - spacefrm = astAnnul( spacefrm ); - } - - - -/* If the STC-S description contained a velocity sub-phrase, issue a - warning. */ - if( astMapGet0A( full_props, "VELOCITY_PROPS", &obj ) ) { - astAddWarning( this, 1, "Ignoring a velocity sub-phrase found in " - "an STC-S description.", "astRead", status ); - obj = astAnnul( obj ); - } - - -/* If the STC-S description contained a spectral sub-phrase, get the KeyMap - containing the proprties of the spectral sub-phrase, and then create AST - Regions describing the spectral coordinate value and its enclosing Region. */ - if( astMapGet0A( full_props, "SPECTRAL_PROPS", &obj ) ) { - props = (AstKeyMap *) obj; - -/* Create the default SpecFrame */ - specfrm = astSpecFrame( " ", status ); - -/* Get the REFPOS property from the KeyMap, and identify the corresponding - AST StdOfRest. */ - sor = AST__BADSOR; - if( astMapGet0C( props, "REFPOS", &cval ) ) { - - if( astChrMatch( cval, "GEOCENTER" ) ) { - sor = AST__GESOR; - - } else if( astChrMatch( cval, "BARYCENTER" ) ) { - sor = AST__BYSOR; - - } else if( astChrMatch( cval, "HELIOCENTER" ) ) { - sor = AST__HLSOR; - - } else if( astChrMatch( cval, "TOPOCENTER" ) ) { - sor = AST__TPSOR; - - } else if( astChrMatch( cval, "LSR" ) || - astChrMatch( cval, "LSRK" ) ) { - sor = AST__LKSOR; - - } else if( astChrMatch( cval, "LSRD" ) ) { - sor = AST__LDSOR; - - } else if( astChrMatch( cval, "GALACTIC_CENTER" ) ) { - sor = AST__GLSOR; - - } else { - astAddWarning( this, 1, "Using 'HELIOCENTER' in place of " - "unsupported spectral reference position '%s' " - "found in an STC-S description.", "astRead", - status, cval ); - } - - } else { - astAddWarning( this, 2, "Spectral reference position defaulting to " - "'HELIOCENTER' in an STC-S description.", "astRead", - status ); - } - -/* If we got a ref pos, set the StdOfRest attribute in the SpecFrame. */ - if( sor != AST__BADSOR ) astSetStdOfRest( specfrm, sor ); - -/* Get the units. */ - if( !astMapGet0C( props, "UNIT", &cval ) ) cval = "Hz"; - - -/* Set the spectral system implied by the unit string. */ - if( !cval || !strcmp( cval, "Hz" ) || !strcmp( cval, "MHz" ) || - !strcmp( cval, "GHz" ) ) { - astSetSystem( specfrm, AST__FREQ ); - - } else if( !strcmp( cval, "m" ) || !strcmp( cval, "mm" ) || - !strcmp( cval, "um" ) || !strcmp( cval, "nm" ) || - !strcmp( cval, "Angstrom" ) ) { - astSetSystem( specfrm, AST__WAVELEN ); - - } else if( !strcmp( cval, "eV" ) || !strcmp( cval, "keV" ) || - !strcmp( cval, "MeV" ) ) { - astSetSystem( specfrm, AST__ENERGY ); - - } else if( astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Unsupported spectral " - "units (%s) found within an STC-S description.", - status, cval ); - } - -/* Set the units. */ - astSetUnit( specfrm, 0, cval ); - -/* Set the epoch */ - if( epoch != AST__BAD ) astSetEpoch( specfrm, epoch ); - -/* Create a suitable Region to describe the enclosure for the spectral - coords */ - if( astMapGet0D( props, "LOLIMIT", &lolim ) ) { - astMapGet0D( props, "HILIMIT", &hilim ); - spec_enc = (AstRegion *) astInterval( specfrm, &lolim, &hilim, - NULL, "", status ); - use_enc = 1; - } - -/* Create a suitable Region to describe the spectral coords contained within - the above enclosure. If any sub-phrase has no coordinate value, then - we cannot produce a PointList describing the complete coordinate set. */ - if( astMapGet0D( props, "SPECTRAL", &value ) ) { - spec_co = (AstRegion *) SinglePointList( (AstFrame *) specfrm, - &value, NULL, status); - } else { - use_co = 0; - } - -/* If no enclosure Region was created for the spectral sub-phrase, use a - copy of any coordinate region. This is because each sub-phrase needs - to have an enclosure of some sort if they are to be combined in parallel - into an enclose for the whole CmpFrame. */ - if( ! spec_enc && spec_co ) spec_enc = astCopy( spec_co ); - -/* Set the filling factor. */ - if( spec_enc && astMapGet0D( props, "FILLFACTOR", &fill ) ) { - astSetFillFactor( spec_enc, fill ); - } - - -/* Associate an uncertainty with the two Regions. */ - if( astMapGet1D( props, "DERROR", 2, &nval, vals ) ) { - if( nval > 1 ) { - astAddWarning( this, 1, "An STC-S spectral sub-phrase contains an " - "Error range. AST does not support error ranges " - "so the mid value will be used as the error.", - "astRead", status ); - vals[ 0 ] = 0.5*( vals[ 0 ] + vals[ 1 ] ); - } - - SetUnc( spec_enc, spec_co, (AstFrame *) specfrm, 0, 1.0, vals, 1, - status ); - } - -/* Free resources */ - props = astAnnul( props ); - specfrm = astAnnul( specfrm ); - } - - - - -/* If the STC-S description contained a redshift sub-phrase, get the KeyMap - containing the properties of the redshift sub-phrase, and then create AST - Regions describing the redshift coordinate value and its enclosing Region. */ - if( astMapGet0A( full_props, "REDSHIFT_PROPS", &obj ) ) { - props = (AstKeyMap *) obj; - -/* Create the default SpecFrame */ - redfrm = astSpecFrame( "Domain=REDSHIFT", status ); - -/* Get the REFPOS property from the KeyMap, and identify the corresponding - AST StdOfRest. */ - sor = AST__BADSOR; - if( astMapGet0C( props, "REFPOS", &cval ) ) { - - if( astChrMatch( cval, "GEOCENTER" ) ) { - sor = AST__GESOR; - - } else if( astChrMatch( cval, "BARYCENTER" ) ) { - sor = AST__BYSOR; - - } else if( astChrMatch( cval, "HELIOCENTER" ) ) { - sor = AST__HLSOR; - - } else if( astChrMatch( cval, "TOPOCENTER" ) ) { - sor = AST__TPSOR; - - } else if( astChrMatch( cval, "LSR" ) || - astChrMatch( cval, "LSRK" ) ) { - sor = AST__LKSOR; - - } else if( astChrMatch( cval, "LSRD" ) ) { - sor = AST__LDSOR; - - } else if( astChrMatch( cval, "GALACTIC_CENTER" ) ) { - sor = AST__GLSOR; - - } else { - astAddWarning( this, 1, "Using 'HELIOCENTER' in place of " - "unsupported redshift reference position '%s' " - "found in an STC-S description.", "astRead", - status, cval ); - } - - } else { - astAddWarning( this, 2, "Redshift reference position defaulting to " - "'HELIOCENTER' in an STC-S description.", "astRead", - status ); - } - -/* If we got a ref pos, set the StdOfRest attribute in the SpecFrame. */ - if( sor != AST__BADSOR ) astSetStdOfRest( redfrm, sor ); - -/* Get the redshift type. */ - if( !astMapGet0C( props, "TYPE", &type ) ) type = "REDSHIFT"; - -/* Now get the velocity definition, and set the equivalent SpecFrame - System value. AST only supports optical redshift, so report an error - or a warning for unsupported combinations. */ - if( astMapGet0C( props, "DOPPLERDEF", &cval ) ){ - - if( astChrMatch( cval, "OPTICAL" ) ) { - if( astChrMatch( type, "VELOCITY" ) ){ - astSetSystem( redfrm, AST__VOPTICAL ); - } else { - astSetSystem( redfrm, AST__REDSHIFT ); - } - - } else if( astChrMatch( cval, "RADIO" ) ) { - if( astChrMatch( type, "VELOCITY" ) ){ - astSetSystem( redfrm, AST__VRADIO ); - } else { - astSetSystem( redfrm, AST__REDSHIFT ); - astAddWarning( this, 1, "STC-S RADIO redshift not supported. " - "Assuming OPTICAL redshift instead.", "astRead", - status ); - } - - } else if( astChrMatch( cval, "RELATIVISTIC" ) ) { - if( astChrMatch( type, "VELOCITY" ) ){ - astSetSystem( redfrm, AST__VREL ); - } else { - astSetSystem( redfrm, AST__REDSHIFT ); - astAddWarning( this, 1, "STC-S RELATIVISTIC redshift not supported. " - "Assuming OPTICAL redshift instead.", "astRead", - status ); - } - - } else { - if( astChrMatch( type, "VELOCITY" ) ){ - astSetSystem( redfrm, AST__VOPTICAL ); - astAddWarning( this, 1, "Doppler velocity definition defaulting" - " to 'OPTICAL' in an STC-S description.", - "astRead", status ); - - } else { - astSetSystem( redfrm, AST__REDSHIFT ); - } - } - } - -/* Set the units. */ - if( astChrMatch( type, "VELOCITY" ) ){ - if( astMapGet0C( props, "UNIT", &cval ) ) { - astSetUnit( redfrm, 0, cval ); - } else { - astSetUnit( redfrm, 0, "km/s" ); - } - - } else if( astMapGet0C( props, "UNIT", &cval ) ) { - astAddWarning( this, 1, "Ignoring units (%s) specified for REDSHIFT " - "in an STC-S description.", "astRead", status, cval ); - } - -/* Set the epoch */ - if( epoch != AST__BAD ) astSetEpoch( redfrm, epoch ); - -/* Create a suitable Region to describe the enclosure for the redshift - coords */ - if( astMapGet0D( props, "LOLIMIT", &lolim ) ) { - astMapGet0D( props, "HILIMIT", &hilim ); - red_enc = (AstRegion *) astInterval( redfrm, &lolim, &hilim, - NULL, "", status ); - use_enc = 1; - } - -/* Create a suitable Region to describe the redshift coords contained within - the above enclosure. If any sub-phrase has no coordinate value, then - we cannot produce a PointList describing the complete coordinate set. */ - if( astMapGet0D( props, "REDSHIFT", &value ) ) { - red_co = (AstRegion *) SinglePointList( (AstFrame *) redfrm, - &value, NULL, status); - } else { - use_co = 0; - } - -/* If no enclosure Region was created for the redshift sub-phrase, use a - copy of any coordinate region. This is because each sub-phrase needs - to have an enclosure of some sort if they are to be combined in parallel - into an enclose for the whole CmpFrame. */ - if( ! red_enc && red_co ) red_enc = astCopy( red_co ); - -/* Set the filling factor. */ - if( red_enc && astMapGet0D( props, "FILLFACTOR", &fill ) ) { - astSetFillFactor( red_enc, fill ); - } - -/* Associate an uncertainty with the two Regions. */ - if( astMapGet1D( props, "DERROR", 2, &nval, vals ) ) { - if( nval > 1 ) { - astAddWarning( this, 1, "An STC-S redshift sub-phrase contains an " - "Error range. AST does not support error ranges " - "so the mid value will be used as the error.", - "astRead", status ); - vals[ 0 ] = 0.5*( vals[ 0 ] + vals[ 1 ] ); - } - - SetUnc( red_enc, red_co, (AstFrame *) redfrm, 0, 1.0, vals, 1, - status ); - } - -/* Free resources */ - props = astAnnul( props ); - redfrm = astAnnul( redfrm ); - } - -/* If a particular position was specified by the STC_S document, create the - full position from the individual sub-phrase position */ - if( use_co ) { - new = time_co ? astClone( time_co ) : NULL; - - if( space_co ) { - if( new ) { - tr = astPrism( new, space_co, "", status ); - (void) astAnnul( new ); - new = (AstObject *) tr; - } else { - new = astClone( space_co ); - } - } - - if( spec_co ) { - if( new ) { - tr = astPrism( new, spec_co, "", status ); - (void) astAnnul( new ); - new = (AstObject *) tr; - } else { - new = astClone( spec_co ); - } - } - - if( red_co ) { - if( new ) { - tr = astPrism( new, red_co, "", status ); - (void) astAnnul( new ); - new = (AstObject *) tr; - } else { - new = astClone( red_co ); - } - } - - if( new ) { - full_co = astSimplify( new ); - new = astAnnul( new ); - } else { - full_co = NULL; - } - - } else { - full_co = NULL; - } - -/* If an enclosing volume was specified by the STC_S document, create the - full enclosure Region from the individual sub-phrase enclosure Regions. */ - if( use_enc ) { - new = time_enc ? astClone( time_enc ) : NULL; - - if( space_enc ) { - if( new ) { - tr = astPrism( new, space_enc, "", status ); - (void) astAnnul( new ); - new = (AstObject *) tr; - } else { - new = astClone( space_enc ); - } - } - - if( spec_enc ) { - if( new ) { - tr = astPrism( new, spec_enc, "", status ); - (void) astAnnul( new ); - new = (AstObject *) tr; - } else { - new = astClone( spec_enc ); - } - } - - if( red_enc ) { - if( new ) { - tr = astPrism( new, red_enc, "", status ); - (void) astAnnul( new ); - new = (AstObject *) tr; - } else { - new = astClone( red_enc ); - } - } - full_enc = astSimplify( new ); - new = astAnnul( new ); - - } else { - full_enc = NULL; - } - -/* See which, and how many, items are to be returned. */ - nwant = 0; - if( ( want_enc = astGetStcsArea( this ) ) ) nwant++; - if( ( want_co = astGetStcsCoords( this ) ) ) nwant++; - if( ( want_props = astGetStcsProps( this ) ) ) nwant++; - -/* If one, and only one, of the three items is to be returned, return it. */ - new = NULL; - if( nwant == 1 ) { - if( want_enc && full_enc ) { - new = astClone( full_enc ); - } else if( want_co && full_co ) { - new = astClone( full_co ); - } else if( want_props && full_props ){ - new = astClone( full_props ); - } - -/* If more than one item is to be returned, put them into a KeyMap and - return the KeyMap. */ - } else if( nwant > 1 ) { - new = (AstObject *) astKeyMap( " ", status ); - if( want_enc && full_enc ) astMapPut0A( new, "AREA", full_enc, NULL ); - if( want_co && full_co ) astMapPut0A( new, "COORDS", full_co, NULL ); - if( want_props && full_props ) astMapPut0A( new, "PROPS", full_props, NULL ); - -/* Report an error if nothing is to be returned. */ - } else if( astOK ){ - astError( AST__ATTIN, "astRead(StcsChan): The StcsArea, StcsCoords " - "and StcsProps attributes indicate that nothing is to be " - "returned (possible programming error).", status ); - } - -/* Free resources */ - if( space_enc ) space_enc = astAnnul( space_enc ); - if( spec_enc ) spec_enc = astAnnul( spec_enc ); - if( time_enc ) time_enc = astAnnul( time_enc ); - if( red_enc ) red_enc = astAnnul( red_enc ); - if( space_co ) space_co = astAnnul( space_co ); - if( spec_co ) spec_co = astAnnul( spec_co ); - if( time_co ) time_co = astAnnul( time_co ); - if( red_co ) red_co = astAnnul( red_co ); - if( full_enc ) full_enc = astAnnul( full_enc ); - if( full_co ) full_co = astAnnul( full_co ); - if( full_props ) full_props = astAnnul( full_props ); - -/* If an error occurred, clean up by deleting the new Object and - return a NULL pointer. */ - if ( !astOK ) new = astDelete( new ); - -/* Return the pointer to the new Object. */ - return new; -} - -static AstKeyMap *ReadProps( AstStcsChan *this, int *status ) { -/* -* Name: -* ReadProps - -* Purpose: -* Read STC-S properties from the source and store in a KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* AstKeyMap *ReadProps( AstStcsChan *this, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function parses the list of space-separated words read from the -* source function, identifies the purpose of each word within the STC-S -* description, and stores the words in a returned KeyMap. - -* Parameters: -* this -* Pointer to the StcsChan. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new KeyMap. This will contain up to five entries -* with any or all of the following keys: TIME_PROPS, SPACE_PROPS, -* VELOCITY_PROPS, SPECTRAL_PROPS, REDSHIFT_PROPS. If an entry is absent, -* it means the STC-S description did not contain the corresponding -* sub-phrase. The value associated with each of these entries will be a -* KeyMap. These will contain values for the sub-phrase proprties read -* from the STC-S description. Properties that are not specified in -* the STC-S description will not be present in the KeyMap. The values -* stored in the KeyMap are the words read form the STC-S description -* without any conversion or other processing. -*/ - -/* Local Constants: */ -#define MAXVAL 6 - -/* Local Variables: */ - AstKeyMap *props; /* KeyMap holding current sub-phrase properties */ - AstKeyMap *result; /* Returned KeyMap holding all properties */ - AstTimeFrame *timefrm; /* Used for unformatting ISO date-times */ - WordContext con; /* Context for finding next source word */ - char *fbuf; /* Pointer to buffer holding document fragment */ - char *prop; /* String holding complete property value */ - const char *subphrase; /* Name of current sub phrase */ - const char *t; /* Temporary character string pointer */ - const char *word; /* Pointer to next source word */ - double val[ MAXVAL ]; /* Array of numerical property values */ - double start; /* Start time (MJD) */ - double stop; /* Stop time (MJD) */ - double time; /* Time value (MJD) */ - double value; /* Axis value */ - int iaxis; /* Axis index */ - int is_jd; /* Is time value a JD rather than an MJD? */ - int nunit; /* Number of units strings supplied */ - int nval; /* Number of numerical values read */ - int naxes; /* No. of space Frame axes */ - int nc; /* Number of characters written to string */ - int new_word; /* Get a new word at the end of the pass? */ - int redid; /* Redshift sub-phrase component identifier */ - int spaceid; /* Space sub-phrase component identifier */ - int specid; /* Spectral sub-phrase component identifier */ - int timeid; /* Time sub-phrase component identifier */ - int velid; /* Velocity sub-phrase component identifier */ - -/* The stage reached in the parsing of the STC-S description is indicated - by the "look_for" variable. This variable is allowed the following - values, indicating the item that is to be checked for next. */ - enum look_for_type { - ERROR, - FILL_FACTOR, - FLAVOUR, - FRAME, - LIMITS, - PIX_SIZE, - POSITION, - POSITION_INTERVAL, - REDSHIFT_IDENTIFIER, - RED_SPEC_LABEL, - RED_SPEC_VALUE, - REFPOS, - RESOLUTION, - SIZE, - SPACE_IDENTIFIER, - SPECTRAL_IDENTIFIER, - START, - STOP, - TIME, - TIME_IDENTIFIER, - TIME_LABEL, - TIME_SCALE, - TYPE_DOPPLER, - UNIT, - VELOCITY_IDENTIFIER, - VELOCITY - } look_for; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Create the returned KeyMap. */ - result = astKeyMap( " ", status ); - -/* Initialise the word search context. */ - (void) GetNextWord( NULL, &con, status ); - -/* Get a pointer to the first word in the STC-S description. */ - word = GetNextWord( this, &con, status ); - -/* Indicate we are currently looking for the time sub-phrase (the first - item in an STC-S description). */ - look_for = TIME_IDENTIFIER; - -/* Initialise everything else. */ - fbuf = NULL; - naxes = 0; - prop = NULL; - props = NULL; - redid = NULL_ID; - spaceid = NULL_ID; - specid = NULL_ID; - subphrase = NULL; - t = NULL; - timeid = NULL_ID; - velid = NULL_ID; - timefrm = NULL; - -/* Loop until all words in the STC-S description have been interpreted or - an error has occurred. */ - while( word && astOK ) { - -/* Initialise a flag to indicate that we have interpreted the current word - sucesfully and so will need to get a new word before the next pass through - this loop. If it turns out that we cannot interpret the current word - in this pass, then this flag will be set to zero at some point, thus - preventing a new word from being acquired and causing another attempt to - re-interpret the current word in a different context. */ - new_word = 1; - -/* If we are currently looking for the time sub-phrase, see if the current - word is any of the known time sub-phrase identifiers. Is so, move on - to read the associated sub-phrase component. */ - if( look_for == TIME_IDENTIFIER ) { -/* ------------------------------------------------------------------ */ - -/* Assume that we will be moving on to read the fill factor (most time - sub-phrases start with the fill factor ). */ - look_for = FILL_FACTOR; - -/* Now check the word to see if it a known time sub-phrase identifier. */ - if( astChrMatch( word, "TimeInterval" ) ) { - timeid = TIME_INTERVAL_ID; - - } else if( astChrMatch( word, "StartTime" ) ) { - timeid = START_TIME_ID; - - } else if( astChrMatch( word, "StopTime" ) ) { - timeid = STOP_TIME_ID; - - } else if( astChrMatch( word, "Time" ) ) { - look_for = TIME_SCALE; /* After "Time", we move on to find the - timeid = TIME_ID; time-scale, not the fill factor */ - -/* If the word is not a known time sub-phrase identifier, indicate that we - should attempt to re-interpret the current word as a space sub-phrase - identifier, rather than getting a new word. */ - } else { - look_for = SPACE_IDENTIFIER; - new_word = 0; - } - -/* If we have found a time sub-phrase identifier, create a KeyMap to hold - the properties of the time sub-phrase, and store the time sub-phrase - identifier in the new KeyMap. */ - if( timeid != NULL_ID ) { - subphrase = "time"; - props = astKeyMap( " ", status ); - astMapPut0A( result, "TIME_PROPS", props, NULL ); - astMapPut0C( props, "ID", word, NULL ); - naxes = 1; - } - - - -/* If we are currently looking for the space sub-phrase, see if the current - word is any of the known space sub-phrase identifiers. Is so, move on - to read the associated sub-phrase component. */ - } else if( look_for == SPACE_IDENTIFIER ) { -/* ------------------------------------------------------------------ */ - -/* Indicate we have finished any preceding time sub-phrase. */ - timeid = NULL_ID; - -/* Now check the word to see if it a known space sub-phrase identifier. */ - spaceid = SpaceId( word, status ); - -/* Decide what to look for next. */ - if( spaceid == POSITION_ID ) { - look_for = FRAME; - - } else if( spaceid != NULL_ID ) { - look_for = FILL_FACTOR; - -/* If the word is not a known space sub-phrase identifier, move on to - re-interpret it as a Spectral sub-phrase identifier. */ - } else { - look_for = SPECTRAL_IDENTIFIER; - new_word = 0; - } - -/* If we have found a space sub-phrase identifier, create a KeyMap to hold - the properties of the space sub-phrase, and store the space sub-phrase - identifier in the new KeyMap. */ - if( spaceid != NULL_ID ) { - subphrase = "space"; - if( props ) props = astAnnul( props ); - props = astKeyMap( " ", status ); - astMapPut0A( result, "SPACE_PROPS", props, NULL ); - astMapPut0C( props, "ID", word, NULL ); - } - - - -/* If we are currently looking for the velocity sub-phrase, see if the current - word is any of the known velocity sub-phrase identifiers. Is so, move on - to read the associated sub-phrase component. */ - } else if( look_for == VELOCITY_IDENTIFIER ) { -/* ------------------------------------------------------------------ */ - -/* Indicate we have finished any preceding space sub-phrase. */ - spaceid = NULL_ID; - -/* Now check the word to see if it a known velocity sub-phrase identifier. */ - if( astChrMatch( word, "VelocityInterval" ) ) { - velid = VELOCITY_INTERVAL_ID; - look_for = FILL_FACTOR; - - } else if( astChrMatch( word, "Velocity" ) ) { - velid = VELOCITY_ID; - look_for = VELOCITY; - -/* If the word is not a known velocity sub-phrase identifier, move on to - re-interpret it as a Spectral sub-phrase identifier. */ - } else { - look_for = SPECTRAL_IDENTIFIER; - new_word = 0; - } - -/* If we have found a velocity sub-phrase identifier, create a KeyMap to - hold the properties of the velocity sub-phrase, and store the velocity - sub-phrase identifier in the new KeyMap. */ - if( velid != NULL_ID ) { - subphrase = "velocity"; - if( props ) props = astAnnul( props ); - props = astKeyMap( " ", status ); - astMapPut0A( result, "VELOCITY_PROPS", props, NULL ); - astMapPut0C( props, "ID", word, NULL ); - } - - - -/* If we are currently looking for the spectral sub-phrase, see if the - word is any of the known spectral sub-phrase identifiers. Is so, move - on to read the associated sub-phrase component. */ - } else if( look_for == SPECTRAL_IDENTIFIER ) { -/* ------------------------------------------------------------------ */ - -/* Indicate we have finished any preceding velocity sub-phrase. */ - velid = NULL_ID; - -/* Now check the word to see if it a known spectral sub-phrase identifier. */ - if( astChrMatch( word, "SpectralInterval" ) ) { - look_for = FILL_FACTOR; /* Move on to find the fill factor */ - specid = SPECTRAL_INTERVAL_ID; - - } else if( astChrMatch( word, "Spectral" ) ) { - look_for = REFPOS; /* Move on to find the refpos */ - specid = SPECTRAL_ID; - -/* If the word is not a known spectral sub-phrase identifier, move on to - look for the Redshift sub-phrase. */ - } else { - look_for = REDSHIFT_IDENTIFIER; - new_word = 0; - } - -/* If we have found a spectral sub-phrase identifier, create a KeyMap to - hold the properties of the spectral sub-phrase, and store the spectral - sub-phrase identifier in the new KeyMap. */ - if( specid != NULL_ID ) { - subphrase = "spectral"; - if( props ) props = astAnnul( props ); - props = astKeyMap( " ", status ); - astMapPut0A( result, "SPECTRAL_PROPS", props, NULL ); - astMapPut0C( props, "ID", word, NULL ); - naxes = 1; - } - - - -/* If we are currently looking for the redshift sub-phrase, see if the - word is any of the known redshift sub-phrase identifiers. Is so, move - on to read the associated sub-phrase component. */ - } else if( look_for == REDSHIFT_IDENTIFIER ) { -/* ------------------------------------------------------------------ */ - -/* Indicate we have finished any preceding spectral sub-phrase. */ - specid = NULL_ID; - -/* Now check the word to see if it a known spectral sub-phrase identifier. */ - if( astChrMatch( word, "RedshiftInterval" ) ) { - look_for = FILL_FACTOR; /* Move on to find the fill factor */ - redid = REDSHIFT_INTERVAL_ID; - - } else if( astChrMatch( word, "Redshift" ) ) { - look_for = REFPOS; /* Move on to find the refpos */ - redid = REDSHIFT_ID; - -/* If the word is not a known redshift sub-phrase identifier, report a - warning. */ - } else if( word[ 0 ] && astOK ) { - astError( AST__BADIN, "astRead(%s): Unsupported or irrelevant " - "word '%s' found in STC-S %s sub-phrase: '%s'.", status, - astGetClass( this ), word, subphrase, - ContextFragment( &con, &fbuf, status ) ); - new_word = 0; - } - -/* If we have found a redshift sub-phrase identifier, create a KeyMap to - hold the properties of the redshift sub-phrase, and store the redshift - sub-phrase identifier in the new KeyMap. */ - if( redid != NULL_ID ) { - subphrase = "redshift"; - if( props ) props = astAnnul( props ); - props = astKeyMap( " ", status ); - astMapPut0A( result, "REDSHIFT_PROPS", props, NULL ); - astMapPut0C( props, "ID", word, NULL ); - naxes = 1; - } - -/* Indicate we can now end when we run out of input words. */ - con.done = 1; - - - -/* If we are currently looking for a fill factor... */ - } else if( look_for == FILL_FACTOR ) { -/* ------------------------------------------------------------------ */ - -/* If the current word is "fillfactor" attempt to read the numerical filling - factor from the next word. If this fails, or if the current word is - not "fillfactor", indicate that we will be re-interpreting the current - word in a new context and so do not need a new word. */ - if( astChrMatch( word, "fillfactor" ) ) { - word = GetNextWord( this, &con, status ); - if( astChr2Double( word ) == AST__BAD ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a numerical " - "filling factor, but found '%s' in the %s " - "sub-phrase of STC-S description: '%s'.", status, - word, subphrase, ContextFragment( &con, &fbuf, - status ) ); - new_word = 0; - } - } else { - new_word = 0; - } - -/* If we are reading a time sub-phrase, move on to read the timescale. */ - if( timeid != NULL_ID ) { - look_for = TIME_SCALE; - -/* If we are reading a space sub-phrase, move on to read the frame. */ - } else if( spaceid != NULL_ID ) { - look_for = FRAME; - -/* If we are reading a velocity sub-phrase, move on to read the limits. */ - } else if( velid != NULL_ID ) { - look_for = LIMITS; - -/* Otherwise (i.e. for spectral and redshift sub-phrases) move on to read - the refpos. */ - } else { - look_for = REFPOS; - } - -/* If the word was usable, record it as the fillfactor property. */ - if( new_word ) astMapPut0C( props, "FILLFACTOR", word, NULL ); - - - -/* If we are currently looking for a time scale... */ - } else if( look_for == TIME_SCALE ) { -/* ------------------------------------------------------------------ */ - -/* If the current word is a recognised STC-S timescale, store it in the - props KeyMap. Otherwise, indicate that the word can be re-used in the - next context. */ - if( astChrMatch( word, "TT" ) || - astChrMatch( word, "TDT" ) || - astChrMatch( word, "ET" ) || - astChrMatch( word, "TAI" ) || - astChrMatch( word, "IAT" ) || - astChrMatch( word, "UTC" ) || - astChrMatch( word, "TEB" ) || - astChrMatch( word, "TDB" ) || - astChrMatch( word, "TCG" ) || - astChrMatch( word, "TCB" ) || - astChrMatch( word, "LST" ) || - astChrMatch( word, "nil" ) ) { - - astMapPut0C( props, "TIMESCALE", word, NULL ); - - } else { - new_word = 0; - } - -/* Move on to look for a refpos */ - look_for = REFPOS; - - - -/* If we are currently looking for a space frame... */ - } else if( look_for == FRAME ) { -/* ------------------------------------------------------------------ */ - -/* If the current word is a recognised STC-S spatial frame, store it in - the props KeyMap. Otherwise, indicate that the word can be re-used. */ - if( astChrMatch( word, "ICRS" ) || - astChrMatch( word, "FK5" ) || - astChrMatch( word, "FK4" ) || - astChrMatch( word, "J2000" ) || - astChrMatch( word, "B1950" ) || - astChrMatch( word, "ECLIPTIC" ) || - astChrMatch( word, "GALACTIC" ) || - astChrMatch( word, "GALACTIC_II" ) || - astChrMatch( word, "SUPER_GALACTIC" ) || - astChrMatch( word, "GEO_C" ) || - astChrMatch( word, "GEO_D" ) || - astChrMatch( word, "UNKNOWNFrame" ) ) { - - astMapPut0C( props, "FRAME", word, NULL ); - - } else { - new_word = 0; - } - -/* Move on to look for a refpos */ - look_for = REFPOS; - - - -/* If we are currently looking for a refpos... */ - } else if( look_for == REFPOS ) { -/* ------------------------------------------------------------------ */ - -/* If the current word is a recognised STC-S reference position, store it in - the props KeyMap. Otherwise, indicate that the word can be re-used. The - first group of reference positions apply to all sub-phrases. */ - if( astChrMatch( word, "GEOCENTER" ) || - astChrMatch( word, "BARYCENTER" ) || - astChrMatch( word, "HELIOCENTER" ) || - astChrMatch( word, "TOPOCENTER" ) || - astChrMatch( word, "GALACTIC_CENTER" ) || - astChrMatch( word, "EMBARYCENTER" ) || - astChrMatch( word, "MOON" ) || - astChrMatch( word, "MERCURY" ) || - astChrMatch( word, "VENUS" ) || - astChrMatch( word, "MARS" ) || - astChrMatch( word, "JUPITER" ) || - astChrMatch( word, "SATURN" ) || - astChrMatch( word, "URANUS" ) || - astChrMatch( word, "NEPTUNE" ) || - astChrMatch( word, "PLUTO" ) || - astChrMatch( word, "UNKNOWNRefPos" ) ) { - - astMapPut0C( props, "REFPOS", word, NULL ); - -/* This group of reference positions apply only to spectral and redshift - sub-phrases. */ - } else if( astChrMatch( word, "LSR" ) || - astChrMatch( word, "LSRK" ) || - astChrMatch( word, "LSRD" ) || - astChrMatch( word, "LOCAL_GROUP_CENTER" ) ) { - - if( specid != NULL_ID || redid != NULL_ID ) { - astMapPut0C( props, "REFPOS", word, NULL ); - - } else if( astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Illegal reference " - "position '%s' found in the %s sub-phrase of " - "STC-S description: '%s'.", status, word, - subphrase, ContextFragment( &con, &fbuf, status ) ); - new_word = 0; - } - - } else { - new_word = 0; - } - -/* Choose what to look for next on the basis of the type of sub-phrase - currently being interpreted. */ - if( timeid == TIME_INTERVAL_ID ){ - look_for = START; /* Move on to find the start time */ - - } else if( timeid == START_TIME_ID ){ - look_for = START; /* Move on to find the start time */ - - } else if( timeid == STOP_TIME_ID ){ - look_for = STOP; /* Move on to find the stop time */ - - } else if( timeid == TIME_ID ){ - look_for = TIME; /* Move on to find the time */ - - } else if( spaceid != NULL_ID ){ - look_for = FLAVOUR; /* Move on to find the spatial flavour */ - - } else if( specid == SPECTRAL_INTERVAL_ID ) { - look_for = LIMITS; /* Move on to find the spectral limits */ - - } else if( specid == SPECTRAL_ID ) { - look_for = RED_SPEC_VALUE; /* Move on to find the spectral value */ - - } else if( redid == REDSHIFT_INTERVAL_ID ) { - look_for = TYPE_DOPPLER; /* Move on to find the redshift type */ - - } else if( redid == REDSHIFT_ID ) { - look_for = TYPE_DOPPLER; /* Move on to find the redshift type */ - - } else if( astOK ) { /* Should never happen */ - astError( AST__INTER, "astRead(StcsChan): Sanity check 1 fails in " - "function ReadProps (AST internal programming error).", - status ); - new_word = 0; - } - - - - - -/* If we are currently looking for a start time... */ - } else if( look_for == START ) { -/* ------------------------------------------------------------------ */ - -/* Save the current word as the start of the START value. */ - nc = 0; - prop = astAppendString( prop, &nc, word ); - -/* If the current word is "JD" or "MJD", the following word should be - numerical. */ - is_jd = astChrMatch( word, "JD" ); - if( is_jd || astChrMatch( word, "MJD" ) ) { - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - if( value == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected numerical " - "value in Start time, but found '%s %s' in STC-S " - "description: '%s'.", status, prop, word, - ContextFragment( &con, &fbuf, status ) ); - -/* Append the second word to the first word. */ - } else { - prop = astAppendString( prop, &nc, " " ); - prop = astAppendString( prop, &nc, word ); - } - -/* Convert JD to MJD if required. */ - start = is_jd ? value - 2400000.5 : value; - -/* Otherwise, the current word should be an ISO date. Use a TimeFrame - to check the string. */ - } else { - if( !timefrm ) timefrm = astTimeFrame( " ", status ); - if( !astUnformat( timefrm, 0, word, &start ) && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected ISO date " - "string Start time, but found '%s' in an STC-S " - "description: '%s'.", status, word, - ContextFragment( &con, &fbuf, status ) ); - } - } - -/* Record the START property. */ - astMapPut0C( props, "START", prop, NULL ); - astMapPut0D( props, "MJDSTART", start, NULL ); - -/* Decide what to do next. */ - if( timeid == TIME_INTERVAL_ID ){ - look_for = STOP; /* Move on to find the stop time */ - - } else if( timeid == START_TIME_ID ){ - look_for = TIME_LABEL; /* Move on to find the "coord" time */ - - } - - - -/* If we are currently looking for a stop time... */ - } else if( look_for == STOP ) { -/* ------------------------------------------------------------------ */ - -/* Save the current word as the start of the STOP value. */ - nc = 0; - prop = astAppendString( prop, &nc, word ); - -/* If the current word is "JD" or "MJD", the following word should be - numerical. */ - is_jd = astChrMatch( word, "JD" ); - if( is_jd || astChrMatch( word, "MJD" ) ) { - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - if( value == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected numerical " - "value in Stop time, but found '%s %s' in STC-S " - "description: '%s'.", status, prop, word, - ContextFragment( &con, &fbuf, status ) ); - -/* Append the second word to the first word. */ - } else { - prop = astAppendString( prop, &nc, " " ); - prop = astAppendString( prop, &nc, word ); - } - -/* Convert JD to MJD if required. */ - stop = is_jd ? value - 2400000.5 : value; - -/* Otherwise, the current word should be an ISO date. Use a TimeFrame - to check the string. */ - } else { - if( !timefrm ) timefrm = astTimeFrame( " ", status ); - if( !astUnformat( timefrm, 0, word, &stop ) && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected ISO date " - "string Stop time, but found '%s' in an STC-S " - "description: '%s'.", status, word, - ContextFragment( &con, &fbuf, status ) ); - } - } - -/* Record the STOP property. */ - astMapPut0C( props, "STOP", prop, NULL ); - astMapPut0D( props, "MJDSTOP", stop, NULL ); - -/* Move on to find the "coord" time. */ - look_for = TIME_LABEL; - - - -/* If we are currently looking for the label before a time coord value... */ - } else if( look_for == TIME_LABEL ) { -/* ------------------------------------------------------------------ */ - if( astChrMatch( word, "Time" ) ) { - look_for = TIME; - } else { - new_word = 0; - look_for = UNIT; - } - - - -/* If we are currently looking for a time... */ - } else if( look_for == TIME ) { -/* ------------------------------------------------------------------ */ - -/* Save the current word as the start of the TIME value. */ - nc = 0; - prop = astAppendString( prop, &nc, word ); - -/* If the current word is "JD" or "MJD", the following word should be - numerical. */ - is_jd = astChrMatch( word, "JD" ); - if( is_jd || astChrMatch( word, "MJD" ) ) { - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - if( value == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected numerical " - "value in Time value, but found '%s %s' in STC-S " - "description: '%s'.", status, prop, word, - ContextFragment( &con, &fbuf, status ) ); - -/* Append the second word to the first word. */ - } else { - prop = astAppendString( prop, &nc, " " ); - prop = astAppendString( prop, &nc, word ); - } - -/* Convert JD to MJD if required. */ - time = is_jd ? value - 2400000.5 : value; - -/* Otherwise, the current word should be an ISO date. Use a TimeFrame - to check the string. */ - } else { - if( !timefrm ) timefrm = astTimeFrame( " ", status ); - if( !astUnformat( timefrm, 0, word, &time ) && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected ISO date " - "string Time value, but found '%s' in an STC-S " - "description: '%s'.", status, word, - ContextFragment( &con, &fbuf, status ) ); - } - } - -/* Record the TIME property. */ - astMapPut0C( props, "TIME", prop, NULL ); - astMapPut0D( props, "MJDTIME", time, NULL ); - -/* Move on to look for the units. */ - look_for = UNIT; - - - -/* If we are currently looking for a space "flavor"... */ - } else if( look_for == FLAVOUR ) { -/* ------------------------------------------------------------------ */ - -/* If the current word is a recognised flavour value, note how many axis - values are required to specify a position. Otherwise, indicate that - the word can be re-used. */ - if( astChrMatch( word, "SPHER2" ) ) { - naxes = 2; - - } else if( astChrMatch( word, "UNITSPHER" ) ) { - naxes = 2; - - } else if( astChrMatch( word, "CART1" ) ) { - naxes = 1; - - } else if( astChrMatch( word, "CART2" ) ) { - naxes = 2; - - } else if( astChrMatch( word, "CART3" ) ) { - naxes = 3; - - } else if( astChrMatch( word, "SPHER3" ) ) { - naxes = 3; - - } else { - naxes = 2; - new_word = 0; - } - -/* If the word was recognised as a flavour, store it in the porperties - KeyMap. */ - if( new_word ) { - astMapPut0C( props, "FLAVOR", word, NULL ); - astMapPut0C( props, "FLAVOUR", word, NULL ); - } - -/* The next set of words to be read from the source function will specify - the arguments of the region enclosing the spatial positions. This may - contain nested regions, so use a recursive function to read the - arguments and store them in the properties KeyMap. */ - if( new_word ) word = GetNextWord( this, &con, status ); - word = ReadSpaceArgs( this, word, spaceid, naxes, &con, props, - status ); - new_word = 0; - -/* Move on to the next look_for (following the region argument list read - by ReadSpaceArgs). */ - if( spaceid == POSITION_ID ) { - look_for = UNIT; - } else { - look_for = POSITION; - } - - - -/* If we are currently looking for interval "lolimit"and "hilimit" ... */ - } else if( look_for == LIMITS ) { -/* ------------------------------------------------------------------ */ - if( velid != NULL_ID ) { - t = "velocity"; - look_for = VELOCITY; - - } else if( specid != NULL_ID ) { - t = "spectral"; - look_for = RED_SPEC_LABEL; - - } else { - t = "redshift"; - look_for = RED_SPEC_LABEL; - } - -/* The current word should be a numerical value (the low limit ). */ - if( astChr2Double( word ) == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a numerical " - "value for a %s lolimit, but found '%s' in an STC-S " - "description: '%s'.", status, t, word, - ContextFragment( &con, &fbuf, status ) ); - } else { - astMapPut0C( props, "LOLIMIT", word, NULL ); - } - -/* The next word should be a numerical value (the high limit ). */ - word = GetNextWord( this, &con, status ); - if( astChr2Double( word ) == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a numerical " - "value for a %s hilimit, but found '%s' in an STC-S " - "description: '%s'.", status, t, word, - ContextFragment( &con, &fbuf, status ) ); - } else { - astMapPut0C( props, "HILIMIT", word, NULL ); - } - - - -/* If we are currently looking for the label before a spectral or redshift - value... */ - } else if( look_for == RED_SPEC_LABEL ) { -/* ------------------------------------------------------------------ */ - if( specid != NULL_ID && astChrMatch( word, "Spectral" ) ) { - look_for = RED_SPEC_VALUE; - - } else if( redid != NULL_ID && astChrMatch( word, "Redshift" ) ) { - look_for = RED_SPEC_VALUE; - - } else { - new_word = 0; - look_for = UNIT; - } - - - -/* If we are currently looking for an spectral or redshift value. */ - } else if( look_for == RED_SPEC_VALUE ) { -/* ------------------------------------------------------------------ */ - - t = ( specid != NULL_ID ) ? "spectral" : "redshift"; - if( astChr2Double( word ) == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a numerical " - "%s value, but found '%s' in an STC-S " - "description: '%s'.", status, t, word, - ContextFragment( &con, &fbuf, status ) ); - } else { - astMapPut0C( props, ( specid != NULL_ID ) ? "SPECTRAL" : "REDSHIFT", - word, NULL ); - } - -/* Decide what to do next. */ - look_for = UNIT; - - - -/* If we are currently looking for information needed to create a spatial - Position ... */ - } else if( look_for == POSITION ) { -/* ------------------------------------------------------------------ */ - -/* Check the current word is "Position". If so, get the next word. */ - if( astChrMatch( word, "Position" ) ) { - word = GetNextWord( this, &con, status ); - -/* Get a value for every space axis. */ - nc = 0; - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - val[ iaxis ] = astChr2Double( word ); - if( val[ iaxis ] == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected another " - "axis value for a space Position, but found " - "'%s' in an STC-S description: '%s'.", status, - word, ContextFragment( &con, &fbuf, status ) ); - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, &con, status ); - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - prop[ nc - 1 ] = 0; - astMapPut0C( props, "POSITION", prop, NULL ); - astMapPut1D( props, "DPOSITION", naxes, val, NULL ); - } - -/* Move on to read the "unit" item. */ - new_word = 0; - look_for = UNIT; - - - -/* If we are currently looking for the redshift type and doppler - definition ... */ - } else if( look_for == TYPE_DOPPLER ) { -/* ------------------------------------------------------------------ */ - - if( astChrMatch( word, "VELOCITY" ) || - astChrMatch( word, "REDSHIFT" ) ) { - astMapPut0C( props, "TYPE", word, NULL ); - word = GetNextWord( this, &con, status ); - } - - if( astChrMatch( word, "OPTICAL" ) || - astChrMatch( word, "RADIO" ) || - astChrMatch( word, "RELATIVISTIC" ) ) { - astMapPut0C( props, "DOPPLERDEF", word, NULL ); - } else { - new_word = 0; - } - -/* Decide what to do next. */ - look_for = ( redid == REDSHIFT_INTERVAL_ID ) ? LIMITS : RED_SPEC_VALUE; - - - -/* If we are currently looking for a velocity label and value... */ - } else if( look_for == VELOCITY ) { -/* ------------------------------------------------------------------ */ - - if( astChrMatch( word, "Velocity" ) ) { - word = GetNextWord( this, &con, status ); - if( astChr2Double( word ) == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a " - "numerical Velocity value but found 'Velocity %s' " - "in an STC-S description: '%s'.", status, word, - ContextFragment( &con, &fbuf, status ) ); - } - - } else { - new_word = 0; - } - - look_for = UNIT; - - - -/* If we are currently looking for a "unit" string... */ - } else if( look_for == UNIT ) { -/* ------------------------------------------------------------------ */ - -/* See if the current word is "unit". If so, read the next word (which - will be the unit string itself). Otherwise, indicate the current word - can be re-used. */ - if( astChrMatch( word, "unit" ) ) { - word = GetNextWord( this, &con, status ); - } else { - new_word = 0; - } - -/* If we have a unit string... */ - if( new_word ) { - -/* Check that the unit string is one of the allowed values (different - values are allowed for different sub-phrases). Space frames can have - multiple units strings (one for each axis) so loop round until a string - is found which is not a valid unit string. */ - nc = 0; - nunit = 0; - while( ( timeid != NULL_ID && ( !strcmp( word, "s" ) || - !strcmp( word, "d" ) || - !strcmp( word, "a" ) || - !strcmp( word, "yr" ) || - !strcmp( word, "cy" ) ) ) || - - ( spaceid != NULL_ID && ( !strcmp( word, "deg" ) || - !strcmp( word, "arcmin" ) || - !strcmp( word, "arcsec" ) || - !strcmp( word, "m" ) || - !strcmp( word, "mm" ) || - !strcmp( word, "m" ) || - !strcmp( word, "km" ) || - !strcmp( word, "AU" ) || - !strcmp( word, "pc" ) || - !strcmp( word, "kpc" ) || - !strcmp( word, "Mpc" ) ) ) || - - ( velid != NULL_ID && ( !strcmp( word, "deg" ) || - !strcmp( word, "arcmin" ) || - !strcmp( word, "arcsec" ) || - !strcmp( word, "m" ) || - !strcmp( word, "mm" ) || - !strcmp( word, "km" ) || - !strcmp( word, "AU" ) || - !strcmp( word, "pc" ) || - !strcmp( word, "kpc" ) || - !strcmp( word, "Mpc" ) ) ) || - - ( !strcmp( word, "Hz" ) || - !strcmp( word, "MHz" ) || - !strcmp( word, "GHz" ) || - !strcmp( word, "m" ) || - !strcmp( word, "mm" ) || - !strcmp( word, "um" ) || - !strcmp( word, "nm" ) || - !strcmp( word, "Angstrom" ) || - !strcmp( word, "eV" ) || - !strcmp( word, "keV" ) || - !strcmp( word, "MeV" ) ) ) { - - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - nunit++; - word = GetNextWord( this, &con, status ); - } - -/* Report an error if an inappropriate number of valid unit strings was - found. */ - if( nunit == 0 && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Unsupported " - "units (%s) for the %s sub-phrase within an " - "STC-S description: '%s'.", status, word, subphrase, - ContextFragment( &con, &fbuf, status ) ); - - } else if( nunit != 1 && nunit != naxes && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Incorrect number of " - "units string (%d) supplied for the %s sub-phrase within an " - "STC-S description: '%s'.", status, nunit, subphrase, - ContextFragment( &con, &fbuf, status ) ); - -/* Otherwise, remove the trailing space, and store the property value in the - KeyMap. */ - } else { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "UNIT", prop, NULL ); - } - -/* The current word is the first word that was not a valid unit string, - and so can be re-used. */ - new_word = 0; - } - -/* Move on to find the errors. */ - look_for = ERROR; - - - -/* If we are currently looking for an "Error" string... */ - } else if( look_for == ERROR ) { -/* ------------------------------------------------------------------ */ - -/* If the current word is "Error" read all subsequent words until the first - non-numerical value is encountered. */ - if( astChrMatch( word, "Error" ) ) { - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - - nc = 0; - nval = 0; - while( value != AST__BAD ) { - if( nval < MAXVAL ) { - val[ nval++ ] = value; - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - } else { - astError( AST__BADIN, "astRead(StcsChan): Too many (more " - "than %d) numerical values found for the Error " - "property of the %s sub-phrase within an STC-S " - "description: '%s'.", status, MAXVAL, subphrase, - ContextFragment( &con, &fbuf, status ) ); - break; - } - } - -/* Report an error if no numerical error values were found. */ - if( nval == 0 && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a " - "numerical error value but found 'Error %s' " - "for the %s sub-phrase within an " - "STC-S description: '%s'.", status, word, subphrase, - ContextFragment( &con, &fbuf, status ) ); - -/* Otherwise, remove the trailing space and store the concatenated - string of formatted values in the properties KeyMap. Also store a - corresponding vector of floating point values in the KeyMap. */ - } else { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "ERROR", prop, NULL ); - astMapPut1D( props, "DERROR", nval, val, NULL ); - } - } - -/* Indicate that we do not need to get a new word (we can re-use the last - one that turned out not to be a numerical value above). */ - new_word = 0; - -/* Next look for Resolution */ - look_for = RESOLUTION; - - - -/* If we are currently looking for a "Resolution" string... */ - } else if( look_for == RESOLUTION ) { -/* ------------------------------------------------------------------ */ - -/* If the current word is "Resolution" read all subsequent words until the - first non-numerical value is encountered. */ - if( astChrMatch( word, "Resolution" ) ) { - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - - nc = 0; - nval = 0; - while( value != AST__BAD ) { - if( nval < MAXVAL ) { - val[ nval++ ] = value; - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - } else { - astError( AST__BADIN, "astRead(StcsChan): Too many (more " - "than %d) numerical values found for the Resolution " - "property of the %s sub-phrase within an STC-S " - "description: '%s'.", status, MAXVAL, subphrase, - ContextFragment( &con, &fbuf, status ) ); - break; - } - } - -/* Report an error if no numerical values were found. */ - if( nval == 0 && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a " - "numerical resolution value but found 'Resolution %s' " - "for the %s sub-phrase within an STC-S description:" - " '%s'.", status, word, subphrase, - ContextFragment( &con, &fbuf, status ) ); - -/* Otherwise, remove the trailing space and store the concatenated - string of formatted values in the properties KeyMap. Also store a - corresponding vector of floating point values in the KeyMap. */ - } else { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "RESOLUTION", prop, NULL ); - astMapPut1D( props, "DRESOLUTION", nval, val, NULL ); - } - } - -/* Indicate that we do not need to get a new word (we can re-use the last - one that turned out not to be a numerical value above). */ - new_word = 0; - -/* Next look for Size. */ - look_for = SIZE; - - - -/* If we are currently looking for a spatial "Size" string... */ - } else if( look_for == SIZE ) { -/* ------------------------------------------------------------------ */ - -/* If the current word is "Size" read all subsequent words until the - first non-numerical value is encountered. */ - if( astChrMatch( word, "Size" ) ) { - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - - nc = 0; - nval = 0; - while( value != AST__BAD ) { - if( nval < MAXVAL ) { - val[ nval++ ] = value; - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - } else { - astError( AST__BADIN, "astRead(StcsChan): Too many (more " - "than %d) numerical values found for the Size " - "property of the %s sub-phrase within an STC-S " - "description: '%s'.", status, MAXVAL, subphrase, - ContextFragment( &con, &fbuf, status ) ); - break; - } - } - -/* Report an error if no numerical values were found. */ - if( nval == 0 && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a " - "numerical size value but found 'Size %s' " - "for the %s sub-phrase within an STC-S description:" - " '%s'.", status, word, subphrase, - ContextFragment( &con, &fbuf, status ) ); - -/* Otherwise, remove the trailing space and store the concatenated - string of formatted values in the properties KeyMap. Also store a - corresponding vector of floating point values in the KeyMap. */ - } else { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "SIZE", prop, NULL ); - astMapPut1D( props, "DSIZE", nval, val, NULL ); - } - } - -/* Indicate that we do not need to get a new word (we can re-use the last - one that turned out not to be a numerical value above). */ - new_word = 0; - -/* Next look for PixSize. */ - look_for = PIX_SIZE; - - - -/* If we are currently looking for a "PixSize" string... */ - } else if( look_for == PIX_SIZE ) { -/* ------------------------------------------------------------------ */ - -/* If the current word is "PixSize" read all subsequent words until the - first non-numerical value is encountered. */ - if( astChrMatch( word, "PixSize" ) ) { - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - - nc = 0; - nval = 0; - while( value != AST__BAD ) { - if( nval < MAXVAL ) { - val[ nval++ ] = value; - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, &con, status ); - value = astChr2Double( word ); - } else { - astError( AST__BADIN, "astRead(StcsChan): Too many (more " - "than %d) numerical values found for the PixSize " - "property of the %s sub-phrase within an STC-S " - "description: '%s'.", status, MAXVAL, subphrase, - ContextFragment( &con, &fbuf, status ) ); - break; - } - } - -/* Report an error if no numerical values were found. */ - if( nval == 0 && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a " - "numerical pixel size but found 'PixSize %s' " - "for the %s sub-phrase within an STC-S description:" - " '%s'.", status, word, subphrase, - ContextFragment( &con, &fbuf, status ) ); - -/* Otherwise, remove the trailing space and store the concatenated - string of formatted values in the properties KeyMap. Also store a - corresponding vector of floating point values in the KeyMap. */ - } else { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "PIXSIZE", prop, NULL ); - astMapPut1D( props, "DPIXSIZE", nval, val, NULL ); - } - } - -/* Indicate that we do not need to get a new word (we can re-use the last - one that turned out not to be a numerical value above). */ - new_word = 0; - -/* Next look for the next sub-phrase. */ - if( timeid != NULL_ID ) { - look_for = SPACE_IDENTIFIER; - - } else if( spaceid != NULL_ID ) { - look_for = VELOCITY_IDENTIFIER; - - } else if( velid != NULL_ID ) { - look_for = SPECTRAL_IDENTIFIER; - - } else if( specid != NULL_ID ) { - look_for = REDSHIFT_IDENTIFIER; - - } else { - break; - } - - - - -/* Report an error for any unknown look_for. */ -/* ------------------------------------------------------------------ */ - } else if( astOK ) { - astError( AST__INTER, "astRead(StcsChan): Illegal look_for value " - "(%d) encountered (internal AST programming error).", - status, look_for ); - } - -/* If required, get the next word in the STC-S description. */ - if( new_word ) word = GetNextWord( this, &con, status ); - } - -/* Free resources stored in the GetNextWord context structure. */ - con.done = 1; - (void) GetNextWord( this, &con, status ); - FreeContext( &con, status ); - -/* Free other resources */ - if( fbuf ) fbuf = astFree( fbuf ); - if( prop ) prop = astFree( prop ); - if( props ) props = astAnnul( props ); - if( timefrm ) timefrm = astAnnul( timefrm ); - -/* If an error occurred, clean up by deleting the new Object and - return a NULL pointer. */ - if ( !astOK ) result = astDelete( result ); - -/* Return the pointer to the properties KeyMap. */ - return result; - -/* Undefine Local Constants: */ -#undef MAXVAL -} - -static const char *ReadSpaceArgs( AstStcsChan *this, const char *word, - int spaceid, int naxes, WordContext *con, - AstKeyMap *props, int *status ){ -/* -* Name: -* ReadSpaceArgs - -* Purpose: -* Read space region arguments from an STC-S description. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* const char *ReadSpaceArgs( AstStcsChan *this, const char *word, -* int spaceid, int naxes, WordContext *con, -* AstKeyMap *props, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function parses the list of space-separated words that form -* the argument list of a spatial region. These words are read from the -* source function, and stored in the supplied KeyMap using keys that -* identify their purpose. -* -* This function calls itself recursively to handle compound regions. - -* Parameters: -* this -* Pointer to the StcsChan. -* word -* The first word of the argument list. -* spaceid -* An integer identifier for the type of spatial region for which -* arguments are being read. -* naxes -* Number of axes in the space frame. -* con -* Pointer to a structure holding context for use with the -* GetNextWord function. On exit, the next word returned by the -* GetNextWord function will be the first word following the -* argument list. -* props -* Pointer to the KeyMap in which the argument values should be -* stored. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the next wpord to be interpreted. - -*/ - - -/* Local Variables: */ - AstKeyMap *new_props; /* KeyMap holding properties of an argument region */ - char *fbuf; /* Pointer to buffer holding document fragment */ - char *prop; /* String property value */ - char key[ 20 ]; /* Key for argument region */ - double *p; /* Pointer to next polygon vertex axis value */ - double *temp; /* Array of polygon vertex axis values */ - double val; /* Single numerical value */ - double vals[ 6 ]; /* List of numerical values */ - int iaxis; /* Axis index */ - int nc; /* Used length of string */ - int new_spaceid; /* Type of next argument region */ - int nreg; /* Number of argument regions found */ - int nvert; /* Number of vertices in polygon */ - -/* Check inherited status */ - if( !astOK ) return word; - -/* Initialise. */ - fbuf = NULL; - prop = NULL; - nc = 0; - -/* If we are looking for information needed to create a spatial - Interval... */ - if( spaceid == POSITION_INTERVAL_ID ) { - -/* Get a lolimit value for every space axis. */ - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vals[ iaxis ] = astChr2Double( word ); - if( vals[ iaxis ] == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected another " - "'lolimit' value for a PositionInterval, but found " - "'%s' in an STC-S description: '%s'.", status, word, - ContextFragment( con, &fbuf, status ) ); - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, con, status ); - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "LOLIMIT", prop, NULL ); - astMapPut1D( props, "DLOLIMIT", naxes, vals, NULL ); - } - -/* Get a hilimit value for every space axis. */ - nc = 0; - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vals[ iaxis ] = astChr2Double( word ); - if( vals[ iaxis ] == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected another " - "'hilimit' value for a PositionInterval, but found " - "'%s' in an STC-S description: '%s'.", status, word, - ContextFragment( con, &fbuf, status ) ); - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, con, status ); - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "HILIMIT", prop, NULL ); - astMapPut1D( props, "DLOLIMIT", naxes, vals, NULL ); - } - -/* If we are currently looking for information needed to create a spatial - AllSky ... */ - } else if( spaceid == ALLSKY_ID ) { - - - -/* If we are currently looking for information needed to create a spatial - Circle ... */ - } else if( spaceid == CIRCLE_ID ) { - -/* Get a centre value for every space axis. */ - nc = 0; - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vals[ iaxis ] = astChr2Double( word ); - if( vals[ iaxis ] == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected another " - "'centre' value for a Circle, but found " - "'%s' in an STC-S description: '%s'.", status, word, - ContextFragment( con, &fbuf, status ) ); - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, con, status ); - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "CENTRE", prop, NULL ); - astMapPut1D( props, "DCENTRE", naxes, vals, NULL ); - } - -/* Get the radius value. */ - val = astChr2Double( word ); - if( val == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a radius " - "value for a Circle, but found '%s' in an STC-S " - "description: '%s'.", status, word, - ContextFragment( con, &fbuf, status ) ); - } - -/* Store the property value in the KeyMap. */ - astMapPut0C( props, "RADIUS", word, NULL ); - -/* Get the next word. */ - word = GetNextWord( this, con, status ); - - - -/* If we are currently looking for information needed to create a spatial - Ellipse ... */ - } else if( spaceid == ELLIPSE_ID ) { - -/* Get a centre value for every space axis. */ - nc = 0; - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vals[ iaxis ] = astChr2Double( word ); - if( vals[ iaxis ] == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected another " - "centre value for an Ellipse, but found " - "'%s' in an STC-S description: '%s'.", status, word, - ContextFragment( con, &fbuf, status ) ); - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, con, status ); - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "CENTRE", prop, NULL ); - astMapPut1D( props, "DCENTRE", naxes, vals, NULL ); - } - -/* Get the first radius value . */ - val = astChr2Double( word ); - if( val == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected the first " - "radius value for an Ellipse, but found " - "'%s' in an STC-S description: '%s'.", status, word, - ContextFragment( con, &fbuf, status ) ); - } - -/* Store the property value in the KeyMap. */ - astMapPut0C( props, "RADIUS1", word, NULL ); - -/* Get the second radius value . */ - word = GetNextWord( this, con, status ); - val = astChr2Double( word ); - if( val == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected the second " - "radius value for an Ellipse, but found " - "'%s' in an STC-S description: '%s'.", status, word, - ContextFragment( con, &fbuf, status ) ); - } - -/* Store the property value in the KeyMap. */ - astMapPut0C( props, "RADIUS2", word, NULL ); - -/* Get the position angle value. */ - word = GetNextWord( this, con, status ); - val = astChr2Double( word ); - if( val == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected the position " - "angle value for an Ellipse, but found " - "'%s' in an STC-S description: '%s'.", status, word, - ContextFragment( con, &fbuf, status ) ); - } - -/* Store the property value in the KeyMap. */ - astMapPut0C( props, "POSANGLE", word, NULL ); - -/* Get the next word. */ - word = GetNextWord( this, con, status ); - - - -/* If we are currently looking for information needed to create a spatial - Box ... */ - } else if( spaceid == BOX_ID ) { - -/* Get a centre value for every space axis. */ - nc = 0; - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vals[ iaxis ] = astChr2Double( word ); - if( vals[ iaxis ] == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected another " - "centre value for a Box, but found " - "'%s' in an STC-S description: '%s'.", status, - word, ContextFragment( con, &fbuf, status ) ); - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, con, status ); - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "CENTRE", prop, NULL ); - astMapPut1D( props, "DCENTRE", naxes, vals, NULL ); - } - -/* Get bsize value for every space axis. */ - nc = 0; - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vals[ iaxis ] = astChr2Double( word ); - if( vals[ iaxis ] == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected another " - "'bsize' value for a Box, but found " - "'%s' in an STC-S description: '%s'.", status, - word, ContextFragment( con, &fbuf, status ) ); - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, con, status ); - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "BSIZE", prop, NULL ); - astMapPut1D( props, "DBSIZE", naxes, vals, NULL ); - } - - -/* If we are currently looking for information needed to create a spatial - Polygon ... */ - } else if( spaceid == POLYGON_ID ) { - -/* Read the first vertex into a dynamically allocated array. */ - temp = astMalloc( sizeof( *temp )*naxes ); - if( temp ) { - nc = 0; - p = temp; - for( iaxis = 0; iaxis < naxes; iaxis++,p++ ) { - val = astChr2Double( word ); - if( val == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected another " - "vertex value for a Polygon, but found " - "'%s' in an STC-S description: '%s'.", status, - word, ContextFragment( con, &fbuf, status ) ); - } else { - *p = val; - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, con, status ); - } - -/* Loop round reading remaining vertices, expanding the array as needed. */ - nvert = 1; - val = astChr2Double( word ); - while( val != AST__BAD && astOK ) { - - temp = astGrow( temp, naxes*( nvert + 1 ), sizeof( *temp ) ); - if( astOK ) { - p = temp + naxes*nvert; - - for( iaxis = 0; iaxis < naxes; iaxis++, p++ ) { - if( val == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected " - "another vertex value for a Polygon, but " - "found '%s' in an STC-S description: '%s'.", - status, word, ContextFragment( con, &fbuf, - status ) ); - } else { - *p = val; - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, con, status ); - val = astChr2Double( word ); - } - nvert++; - } - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "VERTICES", prop, NULL ); - astMapPut1D( props, "DVERTICES", naxes*nvert, temp, NULL ); - } - temp = astFree( temp ); - } - - - -/* If we are currently looking for information needed to create a spatial - Convex ... */ - } else if( spaceid == CONVEX_ID ) { - astError( AST__BADIN, "astRead(StcsChan): A Convex was found " - "within an STC-S description ('Convex' regions " - "are not yet supported by AST): %s", status, - ContextFragment( con, &fbuf, status ) ); - - - -/* If we are currently looking for information needed to create a spatial - Position ... */ - } else if( spaceid == POSITION_ID ) { - -/* Get a value for every space axis. */ - nc = 0; - for( iaxis = 0; iaxis < naxes; iaxis++ ) { - vals[ iaxis ] = astChr2Double( word ); - if( vals[ iaxis ] == AST__BAD && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected another " - "axis value for a space Position, but found " - "'%s' in an STC-S description: '%s'.", status, - word, ContextFragment( con, &fbuf, status ) ); - } - prop = astAppendString( prop, &nc, word ); - prop = astAppendString( prop, &nc, " " ); - word = GetNextWord( this, con, status ); - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( props, "POSITION", prop, NULL ); - astMapPut1D( props, "DPOSITION", naxes, vals, NULL ); - } - - -/* All remaining space id values require the argument list to be enclosed - in parentheses. Report an error if the current word does not start - with an opening parenthesis. */ - } else if( *word != '(' && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected an opening " - "parenthesis but found '%s' in an STC-S description: '%s'.", - status, word, ContextFragment( con, &fbuf, status ) ); - -/* Skip over the opening parenthesis. If the first word consists of just the - opening parenthesis, get the next word. */ - } else { - if( *(++word) == 0 ) word = GetNextWord( this, con, status ); - -/* Loop round all regions included in the compound region. */ - nreg = 0; - while( astOK ) { - -/* If the next word starts with a closing parenthesis, we have reached - the end of the argument list. */ - if( *word == ')' ) { - -/* Skip over the closing parenthesis. If the word consists of just the - closing parenthesis, get the next word. */ - if( *(++word) == 0 ) word = GetNextWord( this, con, status ); - -/* Leave the loop. */ - break; - } - -/* Identify the region type from the current word. */ - new_spaceid = SpaceId( word, status ); - if( new_spaceid == NULL_ID && astOK ) { - astError( AST__BADIN, "astRead(StcsChan): Expected a " - "CoordinateArea or a closing parenthesis but found " - "'%s' in an STC-S description: '%s'.", status, word, - ContextFragment( con, &fbuf, status ) ); - } - -/* Create a new KeyMap to store the properties of the new region. Store - this new KeyMap in the supplied KeyMap using a key of the form - "REGION". */ - new_props = astKeyMap( " ", status ); - astMapPut0C( new_props, "ID", word, NULL ); - sprintf( key, "REGION%d", ++nreg ); - astMapPut0A( props, key, new_props, NULL ); - -/* Get the next word (i.e. the first word of the argument list for the - region). */ - word = GetNextWord( this, con, status ); - -/* Call this function recursively to read the argument list. */ - word = ReadSpaceArgs( this, word, new_spaceid, naxes, con, - new_props, status ); - -/* Free resources. */ - new_props = astAnnul( new_props ); - } - -/* Store the number of regions in the supplied KeyMap. */ - astMapPut0I( props, "NREG", nreg, NULL ); - -/* Report an error if an in appropriate number of argument Regions were - supplied. */ - if( spaceid == UNION_ID ) { - if( nreg < 2 && astOK ){ - astError( AST__BADIN, "astRead(StcsChan): Less than two " - "CoordinateAreas found within a 'Union' element in an " - "STC-S description: '%s'.", status, - ContextFragment( con, &fbuf, status ) ); - } - - } else if( spaceid == INTERSECTION_ID ) { - if( nreg < 2 && astOK ){ - astError( AST__BADIN, "astRead(StcsChan): Less than two " - "CoordinateAreas found within an 'Intersection' element " - "in an STC-S description: '%s'.", status, - ContextFragment( con, &fbuf, status ) ); - } - - } else if( spaceid == DIFFERENCE_ID ) { - if( nreg != 2 && astOK ){ - astError( AST__BADIN, "astRead(StcsChan): %d CoordinateArea(s) " - "found within a 'Difference' element in an STC-S " - "description: '%s'.", status, nreg, - ContextFragment( con, &fbuf, status ) ); - } - - - } else if( spaceid == NOT_ID ) { - if( nreg != 1 && astOK ){ - astError( AST__BADIN, "astRead(StcsChan): %d CoordinateAreas " - "found within a 'Not' element in an STC-S description: " - "'%s'.", status, nreg, - ContextFragment( con, &fbuf, status ) ); - } - -/* Report an error for unknown spaceid values */ - } else if( astOK ) { - astError( AST__INTER, "astRead(StcsChan): Illegal 'spaceid' value " - "passed to function ReadSpaceArgs (internal AST " - "programming error).", status ); - } - } - -/* Free resources */ - if( prop ) prop = astFree( prop ); - -/* Return a pointer to the next word to be interpreted. */ - return word; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a StcsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* StcsChan member function (over-rides the astSetAttrib protected -* method inherited from the Channel class). - -* Description: -* This function assigns an attribute value for a StcsChan, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the StcsChan. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstStcsChan *this; /* Pointer to the StcsChan structure */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by "astSscanf" */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the StcsChan structure. */ - this = (AstStcsChan *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* StcsArea. */ -/* --------- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "stcsarea= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetStcsArea( this, ival ); - -/* StcsCoords. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "stcscoords= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetStcsCoords( this, ival ); - -/* StcsProps. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "stcsprops= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetStcsProps( this, ival ); - -/* StcsLength */ -/* ----------*/ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "stcslength= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetStcsLength( this, ival ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetUnc( AstRegion *reg1, AstRegion *reg2, AstFrame *frm, - int is_skyframe, double scale, double *error, int nax, - int *status ){ -/* -* Name: -* SetUnc - -* Purpose: -* Store an uncertainty Box with a supplied Region. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* void SetUnc( AstRegion *reg1, AstRegion *reg2, AstFrame *frm, -* int is_skyframe, double scale, double *error, int nax, -* int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function creates a new Box with dimensions specified by the -* values in the "error" array, centred on a representative position -* within one of the supplied Regions, and then stores the Box as the -* uncertainty Region within both the supplied Regions. - -* Parameters: -* reg1 -* Pointer to a Region to which the error values relate. -* reg2 -* Pointer to another Region to which the error values relate. -* frm -* Pointer to the Frame encapsulated by both Regions. -* is_skyframe -* Should be non-zero if "frm" is a SkyFrame. -* scale -* A scale factor to apply to the error values before using them. -* error -* Pointer to an array of RMS error values, one for each axis in -* "frm". These are modified on exit. For a SkyFrame, both values -* (including the longitude axis value) should be given as an -* arc-distance. This function will convert the arc-distance to -* a longitude increment using a representative latitude for the -* region. -* nax -* The numner of axes in "frm". -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstBox *unc; /* Uncertainty box */ - double dist; /* Diagonal length of Region bounding box */ - double lbnd[ 6 ]; /* Lower bounds of Region bounding box */ - double spos1[ 6 ]; /* A representative position in the Region */ - double spos2[ 6 ]; /* A second position in the Region */ - double ubnd[ 6 ]; /* Upper bounds of Region bounding box */ - int i; /* Axis index */ - -/* Check the global error status. Also check an error value was supplied, - and at least one of the Region pointers is not NULL. */ - if ( !astOK || error[ 0 ] == AST__BAD || ( !reg1 && !reg2 ) ) return; - -/* We need a representative position within the region. First get the - coordinates at opposite corners of the region bounding box. */ - astRegBaseBox( reg1 ? reg1 : reg2, lbnd, ubnd ); - -/* Find the diagonal length of the bounding box. */ - dist = astDistance( frm, lbnd, ubnd ); - -/* Offset away from one corner towards the other by half the diagonal - length. The resulting position returned in spos1 is our representative - position for the region. */ - astOffset( frm, lbnd, ubnd, dist/2, spos1 ); - -/* Scale the error values */ - for( i = 0; i < nax; i++ ) error[ i ] *= scale; - -/* If the region is defined within a SkyFrame, the supplied longitude - error value will be an arc-distance value. But we need a longitude - increment to create an uncertainty Region, so do the conversion. */ - if( is_skyframe ) { - -/* Offset away from the representative position found above along the - first (i.e. longitude) axis by an arc-distance given by the Error - value. */ - (void) astOffset2( frm, spos1, AST__DPIBY2, error[ 0 ], spos2 ); - -/* Find the positive axis increment along the first axis. */ - error[ 0 ] = astAxDistance( frm, 1, spos1[ 0 ], spos2[ 0 ] ); - if( error[ 0 ] != AST__BAD ) error[ 0 ] = fabs( error[ 0 ] ); - } - -/* The uncertainty Region will be a Box centred at the representative - position found above. Modify the "error" array to hold the corner - axis values. */ - for( i = 0; i < nax; i++ ) error[ i ] += spos1[ i ]; - -/* Create the box, and store it as the uncertainty Region in the supplied - Region. */ - unc = astBox( frm, 0, spos1, error, NULL, " ", status ); - if( reg1 ) astSetUnc( reg1, unc ); - if( reg2 ) astSetUnc( reg2, unc ); - -/* Free resources. */ - unc = astAnnul( unc ); -} - -static AstPointList *SinglePointList( AstFrame *frm, double *pos, - AstRegion *unc, int *status){ -/* -* Name: -* SinglePointList - -* Purpose: -* Create a PointList holding a single point. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* AstPointList *SinglePointList( AstFrame *frm, double *pos, -* AstRegion *unc, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function creates a new PointList holding a single supplied -* position. - -* Parameters: -* frm -* Pointer to the Frame in which the PointList is defined. -* pos -* Array holding the position. The length of this array must equal -* the number of axes in "frm". -* unc -* Pointer to an uncertainty Region to associate with the new -* PointList, or NULL. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new PointList. NULL is returned if an error has -* already occurred, of if this function fails for any reason. -*/ - -/* Local Variables: */ - AstPointList *result; /* Returned pointer. */ - AstPointSet *pset; /* PointSet holding axis values */ - double **ptr; /* Pointer to PointSet data arrays */ - int i; /* Axis index */ - int nax; /* Number of axes */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get he number of axes. */ - nax = astGetNaxes( frm ); - -/* Create a PointSet to hold the supplied point, and get a pointer to its - data arrays. */ - pset = astPointSet( 1, nax, "", status ); - ptr = astGetPoints( pset ); - if( astOK ) { - -/* Copy the supplied axis values into the PointSet data arrays. */ - for( i = 0; i < nax; i++ ) ptr[ i ][ 0 ] = pos[ i ]; - -/* Create the PointList. */ - result = astPointList( frm, pset, unc, "", status ); - } - -/* Free resources */ - pset = astAnnul( pset ); - -/* Return the result. */ - return result; -} - -static void SinkWrap( void (* sink)( const char * ), const char *line, int *status ) { -/* -* Name: -* SinkWrap - -* Purpose: -* Wrapper function to invoke a C StcsChan sink function. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* void SinkWrap( void (* sink)( const char * ), const char *line, int *status ) - -* Class Membership: -* StcsChan member function. - -* Description: -* This function invokes the sink function whose pointer is -* supplied in order to write an output line to an external data -* store. - -* Parameters: -* sink -* Pointer to a sink function, whose single parameter is a -* pointer to a const, null-terminated string containing the -* text to be written, and which returns void. This is the form -* of StcsChan sink function employed by the C language interface -* to the AST library. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the sink function. */ - ( *sink )( line ); -} - -static char *SourceWrap( const char *(* source)( void ), int *status ) { -/* -* Name: -* SourceWrap - -* Purpose: -* Wrapper function to invoke a C StcsChan source function. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* char *SourceWrap( const char *(* source)( void ), int *status ) - -* Class Membership: -* StcsChan member function. - -* Description: -* This function invokes the source function whose pointer is -* supplied in order to read the next input line from an external -* data store. It then returns a pointer to a dynamic string -* containing a copy of the text that was read. - -* Parameters: -* source -* Pointer to a source function, with no parameters, that -* returns a pointer to a const, null-terminated string -* containing the text that it read. This is the form of StcsChan -* source function employed by the C language interface to the -* AST library. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated, null terminated string -* containing a copy of the text that was read. This string must be -* freed by the caller (using astFree) when no longer required. -* -* A NULL pointer will be returned if there is no more input text -* to read. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - char *result; /* Pointer value to return */ - const char *line; /* Pointer to input line */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the source function to read the next input line and return a - pointer to the resulting string. */ - line = ( *source )(); - -/* If a string was obtained, make a dynamic copy of it and save the - resulting pointer. */ - if ( line ) result = astString( line, (int) strlen( line ) ); - -/* Return the result. */ - return result; -} - -static int SpaceId( const char *word, int *status ){ -/* -* Name: -* SpaceId - -* Purpose: -* Return the integer identifier for a given textual space identifier. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* int SpaceId( const char *word, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function returns an integer identifier for the given space -* identifier. - -* Parameters: -* word -* The word holding the textual space identifier. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The integer space identifier, or NULL_ID if the supplied word was -* not a known space identifier. - -*/ - - -/* Local Variables: */ - int spaceid; /* Returned identifier */ - -/* Check inherited status */ - if( !astOK ) return NULL_ID; - - if( astChrMatch( word, "PositionInterval" ) ) { - spaceid = POSITION_INTERVAL_ID; - - } else if( astChrMatch( word, "AllSky" ) ) { - spaceid = ALLSKY_ID; - - } else if( astChrMatch( word, "Circle" ) ) { - spaceid = CIRCLE_ID; - - } else if( astChrMatch( word, "Ellipse" ) ) { - spaceid = ELLIPSE_ID; - - } else if( astChrMatch( word, "Box" ) ) { - spaceid = BOX_ID; - - } else if( astChrMatch( word, "Polygon" ) ) { - spaceid = POLYGON_ID; - - } else if( astChrMatch( word, "Convex" ) ) { - spaceid = CONVEX_ID; - - } else if( astChrMatch( word, "Union" ) ) { - spaceid = UNION_ID; - - } else if( astChrMatch( word, "Intersection" ) ) { - spaceid = INTERSECTION_ID; - - } else if( astChrMatch( word, "Difference" ) ) { - spaceid = DIFFERENCE_ID; - - } else if( astChrMatch( word, "Not" ) ) { - spaceid = NOT_ID; - - } else if( astChrMatch( word, "Position" ) ) { - spaceid = POSITION_ID; - - } else { - spaceid = NULL_ID; - } - -/* Return the integer space identifier. */ - return spaceid; -} - -static void StoreTimeProp( AstKeyMap *props, AstTimeFrame *frm, - const char *key, double value, int *status ){ -/* -* Name: -* StoreTimeProp - -* Purpose: -* Store a time value as an STC-S property, using the existing format. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* void StoreTimeProp( AstKeyMap *props, AstTimeFrame *frm, -* const char *key, double value, int *status ) - -* Class Membership: -* StcsChan member function. - -* Description: -* This function formats the supplied time value and stores it in -* the "props" KeyMap, using the supplied key name. If the KeyMap -* already contains an entry for the given key, the new value is -* written using the same format. Otherwise, the new value is written -* as an ISO date and time string. - -* Parameters: -* props -* Pointer to the KeyMap in which to store the time value. -* frm -* Pointer to a TimeFrame that can be used to format the time value. -* key -* Pointer to a string holding the property name associated with -* the time value. -* value -* The time value, in the system described by "frm". -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstFrame *fmtfrm; /* Frame defining Format/System for formatted value */ - AstFrame *fs; /* FrameSet connecting Frames */ - const char *fmttxt; /* Formatted text */ - const char *oldval; /* Pointer to old formatted time value */ - const char *p; /* Pointer to next character in formatted value */ - double fmtval; /* The time value in the formatting system */ - int ndp; /* Number of decimal places in formatted value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* We want a TimeFrame (fmtfrm) that describes how to format the time - value. If the Format attribute of the supplied TimeFrame has been - set, use it (and the current System). So just take a clone of the - supplied frame pointer. */ - if( astTestFormat( frm, 0 ) ) { - fmtfrm = astClone( frm ); - -/* If the Format attribute has not been set, we create a copy of the - supplied TimeFrame, and set its System and Format attributes to - produce the required format. */ - } else { - fmtfrm = astCopy( frm ); - -/* If the KeyMap contains an entry for the specified key, determine the - format of the time string it contains. */ - if( astMapGet0C( props, key, &oldval ) && oldval ) { - -/* See how many digits there are after the decimal place */ - p = strchr( oldval, '.' ); - ndp = 0; - if( p ) { - while( *(++p) ) { - if( isdigit( *p ) ) { - ndp++; - } else { - break; - } - } - } - -/* If the string starts with "JD", the time is formatted as a numerical - Julian date. */ - if( !strncmp( oldval, "JD", 2 ) ) { - astSetSystem( fmtfrm, AST__JD ); - if( ndp > 0 ) { - astSet( fmtfrm, "Format=JD %%.%df", status, ndp ); - } else { - astSetFormat( fmtfrm, 0, "JD %d" ); - } - -/* If the string starts with "MJD", the time is formatted as a numerical - Modified Julian date. */ - } else if( !strncmp( oldval, "MJD", 3 ) ) { - astSetSystem( fmtfrm, AST__MJD ); - if( ndp > 0 ) { - astSet( fmtfrm, "Format=MJD %%.%df", status, ndp ); - } else { - astSetFormat( fmtfrm, 0, "MJD %d" ); - } - -/* Otherwise, the current word should be an ISO date. See how many - decimal paces in the seconds field there are (if any). */ - } else { - astSet( fmtfrm, "Format=iso.%dT", status, ndp ); - } - -/* If the KeyMap does not contain an entry for the specified key, an - ISO date/time string with 1 decimal place in the seconds field - is used. */ - } else { - astSetFormat( fmtfrm, 0, "iso.1T" ); - } - } - -/* Ensure the displayed value is an abolute value. */ - astClearTimeOrigin( fmtfrm ); - -/* Convert the supplied time value into the required system. */ - fs = astConvert( frm, fmtfrm, "" ); - astTran1( fs, 1, &value, 1, &fmtval ); - -/* Format the value. */ - fmttxt = astFormat( fmtfrm, 0, fmtval ); - -/* Store it in the KeyMap. */ - astMapPut0C( props, key, fmttxt, NULL ); - -/* Free resources. */ - fs = astAnnul( fs ); - fmtfrm = astAnnul( fmtfrm ); -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a StcsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* StcsChan member function (over-rides the astTestAttrib protected -* method inherited from the Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a StcsChan's attributes. - -* Parameters: -* this -* Pointer to the StcsChan. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstStcsChan *this; /* Pointer to the StcsChan structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the StcsChan structure. */ - this = (AstStcsChan *) this_object; - -/* Check the attribute name and test the appropriate attribute. */ - - if ( !strcmp( attrib, "stcsarea" ) ) { - result = astTestStcsArea( this ); - - } else if ( !strcmp( attrib, "stcscoords" ) ) { - result = astTestStcsCoords( this ); - - } else if ( !strcmp( attrib, "stcsprops" ) ) { - result = astTestStcsProps( this ); - - } else if ( !strcmp( attrib, "stcslength" ) ) { - result = astTestStcsLength( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static int Write( AstChannel *this_channel, AstObject *object, int *status ) { -/* -* Name: -* Write - -* Purpose: -* Write an Object to a StcsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* int Write( AstChannel *this, AstObject *object, int *status ) - -* Class Membership: -* StcsChan member function (over-rides the astWrite method -* inherited from the Channel class). - -* Description: -* This function writes an Object to a StcsChan. - -* Parameters: -* this -* Pointer to the StcsChan. -* object -* Pointer to the Object which is to be written. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of Objects written to the StcsChan by this invocation of -* astWrite. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the AST error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstFrame *frm; /* AREA Frame */ - AstFrameSet *fs; /* FrameSet connecting AREA and COORDS */ - AstKeyMap *props; /* A KeyMap holding the STC-S properties list */ - AstMapping *map; /* Mapping connecting AREA and COORDS */ - AstObject *obj; /* A temporary Object pointer */ - AstRegion *area; /* The Region representing the STC CoordArea */ - AstRegion *coords; /* The Region representing the STC Coords */ - AstRegion *new_coords; /* COORDS Region mapped into frame of AREA */ - AstStcsChan *this; /* Pointer to the StcsChan structure */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - const char *class; /* Pointer to string holding object class */ - const char *errclass; /* Type of the failed entry */ - const char *errname; /* Name of the failed entry */ - const char *method; /* Pointer to string holding calling method */ - const char *wantclass; /* The expected type */ - int ret; /* Number of objects read */ - -/* Initialise. */ - ret = 0; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_channel); - -/* Obtain a pointer to the StcsChan structure. */ - this = (AstStcsChan *) this_channel; - -/* Store the calling method, and object class. */ - method = "astWrite"; - class = astGetClass( this ); - -/* Initialise */ - area = NULL; - coords = NULL; - props = NULL; - -/* If the supplied Object is a Region, we will use it to define the AREA - properties. */ - if( astIsARegion( object ) ) { - area = (AstRegion *) astClone( object ); - -/* If the supplied Object is a KeyMap... */ - } else if( astIsAKeyMap( object ) ) { - errname = NULL; - wantclass = NULL; - errclass = NULL; - -/* If the supplied KeyMap contains an entry with key "AREA", and if it is - a Region, use it to define the AREA properties. */ - if( astMapGet0A( (AstKeyMap *) object, "AREA", &obj ) ) { - if( astIsARegion( obj ) ) { - area = (AstRegion *) obj; - } else { - wantclass = "Region"; - errclass = astGetClass( obj ); - errname = "AREA"; - obj = astAnnul( obj ); - } - } - -/* If the supplied KeyMap contains an entry with key "COORDS", and if it is - a Region, use it to define the COORDS properties. */ - if( astMapGet0A( (AstKeyMap *) object, "COORDS", &obj ) ) { - if( astIsARegion( obj ) ) { - coords = (AstRegion *) obj; - } else { - wantclass = "Region"; - errclass = astGetClass( obj ); - errname = "COORDS"; - obj = astAnnul( obj ); - } - } - -/* If the supplied KeyMap contains an entry with key "PROPS", and if it is - a KeyMap, use it to define values for the properties that cannot be - determined from the supplied Regions (Resolution, PixSize, etc). */ - if( astMapGet0A( (AstKeyMap *) object, "PROPS", &obj ) ) { - if( astIsAKeyMap( obj ) ) { - props = (AstKeyMap *) obj; - } else { - wantclass = "KeyMap"; - errclass = astGetClass( obj ); - errname = "PROPS"; - obj = astAnnul( obj ); - } - } - -/* If the supplied KeyMap contains an entry with any of the keys - "TIME_PROPS", "SPACE_PROPS", "SPECTRAL_PROPS" or "REDSHIFT_PROPS", - use the supplied KeyMap to define values for all properties. */ - if( astMapGet0A( (AstKeyMap *) object, "TIME_PROPS", &obj ) || - astMapGet0A( (AstKeyMap *) object, "SPACE_PROPS", &obj ) || - astMapGet0A( (AstKeyMap *) object, "SPECTRAL_PROPS", &obj ) || - astMapGet0A( (AstKeyMap *) object, "REDSHIFT_PROPS", &obj ) ) { - props = astClone( object ); - } - -/* Report an error if the Object in the keymap has the wrong type. */ - if( errname && astOK ) { - astAddWarning( this, 1, "The supplied KeyMap contains a %s " - "called '%s'. But '%s' should be a %s " - "(programming error).", method, status, - errclass, errname, errname, wantclass ); - } - -/* Report an error if the keymap contains none of the above. */ - if( !area && !coords && !props && astOK ) { - astAddWarning( this, 1, "The supplied KeyMap does not " - "contains anything that can be written out " - "through a %s.", method, status, class ); - } - -/* If both COORDS and AREA were supplied, ensure they are in the same - Frame by mapping the COORDS Region into the Frame of the AREA Region. */ - if( area && coords ) { - fs = astConvert( coords, area, " " ); - if( fs ) { - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - frm = astGetFrame( fs, AST__CURRENT ); - - new_coords = astMapRegion( coords, map, frm ); - - map = astAnnul( map ); - frm = astAnnul( frm ); - coords = astAnnul( coords ); - fs = astAnnul( fs ); - - coords = new_coords; - - } else if( astOK ){ - astAddWarning( this, 1, "Cannot convert between the co-ordinate " - "frame of the COORDS Region and the co-ordinate " - "frame of the AREA Region.", method, status ); - } - } - -/* Report an error if the supplied object is neither a KeyMap nor a - Region. */ - } else if( astOK ) { - astAddWarning( this, 1, "Failed to write out a %s through a %s. " - "The %s class cannot be used to write out a %s.", - method, status, astGetClass( object ), class, class, - astGetClass( object ) ); - } - - -/* If we do not have a KeyMap in which to store the STC-S properties, - create one now. */ - if( astOK ) { - if( ! props ) props = astKeyMap ( " ", status ); - -/* Determine the set of STC-S properties that describe the COORDS Region, - and add them into the properties keymap, over-writing any values for the - same properties that are already in the props keymap. */ - ret = coords ? WriteRegion( this, coords, props, status ) : 1; - -/* Determine the set of STC-S properties that describe the AREA Region, - and add them into the properties keymap, over-writing any values for the - same properties that are already in the props keymap. NB, we need to - do AREA after COORDS so that the sub-phrase identifier implied by the - AREA is used in preference to that implied by the COORDS. */ - if( area && ret ) ret = WriteRegion( this, area, props, status ); - -/* Convert the properties list into text and write it out through the - parent Channel's sink function. */ - if( ret ) WriteProps( this, props, status ); - } - -/* Free resources. */ - if( area ) area = astAnnul( area ); - if( coords ) coords = astAnnul( coords ); - if( props ) props = astAnnul( props ); - -/* If an error has occurred, return zero. */ - if( !astOK ) ret = 0; - -/* Return the answer. */ - return ret; -} - -static void WriteProps( AstStcsChan *this, AstKeyMap *props, int *status ){ -/* -* Name: -* WriteProps - -* Purpose: -* Write out a set of STC-S properties to the sink function. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* void WriteProps( AstStcsChan *this, AstKeyMap *props, int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function converts the STC-S properties supplied in a KeyMap -* into text, and writes the text out through the sink function associated -* with the parent Channel. - -* Parameters: -* this -* Pointer to the StcsChan. -* props -* Pointer to the KeyMap holding the STC-S properties. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstKeyMap *spprops; /* Sub-phrase properties */ - AstObject *obj; /* Generic Object pointer */ - char *line; /* Dynamically allocated buffer for output text */ - const char *id; /* Sub-phrase identifier */ - const char *prefix; /* Prefix for property value */ - int nc; /* Number of characters in "line" */ - int pretty; /* Include new-lines and indentation in returned text? */ - int crem; /* Character remaining on current output line */ - int linelen; /* Line length */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise things. */ - nc = 0; - line = NULL; - -/* See if indentation and new-lines are to be added to the output text to - make it look pretty. */ - pretty = astGetIndent( this ); - -/* If so, get the line length to use, and initialise the number of - remaining characters in the current output line. */ - if( pretty ) { - linelen = astGetStcsLength( this ); - } else { - linelen = 0; - } - crem = linelen; - -/* Add each word in the time sub-phrase into the output buffer, in the - order defined by the STC-S standard. */ - if( astMapGet0A( props, "TIME_PROPS", &obj ) ) { - spprops = (AstKeyMap *) obj; - - line = AddItem( this, spprops, "ID", NULL, line, &nc, &crem, linelen, status ); - astMapGet0C( spprops, "ID", &id ); - - line = AddItem( this, spprops, "FILLFACTOR", "fillfactor ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "TIMESCALE", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "REFPOS", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "START", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "STOP", NULL, line, &nc, &crem, linelen, status ); - - prefix = !astChrMatch( id, "Time" ) ? "Time " : NULL; - line = AddItem( this, spprops, "TIME", prefix, line, &nc, &crem, linelen, status ); - - line = AddItem( this, spprops, "UNIT", "unit ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "ERROR", "Error ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "RESOLUTION", "Resolution ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "PIXSIZE", "PixSize ", line, &nc, &crem, linelen, status ); - - spprops = astAnnul( spprops ); - -/* Write out the time sub-phrase text through the Channel sink function. */ - if( pretty && astChrLen( line ) ) { - astPutNextText( this, line ); - nc = 0; - crem = linelen; - } - } - -/* Add each word in the space sub-phrase into the output buffer, in the - order defined by the STC-S standard. */ - if( astMapGet0A( props, "SPACE_PROPS", &obj ) ) { - spprops = (AstKeyMap *) obj; - - line = AddItem( this, spprops, "ID", NULL, line, &nc, &crem, linelen, status ); - astMapGet0C( spprops, "ID", &id ); - - line = AddItem( this, spprops, "FILLFACTOR", "fillfactor ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "FRAME", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "REFPOS", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "FLAVOUR", NULL, line, &nc, &crem, linelen, status ); - - line = PutRegionProps( this, spprops, id, (pretty ? 0 : -1), line, &nc, - &crem, linelen, status ); - - prefix = !astChrMatch( id, "Position" ) ? "Position " : NULL; - line = AddItem( this, spprops, "POSITION", prefix, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "UNIT", "unit ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "ERROR", "Error ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "RESOLUTION", "Resolution ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "SIZE", "Size ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "PIXSIZE", "PixSize ", line, &nc, &crem, linelen, status ); - - spprops = astAnnul( spprops ); - -/* Write out the spatial sub-phrase text through the Channel sink function. */ - if( pretty && astChrLen( line ) ) { - astPutNextText( this, line ); - nc = 0; - crem = linelen; - } - } - -/* Add each word in the spectral sub-phrase into the output buffer, in the - order defined by the STC-S standard. */ - if( astMapGet0A( props, "SPECTRAL_PROPS", &obj ) ) { - spprops = (AstKeyMap *) obj; - - line = AddItem( this, spprops, "ID", NULL, line, &nc, &crem, linelen, status ); - astMapGet0C( spprops, "ID", &id ); - - line = AddItem( this, spprops, "FILLFACTOR", "fillfactor ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "REFPOS", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "LOLIMIT", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "HILIMIT", NULL, line, &nc, &crem, linelen, status ); - - prefix = !astChrMatch( id, "Spectral" ) ? "Spectral " : NULL; - line = AddItem( this, spprops, "SPECTRAL", prefix, line, &nc, &crem, linelen, status ); - - line = AddItem( this, spprops, "UNIT", "unit ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "ERROR", "Error ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "RESOLUTION", "Resolution ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "PIXSIZE", "PixSize ", line, &nc, &crem, linelen, status ); - - spprops = astAnnul( spprops ); - -/* Write out the spectral sub-phrase text through the Channel sink function. */ - if( pretty && astChrLen( line ) ) { - astPutNextText( this, line ); - nc = 0; - crem = linelen; - } - } - -/* Add each word in the redshift sub-phrase into the output buffer, in the - order defined by the STC-S standard. */ - if( astMapGet0A( props, "REDSHIFT_PROPS", &obj ) ) { - spprops = (AstKeyMap *) obj; - - line = AddItem( this, spprops, "ID", NULL, line, &nc, &crem, linelen, status ); - astMapGet0C( spprops, "ID", &id ); - - line = AddItem( this, spprops, "FILLFACTOR", "fillfactor ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "REFPOS", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "TYPE", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "DOPPLERDEF", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "LOLIMIT", NULL, line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "HILIMIT", NULL, line, &nc, &crem, linelen, status ); - - prefix = !astChrMatch( id, "Redshift" ) ? "Redshift " : NULL; - line = AddItem( this, spprops, "REDSHIFT", prefix, line, &nc, &crem, linelen, status ); - - line = AddItem( this, spprops, "UNIT", "unit ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "ERROR", "Error ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "RESOLUTION", "Resolution ", line, &nc, &crem, linelen, status ); - line = AddItem( this, spprops, "PIXSIZE", "PixSize ", line, &nc, &crem, linelen, status ); - - spprops = astAnnul( spprops ); - -/* Write out the redshift sub-phrase text through the Channel sink function. */ - if( pretty && astChrLen( line ) ) { - astPutNextText( this, line ); - nc = 0; - crem = linelen; - } - } - -/* Write out any remaining text through the Channel sink function. */ - if( nc && astChrLen( line ) ) astPutNextText( this, line ); - -/* Free resources. */ - line = astFree( line ); - -} - -static int WriteRegion( AstStcsChan *this, AstRegion *reg, AstKeyMap *props, - int *status ){ -/* -* Name: -* WriteRegion - -* Purpose: -* Convert a Region into a set of STC-S properties and store them in a -* KeyMap. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* int WriteRegion( AstStcsChan *this, AstRegion *reg, AstKeyMap *props, -* int *status ) - -* Class Membership: -* StcsChan member function - -* Description: -* This function attempts to convert the supplied Region nto a set of -* STC-S properties, and stores them in the supplied KeyMap. - -* Parameters: -* this -* Pointer to the StcsChan being used. -* reg -* Pointer to the region to be converted. -* props -* Pointer to the KeyMap in which to store the STC-S properties. -* On exit, each STC-S sub-phrase has an entry in this KeyMap, -* and each of these entries has a value that is another KeyMap -* holding the properties for the sub-phrase. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the conversion was succesful, and -* zero is returned otherwise. -*/ - -/* Local Variables: */ - AstFrame *efrm; /* Pointer to encapsulated Frame */ - AstFrame *pfrm; /* Pointer to primary Frame cntaining an axis */ - AstFrame *spfrm; /* The sub-phrase Frame */ - AstKeyMap *spprops; /* Sub-phrase properties */ - AstMapping *map; /* Base->current Region Mapping */ - AstMapping *sreg; /* Simplified Region */ - AstObject *obj; /* Generic object pointer */ - AstRegion *spreg; /* The sub-phrase Region */ - AstRegion *treg; /* Temporary Region pointer */ - AstRegion *unc; /* Uncertainty region */ - AstRegion *unca; /* Adaptive uncertainty region */ - AstStdOfRestType sor; /* StdOfRest attribute value */ - AstSystemType sys; /* System attribute value */ - char *prop; /* Formatted property string */ - char *unit1; /* Pointer to string holding first axis unit */ - char buf[ 100 ]; /* Buffer for formatted values */ - char fmt[ 10 ]; /* Buffer for format specifier */ - const char *class; /* Class name */ - const char *dom; /* Domain name */ - const char *dopdef; /* DopplerDef value */ - const char *flavour; /* The STC-S flavour for the space frame */ - const char *q; /* Pointer to next character */ - const char *tfrm; /* STC-S string for Frame */ - const char *tsor; /* STC-S string for RefPos */ - const char *tts; /* Time scale label */ - const char *type; /* Redshift Type value */ - const char *unit; /* Unit string */ - double *pcen; /* Pointer to Circle or ellipse centre */ - double equinox; /* The required equinox value */ - double error; /* Axis error value */ - double fill; /* Fill factor */ - double lbnd[ 3 ]; /* Region lower bounds */ - double lim; /* Unlimited bounds value */ - double p1[ 2 ]; /* End point of error line */ - double scale; /* Factor for scaling Region values into required units */ - double ubnd[ 3 ]; /* Region upper bounds */ - int allthesame; /* Do all axes have the same units? */ - int defdigs; /* Default number of digits */ - int defs; /* Include default values in output STC-S? */ - int i; /* Loop index */ - int issky; /* Do the space axes form a SkyFrame? */ - int nax; /* The number of axes */ - int nc; /* Number of characters in "prop" string */ - int nspace; /* Number of space axes */ - int ok; /* Can the Region be written out? */ - int pax; /* Index of axis in primary Frame */ - int redax; /* The index of the redshift axis */ - int retain_units; /* Retain the units/system in properties KeyMap? */ - int spaceax[ 3 ]; /* Indicies of the space axes */ - int spaceid; /* Code for space sub-phrase identifier */ - int specax; /* The index of the spectral axis */ - int timeax; /* Index of time axis */ - int ts; /* Time scale identifier */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise things to avoid comiler warnings. */ - sys = AST__BADSYSTEM; - -/* Assume we can do the conversion. */ - ok = 1; - -/* See if default values are to be included in the output. */ - defs = ( astGetFull( this ) > 0 ); - -/* STC-S requires that the spatial shape (circle, box. etc) refers to - the coordinate system described by the STC-S. This is not quite like - AST, in that the AST class type (Circle, Box, etc) defines the - shape of the region in the base Frame, rather than the current Frame. - So we can only write the Region out using STC-S if the shape in the - current Frame is the same as the shape in the base Frame. This is the - case if the simplified Mapping connecting base and current Frames is - a UnitMap. Get the base->current Mapping from the Region. */ - map = astRegMapping( reg ); - -/* If it is not UnitMap, see if simplifying the whole Region results in - the base->current Mapping in the simplified Region being a UnitMap. */ - if( !astIsAUnitMap( map ) ) { - map = astAnnul( map ); - sreg = astSimplify( reg ); - map = astRegMapping( sreg ); - -/* If it is still not UnitMap, we cannot write out the region. */ - if( !astIsAUnitMap( map ) ) { - astAddWarning( this, 1, "The supplied Region does not have a " - "supported shape within its current coordinate " - "system.", "astWrite", status ); - ok = 0; - } - - } else { - sreg = astClone( reg ); - } - map = astAnnul( map ); - -/* Store a safe value that can be used to test unbounded axes. */ - lim = sqrt( DBL_MAX ); - -/* First job is to identify the Time, Space, Spectral and Redshift axes - in the supplied Region. - ------------------------------------------------------------------- */ - -/* Initialise things. */ - timeax = -1; - nspace = 0; - issky = 0; - specax = -1; - redax = -1; - prop = NULL; - -/* Get a pointer to the Frame encapsulated by the Region. */ - efrm = astRegFrame( sreg ); - -/* Loop round all axes. */ - nax = astGetNaxes( sreg ); - for( i = 0; i < nax; i++ ) { - -/* Get the primary Frame that defines the current axis of the Region. */ - astPrimaryFrame( efrm, i, &pfrm, &pax ); - -/* Get its class and domain. */ - class = astGetClass( pfrm ); - dom = astGetDomain( pfrm ); - if( astOK ) { - -/* The time axis is described by a TimeFrame with any domain. */ - if( !strcmp( class, "TimeFrame" ) ) { - if( timeax == -1 ) { - timeax = i; - } else { - astAddWarning( this, 1, "More than one time axis found. " - "Extra axis (axis %d) will be ignored.", - "astWrite", status, i + 1 ); - } - -/* The space axes are described by a SkyFrame or a basic Frame. If a - mixture of both types are found, report a warning and ignore the later - axes. */ - } else if( !strcmp( class, "SkyFrame" ) ) { - if( issky || nspace == 0 ) { - if( nspace < 2 ) { - spaceax[ nspace++ ] = i; - issky = 1; - } else { - astAddWarning( this, 1, "More than two sky frame axes " - "found. Extra axis (axis %d) will be ignored.", - "astWrite", status, i + 1 ); - } - - } else { - astAddWarning( this, 1, "Mixture of basic and sky frame " - "axes found. Sky frame axis %d will be " - "ignored.", "astWrite", status, i + 1 ); - } - - } else if( !strcmp( class, "Frame" ) ) { - if( !issky ) { - if( nspace < 3 ) { - spaceax[ nspace++ ] = i; - } else { - astAddWarning( this, 1, "More than three basic space frame axes " - "found. Extra axis (axis %d) will be ignored.", - "astWrite", status, i + 1 ); - } - - } else { - astAddWarning( this, 1, "Mixture of basic and sky frame " - "axes found. Basic frame axis %d will be " - "ignored.", "astWrite", status, i + 1 ); - } - -/* The spectral axis is described by a SpecFrame with domain SPECTRUM. */ - } else if( !strcmp( class, "SpecFrame" ) && - !strcmp( dom, "SPECTRUM" ) ) { - if( specax == -1 ) { - specax = i; - } else { - astAddWarning( this, 1, "More than one spectral axis found. " - "Extra axis (axis %d) will be ignored.", - "astWrite", status, i + 1 ); - } - -/* The redshift axis is described by a SpecFrame with domain REDSHIFT. */ - } else if( !strcmp( class, "SpecFrame" ) && - !strcmp( dom, "REDSHIFT" ) ) { - if( redax == -1 ) { - redax = i; - } else { - astAddWarning( this, 1, "More than one redshift axis found. " - "Extra axis (axis %d) will be ignored.", - "astWrite", status, i + 1 ); - } - -/* Warn about unused axes. */ - } else { - astAddWarning( this, 1, "Could not classify axis %d (class=%s " - "domain=%s). It will be ignored.", "astWrite", status, - i + 1, class, dom ); - } - } - -/* Free resources. */ - pfrm = astAnnul( pfrm ); - } - efrm = astAnnul( efrm ); - -/* Set a flag indicating if there is anything to convert. */ - ok = ok && ( timeax != -1 || nspace > 0 || specax != -1 || redax != -1 ); - - -/* Now we have identified the axes, we convert each available STC-S - sub-phrase, starting with the time sub-phrase. - ---------------------------------------------------------------- */ - if( timeax != -1 ) { - -/* Create a Region by picking the time axis from the supplied Region. */ - spreg = astPickAxes( sreg, 1, &timeax, NULL ); - -/* Check it is a Region. If not, we cannot convert anything. */ - if( !astIsARegion( spreg ) ) { - astAddWarning( this, 1, "Cannot determine the region covered by " - "the time axis.", "astWrite", status ); - ok = 0; - -/* Otherwise we add a description of the time sub-phrase to the - properties keymap. */ - } else { - -/* Get a pointer to the Region's time phrase property KeyMap, creating - one if necessary. */ - if( astMapGet0A( props, "TIME_PROPS", &obj ) ) { - spprops = (AstKeyMap *) obj; - } else { - spprops = astKeyMap( " ", status ); - astMapPut0A( props, "TIME_PROPS", spprops, NULL ); - } - -/* Get the Region's fill factor. */ - fill = astGetFillFactor( spreg ); - -/* Ensure the TimeFrame represents MJD. If not, take a deep copy (to - avoid changing the supplied Region), and set its system to MJD. */ - if( astGetSystem( spreg ) != AST__MJD ) { - treg = astCopy( spreg ); - (void) astAnnul( spreg ); - spreg = treg; - astSetAdaptive( spreg, 1 ); - astSetSystem( spreg, AST__MJD ); - } - -/* Get the bounds of the Region (i.e. the time axis coverage). */ - astGetRegionBounds( spreg, lbnd, ubnd ); - -/* Get a pointer to the time Region's encapsulated Frame. */ - spfrm = astRegFrame( spreg ); - -/* Report a warning if the sub-phrase Frame is not a TimeFrame */ - if( !astIsATimeFrame( spfrm ) ) { - ok = 0; - astAddWarning( this, 1, "The time sub-phrase in the supplied " - "KeyMap is not described using an AST TimeFrame.", - "astWrite", status ); - -/* Store properties that are specific to Time moments... */ - } else if( lbnd[ 0 ] == ubnd[ 0 ] ) { - astMapPut0C( spprops, "ID", "Time", NULL ); - StoreTimeProp( spprops, (AstTimeFrame *) spfrm, "TIME", lbnd[ 0 ], status ); - fill = AST__BAD; - -/* Store properties that are specific to Time intervals... */ - } else if( lbnd[ 0 ] > -lim && ubnd[ 0 ] < lim ) { - astMapPut0C( spprops, "ID", "TimeInterval", NULL ); - StoreTimeProp( spprops, (AstTimeFrame *) spfrm, "START", lbnd[ 0 ], status ); - StoreTimeProp( spprops, (AstTimeFrame *) spfrm, "STOP", ubnd[ 0 ], status ); - -/* Store properties that are specific to Start times... */ - } else if( lbnd[ 0 ] > -lim ) { - astMapPut0C( spprops, "ID", "StartTime", NULL ); - StoreTimeProp( spprops, (AstTimeFrame *) spfrm, "START", lbnd[ 0 ], status ); - -/* Store properties that are specific to Stop times... */ - } else { - astMapPut0C( spprops, "ID", "StopTime", NULL ); - StoreTimeProp( spprops, (AstTimeFrame *) spfrm, "STOP", ubnd[ 0 ], status ); - - } - -/* Store properties that are common to all time sub-phrase types. First the - fill factor. */ - MapPut0D( spprops, "FILLFACTOR", fill, 1.0, defs, status ); - -/* Now the time scale. */ - ts = astGetTimeScale( spfrm ); - if( ts == AST__TT ) { - tts = "TT"; - - } else if( ts == AST__TAI ) { - tts = "TAI"; - - } else if( ts == AST__UTC ) { - tts = "UTC"; - - } else if( ts == AST__TDB ) { - tts = "TDB"; - - } else if( ts == AST__TCG ) { - tts = "TCG"; - - } else if( ts == AST__TCB ) { - tts = "TCB"; - - } else if( ts == AST__LMST ) { - tts = "LST"; - - } else { - tts = "nil"; - astAddWarning( this, 1, "Timescale '%s' is unsupported by " - "STC-S.", "astWrite", status, - astGetC( spfrm, "TimeScale" ) ); - ok = 0; - } - - MapPut0C( spprops, "TIMESCALE", tts, "nil", defs, status ); - -/* RefPos. The AST TimeFrame class has no reference position, we leave - unchanged any refpos already in the keymap. If there is no refpos in the - keymap, we use "TOPOCENTER". */ - if( !astMapHasKey( spprops, "REFPOS" ) ) { - astMapPut0C( spprops, "REFPOS", "TOPOCENTER", NULL ); - } - -/* That's it for the time sub-phrase, unless the supplied Region has an - explicit (non-default) uncertainty. */ - unc = astGetUnc( spreg, 0 ); - if( unc ) { - -/* See if the supplied properties KeyMap contains any item that refers to - the Unit included in the STC-S description, but which is not updated by - this function. If it does, we need to retain any units specified - within the KeyMap. */ - retain_units = ( astMapHasKey( spprops, "RESOLUTION" ) || - astMapHasKey( spprops, "PIXSIZE" ) || - astMapHasKey( spprops, "SIZE" ) ); - - if( retain_units ) { - if( !astMapGet0C( spprops, "UNIT", &unit ) ) unit = "s"; - } else { - unit = "s"; - } - -/* Store the units string */ - MapPut0C( spprops, "UNIT", unit, "s", defs, status ); - -/* If necessary, map the uncertainty region into the requied units. Take - a deep copy to avoid changing the supplied Region. */ - if( strcmp( unit, astGetUnit( unc, 0 ) ) ) { - unca = astCopy( unc ); - astSetAdaptive( unca, 0 ); - astSetUnit( unca, 0, unit ); - } else { - unca = astClone( unc ); - } - -/* Get the bounds of the uncertainty. */ - astGetRegionBounds( unca, lbnd, ubnd ); - -/* The error is half the width of the bounding box. */ - astMapPut0D( spprops, "ERROR", 0.5*( ubnd[ 0 ] - lbnd[ 0 ] ), NULL ); - -/* Free resources. */ - unca = astAnnul( unca ); - unc = astAnnul( unc ); - } - -/* Free resources. */ - spfrm = astAnnul( spfrm ); - spprops = astAnnul( spprops ); - } - -/* Free resources. */ - spreg = astAnnul( spreg ); - - } - - -/* Now convert the space sub-phrase. - ---------------------------------------------------------------- */ - if( nspace > 0 && ok ) { - -/* Create a Region by picking the space axes from the supplied Region. */ - spreg = astPickAxes( sreg, nspace, spaceax, NULL ); - -/* Check it is a Region. If not, we cannot convert anything. */ - if( ! astIsARegion( spreg ) ) { - astAddWarning( this, 1, "Cannot determine the region covered by " - "the space axes.", "astWrite", status ); - ok = 0; - -/* Otherwise we add a description of the space sub-phrase to the - properties keymap. */ - } else { - -/* Get a pointer to the Region's space phrase property KeyMap, creating - one if necessary. */ - if( astMapGet0A( props, "SPACE_PROPS", &obj ) ) { - spprops = (AstKeyMap *) obj; - } else { - spprops = astKeyMap( " ", status ); - astMapPut0A( props, "SPACE_PROPS", spprops, NULL ); - } - -/* If the space frame is a SkyFrame, ensure it refers to a coodinate - system that is supported by STC-S. Take a deep copy before changing - anything. */ - if( issky ) { - sys = astGetSystem( spreg ); - if( sys != AST__FK4 && - sys != AST__FK5 && - sys != AST__ICRS && - sys != AST__ECLIPTIC && - sys != AST__GALACTIC && - sys != AST__SUPERGALACTIC && - sys != AST__UNKNOWN ) { - treg = astCopy( spreg ); - (void) astAnnul( spreg ); - spreg = treg; - astSetAdaptive( spreg, 1 ); - astSetSystem( spreg, AST__ICRS ); - } - } - -/* Get a pointer to the Region's encapsulated Frame. */ - spfrm = astRegFrame( spreg ); - -/* If the supplied Region is defined in a SkyFrame, choose the units to - use when storing radius, error, etc in the KeyMap. If the props KeyMap - already contains a unit specification, we use it. Otherwise we use the - default (degrees). AST uses radians internally, so find the scaling - factor. */ - if( issky ) { - if( astMapGet0C( spprops, "UNIT", &unit ) ) { - if( !strcmp( unit, "arcmin" ) ) { - scale = AST__DR2D*60.0; - } else if( !strcmp( unit, "arcsec" ) ) { - scale = AST__DR2D*3600.0; - } else { - unit = "deg"; - scale = AST__DR2D; - } - } else { - unit = "deg"; - scale = AST__DR2D; - } - -/* Store the units string */ - MapPut0C( spprops, "UNIT", unit, "deg", defs, status ); - -/* If the supplied Region is not defined in a SkyFrame, we will arrange - that the Region and the KeyMap use the same units, so set a scale - factor of 1.0. */ - } else { - scale = 1.0; - -/* See if the supplied properties KeyMap contains any item that refers to - the Unit included in the STC-S description, but which is not updated by - this function. If it does, we need to retain any units specified - within the KeyMap. */ - retain_units = ( astMapHasKey( spprops, "RESOLUTION" ) || - astMapHasKey( spprops, "PIXSIZE" ) || - astMapHasKey( spprops, "SIZE" ) ); - -/* If so, and if the properties KeyMap already contains a Unit - specification, we convert the Region to the same units. Take a deep - copy of the Region first to avoid modifying the supplied Region. */ - if( retain_units ) { - if( !astMapGet0C( spprops, "UNIT", &unit ) ) unit = "deg"; - - treg = astCopy( spreg ); - (void) astAnnul( spreg ); - spreg = treg; - - for( i = 0; i < nspace; i++ ) { - astSetUnit( spreg, i, unit ); - -/* Space frames can have different units on different axes. So look for - the start of the next word in the Unit propert. This will be the unit - for the next axis. If there are no more words in the Unit property, - re-use the last unit value. */ - q = unit; - while( *q && !isspace( *q ) ) q++; - while( *q && isspace( *q ) ) q++; - if( *q ) unit = q; - } - -/* If we are not retaining the units specified in the properties KeyMap, we - retain the existing Region units instead, and store these units in the - properties KeyMap. We also check that these units are supported by - STC-S. */ - } else { - - nc = 0; - allthesame = 1; - unit1 = NULL; - - for( i = 0; i < nspace; i++ ) { - unit = astGetUnit( spreg, i ); - - if( !unit1 ) { - unit1 = astStore( NULL, unit, strlen( unit ) + 1 ); - } else { - if( strcmp( unit, unit1 ) ) allthesame = 0; - } - - if( strcmp( unit, "deg" ) && - strcmp( unit, "arcmin" ) && - strcmp( unit, "arcsec" ) && - strcmp( unit, "m" ) && - strcmp( unit, "mm" ) && - strcmp( unit, "km" ) && - strcmp( unit, "AU" ) && - strcmp( unit, "pc" ) && - strcmp( unit, "kpc" ) && - strcmp( unit, "Mpc" ) ) { - astAddWarning( this, 1, "Cannot use spatial units '%s'.", - "astWrite", status, unit ); - ok = 0; - break; - } - prop = astAppendString( prop, &nc, unit ); - prop = astAppendString( prop, &nc, " " ); - } - -/* Remove the trailing space, and store the property value in the KeyMap. */ - if( ! allthesame ) { - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( spprops, "UNIT", prop, NULL ); - } - } else { - astMapPut0C( spprops, "UNIT", unit1, NULL ); - } - - unit1 = astFree( unit1 ); - - } - } - -/* Get the fill factor. */ - fill = astGetFillFactor( spreg ); - -/* Get the default number of digits. This is only used if the supplied - properties KeyMap does not have a value for the item being stored. If - it does, the number of digits is inherited form the value int he KeyMap. */ - defdigs = astGetDigits( spfrm ); - -/* Store properties that are specific to the particular type of Region. */ - spaceid = GetRegionProps( this, spreg, spprops, nspace, defdigs, - scale, issky, status ); - if( spaceid == NULL_ID ) ok = 0; - -/* If the above went OK, store values for the properties that are common - to all types of space sub-phrase. */ - if( ok ) { - -/* First the fill factor. */ - if( spaceid != POSITION_ID ) { - MapPut0D( spprops, "FILLFACTOR", fill, 1.0, defs, status ); - } - -/* Now the coordinate frame. */ - tfrm = NULL; - sys = astGetSystem( spfrm ); - if( issky ) { - if( sys == AST__FK4 ){ - tfrm = "B1950"; - equinox = 1950.0; - - } else if( sys == AST__FK5 ){ - tfrm = "J2000"; - equinox = 2000.0; - - } else if( sys == AST__ICRS ){ - tfrm = "ICRS"; - equinox = AST__BAD; - - } else if( sys == AST__ECLIPTIC ){ - tfrm = "ECLIPTIC"; - equinox = 2000.0; - - } else if( sys == AST__GALACTIC ){ - tfrm = "GALACTIC"; - equinox = AST__BAD; - - } else if( sys == AST__SUPERGALACTIC ){ - tfrm = "SUPER_GALACTIC"; - equinox = AST__BAD; - - } else if( sys == AST__UNKNOWN ){ - tfrm = NULL; - equinox = AST__BAD; - - } else { - tfrm = NULL; - astAddWarning( this, 1, "Sky system '%s' is " - "unsupported by STC-S.", "astWrite", - status, astGetC( spfrm, "System" ) ); - ok = 0; - } - - if( tfrm && equinox != AST__BAD ) { - if( astGetD( spfrm, "Equinox" ) != equinox ) { - astAddWarning( this, 1, "STC-S requires an equinox " - "of %g for the %s frame, but the " - "supplied %s equinox is %g.", "astWrite", - status, equinox, tfrm, - astGetClass( spfrm ), - astGetD( spfrm, "Equinox" ) ); - ok = 0; - tfrm = NULL; - } - } - } - -/* If we do not yet have a Frame, use the Domain value if it is set (and - is a legal STC-S Frame). */ - if( ! tfrm ) { - if( astTestDomain( spfrm ) ) { - tfrm = astGetDomain( spfrm ); - if( strcmp( tfrm, "ICRS" ) && - strcmp( tfrm, "FK5" ) && - strcmp( tfrm, "FK4" ) && - strcmp( tfrm, "J2000" ) && - strcmp( tfrm, "B1950" ) && - strcmp( tfrm, "ECLIPTIC" ) && - strcmp( tfrm, "GALACTIC" ) && - strcmp( tfrm, "GALACTIC_II" ) && - strcmp( tfrm, "SUPER_GALACTIC" ) && - strcmp( tfrm, "GEO_C" ) && - strcmp( tfrm, "GEO_D" ) ){ - astAddWarning( this, 1, "'UNKNOWNFrame' being used in " - "place of unsupported frame '%s'.", - "astWrite", status, tfrm ); - tfrm = NULL; - } - } - } - -/* Store the Frame name in the props keymap. */ - if( !tfrm ) tfrm = "UNKNOWNFrame"; - astMapPut0C( spprops, "FRAME", tfrm, NULL ); - -/* RefPos. The AST SkyFrame and Frame classes have no reference position, so - we leave unchanged any refpos already in the props keymap. If there is - no refpos in the keymap, we use "TOPOCENTER". */ - if( !astMapHasKey( spprops, "REFPOS" ) ) { - astMapPut0C( spprops, "REFPOS", "TOPOCENTER", NULL ); - } - -/* Flavour. */ - if( issky ) { - flavour = "SPHER2"; - } else if( nspace == 1 ){ - flavour = "CART1"; - } else if( nspace == 2 ){ - flavour = "CART2"; - } else { - flavour = "CART3"; - } - MapPut0C( spprops, "FLAVOUR", flavour, "SPHER2", defs, status ); - -/* That's it for the space sub-phrase, unless the supplied Region has an - explicit (non-default) uncertainty. */ - unc = astGetUnc( spreg, 0 ); - if( unc ) { - -/* Get the bounds of the uncertainty. */ - astGetRegionBounds( unc, lbnd, ubnd ); - -/* If its a sky frame, find the position of the centre of the uncertainty - region. */ - pcen = issky ? astRegCentre( unc, NULL, NULL, 0, - AST__CURRENT ) : NULL; - -/* Find the half-width of the bounding box for each space axis, and - concatenate their formatted values into a string. If any bound is - undefined, quit the axis loop with nc=0. We need to convert longitude - axis values from lingitude increments to arc-distance. */ - nc = 0; - defdigs = astGetDigits( unc ); - - for( i = 0; i < nspace; i++ ) { - if( ubnd[ i ] != AST__BAD && lbnd[ i ] != AST__BAD ){ - - if( ! issky ) { - error = 0.5*( ubnd[ i ] - lbnd[ i ] ); - } else { - if( i == 0 ) { - p1[ 0 ] = ubnd[ 0 ]; - p1[ 1 ] = pcen[ 1 ]; - } else { - p1[ 0 ] = pcen[ 0 ]; - p1[ 1 ] = ubnd[ 1 ]; - } - error = astDistance( spfrm, pcen, p1 ); - } - - GetFmt( "ERROR", spprops, i, defdigs, fmt, status ); - (void) sprintf( buf, fmt, scale*error ); - prop = astAppendString( prop, &nc, buf ); - prop = astAppendString( prop, &nc, " " ); - - } else { - nc = 0; - break; - } - } - -/* If the bounds were all good, store the string holding the formatted - error values in the properties KeyMap. */ - if( prop && nc > 0 ) { - prop[ nc - 1 ] = 0; - astMapPut0C( spprops, "ERROR", prop, NULL ); - } - -/* Free resources. */ - pcen = astFree( pcen ); - unc = astAnnul( unc ); - } - } - -/* Free resources. */ - spfrm = astAnnul( spfrm ); - spprops = astAnnul( spprops ); - } - -/* Free resources. */ - spreg = astAnnul( spreg ); - - } - - - -/* Convert the spectral sub-phrase. - ---------------------------------------------------------------- */ - if( specax != -1 ) { - -/* Create a Region by picking the spectral axis from the supplied Region. */ - spreg = astPickAxes( sreg, 1, &specax, NULL ); - -/* Check it is a Region. If not, we cannot convert anything. */ - if( !astIsARegion( spreg ) ) { - astAddWarning( this, 1, "Cannot determine the region covered by " - "the spectral axis.", "astWrite", status ); - ok = 0; - -/* Otherwise we add a description of the spectral sub-phrase to the - properties keymap. */ - } else { - -/* Get a pointer to the Region's spectral phrase property KeyMap, creating - one if necessary. */ - if( astMapGet0A( props, "SPECTRAL_PROPS", &obj ) ) { - spprops = (AstKeyMap *) obj; - } else { - spprops = astKeyMap( " ", status ); - astMapPut0A( props, "SPECTRAL_PROPS", spprops, NULL ); - } - -/* See if the supplied properties KeyMap contains any item that refers to - the Unit included in the STC-S description, but which is not updated by - this function. If it does, we need to retain any units specified - within the KeyMap. */ - retain_units = ( astMapHasKey( spprops, "RESOLUTION" ) || - astMapHasKey( spprops, "PIXSIZE" ) || - astMapHasKey( spprops, "SIZE" ) ); - -/* If so, and if the properties KeyMap already contains a Unit specification, - we convert the Region to the same units and system. Determine the - required system and units. */ - if( retain_units ) { - if( !astMapGet0C( spprops, "UNIT", &unit ) ) unit = "Hz"; - - if( !strcmp( unit, "Hz" ) || - !strcmp( unit, "MHz" ) || - !strcmp( unit, "GHz" ) ) { - sys = AST__FREQ; - - } else if( !strcmp( unit, "m" ) || - !strcmp( unit, "mm" ) || - !strcmp( unit, "um" ) || - !strcmp( unit, "nm" ) || - !strcmp( unit, "Angstrom" ) ) { - sys = AST__WAVELEN; - - } else if( !strcmp( unit, "eV" ) || - !strcmp( unit, "keV" ) || - !strcmp( unit, "MeV" ) ) { - sys = AST__ENERGY; - - } else { - astAddWarning( this, 1, "Illegal STC-S units '%s' found in " - "supplied KeyMap", "astWrite", status, unit ); - ok = 0; - } - -/* If we do not need to retain the units implied by the supplied KeyMap, - use the Units and system in the supplied Region so long as they are - supported by STC-S. If not, use a related supported system instead. */ - } else { - sys = astGetSystem( spreg ); - unit = astGetUnit( spreg, 0 ); - - if( sys == AST__ENERGY ) { - sys = AST__ENERGY; - if( strcmp( unit, "eV" ) && - strcmp( unit, "keV" ) && - strcmp( unit, "MeV" ) ) unit = "eV"; - - } else if( sys == AST__WAVELEN || sys == AST__AIRWAVE || - sys == AST__VOPTICAL || sys == AST__REDSHIFT ){ - sys = AST__WAVELEN; - if( strcmp( unit, "m" ) && - strcmp( unit, "mm" ) && - strcmp( unit, "um" ) && - strcmp( unit, "nm" ) && - strcmp( unit, "Angstrom" ) ) unit = "m"; - - } else { - sys = AST__FREQ; - if( strcmp( unit, "Hz" ) && - strcmp( unit, "MHz" ) && - strcmp( unit, "GHz" ) ) unit = "Hz"; - - } - } - -/* Store the units string */ - MapPut0C( spprops, "UNIT", unit, "Hz", defs, status ); - -/* If either the System or Unit needs to be changed in the Region, take a - deep copy first in order to avoid changing the supplied Region. */ - if( sys != astGetSystem( spreg ) || - ( unit && strcmp( unit, astGetUnit( spreg, 0 ) ) ) ) { - treg = astCopy( spreg ); - (void) astAnnul( spreg ); - spreg = treg; - astSetAdaptive( spreg, 1 ); - astSetSystem( spreg, sys ); - astSetUnit( spreg, 0, unit ); - } - -/* Get the Region's fill factor. */ - fill = astGetFillFactor( spreg ); - -/* Get the bounds of the Region (i.e. the spectral axis coverage). */ - astGetRegionBounds( spreg, lbnd, ubnd ); - -/* Get a pointer to the spectral Region's encapsulated Frame. */ - spfrm = astRegFrame( spreg ); - -/* Report a warning if the sub-phrase Frame is not a SpecFrame */ - if( !astIsASpecFrame( spfrm ) ) { - ok = 0; - astAddWarning( this, 1, "The spectral sub-phrase in the supplied " - "KeyMap is not described using an AST SpecFrame.", - "astWrite", status ); - -/* Store properties that are specific to spectral positions... */ - } else if( lbnd[ 0 ] == ubnd[ 0 ] ) { - astMapPut0C( spprops, "ID", "Spectral", NULL ); - astMapPut0D( spprops, "SPECTRAL", lbnd[ 0 ], NULL ); - fill = AST__BAD; - -/* Store properties that are specific to Spectral intervals... */ - } else if( lbnd[ 0 ] > -lim && ubnd[ 0 ] < lim ) { - astMapPut0C( spprops, "ID", "SpectralInterval", NULL ); - astMapPut0D( spprops, "LOLIMIT", lbnd[ 0 ], NULL ); - astMapPut0D( spprops, "HILIMIT", ubnd[ 0 ], NULL ); - - } else { - ok = 0; - astAddWarning( this, 1, "Cannot write out an unbounded " - "spectral interval.", "astWrite", status ); - } - -/* Store properties that are common to all spectral sub-phrase types. First the - fill factor. */ - MapPut0D( spprops, "FILLFACTOR", fill, 1.0, defs, status ); - -/* Now the reference position. */ - sor = astGetStdOfRest( spfrm ); - if( sor == AST__GESOR ) { - tsor = "GEOCENTER"; - - } else if( sor == AST__BYSOR ) { - tsor = "BARYCENTER"; - - } else if( sor == AST__HLSOR ) { - tsor = "HELIOCENTER"; - - } else if( sor == AST__TPSOR ) { - tsor = "TOPOCENTER"; - - } else if( sor == AST__LKSOR ) { - tsor = "LSRK"; - - } else if( sor == AST__LDSOR ) { - tsor = "LSRD"; - - } else if( sor == AST__GLSOR ) { - tsor = "GALACTIC_CENTER"; - - } else { - tsor = NULL; - } - - if( !tsor ) tsor = "UNKNOWNRefPos"; - MapPut0C( spprops, "REFPOS", tsor, "UNKNOWNRefPos", defs, - status ); - -/* Now the unit string. */ - MapPut0C( spprops, "UNIT", unit, "Hz", defs, status ); - -/* That's it for the spectral sub-phrase, unless the supplied Region has an - explicit (non-default) uncertainty. */ - unc = astGetUnc( spreg, 0 ); - if( unc ) { - -/* Get the bounds of the uncertainty. */ - astGetRegionBounds( unc, lbnd, ubnd ); - -/* The error is half the width of the bounding box. */ - astMapPut0D( spprops, "ERROR", 0.5*( ubnd[ 0 ] - lbnd[ 0 ] ), NULL ); - -/* Free resources. */ - unc = astAnnul( unc ); - } - -/* Free resources. */ - spfrm = astAnnul( spfrm ); - spprops = astAnnul( spprops ); - } - -/* Free resources. */ - spreg = astAnnul( spreg ); - - } - - - -/* Convert the redshift sub-phrase. - ---------------------------------------------------------------- */ - if( redax != -1 ) { - -/* Create a Region by picking the redshift axis from the supplied Region. */ - spreg = astPickAxes( sreg, 1, &redax, NULL ); - -/* Check it is a Region. If not, we cannot convert anything. */ - if( !astIsARegion( spreg ) ) { - astAddWarning( this, 1, "Cannot determine the region covered by " - "the redshift axis.", "astWrite", status ); - ok = 0; - -/* Otherwise we add a description of the redshift sub-phrase to the - properties keymap. */ - } else { - -/* Get a pointer to the Region's redshift phrase property KeyMap, creating - one if necessary. */ - if( astMapGet0A( props, "REDSHIFT_PROPS", &obj ) ) { - spprops = (AstKeyMap *) obj; - } else { - spprops = astKeyMap( " ", status ); - astMapPut0A( props, "REDSHIFT_PROPS", spprops, NULL ); - } - -/* See if the supplied properties KeyMap contains any item that refers to - the system included in the STC-S description, but which is not updated by - this function. If it does, we need to retain any system specified - within the KeyMap. */ - retain_units = ( astMapHasKey( spprops, "RESOLUTION" ) || - astMapHasKey( spprops, "PIXSIZE" ) || - astMapHasKey( spprops, "SIZE" ) ); - -/* If so, and if the properties KeyMap already contains a DopplerDef or - Type specification, we convert the Region to the same system. */ - if( retain_units ){ - if( !astMapGet0C( spprops, "DOPPLERDEF", &dopdef ) ) dopdef = "OPTICAL"; - if( !astMapGet0C( spprops, "TYPE", &type ) ) type = "VELOCITY"; - - if( astChrMatch( type, "VELOCITY" ) ) { - if( astChrMatch( dopdef, "OPTICAL" ) ) { - sys = AST__VOPTICAL; - } else if( astChrMatch( dopdef, "RADIO" ) ) { - sys = AST__VRADIO; - } else if( astChrMatch( dopdef, "RELATIVISTIC" ) ) { - sys = AST__VREL; - } else { - astAddWarning( this, 1, "Illegal STC-S DopplerDef '%s' " - "found in supplied KeyMap", "astWrite", status, - dopdef ); - ok = 0; - } - - } else if( astChrMatch( type, "REDSHIFT" ) ) { - if( astChrMatch( dopdef, "OPTICAL" ) ) { - sys = AST__REDSHIFT; - } else { - astAddWarning( this, 1, "Unsupported combination of " - "DopplerDef='%s' and Type='%s' found in " - "supplied KeyMap", "astWrite", status, dopdef, - type ); - ok = 0; - } - - } else { - astAddWarning( this, 1, "Illegal STC-S Redshift Type '%s' " - "found in supplied KeyMap", "astWrite", status, - type ); - ok = 0; - } - -/* If the supplied KeyMap does not imply the required system, use the - system in the supplied Region. */ - } else { - sys = astGetSystem( spreg ); - } - -/* Choose the requied units. */ - unit = ( sys == AST__REDSHIFT ) ? "": "km/s"; - -/* Store the units string */ - MapPut0C( spprops, "UNIT", unit, unit, defs, status ); - -/* If either the System or Unit needs to be changed in the Region, take a - deep copy first in order to avoid changing the supplied Region. */ - if( sys != astGetSystem( spreg ) || - ( unit && strcmp( unit, astGetUnit( spreg, 0 ) ) ) ) { - treg = astCopy( spreg ); - (void) astAnnul( spreg ); - spreg = treg; - astSetAdaptive( spreg, 1 ); - astSetSystem( spreg, sys ); - astSetUnit( spreg, 0, unit ); - } - -/* Get the Region's fill factor. */ - fill = astGetFillFactor( spreg ); - -/* Get the bounds of the Region (i.e. the redshift axis coverage). */ - astGetRegionBounds( spreg, lbnd, ubnd ); - -/* Get a pointer to the spectral Region's encapsulated Frame. */ - spfrm = astRegFrame( spreg ); - -/* Report a warning if the sub-phrase Frame is not a SpecFrame */ - if( !astIsASpecFrame( spfrm ) ) { - ok = 0; - astAddWarning( this, 1, "The redshift sub-phrase in the supplied " - "KeyMap is not described using an AST SpecFrame.", - "astWrite", status ); - -/* Store properties that are specific to redshift positions... */ - } else if( lbnd[ 0 ] == ubnd[ 0 ] ) { - astMapPut0C( spprops, "ID", "Redshift", NULL ); - astMapPut0D( spprops, "REDSHIFT", lbnd[ 0 ], NULL ); - fill = AST__BAD; - -/* Store properties that are specific to Redshift intervals... */ - } else if( lbnd[ 0 ] > -lim && ubnd[ 0 ] < lim ) { - astMapPut0C( spprops, "ID", "RedshiftInterval", NULL ); - astMapPut0D( spprops, "LOLIMIT", lbnd[ 0 ], NULL ); - astMapPut0D( spprops, "HILIMIT", ubnd[ 0 ], NULL ); - - } else { - ok = 0; - astAddWarning( this, 1, "Cannot write out an unbounded " - "redshift interval.", "astWrite", status ); - } - -/* Store properties that are common to all redshift sub-phrase types. First the - fill factor. */ - MapPut0D( spprops, "FILLFACTOR", fill, 1.0, defs, status ); - -/* Now the reference position. */ - sor = astGetStdOfRest( spfrm ); - - if( sor == AST__GESOR ) { - tsor = "GEOCENTER"; - - } else if( sor == AST__BYSOR ) { - tsor = "BARYCENTER"; - - } else if( sor == AST__HLSOR ) { - tsor = "HELIOCENTER"; - - } else if( sor == AST__TPSOR ) { - tsor = "TOPOCENTER"; - - } else if( sor == AST__LKSOR ) { - tsor = "LSRK"; - - } else if( sor == AST__LDSOR ) { - tsor = "LSRD"; - - } else if( sor == AST__GLSOR ) { - tsor = "GALACTIC_CENTER"; - - } else { - tsor = NULL; - } - - if( !tsor ) tsor = "UNKNOWNRefPos"; - MapPut0C( spprops, "REFPOS", tsor, "UNKNOWNRefPos", defs, - status ); - -/* Type and DopplerDef. */ - if( sys == AST__VOPTICAL ) { - type = "VELOCITY"; - dopdef = "OPTICAL"; - - } else if( sys == AST__VRADIO ) { - type = "VELOCITY"; - dopdef = "RADIO"; - - } else if( sys == AST__VREL ) { - type = "VELOCITY"; - dopdef = "RELATIVISTIC"; - - } else { - type = "REDSHIFT"; - dopdef = "OPTICAL"; - } - astMapPut0C( spprops, "DOPPLERDEF", dopdef, NULL ); - MapPut0C( spprops, "TYPE", type, "REDSHIFT", defs, status ); - -/* Now the unit string. */ - MapPut0C( spprops, "UNIT", unit, unit, defs, status ); - -/* That's it for the redshift sub-phrase, unless the supplied Region has an - explicit (non-default) uncertainty. */ - unc = astGetUnc( spreg, 0 ); - if( unc ) { - -/* Get the bounds of the uncertainty. */ - astGetRegionBounds( unc, lbnd, ubnd ); - -/* The error is half the width of the bounding box. */ - astMapPut0D( spprops, "ERROR", 0.5*( ubnd[ 0 ] - lbnd[ 0 ] ), NULL ); - -/* Free resources. */ - unc = astAnnul( unc ); - } - -/* Free resources. */ - spfrm = astAnnul( spfrm ); - spprops = astAnnul( spprops ); - } - -/* Free resources. */ - spreg = astAnnul( spreg ); - - } - -/* Free resources */ - if( sreg ) sreg = astAnnul( sreg ); - if( prop ) prop = astFree( prop ); - -/* Return the result. */ - return ok; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* StcsArea - -* Purpose: -* Return the CoordinateArea component when reading an STC-S document? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This is a boolean attribute which controls what is returned -* by the -c astRead -f AST_READ -* function when it is used to read from an StcsChan. -* If StcsArea is set non-zero (the default), then a Region -* representing the STC CoordinateArea will be returned by -c astRead. -f AST_READ. -* If StcsArea is set to zero, then the STC CoordinateArea -* will not be returned. - -* Notes: -* - Other attributes such as StcsCoords and StcsProps can be used to -* specify other Objects to be returned by -c astRead. -f AST_READ. -* If more than one of these attributes is set non-zero, then the -* actual Object returned by -c astRead -f AST_READ -* will be a KeyMap, containing the requested Objects. In this -* case, the Region representing the STC CoordinateArea will be -* stored in the returned KeyMap using the key "AREA". If StcsArea -* is the only attribute to be set non-zero, then the Object returned by -c astRead -f AST_READ -* will be the CoordinateArea Region itself. -* - The class of Region used to represent the CoordinateArea for each -* STC-S sub-phrase is determined by the first word in the -* sub-phrase (the "sub-phrase identifier"). The individual sub-phrase -* Regions are combined into a single Prism, which is then simplified -c using astSimplify -f using AST_SIMPLIFY -* to form the returned region. -* - Sub-phrases that represent a single value ( that is, have -* identifiers "Time", "Position", "Spectral" or "Redshift" ) are -* considered to be be part of the STC CoordinateArea component. -* - The TimeFrame used to represent a time STC-S sub-phrase will have -* its TimeOrigin attribute set to the sub-phrase start time. If no -* start time is specified by the sub-phrase, then the stop time will be -* used instead. If no stop time is specified by the sub-phrase, then -* the single time value specified in the sub-phrase will be used -* instead. Subsequently clearing the TimeOrigin attribute (or setting -* its value to zero) will cause the TimeFrame to reprsent absolute times. -* - The Epoch attribute for the returned Region is set in the same -* way as the TimeOrigin attribute (see above). - -* Applicability: -* StcsChan -* All StcsChans have this attribute. -*att-- -*/ - -/* This ia a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of 1. */ -astMAKE_CLEAR(StcsChan,StcsArea,stcsarea,-INT_MAX) -astMAKE_GET(StcsChan,StcsArea,int,1,( this->stcsarea != -INT_MAX ? this->stcsarea : 1 )) -astMAKE_SET(StcsChan,StcsArea,int,stcsarea,( value != 0 )) -astMAKE_TEST(StcsChan,StcsArea,( this->stcsarea != -INT_MAX )) - -/* -*att++ -* Name: -* StcsCoords - -* Purpose: -* Return the Coordinates component when reading an STC-S document? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This is a boolean attribute which controls what is returned -* by the -c astRead -f AST_READ -* function when it is used to read from an StcsChan. -* If StcsCoords is set non-zero, then a PointList -* representing the STC Coordinates will be returned by -c astRead. -f AST_READ. -* If StcsCoords is set to zero (the default), then the STC -* Coordinates will not be returned. - -* Notes: -* - Other attributes such as StcsArea and StcsProps can be used to -* specify other Objects to be returned by -c astRead. -f AST_READ. -* If more than one of these attributes is set non-zero, then the -* actual Object returned by -c astRead -f AST_READ -* will be a KeyMap, containing the requested Objects. In this -* case, the PointList representing the STC Coordinates will be -* stored in the returned KeyMap using the key "COORDS". If StcsCoords -* is the only attribute to be set non-zero, then the Object returned by -c astRead -f AST_READ -* will be the Coordinates PointList itself. -* - The Coordinates component is specified by the additional axis -* values embedded within the body of each STC-S sub-phrase that -* represents an extended area. Sub-phrases that represent a single -* value ( that is, have identifiers "Time", "Position", "Spectral" -* or "Redshift" ) are not considered to be be part of the STC -* Coordinates component. -* - If the STC-S documents does not contain a Coordinates component, -* then a NULL object pointer -f (AST__NULL) -* will be returned by -c astRead -f AST_READ -* if the Coordinates component is the only object being returned. If -* other objects are also being returned (see attributes StcsProps and -* StcsArea), then the returned KeyMap will contain a "COORDS" key -* only if the Coordinates component is read succesfully. -* - The TimeFrame used to represent a time STC-S sub-phrase will have -* its TimeOrigin attribute set to the sub-phrase start time. If no -* start time is specified by the sub-phrase, then the stop time will be -* used instead. If no stop time is specified by the sub-phrase, then -* the single time value specified in the sub-phrase will be used -* instead. Subsequently clearing the TimeOrigin attribute (or setting -* its value to zero) will cause the TimeFrame to reprsent absolute times. -* - The Epoch attribute for the returned Region is set in the same -* way as the TimeOrigin attribute (see above). - -* Applicability: -* StcsChan -* All StcsChans have this attribute. -*att-- -*/ - -/* This ia a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of zero. */ -astMAKE_CLEAR(StcsChan,StcsCoords,stcscoords,-INT_MAX) -astMAKE_GET(StcsChan,StcsCoords,int,0,( this->stcscoords != -INT_MAX ? this->stcscoords : 0 )) -astMAKE_SET(StcsChan,StcsCoords,int,stcscoords,( value != 0 )) -astMAKE_TEST(StcsChan,StcsCoords,( this->stcscoords != -INT_MAX )) - -/* -*att++ -* Name: -* StcsProps - -* Purpose: -* Return all properties when reading an STC-S document? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This is a boolean attribute which controls what is returned -* by the -c astRead -f AST_READ -* function when it is used to read from an StcsChan. -* If StcsProps is set non-zero, then a KeyMap containing all the -* properties read from the STC-S document will be returned by -c astRead. -f AST_READ. -* If StcsProps is set to zero (the default), then the properties -* will not be returned. - -* Notes: -* - Other attributes such as StcsCoords and StcsArea can be used to -* specify other Objects to be returned by -c astRead. -f AST_READ. -* If more than one of these attributes is set non-zero, then the -* actual Object returned by -c astRead -f AST_READ -* will be a KeyMap containing the requested Objects. In this -* case, the properties KeyMap will be stored in the returned KeyMap -* using the key "PROPS". If StcsProps is the only attribute to be -* set non-zero, then the Object returned by -c astRead -f AST_READ -* will be the properties KeyMap itself. -* - The KeyMap containing the properties will have entries for one or -* more of the following keys: "TIME_PROPS", "SPACE_PROPS", "SPECTRAL_PROPS" -* and "REDSHIFT_PROPS". Each of these entries will be another KeyMap -* containing the properties of the corresponding STC-S sub-phrase. - -* Applicability: -* StcsChan -* All StcsChans have this attribute. -*att-- -*/ - -/* This ia a boolean value (0 or 1) with a value of -INT_MAX when - undefined but yielding a default of zero. */ -astMAKE_CLEAR(StcsChan,StcsProps,stcsprops,-INT_MAX) -astMAKE_GET(StcsChan,StcsProps,int,0,( this->stcsprops != -INT_MAX ? this->stcsprops : 0 )) -astMAKE_SET(StcsChan,StcsProps,int,stcsprops,( value != 0 )) -astMAKE_TEST(StcsChan,StcsProps,( this->stcsprops != -INT_MAX )) - -/* -*att++ -* Name: -* StcsLength - -* Purpose: -* Controls output line length. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute specifies the maximum length to use when writing out -* text through the sink function supplied when the StcsChan was created. -* It is ignored if the Indent attribute is zero (in which case the text -* supplied to the sink function can be of any length). The default value -* is 70. -* -* The number of characters in each string written out through the sink -* function will not usually be greater than the value of this attribute -* (but may be less). However, if any single word in the STC-S -* description exceeds the specified length, then the word will be -* written out as a single line. -* -f Note, the default value of zero is unlikely to be appropriate when -f an StcsChan is used within Fortran code. In this case, StcsLength -f should usually be set to the size of the CHARACTER variable used to -f receive the text returned by AST_GETLINE within the sink function. -f In addition, the Indent attribute should be set non-zero. This -f avoids the possibility of long lines being truncated invisibly -f within AST_GETLINE. - -* Applicability: -* StcsChan -* All StcsChans have this attribute. -*att-- -*/ -astMAKE_CLEAR(StcsChan,StcsLength,stcslength,-INT_MAX) -astMAKE_GET(StcsChan,StcsLength,int,70,( ( this->stcslength != -INT_MAX ) ? this->stcslength : 70 )) -astMAKE_SET(StcsChan,StcsLength,int,stcslength,(value<0?0:value)) -astMAKE_TEST(StcsChan,StcsLength,( this->stcslength != -INT_MAX )) - -/* Copy constructor. */ -/* ----------------- */ - -/* Destructor. */ -/* ----------- */ - -/* Dump function. */ -/* -------------- */ - -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for StcsChan objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the StcsChan class to an output Channel. - -* Parameters: -* this -* Pointer to the Object (an StcsChan) whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstStcsChan *this; /* Pointer to the StcsChan structure */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the StcsChan structure. */ - this = (AstStcsChan *) this_object; - -/* Write out values representing the instance variables for the - StcsChan class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* StcsArea. */ -/* --------- */ - set = TestStcsArea( this, status ); - ival = set ? GetStcsArea( this, status ) : astGetStcsArea( this ); - astWriteInt( channel, "StcsArea", set, 0, ival, - ival ? "Read the STC CoordinatesArea component" : - "Do not read the STC CoordinatesArea component" ); - -/* StcsCoords. */ -/* ----------- */ - set = TestStcsCoords( this, status ); - ival = set ? GetStcsCoords( this, status ) : astGetStcsCoords( this ); - astWriteInt( channel, "StcsCoords", set, 0, ival, - ival ? "Read the STC Coordinates component" : - "Do not read the STC Coordinates component" ); - -/* StcsProps. */ -/* ---------- */ - set = TestStcsProps( this, status ); - ival = set ? GetStcsProps( this, status ) : astGetStcsProps( this ); - astWriteInt( channel, "StcsProps", set, 0, ival, - ival ? "Read the STC-S properties" : - "Do not read the STC-S properties" ); - -/* StcsLength */ -/* ---------- */ - set = TestStcsLength( this, status ); - ival = set ? GetStcsLength( this, status ) : astGetStcsLength( this ); - astWriteInt( channel, "StcsLen", set, 0, ival, "STC-S buffer length" ); - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAStcsChan and astCheckStcsChan functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(StcsChan,Channel) -astMAKE_CHECK(StcsChan) - -AstStcsChan *astStcsChan_( const char *(* source)( void ), - void (* sink)( const char * ), - const char *options, int *status, ...) { -/* -*++ -* Name: -c astStcsChan -f AST_STCSCHAN - -* Purpose: -* Create an StcsChan. - -* Type: -* Public function. - -* Synopsis: -c #include "stcschan.h" -c AstStcsChan *astStcsChan( const char *(* source)( void ), -c void (* sink)( const char * ), -c const char *options, ... ) -f RESULT = AST_STCSCHAN( SOURCE, SINK, OPTIONS, STATUS ) - -* Class Membership: -* StcsChan constructor. - -* Description: -* This function creates a new StcsChan and optionally initialises -* its attributes. -* -* A StcsChan is a specialised form of Channel which supports STC-S -* I/O operations. Writing an Object to an StcsChan (using -c astWrite) will, if the Object is suitable, generate an -f AST_WRITE) will, if the Object is suitable, generate an -* STC-S description of that Object, and reading from an StcsChan will -* create a new Object from its STC-S description. -* -* Normally, when you use an StcsChan, you should provide "source" -c and "sink" functions which connect it to an external data store -c by reading and writing the resulting text. These functions -f and "sink" routines which connect it to an external data store -f by reading and writing the resulting text. These routines -* should perform any conversions needed between external character -c encodings and the internal ASCII encoding. If no such functions -f encodings and the internal ASCII encoding. If no such routines -* are supplied, a Channel will read from standard input and write -* to standard output. -* -* Alternatively, an XmlChan can be told to read or write from -* specific text files using the SinkFile and SourceFile attributes, -* in which case no sink or source function need be supplied. - -* Parameters: -c source -f SOURCE = SUBROUTINE (Given) -c Pointer to a source function that takes no arguments and -c returns a pointer to a null-terminated string. If no value -c has been set for the SourceFile attribute, this function -c will be used by the StcsChan to obtain lines of input text. On -c each invocation, it should return a pointer to the next input -c line read from some external data store, and a NULL pointer -c when there are no more lines to read. -c -c If "source" is NULL and no value has been set for the SourceFile -c attribute, the StcsChan will read from standard input instead. -f A source routine, which is a subroutine which takes a single -f integer error status argument. If no value has been set -f for the SourceFile attribute, this routine will be used by -f the StcsChan to obtain lines of input text. On each -f invocation, it should read the next input line from some -f external data store, and then return the resulting text to -f the AST library by calling AST_PUTLINE. It should supply a -f negative line length when there are no more lines to read. -f If an error occurs, it should set its own error status -f argument to an error value before returning. -f -f If the null routine AST_NULL is suppied as the SOURCE value, -f and no value has been set for the SourceFile attribute, -f the StcsChan will read from standard input instead. -c sink -f SINK = SUBROUTINE (Given) -c Pointer to a sink function that takes a pointer to a -c null-terminated string as an argument and returns void. -c If no value has been set for the SinkFile attribute, this -c function will be used by the StcsChan to deliver lines of -c output text. On each invocation, it should deliver the -c contents of the string supplied to some external data store. -c -c If "sink" is NULL, and no value has been set for the SinkFile -c attribute, the StcsChan will write to standard output instead. -f A sink routine, which is a subroutine which takes a single -f integer error status argument. If no value has been set -f for the SinkFile attribute, this routine will be used by -f the StcsChan to deliver lines of output text. On each -f invocation, it should obtain the next output line from the -f AST library by calling AST_GETLINE, and then deliver the -f resulting text to some external data store. If an error -f occurs, it should set its own error status argument to an -f error value before returning. -f -f If the null routine AST_NULL is suppied as the SINK value, -f and no value has been set for the SinkFile attribute, -f the StcsChan will write to standard output instead. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new StcsChan. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new StcsChan. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astStcsChan() -f AST_STCSCHAN = INTEGER -* A pointer to the new StcsChan. - -* Notes: -f - The names of the routines supplied for the SOURCE and SINK -f arguments should appear in EXTERNAL statements in the Fortran -f routine which invokes AST_STCSCHAN. However, this is not generally -f necessary for the null routine AST_NULL (so long as the AST_PAR -f include file has been used). -* - If the external data source or sink uses a character encoding -* other than ASCII, the supplied source and sink functions should -* translate between the external character encoding and the internal -* ASCII encoding used by AST. -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the AST error status set, or if it -* should fail for any reason. -f - Note that the null routine AST_NULL (one underscore) is -f different to AST__NULL (two underscores), which is the null Object -f pointer. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstStcsChan *new; /* Pointer to new StcsChan */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the StcsChan, allocating memory and initialising the - virtual function table as well if necessary. This interface is for - use by other C functions within AST, and uses the standard "wrapper" - functions included in this class. */ - new = astInitStcsChan( NULL, sizeof( AstStcsChan ), !class_init, - &class_vtab, "StcsChan", source, SourceWrap, - sink, SinkWrap ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - StcsChan's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new StcsChan. */ - return new; -} - -AstStcsChan *astStcsChanId_( const char *(* source)( void ), - void (* sink)( const char * ), - const char *options, ... ) { -/* -* Name: -* astStcsChanId_ - -* Purpose: -* Create an StcsChan. - -* Type: -* Private function. - -* Synopsis: -* #include "stcschan.h" -* AstStcsChan *astStcsChanId_( const char *(* source)( void ), -* void (* sink)( const char * ), -* const char *options, ... ) - -* Class Membership: -* StcsChan constructor. - -* Description: -* This function implements the external (public) C interface to the -* astStcsChan constructor function. Another function (astStcsChanForId) -* should be called to create an StcsChan for use within other languages. -* Both functions return an ID value (instead of a true C pointer) to -* external users, and must be provided because astStcsChan_ has a variable -* argument list which cannot be encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astStcsChan_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astStcsChan_. - -* Returned Value: -* The ID value associated with the new StcsChan. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstStcsChan *new; /* Pointer to new StcsChan */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the StcsChan, allocating memory and initialising the - virtual function table as well if necessary. This interface is for - use by external C functions and uses the standard "wrapper" - functions included in this class. */ - new = astInitStcsChan( NULL, sizeof( AstStcsChan ), !class_init, - &class_vtab, "StcsChan", source, SourceWrap, - sink, SinkWrap ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - StcsChan's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new StcsChan. */ - return astMakeId( new ); -} - -AstStcsChan *astStcsChanForId_( const char *(* source)( void ), - char *(* source_wrap)( const char *(*)( void ), int * ), - void (* sink)( const char * ), - void (* sink_wrap)( void (*)( const char * ), - const char *, int * ), - const char *options, ... ) { -/* -*+ -* Name: -* astStcsChanFor - -* Purpose: -* Initialise an StcsChan from a foreign language interface. - -* Type: -* Public function. - -* Synopsis: -* #include "stcschan.h" -* AstStcsChan *astStcsChanFor( const char *(* source)( void ), -* char *(* source_wrap)( const char *(*) -* ( void ), int * ), -* void (* sink)( const char * ), -* void (* sink_wrap)( void (*)( const char * ), -* const char *, int * ), -* const char *options, ... ) - -* Class Membership: -* StcsChan constructor. - -* Description: -* This function creates a new StcsChan from a foreign language -* interface and optionally initialises its attributes. -* -* A StcsChan is a specialised form of Channel which supports STC-S -* I/O operations. Writing an Object to an StcsChan (using -c astWrite) will, if the Object is suitable, generate an -f AST_WRITE) will, if the Object is suitable, generate an -* STC-S description of that Object, and reading from an StcsChan will -* create a new Object from its STC-S description. -* -* Normally, when you use an StcsChan, you should provide "source" -c and "sink" functions which connect it to an external data store -c by reading and writing the resulting text. These functions -f and "sink" routines which connect it to an external data store -f by reading and writing the resulting text. These routines -* should perform any conversions needed between external character -c encodings and the internal ASCII encoding. If no such functions -f encodings and the internal ASCII encoding. If no such routines -* are supplied, a Channel will read from standard input and write -* to standard output. - -* Parameters: -* source -* Pointer to a "source" function which will be used to obtain -* lines of input text. Generally, this will be obtained by -* casting a pointer to a source function which is compatible -* with the "source_wrap" wrapper function (below). The pointer -* should later be cast back to its original type by the -* "source_wrap" function before the function is invoked. -* -* If "source" is NULL, the StcsChan will read from standard -* input instead. -* source_wrap -* Pointer to a function which can be used to invoke the -* "source" function supplied (above). This wrapper function is -* necessary in order to hide variations in the nature of the -* source function, such as may arise when it is supplied by a -* foreign (non-C) language interface. -* -* The single parameter of the "source_wrap" function is a -* pointer to the "source" function, and it should cast this -* function pointer (as necessary) and invoke the function with -* appropriate arguments to obtain the next line of input -* text. The "source_wrap" function should then return a pointer -* to a dynamically allocated, null terminated string containing -* the text that was read. The string will be freed (using -* astFree) when no longer required and the "source_wrap" -* function need not concern itself with this. A NULL pointer -* should be returned if there is no more input to read. -* -* If "source_wrap" is NULL, the StcsChan will read from standard -* input instead. -* sink -* Pointer to a "sink" function which will be used to deliver -* lines of output text. Generally, this will be obtained by -* casting a pointer to a sink function which is compatible with -* the "sink_wrap" wrapper function (below). The pointer should -* later be cast back to its original type by the "sink_wrap" -* function before the function is invoked. -* -* If "sink" is NULL, the StcsChan will write to standard output -* instead. -* sink_wrap -* Pointer to a function which can be used to invoke the "sink" -* function supplied (above). This wrapper function is necessary -* in order to hide variations in the nature of the sink -* function, such as may arise when it is supplied by a foreign -* (non-C) language interface. -* -* The first parameter of the "sink_wrap" function is a pointer -* to the "sink" function, and the second parameter is a pointer -* to a const, null-terminated character string containing the -* text to be written. The "sink_wrap" function should cast the -* "sink" function pointer (as necessary) and invoke the -* function with appropriate arguments to deliver the line of -* output text. The "sink_wrap" function then returns void. -* -* If "sink_wrap" is NULL, the Channel will write to standard -* output instead. -* options -* Pointer to a null-terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new StcsChan. The syntax used is identical to -* that for the astSet function and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of additional arguments may follow it in -* order to supply values to be substituted for these -* specifiers. The rules for supplying these are identical to -* those for the astSet function (and for the C "printf" -* function). - -* Returned Value: -* astStcsChanFor() -* A pointer to the new StcsChan. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -* - This function is only available through the public interface -* to the StcsChan class (not the protected interface) and is -* intended solely for use in implementing foreign language -* interfaces to this class. -*- - -* Implememtation Notes: -* - This function behaves exactly like astStcsChanId_, in that it -* returns ID values and not true C pointers, but it has two -* additional arguments. These are pointers to the "wrapper -* functions" which are needed to accommodate foreign language -* interfaces. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstStcsChan *new; /* Pointer to new StcsChan */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise the StcsChan, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitStcsChan( NULL, sizeof( AstStcsChan ), !class_init, - &class_vtab, "StcsChan", source, source_wrap, - sink, sink_wrap ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - StcsChan's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new StcsChan. */ - return astMakeId( new ); -} - -AstStcsChan *astInitStcsChan_( void *mem, size_t size, int init, - AstStcsChanVtab *vtab, const char *name, - const char *(* source)( void ), - char *(* source_wrap)( const char *(*)( void ), int * ), - void (* sink)( const char * ), - void (* sink_wrap)( void (*)( const char * ), - const char *, int * ), int *status ) { -/* -*+ -* Name: -* astInitStcsChan - -* Purpose: -* Initialise an StcsChan. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcschan.h" -* AstStcsChan *astInitStcsChan( void *mem, size_t size, int init, -* AstStcsChanVtab *vtab, const char *name, -* const char *(* source)( void ), -* char *(* source_wrap)( const char *(*)( void ), int * ), -* void (* sink)( const char * ), -* void (* sink_wrap)( void (*)( const char * ), -* const char *, int * ) ) - -* Class Membership: -* StcsChan initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new StcsChan object. It allocates memory (if -* necessary) to accommodate the StcsChan plus any additional data -* associated with the derived class. It then initialises a -* StcsChan structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual -* function table for an StcsChan at the start of the memory passed -* via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the StcsChan is to be -* initialised. This must be of sufficient size to accommodate -* the StcsChan data (sizeof(StcsChan)) plus any data used by the -* derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the StcsChan (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the StcsChan structure, so a valid value must be -* supplied even if not required for allocating memory. -* init -* A boolean flag indicating if the StcsChan's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new StcsChan. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* source -* Pointer to a "source" function which will be used to obtain -* lines of text. Generally, this will be obtained by -* casting a pointer to a source function which is compatible -* with the "source_wrap" wrapper function (below). The pointer -* should later be cast back to its original type by the -* "source_wrap" function before the function is invoked. -* -* If "source" is NULL, the Channel will read from standard -* input instead. -* source_wrap -* Pointer to a function which can be used to invoke the -* "source" function supplied (above). This wrapper function is -* necessary in order to hide variations in the nature of the -* source function, such as may arise when it is supplied by a -* foreign (non-C) language interface. -* -* The single parameter of the "source_wrap" function is a -* pointer to the "source" function, and it should cast this -* function pointer (as necessary) and invoke the function with -* appropriate arguments to obtain the next line of input -* text. The "source_wrap" function should then return a pointer -* to a dynamically allocated, null terminated string containing -* the text that was read. The string will be freed (using -* astFree) when no longer required and the "source_wrap" -* function need not concern itself with this. A NULL pointer -* should be returned if there is no more input to read. -* -* If "source_wrap" is NULL, the Channel will read from standard -* input instead. -* sink -* Pointer to a "sink" function which will be used to deliver -* lines of text. Generally, this will be obtained by -* casting a pointer to a sink function which is compatible with -* the "sink_wrap" wrapper function (below). The pointer should -* later be cast back to its original type by the "sink_wrap" -* function before the function is invoked. -* -* If "sink" is NULL, the contents of the StcsChan will not be -* written out before being deleted. -* sink_wrap -* Pointer to a function which can be used to invoke the "sink" -* function supplied (above). This wrapper function is necessary -* in order to hide variations in the nature of the sink -* function, such as may arise when it is supplied by a foreign -* (non-C) language interface. -* -* The first parameter of the "sink_wrap" function is a pointer -* to the "sink" function, and the second parameter is a pointer -* to a const, null-terminated character string containing the -* text to be written. The "sink_wrap" function should cast the -* "sink" function pointer (as necessary) and invoke the -* function with appropriate arguments to deliver the line of -* output text. The "sink_wrap" function then returns void. -* -* If "sink_wrap" is NULL, the Channel will write to standard -* output instead. - -* Returned Value: -* A pointer to the new StcsChan. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstStcsChan *new; /* Pointer to new StcsChan */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitStcsChanVtab( vtab, name ); - -/* Initialise a Channel structure (the parent class) as the first - component within the StcsChan structure, allocating memory if - necessary. */ - new = (AstStcsChan *) astInitChannel( mem, size, 0, - (AstChannelVtab *) vtab, name, - source, source_wrap, sink, - sink_wrap ); - - if ( astOK ) { - -/* Initialise the StcsChan data. */ -/* ---------------------------- */ - new->stcsarea = -INT_MAX; - new->stcscoords = -INT_MAX; - new->stcsprops = -INT_MAX; - new->stcslength = -INT_MAX; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstStcsChan *astLoadStcsChan_( void *mem, size_t size, - AstStcsChanVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadStcsChan - -* Purpose: -* Load an StcsChan. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcschan.h" -* AstStcsChan *astLoadStcsChan( void *mem, size_t size, -* AstStcsChanVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* StcsChan loader. - -* Description: -* This function is provided to load a new StcsChan using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* StcsChan structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for an StcsChan at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the StcsChan is to be -* loaded. This must be of sufficient size to accommodate the -* StcsChan data (sizeof(StcsChan)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the StcsChan (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the StcsChan structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstStcsChan) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new StcsChan. If this is NULL, a pointer -* to the (static) virtual function table for the StcsChan class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "StcsChan" is used instead. - -* Returned Value: -* A pointer to the new StcsChan. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstStcsChan *new; /* Pointer to the new StcsChan */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this StcsChan. In this case the - StcsChan belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstStcsChan ); - vtab = &class_vtab; - name = "StcsChan"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitStcsChanVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built StcsChan. */ - new = astLoadChannel( mem, size, (AstChannelVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "StcsChan" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* StcsArea. */ -/* --------- */ - new->stcsarea = astReadInt( channel, "stcsarea", -INT_MAX ); - if ( TestStcsArea( new, status ) ) SetStcsArea( new, new->stcsarea, status ); - -/* StcsCoords. */ -/* ----------- */ - new->stcscoords = astReadInt( channel, "stcscoords", -INT_MAX ); - if ( TestStcsCoords( new, status ) ) SetStcsCoords( new, new->stcscoords, status ); - -/* StcsProps. */ -/* ---------- */ - new->stcsprops = astReadInt( channel, "stcsprops", -INT_MAX ); - if ( TestStcsProps( new, status ) ) SetStcsProps( new, new->stcsprops, status ); - -/* StcsLength */ -/* ---------- */ - new->stcslength = astReadInt( channel, "stcslen", -INT_MAX ); - - } - -/* If an error occurred, clean up by deleting the new StcsChan. */ - if ( !astOK ) new = astDelete( new ); - -/* Return the new StcsChan pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - - - - diff --git a/ast/stcschan.h b/ast/stcschan.h deleted file mode 100644 index 11de827..0000000 --- a/ast/stcschan.h +++ /dev/null @@ -1,308 +0,0 @@ -#if !defined( STCSCHAN_INCLUDED ) /* Include this file only once */ -#define STCSCHAN_INCLUDED -/* -*+ -* Name: -* stcschan.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the StcsChan class. - -* Invocation: -* #include "stcschan.h" - -* Description: -* This include file defines the interface to the StcsChan class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The StcsChan class provides facilities for reading and writing AST -* Objects in the form of STC-S text. - -* Inheritance: -* The StcsChan class inherits from the Channel class. - -* Copyright: -* Copyright (C) 2008 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (JAC, UCLan) - -* History: -* 18-DEC-2008 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "channel.h" /* I/O channels (parent class) */ - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros. */ -/* ------- */ - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* Define constants used to size global arrays in this module. */ -/* Define other numerical constants for use in this module. */ -#define AST__STCSCHAN_GETATTRIB_BUFF_LEN 200 - -/* Type Definitions. */ -/* ================= */ - -/* StcsChan structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstStcsChan { - -/* Attributes inherited from the parent class. */ - AstChannel channel; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int stcsarea; /* Read the STC CoordinatesArea? */ - int stcscoords; /* Read the STC Coordinates? */ - int stcsprops; /* Read the STC-S properties? */ - int stcslength; /* Line length */ -} AstStcsChan; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstStcsChanVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstChannelVtab channel_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - int (* GetStcsArea)( AstStcsChan *, int * ); - int (* TestStcsArea)( AstStcsChan *, int * ); - void (* ClearStcsArea)( AstStcsChan *, int * ); - void (* SetStcsArea)( AstStcsChan *, int, int * ); - - int (* GetStcsCoords)( AstStcsChan *, int * ); - int (* TestStcsCoords)( AstStcsChan *, int * ); - void (* ClearStcsCoords)( AstStcsChan *, int * ); - void (* SetStcsCoords)( AstStcsChan *, int, int * ); - - int (* GetStcsProps)( AstStcsChan *, int * ); - int (* TestStcsProps)( AstStcsChan *, int * ); - void (* ClearStcsProps)( AstStcsChan *, int * ); - void (* SetStcsProps)( AstStcsChan *, int, int * ); - - int (* GetStcsLength)( AstStcsChan *, int * ); - int (* TestStcsLength)( AstStcsChan *, int * ); - void (* ClearStcsLength)( AstStcsChan *, int * ); - void (* SetStcsLength)( AstStcsChan *, int, int * ); - -} AstStcsChanVtab; - -#if defined(THREAD_SAFE) -typedef struct AstStcsChanGlobals { - AstStcsChanVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ AST__STCSCHAN_GETATTRIB_BUFF_LEN + 1 ]; -} AstStcsChanGlobals; - -#endif -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(StcsChan) /* Check class membership */ -astPROTO_ISA(StcsChan) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstStcsChan *astStcsChan_( const char *(*)( void ), void (*)( const char * ), - const char *, int *, ...); -#else -AstStcsChan *astStcsChanId_( const char *(*)( void ), void (*)( const char * ), - const char *, ... ); -AstStcsChan *astStcsChanForId_( const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), - const char *, int * ), - const char *, ... ); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstStcsChan *astInitStcsChan_( void *, size_t, int, AstStcsChanVtab *, - const char *, const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), - const char *, int * ), int * ); - -/* Vtab initialiser. */ -void astInitStcsChanVtab_( AstStcsChanVtab *, const char *, int * ); - - - -/* Loader. */ -AstStcsChan *astLoadStcsChan_( void *, size_t, AstStcsChanVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitStcsChanGlobals_( AstStcsChanGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -# if defined(astCLASS) /* Protected */ -int astGetStcsArea_( AstStcsChan *, int * ); -int astTestStcsArea_( AstStcsChan *, int * ); -void astClearStcsArea_( AstStcsChan *, int * ); -void astSetStcsArea_( AstStcsChan *, int, int * ); - -int astGetStcsCoords_( AstStcsChan *, int * ); -int astTestStcsCoords_( AstStcsChan *, int * ); -void astClearStcsCoords_( AstStcsChan *, int * ); -void astSetStcsCoords_( AstStcsChan *, int, int * ); - -int astGetStcsProps_( AstStcsChan *, int * ); -int astTestStcsProps_( AstStcsChan *, int * ); -void astClearStcsProps_( AstStcsChan *, int * ); -void astSetStcsProps_( AstStcsChan *, int, int * ); - -int astGetStcsLength_( AstStcsChan *, int * ); -int astTestStcsLength_( AstStcsChan *, int * ); -void astClearStcsLength_( AstStcsChan *, int * ); -void astSetStcsLength_( AstStcsChan *, int, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckStcsChan(this) astINVOKE_CHECK(StcsChan,this,0) -#define astVerifyStcsChan(this) astINVOKE_CHECK(StcsChan,this,1) - -/* Test class membership. */ -#define astIsAStcsChan(this) astINVOKE_ISA(StcsChan,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astStcsChan astINVOKE(F,astStcsChan_) -#else -#define astStcsChan astINVOKE(F,astStcsChanId_) -#define astStcsChanFor astINVOKE(F,astStcsChanForId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitStcsChan(mem,size,init,vtab,name,source,source_wrap,sink,sink_wrap) \ -astINVOKE(O,astInitStcsChan_(mem,size,init,vtab,name,source,source_wrap,sink,sink_wrap,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitStcsChanVtab(vtab,name) astINVOKE(V,astInitStcsChanVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadStcsChan(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadStcsChan_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to member functions. */ -/* ------------------------------- */ -/* Here we make use of astCheckStcsChan to validate StcsChan pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - - -#if defined(astCLASS) /* Protected */ - -#define astClearStcsArea(this) \ -astINVOKE(V,astClearStcsArea_(astCheckStcsChan(this),STATUS_PTR)) -#define astGetStcsArea(this) \ -astINVOKE(V,astGetStcsArea_(astCheckStcsChan(this),STATUS_PTR)) -#define astSetStcsArea(this,value) \ -astINVOKE(V,astSetStcsArea_(astCheckStcsChan(this),value,STATUS_PTR)) -#define astTestStcsArea(this) \ -astINVOKE(V,astTestStcsArea_(astCheckStcsChan(this),STATUS_PTR)) - -#define astClearStcsCoords(this) \ -astINVOKE(V,astClearStcsCoords_(astCheckStcsChan(this),STATUS_PTR)) -#define astGetStcsCoords(this) \ -astINVOKE(V,astGetStcsCoords_(astCheckStcsChan(this),STATUS_PTR)) -#define astSetStcsCoords(this,value) \ -astINVOKE(V,astSetStcsCoords_(astCheckStcsChan(this),value,STATUS_PTR)) -#define astTestStcsCoords(this) \ -astINVOKE(V,astTestStcsCoords_(astCheckStcsChan(this),STATUS_PTR)) - -#define astClearStcsProps(this) \ -astINVOKE(V,astClearStcsProps_(astCheckStcsChan(this),STATUS_PTR)) -#define astGetStcsProps(this) \ -astINVOKE(V,astGetStcsProps_(astCheckStcsChan(this),STATUS_PTR)) -#define astSetStcsProps(this,value) \ -astINVOKE(V,astSetStcsProps_(astCheckStcsChan(this),value,STATUS_PTR)) -#define astTestStcsProps(this) \ -astINVOKE(V,astTestStcsProps_(astCheckStcsChan(this),STATUS_PTR)) - -#define astClearStcsLength(this) astINVOKE(V,astClearStcsLength_(astCheckStcsChan(this),STATUS_PTR)) -#define astGetStcsLength(this) astINVOKE(V,astGetStcsLength_(astCheckStcsChan(this),STATUS_PTR)) -#define astSetStcsLength(this,stcslength) astINVOKE(V,astSetStcsLength_(astCheckStcsChan(this),stcslength,STATUS_PTR)) -#define astTestStcsLength(this) astINVOKE(V,astTestStcsLength_(astCheckStcsChan(this),STATUS_PTR)) - -#endif -#endif - - - - diff --git a/ast/stcsearchlocation.c b/ast/stcsearchlocation.c deleted file mode 100644 index aa6bd4e..0000000 --- a/ast/stcsearchlocation.c +++ /dev/null @@ -1,806 +0,0 @@ -/* -*class++ -* Name: -* StcSearchLocation - -* Purpose: -* Correspond to the IVOA SearchLocation class. - -* Constructor Function: -c astStcSearchLocation -f AST_STCSEARCHLOCATION - -* Description: -* The StcSearchLocation class is a sub-class of Stc used to describe -* the coverage of a query. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Inheritance: -* The StcSearchLocation class inherits from the Stc class. - -* Attributes: -* The StcSearchLocation class does not define any new attributes beyond -* those which are applicable to all Stcs. - -* Functions: -c The StcSearchLocation class does not define any new functions beyond those -f The StcSearchLocation class does not define any new routines beyond those -* which are applicable to all Stcs. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 26-NOV-2004 (DSB): -* Original version. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS StcSearchLocation - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "stc.h" /* Coordinate stcs (parent class) */ -#include "channel.h" /* I/O channels */ -#include "region.h" /* Regions within coordinate systems */ -#include "stcsearchlocation.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(StcSearchLocation) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(StcSearchLocation,Class_Init) -#define class_vtab astGLOBAL(StcSearchLocation,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstStcSearchLocationVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstStcSearchLocation *astStcSearchLocationId_( void *, int, AstKeyMap **, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static void Dump( AstObject *, AstChannel *, int * ); - -/* Member functions. */ -/* ================= */ - -void astInitStcSearchLocationVtab_( AstStcSearchLocationVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitStcSearchLocationVtab - -* Purpose: -* Initialise a virtual function table for a StcSearchLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcsearchlocation.h" -* void astInitStcSearchLocationVtab( AstStcSearchLocationVtab *vtab, const char *name ) - -* Class Membership: -* StcSearchLocation vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the StcSearchLocation class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstStcVtab *stc; /* Pointer to Stc component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitStcVtab( (AstStcVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAStcSearchLocation) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstStcVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - mapping = (AstMappingVtab *) vtab; - stc = (AstStcVtab *) vtab; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - -/* Declare the copy constructor, destructor and class dump - functions. */ - astSetDump( vtab, Dump, "StcSearchLocation", "Query coverage" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -/* None */ - -/* Destructor. */ -/* ----------- */ -/* None */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for StcSearchLocation objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the StcSearchLocation class to an output Channel. - -* Parameters: -* this -* Pointer to the StcSearchLocation whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstStcSearchLocation *this; /* Pointer to the StcSearchLocation structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the StcSearchLocation structure. */ - this = (AstStcSearchLocation *) this_object; - -/* Write out values representing the instance variables for the - StcSearchLocation class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* There are no values to write, so return without further action. */ -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAStcSearchLocation and astCheckStcSearchLocation functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(StcSearchLocation,Stc) -astMAKE_CHECK(StcSearchLocation) - -AstStcSearchLocation *astStcSearchLocation_( void *region_void, int ncoords, - AstKeyMap **coords, const char *options, int *status, ...) { -/* -*++ -* Name: -c astStcSearchLocation -f AST_STCSEARCHLOCATION - -* Purpose: -* Create a StcSearchLocation. - -* Type: -* Public function. - -* Synopsis: -c #include "stcsearchlocation.h" -c AstStcResourceProfile *astStcSearchLocation( AstRegion *region, -c int ncoords, AstKeyMap *coords[], const char *options, ... ) -f RESULT = AST_STCSEARCHLOCATION( REGION, NCOORDS, COORDS, OPTIONS, STATUS ) - -* Class Membership: -* StcSearchLocation constructor. - -* Description: -* This function creates a new StcSearchLocation and optionally initialises its -* attributes. -* -* The StcSearchLocation class is a sub-class of Stc used to describe -* the coverage of a VO query. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Parameters: -c region -f REGION = INTEGER (Given) -* Pointer to the encapsulated Region. -c ncoords -f NCOORDS = INTEGER (Given) -c The length of the "coords" array. Supply zero if "coords" is NULL. -f The length of the COORDS array. Supply zero if COORDS should be -f ignored. -c coords -f COORDS( NCOORDS ) = INTEGER (Given) -c Pointer to an array holding "ncoords" AstKeyMap pointers (if "ncoords" -f An array holding NCOORDS AstKeyMap pointers (if NCOORDS -* is zero, the supplied value is ignored). Each supplied KeyMap -* describes the contents of a single STC element, and -* should have elements with keys given by constants AST__STCNAME, -* AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. Any of these elements may be omitted, but no other -* elements should be included. If supplied, the AST__STCNAME element -* should be a vector of character string pointers holding the "Name" -* item for each axis in the coordinate system represented by -c "region". -f REGION. -* Any other supplied elements should be scalar elements, each holding -* a pointer to a Region describing the associated item of ancillary -* information (error, resolution, size, pixel size or value). These -* Regions should describe a volume within the coordinate system -c represented by "region". -f represented by REGION. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new StcSearchLocation. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new StcSearchLocation. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astStcSearchLocation() -f AST_STCSEARCHLOCATION = INTEGER -* A pointer to the new StcSearchLocation. - -* Notes: -* - A deep copy is taken of the supplied Region. This means that -* any subsequent changes made to the encapsulated Region using the -* supplied pointer will have no effect on the Stc. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstRegion *region; /* Pointer to Region structure */ - AstStcSearchLocation *new; /* Pointer to new StcSearchLocation */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain and validate a pointer to the Region structure provided. */ - region = astCheckRegion( region_void ); - -/* Initialise the StcSearchLocation, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitStcSearchLocation( NULL, sizeof( AstStcSearchLocation ), !class_init, - &class_vtab, "StcSearchLocation", region, - ncoords, coords ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new StcSearchLocation's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new StcSearchLocation. */ - return new; -} - -AstStcSearchLocation *astStcSearchLocationId_( void *region_void, int ncoords, - AstKeyMap **coords, const char *options, ... ) { -/* -* Name: -* astStcSearchLocationId_ - -* Purpose: -* Create a StcSearchLocation. - -* Type: -* Private function. - -* Synopsis: -* #include "stcsearchlocation.h" -* AstStcSearchLocation *astStcSearchLocationId_( AstRegion *region, -* int ncoords, AstKeyMap *coords[], const char *options, ... ) - -* Class Membership: -* StcSearchLocation constructor. - -* Description: -* This function implements the external (public) interface to the -* astStcSearchLocation constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astStcSearchLocation_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astStcSearchLocation_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astStcSearchLocation_. - -* Returned Value: -* The ID value associated with the new StcSearchLocation. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstKeyMap **keymaps; /* Pointer to array of KeyMap pointers */ - AstRegion *region; /* Pointer to Region structure */ - AstStcSearchLocation *new; /* Pointer to new StcSearchLocation */ - int icoord; /* Keymap index */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - - /* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Obtain a Region pointer from the supplied ID and validate the - pointer to ensure it identifies a valid Region. */ - region = astVerifyRegion( astMakePointer( region_void ) ); - -/* Obtain pointer from the supplied KeyMap ID's and validate the - pointers to ensure it identifies a valid KeyMap. */ - keymaps = astMalloc( sizeof( AstKeyMap * )*(size_t) ncoords ); - if( keymaps ) { - for( icoord = 0; icoord < ncoords; icoord++ ) { - keymaps[ icoord ] = astVerifyKeyMap( astMakePointer( coords[ icoord ] ) ); - } - } - -/* Initialise the StcSearchLocation, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitStcSearchLocation( NULL, sizeof( AstStcSearchLocation ), !class_init, - &class_vtab, "StcSearchLocation", region, - ncoords, keymaps ); - -/* Free resources. */ - keymaps = astFree( keymaps ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new StcSearchLocation's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new StcSearchLocation. */ - return astMakeId( new ); -} - -AstStcSearchLocation *astInitStcSearchLocation_( void *mem, size_t size, - int init, AstStcSearchLocationVtab *vtab, - const char *name, AstRegion *region, - int ncoords, AstKeyMap **coords, int *status ) { -/* -*+ -* Name: -* astInitStcSearchLocation - -* Purpose: -* Initialise a StcSearchLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcsearchlocation.h" -* AstStcSearchLocation *astInitStcSearchLocation_( void *mem, size_t size, -* int init, AstStcSearchLocationVtab *vtab, -* const char *name, AstRegion *region, -* int ncoords, AstKeyMap **coords ) - -* Class Membership: -* StcSearchLocation initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new StcSearchLocation object. It allocates memory (if necessary) to accommodate -* the StcSearchLocation plus any additional data associated with the derived class. -* It then initialises a StcSearchLocation structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a StcSearchLocation at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the StcSearchLocation is to be initialised. -* This must be of sufficient size to accommodate the StcSearchLocation data -* (sizeof(StcSearchLocation)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the StcSearchLocation (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the StcSearchLocation -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the StcSearchLocation's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new StcSearchLocation. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* region -* A pointer to the Region encapsulated by the StcSearchLocation. -* ncoords -* Number of KeyMap pointers supplied in "coords". Can be zero. -* Ignored if "coords" is NULL. -* coords -* Pointer to an array of "ncoords" KeyMap pointers, or NULL if -* "ncoords" is zero. Each KeyMap defines defines a single -* element, and should have elements with keys given by constants -* AST__STCNAME, AST__STCVALUE, AST__STCERROR, AST__STCRES, AST__STCSIZE, -* AST__STCPIXSZ. These elements hold values for the corresponding -* components of the STC AstroCoords element. Any of these elements may -* be omitted, but no other elements should be included. All supplied -* elements should be vector elements, with vector length less than or -* equal to the number of axes in the supplied Region. The data type of -* all elements should be "double", except for AST__STCNAME which should -* be "character string". If no value is available for a given axis, then -* AST__BAD (or NULL for the AST__STCNAME element) should be stored in -* the vector at the index corresponding to the axis (trailing axes -* can be omitted completely from the KeyMap). - -* Returned Value: -* A pointer to the new StcSearchLocation. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstStcSearchLocation *new; /* Pointer to new StcSearchLocation */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitStcSearchLocationVtab( vtab, name ); - -/* Initialise a Stc structure (the parent class) as the first component - within the StcSearchLocation structure, allocating memory if necessary. */ - new = (AstStcSearchLocation *) astInitStc( mem, size, 0, (AstStcVtab *) vtab, - name, region, ncoords, coords ); - -/* If an error occurred, clean up by deleting the new StcSearchLocation. */ - if ( !astOK ) new = astDelete( new ); - -/* Return a pointer to the new StcSearchLocation. */ - return new; -} - -AstStcSearchLocation *astLoadStcSearchLocation_( void *mem, size_t size, AstStcSearchLocationVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadStcSearchLocation - -* Purpose: -* Load a StcSearchLocation. - -* Type: -* Protected function. - -* Synopsis: -* #include "stcsearchlocation.h" -* AstStcSearchLocation *astLoadStcSearchLocation( void *mem, size_t size, AstStcSearchLocationVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* StcSearchLocation loader. - -* Description: -* This function is provided to load a new StcSearchLocation using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* StcSearchLocation structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a StcSearchLocation at the start of the memory -* passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory into which the StcSearchLocation is to be -* loaded. This must be of sufficient size to accommodate the -* StcSearchLocation data (sizeof(StcSearchLocation)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the StcSearchLocation (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the StcSearchLocation structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstStcSearchLocation) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new StcSearchLocation. If this is NULL, a pointer -* to the (static) virtual function table for the StcSearchLocation class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "StcSearchLocation" is used instead. - -* Returned Value: -* A pointer to the new StcSearchLocation. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstStcSearchLocation *new; /* Pointer to the new StcSearchLocation */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this StcSearchLocation. In this case the - StcSearchLocation belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstStcSearchLocation ); - vtab = &class_vtab; - name = "StcSearchLocation"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitStcSearchLocationVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built StcSearchLocation. */ - new = astLoadStc( mem, size, (AstStcVtab *) vtab, name, channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "StcSearchLocation" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* There are no values to read. */ -/* ---------------------------- */ - -/* If an error occurred, clean up by deleting the new StcSearchLocation. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new StcSearchLocation pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - - - - - - diff --git a/ast/stcsearchlocation.h b/ast/stcsearchlocation.h deleted file mode 100644 index c359711..0000000 --- a/ast/stcsearchlocation.h +++ /dev/null @@ -1,222 +0,0 @@ -#if !defined( STCSEARCHLOCATION_INCLUDED ) /* Include this file only once */ -#define STCSEARCHLOCATION_INCLUDED -/* -*+ -* Name: -* stcsearchlocation.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the StcSearchLocation class. - -* Invocation: -* #include "stcsearchlocation.h" - -* Description: -* This include file defines the interface to the StcSearchLocation class -* and provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The StcSearchLocation class is a sub-class of Stc used to describe -* the coverage of a VO query. -* -* See http://hea-www.harvard.edu/~arots/nvometa/STC.html - -* Inheritance: -* The StcSearchLocation class inherits from the Stc class. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 26-NOV-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "stc.h" /* Coordinate stcs (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* StcSearchLocation structure. */ -/* ----------------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstStcSearchLocation { - -/* Attributes inherited from the parent class. */ - AstStc stc; /* Parent class structure */ - -} AstStcSearchLocation; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstStcSearchLocationVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstStcVtab stc_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -} AstStcSearchLocationVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstStcSearchLocationGlobals { - AstStcSearchLocationVtab Class_Vtab; - int Class_Init; -} AstStcSearchLocationGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitStcSearchLocationGlobals_( AstStcSearchLocationGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(StcSearchLocation) /* Check class membership */ -astPROTO_ISA(StcSearchLocation) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstStcSearchLocation *astStcSearchLocation_( void *, int, AstKeyMap **, const char *, int *, ...); -#else -AstStcSearchLocation *astStcSearchLocationId_( void *, int, AstKeyMap **, const char *, ... )__attribute__((format(printf,4,5))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstStcSearchLocation *astInitStcSearchLocation_( void *, size_t, int, AstStcSearchLocationVtab *, const char *, AstRegion *, int, AstKeyMap **, int * ); - -/* Vtab initialiser. */ -void astInitStcSearchLocationVtab_( AstStcSearchLocationVtab *, const char *, int * ); - -/* Loader. */ -AstStcSearchLocation *astLoadStcSearchLocation_( void *, size_t, AstStcSearchLocationVtab *, const char *, AstChannel *, int * ); - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckStcSearchLocation(this) astINVOKE_CHECK(StcSearchLocation,this,0) -#define astVerifyStcSearchLocation(this) astINVOKE_CHECK(StcSearchLocation,this,1) - -/* Test class membership. */ -#define astIsAStcSearchLocation(this) astINVOKE_ISA(StcSearchLocation,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astStcSearchLocation astINVOKE(F,astStcSearchLocation_) -#else -#define astStcSearchLocation astINVOKE(F,astStcSearchLocationId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitStcSearchLocation(mem,size,init,vtab,name,region,ncoords,coords) \ -astINVOKE(O,astInitStcSearchLocation_(mem,size,init,vtab,name,region,ncoords,coords,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitStcSearchLocationVtab(vtab,name) astINVOKE(V,astInitStcSearchLocationVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadStcSearchLocation(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadStcSearchLocation_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckStcSearchLocation to validate StcSearchLocation pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#endif -#endif - - - - - diff --git a/ast/sun210_figures/cmpframe.pdf b/ast/sun210_figures/cmpframe.pdf deleted file mode 100644 index fd82293..0000000 Binary files a/ast/sun210_figures/cmpframe.pdf and /dev/null differ diff --git a/ast/sun210_figures/complex.pdf b/ast/sun210_figures/complex.pdf deleted file mode 100644 index b743453..0000000 Binary files a/ast/sun210_figures/complex.pdf and /dev/null differ diff --git a/ast/sun210_figures/frames.pdf b/ast/sun210_figures/frames.pdf deleted file mode 100644 index 66d2b2f..0000000 Binary files a/ast/sun210_figures/frames.pdf and /dev/null differ diff --git a/ast/sun210_figures/frameset.pdf b/ast/sun210_figures/frameset.pdf deleted file mode 100644 index d5d9a1a..0000000 Binary files a/ast/sun210_figures/frameset.pdf and /dev/null differ diff --git a/ast/sun210_figures/fronta.pdf b/ast/sun210_figures/fronta.pdf deleted file mode 100644 index 3433a3d..0000000 Binary files a/ast/sun210_figures/fronta.pdf and /dev/null differ diff --git a/ast/sun210_figures/fronta_bw.pdf b/ast/sun210_figures/fronta_bw.pdf deleted file mode 100644 index 2a5ff7e..0000000 Binary files a/ast/sun210_figures/fronta_bw.pdf and /dev/null differ diff --git a/ast/sun210_figures/frontb.pdf b/ast/sun210_figures/frontb.pdf deleted file mode 100644 index 16aeef3..0000000 Binary files a/ast/sun210_figures/frontb.pdf and /dev/null differ diff --git a/ast/sun210_figures/frontb_bw.pdf b/ast/sun210_figures/frontb_bw.pdf deleted file mode 100644 index 78fa1db..0000000 Binary files a/ast/sun210_figures/frontb_bw.pdf and /dev/null differ diff --git a/ast/sun210_figures/frontc.pdf b/ast/sun210_figures/frontc.pdf deleted file mode 100644 index 69ab837..0000000 Binary files a/ast/sun210_figures/frontc.pdf and /dev/null differ diff --git a/ast/sun210_figures/frontc_bw.pdf b/ast/sun210_figures/frontc_bw.pdf deleted file mode 100644 index 17fce95..0000000 Binary files a/ast/sun210_figures/frontc_bw.pdf and /dev/null differ diff --git a/ast/sun210_figures/fsalign.pdf b/ast/sun210_figures/fsalign.pdf deleted file mode 100644 index 7d28fb7..0000000 Binary files a/ast/sun210_figures/fsalign.pdf and /dev/null differ diff --git a/ast/sun210_figures/fsconvert.pdf b/ast/sun210_figures/fsconvert.pdf deleted file mode 100644 index 5b07041..0000000 Binary files a/ast/sun210_figures/fsconvert.pdf and /dev/null differ diff --git a/ast/sun210_figures/fsexample.pdf b/ast/sun210_figures/fsexample.pdf deleted file mode 100644 index 1ba073a..0000000 Binary files a/ast/sun210_figures/fsexample.pdf and /dev/null differ diff --git a/ast/sun210_figures/fsmerge.pdf b/ast/sun210_figures/fsmerge.pdf deleted file mode 100644 index 2098b15..0000000 Binary files a/ast/sun210_figures/fsmerge.pdf and /dev/null differ diff --git a/ast/sun210_figures/fsremap.pdf b/ast/sun210_figures/fsremap.pdf deleted file mode 100644 index 2967186..0000000 Binary files a/ast/sun210_figures/fsremap.pdf and /dev/null differ diff --git a/ast/sun210_figures/gridplot.pdf b/ast/sun210_figures/gridplot.pdf deleted file mode 100644 index 65953d1..0000000 Binary files a/ast/sun210_figures/gridplot.pdf and /dev/null differ diff --git a/ast/sun210_figures/gridplot_bw.pdf b/ast/sun210_figures/gridplot_bw.pdf deleted file mode 100644 index 67353bc..0000000 Binary files a/ast/sun210_figures/gridplot_bw.pdf and /dev/null differ diff --git a/ast/sun210_figures/mapping.pdf b/ast/sun210_figures/mapping.pdf deleted file mode 100644 index 78c12b7..0000000 Binary files a/ast/sun210_figures/mapping.pdf and /dev/null differ diff --git a/ast/sun210_figures/overgrid.pdf b/ast/sun210_figures/overgrid.pdf deleted file mode 100644 index 82c65cf..0000000 Binary files a/ast/sun210_figures/overgrid.pdf and /dev/null differ diff --git a/ast/sun210_figures/overgrid_bw.pdf b/ast/sun210_figures/overgrid_bw.pdf deleted file mode 100644 index 10d65ab..0000000 Binary files a/ast/sun210_figures/overgrid_bw.pdf and /dev/null differ diff --git a/ast/sun210_figures/parallel.pdf b/ast/sun210_figures/parallel.pdf deleted file mode 100644 index 42ff646..0000000 Binary files a/ast/sun210_figures/parallel.pdf and /dev/null differ diff --git a/ast/sun210_figures/series.pdf b/ast/sun210_figures/series.pdf deleted file mode 100644 index df2a23b..0000000 Binary files a/ast/sun210_figures/series.pdf and /dev/null differ diff --git a/ast/sun210_figures/simpexamp.pdf b/ast/sun210_figures/simpexamp.pdf deleted file mode 100644 index d63a5af..0000000 Binary files a/ast/sun210_figures/simpexamp.pdf and /dev/null differ diff --git a/ast/sun211_figures/cmpframe.pdf b/ast/sun211_figures/cmpframe.pdf deleted file mode 100644 index 63ca4e1..0000000 Binary files a/ast/sun211_figures/cmpframe.pdf and /dev/null differ diff --git a/ast/sun211_figures/complex.pdf b/ast/sun211_figures/complex.pdf deleted file mode 100644 index 8e5bbb9..0000000 Binary files a/ast/sun211_figures/complex.pdf and /dev/null differ diff --git a/ast/sun211_figures/frames.pdf b/ast/sun211_figures/frames.pdf deleted file mode 100644 index dbf5070..0000000 Binary files a/ast/sun211_figures/frames.pdf and /dev/null differ diff --git a/ast/sun211_figures/frameset.pdf b/ast/sun211_figures/frameset.pdf deleted file mode 100644 index 697fe38..0000000 Binary files a/ast/sun211_figures/frameset.pdf and /dev/null differ diff --git a/ast/sun211_figures/fronta.pdf b/ast/sun211_figures/fronta.pdf deleted file mode 100644 index 3433a3d..0000000 Binary files a/ast/sun211_figures/fronta.pdf and /dev/null differ diff --git a/ast/sun211_figures/fronta_bw.pdf b/ast/sun211_figures/fronta_bw.pdf deleted file mode 100644 index 54cf906..0000000 Binary files a/ast/sun211_figures/fronta_bw.pdf and /dev/null differ diff --git a/ast/sun211_figures/frontb.pdf b/ast/sun211_figures/frontb.pdf deleted file mode 100644 index 16aeef3..0000000 Binary files a/ast/sun211_figures/frontb.pdf and /dev/null differ diff --git a/ast/sun211_figures/frontb_bw.pdf b/ast/sun211_figures/frontb_bw.pdf deleted file mode 100644 index 03df1c2..0000000 Binary files a/ast/sun211_figures/frontb_bw.pdf and /dev/null differ diff --git a/ast/sun211_figures/frontc.pdf b/ast/sun211_figures/frontc.pdf deleted file mode 100644 index 69ab837..0000000 Binary files a/ast/sun211_figures/frontc.pdf and /dev/null differ diff --git a/ast/sun211_figures/frontc_bw.pdf b/ast/sun211_figures/frontc_bw.pdf deleted file mode 100644 index 29fa5e1..0000000 Binary files a/ast/sun211_figures/frontc_bw.pdf and /dev/null differ diff --git a/ast/sun211_figures/fsalign.pdf b/ast/sun211_figures/fsalign.pdf deleted file mode 100644 index e0b8c15..0000000 Binary files a/ast/sun211_figures/fsalign.pdf and /dev/null differ diff --git a/ast/sun211_figures/fsconvert.pdf b/ast/sun211_figures/fsconvert.pdf deleted file mode 100644 index 3950b3b..0000000 Binary files a/ast/sun211_figures/fsconvert.pdf and /dev/null differ diff --git a/ast/sun211_figures/fsexample.pdf b/ast/sun211_figures/fsexample.pdf deleted file mode 100644 index 097114d..0000000 Binary files a/ast/sun211_figures/fsexample.pdf and /dev/null differ diff --git a/ast/sun211_figures/fsmerge.pdf b/ast/sun211_figures/fsmerge.pdf deleted file mode 100644 index 5d6c198..0000000 Binary files a/ast/sun211_figures/fsmerge.pdf and /dev/null differ diff --git a/ast/sun211_figures/fsremap.pdf b/ast/sun211_figures/fsremap.pdf deleted file mode 100644 index 31772d3..0000000 Binary files a/ast/sun211_figures/fsremap.pdf and /dev/null differ diff --git a/ast/sun211_figures/gridplot.pdf b/ast/sun211_figures/gridplot.pdf deleted file mode 100644 index c06b370..0000000 Binary files a/ast/sun211_figures/gridplot.pdf and /dev/null differ diff --git a/ast/sun211_figures/gridplot_bw.pdf b/ast/sun211_figures/gridplot_bw.pdf deleted file mode 100644 index 67353bc..0000000 Binary files a/ast/sun211_figures/gridplot_bw.pdf and /dev/null differ diff --git a/ast/sun211_figures/mapping.pdf b/ast/sun211_figures/mapping.pdf deleted file mode 100644 index 8228188..0000000 Binary files a/ast/sun211_figures/mapping.pdf and /dev/null differ diff --git a/ast/sun211_figures/overgrid.pdf b/ast/sun211_figures/overgrid.pdf deleted file mode 100644 index f78a965..0000000 Binary files a/ast/sun211_figures/overgrid.pdf and /dev/null differ diff --git a/ast/sun211_figures/overgrid_bw.pdf b/ast/sun211_figures/overgrid_bw.pdf deleted file mode 100644 index 0d972d4..0000000 Binary files a/ast/sun211_figures/overgrid_bw.pdf and /dev/null differ diff --git a/ast/sun211_figures/parallel.pdf b/ast/sun211_figures/parallel.pdf deleted file mode 100644 index 18f9911..0000000 Binary files a/ast/sun211_figures/parallel.pdf and /dev/null differ diff --git a/ast/sun211_figures/series.pdf b/ast/sun211_figures/series.pdf deleted file mode 100644 index 11656da..0000000 Binary files a/ast/sun211_figures/series.pdf and /dev/null differ diff --git a/ast/sun211_figures/simpexamp.pdf b/ast/sun211_figures/simpexamp.pdf deleted file mode 100644 index a685837..0000000 Binary files a/ast/sun211_figures/simpexamp.pdf and /dev/null differ diff --git a/ast/sun_master.tex b/ast/sun_master.tex deleted file mode 100644 index cfa6c43..0000000 --- a/ast/sun_master.tex +++ /dev/null @@ -1,21879 +0,0 @@ -\documentclass[twoside,11pt]{starlink} - -% ? Specify used packages -% ? End of specify used packages - -% ----------------------------------------------------------------------------- -% ? Document identification -% Fixed part -\stardoccategory {Starlink User Note} -\stardocinitials {SUN} -\stardocsource {sun\stardocnumber} - -% Variable part - replace [xxx] as appropriate. -c+ -\stardocnumber {211.28} -c- -f+ -\stardocnumber {210.28} -f- -\stardocauthors {R.F. Warren-Smith \& D.S. Berry} -\stardocdate {17th October 2017} -\stardoctitle {AST\linebreak% - A Library for Handling\linebreak% - World Coordinate Systems\linebreak% - in Astronomy} -\stardoccopyright {Copyright (C) 2017 East Asian Observatory} -\stardocversion {V} -c+ -\stardocmanual {Programmer's Guide\\(C Version)} -\startitlepic{ - \includegraphics[width=0.25\textwidth]{sun211_figures/fronta}~~~~~\hfill - \includegraphics[width=0.25\textwidth]{sun211_figures/frontb}~~~~~\hfill - \includegraphics[width=0.25\textwidth]{sun211_figures/frontc} -} -c- -f+ -\stardocmanual {Programmer's Guide\\(Fortran Version)} -\startitlepic{ - \includegraphics[width=0.25\textwidth]{sun210_figures/fronta}~~~~~\hfill - \includegraphics[width=0.25\textwidth]{sun210_figures/frontb}~~~~~\hfill - \includegraphics[width=0.25\textwidth]{sun210_figures/frontc} -} -f- -\stardocabstract { -The AST library provides a comprehensive range of facilities for -attaching world coordinate systems to astronomical data, for -retrieving and interpreting that information in a variety of formats, -including FITS-WCS, and for generating graphical output based on it. - -This programmer's manual should be of interest to anyone writing -astronomical applications which need to manipulate coordinate system -data, especially celestial or spectral coordinate systems. AST is portable and -environment-independent. -} -% ? End of document identification -% ----------------------------------------------------------------------------- -% ? Document specific \providecommand or \newenvironment commands. - -\providecommand{\appref}[1]{Appendix~\ref{#1}} -\providecommand{\secref}[1]{\S\ref{#1}} - -\providecommand{\fitskey}[3]{{#1}&{#2}&{#3}\\} - -% Use {\tt ... } as \texttt{...} does not work if there are new lines in #1 -\providecommand{\sstsynopsis}[1]{\sstdiytopic{Synopsis}{\tt #1}} - -% Format the constructor section. -\providecommand{\sstconstructor}[1]{\sstdiytopic{Constructor Function}{#1}} - -% ? End of document specific commands -% ----------------------------------------------------------------------------- -% Title Page. -% =========== -\begin{document} -\scfrontmatter - -\begin{center} -c+ -\emph{This is the C version of this document.\\ - For the Fortran version, please see \xref{SUN/210}{sun210}{}.} -c- -f+ -\emph{This is the Fortran version of this document.\\ - For the C version, please see \xref{SUN/211}{sun211}{}.} -f- -\end{center} - -% Main text of document. -\vspace{7mm} -\section{Introduction} - -Welcome to the AST library. If you are writing software for astronomy -and need to use celestial coordinates (\emph{e.g.}\ RA and Dec), spectral -coordinates (\emph{e.g.}\ wavelength, frequency, \emph{etc.}), or -other coordinate system information, then this library should be of -interest. It provides solutions for most of the problems you will meet -and allows you to write robust and flexible software. It is able to read -and write WCS information in a variety of formats, including -\htmladdnormallink{FITS-WCS}{http://fits.gsfc.nasa.gov/fits_wcs.html}. - -%\subsection{TBW---What is a World Coordinate System?} - -\subsection{What Problems Does AST Tackle?} - -Here are some of the main problems you may face when handling world -coordinate system (WCS) information and the solutions that AST -provides: - -\begin{description} -\item[1. The Variety of Coordinate Systems]\mbox{}\\ -Astronomers use a wide range of differing coordinate systems to describe -positions within a variety of physical domains. For instance, there are a -large number of celestial coordinate systems in use within astronomy to -describe positions on the sky. Understanding these, and knowing how to -convert coordinates between them, can require considerable expertise. It -can also be difficult to decide which of them your software should support. -The same applies to coordinate systems describing other domains, such as -position within an electro-magnetic spectrum. - -\textbf{Solution.} AST has built-in knowledge of many coordinate systems -and allows you to convert freely between them without specialist -knowledge. This avoids the need to embed details of specific -coordinate systems in your software. You also benefit automatically -when new coordinate systems are added to AST. - -\item[2. Storing and Retrieving WCS Information]\mbox{}\\ -Storing coordinate system information in astronomical datasets and -retrieving it later can present a considerable challenge. Typically, -it requires knowledge of rather complex conventions -(\emph{e.g.}\ FITS) which are low-level, often mis-interpreted and may -be subject to change. Exchanging information with other software -systems is further complicated by the number of different conventions -in use. - -\textbf{Solution.} AST combines a unifying high-level description of WCS -information with the ability to save and restore this using a variety -of formats. Details of the formats, which include FITS, are handled -internally by AST. This frees you from the need to understand them or -embed the details in your software. Again, you benefit automatically -when new formats are added to AST. - -\item[3. Generating Graphical Output]\mbox{}\\ -Producing graphical displays involving curvilinear coordinate systems, -such as celestial coordinate grids, can be complicated. Particular -difficulties arise when handling large areas of sky, the polar regions -and discontinuous (\emph{e.g.}\ segmented) sky projections. Even just -numbering and labelling curvilinear axes is rarely straightforward. - -\textbf{Solution.} AST provides plotting facilities especially designed -for use with curvilinear coordinate systems. These include the -plotting of axes and complete labelled coordinate grids. A large -number of options are provided for tailoring the output to your -specific needs. Three dimensional coordinate grids can also be produced. - -\item[4. Aligning Data from Different Sources]\mbox{}\\ -One of the main uses of coordinate systems is to facilitate the -inter-comparison of data from different sources. A typical use might -be to plot (say) radio contours over an optical image. In practice, -however, different celestial coordinate systems may have been used, -making accurate alignment far from simple. - -\textbf{Solution} AST provides a one-step method of aligning datasets, -searching for all possible intermediate coordinate systems. This -makes it simple to directly inter-relate the pixel coordinates of -different datasets. - -\item[5. Handling Different Types of Coordinate System]\mbox{}\\ -Not all coordinate systems used in astronomy are celestial ones, so if -you are writing general-purpose software such as (say) a display tool, -you may also need to handle axes representing wavelength, distance, -time or whatever else comes along. Obviously, you would prefer not to -handle each one as a special case. - -\textbf{Solution} AST uses the same flexible high-level model to -describe all types of coordinate system. This allows you to write -software that handles different kinds of coordinate axis without -introducing special cases. -\end{description} - -\subsection{Other Design Objectives} - -As well as its scientific objectives, the AST library's design -includes a number of technical criteria intended to make it applicable -to as wide a range of projects as possible. The main considerations -are described here: - -\begin{enumerate} -\item {\bf{Minimum Software Dependencies.}} -The AST library depends on no other other software\footnote{It comes with -bundled copies of the ERFA and -\xref{Starlink PAL libraries}{sun268}{} which are built -at the same time as the other AST internal libraries. Alternatively, external -PAL and ERFA libraries may be used by specifying the ``\texttt{--with-external\_pal}'' option when configuring AST}. - -\item {\bf{Environment Independence.}} -AST is designed so that it can operate in a variety of ``programming -environments'' and is not tied to any particular one. To allow this, -it uses simple, flexible interfaces to obtain the following services: - -\begin{itemize} -\item {\bf{Data Storage.}} Data I/O operations are based on text -and/or FITS headers. This makes it easy to interface to a wide variety -of astronomical data formats in a machine-independent way. - -\item {\bf{Graphics.}} Graphical output is produced \emph{via} a -simple generic graphics interface, which may easily be re-implemented -over different graphics systems. AST provides a default implementation -based on the widely-used PGPLOT graphics system -(\xref{SUN/15}{sun15}{}). - -\item {\bf{Error Handling.}} Error messages are written to standard -error by default, but go through a simple generic interface similar to -that used for graphics (above). This permits error message delivery -\emph{via} other routes when necessary (\emph{e.g.} in a graphical -interface). -\end{itemize} - -\item {\bf{Multiple Language Support.}} -AST has been designed to be called from more than one language. -c+ -Both C and Fortran interfaces are available (see -\xref{SUN/210}{sun210}{} for the Fortran version) -c- -f+ -Both Fortran and C interfaces are available (see -\xref{SUN/211}{sun211}{} for the C version) -f- -and use from C$++$ is also straightforward if the C interface is -included using: - -\begin{small} -\begin{terminalv} -extern "C" { -#include "ast.h" -} -\end{terminalv} -\end{small} - -A JNI interface (known as ``JNIAST'' - see -\url{http://www.starlink.ac.uk/jniast/}) has also been developed by Starlink -which allows AST to be used from Java. - -\item {\bf{Object Oriented Design.}} -AST uses ``object oriented'' techniques internally in order to provide -a flexible and easily-extended programming model. A fairly -traditional calling interface is provided, however, so that the -library's facilities are easily accessible to programmers using -c+ -C and Fortran. -c- -f+ -Fortran and C. -f- - -\item {\bf{Portability.}} -AST is implemented entirely in ANSI standard C and, when called -\emph{via} its C interface, makes no explicit use of any -machine-dependent facilities. - -The Fortran interface is, unavoidably, machine dependent. However, the -potential for problems has been minimised by encapsulating the -interface layer in a compact set of C macros which facilitate its -transfer to other platforms. No Fortran compiler is needed to build -the library. - -Currently, AST is supported by Starlink on PC~Linux, Sun~Solaris and -Tru64~Unix (formerly DEC~UNIX) platforms. -\end{enumerate} - -\subsection{What Does ``AST'' Stand For?} - -The library name ``AST'' stands for ``ASTrometry Library''. The name -arose when it was thought that knowledge of ``astrometry'' -(\emph{i.e.}\ celestial coordinate systems) would form the bulk of the -library. In fact, it turns out that astrometry forms only a minor -component, but the name AST has stuck. - -\cleardoublepage -\section{Overview of AST Concepts} - -This section presents a brief overview of AST concepts. It is intended -as a basic orientation course before you move on to the more technical -considerations in subsequent sections. - -\subsection{\label{ss:mappingoverview}Relationships Between Coordinate Systems} - -The relationships between coordinate systems are represented in AST by -Objects called Mappings. A Mapping does not represent a coordinate -system itself, but merely the process by which you move from one -coordinate system to another related one. - - A convenient picture of a Mapping is as a ``black box'' - (Figure~\ref{fig:mapping}) into which you can feed sets of - coordinates. - \begin{figure}[bhtp] - \begin{center} -c+ - \includegraphics[width=0.7\textwidth]{sun211_figures/mapping} -c- -f+ - \includegraphics[width=0.7\textwidth]{sun210_figures/mapping} -f- - \caption{A Mapping viewed as a ``black box'' for transforming coordinates.} - \label{fig:mapping} - \end{center} - \end{figure} - -For each set you feed in, the Mapping returns a corresponding set of -transformed coordinates. Since each set of coordinates represents a -point in a coordinate space, the Mapping acts to inter-relate -corresponding positions in the two spaces, although what these spaces -represent is unspecified. Notice that a Mapping need not have the -same number of input and output coordinates. That is, the two -coordinate spaces which it inter-relates need not have the same number -of dimensions. - -In many cases, the transformation can, in principle, be performed in -either direction: either from the \emph{input} coordinate space to the -\emph{output}, or \emph{vice versa}. The first of these is termed the -\emph{forward} transformation and the other the \emph{inverse} -transformation. - - -\textbf{Further reading:} For a more complete discussion of Mappings, -see~\secref{ss:mappings}. - -\subsection{\label{ss:mappingselection}Mappings Available} - -The basic concept of a Mapping (\secref{ss:mappingoverview}) is rather -generic and obviously it is necessary to have specific Mappings that -implement specific relationships between coordinate systems. AST -provides a range of these, to perform transformations such as the -following and, where appropriate, their inverses: - -\begin{itemize} -\item Conversions between various celestial coordinate systems (the -SlaMap). - -\item Conversions between various spectral coordinate systems (the -SpecMap and GrismMap). - -\item Conversions between various time systems (the TimeMap). - -\item Conversion between 2-dimensional spherical celestial coordinates -(longitude and latitude) and a 3-dimensional vectorial positions (the SphMap). - -\item Various projections of the celestial sphere on to 2-dimensional -coordinate spaces---\emph{i.e.}\ map projections (the DssMap and WcsMap). - -\item Permutation, introduction and elimination of coordinates (the -PermMap). - -\item Various linear coordinate transformations (the MatrixMap, WinMap, -ShiftMap and ZoomMap). - -\item General N-dimensional polynomial transformations (the PolyMap and -ChebyMap). - -\item Lookup tables (the LutMap). - -c+ -\item General-purpose transformations expressed using arithmetic -operations and functions similar to those available in C (the -MathMap). -c- -f+ -\item General-purpose transformations expressed using arithmetic -operations and functions similar to those available in Fortran (the -MathMap). -f- - -c+ -\item Transformations for internal use within a program, based on -private transformation functions which you write yourself in C (the -IntraMap). -c- -f+ -\item Transformations for internal use within a program, based on -private transformation routines which you write yourself in Fortran -(the IntraMap). -f- -\end{itemize} - -\textbf{Further reading:} For a more complete description of each of the -Mappings mentioned above, see its entry in -\appref{ss:classdescriptions}. In addition, see the discussion of the -PermMap in \secref{ss:permmapexample}, the UnitMap in -\secref{ss:unitmapexample} and the IntraMap in -\secref{ss:intramaps}. The ZoomMap is used as an example throughout -\secref{ss:primer}. - -\subsection{\label{ss:cmpmapoverview}Compound Mappings} - -The Mappings described in \secref{ss:mappingselection} provide a set -of basic building blocks from which more complex Mappings may be -constructed. The key to doing this is a type of Mapping called a -CmpMap, or compound Mapping. A CmpMap's role is, in principle, very -simple: it allows any other pair of Mappings to be joined together -into a single entity which behaves as if it were a single Mapping. A -CmpMap is therefore a container for another pair of Mappings. - - A pair of Mappings may be combined using a CmpMap in either of two - ways. The first of these, \emph{in series}, is illustrated in - Figure~\ref{fig:seriescmpmap}. - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.7\textwidth]{sun211_figures/series} -c- -f+ - \includegraphics[width=0.7\textwidth]{sun210_figures/series} -f- - \caption[A CmpMap composed of two component Mappings joined in series]{A CmpMap (compound Mapping) composed of two component - Mappings joined in series. The output coordinates of the first Mapping - feed into the input coordinates of the second one, so that the whole - entity behaves like a single Mapping.} - \label{fig:seriescmpmap} - \end{center} - \end{figure} - - - Here, the transformations implemented by each component Mapping are - performed one after the other, with the output from the first Mapping - feeding into the second. The second way, \emph{in parallel}, is shown in - Figure~\ref{fig:parallelcmpmap}. - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.5\textwidth]{sun211_figures/parallel} -c- -f+ - \includegraphics[width=0.5\textwidth]{sun210_figures/parallel} -f- - \caption[A CmpMap composed of two Mappings joined in parallel.]{A CmpMap composed of two Mappings joined in parallel. Each - component Mapping acts on a complementary subset of the input and - output coordinates.} - \label{fig:parallelcmpmap} - \end{center} - \end{figure} - -In this case, each Mapping acts on a complementary subset of the -input and output coordinates.\footnote{A pair of Mappings can be combined -in a third way using a TranMap. A TranMap allows the forward -transformation of one Mapping to be combined with the inverse -transformation of another to produce a single Mapping.} - - The CmpMap forms the key to building arbitrarily complex Mappings - because it is itself a form of Mapping. This means that a CmpMap may - contain other CmpMaps as components - (\emph{e.g.}\ Figure~\ref{fig:complexcmpmap}). This nesting of CmpMaps - can be repeated indefinitely, so that complex Mappings may be built in - a hierarchical manner out of simper ones. - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.65\textwidth]{sun211_figures/complex} -c- -f+ - \includegraphics[width=0.65\textwidth]{sun210_figures/complex} -f- - \caption[CmpMaps may be nested in order to - construct complex Mappings out of simpler building blocks.]{CmpMaps - (compound Mappings) may be nested in order to - construct complex Mappings out of simpler building blocks.} - \label{fig:complexcmpmap} - \end{center} - \end{figure} - This gives AST great flexibility in the coordinate transformations it - can describe. - -\textbf{Further reading:} For a more complete description of CmpMaps, -see \secref{ss:cmpmaps}. Also see the CmpMap entry in -\appref{ss:classdescriptions}. - -\subsection{Representing Coordinate Systems} - - While Mappings (\secref{ss:mappingoverview}) represent the - relationships between coordinate systems in AST, the coordinate - systems themselves are represented by Objects called Frames - (Figure~\ref{fig:frames}). - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.55\textwidth]{sun211_figures/frames} -c- -f+ - \includegraphics[width=0.55\textwidth]{sun210_figures/frames} -f- - \caption[Representing coordinate systems as Frames.]{(a) A basic Frame is used to represent a Cartesian coordinate - system, here 2-dimensional. (b) A SkyFrame represents a (spherical) - celestial coordinate system. (c) The axis order of any Frame may be - permuted to match the coordinate space it describes.} - \label{fig:frames} - \end{center} - \end{figure} - -A Frame is similar in concept to the frame you might draw around a -graph. It contains information about the labels which appear on the -axes, the axis units, a title, knowledge of how to format the -coordinate values on each axis, \emph{etc.} An AST Frame is not, -however, restricted to two dimensions and may have any number of axes. - -c+ -A basic Frame may be used to represent a Cartesian coordinate system -by setting values for its \emph{attributes} (all AST Objects have -values associated with them called attributes, which may be set and -enquired). Usually, this would involve setting appropriate axis -labels and units, for example. Functions are provided for use with -Frames to perform operations such as formatting coordinate values as -text, calculating distances between points, interchanging axes, -\emph{etc.} -c- -f+ -A basic Frame may be used to represent a Cartesian coordinate system -by setting values for its \emph{attributes} (all AST Objects have -values associated with them called attributes, which may be set and -enquired). Usually, this would involve setting appropriate axis -labels and units, for example. Routines are provided for use with -Frames to perform operations such as formatting coordinate values as -text, calculating distances between points, interchanging axes, -\emph{etc.} -f- - -There are several more specialised forms of Frame, which provide the -additional functionality required when handling coordinates within some -specific physical domain. This ranges from tasks such as formatting axis -values, to complex tasks such as determining the transformation between -any pair of related coordinate systems. For instance, the SkyFrame -(Figure~\ref{fig:frames}b,c), represents celestial coordinate systems, -the SpecFrame represents spectral coordinate systems, and the TimeFrame -represents time coordinate systems. All these provide a wide range of -different systems for describing positions within their associated physical -domain, and these may be selected by setting appropriate attributes. - - As with compound Mappings (\secref{ss:cmpmapoverview}), it is possible - to merge two Frames together to form a compound Frame, or CmpFrame, in - which both sets of axes are combined. One could, for example, have - celestial coordinates on two axes and an unrelated coordinate - (wavelength, perhaps) on a third (Figure~\ref{fig:cmpframe}). - Knowledge of the relationships between the axes is preserved - internally by the process of constructing the CmpFrame which - represents them. - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.4\textwidth]{sun211_figures/cmpframe} -c- -f+ - \includegraphics[width=0.4\textwidth]{sun210_figures/cmpframe} -f- - \caption[A CmpFrame (compound Frame) formed by combining two simpler - Frames.]{A CmpFrame (compound Frame) formed by combining two simpler - Frames. Note how the special relationship which exists between the RA - and Dec axes is preserved within this data structure. As with compound - Mappings (Figure~\ref{fig:complexcmpmap}), CmpFrames may be nested in - order to build more complex Frames.} - \label{fig:cmpframe} - \end{center} - \end{figure} - -\textbf{Further reading:} For a more complete description of Frames see -\secref{ss:frames}, for SkyFrames see \secref{ss:skyframes} and for -SpecFrames see \secref{ss:specframes}. Also see the Frame, SkyFrame, -SpecFrame, TimeFrame and CmpFrame entries in \appref{ss:classdescriptions}. - -\subsection{Networks of Coordinate Systems} - - Mappings and Frames may be connected together to form networks called - FrameSets, which are used to represent sets of inter-related - coordinate systems (Figure~\ref{fig:frameset}). - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.65\textwidth]{sun211_figures/frameset} -c- -f+ - \includegraphics[width=0.65\textwidth]{sun210_figures/frameset} -f- - \caption[A FrameSet is a network of Frames.]{A FrameSet is a network of Frames inter-connected by Mappings - such that there is exactly one conversion path, \emph{via} Mappings, - between any pair of Frames.} - \label{fig:frameset} - \end{center} - \end{figure} - - -A FrameSet may be extended by adding a new Frame to it, together with -an associated Mapping which relates the new coordinate system to one -which is already present. This process ensures that there is always -exactly one path, \emph{via} Mappings, between any pair of Frames. A -function is provided for identifying this path and returning the -complete Mapping. - -One of the Frames in a FrameSet is termed its \emph{base} Frame. This -underlies the FrameSet's purpose, which is to calibrate datasets and -other entities by attaching coordinate systems to them. In this -context, the base Frame represents the ``native'' coordinate system -(for example, the pixel coordinates of an image). Similarly, one -Frame is termed the \emph{current} Frame and represents the -``currently-selected'' coordinates. It might, typically, be a -celestial or spectral coordinate system and would be used during -interactions with -a user, as when plotting axes on a graph or producing a table of -results. Other Frames within the FrameSet represent a library of -alternative coordinate systems which a software user can select by -making them current. - -\textbf{Further reading:} For a more complete description of -FrameSets, see \secref{ss:framesets} and \secref{ss:fshigher}. Also -see the FrameSet entry in \appref{ss:classdescriptions}. - -\subsection{Input/Output Facilities} - -AST allows you to convert any kind of Object into a stream of text -which contains a full description of that Object. This text may be -written out by one program and read back in by another, thus allowing -the original Object to be reconstructed. - -The filter which converts Objects into text and back again is itself a -kind of Object, called a Channel. A Channel provides a number of -options for controlling the information content of the text, such as -the addition of comments for human interpretation. It is also -possible to intercept the text being processed by a Channel so that it -may be redirected to/from any chosen external data store, such as a -text file, an astronomical dataset, or a network connection. - -The text format used by the basic Channel class is peculiar to the AST -library - no other software will understand it. However, more specialised -forms of Channel are provided which use text formats more widely -understood. - -To further facilitate the storage of coordinate system information in -astronomical datasets, a more specialised form of Channel called a -FitsChan is provided. Instead of using free-format text, a FitsChan -converts AST Objects to and from FITS header cards. It also allows the -information to be encoded in the FITS cards in a number of ways -(called \emph{encodings}), so that WCS information from a variety of -sources can be handled. - -Another sub-class of Channel, called XmlChan, is a specialised form of -Channel that stores the text in the form of XML markup. Currently, two -markup formats are provided by the XmlChan class, one is closely related -to the text format produced by the basic Channel class (currently, no -schema or DTD is available describing this format). The other is a subset -of an early draft of the IVOA Space-Time-Coordinates XML (STC-X) schema -(V1.20) described at -\url{http://www.ivoa.net/Documents/WD/STC/STC-20050225.html -}\footnote{XML documents which use only the subset of the STC schema -supported by AST can be read by the XmlChan class to produce -corresponding AST objects (subclasses of the Stc class). However, the -reverse is not possible. That is, AST objects can not currently be -written out in the form of STC documents.}. The version of STC-X that has -been adopted by the IVOA differs in several significant respects from -V1.20, and therefore this XmlChan format is of historical interest only. - -Finally, the StcsChan class provides facilities for reading and writing -IVOA STC-S region descriptions. STC-S (see -\url{http://www.ivoa.net/Documents/latest/STC-S.html}) is a linear string -syntax that allows simple specification of STC metadata. AST supports a -subset of the STC-S specification, allowing an STC-S description of a -region within an AST-supported astronomical coordinate system to be converted -into an equivalent AST Region object, and vice-versa. - -\textbf{Further reading:} For a more complete description of Channels -see \secref{ss:channels} and for FitsChans see \secref{ss:nativefits} -and \secref{ss:foreignfits}. Also see the Channel and FitsChan entries -in \appref{ss:classdescriptions} and the Encoding entry in -\appref{ss:attributedescriptions}. - -\subsection{Producing Graphical Output} - -Two dimensional graphical output is supported by a specialised form of -FrameSet called -a Plot, whose base Frame corresponds with the native coordinates of -the underlying graphics system. Plotting operations are specified in -\emph{physical coordinates} which correspond with the Plot's current -Frame. Typically, this might be a celestial coordinate system. - -Three dimensional plotting is also supported, via the Plot3D class - -sub-class of Plot. - -Operations, such as drawing lines, are automatically transformed from -physical to graphical coordinates before plotting, using an adaptive -algorithm which ensures smooth curves (because the transformation is -usually non-linear). ``Missing'' coordinates (\emph{e.g.}\ graphical -coordinates which do not project on to the celestial sphere), -discontinuities and generalised clipping are all consistently handled. -It is possible, for example, to plot in equatorial coordinates and -clip in galactic coordinates. The usual plotting operations are -provided (text, markers), but a geodesic curve replaces the primitive -straight line element. There is also a separate function for drawing -axis lines, since these are normally not geodesics. - -In addition to drawing coordinate grids over an area of the sky, another -common use of the Plot class is to produce line plots such as flux -against wavelength, displacement again time, \emph{etc}. For these -situations the current Frame of the Plot would be a compound Frame -(CmpFrame) containing a pair of 1-dimensional Frames - the first -representing the X axis quantity (wavelength, time, etc), and the second -representing the Y axis quantity (flux, displacement, etc). The Plot -class includes an option for axes to be plotted logarithmically. - - Perhaps the most useful graphics function available is for drawing - fully annotated coordinate grids (\emph{e.g.}\ Figure~\ref{fig:gridplot}). - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.6\textwidth]{sun211_figures/gridplot_bw} -c- -f+ - \includegraphics[width=0.6\textwidth]{sun210_figures/gridplot_bw} -f- - \caption[A labelled coordinate grid for an all-sky zenithal equal area - projection in ecliptic coordinates.]{A labelled coordinate grid for an all-sky zenithal equal area - projection in ecliptic coordinates. This was composed and drawn - \emph{via} a Plot using a -c+ - single function call.} -c- -f+ - single subroutine call.} -f- - \label{fig:gridplot} - \end{center} - \end{figure} - -This uses a general algorithm which does not depend on knowledge of -the coordinates being represented, so can also handle -programmer-defined coordinate systems. Grids for all-sky projections, -including polar regions, can be drawn and most aspects of the output -(colour, line style, \emph{etc.}) can be adjusted by setting -appropriate Plot attributes. - -\textbf{Further reading:} For a more complete description of -Plots and how to produce graphical output, see \secref{ss:plots}. Also -see the Plot entry in \appref{ss:classdescriptions}. - -\cleardoublepage -\section{\label{ss:howto}How To\ldots} - -For those of you with a plane to catch, this section provides some -instant templates and recipes for performing the most -commonly-required operations using AST, but without going into -detail. The examples given (sort of) follow on from each other, so you -should be able to construct a variety of programs by piecing them -together. Note that some of them appear longer than they actually -are, because we have included plenty of comments and a few options -that you probably won't need. - -If any of this material has you completely baffled, then you may want -to read the introduction to AST programming concepts in -\secref{ss:primer} first. Otherwise, references to more detailed -reading are given after each example, just in case they don't quite do -what you want. - -\subsection{\ldots Obtain and Install AST} -The AST library is available both as a stand-alone package and also as -part of the Starlink Software Collection\footnote{The Starlink Software -Collection can be downloaded from -\url{http://www.starlink.ac.uk/Download/}.}. If your site has the Starlink -Software Collection installed then AST should already be available. - -If not, you can download the AST library by itself from -\url{http://www.starlink.ac.uk/ast/}. - -\subsection{\ldots Structure an AST Program} - -An AST program normally has the following structure: - -c+ -\begin{small} -\begin{terminalv} -/* Include the interface to the AST library. */ -#include "ast.h" - -/* Main program (or could be any function). */ -main () { - - -/* Enclose the parts which use AST between the astBegin and astEnd macros. */ - astBegin; - - astEnd; - - -} -\end{terminalv} -\end{small} -c- -f+ -\small -\begin{terminalv} -* Include the interface to the AST library. - INCLUDE 'AST_PAR' - -* Declare an integer status variable. - INTEGER STATUS - - -* Initialise the status to zero. - STATUS = 0 - - -* Enclose the parts which use AST between AST_BEGIN and AST_END calls. - CALL AST_BEGIN( STATUS ) - - CALL AST_END( STATUS ) - - - END -\end{terminalv} -\normalsize -f- - -c+ -The use of astBegin and astEnd is optional, but has the effect of -tidying up after you have finished using AST, so is normally -recommended. For more details of this, see \secref{ss:contexts}. For -details of how to access the ``ast.h'' header file, see -\secref{ss:accessingheaderfile}. -c- -f+ -The use of AST\_BEGIN and AST\_END is optional, but has the effect of -tidying up after you have finished using AST, so is normally -recommended. For more details of this, see \secref{ss:contexts}. For -details of how to access the AST\_PAR include file, see -\secref{ss:accessingheaderfile}. -f- - -\subsection{\label{ss:howtobuild}\ldots Build an AST Program} - -To build a simple AST program that doesn't use graphics, use: - -c+ -\begin{small} -\begin{terminalv} -cc program.c -L/star/lib -I/star/include `ast_link` -o program -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} -f77 program.f -L/star/lib -I/star/include `ast_link` -o program -\end{terminalv} -\end{small} - -On Linux systems you should usually use \verb+g77 -fno-second-underscore+ in -place of \verb+f77+ - see \xref{``Software development on Linux''}{sun212} -{software_development_on_linux} in \xref{SUN/212}{sun212}{}. -f- - -To build a program which uses PGPLOT for graphics, use: - -c+ -\begin{small} -\begin{terminalv} -cc program.c -L/star/lib `ast_link -pgplot` -o program -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} -f77 program.f -L/star/lib `ast_link -pgplot` -o program -\end{terminalv} -\end{small} - -again using \verb+g77 -fno-second-underscore+ in place of \verb+f77+ -on Linux systems. -f- - -c+ -For more details about accessing the ``ast.h'' header file, see -\secref{ss:accessingheaderfile}. For more -details about linking programs, see \secref{ss:linking} and the -description of the ``ast\_link'' command in -\appref{ss:commanddescriptions}. -c- -f+ -For more details about accessing AST include files, see -\secref{ss:accessingheaderfile}. For more -details about linking programs, see \secref{ss:linking} and the -description of the ``ast\_link'' command in -\appref{ss:commanddescriptions}. -f- - -\subsection{\label{ss:howtoreadwcs}\ldots Read a WCS Calibration from a Dataset} - -c+ -Precisely how you extract world coordinate system (WCS) information -from a dataset obviously depends on what type of dataset it -is. Usually, however, you should be able to obtain a set of FITS -header cards which contain the WCS information (and probably much more -besides). Suppose that ``cards'' is a pointer to a string -containing a complete set of concatenated FITS header cards (such as -produced by the CFITSIO function fits\_hdr2str). Then proceed as follows: - -\begin{small} -\begin{terminalv} -fitsfile *fptr; -AstFitsChan *fitschan; -AstFrameSet *wcsinfo; -char *header; -int nkeys, status; - -... - -/* Obtain all the cards in the header concatenated into a single dynamically - allocated null-terminated character string. Note, we do not exclude - any cards since we may later modify the WCS information within the - header and consequently want to write the entire header out again. */ - if( fits_hdr2str( fptr, 0, NULL, 0, &header, &nkeys, &status ) ) - printf(" Error getting header\n"); - ... - -/* Header obtained succesfully... */ - } else { - -/* Create a FitsChan and fill it with FITS header cards. */ - fitschan = astFitsChan( NULL, NULL, "" ); - astPutCards( fitschan, header ); - -/* Free the memory holding the concatenated header cards. */ - header = free( header ); - -/* Read WCS information from the FitsChan. */ - wcsinfo = astRead( fitschan ); - - ... - -\end{terminalv} -\end{small} -c- - -f+ -Precisely how you extract world coordinate system (WCS) information -from a dataset obviously depends on what type of dataset it -is. Usually, however, you should be able to obtain a set of FITS -header cards which contain the WCS information (and probably much more -besides). Suppose that CARDS is an array of character strings -containing a complete set of FITS header cards and NCARD is the number -of cards. Then proceed as follows: - -\small -\begin{terminalv} - INTEGER FITSCHAN, ICARD, NCARD, WCSINFO - CHARACTER * ( 80 ) CARDS( NCARD ) - - ... - -* Create a FitsChan and fill it with FITS header cards. - FITSCHAN = AST_FITSCHAN( AST_NULL, AST_NULL, ' ', STATUS ) - DO 1 ICARD = 1, NCARD - CALL AST_PUTFITS( FITSCHAN, CARDS( ICARD ), .FALSE., STATUS ) - 1 CONTINUE - -* Rewind the FitsChan and read WCS information from it. - CALL AST_CLEAR( FITSCHAN, 'Card', STATUS ) - WCSINFO = AST_READ( FITSCHAN, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -The result should be a pointer, ``wcsinfo'', to a FrameSet which -contains the WCS information. This pointer can now be used to perform -many useful tasks, some of which are illustrated in the following -recipes. -c- -f+ -The result should be a pointer, WCSINFO, to a FrameSet which contains -the WCS information. This pointer can now be used to perform many -useful tasks, some of which are illustrated in the following recipes. -f- - -c+ -Some datasets which do not easily yield FITS header cards may require -a different approach, possibly involving use of a Channel or XmlChan -(\secref{ss:channels}) rather than a FitsChan. In the case of the -Starlink NDF data format, for example, all the above may be replaced -by a single call to the function -\xref{ndfGtwcs}{sun33}{ndfGtwcs}---see \xref{SUN/33}{sun33}{}. The -whole process can probably be encapsulated in a similar way for -most data systems, whether they use FITS header cards or not. -c- -f+ -Some datasets which do not easily yield FITS header cards may require -a different approach, possibly involving use of a Channel or XmlChan -(\secref{ss:channels}) rather than a FitsChan. In the case of the -Starlink NDF data format, for example, all the above may be replaced -by a single call to the routine -\xref{NDF\_GTWCS}{sun33}{NDF_GTWCS}---see \xref{SUN/33}{sun33}{}. The -whole process can probably be encapsulated in a similar way for most -other data systems, whether they use FITS header cards or not. -f- - -For more details about reading WCS information from datasets, see -\secref{ss:identifyingfitsencoding} and -\secref{ss:readingforeignfits}. For a more general description of -FitsChans and their use with FITS header cards, see -\secref{ss:nativefits} and \secref{ss:foreignfits}. For more details -about FrameSets, see \secref{ss:framesets} and \secref{ss:fshigher}. - -\subsection{\ldots Validate WCS Information} - -Once you have read WCS information from a dataset, as in -\secref{ss:howtoreadwcs}, you may wish to check that you have been -successful. The following will detect and classify the things that -might possibly go wrong: - -c+ -\begin{small} -\begin{terminalv} -#include - -... - -if ( !astOK ) { - -} else if ( wcsinfo == AST__NULL ) { - -} else if ( strcmp( astGetC( wcsinfo, "Class" ), "FrameSet" ) ) { - -} else { - -} -\end{terminalv} -\end{small} -c- -f+ -\small -\begin{terminalv} - IF ( STATUS .NE. 0 ) THEN - - ELSE IF ( WCSINFO .EQ. AST__NULL ) THEN - - ELSE IF ( AST_GETC( WCSINFO, 'Class', STATUS ) .NE. 'FrameSet' ) THEN - - ELSE - - END IF -\end{terminalv} -\normalsize -f- - -c+ -For more information about detecting errors in AST functions, see -\secref{ss:errordetection}. For details of how to validate input data -read by AST, see \secref{ss:validatinginput} and -\secref{ss:readingforeignfits}. -c- -f+ -For more information about detecting errors in AST routines, see -\secref{ss:errordetection}. For details of how to validate input data -read by AST, see \secref{ss:validatinginput} and -\secref{ss:readingforeignfits}. -f- - -\subsection{\ldots Display AST Data} - -If you have a pointer to any AST Object, you can display the data -stored in that Object in textual form as follows: - -c+ -\begin{small} -\begin{terminalv} -astShow( wcsinfo ); -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} - CALL AST_SHOW( WCSINFO, STATUS ) -\end{terminalv} -\end{small} -f- - -Here, we have used a pointer to the FrameSet which we read earlier -(\secref{ss:howtoreadwcs}). The result is written to the program's -standard output stream. This can be very useful during debugging. - -c+ -For more details about using astShow, see -\secref{ss:displayingobjects}. For information about interpreting the -output, also see \secref{ss:textualoutputformat}. -c- -f+ -For more details about using AST\_SHOW, see -\secref{ss:displayingobjects}. For information about interpreting the -output, also see \secref{ss:textualoutputformat}. -f- - -\subsection{\label{ss:howtotransform}\ldots Convert Between Pixel and World Coordinates} - -You may use a pointer to a FrameSet, such as we read in -\secref{ss:howtoreadwcs}, to transform a set of points between the -pixel coordinates of an image and the associated world coordinates. If -you are working in two dimensions, proceed as follows: - -c+ -\begin{small} -\begin{terminalv} -double xpixel[ N ], ypixel[ N ]; -double xworld[ N ], yworld[ N ]; - -... - -astTran2( wcsinfo, N, xpixel, ypixel, 1, xworld, yworld ); -\end{terminalv} -\end{small} -c- -f+ -\small -\begin{terminalv} - INTEGER N - DOUBLE PRECISION XPIXEL( N ), YPIXEL( N ) - DOUBLE PRECISION XWORLD( N ), YWORLD( N ) - - ... - - CALL AST_TRAN2( WCSINFO, N, XPIXEL, YPIXEL, .TRUE., - : XWORLD, YWORLD, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, N is the number of points to be transformed, ``xpixel'' and -``ypixel'' hold the pixel coordinates, and ``xworld'' and ``yworld'' -receive the returned world coordinates.\footnote{By pixel coordinates, -we mean a coordinate system in which the first pixel in the image is -centred on (1,1) and each pixel is a unit square. Note that the world -coordinates will not necessarily be celestial coordinates, but if they -are, then they will be in radians.} To transform in the opposite -direction, interchange the two pairs of arrays (so that the world -coordinates are given as input) and change the fifth argument of -astTran2 to zero. -c- -f+ -Here, N is the number of points to be transformed, XPIXEL and YPIXEL -hold the pixel coordinates, and XWORLD and YWORLD receive the returned -world coordinates.\footnote{By pixel coordinates, we mean a coordinate -system in which the first pixel in the image is centred on (1,1) and -each pixel is a unit square. Note that the world coordinates will not -necessarily be celestial coordinates, but if they are, then they will -be in radians.} To transform in the opposite direction, interchange -the two pairs of arrays (so that the world coordinates are given as -input) and change the fifth argument of AST\_TRAN2 to .FALSE.. -f- - -c+ -To transform points in one dimension, use astTran1. In any other -number of dimensions (or if the number of dimensions is initially -unknown), use astTranN or astTranP. These functions are described in -\appref{ss:functiondescriptions}. -c- -f+ -To transform points in one dimension, use AST\_TRAN1. In any other -number of dimensions (or if the number of dimensions is initially -unknown), use AST\_TRANN. These routines are described in -\appref{ss:functiondescriptions}. -f- - -For more information about transforming coordinates, see -\secref{ss:transforming} and \secref{ss:framesetasmapping}. For -details of how to handle missing coordinates, see -\secref{ss:badcoordinates}. - -\subsection{\label{ss:howtotestforcelestial}\ldots Test if a WCS is a Celestial Coordinate System} - -The world coordinate system (WCS) currently associated with an image -may often be a celestial coordinate system, but this need not -necessarily be the case. For instance, instead of right ascension and -declination, an image might have a WCS with axes representing -wavelength and slit position, or maybe just plain old pixels. - -c+ -If you have obtained a WCS calibration for an image, as in -\secref{ss:howtoreadwcs}, in the form of a pointer ``wcsinfo'' to a -FrameSet, then you may determine if the current coordinate system is a -celestial one or not, as follows: -c- -f+ -If you have obtained a WCS calibration for an image, as in -\secref{ss:howtoreadwcs}, in the form of a pointer WCSINFO to a -FrameSet, then you may determine if the current coordinate system is a -celestial one or not, as follows: -f- - -c+ -\begin{small} -\begin{terminalv} -AstFrame *frame; -int issky; - -... - -/* Obtain a pointer to the current Frame and determine if it is a - SkyFrame. */ -frame = astGetFrame( wcsinfo, AST__CURRENT ); -issky = astIsASkyFrame( frame ); -frame = astAnnul( frame ); -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} - INTEGER FRAME - LOGICAL ISSKY - - ... - -* Obtain a pointer to the current Frame and determine if it is a -* SkyFrame. - FRAME = AST_GETFRAME( WCSINFO, AST__CURRENT, STATUS ) - ISSKY = AST_ISASKYFRAME( FRAME, STATUS ) - CALL AST_ANNUL( FRAME, STATUS ) -\end{terminalv} -\end{small} -f- - -c+ -This will set ``issky'' to 1 if the WCS is a celestial coordinate -system, and to zero otherwise. -c- -f+ -This will set ISSKY to .TRUE.\ if the WCS is a celestial coordinate -system, and to .FALSE.\ otherwise. -f- - -\subsection{\label{ss:howtotestforspectral}\ldots Test if a WCS is a Spectral Coordinate System} -Testing for a spectral coordinate system is basically the same as testing -for a celestial coordinate system (see the previous section). The one -difference is that you use the -c+ -astIsASpecFrame function -c- -f+ -AST\_ISASPECFRAME routine -f- -in place of the -c+ -astIsASkyFrame function. -c- -f+ -AST\_ISASKYFRAME routine. -f- - -\subsection{\label{ss:howtoformatcoordinates}\ldots Format Coordinates for Display} - -c+ -Once you have converted pixel coordinates into world coordinates -(\secref{ss:howtotransform}), you may want to format them as text -before displaying them. Typically, this would convert from (say) -radians into something more comprehensible. Using the FrameSet pointer -``wcsinfo'' obtained in \secref{ss:howtoreadwcs} and a pair of world -coordinates ``xw'' and ``yw'' (\emph{e.g.}\ see -\secref{ss:howtotransform}), you could proceed as follows: -c- -f+ -Once you have converted pixel coordinates into world coordinates -(\secref{ss:howtotransform}), you may want to format them as text -before displaying them. Typically, this would convert from (say) -radians into something more comprehensible. Using the FrameSet pointer -WCSINFO obtained in \secref{ss:howtoreadwcs} and a pair of world -coordinates XW and YW (\emph{e.g.}\ see \secref{ss:howtotransform}), -you could proceed as follows: -f- - -c+ -\begin{small} -\begin{terminalv} -#include -const char *xtext, *ytext; -double xw, yw; - -... - -xtext = astFormat( wcsinfo, 1, xw ); -ytext = astFormat( wcsinfo, 2, yw ); - -(void) printf( "Position = %s, %s\n", xtext, ytext ); -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} - CHARACTER * ( 20 ) XTEXT, YTEXT - DOUBLE PRECISION XW, YW - - ... - - XTEXT = AST_FORMAT( WCSINFO, 1, XW, STATUS ) - YTEXT = AST_FORMAT( WCSINFO, 2, YW, STATUS ) - - WRITE ( *, 199 ) XTEXT, YTEXT - 199 FORMAT( 'Position = ', A, ', ', A ) -\end{terminalv} -\end{small} -f- - -c+ -Here, the second argument to astFormat is the axis number. -c- -f+ -Here, the second argument to AST\_FORMAT is the axis number. -f- - -With celestial coordinates, this will usually result in sexagesimal -notation, such as ``12:34:56.7''. However, the same method may be -applied to any type of coordinates and appropriate formatting will be -employed. - -For more information about formatting coordinate values and how to -control the style of formatting used, see -\secref{ss:formattingaxisvalues} and -\secref{ss:formattingskyaxisvalues}. If necessary, also see -\secref{ss:normalising} for details of how to ``normalise'' a set of -coordinates so that they lie within the standard range (\emph{e.g.}\ 0 -to 24 hours for right ascension and $\pm 90^\circ$ for -declination). - -\subsection{\ldots Display Coordinates as they are Transformed} - -c+ -In addition to formatting coordinates as part of a program's output, -you may also want to examine coordinate values while debugging your -program. To save time, you can ``eavesdrop'' on the coordinate values -being processed every time they are transformed. For example, when -using the FrameSet pointer ``wcsinfo'' obtained in -\secref{ss:howtoreadwcs} to transform coordinates -(\secref{ss:howtotransform}), you could inspect the coordinate values -as follows: -c- -f+ -In addition to formatting coordinates as part of a program's output, -you may also want to examine coordinate values while debugging your -program. To save time, you can ``eavesdrop'' on the coordinate values -being processed every time they are transformed. For example, when -using the FrameSet pointer WCSINFO obtained in -\secref{ss:howtoreadwcs} to transform coordinates -(\secref{ss:howtotransform}), you could inspect the coordinate values -as follows: -f- - -c+ -\begin{small} -\begin{terminalv} -astSet( wcsinfo, "Report=1" ); -astTran2( wcsinfo, N, xpixel, ypixel, 1, xworld, yworld ); -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} - CALL AST_SET( WCSINFO, 'Report=1', STATUS ) - CALL AST_TRAN2( WCSINFO, N, XPIXEL, YPIXEL, .TRUE., - : XWORLD, YWORLD, STATUS ) -\end{terminalv} -\end{small} -f- - -By setting the FrameSet's Report attribute to 1, coordinate -transformations are automatically displayed on the program's standard -output stream, appropriately formatted, for example: - -\begin{terminalv} -(42.1087, 20.2717) --> (2:06:03.0, 34:22:39) -(43.0197, 21.1705) --> (2:08:20.6, 35:31:24) -(43.9295, 22.0716) --> (2:10:38.1, 36:40:09) -(44.8382, 22.9753) --> (2:12:55.6, 37:48:55) -(45.7459, 23.8814) --> (2:15:13.1, 38:57:40) -(46.6528, 24.7901) --> (2:17:30.6, 40:06:25) -(47.5589, 25.7013) --> (2:19:48.1, 41:15:11) -(48.4644, 26.6149) --> (2:22:05.6, 42:23:56) -(49.3695, 27.5311) --> (2:24:23.1, 43:32:41) -(50.2742, 28.4499) --> (2:26:40.6, 44:41:27) -\end{terminalv} - -For a complete description of the Report attribute, see its entry in -\appref{ss:attributedescriptions}. For further details of how to set -and enquire attribute values, see \secref{ss:settingattributes} and -\secref{ss:gettingattributes}. - -\subsection{\ldots Read Coordinates Entered by a User} - -In addition to writing out coordinate values generated by your program -(\secref{ss:howtoformatcoordinates}), you may also need to accept -coordinates entered by a user, or perhaps read from a file. In this -case, you will probably want to allow ``free-format'' input, so that -the user has some flexibility in the format that can be used. You will -probably also want to detect any typing errors. - -c+ -Let's assume that you want to read a number of lines of text, each -containing the world coordinates of a single point, and to split each -line into individual numerical coordinate values. Using the FrameSet -pointer ``wcsinfo'' obtained earlier (\secref{ss:howtoreadwcs}), you -could proceed as follows: -c- -f+ -Let's assume that you want to read a number of lines of text, each -containing the world coordinates of a single point, and to split each -line into individual numerical coordinate values. Using the FrameSet -pointer WCSINFO obtained earlier (\secref{ss:howtoreadwcs}), you could -proceed as follows: -f- - -c+ -\begin{small} -\begin{terminalv} -#include -char *t; -char text[ MAXCHARS + 2 ]; -double coord[ 10 ]; -int iaxis, n, naxes; - -... - -/* Obtain the number of coordinate axes (if not already known). */ -naxes = astGetI( wcsinfo, "Naxes" ); - -/* Loop to read each line of input text, in this case from the - standard input stream (your programming environment will probably - provide a better way of reading text than this). Set the pointer - "t" to the start of each line read. */ -while ( t = fgets( text, MAXCHARS + 2, stdin ) ) { - -/* Attempt to read a coordinate for each axis. */ - for ( iaxis = 1; iaxis <= naxes; iaxis++ ) { - n = astUnformat( wcsinfo, iaxis, t, &coord[ iaxis - 1 ] ); - -/* If nothing was read and this is not the first axis or the - end-of-string, try stepping over a separator and reading again. */ - if ( !n && ( iaxis > 1 ) && *t ) - n = astUnformat( wcsinfo, iaxis, ++t, &coord[ iaxis - 1 ] ); - -/* Quit if nothing was read, otherwise move on to the next coordinate. */ - if ( !n ) break; - t += n; - } - -/* Test for the possible errors that may occur... */ - -/* Error detected by AST (a message will have been issued). */ - if ( !astOK ) { - break; - -/* Error in input data at character t[n]. */ - } else if ( *t || !n ) { - - break; - - } else { - - } -} -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} - CHARACTER TEXT * ( 80 ) - DOUBLE PRECISION COORD( 10 ) - INTEGER IAXIS, N, NAXES, T - - ... - -* Obtain the number of coordinate axes (if not already known). - NAXES = AST_GETI( WCSINFO, 'Naxes', STATUS ) - -* Loop to read each line of input text, in this case from the -* standard input channel (your programming environment will probably -* provide a better way of reading text than this). Set the index T to -* the start of each line read. - 2 CONTINUE - READ( *, '(A)', END=99 ) TEXT - T = 1 - -* Attempt to read a coordinate for each axis. - DO 3 IAXIS = 1, NAXES - N = AST_UNFORMAT( WCSINFO, IAXIS, TEXT( T : ), COORD( IAXIS ), - : STATUS ) - -* If nothing was read and this is not the first axis and the end of -* the text has not been reached, try stepping over a separator and -* reading again. - IF ( ( N .EQ. 0 ) .AND. ( IAXIS .GT. 1 ) .AND. - : ( T .LT. LEN( STRING ) ) ) THEN - T = T + 1 - N = AST_UNFORMAT( WCSINFO, IAXIS, TEXT( T : ), - COORD( IAXIS ), STATUS ) - END IF - -* Quit if nothing was read, otherwise move on to the next coordinate. - IF ( N .EQ. 0 ) GO TO 4 - T = T + N - 3 CONTINUE - 4 CONTINUE - -* Test for the possible errors that may occur... - -* Error detected by AST (a message will have been issued). - IF ( STATUS .NE. 0 ) THEN - GO TO 99 - -* Error in input data at character TEXT( T + N : T + N ). - ELSE IF ( ( T .LT. LEN( STRING ) ) .OR. ( N .EQ. 0 ) ) THEN - - GO TO 99 - - ELSE - - END IF - -* Return to read the next input line. - GO TO 2 - 99 CONTINUE -\end{terminalv} -\end{small} -f- - -This algorithm has the advantage of accepting free-format input in -whatever style is appropriate for the world coordinates in use (under -the control of the FrameSet whose pointer you provide). For example, -wavelength values might be read as floating point numbers -(\emph{e.g.}\ ``1.047'' or ``4787''), whereas celestial positions -could be given in sexagesimal format (\emph{e.g.}\ ``12:34:56'' or -``12~34.5'') and would be converted into radians. Individual -coordinate values may be separated by white space and/or any -non-ambiguous separator character, such as a comma. - -c+ -For more information on reading coordinate values using the -astUnformat function, see \secref{ss:unformattingaxisvalues}. For -details of how sexagesimal formats are handled, and the forms of input -that may be used for celestial coordinates, see -\secref{ss:unformattingskyaxisvalues}. -c- -f+ -For more information on reading coordinate values using the -AST\_UNFORMAT function, see \secref{ss:unformattingaxisvalues}. For -details of how sexagesimal formats are handled, and the forms of input -that may be used for for celestial coordinates, see -\secref{ss:unformattingskyaxisvalues}. -f- - -\subsection{\label{ss:howtocreatenewwcs}\ldots Create a New WCS Calibration} - -This section describes how to add a WCS calibration to a data set which you -are creating from scratch, rather than modifying an existing data set. - -In most common cases, the simplest way to create a new WCS calibration -from scratch is probably to create a set of strings describing the -required calibration in terms of the keywords used by the FITS WCS -standard, and then convert these strings into an AST FrameSet describing -the calibration. This FrameSet can then be used for many other purposes, or -simply stored in the data set. - -The full FITS-WCS standard is quite involved, currently running to four -separate papers, but the basic kernel is quite simple, involving the -following keywords (all of which end with an integer axis index, -indicated below by $$): - -\begin{description} -\item[CRPIX]\mbox{}\\ -hold the pixel coordinates at a reference point -\item[CRVAL]\mbox{}\\ -hold the corresponding WCS coordinates at the reference point -\item[CTYPE]\mbox{}\\ -name the quantity represented by the WCS axes, together with the -projection algorithm used to convert the scaled and rotated pixel coordinates -to WCS coordinates. -\item[CD\_]\mbox{}\\ -a set of keywords which specify the elements of a matrix. This matrix scales -pixel offsets from the reference point into the offsets required as input -by the projection algorithm specified by the CTYPE keywords. This matrix -specifies the scale and rotation of the image. If there is no rotation -the off-diagonal elements of the matrix (\emph{e.g.} CD1\_2 and -CD2\_1) can be omitted. -\end{description} - -As an example consider the common case of a simple 2D image of the sky in -which north is parallel to the second pixel axis and east parallel to the -(negative) first pixel axis. The image scale is 1.2 arc-seconds per pixel -on both axes, and the image is presumed to have been obtained with a -tangent plane projection. Furthermore, it is known that pixel coordinates -(100.5,98.4) correspond to an RA of 11:00:10 and a Dec. of -23:26:02. -A suitable set of FITS-WCS header cards could be: - -\begin{small} -\begin{terminalv} -CTYPE1 = 'RA---TAN' / Axis 1 represents RA with a tan projection -CTYPE2 = 'DEC--TAN' / Axis 2 represents Dec with a tan projection -CRPIX1 = 100.5 / Pixel coordinates of reference point -CRPIX2 = 98.4 / Pixel coordinates of reference point -CRVAL1 = 165.04167 / Degrees equivalent of "11:00:10" hours -CRVAL2 = -23.433889 / Decimal equivalent of "-23:26:02" degrees -CD1_1 = -0.0003333333 / Decimal degrees equivalent of -1.2 arc-seconds -CD2_2 = 0.0003333333 / Decimal degrees equivalent of 1.2 arc-seconds -\end{terminalv} -\end{small} - -Notes: -\begin{itemize} -\item a FITS header card begins with the keyword name starting at column 1, -has an equals sign in column 9, and the keyword value in columns 11 to 80. -\item string values must be enclosed in single quotes. -\item celestial longitude and latitude must both be specified in decimal degrees. -\item the CD1\_1 value is negative to indicate that RA increases as the -first pixel axis decreases. -\item the (RA,Dec) coordinates will be taken as ICRS coordinates. For FK5 -you should add: - -\begin{small} -\begin{terminalv} -RADESYS = 'FK5' -EQUINOX = 2005.6 -\end{terminalv} -\end{small} - -The EQUINOX value defaults to J2000.0 if omitted. FK4 can also be used in -place of FK5, in which case EQUINOX defaults to B1950.0. - -\end{itemize} - -Once you have created these FITS-WCS header card strings, you should -store them in a FitsChan and then read the corresponding FrameSet from the -FitsChan. How to do this is described in \secref{ss:howtoreadwcs}. - -Having created the WCS calibration, you may want to store it in a data -file. How to do this is described in \secref{ss:howtowritewcs}).\footnote{If -you are writing the WCS calibration to a FITS file you obviously -have the choice of storing the FITS-WCS cards directly.} - -If the required WCS calibration cannot be described as a set of FITS-WCS -headers, then a different approach is necessary. In this case, you should -first create a Frame describing pixel coordinates, and store this Frame -in a new FrameSet. You should then create a new Frame describing the -world coordinate system. This Frame may be a specific subclass of Frame such -as a SkyFrame for celestial coordinates, a SpecFrame for spectral -coordinates, a Timeframe for time coordinates, or a CmpFrame for a combination -of different coordinates. -You also need to create a suitable Mapping which transforms pixel -coordinates into world coordinates. AST provides many different types of -Mappings, all of which can be combined together in arbitrary fashions to -create more complicated Mappings. The WCS Frame should then be added into -the FrameSet, using the Mapping to connect the WCS Frame with the pixel -Frame. - -\subsection{\label{ss:howtomodifywcs}\ldots Modify a WCS Calibration} - -The usual reason for wishing to modify the WCS calibration associated -with a dataset is that the data have been geometrically transformed in -some way (here, we will assume a 2-dimensional image dataset). This -causes the image features (stars, galaxies, \emph{etc.}) to move with -respect to the grid of pixels which they occupy, so that any -coordinate systems previously associated with the image become -invalid. - -To correct for this, it is necessary to set up a Mapping which -expresses the positions of image features in the new data grid in -terms of their positions in the old grid. In both cases, the grid -coordinates we use will have the first pixel centred at (1,1) with -each pixel being a unit square. - -c+ -AST allows you to correct for any type of geometrical transformation -in this way, so long as a suitable Mapping to describe it can be -constructed. For purposes of illustration, we will assume here that -the new image coordinates ``xnew'' and ``ynew'' can be expressed in -terms of the old coordinates ``xold'' and ``yold'' as follows: -c- -f+ -AST allows you to correct for any type of geometrical transformation -in this way, so long as a suitable Mapping to describe it can be -constructed. For purposes of illustration, we will assume here that -the new image coordinates XNEW and YNEW can be expressed in terms of -the old coordinates XOLD and YOLD as follows: -f- - -c+ -\begin{small} -\begin{terminalv} -double xnew, xold, ynew, yold; -double m[ 4 ], z[ 2 ]; - -... - -xnew = xold * m[ 0 ] + yold * m[ 1 ] + z[ 0 ]; -ynew = xold * m[ 2 ] + yold * m[ 3 ] + z[ 1 ]; -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} - DOUBLE PRECISION XNEW, XOLD, YNEW, YOLD - DOUBLE PRECISION M( 4 ), Z( 2 ) - - ... - - XNEW = XOLD * M( 1 ) + YOLD * M( 2 ) + Z( 1 ) - YNEW = XOLD * M( 3 ) + YOLD * M( 4 ) + Z( 2 ) -\end{terminalv} -\end{small} -f- - -c+ -where ``m'' is a 2$\times$2 transformation matrix and ``z'' represents -a shift of origin. This is therefore a general linear coordinate -transformation which can represent displacement, rotation, -magnification and shear. -c- -f+ -where M is a 2$\times$2 transformation matrix and Z represents a shift -of origin. This is therefore a general linear coordinate -transformation which can represent displacement, rotation, -magnification and shear. -f- - -In AST, it can be represented by concatenating two Mappings. The first -is a MatrixMap, which implements the matrix multiplication. The second -is a WinMap, which linearly transforms one coordinate window on to -another, but will be used here simply to implement the shift of -origin (alternatively, a ShiftMap could have been used in place of a -WinMap). These Mappings may be constructed and concatenated as follows: - -c+ -\begin{small} -\begin{terminalv} -AstCmpMap *newmap; -AstMatrixMap *matrixmap; -AstWinMap *winmap; - -... - -/* The MatrixMap may be constructed directly from the matrix "m". */ -matrixmap = astMatrixMap( 2, 2, 0, m, "" ); - -/* For the WinMap, we set up the coordinates of the corners of a unit - square (window) and then the same square shifted by the required - amount. */ -{ - double ina[] = { 0.0, 0.0 }; - double inb[] = { 1.0, 1.0 }; - double outa[] = { z[ 0 ], z[ 1 ] }; - double outb[] = { 1.0 + z[ 0 ], 1.0 + z[ 1 ] }; - -/* The WinMap will then implement this shift. */ - winmap = astWinMap( 2, ina, inb, outa, outb, "" ); -} - -/* Join the two Mappings together, so that they are applied one after - the other. */ -newmap = astCmpMap( matrixmap, winmap, 1, "" ); -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} - DOUBLE PRECISION INA( 2 ), INB( 2 ), OUTA( 2 ), OUTB( 2 ) - INTEGER MATRIXMAP, WINMAP - - ... - -* Set up the corners of a unit square. - DATA INA / 2 * 0.0D0 / - DATA INB / 2 * 1.0D0 / - -* The MatrixMap may be constructed directly from the matrix M. - MATRIXMAP = AST_MATRIXMAP( 2, 2, 0, M, ' ', STATUS ) - -* For the WinMap, we take the coordinates of the corners of a unit -* square (window) and then shift them by the required amounts. - OUTA( 1 ) = INA( 1 ) + Z( 1 ) - OUTA( 2 ) = INA( 2 ) + Z( 2 ) - OUTB( 1 ) = INB( 1 ) + Z( 1 ) - OUTB( 2 ) = INB( 2 ) + Z( 2 ) - -* The WinMap will then implement this shift. - WINMAP = AST_WINMAP( 2, INA, INB, OUTA, OUTB, ' ', STATUS ) - -* Join the two Mappings together, so that they are applied one after -* the other. - NEWMAP = AST_CMPMAP( MATRIXMAP, WINMAP, 1, ' ', STATUS ) -\end{terminalv} -\end{small} -f- - -You might, of course, create any other form of Mapping depending on -the type of geometrical transformation involved. For an overview of -the Mappings provided by AST, see \secref{ss:mappingselection}, and -for a description of the capabilities of each class of Mapping, see -its entry in \appref{ss:classdescriptions}. For an overview of how -individual Mappings may be combined, see \secref{ss:cmpmapoverview} -(\secref{ss:cmpmaps} gives more details). - -c+ -Assuming you have obtained a WCS calibration for your original image -in the form of a pointer to a FrameSet, ``wcsinfo1'' -(\secref{ss:howtoreadwcs}), the Mapping created above may be used to -produce a calibration for the new image as follows: -c- -f+ -Assuming you have obtained a WCS calibration for your original image -in the form of a pointer to a FrameSet, WCSINFO1 -(\secref{ss:howtoreadwcs}), the Mapping created above may be used to -produce a calibration for the new image as follows: -f- - -c+ -\begin{small} -\begin{terminalv} -AstFrameSet *wcsinfo1, *wcsinfo2; - -... - -/* If necessary, make a copy of the WCS calibration, since we are - about to alter it. */ -wcsinfo2 = astCopy( wcsinfo1 ); - -/* Re-map the base Frame so that it refers to the new data grid - instead of the old one. */ -astRemapFrame( wcsinfo2, AST__BASE, newmap ); -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} - INTEGER WCSINFO1, WCSINFO2 - - ... - -* If necessary, make a copy of the WCS calibration, since we are -* about to alter it. - WCSINFO2 = AST_COPY( WCSINFO1, STATUS ) - -* Re-map the base Frame so that it refers to the new data grid -* instead of the old one. - CALL AST_REMAPFRAME( WCSINFO2, AST__BASE, NEWMAP, STATUS ) -\end{terminalv} -\end{small} -f- - -c+ -This will produce a pointer, ``wcsinfo2'', to a new FrameSet in which -all the coordinate systems associated with your original image are -modified so that they are correctly registered with the new image -instead. -c- -f+ -This will produce a pointer, WCSINFO2, to a new FrameSet in which all -the coordinate systems associated with the original image are modified -so that they are correctly registered with your new image instead. -f- - -For more information about re-mapping the Frames within a FrameSet, -see \secref{ss:remapframe}. Also see \secref{ss:wcsprocessingexample} -for a similar example to the above, applicable to the case of reducing -the size of an image by binning. - -\subsection{\label{ss:howtowritewcs}\ldots Write a Modified WCS Calibration to a Dataset} - -If you have modified the WCS calibration associated with a dataset, -such as in the example above (\secref{ss:howtomodifywcs}), then you -will need to write the modified version out along with any new data. - -In the same way as when reading a WCS calibration -(\secref{ss:howtoreadwcs}), how you do this will depend on your data -system, but we will assume that you wish to generate a set of FITS -header cards that can be stored with the data. You should usually make -preparations for doing this when you first read the WCS calibration -from your input dataset by modifying the example given in -\secref{ss:howtoreadwcs} as follows: - -c+ -\begin{small} -\begin{terminalv} -AstFitsChan *fitschan1; -AstFrameSet *wcsinfo1; -const char *encode; - -... - -/* Create an input FitsChan and fill it with FITS header cards. Note, - if you have all the header cards in a single string, use astPutCards in - place of astPutFits. */ -fitschan1 = astFitsChan( NULL, NULL, "" ); -for ( icard = 0; icard < ncard; icard++ ) astPutFits( fitschan1, cards[ icard ], 0 ); - -/* Note which encoding has been used for the WCS information. */ -encode = astGetC( fitschan1, "Encoding" ); - -/* Rewind the input FitsChan and read the WCS information from it. */ -astClear( fitschan1, "Card" ); -wcsinfo1 = astRead( fitschan1 ); -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} - INTEGER FITSCHAN1, WCSINFO1 - CHARACTER * ( 20 ) ENCODE - - ... - -* Create an input FitsChan and fill it with FITS header cards. Note, -* if you have all the header cards in a single string, use AST_PUTCARDS in -* place of AST_PUTFITS. - FITSCHAN1 = AST_FITSCHAN( AST_NULL, AST_NULL, ' ', STATUS ) - DO 1 ICARD = 1, NCARD - CALL AST_PUTFITS( FITSCHAN1, CARDS( ICARD ), .FALSE., STATUS ) - 1 CONTINUE - -* Note which encoding has been used for the WCS information. - ENCODE = AST_GETC( FITSCHAN1, 'Encoding', STATUS ); - -* Rewind the input FitsChan and read the WCS information from it. - CALL AST_CLEAR( FITSCHAN1, 'Card', STATUS ) - WCSINFO1 = AST_READ( FITSCHAN1, STATUS ) -\end{terminalv} -\end{small} -f- - -c+ -Note how we have added an enquiry to determine how the WCS information -is encoded in the input FITS cards, storing a pointer to the resulting -string in the ``encode'' variable. This must be done \textbf{before} -actually reading the WCS calibration. -c- -f+ -Note how we have added an enquiry to determine how the WCS information -is encoded in the input FITS cards, storing the resulting string in -the ENCODE variable. This must be done \textbf{before} actually reading -the WCS calibration. -f- - -c+ -\emph{(\textbf{N.B.}\ If you will be making extensive use of astGetC in -your program, then you should allocate a buffer and make a copy of -this string, because the pointer returned by astGetC will only remain -valid for 50 invocations of the function, and you will need to use the -Encoding value again later on.)} -c- - -c+ -Once you have produced a modified WCS calibration for the output -dataset (\emph{e.g.}\ \secref{ss:howtomodifywcs}), in the form of a -FrameSet identified by the pointer ``wcsinfo2'', you can produce a new -FitsChan containing the output FITS header cards as follows: -c- -f+ -Once you have produced a modified WCS calibration for the output -dataset (\emph{e.g.}\ \secref{ss:howtomodifywcs}), in the form of a -FrameSet identified by the pointer WCSINFO2, you can produce a new -FitsChan containing the output FITS header cards as follows: -f- - -c+ -\small -\begin{terminalv} -AstFitsChan *fitschan2; -AstFrameSet *wcsinfo2; - -... - -/* Make a copy of the input FitsChan, AFTER the WCS information has - been read from it. This will propagate all the input FITS header - cards, apart from those describing the input WCS calibration. */ -fitschan2 = astCopy( fitschan1 ); - -/* If necessary, make modifications to the cards in "fitschan2" - (e.g. you might need to change NAXIS1, NAXIS2, etc., to account for - a change in image size). You probably only need to do this if your - data system does not provide these facilities itself. */ -
    - -/* Alternatively, if your data system handles the propagation of FITS - header cards to the output dataset for you, then simply create an - empty FitsChan to contain the output WCS information alone. -fitschan2 = astFitsChan( NULL, NULL, "" ); -*/ - -/* Rewind the new FitsChan (if necessary) and attempt to write the - output WCS information to it using the same encoding method as the - input dataset. */ -astSet( fitschan2, "Card=1, Encoding=%s", encode ); -if ( !astWrite( fitschan2, wcsinfo2 ) ) { - -/* If this didn't work (the WCS FrameSet has become too complex), then - use the native AST encoding instead. */ - astSet( fitschan2, "Encoding=NATIVE" ); - (void) astWrite( fitschan2, wcsinfo2 ); -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER FITSCHAN2, JUNK, WCSINFO2 - - ... - -* Make a copy of the input FitsChan, AFTER the WCS information has -* been read from it. This will propagate all the input FITS header -* cards, apart from those describing the WCS calibration. - FITSCHAN2 = AST_COPY( FITSCHAN1, STATUS ) - -* If necessary, make modifications to the cards in FITSCHAN2 -* (e.g. you might need to change NAXIS1, NAXIS2, etc., to account for -* a change in image size). You probably only need to do this if your -* data system does not provide these facilities itself. -
    - -* Alternatively, if your data system handles the propagation of FITS -* header cards to the output dataset for you, then simply create an -* empty FitsChan to contain the output WCS information alone. -* FITSCHAN2 = AST_FITSCHAN( AST_NULL, AST_NULL, ' ', STATUS ) - -* Rewind the new FitsChan (if necessary) and attempt to write the -* output WCS information to it using the same encoding method as the -* input dataset. - CALL AST_SET( FITSCHAN2, 'Card=1, Encoding=' // ENCODE, STATUS ) - IF ( AST_WRITE( FITSCHAN2, WCSINFO2, STATUS ) .EQ. 0 ) THEN - -* If this didn't work (the WCS FrameSet has become too complex), then -* use the native AST encoding instead. - CALL AST_SETC( FITSCHAN2, 'Encoding', 'NATIVE', STATUS ); - JUNK = AST_WRITE( FITSCHAN2, WCSINFO2, STATUS ); - END IF -\end{terminalv} -\normalsize -f- - -For details of how to modify the contents of the output FitsChan in -other ways, such as by adding, over-writing or deleting header cards, -see \secref{ss:addressingfitscards}, \secref{ss:addingmulticards}, \secref{ss:addingfitscards} and -\secref{ss:findingandchangingfits}. - -Once you have assembled the output FITS cards, you may retrieve them -from the FitsChan that contains them as follows: - -c+ -\small -\begin{terminalv} -#include -char card[ 81 ]; - -... - -astClear( fitschan2, "Card" ); -while ( astFindFits( fitschan2, "%f", card, 1 ) ) (void) printf( "%s\n", card ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 80 ) CARD - - ... - - CALL AST_CLEAR( FITSCHAN2, 'Card', STATUS ) - 5 CONTINUE - IF ( AST_FINDFITS( FITSCHAN2, '%f', CARD, .TRUE., STATUS ) ) THEN - WRITE ( *, '(A)' ) CARD - GO TO 5 - END IF -\end{terminalv} -\normalsize -f- - -c+ -Here, we have simply written each card to the standard output stream, -but you would obviously replace this with a function invocation to -store the cards in your output dataset. -c- -f+ -Here, we have simply written each card to the standard output unit, -but you would obviously replace this with a subroutine call to store -the cards in your output dataset. -f- - -c+ -For data systems that do not use FITS header cards, a different -approach may be needed, possibly involving use of a Channel or XmlChan -(\secref{ss:channels}) rather than a FitsChan. In the case of the -Starlink NDF data format, for example, all of the above may be -replaced by a single call to the function -\xref{ndfPtwcs}{sun33}{ndfPtwcs}---see \xref{SUN/33}{sun33}{}. The -whole process can probably be encapsulated in a similar way for most -data systems, whether they use FITS header cards or not. -c- -f+ -For data systems that do not use FITS header cards, a different -approach may be needed, possibly involving use of a Channel or XmlChan -(\secref{ss:channels}) rather than a FitsChan. In the case of the -Starlink NDF data format, for example, all of the above may be -replaced by a single call to the routine -\xref{NDF\_PTWCS}{sun33}{NDF_PTWCS}---see \xref{SUN/33}{sun33}{}. The -whole process can probably be encapsulated in a similar way for most -other data systems, whether they use FITS header cards or not. -f- - -For an overview of how to propagate WCS information through data -processing steps, see \secref{ss:propagatingwcsinformation}. For more -information about writing WCS information to FitsChans, see -\secref{ss:writingnativefits} and \secref{ss:writingforeignfits}. For -information about the options for encoding WCS information in FITS -header cards, see \secref{ss:nativeencoding}, -\secref{ss:foreignencodings}, and the description of the Encoding -attribute in \appref{ss:attributedescriptions}. For a complete -understanding of FitsChans and their use with FITS header cards, you -should read \secref{ss:nativefits} and \secref{ss:foreignfits}. - -\subsection{\label{ss:howtoplotgrid}\ldots Display a Graphical Coordinate Grid} - - A common requirement when displaying image data is to plot an - associated coordinate grid (\emph{e.g.}\ Figure~\ref{fig:overgrid}) - over the displayed image. - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.7\textwidth]{sun211_figures/overgrid_bw} -c- -f+ - \includegraphics[width=0.7\textwidth]{sun210_figures/overgrid_bw} -f- - \caption[An example of a displayed image with a coordinate grid - plotted over it.]{An example of a displayed image with a coordinate grid - plotted over it.} - \label{fig:overgrid} - \end{center} - \end{figure} - -c+ -The use of AST in such circumstances is independent of the underlying -graphics system, so starting up the graphics system, setting up a -coordinate system, displaying the image, and closing down afterwards -can all be done using the graphics functions you would normally use. -c- -f+ -The use of AST in such circumstances is independent of the underlying -graphics system, so starting up the graphics system, setting up a -coordinate system, displaying the image, and closing down afterwards -can all be done using the graphics routines you would normally use. -f- - -c+ -However, displaying an image at a precise location can be a little -fiddly with some graphics systems, and obviously the grid drawn by AST -will not be accurately registered with the image unless this is done -correctly. In the following template, we therefore illustrate both -steps, basing the image display on the C interface to the PGPLOT -graphics package.\footnote{An interface is provided with AST that -allows it to use PGPLOT (\xref{SUN/15}{sun15}{}) for its graphics, -although interfaces to other graphics systems may also be written.} -Plotting a coordinate grid with AST then becomes a relatively minor -part of what is almost a complete graphics program. -c- -f+ -However, displaying an image at a precise location can be a little -fiddly with some graphics systems, and obviously the grid drawn by AST -will not be accurately registered with the image unless this is done -correctly. In the following template, we therefore illustrate both -steps, basing the image display on the PGPLOT graphics -package.\footnote{An interface is provided with AST that allows it to -use PGPLOT (\xref{SUN/15}{sun15}{}) for its graphics, although -interfaces to other graphics systems may also be written.} Plotting a -coordinate grid with AST then becomes a relatively minor part of what -is almost a complete graphics program. -f- - -c+ -Once again, we assume that a pointer, ``wcsinfo'', to a suitable -FrameSet associated with the image has already been obtained -(\secref{ss:howtoreadwcs}). -c- -f+ -Once again, we assume that a pointer, WCSINFO, to a suitable FrameSet -associated with the image has already been obtained -(\secref{ss:howtoreadwcs}). -f- - -c+ -\small -\begin{terminalv} -#include "cpgplot.h" -AstPlot *plot; -const float *data; -float hi, lo, scale, x1, x2, xleft, xright, xscale; -float y1, y2, ybottom, yscale, ytop; -int nx, ny; - -... - -/* Access the image data, which we assume has dimension sizes "nx" and - "ny", and will be accessed via the "data" pointer. Also derive - limits for scaling it, which we assign to the variables "hi" and - "lo". */ - - -/* Open PGPLOT using the device given by environment variable - PGPLOT_DEV and check for success. */ -if( cpgbeg( 0, " ", 1, 1 ) == 1 ) { - -/* Clear the screen and ensure equal scales on both axes. */ - cpgpage(); - cpgwnad( 0.0f, 1.0f, 0.0f, 1.0f ); - -/* Obtain the extent of the plotting area (not strictly necessary for - PGPLOT, but possibly for other graphics systems). From this, derive - the display scale in graphics units per pixel so that the image - will fit within the display area. */ - cpgqwin( &x1, &x2, &y1, &y2 ); - xscale = ( x2 - x1 ) / nx; - yscale = ( y2 - y1 ) / ny; - scale = ( xscale < yscale ) ? xscale : yscale; - -/* Calculate the extent of the area in graphics units that the image - will occupy, so as to centre it within the display area. */ - xleft = 0.5f * ( x1 + x2 - nx * scale ); - xright = 0.5f * ( x1 + x2 + nx * scale ); - ybottom = 0.5f * ( y1 + y2 - ny * scale ); - ytop = 0.5f * ( y1 + y2 + ny * scale ); - -/* Set up a PGPLOT coordinate transformation matrix and display the - image data as a grey scale map (these details are specific to - PGPLOT). */ - { - float tr[] = { xleft - 0.5f * scale, scale, 0.0f, - ybottom - 0.5f * scale, 0.0f, scale }; - cpggray( data, nx, ny, 1, nx, 1, ny, hi, lo, tr ); - } - -/* BEGINNING OF AST BIT */ -/* ==================== */ -/* Store the locations of the bottom left and top right corners of the - region used to display the image, in graphics coordinates. */ - { - float gbox[] = { xleft, ybottom, xright, ytop }; - -/* Similarly, store the locations of the image's bottom left and top - right corners, in pixel coordinates -- with the first pixel centred - at (1,1). */ - double pbox[] = { 0.5, 0.5, nx + 0.5, ny + 0.5 }; - -/* Create a Plot, based on the FrameSet associated with the - image. This attaches the Plot to the graphics surface so that it - matches the displayed image. Specify that a complete set of grid - lines should be drawn (rather than just coordinate axes). */ - plot = astPlot( wcsinfo, gbox, pbox, "Grid=1" ); - } - -/* Optionally, we can now set other Plot attributes to control the - appearance of the grid. The values assigned here use the - colour/font indices defined by the underlying graphics system. */ - astSet( plot, "Colour(grid)=2, Font(textlab)=3" ); - -/* Use the Plot to draw the coordinate grid. */ - astGrid( plot ); - - - -/* Annul the Plot when finished (or use the astBegin/astEnd technique - shown earlier). */ - plot = astAnnul( plot ); - -/* END OF AST BIT */ -/* ============== */ - -/* Close down the graphics system. */ - cpgend(); -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DOUBLE PRECISION BBOX( 4 ) - INTEGER NX, NY, PGBEG, PLOT - REAL DATA( NX, NY ), GBOX( 4 ), HI, LO, SCALE, TR( 6 ) - REAL X1, X2, XLEFT, XRIGHT, Y1, Y2, YBOTTOM, YTOP - - ... - -* Access the image data, which we assume will be stored in the real -* 2-dimensional array DATA with dimension sizes NX and NY. Also -* derive limits for scaling it, which we assign to the variables HI -* and LO. - - -* Open PGPLOT using the device given by environment variable -* PGPLOT_DEV and check for success. - IF ( PGBEG( 0, ' ', 1, 1 ) .EQ. 1 ) THEN - -* Clear the screen and ensure equal scales on both axes. - CALL PGPAGE - CALL PGWNAD( 0.0, 1.0, 0.0, 1.0 ) - -* Obtain the extent of the plotting area (not strictly necessary for -* PGPLOT, but possibly for other graphics systems). From this, derive -* the display scale in graphics units per pixel so that the image -* will fit within the display area. - CALL PGQWIN( X1, X2, Y1, Y2 ) - SCALE = MIN( ( X2 - X1 ) / NX, ( Y2 - Y1 ) / NY ) - -* Calculate the extent of the area in graphics units that the image -* will occupy, so as to centre it within the display area. - XLEFT = 0.5 * ( X1 + X2 - NX * SCALE ) - XRIGHT = 0.5 * ( X1 + X2 + NX * SCALE ) - YBOTTOM = 0.5 * ( Y1 + Y2 - NY * SCALE ) - YTOP = 0.5 * ( Y1 + Y2 + NY * SCALE ) - -* Set up a PGPLOT coordinate transformation matrix and display the -* image data as a grey scale map (these details are specific to -* PGPLOT). - TR( 1 ) = XLEFT - 0.5 * SCALE - TR( 2 ) = SCALE - TR( 3 ) = 0.0 - TR( 4 ) = YBOTTOM - 0.5 * SCALE - TR( 5 ) = 0.0 - TR( 6 ) = SCALE - CALL PGGRAY( DATA, NX, NY, 1, NX, 1, NY, HI, LO, TR ) - -* BEGINNING OF AST BIT -* ==================== -* Store the locations of the bottom left and top right corners of the -* region used to display the image, in graphics coordinates. - GBOX( 1 ) = XLEFT - GBOX( 2 ) = YBOTTOM - GBOX( 3 ) = XRIGHT - GBOX( 4 ) = YTOP - -* Similarly, store the locations of the image's bottom left and top -* right corners, in pixel coordinates -- with the first pixel centred -* at (1,1). - BBOX( 1 ) = 0.5D0 - BBOX( 2 ) = 0.5D0 - BBOX( 3 ) = NX + 0.5D0 - BBOX( 4 ) = NY + 0.5D0 - -* Create a Plot, based on the FrameSet associated with the -* image. This attaches the Plot to the graphics surface so that it -* matches the displayed image. Specify that a complete set of grid -* lines should be drawn (rather than just coordinate axes). - PLOT = AST_PLOT( WCSINFO, GBOX, BBOX, 'Grid=1', STATUS ) - -* Optionally, we can now set other Plot attributes to control the -* appearance of the grid. The values assigned here use the -* colour/font indices defined by the underlying graphics system. - CALL AST_SET( PLOT, 'Colour(grid)=2, Font(textlab)=3', STATUS ) - -* Use the Plot to draw the coordinate grid. - CALL AST_GRID( PLOT, STATUS ) - - - -* Annul the Plot when finished (or use the AST_BEGIN/AST_END -* technique shown earlier). - CALL AST_ANNUL( PLOT, STATUS ) - -* END OF AST BIT -* ============== - -* Close down the graphics system. - CALL PGEND - END IF -\end{terminalv} -\normalsize -f- - -Note that once you have set up a Plot which is aligned with a -displayed image, you may also use it to generate further graphical -output of your own, specified in the image's world coordinate system -(such as markers to represent astronomical objects, annotation, -\emph{etc.}). There is also a range of Plot attributes which gives -control over most aspects of the output's appearance. For details of -the facilities available, see \secref{ss:plots} and the description of -the Plot class in \appref{ss:classdescriptions}. - -For details of how to build a graphics program which uses PGPLOT, see -\secref{ss:howtobuild} and the description of the ast\_link command in -\appref{ss:commanddescriptions}. - -\subsection{\label{ss:howtoswitchgrid}\ldots Switch to Plot a Different Celestial Coordinate Grid} - -c+ -Once you have set up a Plot to draw a coordinate grid -(\secref{ss:howtoplotgrid}), it is a simple matter to change things so -that the grid represents a different celestial coordinate system. For -example, after creating the Plot with astPlot, you could use: -c- -f+ -Once you have set up a Plot to draw a coordinate grid -(\secref{ss:howtoplotgrid}), it is a simple matter to change things so -that the grid represents a different celestial coordinate system. For -example, after creating the Plot with AST\_PLOT, you could use: -f- - -c+ -\small -\begin{terminalv} -astSet( plot, "System=Galactic" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( PLOT, 'System=Galactic', STATUS ) -\end{terminalv} -\normalsize -f- -or: -c+ -\small -\begin{terminalv} -astSet( plot, "System=FK5, Equinox=J2010" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( PLOT, 'System=FK5, Equinox=J2010', STATUS ) -\end{terminalv} -\normalsize -f- - -and any axes and/or grid drawn subsequently would represent the new -celestial coordinate system you specified. Note, however, that this -will only work if the original grid represented celestial coordinates -of some kind (see \secref{ss:howtotestforcelestial} for how to -determine if this is the case\footnote{Note that the methods applied -to a FrameSet may be used equally well with a Plot.}). If it did not, -you will get an error message. - -For more information about the celestial coordinate systems available, -see the descriptions of the System, Equinox and Epoch attributes in -\appref{ss:attributedescriptions}. - -\subsection{\ldots Give a User Control Over the Appearance of a Plot} - -The idea of using a Plot's attributes to control the appearance of the -graphical output it produces (\secref{ss:howtoplotgrid} and -\secref{ss:howtoswitchgrid}) can easily be extended to allow the user -of a program complete control over such matters. - -For instance, if the file ``plot.config'' contains a series of -plotting options in the form of Plot attribute assignments (see below -for an example), then we could create a Plot and implement these -assignments before producing the graphical output as follows: - -c+ -\small -\begin{terminalv} -#include -#define MAXCHARS 120 -FILE *stream; -char line[ MAXCHARS + 2 ]; -int base; - -... - -/* Create a Plot and define the default appearance of the graphical - output it will produce. */ -plot = astPlot( wcsinfo, gbox, pbox, - "Grid=1, Colour(grid)=2, Font(textlab)=3" ); - -/* Obtain the value of any Plot attributes we want to preserve. */ -base = astGetI( plot, "Base" ); - -/* Open the plot configuration file, if it exists. Read each line of - text and use it to set new Plot attribute values. Close the file - when done. */ -if ( stream = fopen( "plot.config", "r" ) ) { - while ( fgets( line, MAXCHARS + 2, stream ) ) astSet( plot, "%s", line ); - close( stream ); -} - -/* Restore any attribute values we are preserving. */ -astSetI( plot, "Base", base ); - -/* Produce the graphical output (e.g.). */ -astGrid( plot ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER LINE( 120 ) - INTEGER BASE - - ... - -* Create a Plot and define the default appearance of the graphical -* output it will produce. - PLOT = AST_PLOT( WCSINFO, GBOX, PBOX, - : 'Grid=1, Colour(grid)=2, Font(textlab)=3', - : STATUS ) - -* Obtain the value of any Plot attributes we want to preserve. - BASE = AST_GETI( PLOT, 'Base', STATUS ) - -* Open the plot configuration file, if it exists. - OPEN ( 1, FILE = 'plot.config', STATUS = 'OLD', ERR = 8 ) - -* Read each line of text and use it to set new Plot attribute -* values. Close the file when done. - 6 CONTINUE - READ ( 1, '(A)', END = 7 ) LINE - CALL AST_SET( PLOT, LINE, STATUS ) - GO TO 6 - 7 CLOSE ( 1 ) - 8 CONTINUE - -* Restore any attribute values we are preserving. - CALL AST_SETI( PLOT, 'Base', BASE, STATUS ) - -* Produce the graphical output (e.g.). - CALL AST_GRID( PLOT, STATUS ) -\end{terminalv} -\normalsize -f- - -Notice that we take care that the Plot's Base attribute is preserved -so that the user cannot change it. This is because graphical output -will not be produced successfully if the base Frame does not describe -the plotting surface to which we attached the Plot when we created it. - -The arrangement shown above allows the contents of the ``plot.config'' -file to control most aspects of the graphical output produced -(including the coordinate system used; the colour, line style, -thickness and font used for each component; the positioning of axes -and tick marks; the precision, format and positioning of labels; -\emph{etc.}) \emph{via} assignments of the form: - -\small -\begin{terminalv} -System=Galactic, Equinox = 2001 -Border = 1, Colour( border ) = 1 -Colour( grid ) = 2 -DrawAxes = 1 -Colour( axes ) = 3 -Digits = 8 -Labelling = Interior -\end{terminalv} -\normalsize - -For a more sophisticated interface, you could obviously perform -pre-processing on this input---for example, to translate words like -``red'', ``green'' and ``blue'' into colour indices, to permit -comments and blank lines, \emph{etc.} - -For a full list of the attributes that may be used to control the -appearance of graphical output, see the description of the Plot class -in \appref{ss:classdescriptions}. For a complete description of each -individual attribute (\emph{e.g.}\ those above), see the attribute's -entry in \appref{ss:attributedescriptions}. - -\cleardoublepage -\section{\label{ss:primer}An AST Object Primer} - -c+ -The AST library deals throughout with entities called Objects and a -basic understanding of how to handle these is needed before you can -use the library effectively. If you are already familiar with an -object-oriented language, such as C$++$, few of the concepts should -seem new to you. Be aware, however, that AST is designed to be used -\emph{via} fairly conventional C and Fortran interfaces, so some -things have to be done a little differently. -c- -f+ -The AST library deals throughout with entities called Objects and a -basic understanding of how to handle these is needed before you can -use the library effectively. If you are already familiar with an -object-oriented language, such as C$++$, few of the concepts should -seem new to you. Be aware, however, that AST is designed to be used -\emph{via} fairly conventional Fortran and C interfaces, so some -things have to be done a little differently. -f- - -c+ -If you are not already familiar with object-oriented programming, then -don't worry---we will not emphasise this aspect more than is necessary -and will not assume any background knowledge. Instead, this section -concentrates on presenting all the fundamental information you will -need, explaining how AST Objects behave and how to manipulate them -from conventional C programs. -c- -f+ -If you are not already familiar with object-oriented programming, then -don't worry---we will not emphasise this aspect more than is necessary -and will not assume any background knowledge. Instead, this section -concentrates on presenting all the fundamental information you will -need, explaining how AST Objects behave and how to manipulate them -from conventional Fortran programs. -f- - -If you like to read documents from cover to cover, then you can -consider this section as an introduction to the programming techniques -used in the rest of the document. Otherwise, you may prefer to skim -through it on a first reading and return to it later as reference -material. - -\subsection{AST Objects} - -An AST Object is an entity which is used to store information and -Objects come in various kinds, called \emph{classes}, according to the -sort of information they hold. Throughout this section, we will make -use of a simple Object belonging to the ``ZoomMap'' class to -illustrate many of the basic concepts. - -A ZoomMap is an Object that contains a recipe for converting -coordinates between two hypothetical coordinate systems. It does this -by multiplying all the coordinate values by a constant called the -\emph{Zoom factor}. A ZoomMap is a very simple Object which exists -mainly for use in examples. It allows us to illustrate the ways in -which Objects are manipulated and to introduce the concept of a -Mapping---a recipe for converting coordinates---which is fundamental -to the way the AST library works. - -\subsection{\label{ss:objectcreation}Object Creation and Pointers} - -Let us first consider how to create a ZoomMap. This is done very -simply as follows: - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstZoomMap *zoommap; - -... - -zoommap = astZoomMap( 2, 5.0, "" ) -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER STATUS, ZOOMMAP - - STATUS = 0 - - ... - - ZOOMMAP = AST_ZOOMMAP( 2, 5.0D0, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -The first step is to include the header file ``ast.h'' which declares -the interface to the AST library. We then declare a pointer of type -AstZoomMap$*$ to receive the result and invoke the function astZoomMap -to create the ZoomMap. The pattern is the same for all other classes -of AST Object---you simply prefix ``ast'' to the class name to obtain -the function that creates the Object and prefix ``Ast'' to obtain the -type of the returned pointer. -c- -f+ -The first step is to include the file AST\_PAR which defines the -interface to the AST library and, amongst other things, declares -AST\_ZOOMMAP to be an integer function. We then declare an integer -variable ZOOMMAP to receive the result and an integer STATUS variable -to hold the error status, which we initialise to zero. Next, we invoke -AST\_ZOOMMAP to create the ZoomMap. The pattern is the same for all -other classes of AST Object---you simply prefix ``AST\_'' to the class -name to obtain the function that creates the Object. -f- - -These functions are called \emph{constructor functions}, or simply -\emph{constructors} (you can find an individual description of all AST -functions in \appref{ss:functiondescriptions}) and the arguments -passed to the constructor are used to initialise the new Object. In -this case, we specify 2 as the number of coordinates (\emph{i.e.}\ we -are going to work in a 2-dimensional -c+ -space) and 5.0 as the Zoom factor to be applied. Note that this is a C -double value. We will return to the final argument, an empty string, -shortly (\secref{ss:attributeinitialisation}). -c- -f+ -space) and 5.0D0 as the Zoom factor to be applied. Note that this is a -Fortran double precision value. We will return to the final two -arguments, a blank string and the error status, shortly -(\secref{ss:attributeinitialisation} and \secref{ss:errordetection}). -f- - -c+ -The value returned by the constructor is termed an \emph{Object pointer} -or, in this case, a \emph{ZoomMap pointer} and is used to refer to the -Object. You perform all subsequent operations on the Object by -passing this pointer to other AST functions. -c- -f+ -The integer value returned by the constructor is termed an \emph{Object -pointer} or, in this case, a \emph{ZoomMap pointer}. This pointer is not -an Object itself, but is a value used to refer to the Object. You -should be careful not to modify any Object pointer yourself, as this -may render it invalid. Instead, you perform all subsequent operations -on the Object by passing this pointer to other AST routines. -f- - -\subsection{\label{ss:objecthierarchy}The Object Hierarchy} - -Now that we have created our first ZoomMap, let us examine how it -relates to other kinds of Object before investigating what we can do -with it. - -We have so far indicated that a ZoomMap is a kind of Object and have -also mentioned that it is a kind of Mapping as well. These statements -can be represented very simply using the following hierarchy: - -\small -\begin{terminalv} -Object - Mapping - ZoomMap -\end{terminalv} -\normalsize - -which is a way of stating that a ZoomMap is a special class of -Mapping, while a Mapping, in turn, is a special class of Object. This -is exactly like saying that an Oak is a special form of Tree, while a -Tree, in turn, is a special form of Plant. This may seem almost -trivial, but before you turn to read something less dull, be assured -that it is a very important idea to keep in mind in what follows. - -If we look at some of the other Objects used by the AST library, we -can see how these are all related in a similar way (don't worry about -what they do at this stage): -\label{ss:mappinghierarchy} - -\small -\begin{terminalv} -Object - Mapping - Frame - FrameSet - Plot - UnitMap - ZoomMap - Channel - FitsChan - XmlChan -\end{terminalv} -\normalsize - -Notice that there are several different types of Mapping available -(\emph{i.e.}\ there are classes of Object indented beneath the -``Mapping'' heading) and, in addition, other types of Object which are -not Mappings---Channels for instance (which are at the same -hierarchical level as Mappings). - -The most specialised Object we have shown here is the Plot (which we -will not discuss in detail until \secref{ss:plots}). As you can see, a -Plot is a FrameSet\ldots\ and a Frame\ldots\ and a Mapping\ldots\ and, -like everything else, ultimately an Object. - -What this means is that you can use a Plot not only for its own -specialised behaviour, but also whenever any of these other -less-specialised classes of Object is called for. The general rule is -that an Object of a particular class may substitute for any of the -classes appearing above it in this hierarchy. The Object is then said -to \emph{inherit} the behaviour of these higher classes. We can -therefore use our ZoomMap whenever a ZoomMap, a Mapping or an Object -is called for. - -Sometimes, this can lead to some spectacular short-cuts by avoiding -the need to break large Objects down in order to access their -components. With some practice and a little lateral thinking you -should soon be able to spot opportunities for this. - -You can find the full \emph{class hierarchy}, as this is called, for -the AST library in \appref{ss:classhierarchy} and you may need to -refer to it occasionally until you are familiar with the classes you -need to use. - -\subsection{\label{ss:displayingobjects}Displaying Objects} - -Let us now return to the ZoomMap that we created earlier -(\secref{ss:objectcreation}) and examine what it's made of. -c+ -There is a function for doing this, called astShow, which is provided -mainly for looking at Objects while you are debugging programs. -c- -f+ -There is a routine for doing this, called AST\_SHOW, which is provided -mainly for looking at Objects while you are debugging programs. -f- - -c+ -If you consult the description of astShow in -\appref{ss:functiondescriptions}, you will find that it takes a -pointer to an Object (of type AstObject$*$) as its argument. Although -we have only a ZoomMap pointer available, this is not a problem. If -you refer to the brief class hierarchy described above -(\secref{ss:mappinghierarchy}), you will see that a ZoomMap is an -Object, albeit a specialised one, so it inherits the properties of all -Objects and can be substituted wherever an Object is required. We can -therefore pass our ZoomMap pointer directly to astShow, as follows: -c- -f+ -If you consult the description of AST\_SHOW in -\appref{ss:functiondescriptions}, you will find that it takes a -pointer to an Object as its argument (in addition to the usual STATUS -argument). Although we have only a ZoomMap pointer available, -fortunately this is not a problem. If you refer to the brief class -hierarchy described above (\secref{ss:mappinghierarchy}), you will see -that a ZoomMap is an Object, albeit a specialised one, so it inherits -the properties of all Objects and can be substituted wherever an -Object is required. We can therefore pass our ZoomMap pointer -directly to AST\_SHOW, as follows: -f- - -c+ -\small -\begin{terminalv} -astShow( zoommap ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SHOW( ZOOMMAP, STATUS ) -\end{terminalv} -\normalsize -f- - -The output from this will appear on the standard output stream and -should look like the following: - -\small -\begin{terminalv} -Begin ZoomMap - Nin = 2 -IsA Mapping - Zoom = 5 -End ZoomMap -\end{terminalv} -\normalsize - -Here, the ``Begin'' and ``End'' lines mark the beginning and end of -the ZoomMap, while the values 2 and 5 are simply the values we -supplied to initialise it (\secref{ss:objectcreation}). These have -been given simple names to make them easy to refer to. - -The line in the middle which says ``IsA~Mapping'' is a dividing line -between the two values. It indicates that the ``Nin'' value is a -property shared by all Mappings, so the ZoomMap has inherited this -from its \emph{parent class} (Mapping). The ``Zoom'' value, however, -is specific to a ZoomMap and isn't shared by other kinds of Mappings. - -\subsection{\label{ss:gettingattributes}Getting Attribute Values} - -We saw above (\secref{ss:displayingobjects}) how to display the -internal values of an Object, but what about accessing these values -from a program? Not all internal Object values are accessible in this -way, but many are. Those that are, are called \emph{attributes}. A -description of all the attributes used by the AST library can be found -in \appref{ss:attributedescriptions}. - -c+ -Attributes come in several data types (character string, integer, -boolean and floating point) and there is a standard way of obtaining -their values. As an example, consider obtaining the value of the Nin -attribute for the ZoomMap created earlier. This could be done as -follows: -c- -f+ -Attributes come in several data types (character string, integer, -boolean and floating point) and there is a standard way of obtaining -their values. As an example, consider obtaining the value of the Nin -attribute for the ZoomMap created earlier. This could be done as -follows: -f- - -c+ -\small -\begin{terminalv} -int nin; - -... - -nin = astGetI( zoommap, "Nin" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER NIN - - ... - - NIN = AST_GETI( ZOOMMAP, 'Nin', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, the function astGetI is used to extract the attribute value by -giving it the ZoomMap pointer and the attribute name (attribute names -are not case sensitive, but we have used consistent capitalisation in -this document in order to identify them). Remember to use the -``ast.h'' header file to include the function prototype. -c- -f+ -Here, the integer function AST\_GETI is used to extract the attribute -value by giving it the ZoomMap pointer and the attribute name -(attribute names are not case sensitive, but we have used consistent -capitalisation in this document in order to identify them). Remember -to use the AST\_PAR include file to save having to declare AST\_GETI -as integer yourself. -f- - -c+ -If we had wanted the value of the Zoom attribute, we would probably -have used astGetD instead, this being a double version of the same -function, for example: -c- -f+ -If we had wanted the value of the Zoom attribute, we would probably -have used AST\_GETD instead, this being a double precision version of -the same function, for example: -f- - -c+ -\small -\begin{terminalv} -double zoom; - -... - -zoom = astGetD( zoommap, "Zoom" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DOUBLE PRECISION ZOOM - - ... - - ZOOM = AST_GETD( ZOOMMAP, 'Zoom', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -However, we could equally well have read the Nin value as double, or -the Zoom value as an integer, or whatever we wanted. -c- -f+ -However, we could equally well have read the Nin value as double -precision, or the Zoom value as an integer, or whatever we wanted. -f- - -c+ -The data type you want returned is specified simply by replacing the -final character of the astGetX function name with C~(character -string), D~(double), F~(float), I~(int) or L~(long). If possible, the -value is converted to the type you want. If not, an error message will -result. Note that all floating point values are stored internally as -double, and all integer values as int. Boolean values are also stored -as integers, but only take the values 1 and 0 (for true/false). -c- -f+ -The data type you want returned is specified simply by replacing the -final character of the AST\_GETx function name with C~(character), -D~(double precision), I~(integer), L~(logical) or R~(real). If -possible, the value is converted to the type you want. If not, an -error message will result. In converting from integer to logical, zero -is regarded as .FALSE.\ and non-zero as .TRUE.. Note that all floating -point values are stored internally as double precision. Boolean values -are stored as integers, but only take the values 1 and 0 (for -true/false). -f- - -\subsection{\label{ss:settingattributes}Setting Attribute Values} - -Some attribute values are read-only and cannot be altered after an -Object has been created. The Nin attribute of a ZoomMap (describing -the number of coordinates) is like this. It is defined when the -ZoomMap is created, but cannot then be altered. - -Other attributes, however, can be modified whenever you want. A -ZoomMap's Zoom attribute is like this. If we wanted to change it, this -could be done simply as follows: - -c+ -\small -\begin{terminalv} -astSetD( zoommap, "Zoom", 99.6 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SETD( ZOOMMAP, 'Zoom', 99.6D0, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -which sets the value to 99.6. As when getting an attribute value -(\secref{ss:gettingattributes}), you have a choice of which data type -you will use to supply the new value. For instance, you could use an -integer value, as in: -c- -f+ -which sets the value to 99.6 (double precision). As when getting an -attribute value (\secref{ss:gettingattributes}), you have a choice of -which data type you will use to supply the new value. For instance, -you could use an integer value, as in: -f- - -c+ -\small -\begin{terminalv} -astSetI( zoommap, "Zoom", 99 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SETI( ZOOMMAP, 'Zoom', 99, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -and the necessary data conversion would occur. You specify the data -type you want to supply simply by replacing the final character of the -astSetX function name with C~(character string), D~(double), -F~(float), I~(int) or L~(long). Setting a boolean attribute to any -non-zero integer causes it to take the value 1. -c- -f+ -and the necessary data conversion would occur. You specify the data -type you want to supply simply by replacing the final character of the -AST\_SETx routine name with C~(character), D~(double precision), -I~(integer), L~(logical) or R~(real). Setting a boolean attribute to -any non-zero integer causes it to take the value 1. -f- - -c+ -An alternative way of setting attribute values for Objects is to use -the astSet function (\emph{i.e.}\ with no final character specifying a -data type). In this case, you supply the attribute values in a -character string. The big advantage of this method is that you can -assign values to several attributes at once, separating them with -commas. This also reads more naturally in programs. For example: -c- -f+ -An alternative way of setting attribute values for Objects is to use -the AST\_SET routine (\emph{i.e.}\ with no final character specifying -a data type). In this case, you supply the attribute values in a -character string. The big advantage of this method is that you can -assign values to several attributes at once, separating them with -commas. This also reads more naturally in programs. For example: -f- - -c+ -\small -\begin{terminalv} -astSet( zoommap, "Zoom=99.6, Report=1" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( ZOOMMAP, 'Zoom=99.6, Report=1', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -would set values for both the Zoom attribute and the Report attribute -(about which more shortly---\secref{ss:transforming}). You don't really -have to worry about data types with this method, as any character -representation will do. Note, when using astSet, a -literal comma may be included in an attribute value by enclosed the value in -quotation marks: -\small -\begin{terminalv} - astSet( skyframe, 'SkyRef="12:13:32,-23:12:44"' ); -\end{terminalv} -\normalsize -c- -f+ -would set values for both the Zoom attribute and the Report attribute -(about which more shortly---\secref{ss:transforming}). You don't really -have to worry about data types with this method, as any character -representation will do (although you must use 0/1 instead of -.TRUE./.FALSE., which are not supported). Note, when using AST\_SET, a -literal comma may be included in an attribute value by enclosed the value in -quotation marks: -\small -\begin{terminalv} - CALL AST_SET( SKYFRAME, 'SkyRef="12:13:32,-23:12:44"', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Another attractive feature of astSet is that you can build the -character string which contains the attribute settings in the same way -as when using the C run time library ``printf'' function. This is most -useful when the values you want to set are held in other -variables. For example: - -\small -\begin{terminalv} -double zoom = 99.6; -int report = 1; - -... - -astSet( zoommap, "Zoom=%g, Report=%d", zoom, report ); -\end{terminalv} -\normalsize - -would replace the ``\%'' conversion specifications by the values -supplied as additional arguments. Any number of additional arguments -may be supplied and the formatting rules are exactly the same as for -the C ``printf'' family of functions. This is a very flexible -technique, but does contain one pitfall: - -\begin{quote} -\textbf{Pitfall.} The default precision used by ``printf'' (and astSet) -for floating point values is only 6 decimal digits, corresponding -approximately to float on most machines, whereas the AST library -stores such values internally as doubles. You should be careful to -specify a larger precision (such as DBL\_DIG, as defined in -$<$float.h$>$) when necessary. For example: - -\small -\begin{terminalv} -#include - -... - -astSet( zoommap, "Zoom=%.*g", DBL_DIG, double_value ); -\end{terminalv} -\normalsize -\end{quote} - -Substituted strings may contain commas and this is a useful way of -assigning such strings as attribute values without the comma being -interpreted as an assignment separator, for example: - -\small -\begin{terminalv} -astSet( object, "Attribute=%s", "A string, containing a comma" ); -\end{terminalv} -\normalsize - -This is equivalent to using astSetC and one of these two methods -should always be used when assigning string attribute values which -might potentially contain a comma (\emph{e.g.}\ strings obtained from -an external source). However, you should not attempt to use astSet to -substitute strings that contain newline characters, since these are -used internally as separators between adjacent attribute assignments. -c- -\label{ss:attributeinitialisation} - -c+ -Finally, a very convenient way of setting attribute values is to do so -at the same time as you create an Object. Every Object constructor -function has a final character string argument which allows you to do -this. Although you can simply supply an empty string, it is an ideal -opportunity to initialise the Object to have just the attributes you -want. For example, we might have created our original ZoomMap with: -c- -f+ -Finally, a very convenient way of setting attribute values is to do so -at the same time as you create an Object. Every Object constructor -function has a penultimate character argument which allows you to do -this. Although you can simply leave this blank, it is an ideal -opportunity to initialise the Object to have just the attributes you -want. For example, we might have created our original ZoomMap with: -f- - -c+ -\small -\begin{terminalv} -zoommap = astZoomMap( 2, 5.0, "Report=1" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - ZOOMMAP = AST_ZOOMMAP( 2, 5.0D0, 'Report=1', STATUS ) -\end{terminalv} -\normalsize -f- - -and it would then start life with its Report attribute set to 1. -c+ -The ``printf''-style substitution described above may also be used -here. -c- - -\subsection{\label{ss:defaultingattributes}Testing, Clearing and Defaulting Attributes} - -c+ -You can use the astGetX family of functions -(\secref{ss:gettingattributes}) to get a value for any Object attribute -at any time, regardless of whether a value has previously been set for -it. If no value has been set, the AST library will generate a suitable -default value. -c- -f+ -You can use the AST\_GETx family of routines -(\secref{ss:gettingattributes}) to get a value for any Object attribute -at any time, regardless of whether a value has previously been set for -it. If no value has been set, the AST library will generate a suitable -default value. -f- - -Often, the default value of an attribute will not simply be trivial -(zero or blank) but may involve considerable processing to -calculate. Wherever possible, defaults are designed to be real-life, -sensible values that convey information about the state of the -Object. In particular, they may often be based on the values of other -attributes, so their values may change in response to changes in these -other attributes. The ZoomMap class that we have studied so far is a -little too simple to show this behaviour, but we will meet it later -on. - -An attribute that returns a default value in this way is said to be -\emph{un-set}. Conversely, once an explicit value has been assigned to -an attribute, it becomes \emph{set} and will always return precisely -that value, never a default. - -c+ -The distinction between set and un-set attributes is important and -affects the behaviour of several key routines in the AST library. You -can test if an attribute is set using the function astTest, which -returns a boolean (integer) result, as in: -c- -f+ -The distinction between set and un-set attributes is important and -affects the behaviour of several key routines in the AST library. You -can test if an attribute is set using the logical function AST\_TEST, -as in: -f- - -c+ -\small -\begin{terminalv} -if ( astTest( zoommap, "Report" ) ) { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - IF ( AST_TEST( ZOOMMAP, 'Report', STATUS ) ) THEN - - END IF -\end{terminalv} -\normalsize -f- - -f+ -(as usual, remember to include the AST\_PAR file to declare the -function as LOGICAL, or make this declaration yourself). -f- - -c+ -Once an attribute is set, you can return it to its un-set state using -astClear. The effect is as if it had never been set in the first -place. For example: -c- -f+ -Once an attribute is set, you can return it to its un-set state using -AST\_CLEAR. The effect is as if it had never been set in the first -place. For example: -f- - -c+ -\small -\begin{terminalv} -astClear( zoommap, "Report" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_CLEAR( ZOOMMAP, 'Report', STATUS ) -\end{terminalv} -\normalsize -f- - -would ensure that the default value of the Report attribute is used -subsequently. - -%\subsection{TBW--Handling Character Attributes} - -\subsection{\label{ss:transforming}Transforming Coordinates} - -We now have the necessary apparatus to start using our ZoomMap to show -what it is really for. Here, we will also encounter a routine that is -a little more fussy about the type of pointer it will accept. - -The purpose of a ZoomMap is to multiply coordinates by a constant zoom -factor. To witness this in action, we will first set the Report -attribute for our ZoomMap to a non-zero value: - -c+ -\small -\begin{terminalv} -astSet( zoommap, "Report=1" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( ZOOMMAP, 'Report=1', STATUS ) -\end{terminalv} -\normalsize -f- - -This boolean (integer) attribute, which is present in all Mappings -(and a ZoomMap is a Mapping), causes the automatic display of all -coordinate values that the Mapping converts. It is not a good idea to -leave this feature turned on in a finished program, but it can save a -lot of work during debugging. - -c+ -Our next step is to set up some coordinates for the ZoomMap to work -on, using two arrays ``xin'' and ``yin'', and two arrays to receive -the transformed coordinates, ``xout'' and ``yout''. Note that these -are arrays of double, as are all coordinate data processed by the AST -library: -c- -f+ -Our next step is to set up some coordinates for the ZoomMap to work -on, using two arrays XIN and YIN, and two arrays to receive the -transformed coordinates, XOUT and YOUT. Note that these arrays are -double precision, as are all coordinate data processed by the AST -library: -f- - -c+ -\small -\begin{terminalv} -double xin[ 10 ] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 }; -double yin[ 10 ] = { 0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0 }; -double xout[ 10 ]; -double yout[ 10 ]; -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DOUBLE PRECISION XIN( 10 ), YIN( 10 ), XOUT( 10 ), YOUT( 10 ) - DATA XIN / 0D0, 1D0, 2D0, 3D0, 4D0, 5D0, 6D0, 7D0, 8D0, 9D0 / - DATA YIN / 0D0, 2D0, 4D0, 6D0, 8D0, 10D0, 12D0, 14D0, 16D0, 18D0 / -\end{terminalv} -\normalsize -f- - -c+ -We will now use the function astTran2 to transform the input -coordinates. This is the most commonly-used (2-dimensional) coordinate -transformation function. If you look at its description in -\appref{ss:functiondescriptions}, you will see that it requires a -pointer to a Mapping, so we cannot supply just any old Object pointer, -as we could with the functions discussed previously. If we passed it a -pointer to an inappropriate Object, an error message would result. -c- -f+ -We will now use the routine AST\_TRAN2 to transform the input -coordinates. This is the most commonly-used (2-dimensional) coordinate -transformation routine. If you look at its description in -\appref{ss:functiondescriptions}, you will see that it requires a -pointer to a Mapping, so we cannot supply just any old Object pointer, -as we could with the routines discussed previously. If we passed it a -pointer to an inappropriate Object, an error message would result. -f- - -c+ -Fortunately, a ZoomMap is a Mapping (\appref{ss:classhierarchy}), so we -can use it with astTran2 to transform our coordinates, as follows: -c- -f+ -Fortunately, a ZoomMap is a Mapping (\appref{ss:classhierarchy}), so we -can use it with AST\_TRAN2 to transform our coordinates, as follows: -f- - -c+ -\small -\begin{terminalv} -astTran2( zoommap, 10, xin, yin, 1, xout, yout ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_TRAN2( ZOOMMAP, 10, XIN, YIN, .TRUE., XOUT, YOUT, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, 10 is the number of points we want to transform and the fifth -argument value of 1 indicates that we want to transform in the -\emph{forward} direction (from input to output). -c- -f+ -Here, 10 is the number of points we want to transform and the fifth -argument value of .TRUE.\ indicates that we want to transform in the -\emph{forward} direction (from input to output). -f- - -Because our ZoomMap's Report attribute is set to 1, this will cause -the effects of the ZoomMap on the coordinates to be displayed on the -standard output stream: - -\small -\begin{terminalv} -(0, 0) --> (0, 0) -(1, 2) --> (5, 10) -(2, 4) --> (10, 20) -(3, 6) --> (15, 30) -(4, 8) --> (20, 40) -(5, 10) --> (25, 50) -(6, 12) --> (30, 60) -(7, 14) --> (35, 70) -(8, 16) --> (40, 80) -(9, 18) --> (45, 90) -\end{terminalv} -\normalsize - -c+ -This shows the coordinate values of each point both before and after -the ZoomMap is applied. You can see that each coordinate value has -been multiplied by the factor 5 determined by the Zoom attribute -value. The transformed coordinates are now stored in the ``xout'' and -``yout'' arrays. -c- -f+ -This shows the coordinate values of each point both before and after -the ZoomMap is applied. You can see that each coordinate value has -been multiplied by the factor 5 determined by the Zoom attribute -value. The transformed coordinates are now stored in the XOUT and YOUT -arrays. -f- - -c+ -If we wanted to transform in the opposite direction, we need simply -change the fifth argument of astTran2 from 1 to 0. We can also feed -the output coordinates from the above back into the function: -c- -f+ -If we wanted to transform in the opposite direction, we need simply -change the fifth argument of AST\_TRAN2 from .TRUE. to .FALSE.. We can -also feed the output coordinates from the above back into the routine: -f- - -c+ -\small -\begin{terminalv} -astTran2( zoommap, 10, xout, yout, 0, xin, yin ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_TRAN2( ZOOMMAP, 10, XOUT, YOUT, .FALSE., XIN, YIN, STATUS ) -\end{terminalv} -\normalsize -f- - -The output would then look like: - -\small -\begin{terminalv} -(0, 0) --> (0, 0) -(5, 10) --> (1, 2) -(10, 20) --> (2, 4) -(15, 30) --> (3, 6) -(20, 40) --> (4, 8) -(25, 50) --> (5, 10) -(30, 60) --> (6, 12) -(35, 70) --> (7, 14) -(40, 80) --> (8, 16) -(45, 90) --> (9, 18) -\end{terminalv} -\normalsize - -This is termed the \emph{inverse} transformation (we have converted -from output to input) and you can see that the original coordinates -have been recovered by dividing by the Zoom factor. - -\subsection{\label{ss:annullingpointers}Managing Object Pointers} - -So far, we have looked at creating Objects and using them in various -simple ways but have not yet considered how to get rid of them again. - -c+ -Every Object consumes various computer resources (principally memory) -and should be disposed of when it is no longer required, so as to free -up these resources. One way of doing this (not necessarily the -best---\secref{ss:contexts}) is to \emph{annul} each Object pointer once -you have finished with it, using astAnnul. For example: -c- -f+ -Every Object consumes various computer resources (principally memory) -and should be disposed of when it is no longer required, so as to free -up these resources. One way of doing this (not necessarily the -best---\secref{ss:contexts}) is to \emph{annul} each Object pointer once -you have finished with it, using AST\_ANNUL. For example: -f- - -c+ -\small -\begin{terminalv} -zoommap = astAnnul( zoommap ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_ANNUL( ZOOMMAP, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -This indicates that you have finished with the pointer. Since astAnnul -always returns the null value AST\_\_NULL (as defined in ``ast.h''), -the recommended way of using it, as here, is to assign the returned -value to the pointer being annulled. This ensures that any attempt to -use the pointer again will generate an error message. -c- -f+ -This indicates that you have finished with the pointer and sets it to -the null value AST\_\_NULL (as defined in the AST\_PAR include file), -so that any attempt to use it again will generate an error message. -f- - -c+ -In general, this process may not delete the Object, because there may -still be other pointers associated with it. However, each Object -maintains a count of the number of pointers associated with it and -will be deleted if you annul the final pointer. Using astAnnul -consistently will therefore ensure that all Objects are disposed of at -the correct time. You can determine how many pointers are associated -with an Object by examining its (read-only) RefCount attribute. -c- -f+ -In general, this process may not delete the Object, because there may -still be other pointers associated with it. However, each Object -maintains a count of the number of pointers associated with it and -will be deleted if you annul the final pointer. Using AST\_ANNUL -consistently will therefore ensure that all Objects are disposed of at -the correct time. You can determine how many pointers are associated -with an Object by examining its (read-only) RefCount attribute. -f- - -c+ -\subsection{\label{ss:contexts}AST Pointer Contexts---Begin and End} -c- -f+ -\subsection{\label{ss:contexts}AST Pointer Contexts---Begin and End} -f- - -c+ -The use of astAnnul (\secref{ss:annullingpointers}) is not completely -foolproof, however. Consider the following: -c- -f+ -The use of AST\_ANNUL (\secref{ss:annullingpointers}) is not completely -foolproof, however. Consider the following: -f- - -c+ -\small -\begin{terminalv} -astShow( astZoomMap( 2, 5.0, "" ) ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SHOW( AST_ZOOMMAP( 2, 5.ODO, ' ', STATUS ), STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -This creates a ZoomMap and displays it on standard output -(\secref{ss:displayingobjects}). Using function invocations as -arguments to other functions in this way is very convenient because it -avoids the need for intermediate pointer variables. However, the -pointer generated by astZoomMap is still active, and since we have not -stored its value, we cannot use astAnnul to annul it. The ZoomMap will -therefore stay around until the end of the program. -c- -f+ -This creates a ZoomMap and displays it on standard output -(\secref{ss:displayingobjects}). Using function invocations as -arguments to other routines in this way is very convenient because it -avoids the need for intermediate pointer variables. However, the -pointer generated by AST\_ZOOMMAP is still active, and since we have -not stored its value, we cannot use AST\_ANNUL to annul it. The -ZoomMap will therefore stay around until the end of the program. -f- - -c+ -A simple way to avoid this problem is to enclose all use of AST -functions between invocations of astBegin and astEnd, for example: -c- -f+ -A simple way to avoid this problem is to enclose all use of AST -routines between calls to AST\_BEGIN and AST\_END, for example: -f- - -c+ -\small -\begin{terminalv} -astBegin; -astShow( astZoomMap( 2, 5.0, "" ) ); -astEnd; -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_BEGIN( STATUS ) - CALL AST_SHOW( AST_ZOOMMAP( 2, 5.ODO, ' ', STATUS ), STATUS ) - CALL AST_END( STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -When the expansion of astEnd (which is a macro) executes, every Object -pointer created since the previous use of astBegin (also a macro) is -automatically annulled and any Objects left without pointers are -deleted. This provides a simple solution to managing Objects and their -pointers, and allows you to create Objects very freely without needing -to keep detailed track of each one. Because this is so convenient, we -implicitly assume that astBegin and astEnd are used in most of the -examples given in this document. Pointer management is not generally -shown explicitly unless it is particularly relevant to the point being -illustrated. -c- -f+ -When the AST\_END call executes, every Object pointer created since -the previous AST\_BEGIN call is automatically annulled and any Objects -left without pointers are deleted. This provides a simple solution to -managing Objects and their pointers, and allows you to create Objects -very freely without needing to keep detailed track of each one. -Because this is so convenient, we implicitly assume that AST\_BEGIN -and AST\_END are used in most of the examples given in this document. -Pointer management is not generally shown explicitly unless it is -particularly relevant to the point being illustrated. -f- - -c+ -If necessary, astBegin and astEnd may be nested, like blocks delimited -by ``\{\ldots\}'' in C, to define a series of AST pointer -contexts. Each use of astEnd will then annul only those Object -pointers created since the matching use of astBegin. -c- -f+ -If necessary, calls to AST\_BEGIN and AST\_END may be nested, like -IF\ldots ENDIF blocks in Fortran, to define a series of AST pointer -contexts. Each call to AST\_END will then annul only those Object -pointers created since the matching call to AST\_BEGIN. -f- - -\subsection{Exporting, Importing and Exempting AST Pointers} -c+ -The astExport function allows you to export particular pointers from -one AST context (\secref{ss:contexts}) to the next outer one, as -follows: -c- -f+ -The AST\_EXPORT routine allows you to export particular pointers from -one AST context (\secref{ss:contexts}) to the next outer one, as -follows: -f- - -c+ -\small -\begin{terminalv} -astExport( zoommap ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_EXPORT( ZOOMMAP, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -This would identify the pointer stored in ``zoommap'' as being required -after the end of the current AST context. It causes any pointers -nominated in this way to survive the next use of astEnd (but only one -such use) unscathed, so that they are available to the next outer -context. This facility is not needed often, but is invaluable when -the purpose of your astBegin\ldots astEnd block is basically to -generate an Object pointer. Without this, there is no way of getting -that pointer out. -c- -f+ -This would identify the pointer stored in ZOOMMAP as being required after -the end of the current AST context. It causes any pointers nominated -in this way to survive the next call to AST\_END (but only one such -call) unscathed, so that they are available to the next outer context. -This facility is not needed often, but is invaluable when the purpose -of your AST\_BEGIN\ldots AST\_END block is basically to generate an -Object pointer. Without this, there is no way of getting that pointer -out. -f- - -f+ -The AST\_IMPORT routine can be used in a similar manner to import a -pointer into the current context, so that it is deleted when the current -context is closed using AST\_END. -f- - -c+ -The astImport routine can be used in a similar manner to import a -pointer into the current context, so that it is deleted when the current -context is closed using astEnd. -c- - -c+ -Sometimes, you may also want to exempt a pointer from all the effects -of AST contexts. You should not need to do this often, but it will -prove essential if you ever need to write a library of functions that -stores AST pointers as part of its own internal data. Without some -form of exemption, the caller of your routines could cause the -pointers you have stored to be annulled---thus corrupting your -internal data---simply by using astEnd. To avoid this, you should use -astExempt on each pointer that you store, for example: -c- -f+ -Sometimes, you may also want to exempt a pointer from all the effects -of AST contexts. You should not need to do this often, but it will -prove essential if you ever need to write a library of routines that -stores AST pointers as part of its own internal data. Without some -form of exemption, the caller of your routines could cause the -pointers you have stored to be annulled---thus corrupting your -internal data---simply by using AST\_END. To avoid this, you should -use AST\_EXEMPT on each pointer that you store, for example: -f- - -c+ -\small -\begin{terminalv} -astExempt( zoommap ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_EXEMPT( ZOOMMAP, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -This will prevent the pointer being affected by any subsequent use of -astEnd. Of course, it then becomes your responsibility to annul this -pointer (using astAnnul) when it is no longer required. -c- -f+ -This will prevent the pointer being affected by any subsequent use of -AST\_END. Of course, it then becomes your responsibility to annul this -pointer (using AST\_ANNUL) when it is no longer required. -f- - - -c+ -\subsection{AST Objects within Multi-threaded Applications} - -When the AST library is built from source, the build process checks to -see if the POSIX threads library (``\texttt{pthreads}'') is available. If so, -appropriate \texttt{pthreads} calls are inserted into the AST source code to -ensure that AST is thread-safe, and the AST\_\_THREADSAFE macro (defined -in the ``ast.h'' header file) is set to ``\texttt{1}''. If the \texttt{pthreads} -library cannot be found when AST is built, a working version of the AST -library will still be created, but it will not be thread-safe. In this -case the AST\_\_THREADSAFE macro will be set to ``\texttt{0}'' in ast.h. The -rest of this section assumes that the thread-safe version of AST is being -used. - -Note, some AST functions call externally specified functions (\emph{e.g.} -the source and sink functions used by the Channel class or the graphics -primitives functions used by the Plot class). AST does not know whether -such functions are thread-safe or not. For this reason, invocations of these -functions within a multi-threaded environment are serialised using a mutex -in order to avoid two or more threads executing an external function -simultaneously. - -If an application uses more than one thread, the possibility arises that -an Object created by one thread may be accessed by another thread, potentially -simultaneously. If any of the threads modifies any aspect of the Object, -this could lead to serious problems within the other threads. For this -reason, some restrictions are placed on how Objects can be used in a -multi-threaded application. - -\subsubsection{Locking AST Objects for Exclusive Use} -The basic restriction is that a thread can only access Objects that it -has previously locked for its own exclusive use. If a thread attempts to -access any Object that it has not locked, an error is reported. - -The astAnnul function is the one exception to this restriction. Pointers -for Objects not currently locked by the calling thread can be annulled -succesfully using astAnnul. This means that a thread that has finished -with an Object pointer can unlock the Object by passing the pointer to -astUnlock (so that other threads can use the Object via their own cloned -pointers), and can then annul the pointer using astAnnul. Note, however, -that an error will be reported by astAnnul if the supplied pointer has -been locked by another thread using astLock. - -When an Object is created, it is initially locked by the calling thread. -Therefore a thread does not need to lock an Object explicitly if it was -created in the same thread. - -If the Object pointer is then passed to another thread, the first thread -must unlock the Object using astUnlock and the second thread must then lock -it using astLock. - -If a thread attempts to lock an Object that is already locked by another -thread, it can choose to report an error immediately or to wait until the -Object is available. - -The astThread function can be used to determine whether an Object is -locked by the running thread, locked by another thread, or unlocked. - -If two or more threads need simultaneous access to an Object, a deep copy -of the Object should be taken for each thread, using astCopy, and then -the copies should be unlocked and passed to the othe threads, which -should then lock them. Note, if a thread modifies the Object, the -modification will have no effect on the other threads, because the Object -copies are independent of each other. - -\subsubsection{AST Pointer Contexts} - -Each thread maintains its own set of nested AST contexts, so when astEnd -is called, only Objects that are locked by the current thread will -be annulled. - -If an Object is unlocked by a thread using astUnlock, it is exempted from -context handling so that subsequent invocations of astEnd will not cause it -to be annulled (this is similar to using astExempt on the Object). When the -Object is subsequently locked by another thread using astLock, it will be -imported into the context that was active when astLock was called. - -c- - - -\subsection{\label{ss:copyingobjects}Copying Objects} - -The AST library makes extensive use of pointers, not only for -accessing Objects directly, but also as a means of storing Objects -inside other Objects (a number of classes of Object are designed to -hold collections of other Objects). Rather than copy an Object in its -entirety, a pointer to the interior Object is simply stored in the -enclosing Object. - -This means that Objects may frequently not be completely independent -of each other because, for instance, they both contain pointers to the -same sub-Object. In this situation, changing one Object (say assigning -an attribute value) may affect the other one \emph{via} the common -Object. - -c+ -It is difficult to describe all cases where this may happen, so you -should always be alert to the possibility. Fortunately, there is a -simple solution. If you require two Objects to be independent, then -simply use astCopy to make a copy of one, \emph{e.g.}: -c- -f+ -It is difficult to describe all cases where this may happen, so you -should always be alert to the possibility. Fortunately, there is a -simple solution. If you require two Objects to be independent, then -simply use AST\_COPY to make a copy of one, \emph{e.g.}: -f- - -c+ -\small -\begin{terminalv} -AstZoomMap *zoommap1, *zoommap2; - -... - -zoommap2 = astCopy( zoommap1 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER ZOOMMAP1, ZOOMMAP2 - - ... - - ZOOMMAP2 = AST_COPY( ZOOMMAP1, STATUS ) -\end{terminalv} -\normalsize -f- - -This process will create a true copy of any Object and return a -pointer to the copy. This copy will not contain any pointers to any -component of the original Object (everything is duplicated), so you -can then modify it safely, without fear of affecting either the -original or any other Object. - -%\subsection{TBW - Inheritance} - -c+ -\subsection{C Pointer Types} - -At this point it is necessary to confess to a small amount of -deception. So far, we have been passing Object pointers to AST -functions in order to perform operations on those Objects. In fact, -however, what we were using were not true C functions at all, but -merely macros which invoke a related set of hidden functions with -essentially the same arguments. In practical terms, this makes very -little difference to how you use the functions, as we will continue to -call them.\footnote{About the only difference is that you cannot store -a pointer to an AST ``function'' in a variable and use the variable's -value to invoke that function again later.} - -The reason for this deception has to do with the rules for data typing -in C. Recall that most AST functions can be used to process Objects -from a range of different classes (\secref{ss:objecthierarchy}). In C, -this means passing different pointer types to the same function and -most C compilers will not permit this (at least, not without -grumbling) because it usually indicates a programming error. In AST, -however, it is perfectly safe if done properly. Some way is therefore -needed of circumventing the normal compiler checking. - -The normal way of doing this in C is with a cast. This approach -quickly becomes cumbersome, however, so we have adopted the strategy -of wrapping each function in a macro which applies the appropriate -cast for you. This means that you can pass pointers of any type to any -AST function. For example, in passing a ZoomMap pointer to astShow: - -\small -\begin{terminalv} -AstZoomMap *zoommap; - -... - -zoommap = astZoomMap( 2, 5.0, "" ); -astShow( zoommap ); -\end{terminalv} -\normalsize - -we are exploiting this mechanism to avoid a compiler warning, because -the notional type of astShow's parameter is AstObject$*$ (not -AstZoomMap$*$). - -We must still guard against programming errors, however, so every -pointer's type is checked by the enclosing macro immediately before -any AST function executes. This allows pointer mis-matches (in the -more liberal AST sense---\emph{i.e.}\ taking account of the class -hierarchy, rather than the stricter C sense) to be detected at -run-time and a suitable error message will be reported. This message -should also identify the line where the error occurs. - -A similar strategy is used when pointers are returned by AST functions -(\emph{i.e.}\ as the function result). In this case the pointer is -cast to void$*$, although we retain the notional pointer type in the -function's documentation -(\emph{e.g.}\ \appref{ss:functiondescriptions}). This allows you to -assign function results to pointer variables without using an explicit -cast. For example, the astRead function returns an Object pointer, but -might be used to read (say) a ZoomMap as follows: - -\small -\begin{terminalv} -AstChannel *channel; -AstZoomMap *zoommap; - -... - -zoommap = astRead( channel ); -\end{terminalv} -\normalsize - -Strictly, there is a C pointer mis-match here, but it is ignored -because the operation makes perfect sense to AST. - -\textbf{There is an important exception to this, however, in that -constructor functions always return strongly-typed pointers.} What -we mean by this is that the returned pointer is never implicitly cast -to void$*$. You must therefore match pointer types when you initially -create an Object using its constructor, such as in the following: - -\small -\begin{terminalv} -AstZoomMap *zoommap; - -... - -zoommap = astZoomMap( 2, 5.0, "" ); -\end{terminalv} -\normalsize - -If the variable receiving the pointer is of a different type, an -appropriate cast should be used, as in: - -\small -\begin{terminalv} -AstMapping *mapping; - -... - -mapping = (AstMapping *) astZoomMap( 2, 5.0, "" ); -\end{terminalv} -\normalsize - -This is an encouragement for you to declare your pointer types -consistently, since this is of great benefit to anyone trying to -understand your software. - -Finally, we should also make one more small confession---AST pointers -are not really pointers at all. Although they behave like pointers, -the actual ``values'' stored are not the addresses of C data -structures. This means that you cannot de-reference an AST pointer to -examine the data within (although you can use astShow -instead---\secref{ss:displayingobjects}). This is necessary so that AST -pointers can be made unique even although several of them might -reference the same Object. -c- - -\subsection{\label{ss:errordetection}Error Detection} - -c+ -If an error occurs in an AST function (for example, if you supply an -invalid argument, such as a pointer to the wrong class of Object), an -error message will be written to the standard error stream and the -function will immediately return. -c- -f+ -If an error occurs in an AST routine (for example, if you supply an -invalid argument, such as a pointer to the wrong class of Object), an -error message will be written to the standard error stream and the -function will immediately return. -f- - -c+ -To indicate than an error has occurred, an AST \emph{error status} -value is used. This integer value is stored internally by AST and is -initially clear (\emph{i.e.}\ set to zero\footnote{We will assume -throughout that the ``OK'' value is zero, as it currently is. However, -a different value could, in principle, be used if the environment in -which AST is running requires it. This is why a simple interface is -provided to isolate you from the actual value of the error status.} -to indicate no error). If an error occurs, it becomes set to a -different \emph{error value}, which allows you to detect the error, as -follows: -c- -f+ -To indicate that an error has occurred, each AST routine that can -potentially fail has a final integer \emph{error status} argument -called STATUS. This is both an input and an output argument. -Normally, you should declare a single error status variable and pass -it as the STATUS argument to every AST routine you invoke. This -variable must initially be cleared (\emph{i.e.}\ set to -zero\footnote{We will assume throughout that the ``OK'' value is zero, -as it currently is. However, a different value could, in principle, be -used if the environment in which AST is running requires it. To allow -for this possibility, you might prefer to use a parameter constant to -represent the value zero when testing for errors.} to indicate no -error). If an error occurs, the STATUS argument is returned set to a -different \emph{error value}, which allows you to detect the error, as -follows: -f- - -c+ -\small -\begin{terminalv} -zoommap = astZoomMap( 2, 5.0, "Title=My ZoomMap" ); -if ( !astOK ) { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - STATUS = 0 - - ... - - ZOOMMAP = AST_ZOOMMAP( 2, 5.0D0, 'Title=My ZoomMap', STATUS ) - IF ( STATUS .NE. 0 ) THEN - - END IF -\end{terminalv} -\normalsize -f- - -c+ -The macro astOK is used to test whether the AST error status is still -OK. In this example it would not be, because we have attempted to set -a value for the Title attribute of a ZoomMap and a ZoomMap does not -have such an attribute. The actual value of the AST error status can -be obtained using the astStatus macro, as follows: - -\small -\begin{terminalv} -int status; - -... - - -status = astStatus; -\end{terminalv} -\normalsize -c- -f+ -In this example, an error would be detected because we have attempted -to set a value for the Title attribute of a ZoomMap and a ZoomMap does -not have such an attribute. -f- - -c+ -A consequence of the AST error status being set is that almost all AST -functions will subsequently cease to function and will instead simply -return without action. This means that you do not need to use astOK -to check for errors very frequently. Instead, you can usually simply -invoke a succession of AST functions. If an error occurs in any of -them, the following ones will do nothing and you can check for the -error at the end, for example: -c- -f+ -A consequence of the error status variable STATUS being set to an -error value is that almost all AST routines will subsequently cease to -function and will instead simply return without action. This means -that you do not need to check for errors very frequently. Instead, you -can usually simply invoke a succession of AST routines. If an error -occurs in any of them, the following ones will do nothing and you can -check for the error at the end, for example: -f- - -c+ -\small -\begin{terminalv} -astFunctionA( ... ); -astFunctionB( ... ); -astFunctionC( ... ); -if ( !astOK ) { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - STATUS = 0 - - ... - - CALL AST_ROUTINEA( ... , STATUS ) - CALL AST_ROUTINEB( ... , STATUS ) - CALL AST_ROUTINEC( ... , STATUS ) - IF ( STATUS .NE. 0 ) THEN - - END IF -\end{terminalv} -\normalsize -f- - -c+ -There are, however, a few functions which do not adhere to this -general rule and which will attempt to execute if the AST error status -is set. These functions, such as astAnnul, are concerned with cleaning -up and recovering resources. For example, in the following: -c- -f+ -There are, however, a few routines which do not adhere to this general -rule and which will attempt to execute if their STATUS argument is -initially set. These routines, such as AST\_ANNUL, are concerned with -cleaning up and recovering resources. For example, in the following: -f- - -c+ -\small -\begin{terminalv} -zoommap = astZoomMap( 2, 5.0, "" ); - -astFunctionX( ... ); -astFunctionY( ... ); -astFunctionZ( ... ); - -zoommap = astAnnul( zoommap ); -if ( !astOK ) { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - STATUS = 0 - - ... - - ZOOMMAP = AST_ZOOMMAP( 2, 5.0D0, ' ', STATUS ) - - CALL AST_ROUTINEX( ... , STATUS ) - CALL AST_ROUTINEY( ... , STATUS ) - CALL AST_ROUTINEZ( ... , STATUS ) - - CALL AST_ANNUL( ZOOMMAP, STATUS ) - IF ( STATUS .NE. 0 ) THEN - - END IF -\end{terminalv} -\normalsize -f- - -c+ -astAnnul will execute normally in order to recover the resources -associated with the ZoomMap that was created earlier, regardless of -whether an error has occurred in any of the intermediate functions. -Functions which behave in this way are noted in the relevant -descriptions in \appref{ss:functiondescriptions}. -c- -f+ -AST\_ANNUL will execute normally in order to recover the resources -associated with the ZoomMap that was created earlier, regardless of -whether an error has occurred in any of the intermediate routines. -Routines which behave in this way are noted in the relevant -descriptions in \appref{ss:functiondescriptions}. -f- - -c+ -If a serious error occurs, you will probably want to abort your -program, but sometimes you may want to recover and carry on. Because -very few AST functions will execute once the AST error status has been -set, you must first clear this status by using the astClearStatus -macro, as follows: -c- -f+ -If a serious error occurs, you will probably want to abort your -program, but sometimes you may want to recover and carry on. This is -simply done by resetting your error status variable to zero, whereupon -the AST routines you pass it to will execute normally again. -f- - -c+ -\small -\begin{terminalv} -astClearStatus; -\end{terminalv} -\normalsize -c- - -c+ -This will restore the AST error status to its OK value, so that AST -functions execute normally again. -c- - -c+ -Occasionally, you may also need to set the AST error status to an -explicit error value (see \secref{ss:channelsink} for an -example). This is done using astSetStatus and can be used to -communicate to AST that an error has occurred in some other item of -software, for example: -c- - -c+ -\small -\begin{terminalv} -int new_status; - -... - -astSetStatus( new_status ); -\end{terminalv} -\normalsize -c- - -c+ -The effect is that most AST routines will subsequently return without -action, just as if an error had occurred within the AST library -itself. -c- - -c+ -\subsection{Sharing the Error Status} - -In some software, it is usual to maintain a single integer error -status variable which is accessed by each function as it executes. If -an error occurs, this status variable is set and other functions can -detect this and take appropriate action. - -If you use AST in such a situation, it can be awkward to have a -separate internal error status used by AST functions alone. To remedy -this, AST is capable of sharing the error status variable used by any -other software, so long as they use the same conventions -(\emph{i.e.}\ a C int with the same ``OK'' value). To enable this -facility, you should pass the address of your status variable to -astWatch, as follows: - -\small -\begin{terminalv} -int my_status; -int *old_address; - -... - -old_address = astWatch( &my_status ); -\end{terminalv} -\normalsize - -Henceforth, instead of using its own internal error status variable, -AST will use the one you supply, so that it can detect errors flagged -by other parts of your software. The address of the original error -status variable is returned by astWatch, so you can restore the -original behaviour later if necessary. - -Note that this facility is not available \emph{via} the Fortran -interface to the AST library. -c- - -\cleardoublepage -\section{\label{ss:mappings}Inter-Relating Coordinate Systems (Mappings)} - -In \secref{ss:primer} we used the ZoomMap as an example of a -Mapping. We saw how it could be used to transform coordinates from its -input to its output and back again (\secref{ss:transforming}). We also -saw how its behaviour could be controlled by setting various -attributes, such as the Zoom factor and the Report attribute that made -it display coordinate values as it transformed them. - -In this section, we will look at Mappings a bit more thoroughly and -explore the behaviour which is common to all the Mappings provided by -AST. This is good background for what follows, because many of the -Objects we discuss later will also turn out to be Mappings in various -disguises. - -\subsection{\label{ss:mappingclass}The Mapping Class} - -Before we start, it is worth taking a quick look at the Mapping class -as a whole and some of the sub-classes it contains: - -\begin{terminalv} - Mapping - CmpMap - DssMap - GrismMap - IntraMap - LutMap - MathMap - MatrixMap - PermMap - PolyMap - ChebyMap - SlaMap - SpecMap - TimeMap - UnitMap - WcsMap - ZoomMap - - Frame - -\end{terminalv} - -The Frame sub-class has been separated out here because it is covered -in detail in \secref{ss:frames}. We start by looking at the parent -class, Mapping. - -c+ -AST does not provide a function to create a basic Mapping -(\emph{i.e.}\ the astMapping constructor does not exist). This is -because the Mapping class itself is ``virtual'' and basic Mappings are -of no use in themselves. The Mapping class serves simply to contain -the various specialised Mappings that exist. -c- -f+ -AST does not provide a function to create a basic Mapping -(\emph{i.e.}\ the AST\_MAPPING constructor does not exist). This is -because the Mapping class itself is ``virtual'' and basic Mappings are -of no use in themselves. The Mapping class serves simply to contain -the various specialised Mappings that exist. -f- -However, it provides more than just a convenient heading for them -because it bestows all classes of Mapping with common properties -(\emph{e.g.}\ attributes) and behaviour. By examining the Mapping -class, we are therefore examining the things that all other Mappings -have in common. - -\subsection{The Mapping Model} - -The concept of a Mapping was illustrated in Figure~\ref{fig:mapping}. -It is a black box which you can supply with a set of coordinate values -in return for a set of transformed coordinates. The two sets are -termed \emph{input} and \emph{output} coordinates. You can also go -back the other way and transform output coordinates back into input -coordinates, as we saw in \secref{ss:transforming}. - -\subsection{Changing Attributes of a Mapping} - -Many classes of Mapping have attributes that provide values for parameter -used within the transformation. For instance, the ZoomMap class has an -attribute called ``Zoom'' that gives the scalar value by which each -coordinate is to be multiplied. These attribute values should be set when -the Mapping is created and should not be changed afterwards. Indeed, the -AST library will report an error if an attempt is made to change the -value of a Mapping attribute. This is because, once created, Mappings are -often later included within other objects such as FrameSets and CmpMaps. -This means that in general there could be many active references to a single -Mapping object within a program. Changing an attribute of the Mapping -via one particular reference (i.e pointer) would cause all the other -references to change too, with often undesirable or unpredictable -consequences. To avoid this, Mappings are considered \emph{immutable} in -most situations. The one exception is if the Mapping has not yet been -cloned or included in another Object (\emph{i.e.} it has a reference -couint of one) - changing the attributes of such a Mapping is allowed, -and will not generate an error. - -Note, the Invert attribute of a Mapping is not subject to this rule and -can be changed at any time. - -\subsection{Input and Output Coordinate Numbers} - -In general, the number of coordinates you feed into a Mapping to -represent a single point need not be the same as the number that comes -out. Often these numbers will be the same, and often they will both -equal 2 (because 2-dimensional coordinate systems are common), but -this needn't necessarily be the case. - -The number of coordinates required to specify an input point is -represented by the integer attribute Nin and the number required to -specify an output point is represented by Nout. These are read-only -attributes common to all Mappings. Generally, their values are fixed -when a Mapping is created. - -c+ -In \secref{ss:objectcreation}, we saw how the Nin attribute for a -ZoomMap was initialised by the call to the constructor function -astZoomMap which created it. In this case, the Nout attribute was not -needed and it implicitly took the same value as Nin, but we could -have enquired about its value had we wanted, as follows: -c- -f+ -In \secref{ss:objectcreation}, we saw how the Nin attribute for a -ZoomMap was initialised by the call to the constructor function -AST\_ZOOMMAP which created it. In this case, the Nout attribute was -not needed and it implicitly took the same value as Nout, but we could -have enquired about its value had we wanted, as follows: -f- - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstZoomMap *zoommap; -int nout; - -... - -nout = astGetI( zoommap, "Nout" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER NOUT, STATUS, ZOOMMAP - - STATUS = 0 - - ... - - NOUT = AST_GETI( ZOOMMAP, 'Nout', STATUS ) -\end{terminalv} -\normalsize -f- - -\subsection{Forward and Inverse Transformations} - -We stated earlier that a Mapping may be used to transform coordinates -either from input to output, or \emph{vice versa}. These are termed -its \emph{forward} and \emph{inverse} transformations. - -This statement was not quite accurate, however, because in general -Mappings are only \textbf{potentially} capable of working in both -directions. In practice, coordinate transformation may only be -feasible in one direction or the other because some functions are not -easily inverted (they may be multi-valued, for instance). Allowance -must be made for this, so each Mapping has two read-only boolean -(integer) attributes, TranForward and TranInverse, which indicate -whether each transformation is available. - -A transformation is available if the corresponding attribute is -non-zero, otherwise it is not.\footnote{Most of the Mappings provided -by the AST library work in both directions, although the LutMap can -behave otherwise.} If you enquire about the value of these attributes, -a value of 0 or 1 is returned. Attempting to use a Mapping to apply a -transformation which is not available will result in an error. - -\subsection{\label{ss:invertingmappings}Inverting Mappings} - -An important attribute, common to all Mappings, is the Invert -flag. This is a boolean (integer) attribute that can be assigned a new -value at any time. If it is non-zero, it has the effect of -interchanging the Mapping's input and output coordinates and the -Mapping is then said to be \emph{inverted}. By default, the Invert -attribute is zero. - -There is no magic in this. There is no fancy arithmetic involved in -inverting mathematical functions, for instance. The Invert flag is -simply a switch that interchanges a Mapping's input and output -ports. If it is non-zero, the Mapping's Nin and Nout attributes are -swapped, its TranForward and TranInverse attributes are swapped, and -when you ask for what was once the forward transformation you get the -inverse transformation instead (and \emph{vice versa}). When you -return the Invert attribute to zero, or clear it, the Mapping returns -to its original behaviour. - -c+ -Often, the actual value of the Invert attribute is unimportant and you -simply wish to invert its boolean sense, so that what was the -Mapping's input becomes its output and \emph{vice versa}. This is most -easily accomplished using astInvert, as follows: -c- -f+ -Often, the actual value of the Invert attribute is unimportant and you -simply wish to invert its boolean sense, so that what was the -Mapping's input becomes its output and \emph{vice versa}. This is most -easily accomplished using AST\_INVERT, as follows: -f- - -c+ -\small -\begin{terminalv} -AstMapping *mapping; - -... - -astInvert( mapping ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER MAPPING - - ... - - CALL AST_INVERT( MAPPING, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -If the Mapping you have happens to be the wrong way around, astInvert -allows you to correct the problem. -c- -f+ -If the Mapping you have happens to be the wrong way around, -AST\_INVERT allows you to correct the problem. -f- - -\subsection{Finding the Rate of Change of a Mapping Output} -The -c+ -astRate -c- -f+ -AST\_RATE -f- -function can be used to find the rate of change of any Mapping output -with respect to any Mapping input, at a given input position. The method -used produces good accuracy (typically a relative error of 10E-10 or -less) but may require the Mapping to be evaluated 100 or more times. -An estimate of the second derivative is also produced by this function. - - -\subsection{Reporting Coordinate Transformations} - -We have already seen (\secref{ss:transforming}) how the boolean -(integer) Report attribute of a Mapping works. If it is non-zero, the -operation of transforming a set of coordinates will result in a report -being written to standard output. This will display the coordinate -values before and after transformation. It can save considerable time -during program development by eliminating the need to add loops and -output statements to your program. - -c+ -In a finished program, however, you should be careful that the Report -attribute is not set to a non-zero value unless you want to see the -output (there may often be rather a lot of this!). To help prevent -unwanted output being produced by accident, the Report attribute is -unusual in that its value is not preserved when a Mapping is copied -using astCopy (\secref{ss:copyingobjects}). Instead, it reverts to its -default of zero (\emph{i.e.}\ un-set) in the copy. It also reverts to -zero when a Mapping is written out, \emph{e.g.}\ to a file using a -Channel (\secref{ss:channels}). -c- -f+ -In a finished program, however, you should be careful that the Report -attribute is not set to a non-zero value unless you want to see the -output (there may often be rather a lot of this!). To help prevent -unwanted output being produced by accident, the Report attribute is -unusual in that its value is not preserved when a Mapping is copied -using AST\_COPY (\secref{ss:copyingobjects}). Instead, it reverts to -its default of zero (\emph{i.e.}\ un-set) in the copy. It also reverts -to zero when a Mapping is written out, \emph{e.g.}\ to a file using a -Channel (\secref{ss:channels}). -f- - -%\subsection{TBW---More on Transforming Coordinates} - -\subsection{\label{ss:badcoordinates}Handling Missing (Bad) Coordinate Values} - -c+ -Even when coordinates can, in principle, be transformed in either -direction by a Mapping, there may still be instances where specific -coordinate values cannot be handled. For example, the Mapping may be -mathematically intractable (\emph{e.g.}\ singular) in certain places, -or it may map a subset of one space on to another, so that some points -in one space are not represented in the other. Sky projections often -show this behaviour, since it is quite common to project only half of -the celestial sphere on to two dimensions, omitting points on the -opposite side of the sky. There are many other examples. -c- -f+ -Even when coordinates can, in principle, be transformed in either -direction by a Mapping, there may still be instances where specific -coordinate values cannot be handled. For example, the Mapping may be -mathematically intractable (\emph{e.g.}\ singular) in certain places, -or it may map a subset of one space on to another, so that some points -in one space are not represented in the other. Sky projections often -show this behaviour, since it is quite common to project only half of -the celestial sphere on to two dimensions, omitting points on the -opposite side of the sky. There are many other examples. -f- - -c+ -To indicate when coordinates cannot be transformed, for whatever -reason, AST substitutes a special output coordinate value given by the -macro AST\_\_BAD (as defined in the ``ast.h'' header file). Before -making use of coordinates generated by any of the AST transformation -functions, therefore, you may need to check for the presence of this -value. -c- -f+ -To indicate when coordinates cannot be transformed, for whatever -reason, AST substitutes a special output coordinate value given by the -parameter constant AST\_\_BAD (as defined in the AST\_PAR include -file). Before making use of coordinates generated by any of the AST -transformation routines, therefore, you may need to check for the -presence of this value. -f- - -c+ -Because coordinates with the value AST\_\_BAD can be generated in this -way, all other AST functions are also capable of recognising this -value and handling it appropriately. The coordinate transformation -functions do this by propagating any missing input coordinate -information through to their output. This means that if you supply -coordinates with the value AST\_\_BAD, the returned coordinates are -also likely to contain this value. Here, for example, is what happens -if you use a ZoomMap (with Zoom factor 5) to transform such a set of -coordinates: -c- -f+ -Because coordinates with the value AST\_\_BAD can be generated in this -way, all other AST routines are also capable of recognising this value -and handling it appropriately. The coordinate transformation routines -do this by propagating any missing input coordinate information -through to their output. This means that if you supply coordinates -with the value AST\_\_BAD, the returned coordinates are also likely to -contain this value. Here, for example, is what happens if you use a -ZoomMap (with Zoom factor 5) to transform such a set of coordinates: -f- - -\small -\begin{terminalv} -(0, 0) --> (0, 0) -(, 2) --> (, 10) -(2, 4) --> (10, 20) -(3, 6) --> (15, 30) -(4, ) --> (20, ) -(5, 10) --> (25, 50) -(, ) --> (, ) -(7, 14) --> (35, 70) -(8, 16) --> (40, 80) -(9, 18) --> (45, 90) -\end{terminalv} -\normalsize - -The AST\_\_BAD value is represented by the string ``$<$bad$>$''. This -is a case of ``garbage in, garbage out'' but at least it's consistent -garbage that you can recognise! - -Note how the presence of the AST\_\_BAD value in one input dimension -does not necessarily result in the loss of information for all output -dimensions. Sometimes, such loss will be unavoidable, but in general -an attempt is made to preserve information as far as possible. The -exact behaviour will depend on the Mapping involved. - -\subsection{\label{ss:unitmapexample}Example---the UnitMap} - -The UnitMap is the simplest of Mappings. It is a null Mapping. Its -purpose is simply to copy coordinate values, unaltered, from its input -to its output and \emph{vice versa}. - -A UnitMap has no additional attributes beyond those of a basic -Mapping. Its Nin and Nout attributes are always equal and are -specified by the first argument supplied to its constructor. For -example: - -c+ -\small -\begin{terminalv} -AstUnitMap *unitmap; - -... - -unitmap = astUnitMap( 2, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER UNITMAP - - ... - - UNITMAP = AST_UNITMAP( 2, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -will create a UnitMap that copies 2-dimensional coordinates. Inverting -a UnitMap has no effect beyond changing the value of its Invert -attribute. - -c+ -The main use of a UnitMap is to allow a Mapping to be supplied when one -is required (as an argument to a function, for example) but you wish -it to leave coordinate values unchanged. -c- -f+ -The main use of a UnitMap is to allow a Mapping to be supplied when one -is required (as an argument to a routine, for example) but you wish -it to leave coordinate values unchanged. -f- - -\subsection{\label{ss:permmapexample}Example---the PermMap} - -The PermMap is a rather more complicated Mapping than we have met -previously. Its purpose is to change the order, or number, of -coordinates. It is also able to substitute fixed values for -coordinates. - -To illustrate its action, suppose our input coordinates are denoted by -($x_1,x_2,x_3,x_4$) in a 4-dimensional space and suppose our output -coordinates are to be ($x_4,x_1,x_2,x_3$). Our PermMap, therefore, -should rotate the coordinate values by one position. - -c+ -To create such a PermMap, we first set up two integer arrays. One of -these, ``outperm'', controls the selection of input coordinates for -use in the output and the other, ``inperm'', controls selection of -output coordinates for use in the input: -c- -f+ -To create such a PermMap, we first set up two integer arrays. One of -these, OUTPERM, controls the selection of input coordinates for use in -the output and the other, INPERM, controls selection of output -coordinates for use in the input: -f- - -c+ -\small -\begin{terminalv} -int outperm[ 4 ] = { 4, 1, 2, 3 }; -int inperm[ 4 ] = { 2, 3, 4, 1 }; -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER OUTPERM( 4 ), INPERM( 4 ) - DATA OUTPERM / 4, 1, 2, 3 / - DATA INPERM / 2, 3, 4, 1 / -\end{terminalv} -\normalsize -f- - -Note that the numbers we store in these arrays are the indices of the -coordinates that we want to select. We have chosen these so that the -forward and inverse transformations will perform complementary -permutations on the coordinates. - -The PermMap is then created by passing these arrays to its -constructor, as follows: - -c+ -\small -\begin{terminalv} -AstPermMap *permmap; - -... - -permmap = astPermMap( 4, inperm, 4, outperm, NULL, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER PERMMAP - DOUBLE PRECISION DUMMY( 1 ) - - ... - - PERMMAP = AST_PERMMAP( 4, INPERM, 4, OUTPERM, DUMMY, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -f+ -(the fifth argument is not being used, so a dummy array has been supplied). -f- -Note that we specify the number of input and output coordinates -separately, but set both to 4 in this example. The resulting PermMap -would have the following effect when used to transform coordinates: - -\begin{terminalv} -Forward: - (1, 2, 3, 4) --> (4, 1, 2, 3) - (2, 4, 6, 8) --> (8, 2, 4, 6) - (3, 6, 9, 12) --> (12, 3, 6, 9) - (4, 8, 12, 16) --> (16, 4, 8, 12) - (5, 10, 15, 20) --> (20, 5, 10, 15) - -Inverse: - (4, 1, 2, 3) --> (1, 2, 3, 4) - (8, 2, 4, 6) --> (2, 4, 6, 8) - (12, 3, 6, 9) --> (3, 6, 9, 12) - (16, 4, 8, 12) --> (4, 8, 12, 16) - (20, 5, 10, 15) --> (5, 10, 15, 20) -\end{terminalv} - -c+ -If the number of input and output coordinates are unequal so, also, -will be the size of the ``outperm'' and ``inperm'' arrays. This means, -however, that we cannot fill them with coordinate indices so that they -perform complementary permutations, because one transformation will -lose information (discard a coordinate) that the other cannot recover. -To give an example, consider the following: -c- -f+ -If the number of input and output coordinates are unequal so, also, -will be the size of the OUTPERM and INPERM arrays. This means, -however, that we cannot fill them with coordinate indices so that they -perform complementary permutations, because one transformation will -lose information (discard a coordinate) that the other cannot recover. -To give an example, consider the following: -f- - -c+ -\small -\begin{terminalv} -int outperm[ 3 ] = { 4, 3, 2 }; -int inperm[ 4 ] = { -1, 3, 2, 1 }; -double con[ 1 ] = { 99.004 }; -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER OUTPERM( 3 ), INPERM( 4 ) - DOUBLE PRECISION CONST( 1 ) - DATA OUTPERM / 4, 3, 2 / - DATA INPERM / -1, 3, 2, 1 / - DATA CONST / 99.004D0 / -\end{terminalv} -\normalsize -f- - -c+ -In this case, the forward transformation will change -($x_1,x_2,x_3,x_4$) into ($x_4,x_3,x_2$) and will discard $x_1$. The -inverse transformation restores the original coordinate order, but has -no value to assign to the first coordinate. In this case, the number -entered in the ``inperm'' array is $-$1. -c- -f+ -In this case, the forward transformation will change -($x_1,x_2,x_3,x_4$) into ($x_4,x_3,x_2$) and will discard $x_1$. The -inverse transformation restores the original coordinate order, but has -no value to assign to the first coordinate. In this case, the number -entered in the INPERM array is $-$1. -f- - -c+ -This negative value indicates that the coordinate value should be -obtained by addressing the first element of the ``con'' array -(\emph{i.e.}\ element zero). This array, ignored in the previous -example, may then be used to supply a value for the missing -coordinate. -c- -f+ -This negative value indicates that the coordinate value should be -obtained by addressing the CONST array using an index of 1 (the -absolute value). This array, ignored in the previous example, may then -be used to supply a value for the missing coordinate. -f- - -The constructor function: - -c+ -\small -\begin{terminalv} -permmap = astPermMap( 4, inperm, 3, outperm, con, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - PERMMAP = AST_PERMMAP( 4, INPERM, 3, OUTPERM, CONST, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -will then create a PermMap with the following effect when used to -transform coordinates: - -\begin{terminalv} -Forward: - (1, 2, 3, 4) --> (4, 3, 2) - (2, 4, 6, 8) --> (8, 6, 4) - (3, 6, 9, 12) --> (12, 9, 6) - (4, 8, 12, 16) --> (16, 12, 8) - (5, 10, 15, 20) --> (20, 15, 10) - -Inverse: - (4, 3, 2) --> (99.004, 2, 3, 4) - (8, 6, 4) --> (99.004, 4, 6, 8) - (12, 9, 6) --> (99.004, 6, 9, 12) - (16, 12, 8) --> (99.004, 8, 12, 16) - (20, 15, 10) --> (99.004, 10, 15, 20) -\end{terminalv} - -c+ -The ``con'' array may contain more than one value if necessary and may -be addressed by both the ``inperm'' and ``outperm'' arrays using -coordinate indices $-$1, $-$2, $-$3,~\emph{etc.}\ to refer to the -first, second, third,~\emph{etc.}\ elements. -c- -f+ -The CONST array may contain more than one value if necessary and may -be addressed by both the INPERM and OUTPERM arrays using coordinate -indices $-$1, $-$2, $-$3,~\emph{etc.}\ to refer to the first, second, -third,~\emph{etc.}\ elements. -f- - -c+ -If there is no suitable replacement value that can be supplied -\emph{via} the ``con'' array, a value of zero may be entered into the -``outperm'' and/or ``inperm'' arrays. This causes the value AST\_\_BAD -to be used for the affected coordinate (as defined in the ``ast.h'' -header file), thus indicating a missing coordinate value -(\secref{ss:badcoordinates}). -c- -f+ -If there is no suitable replacement value that can be supplied -\emph{via} the CONST array, a value of zero may be entered into the -OUTPERM and/or INPERM arrays. This causes the value AST\_\_BAD to be -used for the affected coordinate (as defined in the AST\_PAR include -file), thus indicating a missing coordinate value -(\secref{ss:badcoordinates}). -f- - -The principle use for a PermMap lies in matching a coordinate system -to a data array where there is a choice of storage order for the data. -PermMaps are also useful for discarding unwanted coordinates so as to -reduce the number of dimensions, such as when selecting a ``slice'' -from a multi-dimensional array. - -\cleardoublepage -\section{\label{ss:cmpmaps}Compound Mappings (CmpMaps)} - -We now turn to a rather special form of Mapping, the CmpMap. The -Mappings we have considered so far have been atomic, in the sense that -they perform pre-defined elementary transformations. A CmpMap, -however, is a compound Mapping. In essence, it is a framework for -containing other Mappings and its purpose is to allow those Mappings -to work together in various combinations while appearing as a single -Object. A CmpMap's behaviour is therefore not pre-defined, but is -determined by the other Mappings it contains. - -\subsection{\label{ss:seriescmpmap}Combining Mappings in Series} - -Consider a simple example based on two 2-dimensional coordinate -systems. Suppose that to convert from one to the other we must swap -the coordinate order and multiply both coordinates by 5, so that the -coordinates ($x_1,x_2$) transform into ($5x_2,5x_1$). This can be done -in two stages: - -\begin{enumerate} -\item Apply a PermMap (\secref{ss:permmapexample}) to swap the -coordinate order. - -\item Apply a ZoomMap (\secref{ss:transforming}) to multiply both -coordinate values by the constant 5. -\end{enumerate} - -The PermMap and ZoomMap are then said to operate \emph{in series}, -because they are applied sequentially -(\emph{c.f.}\ Figure~\ref{fig:seriescmpmap}). We can create a CmpMap -that applies these Mappings in series as follows: - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstCmpMap *cmpmap; -AstPermMap *permmap; -AstZoomMap *zoommap; - -... - -/* Create the individual Mappings. */ -{ - int inperm[ 2 ] = { 2, 1 }; - int outperm[ 2 ] = { 2, 1 }; - permmap = astPermMap( 2, inperm, 2, outperm, NULL, "" ); -} -zoommap = astZoomMap( 2, 5.0, "" ) - -/* Combine them in series. */ -cmpmap = astCmpMap( permmap, zoommap, 1, "" ); - -/* Annul the individual Mapping pointers. */ -permmap = astAnnul( permmap ); -zoommap = astAnnul( zoommap ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER CMPMAP, PERMMAP, STATUS, ZOOMMAP - INTEGER INPERM( 2 ), OUTPERM( 2 ), CONST( 1 ) - DATA INPERM / 1, 2 / - DATA OUTPERM / 1, 2 / - - STATUS = 0 - - ... - -* Create the individual Mappings. - PERMMAP = AST_PERMMAP( 2, INPERM, 2, OUTPERM, CONST, ' ', STATUS ) - ZOOMMAP = AST_ZOOMMAP( 2, 5.0D0, ' ', STATUS ) - -* Combine them in series. - CMPMAP = AST_CMPMAP( PERMMAP, ZOOMMAP, .TRUE., ' ', STATUS ) - -* Annul the individual Mapping pointers. - CALL AST_ANNUL( PERMMAP, STATUS ) - CALL AST_ANNUL( ZOOMMAP, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, the third argument (1) of the constructor function astCmpMap -indicates ``in series''. -c- -f+ -Here, the third argument (.TRUE.) of the constructor function -AST\_CMPMAP indicates ``in series''. -f- - -When used to transform coordinates in the forward direction, the -resulting CmpMap will apply the first component Mapping (the PermMap) -and then the second one (the ZoomMap). When transforming in the -inverse direction, it will apply the second one (in the inverse -direction) and then the first one (also in the inverse direction). In -general, although not in this particular example, the order in which -the two component Mappings are supplied is significant. Clearly, also, -the Nout attribute (number of output coordinates) for the first -Mapping must equal the Nin attribute (number of input coordinates) for -the second one. - -\subsection{Combining Mappings in Parallel} - -Connecting two Mappings in series (\secref{ss:seriescmpmap}) is not the -only way of combining them. The alternative, \emph{in parallel}, -involves applying the two Mappings at once but on different subsets of -the coordinate values. - -Consider, for example, a set of 3-dimensional coordinates and suppose -we wish to transform them by swapping the first two coordinate values -and multiplying the final one by 5, so that ($x_1,x_2,x_3$) transforms -into ($x_2,x_1,5x_3$). Again, we can perform each of these steps -individually using Mappings similar to the PermMap and ZoomMap used -earlier (\secref{ss:seriescmpmap}). In this case, however, the ZoomMap is -1-dimensional and the individual Mappings are applied in parallel -(\emph{c.f.}\ Figure~\ref{fig:parallelcmpmap}). - -Creating a CmpMap for this purpose is also very simple: - -c+ -\small -\begin{terminalv} -cmpmap = astCmpMap( permmap, zoommap, 0, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CMPMAP = AST_CMPMAP( PERMMAP, ZOOMMAP, .FALSE., ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -The only difference is that the third argument of astCmpMap is now -zero, meaning ``in parallel''. -c- -f+ -The only difference is that the third argument of AST\_CMPMAP is now -.FALSE., meaning ``in parallel''. -f- - -As before, the order in which the two component Mappings are supplied -is significant. The first one acts on the lower-numbered input -coordinate values (however many it needs) and produces the -lower-numbered output coordinates, while the second Mapping acts on -the higher-numbered input coordinates (however many remain) and -generates the remaining higher-numbered output coordinates. When the -CmpMap transforms coordinates in the inverse direction, both component -Mappings are applied to the same coordinates, but in the inverse -direction. - -Note that the Nin and Nout attributes of the component Mappings -(\emph{i.e.}\ the numbers of input and output coordinates) will sum to -give the Nin and Nout attributes of the overall CmpMap. - -\subsection{\label{ss:cmpmapcomponents}The Component Mappings} - -c+ -A CmpMap does not store copies of its component Mappings, but simply -holds pointers to them. In the example above -(\secref{ss:seriescmpmap}), we were free to annul the individual -Mapping pointers after creating the CmpMap because the pointers held -internally by the CmpMap increased the reference count (RefCount -attribute) of each component Mapping by one. The individual components -are therefore not deleted by astAnnul, but retained until the CmpMap -itself is deleted and annuls the pointers it holds. Consistent use of -astAnnul (\secref{ss:annullingpointers}) and/or pointer contexts -(\secref{ss:contexts}) will therefore ensure that all Objects are -deleted at the appropriate time. -c- -f+ -A CmpMap does not store copies of its component Mappings, but simply -holds pointers to them. In th example above (\secref{ss:seriescmpmap}), -we were free to annul the individual Mapping pointers after creating -the CmpMap because the pointers held internally by the CmpMap -increased the reference count (RefCount attribute) of each component -Mapping by one. The individual components are therefore not deleted by -AST\_ANNUL, but retained until the CmpMap itself is deleted and annuls -the pointers it holds. Consistent use of AST\_ANNUL -(\secref{ss:annullingpointers}) and/or pointer contexts -(\secref{ss:contexts}) will therefore ensure that all Objects are -deleted at the appropriate time. -f- - -Note that access to a CmpMap's component Mappings is not generally -available unless pointers to them are retained when the CmpMap is -created. If such pointers are retained, then subsequent modifications -to the individual components can be used to indirectly modify the -behaviour of the overall CmpMap. - -There is an important exception to this, however, because a CmpMap -retains a copy of the initial Invert flag settings of each of its -components and uses these in order to ignore any subsequent external -changes. This means that you may invert either component Mapping -before inserting it into a CmpMap and need not worry if you un-invert -it again later. The CmpMap's behaviour will not be affected by the -later action. - -\subsection{\label{ss:complexcmpmap}Creating More Complex Mappings} - -c+ -Because a CmpMap is itself a Mapping, any existing CmpMap can -substitute (\secref{ss:objecthierarchy}) as a component Mapping when -constructing a new CmpMap using astCmpMap. This has the effect of -nesting one CmpMap inside another and opens up many new possibilities. -For example, combining three Mappings in series can be accomplished as -follows: -c- -f+ -Because a CmpMap is itself a Mapping, any existing CmpMap can -substitute (\secref{ss:objecthierarchy}) as a component Mapping when -constructing a new CmpMap using AST\_CMPMAP. This has the effect of -nesting one CmpMap inside another and opens up many new possibilities. -For example, combining three Mappings in series can be accomplished as -follows: -f- - -c+ -\small -\begin{terminalv} -AstMapping *map1, *map2, *map3; - -... - -cmpmap = astCmpMap( map1, astCmpMap( map2, map3, 1, "" ), 1, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER MAP1, MAP2, MAP3 - - ... - - CMPMAP = AST_CMPMAP( MAP1, AST_CMPMAP( MAP2, MAP3, .TRUE., ' ', STATUS ), - : .TRUE., ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -The way in which the individual component Mappings are grouped within -the nested CmpMaps is not usually important. - -A similar technique can be used to combine multiple Mappings in -parallel and, of course, mixed series and parallel combinations are -also possible (Figure~\ref{fig:complexcmpmap}). There is no built-in -limit to how many CmpMaps may be nested in this way, so this mechanism -provides an indefinitely extensible method of building complex -Mappings out of the elemental building blocks provided by AST. - -In practice, you might not need to construct such complex CmpMaps -yourself very frequently, but they will often be returned by AST -routines. Nested CmpMaps underlie the library's entire ability to -represent a wide range of different coordinate transformations. - -\subsection{\label{ss:cmpmapexample}Example---Transforming Between Two Calibrated Images} - -Consider, as a practical example of CmpMaps, two images of the -sky. Suppose that for each image we have a Mapping which converts from -pixel coordinates to a standard celestial coordinate system, say -FK5~(J2000.0). If we wish to inter-compare these images, we can do so -by using this celestial coordinate system to align them. That is, we -first convert from pixel coordinates in the first image into FK5 -coordinates and we then convert from FK5 coordinates into pixel -coordinates in the second image. - -c+ -If ``mapa'' and ``mapb'' are pointers to our two original Mappings, we -could form a CmpMap which transforms directly between the pixel -coordinates of the first and second images by combining these -Mappings, as follows: -c- -f+ -If MAPA and MAPB are pointers to our two original Mappings, we could -form a CmpMap which transforms directly between the pixel coordinates -of the first and second images by combining these Mappings, as -follows: -f- - -c+ -\small -\begin{terminalv} -AstCmpMap *alignmap; -AstMapping *mapa, *mapb; - -... - -astInvert( mapb ); -alignmap = astCmpMap( mapa, mapb, 1, "" ); -astInvert( mapb ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER ALIGNMAP, MAPA, MAPB - - ... - - CALL AST_INVERT( MAPB, STATUS ) - ALIGNMAP = AST_CMPMAP( MAPA, MAPB, .TRUE., ' ', STATUS ) - CALL AST_INVERT( MAPB, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, we have used astInvert (\secref{ss:invertingmappings}) to invert -``mapb'' before inserting it into the CmpMap because, as supplied, it -converted in the wrong direction. Afterwards, we invert it again to -return it to its original state. The CmpMap, however, will ignore this -subsequent change (\secref{ss:cmpmapcomponents}). -c- -f+ -Here, we have used AST\_INVERT (\secref{ss:invertingmappings}) to -invert MAPB before inserting it into the CmpMap because, as supplied, -it converted in the wrong direction. Afterwards, we invert it again to -return it to its original state. The CmpMap, however, will ignore this -subsequent change (\secref{ss:cmpmapcomponents}). -f- - -The forward transformation of the resulting CmpMap will now transform -from pixel coordinates in the first image to pixel coordinates in the -second image, while its inverse transformation will convert in the -opposite direction. - -\subsection{\label{ss:overcomplexcmpmaps}Over-Complex Compound Mappings} - -While a CmpMap provides a very flexible way of constructing -arbitrarily complex Mappings (\secref{ss:complexcmpmap}), it -unfortunately also provides an opportunity for representing simple -Mappings in complex ways. Sometimes, unnecessary complexity can be -difficult to avoid but can obscure important simplifications. - -Consider the example above (\secref{ss:cmpmapexample}), in which we -inter-related two images of the sky \emph{via} a CmpMap. If the two -images turned out to be simply offset from each other by a shift along -each pixel axis, then this approach would align them correctly, but it -would be inefficient. This is because it would introduce unnecessary -and expensive transformations to and from an intermediate celestial -coordinate system, whereas a simple shift of pixel origin would -suffice. - -Recognising that a simpler and more efficient solution exists -obviously requires a little more than simply joining two Mappings -end-to-end. We must also determine whether the resulting CmpMap is -more complex than it needs to be, \emph{i.e.}\ contains redundant -information. If it is, we then need a way to simplify it. - -The problem is not always just one of efficiency, however. Sometimes -we may also need to know something about the actual form a Mapping -takes---\emph{i.e.}\ the nature of the operations it performs. -Unnecessary complexity can obscure this, but such complexity can -easily accumulate during normal data processing. - -For example, a Mapping that transforms pixel coordinates into -positions on the sky might be repeatedly modified as changes are made -to the shape and size of the image. Typically, on each occasion, -another Mapping will be concatenated to reflect what has happened to -the image. This could soon make it difficult to discern the overall -nature of the transformation from the complex CmpMap that -accumulates. If only shifts of origin were involved on each occasion, -however, they could be combined into a single shift which could be -represented much more simply. - -Suppose we now wanted to represent our image's celestial coordinate -calibration using FITS conventions (\secref{ss:foreignfits}). This -requires AST to determine whether the Mapping which relates pixel -coordinate to sky positions conforms to the FITS model (for example, -whether it is equivalent to applying a single set of shifts and scale -factors followed by a map projection). Clearly, there is an important -use here for some means of simplifying the internal structure of a -CmpMap. - -\subsection{\label{ss:simplifyingcmpmaps}Simplifying Compound Mappings} - -c+ -The ability to simplify compound Mappings is provided by the -astSimplify function. This function encapsulates a number of -heuristics for converting Mappings, or combinations of Mappings within -a CmpMap, into simpler, equivalent ones. When applied to a CmpMap, -astSimplify tries to reduce the number of individual Mappings within -it by merging neighbouring component Mappings together. It will do -this with both series and parallel combinations of Mappings, or both, -and will handle CmpMaps nested to any depth -(\secref{ss:complexcmpmap}). -c- -f+ -The ability to simplify compound Mappings is provided by the -AST\_SIMPLIFY function. This function encapsulates a number of -heuristics for converting Mappings, or combinations of Mappings within -a CmpMap, into simpler, equivalent ones. When applied to a CmpMap, -AST\_SIMPLIFY tries to reduce the number of individual Mappings within -it by merging neighbouring component Mappings together. It will do -this with both series and parallel combinations of Mappings, or both, -and will handle CmpMaps nested to any depth -(\secref{ss:complexcmpmap}). -f- - -c+ - To illustrate how astSimplify works, consider the combination of - Mappings shown in Figure~\ref{fig:simplifyexample}. -c- -f+ - To illustrate how AST\_SIMPLIFY works, consider the combination of - Mappings shown in Figure~\ref{fig:simplifyexample}. -f- - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.7\textwidth]{sun211_figures/simpexamp} -c- -f+ - \includegraphics[width=0.7\textwidth]{sun210_figures/simpexamp} -f- - \caption[An over-complex compound Mapping.]{An over-complex compound Mapping, consisting of PermMaps, - ZoomMaps and a UnitMap, which can be simplified to become a single - UnitMap. The enclosing nested CmpMaps have been omitted for clarity.} - \label{fig:simplifyexample} - \end{center} - \end{figure} - -If this were contained in a CmpMap, it could be simplified as follows: - -c+ -\small -\begin{terminalv} -AstMapping *simpler; - -... - -simpler = astSimplify( cmpmap ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER SIMPLER - - ... - - SIMPLER = AST_SIMPLIFY( CMPMAP, STATUS ); -\end{terminalv} -\normalsize -f- - -c+ -In this case, the result would be a simple 3-dimensional UnitMap (the -identity Mapping). To reach this conclusion, astSimplify will have -made a number of deductions, roughly as follows: -c- -f+ -In this case, the result would be a simple 3-dimensional UnitMap (the -identity Mapping). To reach this conclusion, AST\_SIMPLIFY will have -made a number of deductions, roughly as follows: -f- - -\begin{enumerate} -\item The two 2-dimensional ZoomMaps in series are equivalent to a -single ZoomMap with a combined Zoom factor of unity. This, in turn, is -equivalent to a 2-dimensional UnitMap. - -\item This UnitMap in parallel with the other 1-dimensional UnitMap is -equivalent to a single 3-dimensional UnitMap. This UnitMap, sandwiched -between any other pair of Mappings, can then be eliminated. - -\item The remaining two PermMaps in series are equivalent to a single -3-dimensional PermMap. When these are combined, the resulting PermMap -is found to be equivalent to a 3-dimensional UnitMap. -\end{enumerate} - -c+ -This example is a little contrived, but illustrates how astSimplify -can deal with even quite complicated compound Mappings through a -series of incremental simplifications. Where possible, this will -result in either a simpler compound Mapping or, if feasible, an atomic -(non-compound) Mapping, as here. If no simplification is possible, -astSimplify will just return a pointer to the original Mapping. -c- -f+ -This example is a little contrived, but illustrates how AST\_SIMPLIFY -can deal with even quite complicated compound Mappings through a -series of incremental simplifications. Where possible, this will -result in either a simpler compound Mapping or, if feasible, an atomic -(non-compound) Mapping, as here. If no simplification is possible, -AST\_SIMPLIFY will just return a pointer to the original Mapping. -f- - -c+ -Although astSimplify cannot identify every simplification that is -theoretically possible, sufficient rules are included to deal with the -most common and important cases. -c- -f+ -Although AST\_SIMPLIFY cannot identify every simplification that is -theoretically possible, sufficient rules are included to deal with the -most common and important cases. -f- - -\cleardoublepage -\section{\label{ss:frames}Representing Coordinate Systems (Frames)} - -An AST Frame is an Object that is used to represent a coordinate -system. Contrast this with a Mapping (\secref{ss:mappings}), which is -used to describe how to convert between coordinate systems. The two -concepts are complementary and we will see how they work together in -\secref{ss:framesets}. - -In this section we will discuss only basic Frames, which represent -Cartesian coordinate systems. More specialised types of Frame -(\emph{e.g.}\ the SkyFrame, which represents celestial coordinate -systems, and the SpecFrame, which represents spectral coordinate -systems) are covered later (\secref{ss:skyframes} and \secref{ss:specframes}) -and, naturally, inherit the properties and behaviour of the simple Frames -discussed here. - -\subsection{The Frame Model} - -The best way to think about a Frame is like the frame that you would -plot around a graph. In two dimensions, you would have an ``$x$'' and -a ``$y$'' axis, a title on the graph and labels on the axes, together -with an indication of the physical units being plotted. The values -marked along each axis would be formatted in a human-readable way. The -frame around a graph therefore defines a coordinate space within which -you can locate points, draw lines, calculate distances, \emph{etc.} - -An AST Frame works in much the same way, embodying all of these -concepts and a few more. It also allows any number of axes, which -means that a Frame can represent coordinate systems with any number of -dimensions. You specify how many when you create it. - -Remember that the basic Frame we are considering here is completely -general. It knows nothing of celestial coordinates, for example, and -all its axes are equivalent. It can be adapted to describe any general -purpose Cartesian coordinate system by setting its attributes, such as -its Title and axis Labels, \emph{etc.}\ to appropriate values. - -\subsection{\label{ss:creatingframes}Creating a Frame} - -Creating a Frame is straightforward and follows the usual pattern: - -c+ -\small -\begin{terminalv} -#include "ast.h" -astFrame *frame; - -... - -frame = astFrame( 2, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER FRAME, STATUS - - STATUS = 0 - - ... - - FRAME = AST_FRAME( 2, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -The first argument of the astFrame constructor function specifies the -number of axes which the Frame should have. -c- -f+ -The first argument of the AST\_FRAME constructor function specifies -the number of axes which the Frame should have. -f- - -\subsection{\label{ss:frameasmapping}Using a Frame as a Mapping} - -We should briefly point out that the Frame we created above -(\secref{ss:creatingframes}) is also a Mapping -(\secref{ss:mappingclass}) and therefore inherits the properties and -behaviour common to other Mappings. - -c+ -One way to see this is to set the Frame's Report attribute (inherited -from the Mapping class) to a non-zero value and pass the Frame pointer -to a coordinate transformation function, such as astTran2. -c- -f+ -One way to see this is to set the Frame's Report attribute (inherited -from the Mapping class) to a non-zero value and pass the Frame pointer -to a coordinate transformation routine, such as AST\_TRAN2. -f- - -c+ -\small -\begin{terminalv} -double xin[ 5 ] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 }; -double yin[ 5 ] = { 0.0, 2.0, 4.0, 6.0, 8.0, 10.0 }; -double xout[ 5 ]; -double yout[ 5 ]; - -... - -astSet( frame, "Report=1" ); -astTran2( frame, 5, xin, yin, 1, xout, yout ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DOUBLE PRECISION XIN( 5 ), YIN( 5 ), XOUT( 5 ), YOUT( 5 ) - DATA XIN / 0D0, 1D0, 2D0, 3D0, 4D0, 5D0 / - DATA YIN / 0D0, 2D0, 4D0, 6D0, 8D0, 10D0 / - - CALL AST_SET( FRAME, 'Report=1', STATUS ) - CALL AST_TRAN2( FRAME, 5, XIN, YIN, .TRUE., XOUT, YOUT, STATUS ) -\end{terminalv} -\normalsize -f- - -The resulting output might then look like this: - -\begin{terminalv} -(1, 2) --> (1, 2) -(2, 4) --> (2, 4) -(3, 6) --> (3, 6) -(4, 8) --> (4, 8) -(5, 10) --> (5, 10) -\end{terminalv} - -This is not very exciting because a Frame implements an identity -transformation just like a UnitMap -(\secref{ss:unitmapexample}). However, it illustrates that a Frame can -be used as a Mapping and that its Nin and Nout attributes are both -equal to the number of Frame axes. - -When we consider more specialised Frames -(\emph{e.g.}~\secref{ss:framesets}), we will see that using them as -Mappings can be very useful indeed. - -\subsection{\label{ss:frameaxisattributes}Frame Axis Attributes} - -Frames have a number of attributes which can take multiple values, one -for each axis. These separate values are identified by appending the -axis number in parentheses to the attribute name. For example, the -Label(1) attribute is a character string containing the label which -appears on the first axis. - -Axis attributes are accessed in the same way as all other attributes -(\secref{ss:gettingattributes}, \secref{ss:settingattributes} and -\secref{ss:defaultingattributes}). For example, the Label on the second -axis might be obtained as follows: - -c+ -\small -\begin{terminalv} -const char *label; - -... - -label = astGetC( frame, "Label(2)" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 70 ) LABEL - - ... - - LABEL = AST_GETC( FRAME, 'Label(2)', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Other attribute access functions (astSetX, astTest and astClear) may -also be applied to axis attributes in the same way. -c- -f+ -Other attribute access routines (AST\_SETx, AST\_TEST and AST\_CLEAR) -may also be applied to axis attributes in the same way. -f- - -If the axis number is stored in a program variable, then its value -must be formatted to generate a suitable attribute name before using -this to access the attribute itself. For example, the following will -print out the Label value for each axis of a Frame: - -c+ -\small -\begin{terminalv} -#include -char name[ 18 ]; -int iaxis, naxes; - -... - -naxes = astGetI( frame, "Naxes" ); -for ( iaxis = 1; iaxis <= naxes; iaxis++ ) { - (void) sprintf( name, "Label(%d)", iaxis ); - label = astGetC( frame, name ); - (void) printf( "Label %2d: %s\n", iaxis, label ); -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 10 ) AXIS - INTEGER IAXIS - - ... - - DO 1 IAXIS = 1, AST_GETI( FRAME, 'Naxes', STATUS ) - WRITE ( AXIS, '( I10 )' ) IAXIS - LABEL = AST_GETC( FRAME, 'Label(' // AXIS // ')', STATUS ) - WRITE ( *, 199 ) IAXIS, LABEL - 199 FORMAT ( 'Label ', I2, ': ', A ) - 1 CONTINUE -\end{terminalv} -\normalsize -f- - -Note the use of the Naxes attribute to determine the number of Frame -axes. - -The output from this might look like the following: - -\begin{terminalv} -Label 1: Axis 1 -Label 2: Axis 2 -\end{terminalv} - -In this case, the Frame's default axis Labels have been revealed as -rather un-exciting. Normally, you would set much more useful values, -typically when you create the Frame---perhaps something like: - -c+ -\small -\begin{terminalv} -frame = astFrame( 2, "Label(1)=Offset from centre of field," - "Unit(1) =mm," - "Label(2)=Transmission coefficient," - "Unit(2) =%" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - FRAME = AST_FRAME( 2, 'Label(1)=Offset from centre of field,' // - 'Unit(1) =mm,' // - 'Label(2)=Transmission coefficient,' // - 'Unit(2) =%', STATUS ) -\end{terminalv} -\normalsize -f- - -Here, we have also set the (character string) Unit attribute for each -axis to describe the physical units represented on that axis. All the -attribute assignments have been combined into a single string, -separated by commas. - -\subsection{\label{ss:frameattributes}Frame Attributes} - -We will now briefly outline the various attributes associated with a -Frame (this is, of course, in addition to those inherited from the -Mapping class). We will not delve too deeply into the details of each -attribute, for which you should consult the appropriate description in -\appref{ss:attributedescriptions}. Instead, we aim simply to sketch -the range of facilities available: - -\begin{quote} -\begin{description} -\item[Naxes]\mbox{}\\ -A read-only integer giving the number of Frame axes. - -\item[Title]\mbox{}\\ -A string describing the coordinate system which the Frame represents. - -\item[Label(axis)]\mbox{}\\ -A label string for each axis. - -\item[Unit(axis)]\mbox{}\\ -A string describing the physical units on each axis. You can choose -whether to make this attribute ``active'' or ``passive'' (using -c+ -astSetActiveUnit -c- -f+ -AST\_SETACTIVEUNIT -f- -). If active, its value will be taken into account when finding the -Mapping between two Frames (\emph{e.g.} a scaling of 0.001 would be used -to connect two axis with units of ``km'' and ``m''). If passive, its value -is ignored. Its use is described in more detail in \secref{ss:frameunits}. - -\item[Symbol(axis)]\mbox{}\\ -A string containing a ``short form'' symbol (\emph{e.g.}\ like ``X'' -or ``Y'') used to represent the quantity plotted on each axis. - -\item[Digits/Digits(axis)]\mbox{}\\ -The preferred number of digits of precision to be used when formatting -values for display on each axis. - -\item[Format(axis)]\mbox{}\\ -A string containing a \emph{format specifier} which determines exactly -how values should be formatted for display on each axis -(\secref{ss:formattingaxisvalues}). If this attribute is un-set, the -formatting is based on the Digits value, otherwise the Format string -over-rides the Digits value. - -\item[Direction(axis)]\mbox{}\\ -A boolean (integer) value which indicates in which direction each axis -should be plotted. If it is non-zero (the default), the axis should be -plotted in the conventional direction---\emph{i.e.}\ increasing to the -right for the abscissa and increasing upwards for the ordinate. If it -is zero, the axis should be plotted in reverse. This attribute is -provided as a hint only and programs are free to ignore it if they -wish. - -\item[Domain]\mbox{}\\ -A character string which identifies the \emph{physical domain} to -which the Frame's coordinate system applies. The primary purpose of -this attribute is to prevent unwanted conversions from occurring -between coordinate systems which are not related. Its use is described -in more detail in \secref{ss:framedomains}. - -\item[System]\mbox{}\\ -A character string which identifies the specific coordinate system used -to describe positions within the physical domain represented by the Frame. -For a simple Frame, this attribute currently has a fixed value of -``Cartesian'', but could in principle be extended to include options such -as ``Polar'', ``Cylindrical'', \emph{etc}. More specialised Frames such -as the SkyFrame, TimeFrame and SpecFrame, re-define the allowed values to be -appropriate to the domain which they describe. For instance, the SkyFrame -allows values such as ``FK4'' and ``Galactic'', and the SpecFrame allows -values such as ``frequency'' and ``wavelength''. - -\item[Epoch]\mbox{}\\ -This value is used to qualify a coordinate system by giving the moment in -time when the coordinates are correct. Usually, this will be the date of -observation. The Epoch value is important in cases where coordinates -systems move with respect to each other over time. An example of two such -coordinate systems are the FK4 and FK5 celestial coordinate systems. - -\item[ObsLon]\mbox{}\\ -Specifies the longitude of the observer (assumed to be on the surface of -the earth). The basic Frame class does not use this value, but -specialised sub-classes may. For instance, the SpecFrame class uses it to -calculate the relative velocity of the observer and the centre of the -earth for use in converting between standards of rest. - -\item[ObsLat]\mbox{}\\ -Specifies the latitude of the observer. Use in conjunction with ObsLon. - -\end{description} -\end{quote} - -There are also some further Frame attributes, not described above, -which are important when Frames are used as templates to search for -other Frames. Their use goes beyond the present discussion. -%TBW---Add reference here. - -\subsection{\label{ss:formattingaxisvalues}Formatting Axis Values} - -c+ -The coordinate values associated with each axis of a Frame are stored -(\emph{e.g.}\ within your program) as double values. The Frame class -therefore provides a function, astFormat, to convert these values into -formatted strings for display: -c- -f+ -The coordinate values associated with each axis of a Frame are stored -(\emph{e.g.}\ within your program) as double precision values. The -Frame class therefore provides a function, AST\_FORMAT, to convert -these values into formatted strings for display: -f- - -c+ -\small -\begin{terminalv} -const char *string -double value; - -... - -string = astFormat( frame, iaxis, value ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 50 ) STRING - DOUBLE PRECISION VALUE - - ... - - STRING = AST_FORMAT( FRAME, IAXIS, VALUE, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, the astFormat function is passed a Frame pointer, the number of -an axis (``iaxis'') and a double precision value to format -(``value''). It returns a pointer to character string containing the -formatted value. -c- -f+ -Here, the AST\_FORMAT character function is passed a Frame pointer, -the number of an axis (IAXIS) and a double precision value to format -(VALUE). It returns a character string containing the formatted value. -f- -\label{ss:formattingwithdigits} - -c+ -By default, the formatting applied will be determined by the Frame's -Digits attribute and will normally display results with seven digits -of precision (corresponding approximately to the C ``float'' data type -on many machines). Setting a different Digits value, however, allows -you to adjust the precision as necessary to suit the accuracy of the -coordinate data you are processing. If finer control is needed, it is -also possible to set a Digits value for each individual axis by -appending an axis number to the attribute name -(\emph{e.g.}\ ``Digits(2)''). If this is done, it over-rides the -effect of the Frame's main Digits value for that axis. -c- -f+ -By default, the formatting applied will be determined by the Frame's -Digits attribute and will normally display results with seven digits -of precision (corresponding approximately to the Fortran REAL data -type on many machines). Setting a different Digits value, however, -allows you to adjust the precision as necessary to suit the accuracy -of the coordinate data you are processing. If finer control is -needed, it is also possible to set a Digits value for each individual -axis by appending an axis number to the attribute name -(\emph{e.g.}\ ``Digits(2)''). If this is done, it over-rides the -effect of the Frame's main Digits value for that axis. -f- - -c+ -Even finer control is possible by setting the (character string) Format -attribute for a Frame axis. The string given should contain a C -\emph{format specifier} which explicitly determines how the values on -that axis should be formatted. This will over-ride the effects of any -Digits value\footnote{The exception to this rule is that if the Format -value includes a precision of ``$.*$'', then Digits will be used to -determine the actual precision used.}. Any valid ``printf'' format -specifier may be used so long as it consumes exactly one double value. -c- -f+ -Even finer control is possible by setting the (character string) -Format attribute for a Frame axis. The string given should contain a -\emph{format specifier} which explicitly determines how the values on -that axis should be formatted. This will over-ride the effects of any -Digits value\footnote{The exception to this rule is that if the Format value -includes a precision of ``$.*$'', then Digits will be used to determine -the actual precision used.}. Unfortunately for Fortran programmers, this must -be a C language format specifier,\footnote{This is a consequence of -implementing the AST library in C.} so you might find the Digits -approach preferable. -f- - -c+ -When setting Format values, remember that the ``\%'' which appears in -the format specifier may need to be doubled to ``\%\%'' if you are -using a function (such as astSet) which interprets ``printf'' format -specifiers itself. -c- -f+ -The simplest type of format specifier takes the form ``\%m.nG'', where -``m'' and ``n'' are integers giving the minimum field width in characters -and the number of significant digits to display (\emph{e.g.}\ -``\%10.5G''). The ''n'' value may be replaced by an asterisk, in which -case the value of the Digits attribute is used to determine the number of -significant digits to display. Other formatting options are also possible -and if you need to use them you may wish to consult a book on C (see the -``printf'' function), remembering that you want to format a double -precision (C double) value. -f- - -c+ -It is recommended that you use astFormat whenever you display -formatted coordinate values, even although you could format them -yourself using ``sprintf''. This is because it puts the Frame in -control of formatting. When you start to handle more elaborate Frames -(representing, say, celestial coordinates), you will need different -formatting methods. This approach delivers them without any change to -your software. -c- -f+ -It is recommended that you use AST\_FORMAT whenever you display -formatted coordinate values, even although you could format them -yourself using a WRITE statement. This is because it puts the Frame in -control of formatting. When you start to handle more elaborate Frames -(representing, say, celestial coordinates), you will need different -formatting methods. This approach delivers them without any change to -your software. -f- - -c+ -You should also consider regularly using the astNorm function, -described below (\secref{ss:normalising}), for any values that will be -made visible to the user of your software. -c- -f+ -You should also consider regularly using the AST\_NORM routine, -described below (\secref{ss:normalising}), for any values that will be -made visible to the user of your software. -f- - -\subsection{\label{ss:normalising}Normalising Frame Coordinates} - -c+ -The function astNorm is provided to cope with the fact that some -coordinate systems do not extend indefinitely in all directions. Some -may have boundaries, outside which coordinates are meaningless, while -others wrap around on themselves, so that after a certain distance you -return to the beginning again (coordinate systems based on circles and -spheres, for instance). A basic Frame has no such complications, but -other more specialised Frames (such as SkyFrames, representing the -celestial sphere---\secref{ss:skyframes}) do. -c- -f+ -The routine AST\_NORM is provided to cope with the fact that some -coordinate systems do not extend indefinitely in all directions. Some -may have boundaries, outside which coordinates are meaningless, while -others wrap around on themselves, so that after a certain distance you -return to the beginning again (coordinate systems based on circles and -spheres, for instance). A basic Frame has no such complications, but -other more specialised Frames (such as SkyFrames, representing the -celestial sphere---\secref{ss:skyframes}) do. -f- - -c+ -The role played by astNorm is to \emph{normalise} any arbitrary set of -coordinates by converting them into a set which is ``within bounds'', -interpreted according to the particular Frame in question. For -example, on the celestial sphere, a right ascension value of 24~hours -or more can have a suitable multiple of 24~hours subtracted without -affecting its meaning and astNorm would perform this task. Similarly, -negative values of right ascension would have a multiple of 24~hours -added, so that the result lies in the range zero to 24~hours. The -coordinates in question are modified in place by astNorm, as follows: -c- -f+ -The role played by AST\_NORM is to \emph{normalise} any arbitrary set -of coordinates by converting them into a set which is ``within -bounds'', interpreted according to the particular Frame in -question. For example, on the celestial sphere, a right ascension -value of 24~hours or more can have a suitable multiple of 24~hours -subtracted without affecting its meaning and AST\_NORM would perform -this task. Similarly, negative values of right ascension would have a -multiple of 24~hours added, so that the result lies in the range zero -to 24~hours. The coordinates in question are modified in place by -AST\_NORM, as follows: -f- - -c+ -\small -\begin{terminalv} -double point[ 2 ]; - -... - -astNorm( frame, point ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DOUBLE PRECISION POINT( 2 ) - - ... - - CALL AST_NORM( FRAME, POINT, STATUS ) -\end{terminalv} -\normalsize -f- - -If the coordinates supplied are initially OK, as they would always be -with a basic Frame, then they are returned unchanged. - -c+ -Because the main purpose of astNorm is to convert coordinates into the -preferred range for human consumption, its use is almost always -appropriate immediately before formatting coordinate values for -display using astFormat (\secref{ss:formattingaxisvalues}). Even if -the Frame in question does not restrict the range of coordinates, so -that astNorm does nothing, using it will allow you to process other -more specialised Frames, where normalisation is important, without -changing your software. -c- -f+ -Because the main purpose of AST\_NORM is to convert coordinates into -the preferred range for human consumption, its use is almost always -appropriate immediately before formatting coordinate values for -display using AST\_FORMAT (\secref{ss:formattingaxisvalues}). Even if -the Frame in question does not restrict the range of coordinates, so -that AST\_NORM does nothing, using it will allow you to process other -more specialised Frames, where normalisation is important, without -changing your software. -f- - -\subsection{\label{ss:unformattingaxisvalues}Reading Formatted Axis Values} - -c+ -The process of converting a formatted coordinate value for a Frame -axis, such as might be produced by astFormat -(\secref{ss:formattingaxisvalues}), back into a numerical (double) -value ready for processing is performed by astUnformat. However, -although this process is essentially the inverse of that performed by -astFormat, there are a number of additional difficulties that must be -addressed in practice. -c- -f+ -The process of converting a formatted coordinate value for a Frame -axis, such as might be produced by AST\_FORMAT -(\secref{ss:formattingaxisvalues}), back into a numerical (double -precision) value ready for processing is performed by AST\_UNFORMAT. -However, although this process is essentially the inverse of that -performed by AST\_FORMAT, there are a number of additional difficulties -that must be addressed in practice. -f- - -c+ -The main use for astUnformat is in reading formatted coordinate values -which have been entered by the user of a program, or read from a -file. As such, we can rarely assume that the values are neatly -formatted in the way that astFormat would produce. Instead, it is -usually desirable to allow considerable flexibility in the form of -input that can be accommodated, so as to permit ``free-format'' data -input by the user. In addition, we may need to extract individual -coordinate values embedded in other textual data. -c- -f+ -The main use for AST\_UNFORMAT is in reading formatted coordinate -values which have been entered by the user of a program, or read from -a file. As such, we can rarely assume that the values are neatly -formatted in the way that AST\_FORMAT would produce. Instead, it is -usually desirable to allow considerable flexibility in the form of -input that can be accommodated, so as to permit ``free-format'' data -input by the user. In addition, we may need to extract individual -coordinate values embedded in other textual data. -f- - -c+ -Underlying these requirements is the root difficulty that the textual -format used to represent a coordinate value will depend on the class -of Frame we are considering. For example, for a basic Frame, -astUnformat may have to read a value like ``1.25e-6'', whereas for a -more specialised Frame representing celestial coordinates it may have -to handle a value like ``-07d~49m~13s''. Of course, the format might -also depend on which axis is being considered. -c- -f+ -Underlying these requirements is the root difficulty that the textual -format used to represent a coordinate value will depend on the class -of Frame we are considering. For example, for a basic Frame, -AST\_UNFORMAT may have to read a value like ``1.25E-6'', whereas a -more specialised Frame representing celestial coordinates may have to -handle a value like ``-07d~49m~13s''. Of course, the format might also -depend on which axis is being considered. -f- - -Ideally, we would like to write software that can handle any kind of -Frame. However, this makes it a little more difficult to analyse -textual input data to extract individual coordinate values, since we -cannot make assumptions about how the values are formatted. It would -not be safe, for example, simply to assume that the values being read -are separated by white space. This is not just because they might be -separated by some other character, but also because celestial -coordinate values might themselves contain spaces. In fact, to be -completely safe, we cannot make any assumptions about how a formatted -coordinate value is separated from the surrounding text, except that -it should be separated in some way which is not ambiguous. - -c+ -This is the very basic assumption upon which astUnformat works. It is -invoked as follows: -c- -f+ -This is the very basic assumption upon which AST\_UNFORMAT works. It is -invoked as follows: -f- - -c+ -\small -\begin{terminalv} -int n; - -... - -n = astUnformat( frame, iaxis, string, &value ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER N - - ... - - N = AST_UNFORMAT( FRAME, IAXIS, STRING, VALUE, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -It is supplied with a Frame pointer (``frame''), the number of an axis -(``iaxis'') and a character string to be read (``string''). If it -succeeds in reading a value, astUnformat returns the resulting -coordinate to the address supplied \emph{via} the final argument -(``\&value''). The returned function value indicates how many -characters were read from the string in order to obtain this result. -c- -f+ -It is supplied with a Frame pointer (FRAME), the number of an axis -(IAXIS) and a character string to be read (STRING). If it succeeds in -reading a value, AST\_UNFORMAT returns the resulting coordinate -\emph{via} its penultimate argument (VALUE). The returned function -value indicates how many characters were read from the string in order -to obtain this result. -f- - -The string is read as follows: - -\begin{enumerate} -\item Any white space at the start is skipped over. - -\item Further characters are considered, one at a time, until the next -character no longer matches any of the acceptable forms of input -(given the characters that precede it). The longest sequence of -characters which matches is then considered ``read''. - -\item If a suitable sequence of characters was read successfully, it -is converted into a coordinate value which is returned. Any white -space following this sequence is then skipped over and the total -number of characters consumed is returned as the function value. - -c+ -\item If the sequence of characters read is empty, or insufficient to -define a coordinate value, then the string does not contain a value to -read. In this case, the read is aborted and astUnformat returns a -function value of zero and no coordinate value. However, it returns -without error. -c- -f+ -\item If the sequence of characters read is empty, or insufficient to -define a coordinate value, then the string does not contain a value to -read. In this case, the read is aborted and AST\_UNFORMAT returns a -function value of zero and no coordinate value. However, it returns -without error. -f- -\end{enumerate} - -c+ -Note that failing to read a coordinate value does not constitute an -error, at least so far as astUnformat is concerned. However, an error -can occur if the sequence of characters read appears to have the -correct form but cannot be converted into a valid coordinate -value. Typically, this will be because it violates some constraint, -such as a limit on the value of one of its fields. The resulting error -message will give details. -c- -f+ -Note that failing to read a coordinate value does not constitute an -error, at least so far as AST\_UNFORMAT is concerned. However, an -error can occur if the sequence of characters read appears to have the -correct form but cannot be converted into a valid coordinate -value. Typically, this will be because it violates some constraint, -such as a limit on the value of one of its fields. The resulting error -message will give details. -f- - -c+ -For any given Frame axis, astUnformat does not necessarily always use -the same algorithm for converting the sequence of characters it reads -into a coordinate value. This is because some forms of input -(particularly free-format input) can be ambiguous and might be -interpreted in several ways depending on the context. For example, the -celestial longitude ``12:34:56.7'' could represent an angle in degrees -or a right ascension in hours. To decide which to use, astUnformat may -examine the Frame's attributes and, in particular, the appropriate -Format(axis) string which is used by astFormat when formatting -coordinate values (\secref{ss:formattingaxisvalues}). This is done in -order that astFormat and astUnformat should complement each other---so -that formatting a value and then un-formatting it will yield the -original value, subject to any rounding error. -c- -f+ -For any given Frame axis, AST\_UNFORMAT does not necessarily always -use the same algorithm for converting the sequence of characters it -reads into a coordinate value. This is because some forms of input -(particularly free-format input) can be ambiguous and might be -interpreted in several ways depending on the context. For example, the -celestial longitude ``12:34:56.7'' could represent an angle in degrees -or a right ascension in hours. To decide which to use, AST\_UNFORMAT -may examine the Frame's attributes and, in particular, the appropriate -Format(axis) string which is used by AST\_FORMAT when formatting -coordinate values (\secref{ss:formattingaxisvalues}). This is done in -order that AST\_FORMAT and AST\_UNFORMAT should complement each -other---so that formatting a value and then un-formatting it will -yield the original value, subject to any rounding error. -f- - -To give a simple (but crucially incomplete!) example, consider reading -a value for the axis of a basic Frame, as follows: - -c+ -\small -\begin{terminalv} -n = astUnformat( frame, iaxis, " 1.5e6 -99.0", &value ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - N = AST_UNFORMAT( FRAME, IAXIS, ' 1.5E6 -99.0', VALUE, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -astUnformat will skip over the initial space in the string supplied -and then examine each successive character. It will accept the -sequence ``1.5e6'' as input, but reject the space which follows -because it does not form part of the format of a floating point -number. It will then convert the characters ``1.5e6'' into a -coordinate value and skip over the three spaces which follow them. The -returned function value will therefore be 9, equal to the total number -of characters consumed. This result may be used to address the string -during a subsequent read, so as to commence reading at the start of -``-99.0''. -c- -f+ -AST\_UNFORMAT will skip over the initial space in the string supplied -and then examine each successive character. It will accept the -sequence ``1.5E6'' as input, but reject the space which follows -because it does not form part of the format of a floating point -number. It will then convert the characters ``1.5E6'' into a -coordinate value and skip over the three spaces which follow them. The -returned function value will therefore be 9, equal to the total number -of characters consumed. This result may be used to address the string -during a subsequent read, so as to commence reading at the start of -``-99.0''. -f- - -c+ -Most importantly, however, note that if the user of a program -mistakenly enters the string ``~1.5r6\ldots'' instead of -``~1.5e6\ldots'', a coordinate value of 1.5 and a function result of 4 -will be returned, because the ``r'' would prematurely terminate the -attempt to read the value. Because this sort of mistake does not -automatically result in an error but can produce incorrect results, it -is \textbf{vital} to check the returned function value to ensure that -the expected number of characters have been read.\footnote{Anyone who -seriously uses the C run time library ``scanf'' function will know -about the need for this check!} For example, if the string is -expected to contain exactly one value, and nothing else, then the -following would suffice: -c- -f+ -Most importantly, however, note that if the user of a program -mistakenly enters the string ``~1.5R6\ldots'' instead of -``~1.5E6\ldots'', a coordinate value of 1.5 and a function result of 4 -will be returned, because the ``R'' would prematurely terminate the -attempt to read the value. Because this sort of mistake does not -automatically result in an error but can produce incorrect results, it -is \textbf{vital} to check the returned function value to ensure that -the expected number of characters have been read. For example, if the -string is expected to contain exactly one value, and nothing else, -then the following would suffice: -f- - -c+ -\small -\begin{terminalv} -n = astUnformat( frame, iaxis, string, &value ); -if ( astOK ) { - if ( string[ n ] || !n ) { - - } else { - - } -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - N = AST_UNFORMAT( FRAME, IAXIS, STRING, VALUE, STATUS ) - IF ( STATUS .EQ. 0 ) THEN - IF ( N .LT. LEN( STRING ) ) THEN - - ELSE - - END IF - END IF -\end{terminalv} -\normalsize -f- - -c+ -If astUnformat does not detect an error itself, we check that it has -read to the end-of-string and consumed at least one character (which -traps the case of a zero-length input string). If this reveals an -error, the value of ``n'' indicates where it occurred. -c- -f+ -If AST\_UNFORMAT does not detect an error itself, we check that it has -read to the end of the string. If this reveals an error, the value of -N indicates where it occurred. -f- - -Another common requirement is to obtain a position by reading a list -of coordinates from a string which contains one value for each axis of -a Frame. We assume that the values are separated in some unambiguous -manner, perhaps using white space and/or some unspecified -single-character separator. The choice of separator is up to the data -supplier, who must choose it so as not to conflict with the format of -the coordinate values, but our software does not need to know what it -is. The following is a template algorithm for reading data in this -form: - -c+ -\small -\begin{terminalv} -const char *s; -double values[ 10 ]; - -... - -/* Initialise a string pointer. */ -s = string; - -/* Obtain the number of Frame axes and loop through them. */ -naxes = astGetI( frame, "Naxes" ); -for ( iaxis = 1; iaxis <= naxes; iaxis++ ) { - -/* Attempt to read a value for this axis. */ - n = astUnformat( frame, iaxis, s, &values[ iaxis - 1 ] ); - -/* If nothing was read and this is not the first axis or the - end-of-string, try stepping over a separator and reading again. */ - if ( !n && ( iaxis > 1 ) && *s ) - n = astUnformat( frame, iaxis, ++s, &values[ iaxis - 1 ] ); - -/* Quit if nothing was read, otherwise move on to the next value. */ - if ( !n ) break; - s += n; -} - -/* Check for possible errors. */ -if ( astOK ) { - if ( *s || !n ) { - - } else { - - } -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER I - DOUBLE PRECISION VALUES( 10 ) - - ... - -* Initialise the string index. - I = 1 - -* Obtain the number of Frame axes and loop through them. - DO 1 IAXIS = 1, AST_GETI( FRAME, 'Naxes', STATUS ) - -* Attempt to read a value for this axis. - N = AST_UNFORMAT( FRAME, IAXIS, STRING( I : ), - : VALUES( IAXIS ), STATUS ) - -* If nothing was read and this is not the first axis and the end of -* the string has not been reached, try stepping over a separator and -* reading again. - IF ( ( N .EQ. 0 ) .AND. ( IAXIS .GT. 1 ) .AND. - : ( I .LT. LEN( STRING ) ) ) THEN - I = I + 1 - N = AST_UNFORMAT( FRAME, IAXIS, STRING( I : ), - : VALUES( IAXIS ), STATUS ) - END IF - -* Quit if nothing was read, otherwise move on to the next value. - IF ( N .EQ. 0 ) GO TO 2 - I = I + N - 1 CONTINUE - 2 CONTINUE - -* Check for possible errors. - IF ( STATUS .EQ. 0 ) THEN - IF ( ( I .LT. LEN( STRING ) ) .OR. ( N .EQ. 0 ) ) THEN - - ELSE - - END IF - END IF -\end{terminalv} -\normalsize -f- - -c+ -In this case, ``s'' will point to the location of any input error. -c- -f+ -In this case, the value of I will indicate the location of any input error. -f- - -Note that this algorithm is insensitive to the precise format of the -data and will therefore work with any class of Frame and any -reasonably unambiguous input data. For example, here is a range of -suitable input data for a 3-dimensional basic Frame: - -\small -\begin{terminalv} -1 2.5 3 -3.1,3.2,3.3 -1.5, 2.6, -9.9e2 --1.1+0.4-1.8 - .1/.2/.3 - 44.0 ; 55.1 -14 -\end{terminalv} -\normalsize - -\subsection{\label{ss:permutingaxes}Permuting Frame Axes} - -Once a Frame has been created, it is not possible to change the number -of axes it contains, but it is possible to change the order in which -these axes occur. To do so, an integer \emph{permutation array} is -filled with the numbers of the axes so as to specify the new order, -\emph{e.g.:} - -c+ -\small -\begin{terminalv} -int perm[ 2 ] = { 2, 1 }; -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER PERM( 2 ) - DATA PERM / 2, 1 / -\end{terminalv} -\normalsize -f- - -c+ -In this case, the axes of a 2-dimensional Frame could be interchanged -by passing this permutation array to the astPermAxes function. That -is, an ($x_1,x_2$) coordinate system would be changed into an -($x_2,x_1$) coordinate system by: -c- -f+ -In this case, the axes of a 2-dimensional Frame could be interchanged -by passing this permutation array to the AST\_PERMAXES function. That -is, an ($x_1,x_2$) coordinate system would be changed into an -($x_2,x_1$) coordinate system by: -f- - -c+ -\small -\begin{terminalv} -astPermAxes( frame, perm ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_PERMAXES( FRAME, PERM, STATUS ) -\end{terminalv} -\normalsize -f- - -If the axes are permuted more than once, the effects are cumulative. -You are, of course, not restricted to Frames with only two axes. - -\subsection{Selecting Frame Axes} - -c+ -An alternative to changing the number of Frame axes, which is not -allowed, is to create a new Frame by selecting axes from an existing -one. The method of doing this is very similar to the way astPermAxes -is used (\secref{ss:permutingaxes}), in that we supply an integer -array filled with the numbers of the axes we want, in their new -order. In this case, however, the number of array elements need not -equal the number of Frame axes. -c- -f+ -An alternative to changing the number of Frame axes, which is not -allowed, is to create a new Frame by selecting axes from an existing -one. The method of doing this is very similar to the way AST\_PERMAXES -is used (\secref{ss:permutingaxes}), in that we supply an integer -array filled with the numbers of the axes we want, in their new -order. In this case, however, the number of array elements need not -equal the number of Frame axes. -f- - -For example, we could select axes 3 and 2 (in that order) from a -3-dimensional Frame as follows: - -c+ -\small -\begin{terminalv} -astFrame *frame1, *frame2; -astMapping *mapping; -int pick[ 2 ] = { 3, 2 }; - -... - -frame2 = astPickAxes( frame1, 2, pick, &mapping ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER FRAME1, FRAME2, MAPPING, PICK( 2 ) - DATA PICK / 3, 2 / - - ... - - FRAME2 = AST_PICKAXES( FRAME1, 2, PICK, MAPPING, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -This would return a pointer to a 2-dimensional Frame (``frame2'') -which contains the information associated with axes 3 and 2, in that -order, from the original Frame (``frame1''). The original Frame is not -altered by this process. Beware, however, that the axis information -may still be shared by both Frames, so if you wish to alter either of -them independently you may first need to use astCopy -(\secref{ss:copyingobjects}) to make an independent copy. -c- -f+ -This would return a pointer to a 2-dimensional Frame (FRAME2) which -contains the information associated with axes 3 and 2, in that order, -from the original Frame (FRAME1). The original Frame is not altered by -this process. Beware, however, that the axis information may still be -shared by both Frames, so if you wish to alter either of them -independently you may first need to use AST\_COPY -(\secref{ss:copyingobjects}) to make an independent copy. -f- - -c+ -In addition to the new Frame pointer, astPickAxes will also return a -pointer to a new Mapping \emph{via} its fourth argument (you may supply a -NULL pointer as an argument if you do not want this Mapping). This -Mapping will inter-relate the two Frames. By this we mean that its -forward transformation will convert coordinates originally in the -coordinate system represented by ``frame1'' into that represented by -``frame2'', while its inverse transformation will convert in the -opposite direction. In this particular case, the Mapping would be a -PermMap (\secref{ss:permmapexample}) and would implement the following -transformations: -c- -f+ -In addition to the new Frame pointer, AST\_PICKAXES will also return a -pointer to a new Mapping \emph{via} its fourth argument. This Mapping will -inter-relate the two Frames. By this we mean that its forward -transformation will convert coordinates originally in the coordinate -system represented by FRAME1 into that represented by FRAME2, while -its inverse transformation will convert in the opposite direction. In -this particular case, the Mapping would be a PermMap -(\secref{ss:permmapexample}) and would implement the following -transformations: -f- - -\begin{terminalv} -Forward: - (1, 2, 3) --> (3, 2) - (2, 4, 6) --> (6, 4) - (3, 6, 9) --> (9, 6) - (4, 8, 12) --> (12, 8) - (5, 10, 15) --> (15, 10) - -Inverse: - (3, 2) --> (, 2, 3) - (6, 4) --> (, 4, 6) - (9, 6) --> (, 6, 9) - (12, 8) --> (, 8, 12) - (15, 10) --> (, 10, 15) -\end{terminalv} - -This is our first introduction to the idea of inter-relating pairs of -Frames \emph{via} a Mapping, but this will assume a central role later on. - -c+ -Note that when using astPickAxes, it is also possible to request more -axes than there were in the original Frame. This will involve -selecting axes from the original Frame that do not exist. To do this, -the corresponding axis number (in the ``pick'' array) should be set to -zero and the effect is to introduce an additional new axis which is -not derived from the original Frame. This axis will have default -values for all its attributes. You will need to do this because -astPickAxes does not allow you to select any of the original axes more -than once.\footnote{It will probably not be obvious why this -restriction is necessary, but consider creating a Frame with one -longitude axis and two latitude axes. Which latitude axis should be -associated with the longitude axis?} -c- -f+ -Note that when using AST\_PICKAXES, it is also possible to request -more axes than there were in the original Frame. This will involve -selecting axes from the original Frame that do not exist. To do this, -the corresponding axis number (in the PICK array) should be set to -zero and the effect is to introduce an additional new axis which is -not derived from the original Frame. This axis will have default -values for all its attributes. You will need to do this because -AST\_PICKAXES does not allow you to select any of the original axes -more than once.\footnote{It will probably not be obvious why this -restriction is necessary, but consider creating a Frame with one -longitude axis and two latitude axes. Which latitude axis should be -associated with the longitude axis?} -f- - -\subsection{\label{ss:distanceandoffset}Calculating Distances, Angles and Offsets} -Some complementary -c+ -functions -c- -f+ -routines -f- -are provided for use with Frames to allow you to perform geometric -operations without needing to know the nature of the coordinate system -represented by the Frame. - -c+ -Functions -c- -f+ -Routines -f- -can be used to find the distance between two points, and to offset a -specified distance along a line joining two points, \emph{etc.} In essence, -these define the metric of the coordinate space which the Frame represents. In -the case of a basic Frame, this is a Cartesian metric. - -c+ -The first of these functions, astDistance, returns a double distance -value when supplied with the Frame coordinates of two points. For -example: -c- -f+ -The first of these routines, AST\_DISTANCE, returns a double precision -distance value when supplied with the Frame coordinates of two -points. For example: -f- - -c+ -\small -\begin{terminalv} -double dist; -double point1[ 2 ] = { 0.0, 0.0 }; -double point2[ 2 ] = { 1.0, 1.0 }; - -... - -dist = astDistance( frame, point1, point2 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DOUBLE PRECISION DIST, POINT1( 2 ), POINT2( 2 ) - DATA POINT1 / 0D0, 0D0 / - DATA POINT2 / 1D0, 1D0 / - - ... - - DIST = AST_DISTANCE( FRAME, POINT1, POINT2, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -This calculates the distance between the origin (0,0) and a point at -position (1,1). In this case, the result, as you would expect, is -$\surd{2}$. However, this is only true for the Cartesian coordinate -system which a basic Frame represents. In general, astDistance will -calculate the geodesic distance between the two points, so that with a -more specialised Frame (such as a SkyFrame, representing the celestial -sphere) a great-circle distance might be returned. -c- -f+ -This calculates the distance between the origin (0,0) and a point at -position (1,1). In this case, the result, as you would expect, is -$\surd{2}$. However, this is only true for the Cartesian coordinate -system which a basic Frame represents. In general, AST\_DISTANCE will -calculate the geodesic distance between the two points, so that with a -more specialised Frame (such as a SkyFrame, representing the celestial -sphere) a great-circle distance might be returned. -f- - -c+ -The astOffset function is really the inverse of astDistance. Given two -points in a Frame, it calculates the coordinates of a third point -which is offset a specified distance away from the first point along -the geodesic joining it to the second one. For example: -c- -f+ -The AST\_OFFSET routine is really the inverse of AST\_DISTANCE. Given -two points in a Frame, it calculates the coordinates of a third point -which is offset a specified distance away from the first point along -the geodesic joining it to the second one. For example: -f- - -c+ -\small -\begin{terminalv} -double point1[ 2 ] = { 0.0, 0.0 }; -double point2[ 2 ] = { 1.0, 1.0 }; -double point3[ 2 ]; - -... - -astOffset( frame, point1. point2, 0.5, point3 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DOUBLE PRECISION POINT1( 2 ), POINT2( 2 ), POINT3( 2 ) - DATA POINT1 / 0D0, 0D0 / - DATA POINT2 / 1D0, 1D0 / - - ... - - CALL AST_OFFSET( FRAME, POINT1, POINT2, 0.5D0, POINT3, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -This would fill the ``point3'' array with the coordinates of a point -which is offset 0.5 units away from the origin (0,0) in the direction -of the position (1,1). Again, this is a simple result in a Cartesian -Frame, as varying the offset will trace out a straight line. On the -celestial sphere, however (\emph{e.g.}\ using a SkyFrame), it would -trace out a great circle. -c- -f+ -This would fill the POINT3 array with the coordinates of a point which -is offset 0.5 units away from the origin (0,0) in the direction of the -position (1,1). Again, this is a simple result in a Cartesian Frame, -as varying the offset will trace out a straight line. On the celestial -sphere, however (\emph{e.g.}\ using a SkyFrame), it would trace out a -great circle. -f- - -c+ -The functions astAxDistance and astAxOffset are similar to astDistance -and astOffset, except that the curves which they use as ``straight -lines'' are not geodesics, but curves parallel to a specified axis\footnote -{For instance, a line of constant Declination is not a geodesic}. One -reason for using these functions is to deal with the cyclic ambiguity of -longitude and latitude axes. -c- -f+ -The routines AST\_AXDISTANCE and AST\_AXOFFSET are similar to AST\_DISTANCE -and AST\_OFFSET, except that the curves which they use as ``straight -lines'' are not geodesics, but curves parallel to a specified axis\footnote -{For instance, a line of constant Declination is not a geodesic}. One -reason for using these routines is to deal with the cyclic ambiguity of -longitude and latitude axes. -f- - -c+ -The astOffset2 function is similar to astOffset, but instead of using the -c- -f+ -The AST\_OFFSET2 routine is similar to AST\_OFFSET, but instead of using the -f- -geodesic which passes through two positions, it uses the geodesic which -passes at a given position angle through the starting position. - -Position angles are always measured from the positive direction of the -second Frame axis to the required line, with positive angles being in the -same sense as rotation from the positive direction of the second axis to -the positive direction of the first Frame axis. This definition applies -to all classes of Frame, including SkyFrame. The default ordering of axes -in a SkyFrame makes the second axis equivalent to north, and so the -definition of position angle given above corresponds to the normal -astronomical usage, ``from north, through east''. However, it should be -remembered that it is possible to permute the axes of a SkyFrame (or -indeed any Frame), so that north becomes axis 1. In this case, an AST -``position angle'' would be the angle ``from east, through north''. -Always take the axis ordering into account when deriving an astronomical -position angle from an AST position angle. - -Within a Cartesian coordinate system, the position angle of a geodesic -(\emph{i.e.}\ a straight line) is constant along its entire length, but -this is not necessarily true of other coordinate systems. Within a -spherical coordinate system, for instance, the position angle of a geodesic -will vary along its length (except for the special cases of a meridian and -the equator). In addition to returning the required offset position, the -c+ -astOffset2 function -c- -f+ -AST\_OFFSET2 routine -f- -returns the position angle of the geodesic at the -offset position. This is useful if you want to trace out a path which -involves turning through specified angles. For instance, tracing out a -rectangle in which each side is a geodesic involves turning through 90 -c+ -degrees at the corners. To do this, use astOffset2 to calculate the -position of each corner, and then add (or subtract) 90 degrees from the -position angle returned by astOffset2. -c- -f+ -degrees at the corners. To do this, use AST\_OFFSET2 to calculate the -position of each corner, and then add (or subtract) 90 degrees from the -position angle returned by AST\_OFFSET2. -f- - -c+ -The astAngle function -c- -f+ -The AST\_ANGLE routine -f- -calculates the angle subtended by two points, at a third point. -If used with a 2-dimensional Frame the returned angle -is signed to indicate the sense of rotation (clockwise or anti-clockwise) -in taking the ``shortest route'' from the first point to the second. -If the Frame has more than 2 axes, the result is un-signed and is always -in the range zero to $\pi$. - -c+ -The astAxAngle function is similar to astAngle, -c- -f+ -The AST\_AXANGLE routine is similar to AST\_AXANGLE, -f- -but the ``reference direction'', from which angles are measured, is -a specified axis. - -c+ -The astResolve function -c- -f+ -The AST\_RESOLVE routine -f- -resolves a given displacement within a Frame into two components, parallel and -perpendicular to a given reference direction. - -The displacement is specified by two positions within the Frame; the -starting and ending positions. The reference direction is defined by the -geodesic curve passing through the starting position and a third specified -position. The lengths of the two components are returned, together with -the position on the reference geodesic which is closest to the third -supplied point. - -\subsection{\label{ss:framedomains}The Domain Attribute} - -The Domain attribute is one of the most important properties of a -Frame, although the concept it expresses can sometimes seem a little -subtle. We will introduce it here, but its true value will probably -not become apparent until later (\secref{ss:framesetconverting}). - -To understand the need for the Domain attribute, consider using -different Frames to represent the following different coordinate -systems associated with a CCD image: - -\begin{enumerate} -\item A coordinate system based on pixel numbers. - -\item Positions on the CCD chip, measured in $\mu$m. - -\item Positions in the focal plane of the telescope, measured in mm. - -\item A celestial coordinate system, measured in radians. -\end{enumerate} - -If we had two such CCD images, we might legitimately want to align -them pixel-for-pixel (\emph{i.e.}\ using the coordinate system based -on pixel numbers) in order to, say, divide by a flat-field exposure. -We might similarly consider aligning them using any of the other -coordinate systems so as to achieve different results. For example, we -might consider merging separate images from a CCD mosaic by using -focal plane positions. - -It would obviously not be legitimate, however, to directly compare -positions in one image measured in pixels with positions in the other -measured in mm, nor to equate chip positions in $\mu$m with sky -coordinates in radians. If we wanted to inter-compare these -coordinates, we would need to do it indirectly, using other -information based on the experimental set-up. For instance, we might -need to know the size of the pixels expressed in mm and the -orientation of the CCD chip in the focal plane. - -Note that it is not simply the difference in physical units which -prevents certain coordinates from being directly inter-compared -(because the appropriate unit scaling factors could be included -without any additional information). Neither is it the fact that -different coordinate systems are in use (because we could legitimately -inter-compare two different celestial coordinate systems without any -extra information). Instead, it is the different nature of the -coordinate spaces to which these coordinate systems have been applied. - -We normally express this by saying that the coordinate systems apply -to different \emph{physical domains}. Although we may establish -\emph{ad hoc} relationships between coordinates in different physical -domains, they are not intrinsically related to each other and we need -to supply extra information before we can convert coordinates between -them. - -In AST, the role of the (character string) Domain attribute is to -assign Frames to their respective physical domains. The way it -operates is as follows: - -\begin{itemize} -\item Coordinate systems which apply to the same physical domain -(\emph{i.e.}\ whose Frames have the same Domain value) can be directly -inter-compared. - -If the domain has several coordinate systems associated with it -(\emph{e.g.}\ the celestial sphere), then a coordinate conversion may -be involved. Otherwise, coordinate values may simply be equated. - -\item Coordinate systems which apply to different physical domains -(\emph{i.e.}\ whose Frames have different Domain values) cannot be -directly inter-compared. - -If any relationship does exist between such coordinate systems---and -it need not---then additional information must be supplied in order to -establish the relationship between them in any particular case. We -will see later (\secref{ss:framesets}) how to establish such -relationships between Frames in different domains. -\end{itemize} - -With the basic Frames we are considering here, each physical domain only -has a single (Cartesian) coordinate system associated with it, so that if -two such Frames have the same Domain value, their coordinate systems will -be identical and may simply be equated. With more specialised Frames, -however, more than one coordinate system may apply to each domain. In -such cases, a coordinate conversion may need to be performed. - -c+ -When a basic Frame is created, its Domain attribute defaults to an -empty string. This means that all such Frames belong to the same -(null) domain by default and therefore describe the same unspecified -physical coordinate space. In order to assign a Frame to a different -domain, you simply need to set its Domain value. This is normally most -conveniently done when it is created, as follows: -c- -f+ -When a basic Frame is created, its Domain attribute defaults to a -blank string. This means that all such Frames belong to the same -(null) domain by default and therefore describe the same unspecified -physical coordinate space. In order to assign a Frame to a different -domain, you simply need to set its Domain value. This is normally most -conveniently done when it is created, as follows: -f- - -c+ -\small -\begin{terminalv} -frame1 = astFrame( 2, "Domain=CCD_CHIP," - "Unit(1)=micron," - "Unit(2)=micron" ); -frame2 = astFrame( 2, "Domain=FOCAL_PLANE," - "Unit(1)=mm," - "Unit(2)=mm" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - FRAME1 = AST_FRAME( 2, 'Domain=CCD_CHIP,' // - 'Unit(1)=micron,' // - 'Unit(2)=micron', STATUS ) - FRAME2 = AST_FRAME( 2, 'Domain=FOCAL_PLANE,' // - 'Unit(1)=mm,' // - 'Unit(2)=mm', STATUS ) -\end{terminalv} -\normalsize -f- - -Here, we have created two Frames in different physical -domains. Although their coordinate values all have units of length, -they cannot be directly inter-compared (because their axes may be -rotated with respect to each other, for instance). - -All Domain values are automatically converted to upper case and white -space is removed, but there are no other restrictions on the names you -may use to label different physical domains. From a practical point of -view, however, it is worth following a few conventions -(\secref{ss:domainconventions}). - -\subsection{\label{ss:domainconventions}Conventions for Domain Names} - -When choosing a value for the Domain attribute of a Frame, it -obviously makes sense to avoid generic names which might clash with -those used for similar (but subtly different!) purposes by other -programmers. If you are developing software for an instrument, for -example, and want to identify an instrumental coordinate system, then -it is sensible to add a distinguishing prefix. For instance, you might -use $<$INST$>$\_FOCAL\_PLANE, where $<$INST$>$ (\emph{e.g.}\ an -acronym) identifies your instrument. - -For some purposes, however, a standard choice of Domain name is -desirable so that different items of software can communicate. For -this purpose, the following Domain names are reserved by AST and the -use recommended below should be carefully observed: - -\begin{quote} -\begin{description} -\item[GRAPHICS]\mbox{}\\ -Identifies the coordinate space used by an underlying computer -graphics system to specify plotting operations. Typically, when -performing graphical operations, AST is used to define additional -coordinate systems which are related to these ``native'' graphical -coordinates. Plotting may be carried out in any of these coordinate -systems, but the GRAPHICS domain identifies the native coordinates -through which AST communicates with the underlying graphics system. - -\item[GRID]\mbox{}\\ -Identifies the instantaneous \emph{data grid} used to store and handle -data, together with an associated coordinate system. In this -coordinate system, the first element stored in an array of data always -has a coordinate value of unity at its centre and all elements have -unit extent. This applies to all dimensions. - -If data are copied or transformed to a new data grid (by whatever -means), or a subset of the original grid is extracted, then the same -rules apply to the copy or subset. Its first element therefore has -GRID coordinate values of unity at its centre. Note that this means -that GRID coordinates remain attached to the first element of the data -grid and not to its data content (\emph{e.g.}\ the features in an -image). - -\item[PIXEL]\mbox{}\\ -Identifies an array of pixels and an associated \emph{pixel-based} -coordinate system which is related to the GRID coordinate system -(above) simply by a shift of origin along each axis. This shift may be -integral, fractional, positive, negative or zero. The data elements -retain their unit extent along each axis. - -Because the amount of shift is unspecified, the PIXEL domain is -distinct from the GRID domain. The relationship between them contains -a degree of uncertainty, such as typically arises from the different -conventions used by different software systems. For instance, in some -software the first pixel is regarded as being centred at (1,1), while -in other software it is at (0.5,0.5). In addition, some software -packages implement a ``pixel origin'' which allows pixel coordinates -to start at an arbitrary value. - -The GRID domain (which corresponds with the pixel-numbering convention -used by FITS) is a special case of the PIXEL domain and avoids this -uncertainty. In general, additional information is required in order -to convert from one to the other. - -\item[SKY]\mbox{}\\ -Identifies the domain which contains all equivalent celestial -coordinate systems. Because these are represented in AST by SkyFrames -(\secref{ss:skyframes}), it should be no surprise that the default -Domain value for a SkyFrame is SKY. Since there is only one sky, you -probably won't need to change this very often. - -\item[SPECTRUM]\mbox{}\\ -Identifies the domain used to describe positions within an -electro-magnetic spectrum. The AST SpecFrame (\secref{ss:specframes}) -class describes positions within this domain, allowing a wide range of -different coordinate systems to be used (frequency, wavelength, -\emph{etc}). The default Domain value for a SpecFrame is SPECTRUM. - -\item[TIME]\mbox{}\\ -Identifies the domain used to describe moments in time. The AST TimeFrame -class describes positions within this domain, allowing a wide range of -different coordinate systems and timescales to be used. The default Domain -value for a TimeFrame is TIME. - -\end{description} -\end{quote} - -Although we have drawn a necessary distinction here between the GRID -and PIXEL domains, we will continue to refer in general terms to image -``pixels'' and ``pixel coordinates'' whenever this distinction is not -important. This should not be taken to imply that the GRID convention -for numbering pixels is excluded---in fact, it is usually to be -preferred (at the level of data handling being discussed in this -document) and we recommend it. - -\subsection{\label{ss:frameunits}The Unit Attribute} -Each axis of a Frame has a Unit attribute which holds the physical units used -to describe positions on the axis. The index of the axis to which the -attribute refers should normally be placed in parentheses following the -attribute name (``Unit(2)'' for instance). However, if the Frame has only -a single axis, then the axis index can be omitted. - -In versions of AST prior to version 2.0, the Unit attribute was nothing -more than a descriptive string intended purely for human readers---no -part of the AST system used the Unit string for any purpose (other than -inclusion in axis labels produced by the Plot class). In particular, no -account was taken of the Unit attribute when finding the Mapping between -two Frames. Thus if the conversion between a pair of 1-dimensional Frames -representing velocity was found (using -c+ -astConvert -c- -f+ -AST\_CONVERT -f- -) the returned Mapping would always be a UnitMap, even if the Unit -attributes of the two Frames were ``km/h'' and ``m/s''. This behaviour is -referred to below as a \emph{passive} Unit attribute. - -As of AST version 2.0, a facility exists which allows the Unit attribute -to be \emph{active}; that is, differences in the -Unit attribute may be taken into account when finding the Mapping between -two Frames. In order to minimise the risk of breaking older software, the -\emph{default} behaviour of simple Frames and SkyFrames is unchanged from -previous versions (\emph{i.e.} they have passive Unit attributes). However, -the new -c+ -functions astSetActiveUnit and astGetActiveUnit -c- -f+ -routines AST\_SETACTIVEUNIT and AST\_GETACTIVEUNIT -f- -allow this default behaviour to be changed. The SpecFrame and TimeFrame -classes \emph{always} have an active Unit attribute (attempts to change this -are ignored). - -For instance, consider the above example of two 1-dimensional Frames -describing velocity. These Frames can be created as follows: - -c+ -\small -\begin{terminalv} -AstFrame *frame1, *frame2; -frame1 = astFrame( 1, "Domain=VELOCITY,Unit=km/h" ); -frame2 = astFrame( 1, "Domain=VELOCITY,Unit=m/s" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER FRAME1, FRAME2 - - FRAME1 = AST_FRAME( 1, 'Domain=VELOCITY,Unit=km/h' ) - FRAME2 = AST_FRAME( 1, 'Domain=VELOCITY,Unit=m/s' ) - -\end{terminalv} -\normalsize -f- - -By default, these Frames have passive Unit attributes, and so an attempt -to find a Mapping between them would ignore the difference in their Unit -attributes and return a unit Mapping. To avoid this, we indicate that we -want these Frames to have \emph{active} Unit attributes, as follows: - -c+ -\small -\begin{terminalv} -astSetActiveUnit( frame1, 1 ); -astSetActiveUnit( frame2, 1 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SETACTIVEUNIT( FRAME1, .TRUE., STATUS ) - CALL AST_SETACTIVEUNIT( FRAME2, .TRUE., STATUS ) -\end{terminalv} -\normalsize -f- - -If we then find the Mapping between them as follows: - -c+ -\small -\begin{terminalv} -AstFrameSet *cvt; -... -cvt = astConvert( frame1, frame2, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER CVT - ... - CVT = AST_CONVERT( FRAME1, FRAME2, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -the Mapping contained within the FrameSet returned by -c+ -astConvert -c- -f+ -AST\_CONVERT -f- -will be a one-dimensional ZoomMap which simply scales its input (a -velocity in $km/h$) by a factor of 0.278 to create its output (a velocity -in $m/s$). - -c+ -In fact we need not have set the Unit attribute active in ``frame1'' -since the behaviour of astConvert is determined by its ``to'' Frame -(the second Frame parameter). -c- -f+ -In fact we need not have set the Unit attribute active in FRAME1 -since the behaviour of AST\_CONVERT is determined by its TO Frame -(the second Frame argument). -f- - -\subsubsection{\label{ss:unitsyntax}The Syntax for Unit Strings} -Conversion between units systems relies on the use of a specific syntax -for the Unit attribute. If the value of the Unit attribute does not -conform to this syntax, then an error will be reported if an attempt is -made to use it to determine an inter-unit Mapping (this will never happen -if the Unit attribute is \emph{passive}). - -The adopted syntax is that described in FITS-WCS paper I "Representation -of World Coordinate in FITS" by Greisen \& Calabretta. We distinguish -here between ``basic'' units and ``derived'' units: derived units are -defined in terms of other units (either derived or basic), whereas basic -units have no such definitions. Derived units may be represented by their -own \emph{symbol} (\emph{e.g.} ``Jy''---the Jansky) or by a -\emph{mathematical expression} which combines other symbols and constants -to form a definition of the unit (\emph{e.g.} ``km/s''---kilometres per -second). Unit symbols may be prefixed by a string representing a standard -multiple or sub-multiple. - -In addition to the unit symbols listed in FITS-WCS Paper I, any other -arbitrary unit symbol may be used, with the proviso that it will not be -possible to convert between Frames using such units. The exception to -this is if both Frames refer to the same unknown unit string. For instance, -an axis with unknown unit symbol "flop" \emph{could} be converted to an axis -with unit "Mflop" (Mega-flop). - -Unit symbols (optionally prefixed with a multiple or sub-multiple) can be -combined together using a limited range of mathematical operators and -functions, to produce new units. Such expressions may also contain -parentheses and numerical constants (these may optionally use -``scientific'' notation including an ``E'' character to represent the -power of 10). - -The following tables list the symbols for the basic and derived units which -may be included in a units string, the standard prefixes for multiples -and sub-multiples, and the strings which may be used to represent -mathematical operators and functions. - -\begin{table}[htbp] -\begin{center} -\begin{tabular}{|l|l|l|} -\hline -\multicolumn{3}{|c|}{{\large Basic units}} \\ \hline -\multicolumn{1}{|c|}{Quantity} & \multicolumn{1}{|c|}{Symbol} & -\multicolumn{1}{c|}{Full Name} \\ \hline -length & m & metre \\ -mass & g & gram \\ -time & s & second \\ -plane angle & rad & radian \\ -solid angle & sr & steradian \\ -temperature & K & Kelvin \\ -electric current & A & Ampere \\ -amount of substance & mol & mole \\ -luminous intensity & cd & candela \\ -\hline -\end{tabular} -\end{center} -\end{table} - -\begin{table}[htbp] -\begin{center} -\begin{small} -\begin{tabular}{|l|l|l|l|} -\hline -\multicolumn{4}{|c|}{{\large Derived units}} \\ \hline -\multicolumn{1}{|c|}{Quantity} & \multicolumn{1}{|c|}{Symbol} & -\multicolumn{1}{c|}{Full Name} & \multicolumn{1}{c|}{Definition} \\ \hline -area & barn & barn & 1.0E-28 m**2 \\ -area & pix & pixel & \\ -area & pixel & pixel & \\ -electric capacitance & F & Farad & C/V \\ -electric charge & C & Coulomb & A s \\ -electric conductance & S & Siemens & A/V \\ -electric potential & V & Volt & J/C \\ -electric resistance & Ohm & Ohm & V/A \\ -energy & J & Joule & N m \\ -energy & Ry & Rydberg & 13.605692 eV \\ -energy & eV & electron-Volt & 1.60217733E-19 J \\ -energy & erg & erg & 1.0E-7 J \\ -events & count & count & \\ -events & ct & count & \\ -events & ph & photon & \\ -events & photon & photon & \\ -flux density & Jy & Jansky & 1.0E-26 W /m**2 /Hz \\ -flux density & R & Rayleigh & 1.0E10/(4*PI) photon.m**-2 /s/sr \\ -flux density & mag & magnitude & \\ -force & N & Newton & kg m/s**2 \\ -frequency & Hz & Hertz & 1/s \\ -illuminance & lx & lux & lm/m**2 \\ -inductance & H & Henry & Wb/A \\ -length & AU & astronomical unit & 1.49598E11 m \\ -length & Angstrom & Angstrom & 1.0E-10 m \\ -length & lyr & light year & 9.460730E15 m \\ -length & pc & parsec & 3.0867E16 m \\ -length & solRad & solar radius & 6.9599E8 m \\ -luminosity & solLum & solar luminosity & 3.8268E26 W \\ -luminous flux & lm & lumen & cd sr \\ -magnetic field & G & Gauss & 1.0E-4 T \\ -magnetic flux & Wb & Weber & V s \\ -mass & solMass & solar mass & 1.9891E30 kg \\ -mass & u & unified atomic mass unit & 1.6605387E-27 kg \\ -magnetic flux density & T & Tesla & Wb/m**2 \\ -plane angle & arcmin & arc-minute & 1/60 deg \\ -plane angle & arcsec & arc-second & 1/3600 deg \\ -plane angle & mas & milli-arcsecond & 1/3600000 deg \\ -plane angle & deg & degree & pi/180 rad \\ -power & W & Watt & J/s \\ -pressure, stress & Pa & Pascal & N/m**2 \\ -time & a & year & 31557600 s \\ -time & d & day & 86400 s \\ -time & h & hour & 3600 s \\ -time & yr & year & 31557600 s \\ -time & min & minute & 60 s \\ - & D & Debye & 1.0E-29/3 C.m \\ -\hline -\end{tabular} -\end{small} -\end{center} -\end{table} - -\begin{table}[htbp] -\begin{center} -\begin{tabular}{|lll|lll|} -\hline -\multicolumn{6}{|c|}{{\large Prefixes for multiples \& -sub-multiples}} \\ \hline -\multicolumn{1}{|c}{Sub-multiple} & \multicolumn{1}{c}{Name} & -\multicolumn{1}{c|}{Prefix} & -\multicolumn{1}{|c}{Sub-multiple} & \multicolumn{1}{c}{Name} & -\multicolumn{1}{c|}{Prefix} \\ \hline -$10^{-1}$ & deci & d & $10$ & deca & da \\ -$10^{-2}$ & centi & c & $10^{2}$ & hecto & h \\ -$10^{-3}$ & milli & m & $10^{3}$ & kilo & k \\ -$10^{-6}$ & micro & u & $10^{6}$ & mega & M \\ -$10^{-9}$ & nano & n & $10^{9}$ & giga & G \\ -$10^{-12}$ & pico & p & $10^{12}$ & tera & T \\ -$10^{-15}$ & femto & f & $10^{15}$ & peta & P \\ -$10^{-18}$ & atto & a & $10^{18}$ & exa & E \\ -$10^{-21}$ & zepto & z & $10^{21}$ & zetta & Z \\ -$10^{-24}$ & yocto & y & $10^{24}$ & yotta & Y \\ -\hline -\end{tabular} -\end{center} -\end{table} - -\begin{table}[htbp] -\begin{center} -\begin{tabular}{|l|l|} -\hline -\multicolumn{2}{|c|}{{\large Mathematical operators \& functions}} \\ -\hline -\multicolumn{1}{|c|}{String} & \multicolumn{1}{|c|}{Meaning} \\ \hline -sym1 sym2 & multiplication (a space) \\ -sym1*sym2 & multiplication (an asterisk) \\ -sym1.sym2 & multiplication (a dot) \\ -sym1/sym2 & division \\ -sym1**y & exponentiation ($y$ must be a numerical constant)\\ -sym1\verb+^+y & exponentiation ($y$ must be a numerical constant)\\ -log(sym1) & common logarithm \\ -ln(sym1) & natural logarithm \\ -exp(sym1) & exponential \\ -sqrt(sym1) & square root \\ -\hline -\end{tabular} -\end{center} -\end{table} - -\subsubsection{Side-effects of Changing the Unit attribute} -If an Axis has an active Unit attribute, changing its value (either by -setting a new value or by clearing it so that the default value is -re-instated) may cause the Label and Symbol attributes to be changed -accordingly. For instance, if an Axis has Unit, Label and Symbol of ``Hz'', -``Frequency'' and ``nu'', then changing its Unit attribute to ``log(Hz)'' -will cause AST to change its Label and Symbol to ``log(Frequency)'' and -``Log(nu)''. These changes are only made if the Unit attribute is active, -and a Mapping can be found from the old units to the new units. On the other - hand, changing the Unit from ``Hz'' to ``MHz'' would not cause any change -to the Label or Symbol attributes. - -\cleardoublepage -\section{\label{ss:skyframes}Celestial Coordinate Systems (SkyFrames)} - -A Frame which is specialised for representing coordinate systems on -the celestial sphere is obviously of great importance in -astronomy. The SkyFrame is such a Frame. In this section we examine -the additional properties and behaviour of a SkyFrame that distinguish -it from a basic Frame (\secref{ss:frames}). - -\subsection{The SkyFrame Model} - -A SkyFrame is, of course, a Frame (\secref{ss:frames}) and also a -Mapping (\secref{ss:mappings}), so it inherits all the properties and -behaviour of these two ancestral classes. When used as a Mapping, a -SkyFrame implements a unit transformation, exactly like a basic Frame -(\secref{ss:frameasmapping}) or a UnitMap, so this aspect of its -behaviour is not of great importance. - -When used as a Frame, however, a SkyFrame represents a 2-dimensional -\emph{spherical} coordinate system, in which the shortest distance -between two points is a great circle. A SkyFrame therefore always has -exactly two axes which represent the longitude and latitude of a -coordinate system residing on the celestial sphere. Many such -coordinate systems can be represented by a SkyFrame, as we will see -shortly. - -A SkyFrame can represent any of the commonly used celestial coordinate -systems. Optionally, the origin of the longitude/latitude system can be -moved to any specified point in the standard celestial system, allowing -a SkyFrame to represent offsets from a specified sky position. - -c+ -When it is first created, a SkyFrame's axes are always in the order -(longitude,~latitude) but this can be changed, if required, by using the -astPermAxes function (\secref{ss:permutingaxes}). The order of the axes -can be determined at any time using the LatAxis and LonAxis attributes. A -SkyFrame's coordinate values are always stored as angles in (double -precision) radians, regardless of the setting of the Unit attribute -c- -f+ -When it is first created, a SkyFrame's axes are always in the order -(longitude,~latitude) but this can be changed, if required, by using the -AST\_PERMAXES routine (\secref{ss:permutingaxes}). The order of the axes -can be determined at any time using the LatAxis and LonAxis attributes. A -SkyFrame's coordinate values are always stored as angles in (double -precision) radians, regardless of the setting of the Unit attribute -f- -\footnote{The units used for the internal floating-point representation of an -axis value can be determined by examining the InternalUnit attribute of -the Frame. For most Frames, the Unit and InternalUnit attributes will be -equal, but InternalUnit is always set to ``\texttt{rad}'' for SkyFrames.}. - -\subsection{Creating a SkyFrame} - -The SkyFrame constructor function is particularly simple and a -SkyFrame with default attributes is created as follows: - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstSkyFrame *skyframe; - -... - -skyframe = astSkyFrame( "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER SKYFRAME, STATUS - - STATUS = 0 - - ... - - SKYFRAME = AST_SKYFRAME( ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -Such a SkyFrame would represent the default celestial coordinate -system which, at present, is the ICRS system (the default was "FK5(J2000)" -in versions of AST prior to 3.0). - -\subsection{Specifying a Particular Celestial Coordinate System} - -For many purposes, the ICRS coordinate system is perfectly -adequate. In order to support conversion between a variety of -celestial coordinate systems, however, you can create SkyFrames that -represent any of these. - -Selection of a particular coordinate system is performed simply by -setting a value for the SkyFrame's (character string) System -attribute. This setting is most conveniently done when the SkyFrame is -created. For example, a SkyFrame representing the old FK4~(B1950.0) -coordinate system would be created by: - -c+ -\small -\begin{terminalv} -skyframe = astSkyFrame( "System=FK4" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - SKYFRAME = AST_SKYFRAME( 'System=FK4', STATUS ) -\end{terminalv} -\normalsize -f- - -Note that specifying ``System$=$FK4'' also changes the associated -equinox (from J2000.0 to B1950.0). This is because the default value -of the SkyFrame's Equinox attribute (\secref{ss:equinoxitem}) depends -on the System attribute setting. - -You may change the System value at any time, although this is not -usually needed. The values supported are set out in the attribute's -description in \appref{ss:attributedescriptions} and include a variety -of equatorial coordinate systems, together with ecliptic and galactic -coordinates. - -General spherical coordinates are supported by specifying -``System$=$unknown''. You should note, though, that no Mapping can be -created to convert between ``unknown'' coordinates and any of the other -celestial coordinate systems (see \secref{ss:introducingconversion} ). - -\subsection{Attributes which Qualify Celestial Coordinate Systems} - -Many celestial coordinate systems have some additional free parameters -which serve to identify a particular coordinate system from amongst a -broader class of related coordinate systems. For example, the -FK5~(J2010.0) system is distinguished from the FK5~(J2000.0) -system by a different equinox---and the coordinates of a fixed -astronomical source would have different values when expressed in -these two systems. - -In AST, these free parameters are represented by additional SkyFrame -attributes, each of which has a default appropriate to -(\emph{i.e.}\ defined by) the setting of the main System -attribute. Each of these \emph{qualifying attributes} may, however, be -assigned an explicit value so as to select a particular coordinate -system. Note, it is usually best to assign explicit -values whenever possible rather than relying on defaults. Attribute -should only be left at their default value if you ``don't care'' what -value is used. In certain circumstances (particularly, when aligning two -Frames), a default value for an attribute may be replaced by the value -from another similar Frame. Such value replacement can be prevented by -assigning an explicit value to the attribute, rather than simply relying on -the default. - - -The main SkyFrame attributes which qualify the System attribute are: - -\begin{quote} -\begin{description} - -\item[\label{ss:epochitem}Epoch]\mbox{}\\ -This attribute is inherited from the Frame class. It gives the moment in -time when the coordinates are correct for the astronomical source -under study (usually the date of observation). - -\item[\label{ss:equinoxitem}Equinox]\mbox{}\\ -This value is used to qualify celestial coordinate systems that are -notionally based on the Earth's equator and/or the ecliptic (the plane -of the Earth's orbit around the Sun). The position of either of these -planes is difficult to specify precisely, so in practice a model -\emph{mean} equator and/or ecliptic are used instead. These, together -with the point on the sky that defines the coordinate origin (termed -the \emph{mean equinox}) move with time according to some model which -smoothes out the more rapid fluctuations. The SkyFrame class supports -both the old FK4 model and the newer FK5 one. - -Coordinates expressed in any of these systems vary with time due to -movement (by definition) of the coordinate system itself, and must -therefore be qualified by a moment in time (the \emph{epoch of the mean -equinox}, or ``equinox'' for short) which specifies the position of -the model coordinate system on the sky. This is the role of the -Equinox attribute. - -Note that it is quite valid and common to relate the position of a -source to an equinox other than the date of observation. Usually a -standard equinox such as J2000.0 is used, meaning that the coordinates -are referred to axes defined by where the model mean equator and -ecliptic would lie on the sky at the Julian epoch J2000.0. -\end{description} -\end{quote} - -For further details of these attributes you should consult their -descriptions in \appref{ss:attributedescriptions} and for details of -the System settings for which they are relevant, see the description -of the System attribute (also in \appref{ss:attributedescriptions}). -For the interested reader, an excellent overview of celestial -coordinate systems can also be found in the documentation for the -SLALIB library (\xref{SUN/67}{sun67}{}). - -The value of these qualifying attributes is most conveniently set at -the same time as the System value, \emph{e.g.}\ when a SkyFrame is -created. For instance: - -c+ -\small -\begin{terminalv} -skyframe = astSkyFrame( "System=Ecliptic, Equinox=J2005.5" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - SKYFRAME = AST_SKYFRAME( 'System=Ecliptic, Equinox=J2005.5', STATUS ) -\end{terminalv} -\normalsize -f- - -would create a SkyFrame representing an ecliptic coordinate system -referred to the mean equinox and ecliptic of Julian epoch J2005.5. - -Note that it does no harm to assign values to qualifying attributes -which are not relevant to the main System value. Any such values are -stored, but are not used unless the System value is later set so that -they become relevant. - -\subsection{Using Default SkyFrame Attributes} - -c+ -The default values supplied for many SkyFrame attributes will depend -on the value of the SkyFrame's System attribute. In practice, this -means that there is usually little need to specify many of these -attributes explicitly unless you have some special requirement. This -can be illustrated by using astShow to examine a SkyFrame, as follows: -c- -f+ -The default values supplied for many SkyFrame attributes will depend -on the value of the SkyFrame's System attribute. In practice, this -means that there is usually little need to specify many of these -attributes explicitly unless you have some special requirement. This -can be illustrated by using AST\_SHOW to examine a SkyFrame, as -follows: -f- - -c+ -\small -\begin{terminalv} -astShow( astSkyFrame( "System=FK4-NO-E, Epoch=1958" ) ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SHOW( AST_SKYFRAME( 'System=FK4-NO-E, Epoch=1958', STATUS ), STATUS ) -\end{terminalv} -\normalsize -f- - -The output from this might look like the following: - -\begin{terminalv} - Begin SkyFrame # Description of celestial coordinate system -# Title = "FK4 equatorial coordinates; no E-terms; mean equinox B1950.0; -epoch B1958.0" # Title of coordinate system - Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain - Epoch = 1958 # Besselian epoch of observation -# Lbl1 = "Right ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 - System = "FK4-NO-E" # Coordinate system type -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction -# Bot2 = -1.5707963267949 # Lowest legal axis value -# Top2 = 1.5707963267949 # Highest legal axis value - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description -# Eqnox = 1950 # Besselian epoch of mean equinox - End SkyFrame -\end{terminalv} - -Note that the defaults (indicated by the ``\verb?#?'' comment -character at the start of the line) for attributes such as the Title, -axis Labels and Format specifiers are all set to values appropriate -for the particular equatorial coordinate system that the SkyFrame -represents. - -c+ -This means, for example, that if we were to use this SkyFrame to -format a right ascension value stored in radians using astFormat -(\secref{ss:formattingaxisvalues}), it would automatically result in a -string in sexagesimal notation (such as ``12:14:35.7'') suitable for -display. If we changed the value of the SkyFrame's Digits attribute -(which is inherited from the Frame class), the number of digits -appearing would also change accordingly. -c- -f+ -This means, for example, that if we were to use this SkyFrame to -format a right ascension value stored in radians using AST\_FORMAT -(\secref{ss:formattingaxisvalues}), it would automatically result in a -string in sexagesimal notation (such as ``12:14:35.7'') suitable for -display. If we changed the value of the SkyFrame's Digits attribute -(which is inherited from the Frame class), the number of digits -appearing would also change accordingly. -f- - -These choices would be appropriate for a System value of ``FK4-NO-E'', -but if a different System value were set, the defaults would be -correspondingly different. For example, ecliptic longitude is -traditionally expressed in degrees, so setting ``System=ecliptic'' -would result in coordinate values being formatted as degrees by -default. - -Of course, if you do not like any of these defaults, you may always -over-ride them by setting explicit attribute values yourself. - -\subsection{\label{ss:formattingskyaxisvalues}Formatting Celestial Coordinates} - -c+ -SkyFrames use astFormat for formatting coordinate values in the same -way as other Frames (\secref{ss:formattingaxisvalues}). However, they -offer a different set of formatting options more appropriate to -celestial coordinates. -c- -f+ -SkyFrames use AST\_FORMAT for formatting coordinate values in the same -way as other Frames (\secref{ss:formattingaxisvalues}). However, they -offer a different set of formatting options more appropriate to -celestial coordinates. -f- - -The Digits attribute of a SkyFrame behaves in essentially the same way -as for a basic Frame (\secref{ss:formattingwithdigits}), so the -precision with which celestial coordinates are displayed can also be -adjusted in this way. However, the range of format specifiers that can -be given for the Format(axis) attribute, and the default format -resulting from any particular Digits value, is different. - -The syntax of SkyFrame format specifiers is detailed under the -description of the Format(axis) attribute in -\appref{ss:attributedescriptions}. Briefly, however, it allows -celestial coordinates to be expressed either as angles or times and to -include one or more of the fields: - -\begin{quote} -\begin{itemize} -\item degrees or hours -\item arc-minutes or minutes -\item arc-seconds or seconds -\end{itemize} -\end{quote} - -with a specified number of decimal places for the final field. A range -of field separators is also available, as the following examples show: - -\begin{quote} -\begin{center} -\begin{tabular}{|l|l|} -\hline -\textbf{Format Specifier} & \textbf{Example Formatted Value}\\ -\hline \hline -{\tt{d}} & {\tt{219}}\\ -{\tt{d.3}} & {\tt{219.123}}\\ -{\tt{dm}} & {\tt{219:05}}\\ -{\tt{dm.2}} & {\tt{219:05.44}}\\ -{\tt{dms}} & {\tt{219:05:42}}\\ -{\tt{hms.1}} & {\tt{15:44:13.8}}\\ -{\tt{bdms.2}} & {\tt{219 05 42.81}}\\ -{\tt{lhms.3}} & {\tt{15h44m13.88s}}\\ -{\tt{+zlhms}} & {\tt{+06h10m44s}}\\ -{\tt{ms.1}} & {\tt{13145:42.8}}\\ -{\tt{lmst.3}} & {\tt{876m22.854s}}\\ -{\tt{s.2}} & {\tt{788742.81}}\\ -\hline -\end{tabular} -\end{center} -\end{quote} - -Note the following key points: - -\begin{itemize} -\item The required fields are specified using characters chosen from -either ``dms'' or ``hms'' according to whether the value is to be -formatted as an angle (in degrees) or a time (in hours). - -\item If no degrees or hours field is required, the distinction -between angle and time may be made by including ``t'' to request time. - -\item The number of decimal places (for the final field) is indicated -using ``\texttt{.}'' followed by an integer. An asterisk can be used in -place of an integer, in which case the number of decimal places is -chosen so that the total number of digits in the formatted value is equal -to the value of the Digits attribute. - -\item ``b'' causes fields to be separated by blanks, while ``l'' -causes them to be separated by the appropriate letters (the default -being a colon). - -\item ``z'' causes padding with leading zeros. - -\item ``+'' cause a plus sign to be prefixed to positive values -(negative values always have a minus sign). -\end{itemize} - -The formatting performed by a SkyFrame is also influenced by the -AsTime(axis) attribute, which has a boolean (integer) value for each -SkyFrame axis. It determines whether the default format specifier for -an axis will present values as angles (\emph{e.g.}\ in degrees) if it -is zero, or as times (\emph{e.g.}\ in hours) if it is non-zero. - -The default AsTime value depends on the celestial coordinate system -which the SkyFrame represents which, in turn, depends on its System -attribute value. For example, equatorial longitude values (right -ascension) are normally expressed in hours, whereas ecliptic -longitudes are normally expressed in degrees, so their default AsTime -values will reflect this difference. - -The value of the AsTime attribute may be set explicitly to over-ride -these defaults if required, with the formatting precision being -determined by the Digits/Digits(axis) value. Alternatively, the -Format(axis) attribute may be set explicitly to specify both the -format and precision required. Setting an explicit Format value always -over-rides the effects of both the Digits and AsTime attributes (unless -the Format value does not specify the required number of decimal places, -in which case Digits is used to determine the default number of decimal -places) - -\subsection{\label{ss:unformattingskyaxisvalues}Reading Formatted Celestial Coordinates} - -c+ -The process of converting formatted celestial coordinates, such as -might be produced by the astFormat function -(\secref{ss:formattingskyaxisvalues}), into numerical (double) -coordinate values is performed by using astUnformat -(\secref{ss:unformattingaxisvalues}) and passing it a pointer to a -SkyFrame. The use of a SkyFrame means that the range of input formats -accepted is appropriate to positions on the sky expressed as angles -and/or times, while the returned value is in radians. -c- -f+ -The process of converting formatted celestial coordinates, such as -might be produced by the AST\_FORMAT function -(\secref{ss:formattingskyaxisvalues}), into numerical (double -precision) coordinate values is performed by using AST\_UNFORMAT -(\secref{ss:unformattingaxisvalues}) and passing it a pointer to a -SkyFrame. The use of a SkyFrame means that the range of input formats -accepted is appropriate to positions on the sky expressed as angles -and/or times, while the returned value is in radians. -f- - -The following describes the forms of celestial coordinate which are -supported: - -\begin{itemize} -\item You may supply an optional sign, followed by between one and -three fields representing either degrees, arc-minutes, arc-seconds or -hours, minutes, seconds (\emph{e.g.}\ ``$-$12~42~03''). - -\item Each field should consist of a sequence of one or more digits, -which may include leading zeros. At most one field may contain a -decimal point, in which case it is taken to be the final field -(\emph{e.g.}\ decimal degrees might be given as ``124.707'', while -degrees and decimal arc-minutes might be given as ``$-$13~33.8''). - -\item The first field given may take any value, allowing angles and -times outside the conventional ranges to be represented. However, -subsequent fields must have values of less than 60 (\emph{e.g.} -``720~45~31'' is valid, whereas ``11~45~61'' is not). - -\item Fields may be separated by white space or by ``:'' (colon), but -the choice of separator must be used consistently throughout the -value. Additional white space may be present around fields and -separators (\emph{e.g.}\ ``$-$~2:~04~:~7.1''). - -\item The following field identification characters may be used as -separators to replace those above (or may be appended to the final -field), in order to identify the field to which they are appended: - -\begin{quote} -\begin{tabular}{lll} -d & -- & degrees \\ -h & -- & hours \\ -m & -- & minutes (of arc or time) \\ -s & -- & seconds (of arc or time) \\ -\texttt{'} & -- & arc-minutes \\ -\texttt{"} & -- & arc-seconds -\end{tabular} -\end{quote} - -Either lower or upper case may be used. Fields must be given in order -of decreasing significance -(\emph{e.g.}\ ``$-$11D~3\texttt{'}~14.4\texttt{"}'' or ``22h14m11.2s''). - -\item The presence of certain field identification characters -indicates whether the value is to be interpreted as an angle or a time -(with 24 hours corresponding to 360 degrees), as follows: - -\begin{quote} -\begin{tabular}{lll} -d & -- & angle \\ -\texttt{'} & -- & angle \\ -\texttt{"} & -- & angle \\ -h & -- & time -\end{tabular} -\end{quote} - -Incompatible angle/time identification characters may not be mixed -(\emph{e.g.}\ ``10h14\texttt{'}3\texttt{"}'' is not valid). The remaining -field identification characters and separators do not specify a -preference for an angle or a time and may be used with either. - -c+ -\item If no preference for an angle or a time is expressed anywhere -within the value, then it is interpreted as an angle if the Format -attribute string associated with the SkyFrame axis generates an angle -and as a time otherwise. This ensures that values produced by -astFormat (\secref{ss:formattingskyaxisvalues}) are correctly -interpreted by astUnformat. -c- -f+ -\item If no preference for an angle or a time is expressed anywhere -within the value, then it is interpreted as an angle if the Format -attribute string associated with the SkyFrame axis generates an angle -and as a time otherwise. This ensures that values produced by -AST\_FORMAT (\secref{ss:formattingskyaxisvalues}) are correctly -interpreted by AST\_UNFORMAT. -f- - -\item Fields may be omitted, in which case they default to zero. The -remaining fields may be identified by using appropriate field -identification characters (see above) and/or by adding extra colon -separators (e.g. ``$-$05m13s'' is equivalent to ``$-$:05:13''). If a field -is not identified explicitly, it is assumed that adjacent fields have -been given, after taking account of any extra separator -characters. For example: - -\begin{quote} -\begin{tabular}{lll} -10d & -- & degrees \\ -10d12 & -- & degrees and arc-minutes \\ -11:14\texttt{"} & -- & arc-minutes and arc-seconds \\ -9h13s & -- & hours and seconds of time \\ -:45:33 & -- & minutes and seconds (of arc or time) \\ -:55: & -- & minutes (of arc or time) \\ -::13 & -- & seconds (of arc or time) \\ -$-$6::2.5 & -- & degrees/hours and seconds (of arc or time) \\ -07m14 & -- & minutes and seconds (of arc or time) \\ -$-$8:14\texttt{'} & -- & degrees and arc-minutes \\ -$-$h3:14 & -- & minutes and seconds of time \\ -h:2.1 & -- & seconds of time -\end{tabular} -\end{quote} - -c+ -\item If fields are omitted in such a way that the remaining ones -cannot be identified uniquely (e.g. ``01:02''), then the first field -(either given explicitly or implied by an extra leading colon -separator) is taken to be the most significant field that astFormat -would produce when formatting a value (using the Format attribute -associated with the SkyFrame axis). By default, this means that the -first field will normally be interpreted as degrees or hours. However, -if this does not result in consistent field identification, then the -last field (either given explicitly or implied by an extra trailing -colon separator) is taken to to be the least significant field that -astFormat would produce. -c- -f+ -\item If fields are omitted in such a way that the remaining ones -cannot be identified uniquely (e.g. ``01:02''), then the first field -(either given explicitly or implied by an extra leading colon -separator) is taken to be the most significant field that AST\_FORMAT -would produce when formatting a value (using the Format attribute -associated with the SkyFrame axis). By default, this means that the -first field will normally be interpreted as degrees or hours. However, -if this does not result in consistent field identification, then the -last field (either given explicitly or implied by an extra trailing -colon separator) is taken to to be the least significant field that -AST\_FORMAT would produce. -f- - -\end{itemize} - -c+ -This final convention is intended to ensure that values formatted by -astFormat which contain less than three fields will be correctly -interpreted if read back using astUnformat, even if they do not -contain field identification characters. However, it also affects -other forms of input. For example, if the Format(axis) string were set -to ``mst.1'' (producing two fields representing minutes and seconds of -time), then formatted input would be interpreted by astUnformat as -follows: -c- -f+ -This final convention is intended to ensure that values formatted by -AST\_FORMAT which contain less than three fields will be correctly -interpreted if read back using AST\_UNFORMAT, even if they do not -contain field identification characters. However, it also affects -other forms of input. For example, if the Format(axis) string were set -to ``mst.1'' (producing two fields representing minutes and seconds of -time), then formatted input would be interpreted by AST\_UNFORMAT as -follows: -f- - -\begin{quote} -\begin{tabular}{lll} -12 13 & -- & minutes and seconds \\ -12 & -- & minutes \\ -:13 & -- & seconds \\ -$-$18: & -- & minutes \\ -12.8 & -- & minutes \\ -1 2 3 & -- & hours, minutes and seconds \\ -& & \\ -4\texttt{'} & -- & arc-minutes \\ -60::\texttt{"} & -- & degrees \\ -$-$23:\texttt{"} & -- & arc-minutes \\ -$-$33h & -- & hours -\end{tabular} -\end{quote} - -(in the last four cases, explicit field identification has been given -which overrides the implicit identification). - -c+ -Alternatively, if the Format(axis) string were set to ``s.3'' -(producing only an arc-seconds field), then formatted input would be -interpreted by astUnformat as follows: -c- -f+ -Alternatively, if the Format(axis) string were set to ``s.3'' -(producing only an arc-seconds field), then formatted input would be -interpreted by AST\_UNFORMAT as follows: -f- - -\begin{quote} -\begin{tabular}{lll} -12.8 & -- & arc-seconds \\ -12 13 & -- & arc-minutes and arc-seconds \\ -:12 & -- & arc-seconds \\ -13: & -- & arc-minutes \\ -1 2 3 & -- & degrees, arc-minutes and arc-seconds -\end{tabular} -\end{quote} - -In general, if you are preparing formatted input data containing -celestial coordinates and wish to omit certain fields, then you are -advised to identify clearly those that you do provide by using the -appropriate field identification characters and/or extra colon -separators. This prevents you depending on the implicit field -identification described above which, in turn, depends on an -appropriate Format(axis) string having been set. - -When writing software, it is also a good idea to set the Format(axis) -string so that data input will be as simple as possible for the -user. Unless some special effect is desired, this normally means that -it should contain ``d'' or ``h'' to ensure that the first field -entered by the user will be interpreted as degrees or hours, unless -otherwise identified. This is the normal behaviour unless an explicit -Format(axis) value has been set to override the default. - -\subsection{Representing Offsets from a Specified Sky Position} -A SkyFrame can be modified so that its longitude and latitude axes are -referred to an origin at any specified sky position. Such a coordinate -system is referred to as an ``offset'' coordinate system. First, the System -attribute should be set to represent the celestial coordinate system in -which the origin is to be specified. Then the SkyRef attribute should be -set to hold the coordinates of the origin within the selected celestial -coordinate system. - -By default, ``north'' in the new offset coordinate system is parallel to -north in the original celestial coordinate system. However, the direction -of north in the offset system can be controlled by assigning a value to -the SkyRefP attribute. This attribute should be assigned the celestial -coordinates of a point which is on the zero longitude meridian and which -has non-zero latitude. - -By default, the position given by the SkyRef attribute is used as the -origin of the new longitude/latitude system, but an option exists to use -it as the north pole of the system instead. This option is controlled by -the SkyRefIs attribute. The choice of value for SkyRefIs depends on what -sort of offset coordinate system you want. Setting SkyRefIs to -``Origin'' (the default) produces an offset coordinate system which is -approximately Cartesian close to the specified position. Setting SkyRefIs -to -``Pole'' produces an offset coordinate system which is approximately Polar -close to the specified position. - -\cleardoublepage -\section{\xlabel{ss_specframes}\label{ss:specframes}Spectral Coordinate Systems (SpecFrames)} - -The SpecFrame is a Frame which is specialised for representing coordinate -systems which describe a position within an electro-magnetic spectrum. -In this section we examine the additional properties and behaviour of a -SpecFrame that distinguish it from a basic Frame (\secref{ss:frames}). - -\subsection{The SpecFrame Model} - -As for a SkyFrame, a SpecFrame is a Frame (\secref{ss:frames}) and also a -Mapping (\secref{ss:mappings}), so it inherits all the properties and -behaviour of these two ancestral classes. When used as a Mapping, a -SpecFrame implements a unit transformation, exactly like a basic Frame -(\secref{ss:frameasmapping}) or a UnitMap, so this aspect of its -behaviour is not of great importance. - -When used as a Frame, however, a SpecFrame represents a wide range of -different 1-dimensional coordinate system which can be used to describe -positions within a spectrum. The options available largely mirror those -described in the FITS-WCS paper III \emph{Representations of spectral -coordinates in FITS} (Greisen, Valdes, Calabretta \& Allen). - -\subsection{Creating a SpecFrame} - -The SpecFrame constructor function is particularly simple and a -SpecFrame with default attributes is created as follows: - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstSpecFrame *specframe; - -... - -specframe = astSpecFrame( "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER SPECFRAME, STATUS - - STATUS = 0 - - ... - - SPECFRAME = AST_SPECFRAME( ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -Such a SpecFrame would represent the default coordinate system which is -heliocentric wavelength in metres (i.e. wavelength corrected to take into -account the Doppler shift caused by the velocity of the observer around the -sun). - -\subsection{Specifying a Particular Spectral Coordinate System} - -Selection of a particular coordinate system is performed simply by -setting a value for the SpecFrame's (character string) System -attribute. This setting is most conveniently done when the SpecFrame is -created. For example, a SpecFrame representing Energy would be created by: - -c+ -\small -\begin{terminalv} -specframe = astSpecFrame( "System=Energy" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - SPECFRAME = AST_SPECFRAME( 'System=Energy', STATUS ) -\end{terminalv} -\normalsize -f- - -Note that specifying ``System$=$Energy'' also changes the associated -Unit (from metres to Joules). This is because the default value -of the SpecFrame's Unit attribute depends on the System attribute setting. - -You may change the System value at any time, although this is not -usually needed. The values supported are set out in the attribute's -description in \appref{ss:attributedescriptions} and include a variety -of velocity systems, together with frequency, wavelength, energy, -wave-number, \emph{etc}. - -\subsection{Attributes which Qualify Spectral Coordinate Systems} - -Many spectral coordinate systems have some additional free parameters -which serve to identify a particular coordinate system from amongst a -broader class of related coordinate systems. For example, the -velocity systems are all parameterised by a rest frequency---the -frequency which defines zero velocity, and all coordinate systems -are qualified by a `standard of rest'' which indicates the rest frame to -which the values refer. - -In AST, these free parameters are represented by additional SpecFrame -attributes, each of which has a default appropriate to -(\emph{i.e.}\ defined by) the setting of the main System -attribute. Each of these \emph{qualifying attributes} may, however, be -assigned an explicit value so as to select a particular coordinate -system. Note, it is usually best to assign explicit -values whenever possible rather than relying on defaults. Attribute -should only be left at their default value if you ``don't care'' what -value is used. In certain circumstances (particularly, when aligning two -Frames), a default value for an attribute may be replaced by the value -from another similar Frame. Such value replacement can be prevented by -assigning an explicit value to the attribute, rather than simply relying on -the default. - - -The main SpecFrame attributes which qualify the System attribute are: - -\begin{quote} -\begin{description} - -\item[Epoch]\mbox{}\\ -This attribute is inherited from the Frame class. It gives the moment in -time when the coordinates are correct for the astronomical source -under study (usually the date of observation). It is needed in order to -calculate the Doppler shift produced by the velocity of the observer -relative to the centre of the earth, and of the earth relative to the sun. - -\item[StdOfRest]\mbox{}\\ -This specifies the rest frame in which the coordinates are correct. -Transforming between different standards of rest involves taking account -of the Doppler shift introduced by the relative motion of the two -standards of rest. - -\item[RestFreq]\mbox{}\\ -Specifies the frequency which correspond to zero velocity. When setting a -value for this attribute, the value may be supplied as a wavelength -(including an indication of the units being used, ``nm'' ``Angstrom'', -\emph{etc.}), which will be automatically be converted to a frequency. - -\item[RefRA]\mbox{}\\ -Specifies the RA (FK5 J2000) of the source. This is used when converting -between standards of rest. It specifies the direction along which the -component of the relative velocity of the two standards of rest is taken. - -\item[RefDec]\mbox{}\\ -Specifies the Dec (FK5 J2000) of the source. Used in conjunction with -REFRA. - -\item[SourceVel]\mbox{}\\ -This defines the ``source'' standard of rest. This is a rest frame which -is moving towards the position given by RefRA and RefDec, at a velocity -given by SourceVel. The velocity is stored internally as a heliocentric -velocity, but can be given in any of the other supported standards of rest. - -\end{description} -\end{quote} - -For further details of these attributes you should consult their -descriptions in \appref{ss:attributedescriptions} and for details of -the System settings for which they are relevant, see the description -of the System attribute (also in \appref{ss:attributedescriptions}). - -Note that it does no harm to assign values to qualifying attributes -which are not relevant to the main System value. Any such values are -stored, but are not used unless the System value is later set so that -they become relevant. - -\subsection{Using Default SpecFrame Attributes} - -c+ -The default values supplied for many SpecFrame attributes will depend -on the value of the SpecFrame's System attribute. In practice, this -means that there is usually little need to specify many of these -attributes explicitly unless you have some special requirement. This -can be illustrated by using astShow to examine a SpecFrame, as follows: -c- -f+ -The default values supplied for many SpecFrame attributes will depend -on the value of the SpecFrame's System attribute. In practice, this -means that there is usually little need to specify many of these -attributes explicitly unless you have some special requirement. This -can be illustrated by using AST\_SHOW to examine a SpecFrame, as -follows: -f- - -c+ -\small -\begin{terminalv} -astShow( astSpecFrame( "System=Vopt, RestFreq=250 GHz" ) ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SHOW( AST_SPECFRAME( 'System=Vopt, RestFreq=250 GHz', STATUS ), - : STATUS ) -\end{terminalv} -\normalsize -f- - -The output from this might look like the following: - -\begin{terminalv} - Begin SpecFrame # Description of spectral coordinate system -# Title = "Optical velocity, rest frequency = 250 GHz" # Title -of coordinate system - Naxes = 1 # Number of coordinate axes -# Domain = "SPECTRUM" # Coordinate system domain -# Epoch = 2000 # Julian epoch of observation -# Lbl1 = "Optical velocity" # Label for axis 1 - System = "VOPT" # Coordinate system type -# Uni1 = "km/s" # Units for axis 1 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - End Axis - IsA Frame # Coordinate system description -# SoR = "Heliocentric" # Standard of rest - RstFrq = 250000000000 # Rest frequency (Hz) - End SpecFrame -\end{terminalv} - -Note that the defaults (indicated by the ``\verb?#?'' comment -character at the start of the line) for attributes such as the Title, -axis Labels and Unit specifiers are all set to values appropriate -for the particular velocity system that the SpecFrame represents. - -These choices would be appropriate for a System value of ``Vopt'', -but if a different System value were set, the defaults would be -correspondingly different. For example, by default frequency is measured in -units of GHz, not $km/s$, so setting ``System=freq'' -would change the appropriate line above from: - -\begin{terminalv} -# Uni1 = "km/s" # Units for axis 1 -\end{terminalv} - -to - -\begin{terminalv} -# Uni1 = "GHz" # Units for axis 1 -\end{terminalv} - -Of course, if you do not like any of these defaults, you may always -over-ride them by setting explicit attribute values yourself. For -instance, you may choose to have your frequency axis expressed in ``kHz'' -rather than ``GHz''. To do this simply set the attribute value as follows: - -c+ -\small -\begin{terminalv} -astSetC( specframe, "Unit", "kHz" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SETC( SPECFRAME, 'Unit', 'kHz', STATUS ) -\end{terminalv} -\normalsize -f- - -No error will be reported if you accidentally set an inappropriate Unit value -(say "J" - Joules)---after all, AST cannot tell what you are about to do, -and you \emph{may} be about to change the System value to ``Energy''. -However, an error \emph{will} be reported if you attempt to find a -conversion between two SpecFrames (for instance using -c+ -astConvert -c- -f+ -AST\_CONVERT -f- -) if either SpecFrame has a Unit value which is inappropriate for its -System value. - -SpecFrame attributes, like all other attributes, all have default -value. However, be aware that for some attributes these default values -can never be more than ``a legal numerical value'' and have no -astronomical significance. For instance, the RefRA and RefDec attributes -(which give the source position) both have a default value of zero. So -unless your source happens to be at that point (highly unlikely!) you will -need to set new values. Likewise, the RestFreq (rest frequency) attribute -has an arbitrary default value of 1.0E5 GHz. Some operations are not -affected by inappropriate values for these attributes (for instance, -converting from frequency to wavelength, changing axis units, \emph{etc}), -but some are. For instance, converting from frequency to velocity -requires a correct rest frequency, moving between different standards of -rest requires a correct source position. The moral is, always set explicit -values for as many attributes as possible. - -\subsection{\label{ss:creatingspectralcubes}Creating Spectral Cubes} -You can use a SpecFrame to describe the spectral axis in a data cube -containing two spatial axes and a spectral axis. To do this you would -create an appropriate SpecFrame, together with a 2-dimensional Frame -(often a SkyFrame) to describe the spatial axes. You would then combine -these two Frames together into a single CmpFrame. - -c+ -\small -\begin{terminalv} -AstSkyFrame *skyframe; -AstSpecFrame *specframe; -AstCmpFrame *cmpframe; -... -skyframe = astSkyFrame( "Epoch=J2002" ); -specframe = astSpecFrame( "System=Freq,StdOfRest=LSRK" ); -cmpframe = astCmpFrame( skyframe, specframe, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER SKYFRAME - INTEGER SPECFRAME - INTEGER CMPFRAME - ... - SKYFRAME = AST_SKYFRAME( 'Epoch=J2002', STATUS ) - SPECFRAME = AST_SPECFRAME( 'System=Freq,StdOfRest=LSRK', - : STATUS ) - CMPFRAME = AST_CMPFRAME( SKYFRAME, SPECFRAME, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -In the resulting CmpFrame, axis 1 will be RA, axis 2 will be Dec and axis -3 will be Frequency. If this is not the order you want, you can permute -the axes using -c+ -astPermAxes. -c- -f+ -AST\_PERMAXES. -f- - -There is one potential problem with this approach if you are interested in -unusually high accuracy. Conversion between different standards of rest -involves taking account of the Doppler shift caused by the relative -motion of the two standards of rest. At some point this involves finding -the component of the relative velocity in the direction of interest. -For a SpecFrame, this direction is always given by the RefRA and RefDec -attributes, even if the SpecFrame is embedded within a CmpFrame as above. -It would be more appropriate if this ``direction of interest'' was -specified by the values passed into the CmpFrame on the RA and DEC axes, -allowing each pixel within a data cube to have a slightly different -correction for Doppler shift. - -Unfortunately, the SpecFrame class cannot do this (since it is purely a -1-dimensional Frame), and so some small degree of error will be -introduced when converting between standards of rest, the size of the -error varying from pixel to pixel. It is hoped that at some point in the -future a sub-class of CmpFrame (a SpecCubeFrame) will be added to AST which -allows for this spatial variation in Doppler shift. - -The maximum velocity error introduced by this problem is of the order of -$V*SIN(FOV)$, where $FOV$ is the angular field of view, and $V$ is the -relative velocity of the two standards of rest. As an example, when -correcting from the observers rest frame (i.e. the topocentric rest -frame) to the kinematic local standard of rest the maximum value of $V$ -is about 20 $km/s$, so for 5 arc-minute field of view the maximum -velocity error introduced by the correction will be about 0.03 $km/s$. As -another example, the maximum error when correcting from the observers -rest frame to the local group is about 5 $km/s$ over a 1 degree field of -view. - -\subsection{\label{ss:handlingdualsidebandspectra}Handling Dual-Sideband Spectra} -Dual sideband super-heterodyne receivers produce spectra in which each channel -contains contributions from two different frequencies, referred to as the -``upper sideband frequency'' and the ``lower sideband frequency''. In the -rest frame of the observer (topocentric), these are related to each other as -follows: - -\begin{quote} -\begin{small} -\begin{equation} -\label{eqn:dsb} - f_{lsb} = 2.f_{LO} - f_{usb} -\end{equation} -\end{small} -\end{quote} - -where $f_{LO}$ is a fixed frequency known as the ``local oscillator -frequency''. In other words, the local oscillator frequency is always -mid-way between any pair of corresponding upper and lower sideband -frequencies\footnote{Note, this simple relationship only applies if all -frequencies are topocentric.}. If you want to describe the spectral axis -of such a spectrum using a SpecFrame you must choose whether you want the -SpecFrame to describe $f_{lsb}$ or $f_{usb}$ - a basic SpecFrame cannot -describe both sidebands simultaneously. However, there is a sub-class of -SpecFrame, called DSBSpecFrame, which overcomes this difficulty. - -A DSBSpecFrame has a SideBand attribute which indicates if the -DSBSpecFrame is currently being used to describe the upper or lower -sideband spectral axis. The value of this attribute can be changed at any -time. If you use the -c+ -astConvert -c- -f+ -AST\_CONVERT -f- -function to find the Mapping between two DSBSpecFrames, the setting for -the two SideBand attributes will be taken into account. Thus, if you take -a copy of a DSBSpecFrame, toggle its SideBand attribute, and then use -c+ -astConvert -c- -f+ -AST\_CONVERT -f- -to find a Mapping from the original to the modified copy, the resulting -Mapping will be of the form of equation \ref{eqn:dsb} (if the -DSBSpecFrame has its StdOfRest attribute set to ``Topocentric''). - -In general, when finding a Mapping between two arbitrary DSBSpecFrames, -the total Mapping is made of of three parts in series: - -\begin{enumerate} -\item A Mapping which converts the first DSBSpecFrame into its upper -sideband representation. If the DSBSpecFrame already represents its upper -sideband, this Mapping will be a UnitMap. -\item A Mapping which converts from the first to the second DSBSpecFrame, -treating them as if they were both basic SpecFrames. This takes account of -any difference in units, standard of rest, system, \emph{etc} between the -two DSBSpecFrames. -\item A Mapping which converts the second DSBSpecFrame from its upper -sideband representation to its current sideband. If the DSBSpecFrame -currently represents its upper sideband, this Mapping will be a UnitMap. -\end{enumerate} - -If an attempt is made to find the Mapping between a DSBSpecFrame and a -basic SpecFrame, then the DSBSpecFrame will be treated like a basic -SpecFrame. In other words, the returned Mapping will not be affected by -the setting of the SideBand attribute (or any of the other attributes -specific to the DSBSpecFrame class). - -In practice, the local oscillator frequency for a dual sideband -instrument may not be easily available to an observer. Instead, it is -common practice to specify the spectral position of some central feature -in the observation (commonly the centre of the instrument passband), -together with an ``intermediate frequency''. Together, these two values -allow the local oscillator frequency to be determined. The intermediate -frequency is the difference between the topocentric frequency at the -central spectral position and the topocentric frequency of the local -oscillator. So: - -\begin{quote} -\begin{small} -\begin{equation} -\label{eqn:dsb2} - f_{LO} = f_{central} + f_{if} -\end{equation} -\end{small} -\end{quote} - -The DSBSpecFrame class uses the DSBCentre attribute to specify the central -spectral position ($f_{central}$), and the IF attribute to specify the -intermediate frequency ($f_{if}$). The DSBCentre value is given and returned -in the spectral system described by the DSBSpecFrame (thus you do not need to -calculate the corresponding topocentric frequency yourself - this will be -done automatically by the DSBSpecFrame when you assign a new value to the -DSBCentre attribute). The value assigned to the IF attribute should -always be a topocentric frequency in units of Hz, however a negative -value may be given to indicate that the DSBCentre value is in the upper -sideband (that is, if $IF < 0$ then $f_{central} > f_{LO}$). A positive -value for IF indicates that the DSBCentre value is in the lower sideband -(that is, if $IF > 0$ then $f_{central} < f_{LO}$). - - -\cleardoublepage -\section{\xlabel{ss_timeframes}\label{ss:timeframes}Time Systems (TimeFrames)} - -The TimeFrame is a Frame which is specialised for representing moments in -time. In this section we examine the additional properties and behaviour of a -TimeFrame that distinguish it from a basic Frame (\secref{ss:frames}). - -\subsection{The TimeFrame Model} - -As for a SkyFrame, a TimeFrame is a Frame (\secref{ss:frames}) and also a -Mapping (\secref{ss:mappings}), so it inherits all the properties and -behaviour of these two ancestral classes. When used as a Mapping, a -TimeFrame implements a unit transformation, exactly like a basic Frame -(\secref{ss:frameasmapping}) or a UnitMap, so this aspect of its -behaviour is not of great importance. - -When used as a Frame, however, a TimeFrame represents a wide range of -different 1-dimensional coordinate system which can be used to describe -moments in time. Absolute times and relative (i.e. elapsed) times are -supported (attribute TimeOrigin), as are a range of different time scales -(attribute TimeScale). An absolute or relative value in any time scale can -be represented in different forms such as Modified Julian Date, Julian Epoch, -\emph{etc} (attribute System). AST extends the definition of these systems to -allow them to be used with any unit of time (attribute Unit). The TimeFrame -class also allows times to formatted as either a simple floating point value -or as a Gregorian date and time of day (attribute Format). - -\subsection{Creating a TimeFrame} - -The TimeFrame constructor function is particularly simple and a -TimeFrame with default attributes is created as follows: - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstTimeFrame *timeframe; - -... - -timeframe = astTimeFrame( "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER TIMEFRAME, STATUS - - STATUS = 0 - - ... - - TIMEFRAME = AST_TIMEFRAME( ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -Such a TimeFrame would represent the default coordinate system which is -Modified Julian Date (with the usual units of days) in the International -Atomic Time (TAI) time scale. - -\subsection{Specifying a Particular Time System} -By setting the System attribute appropriately, the TimeFrame can represent -Julian Date, Modified Julian Date, Julian Epoch or Besselian Epoch (the -time scale is specified by a separate attribute called TimeScale). - -Selection of a particular coordinate system is performed simply by -setting a value for the TimeFrame's (character string) System -attribute. This setting is most conveniently done when the TimeFrame is -created. For example, a TimeFrame representing Julian Epoch would be created -by: - -c+ -\small -\begin{terminalv} -timeframe = astTimeFrame( "System=JEPOCH" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - TIMEFRAME = AST_TIMEFRAME( 'System=JEPOCH', STATUS ) -\end{terminalv} -\normalsize -f- - -Note that specifying ``System$=$JEPOCH'' also changes the associated -default Unit (from days to years). This is because the default value -of the TimeFrame's Unit attribute depends on the System attribute setting. - -You may change the System value at any time, although this is not -usually needed. The values supported are set out in the attribute's -description in \appref{ss:attributedescriptions}. - -\subsection{Attributes which Qualify Time Coordinate Systems} - -Time coordinate systems require some additional free parameters to identify -a particular coordinate system from amongst a broader class of related -coordinate systems. For example, all TimeFrames are qualified by the time -scale (that is, the physical process used to define the flow of time), -and some require the position of the observer's clock. - -In AST, these free parameters are represented by additional TimeFrame -attributes, each of which has a default appropriate to (\emph{i.e.}\ defined -by) the setting of the main System attribute. Each of these \emph{qualifying -attributes} may, however, be assigned an explicit value so as to select a -particular coordinate system. Note, it is usually best to assign explicit -values whenever possible rather than relying on defaults. Attribute -should only be left at their default value if you ``don't care'' what -value is used. In certain circumstances (particularly, when aligning two -Frames), a default value for an attribute may be replaced by the value -from another similar Frame. Such value replacement can be prevented by -assigning an explicit value to the attribute, rather than simply relying on -the default. - -The main TimeFrame attributes which qualify the System attribute are: - -\begin{quote} -\begin{description} - -\item[TimeScale]\mbox{}\\ -This specifies the time scale. - -\item[LTOffset]\mbox{}\\ -This specifies the offset from Local Time to UTC in hours (time zones -east of Greenwich have positive values). Note, AST uses the value as -supplied without making any correction for daylight saving. - -\item[TimeOrigin]\mbox{}\\ -This specifies the zero point from which time values are measured, within -the system specified by the System attribute. Thus, a value of zero (the -default) indicates that time values represent absolute times. Non-zero -values may be used to indicate that the TimeFrame represents elapsed time -since the specified origin. - -\end{description} -\end{quote} - -For further details of these attributes you should consult their -descriptions in \appref{ss:attributedescriptions} and for details of -the System settings for which they are relevant, see the description -of the System attribute (also in \appref{ss:attributedescriptions}). - -Note that it does no harm to assign values to qualifying attributes -which are not relevant to the main System or TimeScale value. Any such -values are stored, but are not used unless the System and/or TimeScale -value is later set so that they become relevant. - -\cleardoublepage -\section{\label{ss:cmpframes}Compound Frames (CmpFrames)} - -We now turn to a rather special form of Mapping, the CmpFrame. The -Frames we have considered so far have been atomic, in the sense that -they represent pre-defined elementary physical domains. A CmpFrame, -however, is a compound Frame. In essence, it is a structure for -containing other Frames and its purpose is to allow those Frames -to work together in various combinations while appearing as a single -Object. A CmpFrame's behaviour is therefore not pre-defined, but is -determined by the other Frames it contains (its ``component'' Frames). - -As with compound Mappings, compound Frames can be nested within each -other, forming arbitrarily complex Frames. - -\subsection{Creating a CmpFrame} -A very common use for a CmpFrame within astronomy is to represent a -``spectral cube''. This is a 3-dimensional Frame in which one of the axes -represents position within a spectrum, and the other two axes represent -position on the sky (or some other spatial domain such as the focal plane -of a telescope). As an example, we create such a CmpFrame in which axes -1 and 2 represent Right Ascension and Declination (ICRS), and axis 3 -represents wavelength (these are the default coordinate Systems -represented by a SkyFrame and a SpecFrame respectively): - -c+ -\small -\begin{terminalv} -AstSkyFrame *skyframe; -AstSpecFrame *specframe; -AstCmpFrame *cmpframe; -... -skyframe = astSkyFrame( "" ); -specframe = astSpecFrame( "" ); -cmpframe = astCmpFrame( skyframe, specframe, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER SKYFRAME - INTEGER SPECFRAME - INTEGER CMPFRAME - ... - SKYFRAME = AST_SKYFRAME( ' ', STATUS ) - SPECFRAME = AST_SPECFRAME( ' ', STATUS ) - CMPFRAME = AST_CMPFRAME( SKYFRAME, SPECFRAME, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -If it was desired to make RA and Dec correspond to axes 1 and 3, with -axis 2 being the spectral axis, then the axes of the CmpFrame created -above would need to be permuted as follows: - -c+ -\small -\begin{terminalv} -int perm[ 3 ]; -... - -perm[ 0 ] = 0; -perm[ 1 ] = 2; -perm[ 2 ] = 1; -astPermAxes( cmpframe, perm ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER PERM(3) - ... - - PERM( 1 ) = 1 - PERM( 2 ) = 3 - PERM( 3 ) = 2 - CALL AST_PERMAXES( CMPFRAME, PERM, STATUS ) -\end{terminalv} -\normalsize -f- - -\subsection{The Attributes of a CmpFrame} - -A CmpFrame \emph{is a} Frame and so has all the attributes of a Frame. -The default value for the Domain attribute for a CmpFrame is formed by -concatenating the Domains of the two component Frames, separated by a -minus sign (``-'').\footnote{If both component Frames have blank Domains, -then the default Domain for the CmpFrame is the string ``CMP''.} The (fixed) -value for its System attribute is ``Compound''.\footnote{Any attempt to -change the System value of a CmpFrame is ignored.} A CmpFrame has no -further attributes over and above those common to all Frames. However, -attributes of the two component Frames can be accessed as if they were -attributes of the CmpFrame, as described below. - -Frame attributes which are specific to individual axes (such as Label(2), -Format(1), \emph{etc}) simply mirror the corresponding axes of the -relevant component Frame. That is, if the ``Label(2)'' attribute of a -CmpFrame is accessed, the CmpFrame will forward the access request to the -component Frame which contains axis 2. Thus, default values for axis -attributes will be the same as those provided by the component Frames. - -An axis index can optionally be appended to the name of Frames attributes -which do not normally have such an index (System, Domain, Epoch, Title, -\emph{etc}). If this is done, the access request is forwarded to the -component Frame containing the indicated axis. For instance, if a -CmpFrame contains a SpecFrame and a SkyFrame in that order, and the axes -have not been permuted, then getting the value of attribute ``System'' will -return ``Compound'' as mentioned above (that is, the System value of the -CmpFrame as a whole), whereas getting the value of attribute -``System(1)'' will return ``Spectral''(that is, the System value of the -component Frame containing axis 1 --- the SpecFrame). - -This technique is not limited to attributes common to all Frames. For -instance, the SkyFrame class defines an attribute called Equinox which is -not held by other classes of Frames. To set a value for the Equinox -attribute of the SkyFrame contained within the above CmpFrame, assign the -value to the ``Equinox(2)'' attribute of the CmpFrame. Since the SkyFrame -defines both axes 2 and 3 of the CmpFrame, we could equivalently have set -a value for ``Equinox(3)'' since this would also result in the attribute -access being forwarded to the SkyFrame. - -Finally, if an attribute is not qualified by a axis index, attempts will -be made to access it using each of the CmpFrame axes in turn. Using the -above example of the spectral cube, if an attempt was made to get the -value of attribute ``Equinox'' (with no axis index), each axis in turn -would be used. Since axis 1 is contained within a SpecFrame, the first -attempt would fail since the SpecFrame class does not have an Equinox -attribute. However, the second attempt would succeed because axis 2 is -contained within a SkyFrame which \emph{does} have an Equinox attribute. Thus -the returned attribute value would be that obtained from the SkyFrame -containing axis 2. When getting or testing an attribute value, the -returned value is determined by the \emph{first} axis which recognises -the attribute. When setting an attribute value, \emph{all} axes -which recognises the attribute have the attribute value set to the given -value. Likewise, when clearing an attribute value, all axes -which recognises the attribute have the attribute value cleared. - -\cleardoublepage -\section{\label{ss:introducingconversion}An Introduction to Coordinate System Conversions} - -In this section, we start to look at techniques for converting between -different coordinate systems. At this stage, the tools we have available -are Frames (\secref{ss:frames}), SkyFrames (\secref{ss:skyframes}), -SpecFrames (\secref{ss:specframes}), TimeFrames (\secref{ss:timeframes}) and -various Mappings (\secref{ss:mappings}). These are sufficient to allow us to -begin examining the problem, but more sophisticated approaches will also emerge -later (\secref{ss:framesetconverting}). - -\subsection{\label{ss:convertingskyframes}Converting between Celestial Coordinate Systems} - -We begin by examining how to convert between two celestial coordinate -systems represented by SkyFrames, as this is both an illuminating and -practical example. Consider the problem of converting celestial -coordinates between: - -\begin{enumerate} -\item The old FK4 system, with no E terms, a Besselian epoch of -1958.0 and a Besselian equinox of 1960.0. - -\item An ecliptic coordinate system based on the mean equinox and -ecliptic of Julian epoch 2010.5. -\end{enumerate} - -This example is arbitrary but not completely unrealistic. Unless you -already have expertise with such conversions, you are unlikely to find -it straightforward. - -Using AST, we begin by creating two SkyFrames to represent these -coordinate systems, as follows: - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstSkyFrame *skyframe1, *skyframe2; - -... - -skyframe1 = astSkyFrame( "System=FK4-NO-E, Epoch=B1958, Equinox=B1960" ); -skyframe2 = astSkyFrame( "System=Ecliptic, Equinox=J2010.5" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER SKYFRAME1, SKYFRAME2, STATUS - - STATUS = 0 - - ... - - SKYFRAME1 = AST_SKYFRAME( 'System=FK4-NO-E, Epoch=B1958, Equinox=B1960', STATUS ) - SKYFRAME2 = AST_SKYFRAME( 'System=Ecliptic, Equinox=J2010.5', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Note how specifying the coordinate systems consists simply of -initialising the attributes of each SkyFrame appropriately. The next -step is to find a way of converting between these SkyFrames. This is -done using astConvert, as follows: -c- -f+ -Note how specifying the coordinate systems consists simply of -initialising the attributes of each SkyFrame appropriately. The next -step is to find a way of converting between these SkyFrames. This is -done using AST\_CONVERT, as follows: -f- - -c+ -\small -\begin{terminalv} -AstFrameSet *cvt; - -... - -cvt = astConvert( skyframe1, skyframe2, "" ); -if ( cvt == AST__NULL ) { - -} else { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER CVT - - ... - - CVT = AST_CONVERT( SKYFRAME1, SKYFRAME2, ' ', STATUS ) - IF ( CVT .EQ. AST__NULL ) THEN - - ELSE - - END IF -\end{terminalv} -\normalsize -f- - -c+ -The third argument of astConvert is not used here and should be an -empty string. -c- -f+ -The third argument of AST\_CONVERT is not used here and should be a -blank string. -f- - -c+ -astConvert will return a null result, AST\_\_NULL (as defined in the -``ast.h'' header file), if conversion is not possible. In this -example, conversion is possible, so it will return a pointer to a new -Object that describes the conversion. -c- -f+ -AST\_CONVERT will return a null result, AST\_\_NULL (as defined in the -AST\_PAR include file), if conversion is not possible. In this -example, conversion is possible, so it will return a pointer to a new -Object that describes the conversion. -f- - -The Object returned is called a FrameSet. We have not discussed -FrameSets yet (\secref{ss:framesets}), but for the present purposes we -can consider them simply as Objects that can behave both as Mappings -and as Frames. It is the FrameSet's behaviour as a Mapping in which we -are mainly interested here, because the Mapping it implements is the -one we require---\emph{i.e.}\ it converts between the two celestial -coordinate systems (\secref{ss:framesetsfromconvert}). - -c+ -For example, if ``alpha1'' and ``delta1'' are two arrays containing -the longitude and latitude, in radians, of N points on the sky in the -original coordinate system (corresponding to ``skyframe1''), then they -could be converted into the new coordinate system (represented by -``skyframe2'') as follows: -c- -f+ -For example, if ALPHA1 and DELTA1 are two arrays containing the -longitude and latitude, in radians, of N points on the sky in the -original coordinate system (corresponding to SKYFRAME1), then they -could be converted into the new coordinate system (represented by -SKYFRAME2) as follows: -f- - -c+ -\small -\begin{terminalv} -#define N 10 -double alpha1[ N ], delta1[ N ]; -double alpha2[ N ], delta2[ N ]; - -... - -astTran2( cvt, N, alpha1, delta1, 1, alpha2, delta2 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER N - DOUBLE PRECISION ALPHA1( N ), DELTA1( N ) - DOUBLE PRECISION ALPHA2( N ), DELTA2( N ) - - ... - - CALL AST_TRAN2( CVT, N, ALPHA1, DELTA1, .TRUE., ALPHA2, DELTA2, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -The new coordinates are returned \emph{via} the ``alpha2'' and -``delta2'' arrays. To transform coordinates in the opposite -direction, we simply invert the 5th (boolean int) argument to -astTran2, as follows: -c- -f+ -The new coordinates are returned \emph{via} the ALPHA2 and DELTA2 -arrays. To transform coordinates in the opposite direction, we simply -invert the 5th (logical) argument to AST\_TRAN2, as follows: -f- - -c+ -\small -\begin{terminalv} -astTran2( cvt, N, alpha2, delta2, 0, alpha1, delta1 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_TRAN2( CVT, N, ALPHA2, DELTA2, .FALSE., ALPHA1, DELTA1, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -The FrameSet returned by astConvert also contains information about -the SkyFrames used in the conversion -(\secref{ss:framesetsfromconvert}). As we mentioned above, a FrameSet -may be used as a Frame and in this case it behaves like the -``destination'' Frame used in the conversion (\emph{i.e.}\ like -``skyframe2''). We could therefore use the ``cvt'' FrameSet to -calculate the distance between two points (with coordinates in -radians) in the destination coordinate system, using astDistance: -c- -f+ -The FrameSet returned by AST\_CONVERT also contains information about -the SkyFrames used in the conversion -(\secref{ss:framesetsfromconvert}). As we mentioned above, a FrameSet -may be used as a Frame and in this case it behaves like the -``destination'' Frame used in the conversion (\emph{i.e.}\ like -SKYFRAME2). We could therefore use the CVT FrameSet to calculate the -distance between two points (with coordinates in radians) in the -destination coordinate system, using AST\_DISTANCE: -f- - -c+ -\small -\begin{terminalv} -double distance, point1[ 2 ], point2[ 2 ]; - -... - -distance = astDistance( cvt, point1, point2 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DOUBLE PRECISION DISTANCE, POINT1( 2 ), POINT2( 2 ) - - ... - - DISTANCE = AST_DISTANCE( CVT, POINT1, POINT2, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -and the result would be the same as if the ``skyframe2'' SkyFrame had -been used. -c- -f+ -and the result would be the same as if the SKYFRAME2 SkyFrame had been -used. -f- - -Another way to see how the FrameSet produced by astConvert retains -information about the coordinate systems involved is to set its Report -attribute (inherited from the Mapping class) so that it displays the -coordinates before and after conversion (\secref{ss:transforming}): - -c+ -\small -\begin{terminalv} -astSet( cvt, "Report=1" ); -astTran2( cvt, N, alpha1, delta1, 1, alpha2, delta2 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( CVT, 'Report=1', STATUS ) - CALL AST_TRAN2( CVT, N, ALPHA1, DELTA1, .TRUE., ALPHA2, DELTA2, STATUS ) -\end{terminalv} -\normalsize -f- - -The output from this might look like the following: - -\begin{terminalv} -(2:06:03.0, 34:22:39) --> (42.1087, 20.2717) -(2:08:20.6, 35:31:24) --> (43.0197, 21.1705) -(2:10:38.1, 36:40:09) --> (43.9295, 22.0716) -(2:12:55.6, 37:48:55) --> (44.8382, 22.9753) -(2:15:13.1, 38:57:40) --> (45.7459, 23.8814) -(2:17:30.6, 40:06:25) --> (46.6528, 24.7901) -(2:19:48.1, 41:15:11) --> (47.5589, 25.7013) -(2:22:05.6, 42:23:56) --> (48.4644, 26.6149) -(2:24:23.1, 43:32:41) --> (49.3695, 27.5311) -(2:26:40.6, 44:41:27) --> (50.2742, 28.4499) -\end{terminalv} - -Here, we see that the input FK4 equatorial coordinate values (given in -radians) have been formatted automatically in sexagesimal notation -using the conventional hours for right ascension and degrees for -declination. Conversely, the output ecliptic coordinates are shown in -decimal degrees, as is conventional for ecliptic coordinates. Both are -displayed using the default precision of 7 digits.\footnote{The -leading digit is zero and is therefore not seen in this particular -example.} - -c+ -In fact, the ``cvt'' FrameSet has access to all the information in the -original SkyFrames which were passed to astConvert. If you had set a -new Digits attribute value for either of these, the formatting above -would reflect the different precision you requested by displaying a -greater or smaller number of digits. -c- -f+ -In fact, the CVT FrameSet has access to all the information in the -original SkyFrames which were passed to AST\_CONVERT. If you had set a -new Digits attribute value for either of these, the formatting above -would reflect the different precision you requested by displaying a -greater or smaller number of digits. -f- - - -\subsection{\label{ss:convertingspecframes}Converting between Spectral Coordinate Systems} -The principles described in the previous section for converting between -celestial coordinate systems also apply to the task of converting between -spectral coordinate systems. As an example, let's look at how we might -convert between frequency measured in $GHz$ as measured in the rest frame -of the telescope, and radio velocity measured in $km/s$ measured with -respect the kinematic Local Standard of Rest. - -First we create a default SpecFrame, and then set its attributes to -describe the required radio velocity system (this is slightly more -convenient, given the relatively large number of attributes, than -specifying the attribute values in a single string such as would be -passed to the SpecFrame constructor). We then take a copy of this -SpecFrame, and change the attribute values so that the copy describes the -original frequency system (modifying a copy, rather than creating a new -SpecFrame from scratch, avoids the need to specify the epoch, reference -position, \emph{etc} a second time since they are all inherited by the copy): - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstSpecFrame *specframe1, *specframe2; - -... - -specframe1 = astSpecFrame( "" ); -astSet( specframe1, "System=vradio" ); -astSet( specframe1, "Unit=km/s" ); -astSet( specframe1, "Epoch=1996-Oct-2 12:13:56.985" ); -astSet( specframe1, "ObsLon=W155:28:18" ); -astSet( specframe1, "ObsLat=N19:49:34" ); -astSet( specframe1, "RefRA=18:14:50.6" ); -astSet( specframe1, "RefDec=-4:40:49" ); -astSet( specframe1, "RestFreq=230.538 GHz" ); -astSet( specframe1, "StdOfRest=LSRK" ); - -specframe2 = astCopy( specframe1 ); -astSet( specframe1, "System=freq" ); -astSet( specframe1, "Unit=GHz" ); -astSet( specframe1, "StdOfRest=Topocentric" ); - -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER SPECFRAME1, SPECFRAME2, STATUS - - STATUS = 0 - - ... - - SPECFRAME1 = AST_SPECFRAME( ' ', STATUS ) - CALL AST_SETC( SPECFRAME1, 'System=vradio', STATUS ) - CALL AST_SETC( SPECFRAME1, 'Unit=km/s', STATUS ) - CALL AST_SETC( SPECFRAME1, 'Epoch=1996-Oct-2 12:13:56.985', - : STATUS ) - CALL AST_SETC( SPECFRAME1, 'ObsLon=W155:28:18', STATUS ) - CALL AST_SETC( SPECFRAME1, 'ObsLat=N19:49:34', STATUS ) - CALL AST_SETC( SPECFRAME1, 'RefRA=18:14:50.6', STATUS ) - CALL AST_SETC( SPECFRAME1, 'RefDec=-4:40:49', STATUS ) - CALL AST_SETC( SPECFRAME1, 'RestFreq=230.538 GHz', STATUS ) - CALL AST_SETC( SPECFRAME1, 'StdOfRest=LSRK', STATUS ) - - SPECFRAME2 = AST_COPY( SPECFRAME1, STATUS ) - CALL AST_SETC( SPECFRAME1, 'System=freq', STATUS ) - CALL AST_SETC( SPECFRAME1, 'Unit=GHz', STATUS ) - CALL AST_SETC( SPECFRAME1, 'StdOfRest=Topocentric', STATUS ) - -\end{terminalv} -\normalsize -f- - -Note, the fact that a SpecFrame has only a single axis means that we were -able to refer to the Unit attribute without an axis index. The other -attributes are: the time of of observation (Epoch), the geographical -position of the telescope (ObsLat \& ObsLon), the position of the source -on the sky (RefRA \& RefDec), the rest frequency (RestFreq) and the -standard of rest (StdOfRest). - -The next step is to find a way of converting between these SpecFrames. We -use exactly the same code that we did in the previous section where we were -converting between celestial coordinate systems: - -c+ -\small -\begin{terminalv} -AstFrameSet *cvt; - -... - -cvt = astConvert( specframe1, specframe2, "" ); -if ( cvt == AST__NULL ) { - -} else { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER CVT - - ... - - CVT = AST_CONVERT( SPECFRAME1, SPECFRAME2, ' ', STATUS ) - IF ( CVT .EQ. AST__NULL ) THEN - - ELSE - - END IF -\end{terminalv} -\normalsize -f- - -A before, this will give us a FrameSet (assuming conversion is possible, -which should always be the case for our example), and we can use the -FrameSet to convert between the two spectral coordinate systems. We use -c+ -astTran1 in place of astTran2 -c- -f+ -AST\_TRAN1 in place of AST\_TRAN2 -f- -since a SpecFrame has only one axis (unlike a SkyFrame which has two). - -c+ -For example, if ``frq'' is an array containing the observed frequency, in -GHz, of N spectral channels (describe by ``specframe1''), then they -could be converted into the new coordinate system (represented by -``specframe2'') as follows: -c- -f+ -For example, if FRQ is an array containing the observed frequency, in -GHz, of N spectral channels (describe by SPECFRAME1), then they -could be converted into the new coordinate system (represented by -SPECFRAME2) as follows: -f- - -c+ -\small -\begin{terminalv} -#define N 10 -double frq[ N ]; -double vel[ N ]; - -... - -astTran1( cvt, N, frq, 1, vel ); -\end{terminalv} -\normalsize - -The radio velocity values are returned in the ``vel'' array. - -c- -f+ -\small -\begin{terminalv} - INTEGER N - DOUBLE PRECISION FRQ( N ) - DOUBLE PRECISION VEL( N ) - - ... - - CALL AST_TRAN1( CVT, N, FRQ, .TRUE., VEL, STATUS ) -\end{terminalv} -\normalsize - -The radio velocity values are returned in the VEL array. -f- - -\subsection{Converting between Time Coordinate Systems} -All the principles outlined in the previous section about aligning -spectral cocordinate systems (SpecFrames) can be applied directly to the -problem of aligning time coordinate systems (TimeFrames). - -\subsection{\label{ss:convertingpermutedaxes}Handling SkyFrame Axis Permutations} - -c+ -We can illustrate an important point if we swap the axis order of -either SkyFrame in the example above (\secref{ss:convertingskyframes}) -before identifying the conversion. Let's assume we use astPermAxes -(\secref{ss:permutingaxes}) to do this to the second SkyFrame, before -applying astConvert, as follows: -c- -f+ -We can illustrate an important point if we swap the axis order of -either SkyFrame in the example above (\secref{ss:convertingskyframes}) -before identifying the conversion. Let's assume we use AST\_PERMAXES -(\secref{ss:permutingaxes}) to do this to the second SkyFrame, before -applying AST\_CONVERT, as follows: -f- - -c+ -\small -\begin{terminalv} -int perm[ 2 ] = { 2, 1 }; - -... - -astPermAxes( skyframe2, perm ); -cvt = astConvert( skyframe1, skyframe2, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER PERM( 2 ) - DATA PERM / 2, 1 / - - ... - - CALL AST_PERMAXES( SKYFRAME2, PERM, STATUS ) - CVT = AST_CONVERT( SKYFRAME1, SKYFRAME2, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -Now, the destination SkyFrame system no longer represents the -coordinate system: - -\begin{quote} -(ecliptic~longitude, ecliptic~latitude) -\end{quote} - -but instead represents the transposed system: - -\begin{quote} -(ecliptic~latitude, ecliptic~longitude) -\end{quote} - -c+ -As a consequence, when we use the FrameSet returned by astConvert to -apply a coordinate transformation, we obtain something like the -following: -c- -f+ -As a consequence, when we use the FrameSet returned by AST\_CONVERT to -apply a coordinate transformation, we obtain something like the -following: -f- - -\begin{terminalv} -(2:06:03.0, 34:22:39) --> (20.2717, 42.1087) -(2:08:20.6, 35:31:24) --> (21.1705, 43.0197) -(2:10:38.1, 36:40:09) --> (22.0716, 43.9295) -(2:12:55.6, 37:48:55) --> (22.9753, 44.8382) -(2:15:13.1, 38:57:40) --> (23.8814, 45.7459) -(2:17:30.6, 40:06:25) --> (24.7901, 46.6528) -(2:19:48.1, 41:15:11) --> (25.7013, 47.5589) -(2:22:05.6, 42:23:56) --> (26.6149, 48.4644) -(2:24:23.1, 43:32:41) --> (27.5311, 49.3695) -(2:26:40.6, 44:41:27) --> (28.4499, 50.2742) -\end{terminalv} - -When compared to the original (\secref{ss:convertingskyframes}), the -output coordinate order has been swapped to compensate for the -different destination SkyFrame axis order. - -c+ -In all, there are four possible axis combinations, corresponding to two -possible axis orders for each of the source and destination SkyFrames, -and astConvert will convert correctly between any of these. -c- -f+ -In all, there are four possible axis combinations, corresponding to two -possible axis orders for each of the source and destination SkyFrames, -and AST\_CONVERT will convert correctly between any of these. -f- -The point to note is that a SkyFrame contains knowledge about how to -convert to and from other SkyFrames. Since its two axes (longitude and -latitude) are distinguishable, the conversion is able to take account -of the axis order. - -If you need to identify the axes of a SkyFrame explicitly, taking into -account any axis permutations, the LatAxis and LonAxis attributes can be -used. These are read-only attributes which give the indices of the -latitude and longitude axes respectively. - -\subsection{\label{ss:convertingframes}Converting Between Frames} - -c+ -Having seen how clever SkyFrames are (\secref{ss:convertingskyframes} -and \secref{ss:convertingpermutedaxes}), we will next examine how dumb -a basic Frame can be in comparison. For example, if we create two -2-dimensional Frames and use astConvert to derive a conversion between -them, as follows: -c- -f+ -Having seen how clever SkyFrames are (\secref{ss:convertingskyframes} -and \secref{ss:convertingpermutedaxes}), we will next examine how dumb -a basic Frame can be in comparison. For example, if we create two -2-dimensional Frames and use AST\_CONVERT to derive a conversion -between them, as follows: -f- - -c+ -\small -\begin{terminalv} -AstFrame *frame1, *frame2; - -... - -frame1 = astFrame( 2, "" ); -frame2 = astFrame( 2, "" ); -cvt = astConvert( frame1, frame2, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER FRAME1, FRAME2 - - ... - - FRAME1 = AST_FRAME( 2, ' ', STATUS ) - FRAME2 = AST_FRAME( 2, ' ', STATUS ) - CVT = AST_CONVERT( FRAME1, FRAME2, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -then the coordinate transformation which the ``cvt'' FrameSet performs -will be as follows: -c- -f+ -then the coordinate transformation which the ``cvt'' FrameSet performs -will be as follows: -f- - -\begin{terminalv} -(1, 2) --> (1, 2) -(2, 4) --> (2, 4) -(3, 6) --> (3, 6) -(4, 8) --> (4, 8) -(5, 10) --> (5, 10) -\end{terminalv} - -This is an identity transformation, exactly the same as a UnitMap -(\secref{ss:unitmapexample}). Even if we permute the axis order of our -Frames, as we did above (\secref{ss:convertingpermutedaxes}), we will -fare no better. The conversion between our two basic Frames will -always be an identity transformation. - -The reason for this is that, unlike a SkyFrame, all basic Frames start -life the same and have axes that are indistinguishable. Therefore, -permuting their axes doesn't make them look any different---they still -represent the same coordinate system. -%Actually, this behaviour isn't as dumb as it seems and can actually be -%very useful, as the following example illustrates. -% -%\subsection{Distinguishable and Indistinguishable Axes} -% -%c+ -%Imagine you have two Frames which represent the pixel coordinates of -%two 2-dimensional images. Let's call their axes ``X'' and ``Y''. -%Suppose you now transpose the second image and swap its Frame axes -%(with astPermAxes) to take account of this. -%c- -%f+ -%Imagine you have two Frames which represent the pixel coordinates of -%two 2-dimensional images. Let's call their axes ``X'' and ``Y''. -%Suppose you now transpose the second image and swap its Frame axes -%(with astPermAxes) to take account of this. -%f- -% -%Next, consider what happens if you want to subtract one image from the -%other. If you have a ``subtract'' program that is intelligent and -%tries to align the two images for you, one of two things could happen: -% -%\begin{enumerate} -%c+ -%\item If the axes are distinguishable, when your program invokes -%astConvert it will derive a transformation between the two images -%which swaps the X and Y coordinates (corresponding to the transposition -%you applied to the second image). However, in aligning X-with-X and -%Y-with-Y, this will completely undo the effects of your transposition! -%c- -%f+ -%\item If the axes are distinguishable, when your program invokes -%AST\_CONVERT it will derive a transformation between the two images -%which swaps the X and Y coordinates (corresponding to the transposition -%you applied to the second image). However, in aligning X-with-X and -%Y-with-Y, this will completely undo the effects of your transposition! -%f- -% -%\item If the axes are indistinguishable, the transformation between -%the two images will always be an identity -%(\secref{ss:convertingframes}). Therefore, your program will align -%X-with-Y and Y-with-X, so that you see the effects of your earlier -%transposition of the second image. -%\end{enumerate} -% -%Clearly, if we are considering pixel coordinates, the latter behaviour -%is preferable, since there would be no point in implementing an image -%transposition program if we could never see the effects of it. This -%indicates that a basic Frame, with is indistinguishable axes, is the -%correct type of Object to represent a pixel coordinate system, where -%this behaviour is necessary. -% -%Conversely, the former behaviour would be more useful if the axes we -%were considering were, say, wavelength (in nm) and slit position (in -%mm). In this case, we would expect our ``subtract'' program to -%subtract data at corresponding wavelengths and slit positions, not -%just at corresponding pixels. This case requires distinguishable axes, -%so that corresponding axes in the two images can be matched up, just -%as happens with a SkyFrame (\secref{ss:convertingpermutedaxes}). -% -%Of course, there may also be intermediate cases, where some axes are -%distinguishable and others aren't. - -\subsection{\label{ss:alignmentsystem}The Choice of Alignment System} - -In practice, when AST is asked to find a conversion between two Frames -describing two different coordinate systems on a given physical domain, -it uses an intermediate ``alignment'' system. Thus, when finding a -conversion from system A to system B, AST first finds the Mapping from -system A to some alignment system, system C, and then finds the Mapping -from this system C to the required system B. It finally concatenates -these two Mappings to get the Mapping from system A to system B. - -One advantage of this is that it cuts down the number of conversion -algorithms required. If there are $N$ different Systems which may be used -to describe positions within the Domain, then this approach requires -about $2*N$ conversion algorithms to be written. The alternative approach -of going directly from system A to system B would require about $N*N$ -conversion algorithms. - -In addition, the use of an intermediate alignment system highlights the -nature of the conversion process. What do we mean by saying that a -Mapping ``converts a position in one coordinate system into the -corresponding position in another''? In practice, it means that the input -and output coordinates correspond to the same coordinates \emph{in some -third coordinate system}. The choice of this third coordinate system, the -``alignment'' system, can completely alter the nature of the Mapping. The -Frame class has an attribute called AlignSystem which can be used to -specify the alignment system. - -As an example, consider the case of aligning two spectra calibrated in -radio velocity, but each with a different rest frequency (each spectrum -will be described by a SpecFrame). Since the rest frequencies differ, a -given velocity will correspond to different frequencies in the two -spectra. So when we come to ``align'' these two spectra (that is, find a -Mapping which converts positions in one SpecFrame to the corresponding -positions in the other), we have the choice of aligning the frequencies -or aligning the velocities. Different Mappings will be required to -describe these two forms of alignment. If we set AlignSystem to ``Freq'' -then the returned Mapping will align the frequencies described by the two -SpecFrames. On the other hand, if we set AlignSystem to ``Vradio'' -then the returned Mapping will align the velocities. - -Some choices of alignment system are redundant. For instance, in the -above example, changing the alignment system from frequency to wavelength -has no effect on the returned Mapping: if two spectra are aligned in -frequency they will also be aligned in wavelength (assuming the speed of -light doesn't change). - -The default value for AlignSystem depends on the class of Frame. For a -SpecFrame, the default is wavelength (or equivalently, frequency) -since this is the system in which observations are usually made. The -SpecFrame class also has an attribute called AlignStdOfRest which -allows the standard of rest of the alignment system to be specified. -Similarly, the TimeFrame class has an attribute called AlignTimeScale -which allows the time scale of the alignment system to be specified. -Currently, the SkyFrame uses ICRS as the default for AlignSystem, since -this is a close approximation to an inertial frame of rest. - -\cleardoublepage -\section{\label{ss:framesets}Coordinate System Networks (FrameSets)} - -c+ -We saw in \secref{ss:introducingconversion} how astConvert could be -used to find a Mapping that inter-relates a pair of coordinate systems -represented by Frames. There is a limitation to this, however, in that -it can only be applied to coordinate systems that are inter-related by -suitable conventions. In the case of celestial coordinates, the -relevant conventions are standards set out by the International -Astronomical Union, and others, that define what these coordinate -systems mean. In practice, however, the relationships between many -other coordinate systems are also of practical importance. -c- -f+ -We saw in \secref{ss:introducingconversion} how AST\_CONVERT could be -used to find a Mapping that inter-relates a pair of coordinate systems -represented by Frames. There is a limitation to this, however, in that -it can only be applied to coordinate systems that are inter-related by -suitable conventions. In the case of celestial coordinates, the -relevant conventions are standards set out by the International -Astronomical Union, and others, that define what these coordinate -systems mean. In practice, however, the relationships between many -other coordinate systems are also of practical importance. -f- - -Consider, for example, the focal plane of a telescope upon which an -image of the sky is falling. We could measure positions in this focal -plane in millimetres or, if there were a detector system such as a CCD -present, we could count pixels. We could also use celestial -coordinates of many different kinds. All of these systems are -equivalent in their effectiveness at specifying positions in the focal -plane, but some are more convenient than others for particular -purposes. - -Although we could, in principle, convert between all of these focal -plane coordinate systems, there is no pre-defined convention for doing -so. This is because the conversions required depend on where the -telescope is pointing and how the CCD is mounted in the focal -plane. Clearly, knowledge about this cannot be built into the AST -library and must be supplied in some other way. Note that this is -exactly the same problem as we met in \secref{ss:framedomains} when -discussing the Domain attribute---\emph{i.e.}\ coordinate systems that -apply to different physical domains require that extra information be -supplied before we can convert between them. - -What we need, therefore, is a general way to describe how coordinate -systems are inter-related, so that when there is no convention already -in place, we can define our own. We can then look forward to -converting, say, from pixels into galactic coordinates and {\emph{vice -versa.} In AST, the FrameSet class provides this capability. - -\subsection{The FrameSet Model} - -Consider a coordinate system (call it number 1) which is represented -by a Frame of some kind. Now consider a Mapping which, when applied to -the coordinates in system 1 yields coordinates in another system, -number 2. The Mapping therefore inter-relates coordinate systems 1 and -2. - -Now consider a second Mapping which inter-relates system 1 and a -further coordinate system, number 3. If we wanted to convert -coordinates between systems 2 and 3, we could do so by: - -\begin{enumerate} -\item Applying our first Mapping in reverse, so as to convert between -systems 2 and 1. - -\item Applying the second Mapping, as given, to convert between -systems 1 and 3. -\end{enumerate} - -We are not limited to three coordinate systems, of course. In fact, we -could continue to introduce any number of further coordinate systems, -so long as we have a suitable Mapping for each one which relates it to -one of the Frames already present. Continuing in this way, we can -build up a network in which Frames are inter-related by Mappings in -such a way that there is always a way of converting between any pair -of coordinate systems. - -The FrameSet (Figure~\ref{fig:frameset}) encapsulates these ideas. It -is a network composed of Frames and associated Mappings, in which -there is always exactly one path, \emph{via} Mappings, between any -pair of Frames. Since we assemble FrameSets ourselves, they can be -used to represent any coordinate systems we choose and to set up the -particular relationships between them that we want. - -\subsection{\label{ss:creatingaframeset}Creating a FrameSet} - -Before we can create a FrameSet, we must have a Frame of some kind to -put into it, so let's create a simple one: - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstFrame *frame1; - -... - -frame1 = astFrame( 2, "Domain=A" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER FRAME1, STATUS - - STATUS = 0 - - ... - - FRAME1 = AST_FRAME( 2, 'Domain=A', STATUS ) -\end{terminalv} -\normalsize -f- - -We have set this Frame's Domain attribute (\secref{ss:framedomains}) to -A so that it will be distinct from the others we will be using. We can -now create a new FrameSet containing just this Frame, as follows: - -c+ -\small -\begin{terminalv} -AstFrameSet *frameset; - -... - -frameset = astFrameSet( frame1, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER FRAMESET - - ... - - FRAMESET = AST_FRAMESET( FRAME1, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -So far, however, this Frame isn't related to any others. - -\subsection{\label{ss:addingframes}Adding New Frames to a FrameSet} - -We can now add further Frames to the FrameSet created above -(\secref{ss:creatingaframeset}). To do so, we must supply a new Frame -and an associated Mapping that relates it to any of the Frames that -are already present (there is only one present so far). To keep the -example simple, we will just use a ZoomMap that multiplies coordinates -by 10. The required Objects are created as follows: - -c+ -\small -\begin{terminalv} -AstFrame *frame2; -AstMapping *mapping12; - -... - -frame2 = astFrame( 2, "Domain=B" ); -mapping12 = astZoomMap( 2, 10.0, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER FRAME2, MAPPING12 - - ... - - FRAME2 = AST_FRAME( 2, 'Domain=B', STATUS ) - MAPPING12 = AST_ZOOMMAP( 2, 10.0D0, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -To add the new Frame into our FrameSet, we use the astAddFrame -function: -c- -f+ -To add the new Frame into our FrameSet, we use the AST\_ADDFRAME -routine: -f- - -c+ -\small -\begin{terminalv} -astAddFrame( frameset, 1, mapping12, frame2 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_ADDFRAME( FRAMESET, 1, MAPPING12, FRAME2, STATUS ) -\end{terminalv} -\normalsize -f- - -Whenever a Frame is added to a FrameSet, it is assigned an integer -index. This index starts with 1 for the initial Frame used to create -the FrameSet (\secref{ss:creatingaframeset}) and increments by one -every time a new Frame is added. This index is the primary way of -identifying the Frames within a FrameSet. - -When a Frame is added, we also have to specify which of the existing -ones the new Frame is related to. Here, we chose number 1, the only -one present so far, and the new one we added became number 2. - -c+ -Note that a FrameSet does not make copies of the Frames and Mappings -that you insert into it. Instead, it holds pointers to them. This -means that if you retain the original pointers to these Objects and -alter them, you will indirectly be altering the FrameSet's -contents. You can, of course, always use astCopy -(\secref{ss:copyingobjects}) to make a separate copy of any Object if -you need to ensure its independence. -c- -f+ -Note that a FrameSet does not make copies of the Frames and Mappings -that you insert into it. Instead, it holds pointers to them. This -means that if you retain the original pointers to these Objects and -alter them, you will indirectly be altering the FrameSet's -contents. You can, of course, always use AST\_COPY -(\secref{ss:copyingobjects}) to make a separate copy of any Object if -you need to ensure its independence. -f- - -c+ -We could also add a third Frame into our FrameSet, this time defining -a coordinate system which is reached by multiplying the original -coordinates (of ``frame1'') by 5: -c- -f+ -We could also add a third Frame into our FrameSet, this time defining -a coordinate system which is reached by multiplying the original -coordinates (of FRAME1) by 5: -f- - -c+ -\small -\begin{terminalv} -astAddFrame( frameset, 1, astZoomMap( 2, 5.0, "" ), astFrame( 2, "Domain=C" ) ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_ADDFRAME( FRAMESET, 1, - : AST_ZOOMMAP( 2, 5.0D0, ' ', STATUS ), - : AST_FRAME( 2, 'Domain=C', STATUS ), - : STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, we have avoided storing unnecessary pointer values by using -function invocations directly as arguments for astAddFrame. This -assumes that we are using astBegin and astEnd (\secref{ss:contexts}) to -ensure that Objects are correctly deleted when no longer required. -c- -f+ -Here, we have avoided storing unnecessary pointer values by using -function invocations directly as arguments for AST\_ADDFRAME. This -assumes that we are using AST\_BEGIN and AST\_END -(\secref{ss:contexts}) to ensure that Objects are correctly deleted -when no longer required. -f- - - Our example FrameSet now contains three Frames and two Mappings with - the arrangement shown in Figure~\ref{fig:fsexample}. - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.7\textwidth]{sun211_figures/fsexample} -c- -f+ - \includegraphics[width=0.7\textwidth]{sun210_figures/fsexample} -f- - \caption[An example FrameSet.]{An example FrameSet, in which Frames~2 and 3 are related to - Frame~1 by multiplying its coordinates by factors of 10 and 5 - respectively. The FrameSet's Base attribute has the value 1 and its - Current attribute has the value 3. The transformation performed when - the FrameSet is used as a Mapping (\emph{i.e.}\ from its base to - its current Frame) is shown in bold.} - \label{fig:fsexample} - \end{center} - \end{figure} - The total number of Frames is given by its read-only Nframe attribute. - -\subsection{\label{ss:baseandcurrent}The Base and Current Frames} - -At all times, one of the Frames in a FrameSet is designated to be its -\emph{base} Frame and one to be its \emph{current} Frame -(Figure~\ref{fig:fsexample}). These Frames are identified by two -integer FrameSet attributes, Base and Current, which hold the indices -of the nominated Frames within the FrameSet. - -The existence of the base and current Frames reflects an important -application of FrameSets, which is to attach coordinate systems to -entities such as data arrays, data files, plotting surfaces (for -graphics), \emph{etc.} In this context, the base Frame represents the -``native'' coordinate system of the attached entity---for example, the -pixel coordinates of an image or the intrinsic coordinates of a -plotting surface. The other Frames within the FrameSet represent -alternative coordinate systems which may also be used to refer to -positions within that entity. The current Frame represents the -particular coordinate system which is currently selected for use. For -instance, if an image were being displayed, you would aim to label it -with coordinates corresponding to the current Frame. In order to see a -different coordinate system, a software user would arrange for a -different Frame to be made current. - -The choice of base and current Frames may be changed at any time, -simply by assigning new values to the FrameSet's Base and Current -attributes. For example, to make the Frame with index 3 become the -current Frame, you could use: - -c+ -\small -\begin{terminalv} -astSetI( frameset, "Current", 3 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SETI( FRAMESET, 'Current', 3, STATUS ) -\end{terminalv} -\normalsize -f- - -You can nominate the same Frame to be both the base and current Frame -if you wish. -\label{ss:baseandcurrentdefault} - -By default (\emph{i.e.}\ if the Base or Current attribute is un-set), -the first Frame added to a FrameSet becomes its base Frame and the -last one added becomes its current Frame.\footnote{Although this is -reversed if the FrameSet's Invert attribute is non-zero.} Whenever a -new Frame is added to a FrameSet, the Current attribute is modified so -that the new Frame becomes the current one. This behaviour is -reflected in the state of the example FrameSet in -Figure~\ref{fig:fsexample}. - -\subsection{\label{ss:astbaseandastcurrent}Referring to the Base and Current Frames} - -c+ -It is often necessary to refer to the base and current Frames -(\secref{ss:baseandcurrent}) within a FrameSet, but it can be -cumbersome having to obtain their indices from the Base and Current -attributes on each occasion. To make this easier, two macros, -AST\_\_BASE and AST\_\_CURRENT, are defined in the ``ast.h'' header -file and may be used to represent the indices of the base and current -Frames respectively. They may be used whenever a Frame index is -required. -c- -f+ -It is often necessary to refer to the base and current Frames -(\secref{ss:baseandcurrent}) within a FrameSet, but it can be -cumbersome having to obtain their indices from the Base and Current -attributes on each occasion. To make this easier, two parameter -constants, AST\_\_BASE and AST\_\_CURRENT, are defined in the AST\_PAR -include file and may be used to represent the indices of the base and -current Frames respectively. They may be used whenever a Frame index -is required. -f- - -For example, when adding a new Frame to a FrameSet -(\secref{ss:addingframes}), you could use the following to indicate -that the new Frame is related to the existing current Frame, whatever -its index happens to be: - -c+ -\small -\begin{terminalv} -AstFrame *frame; -AstMapping *mapping; - -... - -astAddFrame( frameset, AST__CURRENT, mapping, frame ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER FRAME, MAPPING - - ... - - CALL AST_ADDFRAME( FRAMESET, AST__CURRENT, MAPPING, FRAME, STATUS ) -\end{terminalv} -\normalsize -f- - -Of course, the Frame you added would then become the new current -Frame. - -\subsection{\label{ss:framesetasmapping}Using a FrameSet as a Mapping} - -The FrameSet class inherits properties and behaviour from the Frame -class (\secref{ss:frames}) and, in turn, from the Mapping class -(\secref{ss:mappings}). Its behaviour when used as a Mapping is -particularly important. - -c+ -Consider, for instance, passing a FrameSet pointer to a coordinate -transformation function such as astTran2: -c- -f+ -Consider, for instance, passing a FrameSet pointer to a coordinate -transformation routine such as AST\_TRAN2: -f- - -c+ -\small -\begin{terminalv} -#define N 10 -double xin[ N ], yin[ N ], xout[ N ], yout[ N ]; - -... - -astTran2( frameset, N, xin, yin, 1, xout, yout ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER N - DOUBLE PRECISION XIN( N ), YIN( N ) - DOUBLE PRECISION XOUT( N ), YOUT( N ) - - ... - - CALL AST_TRAN2( FRAMESET, N, XIN, YIN, .TRUE., XOUT, YOUT, STATUS ) -\end{terminalv} -\normalsize -f- - -The coordinate transformation applied by this FrameSet would be the -one which converts between its base and current Frames. Using the -FrameSet in Figure~\ref{fig:fsexample}, for example, the coordinates -would be multiplied by a factor of 5. If we instead requested the -FrameSet's inverse transformation, we would be transforming from its -current Frame to its base Frame, so our example FrameSet would then -multiply by a factor of 0.2. - -Whenever the choice of base and current Frames changes, the -transformations which a FrameSet performs when used as a Mapping also -change to reflect this. The Nin and Nout attributes may also change in -consequence, because they are determined by the numbers of axes in the -FrameSet's base and current Frames respectively. These numbers need -not necessarily be equal, of course. - -c+ -Like any Mapping, a FrameSet may also be inverted by changing the -boolean sense of its Invert attribute, \emph{e.g.}\ using astInvert -(\secref{ss:invertingmappings}). If this is happens, the values of the -FrameSet's Base and Current attributes are interchanged, along with -its Nin and Nout attributes, so that its base and current Frames swap -places. When used as a Mapping, the FrameSet will therefore perform -the inverse transformation to that which it performed previously. -c- -f+ -Like any Mapping, a FrameSet may also be inverted by changing the -boolean sense of its Invert attribute, \emph{e.g.}\ using AST\_INVERT -(\secref{ss:invertingmappings}). If this is happens, the values of the -FrameSet's Base and Current attributes are interchanged, along with -its Nin and Nout attributes, so that its base and current Frames swap -places. When used as a Mapping, the FrameSet will therefore perform -the inverse transformation to that which it performed previously. -f- - -To summarise, a FrameSet may be used exactly like any other Mapping -which inter-relates the coordinate systems described by its base and -current Frames. - -\subsection{\label{ss:extractingamapping}Extracting a Mapping from a FrameSet} - -Although it is very convenient to use a FrameSet when a Mapping is -required (\secref{ss:framesetasmapping}), a FrameSet necessarily -contains additional information and sometimes this might cause -inefficiency or confusion. For example, if you wanted to use a -Mapping contained in one FrameSet and insert it into another, it would -probably not be efficient to insert the whole of the first FrameSet -into the second one, although it would work. - -c+ -In such a situation, the astGetMapping function allows you to extract -a Mapping from a FrameSet. You do this by specifying the two Frames -which the Mapping should inter-relate using their indices within the -FrameSet. For example: -c- -f+ -In such a situation, the AST\_GETMAPPING function allows you to -extract a Mapping from a FrameSet. You do this by specifying the two -Frames which the Mapping should inter-relate using their indices -within the FrameSet. For example: -f- - -c+ -\small -\begin{terminalv} -map = astGetMapping( frameset, 2, 3 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - MAP = AST_GETMAPPING( FRAMESET, 2, 3, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -would return a pointer to a Mapping that converted between Frames~2 -and 3 in the FrameSet. Its inverse transformation would then convert -in the opposite direction, \emph{i.e.}\ between Frames~3 and 2. Note -that this Mapping might not be independent of the Mappings contained -within the FrameSet---\emph{i.e.}\ they may share sub-Objects---so -astCopy should be used to make a copy if you need to guarantee -independence (\secref{ss:copyingobjects}). -c- -f+ -would return a pointer to a Mapping that converted between Frames~2 -and 3 in the FrameSet. Its inverse transformation would then convert -in the opposite direction, \emph{i.e.}\ between Frames~3 and 2. Note -that this Mapping might not be independent of the Mappings contained -within the FrameSet---\emph{i.e.}\ they may share sub-Objects---so -AST\_COPY should be used to make a copy if you need to guarantee -independence (\secref{ss:copyingobjects}). -f- - -c+ -Very often, the Mapping returned by astGetMapping will be a compound -Mapping, or CmpMap (\secref{ss:cmpmaps}). This reflects the fact that -conversion between the two Frames may need to be done \emph{via} an -intermediate coordinate system so that several stages may be involved. -You can, however, easily simplify this Mapping (where this is possible) -by using the astSimplify function (\secref{ss:simplifyingcmpmaps}) and -this is recommended if you plan to use it for transforming a large -amount of data. -c- -f+ -Very often, the Mapping returned by AST\_GETMAPPING will be a compound -Mapping, or CmpMap (\secref{ss:cmpmaps}). This reflects the fact that -conversion between the two Frames may need to be done \emph{via} an -intermediate coordinate system so that several stages may be involved. -You can, however, easily simplify this Mapping (where this is possible) -by using the AST\_SIMPLIFY function (\secref{ss:simplifyingcmpmaps}) -and this is recommended if you plan to use it for transforming a large -amount of data. -f- - -\subsection{\label{ss:framesetasframe}Using a FrameSet as a Frame} - -A FrameSet can also be used as a Frame, in which capacity it almost -always behaves as if its current Frame had been used instead. For -example, if you request the Title attribute of a FrameSet using: - -c+ -\small -\begin{terminalv} -const char *title; - -... - -title = astGetC( frameset, "Title" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 80 ) TITLE - - ... - - TITLE = AST_GETC( FRAMESET, 'Title', STATUS ) -\end{terminalv} -\normalsize -f- - -the result will be the Title of the current Frame, or a suitable -default if the current Frame's Title attribute is un-set. The same -also applies to other attribute operations---\emph{i.e.}\ setting, -clearing and testing attributes. Most attributes shared by both -Frames and FrameSets behave in this way, such as Naxes, Label(axis), -Format(axis), \emph{etc.} There are, however, a few exceptions: - -\begin{quote} -\begin{description} -\item[Class]\mbox{}\\ -Has the value ``FrameSet''. - -\item[ID]\mbox{}\\ -Identifies the particular FrameSet (not its current Frame). - -\item[Nin]\mbox{}\\ -Equals the number of axes in the FrameSet's base Frame. - -\item[Invert]\mbox{}\\ -Is independent of any of the Objects within the FrameSet. - -\item[Nobject]\mbox{}\\ -Counts the number of active FrameSets. - -\item[RefCount]\mbox{}\\ -Counts the number of active pointers to the FrameSet (not to its -current Frame). -\end{description} -\end{quote} - -Note that the set of attributes possessed by a FrameSet can vary, -depending on the nature of its current Frame. For example, if the -current Frame is a SkyFrame (\secref{ss:skyframes}), then the FrameSet -will acquire an Equinox attribute from it which can be set, enquired, -\emph{etc.} However, if the current Frame is changed to be a basic -Frame, which does not have an Equinox attribute, then this attribute -will be absent from the FrameSet as well. Any attempt to reference it -will then result in an error. - -\subsection{Extracting a Frame from a FrameSet} - -c+ -Although a FrameSet may be used in place of its current Frame in most -situations, it is sometimes convenient to have direct access to a -specified Frame within it. This may be obtained using the astGetFrame -function, as follows: -c- -f+ -Although a FrameSet may be used in place of its current Frame in most -situations, it is sometimes convenient to have direct access to a -specified Frame within it. This may be obtained using the -AST\_GETFRAME function, as follows: -f- - -c+ -\small -\begin{terminalv} -frame = astGetFrame( frameset, AST__BASE ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - FRAME = AST_GETFRAME( FRAMESET, AST__BASE, STATUS ) -\end{terminalv} -\normalsize -f- - -This would return a pointer (not a copy) to the base Frame within the -FrameSet. Note the use of AST\_\_BASE -(\secref{ss:astbaseandastcurrent}) as shorthand for the value of the -FrameSet's Base attribute, which gives the base Frame's index. - -\subsection{Removing a Frame from a FrameSet} - -c+ -Removing a Frame from a FrameSet is straightforward and is performed -using the astRemoveFrame function. You identify the Frame you wish to -remove in the usual way, by giving its index within the FrameSet. For -example, the following would remove the Frame with index 1: -c- -f+ -Removing a Frame from a FrameSet is straightforward and is performed -using the AST\_REMOVEFRAME routine. You identify the Frame you wish to -remove in the usual way, by giving its index within the FrameSet. For -example, the following would remove the Frame with index 1: -f- - -c+ -\small -\begin{terminalv} -astRemoveFrame( frameset, 1 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_REMOVEFRAME( FRAMESET, 1, STATUS ); -\end{terminalv} -\normalsize -f- - -The only restriction is that you cannot remove the last remaining -Frame because a FrameSet must always contain at least one Frame. When -a Frame is removed, the Frames which follow it are re-numbered -(\emph{i.e.}\ their indices are reduced by one) so as to preserve the -sequence of consecutive Frame indices. The FrameSet's Nframe -attribute is also decremented. - -c+ -If appropriate, astRemoveFrame will modify the FrameSet's Base and/or -Current attributes so that they continue to identify the same Frames -as previously. If either the base or current Frame is removed, -however, the corresponding attribute will become un-set, so that it -reverts to its default value (\secref{ss:baseandcurrentdefault}) and -therefore identifies an alternative Frame. -c- -f+ -If appropriate, AST\_REMOVEFRAME will modify the FrameSet's Base -and/or Current attributes so that they continue to identify the same -Frames as previously. If either the base or current Frame is removed, -however, the corresponding attribute will become un-set, so that it -reverts to its default value (\secref{ss:baseandcurrentdefault}) and -therefore identifies an alternative Frame. -f- - -Note that it is quite permissible to remove any Frame from a FrameSet, -even although other Frames may appear to depend on it. For example, in -Figure~\ref{fig:fsexample}, if Frame~1 were removed, the correct -relationship between Frames~2 and 3 would still be preserved, although -they would be re-numbered as Frames~1 and 2. - -\cleardoublepage -\section{\label{ss:fshigher}Higher Level Operations on FrameSets} - -c+ -\subsection{\label{ss:framesetsfromconvert}Creating FrameSets with astConvert} -c- -f+ -\subsection{\label{ss:framesetsfromconvert}Creating FrameSets with AST\_CONVERT} -f- - -c+ -Before considering the important subject of using FrameSets to convert -between coordinate systems (\secref{ss:framesetconverting}), let us -return briefly to reconsider the output generated by astConvert. We -used this function earlier (\secref{ss:introducingconversion}), when -converting between the coordinate systems represented by various kinds -of Frame, and indicated that it returns a FrameSet to represent the -coordinate conversion it identifies. We are now in a position to -examine the structure of this FrameSet. -c- -f+ -Before considering the important subject of using FrameSets to convert -between coordinate systems (\secref{ss:framesetconverting}), let us -return briefly to reconsider the output generated by AST\_CONVERT. We -used this function earlier (\secref{ss:introducingconversion}), when -converting between the coordinate systems represented by various kinds -of Frame, and indicated that it returns a FrameSet to represent the -coordinate conversion it identifies. We are now in a position to -examine the structure of this FrameSet. -f- - -Take our earlier example (\secref{ss:convertingskyframes}) of -converting between the celestial coordinate systems represented by two -SkyFrames: - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstFrameSet *cvt; -AstSkyFrame *skyframe1, *skyframe2; - -... - -skyframe1 = astSkyFrame( "System=FK4-NO-E, Epoch=B1958, Equinox=B1960" ); -skyframe2 = astSkyFrame( "System=Ecliptic, Equinox=J2010.5" ); - -cvt = astConvert( skyframe1, skyframe2, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER SKYFRAME1, SKYFRAME2, STATUS - - STATUS = 0 - - ... - - SKYFRAME1 = AST_SKYFRAME( 'System=FK4-NO-E, Epoch=B1958, Equinox=B1960', STATUS ) - SKYFRAME2 = AST_SKYFRAME( 'System=Ecliptic, Equinox=J2010.5', STATUS ) - - CVT = AST_CONVERT( SKYFRAME1, SKYFRAME2, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ - This will produce a pointer, ``cvt'', to the FrameSet shown in - Figure~\ref{fig:fsconvert}. -c- -f+ - This will produce a pointer, CVT, to the FrameSet shown in - Figure~\ref{fig:fsconvert}. -f- - \begin{figure}[bhtp] - \begin{center} -c+ - \includegraphics[width=0.7\textwidth]{sun211_figures/fsconvert} -c- -f+ - \includegraphics[width=0.7\textwidth]{sun210_figures/fsconvert} -f- -c+ - \caption[FrameSet produced when converting between two SkyFrames.]{The FrameSet produced when astConvert is used to convert -c- -f+ - \caption[FrameSet produced when converting between two SkyFrames.]{The FrameSet produced when AST\_CONVERT is used to convert -f- - between the coordinate systems represented by two SkyFrames. The - source SkyFrame becomes the base Frame, while the destination SkyFrame - becomes the current Frame. The Mapping between them implements the - required conversion.} - \label{fig:fsconvert} - \end{center} - \end{figure} - -c+ -As can be seen, this FrameSet contains just two Frames. The source -Frame supplied to astConvert becomes its base Frame, while the -destination Frame becomes its current Frame. (The FrameSet, of course, -simply holds pointers to these Frames, rather than making copies.) The -Mapping which relates the base Frame to the current Frame is the one -which implements the required conversion. -c- -f+ -As can be seen, this FrameSet contains just two Frames. The source -Frame supplied to AST\_CONVERT becomes its base Frame, while the -destination Frame becomes its current Frame. (The FrameSet, of course, -simply holds pointers to these Frames, rather than making copies.) The -Mapping which relates the base Frame to the current Frame is the one -which implements the required conversion. -f- - -c+ -As we noted earlier (\secref{ss:convertingskyframes}), the FrameSet -returned by astConvert may be used both as a Mapping and as a Frame to -perform most of the functions you are likely to need. However, the -Mapping may be extracted for use on its own if necessary, using -astGetMapping (\secref{ss:extractingamapping}), for example: -c- -f+ -As we noted earlier (\secref{ss:convertingskyframes}), the FrameSet -returned by AST\_CONVERT may be used both as a Mapping and as a Frame -to perform most of the functions you are likely to need. However, the -Mapping may be extracted for use on its own if necessary, using -AST\_GETMAPPING (\secref{ss:extractingamapping}), for example: -f- - -c+ -\small -\begin{terminalv} -AstMapping *mapping; - -... - -mapping = astGetMapping( cvt, AST__BASE, AST__CURRENT ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER MAPPING - - ... - - MAPPING = AST_GETMAPPING( CVT, AST__BASE, AST__CURRENT, STATUS ) -\end{terminalv} -\normalsize -f- - -\subsection{\label{ss:framesetconverting}Converting between FrameSet Coordinate Systems} - - We now consider the process of converting between the coordinate - systems represented by two FrameSets. This is a most important - operation, as a subsequent example (\secref{ss:registeringimages}) - will show, and is illustrated in Figure~\ref{fig:fsalign}. - \begin{figure} - \begin{center} -c+ - \includegraphics[width=0.7\textwidth]{sun211_figures/fsalign} -c- -f+ - \includegraphics[width=0.7\textwidth]{sun210_figures/fsalign} -f- - \caption[Conversion between two FrameSets is performed by establishin a link between a pair of Frames, one from each FrameSet.]{Conversion - between two FrameSets is performed by establishing - a link between a pair of Frames, one from each FrameSet. If conversion - between these two Frames is possible, then a route for converting - between the current Frames of both FrameSets can also be found. In - practice, there may be many ways of pairing Frames to find the - ``missing link'', so the Frames' Domain attribute may be used to - narrow the choice.} - \label{fig:fsalign} - \end{center} - \end{figure} - -c+ -Recalling (\secref{ss:framesetasframe}) that a FrameSet will behave -like its current Frame when necessary, conversion between two -FrameSets is performed using astConvert -(\secref{ss:convertingskyframes}), but supplying pointers to FrameSets -instead of Frames. The effect of this is to convert between the -coordinate systems represented by the current Frames of each FrameSet: -c- -f+ -Recalling (\secref{ss:framesetasframe}) that a FrameSet will behave -like its current Frame when necessary, conversion between two -FrameSets is performed using AST\_CONVERT -(\secref{ss:convertingskyframes}), but supplying pointers to FrameSets -instead of Frames. The effect of this is to convert between the -coordinate systems represented by the current Frames of each FrameSet: -f- - -c+ -\small -\begin{terminalv} -AstFrameSet *frameseta, *framesetb; - -... - -cvt = astConvert( frameseta, framesetb, "SKY" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER FRAMESETA, FRAMESETB - - ... - - CVT = AST_CONVERT( FRAMESETA, FRAMESETB, 'SKY', STATUS ) -\end{terminalv} -\normalsize -f- - -When using FrameSets, we are presented with considerably more -conversion options than when using Frames alone. This is because each -current Frame is related to all the other Frames in its respective -FrameSet. Therefore, if we can establish a link between any pair of -Frames, one from each FrameSet, we can form a complete conversion path -between the two current Frames (Figure~\ref{fig:fsalign}). - -This expanded range of options is, of course, precisely the -intention. By connecting Frames together within a FrameSet, we have -extended the range of coordinate systems that can be reached from any -one of them. We are therefore no longer restricted to converting -between Frames with the same Domain value (\secref{ss:framedomains}), -but can go \emph{via} a range of intermediate coordinate systems in -order to make the connection we require. Transformation between -different domains has therefore become possible because, in assembling -the FrameSets, we provided the additional information needed to -inter-relate them. - -It is important to appreciate, however, that the choice of ``missing -link'' is crucial in determining the conversion that results. -Although each FrameSet may be perfectly self-consistent internally, -this does not mean that all conversion paths through the combined -network of Mappings are equivalent. Quite the contrary in fact: -everything depends on where the inter-connecting link between the two -FrameSets is made. In practice, there may be a large number of -possible pairings of Frames and hence of possible links. Other factors -must therefore be used to restrict the choice. These are: - -\begin{enumerate} -\item Not every possible pairing of Frames is legitimate. For example, -you cannot convert directly between a basic Frame and a SkyFrame which -belong to different classes, so such pairings will be ignored. - -\item In a similar way, you cannot convert directly between Frames -with different Domain values (\secref{ss:framedomains}). If the Domain -attribute is used consistently (typically only one Frame in each -FrameSet will have a particular Domain value), then this further -restricts the choice. - -c+ -\item The third argument of astConvert may then be used to specify -c- -f+ -\item The third argument of AST\_CONVERT may then be used to specify -f- -explicitly which Domain value the paired Frames should have. You may -also supply a comma-separated list of preferences here (see below). - -\item If the above steps fail to uniquely identify the link, then the -first suitable pairing of Frames is used, so that any ambiguity is -resolved by the order in which Frames are considered for pairing (see -c+ -the description of the astConvert function in -c- -f+ -the description of the AST\_CONVERT function in -f- -\appref{ss:functiondescriptions} for details of the search -order).\footnote{If you find that how this ambiguity is resolved -actually makes a difference to the conversion that results, then you -have probably constructed a FrameSet which lacks internal -self-consistency. For example, you might have two Frames representing -indistinguishable coordinate systems but inter-related by a non-null -Mapping.} -\end{enumerate} - -In the example above we supplied the string ``SKY'' as the third -c+ -argument of astConvert. This constitutes a request that a pair of -Frames with -c- -f+ -argument of AST\_CONVERT. This constitutes a request that a pair of -Frames with -f- -the Domain value SKY (\emph{i.e.}\ representing celestial coordinate -systems) should be used to inter-relate the two FrameSets. Note that -this does not specify which celestial coordinate system to use, but is -a general request that the two FrameSets be inter-related using -coordinates on the celestial sphere. - -Of course, it may be that this request cannot be met because there may -not be a celestial coordinate system in both FrameSets. If this is -likely to happen, we can supply a list of preferences, or a -\emph{domain search path}, -c+ -as the third argument to astConvert, such as -c- -f+ -as the third argument to AST\_CONVERT, such as -f- -the following: - -c+ -\small -\begin{terminalv} -cvt = astConvert( frameseta, framesetb, "SKY,PIXEL,GRID," ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CVT = AST_CONVERT( FRAMESETA, FRAMESETB, 'SKY,PIXEL,GRID,', STATUS ) -\end{terminalv} -\normalsize -f- - -Now, if the two FrameSets cannot be inter-related using the SKY domain, -c+ -astConvert will attempt to use the PIXEL domain instead. If this -c- -f+ -AST\_CONVERT will attempt to use the PIXEL domain instead. If this -f- -also fails, it will try the GRID domain. A blank field in the domain -search path (here indicated by the final comma) allows any Domain -value to be used. This can be employed as a last resort when all else -has failed. - -c+ -If astConvert succeeds in identifying a conversion, it will return a -c- -f+ -If astConvert succeeds in identifying a conversion, it will return a -f- -pointer to a FrameSet (\secref{ss:framesetsfromconvert}) in which the -source and destination Frames are inter-connected by the required -Mapping. In this case, of course, these Frames will be the current -Frames of the two FrameSets, but in all other respects the returned -FrameSet is the same as when converting between Frames. - -c+ -Very importantly, however, astConvert may modify the FrameSets you are -converting between. It does this, in order to indicate which pairing -of Frames was used to inter-relate them, by changing the Base -attribute for each FrameSet so that the Frame used in the pairing -becomes its base Frame (\secref{ss:baseandcurrent}). -c- -f+ -Very importantly, however, AST\_CONVERT may modify the FrameSets you -are converting between. It does this, in order to indicate which -pairing of Frames was used to inter-relate them, by changing the Base -attribute for each FrameSet so that the Frame used in the pairing -becomes its base Frame (\secref{ss:baseandcurrent}). -f- - -c+ -Finally, note that astConvert may also be used to convert between a -FrameSet and a Frame, or \emph{vice versa}. If a pointer to a Frame is -supplied for either the first or second argument, it will behave like -a FrameSet containing only a single Frame. -c- -f+ -Finally, note that AST\_CONVERT may also be used to convert between a -FrameSet and a Frame, or \emph{vice versa}. If a pointer to a Frame is -supplied for either the first or second argument, it will behave like -a FrameSet containing only a single Frame. -f- - -\subsection{\label{ss:registeringimages}Example---Registering Two Images} - -Consider two images which have been calibrated by attaching FrameSets -to them, such that the base Frame of each FrameSet corresponds to the -raw data grid coordinates of each image (the GRID domain of -\secref{ss:domainconventions}). Suppose, also, that these FrameSets -contain an unknown number of other Frames, representing alternative -world coordinate systems. What we wish to do is register these two -images, such that we can transform from a position in the data grid of -one into the corresponding position in the data grid of the other. -This is a very practical example because images will typically be -calibrated using FrameSets in precisely this way. - -c+ -The first step will probably involve making a copy of both FrameSets -(using astCopy---\secref{ss:copyingobjects}), since we will be -modifying them. Let ``frameseta'' and ``framesetb'' be pointers to -these copies. Since we want to convert between the base Frames of -these FrameSets (\emph{i.e.}\ their data grid coordinates), the next -step is to make these Frames current. This is simply done by inverting -both FrameSets, which interchanges their base and current -Frames. astInvert will perform this task: -c- -f+ -The first step will probably involve making a copy of both FrameSets -(using AST\_COPY---\secref{ss:copyingobjects}), since we will be -modifying them. Let ``frameseta'' and ``framesetb'' be pointers to -these copies. Since we want to convert between the base Frames of -these FrameSets (\emph{i.e.}\ their data grid coordinates), the next -step is to make these Frames current. This is simply done by inverting -both FrameSets, which interchanges their base and current -Frames. astInvert will perform this task: -f- - -c+ -\small -\begin{terminalv} -astInvert( frameseta ); -astInvert( framesetb ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_INVERT( FRAMESETA, STATUS ) - CALL AST_INVERT( FRAMESETB, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -To identify the required conversion, we now use astConvert, supplying -a suitable domain search path with which we would like our two images -to be registered: -c- -f+ -To identify the required conversion, we now use AST\_CONVERT, -supplying a suitable domain search path with which we would like our -two images to be registered: -f- - -c+ -\small -\begin{terminalv} -cvt = astConvert( frameseta, framesetb, "SKY,PIXEL,GRID" ); -if ( cvt == AST__NULL ) { - -} else { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CVT = AST_CONVERT( FRAMESETA, FRAMESETB, 'SKY,PIXEL,GRID', STATUS ) - IF ( CVT .EQ. AST__NULL ) THEN - - ELSE - - END IF -\end{terminalv} -\normalsize -f- - -The effects of this are: - -\begin{enumerate} -c+ -\item astConvert first attempts to register the two images on the -c- -f+ -\item AST\_CONVERT first attempts to register the two images on the -f- -celestial sphere (\emph{i.e.}\ using the SKY domain). To do this, it -searches for a celestial coordinate system, although not necessarily -the same one, attached to each image. If it finds a suitable pair of -coordinate systems, it then registers the images by matching -corresponding positions on the sky. - -c+ -\item If this fails, astConvert next tries to match positions in the -c- -f+ -\item If this fails, AST\_CONVERT next tries to match positions in the -f- -PIXEL domain (\secref{ss:framedomains}). If it succeeds, the two -images will then be registered so that their corresponding pixel -positions correspond. If the PIXEL domain is offset from the data grid -(as typically happens in data reduction systems which implement a -``pixel origin''), then this will be correctly accounted for. - -\item If this also fails, the GRID domain is finally used. This will -result in image registration by matching corresponding points in the -data grids used by both images. This means they will be -aligned so that the first element their data arrays correspond. - -c+ -\item If all of the above fail, astConvert will return the value -c- -f+ -\item If all of the above fail, AST\_CONVERT will return the value -f- -AST\_\_NULL. Otherwise a pointer to a FrameSet will be returned. -\end{enumerate} - -c+ -The resulting ``cvt'' FrameSet may then be used directly -(\secref{ss:convertingskyframes}) to convert between positions in the -data grid of the first image and corresponding positions in the data -grid of the second image. -c- -f+ -The resulting CVT FrameSet may then be used directly -(\secref{ss:convertingskyframes}) to convert between positions in the -data grid of the first image and corresponding positions in the data -grid of the second image. -f- - -To determine which domain was used to achieve registration, -we can use the fact that the Base attribute of each FrameSet is set by -c+ -astConvert to indicate which intermediate Frames were used. We -c- -f+ -AST\_CONVERT to indicate which intermediate Frames were used. We -f- -can therefore simply invert either FrameSet (to make its base Frame -become the current one) and then enquire the Domain value: - -c+ -\small -\begin{terminalv} -const char *domain; - -... - -astInvert( frameseta ); -domain = astGetC( frameseta, "Domain" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 20 ) DOMAIN - - ... - - - CALL AST_INVERT( FRAMESETA, STATUS ) - DOMAIN = AST_GETC( FRAMESETA, 'Domain', STATUS ) -\end{terminalv} -\normalsize -f- - -If conversion was successful, the result will be one of the strings -``SKY'', ``PIXEL'' or ``GRID''. - -\subsection{\label{ss:remapframe}Re-Defining a FrameSet Coordinate System} - -As discussed earlier (\secref{ss:baseandcurrent}), an important -application of a FrameSet is to allow coordinate system information to -be attached to entities such as images in order to calibrate them. In -addition, one of the main objectives of AST is to simplify the -propagation of such information through successive stages of data -processing, so that it remains consistent with the associated image -data. - -In such a situation, the FrameSet's base Frame would correspond with -the image's data grid coordinates and its other Frames (if any) with -the various alternative world coordinate systems associated with the -image. If the data processing being performed does not change the -relationship between the image's data grid coordinates and any of the -associated world coordinate systems, then propagation of the WCS -information is straightforward and simply involves copying the -FrameSet associated with the image. - -If any of these relationships change, however, then corresponding -changes must be made to the way Frames within the FrameSet are -inter-related. By far the most common case occurs when the image -undergoes some geometrical transformation resulting in ``re-gridding'' -on to another data grid, but the same principles can be applied to any -re-definition of a coordinate system. - -To pursue the re-gridding example, we would need to modify our -FrameSet to account for the fact that the image's data grid coordinate -system (corresponding to the FrameSet's base Frame) has -changed. Looking at the steps needed in detail, we might proceed as -follows: - -\begin{enumerate} -\item Create a Mapping which represents the relationship between the -original data grid coordinate system and the new one. - -c+ -\item Obtain a Frame to represent the new data grid coordinate system -(we could re-use the original base Frame here, using astGetFrame to -obtain a pointer to it). -c- -f+ -\item Obtain a Frame to represent the new data grid coordinate system -(we could re-use the original base Frame here, using AST\_GETFRAME to -obtain a pointer to it). -f- - -\item Add the new Frame to the FrameSet, related to the original base -Frame by the new Mapping. This Frame now represents the new data grid -coordinate system and is correctly related to all the other Frames -present.\footnote{This is because any transformation to or from this -new Frame must go \emph{via} the base Frame representing the original -data grid coordinate system, which we assume was correctly related to -all the other Frames present.} - -\item Remove the original base Frame (representing the old data grid -coordinate system). - -\item Make the new Frame the base Frame and restore the original -current Frame. -\end{enumerate} - - The effect of these steps is to change the relationship between the - base Frame and all the other Frames present. It is as if a new Mapping - has been interposed between the Frame we want to alter and all the - other Frames within the FrameSet (Figure~\ref{fig:fsremap}). - \begin{figure}[hbtp] - \begin{center} -c+ - \includegraphics[width=0.7\textwidth]{sun211_figures/fsremap} -c- -f+ - \includegraphics[width=0.7\textwidth]{sun210_figures/fsremap} -f- -\caption[Interposing a Mapping into a FrameSet]{The effect -c+ - of astRemapFrame is to interpose a Mapping between -c- -f+ - of AST\_REMAPFRAME is to interpose a Mapping between -f- - a nominated Frame within a FrameSet and the remaining contents of the - FrameSet. This effectively ``re-defines'' the coordinate system - represented by the affected Frame. It may be used to compensate (say) - for geometrical changes made to an associated image. The - inter-relationships between all the other Frames within the FrameSet - remain unchanged.} - \label{fig:fsremap} - \end{center} - \end{figure} - -c+ -Performing the steps above is rather lengthy, however, so the -astRemapFrame function is provided to perform all of these operations -in one go. A practical example of its use is given below -(\secref{ss:wcsprocessingexample}). -c- -f+ -Performing the steps above is rather lengthy, however, so the -AST\_REMAPFRAME function is provided to perform all of these -operations in one go. A practical example of its use is given below -(\secref{ss:wcsprocessingexample}). -f- - -\subsection{\label{ss:wcsprocessingexample}Example---Binning an Image} - -c+ -As an example of using astRemapFrame, consider a case where the pixels -of a 2-dimensional image have been binned 2$\times$2, so as to reduce -the image size by a factor of two in each dimension. We must now -modify the associated FrameSet to reflect this change to the -image. Much the same process would be needed for any other geometrical -change the image might undergo. -c- -f+ -As an example of using AST\_REMAPFRAME, consider a case where the -pixels of a 2-dimensional image have been binned 2$\times$2, so as to -reduce the image size by a factor of two in each dimension. We must -now modify the associated FrameSet to reflect this change to the -image. Much the same process would be needed for any other geometrical -change the image might undergo. -f- - -We first set up a Mapping (a WinMap in this case) which relates the -data grid coordinates in the original image to those in the new one: - -c+ -\small -\begin{terminalv} -AstWinMap *winmap; -double ina[ 2 ] = { 0.5, 0.5 }; -double inb[ 2 ] = { 2.5, 2.5 }; -double outa[ 2 ] = { 0.5, 0.5 }; -double outb[ 2 ] = { 1.5, 1.5 }; - -... - -winmap = astWinMap( 2, ina, inb, outa, outb, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER WINMAP - DOUBLE PRECISION INA( 2 ), INB( 2 ), OUTA( 2 ), OUTB( 2 ) - DATA INA / 0.5D0, 0.5D0 / - DATA INB / 2.5D0, 2.5D0 / - DATA OUTA / 0.5D0, 0.5D0 / - DATA OUTB / 1.5DO, 1.5DO / - - ... - - WINMAP = AST_WINMAP( 2, INA, INB, OUTA, OUTB, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, we have simply set up arrays containing the data grid -coordinates of the bottom left and top right corners of the first -element in the output image (``outa'' and ``outb'') and the -corresponding coordinates in the input image (``ina'' and -``inb''). astWinMap then creates a WinMap which performs the required -transformation. We do not need to know the size of the image. -c- -f+ -Here, we have simply set up arrays containing the data grid -coordinates of the bottom left and top right corners of the first -element in the output image (OUTA and OUTB) and the corresponding -coordinates in the input image (INA and INB). AST\_WINMAP then creates -a WinMap which performs the required transformation. We do not need to -know the size of the image. -f- - -c+ -We can then pass this WinMap to astRemapFrame. This modifies the -relationship between our FrameSet's base Frame and the other Frames in -the FrameSet, so that the base Frame represents the data grid -coordinate system of the new image rather than the old one: -c- -f+ -We can then pass this WinMap to AST\_REMAPFRAME. This modifies the -relationship between our FrameSet's base Frame and the other Frames in -the FrameSet, so that the base Frame represents the data grid -coordinate system of the new image rather than the old one: -f- - -c+ -\small -\begin{terminalv} -AstFrameSet *frameset; - -... - -astRemapFrame( frameset, AST__BASE, winmap ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER FRAMESET - - ... - - CALL AST_REMAPFRAME( FRAMESET, AST__BASE, WINMAP, STATUS ) -\end{terminalv} -\normalsize -f- - -Any other coordinate systems described by the FrameSet, no matter how -many of these there might be, are now correctly associated with the -new image. - -\subsection{\label{ss:framesetintegrity}Maintaining the Integrity of FrameSets} - -When constructing a FrameSet, you are provided with a framework into -which you can place any combination of Frames and Mappings that you -wish. There are relatively few constraints on this process and no -checks are performed to see whether the FrameSet you construct makes -physical sense. It is quite possible, for example, to construct a -FrameSet containing two identical SkyFrames which are inter-related by -a non-unit Mapping. AST will not object if you do this, but it makes -no sense, because applying a non-unit Mapping to any set of celestial -coordinates cannot yield positions that are still in the original -coordinate system. If you use such a FrameSet to perform coordinate -conversions, you are likely to get unpredictable results because the -information in the FrameSet is corrupt. - -It is, of course, your responsibility as a programmer to ensure the -validity of any information which you insert into a -FrameSet. Normally, this is straightforward and simply consists of -formulating your problem correctly (a diagram can often help to -clarify how coordinate systems are inter-related) and writing the -appropriate bug-free code to construct the FrameSet. However, once you -start to modify an existing FrameSet, there are new opportunities for -corrupting it! - -c+ -Consider, for example, a FrameSet whose current Frame is a -SkyFrame. We can set a new value for this SkyFrame's Equinox attribute -simply by using astSet on the FrameSet, as follows: -c- -f+ -Consider, for example, a FrameSet whose current Frame is a -SkyFrame. We can set a new value for this SkyFrame's Equinox attribute -simply by using AST\_SET on the FrameSet, as follows: -f- - -c+ -\small -\begin{terminalv} -astSet( frameset, "Equinox=J2010" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( FRAMESET, 'Equinox=J2010', STATUS ) -\end{terminalv} -\normalsize -f- - -The effect of this will be to change the celestial coordinate system -which the current Frame represents. You can see, however, that this -has the potential to make the FrameSet corrupt unless corresponding -changes are also made to the Mapping which relates this SkyFrame to -the other Frames within the FrameSet. In fact, it is a general rule -that any change to a FrameSet which affects its current Frame can -potentially require corresponding changes to the FrameSet's Mappings -in order to maintain its overall integrity. - -c+ -Fortunately, once you have stored valid information in a FrameSet, AST -will look after these details for you automatically, so that the -FrameSet's integrity is maintained. In the example above, it would do -this by appropriately re-mapping the current Frame (as if -astRemapFrame had been used---\secref{ss:remapframe}) in response to -the use of astSet. One way of illustrating this process is as follows: -c- -f+ -Fortunately, once you have stored valid information in a FrameSet, AST -will look after these details for you automatically, so that the -FrameSet's integrity is maintained. In the example above, it would do -this by appropriately re-mapping the current Frame (as if -AST\_REMAPFRAME had been used---\secref{ss:remapframe}) in response to -the use of AST\_SET. One way of illustrating this process is as -follows: -f- - -c+ -\small -\begin{terminalv} -AstSkyFrame *skyframe; - -... - -skyframe = astSkyFrame( "" ); -frameSet = astFrameSet( skyframe ); -astAddFrame( frameset, 1, astUnitMap( 2, "" ), skyframe ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER SKYFRAME - - ... - - SKYFRAME = AST_SKYFRAME( ' ', STATUS ) - FRAMESET = AST_FRAMESET( SKYFRAME, STATUS ) - CALL AST_ADDFRAME( FRAMESET, 1, AST_UNITMAP( 2, ' ', STATUS ) - : SKYFRAME, STATUS ) -\end{terminalv} -\normalsize -f- - -This constructs a trivial FrameSet whose base and current Frames are -both the same SkyFrame connected by a UnitMap. You can think of this -as a ``pipe'' connecting two coordinate systems. At present, these two -systems represent identical ICRS coordinates, so the FrameSet -implements a unit Mapping. We can change the coordinate system on the -current end of this pipe as follows: - -c+ -\small -\begin{terminalv} -astSet( frameset, "System=Ecliptic, Equinox=J2010" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( FRAMESET, 'System=Ecliptic, Equinox=J2010', STATUS ) -\end{terminalv} -\normalsize -f- - -and the Mapping which the FrameSet implements would change -accordingly. To change the coordinate system on the base end of the -pipe, we might use: - -c+ -\small -\begin{terminalv} -astInvert( frameset ); -astSet( frameset, "System=Galactic" ); -astInvert( frameset ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_INVERT( FRAMESET ) - CALL AST_SET( FRAMESET, 'System=Galactic', STATUS ) - CALL AST_INVERT( FRAMESET ) -\end{terminalv} -\normalsize -f- - -The FrameSet would then convert between galactic and ecliptic -coordinates. - -c+ -Note that astSet is not the only function which has this effect: -astClear behaves similarly, as also does astPermAxes -(\secref{ss:permutingaxes}). If you need to circumvent this mechanism -for any reason, this can be done by going behind the scenes and -obtaining a pointer directly to the Frame you wish to modify. Consider -the following, for example: -c- -f+ -Note that AST\_SET is not the only function which has this effect: -AST\_CLEAR behaves similarly, as also does AST\_PERMAXES -(\secref{ss:permutingaxes}). If you need to circumvent this mechanism -for any reason, this can be done by going behind the scenes and -obtaining a pointer directly to the Frame you wish to modify. Consider -the following, for example: -f- - -c+ -\small -\begin{terminalv} -skyframe = astGetFrame( frameset, AST__CURRENT ); -astSet( skyframe, "Equinox=J2010" ); -skyframe = astAnnul( skyframe ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - SKYFRAME = AST_GETFRAME( FRAMESET, AST__CURRENT, STATUS ) - CALL AST_SET( SKYFRAME, 'Equinox=J2010', STATUS ) - CALL AST_ANNUL( SKYFRAME, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, astSet is applied to the SkyFrame pointer rather than the -FrameSet pointer, so the usual checks on FrameSet integrity do not -occur. The SkyFrame's Equinox attribute will therefore be modified -without any corresponding change to the FrameSet's Mappings. In this -case you must take responsibility yourself for maintaining the -FrameSet's integrity, perhaps through appropriate use of -astRemapFrame. -c- -f+ -Here, AST\_SET is applied to the SkyFrame pointer rather than the -FrameSet pointer, so the usual checks on FrameSet integrity do not -occur. The SkyFrame's Equinox attribute will therefore be modified -without any corresponding change to the FrameSet's Mappings. In this -case you must take responsibility yourself for maintaining the -FrameSet's integrity, perhaps through appropriate use of -AST\_REMAPFRAME. -f- - -\subsection{Merging FrameSets} - - As well as adding individual Frames to a FrameSet - (\secref{ss:addingframes}), it is also possible to add complete sets of - inter-related Frames which are contained within another - FrameSet. This, of course, corresponds to the process of merging two - FrameSets (Figure~\ref{fig:fsmerge}). - \begin{figure}[hbtp] - \begin{center} -c+ - \includegraphics[width=0.7\textwidth]{sun211_figures/fsmerge} -c- -f+ - \includegraphics[width=0.7\textwidth]{sun210_figures/fsmerge} -f- - \caption[Two FrameSets in the process of being merged.]{Two FrameSets in the process of being merged using -c+ - astAddFrame. FrameSet~B is being added to FrameSet~A by supplying a -c- -f+ - AST\_ADDFRAME. FrameSet~B is being added to FrameSet~A by supplying a -f- - new Mapping which inter-relates a nominated Frame in A (here number~1) - and the current Frame of B. In the merged FrameSet, the Frames - contributed by B will be re-numbered to become Frames~4, 5 and 6. The - base Frame will remain unchanged, but the current Frame of B becomes - the new current Frame. Note that FrameSet~B itself is not - altered by this process.} - \label{fig:fsmerge} - \end{center} - \end{figure} - - - -c+ -This process is performed by adding one FrameSet to another using -astAddFrame, in much the same manner as when adding a new Frame to an -existing FrameSet (\secref{ss:addingframes}). It is simply a matter of -providing a FrameSet pointer, instead of a Frame pointer, for the 4th -argument. In performing the merger you must, as usual, supply a -Mapping, but in this case the Mapping should relate the current Frame -of the FrameSet being added to one of the Frames already present. For -example, you might perform the merger shown in -Figure~\ref{fig:fsmerge} as follows: -c- -f+ -This process is performed by adding one FrameSet to another using -AST\_ADDFRAME, in much the same manner as when adding a new Frame to -an existing FrameSet (\secref{ss:addingframes}). It is simply a matter -of providing a FrameSet pointer, instead of a Frame pointer, for the -4th argument. In performing the merger you must, as usual, supply a -Mapping, but in this case the Mapping should relate the current Frame -of the FrameSet being added to one of the Frames already present. For -example, you might perform the merger shown in -Figure~\ref{fig:fsmerge} as follows: -f- - -c+ -\small -\begin{terminalv} -AstMapping *mapping; - -... - -astAddFrame( frameseta, 1, mapping, framesetb ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER MAPPING - - ... - - CALL AST_ADDFRAME( FRAMESETA, 1, MAPPING, FRAMESETB, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -The Frames acquired by ``frameseta'' from the FrameSet being added -(``framesetb'') are re-numbered so that they retain their original -order and follow on consecutively after the Frames that were already -present, whose indices remain unchanged. The base Frame of -``frameseta'' remains unchanged, but the current Frame of -``framesetb'' becomes its new current Frame. All the -inter-relationships between Frames in both FrameSets remain in place -and are preserved in the merged FrameSet. -c- -f+ -The Frames acquired by FRAMESETA from the FrameSet being added -(FRAMESETB) are re-numbered so that they retain their original order -and follow on consecutively after the Frames that were already -present, whose indices remain unchanged. The base Frame of FRAMESETA -remains unchanged, but the current Frame of FRAMESETB becomes its new -current Frame. All the inter-relationships between Frames in both -FrameSets remain in place and are preserved in the merged FrameSet. -f- - -c+ -Note that while this process modifies the first FrameSet -(``frameseta''), it leaves the original contents of the one being -added (``framesetb'') unchanged. -c- -f+ -Note that while this process modifies the first FrameSet (FRAMESETA), -it leaves the original contents of the one being added (FRAMESETB) -unchanged. -f- - -%\cleardoublepage -%\section{\label{ss:searching}TBW - Searching for Coordinate Systems} - -\cleardoublepage -\section{\label{ss:channels}Saving and Restoring Objects (Channels)} - -Facilities are provided by the AST library for performing input and -output (I/O) with any kind of Object. This means it is possible -to write any Object into various external representations for -storage, and then to read these representations back in, so as to -restore the original Object. Typically, an Object would be written by -one program and read back in by another. - -We refer to ``external representations'' in the plural because AST is -designed to function independently of any particular data storage -system. This means that Objects may need converting into a number of -different external representations in order to be compatible with -(say) the astronomical data storage system in which they will reside. - -In this section, we discuss the basic I/O facilities which support -external representations based on a textual format referred to as the AST -``native format''. These are implemented using a new kind of Object---a -Channel. We will examine later how to use other representations, based on -an XML format or on the use of FITS headers, for storing Objects. These -are implemented using more specialised forms of Channel called XmlChan -(\secref{ss:xmlchan}) and FitsChan (\secref{ss:nativefits}). - -\subsection{The Channel Model} - -c+ -The best way to start thinking about a Channel is like a C file -stream, and to think of the process of creating a Channel as that -of opening a file and obtaining a FILE pointer. Subsequently, you can -read and write Objects \emph{via} the Channel. -c- -f+ -The best way to start thinking about a Channel is like a Fortran I/O -unit (also represented by an integer, as it happens) and to think of -the process of creating a Channel as the combined process of -allocating a unit number and attaching it to a file by opening the -file on that unit. Subsequently, you can read and write Objects -\emph{via} the Channel. -f- - -c+ -This analogy is not quite perfect, however, because a Channel has, in -principle, two ``files'' attached to it. One is used when reading, and -the other when writing. These are termed the Channel's \emph{source} -and \emph{sink} respectively. In practice, the source and sink may -both be the same, in which case the analogy with the C file stream is -correct, but this need not always be so. It is not necessarily so with -the basic Channel, as we will now see (\secref{ss:creatingachannel}). -c- -f+ -This analogy is not quite perfect, however, because a Channel has, in -principle, two ``files'' attached to it. One is used when reading, and -the other when writing. These are termed the Channel's \emph{source} -and \emph{sink} respectively. In practice, the source and sink may -both be the same, in which case the analogy with the Fortran I/O unit -is correct, but this need not always be so. It is not necessarily so -with the basic Channel, as we will now see -(\secref{ss:creatingachannel}). -f- - -\subsection{\label{ss:creatingachannel}Creating a Channel} - -c+ -The process of creating a Channel is straightforward. As you -might expect, it uses the constructor function astChannel: - -\small -\begin{terminalv} -#include "ast.h" -AstChannel *channel; - -... - -channel = astChannel( NULL, NULL, "" ); -\end{terminalv} -\normalsize - -The first two arguments to astChannel specify the external source and -sink that the Channel is to use. There arguments are pointers to C -functions and we will examine their use in more detail later -(\secref{ss:channelsource} and \secref{ss:channelsink}). -c- -f+ -The process of creating a Channel is straightforward. As you -might expect, it uses the constructor function AST\_CHANNEL: - -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER CHANNEL, STATUS - - STATUS = 0 - - ... - - CHANNEL = AST_CHANNEL( AST_NULL, AST_NULL, ' ', STATUS ) -\end{terminalv} -\normalsize - -The first two arguments to AST\_CHANNEL specify the external source -and sink that the Channel is to use. There arguments are the names of -Fortran subroutines and we will examine their use in more detail later -(\secref{ss:channelsource} and \secref{ss:channelsink}). -f- - -c+ -In this very simple example we have supplied NULL pointers for both -the source and sink functions. This requests the default behaviour, -which means that textual input will be read from the program's -standard input stream (typically, this means your keyboard) while -textual output will go to the standard output stream (typically -appearing on your screen). On UNIX systems, of course, either of these -streams can easily be redirected to files. This default behaviour can be -changed by assigning values to the Channel's SinkFile and/or SourceFile -attributes. These attributes specify the paths to text files that are to -be used in place of the standard input and output streams. -c- -f+ -In this very simple example we have supplied the name of the null -routine AST\_NULL\footnote{Note that AST\_NULL (one underscore) is a -routine name and is distinct from AST\_\_NULL (two underscores) which -is a null Object pointer. Since we are passing the name of one -routine to another routine, AST\_NULL would normally have to appear in -a Fortran EXTERNAL statement. In this example, however, a suitable -statement is already present in the AST\_PAR include file.} for both -the source and sink routines. This requests the default behaviour, -which means that textual input will be read from the program's -standard input stream (typically, this means your keyboard) while -textual output will go to the standard output stream (typically -appearing on your screen). On UNIX systems, of course, either of these -streams can easily be redirected to files. -f- - -\subsection{\label{ss:writingtoachannel}Writing Objects to a Channel} - -c+ -The process of saving Objects is very straightforward. You can -simply write any Object to a Channel using the astWrite -function, as follows: - -\small -\begin{terminalv} -int nobj; -AstObject *object; - -... - -nobj = astWrite( channel, object ); -\end{terminalv} -\normalsize -c- -f+ -The process of saving Objects is very straightforward. You can -simply write any Object to a Channel using the AST\_WRITE -function, as follows: - -\small -\begin{terminalv} - INTEGER NOBJ, OBJECT - - ... - - NOBJ = AST_WRITE( CHANNEL, OBJECT, STATUS ) -\end{terminalv} -\normalsize -f- - -The effect of this will be to produce a textual description of the -Object which will appear, by default, on your program's standard -output stream. Any class of Object may be converted into text in this -way. - -c+ -astWrite returns a count of the number of Objects written. Usually, -this will be one, unless the Object supplied cannot be -represented. With a basic Channel all Objects can be represented, so a -value of one will always be returned unless there has been an -error. We will see later, however, that more specialised forms of -Channel may impose restrictions on the kind of Object you can write -(\secref{ss:foreignfitslimitations}). In such cases, astWrite may -return zero to indicate that the Object was not acceptable. -c- -f+ -AST\_WRITE returns a count of the number of Objects written. Usually, -this will be one, unless the Object supplied cannot be -represented. With a basic Channel all Objects can be represented, so a -value of one will always be returned unless there has been an -error. We will see later, however, that more specialised forms of -Channel may impose restrictions on the kind of Object you can write -(\secref{ss:foreignfitslimitations}). In such cases, AST\_WRITE may -return zero to indicate that the Object was not acceptable. -f- - -\subsection{\label{ss:readingfromachannel}Reading Objects from a Channel} - -Before discussing the format of the output produced above -(\secref{ss:writingtoachannel}), let us consider how to read it back, -so as to reconstruct the original Object. Naturally, we would first -need to save the output in a file. We can do that either by using the -SinkFile attribute, or (on UNIX systems), by redirecting standard output -to a file using a shell command like: - -\small -\begin{terminalv} -program1 >file -\end{terminalv} -\normalsize - -c+ -Within a subsequent program, we can read this Object back in by -using the astRead function, having first created a suitable -Channel: - -\small -\begin{terminalv} -object = astRead( channel ); -\end{terminalv} -\normalsize -c- -f+ -Within a subsequent program, we can read this Object back in by -using the AST\_READ function, having first created a suitable -Channel: - -\small -\begin{terminalv} - OBJECT = AST_READ( CHANNEL, STATUS ) -\end{terminalv} -\normalsize -f- - -By default, this function will read from the standard input stream -(the default source for a basic Channel), so we would need to ensure -that our second program reads its input from the file in which the -Object description is stored. On UNIX systems, we could again use a -shell redirection command such as: - -\small -\begin{terminalv} -program2 $ family of functions: - -\small -\begin{terminalv} -int ok; - -... - -ok = astIsAFrame( object ); -\end{terminalv} -\normalsize -c- -f+ -The pointer returned by AST\_READ (\secref{ss:readingfromachannel}) -could identify any class of Object---this is determined entirely by -the external data being read. If it is necessary to test for a -particular class (say a Frame), this may be done as follows using the -appropriate member of the AST\_ISA$<$CLASS$>$ family of functions: - -\small -\begin{terminalv} - LOGICAL OK - - ... - - OK = AST_ISAFRAME( OBJECT, STATUS ) -\end{terminalv} -\normalsize -f- - -Note, however, that this will accept any Frame, so would be equally -happy with a basic Frame or a SkyFrame. An alternative validation -strategy would be to obtain the value of the Object's Class attribute -and then test this character string, as follows: - -c+ -\small -\begin{terminalv} -#include - -... - -ok = !strcmp( astGetC( object, "Class" ), "Frame" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - OK = AST_GETC( OBJECT, 'Class', STATUS ) .EQ. 'Frame' -\end{terminalv} -\normalsize -f- - -This would only accept a basic Frame and would reject a SkyFrame. - -\subsection{Storing an ID String with an Object} - -Occasionally, you may want to store a number of Objects and later -retrieve them and use each for a different purpose. If the Objects are -of the same class, you cannot use the Class attribute to distinguish -them when you read them back -(\emph{c.f.}~\secref{ss:validatinginput}). Although relying on the -order in which they are stored is a possible solution, this becomes -complicated if some of the Objects are optional and may not always be -present. It also makes extending your data format in future more -difficult. - -To help with this, every AST Object has an ID attribute and an Ident -attribute, both of which allows you, in effect, to attach a textual -identification label to it. You simply set the ID or Ident attribute before -writing the Object: - -c+ -\small -\begin{terminalv} -astSet( object, "ID=Calibration" ); -nobj = astWrite( channel, object ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( OBJECT, 'ID=Calibration', STATUS ) - NOBJ = AST_WRITE( CHANNEL, OBJECT, STATUS ) -\end{terminalv} -\normalsize -f- - -You can then test its value after you read the Object back: - -c+ -\small -\begin{terminalv} -object = astRead( channel ); -if ( !strcmp( astGetC( object, "ID" ), "Calibration" ) ) { - -} else { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - OBJECT = AST_READ( CHANNEL, STATUS ) - IF ( AST_GETC( OBJECT, 'ID', STATUS ) .EQ. 'Calibration' ) THEN - - ELSE - - END IF -\end{terminalv} -\normalsize -f- - -The only difference between the ID and Ident attributes is that the ID -attribute is unique to a particular Object and is lost if, for example, -you make a copy of the Object. The Ident attrubute, on the other hand, is -transferred to the new Object when a copy is made. Consequently, it is -safest to set the value of the ID attribute immediately before you -perform the write. - -\subsection{\label{ss:textualoutputformat}The Textual Output Format} - -Let us now examine the format of the textual output produced by -writing an Object to a basic Channel -(\secref{ss:writingtoachannel}). To give a concrete example, suppose -the Object in question is a SkyFrame, written out as follows: - -c+ -\small -\begin{terminalv} -AstSkyFrame *skyframe; - -... - -nobj = astWrite( channel, skyframe ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER SKYFRAME - - ... - - NOBJ = AST_WRITE( CHANNEL, SKYFRAME, STATUS ) -\end{terminalv} -\normalsize -f- - -The output should then look like the following: - -\small -\begin{terminalv} - Begin SkyFrame # Description of celestial coordinate system -# Title = "FK4 Equatorial Coordinates, no E-terms, Mean Equinox B1950.0, Epoch B1958.0" # Title of coordinate system - Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Lbl1 = "Right Ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction (hint) - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - System = "FK4-NO-E" # Celestial coordinate system type - Epoch = 1958 # Besselian epoch of observation -# Eqnox = 1950 # Besselian epoch of mean equinox - End SkyFrame -\end{terminalv} -\normalsize - -c+ -You will notice that this output is designed both for a human reader, -in that it is formatted, and also to be read back by a computer in -order to reconstruct the SkyFrame. In fact, this is precisely the way -that astShow works (\secref{ss:displayingobjects}), this function being -roughly equivalent to the following use of a Channel: - -\small -\begin{terminalv} -channel = astChannel( NULL, NULL, "" ); -(void) astWrite( channel, object ); -channel = astAnnul( channel ); -\end{terminalv} -\normalsize -c- -f+ -You will notice that this output is designed both for a human reader, -in that it is formatted, and also to be read back by a computer in -order to reconstruct the SkyFrame. In fact, this is precisely the way -that AST\_SHOW works (\secref{ss:displayingobjects}), this routine -being roughly equivalent to the following use of a Channel: - -\small -\begin{terminalv} - CHANNEL = AST_CHANNEL( AST_NULL, AST_NULL, ' ', STATUS ) - NOBJ = AST_WRITE( CHANNEL, OBJECT, STATUS ) - CALL AST_ANNUL( CHANNEL, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Some lines of the output start with a ``\verb?#?'' comment character, -which turns the rest of the line into a comment. These lines will be -ignored when read back in by astRead. They typically contain default -values, or values that can be derived in some way from the other data -present, so that they do not actually need to be stored in order to -reconstruct the original Object. They are provided purely for human -information. The same comment character is also used to append -explanatory comments to most output lines. -c- -f+ -Some lines of the output start with a ``\verb?#?'' comment character, -which turns the rest of the line into a comment. These lines will be -ignored when read back in by AST\_READ. They typically contain -default values, or values that can be derived in some way from the -other data present, so that they do not actually need to be stored in -order to reconstruct the original Object. They are provided purely for -human information. The same comment character is also used to append -explanatory comments to most output lines. -f- - -It is not sensible to attempt a complete description of this output -format because every class of Object is potentially different and each -can define how its own data should be represented. However, there are -some basic rules, which mean that the following common features will -usually be present: - -\begin{enumerate} -\item Each Object is delimited by matching ``Begin'' and ``End'' -lines, which also identify the class of Object involved. - -\item Within each Object description, data values are represented -by a simple ``keyword~$=$~value'' syntax, with one value to a line. - -\item Lines beginning ``IsA'' are used to mark the divisions between -data belonging to different levels in the class hierarchy -(\appref{ss:classhierarchy}). Thus, ``IsA~Frame'' marks the end of data -associated with the Frame class and the start of data associated with -some derived class (a SkyFrame in the above example). ``IsA'' lines -may be omitted if associated data values are absent and no confusion -arises. - -\item Objects may contain other Objects as data. This is -indicated by an absent value, with the description of the data -Object following on subsequent lines. - -\item Indentation is used to clarify the overall structure. -\end{enumerate} - -Beyond these general principles, the best guide to what a particular -line of output represents will generally be the comment which -accompanies it together with a general knowledge of the class of -Object being described. - -\subsection{\label{ss:controllingchanneloutput}Controlling the Amount of Output} - -c+ -It is not always necessary for the output from astWrite -(\secref{ss:writingtoachannel}) to be human-readable, so a Channel has -attributes that allow the amount of detail in the output to be -controlled. -c- -f+ -It is not always necessary for the output from AST\_WRITE -(\secref{ss:writingtoachannel}) to be human-readable, so a Channel has -attributes that allow the amount of detail in the output to be -controlled. -f- - -The first of these is the integer attribute Full, which controls the -extent to which optional, commented out, output lines are produced. By -default, Full is zero, and this results in the standard style of -output (\secref{ss:textualoutputformat}) where default values that may -be helpful to humans are included. To suppress these optional lines, -Full should be set to $-$1. This is most conveniently done when the -Channel is created, so that: - -c+ -\small -\begin{terminalv} -channel = astChannel( NULL, NULL, "Full=-1" ); -(void) astWrite( channel, skyframe ); -channel = astAnnul( channel ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHANNEL = AST_CHANNEL( AST_NULL, AST_NULL, 'Full=-1', STATUS ) - NOBJ = AST_WRITE( CHANNEL, SKYFRAME, STATUS ) - CALL AST_ANNUL( CHANNEL, STATUS ) -\end{terminalv} -\normalsize -f- - -would result in output containing only the essential information, such -as: - -\small -\begin{terminalv} - Begin SkyFrame # Description of celestial coordinate system - Naxes = 2 # Number of coordinate axes - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis - End SkyAxis - IsA Frame # Coordinate system description - System = "FK4-NO-E" # Celestial coordinate system type - Epoch = 1958 # Besselian epoch of observation - End SkyFrame -\end{terminalv} -\normalsize - -In contrast, setting Full to $+$1 will result in additional output -lines which will reveal every last detail of the Object's -construction. Often this will be rather more than you want, especially -for more complex Objects, but it can sometimes help when debugging -programs. This is how a SkyFrame appears at this level of detail: - -\small -\begin{terminalv} - Begin SkyFrame # Description of celestial coordinate system -# RefCnt = 1 # Count of active Object pointers -# Nobj = 1 # Count of active Objects in same class - IsA Object # Astrometry Object -# Nin = 2 # Number of input coordinates -# Nout = 2 # Number of output coordinates -# Invert = 0 # Mapping not inverted -# Fwd = 1 # Forward transformation defined -# Inv = 1 # Inverse transformation defined -# Report = 0 # Don't report coordinate transformations - IsA Mapping # Mapping between coordinate systems -# Title = "FK4 Equatorial Coordinates, no E-terms, Mean Equinox B1950.0, Epoch B1958.0" # Title of coordinate system - Naxes = 2 # Number of coordinate axes -# Domain = "SKY" # Coordinate system domain -# Lbl1 = "Right Ascension" # Label for axis 1 -# Lbl2 = "Declination" # Label for axis 2 -# Sym1 = "RA" # Symbol for axis 1 -# Sym2 = "Dec" # Symbol for axis 2 -# Uni1 = "hh:mm:ss.s" # Units for axis 1 -# Uni2 = "ddd:mm:ss" # Units for axis 2 -# Dig1 = 7 # Individual precision for axis 1 -# Dig2 = 7 # Individual precision for axis 2 -# Digits = 7 # Default formatting precision -# Fmt1 = "hms.1" # Format specifier for axis 1 -# Fmt2 = "dms" # Format specifier for axis 2 -# Dir1 = 0 # Plot axis 1 in reverse direction (hint) -# Dir2 = 1 # Plot axis 2 in conventional direction (hint) -# Presrv = 0 # Don't preserve target axes -# Permut = 1 # Axes may be permuted to match -# MinAx = 2 # Minimum number of axes to match -# MaxAx = 2 # Maximum number of axes to match -# MchEnd = 0 # Match initial target axes -# Prm1 = 1 # Axis 1 not permuted -# Prm2 = 2 # Axis 2 not permuted - Ax1 = # Axis number 1 - Begin SkyAxis # Celestial coordinate axis -# RefCnt = 1 # Count of active Object pointers -# Nobj = 2 # Count of active Objects in same class - IsA Object # Astrometry Object -# Label = "Angle on Sky" # Axis Label -# Symbol = "delta" # Axis symbol -# Unit = "ddd:mm:ss" # Axis units -# Digits = 7 # Default formatting precision -# Format = "dms" # Format specifier -# Dirn = 1 # Plot in conventional direction - IsA Axis # Coordinate axis -# Format = "dms" # Format specifier -# IsLat = 0 # Longitude axis (not latitude) -# AsTime = 0 # Display values as angles (not times) - End SkyAxis - Ax2 = # Axis number 2 - Begin SkyAxis # Celestial coordinate axis -# RefCnt = 1 # Count of active Object pointers -# Nobj = 2 # Count of active Objects in same class - IsA Object # Astrometry Object -# Label = "Angle on Sky" # Axis Label -# Symbol = "delta" # Axis symbol -# Unit = "ddd:mm:ss" # Axis units -# Digits = 7 # Default formatting precision -# Format = "dms" # Format specifier -# Dirn = 1 # Plot in conventional direction - IsA Axis # Coordinate axis -# Format = "dms" # Format specifier -# IsLat = 0 # Longitude axis (not latitude) -# AsTime = 0 # Display values as angles (not times) - End SkyAxis - IsA Frame # Coordinate system description - System = "FK4-NO-E" # Celestial coordinate system type - Epoch = 1958 # Besselian epoch of observation -# Eqnox = 1950 # Besselian epoch of mean equinox - End SkyFrame -\end{terminalv} -\normalsize - -\subsection{\label{ss:channelcommenting}Controlling Commenting} - -Another way of controlling output from a Channel is \emph{via} the -boolean (integer) Comment attribute, which controls whether comments -are appended to describe the purpose of each value. Comment has the -value 1 by default but, if set to zero, will suppress these -comments. This is normally appropriate only if you wish to minimise -the amount of output, for example: - -c+ -\small -\begin{terminalv} -astSet( channel, "Full=-1, Comment=0" ); -nobj = astWrite( channel, skyframe ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( CHANNEL, 'Full=-1, Comment=0', STATUS ) - NOBJ = AST_WRITE( CHANNEL, SKYFRAME, STATUS ) -\end{terminalv} -\normalsize -f- - -might result in the following more compact output: - -\small -\begin{terminalv} - Begin SkyFrame - Naxes = 2 - Ax1 = - Begin SkyAxis - End SkyAxis - Ax2 = - Begin SkyAxis - End SkyAxis - IsA Frame - System = "FK4-NO-E" - Epoch = 1958 - End SkyFrame -\end{terminalv} -\normalsize - -\subsection{Editing Textual Output} - -c+ -The safest advice about editing the textual output from astWrite (or -astShow) is ``don't!''---unless you know what you are doing. -c+ -f+ -The safest advice about editing the textual output from AST\_WRITE (or -AST\_SHOW) is ``don't!''---unless you know what you are doing. -f- - -Having given that warning, however, it is sometimes possible to make -changes to the text, or even to write entire Object descriptions from -scratch, and to read the results back in to construct new -Objects. Normally, simple changes to numerical values are safest, but -be aware that this is a back door method of creating Objects, so -you are on your own! There are a number of potential pitfalls. In -particular: - -\begin{itemize} -c+ -\item astRead is intended for retrieving data written by astWrite and -not for reading data input by humans. As such, the data validation -provided is very limited and is certainly not foolproof. This makes it -quite easy to construct Objects that are internally inconsistent by -this means. In contrast, the normal programming interface incorporates -numerous checks designed to make it impossible to construct invalid -Objects. You should not necessarily think you have found a bug if your -changes to an Object's textual description fail to produce the results -you expected! -c- -f+ -\item AST\_READ is intended for retrieving data written by AST\_WRITE -and not for reading data input by humans. As such, the data validation -provided is very limited and is certainly not foolproof. This makes it -quite easy to construct Objects that are internally inconsistent by -this means. In contrast, the normal programming interface incorporates -numerous checks designed to make it impossible to construct invalid -Objects. You should not necessarily think you have found a bug if your -changes to an Object's textual description fail to produce the results -you expected! -f- - -\item In many instances the names associated with values in textual -output will correspond with Object attributes. Sometimes, however, -these names may differ from the attribute name. This is mainly because -of length restrictions imposed by other common external formats, such -as FITS headers. Some of the names used do not correspond with -attributes at all. - -\item It is safest to change single numerical or string values. -Beware of changing the size or shape of Objects (\emph{e.g.}\ the -number of axes in a Frame). Often, these values must match others -stored elsewhere within the Object and changing them in a haphazard -fashion will not produce useful results. - -\item Be wary about un-commenting default values. Sometimes this will -work, but often these values are derived from other Objects stored -more deeply in the structure and the proper place to insert a new -value is not where the default itself appears. -\end{itemize} - -\subsection{\label{ss:mixingchanneltext}Mixing Objects with other Text} - -c+ -By default, when you use astRead to read from a basic Channel -(\secref{ss:readingfromachannel}), it is assumed that you are reading a -stream of text containing only AST Objects, which follow each other -end-to-end. If any extraneous input data are encountered which do not -appear to form part of the textual description of an Object, then an -error will result. In particular, the first input line must identify -the start of an Object description, so you cannot start reading half -way through an Object. -c- -f+ -By default, when you use AST\_READ to read from a basic Channel -(\secref{ss:readingfromachannel}), it is assumed that you are reading a -stream of text containing only AST Objects, which follow each other -end-to-end. If any extraneous input data are encountered which do not -appear to form part of the textual description of an Object, then an -error will result. In particular, the first input line must identify -the start of an Object description, so you cannot start reading half -way through an Object. -f- - -Sometimes, however, you may want to store AST Object descriptions -intermixed with other textual data. You can do this by setting the -Channel's boolean (integer) Skip attribute to 1. This will cause every -read to skip over extraneous data until the start of a new AST Object -description, if any, is found. So long as your other data do not mimic -the appearance of an AST Object description, the two sets of data can -co-exist. - -c+ -For example, by setting Skip to 1, the following complete C program -will read all the AST Objects whose descriptions appear in the source -of this document, ignoring the other text. astShow is used to display -those found: - -\small -\begin{terminalv} -#include "ast.h" -main() { - AstChannel *channel; - AstObject *object; - - channel = astChannel( NULL, NULL, "Skip=1" ); - while ( ( object = astRead( channel ) ) != AST__NULL ) { - astShow( object ); - object = astAnnul( object ); - } - channel = astAnnul( channel ); -} -\end{terminalv} -\normalsize -c- -f+ -For example, by setting Skip to 1, the following complete Fortran -program will read all the AST Objects whose descriptions appear in the -source of this document, ignoring the other text. AST\_SHOW is used to -display those found: - -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER CHANNEL, OBJECT, STATUS - - STATUS = 0 - CHANNEL = AST_CHANNEL( AST_NULL, AST_NULL, 'Skip=1', STATUS ) - 1 OBJECT = AST_READ( CHANNEL, STATUS ) - IF ( OBJECT .NE. AST__NULL ) THEN - CALL AST_SHOW( OBJECT, STATUS ) - CALL AST_ANNUL( OBJECT, STATUS ) - GO TO 1 - END IF - CALL AST_ANNUL( CHANNEL, STATUS ) - END -\end{terminalv} -\normalsize -f- - -\subsection{\label{ss:channelsource}Reading Objects from Files} - -Thus far, we have only considered the default behaviour of a Channel -in reading and writing Objects through a program's standard input and -output streams. We will now consider how to access Objects stored in -files more directly. - -The simple approach is to use the SinkFile and SourceFile attributes of -the Channel. For instance, the following will read a pair of Objects from -a text file called ``fred.txt'': - -c+ -\small -\begin{terminalv} -astSet( channel, "SourceFile=fred.txt" ); -obj1 = astRead( channel ); -obj2 = astRead( channel ); -astClear( channel, "SourceFile" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( CHANNEL, 'SourceFile=fred.txt', STATUS ) - OBJ1 = AST_READ( CHANNEL, STATUS ) - OBJ2 = AST_READ( CHANNEL, STATUS ) - CALL AST_CLEAR( CHANNEL, 'SourceFile', STATUS ) -\end{terminalv} -\normalsize -f- - -Note, the act of clearing the attribute tells AST that no more Objects -are to be read from the file and so the file is then closed. If the -attribute is not cleared, the file will remain open and further Objects -can be read from it. The file will always be closed when the Channel is -deleted. - -This simple approach will normally be sufficient. However, because the -AST library is designed to be used from more than one language, it has -to be a little careful about reading and writing to files. This is due -to incompatibilities that may exist between the file I/O facilities -provided by different languages. If such incompatibilities prevent the -above simple system being used, we need to adopt a system that off-loads -all file I/O to external code. - -c+ -What this means in practice is that if the above simple approach cannot -be used, you must instead provide some simple C -functions that perform the actual transfer of data to and from files -and similar external data stores. The functions you provide are -supplied as the source and/or sink function arguments to astChannel -when you create a Channel (\secref{ss:creatingachannel}). An example is -the best way to illustrate this. -c- -f+ -What this means in practice is that if the above simple approach cannot -be used, you must instead provide some simple -Fortran routines that perform the actual transfer of data to and from -files and similar external data stores. The routines you provide are -supplied as the source and/or sink routine arguments to AST\_CHANNEL -when you create a Channel (\secref{ss:creatingachannel}). An example is -the best way to illustrate this. -f- - -c+ -Consider the following simple function called Source. It reads a -single line of text from a C input stream and returns a pointer to it, -or NULL if there is no more input: - -\small -\begin{terminalv} -#include -#define LEN 200 -static FILE *input_stream; - -const char *Source( void ) { - static char buffer[ LEN + 2 ]; - return fgets( buffer, LEN + 2, input_stream ); -} -\end{terminalv} -\normalsize -c- -f+ -Consider the following simple subroutine called SOURCE. It reads a -single line of text from a Fortran I/O unit and then calls -AST\_PUTLINE to pass it to the AST library, together with its -length. It sets this length to be negative if there is no more input: - -\small -\begin{terminalv} - SUBROUTINE SOURCE( STATUS ) - INTEGER STATUS - CHARACTER * ( 200 ) BUFFER - - READ( 1, '(A)', END = 99 ) BUFFER - CALL AST_PUTLINE( BUFFER, LEN( BUFFER ), STATUS ) - RETURN - - 99 CALL AST_PUTLINE( BUFFER, -1, STATUS ) - END -\end{terminalv} -\normalsize -f- - -c+ -Note that the input stream is a static variable which we will also -access from our main program. This might look something like this -(omitting error checking for brevity): - -\small -\begin{terminalv} -/* Open the input file. */ -input_stream = fopen( "infile.ast", "r" ); - -/* Create a Channel and read an Object from it. */ -channel = astChannel( Source, NULL, "" ); -object = astRead( channel ); - -... - -/* Annul the Channel and close the file when done. */ -channel = astAnnul( channel ); -(void) fclose( input_stream ); -\end{terminalv} -\normalsize -c- -f+ -Our main program might then look something like this (omitting error -checking for brevity): - -\small -\begin{terminalv} - EXTERNAL SOURCE - - ... - -* Open the input file. - OPEN( UNIT = 1, FILE = 'infile.ast', STATUS = 'OLD' ) - -* Create the Channel and read an Object from it. - CHANNEL = AST_CHANNEL( SOURCE, AST_NULL, ' ', STATUS ) - OBJECT = AST_READ( CHANNEL, STATUS ) - - ... - -* Annul the Channel and close the file when done. - CALL AST_ANNUL( CHANNEL, STATUS ) - CLOSE( 1 ) -\end{terminalv} -\normalsize -f- - -c+ -Here, we first open the required input file, saving the resulting FILE -pointer. We then pass a pointer to our Source function as the first -argument to astChannel when creating a new Channel. When we read -an Object from this Channel with astRead, the Source -function will be called to obtain the textual data from the file, the -end-of-file being detected when this function returns NULL. -c- -f+ -Here, we first open the required input file. We then pass the name of -our SOURCE routine as the first argument to AST\_CHANNEL when creating -a new Channel (ensuring that SOURCE also appears in an EXTERNAL -statement). When we read an Object from this Channel using -AST\_READ, the SOURCE routine will be called to obtain the textual -data from the file, the end-of-file being detected when it yields a -negative line length. -f- - -Note, if a value is set for the SourceFile attribute, -c+ -the astRead function will ignore any source function -c- -f+ -the AST\_READ function will ignore any source routine -f- -specified when the Channel was created. - -\subsection{\label{ss:channelsink}Writing Objects to Files} - -As for reading, writing Objects to files can be done in two different ways. -Again, the simple approach is to use the SinkFile attribute of the Channel. -For instance, the following will write a pair of Objects to a text file -called ``fred.txt'': - -c+ -\small -\begin{terminalv} -astSet( channel, "SinkFile=fred.txt" ); -nobj = astWrite( channel, object1 ); -nobj = astWrite( channel, object2 ); -astClear( channel, "SinkFile" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_SET( CHANNEL, 'SinkFile=fred.txt', STATUS ) - NOBJ = AST_WRITE( CHANNEL, OBJECT1, STATUS ) - NOBJ = AST_WRITE( CHANNEL, OBJECT2, STATUS ) - CALL AST_CLEAR( CHANNEL, 'SinkFile', STATUS ) -\end{terminalv} -\normalsize -f- - -Note, the act of clearing the attribute tells AST that no more output -will be written to the file and so the file is then closed. If the -attribute is not cleared, the file will remain open and further Objects -can be written to it. The file will always be closed when the Channel is -deleted. - -c+ -If the details of the language's I/O system on the computer you are using -means that the above approach cannot be used, then we can write a Sink function, -that writes a line of output text to a file, and use it in basically the same -way as the Source function in the previous section (\secref{ss:channelsource}): - -\small -\begin{terminalv} -static FILE *output_stream; - -void Sink( const char *line ) { - (void) fprintf( output_stream, "%s\n", line ); -} -\end{terminalv} -\normalsize - -Note that we must supply the final newline character ourselves. -c- -f+ -If the details of the language's I/O system on the computer you are using -means that the above approach cannot be used, then we can write a SINK routine, -that obtains a line of output text from the AST library by calling AST\_GETLINE -and then writes it to a file. We can use this in basically the same way as -the SOURCE routine in the previous section (\secref{ss:channelsource}): - -\small -\begin{terminalv} - SUBROUTINE SINK( STATUS ) - INTEGER L, STATUS - CHARACTER * ( 200 ) BUFFER - - CALL AST_GETLINE( BUFFER, L, STATUS ) - IF ( L .GT. 0 ) WRITE( 2, '(A)' ) BUFFER( : L ) - - END -\end{terminalv} -\normalsize -f- - -c+ -In this case, our main program would supply a pointer to this Sink -function as the second argument to astChannel, as follows: - -\small -\begin{terminalv} -/* Open the output file. */ -output_stream = fopen( "outfile.ast", "w" ); - -/* Create a Channel and write an Object to it. */ -channel = astChannel( Source, Sink, "" ); -nobj = astWrite( channel, object ); - - ... - -/* Annul the Channel and close the file when done. */ -channel = astAnnul( channel ); -(void) fclose( output_stream ); -\end{terminalv} -\normalsize -c- -f+ -In this case, our main program would supply the name of this SINK -routine as the second argument to AST\_CHANNEL (ensuring that it also -appears in an EXTERNAL statement), as follows: - -\small -\begin{terminalv} - EXTERNAL SINK - - ... - -* Open the output file. - OPEN( UNIT = 2, FILE = 'outfile.ast', STATUS = 'NEW' ) - -* Create a Channel and write an Object to it. - CHANNEL = AST_CHANNEL( SOURCE, SINK, ' ', STATUS ) - NOBJ = AST_WRITE( CHANNEL, OBJECT, STATUS ) - - ... - -* Annul the Channel and close the file when done. - CALL AST_ANNUL( CHANNEL, STATUS ) - CLOSE( 2 ) -\end{terminalv} -\normalsize -f- - -c+ -Note that we can specify a source and/or a sink function for the -Channel, and that these may use either the same file, or different -files according to whether we are reading or writing. AST has no -knowledge of the underlying file system, nor of file positioning. It -just reads and writes sequentially. If you wish, for example, to -reposition a file at the beginning in between reads and writes, then -this can be done directly (and completely independently of AST) using -standard C functions. -c- -f+ -Note that we can specify a source and/or a sink routine for the -Channel, and that these may use either the same file, or different -files according to whether we are reading or writing. AST has no -knowledge of the underlying file system, nor of file positioning. It -just reads and writes sequentially. If you wish, for example, to -reposition a file at the beginning in between reads and writes, then -this can be done directly (and completely independently of AST) using -standard Fortran statements. -f- - -c+ -If an error occurs in your source or sink function, you can -communicate this to the AST library by setting its error status to any -error value using astSetStatus (\secref{ss:errordetection}). This will -immediately terminate the read or write operation. -c- -f+ -If an error occurs in your source or sink routine, you can communicate -this to the AST library by setting the STATUS argument to any error -value. This will immediately terminate the read or write operation. -f- - -Note, if a value is set for the SinkFile attribute, -c+ -the astWrite function will ignore any sink function -c- -f+ -the AST\_WRITE function will ignore any sink routine -f- -specified when the Channel was created. - -\subsection{\label{ss:otherplaces}Reading and Writing Objects to other Places} - -c+ -It should be obvious from the above (\secref{ss:channelsource} and -\secref{ss:channelsink}) that a Channel's source and sink functions -provide a flexible means of intercepting textual data that describes -AST Objects as it flows in and out of your program. In fact, you might -like to regard a Channel simply as a filter for converting AST Objects -to and from a stream of text which is then handled by your source and -sink functions, where the real I/O occurs. -c- -f+ -It should be obvious from the above (\secref{ss:channelsource} and -\secref{ss:channelsink}) that a Channel's source and sink routines -provide a flexible means of intercepting textual data that describes -AST Objects as it flows in and out of your program. In fact, you might -like to regard a Channel simply as a filter for converting AST Objects -to and from a stream of text which is then handled by your source and -sink routines, where the real I/O occurs. -f- - -This gives you the ability to store AST Objects in virtually any data -system, so long as you can convert a stream of text into something -that can be stored (it need no longer be text) and retrieve it -again. There is generally no need to retain comments. Other -possibilities, such as inter-process and network communication, could -also be implemented \emph{via} source and sink functions in basically -the same way. - -\cleardoublepage -\section{\label{ss:nativefits}Storing AST Objects in FITS Headers (FitsChans)} - -A FITS header is a sequence of 80-character strings, formatted -according to particular rules defined by the Flexible Image Transport -System -(FITS). \htmladdnormallinkfoot{FITS}{http://fits.gsfc.nasa.gov/} -is a widely-used standard for data interchange in astronomy and has -also been adopted as a data processing format in some astronomical -data reduction systems. The individual 80-character strings in a FITS -header are usually called \emph{cards} or \emph{header cards} (for -entirely anachronistic reasons). - -A sequence of FITS cards appears as a header at the start of every -FITS data file, and sometimes also at other points within it, and is -used to provide ancillary information which qualifies or describes the -main array of data stored in the file. As such, FITS headers are prime -territory for storing information about the coordinate systems -associated with data held in FITS files. - -In this section, we will examine how to store information in FITS -headers directly in the form of AST Objects---a process which is -supported by a specialised class of Channel called a FitsChan. Our -discussion here will turn out to be a transitional step that -emphasises the similarities between a FitsChan and a Channel -(\secref{ss:channels}). At the same time, it will prepare us for the -next section (\secref{ss:foreignfits}), where we will examine how to -use a FitsChan to tackle some of the more difficult problems that FITS -headers can present. - -\subsection{\label{ss:nativeencoding}The Native FITS Encoding} - -As it turns out, we are not the first to have thought of storing WCS -information in FITS headers. In fact, the original FITS standard (1981 -vintage) defined a set of header keywords for this purpose which have -been widely used, although they have proved too limited for many -practical purposes. - -At the time of writing, a number of different ways of using FITS -headers for storing WCS information are in use, most (although not -all) based on the original standard. We will refer to these -alternative ways of storing the information as FITS \emph{encodings} -but will defer a discussion of their advantages and limitations until -the next section (\secref{ss:foreignfits}). - -Here, we will examine how to store AST Objects directly in FITS -headers. In effect, this defines a new encoding, which we will term -the \emph{native encoding}. This is a special kind of encoding, -because not only does it allow us to associate conventional -WCS calibration information with FITS data, but it also allows any other -information that can be expressed in terms of AST Objects to be stored -as well. In fact, the native encoding provides us with facilities -roughly analogous to those of the Channel -(\secref{ss:channels})---\emph{i.e.}\ a lossless way of -transferring AST Objects from program to program---but based on FITS -headers instead of free-format text. - -\subsection{The FitsChan Model} - -I/O between AST Objects and FITS headers is supported by a specialised -form of Channel called a FitsChan. A FitsChan contains a buffer which -may hold any number, including zero, of FITS header cards. This buffer -forms a workspace in which you can assemble FITS cards and manipulate -them before writing them out to a file. - -By default, when a FitsChan is first created, it contains no cards and -there are five ways of inserting cards into it: - -\begin{enumerate} -c+ -\item You may add cards yourself, one at a time, using astPutFits -(\secref{ss:addingfitscards}). -c- -f+ -\item You may add cards yourself, one at a time, using AST\_PUTFITS -(\secref{ss:addingfitscards}). -f- - -c+ -\item You may add cards yourself, supplying all cards concatenated into a -single string, using astPutCards -(\secref{ss:addingmulticards}). -c- -f+ -\item You may add cards yourself, supplying all cards concatenated into a -single string, using AST\_PUTCARDS. -(\secref{ss:addingmulticards}). -f- - -c+ -\item You may write an AST Object to the FitsChan (using astWrite), -which will have the effect of creating new cards within the FitsChan -which describe the Object (\secref{ss:writingnativefits}). -c- -f+ -\item You may write an AST Object to the FitsChan (using AST\_WRITE), -which will have the effect of creating new cards within the FitsChan -which describe the Object (\secref{ss:writingnativefits}). -f- - -\item You may assign a value to the SourceFile attribute of the FitsChan. -The value should be the path to a text file holding a set of FITS header -cards, one per line. When the SourceFile value is set (using -c+ -astSetC or astSet), -c- -f+ -AST\_SETC or AST\_SET). -f- -the file is opened and the headers copied from it into the FitsChan. -The file is then immediately closed. - -c+ -\item You may specify a source function which reads data from some -external store of FITS cards, just like the source associated with a -basic Channel (\secref{ss:channelsource}). If you supply a source -function, it will be called when the FitsChan is created in order to -fill it with an initial set of cards (\secref{ss:fitssourceandsink}). -c- -f+ -\item You may specify a source routine which reads data from some -external store of FITS cards, just like the source associated with a -basic Channel (\secref{ss:channelsource}). If you supply a source -routine, it will be called when the FitsChan is created in order to -fill it with an initial set of cards (\secref{ss:fitssourceandsink}). -f- -\end{enumerate} - -There are also four ways of removing cards from a FitsChan: - -\begin{enumerate} -c+ -\item You may delete cards yourself, one at a time, using astDelFits -(\secref{ss:findingandchangingfits}). -c- -f+ -\item You may delete cards yourself, one at a time, using AST\_DELFITS -(\secref{ss:findingandchangingfits}). -f- - -c+ -\item You may read an AST Object from the FitsChan (using astRead), -which will have the effect of removing those cards from the FitsChan -which describe the Object (\secref{ss:readingnativefits}). -c- -f+ -\item You may read an AST Object from the FitsChan (using AST\_READ), -which will have the effect of removing those cards from the FitsChan -which describe the Object (\secref{ss:readingnativefits}). -f- - -\item You may assign a value to the FitsChan's SinkFile attribute. When -the FitsChan is deleted, any remaining headers are written out to a text -file with path equal to the value of the SinkFile attribute. - -c+ -\item Alternatively, you may specify a sink function which writes data to some -external store of FITS cards, just like the sink associated with a -basic Channel (\secref{ss:channelsink}). If you supply a sink function, -it will be called when the FitsChan is deleted in order to write out -any FITS cards that remain in it (\secref{ss:fitssourceandsink}). Note, -the sink function is not called if the SinkFile attribute has been set. -c- -f+ -\item Alternatively, You may specify a sink routine which writes data to some -external store of FITS cards, just like the sink associated with a -basic Channel (\secref{ss:channelsink}). If you supply a sink routine, -it will be called when the FitsChan is deleted in order to write out -any FITS cards that remain in it (\secref{ss:fitssourceandsink}). Note, -the sink routine is not called if the SinkFile attribute has been set. -f- -\end{enumerate} - -Note, in particular, that reading an AST Object from a FitsChan is -\emph{destructive}. That is, it deletes the FITS cards that describe the -Object. The reason for this is explained in -\secref{ss:destructiveread}. - -c+ -In addition to the above, you may also read individual cards from a -FitsChan using the function astFindFits (which is not -destructive). This is the main means of writing out FITS cards if you -have not supplied a sink function. astFindFits also provides a means -of searching for particular FITS cards (by keyword, for example) and -there are other facilities for overwriting cards when required -(\secref{ss:findingandchangingfits}). -c- -f+ -In addition to the above, you may also read individual cards from a -FitsChan using the function AST\_FINDFITS (which is not -destructive). This is the main means of writing out FITS cards if you -have not supplied a sink routine. AST\_FINDFITS also provides a means -of searching for particular FITS cards (by keyword, for example) and -there are other facilities for overwriting cards when required -(\secref{ss:findingandchangingfits}). -f- - -\subsection{\label{ss:creatingafitschan}Creating a FitsChan} - -c+ -The FitsChan constructor function, astFitsChan, is straightforward to -use: -c- -f+ -The FitsChan constructor function, AST\_FITSCHAN, is straightforward -to use: -f- - -c+ -\small -\begin{terminalv} -#include "ast.h" -AstFitsChan *fitschan; - -... - -fitschan = astFitsChan( NULL, NULL, "Encoding=NATIVE" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER FITSCHAN, STATUS - - STATUS = 0 - - ... - - FITSCHAN = AST_FITSCHAN( AST_NULL, AST_NULL, 'Encoding=NATIVE', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, we have omitted any source or sink functions by supplying NULL -pointers for the first two arguments. -c- -f+ -Here, we have omitted any source or sink functions by supplying the -AST\_NULL routine for the first two arguments (remember to include the -AST\_PAR include file which contains the required EXTERNAL statement -for this routine). -f- -We have also initialised the FitsChan's Encoding attribute to -NATIVE. This indicates that we will be using the native encoding -(\secref{ss:nativeencoding}) to store and retrieve Objects. If this -was left unspecified, the default would depend on the FitsChan's -contents. An attempt is made to use whatever encoding appears to have -been used previously. For an empty FitsChan, the default is NATIVE, -but it does no harm to be sure. - -\subsection{\label{ss:addressingfitscards}Addressing Cards in a FitsChan} - -Because a FitsChan contains an ordered sequence of header cards, a -mechanism is needed for addressing them. This allows you to specify -where new cards are to be added, for example, or which card is to be -deleted. - -This role is filled by the FitsChan's integer Card attribute, which -gives the index of the \emph{current card} in the FitsChan. You can -nominate any card you like to be current, simply by setting a new -value for the Card attribute, for example: - -c+ -\small -\begin{terminalv} -int icard; - -... - -astSetI( fitschan, "Card", icard ) -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER ICARD - - ... - - CALL AST_SETI( FITSCHAN, 'Card', ICARD, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -where ``icard'' contains the index of the card on which you wish to -operate next. Some functions will update the Card attribute as a -means of advancing through the sequence of cards, when reading them -for example, or to indicate which card matches a search criterion. -c- -f+ -where ICARD contains the index of the card on which you wish to -operate next. Some functions will update the Card attribute as a -means of advancing through the sequence of cards, when reading them -for example, or to indicate which card matches a search criterion. -f- - -The default value for Card is one, which is the index of the first -card. This means that you can ``rewind'' a FitsChan to access its -first card by clearing the Card attribute: - -c+ -\small -\begin{terminalv} -astClear( fitschan, "Card" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_CLEAR( FITSCHAN, 'Card', STATUS ) -\end{terminalv} -\normalsize -f- - -The total number of cards in a FitsChan is given by the integer Ncard -attribute. This is a read-only attribute whose value is automatically -updated as you add or remove cards. It means you can address all the -cards in sequence using a loop such as the following: - -c+ -\small -\begin{terminalv} -int ncard; - -... - -ncard = astGetI( fitschan, "Ncard" ); -for ( icard = 1; icard <= ncard; icard++ ) { - astSetI( fitschan, "Card", icard ); - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DO 1 ICARD = 1, AST_GETI( FITSCHAN, 'Ncard', STATUS ) - CALL AST_SETI( FITSCHAN, 'Card', ICARD, STATUS ) - - 1 CONTINUE -\end{terminalv} -\normalsize -f- - -c+ -However, it is usually possible to write slightly tidier loops based -on the astFindFits function described later -(\secref{ss:extractingfitscards} and -\secref{ss:findingandchangingfits}). -c- -f+ -However, it is usually possible to write slightly tidier loops based -on the AST\_FINDFITS function described later -(\secref{ss:extractingfitscards} and -\secref{ss:findingandchangingfits}). -f- - -If you set the Card attribute to a value larger than Ncard, the -FitsChan is regarded as being positioned at its \emph{end-of-file}. In -this case there is no current card and an attempt to obtain a value -for the Card attribute will always return the value Ncard~$+$~1. When -a FitsChan is empty, it is always at the end-of-file. - -\subsection{\label{ss:writingnativefits}Writing Native Objects to a FitsChan} - -c+ -Having created an empty FitsChan (\secref{ss:creatingafitschan}), you -can write any AST Object to it in the native encoding using the -astWrite function. Let us assume we are writing a -SkyFrame,\footnote{More probably, you would want to write a FrameSet, -but for purposes of illustration a SkyFrame contains a more manageable -amount of data.} as follows: -c- -f+ -Having created an empty FitsChan (\secref{ss:creatingafitschan}), you -can write any AST Object to it in the native encoding using the -AST\_WRITE function. Let us assume we are writing a -SkyFrame,\footnote{More probably, you would want to write a FrameSet, -but for purposes of illustration a SkyFrame contains a more manageable -amount of data.} as follows: -f- - -c+ -\small -\begin{terminalv} -AstSkyFrame *skyframe; -int nobj; - -... - -nobj = astWrite( fitschan, skyframe ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER NOBJ, SKYFRAME - - ... - - NOBJ = AST_WRITE( FITSCHAN, SKYFRAME, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Since we have selected the native encoding -(\secref{ss:nativeencoding}), there are no restrictions on the class -of Object we may write, so astWrite should always return a value of -one, unless an error occurs. Unlike a basic Channel -(\secref{ss:writingtoachannel}), this write operation will not produce -any output from our program. The FITS headers produced are simply -stored inside the FitsChan. -c- -f+ -Since we have selected the native encoding -(\secref{ss:nativeencoding}), there are no restrictions on the class -of Object we may write, so AST\_WRITE should always return a value of -one, unless an error occurs. Unlike a basic Channel -(\secref{ss:writingtoachannel}), this write operation will not produce -any output from our program. The FITS headers produced are simply -stored inside the FitsChan. -f- - -After this write operation, the Ncard attribute will be updated to -reflect the number of new cards added to the FitsChan and the Card -attribute will point at the card immediately after the last one -written. Since our FitsChan was initially empty, the Card attribute -will, in this example, point at the end-of-file -(\secref{ss:addressingfitscards}). - -The FITS standard imposes a limit of 68 characters on the length of -strings which may be stored in a single header card. Sometimes, a -description of an AST Object involves the use of strings which exceed -this limit (\emph{e.g.}\ a Frame title can be of arbitrary length). If -this occurs, the long string will be split over two or more header cards. -Each ``continuation'' card will have the keyword \texttt{CONTINUE} in -columns 1 to 8, and will contain a space in column 9 (instead of the -usual equals sign). An ampersand (``\texttt{\&}'') is appended to the end of -each of the strings (except the last one) to indicate that the string is -continued on the next card. - -c+ -Note, this splitting of long strings over several cards only occurs when -writing AST Objects to a FitsChan using the astWrite function and the -\emph{native} encoding. If a long string is stored in a FitsChan using -(for instance) the astPutFits or astPutCards function, it will simply be truncated. -c- - -f+ -Note, this splitting of long strings over several cards only occurs when -writing AST Objects to a FitsChan using the AST\_WRITE routine and the -\emph{native} encoding. If a long string is stored in a FitsChan using -(for instance) the AST\_PUTFITS or AST\_PUTCARDS routine, it will simply be truncated. -f- - -\subsection{\label{ss:extractingfitscards}Extracting Individual Cards from a FitsChan} - -c+ -To examine the contents of the FitsChan after writing the SkyFrame -above (\secref{ss:writingnativefits}), we must write a simple loop to -extract each card in turn and print it out. We must also remember to -rewind the FitsChan first, \emph{e.g.}\ using astClear. The following -loop would do: -c- -f+ -To examine the contents of the FitsChan after writing the SkyFrame -above (\secref{ss:writingnativefits}), we must write a simple loop to -extract each card in turn and print it out. We must also remember to -rewind the FitsChan first, \emph{e.g.}\ using AST\_CLEAR. The -following loop would do: -f- - -c+ -\small -\begin{terminalv} -#include -char card[ 81 ]; - -... - -astClear( fitschan, "Card" ); -while ( astFindFits( fitschan, "%f", card, 1 ) ) (void) printf( "%s\n", card ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 80 ) CARD - - ... - - CALL AST_CLEAR( FITSCHAN, 'Card', STATUS ) - - 2 CONTINUE - IF ( AST_FINDFITS( FITSCHAN, '%f', CARD, .TRUE., STATUS ) ) THEN - WRITE ( *, '(A)' ) CARD - GO TO 2 - END IF -\end{terminalv} -\normalsize -f- - -c+ -Here, we have used the astFindFits function to find a FITS card by -keyword. It is given a keyword template of ``\%f'', which matches any -FITS keyword, so it always finds the current card, which it -returns. Its fourth argument is set to 1, to indicate that the Card -attribute should be incremented afterwards so that the following card -will be found the next time around the loop. astFindFits returns zero -when it reaches the end-of-file and this terminates the loop. -c- -f+ -Here, we have used the AST\_FINDFITS function to find a FITS card by -keyword. It is given a keyword template of ``\%f'', which matches any -FITS keyword, so it always finds the current card, which it -returns. Its fourth argument is set to .TRUE., to indicate that the -Card attribute should be incremented afterwards so that the following -card will be found the next time around the loop. AST\_FINDFITS -returns .FALSE.\ when it reaches the end-of-file and this terminates -the loop. -f- - -c+ -If we were storing the FITS headers in an output FITS file instead of -printing them out, we might use a loop like this but replace -``printf'' with a suitable data storage operation. This would only be -necessary if we had not provided a sink function for the FitsChan -(\secref{ss:fitssourceandsink}). -c- -f+ -If we were storing the FITS headers in an output FITS file instead of -printing them out, we might use a loop like this but replace the WRITE -statement with a call to a suitable data access routine to store the -header card. This would only be necessary if we had not provided a -sink routine for the FitsChan (\secref{ss:fitssourceandsink}). -f- - -\subsection{The Native FitsChan Output Format} - -If we print out the FITS header cards describing the SkyFrame we wrote -earlier (\secref{ss:writingnativefits}), we should obtain something -like the following: - -\small -\begin{terminalv} -COMMENT AST ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AST -COMMENT AST Beginning of AST data for SkyFrame object AST -COMMENT AST ................................................................ AST -BEGAST_A= 'SkyFrame' / Description of celestial coordinate system -NAXES_A = 2 / Number of coordinate axes -AX1_A = ' ' / Axis number 1 -BEGAST_B= 'SkyAxis ' / Celestial coordinate axis -ENDAST_A= 'SkyAxis ' / End of object definition -AX2_A = ' ' / Axis number 2 -BEGAST_C= 'SkyAxis ' / Celestial coordinate axis -ENDAST_B= 'SkyAxis ' / End of object definition -ISA_A = 'Frame ' / Coordinate system description -SYSTEM_A= 'FK4-NO-E' / Celestial coordinate system type -EPOCH_A = 1958.0 / Besselian epoch of observation -ENDAST_C= 'SkyFrame' / End of object definition -COMMENT AST ................................................................ AST -COMMENT AST End of AST data for SkyFrame object AST -COMMENT AST ---------------------------------------------------------------- AST -\end{terminalv} -\normalsize - -As you can see, this resembles the information that would be written -to a basic Channel to describe the same SkyFrame -(\secref{ss:textualoutputformat}), except that it has been formatted -into 80-character header cards according to FITS conventions. - -There are also a number of other differences worth noting: - -\begin{enumerate} -\item There is no unnecessary information about default values -provided for the benefit of the human reader. This is because the Full -attribute for a FitsChan defaults to $-$1, thus suppressing this -information (\emph{c.f.}~\secref{ss:controllingchanneloutput}). You -can restore the information if you wish by setting Full to 0 or $+$1, -in which case additional COMMENT cards will be generated to hold it. - -\item The information is not indented, because FITS does not allow -this. However, if you change the Full attribute to 0 or $+$1, comments -will be included that are intended to help break up the sequence of -headers and highlight its structure. This will probably only be of use -if you are attempting to track down a problem by examining the FITS -cards produced in detail. - -\item The FITS keywords which appear to the left of the ``$=$'' signs -have additional characters (``\_A'', ``\_B'', \emph{etc.}) appended to -them. This is done in order to make each keyword unique. -\end{enumerate} - -c+ -This last point is worth further comment and is necessary because the -FITS standard only allows for certain keywords (such as COMMENT and -HISTORY) to appear more than once. astWrite therefore appends an -arbitrary sequence of two characters to each new keyword it generates -in order to ensure that it does not duplicate any already present in -the FitsChan. -c- -f+ -This last point is worth further comment and is necessary because the -FITS standard only allows for certain keywords (such as COMMENT and -HISTORY) to appear more than once. AST\_WRITE therefore appends an -arbitrary sequence of two characters to each new keyword it generates -in order to ensure that it does not duplicate any already present in -the FitsChan. -f- - -c+ -The main risk from not following this convention is that some software -might ignore (say) all but the last occurrence of a keyword before -passing the FITS headers on. Such an event is unlikely, but would -obviously destroy the information present, so astWrite enforces the -uniqueness of the keywords it uses. The extra characters added are -ignored when the information is read back. -c- -f+ -The main risk from not following this convention is that some software -might ignore (say) all but the last occurrence of a keyword before -passing the FITS headers on. Such an event is unlikely, but would -obviously destroy the information present, so AST\_WRITE enforces the -uniqueness of the keywords it uses. The extra characters added are -ignored when the information is read back. -f- - -As with a basic Channel, you can also suppress the comments produced -in a FitsChan by setting the boolean (integer) Comment attribute to -zero (\secref{ss:channelcommenting}). However, FITS headers are -traditionally generously commented, so this is not recommended. - -\subsection{\label{ss:addingfitscards}Adding Individual Cards to a FitsChan} - -c+ -To insert individual cards into a FitsChan, prior to reading them back -as Objects for example, you should use the astPutFits function. You -can insert a card in front of the current one as follows: -c- -f+ -To insert individual cards into a FitsChan, prior to reading them back -as Objects for example, you should use the AST\_PUTFITS routine. You -can insert a card in front of the current one as follows: -f- - -c+ -\small -\begin{terminalv} -astPutFits( fitschan, card, 0 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_PUTFITS( FITSCHAN, CARD, .FALSE., STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -where the third argument of zero indicates that the current card -should not be overwritten. Note that facilities are not provided by -AST for formatting the card contents. -c- -f+ -where the third argument of .FALSE.\ indicates that the current card -should not be overwritten. Note that facilities are not provided by -AST for formatting the card contents. -f- - -c+ -After inserting a card, the FitsChan's Card attribute points at the -original Card, or at the end-of-file if the FitsChan was originally -empty. Entering a sequence of cards is therefore straightforward. If -``cards'' is an array of pointers to strings containing FITS header -cards and ``ncards'' is the number of cards, then a loop such as the -following will insert the cards in sequence into a FitsChan: -c- -f+ -After inserting a card, the FitsChan's Card attribute points at the -original Card, or at the end-of-file if the FitsChan was originally -empty. Entering a sequence of cards is therefore straightforward. If -CARDS is an array of character strings containing FITS header cards -and NCARDS is the number of cards, then a loop such as the following -will insert the cards in sequence into a FitsChan: -f- - -c+ -\small -\begin{terminalv} -#define MAXCARD 100 -char *cards[ MAXCARD ]; -int ncard; - -... - -for ( icard = 0; icard < ncard; icard++ ) astPutFits( fitschan, cards[ icard ], 0 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER NCARD - CHARACTER * ( 80 ) CARDS( NCARD ) - - ... - - DO 3 ICARD = 1, NCARD - CALL AST_PUTFITS( FITSCHAN, CARDS( ICARD ), .FALSE., STATUS ) - 3 CONTINUE -\end{terminalv} -\normalsize -f- - -c+ -The string containing a card need not be null terminated if it is at -least 80 characters long (we have not allocated space for the strings -themselves in this brief example). -c- - -c+ -Note that astPutFits enforces the validity of a FitsChan by rejecting -any cards which do not adhere to the FITS standard. If any such cards -are detected, an error will result. -c- -f+ -Note that AST\_PUTFITS enforces the validity of a FitsChan by -rejecting any cards which do not adhere to the FITS standard. If any -such cards are detected, an error will result. -f- - -\subsection{\label{ss:addingmulticards}Adding Concatenated Cards to a FitsChan} - -If you have all your cards concatenated together into a single long string, -each occupying 80 characters (with no delimiters), you can insert them -into a FitsChan in a single call using -c+ -astPutCards. -c- -f+ -AST\_PUTCARDS. -f- -This call first empties the supplied FitsChan of any existing cards, then -inserts the new cards, and finally rewinds the FitsChan so that a -subsequent call to -c+ -astRead -c- -f+ -AST\_READ -f- -will start reading from the first supplied card. The -c+ -astPutCards function uses astPutFits -c- -f+ -AST\_PUTCARDS routine uses AST\_PUTFITS -f- -internally to interpret and store each individual card, and so the -caveats in \secref{ss:addingfitscards} should be read. - -c+ -For instance, if you are using the CFITSIO library for access to FITS -files, you can use the CFITSIO fits\_hdr2str function to obtain a string suitable -for passing to astPutCards: - -\small -\begin{terminalv} - - -if( !fits_hdr2str( fptr, 0, NULL, 0, &header, &nkeys, &status ) ) - fitschan = astFitsChan( NULL, NULL, "" ); - astPutCards( fitschan, header ); - header = free( header ); - wcsinfo = astRead( fitschan ); - - ... -} -\end{terminalv} -\normalsize - - -c- - -\subsection{\label{ss:readingnativefits}Reading Native Objects From a FitsChan} - -c+ -Once you have stored a FITS header description of an Object in a -FitsChan using the native encoding (\secref{ss:writingnativefits}), -you can read it back using astRead in much the same way as with a -basic Channel (\secref{ss:readingfromachannel}). Similar comments -about validating the Object you read also apply -(\secref{ss:validatinginput}). If you have just written to the -FitsChan, you must remember to rewind it first: -c- -f+ -Once you have stored a FITS header description of an Object in a -FitsChan using the native encoding (\secref{ss:writingnativefits}), -you can read it back using AST\_READ in much the same way as with a -basic Channel (\secref{ss:readingfromachannel}). Similar comments -about validating the Object you read also apply -(\secref{ss:validatinginput}). If you have just written to the -FitsChan, you must remember to rewind it first: -f- - -c+ -\small -\begin{terminalv} -AstObject *object; - -... - -astClear( fitschan, "Card" ); -object = astRead( fitschan ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER OBJECT - - ... - - CALL AST_CLEAR( FITSCHAN, 'Card', STATUS ) - OBJECT = AST_READ( FITSCHAN, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -An important feature of a FitsChan is that read operations are -destructive. This means that if an Object description is found, it -will be consumed by astRead which will remove all the cards involved, -including associated COMMENT cards, from the FitsChan. Thus, if you -write an Object to a FitsChan, rewind, and read the same Object back, -you should end up with the original FitsChan contents. If you need to -circumvent this behaviour for any reason, it is a simple matter to -make a copy of a FitsChan using astCopy -(\secref{ss:copyingobjects}). If you then read from the copy, the -original FitsChan will remain untouched. -c- -f+ -An important feature of a FitsChan is that read operations are -destructive. This means that if an Object description is found, it -will be consumed by AST\_READ which will remove all the cards -involved, including associated COMMENT cards, from the FitsChan. Thus, -if you write an Object to a FitsChan, rewind, and read the same Object -back, you should end up with the original FitsChan contents. If you -need to circumvent this behaviour for any reason, it is a simple -matter to make a copy of a FitsChan using AST\_COPY -(\secref{ss:copyingobjects}). If you then read from the copy, the -original FitsChan will remain untouched. -f- - -After a read completes, the FitsChan's Card attribute identifies the -card immediately following the last card read, or the end-of-file of -there are no more cards. - -c+ -Since the \emph{native} encoding is being used, any long strings involved -in the object description will have been split into two or more adjacent -contuation cards when the Object was stored in the header using function -astWrite. The astRead function reverses this process by concatenating any -such adjacent continuation cards to re-create the original long string. -c- - -f+ -Since the \emph{native} encoding is being used, any long strings involved -in the object description will have been split into two or more adjacent -contuation cards when the Object was stored in the header using routine -AST\_WRITE. The AST\_READ routine reverses this process by concatenating -any such adjacent continuation cards to re-create the original long -string. -f- - -\subsection{Saving and Restoring Multiple Objects in a FitsChan} - -When using the native FITS encoding, multiple Objects may be stored -and all I/O operations are sequential. This means that you can simply -write a sequence of Objects to a FitsChan. After each write operation, -the Card attribute will be updated so that the next write appends the -next Object description to the previous one. - -If you then rewind the FitsChan, you can read the Objects back in the -original order. Reading them back will, of course, remove their -descriptions from the FitsChan (\secref{ss:readingnativefits}) but the -behaviour of the Card attribute is such that successive reads will -simply return each Object in sequence. - -The only thing that may require care, given that a FitsChan can always -be addressed randomly by setting its Card attribute, is to avoid -writing one Object on top of another. For obvious reasons, the Object -descriptions in a FitsChan must remain separate if they are to make -sense when read back. - -\subsection{Mixing Native Objects with Other FITS Cards} - -Of course, any real FITS header will contain other information besides -AST Objects, if only the mandatory FITS cards that must accompany all -FITS data. When FITS headers are read in from a real dataset, -therefore, any native AST Object descriptions will be inter-mixed with -many other cards. - -Because this is the normal state of affairs, the boolean (integer) -Skip attribute for a FitsChan defaults to one. This means that when -you read an Object From a FitsChan, any irrelevant cards will simply -be skipped over until the start of the next Object description, if -any, is found. If you start reading part way through an Object -description, no error will result. The remainder of the description -will simply be skipped. - -Setting Skip to zero will change this behaviour to resemble that of a -basic Channel (\secref{ss:mixingchanneltext}), where extraneous data -are not permitted by default, but this will probably rarely be useful. - -\subsection{\label{ss:findingandchangingfits}Finding and Changing Cards in a FitsChan} - -c+ -You can search for, and retrieve, particular cards in a FitsChan by -keyword, using the function astFindFits. This performs a search, -starting at the current card, until it finds a card whose keyword -matches the template you supply, or the end-of-file is reached. -c- -f+ -You can search for, and retrieve, particular cards in a FitsChan by -keyword, using the function AST\_FINDFITS. This performs a search, -starting at the current card, until it finds a card whose keyword -matches the template you supply, or the end-of-file is reached. -f- - -c+ -If a suitable card is found, astFindFits optionally returns the card's -contents and then sets the FitsChan's Card attribute either to -identify the card found, or the one following it. The way you want the -Card attribute to be set is indicated by the final boolean (int) -argument to astFindFits. A value of one is returned to indicate -success. If a suitable card cannot be found, astFindFits returns a -value of zero to indicate failure and sets the FitsChan's Card -attribute to the end-of-file. -c- -f+ -If a suitable card is found, AST\_FINDFITS returns the card's contents -and then sets the FitsChan's Card attribute either to identify the -card found, or the one following it. The way you want the Card -attribute to be set is indicated by the fourth (logical) argument to -AST\_FINDFITS. A value of .TRUE.\ is returned to indicate success. If -a suitable card cannot be found, AST\_FINDFITS returns a value of -.FALSE.\ to indicate failure and sets the FitsChan's Card attribute to -the end-of-file. -f- - -c+ -Requesting that the Card attribute be set to indicate the card that -astFindFits finds is useful if you want to replace that card with a -new one, as in this example: -c- -f+ -Requesting that the Card attribute be set to indicate the card that -AST\_FINDFITS finds is useful if you want to replace that card with a -new one, as in this example: -f- - -c+ -\small -\begin{terminalv} -char newcard[ 81 ]; - -... - -(void) astFindFits( fitschan, "AIRMASS", NULL, 0 ); -astPutFits( fitschan, newcard, 1 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 80 ) NEWCARD - LOGICAL JUNK - - ... - - JUNK = AST_FINDFITS( FITSCHAN, 'AIRMASS', CARD, .FALSE., STATUS ) - CALL AST_PUTFITS( FITSCHAN, NEWCARD, .TRUE., STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, astFindFits is used to search for a card with the keyword -AIRMASS, with a NULL pointer being given to indicate that we do not -want the card's contents returned. If the card is found, astPutFits -then overwrites it with a new card. Otherwise, the Card attribute -ends up pointing at the end-of-file and the new card is simply -appended to the end of the FitsChan. -c- -f+ -Here, AST\_FINDFITS is used to search for a card with the keyword -AIRMASS. If the card is found, AST\_PUTFITS then overwrites it with a -new card. Otherwise, the Card attribute ends up pointing at the -end-of-file and the new card is simply appended to the end of the -FitsChan. -f- - -c+ -A similar approach can be used to delete selected cards from a -FitsChan using astDelFits, which deletes the current card: -c- -f+ -A similar approach can be used to delete selected cards from a -FitsChan using AST\_DELFITS, which deletes the current card: -f- - -c+ -\small -\begin{terminalv} -if ( astFindFits( fitschan, "BSCALE", NULL, 0 ) ) astDelFits( fitschan ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - IF ( AST_FINDFITS( FITSCHAN, 'BSCALE', CARD, .FALSE., STATUS ) ) THEN - CALL AST_DELFITS( FITSCHAN, STATUS ) - END IF -\end{terminalv} -\normalsize -f- - -This deletes the first card, if any, with the BSCALE keyword. - -c+ -Requesting that astFindFits increments the Card attribute to identify -the card following the one found is more useful when writing loops. -For example, the following loop extracts each card whose keyword -matches the template ``CD\%6d'' (that is, ``CD'' followed by six -decimal digits): -c- -f+ -Requesting that AST\_FINDFITS increments the Card attribute to -identify the card following the one found is more useful when writing -loops. For example, the following loop extracts each card whose -keyword matches the template ``CD\%6d'' (that is, ``CD'' followed by -six decimal digits): -f- - -c+ -\small -\begin{terminalv} -while ( astFindFits( fitschan, "CD%6d", card, 1 ) { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - 4 CONTINUE - IF ( AST_FINDFITS( FITSCHAN, 'CD%6d', CARD, .TRUE., STATUS ) ) THEN - - GO TO 4 - END IF -\end{terminalv} -\normalsize -f- - -c+ -For further details of keyword templates, see the description of -astFindFits in \appref{ss:functiondescriptions}. -c- -f+ -For further details of keyword templates, see the description of -AST\_FINDFITS in \appref{ss:functiondescriptions}. -f- - -c+ -\subsection{\label{ss:fitssourceandsink}Source and Sink Functions for FitsChans} -c- -f+ -\subsection{\label{ss:fitssourceandsink}Source and Sink Routines for FitsChans} -f- - -c+ -The use of source and sink functions with a FitsChan is optional. This -is because you can always arrange to explicitly fill a FitsChan with -FITS cards (\secref{ss:addingfitscards} and \secref{ss:addingmulticards}) -and you can also extract any -cards that remain and write them out yourself -(\secref{ss:extractingfitscards}) before you delete the FitsChan. -c- -f+ -The use of source and sink routines with a FitsChan is optional. This -is because you can always arrange to explicitly fill a FitsChan with -FITS cards (\secref{ss:addingfitscards} and \secref{ss:addingmulticards}) -and you can also extract any -cards that remain and write them out yourself -(\secref{ss:extractingfitscards}) before you delete the FitsChan. -f- - -c+ -If you choose to use these functions, however, they behave in a very -similar manner to those used by a Channel (\secref{ss:channelsource} -and \secref{ss:channelsink}). You supply pointers to these functions, -as arguments to the constructor function astFitsChan when you create -the FitsChan (\secref{ss:creatingafitschan}). The source function is -invoked implicitly at this point to fill the FitsChan with FITS cards -and the FitsChan is then rewound, so that the first card becomes -current. The sink function is automatically invoked later, when the -FitsChan is deleted, in order to write out any cards that remain in -it. -c- -f+ -If you choose to use these routines, however, they behave in a very -similar manner to those used by a Channel (\secref{ss:channelsource} -and \secref{ss:channelsink}). You supply these routines, as arguments -to the constructor function AST\_FITSCHAN when you create the FitsChan -(\secref{ss:creatingafitschan}). The source routine is invoked -implicitly at this point to fill the FitsChan with FITS cards and the -FitsChan is then rewound, so that the first card becomes current. The -sink routine is automatically invoked later, when the FitsChan is -deleted, in order to write out any cards that remain in it. -f- - -c+ -The only real difference between the source and sink functions for a -FitsChan and a basic Channel is that FITS cards are limited in length -to 80~characters, so the choice of buffer size is simplified. The -``Source'' and ``Sink'' functions in \secref{ss:channelsource} and -\secref{ss:channelsink} could therefore be used to access FITS headers -stored in text files simply by changing LEN to be 80. If you were not -accessing a text file, however, appropriate changes to the I/O -statements would be needed since the separating newline characters -would be absent. The details obviously depend on the format of the -file you are handling, which need not necessarily be a true FITS file. -c- - -f+ -The only real difference between the source and sink routines for a -FitsChan and a basic Channel is that FITS cards are limited in length -to 80~characters, so the choice of buffer size is simplified. This -affects the way the card contents are passed, so the routines -themselves are slightly different. The following is therefore the -FitsChan equivalent of the Channel SOURCE routine given in -\secref{ss:channelsource}: - -\small -\begin{terminalv} - INTEGER FUNCTION FITSSOURCE( CARD, STATUS ) - CHARACTER * ( 80 ) CARD - INTEGER STATUS - - READ( 1, '(A)', END = 99 ) CARD - FITSSOURCE = 1 - RETURN - - 99 FITSSOURCE = 0 - END -\end{terminalv} -\normalsize - -Here, the FITS card contents are returned \emph{via} the CARD argument -(the AST\_PUTLINE routine should not be used) and the function returns -1 to indicate that a card has been read. A value of zero is returned -if there are no more cards to read. - -The sink routine for a FitsChan is also a little different -(\emph{c.f.}\ the SINK routine in~\secref{ss:channelsink}), as -follows: - -\small -\begin{terminalv} - SUBROUTINE FITSSINK( CARD, STATUS ) - CHARACTER * ( 80 ) CARD - INTEGER STATUS - - WRITE( 2, '(A)' ) CARD - - END -\end{terminalv} -\normalsize - -The contents of the FITS card being written are passed \emph{via}\ the -CARD argument (the AST\_GETLINE routine should not be used). - -Of course, both of these examples assume that you are accessing text -files. If this is not the case, then appropriate changes to the I/O -statements would be needed. The details obviously depend on the -format of the file you are handling, which need not necessarily be a -true FITS file. -f- - -\cleardoublepage -\section{\label{ss:foreignfits}Using Foreign FITS Encodings} - -We saw in the previous section (\secref{ss:nativefits}) how to store -and retrieve any kind of AST Object in a FITS header by using a -FitsChan. To achieve this, we set the FitsChan's Encoding attribute to -NATIVE. However, the Objects we wrote could then only be read back by -other programs that use AST. - -In practice, we will also encounter FITS headers containing WCS -information written by other software systems. We will probably also -need to write FITS headers in a format that can be understood by these -systems. Indeed, this interchange of data is one of the main reasons -for the existence of FITS, so in this section we will examine how to -accommodate these requirements. - -\subsection{\label{ss:foreignencodings}The Foreign FITS Encodings} - -As mentioned previously (\secref{ss:nativeencoding}), there are a -number of conventions currently in use for storing WCS information in -FITS headers, which we call \emph{encodings}. Here, we are concerned -with those encodings defined by software systems other than AST, which -we term \emph{foreign encodings}. - -Currently, AST supports six foreign encodings, which may be selected -by setting the Encoding attribute of a FitsChan to one of the -following (character string) values: - -\begin{quote} -\begin{description} -\item[DSS]\mbox{}\\ -This encoding stores WCS information using the convention developed at -the Space Telescope Science Institute for the Digitised Sky Survey -(DSS) astrometric plate calibrations. DSS images which use this -convention are widely available and it is understood by a number of -important and well-established astronomy applications. - -However, the calibration model used (based on a polynomial fit) is not -easily applicable to other types of data and creating the polynomial -coefficients needed to calibrate your own images can prove -difficult. For this reason, the DSS encoding is probably best viewed -as a ``read-only'' format. It is possible, however, to read in WCS -information using this encoding and then to write it back out again, -so long as only minor changes have been made. - -\item[FITS-WCS]\mbox{}\\ -This encoding is very important because it is based on a new FITS standard -which should, for the first time, address the problem of celestial coordinate -systems in a proper manner, by considerably extending the original FITS -standard. - -The conventions used are described in a series of papers by -E.W.\,Greisen, M.\,Calabretta, \emph{et. al.}, often referred to as the -``FITS-WCS papers''. They are described at -\url{http://fits.gsfc.nasa.gov/fits_wcs.html}. Now that the first two papers -in this series have been agreed, this encoding should be understood by any -FITS-WCS compliant software and it is likely to be adopted widely for FITS -data in future. For details of the coverage of these conventions provided -by the FitsChan class, see \appref{ss:fitswcscoverage}. - -\item[FITS-IRAF]\mbox{}\\ -This encoding is based on the conventions described in the document -``World Coordinate Systems Representations Within the FITS Format'' by R.J. -Hanisch and D.G. Wells, 1988.\footnote{Available by ftp from -fits.cv.nrao.edu /fits/documents/wcs/wcs88.ps.Z} It is employed -by the IRAF data analysis facility, so its use will facilitate data -exchange with IRAF. This encoding is in effect a sub-set of the current -FITS-WCS encoding. - -\item[FITS-PC]\mbox{}\\ -This encoding is based on a previous version of the proposed new FITS WCS -standard which used \texttt{PCjjjjiii} and \texttt{CDELTj} keywords to describe -axis rotation and scaling. Versions of AST prior to V1.5 used this scheme -for the FITS-WCS encoding. As of V1.5, FITS-WCS uses \texttt{CDi\_j} -keywords instead.\footnote{There are many other differences between the -previous and the current FITS-WCS encodings. The keywords to describe -axis rotation and scaling is used purely as a label to identify the -scheme.} The FITS-PC encoding is included in AST V1.5 only to allow -FITS-WCS data created with previous versions to be read. It should not, -in general, be used to create new data sets. - -\item[FITS-AIPS]\mbox{}\\ -This encoding is based on the conventions described in the document -``Non-linear Coordinate Systems in AIPS'' by Eric W. Greisen (revised 9th -September, 1994).\footnote{Available by ftp from fits.cv.nrao.edu -/fits/documents/wcs/aips27.ps.Z} It is currently employed by the AIPS -data analysis facility, so its use will facilitate data exchange with -AIPS. This encoding uses \texttt{CROTAi} and \texttt{CDELTi} keywords to -describe axis rotation and scaling. - -\item[FITS-AIPS++]\mbox{}\\ -Encodes coordinate system information in FITS -header cards using the conventions used by the AIPS++ project. -This is an extension of FITS-AIPS which includes some of the -features of FITS-PC and FITS-IRAF. -\end{description} -\end{quote} - -For more detail about the above encodings, see the description of the -Encoding attribute in \appref{ss:attributedescriptions}. - -\subsection{\label{ss:foreignfitslimitations}Limitations of Foreign Encodings} - -The foreign encodings available for storing WCS information in FITS -headers have a number of limitations when compared with the native -encoding of AST Objects (\secref{ss:nativefits}). The main ones are: - -\begin{enumerate} -\item Only one class of AST Object, the FrameSet, may be represented -using a foreign FITS encoding. This should not come as a surprise, -because the purpose of storing WCS information in FITS headers is to -attach coordinate systems to an associated array of data. Since the -FrameSet is the AST Object designed for the same purpose -(\secref{ss:baseandcurrent}), there is a natural correspondence. - -The way in which a FrameSet is translated to and from the foreign -encoding also follows from this correspondence. The FrameSet's base -Frame identifies the data grid coordinates of the associated FITS -data. These are the same as FITS pixel coordinates, in which the first -pixel (in 2 dimensions) has coordinates (1,1) at its -centre. Similarly, the current Frame of the FrameSet identifies the -FITS world coordinate system associated with the data. - -\item You may store a representation of only a single FrameSet in any -individual set of FITS header cards (\emph{i.e.}\ in a single -FitsChan) at one time. If you attempt to store more than one, you may -over-write the previous one or generate an invalid representation of -your WCS information. - -This is mainly a consequence of the use of fixed FITS keywords by -foreign encodings and the fact that you cannot, in general, have -multiple FITS cards with the same keyword. - -\item In general, it will not be possible to store every possible -FrameSet that you might construct. Depending on the encoding, only -certain FrameSets that conform to particular restrictions can be -represented and, even then, some of their information may be lost. See -the description of the Encoding attribute in -\appref{ss:attributedescriptions} for more details of these -limitations. -\end{enumerate} - -It should be understood that using foreign encodings to read and write -information held in AST Objects is essentially a process of converting -the data format. As such, it potentially suffers from the same -problems faced by all such processes, \emph{i.e.}\ differences between -the AST data model and that of the foreign encoding may cause some -information to be lost. Because the AST model is extremely flexible, -however, any data loss can largely be eliminated when reading. -Instead, this effect manifests itself in the form of the above -encoding-dependent restrictions on the kind of AST Objects which may -be written. - -One of the aims of the AST library, of course, is to insulate you from -the details of these foreign encodings and the restrictions they -impose. We will see shortly, therefore, how AST provides a mechanism -for determining whether your WCS information satisfies the necessary -conditions and allows you to make an automatic choice of which -encoding to use. - -\subsection{\label{ss:identifyingfitsencoding}Identifying Foreign Encodings on Input} - -Let us now examine the practicalities of extracting WCS information -from a set of FITS header cards which have been written by some other -software system. We will pretend that our program does not know which -encoding has been used for the WCS information and must discover this -for itself. In order to have a concrete example, however, we will use -the following set of cards. These use the FITS-AIPS encoding and -contain a typical mix of other FITS cards which are irrelevant to the -WCS information in which we are interested: - -\small -\begin{terminalv} -SIMPLE = T / Written by IDL: 30-Jul-1997 05:35:42.00 -BITPIX = -32 / Bits per pixel. -NAXIS = 2 / Number of dimensions -NAXIS1 = 300 / Length of x axis. -NAXIS2 = 300 / Length of y axis. -CTYPE1 = 'GLON-ZEA' / X-axis type -CTYPE2 = 'GLAT-ZEA' / Y-axis type -CRVAL1 = -149.56866 / Reference pixel value -CRVAL2 = -19.758201 / Reference pixel value -CRPIX1 = 150.500 / Reference pixel -CRPIX2 = 150.500 / Reference pixel -CDELT1 = -1.20000 / Degrees/pixel -CDELT2 = 1.20000 / Degrees/pixel -CROTA1 = 0.00000 / Rotation in degrees. -SURVEY = 'COBE DIRBE' -BUNITS = 'MJy/sr ' / -ORIGIN = 'CDAC ' / Cosmology Data Analysis Center -TELESCOP= 'COBE ' / COsmic Background Explorer satellite -INSTRUME= 'DIRBE ' / COBE instrument [DIRBE, DMR, FIRAS] -PIXRESOL= 9 / Quad tree pixel resolution [6, 9] -DATE = '27/09/94' / FITS file creation date (dd/mm/yy) -DATE-MAP= '16/09/94' / Date of original file creation (dd/mm/yy) -COMMENT COBE specific keywords -DATE-BEG= '08/12/89' / date of initial data represented (dd/mm/yy) -DATE-END= '25/09/90' / date of final data represented (dd/mm/yy) -\end{terminalv} -\normalsize - -c+ -The first step is to create a FitsChan and insert these cards into -it. If ``cards'' is an array of pointers to character strings holding -the header cards and ``ncards'' is the number of cards, this could be -done as follows: -c- -f+ -The first step is to create a FitsChan and insert these cards into -it. If CARDS is an array of character strings holding the header cards -and NCARDS is the number of cards, this could be done as follows: -f- - -c+ -\small -\begin{terminalv} -#include "ast.h" -#define MAXCARD 100 -AstFitsChan *fitschan; -char *cards[ MAXCARD ]; -int icard, ncard; - -... - -fitschan = astFitsChan( NULL, NULL, "" ); -for ( icard = 0; icard < ncard; icard++ ) astPutFits( fitschan, cards[ icard ], 0 ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER FITSCHAN, ICARD, NCARD, STATUS - CHARACTER * ( 80 ) CARDS( NCARD ) - - STATUS = 0 - - ... - - FITSCHAN = AST_FITSCHAN( AST_NULL, AST_NULL, ' ', STATUS ) - DO 1 ICARD = 1, NCARD - CALL AST_PUTFITS( FITSCHAN, CARDS( ICARD ), .FALSE., STATUS ) - 1 CONTINUE -\end{terminalv} -\normalsize -f- - -Note that we have not initialised the Encoding attribute of the -FitsChan as we did in \secref{ss:creatingafitschan} when we wanted to -use the native encoding. This is because we are pretending not to know -which encoding to use and want AST to determine this for us. By -leaving the Encoding attribute un-set, its default value will adjust -to whichever encoding AST considers to be most appropriate, according -to the FITS header cards present. For details of how this choice is -made, see the description of the Encoding attribute in -\appref{ss:attributedescriptions}. - -This approach has the obvious advantages of making our program simpler -and more flexible and of freeing us from having to know about the -different encodings available. As a bonus, it also means that the -program will be able to read any new encodings that AST may support in -future, without needing to be changed. - -At this point, we could enquire the default value of the Encoding -attribute, which indicates which encoding AST intends to use, as -follows: - -c+ -\small -\begin{terminalv} -const char *encode; - -... - - -encode = astGetC( fitschan, "Encoding" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 20 ) ENCODE - - ... - - ENCODE = AST_GETC( FITSCHAN, 'Encoding', STATUS ) -\end{terminalv} -\normalsize -f- - -The result of this enquiry would be the string ``FITS-AIPS''. Note -that we could also have set the FitsChan's Encoding attribute -explicitly, such as when creating it: - -c+ -\small -\begin{terminalv} -fitschan = astFitsChan( NULL, NULL, "Encoding=FITS-AIPS" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - FITSCHAN = AST_FITSCHAN( AST_NULL, AST_NULL, 'Encoding=FITS-AIPS', STATUS ) -\end{terminalv} -\normalsize -f- - -If we tried to read information using this encoding -(\secref{ss:readingforeignfits}), but failed, we could then change the -encoding and try again. This would allow our program to take control -of how the optimum choice of encoding is arrived at. However, it would -also involve using explicit knowledge of the encodings available and -this is best avoided if possible. - -\subsection{\label{ss:readingforeignfits}Reading Foreign WCS Information from a FITS Header} - -c+ -Having stored a set of FITS header cards in a FitsChan and determined -how the WCS information is encoded -(\secref{ss:identifyingfitsencoding}), the next step is to read an AST -Object from the FitsChan using astRead. We must also remember to -rewind the FitsChan first, if necessary, such as by clearing its Card -attribute, which defaults to 1: -c- -f+ -Having stored a set of FITS header cards in a FitsChan and determined -how the WCS information is encoded -(\secref{ss:identifyingfitsencoding}), the next step is to read an AST -Object from the FitsChan using AST\_READ. We must also remember to -rewind the FitsChan first, if necessary, such as by clearing its Card -attribute, which defaults to 1: -f- - -c+ -\small -\begin{terminalv} -AstObject *wcsinfo; - -... - -astClear( fitschan, "Card" ); -wcsinfo = astRead( fitschan ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER WCSINFO - - ... - - CALL AST_CLEAR( FITSCHAN, 'Card', STATUS ) - WCSINFO = AST_READ( FITSCHAN, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -If the pointer returned by astRead is not equal to AST\_\_NULL, then -an Object has been read successfully. Otherwise, there was either no -information to read or the choice of FITS encoding -(\secref{ss:identifyingfitsencoding}) was inappropriate. -c- -f+ -If the pointer returned by AST\_READ is not equal to AST\_\_NULL, then -an Object has been read successfully. Otherwise, there was either no -information to read or the choice of FITS encoding -(\secref{ss:identifyingfitsencoding}) was inappropriate. -f- - -At this point you might like to indulge in a little data validation -along the lines described in \secref{ss:validatinginput}, for example: - -c+ -\small -\begin{terminalv} -if ( !strcmp( astGetC( wcsinfo, "Class" ), "FrameSet" ) ) { - -} else { - -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - IF ( AST_GETC( WCSINFO, 'Class', STATUS ) .EQ. 'FrameSet' ) THEN - - ELSE - - END IF -\end{terminalv} -\normalsize -f- - -If a foreign encoding has definitely been used, then the Object will -automatically be a FrameSet (\secref{ss:foreignfitslimitations}), so -this stage can be omitted. However, if the native encoding -(\secref{ss:nativeencoding}) might have been employed, which is a -possibility if you accept the FitsChan's default Encoding value, then -any class of Object might have been read and a quick check would be -worthwhile. - -c+ -If you used astShow (\secref{ss:displayingobjects}) to examine the -FrameSet which results from reading our example FITS header -(\secref{ss:identifyingfitsencoding}), you would find that its base -Frame describes the image's pixel coordinate system and that its -current Frame is a SkyFrame representing galactic coordinates. These -two Frames are inter-related by a Mapping (actually a CmpMap) which -incorporates the effects of various rotations, scalings and a -``zenithal equal area'' sky projection, so that each pixel of the FITS -image is mapped on to a corresponding sky position in galactic -coordinates. -c- -f+ -If you used AST\_SHOW (\secref{ss:displayingobjects}) to examine the -FrameSet which results from reading our example FITS header -(\secref{ss:identifyingfitsencoding}), you would find that its base -Frame describes the image's pixel coordinate system and that its -current Frame is a SkyFrame representing galactic coordinates. These -two Frames are inter-related by a Mapping (actually a CmpMap) which -incorporates the effects of various rotations, scalings and a -``zenithal equal area'' sky projection, so that each pixel of the FITS -image is mapped on to a corresponding sky position in galactic -coordinates. -f- - -Because this FrameSet may be used both as a Mapping -(\secref{ss:framesetasmapping}) and as a Frame -(\secref{ss:framesetasframe}), it may be employed directly to perform -many useful operations without any need to decompose it into its -component parts. These include: - -\begin{itemize} -\item Transforming data grid (FITS pixel) coordinates into galactic -coordinates and \emph{vice versa} (\secref{ss:framesetasmapping}). - -\item Formatting coordinate values (either pixel or galactic -coordinates) ready for display to a user -(\secref{ss:formattingaxisvalues} and \secref{ss:normalising}). - -\item Enquiring about axis labels (or other axis -information---\secref{ss:frameattributes}) which might be used, for -example, to label columns of coordinates in a table -(\secref{ss:frameaxisattributes}). - -\item Aligning the image with another image from which a similar -FrameSet has been obtained (\secref{ss:registeringimages}). - -\item Creating a Plot (\secref{ss:plots}), which can be used to overlay -a variety of graphical information (including a coordinate -grid---Figure~\ref{fig:gridplot}) on the displayed image. - -\item Generating a new FrameSet which reflects any geometrical -processing you perform on the associated image data -(\secref{ss:wcsprocessingexample}). This new FrameSet could then be -written out as FITS headers to describe the modified image -(\secref{ss:writingforeignfits}). -\end{itemize} - -If the FrameSet contains other Frames (apart from the base and current -Frames), then you would also have access to information about other -coordinate systems associated with the image. - -\subsection{\label{ss:destructiveread}Removing WCS Information from FITS Headers---the Destructive Read} - -It is instructive at this point to examine the contents of a FitsChan -after we have read a FrameSet from it -(\secref{ss:readingforeignfits}). The following would rewind our -FitsChan and display its contents: - -c+ -\small -\begin{terminalv} -#include -char card[ 81 ]; - -... - -astClear( fitschan, "Card" ); -while ( astFindFits( fitschan, "%f", card, 1 ) ) (void) printf( "%s\n", card ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER CARD * ( 80 ) - - ... - - CALL AST_CLEAR( FITSCHAN, 'Card', STATUS ) - 2 CONTINUE - IF ( AST_FINDFITS( FITSCHAN, '%f', CARD, .TRUE., STATUS ) ) THEN - WRITE ( *, '(A)' ) CARD - GO TO 2 - END IF -\end{terminalv} -\normalsize -f- - -The output, if we started with the example FITS header in -\secref{ss:identifyingfitsencoding}, might look like this: - -\small -\begin{terminalv} -SIMPLE = T / Written by IDL: 30-Jul-1997 05:35:42.00 -BITPIX = -32 / Bits per pixel. -NAXIS = 2 / Number of dimensions -NAXIS1 = 300 / Length of x axis. -NAXIS2 = 300 / Length of y axis. -SURVEY = 'COBE DIRBE' -BUNITS = 'MJy/sr ' -ORIGIN = 'CDAC ' / Cosmology Data Analysis Center -TELESCOP= 'COBE ' / COsmic Background Explorer satellite -INSTRUME= 'DIRBE ' / COBE instrument [DIRBE, DMR, FIRAS] -PIXRESOL= 9 / Quad tree pixel resolution [6, 9] -DATE = '27/09/94' / FITS file creation date (dd/mm/yy) -DATE-MAP= '16/09/94' / Date of original file creation (dd/mm/yy) -COMMENT COBE specific keywords -DATE-BEG= '08/12/89' / date of initial data represented (dd/mm/yy) -DATE-END= '25/09/90' / date of final data represented (dd/mm/yy) -\end{terminalv} -\normalsize - -c+ -Comparing this with the original, you can see that all the FITS cards -that represent WCS information have been removed. They have -effectively been ``sucked out'' of the FitsChan by the destructive -read that astRead performs and converted into an equivalent -FrameSet. AST remembers where they were stored, however, so that if we -later write WCS information back into the FitsChan -(\secref{ss:writingforeignfits}) they will, as far as possible, go -back into their original locations. This helps to preserve the overall -layout of the FITS header. -c- -f+ -Comparing this with the original, you can see that all the FITS cards -that represent WCS information have been removed. They have -effectively been ``sucked out'' of the FitsChan by the destructive -read that AST\_READ performs and converted into an equivalent -FrameSet. AST remembers where they were stored, however, so that if we -later write WCS information back into the FitsChan -(\secref{ss:writingforeignfits}) they will, as far as possible, go -back into their original locations. This helps to preserve the -overall layout of the FITS header. -f- - -c+ -You can now see why astRead performs destructive reads. It is a -mechanism for removing WCS information from a FITS header while -insulating you, as a programmer, from the details of the encoding -being used. It means you can ensure that all relevant header cards -have been removed, giving you a clean slate, without having to know -which FITS keywords any particular encoding uses. -c- -f+ -You can now see why AST\_READ performs destructive reads. It is a -mechanism for removing WCS information from a FITS header while -insulating you, as a programmer, from the details of the encoding -being used. It means you can ensure that all relevant header cards -have been removed, giving you a clean slate, without having to know -which FITS keywords any particular encoding uses. -f- - -Clearing this WCS information out of a FITS header is particularly -important when considering how to write new WCS information back after -processing (\secref{ss:writingforeignfits}). If any relevant FITS -cards are left over from the input dataset and find their way into the -new processed header, they could interfere with the new information -being written.\footnote{This can happen if a particular keyword is -present in the input header but is not used in the output header -(whether particular keywords are used can depend on the WCS -information being stored). In such a case, the original value would -not be over-written by a new output value, so would remain erroneously -present.} The destructive read mechanism ensures that this doesn't -happen. - -\subsection{\label{ss:propagatingwcsinformation}Propagating WCS Information through Data Processing Steps} - -One of the purposes of AST is to make it feasible to propagate WCS -information through successive stages of data processing, so that it -remains consistent with the associated image data. As far as possible, -this should happen regardless of the FITS encoding used to store the -original WCS information. - -If the data processing being performed does not change the -relationship between image pixel and world coordinates (whatever these -may be), then propagation of the WCS information is -straightforward. You can simply copy the FITS header from input to -output. - -If this relationship changes, however, then the WCS information must -be processed alongside the image data and a new FITS header generated -to represent it. In this case, the sequence of operations within your -program would probably be as follows: - -\begin{enumerate} -\item Read the image data and associated FITS header from the input -dataset, putting the header cards into a FitsChan -(\secref{ss:identifyingfitsencoding}). - -\item Read an AST Object, a FrameSet, from the FitsChan (typically -using a foreign FITS encoding---\secref{ss:readingforeignfits}). - -\item Process the image data and modify the FrameSet accordingly -(\emph{e.g.}~\secref{ss:wcsprocessingexample}). - -\item Write the FrameSet back into the FitsChan -(\secref{ss:writingforeignfits}). - -\item Perform any other modification of FITS header cards your program -may require. - -\item Write the FitsChan contents (\emph{i.e.}\ processed header -cards) and image data to the output dataset. -\end{enumerate} - -In stage (2), the original WCS information will be removed from the -FitsChan by a destructive read. Later, in stage (4), new WCS -information is written to replace it. This is the process which we -consider next (\secref{ss:writingforeignfits}). - -\subsection{\label{ss:writingforeignfits}Writing Foreign WCS Information to a FITS Header} - -Before we can write processed WCS information held in a FrameSet back -into a FitsChan in preparation for output, we must select the FITS -encoding to use. Unfortunately, we cannot simply depend on the -default value of the Encoding attribute, as we did when reading the -input information (\secref{ss:identifyingfitsencoding}), because the -destructive action of reading the WCS data -(\secref{ss:destructiveread}) will have altered the FitsChan's -contents. This, in turn, will have changed the choice of default -encoding, probably causing it to revert to NATIVE. - -c+ -We will return to the question of the optimum choice of encoding -below. For now, let's assume that we want to use the same encoding -for output as we used for input. Since we enquired what that was -before we read the input WCS data from the FitsChan -(\secref{ss:identifyingfitsencoding}), we can now set that value -explicitly. We can also set the FitsChan's Card attribute back to 1 at -the same time (because the write will fail if the FitsChan is not -rewound). astWrite can then be used to write the output WCS -information into the FitsChan: -c- -f+ -We will return to the question of the optimum choice of encoding -below. For now, let's assume we want to use the same encoding for -output as we used for input. Since we enquired what that was before we -read the input WCS data from the FitsChan -(\secref{ss:identifyingfitsencoding}), we can now set that value -explicitly. We can also set the FitsChan's Card attribute back to 1 at -the same time (because the write will fail if the FitsChan is not -rewound). AST\_WRITE can then be used to write the output WCS -information into the FitsChan: -f- - -c+ -\small -\begin{terminalv} -int nobj; - -... - -astSet( fitschan, "Card=1, Encoding=%s", encode ); -nobj = astWrite( fitschan, wcsinfo ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER NOBJ - - ... - - - CALL AST_SET( FITSCHAN, 'Card=1, Encoding=' // ENCODE, STATUS ) - NOBJ = AST_WRITE( FITSCHAN, WCSINFO, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -The value returned by astWrite (assigned to ``nobj'') indicates how -many Objects were written. This will either be 1 or zero. A value of -zero is used to indicate that the information could not be encoded in -the form you requested. If this happens, nothing will have been -written. -c- -f+ -The value returned by AST\_WRITE (assigned to NOBJ) indicates how many -Objects were written. This will either be 1 or zero. A value of zero -is used to indicate that the information could not be encoded in the -form you requested. If this happens, nothing will have been written. -f- - -If your choice of encoding proves inadequate, the probable reason is -that the changes you have made to the FrameSet have caused it to -depart from the data model which the encoding assumes. AST knows -about the data model used by each encoding and will attempt to -simplify the FrameSet you provide so as to fit into that model, thus -relieving you of the need to understand the details and limitations of -each encoding yourself.\footnote{Storing values in the FitsChan for -FITS headers NAXIS1, NAXIS2, \emph{etc.} (the grid dimensions in pixels), -before invoking -c+ -astWrite -c- -f+ -AST\_WRITE -f- -can sometimes help to produce a successful write.} When this attempt fails, -however, you must consider what alternative encoding to use. - -Ideally, you would probably want to try a sequence of alternative -encodings, using an approach such as the following: - -c+ -\small -\begin{terminalv} -/* 1. */ -astSet( fitschan, "Card=1, Encoding=FITS-IRAF" ); -if ( !astWrite( fitschan, wcsinfo ) ) { - -/* 2. */ - astSetC( fitschan, "Encoding", encode ); - if ( !astWrite( fitschan, wcsinfo ) ) { - -/* 3. */ - astSet( fitschan, "Encoding=NATIVE" ); - (void) astWrite( fitschan, wcsinfo ); - } -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} -* 1. - CALL AST_SET( FITSCHAN, 'Card=1, Encoding=FITS-WCS', STATUS ) - IF ( AST_WRITE( FITSCHAN, WCSINFO, STATUS ) .EQ. 0 ) THEN - -* 2. - CALL AST_SETC( FITSCHAN, 'Encoding', ENCODE, STATUS ) - IF ( AST_WRITE( FITSCHAN, WCSINFO, STATUS ) .EQ. 0 ) THEN - -* 3. - CALL AST_SET( FITSCHAN, 'Encoding=NATIVE', STATUS ) - NOBJ = AST_WRITE( FITSCHAN, WCSINFO, STATUS ) - END IF - END IF -\end{terminalv} -\normalsize -f- - -That is: - -\begin{enumerate} -\item Start by trying the FITS-WCS encoding, on the grounds that FITS -should provide a universal interchange standard in which all WCS -information should be expressed if possible. - -\item If that fails, then try the original encoding used for the input -WCS information, on the grounds that you are at least not making the -information any harder for others to read than it originally was. - -\item If that also fails, then you are probably trying to store fairly -complex information for which you need the native encoding. Only other -AST programs will then be able to read this information, but these are -probably the only programs that will be able to do anything sensible -with it anyway. -\end{enumerate} - -c+ -An alternative approach might be to encode the WCS information in several -ways, since this gives the maximum chance that other software will be -able to read it. This approach is only possible if there is no -significant conflict between the FITS keywords used by the different -encodings\footnote{In practice, this means you should avoid mixing -FITS-IRAF, FITS-WCS, FITS-AIPS, FITS-AIPS++ and FITS-PC encodings since they share -many keywords.}. Adopting this approach would simply require multiple -calls to astWrite, rewinding the FitsChan and changing its Encoding value -before each one. -c- -f+ -An alternative approach might be to encode the WCS information in several -ways, since this gives the maximum chance that other software will be -able to read it. This approach is only possible if there is no -significant conflict between the FITS keywords used by the different -encodings\footnote{In practice, this means you should avoid mixing -FITS-IRAF, FITS-WCS, FITS-AIPS, FITS-AIPS++ and FITS-PC encodings since they share -many keywords.}. Adopting this approach would simply require multiple -calls to AST\_WRITE, rewinding the FitsChan and changing its Encoding value -before each one. -f- - -Unfortunately, however, there is a drawback to duplicating WCS -information in the FITS header in this way, because any program which -modifies one version of this information and simply copies the -remainder of the header will risk producing two inconsistent sets of -information. This could obviously be confusing to subsequent -software. Whether you consider this a worthwhile risk probably depends -on the use to which you expect your data to be put. - -\cleardoublepage -\section{\label{ss:xmlchan}Storing AST Objects as XML (XmlChan)} - -\htmladdnormallinkfoot{XML}{http://www.w3.org/XML/} -is fast becoming the standard format for passing structured data around -the internet, and much general purpose software has been written for -tasks such as the parsing, editing, display and transformation of XML -data. The XmlChan class (a specialised form of Channel) provides -facilities for storing AST objects externally in the form of XML documents, -thus allowing such software to be used. - -The primary XML format used by the XmlChan class is a fairly close -transliteration of the AST native format produced by the basic Channel -class. Currently, there is no DTD or schema defining the structure of data -produced in this format by an XmlChan. The following is a native AST -representation of a simple 1-D Frame (including comments and with the Full -attribute set to zero so that some default attribute values are included -as extra comments): - -\small -\begin{terminalv} - Begin Frame # Coordinate system description -# Title = "1-d coordinate system" # Title of coordinate system - Naxes = 1 # Number of coordinate axes - Domain = "SCREEN" # Coordinate system domain -# Lbl1 = "Axis 1" # Label for axis 1 -# Uni1 = "cm" # Units for axis 1 - Ax1 = # Axis number 1 - Begin Axis # Coordinate axis - Unit = "cm" # Axis units - End Axis - End Frame -\end{terminalv} -\normalsize - -The corresponding XmlChan output would look like: - -\small -\begin{terminalv} - - <_attribute name="Title" quoted="true" value="1-d coordinate system" - desc="Title of coordinate system" default="true"/> - <_attribute name="Naxes" value="1" desc="Number of coordinate axes"/> - <_attribute name="Domain" quoted="true" value="SCREEN" - desc="Coordinate system domain"/> - <_attribute name="Lbl1" quoted="true" value="Axis 1" - desc="Label for axis 1" default="true"/> - <_attribute name="Uni1" quoted="true" value="cm" - desc="Units for axis 1" default="true"/> - - - <_attribute name="Unit" quoted="true" value="cm" desc="Axis units"/> - - -\end{terminalv} -\normalsize - - -Notes: - -\begin{enumerate} -\item The AST class name is used as the name for an XML element which contain -a description of an AST object. - -\item AST attributes are described by XML elements with the name -``\_attribute''. Unfortunately, the word ``attribute'' is also used by XML -to refer to a ``name=value'' pair within an element start tag. So for -instance, the ``Title'' attribute of the AST Frame object is described -within an XML element with name ``\_attribute'' in which the XML attribute -``name'' has the value ``Title'', and the XML attribute ``value'' has the -value ``1-d coordinate system''. The moral is always to be clear clear -about the context (AST or XML) in which the word \emph{attribute} is being -used! - -\item The XML includes comments both as XML attributes with the name ``desc'', -and as separate comment tags. - -\item Elements which describe default values are identified by the fact -that they have an XML attribute called ``default'' set to the value -``true''. These elements are ignored when being read back into an XmlChan. - -\item The outer-most XML element of an AST object will set the default -namespace to \verb+http://www.starlink.ac.uk/ast/xml/+ which will be -inherited by all nested elements. - -\end{enumerate} - - -The XmlChan class changes the default value for the Comment and Full -attributes (inherited from the base Channel class) to zero and -1, -resulting in terse output by default. With the default values for these -attributes, the above XML is reduced to the following: - -\small -\begin{terminalv} - - <_attribute name="Naxes" value="1"/> - <_attribute name="Domain" quoted="true" value="SCREEN"/> - - <_attribute name="Unit" quoted="true" value="cm"/> - - -\end{terminalv} -\normalsize - - -The XmlChan class uses the Skip attributes very similarly to the Channel -class. If Skip is zero (the default) then an error will be reported if the text -supplied by the source function does not begin with an AST Object. If -Skip is non-zero, then initial text is skipped over without error until -the start of an AST object is found. this allows an AST object to be -located within a larger XML document. - -\subsection{Reading IVOA Space-Time-Coordinates XML (STC-X) Descriptions} -The XmlChan class also provides support for reading (but not writing) XML -documents which use a restricted subset of an early draft (V1.20) of the -IVOA Space-Time-Coordinates XML (STC-X) system. The version of STC-X -finally adopted by the IVOA differs in several significant respects from -V1.20, and so the STC-X support currently provided by AST is mainly of -historical interest. Note, AST also supports the alternative ``STC-S'' -linear string description of the STC model (see \secref{ss:stcschans}). - -STC-X V1.20 is documented at -\url{http://www.ivoa.net/Documents/WD/STC/STC-20050225.html}, and the current -version is documented at -\url{http://www.ivoa.net/Documents/latest/STC-X.html}. - -When an STC-X document is read using an XmlChan, the read operation -produces an AST Object of the Stc class, which is itself a subclass of -Region. Specifically, each such Object will be an instance of -StcSearchLocation, StcResourceProfile, StcCatalogEntryLocation or -StcObsDataLocation. See the description of the XmlChan class and the -XmlFormat attribute for further details. - -\cleardoublepage -\section{\label{ss:stcschans}Reading and writing STC-S descriptions (StcsChans)} - -The StcsChan class provides facilities for reading and writing -IVOA ``STC-S'' descriptions. STC-S (see -\url{http://www.ivoa.net/Documents/latest/STC-S.html}) is a linear string -syntax that allows simple specification of the STC metadata describing a -region in an astronomical coordinate system. AST supports a -subset of the STC-S specification, allowing an STC-S description of a -region within an AST-supported astronomical coordinate system to be converted -into an equivalent AST Region object, and vice-versa. For further -details, see the full description of the StcsChan class in -\appref{ss:classdescriptions}. - - -\cleardoublepage -\section{\label{ss:intramaps}Creating Your Own Private Mappings (IntraMaps)} - -\subsection{The Need for Extensibility} - -However many Mapping classes are provided by AST, sooner or later you -will want to transform coordinates in some way that has not been -foreseen. You might want to plot a graph in some novel curvilinear -coordinate system (perhaps you already have a WCS system in your -software and just want to use AST for its graphical capabilities). -Alternatively, you might need to calibrate a complex dataset (like an -objective prism plate) where each position must be converted to world -coordinates with reference to calibration data under the control of an -elaborate algorithm. - -In such cases, it is clear that the basic pre-formed components -provided by AST for building Mappings are just not enough. What you -need is access to a programming language. However, if you write your -own software to transform coordinate values, then it must be made -available in the form of an AST class (from which you can create -Objects) before it can be used in conjunction with other AST -facilities. - -At this point you might consider writing your own AST class, but this -is not recommended. Not only would the internal conventions used by -AST take some time to master, but you might also find yourself having -to change your software whenever a new version of AST was -released. Fortunately, there is a much easier route provided by the -IntraMap class. - -\subsection{The IntraMap Model} - -c+ -To allow you to write your own Mappings, AST provides a special kind -of Mapping called an IntraMap. An IntraMap is a sort of ``wrapper'' -for a coordinate transformation function written in C. You write this -function yourself and then register it with AST. This, in effect, -creates a new class from which you can create Mappings -(\emph{i.e.}\ IntraMaps) which will transform coordinates in whatever -way your transformation function specifies. -c- -f+ -To allow you to write your own Mappings, AST provides a special kind -of Mapping called an IntraMap. An IntraMap is a sort of ``wrapper'' -for a coordinate transformation routine written in Fortran. You write -this routine yourself and then register it with AST. This, in effect, -creates a new class from which you can create Mappings -(\emph{i.e.}\ IntraMaps) which will transform coordinates in whatever -way your transformation routine specifies. -f- - -Because IntraMaps are Mappings, they may be used in the same way as -any other Mapping. For instance, they may be combined in series or -parallel with other Mappings using a CmpMap (\secref{ss:cmpmaps}), -they may be inverted (\secref{ss:invertingmappings}), you may enquire -about their attributes (\secref{ss:gettingattributes}), they may be -inserted into FrameSets (\secref{ss:framesets}), \emph{etc.} They do, -however, have some important limitations of which you should be aware -before we go on to consider how to create them. - -\subsection{\label{ss:intramaplimitations}Limitations of IntraMaps} - -c+ -By now, you might be wondering why any other kind of Mapping is -required at all. After all, why not simply write your own coordinate -transformation functions in C, wrap them up in IntraMaps and do away -with all the other Mapping classes in AST? -c- -f+ -By now, you might be wondering why any other kind of Mapping is -required at all. After all, why not simply write your own coordinate -transformation routines in Fortran, wrap them up in IntraMaps and do -away with all the other Mapping classes in AST? -f- - -c+ -The reason is not too hard to find. Any transformation function you -write is created solely by you, so it is a private extension which -does not form a permanent part of AST. If you use it to calibrate some -data and then pass that data to someone else, who has only the -standard version of AST, then they will not be able to interpret it. -c- -f+ -The reason is not too hard to find. Any transformation routine you -write is created solely by you, so it is a private extension which -does not form a permanent part of AST. If you use it to calibrate some -data and then pass that data to someone else, who has only the -standard version of AST, then they will not be able to interpret it. -f- - -c+ -Thus, while an IntraMap is fine for use by you and your collaborators -(who we assume have access to the same transformation functions), it -does not address the need for universal data exchange like other AST -Mappings do. This is where the ``Intra'' in the class name -``IntraMap'' comes from, implying private or internal usage. -c- -f+ -Thus, while an IntraMap is fine for use by you and your collaborators -(who we assume have access to the same transformation routines), it -does not address the need for universal data exchange like other AST -Mappings do. This is where the ``Intra'' in the class name -``IntraMap'' comes from, implying private or internal usage. -f- - -For this reason, it is unwise to store IntraMaps in datasets, unless -they will be used solely for communication between collaborating items -of software which share conventions about their use. A private -database describing coordinate systems on a graphics device might be -an example where IntraMaps would be suitable, because the data would -probably never be accessed by anyone else's software. Restricting -IntraMap usage to within a single program (\emph{i.e.} never writing -it out) is, of course, completely safe. - -c+ -If, by accident, an IntraMap should happen to escape as part of a -dataset, then the unsuspecting recipient is likely to receive an error -message when they attempt to read the data. However, AST will -associate details of the IntraMap's transformation function and its -author (if provided) with the data, so that the recipient can make an -intelligent enquiry to obtain the necessary software if this proves -essential. -c- -f+ -If, by accident, an IntraMap should happen to escape as part of a -dataset, then the unsuspecting recipient is likely to receive an error -message when they attempt to read the data. However, AST will -associate details of the IntraMap's transformation routine and its -author (if provided) with the data, so that the recipient can make an -intelligent enquiry to obtain the necessary software if this proves -essential. -f- - -c+ -\subsection{\label{ss:transformationfunctions}Writing a Transformation Function} -c- -f+ -\subsection{\label{ss:transformationfunctions}Writing a Transformation Routine} -f- - -c+ -The first stage in creating an IntraMap is to write the coordinate -transformation function. This should have a calling interface like the -astTranP function provided by AST (\emph{q.v.}). Here is a simple -example of a suitable transformation function which transforms -coordinates by squaring them: -c- -f+ -The first stage in creating an IntraMap is to write the coordinate -transformation routine. This should have a calling interface like the -AST\_TRANN function provided by AST (\emph{q.v.}). Here is a simple -example of a suitable transformation routine which transforms -coordinates by squaring them: -f- -\xlabel{SqrTran} - -c+ -\small -\begin{terminalv} -#include "ast.h" -#include - -void SqrTran( AstMapping *this, int npoint, int ncoord_in, - const double *ptr_in[], int forward, int ncoord_out, - double *ptr_out[] ) { - int point, coord; - double x; - -/* Forward transformation. */ - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - for ( coord = 0; coord < ncoord_in; coord++ ) { - x = ptr_in[ coord ][ point ]; - ptr_out[ coord ][ point ] = ( x == AST__BAD ) ? AST__BAD : x * x; - } - } - -/* Inverse transformation. */ - } else { - for ( point = 0; point < npoint; point++ ) { - for ( coord = 0; coord < ncoord_in; coord++ ) { - x = ptr_in[ coord ][ point ]; - ptr_out[ coord ][ point ] = - ( x < 0.0 || x == AST__BAD ) ? AST__BAD : sqrt( x ); - } - } - } -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - SUBROUTINE SQRTRAN( THIS, NPOINT, NCOORD_IN, INDIM, IN, FORWARD, - : NCOORD_OUT, OUTDIM, OUT, STATUS ) - INTEGER THIS, NPOINT, NCOORD_IN, INDIM, NCOORD_OUT, OUTDIM, STATUS - DOUBLE PRECISION IN( INDIM, NCOORD_IN ), OUT( OUTDIM, NCOORD_OUT ) - LOGICAL FORWARD - - INCLUDE 'AST_PAR' - DOUBLE PRECISION X - INTEGER COORD, POINT - -* Forward transformation. - IF ( FORWARD ) THEN - DO 2 POINT = 1, NPOINT - DO 1 COORD = 1, NCOORD_IN - X = IN( POINT, COORD ) - IF ( X .EQ. AST__BAD ) THEN - OUT( POINT, COORD ) = AST__BAD - ELSE - OUT( POINT, COORD ) = X * X - ENDIF - 1 CONTINUE - 2 CONTINUE - -* Inverse transformation. - ELSE - DO 4 POINT = 1, NPOINT - DO 3 COORD = 1, NCOORD_IN - X = IN( POINT, COORD ) - IF ( X .LT. 0.0D0 .OR. X .EQ. AST__BAD ) THEN - OUT( POINT, COORD ) = AST__BAD - ELSE - OUT( POINT, COORD ) = SQRT( X ) - ENDIF - 3 CONTINUE - 4 CONTINUE - ENDIF - END -\end{terminalv} -\normalsize -f- - -c+ -As you can see, the function comes in two halves which implement the -forward and inverse coordinate transformations. The number of points -to be transformed (``npoint'') and the numbers of input and output -coordinates per point (``ncoord\_in'' and ``ncoord\_out''---in this -case both are assumed equal) are passed to the function. A pair of -loops then accesses all the coordinate values. Note that it is -legitimate to omit one or other of the forward/inverse transformations -and simply not to implement it, if it will not be required. It is also -permissible to require that the numbers of input and output -coordinates be fixed (\emph{e.g.}\ at 2), or to write the function so -that it can handle arbitrary dimensionality, as here. -c- -f+ -As you can see, the routine comes in two halves which implement the -forward and inverse coordinate transformations. The number of points -to be transformed (NPOINT) and the numbers of input and output -coordinates per point (NCOORD\_IN and NCOORD\_OUT---in this case both -are assumed equal) are passed to the routine. A pair of loops then -accesses all the coordinate values. Note that it is legitimate to -omit one or other of the forward/inverse transformations and simply -not to implement it, if it will not be required. It is also -permissible to require that the numbers of input and output -coordinates be fixed (\emph{e.g.}\ at 2), or to write the routine so -that it can handle arbitrary dimensionality, as here. -f- - -c+ -Before using an incoming coordinate, the function must first check -that it is not set to the value AST\_\_BAD, which indicates missing -data (\secref{ss:badcoordinates}). If it is, the same value is also -assigned to any affected output coordinates. The value AST\_\_BAD is -also generated if any coordinates cannot be transformed. In this -example, this can happen with the inverse transformation if negative -values are encountered, so that the square root cannot be taken. -c- -f+ -Before using an incoming coordinate, the routine must first check that -it is not set to the value AST\_\_BAD, which indicates missing data -(\secref{ss:badcoordinates}). If it is, the same value is also -assigned to any affected output coordinates. The value AST\_\_BAD is -also generated if any coordinates cannot be transformed. In this -example, this can happen with the inverse transformation if negative -values are encountered, so that the square root cannot be taken. -f- - -c+ -There are very few restrictions on what a coordinate transformation -function may do. For example, it may freely perform I/O to access any -external data needed, it may invoke other AST facilities (but beware -of unwanted recursion), \emph{etc.} Typically, you may also want to -pass information to it \emph{via}\ global variables. Remember, -however, that whatever facilities the transformation function requires -must be available in every program which uses it. -c- -f+ -There are very few restrictions on what a coordinate transformation -routine may do. For example, it may freely perform I/O to access any -external data needed, it may invoke other AST facilities (but beware -of unwanted recursion), \emph{etc.} Typically, you may also want to -pass information to it \emph{via}\ global variables held in common -blocks. Remember, however, that whatever facilities the -transformation routine requires must be available in every program -which uses it. -f- - -c+ -Generally, it is not a good idea to retain context information within -a transformation function. That is, it should transform each set of -coordinates as a single point and retain no memory of the points it -has transformed before. This is in order to conform with the AST model -of a Mapping. -c- -f+ -Generally, it is not a good idea to retain context information within -a transformation routine. That is, it should transform each set of -coordinates as a single point and retain no memory of the points it -has transformed before. This is in order to conform with the AST model -of a Mapping. -f- - -c+ -If an error occurs within a transformation function, it should use the -astSetStatus function (\secref{ss:errordetection}) to set the AST -status to an error value before returning. This will alert AST to the -error, causing it to abort the current operation. The error value -AST\_\_ITFER is available for this purpose, but other values may also -be used (\emph{e.g.}\ if you wish to distinguish different types of -error). -c- -f+ -If an error occurs within a transformation routine, it should set its -STATUS argument to an error value before returning. This will alert -AST to the error, causing it to abort the current operation. The error -value AST\_\_ITFER is available for this purpose, but other values may -also be used (\emph{e.g.}\ if you wish to distinguish different types -of error). The AST\_\_ITFER error value is defined in the AST\_ERR -include file. -f- - -c+ -\subsection{\label{ss:registeringintramaps}Registering a Transformation Function} -c- -f+ -\subsection{\label{ss:registeringintramaps}Registering a Transformation Routine} -f- - -c+ -Having written your coordinate transformation function, the next step -is to register it with AST. Registration is performed using -astIntraReg, as follows: -c- -f+ -Having written your coordinate transformation routine, the next step -is to register it with AST. Registration is performed using -AST\_INTRAREG, as follows: -f- - -c+ -\small -\begin{terminalv} -void SqrTran( AstMapping *, int, int, const double *[], int, int, double *[] ); - -const char *author, *contact, *purpose; - -... - -purpose = "Square each coordinate value"; -author = "R.F. Warren-Smith & D.S. Berry"; -contact = "http://www.starlink.ac.uk/cgi-bin/htxserver/sun211.htx/?xref_SqrTran"; - -astIntraReg( "SqrTran", 2, 2, SqrTran, 0, purpose, author, contact ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - EXTERNAL SQRTRAN - - CHARACTER * ( 80 ) AUTHOR, CONTACT, PURPOSE - - ... - - PURPOSE = 'Square each coordinate value' - AUTHOR = 'R.F. Warren-Smith & D.S. Berry' - CONTACT = 'http://www.starlink.ac.uk/cgi-bin/htxserver/' // - 'sun210.htx/?xref_SqrTran' - - CALL AST_INTRAREG( 'SqrTran', 2, 2, SQRTRAN, 0, - : PURPOSE, AUTHOR, CONTACT, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Note that you should also provide a function prototype to describe the -transformation function (the implementation of the function itself -would suffice, of course). -c- -f+ -Note that the transformation routine must also appear in a Fortran -EXTERNAL statement. -f- - -c+ -The first argument to astIntraReg is a name by which the -transformation function will be known. This will be used when we come -to create an IntraMap and is case sensitive. We recommend that you use -the actual function name here and make this sufficiently unusual that -it is unlikely to clash with any other functions in most people's -software. -c- -f+ -The first argument to AST\_INTRAREG is a name by which the -transformation routine will be known. This will be used when we come -to create an IntraMap and is case sensitive. We recommend that you -base this on the actual routine name and make this sufficiently -unusual that it is unlikely to clash with any other routines in most -people's software. -f- - -c+ -The next two arguments specify the number of input and output -coordinates which the transformation function will handle. These -correspond with the Nin and Nout attributes of the IntraMap we will -create. Here, we have set them both to 2, which means that we will -only be able to create IntraMaps with 2 input and 2 output coordinates -(despite the fact that the transformation function can actually handle -other dimensionalities). We will see later -(\secref{ss:variableintramapcoordinates}) how to remove this -restriction. -c- -f+ -The next two arguments specify the number of input and output -coordinates which the transformation routine will handle. These -correspond with the Nin and Nout attributes of the IntraMap we will -create. Here, we have set them both to 2, which means that we will -only be able to create IntraMaps with 2 input and 2 output coordinates -(despite the fact that the transformation routine can actually handle -other dimensionalities). We will see later -(\secref{ss:variableintramapcoordinates}) how to remove this -restriction. -f- - -c+ -The fourth argument should contain a set of flags which describe the -transformation function in a little more detail. We will return to -this shortly (\secref{ss:restrictedintramaps} \& -\secref{ss:simplifyingintramaps}). For now, we supply a value of zero. -c- -f+ -The fourth argument should contain a set of flags which describe the -transformation routine in a little more detail. We will return to this -shortly (\secref{ss:restrictedintramaps} \& -\secref{ss:simplifyingintramaps}). For now, we supply a value of zero. -f- - -c+ -The remaining arguments are character strings which document the -transformation function, mainly for the benefit of anyone who is -unfortunate enough to encounter a reference to it in their data which -they cannot interpret. As explained above -(\secref{ss:intramaplimitations}), you should try and avoid this, but -accidents will happen, so you should always provide strings containing -the following: -c- -f+ -The remaining arguments are character strings which document the -transformation routine, mainly for the benefit of anyone who is -unfortunate enough to encounter a reference to it in their data which -they cannot interpret. As explained above -(\secref{ss:intramaplimitations}), you should try and avoid this, but -accidents will happen, so you should always provide strings containing -the following: -f- - -\begin{enumerate} -c+ -\item A short description of what the transformation function is for. -c- -f+ -\item A short description of what the transformation routine is for. -f- -\item The name of the author. -\item Contact details, such as an e-mail or WWW address. -\end{enumerate} - -c+ -The idea is that anyone finding an IntraMap in their data, but lacking -the necessary transformation function, should be able to contact the -author and make a sensible enquiry in order to obtain it. If you -expect many enquiries, you may like to set up a World Wide Web page -and use that instead (in the example above, we use the WWW address of -the relevant part of this document). -c- -f+ -The idea is that anyone finding an IntraMap in their data, but lacking -the necessary transformation routine, should be able to contact the -author and make a sensible enquiry in order to obtain it. If you -expect many enquiries, you may like to set up a World Wide Web page -and use that instead (in the example above, we use the WWW address of -the relevant part of this document). -f- - -\subsection{Creating an IntraMap} - -c+ -Once a transformation function has been registered, creating an -IntraMap from it is simple: -c- -f+ -Once a transformation routine been registered, creating an IntraMap -from it is simple: -f- - -c+ -\small -\begin{terminalv} -AstIntraMap *intramap; - -... - -intramap = astIntraMap( "SqrTran", 2, 2, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER INTRAMAP - - ... - - INTRAMAP = AST_INTRAMAP( 'SqrTran', 2, 2, ' ', STATUS ); -\end{terminalv} -\normalsize -f- - -c+ -We simply use the astIntraMap constructor function and pass it the -name of the transformation function to use. This name is the same -(case sensitive) one that we associated with the function when we -registered it using astIntraReg (\secref{ss:registeringintramaps}). -c- -f+ -We simply use the AST\_INTRAMAP constructor function and pass it the -name of the transformation routine to use. This name is the same (case -sensitive) one that we associated with the routine when we registered -it using AST\_INTRAREG (\secref{ss:registeringintramaps}). -f- - -c+ -You can, of course, register any number of transformation functions -and select which one to use whenever you create an IntraMap. You can -also create any number of independent IntraMaps using each -transformation function. In this sense, each transformation function -you register effectively creates a new ``sub-class'' of IntraMap, from -which you can create Objects just like any other class. However, an -error will occur if you attempt to use a transformation function that -has not yet been registered. -c- -f+ -You can, of course, register any number of transformation routines and -select which one to use whenever you create an IntraMap. You can also -create any number of independent IntraMaps using each transformation -routine. In this sense, each transformation routine you register -effectively creates a new ``sub-class'' of IntraMap, from which you -can create Objects just like any other class. However, an error will -occur if you attempt to use a transformation routine that has not yet -been registered. -f- - -c+ -The second and third arguments to astIntraMap are the numbers of input -and output coordinates. These define the Nin and Nout attributes for -the IntraMap that is created and they must match the corresponding -numbers given when the transformation function was registered. -c- -f+ -The second and third arguments to AST\_INTRAMAP are the numbers of -input and output coordinates. These define the Nin and Nout attributes -for the IntraMap that is created and they must match the corresponding -numbers given when the transformation routine was registered. -f- - -c+ -The final argument is the usual attribute initialisation string. You -may set attribute values for an IntraMap in exactly the same way as -for any other Mapping (\secref{ss:settingattributes}, and also see -\secref{ss:intraflag}). -c- -f+ -The penultimate argument is the usual attribute initialisation -string. You may set attribute values for an IntraMap in exactly the -same way as for any other Mapping (\secref{ss:settingattributes}, and -also see \secref{ss:intraflag}). -f- - -c+ -\subsection{\label{ss:restrictedintramaps}Restricted Implementations of Transformation Functions} -c- -f+ -\subsection{\label{ss:restrictedintramaps}Restricted Implementations of Transformation Routines} -f- - -c+ -You may not always want to use both the forward and inverse -transformations when you create an IntraMap, so it is possible to omit -either from the underlying coordinate transformation -function. Consider the following, for example: -c- -f+ -You may not always want to use both the forward and inverse -transformations when you create an IntraMap, so it is possible to omit -either from the underlying coordinate transformation routine. Consider -the following, for example: -f- - -c+ -\small -\begin{terminalv} -void Poly3Tran( AstMapping *this, int npoint, int ncoord_in, - const double *ptr_in[], int forward, int ncoord_out, - double *ptr_out[] ) { - double x; - int point; - -/* Forward transformation. */ - for ( point = 0; point < npoint; point++ ) { - x = ptr_in[ 0 ][ point ]; - ptr_out[ 0 ][ point ] = ( x == AST__BAD ) ? AST__BAD : - 6.18 + x * ( 0.12 + x * ( -0.003 + x * 0.0000101 ) ); - } -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - SUBROUTINE POLY3TRAN( THIS, NPOINT, NCOORD_IN, INDIM, IN, FORWARD, - : NCOORD_OUT, OUTDIM, OUT, STATUS ) - INTEGER THIS, NPOINT, NCOORD_IN, INDIM, NCOORD_OUT, OUTDIM, STATUS - DOUBLE PRECISION IN( INDIM, NCOORD_IN ), OUT( OUTDIM, NCOORD_OUT ) - LOGICAL FORWARD - - INCLUDE 'AST_PAR' - DOUBLE PRECISION X - INTEGER POINT - -* Forward transformation. - DO 1 POINT = 1, NPOINT - X = IN( POINT, 1 ) - IF ( X .EQ. AST__BAD ) THEN - OUT( POINT, 1 ) = AST__BAD - ELSE - OUT( POINT, 1 ) = - : 6.18D0 + X * ( 0.12D0 + X * ( -0.003D0 + X * 0.0000101D0 ) ) - END IF - 1 CONTINUE - END -\end{terminalv} -\normalsize -f- - -c+ -This implements a 1-dimensional cubic polynomial transformation. Since -this is somewhat awkward to invert, however, we have only implemented -the forward transformation. When registering the function, this is -indicated via the ``flags'' argument to astIntraReg, as follows: -c- -f+ -This implements a 1-dimensional cubic polynomial transformation. Since -this is somewhat awkward to invert, however, we have only implemented -the forward transformation. When registering the routine, this is -indicated via the FLAGS argument to AST\_INTRAREG, as follows: -f- - -c+ -\small -\begin{terminalv} -void Poly3Tran( AstMapping *, int, int, const double *[], int, int, double *[] ); - -... - -astIntraReg( "Poly3Tran", 1, 1, Poly3Tran, AST__NOINV, - purpose, author, contact ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - EXTERNAL POLY3TRAN - - ... - - CALL AST_INTRAREG( 'Poly3Tran', 1, 1, POLY3TRAN, AST__NOINV, - : PURPOSE, AUTHOR, CONTACT, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, the fifth argument has been set to the flag value AST\_\_NOINV -to indicate the lack of an inverse. If the forward transformation were -absent, we would use AST\_\_NOFOR instead. Flag values for this -argument may be combined using a bitwise OR if necessary. -c- -f+ -Here, the fifth argument has been set to the flag value AST\_\_NOINV -to indicate the lack of an inverse. If the forward transformation were -absent, we would use AST\_\_NOFOR instead. Flag values for this -argument may be combined by summing them if necessary. -f- - -\subsection{\label{ss:variableintramapcoordinates}Variable Numbers of Coordinates} - -c+ -In our earlier examples, we have used a fixed number of input and -output coordinates when registering a coordinate transformation -function. It is not necessary to impose this restriction, however, if -the transformation function can cope with a variable number of -coordinates (as with the example in -\secref{ss:transformationfunctions}). We indicate the acceptability of -a variable number when registering the transformation function by -supplying the value AST\_\_ANY for the number of input and/or output -coordinates, as follows: -c- -f+ -In our earlier examples, we have used a fixed number of input and -output coordinates when registering a coordinate transformation -routine. It is not necessary to impose this restriction, however, if -the transformation routine can cope with a variable number of -coordinates (as with the example in -\secref{ss:transformationfunctions}). We indicate the acceptability of -a variable number when registering the transformation routine by -supplying the value AST\_\_ANY for the number of input and/or output -coordinates, as follows: -f- - -c+ -\small -\begin{terminalv} -astIntraReg( "SqrTran", AST__ANY, AST__ANY, SqrTran, 0, - purpose, author, contact ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_INTRAREG( 'SqrTran', AST__ANY, AST__ANY, SQRTRAN, 0, - : PURPOSE, AUTHOR, CONTACT, STATUS ) -\end{terminalv} -\normalsize -f- - -The result is that an IntraMap may now be created with any number of -input and output coordinates. For example: - -c+ -\small -\begin{terminalv} -AstIntraMap *intramap1, *intramap2; - -... - -intramap1 = astIntraMap( "SqrTran", 1, 1, "" ); -intramap2 = astIntraMap( "SqrTran", 3, 3, "Invert=1" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER INTRAMAP1, INTRAMAP2 - - ... - - INTRAMAP1 = AST_INTRAMAP( 'SqrTran', 1, 1, ' ', STATUS ) - INTRAMAP2 = AST_INTRAMAP( 'SqrTran', 3, 3, 'Invert=1', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -It is possible to fix either the number of input or output coordinates -(by supplying an explicit number to astIntraReg), but more subtle -restrictions on the number of coordinates, such as requiring that Nin -and Nout be equal, are not supported. This means that: -c- -f+ -It is possible to fix either the number of input or output coordinates -(by supplying an explicit number to AST\_INTRAREG), but more subtle -restrictions on the number of coordinates, such as requiring that Nin -and Nout be equal, are not supported. This means that: -f- - -c+ -\small -\begin{terminalv} -intramap = astIntraMap( "SqrTran", 1, 2, "" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTRAMAP = AST_INTRAMAP( 'SqrTran', 1, 2, ' ', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -will be accepted without error, although the transformation function -cannot actually handle such a combination sensibly. If this is -important, it would be worth adding a check within the transformation -function itself, so that the error would be detected when it came to -be used. -c- -f+ -will be accepted without error, although the transformation routine -cannot actually handle such a combination sensibly. If this is -important, it would be worth adding a check within the transformation -routine itself, so that the error would be detected when it came to be -used. -f- - -c+ -\subsection{\label{ss:intraflag}Adapting a Transformation Function to Individual IntraMaps} -c- -f+ -\subsection{\label{ss:intraflag}Adapting a Transformation Routine to Individual IntraMaps} -f- - -c+ -In the examples given so far, our coordinate transformation functions -have not made use of the ``this'' pointer passed to them (which -identifies the IntraMap whose transformation we are implementing). In -practice, this will often be the case. However, the presence of the -``this'' pointer allows the transformation function to invoke any -other AST function on the IntraMap, and this permits enquiries about -its attributes. The transformation function's behaviour can therefore -be modified according to any attribute values which are set. This -turns out to be a useful thing to do, so each IntraMap has a special -IntraFlag attribute reserved for exactly this purpose. -c- -f+ -In the examples given so far, our coordinate transformation routines -have not made use of the THIS pointer passed to them (which identifies -the IntraMap whose transformation we are implementing). In practice, -this will often be the case. However, the presence of the THIS pointer -allows the transformation routine to invoke any other AST routine on -the IntraMap, and this permits enquiries about its attributes. The -transformation routine's behaviour can therefore be modified according -to any attribute values which are set. This turns out to be a useful -thing to do, so each IntraMap has a special IntraFlag attribute reserved -for exactly this purpose. -f- - -c+ -Consider, for instance, the case where the transformation function has -access to several alternative sets of internally-stored data which it -may apply to perform its transformation. Rather than implement many -different versions of the transformation function, you may switch -between them by setting a value for the IntraFlag attribute when you -create an instance of an IntraMap, for example: -c- -f+ -Consider, for instance, the case where the transformation routine has -access to several alternative sets of internally-stored data which it -may apply to perform its transformation. Rather than implement many -different versions of the transformation routine, you may switch -between them by setting a value for the IntraFlag attribute when you -create an instance of an IntraMap, for example: -f- - -c+ -\small -\begin{terminalv} -intramap1 = astIntraMap( "MyTran", 2, 2, "IntraFlag=A" ); -intramap2 = astIntraMap( "MyTran", 2, 2, "IntraFlag=B" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTRAMAP1 = AST_INTRAMAP( 'MyTran', 2, 2, 'IntraFlag=A', STATUS ) - INTRAMAP2 = AST_INTRAMAP( 'MyTran', 2, 2, 'IntraFlag=B', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -The transformation function may then enquire the value of the IntraFlag -attribute (\emph{e.g.}\ using astGetC and passing it the ``this'' -pointer) and use whichever dataset is required for that particular -IntraMap. -c- -f+ -The transformation routine may then enquire the value of the IntraFlag -attribute (\emph{e.g.}\ using AST\_GETC and passing it the THIS -pointer) and use whichever dataset is required for that particular -IntraMap. -f- - -This approach is particularly useful when the number of possible -transformations is unbounded or not known in advance, in which case -the IntraFlag attribute may be used to hold numerical values encoded -as part of a character string (effectively using them as data for the -IntraMap). It is also superior to the use of a global switch for -communication (\emph{e.g.}\ setting an index to select the ``current'' -data before using the IntraMap), because it continues to work when -several IntraMaps are embedded within a more complex compound Mapping, -when you may have no control over the order in which they are used. - -\subsection{\xlabel{MaxTran}\label{ss:simplifyingintramaps}Simplifying IntraMaps} - -c+ -A notable disadvantage of IntraMaps is that they are ``black boxes'' -as far as AST is concerned. This means that they have limited ability -to participate in the simplification of compound Mappings performed, -\emph{e.g.}, by astSimplify (\secref{ss:simplifyingcmpmaps}), because -AST cannot know how they interact with other Mappings. In reality, of -course, they will often implement such specialised coordinate -transformations that the simplification possibilities will be rather -limited anyway. -c- -f+ -A notable disadvantage of IntraMaps is that they are ``black boxes'' -as far as AST is concerned. This means that they have limited ability -to participate in the simplification of compound Mappings performed, -\emph{e.g.}, by AST\_SIMPLIFY (\secref{ss:simplifyingcmpmaps}), -because AST cannot know how they interact with other Mappings. In -reality, of course, they will often implement such specialised -coordinate transformations that the simplification possibilities will -be rather limited anyway. -f- - -One important simplification, however, is the ability of a Mapping to -cancel with its own inverse to yield a unit Mapping (a UnitMap). This -is important because Mappings are frequently used to relate a dataset -to some external standard (a celestial coordinate system, for -example). When inter-relating two similar datasets calibrated using -the same standard, part of the Mapping often cancels, because it is -applied first in one direction and then the other, effectively -eliminating the reference to the standard. This is often a useful -simplification and can lead to greater efficiency. - -c+ -Many transformations have this property of cancelling with their own -inverse, but not necessarily all. Consider the following -transformation function, for example: -c- -f+ -Many transformations have this property of cancelling with their own -inverse, but not necessarily all. Consider the following -transformation routine, for example: -f- - -c+ -\small -\begin{terminalv} -void MaxTran( AstMapping *this, int npoint, int ncoord_in, - const double *ptr_in[], int forward, int ncoord_out, - double *ptr_out[] ) { - double hi, x; - int coord, point; - -/* Forward transformation. */ - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - hi = AST__BAD; - for ( coord = 0; coord < ncoord_in; coord++ ) { - x = ptr_in[ coord ][ point ]; - if ( x != AST__BAD ) { - if ( x > hi || hi == AST__BAD ) hi = x; - } - } - ptr_out[ 0 ][ point ] = hi; - } - -/* Inverse transformation. */ - } else { - for ( coord = 0; coord < ncoord_out; coord++ ) { - for ( point = 0; point < npoint; point++ ) { - ptr_out[ coord ][ point ] = ptr_in[ 0 ][ point ]; - } - } - } -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - SUBROUTINE MAXTRAN( THIS, NPOINT, NCOORD_IN, INDIM, IN, FORWARD, - : NCOORD_OUT, OUTDIM, OUT, STATUS ) - INTEGER THIS, NPOINT, NCOORD_IN, INDIM, NCOORD_OUT, OUTDIM, STATUS - DOUBLE PRECISION IN( INDIM, NCOORD_IN ), OUT( OUTDIM, NCOORD_OUT ) - LOGICAL FORWARD - - INCLUDE 'AST_PAR' - DOUBLE PRECISION HI, X - INTEGER COORD, POINT - -* Forward transformation. - IF ( FORWARD ) THEN - DO 2 POINT = 1, NPOINT - HI = AST__BAD - DO 1 COORD = 1, NCOORD_IN - X = IN( POINT, COORD ) - IF ( X .NE. AST__BAD ) THEN - IF ( X .GT. HI .OR. HI .EQ. AST__BAD ) HI = X - END IF - 1 CONTINUE - 2 CONTINUE - -* Inverse transformation. - ELSE - DO 4 COORD = 1, NCOORD_OUT - DO 3 POINT = 1, NPOINT - OUT( POINT, COORD ) = IN( POINT, 1 ) - 3 CONTINUE - 4 CONTINUE - END IF - END -\end{terminalv} -\normalsize -f- - -c+ -This function takes any number of input coordinates and returns a -single output coordinate which is the maximum value of the input -coordinates. Its inverse (actually a ``pseudo-inverse'') sets all the -input coordinates to the value of the output -coordinate.\footnote{Remember that ``ptr\_in'' identifies the original -``output'' coordinates when applying the inverse transformation and -``ptr\_out'' identifies the original ``input'' coordinates.} -c- -f+ -This routine takes any number of input coordinates and returns a -single output coordinate which is the maximum value of the input -coordinates. Its inverse (actually a ``pseudo-inverse'') sets all the -input coordinates to the value of the output -coordinate.\footnote{Remember that IN holds the original ``output'' -coordinates when applying the inverse transformation and OUT holds the -original ``input'' coordinates.} -f- - -c+ -If this function is applied in the forward direction and then in the -inverse direction, it does \textbf{not} in general restore the original -coordinate values. However, if applied in the inverse direction and -then the forward direction, it does. Hence, replacing the sequence of -operations with an equivalent UnitMap is possible in the latter case, -but not in the former. -c- -f+ -If this routine is applied in the forward direction and then in the -inverse direction, it does \textbf{not} in general restore the original -coordinate values. However, if applied in the inverse direction and -then the forward direction, it does. Hence, replacing the sequence of -operations with an equivalent UnitMap is possible in the latter case, -but not in the former. -f- - -c+ -To distinguish these possibilities, two flag values are provided for -use with astIntraReg to indicate what simplification (if any) is -possible. For example, to register the above transformation function, -we might use: -c- -f+ -To distinguish these possibilities, two flag values are provided for -use with AST\_INTRAREG to indicate what simplification (if any) is -possible. For example, to register the above transformation routine, -we might use: -f- - -c+ -\small -\begin{terminalv} -void MaxTran( AstMapping *, int, int, const double *[], int, int, double *[] ); - -... - -astIntraReg( "MaxTran", AST__ANY, 1, MaxTran, AST__SIMPIF, - purpose, author, contact ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - EXTERNAL MAXTRAN - - ... - - CALL AST_INTRAREG( 'MaxTran', AST__ANY, 1, MAXTRAN, AST__SIMPIF, - : PURPOSE, AUTHOR, CONTACT, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, the flag value AST\_\_SIMPIF supplied for the fifth argument -indicates that simplification is possible if the transformation is -applied in the inverse direction followed by the forward direction. To -indicate the complementary case, the flag AST\_\_SIMPFI would be used -instead. If both simplifications are possible (as with the SqrTran -function in \secref{ss:transformationfunctions}), then we would use -the bitwise OR of both values. -c- -f+ -Here, the flag value AST\_\_SIMPIF supplied for the fifth argument -indicates that simplification is possible if the transformation is -applied in the inverse direction followed by the forward direction. To -indicate the complementary case, the flag AST\_\_SIMPFI would be used -instead. If both simplifications are possible (as with the SQRTRAN -function in \secref{ss:transformationfunctions}), then we would use -the sum of both values. -f- - -c+ -In practice, some judgement is usually necessary when deciding whether -to allow simplification. For example, seen in one light our SqrTran -function (\secref{ss:transformationfunctions}) does not cancel with -its own inverse, because squaring a coordinate value and then taking -its square root can change the original value, if this was -negative. Therefore, replacing this combination with a UnitMap will -change the behaviour of a compound Mapping and should not be -allowed. Seen in another light, however, where the coordinates being -processed are intrinsically all positive, it is a permissible and -probably useful simplification. -c- -f+ -In practice, some judgement is usually necessary when deciding whether -to allow simplification. For example, seen in one light our SQRTRAN -routine (\secref{ss:transformationfunctions}) does not cancel with its -own inverse, because squaring a coordinate value and then taking its -square root can change the original value, if this was -negative. Therefore, replacing this combination with a UnitMap will -change the behaviour of a compound Mapping and should not be -allowed. Seen in another light, however, where the coordinates being -processed are intrinsically all positive, it is a permissible and -probably useful simplification. -f- - -c+ -If such distinctions are ever important in practice, it is simple to -register the same transformation function twice with different flag -values (use a separate name for each) and then use whichever is -appropriate when creating an IntraMap. -c- -f+ -If such distinctions are ever important in practice, it is simple to -register the same transformation routine twice with different flag -values (use a separate name for each) and then use whichever is -appropriate when creating an IntraMap. -f- - -\subsection{\label{ss:readingandwritingintramaps}Writing and Reading IntraMaps} - -c+ -It is most important to realise that when you write an IntraMap to a -Channel (\secref{ss:writingtoachannel}), the transformation function -which it uses is not stored with it. To do so is impossible, because -the function has been compiled and loaded into memory ready for -execution before AST gets to see it. However, AST does store the name -associated with the transformation function and various details about -the IntraMap itself. - -c- -f+ -It is most important to realise that when you write an IntraMap to a -Channel (\secref{ss:writingtoachannel}), the transformation routine -which it uses is not stored with it. To do so is impossible, because -the routine has been compiled and loaded into memory ready for -execution before AST gets to see it. However, AST does store the name -associated with the transformation routine and various details about -the IntraMap itself. -f- - -c+ -This means that any program attempting to read the IntraMap -(\secref{ss:readingfromachannel}) cannot make use of it unless it also -has independent access to the original transformation function. If it -does not have access to this function, an error will occur at the -point where the IntraMap is read and the associated error message will -direct the user to the author of the transformation function for more -information. -c- -f+ -This means that any program attempting to read the IntraMap -(\secref{ss:readingfromachannel}) cannot make use of it unless it also -has independent access to the original transformation routine. If it -does not have access to this routine, an error will occur at the point -where the IntraMap is read and the associated error message will -direct the user to the author of the transformation routine for more -information. -f- - -c+ -However, if the necessary transformation function is available, and -has been registered before the read operation takes place, then AST is -able to re-create the original IntraMap and will do so. Registration -of the transformation function must, of course, use the same name -(and, in fact, be identical in most particulars) as was used in the -original program which wrote the data. -c- -f+ -However, if the necessary transformation routine is available, and -has been registered before the read operation takes place, then AST is -able to re-create the original IntraMap and will do so. Registration -of the transformation routine must, of course, use the same name -(and, in fact, be identical in most particulars) as was used in the -original program which wrote the data. -f- - -c+ -This means that a set of co-operating programs which all have access -to the same set of transformation functions and register them in -identical fashion (see \secref{ss:intramaplibrary} for how this can -best be achieved) can freely exchange data that contain IntraMaps. The -need to avoid exporting such data to unsuspecting third parties -(\secref{ss:intramaplimitations}) must, however, be re-iterated. -c- -f+ -This means that a set of co-operating programs which all have access -to the same set of transformation routines and register them in -identical fashion (see \secref{ss:intramaplibrary} for how this can -best be achieved) can freely exchange data that contain IntraMaps. The -need to avoid exporting such data to unsuspecting third parties -(\secref{ss:intramaplimitations}) must, however, be re-iterated. -f- - -c+ -\subsection{\label{ss:intramaplibrary}Managing Transformation Functions in Libraries} -c- -f+ -\subsection{\label{ss:intramaplibrary}Managing Transformation Routines in Libraries} -f- - -c+ -If you are developing a large suite of data reduction software, you -may have a need to use IntraMaps at various points within it. Very -probably this will occur in unrelated modules which are compiled -separately and then stored in a library. Since the transformation -functions required must be registered before they can be used, this -makes it difficult to decide where to perform this registration, -especially since any particular data reduction program may use an -arbitrary subset of the modules in your library. -c- -f+ -If you are developing a large suite of data reduction software, you -may have a need to use IntraMaps at various points within it. Very -probably this will occur in unrelated modules which are compiled -separately and then stored in a library. Since the transformation -routines required must be registered before they can be used, this -makes it difficult to decide where to perform this registration, -especially since any particular data reduction program may use an -arbitrary subset of the modules in your library. -f- - -c+ -To assist with this problem, AST allows you to perform the same -registration of a transformation function any number of times, so long -as it is performed using an identical invocation of astIntraReg on -each occasion (\emph{i.e.}\ all of its arguments must be -identical). This means you do not have to keep track of whether a -particular function has already been registered but could, in fact, -register it on each occasion immediately before it is required -(wherever that may be). In order that all registrations are identical, -however, it is recommended that you group them all together into a -single function, perhaps as follows: -c- -f+ -To assist with this problem, AST allows you to perform the same -registration of a transformation routine any number of times, so long -as it is performed using an identical invocation of AST\_INTRAREG on -each occasion (\emph{i.e.}\ all of its arguments must be -identical). This means you do not have to keep track of whether a -particular routine has already been registered but could, in fact, -register it on each occasion immediately before it is required -(wherever that may be). In order that all registrations are identical, -however, it is recommended that you group them all together into a -single routine, perhaps as follows: -f- - -c+ -\small -\begin{terminalv} -void MyTrans( void ) { - - ... - - astIntraReg( "MaxTran", AST__ANY, 1, MaxTran, AST__SIMPIF, - purpose, author, contact ); - - ... - - astIntraReg( "Poly3Tran", 1, 1, Poly3Tran, AST__NOINV, - purpose, author, contact ); - - ... - - astIntraReg( "SqrTran", 2, 2, SqrTran, 0, - purpose, author, contact ); -} -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - SUBROUTINE MYTRANS( STATUS ) - INTEGER STATUS - - INCLUDE 'AST_PAR' - EXTERNAL MAXTRAN, POLY3TRAN, SQRTRAN - - ... - - CALL AST_INTRAREG( 'MaxTran', AST__ANY, 1, MAXTRAN, AST__SIMPIF, - : PURPOSE, AUTHOR, CONTACT, STATUS ) - - ... - - CALL AST_INTRAREG( 'Poly3Tran', 1, 1, POLY3TRAN, AST__NOINV, - : PURPOSE, AUTHOR, CONTACT, STATUS ) - - ... - - CALL AST_INTRAREG( 'SqrTran, 2, 2, SQRTRAN, 0, - : PURPOSE, AUTHOR, CONTACT, STATUS ) - END -\end{terminalv} -\normalsize -f- - -c+ -You can then simply invoke this function wherever necessary. It is, in -fact, particularly important to register all relevant transformation -functions in this way before you attempt to read an Object that might -be (or contain) an IntraMap -(\secref{ss:readingandwritingintramaps}). This is because you may not -know in advance which of these transformation functions the IntraMap -will use, so they must all be available in order to avoid an error. -c- -f+ -You can then simply invoke this routine wherever necessary. It is, in -fact, particularly important to register all relevant transformation -routines in this way before you attempt to read an Object that might -be (or contain) an IntraMap -(\secref{ss:readingandwritingintramaps}). This is because you may not -know in advance which of these transformation routines the IntraMap -will use, so they must all be available in order to avoid an error. -f- - -\cleardoublepage -\section{\label{ss:plots}Producing Graphical Output (Plots)} - -Graphical output from AST is performed though an Object called a Plot, -which is a specialised form of FrameSet. A Plot does not represent the -graphical content itself, but is a route through which plotting -operations, such as drawing lines and curves, are conveyed on to a -plotting surface to appear as visible graphics. - -\subsection{The Plot Model} - -When a Plot is created, it is initialised by providing a FrameSet whose -base Frame (as specified by its Base attribute) is mapped linearly or -logarithmically (as specified by the LogPlot attribues) on to a -\emph{plotting area}. This is a rectangular region in the graphical -coordinate space of the underlying graphics system and becomes the new -base Frame of the Plot. In effect, the Plot becomes attached to the -plotting surface, in rather the same way that a basic FrameSet might be -attached to (say) an image. - -The current Frame of the Plot (derived from the current Frame of the -FrameSet supplied) is used to represent a \emph{physical coordinate -system}. This is the system in which plotting operations are -performed by your program. Every plotting operation is then -transformed through the Mapping which inter-relates the Plot's current -and base Frames in order to appear on the plotting surface. - -An example may help here. Suppose we start with a FrameSet whose base -Frame describes the pixel coordinates of an image and whose current -Frame describes a celestial (equatorial) coordinate system. Let us -assume that these two Frames are inter-related by a Mapping within the -FrameSet which represents a particular sky projection. - -When a Plot is created from this FrameSet, we specify how the pixel -coordinates (the base Frame) maps on to the plotting surface. This -simply corresponds to telling the Plot where we have previously -plotted the image data. If we now use the Plot to plot a line with -latitude zero in our physical coordinate system, as given by the -current Frame, this line would appear as a curve (the equator) on the -plotting surface, correctly registered with the image. - -There are a number of plotting functions provided, which all work in a -similar way. Plotting operations are transformed through the Mapping -which the Plot represents before they appear on the plotting -surface.\footnote{Like any FrameSet, a Plot can be used as a -Mapping. In this case it is the inverse transformation which is used -when plotting (\emph{i.e.}\ that which transforms between the current -and base Frames).} It is possible to draw symbols, lines, axes, -entire grids and more in this way. - -%\subsection{TBW---Creating a Plot} - -\subsection{Plotting Symbols} - -c+ -The simplest form of plotting is to draw symbols (termed -\emph{markers}) at a set of points. This is performed by astMark, -which is supplied with a set of physical coordinates at which to place -the markers: -c- -f+ -The simplest form of plotting is to draw symbols (termed -\emph{markers}) at a set of points. This is performed by AST\_MARK, -which is supplied with a set of physical coordinates at which to place -the markers: -f- - -c+ -\small -\begin{terminalv} -#include "ast.h" -#define NCOORD 2 -#define NMARK 10 -double in[ NCOORD ][ NMARK ]; -int type; - -... - -astMark( plot, NMARK, NCOORD, NMARK, in, type ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INCLUDE 'AST_PAR' - INTEGER NCOORD, NMARK, TYPE, STATUS - DOUBLE PRECISION IN( NMARK, NCOORD ) - - STATUS = 0 - - ... - - CALL AST_MARK( PLOT, NMARK, NCOORD, NMARK, IN, TYPE, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, NMARK specifies how many markers to plot and NCOORD specifies -how many coordinates are being supplied for each -point.\footnote{Remember, the physical coordinate space need not -necessarily be 2-dimensional, even if the plotting surface is.} The -array ``in'' supplies the coordinates and the integer ``type'' -specifies which type of marker to plot. -c- -f+ -Here, NMARK specifies how many markers to plot and NCOORD specifies -how many coordinates are being supplied for each -point.\footnote{Remember, the physical coordinate space need not -necessarily be 2-dimensional, even if the plotting surface is.} The -array IN supplies the coordinates and the integer TYPE specifies which -type of marker to plot. -f- - -\subsection{\label{ss:plottinggeodesics}Plotting Geodesic Curves} - -There is no Plot routine to draw a straight line, because any straight -line in physical coordinates can potentially turn into a curve in -graphical coordinates. We therefore start by considering how to draw -geodesic curves. These are curves which trace the path of shortest -distance between two points in physical coordinates - and are the basic drawing element in a Plot. - -c+ -In many instances, the geodesic will, in fact, be a straight line, but -this depends on the Plot's current Frame. If this represents a -celestial coordinate system, for instance, it will be a great circle -(corresponding with the behaviour of the astDistance function which -defines the metric of the physical coordinate space). The geodesic -will, of course, be transformed into graphics coordinates before being -plotted. A geodesic curve is plotted using astCurve as follows: -c- -f+ -In many instances, the geodesic will, in fact, be a straight line, but -this depends on the Plot's current Frame. If this represents a -celestial coordinate system, for instance, it will be a great circle -(corresponding with the behaviour of the AST\_DISTANCE function which -defines the metric of the physical coordinate space). The geodesic -will, of course, be transformed into graphics coordinates before being -plotted. A geodesic curve is plotted using AST\_CURVE as follows: -f- - -c+ -\small -\begin{terminalv} -double start[ NCOORD ], finish[ NCOORD ]; - -... - -astCurve( plot, start, finish ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - DOUBLE PRECISION START( NCOORD ), FINISH( NCOORD ) - - ... - - CALL AST_CURVE( PLOT, START, FINISH, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, ``start'' and ``finish'' are arrays containing the starting and -finishing coordinates of the curve. The astOffset and astDistance -functions can often be useful for computing these -(\secref{ss:distanceandoffset}). -c- -f+ -Here, START and FINISH are arrays containing the starting and -finishing coordinates of the curve. The AST\_OFFSET and AST\_DISTANCE -routines can often be useful for computing these -(\secref{ss:distanceandoffset}). -f- - -c+ -If you need to draw a series of curves end-to-end (when drawing a -contour line, for example), then a more efficient alternative is to -use astPolyCurve. This has the same effect as a sequence of -invocations of astCurve, but allows you to supply a whole set of -points at one time. astPolyCurve then joins them, in sequence, using -geodesic curves: -c- -f+ -If you need to draw a series of curves end-to-end (when drawing a -contour line, for example), then a more efficient alternative is to -use AST\_POLYCURVE. This has the same effect as a sequence of calls to -AST\_CURVE, but allows you to supply a whole set of points at the same -time. AST\_POLYLINE then joins them, in sequence, using geodesic -curves: -f- - -c+ -\small -\begin{terminalv} -#define NPOINT 100 -double coords[ NCOORD ][ NPOINT ]; - -... - -astPolyCurve( plot, NPOINT, NCOORD, NPOINT, coords ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER NPOINT - DOUBLE PRECISION COORDS( NPOINT, NCOORD ) - - ... - - CALL AST_POLYCURVE( PLOT, NPOINT, NCOORD, NPOINT, COORDS, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, NPOINT specifies how many points are to be joined and NCOORD -specifies how many coordinates are being supplied for each point. The -array ``coords'' supplies the coordinates of the points in the Plot's -physical coordinate system. -c- -f+ -Here, NPOINT specifies how many points are to be joined and NCOORD -specifies how many coordinates are being supplied for each point. The -array COORDS supplies the coordinates of the points in the Plot's -physical coordinate system. -f- - -\subsection{Plotting Curves Parallel to Axes} - -c+ -As there is no Plot function to draw a ``straight line'', drawing axes -and grid lines to represent coordinate systems requires a slightly -different approach. The problem is that for some coordinate systems, -these grid lines will not be geodesics, so astCurve and astPolyCurve -(\secref{ss:plottinggeodesics}) cannot easily be used (you would have -to resort to approximating grid lines by many small elements). Lines -of constant celestial latitude provide an example of this, with the -exception of the equator which is a geodesic. -c- -f+ -As there is no Plot routine to draw a ``straight line'', drawing axes -and grid lines to represent coordinate systems requires a slightly -different approach. The problem is that for some coordinate systems, -these grid lines will not be geodesics, so AST\_CURVE and -AST\_POLYCURVE (\secref{ss:plottinggeodesics}) cannot easily be used -(you would have to resort to approximating grid lines by many small -elements). Lines of constant celestial latitude provide an example of -this, with the exception of the equator which is a geodesic. -f- - -c+ -The astGridLine function allows these curves to be drawn, as follows: -c- -f+ -The AST\_GRIDLINE routine allows these curves to be drawn, as follows: -f- - -c+ -\small -\begin{terminalv} -int axis; -double length; - -... - -astGridLine( plot, axis, start, length ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER AXIS - DOUBLE PRECISION LENGTH - - ... - - CALL AST_GRIDLINE( PLOT, AXIS, START, LENGTH, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, ``axis'' specifies which physical coordinate axis we wish to -draw parallel to. The ``start'' array contains the coordinates of the -start of the curve and ``length'' specifies the distance to draw along -the axis in physical coordinate space. -c- -f+ -Here, AXIS specifies which physical coordinate axis we wish to draw -parallel to. The START array contains the coordinates of the start of -the curve and LENGTH specifies the distance to draw along the axis in -physical coordinate space. -f- - -\subsection{\label{ss:plottinggeneralizedcurves}Plotting Generalized Curves} -We have seen how geodesic curves and grid lines can be drawn. The Plot -class includes another method, -c+ -astGenCurve, -c- -f+ -AST\_GENCURVE, -f- -which allows curves of \emph{any} form to be drawn. The caller supplies a -Mapping which maps offset along the curve\footnote{normalized so that the -start of the curve is at offset 0.0 and the end of the curve is at offset -1.0 - offset need not be linearly related to distance.} into the -corresponding position in the current Frame of the Plot. -c+ -astGenCurve, -c- -f+ -AST\_GENCURVE, -f- -then takes care of Mapping these positions into graphics coordinates. The -choice of exactly which positions along the curve are to be used to -define the curve is also made by -c+ -astGenCurve, -c- -f+ -AST\_GENCURVE, -f- -using an adaptive algorithm which concentrates points around areas where -the curve is bending sharply or is discontinuous in graphics coordinates. - -The IntraMap class may be of particular use in this context since it allows -you to code your own Mappings to do any transformation you choose. - - -\subsection{\label{ss:clipping}Clipping} - -Like many graphics systems, a Plot allows you to \emph{clip} the graphics -you produce. This means that plotting is restricted to certain regions -of the plotting surface so that anything drawn outside these regions -will not appear. All Plots automatically clip at the edges of the -plotting area specified when the Plot is created. This means that -graphics are ultimately restricted to the rectangular region of -plotting space to which you have attached the Plot. - -In addition to this, you may also specify lower and upper limits on -each axis at which clipping should occur. This permits you to further -restrict the plotting region. Moreover, you may attach these clipping -limits to \emph{any} of the Frames in the Plot. This allows you to -place restrictions on where plotting will take place in either the -physical coordinate system, the graphical coordinate system, or in any -other coordinate system which is described by a Frame within the Plot. - -For example, you could plot using equatorial coordinates and set up -clipping limits in galactic coordinates. In general, you could set up -arbitrary clipping regions by adding a new Frame to a Plot (in which -clipping will be performed) and inter-relating this to the other -Frames in a suitable way. - -c+ -Clipping limits are defined using the astClip function, as follows: -c- -f+ -Clipping limits are defined using the AST\_CLIP routine, as follows: -f- - -c+ -\small -\begin{terminalv} -#define NAXES 2 -int iframe; -double lbnd[ NAXES ], ubnd[ NAXES ]; - -... -astClip( plot, iframe, lbnd, ubnd); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - INTEGER IFRAME, NAXES - DOUBLE PRECISION LBND( NAXES ), UBND( NAXES ) - - ... - - CALL AST_CLIP( PLOT, IFRAME, LBND, UBND, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, the ``iframe'' value gives the index of the Frame within the -Plot to which clipping is to be applied, while ``lbnd'' and ``ubnd'' -give the limits on each axis of the selected Frame (NAXES is the -number of axes in this Frame). -c- -f+ -Here, the IFRAME value gives the index of the Frame within the Plot to -which clipping is to be applied, while LBND and UBND give the limits -on each axis of the selected Frame (NAXES is the number of axes in -this Frame). -f- - -c+ -You can remove clipping by giving a value of AST\_\_NOFRAME for ``iframe''. -c- -f+ -You can remove clipping by giving a value of AST\_\_NOFRAME for IFRAME. -f- - -\subsection{Using a Plot as a Mapping} - -All Plots are also Mappings (just like the FrameSets from which they -are derived), so can be used to transform coordinates. - -Like FrameSets, the forward transformation of a Plot will convert -coordinates between the base and current Frames (\emph{i.e.}\ between -graphical and physical coordinates). This would be useful if you were -(say) reading a cursor position in graphical coordinates and needed to -convert this into physical coordinates for display. - -c+ -Conversely, a Plot's inverse transformation converts between its -current and base Frames (\emph{i.e.}\ from physical coordinates to -graphical coordinates). This transformation is applied automatically -whenever plotting operations are carried out by AST functions. It may -also be useful to apply it directly, however, if you wish to perform -additional plotting operations (\emph{e.g.}\ those provided by the -native graphics system) at positions specified in physical -coordinates. -c- -f+ -Conversely, a Plot's inverse transformation converts between its -current and base Frames (\emph{i.e.}\ from physical coordinates to -graphical coordinates). This transformation is applied automatically -whenever plotting operations are carried out by AST routines. It may -also be useful to apply it directly, however, if you wish to perform -additional plotting operations (\emph{e.g.}\ those provided by the -native graphics system) at positions specified in physical -coordinates. -f- - -c+ -There is, however, one important difference between using a FrameSet -and a Plot to transform coordinates, and this is that clipping may be -applied by a Plot (if it has been enabled using -astClip---\secref{ss:clipping}). Any point which lies within the -clipped region of a Plot will, when transformed, yield coordinates -with the value AST\_\_BAD. If you wish to avoid this clipping, you -should extract the relevant Mapping from the Plot (using -astGetMapping) and use this, instead of the Plot, to transform the -coordinates. -c- -f+ -There is, however. one important difference between using a FrameSet -and a Plot to transform coordinates, and this is that clipping may be -applied by a Plot (if it has been enabled using -AST\_CLIP---\secref{ss:clipping}). Any point which lies within the -clipped region of a Plot will, when transformed, yield coordinates -with the value AST\_\_BAD. If you wish to avoid this clipping, you -should extract the relevant Mapping from the Plot (using -AST\_GETMAPPING) and use this, instead of the Plot, to transform the -coordinates. -f- - -\subsection{Using a Plot as a Frame} - -Every Plot is also a Frame, so can be used to obtain the values of -Frame attributes such as a Title, axis Labels, axis Units, -\emph{etc.}, which are typically used when displaying data and/or -coordinates. These attributes are, as for any FrameSet, derived from -the current Frame of the Plot (\secref{ss:framesetasframe}). They are -also used automatically when using the Plot to plot coordinate axes -and coordinate grids (\emph{e.g.}\ for labelling -them---\secref{ss:plottingagrid}). - -c+ -Because the current Frame of a Plot represents physical coordinates, -any Frame operation applied to the Plot will effectively be working in -this coordinate system. For example, the astDistance and astOffset -functions will compute distances and offsets in physical coordinate -space, while astFormat and astNorm will format physical coordinates in -an appropriate way for display. -c- -f+ -Because the current Frame of a Plot represents physical coordinates, -any Frame operation applied to the Plot will effectively be working in -this coordinate system. For example, the AST\_DISTANCE and AST\_OFFSET -routines will compute distances and offsets in physical coordinate -space, and AST\_FORMAT will format physical coordinates in an -appropriate way for display. -f- - -\subsection{\label{ss:validphysicalcoordinates}Regions of Valid Physical Coordinates} - -When points in physical coordinate space are transformed by a Plot -into graphics coordinates for plotting, they may not always yield -valid coordinates, irrespective of any clipping being applied -(\secref{ss:clipping}). To indicate this, the resulting coordinate -values will be set to the value AST\_\_BAD -(\secref{ss:badcoordinates}). - -There are a number of reasons why this may occur, but typically it -will be because physical coordinates only map on to a subset of the -graphics coordinate space. This situation is commonly encountered with -all-sky projections where, typically, the celestial sphere appears, -when plotted, as a distorted shape (\emph{e.g.}\ an ellipse) which -does not entirely fill the graphics space. In some cases, there may -even be multiple regions of valid and invalid physical coordinates. - -When plotting is performed \emph{via} a Plot, graphical output will -only appear in the regions of valid physical coordinates. Nothing will -appear where invalid coordinates occur. Such output is effectively -clipped. If you wish to plot in these areas, you must change -coordinate system and use, say, graphical coordinates to address the -plotting surface directly. - -\subsection{Plotting Borders} - -c+ -The astBorder function is provided to draw a (line) border around your -graphical output. With most graphics systems, this would simply be a -rectangular box around the plotting area. With a Plot, however, this -boundary follows the edge of each region containing valid, unclipped -physical coordinates (\secref{ss:validphysicalcoordinates}). -c- -f+ -The AST\_BORDER routine is provided to draw a (line) border around -your graphical output. With most graphics systems, this would simply -be a rectangular box around the plotting area. With a Plot, however, -this boundary follows the edge of each region containing valid, -unclipped physical coordinates (\secref{ss:validphysicalcoordinates}). -f- - -c+ -This means, for example, that if you were plotting an all-sky -projection, this boundary would outline the perimeter of the celestial -sphere when projected on to your plotting surface. Of course, if there -is no clipping and all physical coordinates are valid, then you will -get the traditional rectangular box. astBorder requires only -a pointer to the Plot: -c- -f+ -This means, for example, that if you were plotting an all-sky -projection, this boundary would outline the perimeter of the celestial -sphere when projected on to your plotting surface. Of course, if there -is no clipping and all physical coordinates are valid, then you will -get the traditional rectangular box. AST\_BORDER requires only a -pointer to the Plot and the usual STATUS argument: -f- - -c+ -\small -\begin{terminalv} -int holes; - -... - -holes = astBorder( plot ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - LOGICAL HOLES - - ... - - HOLES = AST_BORDER( PLOT, STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -It returns a boolean (integer) value to indicate if any invalid or -clipped physical coordinates were found within the plotting area. If -they were, it will draw around the valid unclipped regions and return -a value of one. Otherwise, it will draw a simple rectangular border -and return zero. -c- -f+ -It returns a logical value to indicate if any invalid or clipped -physical coordinates were found within the plotting area. If they -were, it will draw around the valid unclipped regions and return -.TRUE.. Otherwise, it will draw a simple rectangular border and return -.FALSE.. -f- - -\subsection{Plotting Text} - -c+ -Using a Plot to draw text involves supplying a string of text to be -displayed and a position in physical coordinates where the text is to -appear. The position is transformed into graphical coordinates to -determine where the text should appear on the plotting surface. You -must also provide a 2-element ``up'' vector which gives the upward -direction of the text in graphical coordinates. This allows text to be -drawn at any angle. -c- -f+ -Using a Plot to draw text involves supplying a string of text to be -displayed and a position in physical coordinates where the text is to -appear. The position is transformed into graphical coordinates to -determine where the text should appear on the plotting surface. You -must also provide a 2-element UP vector which gives the upward -direction of the text in graphical coordinates. This allows text to be -drawn at any angle. -f- - -c+ -Plotting is performed by astText, for example: -c- -f+ -Plotting is performed by AST\_TEXT, for example: -f- - -c+ -\small -\begin{terminalv} -char text[ 21 ]; -double pos[ NCOORD ]; -float up[ 2 ] = { 0.0f, 1.0f }; - -... - -astText( plot, text, pos, up, "TL" ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CHARACTER * ( 20 ) TEXT - DOUBLE PRECISION POS( NCOORD ) - REAL UP( 2 ) - DATA UP / 0.0, 1.0 / - - ... - - CALL AST_TEXT( PLOT, TEXT, POS, UP, 'TL', STATUS ) -\end{terminalv} -\normalsize -f- - -c+ -Here, ``text'' contains the string to be drawn, ``pos'' is an array of -physical coordinates and ``up'' specifies the upward vector. In this -case, the text will be drawn horizontally. The final argument -specifies the text justification, here indicating that the top left -corner of the text should appear at the position given. -c- -f+ -Here, TEXT contains the string to be drawn, POS is an array of -physical coordinates and UP specifies the upward vector. In this case, -the text will be drawn horizontally. The penultimate argument -specifies the text justification, here indicating that the top left -corner of the text should appear at the position given. -f- - -Further control over the appearance of the text is possible by setting -values for various Plot attributes, for example Colour, Font and Size. -Sub-strings within the displayed text can be given different appearances, -or turned into super-scripts or sub-scripts, by the inclusion of escape -sequences (see section~\secref{ss:escapes}) within the supplied text string. - -\subsection{\label{ss:plottingagrid}Plotting a Grid} - -c+ -The most comprehensive plotting function available is astGrid, which -can be used to draw labelled coordinate axes and, optionally, to -overlay coordinate grids on the plotting area -(Figure~\ref{fig:gridplot}). The routine is straightforward to use, -simply requiring a pointer to the Plot: -c- -f+ -The most comprehensive plotting routine available is AST\_GRID, which -can be used to draw labelled coordinate axes and, optionally, to -overlay coordinate grids on the plotting area -(Figure~\ref{fig:gridplot}). The routine is straightforward to use, -simply requiring a pointer to the Plot and a STATUS argument: -f- - -c+ -\small -\begin{terminalv} -astGrid( plot ); -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} - CALL AST_GRID( PLOT, STATUS ) -\end{terminalv} -\normalsize -f- - -It will draw both linear and curvilinear axes and grids, as required -by the particular Plot. The appearance of the output can be modified -in a wide variety of ways by setting various Plot attributes. -The Label attributes of the current Frame are displayed as the axis -labels in the grid, and the Title attribute as the plot title. Sub-strings -within these strings can be given different appearances, or turned into -super-scripts or sub-scripts, by the inclusion of escape sequences (see -section~\secref{ss:escapes}) within the Label attributes. - -\subsection{\label{ss:escapes}Controlling the Appearance of Sub-strings} -Normally, each string of characters displayed using a Plot will be -plotted so that all characters in the string have the same font size, -colour, \emph{etc.}, specified by the appropriate attributes of the -Plot. However, it is possible to include \emph{escape sequences} within -the text to modify the appearance of sub-strings. Escape sequences can be -used to change, colour, font, size, width, to introduce extra horizontal -space between characters, and to change the base line of characters (thus -allowing super-scripts and sub-scripts to be created). See the entry for -the Escape attribute in \appref{ss:attributedescriptions} for details. - -As an example, if the character string ``\verb+10\%^50+\%s70+0.5+'' is -plotted, it will be displayed as ``$10^{0.5}$'' - that is, with a -super-scripted exponent. The exponent text will be 70\% of the size of -normal text (as determined by the Size attribute), and its baseline will -be raised by 50\% of the height of a normal character. - -Such escape sequences can be used in the strings assigned to textual -attributes of the Plot (such as the axis Labels), and may also be -included in strings plotted using -c+ -astText. -c- -f+ -AST\_TEXT. -f- - -The Format attribute for the SkyAxis class includes the ``g'' option -which will cause escape sequences to be included when formatting -celestial positions so that super-script characters are used as -delimiters for the various fields (a super-script ``h'' for hours, ``m'' -for minutes, \emph{etc}). - -Note, the facility for interpreting escape sequences is only available if -the graphics wrapper functions which provide the interface to the -underlying graphics system support all the functions included in the -\verb+grf.h+ file as of AST V3.2. Older grf interfaces may need to be -extended by the addition of new functions before escape sequences can be -interpretted. - -\subsection{\label{ss:logaxes}Producing Logarithmic Axes} -In certain situations you may wish for one or both of the plotted axes to -be displayed logarithmically rather than linearly. For instance, you may -wish to do this when using a Plot to represent a spectrum of, say, flux -against frequency. In this case, you can cause the frequency axis to be drawn -logarithmically simply by setting the boolean LogPlot attribute for the -frequency axis to a non-zero value. This causes several things to happen: - -\begin{enumerate} - -\item The Mapping between the base Frame of the Plot (which represents -the underlying graphics world coordinate system) and the base Frame of -the FrameSet supplied when the Plot was created, is modified. By -default, this mapping is linear on both axes, but setting LogPlot non-zero -for an axis causes the Mapping to be modified so that it is logarithmic -on the specified axis. This is only possible if the displayed section of -the axis does not include the value zero (otherwise the attempt to set -a new value for LogPlot is ignored,and it retains its default value of -zero). - -\item The major tick marks drawn as part of the annotated coordinate grid -are spaced logarithmically rather than linearly. That is, major axis -values are chosen so that there is a constant ratio between adjacent -tick mark values. This ratio is constrained to be a power of ten. The -minor tick marks are drawn at linearly distributed points between the -adjoining major tick values. Thus if a pair of adjacent major tick values -are drawn at axis values 10.0 and 100.0, minor ticks will be placed at -20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0 and 90.0 (note only 8 minor tick -marks are drawn). - -\item If possible, numerical axis labels are shown as powers of ten. -This depends on the facilities implemented by the graphics wrapper -functions (see the next section). Extra functions were introduced to this -set of wrapper functions at AST V3.2 which enable super-scripts and -sub-scripts to be produced. Some older wrappers may not yet have -implemented these functiosn and this will result in axis labels being -drawn in usual scientific or decimal notation. - -\end{enumerate} - -Whilst the LogPlot attribute can be used to control all three of the above -facilities, it is possible to control them individually as well. The -LogTicks and LogLabel attributes control the behaviour specified in items -2 and 3 above, but the default values for these attributes depend on the -setting of the LogPlot attribute. This means that setting LogPlot -non-zero will swicth all three facilites on, so long as zero values have -not been assigned explicitly to LogTicks or LogLabel. - - -\subsection{\label{ss:choosingagraphicspackage}Choosing a Graphics Package} -The Plot class itself does not include any code for actually drawing on a -graphics device. Instead, it requires a set of functions to be provided -which it uses to draw the required graphics. These include functions -to draw a straight line, draw a text string, \emph{etc}. You may choose -to provide functions from your favorite graphics package, or you can even -write your own! To accomodate variations in the calling interfaces of -different graphics packages, AST defines a standard interface for these -routines. If this interface differs from the interface provided by your -graphics package (which in general it will), then you must write a set of -\emph{wrapper functions}, which provide the interface expected by AST but -which then call functions from your graphics package to provide the -required functionality. AST comes with wrapper functions suitable for -the PGPLOT graphics package (see \xref{SUN/15}{sun15}{}). - -There are two ways of indicating which wrapper functions are to be used by -the Plot class: -\begin{enumerate} - -\item A file containing C functions with pre-defined names can be written -and linked with the application using options of the ast\_link command. -(see \secref{ss:howtobuild} and \appref{ss:commanddescriptions}). AST is -distributed with such a file (called \texttt{grf\_pgplot.c}) which calls PGPLOT -functions to implement the required functionality. This file can be used -as a template for writing your own. -f+ -Currently, it is not possible to write such ``grf modules'' in Fortran. -If you want to use wrapper functions written in Fortran, then you must -use the AST\_GRFSET method as described below. -f- - -\item The -c+ -astGrfSet -c- -f+ -AST\_GRFSET -f- -method of the Plot class can be used to ``register'' -wrapper functions at run-time. This allows an application to switch -between graphics systems if required. Graphics functions registered in -this way do not need to have the pre-defined names used in the link-time -method described above. - -\end{enumerate} - -For details of the interfaces of the wrapper routines, see -c+ -either the \texttt{grf\_pgplot.c} file included in the AST source -distribution, or the reference documentation for the astGrfSet method. -c- -f+ -the reference documentation for the AST\_GRFSET method. -f- - -\cleardoublepage -\section{Compiling and Linking Software that Uses AST} - -A small number of UNIX commands are provided by AST to assist with the -process of building software. A description of these can be found in -\appref{ss:commanddescriptions} and their use is discussed here. Note -that in order to access these commands, the appropriate directory -(normally ``/star/bin'') should be on your PATH.\footnote{If you have -not installed AST in the usual location, then substitute the -appropriate directory in place of ``/star'' wherever it occurs.} - -c+ -\subsection{\label{ss:accessingheaderfile}Accessing the ``ast.h'' Header File} -c- -f+ -\subsection{\label{ss:accessingheaderfile}Accessing AST Include Files} -f- - -c+ -The ``ast.h'' header file defines the external interface to the AST library, -including all constants, function prototypes, macros, \emph{etc.}. This file -should be located using the usual compiler options for finding C -include files, for instance: - -\small -\begin{terminalv} -cc prog.c -I/star/include -o prog -\end{terminalv} -\normalsize - -This is preferable to specifying the file's absolute name within your -software. -c- -f+ - -The include files provided for use with Fortran are: - -\begin{quote} -\begin{description} -\item[AST\_PAR]\mbox{}\\ -Declares the types of all AST functions and defines parameter -constants, except those that identify error values. - -\item[AST\_ERR]\mbox{}\\ -Defines parameter constants to represent the various error values to -which the AST error status may be set when an error occurs -(\secref{ss:errordetection}). -\end{description} -\end{quote} - -References to AST include files should be in upper case. Most modern -Fortran compilers allow the directory to be specified as a command line -option: - -\small -\begin{terminalv} -f77 prog.f -I/star/include -o prog -\end{terminalv} -\normalsize - -If you are using such a compiler then your Fortran source code should, -for instance, include: - -\small -\begin{terminalv} - INCLUDE 'AST_PAR' -\end{terminalv} -\normalsize - -(that is, there is no need to include the directory within the INCLUDE -statement). If your compiler does not provide such an option then your -source code must contain an absolute file name identifying the directory -where the include files reside, for instance: - -\small -\begin{terminalv} - INCLUDE '/star/include/AST_PAR' -\end{terminalv} -\normalsize - -f- - -\subsection{\label{ss:linking}Linking with AST Facilities} - -c+ -C programs which use AST facilities may be linked by including -execution of the command ``ast\_link'' on the compiler command -line. Thus, to compile and link a program called ``prog'', the -following might be used: -c- -f+ -Fortran programs may be linked with AST by including execution of the -command ``ast\_link'' on the compiler command line. Thus, to compile -and link a program called ``prog'', the following might be used: -f- - -c+ -\small -\begin{terminalv} -cc prog.c -L/star/lib `ast_link` -o prog -\end{terminalv} -\normalsize -c- -f+ -\small -\begin{terminalv} -f77 prog.f -L/star/lib `ast_link` -o prog -\end{terminalv} -\normalsize - -On Linux systems you should usually use \verb+g77 -fno-second-underscore+ in -place of \verb+f77+ - see \xref{``Software development on Linux''}{sun212} -{software_development_on_linux} in \xref{SUN/212}{sun212}{}. - -f- - -Note the use of backward quote characters, which cause the -``ast\_link'' command to be executed and its result substituted into -the compiler command. An alternative is to save the output from -``ast\_link'' in (say) a shell variable and use this instead. You may -find this a little faster if you are building software repeatedly -during development. - -Programs which use AST can also be linked in a number of other ways, -depending on the facilities they require. In the example above, we -have used the default method which assumes that the program will not -be generating graphical output, so that no graphics libraries need be -linked. If you need other facilities, then various switches can be -applied to the ``ast\_link'' command in order to control the linking -process. - -For example, if you were producing graphical output using the PGPLOT -graphics package, you could link with the AST/PGPLOT interface by -using the ``$-$pgplot'' switch with ``ast\_link'', as -follows:\footnote{Use the ``$-$pgp'' option instead if you wish to use -the Starlink version of PGPLOT which uses GKS to generate its output.} - -c+ -\small -\begin{terminalv} -cc prog.c -L/star/lib `ast_link -pgplot` -o prog -\end{terminalv} -\normalsize -c- -f+ -\begin{small} -\begin{terminalv} -f77 prog.f -L/star/lib `ast_link -pgplot` -o prog -\end{terminalv} -\end{small} - -again using \verb+g77 -fno-second-underscore+ in place of \verb+f77+ -on Linux systems. - -f- - -See the ``ast\_link'' command description in -\appref{ss:commanddescriptions} for details of the options available. - -\subsection{Building ADAM Applications that Use AST} - -Users of Starlink's \xref{ADAM}{sg4}{} programming environment -\latex{(SG/4)} on UNIX should use the -``\xref{alink}{sun144}{ADAM_link_scripts}'' command -(\xref{SUN/144}{sun144}{}) to compile and link applications and can -access the AST library by including execution of the command -``ast\_link\_adam'' on the command line, as follows: - -c+ -\begin{small} -\begin{terminalv} -alink adamprog.c `ast_link_adam` -\end{terminalv} -\end{small} -c- -f+ -\begin{small} -\begin{terminalv} -alink adamprog.f `ast_link_adam` -\end{terminalv} -\end{small} -f- - -Note the use of backward quote characters. - -By default, AST error messages produced by applications built in this -way will be delivered \emph{via} the Starlink EMS Error Message -Service (\xref{SSN/4}{ssn4}{}) so that error handling by AST is -consistent with the \xref{\emph{inherited -status}}{sun104}{inherited_status} error handling normally used in -Starlink software. - -Switches may be given to the ``ast\_link\_adam'' command (in a similar -way to ``ast\_link''---\secref{ss:linking}) in order to link with -additional AST-related facilities, such as a graphics interface. See -the ``ast\_link\_adam'' command description in -\appref{ss:commanddescriptions} for details of the options available. - -\appendix -\cleardoublepage -\section{\label{ss:classhierarchy}The AST Class Hierarchy} -The following table shows the hierarchy of classes in the AST library. -For a description of each class, you should consult -\appref{ss:classdescriptions}. - -\small -\begin{terminalv} -Object - Base class for all AST Objects - Axis - Store axis information - SkyAxis - Store celestial axis information - Channel - Basic (textual) I/O channel - FitsChan - I/O Channel using FITS header cards - XmlChan - I/O Channel using XML - StcsChan - I/O Channel using IVOA STC-S descriptions - KeyMap - Store a set of key/value pairs - Table - Store a 2-dimensional table of values - Mapping - Inter-relate two coordinate systems - CmpMap - Compound Mapping - DssMap - Map points using Digitised Sky Survey plate solution - Frame - Coordinate system description - CmpFrame - Compound Frame - SpecFluxFrame - Observed value versus spectral position - FluxFrame - Observed value at a given fixed spectral position - FrameSet - Set of inter-related coordinate systems - Plot - Provide facilities for 2D graphical output - Plot3D - Provide facilities for 3D graphical output - Region - Specify areas within a coordinate system - Box - A box region with sides parallel to the axes of a Frame - Circle - A circular or spherical region within a Frame - CmpRegion - A combination of two regions within a single Frame - Ellipse - An elliptical region within a 2-dimensional Frame - Interval - Intervals on one or more axes of a Frame. - NullRegion - A boundless region within a Frame - PointList - A collection of points in a Frame - Polygon - A polygonal region within a 2-dimensional Frame - Prism - An extrusion of a Region into orthogonal dimensions - Stc - Represents an generic instance of an IVOA STC-X description - StcResourceProfile - Represents an an IVOA STC-X ResourceProfile - StcSearchLocation - Represents an an IVOA STC-X SearchLocation - StcCatalogEntryLocation - Represents an an IVOA STC-X CatalogEntryLocation - StcObsDataLocation - Represents an an IVOA STC-X ObsDataLocation - SkyFrame - Celestial coordinate system description - SpecFrame - Spectral coordinate system description - DSBSpecFrame - Dual sideband spectral coordinate system description - TimeFrame - Time coordinate system description - GrismMap - Models the spectral dispersion produced by a grism - IntraMap - Map points using a private transformation function - LutMap - Transform 1-dimensional coordinates using a lookup table - MathMap - Transform coordinates using mathematical expressions - MatrixMap - Map positions by multiplying them by a matrix - NormMap - Normalise coordinates using a supplied Frame - PcdMap - Apply 2-dimensional pincushion/barrel distortion - PermMap - Coordinate permutation Mapping - PolyMap - General N-dimensional polynomial Mapping - ChebyMap - N-dimensional Chebyshev polynomial Mapping - RateMap - Calculates an element of a Mapping's Jacobian matrix - SelectorMap - Locates positions within a set of Regions - ShiftMap - Shifts each axis by a constant amount - SlaMap - Sequence of celestial coordinate conversions - SpecMap - Sequence of spectral coordinate conversions - SphMap - Map 3-d Cartesian to 2-d spherical coordinates - SwitchMap - Encapuslates a set of alternate Mappings - TimeMap - Sequence of time coordinate conversions - TranMap - Combine fwd. and inv. transformations from two Mappings - UnitMap - Unit (null) Mapping - UnitNormMap - Converts a vector to a unit vector plus length - WcsMap - Implement a FITS-WCS sky projection - WinMap - Match windows by scaling and shifting each axis - ZoomMap - Zoom coordinates about the origin -\end{terminalv} -\normalsize - -\cleardoublepage -c+ -\section{\label{ss:functiondescriptions}AST Function Descriptions} -\small -\include{c_routines} -\normalsize -c- -f+ -\section{\label{ss:functiondescriptions}AST Routine Descriptions} -\small -\include{f_routines} -\normalsize -f- - -\cleardoublepage -\section{\label{ss:attributedescriptions}AST Attribute Descriptions} -\small -c+ -\include{c_attribs} -c- -f+ -\include{f_attribs} -f- -\normalsize - -\cleardoublepage -\section{\label{ss:classdescriptions}AST Class Descriptions} -\small -c+ -\include{c_classes} -c- -f+ -\include{f_classes} -f- -\normalsize - -\cleardoublepage -\section{\label{ss:commanddescriptions}UNIX Command Descriptions} -The commands described here are provided for use from the UNIX shell -to assist with developing software which uses AST. To use these -commands, you should ensure that the directory -``/star/bin''\footnote{Or the equivalent directory if AST is installed -in a non-standard location.} is on your PATH. -\small -c+ -\include{c_commands} -c- -f+ -\include{f_commands} -f- -\normalsize - -c+ -\cleardoublepage -\section{\label{ss:memoryfunctions}AST Memory Management and Utility Functions} -AST provides a memory management layer that can be used in place of -system functions such as \texttt{malloc}, \texttt{free}, \texttt{realloc}, -\emph{etc.} The AST replacements for these functions ( \texttt{astMalloc}, -\texttt{astFree} and \texttt{astRealloc}) add extra information to each -allocated memory block that allows AST to check the validity of supplied -pointers. For example, this extra information allows \texttt{astFree} to -detect if the supplied pointer has already been freed, and if so to issue -an appropriate error message. The existence of this extra information is -invisible to outside callers, and stored in a header block located just -before the returned memory block. - -In addition to the standard functions, AST provides other memory management -functions, such as: - -\begin{description} -\item [\texttt{astStore}] - stores data in dynamically allocated memory, allocating -the memory (or adjusting the size of previously allocated memory) to match -the amount of data to be stored. -\item [\texttt{astGrow}] - allocates and expands memory to hold an adjustable-sized array. -\item [\texttt{astAppendString}] - allocates and expands memory to hold a -concatenated string. -\end{description} - -Theses are just a few of the available utilities functions in the AST -memory management layer. Prototypes for all AST memory management -functions are included in the header file ``\texttt{ast.h}''. - -An important restriction on these functions is that pointers created by -other memory management functions, such as the system version of \texttt{malloc} \emph{etc.}, should never supplied to an AST memory management -function. Only pointers created by AST should be used by these functions. - -In addition to memory management functions, AST provides various other -utility functions, such as a basic regular expression facility, and other -string manipulation functions. These are also documented in this appendix. - -The AST memory management layer is implemented on top of the usual \texttt{malloc}, {tt free} and \texttt{realloc} functions. By default these will be -the standard functions provided by . However, the facilities of -the STARMEM package (included in the Starlink Software Collection) can be -used to specify alternative functions to use. This requires that AST be -configured using the ``--with-starmem'' option when it is built. - -The STARMEM package provides a wrapper for the standard malloc -implementation that enables the user to switch malloc schemes at runtime -by setting the STARMEM\_MALLOC environment variable. Currently allowed -values for this variable are: - -\begin{description} -\item [SYSTEM] - standard system malloc/free - the default -\item [DL] - Doug Lea's malloc/free -\item [GC] - Hans-Boehm Garbage Collection -\end{description} - -\small -\include{memory_routines} -\normalsize -c- - -\newpage -\section{\xlabel{FitsWcsCoverage}\label{ss:fitswcscoverage}FITS-WCS Coverage} - -This appendix gives details of the FitsChan class -implementation of the conventions described in the FITS-WCS papers -available at -\url{http://fits.gsfc.nasa.gov/fits_wcs.html}. These conventions are -used only if the Encoding attribute of the FitsChan -has the value ``FITS-WCS'' (whether set explicitly or defaulted). It -should always be possible for a FrameSet to be read -(using the -c+ -astRead -c- -f+ -AST\_READ -f- -function) from a FitsChan containing a header which conforms to these -conventions. However, only those FrameSets which are compatible with the -FITS-WCS model can be \emph{written} to a FitsChan using the -c+ -astWrite -c- -f+ -AST\_WRITE -f- -function. For instance, if the current Frame of a -FrameSet is re-mapped using, say, an arbitrary MathMap -then the FrameSet will no longer be compatible with the FITS-WCS model, -and so will not be written out successfully to a FitsChan. - -The following sub-sections describe the details of the implementation of -each of the first four FITS-WCS papers. Here, the term ``pixel axes'' is -used to refer to the FITS pixel coordinates (i.e. the centre of the -first image pixel has a value 1.0 on each pixel axis); the term ``IWC -axes'' is used to refer to the axes of the Intermediate World Coordinate -system; and the term ``WCS axes'' is used to refer to the axes of the final -physical coordinate system described by the CTYPE\emph{i} keywords. - -\subsection{Paper I - General Linear Coordinates} -When reading a FrameSet from a FitsChan, these conventions are used if the CTYPE\emph{i} keyword -values within the FitsChan do not conform to the conventions described in -later papers, in which case the axes are assumed to be linear. When -writing a FrameSet to a FitsChan, these conventions are used for axes -which are described by a simple Frame (\emph{i.e.} not a -SkyFrame, SpecFrame, \emph{etc.}). - -Table \ref{tab:fitspaper1} describes the use made by AST of each keyword -defined by FITS-WCS paper I. - -\begin{table}[htbp] -\begin{tabular}{|l|p{2.5in}|p{2.5in}|} -\hline -\multicolumn{1}{|c|}{\textbf{Keyword}} & \multicolumn{1}{c|}{\textbf{Read}} -& \multicolumn{1}{c|}{\textbf{Write}} \\ \hline - -\fitskey{WCSAXES\emph{a}}{Ignored.}{Set to the number of axes in the WCS -Frame - only written if different to NAXIS.} - -\fitskey{CRVAL\emph{ia}}{Used to create the pixel to WCS -Mapping.}{Always written (see ``Choice of Reference -Point'' below).} - -\fitskey{CRPIX\emph{ja}}{Used to create the pixel to WCS Mapping.}{Always -written (see ``Choice of Reference Point'' below).} - -\fitskey{CDELT\emph{ia}}{Used to create the pixel to WCS Mapping.}{Only -written if the CDMatrix attribute of the FitsChan is -set to zero.} - -\fitskey{CROTA\emph{i}}{Used to create the pixel to WCS Mapping.}{Only -written in FITS-AIPS and FITS-AIPS++ encodings.} - -\fitskey{CTYPE\emph{ia}}{Used to choose the class and attributes of the -WCS Frame, and to create the pixel to WCS Mapping (note, ``STOKES'' and -``COMPLEX'' axes are treated as unknown linear axes).}{Always written -(see ``Use and Choice of CTYPE keywords'' below).} - -\fitskey{CUNIT\emph{ia}}{Used to set the Units attributes -of the WCS Frame.}{Only written if the Units attribute of the WCS Frame -has been set explicitly. If so, the Units value for each axis is used as -the CUNIT value.} - -\fitskey{PC\emph{i\_j}\emph{a}}{Used to create the pixel to WCS -Mapping.}{Only written if the CDMatrix attribute of the FitsChan is set to -zero.} - -\fitskey{CD\emph{i\_j}\emph{a}}{Used to create the pixel to WCS -Mapping.}{Only written if the CDMatrix attribute of the FitsChan is set to -a non-zero value.} - -\fitskey{PV\emph{i\_ma}}{Ignored for linear axes.}{Not written if the axes -are linear.} - -\fitskey{PS\emph{i\_ma}}{Ignored.}{Not used.} - -\fitskey{WCSNAME\emph{a}}{Used to set the Domain attribute -of the WCS Frame.}{Only written if the Domain attribute of the WCS Frame -has been set explicitly. If so, the Domain value is used as the WCSNAME -value.} - -\fitskey{CRDER\emph{ia}}{Ignored.}{Not used.} - -\fitskey{CSYER\emph{ia}}{Ignored.}{Not used.} - -\hline -\end{tabular} -\vspace{3.mm} -\caption{Use of FITS-WCS Paper I keywords} -\label{tab:fitspaper1} -\end{table} - -\subsubsection{Requirements for a Successful Write Operation} -When writing a FrameSet in which the WCS -Frame is a simple Frame to a FitsChan, -success depends on the Mapping from pixel coordinates -(the base Frame in the FrameSet) to the WCS Frame being linear. The write -operation will fail if this is not the case. - -\subsubsection{Use and Choice of CTYPE\emph{i} keywords} -When reading a FrameSet from a FitsChan the CTYPE\emph{i} values in the FitsChan are used to set the -Symbol attributes of the corresponding WCS Frame. The Label attributes of the WCS Frame are set from -the CNAME\emph{i} keywords, if present in the header. Otherwise they are set -from the CTYPE\emph{i} comments strings in the header, so long as each -axis has a unique non-blank comment. Otherwise, the Label attributes are -set to the CTYPE\emph{i} values. The above procedure is over-ridden if -the axis types conform to the conventions described in paper II or III, -as described below. - -When writing a FrameSet to a FitsChan, each CTYPE\emph{i} value is set to -the value of the Symbol attribute of the corresponding axis in the Frame -being written. If a value has been set explicitly for the axis Label -attribute, it is used as the axis comment (except that any existing -comments in the FitsChan take precedence if the keyword value has not -changed). The above procedure is over-ridden if the Frame is a -SkyFrame or a SpecFrame, in which -case the CTYPE\emph{i} value is derived from the System -attribute of the Frame and the nature of the pixel to WCS Mapping -according to the conventions of papers II and III, as described below. - -\subsubsection{Choice of Reference Point} -When writing a FrameSet to a -FitsChan, the pixel coordinates of the -reference point for linear axes (i.e. the CRPIX\emph{j} values) are -chosen as follows: - -\begin{itemize} -\item If the FrameSet is being written to a FitsChan which previously -contained a set of axis descriptions with the same identifying letter, -then the previous CRVAL\emph{j}values are converted into the coordinate system -of the Frame being written (if possible). These values are then -transformed into the pixel Frame, and the closest integer pixel values -are used as the CRPIX keywords. -\item If the above step could not be performed for any reason, the -central pixel is used as the reference point. This requires the image -dimensions to be present in the FitsChan in the form of a set of -NAXIS\emph{j} keyword values. -\item If both the above two steps failed for any axis, then the pixel -reference position is set to a value of 1.0 on the pixel axis. -\end{itemize} - -The pixel to WCS Mapping is then used to find the corresponding -CRVAL\emph{j}values. - -Again, the above procedure is over-ridden if the Frame is a -SkyFrame or a SpecFrame, in which -case the conventions of papers II and III are used as described below. - - -\subsubsection{Choice of Axis Ordering} -When reading a FrameSet from a -FitsChan, WCS axis $i$ in the current -Frame of the -resulting FrameSet corresponds to axis $i$ in the FITS header. - -When writing a FrameSet to a FitsChan, the axis ordering for the FITS -header is chosen to make the CD\emph{i\_j} or PC\emph{i\_j} matrix -predominately diagonal. This means that the axis numbering in the FITS -header will not necessarily be the same as that in the AST Frame. - -\subsubsection{Alternate Axis Descriptions} -When reading a FrameSet from a -FitsChan which contains alternate axis descriptions, -each complete set of axis descriptions results in a single Frame being added -to the final FrameSet, connected via an appropriate -Mapping to the base pixel Frame. The Ident attribute of the Frame is set to hold the single alphabetical -character which is used to identify the set of axis descriptions within -the FITS header (a single space is used for the primary axis descriptions). - -When writing a FrameSet to a FitsChan, it is assumed that the base Frame -represents pixel coordinates, and the current Frame represents the -primary axis descriptions. If there are any other Frames present in the -FrameSet, an attempt is made to create a complete set of ``alternate'' -set of keywords describing each additional Frame. The first character in -the Ident attribute of the Frame is used as the single character -descriptor to be appended to the keyword, with the proviso that a given -character can only be used once. If a second Frame is found with an Ident -attribute which has already been used, its Ident attribute is ignored and -the next free character is used instead. Note, failure to write a set of -alternate axis descriptions does not result in failure of the entire -write operation: the primary axis descriptions are still written, -together with any other alternate axis descriptions which can be produced -successfully. - -\subsection{Paper II - Celestial Coordinates} -These conventions are used when reading a FrameSet -from a FitsChan containing appropriate CTYPE\emph{i} -values, and when writing a FrameSet in which the WCS Frame -is a SkyFrame. - -Table \ref{tab:fitspaper2} describes the use made by AST of each keyword -whose meaning is defined or extended by FITS-WCS paper II. - -\begin{table}[htbp] -\begin{tabular}{|l|p{2.5in}|p{2.5in}|} -\hline -\multicolumn{1}{|c|}{\textbf{Keyword}} & \multicolumn{1}{c|}{\textbf{Read}} -& \multicolumn{1}{c|}{\textbf{Write}} \\ \hline - -\fitskey{CTYPE\emph{ia}}{All coordinate systems and projection types -listed in paper II are supported (note, ``CUBEFACE'' axes are treated as -unknown linear axes). In addition, "-HPX" (HEALPix) and "-XPH" (polar -HEALPix) are supported.}{Determined by the System attribute -of the SkyFrame and the WcsType attribute of the -WcsMap within the FrameSet.} - -\fitskey{CUNIT\emph{ia}}{Ignored (assumed to be 'degrees').}{Not written.} - -\fitskey{PV\emph{i\_ma}}{Used to create the pixel to WCS Mapping (values -are stored as attributes of a WcsMap within this Mapping).}{Values are -obtained from the WcsMap in the pixel to WCS Mapping.} - -\fitskey{LONPOLE\emph{a}}{Used to create the pixel to WCS Mapping. Also -stored as a PVi\_m attribute for the longitude axis of the WcsMap.}{Only -written if not equal to the default value defined in paper II (see -``Choice of LONPOLE/LATPOLE'' below).} - -\fitskey{LATPOLE\emph{a}}{Used to create the pixel to WCS Mapping. Also -stored as a PV attribute for the longitude axis of the WcsMap.}{Only -written if not equal to the default value defined in paper II (see -``Choice of LONPOLE/LATPOLE'' below).} - -\fitskey{RADESYS\emph{a}}{Used to set the attributes of the SkyFrame. All -values supported except that ecliptic coordinates are currently always -assumed to be FK5.}{Always written. Determined by the System attribute of -the SkyFrame.} - -\fitskey{EQUINOX\emph{a}}{Used to set the Equinox attribute -of the SkyFrame.}{Written if relevant. Determined by the Equinox attribute of -the SkyFrame.} - -\fitskey{EPOCH}{Used to set the Equinox attribute of the SkyFrame.}{Only -written if using FITS-AIPS and FITS-AIPS++ encodings. Determined by the Equinox attribute -of the SkyFrame.} - -\fitskey{MJD-OBS}{Used to set the Epoch attribute of the -SkyFrame. DATE-OBS is used if MJD-OBS is not present. A default value based on -RADESYS and EQUINOX is used if used if DATE-OBS is not present -either.}{Determined by the Epoch attribute of the SkyFrame. Only written -if this attribute has been set to an explicit value (in which case -DATE-OBS is also written).} - -\hline -\end{tabular} -\vspace{3.mm} -\caption{Use of FITS-WCS Paper II keywords} -\label{tab:fitspaper2} -\end{table} - -\subsubsection{Requirements for a Successful Write Operation} -When writing a FrameSet in which the WCS -Frame is a SkyFrame to a -FitsChan, success depends on the following conditions -being met: - -\begin{enumerate} -\item The Mapping from pixel coordinates (the base Frame -in the FrameSet) to the WCS SkyFrame includes a WcsMap. -\item The Mapping prior to the WcsMap (\emph{i.e.} from pixel to IWC) is linear. -\item The Mapping after the WcsMap (\emph{i.e.} from native spherical to -celestial coordinates) is a spherical rotation for the -celestial axes, and linear for any other axes. -\item The TabOK attribute is set to a non-zero positive value in the FitsChan, -and the longitude and latitude axes are separable. In this case the Mapping will -be described by a pair of 1-dimensional look-up tables, using the ``-TAB'' -algorithm described in FITS-WCS paper III. -\end{enumerate} - -If none of the above conditions hold, the write operation will be -unsuccessful. - -\subsubsection{Choice of LONPOLE/LATPOLE} -When writing a FrameSet to a FitsChan, -the choice of LONPOLE and LATPOLE values is determined as follows: - -\begin{enumerate} - -\item If the projection represented by the WcsMap is -azimuthal, then any values set for attributes ``PV\emph{i}\_3'' -and ``PV\emph{i}\_4'' (where ``\emph{i}'' is the index of the longitude axis) -within the WcsMap are used as the LONPOLE and LATPOLE values. Reading a -FrameSet from a FITS-WCS header -results in the original LONPOLE and LATPOLE values being stored within a -WcsMap within the FrameSet. Consequently, if a FrameSet is read from a -FITS-WCS header and it is subsequently written out to a new FITS-WCS -header, the original LONPOLE and LATPOLE values will usually be used in -the new header (the exception being if the WcsMap has been explicitly -modified before being written out again). Any extra rotation of the sky -is absorbed into the CD\emph{i\_j} or PC\emph{i\_j} matrix (this is -possible only if the projection is azimuthal). - -\item If the projection represented by the WcsMap is azimuthal but no -values have been set for the ``PV\emph{i}\_3'' and ``PV\emph{i}\_4'' -attributes within the WcsMap, then the default LONPOLE and LATPOLE values -are used. This results in no LONPOLE or LATPOLE keywords being stored in -the header since default values are never stored. Any extra rotation of -the sky is absorbed into the CD\emph{i\_j} or PC\emph{i\_j} matrix (this -is possible only if the projection is azimuthal). - -\item If the projection represented by the WcsMap is not azimuthal, -then the values of LONPOLE and LATPOLE are found by transforming the -coordinates of the celestial north pole (\emph{i.e} longitude zero, -latitude $+\pi/2$) into native spherical coordinates using the inverse of -the Mapping which follows the WcsMap. - -\end{enumerate} - -\subsubsection{User Defined Fiducial Points} -When reading a FrameSet from a FitsChan, projection parameters -PV\emph{i}\_0, PV\emph{i}\_1 and PV\emph{i}\_2 (for longitude axis -``\emph{i}'') are used to indicate a user-defined fiducial point as -described in section 2.5 of paper II. This results in a shift of IWC -origin being applied \emph{before} the WcsMap which converts -IWC into -native spherical coordinates. The values of these projection parameters, -if supplied, are stored as the corresponding PVi\_m attributes -of the WcsMap. - -When writing a FrameSet to a FitsChan, the PV attributes of the WcsMap -determine the native coordinates of the fiducial point (the fixed -defaults for each projection described in paper II are used if the PV -attributes of the WcsMap have not been assigned a value). The -corresponding celestial coordinates are used as the CRVAL\emph{i} -keywords and the corresponding pixel coordinates as the CRPIX\emph{j} -keywords. - -\subsubsection{Common Non-Standard Features} -A collection of common non-standard features are supported when reading a -FrameSet from a FitsChan, in addition -to those embodied within the -available encodings of the FitsChan class. These are translated into the -equivalent standard features before being used to create a FrameSet. -Note, the reverse operation is never performed: it is not possible to -produce non-standard features when writing a FrameSet to a FitsChan -(other than those embodied in the available encodings of the FitsChan -class). The supported non-standard features include: - -\begin{itemize} -\item EQUINOX keywords with string values equal to a date preceded -by the letter B or J (\emph{e.g.} ``B1995.0''). - -\item EQUINOX or EPOCH keywords with value zero (these are converted to -B1950). - -\item The IRAF ``ZPX'' projection is represented by a -WcsMap with type of -AST\_\_ZPN. Projection parameter values are read from any WAT\emph{i\_nnn} -keywords, and corresponding PVi\_m attributes are set in the -WcsMap. The WAT\emph{i\_nnn} keywords may specify corrections to the basic -ZPN projection by including ``lngcor'' or ``latcor'' terms. These are -supported if they use half cross-terms, in either simple or Chebyshev -representation. - -\item The IRAF ``TNX'' projection is represented by a WcsMap with type of -AST\_\_TPN (a distorted TAN projection retained within the WcsMap class -from an early draft of the FITS-WCS paper II). Projection parameter values -are read from any WAT\emph{i\_nnn} keywords, and corresponding PV -attributes are set in the WcsMap. If the TNX projection cannot be -converted exactly into an AST\_\_TPN projection, ASTWARN keywords are -added to the FitsChan containing a warning message (but only if the -Warnings attribute of the FitsChan is set appropriately). Currently, -TNX projections that use half cross-terms, in either simple or Chebyshev -representation, are supported. - -\item ``QV'' parameters for TAN projections (as produced by -\xref{AUTOASTROM}{sun242}{} -\footnote{\url{http://www.astro.gla.ac.uk/users/norman/star/autoastrom/}} -are renamed to the equivalent ``PV'' parameters. - -\item TAN projections that have associated ``PV'' parameters on the -latitude axis are converted to the corresponding TPN (distorted TAN) -projections. This conversion can be controlled using the PolyTan attribute -of the FitsChan class. - -\end{itemize} - -\subsection{Paper III - Spectral Coordinates} -These conventions are used when reading a FrameSet -from a FitsChan which includes appropriate -CTYPE\emph{i} values, and when writing a FrameSet in which -the WCS Frame is a SpecFrame. - -Table \ref{tab:fitspaper3} describes the use made by AST of each keyword -whose meaning is defined or extended by FITS-WCS paper III. - -\begin{table}[htbp] -\begin{footnotesize} -\begin{tabular}{|l|p{2.5in}|p{2.5in}|} -\hline -\multicolumn{1}{|c|}{\textbf{Keyword}} & \multicolumn{1}{c|}{\textbf{Read}} -& \multicolumn{1}{c|}{\textbf{Write}} \\ \hline - -\fitskey{CTYPE\emph{ia}}{All coordinate systems and projection types -listed in paper III are supported algorithm (the ``-LOG'' algorithm may -also be applied to non-spectral linear axes; the ``-TAB'' algorithm -requires the TabOK attribute to be set in the FitsChan).}{Determined by the System attribute of the -SpecFrame and the nature of the pixel to SpecFrame -Mapping.} - -\fitskey{CUNIT\emph{ia}}{Used to set the Units attribute of -the SpecFrame (note, SpecFrames always have an ``active'' Units attribute -(see astSetActiveUnit).}{Always written.} - -\fitskey{PV\emph{i\_ma}}{Used to create the pixel to WCS Mapping (values -are stored as attributes of a GrismMap).} -{Set from the attributes of the GrismMap, if present, and if set explicitly.} - -\fitskey{SPECSYS\emph{a}}{Used to set the StdOfRest -attribute of the SpecFrame (all systems are supported except CMBDIPOL).} -{Set from the StdOfRest attribute of the SpecFrame, but only if it has been -set explicitly.} - -\fitskey{SSYSOBS\emph{a}}{Ignored.}{Never written.} - -\fitskey{OBSGEO-X/Y/Z}{Used to set the ObsLon and -ObsLat attributes of the Frame (the observers -height above sea level is ignored).}{Set from the ObsLon and ObsLat -attributes of the Frame, if they have been set explicitly (it is -assumed that the observer is at sea level).} - -\fitskey{MJD-AVG}{Used to set the Epoch attributes of -the SpecFrame.}{Set from the Epoch attribute of the SpecFrame, if it has -been set explicitly.} - -\fitskey{SSYSSRC\emph{a}}{Used to set the SourceVRF attribute of the -SpecFrame -(all systems are supported except CMBDIPOL).} {Set from the SourceVRF -attribute of the SpecFrame.} - -\fitskey{ZSOURCE\emph{a}}{Used to set the SourceVel -attribute of the SpecFrame (the SourceVRF attribute -is first set to the system indicated by the SSYSSRC keyword, and the -ZSOURCE value is then converted to an apparent radial velocity and stored -as the SourceVel attribute).} -{Set from the SourceVel attribute of -the SpecFrame, if it has been set explicitly (the SourceVel value is -first converted from apparent radial velocity to redshift).} - -\fitskey{VELOSYS\emph{a}}{Ignored.}{Set from the attributes of the -SpecFrame that define the standard of rest and the observers position.} - -\fitskey{RESTFRQ\emph{a}}{Used to set the RestFreq -attribute of the SpecFrame.}{Set from the RestFreq attribute of the -SpecFrame, but only if the System attribute is not set to -``WAVE'', ``VOPT'', ``ZOPT'' or ``AWAV'', and only if RestFreq has been set -explicitly.} - -\fitskey{RESTWAV\emph{a}}{Used to set the RestFreq -attribute of the SpecFrame (after conversion from wavelength to frequency).} -{Set from the RestFreq attribute of the SpecFrame (after conversion), but only if the -System attribute is set to ``WAVE'', ``VOPT'', ``ZOPT'' or -``AWAV'', and only if RestFreq has been set explicitly.} - -\fitskey{CNAME\emph{ia}}{Used to set the Label attributes of -the WCS Frame keywords.}{Set from the Label attributes of the WCS Frame, -if they have been set explicitly.} -\hline -\end{tabular} -\end{footnotesize} -\vspace{3.mm} -\caption{Use of FITS-WCS Paper III keywords} -\label{tab:fitspaper3} -\end{table} - -\subsubsection{Requirements for a Successful Write Operation} -When writing a FrameSet in which the WCS Frame is a SpecFrame to a -FitsChan, the write operation is successful only if -the Mapping from pixel coordinates (the base Frame -in the FrameSet) to the SpecFrame satisfies one of the following conditions: - -\begin{enumerate} -\item It is linear. -\item It is logarithmic. -\item It is linear if the SpecFrame were to be re-mapped into one of the -other spectral systems supported by FITS-WCS paper III. -\item It contains a GrismMap, and the Mapping before the GrismMap (from -pixel coordinates to grism parameter) is linear, and the Mapping after the -GrismMap is either null or represents a change of spectral system from wavelength (air or -vacuum) to one of the supported spectral systems. -\item The TabOK attribute is set to a non-zero positive value in the FitsChan. -\end{enumerate} - -If none of the above conditions hold, the write operation will be -unsuccessful. Note, if the FitsChan's TabOK attribute is set to a positive -non-zero value then any Mapping that does not meet any of the earlier conditions -will be written out as a look-up table, using the ``-TAB'' algorithm described -in FITS-WCS paper III. If the TabOK attribute is to zero (the default) or -negative in the FitsChan, then the write operation will be unsuccessful unless -one of the eaerlier conditions is met.\footnote{If the -TAB algorithm is used, the -positive value of the TabOK attribute is used as the table version number -(the EXTVER header) in the associated FITS binary table.} - -\subsubsection{Common Non-Standard Features} -The following non-standard features are supported when reading spectral -axes from a FitsChan: - -\begin{itemize} -\item Conversion of ``-WAV'', ``-FRQ'' and ``-VEL'' algorithm codes -(specified in early drafts of paper III) to the corresponding -``-X2P'' form. -\item Conversion of ``RESTFREQ'' to ``RESTFRQ'' -\end{itemize} - -\subsection{Paper IV - Coordinate Distortions} - -This paper proposes that an additional 4 character code be appended to -the end of the CTYPE\emph{i} keyword to specify the nature of any -distortion away from the basic algorithm described by the first 8 -characters of the CTYPE\emph{i} value. Currently AST ignores all such -codes when reading a FrameSet from a FitsChan (except for the ``-SIP'' code -defined by the Spitzer Space Telescope project - see below). This means that -a FrameSet can still be read from such headers, but the Mapping which gives -the WCS position associated with a given pixel position will reflect only -the basic algorithm and will not include the effects of the distortion. - -If such a FrameSet is then written out to a FitsChan, the resulting -CTYPE\emph{i} keywords will include no distortion code. - -\subsubsection{The ``-SIP'' distortion code} - -The Spitzer Space Telescope project -(\url{http://www.spitzer.caltech.edu/}) -has developed its own system for encoding 2-dimensional image distortion -within a FITS header, based on the proposals of paper IV. A description -of this system is available in -\url{http://ssc.spitzer.caltech.edu/postbcd/doc/shupeADASS.pdf}. In this -system, the presence of distortion is indicated by appending the -distortion code ``-SIP'' to the CTYPE\emph{i} keyword values for the -celestial axes. The distortion takes the form of a polynomial function -which is applied to the pixel coordinates, after subtraction of the -CRPIX\emph{j} values. - -This system is a strictly 2 dimensional system. When reading a -FrameSet from a FitsChan which -includes the ``-SIP'' distortion code, AST assumes that it -is only applied to the first 2 WCS axes in a FITS header (i.e. -CTYPE1 and CTYPE2). If the ``-SIP'' distortion code is attached to other -axes, it will be ignored. The distortion itself is represented by a -PolyMap within the resulting FrameSet. - -If a FrameSet is read from a FitsChan which includes ``-SIP'' -distortion, and an attempt is then made to write this FrameSet out to a -FitsChan, the write operation will fail unless the distortion is -insignificant (\emph{i.e.} is so small that the tests for linearity built -into AST are passed). In this case, no distortion code will be appended to -the resulting CTYPE\emph{i} keyword values. - -\newpage -\section{\xlabel{changes_and_new_features}\label{ss:changes}Release Notes} - -\subsection{Changes Introduced in V1.1} - -The following describes the most significant changes which occurred in -the AST library between versions V1.0 and V1.1 (not the most recent -version): - -\begin{enumerate} - -\item A new ``How To\ldots'' section (\secref{ss:howto}) has been -added to this document. It contains simple recipies for performing -commonly-required operations using AST. - -c+ -\item A new astUnformat function has been provided to read formatted -coordinate values for the axes of a Frame -(\secref{ss:unformattingaxisvalues}). In essence, this function is the -inverse of astFormat. It may be used to decode user-supplied formatted -values representing coordinates, turning them into numerical values -for processing. Celestial coordinates may also be read using this -function (\secref{ss:unformattingskyaxisvalues}) and free-format input -is supported. -c- -f+ -\item A new AST\_UNFORMAT function has been provided to read formatted -coordinate values for the axes of a Frame -(\secref{ss:unformattingaxisvalues}). In essence, this function is the -inverse of AST\_FORMAT. It may be used to decode user-supplied -formatted values representing coordinates, turning them into numerical -values for processing. Celestial coordinates may also be read using -this function (\secref{ss:unformattingskyaxisvalues}) and free-format -input is supported. -f- - -\item The Format attribute string used by a SkyFrame when formatting -celestial coordinate values now allows the degrees/hours field to be -omitted, so that celestial coordinates may be given in (\emph{e.g.}) -arc-minutes and/or arc-seconds -(\secref{ss:formattingskyaxisvalues}). As a result, the degrees/hours -field is no longer included by default. A new ``t'' format specifier -has been introduced (see the Format attribute) to allow minutes and/or -seconds of time to be specified if required. - -c+ -\item A new function astMapBox has been introduced. This allows you to -find the extent of a ``bounding box'' which just encloses another box -after it has been transformed by a Mapping. A typical use might be to -calculate the size which an image would have if it were transformed by -the Mapping. -c- -f+ -\item A new routine AST\_MAPBOX has been introduced. This allows you -to find the extent of a ``bounding box'' which just encloses another -box after it has been transformed by a Mapping. A typical use might be -to calculate the size which an image would have if it were transformed -by the Mapping. -f- - -c+ -\item A new class of Object, the IntraMap, has been introduced -(\secref{ss:intramaps}). This is a specialised form of Mapping which -encapsulates a privately-defined coordinate transformation function -(\emph{e.g.}\ written in C) so that it may be used like any other AST -Mapping. This allows you to create Mappings that perform any -conceivable coordinate transformation. -c- -f+ -\item A new class of Object, the IntraMap, has been introduced -(\secref{ss:intramaps}). This is a specialised form of Mapping which -encapsulates a privately-defined coordinate transformation routine -(\emph{e.g.}\ written in Fortran) so that it may be used like any -other AST Mapping. This allows you to create Mappings that perform any -conceivable coordinate transformation. -f- - -\item The internal integrity of a FrameSet is now automatically -preserved whenever changes are made to any attributes which affect the -current Frame (either by setting or clearing their values). This is -accomplished by appropriately re-mapping the current Frame to account -for any change to the coordinate system which it represents -(\secref{ss:framesetintegrity}). - -\item The internal structure of a FrameSet is now automatically tidied -to eliminate redundant nodes whenever any of its Frames is removed or -re-mapped. Automatic simplification of any compound Mappings which -result may also occur. The effect of this change is to prevent the -accumulation of unnecessary structure in FrameSets which are -repeatedly modified. - -c+ -\item Some improvements have been made to the algorithms for -simplifying compound Mappings, as used by astSimplify. -c- -f+ -\item Some improvements have been made to the algorithms for -simplifying compound Mappings, as used by AST\_SIMPLIFY. -f- - -\item The textual representation used for some Objects -(\emph{i.e.}\ when they are written to a Channel) has changed -slightly, but remains compatible with earlier versions of AST. - -c+ -\item Interfaces to the internal functions and macros used by AST for -handling memory and error conditions are now provided \emph{via} the -``ast.h'' header file. This is for the benefit of those writing -(\emph{e.g.}) new graphics interfaces for AST. -c- - -c+ -\item A problem has been fixed which could result when using astRead -to read FITS headers in which the CDELT value is zero. Previously, -this could produce a Mapping whose inverse transformation was not -defined and this could unnecessarily restrict the use to which it -could be put. The problem has been overcome by supplying a suitable -small CDELT value for FITS axes which have only a single pixel. -c- -f+ -\item A problem has been fixed which could result when using AST\_READ -to read FITS headers in which the CDELT value is zero. Previously, -this could produce a Mapping whose inverse transformation was not -defined and this could unnecessarily restrict the use to which it -could be put. The problem has been overcome by supplying a suitable -small CDELT value for FITS axes which have only a single pixel. -f- - -\item A bug has been fixed which could occasionally cause a MatrixMap -to be used with the wrong Invert attribute value when it forms part of -c+ -a compound Mapping which is being simplified using astSimplify. -c- -f+ -a compound Mapping which is being simplified using AST\_SIMPLIFY. -f- - -f+ -\item A bug has been fixed which could cause the AST\_\_BAD parameter -to have an incorrect value on some platforms. -f- - -\item A problem has been fixed which could prevent tick marks being -drawn on a coordinate axis close to a singularity in the coordinate -system. -\end{enumerate} - -\subsection{Changes Introduced in V1.2} - -The following describes the most significant changes which occurred in -the AST library between versions V1.1 and V1.2 (not the most recent -version): - -\begin{enumerate} -c+ -\item A new function, astPolyCurve, has been introduced to allow more -efficient plotting of multiple geodesic curves -(\secref{ss:plottinggeodesics}). -c- -f+ -\item A new routine, AST\_POLYCURVE, has been introduced to allow more -efficient plotting of multiple geodesic curves -(\secref{ss:plottinggeodesics}). -f- - -c+ -\item A new set of functions, astResample$<$X$>$, has been introduced -to perform resampling of gridded data such as images -(\emph{i.e.}\ re-gridding) under the control of a geometrical -transformation specified by a Mapping. -c- -f+ -\item A new set of functions, AST\_RESAMPLE$<$X$>$, has been -introduced to perform resampling of gridded data such as images -(\emph{i.e.}\ re-gridding) under the control of a geometrical -transformation specified by a Mapping. -f- - -\item The command-line options ``$-$pgp'' and ``$-$pgplot'', which -were previously synonymous when used with the ``ast\_link'' and -``ast\_link\_adam'' commands, are no longer synonymous. The option -``$-$pgp'' now causes linking with the Starlink version of PGPLOT -(which uses GKS to generate its output), while ``$-$pgplot'' links -with the standard (or ``native'') version of PGPLOT. - -c+ -\item The function astMapBox has been changed to execute more quickly, -although this has been achieved at the cost of some loss of robustness -when used with difficult Mappings. -c- -f+ -\item The routine AST\_MAPBOX has been changed to execute more -quickly, although this has been achieved at the cost of some loss of -robustness when used with difficult Mappings. -f- - -\item A new value of ``FITS-IRAF'' has been introduced for the -Encoding attribute of a FitsChan. This new encoding provides an -interim solution to the problem of storing coordinate system -information in FITS headers, until the proposed new FITS-WCS standard -becomes stable. - -\item When a FrameSet is created from a set of FITS header cards (by -reading from a FitsChan using a ``foreign'' encoding), the base Frame -of the resulting FrameSet now has its Domain attribute set to -``GRID''. This reflects the fact that this Frame represents FITS data -grid coordinates (equivalent to FITS pixel coordinates---see -\secref{ss:domainconventions}). Previously, this Domain value was not -set. - -c+ -\item astFindFits now ignores trailing spaces in its keyword template. -c- -f+ -\item AST\_FINDFITS now ignores trailing spaces in its keyword template. -f- - -c+ -\item astPutFits now recognises ``D'' and ``d'' as valid exponent -characters in floating point numbers. -c- -f+ -\item AST\_PUTFITS now recognises ``D'' and ``d'' as valid exponent -characters in floating point numbers. -f- - -\item The FitsChan class is now more tolerant of common minor -violations of the FITS standard. - -\item The FitsChan class now incorporates an improved test for the -linearity of Mappings, allowing more reliable conversion of AST data -into FITS (using ``foreign'' FITS encodings). - -c+ -\item Some further improvements have been made to the algorithms for -simplifying compound Mappings, as used by astSimplify. -c- -f+ -\item Some further improvements have been made to the algorithms for -simplifying compound Mappings, as used by AST\_SIMPLIFY. -f- - -\item A new UnitRadius attribute has been added to the SphMap -class. This allows improved simplification of compound Mappings -(CmpMaps) involving SphMaps and typically improves performance when -handling FITS world coordinate information. - -\item A MatrixMap no longer propagates input coordinate values of -AST\_\_BAD automatically to all output coordinates. If certain output -coordinates do not depend on the affected input coordinate(s) because -the relevant matrix elements are zero, then they may now remain valid. - -\item A minor bug has been corrected which could cause certain -projections which involve half the celestial sphere to produce valid -coordinates for the other (unprojected) half of the sphere as well. - -c+ -\item A bug has been fixed which could occasionally cause astConvert -to think that conversion between a CmpFrame and another Frame was -possible when, in fact, it wasn't. -c- -f+ -\item A bug has been fixed which could occasionally cause AST\_CONVERT -to think that conversion between a CmpFrame and another Frame was -possible when, in fact, it wasn't. -f- -\end{enumerate} - -\subsection{Changes Introduced in V1.3} - -The following describes the most significant changes which occurred in -the AST library between versions V1.2 and V1.3 (not the most recent -version): - -\begin{enumerate} -c+ -\item A new set of functions, astResample$<$X$>$, has been introduced to -provide efficient resampling of gridded data, such as spectra and -images, under the control of a geometrical transformation specified by -a Mapping. A variety of sub-pixel interpolation schemes are supported. -c- -f+ -\item A new set of functions, AST\_RESAMPLE$<$X$>$, has been introduced to -provide efficient resampling of gridded data, such as spectra and -images, under the control of a geometrical transformation specified by -a Mapping. A variety of sub-pixel interpolation schemes are supported. -f- - -\item A new class, PcdMap, has been introduced. This is a specialised -form of Mapping which implements 2-dimensional pincushion or barrel -distortion. - -\item A bug has been fixed which could cause a FitsChan to produce too -many digits when formatting floating point values for inclusion in a -FITS header if the numerical value was in the range -0.00099999\ldots -to -0.0001. - -\item A bug has been fixed which could cause a FitsChan to lose the -comment associated with a string value in a FITS header. - -\item A FitsChan now reports an error if it reads a FITS header which -identifies a non-standard sky projection (previously, this was -accepted without error and a Cartesian projection used instead). - -\item A bug has been fixed which could prevent conversion between the -coordinate systems represented by two CmpFrames. This could only occur -if the CmpFrames contained a relatively large number of nested Frames. - -%\item A bug has been fixed which could cause a program to crash if -%FrameSets were nested inside each other (for example, if one FrameSet -%had another FrameSet added to it for use as a Frame or Mapping). The -%problem could only occur if the nested structure was loaded from a data -%c+ -%file (using astRead). -%c- -%f+ -%file (using AST\_READ). -%f- -% -\item Further improvements have been made to the simplification of -compound Mappings, including fixes for several bugs which could cause -indefinite looping or unwanted error messages. - -\item Some memory leaks have been fixed. - -\item A small number of documentation errors have been corrected. -\end{enumerate} - -\subsection{Changes Introduced in V1.4} - -The following describes the most significant changes which have occurred -in the AST library between versions V1.3 and V1.4 (not the most recent -version): - -\begin{enumerate} -c+ -\item A new MathMap class has been introduced. This is a form of -Mapping that allows you to define coordinate transformations in a -flexible and transportable way using arithmetic operations and -mathematical functions similar to those available in C. -c- -f+ -\item A new MathMap class has been introduced. This is a form of -Mapping that allows you to define coordinate transformations in a -flexible and transportable way using arithmetic operations and -mathematical functions similar to those available in Fortran. -f- - -c+ -\item {\bf{WARNING---INCOMPATIBLE CHANGE.}} Transformation functions -used with the IntraMap class (see, for example, astIntraReg) now -require a ``this'' pointer as their first parameter. \textbf{Existing -implementations will not continue to work correctly with this version -of AST unless this parameter is added.} There is no need for existing -software to make use of this pointer, but it must be present. -c- -f+ -\item {\bf{WARNING---INCOMPATIBLE CHANGE.}} Transformation routines -used with the IntraMap class (see, for example, AST\_INTRAREG) now -require a THIS pointer as their first argument. \textbf{Existing -implementations will not continue to work correctly with this version -of AST unless this argument is added.} There is no need for existing -software to make use of this pointer, but it must be present. -f- - -This change has been introduced so that transformation functions can gain -access to IntraMap attributes. - -c+ -\item A new IntraFlag attribute has been added to the IntraMap -class. This allows the transformation functions used by IntraMaps to -adapt to produce the required transformation on a per-IntraMap basis -(\secref{ss:intraflag}). -c- -f+ -\item A new IntraFlag attribute has been added to the IntraMap -class. This allows the transformation routines used by IntraMaps to -adapt to produce the required transformation on a per-IntraMap basis -(\secref{ss:intraflag}). -f- - -\item The Plot attributes MajTickLen and MinTickLen, which control the -length of major and minor tick marks on coordinate axes, may now be -subscripted using an axis number. This allows tick marks of different -lengths to be used on each axis. It also allows tick marks to be -suppressed on one axis only by setting the length to zero. - -\item The value of the Plot attribute NumLab, which controls the -plotting of numerical labels on coordinate axes, no longer has any -effect on whether labelling of a coordinate grid is interior or -exterior (as controlled by the Labelling attribute). - -\item The FitsChan class now provides some support for the -IRAF-specific ``ZPX'' sky projection, which is converted transparently -into the equivalent FITS ``ZPN'' projection (see the description of the -Encoding attribute for details). - -\item The FitsChan class now recognises the coordinate system ``ICRS'' -(International Celestial Reference System) as equivalent to -``FK5''. This is an interim measure and full support for the -(exceedingly small) difference between ICRS and FK5 will be added at a -future release. - -Note that ``ICRS'' is not yet recognised as a coordinate system by other -classes such as SkyFrame, so this change only facilitates the -importation of foreign data. - -\item A bug in the FitsChan class has been fixed which could result in -longitude values being incorrect by 180 degrees when using cylindrical -sky projections, such as the FITS ``CAR'' projection. - -\item A bug in the FitsChan class has been fixed which could result in -the FITS sky projection parameters ProjP(0) to ProjP(9) being -incorrectly named PROJP1 to PROJP10 when written out as FITS cards. - -\item A bug in the FitsChan class has been fixed which could cause -confusion between the FITS-IRAF and FITS-WCS encoding schemes if both -a CD matrix and a PC matrix are erroneously present in a FITS header. - -\item Some minor memory leaks have been fixed. - -\item A small number of documentation errors have been corrected. -\end{enumerate} - -\subsection{Changes Introduced in V1.5} - -The following describes the most significant changes which have -occurred in the AST library between versions V1.4 and V1.5 (not the most -recent version): - -\begin{enumerate} - -\item The FitsChan class has been modified to support the latest draft -FITS WCS standard, described in the two papers ``Representation of world -coordinates in FITS'' (E.W.\,Greisen and M.\,Calabretta, dated 30th -November, 1999), and ``Representation of celestial coordinates in FITS'' -(M.\,Calabretta and E.W.\,Greisen, dated 24th September, 1999). These are -available at -\url{http://www.cv.nrao.edu/fits/documents/wcs/wcs.html}. - -The FITS-WCS encoding now uses these updated conventions. The main -changes are: - -\begin{itemize} -\item Rotation and scaling of pixel axes is now represented by a matrix -of \texttt{CDj\_i} keywords instead of a combination of \texttt{PCjjjiii} and -\texttt{CDELTj} keywords. -\item Projection parameters are now associated with particular axes and -are represented by \texttt{PVi\_m} keywords instead of the \texttt{PROJPm} -keywords. -\item The tangent plane projection (``TAN'') can now include optional -polynomial correction terms. -\item An entire set of keywords must be supplied for each set of secondary -axis descriptions, and each such keyword must finish with a single -character indicating which set it belongs to. This means that keywords -which previously occupied eight characters have been shorten to seven to -leave room for this extra character. Thus \texttt{LONGPOLE} has become \texttt{LONPOLE} and \texttt{RADECSYS} has become \texttt{RADESYS}. -\end{itemize} - -\item Two new encodings have been added to the FitsChan class: -\begin{description} - -\item [FITS-PC] This encoding uses the conventions of the now superseded -FITS WCS paper by E.W.\,Greisen and M.\,Calabretta which used keywords -\texttt{CDELTj} and \texttt{PCjjjiii} to describe axis scaling and rotation. -These are the conventions which were used by the FITS-WCS encoding prior -to version 1.5 of AST. This encoding is provided to allow existing data -which use these conventions to be read. It should not in general be used -to create new data. - -\item [FITS-AIPS] This encoding is based on the conventions described in the -document ``Non-linear Coordinate Systems in AIPS'' by Eric W. Greisen -(revised 9th September, 1994 and available by ftp from fits.cv.nrao.edu -/fits/documents/wcs/aips27.ps.Z). This encoding uses \texttt{CROTAi} and -\texttt{CDELTi} keywords to describe axis rotation and scaling. - -\end{description} - -\item The FitsChan class now provides some support for the IRAF-specific -``TNX'' sky projection, which is converted transparently into the -equivalent FITS ``TAN'' projection (see the description of the Encoding -attribute for details). - -\item FrameSets originally read from a DSS encoded FITS header can now be -written out using the FITS-WCS encoding (a TAN projection with correction -terms will be used) in addition to the DSS encoding. The reverse is also -possible: FrameSets originally read from a FITS-WCS encoded FITS header -and which use a TAN projection can now be written out using the DSS -encoding. - -\item The algorithm used by the FitsChan class to verify that a FrameSet -conforms to the FITS-WCS model has been improved so that FrameSets -including more complex mixtures of parallel and serial Mappings -can be written out using the FITS-WCS encoding. - -\item The FitsChan class has been changed so that long strings included in -the description of an Object can be saved and restored without truncation -when using the NATIVE encoding. Previously, very long Frame titles, -mathematical expressions, \emph{etc.} were truncated if they exceeded the -capacity of a single FITS header card. They are now split over several -header cards so that they can be restored without truncation. Note, this -facility is only available when using NATIVE encoding. - -\item The FitsChan class has a new attribute called Warnings which -can be used to select potentially dangerous conditions under which -warnings should be issued. These conditions include (for instance) -unsupported features within non-standard projections, missing keywords -for which default values will be used, \emph{etc}. - -\item The WcsMap class has been changed to support the changes made to the -FITS-WCS encoding in the FitsChan class: -\begin{itemize} -\item Projection parameters are now associated with a particular axis and -are specified using a new set of attributes called PVj\_m. Here, ``j'' is -the index of an axis of WcsMap, and ``m'' is the index of the projection -parameter. -\item The old attributes ProjP(0) to ProjP(9) are still available but are -now deprecated in favour of the new PVj\_m attributes. They are interpreted -as aliases for PV(axlat)\_0 to PV(axlat)\_9, where ``axlat'' is the index of -the latitude axis. -\item The GLS projection projection has been renamed as SFL, but the -AST\_\_GLS type has been retained as an alias for AST\_\_SFL. -\end{itemize} - -\end{enumerate} - -\subsection{Changes Introduced in V1.6} - -The following describes the most significant changes which have -occurred in the AST library between versions V1.5 and V1.6: - -\begin{enumerate} - -c+ -\item The C interface to several methods (astTranN, astMark and -astPolyCurve) have been changed to make them easier to call from C++. -Parameters which previously had type ``double (*)[]'' have been changed -to the simpler ``double *''. Using the old types may result in non-fatal -compiler warnings, but should not change the behaviour of the methods. -c- - -\item A bug has been fixed in the Plot class which could cause groups -of tick marks to be skipped when using very small gaps. - -\item A bug has been fixed in the Plot class which could cause axes to be -labeled outside the visible window, resulting in no axes being visible. - -\item The FITS-WCS encoding used by the FitsChan class now includes the -WCSNAME keyword. When creating a FrameSet from FITS headers, the values of -the WCSNAME keywords are now used as the Domain names for the corresponding -Frames in the returned FrameSet. When writing a FrameSet to a FITS header -the Domain names of each Frame are stored in WCSNAME keywords in the -header. - -\item The FITS-WCS encoding used by the FitsChan class now attempts to -retain the identification letter associated with multiple axis -descriptions. When reading a FrameSet from a FITS header, the identification -letter is stored in the Ident attribute for each Frame. When writing a -FrameSet to a FITS header, the identification letter is read from the -Ident attribute of each Frame. The letter to associate with each Frame -can be changed by assigning a new value to the Frame's Ident attribute. - -\item The FITS-WCS, FITS-PC, FITS-IRAF and FITS-AIPS encodings used by the -FitsChan class now create a SkyFrame with the System attribute set to -``Unknown'' if the CTYPE keywords in the supplied header refers to an -unknown celestial coordinate system. Previously, a Frame was used instead -of a SkyFrame. - -\item The FITS-WCS, FITS-PC, FITS-IRAF and FITS-AIPS encodings used by the -FitsChan class no longer report an error if the FITS header contains no -CTYPE keywords. It is assumed that a missing CTYPE keyword implies that -the world coordinate system is linear and identically equal to -``intermediate world coordinates''. - -\item The new value ``noctype'' is now recognized by the Warnings attribute -of the FitsChan class. This value causes warnings to be issued if CTYPE -keywords are missing from foreign encodings. - -\item A new attribute called AllWarnings has been added to the FitsChan -class. This is a read-only, space separated list of all the known condition -names which can be specified in the Warnings attribute. - -\item The FitsChan class now attempts to assigns a Title to each Frame in -a FrameSet read using a foreign encoding. The Title is based on the Domain -name of the Frame. If the Frame has no Domain name, the default Title -supplied by the Frame class is retained. - -\item The FitsChan class uses the comments associated with CTYPE -keywords as axis labels when reading a foreign encoding. This behaviour -has been modified so that the default labels provided by the Frame class -are retained (instead of using the CTYPE comments) if any of the CTYPE -comments are identical. - -\item A new ``interpolation'' scheme identified by the symbolic constant -AST\_\_BLOCKAVE has been added to the AST\_RESAMPLE$<$X$>$ set of -functions. The new scheme calculates each output pixel value by finding -the mean of the input pixels in a box centred on the output pixel. - -\item The SkyFrame class can now be used to represent an arbitrary spherical -coordinate system by setting its System attribute to ``Unknown''. - -\item The indices of the latitude and longitude axes of a SkyFrame can -now be found using new read-only attributes LatAxis and LonAxis. The -effects of any axis permutation is taken into account. - -\item A new attribute called Ident has been added to the Object class. -This serves the same purpose as the existing ID attribute, but (unlike ID) -its value is transferred to the new Object when a copy is made. - -\item A bug has been fixed which could prevent complex CmpFrames -behaving correctly (for instance, resulting in the failure of attempts -to find a Mapping between a CmpFrame and itself). - -\end{enumerate} - -\subsection{Changes Introduced in V1.7} - -The following describes the most significant changes which have -occurred in the AST library between versions V1.6 and V1.7: - -\begin{enumerate} - -\item The Frame class has a new method called -f+ -AST\_ANGLE -f- -c+ -astAngle -c- -which returns the angle subtended by two points at a third point within a -2 or 3 dimensional Frame. - -\item The Frame class has a new method called -f+ -AST\_OFFSET2 -f- -c+ -astOffset2 -c- -which calculates a position which is offset away from a given starting -point by a specified distance along a geodesic curve which passes -through the starting point at a given position angle. It can only be used -with 2-dimensional Frames. - -\item The Frame class has a new method called -f+ -AST\_AXDISTANCE -f- -c+ -astAxDistance -c- -which returns the increment between two supplied axis values. For -axes belonging to SkyFrames, the returned value is normalized into -the range $\pm\pi$. - -\item The Frame class has a new method called -f+ -AST\_AXOFFSET -f- -c+ -astAxOffset -c- -which returns an axis value a given increment away from a specified axis -value. For axes belonging to SkyFrames, the returned value is normalized into -the range $\pm\pi$ (for latitude axes) or zero to $2\pi$ (for longitude -axes). - -\item The Plot class has a new method called -f+ -AST\_GENCURVE -f- -c+ -astGenCurve -c- -which allows generalised user-defined curves to be drawn. The curve is -defined by a user-supplied Mapping which maps distance along the curve -into the corresponding position in the current Frame of the Plot. The new -method then maps these current Frame position into graphics coordinates, -taking care of any non-linearities or discontinuities in the mapping. - -\item The Plot class has a new method called -f+ -AST\_GRFSET -f- -c+ -astGrfSet -c- -which allows the underlying primitive graphics functions to be selected -at run-time. Previously, the functions used by the Plot class to produce -graphics could only be selected at link-time, using the options of the -ast\_link command. The new Plot method allows an application to over-ride -the functions established at link-time, by specifying alternative -primitive graphics routines. In addition, the two new Plot methods -f+ -AST\_GRFPUSH and AST\_GRFPOP -f- -c+ -astGrfPush and astGrfPop -c- -allow the current graphics routines to be saved and restore on a -first-in-last-out stack, allowing temporary changes to be made to the set -of registered graphics routines. - -\item The DrawAxes attribute of the Plot class can now be specified -independantly for each axis, by appending the axis index to the -end of the attribute name. - -\item A bug has been fixed in the Plot class which could result in axis -labels being drawn on inappropriate edges of the plotting box when using -``interior'' labelling. - -\item A bug has been fixed in the IntraMap class which could cause IntraMaps -to be corrupted after transforming any points. - -\item Bugs have been fixed in the FitsChan class which could cause -inappropriate ordering of headers within a FitsChan when writing or -reading objects using NATIVE encodings. - -\item A bug has been fixed in the FitsChan class which could cause the -celestial longitude of a pixel to be estimated incorrectly by 180 degrees -if the reference point is at either the north or the south pole. - -\end{enumerate} - - -\subsection{Changes Introduced in V1.8-2} - -The following describes the most significant changes which have -occurred in the AST library between versions V1.7 and V1.8-2: - -\begin{enumerate} - -\item The SkyFrame class has a new attribute called NegLon which allows - longitude values to be displayed in the range $-\pi$ to $+\pi$, instead - of the usual range zero to $2.\pi$. - -\item Some new -c+ -functions (astAngle, astAxAngle, astResolve, astOffset2, astAxOffset, -astAxDistance) -c- -f+ -routines (AST\_ANGLE, AST\_AXANGLE, AST\_RESOLVE, AST\_OFFSET2, AST\_AXOFFSET, -AST\_AXDISTANCE) -f- -have been added to the Frame class to allow navigation of the coordinate space -to be performed without needing to know the underlying geometry -of the co-ordinate system (for instance, whether it is Cartesian or -spherical). - -Note, version 1.8-1 contained many of these facilities, but -some have been changed in version 1.8-2. Particularly, positions angles -are now referred to the second Frame axis for \emph{all} classes of Frames -(including SkyFrames), and the -c+ -astBear function has been replaced by astAxAngle. -c- -f+ -AST\_BEAR routine has been replaced by AST\_AXANGLE. -f- - -\end{enumerate} - -\subsection{Changes Introduced in V1.8-3} - -The following describes the most significant changes which -occurred in the AST library between versions V1.8-2 and V1.8-3: - -\begin{enumerate} - -\item A new method called astDecompose has been added to the Mapping class -which enables pointers to be obtained to the component parts of CmpMap and -CmpFrame objects. - -\item Functions within proj.c and wcstrig.c have been renamed to avoid name -clashes with functions in more recent versions of Mark Calabretta's wcslib -library. - -\end{enumerate} - -\subsection{Changes Introduced in V1.8-4} - -The following describes the most significant changes which -occurred in the AST library between versions V1.8-3 and V1.8-4: - -\begin{enumerate} - -\item The FitsChan class has a new attribute called DefB1950 which can be -used to select the default reference frame and equinox to be used if -a FitsChan with foreign encoding contains no indication of the -reference frame or equinox. - -\item A bug has been fixed in the FitsChan class which could prevent -astWrite from creating a set of FITS headers from an otherwise valid -FrameSet, when when using FITS-AIPS encoding. - -\item A bug has been fixed in the FitsChan class which could cause -astRead to mis-interpret the FITS CROTA keyword when using FITS-AIPS -encoding. - -\end{enumerate} - -\subsection{Changes Introduced in V1.8-5} - -The following describes the most significant changes which -occurred in the AST library between versions V1.8-4 and V1.8-5: - -\begin{enumerate} - -\item The Plot class defines new graphical elements Axis1, Axis2, -Grid1, Grid2, NumLabs1, NumLabs2, TextLab1, TextLab2, Ticks1 and Ticks2. -These allow graphical attributes (colour, width, etc) to be set for each -axis individually. Previously, graphical attributes could only be set for -both axes together, using graphical elements Axes, Grid, NumLabs, -TextLabs and Ticks. - -\end{enumerate} - - -\subsection{Changes Introduced in V1.8-7} - -The following describes the most significant changes which -occurred in the AST library between versions V1.8-5 and V1.8-7: - -\begin{enumerate} - -\item A new attribute called CarLin has been added to the FitsChan class -which controls the way CAR projections are handled when reading a -FrameSet from a non-native FITS header. Some FITS writers use a CAR -projection to represent a simple linear transformation between pixel -coordinates and celestial sky coordinates. This is not consistent with -the definition of the CAR projection in the draft FITS-WCS standard, which -requires the resultant Mapping to include a 3D rotation from native -spherical coordinates to celestial spherical coordinates, thus making the -Mapping non-linear. Setting CarLin to 1 forces -c+ -astRead -c- -f+ -AST\_READ -f- -to ignore the FITS-WCS standard and treat any CAR projections as simple -linear Mappings from pixel coordinates to celestial coordinates. - -\item A bug has been fixed which could result in axis Format attributes -set by the user being ignored under certain circumstances. - -\item A bug in the way tick marks positions are selected in the Plot class -has been fixed. This bug could result in extra ticks marks being displayed at -inappropriate positions. This bug manifested itself, for instance, if the -Mapping represented by the Plot was a simple Cartesian to Polar Mapping. -In this example, the bug caused tick marks to be drawn at negative radius -values. - -\item A bug has been fixed which could prevent attribute settings from -being read correctly by -c+ -astSet, -c- -f+ -AST\_SET, -f- -etc., on certain platforms (MacOS, for instance). - -\end{enumerate} - -\subsection{Changes Introduced in V1.8-8} - -The following describes the most significant changes which -occurred in the AST library between versions V1.8-7 and V1.8-8: - -\begin{enumerate} - -\item A bug has been fixed in the FitsChan class which could cause -problems when creating a FrameSet from a FITS header containing WCS -information stored in the form of Digitised Digitised Sky Survey (DSS) -keywords. These problems only occurred for DSS fields in the southern -hemisphere, and resulted in pixel positions being mapped to sky positions -close to the corresponding \emph{northern} hemispshere field. - -\item A new method called -c+ -astBoundingBox -c- -f+ -AST\_BOUNDINGBOX -f- -has been added to the Plot class. This method returns the bounding box of -the previous graphical output produced by a Plot method. - -\item A new attribute called Invisible has been added to the Plot class -which suppresses the graphical output normally produced by Plot methods. -All the calculations needed to produce the normal output are still -performed however, and so the bounding box returned by the new -c+ -astBoundingBox -c- -f+ -AST\_BOUNDINGBOX -f- -method is still usable. - -\item Bugs have been fixed related to the appearance of graphical output -produced by the Plot class. These bugs were to do with the way in which -graphical elements relating to a specific axis (e.g. \texttt{Colour(axis1)}, etc.) -interacted with the corresponding generic element (e.g. -\texttt{Colour(axes)}, etc.). - -\end{enumerate} - - -\subsection{Changes Introduced in V1.8-13} - -The following describes the most significant changes which occurred -in the AST library between versions V1.8-8 and V1.8-13: - -\begin{enumerate} - -\item The FitsChan class has been modified so that LONPOLE keywords -c+ -are only produced by astWrite when necessary. For zenithal projections such as -TAN, the LONPOLE keyword can always take its default value and so is -not included in the FITS header produced by astWrite. -c- -f+ -are only produced by AST\_WRITE when necessary. For zenithal projections such as -TAN, the LONPOLE keyword can always take its default value and so is -not included in the FITS header produced by AST\_WRITE -f- -Previously, the unnecessary production of a LONPOLE keyword could prevent -FrameSets being written out using encodings which do not support the -LONPOLE keyword (such as FITS-IRAF). - -\item The FitsChan class has been modified to retain leading and trailing -spaces within COMMENT cards. - -\item The FitsChan class has been modified to only use CTYPE comments as -axis labels if all non-celestial axes have unique non-blank comments -(otherwise the CTYPE keyword values are used as labels). - -\item The FitsChan class has been modified so that it does not append a -trailing ``Z'' character to the end of DATE-OBS keyword values. - -\item The FitsChan class has been modified to use latest list of FITS-WCS -projections, as described in the FITS-WCS paper II, ``Representations of -celestial coordinates in FITS'' (Calabretta \& Greisen, draft dated 23 -April 2002). Support has been retained for the polynomial correction -terms which previous drafts have allowed to be associated with TAN -projections. - -\item The WcsMap class has additional projection types of AST\_\_TPN -(which implements a distorted TAN projection) and AST\_\_SZP. The AST\_\_TAN -projection type now represents a simple TAN projection and has no -associated projection parameters. In addition, the usage of projection -parameters has been brought into line with the the FITS-WCS paper II. - -\item The WcsMap class has been modified so that a ``get'' operation on a -projection parameter attribute will return the default value defined in the -FITS-WCS paper II if no value has been set for the attribute. Previously, a -value of AST\_\_BAD was returned in such a situation. - -\item The Frame class has new attributes Top(axis) and Bottom(axis) which -allow a ``plottable range'' to be specified for each Frame axis. The grid -c+ -produced by the astGrid method will not extend beyond these limits. -c- -f+ -produced by the AST\_GRID routine will not extend beyond these limits. -f- - -\end{enumerate} - -\subsection{Changes Introduced in V2.0} - -Note, Frame descriptions created using AST V2.0 will not be readable by -applications linked with earlier versions of AST. This applies to Frame -descriptions created using: -\begin{itemize} -\item the Channel class -\item the FitsChan class if the NATIVE Encoding is used -c+ -\item the astShow function -c- -f+ -\item the AST\_SHOW routine. -f- -\end{itemize} - -Applications must be re-linked with AST V2.0 in order to be able to read -Frame descriptions created by AST v2.0. - -The following describes the most significant changes which have -occurred in the AST library between versions V1.8-13 and V2.0 (the -current version): - -\begin{enumerate} - -\item The default value for the Domain attribute provided by the CmpFrame -class has been changed from ``CMP'' to a string formed by concatenating -the Domain attributes of the two component Frames, separated by a minus -sign. If both component Domains are blank, then the old default of -``CMP'' is retained for the CmpFrame Domain. - -\item The implementation of the -c+ -astWrite function -c- -f+ -AST\_WRITE routine -f- -within the FitsChan class has been modified. It will now attempt to -produce a set of FITS header cards to describe a FrameSet even if the -number of axes in the Current Frames is greater than the number in the -Base Frame (that is, if there are more WCS axes than pixel axes). This -has always been possible with NATIVE encoding, but has not previously -been possible for foreign encodings. The WCSAXES keyword is used to store -the number of WCS axes in the FITS header. - -\item Another change to the -c+ -astWrite function -c- -f+ -AST\_WRITE routine -f- -within the FitsChan class is that the ordering of ``foreign'' axes -(\emph{i.e.} CTYPE keywords) is now chosen to make the CD (or PC) matrix -as diagonal as possible - any element of axis transposition is removed by -this re-ordering as recommended in FITS-WCS paper I. Previously the -ordering was determined by the order of the axes in the Current Frame of -the supplied FrameSet. This change does not affect NATIVE encoding. - -\item Support for spectral coordinate systems has been introduced -throught the addition of two new classes, SpecFrame and SpecMap. -The SpecFrame is a 1-dimensional Frame which can be used to describe -positions within an electromagnetic spectrum in various systems -(wavelength, frequency, various forms of velocity,~\emph{etc.}) and referred -to various standards of rest (topocentric, geocentric, heliocentric -LSRK,~\emph{etc.}). The SpecMap is a Mapping which can transform spectral -axis values between these various systems and standards of rest. Note, -FitsChans which have a foreign encoding (\emph{i.e.} any encoding other -than NATIVE) are not yet able to read or write these new classes. - -\item Facilities have been added to the Frame class which allow -differences in axis units to be taken into account when finding a Mapping -between two Frames. In previous versions of AST, the Unit attribute was a -purely descriptive item intended only for human readers - changing the -value of Unit made no difference to the behaviour of the Frame. As of -version 2.0, the Unit attribute can influence the nature of the Mappings -between Frames. For instance, if the -c+ -astFindrame or astConvert -c- -f+ -AST\_FINDRAME or AST\_CONVERT -f- -method is used to find the Mapping between an Axis with Unit set to ``m'' -and another Axis with Unit set to ``km'', then the method will return a -ZoomMap which introduces a scaling factor of 0.001 between the two axes. -These facilities assume that units are specified following the rules -included in FITS-WCS paper I (\emph{Representation of World -Coordinates in FITS}, Greisen \& Calabretta). - -In order to minimise the risk of breaking existing software, the default -behaviour for simple Frames is to ignore the Unit attribute (\emph{i.e.} -to retain the previous behaviour). However, the new Frame method -c+ -astSetActiveUnit -c- -f+ -AST\_SETACTIVEUNIT -f- -may be used to ``activate'' (or deactivate) the new facilities within a -specific Frame. Note, the new SpecFrame class is different to the simple -Frame class in that the new facilities for handling units are always active -within a SpecFrame. - -\item The System and Epoch attributes fo the SkyFrame class have been -moved to the parent Frame class. This enables all sub-classes of Frame -(such as the new SpecFrame class) to share these attributes, and to provide -suitable options for each class. - -\item The Frame class has a new attribute called AlignSystem, which allows -control over the alignment process performed by the methods -c+ -astFindFrame and astConvert. -c- -f+ -AST\_FINDFRAME and AST\_CONVERT. -f- - - -\item The CmpFrame class has been modified so that attributes of a -component Frame can be accessed without needing to extract the Frame first. -To do this, append an axis index to the end of the attribute name. For -instance, if a CmpFrame contains a SpecFrame and a SkyFrame (in that order), -then the StdOfRest attribute of the SpecFrame can be referred to as the -``StdOfRest(1)'' attribute of the CmpFrame. Likewise, the Equinox attribute -of the SkyFrame can be accessed as the ``Equinox(2)'' (or equivalently -``Equinox(3)'') attribute of the CmpFrame. The ``System(1)'' attribute of the -CmpFrame will refer to the System attribute of the SpecFrame, whereas the -``System(2)'' and ``System(3)'' attributes of the CmpFrame will refer to the -System attribute of the SkyFrame (the ``System'' attribute without an axis -specifier will refer to the System attribute of the CmpFrame as a whole, -since System is an attribute of all Frames, and a CmpFrame is a Frame and -so has its own System value which is independant of the System attributes -of its component Frames). - -\item The algorithms used by the Plot class for determining when to omit -overlapping axis labels, and the abbreviation of redundant leading fields -within sexagesimal axis labels, have been improved to avoid some anomolous -behaviour in previous versions. - -\item The curve drawing algorithm used by the Plot class has been -modified to reduce the chance of it ``missing'' small curve sections, -such as may be produced if a grid line cuts across the plot very close to -a corner. Previously, these missed sections could sometimes result in -axis labels being omitted. - -\item A new function -c+ -(astVersion) -c- -f+ -(AST\_VERSION) -f- -has been added to return the version of the AST library in use. - -\item Bugs have been fixed in the Plot class which caused serious problems -when plotting high precision data. These problems could range from the -omission of some tick marks to complete failure to produce a plot. - -\end{enumerate} - -Programs which are statically linked will need to be re-linked in -order to take advantage of these new facilities. - - -\subsection{Changes Introduced in V3.0} - -The following describes the most significant changes which -occurred in the AST library between versions V2.0 and V3.0: - -\begin{enumerate} - -\item Many changes have been made in the FitsChan class in order to bring -the FITS-WCS encoding into line with the current versions of the FITS-WCS -papers (see -\url{http://www.atnf.csiro.au/people/mcalabre/WCS/}): - -\begin{itemize} - -\item The rotation and scaling of the pixel axes may now be specified using -either CD\emph{i\_j} keywords, or PC\emph{i\_j} and CDELTj keywords. A new attribute -called CDMatrix has been added to the FitsChan class to indicate which -set of keywords should be used when writing a FrameSet to a FITS-WCS -header. - -\item The FITS-WCS encoding now supports most of the conventions -described in FITS-WCS paper III for the description of spectral -coordinates. The exceptions are that the SSYSOBS keyword is not -supported, and WCS stored in tabular form (as indicated by the ``-TAB'' -algorithm code) is not supported. - - -\item User-specified fiducial points for WCS projections are now -supported by FitsChans which use FITS-WCS encoding. This use keywords -PVi\_0, PVi\_1 and PVi\_2 for the longitude axis. - -\item When reading a FITS-WCS header, a FitsChan will now use keywords PVi\_3 -and PVi\_4 for the longitude axis (if present) in preference to any LONPOLE -and LATPOLE keywords which may be present. When writing a FITS-WCS header, -both forms are written out. - -\item The number of WCS axes is stored in the WCSAXES keyword if its value -would be different to that of the NAXIS keyword. - -\item Helio-ecliptic coordinates are now supported by FitsChans which use -FITS-WCS encoding. This uses CTYPE codes ``HLON'' and ``HLAT''. The -resulting SkyFrame will have a System value of ``HELIOECLIPTIC'', and all -the usual facilities, such as conversion to other celestial systems, are -available. - -\item The FITS-WCS encoding now supports most of the conventions -described in FITS-WCS paper III for the description of spectral -coordinates. The exceptions are that the SSYSOBS keyword is not -supported, and WCS stored in tabular form (as indicated by the ``-TAB'' -algorithm code) is not supported. - -\item When reading a FITS-WCS header, a FitsChan will now ignore any -distortion codes which are present in CTYPE keywords. Here, a ``distortion -code'' is the final group of four characters in a CTYPE value of the -form ``xxxx-yyy-zzz'', as described in FITS-WCS paper IV. The exception -to this is that the ``-SIP'' distortion code (as used by the Spitzer -Space Telescope project - see -\url{http://ssc.spitzer.caltech.edu/postbcd/doc/shupeADASS.pdf}) is -interpreted correctly and results in a PolyMap being used to represent -the distortion in the resulting FrameSet. Note, ``-SIP'' distortion codes -can only be read, not written. A FrameSet which uses a PolyMap will not -in general be able to be written out to a FitsChan using any foreign -encoding (although NATIVE encoding can of course be used). - -\item The Warnings attribute of the FitsChan class now accepts values -``BadVal'' (which gives warnings about conversion errors when reading -FITS keyword values), ``Distortion'' (which gives warnings about -unsupported distortion codes within CTYPE values), and ``BadMat'' (which -gives a warning if the rotation/scaling matrix cannot be inverted). - -\item When writing a FrameSet to a FitsChan which uses a non-Native -encoding, the comment associated with any card already in the FitsChan -will be retained if the keyword value being written is the same as the -keyword value already in the FitsChan. - -\item A FrameSet which uses the non-FITS projection type AST\_\_TPN (a TAN -projection with polynomial distortion terms) can now be written to a -FitsChan if the Encoding attribute is set to FITS-WCS. The standard -``-TAN'' code is used within the CTYPE values, and the distortion -coefficients are encoded in keywords of the form `` QVi\_ma'', which are -directly analogous to the standard ``PVi\_ma'' projection parameter keywords. -Thus a FITS reader which does not recognise the QV keywords will still -be able to read the header, but the distortion will be ignored. - -\item The default value for DefB1950 attribute now depends on the value -of the Encoding attribute. - -\item A new appendix has been added to SUN/210 and SUN/211 giving details -of the implementation provided by the FitsChan class of the -conventions contained in the first four FITS-WCS papers. -\end{itemize} - -\item The SkyFrame class now supports two new coordinate systems ``ICRS'' -and ``HELIOECLIPTIC''. The default for the System attribute for SkyFrames -has been changed from ``FK5'' to ``ICRS''. - -\item The -c+ -astRate -c- -f+ -AST\_RATE -f- -function has been added which allows an estimate to be made of the rate of -change of a Mapping output with respect to one of the Mapping inputs. - -\item All attribute names for Frames of any class may now include an optional -axis specifier. This includes those attributes which describe a property -of the whole Frame. For instance, the Domain attribute may now be -specified as ``Domain(1)'' in addition to the simpler ``Domain''. In cases -such as this, where the attribute describes a property of the whole -Frame, axis specifiers will usually be ignored. The exception is that a -CmpFrame will use the presence of an axis specifier to indicate that the -attribute name relates to the primary Frame containing the specified -axis, rather than to the CmpFrame as a whole. - -\item A new subclass of Mapping, the PolyMap, has been added which -performs a general N-dimensional polynomial mapping. - -\item A new subclass of Mapping, the GrismMap, has been added which -models the spectral dispersion produced by a grating, prism or grism. - -\item A new subclass of Mapping, the ShiftMap, has been added which adds -constant values onto all coordinates (this is equivalent to a WinMap -with unit scaling on all axes). - -\item Minor bugs have been fixed within the Plot class to do with the choice -and placement of numerical axis labels. - -\item The SphMap class has a new attribute called PolarLong which gives the -longitude value to be returned when a Cartesian position corresponding to -either the north or south pole is transformed into spherical coordinates. - -\item The WcsMap class now assigns a longitude of zero to output -celestial coordinates which have a latitude of plus or minus 90 degrees. - -\item The NatLat and NatLon attributes of the WcsMap class have been -changed so that they now return the fixed native coordinates of the -projection reference point, rather than the native coordinates of the -user-defined fiducial point. - -\item Notation has been changed in both the WcsMap and FitsChan classes to -reflect the convention used in the FITS-WCS papers that index ``i'' refers -to a world coordinate axis, and index ``j'' refers to a pixel axis. - -\item Changes have been made to several Mapping classes in order to allow -the -c+ -astSimplify -c- -f+ -AST\_SIMPLIFY -f- -function to make simplifications in a CmpMap which previously were not -possible. - -\item The SlaMap class has been extended by the addition of conversions -between FK5 and ICRS coordinates, and between FK5 and helio-ecliptic coordinates. - -\item The SpecMap class has been changed to use the equation for the -refractive index of air as given in the current version of FITS-WCS paper -III. Also, the forward and inverse transformations between frequency and -air-wavelength have been made more compatible by using an iterative -procedure to calculate the inverse. - -\end{enumerate} - -\subsection{Changes Introduced in V3.1} - -The following describes the most significant changes which have -occurred in the AST library between versions V3.0 and V3.1 (the -current version): - -\begin{enumerate} -\item Addition of a new class called XmlChan - a Channel which -reads and writes AST objects in the form of XML. -\item A bug has been fixed in the Plot class which could cause incorrect -graphical attributes to be used for various parts of the plot if either -axis has no tick marks (i.e. if both major and minor tick marks have zero -length). -\end{enumerate} - -Programs which are statically linked will need to be re-linked in -order to take advantage of these new facilities. - - -\subsection{Changes Introduced in V3.2} - -The following describes the most significant changes which have -occurred in the AST library between versions V3.1 and V3.2: - -\begin{enumerate} - -\item A new -c+ -function astPutCards -c- -f+ -routine AST\_PUTCARDS -f- -has been added to the FitsChan class. This allows multiple concatenated header -cards to be stored in a FitsChan in a single call, providing an alternative to -the existing -c+ -astPutCards function. -c- -f+ -AST\_PUTCARDS routine. -f- - -\item Some signficant changes have been made to the simplification of Mappings - which should resultin a greater degree of simplication taking place.Some - bugs have also been fixed which could result in an infinite loop being - entered when attempting to simplify certain Mappings. - -\item The FitsChan class now translates the spectral algorithm codes -``-WAV'', ``-FRQ'' and ``-VEL'' (specified in early drafts of paper III) to -the corresponding ``-X2P'' form when reading a spectral axis description -from a set of FITS header cards. - -\item A bug has been fixed in the FitsChan class which could cause -keywords associated with alternate axis descriptions to be mis-interpreted. - -\item The Plot class now provides facilities for modifying the appearance -of sub-strings within text strings such as axis labels, titles, \emph{etc}, -by producing super-scripts, sub-scripts, changing the font colour, size, -\emph{etc}. See attribute Escape. - -\item The default value of the Tol attribute of the Plot class has been -changed from 0.001 to 0.01. This should not usually cause any significant -visible change to the plot, but should make the plotting faster. You may -need to set a lower value for Tol if you are producing a particularly -large plot. - -\item The algorithm for finding the default value for the Gap attribute -has been changed. This attribute specifies the gap between major axis -values in an annotated grid drawn by the Plot class. The change in -algorithm may cause the default value to be different to previous versions -in cirtain circumstances. - -\item Some bugs have been fixed in the Plot class which could cause the -system to hang for a long time while drawing certain all-sky grids -(notable some of the FITS Quad-cube projections). - -\item The SkyAxis class has extended the Format attribute by the addition -of the ``g'' option. this option is similar to the older ``l'' option in that -it results in characters (``h'', ``m'', ``s'', \emph{etc}) being used as -delimiters between the sexagesimal fields of the celestial position. The -difference is that the ``g'' option includes graphics escape sequences -in the returned formatted string which result in the field delimiter -characters being drawn as super-scripts when plotted as numerical axis values -by a Plot. - -\item The Plot class has been extended to include facilities for producing -logarithmic axes. See attributes LogPlot, LogTicks, LogGap and LogLabel. - -\item New functions astGCap and astGScales have been added to the interface -defined by file \verb+grf.h+. The ast\_link command has been modified so -that the \verb+-mygrf+ switch loads dummy versions of the new grf -functions. This means that applications should continue to build without -any change. However, the facilities for interpreting escape sequences -within strings drawn by the Plot class will not be available unless the -new grf functions are implemented. If you choose to implement them, you -should modify your linking procedure to use the \verb+-grf+ switch in -place of the older \verb+-mygrf+ switch. See the description of the ast\_link -command for details of the new switches. Also note that the astGQch -function, whilst included in verb+grf.h+ in pervious versions of AST, was -not actually called. As of this version of AST, calls are made to the -astGQch function, and so any bugs in the implementation of astGQch may -cause spurious behaviour when plotting text strings. - -\item A new 'static' method called astEscapes has been added which is used -to control and enquire whether astGetC and astFormat will strip any graphical -escape sequences which may be present out of the returned value. - -\item New attribute XmlPrefix has been added to the XmlChan class. It -allows XML written by the XmlChan class to include an explicit namespace -prefix on each element. - -\item New attribute XmlFormat has been added to the XmlChan class. It -specifies the format in which AST objects should be written. - -\item A new class of Mapping, the TranMap, has been introduced. A TranMap -takes its forward transformation from an existing Mapping, and its inverse -transformation from another existing Mapping. - -\item A bug has been fixed in WcsMap which caused error reports to -include erroneous axis numbers when referring to missing parameter values. - -\end{enumerate} - -\subsection{Changes Introduced in V3.3} - -The following describes the most significant changes which have -occurred in the AST library between versions V3.2 and V3.3: - -\begin{enumerate} - -\item Options have been added to the SkyFrame class which allows the -origin -of celestial coordinates to be moved to any specified point. See the new -attributes SkyRef, SkyRefIs, SkyRefP and AlignOffset. - -\item An option has been added to the FitsChan class which allows extra -Frames representing cartesian projection plane coordinates (``intermediate -world coordinates'' in the parlance of FITS-WCS) to be created when -reading -WCS information from a foreign FITS header. This option is controlled by -a new attribute called Iwc. - -\item The FitsChan class which been modified to interpret FITS-WCS CAR -projection headers correctly if the longitude reference pixel (CRPIX) is -very large. - -\item The FITS-AIPS++ encoding in the FitsChan class now recognised -spectral axes if they conform to the AIPS convention in which the -spectral axis is descirbed by a CTYPE keyword od the form "AAAA-BBB" -where ``AAAA'' is one of FREQ, VELO or FELO, and ``BBB'' is one of LSR, LSD, -HEL or OBS. Such spectral axes can be both read and written. - -\item The FitsChan class now has a FITS-AIPS++ encoding which represents -WCS information using FITS header cards recognised by the AIPS++ project. -Support for spectral axes is identical to the FITS-AIPS encoding. - -\item The organisation of the AST distribution and the commands for -building it have been changed. Whereas AST used to be built and installed -with \verb+./mk build; ./mk install+, it now builds using the more standard -idiom \verb+./configure; make; make install+. The installation location is -controlled by the \verb+--prefix+ argument to ./configure (as is usual -for other packages which use this scheme). Note that the INSTALL environment -variable now has a \emph{different} meaning to that which it had -before, and it should generally be \emph{unset}. Also, there is no need to -set the SYSTEM variable. - -\item Shared libraries are now installed in the same directory as the -static libraries. In addition, links to sharable libraries are installed -with names which include version information, and ``libtool libraries'' -are also installed (see -\url{http://www.gnu.org/software/libtool/manual.html}). - -\item The \verb+ast_dev+ script has been removed. Instead, the location of -the AST include files should be specified using the -I option when -compiling. - -f+ -\item The names of the installed AST include files have been changed to -upper case. -f- - -\end{enumerate} - - -\subsection{Changes Introduced in V3.4} - -The following describes the most significant changes which have -occurred in the AST library between versions V3.3 and V3.4: - -\begin{enumerate} - -\item The Mapping class has a new method -c+ -(astLinearApprox) -c- -f+ -(AST\_LINEARAPPROX) -f- -which calculates the co-efficients of a linear approximation to a Mapping. - -\item The Format attribute for simple Frames and SkyFrames has been extended. -It has always been possible, in both classes, to specify a precision by -including a dot in the Format value followed by an integer (\emph{e.g.} -``\verb+dms.1+'' for a SkyFrame, or ``\verb+%.10g+'' for a simple Frame). -The precision can now also be specified using an asterisk in place of the -integer (\emph{e.g.} ``\verb+dms.*+'' or ``\verb+%.*g+''). This causes the -precision to be derived on the basis of the Digits attribute value. - -\item The Plot class has been changed so that the default value used for the -Digits attribute is chosen to be the smallest value which results in no -pair of adjacent labels being identical. For instance, if an annotated -grid is being drawn describing a SkyFrame, and the Format(1) value is set -to ``\verb+hms.*g+'' (the ``g'' causes field delimiters to be drawn as -superscripts), and the Digits(1) value is unset, then the seconds field -will have a number of decimal places which results in no pair of labels -being identical. - -\item Addition of a new class classed DSBSpecFrame. This is a -sub-class of SpecFrame which can be used to describe spectral axes -associated with dual sideband spectral data. - -\item The FitsChan class will now read headers which use the old ``-GLS'' -projection code, converting them to the corresponding modern ``-SFL'' code, -provided that the celestial axes are not rotated. - -\item The FitsChan class has a new Encoding, ``FITS-CLASS'', which allows -the reading and writing of FITS headers using the conventions of the CLASS -package - see -\url{http://www.iram.fr/IRAMFR/GILDAS/doc/html/class-html/class.html}). - -\end{enumerate} - - -\subsection{Changes Introduced in V3.5} - -The following describes the most significant changes which have -occurred in the AST library between versions V3.4 and V3.5: - -\begin{enumerate} - -\item AST now provides facilities for representing regions of various -shapes within a coordinate system. The Region class provides general -facilities which are independent of the specific shape of region being -used. Various sub-classes of Region are also now available which provide -means of creating Regions of specific shape. Facilities provided by the -Region class include testing points to see if they are inside the -Region, testing two Regions for overlap, transforming Regions from one -coordinate system to another \emph{etc}. - -\item A new class of 1-dimensional Frame called FluxFrame has been added which -can be used to describe various systems for describing ovserved value at a -single fixed spectral position. - -\item A new class of 2-dimensional Frame called SpecFluxFrame has been added which -can be used to describe a 2-d frame spanned by a spectral position axis -and and an observed value axis. - -\item A new class of Mapping called RateMap has been added. A RateMap encapsulates -a previously created Mapping. The inputs of the RateMap correspond to the -inputs of the encapsulated Mapping. All RateMaps have just a single -output which correspond to the rate of change of a specified output of -the encapsulated Mapping with respect to a specified input. - -\item The SkyFrame class now supports a value of ``J2000'' for System. -This system is an equatorial system based on the mean dynamical equator and -equinox at J2000, and differs slightly from an FK5(J2000) system. - -\item A new class called KeyMap has been added. A KeyMap can be used to -store a collection of vector or scalar values or Objects, indexed by a -character string rather than an integer. - -\item The parameter list for the -c+ -astRate -c- -f+ -AST\_RATE -f- -method of the Mapping class has been modified. It no longer returns a second -derivative estimate. Existing code which uses this method will need to be -changed. - -\item Methods -c+ -(astSetFits) -c- -f+ -(AST\_SETFITS) -f- -have been added to the FitsChan class to allow values for named -keywords to be changed or added. - -\end{enumerate} - - -\subsection{Changes Introduced in V3.6} - -The following describes the most significant changes which -occurred in the AST library between versions V3.5 and V3.6: - -\begin{enumerate} - -\item If the Format attribute associated with an axis of a SkyFrame -starts with a percent character (``\verb+%+''), then axis values are -now formatted and unformatted as a decimal radians value, using the -Format syntax of a simple Frame. - -\item The Plot class has a new attribute called Clip which controls the -clipping performed by AST at the plot boundary. - -\item The keys used to label components of the PolyMap structure when a -PolyMap is written out through a Channel have been changed. The new keys -are shorter than the old keys and so can written succesfully to a FitsChan. -The new PolyMap class always writes new styles keys but can read either -old or new style keys. Consequently, PolyMap dumps written by this -version of AST cannot be read by older versions of AST. - -\item A mimimal cut down subset of the C version of SLALIB is now -included with the AST distribution and built as part of building AST. -This means that it is no longer necessary to have SLALIB installed -separately at your site. The SLALIB code included with AST is distrubuted -under the GPL. The default behaviour of the ast\_link script is now to -link with this internal slalib subset. However, the ``-csla'' option can -still be used to force linking with an external full C SLALIB library. -A new option ``-fsla'' has been introduced which forces linking with the -external full Fortran SLALIB library. - -\end{enumerate} - -\subsection{Changes Introduced in V3.7} - -The following describes the most significant changes which -occurred in the AST library between versions V3.6 and V3.7: - -\begin{enumerate} - -\item Support for time coordinate systems has been introduced -throught the addition of two new classes, TimeFrame and TimeMap. -The TimeFrame is a 1-dimensional Frame which can be used to describe -moments in time (either absolute or relative) in various systems (MJD, -Julian Epoch, \emph{etc.}) and referred to various time scales (TAI, UTC, -UT1, GMST, \emph{etc}). The TimeMap is a Mapping which can transform time -values between these various systems and time scales. Note, -FitsChans which have a foreign encoding (\emph{i.e.} any encoding other -than NATIVE) are not able to read or write these new classes. - -\end{enumerate} - - -\subsection{Changes Introduced in V4.0} - -The following describes the most significant changes which -occurred in the AST library between versions V3.7 and V4.0: - -\begin{enumerate} - -\item Experimental support for reading IVOA Space-Time-Coordinates (STC-X) -descriptions using the XmlChan class has been added. Support is included -for a subset of V1.20 of the draft STC specification. - -\item A new set of methods (AST\_REBIN/astRebin) has been added to -the Mapping class. These are flux-conserving alternatives to the existing -AST\_RESAMPLE/astResample methods. - -\end{enumerate} - - -\subsection{Changes Introduced in V4.1} - -The following describes the most significant changes which -occurred in the AST library between versions V4.0 and V4.1: - -\begin{enumerate} - -\item A new control flag has been added to the AST\_RESAMPLE/astResample -functions which produces approximate flux conservation. - -\item New constants AST\_\_SOMB and AST\_\_SOMBCOS have been added to -c+ -ast.h. These specify kernels for astResample and astRebin -c- -f+ -AST\_PAR. These specify kernels for AST\_RESAMPLE and AST\_REBIN -f- -based on the ``Sombrero'' function ( $2*J1(x)/x$ where $J1(x)$ is the -first order Bessel function of the first kind). - -\item The SkyFrame class now supports a System value of AZEL corresponding -to horizon (azimuth/elevation) coordinates. - -\item The FitsChan class allows the non-standard strings ``AZ--'' and -``EL--'' to be used as axis types in FITS-WCS CTYPE keyword values. - -\item The Frame class now has attributes ObsLon and ObsLat to specify -the geodetic longitude and latitude of the observer. - -\item The ClockLon and ClockLat attributes have been removed from the -TimeFrame class. Likewise, the GeoLon and GeoLat attributes have been -removed from the SpecFrame class. Both classes now use the ObsLon and -ObsLat attributes of the parent Frame class instead. However, the old -attribute names can be used as synonyms for ObsLat and ObsLon. Also, -dumps created using the old scheme can be read succesfully by AST V4.1 -and converted to the new form. - -\item A new -c+ -function astMapSplit -c- -f+ -routine AST\_MAPSPLIT -f- -has been added to the Mapping class. This splits a Mapping into two component -Mappings which, when combined in parallel, are equivalent to the original -Mapping. - -\item The default value for the SkyRefIs attribute has been changed from -``Origin'' to ``Ignored''. This means that if you want to use a SkyFrame -to represent offsets from some origin position, you must now set the -SkyRefIs attribute explicitly to either ``Pole'' or ``Origin'', in -addition to assigning the required origin position to the SkyRef attribute. - -\end{enumerate} - -\subsection{Changes Introduced in V4.2} - -The following describes the most significant changes which -occurred in the AST library between versions V4.1 and V4.2: - -\begin{enumerate} - -\item The SideBand attribute of the DSBSpecFrame class can now take the -option ``LO'' in addition to ``USB'' and ``LSB''. The new option causes the -DSBSpecFrame to represent the offset from the local oscillator frequency, -rather than either of the two sidebands. - -\item The FitsChan class has been changed so that it writes out a VELOSYS -keyword when creating a FITS-WCS encoding (VELOSYS indicates the topocentric -apparent velocity of the standard of rest). FitsChan also strips out VELOSYS -keywords when reading a FrameSet from a FITS-WCS encoding. - -\item The FitsChan class has a new method called -c+ -astRetainFits -c- -f+ -AST\_RETAINFITS -f- -that indicates that the current card in the FitsChan should not be -stripped out of the FitsChan when an AST Object is read from the FitsChan. -Unless this method is used, all cards that were involved in the creation -of the AST Object will be stripped from the FitsChan afte a read operation. - -\item A problem with unaligned memory access that could cause bus errors on -Solaris has been fixed. - -\item A new read-only attribute called ObjSize has been added to the base -Object Class. This gives the number of bytes of memory occupied by the -Object. Note, this is the size of the internal in-memory representation of -the Object, not the size of the textual representation produced by -writing the Object out through a Channel. - -\item A new function -c+ -astTune -c- -f+ -AST\_TUNE -f- -has been added which can be used to get and set global AST tuning -parameters. At the moment there are only two such parameter, both of -which are concerned with memory management within AST. - -\item A new method called -c+ -astTranGrid -c- -f+ -AST\_TRANGRID -f- -has been added to the Mapping class. This method creates a regular -grid of points covering a rectangular region within the input space of a -Mapping, and then transforms this set of points into the output space of the -Mapping, using a piecewise-continuous linear approximation to the Mapping -if appropriate in order to achive higher speed. - -\item A new subclass of Mapping has been added called SwitchMap. A -SwitchMap represents several alternate Mappings, each of which is used to -transforms input positions within a different region of the input -coordinate space. - -\item A new subclass of Mapping has been added called SelectorMap. A -SelectorMap tests each input position to see if it falls within one of -several Regions. If it does, the index of the Region containing the -input position is returned as the Mapping output. - -\item The behaviour of the -c+ -astConvert -c- -f+ -AST\_CONVERT -f- -method when trying to align a CmpFrame with another Frame has been -modified. If no conversion between positions in the Frame and CmpFrame -can be found, an attempt is now made to find a conversion between the -Frame and one of two component Frames contained within the CmpFrame. Thus -is should now be possible to align a SkyFrame with a CmpFrame containing a -SkyFrame and a SpecFrame (for instance). The returned Mapping produces bad -values for the extra axes (i.e. for the SpecFrame axis in the above example). - -\item The ``ast\_link\_adam'' and ``ast\_link'' scripts now ignore the -\verb+-fsla+ and \verb+-csla+ options, and always link against the -minimal cut-down version of SLALIB distributed as part of AST. - -\end{enumerate} - -\subsection{Changes Introduced in V4.3} - -The following describes the most significant changes which occurred in the -AST library between versions V4.2 and V4.3: - -\begin{enumerate} - -\item The -c+ -astGetFitsS -c- -f+ -AST\_GETFITSS -f- -function now strips trailing white space from the returned string, if the -original string contains 8 or fewer characters - -\item The SpecFrame class has a new attribute called SourceSys that specified -whether the SourceVel attribute (which specifies the rest frame of the -source) should be accessed as an apparent radial velocity or a redshift. -Note, any existing software that assumes that SourceVel always represents -a velocity in km/s should be changed to allow for the possibility of -SourceVel representing a redshift value. - -\end{enumerate} - - -\subsection{Changes Introduced in V4.4} - -The following describes the most significant changes which occurred in -the AST library between versions V4.3 and V4.4: - -\begin{enumerate} - -\item The -c+ -astFindFrame -c- -f+ -AST\_FINDFRAME -f- -function can now be used to search a CmpFrame for an instance of a more -specialised class of Frame (SkyFrame, TimeFrame, SpecFrame, DSBSpecFrame -or FluxFrame). That is, if an instance of one of these classes is used as -the ``template'' when calling -c+ -astFindFrame, -c- -f+ -AST\_FINDFRAME, -f- -and the ``target'' being searched is a CmpFrame (or a FrameSet in which the -current Frame is a CmpFrame), then the component Frames within the CmpFrame -will be searched for an instance of the supplied template Frame, and, if -found, a suitable Mapping (which will include a PermMap to select the -required axes from the CmpFrame) will be returned by -c+ -astFindFrame. -c- -f+ -AST\_FINDFRAME. -f- -Note, for this to work, the MaxAxes and MinAxes attributes of the template -Frame must be set so that they cover a range that includes the number of axes -in the target CmpFrame. - -\item The SkyFrame, SpecFrame, DSBSpecFrame, TimeFrame and FluxFrame classes -now allow the MaxAxes and MinAxes attributes to be set freely to any value. -In previous versions of AST, any attempt to change the value of MinAxes -or MaxAxes was ignored, resulting in them always taking the default values. - -\item The DSBSpecFrame class has a new attribute called AlignSB that -specifies whether or not to take account of the SideBand attributes when -aligning two DSBSpecFrames using -c+ -astConvert. -c- -f+ -AST\_CONVERT. -f- - -\item The Frame class has a new attribute called Dut1 that can be used to -store a value for the difference between the UT1 and UTC timescales at -the epoch referred to by the Frame. - -\item The number of digits used to format the Frame attributes ObsLat and -ObsLon has been increased. - -\item The use of the SkyFrame attribute AlignOffset has been changed. This -attribute is used to control how two SkyFrames are aligned by -c+ -astConvert. -c- -f+ -AST\_CONVERT. -f- -If the template and target SkyFrames both have a non-zero value for -AlignOffset, then alignment occurs between the offset coordinate systems -(that is, a UnitMap will always be used to align the two SkyFrames). - -\item The Plot class has a new attribute called ForceExterior that can be -used to force exterior (rather than interior) tick marks to be produced. -By default, exterior ticks are only produced if this would result in -more than 3 tick marks being drawn. - -\item The TimeFrame class now supports conversion between angle based -timescales such as UT1 and atomic based timescales such as UTC. - -\end{enumerate} - -\subsection{Changes Introduced in V4.5} - -The following describes the most significant changes that -occurred in the AST library between versions V4.4 and V4.5: - -\begin{enumerate} - - - -\item All FITS-CLASS headers are now created with a frequency axis. If the -FrameSet supplied to -c+ -astWrite -c- -f+ -AST\_WRITE -f- -contains a velocity axis (or any other form -of spectral axis) it will be converted to an equivalent frequency axis -before being used to create the FITS-CLASS header. - -\item The value stored in the FITS-CLASS keyword ``VELO-LSR'' has been changed -from the velocity of the source to the velocity of the reference channel. - -\item Addition of a new method call -c+ -astPurgeWCS -c- -f+ -AST\_PURGEWCS -f- -to the FitsChan -class. This method removes all WCS-related header cards from a FitsChan. - -\item The Plot class has a new attribute called GrfContext that can be used -to comminicate context information between an application and any -graphics functions registered with the Plot class via the -c+ -astGrfSet function. -c- -f+ -AST\_GRFSET routine. -f- -\item Functions registered with the Plot class using -c+ -astGrfSet -c- -f+ -AST\_GRFSET -f- -now take a new additional integer parameter, ``grfcon''. The Plot class -sets this parameter to the value of the Plot's GrfContext attribute before -calling the graphics function. NOTE, THIS CHANGE WILL REQUIRE EXISTING -CODE THAT USES -c+ -astGrfSet -c- -f+ -AST\_GRFSET -f- -TO BE MODIFIED TO INCLUDE THE NEW PARAMETER. -\item The -c+ -astRebinSeq functions -c- -f+ -AST\_REBINSEQ routines -f- -now have an extra parameter that is used to record the total number of input -data values added into the output array. This is necessary to correct a -flaw in the calculation of output variances based on the spread of input -values. NOTE, THIS CHANGE WILL REQUIRE EXISTING CODE TO BE MODIFIED TO -INCLUDE THE NEW PARAMETER (CALLED "NUSED"). -\item Support has been added for the FITS-WCS ``HPX'' (HEALPix) projection. -\item A new flag ``AST\_\_VARWGT'' can be supplied to -c+ -astRebinSeq. -c- -f+ -AST\_REBINSEQ. -f- -This causes the input data values to be weighted using the reciprocals of -the input variances (if supplied). - -\item The Frame class has a new read-only attribute called NormUnit that -returns the normalised value of the Unit attribute for an axis. Here, -``normalisation'' means cancelling redundant units, etc. So for instance, a -Unit value of ``s*(m/s)'' would result in a NormUnit value of ``m''. - -\item A new -c+ -function astShowMesh -c- -f+ -routine AST\_SHOWMESH -f- -has been added to the Region class. It displays a mesh of points covering -the surface of a Region by writing out a table of axis values to standard -output. - -\item The Plot class now honours the value of the LabelUp attribute even if -numerical labels are placed around the edge of the Plot. Previously -LabelUp was only used if the labels were drawn within the interior of -the plot. The LabelUp attribute controls whether numerical labels are -drawn horizontally or parallel to the axis they describe. - -\item A bug has been fixed that could segmentation violations when setting -attribute values. - -\end{enumerate} - -\subsection{Changes Introduced in V4.6} - -The following describes the most significant changes which have -occurred in the AST library between versions V4.5 and V4.6: - -\begin{enumerate} - -\item The TimeFrame class now support Local Time as a time scale. The offset -from UTC to Local Time is specified by a new TimeFrame attribute called -LTOffset. - -\item A new class called Plot3D has been added. The Plot3D class allows -the creation of 3-dimensional annotated coordinate grids. - -\item A correction for diurnal aberration is now included when -converting between AZEL and other celestial coordinate systems. The -correction is based on the value of the ObsLat Frame attribute (the -geodetic latitude of the observer). - -\item A bug has been fixed which caused the DUT1 attribute to be ignored -by the SkyFrame class when finding conversions between AZEL and other -celestial coordinate systems. - -\end{enumerate} - -\subsection{Changes Introduced in V5.0} - -The following describes the most significant changes which -occurred in the AST library between versions V4.6 and V5.0: - -\begin{enumerate} - - -\item The AST library is now thread-safe (assuming that the POSIX pthreads -library is available when AST is built). Many of the macros defined in -the ast.h header file have changed. It is therefore necessary to -re-compile all source code that includes ast.h. - -\item New methods astLock and astUnlock allow an AST Object to be locked -for exclusive use by a thread. - -\item The TimeFrame class now support Local Time as a time scale. The offset -from UTC to Local Time is specified by a new TimeFrame attribute called -LTOffset. - -\item The Channel class has a new attribute called Strict which controls -whether or not to report an error if unexpected data items are found -within an AST Object description read from an external data source. Note, -the default behaviour is now not to report such errors. This differs from -previous versions of AST which always reported an error is unexpected -input items were encountered. - -\end{enumerate} - -\subsection{Changes Introduced in V5.1} - -The following describes the most significant changes which occurred in the -AST library between versions V5.0 and V5.1: - -\begin{enumerate} - -c+ -\item The astUnlock function now has an extra parameter that controls whether -or not an error is reported if the Object is currently locked by another -thread. -c- - -\item The Prism class has been modified so that any class of Region can -be used to define the extrusion axes. Previously, only a Box or Interval -could be used for this purpose. - -c+ -\item The values of the AST\_\_THREADSAFE macro (defined in ast.h) have -been changed from ``yes'' and ``no'' to ``1'' and ``0''. -c- - -\item Improvements have been made to the way that Prisms are simplified -when -c+ -astSimplify -c- -f+ -AST\_SIMPLIFY -f- -is called. The changes mean that more types of Prism will now simplify -into a simpler class of Region. - -\item The PointList class has a new method, -c+ -astPoints, -c- -f+ -AST\_POINTS, -f- -that copies the axis values from the PointList into a supplied array. - -\item The PointList class has a new (read-only) attribute, ListSize, that -gives the number of points stored in the PointList. - -\item The handling of warnings within different classes of Channel has -been rationalised. The XmlStrict attribute and -c+ -astXmlWarnings -c- -f+ -AST\_XMLWARNINGS -f- -function have been removed. The same functionality is now available via -the existing Strict attribute (which has had its remit widened), a new -attribute called ReportLevel, and the new -c+ -astWarnings -c- -f+ -AST\_WARNINGS -f- -function. This new function can be used on any class of Channel. Teh -FitsChan class retains its long standing ability to store warnings as -header cards within the FitsChan, but it also now stores warnings in the -parent Channel structure, from where they can be retrieved using the -c+ -astWarnings -c- -f+ -AST\_WARNINGS -f- -function. - -\item A new function called -c+ -astIntercept -c- -f+ -AST\_INTERCEPT -f- -has been added to the Frame class. This function finds the point of -intersection beteeen two geodesic curves. - -\item A bug in the type-checking of Objects passed as arguments to constructor -functions has been fixed. This bug could lead to applications crashing or -showing strange behaviour if an inappropriate class of Object was -supplied as an argument to a constructor. - -\item The -c+ -astPickAxes -c- -f+ -AST\_PICKAXES -f- -function will now return a Region, if possible, when applied to a Region. If -this is not possible, a Frame will be returned as before. - -\item The choice of default tick-mark for time axes has been improved, to avoid -previous issues which could result in no suitable gap being found, or -inappropriate tick marks when using formatted dates. - -\item A new function called -c+ -astTestFits -c- -f+ -AST\_TESTFITS -f- -has been added to the FitsChan class. This function tests a FitsChan to -see if it contains a defined value for specified FITS keyword. - -\item The AST\_\_UNDEF parameters used to flag undefined FITS keyword values -have been removed. Use the new -c+ -astTestFits -c- -f+ -AST\_TESTFITS -f- -function instead. - -c+ -\item The astIsUndef functions used to test FITS keyword values -have been removed. Use the new astTestFits function instead. -c- - -\end{enumerate} - -\subsection{Changes Introduced in V5.2} - -The following describes the most significant changes which -occurred in the AST library between versions V5.1 and V5.2: - -\begin{enumerate} - -\item A new method called -c+ -astSetFitsCM -c- -f+ -AST\_SETFITSCM -f- -has been added to the FitsChan class. It stores a pure comment card in a -FitsChan (that is, a card with no keyword name or equals sign). - -\item A new attribute called ObsAlt has been added to the Frame class. It -records the geodetic altitude of the observer, in metres. It defaults to -zero. It is used when converting times to or from the TDB timescale, or -converting spectral positions to or from the topocentric rest frame, or -converting sky positions to or from horizon coordinates. The FitsChan -class will include its effect when creating a set of values for the -OBSGEO-X/Y/Z keywords, and will also assign a value to it when reading a -set of OBSGEO-X/Y/Z keyword values from a FITS header. - -\item The TimeMap conversions ``TTTOTDB'' and ``TDBTOTT'', and the SpecMap -conversions ``TPF2HL'' and ``HLF2TP'', now have an additional argument - -the observer's geodetic altitude. - -\item The Polygon class has been modified to make it consistent with the -IVOA STC definition of a Polygon. Specifically, the inside of a polygon -is now the area to the left of each edge as the vertices are traversed in -an anti-clockwise manner, as seen from the inside of the celestial sphere. -Previously, AST used the anti-clockwise convention, but viewed from the -outside of the celestial sphere instead of the inside. Any Polygon saved -using previous versions of AST will be identified and negated automatically -when read by AST V5.2. - -\item A new class of Channel, called StcsChan, has been added that allows -conversion of suitable AST Objects to and from IVOA STC-S format. - -\item A new method called -c+ -astRemoveRegions -c- -f+ -AST\_REMOVEREGIONS -f- -has been added to the Mapping class. It searches a (possibly compound) -Mapping (or Frame) for any instances of the AST Region class, and either -removes them, or replaces them with UnitMaps (or equivalent Frames). It -can be used to remove the masking effects of Regions from a compound -Mapping or Frame. - -\item A new method called -c+ -astDownsize -c- -f+ -AST\_DOWNSIZE -f- -has been added to the Polygon class. It produces a new Polygon that -contains a subset of the vertices in the supplied Polygon. The subset is -chosen to retain the main features of the supplied Polygion, in so far -as that is possible, within specified constraints. - -\item A new constructor called -c+ -astOutline -c- -f+ -AST\_OUTLINE -f- -has been added to the Polygon class. Given a 2D data array, it identifies -the boundary of a region within the array that holds pixels with -specified values. It then creates a new Polygon to describe this boundary -to a specified accuracy. - -\item A new set of methods, called -c+ -astMapGetElem -c- -f+ -AST\_MAPGETELEM -f- -has been added to the KeyMap class. They allow a single element of a vector -valued entry to be returned. - -\item A new attribute called KeyError has been added to the KeyMap Class. It -controls whether the -c+ -astMapGet... -c- -f+ -AST\_MAPGET... -f- -family of functions report an error if an entry with the requested key does -not exist in the KeyMap. - -\end{enumerate} - -\subsection{Changes Introduced in V5.3} - -The following describes the most significant changes which -occurred in the AST library between versions V5.2 and V5.3: - -\begin{enumerate} - -\item The details of how a Frame is aligned with another Frame by the -c+ -astFindFrame and astConvert -c- -f+ -AST\_FINDFRAME and AST\_CONVERT -f- -functions have been changed. The changes mean that a Frame can now be -aligned with an instance of a sub-class of Frame, so long as the number -of axes and the Domain values are consistent. For instance, a basic -2-dimensional Frame with Domain ``SKY'' will now align succesfully with -a SkyFrame, conversion between the two Frames being achieved using a -UnitMap. - -c+ -\item The arrays that supply input values for astMapPut1 are now -declared ``const''. -c- - -\item Added method -c+ -astMatchAxes -c- -f+ -AST\_MATCHAXES -f- -to the Frame class. This method allows corresponding axes within two -Frames to be identified. - -\item The -c+ -astAddFrame -c- -f+ -AST\_ADDFRAME -f- -method can now be used to append one or more axes to all Frames in a FrameSet. -\end{enumerate} - -\subsection{Changes Introduced in V5.3-1} - -The following describes the most significant changes which have -occurred in the AST library between versions V5.3 and V5.3-1: - -\begin{enumerate} - -c+ -\item The utility functions provided by the AST memory management layer -are now documented in an appendix. -c- - -\item The KeyMap class now supports entries that have undefined values. A -new method called -c+ -astMapPutU -c- -f+ -AST\_MAPPUTU -f- -will store an entry with undefined value in a keymap. Methods that -retrieve values from a KeyMap -c+ -(astMapGet0, etc.) -c- -f+ -(AST\_MAPGET0, etc.) -f- -ignore entries with undefined values when searching for an entry with a given -key. - -\item The KeyMap class has a new method called -c+ -astMapCopy -c- -f+ -AST\_MAPCOPY -f- -that copies entries from one KeyMap to another KeyMap. - -\item The KeyMap class has a new boolean attribute called MapLocked. If -c+ -non-zero, -c- -f+ -.TRUE., -f- -an error is reported if an attempt is made to add any new entries -to a KeyMap (the value associated with any old entry may still be changed -without error). The default is -c+ -zero. -c- -f+ -.FALSE. -f- - -\item The Object class has a new method called astHasAttribute/AST\_HASATTRIBUTE -that returns a boolean value indicating if a specified Object has a named -attribute. - -\item The SkyFrame class has two new read-only boolean attributes called -IsLatAxis and IsLonAxis that can be used to determine the nature of a -specified SkyFrame axis. - -\item A bug has been fixed in the -c+ -astRebin(Seq) -c- -f+ -AST\_REBIN(SEQ) -f- -methods that could cause flux to be lost from the edges of the supplied array. - -\item A bug has been fixed in the -c+ -astRebin(Seq) -c- -f+ -AST\_REBIN(SEQ) -f- -methods that caused the first user supplied parameter to be interpreted as the -full width of the spreading kernel, rather than the half-width. - -\item The StcsChan class now ignores case when reading STC-S phrases (except -that units strings are still case sensitive). - -\item A new Mapping method, -c+ -astQuadApprox, -c- -f+ -AST\_QUADAPPROX, -f- -produces a quadratic least-squares fit to a 2D Mapping. - -\item A new Mapping method, -c+ -astSkyOffsetMap, -c- -f+ -AST\_SKYOFFSETMAP, -f- -produces a Mapping from absolute SkyFrame coordinates to offset SkyFrame -coordinates. - -\item The Channel class now has an Indent attribute that controls indentation -in the text created by -c+ -astWrite. -c- -f+ -AST\_WRITE. -f- -The StcsIndent and XmlIndent attributes have been removed. - -\item All classes of Channel now use the string ``'' to represent the -floating point value AST\_\_BAD, rather than the literal formatted value -(typically ``-1.79769313486232e+308'' ). - -\item The KeyMap class now uses the string ``'' to represent the -floating point value AST\_\_BAD, rather than the literal formatted value -(typically ``-1.79769313486232e+308'' ). - -\item The KeyMap class has a new method called -c+ -astMapPutElem -c- -f+ -AST\_MAPPUTELEM -f- -that allows a value to be put into a single element of a vector entry in -a KeyMap. The vector entry is extended automatically to hold the new -element if required. - -\item The DSBSpecFrame class now reports an error if the local oscillator -frequency is less than the absoliute value of the intermediate frequency. - -\end{enumerate} - - -\subsection{Changes Introduced in V5.3-2} - -The following describes the most significant changes which -occurred in the AST library between versions V5.3-1 and V5.3-2: - -\begin{enumerate} - -\item A bug has been fixed in the FitsChan class that could cause wavelength -axes to be assigned the units ``m/s'' when reading WCS information from a -FITS header. - -\item The -c+ -astSet function -c- -f+ -AST\_SET routine -f- -now allows literal commas to be included in string attribute values. String -attribute values that include a literal comma should be enclosed in quotation -marks. - -\item A bug in FitsChan has been fixed that caused ``-SIN'' projection -codes within FITS-WCS headers to be mis-interpreted, resulting in no -FrameSet being read by astRead. - -\item The KeyMap class has a new attribute called ``SortBy''. It controls -the order in which keys are returned by the -c+ -astMapKey -c- -f+ -AST\_MAPKEY -f- -function. Keys can be sorted alphabetically or by age, or left unsorted. - -\item Access to KeyMaps holding thousands of entries is now significantly -faster. - -\item KeyMaps can now hold word (i.e. -c+ -short integer) -c- -f+ -INTEGER*2) -f- -values. - -\end{enumerate} - - -\subsection{Changes Introduced in V5.4-0} - -The following describes the most significant changes which -occurred in the AST library between versions V5.3-2 and V5.4-0: - -\begin{enumerate} - -\item the FitsChan class now has an option to support reading and writing -of FITS-WCS headers that use the -TAB algorithm described in FITS-WCS paper -III. This option is controlled by a new FitsChan attribute called TabOK. -See the documentation for TabOK for more information. - -\item A new class called ``Table'' has been added. A Table is a KeyMap in -which each entry represents a cell in a two-dimensional table. - -\item A new class called ``FitsTable'' has been added. A FitsTable is a -Table that has an associated FitsChan holding headers appropriate to a -FITS binary table. - -\item KeyMaps can now hold byte values. These are held in variables -of type -c+ -"unsigned char". -c- -f+ -BYTE. -f- - -\item KeyMaps have a new attribute called KeyCase that can be set to zero to -make the handling of keys case insensitive. - -\item a memory leak associated with the use of the -c+ -astMapPutElem -c- -f+ -AST\_MAPPUTELEM -f- -functions has been fixed. - -\item A new method called -c+ -astMapRename -c- -f+ -AST\_MAPRENAME -f- -has been added to rename existing entry in a KeyMap. -\end{enumerate} - -\subsection{Changes Introduced in V5.5-0} - -The following describes the most significant changes which -occurred in the AST library between versions V5.4-0 and V5.5-0: - -\begin{enumerate} - -\item The FitsChan ``TabOK'' attribute is now an integer value rather -than a boolean value. If TabOK is set to a non-zero positive integer -before invoking the -c+ -astWrite -c- -f+ -AST\_WRITE -f- -method, its value is used as the version number for any table that is -created as a consequence of the write operation. This is the value stored -in the PVi\_1a keyword in the IMAGE header, and the EXTVER keyword in the -binary table header. In previous versions of AST, the value used for these -headers could not be controlled and was fixed at 1. If TabOK is set to a -negative or zero value, the -TAB algorithm will not be supported by -either the -c+ -astWrite or astRead -c- -f+ -AST\_WRITE or AST\_READ -f- -methods. - -\end{enumerate} - - - -\subsection{Changes Introduced in V5.6-0} - -The following describes the most significant changes which -occurred in the AST library between versions V5.5-0 and V5.6-0: - -\begin{enumerate} - -\item -c+ -New functions astBBuf and astEBuf -c- -f+ -New routines AST\_BBUF and AST\_EBUF -f- -have been added to the Plot class. These control the buffering of graphical -output produced by other Plot methods. - -\item New functions astGBBuf and astGEBuf have been added to the interface -defined by file \verb+grf.h+. The ast\_link command has been modified so -that the \verb+-grf_v3.2+ switch loads dummy versions of the new grf -functions. This means that applications that use the \verb+-grf_v3.2+ -switch should continue to build without any change. However, the new public -c+ -functions astBBuf and astEBuf -c- -f+ -routines AST\_BBUF and AST\_EBUF -f- -will report an error unless the new grf functions are implemented. If you -choose to implement them, you should modify your linking procedure to -use the \verb+-grf+ (or \verb+-grf_v5.6+ ) switch in place of the older -\verb+-grf_v3.2+ switch. See the description of the ast\_link command for -details of these switches. - -\item New method -c+ -astGetRegionMesh -c- -f+ -AST\_GETREGIONMESH -f- -returns a set of positions covering the boundary, or volume, of a supplied -Region. - -\end{enumerate} - - -\subsection{ChangesIntroduced in V5.6-1} - -The following describes the most significant changes which -occurred in the AST library between versions V5.6-0 and V5.6-1: - -\begin{enumerate} - -\item Tables can now have any number of parameters describing the global -properties of the Table. - -\item Frames now interpret the unit string ``A'' as meaning ``Ampere'' -rather than ``Angstrom'', as specified by FITS-WCS paper I. - -\item A bug has been fixed in the -c+ -astFindFrame -c- -f+ -AST\_FINDFRAME -f- -method that allowed a template Frame of a more specialised class to match -a target frame of a less specialised class. For example, this bug would -allow a template SkyFrame to match a target Frame. This no longer -happens. - -\end{enumerate} - -\subsection{Changes Introduced in V5.7-0} - -The following describes the most significant changes which -occurred in the AST library between versions V5.6-1 and V5.7-0: - -\begin{enumerate} - -\item The FitsChan class support for the IRAF-specific ``TNX'' projection has -been extended to include reading TNX headers that use a Chebyshev -representation for the distortion polynomial. - -\item The FitsChan class support for the IRAF-specific ``ZPX'' projection has -been extended to include reading ZPX headers that use simple or Chebyshev -representation for the distortion polynomial. - -\item A bug has been fixed in the FitsChan class that caused headers -including the Spitzer ``-SIP'' distortion code to be read incorrectly if no -inverse polynomial was specified in the header. - -\item A new attribute called PolyTan has been added to the FitsChan class. It -can be used to indicate that FITS headers that specify a TAN projection -should be interpreted according to the ``distorted TAN'' convention -included in an early draft of FITS-WCS paper II. Such headers are created -by (for instance) the SCAMP tool (\url{http://www.astromatic.net/software/scamp}). - -\item The PolyMap class now provides a method called -c+ -astPolyTran -c- -f+ -AST\_POLYTRAN -f- -that adds an inverse transformation to a PolyMap by sampling the forward -transformation on a regular grid, and then fitting a polynomial function -from the resulting output values to the grid of input values. - -\end{enumerate} - -\subsection{Changes Introduced in V5.7-1} - -The following describes the most significant changes which -occurred in the AST library between versions V5.7-0 and V5.7-1: - -\begin{enumerate} - -\item - All classes of Channel can now read to and write from specified -text files, without the need to provide source and sink functions when -the Channel is created. The files to use are specified by the new -attributes SourceFile and SinkFile. - -\item - The FitsChan class now ignores trailing spaces in character-valued WCS -keywords when reading a FrameSet from a FITS header. - -\item - If the FitsChan astRead method reads a FITS header that uses the --SIP (Spitzer) distortion code within the CTYPE values, but which does -not provide an inverse polynomial correction, the FitsChan class will now -use the PolyTran method of the PolyMap class to create an estimate of the -inverse polynomial correction. - -\end{enumerate} - - -\subsection{Changes Introduced in V5.7-2} - -The following describes the most significant changes which -occurred in the AST library between versions V5.7-1 and V5.7-2: - -\begin{enumerate} - -c+ -\item The Object class has a new function astToString (C only), which creates -an in-memory textual serialisation of a given AST Object. A corresponding -new function called astFromString re-creates the Object from its -serialisation. -c- - -\item The PolyMap class can now use an iterative Newton-Raphson method to -evaluate the inverse the inverse transformation if no inverse -transformation is defined when the PolyMap is created. - -\item The FitsChan class has a new method -c+ -astWriteFits -c- -f+ -AST\_WRITEFITS -f- -which writes out all cards currently in the FitsChan to the associated -external data sink (specified either by the SinkFile attribute or the -sink function supplied when the FitsChan was created), and then empties -the FitsChan. - -\item The FitsChan class has a new read-only attribute called ``Nkey'', which -holds the number of keywords for which values are held in a FitsChan. - -\item The FitsChan -c+ -astGetFits -c- -f+ -AST\_GETFITS -f- -methods can now be used to returned the value of the current card. - -\item The FitsChan class has a new read-only attribute called ``CardType'', which -holds the data type of the keyword value for the current card. - -\item The FitsChan class has a new method -c+ -astReadFits -c- -f+ -AST\_READFITS -f- -which forces the FitsChan to reads cards from the associated external -source and appends them to the end of the FitsChan. - -\item - If the FitsChan astRead method reads a FITS header that uses the --SIP (Spitzer) distortion code within the CTYPE values, but which does -not provide an inverse polynomial correction, and for which the PolyTran -method of the PolyMap class fails to create an accurate estimate of the -inverse polynomial correction, then an iterative method will be used to -evaluate the inverse correction for each point transformed. - -\end{enumerate} - -\subsection{Changes Introduced in V6.0} - -The following describes the most significant changes which -occurred in the AST library between versions V5.7-2 and V6.0: - -\begin{enumerate} - -\item This version of AST is the first that can be used with the Python -AST wrapper module, starlink.Ast, available at \url{http://github.com/timj/starlink-pyast}. - -\item When reading a FITS-WCS header, the FitsChan class now recognises the -non-standard ``TPV'' projection code within a CTYPE keyword value. This -code is used by SCAMP (see www.astromatic.net/software/scamp) to -represent a distorted TAN projection. - -\item The Plot class has been changed to remove visual anomalies (such as -incorrectly rotated numerical axis labels) if the graphics coordinates have -unequal scales on the X and Y axes. - -- The graphics escape sequences used to produce graphical sky axis labels -can now be changed using the new -c+ -function astTuneC. -c- -f+ -routine AST\_TUNEC. -f- - -\end{enumerate} - -\subsection{Changes Introduced in V6.0-1} - -The following describes the most significant changes which -occurred in the AST library between versions V6.0 and V6.0-1: - -\begin{enumerate} - -\item The FitsChan class now recognises the Spitzer ``-SIP'' distortion -code within FITS headers that describe non-celestial axes, as well as -celestial axes. - -\item A bug has been fixed that could cause inappropriate equinox values to -be used when aligning SkyFrames if the AlignSystem attribute is set. - -\item The versioning string for AST has changed from -``$.-$'' to ``$..$''. - -\end{enumerate} - -\subsection{Changes Introduced in V7.0.0} - -The following describes the most significant changes which -occurred in the AST library between versions V6.0-1 and V7.0.0: - -\begin{enumerate} - -\item Fundamental positional astronomy calculations are now performed -using the IAU SOFA library where possible, and the Starlink PAL library \xref{SUN/268}{sun268}{} -otherwise (the PAL library contains a subset of the Fortran Starlink SLALIB -library re-written in C). Copies of these libraries are bundled with AST -and so do not need to be obtained or built separately, although external -copies of SOFA and PAL can be used if necessary by including the -``\texttt{--with-external\_pal}'' option when configuring AST. - -\end{enumerate} - -\subsection{Changes Introduced in V7.0.1} - -The following describes the most significant changes which -occurred in the AST library between versions V7.0.0 and V7.0.1: - -\begin{enumerate} - -\item The levmar and wcslib code distributed within AST is now stored in the -main AST library (libast.so) rather than in separate libraries. - -\end{enumerate} - -\subsection{Changes Introduced in V7.0.2} - -The following describes the most significant changes which -occurred in the AST library between versions V7.0.1 and V7.0.2: - -\begin{enumerate} - -\item The libast\_pal library is no longer built if the -``--with-external\_pal'' option is used when AST is configured. - -\end{enumerate} - -\subsection{Changes Introduced in V7.0.3} - -The following describes the most significant changes which -occurred in the AST library between versions V7.0.2 and V7.0.3: - -\begin{enumerate} - -\item A bug has been fixed which could cause an incorrect axis to be used when -accessing axis attributes within CmpFrames. This could happen if axes -within the CmpFrame have been permuted. - -\item A bug has been fixed in the SkyFrame class that could cause the two -values of the SkyRef and/or SkyRefP attributes to be reversed. - -\item Bugs have been fixed in the CmpRegion class that should allow the border -around a compound Region to be plotted more quickly, and more accurately. -Previously, component Regions nested deeply inside a CmpRegion may have -been completely or partially ignored. - -\item A bug has been fixed in the Plot3D class that caused a segmentation -violation if the MinTick attribute was set to zero. - -\item The astResampleX set of methods now includes astResampleK and -astResampleUK that handles 64 bit integer data. - -\end{enumerate} - - -\subsection{Changes Introduced in V7.0.4} - -The following describes the most significant changes which -occurred in the AST library between versions V7.0.3 and V7.0.4: - - -\begin{enumerate} - -\item The previously private grf3d.h header file is now installed into -prefix/include. - -\end{enumerate} - - -\subsection{Changes Introduced in V7.0.5} - -The following describes the most significant changes which -occurred in the AST library between versions V7.0.4 and V7.0.5: - -\begin{enumerate} - -\item The FitsChan class can now read FITS headers that use the SAO -convention for representing distorted TAN projections, based on the use -of ``COi\_m'' keywords to hold the coefficients of the distortion polynomial. - -\end{enumerate} - - -\subsection{Changes Introduced in V7.0.6} - -The following describes the most significant changes which -occurred in the AST library between versions V7.0.5 and V7.0.6: - -\begin{enumerate} - -\item A bug has been fixed in astRebinSeq which could result in -incorrect normalisation of the final binned data and variance values. - -\item When reading a FrameSet from a FITS-DSS header, the keywords CNPIX1 -and CNPIX2 now default to zero if absent. Previously an error was reported. - -\end{enumerate} - - -\subsection{Changes Introduced in V7.1.0} - -The following describes the most significant changes which occurred in the -AST library between versions V7.0.6 and V7.1.0: - -\begin{enumerate} - -\item IMPORTANT! The default behaviour of astRebinSeq is now NOT to conserve -flux. To conserve flux, the AST\_\_CONSERVEFLUX flag should be supplied -when calling -c+ -astRebinSeq. -c- -f+ -AST\_REBINSEQ. -f- -Without this flag, each output value is a weighted mean of the neighbouring -input values. - -\item A new flag AST\_\_NONORM can be used with astRebinSeq to indicate that -normalisation of the output arrays is not required. In this case no -weights array need be supplied. - -\item A bug has been fixed in -c+ -astAddFrame method -c- -f+ -AST\_ADDFRAME routine -f- -that could result in the incorrect inversion of Mappings within the FrameSet -when the AST\_\_ALLFRAMES flag is supplied for the -c+ -"iframe" parameter. -c- -f+ -IFRAME argument. -f- - -\item The -c+ -astRate method -c- -f+ -AST\_RATE function -f- -has been re-written to make it faster and more reliable. - -\end{enumerate} - -\subsection{Changes Introduced in V7.1.1} - -The following describes the most significant changes which -occurred in the AST library between versions V7.1.0 and V7.1.1: - -\begin{enumerate} - -\item When a FitsChan is used to write an ``offset'' SkyFrame (see attribute -SkyRefIs) to a FITS-WCS encoded header, two alternate axis descriptions -are now created - one for the offset coordinates and one for the absolute -coordinates. If such a header is subsequently read back into AST, the -original offset SkyFrame is recreated. - -\item A bug has been fixed in FitsChan that caused inappropriate CTYPE values -to be generated when writing a FrameSet to FITS-WCS headers if the -current Frame describes generalised spherical coordinates (i.e. a -SkyFrame with System=Unknown). - -\end{enumerate} - -\subsection{Changes Introduced in V7.2.0} - -The following describes the most significant changes which -occurred in the AST library between versions V7.1.1 and V7.2.0: - -\begin{enumerate} - -\item A new method call -c+ -astMapDefined -c- -f+ -AST\_MAPDEFINED -f- -has been added to the KeyMap class. It checks if a gtiven key name has -a defined value in a given KeyMap. - -\end{enumerate} - -\subsection{Changes Introduced in V7.3.0} - -The following describes the most significant changes which -occurred in the AST library between versions V7.2.0 and V7.3.0: - -\begin{enumerate} - -c+ -\item The interface for the astRebinSeq family of functions has -been changed in order to allow a greater number of pixels to be pasted -into the output array. The "nused" parameter is now a pointer to a -"int64\_t" variable, instead of an "int". APPLICATION CODE SHOULD BE -CHANGED ACCORDINGLY TO AVOID SEGMENTATION FAULTS AND OTHER ERRATIC -BEHAVIOUR. -c- -f+ -\item The interface for the AST\_REBINSEQ family of routines has -been changed in order to allow a greater number of pixels to be pasted -into the output array. The NUSED parameter is now an INTEGER*8 variable, -instead of an INTEGER. APPLICATION CODE SHOULD BE CHANGED ACCORDINGLY TO -AVOID SEGMENTATION FAULTS AND OTHER ERRATIC BEHAVIOUR. -f- - -\item Added a new facility to the FrameSet class to allow each Frame to be -associated with multiple Mappings, any one of which can be used to -connect the Frame to the other Frames in the FrameSet. The choice of -which Mapping to use is controlled by the new ``Variant'' attribute of the -FrameSet class. - -\item Mappings (but not Frames) that have a value set for their Ident -attribute are now left unchanged by the -c astSimplify function. -f AST\_SIMPLIFY routine. - -\end{enumerate} - -\subsection{Changes Introduced in V7.3.1} - -The following describes the most significant changes which -occurred in the AST library between versions V7.3.0 and V7.3.1: - -\begin{enumerate} - -\item Fix a bug that could cauise a segmentation violation when reading -certain FITS headers that use a TNX projection. - -\end{enumerate} - -\subsection{Changes Introduced in V7.3.2} - -The following describes the most significant changes which -occurred in the AST library between versions V7.3.1 and V7.3.2: - -\begin{enumerate} - -\item Fix support for reading FITS header that use a GLS projection. -Previously, an incorrect transformation was used for such projections if -any CRVAL or CROTA value was non-zero. - -\item The KeyMap class has new sorting options ``KeyAgeUp'' and -``KeyAgeDown'' that retain the position of an existing entry if its value -is changed. See the SortBy attribute. - -\item A bug has been fixed in the FitsChan class that caused CDELT keywords -for sky axes to be treated as radians rather than degrees when reading a -FITS header, if the corresponding CTYPE values included no projection code. - -\end{enumerate} - -\subsection{Changes Introduced in V7.3.3} - -The following describes the most significant changes which -occurred in the AST library between versions V7.3.2 and V7.3.3: - -\begin{enumerate} - -\item The FitsChan class has new attributes CardName and CardComm, which hold -the keyword name and comment of the current card. - -\item When using the FitsChan class to read FITS-WCS headers that include -polynomial distortion in the SIP format, any inverse transformation specified -in the header is now ignored and a new inverse is created to replace it based -on the supplied forward transformation. Previously, an inverse was created -only if the header did not include an inverse. The accuracy of the inverse -transformation has also been improved, although it may now be slower to -evaluate in some circumstances. - -\end{enumerate} - -\subsection{Changes Introduced in V7.3.4} - -The following describes the most significant changes which -occurred in the AST library between versions V7.3.3 and V7.3.4: - -\begin{enumerate} - -\item By default, the simplification of Polygons no longer checks that the -edges are not bent by the simplification. A new attribute, SimpVertices, -can be set to zero in order to re-instate this check. - -\item The Polygon class has a new mathod, -c+ -astConvex, -c- -f+ -AST\_CONVEX, -f- -that returns a Polygon representing the shortest polygon (i.e. convex -hull) enclosing a specified set of pixel values within a supplied array. - -\end{enumerate} - -\subsection{Changes Introduced in V8.0.0} - -The following describes the most significant changes which -occurred in the AST library between versions V7.3.4 and V8.0.0: - -\begin{enumerate} - -\item AST is now distributed under the Lesser GPL licence. - -\item The PolyMap class now uses files copied from the C/C++ Minpack -package (see \url{http://devernay.free.fr/hacks/cminpack/index.html}) to perform -least squares fitting of N-dimensional polynomials. - -\item Use of the IAU SOFA library has been replaced by ERFA library, which is -a re-badged copy of SOFA distributed under a less restrictive license. A -copy of ERFA is included within AST. - -\end{enumerate} - -\subsection{Changes Introduced in V8.0.1} - -The following describes the most significant changes which -occurred in the AST library between versions V8.0.0 and V8.0.1: - -\begin{enumerate} - -\item The Base and Current attributes of a FrameSet may now be set using the - Domain name or the index of the required Frame. -\item The order of WCS axes within new FITS-WCS headers created by astWrite - can now be controlled using a new attribute called FitsAxisOrder. -\item Supported added for FITS XPH (polar HEALPIX) projection. -c+ -\item The macro used to invoke the astAppendString utility function has - changed to allow printf-style converstions to be included in the - supplied text. Any code that uses this macro must be re-compiled. -\item The astRebin and astRebinSeq family of functions now include support - for arrays with char (byte) and unsigned char (unsigned byte) data types. -c- -f+ -\item The AST\_REBIN and AST\_REBINSEQ family of functions now include support - for arrays with \_BYTE (byte) and and \_UBYTE (unsigned byte) data types. -f- - -\end{enumerate} - -\subsection{Changes Introduced in V8.0.2} -c+ -The following describes the most significant changes which -occurred in the AST library between versions V8.0.1 and V8.0.2: - -\begin{enumerate} -\item For security reasons, the change introduced to astAppendString in - V8.0.1 has been moved to a new function called astAppendStringf, and - astAppendString itself has been reverted to its V8.0.0 version. - Any software that has been built against V8.0.1 will need to be - re-compiled and re-linked against V8.0.2. -\end{enumerate} - -c- -f+ -The changes that occurred in the AST library between versions V8.0.1 and -V8.0.2 only affect the C interface. The Fortran interface remains the -same as V8.0.1. -f- - -\subsection{Changes Introduced in V8.0.3} -The following describes the most significant changes which -occurred in the AST library between versions V8.0.2 and V8.0.3: - -\begin{enumerate} - -\item Methods -c+ -astRebin, astRebinSeq, astResample and astTranGrid -c- -f+ -AST\_REBIN, AST\_REBINSEQ, AST\_RESAMPLE and AST\_TRANGRID. -f- -now report an error if an array is specified that has more pixels than -can be counted by a 32 bit integer. -\item The hypertext documentation is now generated using Tex4HT rather -than latex2html. The format of the hypertext docs has changed significantly. -\item Another bug fix associated with reading CAR projections from -FITS-WCS headers. -f+ -\item Trailing spaces supplied within attribute setting strings are now ignored. -f- -c+ -\item Constructor options strings of the form ``\texttt{..., "\%s", text );}'' -can now be supplied. This avoids a security issue associated with the -alternative form ``\texttt{..., text );}''. -c- -\end{enumerate} - -\subsection{Changes Introduced in V8.0.4} -The following describes the most significant changes which -occurred in the AST library between versions V8.0.3 and V8.0.4: - -\begin{enumerate} - -\item The behaviour of the -c+ -astAddFrame method has been changed slightly. Previously, astAddFrame -c- -f+ -AST\_ADDFRAME method has been changed slightly. Previously, AST\_ADDFRAME -f- -modified the FrameSet by storing references to the supplied Mapping and -Frame objects within the FrameSet. This meant that any subsequent changes -to the current Frame of the modified FrameSet also affected the supplied -Frame object. Now, deep copies of the Mapping and Frame objects (rather -than references) are stored within the modified FrameSet. This means that -subsequent changes to the modified FrameSet will now have no effect on -the supplied Frame. - -\item The choice of default tick-mark gaps for time axes has been -improved, to avoid a previous issue which could result in no suitable gap -being found. - -- A new method called -c+ -astRegionOutline -c- -f+ -AST\_REGIONOUTLINE -f- -has been added to the Plot class. It draws the outline of a supplied AST -Region. - -\item A bug has been fixed that could cause astSimplfy to enter an infinite loop. - -\item Some improvements have been made to the Mapping simplification process -that allow more Mappings to be simplified. - -\item The Frame class has a new read-only attribute called InternalUnit, -which gives the units used for the unformatted (i.e. floating-point) axis -values used internally by application code. For most Frames, the -InternalUnit value is just the same as the Unit value (i.e. formatted and -unformatted axis values use the same units). However, the SkyFrame class -always returns ``\texttt{rad}'' for InternalUnit, regardless of the value of -Unit, indicating that floating-point SkyFrame axis values are always in units -of radians. - -\item The LutMap class has a new attribute called LutEpsilon, which specifies -the relative error of the values in the table. It is used to decide if -the LutMap can be simplified to a straight line. - -\end{enumerate} - - -\subsection{Changes Introduced in V8.0.5} -The following describes the most significant changes which -occurred in the AST library between versions V8.0.4 and V8.0.5: - -\begin{enumerate} - -\item The SkyFrame class has a new attribute called SkyTol, which specifies -the smallest significant distance within the SkyFrame. It is used to -decide if the Mapping between two SkyFrames can be considered a unit -transformation. The default value is 0.001 arc-seconds. - -\item A bug has been fixed in the FitsChan class that prevented illegal -characters within FITS keyword names (i.e. characters not allowed by the -FITS standard) being detected. This bug could under some circumstances -cause a subsequent segmentation violation to occur. - -\item A ``BadKeyName'' warning is now issued by the FitsChan class if a FITS -keyword name is encountered that contains any illegal characters. See -attribute ``Warnings'' and -c+ -function ``astWarnings''. -c- -f+ -routine ``AST\_WARNINGS''. -f- - -\end{enumerate} - -\subsection{Changes Introduced in V8.1.0} -The following describes the most significant changes which -occurred in the AST library between versions V8.0.5 and V8.1.0: - -\begin{enumerate} - -\item The configure script has a new option ``--without-fortran'' that allows -AST to be built in situations where no Fortran compiler is available. The -resulting library has no Fortran interface and so cannot be used within -Fortran applications. Also, the link scripts do not attempt to include the -fortran runtime libraries. - -\end{enumerate} - -\subsection{\xlabel{changes}\xlabel{list_of_most_recent_changes}Changes -Introduced in V8.2} -The following describes the most significant changes which -occurred in the AST library between versions V8.1.0 and V8.2.0: - -\begin{enumerate} - -\item A new class of Mapping called UnitNormMap has been added that converts -a vector to a unit vector relative to a specified centre, plus length. A -UnitNormMap has N inputs and N+1 outputs.The lower N output coordinates -represent a unit vector parallel to the supplied input vector, and the -(N+1)'th output coordinate is the length of the input vector. - -\item The restriction that Mappings are immutable has been extended to all -Mapping classes. This means that attributes representing parameters of -a Mapping's forward or inverse transformation cannot be changed after -the Mapping has been created. In order to minimise the risk to existing -software, this rule does not apply to Mappings that have not yet been -included in other objects such as CmpMaps or FrameSets, or which have not -yet been cloned. In other words, an error is reported if an attempt is -made to change the nature of a Mapping's transformation, but only if the -reference count of the Mapping is greater than one. The Mapping classes -affected include: GrismMap, LutMap, PcdMap, SphMap, WcsMap and ZoomMap. - -\end{enumerate} - - -\subsection{Changes Introduced in V8.3} -The following describes the most significant changes which -occurred in the AST library between versions V8.2.0 and V8.3.0: - -\begin{enumerate} - -c+ -\item A new method called astAxNorm -c- -f+ -\item A new method called AST\_AXNORM -f- -has been added to the Frame class that normalises an array of axis -values. When used with SkyFrames, it allows longitude values to be -normalised into the shortest range. - -f+ -\item A bug has been fixed in the Fortran include file AST\_PAR that caused constants -related to $\pi$ to be defined as single rather than double precision. -f- - -\item A bug has been fixed in the astGetRegionBounds method that could -cause the wrong bounds to be returned for regions spanning a longitude = -zero singularity. - -\end{enumerate} - -\subsection{Changes Introduced in V8.4} -The following describes the most significant changes which -occurred in the AST library between versions V8.3.0 and V8.4.0: - -\begin{enumerate} - -\item The PAL library files included in the AST distribution have been updated -to PAL version 0.9.7. - -\item Multiple identical NormMaps in series will now be simplified to a -single NormMap. - -\item A NormMap that encapsulates a basic Frame will now be simplified to a -UnitMap. - -f+ -\item The AST\_TIMEADD -f- -c+ -\item The astTimeAdd -c- -method of the TimeMap class now include an extra argument that gives the -number of values supplied in the arguments array. Note, any existing code -that uses this method will need to be changed. - -f+ -\item The AST\_SLAADD -f- -c+ -\item The astSlaAdd -c- -method of the SlaMap class now include an extra argument that gives the -number of values supplied in the arguments array. Note, any existing code -that uses this method will need to be changed. - -f+ -\item The AST\_SPECADD -f- -c+ -\item The astSpecAdd -c- -method of the SpecMap class now include an extra argument that gives the -number of values supplied in the arguments array. Note, any existing code -that uses this method will need to be changed. - -\item Multiple identical NormMaps in series will now be simplified to a -single NormMap. - -\item A NormMap that encapsulates a basic Frame will now be simplified to a -UnitMap. - -\item If the -c+ -astMapRegion -c- -f+ -AST\_MAPREGION -f- -method is used to map a Region into a new Frame that has fewer axes than -the original Region, and if the inverse transformation of the supplied -Mapping does not specify a value for the missing axes, then those axes -are removed entirely from the Region. Previously they were retained, but -automatically supplied with bad values. This affects the number of mesh -points per axes for such Regions, and so affects the accuracy of overlap -determination. - -\end{enumerate} - -\subsection{Changes Introduced in V8.5} -The following describes the most significant changes which -occurred in the AST library between versions V8.4.0 and V8.5.1: - -\begin{enumerate} - -\item - A new class of Mapping called ChebyMap has been added. This is a -Mapping that implements Chebyshev polynomial transformations. - -\item A bug has been fixed in the PolyMap class that caused incorrect values -to be returned for the TranForward and TranInverse attributes if the PolyMap -has been inverted. - -\item The KeyMap class has a new method called -c+ -astMapGetC -c- -f+ -AST\_MAPGETC -f- -which returns a named entry as a single string. If the entry is a vector -the returned string is a comma-separated list of its elements, enclosed -in parentheses. - -\item If the -c+ -function that delivers error messages to the user (astPutErr) -c- -f+ -routine that delivers error messages to the user (AST\_PUTERR) -f- -is re-implemented, the new version can now be registered at run-time using -the new -c+ -astSetPutErr function. -c- -f+ -AST\_SETPUTERR routine. -f- -Previously, the new version needed to be linked into the application at -build time. - - -\item The Frame class now has a new attribute caled DTAI, which can be used -to specify the number of leap seconds at the moment represented by the -Frame's Epoch attribute. By default, the internal look-up table of leap -seconds contained within AST is used. The DTAI attribute allows old -versions of AST, which may not include the most recent leap seconds, to -be used with new data. - -\item The TimeMap class has been changed so that some conversions now require -a ``Dtai'' value (\emph{i.e.} the number of leap seconds) to be supplied by the -caller. If AST\_\_BAD is supplied for ``Dtai'', the internal look-up table of -leap seconds contained withn AST will be used. The conversions affected -are those between TAI and UTC, and those between TT and TDB. - -\end{enumerate} - -\subsection{\xlabel{changes}\xlabel{list_of_most_recent_changes}Changes -Introduced in V8.6} -The following describes the most significant changes which have -occurred in the AST library between versions V8.5.1 and V8.6.2 (the -current version): - -\begin{enumerate} - -\item The behaviour of the astLinearApprox method of the Mapping class has -been changed in cases where the Mapping being approximated generates bad -(AST\_\_BAD) values for one or more of its outputs. Previously, any such -Mapping would be deemed non-linear and no fit would be returned. Now, a -fit is returned, provided the other outputs of the Mapping are linear, -but the fit contains AST\_\_BAD values for the coefficients describing the -bad Mapping output. - -\item The astWrite method of the FitsChan class can now create FITS-WCS headers -that include keyords describing focal plane distortion using the -conventions of the Spitzer SIP scheme. This is however only possible if -the SipOK attribute of the FitsChan is set to a non-zero value (which is -the default), and the FrameSet being written out contains an appropriate -PolyMap that conforms to the requirements of the SIP convention. - -\item A new function call astCreatedAt is now available that returns the -function name, file path and line number at which an AST object was first -created. Note, there is no Fortran equivalent to this new C function. - -\item The number of digits used to format floating point values has been -increased in order to avoid loss of precision when converting from binary -to string and back to binary. This could cause very small changes in numerical -values returned by AST functions. - -\item If a FrameSet is supplied as the ``map'' argument to astAddFrame, it now -extracts and stores the base->current Mapping from the supplied FrameSet. -Previously, the entire FrameSet was stored as the Mapping. - -\end{enumerate} - -Programs which are statically linked will need to be re-linked in -order to take advantage of these new facilities. - -\end{document} diff --git a/ast/switchmap.c b/ast/switchmap.c deleted file mode 100644 index 23dec4b..0000000 --- a/ast/switchmap.c +++ /dev/null @@ -1,2875 +0,0 @@ -/* -*class++ -* Name: -* SwitchMap - -* Purpose: -* A Mapping that encapsulates a set of alternate Mappings. - -* Constructor Function: -c astSwitchMap -f AST_SWITCHMAP - -* Description: -* A SwitchMap is a Mapping which represents a set of alternate -* Mappings, each of which is used to transform positions within a -* particular region of the input or output coordinate system of the -* SwitchMap. -* -* A SwitchMap can encapsulate any number of Mappings, but they must -* all have the same number of inputs (Nin attribute value) and the -* same number of outputs (Nout attribute value). The SwitchMap itself -* inherits these same values for its Nin and Nout attributes. Each of -* these Mappings represents a "route" through the switch, and are -* referred to as "route" Mappings below. Each route Mapping transforms -* positions between the input and output coordinate space of the entire -* SwitchMap, but only one Mapping will be used to transform any given -* position. The selection of the appropriate route Mapping to use with -* any given input position is made by another Mapping, called the -* "selector" Mapping. Each SwitchMap encapsulates two selector -* Mappings in addition to its route Mappings; one for use with the -* SwitchMap's forward transformation (called the "forward selector -* Mapping"), and one for use with the SwitchMap's inverse transformation -* (called the "inverse selector Mapping"). The forward selector Mapping -* must have the same number of inputs as the route Mappings, but -* should have only one output. Likewise, the inverse selector Mapping -* must have the same number of outputs as the route Mappings, but -* should have only one input. -* -* When the SwitchMap is used to transform a position in the forward -* direction (from input to output), each supplied input position is -* first transformed by the forward transformation of the forward selector -* Mapping. This produces a single output value for each input position -* referred to as the selector value. The nearest integer to the selector -* value is found, and is used to index the array of route Mappings (the -* first supplied route Mapping has index 1, the second route Mapping has -* index 2, etc). If the nearest integer to the selector value is less -* than 1 or greater than the number of route Mappings, then the SwitchMap -* output position is set to a value of AST__BAD on every axis. Otherwise, -* the forward transformation of the selected route Mapping is used to -* transform the supplied input position to produce the SwitchMap output -* position. -* -* When the SwitchMap is used to transform a position in the inverse -* direction (from "output" to "input"), each supplied "output" position -* is first transformed by the inverse transformation of the inverse -* selector Mapping. This produces a selector value for each "output" -* position. Again, the nearest integer to the selector value is found, -* and is used to index the array of route Mappings. If this selector -* index value is within the bounds of the array of route Mappings, then -* the inverse transformation of the selected route Mapping is used to -* transform the supplied "output" position to produce the SwitchMap -* "input" position. If the selector index value is outside the bounds -* of the array of route Mappings, then the SwitchMap "input" position is -* set to a value of AST__BAD on every axis. -* -* In practice, appropriate selector Mappings should be chosen to -* associate a different route Mapping with each region of coordinate -* space. Note that the SelectorMap class of Mapping is particularly -* appropriate for this purpose. -* -* If a compound Mapping contains a SwitchMap in series with its own -* inverse, the combination of the two adjacent SwitchMaps will be -* replaced by a UnitMap when the compound Mapping is simplified using -c astSimplify. -f AST_SIMPLIFY. - -* Inheritance: -* The SwitchMap class inherits from the Mapping class. - -* Attributes: -* The SwitchMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c The SwitchMap class does not define any new functions beyond those -f The SwitchMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 13-MAR-2006 (DSB): -* Original version. -* 17-MAR-2006 (DSB): -* Guard against AST__BAD selector values. -* 9-MAY-2006 (DSB): -* Check selector Mapping pointers are not NULL before calling -* astEqual in Equal. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS SwitchMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ -#include "unitmap.h" /* Unit Mappings */ -#include "channel.h" /* I/O channels */ -#include "switchmap.h" /* Interface definition for this class */ -#include "frame.h" /* Frames */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(SwitchMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SwitchMap,Class_Init) -#define class_vtab astGLOBAL(SwitchMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSwitchMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSwitchMap *astSwitchMapId_( void *, void *, int, void **, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *RemoveRegions( AstMapping *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetObjSize( AstObject *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static AstMapping *GetSelector( AstSwitchMap *, int, int *, int * ); -static AstMapping *GetRoute( AstSwitchMap *, double, int *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Member functions. */ -/* ================= */ -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two SwitchMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "switchmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* SwitchMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two SwitchMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a SwitchMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the SwitchMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *fsmap1; - AstMapping *fsmap2; - AstMapping *ismap1; - AstMapping *ismap2; - AstMapping *rmap1; - AstMapping *rmap2; - AstSwitchMap *that; - AstSwitchMap *this; - int fsinv1; - int fsinv2; - int isinv1; - int i; - int isinv2; - int nroute; - int result; - int rinv1; - int rinv2; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two SwitchMap structures. */ - this = (AstSwitchMap *) this_object; - that = (AstSwitchMap *) that_object; - -/* Check the second object is a SwitchMap. We know the first is a - SwitchMap since we have arrived at this implementation of the virtual - function. */ - if( astIsASwitchMap( that ) ) { - -/* Check they have the same number of route mappings. */ - nroute = this->nroute; - if( that->nroute == nroute ) { - -/* Get the forward selector Mappings from the two SwitchMaps. */ - fsmap1 = GetSelector( this, 1, &fsinv1, status ); - fsmap2 = GetSelector( that, 1, &fsinv2, status ); - -/* Are they equal? */ - if( ( !fsmap1 && !fsmap2 ) || - ( fsmap1 && fsmap2 && astEqual( fsmap1, fsmap2 ) ) ) { - -/* Get the inverse selector Mappings from the two SwitchMaps. */ - ismap1 = GetSelector( this, 0, &isinv1, status ); - ismap2 = GetSelector( that, 0, &isinv2, status ); - -/* Are they equal? */ - if( ( !ismap1 && !ismap2 ) || - ( ismap1 && ismap2 && astEqual( ismap1, ismap2 ) ) ) { - -/* Loop over the route mappings, breaking as soon as two unequal route - Mappings are found. Re-instate the original values for the route - Mapping Invert flag after testing the route Mappings for equality. */ - result = 1; - for( i = 0; result && i < nroute; i++ ) { - rmap1 = GetRoute( this, (double) ( i + 1 ), &rinv1, status ); - rmap2 = GetRoute( that, (double) ( i + 1 ), &rinv2, status ); - if( !astEqual( rmap1, rmap2 ) ) result = 0; - astSetInvert( rmap2, rinv2 ); - astSetInvert( rmap1, rinv1 ); - } - } - -/* Reinstate the invert flags for the inverse selector Mappings. Ensure - this is done in the opposite order to which the selector Mappings were - obtained (in case they are in fact the same Mapping). */ - if( ismap2 ) astSetInvert( ismap2, isinv2 ); - if( ismap1 ) astSetInvert( ismap1, isinv1 ); - } - -/* Reinstate the invert flags for the forward selector Mappings. Ensure - this is done in the oppsote order to which the selector Mappings were - obtained (in case they are in fact the same Mapping). */ - if( fsmap2 ) astSetInvert( fsmap2, fsinv2 ); - if( fsmap1 ) astSetInvert( fsmap1, fsinv1 ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "switchmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* SwitchMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied SwitchMap, -* in bytes. - -* Parameters: -* this -* Pointer to the SwitchMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSwitchMap *this; - int i; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the SwitchMap structure. */ - this = (AstSwitchMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astGetObjSize( this->fsmap ); - result += astGetObjSize( this->ismap ); - - for( i = 0; i < this->nroute; i++ ) { - result += astGetObjSize( this->routemap[ i ] ); - } - - result += astGetObjSize( this->routeinv ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static AstMapping *GetRoute( AstSwitchMap *this, double sel, int *inv, int *status ){ -/* -* Name: -* GetRoute - -* Purpose: -* Return a pointer to a route Mapping, handling all Invert flags. - -* Type: -* Private function. - -* Synopsis: -* #include "switchmap.h" -* AstMapping *GetRoute( AstSwitchMap *this, double sel, int *inv, int *status ) - -* Class Membership: -* SwitchMap method. - -* Description: -* This function returns a pointer to a route Mapping (specified by a -* floating point selector value) for the given SwitchMap, taking account -* of the state of the Invert flag of both the route Mapping and the -* SwitchMap. - -* Parameters: -* this -* Pointer to the SwitchMap. -* sel -* The selector value. The nearest integer value (minus 1) is used -* to index the array of route Mappings stored in the SwitchMap. A -* NULL pointer is returned if the selector value is out of range. -* inv -* Pointer to an int in which to return the original value of the -* Invert flag of the returned Mapping. The astSetInvert method -* should be used to re-instate this value once all use of the Mapping -* has been completed. -* status -* Pointer to the inherited status variable. - -* Returns: -* A pointer to the route Mapping to use. Note, the returned pointer -* should NOT be annulled when no longer needed. NULL is returned -* (without error) if the SwitchMap does not have a route Mapping for the -* requested selector value. The forward transformation of the -* returned Mapping will implenment the forward transformation of the -* required route Mapping (and vice-versa). - -*/ - -/* Local Variables: */ - AstMapping *ret; - int rindex; - -/* Initialise */ - ret = NULL; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Check selector value is good. */ - if( sel != AST__BAD ) { - -/* Convert the supplied floating point selector value into an integer - index into the array of route Mappings held in the supplied SwitchMap. */ - rindex = (int)( sel + 0.5 ) - 1; - -/* Return the null pointer if the index is out of range. */ - if( rindex >= 0 && rindex < this->nroute ) { - -/* Get the required route Mapping. */ - ret = ( this->routemap )[ rindex ]; - -/* Return its original invert flag. */ - *inv = astGetInvert( ret ); - -/* Set the Invert flag back to the value it had when the SwitchMap was - created. */ - astSetInvert( ret, this->routeinv[ rindex ] ); - -/* If the SwitchMap has since been inverted, also invert the returned - route Mapping, so that the forward transformation of the returned - Mapping implements the forward transformation of the supplied - SwitchMap (and vice-versa). */ - if( astGetInvert( this ) ) astInvert( ret ); - } - } - -/* Return the pointer. */ - return ret; - -} - -static AstMapping *GetSelector( AstSwitchMap *this, int fwd, int *inv, int *status ){ -/* -* Name: -* GetSelector - -* Purpose: -* Return a pointer to a selector Mapping, handling all Invert flags. - -* Type: -* Private function. - -* Synopsis: -* #include "switchmap.h" -* AstMapping *GetSelector( AstSwitchMap *this, int fwd, int *inv, int *status ) - -* Class Membership: -* SwitchMap method. - -* Description: -* This function returns a pointer to either the forward or inverse -* selector Mapping for the given SwitchMap, taking account of the -* state of the Invert flag of bothe the selector Mapping and the -* SwitchMap. - -* Parameters: -* this -* Pointer to the SwitchMap. -* fwd -* If non-zero, return the forward selector Mapping. Otherwise, -* return the inverse selector Mapping. -* inv -* Pointer to an int in which to return the original value of the -* Invert flag of the returned Mapping. The astSetInvert method -* should be used to re-instate this value once all use of the Mapping -* has been completed. -* status -* Pointer to the inherited status variable. - -* Returns: -* A pointer to the selector Mapping to use. Note, the returned pointer -* should NOT be annulled when no longer needed. NULL is returned -* (without error) if the SwitchMap does not have a Mapping for the -* requested selector. - -*/ - -/* Local Variables: */ - AstMapping *ret; - int swinv; - -/* Initialise */ - ret = NULL; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* See if the SwitchMap has been inverted. */ - swinv = astGetInvert( this ); - -/* If the SwitchMap has been inverted, the forward and inverse selector - Mappings should be reversed. */ - if( ( !swinv && !fwd ) || ( swinv && fwd ) ){ - ret = this->ismap; - if( ret ) { - *inv = astGetInvert( ret ); - astSetInvert( ret, this->isinv ); - } - - } else { - ret = this->fsmap; - if( ret ) { - *inv = astGetInvert( ret ); - astSetInvert( ret, this->fsinv ); - } - } - - if( ret && swinv ) astInvert( ret ); - -/* Return the pointer. */ - return ret; - -} - -void astInitSwitchMapVtab_( AstSwitchMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSwitchMapVtab - -* Purpose: -* Initialise a virtual function table for a SwitchMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "switchmap.h" -* void astInitSwitchMapVtab( AstSwitchMapVtab *vtab, const char *name ) - -* Class Membership: -* SwitchMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SwitchMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASwitchMap) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -/* None. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - mapping->Rate = Rate; - mapping->RemoveRegions = RemoveRegions; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "SwitchMap", "Alternate regionalised Mapping" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* SwitchMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstSwitchMap *this; /* Pointer to SwitchMap structure */ - int i; /* Loop count */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the SwitchMap structure. */ - this = (AstSwitchMap *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->fsmap, mode, extra, fail ); - if( !result ) result = astManageLock( this->ismap, mode, extra, fail ); - for( i = 0; i < this->nroute; i++ ) { - if( !result ) result = astManageLock( this->routemap[ i ], mode, - extra, fail ); - } - - return result; - -} -#endif - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a SwitchMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* SwitchMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated SwitchMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated SwitchMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated SwitchMap which is to be merged with -* its neighbours. This should be a cloned copy of the SwitchMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* SwitchMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated SwitchMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstSwitchMap *map; - AstMapping *new; - int i; - int nroute; - int result; - int fsinv_old; - int isinv_old; - int *rinv_old; - AstMapping *sfsmap; - AstMapping *sismap; - int simp; - AstMapping **srmap; - AstSwitchMap *swneb; - int ilo; - int equal; - -/* Initialise.*/ - result = -1; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Get a pointer to this SwitchMap, and note the number of route Mappings. */ - map = (AstSwitchMap *) this; - nroute = map->nroute; - -/* Temporarily put the Invert flag of all encapsulated Mappings (both - route and selector) back to the values they had when the SwitchMap was - created, noting their current values so that they can be re-instated - later. If the SwitchMap itself has been inverted, swap all the original - invert flags. */ - if( map->fsmap ) { - fsinv_old = astGetInvert( map->fsmap ); - astSetInvert( map->fsmap, map->fsinv ); - } else { - fsinv_old = 0; - } - - if( map->ismap ) { - isinv_old = astGetInvert( map->ismap ); - astSetInvert( map->ismap, map->isinv ); - } else { - isinv_old = 0; - } - - rinv_old = astMalloc( sizeof( int )*nroute ); - if( astOK ) { - for( i = 0; i < nroute; i++ ) { - rinv_old[ i ] = astGetInvert( map->routemap[ i ] ); - astSetInvert( map->routemap[ i ], map->routeinv[ i ] ); - } - } - -/* If possible, merge the SwitchMap with a neighbouring SwitchMap. */ -/* =============================================================== */ -/* Only do this if we are combining the Mappings in series. */ - if( series ) { - -/* Is the higher neighbour a SwitchMap? If so get a pointer to it, and - note the index of the lower of the two adjacent SwitchMaps. */ - if( where < ( *nmap - 1 ) && - astIsASwitchMap( ( *map_list )[ where + 1 ] ) ){ - swneb = (AstSwitchMap *) ( *map_list )[ where + 1 ]; - ilo = where; - -/* If not, is the lower neighbour a SwitchMap? If so get a pointer to it, and - note the index of the lower of the two adjacent SwitchMaps. */ - } else if( where > 0 && - astIsASwitchMap( ( *map_list )[ where - 1 ] ) ){ - swneb = (AstSwitchMap *) ( *map_list )[ where - 1 ]; - ilo = where - 1; - - } else { - swneb = NULL; - } - -/* If a neighbouring SwitchMap was found, we can replace the pair by a - UnitMap if the two SwitchMaps are equal but have opposite values for - their Invert flags. Temporarily invert the neighbour, then compare - the two SwitchMaps for equality, then re-invert the neighbour. */ - if( swneb ) { - astInvert( swneb ); - equal = astEqual( map, swneb ); - astInvert( swneb ); - -/* If the two SwitchMaps are equal but opposite, annul the first of the two - Mappings, and replace it with a UnitMap. Also set the invert flag. */ - if( equal ) { - new = (AstMapping *) astUnitMap( astGetNin( ( *map_list )[ ilo ] ), "", status ); - (void) astAnnul( ( *map_list )[ ilo ] ); - ( *map_list )[ ilo ] = new; - ( *invert_list )[ ilo ] = 0; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ ilo + 1 ] ); - for ( i = ilo + 2; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = where; - } - } - } - -/* Attempt to simplify the SwitchMap on its own. */ -/* ============================================= */ -/* Only do this if no change was made above. */ - if( result == -1 ) { - -/* If the SwitchMap is inverted, create an equal SwitchMap which is not - inverted. To do this, invert and swap the selector Mappings, and - invert all the route Mappings. We use astSetInvert rather than astInvert - because two or more more stored pointers may point to the same Mapping - in which case that Mapping would be inverted more than once with - unpredictable results. */ - if( ( *invert_list )[ where ] ) { - if( map->fsmap ) astSetInvert( map->fsmap, !(map->fsinv) ); - if( map->ismap ) astSetInvert( map->ismap, !(map->isinv) ); - for( i = 0; i < nroute; i++ ) { - astSetInvert( map->routemap[ i ], !(map->routeinv[ i ]) ); - } - - new = (AstMapping *) astSwitchMap( map->ismap, map->fsmap, nroute, (void **) map->routemap, "", status ); - - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) new; - ( *invert_list )[ where ] = 0; - result = where; - -/* Otherwise, try to simplify each of the encapsulated Mappings, noting - if any simplification takes place. */ - } else { - sfsmap = ( map->fsmap ) ? astSimplify( map->fsmap ) : NULL; - sismap = ( map->ismap ) ? astSimplify( map->ismap ) : NULL; - simp = ( sfsmap != map->fsmap ) || ( sismap != map->ismap ); - - srmap = astMalloc( sizeof( AstMapping * )*nroute ); - if( astOK ) { - for( i = 0; i < nroute; i++ ) { - srmap[ i ] = astSimplify( map->routemap[ i ] ); - simp = simp || ( srmap[ i ] != map->routemap[ i ] ); - } - } - -/* If any simplification took place, construct a new SwitchMap from these - simplified Mappings. */ - if( simp ) { - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) astSwitchMap( sfsmap, sismap, - nroute, (void **) srmap, "", status ); - result = where; - } - -/* Release resources. */ - if( sfsmap ) sfsmap = astAnnul( sfsmap ); - if( sismap ) sismap = astAnnul( sismap ); - if( srmap ) { - for( i = 0; i < nroute; i++ ) srmap[ i ] = astAnnul( srmap[ i ] ); - srmap = astFree( srmap ); - } - } - } - -/* Re-instate the original Invert values for the encapsulated Mappings. */ - if( map->fsmap ) astSetInvert( map->fsmap, fsinv_old ); - if( map->ismap ) astSetInvert( map->ismap, isinv_old ); - if( rinv_old ) { - for( i = 0; i < nroute; i++ ) { - astSetInvert( map->routemap[ i ], rinv_old[ i ] ); - } - rinv_old = astFree( rinv_old ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "switchmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* SwitchMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. Also evaluates the second derivative. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -*/ - -/* Local Variables: */ - AstSwitchMap *map; - AstMapping *smap; - AstMapping *rmap; - double result; - double sel; - int fsinv; - int rinv; - int nin; - -/* Initialise. */ - result = AST__BAD; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Get a pointer to the SwitchMap structure. */ - map = (AstSwitchMap *) this; - -/* Get a pointer to the effective foward selector Mapping, and its current - invert flag (this takes account of whether the SwtichMap has been - inverted or not). This call resets the selector's invert flag temporarily - back to the value it had when the SwitchMap was created. */ - smap = GetSelector( map, 1, &fsinv, status ); - -/* If the SwitchMap has no forward selector Mapping, return AST__BAD. */ - if( smap ) { - -/* Get the number of inputs */ - nin = astGetNin( smap ); - -/* Transform the supplied position using the selector Mapping. The output - value is the selector value that indicates which route Mapping to use. */ - astTranN( smap, 1, nin, 1, at, 1, 1, 1, &sel ); - -/* Get the index of the route Mapping to use, and check it is valid (if - not, return AST__BAD if not). This takes account of whether the - SwitchMap has been inverted, and also temporarily re-instates the - original value of the route Mapping's Invert flag . */ - rmap = GetRoute( map, sel, &rinv, status ); - if( rmap ) { - -/* Use the astRate method of the route Mapping. */ - result = astRate( rmap, at, ax1, ax2 ); - -/* Reset the Invert flag for the route Mapping. */ - astSetInvert( rmap, rinv ); - } - -/* Reset the Invert flag for the selector Mapping. */ - astSetInvert( smap, fsinv ); - } - -/* Return the result. */ - return result; -} - -static AstMapping *RemoveRegions( AstMapping *this_mapping, int *status ) { -/* -* Name: -* RemoveRegions - -* Purpose: -* Remove any Regions from a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "switchmap.h" -* AstMapping *RemoveRegions( AstMapping *this, int *status ) - -* Class Membership: -* SwitchMap method (over-rides the astRemoveRegions method inherited -* from the Mapping class). - -* Description: -* This function searches the supplied Mapping (which may be a -* compound Mapping such as a SwitchMap) for any component Mappings -* that are instances of the AST Region class. It then creates a new -* Mapping from which all Regions have been removed. If a Region -* cannot simply be removed (for instance, if it is a component of a -* parallel SwitchMap), then it is replaced with an equivalent UnitMap -* in the returned Mapping. -* -* The implementation provided by the SwitchMap class invokes the -* astRemoveRegions method on all the component Mappings, and joins -* the results together into a new SwitchMap. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the modified mapping. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstMapping **temp; /* Array of new route Mappings */ - AstMapping *newfsmap; /* New forward selector Mapping */ - AstMapping *newismap; /* New inverse selector Mapping */ - AstMapping *result; /* Result pointer to return */ - AstSwitchMap *new; /* Pointer to new SwitchMap */ - AstSwitchMap *this; /* Pointer to SwitchMap structure */ - int changed; /* Has any mapping been changed? */ - int i; /* Loop count */ - int nax; /* Number of Frame axes */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the SwitchMap. */ - this = (AstSwitchMap *) this_mapping; - -/* Allocate an array to hold the modified Mapping pointers. */ - temp = astMalloc( sizeof( AstMapping *)*( this->nroute ) ); - if( astOK ) { - -/* Invoke the astRemoveRegions method on all the component Mappings. */ - changed = 0; - for( i = 0; i < this->nroute; i++ ) { - temp[ i ] = astRemoveRegions( this->routemap[ i ] ); - -/* Note if any Mapping was changed. */ - if( temp[ i ] != this->routemap[ i ] ) { - changed = 1; - -/* The implementation of the astRemoveRegions method provided by the - Region class returns a Frame rather than a UnitMap. But we need - Mappings here, not Frames. So if the new Mapping is a Frame, replace - it with an equivalent UnitMap. */ - if( astIsAFrame( temp[ i ] ) ) { - nax = astGetNin( temp[ i ] ); - (void) astAnnul( temp[ i ] ); - temp[ i ] = (AstMapping *) astUnitMap( nax, " ", status ); - } - } - } - -/* And on the other ancillary Mappings */ - if( this->fsmap ) { - newfsmap = astRemoveRegions( this->fsmap ); - if( newfsmap != this->fsmap ) { - changed = 1; - if( astIsAFrame( newfsmap ) ) { - nax = astGetNin( newfsmap ); - (void) astAnnul( newfsmap ); - newfsmap = (AstMapping *) astUnitMap( nax, " ", status ); - } - } - - } else { - newfsmap = NULL; - } - - if( this->ismap ) { - newismap = astRemoveRegions( this->ismap ); - if( newismap != this->ismap ) { - changed = 1; - if( astIsAFrame( newismap ) ) { - nax = astGetNin( newismap ); - (void) astAnnul( newismap ); - newismap = (AstMapping *) astUnitMap( nax, " ", status ); - } - } - - } else { - newismap = NULL; - } - -/* If no component was modified, just return a clone of the supplied - pointer. */ - if( ! changed ) { - result = astClone( this ); - -/* Otherwise, we need to create a new Mapping to return. We take a deep - copy of the supplied SwitchMap and then modify the Mappings so that - we retain any extra information in the supplied SwitchMap. */ - } else { - new = astCopy( this ); - - for( i = 0; i < this->nroute; i++ ) { - (void) astAnnul( new->routemap[ i ] ); - new->routemap[ i ] = astClone( temp[ i ] ); - } - - if( newfsmap ) { - (void) astAnnul( new->fsmap ); - new->fsmap = astClone( newfsmap ); - } - - if( newismap ) { - (void) astAnnul( new->ismap ); - new->ismap = astClone( newismap ); - } - - result = (AstMapping *) new; - } - -/* Free resources. */ - for( i = 0; i < this->nroute; i++ ) { - temp[ i ] = astAnnul( temp[ i ] ); - } - - if( newfsmap ) newfsmap = astAnnul( newfsmap ); - if( newismap ) newismap = astAnnul( newismap ); - } - - temp = astFree( temp ); - -/* Annul the returned Mapping if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -int astSwitchList_( AstSwitchMap *this, int invert, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -*+ -* Name: -* astSwitchList - -* Purpose: -* Extract the selector and route Mappings from a SwitchMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "switchmap.h" -* int astSwitchList( AstSwitchMap *this, int invert, int *nmap, -* AstMapping ***map_list, int **invert_list ) - -* Class Membership: -* SwitchMap member function. - -* Description: -* This function extracts the route and selector Mappings form a -* SwitchMap. - -* Parameters: -* this -* Pointer to the SwitchMap to be decomposed (it is not actually -* modified by this function). -* invert -* The value to which the SwitchMap's Invert attribute is to be -* (notionally) set before performing the decomposition. Normally, -* the value supplied here will be the actual Invert value obtained -* from the SwitchMap (e.g. using astGetInvert). Sometimes, however, -* when a SwitchMap is encapsulated within another structure, that -* structure may retain an Invert value (in order to prevent external -* interference) which should be used instead. -* -* Note that the actual Invert value of the SwitchMap supplied is -* not used (or modified) by this function. -* nmap -* The address of an int in which to return a count of the number of -* individual Mappings in the decomposition. The supplied value is -* ignored. -* map_list -* Address of a pointer to an array of Mapping pointers. The value -* supplied on entry is ignored. On exit, it points at a dynamically -* allocated array containing Mapping pointers ("*nmap" in number) that -* result from the decomposition requested. -* -* The returned Mapping pointers returned will identify the following -* sequence of Mappings; forward selector mapping (or NULL if the -* SwitchMap has no forward selector Mapping), inverse selector -* mapping (or NULL if the SwitchMap has no inverse selector Mapping), -* the route Mappings in the order they were supplied when the -* SwitchMap was constructed. -* -* All the Mapping pointers returned by this function should be -* annulled by the caller, using astAnnul, when no longer -* required. The dynamic array holding these pointers should -* also be freed, using astFree. -* invert_list -* Address of a pointer to an array of int. The value supplied on -* entry is ignored. On exit, it points at a dynamically allocated -* array containing Invert attribute values ("*nmap" in number) that -* result from the decomposition requested. -* -* The returned Invert values returned identify the values which must -* be assigned to the Invert attributes of the corresponding -* Mappings (whose pointers are in the "*map_list" array) before -* they are applied. Note that these values may differ from the -* actual Invert attribute values of these Mappings, which are -* not relevant. -* -* The dynamic array holding these values should be freed by the -* caller, using astFree, when no longer required. - -* Returned Value: -* The number of route Mappings stored in the SwitchMap. - -* Notes: -* - It is unspecified to what extent the original SwitchMap and the -* individual (decomposed) Mappings are inter-dependent. Consequently, -* the individual Mappings cannot be modified without risking -* modification of the original SwitchMap. -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then the *nmap value, the -* list of Mapping pointers and the list of Invert values will all -* be returned unchanged. -*- -*/ - -/* Local Variables: */ - AstMapping *map; /* Pointer to Mapping to return */ - int inv; /* Original Invert flag for Mapping */ - int i; /* Route Mapping index */ - int oldinv; /* Original Invert flag for SwitchMap */ - int result; /* Returned value */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Store the numbe of route Mappings */ - result = this->nroute; - *nmap = result + 2; - -/* Allocate the required arrays. */ - *map_list = astMalloc( sizeof( AstMapping * )*(size_t) *nmap ); - *invert_list = astMalloc( sizeof( int )*(size_t) *nmap ); - -/* Check the pointers can be used safely. */ - if( astOK ) { - -/* Temporaily set the requested Invert flag for the SwitchMap. */ - oldinv = astGetInvert( this ); - astSetInvert( this, invert ); - -/* Get the forward selector Mapping. */ - map = GetSelector( this, 1, &inv, status ); - -/* If the SwitchMap has a forward selector Mapping, return a clone of the - Mapping pointer, and the invert flag to be used with it, then - re-instate the original invert flag value (which was modified by - GetSelector). */ - if( map ) { - ( *map_list )[ 0 ] = astClone( map ); - ( *invert_list )[ 0 ] = astGetInvert( map ); - astSetInvert( map, inv ); - -/* If the SwitchMap does not has a forward selector Mapping, return a - NULL pointer. */ - } else { - ( *map_list )[ 0 ] = NULL; - ( *invert_list )[ 0 ] = 0; - } - -/* Likewise, get and return the inverse selector Mapping.*/ - map = GetSelector( this, 0, &inv, status ); - if( map ) { - ( *map_list )[ 1 ] = astClone( map ); - ( *invert_list )[ 1 ] = astGetInvert( map ); - astSetInvert( map, inv ); - } else { - ( *map_list )[ 1 ] = NULL; - ( *invert_list )[ 1 ] = 0; - } - -/* Loop round all route Mappings. */ - for( i = 0; i < result; i++ ){ - -/* Get the next route Mapping. */ - map = GetRoute( this, (double) i + 1.0, &inv, status ); - -/* If the SwitchMap has a route Mapping for the current selector value, - return a clone of the Mapping pointer, and the invert flag to be used - with it, then re-instate the original invert flag value (which was - modified by GetRoute). */ - if( map ) { - ( *map_list )[ i + 2 ] = astClone( map ); - ( *invert_list )[ i + 2 ] = astGetInvert( map ); - astSetInvert( map, inv ); - -/* If the SwitchMap does not has a route Mapping for the current selector - value, return a NULL pointer. */ - } else { - ( *map_list )[ i + 2 ] = NULL; - ( *invert_list )[ i + 2 ] = 0; - } - - } - -/* Re-instate the original Ivert flag for the SwitchMap. */ - astSetInvert( this, oldinv ); - - } - -/* If an error has occurred, free the returned arrays. */ - if( !astOK ) { - *map_list = astFree( *map_list ); - *invert_list= astFree( *invert_list ); - result= 0; - *nmap = 0; - } - -/* Return the result */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a SwitchMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "switchmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* SwitchMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a SwitchMap and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required Mapping. -* This implies applying each of the SwitchMap's component Mappings in turn, -* either in series or in parallel. - -* Parameters: -* this -* Pointer to the SwitchMap. -* in -* Pointer to the PointSet associated with the input coordinate values. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the SwitchMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstMapping *rmap; - AstMapping *selmap; - AstPointSet *ps1; - AstPointSet *ps1a; - AstPointSet *ps2; - AstPointSet *ps2a; - AstPointSet *result; - AstPointSet *selps; - AstSwitchMap *map; - double **in_ptr; - double **out_ptr; - double **ptr1; - double **ptr2; - double **sel_ptr; - double *outv; - double *sel; - int *popmap; - int iroute; - int ipoint; - int j; - int k; - int maxpop; - int ncin; - int ncout; - int npoint; - int nroute; - int rindex; - int rinv; - int selinv; - int totpop; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the SwitchMap. */ - map = (AstSwitchMap *) this; - -/* Apply the parent Mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We now extend the parent astTransform method by applying the component - Mappings of the SwitchMap to generate the output coordinate values. */ - -/* Get the number of input and output coords. */ - if( forward ) { - ncin = astGetNin( this ); - ncout = astGetNout( this ); - } else { - ncin = astGetNout( this ); - ncout = astGetNin( this ); - } - -/* Get the appropriate selector Mapping. */ - selmap = GetSelector( map, forward, &selinv, status ); - -/* Transform the supplied positions using the above selector Mapping. */ - selps = astTransform( selmap, in, forward, NULL ); - -/* Get a pointer to the array holding the selector value. */ - sel_ptr = astGetPoints( selps ); - -/* Get a pointer to the array holding the input values. */ - in_ptr = astGetPoints( in ); - -/* Get a pointer to the array in which to store the results, and the total - number of points being transformed. */ - out_ptr = astGetPoints( result ); - npoint = astGetNpoint( result ); - -/* We now count how many positions are to be tranformed by each of the - route Mappings. */ - nroute = map->nroute; - popmap = astMalloc( sizeof( int )*nroute ); - if( astOK ) { - for( iroute = 0; iroute < nroute; iroute++ ) popmap[ iroute ] = 0; - - sel = sel_ptr[ 0 ]; - for( ipoint = 0; ipoint < npoint; ipoint++,sel++ ) { - if( *sel != AST__BAD ) { - rindex = (int)( *sel + 0.5 ) - 1; - if( rindex >= 0 && rindex < nroute ) ( popmap[ rindex ] )++; - } - } - -/* Find the number of points transformed by the most popular route Mapping. - Also find the total number of points transformed by any route Mapping. */ - totpop = 0; - maxpop = 0; - for( iroute = 0; iroute < nroute; iroute++ ) { - if( popmap[ iroute ] > maxpop ) maxpop = popmap[ iroute ]; - totpop += popmap[ iroute ]; - } - if( maxpop == 0 ) maxpop = 1; - -/* If some of the points are not transformed by any route Mapping. - Initialise the whole output array to hold AST__BAD at every point. */ - if( totpop < npoint ) { - for( j = 0; j < ncout; j++ ) { - outv = out_ptr[ j ]; - for( ipoint = 0; ipoint < npoint; ipoint++ ) *(outv++) = AST__BAD; - } - } - -/* Create a PointSet large enough to hold all the supplied positions - which are to be transformed by the most popular route Mapping. */ - ps1 = astPointSet( maxpop, ncin, "", status ); - ptr1 = astGetPoints( ps1 ); - -/* Create a PointSet large enough to hold all the output positions - created by the most popular route Mapping. */ - ps2 = astPointSet( maxpop, ncout, "", status ); - ptr2 = astGetPoints( ps2 ); - if( astOK ) { - -/* Loop round each route Mapping which is used by at least 1 point. */ - for( iroute = 0; iroute < nroute; iroute++ ) { - if( popmap[ iroute ] >0 ) { - rmap = GetRoute( map, (double)( iroute + 1 ), &rinv, status ); - -/* Construct two PointSets of the correct size to hold the input and - output points to be processed with the current route Mapping. We - re-use the memory allocated for the largest route Mapping's PointSet. */ - if( popmap[ iroute ] != maxpop ) { - ps1a = astPointSet( popmap[ iroute ], ncin, "", status ); - astSetPoints( ps1a, ptr1 ); - ps2a = astPointSet( popmap[ iroute ], ncout, "", status ); - astSetPoints( ps2a, ptr2 ); - } else { - ps1a = astClone( ps1 ); - ps2a = astClone( ps2 ); - } - -/* Fill the input PointSet with the input positions which are to be - transformed using the current route Mapping. */ - sel = sel_ptr[ 0 ]; - k = 0; - for( ipoint = 0; ipoint < npoint; ipoint++,sel++ ) { - if( *sel != AST__BAD ) { - rindex = (int)( *sel + 0.5 ) - 1; - if( rindex == iroute ) { - for( j = 0; j < ncin; j++ ) { - ptr1[ j ][ k ] = in_ptr[ j ][ ipoint ]; - } - k++; - } - } - } - -/* Use the route Mapping to transform this PointSet. */ - (void) astTransform( rmap, ps1a, forward, ps2a ); - -/* Copy the axis values from the resulting PointSet back into the results - array. */ - sel = sel_ptr[ 0 ]; - k = 0; - for( ipoint = 0; ipoint < npoint; ipoint++,sel++ ) { - if( *sel != AST__BAD ) { - rindex = (int)( *sel + 0.5 ) - 1; - if( rindex == iroute ) { - for( j = 0; j < ncout; j++ ) { - out_ptr[ j ][ ipoint ] = ptr2[ j ][ k ]; - } - k++; - } - } - } - -/* Free resources. */ - ps1a = astAnnul( ps1a ); - ps2a = astAnnul( ps2a ); - -/* Re-instate the Invert flag for the route Mapping. */ - astSetInvert( rmap, rinv ); - } - } - } - -/* Free resources. */ - ps1 = astAnnul( ps1 ); - ps2 = astAnnul( ps2 ); - } - - selps = astAnnul( selps ); - popmap = astFree( popmap ); - -/* Re-instate the Invert flag of the selector Mapping. */ - astSetInvert( selmap, selinv ); - -/* If an error occurred, clean up by deleting the output PointSet (if - allocated by this function) and setting a NULL result pointer. */ - if ( !astOK ) { - if ( !out ) result = astDelete( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for SwitchMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for SwitchMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Mappings within the SwitchMap. -*/ - -/* Local Variables: */ - AstSwitchMap *in; /* Pointer to input SwitchMap */ - AstSwitchMap *out; /* Pointer to output SwitchMap */ - int i; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output SwitchMaps. */ - in = (AstSwitchMap *) objin; - out = (AstSwitchMap *) objout; - -/* For safety, start by clearing any references to the input component - Mappings,etc, from the output SwitchMap. */ - out->fsmap = NULL; - out->ismap = NULL; - out->routemap = NULL; - out->routeinv = NULL; - -/* Make copies of these Mappings, etc, and store pointers to them in the output - SwitchMap structure. */ - if( in->fsmap ) out->fsmap = astCopy( in->fsmap ); - if( in->ismap ) out->ismap = astCopy( in->ismap ); - - out->routemap = astMalloc( sizeof( AstMapping * )*( in->nroute ) ); - out->routeinv = astMalloc( sizeof( int )*( in->nroute ) ); - if( astOK ) { - for( i = 0; i < in->nroute; i++ ) { - out->routemap[ i ] = astCopy( in->routemap[ i ] ); - out->routeinv[ i ] = in->routeinv[ i ]; - } - } - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for SwitchMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for SwitchMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstSwitchMap *this; /* Pointer to SwitchMap */ - int i; - -/* Obtain a pointer to the SwitchMap structure. */ - this = (AstSwitchMap *) obj; - -/* Free dynamically allocated resources. */ - if( this->fsmap ) this->fsmap = astAnnul( this->fsmap ); - if( this->ismap ) this->ismap = astAnnul( this->ismap ); - for( i = 0; i < this->nroute; i++ ) { - this->routemap[ i ] = astAnnul( this->routemap[ i ] ); - } - this->routemap = astFree( this->routemap ); - this->routeinv = astFree( this->routeinv ); - -/* Clear the remaining SwitchMap variables. */ - this->nroute = 0; - this->fsinv = 0; - this->isinv = 0; -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SwitchMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the SwitchMap class to an output Channel. - -* Parameters: -* this -* Pointer to the SwitchMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSwitchMap *this; - int ival; - int set; - int i; - char buf[ 20 ]; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SwitchMap structure. */ - this = (AstSwitchMap *) this_object; - -/* Write out values representing the instance variables for the SwitchMap - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Forward selector Mapping */ -/* ------------------------ */ - if( this->fsmap ) { - astWriteObject( channel, "FSMap", 1, 1, this->fsmap, - "Forward selector Mapping" ); - -/* Forward selector Invert flag. */ -/* ----------------------------- */ - ival = this->fsinv; - set = ( ival != 0 ); - astWriteInt( channel, "FSInv", set, 0, ival, - ival ? "Fwd selector used in inverse direction" : - "Fwd selector used in forward direction" ); - } - - -/* Inverse selector Mapping */ -/* ------------------------ */ - if( this->ismap ) { - astWriteObject( channel, "ISMap", 1, 1, this->ismap, - "Inverse selector Mapping" ); - -/* Forward selector Invert flag. */ -/* ----------------------------- */ - ival = this->isinv; - set = ( ival != 0 ); - astWriteInt( channel, "ISInv", set, 0, ival, - ival ? "Inv selector used in inverse direction" : - "Inv selector used in forward direction" ); - } - -/* Loop to dump each route Mapping and its invert flag. */ -/* ---------------------------------------------------- */ - for( i = 0; i < this->nroute; i++ ) { - sprintf( buf, "RMap%d", i + 1 ); - astWriteObject( channel, buf, 1, 1, this->routemap[ i ], - "Route Mapping" ); - - ival = this->routeinv[ i ]; - set = ( ival != 0 ); - sprintf( buf, "RInv%d", i + 1 ); - astWriteInt( channel, buf, set, 0, ival, - ival ? "Route Mapping used in inverse direction" : - "Route Mapping used in forward direction" ); - } - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASwitchMap and astCheckSwitchMap functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SwitchMap,Mapping) -astMAKE_CHECK(SwitchMap) - -AstSwitchMap *astSwitchMap_( void *fsmap_void, void *ismap_void, int nroute, - void **routemaps_void, const char *options, int *status, ...) { -/* -*+ -* Name: -* astSwitchMap - -* Purpose: -* Create a SwitchMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "switchmap.h" -* AstSwitchMap *astSwitchMap( AstMapping *fsmap, AstMapping *ismap, -* int nroute, AstMapping **routemaps, -* const char *options, ... ) - -* Class Membership: -* SwitchMap constructor. - -* Description: -* This function creates a new SwitchMap and optionally initialises its -* attributes. - -* Parameters: -* fsmap -* Pointer to the forward selector Mapping -* ismap -* Pointer to the inverse selector Mapping -* nroute -* The number of route Mappings. -* routemaps -* An array of pointers to the route Mappings. -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new SwitchMap. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new SwitchMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic SwitchMap constructor which is -* available via the protected interface to the SwitchMap class. A -* public interface is provided by the astSwitchMapId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "map1" and "map2" parameters are of type (void *) and are -* converted and validated within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSwitchMap *new; /* Pointer to new SwitchMap */ - AstMapping *fsmap; /* Pointer to fwd selector Mapping */ - AstMapping *ismap; /* Pointer to inv selector Mapping */ - AstMapping **routemaps; /* Array of route Mapping pointers */ - int i; /* Route Mappings index */ - va_list args; /* Variable argument list */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Report an error if no route Mappings have been supplied. */ - if( nroute <= 0 ) astError( AST__BDPAR, "astSwitchMap(SwitchMap): " - "Bad number of route Mappings (%d) specified.", status, - nroute ); - -/* Otherwise create an array to hold the route Mapping pointers. */ - routemaps = astMalloc( sizeof( AstMapping * )*nroute ); - -/* Obtain and validate pointers to the Mapping structures provided. */ - if( astOK ) { - fsmap = fsmap_void ? astCheckMapping( fsmap_void ) : NULL; - ismap = ismap_void ? astCheckMapping( ismap_void ) : NULL; - for( i = 0; i < nroute; i++ ) { - routemaps[ i ] = astCheckMapping( routemaps_void[ i ] ); - } - } - - if ( astOK ) { - -/* Initialise the SwitchMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSwitchMap( NULL, sizeof( AstSwitchMap ), !class_init, &class_vtab, - "SwitchMap", fsmap, ismap, nroute, routemaps ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new SwitchMap's - attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Free memory used to hold the route Mapping pointers. */ - routemaps = astFree( routemaps ); - -/* Return a pointer to the new SwitchMap. */ - return new; -} - -AstSwitchMap *astSwitchMapId_( void *fsmap_void, void *ismap_void, int nroute, - void **routemaps_void, const char *options, ... ) { -/* -*++ -* Name: -c astSwitchMap -f AST_SWITCHMAP - -* Purpose: -* Create a SwitchMap. - -* Type: -* Public function. - -* Synopsis: -c #include "switchmap.h" -c AstSwitchMap *astSwitchMap( AstMapping *fsmap, AstMapping *ismap, -c int nroute, AstMapping *routemaps[], -c const char *options, ... ) -f RESULT = AST_SWITCHMAP( FSMAP, ISMAP, NROUTE, ROUTEMAPS, OPTIONS, -f STATUS ) - -* Class Membership: -* SwitchMap constructor. - -* Description: -* This function creates a new SwitchMap and optionally initialises -* its attributes. -* -* A SwitchMap is a Mapping which represents a set of alternate -* Mappings, each of which is used to transform positions within a -* particular region of the input or output coordinate system of the -* SwitchMap. -* -* A SwitchMap can encapsulate any number of Mappings, but they must -* all have the same number of inputs (Nin attribute value) and the -* same number of outputs (Nout attribute value). The SwitchMap itself -* inherits these same values for its Nin and Nout attributes. Each of -* these Mappings represents a "route" through the switch, and are -* referred to as "route" Mappings below. Each route Mapping transforms -* positions between the input and output coordinate space of the entire -* SwitchMap, but only one Mapping will be used to transform any given -* position. The selection of the appropriate route Mapping to use with -* any given input position is made by another Mapping, called the -* "selector" Mapping. Each SwitchMap encapsulates two selector -* Mappings in addition to its route Mappings; one for use with the -* SwitchMap's forward transformation (called the "forward selector -* Mapping"), and one for use with the SwitchMap's inverse transformation -* (called the "inverse selector Mapping"). The forward selector Mapping -* must have the same number of inputs as the route Mappings, but -* should have only one output. Likewise, the inverse selector Mapping -* must have the same number of outputs as the route Mappings, but -* should have only one input. -* -* When the SwitchMap is used to transform a position in the forward -* direction (from input to output), each supplied input position is -* first transformed by the forward transformation of the forward selector -* Mapping. This produces a single output value for each input position -* referred to as the selector value. The nearest integer to the selector -* value is found, and is used to index the array of route Mappings (the -* first supplied route Mapping has index 1, the second route Mapping has -* index 2, etc). If the nearest integer to the selector value is less -* than 1 or greater than the number of route Mappings, then the SwitchMap -* output position is set to a value of AST__BAD on every axis. Otherwise, -* the forward transformation of the selected route Mapping is used to -* transform the supplied input position to produce the SwitchMap output -* position. -* -* When the SwitchMap is used to transform a position in the inverse -* direction (from "output" to "input"), each supplied "output" position -* is first transformed by the inverse transformation of the inverse -* selector Mapping. This produces a selector value for each "output" -* position. Again, the nearest integer to the selector value is found, -* and is used to index the array of route Mappings. If this selector -* index value is within the bounds of the array of route Mappings, then -* the inverse transformation of the selected route Mapping is used to -* transform the supplied "output" position to produce the SwitchMap -* "input" position. If the selector index value is outside the bounds -* of the array of route Mappings, then the SwitchMap "input" position is -* set to a value of AST__BAD on every axis. -* -* In practice, appropriate selector Mappings should be chosen to -* associate a different route Mapping with each region of coordinate -* space. Note that the SelectorMap class of Mapping is particularly -* appropriate for this purpose. -* -* If a compound Mapping contains a SwitchMap in series with its own -* inverse, the combination of the two adjacent SwitchMaps will be -* replaced by a UnitMap when the compound Mapping is simplified using -c astSimplify. -f AST_SIMPLIFY. - -* Parameters: -c fsmap -f FSMAP = INTEGER (Given) -* Pointer to the forward selector Mapping. This must have a -* defined forward transformation, but need not have a defined -* inverse transformation. It must have one output, and the number of -* inputs must match the number of inputs of each of the supplied -* route Mappings. -c NULL -f AST__NULL -* may be supplied, in which case the SwitchMap will have an undefined -* forward Mapping. -c ismap -f ISMAP = INTEGER (Given) -* Pointer to the inverse selector Mapping. This must have a -* defined inverse transformation, but need not have a defined -* forward transformation. It must have one input, and the number of -* outputs must match the number of outputs of each of the supplied -* route Mappings. -c NULL -f AST__NULL -* may be supplied, in which case the SwitchMap will have an undefined -* inverse Mapping. -c nroute -f NROUTE = INTEGER (Given) -* The number of supplied route Mappings. -c routemaps -f ROUTEMAPS( NROUTE ) = INTEGER (Given) -* An array of pointers to the route Mappings. All the supplied -* route Mappings must have common values for the Nin and Nout -* attributes, and these values define the number of inputs and -* outputs of the SwitchMap. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new SwitchMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new SwitchMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSwitchMap() -f AST_SWITCHMAP = INTEGER -* A pointer to the new SwitchMap. - -* Notes: -c - Note that the component Mappings supplied are not copied by -c astSwitchMap (the new SwitchMap simply retains a reference to -c them). They may continue to be used for other purposes, but -c should not be deleted. If a SwitchMap containing a copy of its -c component Mappings is required, then a copy of the SwitchMap should -c be made using astCopy. -f - Note that the component Mappings supplied are not copied by -f AST_SWITCHMAP (the new SwitchMap simply retains a reference to -f them). They may continue to be used for other purposes, but -f should not be deleted. If a SwitchMap containing a copy of its -f component Mappings is required, then a copy of the SwitchMap should -f be made using AST_COPY. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astSwitchMap constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astSwitchMap_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "map1" and "map2" parameters -* are of type (void *) and are converted from an ID value to a -* pointer and validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astSwitchMap_ directly, so it must be a re-implementation -* of it in all respects, except for the conversions between IDs -* and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSwitchMap *new; /* Pointer to new SwitchMap */ - AstMapping *fsmap; /* Pointer to fwd selector Mapping */ - AstMapping *ismap; /* Pointer to inv selector Mapping */ - AstMapping **routemaps; /* Array of route Mapping pointers */ - int i; /* Route Mappings index */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Report an error if no route Mappings have been supplied. */ - if( nroute <= 0 ) astError( AST__BDPAR, "astSwitchMap(SwitchMap): " - " Bad number of route Mappings (%d) specified.", status, - nroute ); - -/* Otherwise create an array to hold the route Mapping pointers. */ - routemaps = astMalloc( sizeof( AstMapping * )*nroute ); - -/* Obtain and validate pointers to the Mapping structures provided. */ - if( astOK ) { - fsmap = fsmap_void ? astCheckMapping( astMakePointer(fsmap_void) ) : NULL; - ismap = ismap_void ? astCheckMapping( astMakePointer(ismap_void) ) : NULL; - for( i = 0; i < nroute; i++ ) { - routemaps[ i ] = astVerifyMapping( astMakePointer(routemaps_void[ i ]) ); - } - } - - if ( astOK ) { - -/* Initialise the SwitchMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitSwitchMap( NULL, sizeof( AstSwitchMap ), !class_init, &class_vtab, - "SwitchMap", fsmap, ismap, nroute, routemaps ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new SwitchMap's - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Free memory used to hold the route Mapping pointers. */ - routemaps = astFree( routemaps ); - -/* Return an ID value for the new SwitchMap. */ - return astMakeId( new ); -} - -AstSwitchMap *astInitSwitchMap_( void *mem, size_t size, int init, - AstSwitchMapVtab *vtab, const char *name, - AstMapping *fsmap, AstMapping *ismap, - int nroute, AstMapping **routemaps, int *status ) { -/* -*+ -* Name: -* astInitSwitchMap - -* Purpose: -* Initialise a SwitchMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "switchmap.h" -* AstSwitchMap *astInitSwitchMap( void *mem, size_t size, int init, -* AstSwitchMapVtab *vtab, const char *name, -* AstMapping *fsmap, AstMapping *ismap, -* int nroute, AstMapping **routemaps ) - -* Class Membership: -* SwitchMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new SwitchMap object. It allocates memory (if necessary) to -* accommodate the SwitchMap plus any additional data associated with the -* derived class. It then initialises a SwitchMap structure at the start -* of this memory. If the "init" flag is set, it also initialises the -* contents of a virtual function table for a SwitchMap at the start of -* the memory passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SwitchMap is to be initialised. -* This must be of sufficient size to accommodate the SwitchMap data -* (sizeof(SwitchMap)) plus any data used by the derived class. If a -* value of NULL is given, this function will allocate the memory itself -* using the "size" parameter to determine its size. -* size -* The amount of memory used by the SwitchMap (plus derived class -* data). This will be used to allocate memory if a value of NULL is -* given for the "mem" parameter. This value is also stored in the -* SwitchMap structure, so a valid value must be supplied even if not -* required for allocating memory. -* init -* A logical flag indicating if the SwitchMap's virtual function table -* is to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new SwitchMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* fsmap -* Pointer to the forward selector Mapping. -* ismap -* Pointer to the inverse selector Mapping. -* nroute -* The number of route Mappings supplied. -* routemaps -* An array holdiong pointers to the route Mappings. - -* Returned Value: -* A pointer to the new SwitchMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstSwitchMap *new; /* Pointer to new SwitchMap */ - int i; /* Loop count */ - int nin; /* No. input coordinates for SwitchMap */ - int nout; /* No. output coordinates for SwitchMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSwitchMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Check that all route Mappings have common values for Nin and Nout.*/ - nin = astGetNin( routemaps[ 0 ] ); - nout = astGetNout( routemaps[ 0 ] ); - for( i = 1; i < nroute; i++ ) { - if( nin != astGetNin( routemaps[ i ] ) ){ - if( astOK ) { - astError( AST__BADNI, "astInitSwitchMap(%s): Route Mapping " - "number %d has %d input(s) but the first route " - "Mapping has %d input(s).", status, name, i + 1, - astGetNin( routemaps[ i ] ), nin ); - } - - } else if( nout != astGetNout( routemaps[ i ] ) ){ - if( astOK ) { - astError( AST__BADNO, "astInitSwitchMap(%s): Route Mapping " - "number %d has %d output(s) but the first route " - "Mapping has %d output(s).", status, name, i + 1, - astGetNin( routemaps[ i ] ), nin ); - } - } - } - -/* If supplied, report an error if fsmap has no forward transformation, - or if it has an incorrect number of inputs or output. */ - if( fsmap && astOK ) { - if( !astGetTranForward( fsmap ) ) { - astError( AST__INTRD, "astInitSwitchMap(%s): The forward selector Mapping " - "is not able to transform coordinates in the forward direction.", status, - name ); - - } else if( astGetNin( fsmap ) != nin ){ - astError( AST__BADNI, "astInitSwitchMap(%s): The forward selector " - "Mapping has %d input(s) but the SwitchMap has %d " - "input(s).", status, name, astGetNin( fsmap ), nin ); - - } else if( astGetNout( fsmap ) != 1 ){ - astError( AST__BADNO, "astInitSwitchMap(%s): The forward selector " - "Mapping has %d outputs but should only have 1.", status, name, - astGetNout( fsmap ) ); - } - } - -/* If supplied, report an error if ismap has no inverse transformation, - or if it has an incorrect number of inputs or outputs. */ - if( ismap && astOK ) { - if( !astGetTranInverse( ismap ) ) { - astError( AST__INTRD, "astInitSwitchMap(%s): The inverse selector Mapping " - "is not able to transform coordinates in the inverse direction.", status, - name ); - } else if( nout != astGetNout( ismap ) ){ - astError( AST__BADNO, "astInitSwitchMap(%s): The inverse selector " - "Mapping has %d output(s) but the SwitchMap has %d " - "output(s).", status, name, astGetNout( ismap ), nout ); - - } else if( astGetNin( ismap ) != 1 ){ - astError( AST__BADNI, "astInitSwitchMap(%s): The inverse selector " - "Mapping has %d inputs but should only have 1.", status, name, - astGetNin( ismap ) ); - - } - } - -/* Report an error if neither ismap nor fsmap were supplied. */ - if( !fsmap && !ismap && astOK ) { - astError( AST__INTRD, "astInitSwitchMap(%s): No selector Mappings " - "supplied.", status, name ); - } - -/* Initialise a Mapping structure (the parent class) as the first component - within the SwitchMap structure, allocating memory if necessary. Specify - the number of input and output coordinates and in which directions the - Mapping should be defined. */ - if ( astOK ) { - new = (AstSwitchMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, nout, - ( fsmap != NULL ), - ( ismap != NULL ) ); - if ( astOK ) { - -/* Initialise the SwitchMap data. */ -/* --------------------------- */ -/* Store pointers to the selector Mappings. */ - new->fsmap = fsmap ? astClone( fsmap ) : NULL; - new->ismap = ismap ? astClone( ismap ) : NULL; - -/* Save the initial values of the inversion flags for these Mappings. */ - new->fsinv = fsmap ? astGetInvert( fsmap ) : 0; - new->isinv = ismap ? astGetInvert( ismap ) : 0; - -/* Create arrays for the route Mappings. */ - new->routemap = astMalloc( sizeof( AstMapping * )*nroute ); - new->routeinv = astMalloc( sizeof( int )*nroute ); - -/* Store pointers to the route Mappings and their invert flags. */ - if( astOK ) { - new->nroute = nroute; - for( i = 0; i < nroute; i++ ) { - new->routemap[ i ] = astClone( routemaps[ i ] ); - new->routeinv[ i ] = astGetInvert( routemaps[ i ] ); - } - } else { - new->nroute = 0; - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new object. */ - return new; -} - -AstSwitchMap *astLoadSwitchMap_( void *mem, size_t size, - AstSwitchMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSwitchMap - -* Purpose: -* Load a SwitchMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "switchmap.h" -* AstSwitchMap *astLoadSwitchMap( void *mem, size_t size, -* AstSwitchMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* SwitchMap loader. - -* Description: -* This function is provided to load a new SwitchMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* SwitchMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a SwitchMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the SwitchMap is to be -* loaded. This must be of sufficient size to accommodate the -* SwitchMap data (sizeof(SwitchMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the SwitchMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the SwitchMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstSwitchMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SwitchMap. If this is NULL, a pointer to -* the (static) virtual function table for the SwitchMap class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "SwitchMap" is used instead. - -* Returned Value: -* A pointer to the new SwitchMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSwitchMap *new; - AstMapping *rmap; - int i; - char buf[ 20 ]; - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SwitchMap. In this case the - SwitchMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSwitchMap ); - vtab = &class_vtab; - name = "SwitchMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSwitchMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built SwitchMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "SwitchMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Forward Selector Mapping and its Invert flag. */ -/* --------------------------------------------- */ - new->fsmap = astReadObject( channel, "fsmap", NULL ); - new->fsinv = astReadInt( channel, "fsinv", 0 ); - new->fsinv = ( new->fsinv != 0 ); - -/* Inverse Selector Mapping and its Invert flag. */ -/* --------------------------------------------- */ - new->ismap = astReadObject( channel, "ismap", NULL ); - new->isinv = astReadInt( channel, "isinv", new->fsinv ); - new->isinv = ( new->isinv != 0 ); - -/* Loop to load each route Mapping and its invert flag. */ -/* ---------------------------------------------------- */ - new->routemap = NULL; - new->routeinv = NULL; - i = 0; - while( astOK ) { - sprintf( buf, "rmap%d", i + 1 ); - rmap = astReadObject( channel, buf, NULL ); - if( rmap ) { - new->routemap = astGrow( new->routemap, i + 1, sizeof( AstMapping *) ); - new->routeinv = astGrow( new->routeinv, i + 1, sizeof( int ) ); - if( astOK ) { - new->routemap[ i ] = rmap; - sprintf( buf, "rinv%d", i + 1 ); - new->routeinv[ i ] = astReadInt( channel, buf, 0 ); - new->routeinv[ i ] = ( new->routeinv[ i ] != 0 ); - i++; - } - } else { - break; - } - } - -/* Number of route Mappings. */ - new->nroute = i; - -/* If an error occurred, clean up by deleting the new SwitchMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new SwitchMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -/* None. */ - - - - diff --git a/ast/switchmap.h b/ast/switchmap.h deleted file mode 100644 index 40c60a9..0000000 --- a/ast/switchmap.h +++ /dev/null @@ -1,289 +0,0 @@ -#if !defined( SWITCHMAP_INCLUDED ) /* Include this file only once */ -#define SWITCHMAP_INCLUDED -/* -*+ -* Name: -* switchmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the SwitchMap class. - -* Invocation: -* #include "switchmap.h" - -* Description: -* This include file defines the interface to the SwitchMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. - -* Inheritance: -* The SwitchMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astMapMerge -* Merge a SwitchMap within a sequence of Mappings. -* astTransform -* Transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsASwitchMap -* Test class membership. -* astSwitchMap -* Create a SwitchMap. -* -* Protected: -* astCheckSwitchMap -* Validate class membership. -* astInitSwitchMap -* Initialise a SwitchMap. -* astInitSwitchMapVtab -* Initialise the virtual function table for the SwitchMap class. -* astLoadSwitchMap -* Load a SwitchMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstSwitchMap -* SwitchMap object type. -* -* Protected: -* AstSwitchMapVtab -* SwitchMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 13-MAR-2006 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* SwitchMap structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstSwitchMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstMapping *fsmap; /* Pointer to forward selector Mapping */ - AstMapping *ismap; /* Pointer to inverse selector Mapping */ - int fsinv; /* Inversion flag for forward selector Mapping */ - int isinv; /* Inversion flag for inverse selector Mapping */ - int nroute; /* The number of route Mappings in the SwitchMap */ - AstMapping **routemap; /* Array of route Mapping pointers */ - int *routeinv; /* Array of inversion flags for route Mappings */ -} AstSwitchMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstSwitchMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -/* None. */ -} AstSwitchMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstSwitchMapGlobals { - AstSwitchMapVtab Class_Vtab; - int Class_Init; -} AstSwitchMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitSwitchMapGlobals_( AstSwitchMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(SwitchMap) /* Check class membership */ -astPROTO_ISA(SwitchMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstSwitchMap *astSwitchMap_( void *, void *, int, void **, const char *, int *, ...); -#else -AstSwitchMap *astSwitchMapId_( void *, void *, int, void **, const char *, ... )__attribute__((format(printf,5,6))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstSwitchMap *astInitSwitchMap_( void *, size_t, int, AstSwitchMapVtab *, - const char *, AstMapping *, AstMapping *, - int, AstMapping **, int * ); - -/* Vtab initialiser. */ -void astInitSwitchMapVtab_( AstSwitchMapVtab *, const char *, int * ); - -/* Loader. */ -AstSwitchMap *astLoadSwitchMap_( void *, size_t, AstSwitchMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -#if defined(astCLASS) /* Protected */ - -int astSwitchList_( AstSwitchMap *, int, int *, AstMapping ***, int **, int * ); - -#endif - - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckSwitchMap(this) astINVOKE_CHECK(SwitchMap,this,0) -#define astVerifySwitchMap(this) astINVOKE_CHECK(SwitchMap,this,1) - -/* Test class membership. */ -#define astIsASwitchMap(this) astINVOKE_ISA(SwitchMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astSwitchMap astINVOKE(F,astSwitchMap_) -#else -#define astSwitchMap astINVOKE(F,astSwitchMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitSwitchMap(mem,size,init,vtab,name,fsmap,ismap,nroute,routemaps) \ -astINVOKE(O,astInitSwitchMap_(mem,size,init,vtab,name,astCheckMapping(fsmap),\ - astCheckMapping(ismap),nroute,routemaps,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitSwitchMapVtab(vtab,name) astINVOKE(V,astInitSwitchMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadSwitchMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadSwitchMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) - -#define astSwitchList astSwitchList_ - -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckSwitchMap to validate SwitchMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -/* None. */ -#endif - - - - - diff --git a/ast/table.c b/ast/table.c deleted file mode 100644 index 0d283bc..0000000 --- a/ast/table.c +++ /dev/null @@ -1,5246 +0,0 @@ -/* -*class++ -* Name: -* Table - -* Purpose: -* A 2-dimensional table of values. - -* Constructor Function: -c astTable -f AST_TABLE - -* Description: -* The Table class is a type of KeyMap that represents a two-dimensional -* table of values. The -c astMapGet... and astMapPut... -f AST_MAPGET... and AST_MAPPUT... -* methods provided by the KeyMap class should be used for storing and -* retrieving values from individual cells within a Table. Each entry -* in the KeyMap represents a single cell of the table and has an -* associated key of the form "
    (i)" where "" is the -* upper-case name of a table column and "i" is the row index (the -* first row is row 1). Keys of this form should always be used when -* using KeyMap methods to access entries within a Table. -* -* Columns must be declared using the -c astAddColumn -f AST_ADDCOLUMN -* method before values can be stored within them. This also fixes the -* type and shape of the values that may be stored in any cell of the -* column. Cells may contain scalar or vector values of any data type -* supported by the KeyMap class. Multi-dimensional arrays may also be -* stored, but these must be vectorised when storing and retrieving -* them within a table cell. All cells within a single column must -* have the same type and shape, as specified when the column is added -* to the Table. -* -* Tables may have parameters that describe global properties of the -* entire table. These are stored as entries in the parent KeyMap and -* can be access using the get and set method of the KeyMap class. -* However, parameters must be declared using the -c astAddParameter -f AST_ADDPARAMETER -* method before being accessed. -* -* Note - since accessing entries within a KeyMap is a relatively slow -* process, it is not recommended to use the Table class to store -* very large tables. - -* Inheritance: -* The Table class inherits from the KeyMap class. - -* Attributes: -* In addition to those attributes common to all KeyMaps, every -* Table also has the following attributes: -* -* - ColumnLenC(column): The largest string length of any value in a column -* - ColumnLength(column): The number of elements in each value in a column -* - ColumnNdim(column): The number of axes spanned by each value in a column -* - ColumnType(column): The data type of each value in a column -* - ColumnUnit(column): The unit string describing each value in a column -* - Ncolumn: The number of columns currently in the Table -* - Nrow: The number of rows currently in the Table -* - Nparameter: The number of global parameters currently in the Table - -* Functions: -c In addition to those functions applicable to all KeyMaps, the -c following functions may also be applied to all Tables: -f In addition to those routines applicable to all KeyMaps, the -f following routines may also be applied to all Tables: -* -c - astAddColumn: Add a new column definition to a Table -c - astAddParameter: Add a new global parameter definition to a Table -c - astColumnName: Return the name of the column with a given index -c - astColumnShape: Return the shape of the values in a named column -c - astHasColumn: Checks if a column exists in a Table -c - astHasParameter: Checks if a global parameter exists in a Table -c - astParameterName: Return the name of the parameter with a given index -c - astPurgeRows: Remove all empty rows from a Table -c - astRemoveColumn: Remove a column from a Table -c - astRemoveParameter: Remove a global parameter from a Table -c - astRemoveRow: Remove a row from a Table -f - AST_ADDCOLUMN: Add a new column definition to a Table -f - AST_ADDPARAMETER: Add a new global parameter definition to a Table -f - AST_COLUMNNAME: Return the name of the column with a given index -f - AST_COLUMNSHAPE: Return the shape of the values in a named column -f - AST_HASCOLUMN: Checks if a column exists in a Table -f - AST_HASPARAMETER: Checks if a global parameter exists in a Table -f - AST_PARAMETERNAME: Return the name of the parameter with a given index -f - AST_PURGEROWS: Remove all empty rows from a Table -f - AST_REMOVECOLUMN: Remove a column from a Table -f - AST_REMOVEPARAMETER: Remove a global parameter from a Table -f - AST_REMOVEROW: Remove a row from a Table - -* Copyright: -* Copyright (C) 2010-2011 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-NOV-2010 (DSB): -* Original version. -* 13-MAY-2011 (DSB): -* Added support for table parameters. -* 16-NOV-2013 (DSB): -* Fix bug in forming keys in GetColumnLenC. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS Table - -/* Fixed KeyMap entry names */ -#define LENGTH "Length" -#define NAME "Name" -#define NROW "Nrow" -#define SHAPE "Shape" -#define SIZE "Size" -#define TYPE "Type" -#define UNIT "Unit" - -/* A function macro that puts quotes around a value */ -#define STRING(w) #w - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "keymap.h" /* Coordinate keymaps (parent class) */ -#include "channel.h" /* I/O channels */ -#include "table.h" /* Interface definition for this class */ - - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static void (* parent_setkeycase)( AstKeyMap *, int, int * ); -static void (* parent_clearkeycase)( AstKeyMap *, int * ); -static int (* parent_equal)( AstObject *, AstObject *, int * ); -static int (* parent_getobjsize)( AstObject *, int * ); -static int (* parent_mapget0a)( AstKeyMap *, const char *, AstObject * *, int *); -static int (* parent_mapget0c)( AstKeyMap *, const char *, const char **, int *); -static int (* parent_mapget0d)( AstKeyMap *, const char *, double *, int *); -static int (* parent_mapget0f)( AstKeyMap *, const char *, float *, int *); -static int (* parent_mapget0i)( AstKeyMap *, const char *, int *, int *); -static int (* parent_mapget0p)( AstKeyMap *, const char *, void **, int *); -static int (* parent_mapget0b)( AstKeyMap *, const char *, unsigned char *, int *); -static int (* parent_mapget0s)( AstKeyMap *, const char *, short int *, int *); -static int (* parent_mapget1a)( AstKeyMap *, const char *, int, int *, AstObject **, int * ); -static int (* parent_mapget1c)( AstKeyMap *, const char *, int, int, int *, char *, int * ); -static int (* parent_mapget1d)( AstKeyMap *, const char *, int, int *, double *, int * ); -static int (* parent_mapget1f)( AstKeyMap *, const char *, int, int *, float *, int * ); -static int (* parent_mapget1i)( AstKeyMap *, const char *, int, int *, int *, int * ); -static int (* parent_mapget1p)( AstKeyMap *, const char *, int, int *, void **, int * ); -static int (* parent_mapget1s)( AstKeyMap *, const char *, int, int *, short int *, int * ); -static int (* parent_mapget1b)( AstKeyMap *, const char *, int, int *, unsigned char *, int * ); -static int (* parent_mapgetelema)( AstKeyMap *, const char *, int, AstObject **, int * ); -static int (* parent_mapgetelemc)( AstKeyMap *, const char *, int, int, char *, int * ); -static int (* parent_mapgetelemd)( AstKeyMap *, const char *, int, double *, int * ); -static int (* parent_mapgetelemf)( AstKeyMap *, const char *, int, float *, int * ); -static int (* parent_mapgetelemi)( AstKeyMap *, const char *, int, int *, int * ); -static int (* parent_mapgetelemp)( AstKeyMap *, const char *, int, void **, int * ); -static int (* parent_mapgetelems)( AstKeyMap *, const char *, int, short int *, int * ); -static int (* parent_mapgetelemb)( AstKeyMap *, const char *, int, unsigned char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_mapput0a)( AstKeyMap *, const char *, AstObject *, const char *, int *); -static void (* parent_mapput0c)( AstKeyMap *, const char *, const char *, const char *, int *); -static void (* parent_mapput0d)( AstKeyMap *, const char *, double, const char *, int *); -static void (* parent_mapput0f)( AstKeyMap *, const char *, float, const char *, int *); -static void (* parent_mapput0i)( AstKeyMap *, const char *, int, const char *, int *); -static void (* parent_mapput0p)( AstKeyMap *, const char *, void *, const char *, int *); -static void (* parent_mapput0b)( AstKeyMap *, const char *, unsigned char, const char *, int *); -static void (* parent_mapput0s)( AstKeyMap *, const char *, short int, const char *, int *); -static void (* parent_mapput1a)( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * ); -static void (* parent_mapput1c)( AstKeyMap *, const char *, int, const char *const [], const char *, int * ); -static void (* parent_mapput1d)( AstKeyMap *, const char *, int, const double *, const char *, int * ); -static void (* parent_mapput1f)( AstKeyMap *, const char *, int, const float *, const char *, int * ); -static void (* parent_mapput1i)( AstKeyMap *, const char *, int, const int *, const char *, int * ); -static void (* parent_mapput1p)( AstKeyMap *, const char *, int, void *const [], const char *, int * ); -static void (* parent_mapput1b)( AstKeyMap *, const char *, int, const unsigned char *, const char *, int * ); -static void (* parent_mapput1s)( AstKeyMap *, const char *, int, const short int *, const char *, int * ); -static void (* parent_mapputelema)( AstKeyMap *, const char *, int, AstObject *, int * ); -static void (* parent_mapputelemc)( AstKeyMap *, const char *, int, const char *, int * ); -static void (* parent_mapputelemd)( AstKeyMap *, const char *, int, double, int * ); -static void (* parent_mapputelemf)( AstKeyMap *, const char *, int, float, int * ); -static void (* parent_mapputelemi)( AstKeyMap *, const char *, int, int, int * ); -static void (* parent_mapputelemp)( AstKeyMap *, const char *, int, void *, int * ); -static void (* parent_mapputelemb)( AstKeyMap *, const char *, int, unsigned char, int * ); -static void (* parent_mapputelems)( AstKeyMap *, const char *, int, short int, int * ); -static void (* parent_mapremove)( AstKeyMap *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_mapputu)( AstKeyMap *, const char *, const char *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Table) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Table,Class_Init) -#define class_vtab astGLOBAL(Table,Class_Vtab) -#define getattrib_buff astGLOBAL(Table,GetAttrib_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 101 ]; - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstTableVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstTable *astTableId_( const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstKeyMap *ColumnProps( AstTable *, int * ); -static AstKeyMap *ParameterProps( AstTable *, int * ); -static const char *ColumnName( AstTable *, int index, int * ); -static const char *ParameterName( AstTable *, int index, int * ); -static const char *GetColumnUnit( AstTable *, const char *, int * ); -static const char *TypeString( int ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetColumnLenC( AstTable *, const char *, int * ); -static int GetColumnLength( AstTable *, const char *, int * ); -static int GetColumnNdim( AstTable *, const char *, int * ); -static int GetColumnType( AstTable *, const char *, int * ); -static int GetNcolumn( AstTable *, int * ); -static int GetNparameter( AstTable *, int * ); -static int GetObjSize( AstObject *, int * ); -static int HasColumn( AstTable *, const char *, int *); -static int HasParameter( AstTable *, const char *, int *); -static int MapGet0A( AstKeyMap *, const char *, AstObject **, int * ); -static int MapGet0B( AstKeyMap *, const char *, unsigned char *, int * ); -static int MapGet0C( AstKeyMap *, const char *, const char **, int * ); -static int MapGet0D( AstKeyMap *, const char *, double *, int * ); -static int MapGet0F( AstKeyMap *, const char *, float *, int * ); -static int MapGet0I( AstKeyMap *, const char *, int *, int * ); -static int MapGet0P( AstKeyMap *, const char *, void **, int * ); -static int MapGet0S( AstKeyMap *, const char *, short int *, int * ); -static int MapGet1A( AstKeyMap *, const char *, int, int *, AstObject **, int * ); -static int MapGet1B( AstKeyMap *, const char *, int, int *, unsigned char *, int * ); -static int MapGet1C( AstKeyMap *, const char *, int, int, int *, char *, int * ); -static int MapGet1D( AstKeyMap *, const char *, int, int *, double *, int * ); -static int MapGet1F( AstKeyMap *, const char *, int, int *, float *, int * ); -static int MapGet1I( AstKeyMap *, const char *, int, int *, int *, int * ); -static int MapGet1P( AstKeyMap *, const char *, int, int *, void **, int * ); -static int MapGet1S( AstKeyMap *, const char *, int, int *, short int *, int * ); -static int MapGetElemA( AstKeyMap *, const char *, int, AstObject **, int * ); -static int MapGetElemB( AstKeyMap *, const char *, int, unsigned char *, int * ); -static int MapGetElemC( AstKeyMap *, const char *, int, int, char *, int * ); -static int MapGetElemD( AstKeyMap *, const char *, int, double *, int * ); -static int MapGetElemF( AstKeyMap *, const char *, int, float *, int * ); -static int MapGetElemI( AstKeyMap *, const char *, int, int *, int * ); -static int MapGetElemP( AstKeyMap *, const char *, int, void **, int * ); -static int MapGetElemS( AstKeyMap *, const char *, int, short int *, int * ); -static int ParseKey( AstTable *, const char *, int, char *, int *, AstKeyMap **, const char *, int * ); -static void AddColumn( AstTable *, const char *, int, int, int *, const char *, int * ); -static void AddParameter( AstTable *, const char *, int * ); -static void ColumnShape( AstTable *, const char *, int, int *, int *, int *); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void MapPut0A( AstKeyMap *, const char *, AstObject *, const char *, int * ); -static void MapPut0B( AstKeyMap *, const char *, unsigned char, const char *, int * ); -static void MapPut0C( AstKeyMap *, const char *, const char *, const char *, int * ); -static void MapPut0D( AstKeyMap *, const char *, double, const char *, int * ); -static void MapPut0F( AstKeyMap *, const char *, float, const char *, int * ); -static void MapPut0I( AstKeyMap *, const char *, int, const char *, int * ); -static void MapPut0P( AstKeyMap *, const char *, void *, const char *, int * ); -static void MapPut0S( AstKeyMap *, const char *, short int, const char *, int * ); -static void MapPut1A( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * ); -static void MapPut1B( AstKeyMap *, const char *, int, const unsigned char *, const char *, int * ); -static void MapPut1C( AstKeyMap *, const char *, int, const char *const [], const char *, int * ); -static void MapPut1D( AstKeyMap *, const char *, int, const double *, const char *, int * ); -static void MapPut1F( AstKeyMap *, const char *, int, const float *, const char *, int * ); -static void MapPut1I( AstKeyMap *, const char *, int, const int *, const char *, int * ); -static void MapPut1P( AstKeyMap *, const char *, int, void *const [], const char *, int * ); -static void MapPut1S( AstKeyMap *, const char *, int, const short int *, const char *, int * ); -static void MapPutElemA( AstKeyMap *, const char *, int, AstObject *, int * ); -static void MapPutElemB( AstKeyMap *, const char *, int, unsigned char, int * ); -static void MapPutElemC( AstKeyMap *, const char *, int, const char *, int * ); -static void MapPutElemD( AstKeyMap *, const char *, int, double, int * ); -static void MapPutElemF( AstKeyMap *, const char *, int, float, int * ); -static void MapPutElemI( AstKeyMap *, const char *, int, int, int * ); -static void MapPutElemP( AstKeyMap *, const char *, int, void *, int * ); -static void MapPutElemS( AstKeyMap *, const char *, int, short int, int * ); -static void MapPutU( AstKeyMap *, const char *, const char *, int * ); -static void PurgeRows( AstTable *, int * ); -static void RemoveColumn( AstTable *, const char *, int * ); -static void RemoveParameter( AstTable *, const char *, int * ); -static void RemoveRow( AstTable *, int, int * ); -static void SetKeyCase( AstKeyMap *, int, int * ); -static void ClearKeyCase( AstKeyMap *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static int GetNrow( AstTable *, int * ); -static void SetNrow( AstTable *, int, int * ); - -static int GetNcolumn( AstTable *, int * ); -static int GetNparameter( AstTable *, int * ); - - -/* Member functions. */ -/* ================= */ -static void AddColumn( AstTable *this, const char *name, int type, - int ndim, int *dims, const char *unit, int *status ) { -/* -*++ -* Name: -c astAddColumn -f AST_ADDCOLUMN - -* Purpose: -* Add a new column definition to a table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c void astAddColumn( AstTable *this, const char *name, int type, int ndim, -c int *dims, const char *unit ) -f CALL AST_ADDCOLUMN( THIS, NAME, TYPE, NDIM, DIMS, UNIT, STATUS ) - -* Class Membership: -* Table method. - -* Description: -* Adds the definition of a new column to the supplied table. Initially, -* the column is empty. Values may be added subsequently using the -* methods of the KeyMap class. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c name -f NAME = CHARACTER * ( * ) (Given) -* The column name. Trailing spaces are ignored (all other spaces -* are significant). The supplied string is converted to upper case. -c type -f TYPE = INTEGER (Given) -* The data type associated with the column. See "Applicability:" -* below. -c ndim -f NDIM = INTEGER (Given) -* The number of dimensions spanned by the values stored in a single -* cell of the column. Zero if the column holds scalar values. -c dims -f DIMS( NDIM ) = INTEGER (Given) -* An array holding the the lengths of each of the axes spanned by -* the values stored in a single cell of the column. Ignored if the -* column holds scalara values. -c unit -f UNIT = CHARACTER * ( * ) (Given) -* A string specifying the units of the column. Supply a blank -* string if the column is unitless. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Applicability: -* Table -* Tables can hold columns with any of the following data types - -* AST__INTTYPE (for integer), AST__SINTTYPE (for -c short int), -f INTEGER*2), -* AST__BYTETYPE (for -c unsigned bytes - i.e. unsigned chars), -f bytes), -* AST__DOUBLETYPE (for double -* precision floating point), AST__FLOATTYPE (for single -* precision floating point), AST__STRINGTYPE (for character string), -* AST__OBJECTTYPE (for AST Object pointer), AST__POINTERTYPE (for -* arbitrary C pointer) or AST__UNDEFTYPE (for undefined values -* created by -c astMapPutU). -f AST_MAPPUTU). -* FitsTable -* FitsTables can hold columns with any of the following data types - -* AST__INTTYPE (for integer), AST__SINTTYPE (for -c short int), -f INTEGER*2), -* AST__BYTETYPE (for -c unsigned bytes - i.e. unsigned chars), -f bytes), -* AST__DOUBLETYPE (for double -* precision floating point), AST__FLOATTYPE (for single -* precision floating point), AST__STRINGTYPE (for character string). - -* Notes: -* - This -c function -f routine -* returns without action if a column already exists in the Table -* with the supplied name and properties. However an error is -* reported if any of the properties differ. - -*-- -*/ - -/* Local Variables: */ - AstKeyMap *cols; /* KeyMap holding all column details */ - AstKeyMap *col_km; /* KeyMap holding new column details */ - const char *oldunit; /* Pointer to the old coumn unit string */ - int *olddims; /* Shape of pre-existing column */ - int idim; /* Axis index */ - int namlen; /* Used length of "name" */ - int nval; /* Number of values returned */ - int oldtype; /* Data type of pre-existing column */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Verify supplied values. */ - namlen = astChrLen( name ); - if( namlen == 0 ) { - astError( AST__BADKEY, "astAddColumn(%s): Illegal blank column name " - "supplied.", status, astGetClass( this ) ); - - } else if( namlen > AST__MXCOLNAMLEN ) { - astError( AST__BADKEY, "astAddColumn(%s): Column name '%s' is too " - "long (must be no more than %d characters).", status, - astGetClass( this ), name, AST__MXCOLNAMLEN ); - - } else if( ndim < 0 ) { - astError( AST__NAXIN, "astAddColumn(%s): No of axes (%d) for values in " - "new column %s is invalid.", status, astGetClass( this ), - ndim, name ); - - } else if( TypeString( type ) == NULL ) { - astError( AST__NAXIN, "astAddColumn(%s): Bad data type supplied (%d) " - "for new column %s.", status, astGetClass( this ), type, - name ); - - } else { - for( idim = 0; idim < ndim; idim++ ) { - if( dims[ idim ] < 1 ) { - astError( AST__DIMIN, "astAddColumn(%s): Length of axis %d (%d) " - "for new column %s is invalid.", status, - astGetClass( this ), idim + 1, dims[ idim ], name ); - break; - } - } - } - -/* If there is already a column with the given name, check its properties - match the supplied properties. */ - if( astOK ) { - cols = astColumnProps( this ); - if( astMapGet0A( cols, name, &col_km ) ) { - - astMapGet0I( col_km, TYPE, &oldtype ); - if( oldtype != type && astOK ) { - astError( AST__OLDCOL, "astAddColumn(%s): A column called " - "%s already exists in the table with a different " - "data type (%s).", status, astGetClass( this ), - name, TypeString( oldtype ) ); - } - - if( !astMapGet0C( col_km, UNIT, &oldunit ) ) oldunit = ""; - if( strcmp( oldunit, unit ) && astOK ) { - astError( AST__OLDCOL, "astAddColumn(%s): A column called " - "%s already exists in the table with a different " - "unit string ('%s').", status, astGetClass( this ), - name, oldunit ); - } - - if( ndim != astMapLength( col_km, SHAPE ) && astOK ) { - astError( AST__OLDCOL, "astAddColumn(%s): A column called " - "%s already exists in the table with a different " - "number of axes (%d).", status, astGetClass( this ), - name, astMapLength( col_km, SHAPE ) ); - } - - if( ndim > 0 && astOK ) { - olddims = astMalloc( sizeof( int )*ndim ); - (void) astMapGet1I( col_km, SHAPE, ndim, &nval, olddims ); - for( idim = 0; idim < ndim && astOK; idim++ ) { - if( dims[ idim ] != olddims[ idim ] ) { - astError( AST__OLDCOL, "astAddColumn(%s): A column called " - "%s already exists in the table with a different " - "shape.", status, astGetClass( this ), name ); - } - } - olddims = astFree( olddims ); - } - -/* Otherwise, add a new column to the table. */ - } else { - -/* Add a suitable entry describing the column to the Columns KeyMap. */ - col_km = astKeyMap( " ", status ); - astMapPut0C( col_km, NAME, name, NULL ); - astMapPut0I( col_km, TYPE, type, NULL ); - if( ndim ) astMapPut1I( col_km, SHAPE, ndim, dims, NULL ); - astMapPut0C( col_km, UNIT, unit, NULL ); - -/* Put the column KeyMap into the KeyMap holding details of all columns. - Use the column name as the key. */ - astMapPut0A( cols, name, col_km, NULL ); - } - -/* Annul the local KeyMap pointers. */ - col_km = astAnnul( col_km ); - cols = astAnnul( cols ); - } -} - -static void AddParameter( AstTable *this, const char *name, int *status ) { -/* -*++ -* Name: -c astAddParameter -f AST_ADDPARAMETER - -* Purpose: -* Add a new global parameter definition to a table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c void astAddParameter( AstTable *this, const char *name ) -f CALL AST_ADDPARAMETER( THIS, NAME, STATUS ) - -* Class Membership: -* Table method. - -* Description: -* Adds the definition of a new global parameter to the supplied -* table. Note, this does not store a value for the parameter. To get -* or set the parameter value, the methods of the paremt KeyMap class -* should be used, using the name of the parameter as the key. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c name -f NAME = CHARACTER * ( * ) (Given) -* The parameter name. Trailing spaces are ignored (all other spaces -* are significant). The supplied string is converted to upper case. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Unlike columns, the definition of a parameter does not specify its type, -* size or dimensionality. - -*-- -*/ - -/* Local Variables: */ - AstKeyMap *pars; /* KeyMap holding all parameter details */ - int namlen; /* Used length of "name" */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Verify supplied values. */ - namlen = astChrLen( name ); - if( namlen == 0 ) { - astError( AST__BADKEY, "astAddParameter(%s): Illegal blank parameter name " - "supplied.", status, astGetClass( this ) ); - - } else if( namlen > AST__MXCOLNAMLEN ) { - astError( AST__BADKEY, "astAddParameter(%s): Parameter name '%s' is too " - "long (must be no more than %d characters).", status, - astGetClass( this ), name, AST__MXCOLNAMLEN ); - } - -/* Do nothing if there is already a parameter with the given name. */ - if( astOK ) { - pars = astParameterProps( this ); - if( !astMapHasKey( pars, name ) ) { - -/* Add a suitable entry to the Parameters KeyMap. The value is arbitrary - and currently unused. */ - astMapPut0I( pars, name, 1, NULL ); - } - -/* Annul the local KeyMap pointer. */ - pars = astAnnul( pars ); - } -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* void ClearAttrib( AstObject *this, const char *attrib ) - -* Class Membership: -* Table member function (over-rides the astClearAttrib protected -* method inherited from the KeyMap class). - -* Description: -* This function clears the value of a specified attribute for a -* Table, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Table. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -*/ - -/* Local Variables: */ - AstTable *this; - int nc; - int len; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Table structure. */ - this = (AstTable *) this_object; - -/* Get the length of the attribute string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - /* None yet */ - -/* Define a macro to see if the attribute string matches any of the - read-only column attributes of this class. */ -#define MATCH(attr) \ - ( nc = 0, ( 0 == astSscanf( attrib, attr "(%*s)%n", &nc ) ) && \ - ( nc >= len ) ) - -/* If the name was not recognised, test if it matches any of the - read-only attributes of this class. If it does, then report an - error. */ - if ( !strcmp( attrib, "nrow" ) || - !strcmp( attrib, "ncolumn" ) || - !strcmp( attrib, "nparameter" ) || - MATCH( "columnlenc" ) || - MATCH( "columnlength" ) || - MATCH( "columnndim" ) || - MATCH( "columntype" ) || - MATCH( "columnunit" ) ) { - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } - -#undef MATCH - -} - -static void ClearKeyCase( AstKeyMap *this, int *status ) { -/* -* Name: -* ClearKeyCase - -* Purpose: -* Clear the KeyCase attribute value for a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "keymape.h" -* void ClearKeyCase( AstKeyMap *this, int *status ) - -* Class Membership: -* Table member function (over-rides the astClearKeyCase protected -* method inherited from the KeyMap class). - -* Description: -* This function clears the value of the KeyCase attribute for a -* Table. For a Table, the KeyCase attribute cannot be changed so this -* function exits without action. - -* Parameters: -* this -* Pointer to the Table. -*/ - -} - -static const char *ColumnName( AstTable *this, int index, int *status ) { -/* -*++ -* Name: -c astColumnName -f AST_COLUMNNAME - -* Purpose: -* Get the name of the column at a given index within the Table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c const char *astColumnName( AstTable *this, int index ) -f RESULT = AST_COLUMNNAME( THIS, INDEX, STATUS ) - -* Class Membership: -* Table method. - -* Description: -* This function returns a string holding the name of the column with -* the given index within the Table. -* -* This function is intended primarily as a means of iterating round all -* the columns in a Table. For this purpose, the number of columns in -* the Table is given by the Ncolumn attribute of the Table. This function -* could then be called in a loop, with the index value going from -c zero to one less than Ncolumn. -f one to Ncolumn. -* -* Note, the index associated with a column decreases monotonically with -* the age of the column: the oldest Column in the Table will have index -* one, and the Column added most recently to the Table will have the -* largest index. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c index -f INDEX = INTEGER (Given) -* The index into the list of columns. The first column has index -* one, and the last has index "Ncolumn". -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astColumnName() -c A pointer to a null-terminated string containing the -f AST_COLUMNNAME = CHARACTER * ( AST__SZCHR ) -f The -* upper case column name. - -* Notes: -c - The returned pointer is guaranteed to remain valid and the -c string to which it points will not be over-written for a total -c of 50 successive invocations of this function. After this, the -c memory containing the string may be re-used, so a copy of the -c string should be made if it is needed for longer than this. -c - A NULL pointer will be returned if this function is invoked -c with the AST error status set, or if it should fail for any -c reason. -f - A blank string will be returned if this function is invoked -f with STATUS set to an error value, or if it should fail for any -f reason. -*-- -*/ - -/* Local Variables: */ - AstKeyMap *cols; /* KeyMap holding column definitions */ - const char *result; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get apointer to the KeyMap holding all column definitions. */ - cols = astColumnProps( this ); - -/* Issue a more useful error message than that issued by astMapKey if the - index is invalid. */ - if( index < 1 || index > astMapSize( cols ) ) { - astError( AST__MPIND, "astColumnName(%s): Cannot find column " - "%d (zero-based) of the %s - invalid index.", status, - astGetClass( this ), index, astGetClass( this ) ); - } - -/* Get the column name. */ - result = astMapKey( cols, index - 1 ); - -/* Free resources. */ - cols = astAnnul( cols ); - -/* Return a pointer to the required column name. */ - return result; -} - -static AstKeyMap *ColumnProps( AstTable *this, int *status ) { -/* -*+ -* Name: -* astColumnProps - -* Purpose: -* Returns a pointer to the KeyMap holding column properties. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "table.h" -* AstKeyMap *astColumnProps( AstTable *this ) - -* Class Membership: -* Table method. - -* Description: -* This function returns a pointer to the KeyMap that holds -* definitions of all the coumns added to the Table. - -* Parameters: -* this -* Pointer to the Table. - -* Returned Value: -* A pointer to the KeyMap. It shpould be annulled using astAnnul -* when no longer needed. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Return a cloned pointer to the required KeyMap. */ - return astClone( this->columns ); -} - -static void ColumnShape( AstTable *this, const char *column, int mxdim, - int *ndim, int *dims, int *status ){ -/* -*++ -* Name: -c astColumnShape -f AST_COLUMNSHAPE - -* Purpose: -* Returns the shape of the values in a named column. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c void astColumnShape( AstTable *this, const char *column, int mxdim, -c int *ndim, int *dims ) -f CALL AST_COLUMNSHAPE( THIS, COLUMN, MXDIM, NDIM, DIMS, STATUS ) - -* Class Membership: -* Table method. - -* Description: -c This function -f This routine -* returns the number of dimensions spaned by each value in a named -* column of a Table, together with the length of each dimension. -* These are the values supplied when the column was created using -c astAddColumn. -f AST_ADDCOLUMN. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c column -f COLUMN = CHARACTER * ( * ) (Given) -* The character string holding the upper case name of the column. Trailing -* spaces are ignored. -c mxdim -f MXDIM = INTEGER (Given) -* The length of the -c "dims" array. -f DIMS array. -c ndim -f NDIM = INTEGER (Returned) -c Pointer to an int in which to return the -f The -* number of dimensions spanned by values in the named column. -* This will be zero if the column contains scalar values. -c dims -f DIMS( MXDIM ) = INTEGER (Returned) -c Pointer to an -f An -* array in which to return the length of each dimension. Any -* excess trailing elements will be filled with the value 1. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - No error is reported if the requested column cannot be found in the -* given Table. A value of zero is returned for -c "ndim" and the supplied values in "dims" -f NDIM and the supplied values in DIMS -* are left unchanged. -* - A value of zero is returned for -c "ndim" -f NDIM -* if an error occurs. - -*-- -*/ - -/* Local Variables: */ - AstKeyMap *cols; /* Pointer to KeyMap holding all column info */ - AstKeyMap *col_km; /* Pointer to KeyMap holding requested column info */ - int idim; /* Axis index */ - -/* Initialise */ - *ndim = 0; - -/* Check the inherited status. */ - if( !astOK ) return; - - -/* Get the KeyMap holding information about the requested column. */ - cols = astColumnProps( this ); - if( astMapGet0A( cols, column, &col_km ) ) { - -/* Get the shape of the column values. */ - (void) astMapGet1I( col_km, SHAPE, mxdim, ndim, dims ); - -/* Fill excess array elements with 1. */ - for( idim = *ndim; idim < mxdim; idim++ ) dims[ idim ] = 1; - -/* Free resources. */ - col_km = astAnnul( col_km ); - } - cols = astAnnul( cols ); - -/* If an error has occurred, set ndim to zero. */ - if( !astOK ) *ndim = 0; - -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two Tables are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* Table member function (over-rides the astEqual protected -* method inherited from the astKeyMap class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two Tables are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a Table). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the Tables are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstKeyMap *this_km; - AstKeyMap *that_km; - AstTable *that; - AstTable *this; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two Table structures. */ - this = (AstTable *) this_object; - that = (AstTable *) that_object; - -/* Check the second object is a Table. We know the first is a - Table since we have arrived at this implementation of the virtual - function. */ - if( astIsATable( that ) ) { - -/* Check the Tables are equal when compared as KeyMaps. */ - if( (*parent_equal)( this_object, that_object, status ) ) { - -/* Check the Columns KeyMaps are equal. */ - this_km = astColumnProps( this ); - that_km = astColumnProps( that ); - result = astEqual( this_km, that_km ); - this_km = astAnnul( this_km ); - that_km = astAnnul( that_km ); - -/* Check the Parameter KeyMaps are equal. */ - this_km = astParameterProps( this ); - that_km = astParameterProps( that ); - result = astEqual( this_km, that_km ); - this_km = astAnnul( this_km ); - that_km = astAnnul( that_km ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Table member function (over-rides the protected astGetAttrib -* method inherited from the KeyMap class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Table, formatted as a character string. - -* Parameters: -* this -* Pointer to the Table. -* attrib -* Pointer to a null terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Table, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Table. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char cname[ AST__MXCOLNAMLEN + 1 ]; /* Column name */ - AstTable *this; /* Pointer to the Table structure */ - const char *result; /* Pointer value to return */ - int ival; /* Int attribute value */ - int len; /* Length of attrib string */ - int nc; /* No. characters read by astSscanf */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Table structure. */ - this = (AstTable *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null terminated string in an - appropriate format. Set "result" to point at the result string. */ - -/* Table properties */ -/* ================ */ - -/* Ncolumn */ -/* ------- */ - if( !strcmp( attrib, "ncolumn" ) ) { - ival = astGetNcolumn( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Nrow */ -/* ---- */ - } else if( !strcmp( attrib, "nrow" ) ) { - ival = astGetNrow( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Nparameter */ -/* ---------- */ - } else if( !strcmp( attrib, "nparameter" ) ) { - ival = astGetNparameter( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - - - -/* Column properties */ -/* ================= */ - -/* A macro that gives the scannf pattern to test for a given column - property. Needed since the buffer length is defined by a macro - (AST__MXCOLNAMLEN). */ -#define PATTERN(cnam,blen) #cnam "(%" STRING(blen) "[^()])%n" - -/* ColumnNdim */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, PATTERN(columnndim,AST__MXCOLNAMLEN), - cname, &nc ) ) && ( nc >= len ) ) { - ival = astGetColumnNdim( this, cname ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* ColumnLenC */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, PATTERN(columnlenc,AST__MXCOLNAMLEN), - cname, &nc ) ) && ( nc >= len ) ) { - ival = astGetColumnLenC( this, cname ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* ColumnType */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, PATTERN(columntype,AST__MXCOLNAMLEN), - cname, &nc ) ) && ( nc >= len ) ) { - ival = astGetColumnType( this, cname ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* ColumnLength */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, PATTERN(columnlength,AST__MXCOLNAMLEN), - cname, &nc ) ) && ( nc >= len ) ) { - ival = astGetColumnLength( this, cname ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* ColumnUnit */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, PATTERN(columnunit,AST__MXCOLNAMLEN), - cname, &nc ) ) && ( nc >= len ) ) { - result = astGetColumnUnit( this, cname ); - -#undef PATTERN - - -/* Unknown attributes */ -/* ================== */ - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static int GetColumnLenC( AstTable *this, const char *column, int *status ) { -/* -*+ -* Name: -* astGetColumnLenC - -* Purpose: -* Get the maximum formatted length of any value in a column. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "table.h" -* int astGetColumnLenC( AstTable *this, const char *column ) - -* Class Membership: -* Table method. - -* Description: -* This function returns the minimum length which a character variable -* must have in order to be able to store the longest value currently -* present (at any row) in a specified column of the supplied Table. If -* the named column holds vector values, then the returned value is -* the length of the longest element of the vector value. - -* Parameters: -* this -* Pointer to the Table. -* column -* The character string holding the upper-case name of the column. -* Trailing spaces are ignored. An error is reported if the supplied -* column is not found in the Table. - -* Returned Value: -* The length (i.e. number of characters) of the longest formatted -* value associated with the named column. This does not include the -* trailing null character. - -* Notes: -* - Automatic data type conversion occurs if the named column holds -* numerical values. -* - An error will be reported if named column does not exist or cannot -* be formatted as a character -* string. -* - A function value of zero will be returned if an error has already -* occurred, or if this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - AstKeyMap *cols; /* KeyMap holding column definitions */ - char key[ AST__MXCOLKEYLEN ]; /* Current cell key string */ - int irow; /* Current row index */ - int len; /* Length needed to format current cell */ - int nrow; /* Number of rows in table */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the KeyMap holding information about all columns. */ - cols = astColumnProps( this ); - -/* Check the table contains the requested column. */ - if( astMapHasKey( cols, column ) ) { - -/* Loop round all rows in the table. */ - nrow = astGetNrow( this ); - for( irow = 1; irow <= nrow; irow++ ) { - -/* Format the cell name. */ - sprintf( key, "%.*s(%d)", (int) astChrLen(column), column, irow ); - -/* Get the maximum length needed to format a string in the current - row/column. */ - len = astMapLenC( this, key ); - -/* Return the largest value found for any row. */ - if( len > result ) result = len; - } - -/* Report an error if the column does not exist. */ - } else if( astOK ) { - astError( AST__BADCOL, "astGetColumnLenC(%s): No column named '%s' " - "exists in the table.", status, astGetClass( this ), column ); - } - -/* Free resources */ - cols = astAnnul( cols ); - -/* Return AST__BADTYPE if an error occurred. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int GetColumnLength( AstTable *this, const char *column, int *status ) { -/* -*+ -* Name: -* astGetColumnLength - -* Purpose: -* Get the number of elements in each value in a column. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "table.h" -* int astGetColumnLength( AstTable *this, const char *column ) - -* Class Membership: -* Table method. - -* Description: -* This function returns the number of elements in each value stored -* in a named column. Each value can be a scalar (in which case the -* ColumnLength attribute has a value of 1), or a multi-dimensional -* array ( in which case the ColumnLength value is equal to the -* product of the array dimensions). - -* Parameters: -* this -* Pointer to the Table. -* column -* The character string holding the upper-case name of the column. -* Trailing spaces are ignored. An error is reported if the supplied -* column is not found in the Table. - -* Returned Value: -* The number of elements in each column value. - -* Notes: -* - An error will be reported if named column does not exist or cannot -* be formatted as a character -* string. -* - A function value of zero will be returned if an error has already -* occurred, or if this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - AstKeyMap *col_km; /* KeyMap holding requested column definition */ - AstKeyMap *cols; /* KeyMap holding all column definitions */ - int *dims; /* Pointer to array holding dimensions */ - int idim; /* Index of dimension */ - int ndim; /* Number of dimensions */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the KeyMap holding information about all columns. */ - cols = astColumnProps( this ); - -/* Get the KeyMap holding information about the requested column. */ - if( astMapGet0A( cols, column, &col_km ) ) { - -/* If the Column properties includes the length, return it. Otherwise, - calculate the length and store it in the KeyMap as a column property. */ - if( ! astMapGet0I( col_km, LENGTH, &result ) ) { - -/* Get the number of axes spanned by each column value, and allocate an - array big enough to hold the dimensions of these axes. */ - ndim = astMapLength( col_km, SHAPE ); - dims = astMalloc( sizeof( int )*ndim ); - if( astOK ) { - -/* Get the dimensions. */ - astMapGet1I( col_km, SHAPE, ndim, &ndim, dims ); - -/* Find the number of elements. */ - result = 1; - for( idim = 0; idim < ndim; idim++ ) { - result *= dims[ idim ]; - } - -/* Store the result in the column KeyMap. */ - astMapPut0I( col_km, LENGTH, result, NULL ); - } - dims = astFree( dims ); - } - -/* Free resources */ - col_km = astAnnul( col_km ); - -/* Report an error if the column does not exist. */ - } else if( astOK ) { - astError( AST__BADCOL, "astGetColumnLength(%s): No column named '%s' " - "exists in the table.", status, astGetClass( this ), column ); - } - -/* Free resources */ - cols = astAnnul( cols ); - -/* Return AST__BADTYPE if an error occurred. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int GetColumnNdim( AstTable *this, const char *column, int *status ) { -/* -*+ -* Name: -* astGetColumnNdim - -* Purpose: -* Get the number of dimensions for a column in a Table. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "table.h" -* int astGetColumnNdim( AstTable *this, const char *column ) - -* Class Membership: -* Table method. - -* Description: -* This function attribute holds the number of axes spanned by each value -* in a column. If each cell in the column is a scalar, ColumnNdim will -* be zero. If each cell in the column is a 1D spectrum, ColumnNdim will -* be one. If each cell in the column is a 2D image, ColumnNdim will be -* two, etc. - -* Parameters: -* this -* Pointer to the Table. -* column -* The character string holding the upper-case name of the column. -* Trailing spaces are ignored. An error is reported if the supplied -* column is not found in the Table. - -* Returned Value: -* The number of dimensions - zero for a scalar. - -* Notes: -* - A function value of zero will be returned if an error has -* already occurred, or if this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - AstKeyMap *cols; /* KeyMap holding column definitions */ - AstKeyMap *col_km; /* Pointer to KeyMap holding column info */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the KeyMap holding information about all columns. */ - cols = astColumnProps( this ); - -/* Get the KeyMap holding information about the requested column. */ - if( astMapGet0A( cols, column, &col_km ) ) { - -/* Get the number of dimensions. */ - result = astMapLength( col_km, SHAPE ); - -/* Free resources */ - col_km = astAnnul( col_km ); - -/* Report an error if the column does not exist. */ - } else if( astOK ) { - astError( AST__BADCOL, "astGetColumnNdim(%s): No column named '%s' " - "exists in the table.", status, astGetClass( this ), column ); - } - cols = astAnnul( cols ); - -/* Return AST__BADTYPE if an error occurred. */ - if( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static int GetColumnType( AstTable *this, const char *column, int *status ) { -/* -*+ -* Name: -* astGetColumnType - -* Purpose: -* Get the data type of a column in a Table. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "table.h" -* int astGetColumnType( AstTable *this, const char *column ) - -* Class Membership: -* Table method. - -* Description: -* This function returns a value indicating the data type of a -* named column in a Table. This is the data type which was used -* when the column was added to the Table using astAddColumn. - -* Parameters: -* this -* Pointer to the Table. -* column -* The character string holding the upper-case name of the column. -* Trailing spaces are ignored. An error is reported if the supplied -* column is not found in the Table. - -* Returned Value: -* One of AST__INTTYPE (for integer), AST__SINTTYPE (for short int), -* AST__BYTETYPE (for unsigned bytes - i.e. unsigned chars), -* AST__DOUBLETYPE (for double precision floating point), -* AST__FLOATTYPE (for single precision floating point), AST__STRINGTYPE -* (for character string), AST__OBJECTTYPE (for AST Object pointer), -* AST__POINTERTYPE (for arbitrary C pointer) or AST__UNDEFTYPE (for -* undefined values created by astMapPutU). - -* Notes: -* - A function value of AST__BADTYPE will be returned if an error has -* already occurred, or if this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - AstKeyMap *cols; /* Pointer to KeyMap holding all column info */ - AstKeyMap *col_km; /* Pointer to KeyMap holding requested column info */ - int result; /* Returned value */ - -/* Initialise */ - result = AST__BADTYPE; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the KeyMap holding information about the requested column. */ - cols = astColumnProps( this ); - if( astMapGet0A( cols, column, &col_km ) ) { - -/* Get the column data type. */ - (void) astMapGet0I( col_km, TYPE, &result ); - -/* Annul the KeyMap pointer. */ - col_km = astAnnul( col_km ); - -/* Report an error if the column does not exist. */ - } else if( astOK ) { - astError( AST__BADCOL, "astGetColumnType(%s): No column named '%s' " - "exists in the table.", status, astGetClass( this ), column ); - } - cols = astAnnul( cols ); - -/* Return AST__BADTYPE if an error occurred. */ - if( !astOK ) result = AST__BADTYPE; - -/* Return the result. */ - return result; -} - -static const char *GetColumnUnit( AstTable *this, const char *column, int *status ) { -/* -*+ -* Name: -* astGetColumnUnit - -* Purpose: -* Get the unit string for a column in a Table. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "table.h" -* const char *astGetColumnUnit( AstTable *this, const char *column ) - -* Class Membership: -* Table method. - -* Description: -* This function returns the unit string for a named column in a Table. -* This is the unit string that was provided when the column was added to -* the Table using astAddColumn. - -* Parameters: -* this -* Pointer to the Table. -* column -* The character string holding the upper-case name of the column. -* Trailing spaces are ignored. An error is reported if the supplied -* column is not found in the Table. - -* Returned Value: -* A pointer to a null-terminated string containing the column units. - -*- -*/ - -/* Local Variables: */ - AstKeyMap *col_km; /* Pointer to KeyMap holding requested column info */ - AstKeyMap *cols; /* Pointer to KeyMap holding all column info */ - const char *result; /* Returned value */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the KeyMap holding information about the requested column. */ - cols = astColumnProps( this ); - if( astMapGet0A( cols, column, &col_km ) ) { - -/* Get the column unit string. */ - (void) astMapGet0C( col_km, UNIT, &result ); - -/* Annul the KeyMap pointer. */ - col_km = astAnnul( col_km ); - -/* Report an error if the column does not exist. */ - } else if( astOK ) { - astError( AST__BADCOL, "astGetColumnUnit(%s): No column named '%s' " - "exists in the table.", status, astGetClass( this ), column ); - } - cols = astAnnul( cols ); - -/* Return NULL if an error occurred. */ - if( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static int GetNcolumn( AstTable *this, int *status ) { -/* -*+ -* Name: -* astGetNcolumn - -* Purpose: -* Get the number of columns in a Table. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "table.h" -* int astGetNcolumn( AstTable *this ) - -* Class Membership: -* Table method. - -* Description: -* This function returns the number of columns currently in the Table. - -* Parameters: -* this -* Pointer to the Table. - -* Returned Value: -* Number of columns. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstKeyMap *cols; - int result; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get a pointer to the KeyMap holding the column definitions. */ - cols = astColumnProps( this ); - -/* Get the number of column definitions in the KeyMap. */ - result = astMapSize( cols ); - -/* Annul the KeyMap pointer. */ - cols = astAnnul( cols ); - -/* Return the result. */ - return result; -} - -static int GetNparameter( AstTable *this, int *status ) { -/* -*+ -* Name: -* astGetNparameter - -* Purpose: -* Get the number of global parameters in a Table. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "table.h" -* int astGetNparameter( AstTable *this ) - -* Class Membership: -* Table method. - -* Description: -* This function returns the number of global parameters currently in the Table. - -* Parameters: -* this -* Pointer to the Table. - -* Returned Value: -* Number of parameters. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstKeyMap *pars; - int result; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get a pointer to the KeyMap holding the parameter definitions. */ - pars = astParameterProps( this ); - -/* Get the number of parameter definitions in the KeyMap. */ - result = astMapSize( pars ); - -/* Annul the KeyMap pointer. */ - pars = astAnnul( pars ); - -/* Return the result. */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* Table member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied Tables, -* in bytes. - -* Parameters: -* this -* Pointer to the Table. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Table size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstKeyMap *km; /* KeyMap holding column/parameter definitions */ - AstTable *this; /* Pointer to Table structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the Table structure. */ - this = (AstTable *) this_object; - -/* Invoke the GetObjSize method inherited from the parent KeyMap class, and - then add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - km = astColumnProps( this ); - result += astGetObjSize( km ); - km = astAnnul( km ); - - km = astParameterProps( this ); - result += astGetObjSize( km ); - km = astAnnul( km ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int HasColumn( AstTable *this, const char *column, int *status ){ -/* -*++ -* Name: -c astHasColumn -f AST_HASCOLUMN - -* Purpose: -* Returns a flag indicating if a column is present in a Table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c int astHasColumn( AstTable *this, const char *column ) -f RESULT = AST_HASCOLUMN( THIS, COLUMN, STATUS ) - -* Class Membership: -* Table method. - -* Description: -c This function -f This routine -* returns a flag indicating if a named column exists in a Table, for -* instance, by having been added to to the Table using -c astAddColumn. -f AST_ADDCOLUMN. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c column -f COLUMN = CHARACTER * ( * ) (Given) -* The character string holding the upper case name of the column. Trailing -* spaces are ignored. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - A value of -c zero -f .FALSE. -* is returned for if an error occurs. - -*-- -*/ - -/* Local Variables: */ - AstKeyMap *cols; - int result; - -/* Initialise */ - result = 0; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get the KeyMap holding information about all columns. */ - cols = astColumnProps( this ); - -/* Seeif it contains an entry for the named column. */ - result = astMapHasKey( cols, column ); - -/* Free resources. */ - cols = astAnnul( cols ); - -/* If an error has occurred, return zero. */ - if( !astOK ) result = 0; - return result; -} - -static int HasParameter( AstTable *this, const char *parameter, int *status ){ -/* -*++ -* Name: -c astHasParameter -f AST_HASPARAMETER - -* Purpose: -* Returns a flag indicating if a named global parameter is present in a Table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c int astHasParameter( AstTable *this, const char *parameter ) -f RESULT = AST_HASPARAMETER( THIS, PARAMETER, STATUS ) - -* Class Membership: -* Table method. - -* Description: -c This function -f This routine -* returns a flag indicating if a named parameter exists in a Table, for -* instance, by having been added to to the Table using -c astAddParameter. -f AST_ADDPARAMETER. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c parameter -f PARAMETER = CHARACTER * ( * ) (Given) -* The character string holding the upper case name of the parameter. Trailing -* spaces are ignored. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - A value of -c zero -f .FALSE. -* is returned for if an error occurs. - -*-- -*/ - -/* Local Variables: */ - AstKeyMap *pars; - int result; - -/* Initialise */ - result = 0; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Get the KeyMap holding information about all parameters. */ - pars = astParameterProps( this ); - -/* See if it contains an entry for the named parameter. */ - result = astMapHasKey( pars, parameter ); - -/* Free resources. */ - pars = astAnnul( pars ); - -/* If an error has occurred, return zero. */ - if( !astOK ) result = 0; - return result; -} - -void astInitTableVtab_( AstTableVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitTableVtab - -* Purpose: -* Initialise a virtual function table for a Table. - -* Type: -* Protected function. - -* Synopsis: -* #include "table.h" -* void astInitTableVtab( AstTableVtab *vtab, const char *name ) - -* Class Membership: -* Table vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Table class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstKeyMapVtab *keymap; /* Pointer to KeyMap component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitKeyMapVtab( (AstKeyMapVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsATable) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstKeyMapVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->AddColumn = AddColumn; - vtab->AddParameter = AddParameter; - vtab->ColumnName = ColumnName; - vtab->ParameterName = ParameterName; - vtab->ColumnProps = ColumnProps; - vtab->ColumnShape = ColumnShape; - vtab->GetColumnLenC = GetColumnLenC; - vtab->GetColumnLength = GetColumnLength; - vtab->GetColumnNdim = GetColumnNdim; - vtab->GetColumnType = GetColumnType; - vtab->GetColumnUnit = GetColumnUnit; - vtab->GetNcolumn = GetNcolumn; - vtab->GetNparameter = GetNparameter; - vtab->GetNrow = GetNrow; - vtab->HasColumn = HasColumn; - vtab->HasParameter = HasParameter; - vtab->ParameterProps = ParameterProps; - vtab->PurgeRows = PurgeRows; - vtab->RemoveColumn = RemoveColumn; - vtab->RemoveParameter = RemoveParameter; - vtab->RemoveRow = RemoveRow; - vtab->SetNrow = SetNrow; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - keymap = (AstKeyMapVtab *) vtab; - - parent_equal = object->Equal; - object->Equal = Equal; - - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_mapremove = keymap->MapRemove; - -/* Define convenience macros for overriding methods inherited from the - parent KeyMap class using all data type supported by KeyMap. */ -#define OVERRIDE(method,code,methodlc,codelc) \ - parent_##methodlc##codelc = keymap->method##code; \ - keymap->method##code = method##code; \ - -#define OVERRIDE_METHOD(method,methodlc) \ - OVERRIDE(method,A,methodlc,a) \ - OVERRIDE(method,P,methodlc,p) \ - OVERRIDE(method,C,methodlc,c) \ - OVERRIDE(method,D,methodlc,d) \ - OVERRIDE(method,F,methodlc,f) \ - OVERRIDE(method,I,methodlc,i) \ - OVERRIDE(method,S,methodlc,s) \ - OVERRIDE(method,B,methodlc,b) - -/* Use these macros to override the required methods. */ - OVERRIDE_METHOD(MapPut0,mapput0) - OVERRIDE_METHOD(MapGet0,mapget0) - OVERRIDE_METHOD(MapPut1,mapput1) - OVERRIDE_METHOD(MapGet1,mapget1) - OVERRIDE_METHOD(MapPutElem,mapputelem) - OVERRIDE_METHOD(MapGetElem,mapgetelem) - OVERRIDE(MapPut,U,mapput,u) - OVERRIDE(SetKeyCase,,setkeycase,) - OVERRIDE(ClearKeyCase,,clearkeycase,) - -/* Remove the macros. */ -#undef OVERRIDE_METHOD -#undef OVERRIDE - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "Table", "Two-dimensional table of data values" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* Table member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstTable *this; /* Pointer to Table structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the Table structure. */ - this = (AstTable *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result && this->columns ) result = astManageLock( this->columns, mode, extra, - fail ); - - if( !result && this->parameters ) result = astManageLock( this->parameters, mode, extra, - fail ); - -/* Return the result. */ - return result; -} -#endif - -/* -* Name: -* MapGet0 - -* Purpose: -* Get a scalar value from a cell of a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* int MapGet0( AstKeyMap *this, const char *key, type *value ); - -* Class Membership: -* Table member function (over-rides the astMapGet0 method inherited -* from the KeyMap class). - -* Description: -* This is a set of functions for retrieving a scalar value from a -* cell of a Table. You should replace in the generic function name -* MapGet0 by an appropriate 1-character type code (see the "Data -* Type Codes" section in the astMapGet0 docs). The stored value is -* converted to the data type indiced by before being returned (an -* error is reported if it is not possible to convert the stored value -* to the requested data type). - -* Parameters: -* this -* Pointer to the Table. -* key -* A character string identifying the cell from which the value is -* to be retrieved. It should have the form "COLNAME(irow)", where -* "COLNAME" is replaced by the name of a column that has been -* defined previously using the astAddColumn method, and "irow" is -* an integer row index (the first row is row 1). -* value -* A pointer to a buffer in which to return the requested value. -* If the requested cell is not found, or if it is found but has an -* undefined value (see astMapPutU), then the contents of the buffer -* on entry to this function will be unchanged on exit. For pointer -* types ("A" and "C"), the buffer should be a suitable pointer, and -* the address of this pointer should be supplied as the "value" -* parameter. -* status -* Pointer to inherited status value. - -* Returned Value: -* A non-zero value is returned if the requested key name was found, and -* does not have an undefined value (see astMapPutU). Zero is returned -* otherwise. - -* Notes: -* - No error is reported if the requested cell cannot be found in the -* given KeyMap, but a zero value will be returned as the function value. -* The supplied buffer will be returned unchanged. -* - Key names are case insensitive, and white space is considered -* significant. -* - If the stored value is a vector value, then the first value in -* the vector will be returned. -* - A string pointer returned by astMapGet0C is guaranteed to remain -* valid and the string to which it points will not be over-written for -* a total of 50 successive invocations of this function. After this, -* the memory containing the string may be re-used, so a copy of -* the string should be made if it is needed for longer than this. -* - If the returned value is an AST Object pointer, the Object's reference -* count is incremented by this call. Any subsequent changes made to -* the Object using the returned pointer will be reflected in any -* any other active pointers for the Object. The returned pointer -* should be annulled using astAnnul when it is no longer needed. -*/ - -/* Define a macro to implement the function for a specific data type. */ -#define MAKE_MAPGET0(X,Xlc,Xtype,Itype) \ -static int MapGet0##X( AstKeyMap *this_keymap, const char *key, Xtype *value, \ - int *status ) { \ -\ -/* Local Variables: */ \ - AstTable *this; /* Pointer to Table structure */ \ - char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \ - int irow; /* Row index within key string */ \ - int result; /* Returned flag */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Get a pointer to the Table structure. */ \ - this = (AstTable *) this_keymap; \ -\ -/* If the key is the name of a global table parameter, use the parent \ - method to get the value of hte parameter. */ \ - if( astHasParameter( this, key ) ) { \ - result = (*parent_mapget0##Xlc)( this_keymap, key, value, status ); \ -\ -/* Check the supplied key looks like a table cell key, and get the \ - the column name and the row number. Also checks that the table \ - contains a column with the specified name. */ \ - } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, \ - NULL, "astMapGet0" #X, status ) ) { \ -\ -/* If the row index is larger than the current number of rows in the \ - table, do nothing more. */ \ - if( irow <= astGetNrow( this ) ){ \ -\ -/* Use the astMapGet0 method in the parent keyMap class to get the \ - cell contents. */ \ - result = (*parent_mapget0##Xlc)( this_keymap, key, value, status ); \ - } \ - } \ -\ -/* If an error occurred, return zero. */ \ - if( !astOK ) result = 0; \ -\ -/* Return the result.*/ \ - return result; \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPGET0(I,i,int,AST__INTTYPE) -MAKE_MAPGET0(D,d,double,AST__DOUBLETYPE) -MAKE_MAPGET0(F,f,float,AST__FLOATTYPE) -MAKE_MAPGET0(C,c,const char *,AST__STRINGTYPE) -MAKE_MAPGET0(A,a,AstObject *,AST__OBJECTTYPE) -MAKE_MAPGET0(P,p,void *,AST__POINTERTYPE) -MAKE_MAPGET0(S,s,short int,AST__SINTTYPE) -MAKE_MAPGET0(B,b,unsigned char,AST__BYTETYPE) - -/* Undefine the macro. */ -#undef MAKE_MAPGET0 - -/* -* Name: -* MapGet1 - -* Purpose: -* Get a vector value from a cell of a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* int MapGet1( AstKeyMap *this, const char *key, int mxval, -* int *nval, type *value ) -* int MapGet1C( AstKeyMap *this, const char *key, int l, int mxval, -* int *nval, const char *value ) - -* Class Membership: -* Table member function (over-rides the astMapGet1 method inherited -* from the KeyMap class). - -* Description: -* This is a set of functions for retrieving a vector value from a -* cell of a Table. You should replace in the generic function name -* MapGet1 by an appropriate 1-character type code (see the "Data -* Type Codes" section in the astMapGet1 docs). The stored value is -* converted to the data type indiced by before being returned (an -* error is reported if it is not possible to convert the stored value -* to the requested data type). -* -* Note, the MapGet1C function has an extra parameter "l" which -* specifies the maximum length of each string to be stored in the -* "value" buffer (see the "astMapGet1C" docs). - -* Parameters: -* this -* Pointer to the Table. -* key -* A character string identifying the cell from which the value is -* to be retrieved. It should have the form "COLNAME(irow)", where -* "COLNAME" is replaced by the name of a column that has been -* defined previously using the astAddColumn method, and "irow" is -* an integer row index (the first row is row 1). -* mxval -* The number of elements in the "value" array. -* nval -* The address of an integer in which to put the number of elements -* stored in the "value" array. Any unused elements of the array are -* left unchanged. -* value -* A pointer to an array in which to return the requested values. -* If the requested cell is not found, or if it is found but has an -* undefined value (see astMapPutU), then the contents of the buffer -* on entry to this function will be unchanged on exit. -* status -* Pointer to inherited status value. - -* Returned Value: -* A non-zero value is returned if the requested key name was found, and -* does not have an undefined value (see astMapPutU). Zero is returned -* otherwise. - -* MapGet1C: -* The "value" buffer supplied to the MapGet1C function should be a -* pointer to a character array with "mxval*l" elements, where "l" is -* the maximum length of a string to be returned. The value of "l" -* should be supplied as an extra parameter following "key" when -* invoking MapGet1C, and should include space for a terminating -* null character. - -* Notes: -* - No error is reported if the requested cell cannot be found in the -* given KeyMap, but a zero value will be returned as the function value. -* The supplied buffer will be returned unchanged. -* - Key names are case insensitive, and white space is considered -* significant. -* - If the stored value is a scalar value, then the value will be -* returned in the first element of the supplied array, and "nval" -* will be returned set to 1. -*/ - -/* Define a macro to implement the function for a specific data type - (excluding "C" since that needs an extra parameter). */ -#define MAKE_MAPGET1(X,Xlc,Xtype,Itype) \ -static int MapGet1##X( AstKeyMap *this_keymap, const char *key, int mxval, int *nval, \ - Xtype *value, int *status ) { \ -\ -/* Local Variables: */ \ - AstTable *this; /* Pointer to Table structure */ \ - char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \ - int irow; /* Row index within key string */ \ - int result; /* Returned flag */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Get a pointer to the Table structure. */ \ - this = (AstTable *) this_keymap; \ -\ -/* If the key is the name of a global table parameter, use the parent \ - method to get the value of hte parameter. */ \ - if( astHasParameter( this, key ) ) { \ - result = (*parent_mapget1##Xlc)( this_keymap, key, mxval, nval, \ - value, status ); \ -\ -/* Check the supplied key looks like a table cell key, and get the \ - the column name and the row number. Also checks that the table \ - contains a column with the specified name. */ \ - } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, \ - NULL, "astMapGet1" #X, status ) ) { \ -\ -/* If the row index is larger than the current number of rows in the \ - table, do nothing more. */ \ - if( irow <= astGetNrow( this ) ){ \ -\ -/* Use the astMapGet1 method in the parent keyMap class to get the \ - cell contents. */ \ - result = (*parent_mapget1##Xlc)( this_keymap, key, mxval, nval, \ - value, status ); \ - } \ - } \ -\ -/* If an error occurred, return zero. */ \ - if( !astOK ) result = 0; \ -\ -/* Return the result.*/ \ - return result; \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPGET1(I,i,int,AST__INTTYPE) -MAKE_MAPGET1(D,d,double,AST__DOUBLETYPE) -MAKE_MAPGET1(F,f,float,AST__FLOATTYPE) -MAKE_MAPGET1(A,a,AstObject *,AST__OBJECTTYPE) -MAKE_MAPGET1(P,p,void *,AST__POINTERTYPE) -MAKE_MAPGET1(S,s,short int,AST__SINTTYPE) -MAKE_MAPGET1(B,b,unsigned char,AST__BYTETYPE) - -/* Undefine the macro. */ -#undef MAKE_MAPGET1 - - -static int MapGet1C( AstKeyMap *this_keymap, const char *key, int l, int mxval, - int *nval, char *value, int *status ) { -/* -* Name: -* MapGet1C - -* Purpose: -* Get a vector value from a cell of a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* int MapGet1C( AstKeyMap *this, const char *key, int l, int mxval, -* int *nval, const char *value ) - -* Class Membership: -* Table member function (over-rides the astMapGet1C method inherited -* from the KeyMap class). - -* Description: -* This is the implementation of MapGet1 for = "C". We -* cannot use the MAKE_MAPGET1 macro for this because the string -* version of this function has an extra parameter giving the maximum -* length of each string which can be stored in the supplied buffer. - -* Parameters: -* (see MapGet1) -*/ - -/* Local Variables: */ - AstTable *this; /* Pointer to Table structure */ - char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ - int irow; /* Row index within key string */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Table structure. */ - this = (AstTable *) this_keymap; - -/* If the key is the name of a global table parameter, use the parent - method to get the value of hte parameter. */ - if( astHasParameter( this, key ) ) { - result = (*parent_mapget1c)( this_keymap, key, l, mxval, nval, - value, status ); - -/* Check the supplied key looks like a table cell key, and get the - the column name and the row number. Also checks that the table - contains a column with the specified name. */ - } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, - NULL, "astMapGet1C", status ) ) { - -/* If the row index is larger than the current number of rows in the - table, do nothing more. */ - if( irow <= astGetNrow( this ) ){ - -/* Use the astMapGet1 method in the parent keyMap class to get the - cell contents. */ - result = (*parent_mapget1c)( this_keymap, key, l, mxval, nval, - value, status ); - } - } - -/* If an error occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the result.*/ - return result; -} - -/* -* Name: -* MapGetElem - -* Purpose: -* Get a single element of a vector value from a cell of a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* int MapGetElem( AstKeyMap *this, const char *key, int elem, -* type *value, int *status ) -* int MapGetElemC( AstKeyMap *this, const char *key, int l, int elem, -* char *value, int *status ) - -* Class Membership: -* Table member function (over-rides the astMapGetElem method inherited -* from the KeyMap class). - -* Description: -* This is a set of functions for retrieving a single element of a vector -* value from a cell of a Table. You should replace in the generic -* function name MapGetElem by an appropriate 1-character type code -* (see the "Data Type Codes" section in the astMapGetElem docs). The -* stored value is converted to the data type indiced by before being -* returned (an error is reported if it is not possible to convert the -* stored value to the requested data type). -* -* Note, the MapGetElemC function has an extra parameter "l" which -* specifies the maximum length of each string to be stored in the -* "value" buffer (see the "MapGetElemC" docs). - -* Parameters: -* this -* Pointer to the Table. -* key -* A character string identifying the cell from which the value is -* to be retrieved. It should have the form "COLNAME(irow)", where -* "COLNAME" is replaced by the name of a column that has been -* defined previously using the astAddColumn method, and "irow" is -* an integer row index (the first row is row 1). -* elem -* The index of the vector element to modify, starting at zero. -* If the index is outside the range of the vector, an error will -* be reported. -* value -* A pointer to a buffer in which to return the requested values. -* If the requested cell is not found, or if it is found but has an -* undefined value (see astMapPutU), then the contents of the buffer -* on entry to this function will be unchanged on exit. -* status -* Pointer to inherited status value. - -* Returned Value: -* A non-zero value is returned if the requested key name was found, and -* does not have an undefined value (see astMapPutU). Zero is returned -* otherwise. - -* MapGetElemC: -* The "value" buffer supplied to the MapGetElemC function should be a -* pointer to a character array with "l" elements, where "l" is -* the maximum length of a string to be returned. The value of "l" -* should be supplied as an extra parameter following "key" when -* invoking MapGetElemC, and should include space for a terminating -* null character. - -* Notes: -* - No error is reported if the requested cell cannot be found in the -* given KeyMap, but a zero value will be returned as the function value. -* The supplied buffer will be returned unchanged. -* - Key names are case insensitive, and white space is considered -* significant. -* - If the stored value is a scalar value, then the value will be -* returned in the first element of the supplied array, and "nval" -* will be returned set to 1. -*/ - -/* Define a macro to implement the function for a specific data type -(excluding "C" since that needs an extra parameter). */ -#define MAKE_MAPGETELEM(X,Xlc,Xtype,Itype) \ -static int MapGetElem##X( AstKeyMap *this_keymap, const char *key, int elem, \ - Xtype *value, int *status ) { \ -\ -/* Local Variables: */ \ - AstTable *this; /* Pointer to Table structure */ \ - char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \ - int irow; /* Row index within key string */ \ - int result; /* Returned flag */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Get a pointer to the Table structure. */ \ - this = (AstTable *) this_keymap; \ -\ -/* If the key is the name of a global table parameter, use the parent \ - method to get the value of hte parameter. */ \ - if( astHasParameter( this, key ) ) { \ - result = (*parent_mapgetelem##Xlc)( this_keymap, key, elem, \ - value, status ); \ -\ -/* Check the supplied key looks like a table cell key, and get the \ - the column name and the row number. Also checks that the table \ - contains a column with the specified name. */ \ - } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, \ - NULL, "astMapGetElem" #X, status ) ) { \ -\ -/* If the row index is larger than the current number of rows in the \ - table, do nothing more. */ \ - if( irow <= astGetNrow( this ) ){ \ -\ -/* Use the astMapGetElem method in the parent keyMap class to get the \ - cell contents. */ \ - result = (*parent_mapgetelem##Xlc)( this_keymap, key, elem, \ - value, status ); \ - } \ - } \ -\ -/* If an error occurred, return zero. */ \ - if( !astOK ) result = 0; \ -\ -/* Return the result.*/ \ - return result; \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPGETELEM(I,i,int,AST__INTTYPE) -MAKE_MAPGETELEM(D,d,double,AST__DOUBLETYPE) -MAKE_MAPGETELEM(F,f,float,AST__FLOATTYPE) -MAKE_MAPGETELEM(A,a,AstObject *,AST__OBJECTTYPE) -MAKE_MAPGETELEM(P,p,void *,AST__POINTERTYPE) -MAKE_MAPGETELEM(S,s,short int,AST__SINTTYPE) -MAKE_MAPGETELEM(B,b,unsigned char,AST__BYTETYPE) - -/* Undefine the macro. */ -#undef MAKE_MAPGETELEM - -static int MapGetElemC( AstKeyMap *this_keymap, const char *key, int l, - int elem, char *value, int *status ) { -/* -* Name: -* MapGetElemC - -* Purpose: -* Get a single element of a vector value from a cell of a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* int MapGetElemC( AstKeyMap *this, const char *key, int l, int elem, -* char *value, int *status ) - -* Class Membership: -* Table member function (over-rides the astMapGetElemC method inherited -* from the KeyMap class). - -* Description: -* This is the implementation of MapGetElem for = "C". We -* cannot use the MAKE_MAPGETELEM macro for this because the string -* version of this function has an extra parameter giving the maximum -* length of each string which can be stored in the supplied buffer. - -* Parameters: -* (see MapGetElem) -*/ - -/* Local Variables: */ - AstTable *this; /* Pointer to Table structure */ - char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ - int irow; /* Row index within key string */ - int result; /* Returned flag */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the Table structure. */ - this = (AstTable *) this_keymap; - -/* If the key is the name of a global table parameter, use the parent - method to get the value of hte parameter. */ - if( astHasParameter( this, key ) ) { - result = (*parent_mapgetelemc)( this_keymap, key, l, elem, - value, status ); - -/* Check the supplied key looks like a table cell key, and get the - the column name and the row number. Also checks that the table - contains a column with the specified name. */ - } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, - NULL, "astMapGetElemC", status ) ) { - -/* If the row index is larger than the current number of rows in the - table, do nothing more. */ - if( irow <= astGetNrow( this ) ){ - -/* Use the astMapGetElem method in the parent keyMap class to get the - cell contents. */ - result = (*parent_mapgetelemc)( this_keymap, key, l, elem, - value, status ); - } - } - -/* If an error occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the result.*/ - return result; -} - -/* -* Name: -* MapPut0 - -* Purpose: -* Stores a scalar value in a cell of a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* void MapPut0( AstKeyMap *this, const char *key, type value, -* const char *comment, int *status ) - -* Class Membership: -* Table member function (over-rides the astMapPut0 method inherited -* from the KeyMap class). - -* Description: -* This is a set of functions for storing a scalar value in a cell of -* a Table. You should use a function which matches the data type of the -* data you wish to add to the Table by replacing in the generic -* function name MapPut0 by an appropriate 1-character type code (see -* the "Data Type Codes" section in the astMapPut0 docs). - -* Parameters: -* this -* Pointer to the Table in which to store the supplied value. -* key -* A character string identifying the cell in which the value is -* to be stored. It should have the form "COLNAME(irow)", where -* "COLNAME" is replaced by the name of a column that has been -* defined previously using the astAddColumn method, and "irow" is -* an integer row index (the first row is row 1). -* value -* The value to be stored. The data type of this value should match -* the 1-character type code appended to the function name (e.g. if -* you are using astMapPut0A, the type of this value should be "pointer -* to AstObject"). An error will be reported if this data type is -* different to the data type assigned to the column when it was -* created via astAddColumn. -* comment -* A pointer to a null-terminated comment string to be stored with the -* value. A NULL pointer may be supplied, in which case no comment is -* stored. -* status -* Pointer to inherited status value. - -* Notes: -* - Key names are case insensitive, and white space is considered -* significant. -* - The new value will replace any old value already stored in the -* Table for the specified cell. -* - If the stored value is an AST Object pointer, the Object's reference -* count is incremented by this call. Any subsequent changes made to -* the Object using the returned pointer will be reflected in any -* any other active pointers for the Object, including any obtained -* later using astMapget0A. The reference count for the Object will be -* decremented when the KeyMap is destroyed, or the entry is removed or -* over-written with a different pointer. - -*/ -/* Define a macro to implement the function for a specific data type. */ -#define MAKE_MAPPUT0(X,Xlc,Xtype,Itype,ValExp) \ -static void MapPut0##X( AstKeyMap *this_keymap, const char *key, Xtype value, \ - const char *comment, int *status ) { \ -\ -/* Local Variables: */ \ - AstKeyMap *col_km; /* KeyMap holding details of the requested column */ \ - AstTable *this; /* Pointer to Table structure */ \ - char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \ - int irow; /* Row index within key string */ \ - int type; /* Data type of the requested column */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Get a pointer to the Table structure. */ \ - this = (AstTable *) this_keymap; \ -\ -/* If the key is the name of a global table parameter, use the parent \ - method to put the value of the parameter. */ \ - if( astHasParameter( this, key ) ) { \ - (*parent_mapput0##Xlc)( this_keymap, key, value, comment, status ); \ -\ -/* Check the supplied key looks like a table cell key, and get the \ - the column name and the row number. Also checks that the table \ - contains a column with the specified name. */ \ - } else if( ParseKey( this, key, 1, colname, &irow, &col_km, "astMapPut0" #X, \ - status ) ) { \ -\ -/* Check the column holds scalar values of the type implied by the \ - code in the function name. */ \ - (void) astMapGet0I( col_km, TYPE, &type ); \ - if( type != Itype && astOK ) { \ - astError( AST__BADTYP, "astMapPut0" #X "(%s): Failed to store a " \ - #Xtype " value for cell \"%s\": column %s holds %s " \ - "values.", status, astGetClass( this ), key, colname, \ - TypeString( type ) ); \ - } \ -\ - if( astMapHasKey( col_km, SHAPE ) && astOK ) { \ - astError( AST__BADTYP, "astMapPut0" #X "(%s): Failed to store a " \ - "scalar value for cell \"%s\": column %s holds vector " \ - " values.", status, astGetClass( this ), key, colname ); \ - } \ -\ -/* If the row index is larger than the current number of rows in the \ - table, update the number of rows in the table. */ \ - if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); \ -\ -/* Use the astMapPut0 method in the parent keyMap class to store the \ - new cell contents. */ \ - (*parent_mapput0##Xlc)( this_keymap, key, value, comment, status ); \ -\ -/* Free resources. */ \ - col_km = astAnnul( col_km ); \ - } \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPPUT0(I,i,int,AST__INTTYPE,value) -MAKE_MAPPUT0(D,d,double,AST__DOUBLETYPE,value) -MAKE_MAPPUT0(F,f,float,AST__FLOATTYPE,value) -MAKE_MAPPUT0(C,c,const char *,AST__STRINGTYPE,astStore(NULL,value,strlen(value)+1)) -MAKE_MAPPUT0(A,a,AstObject *,AST__OBJECTTYPE,(value?astClone(value):NULL)) -MAKE_MAPPUT0(P,p,void *,AST__POINTERTYPE,value) -MAKE_MAPPUT0(S,s,short int,AST__SINTTYPE,value) -MAKE_MAPPUT0(B,b,unsigned char,AST__BYTETYPE,value) - -/* Undefine the macro. */ -#undef MAKE_MAPPUT0 - -/* -* Name: -* MapPut1 - -* Purpose: -* Stores a vectorised value in a cell of a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* void MapPut1( AstKeyMap *this, const char *key, int size, -* const type value[], const char *comment, -* int *status ); - -* Class Membership: -* Table member function (over-rides the astMapPut1 method inherited -* from the KeyMap class). - -* Description: -* This is a set of functions for storing a vectorised value in a cell of -* a Table. You should use a function which matches the data type of the -* data you wish to add to the Table by replacing in the generic -* function name MapPut1 by an appropriate 1-character type code (see -* the "Data Type Codes" section in the astMapPut1 docs). - -* Parameters: -* this -* Pointer to the Table in which to store the supplied value. -* key -* A character string identifying the cell in which the value is -* to be stored. It should have the form "COLNAME(irow)", where -* "COLNAME" is replaced by the name of a column that has been -* defined previously using the astAddColumn method, and "irow" is -* an integer row index (the first row is row 1). -* size -* The number of elements in the supplied array of values. -* value -* The value to be stored. The data type of this value should match -* the 1-character type code appended to the function name (e.g. if -* you are using astMapPut0A, the type of this value should be "pointer -* to AstObject"). An error will be reported if this data type is -* different to the data type assigned to the column when it was -* created via astAddColumn. -* comment -* A pointer to a null-terminated comment string to be stored with the -* value. A NULL pointer may be supplied, in which case no comment is -* stored. -* status -* Pointer to inherited status value. - -* Notes: -* - Key names are case insensitive, and white space is considered -* significant. -* - The new value will replace any old value already stored in the -* Table for the specified cell. - -*/ - -/* Define a macro to implement the function for a specific data type. */ -#define MAKE_MAPPUT1(X,Xlc,Xtype,Itype,ValExp) \ -static void MapPut1##X( AstKeyMap *this_keymap, const char *key, int size, \ - Xtype value[], const char *comment, \ - int *status ) { \ -\ -/* Local Variables: */ \ - AstTable *this; /* Pointer to Table structure */ \ - char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \ - int irow; /* Row index within key string */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Get a pointer to the Table structure. */ \ - this = (AstTable *) this_keymap; \ -\ -/* If the key is the name of a global table parameter, use the parent \ - method to put the value of the parameter. */ \ - if( astHasParameter( this, key ) ) { \ - (*parent_mapput1##Xlc)( this_keymap, key, size, value, \ - comment, status ); \ -\ -/* Check the supplied key looks like a table cell key, and get the \ - the column name and the row number. Also checks that the table \ - contains a column with the specified name. */ \ - } else if( ParseKey( this, key, 1, colname, &irow, NULL, "astMapPut1" #X, \ - status ) ) { \ -\ -/* Check the column holds vector values of the type implied by the \ - code in the function name. */ \ - if( astGetColumnType( this, colname ) != Itype && astOK ) { \ - astError( AST__BADTYP, "astMapPut1" #X "(%s): Failed to store " \ - #Xtype " values for cell \"%s\": column %s holds %s values.", \ - status, astGetClass( this ), key, colname, \ - TypeString( astGetColumnType( this, colname ) ) ); \ - } \ -\ -/* Check the column holds vectors with length equal to the supplied vector. */ \ - if( astGetColumnLength( this, colname ) != size && astOK ) { \ - astError( AST__BADTYP, "astMapPut1" #X "(%s): Failed to " \ - "store a vector value for cell \"%s\": column " \ - "%s needs %d values per cell but %d were supplied.", \ - status, astGetClass( this ), key, colname, \ - astGetColumnLength( this, colname ), size ); \ - } \ -\ -/* If all is OK, update the number of rows in the table if required, and \ - store the vector in the parent KeyMap. */ \ - if( astOK ) { \ - if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); \ - (*parent_mapput1##Xlc)( this_keymap, key, size, value, \ - comment, status ); \ - } \ -\ - } \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPPUT1(D,d,const double,AST__DOUBLETYPE,value[i]) -MAKE_MAPPUT1(F,f,const float,AST__FLOATTYPE,value[i]) -MAKE_MAPPUT1(I,i,const int,AST__INTTYPE,value[i]) -MAKE_MAPPUT1(C,c,const char *const,AST__STRINGTYPE,astStore(NULL,value[i],strlen(value[i])+1)) -MAKE_MAPPUT1(A,a,AstObject *const,AST__OBJECTTYPE,(value[i]?astClone(value[i]):NULL)) -MAKE_MAPPUT1(P,p,void *const,AST__POINTERTYPE,value[i]) -MAKE_MAPPUT1(S,s,const short int,AST__SINTTYPE,value[i]) -MAKE_MAPPUT1(B,b,const unsigned char,AST__BYTETYPE,value[i]) - -/* Undefine the macro. */ -#undef MAKE_MAPPUT1 - -/* -* Name: -* MapPutElem - -* Purpose: -* Put a value into an element of a vector value in a cell of a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* void MapPutElem( AstKeyMap *this, const char *key, int elem, -* type *value, int *status ) - -* Class Membership: -* Table member function (over-rides the astMapPutElem method inherited -* from the KeyMap class). - -* Description: -* This is a set of functions for storing a value in a single element -* of a vector value stored in a cell of a Table. You should use a -* function which matches the data type of the data you wish to add to -* the Table by replacing in the generic function name MapPutElem -* by an appropriate 1-character type code (see the "Data Type Codes" -* section in the astMapPutElem docs). - -* Parameters: -* this -* Pointer to the Table in which to store the supplied value. -* key -* A character string identifying the cell in which the value is -* to be stored. It should have the form "COLNAME(irow)", where -* "COLNAME" is replaced by the name of a column that has been -* defined previously using the astAddColumn method, and "irow" is -* an integer row index (the first row is row 1). -* elem -* The index of the vector element to modify, starting at zero. -* If the index is outside the range of the vector, an error will -* be reported. -* value -* The value to be stored. The data type of this value should match -* the 1-character type code appended to the function name (e.g. if -* you are using astMapPut0A, the type of this value should be "pointer -* to AstObject"). An error will be reported if this data type is -* different to the data type assigned to the column when it was -* created via astAddColumn. -* status -* Pointer to inherited status value. - -* Notes: -* - Key names are case insensitive, and white space is considered -* significant. -* - The new value will replace any old value already stored in the -* Table for the specified cell. -* - If the stored value is an AST Object pointer, the Object's reference -* count is incremented by this call. Any subsequent changes made to -* the Object using the returned pointer will be reflected in any -* any other active pointers for the Object, including any obtained -* later using astMapget0A. The reference count for the Object will be -* decremented when the KeyMap is destroyed, or the entry is removed or -* over-written with a different pointer. - -*/ -/* Define a macro to implement the function for a specific data type. */ - -#define MAKE_MAPPUTELEM(X,Xlc,Xtype,Itype) \ -static void MapPutElem##X( AstKeyMap *this_keymap, const char *key, int elem, \ - Xtype value, int *status ) { \ -\ -/* Local Variables: */ \ - AstTable *this; /* Pointer to Table structure */ \ - char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \ - int irow; /* Row index within key string */ \ - int type; /* Data type of the requested column */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Get a pointer to the Table structure. */ \ - this = (AstTable *) this_keymap; \ -\ -/* If the key is the name of a global table parameter, use the parent \ - method to put the value of the parameter. */ \ - if( astHasParameter( this, key ) ) { \ - (*parent_mapputelem##Xlc)( this_keymap, key, elem, value, \ - status ); \ -\ -/* Check the supplied key looks like a table cell key, and get the \ - the column name and the row number. Also checks that the table \ - contains a column with the specified name. */ \ - } else if( ParseKey( this, key, 1, colname, &irow, NULL, "astMapPutElem" #X, \ - status ) ) { \ -\ -/* Check the column holds vector values of the type implied by the \ - code in the function name. */ \ - type = astGetColumnType( this, colname ); \ - if( type != Itype && astOK ) { \ - astError( AST__BADTYP, "astMapPutElem" #X "(%s): Failed to store a " \ - #Xtype " value in cell \"%s\": column %s holds %s values.", \ - status, astGetClass( this ), key, colname, \ - TypeString( type ) ); \ - } \ -\ -/* Check the column holds vectors with length equal to the supplied vector. */ \ - if( astGetColumnLength( this, colname ) <= elem && astOK ) { \ - astError( AST__BADTYP, "astMapPutElem" #X "(%s): Failed to " \ - "store a value for element %d (zero-based) of " \ - "cell \"%s\": column %s has only %d values per " \ - "cell.", status, astGetClass( this ), elem, key, \ - colname, astGetColumnLength( this, colname ) ); \ - } \ -\ -/* If all is OK, update the number of rows in the table if required, and \ - store the value in the parent KeyMap. */ \ - if( astOK ) { \ - if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); \ - (*parent_mapputelem##Xlc)( this_keymap, key, elem, value, \ - status ); \ - } \ - } \ -} - -/* Expand the above macro to generate a function for each required - data type. */ -MAKE_MAPPUTELEM(I,i,int,AST__INTTYPE) -MAKE_MAPPUTELEM(D,d,double,AST__DOUBLETYPE) -MAKE_MAPPUTELEM(F,f,float,AST__FLOATTYPE) -MAKE_MAPPUTELEM(A,a,AstObject *,AST__OBJECTTYPE) -MAKE_MAPPUTELEM(P,p,void *,AST__POINTERTYPE) -MAKE_MAPPUTELEM(C,c,const char *,AST__STRINGTYPE) -MAKE_MAPPUTELEM(S,s,short int,AST__SINTTYPE) -MAKE_MAPPUTELEM(B,b,unsigned char,AST__BYTETYPE) - -/* Undefine the macro. */ -#undef MAKE_MAPPUTELEM - -static void MapPutU( AstKeyMap *this_keymap, const char *key, const char *comment, - int *status ) { -/* -* Name: -* MapPutU - -* Purpose: -* Stores a undefined value in a cell of a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* void MapPutU( AstKeyMap *this, const char *key, const char *comment, -* int *status ) - -* Class Membership: -* Table member function (over-rides the astMapPutU method inherited -* from the KeyMap class). - -* Description: -* This function adds a new cell to a Table, but no value is stored with -* the cell. The cell therefore has a special data type represented by -* symbolic constant AST__UNDEFTYPE. -* -* An example use is to add cells with undefined values to a Table -* prior to locking them with the MapLocked attribute. Such cells -* can act as placeholders for values that can be added to the KeyMap -* later. - -* Parameters: -* this -* Pointer to the Table in which to store the supplied value. -* key -* A character string identifying the cell in which the value is -* to be stored. It should have the form "COLNAME(irow)", where -* "COLNAME" is replaced by the name of a column that has been -* defined previously using the astAddColumn method, and "irow" is -* an integer row index (the first row is row 1). -* comment -* A pointer to a null-terminated comment string to be stored with the -* value. A NULL pointer may be supplied, in which case no comment is -* stored. -* status -* Pointer to inherited status value. - -* Notes: -* - Key names are case insensitive, and white space is considered -* significant. -* - The new undefined value will replace any old value already stored in -* the Table for the specified cell. - -*/ - -/* Local Variables: */ - AstTable *this; /* Pointer to Table structure */ - char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ - int irow; /* Row index within key string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the Table structure. */ - this = (AstTable *) this_keymap; - -/* If the key is the name of a global table parameter, use the parent - method to put the value of the parameter. */ - if( astHasParameter( this, key ) ) { - (*parent_mapputu)( this_keymap, key, comment, status ); - -/* Check the supplied key looks like a table cell key, and get the - the column name and the row number. Also checks that the table - contains a column with the specified name. */ - } else if( ParseKey( this, key, 1, colname, &irow, NULL, "astMapPutU", - status ) ) { - -/* If the row index is larger than the current number of rows in the - table, update the number of rows in the table. */ - if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); - -/* Use the astMapPutU method in the parent keyMap class to store the - new cell contents. */ - (*parent_mapputu)( this_keymap, key, comment, status ); - } -} - -static const char *ParameterName( AstTable *this, int index, int *status ) { -/* -*++ -* Name: -c astParameterName -f AST_PARAMETERNAME - -* Purpose: -* Get the name of the global parameter at a given index within the Table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c const char *astParameterName( AstTable *this, int index ) -f RESULT = AST_PARAMETERNAME( THIS, INDEX, STATUS ) - -* Class Membership: -* Table method. - -* Description: -* This function returns a string holding the name of the global parameter with -* the given index within the Table. -* -* This function is intended primarily as a means of iterating round all -* the parameters in a Table. For this purpose, the number of parameters in -* the Table is given by the Nparameter attribute of the Table. This function -* could then be called in a loop, with the index value going from -c zero to one less than Nparameter. -f one to Nparameter. -* -* Note, the index associated with a parameter decreases monotonically with -* the age of the parameter: the oldest Parameter in the Table will have index -* one, and the Parameter added most recently to the Table will have the -* largest index. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c index -f INDEX = INTEGER (Given) -* The index into the list of parameters. The first parameter has index -* one, and the last has index "Nparameter". -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astParameterName() -c A pointer to a null-terminated string containing the -f AST_PARAMETERNAME = CHARACTER * ( AST__SZCHR ) -f The -* upper case parameter name. - -* Notes: -c - The returned pointer is guaranteed to remain valid and the -c string to which it points will not be over-written for a total -c of 50 successive invocations of this function. After this, the -c memory containing the string may be re-used, so a copy of the -c string should be made if it is needed for longer than this. -c - A NULL pointer will be returned if this function is invoked -c with the AST error status set, or if it should fail for any -c reason. -f - A blank string will be returned if this function is invoked -f with STATUS set to an error value, or if it should fail for any -f reason. -*-- -*/ - -/* Local Variables: */ - AstKeyMap *pars; /* KeyMap holding parameter definitions */ - const char *result; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get apointer to the KeyMap holding all parameter definitions. */ - pars = astParameterProps( this ); - -/* Issue a more useful error message than that issued by astMapKey if the - index is invalid. */ - if( index < 1 || index > astMapSize( pars ) ) { - astError( AST__MPIND, "astParameterName(%s): Cannot find parameter " - "%d (zero-based) of the %s - invalid index.", status, - astGetClass( this ), index, astGetClass( this ) ); - } - -/* Get the parameter name. */ - result = astMapKey( pars, index - 1 ); - -/* Free resources. */ - pars = astAnnul( pars ); - -/* Return a pointer to the required parameter name. */ - return result; -} - -static AstKeyMap *ParameterProps( AstTable *this, int *status ) { -/* -*+ -* Name: -* astParameterProps - -* Purpose: -* Returns a pointer to the KeyMap holding parameter properties. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "table.h" -* AstKeyMap *astParameterProps( AstTable *this ) - -* Class Membership: -* Table method. - -* Description: -* This function returns a pointer to the KeyMap that holds -* definitions of all the parameters added to the Table. - -* Parameters: -* this -* Pointer to the Table. - -* Returned Value: -* A pointer to the KeyMap. It should be annulled using astAnnul -* when no longer needed. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Return a cloned pointer to the required KeyMap. */ - return astClone( this->parameters ); -} - -static int ParseKey( AstTable *this, const char *key, int report, - char colname[ AST__MXCOLNAMLEN + 1 ], int *irow, - AstKeyMap **col_km, const char *method, int *status ){ -/* -* Name: -* ParseKey - -* Purpose: -* Find the column name and row index in a KeyMap key. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* int ParseKey( AstTable *this, const char *key, int report, -* char colname[ AST__MXCOLNAMLEN + 1 ], int *irow, -* AstKeyMap **col_km, const char *method, int *status ) - -* Class Membership: -* Table member function - -* Description: -* This function checks that the supplied KeyMap key conforms to the -* format expected for Table cells: i.e. "COLNAME(irow)", where -* "COLNAME" is the name of a column and "irow" is an integer row -* index (the first row is row 1), An error is reported if this is -* not the case. - -* Parameters: -* this -* Pointer to the table. -* key -* The key string to test. -* report -* If non-zero, an error will be reported if the key does not -* correspond to a cell of an existing column. Otherwise, no -* error will be reported. -* colname -* A buffer in which to return the column name. -* irow -* Address of an int in which to return the row index. -* col_km -* Address of a KeyMap pointer in which to return a pointer to the -* KeyMap holding the information about the column. The returned -* KeyMap pointer should be annulled using astAnnul when no lngerr -* needed. If "col_km" is NULL, no KeyMap pointer is returned. -* method -* Pointer to a string holding the name of the method to include in -* any error message. -* status -* Address of the inherited status value. - -* Returned Value: -* Zero is returned if the key is not a valid Table cell key, or if an -* error occurs. - -*/ - -/* Local Variables: */ - AstKeyMap *cols; /* KeyMap holding column definitions */ - int result; /* Returned flag */ - int collen; /* Length of column name */ - int nctot; /* Number of characters read */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Check the supplied key looks like a table cell key, and extract the - column name and row number. */ - nctot = 0; - if( 1 == astSscanf( key, "%*[^(]%n(%d) %n", &collen, irow, &nctot ) - && ( nctot >= strlen( key ) ) ) { - -/* Check the column name is not too long. */ - if( collen > AST__MXCOLNAMLEN ) { - if( report ) { - astError( AST__BADKEY, "%s(%s): Failed to store a value for cell " - "\"%s\": column name is too long.", status, method, - astGetClass( this ), key ); - } - -/* Check the row index is positive. */ - } else if( *irow < 1 ) { - if( report ) { - astError( AST__BADKEY, "%s(%s): Failed to store a value for cell " - "\"%s\": row index %d is invalid.", status, method, - astGetClass( this ), key, *irow ); - } - -/* If the key looks OK so far... */ - } else { - -/* Convert the column name to upper case and store in the returned buffer. */ - astChrCase( key, colname, 1, collen + 1 ); - colname[ collen ] = 0; - -/* check that the column exists in the Table, returning a pointer to the - column KeyMap is reequired. */ - cols = astColumnProps( this ); - if( col_km ) { - result = astMapGet0A( cols, colname, col_km ); - } else { - result = astMapHasKey( cols, colname ); - } - cols = astAnnul( cols ); - -/* Report an error if the table does not contain the specified column. */ - if( !result && astOK && report) { - astError( AST__BADKEY, "%s(%s): Failed to store a value for " - "cell \"%s\": the table does not contain a column " - "called '%s'.", status, method, astGetClass( this ), - key, colname ); - } - } - -/* Report an error if the cell key has the wrong format. */ - } else if( report ) { - astError( AST__BADKEY, "%s(%s): Failed to store a value for cell " - "\"%s\": the cell name is invalid.", status, method, - astGetClass( this ), key ); - } - -/* Return the result.*/ - return result; -} - -static void PurgeRows( AstTable *this, int *status ) { -/* -*++ -* Name: -c astPurgeRows -f AST_PURGEROWS - -* Purpose: -* Remove all empty rows from a table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c void astPurgeRows( AstTable *this ) -f CALL AST_PURGEROWS( THIS, STATUS ) - -* Class Membership: -* Table method. - -* Description: -* This function removes all empty rows from the Table, renaming -* the key associated with each table cell accordingly. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - char newkey[ AST__MXCOLKEYLEN + 1 ]; /* New cell key string */ - char oldkey[ AST__MXCOLKEYLEN + 1 ]; /* Old cell key string */ - const char *col; /* Column name */ - const char *key; /* Pointer to key string */ - const char *op; /* Pointer to opening parenthesis */ - int *w1; /* Work space pointer */ - int icol; /* Column index */ - int inew; /* New row index */ - int iold; /* Old row index */ - int ncol; /* Number of columns in table */ - int nrow; /* Number of rows in table */ - int reset; /* Start a new pass through the KeyMap? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the number of rows in the table. */ - nrow = astGetNrow( this ); - -/* Create workspace to hold the number of defined values stored in each - row. Initialise every row to have zero defined values. */ - w1 = astCalloc( nrow, sizeof( int ) ); - if( astOK ) { - -/* Iterate round all keys in the KeyMap. */ - reset = 1; - while( ( key = astMapIterate( this, reset ) ) && astOK ) { - reset = 0; - -/* Extract the row number from the key. */ - op = strchr( key, '(' ); - if( !op || astSscanf( op + 1, "%d", &iold ) != 1 || - iold > nrow ) { - astError( AST__INTER, "astPurgeRows(%s): Illegal key '%s' " - "found in a %s (internal programming error).", - status, astGetClass( this ), key, astGetClass( this ) ); - -/* Increment the number of values in this row. Note row indices are - one-based. */ - } else { - w1[ iold - 1 ]++; - } - } - -/* Loop round all columns in the Table. */ - ncol = astGetNcolumn( this ); - inew = nrow; - for( icol = 1; icol <= ncol; icol++ ) { - -/* Get the column name */ - col = astColumnName( this, icol ); - -/* Loop round all the old row numbers. Skip empty rows.*/ - inew = 0; - for( iold = 0; iold < nrow; iold++ ) { - if( w1[ iold ] > 0 ) { - -/* Increment the row number to use in place of the old row number. If the - old and new row numbers are the same, we do not need to rename the cell. */ - if( iold != inew++ ) { - -/* For the old and new cell names */ - sprintf( oldkey, "%s(%d)", col, iold + 1 ); - sprintf( newkey, "%s(%d)", col, inew ); - -/* Rename the KeyMap entry. */ - astMapRename( this, oldkey, newkey ); - } - } - } - -/* If all rows were used, we do not need to check any more columns. */ - if( iold == inew ) break; - } - -/* Store the new number of rows. */ - astSetNrow( this, inew ); - } - -/* Free resources. */ - w1 = astFree( w1 ); - -} - -static void RemoveColumn( AstTable *this, const char *name, int *status ) { -/* -*++ -* Name: -c astRemoveColumn -f AST_REMOVECOLUMN - -* Purpose: -* Remove a column from a table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c void astRemoveColumn( AstTable *this, const char *name ) -f CALL AST_REMOVECOLUMN( THIS, NAME, STATUS ) - -* Class Membership: -* Table method. - -* Description: -* This function removes a specified column from the supplied table. -* The -c function -f routine -* returns without action if the named column does not exist in the -* Table (no error is reported). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c name -f NAME = CHARACTER * ( * ) (Given) -* The column name. Trailing spaces are ignored (all other spaces -* are significant). Case is significant. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - AstKeyMap *cols; /* KeyMap holding column definitions */ - char key[ AST__MXCOLKEYLEN + 1 ]; /* Cell key string */ - int irow; /* Row index */ - int namlen; /* Used length of "name" */ - int nrow; /* Number of rows in table */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Verify supplied values. */ - namlen = astChrLen( name ); - if( namlen == 0 ) { - astError( AST__BADKEY, "astRemoveColumn(%s): Illegal blank column name " - "supplied.", status, astGetClass( this ) ); - } - -/* Get the number of rows in the table. */ - nrow = astGetNrow( this ); - -/* If there is no column with the given name in the Table, do nothing more. */ - cols = astColumnProps( this ); - if( astOK && astMapHasKey( cols, name ) ) { - -/* Remove the column description from the columns keymap. */ - astMapRemove( cols, name ); - -/* Remove any column cells with defined values from the parent KeyMap. */ - for( irow = 1; irow <= nrow; irow++ ) { - sprintf( key, "%.*s(%d)", namlen, name, irow ); - (*parent_mapremove)( (AstKeyMap *) this, key, status ); - } - } - cols = astAnnul( cols ); -} - -static void RemoveParameter( AstTable *this, const char *name, int *status ) { -/* -*++ -* Name: -c astRemoveParameter -f AST_REMOVEPARAMETER - -* Purpose: -* Remove a global parameter from a table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c void astRemoveParameter( AstTable *this, const char *name ) -f CALL AST_REMOVEPARAMETER( THIS, NAME, STATUS ) - -* Class Membership: -* Table method. - -* Description: -* This function removes a specified global parameter from the supplied table. -* The -c function -f routine -* returns without action if the named parameter does not exist in the -* Table (no error is reported). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c name -f NAME = CHARACTER * ( * ) (Given) -* The parameter name. Trailing spaces are ignored (all other spaces -* are significant). Case is significant. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - AstKeyMap *pars; /* KeyMap holding parameter definitions */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Verify supplied values. */ - if( astChrLen( name ) == 0 ) { - astError( AST__BADKEY, "astRemoveParameter(%s): Illegal blank parameter name " - "supplied.", status, astGetClass( this ) ); - } - -/* If there is no parameter with the given name in the Table, do nothing more. */ - pars = astParameterProps( this ); - if( astOK && astMapHasKey( pars, name ) ) { - -/* Remove the parameter description from the parameters keymap. */ - astMapRemove( pars, name ); - -/* Remove any entry holding the parameter value from the parent KeyMap. */ - (*parent_mapremove)( (AstKeyMap *) this, name, status ); - } - pars = astAnnul( pars ); -} - -static void RemoveRow( AstTable *this, int index, int *status ) { -/* -*++ -* Name: -c astRemoveRow -f AST_REMOVEROW - -* Purpose: -* Remove a row from a table. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "table.h" -c void astRemoveRow( AstTable *this, int index ) -f CALL AST_REMOVEROW( THIS, INDEX, STATUS ) - -* Class Membership: -* Table method. - -* Description: -* This function removes a specified row from the supplied table. -* The -c function -f routine -* returns without action if the row does not exist in the -* Table (no error is reported). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Table. -c index -f INDEX = INTEGER (Given) -* The index of the row to be removed. The first row has index 1. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - AstKeyMap *cols; /* KeyMap holding column definitions */ - char key[ AST__MXCOLKEYLEN + 1 ]; /* Cell key string */ - const char *col; /* Column name */ - int icol; /* Column index */ - int ncol; /* Number of columns in table */ - int nrow; /* Number of rows in table */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the number of rows in the table. */ - nrow = astGetNrow( this ); - -/* Do nothing if the specified row is out of bounds. */ - if( index > 0 && index <= nrow ) { - -/* Loop round all columns in the table. */ - cols = astColumnProps( this ); - ncol = astMapSize( cols ); - for( icol = 0; icol < ncol; icol++ ) { - col = astMapKey( cols, icol ); - -/* Remove the cell of the current column at the requested row. */ - sprintf( key, "%s(%d)", col, index ); - (*parent_mapremove)( (AstKeyMap *) this, key, status ); - } - cols = astAnnul( cols ); - -/* If the removed row was the last row, reduce the number of rows in the - Table. */ - if( index == nrow ) astSetNrow( this, index - 1 ); - } -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* Table member function (over-rides the astSetAttrib protected -* method inherited from the KeyMap class). - -* Description: -* This function assigns an attribute value for a Table, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Table. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstTable *this; /* Pointer to the Table structure */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Table structure. */ - this = (AstTable *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - /* None as yet */ - -/* Define a macro to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -#define MATCH2(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "(%*s) =%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -/* If the attribute was not recognised, use this macro to report an error - if a read-only attribute has been specified. */ - if ( MATCH( "ncolumn" ) || - MATCH( "nparameter" ) || - MATCH( "nrow" ) || - MATCH2( "columnlenc" ) || - MATCH2( "columnlength" ) || - MATCH2( "columnndim" ) || - MATCH2( "columntype" ) || - MATCH2( "columnunit" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -#undef MATCH2 -} - -static void SetKeyCase( AstKeyMap *this, int keycase, int *status ) { -/* -* Name: -* SetKeyCase - -* Purpose: -* Set a value for the KeyCase attribute value for a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "keymape.h" -* void SetKeyCase( AstKeyMap *this, int keycase, int *status ) - -* Class Membership: -* Table member function (over-rides the astSetKeyCase protected -* method inherited from the KeyMap class). - -* Description: -* This function assigns a new valeu to the KeyCase attribute for a -* Table. For a Table, the KeyCase attribute cannot be changed so this -* function exits without action. - -* Parameters: -* this -* Pointer to the Table. -* keycase -* The new value to set. -*/ - -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Table member function (over-rides the astTestAttrib protected -* method inherited from the KeyMap class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Table's attributes. - -* Parameters: -* this -* Pointer to the Table. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - int len; /* Length of attribute string */ - int nc; /* Number of characters read by astSscanf */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the length of the attribute string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - /* None as yet */ - -/* Define a macro to see if the attribute string matches any of the - read-only column attributes of this class. */ -#define MATCH(attr) \ - ( nc = 0, ( 0 == astSscanf( attrib, attr "(%*s)%n", &nc ) ) && \ - ( nc >= len ) ) - -/* If the name is not recognised, test if it matches any of the - read-only attributes of this class. If it does, then return - zero. */ - if ( !strcmp( attrib, "ncolumn" ) || - !strcmp( attrib, "nparameter" ) || - !strcmp( attrib, "nrow" ) || - MATCH( "columnlenc" ) || - MATCH( "columnlength" ) || - MATCH( "columnndim" ) || - MATCH( "columntype" ) || - MATCH( "columnunit" ) ) { - result = 0; - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; - -#undef MATCH -} - -static const char *TypeString( int type ) { -/* -* Name: -* TypeString - -* Purpose: -* Return a pointer to a string describing a data type. - -* Type: -* Private function. - -* Synopsis: -* const char *TypeString( int type ); - -* Description: -* This function returns a pointer to a string describing a data type. - -* Parameters: -* type -* The integer data type code. - -* Returned Value: -* Pointer to a a string descirbing the data type (typically the C -* data type). - -*/ - -/* Local Variables: */ - const char *result; - -/* Compare the supplied type code against each supported value. */ - if( type == AST__INTTYPE ) { - result = "int"; - - } else if( type == AST__BYTETYPE ) { - result = "byte"; - - } else if( type == AST__DOUBLETYPE ) { - result = "double"; - - } else if( type == AST__STRINGTYPE ) { - result = "string"; - - } else if( type == AST__OBJECTTYPE ) { - result = "Object"; - - } else if( type == AST__FLOATTYPE ) { - result = "float"; - - } else if( type == AST__POINTERTYPE ) { - result = "pointer"; - - } else if( type == AST__SINTTYPE ) { - result = "short int"; - - } else if( type == AST__UNDEFTYPE ) { - result = "undefined"; - - } else { - result = NULL; - } - -/* Return the result. */ - return result; -} - - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* -*att++ -* Name: -* ColumnLenC(column) - -* Purpose: -* The largest string length of any value in a column - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute holds the minimum length which a character variable -* must have in order to be able to store the longest value currently -* present (at any row) in a specified column of the supplied Table. -c This does not include room for a trailing null character. -* The required column name should be placed inside the parentheses in -* the attribute name. If the named column holds vector values, then -* the attribute value is the length of the longest element of the -* vector value. - -* Applicability: -* Table -* All Tables have this attribute. - -* Notes: -* - If the named column holds numerical values, the length returned -* is the length of the largest string that would be generated if the -* column values were accessed as strings. - -*att-- -*/ - -/* -*att++ -* Name: -* ColumnLength(column) - -* Purpose: -* The number of elements in each value in a column - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute holds the number of elements in each value stored -* in a named column. Each value can be a scalar (in which case the -* ColumnLength attribute has a value of 1), or a multi-dimensional -* array ( in which case the ColumnLength value is equal to the -* product of the array dimensions). - -* Applicability: -* Table -* All Tables have this attribute. - -*att-- -*/ - -/* -*att++ -* Name: -* ColumnNdim(column) - -* Purpose: -* The number of axes spanned by each value in a column - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute holds the number of axes spanned by each value in a -* column. If each cell in the column is a scalar, ColumnNdim will be -* zero. If each cell in the column is a 1D spectrum, ColumnNdim will -* be one. If each cell in the column is a 2D image, ColumnNdim will be -* two, etc. The required column name should be placed inside the -* parentheses in the attribute name. - -* Applicability: -* Table -* All Tables have this attribute. - -*att-- -*/ - -/* -*att++ -* Name: -* ColumnType(column) - -* Purpose: -* The data type of each value in a column - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute holds a integer value indicating the data type of -* a named column in a Table. This is the data type which was used -* when the column was added to the Table using astAddColumn. The -* required column name should be placed inside the parentheses in -* the attribute name. -* -* The attribute value will be one of AST__INTTYPE (for integer), -* AST__SINTTYPE (for -c short int), -f INTEGER*2), -* AST__BYTETYPE (for -c unsigned bytes - i.e. unsigned chars), -f bytes), -* AST__DOUBLETYPE (for double -* precision floating point), AST__FLOATTYPE (for single -* precision floating point), AST__STRINGTYPE (for character string), -* AST__OBJECTTYPE (for AST Object pointer), AST__POINTERTYPE (for -* arbitrary C pointer) or AST__UNDEFTYPE (for undefined values -* created by -c astMapPutU). -f AST_MAPPUTU). - -* Applicability: -* Table -* All Tables have this attribute. - -*att-- -*/ - -/* -*att++ -* Name: -* Ncolumn - -* Purpose: -* The number of columns in the table. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute holds the number of columns currently in the table. Columns -* are added and removed using the -c astAddColumn and astRemoveColumn -f AST_ADDCOLUMN and AST_REMOVECOLUMN -* functions. - -* Applicability: -* Table -* All Tables have this attribute. - -*att-- -*/ - -/* -*att++ -* Name: -* Nparameter - -* Purpose: -* The number of global parameters in the table. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute holds the number of global parameters currently in the table. -* Parameters are added and removed using the -c astAddParameter and astRemoveParameter -f AST_ADDPARAMETER and AST_REMOVEPARAMETER -* functions. - -* Applicability: -* Table -* All Tables have this attribute. - -*att-- -*/ - -/* -*att++ -* Name: -* Nrow - -* Purpose: -* The number of rows in the table. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute holds the index of the last row to which any -* contents have been added using any of the -* astMapPut... -* AST_MAPPUT... -* functions. The first row has index 1. - -* Applicability: -* Table -* All Tables have this attribute. - -*att-- -*/ -astMAKE_GET(Table,Nrow,int,0,this->nrow) -astMAKE_SET(Table,Nrow,int,nrow,value) - - - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Table objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Table objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Mappings within the Table. -*/ - -/* Local Variables: */ - AstTable *in; /* Pointer to input Table */ - AstTable *out; /* Pointer to output Table */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Tables. */ - in = (AstTable *) objin; - out = (AstTable *) objout; - -/* Make copies of the component KeyMaps and store pointers to them in the - output Table structure. */ - out->columns = in->columns ? astCopy( in->columns ) : NULL; - out->parameters = in->parameters ? astCopy( in->parameters ) : NULL; -} - - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Table objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Table objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstTable *this; /* Pointer to Table */ - -/* Obtain a pointer to the Table structure. */ - this = (AstTable *) obj; - -/* Annul the pointers to the component KeyMaps. */ - if( this->columns ) this->columns = astAnnul( this->columns ); - if( this->parameters ) this->parameters = astAnnul( this->parameters ); - -} - - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Table objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Table class to an output Channel. - -* Parameters: -* this -* Pointer to the Table whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstTable *this; /* Pointer to the Table structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Table structure. */ - this = (AstTable *) this_object; - -/* Write out values representing the instance variables for the Table - class. Note, the primitive data in the Table will be written out - by the parent KeyMap Dump function. This function deals just with the - extra information held in the Table structure. */ - -/* Write out the number of rows in the table. */ - astWriteInt( channel, "Nrow", 1, 1, astGetNrow( this ), - "Number of rows in table" ); - -/* Write out the KeyMap holding definitions of each column. */ - if( this->columns ) { - astWriteObject( channel, "Columns", 1, 0, this->columns, "KeyMap holding " - "column definitions" ); - } - -/* Write out the KeyMap holding definitions of each global parameter. */ - if( this->parameters ) { - astWriteObject( channel, "Params", 1, 0, this->parameters, "KeyMap holding " - "parameter definitions" ); - } -} - - - - - - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsATable and astCheckTable functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(Table,KeyMap) -astMAKE_CHECK(Table) - -AstTable *astTable_( const char *options, int *status, ...) { -/* -*++ -* Name: -c astTable -f AST_TABLE - -* Purpose: -* Create a Table. - -* Type: -* Public function. - -* Synopsis: -c #include "table.h" -c AstTable *astTable( const char *options, ... ) -f RESULT = AST_TABLE( OPTIONS, STATUS ) - -* Class Membership: -* Table constructor. - -* Description: -* This function creates a new empty Table and optionally initialises -* its attributes. -* -* The Table class is a type of KeyMap that represents a two-dimensional -* table of values. The -c astMapGet... and astMapPut... -f AST_MAPGET... and AST_MAPPUT... -* methods provided by the KeyMap class should be used for storing and -* retrieving values from individual cells within a Table. Each entry -* in the KeyMap represents a single cell of the table and has an -* associated key of the form "(i)" where "" is the name of a -* table column and "i" is the row index (the first row is row 1). Keys -* of this form should always be used when using KeyMap methods to access -* entries within a Table. -* -* Columns must be declared using the -c astAddColumn -f AST_ADDCOLUMN -* method before values can be stored within them. This also fixes the -* type and shape of the values that may be stored in any cell of the -* column. Cells may contain scalar or vector values of any data type -* supported by the KeyMap class. Multi-dimensional arrays may also be -* stored, but these must be vectorised when storing and retrieving -* them within a table cell. All cells within a single column must -* have the same type and shape (specified when the column is declared). -* -* Tables may have parameters that describe global properties of the -* entire table. These are stored as entries in the parent KeyMap and -* can be access using the get and set method of the KeyMap class. -* However, parameters must be declared using the -c astAddParameter -f AST_ADDPARAMETER -* method before being accessed. -* -* Note - since accessing entries within a KeyMap is a relatively slow -* process, it is not recommended to use the Table class to store -* very large tables. - -* Parameters: -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Table. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Table. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astTable() -f AST_TABLE = INTEGER -* A pointer to the new Table. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list described above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstTable *new; /* Pointer to new Table */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the Table, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitTable( NULL, sizeof( AstTable ), !class_init, &class_vtab, - "Table" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Table's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Table. */ - return new; -} - -AstTable *astTableId_( const char *options, ... ) { -/* -* Name: -* astTableId_ - -* Purpose: -* Create a Table. - -* Type: -* Private function. - -* Synopsis: -* #include "table.h" -* AstTable *astTableId_( const char *options, ... ) - -* Class Membership: -* Table constructor. - -* Description: -* This function implements the external (public) interface to the -* astTable constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astTable_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astTable_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astTable_. - -* Returned Value: -* The ID value associated with the new Table. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstTable *new; /* Pointer to new Table */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the Table, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitTable( NULL, sizeof( AstTable ), !class_init, &class_vtab, - "Table" ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new Table's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new Table. */ - return astMakeId( new ); -} - -AstTable *astInitTable_( void *mem, size_t size, int init, - AstTableVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitTable - -* Purpose: -* Initialise a Table. - -* Type: -* Protected function. - -* Synopsis: -* #include "table.h" -* AstTable *astInitTable( void *mem, size_t size, int init, -* AstTableVtab *vtab, const char *name ) - -* Class Membership: -* Table initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Table object. It allocates memory (if necessary) to accommodate -* the Table plus any additional data associated with the derived class. -* It then initialises a Table structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Table at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Table is to be initialised. -* This must be of sufficient size to accommodate the Table data -* (sizeof(Table)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Table (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Table -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Table's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Table. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). - -* Returned Value: -* A pointer to the new Table. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstTable *new; /* Pointer to new Table */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitTableVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a KeyMap structure (the parent class) as the first component - within the Table structure, allocating memory if necessary. Specify that - the KeyMap should be defined in both the forward and inverse directions. */ - new = (AstTable *) astInitKeyMap( mem, size, 0, (AstKeyMapVtab *) vtab, - name ); - if ( astOK ) { - -/* Initialise the Table data. */ -/* ---------------------------- */ - new->nrow = 0; - new->columns = astKeyMap( "KeyCase=0,Sortby=AgeDown", status ); - new->parameters = astKeyMap( "KeyCase=0,Sortby=AgeDown", status ); - -/* Tables require the KeyCase attribute to be zero. */ - (*parent_setkeycase)( (AstKeyMap *) new, 0, status ); - -/* If an error occurred, clean up by deleting the new Table. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new Table. */ - return new; -} - -AstTable *astLoadTable_( void *mem, size_t size, AstTableVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadTable - -* Purpose: -* Load a Table. - -* Type: -* Protected function. - -* Synopsis: -* #include "table.h" -* AstTable *astLoadTable( void *mem, size_t size, AstTableVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* Table loader. - -* Description: -* This function is provided to load a new Table using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Table structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Table at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the Table is to be -* loaded. This must be of sufficient size to accommodate the -* Table data (sizeof(Table)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Table (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Table structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstTable) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Table. If this is NULL, a pointer -* to the (static) virtual function table for the Table class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Table" is used instead. - -* Returned Value: -* A pointer to the new Table. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstTable *new; /* Pointer to the new Table */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Table. In this case the - Table belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstTable ); - vtab = &class_vtab; - name = "Table"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitTableVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Table. */ - new = astLoadKeyMap( mem, size, (AstKeyMapVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Table" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* The number of rows. */ - new->nrow = astReadInt( channel, "nrow", 0 ); - -/* KeyMap holding columns definitions. */ - new->columns = astReadObject( channel, "columns", NULL ); - -/* KeyMap holding parameter definitions. */ - new->parameters = astReadObject( channel, "params", NULL ); - -/* If an error occurred, clean up by deleting the new Table. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Table pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astAddColumn_( AstTable *this, const char *name, int type, - int ndim, int *dims, const char *unit, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Table,AddColumn))(this,name,type,ndim,dims,unit,status); -} -void astAddParameter_( AstTable *this, const char *name, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Table,AddParameter))(this,name,status); -} -void astRemoveColumn_( AstTable *this, const char *name, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Table,RemoveColumn))(this,name,status); -} -void astRemoveParameter_( AstTable *this, const char *name, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Table,RemoveParameter))(this,name,status); -} -void astRemoveRow_( AstTable *this, int index, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Table,RemoveRow))(this,index,status); -} -void astPurgeRows_( AstTable *this, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Table,PurgeRows))(this,status); -} -int astGetNcolumn_( AstTable *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Table,GetNcolumn))( this, status ); -} -int astGetNparameter_( AstTable *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,Table,GetNparameter))( this, status ); -} -const char *astColumnName_( AstTable *this, int index, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Table,ColumnName))(this,index,status); -} -const char *astParameterName_( AstTable *this, int index, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Table,ParameterName))(this,index,status); -} -int astGetColumnType_( AstTable *this, const char *column, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Table,GetColumnType))(this,column,status); -} -const char *astGetColumnUnit_( AstTable *this, const char *column, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Table,GetColumnUnit))(this,column,status); -} -int astGetColumnLenC_( AstTable *this, const char *column, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Table,GetColumnLenC))(this,column,status); -} -int astGetColumnLength_( AstTable *this, const char *column, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Table,GetColumnLength))(this,column,status); -} -int astGetColumnNdim_( AstTable *this, const char *column, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Table,GetColumnNdim))(this,column,status); -} -void astColumnShape_( AstTable *this, const char *column, int mxdim, - int *ndim, int *dims, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Table,ColumnShape))( this, column, mxdim, ndim, - dims, status ); -} -AstKeyMap *astColumnProps_( AstTable *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Table,ColumnProps))(this,status); -} -AstKeyMap *astParameterProps_( AstTable *this, int *status ){ - if ( !astOK ) return NULL; - return (**astMEMBER(this,Table,ParameterProps))(this,status); -} -int astHasColumn_( AstTable *this, const char *column, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Table,HasColumn))(this,column,status); -} -int astHasParameter_( AstTable *this, const char *parameter, int *status ){ - if ( !astOK ) return 0; - return (**astMEMBER(this,Table,HasParameter))(this,parameter,status); -} diff --git a/ast/table.h b/ast/table.h deleted file mode 100644 index f51690e..0000000 --- a/ast/table.h +++ /dev/null @@ -1,309 +0,0 @@ -#if !defined( TABLE_INCLUDED ) /* Include this file only once */ -#define TABLE_INCLUDED -/* -*+ -* Name: -* table.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the Table class. - -* Invocation: -* #include "table.h" - -* Description: -* This include file defines the interface to the Table class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. - -* Inheritance: -* The Table class inherits from the KeyMap class. - -* Copyright: -* Copyright (C) 2010 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-NOV-2010 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "keymap.h" /* Parent class */ - -#if defined(astCLASS) /* Protected */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -#if defined(astCLASS) /* Protected */ - -/* Maximum length of a column name */ -#define AST__MXCOLNAMLEN 100 - -/* Maximum length of a key for a column cell */ -#define AST__MXCOLKEYLEN ( AST__MXCOLNAMLEN + 23 ) - -#endif - - -/* Type Definitions. */ -/* ================= */ -/* Table structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstTable { - -/* Attributes inherited from the parent class. */ - AstKeyMap keymap; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int nrow; /* Mo. of rows in table */ - AstKeyMap *columns; /* KeyMap holding column definitions */ - AstKeyMap *parameters; /* KeyMap holding parameter definitions */ -} AstTable; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstTableVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstKeyMapVtab keymap_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - AstKeyMap *(* ColumnProps)( AstTable *, int * ); - AstKeyMap *(* ParameterProps)( AstTable *, int * ); - const char *(* ColumnName)( AstTable *, int, int * ); - const char *(* ParameterName)( AstTable *, int, int * ); - const char *(* GetColumnUnit)( AstTable *, const char *, int * ); - int (* GetColumnLenC)( AstTable *, const char *, int * ); - int (* GetColumnLength)( AstTable *, const char *, int * ); - int (* GetColumnNdim)( AstTable *, const char *, int * ); - int (* GetColumnType)( AstTable *, const char *, int * ); - int (* GetNcolumn)( AstTable *, int * ); - int (* GetNparameter)( AstTable *, int * ); - int (* GetNrow)( AstTable *, int * ); - int (* HasColumn)( AstTable *, const char *, int * ); - int (* HasParameter)( AstTable *, const char *, int * ); - void (* AddColumn)( AstTable *, const char *, int, int, int *, const char *, int * ); - void (* AddParameter)( AstTable *, const char *, int * ); - void (* ColumnShape)( AstTable *, const char *, int, int *, int *, int * ); - void (* PurgeRows)( AstTable *, int * ); - void (* RemoveColumn)( AstTable *, const char *, int * ); - void (* RemoveParameter)( AstTable *, const char *, int * ); - void (* RemoveRow)( AstTable *, int, int * ); - void (* SetNrow)( AstTable *, int, int * ); -} AstTableVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstTableGlobals { - AstTableVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 101 ]; -} AstTableGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitTableGlobals_( AstTableGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(Table) /* Check class membership */ -astPROTO_ISA(Table) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstTable *astTable_( const char *, int *, ...); -#else -AstTable *astTableId_( const char *, ... )__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstTable *astInitTable_( void *, size_t, int, AstTableVtab *, - const char *, int * ); - -/* Vtab initialiser. */ -void astInitTableVtab_( AstTableVtab *, const char *, int * ); - -/* Loader. */ -AstTable *astLoadTable_( void *, size_t, AstTableVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -void astAddColumn_( AstTable *, const char *, int, int, int *, const char *, int * ); -void astAddParameter_( AstTable *, const char *, int * ); -void astRemoveColumn_( AstTable *, const char *, int * ); -void astRemoveParameter_( AstTable *, const char *, int * ); -void astRemoveRow_( AstTable *, int, int * ); -void astPurgeRows_( AstTable *, int * ); -const char *astColumnName_( AstTable *, int, int * ); -const char *astParameterName_( AstTable *, int, int * ); -void astColumnShape_( AstTable *, const char *, int, int *, int *, int * ); -int astHasColumn_( AstTable *, const char *, int * ); -int astHasParameter_( AstTable *, const char *, int * ); - -#if defined(astCLASS) /* Protected */ -AstKeyMap *astColumnProps_( AstTable *, int * ); -AstKeyMap *astParameterProps_( AstTable *, int * ); -const char *astGetColumnUnit_( AstTable *, const char *, int * ); -int astGetColumnLenC_( AstTable *, const char *, int * ); -int astGetColumnLength_( AstTable *, const char *, int * ); -int astGetColumnNdim_( AstTable *, const char *, int * ); -int astGetColumnType_( AstTable *, const char *, int * ); -int astGetNcolumn_( AstTable *, int * ); -int astGetNparameter_( AstTable *, int * ); -int astGetNrow_( AstTable *, int * ); -void astSetNrow_( AstTable *, int, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckTable(this) astINVOKE_CHECK(Table,this,0) -#define astVerifyTable(this) astINVOKE_CHECK(Table,this,1) - -/* Test class membership. */ -#define astIsATable(this) astINVOKE_ISA(Table,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astTable astINVOKE(F,astTable_) -#else -#define astTable astINVOKE(F,astTableId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitTable(mem,size,init,vtab,name) \ -astINVOKE(O,astInitTable_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitTableVtab(vtab,name) astINVOKE(V,astInitTableVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadTable(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadTable_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckTable to validate Table pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#define astAddColumn(this,name,type,ndim,dims,unit) astINVOKE(V,astAddColumn_(astCheckTable(this),name,type,ndim,dims,unit, STATUS_PTR)) -#define astAddParameter(this,name) astINVOKE(V,astAddParameter_(astCheckTable(this),name,STATUS_PTR)) -#define astRemoveColumn(this,name) astINVOKE(V,astRemoveColumn_(astCheckTable(this),name,STATUS_PTR)) -#define astRemoveParameter(this,name) astINVOKE(V,astRemoveParameter_(astCheckTable(this),name,STATUS_PTR)) -#define astRemoveRow(this,index) astINVOKE(V,astRemoveRow_(astCheckTable(this),index,STATUS_PTR)) -#define astPurgeRows(this) astINVOKE(V,astPurgeRows_(astCheckTable(this),STATUS_PTR)) -#define astColumnName(this,index) astINVOKE(V,astColumnName_(astCheckTable(this),index,STATUS_PTR)) -#define astParameterName(this,index) astINVOKE(V,astParameterName_(astCheckTable(this),index,STATUS_PTR)) -#define astColumnShape(this,column,mxdim,ndim,dims) astINVOKE(V,astColumnShape_(astCheckTable(this),column,mxdim,ndim,dims,STATUS_PTR)) -#define astHasColumn(this,column) astINVOKE(V,astHasColumn_(astCheckTable(this),column,STATUS_PTR)) -#define astHasParameter(this,param) astINVOKE(V,astHasParameter_(astCheckTable(this),param,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ - -#define astColumnProps(this) \ -astINVOKE(O,astColumnProps_(astCheckTable(this),STATUS_PTR)) -#define astParameterProps(this) \ -astINVOKE(O,astParameterProps_(astCheckTable(this),STATUS_PTR)) -#define astGetNcolumn(this) \ -astINVOKE(V,astGetNcolumn_(astCheckTable(this),STATUS_PTR)) -#define astGetNparameter(this) \ -astINVOKE(V,astGetNparameter_(astCheckTable(this),STATUS_PTR)) -#define astGetNrow(this) \ -astINVOKE(V,astGetNrow_(astCheckTable(this),STATUS_PTR)) -#define astSetNrow(this,value) \ -astINVOKE(V,astSetNrow_(astCheckTable(this),value,STATUS_PTR)) -#define astGetColumnLenC(this,column) \ -astINVOKE(V,astGetColumnLenC_(astCheckTable(this),column,STATUS_PTR)) -#define astGetColumnLength(this,column) \ -astINVOKE(V,astGetColumnLength_(astCheckTable(this),column,STATUS_PTR)) -#define astGetColumnNdim(this,column) \ -astINVOKE(V,astGetColumnNdim_(astCheckTable(this),column,STATUS_PTR)) -#define astGetColumnType(this,column) \ -astINVOKE(V,astGetColumnType_(astCheckTable(this),column,STATUS_PTR)) -#define astGetColumnUnit(this,column) \ -astINVOKE(V,astGetColumnUnit_(astCheckTable(this),column,STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/templateclass.README b/ast/templateclass.README deleted file mode 100644 index 914834e..0000000 --- a/ast/templateclass.README +++ /dev/null @@ -1,29 +0,0 @@ -How to add a new public class to AST: - -1) Make copies of the three files templateclass.c templateclass.h and - ftemplateclass.c, replacing "templateclass" in the file name by the - lower case name of the new class. - -2) Edit each of the files created above and do the following: - - Replace TemplateClass with capitalised class name - - Replace templateclass with lower case class name - - Replace TEMPLATECLASS with upper case class name - - Replace TemplateParent with capitalised parent class name - - Replace templateparent with lower case parent class name - - Replace all occurrences of >>> with suitable text - - Add all the classes new functionality - -3) Add the three new files to CVS - -4) Edit the following files to include reference to the new class - - ast_par.source - - builddocs.in - - loader.c - - Makefile.am - - sun_master.tex - - ast.news - -5) Add a test program to the ast_tester script in the ast_tester directory - -6) Commit all changes to CVS. - diff --git a/ast/templateclass.c b/ast/templateclass.c deleted file mode 100644 index 395f63c..0000000 --- a/ast/templateclass.c +++ /dev/null @@ -1,1483 +0,0 @@ -1 - Replace TemplateClass with capitalised class name -2 - Replace templateclass with lower case class name -3 - Replace TEMPLATECLASS with upper case class name -4 - Replace TemplateParent with capitalised parent class name -5 - Replace templateparent with lower case parent class name -6 - Replace all occurrences of >>> with suitable text - -/* -*class++ -* Name: -* TemplateClass - -* Purpose: -* >>> purpose - -* Constructor Function: -c astTemplateClass -f AST_TEMPLATECLASS - -* Description: -* A TemplateClass is a >>> - -* Inheritance: -* The TemplateClass class inherits from the TemplateParent class. - -* Attributes: -* In addition to those attributes common to all TemplateParents, every -* TemplateClass also has the following attributes: -* -* >>> Describe new attributes -* - AlignStdOfRest: Standard of rest in which to align TemplateClasss - -* Functions: -c In addition to those functions applicable to all TemplateParents, the -c following functions may also be applied to all TemplateClasss: -f In addition to those routines applicable to all TemplateParents, the -f following routines may also be applied to all TemplateClasss: -* -* >>> Describe new functions -c - astSetRefPos: Set reference position in any celestial system -f - AST_SETREFPOS: Set reference position in any celestial system - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* >>> 4-NOV-2002 (DSB): -* Original version. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS TemplateClass - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "templateclass.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ -/* Define the class virtual function table and its initialisation flag as - static variables. */ -static AstTemplateClassVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -/* Pointers to parent class methods which are used or extended by this - class. */ -static int (* parent_getobjsize)( AstObject * ); -static const char *(* parent_getattrib)( AstObject *, const char * ); -static int (* parent_testattrib)( AstObject *, const char * ); -static void (* parent_clearattrib)( AstObject *, const char * ); -static void (* parent_setattrib)( AstObject *, const char * ); -static int (* parent_equal)( AstObject *, AstObject * ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static int Equal( AstObject *, AstObject * ); -static int GetObjSize( AstObject * ); -static void Copy( const AstObject *, AstObject * ); -static void Delete( AstObject * ); -static void Dump( AstObject *, AstChannel * ); - -static const char *GetAttrib( AstObject *, const char * ); -static int TestAttrib( AstObject *, const char * ); -static void ClearAttrib( AstObject *, const char * ); -static void SetAttrib( AstObject *, const char * ); - - -/* Member functions. */ -/* ================= */ - -static void ClearAttrib( AstObject *this_object, const char *attrib ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a TemplateClass. - -* Type: -* Private function. - -* Synopsis: -* #include "templateclass.h" -* void ClearAttrib( AstObject *this, const char *attrib ) - -* Class Membership: -* TemplateClass member function (over-rides the astClearAttrib protected -* method inherited from the TemplateParent class). - -* Description: -* This function clears the value of a specified attribute for a -* TemplateClass, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the TemplateClass. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -*/ - -/* Local Variables: */ - AstTemplateClass *this; /* Pointer to the TemplateClass structure */ - char *new_attrib; /* Pointer value to new attribute name */ - int len; /* Length of attrib string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TemplateClass structure. */ - this = (AstTemplateClass *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - ->>> rEPLACE WITH NEW ATTRIBUTES - -/* AlignStdOfRest. */ -/* --------------- */ - if ( !strcmp( attrib, "alignstdofrest" ) ) { - astClearAlignStdOfRest( this ); - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - TemplateClass had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "geolat" ) ) { - astClearAttrib( this, "obslat" ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib ); - } -} - -static int Equal( AstObject *this_object, AstObject *that_object ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two TemplateClasss are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "templateclass.h" -* int Equal( AstObject *this, AstObject *that ) - -* Class Membership: -* TemplateClass member function (over-rides the astEqual protected -* method inherited from the TemplateParent Object class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two TemplateClasss are equivalent. - -* Parameters: -* this -* Pointer to the first TemplateClass. -* that -* Pointer to the second TemplateClass. - -* Returned Value: -* One if the TemplateClasss are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTemplateClass *that; /* Pointer to the second TemplateClass structure */ - AstTemplateClass *this; /* Pointer to the first TemplateClass structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the Equal method inherited from the parent TemplateParent class. This checks - that the TemplateParents are both of the same class (amongst other things). */ - if( (*parent_equal)( this_object, that_object ) ) { - -/* Obtain pointers to the two TemplateClass structures. */ - this = (AstTemplateClass *) this_object; - that = (AstTemplateClass *) that_object; ->>> - - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetObjSize( AstObject *this_object ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "templateclass.h" -* int GetObjSize( AstObject *this ) - -* Class Membership: -* TemplateClass member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied TemplateClass, -* in bytes. - -* Parameters: -* this -* Pointer to the TemplateClass. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTemplateClass *this; /* Pointer to TemplateClass structure */ - int result; /* Result value to return */ - int i; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the TemplateClass structure. */ - this = (AstTemplateClass *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by this class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object ); - ->>> - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a TemplateClass. - -* Type: -* Private function. - -* Synopsis: -* #include "templateclass.h" -* const char *GetAttrib( AstObject *this, const char *attrib ) - -* Class Membership: -* TemplateClass member function (over-rides the protected astGetAttrib -* method inherited from the TemplateParent class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a TemplateClass, formatted as a character string. - -* Parameters: -* this -* Pointer to the TemplateClass. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - The returned string pointer may point at memory allocated -* within the TemplateClass, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the TemplateClass. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Constants: */ -#define BUFF_LEN 50 /* Max. characters in result buffer */ - -/* Local Variables: */ - AstTemplateClass *this; /* Pointer to the TemplateClass structure */ - char *new_attrib; /* Pointer value to new attribute name */ - const char *result; /* Pointer value to return */ - double dval; /* Attribute value */ - int ival; /* Attribute value */ - int len; /* Length of attrib string */ - static char buff[ BUFF_LEN + 1 ]; /* Buffer for string result */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the TemplateClass structure. */ - this = (AstTemplateClass *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - ->>> - -/* AlignStdOfRest. */ -/* --------------- */ -/* Obtain the AlignStdOfRest code and convert to a string. */ - if ( !strcmp( attrib, "alignstdofrest" ) ) { - sor = astGetAlignStdOfRest( this ); - if ( astOK ) { - result = StdOfRestString( sor ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid AlignStdOfRest " - "identification code (%d).", astGetClass( this ), - astGetClass( this ), (int) sor ); - } - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib ); - } - -/* Return the result. */ - return result; - -/* Undefine macros local to this function. */ -#undef BUFF_LEN -} - -void astInitTemplateClassVtab_( AstTemplateClassVtab *vtab, const char *name ) { -/* -*+ -* Name: -* astInitTemplateClassVtab - -* Purpose: -* Initialise a virtual function table for a TemplateClass. - -* Type: -* Protected function. - -* Synopsis: -* #include "templateclass.h" -* void astInitTemplateClassVtab( AstTemplateClassVtab *vtab, const char *name ) - -* Class Membership: -* TemplateClass vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the TemplateClass class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - AstTemplateParentVtab *templateparent; /* Pointer to TemplateParent component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitTemplateParentVtab( (AstTemplateParentVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsATemplateClass) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_init variable to generate this unique value. */ - vtab->check = &class_init; - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ ->>> - vtab->GetRefPos = GetRefPos; - vtab->SetRefPos = SetRefPos; - - vtab->ClearAlignStdOfRest = ClearAlignStdOfRest; - vtab->TestAlignStdOfRest = TestAlignStdOfRest; - vtab->GetAlignStdOfRest = GetAlignStdOfRest; - vtab->SetAlignStdOfRest = SetAlignStdOfRest; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - templateparent = (AstTemplateParentVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_equal = object->Equal; - object->Equal = Equal; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - ->>> - -/* Store replacement pointers for methods which will be over-ridden by new - member functions implemented here. */ ->>> - templateparent->GetActiveUnit = GetActiveUnit; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "TemplateClass", - ">>>Description of class" ); - -} - -static void SetAttrib( AstObject *this_object, const char *setting ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a TemplateClass. - -* Type: -* Private function. - -* Synopsis: -* #include "templateclass.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* TemplateClass member function (extends the astSetAttrib method inherited from -* the Mapping class). - -* Description: -* This function assigns an attribute value for a TemplateClass, the attribute -* and its value being specified by means of a string of the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in lower -* case with no white space present. The value to the right of the "=" -* should be a suitable textual representation of the value to be assigned -* and this will be interpreted according to the attribute's data type. -* White space surrounding the value is only significant for string -* attributes. - -* Parameters: -* this -* Pointer to the TemplateClass. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. - -* Returned Value: -* void - -* Notes: -* This protected method is intended to be invoked by the Object astSet -* method and makes additional attributes accessible to it. -*/ - -/* Local Vaiables: */ - AstTemplateClass *this; /* Pointer to the TemplateClass structure */ - char *a; /* Pointer to next character */ - char *new_setting; /* Pointer value to new attribute setting */ - double dval; /* Double atribute value */ - double dtemp; /* Temporary double atribute value */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int ulen; /* Used length of setting string */ - int namelen; /* Length of attribute name in setting */ - int nc; /* Number of characters read by astSscanf */ - int off; /* Offset of attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TemplateClass structure. */ - this = (AstTemplateClass *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Obtain the used length of the setting string. */ - ulen = astChrLen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - ->>> - -/* AlignStdOfRest. */ -/* --------------- */ - if ( nc = 0, - ( 0 == astSscanf( setting, "alignstdofrest=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a StdOfRest code before use. */ - sor = StdOfRestCode( setting + off ); - if ( sor != AST__BADSOR ) { - astSetAlignStdOfRest( this, sor ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid standard of rest " - "description \"%s\".", astGetClass( this ), setting+off ); - } - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - TemplateClass had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "geolat=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - new_setting = astStore( NULL, setting, len + 1 ); - new_setting[ 0 ] = 'o'; - new_setting[ 1 ] = 'b'; - new_setting[ 2 ] = 's'; - astSetAttrib( this, new_setting ); - new_setting = astFree( new_setting ); - -/* Pass any unrecognised setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting ); - } -} - -static int TestAttrib( AstObject *this_object, const char *attrib ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a TemplateClass. - -* Type: -* Private function. - -* Synopsis: -* #include "templateclass.h" -* int TestAttrib( AstObject *this, const char *attrib ) - -* Class Membership: -* TemplateClass member function (over-rides the astTestAttrib protected -* method inherited from the TemplateParent class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a TemplateClass's attributes. - -* Parameters: -* this -* Pointer to the TemplateClass. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTemplateClass *this; /* Pointer to the TemplateClass structure */ - char *new_attrib; /* Pointer value to new attribute name */ - int len; /* Length of attrib string */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the TemplateClass structure. */ - this = (AstTemplateClass *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - ->>> - -/* AlignStdOfRest. */ -/* --------------- */ - if ( !strcmp( attrib, "alignstdofrest" ) ) { - result = astTestAlignStdOfRest( this ); - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - TemplateClass had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "geolat" ) ) { - result = astTestAttrib( this, "obslat" ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib ); - } - -/* Return the result, */ - return result; -} - - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* - ->>> Add descriptions and accessors for all new attributes - -*att++ -* Name: -* AlignSpecOffset - -* Purpose: -* Align TemplateClasss using the offset coordinate system? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which controls how a TemplateClass -* behaves when it is used (by -c astFindTemplateParent or astConvert) as a template to match another (target) -f AST_FINDFRAME or AST_CONVERT) as a template to match another (target) -* TemplateClass. It determines whether alignment occurs between the offset -* values defined by the current value of the SpecOffset attribute, or -* between the corresponding absolute spectral values. -* -* The default value of zero results in the two TemplateClasss being aligned -* so that a given absolute spectral value in one is mapped to the same -* absolute value in the other. A non-zero value results in the TemplateClasss -* being aligned so that a given offset value in one is mapped to the same -* offset value in the other. - -* Applicability: -* TemplateClass -* All TemplateClasss have this attribute. -*att-- -*/ -astMAKE_CLEAR(TemplateClass,AlignSpecOffset,alignspecoffset,-INT_MAX) -astMAKE_GET(TemplateClass,AlignSpecOffset,int,0,( ( this->alignspecoffset != -INT_MAX ) ? - this->alignspecoffset : 0 )) -astMAKE_SET(TemplateClass,AlignSpecOffset,int,alignspecoffset,( value != 0 )) -astMAKE_TEST(TemplateClass,AlignSpecOffset,( this->alignspecoffset != -INT_MAX )) - - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for TemplateClass objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout ) - -* Description: -* This function implements the copy constructor for TemplateClass objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstTemplateClass *in; /* Pointer to input TemplateClass */ - AstTemplateClass *out; /* Pointer to output TemplateClass */ - char *usedunit; /* Pointer to an element of usedunits array */ - int i; /* Loop count */ - int nused; /* Size of "usedunits" array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output TemplateClasss. */ - in = (AstTemplateClass *) objin; - out = (AstTemplateClass *) objout; - -/* Nullify the pointers stored in the output object since these will - currently be pointing at the input data (since the output is a simple - byte-for-byte copy of the input). Otherwise, the input data could be - freed by accidient if the output object is deleted due to an error - occuring in this function. */ - out->usedunits = NULL; - ->>> - -/* If an error has occurred, free the output resources. */ - if( !astOK ) Delete( (AstObject *) out ); - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for TemplateClass objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj ) - -* Description: -* This function implements the destructor for TemplateClass objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstTemplateClass *this; - int i; - -/* Release the memory referred to in the TemplateClass structure. */ - this = (AstTemplateClass *) obj; - if( this ) { ->>> - } -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for TemplateClass objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel ) - -* Description: -* This function implements the Dump function which writes out data -* for the TemplateClass class to an output Channel. - -* Parameters: -* this -* Pointer to the TemplateClass whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -*/ - -/* Local Variables: */ - AstTemplateClass *this; /* Pointer to the TemplateClass structure */ - char buff[ 20 ]; /* Buffer for item name */ - char comm[ 50 ]; /* Buffer for comment */ - const char *sval; /* Pointer to string value */ - double dval; /* Double value */ - int i; /* Loop count */ - int ival; /* int value */ - int j; /* Loop count */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TemplateClass structure. */ - this = (AstTemplateClass *) this_object; - -/* Write out values representing the instance variables for the - TemplateClass class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - ->>> - -/* StdOfRest. */ -/* ---------- */ - set = TestStdOfRest( this ); - sor = set ? GetStdOfRest( this ) : astGetStdOfRest( this ); - -/* If set, convert explicitly to a string for the external - representation. */ - sval = ""; - if ( set ) { - if ( astOK ) { - sval = StdOfRestString( sor ); - -/* Report an error if the StdOfRest value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid standard of rest " - "identification code (%d).", "astWrite", - astGetClass( channel ), astGetClass( this ), (int) sor ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "stdofrest" ); - } - -/* Write out the value. */ - astWriteString( channel, "SoR", set, 1, sval, "Standard of rest" ); - - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsATemplateClass and astCheckTemplateClass functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(TemplateClass,TemplateParent,check,&class_init) -astMAKE_CHECK(TemplateClass) - - ->>> Change constructor argument list -AstTemplateClass *astTemplateClass_( >>> const char *options, ... ) { -/* -*+ -* Name: -* astTemplateClass - -* Purpose: -* Create a TemplateClass. - -* Type: -* Protected function. - -* Synopsis: -* #include "templateclass.h" -* AstTemplateClass *astTemplateClass( >>> const char *options, ... ) - -* Class Membership: -* TemplateClass constructor. - -* Description: -* This function creates a new TemplateClass and optionally initialises its -* attributes. - -* Parameters: ->>> -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new TemplateClass. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new TemplateClass. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic TemplateClass constructor which -* is available via the protected interface to the TemplateClass class. -* A public interface is provided by the astTemplateClassId_ function. -*/ - -/* Local Variables: */ - AstTemplateClass *new; /* Pointer to new TemplateClass */ - va_list args; /* Variable argument list */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the TemplateClass, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitTemplateClass( NULL, sizeof( AstTemplateClass ), !class_init, - &class_vtab, "TemplateClass" ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new TemplateClass's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new TemplateClass. */ - return new; -} - -AstTemplateClass *astInitTemplateClass_( void *mem, size_t size, int init, - AstTemplateClassVtab *vtab, const char *name, - >>>) { -/* -*+ -* Name: -* astInitTemplateClass - -* Purpose: -* Initialise a TemplateClass. - -* Type: -* Protected function. - -* Synopsis: -* #include "templateclass.h" -* AstTemplateClass *astInitTemplateClass( void *mem, size_t size, int init, -* AstTemplateParentVtab *vtab, const char *name, -* >>> ) - -* Class Membership: -* TemplateClass initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new TemplateClass object. It allocates memory (if -* necessary) to accommodate the TemplateClass plus any additional data -* associated with the derived class. It then initialises a -* TemplateClass structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual function -* table for a TemplateClass at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the TemplateClass is to be -* created. This must be of sufficient size to accommodate the -* TemplateClass data (sizeof(TemplateClass)) plus any data used by -* the derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the TemplateClass (plus derived -* class data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also stored -* in the TemplateClass structure, so a valid value must be supplied -* even if not required for allocating memory. -* init -* A logical flag indicating if the TemplateClass's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new TemplateClass. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object belongs -* (it is this pointer value that will subsequently be returned by -* the astGetClass method). ->>> - -* Returned Value: -* A pointer to the new TemplateClass. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstTemplateClass *new; /* Pointer to the new TemplateClass */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitTemplateClassVtab( vtab, name ); - -/* Initialise a 1D TemplateParent structure (the parent class) as the first component - within the TemplateClass structure, allocating memory if necessary. */ - new = (AstTemplateClass *) astInitTemplateParent( mem, size, 0, - (AstTemplateParentVtab *) vtab, - name, >>> 1 ); - - if ( astOK ) { - -/* Initialise the TemplateClass data. */ -/* ----------------------------- */ -/* Initialise all attributes to their "undefined" values. */ ->>> - new->alignstdofrest = AST__BADSOR; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - - } - -/* Return a pointer to the new object. */ - return new; -} - -AstTemplateClass *astLoadTemplateClass_( void *mem, size_t size, - AstTemplateClassVtab *vtab, - const char *name, AstChannel *channel ) { -/* -*+ -* Name: -* astLoadTemplateClass - -* Purpose: -* Load a TemplateClass. - -* Type: -* Protected function. - -* Synopsis: -* #include "templateclass.h" -* AstTemplateClass *astLoadTemplateClass( void *mem, size_t size, -* AstTemplateClassVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* TemplateClass loader. - -* Description: -* This function is provided to load a new TemplateClass using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* TemplateClass structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the TemplateClass is to be -* loaded. This must be of sufficient size to accommodate the -* TemplateClass data (sizeof(TemplateClass)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the TemplateClass (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the TemplateClass structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstTemplateClass) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new TemplateClass. If this is NULL, a pointer -* to the (static) virtual function table for the TemplateClass class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "TemplateClass" is used instead. - -* Returned Value: -* A pointer to the new TemplateClass. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - AstTemplateClass *new; /* Pointer to the new TemplateClass */ - char buff[ 20 ]; /* Buffer for item name */ - char *sval; /* Pointer to string value */ - int i; /* Loop count */ - int j; /* Loop count */ - int nc; /* String length */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this TemplateClass. In this case the - TemplateClass belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstTemplateClass ); - vtab = &class_vtab; - name = "TemplateClass"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitTemplateClassVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built TemplateClass. */ - new = astLoadTemplateParent( mem, size, (AstTemplateParentVtab *) vtab, name, - channel ); - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "TemplateClass" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - ->>> - -/* StdOfRest. */ -/* ---------- */ -/* Set the default and read the external representation as a string. */ - new->stdofrest = AST__BADSOR; - sval = astReadString( channel, "sor", NULL ); - -/* If a value was read, convert from a string to a StdOfRest code. */ - if ( sval ) { - if ( astOK ) { - new->stdofrest = StdOfRestCode( sval ); - -/* Report an error if the value wasn't recognised. */ - if ( new->stdofrest == AST__BADSOR ) { - astError( AST__ATTIN, - "astRead(%s): Invalid standard of rest description " - "\"%s\".", astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* If an error occurred, clean up by deleting the new TemplateClass. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new TemplateClass pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ ->>> -void astGetRefPos_( AstTemplateClass *this, AstSkyTemplateParent *frm, double *lon, - double *lat ){ - if ( !astOK ) return; - (**astMEMBER(this,TemplateClass,GetRefPos))(this,frm,lon,lat); -} - - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstTemplateClass *astTemplateClassId_( >>> const char *, ... ); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstTemplateClass *astTemplateClassId_( >>> const char *options, ... ) { -/* -*++ -* Name: -c astTemplateClass -f AST_TEMPLATECLASS - -* Purpose: -* Create a TemplateClass. - -* Type: -* Public function. - -* Synopsis: -c #include "templateclass.h" -c AstTemplateClass *astTemplateClass( >>> const char *options, ... ) -f RESULT = AST_TEMPLATECLASS( >>> OPTIONS, STATUS ) - -* Class Membership: -* TemplateClass constructor. - -* Description: -* This function creates a new TemplateClass and optionally initialises -* its attributes. -* -* A TemplateClass is a >>> (copy from class prologue at top of file) - -* Parameters: ->>> -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new TemplateClass. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new TemplateClass. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astTemplateClass() -f AST_TEMPLATECLASS = INTEGER -* A pointer to the new TemplateClass. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astTemplateClass constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astTemplateClass_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - The variable argument list also prevents this function from -* invoking astTemplateClass_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. -*/ - -/* Local Variables: */ - AstTemplateClass *new; /* Pointer to new TemplateClass */ - va_list args; /* Variable argument list */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the TemplateClass, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitTemplateClass( NULL, sizeof( AstTemplateClass ), !class_init, - &class_vtab, "TemplateClass" >>> ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new TemplateClass's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new TemplateClass. */ - return astMakeId( new ); -} - - - - diff --git a/ast/templateclass.h b/ast/templateclass.h deleted file mode 100644 index 070e84b..0000000 --- a/ast/templateclass.h +++ /dev/null @@ -1,216 +0,0 @@ -1 - Replace TemplateClass with capitalised class name -2 - Replace templateclass with lower case class name -3 - Replace TEMPLATECLASS with upper case class name -4 - Replace TemplateParent with capitalised parent class name -5 - Replace templateparent with lower case parent class name -6 - Replace all occurrences of >>> with suitable text - -#if !defined( TEMPLATECLASS_INCLUDED ) /* Include this file only once */ -#define TEMPLATECLASS_INCLUDED -/* -*+ -* Name: -* templateclass.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the TemplateClass class. - -* Invocation: -* #include "templateclass.h" - -* Description: -* This include file defines the interface to the TemplateClass class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. - -* Copyright: -* Copyright (C) 2007 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* >>> 12-NOV-2002 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "templateparent.h" /* Parent TemplateParent class */ - -/* Macros. */ -/* ======= */ - -#if defined(astCLASS) /* Protected */ - -#endif - -/* Type Definitions. */ -/* ================= */ - -/* TemplateClass structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstTemplateClass { - -/* Attributes inherited from the parent class. */ - AstTemplateParent templateparent; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ ->>> - -} AstTemplateClass; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all objects in the - class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstTemplateClassVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstTemplateParentVtab templateparent_vtab; /* Parent class virtual function table */ - -/* Unique flag value to determine class membership. */ - int *check; /* Check value */ - -/* Properties (e.g. methods) specific to this class. */ ->>> - double (* GetNewAttr)( AstTemplateClass * ); - int (* TestNewAttr)( AstTemplateClass * ); - void (* ClearNewAttr)( AstTemplateClass * ); - void (* SetNewAttr)( AstTemplateClass *, double ); - - -} AstTemplateClassVtab; -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(TemplateClass) /* Check class membership */ -astPROTO_ISA(TemplateClass) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -AstTemplateClass *astTemplateClass_( >>> const char *, ... ); -#else -AstTemplateClass *astTemplateClassId_( >>> const char *, ... ); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstTemplateClass *astInitTemplateClass_( void *, size_t, int, - AstTemplateClassVtab *, - const char * >>> ); - -/* Vtab initialiser. */ -void astInitTemplateClassVtab_( AstTemplateClassVtab *, const char * ); - -/* Loader. */ -AstTemplateClass *astLoadTemplateClass_( void *, size_t, - AstTemplateClassVtab *, - const char *, AstChannel *channel ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ - -#if defined(astCLASS) /* Protected */ - - ->>> -double astGetNewAttr_( AstTemplateClass * ); -int astTestNewAttr_( AstTemplateClass * ); -void astClearNewAttr_( AstTemplateClass * ); -void astSetNewAttr_( AstTemplateClass *, double ); - - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckTemplateClass(this) astINVOKE_CHECK(TemplateClass,this) - -/* Test class membership. */ -#define astIsATemplateClass(this) astINVOKE_ISA(TemplateClass,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -#define astTemplateClass astINVOKE(F,astTemplateClass_) -#else -#define astTemplateClass astINVOKE(F,astTemplateClassId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitTemplateClass(mem,size,init,vtab,name>>>) \ -astINVOKE(O,astInitTemplateClass_(mem,size,init,vtab,name>>>)) - -/* Vtab Initialiser. */ -#define astInitTemplateClassVtab(vtab,name) astINVOKE(V,astInitTemplateClassVtab_(vtab,name)) -/* Loader. */ -#define astLoadTemplateClass(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadTemplateClass_(mem,size,vtab,name,astCheckChannel(channel))) - -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ ->>> - -/* Interfaces to protected member functions. */ -/* ----------------------------------------- */ -/* Here we make use of astCheckTemplateClass to validate TemplateClass pointers - before use. This provides a contextual error report if a pointer to - the wrong sort of object is supplied. */ - -#if defined(astCLASS) /* Protected */ - -#define astGetNewAttr(this) astINVOKE(V,astGetNewAttr_(astCheckTemplateClass(this))) -#define astTestNewAttr(this) astINVOKE(V,astTestNewAttr_(astCheckTemplateClass(this))) -#define astClearNewAttr(this) astINVOKE(V,astClearNewAttr_(astCheckTemplateClass(this))) -#define astSetNewAttr(this,value) astINVOKE(V,astSetNewAttr_(astCheckTemplateClass(this),value)) - -#endif -#endif diff --git a/ast/timeframe.c b/ast/timeframe.c deleted file mode 100644 index 8d0906a..0000000 --- a/ast/timeframe.c +++ /dev/null @@ -1,7530 +0,0 @@ -/* -*class++ -* Name: -* TimeFrame - -* Purpose: -* Time coordinate system description. - -* Constructor Function: -c astTimeFrame -f AST_TIMEFRAME - -* Description: -* A TimeFrame is a specialised form of one-dimensional Frame which -* represents various coordinate systems used to describe positions in -* time. -* -* A TimeFrame represents a moment in time as either an Modified Julian -* Date (MJD), a Julian Date (JD), a Besselian epoch or a Julian epoch, -* as determined by the System attribute. Optionally, a zero point can be -* specified (using attribute TimeOrigin) which results in the TimeFrame -* representing time offsets from the specified zero point. -* -* Even though JD and MJD are defined as being in units of days, the -* TimeFrame class allows other units to be used (via the Unit attribute) -* on the basis of simple scalings (60 seconds = 1 minute, 60 minutes = 1 -* hour, 24 hours = 1 day, 365.25 days = 1 year). Likewise, Julian epochs -* can be described in units other than the usual years. Besselian epoch -* are always represented in units of (tropical) years. -* -* The TimeScale attribute allows the time scale to be specified (that -* is, the physical process used to define the rate of flow of time). -* MJD, JD and Julian epoch can be used to represent a time in any -* supported time scale. However, Besselian epoch may only be used with the -* "TT" (Terrestrial Time) time scale. The list of supported time scales -* includes universal time and siderial time. Strictly, these represent -* angles rather than time scales, but are included in the list since -* they are in common use and are often thought of as time scales. -* -* When a time value is formatted it can be formated either as a simple -* floating point value, or as a Gregorian date (see the Format -* attribute). - -* Inheritance: -* The TimeFrame class inherits from the Frame class. - -* Attributes: -* In addition to those attributes common to all Frames, every -* TimeFrame also has the following attributes: -* -* - AlignTimeScale: Time scale in which to align TimeFrames -* - LTOffset: The offset of Local Time from UTC, in hours. -* - TimeOrigin: The zero point for TimeFrame axis values -* - TimeScale: The timescale used by the TimeFrame -* -* Several of the Frame attributes inherited by the TimeFrame class -* refer to a specific axis of the Frame (for instance Unit(axis), -* Label(axis), etc). Since a TimeFrame is strictly one-dimensional, -* it allows these attributes to be specified without an axis index. -* So for instance, "Unit" is allowed in place of "Unit(1)". - -* Functions: -c In addition to those functions applicable to all Frames, the -c following functions may also be applied to all TimeFrames: -f In addition to those routines applicable to all Frames, the -f following routines may also be applied to all TimeFrames: -* -c - astCurrentTime: Return the current system time -f - AST_CURRENTTIME: Return the current system time - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* NG: Norman Gray (Starlink) -* DSB: David Berry (Starlink) - -* History: -* XX-Aug-2003 (NG): -* Original version, drawing heavily on specframe.c. -* 20-MAY-2005 (NG): -* Merged into main AST system. -* 25-MAY-2005 (DSB): -* Extensive modifications to add extra timescales, unit support, -* support for relative times, etc, and to make it more like the -* other AST Frame classes. -* 12-AUG-2005 (DSB): -* Remove ClockLon and ClockLat attributes. Use the new ObsLon and -* ObsLat attributes in the parent Frame class instead. Note, for -* backward compatibility the public attribute accessors and the -* astLoadTimeFrame functions still recogonise ClockLon and ClockLat, -* but use the ObsLat/ObsLon attributes internally. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 29-JUN-2006 (DSB): -* - Activate astAbbrev function for abbreviating leading fields in -* plot labels. -* - Include TimeOrigin in default Label. -* 30-JUN-2006 (DSB): -* When splitting a date/time string into fields, allow each field -* to include a decimal point. -* 30-JUN-2006 (DSB): -* Allow astAbbrev to have a null "str1" value. -* 16-OCT-2006 (DSB): -* Allow conversions between UTC and UT1 (using the new Frame attribute -* 1-NOV-2006 (DSB): -* Correct sign of longitude passed to TimeMap contrutcorss in -* function MakeMap. -* 31-JAN-2007 (DSB): -* Modified so that a TimeFrame can be used as a template to find a -* TimeFrame contained within a CmpFrame. This involves changes in -* Match and the removal of the local versions of SetMaxAxes and -* SetMinAxes. -* 3-SEP-2007 (DSB): -* In SubFrame, since AlignSystem is extended by the TimeFrame class -* it needs to be cleared before invoking the parent SubFrame -* method in cases where the result Frame is not a TimeFrame. -* 2-OCT-2007 (DSB): -* In Overlay, clear AlignSystem as well as System before calling -* the parent overlay method. -* 2-OCT-2007 (DSB): -* Added "LT" (Local Time) time scale. -* 9-DEC-2008 (DSB): -* Ensure Format string pointer is used correctly. -* 19-JAN-2009 (DSB): -* Ensure "" is returned by astFormat if the axis value is bad. -* 31-MAR-2009 (DSB): -* Extend TimeFrame "iso" Format to allow it to specify the character to -* place between the time and date strings. -* 15-APR-2009 (DSB): -* Increase the number of nice calendar time axis gaps allowed by -* the Gap function. Previously, there was a jump from 1 day to 1 -* year making it difficult to plot calendar axes covering time -* ranges of the order of 0.5 to 2 years. Now, nice numbers of days -* are allowed as intermediate gaps. Since months do not all have -* the same number of days, this means that the day number at major -* ticks will bounce around a bit. -* 29-APR-2011 (DSB): -* Prevent astFindFrame from matching a subclass template against a -* superclass target. -* 16-APR-2015 (DSB): -* Add more choices when chosing gaps on time axes. -* 17-APR-2015 (DSB): -* - Added Centre. -* - Remove some "set but unused" variables. -* 21-APR-2016 (DSB): -* - Over-ride astFields. -* 5-APR-2017 (GSB): -* - Pass DTAI to astAddTime for UTCTOTAI and TAITOUTC conversions and -* check whether there is a relevant DTAI difference in -* MakeTimeMapping. -* 7-APR-2017 (GSB): -* - Add LT to macro defining scales depending on DTAI. -* 10-APR-2017 (GSB): -* - Added macro to test floating point equality and used it for Dtai. -* 27-APR-2017 (DSB): -* Conversions between TT and TDB now require DTAI as an argument. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS TimeFrame - -/* Define the first and last acceptable System values. */ -#define FIRST_SYSTEM AST__MJD -#define LAST_SYSTEM AST__BEPOCH - -/* Define the first and last acceptable TimeScale values. */ -#define FIRST_TS AST__TAI -#define LAST_TS AST__LT - -/* The supported time scales fall into two groups. Time scales in the - first group depend on the clock position. That is, transformation - between a time scale in one group and a timescale in the other group - requires the clock position, as does transformation between two time - scales within the first group. Define a macro which tests if a given - timescale belongs to the first group. */ -#define CLOCK_SCALE(ts) \ - ( ( ts == AST__LMST || \ - ts == AST__LAST || \ - ts == AST__TDB || \ - ts == AST__TCB ) ? 1 : 0 ) - - -/* Define a macro which tests if a given timescale requires a Dut1 value - in order to convert from the timescale to UTC. */ -#define DUT1_SCALE(ts) \ - ( ( ts == AST__LMST || \ - ts == AST__LAST || \ - ts == AST__GMST || \ - ts == AST__UT1 ) ? 1 : 0 ) - -/* Timescales can be divided up into 3 groups such that conversion from a - timescale in one group to a timescale in any other group requires the - DTAI value, but conversion between timescales in the same group does not - require the DTAI value. Define a macro that returns the group number - (1, 2 or 3) for a specific timescale. */ -#define DTAI_SCALE(ts) \ - ( ( ts == AST__LMST || \ - ts == AST__LAST || \ - ts == AST__GMST || \ - ts == AST__UT1 || \ - ts == AST__UTC || \ - ts == AST__LT ) ? 1 : \ - ( ( ts == AST__TAI || ts == AST__TT ) ? 2 : 3 ) ) - -/* Define a macro which tests if a given timescale requires a LTOffset value - in order to convert from the timescale to UTC. */ -#define LTOFFSET_SCALE(ts) \ - ( ( ts == AST__LT ) ? 1 : 0 ) - -/* The Unix epoch (00:00:00 UTC 1 January 1970 AD) as an absolute MJD in - the UTC timescale. */ -#define UNIX_EPOCH 40587.0 - -/* Check for floating point equality (within the given tolerance), taking - bad values into account. */ -#define EQUAL(aa,bb,tol) (((aa)==AST__BAD)?(((bb)==AST__BAD)?1:0):(((bb)==AST__BAD)?0:(fabs((aa)-(bb))<=(tol)))) - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "unit.h" /* Units management facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "timemap.h" /* Time coordinate Mappings */ -#include "frame.h" /* Parent Frame class */ -#include "timeframe.h" /* Interface definition for this class */ -#include "mapping.h" /* Coordinate Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "shiftmap.h" /* Shift of origins */ -#include "pal.h" /* SlaLib interface */ - - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are used or extended by this - class. */ -static AstSystemType (* parent_getalignsystem)( AstFrame *, int * ); -static AstSystemType (* parent_getsystem)( AstFrame *, int * ); -static double (* parent_centre)( AstFrame *, int, double, double, int * ); -static double (* parent_gap)( AstFrame *, int, double, int *, int * ); -static const char *(* parent_abbrev)( AstFrame *, int, const char *, const char *, const char *, int * ); -static const char *(* parent_format)( AstFrame *, int, double, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static const char *(* parent_getdomain)( AstFrame *, int * ); -static const char *(* parent_getlabel)( AstFrame *, int, int * ); -static const char *(* parent_getsymbol)( AstFrame *, int, int * ); -static const char *(* parent_gettitle)( AstFrame *, int * ); -static const char *(* parent_getunit)( AstFrame *, int, int * ); -static double (* parent_getepoch)( AstFrame *, int * ); -static int (* parent_fields)( AstFrame *, int, const char *, const char *, int, char **, int *, double *, int * ); -static int (* parent_match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int (* parent_subframe)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static int (* parent_unformat)( AstFrame *, int, const char *, double *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_clearsystem)( AstFrame *, int * ); -static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_setsystem)( AstFrame *, AstSystemType, int * ); -static void (* parent_setunit)( AstFrame *, int, const char *, int * ); - -/* The Unix epoch (00:00:00 UTC 1 January 1970 AD) as an absolute MJD in - the TAI timescale. */ -static double tai_epoch; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->Format_Buff[ 0 ] = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->GetLabel_Buff[ 0 ] = 0; \ - globals->GetSymbol_Buff[ 0 ] = 0; \ - globals->GetTitle_Buff[ 0 ] = 0; \ - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(TimeFrame) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(TimeFrame,Class_Init) -#define class_vtab astGLOBAL(TimeFrame,Class_Vtab) -#define format_buff astGLOBAL(TimeFrame,Format_Buff) -#define getattrib_buff astGLOBAL(TimeFrame,GetAttrib_Buff) -#define getlabel_buff astGLOBAL(TimeFrame,GetLabel_Buff) -#define getsymbol_buff astGLOBAL(TimeFrame,GetSymbol_Buff) -#define gettitle_buff astGLOBAL(TimeFrame,GetTitle_Buff) - - - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffers for strings returned by various functions. */ -static char getattrib_buff[ AST__TIMEFRAME_GETATTRIB_BUFF_LEN + 1 ]; -static char format_buff[ AST__TIMEFRAME_FORMAT_BUFF_LEN + 1 ]; -static char getlabel_buff[ AST__TIMEFRAME_GETLABEL_BUFF_LEN + 1 ]; -static char getsymbol_buff[ AST__TIMEFRAME_GETSYMBOL_BUFF_LEN + 1 ]; -static char gettitle_buff[ AST__TIMEFRAME_GETTITLE_BUFF_LEN + 1 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstTimeFrameVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#endif - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *MakeMap( AstTimeFrame *, AstSystemType, AstSystemType, AstTimeScaleType, AstTimeScaleType, double, double, const char *, const char *, const char *, int * ); -static AstSystemType GetAlignSystem( AstFrame *, int * ); -static AstSystemType SystemCode( AstFrame *, const char *, int * ); -static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * ); -static AstTimeScaleType TimeScaleCode( const char *, int * ); -static const char *DefUnit( AstSystemType, const char *, const char *, int * ); -static const char *Format( AstFrame *, int, double, int * ); -static const char *GetDomain( AstFrame *, int * ); -static const char *GetLabel( AstFrame *, int, int * ); -static const char *GetSymbol( AstFrame *, int, int * ); -static const char *GetTitle( AstFrame *, int * ); -static const char *GetUnit( AstFrame *, int, int * ); -static const char *SystemLabel( AstSystemType, int * ); -static const char *SystemString( AstFrame *, AstSystemType, int * ); -static const char *TimeScaleString( AstTimeScaleType, int * ); -static double CurrentTime( AstTimeFrame *, int * ); -static double FromMJD( AstTimeFrame *, double, int * ); -static double GetEpoch( AstFrame *, int * ); -static double GetTimeOriginCur( AstTimeFrame *, int * ); -static double ToMJD( AstSystemType, double, int * ); -static double ToUnits( AstTimeFrame *, const char *, double, const char *, int * ); -static int DateFormat( const char *, int *, char *, int * ); -static int Fields( AstFrame *, int, const char *, const char *, int, char **, int *, double *, int * ); -static int GetActiveUnit( AstFrame *, int * ); -static int MakeTimeMapping( AstTimeFrame *, AstTimeFrame *, AstTimeFrame *, int, AstMapping **, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int TestActiveUnit( AstFrame *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void OriginScale( AstTimeFrame *, AstTimeScaleType, const char *, int * ); -static void OriginSystem( AstTimeFrame *, AstSystemType, const char *, int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void SetUnit( AstFrame *, int, const char *, int * ); -static void VerifyAttrs( AstTimeFrame *, const char *, const char *, const char *, int * ); -static AstMapping *ToMJDMap( AstSystemType, double, int * ); -static int Unformat( AstFrame *, int, const char *, double *, int * ); -static const char *Abbrev( AstFrame *, int, const char *, const char *, const char *, int * ); -static double Centre( AstFrame *, int, double, double, int * ); -static double Gap( AstFrame *, int, double, int *, int * ); - -static AstSystemType GetSystem( AstFrame *, int * ); -static void SetSystem( AstFrame *, AstSystemType, int * ); -static void ClearSystem( AstFrame *, int * ); - -static double GetTimeOrigin( AstTimeFrame *, int * ); -static int TestTimeOrigin( AstTimeFrame *, int * ); -static void ClearTimeOrigin( AstTimeFrame *, int * ); -static void SetTimeOrigin( AstTimeFrame *, double, int * ); - -static double GetLTOffset( AstTimeFrame *, int * ); -static int TestLTOffset( AstTimeFrame *, int * ); -static void ClearLTOffset( AstTimeFrame *, int * ); -static void SetLTOffset( AstTimeFrame *, double, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static AstTimeScaleType GetAlignTimeScale( AstTimeFrame *, int * ); -static int TestAlignTimeScale( AstTimeFrame *, int * ); -static void ClearAlignTimeScale( AstTimeFrame *, int * ); -static void SetAlignTimeScale( AstTimeFrame *, AstTimeScaleType, int * ); - -static AstTimeScaleType GetTimeScale( AstTimeFrame *, int * ); -static int TestTimeScale( AstTimeFrame *, int * ); -static void ClearTimeScale( AstTimeFrame *, int * ); -static void SetTimeScale( AstTimeFrame *, AstTimeScaleType, int * ); - -/* Member functions. */ -/* ================= */ -static const char *Abbrev( AstFrame *this_frame, int axis, const char *fmt, - const char *str1, const char *str2, int *status ) { -/* -* Name: -* Abbrev - -* Purpose: -* Abbreviate a formatted Frame axis value by skipping leading fields. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *Abbrev( AstFrame *this, int axis, const char *fmt, -* const char *str1, const char *str2, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astAbbrev protected -* method inherited from the Frame class). - -* Description: -* This function compares two Frame axis values that have been -* formatted (using astFormat) and determines if they have any -* redundant leading fields (i.e. leading fields in common which -* can be suppressed when tabulating the values or plotting them on -* the axis of a graph). - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the Frame axis for which the values have been -* formatted (axis numbering starts at zero for the first axis). -* fmt -* Pointer to a constant null-terminated string containing the -* format specification used to format the two values. -* str1 -* Pointer to a constant null-terminated string containing the -* first formatted value. If this is null, the returned pointer -* points to the start of the final field in str2. -* str2 -* Pointer to a constant null-terminated string containing the -* second formatted value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer into the "str2" string which locates the first -* character in the first field that differs between the two -* formatted values. -* -* If the two values have no leading fields in common, the returned -* value will point at the start of string "str2". If the two -* values are equal, it will point at the terminating null at the -* end of this string. - -* Notes: -* - This function assumes that the format specification used was -* the same when both values were formatted and that they both -* apply to the same Frame axis. -* - A pointer to the start of "str2" will be returned if this -* function is invoked with the global error status set, or if it -* should fail for any reason. -*- -*/ - -/* Local Variables: */ - const char *p1; - const char *p2; - const char *result; - int df; - int nc1; - int nc2; - int ndp; - -/* Initialise. */ - result = str2; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate the axis index. */ - astValidateAxis( this_frame, axis, 1, "astAbbrev" ); - -/* Use the parent astAbbrev function unless the Format attribute indicates - that axis values are to be formatted as multi-field date/time strings. */ - df = DateFormat( fmt, &ndp, NULL, status ); - if( !df ) { - result = (*parent_abbrev)( this_frame, axis, fmt, str1, str2, status ); - -/* Otherwise, if no "str1" string was supplied find the start of the - last field in "str2". */ - } else if( !str1 ){ - -/* Initialise a pointer to the start of the next field in the "str2" string - (skip leading spaces). */ - p2 = str2; - while( *p2 && isspace( *p2 ) ) p2++; - -/* Check the entire string, saving the start of the next field as the - returned pointer. */ - while( *p2 ) { - result = p2; - -/* Each field in a date/time field consists of digits only (and maybe a - decimal point). Find the number of leading digits/dots in this field - and increment the point to the following character (the first delimiter - character). */ - p2 += strspn( p2, "0123456789." ); - -/* Skip inter-field (non-numeric) delimiters. */ - p2 += strcspn( p2, "0123456789." ); - } - -/* Otherwise, if an "str1" string was supplied find the start of the - first differing field in "str2". */ - } else { - -/* Initialise pointers to the start of the next field in each string - (skip leading spaces). */ - p1 = str1; - p2 = str2; - while( *p1 && isspace( *p1 ) ) p1++; - while( *p2 && isspace( *p2 ) ) p2++; - -/* Check the entire string */ - result = p2; - while( *p1 && *p2 ) { - -/* Each field in a date/time field consists of digits only (and maybe a - decimal point). Find the number of leading digits/dots in each string */ - nc1 = strspn( p1, "0123456789." ); - nc2 = strspn( p2, "0123456789." ); - -/* If the next field has different lengths in the two strings, or of the - content of the fields differ, break out of th eloop, leaving "result" - pointing to the start of the current field. */ - if( nc1 != nc2 || strncmp( p1, p2, nc1 ) ) { - break; - -/* If the next field is identical in the two strings, skip to the - character following the end of the field. */ - } else { - p1 += nc1; - p2 += nc2; - -/* Skip inter-field (non-numeric) delimiters. */ - p1 += strcspn( p1, "0123456789." ); - p2 += strcspn( p2, "0123456789." ); - } - -/* Prepare to check the next field. */ - result = p2; - } - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = str2; - -/* Return the result. */ - return result; -} - -static double Centre( AstFrame *this_frame, int axis, double value, - double gap, int *status ) { -/* -* Name: -* Centre - -* Purpose: -* Find a "nice" central value for tabulating Frame axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double Centre( AstFrame *this_frame, int axis, double value, -* double gap, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the protected astCentre method -* inherited from the Frame class). - -* Description: -* This function returns an axis value which produces a nice formatted -* value suitable for a major tick mark on a plot axis, close to the -* supplied axis value. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which a central value -* is to be found. -* value -* An arbitrary axis value in the section that is being plotted. -* gap -* The gap size. - -* Returned Value: -* The nice central axis value. - -* Notes: -* - The supplied axis value is returned if the supplied gap size is -* zero, or if this function is invoked with the global error status -* set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTimeFrame *this; - char *date1; - char *date2; - char *f1; - char *f2; - char *fres; - char *p1; - char *p2; - char *pres; - const char *fmt; - const char *date; - double result; - int df; - int fmod; - int nc1; - int nc2; - int ndp; - int nres; - int v1; - int v2; - -/* Initialise. */ - result = value; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate the axis index. */ - astValidateAxis( this_frame, axis, 1, "astCentre" ); - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* Use the parent astCentre function unless the Format attribute indicates - that axis values are to be formatted as multi-field date/time strings. */ - fmt = astGetFormat( this, 0 ); - df = DateFormat( fmt, &ndp, NULL, status ); - if( !df ) { - result = (*parent_centre)( this_frame, axis, value, gap, status ); - -/* Otherwise. */ - } else { - -/* Format time values one gap above the supplied axis value and one gap below - it. Take copies of each string since the astFormat buffer will be - over-written by each call. */ - date = astFormat( this, 0, value - gap ); - if( date ) date1 = astStore( NULL, date, strlen( date ) + 1 ); - date = astFormat( this, 0, value + gap ); - if( date ) date2 = astStore( NULL, date, strlen( date ) + 1 ); - if( astOK ) { - -/* Initialise a formatted version of the returned central value to be - equal to "date1". */ - nres = strlen( date1 ); - fres = astStore( NULL, date1, nres + 1 ); - -/* Loop over all characters within the first date. */ - fmod = 0; - nc1 = 0; - f1 = NULL; - p1 = date1; - nc2 = 0; - f2 = NULL; - p2 = date2; - while( 1 ) { - -/* If we have not yet found the length of the next numerical field in - date1, continue looking for it. */ - if( !nc1 ) { - -/* If we are currently looking for the start of a numerical field, indicate - we have found one if the current character is a digit. */ - if( !f1 ) { - if( isdigit( *p1 ) ) f1 = p1; - -/* If we are currently looking for the end of a numeric field, we have - found the end if the current character is not a digit. */ - } else { - if( !isdigit( *p1 ) ) { - nc1 = p1 - f1; - } - } - -/* Look at the next character */ - p1++; - } - -/* If we have not yet found the length of the next numerical field in - date2, continue looking for it. */ - if( !nc2 ) { - -/* If we are currently looking for the start of a numerical field, indicate - we have found one if the current character is a digit. */ - if( !f2 ) { - if( isdigit( *p2 ) ) f2 = p2; - -/* If we are currently looking for the end of a numeric field, we have - found the end if the current character is not a digit. */ - } else { - if( !isdigit( *p2 ) ) { - nc2 = p2 - f2; - } - } - -/* Look at the next character */ - p2++; - } - -/* If we have found the next numerical field in both dates, convert them - to integers. */ - if( nc1 && nc2 ) { - v1 = atoi( f1 ); - v2 = atoi( f2 ); - -/* If the values are different, replace this field and all subsequent - fields with zeros in the formatted version of the returned central - value, and leave the loop. */ - if( v1 != v2 ) { - - pres = fres + ( f1 - date1 ) - 1; - while( *(++pres) ) { - if( isdigit( *pres ) ) *pres = '0'; - } - fmod = 1; - - break; - } - -/* Prepare to look for the next numerical field in both strings. */ - nc1 = nc2 = 0; - f1 = f2 = NULL; - -/* If either string has been exhausted, leave the loop. */ - if( !*p1 || !*p2 ) break; - } - } - -/* If the formatted "nice" value was changed, unformatted it to get the - returned axis value. Otherwise we rettina the returned value set - earlier. */ - if( fmod ) { - if( astUnformat( this, 0, fres, &result ) != nres && astOK ) { - astError( AST__INTER, "astCentre(%s): Error unformatting " - "the central time axis value '%s' (internal AST " - "programming error).", status, astClass( this ), fres ); - } - } - -/* Free resources. */ - fres = astFree( fres ); - } - date1 = astFree( date1 ); - date2 = astFree( date2 ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static int DateFormat( const char *fmt, int *ndp, char *sep, int *status ){ -/* -* Name: -* DateFormat - -* Purpose: -* Determine if TimeFrame values should be formatted as a date. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* int DateFormat( const char *fmt, int *ndp, char *sep, int *status ) - -* Class Membership: -* TimeFrame member function - -* Description: -* This function returns a flag indicating if the supplied Format string -* requires the TimeFrame value to be formatted as a date and/or time of -* day. - -* Parameters: -* fmt -* Pointer to Format string. -* ndp -* A pointer to an integer in which is returned a value indicating -* if a time is required as well as a date. A value of -1 will be -* returned in no time is required, otherwise the returned value will -* equal the number of decimal places required for the seconds field. -* sep -* A pointer to a char in which is returned the character that -* should be used to separate the date and time fields. Ignored if -* NULL. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the formatted TimeFrame value should include a date. - -*/ - -/* Local Variables: */ - const char *c; - int nc; - int result; - -/* Initialise */ - result = 0; - *ndp = -1; - -/* Check the Format string */ - if( fmt ) { - -/* Find the first non-white character */ - c = fmt; - while( *c && isspace( *c ) ) c++; - -/* If the first non-white character starts the string "iso" - assume a date is required. If so see if a time is also required - (indicated by 1 dot following) and how many seconds of precision are - required (the interegr following the dot). */ - if( !strncmp( c, "iso", 3 ) ) { - result = 1; - if( astSscanf( c, "iso.%d%n", ndp, &nc ) == 1 ) { - -/* Check the separate character (if any) at the end of the format string. - Only "T" is allowed. A space is used if no separator is given. */ - if( sep ) *sep = ( c[ nc ] == 'T' || c[ nc ] == 't' ) ? 'T' : ' '; - - } else { - *ndp = -1; - } - } - } - - return result; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astClearAttrib protected -* method inherited from the Frame class). - -* Description: -* This function clears the value of a specified attribute for a -* TimeFrame, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the TimeFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -*/ - -/* Local Variables: */ - AstTimeFrame *this; /* Pointer to the TimeFrame structure */ - char *new_attrib; /* Pointer value to new attribute name */ - int len; /* Length of attrib string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* First look for axis attributes defined by the Frame class. Since a - TimeFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strcmp( attrib, "direction" ) || - !strcmp( attrib, "bottom" ) || - !strcmp( attrib, "top" ) || - !strcmp( attrib, "format" ) || - !strcmp( attrib, "label" ) || - !strcmp( attrib, "symbol" ) || - !strcmp( attrib, "unit" ) ) { - -/* Create a new attribute name from the original by appending the string - "(1)" and then use the parent ClearAttrib method. */ - new_attrib = astMalloc( len + 4 ); - if( new_attrib ) { - memcpy( new_attrib, attrib, len ); - memcpy( new_attrib + len, "(1)", 4 ); - (*parent_clearattrib)( this_object, new_attrib, status ); - new_attrib = astFree( new_attrib ); - } - -/* AlignTimeScale. */ -/* --------------- */ - } else if ( !strcmp( attrib, "aligntimescale" ) ) { - astClearAlignTimeScale( this ); - -/* ClockLat. */ -/* --------- */ -/* Retained for backward compatibility with older versions of AST in which - TimeFrame had ClockLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "clocklat" ) ) { - astClearAttrib( this, "obslat" ); - -/* ClockLon. */ -/* --------- */ -/* Retained for backward compatibility with older versions of AST in which - TimeFrame had ClockLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "clocklon" ) ) { - astClearAttrib( this, "obslon" ); - -/* LTOffset. */ -/* --------- */ - } else if ( !strcmp( attrib, "ltoffset" ) ) { - astClearLTOffset( this ); - -/* TimeOrigin. */ -/* ---------- */ - } else if ( !strcmp( attrib, "timeorigin" ) ) { - astClearTimeOrigin( this ); - -/* TimeScale. */ -/* ---------- */ - } else if ( !strcmp( attrib, "timescale" ) ) { - astClearTimeScale( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearSystem - -* Purpose: -* Clear the System attribute for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* void ClearSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astClearSystem protected -* method inherited from the Frame class). - -* Description: -* This function clears the System attribute for a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstSystemType oldsys; /* System before clearing */ - AstTimeFrame *this; /* Pointer to TimeFrame structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* Save the original system */ - oldsys = astGetSystem( this_frame ); - -/* Use the parent ClearSystem method to clear the System value. */ - (*parent_clearsystem)( this_frame, status ); - -/* Do nothing more if the system has not actually changed. */ - if( astGetSystem( this_frame ) != oldsys ) { - -/* Modify the TimeOrigin value to use the new System */ - OriginSystem( this, oldsys, "astClearSystem", status ); - -/* Clear attributes which have system-specific defaults. */ - astClearLabel( this_frame, 0 ); - astClearSymbol( this_frame, 0 ); - astClearTitle( this_frame ); - -/* If the old system was BEPOCH also clear units and timescale. This is - because we need to ensure that TimeScale=TT and Unit=yr will be used - in future (these are the only acceptable values for System=BEPOCH). */ - if( oldsys == AST__BEPOCH ) { - astClearUnit( this_frame, 0 ); - astClearTimeScale( (AstTimeFrame *) this_frame ); - } - } -} - -static void ClearTimeScale( AstTimeFrame *this, int *status ) { -/* -*+ -* Name: -* astClearTimeScale - -* Purpose: -* Clear the TimeScale attribute for a TimeFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* void astClearTimeScale( AstTimeFrame *this ) - -* Class Membership: -* TimeFrame virtual function - -* Description: -* This function clears the TimeScale attribute for a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If the System is currently set to BEPOCH, then the TimeScale will - either be set to TT or will be unset (since SetTimeScale will not - allow any other value than TT if the System is BEPOCH). Therefore, if - System is BEPOCH, we will not need to modify the TimeOrigin value, - since it will already be appropriate. Otherwise, we modify the - TimeOrigin value stored in the TimeFrame structure to refer to the - default timescale (TAI or TT). */ - if( astGetSystem( this ) != AST__BEPOCH ) OriginScale( this, AST__TAI, - "astClearTimeScale", status ); - -/* Store a bad value for the timescale in the TimeFrame structure. */ - this->timescale = AST__BADTS; -} - -static double CurrentTime( AstTimeFrame *this, int *status ){ -/* -*++ -* Name: -c astCurrentTime -f AST_CURRENTTIME - -* Purpose: -* Return the current system time. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "timeframe.h" -c double astCurrentTime( AstTimeFrame *this ) -f RESULT = AST_CURRENTTIME( THIS, STATUS ) - -* Class Membership: -* TimeFrame method. - -* Description: -c This function -f This routine -* returns the current system time, represented in the form specified -* by the supplied TimeFrame. That is, the returned floating point -* value should be interpreted using the attribute values of the -* TimeFrame. This includes System, TimeOrigin, LTOffset, TimeScale, -* and Unit. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the TimeFrame. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astCurrentTime() -f AST_CURRENTTIME = DOUBLE -c A TimeFrame axis value representing the current system time. - -* Notes: -* - Values of AST__BAD will be returned if this function is -c invoked with the AST error status set, or if it should fail for -f invoked with STATUS set to an error value, or if it should fail for -* any reason. -* - It is assumes that the system time (returned by the C time() -* function) follows the POSIX standard, representing a continuous -* monotonic increasing count of SI seconds since the epoch 00:00:00 -* UTC 1 January 1970 AD (equivalent to TAI with a constant offset). -* Resolution is one second. -* - An error will be reported if the TimeFrame has a TimeScale value -* which cannot be converted to TAI (e.g. "angular" systems such as -* UT1, GMST, LMST and LAST). -* - Any inaccuracy in the system clock will be reflected in the value -* returned by this function. -*-- -*/ - -/* Local Constants: */ - -/* Local Variables: */ - AstMapping *map; - double result; - double systime; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a Mapping from the system time (TAI seconds relative to "tai_epoch") - to the system represented by the supplied TimeFrame. */ - map = MakeMap( this, AST__MJD, astGetSystem( this ), - AST__TAI, astGetTimeScale( this ), - tai_epoch, astGetTimeOrigin( this ), - "s", astGetUnit( this, 0 ), "astCurrentTime", status ); - if( !map ) { - astError( AST__INCTS, "astCurrentTime(%s): Cannot convert the " - "current system time to the required timescale (%s).", status, - astGetClass( this ), - TimeScaleString( astGetTimeScale( this ), status ) ); - -/* Get the system time. The "time" function returns a "time_t" which may be - encoded in any way. We use "difftime" to convert this into a floating - point number of seconds by taking the difference between the current - time and zero time. This assumes nothing about the structure of a - "time_t" except that zero can be cast into a time_t representing - the epoch. */ - } else { - systime = difftime( time( NULL ), (time_t) 0 ); - -/* Use the Mapping to convert the time into the requied system. */ - astTran1( map, 1, &systime, 1, &result ); - -/* Free resources */ - map = astAnnul( map ); - } - -/* Set result to AST__BAD if an error occurred. */ - if( !astOK ) result = AST__BAD; - -/* Return the result. */ - return result; -} - -static const char *DefUnit( AstSystemType system, const char *method, - const char *class, int *status ){ -/* -* Name: -* DefUnit - -* Purpose: -* Return the default units for a time coordinate system type. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *DefUnit( AstSystemType system, const char *method, -* const char *class, int *status ) - -* Class Membership: -* TimeFrame member function. - -* Description: -* This function returns a textual representation of the default -* units associated with the specified time coordinate system. - -* Parameters: -* system -* The time coordinate system. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A string describing the default units. This string follows the -* units syntax described in FITS WCS paper I "Representations of world -* coordinates in FITS" (Greisen & Calabretta). - -* Notes: -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Value to return */ - -/* Initialize */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get an identifier for the default units. */ - if( system == AST__MJD ) { - result = "d"; - } else if( system == AST__JD ) { - result = "d"; - } else if( system == AST__BEPOCH ) { - result = "yr"; - } else if( system == AST__JEPOCH ) { - result = "yr"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "%s(%s): Corrupt %s contains illegal System " - "identification code (%d).", status, method, class, class, - (int) system ); - } - -/* Return the result. */ - return result; -} - -static int Fields( AstFrame *this_frame, int axis, const char *fmt, - const char *str, int maxfld, char **fields, - int *nc, double *val, int *status ) { -/* -* Name: -* Fields - -* Purpose: -* Identify numerical fields within a formatted Axis value. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "frame.h" -* int Fields( AstFrame *this, int axis, const char *fmt, -* const char *str, int maxfld, char **fields, -* int *nc, double *val ) - -* Class Membership: -* TimeFrame member function (over-rides the astFields protected -* method inherited from the Frame class). - -* Description: -* This function identifies the numerical fields within a Frame axis -* value that has been formatted using astAxisFormat. It assumes that -* the value was formatted using the supplied format string. It also -* returns the equivalent floating point value. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the Frame axis for which the values have been -* formatted (axis numbering starts at zero for the first axis). -* fmt -* Pointer to a constant null-terminated string containing the -* format used when creating "str". -* str -* Pointer to a constant null-terminated string containing the -* formatted value. -* maxfld -* The maximum number of fields to identify within "str". -* fields -* A pointer to an array of at least "maxfld" character pointers. -* Each element is returned holding a pointer to the start of the -* corresponding field in "str" (in the order in which they occur -* within "str"), or NULL if no corresponding field can be found. -* nc -* A pointer to an array of at least "maxfld" integers. Each -* element is returned holding the number of characters in the -* corresponding field, or zero if no corresponding field can be -* found. -* val -* Pointer to a location at which to store the value -* equivalent to the returned field values. If this is NULL, -* it is ignored. - -* Returned Value: -* The number of fields succesfully identified and returned. - -* Notes: -* - Leading and trailing spaces are ignored. -* - If the formatted value is not consistent with the supplied format -* string, then a value of zero will be returned, "fields" will be -* returned holding NULLs, "nc" will be returned holding zeros, and -* "val" is returned holding VAL__BAD. -* - Fields are counted from the start of the formatted string. If the -* string contains more than "maxfld" fields, then trailing fields are -* ignored. -*/ - -/* Local Variables: */ - AstTimeFrame *this; - char *p; - int bad; - int df; - int ifld; - int ndp; - int result; - int state; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astFields" ); - -/* Call the method inherited from the parent Frame class, unless the - format string indicates date-time formatting. */ - df = DateFormat( fmt, &ndp, NULL, status ); - if( !df ) { - result = (*parent_fields)( this_frame, axis, fmt, str, maxfld, fields, - nc, val, status ); - -/* Now handle date/time formats.... */ - } else { - -/* Initialise. */ - for( ifld = 0; ifld < maxfld; ifld++ ) { - fields[ ifld ] = NULL; - nc[ ifld ] = 0; - } - if( val ) *val = AST__BAD; - -/* The formatted string should always include a date in ISO format - three - integer fields separated by dashes. Loop round each character until - all characters have been read, or the max number of fields have been - obtained, or it is shown that the string is badly formatted. */ - bad = 0; - state = 0; - ifld = 0; - p = (char *) str - 1; - while( *(++p) && ifld < maxfld && !bad ){ - -/* Looking for the start of the year field. */ - if( state == 0 ) { - if( isdigit( *p ) ) { - fields[ ifld ] = p; - nc[ ifld ] = 1; - state = 1; - } else if( !isspace( *p ) ) { - bad = 1; - } - -/* Looking for the end of the year field. */ - } else if( state == 1 ) { - if( isdigit( *p ) ) { - nc[ ifld ]++; - } else if( *p != '-' ){ - bad = 1; - } else { - state = 2; - ifld++; - } - -/* Looking for the start of the month field. */ - } else if( state == 2 ) { - if( isdigit( *p ) ) { - fields[ ifld ] = p; - nc[ ifld ] = 1; - state = 3; - } else { - bad = 1; - } - -/* Looking for the end of the month field. */ - } else if( state == 3 ) { - if( isdigit( *p ) ) { - nc[ ifld ]++; - } else if( *p != '-' ){ - bad = 1; - } else { - state = 4; - ifld++; - } - -/* Looking for the start of the day field. */ - } else if( state == 4 ) { - if( isdigit( *p ) ) { - fields[ ifld ] = p; - nc[ ifld ] = 1; - state = 5; - } else { - bad = 1; - } - -/* Looking for the end of the day field. */ - } else if( state == 5 ) { - if( isdigit( *p ) ) { - nc[ ifld ]++; - } else if( *p != ' ' && *p != 'T' ){ - bad = 1; - } else { - state = 6; - ifld++; - } - -/* Looking for the start of the hour field. */ - } else if( state == 6 ) { - if( isdigit( *p ) ) { - fields[ ifld ] = p; - nc[ ifld ] = 1; - state = 7; - } else { - bad = 1; - } - -/* Looking for the end of the hour field. */ - } else if( state == 7 ) { - if( isdigit( *p ) ) { - nc[ ifld ]++; - } else if( *p != ':' ){ - bad = 1; - } else { - state = 8; - ifld++; - } - -/* Looking for the start of the minute field. */ - } else if( state == 8 ) { - if( isdigit( *p ) ) { - fields[ ifld ] = p; - nc[ ifld ] = 1; - state = 9; - } else { - bad = 1; - } - -/* Looking for the end of the minute field. */ - } else if( state == 9 ) { - if( isdigit( *p ) ) { - nc[ ifld ]++; - } else if( *p != ':' ){ - bad = 1; - } else { - state = 10; - ifld++; - } - -/* Looking for the start of the integer part of the seconds field. */ - } else if( state == 10 ) { - if( isdigit( *p ) ) { - fields[ ifld ] = p; - nc[ ifld ] = 1; - state = 11; - } else { - bad = 1; - } - -/* Looking for the end of the integer part of the seconds field. */ - } else if( state == 11 ) { - if( isdigit( *p ) ) { - nc[ ifld ]++; - } else if( *p != '.' ){ - bad = 1; - } else { - state = 12; - ifld++; - } - -/* Looking for the start of the decimal part of the seconds field. */ - } else if( state == 12 ) { - if( isdigit( *p ) ) { - fields[ ifld ] = p; - nc[ ifld ] = 1; - state = 13; - } else { - bad = 1; - } - -/* Looking for the end of the decimal part of the seconds field. */ - } else if( state == 13 ) { - if( isdigit( *p ) ) { - nc[ ifld ]++; - } else if( !isspace( *p ) ){ - bad = 1; - } - - } else { - bad = 1; - } - } - -/* If he string is badly formatted, return null values. */ - if( bad ) { - result = 0; - for( ifld = 0; ifld < maxfld; ifld++ ) { - fields[ ifld ] = NULL; - nc[ ifld ] = 0; - } - -/* Otherwise, unformat the string if required. */ - } else if( val ) { - (void) astUnformat( this, axis, str, val ); - } - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0; - -/* Return the result. */ - return result; -} - -static const char *Format( AstFrame *this_frame, int axis, double value, int *status ) { -/* -* Name: -* Format - -* Purpose: -* Format a coordinate value for a TimeFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *Format( AstFrame *this, int axis, double value, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astFormat method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to a string containing the formatted -* (character) version of a coordinate value for a TimeFrame axis. The -* formatting applied is that specified by a previous invocation of the -* astSetFormat method. A suitable default format is applied if necessary. - -* Parameters: -* this -* Pointer to the TimeFrame. -* axis -* The number of the axis (zero-based) for which formatting is to be -* performed. -* value -* The coordinate value to be formatted, in radians. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a null-terminated string containing the formatted value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - AstMapping *map; - AstSystemType sys; - AstTimeFrame *this; - AstTimeScaleType ts; - char *d; - char sep; - char tbuf[ 100 ]; - char sign[ 2 ]; - const char *fmt; - const char *result; - const char *u; - double fd; - double mjd; - double off; - int df; - int id; - int ihmsf[ 4 ]; - int im; - int iy; - int j; - int ndp; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_frame); - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astFormat" ); - -/* Check if a bad coordinate value was supplied and return a pointer to an - appropriate string if necessary. */ - if ( value == AST__BAD ) { - result = ""; - } else { - -/* If the format string does not indicate a date/time format, invoke the - parent Format method. */ - fmt = astGetFormat( this, 0 ); - df = DateFormat( fmt, &ndp, &sep, status ); - if( !df ) { - result = (*parent_format)( this_frame, axis, value, status ); - -/* Otherwise, format the value as a date/time */ - } else { - -/* Convert the value to an absolute MJD in units of days. */ - ts = astGetTimeScale( this ); - sys = astGetSystem( this ); - off = astGetTimeOrigin( this ); - u = astGetUnit( this, 0 ); - map = MakeMap( this, sys, AST__MJD, ts, ts, off, 0.0, u, "d", - "astFormat", status ); - if( map ) { - astTran1( map, 1, &value, 1, &mjd ); - map = astAnnul( map ); - -/* If no time fields will be produced, round to the nearest day. */ - if( ndp < 0 ) mjd = (int) ( mjd + 0.5 ); - -/* Convert the MJD into a set of numeric date fields, plus day fraction, - and format them. */ - palDjcl( mjd, &iy, &im, &id, &fd, &j ); - d = format_buff; - d += sprintf( d, "%4d-%2.2d-%2.2d", iy, im, id ); - -/* If required, convert the day fraction into a set of numerical time - fields. */ - if( ndp >= 0 ) { - palDd2tf( ndp, fd, sign, ihmsf ); - -/* Format the time fields. */ - if( ndp > 0 ) { - (void) sprintf( tbuf, "%c%2.2d:%2.2d:%2.2d.%*.*d", sep, - ihmsf[0], ihmsf[1], ihmsf[2], ndp, ndp, - ihmsf[3] ); - } else { - (void) sprintf( tbuf, "%c%2.2d:%2.2d:%2.2d", sep, ihmsf[0], - ihmsf[1], ihmsf[2] ); - } - -/* Add in the formatted time. */ - d += sprintf( d, "%s", tbuf ); - - } - result = format_buff; - } - } - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static double FromMJD( AstTimeFrame *this, double oldval, int *status ){ -/* -* -* Name: -* FromMJD - -* Purpose: -* Convert a supplied MJD value to the System of the supplied TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double FromMJD( AstTimeFrame *this, double oldval, int *status ) - -* Class Membership: -* TimeFrame member function - -* Description: -* This function converts the supplied time value from an MJD to -* the System of the supplied TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* oldval -* The value to be converted. It is assume to be an absolute MJD -* value (i.e. zero offset) in units of days. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The converted value (with zero offset), in the default units -* associated with the System of "this". - -*/ - -/* Local Variables: */ - AstTimeMap *timemap; - AstSystemType newsys; - double args[ 2 ]; - double result; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the System attribute from the supplied TimeFrame. */ - newsys = astGetSystem( this ); - -/* If this is MJD just return the value unchanged. */ - if( newsys == AST__MJD ) { - result = oldval; - -/* Otherwise create a TimeMap wich converts from the MJD to the required - system, and use it to transform the supplied value. */ - } else { - timemap = astTimeMap( 0, "", status ); - -/* The supplied and returned values are assumed to have zero offset.*/ - args[ 0 ] = 0.0; - args[ 1 ] = 0.0; - -/* If required, add a TimeMap conversion which converts from MJD to the - new system. */ - if( newsys == AST__JD ) { - astTimeAdd( timemap, "MJDTOJD", 2, args ); - - } else if( newsys == AST__JEPOCH ) { - astTimeAdd( timemap, "MJDTOJEP", 2, args ); - - } else if( newsys == AST__BEPOCH ) { - astTimeAdd( timemap, "MJDTOBEP", 2, args ); - } - -/* Use the TimeMap to convert the supplied value. */ - astTran1( timemap, 1, &oldval, 1, &result ); - -/* Free resources */ - timemap = astAnnul( timemap ); - - } - -/* Return the result */ - return result; -} - - -static double Gap( AstFrame *this_frame, int axis, double gap, int *ntick, int *status ) { -/* -* Name: -* Gap - -* Purpose: -* Find a "nice" gap for tabulating Frame axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double Gap( AstFrame *this, int axis, double gap, int *ntick, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astGap protected -* method inherited from the Frame class). - -* Description: -* This function returns a gap size which produces a nicely spaced -* series of formatted values for a Frame axis, the returned gap -* size being as close as possible to the supplied target gap -* size. It also returns a convenient number of divisions into -* which the gap can be divided. - -* Parameters: -* this -* Pointer to the Frame. -* axis -* The number of the axis (zero-based) for which a gap is to be found. -* gap -* The target gap size. -* ntick -* Address of an int in which to return a convenient number of -* divisions into which the gap can be divided. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The nice gap size. - -* Notes: -* - A value of zero is returned if the target gap size is zero. -* - A negative gap size is returned if the supplied gap size is negative. -* - A value of zero will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *map; - AstTimeFrame *this; - AstTimeScaleType ts; - const char *fmt; - double mjdgap; - double result; - double xin[2]; - double xout[2]; - int df; - int ndp; - -/* Initialise. */ - result = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Validate the axis index. */ - astValidateAxis( this_frame, axis, 1, "astGap" ); - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* Use the parent astGap function unless the Format attribute indicates - that axis values are to be formatted as multi-field date/time strings. */ - fmt = astGetFormat( this, 0 ); - df = DateFormat( fmt, &ndp, NULL, status ); - if( !df ) { - result = (*parent_gap)( this_frame, axis, gap, ntick, status ); - -/* Otherwise. */ - } else { - -/* Get a Mapping which converts TimeFrame values to MJD values. */ - ts = astGetTimeScale( this ); - map = MakeMap( this, astGetSystem( this ), AST__MJD, ts, ts, - astGetTimeOrigin( this ), 0.0, astGetUnit( this, 0 ), - "d", "astGap", status ); - if( map ) { - -/* Use it to transform two TimeFrame times to MJD. The first is the - current time, and the second is the current time plus the target gap. */ - xin[ 0 ] = astCurrentTime( this ); - xin[ 1 ] = xin[ 0 ] + gap; - astTran1( map, 2, xin, 1, xout ); - -/* Find the target MJD gap. */ - mjdgap = xout[ 1 ] - xout[ 0 ]; - -/* If it is 1 year or more, use the parent astGap method to find a nice - number of years, and convert back to days. */ - if( mjdgap >= 365.25 ) { - mjdgap = 365.25*(*parent_gap)( this_frame, axis, mjdgap/365.25, ntick, status ); - -/* If it is more than 270 days days use 1 year. */ - } else if( mjdgap > 270.0 ) { - mjdgap = 365.25; - *ntick = 4; - -/* If it is more than 150 days days use 180 days (roughly half a year). - Use 6 divisions (30 days each, or roughly 1 month). */ - } else if( mjdgap > 150.0 ) { - mjdgap = 180.0; - *ntick = 6; - -/* If it is more than 90 days days use 120 days (roughly 4 months). */ - } else if( mjdgap > 90.0 ) { - mjdgap = 120.0; - *ntick = 4; - -/* If it is more than 45 days days use 60 days (roughly 2 months). */ - } else if( mjdgap > 45.0 ) { - mjdgap = 60.0; - *ntick = 2; - -/* If it is more than 22 days days use 30 days (roughly one month). Use 3 - ten day divisions. */ - } else if( mjdgap > 22.0 ) { - mjdgap = 30.0; - *ntick = 3; - -/* If it is more than 12 days days use 15 days (roughly half a month). */ - } else if( mjdgap > 12.0 ) { - mjdgap = 15.0; - *ntick = 3; - -/* If it is more than 7.5 days days use 10 days, with 5 two-day divisions. */ - } else if( mjdgap > 7.5 ) { - mjdgap = 10.0; - *ntick = 5; - -/* If it is more than 4.5 days days use 5 days. */ - } else if( mjdgap > 4.5 ) { - mjdgap = 5.0; - *ntick = 5; - -/* If it is more than 3 days days use 4 days. */ - } else if( mjdgap > 3.0 ) { - mjdgap = 4.0; - *ntick = 4; - -/* If it is more than 1.5 days days use 2 days. */ - } else if( mjdgap > 1.5 ) { - mjdgap = 2.0; - *ntick = 2; - -/* If it is more than 0.5 of a day use 1 day. */ - } else if( mjdgap > 0.5 ) { - mjdgap = 1.0; - *ntick = 4; - -/* Otherwise, if the format indicates that no time field is allowed, - use 1 day. */ - } else if( ndp < 0 ) { - mjdgap = 1.0; - *ntick = 2; - -/* Otherwise (i.e. if the target gap is 0.5 day or less and the format - indicates that a time field is allowed), choose a value which looks - nice. */ - } else if( mjdgap >= 6.0/24.0 ) { /* 12 hours */ - mjdgap = 12.0/24.0; - *ntick = 4; - - } else if( mjdgap >= 3.0/24.0 ) { /* 6 hours */ - mjdgap = 6.0/24.0; - *ntick = 3; - - } else if( mjdgap >= 1.0/24.0 ) { /* 2 hours */ - mjdgap = 2.0/24.0; - *ntick = 4; - - } else if( mjdgap >= 30.0/1440.0 ) { /* 1 hour */ - mjdgap = 60.0/1440.0; - *ntick = 4; - - } else if( mjdgap >= 15.0/1440.0 ) { /* 30 minutes */ - mjdgap = 30.0/1440.0; - *ntick = 3; - - } else if( mjdgap >= 5.0/1440.0 ) { /* 10 minutes */ - mjdgap = 10.0/1440.0; - *ntick = 5; - - } else if( mjdgap >= 2.5/1440.0 ) { /* 5 minutes */ - mjdgap = 5.0/1440.0; - *ntick = 5; - - } else if( mjdgap >= 1.0/1440.0 ) { /* 2 minutes */ - mjdgap = 2.0/1440.0; - *ntick = 4; - - } else if( mjdgap >= 0.5/1440.0 ) { /* 1 minute */ - mjdgap = 1.0/1440.0; - *ntick = 4; - - } else if( mjdgap >= 15.0/86400.0 ) { /* 30 seconds */ - mjdgap = 30.0/86400.0; - *ntick = 3; - - } else if( mjdgap >= 5.0/86400.0 ) { /* 10 seconds */ - mjdgap = 10.0/86400.0; - *ntick = 5; - - } else if( mjdgap >= 2.5/86400.0 ) { /* 5 seconds */ - mjdgap = 5.0/86400.0; - *ntick = 5; - - } else if( mjdgap >= 1.0/86400.0 ) { /* 2 seconds */ - mjdgap = 2.0/86400.0; - *ntick = 4; - - } else if( mjdgap >= 0.5/86400.0 ) { /* 1 second */ - mjdgap = 1.0/86400.0; - *ntick = 4; - - } else { /* Less than 1 second */ - mjdgap = 86400.0*(*parent_gap)( this_frame, axis, mjdgap/86400.0, ntick, status ); - - } - -/* Convert the MJD gap back into the system of the supplied TimeFrame. */ - xout[ 1 ] = xout[ 0 ] + mjdgap; - astTran1( map, 2, xout, 0, xin ); - result = xin[ 1 ] - xin[ 0 ]; - -/* Free resources */ - map = astAnnul( map ); - -/* If no Mapping could be found, use the parent astGap method. */ - } else { - result = (*parent_gap)( this_frame, axis, gap, ntick, status ); - } - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = 0.0; - -/* Return the result. */ - return result; -} - -static int GetActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetActiveUnit - -* Purpose: -* Obtain the value of the ActiveUnit flag for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* int GetActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astGetActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function returns the value of the ActiveUnit flag for a -* TimeFrame, which is always 1. - -* Parameters: -* this -* Pointer to the TimeFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to use for the ActiveUnit flag (1). - -*/ - return 1; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the protected astGetAttrib -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a TimeFrame, formatted as a character string. - -* Parameters: -* this -* Pointer to the TimeFrame. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - The returned string pointer may point at memory allocated -* within the TimeFrame, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the TimeFrame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstTimeFrame *this; /* Pointer to the TimeFrame structure */ - AstTimeScaleType ts; /* Time scale */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - char *new_attrib; /* Pointer value to new attribute name */ - const char *result; /* Pointer value to return */ - double dval; /* Attribute value */ - int len; /* Length of attrib string */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* First look for axis attributes defined by the Frame class. Since a - TimeFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strcmp( attrib, "direction" ) || - !strcmp( attrib, "bottom" ) || - !strcmp( attrib, "top" ) || - !strcmp( attrib, "format" ) || - !strcmp( attrib, "label" ) || - !strcmp( attrib, "symbol" ) || - !strcmp( attrib, "unit" ) ) { - -/* Create a new attribute name from the original by appending the string - "(1)" and then use the parent GetAttrib method. */ - new_attrib = astMalloc( len + 4 ); - if( new_attrib ) { - memcpy( new_attrib, attrib, len ); - memcpy( new_attrib + len, "(1)", 4 ); - result = (*parent_getattrib)( this_object, new_attrib, status ); - new_attrib = astFree( new_attrib ); - } - -/* AlignTimeScale. */ -/* --------------- */ -/* Obtain the AlignTimeScale code and convert to a string. */ - } else if ( !strcmp( attrib, "aligntimescale" ) ) { - ts = astGetAlignTimeScale( this ); - if ( astOK ) { - result = TimeScaleString( ts, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid AlignTimeScale " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) ts ); - } - } - -/* ClockLat. */ -/* ------- */ - } else if ( !strcmp( attrib, "clocklat" ) ) { - result = astGetAttrib( this, "obslat" ); - -/* ClockLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "clocklon" ) ) { - result = astGetAttrib( this, "obslon" ); - -/* TimeOrigin. */ -/* ----------- */ - } else if ( !strcmp( attrib, "timeorigin" ) ) { - dval = GetTimeOriginCur( this, status ); - if( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* LTOffset. */ -/* --------- */ - } else if ( !strcmp( attrib, "ltoffset" ) ) { - dval = astGetLTOffset( this ); - if( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* TimeScale. */ -/* ---------- */ -/* Obtain the TimeScale code and convert to a string. */ - } else if ( !strcmp( attrib, "timescale" ) ) { - ts = astGetTimeScale( this ); - if ( astOK ) { - result = TimeScaleString( ts, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid TimeScale " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) ts ); - } - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static double GetTimeOriginCur( AstTimeFrame *this, int *status ) { -/* -* Name: -* GetTimeOriginCur - -* Purpose: -* Obtain the TimeOrigin attribute for a TimeFrame in current units. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double GetTimeOriginCur( AstTimeFrame *this, int *status ) - -* Class Membership: -* TimeFrame virtual function - -* Description: -* This function returns the TimeOrigin attribute for a TimeFrame, in -* the current units of the TimeFrame. The protected astGetTimeOrigin -* method can be used to obtain the time origin in the default units of -* the TimeFrame's System. - -* Parameters: -* this -* Pointer to the TimeFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The TimeOrigin value, in the units, system and timescale specified -* by the current values of the Unit, System and TimeScale attributes -* within "this". - -* Notes: -* - AST__BAD is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *map; - const char *cur; - const char *def; - double result; - double defval; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the value in the default units */ - result = astGetTimeOrigin( this ); - -/* If non-zero we convert to the current units.*/ - if( result != 0.0 && result != AST__BAD ) { - -/* Get the default units for the TimeFrame's System. */ - def = DefUnit( astGetSystem( this ), "astGetTimeOrigin", "TimeFrame", status ); - -/* Get the current units from the TimeFrame. */ - cur = astGetUnit( this, 0 ); - -/* If the units differ, get a Mapping from default to current units. */ - if( cur && def ){ - if( strcmp( cur, def ) ) { - map = astUnitMapper( def, cur, NULL, NULL ); - -/* Report an error if the units are incompatible. */ - if( !map ) { - astError( AST__BADUN, "%s(%s): The current units (%s) are not suitable " - "for a TimeFrame.", status, "astGetTimeOrigin", astGetClass( this ), - cur ); - -/* Otherwise, transform the stored origin value.*/ - } else { - defval = result; - astTran1( map, 1, &defval, 1, &result ); - map = astAnnul( map ); - } - } - } - } - -/* Return the result. */ - return result; -} - -static const char *GetDomain( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetDomain - -* Purpose: -* Obtain a pointer to the Domain attribute string for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *GetDomain( AstFrame *this, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astGetDomain protected -* method inherited from the Frame class). - -* Description: -* This function returns a pointer to the Domain attribute string -* for a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a constant null-terminated string containing the -* Domain value. - -* Notes: -* - The returned pointer or the string it refers to may become -* invalid following further invocation of this function or -* modification of the TimeFrame. -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTimeFrame *this; /* Pointer to TimeFrame structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* If a Domain attribute string has been set, invoke the parent method - to obtain a pointer to it. */ - if ( astTestDomain( this ) ) { - result = (*parent_getdomain)( this_frame, status ); - -/* Otherwise, provide a pointer to a suitable default string. */ - } else { - result = "TIME"; - } - -/* Return the result. */ - return result; -} - -static double GetEpoch( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetEpoch - -* Purpose: -* Get a value for the Epoch attribute of a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double GetEpoch( AstFrame *this, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astGetEpoch method -* inherited from the Frame class). - -* Description: -* This function returns a value for the Epoch attribute of a -* TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Epoch attribute value. - -* Notes: -* - A value of AST__BAD will be returned if this function is invoked -* with the global error status set or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *map; - AstSystemType sys; - AstTimeFrame *this; - AstTimeScaleType ts; - const char *u; - double oldval; - double result; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* If an Epoch attribute value has been set, invoke the parent method - to obtain it. */ - if ( astTestEpoch( this ) ) { - result = (*parent_getepoch)( this_frame, status ); - -/* Otherwise, if the TimeOrigin value is set in the TimeFrame, - return it, converted to an absolute TDB MJD. */ - } else if( astTestTimeOrigin( this ) ){ - -/* Get the required properties of the TimeFrame. */ - oldval = astGetTimeOrigin( this ); - ts = astGetTimeScale( this ); - sys = astGetSystem( this ); - u = DefUnit( sys, "astGetEpoch", "TimeFrame", status ); - -/* Epoch is defined as a TDB value. If the timescale is stored in an angular - timescale such as UT1, then we would not normally be able to convert it - to TDB since knowledge of DUT1 is required (the difference between UTC - and UT1). Since the default Epoch value is not critical we assume a DUT1 - value of zero in this case. We first map the stored value to UT1 then - from UTC to TDB (using the approximation UT1 == UTC). */ - if( ts == AST__UT1 || ts == AST__GMST || - ts == AST__LAST || ts == AST__LMST ) { - map = MakeMap( this, sys, AST__MJD, ts, AST__UT1, 0.0, 0.0, u, - "d", "astGetEpoch", status ); - if( map ) { - astTran1( map, 1, &oldval, 1, &result ); - map = astAnnul( map ); - -/* Update the values to use when converting to TBD. */ - oldval = result; - ts = AST__UTC; - sys = AST__MJD; - u = "d"; - - } else if( astOK ) { - astError( AST__INTER, "astGetEpoch(%s): No Mapping from %s to " - "UT1 (AST internal programming error).", status, - astGetClass( this ), TimeScaleString( ts, status ) ); - } - } - -/* Now convert to TDB */ - map = MakeMap( this, sys, AST__MJD, ts, AST__TDB, 0.0, 0.0, u, - "d", "astGetEpoch", status ); - if( map ) { - oldval = astGetTimeOrigin( this ); - astTran1( map, 1, &oldval, 1, &result ); - map = astAnnul( map ); - - } else if( astOK ) { - astError( AST__INTER, "astGetEpoch(%s): No Mapping from %s to " - "TDB (AST internal programming error).", status, - astGetClass( this ), TimeScaleString( ts, status ) ); - } - -/* Otherwise, return the default Epoch value from the parent Frame. */ - } else { - result = (*parent_getepoch)( this_frame, status ); - } - -/* Return the result. */ - return result; -} - -static const char *GetLabel( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetLabel - -* Purpose: -* Access the Label string for a TimeFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *GetLabel( AstFrame *this, int axis, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astGetLabel method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Label string for a specified axis -* of a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstMapping *map; /* Mapping between units */ - AstSystemType system; /* Code identifying type of time coordinates */ - char *new_lab; /* Modified label string */ - const char *fmt; /* Pointer to original Format string */ - const char *result; /* Pointer to label string */ - double ltoff; /* Local Time offset from UTC (hours) */ - double orig; /* Time origin (seconds) */ - int fmtSet; /* Was Format attribute set? */ - int ndp; /* Number of decimal places for seconds field */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetLabel" ); - -/* Check if a value has been set for the required axis label string. If so, - invoke the parent astGetLabel method to obtain a pointer to it. */ - if ( astTestLabel( this, axis ) ) { - result = (*parent_getlabel)( this, axis, status ); - -/* Otherwise, provide a suitable default label. */ - } else { - -/* If the Format attribute indicates that time values will be formatted - as dates, then choose a suitable label. */ - fmt = astGetFormat( this, 0 ); - if( DateFormat( fmt, &ndp, NULL, status ) ) { - result = ( ndp >= 0 ) ? "Date/Time" : "Date"; - -/* Otherwise, identify the time coordinate system described by the - TimeFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default label string. */ - if ( astOK ) { - result = strcpy( getlabel_buff, SystemLabel( system, status ) ); - getlabel_buff[ 0 ] = toupper( getlabel_buff[ 0 ] ); - -/* If a non-zero TimeOrigin has been specified, include the offset now as a - date/time string. */ - orig = astGetTimeOrigin( this ); - if( orig != 0.0 ) { - -/* Save the Format attribute, and then temporarily set it to give a date/time - string. */ - fmt = astStore( NULL, fmt, strlen( fmt ) + 1 ); - fmtSet = astTestFormat( this, 0 ); - astSetFormat( this, 0, "iso.0" ); - -/* Format the origin value as an absolute time and append it to the - returned label string. Note, the origin always corresponds to a - TimeFrame axis value of zero. */ - sprintf( getlabel_buff + strlen( getlabel_buff ), " offset from %s", - astFormat( this, 0, 0.0 ) ); - -/* Re-instate the original Format value. */ - if( fmtSet ) { - astSetFormat( this, 0, fmt ); - } else { - astClearFormat( this, 0 ); - } - -/* Free the memory holding the copy of the format string. */ - fmt = astFree( (char *) fmt ); - -/* If the time of day is "00:00:00", remove it. */ - if( !strcmp( getlabel_buff + strlen( getlabel_buff ) - 8, "00:00:00" ) ) { - getlabel_buff[ strlen( getlabel_buff ) - 8 ] = 0; - } - } - -/* Modify this default to take account of the current value of the Unit - attribute, if set. */ - if( astTestUnit( this, axis ) ) { - -/* Find a Mapping from the default Units for the current System, to the - units indicated by the Unit attribute. This Mapping is used to modify - the existing default label appropriately. For instance, if the default - units is "yr" and the actual units is "log(yr)", then the default label - of "Julian epoch" is changed to "log( Julian epoch )". */ - map = astUnitMapper( DefUnit( system, "astGetLabel", - astGetClass( this ), status ), - astGetUnit( this, axis ), result, - &new_lab ); - if( new_lab ) { - result = strcpy( getlabel_buff, new_lab ); - new_lab = astFree( new_lab ); - } - -/* Annul the unused Mapping. */ - if( map ) map = astAnnul( map ); - } - } - } - -/* If the time is a Local Time, indicate the offset from UTC. */ - if( astGetTimeScale( this ) == AST__LT ) { - ltoff = astGetLTOffset( this ); - if( ltoff >= 0.0 ) { - sprintf( getlabel_buff, "%s (UTC+%g)", result, ltoff ); - } else { - sprintf( getlabel_buff, "%s (UTC-%g)", result, -ltoff ); - } - result = getlabel_buff; - } - } - -/* Return the result. */ - return result; -} - -static const char *GetSymbol( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetSymbol - -* Purpose: -* Obtain a pointer to the Symbol string for a TimeFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *GetSymbol( AstFrame *this, int axis, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astGetSymbol method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Symbol string for a specified axis -* of a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstMapping *map; /* Mapping between units */ - AstSystemType system; /* Code identifying type of sky coordinates */ - char *new_sym; /* Modified symbol string */ - const char *result; /* Pointer to symbol string */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetSymbol" ); - -/* Check if a value has been set for the required axis symbol string. If so, - invoke the parent astGetSymbol method to obtain a pointer to it. */ - if ( astTestSymbol( this, axis ) ) { - result = (*parent_getsymbol)( this, axis, status ); - -/* Otherwise, identify the sky coordinate system described by the TimeFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default Symbol string. */ - if ( astOK ) { - - if( system == AST__MJD ) { - result = "MJD"; - } else if( system == AST__JD ) { - result = "JD"; - } else if( system == AST__BEPOCH ) { - result = "BEP"; - } else if( system == AST__JEPOCH ) { - result = "JEP"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "astGetSymbol(%s): Corrupt %s contains " - "invalid System identification code (%d).", status, - astGetClass( this ), astGetClass( this ), (int) system ); - } - -/* Modify this default to take account of the current value of the Unit - attribute, if set. */ - if( astTestUnit( this, axis ) ) { - -/* Find a Mapping from the default Units for the current System, to the - units indicated by the Unit attribute. This Mapping is used to modify - the existing default symbol appropriately. For instance, if the default - units is "yr" and the actual units is "log(yr)", then the default symbol - of "JEP" is changed to "log( JEP )". */ - map = astUnitMapper( DefUnit( system, "astGetSymbol", - astGetClass( this ), status ), - astGetUnit( this, axis ), result, - &new_sym ); - if( new_sym ) { - result = strcpy( getsymbol_buff, new_sym ); - new_sym = astFree( new_sym ); - } - -/* Annul the unused Mapping. */ - if( map ) map = astAnnul( map ); - - } - } - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetAlignSystem - -* Purpose: -* Obtain the AlignSystem attribute for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "Specframe.h" -* AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astGetAlignSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the AlignSystem attribute for a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The AlignSystem value. - -*/ - -/* Local Variables: */ - AstTimeFrame *this; /* Pointer to TimeFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* If a AlignSystem attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestAlignSystem( this ) ) { - result = (*parent_getalignsystem)( this_frame, status ); - -/* Otherwise, provide a suitable default. */ - } else { - result = AST__MJD; - } - -/* Return the result. */ - return result; -} - -static AstTimeScaleType GetAlignTimeScale( AstTimeFrame *this, int *status ) { -/* -*+ -* Name: -* astGetAlignTimeScale - -* Purpose: -* Obtain the AlignTimeScale attribute for a TimeFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* AstTimeScaleType GetAlignTimeScale( AstTimeFrame *this ) - -* Class Membership: -* TimeFrame virtual function - -* Description: -* This function returns the System attribute for a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. - -* Returned Value: -* The System value. - -* Notes: -* - AST__BADTS is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstTimeScaleType result; - AstTimeScaleType ts; - -/* Initialise. */ - result = AST__BADTS; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If a value has been set, return it. */ - if( this->aligntimescale != AST__BADTS ) { - result = this->aligntimescale; - -/* Otherwise, return a default depending on the current TimeScale value */ - } else { - ts = astGetTimeScale( this ); - if ( ts == AST__UT1 || ts == AST__LAST || ts == AST__LMST || ts == AST__GMST ) { - result = AST__UT1; - } else { - result = AST__TAI; - } - - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetSystem - -* Purpose: -* Obtain the System attribute for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* AstSystemType GetSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astGetSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the System attribute for a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System value. - -* Notes: -* - AST__BADSYSTEM is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTimeFrame *this; /* Pointer to TimeFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* If a System attribute has been set, invoke the parent method to obtain - it. */ - if ( astTestSystem( this ) ) { - result = (*parent_getsystem)( this_frame, status ); - -/* Otherwise, provide a suitable default. */ - } else { - result = AST__MJD; - } - -/* Return the result. */ - return result; -} - -static AstTimeScaleType GetTimeScale( AstTimeFrame *this, int *status ) { -/* -*+ -* Name: -* astGetTimeScale - -* Purpose: -* Obtain the TimeScale attribute for a TimeFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* AstTimeScaleType GetTimeScale( AstTimeFrame *this ) - -* Class Membership: -* TimeFrame virtual function - -* Description: -* This function returns the System attribute for a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. - -* Returned Value: -* The System value. - -* Notes: -* - AST__BADTS is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstTimeScaleType result; - -/* Initialise. */ - result = AST__BADTS; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If a value has been set, return it. */ - if( this->timescale != AST__BADTS ) { - result = this->timescale; - -/* Otherwise, return a default depending on the current System value. */ - } else { - if ( astGetSystem( this ) == AST__BEPOCH ) { - result = AST__TT; - } else { - result = AST__TAI; - } - - } - -/* Return the result. */ - return result; -} - -static const char *GetTitle( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetTitle - -* Purpose: -* Obtain a pointer to the Title string for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *GetTitle( AstFrame *this_frame, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astGetTitle method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Title string for a TimeFrame. -* A pointer to a suitable default string is returned if no Title value has -* previously been set. - -* Parameters: -* this -* Pointer to the TimeFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null-terminated character string containing the requested -* information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstSystemType system; /* Code identifying type of coordinates */ - AstTimeScaleType ts; /* Time scale value */ - AstTimeFrame *this; /* Pointer to TimeFrame structure */ - const char *fmt; /* Pointer to original Format string */ - const char *result; /* Pointer to result string */ - double ltoff; /* Local Time offset from UTC (hours) */ - double orig; /* Time origin (seconds) */ - int fmtSet; /* Was Format attribute set? */ - int nc; /* No. of characters added */ - int ndp; /* Number of decimal places */ - int pos; /* Buffer position to enter text */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_frame); - -/* Initialise. */ - result = NULL; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* See if a Title string has been set. If so, use the parent astGetTitle - method to obtain a pointer to it. */ - if ( astTestTitle( this ) ) { - result = (*parent_gettitle)( this_frame, status ); - -/* Otherwise, we will generate a default Title string. Obtain the values of the - TimeFrame's attributes that determine what this string will be. */ - } else { - system = astGetSystem( this ); - orig = GetTimeOriginCur( this, status ); - ts = astGetTimeScale( this ); - if ( astOK ) { - result = gettitle_buff; - -/* Begin with the system's default label. */ - pos = sprintf( gettitle_buff, "%s", SystemLabel( system, status ) ); - gettitle_buff[ 0 ] = toupper( gettitle_buff[ 0 ] ); - -/* Append the time scale code, if a value has been set for the timescale. - Do not do this if the system is BEPOCH since BEPOCH can only be used - with the TT timescale. */ - if( system != AST__BEPOCH && astTestTimeScale( this ) ) { - nc = sprintf( gettitle_buff + pos, " [%s", TimeScaleString( ts, status ) ); - pos += nc; - -/* For Local Time, include the offset from UTC. */ - if( ts == AST__LT ) { - ltoff = astGetLTOffset( this ); - if( ltoff >= 0.0 ) { - nc = sprintf( gettitle_buff + pos, " (UTC+%g)", ltoff ); - } else { - nc = sprintf( gettitle_buff + pos, " (UTC-%g)", -ltoff ); - } - pos += nc; - } - -/* Close the brackets. */ - nc = sprintf( gettitle_buff + pos, "]" ); - pos += nc; - } - -/* If a non-zero offset has been specified, and the Format attribute does - not indicate a date string (which is always absolute), include the - offset now as a date/time string. */ - fmt = astGetFormat( this, 0 ); - if( orig != 0.0 && !DateFormat( fmt, &ndp, NULL, status ) ) { - -/* Save the Format attribute, and then temporarily set it to give a date/time - string. */ - fmt = astStore( NULL, fmt, strlen( fmt ) + 1 ); - fmtSet = astTestFormat( this, 0 ); - astSetFormat( this, 0, "iso.0" ); - -/* Format the origin value as an absolute time and append it to the - returned title string. Note, the origin always corresponds to a - TimeFrame axis value of zero. */ - nc = sprintf( gettitle_buff+pos, " offset from %s", - astFormat( this, 0, 0.0 ) ); - pos += nc; - -/* Re-instate the original Format value. */ - if( fmtSet ) { - astSetFormat( this, 0, fmt ); - } else { - astClearFormat( this, 0 ); - } - -/* Free the Format string copy. */ - fmt = astFree( (char *) fmt ); - - } - } - } - -/* If an error occurred, clear the returned pointer value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static const char *GetUnit( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetUnit - -* Purpose: -* Obtain a pointer to the Unit string for a TimeFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *GetUnit( AstFrame *this_frame, int axis ) - -* Class Membership: -* TimeFrame member function (over-rides the astGetUnit method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Unit string for a specified axis -* of a TimeFrame. If the Unit attribute has not been set for the axis, a -* pointer to a suitable default string is returned instead. - -* Parameters: -* this -* Pointer to the TimeFrame. -* axis -* The number of the axis (zero-based) for which information is required. - -* Returned Value: -* A pointer to a null-terminated string containing the Unit value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTimeFrame *this; /* Pointer to the TimeFrame structure */ - AstSystemType system; /* The TimeFrame's System value */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetUnit" ); - -/* If a value has been set for the Unit attribute, use the parent - GetUnit method to return a pointer to the required Unit string. */ - if( astTestUnit( this, axis ) ){ - result = (*parent_getunit)( this_frame, axis, status ); - -/* Otherwise, identify the time coordinate system described by the - TimeFrame. */ - } else { - system = astGetSystem( this ); - -/* Return a string describing the default units. */ - result = DefUnit( system, "astGetUnit", astGetClass( this ), status ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -void astInitTimeFrameVtab_( AstTimeFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitTimeFrameVtab - -* Purpose: -* Initialise a virtual function table for a TimeFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* void astInitTimeFrameVtab( AstTimeFrameVtab *vtab, const char *name ) - -* Class Membership: -* TimeFrame vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the TimeFrame class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstMapping *map; /* Temporary Maping */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - double utc_epoch; /* Unix epoch as a UTC MJD */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameVtab( (AstFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsATimeFrame) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - - vtab->ClearAlignTimeScale = ClearAlignTimeScale; - vtab->TestAlignTimeScale = TestAlignTimeScale; - vtab->GetAlignTimeScale = GetAlignTimeScale; - vtab->SetAlignTimeScale = SetAlignTimeScale; - - vtab->ClearTimeOrigin = ClearTimeOrigin; - vtab->TestTimeOrigin = TestTimeOrigin; - vtab->GetTimeOrigin = GetTimeOrigin; - vtab->SetTimeOrigin = SetTimeOrigin; - - vtab->ClearLTOffset = ClearLTOffset; - vtab->TestLTOffset = TestLTOffset; - vtab->GetLTOffset = GetLTOffset; - vtab->SetLTOffset = SetLTOffset; - - vtab->ClearTimeScale = ClearTimeScale; - vtab->TestTimeScale = TestTimeScale; - vtab->GetTimeScale = GetTimeScale; - vtab->SetTimeScale = SetTimeScale; - - vtab->CurrentTime = CurrentTime; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - frame = (AstFrameVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_getdomain = frame->GetDomain; - frame->GetDomain = GetDomain; - - parent_getsystem = frame->GetSystem; - frame->GetSystem = GetSystem; - parent_setsystem = frame->SetSystem; - frame->SetSystem = SetSystem; - parent_clearsystem = frame->ClearSystem; - frame->ClearSystem = ClearSystem; - - parent_getalignsystem = frame->GetAlignSystem; - frame->GetAlignSystem = GetAlignSystem; - - parent_getlabel = frame->GetLabel; - frame->GetLabel = GetLabel; - - parent_getsymbol = frame->GetSymbol; - frame->GetSymbol = GetSymbol; - - parent_gettitle = frame->GetTitle; - frame->GetTitle = GetTitle; - - parent_getepoch = frame->GetEpoch; - frame->GetEpoch = GetEpoch; - - parent_getunit = frame->GetUnit; - frame->GetUnit = GetUnit; - - parent_setunit = frame->SetUnit; - frame->SetUnit = SetUnit; - - parent_match = frame->Match; - frame->Match = Match; - - parent_overlay = frame->Overlay; - frame->Overlay = Overlay; - - parent_subframe = frame->SubFrame; - frame->SubFrame = SubFrame; - - parent_format = frame->Format; - frame->Format = Format; - - parent_unformat = frame->Unformat; - frame->Unformat = Unformat; - - parent_abbrev = frame->Abbrev; - frame->Abbrev = Abbrev; - - parent_fields = frame->Fields; - frame->Fields = Fields; - - parent_gap = frame->Gap; - frame->Gap = Gap; - - parent_centre = frame->Centre; - frame->Centre = Centre; - -/* Store replacement pointers for methods which will be over-ridden by new - member functions implemented here. */ - frame->GetActiveUnit = GetActiveUnit; - frame->TestActiveUnit = TestActiveUnit; - frame->ValidateSystem = ValidateSystem; - frame->SystemString = SystemString; - frame->SystemCode = SystemCode; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetDump( vtab, Dump, "TimeFrame", - "Description of time coordinate system" ); - -/* Convert the Unix Epoch (00:00:00 UTC 1 January 1970 AD) from UTC to TAI. */ - LOCK_MUTEX2 - map = MakeMap( NULL, AST__MJD, AST__MJD, AST__UTC, AST__TAI, - 0.0, 0.0, "d", "d", "astInitTimeFrameVtab", status ); - utc_epoch = UNIX_EPOCH; - astTran1( map, 1, &utc_epoch, 1, &tai_epoch ); - map = astAnnul( map ); - UNLOCK_MUTEX2 - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static AstMapping *MakeMap( AstTimeFrame *this, AstSystemType sys1, - AstSystemType sys2, AstTimeScaleType ts1, - AstTimeScaleType ts2, double off1, double off2, - const char *unit1, const char *unit2, - const char *method, int *status ){ -/* -* Name: -* MakeMap - -* Purpose: -* Make a Mapping between stated timescales and systems. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* AstMapping *MakeMap( AstTimeFrame *this, AstSystemType sys1, -* AstSystemType sys2, AstTimeScaleType ts1, -* AstTimeScaleType ts2, double off1, double off2, -* const char *unit1, const char unit2, -* const char *method, int *status ) - -* Class Membership: -* TimeFrame member function - -* Description: -* This function creates a Mapping from a stated pair of System and -* TimeScale to another stated pair. - -* Parameters: -* this -* A TimeFrame which specifies extra attributes (the clock position, -* time zone, etc) for both input and output. -* sys1 -* The input System. -* sys2 -* The output System. -* ts1 -* The input System. -* ts2 -* The output System. -* off1 -* The axis offset used with the input, in the defaults units -* associated with "sys1". -* off2 -* The axis offset used with the output, in the defaults units -* associated with "sys2". -* unit1 -* The input units. -* unit2 -* The output units. -* method -* A string containing the method name to include in error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new Mapping. NULL if the timescales were -* incompatible. - -*/ - - -/* Local Variables: */ - AstMapping *result; - AstMapping *tmap; - AstMapping *tmap2; - AstMapping *umap; - AstMapping *umap1; - AstMapping *umap2; - AstTimeMap *timemap; - const char *du; - double args[ 5 ]; - double args_lt[ 1 ]; - double args_ut[ 1 ]; - double args_tai[ 2 ]; - double shift; - -/* Check the global error status. */ - result = NULL; - if ( !astOK ) return result; - -/* If the timescales are equal... */ - if( ts1 == ts2 ) { - -/* and the time systems are equal... */ - if( sys1 == sys2 ) { - -/* and the time offsets are equal... */ - if( astEQUALS( off1, off2, 1.0E3 ) ) { - -/* and the units are equal, return a UnitMap. */ - if( !strcmp( unit1, unit2 ) ) { - result = (AstMapping *) astUnitMap( 1, "", status ); - -/* If only the units differ, return the appropriate units Mapping. */ - } else { - result = astUnitMapper( unit1, unit2, NULL, NULL ); - } - -/* If the time offsets differ... */ - } else { - -/* Transform the difference in offsets from the default units associated - with the (common) system, to the units associated with the output. */ - shift = off1 - off2; - du = DefUnit( sys1, method, "TimeFrame", status ); - if( du && strcmp( du, unit2 ) && shift != 0.0 ) { - umap = astUnitMapper( DefUnit( sys1, method, "TimeFrame", status ), - unit2, NULL, NULL ); - astTran1( umap, 1, &shift, 1, &shift ); - umap = astAnnul( umap ); - } - -/* Create a ShiftMap to apply the shift. */ - result = (AstMapping *) astShiftMap( 1, &shift, "", status ); - -/* If the input and output units also differ, include the appropriate units - Mapping. */ - if( strcmp( unit1, unit2 ) ) { - umap = astUnitMapper( unit1, unit2, NULL, NULL ); - tmap = (AstMapping *) astCmpMap( umap, result, 1, "", status ); - umap = astAnnul( umap ); - (void) astAnnul( result ); - result = tmap; - } - } - } - } - -/* If the systems and/or timescales differ, we convert first from the - input frame to a common frame, then from the common frame to the output - frame. */ - if( !result ) { - -/* First, a Mapping from the input units to the default units for the - input System (these are the units expected by the TimeMap conversions). */ - umap1 = astUnitMapper( unit1, DefUnit( sys1, method, "TimeFrame", status ), - NULL, NULL ); - -/* Now create a null TimeMap. */ - timemap = astTimeMap( 0, "", status ); - -/* Store the input time offsets to use. They correspond to the same moment in - time (the second is the MJD equivalent of the first). */ - args[ 0 ] = off1; - args[ 1 ] = ToMJD( sys1, off1, status ); - -/* Add a conversion from the input System to MJD. */ - if( sys1 == AST__JD ) { - astTimeAdd( timemap, "JDTOMJD", 2, args ); - - } else if( sys1 == AST__JEPOCH ) { - astTimeAdd( timemap, "JEPTOMJD", 2, args ); - - } else if( sys1 == AST__BEPOCH ) { - astTimeAdd( timemap, "BEPTOMJD", 2, args ); - } - -/* All timescale conversions except UTTOUTC and UTCTOUT require the input (MJD) - offset as the first argument. In general, the observers longitude, latitude - and altitude are also needed. The Frame class stores longitude values in a - +ve eastwards sense, but the TimeMap class needs +ve westwards, so negate - the longitude. */ - args[ 0 ] = args[ 1 ]; - args[ 1 ] = this ? -astGetObsLon( this ) : 0.0; - args[ 2 ] = this ? astGetObsLat( this ) : 0.0; - args[ 3 ] = this ? astGetObsAlt( this ) : 0.0; - -/* Currently the only conversion that take 5 arguments require the DTAI - value as the 5th argument. */ - args[ 4 ] = this ? astGetDtai( this ) : AST__BAD; - -/* The UTTOUTC and UTCTOUT conversions required just the DUT1 value. */ - args_ut[ 0 ] = this ? astGetDut1( this ) : 0.0; - -/* The LTTOUTC and UTCTOLT conversions required just the time zone - correction. */ - args_lt[ 0 ] = this ? astGetLTOffset( this ) : 0.0; - -/* The UTCTOTAI and TAITOUTC conversions require the input offset and DTAI. */ - args_tai[ 0 ] = args[ 0 ]; - args_tai[ 1 ] = this ? astGetDtai( this ) : AST__BAD; - -/* If the input and output timescales differ, now add a conversion from the - input timescale to TAI. */ - if( ts1 != ts2 ) { - if( ts1 == AST__TAI ) { - - } else if( ts1 == AST__UTC ) { - astTimeAdd( timemap, "UTCTOTAI", 2, args_tai ); - - } else if( ts1 == AST__TT ) { - astTimeAdd( timemap, "TTTOTAI", 1, args ); - - } else if( ts1 == AST__TDB ) { - astTimeAdd( timemap, "TDBTOTT", 5, args ); - astTimeAdd( timemap, "TTTOTAI", 1, args ); - - } else if( ts1 == AST__TCG ) { - astTimeAdd( timemap, "TCGTOTT", 1, args ); - astTimeAdd( timemap, "TTTOTAI", 1, args ); - - } else if( ts1 == AST__LT ) { - astTimeAdd( timemap, "LTTOUTC", 1, args_lt ); - astTimeAdd( timemap, "UTCTOTAI", 2, args_tai ); - - } else if( ts1 == AST__TCB ) { - astTimeAdd( timemap, "TCBTOTDB", 1, args ); - astTimeAdd( timemap, "TDBTOTT", 5, args ); - astTimeAdd( timemap, "TTTOTAI", 1, args ); - - } else if( ts1 == AST__UT1 ) { - astTimeAdd( timemap, "UTTOUTC", 1, args_ut ); - astTimeAdd( timemap, "UTCTOTAI", 2, args_tai ); - - } else if( ts1 == AST__GMST ) { - astTimeAdd( timemap, "GMSTTOUT", 1, args ); - astTimeAdd( timemap, "UTTOUTC", 1, args_ut ); - astTimeAdd( timemap, "UTCTOTAI", 2, args_tai ); - - } else if( ts1 == AST__LAST ) { - astTimeAdd( timemap, "LASTTOLMST", 3, args ); - astTimeAdd( timemap, "LMSTTOGMST", 3, args ); - astTimeAdd( timemap, "GMSTTOUT", 1, args ); - astTimeAdd( timemap, "UTTOUTC", 1, args_ut ); - astTimeAdd( timemap, "UTCTOTAI", 2, args_tai ); - - } else if( ts1 == AST__LMST ) { - astTimeAdd( timemap, "LMSTTOGMST", 3, args ); - astTimeAdd( timemap, "GMSTTOUT", 1, args ); - astTimeAdd( timemap, "UTTOUTC", 1, args_ut ); - astTimeAdd( timemap, "UTCTOTAI", 2, args_tai ); - } - -/* Now add a conversion from TAI to the output timescale. */ - if( ts2 == AST__TAI ) { - - } else if( ts2 == AST__UTC ) { - astTimeAdd( timemap, "TAITOUTC", 2, args_tai ); - - } else if( ts2 == AST__TT ) { - astTimeAdd( timemap, "TAITOTT", 1, args ); - - } else if( ts2 == AST__TDB ) { - astTimeAdd( timemap, "TAITOTT", 1, args ); - astTimeAdd( timemap, "TTTOTDB", 5, args ); - - } else if( ts2 == AST__TCG ) { - astTimeAdd( timemap, "TAITOTT", 1, args ); - astTimeAdd( timemap, "TTTOTCG", 1, args ); - - } else if( ts2 == AST__TCB ) { - astTimeAdd( timemap, "TAITOTT", 1, args ); - astTimeAdd( timemap, "TTTOTDB", 5, args ); - astTimeAdd( timemap, "TDBTOTCB", 1, args ); - - } else if( ts2 == AST__UT1 ) { - astTimeAdd( timemap, "TAITOUTC", 2, args_tai ); - astTimeAdd( timemap, "UTCTOUT", 1, args_ut ); - - } else if( ts2 == AST__GMST ) { - astTimeAdd( timemap, "TAITOUTC", 2, args_tai ); - astTimeAdd( timemap, "UTCTOUT", 1, args_ut ); - astTimeAdd( timemap, "UTTOGMST", 1, args ); - - } else if( ts2 == AST__LAST ) { - astTimeAdd( timemap, "TAITOUTC", 2, args_tai ); - astTimeAdd( timemap, "UTCTOUT", 1, args_ut ); - astTimeAdd( timemap, "UTTOGMST", 1, args ); - astTimeAdd( timemap, "GMSTTOLMST", 3, args ); - astTimeAdd( timemap, "LMSTTOLAST", 3, args ); - - } else if( ts2 == AST__LMST ) { - astTimeAdd( timemap, "TAITOUTC", 2, args_tai ); - astTimeAdd( timemap, "UTCTOUT", 1, args_ut ); - astTimeAdd( timemap, "UTTOGMST", 1, args ); - astTimeAdd( timemap, "GMSTTOLMST", 3, args ); - - } else if( ts2 == AST__LT ) { - astTimeAdd( timemap, "TAITOUTC", 2, args_tai ); - astTimeAdd( timemap, "UTCTOLT", 1, args_lt ); - - } - } - -/* Add a conversion from MJD to the output System, if needed. */ - args[ 1 ] = off2; - if( sys2 == AST__MJD ) { - if( args[ 0 ] != off2 ) astTimeAdd( timemap, "MJDTOMJD", 2, args ); - - } else if( sys2 == AST__JD ) { - astTimeAdd( timemap, "MJDTOJD", 2, args ); - - } else if( sys2 == AST__JEPOCH ) { - astTimeAdd( timemap, "MJDTOJEP", 2, args ); - - } else if( sys2 == AST__BEPOCH ) { - astTimeAdd( timemap, "MJDTOBEP", 2, args ); - } - -/* Now, create a Mapping from the default units for the output System (these - are the units produced by the TimeMap conversions) to the requested - output units. */ - umap2 = astUnitMapper( DefUnit( sys2, method, "TimeFrame", status ), unit2, - NULL, NULL ); - -/* If OK, combine the Mappings in series. Note, umap1 and umap2 should - always be non-NULL because the suitablity of units strings is checked - within OriginSystem - called from within SetSystem. */ - if( umap1 && umap2 ) { - tmap = (AstMapping *) astCmpMap( umap1, timemap, 1, "", status ); - tmap2 = (AstMapping *) astCmpMap( tmap, umap2, 1, "", status ); - tmap = astAnnul( tmap ); - result = astSimplify( tmap2 ); - tmap2 = astAnnul( tmap2 ); - } - -/* Free remaining resources */ - if( umap1 ) umap1 = astAnnul( umap1 ); - if( umap2 ) umap2 = astAnnul( umap2 ); - timemap = astAnnul( timemap ); - } - -/* Return NULL if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; - -} - -static int MakeTimeMapping( AstTimeFrame *target, AstTimeFrame *result, - AstTimeFrame *align_frm, int report, - AstMapping **map, int *status ) { -/* -* Name: -* MakeTimeMapping - -* Purpose: -* Generate a Mapping between two TimeFrames. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* int MakeTimeMapping( AstTimeFrame *target, AstTimeFrame *result, -* AstTimeFrame *align_frm, int report, -* AstMapping **map, int *status ) { - -* Class Membership: -* TimeFrame member function. - -* Description: -* This function takes two TimeFrames and generates a Mapping that -* converts between them, taking account of differences in their -* coordinate systems, offsets, timescales, units, etc. - -* Parameters: -* target -* Pointer to the first TimeFrame. -* result -* Pointer to the second TimeFrame. -* align_frm -* A TimeFrame defining the system and time scale in which to -* align the target and result TimeFrames. The AlignSystem and -* AlignTimeScale attributes are used for this purpose. -* report -* Should errors be reported if no match is possible? These reports -* will describe why no match was possible. -* map -* Pointer to a location which is to receive a pointer to the -* returned Mapping. The forward transformation of this Mapping -* will convert from "target" coordinates to "result" -* coordinates, and the inverse transformation will convert in -* the opposite direction (all coordinate values in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Mapping could be generated, or zero if the two -* TimeFrames are sufficiently un-related that no meaningful Mapping -* can be produced (albeit an "unmeaningful" Mapping will be returned -* in this case, which will need to be annulled). - -* Notes: -* A value of zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *map1; /* Intermediate Mapping */ - AstMapping *map2; /* Intermediate Mapping */ - AstMapping *tmap; /* Intermediate Mapping */ - AstSystemType sys1; /* Code to identify input system */ - AstSystemType sys2; /* Code to identify output system */ - AstTimeScaleType align_ts; /* Alignment time scale */ - AstTimeScaleType ts1; /* Input time scale */ - AstTimeScaleType ts2; /* Output time scale */ - const char *align_unit; /* Units used for alignment */ - const char *u1; /* Input target units */ - const char *u2; /* Output target units */ - double align_off; /* Axis offset */ - double ltoff1; /* Input axis Local Time offset */ - double ltoff2; /* Output axis Local Time offset */ - double off1; /* Input axis offset */ - double off2; /* Output axis offset */ - int arclk; /* Align->result depends on clock position? */ - int ardtai; /* Align->result depends on Dtai? */ - int ardut; /* Align->result depends on Dut1? */ - int arlto; /* Align->result depends on LT offset? */ - int clkdiff; /* Do target and result clock positions differ? */ - int dtaidiff; /* Do target and result Dtai values differ? */ - int dut1diff; /* Do target and result Dut1 values differ? */ - int ltodiff; /* Do target and result LTOffset values differ? */ - int match; /* Mapping can be generated? */ - int taclk; /* Target->align depends on clock position? */ - int tadut; /* Target->align depends on Dut1? */ - int tadtai; /* Target->align depends on Dtai? */ - int talto; /* Target->align depends on LT offset? */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise the returned values. */ - match = 0; - *map = NULL; - -/* Get the required properties of the input (target) TimeFrame */ - sys1 = astGetSystem( target ); - ts1 = astGetTimeScale( target ); - off1 = astGetTimeOrigin( target ); - u1 = astGetUnit( target, 0 ); - ltoff1= astGetLTOffset( target ); - -/* Get the required properties of the output (result) TimeFrame */ - sys2 = astGetSystem( result ); - ts2 = astGetTimeScale( result ); - off2 = astGetTimeOrigin( result ); - u2 = astGetUnit( result, 0 ); - ltoff2= astGetLTOffset( result ); - -/* Get the timescale in which alignment is to be performed. The alignment - System does not matter since they all supported time systems are linearly - related, and so the choice of alignment System has no effect on the total - Mapping. We arbitrarily choose MJD as the alignment System (if needed). */ - align_ts = astGetAlignTimeScale( align_frm ); - -/* The main difference between this function and the MakeMap function is - that this function takes account of the requested alignment frame. But - the alignment Frame only makes a difference to the overall Mapping if - 1) the observer's positions are different in the target and result Frame, - and 2) one or both of the Mappings to or from the alignment frame depends - on the observer's position. If either of these 2 conditions is not met, - then the alignment frame can be ignored, and the simpler MakeMap function - can be called. See if the observer's positions differ. */ - clkdiff = ( astGetObsLon( target ) != astGetObsLon( result ) || - astGetObsLat( target ) != astGetObsLat( result ) || - astGetObsAlt( target ) != astGetObsAlt( result ) ); - -/* See if the Mapping from target to alignment frame depends on the - observer's position. */ - taclk = CLOCK_SCALE( ts1 ) || CLOCK_SCALE( align_ts ); - -/* See if the Mapping from alignment to result frame depends on the - observer's position. */ - arclk = CLOCK_SCALE( align_ts ) || CLOCK_SCALE( ts2 ); - -/* In addition, the alignment frame is significant if either of the Mappings - depends on DUT1 and the values of the DUT1 attribute are different for the - two TimeFrames. Or if DTAI differs and is similarly relevant. */ - dut1diff = ( astGetDut1( target ) != astGetDut1( result ) ); - tadut = DUT1_SCALE( ts1 ) != DUT1_SCALE( align_ts ); - ardut = DUT1_SCALE( align_ts ) != DUT1_SCALE( ts2 ); - - dtaidiff = ! EQUAL( astGetDtai( target ), astGetDtai( result ), 1.0E-6 ); - tadtai = DTAI_SCALE( ts1 ) != DTAI_SCALE( align_ts ); - ardtai = DTAI_SCALE( align_ts ) != DTAI_SCALE( ts2 ); - -/* In addition, the alignment frame is significant if either of the Mappings - depends on LTOffset and the values of the LTOffset attribute are different - for the two TimeFrames. */ - ltodiff = ( ltoff1 != ltoff2 ); - talto = LTOFFSET_SCALE( ts1 ) != LTOFFSET_SCALE( align_ts ); - arlto = LTOFFSET_SCALE( align_ts ) != LTOFFSET_SCALE( ts2 ); - -/* If the alignment frame can be ignored, use MakeMap */ - if( ( !clkdiff || !( taclk || arclk ) ) && - ( !ltodiff || !( talto || arlto ) ) && - ( !dut1diff || !( tadut || ardut ) ) && - ( !dtaidiff || !( tadtai || ardtai ) ) ) { - *map = MakeMap( target, sys1, sys2, ts1, ts2, off1, off2, u1, u2, - "astSubFrame", status ); - if( *map ) match = 1; - -/* Otherwise, we create the Mapping in two parts; first a Mapping from - the target Frame to the alignment Frame (using the target clock, dtai, dut1 - and ltoffset), then a Mapping from the alignment Frame to the results - Frame (using the result clock, dtai, dut1 and ltoffset). */ - } else { - -/* Create a Mapping from target units/system/timescale/offset to MJD in - the alignment timescale with default units and offset equal to the MJD - equivalent of the target offset. */ - align_off = ToMJD( sys1, off1, status ); - align_unit = DefUnit( AST__MJD, "MakeTimeMap", "TimeFrame", status ); - map1 = MakeMap( target, sys1, AST__MJD, ts1, align_ts, off1, align_off, - u1, align_unit, "MakeTimeMap", status ); - -/* Report an error if the timescales were incompatible. */ - if( !map1 ){ - match = 0; - if( report && astOK ) { - astError( AST__INCTS, "astMatch(%s): Alignment in requested " - "timescale (%s) is not possible since one or both of the " - "TimeFrames being aligned refer to the %s timescale.", status, - astGetClass( target ), TimeScaleString( align_ts, status ), - TimeScaleString( ts1, status ) ); - } - } - -/* We now create a Mapping that converts from the alignment System (MJD), - TimeScale and offset to the result coordinate system. */ - map2 = MakeMap( result, AST__MJD, sys2, align_ts, ts2, align_off, off2, - align_unit, u2, "MakeTimeMap", status ); - -/* Report an error if the timescales were incompatible. */ - if( !map2 ){ - match = 0; - if( report && astOK ) { - astError( AST__INCTS, "astMatch(%s): Alignment in requested " - "timescale (%s) is not possible since one or both of the " - "TimeFrames being aligned refer to the %s timescale.", status, - astGetClass( result ), TimeScaleString( align_ts, status ), - TimeScaleString( ts2, status ) ); - } - } - -/* Combine these two Mappings. */ - if( map1 && map2 ) { - match = 1; - tmap = (AstMapping *) astCmpMap( map1, map2, 1, "", status ); - *map = astSimplify( tmap ); - tmap = astAnnul( tmap ); - } - -/* Free resources. */ - if( map1 ) map1 = astAnnul( map1 ); - if( map2 ) map2 = astAnnul( map2 ); - } - -/* If an error occurred, annul the returned Mapping and clear the returned - values. */ - if ( !astOK ) { - *map = astAnnul( *map ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static int Match( AstFrame *template_frame, AstFrame *target, int matchsub, - int **template_axes, int **target_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* Match - -* Purpose: -* Determine if conversion is possible between two coordinate systems. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the protected astMatch method -* inherited from the Frame class). - -* Description: -* This function matches a "template" TimeFrame to a "target" Frame and -* determines whether it is possible to convert coordinates between them. -* If it is, a mapping that performs the transformation is returned along -* with a new Frame that describes the coordinate system that results when -* this mapping is applied to the "target" coordinate system. In addition, -* information is returned to allow the axes in this "result" Frame to be -* associated with the corresponding axes in the "target" and "template" -* Frames from which they are derived. - -* Parameters: -* template -* Pointer to the template TimeFrame. This describes the coordinate -* system (or set of possible coordinate systems) into which we wish to -* convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate system in -* which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case. -* template_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the template TimeFrame axis from -* which it is derived. If it is not derived from any template -* TimeFrame axis, a value of -1 will be returned instead. -* target_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the target Frame axis from which it -* is derived. If it is not derived from any target Frame axis, a value -* of -1 will be returned instead. -* map -* Address of a location where a pointer to a new Mapping will be -* returned if the requested coordinate conversion is possible. If -* returned, the forward transformation of this Mapping may be used to -* convert coordinates between the "target" Frame and the "result" -* Frame (see below) and the inverse transformation will convert in the -* opposite direction. -* result -* Address of a location where a pointer to a new Frame will be returned -* if the requested coordinate conversion is possible. If returned, this -* Frame describes the coordinate system that results from applying the -* returned Mapping (above) to the "target" coordinate system. In -* general, this Frame will combine attributes from (and will therefore -* be more specific than) both the target and the template Frames. In -* particular, when the template allows the possibility of transformaing -* to any one of a set of alternative coordinate systems, the "result" -* Frame will indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate conversion is -* possible. Otherwise zero is returned (this will not in itself result in -* an error condition). - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* This implementation addresses the matching of a TimeFrame class -* object to any other class of Frame. A TimeFrame will match any class -* of TimeFrame (i.e. possibly from a derived class) but will not match -* a less specialised class of Frame. -*/ - - AstFrame *frame0; /* Pointer to Frame underlying axis 0 */ - AstTimeFrame *template; /* Pointer to template TimeFrame structure */ - int iaxis0; /* Axis index underlying axis 0 */ - int iaxis; /* Axis index */ - int match; /* Coordinate conversion possible? */ - int target_axis0; /* Index of TimeFrame axis in the target */ - int target_naxes; /* Number of target axes */ - -/* Initialise the returned values. */ - *template_axes = NULL; - *target_axes = NULL; - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the template TimeFrame structure. */ - template = (AstTimeFrame *) template_frame; - -/* Obtain the number of axes in the target Frame. */ - target_naxes = astGetNaxes( target ); - -/* The first criterion for a match is that the template matches as a - Frame class object. This ensures that the number of axes (1) and - domain, etc. of the target Frame are suitable. Invoke the parent - "astMatch" method to verify this. */ - match = (*parent_match)( template_frame, target, matchsub, - template_axes, target_axes, map, result, status ); - -/* If a match was found, annul the returned objects, which are not - needed, but keep the memory allocated for the axis association - arrays, which we will re-use. */ - if ( astOK && match ) { - *map = astAnnul( *map ); - *result = astAnnul( *result ); - } - -/* If OK so far, obtain pointers to the primary Frames which underlie - all target axes. Stop when a TimeFrame axis is found. */ - if ( match && astOK ) { - match = 0; - for( iaxis = 0; iaxis < target_naxes; iaxis++ ) { - astPrimaryFrame( target, iaxis, &frame0, &iaxis0 ); - if( astIsATimeFrame( frame0 ) ) { - frame0 = astAnnul( frame0 ); - target_axis0 = iaxis; - match = 1; - break; - } else { - frame0 = astAnnul( frame0 ); - } - } - } - -/* Check at least one TimeFrame axis was found it the target. Store the - axis associataions. */ - if( match && astOK ) { - (*template_axes)[ 0 ] = 0; - (*target_axes)[ 0 ] = target_axis0; - -/* Use the target's "astSubFrame" method to create a new Frame (the - result Frame) with copies of the target axes in the required - order. This process also overlays the template attributes on to the - target Frame and returns a Mapping between the target and result - Frames which effects the required coordinate conversion. */ - match = astSubFrame( target, template, 1, *target_axes, *template_axes, - map, result ); - } - -/* If an error occurred, or conversion to the result Frame's coordinate - system was not possible, then free all memory, annul the returned - objects, and reset the returned value. */ - if ( !astOK || !match ) { - *template_axes = astFree( *template_axes ); - *target_axes = astFree( *target_axes ); - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; -} - -static void OriginScale( AstTimeFrame *this, AstTimeScaleType newts, - const char *method, int *status ){ -/* -* Name: -* OriginScale - -* Purpose: -* Convert the TimeOrigin in a TimeFrame to a new timescale. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* void OriginScale( AstTimeFrame *this, AstTimeScaleType newts, -* const char *method, int *status ) - -* Class Membership: -* TimeFrame member function - -* Description: -* This function converts the value of the TimeOrigin attribute stored -* within a supplied TimeFrame from the timescale currently associated -* with the TimeFrame, to the new timescale indicated by "newts". - -* Parameters: -* this -* Point to the TimeFrame. On entry, the TimeOrigin value is -* assumed to refer to the timescale given by the astGetTimeScale -* method. On exit, the TimeOrigin value refers to the timescale -* supplied in "newts". The TimeScale attribute of the TimeFrame -* should then be modified in order to keep things consistent. -* newts -* The timescale to which the TimeOrigin value stored within "this" -* should refer on exit. -* method -* Pointer to a string holding the name of the method to be -* included in any error messages. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Local Variables: */ - AstMapping *map; - AstSystemType sys; - AstTimeScaleType oldts; - const char *u; - double newval; - double oldval; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do nothing if the TimeOrigin attribute has not been assigned a value. */ - if( astTestTimeOrigin( this ) ) { - -/* Do nothing if the Scale will not change. */ - oldts = astGetTimeScale( this ); - if( newts != oldts ) { - -/* Create a Mapping to perform the TimeScale change. */ - sys = astGetSystem( this ); - u = DefUnit( sys, method, "TimeFrame", status ), - map = MakeMap( this, sys, sys, oldts, newts, 0.0, 0.0, u, u, - method, status ); - -/* Use the Mapping to convert the stored TimeOrigin value. */ - if( map ) { - oldval = astGetTimeOrigin( this ); - astTran1( map, 1, &oldval, 1, &newval ); - -/* Store the new value */ - astSetTimeOrigin( this, newval ); - -/* Free resources */ - map = astAnnul( map ); - - } else if( astOK ) { - astError( AST__INCTS, "%s(%s): Cannot convert the TimeOrigin " - "value to a different timescale because of " - "incompatible time scales.", status, method, - astGetClass( this ) ); - } - } - } -} - -static void OriginSystem( AstTimeFrame *this, AstSystemType oldsys, - const char *method, int *status ){ -/* -* Name: -* OriginSystem - -* Purpose: -* Convert the TimeOrigin in a TimeFrame to a new System. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* void OriginSystem( AstTimeFrame *this, AstSystemType oldsys, -* const char *method, int *status ) - -* Class Membership: -* TimeFrame member function - -* Description: -* This function converts the value of the TimeOrigin attribute stored -* within a supplied TimeFrame from its original System, etc, to the -* System, etc, currently associated with the TimeFrame. - -* Parameters: -* this -* Point to the TimeFrame. On entry, the TimeOrigin value is -* assumed to refer to the System given by "oldsys", etc. On exit, the -* TimeOrigin value refers to the System returned by the astGetSystem -* method, etc. -* oldsys -* The System to which the TimeOrigin value stored within "this" -* refers on entry. -* method -* A string containing the method name for error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMapping *map; - AstSystemType newsys; - AstTimeScaleType ts; - const char *oldu; - const char *newu; - double newval; - double oldval; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do nothing if the TimeOrigin attribute has not been assigned a value. */ - if( astTestTimeOrigin( this ) ) { - -/* Do nothing if the System has not changed. */ - newsys = astGetSystem( this ); - if( oldsys != newsys ) { - -/* Create a Mapping to perform the System change. */ - ts = astGetTimeScale( this ); - oldu = DefUnit( oldsys, method, "TimeFrame", status ), - newu = DefUnit( newsys, method, "TimeFrame", status ), - map = MakeMap( this, oldsys, newsys, ts, ts, 0.0, 0.0, oldu, newu, - method, status ); - -/* Use the Mapping to convert the stored TimeOrigin value. */ - if( map ) { - oldval = astGetTimeOrigin( this ); - astTran1( map, 1, &oldval, 1, &newval ); - -/* Store the new value */ - astSetTimeOrigin( this, newval ); - -/* Free resources */ - map = astAnnul( map ); - - } else if( astOK ) { - astError( AST__INCTS, "%s(%s): Cannot convert the TimeOrigin " - "value to a different System because of incompatible " - "time scales.", status, method, astGetClass( this ) ); - } - } - } -} - -static void Overlay( AstFrame *template, const int *template_axes, - AstFrame *result, int *status ) { -/* -* Name: -* Overlay - -* Purpose: -* Overlay the attributes of a template TimeFrame on to another Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* void Overlay( AstFrame *template, const int *template_axes, -* AstFrame *result, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the protected astOverlay method -* inherited from the Frame class). - -* Description: -* This function overlays attributes of a TimeFrame (the "template") on to -* another Frame, so as to over-ride selected attributes of that second -* Frame. Normally only those attributes which have been specifically set -* in the template will be transferred. This implements a form of -* defaulting, in which a Frame acquires attributes from the template, but -* retains its original attributes (as the default) if new values have not -* previously been explicitly set in the template. -* -* Note that if the result Frame is a TimeFrame and a change of time -* coordinate system occurs as a result of overlaying its System -* attribute, then some of its original attribute values may no -* longer be appropriate (e.g. the Title, or attributes describing -* its axes). In this case, these will be cleared before overlaying -* any new values. - -* Parameters: -* template -* Pointer to the template TimeFrame, for which values should have been -* explicitly set for any attribute which is to be transferred. -* template_axes -* Pointer to an array of int, with one element for each axis of the -* "result" Frame (see below). For each axis in the result frame, the -* corresponding element of this array should contain the (zero-based) -* index of the template axis to which it corresponds. This array is used -* to establish from which template axis any axis-dependent attributes -* should be obtained. -* -* If any axis in the result Frame is not associated with a template -* axis, the corresponding element of this array should be set to -1. -* -* If a NULL pointer is supplied, the template and result axis -* indices are assumed to be identical. -* result -* Pointer to the Frame which is to receive the new attribute values. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - In general, if the result Frame is not from the same class as the -* template TimeFrame, or from a class derived from it, then attributes may -* exist in the template TimeFrame which do not exist in the result Frame. -* In this case, these attributes will not be transferred. -*/ - - -/* Local Variables: */ - AstSystemType new_alignsystem;/* Code identifying new alignment coords */ - AstSystemType new_system; /* Code identifying new cordinates */ - AstSystemType old_system; /* Code identifying old coordinates */ - int resetSystem; /* Was the template System value cleared? */ - int timeframe; /* Result Frame is a TimeFrame? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the old and new systems. */ - old_system = astGetSystem( result ); - new_system = astGetSystem( template ); - -/* If the result Frame is a TimeFrame, we must test to see if overlaying its - System attribute will change the type of coordinate system it describes. - Determine the value of this attribute for the result and template - TimeFrames. */ - resetSystem = 0; - timeframe = astIsATimeFrame( result ); - if( timeframe ) { - -/* If the coordinate system will change, any value already set for the result - TimeFrame's Title, etc, will no longer be appropriate, so clear it. */ - if ( new_system != old_system ) { - astClearTitle( result ); - astClearLabel( result, 0 ); - astClearSymbol( result, 0 ); - } - -/* If the result Frame is not a TimeFrame, we must temporarily clear the - System and AlignSystem values since the values used by this class are only - appropriate to this class. */ - } else { - if( astTestSystem( template ) ) { - astClearSystem( template ); - - new_alignsystem = astGetAlignSystem( template ); - astClearAlignSystem( template ); - - resetSystem = 1; - } - } - -/* Invoke the parent class astOverlay method to transfer attributes inherited - from the parent class. */ - (*parent_overlay)( template, template_axes, result, status ); - -/* Reset the System and AlignSystem values if necessary */ - if( resetSystem ) { - astSetSystem( template, new_system ); - astSetAlignSystem( template, new_alignsystem ); - } - -/* Check if the result Frame is a TimeFrame or from a class derived from - TimeFrame. If not, we cannot transfer TimeFrame attributes to it as it is - insufficiently specialised. In this case simply omit these attributes. */ - if ( timeframe && astOK ) { - -/* Define macros that test whether an attribute is set in the template and, - if so, transfers its value to the result. */ -#define OVERLAY(attribute) \ - if ( astTest##attribute( template ) ) { \ - astSet##attribute( result, astGet##attribute( template ) ); \ - } - -/* Use the macro to transfer each TimeFrame attribute in turn. Note, - SourceVRF must be overlayed before SourceVel. Otherwise the stored value - for SourceVel would be changed from the default SourceVRF to the specified - SourceVRF when SourceVRF was overlayed. */ - OVERLAY(AlignTimeScale) - OVERLAY(LTOffset) - OVERLAY(TimeOrigin) - OVERLAY(TimeScale) - } - -/* Undefine macros local to this function. */ -#undef OVERLAY -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* TimeFrame member function (extends the astSetAttrib method inherited from -* the Mapping class). - -* Description: -* This function assigns an attribute value for a TimeFrame, the attribute -* and its value being specified by means of a string of the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in lower -* case with no white space present. The value to the right of the "=" -* should be a suitable textual representation of the value to be assigned -* and this will be interpreted according to the attribute's data type. -* White space surrounding the value is only significant for string -* attributes. - -* Parameters: -* this -* Pointer to the TimeFrame. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This protected method is intended to be invoked by the Object astSet -* method and makes additional attributes accessible to it. -*/ - -/* Local Vaiables: */ - AstTimeFrame *this; /* Pointer to the TimeFrame structure */ - AstTimeScaleType ts; /* time scale type code */ - char *a; /* Pointer to next character */ - char *new_setting; /* Pointer value to new attribute setting */ - double dval; /* Double atribute value */ - double mjd; /* MJD read from setting */ - double origin; /* TimeOrigin value */ - int len; /* Length of setting string */ - int namelen; /* Length of attribute name in setting */ - int nc; /* Number of characters read by astSscanf */ - int off; /* Offset of attribute value */ - int rep; /* Original error reporting state */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_object; - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* First look for axis attributes defined by the Frame class. Since a - TimeFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strncmp( setting, "direction=", 10 ) || - !strncmp( setting, "bottom=", 7 ) || - !strncmp( setting, "top=", 4 ) || - !strncmp( setting, "format=", 7 ) || - !strncmp( setting, "label=", 6 ) || - !strncmp( setting, "symbol=", 7 ) || - !strncmp( setting, "unit=", 5 ) ) { - -/* Create a new setting string from the original by appending the string - "(1)" to the end of the attribute name and then use the parent SetAttrib - method. */ - new_setting = astMalloc( len + 4 ); - if( new_setting ) { - memcpy( new_setting, setting, len + 1 ); - a = strchr( new_setting, '=' ); - namelen = a - new_setting; - memcpy( a, "(1)", 4 ); - a += 3; - strcpy( a, setting + namelen ); - (*parent_setattrib)( this_object, new_setting, status ); - new_setting = astFree( new_setting ); - } - -/* AlignTimeScale. */ -/* --------------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "aligntimescale=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a TimeScale code before use. */ - ts = TimeScaleCode( setting + off, status ); - if ( ts != AST__BADTS ) { - astSetAlignTimeScale( this, ts ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid time scale " - "description \"%s\".", status, astGetClass( this ), setting+off ); - } - -/* ClockLat. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "clocklat=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - new_setting = astMalloc( sizeof( char )*(size_t) len + 1 ); - new_setting[ 0 ] = 'o'; - new_setting[ 1 ] = 'b'; - new_setting[ 2 ] = 's'; - strcpy( new_setting + 3, setting + 5 ); - astSetAttrib( this, new_setting ); - new_setting = astFree( new_setting ); - -/* ClockLon. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "clocklon=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - new_setting = astMalloc( sizeof( char )*(size_t) len + 1 ); - new_setting[ 0 ] = 'o'; - new_setting[ 1 ] = 'b'; - new_setting[ 2 ] = 's'; - strcpy( new_setting + 3, setting + 5 ); - astSetAttrib( this, new_setting ); - new_setting = astFree( new_setting ); - -/* LTOffset */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "ltoffset= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetLTOffset( this, dval ); - -/* TimeOrigin */ -/* ---------- */ - -/* Floating-point without any units indication - assume the current Unit - value. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "timeorigin= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - - astSetTimeOrigin( this, ToUnits( this, astGetUnit( this, 0 ), dval, - "astSetTimeOrigin", status ) ); - -/* Floating-point with units. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "timeorigin= %lg %n%*s %n", &dval, &off, &nc ) ) - && ( nc >= len ) ) { - -/* Defer error reporting in case a date string was given which starts - with a floating point number, then convert the supplied value to the - default units for the TimeFrame's System. */ - rep = astReporting( 0 ); - origin = ToUnits( this, setting + off, dval, "astSetTimeOrigin", status ); - if( !astOK ) astClearStatus; - astReporting( rep ); - -/* If the origin was converted, store it. */ - if( origin != AST__BAD ) { - astSetTimeOrigin( this, origin ); - -/* Otherwise, interpret the string as a date. Convert first to MJD then to - default system. */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "timeorigin=%n%*[^\n]%n", &off, &nc ) ) - && ( nc >= len ) ) { - mjd = astReadDateTime( setting + off ); - if ( astOK ) { - astSetTimeOrigin( this, FromMJD( this, mjd, status ) ); - -/* Report contextual information if the conversion failed. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid TimeOrigin value " - "\"%s\" given.", status, astGetClass( this ), setting + off ); - } - } - -/* String (assumed to be a date). Convert first to MJD then to default - system. */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "timeorigin=%n%*[^\n]%n", &off, &nc ) ) - && ( nc >= len ) ) { - mjd = astReadDateTime( setting + off ); - if ( astOK ) { - astSetTimeOrigin( this, FromMJD( this, mjd, status ) ); - -/* Report contextual information if the conversion failed. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid TimeOrigin value " - "\"%s\" given.", status, astGetClass( this ), setting + off ); - } - -/* TimeScale. */ -/* ---------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "timescale=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a TimeScale code before use. */ - ts = TimeScaleCode( setting + off, status ); - if ( ts != AST__BADTS ) { - astSetTimeScale( this, ts ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid time scale " - "description \"%s\".", status, astGetClass( this ), setting + off ); - } - -/* Pass any unrecognised setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status ) { -/* -* Name: -* SetSystem - -* Purpose: -* Set the System attribute for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astSetSystem protected -* method inherited from the Frame class). - -* Description: -* This function sets the System attribute for a TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* newsys -* The new System value to be stored. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstTimeFrame *this; /* Pointer to TimeFrame structure */ - AstSystemType oldsys; /* Original System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* If we are changing the System to BEPOCH, set the Unit attribute to - "yr" and TimeScale to "TT". */ - if( newsys == AST__BEPOCH ) { - astSetUnit( this_frame, 0, "yr" ); - astSetTimeScale( (AstTimeFrame *) this_frame, AST__TT ); - } - -/* Save the original System value */ - oldsys = astGetSystem( this_frame ); - -/* Use the parent SetSystem method to store the new System value. */ - (*parent_setsystem)( this_frame, newsys, status ); - -/* If the system has changed... */ - if( oldsys != newsys ) { - -/* Modify the stored TimeOrigin. */ - OriginSystem( this, oldsys, "astSetSystem", status ); - -/* Clear all attributes which have system-specific defaults. */ - astClearLabel( this_frame, 0 ); - astClearSymbol( this_frame, 0 ); - astClearTitle( this_frame ); - } -} - -static void SetTimeScale( AstTimeFrame *this, AstTimeScaleType value, int *status ) { -/* -*+ -* Name: -* astSetTimeScale - -* Purpose: -* Set the TimeScale attribute for a TimeFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* void astSetTimeScale( AstTimeFrame *this, AstTimeScaleType value ) - -* Class Membership: -* TimeFrame virtual function - -* Description: -* This function set a new value for the TimeScale attribute for a -* TimeFrame. - -* Parameters: -* this -* Pointer to the TimeFrame. -* value -* The new value. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Verify the supplied timescale value */ - if( value < FIRST_TS || value > LAST_TS ) { - astError( AST__ATTIN, "%s(%s): Bad value (%d) given for TimeScale " - "attribute.", status, "astSetTimeScale", astGetClass( this ), - (int) value ); - -/* Report an error if System is set to BEPOCH and an in appropriate - TimeScale was supplied. */ - } else if( astGetSystem( this ) == AST__BEPOCH && - value != AST__TT ) { - astError( AST__ATTIN, "%s(%s): Supplied TimeScale (%s) cannot be " - "used because the %s represents Besselian Epoch which " - "is defined in terms of TT.", status, "astSetTimeScale", - astGetClass( this ), TimeScaleString( value, status ), - astGetClass( this ) ); - -/* Otherwise set the new TimeScale */ - } else { - -/* Modify the TimeOrigin value stored in the TimeFrame structure to refer - to the new timescale. */ - OriginScale( this, value, "astSetTimeScale", status ); - -/* Store the new value for the timescale in the TimeFrame structure. */ - this->timescale = value; - - } -} - -static void SetUnit( AstFrame *this_frame, int axis, const char *value, int *status ) { -/* -* Name: -* SetUnit - -* Purpose: -* Set a pointer to the Unit string for a TimeFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* void SetUnit( AstFrame *this_frame, int axis, const char *value ) - -* Class Membership: -* TimeFrame member function (over-rides the astSetUnit method inherited -* from the Frame class). - -* Description: -* This function stores a pointer to the Unit string for a specified axis -* of a TimeFrame. It also stores the string in the "usedunits" array -* in the TimeFrame structure, in the element associated with the -* current System. - -* Parameters: -* this -* Pointer to the TimeFrame. -* axis -* The number of the axis (zero-based) for which information is required. -* unit -* The new string to store. -*/ - -/* Local Variables: */ - AstTimeFrame *this; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astSetUnit" ); - -/* Report an error if System is set to BEPOCH and an in appropriate - Unit was supplied. */ - if( astGetSystem( this ) == AST__BEPOCH && strcmp( "yr", value ) ) { - astError( AST__ATTIN, "astSetUnit(%s): Supplied Unit (%s) cannot " - "be used because the %s represents Besselian Epoch which " - "is defined in units of years (yr).", status, astGetClass( this ), - value, astGetClass( this ) ); - -/* Otherwise use the parent SetUnit method to store the value in the Axis - structure */ - } else { - (*parent_setunit)( this_frame, axis, value, status ); - } -} - -static AstTimeScaleType TimeScaleCode( const char *ts, int *status ) { -/* -* Name: -* TimeScaleCode - -* Purpose: -* Convert a string into a time scale type code. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* AstTimeScaleType TimeScaleCode( const char *ts ) - -* Class Membership: -* TimeFrame member function. - -* Description: -* This function converts a string used for the external description of -* a time scale into a TimeFrame time scale type code (TimeScale attribute -* value). It is the inverse of the TimeScaleString function. - -* Parameters: -* ts -* Pointer to a constant null-terminated string containing the -* external description of the time scale. - -* Returned Value: -* The TimeScale type code. - -* Notes: -* - A value of AST__BADTS is returned if the time scale -* description was not recognised. This does not produce an error. -* - A value of AST__BADTS is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstTimeScaleType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADTS; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the timescale string against each possibility and assign the - result. */ - if ( astChrMatch( "TAI", ts ) ) { - result = AST__TAI; - - } else if ( astChrMatch( "UTC", ts ) ) { - result = AST__UTC; - - } else if ( astChrMatch( "UT1", ts ) ) { - result = AST__UT1; - - } else if ( astChrMatch( "GMST", ts ) ) { - result = AST__GMST; - - } else if ( astChrMatch( "LAST", ts ) ) { - result = AST__LAST; - - } else if ( astChrMatch( "LMST", ts ) ) { - result = AST__LMST; - - } else if ( astChrMatch( "TT", ts ) ) { - result = AST__TT; - - } else if ( astChrMatch( "TDB", ts ) ) { - result = AST__TDB; - - } else if ( astChrMatch( "TCG", ts ) ) { - result = AST__TCG; - - } else if ( astChrMatch( "TCB", ts ) ) { - result = AST__TCB; - - } else if ( astChrMatch( "LT", ts ) ) { - result = AST__LT; - - } - -/* Return the result. */ - return result; -} - -static const char *TimeScaleString( AstTimeScaleType ts, int *status ) { -/* -* Name: -* TimeScaleString - -* Purpose: -* Convert a time scale type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *TimeScaleString( AstTimeScaleType ts, int *status ) - -* Class Membership: -* TimeFrame member function. - -* Description: -* This function converts a TimeFrame time scale type code (TimeScale -* attribute value) into a string suitable for use as an external -* representation of the time scale type. - -* Parameters: -* ts -* The time scale type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the time scale -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the timescale value against each possibility and convert to a - string pointer. */ - switch ( ts ) { - - case AST__TAI: - result = "TAI"; - break; - - case AST__UTC: - result = "UTC"; - break; - - case AST__UT1: - result = "UT1"; - break; - - case AST__GMST: - result = "GMST"; - break; - - case AST__LAST: - result = "LAST"; - break; - - case AST__LMST: - result = "LMST"; - break; - - case AST__TT: - result = "TT"; - break; - - case AST__TDB: - result = "TDB"; - break; - - case AST__TCB: - result = "TCB"; - break; - - case AST__TCG: - result = "TCG"; - break; - - case AST__LT: - result = "LT"; - break; - - } - -/* Return the result pointer. */ - return result; -} - -static int SubFrame( AstFrame *target_frame, AstFrame *template, - int result_naxes, const int *target_axes, - const int *template_axes, AstMapping **map, - AstFrame **result, int *status ) { -/* -* Name: -* SubFrame - -* Purpose: -* Select axes from a TimeFrame and convert to the new coordinate -* system. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* int SubFrame( AstFrame *target, AstFrame *template, -* int result_naxes, const int *target_axes, -* const int *template_axes, AstMapping **map, -* AstFrame **result, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the protected astSubFrame -* method inherited from the Frame class). - -* Description: -* This function selects a requested sub-set (or super-set) of the axes -* from a "target" TimeFrame and creates a new Frame with copies of -* the selected axes assembled in the requested order. It then -* optionally overlays the attributes of a "template" Frame on to the -* result. It returns both the resulting Frame and a Mapping that -* describes how to convert between the coordinate systems described by -* the target and result Frames. If necessary, this Mapping takes -* account of any differences in the Frames' attributes due to the -* influence of the template. - -* Parameters: -* target -* Pointer to the target TimeFrame, from which axes are to be -* selected. -* template -* Pointer to the template Frame, from which new attributes for the -* result Frame are to be obtained. Optionally, this may be NULL, in -* which case no overlaying of template attributes will be performed. -* result_naxes -* Number of axes to be selected from the target Frame. This number may -* be greater than or less than the number of axes in this Frame (or -* equal). -* target_axes -* Pointer to an array of int with result_naxes elements, giving a list -* of the (zero-based) axis indices of the axes to be selected from the -* target TimeFrame. The order in which these are given determines -* the order in which the axes appear in the result Frame. If any of the -* values in this array is set to -1, the corresponding result axis will -* not be derived from the target Frame, but will be assigned default -* attributes instead. -* template_axes -* Pointer to an array of int with result_naxes elements. This should -* contain a list of the template axes (given as zero-based axis indices) -* with which the axes of the result Frame are to be associated. This -* array determines which axes are used when overlaying axis-dependent -* attributes of the template on to the result. If any element of this -* array is set to -1, the corresponding result axis will not receive any -* template attributes. -* -* If the template argument is given as NULL, this array is not used and -* a NULL pointer may also be supplied here. -* map -* Address of a location to receive a pointer to the returned Mapping. -* The forward transformation of this Mapping will describe how to -* convert coordinates from the coordinate system described by the target -* TimeFrame to that described by the result Frame. The inverse -* transformation will convert in the opposite direction. -* result -* Address of a location to receive a pointer to the result Frame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if coordinate conversion is possible -* between the target and the result Frame. Otherwise zero is returned and -* *map and *result are returned as NULL (but this will not in itself -* result in an error condition). In general, coordinate conversion should -* always be possible if no template Frame is supplied but may not always -* be possible otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* - This implementation addresses the selection of axes from a -* TimeFrame object. This results in another object of the same class -* only if the single TimeFrame axis is selected exactly once. -* Otherwise, the result is a Frame class object which inherits the -* TimeFrame's axis information (if appropriate) but none of the other -* properties of a TimeFrame. -* - In the event that a TimeFrame results, the returned Mapping will -* take proper account of the relationship between the target and result -* coordinate systems. -* - In the event that a Frame class object results, the returned Mapping -* will only represent a selection/permutation of axes. - -* Implementation Deficiencies: -* - Any axis selection is currently permitted. Probably this should be -* restricted so that each axis can only be selected once. The -* astValidateAxisSelection method will do this but currently there are bugs -* in the CmpFrame class that cause axis selections which will not pass this -* test. Install the validation when these are fixed. -*/ - -/* Local Variables: */ - AstTimeFrame *target; /* Pointer to the TimeFrame structure */ - AstTimeFrame *temp; /* Pointer to copy of target TimeFrame */ - AstTimeFrame *align_frm; /* Frame in which to align the TimeFrames */ - int match; /* Coordinate conversion is possible? */ - -/* Initialise the returned values. */ - *map = NULL; - *result = NULL; - match = 0; - -/* Check the global error status. */ - if ( !astOK ) return match; - -/* Obtain a pointer to the target TimeFrame structure. */ - target = (AstTimeFrame *) target_frame; - -/* Result is a TimeFrame. */ -/* -------------------------- */ -/* Check if the result Frame is to have one axis obtained by selecting - the single target TimeFrame axis. If so, the result will also be - a TimeFrame. */ - if ( ( result_naxes == 1 ) && ( target_axes[ 0 ] == 0 ) ) { - -/* Form the result from a copy of the target. */ - *result = astCopy( target ); - -/* If required, overlay the template attributes on to the result TimeFrame. - Also choose the Frame which defined the alignment system and time scale - (via its AlignSystem and AlignTimeScale attributes) in which to align the - two TimeFrames. This is the template (if there is a template). */ - if ( template ) { - astOverlay( template, template_axes, *result ); - if( astIsATimeFrame( template ) ) { - align_frm = astClone( template ); - } else { - align_frm = astClone( target ); - } - -/* If no template was supplied, align in the System and TimeScale of the - target. */ - } else { - VerifyAttrs( target, "convert between different time systems", - "TimeScale", "astMatch", status ); - align_frm = astClone( target ); - } - -/* Generate a Mapping that takes account of changes in the sky coordinate - system (equinox, epoch, etc.) between the target TimeFrame and the result - TimeFrame. If this Mapping can be generated, set "match" to indicate that - coordinate conversion is possible. */ - match = ( MakeTimeMapping( target, (AstTimeFrame *) *result, - align_frm, 0, map, status ) != 0 ); - -/* Free resources. */ - align_frm = astAnnul( align_frm ); - -/* Result is not a TimeFrame. */ -/* ------------------------------ */ -/* In this case, we select axes as if the target were from the Frame - class. However, since the resulting data will then be separated - from their enclosing TimeFrame, default attribute values may differ - if the methods for obtaining them were over-ridden by the TimeFrame - class. To overcome this, we ensure that these values are explicitly - set for the result Frame (rather than relying on their defaults). */ - } else { - -/* Make a temporary copy of the target TimeFrame. We will explicitly - set the attribute values in this copy so as not to modify the original. */ - temp = astCopy( target ); - -/* Define a macro to test if an attribute is set. If not, set it - explicitly to its default value. */ -#define SET(attribute) \ - if ( !astTest##attribute( temp ) ) { \ - astSet##attribute( temp, astGet##attribute( temp ) ); \ - } - -/* Set attribute values which apply to the Frame as a whole and which - we want to retain, but whose defaults are over-ridden by the - TimeFrame class. */ - SET(Domain) - SET(Title) - -/* Define a macro to test if an attribute is set for axis zero (the only - axis of a TimeFrame). If not, set it explicitly to its default value. */ -#define SET_AXIS(attribute) \ - if ( !astTest##attribute( temp, 0 ) ) { \ - astSet##attribute( temp, 0, \ - astGet##attribute( temp, 0 ) ); \ - } - -/* Use this macro to set explicit values for all the axis attributes - for which the TimeFrame class over-rides the default value. */ - SET_AXIS(Label) - SET_AXIS(Symbol) - SET_AXIS(Unit) - -/* Clear attributes which have an extended range of values allowed by - this class. */ - astClearSystem( temp ); - astClearAlignSystem( temp ); - -/* Invoke the astSubFrame method inherited from the Frame class to - produce the result Frame by selecting the required set of axes and - overlaying the template Frame's attributes. */ - match = (*parent_subframe)( (AstFrame *) temp, template, - result_naxes, target_axes, template_axes, - map, result, status ); - -/* Delete the temporary copy of the target TimeFrame. */ - temp = astDelete( temp ); - } - -/* If an error occurred or no match was found, annul the returned - objects and reset the returned result. */ - if ( !astOK || !match ) { - if( *map ) *map = astAnnul( *map ); - if( *result ) *result = astAnnul( *result ); - match = 0; - } - -/* Return the result. */ - return match; - -/* Undefine macros local to this function. */ -#undef SET -#undef SET_AXIS -} - -static AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) { -/* -* Name: -* SystemCode - -* Purpose: -* Convert a string into a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astSystemCode method -* inherited from the Frame class). - -* Description: -* This function converts a string used for the external description of -* a coordinate system into a TimeFrame coordinate system type code -* (System attribute value). It is the inverse of the astSystemString -* function. - -* Parameters: -* this -* The Frame. -* system -* Pointer to a constant null-terminated string containing the -* external description of the sky coordinate system. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System type code. - -* Notes: -* - A value of AST__BADSYSTEM is returned if the sky coordinate -* system description was not recognised. This does not produce an -* error. -* - A value of AST__BADSYSTEM is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" string against each possibility and assign the - result. */ - if ( astChrMatch( "MJD", system ) || astChrMatch( "Modified Julian Date", system ) ) { - result = AST__MJD; - - } else if ( astChrMatch( "JD", system ) || astChrMatch( "Julian Date", system ) ) { - result = AST__JD; - - } else if ( astChrMatch( "BEPOCH", system ) || astChrMatch( "Besselian Epoch", system ) ) { - result = AST__BEPOCH; - - } else if ( astChrMatch( "JEPOCH", system ) || astChrMatch( "Julian Epoch", system ) ) { - result = AST__JEPOCH; - - } - -/* Return the result. */ - return result; -} - -static const char *SystemLabel( AstSystemType system, int *status ) { -/* -* Name: -* SystemLabel - -* Purpose: -* Return a label for a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *SystemLabel( AstSystemType system, int *status ) - -* Class Membership: -* TimeFrame member function. - -* Description: -* This function converts a TimeFrame coordinate system type code -* (System attribute value) into a descriptive string for human readers. - -* Parameters: -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the sky coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. */ - switch ( system ) { - - case AST__MJD: - result = "Modified Julian Date"; - break; - - case AST__JD: - result = "Julian Date"; - break; - - case AST__JEPOCH: - result = "Julian Epoch"; - break; - - case AST__BEPOCH: - result = "Besselian Epoch"; - break; - - } - -/* Return the result pointer. */ - return result; -} - -static const char *SystemString( AstFrame *this, AstSystemType system, int *status ) { -/* -* Name: -* SystemString - -* Purpose: -* Convert a coordinate system type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* const char *SystemString( AstFrame *this, AstSystemType system, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astSystemString method -* inherited from the Frame class). - -* Description: -* This function converts a TimeFrame coordinate system type code -* (System attribute value) into a string suitable for use as an -* external representation of the coordinate system type. - -* Parameters: -* this -* The Frame. -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the sky coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. (Where possible, return the same string as would be - used in the FITS WCS representation of the coordinate system). */ - switch ( system ) { - - case AST__MJD: - result = "MJD"; - break; - - case AST__JD: - result = "JD"; - break; - - case AST__JEPOCH: - result = "JEPOCH"; - break; - - case AST__BEPOCH: - result = "BEPOCH"; - break; - } - -/* Return the result pointer. */ - return result; -} - -static int TestActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* TestActiveUnit - -* Purpose: -* Test the ActiveUnit flag for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* int TestActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astTestActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function test the value of the ActiveUnit flag for a TimeFrame, -* which is always "unset". - -* Parameters: -* this -* Pointer to the TimeFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The result of the test (0). - -*/ - return 0; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astTestAttrib protected -* method inherited from the Frame class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a TimeFrame's attributes. - -* Parameters: -* this -* Pointer to the TimeFrame. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - This function uses one-based axis numbering so that it is -* suitable for external (public) use. -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTimeFrame *this; /* Pointer to the TimeFrame structure */ - char *new_attrib; /* Pointer value to new attribute name */ - int len; /* Length of attrib string */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* First look for axis attributes defined by the Frame class. Since a - TimeFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strcmp( attrib, "direction" ) || - !strcmp( attrib, "bottom" ) || - !strcmp( attrib, "top" ) || - !strcmp( attrib, "format" ) || - !strcmp( attrib, "label" ) || - !strcmp( attrib, "symbol" ) || - !strcmp( attrib, "unit" ) ) { - -/* Create a new attribute name from the original by appending the string - "(1)" and then use the parent TestAttrib method. */ - new_attrib = astMalloc( len + 4 ); - if( new_attrib ) { - memcpy( new_attrib, attrib, len ); - memcpy( new_attrib + len, "(1)", 4 ); - result = (*parent_testattrib)( this_object, new_attrib, status ); - new_attrib = astFree( new_attrib ); - } - -/* AlignTimeScale. */ -/* --------------- */ - } else if ( !strcmp( attrib, "aligntimescale" ) ) { - result = astTestAlignTimeScale( this ); - -/* ClockLat. */ -/* ------- */ - } else if ( !strcmp( attrib, "clocklat" ) ) { - result = astTestAttrib( this, "obslat" ); - -/* ClockLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "clocklon" ) ) { - result = astTestAttrib( this, "obslon" ); - -/* LTOffset. */ -/* --------- */ - } else if ( !strcmp( attrib, "ltoffset" ) ) { - result = astTestLTOffset( this ); - -/* TimeOrigin. */ -/* --------- */ - } else if ( !strcmp( attrib, "timeorigin" ) ) { - result = astTestTimeOrigin( this ); - -/* TimeScale. */ -/* ---------- */ - } else if ( !strcmp( attrib, "timescale" ) ) { - result = astTestTimeScale( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static double ToMJD( AstSystemType oldsys, double oldval, int *status ){ -/* -* Name: -* ToMJD - -* Purpose: -* Convert a time value from TimeFrame's System to MJD. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double ToMJD( AstSystemType oldsys, double oldval, int *status ){ - -* Class Membership: -* TimeFrame member function - -* Description: -* This function converts the supplied value from the supplied System -* to an MJD. - -* Parameters: -* oldsys -* The System in which the oldval is supplied. -* oldval -* The value to convert, assumed to be in the default units -* associated with "oldsys". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The MJD value corresponding to "oldval" - -* Notes: -* - Both old and new value are assumed to be absolute (i.e. have zero -* offset). - -*/ - -/* Local Variables; */ - AstMapping *map; - double result; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the old system is MJD just return the value unchanged. */ - if( oldsys == AST__MJD ) { - result = oldval; - -/* Otherwise create a TimeMap wich converts from the TimeFrame system to - MJD, and use it to transform the supplied value. */ - } else { - map = ToMJDMap( oldsys, 0.0, status ); - -/* Use the TimeMap to convert the supplied value. */ - astTran1( map, 1, &oldval, 1, &result ); - -/* Free resources */ - map = astAnnul( map ); - - } - -/* Return the result */ - return result; -} - -static AstMapping *ToMJDMap( AstSystemType oldsys, double off, int *status ){ -/* -* Name: -* ToMJDMap - -* Purpose: -* Create a Mapping from a specified System to MJD. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* AstMapping *ToMJDMap( AstSystemType oldsys, double off, int *status ){ - -* Class Membership: -* TimeFrame member function - -* Description: -* This function creates a Mapping which converts from the supplied -* system and offset to absolute MJD. - -* Parameters: -* oldsys -* The System in which the oldval is supplied. -* off -* The axis offset used with the old System, assumed to be in the -* default system associated with oldsys. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Mapping. - -*/ - -/* Local Variables; */ - AstTimeMap *timemap; - double args[ 2 ]; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Create a null TimeMap */ - timemap = astTimeMap( 0, "", status ); - -/* Set the offsets for the supplied and returned values. */ - args[ 0 ] = off; - args[ 1 ] = 0.0; - -/* If required, add a TimeMap conversion which converts from the TimeFrame - system to MJD. */ - if( oldsys == AST__MJD ) { -/* if( off != 0.0 ) astTimeAdd( timemap, "MJDTOMJD", 2, args ); */ - astTimeAdd( timemap, "MJDTOMJD", 2, args ); - - } else if( oldsys == AST__JD ) { - astTimeAdd( timemap, "JDTOMJD", 2, args ); - - } else if( oldsys == AST__JEPOCH ) { - astTimeAdd( timemap, "JEPTOMJD", 2, args ); - - } else if( oldsys == AST__BEPOCH ) { - astTimeAdd( timemap, "BEPTOMJD", 2, args ); - } - -/* Return the result */ - return (AstMapping *) timemap; -} - -static double ToUnits( AstTimeFrame *this, const char *oldunit, double oldval, - const char *method, int *status ){ -/* -* -* Name: -* ToUnits - -* Purpose: -* Convert a supplied time value to the default units of the supplied TimeFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double ToUnits( AstTimeFrame *this, const char *oldunit, double oldval, -* const char *method, int *status ) - -* Class Membership: -* TimeFrame member function - -* Description: -* This function converts the supplied time value from the supplied -* units to the default units associated with the supplied TimeFrame's -* System. - -* Parameters: -* this -* Pointer to the TimeFrame. -* oldunit -* The units in which "oldval" is supplied. -* oldval -* The value to be converted. -* method -* Pointer to a string holding the name of the method to be -* included in any error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The converted value. - -*/ - -/* Local Variables: */ - AstMapping *map; - const char *defunit; - double result; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get default units associated with the System attribute of the supplied - TimeFrame, and find a Mapping from the old units to the default. */ - defunit = DefUnit( astGetSystem( this ), method, "TimeFrame", status ); - map = astUnitMapper( oldunit, defunit, NULL, NULL ); - if( map ) { - -/* Use the Mapping to convert the supplied value. */ - astTran1( map, 1, &oldval, 1, &result ); - -/* Free resources. */ - map = astAnnul( map ); - -/* Report an error if no conversion is possible. */ - } else if( astOK ){ - astError( AST__BADUN, "%s(%s): Cannot convert the supplied attribute " - "value from units of %s to %s.", status, method, astGetClass( this ), - oldunit, defunit ); - } - -/* Return the result */ - return result; -} - -static int Unformat( AstFrame *this_frame, int axis, const char *string, - double *value, int *status ) { -/* -* Name: -* Unformat - -* Purpose: -* Read a formatted coordinate value for a TimeFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* int Unformat( AstFrame *this, int axis, const char *string, -* double *value, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the public astUnformat -* method inherited from the Frame class). - -* Description: -* This function reads a formatted coordinate value for a TimeFrame -* axis (supplied as a string) and returns the equivalent numerical -* value as a double. It also returns the number of characters read -* from the string. - -* Parameters: -* this -* Pointer to the TimeFrame. -* axis -* The number of the TimeFrame axis for which the coordinate -* value is to be read (axis numbering starts at zero for the -* first axis). -* string -* Pointer to a constant null-terminated string containing the -* formatted coordinate value. -* value -* Pointer to a double in which the coordinate value read will -* be returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of characters read from the string to obtain the -* coordinate value. - -* Notes: -* - Any white space at the beginning of the string will be -* skipped, as also will any trailing white space following the -* coordinate value read. The function's return value will reflect -* this. -* - A function value of zero (and no coordinate value) will be -* returned, without error, if the string supplied does not contain -* a suitably formatted value. -* - The string "" is recognised as a special case and will -* generate the value AST__BAD, without error. The test for this -* string is case-insensitive and permits embedded white space. -* - A function result of zero will be returned and no coordinate -* value will be returned via the "value" pointer if this function -* is invoked with the global error status set, or if it should -* fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *map; - AstTimeFrame *this; - AstTimeScaleType ts1; - AstTimeScaleType ts2; - const char *c; - char *old_fmt; - char *str; - const char *txt; - double mjd; - double val1; - int l; - int lt; - int nc1; - int nc; - int ndp; - int rep; - -/* Initialise. */ - nc = 0; - -/* Check the global error status. */ - if ( !astOK ) return nc; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_frame; - -/* Validate the axis index. */ - (void) astValidateAxis( this, axis, 1, "astUnformat" ); - -/* First attempt to read the value using the parent unformat method, and - note how many characters were used. We temporarily clear the Format - attribute if it has been set to a date format, since the parent Frame - class does not understand date format.*/ - txt = astGetFormat( this, axis ); - if( DateFormat( txt, &ndp, NULL, status ) ) { - old_fmt = astStore( NULL, txt, strlen( txt ) + 1 ); - astClearFormat( this, axis ); - } else { - old_fmt = NULL; - } - - nc1 = (*parent_unformat)( this_frame, axis, string, &val1, status ); - -/* Re-instate the original Format */ - if( old_fmt ) { - astSetFormat( this,axis, old_fmt ); - old_fmt = astFree( old_fmt ); - } - -/* The astReadDateTime function (defined within frame.c) does not allow - for any extra text to be appended to the end of the formatted date/time - (AST__BAD is returned if any such extra text is present). But astUnformat - is contracted to allow such text. So we need to make multiple attempts - at reading the date/time in order to find the longest leading string - which gives a non-bad value. First take a copy of the supplied string - si we can terminate it at any point we wish. */ - l = astChrLen( string ); - str = astStore( NULL, string, l + 1 ); - -/* Now attempt to read an ISO date from the start of the string. We - switch off error reporting to avoid reports of unsuitable syntax. */ - rep = astReporting( 0 ); - -/* Attempt to read a date/time from the whol string. If this fails - terminate the string in order to make it one character shorter and try - again. */ - for( lt = l; lt > 0; lt-- ) { - str[ lt ] = 0; - mjd = astReadDateTime( str ); - if( !astOK ) astClearStatus; - if( mjd != AST__BAD ) break; - } - -/* Re-instate error reporting. */ - astReporting( rep ); - -/* Free resources. */ - str = astFree( str ); - -/* If the whole non-blank start of the string was consumed, add on any - trailing white space. */ - if( lt >= l ) lt = strlen( string ); - -/* If no date/time could be read, or if reading the value as a - floating point value was at least as good, return the floating point - value (assumed to be in the system and units of the TimeFrame. */ - if( mjd == AST__BAD || nc1 >= l ) { - *value = val1; - nc = nc1; - -/* Otherwise, if a date/time was read convert it to the TimeFrame system, - etc. */ - } else if( mjd != AST__BAD ) { - -/* Save the number of character read from the supplied string. */ - nc = lt; - -/* We require a value in the timescale of the supplied TimeFrame. Get - this TimeScale. */ - ts2 = astGetTimeScale( this ); - -/* If the supplied string gave the date/time as a Besselian epoch, the - input timescale is TT, otherwise it is assumed to be the TimeScale of - the TimeFrame. Locate the first non-space character. */ - c = string; - while( *c && isspace( *c ) ) c++; - -/* If the first non-space is a "B", assuming a TT timescale. Otherwise - assume the timescale of the supplied TimeFrame. */ - ts1 = ( *c == 'B' || *c == 'b' ) ? AST__TT : ts2; - -/* Create the Mapping and use it to transform the mjd value. */ - map = MakeMap( this, AST__MJD, astGetSystem( this ), ts1, ts2, - 0.0, astGetTimeOrigin( this ), "d", - astGetUnit( this, 0 ), "astFormat", status ); - if( map ) { - astTran1( map, 1, &mjd, 1, value ); - map = astAnnul( map ); - } else { - astError( AST__INCTS, "astUnformat(%s): Cannot convert the " - "supplied date/time string (%s) to the required " - "timescale (%s).", status, astGetClass( this ), string, - TimeScaleString( ts2, status ) ); - } - } - -/* Return the number of characters read. */ - return nc; -} - -static int ValidateSystem( AstFrame *this, AstSystemType system, const char *method, int *status ) { -/* -* -* Name: -* ValidateSystem - -* Purpose: -* Validate a value for a Frame's System attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "timeframe.h" -* int ValidateSystem( AstFrame *this, AstSystemType system, -* const char *method, int *status ) - -* Class Membership: -* TimeFrame member function (over-rides the astValidateSystem method -* inherited from the Frame class). - -* Description: -* This function checks the validity of the supplied system value. -* If the value is valid, it is returned unchanged. Otherwise, an -* error is reported and a value of AST__BADSYSTEM is returned. - -* Parameters: -* this -* Pointer to the Frame. -* system -* The system value to be checked. -* method -* Pointer to a constant null-terminated character string -* containing the name of the method that invoked this function -* to validate an axis index. This method name is used solely -* for constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The validated system value. - -* Notes: -* - A value of AST__BADSYSTEM will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Validated system value */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the value is out of bounds, report an error. */ - if ( system < FIRST_SYSTEM || system > LAST_SYSTEM ) { - astError( AST__AXIIN, "%s(%s): Bad value (%d) given for the System " - "or AlignSystem attribute of a %s.", status, method, - astGetClass( this ), (int) system, astGetClass( this ) ); - -/* Otherwise, return the supplied value. */ - } else { - result = system; - } - -/* Return the result. */ - return result; -} - -static void VerifyAttrs( AstTimeFrame *this, const char *purp, - const char *attrs, const char *method, int *status ) { -/* -* Name: -* VerifyAttrs - -* Purpose: -* Verify that usable attribute values are available. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* void VerifyAttrs( AstTimeFrame *this, const char *purp, -* const char *attrs, const char *method, int *status ) - -* Class Membership: -* TimeFrame member function - -* Description: -* This function tests each attribute listed in "attrs". It returns -* without action if 1) an explicit value has been set for each attribute -* or 2) the UseDefs attribute of the supplied TimeFrame is non-zero. -* -* If UseDefs is zero (indicating that default values should not be -* used for attributes), and any of the named attributes does not have -* an explicitly set value, then an error is reported. - -* Parameters: -* this -* Pointer to the TimeFrame. -* purp -* Pointer to a text string containing a message which will be -* included in any error report. This shouldindicate the purpose -* for which the attribute value is required. -* attrs -* A string holding a space separated list of attribute names. -* method -* A string holding the name of the calling method for use in error -* messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - const char *a; - const char *desc; - const char *p; - int len; - int set; - int state; - -/* Check inherited status */ - if( !astOK ) return; - -/* Stop compiler warnings about uninitialised variables */ - a = NULL; - desc = NULL; - len = 0; - set = 0; - -/* If the TimeFrame has a non-zero value for its UseDefs attribute, then - all attributes are assumed to have usable values, since the defaults - will be used if no explicit value has been set. So we only need to do - any checks if UseDefs is zero. */ - if( !astGetUseDefs( this ) ) { - -/* Loop round the "attrs" string identifying the start and length of each - non-blank word in the string. */ - state = 0; - p = attrs; - while( 1 ) { - if( state == 0 ) { - if( !isspace( *p ) ) { - a = p; - len = 1; - state = 1; - } - } else { - if( isspace( *p ) || !*p ) { - -/* The end of a word has just been reached. Compare it to each known - attribute value. Get a flag indicating if the attribute has a set - value, and a string describing the attribute.*/ - if( len > 0 ) { - - if( !strncmp( "ObsLat", a, len ) ) { - set = astTestObsLat( this ); - desc = "observer latitude"; - - } else if( !strncmp( "ObsLon", a, len ) ) { - set = astTestObsLon( this ); - desc = "observer longitude"; - - } else if( !strncmp( "ObsAlt", a, len ) ) { - set = astTestObsAlt( this ); - desc = "observer altitude"; - - } else if( !strncmp( "Dtai", a, len ) ) { - set = astTestDtai( this ); - desc = "TAI-UTC correction"; - - } else if( !strncmp( "Dut1", a, len ) ) { - set = astTestDut1( this ); - desc = "UT1-UTC correction"; - - } else if( !strncmp( "TimeOrigin", a, len ) ) { - set = astTestTimeOrigin( this ); - desc = "time offset"; - - } else if( !strncmp( "LTOffset", a, len ) ) { - set = astTestLTOffset( this ); - desc = "local time offset"; - - } else if( !strncmp( "TimeScale", a, len ) ) { - set = astTestTimeScale( this ); - desc = "time scale"; - - } else { - astError( AST__INTER, "VerifyAttrs(TimeFrame): " - "Unknown attribute name \"%.*s\" supplied (AST " - "internal programming error).", status, len, a ); - } - -/* If the attribute does not have a set value, report an error. */ - if( !set && astOK ) { - astError( AST__NOVAL, "%s(%s): Cannot %s.", status, method, - astGetClass( this ), purp ); - astError( AST__NOVAL, "No value has been set for " - "the AST \"%.*s\" attribute (%s).", status, len, a, - desc ); - } - -/* Continue the word search algorithm. */ - } - len = 0; - state = 0; - } else { - len++; - } - } - if( !*(p++) ) break; - } - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ - -/* -*att++ -* Name: -* TimeOrigin - -* Purpose: -* The zero point for TimeFrame axis values - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This specifies the origin from which all time values are measured. -* The default value (zero) results in the TimeFrame describing -* absolute time values in the system given by the System attribute -* (e.g. MJD, Julian epoch, etc). If a TimeFrame is to be used to -* describe elapsed time since some origin, the TimeOrigin attribute -* should be set to hold the required origin value. The TimeOrigin value -* stored inside the TimeFrame structure is modified whenever TimeFrame -* attribute values are changed so that it refers to the original moment -* in time. -* -* Input Formats: -* The formats accepted when setting a TimeOrigin value are listed -* below. They are all case-insensitive and are generally tolerant -* of extra white space and alternative field delimiters: -* -* - Besselian Epoch: Expressed in decimal years, with or without -* decimal places ("B1950" or "B1976.13" for example). -* -* - Julian Epoch: Expressed in decimal years, with or without -* decimal places ("J2000" or "J2100.9" for example). -* -* - Units: An unqualified decimal value is interpreted as a value in -* the system specified by the TimeFrame's System attribute, in the -* units given by the TimeFrame's Unit attribute. Alternatively, an -* appropriate unit string can be appended to the end of the floating -* point value ("123.4 d" for example), in which case the supplied value -* is scaled into the units specified by the Unit attribute. -* -* - Julian Date: With or without decimal places ("JD 2454321.9" for -* example). -* -* - Modified Julian Date: With or without decimal places -* ("MJD 54321.4" for example). -* -* - Gregorian Calendar Date: With the month expressed either as an -* integer or a 3-character abbreviation, and with optional decimal -* places to represent a fraction of a day ("1996-10-2" or -* "1996-Oct-2.6" for example). If no fractional part of a day is -* given, the time refers to the start of the day (zero hours). -* -* - Gregorian Date and Time: Any calendar date (as above) but with -* a fraction of a day expressed as hours, minutes and seconds -* ("1996-Oct-2 12:13:56.985" for example). The date and time can be -* separated by a space or by a "T" (as used by ISO8601 format). - -* Output Format: -* When enquiring TimeOrigin values, the returned formatted floating -* point value represents a value in the TimeFrame's System, in the unit -* specified by the TimeFrame's Unit attribute. - -* Applicability: -* TimeFrame -* All TimeFrames have this attribute. - -*att-- -*/ -/* The time origin, stored internally in the default units associated - with the current System value. Clear the TimeOrigin value by setting it - to AST__BAD, which gives 0.0 as the default value. Any value is acceptable. */ -astMAKE_CLEAR(TimeFrame,TimeOrigin,timeorigin,AST__BAD) -astMAKE_GET(TimeFrame,TimeOrigin,double,0.0,((this->timeorigin!=AST__BAD)?this->timeorigin:0.0)) -astMAKE_SET(TimeFrame,TimeOrigin,double,timeorigin,value) -astMAKE_TEST(TimeFrame,TimeOrigin,( this->timeorigin != AST__BAD )) - -/* -*att++ -* Name: -* LTOffset - -* Purpose: -* The offset from UTC to Local Time, in hours. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This specifies the offset from UTC to Local Time, in hours (fractional -* hours can be supplied). It is positive for time zones east of Greenwich. -* AST uses the figure as given, without making any attempt to correct for -* daylight saving. The default value is zero. - -* Applicability: -* TimeFrame -* All TimeFrames have this attribute. - -*att-- -*/ -astMAKE_CLEAR(TimeFrame,LTOffset,ltoffset,AST__BAD) -astMAKE_GET(TimeFrame,LTOffset,double,0.0,((this->ltoffset!=AST__BAD)?this->ltoffset:0.0)) -astMAKE_SET(TimeFrame,LTOffset,double,ltoffset,value) -astMAKE_TEST(TimeFrame,LTOffset,( this->ltoffset != AST__BAD )) - -/* -*att++ -* Name: -* AlignTimeScale - -* Purpose: -* Time scale to use when aligning TimeFrames. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls how a TimeFrame behaves when it is used (by -c astFindFrame or astConvert) as a template to match another (target) -f AST_FINDFRAME or AST_CONVERT) as a template to match another (target) -* TimeFrame. It identifies the time scale in which alignment is -* to occur. See the TimeScale attribute for a desription of the values -* which may be assigned to this attribute. The default AlignTimeScale -* value depends on the current value of TimeScale: if TimeScale is -* UT1, GMST, LMST or LAST, the default for AlignTimeScale is UT1, for all -* other TimeScales the default is TAI. -* -c When astFindFrame or astConvert is used on two TimeFrames (potentially -f When AST_FindFrame or AST_CONVERT is used on two TimeFrames (potentially -* describing different time coordinate systems), it returns a Mapping -* which can be used to transform a position in one TimeFrame into the -* corresponding position in the other. The Mapping is made up of the -* following steps in the indicated order: -* -* - Map values from the system used by the target (MJD, JD, etc) to the -* system specified by the AlignSystem attribute. -* -* - Map these values from the target's time scale to the time scale -* specified by the AlignTimeScale attribute. -* -* - Map these values from the time scale specified by the AlignTimeScale -* attribute, to the template's time scale. -* -* - Map these values from the system specified by the AlignSystem -* attribute, to the system used by the template. - -* Applicability: -* TimeFrame -* All TimeFrames have this attribute. - -*att-- -*/ -astMAKE_TEST(TimeFrame,AlignTimeScale,( this->aligntimescale != AST__BADTS )) -astMAKE_CLEAR(TimeFrame,AlignTimeScale,aligntimescale,AST__BADTS) -astMAKE_SET(TimeFrame,AlignTimeScale,AstTimeScaleType,aligntimescale,( - ( ( value >= FIRST_TS ) && ( value <= LAST_TS ) ) ? - value : - ( astError( AST__ATTIN, "%s(%s): Bad value (%d) " - "given for AlignTimeScale attribute.", status, - "astSetAlignTimeScale", astGetClass( this ), (int) value ), - -/* Leave the value unchanged on error. */ - this->aligntimescale ) ) ) - -/* -*att++ -* Name: -* TimeScale - -* Purpose: -* Time scale. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute identifies the time scale to which the time axis values -* of a TimeFrame refer, and may take any of the values listed in the -* "Time Scales" section (below). -* -* The default TimeScale value depends on the current System value; if -* the current TimeFrame system is "Besselian epoch" the default is -* "TT", otherwise it is "TAI". Note, if the System attribute is set -* so that the TimeFrame represents Besselian Epoch, then an error -* will be reported if an attempt is made to set the TimeScale to -* anything other than TT. -* -* Note, the supported time scales fall into two groups. The first group -* containing UT1, GMST, LAST and LMST define time in terms of the -* orientation of the earth. The second group (containing all the remaining -* time scales) define time in terms of an atomic process. Since the rate of -* rotation of the earth varies in an unpredictable way, conversion between -* two timescales in different groups relies on a value being supplied for -* the Dut1 attribute (defined by the parent Frame class). This attribute -* specifies the difference between the UT1 and UTC time scales, in seconds, -* and defaults to zero. See the documentation for the Dut1 attribute for -* further details. - -* Applicability: -* TimeFrame -* All TimeFrames have this attribute. - -* Time Scales: -* The TimeFrame class supports the following TimeScale values (all are -* case-insensitive): -* -* - "TAI" - International Atomic Time -* - "UTC" - Coordinated Universal Time -* - "UT1" - Universal Time -* - "GMST" - Greenwich Mean Sidereal Time -* - "LAST" - Local Apparent Sidereal Time -* - "LMST" - Local Mean Sidereal Time -* - "TT" - Terrestrial Time -* - "TDB" - Barycentric Dynamical Time -* - "TCB" - Barycentric Coordinate Time -* - "TCG" - Geocentric Coordinate Time -* - "LT" - Local Time (the offset from UTC is given by attribute LTOffset) -* -* An very informative description of these and other time scales is -* available at http://www.ucolick.org/~sla/leapsecs/timescales.html. - -* UTC Warnings: -* UTC should ideally be expressed using separate hours, minutes and -* seconds fields (or at least in seconds for a given date) if leap seconds -* are to be taken into account. Since the TimeFrame class represents -* each moment in time using a single floating point number (the axis value) -* there will be an ambiguity during a leap second. Thus an error of up to -* 1 second can result when using AST to convert a UTC time to another -* time scale if the time occurs within a leap second. Leap seconds -* occur at most twice a year, and are introduced to take account of -* variation in the rotation of the earth. The most recent leap second -* occurred on 1st January 1999. Although in the vast majority of cases -* leap second ambiguities won't matter, there are potential problems in -* on-line data acquisition systems and in critical applications involving -* taking the difference between two times. - -*att-- -*/ -astMAKE_TEST(TimeFrame,TimeScale,( this->timescale != AST__BADTS )) - -/* Copy constructor. */ -/* ----------------- */ - -/* Destructor. */ -/* ----------- */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for TimeFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the TimeFrame class to an output Channel. - -* Parameters: -* this -* Pointer to the TimeFrame whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstTimeFrame *this; /* Pointer to the TimeFrame structure */ - AstTimeScaleType ts; /* TimeScale attribute value */ - const char *sval; /* Pointer to string value */ - double dval; /* Double value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TimeFrame structure. */ - this = (AstTimeFrame *) this_object; - -/* Write out values representing the instance variables for the - TimeFrame class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* TimeScale. */ -/* ---------- */ - set = TestTimeScale( this, status ); - ts = set ? GetTimeScale( this, status ) : astGetTimeScale( this ); - -/* If set, convert explicitly to a string for the external - representation. */ - sval = ""; - if ( set ) { - if ( astOK ) { - sval = TimeScaleString( ts, status ); - -/* Report an error if the TimeScale value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid time scale " - "identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) ts ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "timescale" ); - } - -/* Write out the value. */ - astWriteString( channel, "TmScl", set, 1, sval, "Time scale" ); - -/* AlignTimeScale. */ -/* --------------- */ - set = TestAlignTimeScale( this, status ); - ts = set ? GetAlignTimeScale( this, status ) : astGetAlignTimeScale( this ); - -/* If set, convert explicitly to a string for the external representation. */ - if ( set ) { - if ( astOK ) { - sval = TimeScaleString( ts, status ); - -/* Report an error if the TimeScale value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid alignment time " - "scale identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) ts ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "aligntimescale" ); - } - -/* Write out the value. */ - astWriteString( channel, "ATmScl", set, 0, sval, "Alignment time scale" ); - -/* TimeOrigin. */ -/* ----------- */ - set = TestTimeOrigin( this, status ); - dval = set ? GetTimeOrigin( this, status ) : astGetTimeOrigin( this ); - astWriteDouble( channel, "TmOrg", set, 0, dval, "Time offset" ); - -/* LTOffset. */ -/* --------- */ - set = TestLTOffset( this, status ); - dval = set ? GetLTOffset( this, status ) : astGetLTOffset( this ); - astWriteDouble( channel, "LTOff", set, 0, dval, "Local Time offset from UTC" ); - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsATimeFrame and astCheckTimeFrame functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(TimeFrame,Frame) -astMAKE_CHECK(TimeFrame) - -AstTimeFrame *astTimeFrame_( const char *options, int *status, ...) { -/* -*+ -* Name: -* astTimeFrame - -* Purpose: -* Create a TimeFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* AstTimeFrame *astTimeFrame( const char *options, int *status, ... ) - -* Class Membership: -* TimeFrame constructor. - -* Description: -* This function creates a new TimeFrame and optionally initialises its -* attributes. - -* Parameters: -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new TimeFrame. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new TimeFrame. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic TimeFrame constructor which -* is available via the protected interface to the TimeFrame class. -* A public interface is provided by the astTimeFrameId_ function. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *um; /* Mapping from default to actual units */ - AstTimeFrame *new; /* Pointer to new TimeFrame */ - AstSystemType s; /* System */ - const char *u; /* Units string */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the TimeFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitTimeFrame( NULL, sizeof( AstTimeFrame ), !class_init, - &class_vtab, "TimeFrame" ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new TimeFrame's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* Check the Units are appropriate for the System. */ - u = astGetUnit( new, 0 ); - s = astGetSystem( new ); - um = astUnitMapper( DefUnit( s, "astTimeFrame", "TimeFrame", status ), - u, NULL, NULL ); - if( um ) { - um = astAnnul( um ); - } else { - astError( AST__BADUN, "astTimeFrame: Inappropriate units (%s) " - "specified for a %s axis.", status, u, SystemLabel( s, status ) ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new TimeFrame. */ - return new; -} - -AstTimeFrame *astInitTimeFrame_( void *mem, size_t size, int init, - AstTimeFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitTimeFrame - -* Purpose: -* Initialise a TimeFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* AstTimeFrame *astInitTimeFrame( void *mem, size_t size, int init, -* AstFrameVtab *vtab, const char *name ) - -* Class Membership: -* TimeFrame initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new TimeFrame object. It allocates memory (if -* necessary) to accommodate the TimeFrame plus any additional data -* associated with the derived class. It then initialises a -* TimeFrame structure at the start of this memory. If the "init" -* flag is set, it also initialises the contents of a virtual function -* table for a TimeFrame at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the TimeFrame is to be -* created. This must be of sufficient size to accommodate the -* TimeFrame data (sizeof(TimeFrame)) plus any data used by -* the derived class. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the TimeFrame (plus derived -* class data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also stored -* in the TimeFrame structure, so a valid value must be supplied -* even if not required for allocating memory. -* init -* A logical flag indicating if the TimeFrame's virtual function -* table is to be initialised. If this value is non-zero, the -* virtual function table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new TimeFrame. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object belongs -* (it is this pointer value that will subsequently be returned by -* the astGetClass method). - -* Returned Value: -* A pointer to the new TimeFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstTimeFrame *new; /* Pointer to the new TimeFrame */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitTimeFrameVtab( vtab, name ); - -/* Initialise a 1D Frame structure (the parent class) as the first component - within the TimeFrame structure, allocating memory if necessary. */ - new = (AstTimeFrame *) astInitFrame( mem, size, 0, - (AstFrameVtab *) vtab, name, 1 ); - - if ( astOK ) { - -/* Initialise the TimeFrame data. */ -/* ----------------------------- */ -/* Initialise all attributes to their "undefined" values. */ - new->timeorigin = AST__BAD; - new->ltoffset = AST__BAD; - new->timescale = AST__BADTS; - new->aligntimescale = AST__BADTS; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - - } - -/* Return a pointer to the new object. */ - return new; -} - -AstTimeFrame *astLoadTimeFrame_( void *mem, size_t size, - AstTimeFrameVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadTimeFrame - -* Purpose: -* Load a TimeFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* AstTimeFrame *astLoadTimeFrame( void *mem, size_t size, -* AstTimeFrameVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* TimeFrame loader. - -* Description: -* This function is provided to load a new TimeFrame using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* TimeFrame structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the TimeFrame is to be -* loaded. This must be of sufficient size to accommodate the -* TimeFrame data (sizeof(TimeFrame)) plus any data used by -* derived classes. If a value of NULL is given, this function -* will allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the TimeFrame (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the TimeFrame structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstTimeFrame) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new TimeFrame. If this is NULL, a pointer -* to the (static) virtual function table for the TimeFrame class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "TimeFrame" is used instead. - -* Returned Value: -* A pointer to the new TimeFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstTimeFrame *new; /* Pointer to the new TimeFrame */ - char *sval; /* Pointer to string value */ - double obslat; /* Value for ObsLat attribute */ - double obslon; /* Value for ObsLon attribute */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this TimeFrame. In this case the - TimeFrame belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstTimeFrame ); - vtab = &class_vtab; - name = "TimeFrame"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitTimeFrameVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built TimeFrame. */ - new = astLoadFrame( mem, size, (AstFrameVtab *) vtab, name, - channel ); - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "TimeFrame" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* TimeScale. */ -/* ---------- */ -/* Set the default and read the external representation as a string. */ - new->timescale = AST__BADTS; - sval = astReadString( channel, "tmscl", NULL ); - -/* If a value was read, convert from a string to a TimeScale code. */ - if ( sval ) { - if ( astOK ) { - new->timescale = TimeScaleCode( sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->timescale == AST__BADTS ) { - astError( AST__ATTIN, - "astRead(%s): Invalid time scale description " - "\"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* AlignTimeScale. */ -/* --------------- */ -/* Set the default and read the external representation as a string. */ - new->aligntimescale = AST__BADTS; - sval = astReadString( channel, "atmscl", NULL ); - -/* If a value was read, convert from a string to a TimeScale code. */ - if ( sval ) { - if ( astOK ) { - new->aligntimescale = TimeScaleCode( sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->aligntimescale == AST__BADTS ) { - astError( AST__ATTIN, - "astRead(%s): Invalid alignment time scale " - "description \"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* ClockLat. */ -/* --------- */ -/* Retained for backward compatibility with older versions of AST in - which TimeFrame had a ClockLat attribute (now ObsLat is used instead). */ - if( !astTestObsLat( new ) ) { - obslat = astReadDouble( channel, "cllat", AST__BAD ); - if ( obslat != AST__BAD ) astSetObsLat( new, obslat ); - } - -/* ClockLon. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in - which TimeFrame had a ClockLon attribute (now ObsLon is used instead). */ - if( !astTestObsLon( new ) ) { - obslon = astReadDouble( channel, "cllon", AST__BAD ); - if ( obslon != AST__BAD ) astSetObsLon( new, obslon ); - } - -/* TimeOrigin. */ -/* --------- */ - new->timeorigin = astReadDouble( channel, "tmorg", AST__BAD ); - if ( TestTimeOrigin( new, status ) ) SetTimeOrigin( new, new->timeorigin, status ); - -/* LTOffset. */ -/* --------- */ - new->ltoffset = astReadDouble( channel, "ltoff", AST__BAD ); - if ( TestLTOffset( new, status ) ) SetLTOffset( new, new->ltoffset, status ); - -/* If an error occurred, clean up by deleting the new TimeFrame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new TimeFrame pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astSetTimeScale_( AstTimeFrame *this, AstTimeScaleType value, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,TimeFrame,SetTimeScale))(this,value, status ); -} - -void astClearTimeScale_( AstTimeFrame *this, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,TimeFrame,ClearTimeScale))(this, status ); -} - -AstTimeScaleType astGetAlignTimeScale_( AstTimeFrame *this, int *status ) { - if ( !astOK ) return AST__BADTS; - return (**astMEMBER(this,TimeFrame,GetAlignTimeScale))(this, status ); -} - -AstTimeScaleType astGetTimeScale_( AstTimeFrame *this, int *status ) { - if ( !astOK ) return AST__BADTS; - return (**astMEMBER(this,TimeFrame,GetTimeScale))(this, status ); -} - -double astCurrentTime_( AstTimeFrame *this, int *status ){ - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,TimeFrame,CurrentTime))(this, status ); -} - - - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstTimeFrame *astTimeFrameId_( const char *, ... ); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstTimeFrame *astTimeFrameId_( const char *options, ... ) { -/* -*++ -* Name: -c astTimeFrame -f AST_TIMEFRAME - -* Purpose: -* Create a TimeFrame. - -* Type: -* Public function. - -* Synopsis: -c #include "timeframe.h" -c AstTimeFrame *astTimeFrame( const char *options, ... ) -f RESULT = AST_TIMEFRAME( OPTIONS, STATUS ) - -* Class Membership: -* TimeFrame constructor. - -* Description: -* This function creates a new TimeFrame and optionally initialises -* its attributes. -* -* A TimeFrame is a specialised form of one-dimensional Frame which -* represents various coordinate systems used to describe positions in -* time. -* -* A TimeFrame represents a moment in time as either an Modified Julian -* Date (MJD), a Julian Date (JD), a Besselian epoch or a Julian epoch, -* as determined by the System attribute. Optionally, a zero point can be -* specified (using attribute TimeOrigin) which results in the TimeFrame -* representing time offsets from the specified zero point. -* -* Even though JD and MJD are defined as being in units of days, the -* TimeFrame class allows other units to be used (via the Unit attribute) -* on the basis of simple scalings (60 seconds = 1 minute, 60 minutes = 1 -* hour, 24 hours = 1 day, 365.25 days = 1 year). Likewise, Julian epochs -* can be described in units other than the usual years. Besselian epoch -* are always represented in units of (tropical) years. -* -* The TimeScale attribute allows the time scale to be specified (that -* is, the physical proces used to define the rate of flow of time). -* MJD, JD and Julian epoch can be used to represent a time in any -* supported time scale. However, Besselian epoch may only be used with the -* "TT" (Terrestrial Time) time scale. The list of supported time scales -* includes universal time and siderial time. Strictly, these represent -* angles rather than time scales, but are included in the list since -* they are in common use and are often thought of as time scales. -* -* When a time value is formatted it can be formated either as a simple -* floating point value, or as a Gregorian date (see the Format -* attribute). - -* Parameters: -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new TimeFrame. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new TimeFrame. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astTimeFrame() -f AST_TIMEFRAME = INTEGER -* A pointer to the new TimeFrame. - -* Notes: -* - When conversion between two TimeFrames is requested (as when -c supplying TimeFrames to astConvert), -f supplying TimeFrames AST_CONVERT), -* account will be taken of the nature of the time coordinate systems -* they represent, together with any qualifying time scale, offset, -* unit, etc. The AlignSystem and AlignTimeScale attributes will also be -* taken into account. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astTimeFrame constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astTimeFrame_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - The variable argument list also prevents this function from -* invoking astTimeFrame_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *um; /* Mapping from default to actual units */ - AstTimeFrame *new; /* Pointer to new TimeFrame */ - AstSystemType s; /* System */ - const char *u; /* Units string */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the TimeFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitTimeFrame( NULL, sizeof( AstTimeFrame ), !class_init, - &class_vtab, "TimeFrame" ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new TimeFrame's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* Check the Units are appropriate for the System. */ - u = astGetUnit( new, 0 ); - s = astGetSystem( new ); - um = astUnitMapper( DefUnit( s, "astTimeFrame", "TimeFrame", status ), - u, NULL, NULL ); - if( um ) { - um = astAnnul( um ); - } else { - astError( AST__BADUN, "astTimeFrame: Inappropriate units (%s) " - "specified for a %s axis.", status, u, SystemLabel( s, status ) ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new TimeFrame. */ - return astMakeId( new ); -} - - - - - - - - - - - - - - - - - - - - diff --git a/ast/timeframe.h b/ast/timeframe.h deleted file mode 100644 index 4aae267..0000000 --- a/ast/timeframe.h +++ /dev/null @@ -1,324 +0,0 @@ -#if !defined( TIMEFRAME_INCLUDED ) /* Include this file only once */ -#define TIMEFRAME_INCLUDED -/* -*+ -* Name: -* timeframe.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the TimeFrame class. - -* Invocation: -* #include "timeframe.h" - -* Description: -* This include file defines the interface to the TimeFrame class -* and provides the type definitions, function prototypes and -* macros, etc. needed to use this class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 20-MAY-2005 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "object.h" /* Base Object class */ -#include "frame.h" /* Parent Frame class */ -#include "skyframe.h" /* Celestial coordinate systems */ - -/* Macros. */ -/* ======= */ -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -#if defined(astCLASS) /* Protected */ - -/* Values used to represent different System attribute values. */ -#define AST__MJD 1 -#define AST__JD 2 -#define AST__JEPOCH 3 -#define AST__BEPOCH 4 - -/* Values used to represent different TimeScale attribute values. */ -#define AST__BADTS 0 -#define AST__TAI 1 -#define AST__UTC 2 -#define AST__UT1 3 -#define AST__GMST 4 -#define AST__LAST 5 -#define AST__LMST 6 -#define AST__TT 7 -#define AST__TDB 8 -#define AST__TCB 9 -#define AST__TCG 10 -#define AST__LT 11 - -/* Define constants used to size global arrays in this module. */ -#define AST__TIMEFRAME_FORMAT_BUFF_LEN 200 -#define AST__TIMEFRAME_GETATTRIB_BUFF_LEN 50 -#define AST__TIMEFRAME_GETLABEL_BUFF_LEN 200 -#define AST__TIMEFRAME_GETSYMBOL_BUFF_LEN 20 -#define AST__TIMEFRAME_GETTITLE_BUFF_LEN 200 - -#endif - -/* Type Definitions. */ -/* ================= */ - -/* Integer type used to store the TimeScale attribute. */ -typedef int AstTimeScaleType; - -/* TimeFrame structure. */ -/* ------------------- */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstTimeFrame { - -/* Attributes inherited from the parent class. */ - AstFrame frame; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double ltoffset; /* Offset from UTC to Local Time */ - double timeorigin; /* Zero point for time axis */ - AstTimeScaleType timescale; /* Time scale */ - AstTimeScaleType aligntimescale; /* Alignment time scale */ -} AstTimeFrame; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all objects in the - class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstTimeFrameVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstFrameVtab frame_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - double (* CurrentTime)( AstTimeFrame *, int * ); - - double (* GetLTOffset)( AstTimeFrame *, int * ); - int (* TestLTOffset)( AstTimeFrame *, int * ); - void (* ClearLTOffset)( AstTimeFrame *, int * ); - void (* SetLTOffset)( AstTimeFrame *, double, int * ); - - double (* GetTimeOrigin)( AstTimeFrame *, int * ); - int (* TestTimeOrigin)( AstTimeFrame *, int * ); - void (* ClearTimeOrigin)( AstTimeFrame *, int * ); - void (* SetTimeOrigin)( AstTimeFrame *, double, int * ); - - AstTimeScaleType (* GetTimeScale)( AstTimeFrame *, int * ); - int (* TestTimeScale)( AstTimeFrame *, int * ); - void (* ClearTimeScale)( AstTimeFrame *, int * ); - void (* SetTimeScale)( AstTimeFrame *, AstTimeScaleType, int * ); - - AstTimeScaleType (* GetAlignTimeScale)( AstTimeFrame *, int * ); - int (* TestAlignTimeScale)( AstTimeFrame *, int * ); - void (* ClearAlignTimeScale)( AstTimeFrame *, int * ); - void (* SetAlignTimeScale)( AstTimeFrame *, AstTimeScaleType, int * ); - -} AstTimeFrameVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstTimeFrameGlobals { - AstTimeFrameVtab Class_Vtab; - int Class_Init; - char Format_Buff[ AST__TIMEFRAME_FORMAT_BUFF_LEN + 1 ]; - char GetAttrib_Buff[ AST__TIMEFRAME_GETATTRIB_BUFF_LEN + 1 ]; - char GetLabel_Buff[ AST__TIMEFRAME_GETLABEL_BUFF_LEN + 1 ]; - char GetSymbol_Buff[ AST__TIMEFRAME_GETSYMBOL_BUFF_LEN + 1 ]; - char GetTitle_Buff[ AST__TIMEFRAME_GETTITLE_BUFF_LEN + 1 ]; -} AstTimeFrameGlobals; - -#endif - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(TimeFrame) /* Check class membership */ -astPROTO_ISA(TimeFrame) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -AstTimeFrame *astTimeFrame_( const char *, int *, ...); -#else -AstTimeFrame *astTimeFrameId_( const char *, ... )__attribute__((format(printf,1,2))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstTimeFrame *astInitTimeFrame_( void *, size_t, int, AstTimeFrameVtab *, - const char *, int * ); - -/* Vtab initialiser. */ -void astInitTimeFrameVtab_( AstTimeFrameVtab *, const char *, int * ); - -/* Loader. */ -AstTimeFrame *astLoadTimeFrame_( void *, size_t, AstTimeFrameVtab *, - const char *, AstChannel *channel, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitTimeFrameGlobals_( AstTimeFrameGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -double astCurrentTime_( AstTimeFrame *, int * ); - -#if defined(astCLASS) /* Protected */ - -double astGetLTOffset_( AstTimeFrame *, int * ); -int astTestLTOffset_( AstTimeFrame *, int * ); -void astClearLTOffset_( AstTimeFrame *, int * ); -void astSetLTOffset_( AstTimeFrame *, double, int * ); - -double astGetTimeOrigin_( AstTimeFrame *, int * ); -int astTestTimeOrigin_( AstTimeFrame *, int * ); -void astClearTimeOrigin_( AstTimeFrame *, int * ); -void astSetTimeOrigin_( AstTimeFrame *, double, int * ); - -AstTimeScaleType astGetTimeScale_( AstTimeFrame *, int * ); -int astTestTimeScale_( AstTimeFrame *, int * ); -void astClearTimeScale_( AstTimeFrame *, int * ); -void astSetTimeScale_( AstTimeFrame *, AstTimeScaleType, int * ); - -AstTimeScaleType astGetAlignTimeScale_( AstTimeFrame *, int * ); -int astTestAlignTimeScale_( AstTimeFrame *, int * ); -void astClearAlignTimeScale_( AstTimeFrame *, int * ); -void astSetAlignTimeScale_( AstTimeFrame *, AstTimeScaleType, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckTimeFrame(this) astINVOKE_CHECK(TimeFrame,this,0) -#define astVerifyTimeFrame(this) astINVOKE_CHECK(TimeFrame,this,1) - -/* Test class membership. */ -#define astIsATimeFrame(this) astINVOKE_ISA(TimeFrame,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected */ -#define astTimeFrame astINVOKE(F,astTimeFrame_) -#else -#define astTimeFrame astINVOKE(F,astTimeFrameId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitTimeFrame(mem,size,init,vtab,name) \ -astINVOKE(O,astInitTimeFrame_(mem,size,init,vtab,name,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitTimeFrameVtab(vtab,name) astINVOKE(V,astInitTimeFrameVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadTimeFrame(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadTimeFrame_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) - -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ - -/* None. */ - -/* Interfaces to protected member functions. */ -/* ----------------------------------------- */ -/* Here we make use of astCheckTimeFrame to validate TimeFrame pointers - before use. This provides a contextual error report if a pointer to - the wrong sort of object is supplied. */ - -#define astCurrentTime(this) astINVOKE(V,astCurrentTime_(astCheckTimeFrame(this),STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ - -#define astGetTimeOrigin(this) astINVOKE(V,astGetTimeOrigin_(astCheckTimeFrame(this),STATUS_PTR)) -#define astTestTimeOrigin(this) astINVOKE(V,astTestTimeOrigin_(astCheckTimeFrame(this),STATUS_PTR)) -#define astClearTimeOrigin(this) astINVOKE(V,astClearTimeOrigin_(astCheckTimeFrame(this),STATUS_PTR)) -#define astSetTimeOrigin(this,value) astINVOKE(V,astSetTimeOrigin_(astCheckTimeFrame(this),value,STATUS_PTR)) - -#define astGetLTOffset(this) astINVOKE(V,astGetLTOffset_(astCheckTimeFrame(this),STATUS_PTR)) -#define astTestLTOffset(this) astINVOKE(V,astTestLTOffset_(astCheckTimeFrame(this),STATUS_PTR)) -#define astClearLTOffset(this) astINVOKE(V,astClearLTOffset_(astCheckTimeFrame(this),STATUS_PTR)) -#define astSetLTOffset(this,value) astINVOKE(V,astSetLTOffset_(astCheckTimeFrame(this),value,STATUS_PTR)) - -#define astGetTimeScale(this) astINVOKE(V,astGetTimeScale_(astCheckTimeFrame(this),STATUS_PTR)) -#define astTestTimeScale(this) astINVOKE(V,astTestTimeScale_(astCheckTimeFrame(this),STATUS_PTR)) -#define astClearTimeScale(this) astINVOKE(V,astClearTimeScale_(astCheckTimeFrame(this),STATUS_PTR)) -#define astSetTimeScale(this,value) astINVOKE(V,astSetTimeScale_(astCheckTimeFrame(this),value,STATUS_PTR)) - -#define astGetAlignTimeScale(this) astINVOKE(V,astGetAlignTimeScale_(astCheckTimeFrame(this),STATUS_PTR)) -#define astTestAlignTimeScale(this) astINVOKE(V,astTestAlignTimeScale_(astCheckTimeFrame(this),STATUS_PTR)) -#define astClearAlignTimeScale(this) astINVOKE(V,astClearAlignTimeScale_(astCheckTimeFrame(this),STATUS_PTR)) -#define astSetAlignTimeScale(this,value) astINVOKE(V,astSetAlignTimeScale_(astCheckTimeFrame(this),value,STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/timemap.c b/ast/timemap.c deleted file mode 100644 index 7eef60b..0000000 --- a/ast/timemap.c +++ /dev/null @@ -1,5330 +0,0 @@ -/* -*class++ -* Name: -* TimeMap - -* Purpose: -* Sequence of time coordinate conversions. - -* Constructor Function: -c astTimeMap (also see astTimeAdd) -f AST_TIMEMAP (also see AST_TIMEADD) - -* Description: -* A TimeMap is a specialised form of 1-dimensional Mapping which can be -* used to represent a sequence of conversions between standard time -* coordinate systems. -* -* When a TimeMap is first created, it simply performs a unit -c (null) Mapping. Using the astTimeAdd -f (null) Mapping. Using the AST_TIMEADD -c function, a series of coordinate conversion steps may then be -f routine, a series of coordinate conversion steps may then be -* added. This allows multi-step conversions between a variety of -* time coordinate systems to be assembled out of a set of building -* blocks. -* -* For details of the individual coordinate conversions available, -c see the description of the astTimeAdd function. -f see the description of the AST_TIMEADD routine. - -* Inheritance: -* The TimeMap class inherits from the Mapping class. - -* Attributes: -* The TimeMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c In addition to those functions applicable to all Mappings, the -c following function may also be applied to all TimeMaps: -f In addition to those routines applicable to all Mappings, the -f following routine may also be applied to all TimeMaps: -* -c - astTimeAdd: Add a time coordinate conversion to an TimeMap -f - AST_TIMEADD: Add a time coordinate conversion to an TimeMap - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* NG: Norman Gray (Starlink) -* DSB: David Berry (Starlink) - -* History: -* 5-Sep-2003 (NG): -* Original version (drawing heavily on specmap.c) -* 25-MAY-2005 (DSB): -* Extensive modifications to make it more AST-like. -* 10-AUG-2005 (DSB): -* Add 2006 leap second. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 10-MAY-2006 (DSB): -* Override astEqual. -* 15-OCT-2006 (DSB): -* Add conversions between UT1 and UTC (UTTOUTC and UTCTOUT). -* 3-APR-2008 (DSB): -* Only call memcpy if the source and destination pointers are -* different. -* 15-APR-2008 (DSB): -* Add missing "break;" statement to "case AST__LMSTTOGMST:" -* in Transform. -* 20-MAY-2008 (DSB): -* Add conversions between Local Time and UTC (LTTOUTC and UTCTOLT). -* 18-JUN-2009 (DSB): -* Add OBSALT to argument list for TTTOTDB and TDBTOTT. Change -* CLOCKLAT/LON to OBSLAT/LON for consistency with other classes. -* 1-SEP-2016 (DSB): -* Add 2017 January 1 leap second. -* 11-NOV-2016 (DSB): -* Add argument "narg" to astTimeAdd method. -* 5-APR-2017 (GSB): -* Add DTAI argument for TAITOUTC and UTCTOTAI. -* 28-APR-2017 (DSB): -* - Fix bug in MapMerge that prevented adjacent TAITOUTC and UTCTOTAI -* conversions cancelling out. -* - Add DTAI argument for TTTOTDB and TDBTOTT. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS TimeMap - -/* Codes to identify time coordinate conversions. */ -#define AST__TIME_NULL 0 /* Null value */ -#define AST__MJDTOMJD 1 /* MJD to MJD */ -#define AST__MJDTOJD 2 /* MJD to JD */ -#define AST__JDTOMJD 3 /* JD to MJD */ -#define AST__MJDTOBEP 4 /* MJD to Besselian epoch */ -#define AST__BEPTOMJD 5 /* Besselian epoch to MJD */ -#define AST__MJDTOJEP 6 /* MJD to Julian epoch */ -#define AST__JEPTOMJD 7 /* Julian epoch to MJD */ -#define AST__TAITOUTC 8 /* TAI to UTC */ -#define AST__UTCTOTAI 9 /* UTC to TAI */ -#define AST__TTTOTAI 10 /* TT to TAI */ -#define AST__TAITOTT 11 /* TAI to TT */ -#define AST__TDBTOTT 12 /* TDB to TT */ -#define AST__TTTOTDB 13 /* TT to TDB */ -#define AST__TCGTOTT 14 /* TCG to TT */ -#define AST__TTTOTCG 15 /* TT to TCG */ -#define AST__TCBTOTDB 16 /* TCB to TDB */ -#define AST__TDBTOTCB 17 /* TDB to TCB */ -#define AST__UTTOGMST 18 /* UT to GMST */ -#define AST__GMSTTOUT 19 /* GMST to UT1 */ -#define AST__GMSTTOLMST 20 /* GMST to LMST */ -#define AST__LMSTTOGMST 21 /* LMST to GMST */ -#define AST__LASTTOLMST 22 /* LAST to LMST */ -#define AST__LMSTTOLAST 23 /* LMST to LAST */ -#define AST__UTTOUTC 24 /* UT1 to UTC */ -#define AST__UTCTOUT 25 /* UTC to UT1 */ -#define AST__LTTOUTC 26 /* Local Time to UTC */ -#define AST__UTCTOLT 27 /* UTC to Local Time */ - -/* Maximum number of arguments required by a conversion. */ -#define MAX_ARGS 7 - -/* The alphabet (used for generating keywords for arguments). */ -#define ALPHABET "abcdefghijklmnopqrstuvwxyz" - -/* Angle conversion */ -#define PI 3.1415926535897932384626433832795028841971693993751 -#define D2PI (2*PI) -#define PIBY2 (PI/2.0) -#define D2R (PI/180.0) -#define R2D (180.0/PI) - -/* Other constants */ -#define SPD 86400 -#define LG 6.969290134E-10 -#define LB 1.55051976772E-8 -#define P0 6.55E-5 -#define TTOFF 32.184 - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "pal.h" /* SLALIB interface */ -#include "slamap.h" /* Spatial sla mappings */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ -#include "unitmap.h" /* Unit (null) Mappings */ -#include "timemap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double (* parent_rate)( AstMapping *, double *, int, int, int * ); - - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(TimeMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(TimeMap,Class_Init) -#define class_vtab astGLOBAL(TimeMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstTimeMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstTimeMap *astTimeMapId_( int, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *CvtString( int, const char **, int *, int *, const char *[ MAX_ARGS ], int **order, int * ); -static double Gmsta( double, double, int, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static double Rcc( double, double, double, double, double, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int CvtCode( const char *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void AddArgs( int, double *, int * ); -static void AddTimeCvt( AstTimeMap *, int, int, const double *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void TimeAdd( AstTimeMap *, const char *, int, const double[], int * ); - -static int GetObjSize( AstObject *, int * ); -/* Member functions. */ -/* ================= */ - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two TimeMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* TimeMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two TimeMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a TimeMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the TimeMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTimeMap *that; - AstTimeMap *this; - const char *argdesc[ MAX_ARGS ]; - const char *comment; - int i, j; - int nargs; - int nin; - int nout; - int result; - int szargs; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two TimeMap structures. */ - this = (AstTimeMap *) this_object; - that = (AstTimeMap *) that_object; - -/* Check the second object is a TimeMap. We know the first is a - TimeMap since we have arrived at this implementation of the virtual - function. */ - if( astIsATimeMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two TimeMaps differ, it may still be possible - for them to be equivalent. First compare the TimeMaps if their Invert - flags are the same. In this case all the attributes of the two TimeMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - if( this->ncvt == that->ncvt ) { - result = 1; - for( i = 0; i < this->ncvt && result; i++ ) { - if( this->cvttype[ i ] != that->cvttype[ i ] ) { - result = 0; - } else { - CvtString( this->cvttype[ i ], &comment, &nargs, - &szargs, argdesc, NULL, status ); - for( j = 0; j < nargs; j++ ) { - if( !astEQUAL( this->cvtargs[ i ][ j ], - that->cvtargs[ i ][ j ] ) ){ - result = 0; - break; - } - } - } - } - } - -/* If the Invert flags for the two TimeMaps differ, the attributes of the two - TimeMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a TimeMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* TimeMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied TimeMap, -* in bytes. - -* Parameters: -* this -* Pointer to the TimeMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTimeMap *this; /* Pointer to TimeMap structure */ - int result; /* Result value to return */ - int cvt; /* Loop counter for coordinate conversions */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the TimeMap structure. */ - this = (AstTimeMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - for ( cvt = 0; cvt < this->ncvt; cvt++ ) { - result += astTSizeOf( this->cvtargs[ cvt ] ); - } - - result += astTSizeOf( this->cvtargs ); - result += astTSizeOf( this->cvttype ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - - -static void AddArgs( int cvttype, double *cvtargs, int *status ) { -/* -* Name: -* AddArgs - -* Purpose: -* Set values for addition conversion arguments. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* void AddArgs( int cvttype, double *cvtargs, int *status ) - -* Class Membership: -* TimeMap member function. - -* Description: -* This function stores value for additional conversion arguments, -* based on the values supplied for the user arguments. - -* Parameters: -* cvttype -* The conversion type. -* cvtargs -* The arguments for the conversion. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double r; /* Distance from Earth axis (AU) */ - double z; /* Distance from plane of Earth equator (AU) */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Test for each valid code value in turn and assign the appropriate - extra values. */ - switch ( cvttype ) { - - case AST__MJDTOMJD: - cvtargs[ 2 ] = cvtargs[ 0 ] - cvtargs[ 1 ]; - break; - - case AST__MJDTOJD: - cvtargs[ 2 ] = cvtargs[ 0 ] - cvtargs[ 1 ] + 2400000.5; - break; - - case AST__JDTOMJD: - cvtargs[ 2 ] = cvtargs[ 0 ] - cvtargs[ 1 ] - 2400000.5; - break; - - case AST__MJDTOBEP: - cvtargs[ 2 ] = palEpb( cvtargs[ 0 ] ) - palEpb( 0.0 ) - cvtargs[ 1 ]; - cvtargs[ 3 ] = palEpb2d( cvtargs[ 1 ] ) - palEpb2d( 0.0 ) - cvtargs[ 0 ]; - break; - - case AST__BEPTOMJD: - cvtargs[ 2 ] = palEpb2d( cvtargs[ 0 ] ) - palEpb2d( 0.0 ) - cvtargs[ 1 ]; - cvtargs[ 3 ] = palEpb( cvtargs[ 1 ] ) - palEpb( 0.0 ) - cvtargs[ 0 ]; - break; - - case AST__MJDTOJEP: - cvtargs[ 2 ] = palEpj( cvtargs[ 0 ] ) - palEpj( 0.0 ) - cvtargs[ 1 ]; - cvtargs[ 3 ] = palEpj2d( cvtargs[ 1 ] ) - palEpj2d( 0.0 ) - cvtargs[ 0 ]; - break; - - case AST__JEPTOMJD: - cvtargs[ 2 ] = palEpj2d( cvtargs[ 0 ] ) - palEpj2d( 0.0 ) - cvtargs[ 1 ]; - cvtargs[ 3 ] = palEpj( cvtargs[ 1 ] ) - palEpj( 0.0 ) - cvtargs[ 0 ]; - break; - - case AST__TTTOTDB: - palGeoc( cvtargs[ 2 ], cvtargs[ 3 ], &r, &z ); - cvtargs[ 5 ] = 0.001*r*AST__AU; - cvtargs[ 6 ] = 0.001*z*AST__AU; - break; - - case AST__TDBTOTT: - palGeoc( cvtargs[ 2 ], cvtargs[ 3 ], &r, &z ); - cvtargs[ 5 ] = 0.001*r*AST__AU; - cvtargs[ 6 ] = 0.001*z*AST__AU; - break; - - case AST__TDBTOTCB: - cvtargs[ 1 ] = LB*( cvtargs[ 0 ] - (TTOFF/SPD) - - 43144.0 ) + P0/SPD; - break; - - case AST__TCBTOTDB: - cvtargs[ 1 ] = LB*( cvtargs[ 0 ] - (TTOFF/SPD) - - 43144.0 ) + P0/SPD; - break; - - case AST__TTTOTCG: - cvtargs[ 1 ] = LG*( cvtargs[ 0 ] - (TTOFF/SPD) - 43144.0 ); - break; - - case AST__TCGTOTT: - cvtargs[ 1 ] = LG*( cvtargs[ 0 ] - (TTOFF/SPD) - 43144.0 ); - break; - - } -} - -static void AddTimeCvt( AstTimeMap *this, int cvttype, int narg, - const double *args, int *status ) { -/* -* Name: -* AddTimeCvt - -* Purpose: -* Add a coordinate conversion step to an TimeMap. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* void AddTimeCvt( AstTimeMap *this, int cvttype, int narg, const -* double *args ) - -* Class Membership: -* TimeMap member function. - -* Description: -* This function allows one of the supported time coordinate -* conversions to be appended to a TimeMap. When a TimeMap is first -* created (using astTimeMap), it simply performs a unit mapping. By -* using AddTimeCvt repeatedly, a series of coordinate conversions may -* then be specified which the TimeMap will subsequently perform in -* sequence. This allows a complex coordinate conversion to be -* assembled out of the basic building blocks. The TimeMap will also -* perform the inverse coordinate conversion (applying the individual -* conversion steps in reverse) if required. - -* Parameters: -* this -* Pointer to the TimeMap. -* cvttype -* A code to identify which time coordinate conversion is to be -* appended. See the "Coordinate Conversions" section for details -* of those available. -* narg -* The number of argument values supplied in "args". -* args -* Pointer to an array of double containing the argument values -* required to fully specify the required coordinate -* conversion. The number of arguments depends on the conversion -* (see the "Coordinate Conversions" section for details). This -* value is ignored and may be NULL if no arguments are required. - -* Returned Value: -* void. - -* Coordinate Conversions: -* The following values may be supplied for the "cvttype" parameter -* in order to specify the coordinate conversion to be performed. -* The argument(s) required to fully specify each conversion are -* indicated in parentheses after each value, and described at the end -* of the list. Values for these should be given in the array pointed -* at by "args". -* -* AST__MJDTOMJD( MJDOFF1, MJDOFF2 ) -* Convert Modified Julian Date from one offset to another. -* AST__MJDTOJD( MJDOFF, JDOFF ) -* Convert Modified Julian Date to Julian Date. -* AST__JDTOMJD( JDOFF, MJDOFF ) -* Convert Julian Date to Modified Julian Date. -* AST__MJDTOBEP( MJDOFF, BEPOFF ) -* Convert Modified Julian Date to Besselian epoch. -* AST__BEPTOMJD( BEPOFF, MJDOFF ) -* Convert Besselian epoch to Modified Julian Date. -* AST__MJDTOJEP( MJDOFF, JEPOFF ) -* Convert Modified Julian Date to Julian epoch. -* AST__JEPTOMJD( JEPOFF, MJDOFF ) -* Convert Julian epoch to Modified Julian Date. -* AST__TAITOUTC( MJDOFF, DTAI ) -* Convert a TAI MJD to a UTC MJD. -* AST__UTCTOTAI( MJDOFF, DTAI ) -* Convert a UTC MJD to a TAI MJD. -* AST__TAITOTT( MJDOFF ) -* Convert a TAI MJD to a TT MJD. -* AST__TTTOTAI( MJDOFF ) -* Convert a TT MJD to a TAI MJD. -* AST__TTTOTDB( MJDOFF, OBSLON, OBSLAT, OBSALT, DTAI ) -* Convert a TT MJD to a TDB MJD. -* AST__TDBTOTT( MJDOFF, OBSLON, OBSLAT, OBSALT, DTAI ) -* Convert a TDB MJD to a TT MJD. -* AST__TTTOTCG( MJDOFF ) -* Convert a TT MJD to a TCG MJD. -* AST__TCGTOTT( MJDOFF ) -* Convert a TCG MJD to a TT MJD. -* AST__TDBTOTCB( MJDOFF) -* Convert a TAI MJD to a TCB MJD. -* AST__TCBTOTDB( MJDOFF) -* Convert a TCB MJD to a TDB MJD. -* AST__UTTOGMST( MJDOFF ) -* Convert a UT MJD to a GMST MJD. -* AST__GMSTTOUT( MJDOFF ) -* Convert a GMST MJD to a UT MJD. -* AST__GMSTTOLMST( MJDOFF, OBSLON, OBSLAT ) -* Convert a GMST MJD to a LMST MJD. -* AST__LMSTTOGMST( MJDOFF, OBSLON, OBSLAT ) -* Convert a LMST MJD to a GMST MJD. -* AST__LASTTOLMST( MJDOFF, OBSLON, OBSLAT ) -* Convert a LAST MJD to a LMST MJD. -* AST__LMSTTOLAST( MJDOFF, OBSLON, OBSLAT ) -* Convert a LMST MJD to a LAST MJD. -* AST__UTTOUTC( DUT1 ) -* Convert a UT1 MJD to a UTC MJD. -* AST__UTCTOUT( DUT1 ) -* Convert a UTC MJD to a UT1 MJD. -* AST__LTTOUTC( LTOFF ) -* Convert a local time MJD to a UTC MJD. -* AST__UTCTOLT( LTOFF ) -* Convert a UTC MJD to a local time MJD. -* -* The units for the values processed by the above conversions are as -* follows: -* -* - MJD, MJDOFF, JD, JDOFF: days -* - Julian epochs, BEPOFF: Tropical years -* - Besselian epochs, JEPOFF: Julian years -* -* The arguments used in the above conversions are as follows: -* -* - MJDOFF: Offset to be added to each MJD value -* - JDOFF: Offset to be added to each JD value -* - JEPOFF: Offset to be added to each Julian epoch value -* - BEPOFF: Offset to be added to each Besselian epoch value -* - OBSLON: Observer's longitude in radians (+ve westwards) -* - OBSLAT: Observer's geodetic latitude in radians (+ve northwards) -* - OBSALT: Observer's geodetic altitude in metres. -* - DTAI: The value of TAI-UTC (the value returned by astDat is used if -* DTAI is AST__BAD). -* - DUT1: The value of UT1-UTC -* - LTOFF: The offset between Local Time and UTC (in hours, positive -* for time zones east of Greenwich). - -* Notes: -* - The specified conversion is appended only if the TimeMap's -* Invert attribute is zero. If it is non-zero, this function -* effectively prefixes the inverse of the conversion specified -* instead. -*/ - -/* Local Variables: */ - const char *argdesc[ MAX_ARGS ]; /* Pointers to argument descriptions */ - const char *comment; /* Pointer to comment string */ - const char *cvt_string; /* Pointer to conversion type string */ - int i; /* Argument index */ - int nargs; /* Number of user-supplied arguments */ - int ncvt; /* Number of coordinate conversions */ - int szargs; /* Size of arguments array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the coordinate conversion type and obtain the number of - required user-supplied arguments, and the size of the array in which - to put the user-supplied arguments (the array may leave room after - the user-supplied arguments for various useful pre-calculated values). */ - cvt_string = CvtString( cvttype, &comment, &nargs, &szargs, argdesc, - NULL, status ); - -/* If the coordinate conversion type was not valid, then report an - error. */ - if ( astOK && !cvt_string ) { - astError( AST__TIMIN, "AddTimeCvt(%s): Invalid time coordinate " - "conversion type (%d).", status, astGetClass( this ), - (int) cvttype ); - } - -/* If the number of supplied arguments is incorrect, then report an error. */ - if ( astOK && nargs != narg ) { - astError( AST__TIMIN, "AddTimeCvt(%s): Invalid no. of arguments for time " - "coordinate conversion type %d - %d supplied, %d required.", - status, astGetClass( this ), (int) cvttype, narg, nargs ); - } - -/* Note the number of coordinate conversions already stored in the TimeMap. */ - if ( astOK ) { - ncvt = this->ncvt; - -/* Extend the array of conversion types and the array of pointers to - their argument lists to accommodate the new one. */ - this->cvttype = (int *) astGrow( this->cvttype, ncvt + 1, - sizeof( int ) ); - this->cvtargs = (double **) astGrow( this->cvtargs, ncvt + 1, - sizeof( double * ) ); - -/* Allocate memory for the argument list, putting a pointer to it into - the TimeMap. */ - this->cvtargs[ ncvt ] = astMalloc( sizeof( double ) * (size_t) szargs ); - -/* Store the conversion type and increment the conversion count. Also - copy the supplied arguments into the memory allocated above and put - suitable values in any elements of the argument array which are beyond - the end of the user-supplied arguments. These are intermediate values - calculated on the basis of the user-supplied arguments. */ - if ( astOK ) { - this->cvttype[ ncvt ] = cvttype; - for( i = 0; i < nargs; i++ ) this->cvtargs[ ncvt ][ i ] = args[ i ]; - for( i = nargs; i < szargs; i++ ) this->cvtargs[ ncvt ][ i ] = AST__BAD; - this->ncvt++; - -/* Test for each valid code value in turn and assign the appropriate extra values. */ - AddArgs( cvttype, this->cvtargs[ ncvt ], status ); - } - } -} - -static int CvtCode( const char *cvt_string, int *status ) { -/* -* Name: -* CvtCode - -* Purpose: -* Convert a conversion type from a string representation to a code value. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* int CvtCode( const char *cvt_string, int *status ) - -* Class Membership: -* TimeMap member function. - -* Description: -* This function accepts a string used to repersent one of the -* TimeMap coordinate conversions and converts it into a code -* value for internal use. - -* Parameters: -* cvt_string -* Pointer to a constant null-terminated string representing a -* time coordinate conversion. This is case sensitive and should -* contain no unnecessary white space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The equivalent conversion code. If the string was not -* recognised, the code AST__TIME_NULL is returned, without error. - -* Notes: -* - A value of AST__TIME_NULL will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - int result; /* Result value to return */ - -/* Initialise. */ - result = AST__TIME_NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Test the string against each recognised value in turn and assign - the result. */ - if ( astChrMatch( cvt_string, "MJDTOJD" ) ) { - result = AST__MJDTOJD; - - } else if ( astChrMatch( cvt_string, "MJDTOMJD" ) ) { - result = AST__MJDTOMJD; - - } else if ( astChrMatch( cvt_string, "JDTOMJD" ) ) { - result = AST__JDTOMJD; - - } else if ( astChrMatch( cvt_string, "JDTOMJD" ) ) { - result = AST__JDTOMJD; - - } else if ( astChrMatch( cvt_string, "MJDTOBEP" ) ) { - result = AST__MJDTOBEP; - - } else if ( astChrMatch( cvt_string, "BEPTOMJD" ) ) { - result = AST__BEPTOMJD; - - } else if ( astChrMatch( cvt_string, "MJDTOJEP" ) ) { - result = AST__MJDTOJEP; - - } else if ( astChrMatch( cvt_string, "JEPTOMJD" ) ) { - result = AST__JEPTOMJD; - - } else if ( astChrMatch( cvt_string, "TAITOUTC" ) ) { - result = AST__TAITOUTC; - - } else if ( astChrMatch( cvt_string, "UTCTOTAI" ) ) { - result = AST__UTCTOTAI; - - } else if ( astChrMatch( cvt_string, "TAITOTT" ) ) { - result = AST__TAITOTT; - - } else if ( astChrMatch( cvt_string, "TTTOTAI" ) ) { - result = AST__TTTOTAI; - - } else if ( astChrMatch( cvt_string, "TTTOTDB" ) ) { - result = AST__TTTOTDB; - - } else if ( astChrMatch( cvt_string, "TDBTOTT" ) ) { - result = AST__TDBTOTT; - - } else if ( astChrMatch( cvt_string, "TTTOTCG" ) ) { - result = AST__TTTOTCG; - - } else if ( astChrMatch( cvt_string, "TCGTOTT" ) ) { - result = AST__TCGTOTT; - - } else if ( astChrMatch( cvt_string, "TDBTOTCB" ) ) { - result = AST__TDBTOTCB; - - } else if ( astChrMatch( cvt_string, "TCBTOTDB" ) ) { - result = AST__TCBTOTDB; - - } else if ( astChrMatch( cvt_string, "UTTOGMST" ) ) { - result = AST__UTTOGMST; - - } else if ( astChrMatch( cvt_string, "GMSTTOUT" ) ) { - result = AST__GMSTTOUT; - - } else if ( astChrMatch( cvt_string, "GMSTTOLMST" ) ) { - result = AST__GMSTTOLMST; - - } else if ( astChrMatch( cvt_string, "LMSTTOGMST" ) ) { - result = AST__LMSTTOGMST; - - } else if ( astChrMatch( cvt_string, "LASTTOLMST" ) ) { - result = AST__LASTTOLMST; - - } else if ( astChrMatch( cvt_string, "LMSTTOLAST" ) ) { - result = AST__LMSTTOLAST; - - } else if ( astChrMatch( cvt_string, "UTTOUTC" ) ) { - result = AST__UTTOUTC; - - } else if ( astChrMatch( cvt_string, "UTCTOUT" ) ) { - result = AST__UTCTOUT; - - } else if ( astChrMatch( cvt_string, "LTTOUTC" ) ) { - result = AST__LTTOUTC; - - } else if ( astChrMatch( cvt_string, "UTCTOLT" ) ) { - result = AST__UTCTOLT; - } - -/* Return the result. */ - return result; -} - -static const char *CvtString( int cvt_code, const char **comment, - int *nargs, int *szargs, - const char *arg[ MAX_ARGS ], - int **order, int *status ) { -/* -* Name: -* CvtString - -* Purpose: -* Convert a conversion type from a code value to a string representation. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* const char *CvtString( int cvt_code, const char **comment, int *nargs, -* int *szargs, const char *arg[ MAX_ARGS ], -* int **order, int *status ) - -* Class Membership: -* TimeMap member function. - -* Description: -* This function accepts a code value used to represent one of the -* TimeMap coordinate conversions and converts it into an -* equivalent string representation. It also returns a descriptive -* comment and information about the arguments required in order to -* perform the conversion. - -* Parameters: -* cvt_code -* The conversion code. -* comment -* Address of a location to return a pointer to a constant -* null-terminated string containing a description of the -* conversion. -* nargs -* Address of an int in which to return the number of arguments -* required from the user in order to perform the conversion (may -* be zero). -* szargs -* Address of an int in which to return the number of arguments -* associated with the conversion. This may be bigger than "nargs" -* if the conversion can pre-calculate useful values on the basis -* of the user-supplied values. Such precalculated values are -* stored after the last user-supplied argument. -* arg -* An array in which to return a pointer to a constant -* null-terminated string for each argument (above) containing a -* description of what each argument represents. This includes both -* user-supplied arguments and pre-calculated values. -* order -* Ignored if NULL. If not NULL, it should be an address at which -* to return a pointer to a dynamically allocated int array (the -* returned array should be freed using astFree when no longer -* needed). The returned array will have "*szargs" elements. The -* index into the array is the index of the argument within the -* external representation of a TimeMap as produced by the Dump -* function. The value stored in each element is the index of -* the argument within the internal argument list. If there is -* no difference between the internal and external order of the -* arguments, a NULL pointer will be returned instead of a pointer -* to an int array. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string representation of -* the conversion code value supplied. If the code supplied is not -* valid, a NULL pointer will be returned, without error. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the global error status set, or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Result pointer to return */ - -/* Initialise the returned values. */ - *comment = NULL; - *nargs = 0; - result = NULL; - if( order ) *order = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Test for each valid code value in turn and assign the appropriate - return values. */ - switch ( cvt_code ) { - - case AST__MJDTOMJD: - *comment = "Convert MJD between offsets"; - result = "MJDTOMJD"; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "Input MJD offset"; - arg[ 1 ] = "Output MJD offset"; - arg[ 2 ] = "Combined offset"; - break; - - case AST__MJDTOJD: - *comment = "Convert MJD to JD"; - result = "MJDTOJD"; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "JD offset"; - arg[ 2 ] = "Combined offset"; - break; - - case AST__JDTOMJD: - *comment = "Convert JD to MJD"; - result = "JDTOMJD"; - *nargs = 2; - *szargs = 3; - arg[ 0 ] = "JD offset"; - arg[ 1 ] = "MJD offset"; - arg[ 2 ] = "Combined offset"; - break; - - case AST__MJDTOBEP: - *comment = "Convert MJD to Besselian epoch"; - result = "MJDTOBEP"; - *nargs = 2; - *szargs = 4; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "Besselian epoch offset"; - arg[ 2 ] = "Combined forward offset"; - arg[ 3 ] = "Combined inverse offset"; - break; - - case AST__BEPTOMJD: - *comment = "Convert Besselian epoch to MJD"; - result = "BEPTOMJD"; - *nargs = 2; - *szargs = 4; - arg[ 0 ] = "Besselian epoch offset"; - arg[ 1 ] = "MJD offset"; - arg[ 2 ] = "Combined forward offset"; - arg[ 3 ] = "Combined inverse offset"; - break; - - case AST__MJDTOJEP: - *comment = "Convert MJD to Julian epoch"; - result = "MJDTOJEP"; - *nargs = 2; - *szargs = 4; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "Julian epoch offset"; - arg[ 2 ] = "Combined forward offset"; - arg[ 3 ] = "Combined inverse offset"; - break; - - case AST__JEPTOMJD: - *comment = "Convert Julian epoch to MJD"; - result = "JEPTOMJD"; - *nargs = 2; - *szargs = 4; - arg[ 0 ] = "Julian epoch offset"; - arg[ 1 ] = "MJD offset"; - arg[ 2 ] = "Combined forward offset"; - arg[ 3 ] = "Combined inverse offset"; - break; - - case AST__TAITOUTC: - *comment = "Convert TAI to UTC"; - result = "TAITOUTC"; - *nargs = 2; - *szargs = 2; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "DTAI"; - break; - - case AST__UTCTOTAI: - *comment = "Convert UTC to TAI"; - result = "UTCTOTAI"; - *nargs = 2; - *szargs = 2; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "DTAI"; - break; - - case AST__TAITOTT: - *comment = "Convert TAI to TT"; - result = "TAITOTT"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "MJD offset"; - break; - - case AST__TTTOTAI: - *comment = "Convert TT to TAI"; - result = "TTTOTAI"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "MJD offset"; - break; - - case AST__TTTOTDB: - *comment = "Convert TT to TDB"; - result = "TTTOTDB"; - *nargs = 5; - *szargs = 7; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "Observer longitude"; - arg[ 2 ] = "Observer latitude"; - arg[ 3 ] = "Observer altitude"; - arg[ 4 ] = "DTAI"; - arg[ 5 ] = "Distance from earth spin axis"; - arg[ 6 ] = "Distance north of equatorial plane"; - -/* For backward compatibility, the order of arguments in the external - representation is different to the internal order. This became - necessary when the DTAI user-supplied argument was added. New user - supplied arguments need to be before the calculated arguments in - the internal list, but need to be added to the end of the external - argument list. This means new TimeMaps read by old software will ignore - the new user supplied argument. It also means that old TimeMaps read by - new software will use default values for the missing user supplied - argument. */ - if( order ) { - *order = astMalloc( 7*sizeof( **order ) ); - if( astOK ) { - (*order)[ 0 ] = 0; - (*order)[ 1 ] = 1; - (*order)[ 2 ] = 2; - (*order)[ 3 ] = 3; - (*order)[ 4 ] = 5; - (*order)[ 5 ] = 6; - (*order)[ 6 ] = 4; - } - } - break; - - case AST__TDBTOTT: - *comment = "Convert TDB to TT"; - result = "TDBTOTT"; - *nargs = 5; - *szargs = 7; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "Observer longitude"; - arg[ 2 ] = "Observer latitude"; - arg[ 3 ] = "Observer altitude"; - arg[ 4 ] = "DTAI"; - arg[ 5 ] = "Distance from earth spin axis"; - arg[ 6 ] = "Distance north of equatorial plane"; - if( order ) { - *order = astMalloc( 7*sizeof( **order ) ); - if( astOK ) { - (*order)[ 0 ] = 0; - (*order)[ 1 ] = 1; - (*order)[ 2 ] = 2; - (*order)[ 3 ] = 3; - (*order)[ 4 ] = 5; - (*order)[ 5 ] = 6; - (*order)[ 6 ] = 4; - } - } - break; - - case AST__TTTOTCG: - *comment = "Convert TT to TCG"; - result = "TTTOTCG"; - *nargs = 1; - *szargs = 2; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "TCG offset"; - break; - - case AST__TCGTOTT: - *comment = "Convert TCG to TT"; - result = "TCGTOTT"; - *nargs = 1; - *szargs = 2; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "TCG offset"; - break; - - case AST__TDBTOTCB: - *comment = "Convert TDB to TCB"; - result = "TDBTOTCB"; - *nargs = 1; - *szargs = 2; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "TCB offset"; - break; - - case AST__TCBTOTDB: - *comment = "Convert TCB to TDB"; - result = "TCBTOTDB"; - *nargs = 1; - *szargs = 2; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "TCB offset"; - break; - - case AST__UTTOGMST: - *comment = "Convert UT to GMST"; - result = "UTTOGMST"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "MJD offset"; - break; - - case AST__GMSTTOUT: - *comment = "Convert GMST to UT"; - result = "GMSTTOUT"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "MJD offset"; - break; - - case AST__GMSTTOLMST: - *comment = "Convert GMST to LMST"; - result = "GMSTTOLMST"; - *nargs = 3; - *szargs = 3; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "Observer longitude"; - arg[ 2 ] = "Observer latitude"; - break; - - case AST__LMSTTOGMST: - *comment = "Convert LMST to GMST"; - result = "LMSTTOGMST"; - *nargs = 3; - *szargs = 3; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "Observer longitude"; - arg[ 2 ] = "Observer latitude"; - break; - - case AST__LASTTOLMST: - *comment = "Convert LAST to LMST"; - result = "LASTTOLMST"; - *nargs = 3; - *szargs = 3; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "Observer longitude"; - arg[ 2 ] = "Observer latitude"; - break; - - case AST__LMSTTOLAST: - *comment = "Convert LMST to LAST"; - result = "LMSTTOLAST"; - *nargs = 3; - *szargs = 3; - arg[ 0 ] = "MJD offset"; - arg[ 1 ] = "Observer longitude"; - arg[ 2 ] = "Observer latitude"; - break; - - case AST__UTTOUTC: - *comment = "Convert UT1 to UTC"; - result = "UTTOUTC"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "DUT1"; - break; - - case AST__UTCTOUT: - *comment = "Convert UTC to UT1"; - result = "UTCTOUT"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "DUT1"; - break; - - case AST__LTTOUTC: - *comment = "Convert Local Time to UTC"; - result = "LTTOUTC"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "LTOFF"; - break; - - case AST__UTCTOLT: - *comment = "Convert UTC to Local Time"; - result = "UTCTOLT"; - *nargs = 1; - *szargs = 1; - arg[ 0 ] = "LTOFF"; - break; - } - -/* Return the result. */ - return result; -} - -double astDat_( double in, int forward, int *status ){ -/* -*+ -* Name: -* Dat - -* Purpose: -* Convert between UTC and TAI. - -* Type: -* Protected function. - -* Synopsis: -* #include "timemap.h" -* double astDat( double in, int forward ) - -* Class Membership: -* TimeMap member function - -* Description: -* This function returns the difference between Coordinated Universal Time -* (UTC) and International Atomic Time (TAI), at a given epoch. - -* Parameters: -* in -* UTC date or TAI time (as selected by "forward"), as an absolute -* MJD. -* forward -* If non-zero, "in" should be a UTC value, and the returned value -* is TAI-UTC. If zero, "in" should be a TAI value, and the returned -* value is UTC-TAI. - -* Returned Value: -* Either UTC-TAI or TAI-UTC (as indicated by "forward") in units of -* seconds. - -* Notes: -* - The UTC is specified to be a date rather than a time to indicate -* that care needs to be taken not to specify an instant which lies -* within a leap second. Though in most cases UTC can include the -* fractional part, correct behaviour on the day of a leap second -* can only be guaranteed up to the end of the second 23:59:59. -* - For epochs from 1961 January 1 onwards, the expressions from the -* file ftp://maia.usno.navy.mil/ser7/tai-utc.dat are used. -* - The 5ms time step at 1961 January 1 is taken from 2.58.1 (p87) of -* the 1992 Explanatory Supplement. -* - UTC began at 1960 January 1.0 (JD 2436934.5) and it is improper -* to call the routine with an earlier epoch. However, if this -* is attempted, the TAI-UTC expression for the year 1960 is used. - -* Implementation Details: -* - This function is based on SLA_DAT by P.T.Wallace. -* - This routine must be updated on each occasion that a leap second is -* announced -* - Latest leap second: 2017 January 1 - -*- -*/ - -/* Local Variables: */ - double result; - -/* Initialise the returned value. */ - if( in == AST__BAD ) return AST__BAD; - -/* First do TAI-UTC at a given UTC - ------------------------------- */ - if( forward ) { - -/* 2017 January 1 */ - if ( in >= 57754.0 ) { - result = 37.0; - -/* 2015 July 1 */ - } else if ( in >= 57204.0 ) { - result = 36.0; - -/* 2012 July 1 */ - } else if ( in >= 56109.0 ) { - result = 35.0; - -/* 2009 January 1 */ - } else if ( in >= 54832.0 ) { - result = 34.0; - -/* 2006 January 1 */ - } else if( in >= 53736.0 ) { - result = 33.0; - -/* 1999 January 1 */ - } else if( in >= 51179.0 ){ - result = 32.0; - -/* 1997 July 1 */ - } else if( in >= 50630.0 ){ - result = 31.0; - -/* 1996 January 1 */ - } else if( in >= 50083.0 ){ - result = 30.0; - -/* 1994 July 1 */ - } else if( in >= 49534.0 ){ - result = 29.0; - -/* 1993 July 1 */ - } else if( in >= 49169.0 ){ - result = 28.0; - -/* 1992 July 1 */ - } else if( in >= 48804.0 ){ - result = 27.0; - -/* 1991 January 1 */ - } else if( in >= 48257.0 ){ - result = 26.0; - -/* 1990 January 1 */ - } else if( in >= 47892.0 ){ - result = 25.0; - -/* 1988 January 1 */ - } else if( in >= 47161.0 ){ - result = 24.0; - -/* 1985 July 1 */ - } else if( in >= 46247.0 ){ - result = 23.0; - -/* 1983 July 1 */ - } else if( in >= 45516.0 ){ - result = 22.0; - -/* 1982 July 1 */ - } else if( in >= 45151.0 ){ - result = 21.0; - -/* 1981 July 1 */ - } else if( in >= 44786.0 ){ - result = 20.0; - -/* 1980 January 1 */ - } else if( in >= 44239.0 ){ - result = 19.0; - -/* 1979 January 1 */ - } else if( in >= 43874.0 ){ - result = 18.0; - -/* 1978 January 1 */ - } else if( in >= 43509.0 ){ - result = 17.0; - -/* 1977 January 1 */ - } else if( in >= 43144.0 ){ - result = 16.0; - -/* 1976 January 1 */ - } else if( in >= 42778.0 ){ - result = 15.0; - -/* 1975 January 1 */ - } else if( in >= 42413.0 ){ - result = 14.0; - -/* 1974 January 1 */ - } else if( in >= 42048.0 ){ - result = 13.0; - -/* 1973 January 1 */ - } else if( in >= 41683.0 ){ - result = 12.0; - -/* 1972 July 1 */ - } else if( in >= 41499.0 ){ - result = 11.0; - -/* 1972 January 1 */ - } else if( in >= 41317.0 ){ - result = 10.0; - -/* 1968 February 1 */ - } else if( in >= 39887.0 ){ - result = 4.2131700 + ( in - 39126.0 )*0.002592; - -/* 1966 January 1 */ - } else if( in >= 39126.0 ){ - result = 4.3131700 + ( in - 39126.0 )*0.002592; - -/* 1965 September 1 */ - } else if( in >= 39004.0 ){ - result = 3.8401300 + ( in - 38761.0 )*0.001296; - -/* 1965 July 1 */ - } else if( in >= 38942.0 ){ - result = 3.7401300 + ( in - 38761.0 )*0.001296; - -/* 1965 March 1 */ - } else if( in >= 38820.0 ){ - result = 3.6401300 + ( in - 38761.0 )*0.001296; - -/* 1965 January 1 */ - } else if( in >= 38761.0 ){ - result = 3.5401300 + ( in - 38761.0 )*0.001296; - -/* 1964 September 1 */ - } else if( in >= 38639.0 ){ - result = 3.4401300 + ( in - 38761.0 )*0.001296; - -/* 1964 April 1 */ - } else if( in >= 38486.0 ){ - result = 3.3401300 + ( in - 38761.0 )*0.001296; - -/* 1964 January 1 */ - } else if( in >= 38395.0 ){ - result = 3.2401300 + ( in - 38761.0 )*0.001296; - -/* 1963 November 1 */ - } else if( in >= 38334.0 ){ - result = 1.9458580 + ( in - 37665.0 )*0.0011232; - -/* 1962 January 1 */ - } else if( in >= 37665.0 ){ - result = 1.8458580 + ( in - 37665.0 )*0.0011232; - -/* 1961 August 1 */ - } else if( in >= 37512.0 ){ - result = 1.3728180 + ( in - 37300.0 )*0.001296; - -/* 1961 January 1 */ - } else if( in >= 37300.0 ){ - result = 1.4228180 + ( in - 37300.0 )*0.001296; - -/* Before that */ - } else { - result = 1.4178180 + ( in - 37300.0 )*0.001296; - } - -/* Now do UTC-TAI at a given TAI. - ------------------------------ */ - } else { - - -/* 2017 January 1 */ - if ( in >= 57754.0 + 37.0/SPD ) { - result = -37.0; - -/* 2015 July 1 */ - } else if ( in >= 57204.0 + 36.0/SPD ) { - result = -36.0; - -/* 2012 July 1 */ - } else if( in >= 56109.0 + 35.0/SPD ) { - result = -35.0; - -/* 2009 January 1 */ - } else if( in >= 54832.0 + 34.0/SPD ) { - result = -34.0; - -/* 2006 January 1 */ - } else if( in >= 53736.0 + 33.0/SPD ){ - result = -33.0; - -/* 1999 January 1 */ - } else if( in >= 51179.0 + 32.0/SPD ){ - result = -32.0; - -/* 1997 July 1 */ - } else if( in >= 50630.0 + 31.0/SPD ){ - result = -31.0; - -/* 1996 January 1 */ - } else if( in >= 50083.0 + 30.0/SPD ){ - result = -30.0; - -/* 1994 July 1 */ - } else if( in >= 49534.0 + 29.0/SPD ){ - result = -29.0; - -/* 1993 July 1 */ - } else if( in >= 49169.0 + 28.0/SPD ){ - result = -28.0; - -/* 1992 July 1 */ - } else if( in >= 48804.0 + 27.0/SPD ){ - result = -27.0; - -/* 1991 January 1 */ - } else if( in >= 48257.0 + 26.0/SPD ){ - result = -26.0; - -/* 1990 January 1 */ - } else if( in >= 47892.0 + 25.0/SPD ){ - result = -25.0; - -/* 1988 January 1 */ - } else if( in >= 47161.0 + 24.0/SPD ){ - result = -24.0; - -/* 1985 July 1 */ - } else if( in >= 46247.0 + 23.0/SPD ){ - result = -23.0; - -/* 1983 July 1 */ - } else if( in >= 45516.0 + 22.0/SPD ){ - result = -22.0; - -/* 1982 July 1 */ - } else if( in >= 45151.0 + 21.0/SPD ){ - result = -21.0; - -/* 1981 July 1 */ - } else if( in >= 44786.0 + 20.0/SPD ){ - result = -20.0; - -/* 1980 January 1 */ - } else if( in >= 44239.0 + 19.0/SPD ){ - result = -19.0; - -/* 1979 January 1 */ - } else if( in >= 43874.0 + 18.0/SPD ){ - result = -18.0; - -/* 1978 January 1 */ - } else if( in >= 43509.0 + 17.0/SPD ){ - result = -17.0; - -/* 1977 January 1 */ - } else if( in >= 43144.0 + 16.0/SPD ){ - result = -16.0; - -/* 1976 January 1 */ - } else if( in >= 42778.0 + 15.0/SPD ){ - result = -15.0; - -/* 1975 January 1 */ - } else if( in >= 42413.0 + 14.0/SPD ){ - result = -14.0; - -/* 1974 January 1 */ - } else if( in >= 42048.0 + 13.0/SPD ){ - result = -13.0; - -/* 1973 January 1 */ - } else if( in >= 41683.0 + 12.0/SPD ){ - result = -12.0; - -/* 1972 July 1 */ - } else if( in >= 41499.0 + 11.0/SPD ){ - result = -11.0; - -/* 1972 January 1 */ - } else if( in >= 41317.0 + 10.0/SPD ){ - result = -10.0; - -/* 1968 February 1 */ - } else if( in >= 39887.0 + ( 4.2131700 - + ( 39887.0 - 39126.0 )*0.002592 )/SPD ){ - result = -( 4.2131700 + ( in - 39126.0 )*0.002592 )/1.02592; - -/* 1966 January 1 */ - } else if( in >= 39126.0 + ( 4.3131700 - + ( 39126.0 - 39126.0 )*0.002592 )/SPD ){ - result = -( 4.2131700 + ( in - 39126.0 )*0.002592 )/1.02592; - -/* 1965 September 1 */ - } else if( in >= 39004.0 + ( 3.8401300 - + ( 39004.0 - 38761.0 )*0.001296 )/SPD ){ - result = -( 3.8401300 + ( in - 38761.0 )*0.001296 )/1.001296; - -/* 1965 July 1 */ - } else if( in >= 38942.0 + ( 3.7401300 - + ( 38942.0 - 38761.0 )*0.001296 )/SPD ){ - result = -( 3.7401300 + ( in - 38761.0 )*0.001296 )/1.01296; - -/* 1965 March 1 */ - } else if( in >= 38820.0 + ( 3.6401300 - + ( 38820.0 - 38761.0 )*0.001296 )/SPD ){ - result = -( 3.6401300 + ( in - 38761.0 )*0.001296 )/1.001296; - -/* 1965 January 1 */ - } else if( in >= 38761.0 + ( 3.5401300 - + ( 38761.0 - 38761.0 )*0.001296 )/SPD ){ - result = -( 3.5401300 + ( in - 38761.0 )*0.001296 )/1.001296; - -/* 1964 September 1 */ - } else if( in >= 38639.0 + ( 3.4401300 - + ( 38639.0 - 38761.0 )*0.001296 )/SPD ){ - result = -( 3.4401300 + ( in - 38761.0 )*0.001296 )/1.001296; - -/* 1964 April 1 */ - } else if( in >= 38486.0 + ( 3.3401300 - + ( 38486.0 - 38761.0 )*0.001296 )/SPD ){ - result = -( 3.3401300 + ( in - 38761.0 )*0.001296 )/1.001296; - -/* 1964 January 1 */ - } else if( in >= 38395.0 + ( 3.2401300 - + ( 38395.0 - 38761.0 )*0.001296 )/SPD ){ - result = -( 3.2401300 + ( in - 38761.0 )*0.001296 )/1.001296; - -/* 1963 November 1 */ - } else if( in >= 38334.0 + ( 1.9458580 - + ( 38334.0 - 37665.0 )*0.0011232 )/SPD ){ - result = -( 1.9458580 + ( in - 37665.0 )*0.0011232 )/1.0011232; - -/* 1962 January 1 */ - } else if( in >= 37665.0 + ( 1.8458580 - + ( 37665.0 - 37665.0 )*0.0011232 )/SPD ){ - result = -( 1.8458580 + ( in - 37665.0 )*0.0011232 )/1.0011232; - -/* 1961 August 1 */ - } else if( in >= 37512.0 + ( 1.3728180 - + ( 37512.0 - 37300.0 )*0.001296 )/SPD ){ - result = -( 1.3728180 + ( in - 37300.0 )*0.001296 )/1.001296; - -/* 1961 January 1 */ - } else if( in >= 37300.0 + ( 1.4228180 - + ( 37300.0 - 37300.0 )*0.001296 )/SPD ){ - result = -( 1.4228180 + ( in - 37300.0 )*0.001296 )/1.001296; - -/* Before that */ - } else { - result = -( 1.4178180 + ( in - 37300.0 )*0.001296 )/1.001296; - } - } - -/* Return the result */ - return result; -} - -static double Gmsta( double in, double off, int forward, int *status ){ -/* -* Name: -* Gmsta - -* Purpose: -* Convert between Universal Time (UT) and Greenwich Mean Sidereal Time (GMST). - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* double Gmsta( double in, double off, int forward, int *status ){ - -* Class Membership: -* TimeMap member function - -* Description: -* This functions converts between UT and GMST. Both timescales are -* represented by an MJD, rather than as an angle (as is done by SLALIB) -* in order to facilitate conversions from GMST to UT1. This means -* that whole days are retained. - -* Parameters: -* in -* The time to convert, represented as an offset in days from the MJD -* zero-point specified by "off". The time is either UT1 or GMST, as -* selected by "forward"). -* off -* The MJD value corresponding to a value of 0.0 for "in". -* forward -* If non-zero, "in" should be a UT1 value, and the returned value -* is GMST. If zero, "in" should be a GMST value, and the returned -* value is UT1. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* An offset in days from the MJD given by "off". When the returned -* value is added to "off" the sum is a GMST MJD (if "forward" is -* non-zero), or a UT1 MJD (if "forward" is zero), - -* Notes: -* - This function is based on SLA_GMST by P.T.Wallace. - -*/ - -/* Local Variables: */ - double dgdu; - double g; - double result; - double t; - double utl; - int nit; - -/* Initialise the returned value. */ - if( in == AST__BAD || off == AST__BAD ) return AST__BAD; - -/* First deal with UT1 -> GMST - --------------------------- */ - if( forward ) { - -/* Julian centuries since J2000. */ - t = ( off + in - 51544.5 )/36525.0; - -/* GMST at this UT1. */ - result = in + ( 24110.54841 + ( 8640184.812866 + ( 0.093104 - - 6.2E-6*t )*t )*t )/86400.0; - -/* Now deal with GMST -> UT1 - ----------------------- */ - } else { - -/* Form an initial guess at the UT1 value using the inverse of a linear - approximation to the UT1->GMST equation. */ - result = 0.996997348638869*in + 154.49194372222 - 0.00300265136113098*off; - -/* Loop round improving the guess, until the guess stops changing, or 10 - iterations have been performed. */ - utl = AST__BAD; - nit = 0; - while( result != utl && nit++ < 10 ){ - -/* Calculate the GMST at the current UT1 guess. */ - t = ( off + result - 51544.5 )/36525.0; - g = result + ( 24110.54841 + ( 8640184.812866 + ( 0.093104 - - 6.2E-6*t )*t )*t )/86400.0; - -/* Calculate the rate of change of GMST with respect to UT1 at the current - UT1 guess. */ - dgdu = 1.0 + ( 8640184.812866 + - ( 0.186208 - 12.4E-6*t )*t)/(36525.0*86400.0); - -/* Improve the UT1 guess. */ - utl = result; - result = result - ( g - in )/dgdu; - } - } - -/* Return the result */ - return result; -} - -void astInitTimeMapVtab_( AstTimeMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitTimeMapVtab - -* Purpose: -* Initialise a virtual function table for a TimeMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "timemap.h" -* void astInitTimeMapVtab( AstTimeMapVtab *vtab, const char *name ) - -* Class Membership: -* TimeMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the TimeMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsATimeMap) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->TimeAdd = TimeAdd; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_rate = mapping->Rate; - mapping->Rate = Rate; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the copy constructor, destructor and class dump - function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "TimeMap", - "Conversion between time coordinate systems" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a TimeMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* TimeMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated TimeMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated TimeMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated TimeMap which is to be merged with -* its neighbours. This should be a cloned copy of the TimeMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* TimeMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated TimeMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *new; /* Pointer to replacement Mapping */ - AstTimeMap *timemap; /* Pointer to TimeMap */ - const char *argdesc[ MAX_ARGS ]; /* Argument descriptions (junk) */ - const char *class; /* Pointer to Mapping class string */ - const char *comment; /* Pointer to comment string (junk) */ - double (*cvtargs)[ MAX_ARGS ]; /* Pointer to argument arrays */ - double tmp; /* Temporary storage */ - int *cvttype; /* Pointer to transformation type codes */ - int *narg; /* Pointer to argument count */ - int *szarg; /* Pointer to argument array size */ - int done; /* Finished (no further simplification)? */ - int iarg; /* Loop counter for arguments */ - int icvt1; /* Loop initial value */ - int icvt2; /* Loop final value */ - int icvt; /* Loop counter for transformation steps */ - int ikeep; /* Index to store step being kept */ - int imap1; /* Index of first TimeMap to merge */ - int imap2; /* Index of last TimeMap to merge */ - int imap; /* Loop counter for Mappings */ - int inc; /* Increment for transformation step loop */ - int invert; /* TimeMap applied in inverse direction? */ - int istep; /* Loop counter for transformation steps */ - int keep; /* Keep transformation step? */ - int ngone; /* Number of Mappings eliminated */ - int nstep0; /* Original number of transformation steps */ - int nstep; /* Total number of transformation steps */ - int result; /* Result value to return */ - int simpler; /* Simplification possible? */ - int unit; /* Replacement Mapping is a UnitMap? */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* TimeMaps can only be merged if they are in series (or if there is - only one Mapping present, in which case it makes no difference), so - do nothing if they are not. */ - if ( series || ( *nmap == 1 ) ) { - -/* Initialise the number of transformation steps to be merged to equal - the number in the nominated TimeMap. */ - nstep = ( (AstTimeMap *) ( *map_list )[ where ] )->ncvt; - -/* Search adjacent lower-numbered Mappings until one is found which is - not a TimeMap. Accumulate the number of transformation steps involved in - any TimeMaps found. */ - imap1 = where; - while ( ( imap1 - 1 >= 0 ) && astOK ) { - class = astGetClass( ( *map_list )[ imap1 - 1 ] ); - if ( !astOK || strcmp( class, "TimeMap" ) ) break; - nstep += ( (AstTimeMap *) ( *map_list )[ imap1 - 1 ] )->ncvt; - imap1--; - } - -/* Similarly search adjacent higher-numbered Mappings. */ - imap2 = where; - while ( ( imap2 + 1 < *nmap ) && astOK ) { - class = astGetClass( ( *map_list )[ imap2 + 1 ] ); - if ( !astOK || strcmp( class, "TimeMap" ) ) break; - nstep += ( (AstTimeMap *) ( *map_list )[ imap2 + 1 ] )->ncvt; - imap2++; - } - -/* Remember the initial number of transformation steps. */ - nstep0 = nstep; - -/* Allocate memory for accumulating a list of all the transformation - steps involved in all the TimeMaps found. */ - cvttype = astMalloc( sizeof( int ) * (size_t) nstep ); - cvtargs = astMalloc( sizeof( double[ MAX_ARGS ] ) * (size_t) nstep ); - szarg = astMalloc( sizeof( int ) * (size_t) nstep ); - narg = astMalloc( sizeof( int ) * (size_t) nstep ); - -/* Loop to obtain the transformation data for each TimeMap being merged. */ - nstep = 0; - for ( imap = imap1; astOK && ( imap <= imap2 ); imap++ ) { - -/* Obtain a pointer to the TimeMap and note if it is being applied in - its inverse direction. */ - timemap = (AstTimeMap *) ( *map_list )[ imap ]; - invert = ( *invert_list )[ imap ]; - -/* Set up loop limits and an increment to scan the transformation - steps in each TimeMap in either the forward or reverse direction, as - dictated by the associated "invert" value. */ - icvt1 = invert ? timemap->ncvt - 1 : 0; - icvt2 = invert ? -1 : timemap->ncvt; - inc = invert ? -1 : 1; - -/* Loop through each transformation step in the TimeMap. */ - for ( icvt = icvt1; icvt != icvt2; icvt += inc ) { - -/* Store the transformation type code and use "CvtString" to determine - the associated number of arguments. Then store these arguments. */ - cvttype[ nstep ] = timemap->cvttype[ icvt ]; - (void) CvtString( cvttype[ nstep ], &comment, - narg + nstep, szarg + nstep, argdesc, - NULL, status ); - if ( !astOK ) break; - for ( iarg = 0; iarg < szarg[ nstep ]; iarg++ ) { - cvtargs[ nstep ][ iarg ] = timemap->cvtargs[ icvt ][ iarg ]; - } - -/* If the TimeMap is inverted, we must not only accumulate its - transformation steps in reverse, but also apply them in - reverse. For some steps this means changing arguments, for some it - means changing the transformation type code to a complementary - value, and for others it means both. Define macros to perform each - of the required changes. */ - -/* Macro to exchange a transformation type code for its inverse (and - vice versa). */ -#define SWAP_CODES( code1, code2 ) \ - if ( cvttype[ nstep ] == code1 ) { \ - cvttype[ nstep ] = code2; \ - AddArgs( code2, cvtargs[ nstep ], status ); \ - } else if ( cvttype[ nstep ] == code2 ) { \ - cvttype[ nstep ] = code1; \ - AddArgs( code1, cvtargs[ nstep ], status ); \ - } - -/* Macro to exchange a transformation type code for its inverse (and - vice versa), and swap the order of its 2 arguments. */ -#define SWAP_CODES2( code1, code2 ) \ - if ( cvttype[ nstep ] == code1 ) { \ - cvttype[ nstep ] = code2; \ - tmp = cvtargs[ nstep ][ 0 ]; \ - cvtargs[ nstep ][ 0 ] = cvtargs[ nstep ][ 1 ]; \ - cvtargs[ nstep ][ 1 ] = tmp; \ - AddArgs( cvttype[ nstep ], cvtargs[ nstep ], status ); \ - } else if ( cvttype[ nstep ] == code2 ) { \ - cvttype[ nstep ] = code1; \ - tmp = cvtargs[ nstep ][ 0 ]; \ - cvtargs[ nstep ][ 0 ] = cvtargs[ nstep ][ 1 ]; \ - cvtargs[ nstep ][ 1 ] = tmp; \ - AddArgs( cvttype[ nstep ], cvtargs[ nstep ], status ); \ - } - -/* Use these macros to apply the changes where needed. */ - if ( invert ) { - -/* Exchange transformation codes for their inverses. */ - SWAP_CODES( AST__TAITOUTC, AST__UTCTOTAI ) - SWAP_CODES( AST__TAITOTT, AST__TTTOTAI ) - SWAP_CODES( AST__TTTOTDB, AST__TDBTOTT ) - SWAP_CODES( AST__TDBTOTCB, AST__TCBTOTDB ) - SWAP_CODES( AST__TTTOTCG, AST__TCGTOTT ) - SWAP_CODES( AST__UTTOGMST, AST__GMSTTOUT ) - SWAP_CODES( AST__GMSTTOLMST, AST__LMSTTOGMST ) - SWAP_CODES( AST__LASTTOLMST, AST__LMSTTOLAST ) - SWAP_CODES( AST__UTTOUTC, AST__UTCTOUT ) - SWAP_CODES( AST__LTTOUTC, AST__UTCTOLT ) - -/* Exchange transformation codes for their inverses, and swap the offset - values. */ - SWAP_CODES2( AST__MJDTOMJD, AST__MJDTOMJD ) - SWAP_CODES2( AST__MJDTOJD, AST__JDTOMJD ) - SWAP_CODES2( AST__MJDTOBEP, AST__BEPTOMJD ) - SWAP_CODES2( AST__MJDTOJEP, AST__JEPTOMJD ) - - } - -/* Undefine the local macros. */ -#undef SWAP_CODES -#undef SWAP_CODES2 - -/* Count the transformation steps. */ - nstep++; - } - } - -/* Loop to simplify the sequence of transformation steps until no - further improvement is possible. */ - done = 0; - while ( astOK && !done ) { - -/* Examine each remaining transformation step in turn. */ - ikeep = -1; - for ( istep = 0; istep < nstep; istep++ ) { - -/* Initially assume we will retain the current step. */ - keep = 1; - -/* We can eliminate changes of system which have no effect. */ - if( ( cvttype[ istep ] == AST__MJDTOMJD || - cvttype[ istep ] == AST__MJDTOJD || - cvttype[ istep ] == AST__JDTOMJD ) && - cvtargs[ istep ][ 2 ] == 0.0 ) { - keep = 0; - -/* The only simplifications for the conversions currently in this class act - to combine adjacent transformation steps, so only apply them while there - are at least 2 steps left. */ - } else if ( istep < ( nstep - 1 ) ) { - -/* Define a macro to test if two adjacent transformation type codes - have specified values. */ -#define PAIR_CVT( code1, code2 ) \ - ( ( cvttype[ istep ] == code1 ) && \ - ( cvttype[ istep + 1 ] == code2 ) ) - -/* Define a macro to test if two adjacent transformation type codes - have specified values, either way round. */ -#define PAIR_CVT2( code1, code2 ) \ - ( ( PAIR_CVT( code1, code2 ) ) || \ - ( PAIR_CVT( code2, code1 ) ) ) - -/* If a correction is followed by its inverse, and the user-supplied argument - values are unchanged (we do not need to test values stored in the - argument array which were not supplied by the user), we can eliminate them. - First check for conversions which have a single user-supplied argument. */ - if( ( PAIR_CVT2( AST__TAITOTT, AST__TTTOTAI ) || - PAIR_CVT2( AST__UTTOGMST, AST__GMSTTOUT ) || - PAIR_CVT2( AST__TTTOTCG, AST__TCGTOTT ) || - PAIR_CVT2( AST__TTTOTCG, AST__TCGTOTT ) || - PAIR_CVT2( AST__UTTOUTC, AST__UTCTOUT ) || - PAIR_CVT2( AST__LTTOUTC, AST__UTCTOLT ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - -/* Now check for conversions which have two user-supplied arguments - that are swapped by inversion. */ - } else if( ( PAIR_CVT2( AST__MJDTOJD, AST__JDTOMJD ) || - PAIR_CVT2( AST__MJDTOMJD, AST__MJDTOMJD ) || - PAIR_CVT2( AST__MJDTOBEP, AST__BEPTOMJD ) || - PAIR_CVT2( AST__MJDTOJEP, AST__JEPTOMJD ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 1 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 0 ] ) ) { - istep++; - keep = 0; - -/* Now check for conversions which have two user-supplied arguments - that are NOT swapped by inversion. */ - } else if( ( PAIR_CVT2( AST__TAITOUTC, AST__UTCTOTAI ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 1 ] ) ) { - istep++; - keep = 0; - -/* Now check for conversions which have three user-supplied arguments. */ - } else if( ( PAIR_CVT2( AST__TDBTOTCB, AST__TCBTOTDB ) || - PAIR_CVT2( AST__GMSTTOLMST, AST__LMSTTOGMST ) || - PAIR_CVT2( AST__LASTTOLMST, AST__LMSTTOLAST ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 1 ] ) && - astEQUAL( cvtargs[ istep ][ 2 ], - cvtargs[ istep + 1 ][ 2 ] ) ) { - istep++; - keep = 0; - -/* Now check for conversions which have five user-supplied arguments. */ - } else if( ( PAIR_CVT2( AST__TTTOTDB, AST__TDBTOTT ) ) && - astEQUAL( cvtargs[ istep ][ 0 ], - cvtargs[ istep + 1 ][ 0 ] ) && - astEQUAL( cvtargs[ istep ][ 1 ], - cvtargs[ istep + 1 ][ 1 ] ) && - astEQUAL( cvtargs[ istep ][ 2 ], - cvtargs[ istep + 1 ][ 2 ] ) && - astEQUAL( cvtargs[ istep ][ 3 ], - cvtargs[ istep + 1 ][ 3 ] ) && - astEQUAL( cvtargs[ istep ][ 4 ], - cvtargs[ istep + 1 ][ 4 ] ) ) { - istep++; - keep = 0; - } - -/* Undefine the local macros. */ -#undef PAIR_CVT -#undef PAIR_CVT2 - } - -/* If the current transformation (possibly modified above) is being - kept, then increment the index that identifies its new location in - the list of transformation steps. */ - if ( keep ) { - ikeep++; - -/* If the new location is different to its current location, copy the - transformation data into the new location. */ - if ( ikeep != istep ) { - cvttype[ ikeep ] = cvttype[ istep ]; - for ( iarg = 0; iarg < szarg[ istep ]; iarg++ ) { - cvtargs[ ikeep ][ iarg ] = cvtargs[ istep ][ iarg ]; - } - szarg[ ikeep ] = szarg[ istep ]; - narg[ ikeep ] = narg[ istep ]; - } - } - } - -/* Note if no simplification was achieved on this iteration (i.e. the - number of transformation steps was not reduced). This is the signal - to quit. */ - done = ( ( ikeep + 1 ) >= nstep ); - -/* Note how many transformation steps now remain. */ - nstep = ikeep + 1; - } - -/* Determine how many Mappings can be eliminated by condensing all - those considered above into a single Mapping. */ - if ( astOK ) { - ngone = imap2 - imap1; - -/* Determine if the replacement Mapping can be a UnitMap (a null - Mapping). This will only be the case if all the transformation - steps were eliminated above. */ - unit = ( nstep == 0 ); - -/* Determine if simplification is possible. This will be the case if - (a) Mappings were eliminated ("ngone" is non-zero), or (b) the - number of transformation steps was reduced, or (c) the TimeMap(s) - can be replaced by a UnitMap, or (d) if there was initially only - one TimeMap present, its invert flag was set (this flag will always - be cleared in the replacement Mapping). */ - simpler = ngone || ( nstep < nstep0 ) || unit || - ( *invert_list )[ where ]; - -/* Do nothing more unless simplification is possible. */ - if ( simpler ) { - -/* If the replacement Mapping is a UnitMap, then create it. */ - if ( unit ) { - new = (AstMapping *) - astUnitMap( astGetNin( ( *map_list )[ where ] ), "", status ); - -/* Otherwise, create a replacement TimeMap and add each of the - remaining transformation steps to it. */ - } else { - new = (AstMapping *) astTimeMap( 0, "", status ); - for ( istep = 0; istep < nstep; istep++ ) { - AddTimeCvt( (AstTimeMap *) new, cvttype[ istep ], - narg[ istep ], cvtargs[ istep ], status ); - } - } - -/* Annul the pointers to the Mappings being eliminated. */ - if ( astOK ) { - for ( imap = imap1; imap <= imap2; imap++ ) { - ( *map_list )[ imap ] = astAnnul( ( *map_list )[ imap ] ); - } - -/* Insert the pointer and invert value for the new Mapping. */ - ( *map_list )[ imap1 ] = new; - ( *invert_list )[ imap1 ] = 0; - -/* Move any subsequent Mapping information down to close the gap. */ - for ( imap = imap2 + 1; imap < *nmap; imap++ ) { - ( *map_list )[ imap - ngone ] = ( *map_list )[ imap ]; - ( *invert_list )[ imap - ngone ] = ( *invert_list )[ imap ]; - } - -/* Blank out any information remaining at the end of the arrays. */ - for ( imap = ( *nmap - ngone ); imap < *nmap; imap++ ) { - ( *map_list )[ imap ] = NULL; - ( *invert_list )[ imap ] = 0; - } - -/* Decrement the Mapping count and return the index of the first - Mapping which was eliminated. */ - ( *nmap ) -= ngone; - result = imap1; - -/* If an error occurred, annul the new Mapping pointer. */ - } else { - new = astAnnul( new ); - } - } - } - -/* Free the memory used for the transformation steps. */ - cvttype = astFree( cvttype ); - cvtargs = astFree( cvtargs ); - szarg = astFree( szarg ); - narg = astFree( narg ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* TimeMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -* Implementation Deficiencies: -* The initial version of this implementation only deals with -* frequency->wavelength conversions. This is because the slowness of -* the numerical differentiation implemented by the astRate method in -* the parent Mapping class is cripples conversion between SpecFluxFrames. -* Such conversions only rely on rate of change of wavelength with -* respect to frequency. This implementation should be extended when -* needed. - -*/ - -/* Local Variables: */ - AstTimeMap *map; - double result; - int cvt; - int i; - -/* Check inherited status */ - if( !astOK ) return AST__BAD; - -/* Get a pointer to the TimeMap structure. */ - map = (AstTimeMap *) this; - -/* Initialise the returned value. */ - result = 1.0; - -/* Loop round each conversion. */ - for( i = 0; i < map->ncvt; i++ ) { - -/* Store the type of the current conversion.*/ - cvt = map->cvttype[ i ]; - -/* Many of the time conversions are linear. If this is the case, multiply - the total rate of change by the rate of change for this step. */ - if( cvt == AST__MJDTOBEP ) { - result *= 1.0/365.242198781; - - } else if( cvt == AST__BEPTOMJD ) { - result *= 365.242198781; - - } else if( cvt == AST__MJDTOJEP ) { - result *= 1.0/365.25; - - } else if( cvt == AST__JEPTOMJD ) { - result *= 365.25; - -/* The GMST scales is not linear, so break if we encounter it, and use the - (numerical) parent astRate method. The other time scale conversions are - assumed to have a slope of unity. In fact the slope will be ever so - slightly different to unity. */ - } else if( cvt == AST__UTTOGMST || cvt == AST__GMSTTOUT ) { - result = AST__BAD; - break; - } - } - -/* If this is non-linear TimeMap, use the astRate method inherited from the - parent Mapping class. */ - if( result == AST__BAD ) result = (*parent_rate)( this, at, ax1, ax2, status ); - -/* Return the result. */ - return result; -} - -static double Rcc( double tdb, double ut1, double wl, double u, double v, int *status ){ -/* -* Name: -* Rcc - -* Purpose: -* Find difference between TDB and TT. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* double Rcc( double tdb, double ut1, double wl, double u, double v, int *status ) - -* Class Membership: -* TimeMap member function - -* Description: -* Relativistic clock correction: the difference between proper time at -* a point on the surface of the Earth and coordinate time in the Solar -* System barycentric space-time frame of reference. -* -* The proper time is terrestrial time, TT; the coordinate time is an -* implementation of barycentric dynamical time, TDB. - -* Parameters: -* tdb -* TDB as an MJD. -* ut1 -* Universal time (only the fraction of the day is relevant) -* wl -* Observer longitude (radians west) -* u -* Observer distance from Earth spin axis (km) -* v -* Observer distance north of Earth equatorial plane (km) -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The clock correction, TDB-TT, in seconds. TDB is coordinate time in the -* solar system barycentre frame of reference, in units chosen to eliminate -* the scale difference with respect to terrestrial time. TT is the proper -* time for clocks at mean sea level on the Earth. - -* Notes: -* - This function is a translation of the fortran routine SLA_RCC -* written by by P.T.Wallace. -* -* - The argument TDB is, strictly, the barycentric coordinate time; -* however, the terrestrial time TT can in practice be used without -* any significant loss of accuracy. -* -* - The result returned by Rcc comprises a main (annual) -* sinusoidal term of amplitude approximately 0.00166 seconds, plus -* planetary and lunar terms up to about 20 microseconds, and diurnal -* terms up to 2 microseconds. The variation arises from the -* transverse Doppler effect and the gravitational red-shift as the -* observer varies in speed and moves through different gravitational -* potentials. -* -* - The geocentric model is that of Fairhead & Bretagnon (1990), in -* its full form. It was supplied by Fairhead (private -* communication) as a FORTRAN subroutine. The original Fairhead -* routine used explicit formulae, in such large numbers that -* problems were experienced with certain compilers (Microsoft -* Fortran on PC aborted with stack overflow, Convex compiled -* successfully but extremely slowly). The present implementation is -* a complete recoding, with the original Fairhead coefficients held -* in a table. To optimise arithmetic precision, the terms are -* accumulated in reverse order, smallest first. A number of other -* coding changes were made, in order to match the calling sequence -* of previous versions of the present routine, and to comply with -* Starlink programming standards. The numerical results compared -* with those from the Fairhead form are essentially unaffected by -* the changes, the differences being at the 10^-20 sec level. -* -* - The topocentric part of the model is from Moyer (1981) and -* Murray (1983). It is an approximation to the expression -* ( v / c ) . ( r / c ), where v is the barycentric velocity of -* the Earth, r is the geocentric position of the observer and -* c is the speed of light. -* -* - During the interval 1950-2050, the absolute accuracy of is better -* than +/- 3 nanoseconds relative to direct numerical integrations -* using the JPL DE200/LE200 solar system ephemeris. -* -* - The IAU definition of TDB was that it must differ from TT only by -* periodic terms. Though practical, this is an imprecise definition -* which ignores the existence of very long-period and secular -* effects in the dynamics of the solar system. As a consequence, -* different implementations of TDB will, in general, differ in zero- -* point and will drift linearly relative to one other. -* -* - TDB was, in principle, superseded by new coordinate timescales -* which the IAU introduced in 1991: geocentric coordinate time, -* TCG, and barycentric coordinate time, TCB. However, Rcc -* can be used to implement the periodic part of TCB-TCG. - -* References: -* - Fairhead, L., & Bretagnon, P., Astron.Astrophys., 229, 240-247 -* (1990). -* -* - Moyer, T.D., Cel.Mech., 23, 33 (1981). -* -* - Murray, C.A., Vectorial Astrometry, Adam Hilger (1983). -* -* - Seidelmann, P.K. et al, Explanatory Supplement to the -* Astronomical Almanac, Chapter 2, University Science Books -* (1992). -* -* - Simon J.L., Bretagnon P., Chapront J., Chapront-Touze M., -* Francou G. & Laskar J., Astron.Astrophys., 282, 663-683 (1994). -*/ - - - - - -/* ----------------------------------------------------------------------- -* -* Fairhead and Bretagnon canonical coefficients -* -* 787 sets of three coefficients. -* -* Each set is amplitude (microseconds) -* frequency (radians per Julian millennium since J2000), -* phase (radians). -* -* Sets 0-473 are the T**0 terms, -* " 474-678 " " T**1 " -* " 679-763 " " T**2 " -* " 764-783 " " T**3 " -* " 784-786 " " T**4 " . -*/ - static double fairhd[ 787 ][ 3 ] = { - - { 1656.674564E-6, 6283.075849991, 6.240054195}, - { 22.417471E-6, 5753.384884897, 4.296977442}, - { 13.839792E-6, 12566.151699983, 6.196904410}, - { 4.770086E-6, 529.690965095, 0.444401603}, - { 4.676740E-6, 6069.776754553, 4.021195093}, - { 2.256707E-6, 213.299095438, 5.543113262}, - { 1.694205E-6, -3.523118349, 5.025132748}, - { 1.554905E-6, 77713.771467920, 5.198467090}, - { 1.276839E-6, 7860.419392439, 5.988822341}, - { 1.193379E-6, 5223.693919802, 3.649823730}, - { 1.115322E-6, 3930.209696220, 1.422745069}, - { 0.794185E-6, 11506.769769794, 2.322313077}, - { 0.447061E-6, 26.298319800, 3.615796498}, - { 0.435206E-6, -398.149003408, 4.349338347}, - { 0.600309E-6, 1577.343542448, 2.678271909}, - { 0.496817E-6, 6208.294251424, 5.696701824}, - { 0.486306E-6, 5884.926846583, 0.520007179}, - { 0.432392E-6, 74.781598567, 2.435898309}, - { 0.468597E-6, 6244.942814354, 5.866398759}, - { 0.375510E-6, 5507.553238667, 4.103476804}, - { 0.243085E-6, -775.522611324, 3.651837925}, - { 0.173435E-6, 18849.227549974, 6.153743485}, - { 0.230685E-6, 5856.477659115, 4.773852582}, - { 0.203747E-6, 12036.460734888, 4.333987818}, - { 0.143935E-6, -796.298006816, 5.957517795}, - { 0.159080E-6, 10977.078804699, 1.890075226}, - { 0.119979E-6, 38.133035638, 4.551585768}, - { 0.118971E-6, 5486.777843175, 1.914547226}, - { 0.116120E-6, 1059.381930189, 0.873504123}, - { 0.137927E-6, 11790.629088659, 1.135934669}, - { 0.098358E-6, 2544.314419883, 0.092793886}, - { 0.101868E-6, -5573.142801634, 5.984503847}, - { 0.080164E-6, 206.185548437, 2.095377709}, - { 0.079645E-6, 4694.002954708, 2.949233637}, - { 0.062617E-6, 20.775395492, 2.654394814}, - { 0.075019E-6, 2942.463423292, 4.980931759}, - { 0.064397E-6, 5746.271337896, 1.280308748}, - { 0.063814E-6, 5760.498431898, 4.167901731}, - { 0.048042E-6, 2146.165416475, 1.495846011}, - { 0.048373E-6, 155.420399434, 2.251573730}, - { 0.058844E-6, 426.598190876, 4.839650148}, - { 0.046551E-6, -0.980321068, 0.921573539}, - { 0.054139E-6, 17260.154654690, 3.411091093}, - { 0.042411E-6, 6275.962302991, 2.869567043}, - { 0.040184E-6, -7.113547001, 3.565975565}, - { 0.036564E-6, 5088.628839767, 3.324679049}, - { 0.040759E-6, 12352.852604545, 3.981496998}, - { 0.036507E-6, 801.820931124, 6.248866009}, - { 0.036955E-6, 3154.687084896, 5.071801441}, - { 0.042732E-6, 632.783739313, 5.720622217}, - { 0.042560E-6, 161000.685737473, 1.270837679}, - { 0.040480E-6, 15720.838784878, 2.546610123}, - { 0.028244E-6, -6286.598968340, 5.069663519}, - { 0.033477E-6, 6062.663207553, 4.144987272}, - { 0.034867E-6, 522.577418094, 5.210064075}, - { 0.032438E-6, 6076.890301554, 0.749317412}, - { 0.030215E-6, 7084.896781115, 3.389610345}, - { 0.029247E-6, -71430.695617928, 4.183178762}, - { 0.033529E-6, 9437.762934887, 2.404714239}, - { 0.032423E-6, 8827.390269875, 5.541473556}, - { 0.027567E-6, 6279.552731642, 5.040846034}, - { 0.029862E-6, 12139.553509107, 1.770181024}, - { 0.022509E-6, 10447.387839604, 1.460726241}, - { 0.020937E-6, 8429.241266467, 0.652303414}, - { 0.020322E-6, 419.484643875, 3.735430632}, - { 0.024816E-6, -1194.447010225, 1.087136918}, - { 0.025196E-6, 1748.016413067, 2.901883301}, - { 0.021691E-6, 14143.495242431, 5.952658009}, - { 0.017673E-6, 6812.766815086, 3.186129845}, - { 0.022567E-6, 6133.512652857, 3.307984806}, - { 0.016155E-6, 10213.285546211, 1.331103168}, - { 0.014751E-6, 1349.867409659, 4.308933301}, - { 0.015949E-6, -220.412642439, 4.005298270}, - { 0.015974E-6, -2352.866153772, 6.145309371}, - { 0.014223E-6, 17789.845619785, 2.104551349}, - { 0.017806E-6, 73.297125859, 3.475975097}, - { 0.013671E-6, -536.804512095, 5.971672571}, - { 0.011942E-6, 8031.092263058, 2.053414715}, - { 0.014318E-6, 16730.463689596, 3.016058075}, - { 0.012462E-6, 103.092774219, 1.737438797}, - { 0.010962E-6, 3.590428652, 2.196567739}, - { 0.015078E-6, 19651.048481098, 3.969480770}, - { 0.010396E-6, 951.718406251, 5.717799605}, - { 0.011707E-6, -4705.732307544, 2.654125618}, - { 0.010453E-6, 5863.591206116, 1.913704550}, - { 0.012420E-6, 4690.479836359, 4.734090399}, - { 0.011847E-6, 5643.178563677, 5.489005403}, - { 0.008610E-6, 3340.612426700, 3.661698944}, - { 0.011622E-6, 5120.601145584, 4.863931876}, - { 0.010825E-6, 553.569402842, 0.842715011}, - { 0.008666E-6, -135.065080035, 3.293406547}, - { 0.009963E-6, 149.563197135, 4.870690598}, - { 0.009858E-6, 6309.374169791, 1.061816410}, - { 0.007959E-6, 316.391869657, 2.465042647}, - { 0.010099E-6, 283.859318865, 1.942176992}, - { 0.007147E-6, -242.728603974, 3.661486981}, - { 0.007505E-6, 5230.807466803, 4.920937029}, - { 0.008323E-6, 11769.853693166, 1.229392026}, - { 0.007490E-6, -6256.777530192, 3.658444681}, - { 0.009370E-6, 149854.400134205, 0.673880395}, - { 0.007117E-6, 38.027672636, 5.294249518}, - { 0.007857E-6, 12168.002696575, 0.525733528}, - { 0.007019E-6, 6206.809778716, 0.837688810}, - { 0.006056E-6, 955.599741609, 4.194535082}, - { 0.008107E-6, 13367.972631107, 3.793235253}, - { 0.006731E-6, 5650.292110678, 5.639906583}, - { 0.007332E-6, 36.648562930, 0.114858677}, - { 0.006366E-6, 4164.311989613, 2.262081818}, - { 0.006858E-6, 5216.580372801, 0.642063318}, - { 0.006919E-6, 6681.224853400, 6.018501522}, - { 0.006826E-6, 7632.943259650, 3.458654112}, - { 0.005308E-6, -1592.596013633, 2.500382359}, - { 0.005096E-6, 11371.704689758, 2.547107806}, - { 0.004841E-6, 5333.900241022, 0.437078094}, - { 0.005582E-6, 5966.683980335, 2.246174308}, - { 0.006304E-6, 11926.254413669, 2.512929171}, - { 0.006603E-6, 23581.258177318, 5.393136889}, - { 0.005123E-6, -1.484472708, 2.999641028}, - { 0.004648E-6, 1589.072895284, 1.275847090}, - { 0.005119E-6, 6438.496249426, 1.486539246}, - { 0.004521E-6, 4292.330832950, 6.140635794}, - { 0.005680E-6, 23013.539539587, 4.557814849}, - { 0.005488E-6, -3.455808046, 0.090675389}, - { 0.004193E-6, 7234.794256242, 4.869091389}, - { 0.003742E-6, 7238.675591600, 4.691976180}, - { 0.004148E-6, -110.206321219, 3.016173439}, - { 0.004553E-6, 11499.656222793, 5.554998314}, - { 0.004892E-6, 5436.993015240, 1.475415597}, - { 0.004044E-6, 4732.030627343, 1.398784824}, - { 0.004164E-6, 12491.370101415, 5.650931916}, - { 0.004349E-6, 11513.883316794, 2.181745369}, - { 0.003919E-6, 12528.018664345, 5.823319737}, - { 0.003129E-6, 6836.645252834, 0.003844094}, - { 0.004080E-6, -7058.598461315, 3.690360123}, - { 0.003270E-6, 76.266071276, 1.517189902}, - { 0.002954E-6, 6283.143160294, 4.447203799}, - { 0.002872E-6, 28.449187468, 1.158692983}, - { 0.002881E-6, 735.876513532, 0.349250250}, - { 0.003279E-6, 5849.364112115, 4.893384368}, - { 0.003625E-6, 6209.778724132, 1.473760578}, - { 0.003074E-6, 949.175608970, 5.185878737}, - { 0.002775E-6, 9917.696874510, 1.030026325}, - { 0.002646E-6, 10973.555686350, 3.918259169}, - { 0.002575E-6, 25132.303399966, 6.109659023}, - { 0.003500E-6, 263.083923373, 1.892100742}, - { 0.002740E-6, 18319.536584880, 4.320519510}, - { 0.002464E-6, 202.253395174, 4.698203059}, - { 0.002409E-6, 2.542797281, 5.325009315}, - { 0.003354E-6, -90955.551694697, 1.942656623}, - { 0.002296E-6, 6496.374945429, 5.061810696}, - { 0.003002E-6, 6172.869528772, 2.797822767}, - { 0.003202E-6, 27511.467873537, 0.531673101}, - { 0.002954E-6, -6283.008539689, 4.533471191}, - { 0.002353E-6, 639.897286314, 3.734548088}, - { 0.002401E-6, 16200.772724501, 2.605547070}, - { 0.003053E-6, 233141.314403759, 3.029030662}, - { 0.003024E-6, 83286.914269554, 2.355556099}, - { 0.002863E-6, 17298.182327326, 5.240963796}, - { 0.002103E-6, -7079.373856808, 5.756641637}, - { 0.002303E-6, 83996.847317911, 2.013686814}, - { 0.002303E-6, 18073.704938650, 1.089100410}, - { 0.002381E-6, 63.735898303, 0.759188178}, - { 0.002493E-6, 6386.168624210, 0.645026535}, - { 0.002366E-6, 3.932153263, 6.215885448}, - { 0.002169E-6, 11015.106477335, 4.845297676}, - { 0.002397E-6, 6243.458341645, 3.809290043}, - { 0.002183E-6, 1162.474704408, 6.179611691}, - { 0.002353E-6, 6246.427287062, 4.781719760}, - { 0.002199E-6, -245.831646229, 5.956152284}, - { 0.001729E-6, 3894.181829542, 1.264976635}, - { 0.001896E-6, -3128.388765096, 4.914231596}, - { 0.002085E-6, 35.164090221, 1.405158503}, - { 0.002024E-6, 14712.317116458, 2.752035928}, - { 0.001737E-6, 6290.189396992, 5.280820144}, - { 0.002229E-6, 491.557929457, 1.571007057}, - { 0.001602E-6, 14314.168113050, 4.203664806}, - { 0.002186E-6, 454.909366527, 1.402101526}, - { 0.001897E-6, 22483.848574493, 4.167932508}, - { 0.001825E-6, -3738.761430108, 0.545828785}, - { 0.001894E-6, 1052.268383188, 5.817167450}, - { 0.001421E-6, 20.355319399, 2.419886601}, - { 0.001408E-6, 10984.192351700, 2.732084787}, - { 0.001847E-6, 10873.986030480, 2.903477885}, - { 0.001391E-6, -8635.942003763, 0.593891500}, - { 0.001388E-6, -7.046236698, 1.166145902}, - { 0.001810E-6, -88860.057071188, 0.487355242}, - { 0.001288E-6, -1990.745017041, 3.913022880}, - { 0.001297E-6, 23543.230504682, 3.063805171}, - { 0.001335E-6, -266.607041722, 3.995764039}, - { 0.001376E-6, 10969.965257698, 5.152914309}, - { 0.001745E-6, 244287.600007027, 3.626395673}, - { 0.001649E-6, 31441.677569757, 1.952049260}, - { 0.001416E-6, 9225.539273283, 4.996408389}, - { 0.001238E-6, 4804.209275927, 5.503379738}, - { 0.001472E-6, 4590.910180489, 4.164913291}, - { 0.001169E-6, 6040.347246017, 5.841719038}, - { 0.001039E-6, 5540.085789459, 2.769753519}, - { 0.001004E-6, -170.672870619, 0.755008103}, - { 0.001284E-6, 10575.406682942, 5.306538209}, - { 0.001278E-6, 71.812653151, 4.713486491}, - { 0.001321E-6, 18209.330263660, 2.624866359}, - { 0.001297E-6, 21228.392023546, 0.382603541}, - { 0.000954E-6, 6282.095528923, 0.882213514}, - { 0.001145E-6, 6058.731054289, 1.169483931}, - { 0.000979E-6, 5547.199336460, 5.448375984}, - { 0.000987E-6, -6262.300454499, 2.656486959}, - { 0.001070E-6, -154717.609887482, 1.827624012}, - { 0.000991E-6, 4701.116501708, 4.387001801}, - { 0.001155E-6, -14.227094002, 3.042700750}, - { 0.001176E-6, 277.034993741, 3.335519004}, - { 0.000890E-6, 13916.019109642, 5.601498297}, - { 0.000884E-6, -1551.045222648, 1.088831705}, - { 0.000876E-6, 5017.508371365, 3.969902609}, - { 0.000806E-6, 15110.466119866, 5.142876744}, - { 0.000773E-6, -4136.910433516, 0.022067765}, - { 0.001077E-6, 175.166059800, 1.844913056}, - { 0.000954E-6, -6284.056171060, 0.968480906}, - { 0.000737E-6, 5326.786694021, 4.923831588}, - { 0.000845E-6, -433.711737877, 4.749245231}, - { 0.000819E-6, 8662.240323563, 5.991247817}, - { 0.000852E-6, 199.072001436, 2.189604979}, - { 0.000723E-6, 17256.631536341, 6.068719637}, - { 0.000940E-6, 6037.244203762, 6.197428148}, - { 0.000885E-6, 11712.955318231, 3.280414875}, - { 0.000706E-6, 12559.038152982, 2.824848947}, - { 0.000732E-6, 2379.164473572, 2.501813417}, - { 0.000764E-6, -6127.655450557, 2.236346329}, - { 0.000908E-6, 131.541961686, 2.521257490}, - { 0.000907E-6, 35371.887265976, 3.370195967}, - { 0.000673E-6, 1066.495477190, 3.876512374}, - { 0.000814E-6, 17654.780539750, 4.627122566}, - { 0.000630E-6, 36.027866677, 0.156368499}, - { 0.000798E-6, 515.463871093, 5.151962502}, - { 0.000798E-6, 148.078724426, 5.909225055}, - { 0.000806E-6, 309.278322656, 6.054064447}, - { 0.000607E-6, -39.617508346, 2.839021623}, - { 0.000601E-6, 412.371096874, 3.984225404}, - { 0.000646E-6, 11403.676995575, 3.852959484}, - { 0.000704E-6, 13521.751441591, 2.300991267}, - { 0.000603E-6, -65147.619767937, 4.140083146}, - { 0.000609E-6, 10177.257679534, 0.437122327}, - { 0.000631E-6, 5767.611978898, 4.026532329}, - { 0.000576E-6, 11087.285125918, 4.760293101}, - { 0.000674E-6, 14945.316173554, 6.270510511}, - { 0.000726E-6, 5429.879468239, 6.039606892}, - { 0.000710E-6, 28766.924424484, 5.672617711}, - { 0.000647E-6, 11856.218651625, 3.397132627}, - { 0.000678E-6, -5481.254918868, 6.249666675}, - { 0.000618E-6, 22003.914634870, 2.466427018}, - { 0.000738E-6, 6134.997125565, 2.242668890}, - { 0.000660E-6, 625.670192312, 5.864091907}, - { 0.000694E-6, 3496.032826134, 2.668309141}, - { 0.000531E-6, 6489.261398429, 1.681888780}, - { 0.000611E-6, -143571.324284214, 2.424978312}, - { 0.000575E-6, 12043.574281889, 4.216492400}, - { 0.000553E-6, 12416.588502848, 4.772158039}, - { 0.000689E-6, 4686.889407707, 6.224271088}, - { 0.000495E-6, 7342.457780181, 3.817285811}, - { 0.000567E-6, 3634.621024518, 1.649264690}, - { 0.000515E-6, 18635.928454536, 3.945345892}, - { 0.000486E-6, -323.505416657, 4.061673868}, - { 0.000662E-6, 25158.601719765, 1.794058369}, - { 0.000509E-6, 846.082834751, 3.053874588}, - { 0.000472E-6, -12569.674818332, 5.112133338}, - { 0.000461E-6, 6179.983075773, 0.513669325}, - { 0.000641E-6, 83467.156352816, 3.210727723}, - { 0.000520E-6, 10344.295065386, 2.445597761}, - { 0.000493E-6, 18422.629359098, 1.676939306}, - { 0.000478E-6, 1265.567478626, 5.487314569}, - { 0.000472E-6, -18.159247265, 1.999707589}, - { 0.000559E-6, 11190.377900137, 5.783236356}, - { 0.000494E-6, 9623.688276691, 3.022645053}, - { 0.000463E-6, 5739.157790895, 1.411223013}, - { 0.000432E-6, 16858.482532933, 1.179256434}, - { 0.000574E-6, 72140.628666286, 1.758191830}, - { 0.000484E-6, 17267.268201691, 3.290589143}, - { 0.000550E-6, 4907.302050146, 0.864024298}, - { 0.000399E-6, 14.977853527, 2.094441910}, - { 0.000491E-6, 224.344795702, 0.878372791}, - { 0.000432E-6, 20426.571092422, 6.003829241}, - { 0.000481E-6, 5749.452731634, 4.309591964}, - { 0.000480E-6, 5757.317038160, 1.142348571}, - { 0.000485E-6, 6702.560493867, 0.210580917}, - { 0.000426E-6, 6055.549660552, 4.274476529}, - { 0.000480E-6, 5959.570433334, 5.031351030}, - { 0.000466E-6, 12562.628581634, 4.959581597}, - { 0.000520E-6, 39302.096962196, 4.788002889}, - { 0.000458E-6, 12132.439962106, 1.880103788}, - { 0.000470E-6, 12029.347187887, 1.405611197}, - { 0.000416E-6, -7477.522860216, 1.082356330}, - { 0.000449E-6, 11609.862544012, 4.179989585}, - { 0.000465E-6, 17253.041107690, 0.353496295}, - { 0.000362E-6, -4535.059436924, 1.583849576}, - { 0.000383E-6, 21954.157609398, 3.747376371}, - { 0.000389E-6, 17.252277143, 1.395753179}, - { 0.000331E-6, 18052.929543158, 0.566790582}, - { 0.000430E-6, 13517.870106233, 0.685827538}, - { 0.000368E-6, -5756.908003246, 0.731374317}, - { 0.000330E-6, 10557.594160824, 3.710043680}, - { 0.000332E-6, 20199.094959633, 1.652901407}, - { 0.000384E-6, 11933.367960670, 5.827781531}, - { 0.000387E-6, 10454.501386605, 2.541182564}, - { 0.000325E-6, 15671.081759407, 2.178850542}, - { 0.000318E-6, 138.517496871, 2.253253037}, - { 0.000305E-6, 9388.005909415, 0.578340206}, - { 0.000352E-6, 5749.861766548, 3.000297967}, - { 0.000311E-6, 6915.859589305, 1.693574249}, - { 0.000297E-6, 24072.921469776, 1.997249392}, - { 0.000363E-6, -640.877607382, 5.071820966}, - { 0.000323E-6, 12592.450019783, 1.072262823}, - { 0.000341E-6, 12146.667056108, 4.700657997}, - { 0.000290E-6, 9779.108676125, 1.812320441}, - { 0.000342E-6, 6132.028180148, 4.322238614}, - { 0.000329E-6, 6268.848755990, 3.033827743}, - { 0.000374E-6, 17996.031168222, 3.388716544}, - { 0.000285E-6, -533.214083444, 4.687313233}, - { 0.000338E-6, 6065.844601290, 0.877776108}, - { 0.000276E-6, 24.298513841, 0.770299429}, - { 0.000336E-6, -2388.894020449, 5.353796034}, - { 0.000290E-6, 3097.883822726, 4.075291557}, - { 0.000318E-6, 709.933048357, 5.941207518}, - { 0.000271E-6, 13095.842665077, 3.208912203}, - { 0.000331E-6, 6073.708907816, 4.007881169}, - { 0.000292E-6, 742.990060533, 2.714333592}, - { 0.000362E-6, 29088.811415985, 3.215977013}, - { 0.000280E-6, 12359.966151546, 0.710872502}, - { 0.000267E-6, 10440.274292604, 4.730108488}, - { 0.000262E-6, 838.969287750, 1.327720272}, - { 0.000250E-6, 16496.361396202, 0.898769761}, - { 0.000325E-6, 20597.243963041, 0.180044365}, - { 0.000268E-6, 6148.010769956, 5.152666276}, - { 0.000284E-6, 5636.065016677, 5.655385808}, - { 0.000301E-6, 6080.822454817, 2.135396205}, - { 0.000294E-6, -377.373607916, 3.708784168}, - { 0.000236E-6, 2118.763860378, 1.733578756}, - { 0.000234E-6, 5867.523359379, 5.575209112}, - { 0.000268E-6, -226858.238553767, 0.069432392}, - { 0.000265E-6, 167283.761587465, 4.369302826}, - { 0.000280E-6, 28237.233459389, 5.304829118}, - { 0.000292E-6, 12345.739057544, 4.096094132}, - { 0.000223E-6, 19800.945956225, 3.069327406}, - { 0.000301E-6, 43232.306658416, 6.205311188}, - { 0.000264E-6, 18875.525869774, 1.417263408}, - { 0.000304E-6, -1823.175188677, 3.409035232}, - { 0.000301E-6, 109.945688789, 0.510922054}, - { 0.000260E-6, 813.550283960, 2.389438934}, - { 0.000299E-6, 316428.228673312, 5.384595078}, - { 0.000211E-6, 5756.566278634, 3.789392838}, - { 0.000209E-6, 5750.203491159, 1.661943545}, - { 0.000240E-6, 12489.885628707, 5.684549045}, - { 0.000216E-6, 6303.851245484, 3.862942261}, - { 0.000203E-6, 1581.959348283, 5.549853589}, - { 0.000200E-6, 5642.198242609, 1.016115785}, - { 0.000197E-6, -70.849445304, 4.690702525}, - { 0.000227E-6, 6287.008003254, 2.911891613}, - { 0.000197E-6, 533.623118358, 1.048982898}, - { 0.000205E-6, -6279.485421340, 1.829362730}, - { 0.000209E-6, -10988.808157535, 2.636140084}, - { 0.000208E-6, -227.526189440, 4.127883842}, - { 0.000191E-6, 415.552490612, 4.401165650}, - { 0.000190E-6, 29296.615389579, 4.175658539}, - { 0.000264E-6, 66567.485864652, 4.601102551}, - { 0.000256E-6, -3646.350377354, 0.506364778}, - { 0.000188E-6, 13119.721102825, 2.032195842}, - { 0.000185E-6, -209.366942175, 4.694756586}, - { 0.000198E-6, 25934.124331089, 3.832703118}, - { 0.000195E-6, 4061.219215394, 3.308463427}, - { 0.000234E-6, 5113.487598583, 1.716090661}, - { 0.000188E-6, 1478.866574064, 5.686865780}, - { 0.000222E-6, 11823.161639450, 1.942386641}, - { 0.000181E-6, 10770.893256262, 1.999482059}, - { 0.000171E-6, 6546.159773364, 1.182807992}, - { 0.000206E-6, 70.328180442, 5.934076062}, - { 0.000169E-6, 20995.392966449, 2.169080622}, - { 0.000191E-6, 10660.686935042, 5.405515999}, - { 0.000228E-6, 33019.021112205, 4.656985514}, - { 0.000184E-6, -4933.208440333, 3.327476868}, - { 0.000220E-6, -135.625325010, 1.765430262}, - { 0.000166E-6, 23141.558382925, 3.454132746}, - { 0.000191E-6, 6144.558353121, 5.020393445}, - { 0.000180E-6, 6084.003848555, 0.602182191}, - { 0.000163E-6, 17782.732072784, 4.960593133}, - { 0.000225E-6, 16460.333529525, 2.596451817}, - { 0.000222E-6, 5905.702242076, 3.731990323}, - { 0.000204E-6, 227.476132789, 5.636192701}, - { 0.000159E-6, 16737.577236597, 3.600691544}, - { 0.000200E-6, 6805.653268085, 0.868220961}, - { 0.000187E-6, 11919.140866668, 2.629456641}, - { 0.000161E-6, 127.471796607, 2.862574720}, - { 0.000205E-6, 6286.666278643, 1.742882331}, - { 0.000189E-6, 153.778810485, 4.812372643}, - { 0.000168E-6, 16723.350142595, 0.027860588}, - { 0.000149E-6, 11720.068865232, 0.659721876}, - { 0.000189E-6, 5237.921013804, 5.245313000}, - { 0.000143E-6, 6709.674040867, 4.317625647}, - { 0.000146E-6, 4487.817406270, 4.815297007}, - { 0.000144E-6, -664.756045130, 5.381366880}, - { 0.000175E-6, 5127.714692584, 4.728443327}, - { 0.000162E-6, 6254.626662524, 1.435132069}, - { 0.000187E-6, 47162.516354635, 1.354371923}, - { 0.000146E-6, 11080.171578918, 3.369695406}, - { 0.000180E-6, -348.924420448, 2.490902145}, - { 0.000148E-6, 151.047669843, 3.799109588}, - { 0.000157E-6, 6197.248551160, 1.284375887}, - { 0.000167E-6, 146.594251718, 0.759969109}, - { 0.000133E-6, -5331.357443741, 5.409701889}, - { 0.000154E-6, 95.979227218, 3.366890614}, - { 0.000148E-6, -6418.140930027, 3.384104996}, - { 0.000128E-6, -6525.804453965, 3.803419985}, - { 0.000130E-6, 11293.470674356, 0.939039445}, - { 0.000152E-6, -5729.506447149, 0.734117523}, - { 0.000138E-6, 210.117701700, 2.564216078}, - { 0.000123E-6, 6066.595360816, 4.517099537}, - { 0.000140E-6, 18451.078546566, 0.642049130}, - { 0.000126E-6, 11300.584221356, 3.485280663}, - { 0.000119E-6, 10027.903195729, 3.217431161}, - { 0.000151E-6, 4274.518310832, 4.404359108}, - { 0.000117E-6, 6072.958148291, 0.366324650}, - { 0.000165E-6, -7668.637425143, 4.298212528}, - { 0.000117E-6, -6245.048177356, 5.379518958}, - { 0.000130E-6, -5888.449964932, 4.527681115}, - { 0.000121E-6, -543.918059096, 6.109429504}, - { 0.000162E-6, 9683.594581116, 5.720092446}, - { 0.000141E-6, 6219.339951688, 0.679068671}, - { 0.000118E-6, 22743.409379516, 4.881123092}, - { 0.000129E-6, 1692.165669502, 0.351407289}, - { 0.000126E-6, 5657.405657679, 5.146592349}, - { 0.000114E-6, 728.762966531, 0.520791814}, - { 0.000120E-6, 52.596639600, 0.948516300}, - { 0.000115E-6, 65.220371012, 3.504914846}, - { 0.000126E-6, 5881.403728234, 5.577502482}, - { 0.000158E-6, 163096.180360983, 2.957128968}, - { 0.000134E-6, 12341.806904281, 2.598576764}, - { 0.000151E-6, 16627.370915377, 3.985702050}, - { 0.000109E-6, 1368.660252845, 0.014730471}, - { 0.000131E-6, 6211.263196841, 0.085077024}, - { 0.000146E-6, 5792.741760812, 0.708426604}, - { 0.000146E-6, -77.750543984, 3.121576600}, - { 0.000107E-6, 5341.013788022, 0.288231904}, - { 0.000138E-6, 6281.591377283, 2.797450317}, - { 0.000113E-6, -6277.552925684, 2.788904128}, - { 0.000115E-6, -525.758811831, 5.895222200}, - { 0.000138E-6, 6016.468808270, 6.096188999}, - { 0.000139E-6, 23539.707386333, 2.028195445}, - { 0.000146E-6, -4176.041342449, 4.660008502}, - { 0.000107E-6, 16062.184526117, 4.066520001}, - { 0.000142E-6, 83783.548222473, 2.936315115}, - { 0.000128E-6, 9380.959672717, 3.223844306}, - { 0.000135E-6, 6205.325306007, 1.638054048}, - { 0.000101E-6, 2699.734819318, 5.481603249}, - { 0.000104E-6, -568.821874027, 2.205734493}, - { 0.000103E-6, 6321.103522627, 2.440421099}, - { 0.000119E-6, 6321.208885629, 2.547496264}, - { 0.000138E-6, 1975.492545856, 2.314608466}, - { 0.000121E-6, 137.033024162, 4.539108237}, - { 0.000123E-6, 19402.796952817, 4.538074405}, - { 0.000119E-6, 22805.735565994, 2.869040566}, - { 0.000133E-6, 64471.991241142, 6.056405489}, - { 0.000129E-6, -85.827298831, 2.540635083}, - { 0.000131E-6, 13613.804277336, 4.005732868}, - { 0.000104E-6, 9814.604100291, 1.959967212}, - { 0.000112E-6, 16097.679950283, 3.589026260}, - { 0.000123E-6, 2107.034507542, 1.728627253}, - { 0.000121E-6, 36949.230808424, 6.072332087}, - { 0.000108E-6, -12539.853380183, 3.716133846}, - { 0.000113E-6, -7875.671863624, 2.725771122}, - { 0.000109E-6, 4171.425536614, 4.033338079}, - { 0.000101E-6, 6247.911759770, 3.441347021}, - { 0.000113E-6, 7330.728427345, 0.656372122}, - { 0.000113E-6, 51092.726050855, 2.791483066}, - { 0.000106E-6, 5621.842923210, 1.815323326}, - { 0.000101E-6, 111.430161497, 5.711033677}, - { 0.000103E-6, 909.818733055, 2.812745443}, - { 0.000101E-6, 1790.642637886, 1.965746028}, - { 102.156724E-6, 6283.075849991, 4.249032005}, - { 1.706807E-6, 12566.151699983, 4.205904248}, - { 0.269668E-6, 213.299095438, 3.400290479}, - { 0.265919E-6, 529.690965095, 5.836047367}, - { 0.210568E-6, -3.523118349, 6.262738348}, - { 0.077996E-6, 5223.693919802, 4.670344204}, - { 0.054764E-6, 1577.343542448, 4.534800170}, - { 0.059146E-6, 26.298319800, 1.083044735}, - { 0.034420E-6, -398.149003408, 5.980077351}, - { 0.032088E-6, 18849.227549974, 4.162913471}, - { 0.033595E-6, 5507.553238667, 5.980162321}, - { 0.029198E-6, 5856.477659115, 0.623811863}, - { 0.027764E-6, 155.420399434, 3.745318113}, - { 0.025190E-6, 5746.271337896, 2.980330535}, - { 0.022997E-6, -796.298006816, 1.174411803}, - { 0.024976E-6, 5760.498431898, 2.467913690}, - { 0.021774E-6, 206.185548437, 3.854787540}, - { 0.017925E-6, -775.522611324, 1.092065955}, - { 0.013794E-6, 426.598190876, 2.699831988}, - { 0.013276E-6, 6062.663207553, 5.845801920}, - { 0.011774E-6, 12036.460734888, 2.292832062}, - { 0.012869E-6, 6076.890301554, 5.333425680}, - { 0.012152E-6, 1059.381930189, 6.222874454}, - { 0.011081E-6, -7.113547001, 5.154724984}, - { 0.010143E-6, 4694.002954708, 4.044013795}, - { 0.009357E-6, 5486.777843175, 3.416081409}, - { 0.010084E-6, 522.577418094, 0.749320262}, - { 0.008587E-6, 10977.078804699, 2.777152598}, - { 0.008628E-6, 6275.962302991, 4.562060226}, - { 0.008158E-6, -220.412642439, 5.806891533}, - { 0.007746E-6, 2544.314419883, 1.603197066}, - { 0.007670E-6, 2146.165416475, 3.000200440}, - { 0.007098E-6, 74.781598567, 0.443725817}, - { 0.006180E-6, -536.804512095, 1.302642751}, - { 0.005818E-6, 5088.628839767, 4.827723531}, - { 0.004945E-6, -6286.598968340, 0.268305170}, - { 0.004774E-6, 1349.867409659, 5.808636673}, - { 0.004687E-6, -242.728603974, 5.154890570}, - { 0.006089E-6, 1748.016413067, 4.403765209}, - { 0.005975E-6, -1194.447010225, 2.583472591}, - { 0.004229E-6, 951.718406251, 0.931172179}, - { 0.005264E-6, 553.569402842, 2.336107252}, - { 0.003049E-6, 5643.178563677, 1.362634430}, - { 0.002974E-6, 6812.766815086, 1.583012668}, - { 0.003403E-6, -2352.866153772, 2.552189886}, - { 0.003030E-6, 419.484643875, 5.286473844}, - { 0.003210E-6, -7.046236698, 1.863796539}, - { 0.003058E-6, 9437.762934887, 4.226420633}, - { 0.002589E-6, 12352.852604545, 1.991935820}, - { 0.002927E-6, 5216.580372801, 2.319951253}, - { 0.002425E-6, 5230.807466803, 3.084752833}, - { 0.002656E-6, 3154.687084896, 2.487447866}, - { 0.002445E-6, 10447.387839604, 2.347139160}, - { 0.002990E-6, 4690.479836359, 6.235872050}, - { 0.002890E-6, 5863.591206116, 0.095197563}, - { 0.002498E-6, 6438.496249426, 2.994779800}, - { 0.001889E-6, 8031.092263058, 3.569003717}, - { 0.002567E-6, 801.820931124, 3.425611498}, - { 0.001803E-6, -71430.695617928, 2.192295512}, - { 0.001782E-6, 3.932153263, 5.180433689}, - { 0.001694E-6, -4705.732307544, 4.641779174}, - { 0.001704E-6, -1592.596013633, 3.997097652}, - { 0.001735E-6, 5849.364112115, 0.417558428}, - { 0.001643E-6, 8429.241266467, 2.180619584}, - { 0.001680E-6, 38.133035638, 4.164529426}, - { 0.002045E-6, 7084.896781115, 0.526323854}, - { 0.001458E-6, 4292.330832950, 1.356098141}, - { 0.001437E-6, 20.355319399, 3.895439360}, - { 0.001738E-6, 6279.552731642, 0.087484036}, - { 0.001367E-6, 14143.495242431, 3.987576591}, - { 0.001344E-6, 7234.794256242, 0.090454338}, - { 0.001438E-6, 11499.656222793, 0.974387904}, - { 0.001257E-6, 6836.645252834, 1.509069366}, - { 0.001358E-6, 11513.883316794, 0.495572260}, - { 0.001628E-6, 7632.943259650, 4.968445721}, - { 0.001169E-6, 103.092774219, 2.838496795}, - { 0.001162E-6, 4164.311989613, 3.408387778}, - { 0.001092E-6, 6069.776754553, 3.617942651}, - { 0.001008E-6, 17789.845619785, 0.286350174}, - { 0.001008E-6, 639.897286314, 1.610762073}, - { 0.000918E-6, 10213.285546211, 5.532798067}, - { 0.001011E-6, -6256.777530192, 0.661826484}, - { 0.000753E-6, 16730.463689596, 3.905030235}, - { 0.000737E-6, 11926.254413669, 4.641956361}, - { 0.000694E-6, 3340.612426700, 2.111120332}, - { 0.000701E-6, 3894.181829542, 2.760823491}, - { 0.000689E-6, -135.065080035, 4.768800780}, - { 0.000700E-6, 13367.972631107, 5.760439898}, - { 0.000664E-6, 6040.347246017, 1.051215840}, - { 0.000654E-6, 5650.292110678, 4.911332503}, - { 0.000788E-6, 6681.224853400, 4.699648011}, - { 0.000628E-6, 5333.900241022, 5.024608847}, - { 0.000755E-6, -110.206321219, 4.370971253}, - { 0.000628E-6, 6290.189396992, 3.660478857}, - { 0.000635E-6, 25132.303399966, 4.121051532}, - { 0.000534E-6, 5966.683980335, 1.173284524}, - { 0.000543E-6, -433.711737877, 0.345585464}, - { 0.000517E-6, -1990.745017041, 5.414571768}, - { 0.000504E-6, 5767.611978898, 2.328281115}, - { 0.000485E-6, 5753.384884897, 1.685874771}, - { 0.000463E-6, 7860.419392439, 5.297703006}, - { 0.000604E-6, 515.463871093, 0.591998446}, - { 0.000443E-6, 12168.002696575, 4.830881244}, - { 0.000570E-6, 199.072001436, 3.899190272}, - { 0.000465E-6, 10969.965257698, 0.476681802}, - { 0.000424E-6, -7079.373856808, 1.112242763}, - { 0.000427E-6, 735.876513532, 1.994214480}, - { 0.000478E-6, -6127.655450557, 3.778025483}, - { 0.000414E-6, 10973.555686350, 5.441088327}, - { 0.000512E-6, 1589.072895284, 0.107123853}, - { 0.000378E-6, 10984.192351700, 0.915087231}, - { 0.000402E-6, 11371.704689758, 4.107281715}, - { 0.000453E-6, 9917.696874510, 1.917490952}, - { 0.000395E-6, 149.563197135, 2.763124165}, - { 0.000371E-6, 5739.157790895, 3.112111866}, - { 0.000350E-6, 11790.629088659, 0.440639857}, - { 0.000356E-6, 6133.512652857, 5.444568842}, - { 0.000344E-6, 412.371096874, 5.676832684}, - { 0.000383E-6, 955.599741609, 5.559734846}, - { 0.000333E-6, 6496.374945429, 0.261537984}, - { 0.000340E-6, 6055.549660552, 5.975534987}, - { 0.000334E-6, 1066.495477190, 2.335063907}, - { 0.000399E-6, 11506.769769794, 5.321230910}, - { 0.000314E-6, 18319.536584880, 2.313312404}, - { 0.000424E-6, 1052.268383188, 1.211961766}, - { 0.000307E-6, 63.735898303, 3.169551388}, - { 0.000329E-6, 29.821438149, 6.106912080}, - { 0.000357E-6, 6309.374169791, 4.223760346}, - { 0.000312E-6, -3738.761430108, 2.180556645}, - { 0.000301E-6, 309.278322656, 1.499984572}, - { 0.000268E-6, 12043.574281889, 2.447520648}, - { 0.000257E-6, 12491.370101415, 3.662331761}, - { 0.000290E-6, 625.670192312, 1.272834584}, - { 0.000256E-6, 5429.879468239, 1.913426912}, - { 0.000339E-6, 3496.032826134, 4.165930011}, - { 0.000283E-6, 3930.209696220, 4.325565754}, - { 0.000241E-6, 12528.018664345, 3.832324536}, - { 0.000304E-6, 4686.889407707, 1.612348468}, - { 0.000259E-6, 16200.772724501, 3.470173146}, - { 0.000238E-6, 12139.553509107, 1.147977842}, - { 0.000236E-6, 6172.869528772, 3.776271728}, - { 0.000296E-6, -7058.598461315, 0.460368852}, - { 0.000306E-6, 10575.406682942, 0.554749016}, - { 0.000251E-6, 17298.182327326, 0.834332510}, - { 0.000290E-6, 4732.030627343, 4.759564091}, - { 0.000261E-6, 5884.926846583, 0.298259862}, - { 0.000249E-6, 5547.199336460, 3.749366406}, - { 0.000213E-6, 11712.955318231, 5.415666119}, - { 0.000223E-6, 4701.116501708, 2.703203558}, - { 0.000268E-6, -640.877607382, 0.283670793}, - { 0.000209E-6, 5636.065016677, 1.238477199}, - { 0.000193E-6, 10177.257679534, 1.943251340}, - { 0.000182E-6, 6283.143160294, 2.456157599}, - { 0.000184E-6, -227.526189440, 5.888038582}, - { 0.000182E-6, -6283.008539689, 0.241332086}, - { 0.000228E-6, -6284.056171060, 2.657323816}, - { 0.000166E-6, 7238.675591600, 5.930629110}, - { 0.000167E-6, 3097.883822726, 5.570955333}, - { 0.000159E-6, -323.505416657, 5.786670700}, - { 0.000154E-6, -4136.910433516, 1.517805532}, - { 0.000176E-6, 12029.347187887, 3.139266834}, - { 0.000167E-6, 12132.439962106, 3.556352289}, - { 0.000153E-6, 202.253395174, 1.463313961}, - { 0.000157E-6, 17267.268201691, 1.586837396}, - { 0.000142E-6, 83996.847317911, 0.022670115}, - { 0.000152E-6, 17260.154654690, 0.708528947}, - { 0.000144E-6, 6084.003848555, 5.187075177}, - { 0.000135E-6, 5756.566278634, 1.993229262}, - { 0.000134E-6, 5750.203491159, 3.457197134}, - { 0.000144E-6, 5326.786694021, 6.066193291}, - { 0.000160E-6, 11015.106477335, 1.710431974}, - { 0.000133E-6, 3634.621024518, 2.836451652}, - { 0.000134E-6, 18073.704938650, 5.453106665}, - { 0.000134E-6, 1162.474704408, 5.326898811}, - { 0.000128E-6, 5642.198242609, 2.511652591}, - { 0.000160E-6, 632.783739313, 5.628785365}, - { 0.000132E-6, 13916.019109642, 0.819294053}, - { 0.000122E-6, 14314.168113050, 5.677408071}, - { 0.000125E-6, 12359.966151546, 5.251984735}, - { 0.000121E-6, 5749.452731634, 2.210924603}, - { 0.000136E-6, -245.831646229, 1.646502367}, - { 0.000120E-6, 5757.317038160, 3.240883049}, - { 0.000134E-6, 12146.667056108, 3.059480037}, - { 0.000137E-6, 6206.809778716, 1.867105418}, - { 0.000141E-6, 17253.041107690, 2.069217456}, - { 0.000129E-6, -7477.522860216, 2.781469314}, - { 0.000116E-6, 5540.085789459, 4.281176991}, - { 0.000116E-6, 9779.108676125, 3.320925381}, - { 0.000129E-6, 5237.921013804, 3.497704076}, - { 0.000113E-6, 5959.570433334, 0.983210840}, - { 0.000122E-6, 6282.095528923, 2.674938860}, - { 0.000140E-6, -11.045700264, 4.957936982}, - { 0.000108E-6, 23543.230504682, 1.390113589}, - { 0.000106E-6, -12569.674818332, 0.429631317}, - { 0.000110E-6, -266.607041722, 5.501340197}, - { 0.000115E-6, 12559.038152982, 4.691456618}, - { 0.000134E-6, -2388.894020449, 0.577313584}, - { 0.000109E-6, 10440.274292604, 6.218148717}, - { 0.000102E-6, -543.918059096, 1.477842615}, - { 0.000108E-6, 21228.392023546, 2.237753948}, - { 0.000101E-6, -4535.059436924, 3.100492232}, - { 0.000103E-6, 76.266071276, 5.594294322}, - { 0.000104E-6, 949.175608970, 5.674287810}, - { 0.000101E-6, 13517.870106233, 2.196632348}, - { 0.000100E-6, 11933.367960670, 4.056084160}, - { 4.322990E-6, 6283.075849991, 2.642893748}, - { 0.406495E-6, 0.000000000, 4.712388980}, - { 0.122605E-6, 12566.151699983, 2.438140634}, - { 0.019476E-6, 213.299095438, 1.642186981}, - { 0.016916E-6, 529.690965095, 4.510959344}, - { 0.013374E-6, -3.523118349, 1.502210314}, - { 0.008042E-6, 26.298319800, 0.478549024}, - { 0.007824E-6, 155.420399434, 5.254710405}, - { 0.004894E-6, 5746.271337896, 4.683210850}, - { 0.004875E-6, 5760.498431898, 0.759507698}, - { 0.004416E-6, 5223.693919802, 6.028853166}, - { 0.004088E-6, -7.113547001, 0.060926389}, - { 0.004433E-6, 77713.771467920, 3.627734103}, - { 0.003277E-6, 18849.227549974, 2.327912542}, - { 0.002703E-6, 6062.663207553, 1.271941729}, - { 0.003435E-6, -775.522611324, 0.747446224}, - { 0.002618E-6, 6076.890301554, 3.633715689}, - { 0.003146E-6, 206.185548437, 5.647874613}, - { 0.002544E-6, 1577.343542448, 6.232904270}, - { 0.002218E-6, -220.412642439, 1.309509946}, - { 0.002197E-6, 5856.477659115, 2.407212349}, - { 0.002897E-6, 5753.384884897, 5.863842246}, - { 0.001766E-6, 426.598190876, 0.754113147}, - { 0.001738E-6, -796.298006816, 2.714942671}, - { 0.001695E-6, 522.577418094, 2.629369842}, - { 0.001584E-6, 5507.553238667, 1.341138229}, - { 0.001503E-6, -242.728603974, 0.377699736}, - { 0.001552E-6, -536.804512095, 2.904684667}, - { 0.001370E-6, -398.149003408, 1.265599125}, - { 0.001889E-6, -5573.142801634, 4.413514859}, - { 0.001722E-6, 6069.776754553, 2.445966339}, - { 0.001124E-6, 1059.381930189, 5.041799657}, - { 0.001258E-6, 553.569402842, 3.849557278}, - { 0.000831E-6, 951.718406251, 2.471094709}, - { 0.000767E-6, 4694.002954708, 5.363125422}, - { 0.000756E-6, 1349.867409659, 1.046195744}, - { 0.000775E-6, -11.045700264, 0.245548001}, - { 0.000597E-6, 2146.165416475, 4.543268798}, - { 0.000568E-6, 5216.580372801, 4.178853144}, - { 0.000711E-6, 1748.016413067, 5.934271972}, - { 0.000499E-6, 12036.460734888, 0.624434410}, - { 0.000671E-6, -1194.447010225, 4.136047594}, - { 0.000488E-6, 5849.364112115, 2.209679987}, - { 0.000621E-6, 6438.496249426, 4.518860804}, - { 0.000495E-6, -6286.598968340, 1.868201275}, - { 0.000456E-6, 5230.807466803, 1.271231591}, - { 0.000451E-6, 5088.628839767, 0.084060889}, - { 0.000435E-6, 5643.178563677, 3.324456609}, - { 0.000387E-6, 10977.078804699, 4.052488477}, - { 0.000547E-6, 161000.685737473, 2.841633844}, - { 0.000522E-6, 3154.687084896, 2.171979966}, - { 0.000375E-6, 5486.777843175, 4.983027306}, - { 0.000421E-6, 5863.591206116, 4.546432249}, - { 0.000439E-6, 7084.896781115, 0.522967921}, - { 0.000309E-6, 2544.314419883, 3.172606705}, - { 0.000347E-6, 4690.479836359, 1.479586566}, - { 0.000317E-6, 801.820931124, 3.553088096}, - { 0.000262E-6, 419.484643875, 0.606635550}, - { 0.000248E-6, 6836.645252834, 3.014082064}, - { 0.000245E-6, -1592.596013633, 5.519526220}, - { 0.000225E-6, 4292.330832950, 2.877956536}, - { 0.000214E-6, 7234.794256242, 1.605227587}, - { 0.000205E-6, 5767.611978898, 0.625804796}, - { 0.000180E-6, 10447.387839604, 3.499954526}, - { 0.000229E-6, 199.072001436, 5.632304604}, - { 0.000214E-6, 639.897286314, 5.960227667}, - { 0.000175E-6, -433.711737877, 2.162417992}, - { 0.000209E-6, 515.463871093, 2.322150893}, - { 0.000173E-6, 6040.347246017, 2.556183691}, - { 0.000184E-6, 6309.374169791, 4.732296790}, - { 0.000227E-6, 149854.400134205, 5.385812217}, - { 0.000154E-6, 8031.092263058, 5.120720920}, - { 0.000151E-6, 5739.157790895, 4.815000443}, - { 0.000197E-6, 7632.943259650, 0.222827271}, - { 0.000197E-6, 74.781598567, 3.910456770}, - { 0.000138E-6, 6055.549660552, 1.397484253}, - { 0.000149E-6, -6127.655450557, 5.333727496}, - { 0.000137E-6, 3894.181829542, 4.281749907}, - { 0.000135E-6, 9437.762934887, 5.979971885}, - { 0.000139E-6, -2352.866153772, 4.715630782}, - { 0.000142E-6, 6812.766815086, 0.513330157}, - { 0.000120E-6, -4705.732307544, 0.194160689}, - { 0.000131E-6, -71430.695617928, 0.000379226}, - { 0.000124E-6, 6279.552731642, 2.122264908}, - { 0.000108E-6, -6256.777530192, 0.883445696}, - { 0.143388E-6, 6283.075849991, 1.131453581}, - { 0.006671E-6, 12566.151699983, 0.775148887}, - { 0.001480E-6, 155.420399434, 0.480016880}, - { 0.000934E-6, 213.299095438, 6.144453084}, - { 0.000795E-6, 529.690965095, 2.941595619}, - { 0.000673E-6, 5746.271337896, 0.120415406}, - { 0.000672E-6, 5760.498431898, 5.317009738}, - { 0.000389E-6, -220.412642439, 3.090323467}, - { 0.000373E-6, 6062.663207553, 3.003551964}, - { 0.000360E-6, 6076.890301554, 1.918913041}, - { 0.000316E-6, -21.340641002, 5.545798121}, - { 0.000315E-6, -242.728603974, 1.884932563}, - { 0.000278E-6, 206.185548437, 1.266254859}, - { 0.000238E-6, -536.804512095, 4.532664830}, - { 0.000185E-6, 522.577418094, 4.578313856}, - { 0.000245E-6, 18849.227549974, 0.587467082}, - { 0.000180E-6, 426.598190876, 5.151178553}, - { 0.000200E-6, 553.569402842, 5.355983739}, - { 0.000141E-6, 5223.693919802, 1.336556009}, - { 0.000104E-6, 5856.477659115, 4.239842759}, - { 0.003826E-6, 6283.075849991, 5.705257275}, - { 0.000303E-6, 12566.151699983, 5.407132842}, - { 0.000209E-6, 155.420399434, 1.989815753} - }; - -/* -------------------------------------------------------------------- */ - -/* Local Variables: */ - double t, tsol, w, elsun, emsun, d, elj, els, wt, w0, w1, w2, w3, w4, - wf, wj; - int i; - - -/* Time since J2000.0 in Julian millennia. */ - t = ( tdb - 51544.5 )/365250; - - - -/* -------------------- Topocentric terms ----------------------------- */ - -/* Convert UT1 to local solar time in radians. */ - tsol = fmod( ut1, 1.0 )*D2PI - wl; - -/* FUNDAMENTAL ARGUMENTS: Simon et al 1994 */ - -/* Combine time argument (millennia ) with deg/arcsec factor. */ - w = t / 3600.0; - -/* Sun Mean Longitude. */ - elsun = fmod( 280.46645683 + 1296027711.03429*w, 360.0 )*D2R; - -/* Sun Mean Anomaly. */ - emsun = fmod( 357.52910918 + 1295965810.481*w, 360.0 )*D2R; - -/* Mean Elongation of Moon from Sun. */ - d = fmod( 297.85019547 + 16029616012.090*w, 360.0 )*D2R; - -/* Mean Longitude of Jupiter. */ - elj = fmod( 34.35151874 + 109306899.89453*w, 360.0 )*D2R; - -/* Mean Longitude of Saturn. */ - els = fmod( 50.07744430 + 44046398.47038*w, 360.0 )*D2R; - -/* TOPOCENTRIC TERMS: Moyer 1981 and Murray 1983. */ - wt = + 0.00029E-10*u*sin( tsol + elsun - els ) - + 0.00100E-10*u*sin( tsol - 2*emsun ) - + 0.00133E-10*u*sin( tsol - d ) - + 0.00133E-10*u*sin( tsol + elsun - elj ) - - 0.00229E-10*u*sin( tsol + 2*elsun + emsun ) - - 0.0220E-10*v*cos( elsun + emsun ) - + 0.05312E-10*u*sin( tsol - emsun ) - - 0.13677E-10*u*sin( tsol + 2*elsun ) - - 1.3184E-10*v*cos( elsun ) - + 3.17679E-10*u*sin( tsol ); - - - -/* --------------- Fairhead model --------------------------------------- */ - -/* t**0 */ - w0 = 0; - for( i = 473; i >= 0; i-- ) { - w0 = w0 + fairhd[ i ][ 0 ]*sin( fairhd[ i ][ 1 ]*t + fairhd[ i ][ 2 ] ); - } - -/* t**1 */ - w1 = 0; - for( i = 678; i >= 474; i-- ) { - w1 = w1 + fairhd[ i ][ 0 ]*sin( fairhd[ i ][ 1 ]*t + fairhd[ i ][ 2 ] ); - } - -/* t**2 */ - w2 = 0; - for( i = 763; i >= 679; i-- ) { - w2 = w2 + fairhd[ i ][ 0 ]*sin( fairhd[ i ][ 1 ]*t + fairhd[ i ][ 2 ] ); - } - -/* t**3 */ - w3 = 0; - for( i = 783; i >= 764; i-- ) { - w3 = w3 + fairhd[ i ][ 0 ]*sin( fairhd[ i ][ 1 ]*t + fairhd[ i ][ 2 ] ); - } - -/* t**4 */ - w4 = 0; - for( i = 786; i >= 784; i-- ) { - w4 = w4 + fairhd[ i ][ 0 ]*sin( fairhd[ i ][ 1 ]*t + fairhd[ i ][ 2 ] ); - } - -/* Multiply by powers of T and combine. */ - wf = t*( t*( t*( t*w4 + w3 ) + w2 ) + w1 ) + w0; - -/* Adjustments to use JPL planetary masses instead of IAU. */ - wj = 0.00065E-6 * sin( 6069.776754 *t + 4.021194 ) + - 0.00033E-6 * sin( 213.299095 *t + 5.543132 ) + - ( -0.00196E-6 * sin( 6208.294251 *t + 5.696701 ) ) + - ( -0.00173E-6 * sin( 74.781599 *t + 2.435900 ) ) + - 0.03638E-6*t*t; - - - -/* -------------------------------------------------------------------- */ - -/* Final result: TDB-TT in seconds. */ - return wt + wf + wj; - -} - -static void TimeAdd( AstTimeMap *this, const char *cvt, int narg, - const double args[], int *status ) { -/* -*++ -* Name: -c astTimeAdd -f AST_TIMEADD - -* Purpose: -* Add a time coordinate conversion to a TimeMap. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "timemap.h" -c void astTimeAdd( AstTimeMap *this, const char *cvt, int narg, -c const double args[] ) -f CALL AST_TIMEADD( THIS, CVT, NARG, ARGS, STATUS ) - -* Class Membership: -* TimeMap method. - -* Description: -c This function adds one of the standard time coordinate -f This routine adds one of the standard time coordinate -* system conversions listed below to an existing TimeMap. -* -c When a TimeMap is first created (using astTimeMap), it simply -f When a TimeMap is first created (using AST_TIMEMAP), it simply -c performs a unit (null) Mapping. By using astTimeAdd (repeatedly -f performs a unit (null) Mapping. By using AST_TIMEADD (repeatedly -* if necessary), one or more coordinate conversion steps may then -* be added, which the TimeMap will perform in sequence. This allows -* multi-step conversions between a variety of time coordinate -* systems to be assembled out of the building blocks provided by -* this class. -* -* Normally, if a TimeMap's Invert attribute is zero (the default), -* then its forward transformation is performed by carrying out -* each of the individual coordinate conversions specified by -c astTimeAdd in the order given (i.e. with the most recently added -f AST_TIMEADD in the order given (i.e. with the most recently added -* conversion applied last). -* -* This order is reversed if the TimeMap's Invert attribute is -* non-zero (or if the inverse transformation is requested by any -* other means) and each individual coordinate conversion is also -* replaced by its own inverse. This process inverts the overall -* effect of the TimeMap. In this case, the first conversion to be -* applied would be the inverse of the one most recently added. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the TimeMap. -c cvt -f CVT = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string which identifies the -f A character string which identifies the -* time coordinate conversion to be added to the -* TimeMap. See the "Available Conversions" section for details of -* those available. -c narg -f NARG = INTEGER (Given) -* The number of argument values supplied in the -c "args" array. -f ARGS array. -c args -f ARGS( * ) = DOUBLE PRECISION (Given) -* An array containing argument values for the time -* coordinate conversion. The number of arguments required, and -* hence the number of array elements used, depends on the -* conversion specified (see the "Available Conversions" -* section). This array is ignored -c and a NULL pointer may be supplied -* if no arguments are needed. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - When assembling a multi-stage conversion, it can sometimes be -* difficult to determine the most economical conversion path. A solution -* to this is to include all the steps which are (logically) necessary, -* but then to use -c astSimplify to simplify the resulting -f AST_SIMPLIFY to simplify the resulting -* TimeMap. The simplification process will eliminate any steps -* which turn out not to be needed. -c - This function does not check to ensure that the sequence of -f - This routine does not check to ensure that the sequence of -* coordinate conversions added to a TimeMap is physically -* meaningful. - -* Available Conversions: -* The following strings (which are case-insensitive) may be supplied -c via the "cvt" parameter to indicate which time coordinate -f via the CVT argument to indicate which time coordinate -* conversion is to be added to the TimeMap. Where arguments are needed by -* the conversion, they are listed in parentheses. Values for -c these arguments should be given, via the "args" array, in the -f these arguments should be given, via the ARGS array, in the -* order indicated. Units and argument names are described at the end of -* the list of conversions, and "MJD" means Modified Julian Date. -* -* - "MJDTOMJD" (MJDOFF1,MJDOFF2): Convert MJD from one offset to another. -* - "MJDTOJD" (MJDOFF,JDOFF): Convert MJD to Julian Date. -* - "JDTOMJD" (JDOFF,MJDOFF): Convert Julian Date to MJD. -* - "MJDTOBEP" (MJDOFF,BEPOFF): Convert MJD to Besselian epoch. -* - "BEPTOMJD" (BEPOFF,MJDOFF): Convert Besselian epoch to MJD. -* - "MJDTOJEP" (MJDOFF,JEPOFF): Convert MJD to Julian epoch. -* - "JEPTOMJD" (JEPOFF,MJDOFF): Convert Julian epoch to MJD. -* - "TAITOUTC" (MJDOFF,DTAI): Convert a TAI MJD to a UTC MJD. -* - "UTCTOTAI" (MJDOFF,DTAI): Convert a UTC MJD to a TAI MJD. -* - "TAITOTT" (MJDOFF): Convert a TAI MJD to a TT MJD. -* - "TTTOTAI" (MJDOFF): Convert a TT MJD to a TAI MJD. -* - "TTTOTDB" (MJDOFF,OBSLON,OBSLAT,OBSALT,DTAI): Convert a TT MJD to a TDB MJD. -* - "TDBTOTT" (MJDOFF,OBSLON,OBSLAT,OBSALT,DTAI): Convert a TDB MJD to a TT MJD. -* - "TTTOTCG" (MJDOFF): Convert a TT MJD to a TCG MJD. -* - "TCGTOTT" (MJDOFF): Convert a TCG MJD to a TT MJD. -* - "TDBTOTCB" (MJDOFF): Convert a TDB MJD to a TCB MJD. -* - "TCBTOTDB" (MJDOFF): Convert a TCB MJD to a TDB MJD. -* - "UTTOGMST" (MJDOFF): Convert a UT MJD to a GMST MJD. -* - "GMSTTOUT" (MJDOFF): Convert a GMST MJD to a UT MJD. -* - "GMSTTOLMST" (MJDOFF,OBSLON,OBSLAT): Convert a GMST MJD to a LMST MJD. -* - "LMSTTOGMST" (MJDOFF,OBSLON,OBSLAT): Convert a LMST MJD to a GMST MJD. -* - "LASTTOLMST" (MJDOFF,OBSLON,OBSLAT): Convert a GMST MJD to a LMST MJD. -* - "LMSTTOLAST" (MJDOFF,OBSLON,OBSLAT): Convert a LMST MJD to a GMST MJD. -* - "UTTOUTC" (DUT1): Convert a UT1 MJD to a UTC MJD. -* - "UTCTOUT" (DUT1): Convert a UTC MJD to a UT1 MJD. -* - "LTTOUTC" (LTOFF): Convert a Local Time MJD to a UTC MJD. -* - "UTCTOLT" (LTOFF): Convert a UTC MJD to a Local Time MJD. -* -* The units for the values processed by the above conversions are as -* follows: -* -* - Julian epochs and offsets: Julian years -* - Besselian epochs and offsets: Tropical years -* - Modified Julian Dates and offsets: days -* - Julian Dates and offsets: days -* -* The arguments used in the above conversions are the zero-points -* used by the -c astTransform function. -f AST_TRANSFORM routine. -* The axis values supplied and returned by -c astTransform -f AST_TRANSFORM -* are offsets away from these zero-points: -* -* - MJDOFF: The zero-point being used with MJD values. -* - JDOFF: The zero-point being used with Julian Date values. -* - BEPOFF: The zero-point being used with Besselian epoch values. -* - JEPOFF: The zero-point being used with Julian epoch values. -* - OBSLON: Observer longitude in radians (+ve westwards). -* - OBSLAT: Observer geodetic latitude (IAU 1975) in radians (+ve northwards). -* - OBSALT: Observer geodetic altitude (IAU 1975) in metres. -* - DTAI: The value of TAI-UTC (the value returned by astDat is used if -* DTAI is AST__BAD). -* - DUT1: The UT1-UTC value to use. -* - LTOFF: The offset between Local Time and UTC (in hours, positive -* for time zones east of Greenwich). -*-- -*/ - -/* Local Variables: */ - int cvttype; /* Conversion type code */ - -/* Check the inherited status. */ - if ( !astOK ) return; - -/* Validate the type string supplied and obtain the equivalent - conversion type code. */ - cvttype = CvtCode( cvt, status ); - -/* If the string was not recognised, then report an error. */ - if ( astOK && ( cvttype == AST__TIME_NULL ) ) { - astError( AST__TIMIN, - "%s(%s): Invalid TimeMap time coordinate " - "conversion type \"%s\".", status, "astAddTime", astGetClass( this ), cvt ); - } - -/* Add the new conversion to the TimeMap. */ - AddTimeCvt( this, cvttype, narg, args, status ); -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a TimeMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* TimeMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a TimeMap and a set of points encapsulated -* in a PointSet and transforms the points so as to perform the -* sequence of time coordinate conversions specified by -* previous invocations of astTimeAdd. - -* Parameters: -* this -* Pointer to the TimeMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the TimeMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstTimeMap *map; /* Pointer to TimeMap to be applied */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *args; /* Pointer to argument list for conversion */ - double *time; /* Pointer to output time axis value array */ - double gmstx; /* GMST offset (in days) */ - double tai; /* Absolute TAI value (in days) */ - double tdb; /* Absolute TDB value (in days) */ - double tt; /* Absolute TT value (in days) */ - double utc; /* Absolute UTC value (in days) */ - int ct; /* Conversion type */ - int cvt; /* Loop counter for conversions */ - int end; /* Termination index for conversion loop */ - int inc; /* Increment for conversion loop */ - int npoint; /* Number of points */ - int point; /* Loop counter for points */ - int start; /* Starting index for conversion loop */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the TimeMap. */ - map = (AstTimeMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - coordinate conversions needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse transformation, according - to the direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( this ) ) forward = !forward; - -/* Transform the coordinate values. */ -/* -------------------------------- */ -/* Use "time" as a synonym for the array of time axis values stored in - the output PointSet. */ - if ( astOK ) { - time = ptr_out[ 0 ]; - -/* Initialise the output coordinate values by copying the input ones. */ - if( time != ptr_in[ 0 ] ) { - (void) memcpy( time, ptr_in[ 0 ], sizeof( double ) * (size_t) npoint ); - } - -/* We will loop to apply each time coordinate conversion in turn to the - (time) array. However, if the inverse transformation was requested, - we must loop through these transformations in reverse order, so set up - appropriate limits and an increment to control this loop. */ - start = forward ? 0 : map->ncvt - 1; - end = forward ? map->ncvt : -1; - inc = forward ? 1 : -1; - -/* Loop through the coordinate conversions in the required order and obtain a - pointer to the argument list for the current conversion. */ - for ( cvt = start; cvt != end; cvt += inc ) { - args = map->cvtargs[ cvt ]; - -/* Classify the SLALIB sky coordinate conversion to be applied. */ - ct = map->cvttype[ cvt ]; - switch ( ct ) { - -/* MJD to MJD. */ -/* ---------- */ - case AST__MJDTOMJD: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += args[ 2 ]; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= args[ 2 ]; - } - } - } - break; - -/* MJD to JD. */ -/* ---------- */ - case AST__MJDTOJD: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += args[ 2 ]; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= args[ 2 ]; - } - } - } - break; - -/* JD to MJD. */ -/* ---------- */ - case AST__JDTOMJD: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += args[ 2 ]; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= args[ 2 ]; - } - } - } - break; - -/* MJD to Besselian epoch. */ -/* ----------------------- */ - case AST__MJDTOBEP: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = palEpb( time[ point ] ) + args[ 2 ]; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = palEpb2d( time[ point ] ) + args[ 3 ]; - } - } - } - break; - -/* Besselian epoch to MJD. */ -/* ----------------------- */ - case AST__BEPTOMJD: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = palEpb2d( time[ point ] ) + args[ 2 ]; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = palEpb( time[ point ] ) + args[ 3 ]; - } - } - } - break; - -/* MJD to Julian epoch. */ -/* -------------------- */ - case AST__MJDTOJEP: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = palEpj( time[ point ] ) + args[ 2 ]; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = palEpj2d( time[ point ] ) + args[ 3 ]; - } - } - } - break; - -/* Julian epoch to MJD. */ -/* -------------------- */ - case AST__JEPTOMJD: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = palEpj2d( time[ point ] ) + args[ 2 ]; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = palEpj( time[ point ] ) + args[ 3 ]; - } - } - } - break; - -/* TAI to UTC. */ -/* ----------- */ - case AST__TAITOUTC: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += ( (args[ 1 ] == AST__BAD) - ? astDat( time[ point ] + args[ 0 ], 0 ) - : - args[ 1 ] )/SPD; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += ( (args[ 1 ] == AST__BAD) - ? astDat( time[ point ] + args[ 0 ], 1 ) - : args[ 1 ] )/SPD; - } - } - } - break; - -/* UTC to TAI. */ -/* ----------- */ - case AST__UTCTOTAI: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += ( (args[ 1 ] == AST__BAD) - ? astDat( time[ point ] + args[ 0 ], 1 ) - : args[ 1 ] )/SPD; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += ( (args[ 1 ] == AST__BAD) - ? astDat( time[ point ] + args[ 0 ], 0 ) - : - args[ 1 ] )/SPD; - } - } - } - break; - -/* TAI to TT. */ -/* ---------- */ - case AST__TAITOTT: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += (TTOFF/SPD); - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= (TTOFF/SPD); - } - } - } - break; - -/* TT to TAI. */ -/* ---------- */ - case AST__TTTOTAI: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= (TTOFF/SPD); - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += (TTOFF/SPD); - } - } - } - break; - -/* TT to TDB. */ -/* ---------- */ -/* For the purpose of estimating TDB-TT, we assume UTC is a good approximation - to UT1, and that TT is a good approximation to TDB. In fact, TAI is - probably a good enough approximation to UTC for the vast majority of - cases, but for completeness we handle the difference between TAI and - UTC (i.e. leap seconds) here. */ - case AST__TTTOTDB: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - tt = time[ point ] + args[ 0 ]; - tai = tt - (TTOFF/SPD); - utc = tai + ( (args[ 4 ] == AST__BAD) ? astDat( tai, 0 ) - : -args[ 4 ] )/SPD; - time[ point ] += Rcc( tt, utc, args[ 1 ], args[ 5 ], - args[ 6 ], status )/SPD; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - tdb = time[ point ] + args[ 0 ]; - tai = tdb - (TTOFF/SPD); - utc = tai + ( (args[ 4 ] == AST__BAD) ? astDat( tai, 0 ) - : -args[ 4 ] )/SPD; - time[ point ] -= Rcc( tdb, utc, args[ 1 ], args[ 5 ], - args[ 6 ], status )/SPD; - } - } - } - break; - -/* TDB to TT. */ -/* ---------- */ -/* For the purpose of estimating TDB-TT, we assume UTC is a good approximation - to UT1, and that TT is a good approximation to TDB. In fact, TAI is - probably a good enough approximation to UTC for the vast majority of - cases, but for completeness we handle the difference between TAI and - UTC (i.e. leap seconds) here. */ - case AST__TDBTOTT: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - tdb = time[ point ] + args[ 0 ]; - tai = tdb - (TTOFF/SPD); - utc = tai + ( (args[ 4 ] == AST__BAD) ? astDat( tai, 0 ) - : -args[ 4 ] )/SPD; - time[ point ] -= Rcc( tdb, utc, args[ 1 ], args[ 5 ], - args[ 6 ], status )/SPD; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - tt = time[ point ] + args[ 0 ]; - tai = tt - (TTOFF/SPD); - utc = tai + ( (args[ 4 ] == AST__BAD) ? astDat( tai, 0 ) - : -args[ 4 ] )/SPD; - time[ point ] += Rcc( tt, utc, args[ 1 ], args[ 5 ], - args[ 6 ], status )/SPD; - } - } - } - break; - -/* TT to TCG. */ -/* ---------- */ - case AST__TTTOTCG: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += time[ point ]*LG + args[ 1 ]; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = ( time[ point ] - args[ 1 ] ) / - ( 1.0 + LG ); - } - } - } - break; - -/* TCG to TT. */ -/* ---------- */ - case AST__TCGTOTT: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = ( time[ point ] - args[ 1 ] ) / - ( 1.0 + LG ); - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += time[ point ]*LG + args[ 1 ]; - } - } - } - break; - -/* TDB to TCB. */ -/* ----------- */ -/* For the purpose of estimating TDB-TT, we assume UTC is a good approximation - to UT1, and that TT is a good approximation to both TDB and TCB. */ - case AST__TDBTOTCB: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += time[ point ]*LB + args[ 1 ]; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = ( time[ point ] - args[ 1 ] ) / - ( 1.0 + LB ); - } - } - } - break; - -/* TCB to TDB. */ -/* ----------- */ -/* For the purpose of estimating TDB-TT, we assume UTC is a good approximation - to UT1, and that TT is a good approximation to TDB. */ - case AST__TCBTOTDB: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = ( time[ point ] - args[ 1 ] ) / - ( 1.0 + LB ); - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += time[ point ]*LB + args[ 1 ]; - } - } - } - break; - -/* UT to GMST . */ -/* ------------ */ - case AST__UTTOGMST: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = Gmsta( time[ point ], args[ 0 ], 1, status ); - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = Gmsta( time[ point ], args[ 0 ], 0, status ); - } - } - } - break; - -/* GMST to UT. */ -/* ----------- */ - case AST__GMSTTOUT: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = Gmsta( time[ point ], args[ 0 ], 0, status ); - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] = Gmsta( time[ point ], args[ 0 ], 1, status ); - } - } - } - break; - -/* GMST to LMST. */ -/* ------------- */ - case AST__GMSTTOLMST: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= args[ 1 ]/D2PI; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += args[ 1 ]/D2PI; - } - } - } - break; - -/* LMST to GMST. */ -/* ------------- */ - case AST__LMSTTOGMST: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += args[ 1 ]/D2PI; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= args[ 1 ]/D2PI; - } - } - } - break; - -/* UT1 to UTC. */ -/* ------------- */ - case AST__UTTOUTC: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= args[ 0 ]/86400.0; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += args[ 0 ]/86400.0; - } - } - } - break; - - -/* UTC to UT1. */ -/* ------------- */ - case AST__UTCTOUT: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += args[ 0 ]/86400.0; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= args[ 0 ]/86400.0; - } - } - } - break; - -/* LT to UTC. */ -/* ---------- */ - case AST__LTTOUTC: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= args[ 0 ]/24.0; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += args[ 0 ]/24.0; - } - } - } - break; - - -/* UTC to LT. */ -/* ---------- */ - case AST__UTCTOLT: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] += args[ 0 ]/24.0; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - time[ point ] -= args[ 0 ]/24.0; - } - } - } - break; - -/* LMST to LAST. */ -/* ------------- */ -/* Calculating the equation of the equinoxes required TDB. So we need to - convert the given LMST to TDB. We first convert LMST to UT1. UT1 is - equal to UTC to within 1 second. We then add on 32 seconds to get TAI - (this value is correct since 1999 - for earlier epochs an error of the - order of a minute will be introduced in the TAI value). We then add on - TTOFF seconds to get TT. This TT is then used as an approximation to - TDB. The total error in TDB is of the order of a few minutes, which - corresponds to an error of a few tens of microseconds in the equation of - the equinoxes. The sla precession-nutation model is accurate to around 3 - mas = 200 us, so the error in TDB will be insignificant. */ - case AST__LMSTTOLAST: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - gmstx = time[ point ] + args[ 1 ]/D2PI; - tdb = Gmsta( gmstx, args[ 0 ], 0, status ) - + args[ 0 ] + (32 + TTOFF)/SPD; - time[ point ] += palEqeqx( tdb )/D2PI; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - gmstx = time[ point ] + args[ 1 ]/D2PI; - tdb = Gmsta( gmstx, args[ 0 ], 0, status ) - + args[ 0 ] + (32+TTOFF)/SPD; - time[ point ] -= palEqeqx( tdb )/D2PI; - } - } - } - break; - -/* LAST to LMST. */ -/* ------------- */ - case AST__LASTTOLMST: - if ( forward ) { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - gmstx = time[ point ] + args[ 1 ]/D2PI; - tdb = Gmsta( gmstx, args[ 0 ], 0, status ) - + args[ 0 ] + (32+TTOFF)/SPD; - time[ point ] -= palEqeqx( tdb )/D2PI; - } - } - } else { - for ( point = 0; point < npoint; point++ ) { - if ( time[ point ] != AST__BAD ) { - gmstx = time[ point ] + args[ 1 ]/D2PI; - tdb = Gmsta( gmstx, args[ 0 ], 0, status ) - + args[ 0 ] + (32 + TTOFF)/SPD; - time[ point ] += palEqeqx( tdb )/D2PI; - } - } - } - - } - } - } - -/* If an error has occurred and a new PointSet may have been created, then - clean up by annulling it. In any case, ensure that a NULL result is - returned.*/ - if ( !astOK ) { - if ( !out ) result = astAnnul( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for TimeMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for TimeMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstTimeMap *in; /* Pointer to input TimeMap */ - AstTimeMap *out; /* Pointer to output TimeMap */ - int cvt; /* Loop counter for coordinate conversions */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output TimeMap structures. */ - in = (AstTimeMap *) objin; - out = (AstTimeMap *) objout; - -/* For safety, first clear any references to the input memory from the output - TimeMap. */ - out->cvtargs = NULL; - out->cvttype = NULL; - -/* Allocate memory for the output array of argument list pointers. */ - out->cvtargs = astMalloc( sizeof( double * ) * (size_t) in->ncvt ); - -/* If necessary, allocate memory and make a copy of the input array of - coordinate conversion codes. */ - if ( in->cvttype ) out->cvttype = astStore( NULL, in->cvttype, - sizeof( int ) - * (size_t) in->ncvt ); - -/* If OK, loop through each conversion in the input TimeMap and make a copy of - its argument list, storing the new pointer in the output argument list - array. */ - if ( astOK ) { - for ( cvt = 0; cvt < in->ncvt; cvt++ ) { - out->cvtargs[ cvt ] = astStore( NULL, in->cvtargs[ cvt ], - astSizeOf( in->cvtargs[ cvt ] ) ); - } - -/* If an error occurred while copying the argument lists, loop through the - conversions again and clean up by ensuring that the new memory allocated for - each argument list is freed. */ - if ( !astOK ) { - for ( cvt = 0; cvt < in->ncvt; cvt++ ) { - out->cvtargs[ cvt ] = astFree( out->cvtargs[ cvt ] ); - } - } - } - -/* If an error occurred, free all other memory allocated above. */ - if ( !astOK ) { - out->cvtargs = astFree( out->cvtargs ); - out->cvttype = astFree( out->cvttype ); - } -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for TimeMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for TimeMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstTimeMap *this; /* Pointer to TimeMap */ - int cvt; /* Loop counter for coordinate conversions */ - -/* Obtain a pointer to the TimeMap structure. */ - this = (AstTimeMap *) obj; - -/* Loop to free the memory containing the argument list for each coordinate - conversion. */ - for ( cvt = 0; cvt < this->ncvt; cvt++ ) { - this->cvtargs[ cvt ] = astFree( this->cvtargs[ cvt ] ); - } - -/* Free the memory holding the array of conversion types and the array of - argument list pointers. */ - this->cvtargs = astFree( this->cvtargs ); - this->cvttype = astFree( this->cvttype ); -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for TimeMap objects. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the TimeMap class to an output Channel. - -* Parameters: -* this -* Pointer to the TimeMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstTimeMap *this; /* Pointer to the TimeMap structure */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - const char *argdesc[ MAX_ARGS ]; /* Pointers to argument descriptions */ - const char *comment; /* Pointer to comment string */ - const char *sval; /* Pointer to string value */ - int iarg; /* Internal index of argument */ - int icvt; /* Loop counter for conversion steps */ - int ival; /* Integer value */ - int jarg; /* External index of argument */ - int nargs; /* Number of user-supplied arguments */ - int *order; /* Order in which to store arguments */ - int szargs; /* Number of stored arguments */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TimeMap structure. */ - this = (AstTimeMap *) this_object; - -/* Write out values representing the instance variables for the TimeMap - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Number of conversion steps. */ -/* --------------------------- */ -/* Regard this as "set" if it is non-zero. */ - ival = this->ncvt; - set = ( ival != 0 ); - astWriteInt( channel, "Ntime", set, 0, ival, "Number of conversion steps" ); - -/* Write out data for each conversion step... */ - for ( icvt = 0; icvt < this->ncvt; icvt++ ) { - -/* Conversion type. */ -/* ---------------- */ -/* Change each conversion type code into an equivalent string and - obtain associated descriptive information. If the conversion code - was not recognised, report an error and give up. */ - if ( astOK ) { - sval = CvtString( this->cvttype[ icvt ], &comment, - &nargs, &szargs, argdesc, &order, status ); - if ( astOK && !sval ) { - astError( AST__TIMIN, - "astWrite(%s): Corrupt %s contains invalid TimeMap " - "time coordinate conversion code (%d).", status, - astGetClass( channel ), astGetClass( this ), - (int) this->cvttype[ icvt ] ); - break; - } - -/* Create an appropriate keyword and write out the conversion code - information. */ - (void) sprintf( key, "Time%d", icvt + 1 ); - astWriteString( channel, key, 1, 1, sval, comment ); - -/* Write out data for each conversion argument... */ - for ( iarg = 0; iarg < szargs; iarg++ ) { - -/* The "iarg" value is the index of the argument within the external - argument list. Get the index of the argument within the internal - argument list. */ - jarg = order ? order[ iarg ] : iarg; - -/* Arguments. */ -/* ---------- */ -/* Create an appropriate keyword and write out the argument value, - accompanied by the descriptive comment obtained above. */ - if( this->cvtargs[ icvt ][ jarg ] != AST__BAD ) { - (void) sprintf( key, "Time%d%c", icvt + 1, ALPHABET[ iarg ] ); - astWriteDouble( channel, key, 1, 1, this->cvtargs[ icvt ][ jarg ], - argdesc[ jarg ] ); - } - } - -/* Free the order array. */ - order = astFree( order ); - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - } - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsATimeMap and astCheckTimeMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(TimeMap,Mapping) -astMAKE_CHECK(TimeMap) - -AstTimeMap *astTimeMap_( int flags, const char *options, int *status, ...) { -/* -*++ -* Name: -c astTimeMap -f AST_TIMEMAP - -* Purpose: -* Create a TimeMap. - -* Type: -* Public function. - -* Synopsis: -c #include "timemap.h" -c AstTimeMap *astTimeMap( int flags, const char *options, ... ) -f RESULT = AST_TIMEMAP( FLAGS, OPTIONS, STATUS ) - -* Class Membership: -* TimeMap constructor. - -* Description: -* This function creates a new TimeMap and optionally initialises -* its attributes. -* -* A TimeMap is a specialised form of 1-dimensional Mapping which can be -* used to represent a sequence of conversions between standard time -* coordinate systems. -* -* When a TimeMap is first created, it simply performs a unit -c (null) Mapping. Using the astTimeAdd -f (null) Mapping. Using the AST_TIMEADD -c function, a series of coordinate conversion steps may then be -f routine, a series of coordinate conversion steps may then be -* added. This allows multi-step conversions between a variety of -* time coordinate systems to be assembled out of a set of building -* blocks. -* -* For details of the individual coordinate conversions available, -c see the description of the astTimeAdd function. -f see the description of the AST_TIMEADD routine. - -* Parameters: -c flags -f FLAGS = INTEGER (Given) -c This parameter is reserved for future use and should currently -f This argument is reserved for future use and should currently -* always be set to zero. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new TimeMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new TimeMap. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astTimeMap() -f AST_TIMEMAP = INTEGER -* A pointer to the new TimeMap. - -* Notes: -* - The nature and units of the coordinate values supplied for the -* first input (i.e. the time input) of a TimeMap must be appropriate -* to the first conversion step applied by the TimeMap. For instance, if -* the first conversion step is "MJDTOBEP" (Modified Julian Date to -* Besselian epoch) then the coordinate values for the first input should -* be date in units of days. Similarly, the nature and units of the -* coordinate values returned by a TimeMap will be determined by the -* last conversion step applied by the TimeMap. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstTimeMap *new; /* Pointer to the new TimeMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the TimeMap, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitTimeMap( NULL, sizeof( AstTimeMap ), !class_init, &class_vtab, - "TimeMap", flags ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new TimeMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new TimeMap. */ - return new; -} - -AstTimeMap *astTimeMapId_( int flags, const char *options, ... ) { -/* -* Name: -* astTimeMapId_ - -* Purpose: -* Create a TimeMap. - -* Type: -* Private function. - -* Synopsis: -* #include "timemap.h" -* AstTimeMap *astTimeMapId_( int flags, const char *options, ... ) - -* Class Membership: -* TimeMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astTimeMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astTimeMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astTimeMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astTimeMap_. - -* Returned Value: -* The ID value associated with the new TimeMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstTimeMap *new; /* Pointer to the new TimeMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the TimeMap, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitTimeMap( NULL, sizeof( AstTimeMap ), !class_init, &class_vtab, - "TimeMap", flags ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new TimeMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new TimeMap. */ - return astMakeId( new ); -} - -AstTimeMap *astInitTimeMap_( void *mem, size_t size, int init, - AstTimeMapVtab *vtab, const char *name, - int flags, int *status ) { -/* -*+ -* Name: -* astInitTimeMap - -* Purpose: -* Initialise a TimeMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "timemap.h" -* AstTimeMap *astInitTimeMap( void *mem, size_t size, int init, -* AstTimeMapVtab *vtab, const char *name, -* int flags ) - -* Class Membership: -* TimeMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new TimeMap object. It allocates memory (if necessary) to accommodate -* the TimeMap plus any additional data associated with the derived class. -* It then initialises a TimeMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a TimeMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the TimeMap is to be initialised. -* This must be of sufficient size to accommodate the TimeMap data -* (sizeof(TimeMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the TimeMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the TimeMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the TimeMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new TimeMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astClass -* method). -* flags -* This parameter is reserved for future use. It is currently ignored. - -* Returned Value: -* A pointer to the new TimeMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstTimeMap *new; /* Pointer to the new TimeMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitTimeMapVtab( vtab, name ); - -/* Initialise a 1D Mapping structure (the parent class) as the first component - within the TimeMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstTimeMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - 1, 1, 1, 1 ); - - if ( astOK ) { - -/* Initialise the TimeMap data. */ -/* --------------------------- */ -/* The initial state is with no conversions set, in which condition the - TimeMap simply implements a unit mapping. */ - new->ncvt = 0; - new->cvtargs = NULL; - new->cvttype = NULL; - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstTimeMap *astLoadTimeMap_( void *mem, size_t size, - AstTimeMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadTimeMap - -* Purpose: -* Load a TimeMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "timemap.h" -* AstTimeMap *astLoadTimeMap( void *mem, size_t size, -* AstTimeMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* TimeMap loader. - -* Description: -* This function is provided to load a new TimeMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* TimeMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a TimeMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the TimeMap is to be -* loaded. This must be of sufficient size to accommodate the -* TimeMap data (sizeof(TimeMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the TimeMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the TimeMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstTimeMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new TimeMap. If this is NULL, a pointer to -* the (static) virtual function table for the TimeMap class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "TimeMap" is used instead. - -* Returned Value: -* A pointer to the new TimeMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstTimeMap *new; /* Pointer to the new TimeMap */ - char *sval; /* Pointer to string value */ - char key[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - const char *argdesc[ MAX_ARGS ]; /* Pointers to argument descriptions */ - const char *comment; /* Pointer to comment string */ - int iarg; /* Internal index of argument */ - int icvt; /* Loop counter for conversion steps */ - int jarg; /* External index of argument */ - int *order; /* Order in which to store arguments */ - int nargs; /* Number of user-supplied arguments */ - int szargs; /* Number of stored arguments */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this TimeMap. In this case the - TimeMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstTimeMap ); - vtab = &class_vtab; - name = "TimeMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitTimeMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built TimeMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "TimeMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Number of conversion steps. */ -/* --------------------------- */ -/* Read the number of conversion steps and allocate memory to hold - data for each step. */ - new->ncvt = astReadInt( channel, "ntime", 0 ); - if ( new->ncvt < 0 ) new->ncvt = 0; - new->cvttype = astMalloc( sizeof( int ) * (size_t) new->ncvt ); - new->cvtargs = astMalloc( sizeof( double * ) * (size_t) new->ncvt ); - -/* If an error occurred, ensure that all allocated memory is freed. */ - if ( !astOK ) { - new->cvttype = astFree( new->cvttype ); - new->cvtargs = astFree( new->cvtargs ); - -/* Otherwise, initialise the argument pointer array. */ - } else { - for ( icvt = 0; icvt < new->ncvt; icvt++ ) { - new->cvtargs[ icvt ] = NULL; - } - -/* Read in data for each conversion step... */ - for ( icvt = 0; icvt < new->ncvt; icvt++ ) { - -/* Conversion type. */ -/* ---------------- */ -/* Create an appropriate keyword and read the string representation of - the conversion type. */ - (void) sprintf( key, "time%d", icvt + 1 ); - sval = astReadString( channel, key, NULL ); - -/* If no value was read, report an error. */ - if ( astOK ) { - if ( !sval ) { - astError( AST__BADIN, - "astRead(%s): A time coordinate conversion " - "type is missing from the input TimeMap data.", status, - astGetClass( channel ) ); - -/* Otherwise, convert the string representation into the required - conversion type code. */ - } else { - new->cvttype[ icvt ] = CvtCode( sval, status ); - -/* If the string was not recognised, report an error. */ - if ( new->cvttype[ icvt ] == AST__TIME_NULL ) { - astError( AST__BADIN, - "astRead(%s): Invalid time conversion " - "type \"%s\" in TimeMap data.", status, - astGetClass( channel ), sval ); - } - } - -/* Free the memory holding the string value. */ - sval = astFree( sval ); - } - -/* Obtain the number of arguments associated with the conversion and - allocate memory to hold them. */ - (void) CvtString( new->cvttype[ icvt ], &comment, - &nargs, &szargs, argdesc, &order, status ); - new->cvtargs[ icvt ] = astMalloc( sizeof( double ) * - (size_t) szargs ); - -/* Read in data for each argument... */ - if ( astOK ) { - for ( iarg = 0; iarg < szargs; iarg++ ) { - -/* The "iarg" value is the index of the argument within the external - argument list. Get the index of the argument within the internal - argument list. */ - jarg = order ? order[ iarg ] : iarg; - -/* Arguments. */ -/* ---------- */ -/* Create an appropriate keyword and read each argument value. */ - (void) sprintf( key, "time%d%c", icvt + 1, ALPHABET[ iarg ] ); - new->cvtargs[ icvt ][ jarg ] = astReadDouble( channel, key, - AST__BAD ); - } - } - -/* Free the order array. */ - order = astFree( order ); - -/* Quit looping if an error occurs. */ - if ( !astOK ) break; - } - } - -/* If an error occurred, clean up by deleting the new TimeMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new TimeMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -void astTimeAdd_( AstTimeMap *this, const char *cvt, int narg, const double args[], - int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,TimeMap,TimeAdd))( this, cvt, narg, args, status ); -} - - - - diff --git a/ast/timemap.h b/ast/timemap.h deleted file mode 100644 index fa24730..0000000 --- a/ast/timemap.h +++ /dev/null @@ -1,285 +0,0 @@ -#if !defined( TIMEMAP_INCLUDED ) /* Include this file only once */ -#define TIMEMAP_INCLUDED -/* -*+ -* Name: -* timemap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the TimeMap class. - -* Invocation: -* #include "timemap.h" - -* Description: -* This include file defines the interface to the TimeMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The TimeMap class encapsulates various time coordinate -* conversions. Since, typically, a sequence of these conversions is -* required, a TimeMap can be used to accumulate a series of conversions -* which it then applies in sequence. - -* Inheritance: -* The TimeMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* astTransform -* Use an TimeMap to transform a set of points. - -* Protected: -* astMapMerge -* Simplify a sequence of Mappings containing an TimeMap. - -* New Methods Defined: -* Public: -* astTimeAdd -* Add a coordinate conversion step to an TimeMap. - -* Private: -* None. - -* Other Class Functions: -* Public: -* astIsATimeMap -* Test class membership. -* astTimeMap -* Create an TimeMap. - -* Protected: -* astCheckTimeMap -* Validate class membership. -* astInitTimeMap -* Initialise an TimeMap. -* astLoadTimeMap -* Load an TimeMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstTimeMap -* TimeMap object type. - -* Protected: -* AstTimeMapVtab -* TimeMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 24-MAY-2005 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* TimeMap structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstTimeMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int *cvttype; /* Pointer to array of conversion types */ - double **cvtargs; /* Pointer to argument list pointer array */ - int ncvt; /* Number of conversions to perform */ -} AstTimeMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstTimeMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - void (* TimeAdd)( AstTimeMap *, const char *, int, const double[], int * ); -} AstTimeMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstTimeMapGlobals { - AstTimeMapVtab Class_Vtab; - int Class_Init; -} AstTimeMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitTimeMapGlobals_( AstTimeMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(TimeMap) /* Check class membership */ -astPROTO_ISA(TimeMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstTimeMap *astTimeMap_( int, const char *, int *, ...); -#else -AstTimeMap *astTimeMapId_( int, const char *, ... )__attribute__((format(printf,2,3))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstTimeMap *astInitTimeMap_( void *, size_t, int, AstTimeMapVtab *, - const char *, int, int * ); - -/* Vtab initialiser. */ -void astInitTimeMapVtab_( AstTimeMapVtab *, const char *, int * ); - -/* Loader. */ -AstTimeMap *astLoadTimeMap_( void *, size_t, AstTimeMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -void astTimeAdd_( AstTimeMap *, const char *, int, const double[], int * ); - -#if defined(astCLASS) /* Protected. */ -double astDat_( double, int, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckTimeMap(this) astINVOKE_CHECK(TimeMap,this,0) -#define astVerifyTimeMap(this) astINVOKE_CHECK(TimeMap,this,1) - -/* Test class membership. */ -#define astIsATimeMap(this) astINVOKE_ISA(TimeMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astTimeMap astINVOKE(F,astTimeMap_) -#else -#define astTimeMap astINVOKE(F,astTimeMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitTimeMap(mem,size,init,vtab,name,flags) \ -astINVOKE(O,astInitTimeMap_(mem,size,init,vtab,name,flags,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitTimeMapVtab(vtab,name) astINVOKE(V,astInitTimeMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadTimeMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadTimeMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckTimeMap to validate TimeMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -#define astTimeAdd(this,cvt,narg,args) \ -astINVOKE(V,astTimeAdd_(astCheckTimeMap(this),cvt,narg,args,STATUS_PTR)) - -#if defined(astCLASS) /* Protected */ -#define astDat(in,forward) astDat_(in,forward,STATUS_PTR) -#endif -#endif - - - - - diff --git a/ast/tpn.c b/ast/tpn.c deleted file mode 100644 index 0d30503..0000000 --- a/ast/tpn.c +++ /dev/null @@ -1,393 +0,0 @@ -#include -#include -#include "wcsmath.h" -#include "wcstrig.h" -#include "proj.h" - -#define icopysign(X, Y) ((Y) < 0.0 ? -abs(X) : abs(X)) -#define TPN 999 - -/*============================================================================ -* TAN: gnomonic projection, with correction terms. -* -* This projection is no longer part of the FITSWCS standard, but is -* retained here for use b the AST library as a means of implementing -* the IRAF TNX projection, and the DSS encoding. -* -* Given and/or returned: -* prj->p Array of latitude coefficients -* prj->p2 Array of longitude coefficients -* prj->flag TPN, or -TPN if prj->flag is given < 0. -* prj->r0 r0; reset to 180/pi if 0. -* prj->n If zero, only do poly part of transformation (i.e. omit -* the TAN projection). -* -* Returned: -* prj->code "TPN" -* prj->phi0 0.0 -* prj->theta0 90.0 -* prj->astPRJfwd Pointer to astTPNfwd(). -* prj->astPRJrev Pointer to astTPNrev(). -* prj->w[ 0 ] Set to 0.0 if a simple tan projection is required -* (with no polynomial correction). Otherwise, set to 1.0. -*===========================================================================*/ - -int astTPNset(prj) - -struct AstPrjPrm *prj; - -{ - int m; - - prj->flag = icopysign(TPN, prj->flag); - prj->phi0 = 0.0; - prj->theta0 = 90.0; - - if (prj->r0 == 0.0) prj->r0 = R2D; - - prj->astPRJfwd = astTPNfwd; - prj->astPRJrev = astTPNrev; - -/* If all co-efficients have their "unit" values, we do not need to - use the polynomial correction. */ - prj->w[ 0 ] = 0.0; - - if( prj->p[ 0 ] != 0.0 || prj->p2[ 0 ] != 0.0 ) { - prj->w[ 0 ] = 1.0; - - } else if( prj->p[ 1 ] != 1.0 || prj->p2[ 1 ] != 1.0 ) { - prj->w[ 0 ] = 1.0; - - } else { - for( m = 2; m < WCSLIB_MXPAR; m++ ){ - if( prj->p[ m ] != 0.0 || prj->p2[ m ] != 0.0 ){ - prj->w[ 0 ] = 1.0; - break; - } - } - } - - return 0; -} - -/*--------------------------------------------------------------------------*/ - -int astTPNfwd(phi, theta, prj, xx, yy) - -const double phi, theta; -double *xx, *yy; -struct AstPrjPrm *prj; - -{ - double r, xi, eta, x2, xy, y2, r2, x3, x2y, xy2, y3, r3, x4, x3y, - x2y2, xy3, y4, x5, x4y, x3y2, x2y3, xy4, y5, r5, x6, x5y, x4y2, - x3y3, x2y4, xy5, y6, x7, x6y, x5y2, x4y3, x3y4, x2y5, xy6, y7, - r7, tol, f, g, fx, fy, gx, gy, dx, dy, x, y, denom; - double *a, *b; - int i, ok; - - if (abs(prj->flag) != TPN ) { - if (astTPNset(prj)) return 1; - } - - if( prj->n ) { - double s = astSind(theta); - if (prj->flag > 0 && s < 0.0) { - return 2; - } - r = prj->r0*astCosd(theta)/s; - xi = r*astSind(phi); - eta = -r*astCosd(phi); - } else { - xi = phi; - eta = theta; - } - - /* Simple tan */ - if( prj->w[ 0 ] == 0.0 ){ - *xx = xi; - *yy = eta; - - /* Tan with polynomial corrections: Iterate using Newton's method to - get the (x,y) corresponding to the above (xi,eta). */ - } else { - a = prj->p2; - b = prj->p; - - /* Initial guess: linear solution assuming a3,... and b3,... are zero. */ - denom = a[1]*b[1] - a[2]*b[2]; - if( denom != 0.0 ) { - x = ( xi*b[1] - eta*a[2] - a[0]*b[1] + b[0]*a[2] )/denom; - y = -( xi*b[2] - eta*a[1] - a[0]*b[2] + b[0]*a[1] )/denom; - - } else { - if( a[1] != 0.0 ){ - x = ( xi - a[0] )/a[1]; - } else { - x = a[0]; - } - - if( b[1] != 0.0 ){ - y = ( eta - b[0] )/b[1]; - } else { - y = b[0]; - } - } - -/* Iterate up to 50 times, until the required relative accuracy is - achieved. */ - tol = 1.0E-5; - ok = 0; - for (i = 0; i < 50; i++) { - -/* Get required products of the current x and y values */ - x2 = x*x; - xy = x*y; - y2 = y*y; - - r2 = x2 + y2; - r = sqrt( r2 ); - - x3 = x2*x; - x2y = x2*y; - xy2 = x*y2; - y3 = y*y2; - - r3 = r*r2; - - x4 = x3*x; - x3y = x3*y; - x2y2 = x2*y2; - xy3 = x*y3; - y4 = y*y3; - - x5 = x4*x; - x4y = x4*y; - x3y2 = x3*y2; - x2y3 = x2*y3; - xy4 = x*y4; - y5 = y*y4; - - r5 = r3*r2; - - x6 = x5*x; - x5y = x5*y; - x4y2 = x4*y2; - x3y3 = x3*y3; - x2y4 = x2*y4; - xy5 = x*y5; - y6 = y*y5; - - x7 = x6*x; - x6y = x6*y; - x5y2 = x5*y2; - x4y3 = x4*y3; - x3y4 = x3*y4; - x2y5 = x2*y5; - xy6 = x*y6; - y7 = y*y6; - - r7 = r5*r2; - -/* Get the xi and eta models corresponding to the current x and y values */ - f = a[0] + a[1]*x + a[2]*y + a[3]*r + a[4]*x2 - + a[5]*xy + a[6]*y2 + a[7]*x3 + a[8]*x2y + a[9]*xy2 - + a[10]*y3 + a[11]*r3 + a[12]*x4 + a[13]*x3y + a[14]*x2y2 - + a[15]*xy3 + a[16]*y4 + a[17]*x5 + a[18]*x4y + a[19]*x3y2 - + a[20]*x2y3 + a[21]*xy4 + a[22]*y5 + a[23]*r5 + a[24]*x6 - + a[25]*x5y + a[26]*x4y2 + a[27]*x3y3 + a[28]*x2y4 + a[29]*xy5 - + a[30]*y6 + a[31]*x7 + a[32]*x6y + a[33]*x5y2 + a[34]*x4y3 - + a[35]*x3y4 + a[36]*x2y5 + a[37]*xy6 + a[38]*y7 + a[39]*r7; - - g = b[0] + b[1]*y + b[2]*x + b[3]*r + b[4]*y2 - + b[5]*xy + b[6]*x2 + b[7]*y3 + b[8]*xy2 + b[9]*x2y - + b[10]*x3 + b[11]*r3 + b[12]*y4 + b[13]*xy3 + b[14]*x2y2 - + b[15]*x3y + b[16]*x4 + b[17]*y5 + b[18]*xy4 + b[19]*x2y3 - + b[20]*x3y2 + b[21]*x4y + b[22]*x5 + b[23]*r5 + b[24]*y6 - + b[25]*xy5 + b[26]*x2y4 + b[27]*x3y3 + b[28]*x4y2 + b[29]*x5y - + b[30]*x6 + b[31]*y7 + b[32]*xy6 + b[33]*x2y5 + b[34]*x3y4 - + b[35]*x4y3 + b[36]*x5y2 + b[37]*x6y + b[38]*x7 + b[39]*r7; - -/* Partial derivative of xi wrt x... */ - fx = a[1] + a[3]*( (r!=0.0)?(x/r):0.0 ) + 2*a[4]*x + - a[5]*y + 3*a[7]*x2 + 2*a[8]*xy + a[9]*y2 + - 3*a[11]*r*x + 4*a[12]*x3 + 3*a[13]*x2y + 2*a[14]*xy2 + - a[15]*y3 + 5*a[17]*x4 + 4*a[18]*x3y + 3*a[19]*x2y2 + - 2*a[20]*xy3 + a[21]*y4 + 5*a[23]*r3*x + 6*a[24]*x5 + - 5*a[25]*x4y + 4*a[26]*x3y2 + 3*a[27]*x2y3 + 2*a[28]*xy4 + - a[29]*y5 + 7*a[31]*x6 + 6*a[32]*x5y + 5*a[33]*x4y2 + - 4*a[34]*x3y3 + 3*a[35]*x2y4 + 2*a[36]*xy5 + a[37]*y6 + - 7*a[39]*r5*x; - -/* Partial derivative of xi wrt y... */ - fy = a[2] + a[3]*( (r!=0.0)?(y/r):0.0 ) + a[5]*x + - 2*a[6]*y + a[8]*x2 + 2*a[9]*xy + 3*a[10]*y2 + - 3*a[11]*r*y + a[13]*x3 + 2*a[14]*x2y + 3*a[15]*xy2 + - 4*a[16]*y3 + a[18]*x4 + 2*a[19]*x3y + 3*a[20]*x2y2 + - 4*a[21]*xy3 + 5*a[22]*y4 + 5*a[23]*r3*y + a[25]*x5 + - 2*a[26]*x4y + 3*a[27]*x3y2 + 4*a[28]*x2y3 + 5*a[29]*xy4 + - 6*a[30]*y5 + a[32]*x6 + 2*a[33]*x5y + 3*a[34]*x4y2 + - 4*a[35]*x3y3 + 5*a[36]*x2y4 + 6*a[37]*xy5 + 7*a[38]*y6 + - 7*a[39]*r5*y; - -/* Partial derivative of eta wrt x... */ - gx = b[2] + b[3]*( (r!=0.0)?(x/r):0.0 ) + b[5]*y + - 2*b[6]*x + b[8]*y2 + 2*b[9]*xy + 3*b[10]*x2 + - 3*b[11]*r*x + b[13]*y3 + 2*b[14]*xy2 + 3*b[15]*x2y + - 4*b[16]*x3 + b[18]*y4 + 2*b[19]*xy3 + 3*b[20]*x2y2 + - 4*b[21]*x3y + 5*b[22]*x4 + 5*b[23]*r3*x + b[25]*y5 + - 2*b[26]*xy4 + 3*b[27]*x2y3 + 4*b[28]*x3y2 + 5*b[29]*x4y + - 6*b[30]*x5 + b[32]*y6 + 2*b[33]*xy5 + 3*b[34]*x2y4 + - 4*b[35]*x3y3 + 5*b[36]*x4y2 + 6*b[37]*x5y + 7*b[38]*x6 + - 7*b[39]*r5*x; - -/* Partial derivative of eta wrt y... */ - gy = b[1] + b[3]*( (r!=0.0)?(y/r):0.0 ) + 2*b[4]*y + - b[5]*x + 3*b[7]*y2 + 2*b[8]*xy + b[9]*x2 + - 3*b[11]*r*y + 4*b[12]*y3 + 3*b[13]*xy2 + 2*b[14]*x2y + - b[15]*x3 + 5*b[17]*y4 + 4*b[18]*xy3 + 3*b[19]*x2y2 + - 2*b[20]*x3y + b[21]*x4 + 5*b[23]*r3*y + 6*b[24]*y5 + - 5*b[25]*xy4 + 4*b[26]*x2y3 + 3*b[27]*x3y2 + 2*b[28]*x4y + - b[29]*x5 + 7*b[31]*y6 + 6*b[32]*xy5 + 5*b[33]*x2y4 + - 4*b[34]*x3y3 + 3*b[35]*x4y2 + 2*b[36]*x5y + b[37]*x6 + - 7*b[39]*r5*y; - -/* Calculate new x and y values. */ - f = f - xi; - g = g - eta; - dx = ( (-f*gy) + (g*fy) ) / ( (fx*gy) - (fy*gx) ); - dy = ( (-g*fx) + (f*gx) ) / ( (fx*gy) - (fy*gx) ); - x += dx; - y += dy; - -/* Check if convergence has been achieved. */ - if( fabs(dx) <= tol*fabs(x) && fabs(dy) <= tol*fabs(y) ) { - ok = 1; - break; - } - } - - *xx = x; - *yy = y; - - if( !ok ) return 2; - - } - - return 0; - -} - -/*--------------------------------------------------------------------------*/ - -int astTPNrev(x, y, prj, phi, theta) - -const double x, y; -double *phi, *theta; -struct AstPrjPrm *prj; - -{ - double r, xi, eta, x2, xy, y2, r2, x3, x2y, xy2, y3, r3, x4, x3y, - x2y2, xy3, y4, x5, x4y, x3y2, x2y3, xy4, y5, r5, x6, x5y, x4y2, - x3y3, x2y4, xy5, y6, x7, x6y, x5y2, x4y3, x3y4, x2y5, xy6, y7, - r7; - double *a, *b; - - if (abs(prj->flag) != TPN ) { - if (astTPNset(prj)) return 1; - } - - /* Simple tan */ - if( prj->w[ 0 ] == 0.0 ){ - xi = x; - eta = y; - - /* Tan with polynomial corrections. */ - } else { - x2 = x*x; - xy = x*y; - y2 = y*y; - - r2 = x2 + y2; - r = sqrt( r2 ); - - x3 = x2*x; - x2y = x2*y; - xy2 = x*y2; - y3 = y*y2; - - r3 = r*r2; - - x4 = x3*x; - x3y = x3*y; - x2y2 = x2*y2; - xy3 = x*y3; - y4 = y*y3; - - x5 = x4*x; - x4y = x4*y; - x3y2 = x3*y2; - x2y3 = x2*y3; - xy4 = x*y4; - y5 = y*y4; - - r5 = r3*r2; - - x6 = x5*x; - x5y = x5*y; - x4y2 = x4*y2; - x3y3 = x3*y3; - x2y4 = x2*y4; - xy5 = x*y5; - y6 = y*y5; - - x7 = x6*x; - x6y = x6*y; - x5y2 = x5*y2; - x4y3 = x4*y3; - x3y4 = x3*y4; - x2y5 = x2*y5; - xy6 = x*y6; - y7 = y*y6; - - r7 = r5*r2; - - a = prj->p2; - xi = a[0] + a[1]*x + a[2]*y + a[3]*r + a[4]*x2 - + a[5]*xy + a[6]*y2 + a[7]*x3 + a[8]*x2y + a[9]*xy2 - + a[10]*y3 + a[11]*r3 + a[12]*x4 + a[13]*x3y + a[14]*x2y2 - + a[15]*xy3 + a[16]*y4 + a[17]*x5 + a[18]*x4y + a[19]*x3y2 - + a[20]*x2y3 + a[21]*xy4 + a[22]*y5 + a[23]*r5 + a[24]*x6 - + a[25]*x5y + a[26]*x4y2 + a[27]*x3y3 + a[28]*x2y4 + a[29]*xy5 - + a[30]*y6 + a[31]*x7 + a[32]*x6y + a[33]*x5y2 + a[34]*x4y3 - + a[35]*x3y4 + a[36]*x2y5 + a[37]*xy6 + a[38]*y7 + a[39]*r7; - - b = prj->p; - eta = b[0] + b[1]*y + b[2]*x + b[3]*r + b[4]*y2 - + b[5]*xy + b[6]*x2 + b[7]*y3 + b[8]*xy2 + b[9]*x2y - + b[10]*x3 + b[11]*r3 + b[12]*y4 + b[13]*xy3 + b[14]*x2y2 - + b[15]*x3y + b[16]*x4 + b[17]*y5 + b[18]*xy4 + b[19]*x2y3 - + b[20]*x3y2 + b[21]*x4y + b[22]*x5 + b[23]*r5 + b[24]*y6 - + b[25]*xy5 + b[26]*x2y4 + b[27]*x3y3 + b[28]*x4y2 + b[29]*x5y - + b[30]*x6 + b[31]*y7 + b[32]*xy6 + b[33]*x2y5 + b[34]*x3y4 - + b[35]*x4y3 + b[36]*x5y2 + b[37]*x6y + b[38]*x7 + b[39]*r7; - - } - - /* Now do the tan projection */ - if( prj->n ) { - r = sqrt(xi*xi + eta*eta); - if (r == 0.0) { - *phi = 0.0; - } else { - *phi = astATan2d(xi, -eta); - } - *theta = astATan2d(prj->r0, r); - } else { - *phi = xi; - *theta = eta; - } - - return 0; -} - diff --git a/ast/tranmap.c b/ast/tranmap.c deleted file mode 100644 index 5abd75d..0000000 --- a/ast/tranmap.c +++ /dev/null @@ -1,2327 +0,0 @@ -/* -*class++ -* Name: -* TranMap - -* Purpose: -* Mapping with specified forward and inverse transformations. - -* Constructor Function: -c astTranMap -f AST_TRANMAP - -* Description: -* A TranMap is a Mapping which combines the forward transformation of -* a supplied Mapping with the inverse transformation of another -* supplied Mapping, ignoring the un-used transformation in each -* Mapping (indeed the un-used transformation need not exist). -* -* When the forward transformation of the TranMap is referred to, the -* transformation actually used is the forward transformation of the -* first Mapping supplied when the TranMap was constructed. Likewise, -* when the inverse transformation of the TranMap is referred to, the -* transformation actually used is the inverse transformation of the -* second Mapping supplied when the TranMap was constructed. - -* Inheritance: -* The TranMap class inherits from the Mapping class. - -* Attributes: -* The TranMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c The TranMap class does not define any new functions beyond those -f The TranMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 10-FEB-2004 (DSB): -* Original version. -* 19-JAN-2005 (DSB): -* Fix memory leak. -* 14-FEB-2006 (DSB): -* - Over-ride the astDecompose method. -* - Fix bug in MapSplit related to use of invert flags. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 10-MAY-2006 (DSB): -* Override astEqual. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS TranMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "permmap.h" /* Coordinate permutation Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "tranmap.h" /* Interface definition for this class */ -#include "frame.h" /* Frames */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int *(* parent_mapsplit)( AstMapping *, int, const int *, AstMapping **, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(TranMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(TranMap,Class_Init) -#define class_vtab astGLOBAL(TranMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstTranMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstTranMap *astTranMapId_( void *, void *, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstMapping *RemoveRegions( AstMapping *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void Decompose( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * ); -static int GetObjSize( AstObject *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - - -/* Member functions. */ -/* ================= */ -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two TranMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "tranmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* TranMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two TranMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a TranMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the TranMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTranMap *that; - AstTranMap *this; - int nin; - int nout; - int result; - int that_inv1; - int that_inv2; - int this_inv1; - int this_inv2; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two TranMap structures. */ - this = (AstTranMap *) this_object; - that = (AstTranMap *) that_object; - -/* Check the second object is a TranMap. We know the first is a - TranMap since we have arrived at this implementation of the virtual - function. */ - if( astIsATranMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* Temporarily re-instate the original Invert flag values. */ - that_inv1 = astGetInvert( that->map1 ); - that_inv2 = astGetInvert( that->map2 ); - this_inv1 = astGetInvert( this->map1 ); - this_inv2 = astGetInvert( this->map2 ); - - astSetInvert( this->map1, this->invert1 ); - astSetInvert( this->map2, this->invert2 ); - astSetInvert( that->map1, that->invert1 ); - astSetInvert( that->map2, that->invert2 ); - -/* If the Invert flags for the two TranMaps differ, it may still be possible - for them to be equivalent. First compare the TranMaps if their Invert - flags are the same. In this case all the attributes of the two TranMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - if( astEqual( this->map1, that->map1 ) && - astEqual( this->map2, that->map2 ) ) { - result = 1; - } - -/* If the Invert flags for the two TranMaps differ, the attributes of the two - TranMaps must be inversely related to each other. */ - } else { - - astInvert( that->map1 ); - astInvert( that->map2 ); - - if( astEqual( this->map1, that->map2 ) && - astEqual( this->map2, that->map1 ) ) { - result = 1; - } - - } - -/* Restore the original Invert flag values. */ - astSetInvert( this->map1, this_inv1 ); - astSetInvert( this->map2, this_inv2 ); - astSetInvert( that->map1, that_inv1 ); - astSetInvert( that->map2, that_inv2 ); - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "tranmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* TranMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied TranMap, -* in bytes. - -* Parameters: -* this -* Pointer to the TranMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstTranMap *this; /* Pointer to TranMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the TranMap structure. */ - this = (AstTranMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astGetObjSize( this->map1 ); - result += astGetObjSize( this->map2 ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static void Decompose( AstMapping *this_mapping, AstMapping **map1, - AstMapping **map2, int *series, int *invert1, - int *invert2, int *status ) { -/* -* -* Name: -* Decompose - -* Purpose: -* Decompose a Mapping into two component Mappings. - -* Type: -* Private function. - -* Synopsis: -* #include "tranmap.h" -* void Decompose( AstMapping *this, AstMapping **map1, -* AstMapping **map2, int *series, -* int *invert1, int *invert2, int *status ) - -* Class Membership: -* TranMap member function (over-rides the protected astDecompose -* method inherited from the Mapping class). - -* Description: -* This function returns pointers to the two Mappings encapsulated by -* a TranMap. - -* Parameters: -* this -* Pointer to the Mapping. -* map1 -* Address of a location to receive a pointer to first component -* Mapping (the forward Mapping). -* map2 -* Address of a location to receive a pointer to second component -* Mapping (the inverse Mapping). -* series -* Address of a location to receive a value indicating if the -* component Mappings are applied in series or parallel. A non-zero -* value means that the supplied Mapping is equivalent to applying map1 -* followed by map2 in series. A zero value means that the supplied -* Mapping is equivalent to applying map1 to the lower numbered axes -* and map2 to the higher numbered axes, in parallel. Zero is -* returned for a TranMap. -* invert1 -* The value of the Invert attribute to be used with map1. -* invert2 -* The value of the Invert attribute to be used with map2. -* status -* Pointer to the inherited status variable. - -* Notes: -* - Any changes made to the component Mappings using the returned -* pointers will be reflected in the supplied Mapping. - -*- -*/ - - -/* Local Variables: */ - AstTranMap *this; /* Pointer to TranMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TranMap structure. */ - this = (AstTranMap *) this_mapping; - -/* If the TranMap has been inverted, return the Mappings in reverse - order with inverted Invert falgs. */ - if( astGetInvert( this ) ) { - if( map1 ) *map1 = astClone( this->map2 ); - if( map2 ) *map2 = astClone( this->map1 ); - if( invert1 ) *invert1 = this->invert2 ? 0 : 1; - if( invert2 ) *invert2 = this->invert1 ? 0 : 1; - -/* If the TranMap has not been inverted, return the Mappings in their - original order with their original Invert flags. */ - } else { - if( map1 ) *map1 = astClone( this->map1 ); - if( map2 ) *map2 = astClone( this->map2 ); - if( invert1 ) *invert1 = this->invert1; - if( invert2 ) *invert2 = this->invert2; - } -} - -void astInitTranMapVtab_( AstTranMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitTranMapVtab - -* Purpose: -* Initialise a virtual function table for a TranMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "tranmap.h" -* void astInitTranMapVtab( AstTranMapVtab *vtab, const char *name ) - -* Class Membership: -* TranMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the TranMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsATranMap) to determine if an object belongs to - this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -/* None. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - mapping->RemoveRegions = RemoveRegions; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_mapsplit = mapping->MapSplit; - mapping->MapSplit = MapSplit; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->Decompose = Decompose; - mapping->MapMerge = MapMerge; - mapping->Rate = Rate; - -/* Declare the copy constructor, destructor and class dump function. */ - astSetCopy( vtab, Copy ); - astSetDelete( vtab, Delete ); - astSetDump( vtab, Dump, "TranMap", "Compound Transformation Mapping" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* TranMap member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstTranMap *this; /* Pointer to TranMap structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the TranMap structure. */ - this = (AstTranMap *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* Invoke the astManageLock method on any Objects contained within - the supplied Object. */ - if( !result ) result = astManageLock( this->map1, mode, extra, fail ); - if( !result ) result = astManageLock( this->map2, mode, extra, fail ); - - return result; - -} -#endif - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a TranMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* TranMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated TranMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated TranMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated TranMap which is to be merged with -* its neighbours. This should be a cloned copy of the TranMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* TranMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated TranMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpMap *cmap; /* Pointer to compound Mapping */ - AstMapping *cmap_f; /* Pointer to compound Mapping */ - AstMapping *cmap_i; /* Pointer to compound Mapping */ - AstMapping *hmap1; /* Pointer to 1st comp of higher TranMap */ - AstMapping *hmap2; /* Pointer to 2nd comp of higher TranMap */ - AstMapping *hmap_f; /* Pointer to fwd Mapping of higher TranMap */ - AstMapping *hmap_i; /* Pointer to inv Mapping of higher TranMap */ - AstMapping *map1; /* Pointer to 1st comp of nominated TranMap */ - AstMapping *map2; /* Pointer to 2nd comp of nominated TranMap */ - AstMapping *map_f; /* Pointer to fwd Mapping of nominated TranMap */ - AstMapping *map_i; /* Pointer to inv Mapping of nominated TranMap */ - AstMapping *smap; /* Pointer to simplified Mapping */ - AstMapping *smap_f; /* Pointer to simplified Mapping */ - AstMapping *smap_i; /* Pointer to simplified Mapping */ - AstTranMap *hmap; /* Pointer to higher TranMap */ - AstTranMap *map; /* Pointer to this TranMap */ - AstTranMap *new; /* Pointer to merged TranMap */ - int i; /* Loop count */ - int old_hinv1; /* Original Invert flag for hmap->map1 */ - int old_hinv2; /* Original Invert flag for hmap->map2 */ - int old_inv1; /* Original Invert flag for this->map1 */ - int old_inv2; /* Original Invert flag for this->map2 */ - int result; /* The value to return */ - -/* Initialise.*/ - result = -1; - -/* Check the inherited status. */ - if ( !astOK ) return result; - -/* Get a pointer to this TranMap. */ - map = (AstTranMap *) this; - -/* Get the two component Mappings,and temporarily set their Invert - attributes back to the values they had when the TranMap was created, - saving their current Invert values so that they can be re-instated later. */ - map1 = map->map1; - old_inv1 = astGetInvert( map1 ); - astSetInvert( map1, map->invert1 ); - - map2 = map->map2; - old_inv2 = astGetInvert( map2 ); - astSetInvert( map2, map->invert2 ); - -/* Simplify the TranMap on its own. */ -/* ================================ */ - -/* If the TranMap is inverted, creat an equal TranMap which is not inverted. - To do this, invert and swap the component Mappings. */ - if( ( *invert_list )[ where ] ) { - astInvert( map1 ); - astInvert( map2 ); - new = astTranMap( map2, map1, "", status ); - astInvert( map1 ); - astInvert( map2 ); - - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) new; - ( *invert_list )[ where ] = 0; - result = where; - -/* Otherwise, try to simplify each of the component Mappings. */ - } else { - smap_f = astSimplify( map1 ); - smap_i = astSimplify( map2 ); - -/* Assume some simplification took place if the pointers have changed. */ - if( smap_f != map1 || smap_i != map2 ) { - -/* Construct a new TranMap from these simplifgied Mappings. */ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) astTranMap( smap_f, smap_i, "", status ); - result = where; - -/* Otherwise, if the both component Mappings are defined in both directions... */ - } else if( astGetTranForward( map1 ) && astGetTranInverse( map1 ) && - astGetTranForward( map2 ) && astGetTranInverse( map2 ) ) { - -/* Form a series CmpMap from the two component Mappings, with the second - Mapping inverted. */ - astInvert( map2 ); - cmap = astCmpMap( map1, map2, 1, "", status ); - astInvert( map2 ); - -/* If this CmpMap simplifies to a UnitMap, then the two components of the - TranMap are equal, and so we can replace the entire TranMap with either - of its components. Note, we leave the supplied invert flag unchanged, - since the copycreated below refers to the Mapping as it was when the - TranMap was created. However, we invert the returned Mapping if - necessary. */ - smap = astSimplify( cmap ); - if( astIsAUnitMap( smap ) ) { - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = astCopy( map1 ); - if( ( *invert_list )[ where ] ) astInvert( ( *map_list )[ where ] ); - result = where; - } - -/* Release resources. */ - smap = astAnnul( smap ); - cmap = astAnnul( cmap ); - } - -/* Release resources. */ - smap_f = astAnnul( smap_f ); - smap_i = astAnnul( smap_i ); - } - -/* Merge the TranMap with a neighbouring TranMap. */ -/* ============================================== */ -/* Only do this if no change was made above, and we are combining the - Mappings in series. */ - if( result == -1 && series ) { - -/* Is the higher neighbour a TranMap? */ - if( where < ( *nmap - 1 ) && - astIsATranMap( ( *map_list )[ where + 1 ] ) ){ - -/* Get the two component Mappings of the higher TranMap, and temporarily set - their Invert attributes back to the values they had when the TranMap was - created, saving their current Invert values so that they can be re-instated - later. */ - hmap = (AstTranMap *) ( *map_list )[ where + 1 ]; - - hmap1 = hmap->map1; - old_hinv1 = astGetInvert( hmap1 ); - astSetInvert( hmap1, hmap->invert1 ); - - hmap2 = hmap->map2; - old_hinv2 = astGetInvert( hmap2 ); - astSetInvert( hmap2, hmap->invert2 ); - -/* Get the Mappings which defines the forward and inverse transformation of - the lower TranMap ("this"). Then, map_f and map_i are pointers to - Mappings which could be used to construct a new TranMap which would be - equivalent to "this" with the supplied invert setting. */ - if( ( *invert_list )[ where ] ) { - map_f = map2; - map_i = map1; - astInvert( map_f ); - astInvert( map_i ); - } else { - map_f = map1; - map_i = map2; - } - -/* Likewise, get the Mappings which defines the forward and inverse - transformation of the higher TranMap. */ - if( ( *invert_list )[ where + 1 ] ) { - hmap_f = hmap2; - hmap_i = hmap1; - astInvert( hmap_f ); - astInvert( hmap_i ); - } else { - hmap_f = hmap1; - hmap_i = hmap2; - } - -/* Combine the two forward Mappings together into a series CmpMap, and - simplify it. */ - cmap_f = (AstMapping *) astCmpMap( map_f, hmap_f, 1, "", status ); - smap_f = astSimplify( cmap_f ); - -/* Do the same for the inverse Mappings */ - cmap_i = (AstMapping *) astCmpMap( map_i, hmap_i, 1, "", status ); - smap_i = astSimplify( cmap_i ); - -/* Was any simplification performed? We assume this is the case if the - either of the simplied pointer differs from the original pointer. */ - if( cmap_f != smap_f || cmap_i != smap_i ) { - -/* In which case,construct a new TranMap from the simplified Mappings. */ - new = astTranMap( smap_f, smap_i, "", status ); - - } else { - new = NULL; - } - -/* Free resources.*/ - cmap_f = astAnnul( cmap_f ); - smap_f = astAnnul( smap_f ); - cmap_i = astAnnul( cmap_i ); - smap_i = astAnnul( smap_i ); - -/* Re-instate the original Invert values for the component Mappings of - the higher TranMap. */ - astSetInvert( hmap1, old_hinv1 ); - astSetInvert( hmap2, old_hinv2 ); - -/* If we have a new TranMap, annul the first of the two Mappings, and replace - it with the merged TranMap. Also set the invert flag. */ - if( new ) { - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) new; - ( *invert_list )[ where ] = 0; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ where + 1 ] ); - for ( i = where + 2; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = where; - } - } - } - -/* Re-instate the original Invert values for the component Mappings. */ - astSetInvert( map1, old_inv1 ); - astSetInvert( map2, old_inv2 ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = -1; - -/* Return the result. */ - return result; -} - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* TranMap. - -* Type: -* Private function. - -* Synopsis: -* #include "tranmap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* TranMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing TranMap. This is only possible if the specified inputs -* correspond to some subset of the TranMap outputs. That is, there -* must exist a subset of the TranMap outputs for which each output -* depends only on the selected TranMap inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied TranMap, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the TranMap to be split (the TranMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied TranMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied TranMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied TranMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstMapping *fmap; /* Pointer to forward Mapping in supplied TranMap */ - AstMapping *imap; /* Pointer to inverse Mapping in supplied TranMap */ - AstMapping *rfmap; /* Pointer to split forward Mapping */ - AstMapping *rimap; /* Pointer to split inverse Mapping */ - AstTranMap *this; /* Pointer to TranMap structure */ - int *ires; /* I/ps of inv Mapping dependent on selected o/ps */ - int *out; /* O/ps of fwd Mapping dependent on selected i/ps */ - int *result; /* Pointer to returned array */ - int finv; /* Invert flag to use with fmap */ - int i; /* Loop count */ - int iinv; /* Invert flag to use with imap */ - int nout; /* No. of outputs dependent on selected inputs */ - int ok; /* Can required Mapping be created? */ - int old_finv; /* Original Invert flag for fmap */ - int old_iinv; /* Original Invert flag for imap */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the parent astMapSplit method to see if it can do the job. */ - result = (*parent_mapsplit)( this_map, nin, in, map, status ); - -/* If not, we provide a special implementation here. */ - if( !result ) { - -/* Get a pointer to the TranMap structure. */ - this = (AstTranMap *) this_map; - -/* Get pointers to the forward and inverse Mappings, taking into account - whether the TranMap has been inverted. */ - if( !astGetInvert( this ) ) { - fmap = this->map1; - finv = this->invert1; - imap = this->map2; - iinv = this->invert2; - } else { - imap = this->map1; - iinv = !( this->invert1 ); - fmap = this->map2; - finv = !( this->invert2 ); - } - -/* Temporarily set the Invert flag of both Mappings back to their - original values. */ - old_finv = astGetInvert( fmap ); - astSetInvert( fmap, finv ); - old_iinv = astGetInvert( imap ); - astSetInvert( imap, iinv ); - -/* Try to split the forward Mapping. */ - out = astMapSplit( fmap, nin, in, &rfmap ); - -/* Check the split could be done. */ - if( out ) { - -/* Get the number of outputs which are fed by the selected inputs. */ - nout = astGetNout( rfmap ); - -/* See if the inverse Mapping can be split using these outputs as inputs. */ - astInvert( imap ); - ires = astMapSplit( imap, nout, out, &rimap ); - astInvert( imap ); - if( ires ) { - astInvert( rimap ); - -/* Check that the resulting inputs are the same as the supplied inputs. */ - if( astGetNin( rimap ) == nin ) { - ok = 1; - for( i = 0; i < nin; i++ ) { - if( in[ i ] != ires[ i ] ) { - ok = 0; - break; - } - } - -/* If so create the required new TranMap. */ - if( ok ) { - *map = (AstMapping *) astTranMap( rfmap, rimap, "", status ); - result = out; - } - } - -/* Free resources. */ - ires = astFree( ires ); - rimap = astAnnul( rimap ); - } - - if( !result ) out = astFree( out ); - rfmap = astAnnul( rfmap ); - } - -/* Re-instate the Invert flags of the component Mappings. */ - astSetInvert( fmap, old_finv ); - astSetInvert( imap, old_iinv ); - } - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "tranmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* TranMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. Also evaluates the second derivative. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -*/ - -/* Local Variables: */ - AstTranMap *map; - AstMapping *cmap; - double result; - int cinv; - int old_inv; - -/* Check inherited status */ - if( !astOK ) return AST__BAD; - -/* Get a pointer to the TranMap structure. */ - map = (AstTranMap *) this; - -/* Choose the component Mapping to use, and get its original Invert - value. Invert this if the TranMap itself has been inverted (this is - because the astRate function has no "invert" argument so we need to - invert the Mapping before calling astRate). */ - if( astGetInvert( this ) ) { - cmap = map->map2; - cinv = !(map->invert2); - } else { - cmap = map->map1; - cinv = map->invert1; - } - -/* Temporarily set the Invert flag of the component Mapping back to its - original value. */ - old_inv = astGetInvert( cmap ); - astSetInvert( cmap, cinv ); - -/* Use the astRate method of the component Mapping. */ - result = astRate( cmap, at, ax1, ax2 ); - -/* Re-instate the Invert flag of the component Mapping. */ - astSetInvert( cmap, old_inv ); - -/* Return the result. */ - return result; -} - -static AstMapping *RemoveRegions( AstMapping *this_mapping, int *status ) { -/* -* Name: -* RemoveRegions - -* Purpose: -* Remove any Regions from a Mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "tranmap.h" -* AstMapping *RemoveRegions( AstMapping *this, int *status ) - -* Class Membership: -* TranMap method (over-rides the astRemoveRegions method inherited -* from the Mapping class). - -* Description: -* This function searches the supplied Mapping (which may be a -* compound Mapping such as a TranMap) for any component Mappings -* that are instances of the AST Region class. It then creates a new -* Mapping from which all Regions have been removed. If a Region -* cannot simply be removed (for instance, if it is a component of a -* parallel TranMap), then it is replaced with an equivalent UnitMap -* in the returned Mapping. -* -* The implementation provided by the TranMap class invokes the -* astRemoveRegions method on the two component Mappings, and joins -* the results together into a new TranMap. - -* Parameters: -* this -* Pointer to the original Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the modified mapping. - -* Notes: -* - A NULL pointer value will be returned if this function is -* invoked with the AST error status set, or if it should fail for -* any reason. -*/ - -/* Local Variables: */ - AstTranMap *new; /* Pointer to new TranMap */ - AstTranMap *this; /* Pointer to TranMap structure */ - AstMapping *newmap1; /* New first component Mapping */ - AstMapping *newmap2; /* New second component Mapping */ - AstMapping *result; /* Result pointer to return */ - int nax; /* Number of Frame axes */ - int unit1; /* Is new first Mapping a UnitMap? */ - int unit2; /* Is new second Mapping a UnitMap? */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the TranMap. */ - this = (AstTranMap *) this_mapping; - -/* Invoke the astRemoveRegions method on the two component Mappings. */ - newmap1 = astRemoveRegions( this->map1 ); - newmap2 = astRemoveRegions( this->map2 ); - -/* If neither component was modified, just return a clone of the supplied - pointer. */ - if( this->map1 == newmap1 && this->map2 == newmap2 ) { - result = astClone( this ); - -/* Otherwise, we need to create a new Mapping to return. */ - } else { - -/* The implementation of the astRemoveRegions method provided by the - Region class returns a Frame rather than a UnitMap. But we need - Mappings here, not Frames. So if either of these new Mappings is - a Frame, replace it with an equivalent UnitMap. Also, get flags - indicating if either Mapping is a UnitMap.*/ - if( astIsAFrame( newmap1 ) ) { - nax = astGetNin( newmap1 ); - (void) astAnnul( newmap1 ); - newmap1 = (AstMapping *) astUnitMap( nax, " ", status ); - unit1 = 1; - } else { - unit1 = astIsAUnitMap( newmap1 ); - } - - if( astIsAFrame( newmap2 ) ) { - nax = astGetNin( newmap2 ); - (void) astAnnul( newmap2 ); - newmap2 = (AstMapping *) astUnitMap( nax, " ", status ); - unit2 = 1; - } else { - unit2 = astIsAUnitMap( newmap2 ); - } - -/* If both new Mappings are UnitMaps, return an equivalent UnitMap. */ - if( unit1 && unit2 ) { - result = (AstMapping *) astUnitMap( astGetNin( newmap1 ) + - astGetNin( newmap2 ), " ", - status ); - -/* Otherwise, return a new TranMap containing the two new Mappings. */ - } else { - new = astCopy( this ); - (void) astAnnul( new->map1 ); - (void) astAnnul( new->map2 ); - new->map1 = astClone( newmap1 ); - new->map2 = astClone( newmap2 ); - result = (AstMapping *) new; - } - } - -/* Free resources. */ - newmap1 = astAnnul( newmap1 ); - newmap2 = astAnnul( newmap2 ); - -/* Annul the returned Mapping if an error has occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a TranMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "tranmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* TranMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a TranMap and a set of points encapsulated in a -* PointSet and transforms the points so as to apply the required Mapping. -* This implies applying each of the TranMap's component Mappings in turn, -* either in series or in parallel. - -* Parameters: -* this -* Pointer to the TranMap. -* in -* Pointer to the PointSet associated with the input coordinate values. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the TranMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstMapping *cmap; /* Mapping which defines the required transformation */ - AstPointSet *result; /* Pointer to output PointSet */ - AstTranMap *map; /* Pointer to TranMap to be applied */ - int cinv; /* Invert flag when TranMap was created */ - int old_inv; /* Invert flag on entry to this function */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the TranMap. */ - map = (AstTranMap *) this; - -/* Apply the parent Mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We now extend the parent astTransform method by applying the component - Mappings of the TranMap to generate the output coordinate values. */ - -/* Determine whether to apply the forward or inverse Mapping, according to the - direction specified and whether the Mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Choose the component Mapping to use, and get its original Invert value. */ - if( forward ) { - cmap = map->map1; - cinv = map->invert1; - }else { - cmap = map->map2; - cinv = map->invert2; - } - -/* Temporarily set the Invert flag of the component Mapping back to its - original value. */ - old_inv = astGetInvert( cmap ); - astSetInvert( cmap, cinv ); - -/* Use the Transform method of the component Mapping. */ - result = astTransform( cmap, in, forward, out ); - -/* Re-instate the Invert flag of the component Mapping. */ - astSetInvert( cmap, old_inv ); - -/* If an error occurred, clean up by deleting the output PointSet (if - allocated by this function) and setting a NULL result pointer. */ - if ( !astOK ) { - if ( !out ) result = astDelete( result ); - result = NULL; - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for TranMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for TranMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the component -* Mappings within the TranMap. -*/ - -/* Local Variables: */ - AstTranMap *in; /* Pointer to input TranMap */ - AstTranMap *out; /* Pointer to output TranMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output TranMaps. */ - in = (AstTranMap *) objin; - out = (AstTranMap *) objout; - -/* For safety, start by clearing any references to the input component - Mappings from the output TranMap. */ - out->map1 = NULL; - out->map2 = NULL; - -/* Make copies of these Mappings and store pointers to them in the output - TranMap structure. */ - out->map1 = astCopy( in->map1 ); - out->map2 = astCopy( in->map2 ); -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for TranMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for TranMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstTranMap *this; /* Pointer to TranMap */ - -/* Obtain a pointer to the TranMap structure. */ - this = (AstTranMap *) obj; - -/* Annul the pointers to the component Mappings. */ - this->map1 = astAnnul( this->map1 ); - this->map2 = astAnnul( this->map2 ); - -/* Clear the remaining TranMap variables. */ - this->invert1 = 0; - this->invert2 = 0; -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for TranMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the TranMap class to an output Channel. - -* Parameters: -* this -* Pointer to the TranMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstTranMap *this; /* Pointer to the TranMap structure */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the TranMap structure. */ - this = (AstTranMap *) this_object; - -/* Write out values representing the instance variables for the TranMap - class. Accompany these with appropriate comment strings, possibly - depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* First Invert flag. */ -/* ------------------ */ - ival = this->invert1; - set = ( ival != 0 ); - astWriteInt( channel, "InvA", set, 0, ival, - ival ? "First Mapping used in inverse direction" : - "First Mapping used in forward direction" ); - -/* Second Invert flag. */ -/* ------------------- */ - ival = this->invert2; - set = ( ival != 0 ); - astWriteInt( channel, "InvB", set, 0, ival, - ival ? "Second Mapping used in inverse direction" : - "Second Mapping used in forward direction" ); - -/* First Mapping. */ -/* -------------- */ - astWriteObject( channel, "MapA", 1, 1, this->map1, - "Mapping for forward transformation" ); - -/* Second Mapping. */ -/* --------------- */ - astWriteObject( channel, "MapB", 1, 1, this->map2, - "Mapping for inverse transformation" ); -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsATranMap and astCheckTranMap functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(TranMap,Mapping) -astMAKE_CHECK(TranMap) - -AstTranMap *astTranMap_( void *map1_void, void *map2_void, const char *options, int *status, ...) { -/* -*+ -* Name: -* astTranMap - -* Purpose: -* Create a TranMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "tranmap.h" -* AstTranMap *astTranMap( AstMapping *map1, AstMapping *map2, const char *options, int *status, ... ) - -* Class Membership: -* TranMap constructor. - -* Description: -* This function creates a new TranMap and optionally initialises its -* attributes. - -* Parameters: -* map1 -* Pointer to the first Mapping (which deinfes the forward -* transformation). -* map2 -* Pointer to the second Mapping (which deinfes the inverse -* transformation). -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new TranMap. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new TranMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- - -* Implementation Notes: -* - This function implements the basic TranMap constructor which is -* available via the protected interface to the TranMap class. A -* public interface is provided by the astTranMapId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "map1" and "map2" parameters are of type (void *) and are -* converted and validated within the function itself. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstTranMap *new; /* Pointer to new TranMap */ - AstMapping *map1; /* Pointer to first Mapping structure */ - AstMapping *map2; /* Pointer to second Mapping structure */ - va_list args; /* Variable argument list */ - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain and validate pointers to the Mapping structures provided. */ - map1 = astCheckMapping( map1_void ); - map2 = astCheckMapping( map2_void ); - if ( astOK ) { - -/* Initialise the TranMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitTranMap( NULL, sizeof( AstTranMap ), !class_init, &class_vtab, - "TranMap", map1, map2 ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new TranMap's - attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new TranMap. */ - return new; -} - -AstTranMap *astTranMapId_( void *map1_void, void *map2_void, - const char *options, ... ) { -/* -*++ -* Name: -c astTranMap -f AST_TRANMAP - -* Purpose: -* Create a TranMap. - -* Type: -* Public function. - -* Synopsis: -c #include "tranmap.h" -c AstTranMap *astTranMap( AstMapping *map1, AstMapping *map2, -c const char *options, ... ) -f RESULT = AST_TRANMAP( MAP1, MAP2, OPTIONS, STATUS ) - -* Class Membership: -* TranMap constructor. - -* Description: -* This function creates a new TranMap and optionally initialises -* its attributes. -* -* A TranMap is a Mapping which combines the forward transformation of -* a supplied Mapping with the inverse transformation of another -* supplied Mapping, ignoring the un-used transformation in each -* Mapping (indeed the un-used transformation need not exist). -* -* When the forward transformation of the TranMap is referred to, the -* transformation actually used is the forward transformation of the -* first Mapping supplied when the TranMap was constructed. Likewise, -* when the inverse transformation of the TranMap is referred to, the -* transformation actually used is the inverse transformation of the -* second Mapping supplied when the TranMap was constructed. - -* Parameters: -c map1 -f MAP1 = INTEGER (Given) -* Pointer to the first component Mapping, which defines the -* forward transformation. -c map2 -f MAP2 = INTEGER (Given) -* Pointer to the second component Mapping, which defines the -* inverse transformation. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new TranMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new TranMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astTranMap() -f AST_TRANMAP = INTEGER -* A pointer to the new TranMap. - -* Notes: -* - The number of output coordinates generated by the two Mappings -* (their Nout attribute) must be equal, as must the number of input -* coordinates accepted by each Mapping (their Nin attribute). -* - The forward transformation of the first Mapping must exist. -* - The inverse transformation of the second Mapping must exist. -c - Note that the component Mappings supplied are not copied by -c astTranMap (the new TranMap simply retains a reference to -c them). They may continue to be used for other purposes, but -c should not be deleted. If a TranMap containing a copy of its -c component Mappings is required, then a copy of the TranMap should -c be made using astCopy. -f - Note that the component Mappings supplied are not copied by -f AST_TRANMAP (the new TranMap simply retains a reference to -f them). They may continue to be used for other purposes, but -f should not be deleted. If a TranMap containing a copy of its -f component Mappings is required, then a copy of the TranMap should -f be made using AST_COPY. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astTranMap constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astTranMap_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "map1" and "map2" parameters -* are of type (void *) and are converted from an ID value to a -* pointer and validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astTranMap_ directly, so it must be a re-implementation -* of it in all respects, except for the conversions between IDs -* and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstTranMap *new; /* Pointer to new TranMap */ - AstMapping *map1; /* Pointer to first Mapping structure */ - AstMapping *map2; /* Pointer to second Mapping structure */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise. */ - new = NULL; - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return new; - -/* Obtain the Mapping pointers from the ID's supplied and validate the - pointers to ensure they identify valid Mappings. */ - map1 = astVerifyMapping( astMakePointer( map1_void ) ); - map2 = astVerifyMapping( astMakePointer( map2_void ) ); - if ( astOK ) { - -/* Initialise the TranMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitTranMap( NULL, sizeof( AstTranMap ), !class_init, &class_vtab, - "TranMap", map1, map2 ); - -/* If successful, note that the virtual function table has been initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new TranMap's - attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new TranMap. */ - return astMakeId( new ); -} - -AstTranMap *astInitTranMap_( void *mem, size_t size, int init, - AstTranMapVtab *vtab, const char *name, - AstMapping *map1, AstMapping *map2, int *status ) { -/* -*+ -* Name: -* astInitTranMap - -* Purpose: -* Initialise a TranMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "tranmap.h" -* AstTranMap *astInitTranMap( void *mem, size_t size, int init, -* AstTranMapVtab *vtab, const char *name, -* AstMapping *map1, AstMapping *map2 ) - -* Class Membership: -* TranMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new TranMap object. It allocates memory (if necessary) to -* accommodate the TranMap plus any additional data associated with the -* derived class. It then initialises a TranMap structure at the start -* of this memory. If the "init" flag is set, it also initialises the -* contents of a virtual function table for a TranMap at the start of -* the memory passed via the "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the TranMap is to be initialised. -* This must be of sufficient size to accommodate the TranMap data -* (sizeof(TranMap)) plus any data used by the derived class. If a -* value of NULL is given, this function will allocate the memory itself -* using the "size" parameter to determine its size. -* size -* The amount of memory used by the TranMap (plus derived class -* data). This will be used to allocate memory if a value of NULL is -* given for the "mem" parameter. This value is also stored in the -* TranMap structure, so a valid value must be supplied even if not -* required for allocating memory. -* init -* A logical flag indicating if the TranMap's virtual function table -* is to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new TranMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* map1 -* Pointer to the first Mapping. -* map2 -* Pointer to the second Mapping. - -* Returned Value: -* A pointer to the new TranMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstTranMap *new; /* Pointer to new TranMap */ - int nin; /* No. input coordinates for TranMap */ - int nout; /* No. output coordinates for TranMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitTranMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Report an error if map1 has no forward transformation. */ - if( !astGetTranForward( map1 ) && astOK ) { - astError( AST__INTRD, "astInitTranMap(%s): The first supplied Mapping " - "is not able to transform coordinates in the forward direction.", status, - name ); - } - -/* Report an error if map2 has no inverse transformation. */ - if( !astGetTranInverse( map2 ) && astOK ) { - astError( AST__INTRD, "astInitTranMap(%s): The second supplied Mapping " - "is not able to transform coordinates in the inverse direction.", status, - name ); - } - -/* Check that the number of coordinates are compatible and report an error if - they are not. */ - nout = astGetNout( map1 ); - if ( astGetNout( map2 ) != nout && astOK ) { - astError( AST__INNCO, "astInitTranMap(%s): The number of output " - "coordinates per point (%d) for the first Mapping " - "supplied does not match the number of output " - "coordinates (%d) for the second Mapping.", status, name, nout, - astGetNout( map2 ) ); - } - - nin = astGetNin( map1 ); - if ( astGetNin( map2 ) != nin && astOK ) { - astError( AST__INNCO, "astInitTranMap(%s): The number of input " - "coordinates per point (%d) for the first Mapping " - "supplied does not match the number of input " - "coordinates (%d) for the second Mapping.", status, name, nin, - astGetNin( map2 ) ); - } - -/* Initialise a Mapping structure (the parent class) as the first component - within the TranMap structure, allocating memory if necessary. Specify - the number of input and output coordinates and in which directions the - Mapping should be defined. */ - if ( astOK ) { - new = (AstTranMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - nin, nout, 1, 1 ); - - if ( astOK ) { - -/* Initialise the TranMap data. */ -/* --------------------------- */ -/* Store pointers to the component Mappings. */ - new->map1 = astClone( map1 ); - new->map2 = astClone( map2 ); - -/* Save the initial values of the inversion flags for these Mappings. */ - new->invert1 = astGetInvert( map1 ); - new->invert2 = astGetInvert( map2 ); - -/* If an error occurred, clean up by annulling the Mapping pointers and - deleting the new object. */ - if ( !astOK ) { - new->map1 = astAnnul( new->map1 ); - new->map2 = astAnnul( new->map2 ); - new = astDelete( new ); - } - } - } - -/* Return a pointer to the new object. */ - return new; -} - -AstTranMap *astLoadTranMap_( void *mem, size_t size, - AstTranMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadTranMap - -* Purpose: -* Load a TranMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "tranmap.h" -* AstTranMap *astLoadTranMap( void *mem, size_t size, -* AstTranMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* TranMap loader. - -* Description: -* This function is provided to load a new TranMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* TranMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a TranMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the TranMap is to be -* loaded. This must be of sufficient size to accommodate the -* TranMap data (sizeof(TranMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the TranMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the TranMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstTranMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new TranMap. If this is NULL, a pointer to -* the (static) virtual function table for the TranMap class is -* used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "TranMap" is used instead. - -* Returned Value: -* A pointer to the new TranMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstTranMap *new; /* Pointer to the new TranMap */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this TranMap. In this case the - TranMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstTranMap ); - vtab = &class_vtab; - name = "TranMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitTranMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built TranMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "TranMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* First Invert flag. */ -/* ------------------ */ - new->invert1 = astReadInt( channel, "inva", 0 ); - new->invert1 = ( new->invert1 != 0 ); - -/* Second Invert flag. */ -/* ------------------- */ - new->invert2 = astReadInt( channel, "invb", 0 ); - new->invert2 = ( new->invert2 != 0 ); - -/* First Mapping. */ -/* -------------- */ - new->map1 = astReadObject( channel, "mapa", NULL ); - -/* Second Mapping. */ -/* --------------- */ - new->map2 = astReadObject( channel, "mapb", NULL ); - -/* If an error occurred, clean up by deleting the new TranMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new TranMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -/* None. */ - - - - diff --git a/ast/tranmap.h b/ast/tranmap.h deleted file mode 100644 index ae16f18..0000000 --- a/ast/tranmap.h +++ /dev/null @@ -1,276 +0,0 @@ -#if !defined( TRANMAP_INCLUDED ) /* Include this file only once */ -#define TRANMAP_INCLUDED -/* -*+ -* Name: -* tranmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the TranMap class. - -* Invocation: -* #include "tranmap.h" - -* Description: -* This include file defines the interface to the TranMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. - -* Inheritance: -* The TranMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astMapMerge -* Merge a TranMap within a sequence of Mappings. -* astTransform -* Transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsATranMap -* Test class membership. -* astTranMap -* Create a TranMap. -* -* Protected: -* astCheckTranMap -* Validate class membership. -* astInitTranMap -* Initialise a TranMap. -* astInitTranMapVtab -* Initialise the virtual function table for the TranMap class. -* astLoadTranMap -* Load a TranMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstTranMap -* TranMap object type. -* -* Protected: -* AstTranMapVtab -* TranMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 10-FEB-2004 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate Mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* TranMap structure. */ -/* ----------------- */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstTranMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - AstMapping *map1; /* Pointer to first Mapping */ - AstMapping *map2; /* Pointer to second Mapping */ - int invert1; /* Inversion flag for first Mapping */ - int invert2; /* Inversion flag for second Mapping */ -} AstTranMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstTranMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -/* None. */ -} AstTranMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstTranMapGlobals { - AstTranMapVtab Class_Vtab; - int Class_Init; -} AstTranMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitTranMapGlobals_( AstTranMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(TranMap) /* Check class membership */ -astPROTO_ISA(TranMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstTranMap *astTranMap_( void *, void *, const char *, int *, ...); -#else -AstTranMap *astTranMapId_( void *, void *, const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstTranMap *astInitTranMap_( void *, size_t, int, AstTranMapVtab *, - const char *, AstMapping *, AstMapping *, int * ); - -/* Vtab initialiser. */ -void astInitTranMapVtab_( AstTranMapVtab *, const char *, int * ); - -/* Loader. */ -AstTranMap *astLoadTranMap_( void *, size_t, AstTranMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -/* None. */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckTranMap(this) astINVOKE_CHECK(TranMap,this,0) -#define astVerifyTranMap(this) astINVOKE_CHECK(TranMap,this,1) - -/* Test class membership. */ -#define astIsATranMap(this) astINVOKE_ISA(TranMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astTranMap astINVOKE(F,astTranMap_) -#else -#define astTranMap astINVOKE(F,astTranMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitTranMap(mem,size,init,vtab,name,map1,map2) \ -astINVOKE(O,astInitTranMap_(mem,size,init,vtab,name,astCheckMapping(map1),astCheckMapping(map2),STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitTranMapVtab(vtab,name) astINVOKE(V,astInitTranMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadTranMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadTranMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckTranMap to validate TranMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -/* None. */ -#endif - - - - - diff --git a/ast/unit.c b/ast/unit.c deleted file mode 100644 index 0ce3184..0000000 --- a/ast/unit.c +++ /dev/null @@ -1,6218 +0,0 @@ -/* -* Name: -* unit.c - -* Purpose: -* Implement unit conversion functions. - -* Description: -* This file implements the Unit module which is used for identifying -* units and transforming between them. It follows the recommendations -* for unit handling contained within FITS WCS paper I (Greisen & -* Calabretta). All methods have protected access. - -* Methods: -* astUnitMapper: Create a Mapping between two systems of units. -* astUnitLabel: Returns a label for a given unit symbol. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 10-DEC-2002 (DSB): -* Original version. -* 10-FEB-2004 (DSB): -* Added debug conditional code to keep track of memory leaks. -* 15-JUL-2004 (DSB): -* In astUnitMapper: if no Mapping can be found from input to -* output units (e.g. because fo the less than perfect simplication -* algorithm in SimplifyTree), try finding a Mapping from output to -* input units and inverting the result. -* 14-DEC-2004 (DSB): -* In CreateTree, move the invocation of FixConstants from after -* InvertConstants to before InvertConstants. This is because -* InvertConstants ignores nodes which contain all constant -* arguments. This results in constants not being inverted in -* expressions such as "1/60 deg" (because all arguments are -* constant in the the "1/60" node). -* 18-JAN-2005 (DSB): -* Fix memory leaks. -* 2-FEB-2005 (DSB): -* - Avoid using astStore to allocate more storage than is supplied -* in the "data" pointer. This can cause access violations since -* astStore will then read beyond the end of the "data" area. -* 15-FEB-2005 (DSB): -* - Modified CleanExp to fix up some common units mistakes. -* 21-FEB-2005 (DSB): -* - Modified CleanExp to accept as equivalent to -* ^. -* - Modified MakeTree to do case insensitive checking if case -* sensitive checking failsto produce a match to a multiplier/unit -* symbol combination. If this still produces no match, do a case -* insensitive match for multiplier/unit label. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 6-APR-2006 (DSB): -* Modify CleanExp to convert "MJY/STER" to standard form ("MJy/sr"). -* 7-JUL-2006 (DSB): -* Correct initialisation of "word" flag in CleanExp. -* 17-MAY-2007 (DSB): -* Simplify the units string returned by astUnitNormaliser. -* - Fix indexing bug in CombineFactors. -* 26-MAY-2007 (DSB): -* - Correct error reporting in astUNitNormaliser. -* - Fix bug in CleanExp that caused (for example) "-2" to be -* converted to "^-2". -* 2-DEC-2008 (DSB): -* Correct memory allocation bug in CleanExp. -* 6-MAY-2011 (DSB): -* Include "adu" as basic unit. -* 9-MAY-2011 (DSB): -* Change "A" to be Ampere (as defined by FITS-WCS paper 1) rather -* than "Angstrom". -*/ - -/* Module Macros. */ -/* ============== */ -/* Define the astCLASS macro (even although this is not a class - implementation) to obtain access to the protected error and memory - handling functions. */ -#define astCLASS -#define PI 3.141592653589793 -#define E 2.718281828459045 - -/* Macro which returns the nearest integer to a given floating point - value. */ -#define NINT(x) (int)((x)+(((x)>0.0)?0.5:-0.5)) - -/* Macro identifying a character as lower or upper case letter, digit or -+ or -. */ -#define ISWORD(c) (isalnum(c)||((c)=='+')||((c)=='-')) - -/* The number of basic dimension quantities used for dimensional analysis. - In addition to the usual M, L and T, this includes pseudo-dimensions - describing strictly dimensionless quantities such as plane angle, - magnitude, etc. */ -#define NQUANT 10 - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "error.h" -#include "memory.h" -#include "pointset.h" -#include "mapping.h" -#include "unitmap.h" -#include "zoommap.h" -#include "mathmap.h" -#include "unit.h" - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include - -#ifdef THREAD_SAFE -#include -#endif - -/* Module Type Definitions. */ -/* ======================== */ - -/* This declaration enumerates the codes for the operations which may - legally be included in a units expression. */ -typedef enum { - OP_LDCON, /* Load constant */ - OP_LDVAR, /* Load variable */ - OP_LOG, /* Common logarithm */ - OP_LN, /* Natural logarithm */ - OP_EXP, /* Natural exponential */ - OP_SQRT, /* Square root */ - OP_POW, /* Exponentiate */ - OP_DIV, /* Division */ - OP_MULT, /* Multiplication */ - OP_LDPI, /* Load constant PI */ - OP_LDE, /* Load constant E */ - OP_NULL /* Null operation */ -} Oper; - -/* A structure describing a standard multiplier prefix. */ -typedef struct Multiplier { - const char *label; /* Multipler label string (null terminated) */ - const char *sym; /* Multipler symbol string (null terminated) */ - int symlen; /* Length of symbol (without trailing null ) */ - int lablen; /* Length of label (without trailing null ) */ - double scale; /* The scale factor associated with the prefix */ - struct Multiplier *next; /* Next Multiplier in linked list */ -} Multiplier; - -/* A structure describing a single node in a tree representation of a - single units expression. */ -typedef struct UnitNode { - Oper opcode; /* Code for operation performed by this node */ - int narg; /* No. of arguments used by the operation */ - struct UnitNode **arg; /* Array of pointers to argument nodes */ - double con; /* Constant to be loaded by OP_LDCON operations */ - struct KnownUnit *unit; /* Known unit referred to by OP_LDVAR nodes */ - Multiplier *mult; /* Multiplier used by OP_LDVAR nodes */ - const char *name; /* User-defined unit referred to by OP_LDVAR - nodes (no multiplier prefix included) */ -} UnitNode; - -/* A structure describing a known unit. */ -typedef struct KnownUnit { - const char *sym; /* Unit symbol string (null terminated) */ - const char *label; /* Unit label string (null terminated) */ - int symlen; /* Length of symbol (without trailing null ) */ - int lablen; /* Length of label (without trailing null ) */ - struct UnitNode *head; /* Head of definition tree (NULL for basic units) */ - struct KnownUnit *next; /* Next KnownUnit in linked list */ - struct KnownUnit *use; /* KnownUnit to be used in place of this one */ -} KnownUnit; - -/* Module Variables. */ -/* ================= */ - -/* A pointer to the KnownUnit structure at the head of a linked list of - such structures containing definitions of all known units. */ -static KnownUnit *known_units = NULL; - -/* An array of pointers to KnownUnits which list the basic quantities -used in dimensional analysis. */ -static KnownUnit *quant_units[ NQUANT ]; - -/* A pointer to the Multiplier structure at the head of a linked list of - such structures containing definitions of all known multipliers. */ -static Multiplier *multipliers = NULL; - -/* Set up mutexes */ -#ifdef THREAD_SAFE - -static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX1 pthread_mutex_lock( &mutex1 ); -#define UNLOCK_MUTEX1 pthread_mutex_unlock( &mutex1 ); - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -#else - -#define LOCK_MUTEX1 -#define UNLOCK_MUTEX1 - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#endif - -/* Prototypes for Private Functions. */ -/* ================================= */ -static AstMapping *MakeMapping( UnitNode *, int * ); -static KnownUnit *GetKnownUnits( int, int * ); -static Multiplier *GetMultipliers( int * ); -static UnitNode *ConcatTree( UnitNode *, UnitNode *, int * ); -static UnitNode *CopyTree( UnitNode *, int * ); -static UnitNode *CreateTree( const char *, int, int, int * ); -static UnitNode *FixUnits( UnitNode *, UnitNode *, int * ); -static UnitNode *FreeTree( UnitNode *, int * ); -static UnitNode *MakeTree( const char *, int, int, int * ); -static UnitNode *MakeLabelTree( const char *, int, int * ); -static UnitNode *NewNode( UnitNode *, Oper, int * ); -static UnitNode *CombineFactors( UnitNode **, double *, int, double, int * ); -static const char *CleanExp( const char *, int * ); -static int EndsWith( const char *, int, const char *, int * ); -static int CmpTree( UnitNode *, UnitNode *, int, int * ); -static void FixConstants( UnitNode **, int, int * ); -static void InvertConstants( UnitNode **, int * ); -static UnitNode *InvertTree( UnitNode *, UnitNode *, int * ); -static void LocateUnits( UnitNode *, UnitNode ***, int *, int * ); -static void MakeKnownUnit( const char *, const char *, const char *, int * ); -static void MakeUnitAlias( const char *, const char *, int * ); -static void RemakeTree( UnitNode **, int * ); -static int SimplifyTree( UnitNode **, int, int * ); -static int ComplicateTree( UnitNode **, int * ); -static int ReplaceNode( UnitNode *, UnitNode *, UnitNode *, int * ); -static void FindFactors( UnitNode *, UnitNode ***, double **, int *, double *, int * ); -static const char *MakeExp( UnitNode *, int, int, int * ); -static int DimAnal( UnitNode *, double[NQUANT], double *, int * ); -static int Ustrcmp( const char *, const char *, int * ); -static int Ustrncmp( const char *, const char *, size_t, int * ); -static int SplitUnit( const char *, int, const char *, int, Multiplier **, int *, int * ); -static UnitNode *ModifyPrefix( UnitNode *, int * ); -static int ConStart( const char *, double *, int *, int * ); - -/* Debug functions... -static const char *DisplayTree( UnitNode *, int ); -static void OpSym( UnitNode *, char * ); -static const char *OpName( Oper ); -static const char *TreeExp( UnitNode * ); -*/ - -/* Function implementations. */ -/* ========================= */ -static const char *CleanExp( const char *exp, int *status ) { -/* -* Name: -* CleanExp - -* Purpose: -* Produce a clean copy of a units expression. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* const char *CleanExp( const char *exp ) - -* Class Membership: -* Unit member function. - -* Description: -* This function returns a pointer to dynamic memory containing a -* cleaned copy of the supplied units expression. Cleaning consists of -* the following operations: -* - removal of leading and trailing white space. -* - replacement of multiple adjacent spaces by a single space -* - removal of spaces adjacent to a parenthesis -* - removal of spaces adjacent to a binary operator -* - translates various common non-standard units into equivalent -* standard units. -* -* Such carefull handling of spaces is necessary since a space is -* recognised by the MakeTree function as a multiplication operator. - -* Parameters: -* exp -* A pointer to the expression to be cleaned. - -* Returned Value: -* A pointer to the cleaned expression, which should be freed using -* astFree when no longer needed. - -* Notes: -* - This function returns NULL if it is invoked with the global error -* status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - char **tok; - char *p; - char *r; - char *result; - char *s; - char *t; - char *w; - const char *start; - int i; - int l; - int len; - char *tt; - int ntok; - int po; - int ps; - int word; - -/* Initialise */ - result = NULL; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Split the supplied string up into tokens. Each block of contiguous - alphanumeric characters is a token. Each contiguous block of - non-alphanumerical characters is also a token. The + and - signs are - counted as alphanumeric. */ - start = exp; - p = (char *) exp - 1; - word = ISWORD( *( p + 1 ) ); - ntok = 0; - tok = NULL; - while( *(++p) ){ - if( word ) { - if( !ISWORD( *p ) ) { - l = p - start; - t = astStore( NULL, start, l + 1 ); - if( t ) t[ l ] = 0; - tok = astGrow( tok, ntok + 1, sizeof( char * ) ); - if( tok ) tok[ ntok++ ] = t; - start = p; - word = 0; - } - } else { - if( ISWORD( *p ) ) { - l = p - start; - t = astStore( NULL, start, l + 1 ); - if( t ) t[ l ] = 0; - tok = astGrow( tok, ntok + 1, sizeof( char * ) ); - if( tok ) tok[ ntok++ ] = t; - start = p; - word = 1; - } - } - } - - l = p - start; - t = astStore( NULL, start, l + 1 ); - if( t ) t[ l ] = 0; - tok = astGrow( tok, ntok + 1, sizeof( char * ) ); - if( tok ) tok[ ntok++ ] = t; - -/* Check the tokens for known non-standard unit syntax, and replace with the - equivalent standard syntax. Starlink SPLAT has a class called UnitUtilities - which has more of these common units mistakes. AST has to be a bit - more conservative than SPLAT though because of its wider remit. */ - len = 0; - tt = NULL; - for( i = 0; i < ntok; i++ ) { - t = tok[ i ]; - l = strlen( t ); - tt = astStore( tt, t, l + 1 ); - -/* Any alphabetical word followed by a digit is taken as ^. - Any alphabetical word followed by a sign and a digit is taken as - ^. */ - if( l > 1 && *t != '-' && *t != '+' && - strcspn( t, "0123456789" ) == l - 1 ) { - tok[ i ] = astMalloc( l + 2 ); - if( tok[ i ] ) { - strcpy( tok[ i ], t ); - w = t + l - 2; - if( *w != '+' && *w != '-' ) { - tok[ i ][ l - 1 ] = '^'; - strcpy( tok[ i ] + l, t + l - 1 ); - } else { - tok[ i ][ l - 2 ] = '^'; - strcpy( tok[ i ] + l - 1, t + l - 2 ); - } - t = astFree( t ); - } - l++; - -/* If the word ends with "micron" change to "(m*1.0E-6)". Should be OK - for things like "Kmicron". */ - } else if( ( s = strstr( t, "micron" ) ) ) { - tok[ i ] = astMalloc( s - t + 11 ); - if( tok[ i ] ) { - w = tok[ i ]; - *(w++) = '('; - if( s > t ) { - strncpy( w, t, s - t ); - w += s - t; - } - strcpy( w, "m*1.0E-6)" ); - l = s - t + 11; - t = astFree( t ); - } - -/* Convert "STER" to "sr". */ - } else if( !Ustrcmp( t, "STER", status ) ) { - tok[ i ] = astStore( NULL, "sr", 3 ); - l = 2; - t = astFree( t ); - -/* If the word ends with "JY" and is preceded by a single character, change - to "Jy". Should be OK for things like "MJY". */ - } else if( l == 3 && !strcmp( t + 1, "JY" ) ) { - tok[ i ][ 2 ] = 'y'; - -/* If the word begins with "nano" (case-insensitive) change "nano" to - "n". Such changes are usually handled by SplitUnit, but we need to - handle this as a special case here since scanf seems to read "nan" as - a string representation of NaN. */ - } else if( !Ustrncmp( t, "nano", 4, status ) ) { - tok[ i ] = astStore( NULL, t + 3, l - 2 ); - if( tok[ i ] ) { - *(tok[ i ]) = 'n'; - t = astFree( t ); - } - l -= 3; - } - -/* Update the total length of the string. */ - len += l; - } - tt = astFree( tt ); - -/* Concatentate the tokens into a single string, freeing the individual - strings. */ - result = astMalloc( len + 1 ); - if( result ) { - p = result; - for( i = 0; i < ntok; i++ ) { - len = strlen( tok[ i ] ); - memcpy( p, tok[ i ], len ); - p += len; - tok[ i ] = astFree( tok[ i ] ); - } - *p = 0; - tok = astFree( tok ); - -/* Now do other cleaning. - ---------------------- */ - -/* Initialise a pointer to the previous character read from the string. */ - r = result - 1; - -/* Initialise a pointer to the next character to be written to the string. */ - w = result; - -/* Pretend the previous character written to the string was a space. */ - ps = 1; - -/* Read all the supplied string, copying it to earlier parts of the - string discarding leading spaces and multiple adjacent embedded spaces in - the process. */ - while( *(++r) ) { - -/* If the character read is a space, only write it to the string if the - previous character written was not a space (in which case set a flag - to indicate that the previous character written to the string is now a - space). */ - if( isspace( *r ) ) { - if( !ps ) { - *(w++) = *r; - ps = 1; - } - -/* Write all non-space characters to the string, and clear the flag which - indicates if the previous character written to the string was a space. */ - } else { - *(w++) = *r; - ps = 0; - } - } - -/* If the last character written to the string was a space, reduce the - length of the string by one since we do not want any trailing spaces. */ - if( ps ) w--; - -/* Terminate the string. */ - *w = 0; - -/* We now need to pass through the string again, this time removing any - spaces which are adjacent to a binary operator or a parenthesis. */ - r = result - 1; - w = result; - ps = 0; - po = 0; - while( *(++r) ) { - -/* If the current character is a space, only write it if the previous - written character was not an operator or parenthesis. */ - if( isspace( *r ) ) { - if( !po ) { - *(w++) = *r; - po = 1; - ps = 1; - } - -/* If the current character is an operator or parenthesis, back up one - character before writing it out if the previous written character was - a space. */ - } else if( *r == '*' || *r == '/' || *r == '^' || *r == '.' || - *r == ')' || *r == '(' ) { - if( ps ) w--; - *(w++) = *r; - po = 1; - ps = 0; - -/* If the current character is not a space and not an operator symbol, - just write it out. */ - } else { - *(w++) = *r; - po = 0; - ps = 0; - } - } - -/* Terminate the string. */ - if( ps ) w--; - *w = 0; - - } - -/* Return the result. */ - return (const char *) result; -} - -static int CmpTree( UnitNode *tree1, UnitNode *tree2, int exact, int *status ) { -/* -* Name: -* CmpTree - -* Purpose: -* Compares two trees of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* int CmpTree( UnitNode *tree1, UnitNode *tree2, int exact, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function returns a zero value if the two trees are -* equivalent. This requires the trees to have identical structure -* except that, if "exact" is zero, arguments for OP_MULT nodes can -* be swapped. -* -* If the trees are not equivalent then a value of +1 or -1 is returned -* depending on whether tree1 should be placed before or after tree2 -* in a sorted list of trees. - -* Parameters: -* tree1 -* A pointer to the UnitNode at the head of the first tree. -* tree2 -* A pointer to the UnitNode at the head of the second tree. -* exact -* If non-zero, then OP_MULT nodes must have their arguments the -* same way round in order for the OP_MULT nodes to match. Otherwise, -* OP_MULT nodes with equivalent arguments match even if the -* arguments are swapped. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the two trees are equal. +1 if tree1 should be placed before -* tree2 in a sorted list of trees. -1 if tree1 should be placed after -* tree2 in a sorted list of trees. - -* Notes: -* - Zero is returned if an error has already occurred, or -* if this function fails for any reason. - -*/ - -/* Local Variables: */ - int result; - int i; - Oper op; - -/* Initialise. */ - result = 0; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* If the op codes differ, compare them as integers. */ - op = tree1->opcode; - if( op != tree2->opcode ) { - result = ( op > tree2->opcode ) ? 1: -1; - -/* If both supplied nodes are OP_LDVAR nodes, compare the associated names. */ - } else if( op == OP_LDVAR ){ - result = strcmp( tree1->name, tree2->name ); - -/* If both supplied nodes are constant nodes, compare the constant values. */ - } else if( tree1->con != AST__BAD ){ - result = astEQUAL( tree1->con, tree2->con ) ? 0 : ( - ( tree1->con > tree2->con ) ? 1 : -1 ); - -/* Otherwise, compare the arguments for the node. */ - } else { - for( i = 0; i < tree1->narg; i++ ) { - result = CmpTree( tree1->arg[ i ], tree2->arg[ i ], exact, status ); - if( result ) break; - } - -/* If the head nodes of the two trees are OP_MULT nodes, and the above - check determined they are different, this may be just because they - have their operands swapped. If "exact" si zero, this is considered an - insignificant difference between the two trees which we should ignore. - To check for this try comparing the arguments again, this time swapping - the arguments of tree2. */ - if( result && op == OP_MULT && !exact ) { - for( i = 0; i < tree1->narg; i++ ) { - result = CmpTree( tree1->arg[ i ], tree2->arg[ 1 - i ], 0, status ); - if( result ) break; - } - } - } - -/* If an error has occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the answer. */ - return result; -} - -static UnitNode *CombineFactors( UnitNode **factors, double *powers, - int nfactor, double coeff, int *status ) { -/* -* Name: -* CombineFactors - -* Purpose: -* Create a tree which represents the product of the supplied factors. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *CombineFactors( UnitNode **factors, double *powers, -* int nfactor, double coeff, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function createa a tree of UnitNodes which represents the -* product of the supplied factors, and the supplied coefficient. -* The factors are sorted before being combined, using the sort order -* implemented by the CmpTree function. - -* Parameters: -* factors -* A pointer to an array with "nfactor" elements, each element being -* a pointer to a UnitNode which is a factor of the required tree. -* On exit, the array is sorted. -* powers -* A pointer to an array with "nfactor" elements, each element being a -* double holding the power of the associated factor in "factors". -* On exit, the array reflects the sorting applied to "factors". -* nfactor -* The number of elements in the "factors" and "powers" arrays. -* coeff -* The overall coefficient to be applied to the product of the factors. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a UnitNode which is at the head of the new tree. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or -* if this function fails for any reason. - -*/ - -/* Local Variables: */ - UnitNode *result; - int i; - int j; - int jp; - int done; - UnitNode *ftmp; - UnitNode *node1; - UnitNode *node2; - UnitNode *pnode; - double ptmp; - -/* Initialise. */ - result = NULL; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Sort the supplied list of factors, modifying the powers array - correspondingly. A simple bubblesort algorithm is used since there - will only be a handfull of factors. */ - for( i = nfactor - 1; i > 0; i-- ) { - done = 1; - for( j = 0, jp = 1; j < i; j++, jp++ ) { - if( CmpTree( factors[ j ], factors[ jp ], 0, status ) > 0 ) { - ftmp = factors[ j ]; - factors[ j ] = factors[ jp ]; - factors[ jp ] = ftmp; - - ptmp = powers[ j ]; - powers[ j ] = powers[ jp ]; - powers[ jp ] = ptmp; - - done = 0; - } - } - if( done ) break; - } - -/* The first root term of the returned tree is the coefficient, unless the - coefficient is 1.0, in which case it will be the first factor. */ - if( coeff != 1.0 ) { - node1 = NewNode( NULL, OP_LDCON, status ); - if( astOK ) node1->con = coeff; - } else { - node1 = NULL; - } - -/* Loop through the factors. */ - for( i = 0; i < nfactor; i++ ) { - -/* If the power of this factor is zero, we ignore the factor. */ - if( powers[ i ] != 0.0 ) { - -/* If the power of this factor is one, we use the factor directly. */ - if( astEQUAL( powers[ i ], 1.0 ) ) { - node2 = CopyTree( factors[ i ], status ); - -/* Otherwise, for non-zero, non-unity powers, we create a POW node for - the factor. */ - } else { - node2 = NewNode( NULL, OP_POW, status ); - pnode = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - pnode->con = powers[ i ]; - node2->arg[ 0 ] = CopyTree( factors[ i ], status ); - node2->arg[ 1 ] = pnode; - } - } - -/* We now combine node1 and node2 using an OP_MULT node, which becomes - the "node1" for the next pass. On the first pass we may have no node1 (if - the supplied coefficient was 1.0), in which case we reserve the current - node2 as the node1 for the next pass. */ - if( node1 ) { - result = NewNode( NULL, OP_MULT, status ); - if( astOK ) { - result->arg[ 0 ] = node1; - result->arg[ 1 ] = node2; - node1 = result; - } - } else { - node1 = node2; - } - } - } - -/* Ensure we have a node to return. */ - if( astOK ) { - if( !result ) result = node1; - if( !result ) { - result = NewNode( NULL, OP_LDCON, status ); - if( astOK ) result->con = 1.0; - } - } - -/* If an error has occurred, free any new tree. */ - if( !astOK ) result = FreeTree( result, status ); - -/* Return the answer. */ - return result; -} - -static int ComplicateTree( UnitNode **node, int *status ) { -/* -* Name: -* ComplicateTree - -* Purpose: -* Removes standardisations introduced by SimplifyTree. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* int ComplicateTree( UnitNode **node ) - -* Class Membership: -* Unit member function. - -* Description: -* This function modifies a tree of UnitNodes by removing standardisations -* introduced by SimplifyTree. The standardisations removed are ones -* which would make the corresponding algebraic expression (as produced -* by MakeExp) unnatural to a human reader. - -* Parameters: -* node -* The address of a pointer to the UnitNode at the head of the tree -* which is to be complicated. On exit the supplied tree is freed and -* a pointer to a new tree is placed at the given address. - -* Returned Value: -* Non-zero if any change was introduced into the tree. - -*/ - -/* Local Variables: */ - int i; - UnitNode *newnode; - UnitNode *node1; - UnitNode *node2; - UnitNode *node3; - Oper op; - double con; - double fk; - int k; - int result; - double kcon; - -/* Initialise */ - result = 0; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Initiallially, we have no replacement node. */ - newnode = NULL; - node1 = NULL; - node3 = NULL; - -/* Complicate the sub-trees corresponding to the arguments of the node at - the head of the supplied tree. */ - for( i = 0; i < (*node)->narg; i++ ) { - if( ComplicateTree( &( (*node)->arg[ i ] ), status ) ) result = 1; - } - -/* Now undo specific simplifications appropriate to the nature of the node at - the head of the tree. */ - op = (*node)->opcode; - -/* If the head is an OP_MULT node with a constant first argument and - a "LN" second argument, rearrange the nodes to represent ln(x**k) instead - of k*ln(x). If k is an integer multiple of "0.1/ln(10)" convert the "ln" - function into a "log" (base 10) function. Check for "k==1" in which - case we do not need a POW node. */ - if( (*node)->opcode == OP_MULT ) { - - con = (*node)->arg[ 0 ]->con; - if( con != AST__BAD && (*node)->arg[ 1 ]->opcode == OP_LN ) { - fk = 10.0*con*log( 10.0 ); - k = NINT(fk); - if( astEQUAL(fk,((double)k)) ) { - newnode = NewNode( NULL, OP_LOG, status ); - con = k/10.0; - } else { - newnode = NewNode( NULL, OP_LN, status ); - } - - node2 = CopyTree( (*node)->arg[ 1 ]->arg[ 0 ], status ); - if( !astEQUAL( con, 1.0 ) ){ - node1 = CopyTree( (*node)->arg[ 0 ], status ); - node3 = NewNode( NULL, OP_POW, status ); - } - - if( astOK ) { - if( !astEQUAL( con, 1.0 ) ){ - node1->con = con; - node3->arg[ 0 ] = node2; - node3->arg[ 1 ] = node1; - newnode->arg[ 0 ] = node3; - } else { - newnode->arg[ 0 ] = node2; - } - } - -/* Replace "(A**-1)*B" with "B/A" */ - } else if( (*node)->arg[ 0 ]->opcode == OP_POW && - astEQUAL( (*node)->arg[ 0 ]->arg[ 1 ]->con, -1.0 )) { - newnode = NewNode( NULL, OP_DIV, status ); - if( astOK ) { - newnode->arg[ 0 ] = CopyTree( (*node)->arg[ 1 ], status ); - newnode->arg[ 1 ] = CopyTree( (*node)->arg[ 0 ]->arg[ 0 ], status ); - } - -/* Replace "B*(A**-1)" with "B/A" */ - } else if( (*node)->arg[ 1 ]->opcode == OP_POW && - astEQUAL( (*node)->arg[ 1 ]->arg[ 1 ]->con, -1.0 )) { - newnode = NewNode( NULL, OP_DIV, status ); - if( astOK ) { - newnode->arg[ 0 ] = CopyTree( (*node)->arg[ 0 ], status ); - newnode->arg[ 1 ] = CopyTree( (*node)->arg[ 1 ]->arg[ 0 ], status ); - } - -/* Convert (x**k)*(y**k) to (x*y)**k. */ - } else if( (*node)->arg[ 0 ]->opcode == OP_POW && - (*node)->arg[ 1 ]->opcode == OP_POW && - astEQUAL( (*node)->arg[ 0 ]->arg[ 1 ]->con, - (*node)->arg[ 1 ]->arg[ 1 ]->con )) { - newnode = NewNode( NULL, OP_POW, status ); - node1 = NewNode( NULL, OP_MULT, status ); - if( astOK ) { - node1->arg[ 0 ] = CopyTree( (*node)->arg[ 0 ]->arg[ 0 ], status ); - node1->arg[ 1 ] = CopyTree( (*node)->arg[ 1 ]->arg[ 0 ], status ); - newnode->arg[ 0 ] = node1; - newnode->arg[ 1 ] = CopyTree( (*node)->arg[ 0 ]->arg[ 1 ], status ); - } - -/* Convert c*sqrt(x) to sqrt((c**2)*x) (if c > 0). */ - } else if( (kcon=(*node)->arg[ 0 ]->con) != AST__BAD && - kcon > 0.0 && (*node)->arg[ 1 ]->opcode == OP_SQRT ) { - newnode = NewNode( NULL, OP_SQRT, status ); - node1 = NewNode( NULL, OP_MULT, status ); - node2 = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - node2->con = kcon*kcon; - node1->arg[ 0 ] = node2; - node1->arg[ 1 ] = CopyTree( (*node)->arg[ 1 ]->arg[ 0 ], status ); - newnode->arg[ 0 ] = node1; - } - } - -/* If the head node is a POW node, replace "x**0.5" by sqrt(x) */ - } else if( (*node)->opcode == OP_POW ) { - if( astEQUAL( (*node)->arg[ 1 ]->con, 0.5 ) ) { - newnode = NewNode( NULL, OP_SQRT, status ); - if( astOK ) { - newnode->arg[ 0 ] = CopyTree( (*node)->arg[ 0 ], status ); - } - } - } - -/* If we have produced a new node which is identical to the old node, - free it. Otherwise, indicate we have made some changes. */ - if( newnode ) { - if( !CmpTree( newnode, *node, 1, status ) ) { - newnode = FreeTree( newnode, status ); - } else { - result = 1; - } - } - -/* If an error has occurred, free any new node. */ - if( !astOK ) { - newnode = FreeTree( newnode, status ); - result = 0; - } - -/* If we have a replacement node, free the supplied tree and return a - pointer to the new tree. */ - if( newnode ) { - FreeTree( *node, status ); - *node = newnode; - } - -/* If the above produced some change, try simplifying (without - re-introducing the standardisation we have just got rid of!) and - then re-complicating the tree. */ - if( result ) { - SimplifyTree( node, 0, status ); - ComplicateTree( node, status ); - } - -/* Return the result. */ - return result; -} - -static UnitNode *ConcatTree( UnitNode *tree1, UnitNode *tree2, int *status ) { -/* -* Name: -* ConcatTree - -* Purpose: -* Concatenate two trees together. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *ConcatTree( UnitNode *tree1, UnitNode *tree2, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function a pointer to the head of a new tree of UnitNodes which -* is formed by feeding the output of "tree1" (i.e. the quantity -* represented by the node at the head of tree1) into the (single) -* input of "tree2" (i.e. the single OP_LDVAR Node containined within -* tree2). - -* Parameters: -* tree1 -* A pointer to the first tree. -* tree2 -* A pointer to the second tree. This should have no more than one -* OP_LDVAR node. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a UnitNode which is at the head of the new tree. - -* Notes: -* - If "tree2" contains zero units, a NULL pointer is returned but no -* error is reported. -* - If "tree2" contains more than one unit, an error is reported -* error is reported. -* - A NULL pointer is returned if an error has already occurred, or -* if this function fails for any reason. - -*/ - -/* Local Variables: */ - UnitNode *result; - UnitNode **units; - int nunits; - -/* Initialise. */ - result = NULL; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Produce a copy of tree2. */ - result = CopyTree( tree2, status ); - -/* Locate the OP_LDVAR node in the copy of tree2. */ - units = NULL; - nunits = 0; - LocateUnits( result, &units, &nunits, status ); - -/* If no OP_LDVAR nodes were found in tree2, we cannot concatenate the - trees. */ - if( nunits > 0 ) { - -/* Report an error if the number of pointers returned is larger than 1. */ - if( nunits > 1 && astOK ) { - astError( AST__INTER, "ConcatTree(unit): tree2 uses %d units - " - "should be 1 (internal AST programming error).", status, nunits ); - } - -/* Replace the OP_LDVAR node in the copy of tree2 with a copy of tree1. */ - if( astOK ) { - -/* If the node at the head of the supplied tree2 is the node to be - replaced, just free the tree created earlier and return a copy of - tree1. */ - if( units[ 0 ] == result ) { - FreeTree( result, status ); - result = CopyTree( tree1, status ); - -/* Otherwise, search for the node to be replaced and do the substitution - within the tree created earlier. */ - } else { - ReplaceNode( result, units[ 0 ], CopyTree( tree1, status ), status ); - } - } - } - -/* Free resources. */ - units = astFree( units ); - -/* If an error has occurred, free any new tree. */ - if( !astOK ) result = FreeTree( result, status ); - -/* Return the answer. */ - return result; -} - -static int ConStart( const char *text, double *val, int *nc, int *status ) { -/* -* Name: -* ConStart - -* Purpose: -* See if the supplied string starts with a literal numeric constant. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* int ConStart( const char *text, double *val, int *nc, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function checks if the supplied string starts with a literal -* numeric constant and returns it if it does. It is a wrap-up for scanf -* since scanf has non-standard behaviour on some platforms (e.g. Cygwin -* scanf interprets the character "n" as a floating point number!). - -* Parameters: -* text -* The text to check. -* val -* Address of a double to receive any numerical constant read -* from the start of the string. Unity is returned if the string -* does not start with a numerical constant. -* nc -* Address of an int to receive the number of characters used to -* create the value returned in "val". Zero is returned if the -* string does not start with a numerical constant. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the text started with a numerical constant. - -*/ - -/* Local Variables: */ - int result; - const char *c; - -/* Initialise */ - *nc = 0; - *val = 1.0; - -/* Return zero if no text was supplied */ - if( !text ) return 0; - -/* Use sscanf to see if the string begin with a numerical constant */ - result = astSscanf( text, "%lf%n", val, nc ); - -/* If so, check that the first non-blank character in the string - is not "N" (interpreted by Cygwin as numerical zero!). */ - if( result ) { - c = text; - while( isspace( *c ) ) c++; - if( *c == 'n' || *c == 'N' ) { - result = 0; - *nc = 0; - *val = 1.0; - } - } - -/* Return the result. */ - return result; -} - -static UnitNode *CopyTree( UnitNode *tree, int *status ) { -/* -* Name: -* CopyTree - -* Purpose: -* Create a new tree of UnitNodes containing a copy of a given tree. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *CopyTree( UnitNode *tree, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function creates a copy of the supplied tree of UnitNodes. - -* Parameters: -* tree -* The UnitNode at the head of the tree to be copied. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the UnitNode at the head of the new tree. - -* Notes: -* - A value of NULL will be returned if this function is invoked with -* the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - UnitNode **args; - UnitNode *result; - int i; - int narg; - -/* Initialise. */ - result = NULL; - -/* Check the inherited status. */ - if( !astOK || !tree ) return result; - -/* Create a new node to represent the head of the supplied tree. */ - result = astMalloc( sizeof( UnitNode ) ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Copy the fields of the supplied node. */ - narg = tree->narg; - - result->arg = NULL; - result->unit = tree->unit; - result->mult = tree->mult; - result->opcode = tree->opcode; - result->narg = narg; - result->con = tree->con; - result->name = tree->name ? astStore( NULL, tree->name, - strlen( tree->name ) + 1 ) : NULL; - -/* Create an array of UnitNode pointers for the arguments. */ - args = astMalloc( narg*sizeof( UnitNode * ) ); - if( astOK ) { - result->arg = args; - -/* Copy the sub-trees headed by the argument nodes. */ - for( i = 0; i < narg; i++ ) { - args[ i ] = CopyTree( tree->arg[ i ], status ); - } - } - } - -/* Free any result if an error occurred. */ - if( !astOK ) result = FreeTree( result, status ); - -/* Return the answer. */ - return result; -} - -static UnitNode *CreateTree( const char *exp, int basic, int lock, int *status ){ -/* -* Name: -* CreateTree - -* Purpose: -* Convert an algebraic units expression into a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *CreateTree( const char *exp, int basic, int lock, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function converts the supplied algebraic units expression into -* a tree of UnitNodes. The result tree can optionally be expanded to -* create a tree in which the "roots" (LDVAR nodes) all refer to -* basic units. - -* Parameters: -* exp -* The units expression. This should not include any leading or -* trailing spaces. -* basic -* Should the tree created from parsing "exp" be expanded so that -* the leaf nodes of the tree are all basic units? -* lock -* Use a mutex to guard access to the KnownUnits list? -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a UnitNode which forms the head of a tree of UnitNodes -* representing the supplied unit expression. - -* Notes: -* - A NULL value is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - UnitNode *result; - const char *cleanex; - -/* Initialise */ - result = NULL; - -/* Check the global error status, and that we have a string. */ - if ( !astOK ) return result; - -/* Produce a clean copy of the supplied string. This has no leading - or trailing white space, and any spaces adjacent to operators within - the string are removed (this is needed because spaces are treated as - multiplication symbols). */ - cleanex = CleanExp( exp, status ); - -/* If the string is blank, return the NULL pointer. Otherwise, create a - tree of UnitNodes describing the units. The returned tree has LDVAR - nodes which refer to the unit symbols contained in the supplied string. */ - if( cleanex && (*cleanex) ) { - result = MakeTree( cleanex, strlen( cleanex ), lock, status ); - -/* Replace each subtree which simply combines constants (i.e. which has no - OP_LDVAR nodes) with a single OP_LDCON node. */ - FixConstants( &result, 0, status ); - -/* Invert literal constant unit multipliers. */ - InvertConstants( &result, status ); - -/* Now replace each LDVAR node which refers to a known derived unit with - a sub-tree which defines the derived unit in terms of known basic units. - The LDVAR nodes in the resulting tree all refer to basic units. */ - if( basic ) RemakeTree( &result, status ); - } - -/* Free resources. */ - cleanex = astFree( (void *) cleanex ); - -/* Free any returned tree if an error has occurred. */ - if( !astOK ) result = FreeTree( result, status ); - -/* Return the result. */ - return result; -} - -static int DimAnal( UnitNode *node, double powers[NQUANT], double *scale, int *status ) { -/* -* Name: -* DimAnal - -* Purpose: -* Perform a dimensional analysis of a unit tree. - -* Type: -* Protected function. - -* Synopsis: -* #include "unit.h" -* int DimAnal( UnitNode *node, double powers[NQUANT], double *scale, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function returns a set of powers and a scaling factor which -* represent the units tree. - -* Parameters: -* node -* Pointer to the UnitNode at the head of the unit tree. -* powers -* An array in which are returned the powers for each of the following -* basic units (in the order shown): kilogramme, metre, second, radian, -* Kelvin, count, adu, photon, magnitude, pixel. If the supplied unit -* does not depend on a given basic unit a value of 0.0 will be returned -* in the array. The returns values represent a system of units which is -* a scaled form of the supplied units, expressed in the basic units of -* m, kg, s, rad, K, count, adu, photon, mag and pixel. For instance, a -* returned array of [1,0,-2,0,0,0,0,0,0,0] would represent "m/s**2". -* scale -* Pointer to a location at which to return a scaling factor for the -* supplied units. The is the value, in the units represented by the -* returned powers, which corresponds to a value of 1.0 in the supplied -* units. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the tree was analysed succesfully. Zero otherwise. - -* Notes: -* - Zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Variables; */ - Oper oper; - int result; - int i; - double p0[ NQUANT ]; - double p1[ NQUANT ]; - double s0; - double s1; - -/* Check inherited status */ - if( !astOK ) return 0; - -/* Initialise the powers of all dimensions to zero, and set the scaling - factor to unity. */ - result = 1; - *scale = 1.0; - for( i = 0; i < NQUANT; i++ ) powers[ i ] = 0.0; - -/* Load constant: constant is dimensionaless so leave powers unchanged, - and set the scaling factor. */ - oper = node->opcode; - if( oper == OP_LDCON ) { - *scale = 1.0/node->con; - -/* Load variable: check it is one of the basic known dimensional - quantities. If so, set the power of the quantity to unity and store - the scale factor. If the unit is "g" modify the scale factor so that - the analysis quantity is "kg". */ - } else if( oper == OP_LDVAR ) { - result = 0; - for( i = 0; i < NQUANT; i++ ) { - if( node->unit == quant_units[ i ] ) { - powers[ i ] = 1.0; - *scale = node->mult ? 1.0/node->mult->scale : 1.0; - if( !strcmp( node->unit->sym, "g" ) ) *scale *= 0.001; - result = 1; - break; - } - } - -/* How does dimensional analysis handle log or exp units?*/ - } else if( oper == OP_LOG ) { - result= 0; - - } else if( oper == OP_LN ) { - result= 0; - - } else if( oper == OP_EXP ) { - result= 0; - -/* Get the powers for the child unit and then multiply each by 0.5 and - take the square root of the scale factor. */ - } else if( oper == OP_SQRT ) { - result = DimAnal( node->arg[0], powers, scale, status ); - if( result ) { - for( i = 0; i < NQUANT; i++ ) powers[ i ]*= 0.5; - *scale = sqrt( *scale ); - } - -/* Similarly for pow nodes. */ - } else if( oper == OP_POW ) { - result = DimAnal( node->arg[0], powers, scale, status ); - if( result ) { - double power = node->arg[1]->con; - for( i = 0; i < NQUANT; i++ ) powers[ i ]*= power; - *scale = pow( *scale, power ); - } - -/* Binary operators. Analyses the operands dimensions and combine. */ - } else if( oper == OP_DIV ) { - if( DimAnal( node->arg[0], p0, &s0, status ) && - DimAnal( node->arg[1], p1, &s1, status ) ) { - for( i = 0; i < NQUANT; i++ ) powers[ i ] = p0[ i ] - p1[ i ]; - *scale = s0/s1; - } else { - result = 0; - } - - } else if( oper == OP_MULT ) { - if( DimAnal( node->arg[0], p0, &s0, status ) && - DimAnal( node->arg[1], p1, &s1, status ) ) { - for( i = 0; i < NQUANT; i++ ) powers[ i ] = p0[ i ] + p1[ i ]; - *scale = s0*s1; - } else { - result = 0; - } - -/* Named constants are dimensionless */ - } else if( oper == OP_LDPI ) { - *scale = 1.0/PI; - - } else if( oper == OP_LDE ) { - *scale = 1.0/E; - - } - - return result; - -} - -static int EndsWith( const char *c, int nc, const char *test, int *status ){ -/* -* Name: -* EndsWith - -* Purpose: -* See if a string ends with another string - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* int EndsWith( const char *c, int nc, const char *test, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function sees if the string given by "c" ends with the string -* given by "test". The comparison is case-insensitive. - -* Parameters: -* c -* A pointer to the last character in the string to be tested. -* nc -* The number of characters in the string to be tested. -* test -* A pointer to the string to be tested for. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the string "c" ends with the string "test". - -*/ - -/* Local Variables: */ - const char *start; - int i; - int result; - int tlen; - -/* initialise. */ - result = 0; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Check the string being tested for is not longer than the string being - tested. */ - tlen = strlen( test ); - if( tlen <= nc ){ - -/* Get a pointer to where the matching string would start if the string "c" - ends with the required string "test". */ - start = c - tlen + 1; - -/* Do the comparison. */ - result = 1; - for( i = 0; i < tlen; i++ ) { - if( tolower( start[ i ] ) != tolower( test[ i ] ) ) { - result = 0; - break; - } - } - } - -/* Return the result. */ - return result; - -} - -static void FindFactors( UnitNode *node, UnitNode ***factors, double **powers, - int *nfactor, double *coeff, int *status ){ -/* -* Name: -* FindFactors - -* Purpose: -* Find the factors within an expression given by a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* void FindFactors( UnitNode *node, UnitNode ***factors, double **powers, -* int *nfactor, double *coeff, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function analyses the supplied tree of UnitNoes and returns -* an array of pointers to nodes within the supplied tree which form -* factors of the tree. The power associated with each factor is also -* returned, together with an overall coefficient for the tree. The -* expression represented by the tree is thus the product of the -* coefficient with each of the factors, each raised to the associated -* power. - -* Parameters: -* node -* A pointer to the UnitNode at the head of the tree which is to be -* analysed. -* factors -* The address at which to return a pointer to an array with "*nfactor" -* elements, each element being a pointer to a UnitNode within the -* supplied tree which is a factor of the supplied tree. -* powers -* The address at which to return a pointer to an array with "*nfactor" -* elements, each element being a double holding the power of the -* associated factor in "*factors". -* nfactor -* The address of an int containing the number of elements in the -* returned "*factors" and "*powers" arrays. -* coeff -* The address of a double containing the overall coefficient to be -* applied to the product of the factors. -* status -* Pointer to the inherited status variable. - -* Notes: -* - If the supplied node is a constant node, then "*coeff" is -* returned holding the value of the constant and "*nfactor" is returned -* equal to zero ("*factors" and "*powers" are returned holding NULL). -* - If an error has already occurred, or if this function fails, then -* "*factors" and "*powers" are returned holding NULL, "*nfactor" is -* returned holding zero and "*coeff" is returned holding 1.0. - -*/ - -/* Local Variables: */ - int i; - int j; - int found; - UnitNode **fact1; - double *pow1; - double coeff1; - int nfac1; - double con; - -/* Initialise */ - *factors = NULL; - *powers = NULL; - *nfactor = 0; - *coeff = 1.0; - -/* Check inherited status. */ - if( !astOK ) return; - -/* If the node at the head of the supplied tree is an OP_MULT node... */ - if( node->opcode == OP_MULT ) { - -/* Find the factors of the two arguments of the OP_MULT node. */ - FindFactors( node->arg[ 0 ], factors, powers, nfactor, coeff, status ); - FindFactors( node->arg[ 1 ], &fact1, &pow1, &nfac1, &coeff1, status ); - -/* Combine the two lists. Loop round the factors of the seocnd argument. */ - for( i = 0; i < nfac1; i++ ) { - -/* See if there is already an equivalent factor in the returned list of - factors. */ - found = 0; - for( j = 0; j < *nfactor; j++ ) { - if( !CmpTree( (*factors)[ j ], fact1[ i ], 0, status ) ){ - found = 1; - break; - } - } - -/* If so, increment the power of the factor. */ - if( found ) { - (*powers)[ j ] += pow1[ i ]; - -/* Otherwise, add the factor to the end of the returned list. */ - } else { - *factors = astGrow( *factors, *nfactor + 1, sizeof( UnitNode *) ); - *powers = astGrow( *powers, *nfactor + 1, sizeof( double ) ); - if( astOK ) { - (*factors)[ *nfactor ] = fact1[ i ]; - (*powers)[ (*nfactor)++ ] = pow1[ i ]; - } - } - } - -/* Modify the overall coefficient. */ - *coeff *= coeff1; - -/* Free resources */ - fact1 = astFree( fact1 ); - pow1 = astFree( pow1 ); - -/* If the node at the head of the supplied tree is an OP_POW node, */ - } else if( node->opcode == OP_POW ) { - -/* Find the factors of the first argument. */ - FindFactors( node->arg[ 0 ], factors, powers, nfactor, coeff, status ); - -/* Multiply all the factor powers by the constant exponent of the POW - node. */ - con = node->arg[ 1 ]->con; - for( j = 0; j < *nfactor; j++ ) { - (*powers)[ j ] *= con; - } - -/* Exponentiate the coefficient. */ - if( *coeff >= 0.0 || (int) con == con ) { - *coeff = pow( *coeff, con ); - } else { - astError( AST__BADUN, "Simplifying a units expression requires a " - "negative value to be raised to a non-intergal power." , status); - } - -/* If the node at the head of the supplied tree is an OP_DIV node, */ - } else if( node->opcode == OP_DIV ) { - -/* Find the factors of the two arguments of the OP_DIV node. */ - FindFactors( node->arg[ 0 ], factors, powers, nfactor, coeff, status ); - FindFactors( node->arg[ 1 ], &fact1, &pow1, &nfac1, &coeff1, status ); - -/* Combine the two lists. Loop round the factors of the second argument - (the denominator). */ - for( i = 0; i < nfac1; i++ ) { - -/* See if there is already an equivalent factor in the returned list of - factors. */ - found = 0; - for( j = 0; j < *nfactor; j++ ) { - if( !CmpTree( (*factors)[ j ], fact1[ i ], 0, status ) ){ - found = 1; - break; - } - } - -/* If so, decrement the power of the factor. */ - if( found ) { - (*powers)[ j ] -= pow1[ i ]; - -/* Otherwise, add the factor to the end of the returned list, with a - negated power. */ - } else { - *factors = astGrow( *factors, *nfactor + 1, sizeof( UnitNode *) ); - *powers = astGrow( *powers, *nfactor + 1, sizeof( double ) ); - if( astOK ) { - (*factors)[ *nfactor ] = fact1[ i ]; - (*powers)[ (*nfactor)++ ] = -pow1[ i ]; - } - } - } - -/* Modify the overall coefficient. */ - if( coeff1 != 0.0 ) { - *coeff /= coeff1; - } else { - astError( AST__BADUN, "Simplifying a units expression" - "requires a division by zero." , status); - } - -/* Free resources */ - fact1 = astFree( fact1 ); - pow1 = astFree( pow1 ); - -/* If the node at the head of the supplied tree is an OP_SQRT node, */ - } else if( node->opcode == OP_SQRT ) { - -/* Find the factors of the argument. */ - FindFactors( node->arg[ 0 ], factors, powers, nfactor, coeff, status ); - -/* Multiply all the factor powers by 0.5. */ - for( j = 0; j < *nfactor; j++ ) { - (*powers)[ j ] *= 0.5; - } - -/* Square root the coefficient. */ - if( *coeff >= 0.0 ) { - *coeff = sqrt( *coeff ); - } else { - astError( AST__BADUN, "Simplifying a units expression requires " - "the square root of a negative value to be taken." , status); - } - -/* If the node at the head of the supplied tree is constant we have no - factors but we have a coeffcient. */ - } else if( node->con != AST__BAD ) { - *coeff = node->con; - -/* Other nodes have no factors other than themselves, so just return a - pointer to the supplied node. */ - } else { - *factors = astMalloc( sizeof( UnitNode *) ); - *powers = astMalloc( sizeof( double ) ); - if( astOK ) { - *nfactor = 1; - (*factors)[ 0 ] = node; - (*powers)[ 0 ] = 1.0; - *coeff = 1.0; - } - } - -/* If an error has occurred, free any returned resources. */ - if( !astOK ) { - *factors = astFree( *factors ); - *powers = astFree( *powers ); - *nfactor = 0; - *coeff = 1.0; - } -} - -static void FixConstants( UnitNode **node, int unity, int *status ) { -/* -* Name: -* FixConstants - -* Purpose: -* Take the reciprocal of all constants in a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* void FixConstants( UnitNode **node, int unity, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function replaces sub-trees which have a constant value by -* a single OP_LDCON node which loads the appropriate constant. - -* Parameters: -* node -* The address of a pointer to the UnitNode at the head of the tree -* which is to be fixed. On exit the supplied tree is freed and a -* pointer to a new tree is palced at he given address. -* unity -* If non-zero, then all multiplicative constants are set to 1.0, and -* their original values are forgotten, but only if the other -* argument of the OP_MULT node is an OP_LDVAR, OP_POW or OP_SQRT Node. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int i; - UnitNode *newnode; - int allcon; - Oper op; - double newcon; - -/* Check inherited status and pointer. */ - if( !astOK || !node || !(*node) ) return; - -/* Initiallially, we have no replacement node */ - newnode = NULL; - newcon = AST__BAD; - -/* There is nothing to fix if the node has no arguments. */ - if( (*node)->narg > 0 ) { - -/* Note the op code for the node. */ - op = (*node)->opcode; - -/* Fix up the argument nodes. Also note if all the arguments are - constants. */ - allcon = 1; - for( i = 0; i < (*node)->narg; i++ ) { - FixConstants( &( (*node)->arg[ i ] ), unity, status ); - if( (*node)->arg[ i ]->con == AST__BAD ) allcon = 0; - } - -/* If an OP_MULT nodes within a simplified tree has a constant argument, - it will always be argument zero. If this is an OP_MULT node and arg[0] - is constant and "unity" is non-zero and arg[1] is an OP_LDVAR, OP_POW - or OP_SQRT node, replace the constant value by 1.0. */ - if( unity && op == OP_MULT && - (*node)->arg[ 0 ]->con != AST__BAD && - ( (*node)->arg[ 1 ]->opcode == OP_LDVAR || - (*node)->arg[ 1 ]->opcode == OP_SQRT || - (*node)->arg[ 1 ]->opcode == OP_POW ) ) { - (*node)->arg[ 0 ]->con = 1.0; - } - -/* If the arguments of this node are all constants, replace the node by - an OP_LDCON node which loads the resulting constant value. */ - if( allcon ) { - if( (*node)->narg > 0 ) { - newnode = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - if( op == OP_LOG ) { - if( (*node)->arg[ 0 ]->con > 0.0 ) { - newcon = log10( (*node)->arg[ 0 ]->con ); - } else { - astError( AST__BADUN, "Illegal negative or zero constant " - "value '%g' encountered.", status, - (*node)->arg[ 0 ]->con ); - } - } else if( op == OP_LN ){ - if( (*node)->arg[ 0 ]->con > 0.0 ) { - newcon = log( (*node)->arg[ 0 ]->con ); - } else { - astError( AST__BADUN, "Illegal negative or zero constant value " - "'%g' encountered.", status, (*node)->arg[ 0 ]->con ); - } - } else if( op == OP_EXP ){ - newcon = exp( (*node)->arg[ 0 ]->con ); - - } else if( op == OP_SQRT ){ - if( (*node)->arg[ 0 ]->con >= 0.0 ) { - newcon = sqrt( (*node)->arg[ 0 ]->con ); - } else { - astError( AST__BADUN, "Illegal negative constant value " - "'%g' encountered.", status, (*node)->arg[ 0 ]->con ); - } - - } else if( op == OP_POW ){ - if( (*node)->arg[ 0 ]->con >= 0.0 || - (int) (*node)->arg[ 1 ]->con == (*node)->arg[ 1 ]->con ) { - newcon = pow( (*node)->arg[ 0 ]->con, - (*node)->arg[ 1 ]->con ); - } else { - astError( AST__BADUN, "Illegal negative constant value " - "'%g' encountered.", status, (*node)->arg[ 0 ]->con ); - } - - } else if( op == OP_DIV ){ - if( (*node)->arg[ 1 ]->con != 0.0 ) { - newcon = (*node)->arg[ 0 ]->con / (*node)->arg[ 1 ]->con; - } else { - astError( AST__BADUN, "Illegal zero constant value encountered." , status); - } - - } else if( op == OP_MULT ){ - newcon = (*node)->arg[ 0 ]->con * (*node)->arg[ 1 ]->con; - - } - - - if( astOK ) newnode->con = newcon; - } - } - } - } - -/* If an error has occurred, free any new node. */ - if( !astOK ) newnode = FreeTree( newnode, status ); - -/* If we have a replacement node, free the supplied tree and return a - pointer to the new tree. */ - if( newnode ) { - FreeTree( *node, status ); - *node = newnode; - } - -} - -static UnitNode *FixUnits( UnitNode *node, UnitNode *test, int *status ) { -/* -* Name: -* FixUnits - -* Purpose: -* Assign a constant value to all units except for one. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *FixUnits( UnitNode *node, UnitNode *test, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function returns a copy of the supplied tree of UnitNodes. All -* OP_LDVAR nodes within the copy which refer to units which differ -* from those referred to by the supplied test node are replaced by -* OP_LDCON nodes which load the constant value 1.0. - -* Parameters: -* node -* A pointer to the UnitNode at the head of the tree to be used. -* test -* A pointer to an OP_LDVAR node which defines the units which are -* *not* to be replaced by a constant value of 1.0. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a UnitNode which is at the head of a tree of UnitNodes -* which forms the required copy of th einput tree. - -* Notes: -* - A NULL pointer is returned if an error has already occurred, or -* if this function fails for any reason. - -*/ - -/* Local Variables: */ - int i; - UnitNode *result; - -/* Initialise. */ - result = NULL; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Create a complete copy of the supplied tree. */ - result = CopyTree( node, status ); - -/* Is the node at the head of the supplied tree an OP_LDVAR node? */ - if( node->opcode == OP_LDVAR ) { - -/* Does it refer to a unit which differs from that of the test node? If so - annul the copy created above and return a new OP_LDCON node which loads - the constant value 1.0. */ - if( strcmp( test->name, node->name ) ) { - FreeTree( result, status ); - result = NewNode( NULL, OP_LDCON, status ); - if( astOK ) result->con = 1.0; - } - -/* If the supplied node is not an OP_LDVAR node, check each argument of - the head node. */ - } else { - for( i = 0; i < node->narg; i++ ) { - -/* Free the resources used to hold this argument in the tree copy created - above. */ - FreeTree( result->arg[ i ], status ); - -/* Create a new argument tree by calling this function recursively to - fix units in the argument sub-trees. */ - result->arg[ i ] = FixUnits( node->arg[ i ], test, status ); - } - } - -/* If an error has occurred, free any new tree. */ - if( !astOK ) result = FreeTree( result, status ); - -/* Return the answer. */ - return result; -} - -static UnitNode *FreeTree( UnitNode *node, int *status ) { -/* -* Name: -* FreeTree - -* Purpose: -* Free resources used by a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *FreeTree( UnitNode *node, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function frees the memory used to store a tree of UnitNodes. - -* Parameters: -* node -* A pointer to the UnitNode at the head of the tree which is to be -* freed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A NULL pointer is returned. - -* Notes: -* - This function attempts to execute even if it is invoked with -* the global error status set. -*/ - -/* Local Variables: */ - int i; - -/* Check a node was supplied. */ - if( node ) { - -/* Recursively free any argument nodes. */ - if( node->arg ) { - for( i = 0; i < node->narg; i++ ) { - (node->arg)[ i ] = FreeTree( (node->arg)[ i ], status ); - } - node->arg = astFree( node->arg ); - } - -/* Nullify other pointers for safety. */ - node->unit = NULL; - node->mult = NULL; - -/* Free the copy of the symbol string (if any). */ - node->name = astFree( (char *) node->name ); - -/* Free the memory holding the node. */ - node = astFree( node ); - } - -/* Return a null pointer. */ - return NULL; -} - -static KnownUnit *GetKnownUnits( int lock, int *status ) { -/* -* Name: -* GetKnownUnits - -* Purpose: -* Get a pointer to the head of a linked list of known unit definitions. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* KnownUnit *GetKnownUnits( int lock, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function returns a pointer to the head of a linked list of known -* unit definitions. The unit definitions are created as static module -* variables if they have not previously been created. - -* Parameters: -* lock -* If non-zero, then lock a mutex prior to accessing the list of -* known units. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the first known unit definition. - -* Notes: -* - A NULL pointer is returned if it is invoked with the global error -* status set, or if an error occurs. -*/ - -/* Local Variables: */ - int iq; - KnownUnit *result; - -/* Initialise. */ - result = NULL; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Ensure the known units list is only initialised once. */ - if( lock ) { - LOCK_MUTEX1 - } - -/* If the linked list of KnownUnit structures describing the known units - has not yet been created, create it now. A pointer to the head of the - linked list is put into the static variable "known_units". */ - if( !known_units ) { - -/* At the same time we store pointers to the units describing the basic - quantities used in dimensional analysis. Initialise th index of the - next such unit. */ - iq = 0; - -/* Create definitions for the known units. First do all IAU basic units. - We include "g" instead of "kg" because otherwise we would have to - refer to a gramme as a milli-kilogramme. */ - MakeKnownUnit( "g", "gram", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "m", "metre", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "s", "second", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "rad", "radian", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "K", "Kelvin", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "A", "Ampere", NULL, status ); - MakeKnownUnit( "mol", "mole", NULL, status ); - MakeKnownUnit( "cd", "candela", NULL, status ); - -/* Now do all IAU derived units. Unit definitions may only refer to units - which have already been defined. */ - MakeKnownUnit( "sr", "steradian", "rad rad", status ); - MakeKnownUnit( "Hz", "Hertz", "1/s", status ); - MakeKnownUnit( "N", "Newton", "kg m/s**2", status ); - MakeKnownUnit( "J", "Joule", "N m", status ); - MakeKnownUnit( "W", "Watt", "J/s", status ); - MakeKnownUnit( "C", "Coulomb", "A s", status ); - MakeKnownUnit( "V", "Volt", "J/C", status ); - MakeKnownUnit( "Pa", "Pascal", "N/m**2", status ); - MakeKnownUnit( "Ohm", "Ohm", "V/A", status ); - MakeKnownUnit( "S", "Siemens", "A/V", status ); - MakeKnownUnit( "F", "Farad", "C/V", status ); - MakeKnownUnit( "Wb", "Weber", "V s", status ); - MakeKnownUnit( "T", "Tesla", "Wb/m**2", status ); - MakeKnownUnit( "H", "Henry", "Wb/A", status ); - MakeKnownUnit( "lm", "lumen", "cd sr", status ); - MakeKnownUnit( "lx", "lux", "lm/m**2", status ); - -/* Now do additional derived and basic units listed in the FITS-WCS paper. */ - MakeKnownUnit( "deg", "degree", "pi/180 rad", status ); - MakeKnownUnit( "arcmin", "arc-minute", "1/60 deg", status ); - MakeKnownUnit( "arcsec", "arc-second", "1/3600 deg", status ); - MakeKnownUnit( "mas", "milli-arcsecond", "1/3600000 deg", status ); - MakeKnownUnit( "min", "minute", "60 s", status ); - MakeKnownUnit( "h", "hour", "3600 s", status ); - MakeKnownUnit( "d", "day", "86400 s", status ); - MakeKnownUnit( "yr", "year", "31557600 s", status ); - MakeKnownUnit( "a", "year", "31557600 s", status ); - MakeKnownUnit( "eV", "electron-Volt", "1.60217733E-19 J", status ); - MakeKnownUnit( "erg", "erg", "1.0E-7 J", status ); - MakeKnownUnit( "Ry", "Rydberg", "13.605692 eV", status ); - MakeKnownUnit( "solMass", "solar mass", "1.9891E30 kg", status ); - MakeKnownUnit( "u", "unified atomic mass unit", "1.6605387E-27 kg", status ); - MakeKnownUnit( "solLum", "solar luminosity", "3.8268E26 W", status ); - MakeKnownUnit( "Angstrom", "Angstrom", "1.0E-10 m", status ); - MakeKnownUnit( "micron", "micron", "1.0E-6 m", status ); - MakeKnownUnit( "solRad", "solar radius", "6.9599E8 m", status ); - MakeKnownUnit( "AU", "astronomical unit", "1.49598E11 m", status ); - MakeKnownUnit( "lyr", "light year", "9.460730E15 m", status ); - MakeKnownUnit( "pc", "parsec", "3.0867E16 m", status ); - MakeKnownUnit( "count", "count", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "adu", "analogue-to-digital unit", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "photon", "photon", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "Jy", "Jansky", "1.0E-26 W /m**2 /Hz", status ); - MakeKnownUnit( "mag", "magnitude", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "G", "Gauss", "1.0E-4 T", status ); - MakeKnownUnit( "pixel", "pixel", NULL, status ); - quant_units[ iq++ ] = known_units; - MakeKnownUnit( "barn", "barn", "1.0E-28 m**2", status ); - MakeKnownUnit( "D", "Debye", "(1.0E-29/3) C.m", status ); - - if( iq != NQUANT && astOK ) { - astError( AST__INTER, "unit(GetKnownUnits): %d basic quantities " - "noted but this should be %d (internal AST programming " - "error).", status, iq, NQUANT ); - } - -/* Unit aliases... */ - MakeUnitAlias( "Angstrom", "Ang", status ); - MakeUnitAlias( "count", "ct", status ); - MakeUnitAlias( "photon", "ph", status ); - MakeUnitAlias( "Jy", "Jan", status ); - MakeUnitAlias( "pixel", "pix", status ); - MakeUnitAlias( "s", "sec", status ); - MakeUnitAlias( "m", "meter", status ); - } - -/* If succesful, return the pointer to the head of the list. */ - if( astOK ) result = known_units; - -/* Allow the next thread to proceed. */ - if( lock ) { - UNLOCK_MUTEX1 - } - -/* Return the result. */ - return result; -} - -static Multiplier *GetMultipliers( int *status ) { -/* -* Name: -* GetMultiplier - -* Purpose: -* Get a pointer to the head of a linked list of multiplier definitions. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* Multiplier *Multipliers( void ) - -* Class Membership: -* Unit member function. - -* Description: -* This function returns a pointer to the head of a linked list of known -* multiplier definitions. The multiplier definitions are created as -* static module variables if they have not previously been created. - -* Returned Value: -* A pointer to the first known multiplier definition. - -* Notes: -* - A NULL pointer is returned if it is invoked with the global error -* status set, or if an error occurs. -*/ - -/* Local Variables: */ - Multiplier *result; - Multiplier *mult; - -/* Initialise. */ - result = NULL; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Ensure the list is only initialised by one thread. */ - LOCK_MUTEX2 - -/* If the linked list of Multiplier structures describing the known - multipliers has not yet been created, create it now. A pointer to the - head of the linked list is put into the static variable "multipliers". */ - if( !multipliers ) { - -/* Define a macro to create a multiplier struncture and add it to the - linked list of multiplier structures. */ -#define MAKEMULT(s,sl,sc,lab,ll) \ - mult = astMalloc( sizeof( Multiplier ) ); \ - if( astOK ) { \ - mult->sym = s; \ - mult->symlen = sl; \ - mult->lablen = ll; \ - mult->scale = sc; \ - mult->label = lab; \ - mult->next = multipliers; \ - multipliers = mult; \ - } - -/* Use the above macro to create all the standard multipliers listed in the - FITS WCS paper I. */ - MAKEMULT("d",1,1.0E-1,"deci",4) - MAKEMULT("c",1,1.0E-2,"centi",5) - MAKEMULT("m",1,1.0E-3,"milli",5) - MAKEMULT("u",1,1.0E-6,"micro",5) - MAKEMULT("n",1,1.0E-9,"nano",4) - MAKEMULT("p",1,1.0E-12,"pico",4) - MAKEMULT("f",1,1.0E-15,"femto",5) - MAKEMULT("a",1,1.0E-18,"atto",4) - MAKEMULT("z",1,1.0E-21,"zepto",5) - MAKEMULT("y",1,1.0E-24,"yocto",5) - MAKEMULT("da",2,1.0E1,"deca",4) - MAKEMULT("h",1,1.0E2,"hecto",5) - MAKEMULT("k",1,1.0E3,"kilo",4) - MAKEMULT("M",1,1.0E6,"mega",4) - MAKEMULT("G",1,1.0E9,"giga",4) - MAKEMULT("T",1,1.0E12,"tera",4) - MAKEMULT("P",1,1.0E15,"peta",4) - MAKEMULT("E",1,1.0E18,"exa",3) - MAKEMULT("Z",1,1.0E21,"zetta",5) - MAKEMULT("Y",1,1.0E24,"yotta",5) - -/* Undefine the macro. */ -#undef MAKEMULT - - } - -/* If succesful, return the pointer to the head of the list. */ - if( astOK ) result = multipliers; - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2 - -/* Return the result. */ - return result; -} - -static void InvertConstants( UnitNode **node, int *status ) { -/* -* Name: -* InvertConstants - -* Purpose: -* Take the reciprocal of all constants in a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* void InvertConstants( UnitNode **node, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function replaces constant unit coefficients by their reciprocal. -* This is because a string such as "0.01 m" will be interpreted as -* meaning "multiply a value in metres by 0.01 to get the value in the -* required units", whereas what is actually meant is "use units of -* 0.01 of a metre" which requires us to divide the value in metres by -* 0.01, not multiply it. - -* Parameters: -* node -* The address of a pointer to the UnitNode at the head of the tree. -* On exit the supplied tree is freed and a pointer to a new tree is -* placed at the given address. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int i; - UnitNode *newnode; - int allcon; - Oper op; - -/* Check inherited status and pointer. */ - if( !astOK || !node || !(*node) ) return; - -/* Initiallially, we have no replacement node */ - newnode = NULL; - -/* There is nothing to fix if the node has no arguments. */ - if( (*node)->narg > 0 ) { - -/* Note the op code for the node. */ - op = (*node)->opcode; - -/* Fix up the argument nodes. Also note if all the arguments are - constants. */ - allcon = 1; - for( i = 0; i < (*node)->narg; i++ ) { - InvertConstants( &( (*node)->arg[ i ] ), status ); - if( (*node)->arg[ i ]->con == AST__BAD ) allcon = 0; - } - -/* If all nodes are constant, there are no co-efficients to invert. */ - if( !allcon ) { - -/* Iif this is a multiplication node, see if either of its arguments - is a constant. If so, invert the constant. This is because a string like - "0.01 m" means "each unit is 0.01 of a metre". Therefore, to transform - a value in metres into required units means multiplying the metres - value by 100.0 (i.e the reciprocal of 0.01), not 0.01. */ - if( op == OP_MULT ) { - for( i = 0; i < 2; i++ ) { - if( (*node)->arg[ i ]->con != AST__BAD ) { - if( (*node)->arg[ i ]->con != 0.0 ) { - - (*node)->arg[ i ]->con = 1.0/(*node)->arg[ i ]->con; - } else { - astError( AST__BADUN, "Illegal zero constant encountered." , status); - } - } - } - -/* Likewise, check for division nodes in which the denominator is - constant. */ - } else if( op == OP_DIV ) { - if( (*node)->arg[ 1 ]->con != AST__BAD ) { - if( (*node)->arg[ 1 ]->con != 0.0 ) { - (*node)->arg[ 1 ]->con = 1.0/(*node)->arg[ 1 ]->con; - } else { - astError( AST__BADUN, "Illegal zero constant encountered." , status); - } - } - -/* If this is a "pow" node check that the second argument is constant - (required by FITS WCS paper I). */ - } else if( op == OP_POW ) { - if( (*node)->arg[ 1 ]->con == AST__BAD ) { - astError( AST__BADUN, "Illegal variable exponent." , status); - } - } - } - } - -/* If an error has occurred, free any new node. */ - if( !astOK ) newnode = FreeTree( newnode, status ); - -/* If we have a replacement node, free the supplied tree and return a - pointer to the new tree. */ - if( newnode ) { - FreeTree( *node, status ); - *node = newnode; - } -} - -static UnitNode *InvertTree( UnitNode *fwdnode, UnitNode *src, int *status ) { -/* -* Name: -* InvertTree - -* Purpose: -* Invert a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *InvertTree( UnitNode *fwdnode, UnitNode *src ) - -* Class Membership: -* Unit member function. - -* Description: -* This function inverts a tree of UnitNodes. The supplied tree should -* have exactly one OP_LDVAR node. This will be the quantity represented -* by the node at the head of the returned tree. - -* Parameters: -* fwdnode -* A pointer to the UnitNode at the head of the tree which is to be -* inverted. -* src -* A pointer to a UnitNode which is to be used as the root of the -* inverted tree. That is, the output from this node should form -* the (one and only) varying input to the inverted tree. If the -* supplied tree is succesfulyl inverted, the tree of which "src" -* is the head will be contained within the returned inverted tree. -* Therefore "src" only needs to be freed explicitly if this -* function fails to invert the supplied tree for any reason. If -* this function succeeds, then "src" will be freed as part of -* freeing the returned inverted tree. - -* Returned Value: -* A pointer to a UnitNode which forms the head of the inverted tree. - -* Algorithm: -* The algorithm works through the supplied forward tree, from the head -* to the roots. First, the supplied node at the head of the forward -* tree is inverted. To be invertable, the supplied head node must have -* exactly one varying argument (any other arguments must be fixed, -* i.e. not vary). This varying argument becomes the output of the -* inverted node. The other (fixed) arguments to the forward node are -* also used as arguments to the inverted node. The supplied "src" node -* is used as the single varying input to the inverted node. Having -* inverted the supplied forward head node, this function is called -* recursively to invert the lower parts of the forward tree (i.e. the -* part of the forward tree which provided the varying input to node -* which has just been inverted). - -* Notes: -* - It is assumed that he supplied forward tree has been simplified -* using SimplifyTree. This means that the tree contains no nodes with -* the following op codes: OP_LOG, OP_SQRT. OP_DIV (SimplifyTree -* converts these nodes into OP_LN, OP_POW and OP_MULT nodes). -* - A value of NULL will be returned if this function is invoked with -* the global error status set, or if it should fail for any reason. - -*/ - -/* Local Variables: */ - UnitNode *newnode; - UnitNode *nextnode; - UnitNode *result; - UnitNode *node1; - Oper fop; - int varg; - -/* Initialise */ - result = NULL; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Initiallially, we have no replacement node */ - newnode = NULL; - nextnode = NULL; - -/* Save the op code at the head of the forward tree. */ - fop = fwdnode->opcode; - -/* If the head of the forward tree is a OP_EXP node. Inverse of - "exp(x)" is "ln(x)". */ - if( fop == OP_EXP ) { - newnode = NewNode( NULL, OP_LN, status ); - if( astOK ) { - newnode->arg[ 0 ] = src; - nextnode = fwdnode->arg[ 0 ]; - } - -/* If the head of the forward tree is a OP_LN node. Inverse of - "ln(x)" is "exp(x)". */ - } else if( fop == OP_LN ) { - newnode = NewNode( NULL, OP_EXP, status ); - if( astOK ) { - newnode->arg[ 0 ] = src; - nextnode = fwdnode->arg[ 0 ]; - } - -/* If the head of the forward tree is a OP_POW node. Inverse of - "x**k" is "x**(1/k)" */ - } else if( fop == OP_POW ) { - newnode = NewNode( NULL, OP_POW, status ); - node1 = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - node1->con = 1.0/fwdnode->arg[ 1 ]->con; - newnode->arg[ 0 ] = src; - newnode->arg[ 1 ] = node1; - nextnode = fwdnode->arg[ 0 ]; - } - -/* If the head of the forward tree is a OP_MULT node... */ - } else if( fop == OP_MULT ) { - -/* The node is only invertable if it has one constant node and one - non-constant node. Get the index of the varying argument. */ - if( fwdnode->arg[ 0 ]->con != AST__BAD && - fwdnode->arg[ 1 ]->con == AST__BAD ) { - varg = 1; - } else if( fwdnode->arg[ 0 ]->con == AST__BAD && - fwdnode->arg[ 1 ]->con != AST__BAD ) { - varg = 0; - } else { - varg = -1; - } - if( varg != -1 ) { - -/* The inverse of "k*x" is "(1/k)*x" (we use MULT nodes instead of DIV - nodes to maintain the standardisation implemented by SimplifyTree). */ - newnode = NewNode( NULL, OP_MULT, status ); - node1 = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - node1->con = 1.0/fwdnode->arg[ 1 - varg ]->con; - newnode->arg[ 0 ] = node1; - newnode->arg[ 1 ] = src; - nextnode = fwdnode->arg[ varg ]; - } - } - -/* If the head of the forward tree is a OP_LDVAR node, there is nothing - left to invert. SO return a pointer to the suppleid source node. */ - } else if( fop == OP_LDVAR ) { - result = src; - nextnode = NULL; - -/* If the head of the forward tree is any other node (e.g. a OP_LDCON node), - the tree cannot be inverted. */ - } else { - nextnode = NULL; - } - -/* If we managed to invert the node at the head of the supplied tree, - continue to invert its varying argument node (if any). */ - if( nextnode && newnode ) result = InvertTree( nextnode, newnode, status ); - -/* If the tree could not be inverted, free the newnode. */ - if( !result ) newnode = FreeTree( newnode, status ); - -/* If an error has occurred, free any new node. */ - if( !astOK ) result = FreeTree( result, status ); - -/* Return the result. */ - return result; - -} - -static void LocateUnits( UnitNode *node, UnitNode ***units, int *nunits, int *status ){ -/* -* Name: -* LocateUnits - -* Purpose: -* Locate the units used by a supplied tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* void LocateUnits( UnitNode *node, UnitNode ***units, int *nunits, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function locates the units used by a supplied tree of -* UnitNodes. - -* Parameters: -* node -* A pointer to the UnitNode at the head of the tree to be searched. -* units -* The address at which is stored a pointer to an array of "*nunits" -* elements. Each element of the array holds a pointer to a UnitNode. -* The array is extended on exit to hold pointers to the OP_LDVAR nodes -* within the supplied tree (i.e. nodes which represent named units, -* either known or unknown). A node is only included in the returned -* array if no other node for the same unit is already included in the -* array. A NULL pointer should be supplied on the first invocation of -* this function. -* nunits -* The address of an integer which holds the number of elements in -* the array given by "*units". Updated on exit to included any -* elements added to the array. Zero should be supplied on the first -* invocation of this function. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int i; - int found; - -/* Check the global error status. */ - if( !astOK ) return; - -/* Is the node at the head of the supplied tree an OP_LDVAR node? */ - if( node->opcode == OP_LDVAR ) { - -/* If an array was supplied, see if it already contains a pointer to a node - which refers to the same units. */ - found = 0; - if( *units ) { - for( i = 0; i < *nunits; i++ ) { - if( !strcmp( (*units)[ i ]->name, node->name ) ) { - found = 1; - break; - } - } - } - -/* If not, ensure the array is big enough and add a pointer to the - supplied node to the array. */ - if( !found ) { - *units = astGrow( *units, *nunits + 1, sizeof( UnitNode * ) ); - if( astOK ) (*units)[ (*nunits)++ ] = node; - } - -/* If the supplied node is not an OP_LDVAR node, call this function - recursively to search the argument sub-trees. */ - } else { - for( i = 0; i < node->narg; i++ ) { - LocateUnits( node->arg[ i ], units, nunits, status ); - } - } -} - -static const char *MakeExp( UnitNode *tree, int mathmap, int top, int *status ) { -/* -* Name: -* MakeExp - -* Purpose: -* Make an algebraic expression from a supplied tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* const char *MakeExp( UnitNode *tree, int mathmap, int top, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function produces a string holding an algebraic expression -* corresponding to a supplied tree of UnitNodes. - -* Parameters: -* tree -* A pointer to the UnitNode at the head of the tree to be converted -* into an algebraic expression. -* mathmap -* If zero, format as an axis label expression. If 1, format as a -* MathMap expression. If 2, format as a FITS unit string. -* top -* Should be non-zero for a top-level entry to this function, and -* zero for a recursive entry. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the cleaned expression, which should be freed using -* astFree when no longer needed. - -* Notes: -* - This function returns NULL if it is invoked with the global error -* status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - UnitNode *newtree; - UnitNode *sunit; - char *a; - char *result; - char buff[200]; - const char *arg0; - const char *arg1; - const char *mtxt; - int larg0; - int larg1; - int lbuff; - int mlen; - int par; - int tlen; - -/* Check inherited status. */ - result = NULL; - if( !astOK ) return result; - -/* Modify the tree to make the resulting transformation functions more - natural to human readers. */ - newtree = CopyTree( tree, status ); - ComplicateTree( &newtree, status ); - -/* If we are producing an axis label... */ - if( !mathmap ) { - -/* Fix all multiplicative constants to 1.0 if they multiply an OP_LDVAR - OP_SQRT or OP_POW node. This is on the assumption that the returned label - should not include any simple unit scaling (e.g. if the output label would - be "2.345*wavelength", we prefer simply to use "wavelength" since a scaled - wavelength is still a wavelength - i.e. simple scaling does not change - the dimensions of a quantity). */ - FixConstants( &newtree, 1, status ); - -/* Simplify the tree again to get rid of the 1.0 terms which may have - been introduced by the previous line (but do not re-introduce any - standardisations - removing them was the reason for calling ComplicateTree). - If this simplication introduces any changes, try fixing multiplicative - constants again, and so on, until no more changes occur. */ - while( SimplifyTree( &newtree, 0, status ) ) { - FixConstants( &newtree, 1, status ); - } - - } - -/* Produce a string describing the action performed by the UnitNode at - the head of the supplied tree, and then invoke this function recursively - to format any arguments of the head node. */ - -/* Constant valued nodes... just format the constant in a local buffer and - then copy the buffer. */ - if( newtree->con != AST__BAD ) { - lbuff = sprintf( buff, "%.*g", AST__DBL_DIG, newtree->con ); - result = astStore( NULL, buff, lbuff + 1 ); - -/* "Load Variable Value" nodes - return the variable name. If this is a - recursive call to this function, and we are producing a label, append a - single space before and after the name. */ - } else if( newtree->opcode == OP_LDVAR ) { - tlen = strlen( newtree->name ); - - if( !mathmap && !top ){ - result = astMalloc( tlen + 3 ); - if( result ) { - result[ 0 ] = ' '; - memcpy( result + 1, newtree->name, tlen ); - memcpy( result + tlen + 1, " ", 2 ); - } - - } else if( mathmap == 2 ) { - - if( newtree->mult ) { - mlen = newtree->mult->symlen; - mtxt = newtree->mult->sym; - } else { - mlen = 0; - mtxt = NULL; - } - - result = astMalloc( tlen + 1 + mlen ); - if( result ) { - if( mtxt ) memcpy( result, mtxt, mlen ); - memcpy( result + mlen, newtree->name, tlen + 1 ); - } - - } else { - result = astStore( NULL, newtree->name, tlen + 1 ); - } - -/* Single argument functions... place the argument in parentheses after - the function name. */ - } else if( newtree->opcode == OP_LOG ) { - arg0 = MakeExp( newtree->arg[ 0 ], mathmap, 0, status ); - larg0 = strlen( arg0 ); - if( mathmap == 1 ) { - result = astMalloc( larg0 + 8 ); - if( result ) memcpy( result, "log10(", 7 ); - a = result + 6; - } else { - result = astMalloc( larg0 + 6 ); - if( result ) memcpy( result, "log(", 5 ); - a = result + 4; - } - if( result ){ - memcpy( a, arg0, larg0 + 1 ); - memcpy( a + larg0, ")", 2 ); - } - arg0 = astFree( (void *) arg0 ); - - } else if( newtree->opcode == OP_LN ) { - arg0 = MakeExp( newtree->arg[ 0 ], mathmap, 0, status ); - larg0 = strlen( arg0 ); - if( mathmap == 1 ) { - result = astMalloc( larg0 + 6 ); - if( result ) memcpy( result, "log(", 5 ); - a = result + 4; - } else { - result = astMalloc( larg0 + 5 ); - if( result ) memcpy( result, "ln(", 4 ); - a = result + 3; - } - if( astOK ){ - memcpy( a, arg0, larg0 ); - memcpy( a + larg0, ")", 2 ); - } - arg0 = astFree( (void *) arg0 ); - - } else if( newtree->opcode == OP_EXP ) { - arg0 = MakeExp( newtree->arg[ 0 ], mathmap, 0, status ); - larg0 = strlen( arg0 ); - result = astMalloc( larg0 + 6 ); - if( result ){ - memcpy( result, "exp(", 5 ); - memcpy( result + 4, arg0, larg0 ); - memcpy( result + 4 + larg0, ")", 2 ); - } - arg0 = astFree( (void *) arg0 ); - - } else if( newtree->opcode == OP_SQRT ) { - arg0 = MakeExp( newtree->arg[ 0 ], mathmap, 0, status ); - larg0 = strlen( arg0 ); - result = astMalloc( larg0 + 7 ); - if( result ){ - memcpy( result, "sqrt(", 6 ); - memcpy( result + 5, arg0, larg0 ); - memcpy( result + 5 + larg0, ")", 2 ); - } - arg0 = astFree( (void *) arg0 ); - -/* POW... the exponent (arg[1]) is always a constant and so does not need - to be placed in parentheses. The first argument only needs to be - placed in parentheses if it is a two arg node (except we also put it - in parentheses if it is an OP_LDVAR node and "mathmap" is zero - this is - because such OP_LDVAR nodes will correspond to axis labels which will - have spaces before and after them which would look odd if not encloses - in parentheses). */ - } else if( newtree->opcode == OP_POW ) { - - arg0 = MakeExp( newtree->arg[ 0 ], mathmap, 0, status ); - larg0 = strlen( arg0 ); - - arg1 = MakeExp( newtree->arg[ 1 ], mathmap, 0, status ); - larg1 = strlen( arg1 ); - - if( newtree->arg[ 0 ]->narg == 2 || - (newtree->arg[ 0 ]->opcode == OP_LDVAR && !mathmap) ) { - par = 1; - result = astMalloc( larg0 + larg1 + 7 ); - if( result ) memcpy( result, "(", 2 ); - a = result + 1; - } else { - par = 0; - result = astMalloc( larg0 + larg1 + 5 ); - a = result; - } - - if( result ) { - memcpy( a, arg0, larg0 ); - a += larg0; - if( par ) *(a++) = ')'; - memcpy( a, "**", 3 ); - a += 2; - memcpy( a, arg1, larg1 ); - a += larg1; - *a = 0; - } - - arg0 = astFree( (void *) arg0 ); - arg1 = astFree( (void *) arg1 ); - -/* DIV... the first argument (numerator) never needs to be in parentheses. - The second argument (denominator) only needs to be placed in parentheses - if it is a MULT node. */ - } else if( newtree->opcode == OP_DIV ) { - - if( mathmap == 2 && ( sunit = ModifyPrefix( newtree, status ) ) ) { - result = (char *) MakeExp( sunit, mathmap, 0, status ); - sunit = FreeTree( sunit, status ); - - } else { - arg0 = MakeExp( newtree->arg[ 0 ], mathmap, 0, status ); - larg0 = strlen( arg0 ); - - arg1 = MakeExp( newtree->arg[ 1 ], mathmap, 0, status ); - larg1 = strlen( arg1 ); - - if( newtree->arg[ 1 ]->opcode == OP_MULT && - strchr( arg1, '*' ) ) { - par = 1; - result = astMalloc( larg0 + larg1 + 4 ); - } else { - par = 0; - result = astMalloc( larg0 + larg1 + 2 ); - } - - if( result ) { - memcpy( result, arg0, larg0 ); - a = result + larg0; - *(a++) = '/'; - if( par ) *(a++) = '('; - memcpy( a, arg1, larg1 ); - a += larg1; - if( par ) *(a++) = ')'; - *a = 0; - } - - arg0 = astFree( (void *) arg0 ); - arg1 = astFree( (void *) arg1 ); - } - -/* MULT... the second argument never needs to be in parentheses. The first - argument only needs to be placed in parentheses if it is a DIV or POW - node. */ - } else if( newtree->opcode == OP_MULT ) { - if( mathmap == 2 && ( sunit = ModifyPrefix( newtree, status ) ) ) { - result = (char *) MakeExp( sunit, mathmap, 0, status ); - sunit = FreeTree( sunit, status ); - - } else { - arg0 = MakeExp( newtree->arg[ 0 ], mathmap, 0, status ); - larg0 = strlen( arg0 ); - - arg1 = MakeExp( newtree->arg[ 1 ], mathmap, 0, status ); - larg1 = strlen( arg1 ); - -/* If this is a top-level entry and we are producing an axis label, do - not include any constant multiplicative terms. */ - if( top && !mathmap ) { - if( newtree->arg[ 0 ]->con != AST__BAD ) arg0 = astFree( (void *) arg0 ); - if( newtree->arg[ 1 ]->con != AST__BAD ) arg1 = astFree( (void *) arg1 ); - } - -/* If we have two arguments, concatentate them, placing the operands in - parentheses if necessary. */ - if( arg0 && arg1 ) { - - if( ( newtree->arg[ 0 ]->opcode == OP_DIV && - strchr( arg0, '/' ) ) || - ( newtree->arg[ 0 ]->opcode == OP_POW && - strstr( arg0, "**" ) ) ) { - par = 1; - result = astMalloc( larg0 + larg1 + 4 ); - if( result ) result[ 0 ] = '('; - a = result + 1; - } else { - par = 0; - result = astMalloc( larg0 + larg1 + 2 ); - a = result; - } - - if( result ) { - memcpy( a, arg0, larg0 ); - a += larg0; - if( par ) *(a++) = ')'; - *(a++) = '*'; - memcpy( a, arg1, larg1 ); - a += larg1; - *a = 0; - } - - arg0 = astFree( (void *) arg0 ); - arg1 = astFree( (void *) arg1 ); - -/* If we do not have two arguments, just return the one we do have. */ - } else if( arg0 ){ - result = (char *) arg0; - - } else { - result = (char *) arg1; - } - } - } - -/* Free the complicated tree. */ - newtree = FreeTree( newtree, status ); - -/* Free the returned string if an error has occurred. */ - if( !astOK ) result = astFree( result ); - -/* Return the result. */ - return (const char *) result; -} - -static void MakeKnownUnit( const char *sym, const char *label, const char *exp, int *status ){ -/* -* Name: -* MakeKnownUnit - -* Purpose: -* Create a KnownUnit structure describing a known unit. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* void MakeKnownUnit( const char *sym, const char *label, const char *exp, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function creates a KnownUnit structure decribing a known unit, -* and adds it to the head of the linked list of known units stored in -* a module variable. - -* Parameters: -* sym -* A pointer to a string which can be used as a symbol to represent -* the new named unit. Once defined, this symbol can be included within -* the definition of other derived units. The string should contain -* only alphabetical characters (no digits, spaces, punctuation, -* etc). Symbols are case sensitive (e.g. "s" is second, but "S" is -* Siemens). The string should not include any multiplier prefix. -* label -* Pointer to a null terminated string containing the label for -* the required units. No restriction on content. -* exp -* This should be a pointer to a null terminated string containing -* a definition of the required unit. See the description of the -* "in" and "out" parameters for the astUnitMapper function. -* -* A NULL pointer or a blank string may supplied for "exp", which -* is interpreted as a request for a new basic unit to be created with -* the symbol and label given by the other parameters. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The supplied symbol and label strings are not copied. The -* supplied pointers are simply stored in the returned structure. -* Therefore the strings to which the pointers point should not be -* modified after this function returned (in fact this function is -* always called with literal strings for these arguments). -*/ - -/* Local Variables: */ - KnownUnit *result; - -/* Check the global error status. */ - if( !astOK ) return; - -/* Indicate that subsequent memory allocations may never be freed (other - than by any AST exit handler). */ - astBeginPM; - -/* Allocate memory for the structure, and check the returned pointer can - be used safely. */ - result = astMalloc( sizeof( KnownUnit ) ); - if( astOK ) { - -/* In case of errors, first nullify the pointer to the next KnownUnit. */ - result->next = NULL; - -/* Store the supplied label and symbol pointers. */ - result->sym = sym; - result->label = label; - -/* Store the length of the symbol (without the trailing null character). */ - result->symlen = strlen( sym ); - -/* Store the length of the label (without the trailing null character). */ - result->lablen = strlen( label ); - -/* Create a tree of UnitNodes describing the unit if an expression was - supplied. */ - result->head = exp ? CreateTree( exp, 1, 0, status ) : NULL; - -/* Unit aliases are replaced in use by the KnownUnit pointed to by the - "use" component of the structure. Indicate this KnownUnitis not an - alias by setting its "use" component NULL. */ - result->use = NULL; - } - -/* Mark the end of the section in which memory allocations may never be - freed (other than by any AST exit handler). */ - astEndPM; - -/* If an error has occurred, free any returned structure. */ - if( !astOK ) { - result->head = FreeTree( result->head, status ); - result = astFree( result ) ; - -/* Otherwise, add the new KnownUnit to the head of the linked list of - known units. */ - } else { - result->next = known_units; - known_units = result; - } - -} - -static AstMapping *MakeMapping( UnitNode *tree, int *status ) { -/* -* Name: -* MakeMapping - -* Purpose: -* Create a new Mapping from a given tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* AstMapping *MakeMapping( UnitNode *tree ) - -* Class Membership: -* Unit member function. - -* Description: -* This function creates a Mapping with a forward transformation equal -* to the transformation described by the tree of UnitNodes. The head -* node of the tree corresponds to the output of the Mapping. - -* Parameters: -* tree -* The UnitNode at the head of the tree to be used. It should have -* exactly one OP_LDVAR node, and should have been simplified using -* the SimplifyTree function. - -* Returned Value: -* A pointer to the Mapping. Its Nin and Nout attributes will both be 1. - -* Notes: -* - A value of NULL will be returned if this function is invoked with -* the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *result; - UnitNode *inv; - UnitNode *src; - const char *fwdexp; - char *fwdfun; - const char *invexp; - char *invfun; - int lfwd; - int linv; - -/* Initialise. */ - result = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* First see if a UnitMap can be used to represent the Mapping from - input units to output units. This will be the case if the supplied tree - consists of a aingle OP_LDVAR node (corresponding to the input units). */ - if( tree->opcode == OP_LDVAR ) { - result = (AstMapping *) astUnitMap( 1, "", status ); - -/* Now see if a UnitMap or ZoomMap can be used to represent the Mapping from - input units to output units. This will be the case if the supplied tree - consists of a OP_MULT node with one constant argument and on OP_LDVAR - argument (corresponding to the input units). The standardisation done by - SimplifyTree will have ensured that the constant will be argument 0 - (and will also have converted "x/k" trees into "(1/k)*x" trees). */ - } else if( tree->opcode == OP_MULT && - tree->arg[ 0 ]->con != AST__BAD && - tree->arg[ 1 ]->opcode == OP_LDVAR ) { - - if( tree->arg[ 0 ]->con == 1.0 ) { - result = (AstMapping *) astUnitMap( 1, "", status ); - } else { - result = (AstMapping *) astZoomMap( 1, tree->arg[ 0 ]->con, "", status ); - } - -/* For other trees we need to create a MathMap. */ - } else { - -/* Format the supplied tree as an algebraic expression, and get its length. */ - fwdexp = MakeExp( tree, 1, 1, status ); - lfwd = strlen( fwdexp ); - -/* The MathMap constructor requires the forward and inverse - transformation functions to be specified as equations (i.e. including an - equals sign). We use the output variable name "output_units" (the - astUnitMapper function creates the supplied tree usign the variable - name "input_units" ). */ - lfwd += 13; - -/* Invert the supplied tree and create an algebraic expression from it. */ - src = NewNode( NULL, OP_LDVAR, status ); - if( astOK ) src->name = astStore( NULL, "output_units", 13 ); - inv = InvertTree( tree, src, status ); - if( !inv ) { - src = FreeTree( src, status ); - astError( AST__BADUN, "MakeMapping(Unit): Failed to invert " - "supplied tree '%s' (internal AST programming error).", status, - fwdexp ); - -/* If inverted succesfully (which it should be since astUnitMapper should - have checked this)... */ - } else { - -/* Format the inverted tree as an algebraic expression, and get its - length, adding on extra characters for the variable name ("input_units") - and equals sign. */ - invexp = MakeExp( inv, 1, 1, status ); - linv = strlen( invexp ); - linv += 12; - -/* Allocate memory for the transformation functions, plus an extra - character for the trailing null. */ - fwdfun = astMalloc( lfwd + 1 ); - invfun = astMalloc( linv + 1 ); - if( invfun ) { - memcpy( fwdfun, "output_units=", 14 ); - memcpy( invfun, "input_units=", 13 ); - -/* Append the expressions following the equals signs. */ - strcpy( fwdfun + 13, fwdexp ); - strcpy( invfun + 12, invexp ); - -/* Create the MathMap. */ - result = (AstMapping *) astMathMap( 1, 1, 1, - (const char **) &fwdfun, 1, - (const char **) &invfun, - "SimpFI=1,SimpIF=1", status ); - } - -/* Free resources. */ - inv = FreeTree( inv, status ); - fwdfun = astFree( fwdfun ); - invfun = astFree( invfun ); - invexp = astFree( (void *) invexp ); - } - fwdexp = astFree( (void *) fwdexp ); - } - -/* Free any result if an error occurred. */ - if( !astOK ) result = astAnnul( result ); - -/* Return the answer. */ - return result; -} - -static UnitNode *MakeLabelTree( const char *lab, int nc, int *status ){ -/* -* Name: -* MakeLabelTree - -* Purpose: -* Convert an axis label into a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *MakeLabelTree( const char *lab, int nc, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function converts an axis label into a tree of UnitNodes. -* It is assumed the supplied label represents some "basic" label -* modified by the application of one or more single function arguments -* and/or exponentiation operators. The (single) OP_LDVAR node in the -* returned tree refers to the basic label (it is stored as the "name" -* component of UnitNode structure). - -* Parameters: -* lab -* The label expression. -* nc -* The number of characters from "lab" to use. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a UnitNode which forms the head of a tree of UnitNodes -* representing the supplied label expression. - -* Notes: -* - A NULL value is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - Oper op; - UnitNode *result; - char buff[ 10 ]; - const char *c; - const char *exp; - int depth; - int i; - int oplen; - int n; - double con; - -/* Initialise */ - result = NULL; - oplen = 0; - -/* Check the global error status, and that we have a string. */ - if ( !astOK || !lab || !nc ) return result; - -/* Get a pointer to the first non-blank character, and store the number of - characters to examine (this excludes any trailing white space). */ - exp = lab; - while( isspace( *exp ) ) exp++; - c = lab + nc - 1; - while( c >= exp && isspace( *c ) ) c--; - nc = c - exp + 1; - -/* Scan through the supplied string looking for the first pow operator at - zero depth of nesting within parentheses. */ - depth = 0; - c = exp; - i = 0; - op = OP_NULL; - while( i < nc && *c ){ - -/* If this character is an opening parenthesis, increment the depth of - nesting. */ - if( *c == '(' ) { - depth++; - -/* If this character is an closing parenthesis, decrement the depth of - nesting. Report an error if it ever goes negative. */ - } else if( *c == ')' ) { - depth--; - if( depth < 0 && astOK ) { - astError( AST__BADUN, "Missing opening parenthesis." , status); - break; - } - -/* Ignore all other characters unless they are at zero depth of nesting. - Also ignore spaces. */ - } else if( depth == 0 && !isspace( *c ) ) { - -/* Compare the next part of the string with each of the "pow" operators. */ - if( !strncmp( c, "**", 2 ) ) { - op = OP_POW; - oplen = 2; - } else if( *c == '^' ) { - op = OP_POW; - oplen = 1; - } - -/* If an operator was found, break out of the loop. */ - if( op != OP_NULL ) break; - } - -/* Pass on to check the next character. */ - i++; - c++; - } - -/* If a "pow" operator was found, the strings on either side of it should be - valid unit expressions, in which case we use this routine recursively to - create corresponding trees of UnitNodes. */ - if( op != OP_NULL ) { - -/* Create a UnitNode for the operator. */ - result = NewNode( NULL, op, status ); - if( astOK ) { - -/* Create a tree of unit nodes from the string which precedes the binary - operator. Report an error if it cannot be done. */ - result->arg[ 0 ] = MakeLabelTree( exp, i, status ); - if( !result->arg[ 0 ] && astOK ) { - for( i = 0; i < oplen; i++ ) buff[ i ] = c[ i ]; - buff[ oplen ] = 0; - astError( AST__BADUN, "Missing operand before '%s'.", status, buff ); - } - -/* Create a tree of unit nodes from the string which follows the binary - operator. Report an error if it cannot be done. */ - result->arg[ 1 ] = MakeLabelTree( c + oplen, nc - i - oplen, status ); - if( !result->arg[ 1 ] && astOK ) { - for( i = 0; i < oplen; i++ ) buff[ i ] = c[ i ]; - buff[ oplen ] = 0; - astError( AST__BADUN, "Missing operand after '%s'.", status, buff ); - } - } - -/* If no binary operator was found at depth zero, see if the supplied string - starts with a function name (the only legal place for a function name - given that the string has no binary operators at depth zero). */ - } else { - if( !strncmp( exp, "sqrt(", 5 ) || !strncmp( exp, "SQRT(", 5 ) ) { - op = OP_SQRT; - oplen = 4; - } else if( !strncmp( exp, "exp(", 4 ) || !strncmp( exp, "EXP(", 4 ) ) { - op = OP_EXP; - oplen = 3; - } else if( !strncmp( exp, "ln(", 3 ) || !strncmp( exp, "LN(", 3 ) ) { - op = OP_LN; - oplen = 2; - } else if( !strncmp( exp, "log(", 4 ) || !strncmp( exp, "LOG(", 4 ) ) { - op = OP_LOG; - oplen = 3; - } - -/* If a function was found, the string following the function name - (including the opening parenthesis) should form a legal units - expresssion (all the supported functions take a single argument and - so we do not need to worry about comma-separated lists of function - arguments). Use this routine recursively to create a tree of UnitNodes - from the string which forms the function argument. */ - if( op != OP_NULL ) { - -/* Create a UnitNode for the function. */ - result = NewNode( NULL, op, status ); - if( astOK ) { - -/* Create a tree of unit nodes from the string which follows the function - name. Report an error if it cannot be done. */ - result->arg[ 0 ] = MakeLabelTree( exp + oplen, nc - oplen, status ); - if( !result->arg[ 0 ] && astOK ) { - for( i = 0; i < oplen; i++ ) buff[ i ] = c[ i ]; - buff[ oplen ] = 0; - astError( AST__BADUN, "Missing argument for '%s'.", status, buff ); - } - } - -/* Arrive here if the supplied string does not contain a POW operator - or function at depth zero. Check to see if the whole string is contained - within parentheses, In which we interpret the contents of the - parentheses as a units expression. It is safe simply to check the - first and last characters (a string like "(fred)(Harry)" is not a - legal possibility since there should be an operator in the middle).*/ - } else if( nc > 0 && ( exp[ 0 ] == '(' && exp[ nc - 1 ] == ')' ) ) { - result = MakeLabelTree( exp + 1, nc - 2, status ); - -/* Does the string begin with a numerical constant? */ - } else if( ConStart( exp, &con, &n, status ) == 1 ) { - -/* If the entire string was a numerical constant, represent it by a LDCON - node. */ - if( n == nc ) { - result = NewNode( NULL, OP_LDCON, status ); - if( astOK ) result->con = con; - -/* If there was anything following the numerical constant, report an - error. */ - } else if( astOK ){ - astError( AST__BADUN, "Missing operator after " - "numerical string '%.*s'.", status, n, exp ); - } - -/* The only legal possibility left is that the string represents the basic - label. Create an OP_LDVAR node for it and store the basic label as - the node name, omitting any enclosing white space. */ - } else { - result = NewNode( NULL, OP_LDVAR, status ); - if( astOK ) { - result->name = astStore( NULL, exp, nc + 1 ); - if( astOK ) ( (char *) result->name)[ nc ] = 0; - } - } - } - -/* Free any returned tree if an error has occurred. */ - if( !astOK ) result = FreeTree( result, status ); - -/* Return the result. */ - return result; -} - -static UnitNode *MakeTree( const char *exp, int nc, int lock, int *status ){ -/* -* Name: -* MakeTree - -* Purpose: -* Convert an algebraic units expression into a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *MakeTree( const char *exp, int nc, int lock, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function converts an algebraic units expression into a tree of -* UnitNodes. It is a service routine for CreateTree. The roots of the -* returned tree (i.e. the LDVAR nodes) refer to the unit symbols -* contained within the supplied expression (i.e. definitions of these -* units are not grafted onto the tree in place of the original nodes, -* as is done by CreateTree). - -* Parameters: -* exp -* The units expression. This should not include any leading or -* trailing spaces. -* nc -* The number of characters from "exp" to use. -* lock -* Use a mutex to guard access to the KnownUnits list? -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a UnitNode which forms the head of a tree of UnitNodes -* representing the supplied unit expression. - -* Notes: -* - A NULL value is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - KnownUnit *munit; - KnownUnit *unit; - Multiplier *mmult; - Multiplier *mult; - Oper op; - UnitNode *result; - char buff[ 10 ]; - char d; - const char *c; - double con; - int depth; - int i; - int l; - int maxlen; - int n; - int oplen; - int plural; - -/* Initialise */ - result = NULL; - -/* Check the global error status, and that we have a string. */ - if ( !astOK || !exp || nc <= 0 ) return result; - -/* Scan through the supplied string from the end to the start looking for - the last multiplication or division operator at zero depth of nesting - within parentheses. We go backwards through the string in order to - give the correct priority to multiple division operators (i.e. "a/b/c" - needs to be interpreted as "(a/b)/c", not "a/(b/c)"). */ - op = OP_NULL; - oplen = 1; - depth = 0; - c = exp + nc - 1; - i = nc - 1; - while( i >= 0 ){ - -/* If this character is an opening parenthesis, decrement the depth of - nesting. Report an error if it ever goes negative. */ - if( *c == '(' ) { - depth--; - if( depth < 0 && astOK ) { - astError( AST__BADUN, "Missing closing parenthesis." , status); - break; - } - -/* An opening parenthesis at level zero must always be either the first - character in the string, or be preceded by the name of a function, or - be preceded by an operator. If none of these are true, assume there is - an implicit multiplication operator before the parenthesis. */ - if( depth == 0 && i > 0 ) { - d = *( c - 1 ); - if( d != '*' && d != '/' && d != '^' && d != '.' && d != ' ' && - !EndsWith( c, i + 1, "sqrt(", status ) && !EndsWith( c, i + 1, "exp(", status ) && - !EndsWith( c, i + 1, "ln(", status ) && !EndsWith( c, i + 1, "log(", status ) ) { - op = OP_MULT; - oplen = 0; - break; - } - } - -/* If this character is an closing parenthesis, increment the depth of - nesting. */ - } else if( *c == ')' ) { - depth++; - -/* A closing parenthesis at level zero must always be either the last - character in the string, or be followed by an operator. If neither of - these are true, assume there is an implicit multiplication operator. */ - if( depth == 1 && i < nc - 1 ) { - d = *(c+1); - if( d != '*' && d != '/' && d != '^' && d != '.' && d != ' ') { - op = OP_MULT; - oplen = 0; - -/* Correct "i" so that it gives the length of the left hand operand of - the implicit MULT operator, correct "c" so that it points to the first - character in the right hand operand, and leave the loop. */ - i++; - c++; - break; - } - } - -/* Ignore all other characters unless they are at zero depth of nesting. */ - } else if( depth == 0 ) { - -/* Compare the next part of the string with each of the multiplication - and division operators. */ - if( *c == '/' ) { - op = OP_DIV; - - } else if( *c == ' ' ) { - op = OP_MULT; - -/* An asterisk is only treated as a multiplication symbol if it does not occur - before or after another asterisk. */ - } else if( *c == '*' ) { - if( c == exp ) { - if( *(c+1) != '*' ) op = OP_MULT; - } else if( i == nc - 1 ) { - if( *(c-1) != '*' ) op = OP_MULT; - } else { - if( *(c+1) != '*' && *(c-1) != '*' ) op = OP_MULT; - } - -/* A dot is only treated as a multiplication symbol if it does not occur - between two digits. */ - } else if( *c == '.' ) { - if( ( c == exp || !isdigit( *(c-1) ) ) && - ( i == nc - 1 || !isdigit( *(c+1) ) ) ) { - op = OP_MULT; - } - } - } - -/* If an operator was found, break out of the loop. */ - if( op != OP_NULL ) break; - -/* Pass on to check the next character. */ - i--; - c--; - } - -/* If a multiplication or division operator was found, the strings on either - side of it should be valid unit expressions, in which case we use this - routine recursively to create corresponding trees of UnitNodes. */ - if( op != OP_NULL ) { - -/* Create a UnitNode for the binary operator. */ - result = NewNode( NULL, op, status ); - if( astOK ) { - -/* Create a tree of unit nodes from the string which precedes the binary - operator. Report an error if it cannot be done. */ - result->arg[ 0 ] = MakeTree( exp, i, lock, status ); - if( !result->arg[ 0 ] && astOK ) { - for( i = 0; i < oplen; i++ ) buff[ i ] = c[ i ]; - buff[ oplen ] = 0; - astError( AST__BADUN, "Missing operand before '%s'.", status, buff ); - } - -/* Create a tree of unit nodes from the string which follows the binary - operator. Report an error if it cannot be done. */ - result->arg[ 1 ] = MakeTree( c + oplen, nc - i - oplen, lock, status ); - if( !result->arg[ 1 ] && astOK ) { - for( i = 0; i < oplen; i++ ) buff[ i ] = c[ i ]; - buff[ oplen ] = 0; - astError( AST__BADUN, "Missing operand after '%s'.", status, buff ); - } - } - -/* If no multiplication or division operator was found at depth zero, check - that the final depth of nesting was zero. Report an error if not. */ - } else if( depth > 0 && astOK ) { - astError( AST__BADUN, "Missing opening parenthesis." , status); - -/* Otherwise check for a "Pow" operator at depth zero. */ - } else { - -/* Scan through the supplied string looking for the first pow operator at - zero depth of nesting within parentheses. */ - depth = 0; - c = exp; - i = 0; - while( i < nc && *c ){ - -/* If this character is an opening parenthesis, increment the depth of - nesting. */ - if( *c == '(' ) { - depth++; - -/* If this character is an closing parenthesis, decrement the depth of - nesting. Report an error if it ever goes negative. */ - } else if( *c == ')' ) { - depth--; - if( depth < 0 && astOK ) { - astError( AST__BADUN, "Missing opening parenthesis." , status); - break; - } - -/* Ignore all other characters unless they are at zero depth of nesting. */ - } else if( depth == 0 ) { - -/* Compare the next part of the string with each of the "pow" operators. */ - if( !strncmp( c, "**", 2 ) ) { - op = OP_POW; - oplen = 2; - } else if( *c == '^' ) { - op = OP_POW; - oplen = 1; - } - -/* If an operator was found, break out of the loop. */ - if( op != OP_NULL ) break; - } - -/* Pass on to check the next character. */ - i++; - c++; - } - -/* If a "pow" operator was found, the strings on either side of it should be - valid unit expressions, in which case we use this routine recursively to - create corresponding trees of UnitNodes. */ - if( op != OP_NULL ) { - -/* Create a UnitNode for the operator. */ - result = NewNode( NULL, op, status ); - if( astOK ) { - -/* Create a tree of unit nodes from the string which precedes the binary - operator. Report an error if it cannot be done. */ - result->arg[ 0 ] = MakeTree( exp, i, lock, status ); - if( !result->arg[ 0 ] && astOK ) { - for( i = 0; i < oplen; i++ ) buff[ i ] = c[ i ]; - buff[ oplen ] = 0; - astError( AST__BADUN, "Missing operand before '%s'.", status, buff ); - } - -/* Create a tree of unit nodes from the string which follows the binary - operator. Report an error if it cannot be done. */ - result->arg[ 1 ] = MakeTree( c + oplen, nc - i - oplen, lock, status ); - if( !result->arg[ 1 ] && astOK ) { - for( i = 0; i < oplen; i++ ) buff[ i ] = c[ i ]; - buff[ oplen ] = 0; - astError( AST__BADUN, "Missing operand after '%s'.", status, buff ); - } - } - -/* If no binary operator was found at depth zero, see if the supplied string - starts with a function name (the only legal place for a function name - given that the string has no binary operators at depth zero). */ - } else { - if( !strncmp( exp, "sqrt(", 5 ) || !strncmp( exp, "SQRT(", 5 ) ) { - op = OP_SQRT; - oplen = 4; - } else if( !strncmp( exp, "exp(", 4 ) || !strncmp( exp, "EXP(", 4 ) ) { - op = OP_EXP; - oplen = 3; - } else if( !strncmp( exp, "ln(", 3 ) || !strncmp( exp, "LN(", 3 ) ) { - op = OP_LN; - oplen = 2; - } else if( !strncmp( exp, "log(", 4 ) || !strncmp( exp, "LOG(", 4 ) ) { - op = OP_LOG; - oplen = 3; - } - -/* If a function was found, the string following the function name - (including the opening parenthesis) should form a legal units - expresssion (all the supported functions take a single argument and - so we do not need to worry about comma-separated lists of function - arguments). Use this routine recursively to create a tree of UnitNodes - from the string which forms the function argument. */ - if( op != OP_NULL ) { - -/* Create a UnitNode for the function. */ - result = NewNode( NULL, op, status ); - if( astOK ) { - -/* Create a tree of unit nodes from the string which follows the function - name. Report an error if it cannot be done. */ - result->arg[ 0 ] = MakeTree( exp + oplen, nc - oplen, lock, status ); - if( !result->arg[ 0 ] && astOK ) { - for( i = 0; i < oplen; i++ ) buff[ i ] = c[ i ]; - buff[ oplen ] = 0; - astError( AST__BADUN, "Missing argument for '%s'.", status, buff ); - } - } - -/* Arrive here if the supplied string does not contain a binary operator - or function at depth zero. Check to see if the whole string is contained - within parentheses, In which we interpret the contents of the - parentheses as a units expression. It is safe simply to check the - first and last characters (a string like "(fred)(Harry)" is not a - legal possibility since there should be an operator in the middle).*/ - } else if( exp[ 0 ] == '(' && exp[ nc - 1 ] == ')' ) { - result = MakeTree( exp + 1, nc - 2, lock, status ); - -/* Does the string begin with a numerical constant? */ - } else if( ConStart( exp, &con, &n, status ) == 1 ) { - -/* If the entire string was a numerical constant, represent it by a LDCON - node. */ - if( n == nc ) { - result = NewNode( NULL, OP_LDCON, status ); - if( astOK ) result->con = con; - -/* If there was anything following the numerical constant, report an - error. */ - } else if( astOK ){ - astError( AST__BADUN, "Missing operator after " - "numerical string '%.*s'.", status, n, exp ); - } - -/* Does the string represent one of the named constants? If so represent it - by a an appropriate operator. */ - } else if( nc == 2 && ( !strncmp( exp, "pi", 2 ) || - !strncmp( exp, "PI", 2 ) ) ) { - result = NewNode( NULL, OP_LDPI, status ); - - } else if( nc == 1 && ( !strncmp( exp, "e", 1 ) || - !strncmp( exp, "E", 1 ) ) ) { - result = NewNode( NULL, OP_LDE, status ); - -/* The only legal possibility left is that the string represents the name - of a basic unit, possibly prefixed by a multiplier character. */ - } else { - -/* See if the string ends with the symbol for any of the known basic - units. If it matches more than one basic unit, choose the longest. - First ensure descriptions of the known units are available. */ - mmult = NULL; - plural = 0; - while( 1 ) { - unit = GetKnownUnits( lock, status ); - - maxlen = -1; - munit = NULL; - while( unit ) { - if( SplitUnit( exp, nc, unit->sym, 1, &mult, &l, status ) ) { - if( l > maxlen ) { - maxlen = l; - munit = unit; - mmult = mult; - } - } - unit = unit->next; - } - -/* If the above did not produce a match, try matching the unit symbol - case insensitive. */ - if( !munit ) { - unit = GetKnownUnits( lock, status ); - while( unit ) { - if( SplitUnit( exp, nc, unit->sym, 0, &mult, &l, status ) ) { - if( l > maxlen ) { - maxlen = l; - munit = unit; - mmult = mult; - } - } - unit = unit->next; - } - } - -/* If the above did not produce a match, try matching the unit label - case insensitive. */ - if( !munit ) { - unit = GetKnownUnits( lock, status ); - while( unit ) { - if( SplitUnit( exp, nc, unit->label, 0, &mult, &l, status ) ) { - if( l > maxlen ) { - maxlen = l; - munit = unit; - mmult = mult; - } - } - unit = unit->next; - } - } - -/* If we still do not have a match, and if the string ends with "s", try - removing the "s" (which could be a plural as in "Angstroms") and - trying again. */ - if( !munit && nc > 1 && !plural && - ( exp[ nc - 1 ] == 's' || exp[ nc - 1 ] == 'S' ) ) { - plural = 1; - nc--; - } else { - break; - } - } - if( plural ) nc++; - -/* If a known unit and multiplier combination was found, create an - OP_LDVAR node from it. */ - unit = munit; - mult = mmult; - if( unit ) { - -/* If the unit is an alias for another unit, it will have a non-NULL - value for its "use" component.In this case, use the unit for which the - identified unit is an alias. */ - result = NewNode( NULL, OP_LDVAR, status ); - if( astOK ) { - result->unit = unit->use ? unit->use : unit; - result->mult = mult; - result->name = astStore( NULL, result->unit->sym, result->unit->symlen + 1 ); - } - -/* If no known unit and multiplier combination was found, we assume the - string represents a new user-defined basic unit, possibly preceded by a - standard multiplier prefix. */ - } else { - -/* Check the string to see if starts with a known multiplier prefix (but - do not allow the multiplier to account for the entire string). */ - mult = GetMultipliers( status ); - c = exp; - while( mult ) { - n = nc - mult->symlen; - if( n > 0 && !strncmp( exp, mult->sym, mult->symlen ) ) { - c += mult->symlen; - break; - } - mult = mult->next; - } - if( !mult ) n = nc; - -/* Check there are no illegal characters in the following string. */ - for( i = 0; i < n && astOK; i++ ) { - if( !isalpha( c[ i ] ) ) { - astError( AST__BADUN, "Illegal character '%c' found.", status, c[ i ] ); - break; - } - } - -/* If succesfull, create an OP_LDVAR node for th user-defined basic unit. */ - if( astOK ) { - result = NewNode( NULL, OP_LDVAR, status ); - if( astOK ) { - result->mult = mult; - result->name = astStore( NULL, c, n + 1 ); - if( astOK ) ( (char *) result->name)[ n ] = 0; - } - } - } - } - } - } - -/* Free any returned tree if an error has occurred. */ - if( !astOK ) result = FreeTree( result, status ); - -/* Return the result. */ - return result; -} - -static void MakeUnitAlias( const char *sym, const char *alias, int *status ){ -/* -* Name: -* MakeUnitAlias - -* Purpose: -* Create a KnownUnit structure describing an alias for a known unit. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* void MakeUnitAlias( const char *sym, const char *alias, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function creates a KnownUnit structure decribing an alias for a -* known unit, and adds it to the head of the linked list of known units -* stored in a module variable. An alias is a KnownUnit which is -* identical to an existing known but which has a different symbol. - -* Parameters: -* sym -* A pointer to the symbol string of an existing KnwonUnit. The string -* should not include any multiplier prefix. -* alias -* A pointer to the symbol string to use as the alasi for the existing -* KnownUnit. The string should not include any multiplier prefix. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The supplied symbol and label strings are not copied. The -* supplied pointers are simply stored in the returned structure. -* Therefore the strings to which the pointers point should not be -* modified after this function returned (in fact this function is -* always called with literal strings for these arguments). -*/ - -/* Local Variables: */ - KnownUnit *unit; - -/* Check the global error status. */ - if( !astOK ) return; - -/* Search the existing list of KnownUnits for the specified symbol. */ - unit = known_units; - while( unit ) { - if( !strcmp( sym, unit->sym ) ) { - -/* Create a new KnownUnit for the alias. It will becomes the head of the - known units chain. */ - MakeKnownUnit( alias, unit->label, NULL, status ); - -/* Store a pointer to the KnownUnit which is to be used in place of the - alias. */ - known_units->use = unit; - -/* Leave the loop. */ - break; - } - -/* Move on to check the next existing KnownUnit. */ - unit = unit->next; - } - -/* Report an error if the supplied unit was not found. */ - if( !unit ) { - astError( AST__INTER, "MakeUnitAlias(Unit): Cannot find existing " - "units \"%s\" to associate with the alias \"%s\" (AST " - "internal programming error).", status, sym, alias ); - } -} - -static UnitNode *ModifyPrefix( UnitNode *old, int *status ) { -/* -* Name: -* ModifyPrefix - -* Purpose: -* Replace a MULT or DIV node with a LDVAR and suitable multiplier. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *ModifyPrefix( UnitNode *old, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function checks the supplied node. If it is a DIV or MULT node -* in which one argument is an LDVAR and the other is a constant, then -* its checks to see if the constant can be absorbed into the LDVAR by -* changing the multiplier in the LDVAR node. If so, it returns a new -* node which is an LDVAR with the modified multiplier. Otherwise it -* returns NULL. - -* Parameters: -* old -* Pointer to an existing UnitNode to be checked. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new UnitNode. - -* Notes: -* - A value of NULL will be returned if this function is invoked with -* the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - Multiplier *mult; - Multiplier *mmult; - UnitNode *ldcon; - UnitNode *ldvar; - UnitNode *newtree; - UnitNode *result; - double con; - double cmult; - double r; - double rmin; - int recip; - int changed; - -/* Initialise. */ - result = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* Indicate that we have not yet found any reason to return a changed - node. */ - changed = 0; - -/* Check the supplied node is a DIV or MULT node. */ - if( old->opcode == OP_DIV || old->opcode == OP_MULT ) { - -/* Get a copy of the supplied tree which we can modify safely. */ - newtree = CopyTree( old, status ); - -/* Identify the LDVAR argument (if any). */ - if( newtree->arg[ 0 ]->opcode == OP_LDVAR ) { - ldvar = newtree->arg[ 0 ]; - - } else if( newtree->arg[ 1 ]->opcode == OP_LDVAR ) { - ldvar = newtree->arg[ 1 ]; - - } else { - ldvar = NULL; - } - -/* Identify the LDCON argument (if any). */ - if( newtree->arg[ 0 ]->opcode == OP_LDCON ) { - ldcon = newtree->arg[ 0 ]; - - } else if( newtree->arg[ 1 ]->opcode == OP_LDCON ) { - ldcon = newtree->arg[ 1 ]; - - } else { - ldcon = NULL; - } - -/* If either was not found, return NULL. */ - if( !ldvar || !ldcon ) { - newtree = FreeTree( newtree, status ); - -/* Otherwise, extract the multiplier constant. If there is no multiplier, the - constant is 1.0. */ - } else { - cmult = ldvar->mult ? ldvar->mult->scale: 1.0; - -/* Extract the constant. */ - con = ldcon->con; - -/* Combine the multiplier and the constant. The resulting constant is a - factor which is used to multiply the LDVAR quantity. If the original - node is a DIV node in which the LDVAR is in the denominator, then - flag that we need to reciprocate the new MULT node which represents - "constant*LDVAR" before returning. */ - if( newtree->opcode == OP_MULT ) { - con = con*cmult; - recip = 0; - } else { - con = cmult/con; - recip = ( ldvar == newtree->arg[ 1 ] ); - } - -/* Find the closest known multiplier to the new constant. */ - rmin = ( con > 1 ) ? con : 1.0/con; - mmult = NULL; - mult = GetMultipliers( status ); - while( mult ) { - r = ( con > mult->scale) ? con/mult->scale : mult->scale/con; - if( r < rmin ) { - mmult = mult; - rmin = r; - } - mult = mult->next; - } - -/* Modify the constant to take account of the new multiplier chosen - above. "mmult" will be NULL if the best multiplier is unity. */ - if( mmult ) con = con/mmult->scale; - -/* If they have changed, associate the chosen multiplier with the LDVAR node, - and the constant with the LDCON node. */ - if( ldvar->mult != mmult ) { - ldvar->mult = mmult; - changed = 1; - } - - if( ldcon->con != con ) { - ldcon->con = con; - changed = 1; - } - -/* Unless the node is proportional to the reciprocal of the variable, the - new node should be a MULT node (it may originally have been a DIV). */ - if( !recip ) { - if( newtree->opcode != OP_MULT ){ - newtree->opcode = OP_MULT; - changed = 1; - } - -/* If the constant is 1.0 we can just return the LDVAR node by itself. */ - if( fabs( con - 1.0 ) < 1.0E-6 ) { - result = CopyTree( ldvar, status ); - newtree = FreeTree( newtree, status ); - changed = 1; - -/* Otherwise return the modified tree containing both LDVAR and LDCON nodes. */ - } else { - result = newtree; - } - -/* If the node is proportional to the reciprocal of the variable, the - new node will already be a DIV node and will have an LDCON as the first - argument (numerator) and an LDVAR as the second argument (denominator). */ - } else { - -/* The first argument (the numerator) should be the reciprocal of the constant - found above. */ - ldcon->con = 1.0/ldcon->con; - if( !astEQUAL( ldcon->con, old->arg[0]->con ) ) changed = 1; - -/* Return the modified tree containing both LDVAR and LDCON nodes. */ - result = newtree; - } - } - } - -/* If the new and old trees are equivalent, then we do not need to return - it. */ - if( !changed && result ) result = FreeTree( result, status ); - -/* Return the answer. */ - return result; -} - - -static UnitNode *NewNode( UnitNode *old, Oper code, int *status ) { -/* -* Name: -* NewNode - -* Purpose: -* Create and initialise a new UnitNode. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* UnitNode *NewNode( UnitNode *old, Oper code, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function creates and initialises a new UnitNode, or -* re-initialises an existing UnitNode to use a different op code. - -* Parameters: -* old -* Pointer to an existing UnitNode to be modified, or NULL to create -* a new UnitNode. -* code -* The op code for the new UnitNode. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new UnitNode. - -* Notes: -* - A value of NULL will be returned if this function is invoked with -* the global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - UnitNode **args; - UnitNode *result; - int i; - -/* Initialise. */ - result = NULL; - args = NULL; - -/* Check the inherited status. */ - if( !astOK ) return result; - -/* If an existig UnitNode was supplied, free any memory used to hold - pointers to its arguments. */ - if( old ) { - old->arg = astFree( old->arg ); - result = old; - -/* Otherwise, allocate memory for a new structure. */ - } else { - result = astMalloc( sizeof( UnitNode ) ); - } - -/* Check the pointer can be used safely. */ - if( astOK ) { - -/* Initialise the members of the UnitNode structure. */ - result->opcode = code; - result->arg = NULL; - result->con = AST__BAD; - result->name = NULL; - result->unit = NULL; - result->mult = NULL; - result->narg = 0; - - switch( code ){ - case OP_LDPI: - result->con = PI; - break; - - case OP_LDE: - result->con = E; - break; - - case OP_LOG: - case OP_LN: - case OP_EXP: - case OP_SQRT: - result->narg = 1; - break; - - case OP_POW: - case OP_DIV: - case OP_MULT: - result->narg = 2; - break; - - default: - ; - } - -/* Allocate memory for the UnitNode pointers which will locate the - nodes forming the arguments to the new node. */ - args = astMalloc( (result->narg)*sizeof( UnitNode * ) ); - if( astOK ) { - result->arg = args; - -/* Initialise the argument pointers to NULL. */ - for( i = 0; i < result->narg; i++ ) args[ i ] = NULL; - } - } - -/* Free any result if an error occurred. */ - if( !astOK ) { - args = astFree( args ); - result = astFree( result ); - } - -/* Return the answer. */ - return result; -} - -static void RemakeTree( UnitNode **node, int *status ) { -/* -* Name: -* RemakeTree - -* Purpose: -* Replace derived units within a tree of UnitNodes by basic units. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* void RemakeTree( UnitNode **node, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function searches for LDVAR nodes (i.e. references to unit -* symbols) within the given tree, and replaces each such node which -* refers to known derived unit with a sub-tree of nodes which -* define the derived unit in terms of known basic units. - -* Parameters: -* node -* The address of a pointer to the UnitNode at the head of the tree -* which is to be simplified. On exit the supplied tree is freed and a -* pointer to a new tree is placed at the given address. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - KnownUnit *unit; - int i; - UnitNode *newnode; - -/* Check inherited status. */ - if( !astOK ) return; - -/* Initially, we have no replacement node */ - newnode = NULL; - -/* If this is an LDVAR node... */ - if( (*node)->opcode == OP_LDVAR ) { - -/* If the LDVAR node has a multiplier associated with it, we need to - introduce a OP_MULT node to perform the scaling. */ - if( (*node)->mult ) { - newnode = NewNode( NULL, OP_MULT, status ); - if( astOK ) { - newnode->arg[0] = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - newnode->arg[0]->con = 1.0/(*node)->mult->scale; - -/* See if the node refers to a known unit. If not, or if the known unit - is a basic unit (i.e. not a derived unit) use the supplied node for - the second argument of the OP_MULT node (without the multiplier). - Otherwise, use a copy of the tree which defines the derived unit. */ - unit = (*node)->unit; - if( unit && unit->head ) { - newnode->arg[1] = CopyTree( unit->head, status ); - } else { - newnode->arg[1] = CopyTree( *node, status ); - if( astOK ) newnode->arg[1]->mult = NULL; - } - } - } - -/* If no multiplier is supplied, the replacement node is simply the tree - which defines the unscaled unit (if known), or the original node (if - unknown). */ - } else { - unit = (*node)->unit; - if( unit && unit->head ) newnode = CopyTree( unit->head, status ); - } - -/* If this is not an LDVAR Node, remake the sub-trees which form the - arguments of this node. */ - } else { - for( i = 0; i < (*node)->narg; i++ ) { - RemakeTree( &((*node)->arg[ i ]), status ); - } - } - -/* If an error has occurred, free any new node. */ - if( !astOK ) newnode = FreeTree( newnode, status ); - -/* If we have a replacement node, free the supplied tree and return a - pointer to the new tree. */ - if( newnode ) { - FreeTree( *node, status ); - *node = newnode; - } -} - -static int ReplaceNode( UnitNode *target, UnitNode *old, UnitNode *new, int *status ) { -/* -* Name: -* ReplaceNode - -* Purpose: -* Replace a node within a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* int ReplaceNode( UnitNode *target, UnitNode *old, UnitNode *new, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function replaces a specified node within a tree of UnitNodes -* with another given node. The original node is freed if found. - -* Parameters: -* target -* A pointer to the UnitNode at the head of the tree containing the -* node to be replaced. -* old -* A pointer to the UnitNode to be replaced. -* new -* A pointer to the UnitNode to replace "old". -* status -* Pointer to the inherited status variable. - -* Return Value: -* Non-zero if the "old" node was found and replaced (in which case -* the "old" node will have been freed). - -* Notes: -* - It is assumed that the "old" node occurs at most once within the -* target tree. -* - The node at the head of the target tree is not compared with the -* "old" node. It is assumed the called will already have done this. -* - A value of zero is returned if an error has already occurred, or -* if this function fails for any reason. - -*/ - -/* Local Variables: */ - int i; - int result; - -/* Initialise */ - result = 0; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Loop round the arguments of the node at the head of the target tree. - Break out of the loop as soone as the old node is found. */ - for( i = 0; i < target->narg; i++ ) { - -/* If this argument is the node to be replaced, free the old one and store - the new one, and then leave the loop. */ - if( target->arg[ i ] == old ) { - FreeTree( old, status ); - target->arg[ i ] = new; - result = 1; - break; - -/* Otherwise use this function recursively to search for the old node - within the current argument. */ - } else { - if( ReplaceNode( target->arg[ i ], old, new, status ) ) break; - } - } - -/* If an error has occurred, return zero. */ - if( !astOK ) result = 0; - -/* Return the answer. */ - return result; -} - -static int SimplifyTree( UnitNode **node, int std, int *status ) { -/* -* Name: -* SimplifyTree - -* Purpose: -* Simplify a tree of UnitNodes. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* int SimplifyTree( UnitNode **node, int std, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* This function simplifies a tree of UnitNodes. It is assumed that -* all the OP_LDVAR nodes in the tree refer to the same basic unit. -* A primary purpose of this function is to standardise the tree so -* that trees which implement equivalent transformations but which -* have different structures can be compared (for instance, so that -* "2*x" and "x*2" are treated as equal trees). If "std" is non-zero, -* reducing the complexity of the tree is only of secondary importance. -* This explains why some "simplifications" actually produced trees which -* are more complicated. - -* Parameters: -* node -* The address of a pointer to the UnitNode at the head of the tree -* which is to be simplified. On exit the supplied tree is freed and a -* pointer to a new tree is placed at the given address. -* std -* If non-zero, perform standardisations. Otherwise only perform -* genuine simplifications. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if some change was made to the tree. - -*/ - -/* Local Variables: */ - int i; - UnitNode *newnode; - UnitNode *node1; - UnitNode *node2; - Oper op; - UnitNode **factors; - double *powers; - int nfactor; - double coeff; - int result; - -/* Initialise */ - result = 0; - -/* Check inherited status. */ - if( !astOK ) return result; - -/* Initiallially, we have no replacement node. */ - newnode = NULL; - -/* First replace any complex constant expressions any corresponding - OP_LDCON nodes. */ - FixConstants( node, 0, status ); - -/* Simplify the sub-trees corresponding to the arguments of the node at - the head of the supplied tree. */ - for( i = 0; i < (*node)->narg; i++ ) { - if( SimplifyTree( &( (*node)->arg[ i ] ), std, status ) ) result = 1; - } - -/* Now do specific simplifications appropriate to the nature of the node at - the head of the tree. */ - op = (*node)->opcode; - -/* Natural log */ -/* =========== */ -/* We standardise argument powers into coefficients of the LN value. */ - if( op == OP_LN ) { - -/* If the argument is a OP_EXP node, they cancel out. Return a copy of the - argument of OP_EXP node. */ - if( (*node)->arg[ 0 ]->opcode == OP_EXP ) { - newnode = CopyTree( (*node)->arg[ 0 ]->arg[ 0 ], status ); - -/* If the argument is an OP_POW node, rearrange the nodes to represent - k*ln(x) instead of ln(x**k) (note pow nodes always have a constant - exponent - this is checked in InvertConstants). SQRT arguments will - not occur because they will have been changed into POW nodes when the - arguments of the supplied head node were simplified above. */ - } else if( std && (*node)->arg[ 0 ]->opcode == OP_POW ) { - newnode = NewNode( NULL, OP_MULT, status ); - node1 = CopyTree( (*node)->arg[ 0 ]->arg[ 1 ], status ); - node2 = NewNode( NULL, OP_LN, status ); - if( astOK ) { - node2->arg[ 0 ] = CopyTree( (*node)->arg[ 0 ]->arg[ 0 ], status ); - newnode->arg[ 0 ] = node1; - newnode->arg[ 1 ] = node2; - } - } - -/* Common log */ -/* ========== */ -/* We standardise natural logs into common logs. */ - } else if( op == OP_LOG ) { - if( std ) { - newnode = NewNode( NULL, OP_DIV, status ); - node1 = NewNode( NULL, OP_LN, status ); - node2 = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - node1->arg[ 0 ] = CopyTree( (*node)->arg[ 0 ], status ); - node2->con = log( 10.0 ); - newnode->arg[ 0 ] = node1; - newnode->arg[ 1 ] = node2; - } - } - -/* Exponential */ -/* =========== */ -/* We prefer to minimise the number of EXP nodes, so, for instance, we do not - change "exp(x*y)" to "exp(x)+exp(y)" (and the code for ADD nodes does - the inverse conversion). */ - } else if( op == OP_EXP ) { - -/* If the argument is an OP_LN node, they cancel out. Return a copy of the - argument of the OP_LN node. Common log arguments will not occur because - they will have been changed into natural logs when the arguments of - the supplied head node were simplified above. */ - if( (*node)->arg[ 0 ]->opcode == OP_LN ) { - newnode = CopyTree( (*node)->arg[ 0 ]->arg[ 0 ], status ); - } - -/* Square root */ -/* =========== */ -/* We standardise sqrt nodes into pow nodes. */ - } else if( op == OP_SQRT ) { - if( std ) { - newnode = NewNode( NULL, OP_POW, status ); - node1 = CopyTree( (*node)->arg[ 0 ], status ); - node2 = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - node2->con = 0.5; - newnode->arg[ 0 ] = node1; - newnode->arg[ 1 ] = node2; - } - } - -/* Exponentiation */ -/* ============== */ -/* We want to simplfy factors. So, for instance, (x*y)**k is converted to - (x**k)*(y**k). */ - } else if( op == OP_POW ) { - -/* If the first argument is an OP_EXP node, then change "(e**x)**k" into - "e**(k*x)" */ - if( (*node)->arg[ 0 ]->opcode == OP_EXP ) { - newnode = NewNode( NULL, OP_EXP, status ); - node1 = NewNode( NULL, OP_MULT, status ); - if( astOK ) { - node1->arg[ 0 ] = CopyTree( (*node)->arg[ 1 ], status ); - node1->arg[ 1 ] = CopyTree( (*node)->arg[ 0 ]->arg[ 0 ], status ); - newnode->arg[ 0 ] = node1; - } - -/* "x**0" can be replaced by 1.0 */ - } else if( (*node)->arg[ 1 ]->con == 0.0 ) { - newnode = NewNode( NULL, OP_LDCON, status ); - if( astOK ) newnode->con = 1.0; - -/* "x**1" can be replaced by x */ - } else if( astEQUAL( (*node)->arg[ 1 ]->con, 1.0 ) ) { - newnode = CopyTree( (*node)->arg[ 0 ], status ); - -/* If the first argument is an OP_POW node, then change "(x**k1)**k2" into - "x**(k1*k2)" */ - } else if( (*node)->arg[ 0 ]->opcode == OP_POW ) { - newnode = NewNode( NULL, OP_POW, status ); - node1 = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - node1->con = ( (*node)->arg[ 0 ]->arg[ 1 ]->con )* - ( (*node)->arg[ 1 ]->con ); - newnode->arg[ 0 ] = CopyTree( (*node)->arg[ 0 ]->arg[ 0 ], status ); - newnode->arg[ 1 ] = node1; - } - -/* If the first argument is an OP_MULT node, then change "(x*y)**k" into - "(x**(k))*(y**(k))" */ - } else if( std && (*node)->arg[ 0 ]->opcode == OP_MULT ) { - newnode = NewNode( NULL, OP_MULT, status ); - node1 = NewNode( NULL, OP_POW, status ); - if( astOK ) { - node1->arg[ 1 ] = CopyTree( (*node)->arg[ 1 ], status ); - node2 = CopyTree( node1, status ); - node1->arg[ 0 ] = CopyTree( (*node)->arg[ 0 ]->arg[ 0 ], status ); - node2->arg[ 0 ] = CopyTree( (*node)->arg[ 0 ]->arg[ 1 ], status ); - newnode->arg[ 0 ] = node1; - newnode->arg[ 1 ] = node2; - } - } - -/* Division. */ -/* ========= */ -/* We standardise divisions into corresponding multiplications. */ - } else if( op == OP_DIV ) { - -/* Division by 1 is removed. */ - if( astEQUAL( (*node)->arg[ 1 ]->con, 1.0 ) ){ - newnode = CopyTree( (*node)->arg[ 0 ], status ); - -/* Division by any other constant (except zero) is turned into a - multiplication by the reciprocal constant. */ - } else if( (*node)->arg[ 1 ]->con != AST__BAD ) { - if( (*node)->arg[ 1 ]->con != 0.0 ) { - newnode = NewNode( NULL, OP_MULT, status ); - node1 = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - node1->con = 1.0/(*node)->arg[ 1 ]->con; - newnode->arg[ 0 ] = node1; - newnode->arg[ 1 ] = CopyTree( (*node)->arg[ 0 ], status ); - } - } else { - astError( AST__BADUN, "Simplifying a units expression" - "requires a division by zero." , status); - } - -/* Other divisions "x/y" are turned into "x*(y**(-1))" */ - } else if( std ) { - newnode = NewNode( NULL, OP_MULT, status ); - node1 = NewNode( NULL, OP_POW, status ); - node2 = NewNode( NULL, OP_LDCON, status ); - if( astOK ) { - node2->con = -1.0; - node1->arg[ 0 ] = CopyTree( (*node)->arg[ 1 ], status ); - node1->arg[ 1 ] = node2; - newnode->arg[ 0 ] = CopyTree( (*node)->arg[ 0 ], status ); - newnode->arg[ 1 ] = node1; - } - } - -/* Multiplication */ -/* ============== */ - } else if( op == OP_MULT ) { - -/* If the right hand argument is constant, swap the arguments. */ - if( (*node)->arg[ 1 ]->con != AST__BAD ) { - newnode = NewNode( NULL, OP_MULT, status ); - if( astOK ) { - newnode->arg[ 0 ] = CopyTree( (*node)->arg[ 1 ], status ); - newnode->arg[ 1 ] = CopyTree( (*node)->arg[ 0 ], status ); - } - -/* Multiplication by zero produces a constant zero. */ - } else if( (*node)->arg[ 0 ]->con == 0.0 ){ - newnode = NewNode( NULL, OP_LDCON, status ); - if( astOK ) newnode->con = 0.0; - -/* Multiplication by 1 is removed. */ - } else if( astEQUAL( (*node)->arg[ 0 ]->con, 1.0 ) ){ - newnode = CopyTree( (*node)->arg[ 1 ], status ); - -/* For other MULT nodes, analyse the tree to find a list of all its - factors with an associated power for each one, and an overall constant - coefficient. */ - } else if( std ) { - FindFactors( (*node), &factors, &powers, &nfactor, &coeff, status ); - -/* Produce a new tree from these factors. The factors are standardised by - ordering them alphabetically (after conversion to a character string). */ - newnode = CombineFactors( factors, powers, nfactor, coeff, status ); - -/* Free resources */ - factors = astFree( factors ); - powers = astFree( powers ); - - } - } - -/* If we have produced a new node which is identical to the old node, - free it. Otherwise, indicate we have made some changes. */ - if( newnode ) { - if( !CmpTree( newnode, *node, 1, status ) ) { - newnode = FreeTree( newnode, status ); - } else { - result = 1; - } - } - -/* If an error has occurred, free any new node. */ - if( !astOK ) newnode = FreeTree( newnode, status ); - -/* If we have a replacement node, free the supplied tree and return a - pointer to the new tree. */ - if( newnode ) { - FreeTree( *node, status ); - *node = newnode; - } - -/* If the above produced some change, try re-simplifying the tree. */ - if( result ) SimplifyTree( node, std, status ); - -/* Return the result. */ - return result; - -} - -static int SplitUnit( const char *str, int ls, const char *u, int cs, - Multiplier **mult, int *l, int *status ) { -/* -* Name: -* SplitUnit - -* Purpose: -* Split a given string into unit name and multiplier. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* int SplitUnit( const char *str, int ls, const char *u, int cs, -* Multiplier **mult, int *l, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* Returns non-zer0 if the supplied string ends with the supplied unit -* name or label, and any leading string is a known multiplier. - -* Parameters: -* str -* The string to test, typically containing a multiplier and a unit -* symbol or label. -* ls -* Number of characters to use from "str" (not including trailing null) -* u -* Pointer to the unit label or symbol string to be searched for. -* cs -* If non-zero, the test for "u" is case insensitive. -* mult -* Address of a location at which to return the multiplier at the -* start of the supplied string. NULL is returned if the supplied -* string does not match the supplied unit, or if the string -* includes no multiplier. -* l -* Address of an int in which to return the length of "u". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if "str" ends with "u" and starts with a null string or a -* known multiplier string. - -*/ - -/* Local Variables: */ - int ret; - int lm; - int lu; - -/* Initialise */ - ret = 0; - *mult = NULL; - *l = 0; - -/* Check inherited status. */ - if( !astOK ) return ret; - -/* Find the number of characters in the supplied unit label or symbol. The - difference between lu and ls must be the length of the multiplier. */ - lu = strlen( u ); - lm = ls - lu; - -/* Make sure "str" is not shorter than "u" */ - if( lm >= 0 ) { - -/* Compare the end of "str" against "u" */ - if( cs ? !strncmp( str + lm, u, lu ) : - !Ustrncmp( str + lm, u, lu, status ) ) { - ret = 1; - -/* If "str" ends with "u", see if it starts with a known multiplier */ - if( lm > 0 ) { - ret = 0; - *mult = GetMultipliers( status ); - while( *mult ) { - if( (*mult)->symlen == lm && !strncmp( str, (*mult)->sym, lm ) ) { - ret = 1; - break; - } - *mult = (*mult)->next; - } - -/* If not, try again using case-insensitive matching. */ - if( !ret ) { - *mult = GetMultipliers( status ); - while( *mult ) { - if( (*mult)->symlen == lm && !Ustrncmp( str, (*mult)->sym, lm, status ) ) { - ret = 1; - break; - } - *mult = (*mult)->next; - } - } - -/* If not, try again using case-insensitive matching against the - multiplier label. */ - if( !ret ) { - *mult = GetMultipliers( status ); - while( *mult ) { - if( (*mult)->lablen == lm && !Ustrncmp( str, (*mult)->label, lm, status ) ) { - ret = 1; - break; - } - *mult = (*mult)->next; - } - } - - } - } - } - - *l = lu; - return ret; -} - -double astUnitAnalyser_( const char *in, double powers[9], int *status ){ -/* -*+ -* Name: -* astUnitAnalyser - -* Purpose: -* Perform a dimensional analysis of a unti string. - -* Type: -* Protected function. - -* Synopsis: -* #include "unit.h" -* double astUnitAnalyser_( const char *in, double powers[9] ) - -* Class Membership: -* Unit member function. - -* Description: -* This function parses the supplied units string if possible, and -* returns a set of pwoers and a scaling factor which represent the -* units string. - -* Parameters: -* in -* A string representation of the units, for instance "km/h". -* powers -* An array in which are returned the powers for each of the following -* basic units (in the order shown): kilogramme, metre, second, radian, -* Kelvin, count, adu, photon, magnitude, pixel. If the supplied unit -* does not depend on a given basic unit a value of 0.0 will be returned -* in the array. The returns values represent a system of units which is -* a scaled form of the supplied units, expressed in the basic units of -* m, kg, s, rad, K, count, adu, photon, mag and pixel. For instance, a -* returned array of [1,0,-2,0,0,0,0,0,0] would represent "m/s**2". - -* Returned Value: -* A scaling factor for the supplied units. The is the value, in the -* units represented by the returned powers, which corresponds to a -* value of 1.0 in the supplied units. - -* Notes: -* - An error will be reported if the units string cannot be parsed -* or refers to units or functions which cannot be analysed in this way. -* - AST__BAD is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - UnitNode *in_tree; - double result; - -/* Initialise */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Parse the input units string, producing a tree of UnitNodes which - represents the input units. A pointer to the UnitNode at the head of - the tree is returned if succesfull. Report a context message if this - fails. */ - in_tree = CreateTree( in, 1, 1, status ); - if( in_tree ) { - -/* Analyse the tree */ - if( !DimAnal( in_tree, powers, &result, status ) && astOK ) { - result = AST__BAD; - astError( AST__BADUN, "astUnitAnalyser: Error analysing input " - "units string '%s' (it may contain unsupported " - "functions or dimensionless units).", status, in ); - } - -/* Free the tree. */ - in_tree = FreeTree( in_tree, status ); - - } else if( astOK ) { - astError( AST__BADUN, "astUnitAnalyser: Error parsing input " - "units string '%s'.", status, in ); - } - -/* Return the result */ - return result; -} - -const char *astUnitLabel_( const char *sym, int *status ){ -/* -*+ -* Name: -* astUnitLabel - -* Purpose: -* Return a string label for a given unit symbol. - -* Type: -* Protected function. - -* Synopsis: -* #include "unit.h" -* const char *astUnitLabel( const char *sym ) - -* Class Membership: -* Unit member function. - -* Description: -* This function returns a pointer to a constant string containing a -* descriptive label for the unit specified by the given unit symbol. - -* Parameters: -* sym -* A string holing a known unit symbol. - -* Returned Value: -* A pointer to constant string holding a descriptive label for the -* supplied unit. A NULL pointer is returned (without error) if the -* supplied unit is unknown. - -* Notes: -* - A NULL pointer is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - const char *result; - KnownUnit *unit; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Ensure descriptions of the known units are available. */ - unit = GetKnownUnits( 1, status ); - -/* Loop through the chain of known units looking for a unit with a symbol - equal to the supplied string. If found, store a pointer to its label - and break out of the loop. */ - while( unit ) { - if( !strcmp( sym, unit->sym ) ) { - result = unit->label; - break; - } - - unit = unit->next; - } - -/* Return the answer. */ - return result; -} - -AstMapping *astUnitMapper_( const char *in, const char *out, - const char *in_lab, char **out_lab, int *status ){ -/* -*+ -* Name: -* astUnitMapper - -* Purpose: -* Create a Mapping between two system of units. - -* Type: -* Protected function. - -* Synopsis: -* #include "unit.h" -* AstMapping *astUnitMapper( const char *in, const char *out, -* const char *in_lab, char **out_lab ) - -* Class Membership: -* Unit member function. - -* Description: -* This function creates a Mapping between two specified system of -* units. It also modifes a supplied label (which is typically -* the axis label associated with the input units) so that it includes -* any functional change implied by the supplied "in" and "out" units. - -* Parameters: -* in -* A string representation of the input units, for instance "km/h". -* See "Unit Representations:" below. -* out -* A string representation of the output units, for instance "m/s". -* See "Unit Representations:" below. -* in_lab -* A label describing the quantity associated with the input units. -* If the "in" string is the Units attribute of an Axis, then -* "in_lab" should be the Label of the same Axis. May be supplied -* NULL in which case "out_lab" is ignored. -* out_lab -* The address at which to return a pointer to a label describing the -* quantity associated with the output units. For instance, if the -* input and output units are "Hz" and "sqrt(Hz)", and the input -* label is "Frequency", then the returned output label will be -* "sqrt( Frequency )". The returned label is stored in dynamically -* allocated memory which should be freed (using astFree) when no longer -* needed. - -* Returned Value: -* A pointer to a Mapping which can be used to transform values in the -* "in" system of units into the "out" system of units. The Mapping -* will have 1 input and 1 output. - -* Unit Representations: -* The string supplied for "in" and "out" should represent a system of -* units following the recommendations of the FITS WCS paper I -* "Representation of World Coordinates in FITS" (Greisen & Calabretta). -* Various commonly used variants are also allowed. -* -* To summarise, a string describing a system of units should be an -* algebraic expression which combines one or more named units. The -* following functions and operators may be used within these algebraic -* expressions: -* -* - "*": multiplication. A period "." or space " " may also be used -* to represent multiplication (a period is only interpreted as a -* multiplication operator if it is not positioned between two digits, -* and a space is only interpreted as a multiplication operator if it -* occurs between two operands). -* - "/": division. -* - "**": exponentiation. The exponent (i.e. the operand following the -* exponentiation operator) must be a constant. The symbol "^" is also -* interpreted as an exponentiation operator. Exponentiation is also -* implied by an integer following a unit name without any separator -* (e.g. "cm2" is "cm^2"). -* - log(): Common logarithm. -* - ln(): Natural logarithm. -* - sqrt(): Square root. -* - exp(): Exponential. -* -* Function names are case insensitive. White space may be included -* within an expression (note that white space between two operands -* will be interpreted as a muiltiplication operator as described -* above). Parentheses may be used to indicate the order in which -* expressions are to be evaluated (normal mathematical precedence is -* used otherwise). The following symbols may be used to represent -* constants: -* -* - "pi" -* - "e" -* -* These symbols are also case in-sensitive. -* -* The above operators and functions are used to combine together one -* or more "unit symbols". The following base unit symbols are recognised: -* -* - "m": metre. -* - "g": gram. -* - "s": second. -* - "rad": radian. -* - "sr": steradian. -* - "K": Kelvin. -* - "mol": mole. -* - "cd": candela. -* -* The following symbols for units derived fro the above basic units are -* recognised: -* -* - "sec": second (1 s) -* - "Hz": Hertz (1/s). -* - "N": Newton (kg m/s**2). -* - "J": Joule (N m). -* - "W": Watt (J/s). -* - "C": Coulomb (A s). -* - "V": Volt (J/C). -* - "Pa": Pascal (N/m**2). -* - "Ohm": Ohm (V/A). -* - "S": Siemens (A/V). -* - "F": Farad (C/V). -* - "Wb": Weber (V s). -* - "T": Tesla (Wb/m**2). -* - "H": Henry (Wb/A). -* - "lm": lumen (cd sr). -* - "lx": lux (lm/m**2). -* - "deg": degree (pi/180 rad). -* - "arcmin": arc-minute (1/60 deg). -* - "arcsec": arc-second (1/3600 deg). -* - "mas": milli-arcsecond (1/3600000 deg). -* - "min": minute (60 s). -* - "h": hour (3600 s). -* - "d": day (86400 s). -* - "yr": year (31557600 s). -* - "a": year (31557600 s). -* - "eV": electron-Volt (1.60217733E-19 J). -* - "erg": erg (1.0E-7 J). -* - "Ry": Rydberg (13.605692 eV). -* - "solMass": solar mass (1.9891E30 kg). -* - "u": unified atomic mass unit (1.6605387E-27 kg). -* - "solLum": solar luminosity (3.8268E26 W). -* - "Angstrom": Angstrom (1.0E-10 m). -* - "Ang": Angstrom -* - "A": Ampere -* - "micron": micron (1.0E-6 m). -* - "solRad": solar radius (6.9599E8 m). -* - "AU": astronomical unit (1.49598E11 m). -* - "lyr": light year (9.460730E15 m). -* - "pc": parsec (3.0867E16 m). -* - "count": count. -* - "ct": count. -* - "adu": analogue-to-digital converter unit. -* - "photon": photon. -* - "ph": photon. -* - "Jy": Jansky (1.0E-26 W /m**2 /Hz). -* - "Jan": Jansky -* - "mag": magnitude. -* - "G": Gauss (1.0E-4 T). -* - "pixel": pixel. -* - "pix": pixel. -* - "barn": barn (1.0E-28 m**2). -* - "D": Debye (1.0E-29/3 C.m). -* -* In addition, any other unknown unit symbol may be used (but of course -* no mapping will be possible between unknown units). -* -* Unit symbols may be preceded with a numerical constant (for -* instance "1000 m") or a standard multiplier symbol (for instance "km") -* to represent some multiple of the unit. The following standard -* multipliers are recognised: -* -* - "d": deci (1.0E-1) -* - "c": centi (1.0E-2) -* - "m": milli (1.0E-3) -* - "u": micro (1.0E-6) -* - "n": nano (1.0E-9) -* - "p": pico (1.0E-12) -* - "f": femto (1.0E-15) -* - "a": atto (1.0E-18) -* - "z": zepto (1.0E-21) -* - "y": yocto (1.0E-24) -* - "da": deca (1.0E1) -* - "h": hecto (1.0E2) -* - "k": kilo (1.0E3) -* - "M": mega (1.0E6) -* - "G": giga (1.0E9) -* - "T": tera (1.0E12) -* - "P": peta (1.0E15) -* - "E": exa (1.0E18) -* - "Z": zetta (1.0E21) -* - "Y": yotta (1.0E24) - -* Notes: -* - NULL values are returned without error if the supplied units are -* incompatible (for instance, if the input and output units are "kg" -* and "m" ). -* - NULL values are returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstMapping *result; - UnitNode **units; - UnitNode *in_tree; - UnitNode *intemp; - UnitNode *inv; - UnitNode *labtree; - UnitNode *newtest; - UnitNode *out_tree; - UnitNode *outtemp; - UnitNode *src; - UnitNode *testtree; - UnitNode *tmp; - UnitNode *totaltree; - UnitNode *totlabtree; - const char *c; - const char *exp; - int i; - int nc; - int nunits; - int ipass; - -/* Initialise */ - result = NULL; - if( in_lab ) *out_lab = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* A quick check for a common simple case: if the two strings are - identical, return a UnitMap.*/ - if( !strcmp( in, out ) ) { - if( in_lab ) *out_lab = astStore( NULL, in_lab, strlen( in_lab ) + 1 ); - return (AstMapping *) astUnitMap( 1, "", status ); - } - -/* More initialisation. */ - in_tree = NULL; - out_tree = NULL; - units = NULL; - -/* Parse the input units string, producing a tree of UnitNodes which - represents the input units. A pointer to the UnitNode at the head of - the tree is returned if succesfull. Report a context message if this - fails. The returned tree contains branch nodes which correspond to - operators or functions, and leaf nodes which represent constant values - or named basic units (m, s, g, K, etc). Each branch node has one or more - "arguments" (i.e. child nodes) which are operated on or combined by - the branch node in some way to produce the nodes "value". This value - is then used as an argument for the node's parent node (if any). If - the string supplied by the user refers to any known derived units (e.g. "N", - Newton) then each such unit is represented in the returned tree by a - complete sub-tree in which the head node corresponds to the derived - unit (e.g. "N") and the leaf nodes correspond to the basic units needed - to define the derived unit ( for instance, "m", "s" and "g" - metres, - seconds and grammes), or numerical constants. Thus every leaf node in the - returned tree will be a basic unit (i.e. a unit which is not defined in - terms of other units), or a numerical constant. */ - in_tree = CreateTree( in, 1, 1, status ); - if( !astOK ) astError( AST__BADUN, "astUnitMapper: Error parsing input " - "units string '%s'.", status, in ); - -/* Do the same for the output units. */ - if( astOK ) { - out_tree = CreateTree( out, 1, 1, status ); - if( !astOK ) astError( AST__BADUN, "astUnitMapper: Error parsing output " - "units string '%s'.", status, out ); - } - -/* If a blank string is supplied for both input and output units, then - assume a UnitMap is the appropriate Mapping. */ - if( !in_tree && !out_tree && astOK ) { - result = (AstMapping *) astUnitMap( 1, "", status ); - if( in_lab ) *out_lab = astStore( NULL, in_lab, strlen( in_lab ) + 1 ); - -/* Otherwise, if we have both input and output trees... */ - } else if( in_tree && out_tree && astOK ) { - -/* Locate all the basic units used within either of these two trees. An - array is formed in which each element is a pointer to a UnitNode - contained within one of the trees created above. Each basic unit - referred to in either tree will have a single entry in this array - (even if the unit is referred to more than once). */ - units = NULL; - nunits = 0; - LocateUnits( in_tree, &units, &nunits, status ); - LocateUnits( out_tree, &units, &nunits, status ); - -/* Due to the simple nature of the simplification process in SimplifyTree, - the following alogorithm sometimes fails to find a Mapping form input - to output units, but can find a Mapping from output to input units. - In this latter case, we can get the required Mapping from input to - output simply by inverting the Mapign from output to input. So try - first with the units in the original order. If this fails to find a - Mapping, try again with the units swapped, and note that the final - Mapping should be inverted before being used. */ - for( ipass = 0; ipass < 2; ipass++ ){ - if( ipass == 1 ) { - tmp = in_tree; - in_tree = out_tree; - out_tree = tmp; - } - -/* We are going to create a new tree of UnitNodes in which the head node - corresponds to the requested output units, and which has a single - non-constant leaf node corresponding to the input units. Initialise a - pointer to this new tree to indicate that it has not yet been created. */ - testtree = NULL; - -/* Loop round each basic unit used in the definition of either the input - or the output units (i.e. the elements of the array created above by - "LocateUnits"). The unit selected by this loop is referred to as the - "current" unit. On each pass through this loop, we create a tree which - is a candidate for the final required tree (the "test tree" pointed to - by the testtree pointer initialised above). In order for a mapping to - be possible between input and output units, the test tree created on - each pass through this loop must be equivalent to the test tree for the - previous pass (in other words, all the test trees must be equivalent). - We break out of the loop (and return a NULL Mapping) as soon as we find - a test tree which differs from the previous test tree. */ - for( i = 0; i < nunits; i++ ) { - -/* Create copies of the trees describing the input and output units, in which - all units other than the current unit are set to a constant value of 1. - This is done by replacing OP_LDVAR nodes (i.e. nodes which "load" the - value of a named basic unit) by OP_LDCON nodes (i.e. nodes which load - a specified constant value) in the tree copy. */ - intemp = FixUnits( in_tree, units[ i ], status ); - outtemp = FixUnits( out_tree, units[ i ], status ); - -/* Simplify these trees. An important side-effect of this simplification - is that trees are "standardised" which allows them to be compared for - equivalence. A single mathematical expression can often be represented - in many different ways (for instance "A/B" is equivalent to "(B**(-1))*A"). - Standardisation is a process of forcing all equivalent representations - into a single "standard" form. Without standardisation, trees representing - the above two expressions would not be considered to be equivalent - since thy would contain different nodes and have different structures. - As a consequence of this standardisation, the "simplification" performed - by SimplifyTree can sometimes actually make the tree more complicated - (in terms of the number of nodes in the tree). */ - SimplifyTree( &intemp, 1, status ); - SimplifyTree( &outtemp, 1, status ); - -/* If either of the simplified trees does not depend on the current unit, - then the node at the head of the simplified tree will have a constant - value (because all the units other than the current unit have been fixed - to a constant value of 1.0 above by FixUnits, leaving only the current - unit to vary in value). If both simplified trees are constants, then - neither tree depends on the current basic unit (i.e. references to the - current basic unit cancel out within each string expression - for - instance if converting from "m.s.Hz" to "km" and the current unit - is "s", then the "s.Hz" term will cause the "s" units to cancel out). In - this case ignore this basic unit and pass on to the next. */ - if( outtemp->con != AST__BAD && intemp->con != AST__BAD ) { - -/* If just one simplified tree is constant, then the two units cannot - match since one depends on the current basic unit and the other does - not. Free any test tree from previous passes and break out of the loop. */ - } else if( outtemp->con != AST__BAD || intemp->con != AST__BAD ) { - intemp = FreeTree( intemp, status ); - outtemp = FreeTree( outtemp, status ); - testtree = FreeTree( testtree, status ); - break; - -/* If neither simplified tree is constant, both depend on the current - basic unit and so we can continue to see if their dependencies are - equivalent. */ - } else { - -/* We are going to create a new tree which is the inverse of the above - simplified "intemp" tree. That is, the new tree will have a head node - corresponding to the current unit, and a single non-constant leaf node - corresponding to the input units. Create an OP_LDVAR node which can be - used as the leaf node for this inverted tree. If the input tree is - inverted successfully, this root node becomes part of the inverted tree, - and so does not need to be freed explicitly (it will be freed when the - inverted tree is freed). */ - src = NewNode( NULL, OP_LDVAR, status ); - if( astOK ) src->name = astStore( NULL, "input_units", 12 ); - -/* Now produce the inverted input tree. If the tree cannot be inverted, a - null pointer is returned. Check for this. Otherwise a pointer to the - UnitNode at the head of the inverted tree is returned. */ - inv = InvertTree( intemp, src, status ); - if( inv ) { - -/* Concatenate this tree (which goes from "input units" to "current unit") - with the simplified output tree (which goes from "current unit" to - "output units"), to get a new tree which goes from input units to output - units. */ - totaltree = ConcatTree( inv, outtemp, status ); - -/* Simplify this tree. */ - SimplifyTree( &totaltree, 1, status ); - -/* Compare this simplified tree with the tree produced for the previous - unit (if any). If they differ, we cannot map between the supplied - units so annul the test tree and break out of the loop. If this is the - first unit to be tested, use the total tree as the test tree for the - next unit. */ - if( testtree ) { - if( CmpTree( totaltree, testtree, 0, status ) ) testtree = FreeTree( testtree, status ); - totaltree = FreeTree( totaltree, status ); - if( !testtree ) break; - } else { - testtree = totaltree; - } - } - -/* If the input tree was inverted, free the inverted tree. */ - if( inv ) { - inv = FreeTree( inv, status ); - -/* If the input tree could not be inverted, we cannot convert between input - and output units. Free the node which was created to be the root of the - inverted tree (and which has consequently not been incorporated into the - inverted tree), free any testtree and break out of the loop. */ - } else { - src = FreeTree( src, status ); - testtree = FreeTree( testtree, status ); - break; - } - } - -/* Free the other trees. */ - intemp = FreeTree( intemp, status ); - outtemp = FreeTree( outtemp, status ); - - } - -/* If all the basic units used by either of the supplied system of units - produced the same test tree, leave the "swap in and out units" loop. */ - if( testtree ) break; - - } - -/* If the input and output units have been swapped, swap them back to - their original order, and invert the test tree (if there is one). */ - if( ipass > 0 ) { - tmp = in_tree; - in_tree = out_tree; - out_tree = tmp; - if( testtree ) { - src = NewNode( NULL, OP_LDVAR, status ); - if( astOK ) src->name = astStore( NULL, "input_units", 12 ); - newtest = InvertTree( testtree, src, status ); - FreeTree( testtree, status ); - testtree = newtest; - if( !newtest ) src = FreeTree( src, status ); - } - } - -/* If all the basic units used by either of the supplied system of units - produced the same test tree, create a Mapping which is equivalent to the - test tree and return it. */ - if( testtree ) { - result = MakeMapping( testtree, status ); - -/* We now go on to produce the output axis label from the supplied input - axis label. Get a tree of UnitNodes which describes the supplied label - associated with the input axis. The tree will have single OP_LDVAR node - corresponding to the basic label (i.e. the label without any single - argument functions or exponentiation operators applied). */ - if( in_lab && astOK ) { - -/* Get a pointer to the first non-blank character, and store the number of - characters to examine (this excludes any trailing white space). */ - exp = in_lab; - while( isspace( *exp ) ) exp++; - c = exp + strlen( exp ) - 1; - while( c >= exp && isspace( *c ) ) c--; - nc = c - exp + 1; - -/* Create the tree. */ - labtree = MakeLabelTree( exp, nc, status ); - if( astOK ) { - -/* Concatenate this tree (which goes from "basic label" to "input label") - with the test tree found above (which goes from "input units" to "output - units"), to get a tree which goes from basic label to output label. */ - totlabtree = ConcatTree( labtree, testtree, status ); - -/* Simplify this tree. */ - SimplifyTree( &totlabtree, 1, status ); - -/* Create the output label from this tree. */ - *out_lab = (char *) MakeExp( totlabtree, 0, 1, status ); - -/* Free the trees. */ - totlabtree = FreeTree( totlabtree, status ); - labtree = FreeTree( labtree, status ); - -/* Report a context error if the input label could not be parsed. */ - } else { - astError( AST__BADUN, "astUnitMapper: Error parsing axis " - "label '%s'.", status, in_lab ); - } - } - -/* Free the units tree. */ - testtree = FreeTree( testtree, status ); - - } - } - -/* Free resources. */ - in_tree = FreeTree( in_tree, status ); - out_tree = FreeTree( out_tree, status ); - units = astFree( units ); - -/* If an error has occurred, annul the returned Mapping. */ - if( !astOK ) { - result = astAnnul( result ); - if( in_lab ) *out_lab = astFree( *out_lab ); - } - -/* Return the result. */ - return result; - -} - -const char *astUnitNormaliser_( const char *in, int *status ){ -/* -*+ -* Name: -* astUnitNormalizer - -* Purpose: -* Normalise a unit string into FITS-WCS format. - -* Type: -* Protected function. - -* Synopsis: -* #include "unit.h" -* const char *astUnitNormaliser( const char *in ) - -* Class Membership: -* Unit member function. - -* Description: -* This function returns a standard FITS-WCS form of the supplied unit -* string. - -* Parameters: -* in -* A string representation of the units, for instance "km/h". - -* Returned Value: -* A pointer to a dynamically allocated string holding the normalized -* unit string. It should be freed using astFree when no longer needed. - -* Notes: -* - An error will be reported if the units string cannot be parsed. -* - NULL is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - UnitNode *in_tree; - double dval; - const char *result; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Parse the input units string, producing a tree of UnitNodes which - represents the input units. A pointer to the UnitNode at the head of - the tree is returned if succesfull. Report a context message if this - fails. */ - in_tree = CreateTree( in, 0, 1, status ); - if( in_tree ) { - -/* Simplify the units expression, only doing genuine simplifications. */ - SimplifyTree( &in_tree, 1, status ); - -/* Invert literal constant unit multipliers. This is because a constant of - say 1000 for a unit of "m" means "multiply the value in metres by 1000", - but a unit string of "1000 m" means "value in units of 1000 m" (i.e. - *divide* the value in metres by 1000). */ - InvertConstants( &in_tree, status ); - -/* Convert the tree into string form. */ - result = MakeExp( in_tree, 2, 1, status ); - -/* If the result is a constant value, return a blank string. */ - if( 1 == astSscanf( result, "%lg", &dval ) ) { - *((char *) result) = 0; - } - -/* Free the tree. */ - in_tree = FreeTree( in_tree, status ); - - } else { - astError( AST__BADUN, "astUnitNormaliser: Error parsing input " - "units string '%s'.", status, in ); - } - -/* Return the result */ - return result; -} - -static int Ustrcmp( const char *a, const char *b, int *status ){ -/* -* Name: -* Ustrcmp - -* Purpose: -* A case blind version of strcmp. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* int Ustrcmp( const char *a, const char *b, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* Returns 0 if there are no differences between the two strings, and 1 -* otherwise. Comparisons are case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference between -* the two strings, whereas "strcmp" does. -* - This function attempts to execute even if an error has occurred. - -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int ret; /* Returned value */ - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Loop round each character. */ - while( 1 ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - - } - - } - -/* Return the result. */ - return ret; - -} - -static int Ustrncmp( const char *a, const char *b, size_t n, int *status ){ -/* -* Name: -* Ustrncmp - -* Purpose: -* A case blind version of strncmp. - -* Type: -* Private function. - -* Synopsis: -* #include "unit.h" -* int Ustrncmp( const char *a, const char *b, size_t n, int *status ) - -* Class Membership: -* Unit member function. - -* Description: -* Returns 0 if there are no differences between the first "n" -* characters of the two strings, and 1 otherwise. Comparisons are -* case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. -* n -* The maximum number of characters to compare. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference between -* the two strings, whereas "strncmp" does. -* - This function attempts to execute even if an error has occurred. - -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int i; /* Character index */ - int ret; /* Returned value */ - - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Check pointer have been supplied. */ - if( !a || !b ) return ret; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Compare up to "n" characters. */ - for( i = 0; i < (int) n; i++ ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - - } - - } - -/* Return the result. */ - return ret; - -} - - - - - - - - - - - - -/* The rest of this file contains functions which are of use for debugging - this module. They are usually commented out. - -static const char *DisplayTree( UnitNode *node, int ind ) { - int i; - char buf[200]; - const char *result; - char *a; - const char *arg[ 2 ]; - int rl; - int slen; - const opsym[ 100 ]; - - result = ""; - - for( i = 0; i < ind; i++ ) buf[ i ] = ' '; - buf[ ind ] = 0; - - if( !node ) { - printf( "%s \n", buf ); - } else { - - printf( "%s Code: '%s' (%d)\n", buf, OpName( node->opcode ), node->opcode ); - printf( "%s Narg: %d\n", buf, node->narg ); - printf( "%s Constant: %g\n", buf, node->con ); - printf( "%s Name: %s\n", buf, node->name?node->name:"" ); - printf( "%s Unit: %s\n", buf, node->unit?node->unit->sym:"" ); - printf( "%s Mult: %s\n", buf, node->mult?node->mult->sym:"" ); - - OpSym( node, opsym ); - slen = strlen( opsym ); - rl = slen; - - if( node->narg == 0 ) { - result = astMalloc( rl + 1 ); - if( astOK ) strcpy( (char *) result, opsym ); - - } else if( node->narg == 1 ) { - rl += 2; - printf( "%s Arg 0:\n", buf ); - arg[ 0 ] = DisplayTree( (node->arg)[ 0 ], ind + 2 ); - rl += strlen( arg[ 0 ] ); - - result = astMalloc( rl + 1 ); - if( astOK ) { - a = (char *) result; - strcpy( a, opsym ); - a += slen; - *(a++) = '('; - strcpy( a, arg[0] ); - a += strlen( arg[ 0 ] ); - *(a++) = ')'; - } - - } else { - rl += 4; - for( i = 0; i < node->narg; i++ ) { - printf( "%s Arg %d:\n", buf, i ); - arg[ i ] = DisplayTree( (node->arg)[ i ], ind + 2 ); - rl += strlen( arg[ i ] ); - } - - result = astMalloc( rl + 1 ); - if( astOK ) { - a = (char *) result; - *(a++) = '('; - strcpy( a, arg[0] ); - a += strlen( arg[ 0 ] ); - *(a++) = ')'; - strcpy( a, opsym ); - a += slen; - *(a++) = '('; - strcpy( a, arg[1] ); - a += strlen( arg[ 1 ] ); - *(a++) = ')'; - } - } - } - - if( !astOK ) { - astFree( (void *) result ); - result = ""; - } - - return result; -} - -static const char *OpName( Oper op ) { - const char *name; - - if( op == OP_LDCON ) { - name = "LDCON"; - } else if( op == OP_LDVAR ) { - name = "LDVAR"; - } else if( op == OP_LOG ) { - name = "LOG"; - } else if( op == OP_LN ) { - name = "LN"; - } else if( op == OP_EXP ) { - name = "EXP"; - } else if( op == OP_SQRT ) { - name = "SQRT"; - } else if( op == OP_POW ) { - name = "POW"; - } else if( op == OP_DIV ) { - name = "DIV"; - } else if( op == OP_MULT ) { - name = "MULT"; - } else if( op == OP_LDPI ) { - name = "LDPI"; - } else if( op == OP_LDE ) { - name = "LDE"; - } else if( op == OP_NULL ) { - name = "NULL"; - } else { - name = ""; - } - - return name; -} - -static void OpSym( UnitNode *node, char *buff ) { - const char *sym = NULL; - - if( node->con != AST__BAD ) { - sprintf( buff, "%g", node->con ); - - } else if( node->opcode == OP_LDVAR ) { - sym = node->name; - - } else if( node->opcode == OP_LOG ) { - sym = "log"; - - } else if( node->opcode == OP_LN ) { - sym = "ln"; - - } else if( node->opcode == OP_EXP ) { - sym = "exp"; - - } else if( node->opcode == OP_SQRT ) { - sym = "sqrt"; - - } else if( node->opcode == OP_POW ) { - sym = "**"; - - } else if( node->opcode == OP_DIV ) { - sym = "/"; - - } else if( node->opcode == OP_MULT ) { - sym = "*"; - - } else if( node->opcode == OP_NULL ) { - sym = "NULL"; - - } else { - sym = ""; - } - - if( sym ) strcpy( buff, sym ); -} - -static const char *TreeExp( UnitNode *node ) { - char buff[ 100 ]; - char buff2[ 100 ]; - - if( node->narg == 0 ) { - OpSym( node, buff ); - - } else if( node->narg == 1 ) { - OpSym( node, buff2 ); - sprintf( buff, "%s(%s)", buff2, TreeExp( node->arg[ 0 ] ) ); - - } else if( node->narg == 2 ) { - OpSym( node, buff2 ); - sprintf( buff, "(%s)%s(%s)", TreeExp( node->arg[ 0 ] ), buff2, - TreeExp( node->arg[ 1 ] ) ); - } - - return astStore( NULL, buff, strlen( buff ) + 1 ); -} - -*/ - - - - diff --git a/ast/unit.h b/ast/unit.h deleted file mode 100644 index 3637f13..0000000 --- a/ast/unit.h +++ /dev/null @@ -1,83 +0,0 @@ -#if !defined( UNIT_INCLUDED ) /* Include this file only once */ -#define UNIT_INCLUDED -/* -*+ -* Name: -* unit.h - -* Purpose: -* Define the interface to the Unit module. - -* Description: -* This module defines functions which identify units and transform -* between them. -* -* Note that this module is not a class implementation, although it -* resembles one. - -* Functions Defined: -* Public: -* None. -* -* Protected: - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 10-DEC-2002 (DSB): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -#include "mapping.h" /* Coordinate mappings */ - -/* C header files. */ -/* --------------- */ - -/* Function prototypes. */ -/* ==================== */ -#if defined(astCLASS) /* Protected */ -AstMapping *astUnitMapper_( const char *, const char *, const char *, - char **, int * ); -const char *astUnitLabel_( const char *, int * ); -double astUnitAnalyser_( const char *, double[9], int * ); -const char *astUnitNormaliser_( const char *, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These wrap up the functions defined by this module. */ - -#if defined(astCLASS) /* Protected */ -#define astUnitMapper(in,out,inlab,outlab) astINVOKE(O,astUnitMapper_(in,out,inlab,outlab,STATUS_PTR)) -#define astUnitAnalyser(in,powers) astUnitAnalyser_(in,powers,STATUS_PTR) -#define astUnitNormaliser(in) astUnitNormaliser_(in,STATUS_PTR) -#define astUnitLabel(sym) astINVOKE(O,astUnitLabel_(sym,STATUS_PTR)) -#endif -#endif - - - diff --git a/ast/unitmap.c b/ast/unitmap.c deleted file mode 100644 index a371031..0000000 --- a/ast/unitmap.c +++ /dev/null @@ -1,1425 +0,0 @@ -/* -*class++ -* Name: -* UnitMap - -* Purpose: -* Unit (null) Mapping. - -* Constructor Function: -c astUnitMap -f AST_UNITMAP - -* Description: -* A UnitMap is a unit (null) Mapping that has no effect on the -* coordinates supplied to it. They are simply copied. This can be -* useful if a Mapping is required (e.g. to pass to another -c function) but you do not want it to have any effect. -f routine) but you do not want it to have any effect. -* The Nin and Nout attributes of a UnitMap are always equal and -* are specified when it is created. - -* Inheritance: -* The UnitMap class inherits from the Mapping class. - -* Attributes: -* The UnitMap class does not define any new attributes beyond -* those which are applicable to all Mappings. - -* Functions: -c The UnitMap class does not define any new functions beyond those -f The UnitMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S Berry (JAC, Hawaii) - -* History: -* 7-FEB-1996 (RFWS): -* Original version. -* 13-DEC-1996 (RFWS): -* Over-ride the astMapMerge method. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitUnitMapVtab -* method. -* 10-MAY-2006 (DSB): -* Override astEqual. -* 17-FEB-2012 (DSB): -* In Transform, do not copy the coordinate values if the input and -* output array are the same. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS UnitMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "object.h" /* Base Object class */ -#include "memory.h" /* AST memory management */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "unitmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(UnitMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(UnitMap,Class_Init) -#define class_vtab astGLOBAL(UnitMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstUnitMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstUnitMap *astUnitMapId_( int, const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetIsLinear( AstMapping *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void Dump( AstObject *, AstChannel *, int * ); - -/* Member functions. */ -/* ================= */ -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two UnitMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "unitmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* UnitMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two UnitMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a UnitMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the UnitMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstUnitMap *that; - AstUnitMap *this; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two UnitMap structures. */ - this = (AstUnitMap *) this_object; - that = (AstUnitMap *) that_object; - -/* Check the second object is a UnitMap. We know the first is a - UnitMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAUnitMap( that ) ) { - -/* Get the number of inputs check they are the same for both. */ - result = ( astGetNin( this ) == astGetNin( that ) ); - - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetIsLinear( AstMapping *this_mapping, int *status ){ -/* -* Name: -* GetIsLinear - -* Purpose: -* Return the value of the IsLinear attribute for a UnitMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GetIsLinear( AstMapping *this, int *status ) - -* Class Membership: -* UnitMap member function (over-rides the protected astGetIsLinear -* method inherited from the Mapping class). - -* Description: -* This function returns the value of the IsLinear attribute for a -* Frame, which is always one. - -* Parameters: -* this -* Pointer to the UnitMap. -* status -* Pointer to the inherited status variable. -*/ - return 1; -} - -void astInitUnitMapVtab_( AstUnitMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitUnitMapVtab - -* Purpose: -* Initialise a virtual function table for a UnitMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "unitmap.h" -* void astInitUnitMapVtab( AstUnitMapVtab *vtab, const char *name ) - -* Class Membership: -* UnitMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the UnitMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAUnitMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - -/* None. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - mapping->MapSplit = MapSplit; - mapping->Rate = Rate; - mapping->GetIsLinear = GetIsLinear; - -/* Declare the class dump function. There is no copy constructor or - destructor. */ - astSetDump( vtab, Dump, "UnitMap", "Unit (null) Mapping" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a UnitMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* UnitMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated UnitMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated UnitMap with one which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated UnitMap which is to be merged with -* its neighbours. This should be a cloned copy of the UnitMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* UnitMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated UnitMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *new; /* Pointer to replacement UnitMap */ - const char *class; /* Pointer to Mapping class string */ - int i1; /* Index of first UnitMap to merge */ - int i2; /* Index of last UnitMap to merge */ - int i; /* Loop counter for Mappings */ - int ngone; /* Number of UnitMaps eliminated */ - int nin; /* Number of coordinates for UnitMap */ - int result; /* Result value to return */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* If the Mapping sequence consists of a single UnitMap, simply check - if the asociated Invert flag is set, and clear it if necessary. */ - if ( *nmap == 1 ) { - if ( ( *invert_list )[ 0 ] ) { - ( *invert_list )[ 0 ] = 0; - -/* Note if the Mapping sequence was modified. */ - result = 0; - } - -/* In series. */ -/* ========== */ -/* If a UnitMap occurs in series with any other Mapping, it can simply - be eliminated, so annul its Mapping pointer. */ - } else if ( *nmap > 1 ) { - if ( series ) { - ( *map_list )[ where ] = astAnnul( ( *map_list )[ where ] ); - -/* Loop to move any following pointers and their Invert flags down in - the array to fill the gap, and clear the vacated elements at the - end of the arrays. */ - for ( i = where + 1; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = where; - -/* In parallel. */ -/* ============ */ -/* If a UnitMap occurs in parallel with other Mappings, it can be - merged with any UnitMaps on either side of itself. */ - } else { - -/* Initialise indices to identify any adjacent UnitMaps and the number - of coordinates to be handled by the replacement. */ - i1 = i2 = where; - nin = astGetNin( ( *map_list )[ where ] ); - -/* Loop to inspect earlier Mappings, obtaining the Mapping Class name - and checking it is "UnitMap". Quit looping as soon as any other - class of Mapping is found. */ - while ( i1 - 1 >= 0 ) { - class = astGetClass( ( *map_list )[ i1 - 1 ] ); - if ( !astOK || strcmp( class, "UnitMap" ) ) break; - -/* Update the index of the earliest UnitMap that is to be merged and - increment the total number of coordinates involved. */ - i1--; - nin += astGetNin( ( *map_list )[ i1 ] ); - } - -/* Repeat the above process to inspect any later Mappings in the - sequence. */ - while ( i2 + 1 < *nmap ) { - class = astGetClass( ( *map_list )[ i2 + 1 ] ); - if ( !astOK || strcmp( class, "UnitMap" ) ) break; - i2++; - nin += astGetNin( ( *map_list )[ i2 ] ); - } - -/* Calculate the net number of Mappings that can be removed from the - sequence and check if this is zero, meaning that there were no - adjacent UnitMaps to merge with. */ - if ( astOK ) { - ngone = i2 - i1; - if ( !ngone ) { - -/* If so, simply check if the nominated UnitMap's Invert flag is set, - and clear it if necessary. */ - if ( ( *invert_list )[ where ] ) { - ( *invert_list )[ where ] = 0; - -/* Note if the Mapping sequence was modified. */ - result = where; - } - -/* If UnitMaps can be merged, create the replacement UnitMap. */ - } else { - new = (AstMapping *) astUnitMap( nin, "", status ); - if ( astOK ) { - -/* Annul the pointers to all the UnitMaps that are being replaced. */ - for ( i = i1; i <= i2; i++ ) { - ( *map_list )[ i ] = astAnnul( ( *map_list )[ i ] ); - } - -/* Insert the new pointer and the associated Invert flag. */ - ( *map_list )[ i1 ] = new; - ( *invert_list )[ i1 ] = 0; - -/* Loop to close the resulting gap by moving subsequent elements down - in the arrays. */ - for ( i = i2 + 1; i < *nmap; i++ ) { - ( *map_list )[ i - ngone ] = ( *map_list )[ i ]; - ( *invert_list )[ i - ngone ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated elements at the end. */ - for ( i = *nmap - ngone; i < *nmap; i++ ) { - ( *map_list )[ i ] = NULL; - ( *invert_list )[ i ] = 0; - } - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap ) -= ngone; - result = i1; - } - } - } - } - } - -/* Return the result. */ - return result; -} - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* UnitMap. - -* Type: -* Private function. - -* Synopsis: -* #include "unitmap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* UnitMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing UnitMap. This is only possible if the specified inputs -* correspond to some subset of the UnitMap outputs. That is, there -* must exist a subset of the UnitMap outputs for which each output -* depends only on the selected UnitMap inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied UnitMap, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the UnitMap to be split (the UnitMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied UnitMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied UnitMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied UnitMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstUnitMap *this; /* Pointer to UnitMap structure */ - int *result; /* Pointer to returned array */ - int i; /* Loop count */ - int iin; /* Mapping input index */ - int mnin; /* No. of Mapping inputs */ - int ok; /* Are input indices OK? */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the UnitMap structure. */ - this = (AstUnitMap *) this_map; - -/* Allocate memory for the returned array and create a UnitMap with the - required number of axes. */ - result = astMalloc( sizeof( int )*(size_t) nin ); - *map = (AstMapping *) astUnitMap( nin, "", status ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Store the required output axis indices. At the same time check that each - axis is valid. */ - mnin = astGetNin( this ); - ok = 1; - for( i = 0; i < nin; i++ ) { - iin = in[ i ]; - if( iin >= 0 && iin < mnin ) { - result[ i ] = iin; - } else { - ok = 0; - break; - } - } - -/* If the "in" array contained any invalid values, free the returned - resources. */ - if( !ok ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - } - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "unitmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* UnitMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -*/ - - return ( ax1 == ax2 ) ? 1.0 : 0.0; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a UnitMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "unitmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* UnitMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a UnitMap and a set of points encapsulated in a -* PointSet and transforms the points so as to perform the identity -* transformation (i.e. simply copies the coordinate values). - -* Parameters: -* this -* Pointer to the UnitMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. In this case, both transformations are equivalent. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the UnitMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstUnitMap *map; /* Pointer to UnitMap to be applied */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - int coord; /* Loop counter for coordinates */ - int ncoord_in; /* Number of coordinates per input point */ - int npoint; /* Number of points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the UnitMap. */ - map = (AstUnitMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - coordinate copy needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - ncoord_in = astGetNcoord( in ); - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* We need not determine whether to apply the forward or inverse - transformation, as they are both the same. */ - -/* Copy the coordinate values. */ -/* --------------------------- */ - if ( astOK ) { - -/* Loop to copy the values for each coordinate. Use a memory copy for speed. - Do not do the copy if the input and output arrays are the same. */ - for ( coord = 0; coord < ncoord_in; coord++ ) { - if( ptr_out[ coord ] != ptr_in[ coord ] ) { - (void) memcpy( (void *) ptr_out[ coord ], - (const void *) ptr_in[ coord ], - sizeof( double ) * (size_t) npoint ); - } - } - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Copy constructor. */ -/* ----------------- */ -/* No copy constructor is needed, as a byte-by-byte copy suffices. */ - -/* Destructor. */ -/* ----------- */ -/* No destructor is needed as no memory, etc. needs freeing. */ - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for UnitMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the UnitMap class to an output Channel. - -* Parameters: -* this -* Pointer to the UnitMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstUnitMap *this; /* Pointer to the UnitMap structure */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the UnitMap structure. */ - this = (AstUnitMap *) this_object; - -/* Write out values representing the instance variables for the - UnitMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* There are no values to write, so return without further action. */ -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAUnitMap and astCheckUnitMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(UnitMap,Mapping) -astMAKE_CHECK(UnitMap) - -AstUnitMap *astUnitMap_( int ncoord, const char *options, int *status, ...) { -/* -*++ -* Name: -c astUnitMap -f AST_UNITMAP - -* Purpose: -* Create a UnitMap. - -* Type: -* Public function. - -* Synopsis: -c #include "unitmap.h" -c AstUnitMap *astUnitMap( int ncoord, const char *options, ... ) -f RESULT = AST_UNITMAP( NCOORD, OPTIONS, STATUS ) - -* Class Membership: -* UnitMap constructor. - -* Description: -* This function creates a new UnitMap and optionally initialises -* its attributes. -* -* A UnitMap is a unit (null) Mapping that has no effect on the -* coordinates supplied to it. They are simply copied. This can be -* useful if a Mapping is required (e.g. to pass to another -c function) but you do not want it to have any effect. -f routine) but you do not want it to have any effect. - -* Parameters: -c ncoord -f NCOORD = INTEGER (Given) -* The number of input and output coordinates (these numbers are -* necessarily the same). -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new UnitMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new UnitMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astUnitMap() -f AST_UNITMAP = INTEGER -* A pointer to the new UnitMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstUnitMap *new; /* Pointer to new UnitMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the UnitMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitUnitMap( NULL, sizeof( AstUnitMap ), !class_init, &class_vtab, - "UnitMap", ncoord ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - UnitMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new UnitMap. */ - return new; -} - -AstUnitMap *astUnitMapId_( int ncoord, const char *options, ... ) { -/* -* Name: -* astUnitMapId_ - -* Purpose: -* Create a UnitMap. - -* Type: -* Private function. - -* Synopsis: -* #include "unitmap.h" -* AstUnitMap *astUnitMapId_( int ncoord, const char *options, ... ) - -* Class Membership: -* UnitMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astUnitMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astUnitMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astUnitMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astUnitMap_. - -* Returned Value: -* The ID value associated with the new UnitMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstUnitMap *new; /* Pointer to new UnitMap */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the UnitMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitUnitMap( NULL, sizeof( AstUnitMap ), !class_init, &class_vtab, - "UnitMap", ncoord ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - UnitMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new UnitMap. */ - return astMakeId( new ); -} - -AstUnitMap *astInitUnitMap_( void *mem, size_t size, int init, - AstUnitMapVtab *vtab, const char *name, - int ncoord, int *status ) { -/* -*+ -* Name: -* astInitUnitMap - -* Purpose: -* Initialise a UnitMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "unitmap.h" -* AstUnitMap *astInitUnitMap( void *mem, size_t size, int init, -* AstUnitMapVtab *vtab, const char *name, -* int ncoord ) - -* Class Membership: -* UnitMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new UnitMap object. It allocates memory (if necessary) to accommodate -* the UnitMap plus any additional data associated with the derived class. -* It then initialises a UnitMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a UnitMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the UnitMap is to be initialised. -* This must be of sufficient size to accommodate the UnitMap data -* (sizeof(UnitMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the UnitMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the UnitMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the UnitMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new UnitMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the Object -* astClass function). -* ncoord -* The number of coordinate values per point. - -* Returned Value: -* A pointer to the new UnitMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstUnitMap *new; /* Pointer to new UnitMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitUnitMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a Mapping structure (the parent class) as the first component - within the UnitMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstUnitMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - ncoord, ncoord, 1, 1 ); - - if ( astOK ) { - -/* Initialise the UnitMap data. */ -/* ---------------------------- */ -/* There is nothing else to store. */ - -/* If an error occurred, clean up by deleting the new object (if any other - resources had been allocated, we would free these first). */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new object. */ - return new; -} - -AstUnitMap *astLoadUnitMap_( void *mem, size_t size, - AstUnitMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadUnitMap - -* Purpose: -* Load a UnitMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "unitmap.h" -* AstUnitMap *astLoadUnitMap( void *mem, size_t size, -* AstUnitMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* UnitMap loader. - -* Description: -* This function is provided to load a new UnitMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* UnitMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a UnitMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the UnitMap is to be -* loaded. This must be of sufficient size to accommodate the -* UnitMap data (sizeof(UnitMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the UnitMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the UnitMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstUnitMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new UnitMap. If this is NULL, a pointer -* to the (static) virtual function table for the UnitMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "UnitMap" is used instead. - -* Returned Value: -* A pointer to the new UnitMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstUnitMap *new; /* Pointer to the new UnitMap */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this UnitMap. In this case the - UnitMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstUnitMap ); - vtab = &class_vtab; - name = "UnitMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitUnitMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built UnitMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "UnitMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* There are no values to read. */ -/* ---------------------------- */ - -/* If an error occurred, clean up by deleting the new UnitMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new UnitMap pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -/* There are none of these. */ - - - - diff --git a/ast/unitmap.h b/ast/unitmap.h deleted file mode 100644 index c808ed1..0000000 --- a/ast/unitmap.h +++ /dev/null @@ -1,288 +0,0 @@ -#if !defined( UNITMAP_INCLUDED ) /* Include this file only once */ -#define UNITMAP_INCLUDED -/* -*+ -* Name: -* unitmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the UnitMap class. - -* Invocation: -* #include "unitmap.h" - -* Description: -* This include file defines the interface to the UnitMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The UnitMap class implements Mappings that perform an identity -* (unit) coordinate transformation, simply by copying each -* coordinate value from input to output (and similarly for the -* inverse transformation). UnitMaps are therefore of little use -* for converting coordinates, but they serve a useful role as -* "null" Mappings in cases where a Mapping is needed (e.g. to -* pass to a function), but no coordinate transformation is wanted. - -* Inheritance: -* The UnitMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astMapMerge -* Simplify a sequence of Mappings containing a UnitMap. -* astTransform -* Transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsAUnitMap -* Test class membership. -* astUnitMap -* Create a UnitMap. -* -* Protected: -* astCheckUnitMap -* Validate class membership. -* astInitUnitMap -* Initialise a UnitMap. -* astInitUnitMapVtab -* Initialise the virtual function table for the UnitMap class. -* astLoadUnitMap -* Load a UnitMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstUnitMap -* UnitMap object type. -* -* Protected: -* AstUnitMapVtab -* UnitMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RFWS: R.F. Warren-Smith (Starlink) -* DSB: David S. Berry (Starlink) - -* History: -* 7-FEB-1996 (RFWS): -* Original version. -* 13-DEC-1996 (RFWS): -* Over-ride the astMapMerge method. -* 8-JAN-2003 (DSB): -* Added protected astInitUnitMapVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* UnitMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each - object in the class (e.g. its instance variables). */ -typedef struct AstUnitMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ -/* None. */ -} AstUnitMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstUnitMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ -/* None. */ -} AstUnitMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstUnitMapGlobals { - AstUnitMapVtab Class_Vtab; - int Class_Init; -} AstUnitMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitUnitMapGlobals_( AstUnitMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(UnitMap) /* Check class membership */ -astPROTO_ISA(UnitMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstUnitMap *astUnitMap_( int, const char *, int *, ...); -#else -AstUnitMap *astUnitMapId_( int, const char *, ... )__attribute__((format(printf,2,3))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstUnitMap *astInitUnitMap_( void *, size_t, int, AstUnitMapVtab *, - const char *, int, int * ); - -/* Vtab initialiser. */ -void astInitUnitMapVtab_( AstUnitMapVtab *, const char *, int * ); - -/* Loader. */ -AstUnitMap *astLoadUnitMap_( void *, size_t, AstUnitMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -/* None. */ - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckUnitMap(this) astINVOKE_CHECK(UnitMap,this,0) -#define astVerifyUnitMap(this) astINVOKE_CHECK(UnitMap,this,1) - -/* Test class membership. */ -#define astIsAUnitMap(this) astINVOKE_ISA(UnitMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astUnitMap astINVOKE(F,astUnitMap_) -#else -#define astUnitMap astINVOKE(F,astUnitMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitUnitMap(mem,size,init,vtab,name,ncoord) \ -astINVOKE(O,astInitUnitMap_(mem,size,init,vtab,name,ncoord,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitUnitMapVtab(vtab,name) astINVOKE(V,astInitUnitMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadUnitMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadUnitMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckUnitMap to validate UnitMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ -/* None. */ -#endif - - - - - diff --git a/ast/unitnormmap.c b/ast/unitnormmap.c deleted file mode 100644 index c9e69c2..0000000 --- a/ast/unitnormmap.c +++ /dev/null @@ -1,1666 +0,0 @@ -/* -*class++ -* Name: -* UnitNormMap - -* Purpose: -* Convert a vector to a unit vector and its norm, relative to a specified centre. - -* Constructor Function: -c astUnitNormMap -f AST_UNITNORMMAP - -* Description: -* The forward transformation of a UnitNormMap subtracts the specified centre -* and then transforms the resulting vector to a unit vector and the vector norm. -* The output contains one more coordinate than the input: the initial -* Nin outputs are in the same order as the input; the final output is the norm. -* If the norm is 0, then the output of the forward transformation is AST__BAD -* for each component of the unit vector and 0 for the norm (the final value). -* -* The inverse transformation of a UnitNormMap multiplies each component -* of the provided vector by the provided norm and adds the specified centre. -* The output contains one fewer coordinate than the input: the initial Nin inputs -* are in the same order as the output; the final input is the norm. -* If the provided norm is 0 then the other input values are ignored, -* and the output vector is the centre. -* -* Example: if centre = [1, -1] then [5, 2] transforms to [4, 3] after subtracting the centre; -* the norm is 5, so the output is [0.8, 0.6, 5]. -* -* UnitNormMap enables radially symmetric transformations, as follows: -* - apply a UnitNormMap to produce a unit vector and norm (radius) -* - apply a one-dimensional mapping to the norm (radius), while passing the unit vector unchanged -* - apply the same UnitNormMap in the inverse direction to produce the result - -* Inheritance: -* The UnitNormMap class inherits from the Mapping class. - -* Attributes: -* The UnitNormMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c The UnitNormMap class does not define any new functions beyond those -f The UnitNormMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 2016 University of Washington - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RO: Russell Owen (LSST) -* DSB: David S Berry (EAO) - -* History: -* 20-APR-2016 (RO): -* Original version. -* 17-MAR-2017 (DSB): -* Fix some memory leaks in MakeMergedMap. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS UnitNormMap - -/* Macros which return the maximum and minimum of two values. */ -#define MAX(aa,bb) ((aa)>(bb)?(aa):(bb)) -#define MIN(aa,bb) ((aa)<(bb)?(aa):(bb)) - -/* Macro to check for equality of floating point values. We cannot - compare bad values directory because of the danger of floating point - exceptions, so bad values are dealt with explicitly. */ -#define EQUAL(aa,bb) (((aa)==AST__BAD)?(((bb)==AST__BAD)?1:0):(((bb)==AST__BAD)?0:(fabs((aa)-(bb))<=1.0E9*MAX((fabs(aa)+fabs(bb))*DBL_EPSILON,DBL_MIN)))) - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "unitmap.h" /* Unit mappings */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "shiftmap.h" /* ShiftMap */ -#include "winmap.h" /* ShiftMap */ -#include "channel.h" /* I/O channels */ -#include "unitnormmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(UnitNormMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(UnitNormMap,Class_Init) -#define class_vtab astGLOBAL(UnitNormMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstUnitNormMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstUnitNormMap *astUnitNormMapId_( int, const double [], const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ - -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static int GetMappingType( AstMapping *, int * ); -static AstMapping * MakeMergedMap( AstMapping *, AstMapping *, int * ); -static int GetObjSize( AstObject *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static int GetIsLinear( AstMapping *, int * ); - -/* Member functions. */ -/* ================= */ -static int GetMappingType( AstMapping *map, int *status ) { -/* -* -* Name: -* GetMappingType - -* Purpose: -* Return a code describing the mapping type, to aid simplification. - -* Type: -* Private function. - -* Synopsis: -* #include "unitnormmap.h" -* int MakeMergedMap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, int *status ) - -* Class Membership: -* UnitNormMap internal utility function. - -* Description: -* This function returns an integer code describing the type of a mapping, -* to help with merging two mappings. The codes are: -* 3 = WinMap -* 2 = ShiftMap -* 1 = UnitNormMap -* 0 = other - -* Parameters: -* map -* A pointer to the mapping -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the merged mapping, or NULL if the Mappings cannot be merged - -*/ - const char *class = astGetClass( map ); - int type = 0; - if( strcmp( class, "UnitNormMap" ) == 0 ) { - type = 1; - } else if( strcmp( class, "ShiftMap" ) == 0 ) { - type = 2; - } else if( strcmp( class, "WinMap" ) == 0){ - type = 3; - } - return type; -} - -static AstMapping * MakeMergedMap( AstMapping *map1, AstMapping *map2, int *status ){ -/* -* -* Name: -* MakeMergedMap - -* Purpose: -* Make a single Mapping that is equivalent to the merging of two other Mappings, -* one of which must be a UnitNormMap. - -* Type: -* Private function. - -* Synopsis: -* #include "unitnormmap.h" -* int MakeMergedMap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, int *status ) - -* Class Membership: -* UnitNormMap internal utility function. - -* Description: -* This function returns a single Mapping that is the equivalent of the two supplied Mappings, -* if they can be merged. One of the pair must be a UnitNormMap. -* -* Supported merges, which must be in series: -* ShiftMap + UnitNormMap(forward) = UnitNormMap(forward) -* WinMap with unit scale + UnitNormMap(forward) = UnitNormMap(forward) -* UnitNormMap(inverted) + ShiftMap = UnitNormMap(inverted) -* UnitNormMap(inverted) + WinMap with unit scale = UnitNormMap(inverted) -* UnitNormMap(forward) + identical UnitNormMap(inverted) = UnitMap -* UnitNormMap(inverted) + identical UnitNormMap(forward) = UnitMap -* UnitNormMap(forward) + UnitNormMap(inverted) = ShiftMap -* -* -* Notes: -* - A UnitMap before or after a UnitNormMap = the UnitNormMap, but UnitMap takes care of that merge. -* - The code that checks for ShiftMap + UnitNormMap probably never runs, because ShiftMap is -* converted to WinMap during simplification before it gets here. - -* Parameters: -* map1 -* A pointer to the first mapping. -* map2 -* A pointer to the second mapping. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the merged mapping, or NULL if the Mappings cannot be merged - -*/ - -/* Check the global error status. */ - if( !astOK ) return NULL; - -/* Initialise returned mapping */ - AstMapping *retmap = NULL; - -/* Set type to 1=UnitNormMap, 2=ShiftMap, 0=other for both maps */ - int type1 = GetMappingType( map1, status ); - int type2 = GetMappingType( map2, status ); - if( !astOK ) return NULL; - - if( type1 == 0 || type2 == 0 ) return NULL; /* can only merge with UnitNormMap or ShiftMap */ - - if( !(type1 == 1 || type2 == 1) ) return NULL; /* one must be a UnitNormMap */ - - if( type1 == 2 ) { - if( astGetInvert( map2 )) return NULL; /* ShiftMap + UnitNormMap(inverted) not supported */ - -/* ShiftMap + UnitNormMap(forward) = UnitNormMap(forward) */ - AstShiftMap *shiftmap = (AstShiftMap *) map1; - AstUnitNormMap *unm = (AstUnitNormMap *) map2; - int nin = astGetNin( shiftmap ); - double shiftmult = astGetInvert( shiftmap ) ? -1 : 1; - double *newcentre = astMalloc( sizeof(double)*(size_t)nin ); - if( astOK ) { - int coord = 0; - for( coord = 0; coord < nin; coord++ ){ - newcentre[coord] = unm->centre[coord] - shiftmult*shiftmap->shift[coord]; - } - retmap = (AstMapping *) astUnitNormMap( nin, newcentre, "", status ); - newcentre = astFree( (void *) newcentre ); - } - } else if( type1 == 3 ) { - if( astGetInvert( map2 )) return NULL; /* WinMap + UnitNormMap(inverted) not supported */ - -/* WinMap with unit scale + UnitNormMap(forward) = UnitNormMap(forward); - Do not create a returned Mapping (but do free the newcentre memory) if WinMap - does not have unit scale */ - AstWinMap *winmap = (AstWinMap *) map1; - AstUnitNormMap *unm = (AstUnitNormMap *) map2; - int nin = astGetNin( winmap ); - double shiftmult = astGetInvert( winmap ) ? -1 : 1; - double *newcentre = astMalloc( sizeof(double)*(size_t)nin ); - if( astOK ) { - int coord = 0; - int ok = 1; - for( coord = 0; coord < nin; coord++ ){ - if( !EQUAL( winmap->b[coord], 1.0 )) ok = 0; - newcentre[coord] = unm->centre[coord] - shiftmult*winmap->a[coord]; - } - if( ok ) retmap = (AstMapping *) astUnitNormMap( nin, newcentre, "", status ); - newcentre = astFree( (void *) newcentre ); - } - } else if( type2 == 2 ) { - if( !astGetInvert( map1 )) return NULL; /* UnitNormMap(forward) + ShiftMap not supported */ - -/* UnitNormMap(inverted) + ShiftMap = UnitNormMap(inverted) */ - AstShiftMap *shiftmap = (AstShiftMap *) map2; - AstUnitNormMap *unm = (AstUnitNormMap *) map1; - int nin = astGetNin( shiftmap ); - double shiftmult = astGetInvert( shiftmap ) ? -1 : 1; - double *newcentre = astMalloc( sizeof(double)*(size_t)nin ); - if( astOK ) { - int coord = 0; - for( coord = 0; coord < nin; coord++ ){ - newcentre[coord] = unm->centre[coord] + shiftmult*shiftmap->shift[coord]; - } - retmap = (AstMapping *) astUnitNormMap( nin, newcentre, "Invert=1", status ); - newcentre = astFree( (void *) newcentre ); - } - } else if( type2 == 3 ) { - if( !astGetInvert( map1 )) return NULL; /* UnitNormMap(forward) + WinMap not supported */ - -/* UnitNormMap(inverted) + WinMap = UnitNormMap(inverted); - Do not create a returned Mapping - but do free the newcentre memory - if WinMap - does not have unit scale */ - AstWinMap *winmap = (AstWinMap *) map2; - AstUnitNormMap *unm = (AstUnitNormMap *) map1; - int nin = astGetNin( winmap ); - double shiftmult = astGetInvert( winmap ) ? -1 : 1; - double *newcentre = astMalloc( sizeof(double)*(size_t)nin ); - if( astOK ) { - int coord = 0; - int ok = 1; - for( coord = 0; coord < nin; coord++ ){ - if( !EQUAL( winmap->b[coord], 1.0 )) ok = 0; - newcentre[coord] = unm->centre[coord] + shiftmult*winmap->a[coord]; - } - if( ok ) retmap = (AstMapping *) astUnitNormMap( nin, newcentre, "Invert=1", status ); - newcentre = astFree( (void *) newcentre ); - } - } else { - if( !astGetInvert( map1 ) == !astGetInvert( map2 )) return NULL; /* UNMs must have opposite dir. */ - -/* Two UnitNormMaps in opposite directions */ - AstUnitNormMap *unm1 = (AstUnitNormMap *) map1; - AstUnitNormMap *unm2 = (AstUnitNormMap *) map2; - - int ctrlen = MIN( astGetNin( map1 ), astGetNin( map2 ) ); - int centres_equal = 1; - int i = 0; - for( i = 0; i < ctrlen; i++ ){ - if( !EQUAL( unm1->centre[i], unm2->centre[i] )){ - centres_equal = 0; - break; - } - } - if( centres_equal ) { - -/* Two UnitNormMap in opposite directions with identical centres = UnitMap */ - retmap = (AstMapping *) astUnitMap( astGetNin( map1 ), "", status ); - } else { - if( astGetInvert( map2 )) { - -/* UnitNormMap(forward) + UnitNormMap(inverted) = ShiftMap */ - int nin = astGetNin( map1 ); - double *shift = astMalloc( sizeof(double)*(size_t)nin ); - if( astOK ) { - int coord = 0; - for( coord = 0; coord < nin; coord++ ){ - shift[coord] = unm2->centre[coord] - unm1->centre[coord]; - } - retmap = (AstMapping *) astShiftMap( nin, shift, "", status ); - shift = astFree( (void *) shift ); - } - } - } - } - - return astOK ? retmap : NULL; -} - -static int GetIsLinear( AstMapping *this_mapping, int *status ){ -/* -* Name: -* GetIsLinear - -* Purpose: -* Return the value of the IsLinear attribute for a UnitNormMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GetIsLinear( AstMapping *this, int *status ) - -* Class Membership: -* UnitNormMap member function (over-rides the protected astGetIsLinear -* method inherited from the Mapping class). - -* Description: -* This function returns the value of the IsLinear attribute for a -* Frame, which is always one. - -* Parameters: -* this -* Pointer to the UnitNormMap. -* status -* Pointer to the inherited status variable. -*/ - return 0; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "unitnormmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* UnitNormMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied UnitNormMap, -* in bytes. - -* Parameters: -* this -* Pointer to the UnitNormMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Initialise. */ - int result = 0; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Obtain a pointers to the UnitNormMap structure. */ - AstUnitNormMap *this = (AstUnitNormMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astTSizeOf( this->centre ); - -/* If an error occurred, clear the result value. */ - if( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -void astInitUnitNormMapVtab_( AstUnitNormMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitUnitNormMapVtab - -* Purpose: -* Initialise a virtual function table for a UnitNormMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "unitnormmap.h" -* void astInitUnitNormMapVtab( AstUnitNormMapVtab *vtab, const char *name ) - -* Class Membership: -* UnitNormMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the UnitNormMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Check the local error status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAUnitNormMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - AstObjectVtab *object = (AstObjectVtab *) vtab; - AstMappingVtab *mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - mapping->MapMerge = MapMerge; - mapping->GetIsLinear = GetIsLinear; - -/* Declare the class dump, copy and delete functions.*/ - astSetDump( vtab, Dump, "UnitNormMap", "Compute unit vector and norm relative to a centre" ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - astSetDelete( (AstObjectVtab *) vtab, Delete ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a UnitNormMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* UnitNormMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated UnitNormMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated UnitNormMap with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated UnitNormMap which is to be merged with -* its neighbours. This should be a cloned copy of the UnitNormMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* UnitNormMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated UnitNormMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Initialise. */ - int result = -1; - -/* Check the global error status. */ - if( !astOK ) return result; - - if( series ) { - -/* In series */ -/* Try to merge UnitNormMap with either of its neighbours. */ - AstMapping *map1 = NULL; /* The first Mapping to merge */ - AstMapping *map2 = NULL; /* The second Mapping to merge */ - AstMapping *newmap = NULL; /* The merged Mapping */ - int i1 = MAX( where - 1, 0 ); - int i2 = i1 + 1; - for( ; i2 < *nmap; i1++, i2++ ){ - map1 = ( *map_list )[ i1 ]; - map2 = ( *map_list )[ i2 ]; - int wasinverted1 = astGetInvert( map1 ); - int wasinverted2 = astGetInvert( map2 ); - astSetInvert( map1, ( *invert_list )[ i1 ] ); - astSetInvert( map2, ( *invert_list )[ i2 ] ); - newmap = MakeMergedMap( map1, map2, status ); - astSetInvert( map1, wasinverted1 ); - astSetInvert( map2, wasinverted2 ); - if( newmap ) break; - } - - if( !newmap ) return -1; - if( !astOK ) { - astAnnul( newmap ); - return -1; - } - -/* Annul the first of the two Mappings, and replace it with the merged Mapping. - Also update the invert flag. */ - (void) astAnnul( map1 ); - ( *map_list )[ i1 ] = newmap; - ( *invert_list )[ i1 ] = astGetInvert( newmap ); - -/* Annul the second of the two Mappings, and shuffle down the rest of the list to fill the gap. */ - (void) astAnnul( map2 ); - int i = 0; - for( i = i2 + 1; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first modified element. */ - ( *nmap )--; - result = i1; - - } else { - -/* In parallel. */ -/* UnitNormMaps cannot combine in parallel with any other Mappings. */ - } - -/* Return the result. */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a UnitNormMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "unitnormmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* UnitNormMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a UnitNormMap and a set of points encapsulated in a -* PointSet and transforms the points so as to map them into the -* required window. - -* Parameters: -* this -* Pointer to the UnitNormMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the UnitNormMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Check the global error status. */ - if( !astOK ) return NULL; - -/* Obtain a pointer to the UnitNormMap. */ - AstUnitNormMap *map = (AstUnitNormMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - AstPointSet *result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - int ncoord_in = astGetNcoord( in ); - int ncoord_out = astGetNcoord( result ); - int npoint = astGetNpoint(in); - double **ptr_in = astGetPoints(in); - double **ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse mapping, according to the - direction specified and whether the mapping has been inverted. */ - if( astGetInvert(map) ){ - forward = !forward; - } - -/* Report an error if the UnitNormMap does not contain a centre. */ - if( !map->centre && astOK ){ - const char *class = astGetClass( this ); - astError( AST__BADSM, "astTransform(%s): The supplied %s does not " - "contain any centre information.", status, class, class ); - } - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if( astOK ){ - -/* If any centre coordinate is bad then set all outputs bad */ - int const ncoord_centre = forward ? ncoord_in : ncoord_out; - int coord_ctr = 0; - for( coord_ctr = 0; coord_ctr < ncoord_centre; coord_ctr++ ){ - if( (map->centre)[coord_ctr] == AST__BAD ){ - int coord_out = 0; - for( coord_out = 0; coord_out < ncoord_out; coord_out++ ){ - int point = 0; - for( point = 0; point < npoint; point++ ){ - ptr_out[point][coord_out] = AST__BAD; - } - } - return result; - } - } - - if( forward ){ - -/* Forward transformation: vector to unit vector, norm */ - int point = 0; - for( point = 0; point < npoint; point++ ){ - -/* Compute max_relin: the maximum absolute input value relative to centre */ - double max_relin = 0; - int coord_in = 0; - for( coord_in = 0; coord_in < ncoord_in; coord_in++ ){ - double in = ptr_in[coord_in][point]; - if( in == AST__BAD ){ - -/* An input coord is bad, so all outputs are bad */ - int coord_out = 0; - for( coord_out = 0; coord_out < ncoord_out; coord_out++ ){ - ptr_out[coord_out][point] = AST__BAD; - } - goto forward_next_point; - } - double abs_relin = fabs(in - map->centre[coord_in]); - if( abs_relin > max_relin ){ - max_relin = abs_relin; - } - } - - if( max_relin == 0 ){ - -/* The norm is 0, so the unit vector (first nin components of output) is unknown */ - int coord = 0; - for( coord = 0; coord < ncoord_out - 1; coord++ ){ - ptr_out[coord][point] = AST__BAD; - } - ptr_out[ncoord_out - 1][point] = 0; - continue; - } - -/* All is well; compute scaled_sum as the sum of (relin/max_relin)^2 for each input - where relin = in - centre (the scaling avoids overflow), - then compute norm = max_relin * sqrt(scaled_sum) and set all outputs */ - double scaled_sum = 0; - int coord = 0; - for( coord = 0; coord < ncoord_in; coord++ ){ - double scaled_in = (ptr_in[coord][point] - map->centre[coord])/max_relin; - scaled_sum += scaled_in*scaled_in; - } - double norm = max_relin*sqrt(scaled_sum); - for( coord = 0; coord < ncoord_in; coord++ ){ - ptr_out[coord][point] = (ptr_in[coord][point] - map->centre[coord])/norm; - } - ptr_out[ncoord_out - 1][point] = norm; - - forward_next_point: ; - } - } else { - -/* Inverse transformation: unit vector, norm -> vector */ - int point = 0; - for( point = 0; point < npoint; point++ ){ - double norm = ptr_in[ncoord_in-1][point]; - if( norm == AST__BAD ){ - -/* Norm is bad for this point; set all output coords bad */ - int coord = 0; - for( coord = 0; coord < ncoord_out; coord++ ){ - ptr_out[coord][point] = AST__BAD; - } - } else if( norm == 0 ){ - -/* Norm is 0 for this point; set the output to the centre */ - int coord = 0; - for( coord = 0; coord < ncoord_out; coord++ ){ - ptr_out[coord][point] = map->centre[coord]; - } - } else { - int coord = 0; - for( coord = 0; coord < ncoord_out; coord++ ){ - double in = ptr_in[coord][point]; - if( in == AST__BAD ){ - ptr_out[coord][point] = AST__BAD; - } else { - ptr_out[coord][point] = in*norm + map->centre[coord]; - } - } - } - } - } - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for UnitNormMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for UnitNormMap objects. - -* Parameters: -* objin -* Pointer to the UnitNormMap to be copied. -* objout -* Pointer to the UnitNormMap being constructed. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstUnitNormMap *out; /* Pointer to output UnitNormMap */ - AstUnitNormMap *in; /* Pointer to input UnitNormMap */ - int ncoord; /* No. of axes for the mapping */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Obtain a pointer to the input and output UnitNormMaps. */ - in= (AstUnitNormMap *) objin; - out = (AstUnitNormMap *) objout; - -/* Get the number of coordinates mapped by the UnitNormMap. */ - ncoord = astGetNin( in ); - -/* Allocate memory holding copies of the centre defining the mapping. */ - out->centre = (double *) astStore( NULL, (void *) in->centre, - sizeof(double)*(size_t)ncoord ); - -/* If an error occurred, free any allocated memory. */ - if( !astOK ) { - out->centre = (double *) astFree( (void *) out->centre ); - } - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for UnitNormMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for UnitNormMap objects. - -* Parameters: -* obj -* Pointer to the UnitNormMap to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This destructor does nothing and exists only to maintain a -* one-to-one correspondence between destructors and copy -* constructors. -*/ - -/* Local Variables: */ - AstUnitNormMap *this; /* Pointer to UnitNormMap */ - -/* Obtain a pointer to the UnitNormMap structure. */ - this = (AstUnitNormMap *) obj; - -/* Free the memory holding the centre. */ - this->centre = (double *) astFree( (void *) this->centre ); - -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for UnitNormMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the UnitNormMap class to an output Channel. - -* Parameters: -* this -* Pointer to the UnitNormMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define COMMENT_LEN 50 /* Maximum length of a comment string */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment string */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Obtain a pointer to the UnitNormMap structure. */ - AstUnitNormMap *this = (AstUnitNormMap *) this_object; - -/* Get the number of coordinates to be mapped. */ - int ncoord = astGetNin( this ); - -/* Write out values representing the instance variables for the - UnitNormMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* The centre. */ - int axis = 0; - for( axis = 0; axis < ncoord; axis++ ){ - (void) sprintf( buff, "Ctr%d", axis + 1 ); - (void) sprintf( comment, "Centre for axis %d", axis + 1 ); - astWriteDouble( channel, buff, (this->centre)[ axis ] != 0.0, 0, - (this->centre)[ axis ], comment ); - } - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAUnitNormMap and astCheckUnitNormMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(UnitNormMap,Mapping) -astMAKE_CHECK(UnitNormMap) - -AstUnitNormMap *astUnitNormMap_( int ncoord, const double centre[], const char *options, int *status, ...) { -/* -*++ -* Name: -c astUnitNormMap -f AST_UNITNORMMAP - -* Purpose: -* Create a UnitNormMap. - -* Type: -* Public function. - -* Synopsis: -c #include "unitnormmap.h" -c AstUnitNormMap *astUnitNormMap( int ncoord, const double centre[], -c const char *options, ... ) -f RESULT = AST_UNITNORMMAP( NCOORD, CENTRE, OPTIONS, STATUS ) - -* Class Membership: -* UnitNormMap constructor. - -* Description: -* This function creates a new UnitNormMap and optionally initialises its -* attributes. -* -* The forward transformation of a UnitNormMap subtracts the specified centre -* and then transforms the resulting vector to a unit vector and the vector norm. -* The output contains one more coordinate than the input: the initial -* Nin outputs are in the same order as the input; the final output is the norm. -* If the norm is 0, then the output of the forward transformation is AST__BAD -* for each component of the unit vector and 0 for the norm (the final value). -* -* The inverse transformation of a UnitNormMap multiplies each component -* of the provided vector by the provided norm and adds the specified centre. -* The output contains one fewer coordinate than the input: the initial Nin inputs -* are in the same order as the output; the final input is the norm. -* If the provided norm is 0 then the other input values are ignored, -* and the output vector is the centre. -* -* Example: if centre = [1, -1] then [5, 2] transforms to [4, 3] after subtracting the centre; -* the norm is 5, so the output is [0.8, 0.6, 5]. -* -* UnitNormMap enables radially symmetric transformations, as follows: -* - apply a UnitNormMap to produce a unit vector and norm (radius) -* - apply a one-dimensional mapping to the norm (radius), while passing the unit vector unchanged -* - apply the same UnitNormMap in the inverse direction to produce the result - -* Parameters: -c ncoord -f NCOORD = INTEGER (Given) -* The number of coordinate values for each point to be -* transformed (i.e. the number of dimensions of the space in -* which the points will reside). Output will include one additional coordinate. -c centre -f CENTRE( NCOORD ) = DOUBLE PRECISION (Given) -* An array containing the values to be subtracted from the input -* coordinates before computing unit vector and norm. A separate -* value must be supplied for each coordinate. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new UnitNormMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new UnitNormMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astUnitNormMap() -f AST_UNITNORMMAP = INTEGER -* A pointer to the new UnitNormMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Get a pointer to the thread specific global data structure. */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Initialise the UnitNormMap, allocating memory and initialising the - virtual function table as well if necessary. */ - AstUnitNormMap *new = astInitUnitNormMap( NULL, sizeof( AstUnitNormMap ), !class_init, &class_vtab, - "UnitNormMap", ncoord, centre ); - -/* If successful, note that the virtual function table has been - initialised. */ - if( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new UnitNormMap's attributes. */ - va_list args; - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new UnitNormMap. */ - return new; -} - -AstUnitNormMap *astUnitNormMapId_( int ncoord, const double centre[], - const char *options, ... ) { -/* -* Name: -* astUnitNormMapId_ - -* Purpose: -* Create a UnitNormMap. - -* Type: -* Private function. - -* Synopsis: -* #include "unitnormmap.h" -* AstUnitNormMap *astUnitNormMapId_( int ncoord, const double centre[], -* const char *options, ... ) - -* Class Membership: -* UnitNormMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astUnitNormMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astUnitNormMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astUnitNormMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astUnitNormMap_. - -* Returned Value: -* The ID value associated with the new UnitNormMap. -*/ - - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Initialise the UnitNormMap, allocating memory and initialising the - virtual function table as well if necessary. */ - AstUnitNormMap *new = astInitUnitNormMap( NULL, sizeof( AstUnitNormMap ), !class_init, &class_vtab, - "UnitNormMap", ncoord, centre ); - -/* If successful, note that the virtual function table has been - initialised. */ - if( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new UnitNormMap's attributes. */ - va_list args; /* Variable argument list */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new UnitNormMap. */ - return astMakeId( new ); -} - -AstUnitNormMap *astInitUnitNormMap_( void *mem, size_t size, int init, - AstUnitNormMapVtab *vtab, const char *name, - int ncoord, const double *centre, int *status ) { -/* -*+ -* Name: -* astInitUnitNormMap - -* Purpose: -* Initialise a UnitNormMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "unitnormmap.h" -* AstUnitNormMap *astInitUnitNormMap( void *mem, size_t size, int init, -* AstUnitNormMapVtab *vtab, const char *name, -* int ncoord, const double *centre ) - -* Class Membership: -* UnitNormMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new UnitNormMap object. It allocates memory (if necessary) to accommodate -* the UnitNormMap plus any additional data associated with the derived class. -* It then initialises a UnitNormMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a UnitNormMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the UnitNormMap is to be initialised. -* This must be of sufficient size to accommodate the UnitNormMap data -* (sizeof(UnitNormMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the UnitNormMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the UnitNormMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the UnitNormMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new UnitNormMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* ncoord -* The number of coordinate values per point. -* centre -* Pointer to an array of centres, one for each coordinate. - -* Returned Value: -* A pointer to the new UnitNormMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstUnitNormMap *new; /* Pointer to new UnitNormMap */ - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Check centre */ - if( ncoord <= 0 ){ - astError( AST__BADSM, "The centre must have at least one axis", status ); - return NULL; - } - -/* If necessary, initialise the virtual function table. */ - if( init ) astInitUnitNormMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a Mapping structure (the parent class) as the first component - within the UnitNormMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstUnitNormMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - ncoord, ncoord+1, 1, 1 ); - - if( astOK ) { - -/* Initialise the UnitNormMap data. */ -/* ---------------------------- */ -/* Allocate memory to hold the centre for each axis. */ - new->centre = (double *) astMalloc( sizeof(double)*(size_t)ncoord ); - -/* Check the pointers can be used */ - if( astOK ){ - -/* Store the centre for each axis. */ - int axis = 0; - for( axis = 0; axis < ncoord; axis++ ){ - (new->centre)[ axis ] = centre ? centre[ axis ] : AST__BAD; - } - - } - -/* If an error occurred, clean up by deleting the new UnitNormMap. */ - if( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new UnitNormMap. */ - return new; -} - -AstUnitNormMap *astLoadUnitNormMap_( void *mem, size_t size, - AstUnitNormMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadUnitNormMap - -* Purpose: -* Load a UnitNormMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "unitnormmap.h" -* AstUnitNormMap *astLoadUnitNormMap( void *mem, size_t size, -* AstUnitNormMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* UnitNormMap loader. - -* Description: -* This function is provided to load a new UnitNormMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* UnitNormMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a UnitNormMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the UnitNormMap is to be -* loaded. This must be of sufficient size to accommodate the -* UnitNormMap data (sizeof(UnitNormMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the UnitNormMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the UnitNormMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstUnitNormMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new UnitNormMap. If this is NULL, a pointer -* to the (static) virtual function table for the UnitNormMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "UnitNormMap" is used instead. - -* Returned Value: -* A pointer to the new UnitNormMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants. */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - -/* Get a pointer to the thread specific global data structure. */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - astGET_GLOBALS(channel); - -/* Initialise. */ - AstUnitNormMap *new = NULL; - -/* Check the global error status. */ - if( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this UnitNormMap. In this case the - UnitNormMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if( !vtab ) { - size = sizeof( AstUnitNormMap ); - vtab = &class_vtab; - name = "UnitNormMap"; - -/* If required, initialise the virtual function table for this class. */ - if( !class_init ) { - astInitUnitNormMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built UnitNormMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if( astOK ) { - -/* Get the number of axis for the mapping. */ - int ncoord = astGetNin( (AstMapping *) new ); - -/* Allocate memory to hold the centre. */ - new->centre = (double *) astMalloc( sizeof(double)*(size_t)ncoord ); - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "UnitNormMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* The centre. */ - int axis = 0; - for( axis = 0; axis < ncoord; axis++ ){ - (void) sprintf( buff, "ctr%d", axis + 1 ); - (new->centre)[ axis ] = astReadDouble( channel, buff, 0.0 ); - } - } - -/* If an error occurred, clean up by deleting the new UnitNormMap. */ - if( !astOK ) new = astDelete( new ); - -/* Return the new UnitNormMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ diff --git a/ast/unitnormmap.h b/ast/unitnormmap.h deleted file mode 100644 index c18ba14..0000000 --- a/ast/unitnormmap.h +++ /dev/null @@ -1,299 +0,0 @@ -#if !defined( UNITNORMMAP_INCLUDED ) /* Include this file only once */ -#define UNITNORMMAP_INCLUDED -/* -*+ -* Name: -* unitnormmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the UnitNormMap class. - -* Invocation: -* #include "unitnormmap.h" - -* Description: -* This include file defines the interface to the UnitNormMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* A UnitNormMap is a Mapping which, in the forward direction, -* subtracts the specified centre and then transforms the resulting vector -* to a unit vector and the vector norm. -* The forward direction outputs one more coordinate than is input. -* -* The inverse transformation of a UnitNormMap multiplies each component -* of the provided vector by the provided norm and adds the specified centre. -* The forward direction outputs one fewer coordinate than is input. -* -* Example: if centre = [1, -1] then [5, 2] transforms to [4, 3] after subtracting the centre; -* the norm is 5, so the output is [0.8, 0.6, 5] -* -* UnitNormMap is intended for applying radially symmetric distortions, as follows: -* - apply a UnitNormMap to produce a unit vector and norm (radius) -* - apply some one-dimensional mapping to the norm (radius), while passing the unit vector unchanged -* - apply the same UnitNormMap in the inverse direction to produce the result -* - -* Inheritance: -* The UnitNormMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* ClearAttrib -* Clear an attribute value for a UnitNormMap. -* GetAttrib -* Get an attribute value for a UnitNormMap. -* SetAttrib -* Set an attribute value for a UnitNormMap. -* TestAttrib -* Test if an attribute value has been set for a UnitNormMap. -* astMapMerge -* Simplify a sequence of Mappings containing a UnitNormMap. -* astTransform -* Apply a UnitNormMap to transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* None. - -* Other Class Functions: -* Public: -* astIsAUnitNormMap -* Test class membership. -* astUnitNormMap -* Create a UnitNormMap. -* -* Protected: -* astCheckUnitNormMap -* Validate class membership. -* astInitUnitNormMap -* Initialise a UnitNormMap. -* astInitUnitNormMapVtab -* Initialise the virtual function table for the UnitNormMap class. -* astLoadUnitNormMap -* Load a UnitNormMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstUnitNormMap -* UnitNormMap object type. -* -* Protected: -* AstUnitNormMapVtab -* UnitNormMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 2016 University of Washington - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* RO: Russell Owen (LSST) - -* History: -* 20-APR-2016 (RO): -* Original version. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* UnitNormMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstUnitNormMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *centre; /* Pointer to array of shifts */ - -} AstUnitNormMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstUnitNormMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - -} AstUnitNormMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstUnitNormMapGlobals { - AstUnitNormMapVtab Class_Vtab; - int Class_Init; -} AstUnitNormMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitUnitNormMapGlobals_( AstUnitNormMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(UnitNormMap) /* Check class membership */ -astPROTO_ISA(UnitNormMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstUnitNormMap *astUnitNormMap_( int, const double [], const char *, int *, ...); -#else -AstUnitNormMap *astUnitNormMapId_( int, const double [], const char *, ... )__attribute__((format(printf,3,4))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstUnitNormMap *astInitUnitNormMap_( void *, size_t, int, AstUnitNormMapVtab *, - const char *, int, const double *, int * ); - -/* Vtab initialiser. */ -void astInitUnitNormMapVtab_( AstUnitNormMapVtab *, const char *, int * ); - -/* Loader. */ -AstUnitNormMap *astLoadUnitNormMap_( void *, size_t, AstUnitNormMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckUnitNormMap(this) astINVOKE_CHECK(UnitNormMap,this,0) -#define astVerifyUnitNormMap(this) astINVOKE_CHECK(UnitNormMap,this,1) - -/* Test class membership. */ -#define astIsAUnitNormMap(this) astINVOKE_ISA(UnitNormMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astUnitNormMap astINVOKE(F,astUnitNormMap_) -#else -#define astUnitNormMap astINVOKE(F,astUnitNormMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define \ -astInitUnitNormMap(mem,size,init,vtab,name,ncoord,centre) \ -astINVOKE(O,astInitUnitNormMap_(mem,size,init,vtab,name,ncoord,centre,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitUnitNormMapVtab(vtab,name) astINVOKE(V,astInitUnitNormMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadUnitNormMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadUnitNormMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckUnitNormMap to validate UnitNormMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#endif - -#endif diff --git a/ast/version.h.in b/ast/version.h.in deleted file mode 100644 index 49d6643..0000000 --- a/ast/version.h.in +++ /dev/null @@ -1,73 +0,0 @@ -#if !defined( VERSION_INCLUDED ) -#define VERSION_INCLUDED 1 -/* -*+ -* Name: -* version.h - -* Purpose: -* Declare version numbers - -* Description: -* Defines macros which expand to the components of the AST version -* number, namely the major and minor version numbers, and the -* release number. The version number as a string is available by -* including the file config.h, which defines macros PACKAGE_STRING, -* PACKAGE_VERSION and (equivalently to the latter) VERSION. -* -* For example, the version string `3.2.1' corresponds to major version -* 3, minor version 2, release 1. - -* Macros defined: -* AST__VMAJOR -* The AST major version number -* AST__VMINOR -* The AST minor version number -* AST__RELEASE -* The AST release number -* -* For backwards compatibility, this module also declares macros -* AST_MAJOR_VERS, AST_MINOR_VERS and AST_RELEASE. The AST__* -* macros should be used in preference to these, since the latter -* use (non-standard) single underscores. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* NG: Norman Gray (Starlink) - -* History: -* 25-NOV-2003 (NG): -* Original version -*- -*/ - -/* The current version of AST is @PACKAGE_VERSION@ */ -#define AST__VMAJOR @PACKAGE_VERSION_MAJOR@ -#define AST__VMINOR @PACKAGE_VERSION_MINOR@ -#define AST__RELEASE @PACKAGE_VERSION_RELEASE@ - -/* Deprecated macros */ -#define AST_MAJOR_VERS @PACKAGE_VERSION_MAJOR@ -#define AST_MINOR_VERS @PACKAGE_VERSION_MINOR@ -#define AST_RELEASE @PACKAGE_VERSION_RELEASE@ - -#endif /* #if ! defined(VERSION_INCLUDED) */ diff --git a/ast/wcsmap.c b/ast/wcsmap.c deleted file mode 100644 index 6ba3811..0000000 --- a/ast/wcsmap.c +++ /dev/null @@ -1,6094 +0,0 @@ -/* -*class++ -* Name: -* WcsMap - -* Purpose: -* Implement a FITS-WCS sky projection. - -* Constructor Function: -c astWcsMap -f AST_WCSMAP - -* Description: -* This class is used to represent sky coordinate projections as -* described in the FITS world coordinate system (FITS-WCS) paper II -* "Representations of Celestial Coordinates in FITS" by M. Calabretta -* and E.W. Griesen. This paper defines a set of functions, or sky -* projections, which transform longitude-latitude pairs representing -* spherical celestial coordinates into corresponding pairs of Cartesian -* coordinates (and vice versa). -* -* A WcsMap is a specialised form of Mapping which implements these -* sky projections and applies them to a specified pair of coordinates. -* All the projections in the FITS-WCS paper are supported, plus the now -* deprecated "TAN with polynomial correction terms" projection which -* is refered to here by the code "TPN". Using the FITS-WCS terminology, -* the transformation is between "native spherical" and "projection -* plane" coordinates (also called "intermediate world coordinates". -* These coordinates may, optionally, be embedded in a space with more -* than two dimensions, the remaining coordinates being copied unchanged. -* Note, however, that for consistency with other AST facilities, a -* WcsMap handles coordinates that represent angles in radians (rather -* than the degrees used by FITS-WCS). -* -* The type of FITS-WCS projection to be used and the coordinates -* (axes) to which it applies are specified when a WcsMap is first -* created. The projection type may subsequently be determined -* using the WcsType attribute and the coordinates on which it acts -* may be determined using the WcsAxis(lonlat) attribute. -* -* Each WcsMap also allows up to 100 "projection parameters" to be -* associated with each axis. These specify the precise form of the -* projection, and are accessed using PVi_m attribute, where "i" is -* the integer axis index (starting at 1), and m is an integer -* "parameter index" in the range 0 to 99. The number of projection -* parameters required by each projection, and their meanings, are -* dependent upon the projection type (most projections either do not -* use any projection parameters, or use parameters 1 and 2 associated -* with the latitude axis). Before creating a WcsMap you should consult -* the FITS-WCS paper for details of which projection parameters are -* required, and which have defaults. When creating the WcsMap, you must -* explicitly set values for all those required projection parameters -* which do not have defaults defined in this paper. - -* Inheritance: -* The WcsMap class inherits from the Mapping class. - -* Attributes: -* In addition to those attributes common to all Mappings, every -* WcsMap also has the following attributes: -* -* - NatLat: Native latitude of the reference point of a FITS-WCS projection -* - NatLon: Native longitude of the reference point of a FITS-WCS projection -* - PVi_m: FITS-WCS projection parameters -* - PVMax: Maximum number of FITS-WCS projection parameters -* - WcsAxis(lonlat): FITS-WCS projection axes -* - WcsType: FITS-WCS projection type - -* Functions: -c The WcsMap class does not define any new functions beyond those -f The WcsMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 15-FEB-1996 (DSB): -* Original version. -* 23-MAR-1996 (DSB): -* Added support for PointSets with more than 2 axes. -* 14-NOV-1996 (DSB): -* Added I/O facilities, external interface, attributes, etc. -* 16-JAN-1997 (DSB): -* Allowed WCSBAD as a projection type in astWcsMap. -* 24-APR-1997 (RFWS): -* Tidied prologues. -* 26-SEP-1997 (DSB): -* o Long descriptions of projections changed to include a textual -* description as well as the three letter acronym. -* o Added protected function astPrjDesc. -* o String values now used instead of integers to represent -* "choice" attributes externally (eg WcsType). -* 8-APR-1998 (DSB): -* Modified MapMerge so that a WcsMap can merge with its own -* inverse when astSimplify is used. -* 20-APR-1998 (DSB): -* Modified MapMerge to avoid the possibility of returning an -* empty mappings list. -* 4-SEP-1998 (DSB): -* Changed MapMerge to allow WcsMaps to swap with PermMaps in -* order to bring mergable WcsMaps closer together. -* 5-MAY-1999 (DSB): -* More corrections to MapMerge: Cleared up errors in the use of the -* supplied invert flags, and corrected logic for deciding which -* neighbouring Mapping to swap with. -* 12-JUL-1999 (DSB): -* - Report an error if too many or two few projection parameters are -* supplied in a WcsMap. -* - Corrected MapMerge to prevent unset projection parameters -* being copied to any new WcsMaps. -* - Correct handling of invert flags in WcsPerm. -* 16-JUL-1999 (DSB): -* Fixed memory leak in MapMerge. -* 11-FEB-2000 (DSB): -* Added PVj_m attributes. Attributes ProjP(0) to ProjP(9) are now -* aliases for PV(axlat)_0 to PV(axlat)_9. Renamed GLS projection -* as SFL (GLS retained as alias for SFL). -* 10-AUG-2000 (DSB): -* MapMerge no longer simplifies a CAR projection. Previously they -* were replaced by a UnitMap, but this removed the cylic nature of -* the mapping (i.e. 2.PI == 0 ). -* 6-OCT-2000 (DSB): -* Ignore leading and trailing spaces in astWCsPrjType (some -* CTYPE FITS keywords have appeared with trailing white space). -* 26-SEP-2001 (DSB): -* Changed names of all functions and structure to avoid name clashes -* with wcslib. -* 10-OCT-2002 (DSB): -* Added astIsZenithal. -* 22-OCT-2002 (DSB): -* - GetPV now returns the FITS default value instead of AST__BAD -* if a defaultable latitude projection parameter has not been set. -* - A number of changes needed to support WcsLib v2.9. -* - Added AST__TPN projection. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitWcsMapVtab -* method. -* 4-JUN-2003 (DSB): -* - Added attribute "NatLon". -* - Changed to allow a user-specified fiducial point to be stored -* in projection parameter PVi_1 and PVi_2 for the longitude axis. -* - Changed "PVj_m" to "PVi_m" for consistency with FITS-WCS paper II. -* 18-AUG-2003 (DSB): -* In function Map, assign zero longitude to output positions which -* are very close to a pole. -* 23-SEP-2003 (DSB): -* - Changed so that the NatLat and NatLon attributes refer to the -* fixed values for the projections defined in FITS-WCS paper II, rather -* than the user-defined values stored in projection parameter PVi_1 and -* PVi_2 for the longitude axis. -* 11-FEB-2004 (DSB): -* Corrected axis numbering when reporting missing keywords in -* Transform. -* 23-APR-2004 (DSB): -* Changes to simplification algorithm. -* 1-SEP-2004 (DSB): -* CopyPV rewritten to avoid assumption that the input and output -* WcsMaps have the same number of axes and that the lon/lat axes have -* the same indices. -* 7-DEC-2005 (DSB): -* Free memory allocated by calls to astReadString. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 15-FEB-2006 (DSB): -* Use dynamic rather than static memory for the parameter arrays in -* the AstPrjPrm structure.Override astGetObjSize. This is to -* reduce the in-memory size of a WcsMap. -* 10-MAY-2006 (DSB): -* Override astEqual. -* 10-AUG-2006 (DSB): -* Correct astLoadWcsMap to take acount of the different number of -* PVi_m values that can be associated with each axis. -* 4-JAN-2007 (DSB): -* Correct astLoadWcsMap to load the projection parameter with -* highest index correctly. -* 23-FEB-2007 (DSB): -* Added HPX projection. -* 1-MAR-2011 (DSB): -* In function Map, do not allow valid longitude range to include both -* the high limit and the low limt (since they are both the same point on -* the sky). -* 7-MAR-2011 (DSB): -* In function Map, only do the longitude check if the projection -* is not cyclic. -* 24-MAY-2011 (DSB): -* Added protected FITSProj and TPNTan attributes (they should be -* removed when the PolyMap class has an iterative inverse). -* 6-MAR-2014 (DSB): -* Revert the change made on 18-AUG-2003 since setting the -* longitude arbitrarily to zero for points close to the pole -* causes significant round trip errors when doing pixel->sky->pixel -* transformation for points very close to the pole, if the pixel -* size is very small. The longitude at the pole is indeterminate, -* but whatever random numerical value is returned by atan2 is -* no less useful (and no more useful) than a fixed value of zero. -* 12-JUN-2014 (DSB): -* Added XPH projection. -* 30-DEC-2017 (DSB): -* Improve merging of WcsMaps and PermMaps. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS WcsMap - -/* Macros which return the maximum and minimum of two values. */ -#define MAX(aa,bb) ((aa)>(bb)?(aa):(bb)) -#define MIN(aa,bb) ((aa)<(bb)?(aa):(bb)) - -/* Macros to check for equality of floating point values. We cannot - compare bad values directory because of the danger of floating point - exceptions, so bad values are dealt with explicitly. */ -#define EQUAL(aa,bb) (((aa)==AST__BAD)?(((bb)==AST__BAD)?1:0):(((bb)==AST__BAD)?0:(fabs((aa)-(bb))<=1.0E5*MAX((fabs(aa)+fabs(bb))*DBL_EPSILON,DBL_MIN)))) - -/* -* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a method to clear a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "wcsmap.h" -* MAKE_CLEAR(attr,component,assign,nval) - -* Class Membership: -* Defined by the WcsMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear( AstWcsMap *this, int axis ) -* -* and an external interface function of the form: -* -* void astClear_( AstWcsMap *this, int axis ) -* -* which implement a method for clearing a single value in a specified -* multi-valued attribute for an axis of a WcsMap. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. Label in "astClearLabelAt"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. The variable "axis" can be used to refer to -* the zero-based index of the attribute component being cleared. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attr,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstWcsMap *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astClear" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Assign the "clear" value. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attr##_( AstWcsMap *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,WcsMap,Clear##attr))( this, axis, status ); \ -} - - -/* -* -* Name: -* MAKE_GET - -* Purpose: -* Implement a method to get a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "wcsmap.h" -* MAKE_GET(attr,type,bad_value,assign,nval) - -* Class Membership: -* Defined by the WcsMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static Get( AstWcsMap *this, int axis ) -* -* and an external interface function of the form: -* -* astGet_( AstWcsMap *this, int axis ) -* -* which implement a method for getting a single value from a specified -* multi-valued attribute for an axis of a WcsMap. - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. This can -* use the string "axis" to represent the zero-based value index. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET(attr,type,bad_value,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attr( AstWcsMap *this, int axis, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Initialise */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astGet" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -type astGet##attr##_( AstWcsMap *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,WcsMap,Get##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_SET - -* Purpose: -* Implement a method to set a single value in a multi-valued attribute -* for a WcsMap. - -* Type: -* Private macro. - -* Synopsis: -* #include "wcsmap.h" -* MAKE_SET(attr,type,component,assign,nval) - -* Class Membership: -* Defined by the WcsMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set( AstWcsMap *this, int axis, value ) -* -* and an external interface function of the form: -* -* void astSet_( AstWcsMap *this, int axis, value ) -* -* which implement a method for setting a single value in a specified -* multi-valued attribute for a WcsMap. - -* Parameters: -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. Label in "astSetLabelAt"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET(attr,type,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstWcsMap *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astSet" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Store the new value in the structure component. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attr##_( AstWcsMap *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,WcsMap,Set##attr))( this, axis, value, status ); \ -} - -/* -* -* Name: -* MAKE_TEST - -* Purpose: -* Implement a method to test if a single value has been set in a -* multi-valued attribute for a class. - -* Type: -* Private macro. - -* Synopsis: -* #include "wcsmap.h" -* MAKE_TEST(attr,assign,nval) - -* Class Membership: -* Defined by the WcsMap class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static int Test( AstWcsMap *this, int axis ) -* -* and an external interface function of the form: -* -* int astTest_( AstWcsMap *this, int axis ) -* -* which implement a method for testing if a single value in a specified -* multi-valued attribute has been set for a class. - -* Parameters: -* attr -* The name of the attribute to be tested, as it appears in the function -* name (e.g. Label in "astTestLabelAt"). -* assign -* An expression that evaluates to 0 or 1, to be used as the returned -* value. This can use the string "axis" to represent the zero-based -* index of the value within the attribute. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_TEST(attr,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static int Test##attr( AstWcsMap *this, int axis, int *status ) { \ - int result; /* Value to return */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= nval ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astTest" #attr, astGetClass( this ), \ - axis + 1, nval ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -int astTest##attr##_( AstWcsMap *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,WcsMap,Test##attr))( this, axis, status ); \ -} - - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "globals.h" /* Thread-safe global data access */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "unitmap.h" /* Unit mappings */ -#include "permmap.h" /* Axis permutation mappings */ -#include "wcsmap.h" /* Interface definition for this class */ -#include "pal.h" /* SLALIB function prototypes */ -#include "channel.h" /* I/O channels */ -#include "proj.h" /* WCSLIB projections and WCSLIB_MXPAR */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Local Type Definitions. */ -/* ----------------------- */ -/* This structure is used to hold information describing a WCSLIB - projection. */ -typedef struct PrjData { - int prj; /* WCSLIB projection identifier value */ - int mxpar; /* Max index for a lat axis projection param */ - int mxpar2; /* Max index for a lon axis projection param */ - char desc[60]; /* Long projection description */ - char ctype[5]; /* FITS CTYPE identifying string */ - int (* WcsFwd)(double, double, struct AstPrjPrm *, double *, double *); - /* Pointer to forward projection function */ - int (* WcsRev)(double, double, struct AstPrjPrm *, double *, double *); - /* Pointer to reverse projection function */ - double theta0; /* Default native latitude of fiducial point */ -} PrjData; - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static int *(* parent_mapsplit)( AstMapping *, int, const int *, AstMapping **, int * ); - -/* The following array of PrjData structured describes each of the WCSLIB - projections. The last entry in the list should be for the AST__WCSBAD - projection. This marks the end of the list. */ -static PrjData PrjInfo[] = { - { AST__AZP, 2, 4, "zenithal perspective", "-AZP", astAZPfwd, astAZPrev, AST__DPIBY2 }, - { AST__SZP, 3, 4, "slant zenithal perspective", "-SZP", astSZPfwd, astSZPrev, AST__DPIBY2 }, - { AST__TAN, 0, 4, "gnomonic", "-TAN", astTANfwd, astTANrev, AST__DPIBY2 }, - { AST__STG, 0, 4, "stereographic", "-STG", astSTGfwd, astSTGrev, AST__DPIBY2 }, - { AST__SIN, 2, 4, "orthographic", "-SIN", astSINfwd, astSINrev, AST__DPIBY2 }, - { AST__ARC, 0, 4, "zenithal equidistant", "-ARC", astARCfwd, astARCrev, AST__DPIBY2 }, - { AST__ZPN, WCSLIB_MXPAR, 4, "zenithal polynomial", "-ZPN", astZPNfwd, astZPNrev, AST__DPIBY2 }, - { AST__ZEA, 0, 4, "zenithal equal area", "-ZEA", astZEAfwd, astZEArev, AST__DPIBY2 }, - { AST__AIR, 1, 4, "Airy", "-AIR", astAIRfwd, astAIRrev, AST__DPIBY2 }, - { AST__CYP, 2, 4, "cylindrical perspective", "-CYP", astCYPfwd, astCYPrev, 0.0 }, - { AST__CEA, 1, 4, "cylindrical equal area", "-CEA", astCEAfwd, astCEArev, 0.0 }, - { AST__CAR, 0, 4, "Cartesian", "-CAR", astCARfwd, astCARrev, 0.0 }, - { AST__MER, 0, 4, "Mercator", "-MER", astMERfwd, astMERrev, 0.0 }, - { AST__SFL, 0, 4, "Sanson-Flamsteed", "-SFL", astSFLfwd, astSFLrev, 0.0 }, - { AST__PAR, 0, 4, "parabolic", "-PAR", astPARfwd, astPARrev, 0.0 }, - { AST__MOL, 0, 4, "Mollweide", "-MOL", astMOLfwd, astMOLrev, 0.0 }, - { AST__AIT, 0, 4, "Hammer-Aitoff", "-AIT", astAITfwd, astAITrev, 0.0 }, - { AST__COP, 2, 4, "conical perspective", "-COP", astCOPfwd, astCOPrev, AST__BAD }, - { AST__COE, 2, 4, "conical equal area", "-COE", astCOEfwd, astCOErev, AST__BAD }, - { AST__COD, 2, 4, "conical equidistant", "-COD", astCODfwd, astCODrev, AST__BAD }, - { AST__COO, 2, 4, "conical orthomorphic", "-COO", astCOOfwd, astCOOrev, AST__BAD }, - { AST__BON, 1, 4, "Bonne's equal area", "-BON", astBONfwd, astBONrev, 0.0 }, - { AST__PCO, 0, 4, "polyconic", "-PCO", astPCOfwd, astPCOrev, 0.0 }, - { AST__TSC, 0, 4, "tangential spherical cube", "-TSC", astTSCfwd, astTSCrev, 0.0 }, - { AST__CSC, 0, 4, "cobe quadrilateralized spherical cube", "-CSC", astCSCfwd, astCSCrev, 0.0 }, - { AST__QSC, 0, 4, "quadrilateralized spherical cube", "-QSC", astQSCfwd, astQSCrev, 0.0 }, - { AST__NCP, 2, 4, "AIPS north celestial pole", "-NCP", NULL, NULL, 0.0 }, - { AST__GLS, 0, 4, "sinusoidal", "-GLS", astSFLfwd, astSFLrev, 0.0 }, - { AST__HPX, 2, 4, "HEALPix", "-HPX", astHPXfwd, astHPXrev, 0.0 }, - { AST__XPH, 0, 4, "polar HEALPix", "-XPH", astXPHfwd, astXPHrev, AST__DPIBY2 }, - { AST__TPN, WCSLIB_MXPAR, WCSLIB_MXPAR, "gnomonic polynomial", "-TPN", astTPNfwd, astTPNrev, AST__DPIBY2 }, - { AST__WCSBAD, 0, 4, "", " ", NULL, NULL, 0.0 } }; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GetAttrib_Buff[ 0 ] = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(WcsMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(WcsMap,Class_Init) -#define class_vtab astGLOBAL(WcsMap,Class_Vtab) -#define getattrib_buff astGLOBAL(WcsMap,GetAttrib_Buff) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -static char getattrib_buff[ 101 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstWcsMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstWcsMap *astWcsMapId_( int, int, int, int, const char *options, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static int GetObjSize( AstObject *, int * ); -static double GetPV( AstWcsMap *, int, int, int * ); -static int TestPV( AstWcsMap *, int, int, int * ); -static void ClearPV( AstWcsMap *, int, int, int * ); -static void SetPV( AstWcsMap *, int, int, double, int * ); - -static int GetPVMax( AstWcsMap *, int, int * ); -static int GetWcsType( AstWcsMap *, int * ); -static double GetNatLat( AstWcsMap *, int * ); -static double GetNatLon( AstWcsMap *, int * ); -static int GetWcsAxis( AstWcsMap *, int, int * ); - -static int GetFITSProj( AstWcsMap *, int * ); -static int TestFITSProj( AstWcsMap *, int * ); -static void ClearFITSProj( AstWcsMap *, int * ); -static void SetFITSProj( AstWcsMap *, int, int * ); - -static int GetTPNTan( AstWcsMap *, int * ); -static int TestTPNTan( AstWcsMap *, int * ); -static void ClearTPNTan( AstWcsMap *, int * ); -static void SetTPNTan( AstWcsMap *, int, int * ); - -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const PrjData *FindPrjData( int, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static int CanMerge( AstMapping *, int, AstMapping *, int, int * ); -static int CanSwap( AstMapping *, AstMapping *, int, int, int *, AstWcsMap **, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetNP( AstWcsMap *, int, int * ); -static int IsZenithal( AstWcsMap *, int * ); -static int LongRange( const PrjData *, struct AstPrjPrm *, double *, double *, int * ); -static int Map( AstWcsMap *, int, int, double *, double *, double *, double *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void CopyPV( AstWcsMap *, AstWcsMap *, int * ); -static void Delete( AstObject *obj, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void FreePV( AstWcsMap *, int * ); -static void InitPrjPrm( AstWcsMap *, int * ); -static void PermGet( AstPermMap *, int **, int **, double **, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void WcsPerm( AstMapping **, int *, int, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); - -/* Member functions. */ -/* ================= */ -static int CanMerge( AstMapping *map1, int inv1, AstMapping *map2, int inv2, int *status ){ -/* -* -* Name: -* CanMerge - -* Purpose: -* Checks if two WcsMaps can be merged. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* int CanMerge( AstMapping *map1, int inv1, AstMapping *map2, int inv2, int *status ) - -* Class Membership: -* WcsMap internal utility function. - -* Description: -* This function checks the two supplied Mappings to see if they are -* two WcsMaps which can be merged. This is only possible if they -* form an inverse pair. - -* Parameters: -* map1 -* A pointer to the first mapping. -* map2 -* A pointer to the second mapping. -* inv1 -* The invert flag to use with the first mapping. -* inv2 -* The invert flag to use with the second mapping. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* 1 if the WcsMaps can be merged, zero otherwise. - -*/ - -/* Local Variables: */ - AstWcsMap *wcs1; /* Pointer to first WcsMap */ - AstWcsMap *wcs2; /* Pointer to second WcsMap */ - int m; /* Projection parameter index */ - int ret; /* Can the Mappings be merged? */ - int i; /* Axis index */ - -/* Initialise the returned value. */ - ret = 0; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Both Mappings must be WcsMaps to merge. */ - if( !strcmp( "WcsMap", astGetClass( map1 ) ) && - !strcmp( "WcsMap", astGetClass( map2 ) ) ) { - -/* Get pointers to the WcsMaps. */ - wcs1 = (AstWcsMap *) map1; - wcs2 = (AstWcsMap *) map2; - -/* Check that the two WcsMaps performs the same sort of projection, and - have the same number of axes. */ - if( astGetWcsType( wcs1 ) == astGetWcsType( wcs2 ) && - astGetNin( wcs1 ) == astGetNin( wcs2 ) ) { - -/* Check that the Mappings are applied in opposite senses. */ - if( inv1 != inv2 ) { - -/* Check that the latitude and longitude axes have the same indices in - both WcsMaps. */ - if( astGetWcsAxis( wcs1, 0 ) == astGetWcsAxis( wcs2, 0 ) && - astGetWcsAxis( wcs1, 1 ) == astGetWcsAxis( wcs2, 1 ) ){ - -/* We nopw check the projection parameters are equal. Assume they are for - the moment. */ - ret = 1; - -/* Check the parameters for each axis in turn. */ - for( i = 0; i < astGetNin( wcs1 ); i++ ){ - -/* If the two WcsMaps have a different number of parameters for this axes, - they cannot merge. */ - if( GetNP( wcs1, i, status ) != GetNP( wcs1, i, status ) ){ - ret = 0; - break; - -/* Otherwise, check each parameter value in turn. If any are found which - are not equal, the WcsMaps cannot merge. */ - } else { - for( m = 0; m < GetNP( wcs1, i, status ); m++ ){ - if( !EQUAL( astGetPV( wcs1, i, m ), - astGetPV( wcs2, i, m ) ) ){ - ret = 0; - break; - } - } - if( !ret ) break; - } - } - } - } - } - } - -/* Return the answer. */ - return ret; -} - -static int CanSwap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, - int *simpler, AstWcsMap **newwcsmap, int *status ){ -/* -* Name: - -* CanSwap - -* Purpose: -* Determine if two Mappings could be swapped. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* int CanSwap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, -* int *simpler, AstWcsMap **newwcssmap ) - -* Class Membership: -* WcsMap member function - -* Description: -* This function returns a flag indicating if the pair of supplied -* Mappings could be replaced by an equivalent pair of Mappings from the -* same classes as the supplied pair, but in reversed order. Each pair -* of Mappings is considered to be compunded in series. The supplied -* Mapings are not changed in any way. - -* Parameters: -* map1 -* The Mapping to be applied first. -* map2 -* The Mapping to be applied second. -* inv1 -* The invert flag to use with map1. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* inv2 -* The invert flag to use with map2. -* simpler -* Addresss of a location at which to return a flag indicating if -* the swapped Mappings would be intrinsically simpler than the -* original Mappings. -* newwcsmap -* Addresss of a location at which to return a pointer to the -* WcsMap that would be produced if the two Mappings were swapped. -* Returned holding NULL if the supplied Mappings cannot be swapped. - -* Returned Value: -* 1 if the Mappings could be swapped, 0 otherwise. - -* Notes: -* - One of the supplied pair of Mappings must be a WcsMap. -* - A value of 0 is returned if the two Mappings could be merged into -* a single Mapping. -* - A value of 0 is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *maps[2]; /* Pointer to Mappign list */ - AstMapping *nowcs; /* Pointer to non-WcsMap Mapping */ - AstWcsMap *wcs; /* Pointer to WcsMap Mapping */ - const char *class1; /* Pointer to map1 class string */ - const char *class2; /* Pointer to map2 class string */ - const char *nowcs_class; /* Pointer to non-WcsMap class string */ - double *consts; /* Pointer to constants array */ - int *inperm; /* Pointer to input axis permutation array */ - int *outperm; /* Pointer to output axis permutation array */ - int i; /* Loop count */ - int invert[ 2 ]; /* Original invert flags */ - int iwm; /* Index of WcsMap within "maps" */ - int latax; /* Index of latitude axis in WcsMap */ - int lonax; /* Index of longitude axis in WcsMap */ - int nin; /* No. of input coordinates for the PermMap */ - int nout; /* No. of output coordinates for the PermMap */ - int ret; /* Returned flag */ - -/* Initialise */ - ret = 0; - *simpler = 0; - *newwcsmap = NULL; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Temporarily set the Invert attributes of both Mappings to the supplied - values. */ - invert[ 0 ] = astGetInvert( map1 ); - astSetInvert( map1, inv1 ); - - invert[ 1 ] = astGetInvert( map2 ); - astSetInvert( map2, inv2 ); - -/* Get the classes of the two mappings. */ - class1 = astGetClass( map1 ); - class2 = astGetClass( map2 ); - if( astOK ){ - -/* Get a pointer to the non-WcsMap Mapping. */ - if( !strcmp( class1, "WcsMap" ) ){ - iwm = 0; - wcs = (AstWcsMap *) map1; - nowcs = map2; - nowcs_class = class2; - } else { - iwm = 1; - nowcs = map1; - wcs = (AstWcsMap *) map2; - nowcs_class = class1; - } - -/* If it is a PermMap, the Mappings can be swapped so long as: - 1) all links between input and output axes in the PermMap are - bi-directional. This does not preclude the existence of unconnected axes, - which do not have links (bi-directional or otherwise). - 2) The PermMap passesd though both the longitude and latitude axes of - the WcsMap */ - if( !strcmp( nowcs_class, "PermMap" ) ){ - -/* Get the number of input and output coordinates. */ - nin = astGetNin( nowcs ); - nout = astGetNout( nowcs ); - -/* We need to know the axis permutation arrays and constants array for - the PermMap. */ - PermGet( (AstPermMap *) nowcs, &outperm, &inperm, &consts, status ); - if( astOK ) { - -/* Indicate we can swap with the PermMap. */ - ret = 1; - -/* Check each output axis. If any links between axes are found which are - not bi-directional, indicate that we cannot swap with the PermMap. */ - for( i = 0; i < nout; i++ ){ - if( outperm[ i ] >= 0 && outperm[ i ] < nin ) { - if( inperm[ outperm[ i ] ] != i ) { - ret = 0; - break; - } - } - } - -/* Check each input axis. If any links between axes are found which are - not bi-directional, indicate that we cannot swap with the PermMap. */ - for( i = 0; i < nin; i++ ){ - if( inperm[ i ] >= 0 && inperm[ i ] < nout ) { - if( outperm[ inperm[ i ] ] != i ) { - ret = 0; - break; - } - } - } - -/* Check that the longitude and latitude axes both have bi-directional - links in the PermMap, or are both unassigned. */ - if( ret ) { - -/* Get the indices of the longitude and latitude axes in the WcsMap */ - lonax = astGetWcsAxis( wcs, 0 ); - latax = astGetWcsAxis( wcs, 1 ); - -/* If the WcsMap is applied first... */ - if( wcs == (AstWcsMap *) map1 ) { - if( inperm[ lonax] < 0 && inperm[ latax ] < 0 ) { - ret = 1; - } else if( inperm[ lonax ] < 0 || inperm[ lonax ] >= nout || - inperm[ latax ] < 0 || inperm[ latax ] >= nout ) { - ret = 0; - } - -/* If the WcsMap is applied second ... */ - } else { - if( outperm[ lonax ] < 0 && outperm[ latax ] < 0 ) { - ret = 1; - } else if( outperm[ lonax ] < 0 || outperm[ lonax ] >= nin || - outperm[ latax ] < 0 || outperm[ latax ] >= nin ) { - ret = 0; - } - } - } - -/* If we can swap with the PermMap, the swapped Mappings may be - intrinsically simpler than the original mappings. */ - if( ret ) { - -/* If the PermMap precedes the WcsMap, this will be the case if the PermMap - has more outputs than inputs. If the WcsMap precedes the PermMap, this - will be the case if the PermMap has more inputs than outputs. */ - *simpler = ( nowcs == map1 ) ? nout > nin : nin > nout; - } - -/* Free the axis permutation and constants arrays. */ - outperm = (int *) astFree( (void *) outperm ); - inperm = (int *) astFree( (void *) inperm ); - consts = (double *) astFree( (void *) consts ); - } - } - } - -/* Re-instate the original settings of the Invert attributes for the - supplied MatrixMaps. */ - astSetInvert( map1, invert[ 0 ] ); - astSetInvert( map2, invert[ 1 ] ); - -/* If the Mappings can swap, get the equivalent swapped mappings. */ - if( ret ) { - maps[ 0 ] = astClone( map1 ); - maps[ 1 ] = astClone( map2 ); - invert[ 0 ] = inv1; - invert[ 1 ] = inv2; - WcsPerm( maps, invert, iwm, status ); - -/* Return a pointer to the swapped WcsMap. */ - *newwcsmap = astClone( maps[ 1 - iwm ] ); - -/* Free resources */ - maps[ 0 ] = astAnnul( maps[ 0 ] ); - maps[ 1 ] = astAnnul( maps[ 1 ] ); - } - -/* Return the answer. */ - return astOK ? ret : 0; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a WcsMap. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* WcsMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* WcsMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the WcsMap. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstWcsMap *this; /* Pointer to the WcsMap structure */ - int i; /* Axis index */ - int len; /* Length of the attribute name */ - int m; /* Projection parameter index */ - int nc; /* No. of characters read by astSscanf */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the WcsMap structure. */ - this = (AstWcsMap *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* ProjP. */ -/* ------ */ - if ( nc = 0, ( 1 == astSscanf( attrib, "prpjp(%d)%n", &m, &nc ) ) - && ( nc >= len ) ) { - astClearPV( this, astGetWcsAxis( this, 1 ), m ); - -/* PV. */ -/* ------ */ - } else if ( nc = 0, ( 2 == astSscanf( attrib, "pv%d_%d%n", &i, &m, &nc ) ) - && ( nc >= len ) ) { - astClearPV( this, i - 1, m ); - -/* If the name was not recognised, test if it matches any of the - read-only attributes of this class. If it does, then report an - error. */ - } else if ( ( nc = 0, ( 1 == astSscanf( attrib, "wcsaxis(%d)%n", &i, &nc ) ) - && ( nc >= len ) ) || - !strcmp( attrib, "wcstype" ) || - !strcmp( attrib, "natlat" ) || - !strcmp( attrib, "natlon" ) ){ - astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" " - "value for a %s.", status, attrib, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearPV( AstWcsMap *this, int i, int m, int *status ) { -/* -*+ -* Name: -* astClearPV - -* Purpose: -* Clear a PVi_m attribute. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* void astClearPV( AstWcsMap *this, int i, int m ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function clears a specified member of the PV attribute array, by -* resetting its value to AST__BAD. - -* Parameters: -* this -* A pointer to the WcsMap. -* i -* Zero based axis index. -* m -* Zero based parameter index. - -*- -*/ -/* Local Variables; */ - int npar; - int mxpar; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Report an error if the object has been cloned (i.e. has a reference - count that is greater than one). */ - if( astGetRefCount( this ) > 1 ) { - astError( AST__IMMUT, "astClear(%s): Projection parameter values " - "within the supplied %s cannot be cleared because the %s has " - "been cloned (programming error).", status, - astGetClass(this), astGetClass(this), astGetClass(this) ); - -/* Validate the axis index. */ - } else if( i < 0 || i >= astGetNin( this ) ){ - astError( AST__AXIIN, "astClearPV(%s): Axis index (%d) is invalid in " - "attribute PV%d_%d - it should be in the range 1 to %d.", - status, astGetClass( this ), i + 1, i + 1, m, - astGetNin( this ) ); - - } else { - -/* Find the maximum number of parameters allowed for the axis. */ - mxpar = astGetPVMax( this, i ); - -/* Ignore unused parameters. */ - if( m < 0 || m > mxpar ){ - -/* See if the parameter is currently set. Is so, set its value to - AST__BAD. */ - } else if( this->np && this->p ){ - npar = this->np[ i ]; - if( m < npar && this->p[ i ] ) this->p[ i ][ m ] = AST__BAD; - } - -/* Re-initialize the values stored in the "AstPrjPrm" structure. */ - InitPrjPrm( this, status ); - } -} - -static void ClearTPNTan( AstWcsMap *this, int *status ) { -/* -*+ -* Name: -* astClearTPNTan - -* Purpose: -* Clear the TPNTan attribute. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* void ClearTPNTan( AstWcsMap *this, int *status ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function clears the TPNTan attribute, ensuring the projection -* parameters used by WCSLIB are adjusted accordingly. - -* Parameters: -* this -* A pointer to the WcsMap. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Clear the value. */ - this->tpn_tan = -INT_MAX; - -/* Re-initialize the values stored in the "AstPrjPrm" structure. */ - InitPrjPrm( this, status ); -} - -static void CopyPV( AstWcsMap *in, AstWcsMap *out, int *status ) { -/* -* Name: -* CopyPV - -* Purpose: -* Copy projection parameter information from one WcsMap to another. - -* Type: -* Private function. - -* Synopsis: -* void CopyPV( AstWcsMap *in, AstWcsMap *out ) - -* Description: -* This function copies projection parameter information from one -* WcsMap to another. - -* Parameters: -* in -* Pointer to the input WcsMap. -* out -* Pointer to the output WcsMap. - -*/ - - -/* Local Variables: */ - int i; /* Axis index */ - int latax_in; /* Index of input latitude axis */ - int latax_out; /* Index of output latitude axis */ - int lonax_in; /* Index of input longitude axis */ - int lonax_out; /* Index of output longitude axis */ - int nax_out; /* No. of axis in the output WcsMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Nullify the pointers stored in the output WcsMap since these may - currently be pointing at good data. Otherwise, the good data could be - freed by accident if the output object is deleted due to an error - occuring in this function. */ - out->np = NULL; - out->p = NULL; - -/* Do nothing more if either of the input pointers are null (i.e. if there - are no projection parameters. */ - if( in->np && in->p ){ - -/* Store the number of axes in the input and output WcsMaps */ - nax_out = astGetNin( out ); - -/* Allocate memory for the array holding the number of projection parameters - associated with each axis. */ - out->np = (int *) astMalloc( sizeof( int )*nax_out ); - -/* Allocate memory for the array of pointers which identify the arrays - holding the parameter values. */ - out->p = (double **) astMalloc( sizeof( double *)*nax_out ); - -/* Check pointers can be used */ - if( astOK ) { - -/* Initialise the above arrays. */ - for( i = 0; i < nax_out; i++ ) { - (out->np)[ i ] = 0; - (out->p)[ i ] = NULL; - } - -/* Copy the longitude and latitude values from in to out (other axes do - not have projection parameters). */ - lonax_in = astGetWcsAxis( in, 0 ); - latax_in = astGetWcsAxis( in, 1 ); - lonax_out = astGetWcsAxis( out, 0 ); - latax_out = astGetWcsAxis( out, 1 ); - - (out->np)[ lonax_out ] = (in->np)[ lonax_in ]; - (out->p)[ lonax_out ] = (double *) astStore( NULL, - (void *) (in->p)[ lonax_in ], - sizeof(double)*(in->np)[ lonax_in ] ); - - (out->np)[ latax_out ] = (in->np)[ latax_in ]; - (out->p)[ latax_out ] = (double *) astStore( NULL, - (void *) (in->p)[ latax_in ], - sizeof(double)*(in->np)[ latax_in ] ); - } - -/* If an error has occurred, free the output arrays. */ - if( !astOK ) FreePV( out, status ); - - } - -/* Re-initialize the values stored in the "AstPrjPrm" structure. */ - InitPrjPrm( out, status ); - -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two WcsMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* WcsMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two WcsMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a WcsMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the WcsMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstWcsMap *that; - AstWcsMap *this; - int i, j; - int nin; - int nout; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two WcsMap structures. */ - this = (AstWcsMap *) this_object; - that = (AstWcsMap *) that_object; - -/* Check the second object is a WcsMap. We know the first is a - WcsMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAWcsMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - nout = astGetNout( this ); - if( astGetNin( that ) == nin && astGetNout( that ) == nout ) { - -/* If the Invert flags for the two WcsMaps differ, it may still be possible - for them to be equivalent. First compare the WcsMaps if their Invert - flags are the same. In this case all the attributes of the two WcsMaps - must be identical. */ - if( astGetInvert( this ) == astGetInvert( that ) ) { - - if( this->type == that->type && - this->wcsaxis[ 0 ] == that->wcsaxis[ 0 ] && - this->wcsaxis[ 1 ] == that->wcsaxis[ 1 ] ) { - - result = 1; - - if( this->np && that->np ){ - - for( i = 0; i < nout && result; i++ ) { - - if( (this->np)[ i ] != (that->np)[ i ] ) { - result = 0; - - } else if( (this->p)[ i ] && !(this->p)[ i ] ) { - result = 0; - - } else if( !(this->p)[ i ] && (this->p)[ i ] ) { - result = 0; - - } else if( (this->p)[ i ] && (this->p)[ i ] ) { - - for( j = 0; j < (this->np)[ i ]; j++ ) { - if( !astEQUAL( (this->p)[ i ][ j ], - (that->p)[ i ][ j ] ) ) { - result = 0; - break; - } - } - } - } - } - - } else if( this->np || that->np ){ - result = 0; - } - -/* If the Invert flags for the two WcsMaps differ, the attributes of the two - WcsMaps must be inversely related to each other. */ - } else { - -/* In the specific case of a WcsMap, Invert flags must be equal. */ - result = 0; - - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const PrjData *FindPrjData( int type, int *status ){ -/* -*+ -* Name: -* FindPrjData - -* Purpose: -* Get information about a WCSLIB projection given a projection type. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* const PrjData *FindPrjData( int type, int *status ) - -* Class Membership: -* WcsMap member function - -* Description: -* This function returns a pointer to an PrjData structure describing -* the WCSLIB projection with the supplied type. - -* Parameters: -* type -* The projection type. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the "const" PrjData structure describing the projection. - -* Notes: -* - The returned pointer points to an element in a static array and -* should not be freed. -* - This function attempts to execute even if an error has already -* occurred. A description of a "null" projection will be returned if -* this function subsequently fails (for instance if the projection is -* not recognised). -*- -*/ - - const PrjData *data; - data = PrjInfo; - while( data->prj != AST__WCSBAD && data->prj != type ) data++; - return data; -} - -static void FreePV( AstWcsMap *this, int *status ) { -/* -* -* Name: -* FreePV - -* Purpose: -* Free memory used to hold projection parameters - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* FreePV( AstWcsMap *this, int *status ) - -* Class Membership: -* WcsMap private function - -* Description: -* This function frees all the dynamic memory used to store projection -* parameter information in the supplied WcsMap. - -* Parameters: -* this -* A pointer to the WcsMap. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if an error has already occurred. - -* -*/ - int i; /* Axis index */ - - if( this->np ) this->np = (int *) astFree( (void *) this->np ); - if( this->p ){ - for( i = 0; i < astGetNin( this ); i++ ){ - this->p[ i ] = (double *) astFree( (void *) this->p[ i ] ); - } - this->p = (double **) astFree( (void *) this->p ); - } - -/* Re-initialize the values stored in the "AstPrjPrm" structure. */ - InitPrjPrm( this, status ); - - -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* WcsMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied WcsMap, -* in bytes. - -* Parameters: -* this -* Pointer to the WcsMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstWcsMap *this; /* Pointer to WcsMap structure */ - int result; /* Result value to return */ - int i; /* Axis index */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the WcsMap structure. */ - this = (AstWcsMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - - result += astTSizeOf( this->np ); - if( this->p ){ - for( i = 0; i < astGetNin( this ); i++ ){ - result += astTSizeOf( (void *) this->p[ i ] ); - } - result += astTSizeOf( this->p ); - } - - result += astTSizeOf( this->params.p ); - result += astTSizeOf( this->params.p2 ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a WcsMap. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* WcsMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a WcsMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the WcsMap. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the WcsMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the WcsMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstWcsMap *this; /* Pointer to the WcsMap structure */ - const char *result; /* Pointer value to return */ - double dval; /* Floating point attribute value */ - int i; /* Axis index */ - int ival; /* Integer attribute value */ - int len; /* Length of attribute string */ - int m; /* Projection parameter index */ - int nc; /* No. of characters read by astSscanf */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the WcsMap structure. */ - this = (AstWcsMap *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* ProjP. */ -/* ------ */ - if ( nc = 0, ( 1 == astSscanf( attrib, "projp(%d)%n", &m, &nc ) ) - && ( nc >= len ) ) { - dval = astGetPV( this, astGetWcsAxis( this, 1 ), m ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* PV. */ -/* --- */ - } else if ( nc = 0, ( 2 == astSscanf( attrib, "pv%d_%d%n", &i, &m, &nc ) ) - && ( nc >= len ) ) { - dval = astGetPV( this, i - 1, m ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* WcsType */ -/* ======= */ - } else if ( !strcmp( attrib, "wcstype" ) ) { - ival = astGetWcsType( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* PVMax */ -/* ===== */ - } else if ( nc = 0, ( 1 == astSscanf( attrib, "pvmax(%d)%n", &i, &nc ) ) - && ( nc >= len ) ) { - ival = astGetPVMax( this, i - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* NatLat */ -/* ====== */ - } else if ( !strcmp( attrib, "natlat" ) ) { - dval = astGetNatLat( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - -/* NatLon */ -/* ====== */ - } else if ( !strcmp( attrib, "natlon" ) ) { - dval = astGetNatLon( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval ); - result = getattrib_buff; - } - - -/* WcsAxis */ -/* ======= */ - } else if ( nc = 0, ( 1 == astSscanf( attrib, "wcsaxis(%d)%n", &i, &nc ) ) - && ( nc >= len ) ) { - ival = astGetWcsAxis( this, i - 1 ) + 1; - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static double GetNatLat( AstWcsMap *this, int *status ) { -/* -*+ -* Name: -* GetNatLat - -* Purpose: -* Get the value of the NatLat attribute. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* double GetNatLat( AstWcsMap *this, int *status ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns the value of the NatLat attribute. This is -* fixed value for most projection types , defined in the FITS-WCS paper -* II. For instance, all zenithal projections have NatLat = PI/2 (90 -* degrees). For some prjections (e.g. conics), the value is defined -* by a projection parameter. - -* Parameters: -* this -* A pointer to the WcsMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The attribute value, in radians. - -*- -*/ - double ret; /* Returned value */ - -/* The native latitude of the reference point of the projection is - constant for most projection, but for some (the conics) it is - specified by projection one on the latitude axis. */ - ret = FindPrjData( this->type, status )->theta0; - if( ret == AST__BAD ){ - ret = astGetPV( this, astGetWcsAxis( this, 1 ), 1 ); - if( ret != AST__BAD ) ret *= AST__DD2R; - } - -/* Return the result. */ - return ret; -} - -static double GetNatLon( AstWcsMap *this, int *status ) { -/* -*+ -* Name: -* GetNatLon - -* Purpose: -* Get the value of the NatLon attribute. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* double GetNatLon( AstWcsMap *this, int *status ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns the value of the NatLon attribute. This is -* fixed value of zero for all projection types. - -* Parameters: -* this -* A pointer to the WcsMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The attribute value, in radians. - -*- -*/ - return 0.0; -} - -static int GetNP( AstWcsMap *this, int i, int *status ) { -/* -*+ -* Name: -* GetNP - -* Purpose: -* Get the number of projection parameters for a specified axis. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* int GetNP( AstWcsMap *this, int i, int *status ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns the current number of projection parameters -* associated with the speified axis. Some of these may be unset (i.e. -* equal to AST__BAD). The returned number is the size of the array -* holding the projection parameters. - -* Parameters: -* this -* A pointer to the WcsMap. -* i -* Zero based axis index. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of projection parameters for the specified axis. - -*- -*/ - double ret; - -/* Initialise */ - ret = 0; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Validate the axis index, and get the count. */ - if( i >= 0 && this->np && i < astGetNin( this ) ) ret = this->np[ i ]; - - return ret; - -} - -static double GetPV( AstWcsMap *this, int i, int m, int *status ) { -/* -*+ -* Name: -* astGetPV - -* Purpose: -* Get the value of a PVi_m attribute. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* double astGetPV( AstWcsMap *this, int i, int m ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns the current value of a specified member of the -* PV attribute array. A value of AST__BAD is returned if no value has -* been set for the parameter. - -* Parameters: -* this -* A pointer to the WcsMap. -* i -* Zero based axis index. -* m -* Zero based parameter index. - -* Returned Value: -* The value of the requested attribute, of AST__BAD if not set. - -*- -*/ - -/* Local Variables: */ - double ret; - int npar; - int mxpar; - -/* Initialise */ - ret = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Validate the axis index. */ - if( i < 0 || i >= astGetNin( this ) ){ - astError( AST__AXIIN, "astGetPV(%s): Axis index (%d) is invalid in " - "attribute PV%d_%d - it should be in the range 1 to %d.", - status, astGetClass( this ), i + 1, i + 1, m, astGetNin( this ) ); - -/* Find the maximum number of parameters allowed for the axis. */ - } else { - mxpar = astGetPVMax( this, i ); - -/* Validate the parameter index. */ - if( m < 0 || m > mxpar ){ - astError( AST__AXIIN, "astGetPV(%s): Parameter index (%d) is invalid " - "in attribute PV%d_%d for a \"%s\" projection - it should be " - "in the range 0 to %d.", status, astGetClass( this ), m, i + 1, m, - FindPrjData( this->type, status )->ctype, mxpar ); - -/* For latitude parameters use the values in the "params" structure which will - have been defaulted. */ - } else if( i == astGetWcsAxis( this, 1 ) ) { - ret = (this->params).p[ m ]; - -/* For other axes, see if the arrays stored in the WcsMap structure extend as - far as the requested parameter. If so, return the required attribute value. - Otherwise the AST__BAD value initialised above is retained. */ - } else if( this->np && this->p ){ - npar = this->np[ i ]; - if( m < npar && this->p[ i ] ) ret = this->p[ i ][ m ]; - } - -/* FITS-WCS paper II gives defaults for the first 3 longitude axis - parameters. The AST-specific TPN projection does not use this - convention since it needs all projection parameters to specify - correction terms. */ - if( ret == AST__BAD && i == astGetWcsAxis( this, 0 ) && - astGetWcsType( this ) != AST__TPN ) { - -/* Parameter zero has a default of zero. */ - if( m == 0 ) { - ret = 0.0; - -/* Parameter one has a default equal to the native longitude of the - reference point of the projection, in degrees. */ - } else if( m == 1 ) { - ret = astGetNatLon( this )*AST__DR2D; - -/* Parameter two has a default equal to the native latitude of the - reference point of the projection (in degrees). This is constant for - most projection, but for some (the conics) it is specified by - projection one on the latitude axis. */ - } else if( m == 2 ) { - ret = astGetNatLat( this )*AST__DR2D; - } - } - } - - return ret; - -} - -static int GetPVMax( AstWcsMap *this, int i, int *status ) { -/* -*+ -* Name: -* astGetPVMax - -* Purpose: -* Get the maximum projection parameter index for a WcsMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* int astGetPVMax( AstWcsMap *this, int i ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns the largest legal projection parameter index -* for a specified axis of the given WcsMap (i.e. the largest value of -* "m" in the attribute "PVi_m"). - -* Parameters: -* this -* A pointer to the WcsMap. -* i -* Zero based axis index. - -* Returned Value: -* The largest legal projection parameter index, or -1 if no -* projection parameters are allowed on the specified axis. - -*- -*/ - -/* Local Variables: */ - int mxpar; - -/* Initialise */ - mxpar = 0; - -/* Check the global error status. */ - if ( !astOK ) return -1; - -/* Validate the axis index. */ - if( i < 0 || i >= astGetNin( this ) ){ - astError( AST__AXIIN, "astGetPVMax(%s): Axis index (%d) is invalid in " - "attribute PVMax(%d) - it should be in the range 1 to %d.", - status, astGetClass( this ), i + 1, i + 1, astGetNin( this ) ); - -/* Find the maximum number of parameters allowed for the axis. */ - } else if( i == astGetWcsAxis( this, 0 ) ) { - mxpar = astSizeOf( this->params.p2 )/sizeof( double ); - - } else if( i == astGetWcsAxis( this, 1 ) ) { - mxpar = astSizeOf( this->params.p )/sizeof( double ); - - } - -/* The mxpar variable holds the max number of parameters. Return the the - largest legal parameter index (one less than the max number of - parameters). */ - return mxpar - 1; -} - -static void InitPrjPrm( AstWcsMap *this, int *status ) { -/* -* Name: -* InitPrjPrm - -* Purpose: -* Initialise the WcsLib PrjPrm structure, assigning default values for -* missing parameters. - -* Type: -* Private function. - -* Synopsis: -* void InitPrjPrm( AstWcsMap *this, int *status ) - -* Description: -* This function initializes the projection parameter information -* stored within the WcsLib AstPrjPrm structure associated with the -* supplied WcsMap. Default values are assigned to any unspecified -* parameter values. AST__BAD values are assigned if any parameters -* have not been supplied for which there is no default. - -* Parameters: -* this -* The WcsMap. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Local Variables: */ - struct AstPrjPrm *params; /* The AstPrjPrm structure from the WcsMap */ - int i; /* Loop index */ - int latax; /* Index of latitude axis */ - int lonax; /* Index of longitude axis */ - int npar; /* No. of parameters supplied */ - int plen; /* Length of params array */ - int plen2; /* Length of latitude params array */ - int type; /* Projection type */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the AstPrjPrm structure*/ - params = &(this->params); - -/* Tell the routines within the WcsLib "proj.c" module to re-calculate - intermediate values. */ - params->flag = 0; - params->r0 = 0; - -/* If this is a TPN projection, indicate whether or not the - transformation should include the TAN projection or just the - polynomial transformation. */ - if( this->type == AST__TPN ) params->n = astGetTPNTan( this ); - -/* Find the max number of projection parameters associated with each - axis.*/ - plen2 = astSizeOf( params->p2 )/sizeof( double ); - plen = astSizeOf( params->p )/sizeof( double ); - -/* Initially set all parameter to AST__BAD. */ - for( i = 0; i < plen; i++ ) (params->p)[i] = AST__BAD; - for( i = 0; i < plen2; i++ ) (params->p2)[i] = AST__BAD; - -/* If the WcsMap contains any projection parameter values... */ - if( this->np && this->p ){ - -/* Get the index of the latitude axis. Currently, all projection - parameters are associated with the latitude axis (except for - the TPN projection, which is a hang-over from a earlier draft of the - FITS-WCS paper). */ - latax = astGetWcsAxis( this, 1 ); - -/* Find the number of projection parameters in the WcsMap for the - latitude axis. */ - npar = (this->np)[ latax ]; - if( npar > plen ) { - astError( AST__INTER, "InitPrjPrm(WcsMap): Too many projection " - "parameters on the latitude axis (%d > %d) (internal " - "AST programming error).", status, npar, plen ); - } - -/* Copy the parameters to the AstPrjPrm structure. Do not copy more than - can be stored in the AstPrjPrm structure. */ - for( i = 0; i < npar && i < plen; i++ ) { - (params->p)[ i ] = (this->p)[ latax ][ i ]; - } - -/* Do the same for the longitude axis (for the benefit of the TPN projection). */ - lonax = astGetWcsAxis( this, 0 ); - npar = (this->np)[ lonax ]; - - if( npar > plen2 ) { - astError( AST__INTER, "InitPrjPrm(WcsMap): Too many projection " - "parameters on the longitude axis (%d > %d) (internal " - "AST programming error).", status, npar, plen2 ); - } - - for( i = 0; i < npar && i < plen2; i++ ) { - (params->p2)[ i ] = (this->p)[ lonax ][ i ]; - } - - } - -/* Get the projection type. */ - type = astGetWcsType( this ); - -/* First supply default values for any missing projection parameters which - do not default to zero. */ - if( type == AST__SZP ){ - if( (params->p)[ 3 ] == AST__BAD ) (params->p)[ 3 ] = 90.0; - - } else if( type == AST__AIR ){ - if( (params->p)[ 1 ] == AST__BAD ) (params->p)[ 1 ] = 90.0; - - } else if( type == AST__CYP ){ - if( (params->p)[ 1 ] == AST__BAD ) (params->p)[ 1 ] = 1.0; - if( (params->p)[ 2 ] == AST__BAD ) (params->p)[ 2 ] = 1.0; - - } else if( type == AST__CEA ){ - if( (params->p)[ 1 ] == AST__BAD ) (params->p)[ 1 ] = 1.0; - - } else if( type == AST__TPN ){ - if( (params->p)[ 1 ] == AST__BAD ) (params->p)[ 1 ] = 1.0; - if( (params->p2)[ 1 ] == AST__BAD ) (params->p2)[ 1 ] = 1.0; - - } else if( type == AST__HPX ){ - if( (params->p)[ 1 ] == AST__BAD ) (params->p)[ 1 ] = 4.0; - if( (params->p)[ 2 ] == AST__BAD ) (params->p)[ 2 ] = 3.0; - - } - -/* Now use a default value of zero for any remaining unspecified values, - except for un-defaultable projection parameters. */ - for( i = 0; i < plen; i++ ){ - -/* Retain any AST__BAD value for these undefaultable parameters. */ - if( i == 1 && ( type == AST__BON || - type == AST__COP || type == AST__COE || - type == AST__COD || type == AST__COO ) ){ - -/* Use a default of zero for all other parameters. */ - } else { - if( (params->p)[ i ] == AST__BAD ) (params->p)[ i ] = 0.0; - } - } - -/* Do the same for the latitude projection parameters (if any) */ - for( i = 0; i < plen2; i++ ){ - if( i == 1 && ( type == AST__BON || - type == AST__COP || type == AST__COE || - type == AST__COD || type == AST__COO ) ){ - } else { - if( (params->p2)[ i ] == AST__BAD ) (params->p2)[ i ] = 0.0; - } - } -} - -void astInitWcsMapVtab_( AstWcsMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitWcsMapVtab - -* Purpose: -* Initialise a virtual function table for a WcsMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* void astInitWcsMapVtab( AstWcsMapVtab *vtab, const char *name ) - -* Class Membership: -* WcsMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the WcsMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAWcsMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->ClearPV = ClearPV; - vtab->GetNatLat = GetNatLat; - vtab->GetNatLon = GetNatLon; - vtab->GetPV = GetPV; - vtab->GetWcsAxis = GetWcsAxis; - vtab->GetPVMax = GetPVMax; - vtab->GetWcsType = GetWcsType; - vtab->SetPV = SetPV; - vtab->TestPV = TestPV; - vtab->IsZenithal = IsZenithal; - - vtab->ClearFITSProj = ClearFITSProj; - vtab->TestFITSProj = TestFITSProj; - vtab->GetFITSProj = GetFITSProj; - vtab->SetFITSProj = SetFITSProj; - - vtab->ClearTPNTan = ClearTPNTan; - vtab->TestTPNTan = TestTPNTan; - vtab->GetTPNTan = GetTPNTan; - vtab->SetTPNTan = SetTPNTan; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_mapsplit = mapping->MapSplit; - mapping->MapSplit = MapSplit; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - -/* Declare the destructor and copy constructor. */ - astSetDelete( (AstObjectVtab *) vtab, Delete ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - -/* Declare the class dump function. */ - astSetDump( vtab, Dump, "WcsMap", "FITS-WCS sky projection" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int IsZenithal( AstWcsMap *this, int *status ){ -/* -*+ -* Name: -* IsZenithal - -* Purpose: -* Determine if this WcsMap represents a zenithal projection. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* int IsZenithal( AstWcsMap *this, int *status ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns a flag indicating if this WcsMap is a zenithal -* projection. Some projections which are classed as zenithal in the -* Calabretta and Greisen paper are only genuinely zenithal if the -* projection parameters have certain values. These projections are -* not considered to be zenithal unless the projection parameters have -* appropriate values. - -* Parameters: -* this -* The WcsMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value if the WcsMap represents a zenithal projection. - -*- -*/ - -/* Local Variables: */ - double p1; /* PVi_1 */ - double p2; /* PVi_2 */ - double p3; /* PVi_3 */ - int latax; /* Index of latitude axis */ - int ret; /* Returned flag */ - int type; /* Projection type */ - -/* Initialise the returned value. */ - ret = 0; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Get the projection type. */ - type = astGetWcsType( this ); - -/* Get the index of the latitude axis. */ - latax = astGetWcsAxis( this, 1 ); - -/* The following are always zenithal... */ - if( type == AST__TAN || type == AST__STG || type == AST__ARC || - type == AST__ZPN || type == AST__ZEA || type == AST__AIR || - type == AST__TPN ) { - ret = 1; - -/* The following are sometimes zenithal... */ - } else if( type == AST__AZP ) { - p2 = astGetPV( this, latax, 2 ); - if( p2 == AST__BAD || p2 == 0.0 ) ret = 1; - - } else if( type == AST__SIN ) { - p1 = astGetPV( this, latax, 1 ); - p2 = astGetPV( this, latax, 2 ); - if( p1 == AST__BAD ) p1 = 0.0; - if( p2 == AST__BAD ) p2 = 0.0; - if( p1 == 0.0 && p2 == 0.0 ) ret = 1; - - } else if( type == AST__SZP ) { - p3 = astGetPV( this, latax, 2 ); - if( p3 == AST__BAD ) p3 = 90.0; - if( p3 == 90.0 || p3 == -90.0 ) ret = 1; - - } - - return ret; -} - -static int LongRange( const PrjData *prjdata, struct AstPrjPrm *params, - double *high, double *low, int *status ){ -/* -* -* Name: -* LongRange - -* Purpose: -* See if primary range of longitude produced by a WCSLIB mapping is -* [0,360] or [-180,+180]. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* void LongRange( const PrjData *prjdata, struct AstPrjPrm *params, -* double *high, double *low, int *status ) - -* Class Membership: -* WcsMap internal utility function. - -* Description: -* This function uses the WCSLIB library to transform the supplied input -* positions. - -* Parameters: -* prjdata -* A pointer to information about the mapping. -* params -* Pointer to a WCSLIB "AstPrjPrm" structure containing the projection -* parameters, etc. -* high -* A pointer to a location at which is returned the upper bound of -* the primary longitude range. -* low -* A pointer to a location at which is returned the lower bound of -* the primary longitude range. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A flag indicating if the sky->xy transformation is cyclic (i.e. -* [a,0] gets mapped to the same (x,y) position as [a+2.PI,0]). -*/ - - -/* Local Variables: */ - int point; /* Loop counter for points */ - static double xx[ 4 ] = { -1.0E-6, 0.0, 1.0E-6, 0.0 }; - static double yy[ 4 ] = { 0.0, 1.0E-6, 0.0, -1.0E-6 }; - double aa; - double bb; - double xxx[ 2 ]; - double yyy[ 2 ]; - int cyclic; - -/* Initialise the returned values. */ - *high = 180.0; - *low = -180.0; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Project each of the points. If any longitude value is found which is - greater than 180 degrees, return [0,360] as the longitude range. */ - for( point = 0; point < 4; point++ ){ - if( !prjdata->WcsRev( xx[ point ], yy[ point ], params, &aa, &bb ) ){ - if( aa > 180.0 ){ - *high = 360.0; - *low = 0.0; - break; - } - } - } - -/* See if the projection is cyclic. Transform the sky positions [90,bb] and - [450,bb] into cartesian positions and see if they are the same. */ - prjdata->WcsFwd( 90.0, bb, params, xxx, yyy ); - prjdata->WcsFwd( 450.0, bb, params, xxx + 1, yyy + 1 ); - cyclic = ( fabs( xxx[ 0 ] - xxx[ 1 ] ) < 1.0E-10 && - fabs( yyy[ 0 ] - yyy[ 1 ] ) < 1.0E-10 ); - -/* Return. */ - return cyclic; - -} - -static int Map( AstWcsMap *this, int forward, int npoint, double *in0, - double *in1, double *out0, double *out1, int *status ){ -/* -* -* Name: -* Map - -* Purpose: -* Transform a set of points using a function from the WCSLIB library. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* int Map( AstWcsMap *this, int forward, int npoint, double *in0, -* double *in1, double *out0, double *out1 ) - -* Class Membership: -* WcsMap internal utility function. - -* Description: -* This function uses the WCSLIB library to transform the supplied input -* positions. - -* Parameters: -* this -* Pointer to the WcsMap. -* forward -* A non-zero value indicates that the forward projection from -* (long,lat) to (x,y) is required, while a zero value requests the -* reverse transformation. -* npoint -* The number of points to transform (i.e. the size of the -* in0, in1, out0 and out1 arrays). -* in0 -* A pointer to the input coordinate data for the 0th axis (i.e. -* longitude or X depending on "forward"). -* in1 -* A pointer to the input coordinate data for the 1st axis (i.e. -* latitude or Y depending on "forward"). -* out0 -* A pointer to the returned output coordinate data for the 0th axis -* (i.e. X or longitude depending on "forward"). -* out1 -* A pointer to the returned output coordinate data for the 1st axis -* (i.e. Y or latitude depending on "forward"). - -* Returned Value: -* The status value: 0 - Success -* 1 - Unrecognised projection type -* 2 - Invalid projection parameters values. -* 4 - Error existed on entry -* 100 - 399: Longitude axis projection parameter -* (status-100) not supplied. -* 400 - 699: Latitude axis projection parameter -* (status-400) not supplied. - - -* Notes: -* - This function does not report any errors. Reporting of suitable -* error messages is the responsibility of the calling function. -* - The value 4 will be returned if this function is invoked with the -* global error status set. -* -*/ - -/* Local Variables: */ - const PrjData *prjdata; /* Information about the projection */ - double factor; /* Factor that scales input into radians. */ - double latitude; /* Latitude value in degrees */ - double longhi; /* Upper longitude limit in degrees */ - double longitude; /* Longitude value in degrees */ - double longlo; /* Lower longitude limit in degrees */ - double x; /* X Cartesian coordinate in degrees */ - double y; /* Y Cartesian coordinate in degrees */ - int cyclic; /* Is sky->xy transformation cyclic? */ - int i; /* Loop count */ - int plen; /* Length of proj par array */ - int point; /* Loop counter for points */ - int type; /* Projection type */ - int wcs_status; /* Status from WCSLIB functions */ - struct AstPrjPrm *params; /* Pointer to structure holding WCSLIB info */ - -/* Check the global error status. */ - if ( !astOK ) return 4; - -/* Initialise variables to avoid compiler warnings. */ - longlo = AST__BAD; - longhi = AST__BAD; - -/* Store the projection type. */ - type = astGetWcsType( this ); - -/* Get information about the projection. */ - prjdata = FindPrjData( type, status ); - -/* Return if there are no WcsLib mapping functons associated with the - projection. */ - if( ( !prjdata->WcsFwd && forward ) || - ( !prjdata->WcsRev && !forward ) ) return 1; - -/* Check that all necessary projection parameters have been supplied, or - can be defaulted. */ - params = &(this->params); - plen = astSizeOf( params->p )/sizeof( double ); - for( i = 0; i < plen; i++ ) { - if( ( params->p)[ i ] == AST__BAD ) return 400+i; - } - -/* If we are doing a reverse mapping, get the acceptable range of longitude - values. */ - cyclic = forward ? 0 : LongRange( prjdata, params, &longhi, &longlo, - status ); - -/* The WcsMap input and output values are normally in radians, but if - the TPNTan attribute has been reset then they are in degrees. The - WCSLIB projection functions always expect and return degrees. Get - the factor that scales the WcsMap input into radians. */ - factor = astGetTPNTan( this ) ? 1.0 : AST__DD2R; - -/* Loop to apply the projection to each point in turn, checking for - (and propagating) bad values in the process. */ - for ( point = 0; point < npoint; point++ ) { - if ( in0[ point ] == AST__BAD || - in1[ point ] == AST__BAD ){ - out0[ point ] = AST__BAD; - out1[ point ] = AST__BAD; - } else { - -/* First deal with forward projection calls */ - if ( forward ){ - -/* The input coordinates are assumed to be longitude and latitude, in - radians or degrees (as specified by the TPNTan attribute). Convert them - to degrees ensuring that the longitude value is in the range [-180,180] - and the latitude is in the range [-90,90] (as required by the WCSLIB - library). Any point with a latitude outside the range [-90,90] is - converted to the equivalent point on the complementary meridian. */ - latitude = AST__DR2D*palDrange( factor*in1[ point ] ); - if ( latitude > 90.0 ){ - latitude = 180.0 - latitude; - longitude = AST__DR2D*palDrange( AST__DPI + factor*in0[ point ] ); - - } else if ( latitude < -90.0 ){ - latitude = -180.0 - latitude; - longitude = AST__DR2D*palDrange( AST__DPI + factor*in0[ point ] ); - - } else { - longitude = AST__DR2D*palDrange( factor*in0[ point ] ); - } - -/* Call the relevant WCSLIB forward projection function. */ - wcs_status = prjdata->WcsFwd( longitude, latitude, params, &x, &y ); - -/* Store the returned Cartesian coordinates, converting them from degrees - to radians. If the position could not be projected, use the value - AST__BAD. Abort for any other bad status. */ - if( wcs_status == 0 ){ - out0[ point ] = (AST__DD2R/factor)*x; - out1[ point ] = (AST__DD2R/factor)*y; - - } else if( wcs_status == 1 ){ - return 2; - - } else if( wcs_status == 2 ){ - out0[ point ] = AST__BAD; - out1[ point ] = AST__BAD; - - } else { - return wcs_status; - } - -/* Now deal with reverse projection calls */ - } else { - -/* Convert the supplied Cartesian coordinates from radians to degrees. */ - x = (AST__DR2D*factor)*in0[ point ]; - y = (AST__DR2D*factor)*in1[ point ]; - -/* Call the relevant WCSLIB reverse projection function. */ - wcs_status = prjdata->WcsRev( x, y, params, &longitude, &latitude ); - -/* Store the returned longitude and latitude, converting them from degrees - to radians. Many projections (ARC, AIT, ZPN, etc) are not cyclic (i.e. - [long,lat]=[0,0] does not get mapped to the same place as - [long,lat]=[360,0] ). Only accept values in the primary longitude or - latitude ranges. This avoids (x,y) points outside the physical domain - of the mapping being assigned valid (long,lat) values. */ - if( wcs_status == 0 ){ - if( ( cyclic || ( longitude < longhi && - longitude >= longlo ) ) && - fabs( latitude ) <= 90.0 ){ - - out0[ point ] = (AST__DD2R/factor)*longitude; - out1[ point ] = (AST__DD2R/factor)*latitude; - - } else { - out0[ point ] = AST__BAD; - out1[ point ] = AST__BAD; - } - -/* Abort if projection parameters were unusable. */ - } else if( wcs_status == 1 ){ - return 2; - -/* If the position could not be projected, use the value AST__BAD. */ - } else if( wcs_status == 2 ){ - out0[ point ] = AST__BAD; - out1[ point ] = AST__BAD; - -/* Abort if projection parameters were not supplied. */ - } else { - return wcs_status; - } - - } - - } - - } - - return 0; -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a WcsMap. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* WcsMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated WcsMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated WcsMap with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated WcsMap which is to be merged with -* its neighbours. This should be a cloned copy of the WcsMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* WcsMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated WcsMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstMapping *mc[2]; /* Copies of supplied Mappings to swap */ - AstMapping *smc0; /* Simplied Mapping */ - AstMapping *smc1; /* Simplied Mapping */ - AstWcsMap *newwcsmap; /* The WcsMap after swapping */ - const char *nclass; /* Pointer to neighbouring Mapping class */ - const char *class1; /* Pointer to first Mapping class string */ - const char *class2; /* Pointer to second Mapping class string */ - int do1; /* Would a backward swap make a simplification? */ - int do2; /* Would a forward swap make a simplification? */ - int i1; /* Lower index of the two WcsMaps being merged */ - int i2; /* Upper index of the two WcsMaps being merged */ - int i; /* Mapping index */ - int ic[2]; /* Copies of supplied invert flags to swap */ - int merge; /* Can WcsMap merge with a neighbour? */ - int nin; /* Number of coordinates for WcsMap */ - int nstep1; /* No. of Mappings backwards to next mergable Mapping */ - int nstep2; /* No. of Mappings forward to next mergable Mapping */ - int result; /* Result value to return */ - int swaphi; /* Can WcsMap be swapped with higher neighbour? */ - int swaplo; /* Can WcsMap be swapped with lower neighbour? */ - int type; /* Projection type */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - i1 = 0; - i2 = 0; - -/* Get the number of axes for the WcsMap. */ - nin = astGetNin( ( *map_list )[ where ] ); - -/* First of all, see if the WcsMap can be replaced by a simpler Mapping, - without reference to the neighbouring Mappings in the list. */ -/* ======================================================================*/ -/* WcsMaps with map type of AST__WCSBAD are equivalent to a UnitMap. */ - type = astGetWcsType( this ); - if( type == AST__WCSBAD ){ - -/* Annul the WcsMap pointer in the list and replace it with a UnitMap - pointer, and indicate that the forward transformation of the returned - UnitMap should be used. */ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) astUnitMap( nin, "", status ); - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - -/* If the WcsMap itself could not be simplified, see if it can be merged - with the Mappings on either side of it in the list. This can only be - done in series for a WcsMap. */ -/* ===================================================================== */ - } else if( series && *nmap > 1 ) { - -/* Store the classes of the neighbouring Mappings in the list. */ - class1 = ( where > 0 ) ? astGetClass( ( *map_list )[ where - 1 ] ) : NULL; - class2 = ( where < *nmap - 1 ) ? astGetClass( ( *map_list )[ where + 1 ] ) : NULL; - -/* A WcsMap can only combine with its own inverse. Set a flag indicating - that we have not yet found a neighbour with which the WcsMap can be - merged. */ - merge = 0; - -/* First check the lower neighbour (if any). */ - if( where > 0 ) { - i1 = where - 1; - i2 = where; - merge = CanMerge( ( *map_list )[ i1 ], (* invert_list)[ i1 ], - ( *map_list )[ i2 ], (* invert_list)[ i2 ], status ); - } - -/* If the WcsMap can not be merged with its lower neighbour, check its - upper neighbour (if any) in the same way. */ - if( !merge && where < *nmap - 1 ) { - i1 = where; - i2 = where + 1; - merge = CanMerge( ( *map_list )[ i1 ], (* invert_list)[ i1 ], - ( *map_list )[ i2 ], (* invert_list)[ i2 ], status ); - } - -/* If either neighbour has passed these checks, it is the inverse of the - WcsMap being checked. The pair of WcsMaps can be replaced by a single - UnitMap. */ - if( merge ) { - -/* Annul the two WcsMaps. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - (void) astAnnul( ( *map_list )[ i2 ] ); - -/* Create a UnitMap, and store a pointer for it in place of the first - WcsMap. */ - ( *map_list )[ i1 ] = (AstMapping *) astUnitMap( nin, "", status ); - ( *invert_list )[ i1 ] = 0; - -/* Shuffle down the remaining Mappings to fill the hole left by the - second WcsMap. */ - for ( i = i2 + 1; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - (*nmap)--; - result = i1; - -/* If the WcsMap could not merge directly with either of its neighbours, - we consider whether it would be worthwhile to swap the WcsMap with - either of its neighbours. This can only be done for certain PermMaps, - and will usually require both Mappings to be modified (unless they are - commutative). The advantage of swapping the order of the Mappings is that - it may result in the WcsMap being adjacent to a Mapping with which it can - merge directly on the next invocation of this function, thus reducing the - number of Mappings in the list. */ - } else { - -/* Set a flag if we could swap the WcsMap with its higher neighbour. "do2" - is returned if swapping the Mappings would simplify either of the - Mappings. */ - if( where + 1 < *nmap ){ - swaphi = CanSwap( ( *map_list )[ where ], - ( *map_list )[ where + 1 ], - ( *invert_list )[ where ], - ( *invert_list )[ where + 1 ], &do2, - &newwcsmap, status ); - } else { - do2 = 0; - swaphi = 0; - newwcsmap = NULL; - } - -/* If so, step through each of the Mappings which follow the WcsMap, - looking for a Mapping with which the WcsMap could merge directly. Stop - when such a Mapping is found, or if a Mapping is found with which the - WcsMap could definitely not swap. Note the number of Mappings which - separate the WcsMap from the Mapping with which it could merge (if - any). */ - nstep2 = -1; - if( swaphi ){ - for( i2 = where + 1; i2 < *nmap; i2++ ){ - -/* See if we can merge with this Mapping. If so, note the number of steps - between the two Mappings and leave the loop. */ - if( CanMerge( ( *map_list )[ i2 ], ( *invert_list )[ i2 ], - (AstMapping *) newwcsmap, astGetInvert(newwcsmap), status ) ) { - nstep2 = i2 - where - 1; - break; - } - -/* If there is no chance that we can swap with this Mapping, leave the loop - with -1 for the number of steps to indicate that no merging is possible. - WcsMaps can swap only with some PermMaps. */ - nclass = astGetClass( ( *map_list )[ i2 ] ); - if( strcmp( nclass, "PermMap" ) ) { - break; - } - } - } - - if( newwcsmap ) newwcsmap = astAnnul( newwcsmap ); - -/* Do the same working forward from the WcsMap towards the start of the map - list. */ - if( where > 0 ){ - swaplo = CanSwap( ( *map_list )[ where - 1 ], - ( *map_list )[ where ], - ( *invert_list )[ where - 1 ], - ( *invert_list )[ where ], &do1, - &newwcsmap, status ); - } else { - do1 = 0; - swaplo = 0; - newwcsmap = NULL; - } - - nstep1 = -1; - if( swaplo ){ - for( i1 = where - 1; i1 >= 0; i1-- ){ - - if( CanMerge( ( *map_list )[ i1 ], ( *invert_list )[ i1 ], - (AstMapping *) newwcsmap, astGetInvert(newwcsmap), status ) ) { - nstep1 = where - 1 - i1; - break; - } - - nclass = astGetClass( ( *map_list )[ i1 ] ); - if( strcmp( nclass, "PermMap" ) ) { - break; - } - } - } - - if( newwcsmap ) newwcsmap = astAnnul( newwcsmap ); - -/* Choose which neighbour to swap with so that the WcsMap moves towards the - nearest Mapping with which it can merge. */ - if( do1 || ( - nstep1 != -1 && ( nstep2 == -1 || nstep2 > nstep1 ) ) ){ - nclass = class1; - i1 = where - 1; - i2 = where; - } else if( do2 || nstep2 != -1 ){ - nclass = class2; - i1 = where; - i2 = where + 1; - } else { - nclass = NULL; - } - -/* If there is a target Mapping in the list with which the WcsMap could - merge, replace the supplied Mappings with swapped Mappings to bring a - WcsMap closer to the target Mapping. */ - if( nclass ){ - WcsPerm( (*map_list) + i1, (*invert_list) + i1, where - i1, status ); - -/* Store the index of the first modified Mapping. */ - result = i1; - -/* If there is no Mapping available for merging, it may still be - advantageous to swap with a neighbour because the swapped Mapping may - be simpler than the original Mappings. */ - } else if( swaphi || swaplo ) { - -/* Choose a neightbour to swap with. If both are suitable for swapping, - swap with the lower. */ - if( swaplo ){ - nclass = class1; - i1 = where - 1; - i2 = where; - } else { - nclass = class2; - i1 = where; - i2 = where + 1; - } - -/* Take copies of the Mapping and Invert flag arrays so we do not change - the supplied values. */ - mc[ 0 ] = (AstMapping *) astCopy( ( (*map_list) + i1 )[0] ); - mc[ 1 ] = (AstMapping *) astCopy( ( (*map_list) + i1 )[1] ); - ic[ 0 ] = ( (*invert_list) + i1 )[0]; - ic[ 1 ] = ( (*invert_list) + i1 )[1]; - -/* Swap these Mappings. */ - WcsPerm( mc, ic, where - i1, status ); - -/* If neither of the swapped Mappings can be simplified further, then there - is no point in swapping the Mappings, so just annul the map copies. */ - smc0 = astSimplify( mc[0] ); - smc1 = astSimplify( mc[1] ); - - if( astGetClass( smc0 ) == astGetClass( mc[0] ) && - astGetClass( smc1 ) == astGetClass( mc[1] ) ) { - - mc[ 0 ] = (AstMapping *) astAnnul( mc[ 0 ] ); - mc[ 1 ] = (AstMapping *) astAnnul( mc[ 1 ] ); - -/* If one or both of the swapped Mappings could be simplified, then annul - the supplied Mappings and return the swapped mappings, storing the index - of the first modified Mapping. */ - } else { - (void ) astAnnul( ( (*map_list) + i1 )[0] ); - (void ) astAnnul( ( (*map_list) + i1 )[1] ); - - ( (*map_list) + i1 )[0] = mc[ 0 ]; - ( (*map_list) + i1 )[1] = mc[ 1 ]; - - ( (*invert_list) + i1 )[0] = ic[ 0 ]; - ( (*invert_list) + i1 )[1] = ic[ 1 ]; - - result = i1; - - } - -/* Annul the simplied Mappings */ - smc0 = astAnnul( smc0 ); - smc1 = astAnnul( smc1 ); - - } - } - } - -/* Return the result. */ - return result; -} - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* WcsMap. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* WcsMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing WcsMap. This is only possible if the specified inputs -* correspond to some subset of the WcsMap outputs. That is, there -* must exist a subset of the WcsMap outputs for which each output -* depends only on the selected WcsMap inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied WcsMap, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the WcsMap to be split (the WcsMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied WcsMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied WcsMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied WcsMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstWcsMap *newwcs; /* Pointer to returned WcsMap */ - AstWcsMap *this; /* Pointer to WcsMap structure */ - int *result; /* Pointer to returned array */ - int *inperm; /* Input axis permutation array */ - int *outperm; /* Output axis permutation array */ - int i; /* Loop count */ - int iin; /* Mapping input index */ - int ilat; /* Index of latitude axis in new WcsMap */ - int ilatlon; /* Index of last lat or lon axis */ - int ilon; /* Index of longitude axis in new WcsMap */ - int latax; /* Index of latitude axis in supplied WcsMap */ - int lonax; /* Index of longitude axis in supplied WcsMap */ - int mnin; /* No. of Mapping inputs */ - int ok; /* Are input indices OK? */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Invoke the parent astMapSplit method to see if it can do the job. */ - result = (*parent_mapsplit)( this_map, nin, in, map, status ); - -/* If not, we provide a special implementation here. */ - if( !result ) { - -/* Get a pointer to the WcsMap structure. */ - this = (AstWcsMap *) this_map; - -/* Prevent compiler warnings. */ - ilatlon = -1; - -/* Allocate memory for the returned array. */ - result = astMalloc( sizeof( int )*(size_t) nin ); - if( astOK ) { - -/* Get the indices of the longitude and latitude axes in the WcsMap */ - lonax = astGetWcsAxis( this, 0 ); - latax = astGetWcsAxis( this, 1 ); - -/* See if the selected axes include the longitude and/or latitude axis. - At the same time check the axis indices are ok, and set up the output - axis array. */ - ilat = -1; - ilon = -1; - mnin = astGetNin( this ); - ok = 1; - for( i = 0; i < nin; i++ ) { - iin = in[ i ]; - if( iin < 0 || iin >= mnin ) { - ok = 0; - break; - } else if( iin == lonax ) { - ilon = i; - ilatlon = i; - } else if( iin == latax ) { - ilat = i; - ilatlon = i; - } - result[ i ] = iin; - } - -/* If any of the input indices were invalid, free the returned array. */ - if( !ok ) { - result = astFree( result ); - -/* If both longitude and latitude axes are selected, then the returned Mapping - is a WcsMap. Create one based on the supplied WcsMap. */ - } else if( ilat != -1 && ilon != -1 ) { - newwcs = astWcsMap( nin, astGetWcsType( this ), ilon + 1, ilat + 1, - "", status ); - CopyPV( this, newwcs, status ); - astSetInvert( newwcs, astGetInvert( this ) ); - *map = (AstMapping *) newwcs; - -/* If neither the longitude nor the latitude axis has been selected, then - the returned Mapping is a UnitMap. */ - } else if( ilat == -1 && ilon == -1 ) { - *map = (AstMapping *) astUnitMap( nin, "", status ); - -/* If only one of the latitude and longitude axes was selected we remove - it from the returned Mapping (a PermMap) and list of outputs */ - } else if( nin > 1 ) { - - for( i = ilatlon; i < nin - 1; i++ ) { - result[ i ] = result[ i + 1 ]; - } - result[ i ] = -1; - - inperm = astMalloc( sizeof( int )*(size_t) nin ); - outperm = astMalloc( sizeof( int )*(size_t) ( nin - 1 ) ); - if( outperm ) { - for( i = 0; i < ilatlon; i++ ) { - inperm[ i ] = i; - outperm[ i ] = i; - } - inperm[ ilatlon ] = INT_MAX; - for( i = ilatlon + 1; i < nin; i++ ) { - inperm[ i ] = i - 1; - outperm[ i - 1 ] = i; - } - - *map = (AstMapping *) astPermMap( nin, inperm, nin - 1, outperm, NULL, " ", status ); - - } - inperm = astFree( inperm ); - outperm = astFree( outperm ); - - } else { - result = astFree( result ); - } - } - } - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static void PermGet( AstPermMap *map, int **outperm, int **inperm, - double **consts, int *status ){ -/* -* Name: -* PermGet - -* Purpose: -* Get the axis permutation and constants array for a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* void PermGet( AstPermMap *map, int **outperm, int **inperm, -* double **const, int *status ) - -* Class Membership: -* WcsMap member function - -* Description: -* This function returns axis permutation and constants arrays which can -* be used to create a PermMap which is equivalent to the supplied PermMap. - -* Parameters: -* map -* The PermMap. -* outperm -* An address at which to return a popinter to an array of ints -* holding the output axis permutation array. The array should be -* released using astFree when no longer needed. -* inperm -* An address at which to return a popinter to an array of ints -* holding the input axis permutation array. The array should be -* released using astFree when no longer needed. -* consts -* An address at which to return a popinter to an array of doubles -* holding the constants array. The array should be released using -* astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - NULL pointers are returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* PointSet holding input positions for PermMap */ - AstPointSet *pset2; /* PointSet holding output positions for PermMap */ - double **ptr1; /* Pointer to pset1 data */ - double **ptr2; /* Pointer to pset2 data */ - double *cnst; /* Pointer to constants array */ - double cn; /* Potential new constant value */ - double ip; /* Potential output axis index */ - double op; /* Potential input axis index */ - int *inprm; /* Pointer to input axis permutation array */ - int *outprm; /* Pointer to output axis permutation array */ - int i; /* Axis count */ - int nc; /* Number of constants stored so far */ - int nin; /* No. of input coordinates for the PermMap */ - int nout; /* No. of output coordinates for the PermMap */ - -/* Initialise. */ - if( outperm ) *outperm = NULL; - if( inperm ) *inperm = NULL; - if( consts ) *consts = NULL; - -/* Check the global error status and the supplied pointers. */ - if ( !astOK || !outperm || !inperm || !consts ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - nc = 0; - -/* Get the number of input and output axes for the supplied PermMap. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - -/* Allocate the memory for the returned arrays. */ - outprm = (int *) astMalloc( sizeof( int )* (size_t) nout ); - inprm = (int *) astMalloc( sizeof( int )* (size_t) nin ); - cnst = (double *) astMalloc( sizeof( double )* (size_t) ( nout + nin ) ); - -/* Returned the pointers to these arrays.*/ - *outperm = outprm; - *inperm = inprm; - *consts = cnst; - -/* Create two PointSets, each holding two points, which can be used for - input and output positions with the PermMap. */ - pset1 = astPointSet( 2, nin, "", status ); - pset2 = astPointSet( 2, nout, "", status ); - -/* Set up the two input positions to be [0,1,2...] and [-1,-1,-1,...]. The - first position is used to enumerate the axes, and the second is used to - check for constant axis values. */ - ptr1 = astGetPoints( pset1 ); - if( astOK ){ - for( i = 0; i < nin; i++ ){ - ptr1[ i ][ 0 ] = ( double ) i; - ptr1[ i ][ 1 ] = -1.0; - } - } - -/* Use the PermMap to transform these positions in the forward direction. */ - (void) astTransform( map, pset1, 1, pset2 ); - -/* Look at the mapped positions to determine the output axis permutation - array. */ - ptr2 = astGetPoints( pset2 ); - if( astOK ){ - -/* No constant axis valeus found yet. */ - nc = 0; - -/* Do each output axis. */ - for( i = 0; i < nout; i++ ){ - -/* If the output axis value is copied from an input axis value, the index - of the appropriate input axis will be in the mapped first position. */ - op = ptr2[ i ][ 0 ]; - -/* If the output axis value is assigned a constant value, the result of - mapping the two different input axis values will be the same. */ - cn = ptr2[ i ][ 1 ]; - if( op == cn ) { - -/* We have found another constant. Store it in the constants array, and - store the index of the constant in the output axis permutation array. */ - cnst[ nc ] = cn; - outprm[ i ] = -( nc + 1 ); - nc++; - -/* If the output axis values are different, then the output axis value - must be copied from the input axis value. */ - } else { - outprm[ i ] = (int) ( op + 0.5 ); - } - } - } - -/* Now do the same thing to determine the input permutation array. */ - if( astOK ){ - for( i = 0; i < nout; i++ ){ - ptr2[ i ][ 0 ] = ( double ) i; - ptr2[ i ][ 1 ] = -1.0; - } - } - - (void) astTransform( map, pset2, 0, pset1 ); - - if( astOK ){ - - for( i = 0; i < nin; i++ ){ - - ip = ptr1[ i ][ 0 ]; - cn = ptr1[ i ][ 1 ]; - if( ip == cn ) { - - cnst[ nc ] = cn; - inprm[ i ] = -( nc + 1 ); - nc++; - - } else { - inprm[ i ] = (int) ( ip + 0.5 ); - } - } - } - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* If an error has occurred, attempt to free the returned arrays. */ - if( !astOK ) { - *outperm = (int *) astFree( (void *) *outperm ); - *inperm = (int *) astFree( (void *) *inperm ); - *consts = (double *) astFree( (void *) *consts ); - } - -/* Return. */ - return; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a WcsMap. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* WcsMap member function (over-rides the astSetAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function assigns an attribute value for a WcsMap, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the WcsMap. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. -*/ - -/* Local Variables: */ - AstWcsMap *this; /* Pointer to the WcsMap structure */ - double dval; /* Attribute value */ - int len; /* Length of setting string */ - int nc; /* Number of characters read by astSscanf */ - int i; /* Axis index */ - int m; /* Projection parameter number */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the WcsMap structure. */ - this = (AstWcsMap *) this_object; - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* ProjP(i). */ -/* --------- */ - if ( nc = 0, ( 2 == astSscanf( setting, "projp(%d)= %lg %n", &m, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetPV( this, astGetWcsAxis( this, 1 ), m, dval ); - -/* PV. */ -/* --- */ - } else if ( nc = 0, ( 3 == astSscanf( setting, "pv%d_%d= %lg %n", &i, &m, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetPV( this, i - 1, m, dval ); - -/* Define macros to see if the setting string matches any of the - read-only attributes of this class. */ -#define MATCH(attrib) \ - ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \ - ( nc >= len ) ) - -#define MATCH2(attrib) \ - ( nc = 0, ( 1 == astSscanf( setting, attrib "(%d)=%*[^\n]%n", &i, &nc ) ) && \ - ( nc >= len ) ) - -/* If the attribute was not recognised, use this macro to report an error - if a read-only attribute has been specified. */ - } else if ( MATCH( "wcstype" ) || - MATCH( "natlat" ) || - MATCH( "natlon" ) || - MATCH2( "wcsaxis" ) ) { - astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status, - setting, astGetClass( this ) ); - astError( AST__NOWRT, "This is a read-only attribute." , status); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -#undef MATCH2 -} - -static void SetPV( AstWcsMap *this, int i, int m, double val, int *status ) { -/* -*+ -* Name: -* astSetPV - -* Purpose: -* Set the value of a PVi_m attribute. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* void astSetPV( AstWcsMap *this, int i, int m, double val ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function stores a value for the specified member of the PV -* attribute array. - -* Parameters: -* this -* A pointer to the WcsMap. -* i -* Zero based axis index. -* m -* Zero based parameter index. - -*- -*/ -/* Local Variables: */ - int naxis; /* No. of axes in WcsMap */ - int mm; /* Loop count */ - int mxpar; /* Max number of parameters allowed for the axis */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Find the number of axes in the WcsMap. */ - naxis = astGetNin( this ); - -/* Report an error if the object has been cloned (i.e. has a reference - count that is greater than one). */ - if( astGetRefCount( this ) > 1 ) { - astError( AST__IMMUT, "astSet(%s): Projection parameter values " - "within the supplied %s cannot be changed because the %s has " - "been cloned (programming error).", status, - astGetClass(this), astGetClass(this), astGetClass(this) ); - -/* Validate the axis index. */ - } else if( i < 0 || i >= naxis ){ - astError( AST__AXIIN, "astSetPV(%s): Axis index (%d) is invalid in " - "attribute PV%d_%d - it should be in the range 1 to %d.", - status, astGetClass( this ), i + 1, i + 1, m, naxis ); - -/* Validate the parameter index. */ - } else { - mxpar = astGetPVMax( this, i ); - if( m < 0 || m > mxpar ){ - astError( AST__AXIIN, "astSetPV(%s): Parameter index (%d) is invalid " - "in attribute PV%d_%d for a \"%s\" projection - it should be " - "in the range 0 to %d.", status, astGetClass( this ), m, i + 1, m, - FindPrjData( this->type, status )->ctype, mxpar ); - -/* If the dynamic arrays used to hold the parameters have not yet been - created, create them now, and store pointers to them in the WcsMap - structure. */ - } else { - if( !this->np || !this->p ) { - this->np = (int *) astMalloc( sizeof(int)*naxis ); - this->p = (double **) astMalloc( sizeof(double *)*naxis ); - if( astOK ) { - for( mm = 0; mm < naxis; mm++ ) { - this->np[ mm ] = 0; - this->p[ mm ] = NULL; - } - } - -/* Release the dynamic arrays if an error has occurred. */ - if( !astOK ) FreePV( this, status ); - - } - } - -/* Check we can use the arrays. */ - if( astOK ) { - -/* Ensure the dynamic array used to hold parameter values for the - specified axis is big enough to hold the specified parameter. */ - this->p[ i ] = (double *) astGrow( (void *) this->p[ i ], - m + 1, sizeof(double) ); - -/* Check we can use this array. */ - if( astOK ) { - -/* Store the supplied value in the relevant element of this array. */ - this->p[ i ][ m ] = val; - -/* If the array was extended to hold this parameter... */ - if( this->np[ i ] <= m ) { - -/* Fill any other new elements in this array with AST__BAD */ - for( mm = this->np[ i ]; mm < m; mm++ ) this->p[ i ][ mm ] = AST__BAD; - -/* Remember the new array size. */ - this->np[ i ] = m + 1; - } - } - } - } - -/* Re-initialize the values stored in the "AstPrjPrm" structure. */ - InitPrjPrm( this, status ); -} - -static void SetTPNTan( AstWcsMap *this, int val, int *status ) { -/* -*+ -* Name: -* astSetTPNTan - -* Purpose: -* Set the value of a TPNTan attribute. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* void astSetTPNTan( AstWcsMap *this, int val ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function stores a value for the TPNTan attribute and updates -* the projection parameters used by WCSLIB accordingly. - -* Parameters: -* this -* A pointer to the WcsMap. -* val -* New attribute value. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the new value. */ - this->tpn_tan = ( val != 0 ); - -/* Re-initialize the values stored in the "AstPrjPrm" structure. */ - InitPrjPrm( this, status ); -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a WcsMap. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* WcsMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a WcsMap's attributes. - -* Parameters: -* this -* Pointer to the WcsMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstWcsMap *this; /* Pointer to the WcsMap structure */ - int i; /* Axis index */ - int m; /* Projection parameter index */ - int len; /* Length os supplied string */ - int nc; /* No. of characters read by astSscanf */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the WcsMap structure. */ - this = (AstWcsMap *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - - -/* ProjP(i). */ -/* --------- */ - if ( nc = 0, ( 1 == astSscanf( attrib, "projp(%d)%n", &m, &nc ) ) - && ( nc >= len ) ) { - result = astTestPV( this, astGetWcsAxis( this, 1 ), m ); - -/* PV. */ -/* --- */ - } else if ( nc = 0, ( 2 == astSscanf( attrib, "pv%d_%d%n", &i, &m, &nc ) ) - && ( nc >= len ) ) { - result = astTestPV( this, i - 1, m ); - -/* If the name is not recognised, test if it matches any of the - read-only attributes of this class. If it does, then return - zero. */ - } else if ( !strcmp( attrib, "wcstype" ) || - !strcmp( attrib, "natlat" ) || - !strcmp( attrib, "natlon" ) || - ( nc = 0, ( 1 == astSscanf( attrib, "wcsaxis(%d)%n", &i, &nc ) ) - && ( nc >= len ) ) ) { - result = 0; - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static int TestPV( AstWcsMap *this, int i, int m, int *status ) { -/* -*+ -* Name: -* astTestPV - -* Purpose: -* Test a PVi_m attribute. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* int astTestPV( AstWcsMap *this, int i, int m ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns 1 if a specified member of the PV attribute -* array is currently set, and 0 otherwise. - -* Parameters: -* this -* A pointer to the WcsMap. -* i -* Zero based axis index. -* m -* Zero based parameter index. - -* Returned Value: -* 1 if the attribute is set, 0 otherwise. - -*- -*/ -/* Local Variables: */ - int ret; - int npar; - int mxpar; - -/* Initialise */ - ret = 0; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Validate the axis index. */ - if( i < 0 || i >= astGetNin( this ) ){ - astError( AST__AXIIN, "astTestPV(%s): Axis index (%d) is invalid in " - "attribute PV%d_%d - it should be in the range 1 to %d.", - status, astGetClass( this ), i + 1, i + 1, m, astGetNin( this ) ); - -/* Find the maximum number of parameters allowed for the axis. */ - } else { - mxpar = astGetPVMax( this, i ); - -/* Ignore unused parameters. */ - if( m < 0 || m > mxpar ){ - -/* See if the parameter is currently set. */ - } else if( this->np && this->p ){ - npar = this->np[ i ]; - if( m < npar && this->p[ i ] ){ - ret = ( this->p[ i ][ m ] != AST__BAD ); - } - } - } - - return ret; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -*+ -* Name: -* Transform - -* Purpose: -* Apply a WcsMap to a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* WcsMap member function (over-rides the astTransform method inherited -* from the Mapping class). - -* Description: -* This function takes a WcsMap and a set of points encapsulated in a -* PointSet and transforms the points using the requested projection. - -* Parameters: -* this -* Pointer to the WcsMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - Assuming the WcsMap has not been inverted, the forward mapping -* transforms spherical (longitude,latitude) pairs into Cartesian (x,y) -* pairs. Longitude and latitude values are given and returned in radians, -* and no restrictions are imposed on their ranges. X and Y values are -* also given and returned in radians, with no restrictions imposed on -* their ranges. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the WcsMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*- -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstWcsMap *map; /* Pointer to WcsMap to be applied */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - int i; /* Axis count */ - int latax; /* Latitude axis index */ - int lonax; /* Longitude axis index */ - int npoint; /* Number of points */ - int status_value; /* Status from Map function */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the WcsMap. */ - map = (AstWcsMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points from the input PointSet and obtain pointers - for accessing the input and output coordinate values. */ - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* If a genuine FITS-WCS projection is being performed... */ - if( astGetWcsType( map ) != AST__WCSBAD ){ - -/* Determine whether to apply the forward or inverse mapping, according to the - direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Do the coordinate transformation. */ - lonax = astGetWcsAxis( map, 0 ); - latax = astGetWcsAxis( map, 1 ); - status_value = Map( map, forward, npoint, ptr_in[ lonax ], ptr_in[ latax ], - ptr_out[ lonax ], ptr_out[ latax ], status ); - -/* Report an error if the projection type was unrecognised. */ - if ( status_value == 1 ) { - astError( AST__WCSTY, "astTransform(%s): The %s specifies an " - "illegal projection type ('%s').", status, astClass( this ), - astClass( this ), FindPrjData( map->type, status )->desc ); - -/* Report an error if the projection parameters were invalid. */ - } else if ( status_value == 2 ) { - astError( AST__WCSPA, "astTransform(%s): The %s projection " - "parameter values in this %s are unusable.", status, - astClass( this ), FindPrjData( map->type, status )->desc, - astClass( this ) ); - -/* Report an error if required projection parameters were not supplied. */ - } else if ( status_value >= 400 ) { - astError( AST__WCSPA, "astTransform(%s): Required projection " - "parameter PV%d_%d was not supplied for a %s " - "projection.", status, astClass( this ), latax+1, status_value - 400, - FindPrjData( map->type, status )->desc ); - - } else if ( status_value >= 100 ) { - astError( AST__WCSPA, "astTransform(%s): Required projection " - "parameter PV%d_%d was not supplied for a %s " - "projection.", status, astClass( this ), lonax+1, status_value - 100, - FindPrjData( map->type, status )->desc ); - } - -/* Copy the remaining axes (i.e. all axes except the longitude and latitude - axes) from the input to the output. */ - for( i = 0; i < astGetNcoord( in ); i++ ){ - if( ( i != lonax && i != latax ) ){ - (void) memcpy( ptr_out[ i ], ptr_in[ i ], sizeof( double )* - (size_t) npoint ); - } - - } - -/* If there is no FITS-WCS projection, just copy all the axes from input to - output. */ - } else { - for( i = 0; i < astGetNcoord( in ); i++ ){ - (void) memcpy( ptr_out[ i ], ptr_in[ i ], sizeof( double )* - (size_t) npoint ); - } - } - -/* If an error has occurred, attempt to delete the results PointSet. */ - if ( !astOK ) result = astDelete( result ); - -/* Return a pointer to the output PointSet. */ - return result; - -} - -int astWcsPrjType_( const char *ctype, int *status ){ -/* -*+ -* Name: -* astWcsPrjType - -* Purpose: -* Get the integer identifier for a WCSLIB projection given by a FITS -* CTYPE keyword value. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* int astWcsPrjType( const char *ctype ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns the integer identifier for the WCSLIB projection -* specified by the supplied FITS CTYPE keyword value. The returned -* value can be passed to astWcsMap to create a WcsMap which implements -* the corresponding projection. - -* Parameters: -* ctype -* A pointer to the last 4 characters of a FITS CTYPE1 (etc) keyword. - -* Returned Value: -* The integer identifier associated with the projection. - -* Notes: -* - A value of AST__WCSBAD is returned if the projection type is -* unknown, but no error is reported. -*- -*/ - - PrjData *data; - char buffer[81]; - const char *a; - char *b; - -/* Remove leading and trailing blanks from the supplied string. */ - a = ctype; - b = buffer; - while( *a && (b - buffer) < 80 ){ - if( !isspace( (int) *a ) ) { - *(b++) = *a; - } - a++; - } - *b = 0; - -/* Search for the projection in the list of available projectons. */ - data = PrjInfo; - while( data->prj != AST__WCSBAD && strcmp( data->ctype, buffer ) ) data ++; - - return data->prj; -} - -const char *astWcsPrjName_( int type, int *status ){ -/* -*+ -* Name: -* astWcsPrjName - -* Purpose: -* Get the name of a projection given its integer identifier. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* const char *astWcsPrjName( int type ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns a string holding 4 characters which can be -* used as the last 4 characters of a FITS CTYPE keyword value -* describing the WCSLIB projection specified by the supplied type. - -* Parameters: -* type -* The projection type. - -* Returned Value: -* A pointer to a null-terminated const character string holding the -* last 4 CTYPE characters describing the projection. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*- -*/ - - PrjData *data; - data = PrjInfo; - while( data->prj != AST__WCSBAD && data->prj != type ) data ++; - return data->ctype; -} - -const char *astWcsPrjDesc_( int type, int *status ){ -/* -*+ -* Name: -* astWcsPrjDesc - -* Purpose: -* Get a textual description of a projection given its integer -* identifier. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* const char *astWcsPrjDesc( int type ) - -* Class Membership: -* WcsMap protected function - -* Description: -* This function returns a pointer to a string string holding a -* textual description of the specified projection type. - -* Parameters: -* type -* The projection type. - -* Returned Value: -* A pointer to a null-terminated const character string holding the -* projection description. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*- -*/ - - PrjData *data; - data = PrjInfo; - while( data->prj != AST__WCSBAD && data->prj != type ) data ++; - return data->desc; -} - -static void WcsPerm( AstMapping **maps, int *inverts, int iwm, int *status ){ -/* -* Name: -* WcsPerm - -* Purpose: -* Swap a WcsMap and a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* void WcsPerm( AstMapping **maps, int *inverts, int iwm, int *status ) - -* Class Membership: -* WcsMap member function - -* Description: -* A list of two Mappings is supplied containing a WcsMap and a -* PermMap. These Mappings are annulled, and replaced with -* another pair of Mappings consisting of a WcsMap and a PermMap -* in the opposite order. These Mappings are chosen so that their -* combined effect is the same as the original pair of Mappings. - -* Parameters: -* maps -* A pointer to an array of two Mapping pointers. -* inverts -* A pointer to an array of two invert flags. -* iwm -* The index within "maps" of the WcsMap. -* status -* Pointer to the inherited status variable. - -* Notes: -* - All links between input and output axes in the PermMap must -* be bi-directional, but there can be unconnected axes, and there -* need not be the same number of input and output axes. Both -* longitude and latitude axes must be passed by the PermMap. - -*/ - -/* Local Variables: */ - AstPermMap *pm; /* Pointer to the supplied PermMap */ - AstPermMap *newpm; /* Pointer to the returned PermMap */ - AstMapping *newwm; /* Pointer to the returned WcsMap */ - AstWcsMap *wm; /* Pointer to the supplied WcsMap */ - double *consts; /* Pointer to constants array */ - int *inperm; /* Pointer to input axis permutation array */ - int *outperm; /* Pointer to output axis permutation array */ - int latax; /* Index of latitude axis */ - int lonax; /* Index of longitude axis */ - int npin; /* No. of input axes in supplied PermMap */ - int npout; /* No. of output axes in supplied PermMap */ - int old_pinv; /* Invert value for the supplied PermMap */ - int old_winv; /* Invert value for the supplied WcsMap */ - int type; /* Projection type */ - int done; /* Have Mappings been swapped? */ - int i; /* AXis index */ - double *p; /* Pointer to input position */ - double *q; /* Pointer to output position */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - newpm = NULL; - newwm = NULL; - -/* Store pointers to the supplied WcsMap and the PermMap. */ - wm = (AstWcsMap *) maps[ iwm ]; - pm = (AstPermMap *) maps[ 1 - iwm ]; - -/* Temporarily set the Invert attribute of the supplied PermMap to the - supplied values. */ - old_pinv = astGetInvert( pm ); - astSetInvert( pm, inverts[ 1 - iwm ] ); - old_winv = astGetInvert( wm ); - astSetInvert( wm, inverts[ iwm ] ); - -/* Get the projection type of the supplied WcsMap and the indices of the - longitude and latitude axes. */ - type = astGetWcsType( wm ); - lonax = astGetWcsAxis( wm, 0 ); - latax = astGetWcsAxis( wm, 1 ); - -/* Get the axis permutation and constants arrays representing the - PermMap. Note, no constants are used more than once in the returned - arrays (i.e. duplicate constants are returned in "consts" if more than - one axis uses a given constant). */ - PermGet( pm, &outperm, &inperm, &consts, status ); - - if( astOK ) { - -/* Get the number of input and output axes in the PermMap. */ - npin = astGetNin( pm ); - npout = astGetNout( pm ); - -/* If the lon and lat axes of the WcsMap are unassigned, we return a - UnitMap instead of a WcsMap. - ================================================================ */ - done = 0; - -/* If the PermMap comes after the WcsMap... */ - if( iwm == 0 ) { - if( inperm[ lonax ] < 0 && inperm[ latax ] < 0 ) { - done = 1; - -/* Transform the constant values, using AST__BAD for other axes. */ - p = (double *) astMalloc( sizeof( double )*(size_t) npin ); - q = (double *) astMalloc( sizeof( double )*(size_t) npin ); - if( astOK ) { - for( i = 0; i < npin; i++ ) { - if( inperm[ i ] < 0 ) { - p[ i ] = consts[ -inperm[ i ] - 1 ]; - } else { - p[ i ] = AST__BAD; - } - } - -/* Transform this position using the inverse WcsMap. */ - astTranN( wm, 1, npin, 1, p, 0, npin, 1, q ); - -/* The new PermMap has the same axis permutations as the original, but it - has different constants. */ - for( i = 0; i < npin; i++ ) { - if( inperm[ i ] < 0 ) { - consts[ -inperm[ i ] - 1 ] = q[ i ]; - } - } - - newpm = astPermMap( npin, inperm, npout, outperm, consts, "", status ); - -/* Use a UnitMap instead of the WcsMap. */ - newwm = (AstMapping *) astUnitMap( npout, "", status ); - - } - -/* Free memory */ - p = astFree( p ); - q = astFree( q ); - - } - -/* If the WcsMap comes after the PermMap... */ - } else { - if( outperm[ lonax ] < 0 && outperm[ latax ] < 0 ) { - done = 1; - -/* Transform the constant values, using AST__BAD for other axes. */ - p = (double *) astMalloc( sizeof( double )*(size_t) npout ); - q = (double *) astMalloc( sizeof( double )*(size_t) npout ); - if( astOK ) { - for( i = 0; i < npout; i++ ) { - if( outperm[ i ] < 0 ) { - p[ i ] = consts[ -outperm[ i ] - 1 ]; - } else { - p[ i ] = AST__BAD; - } - } - -/* Transform this position using the forward WcsMap. */ - astTranN( wm, 1, npout, 1, p, 1, npout, 1, q ); - -/* The new PermMap has the same axis permutations as the original, but it - has different constants. */ - for( i = 0; i < npout; i++ ) { - if( outperm[ i ] < 0 ) { - consts[ -outperm[ i ] - 1 ] = q[ i ]; - } - } - - newpm = astPermMap( npin, inperm, npout, outperm, consts, "", status ); - -/* Use a UnitMap instead ofhte WcsMap. */ - newwm = (AstMapping *) astUnitMap( npin, "", status ); - - } - -/* Free memory */ - p = astFree( p ); - q = astFree( q ); - - } - } - -/* If the lon and lat axes of the WcsMap are both assigned, we return a - WcsMap. - ================================================================ */ - if( !done ) { - -/* Create the new WcsMap with permuted longitude and latitude axes. Note, - the private interface to astWcsMap uses 1-based axis indices. */ - if( iwm == 0 ) { - newwm = (AstMapping *) astWcsMap( npout, type, inperm[ lonax ] + 1, - inperm[ latax ] + 1, "", status ); - } else { - newwm = (AstMapping *) astWcsMap( npin, type, outperm[ lonax ] + 1, - outperm[ latax ] + 1, "", status ); - } - -/* Copy any projection parameters which have been set. */ - CopyPV( wm, (AstWcsMap *) newwm, status ); - -/* Set the invert flag. */ - astSetInvert( newwm, inverts[ iwm ] ); - -/* The returned PermMap is a clone of the supplied PermMap */ - newpm = astClone( pm ); - } - -/* Free the axis permutation and constants arrays. */ - outperm = (int *) astFree( (void *) outperm ); - inperm = (int *) astFree( (void *) inperm ); - consts = (double *) astFree( (void *) consts ); - } - -/* Re-instate the original value of the Invert attributes. */ - astSetInvert( pm, old_pinv ); - astSetInvert( wm, old_winv ); - -/* Annul the supplied pointers */ - pm = astAnnul( pm ); - wm = astAnnul( wm ); - -/* Store the returned Mappings. */ - maps[ iwm ] = (AstMapping *) newpm; - inverts[ iwm ] = astGetInvert( newpm ); - maps[ 1 - iwm ] = newwm; - inverts[ 1 - iwm ] = astGetInvert( newwm ); - -/* Return. */ - return; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - - -/* -*att+ -* Name: -* FITSProj - -* Purpose: -* Is this WcsMap used as a FITS-WCS projection? - -* Type: -* Protected attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls how a WcsMap is used when creating a set -* of FITS headers. If the WcsMap is contained within a FrameSet -* that is to be converted into a set of FITS headers using the -c astWrite funtion, -f AST_WRITE routine, -* the WcsMap will be used to define the projection code appended to -* the FITS "CTYPEi" keywords if, and only if, the FITSProj attribute -* is set non-zero in the WcsMap. In order for the conversion to be -* successful, the compound Mapping connecting the base and current -* Frames in the FrameSet must contained one (and only one) WcsMap -* that has a non-zero value for its FITSProj attribute. -* -* The default value is one. - -* Applicability: -* WcsMap -* All Frames have this attribute. -*att- -*/ -astMAKE_CLEAR(WcsMap,FITSProj,fits_proj,-INT_MAX) -astMAKE_GET(WcsMap,FITSProj,int,1,( ( this->fits_proj != -INT_MAX ) ? - this->fits_proj : 1 )) -astMAKE_SET(WcsMap,FITSProj,int,fits_proj,( value != 0 )) -astMAKE_TEST(WcsMap,FITSProj,( this->fits_proj != -INT_MAX )) - -/* -*att+ -* Name: -* TPNTan - -* Purpose: -* Should the TPN projection include a TAN projection? - -* Type: -* Protected attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls how a WcsMap with a AST__TPN projection -* type behaves. If the attribute value is non-zero (the default), -* the complete projection is performed as described in the draft -* version of FITS-WCS paper II. If it is zero, then the TAN -* projection from (psi,theta) to (xi,eta) is replaced by a unit -* transformation, so that the WcsMap implements the polynomial -* transformation only, without any preceding TAN projection. -* -* In addition if the TPNTan value is zero, then the WcsMap -* assumes that the input and output values are in degrees rather -* than radians. - -* Applicability: -* WcsMap -* All Frames have this attribute. -*att- -*/ -astMAKE_GET(WcsMap,TPNTan,int,1,( ( this->tpn_tan != -INT_MAX ) ? - this->tpn_tan : 1 )) -astMAKE_TEST(WcsMap,TPNTan,( this->tpn_tan != -INT_MAX )) - -/* ProjP. */ -/* ------ */ -/* -*att++ -* Name: -* ProjP(m) - -* Purpose: -* FITS-WCS projection parameters. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute provides aliases for the PV attributes, which -* specifies the projection parameter values to be used by a WcsMap -* when implementing a FITS-WCS sky projection. ProjP is retained for -* compatibility with previous versions of FITS-WCS and AST. New -* applications should use the PV attibute instead. -* -* Attributes ProjP(0) to ProjP(9) correspond to attributes PV_0 -* to PV_9, where is replaced by the index of the -* latitude axis (given by attribute WcsAxis(2)). See PV for further -* details. -* -* Note, the value of this attribute may changed only if the WcsMap -* has no more than one reference. That is, an error is reported if the -* WcsMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. - -* Applicability: -* WcsMap -* All WcsMaps have this attribute. - -*att-- -*/ - -/* PV. */ -/* --- */ -/* -*att++ -* Name: -* PVi_m - -* Purpose: -* FITS-WCS projection parameters. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the projection parameter values to be -* used by a WcsMap when implementing a FITS-WCS sky projection. -* Each PV attribute name should include two integers, i and m, -* separated by an underscore. The axis index is specified -* by i, and should be in the range 1 to 99. The parameter number -* is specified by m, and should be in the range 0 to 99. For -* example, "PV2_1=45.0" would specify a value for projection -* parameter 1 of axis 2 in a WcsMap. -* -* These projection parameters correspond exactly to the values -* stored using the FITS-WCS keywords "PV1_1", "PV1_2", etc. This -* means that projection parameters which correspond to angles must -* be given in degrees (despite the fact that the angular -* coordinates and other attributes used by a WcsMap are in -* radians). -* -* The set of projection parameters used by a WcsMap depends on the -* type of projection, which is determined by its WcsType -* parameter. Most projections either do not require projection -* parameters, or use parameters 1 and 2 associated with the latitude -* axis. You should consult the FITS-WCS paper for details. -* -* Some projection parameters have default values (as defined in -* the FITS-WCS paper) which apply if no explicit value is given. -* You may omit setting a value for these "optional" parameters and the -* default will apply. Some projection parameters, however, have no -* default and a value must be explicitly supplied. This is most -* conveniently -c done using the "options" argument of astWcsMap (q.v.) when a WcsMap -f done using the OPTIONS argument of AST_WCSMAP (q.v.) when a WcsMap -* is first created. An error will result when a WcsMap is used to -* transform coordinates if any of its required projection -* parameters has not been set and lacks a default value. - -* A "get" operation for a parameter which has not been assigned a value -* will return the default value defined in the FITS-WCS paper, or -* AST__BAD if the paper indicates that the parameter has no default. -* A default value of zero is returned for parameters which are not -* accessed by the projection. -* -* Note, the FITS-WCS paper reserves parameters 1 and 2 on the longitude -* axis to hold the native longitude and latitude of the fiducial -* point of the projection, in degrees. The default values for these -* parameters are determined by the projection type. The AST-specific -* TPN projection does not use this convention - all projection -* parameters for both axes are used to represent polynomical correction -* terms, and the native longitude and latitude at the fiducial point may -* not be changed from the default values of zero and 90 degrees. - -* Applicability: -* WcsMap -* All WcsMaps have this attribute. - -* Notes: -* - The value of this attribute may changed only if the WcsMap -* has no more than one reference. That is, an error is reported if the -* WcsMap has been cloned, either by including it within another object -* such as a CmpMap or FrameSet or by calling the -c astClone -f AST_CLONE -* function. -* - If the projection parameter values given for a WcsMap do not -* satisfy all the required constraints (as defined in the FITS-WCS -* paper), then an error will result when the WcsMap is used to -* transform coordinates. -*att-- -*/ - -/* PVMax. */ -/* ------ */ -/* -*att++ -* Name: -* PVMax(i) - -* Purpose: -* Maximum number of FITS-WCS projection parameters. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute specifies the largest legal index for a PV projection -* parameter attached to a specified axis of the WcsMap (i.e. the -* largest legal value for "m" when accessing the "PVi_m" attribute). -* The axis index is specified by i, and should be in the range 1 to 99. -* The value for each axis is determined by the projection type specified -* when the WcsMap -c is first created using astWcsMap and cannot subsequently be -f is first created using AST_WCSMAP and cannot subsequently be -* changed. - -* Applicability: -* WcsMap -* All WcsMaps have this attribute. -*att-- -*/ - -/* WcsType. */ -/* -------- */ -/* -*att++ -* Name: -* WcsType - -* Purpose: -* FITS-WCS projection type. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute specifies which type of FITS-WCS projection will -* be performed by a WcsMap. The value is specified when a WcsMap -c is first created using astWcsMap and cannot subsequently be -f is first created using AST_WCSMAP and cannot subsequently be -* changed. -* -c The values used are represented by macros with names of -f The values used are represented by symbolic constants with names of -* the form "AST__XXX", where "XXX" is the (upper case) 3-character -* code used by the FITS-WCS "CTYPEi" keyword to identify the -* projection. For example, possible values are AST__TAN (for the -* tangent plane or gnomonic projection) and AST__AIT (for the -* Hammer-Aitoff projection). AST__TPN is an exception in that it -* is not part of the FITS-WCS standard (it represents a TAN -* projection with polynomial correction terms as defined in an early -* draft of the FITS-WCS paper). - -* Applicability: -* WcsMap -* All WcsMaps have this attribute. - -* Notes: -* - For a list of available projections, see the FITS-WCS paper. -*att-- -*/ - -/* Type of FITS-WCS projection. Read only. */ -astMAKE_GET(WcsMap,WcsType,int,AST__WCSBAD,this->type) - -/* NatLat. */ -/* ------- */ -/* -*att++ -* Name: -* NatLat - -* Purpose: -* Native latitude of the reference point of a FITS-WCS projection. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point, read-only. - -* Description: -* This attribute gives the latitude of the reference point of the -* FITS-WCS projection implemented by a WcsMap. The value is in -* radians in the "native spherical" coordinate system. This value is -* fixed for most projections, for instance it is PI/2 (90 degrees) -* for all zenithal projections. For some projections (e.g. the conics) -* the value is not fixed, but is specified by parameter one on the -* latitude axis. -* -* FITS-WCS paper II introduces the concept of a "fiducial point" -* which is logical distinct from the projection reference point. -* It is easy to confuse the use of these two points. The fiducial -* point is the point which has celestial coordinates given by the -* CRVAL FITS keywords. The native spherical coordinates for this point -* default to the values of the NatLat and NatLon, but these defaults -* mey be over-ridden by values stored in the PVi_j keywords. Put -* another way, the CRVAL keywords will by default give the celestial -* coordinates of the projection reference point, but may refer to -* some other point if alternative native longitude and latitude values -* are provided through the PVi_j keywords. -* -* The NatLat attribute is read-only. - -* Applicability: -* WcsMap -* All WcsMaps have this attribute. - -* Notes: -* - A default value of AST__BAD is used if no latitude value is available. -*att-- -*/ - -/* -*att++ -* Name: -* NatLon - -* Purpose: -* Native longitude of the reference point of a FITS-WCS projection. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point, read-only. - -* Description: -* This attribute gives the longitude of the reference point of the -* FITS-WCS projection implemented by a WcsMap. The value is in -* radians in the "native spherical" coordinate system, and will -* usually be zero. See the description of attribute NatLat for further -* information. -* -* The NatLon attribute is read-only. - -* Applicability: -* WcsMap -* All WcsMaps have this attribute. - -* Notes: -*att-- -*/ - -/* WcsAxis. */ -/* -------- */ -/* -*att++ -* Name: -* WcsAxis(lonlat) - -* Purpose: -* FITS-WCS projection axes. - -* Type: -* Public attribute. - -* Synopsis: -* Integer, read-only. - -* Description: -* This attribute gives the indices of the longitude and latitude -* coordinates of the FITS-WCS projection within the coordinate -* space used by a WcsMap. These indices are defined when the -c WcsMap is first created using astWcsMap and cannot -f WcsMap is first created using AST_WCSMAP and cannot -* subsequently be altered. -* -* If "lonlat" is 1, the index of the longitude axis is -* returned. Otherwise, if it is 2, the index of the latitude axis -* is returned. - -* Applicability: -* WcsMap -* All WcsMaps have this attribute. -*att-- -*/ - -/* Index of the latitude or longitude axis. */ -MAKE_GET(WcsAxis,int,0,this->wcsaxis[ axis ],2) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for WcsMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for WcsMap objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* - This constructor makes a deep copy, including a copy of the -* projection parameter values associated with the input WcsMap. -*/ - - -/* Local Variables: */ - AstWcsMap *in; /* Pointer to input WcsMap */ - AstWcsMap *out; /* Pointer to output WcsMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output WcsMaps. */ - in = (AstWcsMap *) objin; - out = (AstWcsMap *) objout; - -/* Allocate memory to hold the projection parameters within the AstPrjPrm - structure used by WCSLIB. */ - (out->params).p = astMalloc( astSizeOf( (in->params).p ) ); - (out->params).p2 = astMalloc( astSizeOf( (in->params).p2 ) ); - -/* Copy the projection parameter information. */ - CopyPV( in, out, status ); - - return; - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for WcsMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for WcsMap objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstWcsMap *this; /* Pointer to WcsMap */ - -/* Obtain a pointer to the WcsMap structure. */ - this = (AstWcsMap *) obj; - -/* Free the arrays used to store projection parameters. */ - FreePV( this, status ); - -/* Free memory used to hold the projection parameters within the AstPrjPrm - structure used by WCSLIB. */ - this->params.p = astFree( this->params.p ); - this->params.p2 = astFree( this->params.p2 ); - -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for WcsMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the WcsMap class to an output Channel. - -* Parameters: -* this -* Pointer to the WcsMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -#define COMMENT_LEN 150 /* Maximum length of a keyword comment */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstWcsMap *this; /* Pointer to the WcsMap structure */ - char *comment; /* Pointer to comment string */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char comment_buff[ COMMENT_LEN + 1 ]; /* Buffer for keyword comment */ - const PrjData *prjdata; /* Information about the projection */ - double dval; /* Double precision value */ - int axis; /* Zero based axis index */ - int i; /* Axis index */ - int m; /* Parameter index */ - int ival; /* Integer value */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the WcsMap structure. */ - this = (AstWcsMap *) this_object; - -/* Write out values representing the instance variables for the - WcsMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. Note, all read-only attributes are considered to be set. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* WcsType. */ -/* -------- */ - ival = GetWcsType( this, status ); - prjdata = FindPrjData( ival, status ); - (void) sprintf( comment_buff, "%s projection", prjdata->desc ); - comment_buff[ 0 ] = toupper( comment_buff[ 0 ] ); - astWriteString( channel, "Type", 1, 1, prjdata->ctype + 1, comment_buff ); - -/* FITSProj */ -/* -------- */ - set = TestFITSProj( this, status ); - ival = set ? GetFITSProj( this, status ) : astGetFITSProj( this ); - astWriteInt( channel, "FitsPrj", set, 0, ival, - ival ? "Defines the FITS-WCS projection" : - "Does not define the FITS-WCS projection" ); - -/* TPNTan */ -/* ------ */ - set = TestTPNTan( this, status ); - ival = set ? GetTPNTan( this, status ) : astGetTPNTan( this ); - astWriteInt( channel, "TpnTan", set, 0, ival, - ival ? "Include TAN projection in TPN mapping" : - "Exclude TAN projection from TPN mapping" ); - -/* PVi_m. */ -/* ------ */ - for( i = 0; i < astGetNin( this ); i++ ){ - if( this->np ) { - for( m = 0; m < this->np[ i ]; m++ ){ - set = TestPV( this, i, m, status ); - if( set ) { - dval = set ? GetPV( this, i, m, status ) : astGetPV( this, i, m ); - (void) sprintf( buff, "PV%d_%d", i + 1, m ); - (void) sprintf( comment_buff, "Projection parameter %d for axis %d", m, i + 1 ); - astWriteDouble( channel, buff, set, 0, dval, comment_buff ); - } - } - } - } - -/* WcsAxis(axis). */ -/* -------------- */ - for( axis = 0; axis < 2; axis++ ){ - ival = GetWcsAxis( this, axis, status ); - (void) sprintf( buff, "WcsAx%d", axis + 1 ); - if( axis == 0 ) { - comment = "Index of celestial longitude axis"; - } else { - comment = "Index of celestial latitude axis"; - } - astWriteInt( channel, buff, (axis!=ival), 0, ival + 1, comment ); - } - -/* Note, the "params" component of the AstWcsMap structure is not written out - because it can be re-generated from the other components. */ - -/* Return. */ - return; - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAWcsMap and astCheckWcsMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(WcsMap,Mapping) -astMAKE_CHECK(WcsMap) - -AstWcsMap *astWcsMap_( int ncoord, int type, int lonax, int latax, - const char *options, int *status, ...){ -/* -*++ -* Name: -c astWcsMap -f AST_WCSMAP - -* Purpose: -* Create a WcsMap. - -* Type: -* Public function. - -* Synopsis: -c #include "wcsmap.h" -c AstWcsMap *astWcsMap( int ncoord, int type, int lonax, int latax, -c const char *options, ... ) -f RESULT = AST_WCSMAP( NCOORD, TYPE, LONAX, LATAX, OPTIONS, STATUS ) - -* Class Membership: -* WcsMap constructor. - -* Description: -* This function creates a new WcsMap and optionally initialises its -* attributes. -* -* A WcsMap is used to represent sky coordinate projections as -* described in the (draft) FITS world coordinate system (FITS-WCS) -* paper by E.W. Griesen and M. Calabretta (A & A, in preparation). -* This paper defines a set of functions, or sky projections, which -* transform longitude-latitude pairs representing spherical -* celestial coordinates into corresponding pairs of Cartesian -* coordinates (and vice versa). -* -* A WcsMap is a specialised form of Mapping which implements these -* sky projections and applies them to a specified pair of coordinates. -* All the projections in the FITS-WCS paper are supported, plus the now -* deprecated "TAN with polynomial correction terms" projection which -* is refered to here by the code "TPN". Using the FITS-WCS terminology, -* the transformation is between "native spherical" and "projection -* plane" coordinates. These coordinates may, optionally, be embedded in -* a space with more than two dimensions, the remaining coordinates being -* copied unchanged. Note, however, that for consistency with other AST -* facilities, a WcsMap handles coordinates that represent angles -* in radians (rather than the degrees used by FITS-WCS). -* -* The type of FITS-WCS projection to be used and the coordinates -* (axes) to which it applies are specified when a WcsMap is first -* created. The projection type may subsequently be determined -* using the WcsType attribute and the coordinates on which it acts -* may be determined using the WcsAxis(lonlat) attribute. -* -* Each WcsMap also allows up to 100 "projection parameters" to be -* associated with each axis. These specify the precise form of the -* projection, and are accessed using PVi_m attribute, where "i" is -* the integer axis index (starting at 1), and m is an integer -* "parameter index" in the range 0 to 99. The number of projection -* parameters required by each projection, and their meanings, are -* dependent upon the projection type (most projections either do not -* use any projection parameters, or use parameters 1 and 2 associated -* with the latitude axis). Before creating a WcsMap you should consult -* the FITS-WCS paper for details of which projection parameters are -* required, and which have defaults. When creating the WcsMap, you must -* explicitly set values for all those required projection parameters -* which do not have defaults defined in this paper. - -* Parameters: -c ncoord -f NCOORD = INTEGER (Given) -* The number of coordinate values for each point to be -* transformed (i.e. the number of dimensions of the space in -* which the points will reside). This must be at least 2. The -* same number is applicable to both input and output points. -c type -f TYPE = INTEGER (Given) -* The type of FITS-WCS projection to apply. This should be -c given using a macro value such as AST__TAN (for a tangent -f given as a symbolic value such as AST__TAN (for a tangent -* plane projection), where the characters following the double -* underscore give the projection type code (in upper case) as -* used in the FITS-WCS "CTYPEi" keyword. You should consult the -* FITS-WCS paper for a list of the available projections. The -* additional code of AST__TPN can be supplied which represents a -* TAN projection with polynomial correction terms as defined in an -* early draft of the FITS-WCS paper. -c lonax -f LONAX = INTEGER (Given) -* The index of the longitude axis. This should lie in the range -c 1 to "ncoord". -f 1 to NCOORD. -c latax -f LATAX = INTEGER (Given) -* The index of the latitude axis. This should lie in the range -c 1 to "ncoord" and be distinct from "lonax". -f 1 to NCOORD and be distinct from LONAX. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new WcsMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new WcsMap. The syntax used is identical to that for the -f AST_SET routine. -* -* If the sky projection to be implemented requires projection -* parameter values to be set, then this should normally be done -* here via the PVi_m attribute (see the "Examples" -* section). Setting values for these parameters is mandatory if -* they do not have default values (as defined in the FITS-WCS -* paper). -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astWcsMap() -f AST_WCSMAP = INTEGER -* A pointer to the new WcsMap. - -* Examples: -c wcsmap = astWcsMap( 2, AST__MER, 1, 2, "" ); -f WCSMAP = AST_WCSMAP( 2, AST__MER, 1, 2, ' ', STATUS ) -* Creates a WcsMap that implements a FITS-WCS Mercator -* projection on pairs of coordinates, with coordinates 1 and 2 -* representing the longitude and latitude respectively. Note -* that the FITS-WCS Mercator projection does not require any -* projection parameters. -c wcsmap = astWcsMap( 3, AST__COE, 2, 3, "PV3_1=40.0" ); -f WCSMAP = AST_WCSMAP( 3, AST__COE, 2, 3, 'PV3_1=40.0', STATUS ) -* Creates a WcsMap that implements a FITS-WCS conical equal -* area projection. The WcsMap acts on points in a 3-dimensional -* space; coordinates 2 and 3 represent longitude and latitude -* respectively, while the values of coordinate 1 are copied -* unchanged. Projection parameter 1 associatyed with the latitude -* axis (corresponding to FITS keyword "PV3_1") is required and has -* no default, so is set explicitly to 40.0 degrees. Projection -* parameter 2 (corresponding to FITS keyword "PV3_2") is required -* but has a default of zero, so need not be specified. - -* Notes: -* - The forward transformation of a WcsMap converts between -* FITS-WCS "native spherical" and "relative physical" coordinates, -* while the inverse transformation converts in the opposite -* direction. This arrangement may be reversed, if required, by -c using astInvert or by setting the Invert attribute to a non-zero -f using AST_INVERT or by setting the Invert attribute to a non-zero -* value. -* - If any set of coordinates cannot be transformed (for example, -* many projections do not cover the entire celestial sphere), then -* a WcsMap will yield coordinate values of AST__BAD. -* - The validity of any projection parameters given via the PVi_m -c parameter in the "options" string is not checked by this -f parameter in the OPTIONS string is not checked by this -* function. However, their validity is checked when the resulting -* WcsMap is used to transform coordinates, and an error will -* result if the projection parameters do not satisfy all the -* required constraints (as defined in the FITS-WCS paper). -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstWcsMap *new; /* Pointer to new WcsMap */ - va_list args; /* Variable argument list */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise the WcsMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitWcsMap( NULL, sizeof( AstWcsMap ), !class_init, &class_vtab, - "WcsMap", ncoord, type, lonax - 1, latax - 1 ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new WcsMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new WcsMap. */ - return new; -} - -AstWcsMap *astWcsMapId_( int ncoord, int type, int lonax, int latax, - const char *options, ... ){ -/* -* Name: -* astWcsMapId_ - -* Purpose: -* Create a WcsMap. - -* Type: -* Private function. - -* Synopsis: -* #include "wcsmap.h" -* AstWcsMap *astWcsMap_( int ncoord, int type, int lonax, int latax, -* const char *options, ... ) - -* Class Membership: -* WcsMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astWcsMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astWcsMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astWcsMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astWcsMap_. - -* Returned Value: -* The ID value associated with the new WcsMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstWcsMap *new; /* Pointer to new WcsMap */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the WcsMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitWcsMap( NULL, sizeof( AstWcsMap ), !class_init, &class_vtab, - "WcsMap", ncoord, type, lonax - 1, latax - 1 ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new WcsMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new WcsMap. */ - return astMakeId( new ); -} - -AstWcsMap *astInitWcsMap_( void *mem, size_t size, int init, - AstWcsMapVtab *vtab, const char *name, - int ncin, int type, int lonax, int latax, int *status ) { -/* -*+ -* Name: -* astInitWcsMap - -* Purpose: -* Initialise a WcsMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* AstWcsMap *astInitWcsMap( void *mem, size_t size, int init, -* AstWcsMapVtab *vtab, const char *name, -* int ncin, int type, int lonax, int latax ) - -* Class Membership: -* WcsMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new WcsMap object. It allocates memory (if necessary) to accommodate -* the WcsMap plus any additional data associated with the derived class. -* It then initialises a WcsMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a WcsMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the WcsMap is to be initialised. -* This must be of sufficient size to accommodate the WcsMap data -* (sizeof(WcsMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the WcsMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the WcsMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the WcsMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new WcsMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* ncin -* The number of coordinate values per point. -* type -* The type of projection to use, choosen from the list available -* in the FITS celestial coordinates system. These are specified by -* symbolic values such as AST__TAN (specifying a tangent plane -* projection), where the characters following the double underscore -* gives the FITS projection type (in upper case) as used in the FITS -* "CTYPEn" keyword. -* lonax -* The index of the longitude axis. The first axis has index 0. -* latax -* The index of the latitude axis. The first axis has index 0. - -* Returned Value: -* A pointer to the new WcsMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - const PrjData *prjdata; /* Information about the projection */ - AstWcsMap *new; /* Pointer to new WcsMap */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitWcsMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* If a genuine FITS-WCS projection has been specified, check the initialisation - value(s) for validity, reporting an error if necessary. Prefix the error - report with the name of the function and the class of object being - processed. First check that at least two dimensions are to be mapped. */ - if( type != AST__WCSBAD ){ - if ( ncin < 2 ){ - astError( AST__WCSNC, "astInitWcsMap(%s): Too few axes (%d) " - "specified. Must be at least 2.", status, name, ncin ); - -/* Report an error if either the longitude or latitude axes are out of - bounds. */ - } else if ( lonax < 0 || lonax >= ncin ){ - astError( AST__WCSAX, "astInitWcsMap(%s): Specified longitude axis (%d) " - "does not exist within a %d dimensional coordinate system. ", status, - name, lonax + 1, ncin ); - - } else if ( latax < 0 || latax >= ncin ){ - astError( AST__WCSAX, "astInitWcsMap(%s): Specified latitude axis (%d) " - "does not exist within a %d dimensional coordinate system. ", status, - name, latax + 1, ncin ); - -/* Report an error if the longitude or latitude axes are the same. */ - } else if ( lonax == latax ){ - astError( AST__WCSAX, "astInitWcsMap(%s): The same axis (%d) has been " - "given for both the longitude and the latitude axis.", status, name, - lonax + 1 ); - -/* Report an error if projection type is unknown. */ - } else if ( type < 1 || type >= AST__WCSBAD ){ - astError( AST__WCSTY, "astInitWcsMap(%s): Projection type %d is " - "undefined. Projection types must be in the range 1 to %d.", status, - name, type, AST__WCSBAD - 1 ); - } - } - -/* Get a description of the requeste dprojection type. */ - prjdata = FindPrjData( type, status ); - -/* If all the above checks have been passed succesfully... */ - if( astOK ){ - -/* Initialise a Mapping structure (the parent class) as the first component - within the WcsMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstWcsMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - ncin, ncin, 1, 1 ); - - if ( astOK ) { - -/* Initialise the WcsMap data. */ -/* ---------------------------- */ -/* Store the projection type. */ - new->type = type; - -/* Store the "use as FITS-WCS projection" flag. */ - new->fits_proj = -INT_MAX; - -/* Store the "include TAN component in TPN Mapping" flag. */ - new->tpn_tan = -INT_MAX; - -/* Store the axes associated with longitude and latitude. */ - new->wcsaxis[0] = lonax; - new->wcsaxis[1] = latax; - -/* Store NULL pointers for the arrays holding projection parameters. */ - new->p = NULL; - new->np = NULL; - -/* Allocate memory of the right size to hold the maximum number of - projection parameters needed by the projection. */ - new->params.p = astMalloc( sizeof( double ) * (prjdata->mxpar + 1) ); - new->params.p2 = astMalloc( sizeof( double ) * (prjdata->mxpar2 + 1) ); - -/* Initialise the "AstPrjPrm" structure (defined in proj.h). */ - InitPrjPrm( new, status ); - -/* If an error occurred, clean up by deleting the new WcsMap. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new WcsMap. */ - return new; -} - -AstWcsMap *astLoadWcsMap_( void *mem, size_t size, - AstWcsMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadWcsMap - -* Purpose: -* Load a WcsMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "wcsmap.h" -* AstWcsMap *astLoadWcsMap( void *mem, size_t size, -* AstWcsMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* WcsMap loader. - -* Description: -* This function is provided to load a new WcsMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* WcsMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a WcsMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the WcsMap is to be -* loaded. This must be of sufficient size to accommodate the -* WcsMap data (sizeof(WcsMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the WcsMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the WcsMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstWcsMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new WcsMap. If this is NULL, a pointer -* to the (static) virtual function table for the WcsMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "WcsMap" is used instead. - -* Returned Value: -* A pointer to the new WcsMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -/* Local Variables: */ - const PrjData *prjdata; /* Information about the projection */ - AstWcsMap *new; /* Pointer to the new WcsMap */ - char *text; /* Textual form of an integer value */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - double pv; /* Projection parameter */ - int axis; /* Axis index */ - int i; /* Axis index */ - int m; /* Parameter index */ - int mxpar; /* Maximum number of PVi_m values */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this WcsMap. In this case the - WcsMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstWcsMap ); - vtab = &class_vtab; - name = "WcsMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitWcsMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built WcsMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "WcsMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. Note, this is only - done for read/write attributes, not read-only ones. */ - -/* FITSProj */ -/* -------- */ - new->fits_proj = astReadInt( channel, "fitsprj", -INT_MAX ); - if ( TestFITSProj( new, status ) ) { - SetFITSProj( new, new->fits_proj, status ); - } - -/* TPNTan */ -/* -------- */ - new->tpn_tan = astReadInt( channel, "tpntan", -INT_MAX ); - if ( TestTPNTan( new, status ) ) { - SetTPNTan( new, new->tpn_tan, status ); - } - -/* WcsType */ -/* ------- */ - text = astReadString( channel, "type", " " ); - if( strcmp( text, " " ) ){ - char tmp[ 10 ]; - (void) sprintf( tmp, "-%.8s", text ); - new->type = astWcsPrjType( tmp ); - } else { - new->type = AST__WCSBAD; - } - text = astFree( text ); - prjdata = FindPrjData( new->type, status ); - -/* WcsAxis(axis). */ -/* -------------- */ - for( axis = 0; axis < 2; axis++ ){ - (void) sprintf( buff, "wcsax%d", axis + 1 ); - new->wcsaxis[ axis ] = astReadInt( channel, buff, axis + 1 ) - 1; - } - -/* Initialise the pointers to the projection parameter information. */ - new->p = NULL; - new->np = NULL; - new->params.p = astMalloc( sizeof( double ) * (prjdata->mxpar + 1) ); - new->params.p2 = astMalloc( sizeof( double ) * (prjdata->mxpar2 + 1) ); - -/* Initialise the structure used by WCSLIB to hold intermediate values, - so that the values will be re-calculated on the first invocation of a - mapping function. */ - InitPrjPrm( new, status ); - -/* ProjP(m). */ -/* --------- */ - for( m = 0; m < AST__WCSMX; m++ ){ - (void) sprintf( buff, "projp%d", m ); - pv = astReadDouble( channel, buff, AST__BAD ); - if( pv != AST__BAD ) SetPV( new, new->wcsaxis[ 1 ], m, pv, status ); - } - -/* PVi_m. */ -/* -------*/ - for( i = 0; i < astGetNin( new ); i++ ){ - - if( i == new->wcsaxis[ 0 ] ) { - mxpar = prjdata->mxpar2; - } else if( i == new->wcsaxis[ 1 ] ) { - mxpar = prjdata->mxpar; - } else { - mxpar = 0; - } - - for( m = 0; m <= mxpar; m++ ){ - (void) sprintf( buff, "pv%d_%d", i + 1, m ); - pv = astReadDouble( channel, buff, AST__BAD ); - if( pv != AST__BAD ) SetPV( new, i, m, pv, status ); - } - } - -/* If an error occurred, clean up by deleting the new WcsMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new WcsMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astClearPV_( AstWcsMap *this, int i, int m, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,WcsMap,ClearPV))( this, i, m, status ); -} - -void astClearTPNTan_( AstWcsMap *this, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,WcsMap,ClearTPNTan))( this, status ); -} - -double astGetPV_( AstWcsMap *this, int i, int m, int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,WcsMap,GetPV))( this, i, m, status ); -} - -void astSetPV_( AstWcsMap *this, int i, int m, double val, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,WcsMap,SetPV))( this, i, m, val, status ); -} - -void astSetTPNTan_( AstWcsMap *this, int val, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,WcsMap,SetTPNTan))( this, val, status ); -} - -int astTestPV_( AstWcsMap *this, int i, int m, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,WcsMap,TestPV))( this, i, m, status ); -} - -int astIsZenithal_( AstWcsMap *this, int *status ) { - if ( !astOK ) return 0; - return (**astMEMBER(this,WcsMap,IsZenithal))( this, status ); -} - -double astGetNatLat_( AstWcsMap *this, int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,WcsMap,GetNatLat))( this, status ); -} - -double astGetNatLon_( AstWcsMap *this, int *status ) { - if ( !astOK ) return AST__BAD; - return (**astMEMBER(this,WcsMap,GetNatLon))( this, status ); -} - -int astGetPVMax_( AstWcsMap *this, int i, int *status ) { - if ( !astOK ) return -1; - return (**astMEMBER(this,WcsMap,GetPVMax))( this, i, status ); -} - - - - - - - diff --git a/ast/wcsmap.h b/ast/wcsmap.h deleted file mode 100644 index 16ec3a7..0000000 --- a/ast/wcsmap.h +++ /dev/null @@ -1,591 +0,0 @@ -#if !defined( WCSMAP_INCLUDED ) /* Include this file only once */ -#define WCSMAP_INCLUDED -/* -*+ -* Name: -* wcsmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the WcsMap class. - -* Invocation: -* #include "wcsmap.h" - -* Description: -* This include file defines the interface to the WcsMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The WcsMap class implements Mappings that transform a pair of -* longitude/latitude values into a pair of projected Cartesian -* coordinates. All the projections included in FITS WCS are included. -* For more information about these projections, see the appropriate -* FITS document. - -* Inheritance: -* The WcsMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* NatLat (double) -* This attribute gives the latitude of the reference point of -* a FITS WCS projection, in the native coordinate system. The value -* returned is in radians. A value of AST__BAD is returned if -* no value is defined. This attribute is read only, and may change -* if new values are assigned to the projection parameters. -* NatLon (double) -* This attribute gives the longitude of the reference point of -* a FITS WCS projection, in the native coordinate system. The value -* returned is in radians. A value of AST__BAD is returned if -* no value is defined. This attribute is read only, and may change -* if new values are assigned to the projection parameters. -* ProjP(i) (double) -* This attribute provides aliases for the PV attributes, which -* specifies the projection parameter values to be used by a WcsMap -* when implementing a FITS-WCS sky projection. ProjP is retained for -* compatibility with previous versions of FITS-WCS and AST. New -* applications should use the PV attibute instead. -* PVj_m (double) -* This attribute gives the parameter values used by a FITS WCS -* projection. The index j is the axis index in the range 1 to 99, and -* the index m is the parameter index in the range 0 to 99. They will -* have the value AST__BAD if undefined. By default, no projection -* parameters are defined. These should be assigned appropriate values -* before using a WcsMap to transform points. -* WcsAxis(lonlat) (int) -* This attribute gives the indices of the longitude and latitude axes -* of a FITS WCS projection within the coordinate system used by a -* WcsMap. If "lonlat" is 1 then the index of the longitude axis is -* returned. If it is 2 the index of the latitude axis is returned. -* The first axis in the coordinate system is axis 1. This is a -* read-only attribute. -* WcsType (int) -* This attribute gives the FITS WCS projection type implemented by a -* WcsMap. Macros giving the integer value associated with supported -* projections are defined. They have the general form "AST__xxx" where -* "xxx" is the 3-character code used to represent the projection in the -* FITS CTYPE keyword. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* astClearAttrib -* Clear an attribute value for a WcsMap. -* astGetAttrib -* Get an attribute value for a WcsMap. -* astSetAttrib -* Set an attribute value for a WcsMap. -* astTestAttrib -* Test if an attribute value has been set for a WcsMap. -* astTransform -* Apply a WcsMap to transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* astClearPV -* Clear a PVi_j attribute value for a WcsMap. -* astGetNatLat -* Get the NatLat attribute value for a WcsMap. -* astGetNatLon -* Get the NatLon attribute value for a WcsMap. -* astGetPV -* Get a PVi_j attribute value for a WcsMap. -* astGetWcsAxis -* Get a WcsAxis attribute value for a WcsMap. -* astGetWcsType -* Get the WcsType attribute value for a WcsMap. -* astIsZenithal -* Is the projection zenithal? -* astSetPV -* Set a PVi_j attribute value for a WcsMap. -* astTestPV -* Test if a PVi_j attribute value has been set for a WcsMap. -* astWcsPrjName -* Return the FITS CTYPE keyword value for a given projection type. -* astWcsPrjDesc -* Return a textual description for a given projection type. -* astWcsPrjType -* Return the projection type given a FITS CTYPE keyword value. - -* Other Class Functions: -* Public: -* astIsAWcsMap -* Test class membership. -* astWcsMap -* Create a WcsMap. -* -* Protected: -* astCheckWcsMap -* Validate class membership. -* astInitWcsMap -* Initialise a WcsMap. -* astInitWcsMapVtab -* Initialise the virtual function table for the WcsMap class. -* astLoadWcsMap -* Load a WcsMap. - -* Macros: -* Public: -* AST__WCSMX -* Maximum number of parameters associated with a projection. -* AST__DPI -* 180 degrees in radians. -* AST__DPIBY2 -* 90 degrees in radians. -* AST__DD2R -* Factor for converting degrees to radians. -* AST__DR2D -* Factor for converting radians to degrees. -* AST__AZP -* An integer identifier for the FITS AZP projection. -* AST__TAN -* An integer identifier for the FITS TAN projection. -* AST__SIN -* An integer identifier for the FITS SIN projection. -* AST__STG -* An integer identifier for the FITS STG projection. -* AST__ARC -* An integer identifier for the FITS ARC projection. -* AST__ZPN -* An integer identifier for the FITS ZPN projection. -* AST__ZEA -* An integer identifier for the FITS ZEA projection. -* AST__AIR -* An integer identifier for the FITS AIR projection. -* AST__CYP -* An integer identifier for the FITS CYP projection. -* AST__CAR -* An integer identifier for the FITS CAR projection. -* AST__MER -* An integer identifier for the FITS MER projection. -* AST__CEA -* An integer identifier for the FITS CEA projection. -* AST__COP -* An integer identifier for the FITS COP projection. -* AST__COD -* An integer identifier for the FITS COD projection. -* AST__COE -* An integer identifier for the FITS COE projection. -* AST__COO -* An integer identifier for the FITS COO projection. -* AST__BON -* An integer identifier for the FITS BON projection. -* AST__PCO -* An integer identifier for the FITS PCO projection. -* AST__GLS -* A depracated integer identifier for the FITS SFL projection. -* AST__SFL -* An integer identifier for the FITS SFL projection. -* AST__PAR -* An integer identifier for the FITS PAR projection. -* AST__AIT -* An integer identifier for the FITS AIT projection. -* AST__MOL -* An integer identifier for the FITS MOL projection. -* AST__CSC -* An integer identifier for the FITS CSC projection. -* AST__QSC -* An integer identifier for the FITS QSC projection. -* AST__TSC -* An integer identifier for the FITS TSC projection -* AST__HPX -* An integer identifier for the FITS HPX projection. -* AST__XPH -* An integer identifier for the FITS XPH projection. -* AST__TPN -* An integer identifier for a "TAN with correction terms" projection. -* AST__WCSBAD -* An integer identifier for a "null" projection. -* -* Protected: -* None. - -* Type Definitions: -* Public: -* AstWcsMap -* WcsMap object type. -* -* Protected: -* AstWcsMapVtab -* WcsMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 15-Feb-1996 (DSB): -* Original version. -* 23-MAR-1996 (DSB): -* Support for PointSets with more than 2 axes added. -* 18-NOV-1996 (DSB): -* Updated to include attributes, etc. -* 26-SEP-1997 (DSB): -* Included new protected function, astPrjDesc. -* 11-FEB-2000 (DSB): -* Replaced wcsmap component projp by pointers p and np. -* 20-OCT-2002 (DSB): -* Added astIsZenithal -* 8-JAN-2003 (DSB): -* Added protected astInitWcsMapVtab method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "proj.h" /* Mark Calabretta's WCSLIB library header - file */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros. */ -/* ------- */ -/* Max. number of parameters for a WCS projection */ - -#if defined(astCLASS) || defined(astFORTRAN77) -#define STATUS_PTR status -#else -#define STATUS_PTR astGetStatusPtr -#endif -#define AST__WCSMX 10 - -/* pi: 180 degrees in radians - from SLALIB file slamac.h. */ -#define AST__DPI 3.1415926535897932384626433832795028841971693993751 - -/* pi/2: 90 degrees in radians - from SLALIB file slamac.h. */ -#define AST__DPIBY2 1.5707963267948966192313216916397514420985846996876 - -/* pi/180: degrees to radians - from SLALIB file slamac.h. */ -#define AST__DD2R 0.017453292519943295769236907684886127134428718885417 - -/* 180/pi: radians to degrees - from SLALIB file slamac.h. */ -#define AST__DR2D 57.295779513082320876798154814105170332405472466564 - -/* Projection Types: (note, WCSBAD must be the last in this list) */ - -#define AST__AZP 1 -#define AST__SZP 2 -#define AST__TAN 3 -#define AST__STG 4 -#define AST__SIN 5 -#define AST__ARC 6 -#define AST__ZPN 7 -#define AST__ZEA 8 -#define AST__AIR 9 -#define AST__CYP 10 -#define AST__CEA 11 -#define AST__CAR 12 -#define AST__MER 13 -#define AST__SFL 14 -#define AST__PAR 15 -#define AST__MOL 16 -#define AST__AIT 17 -#define AST__COP 18 -#define AST__COE 19 -#define AST__COD 20 -#define AST__COO 21 -#define AST__BON 22 -#define AST__PCO 23 -#define AST__TSC 24 -#define AST__CSC 25 -#define AST__QSC 26 -#define AST__NCP 27 -#define AST__GLS 28 -#define AST__TPN 29 -#define AST__HPX 30 -#define AST__XPH 31 -#define AST__WCSBAD 32 /* A bad projection type */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* WcsMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstWcsMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - int type; /* Projection type */ - int wcsaxis[2]; /* Indices of lon and lat. axes */ - double **p; /* Pointer to array of projection parameter arrays */ - int *np; /* Pointer to array of projection parameter counts */ - struct AstPrjPrm params; /* WCS structure holding projection - parameters, etc. Defined in proj.h */ - int fits_proj; /* Use as FITS-WCS projection? */ - int tpn_tan; /* Include TAN projection in TPN transformation? */ -} AstWcsMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstWcsMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - double (* GetNatLat)( AstWcsMap *, int * ); - double (* GetNatLon)( AstWcsMap *, int * ); - double (* GetPV)( AstWcsMap *, int, int, int * ); - int (* GetWcsAxis)( AstWcsMap *, int, int * ); - int (* GetWcsType)( AstWcsMap *, int * ); - int (* GetPVMax)( AstWcsMap *, int, int * ); - int (* TestPV)( AstWcsMap *, int, int, int * ); - void (* ClearPV)( AstWcsMap *, int, int, int * ); - void (* SetPV)( AstWcsMap *, int, int, double, int * ); - int (* IsZenithal)( AstWcsMap *, int * ); - - int (* GetFITSProj)( AstWcsMap *, int * ); - int (* TestFITSProj)( AstWcsMap *, int * ); - void (* ClearFITSProj)( AstWcsMap *, int * ); - void (* SetFITSProj)( AstWcsMap *, int, int * ); - - int (* GetTPNTan)( AstWcsMap *, int * ); - int (* TestTPNTan)( AstWcsMap *, int * ); - void (* ClearTPNTan)( AstWcsMap *, int * ); - void (* SetTPNTan)( AstWcsMap *, int, int * ); - -} AstWcsMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within this - class. */ -typedef struct AstWcsMapGlobals { - AstWcsMapVtab Class_Vtab; - int Class_Init; - char GetAttrib_Buff[ 101 ]; -} AstWcsMapGlobals; - -#endif -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(WcsMap) /* Check class membership */ -astPROTO_ISA(WcsMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstWcsMap *astWcsMap_( int, int, int, int, const char *, int *, ...); -#else -AstWcsMap *astWcsMapId_( int, int, int, int, const char *, ... )__attribute__((format(printf,5,6))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstWcsMap *astInitWcsMap_( void *, size_t, int, AstWcsMapVtab *, - const char *, int, int, int, int, int * ); - -/* Vtab initialiser. */ -void astInitWcsMapVtab_( AstWcsMapVtab *, const char *, int * ); - -/* Loader. */ -AstWcsMap *astLoadWcsMap_( void *, size_t, AstWcsMapVtab *, - const char *, AstChannel *, int * ); - -/* Thread-safe initialiser for all global data used by this module. */ -#if defined(THREAD_SAFE) -void astInitWcsMapGlobals_( AstWcsMapGlobals * ); -#endif - -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ - const char *astWcsPrjDesc_( int, int * ); - const char *astWcsPrjName_( int, int * ); - double astGetNatLat_( AstWcsMap *, int * ); - double astGetNatLon_( AstWcsMap *, int * ); - double astGetPV_( AstWcsMap *, int, int, int * ); - int astWcsPrjType_( const char *, int * ); - int astGetWcsAxis_( AstWcsMap *, int, int * ); - int astGetWcsType_( AstWcsMap *, int * ); - int astGetPVMax_( AstWcsMap *, int, int * ); - int astTestPV_( AstWcsMap *, int, int, int * ); - int astIsZenithal_( AstWcsMap *, int * ); - void astClearPV_( AstWcsMap *, int, int, int * ); - void astSetPV_( AstWcsMap *, int, int, double, int * ); - - int astGetFITSProj_( AstWcsMap *, int * ); - int astTestFITSProj_( AstWcsMap *, int * ); - void astClearFITSProj_( AstWcsMap *, int * ); - void astSetFITSProj_( AstWcsMap *, int, int * ); - - int astGetTPNTan_( AstWcsMap *, int * ); - int astTestTPNTan_( AstWcsMap *, int * ); - void astClearTPNTan_( AstWcsMap *, int * ); - void astSetTPNTan_( AstWcsMap *, int, int * ); - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckWcsMap(this) astINVOKE_CHECK(WcsMap,this,0) -#define astVerifyWcsMap(this) astINVOKE_CHECK(WcsMap,this,1) - -/* Test class membership. */ -#define astIsAWcsMap(this) astINVOKE_ISA(WcsMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astWcsMap astINVOKE(F,astWcsMap_) -#else -#define astWcsMap astINVOKE(F,astWcsMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define astInitWcsMap(mem,size,init,vtab,name,ncoord,type,lon,lat) \ -astINVOKE(O,astInitWcsMap_(mem,size,init,vtab,name,ncoord,type,lon,lat,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitWcsMapVtab(vtab,name) astINVOKE(V,astInitWcsMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadWcsMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadWcsMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckWcsMap to validate WcsMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ - -#define astWcsPrjType(ctype) astWcsPrjType_(ctype,STATUS_PTR) -#define astWcsPrjName(type) astWcsPrjName_(type,STATUS_PTR) -#define astWcsPrjDesc(type) astWcsPrjDesc_(type,STATUS_PTR) - -#define astClearPV(this,i,j) \ -astINVOKE(V,astClearPV_(astCheckWcsMap(this),i,j,STATUS_PTR)) -#define astGetPV(this,i,j) \ -astINVOKE(V,astGetPV_(astCheckWcsMap(this),i,j,STATUS_PTR)) -#define astSetPV(this,i,j,par) \ -astINVOKE(V,astSetPV_(astCheckWcsMap(this),i,j,par,STATUS_PTR)) -#define astTestPV(this,i,j) \ -astINVOKE(V,astTestPV_(astCheckWcsMap(this),i,j,STATUS_PTR)) - -#define astClearFITSProj(this) \ -astINVOKE(V,astClearFITSProj_(astCheckWcsMap(this),STATUS_PTR)) -#define astGetFITSProj(this) \ -astINVOKE(V,astGetFITSProj_(astCheckWcsMap(this),STATUS_PTR)) -#define astSetFITSProj(this,value) \ -astINVOKE(V,astSetFITSProj_(astCheckWcsMap(this),value,STATUS_PTR)) -#define astTestFITSProj(this) \ -astINVOKE(V,astTestFITSProj_(astCheckWcsMap(this),STATUS_PTR)) - -#define astClearTPNTan(this) \ -astINVOKE(V,astClearTPNTan_(astCheckWcsMap(this),STATUS_PTR)) -#define astGetTPNTan(this) \ -astINVOKE(V,astGetTPNTan_(astCheckWcsMap(this),STATUS_PTR)) -#define astSetTPNTan(this,value) \ -astINVOKE(V,astSetTPNTan_(astCheckWcsMap(this),value,STATUS_PTR)) -#define astTestTPNTan(this) \ -astINVOKE(V,astTestTPNTan_(astCheckWcsMap(this),STATUS_PTR)) - -#define astGetWcsType(this) \ -astINVOKE(V,astGetWcsType_(astCheckWcsMap(this),STATUS_PTR)) - -#define astGetPVMax(this,i) \ -astINVOKE(V,astGetPVMax_(astCheckWcsMap(this),i,STATUS_PTR)) - -#define astGetNatLat(this) \ -astINVOKE(V,astGetNatLat_(astCheckWcsMap(this),STATUS_PTR)) - -#define astGetNatLon(this) \ -astINVOKE(V,astGetNatLon_(astCheckWcsMap(this),STATUS_PTR)) - -#define astGetWcsAxis(this,index) \ -astINVOKE(V,astGetWcsAxis_(astCheckWcsMap(this),index,STATUS_PTR)) - -#define astIsZenithal(this) \ -astINVOKE(V,astIsZenithal_(astCheckWcsMap(this),STATUS_PTR)) - -#endif -#endif - - - - - diff --git a/ast/wcsmath.h b/ast/wcsmath.h deleted file mode 100644 index 1f8977a..0000000 --- a/ast/wcsmath.h +++ /dev/null @@ -1,67 +0,0 @@ -/*============================================================================= -* -* WCSLIB - an implementation of the FITS WCS proposal. -* Copyright (C) 1995-2002, Mark Calabretta -* -* This library is free software; you can redistribute it and/or modify it -* under the terms of the GNU Library General Public License as published -* by the Free Software Foundation; either version 2 of the License, or (at -* your option) any later version. -* -* This library is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library -* General Public License for more details. -* -* You should have received a copy of the GNU Library General Public License -* along with this library; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street,Fifth Floor, Boston, MA 02110-1301, USA -* -* Correspondence concerning WCSLIB may be directed to: -* Internet email: mcalabre@atnf.csiro.au -* Postal address: Dr. Mark Calabretta, -* Australia Telescope National Facility, -* P.O. Box 76, -* Epping, NSW, 2121, -* AUSTRALIA -* -* Author: Mark Calabretta, Australia Telescope National Facility -* $Id$ -*============================================================================= -* -* This version of wcstrig.h is based on the version in wcslib-2.9, but has -* been modified in the following ways by the Starlink project (e-mail: -* ussc@star.rl.ac.uk): -* - Changed the name of the WCSLIB_MATH macro to WCSLIB_MATH_INCLUDED -*===========================================================================*/ - -#ifndef WCSLIB_MATH_INCLUDED -#define WCSLIB_MATH_INCLUDED - -#ifdef PI -#undef PI -#endif - -#ifdef D2R -#undef D2R -#endif - -#ifdef R2D -#undef R2D -#endif - -#ifdef SQRT2 -#undef SQRT2 -#endif - -#ifdef SQRT2INV -#undef SQRT2INV -#endif - -#define PI 3.141592653589793238462643 -#define D2R PI/180.0 -#define R2D 180.0/PI -#define SQRT2 1.4142135623730950488 -#define SQRT2INV 1.0/SQRT2 - -#endif /* WCSLIB_MATH_INCLUDED */ diff --git a/ast/wcstrig.c b/ast/wcstrig.c deleted file mode 100644 index d3ba400..0000000 --- a/ast/wcstrig.c +++ /dev/null @@ -1,189 +0,0 @@ -/*============================================================================ -* -* WCSLIB - an implementation of the FITS WCS proposal. -* Copyright (C) 1995-2002, Mark Calabretta -* -* This library is free software; you can redistribute it and/or modify it -* under the terms of the GNU Library General Public License as published -* by the Free Software Foundation; either version 2 of the License, or (at -* your option) any later version. -* -* This library is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library -* General Public License for more details. -* -* You should have received a copy of the GNU Library General Public License -* along with this library; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street,Fifth Floor, Boston, MA 02110-1301, USA -* -* Correspondence concerning WCSLIB may be directed to: -* Internet email: mcalabre@atnf.csiro.au -* Postal address: Dr. Mark Calabretta, -* Australia Telescope National Facility, -* P.O. Box 76, -* Epping, NSW, 2121, -* AUSTRALIA -* -*============================================================================= -* -* This version of wcstrig.c is based on the version in wcslib-2.9, but has -* been modified in the following ways by the Starlink project (e-mail: -* ussc@star.rl.ac.uk): -* - Support for non-ANSI C "const" class removed -* - Changed names of projection functions and degrees trig functions -* to avoid clashes with wcslib. -*============================================================================= -* -* The functions defined herein are trigonometric or inverse trigonometric -* functions which take or return angular arguments in decimal degrees. -* -* $Id$ -*---------------------------------------------------------------------------*/ - -#include -#include "wcsmath.h" -#include "wcstrig.h" - -double astCosd(angle) - -const double angle; - -{ - double resid; - - resid = fabs(fmod(angle,360.0)); - if (resid == 0.0) { - return 1.0; - } else if (resid == 90.0) { - return 0.0; - } else if (resid == 180.0) { - return -1.0; - } else if (resid == 270.0) { - return 0.0; - } - - return cos(angle*D2R); -} - -/*--------------------------------------------------------------------------*/ - -double astSind(angle) - -const double angle; - -{ - double resid; - - resid = fmod(angle-90.0,360.0); - if (resid == 0.0) { - return 1.0; - } else if (resid == 90.0) { - return 0.0; - } else if (resid == 180.0) { - return -1.0; - } else if (resid == 270.0) { - return 0.0; - } - - return sin(angle*D2R); -} - -/*--------------------------------------------------------------------------*/ - -double astTand(angle) - -const double angle; - -{ - double resid; - - resid = fmod(angle,360.0); - if (resid == 0.0 || fabs(resid) == 180.0) { - return 0.0; - } else if (resid == 45.0 || resid == 225.0) { - return 1.0; - } else if (resid == -135.0 || resid == -315.0) { - return -1.0; - } - - return tan(angle*D2R); -} - -/*--------------------------------------------------------------------------*/ - -double astACosd(v) - -const double v; - -{ - if (v >= 1.0) { - if (v-1.0 < WCSTRIG_TOL) return 0.0; - } else if (v == 0.0) { - return 90.0; - } else if (v <= -1.0) { - if (v+1.0 > -WCSTRIG_TOL) return 180.0; - } - - return acos(v)*R2D; -} - -/*--------------------------------------------------------------------------*/ - -double astASind(v) - -const double v; - -{ - if (v <= -1.0) { - if (v+1.0 > -WCSTRIG_TOL) return -90.0; - } else if (v == 0.0) { - return 0.0; - } else if (v >= 1.0) { - if (v-1.0 < WCSTRIG_TOL) return 90.0; - } - - return asin(v)*R2D; -} - -/*--------------------------------------------------------------------------*/ - -double astATand(v) - -const double v; - -{ - if (v == -1.0) { - return -45.0; - } else if (v == 0.0) { - return 0.0; - } else if (v == 1.0) { - return 45.0; - } - - return atan(v)*R2D; -} - -/*--------------------------------------------------------------------------*/ - -double astATan2d(y, x) - -const double x, y; - -{ - if (y == 0.0) { - if (x >= 0.0) { - return 0.0; - } else if (x < 0.0) { - return 180.0; - } - } else if (x == 0.0) { - if (y > 0.0) { - return 90.0; - } else if (y < 0.0) { - return -90.0; - } - } - - return atan2(y,x)*R2D; -} diff --git a/ast/wcstrig.h b/ast/wcstrig.h deleted file mode 100644 index 36463bb..0000000 --- a/ast/wcstrig.h +++ /dev/null @@ -1,63 +0,0 @@ -/*============================================================================= -* -* WCSLIB - an implementation of the FITS WCS proposal. -* Copyright (C) 1995-2002, Mark Calabretta -* -* This library is free software; you can redistribute it and/or modify it -* under the terms of the GNU Library General Public License as published -* by the Free Software Foundation; either version 2 of the License, or (at -* your option) any later version. -* -* This library is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library -* General Public License for more details. -* -* You should have received a copy of the GNU Library General Public License -* along with this library; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street,Fifth Floor, Boston, MA 02110-1301, USA -* -* Correspondence concerning WCSLIB may be directed to: -* Internet email: mcalabre@atnf.csiro.au -* Postal address: Dr. Mark Calabretta, -* Australia Telescope National Facility, -* P.O. Box 76, -* Epping, NSW, 2121, -* AUSTRALIA -* -* Author: Mark Calabretta, Australia Telescope National Facility -* $Id$ -*============================================================================= -* -* This version of wcstrig.h is based on the version in wcslib-2.9, but has -* been modified in the following ways by the Starlink project (e-mail: -* ussc@star.rl.ac.uk): -* - Support for non-ANSI C prototypes removed -* - Changed the name of the WCSLIB_TRIG macro to WCSLIB_TRIG_INCLUDED -* - Changed names of degrees trig functions to avoid clashes with -* wcslib. -*===========================================================================*/ - -#ifndef WCSLIB_TRIG_INCLUDED -#define WCSLIB_TRIG_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - -double astCosd(const double); -double astSind(const double); -double astTand(const double); -double astACosd(const double); -double astASind(const double); -double astATand(const double); -double astATan2d(const double, const double); - -/* Domain tolerance for asin and acos functions. */ -#define WCSTRIG_TOL 1e-10 - -#ifdef __cplusplus -}; -#endif - -#endif /* WCSLIB_TRIG_INCLUDED */ diff --git a/ast/winmap.c b/ast/winmap.c deleted file mode 100644 index 5ba97d5..0000000 --- a/ast/winmap.c +++ /dev/null @@ -1,4389 +0,0 @@ -/* -*class++ -* Name: -* WinMap - -* Purpose: -* Map one window on to another by scaling and shifting each axis. - -* Constructor Function: -c astWinMap -f AST_WINMAP - -* Description: -* A Winmap is a linear Mapping which transforms a rectangular -* window in one coordinate system into a similar window in another -* coordinate system by scaling and shifting each axis (the window -* edges being parallel to the coordinate axes). -* -* A WinMap is specified by giving the coordinates of two opposite -* corners (A and B) of the window in both the input and output -* coordinate systems. - -* Inheritance: -* The WinMap class inherits from the Mapping class. - -* Attributes: -* The WinMap class does not define any new attributes beyond those -* which are applicable to all Mappings. - -* Functions: -c The WinMap class does not define any new functions beyond those -f The WinMap class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 23-OCT-1996 (DSB): -* Original version. -* 4-MAR-1997 (RFWS): -* Tidied public prologues. -* 11-MAR-1997 (DSB): -* Added MapMerge method and associated bits. -* 30-JUN-1997 (DSB): -* Bug fixed which caused the MapMerge method to generate a -* segmentation violation. -* 24-MAR-1998 (RFWS): -* Improved output format from Dump. -* 9-APR-1998 (DSB): -* MapMerge modified to allow merging of WinMaps with ZoomMaps and -* and UnitMaps in parallel. -* 4-SEP-1998 (DSB): -* Improved MapMerge so that WinMaps can change places with a wider -* range of PermMaps, allowing them to approach closer to a Mapping -* with which they can merge. -* 22-FEB-1999 (DSB): -* Corrected logic of MapMerge method to avoid infinite looping. -* 5-MAY-1999 (DSB): -* More corrections to MapMerge: Cleared up errors in the use of the -* supplied invert flags, and corrected logic for deciding which -* neighbouring Mapping to swap with. -* 16-JUL-1999 (DSB): -* Fixed memory leaks in WinMat and MapMerge. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitWinMapVtab -* method. -* 8-SEP-2003 (DSB): -* Allow WinMaps to swap with WcsMaps if possible. -* 10-NOV-2003 (DSB): -* Modified functions which swap a WinMap with another Mapping -* (e.g. WinPerm, etc), to simplify the returned Mappings. -* 23-APR-2004 (DSB): -* Changes to simplification algorithm. -* 1-SEP-2004 (DSB): -* Ensure do1 and do2 are initialised before use in MapMerge. -* 7-SEP-2005 (DSB): -* Take account of the Invert flag when using the soom factor from -* a ZoomMap. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 15-MAR-2006 (DSB): -* Override astEqual. -* 23-AUG-2006 (DSB): -* Correct initialisation of "result" in the Equal function. -* 19-JAN-2007 (DSB): -* Fix memory leak. -* 3-MAY-2013 (DSB): -* Improve simplification by adding check for inverse pairs of -* WinMaps in function WinWin. -* 23-APR-2015 (DSB): -* Improve MapMerge. If a WinMap can merge with its next-but-one -* neighbour, then swap the WinMap with its neighbour, so that -* it is then next its next-but-one neighbour, and then merge the -* two Mappings into a single Mapping. Previously, only the swap -* was performed - not the merger. And the swap was only performed -* if the intervening neighbour could not itself merge. This could -* result in an infinite simplification loop, which was detected by -* CmpMap and and aborted, resulting in no useful simplification. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS WinMap - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory management facilities */ -#include "object.h" /* Base Object class */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "matrixmap.h" /* Linear mappings */ -#include "unitmap.h" /* Unit mappings */ -#include "zoommap.h" /* Zoom mappings */ -#include "permmap.h" /* Axis permutations */ -#include "cmpmap.h" /* Compound mappings */ -#include "wcsmap.h" /* Celestial projections */ -#include "mapping.h" /* Coordinate mappings (parent class) */ -#include "channel.h" /* I/O channels */ -#include "winmap.h" /* Interface definition for this class */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - - -#ifdef THREAD_SAFE -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(WinMap) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(WinMap,Class_Init) -#define class_vtab astGLOBAL(WinMap,Class_Vtab) - - -#include - - -#else - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstWinMapVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstWinMap *astWinMapId_( int, const double [], const double [], - const double [], const double [], const char *, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ - -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static AstWinMap *WinUnit( AstWinMap *, AstUnitMap *, int, int, int * ); -static AstWinMap *WinWin( AstMapping *, AstMapping *, int, int, int, int * ); -static AstWinMap *WinZoom( AstWinMap *, AstZoomMap *, int, int, int, int, int * ); -static int GetObjSize( AstObject *, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static double Rate( AstMapping *, double *, int, int, int * ); -static int CanSwap( AstMapping *, AstMapping *, int, int, int *, int * ); -static int Equal( AstObject *, AstObject *, int * ); -static int GetIsLinear( AstMapping *, int * ); -static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int WinTerms( AstWinMap *, double **, double **, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void PermGet( AstPermMap *, int **, int **, double **, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void WinMat( AstMapping **, int *, int, int * ); -static void WinPerm( AstMapping **, int *, int, int * ); -static void WinWcs( AstMapping **, int *, int, int * ); -static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * ); - -/* Member functions. */ -/* ================= */ -static int CanSwap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, - int *simpler, int *status ){ -/* -* Name: -* CanSwap - -* Purpose: -* Determine if two Mappings could be swapped. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* int CanSwap( AstMapping *map1, AstMapping *map2, int inv1, int inv2, -* int *simpler, int *status ) - -* Class Membership: -* WinMap member function - -* Description: -* This function returns a flag indicating if the pair of supplied -* Mappings could be replaced by an equivalent pair of Mappings from the -* same classes as the supplied pair, but in reversed order. Each pair -* of Mappings is considered to be compunded in series. The supplied -* Mapings are not changed in any way. - -* Parameters: -* map1 -* The Mapping to be applied first. -* map2 -* The Mapping to be applied second. -* inv1 -* The invert flag to use with map1. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* inv2 -* The invert flag to use with map2. -* simpler -* Addresss of a location at which to return a flag indicating if -* the swapped Mappings would be intrinsically simpler than the -* original Mappings. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* 1 if the Mappings could be swapped, 0 otherwise. - -* Notes: -* - One of the supplied pair of Mappings must be a WinMap. -* - A value of 0 is returned if the two Mappings could be merged into -* a single Mapping. -* - A value of 0 is returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *nowin; /* Pointer to non-WinMap Mapping */ - AstWinMap *win; /* Pointer to the WinMap */ - const char *class1; /* Pointer to map1 class string */ - const char *class2; /* Pointer to map2 class string */ - const char *nowin_class; /* Pointer to non-WinMap class string */ - double *consts; /* Pointer to constants array */ - int *inperm; /* Pointer to input axis permutation array */ - int *outperm; /* Pointer to output axis permutation array */ - int axlat; /* Latitude axis in WcsMap */ - int axlon; /* Longitude axis in WcsMap */ - int i; /* Loop count */ - int invert[ 2 ]; /* Original invert flags */ - int nin; /* No. of input coordinates for the PermMap */ - int nout; /* No. of output coordinates for the PermMap */ - int ret; /* Returned flag */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise */ - ret = 0; - *simpler = 0; - -/* Temporarily set the Invert attributes of both Mappings to the supplied - values. */ - invert[ 0 ] = astGetInvert( map1 ); - astSetInvert( map1, inv1 ); - - invert[ 1 ] = astGetInvert( map2 ); - astSetInvert( map2, inv2 ); - -/* Get the classes of the two mappings. */ - class1 = astGetClass( map1 ); - class2 = astGetClass( map2 ); - if( astOK ){ - -/* Get a pointer to the non-WinMap Mapping. */ - if( !strcmp( class1, "WinMap" ) ){ - nowin = map2; - nowin_class = class2; - win = (AstWinMap *) map1; - } else { - nowin = map1; - nowin_class = class1; - win = (AstWinMap *) map2; - } - -/* If it is a MatrixMap, the Mappings can be swapped. */ - if( !strcmp( nowin_class, "MatrixMap" ) ){ - ret = 1; - -/* If it is a WcsMap, the Mappings can be swapped if the WinMap is - equivalent to a unit transformation on the celestial axes of the - WcsMap. */ - } else if( !strcmp( nowin_class, "WcsMap" ) ){ - -/* Get the indices of the celestial coordinates inthe WcsMap. */ - axlat = astGetWcsAxis( (AstWcsMap *) nowin, 1 ); - axlon = astGetWcsAxis( (AstWcsMap *) nowin, 0 ); - -/* Check the shift and scale for these axes. */ - ret = ( win->a[ axlon ] == 0.0 && win->b[ axlon ] == 1.0 && - win->a[ axlat ] == 0.0 && win->b[ axlat ] == 1.0 ); - -/* If it is a PermMap, the Mappings can be swapped so long as all links - between input and output axes in the PermMap are bi-directional. This - does not preclude the existence of unconnected axes, which do not - have links (bi-directional or otherwise). */ - } else if( !strcmp( nowin_class, "PermMap" ) ){ - -/* Get the number of input and output coordinates. */ - nin = astGetNin( nowin ); - nout = astGetNout( nowin ); - -/* We need to know the axis permutation arrays and constants array for - the PermMap. */ - PermGet( (AstPermMap *) nowin, &outperm, &inperm, &consts, status ); - if( astOK ) { - -/* Indicate we can swap with the PermMap. */ - ret = 1; - -/* Check each output axis. If any links between axes are found which are - not bi-directional, indicate that we cannot swap with the PermMap. */ - for( i = 0; i < nout; i++ ){ - if( outperm[ i ] >= 0 && outperm[ i ] < nin ) { - if( inperm[ outperm[ i ] ] != i ) { - ret = 0; - break; - } - } - } - -/* Check each input axis. If any links between axes are found which are - not bi-directional, indicate that we cannot swap with the PermMap. */ - for( i = 0; i < nin; i++ ){ - if( inperm[ i ] >= 0 && inperm[ i ] < nout ) { - if( outperm[ inperm[ i ] ] != i ) { - ret = 0; - break; - } - } - } - -/* If we can swap with the PermMap, the swapped Mappings may be - intrinsically simpler than the original mappings. */ - if( ret ) { - -/* If the PermMap precedes the WinMap, this will be the case if the PermMap - has more outputs than inputs. If the WinMap precedes the PermMap, this - will be the case if the PermMap has more inputs than outputs. */ - *simpler = ( nowin == map1 ) ? nout > nin : nin > nout; - } - -/* Free the axis permutation and constants arrays. */ - outperm = (int *) astFree( (void *) outperm ); - inperm = (int *) astFree( (void *) inperm ); - consts = (double *) astFree( (void *) consts ); - } - } - } - -/* Re-instate the original settings of the Invert attributes for the - supplied MatrixMaps. */ - astSetInvert( map1, invert[ 0 ] ); - astSetInvert( map2, invert[ 1 ] ); - -/* Return the answer. */ - return astOK ? ret : 0; -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a WinMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* WinMap member function (over-rides the astClearAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function clears the value of a specified attribute for a -* WinMap, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the WinMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* At the moment the WinMap class has no attributes, so pass it on to the - parent method for further interpretation. */ - (*parent_clearattrib)( this_object, attrib, status ); - -} - -static int Equal( AstObject *this_object, AstObject *that_object, int *status ) { -/* -* Name: -* Equal - -* Purpose: -* Test if two WinMaps are equivalent. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* int Equal( AstObject *this, AstObject *that, int *status ) - -* Class Membership: -* WinMap member function (over-rides the astEqual protected -* method inherited from the astMapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* two WinMaps are equivalent. - -* Parameters: -* this -* Pointer to the first Object (a WinMap). -* that -* Pointer to the second Object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the WinMaps are equivalent, zero otherwise. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstWinMap *that; - AstWinMap *this; - double *a_that; - double *a_this; - double *b_that; - double *b_this; - int i; - int nin; - int result; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain pointers to the two WinMap structures. */ - this = (AstWinMap *) this_object; - that = (AstWinMap *) that_object; - -/* Check the second object is a WinMap. We know the first is a - WinMap since we have arrived at this implementation of the virtual - function. */ - if( astIsAWinMap( that ) ) { - -/* Get the number of inputs and outputs and check they are the same for both. */ - nin = astGetNin( this ); - if( astGetNin( that ) == nin ) { - -/* Assume the WinMaps are equivalent. */ - result = 1; - -/* Compare the shift and scale terms from both WinMaps ignoring the - setting of the Invert flag for the moment. */ - for( i = 0; i < nin; i++ ) { - if( !astEQUAL( this->a[ i ], that->a[ i ] ) || - !astEQUAL( this->b[ i ], that->b[ i ] ) ) { - result = 0; - break; - } - } - -/* If the scale and shifts are equal, check the Invert flags are equal. */ - if( result ) { - result= ( astGetInvert( this ) == astGetInvert( that ) ); - -/* If the scale and shifts differ, there is still a chance that the - WinMaps may be equivalent if their Invert flags differ. */ - } else if( astGetInvert( this ) != astGetInvert( that ) ) { - -/* Create copies of the scale and shift terms from the two WinMaps, taking - into account the setting of the Invert attribute. Finding the inverted - terms involves arithmetic which introduces rounding errors, so this - test is not as reliable as the above direct comparison of terms. */ - astWinTerms( this, &a_this, &b_this ); - astWinTerms( that, &a_that, &b_that ); - result = 1; - - for( i = 0; i < nin; i++ ) { - if( !astEQUAL( a_this[ i ], a_that[ i ] ) || - !astEQUAL( b_this[ i ], b_that[ i ] ) ) { - result = 0; - break; - } - } - -/* Free resources */ - a_this = astFree( a_this ); - a_that = astFree( a_that ); - b_this = astFree( b_this ); - b_that = astFree( b_that ); - } - } - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetIsLinear( AstMapping *this_mapping, int *status ){ -/* -* Name: -* GetIsLinear - -* Purpose: -* Return the value of the IsLinear attribute for a WinMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* void GetIsLinear( AstMapping *this, int *status ) - -* Class Membership: -* WinMap member function (over-rides the protected astGetIsLinear -* method inherited from the Mapping class). - -* Description: -* This function returns the value of the IsLinear attribute for a -* Frame, which is always one. - -* Parameters: -* this -* Pointer to the WinMap. -* status -* Pointer to the inherited status variable. -*/ - return 1; -} - -static int GetObjSize( AstObject *this_object, int *status ) { -/* -* Name: -* GetObjSize - -* Purpose: -* Return the in-memory size of an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* WinMap member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied WinMap, -* in bytes. - -* Parameters: -* this -* Pointer to the WinMap. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Object size, in bytes. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstWinMap *this; /* Pointer to WinMap structure */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the WinMap structure. */ - this = (AstWinMap *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - result += astTSizeOf( this->a ); - result += astTSizeOf( this->b ); - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a WinMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* WinMap member function (over-rides the protected astGetAttrib -* method inherited from the Mapping class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a WinMap, formatted as a character string. - -* Parameters: -* this -* Pointer to the WinMap. -* attrib -* Pointer to a null-terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null-terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the WinMap, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the WinMap. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Constants: */ -#define BUFF_LEN 50 /* Max. characters in result buffer */ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* At the moment the WinMap class has no attributes, so pass it on to the - parent method for further interpretation. */ - result = (*parent_getattrib)( this_object, attrib, status ); - -/* Return the result. */ - return result; - -/* Undefine macros local to this function. */ -#undef BUFF_LEN -} - -void astInitWinMapVtab_( AstWinMapVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitWinMapVtab - -* Purpose: -* Initialise a virtual function table for a WinMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "winmap.h" -* void astInitWinMapVtab( AstWinMapVtab *vtab, const char *name ) - -* Class Membership: -* WinMap vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the WinMap class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitMappingVtab( (AstMappingVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsAWinMap) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstMappingVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->WinTerms = WinTerms; - -/* Save the inherited pointers to methods that will be extended, and - replace them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - parent_getobjsize = object->GetObjSize; - object->GetObjSize = GetObjSize; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - -/* Store replacement pointers for methods which will be over-ridden by - new member functions implemented here. */ - object->Equal = Equal; - mapping->MapMerge = MapMerge; - mapping->MapSplit = MapSplit; - mapping->Rate = Rate; - mapping->GetIsLinear = GetIsLinear; - -/* Declare the class dump, copy and delete functions.*/ - astSetDump( vtab, Dump, "WinMap", "Map one window on to another" ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - astSetDelete( (AstObjectVtab *) vtab, Delete ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int MapMerge( AstMapping *this, int where, int series, int *nmap, - AstMapping ***map_list, int **invert_list, int *status ) { -/* -* Name: -* MapMerge - -* Purpose: -* Simplify a sequence of Mappings containing a WinMap. - -* Type: -* Private function. - -* Synopsis: -* #include "mapping.h" -* int MapMerge( AstMapping *this, int where, int series, int *nmap, -* AstMapping ***map_list, int **invert_list, int *status ) - -* Class Membership: -* WinMap method (over-rides the protected astMapMerge method -* inherited from the Mapping class). - -* Description: -* This function attempts to simplify a sequence of Mappings by -* merging a nominated WinMap in the sequence with its neighbours, -* so as to shorten the sequence if possible. -* -* In many cases, simplification will not be possible and the -* function will return -1 to indicate this, without further -* action. -* -* In most cases of interest, however, this function will either -* attempt to replace the nominated WinMap with a Mapping which it -* considers simpler, or to merge it with the Mappings which -* immediately precede it or follow it in the sequence (both will -* normally be considered). This is sufficient to ensure the -* eventual simplification of most Mapping sequences by repeated -* application of this function. -* -* In some cases, the function may attempt more elaborate -* simplification, involving any number of other Mappings in the -* sequence. It is not restricted in the type or scope of -* simplification it may perform, but will normally only attempt -* elaborate simplification in cases where a more straightforward -* approach is not adequate. - -* Parameters: -* this -* Pointer to the nominated WinMap which is to be merged with -* its neighbours. This should be a cloned copy of the WinMap -* pointer contained in the array element "(*map_list)[where]" -* (see below). This pointer will not be annulled, and the -* WinMap it identifies will not be modified by this function. -* where -* Index in the "*map_list" array (below) at which the pointer -* to the nominated WinMap resides. -* series -* A non-zero value indicates that the sequence of Mappings to -* be simplified will be applied in series (i.e. one after the -* other), whereas a zero value indicates that they will be -* applied in parallel (i.e. on successive sub-sets of the -* input/output coordinates). -* nmap -* Address of an int which counts the number of Mappings in the -* sequence. On entry this should be set to the initial number -* of Mappings. On exit it will be updated to record the number -* of Mappings remaining after simplification. -* map_list -* Address of a pointer to a dynamically allocated array of -* Mapping pointers (produced, for example, by the astMapList -* method) which identifies the sequence of Mappings. On entry, -* the initial sequence of Mappings to be simplified should be -* supplied. -* -* On exit, the contents of this array will be modified to -* reflect any simplification carried out. Any form of -* simplification may be performed. This may involve any of: (a) -* removing Mappings by annulling any of the pointers supplied, -* (b) replacing them with pointers to new Mappings, (c) -* inserting additional Mappings and (d) changing their order. -* -* The intention is to reduce the number of Mappings in the -* sequence, if possible, and any reduction will be reflected in -* the value of "*nmap" returned. However, simplifications which -* do not reduce the length of the sequence (but improve its -* execution time, for example) may also be performed, and the -* sequence might conceivably increase in length (but normally -* only in order to split up a Mapping into pieces that can be -* more easily merged with their neighbours on subsequent -* invocations of this function). -* -* If Mappings are removed from the sequence, any gaps that -* remain will be closed up, by moving subsequent Mapping -* pointers along in the array, so that vacated elements occur -* at the end. If the sequence increases in length, the array -* will be extended (and its pointer updated) if necessary to -* accommodate any new elements. -* -* Note that any (or all) of the Mapping pointers supplied in -* this array may be annulled by this function, but the Mappings -* to which they refer are not modified in any way (although -* they may, of course, be deleted if the annulled pointer is -* the final one). -* invert_list -* Address of a pointer to a dynamically allocated array which, -* on entry, should contain values to be assigned to the Invert -* attributes of the Mappings identified in the "*map_list" -* array before they are applied (this array might have been -* produced, for example, by the astMapList method). These -* values will be used by this function instead of the actual -* Invert attributes of the Mappings supplied, which are -* ignored. -* -* On exit, the contents of this array will be updated to -* correspond with the possibly modified contents of the -* "*map_list" array. If the Mapping sequence increases in -* length, the "*invert_list" array will be extended (and its -* pointer updated) if necessary to accommodate any new -* elements. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If simplification was possible, the function returns the index -* in the "map_list" array of the first element which was -* modified. Otherwise, it returns -1 (and makes no changes to the -* arrays supplied). - -* Notes: -* - A value of -1 will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - AstCmpMap *cm; /* Pointer to neighbouring CmpMap */ - AstMapping **maplt; /* New mappings list pointer */ - AstMapping *map2; /* Pointer to replacement Mapping */ - AstMapping *mc[2]; /* Copies of supplied Mappings to swap */ - AstMapping *nc[2]; /* Copies of neighbouring Mappings to merge */ - AstMapping *smc0; /* Simplified Mapping */ - AstMapping *smc1; /* Simplified Mapping */ - AstMapping *simp1; /* Simplified Mapping */ - AstMapping *simp2; /* Simplified Mapping */ - AstMatrixMap *mtr; /* Pointer to replacement MatrixMap */ - AstWinMap *newwm2; /* Second component WinMap */ - AstWinMap *newwm; /* Pointer to replacement WinMap */ - AstWinMap *oldwm; /* Pointer to supplied WinMap */ - const char *class1; /* Pointer to first Mapping class string */ - const char *class2; /* Pointer to second Mapping class string */ - const char *nclass; /* Pointer to neighbouring Mapping class */ - double *a; /* Pointer to zero terms */ - double *b; /* Pointer to scale terms */ - int *invlt; /* New invert flags list pointer */ - int cmlow; /* Is lower neighbour a CmpMap? */ - int diag; /* Is WinMap equivalent to a diagonal matrix? */ - int do1; /* Would a backward swap make a simplification? */ - int do2; /* Would a forward swap make a simplification? */ - int i1; /* Index of first WinMap to merge */ - int i2; /* Index of last WinMap to merge */ - int i; /* Loop counter */ - int ic[2]; /* Copies of supplied invert flags to swap */ - int inc[4]; /* Copies of supplied invert flags to merge */ - int invert; /* Should the inverted Mapping be used? */ - int nin2; /* No. of inputs for second component WinMap */ - int nin; /* Number of coordinates for WinMap */ - int nmapt; /* No. of Mappings in list */ - int nstep1; /* No. of Mappings backwards to next mergable Mapping */ - int nstep2; /* No. of Mappings forward to next mergable Mapping */ - int old_winv; /* original Invert value for supplied WinMap */ - int result; /* Result value to return */ - int ser; /* Are Mappings applied in series? */ - int simpler; /* Is the resulting Mapping simpler than original? */ - int swap; /* Is there an advantage in swapping mappings? */ - int swaphi; /* Can WinMap be swapped with higher neighbour? */ - int swaplo; /* Can WinMap be swapped with lower neighbour? */ - -/* Initialise. */ - result = -1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - i1 = 0; - i2 = 0; - -/* Get the number of axes for the WinMap. */ - nin = astGetNin( ( *map_list )[ where ] ); - -/* Get a pointer to the WinMap. */ - oldwm = (AstWinMap *) this; - -/* First of all, see if the WinMap can be replaced by a simpler Mapping, - without reference to the neighbouring Mappings in the list. */ -/* ======================================================================*/ -/* If the shift terms in the WinMap are all zero, the WinMap can be - replaced by a diagonal MatrixMap (which is faster to compute). Check the - shift terms. */ - diag = 1; - newwm = (AstWinMap *) ( *map_list )[ where ]; - for( i = 0; i < nin; i++ ){ - if( !astEQUAL( ( newwm->a )[ i ], 0.0 ) ){ - diag = 0; - break; - } - } - -/* If all the shift terms are zero... */ - if( diag ){ - -/* Temporarily set the Invert attribute of the WinMap to the supplied - value. */ - old_winv = astGetInvert( newwm ); - astSetInvert( newwm, ( *invert_list )[ where ] ); - -/* Get a copy of the scale terms from the WinMap. */ - astWinTerms( newwm, NULL, &b ); - -/* Create a diagonal MatrixMap holding the scale terms. */ - mtr = astMatrixMap( nin, nin, 1, b, "", status ); - -/* Restore the Invert attribute of the supplied WinMap. */ - astSetInvert( newwm, old_winv ); - -/* Free the memory used to hold the scale terms. */ - b = (double *) astFree( (void *) b ); - -/* Annul the WinMap pointer in the list and replace it with the MatrixMap - pointer, and indicate that the forward transformation of the returned - MatrixMap should be used. */ - (void) astAnnul( ( *map_list )[ where ] ); - ( *map_list )[ where ] = (AstMapping *) mtr; - ( *invert_list )[ where ] = 0; - -/* Return the index of the first modified element. */ - result = where; - -/* If the WinMap itself could not be simplified, see if it can be merged - with the Mappings on either side of it in the list. */ - } else { - -/* Store the classes of the neighbouring Mappings in the list. */ - class1 = ( where > 0 ) ? astGetClass( ( *map_list )[ where - 1 ] ) : NULL; - class2 = ( where < *nmap - 1 ) ? astGetClass( ( *map_list )[ where + 1 ] ) : NULL; - -/* In series. */ -/* ========== */ - if ( series ) { - -/* We first look to see if the WinMap can be merged with one of its - neighbours, resulting in a reduction of one in the number of Mappings - in the list. WinMaps can only merge directly with another WinMap, a - ZoomMap, or a UnitMap. */ - if( class1 && ( !strcmp( class1, "WinMap" ) || - !strcmp( class1, "ZoomMap" ) || - !strcmp( class1, "UnitMap" ) ) ){ - nclass = class1; - i1 = where - 1; - i2 = where; - - } else if( class2 && ( !strcmp( class2, "WinMap" ) || - !strcmp( class2, "ZoomMap" ) || - !strcmp( class2, "UnitMap" ) ) ){ - nclass = class2; - i1 = where; - i2 = where + 1; - - } else { - nclass = NULL; - } - -/* If the WinMap can merge with one of its neighbours, create the merged - Mapping. */ - if( nclass ){ - - if( !strcmp( nclass, "WinMap" ) ){ - newwm = WinWin( ( *map_list )[ i1 ], ( *map_list )[ i2 ], - ( *invert_list )[ i1 ], ( *invert_list )[ i2 ], - 1, status ); - invert = 0; - - } else if( !strcmp( nclass, "ZoomMap" ) ){ - if( i1 == where ){ - newwm = WinZoom( (AstWinMap *)( *map_list )[ i1 ], - (AstZoomMap *)( *map_list )[ i2 ], - ( *invert_list )[ i1 ], ( *invert_list )[ i2 ], 1, 1, status ); - } else { - newwm = WinZoom( (AstWinMap *)( *map_list )[ i2 ], - (AstZoomMap *)( *map_list )[ i1 ], - ( *invert_list )[ i2 ], ( *invert_list )[ i1 ], 0, 1, status ); - } - invert = 0; - - } else { - newwm = astClone( ( *map_list )[ where ] ); - invert = ( *invert_list )[ where ]; - } - -/* If succesfull... */ - if( astOK ){ - -/* Annul the first of the two Mappings, and replace it with the merged - WinMap. Also set the invert flag. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - ( *map_list )[ i1 ] = (AstMapping *) newwm; - ( *invert_list )[ i1 ] = invert; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ i2 ] ); - for ( i = i2 + 1; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = i1; - - } - -/* If one of the neighbours is a (parallel) CmpMap, we convert the WinMap - into an equivalent parallel CmpMap, and then merge this parallel - CmpMap with the neighbouring parallel CmpMap to create a parallel CmpMap - containing two series CmpMaps. */ - } else if( ( class1 && !strcmp( "CmpMap", class1 ) ) || - ( class2 && !strcmp( "CmpMap", class2 ) ) ) { - -/* Identify the WinMap and the CmpMap. */ - if( class1 && !strcmp( "CmpMap", class1 ) ) { - i1 = where - 1; - i2 = where; - cm = (AstCmpMap *) ( *map_list )[ where - 1 ]; - cmlow = 1; - - } else { - i1 = where; - i2 = where + 1; - cm = (AstCmpMap *) ( *map_list )[ where + 1 ]; - cmlow = 0; - - } - -/* Temporarily set the required Invert attributes in the two Mappings. */ - inc[ 0 ] = astGetInvert( ( *map_list )[ i1 ] ); - astSetInvert( ( *map_list )[ i1 ], ( *invert_list )[ i1 ] ); - - inc[ 1 ] = astGetInvert( ( *map_list )[ i2 ] ); - astSetInvert( ( *map_list )[ i2 ], ( *invert_list )[ i2 ] ); - -/* Now get pointers to the scale and zero terms of the nominated WinMap - (these describe the forward transformation, taking into account the - setting of the Invert flag). */ - (void) astWinTerms( oldwm , &a, &b ); - -/* Get pointers to the two components of the parallel CmpMap. */ - astDecompose( cm, mc, mc + 1, &ser, ic, ic + 1 ); - -/* Check component Mappings are combined in parallel. */ - map2 = NULL; - if( astOK && !ser ) { - -/* Temporarily set the required Invert attributes in the two component - Mappings to the indicated values. */ - inc[ 2 ] = astGetInvert( mc[ 0 ] ); - astSetInvert( mc[ 0 ], ic[ 0 ] ); - - inc[ 3 ] = astGetInvert( mc[ 1 ] ); - astSetInvert( mc[ 1 ], ic[ 1 ] ); - -/* Create the first of two corresponding WinMaps, initially with undefined - corners. These could be combined into a parallel CmpMap which would be - equivalent to the nominated WinMap. The number of inputs for each WinMap - is equal to either the number of outputs or inputs of the corresponding - component of the CmpMap, depending on whether the CmpMap is upper or lower - neighbour. */ - nin = cmlow ? astGetNout( mc[ 0 ] ):astGetNin( mc[ 0 ] ); - newwm = astWinMap( nin, NULL, NULL, NULL, NULL, "", status ); - if( astOK ) { - -/* Store the first "nin" scale and zero terms from the nominated WinMap - in the new WinMap. */ - for( i = 0; i < nin; i++ ) { - (newwm->a)[ i ] = a[ i ]; - (newwm->b)[ i ] = b[ i ]; - } - } - -/* Now create the second WinMap in the same way, which transforms the - remaining outputs of the CmpMap. */ - nin2 = cmlow ? astGetNout( mc[ 1 ] ):astGetNin( mc[ 1 ] ); - newwm2 = astWinMap( nin2, NULL, NULL, NULL, NULL, "", status ); - if( astOK ) { - -/* Store the remaining scale and zero terms from the nominated WinMap - in the new WinMap. */ - for( i = 0; i < nin2; i++ ) { - (newwm2->a)[ i ] = a[ i + nin ]; - (newwm2->b)[ i ] = b[ i + nin ]; - } - } - -/* Combine the two corresponding lower component Mappings into a series - CmpMap, and likewise combine the two corresponding upper component - Mappings into a series CmpMap. */ - if( cmlow ) { - nc[ 0 ] = (AstMapping *) astCmpMap( mc[ 0 ], newwm, 1, "", status ); - nc[ 1 ] = (AstMapping *) astCmpMap( mc[ 1 ], newwm2, 1, "", status ); - } else { - nc[ 0 ] = (AstMapping *) astCmpMap( newwm, mc[ 0 ], 1, "", status ); - nc[ 1 ] = (AstMapping *) astCmpMap( newwm2, mc[ 1 ], 1, "", status ); - } - newwm = astAnnul( newwm ); - newwm2 = astAnnul( newwm2 ); - -/* Attempt to simplify each of the two new series CmpMaps. If neither of - them simplify then there is no point in doing the current merger. In fact - it would be dangerous to do so since we may end up in an infinite loop - where the resulting parallel CmpMap gets converted back into the - existing series CmpMap by the CmpMap MapMerge method, and then back - again by this method, etc. */ - simp1 = astSimplify( nc[ 0 ] ); - simp2 = astSimplify( nc[ 1 ] ); - -/* Test if either could be simplified by checking if its pointer value - has changed. */ - simpler = ( simp1 != nc[ 0 ] ) || ( simp2 != nc[ 1 ] ); - -/* If either CmpMap was simplified, then combine the two series CmpMap into - a single parallel CmpMap. */ - if( simpler ) { - map2 = (AstMapping *) astCmpMap( simp1, simp2, 0, "", status ); - } - -/* Re-instate the original Invert attributes in the two component Mappings. */ - astSetInvert( mc[ 0 ], inc[ 2 ] ); - astSetInvert( mc[ 1 ], inc[ 3 ] ); - -/* Free resources. */ - simp1 = astAnnul( simp1 ); - simp2 = astAnnul( simp2 ); - nc[ 0 ] = astAnnul( nc[ 0 ] ); - nc[ 1 ] = astAnnul( nc[ 1 ] ); - - } - -/* Free resources. */ - mc[ 0 ] = astAnnul( mc[ 0 ] ); - mc[ 1 ] = astAnnul( mc[ 1 ] ); - a = astFree( a ); - b = astFree( b ); - -/* Re-instate the original Invert attributes. */ - astSetInvert( ( *map_list )[ i1 ], inc[ 0 ] ); - astSetInvert( ( *map_list )[ i2 ], inc[ 1 ] ); - -/* If the above produced a new Mapping, annul the supplied pointers for - the two merged Mappings, store the pointer for the new merged Mapping, - and shuffle the remaining Mappings down to fill the space left. Nullify - the end slot which is no longer used, reduce the number of Mappings in - the list by 1, and return the index of the first modified Mapping. */ - if( map2 ) { - (void) astAnnul( ( *map_list )[ i1 ] ); - (void) astAnnul( ( *map_list )[ i2 ] ); - ( *map_list )[ i1 ] = map2; - ( *invert_list )[ i1 ] = 0; - for( i = i2 + 1; i < *nmap; i++ ){ - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - ( *map_list )[ *nmap - 1 ] = NULL; - (*nmap)--; - result = i1; - } - -/* If the WinMap could not merge directly with either of its neighbours, - we consider whether it would be worthwhile to swap the WinMap with - either of its neighbours. This can only be done for certain classes - of Mapping (MatrixMap & some PermMaps & WcsMaps), and will usually require both - Mappings to be modified (unless they are commutative). The advantage of - swapping the order of the Mappings is that it may result in the WinMap - being adjacent to a Mapping with which it can merge directly on the next - invocation of this function, thus reducing the number of Mappings - in the list. */ - } else { - -/* Set a flag if we could swap the WinMap with its higher neighbour. "do2" - is returned if swapping the Mappings would simplify either of the - Mappings. */ - if( where + 1 < *nmap ){ - swaphi = CanSwap( ( *map_list )[ where ], - ( *map_list )[ where + 1 ], - ( *invert_list )[ where ], - ( *invert_list )[ where + 1 ], &do2, status ); - } else { - swaphi = 0; - do2 = 0; - } - -/* If so, step through each of the Mappings which follow the WinMap, - looking for a Mapping with which the WinMap could merge directly. Stop - when such a Mapping is found, or if a Mapping is found with which the - WinMap could definitely not swap. Note the number of Mappings which - separate the WinMap from the Mapping with which it could merge (if - any). */ - nstep2 = -1; - if( swaphi ){ - for( i2 = where + 1; i2 < *nmap; i2++ ){ - -/* See if we can merge with this Mapping. If so, note the number of steps - between the two Mappings and leave the loop. */ - nclass = astGetClass( ( *map_list )[ i2 ] ); - if( !strcmp( nclass, "WinMap" ) || - !strcmp( nclass, "ZoomMap" ) || - !strcmp( nclass, "UnitMap" ) ) { - nstep2 = i2 - where - 1; - break; - } - -/* If there is no chance that we can swap with this Mapping, leave the loop - with -1 for the number of steps to indicate that no merging is possible. - WinMaps can swap with MatrixMaps and some PermMaps. */ - if( strcmp( nclass, "MatrixMap" ) && - strcmp( nclass, "WcsMap" ) && - strcmp( nclass, "PermMap" ) ) { - break; - } - - } - - } - -/* Do the same working forward from the WinMap towards the start of the map - list. */ - if( where > 0 ){ - swaplo = CanSwap( ( *map_list )[ where - 1 ], - ( *map_list )[ where ], - ( *invert_list )[ where - 1 ], - ( *invert_list )[ where ], &do1, status ); - } else { - swaplo = 0; - do1 = 0; - } - - nstep1 = -1; - if( swaplo ){ - for( i1 = where - 1; i1 >= 0; i1-- ){ - - nclass = astGetClass( ( *map_list )[ i1 ] ); - if( !strcmp( nclass, "WinMap" ) || - !strcmp( nclass, "ZoomMap" ) || - !strcmp( nclass, "UnitMap" ) ) { - nstep1 = where - 1 - i1; - break; - } - - if( strcmp( nclass, "MatrixMap" ) && - strcmp( nclass, "WcsMap" ) && - strcmp( nclass, "PermMap" ) ) { - break; - } - - } - - } - -/* Choose which neighbour to swap with so that the WinMap moves towards the - nearest Mapping with which it can merge. */ - if( do1 || ( - nstep1 != -1 && ( nstep2 == -1 || nstep2 > nstep1 ) ) ){ - nclass = class1; - i1 = where - 1; - i2 = where; - } else if( do2 || nstep2 != -1 ){ - nclass = class2; - i1 = where; - i2 = where + 1; - } else { - nclass = NULL; - } - -/* If there is a target Mapping in the list with which the WinMap could - merge, replace the supplied Mappings with swapped Mappings to bring a - WinMap closer to the target Mapping. */ - if( nclass ){ - -/* Swap the Mappings. */ - if( !strcmp( nclass, "MatrixMap" ) ){ - WinMat( (*map_list) + i1, (*invert_list) + i1, where - i1, status ); - - } else if( !strcmp( nclass, "PermMap" ) ){ - WinPerm( (*map_list) + i1, (*invert_list) + i1, where - i1, status ); - - } else if( !strcmp( nclass, "WcsMap" ) ){ - WinWcs( (*map_list) + i1, (*invert_list) + i1, where - i1, status ); - } - -/* And then merge them if possible. */ - if( where == i1 && where + 1 < *nmap ) { /* Merging upwards */ - map2 = astClone( (*map_list)[ where + 1 ] ); - nmapt = *nmap - where - 1; - maplt = *map_list + where + 1; - invlt = *invert_list + where + 1; - - (void) astMapMerge( map2, 0, series, &nmapt, &maplt, &invlt ); - map2 = astAnnul( map2 ); - *nmap = where + 1 + nmapt; - - } else if( where - 2 >= 0 ) { /* Merging downwards */ - map2 = astClone( (*map_list)[ where - 2 ] ); - nmapt = *nmap - where + 2; - maplt = *map_list + where - 2 ; - invlt = *invert_list + where - 2; - - (void) astMapMerge( map2, 0, series, &nmapt, &maplt, &invlt ); - map2 = astAnnul( map2 ); - *nmap = where - 2 + nmapt; - } - - result = i1; - -/* If there is no Mapping available for merging, it may still be - advantageous to swap with a neighbour because the swapped Mapping may - be simpler than the original Mappings. For instance, a PermMap may - strip axes of the WinMap leaving only a UnitMap. Also, the two neighbours - may be able to merge. */ - } else if( swaphi || swaplo ) { - -/* Try swapping with each possible neighbour in turn. */ - for( i = 0; i < 2; i++ ) { - -/* Set up the class and pointers for the mappings to be swapped, first - the lower neighbour, then the upper neighbour. */ - if( i == 0 && swaplo ){ - nclass = class1; - i1 = where - 1; - i2 = where; - - } else if( i == 1 && swaphi ){ - nclass = class2; - i1 = where; - i2 = where + 1; - - } else { - nclass = NULL; - } - -/* If we have a Mapping to swap with... */ - if( nclass ) { - -/* Take copies of the Mapping and Invert flag arrays so we do not change - the supplied values. */ - mc[ 0 ] = (AstMapping *) astCopy( ( (*map_list) + i1 )[0] ); - mc[ 1 ] = (AstMapping *) astCopy( ( (*map_list) + i1 )[1] ); - ic[ 0 ] = ( (*invert_list) + i1 )[0]; - ic[ 1 ] = ( (*invert_list) + i1 )[1]; - -/* Swap these Mappings. */ - if( !strcmp( nclass, "MatrixMap" ) ){ - WinMat( mc, ic, where - i1, status ); - } else if( !strcmp( nclass, "PermMap" ) ){ - WinPerm( mc, ic, where - i1, status ); - } else if( !strcmp( nclass, "WcsMap" ) ){ - WinWcs( mc, ic, where - i1, status ); - } - -/* See if the two neighbouring Mappings can merge now that the nominated - Mapping is no longer in between them. First get a list of Mapping - pointers containing the two Mappings to be merged, and associated - invert flags. */ - if( i == 0 && where != *nmap - 1 ) { - nc[ 0 ] = astClone( mc[ 1 ] ); - nc[ 1 ] = astClone( (*map_list)[ where + 1 ] ); - inc[ 0 ] = ic[ 1 ]; - inc[ 1 ] = (*invert_list)[ where + 1 ]; - - } else if( i == 1 && where > 0 ) { - nc[ 0 ] = astClone( (*map_list)[ where - 1 ] ); - nc[ 1 ] = astClone( mc[ 0 ] ); - inc[ 0 ] = (*invert_list)[ where - 1 ]; - inc[ 1 ] = ic[ 0 ]; - - } else { - nc[ 0 ] = NULL; - nc[ 1 ] = NULL; - } - -/* If both neighbours are available, use astMapMerge to see if it is - possible to merge the two Mappings. */ - swap = 0; - if( nc[ 0 ] && nc[ 1 ] ) { - nmapt = 2; - maplt = nc; - invlt = inc; - map2 = astClone( nc[ 0 ] ); - swap = astMapMerge( map2, 0, series, &nmapt, &maplt, &invlt ); - map2 = astAnnul( map2 ); - if( swap == -1 ) { - map2 = astClone( nc[ 1 ] ); - swap = astMapMerge( map2, 1, series, &nmapt, &maplt, &invlt ); - map2 = astAnnul( map2 ); - } - swap = ( nmapt < 2 ) ? 1 : 0; - } - -/* Free resources. */ - if( nc[ 0 ] ) nc[ 0 ] = astAnnul( nc[ 0 ] ); - if( nc[ 1 ] ) nc[ 1 ] = astAnnul( nc[ 1 ] ); - -/* If the neighbours could not merge, see if either swapped Mapping can - be simplified. */ - if( !swap ) { - smc0 = astSimplify( mc[0] ); - if( smc0 != mc[0] ) { - swap = 1; - } else { - smc1 = astSimplify( mc[1] ); - swap = ( smc1 != mc[1] ); - smc1 = astAnnul( smc1 ); - } - smc0 = astAnnul( smc0 ); - } - -/* If there is some point in swapping the Mappings, swap them in the - supplied lists. Otherwise annul the swapped Mappings. */ - if( swap ) { - (*map_list)[ i1 ] = astAnnul( (*map_list)[ i1 ] ); - (*map_list)[ i2 ] = astAnnul( (*map_list)[ i2 ] ); - (*map_list)[ i1 ] = mc[ 0 ]; - (*map_list)[ i2 ] = mc[ 1 ]; - (*invert_list)[ i1 ] = ic[ 0 ]; - (*invert_list)[ i2 ] = ic[ 1 ]; - result = i1; - break; - - } else { - mc[ 0 ] = astAnnul( mc[ 0 ] ); - mc[ 1 ] = astAnnul( mc[ 1 ] ); - } - } - } - } - } - -/* In parallel. */ -/* ============ */ -/* WinMaps are combined in parallel with neighbouring WinMaps, ZoomMaps and - UnitMaps. */ - } else { - -/* We first look to see if the WinMap can be merged with one of its - neighbours, resulting in a reduction of one in the number of Mappings - in the list. WinMaps can only merge directly with another WinMap, a - ZoomMap, or a UnitMap. */ - if( class1 && ( !strcmp( class1, "WinMap" ) || - !strcmp( class1, "ZoomMap" ) || - !strcmp( class1, "UnitMap" ) ) ){ - nclass = class1; - i1 = where - 1; - i2 = where; - - } else if( class2 && ( !strcmp( class2, "WinMap" ) || - !strcmp( class2, "ZoomMap" ) || - !strcmp( class2, "UnitMap" ) ) ){ - nclass = class2; - i1 = where; - i2 = where + 1; - - } else { - nclass = NULL; - } - -/* If the WinMap can merge with one of its neighbours, create the merged - Mapping. */ - if( nclass ){ - - if( !strcmp( nclass, "WinMap" ) ){ - newwm = WinWin( ( *map_list )[ i1 ], ( *map_list )[ i2 ], - ( *invert_list )[ i1 ], ( *invert_list )[ i2 ], - 0, status ); - invert = 0; - - } else if( !strcmp( nclass, "ZoomMap" ) ){ - if( i1 == where ){ - newwm = WinZoom( (AstWinMap *)( *map_list )[ i1 ], - (AstZoomMap *)( *map_list )[ i2 ], - ( *invert_list )[ i1 ], ( *invert_list )[ i2 ], 1, 0, status ); - } else { - newwm = WinZoom( (AstWinMap *)( *map_list )[ i2 ], - (AstZoomMap *)( *map_list )[ i1 ], - ( *invert_list )[ i2 ], ( *invert_list )[ i1 ], 0, 0, status ); - } - invert = 0; - - } else { - if( i1 == where ){ - newwm = WinUnit( (AstWinMap *)( *map_list )[ i1 ], - (AstUnitMap *)( *map_list )[ i2 ], - ( *invert_list )[ i1 ], 1, status ); - } else { - newwm = WinUnit( (AstWinMap *)( *map_list )[ i2 ], - (AstUnitMap *)( *map_list )[ i1 ], - ( *invert_list )[ i2 ], 0, status ); - } - invert = 0; - - } - -/* If succesfull... */ - if( astOK ){ - -/* Annul the first of the two Mappings, and replace it with the merged - WinMap. Also set the invert flag. */ - (void) astAnnul( ( *map_list )[ i1 ] ); - ( *map_list )[ i1 ] = (AstMapping *) newwm; - ( *invert_list )[ i1 ] = invert; - -/* Annul the second of the two Mappings, and shuffle down the rest of the - list to fill the gap. */ - (void) astAnnul( ( *map_list )[ i2 ] ); - for ( i = i2 + 1; i < *nmap; i++ ) { - ( *map_list )[ i - 1 ] = ( *map_list )[ i ]; - ( *invert_list )[ i - 1 ] = ( *invert_list )[ i ]; - } - -/* Clear the vacated element at the end. */ - ( *map_list )[ *nmap - 1 ] = NULL; - ( *invert_list )[ *nmap - 1 ] = 0; - -/* Decrement the Mapping count and return the index of the first - modified element. */ - ( *nmap )--; - result = i1; - - } - } - } - } - -/* Return the result. */ - return result; -} - -static int *MapSplit( AstMapping *this_map, int nin, const int *in, AstMapping **map, int *status ){ -/* -* Name: -* MapSplit - -* Purpose: -* Create a Mapping representing a subset of the inputs of an existing -* WinMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* int *MapSplit( AstMapping *this, int nin, const int *in, AstMapping **map, int *status ) - -* Class Membership: -* WinMap method (over-rides the protected astMapSplit method -* inherited from the Mapping class). - -* Description: -* This function creates a new Mapping by picking specified inputs from -* an existing WinMap. This is only possible if the specified inputs -* correspond to some subset of the WinMap outputs. That is, there -* must exist a subset of the WinMap outputs for which each output -* depends only on the selected WinMap inputs, and not on any of the -* inputs which have not been selected. If this condition is not met -* by the supplied WinMap, then a NULL Mapping is returned. - -* Parameters: -* this -* Pointer to the WinMap to be split (the WinMap is not actually -* modified by this function). -* nin -* The number of inputs to pick from "this". -* in -* Pointer to an array of indices (zero based) for the inputs which -* are to be picked. This array should have "nin" elements. If "Nin" -* is the number of inputs of the supplied WinMap, then each element -* should have a value in the range zero to Nin-1. -* map -* Address of a location at which to return a pointer to the new -* Mapping. This Mapping will have "nin" inputs (the number of -* outputs may be different to "nin"). A NULL pointer will be -* returned if the supplied WinMap has no subset of outputs which -* depend only on the selected inputs. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated array of ints. The number of -* elements in this array will equal the number of outputs for the -* returned Mapping. Each element will hold the index of the -* corresponding output in the supplied WinMap. The array should be -* freed using astFree when no longer needed. A NULL pointer will -* be returned if no output Mapping can be created. - -* Notes: -* - If this function is invoked with the global error status set, -* or if it should fail for any reason, then NULL values will be -* returned as the function value and for the "map" pointer. -*/ - -/* Local Variables: */ - AstWinMap *newwm; /* Pointer to returned WinMap */ - AstWinMap *this; /* Pointer to WinMap structure */ - double *a; /* Pointer to zero terms */ - double *b; /* Pointer to scale terms */ - int *result; /* Pointer to returned array */ - int i; /* Loop count */ - int iin; /* Mapping input index */ - int mnin; /* No. of Mapping inputs */ - int ok; /* Are input indices OK? */ - -/* Initialise */ - result = NULL; - *map = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the WinMap structure. */ - this = (AstWinMap *) this_map; - -/* Allocate memory for the returned array and create a WinMap with the - required number of axes and undefined corners. */ - result = astMalloc( sizeof( int )*(size_t) nin ); - newwm = astWinMap( nin, NULL, NULL, NULL, NULL, "", status ); - *map = (AstMapping *) newwm; - -/* Now get pointers to the scale and zero terms of the supplied WinMap - (these describe the forward transformation, taking into account the - setting of the Invert flag). */ - (void) astWinTerms( this , &a, &b ); - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* Store the required scale and zero terms from the supplied WinMap - in the new WinMap. At the same time check that each axis is valid. */ - mnin = astGetNin( this ); - ok = 1; - for( i = 0; i < nin; i++ ) { - iin = in[ i ]; - if( iin >= 0 && iin < mnin ) { - (newwm->a)[ i ] = a[ iin ]; - (newwm->b)[ i ] = b[ iin ]; - result[ i ] = iin; - } else { - ok = 0; - break; - } - } - -/* If the "in" array contained any invalid values, free the returned - resources. */ - if( !ok ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - } - -/* Free resources. */ - a = astFree( a ); - b = astFree( b ); - -/* Free returned resources if an error has occurred. */ - if( !astOK ) { - result = astFree( result ); - *map = astAnnul( *map ); - } - -/* Return the list of output indices. */ - return result; -} - -static void PermGet( AstPermMap *map, int **outperm, int **inperm, - double **consts, int *status ){ -/* -* Name: -* PermGet - -* Purpose: -* Get the axis permutation and constants array for a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* void PermGet( AstPermMap *map, int **outperm, int **inperm, -* double **const, int *status ) - -* Class Membership: -* WinMap member function - -* Description: -* This function returns axis permutation and constants arrays which can -* be used to create a PermMap which is equivalent to the supplied PermMap. - -* Parameters: -* map -* The PermMap. -* outperm -* An address at which to return a popinter to an array of ints -* holding the output axis permutation array. The array should be -* released using astFree when no longer needed. -* inperm -* An address at which to return a popinter to an array of ints -* holding the input axis permutation array. The array should be -* released using astFree when no longer needed. -* consts -* An address at which to return a popinter to an array of doubles -* holding the constants array. The array should be released using -* astFree when no longer needed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - NULL pointers are returned if an error has already occurred, or if -* this function should fail for any reason. -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* PointSet holding input positions for PermMap */ - AstPointSet *pset2; /* PointSet holding output positions for PermMap */ - double **ptr1; /* Pointer to pset1 data */ - double **ptr2; /* Pointer to pset2 data */ - double *cnst; /* Pointer to constants array */ - double cn; /* Potential new constant value */ - double ip; /* Potential output axis index */ - double op; /* Potential input axis index */ - int *inprm; /* Pointer to input axis permutation array */ - int *outprm; /* Pointer to output axis permutation array */ - int i; /* Axis count */ - int nc; /* Number of constants stored so far */ - int nin; /* No. of input coordinates for the PermMap */ - int nout; /* No. of output coordinates for the PermMap */ - -/* Initialise. */ - if( outperm ) *outperm = NULL; - if( inperm ) *inperm = NULL; - if( consts ) *consts = NULL; - -/* Check the global error status and the supplied pointers. */ - if ( !astOK || !outperm || !inperm || !consts ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - nc = 0; - -/* Get the number of input and output axes for the supplied PermMap. */ - nin = astGetNin( map ); - nout = astGetNout( map ); - -/* Allocate the memory for the returned arrays. */ - outprm = (int *) astMalloc( sizeof( int )* (size_t) nout ); - inprm = (int *) astMalloc( sizeof( int )* (size_t) nin ); - cnst = (double *) astMalloc( sizeof( double )* (size_t) ( nout + nin ) ); - -/* Returned the pointers to these arrays.*/ - *outperm = outprm; - *inperm = inprm; - *consts = cnst; - -/* Create two PointSets, each holding two points, which can be used for - input and output positions with the PermMap. */ - pset1 = astPointSet( 2, nin, "", status ); - pset2 = astPointSet( 2, nout, "", status ); - -/* Set up the two input positions to be [0,1,2...] and [-1,-1,-1,...]. The - first position is used to enumerate the axes, and the second is used to - check for constant axis values. */ - ptr1 = astGetPoints( pset1 ); - if( astOK ){ - for( i = 0; i < nin; i++ ){ - ptr1[ i ][ 0 ] = ( double ) i; - ptr1[ i ][ 1 ] = -1.0; - } - } - -/* Use the PermMap to transform these positions in the forward direction. */ - (void) astTransform( map, pset1, 1, pset2 ); - -/* Look at the mapped positions to determine the output axis permutation - array. */ - ptr2 = astGetPoints( pset2 ); - if( astOK ){ - -/* No constant axis valeus found yet. */ - nc = 0; - -/* Do each output axis. */ - for( i = 0; i < nout; i++ ){ - -/* If the output axis value is copied from an input axis value, the index - of the appropriate input axis will be in the mapped first position. */ - op = ptr2[ i ][ 0 ]; - -/* If the output axis value is assigned a constant value, the result of - mapping the two different input axis values will be the same. */ - cn = ptr2[ i ][ 1 ]; - if( op == cn ) { - -/* We have found another constant. Store it in the constants array, and - store the index of the constant in the output axis permutation array. */ - cnst[ nc ] = cn; - outprm[ i ] = -( nc + 1 ); - nc++; - -/* If the output axis values are different, then the output axis value - must be copied from the input axis value. */ - } else { - outprm[ i ] = (int) ( op + 0.5 ); - } - } - } - -/* Now do the same thing to determine the input permutation array. */ - if( astOK ){ - for( i = 0; i < nout; i++ ){ - ptr2[ i ][ 0 ] = ( double ) i; - ptr2[ i ][ 1 ] = -1.0; - } - } - - (void) astTransform( map, pset2, 0, pset1 ); - - if( astOK ){ - - for( i = 0; i < nin; i++ ){ - - ip = ptr1[ i ][ 0 ]; - cn = ptr1[ i ][ 1 ]; - if( ip == cn ) { - - cnst[ nc ] = cn; - inprm[ i ] = -( nc + 1 ); - nc++; - - } else { - inprm[ i ] = (int) ( ip + 0.5 ); - } - } - } - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* If an error has occurred, attempt to free the returned arrays. */ - if( !astOK ) { - *outperm = (int *) astFree( (void *) *outperm ); - *inperm = (int *) astFree( (void *) *inperm ); - *consts = (double *) astFree( (void *) *consts ); - } - -/* Return. */ - return; -} - -static double Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ){ -/* -* Name: -* Rate - -* Purpose: -* Calculate the rate of change of a Mapping output. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* result = Rate( AstMapping *this, double *at, int ax1, int ax2, int *status ) - -* Class Membership: -* WinMap member function (overrides the astRate method inherited -* from the Mapping class ). - -* Description: -* This function returns the rate of change of a specified output of -* the supplied Mapping with respect to a specified input, at a -* specified input position. - -* Parameters: -* this -* Pointer to the Mapping to be applied. -* at -* The address of an array holding the axis values at the position -* at which the rate of change is to be evaluated. The number of -* elements in this array should equal the number of inputs to the -* Mapping. -* ax1 -* The index of the Mapping output for which the rate of change is to -* be found (output numbering starts at 0 for the first output). -* ax2 -* The index of the Mapping input which is to be varied in order to -* find the rate of change (input numbering starts at 0 for the first -* input). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The rate of change of Mapping output "ax1" with respect to input -* "ax2", evaluated at "at", or AST__BAD if the value cannot be -* calculated. - -*/ - -/* Local Variables: */ - AstWinMap *map; - double result; - -/* Check inherited status */ - if( !astOK ) return AST__BAD; - -/* Get a pointer to the WinMap structure. */ - map = (AstWinMap *) this; - -/* If the input and output axes are not equal the result is zero. */ - if( ax1 != ax2 ) { - result = 0.0; - -/* Otherwise, return the scale factor for the axis, taking the reciprocal - if the WinMap has been inverted. */ - } else { - result = ( map->b )[ ax1 ]; - if( astGetInvert( map ) ) { - if( result != 0.0 && result != AST__BAD ) { - result = 1.0/result; - } else { - result = AST__BAD; - } - } - } - -/* Return the result. */ - return result; -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a WinMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* void SetAttrib( AstObject *this, const char *setting ) - -* Class Membership: -* WinMap member function (over-rides the astSetAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function assigns an attribute value for a WinMap, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the WinMap. -* setting -* Pointer to a null-terminated string specifying the new attribute -* value. -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* The WinMap class currently has no attributes, so pass it on to the parent - method for further interpretation. */ - (*parent_setattrib)( this_object, setting, status ); - -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a WinMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* WinMap member function (over-rides the astTestAttrib protected -* method inherited from the Mapping class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a WinMap's attributes. - -* Parameters: -* this -* Pointer to the WinMap. -* attrib -* Pointer to a null-terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* The WinMap class currently has no attributes, so pass it on to the parent - method for further interpretation. */ - result = (*parent_testattrib)( this_object, attrib, status ); - -/* Return the result, */ - return result; -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Apply a WinMap to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out, int *status ) - -* Class Membership: -* WinMap member function (over-rides the astTransform protected -* method inherited from the Mapping class). - -* Description: -* This function takes a WinMap and a set of points encapsulated in a -* PointSet and transforms the points so as to map them into the -* required window. - -* Parameters: -* this -* Pointer to the WinMap. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate transformation -* should be applied, while a zero value requests the inverse -* transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the WinMap being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstPointSet *result; /* Pointer to output PointSet */ - AstWinMap *map; /* Pointer to WinMap to be applied */ - const char *class; /* Object class */ - double **ptr_in; /* Pointer to input coordinate data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *axin; /* Pointer to next input axis value */ - double *axout; /* Pointer to next output axis value */ - double *a; /* Pointer to next constant term */ - double *b; /* Pointer to next multiplicative term */ - double aa; /* Constant term */ - double bb; /* Multiplicative term */ - int coord; /* Loop counter for coordinates */ - int def; /* Is mapping defined? */ - int ncoord; /* Number of coordinates per point */ - int npoint; /* Number of points */ - int point; /* Loop counter for points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - aa = 0.0; - bb = 0.0; - -/* Obtain a pointer to the WinMap. */ - map = (AstWinMap *) this; - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent Mapping class. This function validates - all arguments and generates an output PointSet if necessary, but does not - actually transform any coordinate values. */ - result = (*parent_transform)( this, in, forward, out, status ); - -/* We will now extend the parent astTransform method by performing the - calculations needed to generate the output coordinate values. */ - -/* Determine the numbers of points and coordinates per point from the input - PointSet and obtain pointers for accessing the input and output coordinate - values. */ - ncoord = astGetNcoord( in ); - npoint = astGetNpoint( in ); - ptr_in = astGetPoints( in ); - ptr_out = astGetPoints( result ); - -/* Determine whether to apply the forward or inverse mapping, according to the - direction specified and whether the mapping has been inverted. */ - if ( astGetInvert( map ) ) forward = !forward; - -/* Report an error if the WinMap does not contain any scales or shifts. */ - if( !(map->a && map->b) && astOK ){ - class = astGetClass( this ); - astError( AST__BADWM, "astTransform(%s): The supplied %s does not " - "contain any window information.", status, class, class ); - } - -/* Perform coordinate arithmetic. */ -/* ------------------------------ */ - if( astOK ){ - -/* Store pointers to the shift and scale for the next axis. */ - a = map->a; - b = map->b; - -/* Apply the mapping to each axis. */ - for( coord = 0; coord < ncoord; coord++ ){ - -/* If either the scale or shift is bad indicate that the mapping is - not defined on this axis. */ - if( *a == AST__BAD || *b == AST__BAD ){ - def = 0; - -/* Otherwise, get the scale and offset factors for this axis, taking account of - whether the mapping is inverted or not. If the mapping is undefined, set - the "def" flag to indicate this. */ - } else { - aa = *a; - bb = *b; - - if( forward ){ - def = 1; - - } else if( bb != 0.0 ){ - bb = 1.0/bb; - aa = -aa*bb; - def = 1; - - } else { - def = 0; - } - - } - -/* Store pointers to the first inpout and output values on this axis. */ - axin = ptr_in[ coord ]; - axout = ptr_out[ coord ]; - -/* If the mapping is defined, apply it to the supplied points. */ - if( def ){ - - for( point = 0; point < npoint; point++ ){ - if( *axin != AST__BAD ){ - *(axout++) = aa + bb*(*axin); - } else { - *(axout++) = AST__BAD; - } - axin++; - } - -/* If the mapping is not defined, store bad values on this axis in the - returned points. */ - } else { - for( point = 0; point < npoint; point++ ) *(axout++) = AST__BAD; - } - -/* Point to the scale and shift for the next axis. */ - a++; - b++; - } - - } - -/* Return a pointer to the output PointSet. */ - return result; -} - -static void WinMat( AstMapping **maps, int *inverts, int iwm, int *status ){ -/* -* Name: -* WinMat - -* Purpose: -* Swap a WinMap and a MatrixMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* void WinMat( AstMapping **maps, int *inverts, int iwm, int *status ) - -* Class Membership: -* WinMap member function - -* Description: -* A list of two Mappings is supplied containing a WinMap and a -* MatrixMap. These Mappings are annulled, and replaced with -* another pair of Mappings consisting of a WinMap and a MatrixMap -* in the opposite order. These Mappings are chosen so that their -* combined effect is the same as the original pair of Mappings. -* The scale factors in the returned WinMap are always unity (i.e. -* the differences in scaling get absorbed into the returned -* MatrixMap). - -* Parameters: -* maps -* A pointer to an array of two Mapping pointers. -* inverts -* A pointer to an array of two invert flags. -* iwm -* The index within "maps" of the WinMap. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMatrixMap *m1; /* Pointer to Diagonal scale factor MatrixMap */ - AstMatrixMap *m2; /* Pointer to returned MatrixMap */ - AstMatrixMap *sm2; /* Pointer to simplified returned MatrixMap */ - AstMatrixMap *mm; /* Pointer to the supplied MatrixMap */ - AstPointSet *pset1; /* Shift terms from supplied WinMap */ - AstPointSet *pset2; /* Shift terms for returned WinMap */ - AstWinMap *w1; /* Pointer to the returned WinMap */ - AstWinMap *sw1; /* Pointer to the simplified returned WinMap */ - AstWinMap *wm; /* Pointer to the supplied WinMap */ - double **ptr1; /* Pointer to pset1 data */ - double **ptr2; /* Pointer to pset2 data */ - double *a; /* Array of shift terms from supplied WinMap */ - double *aa; /* Pointer to next shift term */ - double *b; /* Array of scale terms from supplied WinMap */ - double *bb; /* Pointer to next scale term */ - int i; /* Axis count */ - int nin; /* No. of axes in supplied WinMap */ - int nout; /* No. of axes in returned WinMap */ - int old_minv; /* Invert value for the supplied MatrixMap */ - int old_winv; /* Invert value for the supplied WinMap */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store pointers to the supplied WinMap and the MatrixMap. */ - wm = (AstWinMap *) maps[ iwm ]; - mm = (AstMatrixMap *) maps[ 1 - iwm ]; - -/* Temporarily set the Invert attribute of the supplied Mappings to the - supplied values. */ - old_winv = astGetInvert( wm ); - astSetInvert( wm, inverts[ iwm ] ); - - old_minv = astGetInvert( mm ); - astSetInvert( mm, inverts[ 1 - iwm ] ); - -/* Get copies of the shift and scale terms used by the WinMap. This - also returns the number of axes in the WinMap. */ - nin = astWinTerms( wm, &a, &b ); - -/* Create a diagonal MatrixMap holding the scale factors from the - supplied WinMap. */ - m1 = astMatrixMap( nin, nin, 1, b, "", status ); - -/* Create a PointSet holding a single position given by the shift terms - in the supplied WinMap. */ - pset1 = astPointSet( 1, nin, "", status ); - ptr1 = astGetPoints( pset1 ); - if( astOK ){ - aa = a; - for( i = 0; i < nin; i++ ) ptr1[ i ][ 0 ] = *(aa++); - } - -/* First deal with cases when the WinMap is applied first, followed by - the MatrixMap. */ - if( iwm == 0 ){ - -/* Multiply the diagonal matrix holding the WinMap scale factors by the - supplied matrix. The resulting MatrixMap is the one to return in the - map list. */ - m2 = astMtrMult( m1, mm ); - -/* Transform the position given by the shift terms from the supplied - WinMap using the supplied MatrixMap to get the shift terms for - the returned WinMap. */ - pset2 = astTransform( mm, pset1, 1, NULL ); - -/* Now deal with cases when the MatrixMap is applied first, followed by - the WinMap. */ - } else { - -/* Multiply the supplied MatrixMap by the diagonal matrix holding scale - factors from the supplied WinMap. The resulting MatrixMap is the one to - return in the map list. */ - m2 = astMtrMult( mm, m1 ); - -/* Transform the position given by the shift terms from the supplied - WinMap using the inverse of the returned MatrixMap to get the shift - terms for the returned WinMap. */ - pset2 = astTransform( m2, pset1, 0, NULL ); - - } - -/* Re-instate the original value of the Invert attributes of the supplied - Mappings. */ - astSetInvert( wm, old_winv ); - astSetInvert( mm, old_minv ); - -/* Get pointers to the shift terms for the returned WinMap. */ - ptr2 = astGetPoints( pset2 ); - -/* Create the returned WinMap, initially with undefined corners. The number of - axes in the WinMap must equal the number of shift terms. */ - nout = astGetNcoord( pset2 ); - w1 = astWinMap( nout, NULL, NULL, NULL, NULL, "", status ); - -/* If succesful, store the scale and shift terms in the WinMap. The scale - terms are always unity. */ - if( astOK ){ - bb = w1->b; - aa = w1->a; - for( i = 0; i < nout; i++ ) { - *(bb++) = 1.0; - *(aa++) = ptr2[ i ][ 0 ]; - } - -/* Replace the supplied Mappings and invert flags with the ones found - above. Remember that the order of the Mappings is now swapped */ - (void) astAnnul( maps[ 0 ] ); - (void) astAnnul( maps[ 1 ] ); - - sw1 = astSimplify( w1 ); - w1 = astAnnul( w1 ); - - maps[ 1 - iwm ] = (AstMapping *) sw1; - inverts[ 1 - iwm ] = astGetInvert( sw1 ); - - sm2 = astSimplify( m2 ); - m2 = astAnnul( m2 ); - - maps[ iwm ] = (AstMapping *) sm2; - inverts[ iwm ] = astGetInvert( sm2 ); - - } - -/* Annul the MatrixMap and PointSet holding the scale and shift terms from the - supplied WinMap. */ - m1 = astAnnul( m1 ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Free the copies of the scale and shift terms from the supplied WinMap. */ - b = (double *) astFree( (void *) b ); - a = (double *) astFree( (void *) a ); - -/* Return. */ - return; -} - -static void WinWcs( AstMapping **maps, int *inverts, int iwm, int *status ){ -/* -* Name: -* WinWcs - -* Purpose: -* Swap a WinMap and a WcsMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* void WinWcs( AstMapping **maps, int *inverts, int iwm, int *status ) - -* Class Membership: -* WinMap member function - -* Description: -* A list of two Mappings is supplied containing a WinMap and a -* WcsMap. These Mappings are swapped. - -* Parameters: -* maps -* A pointer to an array of two Mapping pointers. -* inverts -* A pointer to an array of two invert flags. -* iwm -* The index within "maps" of the WinMap. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstMapping *m1; /* Pointer to a Mapping */ - int inv; /* Invert value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Simply swap the values (the CanSwap function will have checked that - the WcsMap and WinMap can simply be swapped). */ - m1 = maps[ 0 ]; - maps[ 0 ] = maps[ 1 ]; - maps[ 1 ] = m1; - - inv = inverts[ 0 ]; - inverts[ 0 ] = inverts[ 1 ]; - inverts[ 1 ] = inv; - -/* Return. */ - return; -} - -static void WinPerm( AstMapping **maps, int *inverts, int iwm, int *status ){ -/* -* Name: -* WinPerm - -* Purpose: -* Swap a WinMap and a PermMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* void WinPerm( AstMapping **maps, int *inverts, int iwm, int *status ) - -* Class Membership: -* WinMap member function - -* Description: -* A list of two Mappings is supplied containing a WinMap and a -* PermMap. These Mappings are annulled, and replaced with -* another pair of Mappings consisting of a WinMap and a PermMap -* in the opposite order. These Mappings are chosen so that their -* combined effect is the same as the original pair of Mappings. - -* Parameters: -* maps -* A pointer to an array of two Mapping pointers. -* inverts -* A pointer to an array of two invert flags. -* iwm -* The index within "maps" of the WinMap. -* status -* Pointer to the inherited status variable. - -* Notes: -* - All links between input and output axes in the PermMap must -* be bi-directional, but there can be unconnected axes, and there -* need not be the same number of input and output axes. - -*/ - -/* Local Variables: */ - AstPermMap *pm; /* Pointer to the supplied PermMap */ - AstPermMap *p1; /* Pointer to the returned PermMap */ - AstPermMap *sp1; /* Pointer to the simplified returned PermMap */ - AstWinMap *w1; /* Pointer to the returned WinMap */ - AstWinMap *sw1; /* Pointer to the simplified returned PermMap */ - AstWinMap *wm; /* Pointer to the supplied WinMap */ - double *a; /* Array of shift terms from supplied WinMap */ - double *aa; /* Pointer to next shift term */ - double *b; /* Array of scale terms from supplied WinMap */ - double *bb; /* Pointer to next scale term */ - double *consts; /* Pointer to constants array */ - double c; /* A constant value */ - int *inperm; /* Pointer to input axis permutation array */ - int *outperm; /* Pointer to output axis permutation array */ - int i; /* Axis count */ - int j; /* Axis index */ - int nin; /* No. of axes in supplied WinMap */ - int npin; /* No. of input axes in supplied PermMap */ - int npout; /* No. of output axes in supplied PermMap */ - int old_pinv; /* Invert value for the supplied PermMap */ - int old_winv; /* Invert value for the supplied WinMap */ - - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - p1 = NULL; - w1 = NULL; - -/* Store pointers to the supplied WinMap and the PermMap. */ - wm = (AstWinMap *) maps[ iwm ]; - pm = (AstPermMap *) maps[ 1 - iwm ]; - -/* Temporarily set the Invert attribute of the supplied Mappings to the - supplied values. */ - old_winv = astGetInvert( wm ); - astSetInvert( wm, inverts[ iwm ] ); - - old_pinv = astGetInvert( pm ); - astSetInvert( pm, inverts[ 1 - iwm ] ); - -/* Get copies of the shift and scale terms used by the WinMap. This - also returns the number of axes in the WinMap. */ - nin = astWinTerms( wm, &a, &b ); - -/* Get the axis permutation and constants arrays representing the - PermMap. Note, no constants are used more than once in the returned - arrays (i.e. duplicate constants are returned in "consts" if more than - one axis uses a given constant). */ - PermGet( pm, &outperm, &inperm, &consts, status ); - - if( astOK ) { - -/* Get the number of input and output axes in the PermMap. */ - npin = astGetNin( pm ); - npout = astGetNout( pm ); - -/* First consider cases where the WinMap is applied first, followed by the - PermMap. */ - if( iwm == 0 ) { - -/* Create the new WinMap, initially with undefined corners. Its number - of axes will equal the number of output axes of the PermMap. */ - w1 = astWinMap( npout, NULL, NULL, NULL, NULL, "", status ); - -/* Get pointers to the scale and shift terms for the new WinMap. */ - bb = w1->b; - aa = w1->a; - -/* Thinking of the forward CmpMap first, consider each of the output axes of - the PermMap. */ - for( i = 0; i < npout; i++ ){ - -/* If the value for this output axis is derived from an input axis, copy the - scale and shift terms from the corresponding input axis to the new - WinMap. */ - j = outperm[ i ]; - if( j >= 0 && j < nin ) { - aa[ i ] = a[ j ]; - bb[ i ] = b[ j ]; - -/* If this output axis is assigned a constant value, use zero and one for - the shift and scale in order to preserve the constant value produced - by the PermMap. */ - } else { - aa[ i ] = 0.0; - bb[ i ] = 1.0; - } - - } - -/* Now consider the inverse CmpMap. Any constants produced by the inverse - PermMap would previously have been scaled by the inverse WinMap. Since - there will be no inverse WinMap to perform this scaling in the returned - Mappings, we need to change the constant values to be the values after - the scaling which would have been applied by the WinMap. Consider each - of the input axes of the PermMap.*/ - for( i = 0; i < npin; i++ ){ - -/* Skip axes which are not assigned a constant value. */ - if( inperm[ i ] < 0 ) { - -/* Scale the constant term associated with this input axis using the - inverse WinMap unless it is AST__BAD. */ - c = consts[ -inperm[ i ] - 1 ]; - if( c != AST__BAD ) { - - if( a[ i ] != AST__BAD && b[ i ] != AST__BAD && - b[ i ] != 0.0 ) { - consts[ -inperm[ i ] - 1 ] = ( c - a[ i ] )/b[ i ]; - } else { - consts[ -inperm[ i ] - 1 ] = AST__BAD; - } - - } - - } - - } - -/* Now consider cases where the PermMap is applied first, followed by the - WinMap. */ - } else { - -/* Create the new WinMap, initially with undefined corners. Its number - of axes will equal the number of input axes of the PermMap. */ - w1 = astWinMap( npin, NULL, NULL, NULL, NULL, "", status ); - -/* Get pointers to the scale and shift terms for the new WinMap. */ - bb = w1->b; - aa = w1->a; - -/* Thinking first about the inverse WinMap, consider each of the input axes - of the PermMap. */ - for( i = 0; i < npin; i++ ){ - -/* If the value for this input axis is derived from an output axis, copy the - scale and shift terms from the corresponding output axis to the new - WinMap. */ - j = inperm[ i ]; - if( j >= 0 && j < nin ) { - aa[ i ] = a[ j ]; - bb[ i ] = b[ j ]; - -/* If this input axis is assigned a constant value, use zero and one for - the shift and scale in order to preserve the constant value produced - by the PermMap. */ - } else { - aa[ i ] = 0.0; - bb[ i ] = 1.0; - } - - } - -/* Now consider the forward WinMap. Any constants produced by the forward - PermMap would previously have been scaled by the forward WinMap. Since - there will be no forward WinMap to perform this scaling in the returned - Mappings, we need to change the constant values to be the values after - the scaling which would have been applied by the WinMap. Consider each - of the output axes of the PermMap.*/ - for( i = 0; i < npout; i++ ){ - -/* Skip axes which are not assigned a constant value. */ - if( outperm[ i ] < 0 ) { - -/* Scale the constant term associated with this input axis using the - forward WinMap unless it is AST__BAD. */ - c = consts[ -outperm[ i ] - 1 ]; - if( c != AST__BAD ) { - - if( a[ i ] != AST__BAD && b[ i ] != AST__BAD ) { - consts[ -outperm[ i ] - 1 ] = a[ i ] + c*b[ i ]; - } else { - consts[ -outperm[ i ] - 1 ] = AST__BAD; - } - - } - - } - - } - - } - -/* Create a new PermMap (since the constants may have changed). */ - p1 = astPermMap( npin, inperm, npout, outperm, consts, "", status ); - -/* Free the axis permutation and constants arrays. */ - outperm = (int *) astFree( (void *) outperm ); - inperm = (int *) astFree( (void *) inperm ); - consts = (double *) astFree( (void *) consts ); - } - -/* Re-instate the original value of the Invert attributes of the supplied - Mappings. */ - astSetInvert( wm, old_winv ); - astSetInvert( pm, old_pinv ); - -/* Replace the supplied Mappings with the ones created above, swapping the - order. */ - if( astOK ){ - (void) astAnnul( wm ); - (void) astAnnul( pm ); - - sp1 = astSimplify( p1 ); - p1 = astAnnul( p1 ); - - sw1 = astSimplify( w1 ); - w1 = astAnnul( w1 ); - - maps[ iwm ] = (AstMapping *) sp1; - inverts[ iwm ] = 0; - - maps[ 1 - iwm ] = (AstMapping *) sw1; - inverts[ 1 - iwm ] = astGetInvert( sw1 ); - } - -/* Free the copies of the scale and shift terms from the supplied WinMap. */ - b = (double *) astFree( (void *) b ); - a = (double *) astFree( (void *) a ); - -/* Return. */ - return; -} - -static int WinTerms( AstWinMap *this, double **shift, double **scale, int *status ){ -/* -*+ -* Name: -* astWinTerms - -* Purpose: -* Obtain the scale and shift terms used by a WinMap. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "winmap.h" -* int astWinTerms( AstWinMap *this, double **shift, double **scale ) - -* Class Membership: -* WinMap mewthod. - -* Description: -* This function returns copies of the scale and shift terms used by a -* WinMap when transforming points. Each axis of the WinMap has a scale -* term B, and a shift term A, and the transformation of a point is done -* by applying these to each input axis value X in turn, to get the -* output axis value B.X + A. The returned terms take into account the -* current setting of the Invert attribute of the WinMap. - -* Parameters: -* this -* Pointer to the WinMap. -* shift -* The address of a location at which to return a pointer to the -* start of a dynamically allocated array holding the shift terms -* for each axis. -* scale -* The address of a location at which to return a pointer to the -* start of a dynamically allocated array holding the scale terms -* for each axis. - -* Returned Value: -* The number of axes in the WinMap. This is the same as the number of -* elements in the returned arrays. - -* Notes: -* - The returned arrays should be released using astFree when no -* longer needed. -* - NULL pointers can be supplied for "scale" or "shift" if the -* corresponding arrays are not required. -* - A value of zero will be returned, together with NULL pointers -* for "scale" and "shift" if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - double *a; /* Pointer to a copy of the shift term array */ - double *aa; /* Pointer to the next shift term */ - double *b; /* Pointer to a copy of the scale term array */ - double *bb; /* Pointer to the next scale term */ - int i; /* Axis count */ - int result; /* The returned number of axes */ - size_t absize; /* Size of shift and scale arrays */ - -/* Initialise. */ - result = 0; - if( scale ) *scale = NULL; - if( shift ) *shift = NULL; - -/* Check the global status. */ - if ( !astOK ) return result; - -/* Get the number of axes in the WinMap. */ - result = astGetNin( this ); - -/* Create copies of the scale and shift terms from the WinMap. */ - absize = sizeof( double )*(size_t) result; - b = (double *) astStore( NULL, (void *) this->b, absize ); - a = (double *) astStore( NULL, (void *) this->a, absize ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* If the WinMap is inverted, replace the scale and shift terms - by the corresponding values for the inverted mapping. */ - if( astGetInvert( this ) ){ - bb = b; - aa = a; - - for( i = 0; i < result; i++ ){ - if( *aa != AST__BAD && *bb != 0.0 && *bb != AST__BAD ){ - *bb = 1.0/(*bb); - *aa *= -(*bb); - } else { - *bb = AST__BAD; - *aa = AST__BAD; - } - - aa++; - bb++; - - } - } - -/* Store the required pointers, and free arrays which are not required. */ - if( scale ){ - *scale = b; - } else { - b = (double *) astFree( (void *) b ); - } - - if( shift ){ - *shift = a; - } else { - a = (double *) astFree( (void *) a ); - } - - } - -/* If an error has occurred, free the arrays and return zero. */ - if( !astOK ){ - if( scale ) *scale = (double *) astFree( (void *) *scale ); - if( shift ) *shift = (double *) astFree( (void *) *shift ); - result = 0; - } - -/* Return the answer. */ - return result; - -} - -static AstWinMap *WinUnit( AstWinMap *wm, AstUnitMap *um, int winv, - int win1, int *status ){ -/* -* Name: -* WinUnit - -* Purpose: -* Create a WinMap by merging a WinMap and a UnitMap in parallel. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* AstWinMap *WinUnit( AstWinMap *wm, AstUnitMap *um, int winv, int win1, int *status ) - -* Class Membership: -* WinMap member function - -* Description: -* This function creates a new WinMap which performs a mapping -* equivalent to applying the two supplied Mappings in parallel in -* the directions specified by the "invert" flag (the Invert -* attribute of the supplied WinMap is ignored). - -* Parameters: -* wm -* A pointer to the WinMap. -* um -* A pointer to the UnitMap. -* winv -* The invert flag to use with wm. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* win1 -* Indicates the order in which the Mappings should be applied. -* -* If win1 is non-zero: -* "wm" applies to the lower axis indices and "um" to the upper -* axis indices. -* -* If win1 is zero: -* "um" applies to the lower axis indices and "wm" to the upper -* axis indices. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new WinMap. - -* Notes: -* - The forward direction of the returned WinMap is equivalent to the -* combined effect of the two supplied Mappings, operating in the -* directions specified by "winv". -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstWinMap *result; /* Pointer to output WinMap */ - double *a; /* Pointer to shift term array */ - double *aa; /* Pointer to next shift term */ - double *ar; /* Pointer to next shift term in result */ - double *b; /* Pointer to scale term array */ - double *bb; /* Pointer to next scale term */ - double *br; /* Pointer to next scale term in result */ - int i; /* Axis index */ - int ninw; /* No. of axes in the WinMap */ - int ninu; /* No. of axes in the UnitMap */ - int old_winv; /* Original setting of WinMap Invert attribute */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the returned pointer. */ - result = NULL; - -/* Temporarily set the Invert attribute of the WinMap to the supplied - value. */ - old_winv = astGetInvert( wm ); - astSetInvert( wm, winv ); - -/* Create copies of the scale and shift terms from the WinMap, and store the - number of axes in it. */ - ninw = astWinTerms( wm, &a, &b ); - -/* Get the number of axes in the UnitMap. */ - ninu = astGetNin( um ); - -/* Create the merged WinMap with unspecified corners. */ - result = astWinMap( ninw + ninu, NULL, NULL, NULL, NULL, "", status ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* If the WinMap applies to the lower axis indices... */ - if( win1 ){ - -/* Use the scale and shift terms from the WinMap for the lower axes of - the new WinMap. */ - aa = a; - bb = b; - ar = result->a; - br = result->b; - - for( i = 0; i < ninw; i++ ){ - *(ar++) = *(aa++); - *(br++) = *(bb++); - } - -/* Use the scale factor to 1.0 and the shift term to zero for the upper axes - of the new WinMap. */ - for( i = 0; i < ninu; i++ ){ - *(ar++) = 0.0; - *(br++) = 1.0; - } - -/* If the WinMap applies to the upper axis indices... */ - } else { - -/* Use the scale factor to 1.0 and the shift term to zero for the lower axes - of the new WinMap. */ - ar = result->a; - br = result->b; - - for( i = 0; i < ninu; i++ ){ - *(ar++) = 0.0; - *(br++) = 1.0; - } - -/* Use the scale and shift terms from the WinMap for the upper axes of - the new WinMap. */ - aa = a; - bb = b; - - for( i = 0; i < ninw; i++ ){ - *(ar++) = *(aa++); - *(br++) = *(bb++); - } - } - } - -/* Free the copies of the scale and shift terms from the supplied WinMap. */ - b = (double *) astFree( (void *) b ); - a = (double *) astFree( (void *) a ); - -/* Re-instate the original setting of the Invert attribute for the - supplied WinMap. */ - astSetInvert( wm, old_winv ); - -/* If an error has occurred, annull the returned WinMap. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output WinMap. */ - return result; -} - -static AstWinMap *WinWin( AstMapping *map1, AstMapping *map2, int inv1, - int inv2, int series, int *status ){ -/* -* Name: -* WinWin - -* Purpose: -* Create a merged WinMap from two supplied WinMaps. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* AstWinMap *WinWin( AstMapping *map1, AstMapping *map2, int inv1, -* int inv2, int series, int *status ) - -* Class Membership: -* WinMap member function - -* Description: -* This function creates a new WinMap which performs a mapping -* equivalent to applying the two supplied WinMaps either in series -* or parallel in the directions specified by the "invert" flags -* (the Invert attributes of the supplied WinMaps are ignored). - -* Parameters: -* map1 -* A pointer to the WinMap to apply first (if in series), or to the -* lower axis indices (if in parallel) -* map2 -* A pointer to the WinMap to apply second (if in series), or to the -* upper axis indices (if in parallel) -* inv1 -* The invert flag to use with map1. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* inv2 -* The invert flag to use with map2. -* series -* If non-zero, then the supplied WinMaps are combined in series. -* Otherwise, they are combined in parallel. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new WinMap. - -* Notes: -* - The forward direction of the returned WinMap is equivalent to the -* combined effect of the two supplied WinMap, operating in the -* directions specified by "inv1" and "inv2". -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstWinMap *result; /* Pointer to output WinMap */ - AstWinMap *wm1; /* Pointer to the first supplied WinMap */ - AstWinMap *wm2; /* Pointer to the second supplied WinMap */ - double *a[ 2 ]; /* Pointers to shift term arrays */ - double *a0; /* Pointer to next shift term from WinMap 1 */ - double *a1; /* Pointer to next shift term from WinMap 2 */ - double *ar; /* Pointer to next shift term in result */ - double *b[ 2 ]; /* Pointers to scale term arrays */ - double *b0; /* Pointer to next scale term from WinMap 1 */ - double *b1; /* Pointer to next scale term from WinMap 2 */ - double *br; /* Pointer to next scale term in result */ - double amean; /* Geometric mean of the offset terms */ - int cancel; /* Do the two WinMaps cancel out? */ - int i; /* Axis index */ - int invert[ 2 ]; /* Array of invert flags */ - int nin[ 2 ]; /* No. of axes in the two WinMaps */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the returned pointer. */ - result = NULL; - -/* Store pointers to the WinMaps. */ - wm1 = (AstWinMap *) map1; - wm2 = (AstWinMap *) map2; - -/* Temporarily set their Invert attributes to the supplied values. */ - invert[ 0 ] = astGetInvert( wm1 ); - astSetInvert( wm1, inv1 ); - - invert[ 1 ] = astGetInvert( wm2 ); - astSetInvert( wm2, inv2 ); - -/* Create copies of the scale and shift terms from the two WinMaps, - and store the number of axes in each WinMap. The scale and shift terms - returned take into account the setting of the Invert attribute. */ - nin[ 0 ] = astWinTerms( wm1, a, b ); - nin[ 1 ] = astWinTerms( wm2, a + 1, b + 1 ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Series */ -/* ====== */ - if( series ){ - -/* Check for equal and opposite WinMaps. Do this explicitly using the - supplied Mappings rather than the values returned by astWinTerms to - avoid the affects of rounding errors in the inversions performed by - astWinTerms. */ - if( ( inv1 == 0 ) != ( inv2 == 0 ) ) { - cancel = 1; - for( i = 0; i < nin[ 0 ]; i++ ){ - if( !astEQUAL( (wm1->a)[ i ], (wm2->a)[ i ] ) || - !astEQUAL( (wm1->b)[ i ], (wm2->b)[ i ] ) ) { - cancel = 0; - break; - } - } - } else { - cancel = 0; - } - -/* If they cancel, just put unit values into the WinMap. */ - if( cancel ) { - a0 = a[ 0 ]; - b0 = b[ 0 ]; - for( i = 0; i < nin[ 0 ]; i++ ){ - *(a0++) = 0.0; - *(b0++) = 1.0; - } - -/* Otherwise, merge the scale and shift terms for the two WinMaps, overwriting - the terms for the first WinMap. To be merged in series, both WinMaps must - have the same number of axes, so it matters not whether we use nin[ 0 ] - or nin[ 1 ] to specify the number of axes. Include rounding checks for values - close to a unit mapping. */ - } else { - a0 = a[ 0 ]; - b0 = b[ 0 ]; - a1 = a[ 1 ]; - b1 = b[ 1 ]; - for( i = 0; i < nin[ 0 ]; i++ ){ - - if( *a0 != AST__BAD && *b0 != AST__BAD && - *a1 != AST__BAD && *b1 != AST__BAD ){ - - amean = sqrt(fabs((*a0)*(*a1))); - - *a0 *= (*b1); - *a0 += (*a1); - *b0 *= (*b1); - - if( fabs( *a0 ) < amean*1E-15 ) *a0 = 0.0; - if( fabs( *b0 - 1.0 ) < 1E-15 ) *b0 = 1.0; - - } else { - *a0 = AST__BAD; - *b0 = AST__BAD; - *a1 = AST__BAD; - *b1 = AST__BAD; - } - -/* Move on to the next axis. */ - a0++; - b0++; - a1++; - b1++; - } - } - -/* Create the merged WinMap with unspecified corners. */ - result = astWinMap( nin[ 0 ], NULL, NULL, NULL, NULL, "", status ); - -/* Store the merged scale and shift terms in the new WinMap. The forward - transformation of this WinMap then corresponds to the combination of the - two supplied WinMaps, taking into account their invert flags. */ - a0 = a[ 0 ]; - b0 = b[ 0 ]; - ar = result->a; - br = result->b; - for( i = 0; i < nin[ 0 ]; i++ ){ - *(ar++) = *(a0++); - *(br++) = *(b0++); - } - -/* Parallel */ -/* ======== */ - } else { - -/* Create the merged WinMap with unspecified corners. */ - result = astWinMap( nin[ 0 ] + nin[ 1 ], NULL, NULL, NULL, NULL, "", status ); - -/* Copy the scale and shift terms into the new WinMap. */ - a0 = a[ 0 ]; - b0 = b[ 0 ]; - a1 = a[ 1 ]; - b1 = b[ 1 ]; - ar = result->a; - br = result->b; - - for( i = 0; i < nin[ 0 ]; i++ ){ - *(ar++) = *(a0++); - *(br++) = *(b0++); - } - - for( i = 0; i < nin[ 1 ]; i++ ){ - *(ar++) = *(a1++); - *(br++) = *(b1++); - } - } - } - -/* Re-instate the original settings of the Invert attributes for the - supplied WinMaps. */ - astSetInvert( wm1, invert[ 0 ] ); - astSetInvert( wm2, invert[ 1 ] ); - -/* Free the memory. */ - a[ 0 ] = (double *) astFree( (void *) a[ 0 ] ); - b[ 0 ] = (double *) astFree( (void *) b[ 0 ] ); - a[ 1 ] = (double *) astFree( (void *) a[ 1 ] ); - b[ 1 ] = (double *) astFree( (void *) b[ 1 ] ); - -/* If an error has occurred, annull the returned WinMap. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output WinMap. */ - return result; -} - -static AstWinMap *WinZoom( AstWinMap *wm, AstZoomMap *zm, int winv, - int zinv, int win1, int series, int *status ){ -/* -* Name: -* WinZoom - -* Purpose: -* Create a WinMap by merging a WinMap and a ZoomMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* AstWinMap *WinZoom( AstWinMap *wm, AstZoomMap *zm, int winv, -* int zinv, int win1, int series, int *status ) - -* Class Membership: -* WinMap member function - -* Description: -* This function creates a new WinMap which performs a mapping -* equivalent to applying the two supplied Mappings in series or -* parallel in the directions specified by the "invert" flags (the -* Invert attributes of the supplied WinMaps are ignored). - -* Parameters: -* wm -* A pointer to the WinMap. -* zm -* A pointer to the ZoomMap. -* winv -* The invert flag to use with wm. A value of zero causes the forward -* mapping to be used, and a non-zero value causes the inverse -* mapping to be used. -* zinv -* The invert flag to use with zm. -* win1 -* Indicates the order in which the Mappings should be applied. -* -* If win1 is non-zero: -* If in series: -* "wm" is applied first followed by "zm". -* If in parallel: -* "wm" applies to the lower axis indices and "zm" to the upper -* axis indices. -* -* If win1 is zero: -* If in series: -* "zm" is applied first followed by "wm". -* If in parallel: -* "zm" applies to the lower axis indices and "wm" to the upper -* axis indices. -* series -* Should be supplied non-zero if the Mappings are to be combined in -* series. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the new WinMap. - -* Notes: -* - The forward direction of the returned WinMap is equivalent to the -* combined effect of the two supplied Mappings, operating in the -* directions specified by "zinv" and "winv". -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstWinMap *result; /* Pointer to output WinMap */ - double *a; /* Pointer to shift term array */ - double *aa; /* Pointer to next shift term */ - double *ar; /* Pointer to next shift term in result */ - double *b; /* Pointer to scale term array */ - double *bb; /* Pointer to next scale term */ - double *br; /* Pointer to next scale term in result */ - double zfac; /* Zoom factor */ - int i; /* Axis index */ - int ninw; /* No. of axes in the WinMap */ - int ninz; /* No. of axes in the ZoomMap */ - int old_winv; /* Original setting of WinMap Invert attribute */ - int old_zinv; /* Original setting of ZoomMap Invert attribute */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Initialise the returned pointer. */ - result = NULL; - -/* Temporarily set the Invert attributes of both Mappings to the supplied - values. */ - old_winv = astGetInvert( wm ); - astSetInvert( wm, winv ); - - old_zinv = astGetInvert( zm ); - astSetInvert( zm, zinv ); - -/* Get the zoom factor implemented by the ZoomMap. Invert it if necessary - since astGetZoom does not take account of the Invert setting. */ - zfac = astGetZoom( zm ); - if( zinv ) zfac = 1.0 / zfac; - -/* Create copies of the scale and shift terms from the WinMap, and store the - number of axes in it. */ - ninw = astWinTerms( wm, &a, &b ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* First do series mode... */ - if( series ) { - -/* Modify the WinMap scale and shift terms by the zoom factor. How this is - done depends on which way round the Mappings are applied. */ - bb = b; - aa = a; - - for( i = 0; i < ninw; i++ ){ - - if( *aa != AST__BAD && *bb != AST__BAD && zfac != AST__BAD ){ - *bb *= zfac; - if( win1 ) *aa *= zfac; - } else { - *bb = AST__BAD; - *aa = AST__BAD; - } - - aa++; - bb++; - } - -/* Create the merged WinMap with unspecified corners. */ - result = astWinMap( ninw, NULL, NULL, NULL, NULL, "", status ); - -/* Store the merged scale and shift terms in the new WinMap. The forward - transformation of this WinMap then corresponds to the combination of the - two supplied Mappings, taking into account their invert flags. */ - aa = a; - bb = b; - ar = result->a; - br = result->b; - for( i = 0; i < ninw; i++ ){ - *(ar++) = *(aa++); - *(br++) = *(bb++); - } - -/* Now do parallel mode... */ - } else { - -/* Get the number of axes in the ZoomMap. */ - ninz = astGetNin( zm ); - -/* Create the merged WinMap with unspecified corners. */ - result = astWinMap( ninw + ninz, NULL, NULL, NULL, NULL, "", status ); - -/* If the WinMap applies to the lower axis indices... */ - if( win1 ) { - -/* Use the scale and shift terms from the WinMap for the lower axes of - the new WinMap. */ - aa = a; - bb = b; - ar = result->a; - br = result->b; - - for( i = 0; i < ninw; i++ ){ - *(ar++) = *(aa++); - *(br++) = *(bb++); - } - -/* Use the scale factor (with zero shift) from the ZoomMap for the upper axes - of the new WinMap. */ - for( i = 0; i < ninz; i++ ){ - *(ar++) = 0.0; - *(br++) = zfac; - } - -/* If the WinMap applies to the upper axis indices... */ - } else { - -/* Use the scale factor (with zero shift) from the ZoomMap for the lower axes - of the new WinMap. */ - ar = result->a; - br = result->b; - - for( i = 0; i < ninz; i++ ){ - *(ar++) = 0.0; - *(br++) = zfac; - } - -/* Use the scale and shift terms from the WinMap for the upper axes of - the new WinMap. */ - aa = a; - bb = b; - - for( i = 0; i < ninw; i++ ){ - *(ar++) = *(aa++); - *(br++) = *(bb++); - } - } - } - } - -/* Free the copies of the scale and shift terms from the supplied WinMap. */ - b = (double *) astFree( (void *) b ); - a = (double *) astFree( (void *) a ); - -/* Re-instate the original settings of the Invert attribute for the - supplied Mappings. */ - astSetInvert( wm, old_winv ); - astSetInvert( zm, old_zinv ); - -/* If an error has occurred, annull the returned WinMap. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output WinMap. */ - return result; -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* Implement member functions to access the attributes associated with - this class using the macros defined for this purpose in the - "object.h" file. For a description of each attribute, see the class - interface (in the associated .h file). */ - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for WinMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for WinMap objects. - -* Parameters: -* objin -* Pointer to the WinMap to be copied. -* objout -* Pointer to the WinMap being constructed. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstWinMap *out; /* Pointer to output WinMap */ - AstWinMap *in; /* Pointer to input WinMap */ - int ncoord; /* No. of axes for the mapping */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the input and output WinMaps. */ - in= (AstWinMap *) objin; - out = (AstWinMap *) objout; - -/* Get the number of coordinates mapped by the WinMap. */ - ncoord = astGetNin( in ); - -/* Allocate memory holding copies of the scales and shifts window defining the - mapping. */ - out->a = (double *) astStore( NULL, (void *) in->a, - sizeof(double)*(size_t)ncoord ); - out->b = (double *) astStore( NULL, (void *) in->b, - sizeof(double)*(size_t)ncoord ); - -/* If an error occurred, free any allocated memory. */ - if ( !astOK ) { - out->a = (double *) astFree( (void *) out->a ); - out->b = (double *) astFree( (void *) out->b ); - } - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for WinMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for WinMap objects. - -* Parameters: -* obj -* Pointer to the WinMap to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This destructor does nothing and exists only to maintain a -* one-to-one correspondence between destructors and copy -* constructors. -*/ - -/* Local Variables: */ - AstWinMap *this; /* Pointer to WinMap */ - -/* Obtain a pointer to the WinMap structure. */ - this = (AstWinMap *) obj; - -/* Free the memory holding the scales and shifts. */ - this->a = (double *) astFree( (void *) this->a ); - this->b = (double *) astFree( (void *) this->b ); - -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for WinMap objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the WinMap class to an output Channel. - -* Parameters: -* this -* Pointer to the WinMap whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Constants: */ -#define COMMENT_LEN 50 /* Maximum length of a comment string */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstWinMap *this; /* Pointer to the WinMap structure */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment string */ - int axis; /* Axis index */ - int ncoord; /* No. of axes for mapping */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the WinMap structure. */ - this = (AstWinMap *) this_object; - -/* Get the number of coordinates to be mapped. */ - ncoord = astGetNin( this ); - -/* Write out values representing the instance variables for the - WinMap class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* The scales and shifts. */ - for( axis = 0; axis < ncoord; axis++ ){ - (void) sprintf( buff, "Sft%d", axis + 1 ); - (void) sprintf( comment, "Shift for axis %d", axis + 1 ); - astWriteDouble( channel, buff, (this->a)[ axis ] != 0.0, 0, - (this->a)[ axis ], comment ); - (void) sprintf( buff, "Scl%d", axis + 1 ); - (void) sprintf( comment, "Scale factor for axis %d", axis + 1 ); - astWriteDouble( channel, buff, (this->b)[ axis ] != 1.0, 0, - (this->b)[ axis ], comment ); - } - -/* Undefine macros local to this function. */ -#undef COMMENT_LEN -#undef KEY_LEN -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAWinMap and astCheckWinMap functions using the macros - defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(WinMap,Mapping) -astMAKE_CHECK(WinMap) - -AstWinMap *astWinMap_( int ncoord, const double c1_in[], const double c2_in[], - const double c1_out[], const double c2_out[], - const char *options, int *status, ...) { -/* -*++ -* Name: -c astWinMap -f AST_WINMAP - -* Purpose: -* Create a WinMap. - -* Type: -* Public function. - -* Synopsis: -c #include "winmap.h" -c AstWinMap *astWinMap( int ncoord, -c const double ina[], const double inb[], -c const double outa[], const double outb[], -c const char *options, ... ) -f RESULT = AST_WINMAP( NCOORD, INA, INB, OUTA, OUTB, OPTIONS, STATUS ) - -* Class Membership: -* WinMap constructor. - -* Description: -* This function creates a new WinMap and optionally initialises its -* attributes. -* -* A Winmap is a linear Mapping which transforms a rectangular -* window in one coordinate system into a similar window in another -* coordinate system by scaling and shifting each axis (the window -* edges being parallel to the coordinate axes). -* -* A WinMap is specified by giving the coordinates of two opposite -* corners (A and B) of the window in both the input and output -* coordinate systems. - -* Parameters: -c ncoord -f NCOORD = INTEGER (Given) -* The number of coordinate values for each point to be -* transformed (i.e. the number of dimensions of the space in -* which the points will reside). The same number is applicable -* to both input and output points. -c ina -f INA( NCOORD ) = DOUBLE PRECISION (Given) -c An array containing the "ncoord" -f An array containing the -* coordinates of corner A of the window in the input coordinate -* system. -c inb -f INB( NCOORD ) = DOUBLE PRECISION (Given) -c An array containing the "ncoord" -f An array containing the -* coordinates of corner B of the window in the input coordinate -* system. -c outa -f OUTA( NCOORD ) = DOUBLE PRECISION (Given) -c An array containing the "ncoord" -f An array containing the -* coordinates of corner A of the window in the output coordinate -* system. -c outb -f OUTB( NCOORD ) = DOUBLE PRECISION (Given) -c An array containing the "ncoord" -f An array containing the -* coordinates of corner B of the window in the output coordinate -* system. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new WinMap. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new WinMap. The syntax used is identical to that for the -f AST_SET routine. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astWinMap() -f AST_WINMAP = INTEGER -* A pointer to the new WinMap. - -* Notes: -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. - -* Status Handling: -* The protected interface to this function includes an extra -* parameter at the end of the parameter list descirbed above. This -* parameter is a pointer to the integer inherited status -* variable: "int *status". - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstWinMap *new; /* Pointer to new WinMap */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the WinMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitWinMap( NULL, sizeof( AstWinMap ), !class_init, &class_vtab, - "WinMap", ncoord, c1_in, c2_in, c1_out, c2_out ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new WinMap's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new WinMap. */ - return new; -} - -AstWinMap *astWinMapId_( int ncoord, const double c1_in[], const double c2_in[], - const double c1_out[], const double c2_out[], - const char *options, ... ) { -/* -* Name: -* astWinMapId_ - -* Purpose: -* Create a WinMap. - -* Type: -* Private function. - -* Synopsis: -* #include "winmap.h" -* AstWinMap *astWinMapId_( int ncoord, const double c1_in[], -* const double c2_in[], const double c1_out[], -* const double c2_out[], -* const char *options, ... ) - -* Class Membership: -* WinMap constructor. - -* Description: -* This function implements the external (public) interface to the -* astWinMap constructor function. It returns an ID value (instead -* of a true C pointer) to external users, and must be provided -* because astWinMap_ has a variable argument list which cannot be -* encapsulated in a macro (where this conversion would otherwise -* occur). -* -* The variable argument list also prevents this function from -* invoking astWinMap_ directly, so it must be a re-implementation -* of it in all respects, except for the final conversion of the -* result to an ID value. - -* Parameters: -* As for astWinMap_. - -* Returned Value: -* The ID value associated with the new WinMap. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstWinMap *new; /* Pointer to new WinMap */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the WinMap, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitWinMap( NULL, sizeof( AstWinMap ), !class_init, &class_vtab, - "WinMap", ncoord, c1_in, c2_in, c1_out, c2_out ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the options string - to the astVSet method to initialise the new WinMap's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new WinMap. */ - return astMakeId( new ); -} - -AstWinMap *astInitWinMap_( void *mem, size_t size, int init, - AstWinMapVtab *vtab, const char *name, - int ncoord, const double *c1_in, - const double *c2_in, const double *c1_out, - const double *c2_out, int *status ) { -/* -*+ -* Name: -* astInitWinMap - -* Purpose: -* Initialise a WinMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "winmap.h" -* AstWinMap *astInitWinMap( void *mem, size_t size, int init, -* AstWinMapVtab *vtab, const char *name, -* int ncoord, const double *c1_in, -* const double *c2_in, -* const double *c1_out, const double *c2_out ) - -* Class Membership: -* WinMap initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new WinMap object. It allocates memory (if necessary) to accommodate -* the WinMap plus any additional data associated with the derived class. -* It then initialises a WinMap structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a WinMap at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the WinMap is to be initialised. -* This must be of sufficient size to accommodate the WinMap data -* (sizeof(WinMap)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the WinMap (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the WinMap -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the WinMap's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new WinMap. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* ncoord -* The number of coordinate values per point. -* c1_in -* The input coordinates of corner C1 of the window. -* c2_in -* The input coordinates of corner C2 of the window. -* c1_out -* The output coordinates of corner C1 of the window. -* c2_out -* The output coordinates of corner C2 of the window. - -* Returned Value: -* A pointer to the new WinMap. - -* Notes: -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstWinMap *new; /* Pointer to new WinMap */ - double denom; /* Denominotor */ - int axis; /* Axis index */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitWinMapVtab( vtab, name ); - -/* Initialise. */ - new = NULL; - -/* Initialise a Mapping structure (the parent class) as the first component - within the WinMap structure, allocating memory if necessary. Specify that - the Mapping should be defined in both the forward and inverse directions. */ - new = (AstWinMap *) astInitMapping( mem, size, 0, - (AstMappingVtab *) vtab, name, - ncoord, ncoord, 1, 1 ); - - if ( astOK ) { - -/* Initialise the WinMap data. */ -/* ---------------------------- */ -/* Allocate memory to hold the shift and scale for each axis. */ - new->a = (double *) astMalloc( sizeof(double)*(size_t)ncoord ); - new->b = (double *) astMalloc( sizeof(double)*(size_t)ncoord ); - -/* Check the pointers can be used */ - if( astOK ){ - -/* Calculater and store the shift and scale for each axis. */ - for( axis = 0; axis < ncoord; axis++ ){ - -/* If any of the corners have not been provided, store bad values. */ - if( !c1_in || !c1_out || !c2_in || !c2_out ) { - (new->b)[ axis ] = AST__BAD; - (new->a)[ axis ] = AST__BAD; - -/* Otherwise, check the corners are good (not AST__BAD or NaN)... */ - } else if( astISGOOD(c2_in[ axis ]) && astISGOOD(c1_in[ axis ]) && - astISGOOD(c2_out[ axis ]) && astISGOOD(c1_out[ axis ]) ){ - - denom = c2_in[ axis ] - c1_in[ axis ]; - if( denom != 0.0 ){ - (new->b)[ axis ] = ( c2_out[ axis ] - c1_out[ axis ] )/denom; - (new->a)[ axis ] = c1_out[ axis ] - (new->b)[ axis ]*c1_in[ axis ]; - } else { - (new->b)[ axis ] = AST__BAD; - (new->a)[ axis ] = AST__BAD; - } - - } else { - (new->b)[ axis ] = AST__BAD; - (new->a)[ axis ] = AST__BAD; - } - - } - - } - -/* If an error occurred, clean up by deleting the new WinMap. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new WinMap. */ - return new; -} - -AstWinMap *astLoadWinMap_( void *mem, size_t size, - AstWinMapVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadWinMap - -* Purpose: -* Load a WinMap. - -* Type: -* Protected function. - -* Synopsis: -* #include "winmap.h" -* AstWinMap *astLoadWinMap( void *mem, size_t size, -* AstWinMapVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* WinMap loader. - -* Description: -* This function is provided to load a new WinMap using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* WinMap structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a WinMap at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the WinMap is to be -* loaded. This must be of sufficient size to accommodate the -* WinMap data (sizeof(WinMap)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the WinMap (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the WinMap structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstWinMap) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new WinMap. If this is NULL, a pointer -* to the (static) virtual function table for the WinMap class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "WinMap" is used instead. - -* Returned Value: -* A pointer to the new WinMap. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Constants. */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstWinMap *new; /* Pointer to the new WinMap */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - int axis; /* Axis index */ - int ncoord; /* The number of coordinate axes */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this WinMap. In this case the - WinMap belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstWinMap ); - vtab = &class_vtab; - name = "WinMap"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitWinMapVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built WinMap. */ - new = astLoadMapping( mem, size, (AstMappingVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Get the number of axis for the mapping. */ - ncoord = astGetNin( (AstMapping *) new ); - -/* Allocate memory to hold the scales and shifts. */ - new->a = (double *) astMalloc( sizeof(double)*(size_t)ncoord ); - new->b = (double *) astMalloc( sizeof(double)*(size_t)ncoord ); - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "WinMap" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* The scales and shifts. */ - for( axis = 0; axis < ncoord; axis++ ){ - (void) sprintf( buff, "sft%d", axis + 1 ); - (new->a)[ axis ] = astReadDouble( channel, buff, 0.0 ); - (void) sprintf( buff, "scl%d", axis + 1 ); - (new->b)[ axis ] = astReadDouble( channel, buff, 1.0 ); - } - } - -/* If an error occurred, clean up by deleting the new WinMap. */ - if ( !astOK ) new = astDelete( new ); - -/* Return the new WinMap pointer. */ - return new; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -int astWinTerms_( AstWinMap *this, double **scale, double **shift, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,WinMap,WinTerms))( this, scale, shift, status ); -} - - - - diff --git a/ast/winmap.h b/ast/winmap.h deleted file mode 100644 index fd05066..0000000 --- a/ast/winmap.h +++ /dev/null @@ -1,300 +0,0 @@ -#if !defined( WINMAP_INCLUDED ) /* Include this file only once */ -#define WINMAP_INCLUDED -/* -*+ -* Name: -* winmap.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the WinMap class. - -* Invocation: -* #include "winmap.h" - -* Description: -* This include file defines the interface to the WinMap class and -* provides the type definitions, function prototypes and macros, -* etc. needed to use this class. -* -* The WinMap class implements Mappings which maps one window onto -* another window by scaling and shifting the values on each axis. - -* Inheritance: -* The WinMap class inherits from the Mapping class. - -* Attributes Over-Ridden: -* None. - -* New Attributes Defined: -* None. - -* Methods Over-Ridden: -* Public: -* None. -* -* Protected: -* ClearAttrib -* Clear an attribute value for a WinMap. -* GetAttrib -* Get an attribute value for a WinMap. -* SetAttrib -* Set an attribute value for a WinMap. -* TestAttrib -* Test if an attribute value has been set for a WinMap. -* astMapMerge -* Simplify a sequence of Mappings containing a WinMap. -* astTransform -* Apply a WinMap to transform a set of points. - -* New Methods Defined: -* Public: -* None. -* -* Protected: -* astWinTerms -* Obtain copies of the shift and scale terms used by a WinMap. - -* Other Class Functions: -* Public: -* astIsAWinMap -* Test class membership. -* astWinMap -* Create a WinMap. -* -* Protected: -* astCheckWinMap -* Validate class membership. -* astInitWinMap -* Initialise a WinMap. -* astInitWinMapVtab -* Initialise the virtual function table for the WinMap class. -* astLoadWinMap -* Load a WinMap. - -* Macros: -* None. - -* Type Definitions: -* Public: -* AstWinMap -* WinMap object type. -* -* Protected: -* AstWinMapVtab -* WinMap virtual function table type. - -* Feature Test Macros: -* astCLASS -* If the astCLASS macro is undefined, only public symbols are -* made available, otherwise protected symbols (for use in other -* class implementations) are defined. This macro also affects -* the reporting of error context information, which is only -* provided for external calls to the AST library. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: D.S. Berry (Starlink) - -* History: -* 23-OCT-1996 (DSB): -* Original version. -* 8-JAN-2003 (DSB): -* Changed private InitVtab method to protected astInitWinMapVtab -* method. -*- -*/ - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "mapping.h" /* Coordinate mappings (parent class) */ - -#if defined(astCLASS) /* Protected */ -#include "pointset.h" /* Sets of points/coordinates */ -#include "channel.h" /* I/O channels */ -#endif - -/* C header files. */ -/* --------------- */ -#if defined(astCLASS) /* Protected */ -#include -#endif - -/* Macros */ -/* ====== */ - -/* Define a dummy __attribute__ macro for use on non-GNU compilers. */ -#ifndef __GNUC__ -# define __attribute__(x) /*NOTHING*/ -#endif - -/* Type Definitions. */ -/* ================= */ -/* WinMap structure. */ -/* ------------------ */ -/* This structure contains all information that is unique to each object in - the class (e.g. its instance variables). */ -typedef struct AstWinMap { - -/* Attributes inherited from the parent class. */ - AstMapping mapping; /* Parent class structure */ - -/* Attributes specific to objects in this class. */ - double *a; /* Pointer to array of shifts */ - double *b; /* Pointer to array of scale factors */ - -} AstWinMap; - -/* Virtual function table. */ -/* ----------------------- */ -/* This table contains all information that is the same for all - objects in the class (e.g. pointers to its virtual functions). */ -#if defined(astCLASS) /* Protected */ -typedef struct AstWinMapVtab { - -/* Properties (e.g. methods) inherited from the parent class. */ - AstMappingVtab mapping_vtab; /* Parent class virtual function table */ - -/* A Unique identifier to determine class membership. */ - AstClassIdentifier id; - -/* Properties (e.g. methods) specific to this class. */ - int (* WinTerms)( AstWinMap *, double **, double **, int * ); - -} AstWinMapVtab; - -#if defined(THREAD_SAFE) - -/* Define a structure holding all data items that are global within the - object.c file. */ - -typedef struct AstWinMapGlobals { - AstWinMapVtab Class_Vtab; - int Class_Init; -} AstWinMapGlobals; - - -/* Thread-safe initialiser for all global data used by this module. */ -void astInitWinMapGlobals_( AstWinMapGlobals * ); - -#endif - - -#endif - -/* Function prototypes. */ -/* ==================== */ -/* Prototypes for standard class functions. */ -/* ---------------------------------------- */ -astPROTO_CHECK(WinMap) /* Check class membership */ -astPROTO_ISA(WinMap) /* Test class membership */ - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -AstWinMap *astWinMap_( int, const double [], const double [], const double [], const double [], const char *, int *, ...); -#else -AstWinMap *astWinMapId_( int, const double [], const double [], const double [], const double [], const char *, ... )__attribute__((format(printf,6,7))); -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -AstWinMap *astInitWinMap_( void *, size_t, int, AstWinMapVtab *, - const char *, int, const double *, const double *, - const double *, const double *, int * ); - -/* Vtab initialiser. */ -void astInitWinMapVtab_( AstWinMapVtab *, const char *, int * ); - -/* Loader. */ -AstWinMap *astLoadWinMap_( void *, size_t, AstWinMapVtab *, - const char *, AstChannel *, int * ); -#endif - -/* Prototypes for member functions. */ -/* -------------------------------- */ -# if defined(astCLASS) /* Protected */ -int astWinTerms_( AstWinMap *, double **, double **, int * ); -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These macros are wrap-ups for the functions defined by this class - to make them easier to invoke (e.g. to avoid type mis-matches when - passing pointers to objects from derived classes). */ - -/* Interfaces to standard class functions. */ -/* --------------------------------------- */ -/* Some of these functions provide validation, so we cannot use them - to validate their own arguments. We must use a cast when passing - object pointers (so that they can accept objects from derived - classes). */ - -/* Check class membership. */ -#define astCheckWinMap(this) astINVOKE_CHECK(WinMap,this,0) -#define astVerifyWinMap(this) astINVOKE_CHECK(WinMap,this,1) - -/* Test class membership. */ -#define astIsAWinMap(this) astINVOKE_ISA(WinMap,this) - -/* Constructor. */ -#if defined(astCLASS) /* Protected. */ -#define astWinMap astINVOKE(F,astWinMap_) -#else -#define astWinMap astINVOKE(F,astWinMapId_) -#endif - -#if defined(astCLASS) /* Protected */ - -/* Initialiser. */ -#define \ -astInitWinMap(mem,size,init,vtab,name,ncoord,c1_in,c2_in,c1_out,c2_out) \ -astINVOKE(O,astInitWinMap_(mem,size,init,vtab,name,ncoord,c1_in,c2_in,c1_out,c2_out,STATUS_PTR)) - -/* Vtab Initialiser. */ -#define astInitWinMapVtab(vtab,name) astINVOKE(V,astInitWinMapVtab_(vtab,name,STATUS_PTR)) -/* Loader. */ -#define astLoadWinMap(mem,size,vtab,name,channel) \ -astINVOKE(O,astLoadWinMap_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR)) -#endif - -/* Interfaces to public member functions. */ -/* -------------------------------------- */ -/* Here we make use of astCheckWinMap to validate WinMap pointers - before use. This provides a contextual error report if a pointer - to the wrong sort of Object is supplied. */ - -#if defined(astCLASS) /* Protected */ -#define astWinTerms(this,scale,shift) \ -astINVOKE(V,astWinTerms_(astCheckWinMap(this),scale,shift,STATUS_PTR)) -#endif - -#endif - - - - - diff --git a/ast/xml.c b/ast/xml.c deleted file mode 100644 index f14cb22..0000000 --- a/ast/xml.c +++ /dev/null @@ -1,7119 +0,0 @@ -/* -* Name: -* xml.c - -* Purpose: -* Implement XML functions for AST. - -* Description: -* This file implements the Xml module which provides generic XML -* reading and writing functions for the XmlChan class. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 22-OCT-2003 (DSB): -* Original version. -* 12-JAN-2004 (DSB): -* Major revisions. -* 10-FEB-2004 (DSB): -* - Added debug conditional code to keep track of memory leaks. -* - Other minor bug fixes. -* 6-FEB-2004 (DSB): -* DefaultURI and astXmlAddURI modified to allow a blank URI to be -* used to ignore a default namespace URI provided by an enclosing -* element. -* 29-NOV-2004 (DSB): -* Added astXmlGetType method. -* 27-JAN-2005 (DSB): -* - Move astXmlTrace and associated code into conditional -* compilation blokc (included if DEBUG macro is defined). This -* speeds up the create and destruction of XmlObjects in non-DEBUG code. -* - Renamed the private Delete function as astXmlDelete and gave -* it protected access. -* - Modify astXmlDelete so that it can succesfully annul objects -* which have no parent. -* - Include extra info in some error messages. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 10-DEC-2008 (DSB): -* Allow a prefix to be included with the attribute name in -* astXmlGetAttributeValue. -*/ - - -/* Module Constants. */ -/* ----------------- */ -/* Set the name of the module we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. NB, this module is not a proper AST - class, but it defines this macro sanyway in order to get the protected - symbols defined in memory.h */ -#define astCLASS Xml - -#define IND_INC 3 - - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ -#include "memory.h" /* Interface to the memory management module */ -#include "error.h" /* Interface to the error module */ -#include "xml.h" /* Interface to this module */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include - - -/* -* Name: -* MAKE_CHECK - -* Type: -* Private macro. - -* Purpose: -* Implement the astXmlCheck_ function for XML structures. - -* Synopsis: -* #include "xml.h" -* MAKE_CHECK(type,id) - -* Class Membership: -* Defined by the xml module. - -* Description: -* This macro expands to an implementation of the protected -* astXmlCheck_ function (q.v.) which validates membership of -* a specified XML data type. - -* Parameters: -* type -* The type whose membership is to be validated (e.g. "Element" not -* "XmlElement"). -* id -* The constant (e.g. "AST__XMLELEM") defining the data type. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*/ - -/* Define the macro. */ -#define MAKE_CHECK(type,id) \ -\ -/* Declare the function */ \ -AstXml##type *astXmlCheck##type##_( void *this, int nullok, int *status ) { \ -\ -/* Local Variables: */\ - AstXml##type *result; /* The returned pointer */\ -\ -/* Check the global error status. If an error has already occurred just\ - return the supplied pointer. This is so that functions such as\ - astXmlAnnul which do not check the inherited status receive the\ - supplied pointer. */\ - if( !astOK ) return this;\ -\ -/* Initialise */\ - result = NULL;\ -\ -/* If the pointer is NULL issue an error if nullok is zero. */\ - if( !this ) {\ - if( !nullok ) astError( AST__PTRIN, "astXmlCheck"#type": Invalid "\ - "NULL pointer supplied." , status);\ -\ -/* Otherwise get the "type" component which holds a magic value for each\ - different class of structure. Compare this value against all valid \ - classes of structure. If no match is found, the pointer does not \ - identify an suitable structure, and so report an error and return \ - NULL. */\ - } else {\ - if( !astXmlCheckType( ( AstXmlObject * ) this, id ) ) {\ - astError( AST__PTRIN, "astXmlCheck"#type": Invalid pointer "\ - "supplied; pointer to AstXml"#type" required." , status);\ - } else {\ - result = (AstXml##type *) this;\ - }\ - }\ -\ -/* Return the result. */\ - return result;\ -} - - -/* Module variables. */ -/* ================= */ - -/* Define macros for accessing all items of thread-safe global data - used by this module. */ -#ifdef THREAD_SAFE - -#define next_id astGLOBAL(Xml,Next_ID) -#define gettag_buff astGLOBAL(Xml,GetTag_Buff) -#define GLOBAL_inits globals->Next_ID = 0; -astMAKE_INITGLOBALS(Xml) - -/* Set up mutexes */ -static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX1 pthread_mutex_lock( &mutex1 ); -#define UNLOCK_MUTEX1 pthread_mutex_unlock( &mutex1 ); - -/* If thread safety is not needed, declare globals at static variables. */ -#else - -static int next_id = 0; -static char gettag_buff[ AST__XML_GETTAG_BUFF_LEN + 1 ]; - -#define LOCK_MUTEX1 -#define UNLOCK_MUTEX1 - -#ifdef DEBUG /* Not available in thread-safe compilations */ -static int nobj = 0; -static AstXmlObject **existing_objects = NULL; -#endif - -#endif - - -/* Function prototypes. */ -/* ==================== */ - -/* Private member functions. */ -/* ------------------------- */ -static AstXmlAttribute *FindAttribute( AstXmlElement *, const char *, int * ); -static AstXmlAttribute *NewAttribute( const char *, const char *, const char *, int * ); -static AstXmlDocument *NewDocument( int * ); -static AstXmlPrologue *NewPrologue( AstXmlDocument *, int * ); -static AstXmlNamespace *NewNamespace( const char *, const char *, int * ); -static char *AppendChar( char *, int *, char, int * ); -static char *AppendLine( char *, int *, const char *, int, int * ); -static char *RemoveEscapes( const char *, int * ); -static char *CleanText( const char *, int * ); -static const char *AddEscapes( const char *, int * ); -static const char *DefaultURI( AstXmlElement *, int * ); -static const char *Format( AstXmlObject *, int, int * ); -static char *FormatTag( AstXmlObject *, int, int * ); -static const char *ResolvePrefix( const char *, AstXmlElement *, int * ); -static int CheckType( long int, long int, int * ); -static int MatchName( AstXmlElement *, const char *, int * ); -static int Ustrcmp( const char *, const char *, int * ); -static void AddContent( AstXmlParent *, int, AstXmlContentItem *, int * ); -static void CheckName( const char *, const char *, const char *, int, int * ); -static void CheckPrefName( char *, const char *, const char *, int * ); -static void CleanXml( AstXmlObject *, long int, int * ); -static void InitXmlAttribute( AstXmlAttribute *, int, const char *, const char *, const char *, int * ); -static void InitXmlCDataSection( AstXmlCDataSection *, int, const char *, int * ); -static void InitXmlWhite( AstXmlWhite *, int, const char *, int * ); -static void InitXmlBlack( AstXmlBlack *, int, const char *, int * ); -static void InitXmlComment( AstXmlComment *, int, const char *, int * ); -static void InitXmlDocument( AstXmlDocument *, int, int * ); -static void InitXmlPrologue( AstXmlPrologue *, int, int * ); -static void InitXmlDeclPI( AstXmlDeclPI *, int, const char *, int * ); -static void InitXmlDTDec( AstXmlDTDec *, int, const char *, const char *, const char *, int * ); -static void InitXmlElement( AstXmlElement *, int, const char *, const char *, int * ); -static void InitXmlNamespace( AstXmlNamespace *, int, const char *, const char *, int * ); -static void InitXmlObject( AstXmlObject *, long int, int * ); -static void InitXmlPI( AstXmlPI *, int, const char *, const char *, int * ); -static AstXmlElement *ReadContent( AstXmlDocument **, int, int (*)( AstXmlElement *, int * ), int, char (*)( void *, int * ), void *, int, int * ); - -#ifdef DEBUG -static void AddObjectToList( AstXmlObject * ); -static void RemoveObjectFromList( AstXmlObject * ); -#endif - -/* Function implementations. */ -/* ========================= */ - -/* Create the astXmlCheck... functiosn which check a pointer identifies - an XML structure of a given type. */ - -MAKE_CHECK(Document,AST__XMLDOC) -MAKE_CHECK(Object,AST__XMLOBJECT) -MAKE_CHECK(Element,AST__XMLELEM) -MAKE_CHECK(Attribute,AST__XMLATTR) -MAKE_CHECK(CDataSection,AST__XMLCDATA) -MAKE_CHECK(Comment,AST__XMLCOM) -MAKE_CHECK(PI,AST__XMLPI) -MAKE_CHECK(Namespace,AST__XMLNAME) -MAKE_CHECK(Prologue,AST__XMLPRO) -MAKE_CHECK(DeclPI,AST__XMLDEC) -MAKE_CHECK(DTDec,AST__XMLDTD) -MAKE_CHECK(White,AST__XMLWHITE) -MAKE_CHECK(Black,AST__XMLBLACK) -MAKE_CHECK(CharData,AST__XMLCHAR) -MAKE_CHECK(ContentItem,AST__XMLCONT) -MAKE_CHECK(MiscItem,AST__XMLMISC) -MAKE_CHECK(Parent,AST__XMLPAR) - - -static void AddContent( AstXmlParent *this, int where, AstXmlContentItem *item, int *status ){ -/* -* Name: -* AddContent - -* Purpose: -* Add a content item to an XmlElement. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* void AddContent( AstXmlParent *this, int where, AstXmlContentItem *item, int *status ) - -* Description: -* This function adds a supplied item to a specified XmlElement or -* XmlDocument. An error is reported if the item is not appropriate. - -* Parameters: -* this -* The pointer to the element or document to be modified. -* where -* Ignored if "this" is an XmlElement pointer. Otherwise, "where" -* indicates where the item should be added to the document: -* 1 - In the prologue, after the XML declaration but before the DTD. -* 2 - In the prologue, after the DTD but before the root element. -* 3 - In the epilogue, after the root element. -* item -* Pointer to the content item to be added to the element. If -* "this" is an XmlElement, this can be a pointer to any of the -* following types: AstXmlElement, AstXmlWhite, AstXmlBlack, -* AstXmlCDataSection, AstXmlComment, AstXmlPI. If "this" is a -* document, the list is restricted to: AstXmlWhite, AstXmlComment, -* AstXmlPI. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstXmlDocument *doc; /* Document pointer */ - AstXmlElement *elem; /* Element pointer */ - AstXmlPrologue *pro; /* Prologue pointer */ - int nitem; /* Number of items in the parent */ - -/* Check the global error status and the supplied pointers. */ - if( !astOK || !this || !item ) return; - -/* Split for the two forms of parent. */ - if( astXmlCheckType( this, AST__XMLELEM ) ) { - elem = (AstXmlElement *) this; - -/* Save the number of content items currently stored in the element. */ - nitem = ( elem->items ) ? elem->nitem : 0; - -/* Attempt to extend the array to hold an extra item. */ - elem->items = astGrow( elem->items, nitem + 1, - sizeof( AstXmlContentItem * ) ); - -/* Check the memory was allocated succesfully. */ - if( astOK ) { - -/* Store the supplied pointer in the array of content items. */ - elem->items[ nitem ] = item; - -/* Increment the number of content items in this element */ - elem->nitem = nitem + 1; - -/* Indicate that the item is owned by the element. */ - ( (AstXmlObject *) item )->parent = this; - } - -/* Now deal with cases where we are adding an item to the prologue or - epilogue of the document. */ - } else { - if( !astXmlCheckType( item, AST__XMLMISC ) ){ - astError( AST__INTER, "AddContent(xml): Inappropriate attempt to " - "add an item of type %ld to an XML document (internal " - "AST programming error).", status, ( (AstXmlObject *) item)->type ); - - } else if( !astXmlCheckType( this, AST__XMLDOC ) ){ - astError( AST__INTER, "AddContent(xml): Inappropriate attempt to " - "add an item of type %ld to an XML object of type %ld " - "(internal AST programming error).", status, - ( (AstXmlObject *) item)->type, - ( (AstXmlObject *) this)->type ); - - } else { - doc = (AstXmlDocument *) this; - -/* Create a prologue if necessary. */ - if( where < 3 && !doc->prolog ) doc->prolog = NewPrologue( doc, status ); - pro = doc->prolog; - - if( where < 2 ) { - nitem = ( pro->misc1 ) ? pro->nmisc1 : 0; - pro->misc1 = astGrow( pro->misc1, nitem + 1, sizeof( AstXmlMiscItem * ) ); - if( astOK ) { - pro->misc1[ nitem ] = item; - pro->nmisc1 = nitem + 1; - ( (AstXmlObject *) item )->parent = (AstXmlParent *) pro; - } - - } else if( where == 2 ) { - nitem = ( pro->misc2 ) ? pro->nmisc2 : 0; - pro->misc2 = astGrow( pro->misc2, nitem + 1, sizeof( AstXmlMiscItem * ) ); - if( astOK ) { - pro->misc2[ nitem ] = item; - pro->nmisc2 = nitem + 1; - ( (AstXmlObject *) item )->parent = (AstXmlParent *) pro; - } - - } else { - nitem = ( doc->epilog ) ? doc->nepi : 0; - doc->epilog = astGrow( doc->epilog, nitem + 1, sizeof( AstXmlMiscItem * ) ); - if( astOK ) { - doc->epilog[ nitem ] = item; - doc->nepi = nitem + 1; - ( (AstXmlObject *) item )->parent = this; - } - } - } - } -} - -static const char *AddEscapes( const char *text, int *status ){ -/* -* Name: -* AddEscapes - -* Purpose: -* Replaces characters by corresponding entity references. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* const char *AddEscapes( const char *text, int *status ) - -* Description: -* This function produces a dynamic copy of the supplied text in which -* occurrences of "&", "<", ">", and "\"" are replaced by the corresponding -* XML entity reference. -* -* The "&" character is only replaced by an entity reference if it is -* followed by a non-name character (i.e. anything except a letter -* underscore or colon). If it is followed by a name character, it is -* assumed to mark the start of an entity reference. - -* Parameters: -* text -* A pointer to a text string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated string containing the required -* copy. - -* Notes: -* - NULL is returned if this function is called with the global error -* status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - char *result; /* Returned pointer */ - const char *c; /* Pointer to next supplied character */ - char *d; /* Pointer to next returned character */ - -/* Initialise */ - result = NULL; - -/* Return if the pointer is NULL or if an error has occurred. */ - if( !astOK || !text ) return result; - -/* Allocate the maximum possible amount of memory that may be needed to - store the returned string. */ - result = astMalloc( 6*strlen( text ) + 1 ); - -/* Check the pointer can be used safely. */ - if( astOK ) { - -/* Loop round every character in the supplied text. */ - c = text - 1; - d = result; - while( *(++c) ) { - -/* We replace this character if it is a <, >, ', &, or ". */ - if( *c == '<' ) { - strcpy( d, "<" ); - d += 4; - - } else if( *c == '>' ) { - strcpy( d, ">" ); - d += 4; - - } else if( *c == '"' ) { - strcpy( d, """ ); - d += 6; - - } else if( *c == '\'' ) { - strcpy( d, "'" ); - d += 6; - - } else if( *c == '&' ) { - strcpy( d, "&" ); - d += 5; - -/* Otherwise just append the supplied character. */ - } else { - *(d++) = *c; - } - } - -/* Terminate the returned string. */ - *d = 0; - -/* Reallocate the string to free up any unused space. */ - result = astRealloc( result, d - result + 1 ); - } - -/* Return the result. */ - return (const char *) result; -} - - -#ifdef DEBUG -static void AddObjectToList( AstXmlObject *obj ){ -/* -* Name: -* AddObjectToList - -* Purpose: -* Adds an XmlObject to a static list of all currently active XmlObjects. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* void AddObjectToList( AstXmlObject *obj ) - -* Description: -* This function adds the supplied pointer to a static list of pointers, -* and increments the number of elements in the list. This list holds -* pointers to all the XmlObjects which currently exist. - -* Parameters: -* this -* A pointer to a new XmlObject. -*/ - -/* Return if the pointer is NULL or if an error has occurred. */ - if( !astOK || !obj ) return; - -/* Increment the number of objects in the list and increase the size of - the list. */ - astBeginPM; - existing_objects = astGrow( existing_objects, ++nobj, sizeof( AstXmlObject *) ); - astEndPM; - -/* Add the new pointer to the end of the list. */ - existing_objects[ nobj - 1 ] = obj; -} -#endif - -static char *AppendChar( char *str1, int *nc, char ch, int *status ) { -/* -* Name: -* AppendChar - -* Purpose: -* Append a character to a string which grows dynamically. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* char *AppendChar( char *str1, int *nc, char ch, int *status ) - -* Description: -* This function appends a character to a dynamically -* allocated string, extending the dynamic string as necessary to -* accommodate the new character (plus the final null). - -* Parameters: -* str1 -* Pointer to the null-terminated dynamic string, whose memory -* has been allocated using the AST memory allocation functions -* defined in "memory.h". If no space has yet been allocated for -* this string, a NULL pointer may be given and fresh space will -* be allocated by this function. -* nc -* Pointer to an integer containing the number of characters in -* the dynamic string (excluding the final null). This is used -* to save repeated searching of this string to determine its -* length and it defines the point where the new string will be -* appended. Its value is updated by this function to include -* the extra characters appended. -* -* If "str1" is NULL, the initial value supplied for "*nc" will -* be ignored and zero will be used. -* ch -* The character which is to be appended to "str1". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A possibly new pointer to the dynamic string with the new character -* appended (its location in memory may have to change if it has to -* be extended, in which case the original memory is automatically -* freed by this function). When the string is no longer required, -* its memory should be freed using astFree. - -* Notes: -* - If this function is invoked with the global error status set -* or if it should fail for any reason, then the returned pointer -* will be equal to "str1" and the dynamic string contents will be -* unchanged. -*/ - -/* Local Variables: */ - char *result; /* Pointer value to return */ - int len; /* Length of new string */ - -/* Initialise. */ - result = str1; - -/* If the first string pointer is NULL, also initialise the character - count to zero. */ - if ( !str1 ) *nc = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Calculate the total string length once the character has been added. */ - len = *nc + 1; - -/* Extend the dynamic string to the required length, including - a final null. Save the resulting pointer, which will be - returned. */ - result = astGrow( str1, len + 1, sizeof( char ) ); - -/* If OK, append the second string and update the total character - count. */ - if ( astOK ) { - result[ *nc ] = ch; - *nc = len; - result[ *nc ] = 0; - } - -/* Return the result pointer. */ - return result; -} - -static char *AppendLine( char *str1, int *nc, const char *str2, int ind, int *status ) { -/* -* Name: -* AppendLine - -* Purpose: -* Append an indented new line to another string which grows dynamically. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* char *AppendLine( char *str1, int *nc, const char *str2, int ind, int *status ) - -* Description: -* This function appends one string to another dynamically -* allocated string, extending the dynamic string as necessary to -* accommodate the new characters (plus the final null). -* -* A newline character is inserted if necessary to ensure that the "str2" -* string starts on a newline. If "ind" is positive, spaces are added -* as necessary to ensure that "str2" begins with the specified number of -* spaces. - -* Parameters: -* str1 -* Pointer to the null-terminated dynamic string, whose memory -* has been allocated using the AST memory allocation functions -* defined in "memory.h". If no space has yet been allocated for -* this string, a NULL pointer may be given and fresh space will -* be allocated by this function. -* nc -* Pointer to an integer containing the number of characters in -* the dynamic string (excluding the final null). This is used -* to save repeated searching of this string to determine its -* length and it defines the point where the new string will be -* appended. Its value is updated by this function to include -* the extra characters appended. -* -* If "str1" is NULL, the initial value supplied for "*nc" will -* be ignored and zero will be used. -* str2 -* Pointer to a constant null-terminated string, a copy of which -* is to be appended to "str1". -* ind -* The number of spaces to use as the indentation string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A possibly new pointer to the dynamic string with the new string -* appended (its location in memory may have to change if it has to -* be extended, in which case the original memory is automatically -* freed by this function). When the string is no longer required, -* its memory should be freed using astFree. - -* Notes: -* - If this function is invoked with the global error status set -* or if it should fail for any reason, then the returned pointer -* will be equal to "str1" and the dynamic string contents will be -* unchanged. -*/ - -/* Local Variables: */ - char *c; /* Point to next character */ - char *result; /* Pointer value to return */ - char *temp; /* Pointer to modified string */ - int j; /* Loop count */ - -/* Initialise. */ - result = str1; - -/* If the first string pointer is NULL, also initialise the character - count to zero. */ - if ( !str1 ) *nc = 0; - -/* Check the global error status. */ - if ( !astOK || !str2 ) return result; - -/* Remove any trailing white space (except for newlines) from the supplied - string. */ - if( *nc > 0 ) { - c = str1 + *nc - 1; - while( isspace( *c ) && *c != '\n' ) { - *(c--) = 0; - (*nc)--; - } - -/* If the last character in the returned string is not now a newline, - append a newline, so long as the new item does not start with a newline. */ - if( str1[ *nc - 1 ] != '\n' ) { - temp = AppendChar( str1, nc, '\n', status ); - } else { - temp = str1; - } - - } else { - temp = str1; - } - -/* If a fixed indentation is specified, skip over any leading spaces in - the second string. */ - if( str2 ) { - if( ind > 0 ) { - while( isspace( *str2 ) ) str2++; - } - -/* If the first character of the second string is a newline, ignore it. */ - if( str2[ 0 ] == '\n' ) str2++; - } - -/* Append the indentation string. */ - for( j = 0; j < ind; j++ ) temp = AppendChar( temp, nc, ' ', status ); - -/* Append the supplied string. */ - return astAppendString( temp, nc, str2 ); -} - -void astXmlAddAttr_( AstXmlElement *this, const char *name, const char *value, - const char *prefix, int *status ){ -/* -*+ -* Name: -* astXmlAddAttr - -* Purpose: -* Add an attribute to an XmlElement. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlAddAttr( AstXmlElement *this, const char *name, -* const char *value, const char *prefix ) - -* Description: -* This function adds an attribute to a specified XmlElement. If the -* element already contains an attribute with the given name amd prefix, -* then the value of the attribute is changed to be the supplied value. - -* Parameters: -* this -* The pointer to the element to be modified. -* name -* Pointer to a null terminated string containing the attribute name. -* value -* Pointer to a null terminated string containing the attribute value. -* prefix -* The namespace prefix for the attribute. May be NULL or blank, in -* which case any prefix at the start of "name" is used. -*- -*/ - -/* Local Variables: */ - AstXmlAttribute *attr; /* The new attribute. */ - AstXmlAttribute *oldattr; /* Pointer to existing attribute */ - int i; /* Loop index */ - int nattr; /* Number of attributes in the element */ - int oldi; /* Index of existing attribute */ - char *my_value; /* Cleaned value text */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Initialise */ - oldattr = NULL; - -/* Clean the value text. */ - my_value = CleanText( value, status ); - -/* Create a new XmlAttribute. */ - attr = NewAttribute( name, my_value, prefix, status ); - -/* Free the memory */ - my_value = astFree( my_value ); - -/* If OK, indicate that the attribute is owned by the element. */ - if( astOK ) { - ( (AstXmlObject *) attr )->parent = (AstXmlParent *) this; - -/* Save the number of attributes currently stored in the element. */ - nattr = ( this->attrs ) ? this->nattr : 0; - -/* Search the existing attributes to see if an attribute with the given - name and prefix already exists. */ - oldi = -1; - for( i = 0; i < nattr; i++ ) { - oldattr = this->attrs[ i ]; - if( !strcmp( oldattr->name, attr->name ) ) { - if( !oldattr->prefix && !attr->prefix ) { - oldi = i; - break; - } else if( oldattr->prefix && attr->prefix && - !strcmp( oldattr->prefix, attr->prefix ) ){ - oldi = i; - break; - } - } - } - -/* If there is an existing attribute with the same name and prefix, - replace the old attribute with the new one created above. */ - if( oldi > -1 ){ - ((AstXmlObject *)oldattr)->parent = NULL; - oldattr = astXmlAnnul( oldattr ); - this->attrs[ oldi ] = attr; - -/* Otherwise, attempt to extend the array to hold an extra attribute. */ - } else { - this->attrs = astGrow( this->attrs, nattr + 1, - sizeof( AstXmlAttribute * ) ); - -/* Check all has gone OK. */ - if( astOK ) { - -/* Store the attribute pointer in the array of attribute pointers. */ - this->attrs[ nattr ] = attr; - -/* Increment the number of content items in this element */ - this->nattr = nattr + 1; - - } - } - } -} - -void astXmlAddCDataSection_( AstXmlElement *this, const char *text, int *status ){ -/* -*+ -* Name: -* astXmlAddCDataSection - -* Purpose: -* Create a new XmlCDataSection and add it to an XmlElement. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlAddCDataSection( AstXmlElement *this, const char *text ) - -* Description: -* This function creates a new XmlCDataSection structure representing -* an unparsed character data (CDATA) section, and adds it into an -* existing element. - -* Parameters: -* this -* A pointer to the element to be modified. -* text -* Pointer to a null terminated string containing the character data. - -*- -*/ - -/* Local Variables: */ - AstXmlCDataSection *new; /* Pointer to new structure */ - char *my_text; /* Cleaned text */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Allocate space for the new structure. */ - new = (AstXmlCDataSection *) astMalloc( sizeof( AstXmlCDataSection ) ); - -/* Clean the text. */ - my_text = CleanText( text, status ); - -/* Initialise it. */ - InitXmlCDataSection( new, AST__XMLCDATA, my_text, status ); - -/* Free the memory */ - my_text = astFree( my_text ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) { - new = astXmlDelete( new ); - -/* Otherwise, add the content item to the element. */ - } else { - AddContent( (AstXmlParent *) this, 0, (AstXmlContentItem *) new, status ); - } -} - -void astXmlAddCharData_( AstXmlParent *this, int where, const char *text, int *status ){ -/* -*+ -* Name: -* astXmlAddCharData - -* Purpose: -* Create a new XmlCharData and add it to an XmlElement or XmlDocument. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlAddCharData( AstXmlParent *this, int where, const char *text ) - -* Description: -* This function creates a new XmlCharData structure representing -* parsed character data, and adds it into an existing element or -* document. - -* Parameters: -* this -* Pointer to the element or document to be modified. -* where -* Ignored if "this" is an XmlElement pointer. Otherwise, "where" -* indicates where the item should be added to the document: -* 1 - In the prologue, after the XML declaration but before the DTD. -* 2 - In the prologue, after the DTD but before the root element. -* 3 - In the epilogue, after the root element. -* text -* Pointer to a null terminated string containing the character data. -* If "this" is a document, the text must consist entirely of white -* space. - -*- -*/ - -/* Local Variables: */ - AstXmlCharData *new; /* Pointer to the new structure */ - char *my_text; /* Pointer to cleaned text */ - char *c; /* Pointer to next character */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Initialise */ - new = NULL; - -/* Clean the text by replacing "\r\n" by "\n". */ - my_text = CleanText( text, status ); - -/* See if the text is all white. */ - c = my_text - 1; - while( *(++c) && isspace( *c ) ); - -/* If the string contains a non-white character, allocate memory for - a XmlBlack structure, and initialise it to hold the supplied text. - Otherwise, allocate memory for a XmlWhite structure, and initialise it - to hold the supplied text. */ - if( *c ) { - if( astXmlCheckType( this, AST__XMLDOC ) ) { - astError( AST__XMLCM, "astXmlAddCharData(xml): Illegal attempt " - "to add non-white character data to the prologue or " - "epilogue of an XML document: \"%s\".", status, my_text ); - } else { - new = (AstXmlCharData *) astMalloc( sizeof( AstXmlBlack ) ); - InitXmlBlack( (AstXmlBlack *) new, AST__XMLBLACK, my_text, status ); - } - - } else { - new = (AstXmlCharData *) astMalloc( sizeof( AstXmlWhite ) ); - InitXmlWhite( (AstXmlWhite *) new, AST__XMLWHITE, my_text, status ); - } - -/* Free the memory holding the cleaned text */ - my_text = astFree( my_text ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) { - new = astXmlDelete( new ); - -/* Otherwise, add the content item to the element. */ - } else { - AddContent( this, where, (AstXmlContentItem *) new, status ); - } -} - -void astXmlAddComment_( AstXmlParent *this, int where, const char *text, int *status ){ -/* -*+ -* Name: -* astXmlAddComment - -* Purpose: -* Create a new XmlComment and add it to an XmlElement or XmlDocument. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlAddComment( AstXmlParent *this, int where, const char *text ) - -* Description: -* This function creates a new XmlComment structure representing -* an XML comment, and adds it into an existing element or document. - -* Parameters: -* this -* Pointer to the element or document to be modified. -* where -* Ignored if "this" is an XmlElement pointer. Otherwise, "where" -* indicates where the item should be added to the document: -* 1 - In the prologue, after the XML declaration but before the DTD. -* 2 - In the prologue, after the DTD but before the root element. -* 3 - In the epilogue, after the root element. -* text -* Pointer to a null terminated string containing the comment text. - -*- -*/ - -/* Local Variables: */ - AstXmlComment *new; /* Pointer to the new structure */ - char *my_text; /* Cleaned text */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Allocate space for the new structure. */ - new = (AstXmlComment *) astMalloc( sizeof( AstXmlComment ) ); - -/* Clean the text. */ - my_text = CleanText( text, status ); - -/* Initialise it. */ - InitXmlComment( new, AST__XMLCOM, my_text, status ); - -/* Free the memory */ - my_text = astFree( my_text ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) { - new = astXmlDelete( new ); - -/* Otherwise, add the content item to the element. */ - } else { - AddContent( this, where, (AstXmlContentItem *) new, status ); - } - -} - -AstXmlElement *astXmlAddElement_( AstXmlElement *this, const char *name, - const char *prefix, int *status ){ -/* -*+ -* Name: -* astXmlAddElement - -* Purpose: -* Create a new empty XmlElement and adds it to an XmlElement. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* AstXmlElement *astXmlAddElement( AstXmlElement *this, const char *name, -* const char *prefix ) - -* Description: -* This function creates a new XmlElement structure representing an -* empty XML element with the given name and namespace prefix, and -* adds it into an existing element. - -* Parameters: -* this -* A pointer to the element to be modified. This may be NULL. -* name -* The name for the element. -* prefix -* The namespace prefix for the element. May be NULL or blank, in -* which case any prefix at the start of "name" is used. - -* Returned Value: -* A pointer to the new structure is returned. This pointer should be -* freed using astXmlAnnul when no longer needed. - -* Notes: -* - A NULL pointer is returned if the inherited status value -* indicates an error has occurred on entry, or if this function -* should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstXmlElement *new; /* The returned pointer */ - -/* Initialise */ - new = NULL; - -/* Check the global error status. */ - if( !astOK ) return new; - -/* Allocate space for the new structure. */ - new = (AstXmlElement *) astMalloc( sizeof( AstXmlElement ) ); - -/* Initialise it. */ - InitXmlElement( new, AST__XMLELEM, name, prefix, status ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) { - new = astXmlDelete( new ); - -/* Otherwise, add the content item to the element. */ - } else { - AddContent( (AstXmlParent *) this, 0, (AstXmlContentItem *) new, status ); - } - -/* Return the result. */ - return new; - -} - -void astXmlAddPI_( AstXmlParent *this, int where, const char *target, const char *text, int *status ){ -/* -*+ -* Name: -* astXmlAddPI - -* Purpose: -* Create a new XmlPI and add it to an element or document. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlAddPI( AstXmlParent *this, int where, const char *target, -* const char *text ) - -* Description: -* This function creates a new XmlPI structure representing an -* XML "programming instruction", and adds it into an existing element -* or document. - -* Parameters: -* this -* Pointer to the element or document to be modified. This should -* be a pointer to an XmlElement or an XmlDocument. -* where -* Ignored if "this" is an XmlElement pointer. Otherwise, "where" -* indicates where the PI should be added to the document: -* 1 - In the prologue, after the XML declaration but before the DTD. -* 2 - In the prologue, after the DTD but before the root element. -* 3 - In the epilogue, after the root element. -* target -* Pointer to a null terminated string containing the PI target. -* text -* Pointer to a null terminated string containing the PI text. - -*- -*/ - -/* Local Variables: */ - AstXmlPI *new; /* Pointer to the new structure */ - char *my_text; /* Cleaned text */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Allocate space for the new structure. */ - new = (AstXmlPI *) astMalloc( sizeof( AstXmlPI ) ); - -/* Clean the text. */ - my_text = CleanText( text, status ); - -/* Initialise it. */ - InitXmlPI( new, AST__XMLPI, target, my_text, status ); - -/* Free the memory */ - my_text = astFree( my_text ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) { - new = astXmlDelete( new ); - -/* Otherwise, add the content item to the element. */ - } else { - AddContent( this, where, (AstXmlContentItem *) new, status ); - } -} - -void astXmlAddURI_( AstXmlElement *this, const char *prefix, const char *uri, int *status ){ -/* -*+ -* Name: -* astXmlAddURI - -* Purpose: -* Add a namespace prefix definition to an XmlElement, or change the -* default namespace. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlAddURI( AstXmlElement *this, const char *prefix, -* const char *uri ) - -* Description: -* This function adds a namespace prefix definition to a specified -* XmlElement, or changes the default namespace. If the suppliedprefix -* is already defined in the element, the associated URI is changed to -* the supplied URI. - -* Parameters: -* this -* The pointer to the element to be modified. -* prefix -* Pointer to a null terminated string containing the namespace -* prefix. If this is NULL or blank, then the supplied URI is used -* as the default namespace for this element and all child elements -* (except for child elements which define their own default -* namespace). -* uri -* Pointer to a null terminated string containing the namespace URI. -* If this is NULL or blank, and "prefix" is also NULL or blank, then -* this has the same effect of there being no default namespace within -* the supplied element. -*- -*/ - -/* Local Variables: */ - AstXmlNamespace *ns; /* The new namespace definition */ - AstXmlNamespace *oldns; /* The existing namespace definition */ - int i; /* Loop index */ - int nc; /* Length of namespace prefix */ - int nnspref; /* Number of namespace defintions in the element */ - int oldi; /* Index of existing attribute */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Initialise */ - oldns = NULL; - -/* Store the used length of the namespace prefix. */ - nc = prefix ? astChrLen( prefix ) : 0; - -/* If no namespace prefix has been supplied, just change the default - namespace URI. */ - if( !nc ) { - if( uri ) { - this->defns = astStore( this->defns, uri, strlen( uri ) + 1 ); - } else { - this->defns = astStore( this->defns, "", 1 ); - } - -/* Otherwise, add the namespace definition to the element. */ - } else { - -/* Create a new XmlNamespace. */ - ns = NewNamespace( prefix, uri, status ); - -/* If OK, indicate that the namespace is owned by the element. */ - if( astOK ) { - ( (AstXmlObject *) ns )->parent = (AstXmlParent *) this; - -/* Save the number of namespace definitions currently stored in the element. */ - nnspref = ( this->nsprefs ) ? this->nnspref : 0; - -/* Search the existing prefixes to see if a namespace with the given - prefix already exists. */ - oldi = -1; - for( i = 0; i < nnspref; i++ ) { - oldns = this->nsprefs[ i ]; - if( !strcmp( oldns->prefix, ns->prefix ) ) { - oldi = i; - break; - } - } - -/* If there is an existing namespace with the same prefix, replace the old - namespace with the new one created above. */ - if( oldi > -1 ){ - ((AstXmlObject *)oldns)->parent = NULL; - oldns = astXmlAnnul( oldns ); - this->nsprefs[ oldi ] = ns; - -/* Otherwise, attempt to extend the array to hold an extra namespace definition. */ - } else { - this->nsprefs = astGrow( this->nsprefs, nnspref + 1, - sizeof( AstXmlNamespace * ) ); - -/* Check all has gone OK. */ - if( astOK ) { - -/* Store the Namespace pointer in the array of Namespace pointers. */ - this->nsprefs[ nnspref ] = ns; - -/* Increment the number of namespaces in this element */ - this->nnspref = nnspref + 1; - } - } - } - } -} - -void *astXmlAnnul_( AstXmlObject *this, int *status ){ -/* -*+ -* Name: -* astXmlAnnul - -* Purpose: -* Free the resources used by an XmlObject. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void *astXmlAnnul( AstXmlObject *this ) - -* Description: -* This function frees the resources used to hold the XmlObject, together -* with any child objects contained within the supplied XmlObject. A NULL -* pointer is always returned. If the supplied object is still in use -* (that is, if its parent XmlElement still exists) then the resources -* are not freed, and a copy of the supplied pointer is returned. - -* Parameters: -* this -* pointer to the XmlObject to be freed. - -* Returned Value: -* A NULL pointer, or the supplied pointer if the XmlObject is still -* in use. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*- -*/ - -/* Return if a NULL pointer has been suppplied. */ - if( !this ) return NULL; - -/* Return the supplied pointer if the objects parent still exists. */ - if( this->parent && - astXmlCheckType( this->parent, AST__XMLPAR ) ) return this; - -#ifdef DEBUG -/* Remove the supplied object from the list of currently active XmlObjects. */ - RemoveObjectFromList( this ); -#endif - -/* Clean the objects contents, and free the memory holding the XmlObject. */ - CleanXml( this, this->type, status ); - astFree( this ); - -/* Return a NULL pointer. */ - return NULL; -} - -void *astXmlAnnulTree_( AstXmlObject *this, int *status ){ -/* -*+ -* Name: -* astXmlAnnulTree - -* Purpose: -* Free the resources used by a tree of XmlObjects. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void *astXmlAnnulTree( AstXmlObject *this ) - -* Description: -* This function finds the head of the tree containing the supplied -* XmlObject (either an XmlElement or an XmlDocument), and frees the -* resources associated with all members of the tree. A NULL pointer -* is always returned. - -* Parameters: -* this -* Pointer to a member of the tree of XmlObjects to be freed. - -* Returned Value: -* A NULL pointer. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*- -*/ - -/* Return if a NULL pointer has been suppplied. */ - if( !this ) return NULL; - -/* Find the root and annull it. This will free all children (i.e. - the entire tree). */ - return astXmlAnnul( astXmlGetRoot( this ) ); -} - -AstXmlObject *astXmlCopy_( AstXmlObject *this, int *status ) { -/* -*+ -* Name: -* astXmlCopy - -* Purpose: -* Produce a deep copy of a supplied XmlObject. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* AstXmlObject *astXmlCopy( AstXmlObject *this ) - -* Description: -* This function returns a pointer to a deep copy of the supplied -* XmlObject. - -* Parameters: -* this -* Pointer to the XmlObject to copy. - -* Returned Value: -* Pointer to the new copy. - -* Notes: -* - NULL is returned if NULL pointer is supplied. -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - - -/* Local Variables: */ - AstXmlAttribute *attr; - AstXmlBlack *black; - AstXmlCDataSection *cdata; - AstXmlComment *comm; - AstXmlDTDec *dtd; - AstXmlDeclPI *dec; - AstXmlDocument *doc, *newdoc; - AstXmlElement *elem, *newelem; - AstXmlNamespace *ns; - AstXmlObject *new; - AstXmlPI *pi; - AstXmlPrologue *pro, *newpro; - AstXmlWhite *white; - int i, type; - -/* Initialise */ - new = NULL; - -/* Check the global error status. */ - if( !astOK || !this ) return new; - -/* Initialise a new XmlObject of the required class, and copy any - sub-objects. */ - type = this->type; - if( type == AST__XMLELEM ){ - elem = (AstXmlElement *) this; - new = astMalloc( sizeof( AstXmlElement ) ); - InitXmlElement( (AstXmlElement *) new, AST__XMLELEM, - elem->name, elem->prefix, status ); - - newelem = (AstXmlElement *) new; - - newelem->attrs = astMalloc( sizeof( AstXmlAttribute *) * (size_t)elem->nattr ); - newelem->nattr = elem->nattr; - for( i = 0; i < elem->nattr; i++ ) { - newelem->attrs[ i ] = (AstXmlAttribute *) astXmlCopy( elem->attrs[ i ] ); - ((AstXmlObject *) newelem->attrs[ i ])->parent = (AstXmlParent *) newelem; - } - - newelem->items = astMalloc( sizeof( AstXmlContentItem *) * (size_t)elem->nitem ); - newelem->nitem = elem->nitem; - for( i = 0; i < elem->nitem; i++ ) { - newelem->items[ i ] = (AstXmlContentItem *) astXmlCopy( elem->items[ i ] ); - ((AstXmlObject *) newelem->items[ i ])->parent = (AstXmlParent *) newelem; - } - - newelem->nsprefs = astMalloc( sizeof( AstXmlNamespace *) * (size_t)elem->nnspref ); - newelem->nnspref = elem->nnspref; - for( i = 0; i < elem->nnspref; i++ ) { - newelem->nsprefs[ i ] = (AstXmlNamespace *) astXmlCopy( elem->nsprefs[ i ] ); - ((AstXmlObject *) newelem->nsprefs[ i ])->parent = (AstXmlParent *) newelem; - } - - if( elem->defns ) { - newelem->defns = astStore( NULL, elem->defns, - strlen( elem->defns ) + 1 ); - } - - newelem->complete = elem->complete; - - - } else if( type == AST__XMLATTR ){ - attr = (AstXmlAttribute *) this; - new = astMalloc( sizeof( AstXmlAttribute ) ); - InitXmlAttribute( (AstXmlAttribute *) new, AST__XMLATTR, - attr->name, attr->value, attr->prefix, status ); - - } else if( type == AST__XMLBLACK ){ - black = (AstXmlBlack *) this; - new = astMalloc( sizeof( AstXmlBlack ) ); - InitXmlBlack( (AstXmlBlack *) new, AST__XMLBLACK, - black->text, status ); - - } else if( type == AST__XMLWHITE ){ - white = (AstXmlWhite *) this; - new = astMalloc( sizeof( AstXmlWhite ) ); - InitXmlWhite( (AstXmlWhite *) new, AST__XMLWHITE, - white->text, status ); - - } else if( type == AST__XMLCDATA ){ - cdata = (AstXmlCDataSection *) this; - new = astMalloc( sizeof( AstXmlCDataSection ) ); - InitXmlCDataSection( (AstXmlCDataSection *) new, AST__XMLCDATA, - cdata->text, status ); - - } else if( type == AST__XMLCOM ){ - comm = (AstXmlComment *) this; - new = astMalloc( sizeof( AstXmlComment ) ); - InitXmlComment( (AstXmlComment *) new, AST__XMLCOM, - comm->text, status ); - - } else if( type == AST__XMLPI ){ - pi = (AstXmlPI *) this; - new = astMalloc( sizeof( AstXmlPI ) ); - InitXmlPI( (AstXmlPI *) new, AST__XMLPI, pi->target, pi->text, status ); - - } else if( type == AST__XMLNAME ){ - ns = (AstXmlNamespace *) this; - new = astMalloc( sizeof( AstXmlNamespace ) ); - InitXmlNamespace( (AstXmlNamespace *) new, AST__XMLNAME, ns->prefix, - ns->uri, status ); - - } else if( type == AST__XMLDOC ){ - doc = (AstXmlDocument *) this; - new = astMalloc( sizeof( AstXmlDocument ) ); - InitXmlDocument( (AstXmlDocument *) new, AST__XMLDOC, status ); - - newdoc = (AstXmlDocument *) new; - - if( doc->prolog ) { - newdoc->prolog = (AstXmlPrologue *) astXmlCopy( doc->prolog ); - ((AstXmlObject *) newdoc->prolog)->parent = (AstXmlParent *) newdoc; - } - - if( doc->root ) { - newdoc->root = (AstXmlElement *) astXmlCopy( doc->root ); - ((AstXmlObject *) newdoc->root)->parent = (AstXmlParent *) newdoc; - } - - newdoc->epilog = astMalloc( sizeof( AstXmlMiscItem *) * (size_t)doc->nepi ); - newdoc->nepi = doc->nepi; - for( i = 0; i < doc->nepi; i++ ) { - newdoc->epilog[ i ] = (AstXmlMiscItem *) astXmlCopy( doc->epilog[ i ] ); - ((AstXmlObject *) newdoc->epilog[ i ])->parent = (AstXmlParent *) newdoc; - } - - newdoc->current = NULL; - - } else if( type == AST__XMLPRO ){ - pro = (AstXmlPrologue *) this; - new = astMalloc( sizeof( AstXmlPrologue ) ); - InitXmlPrologue( (AstXmlPrologue *) new, AST__XMLPRO, status ); - - newpro = (AstXmlPrologue *) new; - - if( pro->xmldecl ) { - newpro->xmldecl = (AstXmlDeclPI *) astXmlCopy( pro->xmldecl ); - ((AstXmlObject *) newpro->xmldecl)->parent = (AstXmlParent *) newpro; - } - - if( pro->dtdec ) { - newpro->dtdec = (AstXmlDTDec *) astXmlCopy( pro->dtdec ); - ((AstXmlObject *) newpro->dtdec)->parent = (AstXmlParent *) newpro; - } - - newpro->misc1 = astMalloc( sizeof( AstXmlMiscItem *) * (size_t)pro->nmisc1 ); - newpro->nmisc1 = pro->nmisc1; - for( i = 0; i < pro->nmisc1; i++ ) { - newpro->misc1[ i ] = (AstXmlMiscItem *) astXmlCopy( pro->misc1[ i ] ); - ((AstXmlObject *) newpro->misc1[ i ])->parent = (AstXmlParent *) newpro; - } - - newpro->misc2 = astMalloc( sizeof( AstXmlMiscItem *) * (size_t)pro->nmisc2 ); - newpro->nmisc2 = pro->nmisc2; - for( i = 0; i < pro->nmisc2; i++ ) { - newpro->misc2[ i ] = (AstXmlMiscItem *) astXmlCopy( pro->misc2[ i ] ); - ((AstXmlObject *) newpro->misc2[ i ])->parent = (AstXmlParent *) newpro; - } - - } else if( type == AST__XMLDEC ){ - dec = (AstXmlDeclPI *) this; - new = astMalloc( sizeof( AstXmlDeclPI ) ); - InitXmlDeclPI( (AstXmlDeclPI *) new, AST__XMLDEC, dec->text, status ); - - } else if( type == AST__XMLDTD ){ - dtd = (AstXmlDTDec *) this; - new = astMalloc( sizeof( AstXmlDTDec ) ); - InitXmlDTDec( (AstXmlDTDec *) new, AST__XMLDTD, dtd->name, - dtd->external, dtd->internal, status ); - - } else if( astOK ) { - astError( AST__INTER, "CopyXml: Invalid object type (%d) supplied " - "(internal AST programming error).", status, type ); - } - -/* If an error occurred, delete the new structure. */ - if( !astOK ) new = astXmlDelete( new ); - -/* Return the result. */ - return new; -} - -const char *astXmlFormat_( AstXmlObject *this, int *status ) { -/* -*+ -* Name: -* astXmlFormat - -* Purpose: -* Converts an XmlObject into a character string. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* const char *astXmlFormat( AstXmlObject *this ) - -* Description: -* This function returns a pointer to a dynamically allocated string -* containing a textual representation of the supplied XmlObject. - -* Parameters: -* this -* Pointer to the XmlObject to format. - -* Returned Value: -* Pointer to a null terminated string holding the formated XmlObject. -* This string should be freed when no longer needed using astFree. - -* Notes: -* - No newlines or indentation strings are added to the returned string. -* - NULL is returned if NULL pointer is supplied. -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - return Format( this, -1, status ); -} - -const char *astXmlGetAttributeValue_( AstXmlElement *this, const char *name, int *status ){ -/* -*+ -* Name: -* astXmlGetAttributeValue - -* Purpose: -* Return a pointer to a string holding the value of a named attribute. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* const char *astXmlGetAttributeValue( AstXmlElement *this, const char *name ) - -* Description: -* This function returns a pointer to a constant string holding the -* value of a named attribute of a supplied element. If the element -* does not have the named attribute, a NULL pointer is returned but -* no error is reported. - -* Parameters: -* this -* The pointer to the XmlElement. -* name -* Pointer to a string holding the name of the attribute. The name -* may be preceded with a "prefix:" string, in which case the -* prefix will also be matched. If no prefix is included, the first -* attribute with the specified name is returned, regardless of -* its prefix. - -* Returned Value: -* Pointer to a string holding the value of the attribute within the -* supplied element, or NULL if the attribute was not found. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Local Variables: */ - const char *result; /* Returned pointer */ - AstXmlAttribute *attr; /* Pointer to the attribute */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Find the attribute. */ - attr = FindAttribute( this, name, status ); - -/* Get its value. */ - if( attr ) result = attr->value; - -/* Return the result. */ - return result; -} - -AstXmlContentItem *astXmlGetItem_( AstXmlElement *this, int item, int *status ){ -/* -*+ -* Name: -* astXmlGetItem - -* Purpose: -* Return a specified item of the content of an element. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* AstXmlContentItem *astXmlGetItem( AstXmlElement *this, int item ) - -* Description: -* This function returns a pointer to an item of the content of the -* specified element. - -* Parameters: -* this -* The pointer to the XmlElement. -* item -* The index of the required item, in the range zero to "nitem-1", -* where "nitem" is the number of items in the element as returned -* by astXmlGetNitem. An error is reported if the specified index -* is out of bounds. - -* Returned Value: -* A pointer to the requested item. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstXmlContentItem *result; /* The returned pointer */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Report an error if the supplie dindex is bad. */ - if( this->nitem == 0 ) { - astError( AST__XMLIT, "astXmlGetItem(xml): The supplied item index (%d) " - "is out of bounds. The supplied XmlObject has no content.", status, - item ); - - } else if( item < 0 || item >= this->nitem ) { - astError( AST__XMLIT, "astXmlGetItem(xml): The supplied item index (%d) " - "is out of bounds. Should be in the range 0 to %d.", status, - item, this->nitem-1 ); - } else { - result = this->items[ item ]; - } - -/* Return the result. */ - return result; -} - -const char *astXmlGetName_( AstXmlObject *this, int *status ){ -/* -*+ -* Name: -* astXmlGetName - -* Purpose: -* Return a pointer to a string holding the name of an XmlObject. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* const char *astXmlGetName( AstXmlObject *this ) - -* Description: -* This function returns a pointer to a constant string holding the -* name associated with an XmlObject. For elements and attributes, the -* "name" value is returned. For PI elements, the "target" value is -* returned. For namespace definitions, the "prefix" value is returned. -* An error is reported if the supplied XmlObject is of any other class. - -* Parameters: -* this -* The pointer to the XmlObject. - -* Returned Value: -* Pointer to the name string within the XML object. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Local Variables: */ - const char *result; /* Returned pointer */ - int type; /* Object type */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Return the relevant component of the structure, depending on its type. */ - type = this->type; - if( type == AST__XMLELEM ){ - result = ( (AstXmlElement *) this )->name; - - } else if( type == AST__XMLATTR ){ - result = ( (AstXmlAttribute *) this )->name; - - } else if( type == AST__XMLPI ){ - result = ( (AstXmlPI *) this )->target; - - } else if( type == AST__XMLNAME ){ - result = ( (AstXmlNamespace *) this )->prefix; - - } else { - astError( AST__INTER, "astXmlGetName: Inappropriate object type (%d) supplied " - "(internal AST programming error).", status, type ); - } - -/* Return the result. */ - return result; -} - -int astXmlGetNattr_( AstXmlElement *this, int *status ){ -/* -*+ -* Name: -* astXmlGetNattr - -* Purpose: -* Return the number of attributes held by an element. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* int astXmlGetNattr( AstXmlElement *this ) - -* Description: -* This function returns the number of attributes held by an element. - -* Parameters: -* this -* The pointer to the XmlElement. - -* Returned Value: -* The number of attributes held by the supplied element. - -* Notes: -* - Zero is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Check the global error status. */ - if( !astOK ) return 0; - -/* Return the result. */ - return ( this->attrs ) ? this->nattr : 0; -} - -int astXmlGetNitem_( AstXmlElement *this, int *status ){ -/* -*+ -* Name: -* astXmlGetNitem - -* Purpose: -* Return the number of items within the content of an element. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* int astXmlGetNitem( AstXmlElement *this ) - -* Description: -* This function returns the number of items within the content of an -* XmlElement. - -* Parameters: -* this -* The pointer to the XmlElement. - -* Returned Value: -* The number of items in the content of the supplied element. - -* Notes: -* - Zero is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Check the global error status. */ - if( !astOK ) return 0; - -/* Return the result. */ - return this->nitem; -} - -AstXmlParent *astXmlGetParent_( AstXmlObject *this, int *status ){ -/* -*+ -* Name: -* astXmlGetParent - -* Purpose: -* Return a pointer to the object which contains the supplied XmlObject. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* AstXmlParent *astXmlGetParent( AstXmlObject *this ) - -* Description: -* This function returns a pointer to the XmlParent object (either an -* XmlElement or an XmlDocument) which contains the specified XmlObject. -* The object can be a content item (an element, a comment, a CDATA -* section, a PI, or character data) in which case the enclosing -* XmlElement is returned, or an attribute or namespace definition in -* which case the XmlElement to which object refers is returned. -* If "this" is the root element of a document, a pointer to the -* XmlDocument is returned. - - -* Parameters: -* this -* The pointer to check. - -* Returned Value: -* Pointer to the parent, or NULL if the object does not have a parent. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Check the global error status. */ - if( !astOK ) return NULL; - -/* Return the result. */ - return this->parent; -} - -AstXmlObject *astXmlGetRoot_( AstXmlObject *this, int *status ){ -/* -*+ -* Name: -* astXmlGetRoot - -* Purpose: -* Return a pointer to the root XmlObject which contains the supplied -* XmlObject. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* AstXmlObject *astXmlGetRoot( AstXmlObject *this ) - -* Description: -* This function returns a pointer to the XmlObject which is the root of -* the tree containing the specified XmlObject. A pointer to the -* supplied XmlObject is returned if it has no parent. - -* Parameters: -* this -* The pointer to check. - -* Returned Value: -* Pointer to the root XmlObject, or a copy of the supplied pointer if -* the supplied XmlObject is the root. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstXmlObject *result; - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* If "this" is a document, check it has no parent. If not, return a - pointer to it. */ - if( astXmlCheckType( this, AST__XMLDOC ) ) { - if( this->parent ) { - astError( AST__INTER, "astXmlGetRoot(xml): An XmlDocument has a " - "non-null parent of type %ld (internal AST programming " - "error).", status, this->type ); - } else { - result = (AstXmlObject *) this; - } - -/* Otherwise... */ - } else if( this->parent ) { - result = astXmlGetRoot( this->parent ); - - } else { - result = this; - } - -/* Return the result. */ - return result; -} - -const char *astXmlGetTag_( AstXmlObject *this, int opening, int *status ){ -/* -*+ -* Name: -* astXmlGetTag - -* Purpose: -* Returns a string holding an XML tag describing the given XmlObject. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* const char *astXmlGetTag( AstXmlObject *this, int opening ) - -* Description: -* This function returns a pointer to a static string containing an -* XML tag describing the given XmlObject. - -* Parameters: -* this -* Pointer to the XmlObject. -* opening -* Indicates which tag is to be returned; the start tag or the end -* tag. If non-zero the start tag is returned. Otherwise, the -* end tag is returned. If the supplied XmlObject has no end -* tag (i.e. if it is an empty element, or if it is not an element), -* then NULL is returned but no error is reported. - -* Returned Value: -* Pointer to a null terminated string holding the tag. If the tag -* exceeds 200 characters, only the first 197 characters are returned -* and "..." is appended to the end. - -* Notes: -* - Subsequent invocations of this function will over-write the -* buffer which used to hold the returned string. -* - Empty elements are represented as an start tag of the form <.../>, -* with no corresponding end tag. -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char *result; /* The returned pointer */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get a dynamic string holding the formatted tag. */ - result = FormatTag( this, opening, status ); - -/* If OK, copy the result into the static buffer. */ - gettag_buff[ 0 ] = 0; - if( result ) { - if( astOK ) { - - if( strlen( result ) > AST__XML_GETTAG_BUFF_LEN ) { - strncpy( gettag_buff, result, AST__XML_GETTAG_BUFF_LEN -3 ); - strcpy( gettag_buff + AST__XML_GETTAG_BUFF_LEN - 3, "..." ); - } else { - strncpy( gettag_buff, result, AST__XML_GETTAG_BUFF_LEN ); - } - - gettag_buff[ AST__XML_GETTAG_BUFF_LEN ] = 0; - astFree( result ); - result = gettag_buff; - } else { - result = astFree( result ); - } - } - -/* Return the result. */ - return result; -} - -const char *astXmlGetType_( AstXmlObject *this, int *status ){ -/* -*+ -* Name: -* astXmlGetType - -* Purpose: -* Returns a string holding the type of the given XmlObject. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* const char *astXmlGetType( AstXmlObject *this ) - -* Description: -* This function returns a pointer to a static string containing the -* type of the given XmlObject. - -* Parameters: -* this -* Pointer to the XmlObject. - -* Returned Value: -* Pointer to a null terminated string holding the type string. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Local Variables: */ - const char *result; /* The returned pointer */ - int type; /* Element type */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - - type = this->type; - if( type == AST__XMLELEM ) { - result = "element"; - - } else if( type == AST__XMLATTR ) { - result = "attribute"; - - } else if( type == AST__XMLCDATA ) { - result = "CDATA section"; - - } else if( type == AST__XMLCOM ) { - result = "comment"; - - } else if( type == AST__XMLPI ) { - result = "processing instruction"; - - } else if( type == AST__XMLNAME ) { - result = "namespace"; - - } else if( type == AST__XMLDOC ) { - result = "document"; - - } else if( type == AST__XMLPRO ) { - result = "prologue"; - - } else if( type == AST__XMLDEC ) { - result = "XML delaration PI"; - - } else if( type == AST__XMLDTD ) { - result = "DTD"; - - } else if( type == AST__XMLWHITE ) { - result = "white-space character data "; - - } else if( type == AST__XMLBLACK ) { - result = "non-blank character data"; - - } else { - result = "unknown XML object"; - } - -/* Return the result. */ - return result; -} - -const char *astXmlGetURI_( AstXmlObject *this, int *status ){ -/* -*+ -* Name: -* astXmlGetURI - -* Purpose: -* Return a pointer to a string holding the namespace URI of an XmlObject. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* const char *astXmlGetURI( AstXmlObject *this ) - -* Description: -* This function returns a pointer to a constant string holding the -* namespace URI associated with an XmlObject. Only attributes, -* elements and namespaces have associated URIs, so a NULL pointer is -* returned for any other class of XmlObject. A NULL pointer is also -* returned if XmlObject does not belong to any namespace, or if it -* belongs to a unknown namespace (i.e. one for which no URI is -* available). Any namespace prefix attached to the supplied object is -* resolved first using any "xmlns" attributes contained in the same -* element, then using any "xmlns" attributes contained in the parent -* element, etc. - -* Parameters: -* this -* The pointer to the XmlObject. - -* Returned Value: -* Pointer to a string holding the namespace URI, or NULL. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Local Variables: */ - const char *prefix; /* Namespace prefix */ - const char *result; /* Returned pointer */ - int type; /* Object type */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Do each type of object separately. */ - type = this->type; - if( type == AST__XMLATTR ){ - prefix = ( (AstXmlAttribute *) this )->prefix; - -/* Attributes have no default name space. Therefore if there is no prefix, - return NULL. If there is a prefix, resolve it within the context of - the attributes parent element. */ - if( prefix ) { - result = ResolvePrefix( prefix, (AstXmlElement *) this->parent, status ); - } - - } else if( type == AST__XMLELEM ){ - prefix = ( (AstXmlElement *) this )->prefix; - -/* If there is a prefix, resolve it within the context of this element. */ - if( prefix ) { - result = ResolvePrefix( prefix, (AstXmlElement *) this, status ); - -/* Elements do have a default name space. Therefore if there is no prefix, - return the default name space within the context of this element. */ - } else { - result = DefaultURI( (AstXmlElement *) this, status ); - } - -/* If the supplied object is a namespace, just return the associated URI. */ - } else if( type == AST__XMLNAME ){ - result = ( (AstXmlNamespace *) this )->uri; - - } - -/* Return the result. */ - return result; -} - -const char *astXmlGetValue_( AstXmlObject *this, int report, int *status ){ -/* -*+ -* Name: -* astXmlGetValue - -* Purpose: -* Return a pointer to a string holding the value of an XmlObject. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* const char *astXmlGetValue( AstXmlObject *this, int report ) - -* Description: -* This function returns a pointer to a constant string holding the -* value associated with an XmlObject. For attributes, the attribute value -* is returned. For PI elements, the "text" value is returned. For -* namespace definitions, the "URI" value is returned. For character -* data, the character data is returned. For CDATA sections the "text" -* value is returned. For comments, the "text" value is returned. -* If the XmlObject is an element, then a non-NULL value is returned -* only if the element contains a single content item holding character -* data. In this case a pointer to the character data is returned. -* A null value is returned in all other cases (but no error is -* reported unless "report" is non-zero). - -* Parameters: -* this -* The pointer to the XmlObject. -* report -* Report an error if the supplied XmlObject does not have a value? - -* Returned Value: -* Pointer to a string holding the value of the XML object. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - -/* Local Variables: */ - AstXmlContentItem *item;/* Element content */ - const char *result; /* Returned pointer */ - int type; /* Object type */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Return the relevant component of the structure, depending on its type. */ - type = this->type; - if( type == AST__XMLATTR ){ - result = ( (AstXmlAttribute *) this )->value; - - } else if( type == AST__XMLBLACK ){ - result = ( (AstXmlBlack *) this )->text; - - } else if( type == AST__XMLWHITE ){ - result = ( (AstXmlWhite *) this )->text; - - } else if( type == AST__XMLCDATA ){ - result = ( (AstXmlCDataSection *) this )->text; - - } else if( type == AST__XMLCOM ){ - result = ( (AstXmlComment *) this )->text; - - } else if( type == AST__XMLPI ){ - result = ( (AstXmlPI *) this )->text; - - } else if( type == AST__XMLNAME ){ - result = ( (AstXmlNamespace *) this )->uri; - - } else if( type == AST__XMLELEM ){ - if( astXmlGetNitem( (AstXmlElement *) this ) == 1 ) { - item = astXmlGetItem( (AstXmlElement *) this, 0 ); - if( astXmlCheckType( item, AST__XMLCHAR ) ) { - result = astXmlGetValue( item, report ); - } - } - - if( !result && astOK && report ) { - astError( AST__BADIN, "astRead(xml): Cannot get the value of " - "element \"<%s>\": its contents are not pure character " - "data.", status, astXmlGetName( this ) ); - } - - } else if( report ) { - astError( AST__INTER, "astXmlGetValue(xml): Cannot get the value of " - "an XmlObject of type %d (internal AST programming " - "error).", status, type ); - } - -/* Return the result. */ - return result; -} - -void astXmlInsertElement_( AstXmlElement *this, AstXmlElement *elem, int *status ){ -/* -*+ -* Name: -* astXmlInsertElement - -* Purpose: -* Inserts an existing XmlElement into another XmlElement. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlInsertElement( AstXmlElement *this, AstXmlElement *elem ) - -* Description: -* This function inserts a given XmlElement "elem" into another given -* XmlElement "this". An error is reported if "elem" already has a -* parent. - -* Parameters: -* this -* A pointer to the element to be modified. -* elem -* The element to be inserted into "this". - -*- -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Report AN error if "elem" has already been inserted into - another element. */ - if( ((AstXmlObject *) elem)->parent ) { - astError( AST__INTER, "astXmlInsertElement(xml): Cannot insert \"%s\" " - "into \"%s\" because it already has a parent (\"%s\") " - "(internal AST programming error).", status, - astXmlGetTag( elem, 1 ), astXmlGetTag( this, 1 ), - astXmlGetTag( ((AstXmlObject *) elem)->parent, 1 ) ); - -/* Otherwise, add the content item to the element. */ - } else { - AddContent( (AstXmlParent *) this, 0, (AstXmlContentItem *) elem, status ); - } -} - -void astXmlPurge_( AstXmlParent *this, int *status ) { -/* -*+ -* Name: -* astXmlPurge - -* Purpose: -* Remove blank content from a parent object. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlPurge( AstXmlParent *this ) - -* Description: -* This function removes all character data containing only whitespace -* from the supplied document or element. It is recursive, in that it also -* removes white space from all children elements. - -* Parameters: -* this -* Pointer to the document or element. - -*- -*/ - -/* Local Variables: */ - int i; /* Content item index */ - AstXmlContentItem *item; /* Next content item */ - AstXmlMiscItem *misc; /* Nest miscalleneous item */ - AstXmlDocument *doc; /* This document */ - AstXmlPrologue *pro; /* This document prologue */ - AstXmlElement *elem; /* This element */ - -/* Check the global error status. */ - if( !astOK || !this ) return; - -/* If this is a a document.. */ - if( astXmlCheckType( this, AST__XMLDOC ) ) { - doc = (AstXmlDocument *) this; - astXmlPurge( doc->prolog ); - astXmlPurge( doc->root ); - - i = -1; - while( ++i < doc->nepi ) { - misc = doc->epilog[ i ]; - if( astXmlCheckType( misc, AST__XMLWHITE ) ) { - misc = astXmlDelete( misc ); - i--; - } - } - -/* If this is a prologue.. */ - } else if( astXmlCheckType( this, AST__XMLPRO ) ) { - pro = (AstXmlPrologue *) this; - - i = -1; - while( ++i < pro->nmisc1 ) { - misc = pro->misc1[ i ]; - if( astXmlCheckType( misc, AST__XMLWHITE ) ) { - misc = astXmlDelete( misc ); - i--; - } - } - - i = -1; - while( ++i < pro->nmisc2 ) { - misc = pro->misc2[ i ]; - if( astXmlCheckType( misc, AST__XMLWHITE ) ) { - misc = astXmlDelete( misc ); - i--; - } - } - - -/* If this is an element */ - } else if( astXmlCheckType( this, AST__XMLELEM ) ) { - elem = (AstXmlElement *) this; - - i = -1; - while( ++i < elem->nitem ) { - item = elem->items[ i ]; - - if( astXmlCheckType( item, AST__XMLWHITE ) ) { - item = astXmlDelete( item ); - i--; - - } else if( astXmlCheckType( item, AST__XMLELEM ) ) { - astXmlPurge( (AstXmlParent *) item ); - } - } - } -} - -void astXmlRemoveAttr_( AstXmlElement *this, const char *name, - const char *prefix, int *status ){ -/* -*+ -* Name: -* astXmlRemoveAttr - -* Purpose: -* Removes an attribute from its parent element. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlRemoveAttr( AstXmlElement *this, const char *name, -* const char *prefix ) - -* Description: -* This function removes a named attribute from its parent element. - -* Parameters: -* this -* The pointer to the element containing the attribute to be removed. -* name -* Pointer to a null terminated string containing the attribute name. -* prefix -* The namespace prefix for the attribute. May be NULL or blank, in -* which case any prefix at the start of "name" is used. -*- -*/ - -/* Local Variables: */ - AstXmlAttribute *attr; /* Pointer to temporary attribute structure */ - AstXmlAttribute *oldattr; /* Pointer to existing attribute */ - int i; /* Attribute index */ - int nattr; /* Number of attributes in parent */ - int oldi; /* Indexof existing attribute */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Initialise */ - oldattr = NULL; - -/* Create a new XmlAttribute with blank value. */ - attr = NewAttribute( name, "", prefix, status ); - if( astOK ) { - -/* Get the number of attributes currently stored in the element. */ - nattr = ( this->attrs ) ? this->nattr : 0; - -/* Search the existing attributes to see if an attribute with the given - name and prefix already exists. */ - oldi = -1; - for( i = 0; i < nattr; i++ ) { - oldattr = this->attrs[ i ]; - if( !strcmp( oldattr->name, attr->name ) ) { - if( !oldattr->prefix && !attr->prefix ) { - oldi = i; - break; - } else if( oldattr->prefix && attr->prefix && - !strcmp( oldattr->prefix, attr->prefix ) ){ - oldi = i; - break; - } - } - } - -/* If there is an existing attribute with the same name and prefix, - delete it. */ - if( oldi > -1 ) astXmlDelete( oldattr ); - -/* Delete the temporary attribute structure. */ - attr = astXmlDelete( attr ); - - } -} - -void astXmlRemoveItem_( AstXmlContentItem *this, int *status ){ -/* -*+ -* Name: -* astXmlRemoveItem - -* Purpose: -* Removes an item of content from its parent element or document. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlRemoveItem( AstXmlContentItem *this ) - -* Description: -* This function removes an item of content from its parent element, -* or removes the root element from a document. The removed item is not -* annulled and may be subsequently added into another element. - -* Parameters: -* this -* The pointer to the item to be removed form its parent. -*- -*/ - -/* Local Variables: */ - AstXmlDocument *doc; /* Pointer to parent document */ - AstXmlElement *elem; /* Pointer to parent element */ - AstXmlParent *parent; /* Pointer to parent */ - int found; /* Was the item found within its parent? */ - int i; /* Item index */ - int j; /* Item index */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Get a pointer to the items parent element, and check it is not null. */ - parent = ( (AstXmlObject *) this )->parent; - if( parent && astXmlCheckType( parent, AST__XMLELEM ) ) { - elem = (AstXmlElement *) parent; - -/* Search through all the items within the parent element looking for the - supplied item. */ - found = 0; - for( i = 0; i < elem->nitem; i++ ) { - if( elem->items[ i ] == this ) { - -/* When found, decrement the number of items in the element, and shuffle - all the remaining item pointers down one slot to over-write it, then - nullify the parent pointer in the supplied object and leave the loop. */ - (elem->nitem)--; - for( j = i; j < elem->nitem; j++ ) { - elem->items[ j ] = elem->items[ j + 1 ]; - } - ( (AstXmlObject *) this )->parent = NULL; - found = 1; - break; - } - } - -/* Report an error if the item was not found. */ - if( !found ) { - astError( AST__INTER, "astXmlRemoveItem: The parent of the supplied " - "item does not contain the item (internal AST programming " - "error)." , status); - } - -/* If the parent is an XmlDocument, check the item being removed is the - root element. */ - } else if( parent && astXmlCheckType( parent, AST__XMLDOC ) ) { - doc = (AstXmlDocument *) parent; - if( (AstXmlElement *) this == doc->root ) { - ( (AstXmlObject *) this )->parent = NULL; - doc->root = NULL; - } - } -} - -void astXmlRemoveURI_( AstXmlElement *this, const char *prefix, int *status ){ -/* -*+ -* Name: -* astXmlRemoveURI - -* Purpose: -* Removes an namespace prefix from its parent element. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlRemoveURI( AstXmlElement *this, const char *prefix ) - -* Description: -* This function removes a named namespace prefix from its parent element. - -* Parameters: -* this -* The pointer to the element containing the namespace prefix to be -* removed. -* prefix -* The namespace prefix to remove. -*- -*/ - -/* Local Variables: */ - AstXmlNamespace *ns; /* Temporary namespace structure */ - AstXmlNamespace *oldns; /* Pointer to existing namespace */ - int oldi; /* Index of namespace within its parent */ - int i; /* Namespace index */ - int nns; /* Number of existing namespaces */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Initialise */ - oldns = NULL; - -/* Create a new XmlNamespace with blank URI. */ - ns = NewNamespace( prefix, "", status ); - if( astOK ) { - -/* Get the number of namespace prefixes currently stored in the element. */ - nns = ( this->nsprefs ) ? this->nnspref : 0; - -/* Search the list of existing namespace prefixes to see if the given prefix - is included. */ - oldi = -1; - for( i = 0; i < nns; i++ ) { - oldns = this->nsprefs[ i ]; - if( !strcmp( oldns->prefix, ns->prefix ) ){ - oldi = i; - break; - } - } - -/* If the supplied namespace prefix was found in the list, delete it. */ - if( oldi > -1 ) astXmlDelete( oldns ); - -/* Delete the temporary namespace structure. */ - ns = astXmlDelete( ns ); - - } -} - -void astXmlSetDTDec_( AstXmlDocument *this, const char *text1, - const char *text2, const char *text3, int *status ){ -/* -*+ -* Name: -* astXmlSetDTDec - -* Purpose: -* Set the Document Type declaration for a document. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlSetDTDEC( AstXmlDocument *this, const char *text1, -* const char *text2, const char *text3 ) - -* Description: -* This function stores an Document Type declaration of the form -* -* -* -* in the supplied document. Any previous DTD is removed. - -* Parameters: -* this -* The pointer to the document. -* text1 -* The document type name. -* text2 -* The text defining the external elements of the document type -* (may be NULL). -* text3 -* The text defining the internal elements of the document type -* (may be NULL). Do not include delimiting "[" and "]" characters. -*- -*/ - -/* Local Variables: */ - AstXmlDTDec *new; /* Pointer to new DT declaration */ - AstXmlPrologue *pro; /* Pointer to prologue */ - char *my_text2; /* Cleaned text2 */ - char *my_text3; /* Cleaned text3 */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Allocate space for the new structure. */ - new = (AstXmlDTDec *) astMalloc( sizeof( AstXmlDTDec ) ); - -/* Clean the text. */ - my_text2 = CleanText( text2, status ); - my_text3 = CleanText( text3, status ); - -/* Initialise it. */ - InitXmlDTDec( new, AST__XMLDTD, text1, my_text2, my_text3, status ); - -/* Free the memory */ - my_text2 = astFree( my_text2 ); - my_text3 = astFree( my_text3 ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) { - new = astXmlDelete( new ); - -/* Otherwise, store it in the document, deleting any existing declaration - first. */ - } else { - -/* Create a prologue if necessary. */ - if( !this->prolog ) this->prolog = NewPrologue( this, status ); - - pro = this->prolog; - if( pro->dtdec ) astXmlDelete( pro->dtdec ); - pro->dtdec = new; - } -} - -void astXmlSetXmlDec_( AstXmlDocument *this, const char *text, int *status ){ -/* -*+ -* Name: -* astXmlSetXmlDec - -* Purpose: -* Set the XML declaration for a document. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void astXmlSetXmlDec( AstXmlDocument *this, const char *text ) - -* Description: -* This function stores an XML declaration of the form -* -* -* -* in the supplied document. Any previous XML declaration is removed. - -* Parameters: -* this -* The pointer to the document. -* text -* The text to include in the XML declaration tag. -*- -*/ - -/* Local Variables: */ - AstXmlDeclPI *new; /* Pointer to new XML delcaration */ - AstXmlPrologue *pro; /* Pointer to prologue */ - char *my_text; /* Cleaned text */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Allocate space for the new structure. */ - new = (AstXmlDeclPI *) astMalloc( sizeof( AstXmlDeclPI ) ); - -/* Clean the text. */ - my_text = CleanText( text, status ); - -/* Initialise it. */ - InitXmlDeclPI( new, AST__XMLDEC, my_text, status ); - -/* Free the memory */ - my_text = astFree( my_text ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) { - new = astXmlDelete( new ); - -/* Otherwise, store it in the document, deleting any existing declaration - first. */ - } else { - -/* Create a prologue if necessary. */ - if( !this->prolog ) this->prolog = NewPrologue( this, status ); - - pro = this->prolog; - if( pro->xmldecl ) astXmlDelete( pro->xmldecl ); - pro->xmldecl = new; - } -} - -const char *astXmlShow_( AstXmlObject *this, int *status ) { -/* -*+ -* Name: -* astXmlShow - -* Purpose: -* Converts an XmlObject into a character string with indentation. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* const char *astXmlShow( AstXmlObject *this ) - -* Description: -* This function returns a pointer to a dynamically allocated string -* containing a textual representation of the supplied XmlObject. -* Newline characters are added to the string if needed to ensure that -* each item of content within an element starts on a new line, and all -* tags are preceded by an indentation string consisting of a number -* of spaces. - -* Parameters: -* this -* Pointer to the XmlObject to format. - -* Returned Value: -* Pointer to a null terminated string holding the formated XmlObject. -* This string should be freed when no longer needed using astFree. - -* Notes: -* - NULL is returned if a NULL pointer is supplied. -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - return Format( this, 0, status ); -} - -static void CheckName( const char *name, const char *noun, const char *method, - int nullok, int *status ){ -/* -* Name: -* CheckName - -* Purpose: -* Checks the supplied string is a valid XML name. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* void CheckName( const char *name, const char *noun, const char *method, -* int nullok, int *status ) - -* Description: -* This function checks that the supplied string is a valid XML name, -* and reports an error otherwise. - -* Parameters: -* name -* The name string to check -* noun -* A word to describe the object which the name applies to - for use in -* error messages only. -* method -* The name of the calling method - for use in error messages only. -* nullok -* If non-zero, then a null or empty name is assumed to be -* acceptable. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - const char *c; /* Pointer to next character to check */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the string is not null. */ - if( !name ) { - if( !nullok ) astError( AST__XMLNM, "%s: A NULL pointer was supplied " - "instead of an XML %s name.", status, method, noun ); - } else { - - c = name; - if( *c == 0 ) { - if( !nullok ) astError( AST__XMLNM, "%s: An empty string was supplied " - "instead of an XML %s name.", status, method, noun ); - } else { - - if( !isalpha( *c ) && *c != '_' ) { - astError( AST__XMLNM, "%s: The illegal XML %s name \"%s\" was " - "encountered.", status, method, noun, name ); - - } else { - while( *(++c) ) { - if( !isalnum( *c ) && *c != '_' && *c != '-' && *c != '.' ){ - astError( AST__XMLNM, "%s: The illegal XML %s name \"%s\" was " - "encountered.", status, method, noun, name ); - break; - } - } - } - } - } -} - -static void CheckPrefName( char *name, const char *noun, const char *method, int *status ){ -/* -* Name: -* CheckPrefName - -* Purpose: -* Checks the supplied string is a valid XML (prefix:)name. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* void CheckPrefName( char *name, const char *noun, const char *method, int *status ) - -* Description: -* This function checks that the supplied string is a valid XML -* (prefix:)name combination and reports an error otherwise. - -* Parameters: -* name -* The string to check -* noun -* A word to describe the object which the name applies to - for use in -* error messages only. -* method -* The name of the calling method - for use in error messages only. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - char *colon; /* Pointer to first colon */ - char *temp; /* Pointer to temporary string */ - int nc; /* Length of temporary string */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Search for a ":" character. */ - colon = strchr( name, ':' ); - -/* If found, temporarily convert the colon into a null so that it - terminates the prefix string. */ - if( colon ) { - *colon = 0; - -/* Check the string before the colon is a valid name. */ - temp = NULL; - temp = astAppendString( temp, &nc, noun ); - temp = astAppendString( temp, &nc, " prefix" ); - CheckName( name, temp, method, 0, status ); - temp = astFree( temp ); - -/* Restore the colon. */ - *colon = ':'; - -/* Check the string following the colon is a valid name. */ - CheckName( colon + 1, noun, method, 0, status ); - -/* If not found, the whole supplied string must be a name. */ - } else { - CheckName( name, noun, method, 0, status ); - } -} - -static int CheckType( long int given, long int want, int *status ){ -/* -* Name: -* CheckType - -* Purpose: -* Check that the supplied type identifies an object of a given class. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* int CheckType( long int given, long int want, int *status ) - -* Description: -* This function checks that the supplied type identifier identifies -* a specified class of XML object, or a derived class. A flag is -* returned indicating if the check succeeds. No error is reported if -* the check fails. - -* Parameters: -* given -* The type value to be checked. -* want -* The type of the required class. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the check is passed, zero if not of if an error has -* already occurred. - -* Notes: -* - This function attempts to execute even if the error status is set. -*/ - -/* Local Variables: */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - -/* Check the wanted type is recognised. Report an error if not. */ - if( want != AST__XMLOBJECT && - want != AST__XMLELEM && - want != AST__XMLATTR && - want != AST__XMLCHAR && - want != AST__XMLCDATA && - want != AST__XMLCOM && - want != AST__XMLPI && - want != AST__XMLNAME && - want != AST__XMLCONT && - want != AST__XMLPRO && - want != AST__XMLDEC && - want != AST__XMLDTD && - want != AST__XMLMISC && - want != AST__XMLBLACK && - want != AST__XMLWHITE && - want != AST__XMLPAR && - want != AST__XMLDOC ) { - if( astOK ) { - astError( AST__INTER, "CheckType(Xml): Unsupported XML object " - "type (%ld) supplied for parameter \"want\" (internal " - "AST programming error). ", status, want ); - } - -/* You should never be given a generic "interface" type since the - "wanted" value comes from the "type" component of an XmlObject (an explicit - class type should always be given). */ - } else if( given == AST__XMLPAR || - given == AST__XMLMISC || - given == AST__XMLCONT || - given == AST__XMLCHAR ) { - if( astOK ) { - astError( AST__INTER, "CheckType(Xml): Generic type (%ld) supplied for " - "parameter \"given\" (internal AST programming error).", status, - given ); - } - -/* If the above is OK, return a non-zero value if the type to be tested - equals the wanted type. */ - } else if( want == given ) { - result = 1; - -/* If any class of XmlObject is acceptable, check that he given class - type is a valid XML class type. */ - } else if( want == AST__XMLOBJECT ) { - result = ( given == AST__XMLELEM || - given == AST__XMLATTR || - given == AST__XMLCDATA || - given == AST__XMLCOM || - given == AST__XMLPI || - given == AST__XMLNAME || - given == AST__XMLPRO || - given == AST__XMLDEC || - given == AST__XMLDTD || - given == AST__XMLWHITE || - given == AST__XMLBLACK || - given == AST__XMLDOC ); - -/* Otherwise, for "interface" types, check if the given class "implements - the interface". */ - } else if( want == AST__XMLCONT ) { - result = ( given == AST__XMLELEM || - given == AST__XMLBLACK || - given == AST__XMLWHITE || - given == AST__XMLCDATA || - given == AST__XMLCOM || - given == AST__XMLPI ); - - } else if( want == AST__XMLMISC ) { - result = ( given == AST__XMLWHITE || - given == AST__XMLCOM || - given == AST__XMLPI ); - - } else if( want == AST__XMLCHAR ) { - result = ( given == AST__XMLWHITE || - given == AST__XMLBLACK ); - - } else if( want == AST__XMLPAR ) { - result = ( given == AST__XMLDOC || - given == AST__XMLPRO || - given == AST__XMLELEM ); - } - -/* Return the result. */ - return result; -} - -int astXmlCheckType_( void *this, long int want, int *status ){ -/* -*+ -* Name: -* astXmlCheckType - -* Purpose: -* Check that the supplied object is of a given class. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* int astXmlCheckType( void *this, long int want ) - -* Description: -* This function checks that the supplied XmlObject is of a specified -* class of XML object, or a derived class. A flag is returned indicating -* if the check succeeds. No error is reported if the check fails. - -* Parameters: -* this -* The object to check. -* want -* The type of the required class. - -* Returned Value: -* Non-zero if the check is passed, zero if not of if an error has -* already occurred. - -* Notes: -* - This function attempts to execute even if the error status is set. -*- -*/ - - if( this ) { - return CheckType( ((AstXmlObject *) this)->type, want, status ); - } else { - return 0; - } -} - -static char *CleanText( const char *text, int *status ){ -/* -* Name: -* CleanText - -* Purpose: -* Normalise end-of-lines in the supplied text. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* char *CleanText( const char *text, int *status ) - -* Description: -* This function returns a copy of "text in which "\r\n" has been -* replaced by "\n" and any remaining "\r" characters have been -* replaced by "\n". - -* Parameters: -* text -* A pointer to a text string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated string containing the required -* copy. - -* Notes: -* - NULL is returned if this function is called with the global error -* status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - char *d; /* Pointer to next returned character */ - char *result; /* Returned pointer */ - char *c; /* Pointer to next supplied character */ - char lc; /* Previous character */ - -/* Initialise */ - result = NULL; - -/* Return if the pointer is NULL or if an error has occurred. */ - if( !astOK || !text ) return result; - -/* Take a copy of the supplied text */ - result = astStore( NULL, text, strlen( text ) + 1 ); - -/* Clean the text by replacing "\r\n" by "\n". */ - c = result - 1; - d = c; - lc = 0; - while( *(++c) ) { - if( *c != '\n' || lc != '\r' ) d++; - *d = ( lc = *c ); - } - *(++d) = 0; - -/* Now further clean it by replacing "\r" by "\n". */ - c = result - 1; - while( *(++c) ) { - if( *c == '\r' ) *c = '\n'; - } - -/* Return the result. */ - return result; -} - -static void CleanXml( AstXmlObject *this, long int type, int *status ){ -/* -* Name: -* CleanXml - -* Purpose: -* Free the resources used within an XmlObject. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* void CleanXml( AstXmlObject *this, long int type, int *status ) - -* Description: -* This function frees the resources used internally within the -* supplied XmlObject. - -* Parameters: -* this -* pointer to the XmlObject to be cleaned. -* type -* The type of XmlObject being cleaned. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if an error has already -* occurred. -*- -*/ - -/* Local Variables: */ - AstXmlAttribute *attr; - AstXmlBlack *black; - AstXmlCDataSection *cdatasec; - AstXmlComment *comm; - AstXmlDTDec *dtd; - AstXmlDeclPI *dec; - AstXmlDocument *doc; - AstXmlElement *elem; - AstXmlNamespace *ns; - AstXmlPI *pi; - AstXmlPrologue *pro; - AstXmlWhite *white; - -/* Return if a NULL pointer has been suppplied. */ - if( !this ) return; - -/* For the base XmlObject class, clear the object type, etc. */ - if( type == AST__XMLOBJECT ){ - this->type = AST__XMLBAD; - this->parent = NULL; - -/* For each derived class of XmlObject, first clean the parent component, - then clean any further resources. */ - } else if( type == AST__XMLELEM ){ - - elem = (AstXmlElement *) this; - - elem->name = astFree( elem->name ); - elem->defns = astFree( elem->defns ); - elem->prefix = astFree( elem->prefix ); - - while( elem->nattr > 0 ) astXmlDelete( elem->attrs[ 0 ] ); - elem->attrs = astFree( elem->attrs ); - - while( elem->nitem > 0 ) astXmlDelete( elem->items[ 0 ] ); - elem->items = astFree( elem->items ); - - while( elem->nnspref > 0 ) astXmlDelete( elem->nsprefs[ 0 ] ); - elem->nsprefs = astFree( elem->nsprefs ); - - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLATTR ){ - attr = (AstXmlAttribute *) this; - attr->name = astFree( attr->name ); - attr->value = astFree( attr->value ); - attr->prefix = astFree( attr->prefix ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLBLACK ){ - black = (AstXmlBlack *) this; - black->text = astFree( black->text ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLWHITE ){ - white = (AstXmlWhite *) this; - white->text = astFree( white->text ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLCDATA ){ - cdatasec = (AstXmlCDataSection *) this; - cdatasec->text = astFree( cdatasec->text ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLCOM ){ - comm = (AstXmlComment *) this; - comm->text = astFree( comm->text ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLPI ){ - pi = (AstXmlPI *) this; - pi->target = astFree( pi->target ); - pi->text = astFree( pi->text ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLNAME ){ - ns = (AstXmlNamespace *) this; - ns->prefix = astFree( ns->prefix ); - ns->uri = astFree( ns->uri ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLDOC ){ - doc = (AstXmlDocument *) this; - doc->prolog = astXmlDelete( doc->prolog ); - doc->root = astXmlDelete( doc->root ); - while( doc->nepi > 0 ) astXmlDelete( doc->epilog[ 0 ] ); - doc->epilog = astFree( doc->epilog ); - doc->current = NULL; - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLPRO ){ - pro = (AstXmlPrologue *) this; - pro->xmldecl = astXmlDelete( pro->xmldecl ); - while( pro->nmisc1 > 0 ) astXmlDelete( pro->misc1[ 0 ] ); - pro->misc1 = astFree( pro->misc1 ); - pro->dtdec = astXmlDelete( pro->dtdec ); - while( pro->nmisc2 > 0 ) astXmlDelete( pro->misc2[ 0 ] ); - pro->misc2 = astFree( pro->misc2 ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLDEC ){ - dec = (AstXmlDeclPI *) this; - dec->text = astFree( dec->text ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( type == AST__XMLDTD ){ - dtd = (AstXmlDTDec *) this; - dtd->name = astFree( dtd->name ); - dtd->external = astFree( dtd->external ); - dtd->internal = astFree( dtd->internal ); - CleanXml( this, AST__XMLOBJECT, status ); - - } else if( astOK ) { - astError( AST__INTER, "CleanXml: Invalid object type (%ld) supplied " - "(internal AST programming error).", status, type ); - } - -} - -static const char *DefaultURI( AstXmlElement *elem, int *status ){ -/* -* Name: -* DefaultURI - -* Purpose: -* Find the URI associated with the default namespace. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* const char *DefaultURI( AstXmlElement *elem, int *status ) - -* Description: -* This function returns the default namespace URI defined within the -* given element. If the element does not define a default namespace URI, -* then this function is called recursively on the parent element. If -* there is no parent element, NULL is returned. - -* Parameters: -* elem -* The pointer to the XmlElement. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a string holding the URI, or NULL if not found. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*/ - -/* Local Variables: */ - AstXmlParent *parent; /* Parent of "this" */ - const char *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - -/* Check the global error status, and the supplied element. */ - if( !astOK || !elem ) return result; - -/* If the supplied element defines a default namespace URI, return it. - Otherwise, call this function to get the default namespace URI from the - parent element. */ - result = elem->defns; - if( !result ) { - parent = ( (AstXmlObject *) elem )->parent; - if( astXmlCheckType( parent, AST__XMLELEM ) ) { - result = DefaultURI( (AstXmlElement *) parent, status ); - } - } - -/* If the element has a blank default namespace URI, then return NULL - since the XML namespaces specification says that "The default - namespace can be set to the empty string. This has the same effect, - within the scope of the declaration, of there being no default - namespace". */ - if( result && astChrLen( result ) == 0 ) result = NULL; - -/* Return the result. */ - return result; -} - -void *astXmlDelete_( void *obj_ptr, int *status ){ -/* -*+ -* Name: -* astXmlDelete - -* Purpose: -* Remove the supplied XmlObject from its parent and delete it. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* void *astXmlDelete( void *obj ) - -* Description: -* This function removes the supplied XmlObject from its parent and -* deletes it using astXmlAnnul. - -* Parameters: -* obj -* The pointer to the XmlObject to be deleted. - -* Returned Value: -* NULL - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*- -*/ - -/* Local Variables: */ - AstXmlDocument *doc; /* Pointer to XM document */ - AstXmlElement *elem; /* Pointer to XML element */ - AstXmlObject *obj; /* Pointer to XmlObject */ - AstXmlParent *parent; /* Pointer to parent */ - AstXmlPrologue *pro; /* Pointer to XML prologue */ - int i; /* Loop counter */ - int j; /* Loop counter */ - int n; /* Number of values in list */ - int ok; /* Is obj a child of its parent? */ - void *result; /* Returned pointer */ - -/* Initialise */ - result = NULL; - ok = 0; - -/* Check we have an XmlObject. */ - if( !astXmlCheckType( obj_ptr, AST__XMLOBJECT ) ) return result; - -/* Get the parent of the supplied object. */ - obj = (AstXmlObject *) obj_ptr; - parent = obj->parent; - if( parent ) { - -/* First deal with cases where we are deleting items from a document. */ - if( astXmlCheckType( parent, AST__XMLDOC ) ) { - doc = (AstXmlDocument *) parent; - - if( astXmlCheckType( obj, AST__XMLPRO ) ) { - if( (AstXmlPrologue *) obj == doc->prolog ) { - doc->prolog = NULL; - ok = 1; - } - - } else if( astXmlCheckType( obj, AST__XMLELEM ) ) { - if( (AstXmlElement *) obj == doc->root ) { - doc->root = NULL; - ok = 1; - } - - } else if( astXmlCheckType( obj, AST__XMLMISC ) ) { - n = doc->nepi; - for( i = 0; i < n; i++ ) { - if( doc->epilog[ i ] == (AstXmlMiscItem *) obj ) { - for( j = i + 1; j < n; j++ ) { - doc->epilog[ j - 1 ] = doc->epilog[ j ]; - } - doc->epilog[ --doc->nepi ] = NULL; - ok = 1; - break; - } - } - - } else if( astOK ) { - astError( AST__INTER, "astXmlDelete(xml): XmlObject of type %ld has " - "inappropriate parent of type %ld (internal AST " - "programming error).", status, obj->type, parent->type ); - } - -/* Now deal with cases where we are deleting items from a prologue. */ - } else if( astXmlCheckType( parent, AST__XMLPRO ) ) { - pro = (AstXmlPrologue *) parent; - - if( astXmlCheckType( obj, AST__XMLDEC ) ) { - if( (AstXmlDeclPI *) obj == pro->xmldecl ) { - pro->xmldecl = NULL; - ok = 1; - } - - } else if( astXmlCheckType( obj, AST__XMLDTD ) ) { - if( (AstXmlDTDec *) obj == pro->dtdec ) { - pro->dtdec = NULL; - ok = 1; - } - - } else if( astXmlCheckType( obj, AST__XMLMISC ) ) { - n = pro->nmisc1; - for( i = 0; i < n; i++ ) { - if( pro->misc1[ i ] == (AstXmlMiscItem *) obj ) { - for( j = i + 1; j < n; j++ ) { - pro->misc1[ j - 1 ] = pro->misc1[ j ]; - } - pro->misc1[ --pro->nmisc1 ] = NULL; - ok = 1; - break; - } - } - - if( !ok ) { - n = pro->nmisc2; - for( i = 0; i < n; i++ ) { - if( pro->misc2[ i ] == (AstXmlMiscItem *) obj ) { - for( j = i + 1; j < n; j++ ) { - pro->misc2[ j - 1 ] = pro->misc2[ j ]; - } - pro->misc2[ --pro->nmisc2 ] = NULL; - ok = 1; - break; - } - } - } - - } else if( astOK ) { - astError( AST__INTER, "astXmlDelete(xml): XmlObject of type %ld has " - "inappropriate parent of type %ld (internal AST " - "programming error).", status, obj->type, parent->type ); - } - -/* Now deal with cases where we are deleting items from an element. */ - } else if( astXmlCheckType( parent, AST__XMLELEM ) ) { - elem = (AstXmlElement *) parent; - -/* Remove the object form the appropriate list in the parent, and - then shuffle down the remaining entries in the list and decrement the - size of the list. */ - if( astXmlCheckType( obj, AST__XMLATTR ) ) { - n = elem->nattr; - for( i = 0; i < n; i++ ) { - if( elem->attrs[ i ] == (AstXmlAttribute *) obj ) { - for( j = i + 1; j < n; j++ ) { - elem->attrs[ j - 1 ] = elem->attrs[ j ]; - } - elem->attrs[ --elem->nattr ] = NULL; - ok = 1; - break; - } - } - - } else if( astXmlCheckType( obj, AST__XMLNAME ) ) { - n = elem->nnspref; - for( i = 0; i < n; i++ ) { - if( elem->nsprefs[ i ] == (AstXmlNamespace *) obj ) { - for( j = i + 1; j < n; j++ ) { - elem->nsprefs[ j - 1 ] = elem->nsprefs[ j ]; - } - elem->nsprefs[ --elem->nnspref ] = NULL; - ok = 1; - break; - } - } - - } else if( astXmlCheckType( obj, AST__XMLCONT ) ) { - n = elem->nitem; - for( i = 0; i < n; i++ ) { - if( elem->items[ i ] == (AstXmlContentItem *) obj ) { - for( j = i + 1; j < n; j++ ) { - elem->items[ j - 1 ] = elem->items[ j ]; - } - elem->items[ --elem->nitem ] = NULL; - ok = 1; - break; - } - } - } - - } else if( astOK ) { - astError( AST__INTER, "astXmlDelete(xml): XmlObject of type %ld has " - "inappropriate parent of type %ld (internal AST " - "programming error).", status, obj->type, parent->type ); - } - -/* Nullify the parent pointer so that astXmlAnnul will delete the object. */ - obj->parent = NULL; - -/* If the supplied object has no parent, we can continue to annul it. */ - } else { - ok = 1; - } - -/* Report an error if required. */ - if( !ok && astOK ) { - astError( AST__INTER, "astXmlDelete(xml): Supplied XmlObject (type %ld) " - "is not owned by its own parent (internal AST " - "programming error).", status, obj->type ); - } - -/* Delete the object. */ - result = astXmlAnnul( obj ); - -/* Annul the object and return the resulting NULL pointer. */ - return result; -} - -static AstXmlAttribute *FindAttribute( AstXmlElement *this, const char *name0, - int *status ){ -/* -* Name: -* FindAttribute - -* Purpose: -* Search an XmlElement for a named attribute - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* AstXmlAttribute *FindAttribute( AstXmlElement *this, const char *name0, -* int *status ) - -* Description: -* This function searches the supplied XmlElement for an attribute -* with the given name. If found, a pointer to the XmlAttribute is -* returned. Otherwise NULL is returned. - -* Parameters: -* this -* The pointer to the XmlElement. -* name0 -* Pointer to a string holding the name of the attribute. The name -* may be preceded with a "prefix:" string, in which case the -* prefix will also be matched. If no prefix is included, the first -* attribute with the specified name is returned, regardless of -* its prefix. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to the XmlAttribute, or NULL if not found. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*/ - -/* Local Variables: */ - AstXmlAttribute *result; /* Returned pointer */ - char name_buffer[ 50 ]; /* Buffer for name */ - char prefix_buffer[ 50 ]; /* Buffer for prefix */ - const char *colon; /* Pointer to colon in supplied string */ - const char *name1; /* Pointer to name to be checked */ - const char *name; /* Pointer to name to be searched for */ - const char *prefix1; /* Pointer to prefix to be checked */ - const char *prefix; /* Pointer to prefix to be searched for */ - int i; /* Loop count */ - size_t len; /* Length of string */ - -/* Initialise */ - result = NULL; - name = name0; - prefix = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* If the supplied name string contains a colon, split it up into prefix - and name. */ - if( ( colon = strchr( name0, ':' ) ) ) { - len = colon - name0; - - if( len > 49 ) { - astError( AST__XMLNM, "FindAttribute: The XML prefix in \"%s\" " - "is too long (> 49 characters).", status, name0 ); - } else { - strncpy( prefix_buffer, name0, len ); - prefix_buffer[ len ] = 0; - prefix = prefix_buffer; - len = strlen( colon + 1 ); - - if( len > 49 ) { - astError( AST__XMLNM, "FindAttribute: The XML attribute name " - "in \"%s\" is too long (> 49 characters).", status, name0 ); - } else { - strcpy( name_buffer, colon + 1 ); - name = name_buffer; - } - - } - - } - -/* Loop round all the attributes in the element. */ - for( i = 0; i < this->nattr; i++ ) { - name1 = this->attrs[ i ]->name; - prefix1 = this->attrs[ i ]->prefix; - -/* Compare the attribute name (and prefix) with the supplied name (and - prefix). Leave the loop if they match. */ - if( !strcmp( name1, name ) && - ( !prefix || ( prefix1 && !strcmp( prefix1, prefix ) ) ) ) { - result = this->attrs[ i ]; - break; - } - } - -/* Return the result. */ - return result; -} - -static const char *Format( AstXmlObject *this, int ind, int *status ){ -/* -* Name: -* Format - -* Purpose: -* Converts an XmlObject into a character string. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* const char *Format( AstXmlObject *this, int ind, int *status ) - -* Description: -* This function returns a pointer to a dynamically allocated string -* containing a textual representation of the supplied XmlObject. - -* Parameters: -* this -* Pointer to the XmlObject to format. -* ind -* If the XmlObject is an element, then each content item within -* the element will be prefixed by a string containing "ind" spaces -* (indenting the returned element itself is the responsibility of -* the caller and so "this" is not itself indented within this function). -* In addition, a newline character will be included at the start -* of the prefix if required, to ensure that each new item starts -* on a new line. If "ind" is less than zero, then no prefixes are -* added. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null terminated string holding the formated XmlObject. -* This string should be freed when no longer needed using astFree. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*/ - -/* Local Variables: */ - AstXmlPrologue *pro; /* Pointer to XML prologue */ - AstXmlDocument *doc; /* Pointer to XML document */ - AstXmlAttribute *attrib; /* Pointer to XML attribute */ - AstXmlWhite *white; /* Pointer to character data */ - AstXmlBlack *black; /* Pointer to character data */ - AstXmlElement *elem; /* Pointer to XML element */ - AstXmlNamespace *ns; /* Pointer to XML namespace instruction */ - char *result; /* The returned pointer */ - const char *temp; /* A temporary string pointer */ - int i; /* Loop count */ - int nc; /* Length of returned string */ - int type; /* Object type */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK || !this ) return result; - -/* Get the object type */ - type = this->type; - -/* If this is an element... */ - if( this->type == AST__XMLELEM ) { - temp = FormatTag( this, 1, status ); - result = astAppendString( result, &nc, temp ); - temp = astFree( (void *) temp ); - - elem = (AstXmlElement *) this; - if( elem->nitem > 0 ) { - -/* Go round all the items of content. */ - for( i = 0; i < elem->nitem; i++ ) { - -/* Ignore whitespace elements unless we are not producing indentation. */ - if( !astXmlCheckType( elem->items[ i ], AST__XMLWHITE ) || - ind < 0 ) { - -/* Format the item */ - temp = Format( (AstXmlObject *) elem->items[ i ], ( ( ind > -1 ) ? ind + IND_INC : -1 ), status ); - if( temp ) { - -/* Now append the next item of content, and free its memory. */ - if( ind > -1 ) { - result = AppendLine( result, &nc, temp, - ( (ind > -1) ? ind + IND_INC : -1 ), status ); - } else { - result = astAppendString( result, &nc, temp ); - } - temp = astFree( (void *) temp ); - } - } - } - -/* Finally append the end tag. */ - temp = FormatTag( this, 0, status ); - if( ind > -1 ) { - result = AppendLine( result, &nc, temp, ind, status ); - } else { - result = astAppendString( result, &nc, temp ); - } - temp = astFree( (void *) temp ); - - } - -/* If this is an attribute... */ - } else if( type == AST__XMLATTR ){ - attrib = (AstXmlAttribute *) this; - - if( attrib->prefix ) { - result = astAppendString( result, &nc, attrib->prefix ); - result = astAppendString( result, &nc, ":" ); - } - - temp = AddEscapes( attrib->value, status ); - result = astAppendString( result, &nc, attrib->name ); - result = astAppendString( result, &nc, "=\"" ); - result = astAppendString( result, &nc, temp ); - result = astAppendString( result, &nc, "\"" ); - temp = astFree( (void *) temp ); - - } else if( type == AST__XMLWHITE ){ - white = (AstXmlWhite *) this; - temp = AddEscapes( white->text, status ); - result = astAppendString( result, &nc, temp ); - temp = astFree( (void *) temp ); - - } else if( type == AST__XMLBLACK ){ - black = (AstXmlBlack *) this; - temp = AddEscapes( black->text, status ); - result = astAppendString( result, &nc, temp ); - temp = astFree( (void *) temp ); - - } else if( type == AST__XMLCDATA || - type == AST__XMLCOM || - type == AST__XMLPI || - type == AST__XMLDEC || - type == AST__XMLDTD ){ - - temp = FormatTag( this, 1, status ); - result = astAppendString( result, &nc, temp ); - temp = astFree( (void *) temp ); - - } else if( type == AST__XMLNAME ){ - ns = (AstXmlNamespace *) this; - result = astAppendString( result, &nc, "xmlns:" ); - result = astAppendString( result, &nc, ns->prefix ); - result = astAppendString( result, &nc, "=\"" ); - result = astAppendString( result, &nc, ns->uri ); - result = astAppendString( result, &nc, "\"" ); - - } else if( type == AST__XMLPRO ){ - pro = (AstXmlPrologue *) this; - result = astAppendString( result, &nc, - Format( (AstXmlObject *) pro->xmldecl, ind, status ) ); - -/* Append all the miscalleneous items before the DTD. */ - for( i = 0; i < pro->nmisc1; i++ ) { - temp = Format( (AstXmlObject *) pro->misc1[ i ], ind, status ); - if( temp ) { - if( ind > -1 ) { - result = AppendLine( result, &nc, temp, ind, status ); - } else { - result = astAppendString( result, &nc, temp ); - } - temp = astFree( (void *) temp ); - } - } - -/* Append the DTD. */ - temp = Format( (AstXmlObject *) pro->dtdec, ind, status ); - if( temp ) { - if( ind > -1 ) { - result = AppendLine( result, &nc, temp, ind, status ); - } else { - result = astAppendString( result, &nc, temp ); - } - temp = astFree( (void *) temp ); - } - -/* Append all the miscalleneous items after the DTD. */ - for( i = 0; i < pro->nmisc2; i++ ) { - temp = Format( (AstXmlObject *) pro->misc2[ i ], ind, status ); - if( temp ) { - if( ind > -1 ) { - result = AppendLine( result, &nc, temp, ind, status ); - } else { - result = astAppendString( result, &nc, temp ); - } - temp = astFree( (void *) temp ); - } - } - - } else if( type == AST__XMLDOC ){ - doc = (AstXmlDocument *) this; - -/* Format the prologue. */ - result = astAppendString( result, &nc, - Format( (AstXmlObject *) doc->prolog, ind, status ) ); - -/* Append the root element. */ - temp = Format( (AstXmlObject *) doc->root, ind, status ); - if( temp ) { - if( ind > -1 ) { - result = AppendLine( result, &nc, temp, ind, status ); - } else { - result = astAppendString( result, &nc, temp ); - } - temp = astFree( (void *) temp ); - } - -/* Append all the miscalleneous items in the epilogue. */ - for( i = 0; i < doc->nepi; i++ ) { - temp = Format( (AstXmlObject *) doc->epilog[ i ], ind, status ); - if( temp ) { - if( ind > -1 ) { - result = AppendLine( result, &nc, temp, ind, status ); - } else { - result = astAppendString( result, &nc, temp ); - } - temp = astFree( (void *) temp ); - } - } - - } else if( astOK ) { - astError( AST__INTER, "Format(xml): Invalid object type (%d) supplied " - "(internal AST programming error).", status, type ); - } - -/* Free the returned string if an error has occurred. */ - if( !astOK ) result = astFree( result ); - -/* Return the result. */ - return result; -} - -static char *FormatTag( AstXmlObject *this, int opening, int *status ){ -/* -* Name: -* FormatTag - -* Purpose: -* Returns a string holding an XML tag describing the given XmlObject. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* char *FormatTag( AstXmlObject *this, int opening, int *status ) - -* Description: -* This function returns a pointer to a dynamic string containing an -* XML tag describing the given XmlObject. - -* Parameters: -* this -* Pointer to the XmlObject. -* opening -* Indicates which tag is to be returned; the start tag or the end -* tag. If non-zero the start tag is returned. Otherwise, the -* end tag is returned. If the supplied XmlObject has no end -* tag (i.e. if it is an empty element, or if it is not an element), -* then NULL is returned but no error is reported. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a dynamically allocated string holding the tag. - -* Notes: -* - Empty elements are represented as an start tag of the form <.../>, -* with no corresponding end tag. -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*- -*/ - - -/* Local Variables: */ - AstXmlCDataSection *cdata;/* Pointer to XML CDATA section */ - AstXmlElement *elem; /* Pointer to XML element */ - AstXmlComment *com; /* Pointer to XML comment */ - AstXmlPI *pi; /* Pointer to XML processing instruction */ - AstXmlDTDec *dtd; /* Pointer to XML data type declaration */ - AstXmlDeclPI *xmlpi; /* XML version declaration */ - char *result; /* The returned pointer */ - const char *temp; /* A temporary string pointer */ - int i; /* Loop count */ - int nc; /* Length of returned string */ - int type; /* Object type */ - -/* Initialise */ - result = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Get the object type */ - type = this->type; - -/* If this is an element... */ - if( this->type == AST__XMLELEM ) { - elem = (AstXmlElement *) this; - - if( opening ) { - result = astAppendString( result, &nc, "<" ); - if( elem->prefix ) { - result = astAppendString( result, &nc, elem->prefix ); - result = astAppendString( result, &nc, ":" ); - } - result = astAppendString( result, &nc, elem->name ); - - if( elem->defns ) { - result = astAppendString( result, &nc, " xmlns=\"" ); - result = astAppendString( result, &nc, elem->defns ); - result = astAppendString( result, &nc, "\"" ); - } - - for( i = 0; i < elem->nnspref; i++ ) { - temp = Format( (AstXmlObject *) elem->nsprefs[ i ], -1, status ); - if( temp ) { - result = AppendChar( result, &nc, ' ', status ); - result = astAppendString( result, &nc, temp ); - temp = astFree( (void *) temp ); - } - } - - for( i = 0; i < elem->nattr; i++ ) { - temp = Format( (AstXmlObject *) elem->attrs[ i ], -1, status ); - if( temp ){ - result = AppendChar( result, &nc, ' ', status ); - result = astAppendString( result, &nc, temp ); - temp = astFree( (void *) temp ); - } - } - - if( elem->nitem == 0 ) result = astAppendString( result, &nc, "/" ); - result = astAppendString( result, &nc, ">" ); - - } else if( elem->nitem > 0 ) { - result = astAppendString( result, &nc, "prefix ) { - result = astAppendString( result, &nc, elem->prefix ); - result = astAppendString( result, &nc, ":" ); - } - result = astAppendString( result, &nc, elem->name ); - result = astAppendString( result, &nc, ">" ); - } - - } else if( type == AST__XMLDTD ){ - dtd = (AstXmlDTDec *) this; - if( opening && dtd->name && dtd->name[0] ) { - result = astAppendString( result, &nc, "name ); - if( dtd->external && dtd->external[ 0 ] ) { - result = astAppendString( result, &nc, " " ); - result = astAppendString( result, &nc, dtd->external ); - } - if( dtd->internal && dtd->internal[ 0 ] ) { - result = astAppendString( result, &nc, " [" ); - result = astAppendString( result, &nc, dtd->internal ); - result = astAppendString( result, &nc, "]" ); - } - result = astAppendString( result, &nc, ">" ); - } - - } else if( type == AST__XMLCDATA ){ - if( opening ) { - cdata = (AstXmlCDataSection *) this; - result = astAppendString( result, &nc, "text ); - result = astAppendString( result, &nc, "]]>" ); - } - - } else if( type == AST__XMLCOM ){ - if( opening ) { - com = (AstXmlComment *) this; - result = astAppendString( result, &nc, "" ); - } - - } else if( type == AST__XMLPI ){ - pi = (AstXmlPI *) this; - if( opening ) { - result = astAppendString( result, &nc, "target ); - if( pi->text && pi->text[0] ) { - result = astAppendString( result, &nc, " " ); - result = astAppendString( result, &nc, pi->text ); - } - result = astAppendString( result, &nc, "?>" ); - } - - } else if( type == AST__XMLDEC ){ - xmlpi = (AstXmlDeclPI *) this; - if( opening && xmlpi->text && xmlpi->text[0] ) { - result = astAppendString( result, &nc, "text && xmlpi->text[0] ) { - result = astAppendString( result, &nc, " " ); - result = astAppendString( result, &nc, xmlpi->text ); - } - result = astAppendString( result, &nc, "?>" ); - } - } - -/* If notOK, free the rteurned string. */ - if( !astOK ) result = astFree( result ); - -/* Return the result. */ - return result; -} - -static void InitXmlAttribute( AstXmlAttribute *new, int type, const char *name, - const char *value, const char *prefix, int *status ){ -/* -* Name: -* InitXmlAttribute - -* Purpose: -* Initialise a new XmlAttribute. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlAttribute( AstXmlAttribute *new, int type, const char *name, -* const char *value, const char *prefix, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlAttribute -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* name -* The name for the attribute. -* value -* The value for the attribute -* prefix -* The namespace prefix for the attribute. May be NULL or blank, in -* which case any prefix at the start of "name" is used. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - const char *colon; /* Pointer to colon within supplied name */ - char *newname; /* Pointer to name string (no prefix) */ - char *newpref; /* Pointer to name string */ - int nc; /* Length of prefix string */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLATTR, status ) ){ - astError( AST__INTER, "InitXmlAttribute: Supplied object type (%d) " - "does not represent an XmlAttribute", status, type ); - } - -/* Ensure we have non-NULL pointers. */ - if( !name ) name = ""; - if( !value ) value = ""; - -/* If no prefix was supplied, extract any prefix from the start of the - supplied name. */ - newname = (char *) name; - newpref = (char *) prefix; - colon = NULL; - - if( !prefix || astChrLen( prefix ) == 0 ){ - colon = strchr( name, ':' ); - if( colon ) { - nc = colon - name; - newpref = astStore( NULL, name, nc + 1 ); - newpref[ nc ] = 0; - - nc = strlen( name ) - ( colon - name ) - 1; - newname = astStore( NULL, colon + 1, nc + 1 ); - newname[ nc ] = 0; - } - } - -/* Check the supplied name and prefix are valid XML 'names'. */ - CheckName( newname, "attribute", "InitXmlAttribute", 0, status ); - CheckName( newpref, "attribute", "InitXmlAttribute", 1, status ); - -/* Initialise the parent XmlObject component. */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Initialise the items specific to this class of structure. */ - new->name = astStore( NULL, newname, strlen( newname ) + 1 ); - new->value = astStore( NULL, value, strlen( value ) + 1 ); - new->prefix = NULL; - if( newpref ) { - nc = strlen( newpref ); - if( nc > 0 ) new->prefix = astStore( NULL, newpref, nc + 1 ); - } - -/* Free any name and prefix extracted from the supplied name string */ - if( colon ) { - newname = astFree( newname ); - newpref = astFree( newpref ); - } -} - -static void InitXmlCDataSection( AstXmlCDataSection *new, int type, - const char *text, int *status ){ -/* -* Name: -* InitXmlCDataSection - -* Purpose: -* Initialise a new XmlCDataSection. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlCDataSection( AstXmlCDataSection *new, int type, -* const char *text, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlCDataSection -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* text -* Pointer to a null terminated string holding the text. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLCDATA, status ) ){ - astError( AST__INTER, "InitXmlCDataSection: Supplied object type (%d) " - "does not represent an XmlCDataSection", status, type ); - } - -/* Initialise the parent XmlObject component. */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Ensure we have non-NULL pointers. */ - if( !text ) text = ""; - -/* Initialise the items specific to this class of structure. */ - new->text = astStore( NULL, text, strlen( text ) + 1 ); -} - -static void InitXmlWhite( AstXmlWhite *new, int type, const char *text, int *status ){ -/* -* Name: -* InitXmlWhite - -* Purpose: -* Initialise a new XmlWhite. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlWhite( AstXmlWhite *new, int type, const char *text, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlWhite -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* text -* Pointer to a null terminated string holding the text. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - const char *c; /* Pointer to next character */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLWHITE, status ) ){ - astError( AST__INTER, "InitXmlWhite: Supplied object type (%d) " - "does not represent an XmlWhite", status, type ); - } - -/* Initialise the parent XmlObject component. */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Ensure we have non-NULL pointers. */ - if( !text ) text = ""; - -/* Report an error if the text is not white. */ - c = text - 1; - while( *(++c) ) { - if( !isspace( *c ) ) { - astError( AST__XMLCM, "InitXmlWhite(xml): Illegal XML whitespace " - "string supplied \"%s\" - not all characters are white.", status, - text ); - break; - } - } - -/* Initialise the items specific to this class of structure. */ - new->text = astStore( NULL, text, strlen( text ) + 1 ); -} - -static void InitXmlBlack( AstXmlBlack *new, int type, const char *text, int *status ){ -/* -* Name: -* InitXmlBlack - -* Purpose: -* Initialise a new XmlBlack. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlBlack( AstXmlBlack *new, int type, const char *text, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlBlack -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* text -* Pointer to a null terminated string holding the text. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLBLACK, status ) ){ - astError( AST__INTER, "InitXmlBlack: Supplied object type (%d) " - "does not represent an XmlBlack", status, type ); - } - -/* Initialise the parent XmlObject component. */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Ensure we have non-NULL pointers. */ - if( !text ) text = ""; - -/* Initialise the items specific to this class of structure. */ - new->text = astStore( NULL, text, strlen( text ) + 1 ); -} - -static void InitXmlComment( AstXmlComment *new, int type, const char *text, int *status ){ -/* -* Name: -* InitXmlComment - -* Purpose: -* Initialise a new XmlComment. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlComment( AstXmlComment *new, int type, const char *text, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlComment -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* text -* Pointer to a null terminated string holding the text. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLCOM, status ) ){ - astError( AST__INTER, "InitXmlComment: Supplied object type (%d) " - "does not represent an XmlComment", status, type ); - } - -/* Initialise the parent XmlObject component. */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Ensure we have non-NULL pointers. */ - if( !text ) text = ""; - -/* Initialise the items specific to this class of structure. Report an error - if the comment is illegal. */ - if( strstr( text, "--" ) && astOK ) { - astError( AST__XMLCM, "InitXmlCom(xml): Illegal XML comment " - "supplied \"%s\" - comments may not contain the " - "string \"--\".", status, text ); - new->text = NULL; - } else { - new->text = astStore( NULL, text, strlen( text ) + 1 ); - } -} - -static void InitXmlDeclPI( AstXmlDeclPI *new, int type, const char *text, int *status ){ -/* -* Name: -* InitXmlDeclPI - -* Purpose: -* Initialise a new XmlDeclPI. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlDeclPI( AstXmlDeclPI *new, int type, const char *text, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlDeclPI -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* text -* Pointer to a null terminated string holding the text. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLDEC, status ) ){ - astError( AST__INTER, "InitXmlDeclPI: Supplied object type (%d) " - "does not represent an XmlDeclPI", status, type ); - } - -/* Initialise the parent XmlObject component. */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Ensure we have non-NULL pointers. */ - if( !text ) text = ""; - -/* Initialise the items specific to this class of structure. */ - new->text = astStore( NULL, text, strlen( text ) + 1 ); -} - -static void InitXmlDocument( AstXmlDocument *new, int type, int *status ){ -/* -* Name: -* InitXmlDocument - -* Purpose: -* Initialise a new XmlDocument. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlDocument( AstXmlDocument *new, int type, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlDocument -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLDOC, status ) ){ - astError( AST__INTER, "InitXmlDocument: Supplied object type (%d) " - "does not represent an XmlDocument", status, type ); - } - -/* Initialise the parent XmlObject */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Initialise the items specific to this class of structure. */ - new->prolog = NULL; - new->root = NULL; - new->epilog = NULL; - new->nepi = 0; - new->current = NULL; -} - -static void InitXmlDTDec( AstXmlDTDec *new, int type, const char *name, - const char *external, const char *internal, int *status ){ -/* -* Name: -* InitXmlDTDec - -* Purpose: -* Initialise a new XmlDTDec. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* void InitXmlDTDec( AstXmlDTDec *new, int type, const char *name, -* const char *external, const char *internal, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlDTDec -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* name -* The document type name -* external -* The external SYSTEM id. -* internal -* The internal declaration markup text (this is not checked or -* parsed). -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLDTD, status ) ){ - astError( AST__INTER, "InitXmlDTDec: Supplied object type (%d) " - "does not represent an XmlDTDec", status, type ); - } - -/* Initialise the parent XmlObject */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Ensure we have non-NULL pointers. */ - if( !name ) name = ""; - if( !external ) external = ""; - if( !internal ) internal = ""; - -/* Initialise the items specific to this class of structure. */ - new->name = astStore( NULL, name, strlen( name ) + 1 ); - new->external = astStore( NULL, external, strlen( external ) + 1 ); - new->internal = astStore( NULL, internal, strlen( internal ) + 1 ); -} - -static void InitXmlElement( AstXmlElement *new, int type, const char *name, - const char *prefix, int *status ){ -/* -* Name: -* InitXmlElement - -* Purpose: -* Initialise a new XmlElement. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlElement( AstXmlElement *new, int type, const char *name, -* const char *prefix, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlElement -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* name -* The name for the element. -* prefix -* The namespace prefix for the element. May be NULL or blank, in -* which case any prefix at the start of "name" is used. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - const char *colon; /* Pointer to colon within supplied name */ - char *newname; /* Pointer to name string (no prefix) */ - char *newpref; /* Pointer to name string */ - int nc; /* Length of prefix string */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLELEM, status ) ){ - astError( AST__INTER, "InitXmlElement: Supplied object type (%d) " - "does not represent an XmlElement", status, type ); - } - -/* Ensure we have non-NULL pointers. */ - if( !name ) name = ""; - -/* If no prefix was supplied, extract any prefix from the start of the - supplied name. */ - newname = (char *) name; - newpref = (char *) prefix; - colon = NULL; - - if( !prefix || astChrLen( prefix ) == 0 ){ - colon = strchr( name, ':' ); - if( colon ) { - nc = colon - name; - newpref = astStore( NULL, name, nc + 1 ); - newpref[ nc ] = 0; - - nc = strlen( name ) - ( colon - name ) - 1; - newname = astStore( NULL, colon + 1, nc + 1 ); - newname[ nc ] = 0; - } - } - -/* Check the supplied name and prefix are valid XML 'names'. */ - CheckName( newname, "element", "InitXmlElement", 0, status ); - CheckName( newpref, "element", "InitXmlElement", 1, status ); - -/* Initialise the parent XmlObject component. */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Initialise the items specific to this class of structure. */ - new->name = astStore( NULL, newname, strlen( newname ) + 1 ); - new->attrs = NULL; - new->nattr = 0; - new->items = NULL; - new->nitem = 0; - new->defns = NULL; - new->nsprefs = NULL; - new->nnspref = 0; - new->complete = 0; - - new->prefix = NULL; - if( newpref ) { - nc = strlen( newpref ); - if( nc > 0 ) new->prefix = astStore( NULL, newpref, nc + 1 ); - } - -/* Free any name and prefix extracted from the supplied name string */ - if( colon ) { - newname = astFree( newname ); - newpref = astFree( newpref ); - } -} - -static void InitXmlNamespace( AstXmlNamespace *new, int type, const char *prefix, - const char *uri, int *status ){ -/* -* Name: -* InitXmlNamespace - -* Purpose: -* Initialise a new XmlNamespace. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlNamespace( AstXmlNamespace *new, int type, const char *prefix, -* const char *uri, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlNamespace -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* prefix -* Pointer to a null terminated string holding the namespace prefix. -* uri -* Pointer to a null terminated string holding the namespace URI. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLNAME, status ) ){ - astError( AST__INTER, "InitXmlNamespace: Supplied object type (%d) " - "does not represent an XmlNamespace", status, type ); - } - -/* Ensure we have non-NULL pointers. */ - if( !prefix ) prefix = ""; - if( !uri ) uri = ""; - -/* Check the supplied prefix is a valid XML 'name'. */ - CheckName( prefix, "namespace prefix", "InitXmlNamespace", 0, status ); - -/* Initialise the parent XmlObject component. */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Initialise the items specific to this class of structure. */ - new->prefix = astStore( NULL, prefix, strlen( prefix ) + 1 ); - new->uri = astStore( NULL, uri, strlen( uri ) + 1 ); -} - -static void InitXmlObject( AstXmlObject *new, long int type, int *status ){ -/* -* Name: -* InitXmlObject - -* Purpose: -* Initialise a new XmlObject. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlObject( AstXmlObject *new, long int type, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlObject -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Check the global error status. */ - if( !astOK ) return; - -/* If needed, get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the supplied object type is OK. Report an error if not. */ - if( !CheckType( type, AST__XMLOBJECT, status ) ){ - astError( AST__INTER, "InitXmlObject: Supplied object type (%ld) " - "is not appropriate for an XmlObject", status, type ); - } - -/* This class of structure is the base class for XML objects so it has no - parent class to be initialised. So just initialise the items specific to - this class of structure. */ - new->parent = NULL; - new->type = type; - new->id = next_id++; - -#ifdef DEBUG -/* Add the new XmlObject to the list of all XmlObjects. */ - AddObjectToList( new ); -#endif - -} - -static void InitXmlPI( AstXmlPI *new, int type, const char *target, - const char *text, int *status ){ -/* -* Name: -* InitXmlPI - -* Purpose: -* Initialise a new XmlPI. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlPI( AstXmlPI *new, int type, const char *target, -* const char *text, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlPI -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* target -* Pointer to a null terminated string holding the PI target. -* text -* Pointer to a null terminated string holding the PI text. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLPI, status ) ){ - astError( AST__INTER, "InitXmlPI: Supplied object type (%d) " - "does not represent an XmlPI", status, type ); - } - -/* Initialise the parent XmlObject component. */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Ensure we have non-NULL pointers. */ - if( !target ) target = ""; - if( !text ) text = ""; - -/* Initialise the items specific to this class of structure. Report an error - if anything is illegal. */ - new->target = NULL; - new->text = NULL; - - if( !Ustrcmp( target, "XML", status ) && astOK ) { - astError( AST__XMLPT, "InitXmlPI(xml): Illegal XML PI target \"%s\"" - " supplied.", status, target ); - } else { - new->target = astStore( NULL, target, strlen( target ) + 1 ); - new->text = astStore( NULL, text, strlen( text ) + 1 ); - } -} - -static void InitXmlPrologue( AstXmlPrologue *new, int type, int *status ){ -/* -* Name: -* InitXmlPrologue - -* Purpose: -* Initialise a new XmlPrologue. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* InitXmlPrologue( AstXmlPrologue *new, int type, int *status ) - -* Description: -* This function initialises supplied memory to hold an XmlPrologue -* structure. - -* Parameters: -* new -* The memory in which to initialise the structure. -* type -* An identifier for the structure type. -* status -* Pointer to the inherited status variable. -*/ - -/* Check the global error status. */ - if( !astOK ) return; - -/* Check the supplied object type is appropriate for the class of - structure being initialised. If not report an error. */ - if( !CheckType( type, AST__XMLPRO, status ) ){ - astError( AST__INTER, "InitXmlPrologue: Supplied object type (%d) " - "does not represent an XmlPrologue", status, type ); - } - -/* Initialise the parent XmlObject */ - InitXmlObject( (AstXmlObject *) new, type, status ); - -/* Initialise the items specific to this class of structure. */ - new->xmldecl = NULL; - new->misc1 = NULL; - new->nmisc1 = 0; - new->dtdec = NULL; - new->misc2 = NULL; - new->nmisc2 = 0; -} - -static int MatchName( AstXmlElement *this, const char *name, int *status ){ -/* -* Name: -* MatchName - -* Purpose: -* Check that an element has a specified name and/or prefix. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* int MatchName( AstXmlElement *this, const char *name, int *status ) - -* Description: -* This function checks that an element has a specified name and/or prefix. - -* Parameters: -* this -* The XmlElement to check. -* name -* The name for the element (may include a namespace prefix). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the supplied element has the supplie dname/prefix. Zero -* otherwise. - -*/ - - -/* Local Variables: */ - const char *colon; /* Pointer to colon within supplied name */ - char *newname; /* Pointer to name string (no prefix) */ - char *newpref; /* Pointer to name string */ - int nc; /* Length of prefix string */ - int result; /* Returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* Extract any prefix from the start of the supplied name. */ - newpref = NULL; - newname = (char *) name; - colon = strchr( name, ':' ); - if( colon ) { - nc = colon - name; - newpref = astStore( NULL, name, nc + 1 ); - newpref[ nc ] = 0; - - nc = strlen( name ) - ( colon - name ) - 1; - newname = astStore( NULL, colon + 1, nc + 1 ); - newname[ nc ] = 0; - } - -/* Compare the prefix. */ - if( newpref && this->prefix ) { - result = !strcmp( newpref, this->prefix ); - - } else if( !newpref && !this->prefix ) { - result = 1; - - } else { - result = 0; - } - -/* If the prefixes matches, compare the names */ - if( result ) { - if( newname && this->name ) { - result = !strcmp( newname, this->name ); - - } else if( !newname && !this->name ) { - result = 1; - - } else { - result = 0; - } - } - -/* Free any name and prefix extracted from the supplied name string */ - if( colon ) { - newname = astFree( newname ); - newpref = astFree( newpref ); - } - -/* Return the result. */ - return result; -} - -static AstXmlAttribute *NewAttribute( const char *name, const char *value, - const char *prefix, int *status ){ -/* -* Name: -* NewAttribute - -* Purpose: -* Create a new XmlAttribute. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* AstXmlAttribute *NewAttribute( const char *name, const char *value, -* const char *prefix, int *status ) - -* Description: -* This function creates a new XmlAttribute structure representing an -* XML attribute with the given name, value and namespace prefix. - -* Parameters: -* name -* Pointer to a null terminated string containing the attribute name. -* value -* Pointer to a null terminated string containing the attribute value. -* prefix -* Pointer to a null terminated string containing the attribute -* namespace prefix (may be NULL or blank). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new structure is returned. - -* Notes: -* - A NULL pointer is returned if the inherited status value -* indicates an error has occurred on entry, or if this function -* should fail for any reason. -*/ - -/* Local Variables: */ - AstXmlAttribute *new; /* The returned pointer */ - -/* Initialise */ - new = NULL; - -/* Check the global error status. */ - if( !astOK ) return new; - -/* Allocate space for the new structure. */ - new = (AstXmlAttribute *) astMalloc( sizeof( AstXmlAttribute ) ); - -/* Initialise it. */ - InitXmlAttribute( new, AST__XMLATTR, name, value, prefix, status ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) new = astXmlDelete( new ); - -/* Return the result. */ - return new; - -} - -static AstXmlDocument *NewDocument( int *status ){ -/* -* Name: -* NewDocument - -* Purpose: -* Create a new empty XmlDocument. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* AstXmlDocument *NewDocument( int *status ) - -* Description: -* This function creates a new empty XmlDocument structure representing -* an entire XML Document. - -* Parameters: -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new structure is returned. - -* Notes: -* - A NULL pointer is returned if the inherited status value -* indicates an error has occurred on entry, or if this function -* should fail for any reason. -*/ - -/* Local Variables: */ - AstXmlDocument *new; /* The returned pointer */ - -/* Initialise */ - new = NULL; - -/* Check the global error status. */ - if( !astOK ) return new; - -/* Allocate space for the new structure. */ - new = (AstXmlDocument *) astMalloc( sizeof( AstXmlDocument ) ); - -/* Initialise it. */ - InitXmlDocument( new, AST__XMLDOC, status ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) new = astXmlDelete( new ); - -/* Return the result. */ - return new; - -} - -static AstXmlNamespace *NewNamespace( const char *prefix, const char *uri, int *status ){ -/* -* Name: -* NewNamespace - -* Purpose: -* Create a new XmlNamespace. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* AstXmlNamespace *NewNamespace( const char *prefix, -* const char *uri, int *status ) - -* Description: -* This function creates a new XmlNamespace structure representing an -* XML namespace with the given prefix and uri. - -* Parameters: -* prefix -* Pointer to a null terminated string containing the namespace prefix. -* uri -* Pointer to a null terminated string containing the associated URI. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new structure is returned. - -* Notes: -* - A NULL pointer is returned if the inherited status value -* indicates an error has occurred on entry, or if this function -* should fail for any reason. -*/ - -/* Local Variables: */ - AstXmlNamespace *new; /* The returned pointer */ - -/* Initialise */ - new = NULL; - -/* Check the global error status. */ - if( !astOK ) return new; - -/* Allocate space for the new structure. */ - new = (AstXmlNamespace *) astMalloc( sizeof( AstXmlNamespace ) ); - -/* Initialise it. */ - InitXmlNamespace( new, AST__XMLNAME, prefix, uri, status ); - -/* If an error occurred, delete the new structure. */ - if( !astOK ) new = astXmlDelete( new ); - -/* Return the result. */ - return new; - -} - -static AstXmlPrologue *NewPrologue( AstXmlDocument *doc, int *status ){ -/* -* Name: -* NewPrologue - -* Purpose: -* Create a new empty XmlPrologue. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* AstXmlPrologue *NewPrologue( AstXmlDocument *doc, int *status ) - -* Description: -* This function creates a new empty XmlPrologue structure representing -* an entire prologue. - -* Parameters: -* doc -* A pointer to the XmlDocument to add the XmlPrologue to, or NULL. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new structure is returned. - -* Notes: -* - A NULL pointer is returned if the inherited status value -* indicates an error has occurred on entry, or if this function -* should fail for any reason. -*/ - -/* Local Variables: */ - AstXmlPrologue *new; /* The returned pointer */ - -/* Initialise */ - new = NULL; - -/* Check the global error status. */ - if( !astOK ) return new; - -/* Allocate space for the new structure. */ - new = (AstXmlPrologue *) astMalloc( sizeof( AstXmlPrologue ) ); - -/* Initialise it. */ - InitXmlPrologue( new, AST__XMLPRO, status ); - -/* Set its parent. */ - ((AstXmlObject *) new )->parent = (AstXmlParent *) doc; - -/* If an error occurred, delete the new structure. */ - if( !astOK ) new = astXmlDelete( new ); - -/* Return the result. */ - return new; - -} - -static char *RemoveEscapes( const char *text, int *status ){ -/* -* Name: -* RemoveEscapes - -* Purpose: -* Replaces entity references by corresponding ascii characters. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* char *RemoveEscapes( const char *text, int *status ) - -* Description: -* This function produces a dynamic copy of the supplied text in which -* occurrences of XML entity references are replaced by the corresponding -* ASCII text. - -* Parameters: -* text -* A pointer to a text string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated string containing the required -* copy. - -* Notes: -* - NULL is returned if this function is called with the global error -* status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - char *d; /* Pointer to next returned character */ - char *result; /* Returned pointer */ - char rc; /* Replacement character */ - const char *c; /* Pointer to next supplied character */ - int nc; /* Number of characters to skip */ - -/* Initialise */ - result = NULL; - nc = 0; - -/* Return if the pointer is NULL or if an error has occurred. */ - if( !astOK || !text ) return result; - -/* Allocate memory to hold a copy of the supplied text. */ - result = astMalloc( strlen( text ) + 1 ); - -/* Check the pointer can be used safely. */ - if( astOK ) { - -/* Loop round every character in the supplied text. */ - c = text - 1; - d = result; - while( *(++c) ) { - -/* If this character marks the start of a entity reference, replace it by - the corresponding ascii character and shuffle the remaining text down. */ - if( !strncmp( c, "&", 5 ) ) { - rc = '&'; - nc= 4; - - } else if( !strncmp( c, "<", 4 ) ) { - rc = '<'; - nc= 3; - - } else if( !strncmp( c, ">", 4 ) ) { - rc = '>'; - nc= 3; - - } else if( !strncmp( c, "'", 6 ) ) { - rc = '\''; - nc= 5; - - } else if( !strncmp( c, """, 6 ) ) { - rc = '"'; - nc= 5; - - } else { - rc = 0; - } - - if( rc ) { - *(d++) = rc; - c += nc; - } else { - *(d++) = *c; - } - - } - -/* Terminate the returned string. */ - *d = 0; - -/* Reallocate the string to free up any unused space. */ - result = astRealloc( result, d - result + 1 ); - } - -/* Return the result. */ - return result; -} - -#ifdef DEBUG -static void RemoveObjectFromList( AstXmlObject *obj ){ -/* -* Name: -* RemoveObjectFromList - -* Purpose: -* Removes an XmlObject from a static list of all currently active XmlObjects. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* void RemoveObjectFromList( AstXmlObject *obj ) - -* Description: -* This function removes the supplied pointer from a static list of -* pointers, and decrements the number of elements in the list. This list -* holds pointers to all the XmlObjects which currently exist. If the -* supplied pointer is not found in the list, this function returns -* without action. - -* Parameters: -* this -* A pointer to the XmlObject. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variavles: */ - int i; - int ii; - -/* Locate the supplied pointer within the list of pointers to all - currently active XmlObjects. */ - ii = -1; - for( i = 0; i < nobj; i++ ){ - if( existing_objects[ i ]->id == obj->id ) { - ii = i; - break; - } - } - -/* Check the pointer was found. */ - if( ii != -1 ) { - -/* Shuffle all higher index pointers down one in the list in order to fill - the gap left by removing the supplied pointer. */ - for( ii++; ii < nobj; ii++ ){ - existing_objects[ ii - 1 ] = existing_objects[ ii ]; - } - -/* Decrement the number of pointers in the list. */ - nobj--; - -/* Nullify the pointer at the end of the list which is no longer used. */ - existing_objects[ nobj ] = NULL; - } -} -#endif - -static const char *ResolvePrefix( const char *prefix, AstXmlElement *elem, int *status ){ -/* -* Name: -* ResolvePrefix - -* Purpose: -* Find the URI associated with a namespace prefix. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* const char *ResolvePrefix( const char *prefix, AstXmlElement *elem, int *status) - -* Description: -* This function searches the namespaces defined within the supplied -* element for a prefix which matches the supplied prefix. If found, -* it returns a pointer to the URI string associated with the prefix. -* If not found, it calls this function recursively on the parent -* element. If there is no parent element, NULL is returned. - -* Parameters: -* prefix -* Pointer to a string holding the namespace prefix. -* elem -* The pointer to the XmlElement. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a string holding the URI, or NULL if not found. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -*/ - -/* Local Variables: */ - AstXmlParent *parent; /* Parent object */ - AstXmlNamespace *ns; /* Next namespace */ - const char *result; /* Returned pointer */ - int i; /* Loop count */ - -/* Initialise */ - result = NULL; - -/* Check the global error status, and the supplied element. */ - if( !astOK || !elem ) return result; - -/* Loop round all the namespace definitions in the element. */ - for( i = 0; i < elem->nnspref; i++ ) { - ns = elem->nsprefs[ i ]; - -/* Compare the namespace prefix with the supplied prefix (case sensitive). - Store a pointer to the associated URI if they match, and leave the - loop. */ - if( !strcmp( ns->prefix, prefix ) ) { - result = ns->uri; - break; - } - } - -/* If no matching namespace was found, attempt to resolve the prefix - within the context of the parent element. */ - if( !result ) { - parent = ((AstXmlObject *) elem )->parent; - if( astXmlCheckType( parent, AST__XMLELEM ) ) { - result = ResolvePrefix( prefix, (AstXmlElement *) parent, status ); - } - } - -/* Return the result. */ - return result; -} - -static int Ustrcmp( const char *a, const char *b, int *status ){ -/* -* Name: -* Ustrncmp - -* Purpose: -* A case blind version of strcmp. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* int Ustrcmp( const char *a, const char *b ) - -* Description: -* Returns 0 if there are no differences between the two strings, and 1 -* otherwise. Comparisons are case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference between -* the two strings, whereas "strcmp" does. -* - This function attempts to execute even if an error has occurred. - -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int ret; /* Returned value */ - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Loop round each character. */ - while( 1 ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - - } - - } - -/* Return the result. */ - return ret; - -} - -#ifdef DEBUG -int astXmlTrace( int show ){ -/* -*+ -* Name: -* astXmlTrace - -* Purpose: -* List details of XML objects currently in existence. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* int astXmlTrace( int show ) - -* Description: -* Lists details of XML objects currently in existence. Details are -* written to standard output. - -* Parameters: -* show -* - 0, the ID values of all currently active XmlObjects are -* listed. The objects themselves are unchanged. -* - 1, each object is displayed using astXmlShow unless it has -* already been included in the display of a previous object, and then -* annulled. Consequently, this mode is destructive, and none of the -* displayed XmlObjects will be acessable afterwards. -* - 2, each object is displayed using astXmlShow whether or not it -* has already been included in the display of a previous object. -* The objects are left unchanged. -* - 3, nothing is written to standard output, but the number of -* active XmlObjects is still returned. - -* Returned Value: -* The number of XMLObjects which are in existence on entry to this -* function. - -*- -*/ - -/* Local Variables: */ - AstXmlObject *root; - int i, result, old_status; - - old_status = astStatus; - astClearStatus; - - result = nobj; - - if( show == 0 ) { - printf( "Current list of active XmlObject identifiers: " ); - for( i = 0; i < nobj; i++ ) printf( "%d ", existing_objects[ i ]->id ); - printf("\n"); - - } else if( show ==1 ){ - while( nobj > 0 ) { - root = astXmlGetRoot( existing_objects[0] ); - printf( "ID = %d (type %ld)\n%s\n------------\n", - root->id, root->type, astXmlShow( root ) ); - root = astXmlAnnulTree( root ); - } - - } else if( show == 2 ) { - for( i = 0; i < nobj; i++ ) printf( "%d\n%s\n------------\n", - existing_objects[ i ]->id, - astXmlShow(existing_objects[ i ]) ); - printf("\n"); - } - - astSetStatus( old_status ); - - return result; -} -#endif - -AstXmlElement *astXmlReadDocument_( AstXmlDocument **doc, - int (*is_wanted)( AstXmlElement *, int * ), - int skip, char (*source)( void *, int * ), - void *data, int *status ){ -/* -*+ -* Name: -* astXmlReadDocument - -* Purpose: -* Read and parse an XML document. - -* Type: -* Protected function. - -* Synopsis: -* #include "xml.h" -* AstXmlElement *astXmlReadDocument( AstXmlDocument **doc, -* int (*is_wanted)( AstXmlElement *, int * ), -* int skip, char (*source)( void *, int * ), -* void *data ) - -* Description: -* This function reads and parses text from an XML source. The text is -* obtained by calling the supplied "source" function, which returns -* the next character read from the external source on each invocation. -* -* The reading scheme combines elements of the SAX and DOM schemes in -* an attempt to minimise memory requirements (a potential problem with -* DOM) whilst retaining a simple interface for accessing the XML -* elements of interest to the client (a potential problem for SAX). -* -* When an element start tag is encountered in the source, the client -* is asked to indicate whether the element is of interest. This is -* done by calling the supplied "is_wanted" function. If the client -* indicates that the element is of interest, its contents are read -* and a pointer to a corresponding XmlElement structure is returned. -* Reading stops when the element has been read. If the client -* indicates that the element is not of interest, then (if "skip" is -* non-zero) the contents of the element are skipped over, and reading -* continues following the element end tag. When the next element is -* encountered the client will again be asked to indicate its interest -* in the element. This continues until either the client indicates that -* an element is of interest, or the end of the source is reached. If -* "skip" is zero, then an error is reported if the first element in -* the document is not of interest. -* -* The client has an option to reply that an element is not itself of -* interest, but may possibly contain interesting elements. In this case, -* the sub-elements within the element are read and checked in the same -* way. -* -* This function returns, and no more characters are read from the -* source, once the contents of the first "interesting" element has been -* read. -* -* The function thus returns a pointer to an XmlElement containing the -* entire contents of the first interesting element encountered in the -* source. This function can then be invoked again to read further -* interesting elements from the source. In this case, the XmlDocument -* structure created by the initial invocation (see parameter "doc") -* must be supplied, as this indicates the point in the total document -* structure at which the previous "interesting" element was located. - -* Parameters: -* doc -* Address of a location holding a pointer to an AstXmlDocument -* structure. The AstXmlDocument pointer should be supplied as NULL -* when invoking this function for the first time on a document -* source (i.e. when reading from the beginning of the document). -* In this case a new AstXmlDocument structure will be created and a -* pointer to it stored at the supplied address. This structure -* holds the context which enables subsequent invocations of this -* function to determine the point in the document structure at -* which to store any further text read from the source. It also -* holds the document prologue, root element, and epilogue. -* is_wanted -* Pointer to a function which is called to decide if the client is -* interested in each element start tag which has just been read. -* It has a single argument which is a pointer to the (empty) XmlElement -* corresponding to the element start tag which has just been read. -* It returns an integer: -* -1 : the element is not itself of interest but it may contain -* an interesting element, so look through the content and -* ask the client again about any elements found inside it. -* 0 : the element definately contains nothing of interest to -* the client. kip its content and continue looking for new -* elements. -* 1 : the element is definately of interest to the client so -* read its contents and return a pointer to it. -* If NULL is supplied, a value of "+1" is assumed. -* skip -* Indicates if any uninteresting elements may proceed the first -* element of interest. If zero, then an error is reported if the -* first element read from the source is not of interest to the client. -* If non-zero, then any uninteresting elements are simply skipped -* over until an interesting element is found or the document ends. -* source -* Pointer to a function which is called to return the next -* character from the source. It has a single argument which is -* used to pass any supplied data to it. It should return zero when -* the end of the source is reached. -* data -* Pointer to a structure to pass to the source function. This -* structure may contain any data needed by the source function. - -* Returned Value: -* A pointer to the first element of interest, or NULL if there are no -* interesting elements in the source. The returned element will be a -* descendant of "*doc". For this reason, the returned pointer need not -* be annulled explicitly since it will be freed when the XmlDocument -* is annulled. However, if required (e.g. to save memory) it may be -* annulled before the document is annulled by using astXmlRemoveItem to -* remove it from its parent, and then using astXmlAnnul to annul it. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -* - It is assumed that the read commences outside any tag (i.e. -* in between tags or within character data). -*- -*/ - -/* Local Variables: */ - AstXmlElement *result; - -/* Check any supplied pointer is for an XmlDocument. */ - astXmlCheckDocument( *doc, 1 ); - -/* Read and parse the source text. Indicate that the element being read - *may* contain items of interest to the client. Surround with a mutex - since the supplied functions may not be thread-safe. */ - LOCK_MUTEX1; - result = ReadContent( doc, -1, is_wanted, skip, source, data, 0, status ); - UNLOCK_MUTEX1; - -/* Return the result. */ - return result; -} - - -static AstXmlElement *ReadContent( AstXmlDocument **doc, int wanted, - int (*is_wanted)( AstXmlElement *, int * ), - int skip, char (*source)( void *, int * ), - void *data, int depth, int *status ){ -/* -* Name: -* ReadContent - -* Purpose: -* Read and parse an XML document. - -* Type: -* Private function. - -* Synopsis: -* #include "xml.h" -* AstXmlElement *ReadContent( AstXmlDocument **doc, int wanted, -* int (*is_wanted)( AstXmlElement *, int * ), -* int skip, char (*source)( void *, int * ), -* void *data, int depth, int *status ) - -* Description: -* This function reads and parses text from an XML source. The text is -* obtained by calling the supplied "source" function, which returns -* the next character read from the external source on each invocation. -* -* See astXmlReadDocument for more details. - -* Parameters: -* doc -* Address of a location holding a pointer to an AstXmlDocument -* structure. The AstXmlDocument pointer should be supplied as NULL -* when invoking this function for the first time on a document -* source (i.e. when reading from the beginning of the document). -* In this case a new AstXmlDocument structure will be created and a -* pointer to it stored at the supplied address. This structure -* holds the context which enables subsequent invocations of this -* function to determine the point in the document structure at -* which to store any further text read from the source. It also -* holds the document prologue, root element, and epilogue. -* wanted -* Indicates if the content read from the XML source is of interest -* to the client. If a positive value is supplied, all content read -* from the source (up to the end tag which corresponds to the -* supplied "parent") is added to the "parent" element (if supplied). -* If zero is supplied, then all content read from the source is -* discarded. If a negative value is supplied, then all content up -* to the first element start tag is discarded. When the first -* element start tag is encountered, it is passed back to the client -* by invoking the supplied "is_wanted" function. If this function -* returns a non-zero value, then the contents of the new element -* is read (by calling this function recursively) and a pointer to -* the new element is returned as the function value (reading then -* stops and the function returns). If the "is_wanted" function returns -* zero, then the contents of the new element is skipped over, and -* reading continues until the next element start tag is encountered, -* when the "is_wanted" function is again invoked. -* is_wanted -* Pointer to a function which is called to decide if the client is -* interested in the element start tag which has just been read. -* It has a single argument which is a pointer to the (empty) XmlElement -* corresponding to the element start tag which has just been read. -* It returns an integer: -* -1 : the element is not itself of interest but it may contain -* an interesting element, so look through the content and -* ask the client again about any elements found inside it. -* 0 : the element definately contains nothing of interest to -* the client. kip its content and continue looking for new -* elements. -* 1 : the element is definately of interest to the client so -* read its contents and return a pointer to it. -* If NULL is supplied, a value of "+1" is assumed. -* skip -* Indicates if any uninteresting elements may proceed the first -* element of interest. If zero, then an error is reported if the -* first element read from the source is not of interest to the client. -* If non-zero, then any uninteresting elements are simply skipped -* over until an interesting element is found or the document ends. -* source -* Pointer to a function which is called to return the next -* character from the source. It has a single argument which is -* used to pass any supplied data to it. It should return zero when -* the end of the source is reached. -* data -* Pointer to a structure to pass to the source function. This -* structure may contain any data needed by the source function. -* depth -* Depth of nesting (i.e. zero if this function was invoked from -* astXmlReadDocument, and a positive value if it was invoked -* recursively from within itself). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the first element of interest, or NULL if there are no -* interesting elements in the source. If the first element of -* interest has already been found (as indicated by "wanted" being +1) -* then NULL is returned. The returned element may be a child of a -* parent element containing namespace definitions (which may itself -* have a parent, etc). For this reason, the returned pointer should be -* freed using astXmlAnnulTree rather than astXmlAnnul. - -* Notes: -* - NULL is returned if an error has already occurred, or if this -* function should fail for any reason. -* - It is assumed that the read commences outside any tag (i.e. -* in between tags or within character data). -*/ - -/* Local Variables; */ - AstXmlElement *answer; /* Result of reading a sub-element */ - AstXmlElement *parent; /* Pointer to current parent element */ - AstXmlElement *elem; /* A new element to be read */ - AstXmlElement *result; /* The returned pointer */ - char *cc; /* Pointer to next character */ - char *msg; /* Pointer to message buffer */ - char *text1; /* Pointer to dynamic string */ - char *text2; /* Pointer to another dynamic string */ - char *text3; /* Pointer to another dynamic string */ - char *text4; /* Pointer to another dynamic string */ - char c; /* Current character read from source */ - char lc2; /* Last but one character read */ - char lc; /* Last character read */ - char quoted; /* Character which opened current quote */ - int nc1; /* No. of characters stored in text1 */ - int nc2; /* No. of characters stored in text2 */ - int nc3; /* No. of characters stored in text2 */ - int ncmsg; /* Length of "msg" */ - int newwanted; /* Is the new element wanted? */ - int state; /* Current action being performed */ - int prolog_ok; /* OK for source to start with a prolog? */ - int where; /* Where to add the item within the document */ - -/* Initialise */ - result = NULL; - elem = NULL; - -/* Check the global error status. */ - if( !astOK ) return result; - -/* If no XmlDocument was supplied, assume we are commencing to read a new - document from the begining. Create a new XmlDocument to store the - prologue, root element and epilogue, together with a pointer to the - "current" element, i.e. the element whose content is currently being - read. Also, since we have not yet asked the client if it is interested - in anything, ignore the supplied "wanted" value and use -1 to ensure - that we ask the client when the first element start tag is encountered. */ - if( !*doc ){ - prolog_ok = 1; - *doc = NewDocument( status ); - wanted = -1; - } else { - prolog_ok = 0; - } - -/* Any content read from the source (except for prologue and epilogue) - will be placed into the "parent" element. A pointer to this element is - stored in the XmlDocument structure. The parent element will always be - a descendant of the root element, or the root element itself. */ - parent = (*doc)->current; - -/* If the supplied parent has already been completed (typically because - it was read from an empty element tag), then just return without - action. */ - if( parent && parent->complete ) { - -/* If an error has occurred, or if this invocation of ReadContent was - made recursively (rather than by the client), or if we have something - to return, return. */ - if( !astOK || depth > 0 || result ) { - return result; - -/* Otherwise, returning would result in returning a null pointer to the - client even though the end of the document may not have been reached. - Revert to state 0 and search for further interesting elements. */ - } else { - if( parent != (*doc)->root ) { - (*doc)->current = (AstXmlElement *) ( (AstXmlObject *) parent )->parent; - } else { - (*doc)->current = NULL; - } - parent = (*doc)->current; - state = 0; - } - } - -/* Initialise the previous two characters read. */ - lc = 0; - lc2 = 0; - -/* Initialise pointer to dynamically allocated strings. */ - text1 = NULL; - text2 = NULL; - text3 = NULL; - msg = NULL; - -/* We are not in a quote. */ - quoted = 0; - -/* Initialise the "state" variable which indicates what we are currently - looking for. */ - state = 0; - -/* Loop round reading characters from the source. */ - while( 1 ) { - c = (*source)( data, status ); - -/* Leave the loop if an error occurred whilst reading the character. */ - if( !astOK ) break; - -/* If a parent element has been supplied, (i.e. if we are currently - reading the content of an element), or if we are not in state zero, - report an error and leave the loop if the end of the text has been - reached. If no parent was supplied, just leave the loop. */ - if( !c ) { - if( parent ) { - astError( AST__XMLWF, "astRead(XmlChan): End of XML input text " - "reached whilst reading the content of element %s.", status, - astXmlGetTag( parent, 1 ) ); - - } else if( state > 1 ) { - if( msg ) { - astError( AST__XMLWF, "astRead(XmlChan): End of XML input text " - "reached whilst reading the document epilogue " - "(\"%s\").", status, msg ); - } else { - astError( AST__XMLWF, "astRead(XmlChan): End of XML input text " - "reached whilst reading the document epilogue." , status); - } - } - break; - } - -/* Save text which is not character data for use in error messages. */ - if( state < 2 ) { - if( msg ) msg = astFree( msg ); - } else { - msg = AppendChar( msg, &ncmsg, c, status ); - } - -/* State 0: Use the first character to decide what sort of content item - follows (character data or a tag of some form). */ - if( state == 0 ) { - if( c != '<' ) { - state = 1; - text1 = AppendChar( text1, &nc1, c, status ); - } else { - msg = AppendChar( msg, &ncmsg, '<', status ); - state = 2; - } - -/* State 1: We are reading character data. The character data ends at the - first occurrence of "<", at which point the character data is added to - the parent if required and we continue to state 2.*/ - } else if( state == 1 ) { - if( c != '<' ) { - text1 = AppendChar( text1, &nc1, c, status ); - } else { - msg = AppendChar( msg, &ncmsg, '<', status ); - if( text1 ){ - -/* If we have a parent element, just add it to the element. */ - if( parent ) { - if( wanted > 0 ) { - text4 = RemoveEscapes( text1, status ); - astXmlAddCharData( (AstXmlParent *) parent, 0, text4 ); - text4 = astFree( text4 ); - - -/* If we are not allowed to skip over non-blank content, report an - error if the text is not blank. */ - } else if( !skip ) { - cc = text1 - 1; - while( *(++cc) ) { - if( !isspace( *cc ) ) { - if( parent ) { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data \"%s\" within element %s.", status, - text1, astXmlGetTag( parent, 1 ) ); - } else { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data: \"%s\".", status, text1 ); - } - break; - } - } - } - -/* Otherwise, add it to the document prologue or epilogue. */ - } else { - if( (*doc)->root ) { - where = 3; - } else if( (*doc)->prolog && (*doc)->prolog->dtdec ){ - where = 2; - } else { - where = 1; - } - - text4 = RemoveEscapes( text1, status ); - astXmlAddCharData( (AstXmlParent *) *doc, where, text4 ); - text4 = astFree( text4 ); - } - - text1 = astFree( text1 ); - } - state = 2; - } - -/* State 2: We are using the character following a "<" to determine what - type of tag is commencing. */ - } else if( state == 2 ) { - -/* If the character is a ">", report an error. */ - if( c == '>' ) { - if( parent ) { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"<>\" " - "encountered within element %s.", status, astXmlGetTag( parent, 1 ) ); - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"<>\" " - "encountered." , status); - } - break; - -/* If the character is a "?", this must be a PI tag. */ - } else if( c == '?' ) { - state = 3; - -/* If the character is a "!", it must be a comment or a CDATA section - or a DTD. */ - } else if( c == '!' ) { - state = 4; - -/* If the character is a "/", it must be an element end tag. */ - } else if( c == '/' ) { - state = 5; - -/* Otherwise, this must be an element start tag. Append the character - to "text1". */ - } else { - state = 6; - text1 = AppendChar( text1, &nc1, c, status ); - } - -/* State 3: We are reading the initial text following the opening "" string is the target text. */ - } else if( state == 3 ) { - if( c == '>' && lc == '?' ) { - if( text1 ) text1[ --nc1 ] = 0; - state = 100; - } else if( isspace( c ) ) { - state = 7; - } else { - text1 = AppendChar( text1, &nc1, c, status ); - } - -/* State 4: We are using the characters following the opening "' ) { - state = 101; - } else { - text1 = AppendChar( text1, &nc1, c, status ); - } - -/* State 6: We are looking for the (prefix:)name combination at the start of - an element start tag. */ - } else if( state == 6 ) { - if( c == '>' ) { - state = ( lc != '/' ) ? 102 : 103; - } else if( isspace( c ) ) { - state = 104; - } else if( c != '/' ){ - text1 = AppendChar( text1, &nc1, c, status ); - } - -/* State 7: We are reading the remaining text in a PI tag following the target - text. */ - } else if( state == 7 ) { - if( c == '>' && lc == '?' ) { - if( text2 ) text2[ --nc2 ] = 0; - state = 100; - } else if( text2 || !isspace( c ) ) { - text2 = AppendChar( text2, &nc2, c, status ); - } - -/* State 8: We are looking for the start of the text within a comment tag. */ - } else if( state == 8 ) { - if( c == '-' ) { - state = 10; - } else { - if( parent ) { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag " - "starting with \"" is reached, check the previous 2 characters are "--" and then terminate - the text1 string in order to remove these two characters from the comment - text. */ - } else if( state == 10 ) { - if( c == '>' && lc == '-' && lc2 == '-' ) { - text1[ nc1 - 2 ] = 0; - state = 105; - } else { - text1 = AppendChar( text1, &nc1, c, status ); - } - -/* State 11: We are reading the remaining text in a CDATA tag. */ - } else if( state == 11 ) { - if( c == '>' && lc == ']' && lc2 == ']' ) { - text1[ nc1 - 2 ] = 0; - state = 106; - } else { - text1 = AppendChar( text1, &nc1, c, status ); - } - -/* State 12: We are looking for an equals sign marking the end of an - attribute name within an element start tag. */ - } else if( state == 12 ) { - if( c == '=' ) { - state = 13; - - } else if( c == '>' ) { - if( text1 ) { - if( parent ) { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag " - " \"%s...\" encountered within element %s.", status, msg, - astXmlGetTag( parent, 1 ) ); - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s...\" " - "encountered.", status, msg ); - } - break; - } else { - if( lc == '/' ) { - state = 108; - } else { - state = 200; - } - } - - } else if( text1 || !isspace( c ) ) { - if( c != '/' ) text1 = AppendChar( text1, &nc1, c, status ); - } - -/* State 13: We are looking for a '"' or ''' marking the start of an attribute - value within an element start tag. */ - } else if( state == 13 ) { - if( c == '"' ) { - state = 14; - - } else if( c == '\'' ) { - state = 15; - - } else if( c == '>' ) { - astError( AST__XMLWF, "astRead(XmlChan): Illegal value for attribute " - "\"%s\" in XML tag \"%s...\".", status, text1, msg ); - break; - } - -/* State 14: We are looking for a '"' marking the end of an attribute value - within an element start tag. */ - } else if( state == 14 ) { - if( c == '"' ) { - state = 107; - - } else if( c == '>' ) { - astError( AST__XMLWF, "astRead(XmlChan): Illegal value for attribute " - "\"%s\" in XML tag \"%s...\".", status, text1, msg ); - break; - - } else { - text2 = AppendChar( text2, &nc2, c, status ); - } - -/* State 15: We are looking for a ''' marking the end of an attribute value - within an element start tag. */ - } else if( state == 15 ) { - if( c == '\'' ) { - state = 107; - - } else if( c == '>' ) { - astError( AST__XMLWF, "astRead(XmlChan): Illegal value for attribute " - "\"%s\" in XML tag \"%s...\".", status, text1, msg ); - break; - - } else { - text2 = AppendChar( text2, &nc2, c, status ); - } - -/* State 16: We are looking for the end of a DOCTYPE string. */ - } else if( state == 16 ) { - if( isspace( c ) ) { - if( !strcmp( text1, "' ) { - state = 109; - } else { - text1 = AppendChar( text1, &nc1, c, status ); - } - -/* State 19: We are looking for the start of a string following a DOCTYPE - name string. */ - } else if( state == 19 ) { - if( !isspace( c ) ) { - if( c == '[' ) { - state = 20; - } else if( c == '>' ) { - state = 109; - } else { - state = 21; - text2 = AppendChar( text2, &nc2, c, status ); - } - } - -/* State 20: We are looking for the "]" marking the end of the internal - markup of a DOCTYPE element. Avoid the contents of quoted strings (such - as #FIXED attribute values). */ - } else if( state == 20 ) { - text3 = AppendChar( text3, &nc3, c, status ); - if( c == '\'' ) { - if( quoted == '\'' ) { - quoted = 0; - } else if( !quoted ) { - quoted = '\''; - } - - } else if( c == '"' ) { - if( quoted == '"' ) { - quoted = 0; - } else if( !quoted ) { - quoted = '"'; - } - - } else if( !quoted && c == ']' ) { - text3[ --nc3 ] = 0; - state = 22; - } - -/* State 21: We are looking for the start of a DOCTYPE internal section. */ - } else if( state == 21 ) { - if( c == '[' ) { - state = 20; - } else if( c == '>' ) { - state = 109; - } else { - text2 = AppendChar( text2, &nc2, c, status ); - } - -/* State 22: We are looking for the ">" at the end of a DOCTYPE. */ - } else if( state == 22 ) { - if( !isspace( c ) ) { - if( c == '>' ) { - state = 109; - } else { - astError( AST__XMLWF, "astRead(XmlChan): Extra text found " - "at end of XML DOCTYPE tag \"%s\".", status, msg ); - } - } - - } else { - astError( AST__INTER, "ReadContent(xml): Illegal state (%d) encountered " - "(AST internal programming error).", status, state ); - } - -/* The following states perform actions consequent on the decisons made - above, but which must be performed before reading the next character. */ - -/* In most cases there will be no actions to perform. Therefore check for - this first (to avoid the time spent doing all the following usually - irrelevant checks). */ - if( state < 23 ) { - -/* State 100: We have just reached the end of a PI tag. Create a new XmlPI and - store it in the parent (if required). */ - } else if( state == 100 ) { - if( text1 ){ - -/* First deal with XML declaration PI's. These must be the first item in - the source. */ - if( !strcmp( text1, "xml" ) ) { - if( (*doc)->root || (*doc)->prolog || (*doc)->nepi > 0 ) { - astError( AST__XMLWF, "astRead(XmlChan): An XML " - "declaration \"%s\" was encountered within the " - "body of the document.", status, msg ); - } else { - astXmlSetXmlDec( *doc, text2 ); - } - -/* Now deal with other PI's. */ - } else { - -/* If we have a parent element, just add it to the element. */ - if( parent ) { - if( wanted > 0 ) { - astXmlAddPI( (AstXmlParent *) parent, 0, text1, text2 ); - } else if( !skip ) { - if( parent ) { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data \"%s\" within element %s.", status, - msg, astXmlGetTag( parent, 1 ) ); - } else { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data: \"%s\".", status, msg ); - } - break; - } - -/* Otherwise, add it to the document prologue or epilogue. */ - } else { - if( (*doc)->root ) { - where = 3; - } else if( (*doc)->prolog->dtdec ){ - where = 2; - } else { - where = 1; - } - astXmlAddPI( (AstXmlParent *) *doc, where, text1, text2 ); - - } - } - text1 = astFree( text1 ); - if( text2 ) text2 = astFree( text2 ); - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" " - "encountered.", status, msg ); - break; - } - state = 0; - -/* State 101: We have just reached the end of an element end tag. Check that - the (prefix:)name is legal, and matches that of the current parent, - re-instate the parent's parent as the current element in the document, - and leave the loop if appropriate. */ - } else if( state == 101 ) { - if( text1 ){ - CheckPrefName( text1, "element", "astRead(XmlChan)", status ); - if( parent ) { - if( MatchName( parent, text1, status ) ) { - parent->complete = 1; - if( parent != (*doc)->root ) { - (*doc)->current = (AstXmlElement *) ( (AstXmlObject *) parent )->parent; - } else { - (*doc)->current = NULL; - } - } else { - astError( AST__XMLWF, "astRead(XmlChan): Start tag \"%s\" " - "closed by end tag \"%s\".", status, astXmlGetTag( parent, 1 ), - msg ); - } - - } else { - (*doc)->current = NULL; - astError( AST__XMLWF, "astRead(XmlChan): Unmatched end tag " - "\"%s\" encountered.", status, msg ); - } - - text1 = astFree( text1 ); - - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" " - "encountered.", status, msg ); - } - -/* If an error has occurred, or if this invocation of ReadContent was - made recursively (rather tnan by the client), or if we have something - to return, break out of the loop. */ - if( !astOK || depth > 0 || result ) { - break; - -/* Otherwise, breaking would result in returning a null pointer to the - client even though the end of the document may not have been reached. - Revert to state 0 and search for further intersting elements. */ - } else { - parent = (*doc)->current; - state = 0; - } - -/* State 102: We have just got the (prefix:)name for an element start tag, and - the start tag contains no attributes, etc. Create a new XmlElement, adding - it to the supplied parent, and then proceed to state 200 to read the - content of the element. */ - } else if( state == 102 ) { - if( text1 ){ - elem = astXmlAddElement( parent, text1, NULL ); - text1 = astFree( text1 ); - state = 200; - - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" " - "encountered.", status, msg ); - break; - } - -/* State 103: We have just got the (prefix:)name for an empty element tag, and - the tag does not contain further attributes, etc. Create a new XmlElement - and store it in the container (if any). Indicate that there is no - content to read, and then go on to state 200. */ - } else if( state == 103 ) { - if( text1 ){ - elem = astXmlAddElement( parent, text1, NULL ); - elem->complete = 1; - text1 = astFree( text1 ); - state = 200; - - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" " - "encountered.", status, msg ); - break; - } - -/* State 104: We have just got the (prefix:)name for an element start tag, but - the start tag may contain further attributes, etc. Create a new XmlElement - and store it in the container (if any). Then go to state 12 in which we - look for further attributes, etc. */ - } else if( state == 104 ) { - if( text1 ){ - elem = astXmlAddElement( parent, text1, NULL ); - text1 = astFree( text1 ); - state = 12; - - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" " - "encountered.", status, msg ); - break; - } - -/* State 105: We have just reached the end of a comment tag. Create a new - XmlComment and store it in the parent. */ - } else if( state == 105 ) { - if( text1 ){ - -/* If we have a parent element, just add it to the element. */ - if( parent ) { - if( wanted > 0 ) { - astXmlAddComment( (AstXmlParent *) parent, 0, text1 ); - } else if( !skip ) { - if( parent ) { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data \"%s\" within element %s.", status, - msg, astXmlGetTag( parent, 1 ) ); - } else { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data: \"%s\".", status, msg ); - } - break; - } - -/* Otherwise, add it to the document prologue or epilogue. */ - } else { - if( (*doc)->root ) { - where = 3; - } else if( (*doc)->prolog->dtdec ){ - where = 2; - } else { - where = 1; - } - astXmlAddComment( (AstXmlParent *) *doc, where, text1 ); - } - - text1 = astFree( text1 ); - - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" " - "encountered.", status, msg ); - break; - } - state = 0; - -/* State 106: We have just reached the end of a CDATA tag. Create a new - XmlCDATASection and store it in the container (if any). */ - } else if( state == 106 ) { - if( text1 ){ - if( parent && wanted > 0 ) { - astXmlAddCDataSection( parent, text1 ); - } else if( !skip ) { - if( parent ) { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data \"%s\" within element %s.", status, - msg, astXmlGetTag( parent, 1 ) ); - } else { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data: \"%s\".", status, msg ); - } - break; - } - text1 = astFree( text1 ); - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" " - "encountered.", status, msg ); - break; - } - state = 0; - -/* State 107: We have just reached the end of an attribute or namespace - setting. Create a new object and store it in the element created - earlier. */ - } else if( state == 107 ) { - if( text1 ){ - if( !elem ) { - astError( AST__INTER, "ReadContent(xml): Container lost at state " - "107 (AST internal programming error).", status ); - break; - } - - if( !strcmp( text1, "xmlns" ) ) { - astXmlAddURI( elem, NULL, text2 ); - - } else if( !strncmp( text1, "xmlns:", 6 ) ) { - astXmlAddURI( elem, text1+6, text2 ); - - } else { - text4 = RemoveEscapes( text2, status ); - astXmlAddAttr( elem, text1, text4, NULL ); - text4 = astFree( text4 ); - } - - text1 = astFree( text1 ); - text2 = astFree( text2 ); - - } else { - astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" " - "encountered.", status, msg ); - break; - } - state = 12; - -/* State 108: We have just reached the end of an empty element tag to which - we have been adding attributes, etc. */ - } else if( state == 108 ) { - if( elem ) { - elem->complete = 1; - state = 200; - } else { - astError( AST__INTER, "Parse(xml): No container in state 108 " - "(AST internal programming error).", status ); - break; - } - -/* State 109: We have just reached the end of a DOCTYPE tag. */ - } else if( state == 109 ) { - - if( (*doc)->root ){ - astError( AST__XMLWF, "astRead(XmlChan): An DOCTYPE tag " - "\"%s\" was encountered within the body of the " - "document.", status, msg ); - break; - - } else if( (*doc)->prolog->dtdec ){ - astError( AST__XMLWF, "astRead(XmlChan): Multiple DOCTYPE tags " - "encountered." , status); - break; - - } else { - astXmlSetDTDec( *doc, text1, text2, text3 ); - text1 = astFree( text1 ); - text2 = astFree( text2 ); - text3 = astFree( text3 ); - state = 0; - } - - } else if( state != 200 ) { - astError( AST__INTER, "ReadContent(xml): Illegal state (%d) encountered " - "(AST internal programming error).", status, state ); - } - - - -/* State 200: We now have now read a complete element start tag and have - a corresponding XmlElement ("elem"), with all attributes and namespaces, - etc (but no content). Call the "is_wanted" function to see if the client - is interested in the element. */ - if( state == 200 ) { - -/* If this element is found at the root level of the document, store a - pointer to it as the root element. Report an error if there is already - a root element. */ - if( !parent ) { - if( (*doc)->root ){ - if( astOK ) { - astError( AST__XMLWF, "astRead(XmlChan): Multiple root " - "elements encountered." , status); - elem = astXmlDelete( elem ); - } - break; - } else { - (*doc)->root = elem; - ((AstXmlObject *) elem )->parent = (AstXmlParent *) (*doc); - } - } - -/* If we do not already know, ask the caller if it is interested in this new - element. If no "is_wanted" function was supplied, assume all elements - are interesting. */ - if( wanted == -1 ) { - newwanted = is_wanted ? (*is_wanted)( elem, status ) : 1; - } else { - newwanted = wanted; - } - -/* If it is not interested, report an error if skip is zero. */ - if( newwanted != 1 && !skip ) { - if( parent ) { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data \"%s\" within element %s.", status, - msg, astXmlGetTag( parent, 1 ) ); - } else { - astError( AST__BADIN, "astRead(XmlChan): Cannot interpret " - "the input data: \"%s\".", status, msg ); - } - break; - } - -/* Make the new element the "current" element in the document. */ - (*doc)->current = elem; - -/* Read the contents of the new element from the source. If the client is - interested in the element, the read contents will be added to the - element, otherwise they will be discarded after being read. */ - answer = ReadContent( doc, newwanted, is_wanted, skip, source, - data, depth + 1, status ); - -/* If the first interesting element was found inside "elem", then - return it. If "elem" is not interesting and did not contain anything - of interest, delete it and return the initialised NULL pointer. */ - if( newwanted < 0 ) { - if( answer ) { - result = answer; - } else { - elem = astXmlDelete( elem ); - } - -/* If the elem is of no interest, delete it and return the initialised - NULL pointer. */ - } else if( newwanted == 0 ) { - elem = astXmlDelete( elem ); - -/* Otherwise, "elem" itself is definitely of interest. If "elem" is - the first item of interest, return it. */ - } else if( wanted < 0 ) { - result = elem; - } - -/* If we have an answer to return, leave the loop, otherwise re-instate the - original current element in the document and continue to read any text - following the element. */ - if( result ) { - break; - } else { - (*doc)->current = parent; - state = 0; - } - - } if( state > 22 ) { - astError( AST__INTER, "ReadContent(xml): Illegal state (%d) encountered " - "(AST internal programming error).", status, state ); - } - -/* Remember the previous two character */ - lc2 = lc; - lc = c; - } - -/* Free any dynamic strings */ - text1 = astFree( text1 ); - text2 = astFree( text2 ); - text3 = astFree( text3 ); - if( msg ) msg = astFree( msg ); - -/* Delete the returned object if an error occurred. */ - if( !astOK ) result = astXmlDelete( result ); - -/* Return the result. */ - return result; -} - - - diff --git a/ast/xml.h b/ast/xml.h deleted file mode 100644 index bbd0c89..0000000 --- a/ast/xml.h +++ /dev/null @@ -1,392 +0,0 @@ -#if !defined( XML_INCLUDED ) /* Include this file only once */ -#define XML_INCLUDED -/* -*+ -* Name: -* xml.h - -* Type: -* C include file. - -* Purpose: -* Define the interface to the AST xml module - -* Invocation: -* #include "xml.h" - -* Description: -* This include file defines the interface to the internal xml module -* used by the AST library and provides the type definitions, function -* prototypes and macros, etc. needed to use this module. - -* Inheritance: -* The xml module is not a class and does not inherit. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David S. Berry (Starlink) - -* History: -* 23-OCT-2003 (DSB): -* Original version. -* 12-JAN-2004 (DSB): -* Major revisions. -*/ - - - -/* Constant Values. */ -/* ================ */ - -/* These constants are used as identifiers for the different classes of - XML object defined in this file. They are purposefully obscure to reduce - the possibility of random integer values being incorrectly interpreted - as valid XML types */ -#define AST__XMLBAD 0 /* Id for an uninitialised XmlObject */ -#define AST__XMLOBJECT 198263577 /* Id for XmlObject structure */ -#define AST__XMLELEM 182874779 /* Id for XmlElement structure */ -#define AST__XMLATTR 837746634 /* Id for XmlAttribute structure */ -#define AST__XMLCDATA 293854662 /* Id for XmlCDdataSection structure */ -#define AST__XMLCOM 748737648 /* Id for XmlComment structure */ -#define AST__XMLPI 983763553 /* Id for XmlPI structure */ -#define AST__XMLNAME 236756469 /* Id for XmlNamespace structure */ -#define AST__XMLDOC 356274395 /* Id for XmlDocument structure */ -#define AST__XMLPRO 743682474 /* Id for XmlPrologue structure */ -#define AST__XMLDEC 987546328 /* Id for XmlDeclPI structure */ -#define AST__XMLDTD 874673747 /* Id for XmlDTDec structure */ -#define AST__XMLWHITE 675849952 /* Id for XmlWhite structure */ -#define AST__XMLBLACK 347657863 /* Id for XmlBlack structure */ - -/* The following constants refer to "interfaces", not "classes". */ - -#define AST__XMLCHAR 456739289 /* Id for XmlCharData structure */ -#define AST__XMLCONT 673882993 /* Id for XmlContentItem structure */ -#define AST__XMLMISC 358768954 /* Id for XmlMiscItem structure */ -#define AST__XMLPAR 874366235 /* Id for XmlParent structure */ - -/* Define constants used to size global arrays in this module. */ -#define AST__XML_GETTAG_BUFF_LEN 200 - -/* Type Definitions. */ -/* ================= */ - -/* Pre-define types so they can be used within structure definitions. */ -typedef struct AstXmlObject AstXmlObject; -typedef struct AstXmlAttribute AstXmlAttribute; -typedef struct AstXmlNamespace AstXmlNamespace; -typedef struct AstXmlElement AstXmlElement; -typedef struct AstXmlBlack AstXmlBlack; -typedef struct AstXmlWhite AstXmlWhite; -typedef struct AstXmlCDataSection AstXmlCDataSection; -typedef struct AstXmlComment AstXmlComment; -typedef struct AstXmlPI AstXmlPI; -typedef struct AstXmlDocument AstXmlDocument; -typedef struct AstXmlPrologue AstXmlPrologue; -typedef struct AstXmlDeclPI AstXmlDeclPI; -typedef struct AstXmlDTDec AstXmlDTDec; - -/* The following data types define "interfaces". That is each data type - corresponds to a subset of the above classes. */ - -/* Marks a class as "character data" */ -typedef AstXmlObject AstXmlCharData; - -/* Marks a class as a "content item" */ -typedef AstXmlObject AstXmlContentItem; - -/* Marks a class as a "miscalleneous item" */ -typedef AstXmlObject AstXmlMiscItem; - -/* Marks a class as being able to own a child */ -typedef AstXmlObject AstXmlParent; - -/* XmlObject structure. */ -/* -------------------- */ -/* Contains data common to all other structures */ -struct AstXmlObject { - AstXmlParent *parent; /* The parent which contains this XmlObject */ - long int type; /* An ID giving the type of structure */ - int id; /* A unique id for this object. */ -}; - -/* XmlAttribute structure. */ -/* ----------------------- */ -/* Describes an XML attribute */ -struct AstXmlAttribute { - AstXmlObject obj; /* General information for this XmlObject */ - char *name; /* The name of the attribute */ - char *value; /* Attribute value */ - char *prefix; /* Namespace prefix for this attribute */ -}; - -/* XmlNamespace structure. */ -/* ----------------------- */ -/* Describes an XML namespace definition */ -struct AstXmlNamespace { - AstXmlObject obj; /* General information for this XmlObject */ - char *prefix; /* Namespace prefix */ - char *uri; /* Namespace URI */ -}; - -/* XmlElement structure. */ -/* --------------------- */ -/* Describes an XML element */ -struct AstXmlElement { - AstXmlObject obj; /* General information for this XmlObject */ - char *name; /* The type (name) of the element */ - AstXmlAttribute **attrs; /* Ptr. to list of attributes of the element */ - int nattr; /* Number of attributes in the above list */ - AstXmlContentItem **items; /* Ptr. to list of items in the element's content */ - int nitem; /* Number of items in above list */ - char *defns; /* Default Namespace URI for element content */ - char *prefix; /* Namespace prefix for this element */ - AstXmlNamespace **nsprefs; /* Ptr. to list of new Namespaces defined by this element */ - int nnspref; /* Number of Namespaces in above list */ - int complete; /* Have the contents of the element been read? */ -}; - -/* XmlBlack structure. */ -/* ---------------------- */ -/* Describes character data containing at least one non-blank character. */ -struct AstXmlBlack { - AstXmlObject obj; /* General information for this XmlObject */ - char *text; /* The character data */ -}; - -/* XmlWhite structure. */ -/* ------------------- */ -/* Describes character data containing no one non-blank characters. */ -struct AstXmlWhite { - AstXmlObject obj; /* General information for this XmlObject */ - char *text; /* The white character data */ -}; - -/* XmlCDataSection structure. */ -/* ----------------------- */ -/* Describes an XML CDATA section */ -struct AstXmlCDataSection { - AstXmlObject obj; /* General information for this XmlObject */ - char *text; /* The text of the cdata section */ -}; - -/* XmlComment structure. */ -/* --------------------- */ -/* Describes an XML CDATA section */ -struct AstXmlComment { - AstXmlObject obj; /* General information for this XmlObject */ - char *text; /* The text of the comment */ -}; - -/* XmlPI structure. */ -/* ---------------- */ -/* Describes an XML processing instruction */ -struct AstXmlPI { - AstXmlObject obj; /* General information for this XmlObject */ - char *target; /* The target of the processing instruction */ - char *text; /* The text of the processing instruction */ -}; - -/* XmlDocument structure. */ -/* ---------------------- */ -/* Describes an entire XML document */ -struct AstXmlDocument { - AstXmlObject obj; /* General information for this XmlObject */ - AstXmlPrologue *prolog; /* Pointer to document prologue */ - AstXmlElement *root; /* Pointer to root element */ - AstXmlMiscItem **epilog; /* List of XmlObjects forming the document epilogue */ - int nepi; /* No of XmlObjects pointers in "epilogue" */ - AstXmlElement *current; /* Pointer to element being read */ -}; - -/* XmlPrologue structure. */ -/* ---------------------- */ -/* Describes an XML document prologue */ -struct AstXmlPrologue { - AstXmlObject obj; /* General information for this XmlObject */ - AstXmlDeclPI *xmldecl; /* Pointer to XML declaration PI */ - AstXmlMiscItem **misc1; /* Group of of miscalleneous XmlObjects pointers */ - int nmisc1; /* No of XmlObjects pointers in "misc1" */ - AstXmlDTDec *dtdec; /* Pointer to Document Type Declaration */ - AstXmlMiscItem **misc2; /* Group of of miscalleneous XmlObjects pointers */ - int nmisc2; /* No of XmlObjects pointers in "misc2" */ -}; - -/* XmlDecPI structure. */ -/* ------------------- */ -/* Describes an XML declaration PI */ -struct AstXmlDeclPI { - AstXmlObject obj; /* General information for this XmlObject */ - char *text; /* The text of the XML declaration */ -}; - -/* XmlDTDec structure. */ -/* ------------------- */ -/* Describes a data type declaration */ -struct AstXmlDTDec { - AstXmlObject obj; /* General information for this XmlObject */ - char *name; /* Document type name */ - char *external; /* External ID */ - char *internal; /* Internal declarations */ -}; - - -#if defined(THREAD_SAFE) && defined(astCLASS) - -/* Define a structure holding all data items that are global within the - xml.c file. */ -typedef struct AstXmlGlobals { - int Next_ID; - char GetTag_Buff[ AST__XML_GETTAG_BUFF_LEN + 1 ]; -} AstXmlGlobals; - -#endif - - - - -/* Function prototypes. */ -/* ==================== */ -AstXmlAttribute *astXmlCheckAttribute_( void *, int, int * ); -AstXmlBlack *astXmlCheckBlack_( void *, int, int * ); -AstXmlCDataSection *astXmlCheckCDataSection_( void *, int, int * ); -AstXmlComment *astXmlCheckComment_( void *, int, int * ); -AstXmlContentItem *astXmlGetItem_( AstXmlElement *, int, int * ); -AstXmlDTDec *astXmlCheckDTDec_( void *, int, int * ); -AstXmlDeclPI *astXmlCheckDeclPI_( void *, int, int * ); -AstXmlDocument *astXmlCheckDocument_( void *, int, int * ); -AstXmlElement *astXmlAddElement_( AstXmlElement *, const char *, const char *, int * ); -AstXmlElement *astXmlCheckElement_( void *, int, int * ); -AstXmlParent *astXmlGetParent_( AstXmlObject *, int * ); -AstXmlObject *astXmlGetRoot_( AstXmlObject *, int * ); -AstXmlElement *astXmlReadDocument_( AstXmlDocument **, int (*)( AstXmlElement *, int * ), int, char (*)( void *, int * ), void *, int * ); -AstXmlNamespace *astXmlCheckNamespace_( void *, int, int * ); -AstXmlObject *astXmlCopy_( AstXmlObject *, int * ); -AstXmlObject *astXmlCheckObject_( void *, int, int * ); -AstXmlPI *astXmlCheckPI_( void *, int, int * ); -AstXmlPrologue *astXmlCheckPrologue_( void *, int, int * ); -AstXmlWhite *astXmlCheckWhite_( void *, int, int * ); -AstXmlCharData *astXmlCheckCharData_( void *, int, int * ); -AstXmlContentItem *astXmlCheckContentItem_( void *, int, int * ); -AstXmlMiscItem *astXmlCheckMiscItem_( void *, int, int * ); -AstXmlParent *astXmlCheckParent_( void *, int, int * ); -const char *astXmlFormat_( AstXmlObject *, int * ); -const char *astXmlGetAttributeValue_( AstXmlElement *, const char *, int * ); -const char *astXmlGetName_( AstXmlObject *, int * ); -const char *astXmlGetTag_( AstXmlObject *, int, int * ); -const char *astXmlGetType_( AstXmlObject *, int * ); -const char *astXmlGetURI_( AstXmlObject *, int * ); -const char *astXmlGetValue_( AstXmlObject *, int, int * ); -const char *astXmlShow_( AstXmlObject *, int * ); -int astXmlCheckType_( void *, long int, int * ); -int astXmlGetNattr_( AstXmlElement *, int * ); -int astXmlGetNitem_( AstXmlElement *, int * ); -void *astXmlAnnulTree_( AstXmlObject *, int * ); -void *astXmlAnnul_( AstXmlObject *, int * ); -void *astXmlDelete_( void *, int * ); -void astXmlAddAttr_( AstXmlElement *, const char *, const char *, const char *, int * ); -void astXmlAddCDataSection_( AstXmlElement *, const char *, int * ); -void astXmlAddCharData_( AstXmlParent *, int, const char *, int * ); -void astXmlAddComment_( AstXmlParent *, int, const char *, int * ); -void astXmlAddPI_( AstXmlParent *, int, const char *, const char *, int * ); -void astXmlAddURI_( AstXmlElement *, const char *, const char *, int * ); -void astXmlInsertElement_( AstXmlElement *, AstXmlElement *, int * ); -void astXmlPurge_( AstXmlParent *, int * ); -void astXmlRemoveAttr_( AstXmlElement *, const char *, const char *, int * ); -void astXmlRemoveItem_( AstXmlContentItem *, int * ); -void astXmlRemoveURI_( AstXmlElement *, const char *, int * ); -void astXmlSetXmlDec_( AstXmlDocument *, const char *, int * ); -void astXmlSetDTDec_( AstXmlDocument *, const char *, const char *, const char *, int * ); - -#if defined(THREAD_SAFE) && defined(astCLASS) -void astInitXmlGlobals_( AstXmlGlobals * ); -#else - -#ifdef DEBUG -int astXmlTrace_( int ); -#endif - -#endif - -/* Function interfaces. */ -/* ==================== */ -/* These wrap up the functions defined by this module. */ -#define astXmlGetType(this) astXmlGetType_(this,STATUS_PTR) -#define astXmlCheckAttribute(this,nullok) astXmlCheckAttribute_(this,nullok,STATUS_PTR) -#define astXmlCheckBlack(this,nullok) astXmlCheckBlack_(this,nullok,STATUS_PTR) -#define astXmlCheckCDataSection(this,nullok) astXmlCheckCDataSection_(this,nullok,STATUS_PTR) -#define astXmlCheckCharData(this,nullok) astXmlCheckCharData_(this,nullok,STATUS_PTR) -#define astXmlCheckComment(this,nullok) astXmlCheckComment_(this,nullok,STATUS_PTR) -#define astXmlCheckContentItem(this,nullok) astXmlCheckContentItem_(this,nullok,STATUS_PTR) -#define astXmlCheckDTDec(this,nullok) astXmlCheckDTDec_(this,nullok,STATUS_PTR) -#define astXmlCheckDeclPI(this,nullok) astXmlCheckDeclPI_(this,nullok,STATUS_PTR) -#define astXmlCheckDocument(this,nullok) astXmlCheckDocument_(this,nullok,STATUS_PTR) -#define astXmlCheckElement(this,nullok) astXmlCheckElement_(this,nullok,STATUS_PTR) -#define astXmlCheckMiscItem(this,nullok) astXmlCheckMiscItem_(this,nullok,STATUS_PTR) -#define astXmlCheckNamespace(this,nullok) astXmlCheckNamespace_(this,nullok,STATUS_PTR) -#define astXmlCheckObject(this,nullok) astXmlCheckObject_(this,nullok,STATUS_PTR) -#define astXmlCheckPI(this,nullok) astXmlCheckPI_(this,nullok,STATUS_PTR) -#define astXmlCheckParent(this,nullok) astXmlCheckParent_(this,nullok,STATUS_PTR) -#define astXmlCheckPrologue(this,nullok) astXmlCheckPrologue_(this,nullok,STATUS_PTR) -#define astXmlCheckWhite(this,nullok) astXmlCheckWhite_(this,nullok,STATUS_PTR) - -#define astXmlAddAttr(elem,name,value,prefix) astXmlAddAttr_(astXmlCheckElement(elem,0),name,value,prefix,STATUS_PTR) -#define astXmlAddURI(elem,prefix,uri) astXmlAddURI_(astXmlCheckElement(elem,0),prefix,uri,STATUS_PTR) -#define astXmlAnnul(this) astXmlAnnul_(astXmlCheckObject(this,1),STATUS_PTR) -#define astXmlDelete(this) astXmlDelete_(this,STATUS_PTR) -#define astXmlAnnulTree(this) astXmlAnnulTree_(astXmlCheckObject(this,1),STATUS_PTR) -#define astXmlAddCDataSection(this,text) astXmlAddCDataSection_(astXmlCheckElement(this,0),text,STATUS_PTR) -#define astXmlAddCharData(this,where,text) astXmlAddCharData_(astXmlCheckParent(this,0),where,text,STATUS_PTR) -#define astXmlAddComment(this,where,text) astXmlAddComment_(astXmlCheckParent(this,0),where,text,STATUS_PTR) -#define astXmlAddElement(this,name,prefix) astXmlAddElement_(astXmlCheckElement(this,1),name,prefix,STATUS_PTR) -#define astXmlAddPI(this,where,target,text) astXmlAddPI_(astXmlCheckParent(this,0),where,target,text,STATUS_PTR) -#define astXmlGetParent(this) astXmlGetParent_(astXmlCheckObject(this,0),STATUS_PTR) -#define astXmlGetRoot(this) astXmlGetRoot_(astXmlCheckObject(this,0),STATUS_PTR) -#define astXmlGetName(this) astXmlGetName_(astXmlCheckObject(this,0),STATUS_PTR) -#define astXmlGetValue(this,report) astXmlGetValue_(astXmlCheckObject(this,0),report,STATUS_PTR) -#define astXmlGetAttributeValue(this,name) astXmlGetAttributeValue_(astXmlCheckElement(this,0),name,STATUS_PTR) -#define astXmlGetNattr(this) astXmlGetNattr_(astXmlCheckElement(this,0),STATUS_PTR) -#define astXmlGetNitem(this) astXmlGetNitem_(astXmlCheckElement(this,0),STATUS_PTR) -#define astXmlGetItem(this,item) astXmlGetItem_(astXmlCheckElement(this,0),item,STATUS_PTR) -#define astXmlGetAttributeValue(this,name) astXmlGetAttributeValue_(astXmlCheckElement(this,0),name,STATUS_PTR) -#define astXmlGetTag(this,opening) astXmlGetTag_(astXmlCheckObject(this,0),opening,STATUS_PTR) -#define astXmlGetURI(this) astXmlGetURI_(astXmlCheckObject(this,0),STATUS_PTR) -#define astXmlFormat(this) astXmlFormat_(astXmlCheckObject(this,0),STATUS_PTR) -#define astXmlShow(this) astXmlShow_(astXmlCheckObject(this,0),STATUS_PTR) -#define astXmlRemoveItem(this) astXmlRemoveItem_(astXmlCheckContentItem(this,0),STATUS_PTR) -#define astXmlRemoveAttr(this,name,prefix) astXmlRemoveAttr_(astXmlCheckElement(this,0),name,prefix,STATUS_PTR) -#define astXmlRemoveURI(this,prefix) astXmlRemoveURI_(astXmlCheckElement(this,0),prefix,STATUS_PTR) -#define astXmlReadDocument(doc,is_wanted,skip,source,data) astXmlReadDocument_(doc,is_wanted,skip,source,data,STATUS_PTR) -#define astXmlInsertElement(this,elem) astXmlInsertElement_(astXmlCheckElement(this,0),astXmlCheckElement(elem,0),STATUS_PTR) -#define astXmlPurge(this) astXmlPurge_(astXmlCheckParent(this,1),STATUS_PTR) -#define astXmlSetXmlDec(this,text) astXmlSetXmlDec_(astXmlCheckDocument(this,0),text,STATUS_PTR) -#define astXmlSetDTDec(this,text1,text2,text3) astXmlSetDTDec_(astXmlCheckDocument(this,0),text1,text2,text3,STATUS_PTR) -#define astXmlCheckType(this,type) astXmlCheckType_(this,type,STATUS_PTR) -#define astXmlCopy(this) astXmlCopy_(astXmlCheckObject(this,1),STATUS_PTR) - -#ifdef DEBUG -#define astXmlTrace(show) astXmlTrace_(show) -#endif - -#endif - - - diff --git a/ast/xmlchan.c b/ast/xmlchan.c deleted file mode 100644 index a03e252..0000000 --- a/ast/xmlchan.c +++ /dev/null @@ -1,14120 +0,0 @@ -/* -*class++ -* Name: -* XmlChan - -* Purpose: -* I/O Channel using XML to represent Objects. - -* Constructor Function: -c astXmlChan -f AST_XMLCHAN - -* Description: -* A XmlChan is a specialised form of Channel which supports XML I/O -* operations. Writing an Object to an XmlChan (using -c astWrite) will, if the Object is suitable, generate an -f AST_WRITE) will, if the Object is suitable, generate an -* XML description of that Object, and reading from an XmlChan will -* create a new Object from its XML description. -* -* Normally, when you use an XmlChan, you should provide "source" -c and "sink" functions which connect it to an external data store -c by reading and writing the resulting XML text. These functions -f and "sink" routines which connect it to an external data store -f by reading and writing the resulting XML text. These routines -* should perform any conversions needed between external character -c encodings and the internal ASCII encoding. If no such functions -f encodings and the internal ASCII encoding. If no such routines -* are supplied, a Channel will read from standard input and write -* to standard output. -* -* Alternatively, an XmlChan can be told to read or write from -* specific text files using the SinkFile and SourceFile attributes, -* in which case no sink or source function need be supplied. - -* Inheritance: -* The XmlChan class inherits from the Channel class. - -* Attributes: -* In addition to those attributes common to all Channels, every -* XmlChan also has the following attributes: -* -* - XmlFormat: System for formatting Objects as XML -* - XmlLength: Controls output buffer length -* - XmlPrefix: The namespace prefix to use when writing - -* Functions: -c The XmlChan class does not define any new functions beyond those -f The XmlChan class does not define any new routines beyond those -* which are applicable to all Mappings. - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* . - -* Authors: -* DSB: David Berry (Starlink) - -* History: -* 10-OCT-2003 (DSB): -* Original version. -* 6-FEB-2004 (DSB): -* Added XmlPrefix and XmlFormat attributes. -* 10-FEB-2004 (DSB): -* - Added debug conditional code to keep track of memory leaks. -* - Fixed bug which prevented more than 1 object being read from -* an XmlChan. -* 7-DEC-2005 (DSB): -* Free memory allocated by calls to astReadString. -* 12-FEB-2010 (DSB): -* Represent AST__BAD externally using the string "". -*class-- - -* Further STC work: -* - Speed up general STC processing (a lot of time seems to be spent -* simplifying things) -* - Document (including a complete description of what is and is not -* supported in the reference docs for the XmlFormat attribute). -* - Produce a schema describing the format which can in fact be read by -* AST. -* - Look at Jonathan McDowell's mini-STC schema (also STC stuff in -* spectral data model) -* - Web services. Read only: test STCs for overlap, test points for -* inclusion/exclusion, plot a mask over an image, verification (can AST -* read it & does it generate warnings?). Read/Write: convert FITS to STC, -* transform STC into a new coord system. -* - Add support for writing as well as reading -* - Modify Stc... constructors to check that the supplied Frame is suitable. -* - What about multiple AstroCoordFrames and AstroCoordAreas in a STC? -* - Add support for generic CoordFrames -* - What should be done with pixel coords info within STC? -* - Extend coverage (e.g. to 3D space frames, etc) - -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to - the header files that define class interfaces that they should make - "protected" symbols available. */ -#define astCLASS XmlChan - -/* The XML element name used to store an AST attribute setting */ -#define ATTR "_attribute" - -/* The XML element name used for an AST "isa" element */ -#define ISA "_isa" - -/* The XML attribute name which holds the name of the AST class which - defines the item contained in the element. */ -#define DEFINEDBY "definedby" - -/* The XML attribute name which holds the name of the AST attribute */ -#define NAME "name" - -/* The XML attribute name which holds the value of the AST attribute */ -#define VALUE "value" - -/* The XML attribute name which indicates if the AST attribute value is a - default value. */ -#define DEFAULT "default" - -/* The XML attribute name which indicates if the AST attribute value was - originally a string value. */ -#define QUOTED "quoted" - -/* The XML attribute name which holds a description of the AST attribute. */ -#define DESC "desc" - -/* The XML attribute name which holds the label associated with an AST - Object (if any). */ -#define LABEL "label" - -/* A string used to indicate atrue attribute value */ -#define TRUE "true" - -/* Format identifiers and strings */ -#define UNKNOWN_FORMAT -1 -#define NATIVE_FORMAT 0 -#define QUOTED_FORMAT 1 -#define IVOA_FORMAT 2 -#define MAX_FORMAT 2 -#define UNKNOWN_STRING "UNKNOWN" -#define NATIVE_STRING "NATIVE" -#define QUOTED_STRING "QUOTED" -#define IVOA_STRING "IVOA" - -/* Values representing message severities. */ -#define WARNING 0 -#define FAILURE 1 -#define RESET 2 - -/* Known IVOA namespaces. When a new name is added, update the FindIVOAClass - function. */ -#define STC_URI "urn:nvo-stc" - -/* Known IVOA Classes and attributes. When a new name is added, it may be - necessary to update the FindIVOAClass function. */ -#define STC_RESOURCE_PROFILE "STCResourceProfile" -#define SEARCH_LOCATION "SearchLocation" -#define OBSERVATION_LOCATION "ObservationLocation" -#define OBSERVATORY_LOCATION "ObservatoryLocation" -#define CATALOG_ENTRY_LOCATION "CatalogEntryLocation" -#define OBS_DATA_LOCATION "ObsDataLocation" -#define ASTRO_COORD_SYSTEM "AstroCoordSystem" -#define ASTRO_COORD_AREA "AstroCoordArea" -#define ASTRO_COORDS "AstroCoords" -#define TIME_FRAME "TimeFrame" -#define SPACE_FRAME "SpaceFrame" -#define SPECTRAL_FRAME "SpectralFrame" -#define REDSHIFT_FRAME "RedshiftFrame" -#define DOPPLER_DEFINITION "DopplerDefinition" - -/* Returns string "an" or "a" depending on whether the first character of - the supplied string is a vowel or not. */ -#define ANA(t) (t?(strchr("AaEeIiOoUu",t[0])?"an":"a"):"") - -/* String used to represent AST__BAD externally. */ -#define BAD_STRING "" - -/* Include files. */ -/* ============== */ -/* Interface definitions. */ -/* ---------------------- */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "frame.h" /* Coordinate Frames */ -#include "timeframe.h" /* Time coordinate Frames */ -#include "cmpframe.h" /* Coordinate Frames */ -#include "skyframe.h" /* Celestial coordinate Frames */ -#include "specframe.h" /* Spectral coordinate Frames */ -#include "region.h" /* Regions within coordinate Frames */ -#include "ellipse.h" /* Ellipses within coordinate Frames */ -#include "pointlist.h" /* Points within coordinate Frames */ -#include "polygon.h" /* Polygons within coordinate Frames */ -#include "circle.h" /* Circles within coordinate Frames */ -#include "keymap.h" /* Mapping of keys to values */ -#include "channel.h" /* Interface for parent class */ -#include "xmlchan.h" /* Interface definition for this class */ -#include "loader.h" /* Interface to the global loader */ -#include "object.h" /* Base Object class */ -#include "wcsmap.h" /* Angular conversion constants */ -#include "xml.h" /* AST XML facilities */ -#include "erfa.h" /* ERFA functions */ -#include "stcresourceprofile.h" /* IVOA StcResourceProfile class */ -#include "stcsearchlocation.h" /* IVOA SearchLocation class */ -#include "stccatalogentrylocation.h"/* IVOA CatalogEntryLocation class */ -#include "stcobsdatalocation.h" /* IVOA ObsDataLocation class */ -#include "nullregion.h" /* Null regions */ -#include "interval.h" /* Axis intervals */ -#include "box.h" /* Box regions */ -#include "cmpregion.h" /* Compound regions */ -#include "prism.h" /* Prism regions */ -#include "unitmap.h" /* Unit Mappings */ -#include "unit.h" /* Unit handling utilities */ -#include "pal.h" /* slalib functions */ -#include "globals.h" /* Thread-safe global data access */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include -#include -#include -#include -#include -#include -#include - -/* Type Definitions */ -/* ================ */ - -/* A type for functions which read an IVOA element and return a - corresponding AST Object. */ -typedef AstObject *(*IVOAReader)( AstXmlChan *, AstXmlElement *, int * ); - -/* A structure to hold the result of scanning the content of an IVOA - element.*/ -typedef struct IVOAScan { - int n; /* Number of element names described by this structure */ - int *count; /* Array holding number of each element name found */ - AstXmlElement ***el; /* Array holding pointers to each element found */ -} IVOAScan; - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static int (* parent_getfull)( AstChannel *, int * ); -static int (* parent_getcomment)( AstChannel *, int * ); -static int (* parent_getindent)( AstChannel *, int * ); - -/* Text values used to represent XmlFormat values externally. These - should be in the order defined by the associated constants above. */ -static const char *xformat[3] = { NATIVE_STRING, QUOTED_STRING, IVOA_STRING }; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->IsUsable_This = NULL; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->GetNextChar_C = NULL; \ - globals->GetNextChar_Buf = NULL; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(XmlChan) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(XmlChan,Class_Init) -#define class_vtab astGLOBAL(XmlChan,Class_Vtab) -#define isusable_this astGLOBAL(XmlChan,IsUsable_This) -#define getattrib_buff astGLOBAL(XmlChan,GetAttrib_Buff) -#define getnextchar_c astGLOBAL(XmlChan,GetNextChar_C) -#define getnextchar_buf astGLOBAL(XmlChan,GetNextChar_Buf) - - - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* An XmlChan pointer use to communicate with the IsUsable function. */ -static AstXmlChan *isusable_this = NULL; - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ 51 ]; - -/* Variables used in GetNextChar */ -static char *getnextchar_c = NULL; /* Pointer to next character to read */ -static char *getnextchar_buf = NULL; /* Pointer to previously read text */ - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstXmlChanVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#endif - - -/* External Interface Function Prototypes. */ -/* ======================================= */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstXmlChan *astXmlChanForId_( const char *(*)( void ), - char *(*)( const char *(*)( void ), int * ), - void (*)( const char * ), - void (*)( void (*)( const char * ), const char *, int * ), - const char *, ... ); -AstXmlChan *astXmlChanId_( const char *(* source)( void ), - void (* sink)( const char * ), - const char *options, ... ); - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstObject *AstroCoordSystemReader( AstXmlChan *, AstXmlElement *, int * ); -static AstObject *MakeAstFromXml( AstXmlChan *, AstXmlElement *, int * ); -static AstObject *ObsDataLocationReader( AstXmlChan *, AstXmlElement *, int * ); -static AstObject *Read( AstChannel *, int * ); -static AstObject *ReadObject( AstChannel *, const char *, AstObject *, int * ); -static AstObject *RedshiftFrameReader( AstXmlChan *, AstXmlElement *, int * ); -static AstObject *SpaceFrameReader( AstXmlChan *, AstXmlElement *, int * ); -static AstObject *SpectralFrameReader( AstXmlChan *, AstXmlElement *, int * ); -static AstObject *StcMetadataReader( AstXmlChan *, AstXmlElement *, int * ); -static AstObject *TimeFrameReader( AstXmlChan *, AstXmlElement *, int * ); -static AstPointList *ObservatoryLocationReader( AstXmlChan *, AstXmlElement *, AstStcObsDataLocation *, int * ); -static AstRegion *AllSkyReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *AstroCoordAreaReader( AstXmlChan *, AstXmlElement *, AstFrame *, AstRegion *[4], int, AstKeyMap **, int * ); -static AstRegion *BoxReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *CircleReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *ConstraintReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *ConvexReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *Coord2VecIntervalReader( AstXmlChan *, AstXmlElement *, const char *, AstFrame *, int * ); -static AstRegion *Coord3VecIntervalReader( AstXmlChan *, AstXmlElement *, const char *, AstFrame *, int * ); -static AstRegion *CoordScalarIntervalReader( AstXmlChan *, AstXmlElement *, const char *, AstFrame *, int * ); -static AstRegion *EllipseReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *IntersectionReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *NegationReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *PolygonReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *Position2DReader( AstXmlChan *, AstXmlElement *, AstFrame *, double *, AstKeyMap **, int * ); -static AstRegion *PositionIntervalReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *RedshiftIntervalReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *RedshiftReader( AstXmlChan *, AstXmlElement *, AstFrame *, AstKeyMap **, int * ); -static AstRegion *StcRegionReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *RegionReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *SpectralIntervalReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *SpectralReader( AstXmlChan *, AstXmlElement *, AstFrame *, double *, AstKeyMap **, int * ); -static AstRegion *SphereReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstRegion *TimeIntervalReader( AstXmlChan *, AstXmlElement *, AstTimeFrame *, int * ); -static AstRegion *TimeReader( AstXmlChan *, AstXmlElement *, AstTimeFrame *, double *, AstKeyMap **, int * ); -static AstRegion *UnionReader( AstXmlChan *, AstXmlElement *, AstFrame *, int * ); -static AstSystemType RedshiftSys( AstXmlChan *, AstXmlElement *, char **, int, int * ); -static AstSystemType SpecSys( AstXmlChan *, AstXmlElement *, const char *, int, int * ); -static AstXmlElement *FindAttribute( AstXmlChan *, const char *, int * ); -static AstXmlElement *FindElement( AstXmlChan *, AstXmlElement *, const char *, int * ); -static AstXmlElement *FindObject( AstXmlChan *, const char *, int * ); -static AstXmlElement *MakePos2D( AstXmlChan *, AstXmlElement *, int * ); -static AstXmlElement *ReadXmlText( AstXmlChan *, int * ); -static AstXmlElement *Remove( AstXmlChan *, AstXmlElement *, int * ); -static IVOAReader FindIVOAClass( AstXmlElement *, int *, int * ); -static IVOAScan *FreeIVOAScan( IVOAScan *, int * ); -static IVOAScan *ScanIVOAElement( AstXmlChan *, AstXmlElement *, int, const char *[], int[], int[], int * ); -static char *ReadString( AstChannel *, const char *, const char *, int * ); -static char *SourceWrap( const char *(*)( void ), int * ); -static char GetNextChar( void *, int * ); -static const char *FindNextIsA( AstXmlElement *, int, int * ); -static const char *GetAttrib( AstObject *, const char *, int * ); -static const char *GetTag( AstXmlObject *, int, int * ); -static double AstronTimeReader( AstXmlChan *, AstXmlElement *, AstTimeFrame *, int * ); -static double AttrValueD( AstXmlChan *, AstXmlElement *, const char *, double, int * ); -static double ElemValueD( AstXmlChan *, AstXmlElement *, double, int * ); -static double Error2PAReader( AstXmlChan *, AstXmlElement *, double *, int * ); -static double MakeMJD( AstTimeFrame *, double, int * ); -static double PosAngleReader( AstXmlChan *, AstXmlElement *, int * ); -static double ReadDouble( AstChannel *, const char *, double, int * ); -static int AstroCoordsReader( AstXmlChan *, AstXmlElement *, AstFrame *, AstRegion *[4], AstKeyMap **, int * ); -static int AttrValueB( AstXmlChan *, AstXmlElement *, const char *, int, int * ); -static int AttrValueI( AstXmlChan *, AstXmlElement *, const char *, int, int * ); -static int ElemListD( AstXmlChan *, AstXmlElement *, int, double *, int * ); -static int FindString( int, const char *[], const char *, const char *, const char *, const char *, int * ); -static int GetComment( AstChannel *, int * ); -static int GetFull( AstChannel *, int * ); -static int GetIndent( AstChannel *, int * ); -static int IsUsable( AstXmlElement *, int * ); -static int ReadInt( AstChannel *, const char *, int, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static int Use( AstXmlChan *, int, int, int * ); -static int Ustrcmp( const char *, const char *, int * ); -static int Ustrncmp( const char *, const char *, size_t, int * ); -static int VertexReader( AstXmlChan *, AstXmlElement *, double *, double *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void FillAndLims( AstXmlChan *, AstXmlElement *, AstRegion *, int * ); -static void OutputText( AstXmlChan *, const char *, int, int * ); -static void ReCentreAnc( AstRegion *, int, AstKeyMap **, int * ); -static void ReadClassData( AstChannel *, const char *, int * ); -static void Report( AstXmlChan *, AstXmlElement *, int, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); -static void SinkWrap( void (*)( const char * ), const char *, int * ); -static void WriteBegin( AstChannel *, const char *, const char *, int * ); -static void WriteDouble( AstChannel *, const char *, int, int, double, const char *, int * ); -static void WriteEnd( AstChannel *, const char *, int * ); -static void WriteInt( AstChannel *, const char *, int, int, int, const char *, int * ); -static void WriteIsA( AstChannel *, const char *, const char *, int * ); -static void WriteObject( AstChannel *, const char *, int, int, AstObject *, const char *, int * ); -static void WriteString( AstChannel *, const char *, int, int, const char *, const char *, int * ); -static AstTimeScaleType TimeScaleReader( AstXmlChan *, AstXmlElement *, int * ); - -static int TestXmlLength( AstXmlChan *, int * ); -static void ClearXmlLength( AstXmlChan *, int * ); -static void SetXmlLength( AstXmlChan *, int, int * ); -static int GetXmlLength( AstXmlChan *, int * ); - -static int TestXmlFormat( AstXmlChan *, int * ); -static void ClearXmlFormat( AstXmlChan *, int * ); -static void SetXmlFormat( AstXmlChan *, int, int * ); -static int GetXmlFormat( AstXmlChan *, int * ); - -static int TestXmlPrefix( AstXmlChan *, int * ); -static void ClearXmlPrefix( AstXmlChan *, int * ); -static void SetXmlPrefix( AstXmlChan *, const char *, int * ); -static const char * GetXmlPrefix( AstXmlChan *, int * ); - -/* Member functions. */ -/* ================= */ - -static AstRegion *AllSkyReader( AstXmlChan *this, AstXmlElement *elem, - AstFrame *frm, int *status ){ -/* -* Name: -* AllSkyReader - -* Purpose: -* Make an AST Region from an IVOA AllSky element. - -* Type: -* Private function. - -* Synopsis: -* #include "xmlchan.h" -* AstRegion *AllSkyReader( AstXmlChan *this, AstXmlElement *elem, -* AstFrame *frm, int *status ) - -* Class Membership: -* XmlChan member function. - -* Description: -* This function makes a new AST Region from the supplied IVOA -* AllSky element. - -* Parameters: -* this -* Pointer to the XmlChan. -* elem -* Pointer to the IVOA AllSky element. -* frm -* Pointer to the 2D Frame in which the returned Region should be -* defined. If the Unit attribute is not set, this function will -* set it to the value supplied in "unit" before returning. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new Region. - -*/ - -/* Local Variables: */ - AstRegion *new; /* Pointer to returned Region */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Create a negated NullRegion (this is a boundless Region which includes - all points in the Frame). */ - new = (AstRegion *) astNullRegion( frm, NULL, "negated=1", status ); - -/* Get any fill factor from the element and assign to the returned Region. */ - FillAndLims( this, elem, new, status ); - -/* Annul any returned Frame if an error has occurred. */ - if( !astOK ) new = astAnnul( new ); - -/* Return the pointer to the new Region. */ - return new; -} - -static AstRegion *AstroCoordAreaReader( AstXmlChan *this, AstXmlElement *elem, - AstFrame *frm, AstRegion *uncs[4], - int nanc, AstKeyMap **ancs, int *status ) { -/* -* Name: -* AstroCoordAreaReader - -* Purpose: -* Make an AST Region from an IVOA AstroCoordArea element. - -* Type: -* Private function. - -* Synopsis: -* #include "xmlchan.h" -* AstRegion *AstroCoordAreaReader( AstXmlChan *this, AstXmlElement *elem, -* AstFrame *frm, AstRegion *uncs[4], -* int nanc, AstKeyMap **ancs, int *status ) - -* Class Membership: -* XmlChan member function. - -* Description: -* This function makes a new AST Region from the supplied IVOA -* AstroCoordArea element. - -* Parameters: -* this -* Pointer to the XmlChan. -* elem -* Pointer to the IVOA AstroCoordArea element. May be NULL, in -* which case a NullRegion is returned. -* frm -* The Frame in which the returned Region is to be defined. If -* Units or reference values (Epoch, RestFreq, RefRA, etc) are not set -* for any axes, then they will be set by this function if possible. -* uncs -* Array holding pointers to the uncertainty Regions to be associated -* with each of the four STC domains (space, time, spectral, redshift). -* NULL should be suppied in any element for which no uncertainty is -* available. -* nanc -* Number of KeyMap pointers stored in "ancs" -* ancs -* Pointer to an array of "nanc" elements, each being a pointer to -* a KeyMap. Each one describes the ancilary information in an -* AstroCoords element associated with the AstroCoordsArea decribed -* by "region". Each KeyMap has elements with keys AST__STCERROR, -* AST__STCRES, AST__STCSIZE, AST__STCPIXSZ, AST__STCVALUE each of -* which holds a pointer to a Region. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the new Region. -*/ - -/* Local Variables: */ - AstRegion *r; - AstFrame *cfrm; - AstFrame *fr; - AstFrame *pfrm; - AstFrame *red_frame; - AstFrame *space_frame; - AstFrame *spec_frame; - AstFrameSet *fs; - AstMapping *map; - AstObject *o; - AstRegion **red_list; - AstRegion **spec_list; - AstRegion **space_list; - AstRegion **time_list; - AstRegion *new; - AstRegion *reg; - AstRegion *rred; - AstRegion *rspec; - AstRegion *rspace; - AstRegion *rtime; - AstRegion *sum; - AstRegion *tmp; - AstTimeFrame *time_frame; - IVOAScan *scan; - char *decset; - char *raset; - char buff[ AST__DBL_DIG + 30 ]; - char setting[ 100 ]; - const char *dom; - const char *id; - const char *names[4]; - const char *name; - const char *old_units; - const char *text; - double decref; - double lbnd[2]; - double raref; - double space_val[2]; - double spec_val; - double time_val; - double ubnd[2]; - int i; - int ianc; - int ired; - int ispace; - int ispec; - int itime; - int k; - int l; - int max[4]; - int min[4]; - int nax; - int nred; - int nspace; - int nspec; - int ntime; - int paxis; - - static const char *key[ 5 ] = { AST__STCERROR, - AST__STCRES, - AST__STCSIZE, - AST__STCPIXSZ, - AST__STCVALUE }; - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If null AstroCoordArea element has been supplied, return a NullRegion. */ - if( !elem ) { - new = (AstRegion *) astNullRegion( frm, NULL, "", status ); - -/* Otherwise, create a Region of suitable class. */ - } else { - -/* First identify the individual Frames within the supplied Frame. Current - implementation for spatial axes is limited to celestial longitude and - latitude. */ - space_frame = NULL; - spec_frame = NULL; - red_frame = NULL; - time_frame = NULL; - - nax = astGetNaxes( frm ); - for( i = 0; i < nax; i++ ) { - astPrimaryFrame( frm, i, &pfrm, &paxis ); - dom = astGetDomain( pfrm ); - if( !strcmp( dom, "SKY" ) ) { - if( !space_frame ) { - space_frame = astClone( pfrm ); - } else if( pfrm != space_frame) { - Report( this, elem, FAILURE, "contains more than 2 spatial axes", status ); - } - - } else if( !strcmp( dom, "TIME" ) ) { - if( !time_frame ) { - if( astIsATimeFrame( pfrm ) ) { - time_frame = (AstTimeFrame *) astClone( pfrm ); - } else if( astOK ) { - astError( AST__INTER, "AstroCoordAreaReader(XmlChan): %s " - "supplied where TimeFrame expected (internal " - "AST programming error).", status, astGetClass( pfrm ) ); - } - } else { - Report( this, elem, FAILURE, "contains more than 1 time axis", status ); - } - - } else if( !strcmp( dom, "SPECTRUM" ) ) { - if( !spec_frame ) { - spec_frame = astClone( pfrm ); - } else { - Report( this, elem, FAILURE, "contains more than 1 spectral axis", status ); - } - - } else if( !strcmp( dom, "REDSHIFT" ) ) { - if( !red_frame ) { - red_frame = astClone( pfrm ); - } else { - Report( this, elem, FAILURE, "contains more than 1 redshift axis", status ); - } - - } else { - Report( this, elem, FAILURE, "contains axes for an unsupported domain", status ); - } - pfrm = astAnnul( pfrm ); - } - -/* Search the supplied element for the required sub-elements. */ - names[ 0 ] = "Sphere|PositionInterval|Region"; - names[ 1 ] = "TimeInterval"; - names[ 2 ] = "SpectralInterval"; - names[ 3 ] = "RedshiftInterval"; - min[ 0 ] = 0; - min[ 1 ] = 0; - min[ 2 ] = 0; - min[ 3 ] = 0; - max[ 0 ] = INT_MAX; - max[ 1 ] = INT_MAX; - max[ 2 ] = INT_MAX; - max[ 3 ] = INT_MAX; - scan = ScanIVOAElement( this, elem, 4, names, min, max, status ); - -/* If succesfull.. */ - if( scan ) { - -/* Create Regions for all the SpatialIntervals found in the supplied element. */ - space_val[ 0 ] = AST__BAD; - space_val[ 1 ] = AST__BAD; - nspace = scan->count[ 0 ]; - space_list = astMalloc( sizeof(AstRegion *)*(size_t)nspace ); - if( space_list ) { - for( ispace = 0; ispace < nspace; ispace++ ) { - name = astXmlGetName( scan->el[ 0 ][ ispace ] ); - if( !strcmp( name, "Sphere" ) ) { - space_list[ ispace ] = SphereReader( this, - scan->el[ 0 ][ ispace ], - space_frame, status ); - } else if( !strcmp( name, "PositionInterval" ) ) { - space_list[ ispace ] = PositionIntervalReader( this, - scan->el[ 0 ][ ispace ], - space_frame, status ); - } else if( !strcmp( name, "Region" ) ) { - space_list[ ispace ] = StcRegionReader( this, - scan->el[ 0 ][ ispace ], - space_frame, status ); - } else if( astOK ) { - astError( AST__INTER, "AstroCoordAreaReader(XmlChan): " - "SpatialInterval type %s not yet supported " - "(AST internal programming error).", status, name ); - break; - } - -/* Store any uncertainty region.*/ - if( uncs[ 0 ] ) astSetUnc( space_list[ ispace ], uncs[ 0 ] ); - - } - -/* If the spatial region is a single point we will use the point as the - reference position for any SpecFrames which are created. If there is - just one spatial interval, and if it is bounded. and if the bounds are - equal on both axes, note the mean position. */ - if( nspace == 1 ){ - if( astGetBounded( space_list[ 0 ] ) ) { - astGetRegionBounds( space_list[ 0 ], lbnd, ubnd ); - if( astEQUAL( lbnd[ 0 ], ubnd[ 0 ] ) && - astEQUAL( lbnd[ 1 ], ubnd[ 1 ] ) ) { - space_val[ 0 ] = 0.5*( lbnd[ 0 ] + ubnd[ 0 ] ); - space_val[ 1 ] = 0.5*( lbnd[ 1 ] + ubnd[ 1 ] ); - } - } - } - } - -/* Create Regions for all the TimeIntervals found in the supplied element. */ - time_val = AST__BAD; - ntime = scan->count[ 1 ]; - time_list = astMalloc( sizeof(AstRegion *)*(size_t)ntime ); - if( time_list ) { - for( itime = 0; itime < ntime; itime++ ) { - time_list[ itime ] = TimeIntervalReader( this, - scan->el[ 1 ][ itime ], - time_frame, status ); - -/* Store any uncertainty region. Transfer the System and TimeOrigin - values from the time region to the time uncertainty, if set. */ - if( uncs[ 1 ] ) { - - if( astTestSystem( time_frame ) && - astTestTimeOrigin( time_frame ) ) { - - sprintf( setting, "System=%s", - astGetC( time_frame, "System" ) ); - astRegSetAttrib( uncs[ 1 ], setting, NULL ); - - - if( astTestUnit( time_frame, 0 ) ) { - old_units = astGetUnit( time_frame, 0 ); - old_units = astStore( NULL, old_units, - strlen( old_units ) + 1 ); - } else { - old_units = NULL; - } - - astSetUnit( time_frame, 0, astGetUnit( uncs[ 1 ], 0 ) ); - - sprintf( setting, "TimeOrigin=%s", - astGetC( time_frame, "TimeOrigin" ) ); - astRegSetAttrib( uncs[ 1 ], setting, NULL ); - - if( old_units ) { - astSetUnit( time_frame, 0, old_units ); - old_units = astFree( (void *) old_units ); - } else { - astClearUnit( time_frame, 0 ); - } - - } - - astSetUnc( time_list[ itime ], uncs[ 1 ] ); - } - } - -/* Use the mid point as the Epoch for all Frames which are created. If - either limit is not specified, use the specified limit. */ - if( ntime > 0 ){ - astGetRegionBounds( time_list[ 0 ], lbnd, ubnd ); - if( fabs( lbnd[ 0 ] ) != DBL_MAX && lbnd[ 0 ] != AST__BAD ){ - if( fabs( ubnd[ 0 ] ) != DBL_MAX && ubnd[ 0 ] != AST__BAD ){ - time_val = 0.5*( lbnd[ 0 ] + ubnd[ 0 ] ); - } else { - time_val = lbnd[ 0 ]; - } - } else if( fabs( ubnd[ 0 ] ) != DBL_MAX && ubnd[ 0 ] != AST__BAD ){ - time_val = ubnd[ 0 ]; - } - } - } - -/* Create Regions for all the SpectralIntervals found in the supplied element. */ - spec_val = AST__BAD; - nspec = scan->count[ 2 ]; - spec_list = astMalloc( sizeof(AstRegion *)*(size_t)nspec ); - if( spec_list ) { - for( ispec = 0; ispec < nspec; ispec++ ) { - spec_list[ ispec ] = SpectralIntervalReader( this, - scan->el[ 2 ][ ispec ], - spec_frame, status ); -/* Store any uncertainty region.*/ - if( uncs[ 2 ] ) astSetUnc( spec_list[ ispec ], uncs[ 2 ] ); - } - -/* If the spectral region is a single point we will use the point as the - rest frequency for all RedShift Frames which are created. If there is just - one spectral interval, and if it is bounded. and if the bounds are equal, - note the mean spectral value. */ - if( nspec == 1 ){ - if( astGetBounded( spec_list[ 0 ] ) ) { - astGetRegionBounds( spec_list[ 0 ], lbnd, ubnd ); - if( astEQUAL( lbnd[ 0 ], ubnd[ 0 ] ) ) { - spec_val = 0.5*( lbnd[ 0 ] + ubnd[ 0 ] ); - } - } - } - } - -/* Create Regions for all the RedshiftIntervals found in the supplied element. */ - nred = scan->count[ 3 ]; - red_list = astMalloc( sizeof(AstRegion *)*(size_t)nred ); - if( red_list ) { - for( ired = 0; ired < nred; ired++ ) { - red_list[ ired ] = RedshiftIntervalReader( this, - scan->el[ 3 ][ ired ], - red_frame, status ); -/* Store any uncertainty region.*/ - if( uncs[ 3 ] ) astSetUnc( red_list[ ired ], uncs[ 3 ] ); - } - } - -/* Free the can result structure.*/ - scan = FreeIVOAScan( scan, status ); - -/* If the spatial regions cover only a single point, convert it to FK5 - J2000 and use it as the reference position for any SpecFrames (spectral or - redshift) unless values were inherited from the supplied Frame. If the - supplied Frame did not contain set values for these attributes, set them - now. Use astRegSetAttrib which applies the attribute setting to both - base and current Frame of the Region's FrameSet, and avoids re-mapping - the current Frame. */ - if( astOK ) { - if( space_val[ 0 ] != AST__BAD && space_val[ 1 ] != AST__BAD ) { - -/* First need to convert to FK5 J2000 and format into a string for use with - astRegSetAttrib. Need to ensure that the Format and Digits attributes - are set to values which will result in no loss of precision in the - formatting and unformatting steps. */ - fr = astCopy( space_frame ); - astClear( fr, "Format(1),Format(2),Digits(1),Digits(2)" ); - astSet( fr, "digits=%d,system=FK5,equinox=J2000", status, AST__DBL_DIG); - fs = astConvert( space_frame, fr, "" ); - fr = astAnnul( fr ); - if( fs ) { - astTran2( fs, 1, space_val, space_val + 1, 1, &raref, &decref ); - - text = astFormat( fs, raref, 0 ); - l = text ? strlen( text ) : 0; - raset = astMalloc( l + 10 ); - if( raset ) sprintf( raset, "refra=%s", text ); - - text = astFormat( fs, decref, 1 ); - l = text ? strlen( text ) : 0; - decset = astMalloc( l + 10 ); - if( decset ) sprintf( decset, "refdec=%s", text ); - - fs = astAnnul( fs ); - -/* Now set the FK5 J2000 values in the required Frames and Regions. */ - if( !spec_frame || !astTestRefRA( spec_frame ) || - !astTestRefDec( spec_frame ) ) { - for( ispec = 0; ispec < nspec; ispec++ ) { - astRegSetAttrib( spec_list[ ispec ], raset, NULL ); - astRegSetAttrib( spec_list[ ispec ], decset, NULL ); - } - - if( spec_frame ) { - astSetRefRA( (AstSpecFrame *) spec_frame, raref ); - astSetRefDec( (AstSpecFrame *) spec_frame, decref ); - } - } - - if( !red_frame || !astTestRefRA( red_frame ) || - !astTestRefDec( red_frame ) ) { - for( ired = 0; ired < nred; ired++ ) { - astRegSetAttrib( red_list[ ired ], raset, NULL ); - astRegSetAttrib( red_list[ ired ], decset, NULL ); - } - - if( red_frame ) { - astSetRefRA( (AstSpecFrame *) red_frame, raref ); - astSetRefDec( (AstSpecFrame *) red_frame, decref ); - } - } - - for( ianc = 0; ianc < nanc; ianc++ ) { - for( k = 0; k < 5; k++ ) { - if( astMapGet0A( ancs[ ianc ], key[ k ], &o ) ) { - r = (AstRegion *) o; - astRegSetAttrib( r, raset, NULL ); - astRegSetAttrib( r, decset, NULL ); - r = astAnnul( r ); - } - } - } - -/* Free resources. */ - if( raset ) raset = astFree( raset ); - if( decset ) decset = astFree( decset ); - - } else if( astOK ) { - astError( AST__INTER, "AstroCoordAreaReader(XmlChan):" - " Cannot convert spatial position to FK5 J2000" , status); - } - } - -/* If a time region was specified, use a typical value as the epoch for - all Frames. Call MakeMJD to convert "time_val" from the system of the - TimeFrame to an MJD (as required by the Frame Epoch attribute). Set - the value in both the returned Region and the supplied Frame. */ - if( time_val != AST__BAD ) { - fr = astRegFrame( time_list[ 0 ] ); - if( astIsATimeFrame( fr ) ) { - time_val = MakeMJD( (AstTimeFrame *) fr, time_val, status ); - } else if( astOK ) { - astError( AST__INTER, "AstroCoordAreaReader(XmlChan): %s " - "supplied where TimeFrame expected (internal " - "AST programming error).", status, astGetClass( fr ) ); - } - fr = astAnnul( fr ); - - sprintf( buff, "epoch= MJD %.*g", AST__DBL_DIG, time_val ); - - if( !space_frame || !astTestEpoch( space_frame ) ) { - for( ispace = 0; ispace < nspace; ispace++ ) { - astRegSetAttrib( space_list[ ispace ], buff, NULL ); - } - if( space_frame ) astSetEpoch( space_frame, time_val ); - } - - if( !spec_frame || !astTestEpoch( spec_frame ) ) { - for( ispec = 0; ispec < nspec; ispec++ ) { - astRegSetAttrib( spec_list[ ispec ], buff, NULL ); - } - if( spec_frame ) astSetEpoch( spec_frame, time_val ); - } - - if( !red_frame || !astTestEpoch( red_frame ) ) { - for( ired = 0; ired < nred; ired++ ) { - astRegSetAttrib( red_list[ ired ], buff, NULL ); - } - if( red_frame ) astSetEpoch( red_frame, time_val ); - } - - for( ianc = 0; ianc < nanc; ianc++ ) { - for( k = 0; k < 5; k++ ) { - if( astMapGet0A( ancs[ ianc ], key[ k ], &o ) ) { - r = (AstRegion *) o; - astRegSetAttrib( r, buff, NULL ); - r = astAnnul( r ); - } - } - } - - } - -/* If the spectral regions cover only a single point, format it with its - units so that the astSetAttrib function can convert it to Hz and use - it as the rest frequency for any redshift Frames. */ - if( spec_val != AST__BAD && nred > 0 ) { - - text = astGetUnit( spec_frame, 0 ); - if( text ) sprintf( buff, "restfreq= %.*g %s", AST__DBL_DIG, - spec_val, text ); - - if( !red_frame || !astTestRestFreq( red_frame ) ) { - for( ired = 0; ired < nred; ired++ ) { - astRegSetAttrib( red_list[ ired ], buff, NULL ); - } - if( red_frame ) astSetAttrib( red_frame, buff ); - } - - for( ianc = 0; ianc < nanc; ianc++ ) { - for( k = 0; k < 5; k++ ) { - if( astMapGet0A( ancs[ ianc ], key[ k ], &o ) ) { - r = (AstRegion *) o; - astRegSetAttrib( r, buff, NULL ); - r = astAnnul( r ); - } - } - } - } - -/* Create Regions corresponding to every possible combination of interval - on each axis type, and assemble the union of these into a CmpRegion (if - there is more than one). */ - sum = NULL; - -/* Initialise indices of the sub-Frame intervals to use. */ - ispace = 0; - itime = 0; - ispec = 0; - ired = 0; - -/* Loop over all possible combinations of time+space+spec+red intervals. */ - while( 1 ) { - rspace = ( ispace < nspace ) ? space_list[ ispace ] : NULL; - rtime = ( itime < ntime ) ? time_list[ itime ] : NULL; - rspec = ( ispec < nspec ) ? spec_list[ ispec ] : NULL; - rred = ( ired < nred ) ? red_list[ ired ] : NULL; - -/* Prism Regions extrude a Region into higher dimensions, and the - extrusion is defined by an Interval. Spatial Regions are not - restricted to Intervals and so any spatial Region must be the first - Region to be included in the Prism (all the other axis types *are* - restricted to Intervals and so can be used to extrude the spatial - region). */ - reg = rspace ? astClone( rspace ) : NULL; - -/* Now extrude this region (if any) into the time axis. */ - if( rtime ) { - if( reg ) { - tmp = (AstRegion *) astPrism( reg, rtime, "", status ); - (void) astAnnul( reg ); - reg = tmp; - } else { - reg = astClone( rtime ); - } - } - -/* Now extrude this region (if any) into the spectral axis. */ - if( rspec ) { - if( reg ) { - tmp = (AstRegion *) astPrism( reg, rspec, "", status ); - (void) astAnnul( reg ); - reg = tmp; - } else { - reg = astClone( rspec ); - } - } - -/* Now extrude this region (if any) into the redshift axis. */ - if( rred ) { - if( reg ) { - tmp = (AstRegion *) astPrism( reg, rred, "", status ); - (void) astAnnul( reg ); - reg = tmp; - } else { - reg = astClone( rred ); - } - } - - -/* If a Prism was created, add it into the CmpRegion which holds the - running sum of the union of all Prisms created so far. */ - if( reg ) { - if( !sum ) { - sum = astClone( reg ); - } else { - tmp = (AstRegion *) astCmpRegion( sum, reg, AST__OR, "", status ); - (void) astAnnul( sum ); - sum = tmp; - } - reg = astAnnul( reg ); - } - -/* Increment the indices of the next set of sub-Frame Intervals to use. - Leave the while loop when all combinations have been done. */ - if( ++ired >= nred ) { - ired = 0; - if( ++ispec >= nspec ) { - ispec = 0; - if( ++itime >= ntime ) { - itime = 0; - if( ++ispace >= nspace ) break; - } - } - } - } - -/* Simplify the total sum Region. */ - tmp = astSimplify( sum ); - (void) astAnnul( sum ); - sum = tmp; - -/* The axes in this sum Region may not be in the correct order or units (i.e - in the order and units specified in the supplied Frame). So use - astConvert to get a Mapping from the Frame represented by the sum - Region to the supplied Frame. */ - fs = astConvert( sum, frm, "" ); - if( fs ) { - -/* Unless the Mapping is a UnitMap, remap the sum Region into the - supplied Frame using this Mapping. */ - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - if( !astIsAUnitMap( map ) ) { - new = astMapRegion( sum, map, frm ); - } else { - new = astClone( sum ); - } - - map = astAnnul( map ); - fs = astAnnul( fs ); - - } else if( astOK ) { - astError( AST__INTER, "AstroCoordAreaReader(%s): Cannot " - "convert from supplied Frame to internal Frame (AST " - "internal programming error).", status, astGetClass( this ) ); - } - -/* Transfer selected properties from the supplied Frame to the current Frame - of the returned Region. */ - cfrm = astRegFrame( new ); - if( astTestIdent( frm ) ) astSetIdent( cfrm, astGetIdent( frm ) ); - if( astTestTitle( frm ) ) astSetTitle( cfrm, astGetTitle( frm ) ); - -/* Ensure the Epoch is set correctly in the Region */ - if( time_val != AST__BAD ) { - sprintf( buff, "epoch= MJD %.*g", AST__DBL_DIG, time_val ); - astRegSetAttrib( new, buff, NULL ); - } - -/* Free resources. */ - cfrm = astAnnul( cfrm ); - sum = astAnnul( sum ); - } - - if( space_list ) { - for( i = 0; i < nspace; i++ ) space_list[ i ] = astAnnul( space_list[ i ] ); - space_list = astFree( space_list ); - } - - if( time_list ) { - for( i = 0; i < ntime; i++ ) time_list[ i ] = astAnnul( time_list[ i ] ); - time_list = astFree( time_list ); - } - - if( spec_list ) { - for( i = 0; i < nspec; i++ ) spec_list[ i ] = astAnnul( spec_list[ i ] ); - spec_list = astFree( spec_list ); - } - - if( red_list ) { - for( i = 0; i < nred; i++ ) red_list[ i ] = astAnnul( red_list[ i ] ); - red_list = astFree( red_list ); - } - - } - - if( space_frame ) space_frame = astAnnul( space_frame ); - if( time_frame ) time_frame = astAnnul( time_frame ); - if( spec_frame ) spec_frame = astAnnul( spec_frame ); - if( red_frame ) red_frame = astAnnul( red_frame ); - -/* Get the ID attribute from the AstroCoordArea element and store in the - returned Region. */ - id = astXmlGetAttributeValue( elem, "ID" ); - if( id ) astSetIdent( new, id ); - - } - -/* If an error has occurred,annul the returned pointer. */ - if( !astOK ) new = astAnnul( new ); - -/* Return the pointer to the new Region. */ - return new; -} - -static int AstroCoordsReader( AstXmlChan *this, AstXmlElement *elem, - AstFrame *frm, AstRegion *uncs[4], - AstKeyMap **anc, int *status ) { -/* -* Name: -* AstroCoordsReader - -* Purpose: -* Modify a Frame to take account of an IVOA AstroCoords element, and -* return an coordinate uncertainties. - -* Type: -* Private function. - -* Synopsis: -* #include "xmlchan.h" -* int AstroCoordsReader( AstXmlChan *this, AstXmlElement *elem, -* AstFrame *frm, AstRegion *uncs[4], -* AstKeyMap **anc, int *status ) - -* Class Membership: -* XmlChan member function. - -* Description: -* This function modifies the supplied Frame object to incorporate the -* effects of the supplied AstroCoords element. It may also return -* Regions representing the bounds of the uncertainties in the four -* component coordinate Frames, depending on the contents of the -* AstroCoords element. - -* Parameters: -* this -* Pointer to the XmlChan. -* elem -* Pointer to the IVOA AstroCoords element. -* frm -* The Frame object to modify. -* uncs -* Array in which to return pointers to the uncertainty Regions to -* be associated with each of the four STC domains (space, time, -* spectral, redshift). NULL is returned in any element for which -* no uncertainty is specified within the supplied AstroCoords element. -* anc -* Address of a location at which to store the pointer to a newly -* created KeyMap holding ancillary information describing the -* AstroCoords element in the form required by constructors of AST -* Stc objects. A NULL pointer is returned if no usable ancillary -* information is found in the AstroCoords. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if any non-NULL values have been returned in the "uncs" -* array. Zero otherwise. - -*/ - -/* Local Variables: */ - AstFrame *afrm; /* Pointer to axis Frame */ - AstFrame *gfrm; /* Pointer to generic Frame */ - AstFrame *pfrm; /* Pointer to position Frame */ - AstFrame *rfrm; /* Pointer to redshift Frame */ - AstFrame *sfrm; /* Pointer to spectral Frame */ - AstTimeFrame *tfrm; /* Pointer to time Frame */ - AstKeyMap *panc; /* KeyMap holding spatial ancillary data */ - AstKeyMap *ranc; /* KeyMap holding redshift ancillary data */ - AstKeyMap *sanc; /* KeyMap holding spectral ancillary data */ - AstKeyMap *tanc; /* KeyMap holding temporal ancillary data */ - AstObject *o; /* Pointer to object retrieved from KeyMap */ - AstRegion *r; /* Individual ancillary Region */ - AstRegion *t; /* Total extruded ancillary Region */ - AstRegion *tt; /* Temporary Region pointer */ - AstXmlElement *el; /* Pointer to Position2D element */ - IVOAScan *scan; /* Structure holding scan results */ - char **anames; /* Pointer to list of ancillary name pointers */ - const char *dom; /* Pointer to Domain attribute value */ - const char *nam; /* Pointer to ancillary Name string */ - const char *names[4]; /* Names of the subelements to be searched for */ - char buff[100]; /* Message buffer */ - double epoch; /* Epoch */ - double hi; /* High limit for zero-width interval */ - double lo; /* Low limit for zero-width interval */ - double pos[2]; /* Reference spatial position */ - double rf; /* Rest frequency */ - int axes[2]; /* Indices of position axes */ - int axis; /* Index of next axis to use */ - int empty; /* Is returned KeyMap empty? */ - int i; /* Loop count */ - int isearth; /* Does the SkyFrame represent terrestrial lon/lat? */ - int junk; /* Unused integer value */ - int max[4]; /* Max allowed occurrences of each name */ - int min[4]; /* Min allowed occurrences of each name */ - int nax; /* Number of axes in supplied Frame */ - int unc; /* Any uncertainty Regions found? */ - int use; /* Use ancillary information? */ - - static const char *key[ 5 ] = { AST__STCERROR, - AST__STCRES, - AST__STCSIZE, - AST__STCPIXSZ, - AST__STCVALUE }; -/* Initialise */ - unc = 0; - uncs[ 0 ] = NULL; - uncs[ 1 ] = NULL; - uncs[ 2 ] = NULL; - uncs[ 3 ] = NULL; - *anc = NULL; - -/* Check the global error status. */ - if ( !astOK ) return unc; - -/* Search the supplied element for the required sub-elements. */ - names[ 0 ] = "Position2D|Position3D"; - names[ 1 ] = "Time"; - names[ 2 ] = "Spectral"; - names[ 3 ] = "Redshift"; - min[ 0 ] = 0; - min[ 1 ] = 0; - min[ 2 ] = 0; - min[ 3 ] = 0; - max[ 0 ] = 1; - max[ 1 ] = 1; - max[ 2 ] = 1; - max[ 3 ] = 1; - scan = ScanIVOAElement( this, elem, 4, names, min, max, status ); - -/* If succesfull.. */ - if( scan ) { - -/* Initialise pointers to component Frames */ - pfrm = NULL; - tfrm = NULL; - sfrm = NULL; - rfrm = NULL; - -/* Initialise pointers to KeyMaps holding ancillary data. */ - panc = NULL; - tanc = NULL; - sanc = NULL; - ranc = NULL; - -/* Allocate storage for an array of pointers to strings holding the Name - value for each axis. Initialise them to a null string. */ - nax = astGetNaxes( frm ); - anames = astMalloc( sizeof( char * )*(size_t)nax ); - for( i = 0; i < nax; i++ ) anames[ i ] = NULL; - -/* Initialise the index of the next Frame axis to use. */ - axis = 0; - -/* Check to see if the next 2 axes describe positions on the sky or earth - (see SpaceFrameReader). */ - axes[ 0 ] = 0; - axes[ 1 ] = 1; - afrm = astPickAxes( frm, 2, axes, NULL ); - dom = astGetDomain( afrm ); - isearth = dom && ( !strcmp( dom, "GEO_D" ) || - !strcmp( dom, "GEO_C" ) ); - - if( isearth || ( dom && !strcmp( dom, "SKY" ) ) ){ - astPrimaryFrame( frm, axis, &pfrm, &junk ); - if( scan->count[ 0 ] ) { - -/* We currently also use SkyFrames to represent geographical long/lat used to - describe observatory positions. These may have 3D positions, in which - case we convert the 3D position to a 2D position by ignoring the 3rd axis - value (height). See SpaceFrameReader. */ - el = MakePos2D( this, scan->el[ 0 ][ 0 ], status ); - -/* Use the Position2D to create a Region describing the uncertainty in - the space axes of the Frame. Also create a KeyMap holding Regions - describing any ancillary information stored in the Position2D. */ - uncs[ 0 ] = Position2DReader( this, el, pfrm, pos, &panc, status ); - if( uncs[ 0 ] ) unc = 1; - el = astXmlDelete( el ); - -/* If ancillary information was returned, extract the Name element, and - store it twice (once for each axis) in the "names" array. */ - if( panc && astMapGet0C( panc, AST__STCNAME, &nam ) ) { - anames[ axis ] = astStore( NULL, nam, strlen( nam ) + 1 ); - anames[ axis + 1 ] = astStore( NULL, nam, strlen( nam ) + 1 ); - } - } - -/* Increment the axis index. */ - axis += 2; - -/* If the supplied Frame has no sky frame, but we found a Position2D, then - report a warning and ignore the Position2D. */ - } else if( scan->count[ 0 ] ) { - sprintf( buff, "contains a <%s> which is not being used.", - astXmlGetName( scan->el[ 0 ][ 0 ] ) ); - Report( this, elem, WARNING, buff, status ); - } - afrm = astAnnul( afrm ); - -/* Indicate we do not yet have an epoch to use. */ - epoch = AST__BAD; - -/* Check to see if the Frame contains a time frame. It will be the next - axis if it does. */ - afrm = astPickAxes( frm, 1, &axis, NULL ); - dom = astGetDomain( afrm ); - if( dom && !strcmp( dom, "TIME" ) ){ - astPrimaryFrame( frm, axis, &gfrm, &junk ); - -/* Report an error if it is not an AST TimeFrame. */ - if( !astIsATimeFrame( gfrm ) && astOK ) { - astError( AST__INTER, "AstroCoordAreaReader(XmlChan): %s " - "supplied where TimeFrame expected (internal " - "AST programming error).", status, astGetClass( pfrm ) ); - } else { - tfrm = (AstTimeFrame *) gfrm; - } - -/* Use any Time element to create a Region describing the uncertainty in the - time axis of the Frame. Also create a KeyMap holding Regions describing - any ancillary information stored in the Time element. */ - if( scan->count[ 1 ] ) { - uncs[ 1 ] = TimeReader( this, scan->el[ 1 ][ 0 ], tfrm, &epoch, - &tanc, status ); - if( uncs[ 1 ] ) unc = 1; - -/* If ancillary information was returned, extract the Name element, and - store it in the "names" array. */ - if( tanc && astMapGet0C( tanc, AST__STCNAME, &nam ) ) { - anames[ axis ] = astStore( NULL, nam, strlen( nam ) + 1 ); - } - } - -/* Increment the index of the next axis to use. */ - axis++; - -/* If the supplied Frame has no time frame, but we found a Time element, then - report a warning and ignore the Time element. */ - } else if( scan->count[ 1 ] ) { - Report( this, elem, WARNING, "contains a